diff -urN linux-2.4.29/arch/arm/boot/compressed/big-endian.S linux-2.4.29-uc1/arch/arm/boot/compressed/big-endian.S
--- linux-2.4.29/arch/arm/boot/compressed/big-endian.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/boot/compressed/big-endian.S	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,13 @@
+/*
+ *  linux/arch/arm/boot/compressed/big-endian.S
+ *
+ *  Switch CPU into big endian mode.
+ *  Author: Nicolas Pitre
+ */
+
+		.section ".start", #alloc, #execinstr
+
+		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
+		orr	r0, r0, #(1 << 7)	@ enable big endian mode
+		mcr	p15, 0, r0, c1, c0, 0	@ write control reg
+
diff -urN linux-2.4.29/arch/arm/boot/compressed/head-ks8695.S linux-2.4.29-uc1/arch/arm/boot/compressed/head-ks8695.S
--- linux-2.4.29/arch/arm/boot/compressed/head-ks8695.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/boot/compressed/head-ks8695.S	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,4 @@
+#include <asm/mach-types.h>
+
+		.section	".start", #alloc, #execinstr
+		mov	r7, #MACH_TYPE_KS8695
diff -urN linux-2.4.29/arch/arm/boot/compressed/head.S linux-2.4.29-uc1/arch/arm/boot/compressed/head.S
--- linux-2.4.29/arch/arm/boot/compressed/head.S	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/boot/compressed/head.S	2005-06-14 02:11:00.000000000 +0100
@@ -1,3 +1,4 @@
+/*#define	DEBUG	1*/
 /*
  *  linux/arch/arm/boot/compressed/head.S
  *
@@ -73,6 +74,25 @@
  */
 		str	\rb, [r3, #0x14]	@ UTDR
 		.endm
+#elif defined(CONFIG_ARCH_IXP425)
+		.macro	loadsp, rb
+		mov	\rb, #0xc8000000
+		.endm
+		.macro	writeb, rb
+		str	\rb, [r3, #0]
+		.endm
+#elif defined(CONFIG_ARCH_EP9312)
+		.macro	loadsp, rb
+		mov	\rb, #0x80000000	@ physical base address
+#if defined(CONFIG_MACH_IPD)
+		add	\rb, \rb, #0x008d0000	@ Ser2
+#else
+		add	\rb, \rb, #0x008c0000	@ Ser1
+#endif
+		.endm
+		.macro	writeb, rb
+		strb	\rb, [r3, #0]
+		.endm
 #else
 #error no serial architecture defined
 #endif
@@ -343,7 +363,11 @@
 		orr	r1, r1, #3 << 10
 		add	r2, r3, #16384
 1:		cmp	r1, r8			@ if virt > start of RAM
+#ifdef CONFIG_XSCALE_CACHE_ERRATA
+		orrhs	r1, r1, #0x08		@ set cacheable, not bufferable
+#else
 		orrhs	r1, r1, #0x0c		@ set cacheable, bufferable
+#endif
 		cmp	r1, r9			@ if virt > end of RAM
 		bichs	r1, r1, #0x0c		@ clear cacheable, bufferable
 		str	r1, [r0], #4		@ 1:1 mapping
@@ -376,7 +400,7 @@
 		mov	r0, #-1
 		mcr	p15, 0, r0, c3, c0, 0	@ load domain access register
 		mrc	p15, 0, r0, c1, c0, 0
-		orr	r0, r0, #0x1000		@ I-cache enable
+		orr	r0, r0, #0x5000		@ I-cache enable, RR cache replacement
 #ifndef DEBUG
 		orr	r0, r0, #0x003d		@ Write buffer, mmu
 #endif
@@ -396,6 +420,20 @@
 		mcr	p15, 0, r0, c1, c0, 0	@ load control register
 		mov	pc, r12
 
+__arm7_cache_on:
+		mov	r12, lr
+		bl	__setup_mmu
+		mov	r0, #0
+		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
+		mcr	p15, 0, r0, c5, c0, 0	@ invalidate whole TLB v3
+		mcr	p15, 0, r3, c2, c0, 0	@ load page table pointer
+		mov	r0, #-1
+		mcr	p15, 0, r0, c3, c0, 0	@ load domain access control
+		mov	r0, #0x7d
+		mcr	p15, 0, r0, c1, c0, 0	@ load control register
+		mov	pc, r12
+
+
 /*
  * All code following this line is relocatable.  It is relocated by
  * the above code to the end of the decompressed kernel image and
@@ -429,6 +467,11 @@
 		mov	r1, r7			@ restore architecture number
 		mov	pc, r4			@ call kernel
 
+		.type	proc_xscale_type,#object
+proc_xscale_type:
+		.word	0x69050000
+		.size	proc_xscale_type, . - proc_xscale_type
+
 /*
  * Here follow the relocatable cache support functions for the
  * various processors.  This is a generic hook for locating an
@@ -480,9 +523,9 @@
 
 		.word	0x41007000		@ ARM7/710
 		.word	0xfff8fe00
+		b	__arm7_cache_on
 		b	__arm7_cache_off
-		b	__arm7_cache_off
-		mov	pc, lr
+		b	__armv3_cache_flush
 
 		.word	0x41807200		@ ARM720T (writethrough)
 		.word	0xffffff00
@@ -490,14 +533,14 @@
 		b	__armv4_cache_off
 		mov	pc, lr
 
-		.word	0x41129200		@ ARM920T
-		.word	0xff00fff0
+		.word	0x41009200		@ ARM920T, ARM922T, ARM926TEJ-S
+		.word	0xff00ff90
 		b	__armv4_cache_on
 		b	__armv4_cache_off
 		b	__armv4_cache_flush
 
-		.word	0x41029220		@ ARM922T
-		.word	0xff00fff0
+		.word	0x4100a200		@ ARM1020T/E, ARM1022E, ARM1026TEJ-S
+		.word	0xff00ff90
 		b	__armv4_cache_on
 		b	__armv4_cache_off
 		b	__armv4_cache_flush
diff -urN linux-2.4.29/arch/arm/boot/compressed/head-xscale.S linux-2.4.29-uc1/arch/arm/boot/compressed/head-xscale.S
--- linux-2.4.29/arch/arm/boot/compressed/head-xscale.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/boot/compressed/head-xscale.S	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,130 @@
+/* 
+ * linux/arch/arm/boot/compressed/head-xscale.S
+ * 
+ * XScale specific tweaks.  This is merged into head.S by the linker.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/mach-types.h>
+
+		.section        ".start", #alloc, #execinstr
+
+__XScale_start:
+
+		@ Preserve r8/r7 i.e. kernel entry values
+
+		@ Be sure to flush kernel binary out of the cache,
+		@ whatever state it is, before it is turned off.
+		@ This is done by fetching through currently executed
+		@ memory to be sure we hit the same cache.
+
+		bic	r2, pc, #0x1f
+		add	r3, r2, #0x10000	@ 64 kb is quite enough...
+1:		ldr	r0, [r2], #32
+		teq	r2, r3
+		bne	1b
+		mcr	p15, 0, r0, c7, c10, 4	@ drain WB
+		mcr	p15, 0, r0, c7, c7, 0	@ flush I & D caches
+
+		@ disabling MMU and caches
+		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
+		bic	r0, r0, #0x05		@ clear DC, MMU
+		bic	r0, r0, #0x1000		@ clear Icache
+		mcr	p15, 0, r0, c1, c0, 0
+#ifdef	CONFIG_ARCH_IQ80321
+	orr	pc, pc, #0xa0000000
+	nop
+	mov	r7, #MACH_TYPE_IQ80321
+#endif
+
+#ifdef CONFIG_ARCH_IQ80310	
+
+		/*
+		 * Crank the CPU up to 733MHz
+		 */
+		mov r1, #9
+		mcr p14, 0, r1, c6, c0, 0	
+
+		/*	
+		 * Disable ECC error notification
+		 * At some point, we should add an ECC handler to Linux
+		 */
+		mov	r1, #0x1500
+		mov	r0, #0x4
+		str	r0, [r1, #0x34]	
+
+		mov	r7, #MACH_TYPE_IQ80310
+#endif		
+
+#ifdef CONFIG_ARCH_BRH
+		mov	r7, #MACH_TYPE_BRH
+#endif
+
+#ifdef CONFIG_ARCH_IXDP425
+		mov	r7, #MACH_TYPE_IXDP425
+#endif
+
+#ifdef CONFIG_MACH_IXDP465
+		mov r7, #MACH_TYPE_IXDP465 & 0xff
+		orr r7, r7, #MACH_TYPE_IXDP465 & 0xff00
+#endif
+
+#ifdef CONFIG_ARCH_PRPMC1100
+		mov	r7, #(MACH_TYPE_PRPMC1100 & 0xff)
+		orr	r7, r7, #(MACH_TYPE_PRPMC1100 & 0xff00)
+#endif
+
+#ifdef CONFIG_ARCH_ADI_COYOTE
+		# Set machine ID into r7 (Coyote ID > 255 hence needs
+		# two instructions to build the ID safely).
+		mov r7, #MACH_TYPE_ADI_COYOTE & 0xff
+		orr r7, r7, #MACH_TYPE_ADI_COYOTE & 0xff00
+#endif
+
+#ifdef CONFIG_ARCH_SE4000
+		mov r7, #MACH_TYPE_SE4000 & 0xff
+		orr r7, r7, #MACH_TYPE_SE4000 & 0xff00
+#endif
+
+#ifdef CONFIG_MACH_ESS710
+		mov r7, #MACH_TYPE_ESS710 & 0xff
+		orr r7, r7, #MACH_TYPE_ESS710 & 0xff00
+#endif
+
+#ifdef CONFIG_MACH_MONTEJADE
+		mov r7, #MACH_TYPE_MONTEJADE & 0xff
+		orr r7, r7, #MACH_TYPE_MONTEJADE & 0xff00
+#endif
+
+#ifdef CONFIG_MACH_IVPN
+		mov r7, #MACH_TYPE_IVPN & 0xff
+		orr r7, r7, #MACH_TYPE_IVPN & 0xff00
+#endif
+
+#ifdef CONFIG_MACH_SE5100
+		mov r7, #MACH_TYPE_SE5100 & 0xff
+		orr r7, r7, #MACH_TYPE_SE5100 & 0xff00
+#endif
+
+#ifdef CONFIG_MACH_SG560
+		mov r7, #MACH_TYPE_SG560 & 0xff
+		orr r7, r7, #MACH_TYPE_SG560 & 0xff00
+#endif
+
+#ifdef CONFIG_MACH_SG565
+		mov r7, #MACH_TYPE_SG565 & 0xff
+		orr r7, r7, #MACH_TYPE_SG565 & 0xff00
+#endif
+
+#ifdef CONFIG_MACH_SHIVA1100
+		mov r7, #MACH_TYPE_SHIVA1100 & 0xff
+		orr r7, r7, #MACH_TYPE_SHIVA1100 & 0xff00
+#endif
+
+#ifdef CONFIG_MACH_SG580
+		mov r7, #MACH_TYPE_SG580 & 0xff
+		orr r7, r7, #MACH_TYPE_SG580 & 0xff00
+#endif
+
diff -urN linux-2.4.29/arch/arm/boot/compressed/Makefile linux-2.4.29-uc1/arch/arm/boot/compressed/Makefile
--- linux-2.4.29/arch/arm/boot/compressed/Makefile	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/boot/compressed/Makefile	2005-06-14 02:11:00.000000000 +0100
@@ -38,6 +38,10 @@
 OBJS		+= head-integrator.o
 endif
 
+ifeq ($(CONFIG_ARCH_KS8695),y)
+OBJS		+= head-ks8695.o
+endif
+
 ifeq ($(CONFIG_ARCH_AT91RM9200),y)
 OBJS		+= head-at91rm9200.o
 endif
@@ -71,6 +75,21 @@
 OBJS		+= head-sa1100.o
 endif
 
+ifeq ($(CONFIG_CPU_XSCALE),y)
+OBJS		+= head-xscale.o
+endif
+
+#
+# Just borrow from SA1* for now
+#
+ifeq ($(CONFIG_ARCH_IXP1200),y)
+OBJS		+= head-sa1100.o
+endif
+
+ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
+OBJS		+= big-endian.o
+endif
+
 SEDFLAGS	= s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;s/BSS_START/$(ZBSSADDR)/
 
 LIBGCC		:= $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
diff -urN linux-2.4.29/arch/arm/boot/endianswap.c linux-2.4.29-uc1/arch/arm/boot/endianswap.c
--- linux-2.4.29/arch/arm/boot/endianswap.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/boot/endianswap.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ * endianswap.c : Swaps endianness on 4-byte boundaries.
+ * Author: 	Nicolas Pitre
+ * Copyright:	(C) 2001 MontaVista Software Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The purpose of this tool is to convert a kernel image which is compiled
+ * to run in a different endianness than what the CPU is initially set with.
+ * The kernel will switch the CPU endian mode as required, but since the 
+ * bootloader lays the kernel in memory according to the current endianness
+ * we have to swap it over.  As long as the desired endianness is set before
+ * any memory access smaller than a word is performed there shouldn't be any
+ * problem executing such code.
+ */
+
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+	int a, b, c, d;
+
+	for (;;) {
+		a = getchar();
+		b = getchar();
+		c = getchar();
+		d = getchar();
+		if ((a|b|c|d) & ~0xff)
+			break;
+		putchar(d);
+		putchar(c);
+		putchar(b);
+		putchar(a);
+	}
+	if (a < 0)
+		return 0;
+	if (b < 0)
+		b = 0;
+	if (c < 0)
+		c = 0;
+	if (d < 0)
+		d = 0;
+	putchar(d);
+	putchar(c);
+	putchar(b);
+	putchar(a);
+	return 0;
+}
diff -urN linux-2.4.29/arch/arm/boot/Makefile linux-2.4.29-uc1/arch/arm/boot/Makefile
--- linux-2.4.29/arch/arm/boot/Makefile	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/boot/Makefile	2005-06-14 02:11:00.000000000 +0100
@@ -60,6 +60,13 @@
 INITRD_PHYS	 = 0x00800000
 endif
 
+ifeq ($(CONFIG_ARCH_KS8695),y)
+ZRELADDR	 = 0x00008000
+PARAMS_PHYS	 = 0x00000100
+INITRD_PHYS	 = 0x00800000
+INITRD_VIRT	 = 0xc0800000
+endif
+
 ifeq ($(CONFIG_ARCH_AT91RM9200),y)
 ZRELADDR	 = 0x20008000
 endif
@@ -86,6 +93,38 @@
 PARAMS_PHYS	 = 0xc0000100
 endif
 
+ifeq ($(CONFIG_ARCH_EDB7312),y)
+ZRELADDR	 = 0xc0038000
+PARAMS_PHYS	 = 0xc0030000
+INITRD_PHYS	 = 0xc0800000
+endif
+
+ifeq ($(CONFIG_ARCH_EDB9301),y)
+ZRELADDR	 = 0x00008000
+PARAMS_PHYS	 = 0x00000100
+INITRD_PHYS	 = 0x01000000
+endif
+ifeq ($(CONFIG_ARCH_EDB9302),y)
+ZRELADDR	 = 0x00008000
+PARAMS_PHYS	 = 0x00000100
+INITRD_PHYS	 = 0x01000000
+endif
+ifeq ($(CONFIG_ARCH_EDB9312),y)
+ZRELADDR	 = 0x00008000
+PARAMS_PHYS	 = 0x00000100
+INITRD_PHYS	 = 0x00800000
+endif
+ifeq ($(CONFIG_ARCH_EDB9315),y)
+ZRELADDR	 = 0x00008000
+PARAMS_PHYS	 = 0x00000100
+INITRD_PHYS	 = 0x00800000
+endif
+ifeq ($(CONFIG_MACH_IPD),y)
+ZRELADDR	 = 0xc0218000
+PARAMS_PHYS	 = 0xc0000100
+INITRD_PHYS	 = 0xc0800000
+endif
+
 # Should probably have some agreement on these...
 ifeq ($(CONFIG_ARCH_P720T),y)
 INITRD_PHYS	 = 0xc0400000
@@ -117,6 +156,64 @@
 ZRELADDR	 = 0x20008000
 endif
 
+
+ifeq ($(CONFIG_ARCH_IOP3XX),y)
+
+ZRELADDR	= 0xa0008000
+
+# For serial upload
+ZTEXTADDR	= 0xa1008000
+
+# For direct flash exec
+# ZTEXTADDR	= 0x00060000
+# ZBSSADDR	= 0xa1008000
+endif
+
+ifeq ($(CONFIG_ARCH_ADIFCC),y)
+ZRELADDR	= 0xc0008000
+ZTEXTADDR	= 0xc1000000
+PARAMS_PHYS	= 0xc0000100
+endif
+
+ifeq ($(CONFIG_ARCH_IXP1200),y)
+ZTEXTADDR	= 0xc0800000
+# ZRELADDR	= 0xc0008000
+ZRELADDR	= 0x$(shell echo $(CONFIG_IXP1200_SDRAM_BASE) | sed -e 's/0000$$/8000/')
+endif
+
+ifeq ($(CONFIG_ARCH_IXP425),y)
+ZTEXTADDR	= 0x1d600000
+ZRELADDR	= 0x00008000
+PARAMS_PHYS	= 0x00002000
+endif
+
+ifeq ($(CONFIG_ARCH_IXP2000),y)
+# compressed kernel relocating address
+ZRELADDR        = 0x1c008000
+ZTEXTADDR       = 0x1d008000
+endif
+
+ifeq ($(CONFIG_ARCH_IQ80310),y)
+ZRELADDR	 = 0xa0008000
+
+# for serial upload
+ZTEXTADDR	 = 0xa1008000
+
+# for direct flash execution
+# ZTEXTADDR       = 0x00060000
+# ZBSSADDR       = 0xa1008000
+endif
+
+ifeq ($(CONFIG_ARCH_ADIFCC),y)
+ZRELADDR	= 0xc0008000
+ZTEXTADDR	= 0xc1008000
+
+# For flash boot
+# ZTEXTADDR	= 0x00000000
+# ZBSSADDR	= 0xc1000000
+
+endif
+
 #
 # We now have a PIC decompressor implementation.  Decompressors running
 # from RAM should not define ZTEXTADDR.  Decompressors running directly
@@ -126,7 +223,7 @@
 ZTEXTADDR	=0x$(CONFIG_ZBOOT_ROM_TEXT)
 ZBSSADDR	=0x$(CONFIG_ZBOOT_ROM_BSS)
 else
-ZTEXTADDR	=0
+ZTEXTADDR	?=0
 ZBSSADDR	=ALIGN(4)
 endif
 
@@ -140,6 +237,9 @@
 zImage:	compressed/vmlinux
 	$(OBJCOPY) $(OBJCOPYFLAGS) $< $@
 
+zsrec: compressed/vmlinux
+	$(OBJCOPY) -O srec -R .note -R .comment -S $< $@   
+
 bootpImage: bootp/bootp
 	$(OBJCOPY) $(OBJCOPYFLAGS) $< $@
 
@@ -159,8 +259,14 @@
 zinstall: zImage
 	sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
 
+endianswap: endianswap.c
+	$(HOSTCC) $(HOSTCFLAGS) -o $@ $<
+
+%.swap: % endianswap
+	./endianswap < $< > $@
+
 clean:
-	$(RM) Image zImage bootpImage
+	$(RM) Image zImage bootpImage endianswap zsrec *.swap
 	@$(MAKE) -C compressed clean
 	@$(MAKE) -C bootp clean
 
diff -urN linux-2.4.29/arch/arm/common/Makefile linux-2.4.29-uc1/arch/arm/common/Makefile
--- linux-2.4.29/arch/arm/common/Makefile	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/common/Makefile	2005-06-14 02:10:59.000000000 +0100
@@ -13,5 +13,6 @@
 
 obj-$(CONFIG_USB_OHCI_SA1111)   += pcipool.o
 obj-$(CONFIG_USB_OHCI_AT91)	+= pcipool.o
+obj-$(CONFIG_USB_OHCI_EP93XX)	+= pcipool.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/arm/common/pcipool.h linux-2.4.29-uc1/arch/arm/common/pcipool.h
--- linux-2.4.29/arch/arm/common/pcipool.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/common/pcipool.h	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,8 @@
+
+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t allocation, int flags);
+void pci_pool_destroy (struct pci_pool *pool);
+
+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+
diff -urN linux-2.4.29/arch/arm/config.in linux-2.4.29-uc1/arch/arm/config.in
--- linux-2.4.29/arch/arm/config.in	2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.29-uc1/arch/arm/config.in	2005-06-14 02:11:00.000000000 +0100
@@ -17,6 +17,7 @@
 mainmenu_option next_comment
 comment 'Code maturity level options'
 bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+bool 'Prompt for advanced kernel configuration options' CONFIG_ADVANCED_OPTIONS
 bool 'Prompt for obsolete code/drivers' CONFIG_OBSOLETE
 endmenu
 
@@ -33,7 +34,8 @@
 comment 'System Type'
 
 choice 'ARM system type' \
-	"Anakin			CONFIG_ARCH_ANAKIN \
+	"ADIFCC-based		CONFIG_ARCH_ADIFCC \
+	 Anakin			CONFIG_ARCH_ANAKIN \
 	 Archimedes/A5000	CONFIG_ARCH_ARCA5K \
 	 Cirrus-CL-PS7500FE     CONFIG_ARCH_CLPS7500 \
  	 CLPS711x/EP721x-based	CONFIG_ARCH_CLPS711X \
@@ -42,9 +44,15 @@
  	 Excalibur-ARM          CONFIG_ARCH_CAMELOT \
 	 FootBridge		CONFIG_ARCH_FOOTBRIDGE \
 	 Integrator		CONFIG_ARCH_INTEGRATOR \
+	 KS8695			CONFIG_ARCH_KS8695 \
+	 IOP3xx-based		CONFIG_ARCH_IOP3XX \
+	 IXP1200-based		CONFIG_ARCH_IXP1200 \
+	 IXP2000-based		CONFIG_ARCH_IXP2000 \
+	 IXP425-based		CONFIG_ARCH_IXP425 \
 	 Omaha			CONFIG_ARCH_OMAHA \
 	 LinkUp-L7200		CONFIG_ARCH_L7200 \
 	 Motorola-MX1ADS        CONFIG_ARCH_MX1ADS \
+	 EP93xx-based		CONFIG_ARCH_EP93XX \
 	 RiscPC			CONFIG_ARCH_RPC \
 	 RiscStation		CONFIG_ARCH_RISCSTATION \
 	 SA1100-based		CONFIG_ARCH_SA1100 \
@@ -136,14 +144,89 @@
 dep_tristate 'SA1100 USB function support' CONFIG_SA1100_USB $CONFIG_ARCH_SA1100
 dep_tristate '  Support for SA11x0 USB network link function' CONFIG_SA1100_USB_NETLINK $CONFIG_SA1100_USB
 dep_tristate '  Support for SA11x0 USB character device emulation' CONFIG_SA1100_USB_CHAR $CONFIG_SA1100_USB
-
 dep_tristate 'SA1100 Generic PIO SSP support' CONFIG_SA1100_SSP $CONFIG_ARCH_SA1100
-
 endmenu
 
+if [ "$CONFIG_ARCH_IOP3XX" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'IOP3xx Implementation Options'
+   choice 'IOP3xx System Type' \
+      "IQ80310		CONFIG_ARCH_IQ80310\
+       IQ80321		CONFIG_ARCH_IQ80321" IQ80310
+
+# Which IOP variant are we running?
+   if [ "$CONFIG_ARCH_IQ80310" = "y" ]; then
+      define_bool CONFIG_ARCH_IOP310 y
+   else
+      define_bool CONFIG_ARCH_IOP310 n
+   fi
+
+   if [ "$CONFIG_ARCH_IQ80321" = "y" ]; then
+      define_bool CONFIG_ARCH_IOP321 y
+   else
+      define_bool CONFIG_ARCH_IOP321 n
+   fi
+
+   comment 'IOP3xx Chipset Features'
+   dep_bool 'Support IOP3xx AAU (EXPERIMENTAL)' CONFIG_IOP3XX_AAU $CONFIG_EXPERIMENTAL
+   dep_bool 'Support IOP3xx DMA (EXPERIMENTAL)' CONFIG_IOP3XX_DMA $CONFIG_EXPERIMENTAL
+   dep_bool 'Support IOP3xx Messaging Unit (EXPERIMENTAL)' CONFIG_IOP3XX_MU $CONFIG_EXPERIMENTAL
+   dep_bool 'Support IOP3xx Performance Monitor (EXPERIMENTAL)' CONFIG_IOP3XX_PMON $CONFIG_EXPERIMENTAL
+   endmenu
+fi
+
+if [ "$CONFIG_ARCH_IXP425" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'IXP4xx Implementation Options'
+   choice 'IXP4xx Board Type' \
+     "IXDP425 CONFIG_ARCH_IXDP425 \
+      IXDP465 CONFIG_MACH_IXDP465 \
+      Montejade CONFIG_MACH_MONTEJADE \
+      IXCDP1100 CONFIG_ARCH_IXCDP1100 \
+      PrPMC1100 CONFIG_ARCH_PRPMC1100 \
+      COYOTE CONFIG_ARCH_ADI_COYOTE \
+      SE4000 CONFIG_ARCH_SE4000 \
+      SG560 CONFIG_MACH_SG560 \
+      SG565 CONFIG_MACH_SG565 \
+      Shiva1100 CONFIG_MACH_SHIVA1100 \
+      SG580 CONFIG_MACH_SG580 \
+      SG710 CONFIG_MACH_ESS710 \
+      iVPN CONFIG_MACH_IVPN \
+      SE5100 CONFIG_MACH_SE5100" IXDP425
+   endmenu
+fi
+
+
+if [ "$CONFIG_ARCH_IXP1200" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'IXP1200 Implementation Options'
+   hex 'IXP12000 SDRAM base for Linux' CONFIG_IXP1200_SDRAM_BASE 0xc0000000
+   int 'IXP1200 SDRAM size for Linux (MB)' CONFIG_IXP1200_SDRAM_SIZE 128
+   endmenu
+fi
+
+if [ "$CONFIG_ARCH_IXP2000" = "y" ]; then
+   choice  'IXP2000 System Type' \
+      "IXDP2400    CONFIG_ARCH_IXDP2400\
+       IXDP2800    CONFIG_ARCH_IXDP2800" IXDP2400
+   bool 'Workaround for PCI I/O errrata' CONFIG_IXP2000_PCI_IO_ERRATA
+fi
+
+if [ "$CONFIG_ARCH_KS8695" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'KS8695 Implementation Options'
+   choice 'KS8695 Board Type' \
+     "KS8695	CONFIG_MACH_KS8695 \
+      CM4008	CONFIG_MACH_CM4008 \
+      CM41xx	CONFIG_MACH_CM41xx \
+      LITE300	CONFIG_MACH_LITE300" KS8695
+   endmenu
+fi
+
 mainmenu_option next_comment
 comment 'AT91RM9200 Implementations'
 dep_bool '  Atmel AT91RM9200 Development Board' CONFIG_ARCH_AT91RM9200DK $CONFIG_ARCH_AT91RM9200
+dep_bool '  Cogent CSB337' CONFIG_MACH_CSB337 $CONFIG_ARCH_AT91RM9200
 endmenu
 
 mainmenu_option next_comment
@@ -152,6 +235,7 @@
 dep_bool '  CDB89712' CONFIG_ARCH_CDB89712 $CONFIG_ARCH_CLPS711X
 dep_bool '  CLEP7312' CONFIG_ARCH_CLEP7312 $CONFIG_ARCH_CLPS711X
 dep_bool '  EDB7211' CONFIG_ARCH_EDB7211 $CONFIG_ARCH_CLPS711X
+dep_bool '  EDB7312' CONFIG_ARCH_EDB7312 $CONFIG_ARCH_CLPS711X
 dep_bool '  FORTUNET' CONFIG_ARCH_FORTUNET $CONFIG_ARCH_CLPS711X
 dep_bool '  GUIDEA07' CONFIG_ARCH_GUIDEA07 $CONFIG_ARCH_CLPS711X
 dep_bool '  P720T' CONFIG_ARCH_P720T $CONFIG_ARCH_CLPS711X
@@ -169,9 +253,15 @@
 else
    define_bool CONFIG_ARCH_EP7212 n
 fi
+if [ "$CONFIG_ARCH_EDB7312" = "y" ]; then
+   define_bool CONFIG_ARCH_EP7312 y
+else
+   define_bool CONFIG_ARCH_EP7312 n
+fi
 
 if [ "$CONFIG_ARCH_EP7211" = "y" -o \
-     "$CONFIG_ARCH_EP7212" = "y" ]; then
+     "$CONFIG_ARCH_EP7212" = "y" -o \
+     "$CONFIG_ARCH_EP7312" = "y" ]; then
    bool '  EP72xx ROM boot' CONFIG_EP72XX_ROM_BOOT
 fi
 
@@ -181,6 +271,60 @@
 
 endmenu
 
+if [ "$CONFIG_ARCH_ADIFCC" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'ADI FCC Implementation Options'
+   choice 'ADI FCC System Type' \
+	"80200EVB	CONFIG_ARCH_ADI_EVB \
+	 BRH		CONFIG_ARCH_BRH" 80200EVB
+   endmenu
+fi 
+
+if [ "$CONFIG_ARCH_EP93XX" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'EP93xx Implementations'
+   choice 'EP93xx Implementation' \
+	  "EDB9301 CONFIG_ARCH_EDB9301 \
+	   EDB9302 CONFIG_ARCH_EDB9302 \
+	   EDB9312 CONFIG_ARCH_EDB9312 \
+	   EDB9315 CONFIG_ARCH_EDB9315" EDB9312
+
+   if [ "$CONFIG_ARCH_EDB9301" = "y" ]; then
+      define_bool CONFIG_ARCH_EP9301 y
+   else
+      define_bool CONFIG_ARCH_EP9301 n
+   fi
+
+   if [ "$CONFIG_ARCH_EDB9302" = "y" ]; then
+      define_bool CONFIG_ARCH_EP9302 y
+   else
+      define_bool CONFIG_ARCH_EP9302 n
+   fi
+
+   if [ "$CONFIG_ARCH_EDB9312" = "y" ]; then
+      define_bool CONFIG_ARCH_EP9312 y
+   else
+      define_bool CONFIG_ARCH_EP9312 n
+   fi
+
+   if [ "$CONFIG_ARCH_EDB9315" = "y" ]; then
+      define_bool CONFIG_ARCH_EP9315 y
+   else
+      define_bool CONFIG_ARCH_EP9315 n
+   fi
+
+   endmenu
+else
+   define_bool CONFIG_ARCH_EP9301 n
+   define_bool CONFIG_ARCH_EP9302 n
+   define_bool CONFIG_ARCH_EP9312 n
+   define_bool CONFIG_ARCH_EP9315 n
+   define_bool CONFIG_ARCH_EDB9301 n
+   define_bool CONFIG_ARCH_EDB9302 n
+   define_bool CONFIG_ARCH_EDB9312 n
+   define_bool CONFIG_ARCH_EDB9315 n
+fi
+
 # Definitions to make life easier
 if [ "$CONFIG_ARCH_ARCA5K" = "y" -o \
      "$CONFIG_ARCH_RPC" = "y" ]; then
@@ -189,6 +333,13 @@
    define_bool CONFIG_ARCH_ACORN n
 fi
 
+if [ "$CONFIG_ARCH_EP9312" = "y" ]; then
+   comment 'EP9312 Implementation Options'
+   choice 'EP9312 Board Type' \
+      "EP9312  CONFIG_MACH_EP9312 \
+       IPD    CONFIG_MACH_IPD" EP9312
+fi
+
 #####################################################################
 # Footbridge support
 if [ "$CONFIG_ARCH_CO285" = "y" -o \
@@ -217,6 +368,23 @@
 fi
 
 #####################################################################
+# EP93xx Graphics accelerator support
+  if [ "$CONFIG_ARCH_EP9315" = "y" ]; then
+    define_bool CONFIG_EP93XX_GRAPHICS y
+else
+    define_bool CONFIG_EP93XX_GRAPHICS n
+  fi
+  
+# EP93xx MaverickCrunch support
+if [ "$CONFIG_ARCH_EP9302" = "y" -o \
+     "$CONFIG_ARCH_EP9312" = "y" -o \
+     "$CONFIG_ARCH_EP9315" = "y" ]; then
+    bool 'EP93xx MaverickCrunch support' CONFIG_EP93XX_CRUNCH
+else
+    define_bool CONFIG_EP93XX_CRUNCH n
+fi
+    
+#####################################################################
 # SA1111 support
 if [ "$CONFIG_ASSABET_NEPONSET" = "y" -o \
      "$CONFIG_SA1100_ACCELENT" = "y" -o \
@@ -300,6 +468,7 @@
 
 # ARM920T
 if [ "$CONFIG_ARCH_MX1ADS" = "y" -o \
+     "$CONFIG_ARCH_EP93XX" = "y" -o \
      "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
    define_bool CONFIG_CPU_ARM920T y
 else
@@ -313,7 +482,7 @@
 
 
 # ARM922T
-if [ "$CONFIG_ARCH_CAMELOT" = "y" ]; then
+if [ "$CONFIG_ARCH_CAMELOT" = "y" -o "$CONFIG_ARCH_KS8695" = "y" ]; then
    define_bool CONFIG_CPU_ARM922T y
    define_bool CONFIG_PLD y
 else
@@ -345,7 +514,8 @@
 # SA110
 if [ "$CONFIG_ARCH_EBSA110"  = "y" -o "$CONFIG_FOOTBRIDGE" = "y" -o \
      "$CONFIG_ARCH_TBOX"     = "y" -o "$CONFIG_ARCH_SHARK" = "y" -o \
-     "$CONFIG_ARCH_NEXUSPCI" = "y" -o "$CONFIG_ARCH_ANAKIN" = "y" ]; then
+     "$CONFIG_ARCH_NEXUSPCI" = "y" -o "$CONFIG_ARCH_ANAKIN" = "y" -o \
+     "$CONFIG_ARCH_IXP1200" = "y" ]; then
    define_bool CONFIG_CPU_SA110 y
 else
    if [ "$CONFIG_ARCH_RPC" = "y" ]; then
@@ -378,14 +548,30 @@
      "$CONFIG_ARCH_INTEGRATOR" = "y" -o "$CONFIG_ARCH_SA1100"   = "y" -o \
      "$CONFIG_ARCH_L7200"      = "y" -o "$CONFIG_ARCH_ANAKIN"	= "y" -o \
      "$CONFIG_ARCH_CAMELOT"    = "y" -o "$CONFIG_ARCH_MX1ADS"   = "y" -o \
-     "$CONFIG_ARCH_OMAHA"      = "y" -o "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
+     "$CONFIG_ARCH_EP93XX"     = "y" -o \
+     "$CONFIG_ARCH_OMAHA"      = "y" -o "$CONFIG_ARCH_AT91RM9200" = "y" -o \
+     "$CONFIG_ARCH_KS8695"     = "y" ]; then
    define_bool CONFIG_CPU_32v4 y
 else
    define_bool CONFIG_CPU_32v4 n
 fi
+# XScale
+if [ "$CONFIG_ARCH_IOP3XX" = "y" -o "$CONFIG_ARCH_ADIFCC" = "y" -o \
+     "$CONFIG_ARCH_IXP425" = "y" -o "$CONFIG_ARCH_IXP2000" = "y" ]; then
+  define_bool CONFIG_CPU_32v5 y
+  define_bool CONFIG_CPU_XSCALE y
+  define_bool CONFIG_ARM_THUMB y
+fi
 
 comment 'Processor Features'
 
+if [ "$CONFIG_CPU_XSCALE" = "y" ]; then
+   bool 'Use XScale PMU as timer source' CONFIG_XSCALE_PMU_TIMER
+   bool 'Workaround for XScale Cache Errata(see help)' CONFIG_XSCALE_CACHE_ERRATA
+   bool 'Support for BDI2000 JTAG Debugger' CONFIG_XSCALE_BDI2000
+   bool 'Support Fast Address-Space Switching (FASS)' CONFIG_ARM_FASS
+fi
+
 if [ "$CONFIG_CPU_ARM720T" = "y" -o "$CONFIG_CPU_ARM920T" = "y" -o \
      "$CONFIG_CPU_ARM922T" = "y" -o "$CONFIG_CPU_ARM926T" = "y" -o \
      "$CONFIG_CPU_ARM1020" = "y" -o "$CONFIG_CPU_ARM1026" = "y" ]; then
@@ -396,7 +582,7 @@
      "$CONFIG_CPU_ARM1026" = "y" ]; then
    bool 'Disable I-Cache' CONFIG_CPU_ICACHE_DISABLE
    bool 'Disable D-Cache' CONFIG_CPU_DCACHE_DISABLE
-   if [ "$CONFIG_CPU_DISABLE_DCACHE" = "n" ]; then
+   if [ "$CONFIG_CPU_DCACHE_DISABLE" = "n" ]; then
       bool 'Force write through D-cache' CONFIG_CPU_DCACHE_WRITETHROUGH
    fi
 fi
@@ -420,6 +606,8 @@
    define_bool CONFIG_DISCONTIGMEM n
 fi
 
+bool 'Generate big endian kernel' CONFIG_CPU_BIG_ENDIAN
+
 endmenu
 
 mainmenu_option next_comment
@@ -428,17 +616,36 @@
 # Now handle the bus types
 if [ "$CONFIG_ARCH_FTVPCI" = "y" -o \
      "$CONFIG_ARCH_SHARK" = "y" -o \
-     "$CONFIG_FOOTBRIDGE_HOST" = "y" ]; then
+     "$CONFIG_FOOTBRIDGE_HOST" = "y" -o \
+     "$CONFIG_ARCH_IXP1200" = "y" -o \
+     "$CONFIG_ARCH_IOP3XX" = "y" -o \
+     "$CONFIG_ARCH_BRH" = "y"  -o \
+     "$CONFIG_ARCH_IXP425" = "y" -o \
+     "$CONFIG_ARCH_IXP2000" = "y" ]; then
    define_bool CONFIG_PCI y
 else
    if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
       bool 'PCI support' CONFIG_PCI_INTEGRATOR
       define_bool CONFIG_PCI $CONFIG_PCI_INTEGRATOR
    else
-      define_bool CONFIG_PCI n
+      if [ "$CONFIG_ARCH_KS8695" = "y" ]; then
+         bool 'PCI support' CONFIG_PCI_KS8695P
+         define_bool CONFIG_PCI $CONFIG_PCI_KS8695P
+         define_bool CONFIG_ARCH_KS8695P $CONFIG_PCI_KS8695P
+      else 
+         define_bool CONFIG_PCI n
+      fi
    fi
 fi
 
+if [ "$CONFIG_ARCH_IXP1200" = "y" -o \
+     "$CONFIG_ARCH_IOP3XX" = "y" -o \
+     "$CONFIG_ARCH_BRH" = "y"  -o \
+     "$CONFIG_ARCH_IXP425" = "y" -o \
+     "$CONFIG_ARCH_IXP2000" = "y" ]; then
+   define_bool CONFIG_PCI_AUTOCONFIG y
+fi
+
 if [ "$CONFIG_FOOTBRIDGE_HOST" = "y" -o \
      "$CONFIG_ARCH_SHARK" = "y" -o \
      "$CONFIG_ARCH_CLPS7500" = "y" -o \
@@ -446,6 +653,8 @@
      "$CONFIG_ARCH_EBSA110" = "y" -o \
      "$CONFIG_ARCH_CDB89712" = "y" -o \
      "$CONFIG_ARCH_EDB7211" = "y" -o \
+     "$CONFIG_ARCH_EDB7312" = "y" -o \
+     "$CONFIG_ARCH_EP9315" = "y" -o \
      "$CONFIG_ARCH_SA1100" = "y" ]; then
    define_bool CONFIG_ISA y
 else
@@ -459,6 +668,18 @@
    define_bool CONFIG_ISA_DMA n
 fi
 
+if [ "$CONFIG_ADVANCED_OPTIONS" = "y" -a  "$CONFIG_CPU_32" = "y" -a \
+     "$CONFIG_DISCONTIGMEM" != "y" ]; then
+  bool "Set custom kernel base address" CONFIG_KERNEL_START_BOOL
+  if [ "$CONFIG_KERNEL_START_BOOL" = "y" ]; then
+    hex "  Virtual address of kernel base" CONFIG_KERNEL_START 0xc0000000
+  fi
+fi
+
+if [ "$CONFIG_KERNEL_START_BOOL" != "y" ]; then
+  define_hex CONFIG_KERNEL_START 0xc0000000
+fi
+
 # Compressed boot loader in ROM.  Yes, we really want to ask about
 # TEXT and BSS so we preserve their values in the config files.
 bool 'Compressed boot loader in ROM/flash' CONFIG_ZBOOT_ROM
@@ -466,7 +687,8 @@
 hex 'Compressed ROM boot loader BSS address' CONFIG_ZBOOT_ROM_BSS 0
 
 if [ "$CONFIG_ARCH_SA1100" = "y" -o \
-     "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
+     "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
+     "$CONFIG_ARCH_KS8695" = "y" ]; then
    dep_bool 'Support CPU clock change (EXPERIMENTAL)' CONFIG_CPU_FREQ $CONFIG_EXPERIMENTAL
 fi
 
@@ -500,9 +722,16 @@
 tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
 bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER
 dep_bool 'Power Management support (experimental)' CONFIG_PM $CONFIG_EXPERIMENTAL
 dep_tristate 'RISC OS personality' CONFIG_ARTHUR $CONFIG_CPU_32
-string 'Default kernel command string' CONFIG_CMDLINE ""
+bool 'Enable default kernel command string' CONFIG_CMDLINE_BOOL
+if [ "$CONFIG_CMDLINE_BOOL" = "y" ] ; then
+	bool 'Force default kernel command string' CONFIG_CMDLINE_FORCE
+	string 'Default kernel command string' CONFIG_CMDLINE ""
+else
+	define_string CONFIG_CMDLINE ""
+fi
 
 if [ "$CONFIG_ARCH_NETWINDER" = "y" -o  \
      "$CONFIG_ARCH_EBSA110" = "y" -o    \
@@ -510,21 +739,29 @@
      "$CONFIG_ARCH_FTVPCI" = "y" -o     \
      "$CONFIG_ARCH_SHARK" = "y" -o      \
      "$CONFIG_ARCH_CO285" = "y" -o      \
+     "$CONFIG_ARCH_IXP1200"   = "y" -o	\
      "$CONFIG_ARCH_SA1100" = "y" -o     \
      "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
+     "$CONFIG_ARCH_KS8695" = "y" -o	\
      "$CONFIG_ARCH_CDB89712" = "y" -o   \
      "$CONFIG_ARCH_P720T" = "y" -o	\
-     "$CONFIG_ARCH_OMAHA" = "y" ]; then
+     "$CONFIG_ARCH_OMAHA" = "y" -o	\
+     "$CONFIG_ARCH_AT91RM9200" = "y" -o	\
+     "$CONFIG_ARCH_IXDP2800" = "y" ]; then
    bool 'Timer and CPU usage LEDs' CONFIG_LEDS
    if [ "$CONFIG_LEDS" = "y" ]; then
       if [ "$CONFIG_ARCH_NETWINDER" = "y" -o  \
 	   "$CONFIG_ARCH_EBSA285" = "y" -o    \
 	   "$CONFIG_ARCH_SHARK" = "y" -o      \
 	   "$CONFIG_ARCH_CO285" = "y" -o      \
+	   "$CONFIG_ARCH_IXP1200" = "y" -o    \
 	   "$CONFIG_ARCH_SA1100" = "y" -o     \
            "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
+           "$CONFIG_ARCH_KS8695" = "y" -o     \
 	   "$CONFIG_ARCH_P720T" = "y" -o      \
-	   "$CONFIG_ARCH_OMAHA" = "y" ]; then
+	   "$CONFIG_ARCH_OMAHA" = "y" -o      \
+	   "$CONFIG_ARCH_AT91RM9200" = "y" -o \
+	   "$CONFIG_ARCH_IXDP2800" = "y" ]; then
          bool '  Timer LED' CONFIG_LEDS_TIMER
          bool '  CPU usage LED' CONFIG_LEDS_CPU
       fi
@@ -545,13 +782,7 @@
 endmenu
 
 source drivers/parport/Config.in
-
-if [ "$CONFIG_ALIGNMENT_TRAP" = "y" ]; then
-  source drivers/mtd/Config.in
-else
-  define_bool CONFIG_MTD n
-fi
-
+source drivers/mtd/Config.in
 source drivers/pnp/Config.in
 source drivers/block/Config.in
 source drivers/md/Config.in
@@ -674,6 +905,9 @@
 
 if [ "$CONFIG_ARCH_ACORN" = "y" -o \
      "$CONFIG_ARCH_CLPS7500" = "y" -o \
+     "$CONFIG_ARCH_EP7212" = "y" -o \
+     "$CONFIG_ARCH_EP7312" = "y" -o \
+     "$CONFIG_ARCH_EP93XX" = "y" -o \
      "$CONFIG_ARCH_RISCSTATION" = "y" -o \
      "$CONFIG_ARCH_TBOX" = "y" -o \
      "$CONFIG_ARCH_SHARK" = "y" -o \
@@ -729,9 +963,53 @@
 dep_bool '  Kernel low-level debugging functions' CONFIG_DEBUG_LL $CONFIG_DEBUG_KERNEL
 dep_bool '    Kernel low-level debugging messages via footbridge serial port' CONFIG_DEBUG_DC21285_PORT $CONFIG_DEBUG_LL $CONFIG_FOOTBRIDGE
 dep_bool '    Kernel low-level debugging messages via UART2' CONFIG_DEBUG_CLPS711X_UART2 $CONFIG_DEBUG_LL $CONFIG_ARCH_CLPS711X
-
+dep_bool '  KGDB support' CONFIG_KGDB $CONFIG_DEBUG_KERNEL
+dep_bool '     KGB over serial port' CONFIG_KGDB_SERIAL $CONFIG_KGDB
+dep_bool '     Console messages over KGDB' CONFIG_KGDB_CONSOLE $CONFIG_KGDB
+dep_bool '     Enable SysRq-D command to invoke kgdb via breakpoint?' CONFIG_KGDB_SYSRQ $CONFIG_MAGIC_SYSRQ $CONFIG_KGDB
+# dep_bool '     Include KGDB thread support' CONFIG_KGDB_THREAD $CONFIG_KGDB
+# dep_bool '     KGDB over ethernet' CONFIG_KGDB_UDP
+dep_bool '     Add additional compile options' CONFIG_KGDB_MORE $CONFIG_KGDB
+if [ "$CONFIG_KGDB_MORE" = "y" ]; then
+   string ' Additional compile options' CONFIG_KGDB_OPTIONS "-O1"
+fi
+if [ "$CONFIG_KGDB_SERIAL" = "y" ]; then
+   if [ "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
+        "$CONFIG_ARCH_IQ80310" = "y" -o \
+        "$CONFIG_ARCH_EDB7312" = "y" -o \
+        "$CONFIG_ARCH_EP9301" = "y" -o \
+        "$CONFIG_ARCH_EP9302" = "y" ]; then
+	choice 'KGDB serial port UART selection' \
+		"0	CONFIG_KGDB_UART0 \
+		 1	CONFIG_KGDB_UART1" 1
+   fi
+   if [ "$CONFIG_ARCH_EP9312" = "y" -o \
+        "$CONFIG_ARCH_EP9315" = "y" ]; then
+	choice 'KGDB serial port UART selection' \
+		"0	CONFIG_KGDB_UART0 \
+		 1	CONFIG_KGDB_UART1 \
+		 2	CONFIG_KGDB_UART2" 2
+   fi
+   if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
+	choice 'KGDB serial port UART selection' \
+		"1	CONFIG_KGDB_UART1 \
+		 2	CONFIG_KGDB_UART2 \
+		 3	CONFIG_KGDB_UART3" 1
+   fi
+   if [ "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
+        "$CONFIG_ARCH_IQ80310" = "y" -o \
+        "$CONFIG_ARCH_SA1100" = "y" -o \
+        "$CONFIG_ARCH_EDB7312" = "y" -o \
+        "$CONFIG_ARCH_EP93XX" = "y" ]; then
+	choice 'KGDB serial port BAUD rate selection' \
+		"9600	CONFIG_KGDB_9600BAUD \
+		 19200	CONFIG_KGDB_19200BAUD \
+		 38400	CONFIG_KGDB_38400BAUD \
+		 57600	CONFIG_KGDB_57600BAUD \
+		 115200	CONFIG_KGDB_115200BAUD" 9600
+   fi
+fi
 int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
-
 endmenu
 
 source crypto/Config.in
diff -urN linux-2.4.29/arch/arm/def-configs/adi_evb linux-2.4.29-uc1/arch/arm/def-configs/adi_evb
--- linux-2.4.29/arch/arm/def-configs/adi_evb	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/adi_evb	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,791 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+CONFIG_ARCH_ADIFCC=y
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP1200 is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+
+#
+# ADI FCC Implementation Options
+#
+CONFIG_ARCH_ADI_EVB=y
+# CONFIG_ARCH_BRH is not set
+CONFIG_XSCALE_PMU_TIMER=y
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+
+#
+# Processor Type
+#
+# CONFIG_CPU_32v3 is not set
+# CONFIG_CPU_32v4 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+CONFIG_CPU_32v4=y
+CONFIG_CPU_XSCALE=y
+CONFIG_ARM_THUMB=y
+CONFIG_XSCALE_PMU_TIMER=y
+# CONFIG_XSCALE_CACHE_ERRATA is not set
+# CONFIG_XSCALE_PMU is not set
+CONFIG_ARM_THUMB=y
+# CONFIG_DISCONTIGMEM is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+# CONFIG_3G_KERNEL is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/mtdblock1"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_BOOTLDR_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+CONFIG_MTD_ADI_EVB=y
+# CONFIG_MTD_BRH is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_IXP1200 is not set
+# CONFIG_SERIAL_IXP1200_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.29/arch/arm/def-configs/at91rm9200dk linux-2.4.29-uc1/arch/arm/def-configs/at91rm9200dk
--- linux-2.4.29/arch/arm/def-configs/at91rm9200dk	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-uc1/arch/arm/def-configs/at91rm9200dk	2005-06-14 02:11:02.000000000 +0100
@@ -1,5 +1,5 @@
 #
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
 #
 CONFIG_ARM=y
 # CONFIG_EISA is not set
@@ -21,7 +21,7 @@
 # Loadable module support
 #
 CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
+CONFIG_MODVERSIONS=y
 CONFIG_KMOD=y
 
 #
@@ -43,91 +43,38 @@
 # CONFIG_ARCH_RISCSTATION is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_SHARK is not set
-CONFIG_ARCH_AT91RM9200=y
+CONFIG_ARCH_AT91RM9200DK=y
 
 #
 # Archimedes/A5000 Implementations
 #
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
 
 #
-# Footbridge Implementations
+# Archimedes/A5000 Implementations (select only ONE)
 #
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
 
 #
-# SA11x0 Implementations
+# Footbridge Implementations
 #
-# CONFIG_SA1100_ACCELENT is not set
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSAGC is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_ADSBITSYPLUS is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_H3XXX is not set
-# CONFIG_H3600_SLEEVE is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_HACKKIT is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_SIMPUTER is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_USB is not set
-# CONFIG_SA1100_USB_NETLINK is not set
-# CONFIG_SA1100_USB_CHAR is not set
-# CONFIG_SA1100_SSP is not set
 
 #
-# AT91RM9200 Implementations
+# SA11x0 Implementations
 #
-CONFIG_ARCH_AT91RM9200DK=y
+# CONFIG_SA1100_H3XXX is not set
 
 #
 # CLPS711X/EP721X Implementations
 #
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_GUIDEA07 is not set
-# CONFIG_ARCH_P720T is not set
 # CONFIG_ARCH_EP7211 is not set
 # CONFIG_ARCH_EP7212 is not set
 # CONFIG_ARCH_ACORN is not set
 # CONFIG_FOOTBRIDGE is not set
 # CONFIG_FOOTBRIDGE_HOST is not set
 # CONFIG_FOOTBRIDGE_ADDIN is not set
+
+#
+# Processor Type
+#
 CONFIG_CPU_32=y
 # CONFIG_CPU_26 is not set
 # CONFIG_CPU_ARM610 is not set
@@ -143,6 +90,10 @@
 # CONFIG_CPU_SA1100 is not set
 # CONFIG_CPU_32v3 is not set
 CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
 # CONFIG_ARM_THUMB is not set
 # CONFIG_CPU_ICACHE_DISABLE is not set
 # CONFIG_CPU_DCACHE_DISABLE is not set
@@ -163,16 +114,20 @@
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
 CONFIG_FPE_NWFPE=y
 # CONFIG_FPE_FASTFPE is not set
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_AOUT=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 # CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20210000,3145728 root=/dev/ram rw"
+CONFIG_CMDLINE="console=ttyS4,115200  mem=32M root=/dev/ram rw"
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -187,9 +142,10 @@
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_PARTITIONS is not set
 # CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
@@ -199,48 +155,35 @@
 # RAM/ROM/Flash chip drivers
 #
 CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
+# CONFIG_MTD_JEDECPROBE is not set
 CONFIG_MTD_GEN_PROBE=y
 # CONFIG_MTD_CFI_ADV_OPTIONS is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
 # CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
 
 #
 # Mapping drivers for chip access
 #
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=10000000
-CONFIG_MTD_PHYSMAP_LEN=200000
-CONFIG_MTD_PHYSMAP_BUSWIDTH=2
+# CONFIG_MTD_PHYSMAP is not set
 # CONFIG_MTD_NORA is not set
 # CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-# CONFIG_MTD_SA1100 is not set
-# CONFIG_MTD_DC21285 is not set
 # CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_EPXA is not set
-# CONFIG_MTD_AUTCPU12 is not set
 # CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_PCI is not set
 
 #
 # Self-contained MTD device drivers
 #
-# CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
-CONFIG_MTD_AT91_DATAFLASH=y
-# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
 # CONFIG_MTD_MTDRAM is not set
 # CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
 # CONFIG_MTD_DOC1000 is not set
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
@@ -249,28 +192,17 @@
 #
 # NAND Flash Device Drivers
 #
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ECC=y
-# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-CONFIG_MTD_AT91_SMARTMEDIA=y
+# CONFIG_MTD_NAND is not set
 
 #
 # Plug and Play configuration
 #
 # CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
 
 #
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -281,19 +213,11 @@
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
 
 #
 # Networking options
 #
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
+# CONFIG_PACKET is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -314,13 +238,16 @@
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
+
+#
+#
+#
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
 
 #
 # Appletalk devices
 #
-# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -345,72 +272,7 @@
 #
 # Network device support
 #
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_ARM_AM79C961A is not set
-# CONFIG_ARM_CIRRUS is not set
-CONFIG_AT91_ETHER=y
-CONFIG_AT91_ETHER_RMII=y
-# CONFIG_SUNLANCE is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
+# CONFIG_NETDEVICES is not set
 
 #
 # Amateur Radio support
@@ -437,10 +299,6 @@
 # I2O device support
 #
 # CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
 
 #
 # ISDN subsystem
@@ -451,114 +309,68 @@
 # Input core support
 #
 # CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 
 #
 # Character devices
 #
 # CONFIG_VT is not set
 # CONFIG_SERIAL is not set
-# CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_AT91_SPIDEV=y
 
 #
 # Serial drivers
 #
-# CONFIG_SERIAL_ANAKIN is not set
-# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-# CONFIG_SERIAL_SA1100 is not set
-# CONFIG_SERIAL_SA1100_CONSOLE is not set
-# CONFIG_SERIAL_OMAHA is not set
-# CONFIG_SERIAL_OMAHA_CONSOLE is not set
-CONFIG_SERIAL_AT91=y
-CONFIG_SERIAL_AT91_CONSOLE=y
 # CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
 
 #
 # I2C support
 #
-CONFIG_I2C=y
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-CONFIG_I2C_AT91=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_PROC=y
-# CONFIG_I2C_DS1307 is not set
+# CONFIG_I2C is not set
 
 #
 # L3 serial bus support
 #
 # CONFIG_L3 is not set
-# CONFIG_L3_ALGOBIT is not set
-# CONFIG_L3_BIT_SA1100_GPIO is not set
-# CONFIG_L3_SA1111 is not set
+
+#
+# Other L3 adapters
+#
 # CONFIG_BIT_SA1100_GPIO is not set
 
 #
 # Mice
 #
 # CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
 
 #
 # Joysticks
 #
 # CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
 # CONFIG_QIC02_TAPE is not set
 
 #
 # Watchdog Cards
 #
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-# CONFIG_ACQUIRE_WDT is not set
-# CONFIG_ADVANTECH_WDT is not set
-# CONFIG_ALIM7101_WDT is not set
-# CONFIG_SC520_WDT is not set
-# CONFIG_PCWATCHDOG is not set
-# CONFIG_21285_WATCHDOG is not set
-# CONFIG_977_WATCHDOG is not set
-# CONFIG_SA1100_WATCHDOG is not set
-# CONFIG_OMAHA_WATCHDOG is not set
-CONFIG_AT91_WATCHDOG=y
-# CONFIG_EUROTECH_WDT is not set
-# CONFIG_IB700_WDT is not set
-# CONFIG_WAFER_WDT is not set
-# CONFIG_I810_TCO is not set
-# CONFIG_MIXCOMWD is not set
-# CONFIG_60XX_WDT is not set
-# CONFIG_SC1200_WDT is not set
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_W83877F_WDT is not set
-# CONFIG_WDT is not set
-# CONFIG_WDTPCI is not set
-# CONFIG_MACHZ_WDT is not set
+# CONFIG_WATCHDOG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-CONFIG_AT91_RTC=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -582,20 +394,13 @@
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
-# CONFIG_JBD_DEBUG is not set
 # CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
@@ -603,58 +408,52 @@
 # CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
 # CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
 CONFIG_DEVFS_FS=y
 CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVFS_DEBUG=y
+CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_ROMFS_FS=y
 CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
 
 #
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
 # CONFIG_INTERMEZZO_FS is not set
-# CONFIG_NFS_FS is not set
+CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
-# CONFIG_ROOT_NFS is not set
+CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-# CONFIG_SUNRPC is not set
-# CONFIG_LOCKD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
 # CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
 #
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
@@ -662,91 +461,11 @@
 # Multimedia Capabilities Port drivers
 #
 # CONFIG_MCP is not set
-# CONFIG_MCP_SA1100 is not set
-# CONFIG_MCP_UCB1200 is not set
-# CONFIG_MCP_UCB1200_AUDIO is not set
-# CONFIG_MCP_UCB1200_TS is not set
 
 #
 # USB support
 #
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_LONG_TIMEOUT is not set
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-# CONFIG_USB_OHCI_SA1111 is not set
-CONFIG_USB_OHCI_AT91=y
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_BLUETOOTH is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_HID is not set
-# CONFIG_USB_HIDINPUT is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_BRLVGER is not set
+# CONFIG_USB is not set
 
 #
 # Bluetooth support
@@ -759,14 +478,4 @@
 CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_ERRORS is not set
-CONFIG_DEBUG_LL=y
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
+# CONFIG_DEBUG_KERNEL is not set
diff -urN linux-2.4.29/arch/arm/def-configs/badge4 linux-2.4.29-uc1/arch/arm/def-configs/badge4
--- linux-2.4.29/arch/arm/def-configs/badge4	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-uc1/arch/arm/def-configs/badge4	2005-06-14 02:11:02.000000000 +0100
@@ -797,7 +797,6 @@
 # CONFIG_RADIO_MIROPCM20 is not set
 # CONFIG_RADIO_MIROPCM20_RDS is not set
 # CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_SF16FMR2 is not set
 # CONFIG_RADIO_TERRATEC is not set
 # CONFIG_RADIO_TRUST is not set
 # CONFIG_RADIO_TYPHOON is not set
diff -urN linux-2.4.29/arch/arm/def-configs/brh linux-2.4.29-uc1/arch/arm/def-configs/brh
--- linux-2.4.29/arch/arm/def-configs/brh	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/brh	2005-06-14 02:11:01.000000000 +0100
@@ -0,0 +1,763 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_ADVANCED_OPTIONS is not set
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+CONFIG_ARCH_ADIFCC=y
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP1200 is not set
+# CONFIG_ARCH_IXP425 is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+
+#
+# ADI FCC Implementation Options
+#
+# CONFIG_ARCH_ADI_EVB is not set
+CONFIG_ARCH_BRH=y
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+# CONFIG_CPU_32v4 is not set
+CONFIG_CPU_32v4=y
+CONFIG_CPU_XSCALE=y
+CONFIG_ARM_THUMB=y
+
+#
+# Processor Features
+#
+# CONFIG_XSCALE_PMU_TIMER is not set
+# CONFIG_XSCALE_CACHE_ERRATA is not set
+# CONFIG_XSCALE_BDI2000 is not set
+# CONFIG_DISCONTIGMEM is not set
+CONFIG_CPU_BIG_ENDIAN=y
+
+#
+# General setup
+#
+CONFIG_PCI=y
+CONFIG_PCI_AUTOCONFIG=y
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+CONFIG_KERNEL_START=0xc0000000
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp initrd=0xc0800000,4M"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_IQ80321 is not set
+# CONFIG_MTD_FORTUNET is not set
+CONFIG_MTD_BRH=y
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_IXP425 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=m
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_IXP1200 is not set
+# CONFIG_SERIAL_IXP1200_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.29/arch/arm/def-configs/coyote linux-2.4.29-uc1/arch/arm/def-configs/coyote
--- linux-2.4.29/arch/arm/def-configs/coyote	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/coyote	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,796 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_ADVANCED_OPTIONS is not set
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ADIFCC is not set
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP1200 is not set
+# CONFIG_ARCH_IXP2000 is not set
+CONFIG_ARCH_IXP425=y
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# IXP425 Implementation Options
+#
+
+#
+# IXP425 Board Types
+#
+# CONFIG_ARCH_IXDP425 is not set
+# CONFIG_ARCH_IXCDP1100 is not set
+# CONFIG_ARCH_PRPMC1100 is not set
+CONFIG_ARCH_ADI_COYOTE=y
+
+#
+# IXP425 Options
+#
+CONFIG_IXP425_PCI_ERRATA=y
+# CONFIG_XSCALE_PMU_TIMER is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+# CONFIG_CPU_32v4 is not set
+CONFIG_CPU_32v5=y
+CONFIG_CPU_XSCALE=y
+CONFIG_ARM_THUMB=y
+
+#
+# Processor Features
+#
+# CONFIG_XSCALE_PMU_TIMER is not set
+# CONFIG_XSCALE_CACHE_ERRATA is not set
+# CONFIG_XSCALE_BDI2000 is not set
+# CONFIG_DISCONTIGMEM is not set
+CONFIG_CPU_BIG_ENDIAN=y
+
+#
+# General setup
+#
+CONFIG_PCI=y
+CONFIG_PCI_AUTOCONFIG=y
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+CONFIG_KERNEL_START=0xc0000000
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttyS1,115200 root=/dev/nfs ip=bootp mem=32M@0x00000000"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IOP3XX is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_BRH is not set
+# CONFIG_MTD_EPXA is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+CONFIG_MTD_IXP425=y
+# CONFIG_MTD_IXP2000 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=m
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_IXP1200 is not set
+# CONFIG_SERIAL_IXP1200_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_AT91US3 is not set
+# CONFIG_SERIAL_AT91US3_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_IXP2000_SLAVE is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_PHILIPSPAR is not set
+# CONFIG_I2C_ELV is not set
+# CONFIG_I2C_VELLEMAN is not set
+# CONFIG_I2C_GUIDE is not set
+CONFIG_I2C_IXP425=y
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PROC=y
+# CONFIG_I2C_DS1307 is not set
+CONFIG_PCF8549C_NVRAM=y
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.29/arch/arm/def-configs/csb337 linux-2.4.29-uc1/arch/arm/def-configs/csb337
--- linux-2.4.29/arch/arm/def-configs/csb337	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/csb337	2005-06-14 02:11:02.000000000 +0100
@@ -0,0 +1,760 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+CONFIG_ARCH_AT91RM9200=y
+
+#
+# Archimedes/A5000 Implementations
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# AT91RM9200 Implementations
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+CONFIG_MACH_CSB337=y
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_PLD is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+CONFIG_CPU_ARM920T=y
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1020E is not set
+# CONFIG_CPU_ARM1022 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_DISCONTIGMEM is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="mem=32M console=ttyS0,38400 initrd=0x20800000,10M root=/dev/ram rw"
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_RAM is not set
+CONFIG_MTD_ROM=y
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=10000000
+CONFIG_MTD_PHYSMAP_LEN=200000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=2
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_CEIVA is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PCMCIA is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+CONFIG_MTD_AT91_DATAFLASH=y
+# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_AT91_SMARTMEDIA is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_CISS_MONITOR_THREAD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+
+#
+#    SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+CONFIG_AT91_ETHER=y
+# CONFIG_AT91_ETHER_RMII is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_INPUT_MX1TS is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_AT91_SPIDEV=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+CONFIG_SERIAL_AT91=y
+CONFIG_SERIAL_AT91_CONSOLE=y
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_I2C_AT91=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PROC=y
+CONFIG_I2C_DS1307=y
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_ALIM1535_WDT is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_21285_WATCHDOG is not set
+# CONFIG_977_WATCHDOG is not set
+# CONFIG_SA1100_WATCHDOG is not set
+# CONFIG_EPXA_WATCHDOG is not set
+# CONFIG_OMAHA_WATCHDOG is not set
+CONFIG_AT91_WATCHDOG=y
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_WAFER_WDT is not set
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_SCx200_WDT is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_MACHZ_WDT is not set
+# CONFIG_AMD7XX_TCO is not set
+# CONFIG_SCx200 is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_AT91_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+
+#
+# Direct Rendering Manager (XFree86 DRI support)
+#
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Support for USB gadgets
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
+
+#
+# Library routines
+#
+CONFIG_CRC32=y
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.29/arch/arm/def-configs/edb7312 linux-2.4.29-uc1/arch/arm/def-configs/edb7312
--- linux-2.4.29/arch/arm/def-configs/edb7312	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/edb7312	2005-06-14 02:11:01.000000000 +0100
@@ -0,0 +1,912 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+CONFIG_ARCH_CLPS711X=y
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200 is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# AT91RM9200 Implementations
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+CONFIG_ARCH_EDB7312=y
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+CONFIG_ARCH_EP7312=y
+# CONFIG_EP72XX_ROM_BOOT is not set
+# CONFIG_ARCH_EP9301 is not set
+# CONFIG_ARCH_EP9302 is not set
+# CONFIG_ARCH_EP9312 is not set
+# CONFIG_ARCH_EP9315 is not set
+# CONFIG_ARCH_EDB9301 is not set
+# CONFIG_ARCH_EDB9302 is not set
+# CONFIG_ARCH_EDB9312 is not set
+# CONFIG_ARCH_EDB9315 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+# CONFIG_EP93XX_GRAPHICS is not set
+# CONFIG_EP93XX_CRUNCH is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+CONFIG_CPU_ARM720T=y
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_DISCONTIGMEM is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="root=/dev/ram"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_CLPS7500 is not set
+CONFIG_MTD_EDB7312=y
+# CONFIG_MTD_EDB9301 is not set
+# CONFIG_MTD_EDB9302 is not set
+# CONFIG_MTD_EDB9312 is not set
+# CONFIG_MTD_EDB9315 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_CEIVA is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PCMCIA is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_NAND_EDB7312 is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=6144
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_STATS is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+CONFIG_CS89x0=y
+# CONFIG_TULIP is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_EEPRO100_PIO is not set
+# CONFIG_E100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_SUNDANCE_MMIO is not set
+# CONFIG_TC35815 is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_BLK_DEV_IDE_EP93XX is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_SII is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Synchronous Serial Interface
+#
+# CONFIG_SSI is not set
+
+#
+# SSI Bus Drivers
+#
+# CONFIG_SSI_CLPS711X is not set
+
+#
+# SSI Device Drivers
+#
+# CONFIG_SSI_JUNO is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_MX1TS is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+CONFIG_SERIAL_CLPS711X=y
+CONFIG_SERIAL_CLPS711X_CONSOLE=y
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_AT91 is not set
+# CONFIG_SERIAL_AT91_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+CONFIG_EDB7312_TS=y
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_ACORN is not set
+# CONFIG_FB_EP93XX is not set
+# CONFIG_FB_ANAKIN is not set
+# CONFIG_FB_CLPS711X is not set
+CONFIG_FB_EDB7312=y
+# CONFIG_FB_EDB7312_16BPP is not set
+# CONFIG_FB_SA1100 is not set
+# CONFIG_FB_DBMX1 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB12=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_VTX_6x8=y
+CONFIG_FONT_VTX_4x8=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+CONFIG_USB_EDB7312=y
+CONFIG_USB=y
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
+# CONFIG_KGDB is not set
+# CONFIG_KGDB_SERIAL is not set
+# CONFIG_KGDB_CONSOLE is not set
+# CONFIG_KGDB_SYSRQ is not set
+# CONFIG_KGDB_MORE is not set
+
+#
+# Library routines
+#
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff -urN linux-2.4.29/arch/arm/def-configs/edb9301 linux-2.4.29-uc1/arch/arm/def-configs/edb9301
--- linux-2.4.29/arch/arm/def-configs/edb9301	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/edb9301	2005-06-14 02:11:02.000000000 +0100
@@ -0,0 +1,816 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+CONFIG_ARCH_EP93XX=y
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200 is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# AT91RM9200 Implementations
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_EDB7312 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_EP7312 is not set
+
+#
+# EP93xx Implementations
+#
+CONFIG_ARCH_EDB9301=y
+# CONFIG_ARCH_EDB9302 is not set
+# CONFIG_ARCH_EDB9312 is not set
+# CONFIG_ARCH_EDB9315 is not set
+CONFIG_ARCH_EP9301=y
+# CONFIG_ARCH_EP9302 is not set
+# CONFIG_ARCH_EP9312 is not set
+# CONFIG_ARCH_EP9315 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+# CONFIG_EP93XX_GRAPHICS is not set
+# CONFIG_EP93XX_CRUNCH is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+CONFIG_CPU_ARM920T=y
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_DISCONTIGMEM is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="root=/dev/ram"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_CLPS7500 is not set
+# CONFIG_MTD_EDB7312 is not set
+CONFIG_MTD_EDB9301=y
+# CONFIG_MTD_EDB9302 is not set
+# CONFIG_MTD_EDB9312 is not set
+# CONFIG_MTD_EDB9315 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_CEIVA is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PCMCIA is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=12288
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_STATS=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+CONFIG_EP93XX_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_MX1TS is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+CONFIG_SERIAL_EP93XX=y
+CONFIG_SERIAL_EP93XX_CONSOLE=y
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_AT91 is not set
+# CONFIG_SERIAL_AT91_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_ALI5455 is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_OSS=y
+# CONFIG_SOUND_TRACEINIT is not set
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_AD1889 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_ACI_MIXER is not set
+# CONFIG_SOUND_CS4232 is not set
+CONFIG_SOUND_EP93XX=y
+# CONFIG_SOUND_EP93XX_AC97 is not set
+CONFIG_SOUND_EP93XX_I2S=y
+CONFIG_CODEC_CS4271=y
+# CONFIG_CODEC_CS4228A is not set
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_PAS_JOYSTICK is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_AWE32_SYNTH is not set
+# CONFIG_SOUND_KAHLUA is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMFPCI is not set
+# CONFIG_SOUND_YMFPCI_LEGACY is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
+# CONFIG_KGDB is not set
+# CONFIG_KGDB_SERIAL is not set
+# CONFIG_KGDB_CONSOLE is not set
+# CONFIG_KGDB_SYSRQ is not set
+# CONFIG_KGDB_MORE is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.29/arch/arm/def-configs/edb9302 linux-2.4.29-uc1/arch/arm/def-configs/edb9302
--- linux-2.4.29/arch/arm/def-configs/edb9302	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/edb9302	2005-06-14 02:11:02.000000000 +0100
@@ -0,0 +1,920 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+CONFIG_ARCH_EP93XX=y
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200 is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# AT91RM9200 Implementations
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_EDB7312 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_EP7312 is not set
+
+#
+# EP93xx Implementations
+#
+# CONFIG_ARCH_EDB9301 is not set
+CONFIG_ARCH_EDB9302=y
+# CONFIG_ARCH_EDB9312 is not set
+# CONFIG_ARCH_EDB9315 is not set
+# CONFIG_ARCH_EP9301 is not set
+CONFIG_ARCH_EP9302=y
+# CONFIG_ARCH_EP9312 is not set
+# CONFIG_ARCH_EP9315 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+# CONFIG_EP93XX_GRAPHICS is not set
+CONFIG_EP93XX_CRUNCH=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+CONFIG_CPU_ARM920T=y
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_DISCONTIGMEM is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="root=/dev/ram"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_CLPS7500 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_EDB9301 is not set
+CONFIG_MTD_EDB9302=y
+# CONFIG_MTD_EDB9312 is not set
+# CONFIG_MTD_EDB9315 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_CEIVA is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PCMCIA is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=12288
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_STATS=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+CONFIG_EP93XX_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_MX1TS is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+CONFIG_SERIAL_EP93XX=y
+CONFIG_SERIAL_EP93XX_CONSOLE=y
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_AT91 is not set
+# CONFIG_SERIAL_AT91_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_ALI5455 is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_OSS=y
+# CONFIG_SOUND_TRACEINIT is not set
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_AD1889 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_ACI_MIXER is not set
+# CONFIG_SOUND_CS4232 is not set
+CONFIG_SOUND_EP93XX=y
+# CONFIG_SOUND_EP93XX_AC97 is not set
+CONFIG_SOUND_EP93XX_I2S=y
+CONFIG_CODEC_CS4271=y
+# CONFIG_CODEC_CS4228A is not set
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_PAS_JOYSTICK is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_AWE32_SYNTH is not set
+# CONFIG_SOUND_KAHLUA is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMFPCI is not set
+# CONFIG_SOUND_YMFPCI_LEGACY is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+CONFIG_USB_OHCI_EP93XX=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_MIDI is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+# CONFIG_USB_HID is not set
+
+#
+#     Input core support is needed for USB HID input layer or HIDBP support
+#
+# CONFIG_USB_HIDINPUT is not set
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_TIGL is not set
+# CONFIG_USB_BRLVGER is not set
+# CONFIG_USB_LCD is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
+# CONFIG_KGDB is not set
+# CONFIG_KGDB_SERIAL is not set
+# CONFIG_KGDB_CONSOLE is not set
+# CONFIG_KGDB_SYSRQ is not set
+# CONFIG_KGDB_MORE is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.29/arch/arm/def-configs/edb9312 linux-2.4.29-uc1/arch/arm/def-configs/edb9312
--- linux-2.4.29/arch/arm/def-configs/edb9312	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/edb9312	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,1058 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+CONFIG_ARCH_EP93XX=y
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200 is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# AT91RM9200 Implementations
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_EDB7312 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_EP7312 is not set
+
+#
+# EP93xx Implementations
+#
+# CONFIG_ARCH_EDB9301 is not set
+# CONFIG_ARCH_EDB9302 is not set
+CONFIG_ARCH_EDB9312=y
+# CONFIG_ARCH_EDB9315 is not set
+# CONFIG_ARCH_EP9301 is not set
+# CONFIG_ARCH_EP9302 is not set
+CONFIG_ARCH_EP9312=y
+# CONFIG_ARCH_EP9315 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+# CONFIG_EP93XX_GRAPHICS is not set
+CONFIG_EP93XX_CRUNCH=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+CONFIG_CPU_ARM920T=y
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_DISCONTIGMEM is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="root=/dev/ram"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_CLPS7500 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_EDB9301 is not set
+# CONFIG_MTD_EDB9302 is not set
+CONFIG_MTD_EDB9312=y
+# CONFIG_MTD_EDB9315 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_CEIVA is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PCMCIA is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=12288
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_STATS=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+CONFIG_EP93XX_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+CONFIG_BLK_DEV_IDE_EP93XX=y
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_SII is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_MX1TS is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_EP93XX_VT=y
+CONFIG_EP93XX_KBD_SPI=y
+# CONFIG_EP93XX_KBD_USB is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+CONFIG_SERIAL_EP93XX=y
+CONFIG_SERIAL_EP93XX_CONSOLE=y
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_AT91 is not set
+# CONFIG_SERIAL_AT91_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+CONFIG_EP93XX_TOUCHSCREEN=y
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_ACORN is not set
+CONFIG_FB_EP93XX=y
+# CONFIG_FB_CRT_EP93XX is not set
+CONFIG_FB_LCD_EP93XX=y
+# CONFIG_FB_CX25871 is not set
+# CONFIG_FB_EP93XX_8BPP is not set
+CONFIG_FB_EP93XX_16BPP_565=y
+# CONFIG_FB_CX25871_OVERSCAN is not set
+# CONFIG_FB_ANAKIN is not set
+# CONFIG_FB_CLPS711X is not set
+# CONFIG_FB_EDB7312 is not set
+# CONFIG_FB_SA1100 is not set
+# CONFIG_FB_DBMX1 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_ACORN_8x8=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_ALI5455 is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_OSS=y
+# CONFIG_SOUND_TRACEINIT is not set
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_AD1889 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_ACI_MIXER is not set
+# CONFIG_SOUND_CS4232 is not set
+CONFIG_SOUND_EP93XX=y
+# CONFIG_SOUND_EP93XX_AC97 is not set
+CONFIG_SOUND_EP93XX_I2S=y
+# CONFIG_CODEC_CS4271 is not set
+CONFIG_CODEC_CS4228A=y
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_PAS_JOYSTICK is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_AWE32_SYNTH is not set
+# CONFIG_SOUND_KAHLUA is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMFPCI is not set
+# CONFIG_SOUND_YMFPCI_LEGACY is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+CONFIG_USB_OHCI_EP93XX=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_MIDI is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_TIGL is not set
+# CONFIG_USB_BRLVGER is not set
+# CONFIG_USB_LCD is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
+# CONFIG_KGDB is not set
+# CONFIG_KGDB_SERIAL is not set
+# CONFIG_KGDB_CONSOLE is not set
+# CONFIG_KGDB_SYSRQ is not set
+# CONFIG_KGDB_MORE is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.29/arch/arm/def-configs/edb9315 linux-2.4.29-uc1/arch/arm/def-configs/edb9315
--- linux-2.4.29/arch/arm/def-configs/edb9315	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/edb9315	2005-06-14 02:11:01.000000000 +0100
@@ -0,0 +1,1067 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+CONFIG_ARCH_EP93XX=y
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200 is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# AT91RM9200 Implementations
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_EDB7312 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_EP7312 is not set
+
+#
+# EP93xx Implementations
+#
+# CONFIG_ARCH_EDB9301 is not set
+# CONFIG_ARCH_EDB9302 is not set
+# CONFIG_ARCH_EDB9312 is not set
+CONFIG_ARCH_EDB9315=y
+# CONFIG_ARCH_EP9301 is not set
+# CONFIG_ARCH_EP9302 is not set
+# CONFIG_ARCH_EP9312 is not set
+CONFIG_ARCH_EP9315=y
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_EP93XX_GRAPHICS=y
+CONFIG_EP93XX_CRUNCH=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+CONFIG_CPU_ARM920T=y
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_DISCONTIGMEM is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
+# CONFIG_PCMCIA_CLPS6700 is not set
+# CONFIG_PCMCIA_SA1100 is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="root=/dev/ram"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_CLPS7500 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_EDB9301 is not set
+# CONFIG_MTD_EDB9302 is not set
+# CONFIG_MTD_EDB9312 is not set
+# CONFIG_MTD_EDB9315 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_CEIVA is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PCMCIA is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=12288
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_STATS=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+CONFIG_EP93XX_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+CONFIG_BLK_DEV_IDE_EP93XX=y
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_SII is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_MX1TS is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_EP93XX_VT=y
+CONFIG_EP93XX_KBD_SPI=y
+# CONFIG_EP93XX_KBD_USB is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+CONFIG_SERIAL_EP93XX=y
+CONFIG_SERIAL_EP93XX_CONSOLE=y
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_AT91 is not set
+# CONFIG_SERIAL_AT91_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+CONFIG_EP93XX_TOUCHSCREEN=y
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_ACORN is not set
+CONFIG_FB_EP93XX=y
+# CONFIG_FB_CRT_EP93XX is not set
+CONFIG_FB_LCD_EP93XX=y
+# CONFIG_FB_CX25871 is not set
+# CONFIG_FB_EP93XX_8BPP is not set
+CONFIG_FB_EP93XX_16BPP_565=y
+# CONFIG_FB_CX25871_OVERSCAN is not set
+# CONFIG_FB_ANAKIN is not set
+# CONFIG_FB_CLPS711X is not set
+# CONFIG_FB_EDB7312 is not set
+# CONFIG_FB_SA1100 is not set
+# CONFIG_FB_DBMX1 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_ACORN_8x8=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_ALI5455 is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_OSS=y
+# CONFIG_SOUND_TRACEINIT is not set
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_AD1889 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_ACI_MIXER is not set
+# CONFIG_SOUND_CS4232 is not set
+CONFIG_SOUND_EP93XX=y
+# CONFIG_SOUND_EP93XX_AC97 is not set
+CONFIG_SOUND_EP93XX_I2S=y
+# CONFIG_CODEC_CS4271 is not set
+CONFIG_CODEC_CS4228A=y
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_PAS_JOYSTICK is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_AWE32_SYNTH is not set
+# CONFIG_SOUND_KAHLUA is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMFPCI is not set
+# CONFIG_SOUND_YMFPCI_LEGACY is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+CONFIG_USB_OHCI_EP93XX=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_MIDI is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_TIGL is not set
+# CONFIG_USB_BRLVGER is not set
+# CONFIG_USB_LCD is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
+# CONFIG_KGDB is not set
+# CONFIG_KGDB_SERIAL is not set
+# CONFIG_KGDB_CONSOLE is not set
+# CONFIG_KGDB_SYSRQ is not set
+# CONFIG_KGDB_MORE is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.29/arch/arm/def-configs/empeg linux-2.4.29-uc1/arch/arm/def-configs/empeg
--- linux-2.4.29/arch/arm/def-configs/empeg	2003-06-13 15:51:29.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/empeg	2005-06-14 02:11:00.000000000 +0100
@@ -119,7 +119,6 @@
 # CONFIG_VIDEO_PMS is not set
 # CONFIG_VIDEO_SAA5249 is not set
 # CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_SF16FMR2 is not set
 # CONFIG_RADIO_TYPHOON is not set
 # CONFIG_RADIO_ZOLTRIX is not set
 
diff -urN linux-2.4.29/arch/arm/def-configs/ep9301 linux-2.4.29-uc1/arch/arm/def-configs/ep9301
--- linux-2.4.29/arch/arm/def-configs/ep9301	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/ep9301	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,699 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+CONFIG_ARCH_EP9301=y
+# CONFIG_ARCH_EP9312 is not set
+# CONFIG_ARCH_EP9315 is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200 is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# AT91RM9200 Implementations
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+
+#
+# EP9301 Options
+#
+CONFIG_EP93XX_DMA=y
+# CONFIG_EP93XX_CRUNCH is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+CONFIG_CPU_ARM920T=y
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+CONFIG_DISCONTIGMEM=y
+# CONFIG_MMU_TABLE_DUMP is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="root=/dev/ram"
+# CONFIG_ALIGNMENT_TRAP is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=12288
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_STATS is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+CONFIG_EP93XX_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_MX1TS is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+CONFIG_SERIAL_EP93XX=y
+# CONFIG_SERIAL_AMBA is not set
+CONFIG_SERIAL_AMBA_CONSOLE=y
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_AT91 is not set
+# CONFIG_SERIAL_AT91_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_ALI5455 is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_OSS=y
+# CONFIG_SOUND_TRACEINIT is not set
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_AD1889 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_ACI_MIXER is not set
+# CONFIG_SOUND_CS4232 is not set
+# CONFIG_SOUND_EP93XX_NONE is not set
+# CONFIG_SOUND_EP93XX_AC97 is not set
+CONFIG_SOUND_EP93XX_I2S=y
+CONFIG_CODEC_CS4271=y
+# CONFIG_CODEC_CS4228A is not set
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_PAS_JOYSTICK is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_AWE32_SYNTH is not set
+# CONFIG_SOUND_KAHLUA is not set
+# CONFIG_SOUND_WAVEFRONT is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMFPCI is not set
+# CONFIG_SOUND_YMFPCI_LEGACY is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
+# CONFIG_KGDB is not set
+# CONFIG_KGDB_SERIAL is not set
+# CONFIG_KGDB_CONSOLE is not set
+# CONFIG_KGDB_SYSRQ is not set
+# CONFIG_KGDB_MORE is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.29/arch/arm/def-configs/ep9312 linux-2.4.29-uc1/arch/arm/def-configs/ep9312
--- linux-2.4.29/arch/arm/def-configs/ep9312	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/ep9312	2005-06-14 02:11:01.000000000 +0100
@@ -0,0 +1,738 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_EP9301 is not set
+CONFIG_ARCH_EP9312=y
+# CONFIG_ARCH_EP9315 is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200 is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# AT91RM9200 Implementations
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+
+#
+# EP9312 Options
+#
+CONFIG_EP93XX_DMA=y
+# CONFIG_EP93XX_CRUNCH is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+CONFIG_CPU_ARM920T=y
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+CONFIG_DISCONTIGMEM=y
+# CONFIG_MMU_TABLE_DUMP is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="root=/dev/ram video=ep93xxfb"
+# CONFIG_ALIGNMENT_TRAP is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=12288
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_STATS is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+CONFIG_EP93XX_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_MX1TS is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+CONFIG_EP93XX_VT=y
+CONFIG_EP93XX_KBD_SPI=y
+# CONFIG_EP93XX_KBD_USB is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+CONFIG_SERIAL_EP93XX=y
+# CONFIG_SERIAL_AMBA is not set
+CONFIG_SERIAL_AMBA_CONSOLE=y
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_AT91 is not set
+# CONFIG_SERIAL_AT91_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+# CONFIG_PSMOUSE is not set
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+CONFIG_EP93XX_TOUCHSCREEN=y
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_ACORN is not set
+CONFIG_FB_EP93XX=y
+# CONFIG_FB_CRT_EP93XX is not set
+CONFIG_FB_LCD_EP93XX=y
+# CONFIG_FB_CX25871 is not set
+# CONFIG_FB_EP93XX_8BPP is not set
+CONFIG_FB_EP93XX_16BPP_565=y
+# CONFIG_FB_ANAKIN is not set
+# CONFIG_FB_CLPS711X is not set
+# CONFIG_FB_SA1100 is not set
+# CONFIG_FB_DBMX1 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_ACORN_8x8=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_ALI5455 is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_OSS=y
+# CONFIG_SOUND_TRACEINIT is not set
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_AD1889 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_ACI_MIXER is not set
+# CONFIG_SOUND_CS4232 is not set
+# CONFIG_SOUND_EP93XX_NONE is not set
+CONFIG_SOUND_EP93XX_AC97=y
+# CONFIG_SOUND_EP93XX_I2S is not set
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_PAS_JOYSTICK is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_AWE32_SYNTH is not set
+# CONFIG_SOUND_KAHLUA is not set
+# CONFIG_SOUND_WAVEFRONT is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMFPCI is not set
+# CONFIG_SOUND_YMFPCI_LEGACY is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
+# CONFIG_KGDB is not set
+# CONFIG_KGDB_SERIAL is not set
+# CONFIG_KGDB_CONSOLE is not set
+# CONFIG_KGDB_SYSRQ is not set
+# CONFIG_KGDB_MORE is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.29/arch/arm/def-configs/footbridge linux-2.4.29-uc1/arch/arm/def-configs/footbridge
--- linux-2.4.29/arch/arm/def-configs/footbridge	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-uc1/arch/arm/def-configs/footbridge	2005-06-14 02:11:01.000000000 +0100
@@ -598,7 +598,6 @@
 # CONFIG_RADIO_MAESTRO is not set
 # CONFIG_RADIO_MIROPCM20 is not set
 # CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_SF16FMR2 is not set
 # CONFIG_RADIO_TERRATEC is not set
 # CONFIG_RADIO_TRUST is not set
 # CONFIG_RADIO_TYPHOON is not set
diff -urN linux-2.4.29/arch/arm/def-configs/integrator-kgdb linux-2.4.29-uc1/arch/arm/def-configs/integrator-kgdb
--- linux-2.4.29/arch/arm/def-configs/integrator-kgdb	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/integrator-kgdb	2005-06-14 02:11:02.000000000 +0100
@@ -0,0 +1,959 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+CONFIG_ARCH_INTEGRATOR=y
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+CONFIG_CPU_ARM720T=y
+CONFIG_CPU_ARM920T=y
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_DISCONTIGMEM is not set
+
+#
+# General setup
+#
+CONFIG_PCI_INTEGRATOR=y
+CONFIG_PCI=y
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+CONFIG_ZBOOT_ROM=y
+CONFIG_ZBOOT_ROM_TEXT=24000000
+CONFIG_ZBOOT_ROM_BSS=00400000
+CONFIG_CPU_FREQ=y
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=m
+CONFIG_FPE_FASTFPE=m
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PM=y
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="noinitrd root=/dev/nfs ip=bootp console=ttyAM0,38400n8"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=m
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=m
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_B1 is not set
+# CONFIG_MTD_CFI_B2 is not set
+CONFIG_MTD_CFI_B4=y
+# CONFIG_MTD_CFI_B8 is not set
+# CONFIG_MTD_CFI_I1 is not set
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=m
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+CONFIG_MTD_ARM_INTEGRATOR=m
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+# CONFIG_IRTTY_SIR is not set
+# CONFIG_IRPORT_SIR is not set
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_NSC_FIR is not set
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_TOSHIBA_FIR is not set
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VLSI_FIR is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=m
+CONFIG_INPUT_KEYBDEV=m
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+CONFIG_SERIAL_AMBA=y
+CONFIG_SERIAL_AMBA_CONSOLE=y
+CONFIG_SERIAL_INTEGRATOR=y
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=m
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=m
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS_FS=m
+CONFIG_JFFS_FS_VERBOSE=0
+# CONFIG_JFFS_PROC_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_CRAMFS=m
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+CONFIG_MINIX_FS=m
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+CONFIG_SMB_NLS=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Console drivers
+#
+CONFIG_KMI_KEYB=y
+CONFIG_KMI_MOUSE=y
+CONFIG_PC_KEYMAP=y
+CONFIG_VGA_CONSOLE=y
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
+# CONFIG_FB_CLPS711X is not set
+# CONFIG_FB_SA1100 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+# CONFIG_FB_MATROX_MYSTIQUE is not set
+# CONFIG_FB_MATROX_G100 is not set
+# CONFIG_FB_MATROX_G450 is not set
+# CONFIG_FB_MATROX_MULTIHEAD is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=m
+CONFIG_FBCON_CFB16=m
+CONFIG_FBCON_CFB24=m
+CONFIG_FBCON_CFB32=m
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+CONFIG_FBCON_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
+CONFIG_KGDB=y
+CONFIG_KGDB_SERIAL=y
+# CONFIG_KGDB_CONSOLE is not set
+CONFIG_KGDB_SYSRQ=y
+# CONFIG_KGDB_MORE is not set
+# CONFIG_KGDB_UART0 is not set
+CONFIG_KGDB_UART1=y
+CONFIG_KGDB_9600BAUD=y
+# CONFIG_KGDB_19200BAUD is not set
+# CONFIG_KGDB_38400BAUD is not set
+# CONFIG_KGDB_57600BAUD is not set
+# CONFIG_KGDB_115200BAUD is not set
diff -urN linux-2.4.29/arch/arm/def-configs/iq31244 linux-2.4.29-uc1/arch/arm/def-configs/iq31244
--- linux-2.4.29/arch/arm/def-configs/iq31244	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/iq31244	2005-06-14 02:11:02.000000000 +0100
@@ -0,0 +1,874 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_ADVANCED_OPTIONS is not set
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_ADIFCC is not set
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+CONFIG_ARCH_IOP3XX=y
+# CONFIG_ARCH_IXP1200 is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP425 is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# IOP3xx Implementation Options
+#
+# CONFIG_ARCH_IQ80310 is not set
+# CONFIG_ARCH_IQ80321 is not set
+CONFIG_ARCH_IQ31244=y
+# CONFIG_ARCH_IOP310 is not set
+CONFIG_ARCH_IOP321=y
+
+#
+# IOP3xx Chipset Features
+#
+CONFIG_IOP3XX_AAU=y
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+# CONFIG_CPU_32v4 is not set
+CONFIG_CPU_32v5=y
+CONFIG_CPU_XSCALE=y
+CONFIG_ARM_THUMB=y
+
+#
+# Processor Features
+#
+# CONFIG_XSCALE_PMU_TIMER is not set
+# CONFIG_XSCALE_CACHE_ERRATA is not set
+# CONFIG_XSCALE_BDI2000 is not set
+# CONFIG_DISCONTIGMEM is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+
+#
+# General setup
+#
+CONFIG_PCI=y
+CONFIG_PCI_AUTOCONFIG=y
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+CONFIG_KERNEL_START=0xc0000000
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+CONFIG_MTD_IOP3XX=y
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_BRH is not set
+# CONFIG_MTD_EPXA is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_IXP425 is not set
+# CONFIG_MTD_IXP2000 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+CONFIG_MD_RAID5=y
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set
+# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
+CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_CMD680 is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_IXP1200 is not set
+# CONFIG_SERIAL_IXP1200_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_AT91US3 is not set
+# CONFIG_SERIAL_AT91US3_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_IXP2000_SLAVE is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.29/arch/arm/def-configs/iq80310 linux-2.4.29-uc1/arch/arm/def-configs/iq80310
--- linux-2.4.29/arch/arm/def-configs/iq80310	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/iq80310	2005-06-14 02:11:02.000000000 +0100
@@ -0,0 +1,886 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_ADVANCED_OPTIONS is not set
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_ADIFCC is not set
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+CONFIG_ARCH_IOP3XX=y
+# CONFIG_ARCH_IXP1200 is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP425 is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# IOP3xx Implementation Options
+#
+CONFIG_ARCH_IQ80310=y
+# CONFIG_ARCH_IQ80321 is not set
+CONFIG_ARCH_IOP310=y
+# CONFIG_ARCH_IOP321 is not set
+CONFIG_IOP3XX_AAU=y
+# CONFIG_IOP3XX_DMA is not set
+# CONFIG_IOP3XX_MU is not set
+# CONFIG_IOP3XX_PMON is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+# CONFIG_CPU_32v4 is not set
+CONFIG_CPU_32v5=y
+CONFIG_CPU_XSCALE=y
+CONFIG_ARM_THUMB=y
+# CONFIG_XSCALE_PMU_TIMER is not set
+# CONFIG_XSCALE_CACHE_ERRATA is not set
+# CONFIG_XSCALE_BDI2000 is not set
+# CONFIG_DISCONTIGMEM is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+
+#
+# General setup
+#
+CONFIG_PCI=y
+CONFIG_PCI_AUTOCONFIG=y
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+CONFIG_KERNEL_START=0xc0000000
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttyS0,115200 ip=bootp"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+CONFIG_MTD_IQ80310=y
+# CONFIG_MTD_IQ80321 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_BRH is not set
+# CONFIG_MTD_EPXA is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_IXP425 is not set
+# CONFIG_MTD_IXP2000 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set
+# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
+CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_CMD680 is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AACRAID is not set
+CONFIG_SCSI_AIC7XXX_OLD=y
+# CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT is not set
+CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=127
+# CONFIG_AIC7XXX_OLD_PROC_STATS is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_IXP1200 is not set
+# CONFIG_SERIAL_IXP1200_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_AT91US3 is not set
+# CONFIG_SERIAL_AT91US3_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_IXP2000_SLAVE is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.29/arch/arm/def-configs/iq80321 linux-2.4.29-uc1/arch/arm/def-configs/iq80321
--- linux-2.4.29/arch/arm/def-configs/iq80321	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/iq80321	2005-06-14 02:11:02.000000000 +0100
@@ -0,0 +1,874 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_ADVANCED_OPTIONS is not set
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_ADIFCC is not set
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+CONFIG_ARCH_IOP3XX=y
+# CONFIG_ARCH_IXP1200 is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP425 is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# IOP3xx Implementation Options
+#
+# CONFIG_ARCH_IQ80310 is not set
+CONFIG_ARCH_IQ80321=y
+# CONFIG_ARCH_IQ31244 is not set
+# CONFIG_ARCH_IOP310 is not set
+CONFIG_ARCH_IOP321=y
+
+#
+# IOP3xx Chipset Features
+#
+CONFIG_IOP3XX_AAU=y
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+# CONFIG_CPU_32v4 is not set
+CONFIG_CPU_32v5=y
+CONFIG_CPU_XSCALE=y
+CONFIG_ARM_THUMB=y
+
+#
+# Processor Features
+#
+# CONFIG_XSCALE_PMU_TIMER is not set
+# CONFIG_XSCALE_CACHE_ERRATA is not set
+# CONFIG_XSCALE_BDI2000 is not set
+# CONFIG_DISCONTIGMEM is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+
+#
+# General setup
+#
+CONFIG_PCI=y
+CONFIG_PCI_AUTOCONFIG=y
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+CONFIG_KERNEL_START=0xc0000000
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200 mem=128M@0xa0000000"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+CONFIG_MTD_IOP3XX=y
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_BRH is not set
+# CONFIG_MTD_EPXA is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_IXP425 is not set
+# CONFIG_MTD_IXP2000 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+CONFIG_MD_RAID5=y
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set
+# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
+CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_CMD680 is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_IXP1200 is not set
+# CONFIG_SERIAL_IXP1200_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_AT91US3 is not set
+# CONFIG_SERIAL_AT91US3_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_IXP2000_SLAVE is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.29/arch/arm/def-configs/ixdp2400 linux-2.4.29-uc1/arch/arm/def-configs/ixdp2400
--- linux-2.4.29/arch/arm/def-configs/ixdp2400	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/ixdp2400	2005-06-14 02:11:01.000000000 +0100
@@ -0,0 +1,781 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_ADVANCED_OPTIONS=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ADIFCC is not set
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP1200 is not set
+CONFIG_ARCH_IXP2000=y
+# CONFIG_ARCH_IXP425 is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+CONFIG_ARCH_IXDP2400=y
+# CONFIG_ARCH_IXDP2800 is not set
+CONFIG_IXP2000_PCI_IO_ERRATA=y
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+# CONFIG_CPU_32v4 is not set
+CONFIG_CPU_32v5=y
+CONFIG_CPU_XSCALE=y
+CONFIG_ARM_THUMB=y
+
+#
+# Processor Features
+#
+# CONFIG_XSCALE_PMU_TIMER is not set
+# CONFIG_XSCALE_CACHE_ERRATA is not set
+# CONFIG_XSCALE_BDI2000 is not set
+# CONFIG_DISCONTIGMEM is not set
+CONFIG_CPU_BIG_ENDIAN=y
+
+#
+# General setup
+#
+CONFIG_PCI=y
+CONFIG_PCI_AUTOCONFIG=y
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+CONFIG_KERNEL_START_BOOL=y
+CONFIG_KERNEL_START=80000000
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttyS0,57600 root=nfs ip=bootp"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IOP3XX is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_BRH is not set
+# CONFIG_MTD_EPXA is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_IXP425 is not set
+CONFIG_MTD_IXP2000=y
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_IXP1200 is not set
+# CONFIG_SERIAL_IXP1200_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_AT91US3 is not set
+# CONFIG_SERIAL_AT91US3_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+CONFIG_IXP2000_SLAVE=y
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_PHILIPSPAR is not set
+# CONFIG_I2C_ELV is not set
+# CONFIG_I2C_VELLEMAN is not set
+# CONFIG_I2C_GUIDE is not set
+# CONFIG_I2C_IXP2000 is not set
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PROC=y
+# CONFIG_I2C_DS1307 is not set
+# CONFIG_PCF8549C_NVRAM is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.29/arch/arm/def-configs/ixdp2800 linux-2.4.29-uc1/arch/arm/def-configs/ixdp2800
--- linux-2.4.29/arch/arm/def-configs/ixdp2800	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/ixdp2800	2005-06-14 02:11:01.000000000 +0100
@@ -0,0 +1,685 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_ADVANCED_OPTIONS=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ADIFCC is not set
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP1200 is not set
+CONFIG_ARCH_IXP2000=y
+# CONFIG_ARCH_IXP425 is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+# CONFIG_ARCH_IXDP2400 is not set
+CONFIG_ARCH_IXDP2800=y
+# CONFIG_IXP2000_PCI_IO_ERRATA is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+# CONFIG_CPU_32v4 is not set
+CONFIG_CPU_32v5=y
+CONFIG_CPU_XSCALE=y
+CONFIG_ARM_THUMB=y
+
+#
+# Processor Features
+#
+# CONFIG_XSCALE_PMU_TIMER is not set
+# CONFIG_XSCALE_CACHE_ERRATA is not set
+# CONFIG_XSCALE_BDI2000 is not set
+# CONFIG_DISCONTIGMEM is not set
+CONFIG_CPU_BIG_ENDIAN=y
+
+#
+# General setup
+#
+CONFIG_PCI=y
+CONFIG_PCI_AUTOCONFIG=y
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+CONFIG_KERNEL_START_BOOL=y
+CONFIG_KERNEL_START=80000000
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttyS0 ip=bootp root=nfs nohalt"
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_IXP1200 is not set
+# CONFIG_SERIAL_IXP1200_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_AT91US3 is not set
+# CONFIG_SERIAL_AT91US3_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_IXP2000_SLAVE is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.29/arch/arm/def-configs/ixdp425 linux-2.4.29-uc1/arch/arm/def-configs/ixdp425
--- linux-2.4.29/arch/arm/def-configs/ixdp425	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/ixdp425	2005-06-14 02:11:01.000000000 +0100
@@ -0,0 +1,795 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_ADVANCED_OPTIONS is not set
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ADIFCC is not set
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP1200 is not set
+# CONFIG_ARCH_IXP2000 is not set
+CONFIG_ARCH_IXP425=y
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# IXP425 Implementation Options
+#
+
+#
+# IXP425 Board Types
+#
+CONFIG_ARCH_IXDP425=y
+# CONFIG_ARCH_IXCDP1100 is not set
+# CONFIG_ARCH_PRPMC1100 is not set
+
+#
+# IXP425 Options
+#
+CONFIG_IXP425_PCI_ERRATA=y
+# CONFIG_XSCALE_PMU_TIMER is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+# CONFIG_CPU_32v4 is not set
+CONFIG_CPU_32v5=y
+CONFIG_CPU_XSCALE=y
+CONFIG_ARM_THUMB=y
+
+#
+# Processor Features
+#
+# CONFIG_XSCALE_PMU_TIMER is not set
+# CONFIG_XSCALE_CACHE_ERRATA is not set
+# CONFIG_XSCALE_BDI2000 is not set
+# CONFIG_DISCONTIGMEM is not set
+CONFIG_CPU_BIG_ENDIAN=y
+
+#
+# General setup
+#
+CONFIG_PCI=y
+CONFIG_PCI_AUTOCONFIG=y
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+CONFIG_KERNEL_START=0xc0000000
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=256M@0x00000000"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IOP3XX is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_BRH is not set
+# CONFIG_MTD_EPXA is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+CONFIG_MTD_IXP425=y
+# CONFIG_MTD_IXP2000 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=m
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_IXP1200 is not set
+# CONFIG_SERIAL_IXP1200_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_AT91US3 is not set
+# CONFIG_SERIAL_AT91US3_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_IXP2000_SLAVE is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_PHILIPSPAR is not set
+# CONFIG_I2C_ELV is not set
+# CONFIG_I2C_VELLEMAN is not set
+# CONFIG_I2C_GUIDE is not set
+CONFIG_I2C_IXP425=y
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PROC=y
+# CONFIG_I2C_DS1307 is not set
+CONFIG_PCF8549C_NVRAM=y
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.29/arch/arm/def-configs/ixm1200 linux-2.4.29-uc1/arch/arm/def-configs/ixm1200
--- linux-2.4.29/arch/arm/def-configs/ixm1200	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/ixm1200	2005-06-14 02:11:02.000000000 +0100
@@ -0,0 +1,682 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_ADVANCED_OPTIONS is not set
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_ADIFCC is not set
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+CONFIG_ARCH_IXP1200=y
+# CONFIG_ARCH_IXP425 is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# IXP1200 Implementation Options
+#
+CONFIG_IXP1200_SDRAM_BASE=c0000000
+CONFIG_IXP1200_SDRAM_SIZE=128
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+CONFIG_CPU_SA110=y
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+# CONFIG_CPU_32v4 is not set
+
+#
+# Processor Features
+#
+# CONFIG_DISCONTIGMEM is not set
+CONFIG_CPU_BIG_ENDIAN=y
+
+#
+# General setup
+#
+CONFIG_PCI=y
+CONFIG_PCI_AUTOCONFIG=y
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+CONFIG_KERNEL_START=0xc0000000
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="ip=bootp ixphost console=ttyIXP0,38400"
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+CONFIG_SERIAL_IXP1200=y
+CONFIG_SERIAL_IXP1200_CONSOLE=y
+CONFIG_IXP1200_DEFAULT_BAUDRATE=38400
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.29/arch/arm/def-configs/ixp12eb linux-2.4.29-uc1/arch/arm/def-configs/ixp12eb
--- linux-2.4.29/arch/arm/def-configs/ixp12eb	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/ixp12eb	2005-06-14 02:11:01.000000000 +0100
@@ -0,0 +1,741 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+CONFIG_ARCH_IXP1200=y
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# IXP12xx Implementation Options
+#
+CONFIG_ARCH_IXP12EB=y
+# CONFIG_ARCH_IXM1200 is not set
+CONFIG_IXP1200_SDRAM_BASE=c0000000
+CONFIG_IXP1200_SDRAM_SIZE=32
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+
+#
+# Processor Type
+#
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+CONFIG_CPU_SA110=y
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_ARM_THUMB is not set
+# CONFIG_DISCONTIGMEM is not set
+CONFIG_CPU_BIG_ENDIAN=y
+
+#
+# General setup
+#
+CONFIG_PCI=y
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="ip=bootp rw"
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+CONFIG_SERIAL_IXP1200=y
+CONFIG_SERIAL_IXP1200_CONSOLE=y
+CONFIG_IXP1200_DEFAULT_BAUDRATE=9600
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.29/arch/arm/def-configs/prpmc1100 linux-2.4.29-uc1/arch/arm/def-configs/prpmc1100
--- linux-2.4.29/arch/arm/def-configs/prpmc1100	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/prpmc1100	2005-06-14 02:11:02.000000000 +0100
@@ -0,0 +1,748 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_ADVANCED_OPTIONS is not set
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ADIFCC is not set
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP1200 is not set
+# CONFIG_ARCH_IXP2000 is not set
+CONFIG_ARCH_IXP425=y
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# IXP425 Implementation Options
+#
+CONFIG_ARCH_IXDP425=y
+CONFIG_ARCH_IXCDP1100=y
+CONFIG_ARCH_PRPMC1100=y
+CONFIG_IXP425_PCI_ERRATA=y
+# CONFIG_XSCALE_PMU_TIMER is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+# CONFIG_CPU_32v4 is not set
+CONFIG_CPU_32v5=y
+CONFIG_CPU_XSCALE=y
+CONFIG_ARM_THUMB=y
+# CONFIG_XSCALE_PMU_TIMER is not set
+# CONFIG_XSCALE_CACHE_ERRATA is not set
+# CONFIG_XSCALE_BDI2000 is not set
+# CONFIG_DISCONTIGMEM is not set
+CONFIG_CPU_BIG_ENDIAN=y
+
+#
+# General setup
+#
+CONFIG_PCI=y
+CONFIG_PCI_AUTOCONFIG=y
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+CONFIG_KERNEL_START=0xc0000000
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=256M@0x00000000"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_IQ80321 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_BRH is not set
+# CONFIG_MTD_EPXA is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+CONFIG_MTD_IXP425=y
+# CONFIG_MTD_IXP2000 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=m
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_IXP1200 is not set
+# CONFIG_SERIAL_IXP1200_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_AT91US3 is not set
+# CONFIG_SERIAL_AT91US3_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_IXP2000_SLAVE is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_PHILIPSPAR is not set
+# CONFIG_I2C_ELV is not set
+# CONFIG_I2C_VELLEMAN is not set
+# CONFIG_I2C_GUIDE is not set
+CONFIG_I2C_IXP425=y
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PROC=y
+# CONFIG_I2C_DS1307 is not set
+CONFIG_PCF8549C_NVRAM=y
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -urN linux-2.4.29/arch/arm/def-configs/se4000 linux-2.4.29-uc1/arch/arm/def-configs/se4000
--- linux-2.4.29/arch/arm/def-configs/se4000	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/def-configs/se4000	2005-06-14 02:11:02.000000000 +0100
@@ -0,0 +1,868 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_ADVANCED_OPTIONS is not set
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ADIFCC is not set
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP1200 is not set
+# CONFIG_ARCH_IXP2000 is not set
+CONFIG_ARCH_IXP425=y
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200 is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# IXP425 Implementation Options
+#
+# CONFIG_ARCH_IXDP425 is not set
+# CONFIG_ARCH_IXCDP1100 is not set
+# CONFIG_ARCH_PRPMC1100 is not set
+# CONFIG_ARCH_IXP425_COYOTE is not set
+CONFIG_ARCH_SE4000=y
+
+#
+# AT91RM9200 Implementations
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+# CONFIG_CPU_32v4 is not set
+CONFIG_CPU_32v5=y
+CONFIG_CPU_XSCALE=y
+CONFIG_ARM_THUMB=y
+
+#
+# Processor Features
+#
+# CONFIG_XSCALE_PMU_TIMER is not set
+# CONFIG_XSCALE_CACHE_ERRATA is not set
+# CONFIG_XSCALE_BDI2000 is not set
+# CONFIG_DISCONTIGMEM is not set
+CONFIG_CPU_BIG_ENDIAN=y
+
+#
+# General setup
+#
+CONFIG_PCI=y
+CONFIG_PCI_AUTOCONFIG=y
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+CONFIG_KERNEL_START=0xc0000000
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram0 initrd=0x00800000,8M mem=32M@0x00000000"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_DRAGONIX is not set
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_SNAPGEODE is not set
+# CONFIG_MTD_NETteluC is not set
+# CONFIG_MTD_MBVANILLA is not set
+# CONFIG_MTD_KeyTechnology is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_IXP425 is not set
+# CONFIG_MTD_IXP425_COYOTE is not set
+CONFIG_MTD_SE4000=y
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_CEIVA is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PCMCIA is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_RAMDISK_DATA is not set
+# CONFIG_BLK_DEV_BLKMEM is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_FWMARK=y
+# CONFIG_IP_ROUTE_NAT is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_MULTIPATH_SEQUENTIAL is not set
+CONFIG_IP_ROUTE_TOS=y
+# CONFIG_IP_ROUTE_VERBOSE is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_ARP_LIMIT is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+
+#
+#   IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=y
+CONFIG_IP_NF_FTP=y
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+CONFIG_IP_NF_H323=y
+# CONFIG_IP_NF_AMANDA is not set
+# CONFIG_IP_NF_TFTP is not set
+CONFIG_IP_NF_IRC=y
+CONFIG_IP_NF_CT_PROTO_GRE=y
+CONFIG_IP_NF_PPTP=y
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_LIMIT=y
+# CONFIG_IP_NF_MATCH_IPRANGE is not set
+CONFIG_IP_NF_MATCH_MAC=y
+# CONFIG_IP_NF_MATCH_PKTTYPE is not set
+CONFIG_IP_NF_MATCH_MARK=y
+CONFIG_IP_NF_MATCH_MULTIPORT=y
+CONFIG_IP_NF_MATCH_TOS=y
+# CONFIG_IP_NF_MATCH_TIME is not set
+# CONFIG_IP_NF_MATCH_RECENT is not set
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_DSCP=y
+# CONFIG_IP_NF_MATCH_AH_ESP is not set
+CONFIG_IP_NF_MATCH_LENGTH=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_MATCH_TCPMSS=y
+CONFIG_IP_NF_MATCH_HELPER=y
+CONFIG_IP_NF_MATCH_STATE=y
+# CONFIG_IP_NF_MATCH_CONNTRACK is not set
+# CONFIG_IP_NF_MATCH_UNCLEAN is not set
+# CONFIG_IP_NF_MATCH_STRING is not set
+# CONFIG_IP_NF_MATCH_OWNER is not set
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+# CONFIG_IP_NF_TARGET_MIRROR is not set
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+# CONFIG_IP_NF_TARGET_NETMAP is not set
+CONFIG_IP_NF_NAT_H323=y
+CONFIG_IP_NF_NAT_LOCAL=y
+# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
+CONFIG_IP_NF_NAT_IRC=y
+CONFIG_IP_NF_NAT_FTP=y
+CONFIG_IP_NF_NAT_PPTP=y
+CONFIG_IP_NF_NAT_PROTO_GRE=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_TOS=y
+CONFIG_IP_NF_TARGET_ECN=y
+CONFIG_IP_NF_TARGET_DSCP=y
+CONFIG_IP_NF_TARGET_MARK=y
+CONFIG_IP_NF_TARGET_LOG=y
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_IP_NF_TARGET_TCPMSS=y
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_CSZ=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_SCH_RED=y
+CONFIG_NET_SCH_SFQ=y
+CONFIG_NET_SCH_TEQL=y
+CONFIG_NET_SCH_TBF=y
+CONFIG_NET_SCH_GRED=y
+CONFIG_NET_SCH_DSMARK=y
+CONFIG_NET_SCH_INGRESS=y
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=y
+CONFIG_NET_CLS_ROUTE4=y
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=y
+CONFIG_NET_CLS_U32=y
+CONFIG_NET_CLS_RSVP=y
+# CONFIG_NET_CLS_RSVP6 is not set
+CONFIG_NET_CLS_POLICE=y
+CONFIG_IPSEC=y
+
+#
+# IPSec options (FreeS/WAN)
+#
+CONFIG_IPSEC_IPIP=y
+CONFIG_IPSEC_ALG=y
+CONFIG_IPSEC_ALG_AES=y
+CONFIG_IPSEC_AH=y
+CONFIG_IPSEC_AUTH_HMAC_MD5=y
+CONFIG_IPSEC_AUTH_HMAC_SHA1=y
+CONFIG_IPSEC_ESP=y
+CONFIG_IPSEC_ENC_DES=y
+CONFIG_IPSEC_ENC_3DES=y
+CONFIG_IPSEC_IPCOMP=y
+# CONFIG_IPSEC_IPCOMP_LZS is not set
+CONFIG_IPSEC_DEBUG=y
+CONFIG_IPSEC_NAT_TRAVERSAL=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FEC is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_UCCS8900 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPPOE=y
+CONFIG_SLIP=y
+CONFIG_SLIP_COMPRESSED=y
+# CONFIG_SLIP_SMART is not set
+# CONFIG_SLIP_MODE_SLIP6 is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_LEDMAN=y
+# CONFIG_DS1302 is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Controller Area Network Cards/Chips
+#
+# CONFIG_CAN4LINUX is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_COREDUMP_PRINTK is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Misc devices
+#
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff -urN linux-2.4.29/arch/arm/fastfpe/CPDO.S linux-2.4.29-uc1/arch/arm/fastfpe/CPDO.S
--- linux-2.4.29/arch/arm/fastfpe/CPDO.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/fastfpe/CPDO.S	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,682 @@
+/*
+The FP structure has 4 words reserved for each register, the first is used just
+for the sign in bit 31, the second and third are for the mantissa (unsigned
+integer, high 32 bit first) and the fourth is the exponent (signed integer).
+The mantissa is always normalized.
+
+If the exponent is 0x80000000, that is the most negative value, the number
+represented is 0 and both mantissa words are also 0.
+
+If the exponent is 0x7fffffff, that is the biggest positive value, the number
+represented is infinity if the high 32 mantissa bit are also 0, otherwise it is
+a NaN. The low 32 mantissa bit are 0 if the number represented is infinity.
+
+Decimal and packed decimal numbers are not supported yet.
+
+The parameters to these functions are r0=destination pointer, r1 and r2
+source pointers. r4 is the instruction. They may use r0-r8 and r14. They return
+to fastfpe_next, except CPDO_rnf_core which expects the return address in r14.
+*/
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_adf
+CPDO_adf:
+	ldmia	r1,{r1,r3,r5,r7}
+	ldmia	r2,{r2,r4,r6,r8}
+
+	cmp	r7,#0x7fffffff
+	cmpne	r8,#0x7fffffff
+	beq	CPDO_adf_extra
+
+	cmp	r1,r2
+	bne	CPDO_suf_s
+
+CPDO_adf_s:
+	subs	r2,r7,r8
+	bge	CPDO_adf_2nd
+	
+	mov	r7,r8
+	rsb	r2,r2,#0
+	cmp	r2,#32
+	ble	CPDO_adf_1st2
+
+	sub	r2,r2,#32
+	cmp	r2,#32
+	movgt	r2,#32
+	mov	r5,r3,lsr r2
+	mov	r3,#0
+	b	CPDO_adf_add
+
+CPDO_adf_1st2:
+	rsb	r8,r2,#32
+	mov	r5,r5,lsr r2
+	orr	r5,r5,r3,lsl r8
+	mov	r3,r3,lsr r2	@ 1. op normalized
+	b	CPDO_adf_add
+
+CPDO_adf_2nd:
+	cmp	r2,#32
+	ble	CPDO_adf_2nd2
+
+	sub	r2,r2,#32
+	cmp	r2,#32
+	movgt	r2,#32
+	mov	r6,r4,lsr r2
+	mov	r4,#0
+	b	CPDO_adf_add
+
+CPDO_adf_2nd2:
+	rsb	r8,r2,#32
+	mov	r6,r6,lsr r2
+	orr	r6,r6,r4,lsl r8
+	mov	r4,r4,lsr r2	@ 2. op normalized
+
+CPDO_adf_add:
+	adds	r5,r5,r6
+	adcs	r3,r3,r4	@ do addition
+	bcc	CPDO_adf_end
+
+	add	r7,r7,#1
+	movs	r3,r3,rrx
+	mov	r5,r5,rrx	@ correct for overflow
+
+CPDO_adf_end:
+	cmp	r7,#0x20000000
+	bge	CPDO_inf
+
+	stmia	r0,{r1,r3,r5,r7}
+	b	fastfpe_next
+
+CPDO_adf_extra:
+	cmp	r7,#0x7fffffff		@ was it the 1st ?
+	bne	CPDO_infnan_2		@ no it was the 2nd
+	cmp	r8,#0x7fffffff		@ if 1st, 2nd too ?
+	bne	CPDO_infnan_1		@ no only 1st
+	cmp	r3,#0
+	cmpeq	r4,#0
+	bne	CPDO_nan_12
+	b	CPDO_inf
+
+/*---------------------------------------------------------------------------*/
+
+CPDO_infnan_1:
+	stmia	r0,{r1,r3,r5,r7}
+	b	fastfpe_next
+
+CPDO_infnan_2:
+	stmia	r0,{r2,r4,r6,r8}
+	b	fastfpe_next
+	
+CPDO_nan_12:
+	orr	r2,r3,r4
+	b	CPDO_inf_1
+
+CPDO_nan:
+	mov	r2,#0x40000000		@ create non signalling NaN
+	b	CPDO_inf_1
+
+CPDO_inf:
+	mov	r2,#0
+CPDO_inf_1:
+	mov	r3,#0
+	mov	r4,#0x7fffffff
+CPDO_store_1234:
+	stmia	r0,{r1,r2,r3,r4}
+	b	fastfpe_next
+
+CPDO_zero:
+	mov	r1,#0
+CPDO_zero_1:
+	mov	r2,#0
+	mov	r3,#0
+	mov	r4,#0x80000000
+	stmia	r0,{r1,r2,r3,r4}
+	b	fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_suf
+CPDO_suf:
+	ldmia	r1,{r1,r3,r5,r7}
+	ldmia	r2,{r2,r4,r6,r8}
+
+CPDO_suf_l:
+	cmp	r7,#0x7fffffff
+	cmpne	r8,#0x7fffffff
+	beq	CPDO_suf_extra
+
+	cmp	r1,r2
+	bne	CPDO_adf_s
+
+CPDO_suf_s:
+	subs	r2,r7,r8		@ determine greater number
+	bgt	CPDO_suf_2nd		@ first number is greater
+	blt	CPDO_suf_1st		@ second number is greater
+	cmp	r3,r4			@ also mantissa is important
+	cmpeq	r5,r6
+	bhi	CPDO_suf_2nd		@ first number is greater
+	beq	CPDO_zero
+
+CPDO_suf_1st:
+	eor	r1,r1,#0x80000000	@ second number is greater, invert sign
+	mov	r7,r8
+	rsb	r2,r2,#0
+	cmp	r2,#32
+	ble	CPDO_suf_1st2
+
+	sub	r2,r2,#32
+	cmp	r2,#32
+	movgt	r2,#32
+	mov	r5,r3,lsr r2
+	mov	r3,#0
+	b	CPDO_suf_1st_sub
+
+CPDO_suf_1st2:
+	rsb	r8,r2,#32
+	mov	r5,r5,lsr r2
+	orr	r5,r5,r3,lsl r8
+	mov	r3,r3,lsr r2	@ 1. op normalized
+
+CPDO_suf_1st_sub:
+	subs	r5,r6,r5	@ do subtraction
+	sbc	r3,r4,r3
+	b	CPDO_suf_norm
+
+CPDO_suf_2nd:
+	cmp	r2,#32
+	ble	CPDO_suf_2nd2
+
+	sub	r2,r2,#32
+	cmp	r2,#32
+	movgt	r2,#32
+	mov	r6,r4,lsr r2
+	mov	r4,#0
+	b	CPDO_suf_2nd_sub
+
+CPDO_suf_2nd2:
+	rsb	r8,r2,#32
+	mov	r6,r6,lsr r2
+	orr	r6,r6,r4,lsl r8
+	mov	r4,r4,lsr r2	@ 2. op normalized
+
+CPDO_suf_2nd_sub:
+	subs	r5,r5,r6
+	sbc	r3,r3,r4	@ do subtraction
+
+CPDO_suf_norm:
+	teq	r3,#0		@ normalize 32bit
+	moveq	r3,r5
+	moveq	r5,#0
+	subeq	r7,r7,#32
+	
+	cmp	r3,#0x00010000	@ 16bit
+	movcc	r3,r3,lsl#16
+	orrcc	r3,r3,r5,lsr#16
+	movcc	r5,r5,lsl#16
+	subcc	r7,r7,#16
+	
+	cmp	r3,#0x01000000	@ 8bit
+	movcc	r3,r3,lsl#8
+	orrcc	r3,r3,r5,lsr#24
+	movcc	r5,r5,lsl#8
+	subcc	r7,r7,#8
+	
+	cmp	r3,#0x10000000	@ 4bit
+	movcc	r3,r3,lsl#4
+	orrcc	r3,r3,r5,lsr#28
+	movcc	r5,r5,lsl#4
+	subcc	r7,r7,#4
+	
+	cmp	r3,#0x40000000	@ 2bit
+	movcc	r3,r3,lsl#2
+	orrcc	r3,r3,r5,lsr#30
+	movcc	r5,r5,lsl#2
+	subcc	r7,r7,#2
+	
+	cmp	r3,#0x80000000	@ 1bit
+	movcc	r3,r3,lsl#1
+	orrcc	r3,r3,r5,lsr#31
+	movcc	r5,r5,lsl#1
+	subcc	r7,r7,#1
+
+	cmp	r7,#0xe0000000
+	ble	CPDO_zero_1
+
+	stmia	r0,{r1,r3,r5,r7}
+	b	fastfpe_next
+
+CPDO_suf_extra:
+	cmp	r7,#0x7fffffff		@ was it the 1st ?
+	eorne	r2,r2,#0x80000000	@ change sign, might have been INF
+	bne	CPDO_infnan_2		@ no it was the 2nd
+	cmp	r8,#0x7fffffff		@ if 1st, 2nd too ?
+	bne	CPDO_infnan_1		@ no only 1st
+	cmp	r3,#0
+	cmpeq	r4,#0
+	bne	CPDO_nan_12
+	b	CPDO_nan		@ here is difference with adf !
+
+/*---------------------------------------------------------------------------*/
+
+	.globl CPDO_rsf
+CPDO_rsf:
+	mov	r3,r2
+	ldmia	r1,{r2,r4,r6,r8}
+	ldmia	r3,{r1,r3,r5,r7}
+	b	CPDO_suf_l
+	
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_muf
+CPDO_muf:
+	ldmia	r1,{r1,r3,r5,r7}
+	ldmia	r2,{r2,r4,r6,r8}
+
+	cmp	r7,#0x7fffffff
+	cmpne	r8,#0x7fffffff
+	beq	CPDO_muf_extra
+	
+	eor	r1,r1,r2
+	adds	r8,r7,r8
+	bvs	CPDO_zero_1
+
+	umull	r7,r2,r3,r4
+	umull	r14,r3,r6,r3
+	adds	r7,r7,r3	@ r2|r7|r14 = r2|r7|#0 + #0|r3|r14
+	adc	r2,r2,#0
+	umull	r4,r3,r5,r4
+	adds	r14,r14,r4	@ r2|r7|r14 += #0|r3|r4
+	adcs	r7,r7,r3
+	adc	r2,r2,#0
+	umull	r4,r3,r5,r6
+	adds	r14,r14,r3	@ r2|r7|r14 += #0|#0|r3
+	adcs	r7,r7,#0
+	adcs	r2,r2,#0
+
+	bpl	CPDO_muf_norm
+	
+	add	r8,r8,#1
+	b	CPDO_muf_end
+	
+CPDO_muf_norm:
+	adds	r14,r14,r14
+	adcs	r7,r7,r7
+	adcs	r2,r2,r2
+
+CPDO_muf_end:
+	cmp	r8,#0x20000000
+	bge	CPDO_inf
+	cmp	r8,#0xe0000000
+	ble	CPDO_zero_1
+	stmia	r0,{r1,r2,r7,r8}
+	b	fastfpe_next
+
+CPDO_muf_extra:
+	cmp	r7,#0x7fffffff		@ was it the first?
+	bne	CPDO_muf_extra_2nd	@ no, so it was the second
+	cmp	r8,#0x7fffffff		@ yes, second too?
+	bne	CPDO_muf_extra_1st	@ no, only first
+	orr	r3,r3,r4		@ if both inf -> inf, otherwise nan
+	eor	r1,r1,r2		@ sign for the inf case
+	b	CPDO_infnan_1
+
+CPDO_muf_extra_1st:
+	cmp	r3,#0			@ is it a nan?
+	bne	CPDO_infnan_1
+	cmp	r8,#0x80000000		@ is the second 0?
+	beq	CPDO_nan
+	eor	r1,r1,r2		@ correct sign for inf
+	b	CPDO_inf
+
+CPDO_muf_extra_2nd:
+	cmp	r4,#0			@ is it a nan?
+	bne	CPDO_infnan_2
+	cmp	r7,#0x80000000		@ is the first 0?
+	beq	CPDO_nan
+	eor	r1,r1,r2		@ correct sign for inf
+	b	CPDO_inf
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_dvf
+CPDO_dvf:
+	ldmia	r1,{r1,r3,r5,r7}
+	ldmia	r2,{r2,r4,r6,r8}
+
+CPDO_dvf_l:
+	cmp	r7,#0x7fffffff
+	cmpne	r8,#0x7fffffff
+	beq	CPDO_dvf_extra
+	cmp	r8,#0x80000000
+	beq	CPDO_dvf_by0
+
+	eor	r1,r1,r2
+	cmp	r7,#0x80000000
+	beq	CPDO_zero_1
+	
+	sub	r8,r7,r8
+	
+	mov	r2,#0
+	mov	r7,#1
+
+	cmp	r3,r4
+	cmpeq	r5,r6
+	bcs	CPDO_dvf_loop_
+
+	sub	r8,r8,#1
+
+CPDO_dvf_loop:
+	adds	r5,r5,r5
+	adcs	r3,r3,r3
+	bcs	CPDO_dvf_anyway
+CPDO_dvf_loop_:
+	subs	r5,r5,r6
+	sbcs	r3,r3,r4
+	bcs	CPDO_dvf_okay
+
+	adds	r5,r5,r6
+	adc	r3,r3,r4
+	adds	r7,r7,r7
+	adcs	r2,r2,r2
+	bcc	CPDO_dvf_loop
+	b	CPDO_dvf_end
+
+CPDO_dvf_anyway:
+	adcs	r7,r7,r7
+	adcs	r2,r2,r2
+	bcs	CPDO_dvf_end
+	subs	r5,r5,r6
+	sbc	r3,r3,r4
+	b	CPDO_dvf_loop
+
+CPDO_dvf_okay:
+	adcs	r7,r7,r7
+	adcs	r2,r2,r2
+	bcc	CPDO_dvf_loop
+
+CPDO_dvf_end:
+	b	CPDO_muf_end
+
+CPDO_dvf_by0:
+	cmp	R7,#0x80000000
+	beq	CPDO_nan		@ first also 0 -> nan
+	eor	r1,r1,r2		@ otherwise calculatesign for inf
+	b	CPDO_inf
+
+CPDO_dvf_extra:
+	cmp	r7,#0x7fffffff		@ was it the first?
+	bne	CPDO_dvf_extra_2nd	@ no, so it was the second
+	cmp	r8,#0x7fffffff		@ yes, second too?
+	bne	CPDO_dvf_extra_1st	@ no, only first
+	orrs	r3,r3,r4
+	beq	CPDO_nan		@ if both inf -> create nan
+	b	CPDO_nan_12		@ otherwise keep nan
+
+CPDO_dvf_extra_1st:
+	eor	r1,r1,r2		@ correct sign for inf
+	b	CPDO_infnan_1
+
+CPDO_dvf_extra_2nd:
+	cmp	r4,#0			@ is it a nan?
+	bne	CPDO_infnan_2
+	eor	r1,r1,r2		@ correct sign for zero
+	b	CPDO_zero_1
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_rdf
+CPDO_rdf:
+	mov	r3,r2
+	ldmia	r1,{r2,r4,r6,r8}
+	ldmia	r3,{r1,r3,r5,r7}
+	b	CPDO_dvf_l
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_rmf
+CPDO_rmf:
+	b	fastfpe_next
+	
+/*---------------------------------------------------------------------------*/
+
+
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_mvf
+CPDO_mvf:
+	ldmia	r2,{r1,r2,r3,r4}
+	stmia	r0,{r1,r2,r3,r4}
+	b	fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_mnf
+CPDO_mnf:
+	ldmia	r2,{r1,r2,r3,r4}
+	eor	r1,r1,#0x80000000
+	stmia	r0,{r1,r2,r3,r4}
+	b	fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_abs
+CPDO_abs:
+	ldmia	r2,{r1,r2,r3,r4}
+	bic	r1,r1,#0x80000000
+	stmia	r0,{r1,r2,r3,r4}
+	b	fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+	
+	.globl	CPDO_sqt
+CPDO_sqt:
+	ldmia	r2,{r1,r2,r3,r4}
+	cmp	r1,#0
+	bne	CPDO_nan
+	cmp	r4,#0x7fffffff
+	beq	CPDO_store_1234
+
+	tst	r4,r4,lsr#1		@carry=exponent bit 0
+	bcc	CPDO_sqt_exponenteven
+	adds	r3,r3,r3
+	adcs	r2,r2,r2		@carry is needed in loop!
+CPDO_sqt_exponenteven:
+	mov	r4,r4,asr #1
+	str	r4,[r0,#12]
+
+	mov	r4,#0x80000000
+	mov	r5,#0
+	sub	r2,r2,#0x80000000
+
+	mov	r8,#0x40000000
+	mov	r14,#0x80000000
+
+	mov	r1,#1
+	b	CPDO_sqt_loop1_first
+CPDO_sqt_loop1:
+	adds	r3,r3,r3
+	adcs	r2,r2,r2
+CPDO_sqt_loop1_first:
+	add	r6,r4,r8,lsr r1		@r7 const = r5
+	bcs	CPDO_sqt_loop1_1
+	cmp	r2,r6
+	cmpeq	r3,r5			@r5 for r7
+	bcc	CPDO_sqt_loop1_0
+CPDO_sqt_loop1_1:
+	orr	r4,r4,r14,lsr r1
+	subs	r3,r3,r5		@r5 for r7
+	sbc	r2,r2,r6
+CPDO_sqt_loop1_0:
+	add	r1,r1,#1
+	cmp	r1,#30
+	ble	CPDO_sqt_loop1
+
+	adds	r3,r3,r3
+	adcs	r2,r2,r2
+	bcs	CPDO_sqt_between_1
+	adds	r7,r5,#0x80000000
+	adc	r6,r4,#0
+	cmp	r2,r6
+	cmpeq	r3,r7
+	bcc	CPDO_sqt_between_0
+CPDO_sqt_between_1:
+	orr	r4,r4,#0x00000001
+	subs	r3,r3,r5
+	sbc	r2,r2,r4
+	subs	r3,r3,#0x80000000
+	sbc	r2,r2,#0
+CPDO_sqt_between_0:
+	mov	r1,#0
+
+CPDO_sqt_loop2:
+	adds	r3,r3,r3
+	adcs	r2,r2,r2
+	bcs	CPDO_sqt_loop2_1
+	adds	r7,r5,r8,lsr r1
+	adc	r6,r4,#0
+	cmp	r2,r6
+	cmpeq	r3,r7
+	bcc	CPDO_sqt_loop2_0
+CPDO_sqt_loop2_1:
+	orr	r5,r5,r14,lsr r1
+	subs	r3,r3,r5
+	sbc	r2,r2,r4
+	subs	r3,r3,r8,lsr r1
+	sbc	r2,r2,#0
+CPDO_sqt_loop2_0:
+	add	r1,r1,#1
+	cmp	r1,#30
+	ble	CPDO_sqt_loop2
+
+	adds	r3,r3,r3
+	adcs	r2,r2,r2
+	bcs	CPDO_sqt_after_1
+	cmp	r2,r6
+	cmpeq	r3,r7
+	bcc	CPDO_sqt_after_0
+CPDO_sqt_after_1:
+	orr	r5,r5,#0x00000001
+CPDO_sqt_after_0:
+
+	mov	r1,#0
+	stmia	r0,{r1,r4,r5}
+	b	fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+	
+	.globl	CPDO_rnd
+CPDO_rnd:
+	ldmia	r2,{r1,r2,r3,r5}
+        bl      CPDO_rnd_core
+
+CPDO_rnd_store:
+	stmia	r0,{r1,r2,r3,r5}
+    	b	fastfpe_next
+	
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_rnd_core
+CPDO_rnd_core:
+	and	r4,r4,#0x00000060
+	add	pc,pc,r4,lsr#3
+	mov	r0,r0
+	b	CPDO_rnd_N
+	b	CPDO_rnd_P
+	b	CPDO_rnd_M
+	b	CPDO_rnd_Z
+	
+CPDO_rnd_N:
+	cmp	r5,#-1
+	blt	CPDO_rnd_zero
+	cmp	r5,#63
+	movge	pc,r14
+	mov	r4,#0x40000000
+	cmp	r5,#31
+	bge	CPDO_rnd_N_2
+
+	adds	r2,r2,r4,lsr r5
+	bcc	CPDO_rnd_end
+	b	CPDO_rnd_end_norm
+
+CPDO_rnd_N_2:
+CPDO_rnd_P_2:
+	sub	r6,r5,#32
+	adds	r3,r3,r4,ror r6	@ror ist needed to handle a -1 correctly
+	adcs	r2,r2,#0
+	bcc	CPDO_rnd_end
+	b	CPDO_rnd_end_norm
+
+CPDO_rnd_P:
+	tst	r1,#0x80000000
+	bne	CPDO_rnd_M_entry
+CPDO_rnd_P_entry:
+	cmp	r5,#0
+	blt	CPDO_rnd_P_small
+	cmp	r5,#63
+	movge	pc,r14
+	mov	r4,#0x7fffffff
+	cmp	r5,#32
+	bge	CPDO_rnd_P_2
+
+	adds	r3,r3,#0xffffffff
+	adcs	r2,r2,r4,lsr r5
+	bcc	CPDO_rnd_end
+	b	CPDO_rnd_end_norm
+
+CPDO_rnd_P_small:
+	cmp	r5,#0x80000000
+	moveq	pc,r14
+	b	CPDO_rnd_one
+
+CPDO_rnd_M:
+	tst	r1,#0x80000000
+	bne	CPDO_rnd_P_entry
+CPDO_rnd_M_entry:
+	cmp	r5,#0
+	blt	CPDO_rnd_zero
+	cmp	r5,#63
+	movge	pc,r14
+
+	b	CPDO_rnd_end
+	
+CPDO_rnd_Z:
+	cmp	r5,#0
+	blt	CPDO_rnd_zero
+	cmp	r5,#63
+	movge	pc,r14
+	b	CPDO_rnd_end
+
+CPDO_rnd_end_norm:
+	add	r5,r5,#1
+	movs	r2,r2,rrx
+	mov	r3,r3,rrx
+CPDO_rnd_end:
+	rsbs	r4,r5,#31
+	bmi	CPDO_rnd_end_2
+	mov     r3,#0
+	mov     r2,r2,lsr r4
+	mov	r2,r2,lsl r4
+	mov	pc,r14
+
+CPDO_rnd_end_2:
+	rsb	r4,r5,#63
+	mov	r3,r3,lsr r4
+	mov	r3,r3,lsl r4
+	mov	pc,r14
+
+CPDO_rnd_one:
+	mov	r2,#0x80000000
+	mov	r3,#0
+	mov	r5,#0
+	mov	pc,r14
+	
+CPDO_rnd_zero:
+	mov	r1,#0
+	mov	r2,#0
+	mov	r3,#0
+	mov	r5,#0x80000000
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
diff -urN linux-2.4.29/arch/arm/fastfpe/CPDT.S linux-2.4.29-uc1/arch/arm/fastfpe/CPDT.S
--- linux-2.4.29/arch/arm/fastfpe/CPDT.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/fastfpe/CPDT.S	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,430 @@
+/*
+The FP structure has 4 words reserved for each register, the first is used just
+for the sign in bit 31, the second and third are for the mantissa (unsigned
+integer, high 32 bit first) and the fourth is the exponent (signed integer).
+The mantissa is always normalized.
+
+If the exponent is 0x80000000, that is the most negative value, the number
+represented is 0 and both mantissa words are also 0.
+
+If the exponent is 0x7fffffff, that is the biggest positive value, the number
+represented is infinity if the high 32 mantissa bit are also 0, otherwise it is
+a NaN. The low 32 mantissa bit are 0 if the number represented is infinity.
+
+Decimal and packed decimal numbers are not supported yet.
+*/
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_load_single
+CPDT_load_single:
+	ldr	r1,[r6]
+	
+	and	r2,r1,#0x80000000	@ r2 = sign
+	
+	mov	r5,r1,lsr#23
+	bics	r5,r5,#0x100
+	beq	CPDT_ls_e0		@ exponent = 0; zero/denormalized
+	teq	r5,#255
+	beq	CPDT_ls_e255		@ exponent = 255; infinity/NaN
+
+	sub     r5,r5,#127		@ r5 = exponent, remove normalized bias
+
+	mov	r3,r1,lsl#8
+	orr	r3,r3,#0x80000000
+	mov	r4,#0			@ r3,r4 = mantissa
+
+	stmia	r0,{r2-r5}
+	b	fastfpe_next
+
+CPDT_ls_e0:
+	movs	r3,r1,lsl#9
+	beq	CPDT_load_zero
+
+	mov	r5,#-127
+
+CPDT_ls_e0_norm:
+	tst	r3,#0x80000000
+	subeq	r5,r5,#1
+	moveq	r3,r3,lsl#1
+	beq	CPDT_ls_e0_norm
+
+	mov	r4,#0
+	stmia	r0,{r2-r5}
+	b	fastfpe_next
+
+CPDT_ls_e255:
+	mov	r3,r1,lsl#9
+	mov	r4,#0
+	mov	r5,#0x7fffffff
+	stmia	r0,{r2-r5}
+	b	fastfpe_next
+
+CPDT_load_zero:
+	mov	r3,#0
+	mov	r4,#0
+	mov	r5,#0x80000000
+	stmia	r0,{r2-r5}
+	b	fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_load_double
+CPDT_load_double:
+	ldr	r1,[r6]
+	ldr	r6,[r6,#4]
+
+	and	r2,r1,#0x80000000	@ r2 = sign
+
+	mov	r5,r1,lsr#20
+	bics	r5,r5,#0x800
+	beq	CPDT_ld_e0		@ exponent = 0; zero/denormalized
+	add	r4,r5,#1
+	teq	r4,#2048
+	beq	CPDT_ld_e2047		@ exponent = 2047; infinity/NaN
+
+	add     r5,r5,#1
+	sub	r5,r5,#1024		@ r5 = exponent, remove normalized bias
+
+	mov	r3,r1,lsl#11
+	orr	r3,r3,#0x80000000
+	orr	r3,r3,r6,lsr #21
+	mov	r4,r6,lsl#11		@ r3,r4 = mantissa
+
+	stmia	r0,{r2-r5}
+	b	fastfpe_next
+
+CPDT_ld_e0:
+	mov	r3,r1,lsl#12
+	orr	r3,r3,r6,lsr#20
+	movs	r4,r6,lsl#12
+	teqeq	r3,#0
+	beq	CPDT_load_zero
+	
+	mov	r5,#1
+	sub	r5,r5,#1024
+
+CPDT_ld_e0_norm:
+	tst	r3,#0x80000000
+	subeq	r5,r5,#1
+	moveqs	r4,r4,lsl#1
+	adceq	r3,r3,r3
+	beq	CPDT_ld_e0_norm
+
+	stmia	r0,{r2-r5}
+	b	fastfpe_next
+
+CPDT_ld_e2047:
+	mov	r3,r1,lsl#12
+	orr	r3,r3,r6,lsr#1
+	bic	r6,r6,#0x80000000
+	orr	r3,r3,r6		@ to get all fraction bits !
+	mov	r4,#0
+	mov	r5,#0x7fffffff
+	stmia	r0,{r2-r5}
+	b	fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_load_extended
+CPDT_load_extended:
+	ldr	r1,[r6]
+	ldr	r3,[r6,#4]
+	ldr	r4,[r6,#8]
+	
+	and	r2,r1,#0x80000000
+	bics	r5,r1,#0x80000000
+	beq	CPDT_le_e0
+	add	r1,r5,#1
+	teq	r4,#32768
+	beq	CPDT_le_e32767
+
+	add	r5,r5,#1
+	sub	r5,r5,#16384
+
+	stmia	r0,{r2-r5}
+	b	fastfpe_next
+
+CPDT_le_e0:
+	teq	r3,#0
+	teqeq	r4,#0
+	beq	CPDT_load_zero
+	
+	mov	r5,#2
+	sub	r5,r5,#16384
+	b	CPDT_ld_e0_norm
+
+CPDT_le_e32767:
+	mov	r3,r3,lsl#1
+	orr	r3,r3,r4,lsr#1
+	bic	r4,r4,#0x80000000
+	orr	r3,r3,r4
+	mov	r5,#0x7fffffff
+	stmia	r0,{r2-r5}
+	b	fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_load_decimal
+CPDT_load_decimal:
+	
+	b	fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_store_single
+CPDT_store_single:
+	ldmia	r0,{r1-r4}
+	
+	cmp	r4,#-127
+	ble	CPDT_ss_e0
+	cmp	r4,#128
+	bge	CPDT_ss_e255
+
+	adds	r2,r2,#1<<7		@ round to nearest
+	bcs	CPDT_ss_rnd_ovfl	@ very very seldom taken
+
+CPDT_ss_store:
+	add	r4,r4,#127
+	orr	r1,r1,r4,lsl#23
+	
+	bic	r2,r2,#0x80000000
+	orr	r1,r1,r2,lsr#8
+
+	str	r1,[r6]
+	b	fastfpe_next
+
+CPDT_ss_rnd_ovfl:
+	add	r4,r4,#1
+	cmp	r4,#128
+	bge	CPDT_ss_e255
+
+	mov	r2,#0x80000000
+	mov	r3,#0
+	b	CPDT_ss_store
+
+CPDT_ss_e0:
+	cmp	r4,#-150
+	ble	CPDT_ss_zero
+
+	add	r4,r4,#126
+CPDT_ss_unnormalize:
+	mov	r2,r2,lsr#1
+	adds	r4,r4,#1
+	bne	CPDT_ss_unnormalize
+
+	orr	r1,r1,r2,lsr#8
+
+CPDT_ss_zero:
+	str	r1,[r6]
+	b	fastfpe_next
+
+CPDT_ss_e255:
+	cmp	r4,#0x7fffffff
+	bne	CPDT_ss_inf
+	cmp	r2,#0
+	beq	CPDT_ss_inf
+
+	orr	r1,r1,#0x00200000	@ for safety so that it is not INF
+	orr	r1,r1,r2,lsr#9		@ get highest bit of mantissa
+
+CPDT_ss_inf:
+	orr	r1,r1,#0x7f000000
+	orr	r1,r1,#0x00800000
+	str	r1,[r6]
+	b	fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_store_double
+CPDT_store_double:
+	ldmia	r0,{r1-r4}
+	
+	cmp	r4,#1024		@ this check has to be first, or
+	bge	CPDT_sd_e2047		@ overflow can occur on second !
+	add	r0,r4,#3
+	cmp	r0,#-1023+3		@ cmp with -1023
+	ble	CPDT_sd_e0
+
+	adds	r3,r3,#1<<10		@ round to nearest
+	adcs	r2,r2,#0
+	bcs	CPDT_sd_rnd_ovfl	@ very very seldom taken
+
+CPDT_sd_store:
+	sub	r4,r4,#1
+	add	r4,r4,#1024
+	orr	r1,r1,r4,lsl#20
+	
+	bic	r2,r2,#0x80000000
+	orr	r1,r1,r2,lsr#11
+
+	mov	r2,r2,lsl#21
+	orr	r2,r2,r3,lsr#11
+
+	stmia	r6,{r1,r2}
+	b	fastfpe_next
+
+CPDT_sd_rnd_ovfl:
+	add	r4,r4,#1
+	cmp	r4,#1024
+	bge	CPDT_sd_e2047
+
+	mov	r2,#0x80000000
+	mov	r3,#0
+	b	CPDT_sd_store
+
+CPDT_sd_e0:
+	add	r0,r4,#1075-1024
+	cmp	r0,#-1024
+	ble	CPDT_sd_zero
+
+	add	r4,r4,#1024
+	sub	r4,r4,#2
+CPDT_sd_unnormalize:
+	movs	r2,r2,lsr#1
+	mov	r3,r3,rrx
+	adds	r4,r4,#1
+	bne	CPDT_sd_unnormalize
+
+	orr	r1,r1,r2,lsr#11
+	mov	r2,r2,lsl#21
+	orr	r2,r2,r3,lsr#11
+
+	stmia	r6,{r1,r2}
+	b	fastfpe_next
+
+CPDT_sd_zero:
+	mov	r2,#0
+	stmia	r6,{r1,r2}
+	b	fastfpe_next
+
+CPDT_sd_e2047:
+	cmp	r4,#0x7fffffff
+	bne	CPDT_sd_inf
+	cmp	r2,#0
+	beq	CPDT_sd_inf
+
+	orr	r1,r1,#0x00040000	@ for safety so that it is not INF
+	orr	r1,r1,r2,lsr#12		@ get highest bit of mantissa
+
+CPDT_sd_inf:
+	orr	r1,r1,#0x7f000000
+	orr	r1,r1,#0x00f00000
+	stmia	r6,{r1,r2}
+	b	fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_store_extended
+CPDT_store_extended:
+	ldmia	r0,{r1-r4}
+	
+	cmp	r4,#16384		@ this check has to be first, or
+	bge	CPDT_se_e32767		@ overflow can occur with second !
+	add	r0,r4,#63
+	cmp	r0,#-16383+63
+	ble	CPDT_se_e0
+
+	sub	r4,r4,#1
+	add	r4,r4,#16384
+	orr	r1,r1,r4
+	
+	stmia	r6,{r1-r3}
+	b	fastfpe_next
+
+CPDT_se_e0:
+	add	r0,r4,#16446-16384
+	cmp	r0,#-16384
+	ble	CPDT_se_zero
+
+	add	r4,r4,#16384
+	sub	r4,r4,#2
+CPDT_se_unnormalize:
+	movs	r2,r2,lsr#1
+	mov	r3,r3,rrx
+	adds	r4,r4,#1
+	bne	CPDT_se_unnormalize
+
+	stmia	r6,{r1-r3}
+	b	fastfpe_next
+	
+CPDT_se_zero:
+	mov	r2,#0
+	mov	r3,#0
+	stmia	r6,{r1-r3}
+	b	fastfpe_next
+
+CPDT_se_e32767:
+	cmp	r4,#0x7fffffff
+	bne	CPDT_se_inf
+	cmp	r2,#0
+	beq	CPDT_se_inf
+
+	mov	r2,r2,lsl#1
+	orr	r2,r2,#0x20000000
+
+CPDT_se_inf:
+	orr	r1,r1,#0x00007f00
+	orr	r1,r1,#0x000000ff
+	stmia	r6,{r1-r3}
+	b	fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_store_decimal
+CPDT_store_decimal:
+
+	b	fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_sfm
+CPDT_sfm:
+	add	r2,r10,r0,lsr#8
+	ldr	r4,[r2,#0]
+	ldr	r3,[r2,#4]
+	bic	r3,r3,#0x80000000
+	orr	r3,r3,r4
+	str	r3,[r6],#4
+	ldr	r3,[r2,#8]
+	str	r3,[r6],#4
+	ldr	r3,[r2,#12]
+	str	r3,[r6],#4
+
+	add	r0,r0,#1<<12
+	and	r0,r0,#7<<12
+	subs	r1,r1,#1
+	bne	CPDT_sfm
+	b	fastfpe_next
+	
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_lfm
+CPDT_lfm:
+	add	r2,r10,r0,lsr#8
+	ldr	r4,[r6],#4
+	and	r3,r4,#0x80000000
+	str	r3,[r2,#0]
+	ldr	r3,[r6],#4
+	str	r3,[r2,#8]
+	ldr	r3,[r6],#4
+	str	r3,[r2,#12]
+
+	cmp	r3,#0x80000000		@ does the exp indicate zero?
+	biceq	r4,r4,#0x80000000	@ if so, indicate 'denormalized'
+	beq	CPDT_lfm_storer4
+	cmp	r3,#0x7fffffff		@ does the exp indicate inf or NaN?
+	biceq	r4,r4,#0x80000000	@ if so, indicate 'denormalized'
+	beq	CPDT_lfm_storer4
+	orrne	r4,r4,#0x80000000	@ otherwise, set normalized bit
+
+CPDT_lfm_storer4:
+	str	r4,[r2,#4]
+
+	add	r0,r0,#1<<12
+	and	r0,r0,#7<<12
+	subs	r1,r1,#1
+	bne	CPDT_lfm
+	b	fastfpe_next
+	
+/*---------------------------------------------------------------------------*/
diff -urN linux-2.4.29/arch/arm/fastfpe/CPRT.S linux-2.4.29-uc1/arch/arm/fastfpe/CPRT.S
--- linux-2.4.29/arch/arm/fastfpe/CPRT.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/fastfpe/CPRT.S	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,185 @@
+/*
+The FP structure has 4 words reserved for each register, the first is used
+just
+for the sign in bit 31, the second and third are for the mantissa (unsigned
+integer, high 32 bit first) and the fourth is the exponent (signed integer).
+The mantissa is always normalized.
+
+If the exponent is 0x80000000, that is the most negative value, the number
+represented is 0 and both mantissa words are also 0.
+
+If the exponent is 0x7fffffff, that is the biggest positive value, the
+number
+represented is infinity if the high 32 mantissa bit are also 0, otherwise it
+is
+a NaN. The low 32 mantissa bit are 0 if the number represented is infinity.
+
+Decimal and packed decimal numbers are not supported yet.
+*/
+
+/*---------------------------------------------------------------------------*/
+
+	.text
+	.globl	CPRT_flt
+CPRT_flt:
+	add	r0,r13,r0,lsr#10
+	ldr	r2,[r0]
+	mov	r3,#0
+	cmp	r2,#0
+	beq	CPRT_flt_zero
+	
+	ands	r0,r2,#0x80000000
+	rsbne	r2,r2,#0
+	mov	r4,#31
+	
+	cmp	r2,#0x00010000
+	movcc	r2,r2,lsl#16
+	subcc	r4,r4,#16
+	
+	cmp	r2,#0x01000000
+	movcc	r2,r2,lsl#8
+	subcc	r4,r4,#8
+	
+	cmp	r2,#0x10000000
+	movcc	r2,r2,lsl#4
+	subcc	r4,r4,#4
+	
+	cmp	r2,#0x40000000
+	movcc	r2,r2,lsl#2
+	subcc	r4,r4,#2
+	
+	cmp	r2,#0x80000000
+	movcc	r2,r2,lsl#1
+	subcc	r4,r4,#1
+
+	stmia	r1,{r0,r2,r3,r4}
+	b	fastfpe_next
+
+CPRT_flt_zero:
+	mov	r0,#0
+	mov	r4,#0x80000000
+	stmia	r1,{r0,r2,r3,r4}
+	b	fastfpe_next
+	
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPRT_fix
+CPRT_fix:
+	ldmia	r2,{r1,r2,r3,r5}
+	bl	CPDO_rnd_core
+	
+CPRT_back:
+	add	r0,r13,r0,lsr#10
+	cmp	r5,#0
+	blt	CPRT_int_zero
+	cmp	r5,#30
+	bgt	CPRT_overflow
+	
+	rsb	r5,r5,#31
+	mov	r2,r2,lsr r5
+	tst	r1,#0x80000000
+	rsbne	r2,r2,#0
+	
+	str	r2,[r0]
+	b	fastfpe_next
+
+CPRT_int_zero:
+	mov	r2,#0
+	str	r2,[r0]
+	b	fastfpe_next
+
+CPRT_overflow:
+	mov	r2,#0x80000000
+	tst	r1,#0x80000000
+	subeq	r2,r2,#1
+	str	r2,[r0]
+	b	fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPRT_wfs
+CPRT_wfs:
+	b	fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPRT_rfs
+CPRT_rfs:
+	add	r0,r13,r0,lsr#10
+	mov	r1,#0x02000000		@ Software Emulation, not Acorn FPE
+	str	r1,[r0]
+	b	fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPRT_cmf
+CPRT_cmf:
+	ldmia	r1,{r1,r3,r5,r7}
+	ldmia	r2,{r2,r4,r6,r8}
+
+CPRT_cmf_e:
+	ldr	r0,[r13,#16*4]
+	
+	cmp	r7,#0x7fffffff
+	bic	r0,r0,#0xf0000000
+
+	cmpeq	r3,#0xffffffff
+	beq	CPRT_cmf_unordered
+	cmp	r8,#0x7fffffff
+	cmpeq	r4,#0xffffffff
+	beq	CPRT_cmf_unordered
+
+	cmp	r1,r2
+	beq	CPRT_cmf_equalsign
+	b	CPRT_cmf_sign
+
+CPRT_cmf_equalsign:
+	cmp	r7,r8
+	beq	CPRT_cmf_equalexponent
+	bgt	CPRT_cmf_sign
+	b	CPRT_cmf_signb	
+
+CPRT_cmf_equalexponent:
+	cmp	r3,r4
+	cmpeq	r5,r6
+	beq	CPRT_cmf_equal
+	bhi	CPRT_cmf_sign
+	b	CPRT_cmf_signb
+
+CPRT_cmf_sign:
+	cmp     r7,#0x80000000		@ (0.0 == -0.0)?
+	cmpeq   r7,r8
+	beq     CPRT_cmf_equal
+	tst	r1,#0x80000000
+	orreq	r0,r0,#0x20000000
+	orrne	r0,r0,#0x80000000
+	str	r0,[r13,#16*4]
+	b	fastfpe_next
+
+CPRT_cmf_signb:
+	tst	r1,#0x80000000
+	orrne	r0,r0,#0x20000000
+	orreq	r0,r0,#0x80000000
+	str	r0,[r13,#16*4] 
+	b	fastfpe_next
+
+CPRT_cmf_equal:
+	orr	r0,r0,#0x60000000
+	str	r0,[r13,#16*4]
+	b	fastfpe_next
+
+CPRT_cmf_unordered:
+	orr	r0,r0,#0x10000000
+        str     r0,[r13,#16*4]
+        b       fastfpe_next
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPRT_cnf
+CPRT_cnf:
+	ldmia	r1,{r1,r3,r5,r7}
+	ldmia	r2,{r2,r4,r6,r8}
+	eor	r2,r2,#0x80000000
+	b	CPRT_cmf_e
+
+/*---------------------------------------------------------------------------*/
diff -urN linux-2.4.29/arch/arm/fastfpe/entry.S linux-2.4.29-uc1/arch/arm/fastfpe/entry.S
--- linux-2.4.29/arch/arm/fastfpe/entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/fastfpe/entry.S	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,295 @@
+/*
+At entry the registers contain the following information:
+
+r14	return address for undefined exception return
+r9	return address for return from exception
+r13	user registers on stack, offset 0 up to offset 4*15 contains
+	registers r0..15, then the psr
+r10	FP workspace 35 words (init, reg[8][4], fpsr, fpcr)
+ 
+*/
+
+/*---------------------------------------------------------------------------*/
+
+	.data
+fp_const:
+	.word	0, 0x00000000, 0, 0x80000000	@ 0
+	.word	0, 0x80000000, 0,          0	@ 1
+	.word	0, 0x80000000, 0,          1	@ 2
+	.word	0, 0xc0000000, 0,          1	@ 3
+	.word	0, 0x80000000, 0,          2	@ 4
+	.word	0, 0xa0000000, 0,          2	@ 5
+	.word	0, 0x80000000, 0,	  -1	@ 0.5
+	.word	0, 0xa0000000, 0,          3	@ 10
+fp_undef:
+	.word	0
+fp_cond:
+	.word	0xf0f0	@ eq
+	.word	0x0f0f	@ ne
+	.word	0xcccc	@ cs
+	.word	0x3333	@ cc
+	.word	0xff00	@ mi
+	.word	0x00ff	@ pl
+	.word	0xaaaa	@ vs
+	.word	0x5555	@ vc
+	.word	0x0c0c	@ hi
+	.word	0xf3f3	@ ls
+	.word	0xaa55	@ ge
+	.word	0x55aa	@ lt
+	.word	0x0a05	@ gt
+	.word	0xf5fa	@ le
+	.word	0xffff	@ al
+	.word	0x0000	@ nv
+	
+/*---------------------------------------------------------------------------*/
+	
+	.text
+	.globl	fastfpe_enter
+fastfpe_enter:
+	ldr	r4,=fp_undef
+	str	r14,[r4]		@ to free one register
+	add	r10,r10,#4		@ to make the code simpler
+	ldr	r4,[r13,#60]		@ r4=saved PC
+	ldr	r4,[r4,#-4]		@ r4=trapped instruction
+	and	r1,r4,#0x00000f00	@ r1=coprocessor << 8
+next_enter:
+	cmp	r1,#1<<8		@ copro 1 ?
+	beq	copro_1
+	cmp	r1,#2<<8
+	movne	pc,r14
+
+copro_2:
+	and	r1,r4,#0x0f000000
+	cmp	r1,#0x0c000000          @ CPDT with post indexing
+        cmpne   r1,#0x0d000000          @ CPDT with pre indexing
+        beq     CPDT_M_enter
+	mov	pc,r14
+
+copro_1:
+	and	r1,r4,#0x0f000000
+	cmp	r1,#0x0e000000		@ CPDO
+	beq	CPDO_CPRT_enter
+	cmp	r1,#0x0c000000		@ CPDT with post indexing
+	cmpne	r1,#0x0d000000		@ CPDT with pre indexing
+	beq	CPDT_1_enter
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	fastfpe_next
+fastfpe_next:
+	ldr	r5,[r13,#60]
+next_after_cond:
+__x1:
+	ldrt	r4,[r5],#4
+	
+	ldr	r0,=fp_cond		@ check condition of next instruction
+	ldr	r1,[r13,#64]		@ psr containing flags
+	mov	r2,r4,lsr#28
+	mov	r1,r1,lsr#28
+	ldr	r0,[r0,r2,lsl#2]
+	mov	r0,r0,lsr r1
+	tst	r0,#1
+	beq	next_after_cond		@ must not necessarily have been an
+					@ FP instruction !
+	and	r1,r4,#0x0f000000	@ Test for copro instruction
+	cmp	r1,#0x0c000000
+	rsbgts	r0,r1,#0x0e000000	@ cmpgt #0x0e000000,r1
+	movlt	pc,r9			@ next is no copro instruction, return
+	
+	ands	r1,r4,#0x00000f00	@ r1 = coprocessor << 8
+	cmpne	r1,#3<<8
+	movge	pc,r9			@ copro = 0 or >=3, return
+		
+	str	r5,[r13,#60]		@ save updated pc
+	b	next_enter
+
+/*---------------------------------------------------------------------------*/
+
+undefined:
+	ldr	r4,=fp_undef
+	ldr	pc,[r4]	
+
+/*---------------------------------------------------------------------------*/
+
+CPDT_1_enter:
+	and	r5,r4,#0x000f0000	@ r5=base register number << 16
+	ldr	r6,[r13,r5,lsr#14]	@ r6=base address
+	cmp	r5,#0x000f0000		@ base register = pc ?
+	addeq	r6,r6,#4
+	and	r7,r4,#0x000000ff	@ r7=offset value
+
+	tst	r4,#0x00800000		@ up or down?
+	addne	r7,r6,r7,lsl#2
+	subeq	r7,r6,r7,lsl#2		@ r6=base address +/- offset
+	tst	r4,#0x01000000		@ preindexing ?
+	movne	r6,r7
+	tst	r4,#0x00200000		@ write back ?
+	cmpne	r5,#0x000f0000		@ base register = pc ?
+	strne	r7,[r13,r5,lsr#14]
+
+	and	r0,r4,#0x00007000	@ r0=fp register number << 12
+	add	r0,r10,r0,lsr#8		@ r0=address of fp register
+	mov	r1,#0
+	tst	r4,#0x00008000
+	orrne	r1,r1,#1		@ T0
+	tst	r4,#0x00400000
+	orrne	r1,r1,#2		@ T1
+	tst	r4,#0x00100000
+	orrne	r1,r1,#4		@ L/S
+
+	add	pc,pc,r1,lsl#2
+	mov	r0,r0
+	b	CPDT_store_single	@ these functions get 
+	b	CPDT_store_double	@ r0=address of fp register
+	b	CPDT_store_extended	@ r6=address of data
+	b	undefined		@ CPDT_store_decimal
+        b       CPDT_load_single
+        b       CPDT_load_double
+        b       CPDT_load_extended
+        b       undefined		@ CPDT_load_decimal
+
+/*---------------------------------------------------------------------------*/
+
+CPDT_M_enter:
+	and	r5,r4,#0x000f0000	@ r5=base register number << 16
+	ldr	r6,[r13,r5,lsr#14]	@ r6=base address
+	cmp	r5,#0x000f0000		@ base register = pc ?
+	addeq	r6,r6,#4
+	and	r7,r4,#0x000000ff	@ r7=offset value
+
+	tst	r4,#0x00800000		@ up or down?
+	addne	r7,r6,r7,lsl#2
+	subeq	r7,r6,r7,lsl#2		@ r7=base address +/- offset
+	tst	r4,#0x01000000		@ preindexing ?
+	movne	r6,r7
+	tst	r4,#0x00200000		@ write back ?
+	cmpne	r5,#0x000f0000		@ base register = pc ?
+	strne	r7,[r13,r5,lsr#14]
+
+	and	r0,r4,#0x00007000	@ r0=fp register number << 12
+	and	r1,r4,#0x00008000
+	mov	r1,r1,lsr#15		@ N0
+	and	r2,r4,#0x00400000
+	orrs	r1,r1,r2,lsr#21		@ N1
+	addeq	r1,r1,#4		@ r1=register count
+
+	tst	r4,#0x00100000		@ load/store
+	beq	CPDT_sfm
+	b	CPDT_lfm
+
+/*---------------------------------------------------------------------------*/
+
+CPDO_CPRT_enter:
+	tst	r4,#0x00000010
+	bne	CPRT_enter
+	
+	and	r0,r4,#0x00007000
+	add	r0,r10,r0,lsr#8		@ r0=address of Fd
+	and	r1,r4,#0x00070000
+	add	r1,r10,r1,lsr#12	@ r1=address of Fn
+	tst	r4,#0x00000008
+	bne	CPDO_const
+	and	r2,r4,#0x00000007
+	add	r2,r10,r2,lsl#4		@ r2=address of Fm
+	
+CPDO_constback:
+	and	r3,r4,#0x00f00000
+	tst	r4,#0x00008000
+	orrne	r3,r3,#0x01000000
+		
+	add	pc,pc,r3,lsr#18
+	mov	r0,r0
+	b	CPDO_adf
+	b	CPDO_muf
+	b	CPDO_suf
+	b	CPDO_rsf
+	b	CPDO_dvf
+	b	CPDO_rdf
+	b	undefined
+	b	undefined
+	b	undefined		@ CPDO_rmf
+	b	CPDO_muf
+	b	CPDO_dvf
+	b	CPDO_rdf
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	CPDO_mvf
+	b	CPDO_mnf
+	b	CPDO_abs
+	b	CPDO_rnd
+	b	CPDO_sqt
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	CPDO_rnd
+	b	fastfpe_next
+
+CPDO_const:
+	ldr	r2,=fp_const
+	and	r3,r4,#0x00000007
+	add	r2,r2,r3,lsl#4	
+	b	CPDO_constback
+	
+/*---------------------------------------------------------------------------*/
+
+CPRT_enter:
+	and	r0,r4,#0x0000f000	@ r0=Rd<<12
+	and	r1,r4,#0x00070000
+	add	r1,r10,r1,lsr#12	@ r1=address of Fn
+	tst	r4,#0x00000008
+	bne	CPRT_const
+	and	r2,r4,#0x00000007
+	add	r2,r10,r2,lsl#4		@ r2=address of Fm
+	
+CPRT_constback:
+	and	r3,r4,#0x00f00000
+		
+	add	pc,pc,r3,lsr#18
+	mov	r0,r0
+	b	CPRT_flt
+	b	CPRT_fix
+	b	CPRT_wfs
+	b	CPRT_rfs
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	CPRT_cmf
+	b	undefined
+	b	CPRT_cnf
+	b	undefined
+	b	CPRT_cmf
+	b	undefined
+	b	CPRT_cnf
+
+CPRT_const:
+	ldr	r2,=fp_const
+	and	r3,r4,#0x00000007
+	add	r2,r2,r3,lsl#4	
+	b	CPRT_constback
+	
+/*---------------------------------------------------------------------------*/
+
+	@ The fetch of the next instruction to emulate could fault
+
+	.section .fixup,"ax"
+	.align
+__f1:
+	mov	pc,r9
+	.previous
+	.section __ex_table,"a"
+	.align 3
+	.long	__x1,__f1
+	.previous
+	
+/*---------------------------------------------------------------------------*/
diff -urN linux-2.4.29/arch/arm/fastfpe/Makefile linux-2.4.29-uc1/arch/arm/fastfpe/Makefile
--- linux-2.4.29/arch/arm/fastfpe/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/fastfpe/Makefile	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,25 @@
+#
+# linux/arch/arm/fastfpe/Makefile
+#
+# Copyright (C) Peter Teichmann
+#
+
+O_TARGET := fast-math-emu.o
+
+obj-y	:=
+obj-m	:=
+obj-n	:=
+obj-	:=
+
+fastfpe-objs := module.o entry.o CPDO.o CPRT.o CPDT.o
+
+list-multi := fastfpe.o
+
+obj-$(CONFIG_FPE_FASTFPE) += fastfpe.o
+
+USE_STANDARD_AS_RULE := true
+
+include $(TOPDIR)/Rules.make
+
+fastfpe.o: $(fastfpe-objs)
+	 $(LD) -r -o $@ $(fastfpe-objs)
diff -urN linux-2.4.29/arch/arm/fastfpe/module.c linux-2.4.29-uc1/arch/arm/fastfpe/module.c
--- linux-2.4.29/arch/arm/fastfpe/module.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/fastfpe/module.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,78 @@
+/*
+    Fast Floating Point Emulator
+    (c) Peter Teichmann <mail@peter-teichmann.de>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#ifndef MODULE
+#define kern_fp_enter	fp_enter
+
+extern char fpe_type[];
+#endif
+
+static void (*orig_fp_enter)(void);	/* old kern_fp_enter value */
+extern void (*kern_fp_enter)(void);	/* current FP handler */
+extern void fastfpe_enter(void);	/* forward declarations */
+
+#ifdef MODULE
+/*
+ * Return 0 if we can be unloaded.  This can only happen if
+ * kern_fp_enter is still pointing at fastfpe_enter
+ */
+static int fpe_unload(void)
+{
+  return (kern_fp_enter == fastfpe_enter) ? 0 : 1;
+}
+#endif
+
+static int __init fpe_init(void)
+{
+#ifdef MODULE
+  if (!mod_member_present(&__this_module, can_unload))
+    return -EINVAL;
+  __this_module.can_unload = fpe_unload;
+#else
+  if (fpe_type[0] && strcmp(fpe_type, "fastfpe"))
+    return 0;
+#endif
+
+  printk("Fast Floating Point Emulator V0.9 (c) Peter Teichmann.\n");
+
+  /* Save pointer to the old FP handler and then patch ourselves in */
+  orig_fp_enter = kern_fp_enter;
+  kern_fp_enter = fastfpe_enter;
+
+  return 0;
+}
+
+static void __exit fpe_exit(void)
+{
+  /* Restore the values we saved earlier. */
+  kern_fp_enter = orig_fp_enter;
+}
+
+module_init(fpe_init);
+module_exit(fpe_exit);
+
+MODULE_AUTHOR("Peter Teichmann <mail@peter-teichmann.de>");
+MODULE_DESCRIPTION("Fast floating point emulator with full precision");
diff -urN linux-2.4.29/arch/arm/kernel/armksyms.c linux-2.4.29-uc1/arch/arm/kernel/armksyms.c
--- linux-2.4.29/arch/arm/kernel/armksyms.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/armksyms.c	2005-06-14 02:11:00.000000000 +0100
@@ -57,6 +57,7 @@
 extern void __ashldi3(void);
 extern void __ashrdi3(void);
 extern void __divsi3(void);
+extern void __divdi3(void);
 extern void __lshrdi3(void);
 extern void __modsi3(void);
 extern void __muldi3(void);
@@ -228,6 +229,7 @@
 EXPORT_SYMBOL_NOVERS(__ashldi3);
 EXPORT_SYMBOL_NOVERS(__ashrdi3);
 EXPORT_SYMBOL_NOVERS(__divsi3);
+EXPORT_SYMBOL_NOVERS(__divdi3);
 EXPORT_SYMBOL_NOVERS(__lshrdi3);
 EXPORT_SYMBOL_NOVERS(__modsi3);
 EXPORT_SYMBOL_NOVERS(__muldi3);
@@ -240,14 +242,25 @@
 EXPORT_SYMBOL_NOVERS(abort);
 
 	/* bitops */
-EXPORT_SYMBOL(set_bit);
-EXPORT_SYMBOL(test_and_set_bit);
-EXPORT_SYMBOL(clear_bit);
-EXPORT_SYMBOL(test_and_clear_bit);
-EXPORT_SYMBOL(change_bit);
-EXPORT_SYMBOL(test_and_change_bit);
-EXPORT_SYMBOL(find_first_zero_bit);
-EXPORT_SYMBOL(find_next_zero_bit);
+EXPORT_SYMBOL(_set_bit_le);
+EXPORT_SYMBOL(_test_and_set_bit_le);
+EXPORT_SYMBOL(_clear_bit_le);
+EXPORT_SYMBOL(_test_and_clear_bit_le);
+EXPORT_SYMBOL(_change_bit_le);
+EXPORT_SYMBOL(_test_and_change_bit_le);
+EXPORT_SYMBOL(_find_first_zero_bit_le);
+EXPORT_SYMBOL(_find_next_zero_bit_le);
+
+#ifdef __ARMEB__
+EXPORT_SYMBOL(_set_bit_be);
+EXPORT_SYMBOL(_test_and_set_bit_be);
+EXPORT_SYMBOL(_clear_bit_be);
+EXPORT_SYMBOL(_test_and_clear_bit_be);
+EXPORT_SYMBOL(_change_bit_be);
+EXPORT_SYMBOL(_test_and_change_bit_be);
+EXPORT_SYMBOL(_find_first_zero_bit_be);
+EXPORT_SYMBOL(_find_next_zero_bit_be);
+#endif
 
 	/* elf */
 EXPORT_SYMBOL(elf_platform);
diff -urN linux-2.4.29/arch/arm/kernel/bios32.c linux-2.4.29-uc1/arch/arm/kernel/bios32.c
--- linux-2.4.29/arch/arm/kernel/bios32.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/bios32.c	2005-06-14 02:11:00.000000000 +0100
@@ -19,20 +19,6 @@
 static int debug_pci;
 int have_isa_bridge;
 
-struct pci_sys_data {
-	/*
-	 * The hardware we are attached to
-	 */
-	struct hw_pci	*hw;
-
-	unsigned long	mem_offset;
-
-	/*
-	 * These are the resources for the root bus.
-	 */
-	struct resource *resource[3];
-};
-
 void pcibios_report_status(u_int status_mask, int warn)
 {
 	struct pci_dev *dev;
@@ -245,7 +231,30 @@
 	}
 }
 
+
+#ifdef CONFIG_ARCH_IXP1200
+/* Properly setup 32-byte cache line size */
+static void __init pci_fixup_ixp12xx(struct pci_dev *dev)
+{
+	u8 foo;
+	pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &foo);
+
+	printk("PCI: %s has cache line of %#02x\n", dev->name, foo);
+
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
+
+}
+#endif
+
+
 struct pci_fixup pcibios_fixups[] = {
+#ifdef CONFIG_ARCH_IXP12xx
+	{
+		PCI_FIXUP_FINAL,
+		PCI_ANY_ID,		PCI_ANY_ID,
+		pci_fixup_ixp12xx
+	},
+#endif
 	{
 		PCI_FIXUP_HEADER,
 		PCI_VENDOR_ID_CONTAQ,	PCI_DEVICE_ID_CONTAQ_82C693,
@@ -456,6 +465,20 @@
 extern struct hw_pci ftv_pci;
 extern struct hw_pci shark_pci;
 extern struct hw_pci integrator_pci;
+extern struct hw_pci ks8695p_pci;
+extern struct hw_pci ixp1200_pci;
+extern struct hw_pci iq80310_pci;
+extern struct hw_pci iq80321_pci;
+extern struct hw_pci iq31244_pci;
+extern struct hw_pci brh_pci;
+extern struct hw_pci ixdp425_pci;
+extern struct hw_pci coyote_pci;
+extern struct hw_pci ess710_pci;
+extern struct hw_pci sg580_pci;
+extern struct hw_pci montejade_pci;
+extern struct hw_pci ixdp2400_pci;
+extern struct hw_pci ixdp2800_pci;
+extern struct hw_pci prpmc1100_pci;
 
 void __init pcibios_init(void)
 {
@@ -505,6 +528,77 @@
 			break;
 		}
 #endif
+#ifdef CONFIG_ARCH_KS8695
+		if (machine_is_ks8695()) {
+                        hw = &ks8695p_pci;
+			break;
+                 }
+#endif
+#ifdef CONFIG_ARCH_IXP1200
+		if(machine_is_ixp1200()) {
+			hw = &ixp1200_pci;
+			break;
+		}
+#endif
+#ifdef CONFIG_ARCH_IOP3XX
+		if(machine_is_iq80310()) {
+			hw = &iq80310_pci;
+			break;
+		}
+		if(machine_is_iq80321()) {
+			hw = &iq80321_pci;
+			break;
+		}
+		if(machine_is_iq31244()) {
+			hw = &iq31244_pci;
+			break;
+		}
+#endif
+#ifdef	CONFIG_ARCH_BRH
+		if (machine_is_brh()) {
+			hw = &brh_pci;
+			break;
+		}
+#endif
+#ifdef CONFIG_ARCH_IXP425
+		if (machine_is_ixdp425() || machine_is_ixdp465()) {
+			hw = &ixdp425_pci;
+			break;
+		}
+		if (machine_is_prpmc1100()) {
+			hw = &prpmc1100_pci;
+			break;
+		}
+		if (machine_is_adi_coyote()) {
+			hw = &coyote_pci;
+			break;
+		}
+		if (machine_is_ess710()) {
+			hw = &ess710_pci;
+			break;
+		}
+		if (machine_is_sg565() || machine_is_sg580() ||
+				machine_is_shiva1100()) {
+			hw = &sg580_pci;
+			break;
+		}
+		if (machine_is_montejade() || machine_is_se5100()) {
+			hw = &montejade_pci;
+			break;
+		}
+#endif
+#ifdef CONFIG_ARCH_IXDP2400
+		if (machine_is_ixdp2400()) {
+			hw = &ixdp2400_pci;
+			break;
+		}
+#endif
+#ifdef CONFIG_ARCH_IXDP2800
+		if (machine_is_ixdp2800()) {
+			hw = &ixdp2800_pci;
+			break;
+		}
+#endif
 	} while (0);
 
 	if (hw == NULL)
@@ -541,7 +635,12 @@
 	/*
 	 * Assign any unassigned resources.
 	 */
+
+	// TODO: Make PCI_AUTO go away
+#ifndef CONFIG_PCI_AUTOCONFIG
 	pci_assign_unassigned_resources();
+#endif
+
 	pci_fixup_irqs(root->hw->swizzle, root->hw->map_irq);
 }
 
diff -urN linux-2.4.29/arch/arm/kernel/debug-armv.S linux-2.4.29-uc1/arch/arm/kernel/debug-armv.S
--- linux-2.4.29/arch/arm/kernel/debug-armv.S	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/debug-armv.S	2005-06-14 02:11:00.000000000 +0100
@@ -435,6 +435,180 @@
 		bne	1001b
 		.endm
 
+#elif defined(CONFIG_ARCH_IXP1200)
+
+                .macro  addruart,rx
+                mrc     p15, 0, \rx, c1, c0
+                tst     \rx, #1                 @ MMU enabled?
+                moveq   \rx, #0x90000000        @ physical base address
+                movne   \rx, #0xf0000000        @ virtual address
+                add     \rx, \rx, #0x00003000   @
+                .endm
+
+                .macro  senduart,rd,rx
+                str     \rd, [\rx, #0xc00]      @ UARTDR
+                .endm
+
+		.macro	busyuart,rd,rx
+1001:           ldr     \rd, [\rx, #0x400]      @ UARTFLG 
+		tst     \rd, #1 << 2            @ loop until set
+                beq     1001b
+                .endm
+
+                .macro  waituart,rd,rx
+                .endm
+
+#elif defined(CONFIG_ARCH_IOP3XX)
+
+		.macro	addruart,rx
+		mov	\rx, #0xfe000000
+#ifdef CONFIG_ARCH_IQ80310)
+		orr	\rx, \rx, #0x00810000
+#elif defined(CONFIG_ARCH_IQ80321) || defined(CONFIG_ARCH_IQ31244)
+		orr	\rx, \rx, #0x00800000
+#else
+#error Unknown IOP3XX implementation
+#endif
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldrb	\rd, [\rx, #0x5]
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		bne	1002b
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
+
+#elif defined(CONFIG_ARCH_ADI_EVB)
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		mov	\rx, #0x00400000	@ physical base address
+		orrne	\rx, \rx, #0xff000000	@ virtual base
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldrb	\rd, [\rx, #0x5]
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		bne	1002b
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldrb	\rd, [\rx, #0x6]
+		tst	\rd, #0x10
+		beq	1001b
+		.endm
+
+#elif defined(CONFIG_ARCH_ADIFCC)
+
+#ifdef CONFIG_ARCH_ADI_EVB
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		mov	\rx, #0x00400000	@ physical base address
+		orrne	\rx, #0xff000000	@ virtual base
+		.endm
+#elif defined(CONFIG_ARCH_BRH)
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0x03000000	@ physical base address
+		movne	\rx, #0xff000000	@ virtual base
+		.endm
+#endif
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldrb	\rd, [\rx, #0x5]
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		bne	1002b
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldrb	\rd, [\rx, #0x6]
+		tst	\rd, #0x10
+		beq	1001b
+		.endm
+
+#elif defined(CONFIG_ARCH_IXP2000)
+
+		.macro  addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0xc0000000	@ Physical base
+		addeq	\rx, \rx, #0x00030000
+		movne	\rx, #0xfa000000	@ virtual base
+		addne	\rx, \rx, #0x00ff0000
+		addne	\rx, \rx, #0x0000b000
+#ifdef	__ARMEB__
+		orr	\rx, \rx, #0x00000003
+#endif
+		.endm 
+		
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldrb	\rd, [\rx, #0x14]
+		tst	\rd, #0x60       
+		beq	1002b
+		.endm
+
+		.macro	waituart,rd,rx
+		nop
+		nop
+		nop
+		.endm
+
+
+#elif defined(CONFIG_ARCH_IXP425)
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0xc8000000	@ Physical
+		movne	\rx, #0xff000000	@ Virtual
+		orrne	\rx, \rx, #0x00fd0000	
+		orrne	\rx, \rx, #0x00002000
+#ifdef __ARMEB__
+		add	\rx,\rx,#3            
+#endif
+		.endm
+
+		.macro  senduart,rd,rx
+		strb    \rd, [\rx]
+		.endm
+
+		.macro  busyuart,rd,rx
+1002:		ldrb    \rd, [\rx, #0x14]
+		and     \rd, \rd, #0x60	@ check THRE and TEMT bits
+		teq     \rd, #0x60
+		beq     1002b
+		.endm 
+		
+		.macro  waituart,rd,rx
+		nop
+		nop
+		nop
+		.endm
+
 #elif defined(CONFIG_ARCH_MX1ADS)
 
 		.macro	addruart,rx
@@ -469,7 +643,6 @@
 		.endm
 
 
-
 #else
 #error Unknown architecture
 #endif
diff -urN linux-2.4.29/arch/arm/kernel/dma.c linux-2.4.29-uc1/arch/arm/kernel/dma.c
--- linux-2.4.29/arch/arm/kernel/dma.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/dma.c	2005-06-14 02:11:00.000000000 +0100
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 
+#include <asm/hardware.h>
 #include <asm/dma.h>
 
 #include <asm/mach/dma.h>
diff -urN linux-2.4.29/arch/arm/kernel/entry-armv.S linux-2.4.29-uc1/arch/arm/kernel/entry-armv.S
--- linux-2.4.29/arch/arm/kernel/entry-armv.S	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/entry-armv.S	2005-06-14 02:11:00.000000000 +0100
@@ -14,6 +14,7 @@
  *  it to save wrong values...  Be aware!
  */
 #include <linux/config.h>
+#include <asm/kgdb.h>
 #include "entry-header.S"
 
 
@@ -453,6 +454,61 @@
 		.macro	irq_prio_table
 		.endm
 
+#elif defined(CONFIG_ARCH_EP93XX)
+  
+		.macro  disable_fiq
+		.endm
+  
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\irqstat, =VIC0IRQSTATUS
+		ldr	\irqstat, [\irqstat, #0]
+  
+		mov	\irqnr, #0
+  
+1001:		tst	\irqstat, #1
+		bne	1003f
+		add	\irqnr, \irqnr, #1
+		mov	\irqstat, \irqstat, lsr #1
+		cmp	\irqnr, #32
+		bcc	1001b
+
+		ldr	\irqstat, =VIC1IRQSTATUS
+		ldr	\irqstat, [\irqstat, #0]
+
+1002:		tst	\irqstat, #1
+		bne	1003f
+		add	\irqnr, \irqnr, #1
+		mov	\irqstat, \irqstat, lsr #1
+		cmp	\irqnr, #64
+		bcc	1002b
+1003:
+		.endm
+  
+		.macro  irq_prio_table
+		.endm
+  
+#elif defined(CONFIG_ARCH_KS8695)
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\irqnr, =IO_ADDRESS(KS8695_IO_BASE)+KS8695_INT_MASK_STATUS
+		ldr	\irqstat, [\irqnr]		@ get masked status
+
+		mov	\irqnr, #0
+1001:		tst	\irqstat, #1
+		bne	1002f
+		add	\irqnr, \irqnr, #1
+		mov	\irqstat, \irqstat, lsr #1
+		cmp	\irqnr, #32
+		bcc	1001b
+1002:		/* EQ will be set if we reach 32 */
+		.endm
+
+		.macro	irq_prio_table
+		.endm
+
 #elif defined(CONFIG_ARCH_AT91RM9200)
 #include <asm/hardware.h>
 
@@ -615,6 +671,379 @@
 		.text
 		.endm
 
+#elif defined(CONFIG_ARCH_IXP1200) 
+
+#include <asm/hardware.h>	
+
+		.macro	disable_fiq    
+		.endm
+
+		.equ	irq_mask_pci_err_high, IRQ_MASK_PCI_ERR & 0xff000000
+		.equ	irq_mask_pci_err_low,  IRQ_MASK_PCI_ERR & 0x00ffffff
+		.equ	arm_csr_base_3, ARM_CSR_BASE & 0xff000000
+		.equ	arm_csr_base_2, ARM_CSR_BASE & 0x00ff0000
+		.equ	arm_csr_base_1, ARM_CSR_BASE & 0x0000ff00
+		.equ    pci_csr_base_3, PCI_CSR_BASE & 0xff000000
+		.equ    pci_csr_base_2, PCI_CSR_BASE & 0x00ff0000
+		.equ	pci_csr_base_1,	PCI_CSR_BASE & 0x0000ff00
+	
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+		mov	r4, #arm_csr_base_3
+		orr	r4, r4, #arm_csr_base_2
+		orr	r4, r4, #arm_csr_base_1
+		add     r4, r4, #CSR_ARM_IRQ
+		ldr	\irqstat, [r4]		@ get interrupts
+		tst	\irqstat, #IXP1200_IRQS @ check for interrupts 
+		beq     1001f
+
+		tst	\irqstat, #IRQ_MASK_UENG
+		movne	\irqnr, #IXP1200_IRQ_UENG
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_CINT
+		movne	\irqnr, #IXP1200_IRQ_CINT
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_SRAM
+		movne	\irqnr, #IXP1200_IRQ_SRAM
+		bne	1001f
+	
+		tst	\irqstat, #IRQ_MASK_SDRAM
+		movne	\irqnr, #IXP1200_IRQ_SDRAM
+		bne	1001f
+	
+		tst	\irqstat, #IRQ_MASK_UART
+		movne	\irqnr, #IXP1200_IRQ_UART
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_RTC
+		movne	\irqnr, #IXP1200_IRQ_RTC
+		bne	1001f
+
+		@ Check for an ints from PCI register
+
+		tst	\irqstat, #IRQ_MASK_PCI_INTS
+		beq	1001f
+
+		mov     r4, #pci_csr_base_3
+		orr     r4, r4, #pci_csr_base_2
+		orr	r4, r4, #pci_csr_base_1
+		add     r4, r4, #CSR_IRQ_STATUS
+		ldr	\irqstat, [r4]		@ get pci interrupts
+	
+		tst	\irqstat, #IRQ_MASK_DMA1
+		movne	\irqnr, #IXP1200_IRQ_DMA1
+		bne	1001f
+			
+		tst	\irqstat, #IRQ_MASK_DMA2
+		movne	\irqnr, #IXP1200_IRQ_DMA2
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_DMA1NB
+		movne	\irqnr, #IXP1200_IRQ_DMA1NB
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_DMA2NB
+		movne	\irqnr, #IXP1200_IRQ_DMA2NB
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_PCI
+		movne	\irqnr, #IXP1200_IRQ_PCI
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_I2O
+		movne	\irqnr, #IXP1200_IRQ_I2O
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_DOORBELL
+		movne	\irqnr, #IXP1200_IRQ_DOORBELL
+
+		tst	\irqstat, #IRQ_MASK_TIMER1
+		movne	\irqnr, #IXP1200_IRQ_TIMER1
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_TIMER2
+		movne	\irqnr, #IXP1200_IRQ_TIMER2
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_TIMER3
+		movne	\irqnr, #IXP1200_IRQ_TIMER3
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_TIMER4
+		movne	\irqnr, #IXP1200_IRQ_TIMER4
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_SWI
+		movne	\irqnr, #IXP1200_IRQ_SWI
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_BIST
+		movne	\irqnr, #IXP1200_IRQ_BIST
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_PWRM
+		movne	\irqnr, #IXP1200_IRQ_PWRM
+		bne	1001f
+		
+		tst	\irqstat, #irq_mask_pci_err_high
+		tsteq	\irqstat, #irq_mask_pci_err_low
+		movne	\irqnr, #IXP1200_IRQ_PCI_ERR
+		bne	1001f
+
+1001:
+		.endm
+
+		.macro	irq_prio_table
+		.endm
+
+#elif defined(CONFIG_ARCH_IOP310) || defined(CONFIG_ARCH_ADIFCC)
+
+		.macro	disable_fiq
+		.endm
+
+        	.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+        	mrc p13, 0, \irqstat, c4, c0, 0 @ get INTSRC
+        	mrc p13, 0, \base, c0, c0, 0    @ get INTCTL
+
+        	tst \irqstat, #(1<<29)      	@ if INTSRC_BI
+        	tstne   \base, #(1<<3)          @ and INTCTL_BM
+        	movne   \irqnr, #IRQ_XS80200_BCU
+        	bne 1001f
+	
+        	tst \irqstat, #(1<<28)      	@ if INTSRC_PI
+   	    	tstne   \base, #(1<<2)          @ and INTCTL_PM
+        	movne   \irqnr, #IRQ_XS80200_PMU
+        	bne 1001f
+	
+        	tst \irqstat, #(1<<31)      	@ if INTSRC_FI
+        	tstne   \base, #(1<<0)          @ and INTCTL_FM
+        	movne   \irqnr, #IRQ_XS80200_EXTFIQ
+        	bne 1001f
+	
+        	tst \irqstat, #(1<<30)      	@ if INTSRC_II
+        	tstne   \base, #(1<<1)          @ and INTCTL_IM
+        	movne   \irqnr, #IRQ_XS80200_EXTIRQ
+1001:
+  		.endm
+  
+  		.macro	irq_prio_table
+ 		.endm
+
+#elif defined(CONFIG_ARCH_IOP321)
+		.macro  disable_fiq
+		.endm
+
+		/*
+		 * Note: only deal with normal interrupts, not FIQ
+		 */
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov     \irqnr, #0
+		mrc     p6, 0, \irqstat, c8, c0, 0      @ Read IINTSRC
+		cmp     \irqstat, #0
+		beq     1001f
+		clz     \irqnr, \irqstat 
+		mov     \base, #31
+		subs    \irqnr,\base,\irqnr
+		add     \irqnr,\irqnr,#IRQ_IOP321_DMA0_EOT
+1001:
+		.endm 
+
+		.macro  irq_prio_table
+		.endm
+
+#elif defined(CONFIG_ARCH_IXP2000)
+
+		.macro  disable_fiq
+		.endm
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		
+		mov	\irqnr, #0x0              @clear out irqnr as default
+                mov	\base, #0xfa000000        
+		orr	\base, \base, #0x00ff0000
+		orr	\base, \base, #0x0000d000
+		orr	\base, \base, #0x08
+		ldr	\irqstat, [\base]         @ get interrupts 
+		
+		mov	\tmp, #(1<<4)     @#IRQ_MASK_TIMER1
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_TIMER1
+		bne	1001f 
+		
+		mov	\tmp, #(1<<0)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_SWI
+		bne	1001f
+
+		mov	\tmp, #(1<<1)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_ERRSUM
+		bne	1001f
+
+		mov	\tmp, #(1<<2)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_UART
+		bne	1001f 
+		
+		mov	\tmp, #(1<<3)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_GPIO
+		bne	1001f
+
+                mov	\tmp, #(1<<5)
+		tst	\irqstat, \tmp
+                movne	\irqnr, #IRQ_IXP2000_TIMER2
+		bne	1001f 
+		
+		mov	\tmp, #(1<<6)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_TIMER3
+		bne	1001f 
+		
+		mov	\tmp, #(1<<7)
+		tst	\irqstat, \tmp
+                movne	\irqnr, #IRQ_IXP2000_TIMER4
+		bne	1001f 
+		
+		mov	\tmp, #(1<<8)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_PMU
+		bne	1001f 
+		
+		mov	\tmp, #(1<<9)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_SPF
+		bne	1001f 
+		
+		mov	\tmp, #(1<<10)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_DMA1
+		bne	1001f 
+		
+		mov	\tmp, #(1<<11)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_DMA2
+		bne	1001f 
+		
+		mov	\tmp, #(1<<12)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_DMA3
+		bne	1001f 
+		
+		mov	\tmp, #(1<<13)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_PCI_DOORBELL
+		bne	1001f 
+		
+		mov	\tmp, #(1<<14)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_ME_ATTN
+		bne	1001f 
+		
+		mov	\tmp, #(1<<15)
+		tst	\irqstat, \tmp
+		beq	999f
+
+		mov	\base, #0xfa000000
+		orr	\base, \base, #0x00ff0000
+		orr	\base, \base, #0x0000f100
+		orr	\base, \base, #0x00000058
+		ldr	\irqstat, [\base]
+
+		mov	\tmp, #(1<<26)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_PCIA
+		bne	1001f
+
+		mov	\tmp, #(1<<27)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_PCIB
+		moveq	\irqnr, #IRQ_IXP2000_PCI
+		b	1001f
+
+999:		mov	\tmp, #(1<<16)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_THDA0
+		bne	1001f 
+		
+		mov	\tmp, #(1<<17)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_THDA1
+		bne	1001f 
+		
+		mov	\tmp, #(1<<18)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_THDA2
+		bne	1001f
+		
+		mov	\tmp, #(1<<19)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_THDA3
+		bne	 1001f
+		
+		mov	\tmp, #(1<<24)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_THDB0
+		bne	1001f 
+		
+		mov	\tmp, #(1<<25)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_THDB1
+		bne	1001f
+		
+		mov	\tmp, #(1<<26)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_THDB2
+		bne	1001f 
+		
+		mov	\tmp, #(1<<27)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_THDB3
+		bne	1001f
+
+1001:
+		.endm 
+		
+		.macro  irq_prio_table
+		.endm
+
+#elif defined (CONFIG_ARCH_IXP425)
+
+		.macro	disable_fiq
+		.endm
+		
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\irqstat, =(IXP425_INTC_BASE_VIRT+IXP425_ICIP_OFFSET)
+		ldr	\irqstat, [\irqstat]		@ get interrupts
+		mov	\irqnr, #0
+1001:		tst	\irqstat, #1
+		addeq	\irqnr, \irqnr, #1
+		moveq	\irqstat, \irqstat, lsr #1
+		tsteq	\irqnr, #32
+		beq	1001b
+		teq	\irqnr, #32
+
+#ifdef CONFIG_MACH_IXDP465
+		bne 1003f
+		ldr	\irqstat, =(IXP425_INTC_BASE_VIRT+IXP425_ICIP2_OFFSET)
+		ldr	\irqstat, [\irqstat]		@ get interrupts
+1002:		tst	\irqstat, #1
+		addeq	\irqnr, \irqnr, #1
+		moveq	\irqstat, \irqstat, lsr #1
+		tsteq	\irqnr, #64
+		beq	1002b
+		teq	\irqnr, #64
+1003:
+#endif
+
+		.endm
+
+                .macro  irq_prio_table
+                .endm
+
 #else
 #error Unknown architecture
 #endif
@@ -729,9 +1158,47 @@
 		add	r4, sp, #S_SP
 		stmia	r4, {r5 - r9}			@ save sp_SVC, lr_SVC, pc, cpsr, old_ro
 
+
+#ifdef	CONFIG_KGDB
+		/*
+		 * This is somewhat of a hack, but it is the only way
+		 * that seems doable.  __und_svc assumes that by the
+		 * time it is called, the FPE has been initalized.
+		 * Since we may want to breakpoint very early on
+		 * (just following trap_init), that's not the case.
+		 * If we bl to call_fpe before the FPE is initialized,
+		 * bad things happen.
+		 *
+		 * So we check  for the KGDB traps and if we encounter
+		 * them, just jump over the FPE call.
+		 */
+		adr	r10, kgdb_brk_instr
+		ldr	r10, [r10]
+		ldr	r9, [sp, #S_PC]		@ Load PC
+		sub	r9, r9, #4
+		mask_pc	r9, r9
+		ldr	r9, [r9]		@ get instruction
+		teq	r10, r9			@ Is it GDB breakpoint?
+		beq	2f
+		adr	r10, kgdb_trap_instr	@ Compiled in breakpoint?
+		ldr	r10, [r10]
+		teq	r10, r9
+		beq	2f
+#endif
+
+#ifdef CONFIG_EP93XX_CRUNCH
+		mov	r0, sp
+		bl	crunch_opcode
+		cmp	r0, #1
+		beq	1f
+#endif
+
 		adrsvc	al, r9, 1f			@ r9  = normal FP return
 		bl	call_fpe			@ lr  = undefined instr return
 
+#ifdef	CONFIG_KGDB
+2:
+#endif
 		mov	r0, r5				@ unsigned long pc
 		mov	r1, sp				@ struct pt_regs *regs
 		bl	SYMBOL_NAME(do_undefinstr)
@@ -742,6 +1209,12 @@
 		msr	spsr, lr
 		ldmia	sp, {r0 - pc}^			@ Restore SVC registers
 
+#ifdef	CONFIG_KGDB
+kgdb_brk_instr:		.word	KGDB_BREAKINST
+kgdb_trap_instr:	.word	KGDB_COMPILED_BREAK
+#endif
+
+
 		.align	5
 __pabt_svc:	sub	sp, sp, #S_FRAME_SIZE
 		stmia	sp, {r0 - r12}			@ save r0 - r12
@@ -833,6 +1306,12 @@
 		ldmia	r4, {r5 - r7}
 		stmia	r8, {r5 - r7}			@ Save USR pc, cpsr, old_r0
 		stmdb	r8, {sp, lr}^			@ Save user sp, lr
+#ifdef CONFIG_EP93XX_CRUNCH
+		mov	r0, sp
+		bl	crunch_opcode
+		cmp	r0, #1
+		beq	ret_from_exception
+#endif
 		alignment_trap r4, r7, __temp_und
 		zero_fp
 		tst	r6, #T_BIT			@ Thumb mode
@@ -885,6 +1364,7 @@
 		.text
 /*
  * Register switch for ARMv3 and ARMv4 processors
+ * Save DSP (CP0) state on XScale CPUs
  * r0 = previous, r1 = next, return previous.
  * previous and next are guaranteed not to be the same.
  */
@@ -892,11 +1372,30 @@
 		stmfd	sp!, {r4 - sl, fp, lr}		@ Store most regs on stack
 		mrs	ip, cpsr
 		str	ip, [sp, #-4]!			@ Save cpsr_SVC
+#ifdef CONFIG_CPU_XSCALE
+		mra	r4, r5, acc0
+		stmfd	sp!, {r4, r5}
+#endif
 		str	sp, [r0, #TSS_SAVE]		@ Save sp_SVC
 		ldr	sp, [r1, #TSS_SAVE]		@ Get saved sp_SVC
+#ifdef CONFIG_ARM_FASS
+		ldr	r3, [r1, #TSK_MM]		@ Get tasks mm_struct*
+		ldr	r2, [r1, #TSS_DACR]		@ Get task DACR
+		teq	r3, #0				@ Have mm_struct?
+		ldrne	r1, [r3, #MM_CONTEXT_PID]	@ Get mm contexts PID
+		ldrne	r3, [r3, #MM_CONTEXT_DACR]	@ Get mm contexts DACR
+		moveq	r1, #0				@ Set PID to zero
+		orr	r2, r2, r3			@ Build CPU DACR
+		mcr	p15, 0, r1, c13, c0		@ Set CPU PID
+#else
 		ldr	r2, [r1, #TSS_DOMAIN]
+#endif
+#ifdef CONFIG_CPU_XSCALE
+		ldmfd	sp!, {r4, r5}
+		mar	acc0, r4, r5
+#endif
 		ldr	ip, [sp], #4
-		mcr	p15, 0, r2, c3, c0		@ Set domain register
+		mcr	p15, 0, r2, c3, c0		@ Set domain/CPU DACR
 		msr	spsr, ip			@ Save tasks CPSR into SPSR for this return
 		ldmfd	sp!, {r4 - sl, fp, pc}^		@ Load all regs saved previously
 
@@ -1145,6 +1644,9 @@
 		str	r3, [r2], #4
 		cmp	r0, r1
 		blt	1b
+#ifdef CONFIG_XSCALE_BDI2000
+		bkpt	#1
+#endif
 		LOADREGS(fd, sp!, {r4 - r6, pc})
 
 		.data
diff -urN linux-2.4.29/arch/arm/kernel/entry-common.S linux-2.4.29-uc1/arch/arm/kernel/entry-common.S
--- linux-2.4.29/arch/arm/kernel/entry-common.S	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/entry-common.S	2005-06-14 02:11:00.000000000 +0100
@@ -128,6 +128,7 @@
 
 	.align	5
 ENTRY(vector_swi)
+
 	save_user_regs
 	zero_fp
 	get_scno
diff -urN linux-2.4.29/arch/arm/kernel/fiq.c linux-2.4.29-uc1/arch/arm/kernel/fiq.c
--- linux-2.4.29/arch/arm/kernel/fiq.c	2003-06-13 15:51:29.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/fiq.c	2005-06-14 02:11:00.000000000 +0100
@@ -122,23 +122,23 @@
 	register unsigned long tmp, tmp2;
 	__asm__ volatile (
 #ifdef CONFIG_CPU_26
-	"mov	%0, pc
-	bic	%1, %0, #0x3
-	orr	%1, %1, %3
-	teqp	%1, #0		@ select FIQ mode
-	mov	r0, r0
-	ldmia	%2, {r8 - r14}
-	teqp	%0, #0		@ return to SVC mode
-	mov	r0, r0"
+	"mov	%0, pc		\n\t"
+	"bic	%1, %0, #0x3	\n\t"
+	"orr	%1, %1, %3	\n\t"
+	"teqp	%1, #0		@ select FIQ mode	\n\t"
+	"mov	r0, r0		\n\t"
+	"ldmia	%2, {r8 - r14}	\n\t"
+	"teqp	%0, #0		@ return to SVC mode	\n\t"
+	"mov	r0, r0"
 #endif
 #ifdef CONFIG_CPU_32
-	"mrs	%0, cpsr
-	mov	%1, %3
-	msr	cpsr_c, %1	@ select FIQ mode
-	mov	r0, r0
-	ldmia	%2, {r8 - r14}
-	msr	cpsr_c, %0	@ return to SVC mode
-	mov	r0, r0"
+	"mrs	%0, cpsr	\n\t"
+	"mov	%1, %3		\n\t"
+	"msr	cpsr_c, %1	@ select FIQ mode	\n\t"
+	"mov	r0, r0		\n\t"
+	"ldmia	%2, {r8 - r14}	\n\t"
+	"msr	cpsr_c, %0	@ return to SVC mode	\n\t"
+	"mov	r0, r0"
 #endif
 	: "=&r" (tmp), "=&r" (tmp2)
 	: "r" (&regs->ARM_r8), "I" (I_BIT | F_BIT | FIQ_MODE)
@@ -154,23 +154,23 @@
 	register unsigned long tmp, tmp2;
 	__asm__ volatile (
 #ifdef CONFIG_CPU_26
-	"mov	%0, pc
-	bic	%1, %0, #0x3
-	orr	%1, %1, %3
-	teqp	%1, #0		@ select FIQ mode
-	mov	r0, r0
-	stmia	%2, {r8 - r14}
-	teqp	%0, #0		@ return to SVC mode
-	mov	r0, r0"
+	"mov	%0, pc	\n\t"
+	"bic	%1, %0, #0x3	\n\t"
+	"orr	%1, %1, %3	\n\t"
+	"teqp	%1, #0		@ select FIQ mode	\n\t"
+	"mov	r0, r0		\n\t"
+	"stmia	%2, {r8 - r14}	\n\t"
+	"teqp	%0, #0		@ return to SVC mode	\n\t"
+	"mov	r0, r0"
 #endif
 #ifdef CONFIG_CPU_32
-	"mrs	%0, cpsr
-	mov	%1, %3
-	msr	cpsr_c, %1	@ select FIQ mode
-	mov	r0, r0
-	stmia	%2, {r8 - r14}
-	msr	cpsr_c, %0	@ return to SVC mode
-	mov	r0, r0"
+	"mrs	%0, cpsr	\n\t"
+	"mov	%1, %3		\n\t"
+	"msr	cpsr_c, %1	@ select FIQ mode	\n\t"
+	"mov	r0, r0		\n\t"
+	"stmia	%2, {r8 - r14}	\n\t"
+	"msr	cpsr_c, %0	@ return to SVC mode	\n\t"
+	"mov	r0, r0"
 #endif
 	: "=&r" (tmp), "=&r" (tmp2)
 	: "r" (&regs->ARM_r8), "I" (I_BIT | F_BIT | FIQ_MODE)
diff -urN linux-2.4.29/arch/arm/kernel/head-armv.S linux-2.4.29-uc1/arch/arm/kernel/head-armv.S
--- linux-2.4.29/arch/arm/kernel/head-armv.S	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/head-armv.S	2005-06-14 02:11:00.000000000 +0100
@@ -129,6 +129,8 @@
  * FIXME - No bootloader, so manually set 'r1' with our architecture number.
  */
 		mov	r1, #MACH_TYPE_L7200
+#elif defined(CONFIG_ARCH_IXP1200)
+		mov	r1, #MACH_TYPE_IXP1200
 #endif
 
 		mov	r0, #F_BIT | I_BIT | MODE_SVC	@ make sure svc mode
@@ -254,6 +256,7 @@
 		add	r3, r3, #1 << 20
 		str	r3, [r0], #4			@ KERNEL + 3MB
 
+#ifndef CONFIG_ARCH_IXP1200
 		/*
 		 * Ensure that the first section of RAM is present.
 		 * we assume that:
@@ -265,7 +268,7 @@
 		and	r2, r5, #0xfe000000		@ round down
 		add	r3, r8, r2			@ flags + rambase
 		str	r3, [r0]
-
+#endif
 		bic	r8, r8, #0x0c			@ turn off cacheable
 							@ and bufferable bits
 #ifdef CONFIG_DEBUG_LL
diff -urN linux-2.4.29/arch/arm/kernel/irq.c linux-2.4.29-uc1/arch/arm/kernel/irq.c
--- linux-2.4.29/arch/arm/kernel/irq.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/irq.c	2005-06-14 02:11:00.000000000 +0100
@@ -549,7 +549,7 @@
 		kfree(action);
 		goto out;
 	}
-	printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
+	printk(KERN_ERR "Trying to free IRQ%d\n",irq);
 #ifdef CONFIG_DEBUG_ERRORS
 	__backtrace();
 #endif
diff -urN linux-2.4.29/arch/arm/kernel/isa.c linux-2.4.29-uc1/arch/arm/kernel/isa.c
--- linux-2.4.29/arch/arm/kernel/isa.c	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-uc1/arch/arm/kernel/isa.c	2005-06-14 02:11:00.000000000 +0100
@@ -38,7 +38,7 @@
 
 static struct ctl_table_header *isa_sysctl_header;
 
-static ctl_table ctl_isa[2] = {{CTL_BUS_ISA, "isa", NULL, 0, 0555, ctl_isa_vars},
+static ctl_table ctl_isa[2] = {{BUS_ISA, "isa", NULL, 0, 0555, ctl_isa_vars},
 			       {0}};
 static ctl_table ctl_bus[2] = {{CTL_BUS, "bus", NULL, 0, 0555, ctl_isa},
 			       {0}};
diff -urN linux-2.4.29/arch/arm/kernel/kgdb-jmp.S linux-2.4.29-uc1/arch/arm/kernel/kgdb-jmp.S
--- linux-2.4.29/arch/arm/kernel/kgdb-jmp.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/kgdb-jmp.S	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,49 @@
+/*
+ * FILE NAME: arch/arm/kernel/kgdb-jmp.S
+ *
+ * MODULE DESCRIPTION:
+ * Trivial setjmp and longjmp procedures to support bus error recovery
+ * which may occur during kgdb memory read/write operations.
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/linkage.h>
+
+ENTRY (kgdb_setjmp)
+	/* Save registers */
+	stmia	r0, {r0-r14}
+	str	lr,[r0, #60]
+	mrs	r1,cpsr
+	str	r1,[r0,#64]
+	ldr	r1,[r0,#4]
+	mov	r0, #0
+	mov	pc,lr
+
+ENTRY (kgdb_longjmp)
+	/* Restore registers */
+	str	r1,[r0]
+	ldmia	r0,{r0-pc}^
diff -urN linux-2.4.29/arch/arm/kernel/kgdb-serial.c linux-2.4.29-uc1/arch/arm/kernel/kgdb-serial.c
--- linux-2.4.29/arch/arm/kernel/kgdb-serial.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/kgdb-serial.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,278 @@
+/*
+ * arch/arm/kernel/kgdb-serial.c
+ *
+ * Generic serial access routines for use by kgdb.
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ * Based on original KGDB code developed by various people:
+ *
+ * This is a simple middle layer that allows KGDB to run on
+ * top of any serial device.  This layer expects the board
+ * port to provide the following functions:
+ *
+ * 	void kgdb_serial_init(void)
+ * 		initialize serial interface if needed
+ * 	void kgdb_serial_putchar(unsigned char)
+ * 		send a character over the serial connection
+ * 	kgdb_serial_getchar()
+ * 		get a character from the serial connection
+ *
+ * Note that this is not meant for debugging over sercons, but for
+ * when you have a _dedicated_ serial port for kgdb.  To send debug
+ * and console messages over the same port (ICK), you need to
+ * turn on CONFIG_KGDB_CONSOLE, which uses kgb-console.c instead and
+ * hooks into the console system.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/personality.h>
+#include <linux/ptrace.h>
+#include <linux/elf.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/atomic.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+
+#include <asm/kgdb.h>
+
+#ifdef CONFIG_KGDB_CONSOLE
+#include <linux/console.h>
+#endif
+
+static int kgdb_io_initialized = 0;
+
+static const char hexchars[]="0123456789abcdef";
+
+static int
+hex(unsigned char ch)
+{
+  if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10);
+  if ((ch >= '0') && (ch <= '9')) return (ch-'0');
+  if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10);
+  return (-1);
+}
+
+/*
+ *
+ * Scan the serial stream for the sequence $<data>#<checksum>
+ *
+ */
+void
+kgdb_get_packet(unsigned char *buffer, int buflen)
+{
+	unsigned char checksum;
+	unsigned char xmitcsum;
+	int i;
+	int count;
+	char ch;
+
+	do {
+		/* Ignore everything until the start character */
+		while ((ch = kgdb_serial_getchar()) != '$') ;
+
+		checksum = 0;
+		xmitcsum = -1;
+		count = 0;
+
+		/* Now, read until a # or end of buffer is found */
+		while (count < (buflen - 1)) {
+			ch = kgdb_serial_getchar();
+
+			if (ch == '#')
+				break;
+
+			checksum = checksum + ch;
+			buffer[count] = ch;
+			count = count + 1;
+		}
+
+		buffer[count] = 0;
+
+		/* Continue to read checksum following # */
+		if (ch == '#') {
+			xmitcsum = hex(kgdb_serial_getchar()) << 4;
+			xmitcsum += hex(kgdb_serial_getchar());
+
+			/* Checksum */
+			if (checksum != xmitcsum)
+				kgdb_serial_putchar('-'); /* Failed checksum */
+			else {
+				/* Ack successful transfer */
+				kgdb_serial_putchar('+');
+
+				/* If a sequence char is present, reply
+				   the sequence ID */
+				if (buffer[2] == ':') {
+					kgdb_serial_putchar(buffer[0]);
+					kgdb_serial_putchar(buffer[1]);
+
+					/* Remove sequence chars from buffer */
+					count = strlen(buffer);
+					for (i = 3; i <= count; i++)
+						buffer[i - 3] = buffer[i];
+				}
+			}
+		}
+	} while (checksum != xmitcsum);	/* Keep trying while we fail */
+}
+
+
+/*
+ *
+ * Send packet in the buffer with run-length encoding as follows:
+ *
+ * $<packet info>#<checksum>.
+ *
+ */
+void
+kgdb_put_packet(const unsigned char *buffer)
+{
+	unsigned char checksum;
+	const unsigned char *src;
+	int runlen;
+	int encode;
+
+	do {
+		src = buffer;
+		kgdb_serial_putchar('$');
+		checksum = 0;
+
+		/* Continue while we still have chars left */
+		while (*src) {
+			/* Check for runs up to 99 chars long */
+			for (runlen = 1; runlen < 99; runlen++) {
+				if (src[0] != src[runlen])
+					break;
+			}
+
+			if (runlen > 3) {
+				/* Got a useful amount, send encoding */
+				encode = runlen + ' ' - 4;
+				kgdb_serial_putchar(*src);
+				checksum += *src;
+				kgdb_serial_putchar('*');
+				checksum += '*';
+				kgdb_serial_putchar(encode);
+				checksum += encode;
+				src += runlen;
+			} else {
+				/* Otherwise just send the current char */
+				kgdb_serial_putchar(*src);
+				checksum += *src;
+				src += 1;
+			}
+		}
+
+		/* '#' Separator, put high and low components of checksum */
+		kgdb_serial_putchar('#');
+		kgdb_serial_putchar(hexchars[(checksum >> 4) & 0xf]);
+		kgdb_serial_putchar(hexchars[checksum & 0xf]);
+	} while ((kgdb_serial_getchar()) != '+'); /* While no ack */
+}
+
+int
+kgdb_io_init(void)
+{
+	if (kgdb_io_initialized)
+		return 0;
+
+	kgdb_serial_init();
+
+	kgdb_io_initialized = 1;
+
+	return 0;
+}
+
+
+/*
+ * If only one serial port is available on the board or if you want
+ * to send console messages over KGDB, this is a nice and easy way
+ * to accomplish this. Just add "console=ttyKGDB" to the command line
+ * and all console output will be piped to the GDB client.
+ */
+#ifdef CONFIG_KGDB_CONSOLE
+
+static char kgdb_console_buf[4096];
+
+static void
+kgdb_console_write(struct console *co, const char *s, unsigned count)
+{
+	int i = 0;
+	static int j = 0;
+
+	if(!kgdb_active())
+		return;
+
+	kgdb_console_buf[0] = 'O';
+	j = 1;
+
+	for(i = 0; i < count; i++, s++)
+	{
+		kgdb_console_buf[j++] = hexchars[*s >> 4];
+		kgdb_console_buf[j++] = hexchars[*s & 0xf];
+
+		if(*s == '\n')
+		{
+			kgdb_console_buf[j] = 0;
+			kgdb_put_packet(kgdb_console_buf);
+
+			kgdb_console_buf[0]='O';
+			j = 1;
+		}
+	}
+
+	if(j != 1)
+	{
+		kgdb_console_buf[j] = 0;
+		kgdb_put_packet(kgdb_console_buf);
+	}
+}
+
+static kdev_t
+kgdb_console_device(struct console *c)
+{
+	return 0;
+}
+
+static int
+kgdb_console_setup(struct console *co, char *options)
+{
+	kgdb_io_init();
+
+	return 0;
+}
+
+static struct console kgdb_console = {
+	name:		"ttyKGDB",
+	write:		kgdb_console_write,
+	device:		kgdb_console_device,
+	setup:		kgdb_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1
+};
+
+void __init
+kgdb_console_init(void)
+{
+	register_console(&kgdb_console);
+}
+
+#endif // CONFIG_KGDB_CONSOLE
diff -urN linux-2.4.29/arch/arm/kernel/kgdb-stub.c linux-2.4.29-uc1/arch/arm/kernel/kgdb-stub.c
--- linux-2.4.29/arch/arm/kernel/kgdb-stub.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/kgdb-stub.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,1483 @@
+/****************************************************************************
+ *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ *  Module name: remcom.c $
+ *  Revision: 1.34 $
+ *  Date: 91/03/09 12:29:49 $
+ *  Contributor:     Lake Stevens Instrument Division$
+ *
+ *  Description:     low level support for gdb debugger. $
+ *
+ *  Considerations:  only works on target hardware $
+ *
+ *  Written by:      Glenn Engel $
+ *  ModuleState:     Experimental $
+ *
+ *  NOTES:           See Below $
+ *
+ *  Modified for 386 by Jim Kingdon, Cygnus Support.
+ *
+ *  To enable debugger support, two things need to happen.  One, a
+ *  call to set_debug_traps() is necessary in order to allow any breakpoints
+ *  or error conditions to be properly intercepted and reported to gdb.
+ *  Two, a breakpoint needs to be generated to begin communication.  This
+ *  is most easily accomplished by a call to breakpoint().  Breakpoint()
+ *  simulates a breakpoint by executing a trap #1.
+ *
+ *  The external function exceptionHandler() is
+ *  used to attach a specific handler to a specific 386 vector number.
+ *  It should use the same privilege level it runs at.  It should
+ *  install it as an interrupt gate so that interrupts are masked
+ *  while the handler runs.
+ *
+ *  Because gdb will sometimes write to the stack area to execute function
+ *  calls, this program cannot rely on using the supervisor stack so it
+ *  uses it's own stack area reserved in the int array remcomStack.
+ *
+ *************
+ *
+ *    The following gdb commands are supported:
+ *
+ * command          function                               Return value
+ *
+ *    g             return the value of the CPU registers  hex data or ENN
+ *    G             set the value of the CPU registers     OK or ENN
+ *
+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
+ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
+ *    XAA..AA,LLLL: Same, but data is binary (not hex)     OK or ENN
+ *
+ *    c             Resume at current address              SNN   ( signal NN)
+ *    cAA..AA       Continue at address AA..AA             SNN
+ *    CNN;          Resume at current address with signal  SNN
+ *    CNN;AA..AA    Resume at address AA..AA with signal   SNN
+ *
+ *    s             Step one instruction                   SNN
+ *    sAA..AA       Step one instruction from AA..AA       SNN
+ *    SNN;          Step one instruction with signal       SNN
+ *    SNNAA..AA     Step one instruction from AA..AA w/NN  SNN
+ *
+ *    k             kill (Detach GDB)
+ *
+ *    d             Toggle debug flag
+ *    D             Detach GDB
+ *
+ *    Hct           Set thread t for operations,           OK or ENN
+ *                  c = 'c' (step, cont), c = 'g' (other
+ *                  operations)
+ *
+ *    qC            Query current thread ID                QCpid
+ *    qfThreadInfo  Get list of current threads (first)    m<id>
+ *    qsThreadInfo   "    "  "     "      "   (subsequent)
+ *    qOffsets      Get section offsets                  Text=x;Data=y;Bss=z
+ *
+ *    TXX           Find if thread XX is alive             OK or ENN
+ *    ?             What was the last sigval ?             SNN   (signal NN)
+ *    O             Output to GDB console
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum.  A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer.  '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host:                  Reply:
+ * $m0,10#2a               +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+/*
+ *
+ * Remote communication protocol.
+ *
+ *    A debug packet whose contents are <data> is encapsulated for
+ *    transmission in the form:
+ *
+ *       $ <data> # CSUM1 CSUM2
+ *
+ *       <data> must be ASCII alphanumeric and cannot include characters
+ *       '$' or '#'.  If <data> starts with two characters followed by
+ *       ':', then the existing stubs interpret this as a sequence number.
+ *
+ *       CSUM1 and CSUM2 are ascii hex representation of an 8-bit
+ *       checksum of <data>, the most significant nibble is sent first.
+ *       the hex digits 0-9,a-f are used.
+ *
+ *    Receiver responds with:
+ *
+ *       +       - if CSUM is correct and ready for next packet
+ *       -       - if CSUM is incorrect
+ *
+ * Responses can be run-length encoded to save space.  A '*' means that
+ * the next character is an ASCII encoding giving a repeat count which
+ * stands for that many repititions of the character preceding the '*'.
+ * The encoding is n+29, yielding a printable character where n >=3
+ * (which is where RLE starts to win).  Don't use an n > 126.
+ *
+ * So "0* " means the same as "0000".
+ */
+
+/*
+ * ARM port Copyright (c) 2002 MontaVista Software, Inc
+ *
+ * Authors:  George Davis <davis_g@mvista.com>
+ *          Deepak Saxena <dsaxena@mvista.com>
+ *
+ *
+ * See Documentation/ARM/kgdb for information on porting to a new board
+ *
+ * tabstop=3 to make this readable
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/personality.h>
+#include <linux/ptrace.h>
+#include <linux/elf.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/atomic.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+
+#include <asm/kgdb.h>
+
+#ifdef CONFIG_MAGIC_SYSRQ
+#include <linux/sysrq.h>
+#endif
+
+
+#ifdef	CONFIG_DEBUG_LL
+// #define printascii(x, args...)  printk(x, ## args)
+// #undef printascii
+// #define printascii(x, args...)
+extern void printascii(const char *);
+extern void printhex8(unsigned int);
+#else
+#define	printascii(s)
+#define	printhex8(i)
+#endif
+
+
+#define GDB_MAXREGS	(16 + 8 * 3 + 1 + 1)
+#define GDB_REGBYTES	(GDB_MAXREGS << 2)
+
+#define BUFMAX 2048
+
+#define PC_REGNUM	0x0f
+#define	LR_REGNUM	0x0e
+#define	SP_REGNUM	0x0d
+
+
+/* External functions */
+
+extern struct pt_regs *get_task_registers(const struct task_struct *);
+
+
+/* Forward declarations */
+
+static unsigned long get_next_pc(struct pt_regs *);
+
+
+/* Globals */
+
+int kgdb_fault_expected = 0;	/* Boolean to ignore bus errs (i.e. in GDB) */
+int kgdb_enabled = 0;
+
+
+/* Locals */
+
+static char remote_debug = 0;
+static const char hexchars[]="0123456789abcdef";
+static int fault_jmp_buf[32]; /* Jump buffer for kgdb_setjmp/longjmp */
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+static int kgdb_initialized = 0;
+static volatile unsigned int *step_addr = NULL;
+static unsigned int step_instr = 0;
+
+static struct pt_regs kgdb_regs;
+static unsigned int gdb_regs[GDB_MAXREGS];
+
+#ifdef CONFIG_KGDB_THREAD
+static struct task_struct *trapped_thread;
+static struct task_struct *current_thread;
+typedef unsigned char threadref[8];
+#define BUF_THREAD_ID_SIZE 16
+#endif
+
+
+/*
+ * Various conversion functions
+ */
+static int hex(unsigned char ch)
+{
+  if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10);
+  if ((ch >= '0') && (ch <= '9')) return (ch-'0');
+  if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10);
+  return (-1);
+}
+
+static unsigned char * mem2hex(const char *mem, char *buf, int count)
+{
+	/* Accessing 16-bit and 32-bit objects in a single
+	 * load instruction is required to avoid bad side
+	 * effects for some IO registers.
+	 */
+
+	if ((count == 2) && (((long)mem & 1) == 0)) {
+		unsigned short tmp_s =
+			cpu_to_be16(*(unsigned short *)mem);
+		mem += 2;
+		*buf++ = hexchars[(tmp_s >> 12) & 0xf];
+		*buf++ = hexchars[(tmp_s >> 8) & 0xf];
+		*buf++ = hexchars[(tmp_s >> 4) & 0xf];
+		*buf++ = hexchars[tmp_s & 0xf];
+	} else if ((count == 4) && (((long)mem & 3) == 0)) {
+		unsigned int tmp_l =
+			cpu_to_be32(*(unsigned int *)mem);
+		mem += 4;
+		*buf++ = hexchars[(tmp_l >> 28) & 0xf];
+		*buf++ = hexchars[(tmp_l >> 24) & 0xf];
+		*buf++ = hexchars[(tmp_l >> 20) & 0xf];
+		*buf++ = hexchars[(tmp_l >> 16) & 0xf];
+		*buf++ = hexchars[(tmp_l >> 12) & 0xf];
+		*buf++ = hexchars[(tmp_l >> 8) & 0xf];
+		*buf++ = hexchars[(tmp_l >> 4) & 0xf];
+		*buf++ = hexchars[tmp_l & 0xf];
+	} else {
+		unsigned char ch;
+		while (count-- > 0) {
+			ch = *mem++;
+			*buf++ = hexchars[ch >> 4];
+			*buf++ = hexchars[ch & 0xf];
+		}
+	}
+
+	*buf = 0;
+	return buf;
+}
+
+/*
+ * convert the hex array pointed to by buf into binary to be placed in mem
+ * return a pointer to the character AFTER the last byte written.
+ */
+static char * hex2mem(char *buf, char *mem, int count)
+{
+	/* Accessing 16-bit and 32-bit objects in a single
+	 * store instruction is required to avoid bad side
+	 * effects for some IO registers.
+	 */
+
+	if ((count == 2) && (((long)mem & 1) == 0)) {
+		unsigned short tmp_s =
+			hex(*buf++) << 12;
+		tmp_s |= hex(*buf++) << 8;
+		tmp_s |= hex(*buf++) << 4;
+		tmp_s |= hex(*buf++);
+		*(unsigned short *)mem = be16_to_cpu(tmp_s);
+		mem += 2;
+	} else if ((count == 4) && (((long)mem & 3) == 0)) {
+		unsigned int tmp_l =
+			hex(*buf++) << 28;
+		tmp_l |= hex(*buf++) << 24;
+		tmp_l |= hex(*buf++) << 20;
+		tmp_l |= hex(*buf++) << 16;
+		tmp_l |= hex(*buf++) << 12;
+		tmp_l |= hex(*buf++) << 8;
+		tmp_l |= hex(*buf++) << 4;
+		tmp_l |= hex(*buf++);
+		*(unsigned int *)mem = be32_to_cpu(tmp_l);
+		mem += 4;
+	} else {
+		int i;
+		unsigned char ch;
+		for (i=0; i<count; i++) {
+			ch = hex(*buf++) << 4;
+			ch |= hex(*buf++);
+			*mem++ = ch;
+		}
+	}
+
+	return mem;
+}
+
+/*  Copy the binary array pointed to by buf into mem.  Fix $, #,
+    and 0x7d escaped with 0x7d.  Return a pointer to the character
+    after the last byte written. */
+static char *ebin2mem(const char *buf, char *mem, int count)
+{
+	for (; count > 0; count--, buf++) {
+		if (*buf == 0x7d)
+			*mem++ = *(++buf) ^ 0x20;
+		else
+			*mem++ = *buf;
+	}
+	return mem;
+}
+
+/*
+ * While we find nice hex chars, build an int.
+ * Return number of chars processed.
+ */
+static int hex2int(char **ptr, int *intValue)
+{
+	int numChars = 0;
+	int hexValue;
+
+	*intValue = 0;
+
+	while (**ptr) {
+		hexValue = hex(**ptr);
+		if (hexValue < 0)
+			break;
+
+		*intValue = (*intValue << 4) | hexValue;
+		numChars ++;
+
+		(*ptr)++;
+	}
+
+	return (numChars);
+}
+
+/* Make a local copy of the registers passed into the handler (bletch) */
+static void kregs2gregs(const struct pt_regs *kregs, int *gregs)
+{
+	int regno;
+
+	/* Initialize to zero */
+	for (regno = 0; regno < GDB_MAXREGS; regno++)
+		gregs[regno] = 0;
+
+	gregs[0] = kregs->ARM_r0;
+	gregs[1] = kregs->ARM_r1;
+	gregs[2] = kregs->ARM_r2;
+	gregs[3] = kregs->ARM_r3;
+	gregs[4] = kregs->ARM_r4;
+	gregs[5] = kregs->ARM_r5;
+	gregs[6] = kregs->ARM_r6;
+	gregs[7] = kregs->ARM_r7;
+	gregs[8] = kregs->ARM_r8;
+	gregs[9] = kregs->ARM_r9;
+	gregs[10] = kregs->ARM_r10;
+	gregs[11] = kregs->ARM_fp;
+	gregs[12] = kregs->ARM_ip;
+	gregs[13] = kregs->ARM_sp;
+	gregs[14] = kregs->ARM_lr;
+	gregs[15] = kregs->ARM_pc;
+	gregs[GDB_MAXREGS - 1] = kregs->ARM_cpsr;
+}
+
+/* Copy local gdb registers back to kgdb regs, for later copy to kernel */
+static void gregs2kregs(const int *gregs, struct pt_regs *kregs)
+{
+	kregs->ARM_r0 = gregs[0];
+	kregs->ARM_r1 = gregs[1];
+	kregs->ARM_r2 = gregs[2];
+	kregs->ARM_r3 = gregs[3];
+	kregs->ARM_r4 = gregs[4];
+	kregs->ARM_r5 = gregs[5];
+	kregs->ARM_r6 = gregs[6];
+	kregs->ARM_r7 = gregs[7];
+	kregs->ARM_r8 = gregs[8];
+	kregs->ARM_r9 = gregs[9];
+	kregs->ARM_r10 = gregs[10];
+	kregs->ARM_fp = gregs[11];
+	kregs->ARM_ip = gregs[12];
+	kregs->ARM_sp = gregs[13];
+	kregs->ARM_lr = gregs[14];
+	kregs->ARM_pc = gregs[15];
+	kregs->ARM_cpsr = gregs[GDB_MAXREGS - 1];
+}
+
+#ifdef CONFIG_KGDB_THREAD
+/* Make a local copy of registers from the specified thread */
+static void tregs2gregs(const struct task_struct *task, int *gregs)
+{
+	int regno;
+	struct pt_regs *tregs;
+
+	/* Initialize to zero */
+	for (regno = 0; regno < GDB_MAXREGS; regno++)
+		gregs[regno] = 0;
+
+	/* Just making sure... */
+	if (task == NULL)
+		return;
+
+#if	0 /* REVISIT */
+	/* A new fork has pt_regs on the stack from a fork() call */
+	if (task->thread->save.pc == (unsigned long)ret_from_fork) {
+		struct pt_regs *tregs;
+		kregs = (struct pt_regs*)task->thread->save;
+
+		gregs[0] = tregs->ARM_r0;
+		gregs[1] = tregs->ARM_r1;
+		gregs[2] = tregs->ARM_r2;
+		gregs[3] = tregs->ARM_r3;
+		gregs[4] = tregs->ARM_r4;
+		gregs[5] = tregs->ARM_r5;
+		gregs[6] = tregs->ARM_r6;
+		gregs[7] = tregs->ARM_r7;
+		gregs[8] = tregs->ARM_r8;
+		gregs[9] = tregs->ARM_r9;
+		gregs[10] = tregs->ARM_r10;
+		gregs[11] = tregs->ARM_fp;
+		gregs[12] = tregs->ARM_ip;
+		gregs[13] = tregs->ARM_sp;
+		gregs[14] = tregs->ARM_lr;
+		gregs[15] = tregs->ARM_pc;
+		gregs[GDB_MAXREGS - 1] = tregs->ARM_cpsr;
+	}
+#endif
+
+	/* Otherwise, we have only some registers from switch_to() */
+	tregs = get_task_registers(task);
+	gregs[0] = tregs->ARM_r0; /* Not really valid? */
+	gregs[1] = tregs->ARM_r1; /* "               " */
+	gregs[2] = tregs->ARM_r2; /* "               " */
+	gregs[3] = tregs->ARM_r3; /* "               " */
+	gregs[4] = tregs->ARM_r4;
+	gregs[5] = tregs->ARM_r5;
+	gregs[6] = tregs->ARM_r6;
+	gregs[7] = tregs->ARM_r7;
+	gregs[8] = tregs->ARM_r8;
+	gregs[9] = tregs->ARM_r9;
+	gregs[10] = tregs->ARM_r10;
+	gregs[11] = tregs->ARM_fp;
+	gregs[12] = tregs->ARM_ip;
+	gregs[13] = tregs->ARM_sp;
+	gregs[14] = tregs->ARM_lr;
+	gregs[15] = tregs->ARM_pc;
+	gregs[GDB_MAXREGS - 1] = tregs->ARM_cpsr;
+}
+
+static char * pack_hex_byte(char *pkt, int byte)
+{
+	*pkt++ = hexchars[(byte >> 4) & 0xf];
+	*pkt++ = hexchars[(byte & 0xf)];
+	return pkt;
+}
+
+static char * pack_threadid(char *pkt, threadref * id)
+{
+	char *limit;
+	unsigned char *altid;
+
+	altid = (unsigned char *) id;
+
+	limit = pkt + BUF_THREAD_ID_SIZE;
+	while (pkt < limit)
+		pkt = pack_hex_byte(pkt, *altid++);
+	return pkt;
+}
+
+static void int_to_threadref(threadref * id, const int value)
+{
+	unsigned char *scan = (unsigned char *) id;
+	int i = 4;
+
+	while (i--)
+		*scan++ = 0;
+
+	*scan++ = (value >> 24) & 0xff;
+	*scan++ = (value >> 16) & 0xff;
+	*scan++ = (value >> 8) & 0xff;
+	*scan++ = (value & 0xff);
+}
+
+/* Return a task structure ptr for a particular pid */
+static struct task_struct * get_thread(int pid)
+{
+	struct task_struct *thread;
+
+	/* Use PID_MAX w/gdb for pid 0 */
+	if (pid == PID_MAX) pid = 0;
+
+	/* First check via PID */
+	thread = find_task_by_pid(pid);
+
+	if (thread)
+		return thread;
+
+	/* Start at the start */
+	thread = init_tasks[0];
+
+	/* Walk along the linked list of tasks */
+	do {
+		if (thread->pid == pid)
+			return thread;
+		thread = thread->next_task;
+	} while (thread != init_tasks[0]);
+
+	return NULL;
+}
+#endif /* CONFIG_KGDB_THREAD */
+
+void kgdb_msg(const char * msg)
+{
+	const char *emsg;
+
+	for (emsg = msg; *emsg; emsg++) ;
+
+	remcomOutBuffer[0] = 'O';
+
+	mem2hex(msg, remcomOutBuffer+1, emsg-msg);
+
+	if (kgdb_active()) kgdb_put_packet(remcomOutBuffer);
+}
+
+static void send_ok_msg(void)
+{
+	kgdb_put_packet("OK");
+}
+
+static void send_err_msg(void)
+{
+	kgdb_put_packet("E01");
+}
+
+static void send_empty_msg(void)
+{
+	kgdb_put_packet("");
+}
+
+static void send_signal_msg(const int signum)
+{
+#ifndef CONFIG_KGDB_THREAD
+	remcomOutBuffer[0] = 'S';
+	remcomOutBuffer[1] =  hexchars[(signum >> 4) & 0xf];
+	remcomOutBuffer[2] =  hexchars[signum % 16];
+	remcomOutBuffer[3] = 0;
+#else /* CONFIG_KGDB_THREAD */
+	int threadid;
+	threadref thref;
+	char *out = remcomOutBuffer;
+	const char *tstring = "thread";
+
+	*out++ = 'T';
+	*out++ = hexchars[(signum >> 4) & 0xf];
+	*out++ = hexchars[signum % 16];
+
+	while (*tstring) {
+                *out++ = *tstring++;
+	}
+	*out++ = ':';
+
+	threadid = trapped_thread->pid;
+	if (threadid == 0) threadid = PID_MAX;
+	int_to_threadref(&thref, threadid);
+	pack_threadid(out, &thref);
+	out += BUF_THREAD_ID_SIZE;
+	*out++ = ';';
+
+	*out = 0;
+#endif /* CONFIG_KGDB_THREAD */
+	kgdb_put_packet(remcomOutBuffer);
+}
+
+static void send_regs_msg(void)
+{
+#ifdef CONFIG_KGDB_THREAD
+	if (!current_thread)
+		kregs2gregs(&kgdb_regs, gdb_regs);
+	else
+		tregs2gregs(current_thread, gdb_regs);
+#else
+	kregs2gregs(&kgdb_regs, gdb_regs);
+#endif
+	mem2hex((const char *)gdb_regs, remcomOutBuffer, GDB_REGBYTES);
+	kgdb_put_packet(remcomOutBuffer);
+}
+
+/* Set register contents - currently can't set other thread's registers */
+static void set_regs_msg(void)
+{
+#ifdef CONFIG_KGDB_THREAD
+	if (!current_thread) {
+#endif
+		kregs2gregs(&kgdb_regs, gdb_regs);
+		hex2mem(&remcomInBuffer[1], (char *) gdb_regs, GDB_REGBYTES);
+		gregs2kregs(gdb_regs, &kgdb_regs);
+		send_ok_msg();
+#ifdef CONFIG_KGDB_THREAD
+	} else
+		send_err_msg();
+#endif
+}
+
+/* The following provides support for recovery from bus
+ * errors during kgdb memory read/write operations.
+ */
+void kgdb_handle_bus_error(void)
+{
+	kgdb_longjmp(fault_jmp_buf, 1);
+}
+
+/* Read memory due to 'm' message */
+static void read_mem_msg(void)
+{
+	char *ptr;
+	int addr;
+	int length;
+
+	/* Jmp, disable bus error handler */
+	if (kgdb_setjmp(fault_jmp_buf) == 0) {
+
+		kgdb_fault_expected = 1;
+
+		/* Walk through, have m<addr>,<length> */
+		ptr = &remcomInBuffer[1];
+		if (hex2int(&ptr, &addr) && (*ptr++ == ','))
+			if (hex2int(&ptr, &length)) {
+				ptr = 0;
+				if (length * 2 > BUFMAX)
+					length = BUFMAX / 2;
+				mem2hex((char *) addr, remcomOutBuffer, length);
+			}
+		if (ptr)
+			send_err_msg();
+		else
+			kgdb_put_packet(remcomOutBuffer);
+	} else
+		send_err_msg();
+
+	/* Restore bus error handler */
+	kgdb_fault_expected = 0;
+}
+
+/* Write memory due to 'M' or 'X' message */
+static void write_mem_msg(int binary)
+{
+	char *ptr;
+	int addr;
+	int length;
+
+	if (kgdb_setjmp(fault_jmp_buf) == 0) {
+
+		kgdb_fault_expected = 1;
+
+		/* Walk through, have M<addr>,<length>:<data> */
+		ptr = &remcomInBuffer[1];
+		if (hex2int(&ptr, &addr) && (*ptr++ == ','))
+			if (hex2int(&ptr, &length) && (*ptr++ == ':')) {
+				if (binary)
+					ebin2mem(ptr, (char*)addr, length);
+				else
+					hex2mem(ptr, (char*)addr, length);
+				ptr = 0;
+
+				/*
+				 * Trap breakpoints
+				 */
+				if(length == 4 && !(addr & 0x3) &&
+					*((unsigned *)addr) == GDB_BREAKINST)
+					*((unsigned *)addr) = KGDB_BREAKINST;
+
+				send_ok_msg();
+			}
+		if (ptr)
+			send_err_msg();
+	} else
+		send_err_msg();
+
+	/* Restore bus error handler */
+	kgdb_fault_expected = 0;
+}
+
+static void continue_msg(void)
+{
+        /* Try to read optional parameter, PC unchanged if none */
+        char *ptr = &remcomInBuffer[1];
+        int addr;
+
+        if (hex2int(&ptr, &addr))
+                kgdb_regs.ARM_pc = addr;
+
+	strcpy(remcomOutBuffer, "OK");
+	kgdb_put_packet(remcomOutBuffer);
+}
+
+static void continue_with_sig_msg(void)
+{
+        int signal;
+        char *ptr = &remcomInBuffer[1];
+        int addr;
+
+        /* Report limitation */
+        kgdb_msg("Cannot force signal in kgdb, continuing anyway.\n");
+
+        /* Signal */
+        hex2int(&ptr, &signal);
+        if (*ptr == ';')
+                ptr++;
+
+        /* Optional address */
+        if (hex2int(&ptr, &addr))
+                kgdb_regs.ARM_pc = addr;
+
+	strcpy(remcomOutBuffer, "OK");
+	kgdb_put_packet(remcomOutBuffer);
+}
+
+void do_single_step(void)
+{
+	step_addr = (unsigned int *) get_next_pc(&kgdb_regs);
+	step_instr = *step_addr;
+	*step_addr = KGDB_BREAKINST;
+}
+
+static void undo_single_step(void)
+{
+	if (step_addr != NULL) {
+		*step_addr = step_instr;
+		step_addr = NULL;
+		step_instr = 0;
+	}
+}
+
+static void step_msg(void)
+{
+        continue_msg();
+        do_single_step();
+}
+
+static void step_with_sig_msg(void)
+{
+        continue_with_sig_msg();
+        do_single_step();
+}
+
+/* Set the status for a thread */
+void set_thread_msg(void)
+{
+#ifndef CONFIG_KGDB_THREAD
+	strcpy(remcomOutBuffer, "OK");
+	kgdb_put_packet(remcomOutBuffer);
+#else
+	int threadid;
+	struct task_struct *thread = NULL;
+	char *ptr;
+
+	switch (remcomInBuffer[1]) {
+
+       	/* To select which thread for gG etc messages, i.e. supported */
+	case 'g':
+		ptr = &remcomInBuffer[2];
+		hex2int(&ptr, &threadid);
+		thread = get_thread(threadid);
+
+		/* If we haven't found it */
+		if (!thread) {
+			send_err_msg();
+			break;
+		}
+
+		/* Set current_thread (or not) */
+		if (thread == trapped_thread)
+			current_thread = NULL;
+		else
+			current_thread = thread;
+		send_ok_msg();
+		break;
+
+	/* To select which thread for cCsS messages, i.e. unsupported */
+	case 'c':
+		send_ok_msg();
+		break;
+
+	default:
+		send_empty_msg();
+		break;
+	}
+#endif
+}
+
+#ifdef CONFIG_KGDB_THREAD
+/* Is a thread alive? */
+static void thread_status_msg(void)
+{
+	char *ptr;
+	int threadid;
+	struct task_struct *thread = NULL;
+
+	ptr = &remcomInBuffer[1];
+	hex2int(&ptr, &threadid);
+	thread = get_thread(threadid);
+	if (thread)
+		send_ok_msg();
+	else
+		send_err_msg();
+}
+
+/* Send the current thread ID */
+static void thread_id_msg(void)
+{
+	int threadid;
+	threadref thref;
+
+	remcomOutBuffer[0] = 'Q';
+	remcomOutBuffer[1] = 'C';
+
+	if (current_thread)
+		threadid = current_thread->pid;
+	else if (trapped_thread)
+		threadid = trapped_thread->pid;
+	else /* Impossible, but just in case! */
+	{
+		send_err_msg();
+		return;
+	}
+
+	/* Translate pid 0 to PID_MAX for gdb */
+	if (threadid == 0) threadid = PID_MAX;
+
+	int_to_threadref(&thref, threadid);
+	pack_threadid(remcomOutBuffer + 2, &thref);
+	remcomOutBuffer[2 + BUF_THREAD_ID_SIZE] = '\0';
+	kgdb_put_packet(remcomOutBuffer);
+}
+
+/* Send thread info */
+static void thread_info_msg(void)
+{
+	struct task_struct *thread = NULL;
+	int threadid;
+	char *pos;
+	threadref thref;
+
+	/* Start with 'm' */
+	remcomOutBuffer[0] = 'm';
+	pos = &remcomOutBuffer[1];
+
+	/* For all possible thread IDs - this will overrun if > 44 threads! */
+	/* Start at 1 and include PID_MAX (since GDB won't use pid 0...) */
+	for (threadid = 1; threadid <= PID_MAX; threadid++) {
+
+		read_lock(&tasklist_lock);
+		thread = get_thread(threadid);
+		read_unlock(&tasklist_lock);
+
+		/* If it's a valid thread */
+		if (thread) {
+			int_to_threadref(&thref, threadid);
+			pack_threadid(pos, &thref);
+			pos += BUF_THREAD_ID_SIZE;
+			*pos++ = ',';
+		}
+	}
+	*--pos = 0;		/* Lose final comma */
+	kgdb_put_packet(remcomOutBuffer);
+
+}
+
+/* Return printable info for gdb's 'info threads' command */
+static void thread_extra_info_msg(void)
+{
+	int threadid;
+	struct task_struct *thread = NULL;
+	char buffer[20], *ptr;
+	int i;
+
+	/* Extract thread ID */
+	ptr = &remcomInBuffer[17];
+	hex2int(&ptr, &threadid);
+	thread = get_thread(threadid);
+
+	/* If we don't recognise it, say so */
+	if (thread == NULL)
+		strcpy(buffer, "(unknown)");
+	else
+		strcpy(buffer, thread->comm);
+
+	/* Construct packet */
+	for (i = 0, ptr = remcomOutBuffer; buffer[i]; i++)
+		ptr = pack_hex_byte(ptr, buffer[i]);
+
+#if	0 /* REVISIT! */
+	if (thread->thread.pc == (unsigned long)ret_from_fork) {
+		strcpy(buffer, "<new fork>");
+		for (i = 0; buffer[i]; i++)
+			ptr = pack_hex_byte(ptr, buffer[i]);
+	}
+#endif
+
+	*ptr = '\0';
+	kgdb_put_packet(remcomOutBuffer);
+}
+
+/* Handle all qFooBarBaz messages - have to use an if statement as
+   opposed to a switch because q messages can have > 1 char id. */
+static void query_msg(void)
+{
+	const char *q_start = &remcomInBuffer[1];
+
+	/* qC = return current thread ID */
+	if (strncmp(q_start, "C", 1) == 0)
+		thread_id_msg();
+
+	/* qfThreadInfo = query all threads (first) */
+	else if (strncmp(q_start, "fThreadInfo", 11) == 0)
+		thread_info_msg();
+
+	/* qsThreadInfo = query all threads (subsequent). We know we have sent
+	   them all after the qfThreadInfo message, so there are no to send */
+	else if (strncmp(q_start, "sThreadInfo", 11) == 0)
+		kgdb_put_packet("l");	/* el = last */
+
+	/* qThreadExtraInfo = supply printable information per thread */
+	else if (strncmp(q_start, "ThreadExtraInfo", 15) == 0)
+		thread_extra_info_msg();
+
+	/* Unsupported - empty message as per spec */
+	else
+		send_empty_msg();
+}
+#endif /* CONFIG_KGDB_THREAD */
+
+/*
+ * This function does all command procesing for interfacing to gdb.
+ */
+void do_kgdb(struct pt_regs *trap_regs, unsigned char sigval)
+{
+	unsigned long flags;
+
+	save_flags_cli(flags);
+
+	kgdb_regs = *trap_regs; /* Quick and dirty clone of pt_regs */
+
+	/*
+	 * reply to host that an exception has occurred
+	 *
+	 * We don't do this on the first call as it would cause a sync problem.
+	 */
+	if (kgdb_initialized) {
+		send_signal_msg(sigval);
+	} else {
+		/*
+		 * This is the first breakpoint, called from
+		 * start_kernel or elsewhere. We need to
+		 * (re-)initialize the I/O subsystem.
+		 */
+
+		printk("Breaking into KGDB\n");
+
+		if(kgdb_io_init())
+		{
+			printk("KGB I/O INIT FAILED...HALTING!");
+			while(1){ };
+		}
+	}
+
+	kgdb_initialized = 1;
+
+#ifdef CONFIG_KGDB_THREAD
+        /* Until GDB specifies a thread */
+        current_thread = NULL;
+        trapped_thread = current;
+#endif
+
+	/*
+	 * Check to see if this is a compiled in breakpoint
+	 * (sysrq-G or initial breakpoint).  If so, we
+	 * need to increment the PC to the next instruction
+	 * so that we don't infinite loop.
+	 *
+	 * NOTE: THIS COULD BE BAD.  We're reading the PC and
+	 * if the cause of the fault is a bad PC, we're going
+	 * to suffer massive death. Need to find some way to
+	 * validate the PC address or use our setjmp/longjmp.
+	 */
+	if (sigval == SIGTRAP) {
+		/* Only do this check for the SIGTRAP case! */
+		if (*(unsigned int *)(kgdb_regs.ARM_pc) == KGDB_COMPILED_BREAK)
+			kgdb_regs.ARM_pc += 4;
+	}
+
+
+	undo_single_step(); /* handles cleanup upon step/stepi return */
+
+	while (1) {
+		remcomOutBuffer[0] = 0;
+
+		kgdb_get_packet(remcomInBuffer, BUFMAX);
+
+		switch (remcomInBuffer[0])
+		{
+		case '?':	/* Report most recent signal */
+			send_signal_msg(sigval);
+			break;
+
+		case 'g':	/* return the values of the CPU registers */
+			send_regs_msg();
+               		break;
+
+     		case 'G':	/* set the values of the CPU registers */
+			set_regs_msg();
+			break;
+
+		case 'm':	/* Read LLLL bytes address AA..AA */
+			read_mem_msg();
+	          	break;
+
+		case 'M':	/* Write LLLL bytes address AA.AA ret OK */
+			write_mem_msg(0);
+                	break;
+
+		case 'X':       /* Write LLLL bytes esc bin address AA..AA */
+			/* WARNING: UART must be configured for 8-bit chars */
+			write_mem_msg(1); /* 1 = data in binary */
+			break;
+
+		case 'C':	/* Continue, signum included, we ignore it */
+			continue_with_sig_msg();
+			goto exit_kgdb;
+
+		case 'c':	/* Continue at address AA..AA (optional) */
+			continue_msg();
+			goto exit_kgdb;
+
+		case 'S':	/* Step, signum included, we ignore it */
+			step_with_sig_msg();
+			goto exit_kgdb;
+
+		case 's':	/* Step one instruction from AA..AA */
+			step_msg();
+			goto exit_kgdb;
+
+		case 'H':	/* Task related */
+			set_thread_msg();
+			break;
+
+#ifdef CONFIG_KGDB_THREAD
+		case 'T':	/* Query thread status */
+			thread_status_msg();
+			break;
+
+		case 'q':	/* Handle query - currently thread-related */
+			query_msg();
+			break;
+#endif
+
+		case 'k':	/* kill the program - do nothing */
+			break;
+
+		case 'D':	/* Detach from program, send reply OK */
+			kgdb_enabled = 0;
+			send_ok_msg();
+			kgdb_serial_getchar();
+			goto exit_kgdb;
+
+		case 'd':	/* toggle debug flag */
+			remote_debug = !(remote_debug);
+               		break;
+
+		default:
+			send_empty_msg();
+			break;
+		}
+    	}
+
+exit_kgdb:
+	*trap_regs = kgdb_regs; /* Copy back any register updates */
+	cpu_cache_clean_invalidate_all();
+	restore_flags(flags);
+}
+
+/*
+ * TODO: If remote GDB disconnects from us, we need to return
+ * 0 as we're no longer active.  Does GDB send us a disconnect
+ * message??
+ */
+int kgdb_active(void)
+{
+	return kgdb_enabled;
+}
+
+
+/* Trigger a breakpoint by function */
+void breakpoint(void)
+{
+        if (!kgdb_enabled) {
+                kgdb_enabled = 1;
+        }
+        BREAKPOINT();
+}
+
+
+/*
+ * Code to determine next PC based on current PC address.
+ * Taken from GDB source code.  Open Source is good. :)
+ */
+#define read_register(x) regs->uregs[x]
+
+#define addr_bits_remove(x) (x & 0xfffffffc)
+
+#define submask(x) ((1L << ((x) + 1)) - 1)
+#define bit(obj,st) (((obj) >> (st)) & 1)
+#define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st)))
+#define sbits(obj,st,fn) \
+  ((long) (bits(obj,st,fn) | ((long) bit(obj,fn) * ~ submask (fn - st))))
+#define BranchDest(addr,instr) \
+  ((unsigned) (((long) (addr)) + 8 + (sbits (instr, 0, 23) << 2)))
+
+
+/* Instruction condition field values.  */
+#define INST_EQ         0x0
+#define INST_NE         0x1
+#define INST_CS         0x2
+#define INST_CC         0x3
+#define INST_MI         0x4
+#define INST_PL         0x5
+#define INST_VS         0x6
+#define INST_VC         0x7
+#define INST_HI         0x8
+#define INST_LS         0x9
+#define INST_GE         0xa
+#define INST_LT         0xb
+#define INST_GT         0xc
+#define INST_LE         0xd
+#define INST_AL         0xe
+#define INST_NV         0xf
+
+#define FLAG_N          0x80000000
+#define FLAG_Z          0x40000000
+#define FLAG_C          0x20000000
+#define FLAG_V          0x10000000
+
+#define error(x)
+
+static unsigned long
+shifted_reg_val (unsigned long inst, int carry, unsigned long pc_val,
+		 unsigned long status_reg, struct pt_regs* regs)
+{
+  unsigned long res = 0, shift = 0;
+  int rm = bits (inst, 0, 3);
+  unsigned long shifttype = bits (inst, 5, 6);
+
+  if (bit (inst, 4))
+    {
+      int rs = bits (inst, 8, 11);
+      shift = (rs == 15 ? pc_val + 8 : read_register (rs)) & 0xFF;
+    }
+  else
+    shift = bits (inst, 7, 11);
+
+  res = (rm == 15
+	 ? ((pc_val | (1 ? 0 : status_reg))
+	    + (bit (inst, 4) ? 12 : 8)) : read_register (rm));
+
+  switch (shifttype)
+    {
+    case 0:			/* LSL */
+      res = shift >= 32 ? 0 : res << shift;
+      break;
+
+    case 1:			/* LSR */
+      res = shift >= 32 ? 0 : res >> shift;
+      break;
+
+    case 2:			/* ASR */
+      if (shift >= 32)
+	shift = 31;
+      res = ((res & 0x80000000L)
+	     ? ~((~res) >> shift) : res >> shift);
+      break;
+
+    case 3:			/* ROR/RRX */
+      shift &= 31;
+      if (shift == 0)
+	res = (res >> 1) | (carry ? 0x80000000L : 0);
+      else
+	res = (res >> shift) | (res << (32 - shift));
+      break;
+    }
+
+  return res & 0xffffffff;
+}
+
+/* Return number of 1-bits in VAL.  */
+
+static int
+bitcount (unsigned long val)
+{
+  int nbits;
+  for (nbits = 0; val != 0; nbits++)
+    val &= val - 1;		/* delete rightmost 1-bit in val */
+  return nbits;
+}
+
+static int
+condition_true (unsigned long cond, unsigned long status_reg)
+{
+	if (cond == INST_AL || cond == INST_NV)
+		return 1;
+
+	switch (cond)
+	{
+		case INST_EQ:
+		  return ((status_reg & FLAG_Z) != 0);
+		case INST_NE:
+		  return ((status_reg & FLAG_Z) == 0);
+		case INST_CS:
+		  return ((status_reg & FLAG_C) != 0);
+		case INST_CC:
+		  return ((status_reg & FLAG_C) == 0);
+		case INST_MI:
+		  return ((status_reg & FLAG_N) != 0);
+		case INST_PL:
+		  return ((status_reg & FLAG_N) == 0);
+		case INST_VS:
+		  return ((status_reg & FLAG_V) != 0);
+		case INST_VC:
+		  return ((status_reg & FLAG_V) == 0);
+		case INST_HI:
+		  return ((status_reg & (FLAG_C | FLAG_Z)) == FLAG_C);
+		case INST_LS:
+		  return ((status_reg & (FLAG_C | FLAG_Z)) != FLAG_C);
+		case INST_GE:
+		  return (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0));
+		case INST_LT:
+		  return (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0));
+		case INST_GT:
+		  return (((status_reg & FLAG_Z) == 0) &&
+					(((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0)));
+		case INST_LE:
+		  return (((status_reg & FLAG_Z) != 0) ||
+					(((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0)));
+	}
+	return 1;
+}
+
+unsigned long
+get_next_pc(struct pt_regs *regs)
+{
+  unsigned long pc_val;
+  unsigned long this_instr;
+  unsigned long status;
+  unsigned long nextpc;
+
+  pc_val = regs->ARM_pc;
+  this_instr = *((unsigned long *)regs->ARM_pc);
+  status = regs->ARM_cpsr;
+  nextpc = pc_val + 4;	/* Default case */
+
+  if (condition_true (bits (this_instr, 28, 31), status))
+  {
+	  switch (bits (this_instr, 24, 27))
+	  {
+		case 0x0:
+		case 0x1:		/* data processing */
+		case 0x2:
+		case 0x3:
+		{
+			unsigned long operand1, operand2, result = 0;
+		 	unsigned long rn;
+			int c;
+
+			if (bits (this_instr, 12, 15) != 15)
+				break;
+
+			if (bits (this_instr, 22, 25) == 0
+					&& bits (this_instr, 4, 7) == 9)
+				/* multiply */
+				error ("Illegal update to pc in instruction");
+
+			/* Multiply into PC */
+			c = (status & FLAG_C) ? 1 : 0;
+			rn = bits (this_instr, 16, 19);
+			operand1 = (rn == 15) ? pc_val + 8 : read_register (rn);
+
+			if (bit (this_instr, 25))
+			{
+				unsigned long immval = bits (this_instr, 0, 7);
+				unsigned long rotate = 2 * bits (this_instr, 8, 11);
+				operand2 = ((immval >> rotate) | (immval << (32 - rotate)))
+									& 0xffffffff;
+			}
+			else		/* operand 2 is a shifted register */
+				operand2 = shifted_reg_val (this_instr, c, pc_val, status, regs);
+
+			switch (bits (this_instr, 21, 24))
+			{
+				case 0x0:	/*and */
+					result = operand1 & operand2;
+					break;
+
+				case 0x1:	/*eor */
+					result = operand1 ^ operand2;
+					break;
+
+				case 0x2:	/*sub */
+					result = operand1 - operand2;
+					break;
+
+				case 0x3:	/*rsb */
+					result = operand2 - operand1;
+					break;
+
+				case 0x4:	/*add */
+					result = operand1 + operand2;
+					break;
+
+				case 0x5:	/*adc */
+					result = operand1 + operand2 + c;
+					break;
+
+				case 0x6:	/*sbc */
+					result = operand1 - operand2 + c;
+					break;
+
+				case 0x7:	/*rsc */
+					result = operand2 - operand1 + c;
+					break;
+
+				case 0x8:
+				case 0x9:
+				case 0xa:
+				case 0xb:	/* tst, teq, cmp, cmn */
+					result = (unsigned long) nextpc;
+					break;
+
+				case 0xc:	/*orr */
+					result = operand1 | operand2;
+					break;
+
+				case 0xd:	/*mov */
+					/* Always step into a function.  */
+					result = operand2;
+					break;
+
+				case 0xe:	/*bic */
+					result = operand1 & ~operand2;
+					break;
+
+				case 0xf:	/*mvn */
+					result = ~operand2;
+					break;
+			}
+			nextpc = addr_bits_remove(result);
+
+			break;
+	  }
+
+		case 0x4:
+		case 0x5:		/* data transfer */
+		case 0x6:
+		case 0x7:
+		if (bit (this_instr, 20))
+		{
+			/* load */
+			if (bits (this_instr, 12, 15) == 15)
+			{
+				/* rd == pc */
+				unsigned long rn;
+				unsigned long base;
+
+				if (bit (this_instr, 22))
+					error ("Illegal update to pc in instruction");
+
+				/* byte write to PC */
+				rn = bits (this_instr, 16, 19);
+				base = (rn == 15) ? pc_val + 8 : read_register (rn);
+				if (bit (this_instr, 24))
+				{
+					/* pre-indexed */
+					int c = (status & FLAG_C) ? 1 : 0;
+					unsigned long offset =
+							  (bit (this_instr, 25)
+								? shifted_reg_val (this_instr, c, pc_val, status, regs)
+								: bits (this_instr, 0, 11));
+
+					if (bit (this_instr, 23))
+						base += offset;
+					else
+						base -= offset;
+				}
+				nextpc = *((unsigned long *) base);
+
+				nextpc = addr_bits_remove (nextpc);
+
+				if (nextpc == regs->ARM_pc)
+						  error ("Infinite loop detected");
+			}
+		}
+		break;
+
+		case 0x8:
+		case 0x9:		/* block transfer */
+		if (bit (this_instr, 20))
+		{
+			/* LDM */
+			if (bit (this_instr, 15))
+			{
+				/* loading pc */
+				int offset = 0;
+
+				if (bit (this_instr, 23))
+				{
+					/* up */
+					unsigned long reglist = bits (this_instr, 0, 14);
+					offset = bitcount (reglist) * 4;
+					if (bit (this_instr, 24))		/* pre */
+						offset += 4;
+				}
+				else if (bit (this_instr, 24))
+					offset = - 4;
+
+				{
+					unsigned long rn_val =
+						read_register (bits (this_instr, 16, 19));
+					nextpc = *((unsigned int *) (rn_val + offset));
+				}
+
+				nextpc = addr_bits_remove (nextpc);
+				if (nextpc == regs->ARM_pc)
+						  error ("Infinite loop detected");
+			}
+		}
+		break;
+
+		case 0xb:		/* branch & link */
+		case 0xa:		/* branch */
+		{
+			nextpc = BranchDest (regs->ARM_pc, this_instr);
+			nextpc = addr_bits_remove (nextpc);
+
+			if (nextpc == regs->ARM_pc)
+				error ("Infinite loop detected");
+
+			break;
+		}
+
+		case 0xc:
+		case 0xd:
+		case 0xe:		/* coproc ops */
+		case 0xf:		/* SWI */
+			break;
+
+		default:
+			error("Bad bit-field extraction");
+			return (regs->ARM_pc);
+	  }
+  }
+
+  return nextpc;
+}
diff -urN linux-2.4.29/arch/arm/kernel/Makefile linux-2.4.29-uc1/arch/arm/kernel/Makefile
--- linux-2.4.29/arch/arm/kernel/Makefile	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/Makefile	2005-06-14 02:11:00.000000000 +0100
@@ -24,6 +24,7 @@
 pci-footbridge	  = dec21285.o
 pci-shark	  = via82c505.o
 
+
 # this is here to allow us to eventually move it out to mach-ftvpci
 pci-$(CONFIG_ARCH_FTVPCI) += ftv-pci.o
 
@@ -44,8 +45,11 @@
 no-irq-arch	:= $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) \
 		   $(CONFIG_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \
 		   $(CONFIG_ARCH_SA1100) $(CONFIG_ARCH_CAMELOT) \
-		   $(CONFIG_ARCH_MX1ADS) $(CONFIG_ARCH_OMAHA) \
-		   $(CONFIG_ARCH_AT91RM9200)
+		   $(CONFIG_ARCH_MX1ADS) $(CONFIG_ARCH_IXP1200) \
+		   $(CONFIG_ARCH_IOP3XX) $(CONFIG_ARCH_ADIFCC) \
+		   $(CONFIG_ARCH_OMAHA) $(CONFIG_ARCH_IXP425) \
+		   $(CONFIG_ARCH_IXP2000) $(CONFIG_ARCH_AT91RM9200) \
+		   $(CONFIG_ARCH_EP93XX) $(CONFIG_ARCH_KS8695)
 
 ifneq ($(findstring y,$(no-irq-arch)),y)
   obj-y		+= irq-arch.o
@@ -54,12 +58,20 @@
 obj-$(CONFIG_ARCH_ACORN) += ecard.o fiq.o time-acorn.o
 obj-$(CONFIG_ARCH_CLPS7500) += time-acorn.o
 obj-$(CONFIG_ARCH_RISCSTATION) += time-acorn.o
+obj-$(CONFIG_ARCH_EDB7312) += fiq.o
+obj-$(CONFIG_ARCH_CDB89712) += fiq.o
 obj-$(CONFIG_DEBUG_LL)	+= debug-$(PROCESSOR).o
 obj-$(CONFIG_MODULES)	+= armksyms.o
 obj-$(CONFIG_ARTHUR)	+= arthur.o
 obj-$(CONFIG_ISA_DMA)	+= dma-isa.o
 obj-$(CONFIG_PCI)	+= bios32.o $(pci-$(MACHINE)) $(pci-y)
 
+obj-$(CONFIG_XSCALE_PMU_TIMER) += xscale-time.o
+obj-$(CONFIG_XSCALE_PMU) += xscale-pmu.o
+
+obj-$(CONFIG_XSCALE_PMU_TIMER) += xscale-time.o
+obj-$(CONFIG_XSCALE_PMU)       += xscale-pmu.o
+
 ifneq ($(MACHINE),ebsa110)
   obj-y		+= io.o
 endif
diff -urN linux-2.4.29/arch/arm/kernel/process.c linux-2.4.29-uc1/arch/arm/kernel/process.c
--- linux-2.4.29/arch/arm/kernel/process.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/process.c	2005-06-14 02:11:00.000000000 +0100
@@ -118,6 +118,9 @@
 void machine_halt(void)
 {
 	leds_event(led_halted);
+	/* actually halt */
+	while (1)
+		;
 }
 
 void machine_power_off(void)
diff -urN linux-2.4.29/arch/arm/kernel/semaphore.c linux-2.4.29-uc1/arch/arm/kernel/semaphore.c
--- linux-2.4.29/arch/arm/kernel/semaphore.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/semaphore.c	2005-06-14 02:11:00.000000000 +0100
@@ -193,7 +193,7 @@
 	bl	__down_interruptible		\n\
 	mov	ip, r0				\n\
 	ldmfd	sp!, {r0 - r3, pc}^		\n\
-
+						\n\
 	.align	5				\n\
 	.globl	__down_trylock_failed		\n\
 __down_trylock_failed:				\n\
diff -urN linux-2.4.29/arch/arm/kernel/setup.c linux-2.4.29-uc1/arch/arm/kernel/setup.c
--- linux-2.4.29/arch/arm/kernel/setup.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/setup.c	2005-06-14 02:11:00.000000000 +0100
@@ -141,6 +141,10 @@
 	sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
 	elf_hwcap = list->elf_hwcap;
 
+#ifdef CONFIG_EP93XX_CRUNCH
+        elf_hwcap |= HWCAP_CRUNCH;
+#endif
+
 	cpu_proc_init();
 }
 
@@ -432,8 +436,10 @@
 
 static int __init parse_tag_cmdline(const struct tag *tag)
 {
+#ifndef CONFIG_CMDLINE_FORCE
 	strncpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
 	default_command_line[COMMAND_LINE_SIZE - 1] = '\0';
+#endif
 	return 0;
 }
 
diff -urN linux-2.4.29/arch/arm/kernel/signal.c linux-2.4.29-uc1/arch/arm/kernel/signal.c
--- linux-2.4.29/arch/arm/kernel/signal.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/signal.c	2005-06-14 02:11:00.000000000 +0100
@@ -641,10 +641,7 @@
 				/* FALLTHRU */
 
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -urN linux-2.4.29/arch/arm/kernel/time.c linux-2.4.29-uc1/arch/arm/kernel/time.c
--- linux-2.4.29/arch/arm/kernel/time.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/time.c	2005-06-14 02:11:00.000000000 +0100
@@ -71,7 +71,7 @@
 /*
  * Handle kernel profile stuff...
  */
-static inline void do_profile(struct pt_regs *regs)
+inline void do_profile(struct pt_regs *regs)
 {
 	if (!user_mode(regs) &&
 	    prof_buffer &&
@@ -136,7 +136,7 @@
 #endif
 
 #ifdef CONFIG_LEDS_TIMER
-static void do_leds(void)
+void do_leds(void)
 {
 	static unsigned int count = 50;
 
diff -urN linux-2.4.29/arch/arm/kernel/traps.c linux-2.4.29-uc1/arch/arm/kernel/traps.c
--- linux-2.4.29/arch/arm/kernel/traps.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/traps.c	2005-06-14 02:11:00.000000000 +0100
@@ -24,11 +24,13 @@
 #include <linux/elf.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/sysrq.h>
 
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
+#include <asm/kgdb.h>
 
 #include "ptrace.h"
 
@@ -199,6 +201,13 @@
 		dump_instr(regs);
 	}
 
+#ifdef	CONFIG_KGDB
+	/* REVISIT: I'm not sure where to place this call to do_kgdb. So it's here for now... */
+	if (kgdb_active()) {
+		do_kgdb(regs, SIGKILL); /* SIGKILL sure seems appropriate here. : ) */
+	}
+#endif
+
 	spin_unlock_irq(&die_lock);
 	do_exit(SIGSEGV);
 }
@@ -223,6 +232,18 @@
 	regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
 	pc = (unsigned long *)instruction_pointer(regs);
 
+#ifdef CONFIG_KGDB
+	/* 
+	 * If we're not in user mode, we must have hit a breakpoint 
+	 * (or something * else has gone terribly wrong). 
+	 * So check in with do_kgdb...
+	 */
+	if (!user_mode(regs) && kgdb_active()) {
+		do_kgdb(regs, SIGTRAP);
+		return;
+	}
+#endif
+
 #ifdef CONFIG_DEBUG_USER
 	printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
 		current->comm, current->pid, pc);
@@ -239,6 +260,7 @@
 
 	force_sig_info(SIGILL, &info, current);
 
+
 	die_if_kernel("Oops - undefined instruction", regs, mode);
 }
 
@@ -252,6 +274,12 @@
 		current->comm, current->pid, instruction_pointer(regs));
 	dump_instr(regs);
 #endif
+#ifdef CONFIG_KGDB
+	/* REVISIT: We don't need this since we only support CONFIG_CPU_32 case. */
+	if (!user_mode(regs) && kgdb_active()) {
+		do_kgdb(regs, SIGBUS);
+	}
+#endif
 
 	current->thread.error_code = 0;
 	current->thread.trap_no = 11;
@@ -287,7 +315,7 @@
 
 	console_verbose();
 
-	printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n",
+	printk("Bad mode in %s handler detected: mode %s\n",
 		handler[reason], processor_modes[proc_mode]);
 
 	/*
@@ -348,6 +376,11 @@
 
 	switch (no & 0xffff) {
 	case 0: /* branch through 0 */
+#ifdef CONFIG_KGDB
+		if (!user_mode(regs) && kgdb_active()) {
+			do_kgdb(regs, -1);
+		}
+#endif
 		info.si_signo = SIGSEGV;
 		info.si_errno = 0;
 		info.si_code  = SEGV_MAPERR;
@@ -422,6 +455,11 @@
 		c_backtrace(regs->ARM_fp, processor_mode(regs));
 	}
 #endif
+#ifdef CONFIG_KGDB
+	if (!user_mode(regs) && kgdb_active()) {
+		do_kgdb(regs, SIGILL);
+	}
+#endif
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
 	info.si_code  = ILL_ILLTRP;
@@ -456,6 +494,11 @@
 	dump_instr(regs);
 	show_pte(current->mm, addr);
 #endif
+#ifdef CONFIG_KGDB
+	if (!user_mode(regs) && kgdb_active()) {
+		do_kgdb(regs, SIGILL);
+	}
+#endif
 
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
@@ -510,6 +553,32 @@
 	panic("Oops failed to kill thread");
 }
 
+#ifdef CONFIG_KGDB
+#ifdef CONFIG_KGDB_SYSRQ
+static void
+sysrq_handle_gdb(int key, struct pt_regs *pt_regs,
+                 struct kbd_struct *kbd, struct tty_struct *tty)
+{
+	breakpoint();
+}
+
+static struct sysrq_key_op sysrq_gdb_op = {
+	handler:	sysrq_handle_gdb,
+	help_msg:	"gDb",
+	action_msg:	"breaking into GDB",
+};
+#endif
+
+static int kgdb_halt = 1;
+
+void __init nohalt_setup(char *line)
+{
+	kgdb_halt = 0;
+}
+
+__setup("nohalt", nohalt_setup);
+#endif
+
 void __init trap_init(void)
 {
 	extern void __trap_init(unsigned long);
@@ -522,4 +591,16 @@
 #ifdef CONFIG_CPU_32
 	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
 #endif
+
+	/*
+	 * This is the earliest we can bkpt for now as we rely on
+	 * undefined instruction trap to hook into KGDB.
+	 */
+#ifdef CONFIG_KGDB
+#ifdef CONFIG_KGDB_SYSRQ
+	register_sysrq_key('d', &sysrq_gdb_op);
+#endif
+	if(kgdb_halt)
+		breakpoint();
+#endif
 }
diff -urN linux-2.4.29/arch/arm/kernel/xscale-pmu.c linux-2.4.29-uc1/arch/arm/kernel/xscale-pmu.c
--- linux-2.4.29/arch/arm/kernel/xscale-pmu.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/xscale-pmu.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,174 @@
+/*
+ * pmu.c
+ *
+ * This function provides the implementation of the access functions to 
+ * the Performance Monitoring Unit on all CPUs based on the XScale core.
+ *
+ * See Documentation/arm/XScale/pmu.txt for example usage
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2000-2001 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <asm/atomic.h>
+#include <asm/xscale-pmu.h>
+#include <asm/arch/irqs.h>
+
+static atomic_t usage = ATOMIC_INIT(0);
+static unsigned long id = 0;
+static u32 pmnc;
+struct pmu_results results;
+
+#define	PMU_ENABLE	0x001	/* Enable counters */
+#define PMN_RESET	0x002	/* Reset event counters */
+#define	CCNT_RESET	0x004	/* Reset clock counter */
+#define	PMU_RESET	CCNT_RESET | PMN_RESET
+#define	CLK_DIV		0x008	/* Clock divide enbable */
+#define INT_ENABLE	0x070	/* Interrupt enable */
+
+#define	PMN0_OVERFLOW	0x100	/* Perfromance counter 0 overflow */
+#define PMN1_OVERFLOW	0x200	/* Performance counter 1 overflow */
+#define CCNT_OVERFLOW	0x400	/* Clock counter overflow */
+
+static void pmu_irq_handler(int, void *, struct pt_regs *);
+
+
+int pmu_claim(void)
+{
+	int err = 0;
+
+	if(atomic_read(&usage))
+		return -EBUSY;
+
+	err = request_irq(XSCALE_PMU_IRQ, pmu_irq_handler, SA_INTERRUPT,
+					  NULL, (void *)&results);
+	if(err < 0)
+	{
+		printk(KERN_ERR "unable to request IRQ %d for 80200 PMU: %d\n",
+			   XSCALE_PMU_IRQ, err);
+		return err;
+	}
+	
+	atomic_inc(&usage);
+	pmnc = 0;
+	asm ("mcr p14, 0, %0, c0, c0, 0" : : "r" (pmnc));
+	
+	return ++id;
+}
+
+int pmu_release(int claim_id)
+{
+	if(!atomic_read(&usage))
+		return 0;
+
+	if(claim_id != id)
+		return -EPERM;
+
+	free_irq(XSCALE_PMU_IRQ, (void *)&results);
+	atomic_dec(&usage);
+
+	return 0;
+}
+
+int pmu_start(u32 pmn0, u32 pmn1)
+{
+	results.ccnt_of = 0;
+	results.ccnt = 0;
+	results.pmn0_of = 0;
+	results.pmn0 = 0;
+	results.pmn1_of = 0;
+	results.pmn1 = 0;
+
+	pmnc = (pmn1 << 20) | (pmn0 << 12);
+	pmnc |= PMU_ENABLE | PMU_RESET | INT_ENABLE;
+
+	asm ("mcr p14, 0, %0, c0, c0, 0" : : "r" (pmnc));
+
+	/* event 0x5 branch instr exec work around */
+	/* fixed in B stepping of the chip */
+	/* A stepping requires two writes to pmnc to execute correctly */
+	if((pmn0 == 0x5) || (pmn1 == 0x5))
+	{
+		asm ("mcr p14, 0, %0, c0, c0, 0" : : "r" (pmnc));
+	}
+
+	return 0;
+}
+
+int pmu_stop(struct pmu_results *results)
+{
+	u32 ccnt;
+	u32 pmn0;
+	u32 pmn1;
+
+	if(!pmnc)
+		return -ENOSYS;
+
+	asm ("mrc p14, 0, %0, c1, c0, 0" : "=r" (ccnt));
+	asm ("mrc p14, 0, %0, c2, c0, 0" : "=r" (pmn0));
+	asm ("mrc p14, 0, %0, c3, c0, 0" : "=r" (pmn1));
+
+	pmnc = 0;
+
+	asm ("mcr p14, 0, %0, c0, c0, 0" : : "r" (pmnc));
+
+	results->ccnt = ccnt;
+	results->pmn0 = pmn0;
+	results->pmn1 = pmn1;
+	return 0;
+}
+
+static void pmu_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct pmu_results *results = (struct pmu_results *)dev_id;
+
+	/* NOTE: there's an A stepping errata that states if an overflow */
+	/*       bit already exists and another occurs, the previous     */
+	/*       Overflow bit gets cleared. There's no workaround.	 */
+	/*	 Fixed in B stepping or later			 	 */
+
+	/* read the status */
+	asm ("mrc p14, 0, %0, c0, c0, 0" : "=r" (pmnc));
+
+	if(pmnc & PMN0_OVERFLOW)
+	{
+		results->pmn0_of++;
+	}
+
+	if(pmnc & PMN1_OVERFLOW)
+	{
+		results->pmn1_of++;
+	}
+
+	if(pmnc & CCNT_OVERFLOW)
+	{
+		results->ccnt_of++;
+	}
+
+	asm ("mcr p14, 0, %0, c0, c0, 0" : : "r" (pmnc));
+}
+
diff -urN linux-2.4.29/arch/arm/kernel/xscale-time.c linux-2.4.29-uc1/arch/arm/kernel/xscale-time.c
--- linux-2.4.29/arch/arm/kernel/xscale-time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/kernel/xscale-time.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,133 @@
+/*
+ * linux/arch/arm/kernel/xscale-time.c
+ *
+ * This file implements a timer based on the XScale's internal
+ * performance monitoring clock counter.  This code exists for
+ * boards without external timers to be developed on or during 
+ * early hardware bring up if the external timer does not
+ * work.  To utilize it, CONFIG_XSCALE_PMU_TIMER should be
+ * set by the configuration scripts. You also need to have
+ * a #define for IRQ_XSCALE_PMU that maps the PMU interrupt
+ * on your specific board/processor.
+ * 
+ * Author:  Nicolas Pitre
+ * Copyright:   (C) 2001 MontaVista Software Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/timex.h>
+#include <asm/hardware.h>
+
+#include <asm/mach-types.h>
+
+extern int setup_arm_irq(int, struct irqaction *);
+
+/* IRQs are disabled before entering here from do_gettimeofday() */
+static unsigned long xscale_pmu_gettimeoffset (void)
+{
+	unsigned long elapsed, usec;
+
+	/* We need elapsed timer ticks since last interrupt */
+	/* 
+	 * Read the CCNT value.  The returned value is 
+	 * between -LATCH and 0, 0 corresponding to a full jiffy 
+	 */
+	asm volatile ("mrc p14, 0, %0, c1, c0, 0" : "=r" (elapsed));
+	elapsed += LATCH;
+
+	/* Now convert them to usec */
+	usec = (unsigned long)(elapsed*tick)/LATCH;
+
+	return usec;
+}
+
+static void xscale_pmu_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	long cnt;
+	unsigned long PMNC;
+
+	/*
+	 * The overflow must be cleared before the CCNT
+	 * register is updated to prevent a race condition
+	 * that can cause a lost timer tick.
+	 */
+	asm volatile ("mrc p14, 0, %0, c0, c0, 0" : "=r" (PMNC));
+	/* Enable CCNT overflow interrupt in the PMNC */
+	asm volatile ("mcr p14, 0, %0, c0, c0, 0" : : "r" (PMNC & 0x0ffff479));
+
+	do {
+		do_timer(regs);
+
+		/* 
+		 * Bring the count back for one timer tick.
+		 * To be precise, we need to consider the cycles 
+		 * involved in this read-modify-write sequence, as well as
+		 * cache fill operations which can stall the instruction 
+		 * pipeline.
+		 */
+		asm volatile ( "\
+		mcr p15, 0, ip, c7, c10, 4 @ Flush the write (& read) buffers\n\
+		b	1f\n\
+		.align	5		@ Align code on a cache line boundary\n\
+1:		mrc p14, 0, %0, c1, c0, 0\n\
+		sub	%0, %0, %1\n\
+		mcr p14, 0, %0, c1, c0, 0"
+		: "=&r" (cnt) : "r" (LATCH-10));
+	} while (cnt >= 0);
+}
+
+extern unsigned long (*gettimeoffset)(void);
+
+static struct irqaction timer_irq = {
+	name: "timer",
+	handler: xscale_pmu_timer_interrupt,
+	flags: SA_INTERRUPT
+};
+
+void __init setup_timer (void)
+{
+    unsigned long INTSTR;
+
+	gettimeoffset = xscale_pmu_gettimeoffset;
+	setup_arm_irq(XSCALE_PMU_IRQ, &timer_irq);
+
+	printk("Using XScale PMU as timer source(IRQ %d, %d MHz Clock Tick)\n",
+		XSCALE_PMU_IRQ, CLOCK_TICK_RATE / 1000000 );
+
+	/*
+	 * Need to do this b/c going to IDLE mode on XScale causes
+	 * the PMU to idle also, which means we loose the timer tick!
+	 */
+	disable_hlt();
+
+
+	if(machine_is_iq80310())
+	{
+		/* Steer PMU int to IRQ */
+		asm volatile("mrc p13, 0, %0, c8, c0, 0" : "=r" (INTSTR));
+		/* Clear write-as-zero bits 31:2 and PMU steering bit 0 */
+		asm volatile ("mcr p13, 0, %0, c8, c0, 0" : : "r" (INTSTR & 2));
+	}
+
+	/* set the initial CCNT value */
+	asm volatile ("mcr p14, 0, %0, c1, c0, 0" : : "r" (-LATCH));
+	
+	/* enable interrupt to occur on CCNT wraps in the PMNC */
+	asm volatile ("mcr p14, 0, %0, c0, c0, 0" : : "r" (0x0ffff443));
+}
diff -urN linux-2.4.29/arch/arm/lib/adddf3.c linux-2.4.29-uc1/arch/arm/lib/adddf3.c
--- linux-2.4.29/arch/arm/lib/adddf3.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/adddf3.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,188 @@
+/*
+** libgcc support for software floating point.
+** Copyright (C) 1991 by Pipeline Associates, Inc.  All rights reserved.
+** Permission is granted to do *anything* you want with this file,
+** commercial or otherwise, provided this message remains intact.  So there!
+** I would appreciate receiving any updates/patches/changes that anyone
+** makes, and am willing to be the repository for said changes (am I
+** making a big mistake?).
+
+Warning! Only single-precision is actually implemented.  This file
+won't really be much use until double-precision is supported.
+
+However, once that is done, this file might make possible
+cross-compilation for an IEEE target machine from a non-IEEE
+host such as a VAX.
+
+If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
+
+--> Double precision floating support added by James Carlson on 20 April 1998.
+
+**
+** Pat Wood
+** Pipeline Associates, Inc.
+** pipeline!phw@motown.com or
+** sun!pipeline!phw or
+** uunet!motown!pipeline!phw
+**
+** 05/01/91 -- V1.0 -- first release to gcc mailing lists
+** 05/04/91 -- V1.1 -- added float and double prototypes and return values
+**                  -- fixed problems with adding and subtracting zero
+**                  -- fixed rounding in truncdfsf2
+**                  -- fixed SWAP define and tested on 386
+*/
+
+/*
+** The following are routines that replace the libgcc soft floating point
+** routines that are called automatically when -msoft-float is selected.
+** The support single and double precision IEEE format, with provisions
+** for byte-swapped machines (tested on 386).  Some of the double-precision
+** routines work at full precision, but most of the hard ones simply punt
+** and call the single precision routines, producing a loss of accuracy.
+** long long support is not assumed or included.
+** Overall accuracy is close to IEEE (actually 68882) for single-precision
+** arithmetic.  I think there may still be a 1 in 1000 chance of a bit
+** being rounded the wrong way during a multiply.  I'm not fussy enough to
+** bother with it, but if anyone is, knock yourself out.
+**
+** Efficiency has only been addressed where it was obvious that something
+** would make a big difference.  Anyone who wants to do this right for
+** best speed should go in and rewrite in assembler.
+**
+** I have tested this only on a 68030 workstation and 386/ix integrated
+** in with -msoft-float.
+*/
+
+/* the following deal with IEEE single-precision numbers */
+#define EXCESS		126
+#define SIGNBIT		0x80000000
+#define HIDDEN		(1 << 23)
+#define SIGN(fp)	((fp) & SIGNBIT)
+#define EXP(fp)		(((fp) >> 23) & 0xFF)
+#define MANT(fp)	(((fp) & 0x7FFFFF) | HIDDEN)
+#define PACK(s,e,m)	((s) | ((e) << 23) | (m))
+
+/* the following deal with IEEE double-precision numbers */
+#define EXCESSD		1022
+#define HIDDEND		(1 << 20)
+#define EXPD(fp)	(((fp.l.upper) >> 20) & 0x7FF)
+#define SIGND(fp)	((fp.l.upper) & SIGNBIT)
+#define MANTD(fp)	(((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
+				(fp.l.lower >> 22))
+#define HIDDEND_LL	((long long)1 << 52)
+#define MANTD_LL(fp)	((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
+#define PACKD_LL(s,e,m)	(((long long)((s)+((e)<<20))<<32)|(m))
+
+/* define SWAP for 386/960 reverse-byte-order brain-damaged CPUs */
+union double_long {
+    double d;
+#ifdef SWAP
+    struct {
+      unsigned long lower;
+      long upper;
+    } l;
+#else
+    struct {
+      long upper;
+      unsigned long lower;
+    } l;
+#endif
+    long long ll;
+};
+
+union float_long
+  {
+    float f;
+    long l;
+  };
+
+
+/* addtwo doubles */
+double
+__adddf3 (double a1, double a2)
+{
+    long long mant1, mant2;
+    union double_long fl1, fl2;
+    int exp1, exp2;
+    int sign = 0;
+
+    fl1.d = a1;
+    fl2.d = a2;
+
+    /* check for zero args */
+    if (!fl2.ll)
+	goto test_done;
+    if (!fl1.ll) {
+	fl1.d = fl2.d;
+	goto test_done;
+    }
+
+    exp1 = EXPD(fl1);
+    exp2 = EXPD(fl2);
+
+    if (exp1 > exp2 + 54)
+	goto test_done;
+    if (exp2 > exp1 + 54) {
+	fl1.d = fl2.d;
+	goto test_done;
+    }
+
+    /* do everything in excess precision so's we can round later */
+    mant1 = MANTD_LL(fl1) << 9;
+    mant2 = MANTD_LL(fl2) << 9;
+
+    if (SIGND(fl1))
+	mant1 = -mant1;
+    if (SIGND(fl2))
+	mant2 = -mant2;
+
+    if (exp1 > exp2)
+	mant2 >>= exp1 - exp2;
+    else {
+	mant1 >>= exp2 - exp1;
+	exp1 = exp2;
+    }
+    mant1 += mant2;
+
+    if (mant1 < 0) {
+	mant1 = -mant1;
+	sign = SIGNBIT;
+    } else if (!mant1) {
+	fl1.d = 0;
+	goto test_done;
+    }
+
+    /* normalize up */
+    while (!(mant1 & ((long long)7<<61))) {
+	mant1 <<= 1;
+	exp1--;
+    }
+
+    /* normalize down? */
+    if (mant1 & ((long long)3<<62)) {
+	mant1 >>= 1;
+	exp1++;
+    }
+
+    /* round to even */
+    mant1 += (mant1 & (1<<9)) ? (1<<8) : ((1<<8)-1);
+
+    /* normalize down? */
+    if (mant1 & ((long long)3<<62)) {
+	mant1 >>= 1;
+	exp1++;
+    }
+
+    /* lose extra precision */
+    mant1 >>= 9;
+
+    /* turn off hidden bit */
+    mant1 &= ~HIDDEND_LL;
+
+    /* pack up and go home */
+    fl1.ll = PACKD_LL(sign,exp1,mant1);
+
+test_done:
+    return (fl1.d);
+}
+
diff -urN linux-2.4.29/arch/arm/lib/changebit.S linux-2.4.29-uc1/arch/arm/lib/changebit.S
--- linux-2.4.29/arch/arm/lib/changebit.S	2000-09-18 23:15:25.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/changebit.S	2005-06-14 02:11:00.000000000 +0100
@@ -14,7 +14,10 @@
 /* Purpose  : Function to change a bit
  * Prototype: int change_bit(int bit, void *addr)
  */
-ENTRY(change_bit)
+
+ENTRY(_change_bit_be)
+		eor	r0, r0, #0x18		@ big endian byte ordering
+ENTRY(_change_bit_le)
 		and	r2, r0, #7
 		mov	r3, #1
 		mov	r3, r3, lsl r2
diff -urN linux-2.4.29/arch/arm/lib/clearbit.S linux-2.4.29-uc1/arch/arm/lib/clearbit.S
--- linux-2.4.29/arch/arm/lib/clearbit.S	2000-09-18 23:15:25.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/clearbit.S	2005-06-14 02:10:59.000000000 +0100
@@ -16,7 +16,9 @@
  * Prototype: int clear_bit(int bit, void *addr)
  */
 
-ENTRY(clear_bit)
+ENTRY(_clear_bit_be)
+		eor	r0, r0, #0x18		@ big endian byte ordering
+ENTRY(_clear_bit_le)
 		and	r2, r0, #7
 		mov	r3, #1
 		mov	r3, r3, lsl r2
diff -urN linux-2.4.29/arch/arm/lib/csumpartialcopygeneric.S linux-2.4.29-uc1/arch/arm/lib/csumpartialcopygeneric.S
--- linux-2.4.29/arch/arm/lib/csumpartialcopygeneric.S	2001-05-16 23:25:16.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/csumpartialcopygeneric.S	2005-06-14 02:10:59.000000000 +0100
@@ -36,16 +36,16 @@
 
 		load1b	ip
 		sub	len, len, #1
-		adcs	sum, sum, ip, lsl #8	@ update checksum
+		adcs	sum, sum, ip, lsl #byte(1)	@ update checksum
 		strb	ip, [dst], #1
 		tst	dst, #2
 		moveq	pc, lr			@ dst is now 32bit aligned
 
 .dst_16bit:	load2b	r8, ip
 		sub	len, len, #2
-		adcs	sum, sum, r8
+		adcs	sum, sum, r8, lsl #byte(0)
 		strb	r8, [dst], #1
-		adcs	sum, sum, ip, lsl #8
+		adcs	sum, sum, ip, lsl #byte(1)
 		strb	ip, [dst], #1
 		mov	pc, lr			@ dst is now 32bit aligned
 
@@ -63,16 +63,16 @@
 		/* Align dst */
 		load1b	ip
 		sub	len, len, #1
-		adcs	sum, sum, ip, lsl #8	@ update checksum
+		adcs	sum, sum, ip, lsl #byte(1)	@ update checksum
 		strb	ip, [dst], #1
 		tst	len, #6
 		beq	.less8_byteonly
 
 1:		load2b	r8, ip
 		sub	len, len, #2
-		adcs	sum, sum, r8
+		adcs	sum, sum, r8, lsl #byte(0)
 		strb	r8, [dst], #1
-		adcs	sum, sum, ip, lsl #8
+		adcs	sum, sum, ip, lsl #byte(1)
 		strb	ip, [dst], #1
 .less8_aligned:	tst	len, #6
 		bne	1b
@@ -80,7 +80,7 @@
 		tst	len, #1
 		beq	.done
 		load1b	r8
-		adcs	sum, sum, r8		@ update checksum
+		adcs	sum, sum, r8, lsl #byte(0)	@ update checksum
 		strb	r8, [dst], #1
 		b	.done
 
@@ -139,16 +139,17 @@
 		beq	.done
 		load1l	r4
 		tst	len, #2
+		mov	r5, r4, lsr #byte(0)
 		beq	.exit
-		adcs	sum, sum, r4, lsl #16
-		strb	r4, [dst], #1
-		mov	r4, r4, lsr #8
-		strb	r4, [dst], #1
-		mov	r4, r4, lsr #8
+		adcs	sum, sum, r4, push #16
+		strb	r5, [dst], #1
+		mov	r5, r4, lsr #byte(1)
+		strb	r5, [dst], #1
+		mov	r5, r4, lsr #byte(2)
 .exit:		tst	len, #1
-		strneb	r4, [dst], #1
-		andne	r4, r4, #255
-		adcnes	sum, sum, r4
+		strneb	r5, [dst], #1
+		andne	r5, r5, #255
+		adcnes	sum, sum, r5, lsl #byte(0)
 
 		/*
 		 * If the dst pointer was not 16-bit aligned, we
@@ -167,27 +168,27 @@
 		adc	sum, sum, #0		@ include C from dst alignment
 		and	ip, src, #3
 		bic	src, src, #3
-		load1l	r4
+		load1l	r5
 		cmp	ip, #2
 		beq	.src2_aligned
 		bhi	.src3_aligned
-		mov	r4, r4, lsr #8		@ C = 0
+		mov	r4, r5, pull #8		@ C = 0
 		bics	ip, len, #15
 		beq	2f
 1:		load4l	r5, r6, r7, r8
-		orr	r4, r4, r5, lsl #24
-		mov	r5, r5, lsr #8
-		orr	r5, r5, r6, lsl #24
-		mov	r6, r6, lsr #8
-		orr	r6, r6, r7, lsl #24
-		mov	r7, r7, lsr #8
-		orr	r7, r7, r8, lsl #24
+		orr	r4, r4, r5, push #24
+		mov	r5, r5, pull #8
+		orr	r5, r5, r6, push #24
+		mov	r6, r6, pull #8
+		orr	r6, r6, r7, push #24
+		mov	r7, r7, pull #8
+		orr	r7, r7, r8, push #24
 		stmia	dst!, {r4, r5, r6, r7}
 		adcs	sum, sum, r4
 		adcs	sum, sum, r5
 		adcs	sum, sum, r6
 		adcs	sum, sum, r7
-		mov	r4, r8, lsr #8
+		mov	r4, r8, pull #8
 		sub	ip, ip, #16
 		teq	ip, #0
 		bne	1b
@@ -196,49 +197,50 @@
 		tst	ip, #8
 		beq	3f
 		load2l	r5, r6
-		orr	r4, r4, r5, lsl #24
-		mov	r5, r5, lsr #8
-		orr	r5, r5, r6, lsl #24
+		orr	r4, r4, r5, push #24
+		mov	r5, r5, pull #8
+		orr	r5, r5, r6, push #24
 		stmia	dst!, {r4, r5}
 		adcs	sum, sum, r4
 		adcs	sum, sum, r5
-		mov	r4, r6, lsr #8
+		mov	r4, r6, pull #8
 		tst	ip, #4
 		beq	4f
 3:		load1l	r5
-		orr	r4, r4, r5, lsl #24
+		orr	r4, r4, r5, push #24
 		str	r4, [dst], #4
 		adcs	sum, sum, r4
-		mov	r4, r5, lsr #8
+		mov	r4, r5, pull #8
 4:		ands	len, len, #3
 		beq	.done
+		mov	r5, r4, lsr #byte(0)
 		tst	len, #2
 		beq	.exit
-		adcs	sum, sum, r4, lsl #16
-		strb	r4, [dst], #1
-		mov	r4, r4, lsr #8
-		strb	r4, [dst], #1
-		mov	r4, r4, lsr #8
+		adcs	sum, sum, r4, push #16
+		strb	r5, [dst], #1
+		mov	r5, r4, lsr #byte(1)
+		strb	r5, [dst], #1
+		mov	r5, r4, lsr #byte(2)
 		b	.exit
 
-.src2_aligned:	mov	r4, r4, lsr #16
+.src2_aligned:	mov	r4, r5, pull #16
 		adds	sum, sum, #0
 		bics	ip, len, #15
 		beq	2f
 1:		load4l	r5, r6, r7, r8
-		orr	r4, r4, r5, lsl #16
-		mov	r5, r5, lsr #16
-		orr	r5, r5, r6, lsl #16
-		mov	r6, r6, lsr #16
-		orr	r6, r6, r7, lsl #16
-		mov	r7, r7, lsr #16
-		orr	r7, r7, r8, lsl #16
+		orr	r4, r4, r5, push #16
+		mov	r5, r5, pull #16
+		orr	r5, r5, r6, push #16
+		mov	r6, r6, pull #16
+		orr	r6, r6, r7, push #16
+		mov	r7, r7, pull #16
+		orr	r7, r7, r8, push #16
 		stmia	dst!, {r4, r5, r6, r7}
 		adcs	sum, sum, r4
 		adcs	sum, sum, r5
 		adcs	sum, sum, r6
 		adcs	sum, sum, r7
-		mov	r4, r8, lsr #16
+		mov	r4, r8, pull #16
 		sub	ip, ip, #16
 		teq	ip, #0
 		bne	1b
@@ -247,51 +249,52 @@
 		tst	ip, #8
 		beq	3f
 		load2l	r5, r6
-		orr	r4, r4, r5, lsl #16
-		mov	r5, r5, lsr #16
-		orr	r5, r5, r6, lsl #16
+		orr	r4, r4, r5, push #16
+		mov	r5, r5, pull #16
+		orr	r5, r5, r6, push #16
 		stmia	dst!, {r4, r5}
 		adcs	sum, sum, r4
 		adcs	sum, sum, r5
-		mov	r4, r6, lsr #16
+		mov	r4, r6, pull #16
 		tst	ip, #4
 		beq	4f
 3:		load1l	r5
-		orr	r4, r4, r5, lsl #16
+		orr	r4, r4, r5, push #16
 		str	r4, [dst], #4
 		adcs	sum, sum, r4
-		mov	r4, r5, lsr #16
+		mov	r4, r5, pull #16
 4:		ands	len, len, #3
 		beq	.done
+		mov	r5, r4, lsr #byte(0)
 		tst	len, #2
 		beq	.exit
-		adcs	sum, sum, r4, lsl #16
-		strb	r4, [dst], #1
-		mov	r4, r4, lsr #8
-		strb	r4, [dst], #1
+		adcs	sum, sum, r4
+		strb	r5, [dst], #1
+		mov	r5, r4, lsr #byte(1)
+		strb	r5, [dst], #1
 		tst	len, #1
 		beq	.done
-		load1b	r4
+		load1b	r5
 		b	.exit
 
-.src3_aligned:	mov	r4, r4, lsr #24
+.src3_aligned:	mov	r4, r5, pull #24
 		adds	sum, sum, #0
 		bics	ip, len, #15
 		beq	2f
 1:		load4l	r5, r6, r7, r8
-		orr	r4, r4, r5, lsl #8
-		mov	r5, r5, lsr #24
-		orr	r5, r5, r6, lsl #8
-		mov	r6, r6, lsr #24
-		orr	r6, r6, r7, lsl #8
-		mov	r7, r7, lsr #24
-		orr	r7, r7, r8, lsl #8
+		orr	r4, r4, r5, push #8
+		mov	r5, r5, pull #24
+		orr	r5, r5, r6, push #8
+		mov	r6, r6, pull #24
+		orr	r6, r6, r7, push #8
+		mov	r7, r7, pull #24
+		orr	r7, r7, r8, push #8
 		stmia	dst!, {r4, r5, r6, r7}
 		adcs	sum, sum, r4
 		adcs	sum, sum, r5
 		adcs	sum, sum, r6
 		adcs	sum, sum, r7
-		mov	r4, r8, lsr #24
+		mov	r4, r8, pull #24
 		sub	ip, ip, #16
 		teq	ip, #0
 		bne	1b
@@ -300,28 +303,30 @@
 		tst	ip, #8
 		beq	3f
 		load2l	r5, r6
-		orr	r4, r4, r5, lsl #8
-		mov	r5, r5, lsr #24
-		orr	r5, r5, r6, lsl #8
+		orr	r4, r4, r5, push #8
+		mov	r5, r5, pull #24
+		orr	r5, r5, r6, push #8
 		stmia	dst!, {r4, r5}
 		adcs	sum, sum, r4
 		adcs	sum, sum, r5
-		mov	r4, r6, lsr #24
+		mov	r4, r6, pull #24
 		tst	ip, #4
 		beq	4f
 3:		load1l	r5
-		orr	r4, r4, r5, lsl #8
+		orr	r4, r4, r5, push #8
 		str	r4, [dst], #4
 		adcs	sum, sum, r4
-		mov	r4, r5, lsr #24
+		mov	r4, r5, pull #24
 4:		ands	len, len, #3
 		beq	.done
+		mov	r5, r4, lsr #byte(0)
 		tst	len, #2
 		beq	.exit
-		adcs	sum, sum, r4, lsl #16
-		strb	r4, [dst], #1
+		strb	r5, [dst], #1
+		adcs	sum, sum, r4
 		load1l	r4
-		strb	r4, [dst], #1
-		adcs	sum, sum, r4, lsl #24
-		mov	r4, r4, lsr #8
+		mov	r5, r4, lsr #byte(0)
+		strb	r5, [dst], #1
+		adcs	sum, sum, r4, push #24
+		mov	r5, r4, lsr #byte(1)
 		b	.exit
diff -urN linux-2.4.29/arch/arm/lib/csumpartial.S linux-2.4.29-uc1/arch/arm/lib/csumpartial.S
--- linux-2.4.29/arch/arm/lib/csumpartial.S	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/csumpartial.S	2005-06-14 02:10:59.000000000 +0100
@@ -41,7 +41,7 @@
 		tst	buf, #1			@ odd address?
 		ldrneb	td0, [buf], #1
 		subne	len, len, #1
-		adcnes	sum, sum, td0, lsl #8
+		adcnes	sum, sum, td0, lsl #byte(1)
 
 .less4:		tst	len, #6
 		beq	.less8_byte
@@ -57,7 +57,11 @@
 		ldrb	td0, [buf], #1
 		ldrb	td3, [buf], #1
 		sub	len, len, #2
+#ifndef __ARMEB__
 		orr	td0, td0, td3, lsl #8
+#else
+		orr	td0, td3, td0, lsl #8
+#endif
 #endif
 		adcs	sum, sum, td0
 		tst	len, #6
@@ -65,7 +69,7 @@
 
 .less8_byte:	tst	len, #1			@ odd number of bytes
 		ldrneb	td0, [buf], #1		@ include last byte
-		adcnes	sum, sum, td0		@ update checksum
+		adcnes	sum, sum, td0, lsl #byte(0)	@ update checksum
 
 .done:		adc	r0, sum, #0		@ collect up the last carry
 		ldr	td0, [sp], #4
@@ -77,7 +81,7 @@
 .not_aligned:	tst	buf, #1			@ odd address
 		ldrneb	td0, [buf], #1		@ make even
 		subne	len, len, #1
-		adcnes	sum, sum, td0, lsl #8	@ update checksum
+		adcnes	sum, sum, td0, lsl #byte(1)	@ update checksum
 
 		tst	buf, #2			@ 32-bit aligned?
 #if __LINUX_ARM_ARCH__ >= 4
@@ -88,7 +92,11 @@
 		ldrneb	td0, [buf], #1
 		ldrneb	ip, [buf], #1
 		subne	len, len, #2
+#ifndef __ARMEB__
 		orrne	td0, td0, ip, lsl #8
+#else
+		orrne	td0, ip, td0, lsl #8
+#endif
 #endif
 		adcnes	sum, sum, td0		@ update checksum
 		mov	pc, lr
diff -urN linux-2.4.29/arch/arm/lib/delay.S linux-2.4.29-uc1/arch/arm/lib/delay.S
--- linux-2.4.29/arch/arm/lib/delay.S	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/delay.S	2005-06-14 02:10:59.000000000 +0100
@@ -56,5 +56,21 @@
 
 ENTRY(__delay)
 		subs	r0, r0, #1
-		bcs	SYMBOL_NAME(__delay)
+#if 0
+		RETINSTR(movls,pc,lr)
+		subs	r0, r0, #1
+		RETINSTR(movls,pc,lr)
+		subs	r0, r0, #1
+		RETINSTR(movls,pc,lr)
+		subs	r0, r0, #1
+		RETINSTR(movls,pc,lr)
+		subs	r0, r0, #1
+		RETINSTR(movls,pc,lr)
+		subs	r0, r0, #1
+		RETINSTR(movls,pc,lr)
+		subs	r0, r0, #1
+		RETINSTR(movls,pc,lr)
+		subs	r0, r0, #1
+#endif
+		bhi	SYMBOL_NAME(__delay)
 		RETINSTR(mov,pc,lr)
diff -urN linux-2.4.29/arch/arm/lib/divdi3.c linux-2.4.29-uc1/arch/arm/lib/divdi3.c
--- linux-2.4.29/arch/arm/lib/divdi3.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/divdi3.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,58 @@
+/* More subroutines needed by GCC output code on some machines.  */
+/* Compile this one with gcc.  */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself cause the resulting executable
+   to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.
+ */
+#include "gcclib.h"
+#include "longlong.h"
+
+#define UDWtype		UDItype
+#define DWunion		DIunion
+#define DWtype		DItype
+
+DWtype
+__divdi3 (DWtype u, DWtype v)
+{
+  word_type c = 0;
+  DWunion uu, vv;
+  DWtype w;
+
+  uu.ll = u;
+  vv.ll = v;
+
+  if (uu.s.high < 0)
+    c = ~c,
+    uu.ll = -uu.ll;
+  if (vv.s.high < 0)
+    c = ~c,
+    vv.ll = -vv.ll;
+
+  w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
+  if (c)
+    w = -w;
+
+  return w;
+}
diff -urN linux-2.4.29/arch/arm/lib/findbit.S linux-2.4.29-uc1/arch/arm/lib/findbit.S
--- linux-2.4.29/arch/arm/lib/findbit.S	2000-09-18 23:15:25.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/findbit.S	2005-06-14 02:11:00.000000000 +0100
@@ -15,14 +15,14 @@
  * Purpose  : Find a 'zero' bit
  * Prototype: int find_first_zero_bit(void *addr, int maxbit);
  */
-ENTRY(find_first_zero_bit)
+ENTRY(_find_first_zero_bit_le)
 		mov	r2, #0
-.bytelp:	ldrb	r3, [r0, r2, lsr #3]
+1:		ldrb	r3, [r0, r2, lsr #3]
 		eors	r3, r3, #0xff		@ invert bits
 		bne	.found			@ any now set - found zero bit
 		add	r2, r2, #8		@ next bit pointer
 		cmp	r2, r1			@ any more?
-		bcc	.bytelp
+		bcc	1b
 		add	r0, r1, #1		@ no free bits
 		RETINSTR(mov,pc,lr)
 
@@ -30,15 +30,43 @@
  * Purpose  : Find next 'zero' bit
  * Prototype: int find_next_zero_bit(void *addr, int maxbit, int offset)
  */
-ENTRY(find_next_zero_bit)
+ENTRY(_find_next_zero_bit_le)
 		ands	ip, r2, #7
-		beq	.bytelp			@ If new byte, goto old routine
+		beq	1b			@ If new byte, goto old routine
 		ldrb	r3, [r0, r2, lsr#3]
 		eor	r3, r3, #0xff		@ now looking for a 1 bit
 		movs	r3, r3, lsr ip		@ shift off unused bits
+		bne	.found
+		orr	r2, r2, #7		@ if zero, then no bits here
+		add	r2, r2, #1		@ align bit pointer
+		b	1b			@ loop for next bit
+
+#ifdef __ARMEB__
+
+ENTRY(_find_first_zero_bit_be)
+		mov	r2, #0
+1:		eor	r3, r2, #0x18		@ big endian byte ordering
+		ldrb	r3, [r0, r3, lsr #3]
+		eors	r3, r3, #0xff		@ invert bits
+		bne	.found			@ any now set - found zero bit
+		add	r2, r2, #8		@ next bit pointer
+		cmp	r2, r1			@ any more?
+		bcc	1b
+		add	r0, r1, #1		@ no free bits
+		RETINSTR(mov,pc,lr)
+
+ENTRY(_find_next_zero_bit_be)
+		ands	ip, r2, #7
+		beq	1b			@ If new byte, goto old routine
+		eor	r3, r2, #0x18		@ big endian byte ordering
+		ldrb	r3, [r0, r3, lsr#3]
+		eor	r3, r3, #0xff		@ now looking for a 1 bit
+		movs	r3, r3, lsr ip		@ shift off unused bits
 		orreq	r2, r2, #7		@ if zero, then no bits here
 		addeq	r2, r2, #1		@ align bit pointer
-		beq	.bytelp			@ loop for next bit
+		beq	1b			@ loop for next bit
+
+#endif
 
 /*
  * One or more bits in the LSB of r3 are assumed to be set.
diff -urN linux-2.4.29/arch/arm/lib/floatsidf.c linux-2.4.29-uc1/arch/arm/lib/floatsidf.c
--- linux-2.4.29/arch/arm/lib/floatsidf.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/floatsidf.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,138 @@
+/*
+** libgcc support for software floating point.
+** Copyright (C) 1991 by Pipeline Associates, Inc.  All rights reserved.
+** Permission is granted to do *anything* you want with this file,
+** commercial or otherwise, provided this message remains intact.  So there!
+** I would appreciate receiving any updates/patches/changes that anyone
+** makes, and am willing to be the repository for said changes (am I
+** making a big mistake?).
+
+Warning! Only single-precision is actually implemented.  This file
+won't really be much use until double-precision is supported.
+
+However, once that is done, this file might make possible
+cross-compilation for an IEEE target machine from a non-IEEE
+host such as a VAX.
+
+If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
+
+--> Double precision floating support added by James Carlson on 20 April 1998.
+
+**
+** Pat Wood
+** Pipeline Associates, Inc.
+** pipeline!phw@motown.com or
+** sun!pipeline!phw or
+** uunet!motown!pipeline!phw
+**
+** 05/01/91 -- V1.0 -- first release to gcc mailing lists
+** 05/04/91 -- V1.1 -- added float and double prototypes and return values
+**                  -- fixed problems with adding and subtracting zero
+**                  -- fixed rounding in truncdfsf2
+**                  -- fixed SWAP define and tested on 386
+*/
+
+/*
+** The following are routines that replace the libgcc soft floating point
+** routines that are called automatically when -msoft-float is selected.
+** The support single and double precision IEEE format, with provisions
+** for byte-swapped machines (tested on 386).  Some of the double-precision
+** routines work at full precision, but most of the hard ones simply punt
+** and call the single precision routines, producing a loss of accuracy.
+** long long support is not assumed or included.
+** Overall accuracy is close to IEEE (actually 68882) for single-precision
+** arithmetic.  I think there may still be a 1 in 1000 chance of a bit
+** being rounded the wrong way during a multiply.  I'm not fussy enough to
+** bother with it, but if anyone is, knock yourself out.
+**
+** Efficiency has only been addressed where it was obvious that something
+** would make a big difference.  Anyone who wants to do this right for
+** best speed should go in and rewrite in assembler.
+**
+** I have tested this only on a 68030 workstation and 386/ix integrated
+** in with -msoft-float.
+*/
+
+/* the following deal with IEEE single-precision numbers */
+#define EXCESS		126
+#define SIGNBIT		0x80000000
+#define HIDDEN		(1 << 23)
+#define SIGN(fp)	((fp) & SIGNBIT)
+#define EXP(fp)		(((fp) >> 23) & 0xFF)
+#define MANT(fp)	(((fp) & 0x7FFFFF) | HIDDEN)
+#define PACK(s,e,m)	((s) | ((e) << 23) | (m))
+
+/* the following deal with IEEE double-precision numbers */
+#define EXCESSD		1022
+#define HIDDEND		(1 << 20)
+#define EXPD(fp)	(((fp.l.upper) >> 20) & 0x7FF)
+#define SIGND(fp)	((fp.l.upper) & SIGNBIT)
+#define MANTD(fp)	(((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
+				(fp.l.lower >> 22))
+#define HIDDEND_LL	((long long)1 << 52)
+#define MANTD_LL(fp)	((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
+#define PACKD_LL(s,e,m)	(((long long)((s)+((e)<<20))<<32)|(m))
+
+/* define SWAP for 386/960 reverse-byte-order brain-damaged CPUs */
+union double_long {
+    double d;
+#ifdef SWAP
+    struct {
+      unsigned long lower;
+      long upper;
+    } l;
+#else
+    struct {
+      long upper;
+      unsigned long lower;
+    } l;
+#endif
+    long long ll;
+};
+
+union float_long
+  {
+    float f;
+    long l;
+  };
+
+/* convert int to double */
+double
+__floatsidf (long a1)
+{
+  int sign = 0, exp = 31 + EXCESSD;
+  union double_long dl;
+
+  if (!a1)
+    {
+      dl.l.upper = dl.l.lower = 0;
+      return (dl.d);
+    }
+
+  if (a1 < 0)
+    {
+      sign = SIGNBIT;
+      a1 = -a1;
+    }
+
+  while (a1 < 0x1000000)
+    {
+      a1 <<= 4;
+      exp -= 4;
+    }
+
+  while (a1 < 0x40000000)
+    {
+      a1 <<= 1;
+      exp--;
+    }
+
+  /* pack up and go home */
+  dl.l.upper = sign;
+  dl.l.upper |= exp << 20;
+  dl.l.upper |= (a1 >> 10) & ~HIDDEND;
+  dl.l.lower = a1 << 22;
+
+  return (dl.d);
+}
+
diff -urN linux-2.4.29/arch/arm/lib/getuser.S linux-2.4.29-uc1/arch/arm/lib/getuser.S
--- linux-2.4.29/arch/arm/lib/getuser.S	2002-08-03 01:39:42.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/getuser.S	2005-06-14 02:10:59.000000000 +0100
@@ -42,14 +42,18 @@
 
 	.global	__get_user_2
 __get_user_2:
-	bic	r2, sp, #0x1f00
-	bic	r2, r2, #0x00ff
-	ldr	r2, [r2, #TSK_ADDR_LIMIT]
-	sub	r2, r2, #2
-	cmp	r0, r2
+	bic	ip, sp, #0x1f00
+	bic	ip, ip, #0x00ff
+	ldr	ip, [ip, #TSK_ADDR_LIMIT]
+	sub	ip, ip, #2
+	cmp	r0, ip
 2:	ldrlsbt	r1, [r0], #1
-3:	ldrlsbt	r2, [r0]
-	orrls	r1, r1, r2, lsl #8
+3:	ldrlsbt	ip, [r0]
+#ifndef __ARMEB__
+	orrls	r1, r1, ip, lsl #8
+#else
+	orrls	r1, ip, r1, lsl #8
+#endif
 	movls	r0, #0
 	movls	pc, lr
 	b	__get_user_bad
diff -urN linux-2.4.29/arch/arm/lib/io-readsb.S linux-2.4.29-uc1/arch/arm/lib/io-readsb.S
--- linux-2.4.29/arch/arm/lib/io-readsb.S	2001-08-12 19:13:59.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/io-readsb.S	2005-06-14 02:10:59.000000000 +0100
@@ -9,7 +9,6 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-#include <asm/hardware.h>
 
 .insb_align:	rsb	ip, ip, #4
 		cmp	ip, r2
@@ -30,80 +29,87 @@
 		ands	ip, r1, #3
 		bne	.insb_align
 
-.insb_aligned:	stmfd	sp!, {r4 - r6, lr}
+.insb_aligned:	stmfd	sp!, {r4, r5, lr}
 
 		subs	r2, r2, #16
 		bmi	.insb_no_16
 
 .insb_16_lp:	ldrb	r3, [r0]
+		mov	r3, r3, lsl #byte(0)
 		ldrb	r4, [r0]
-		orr	r3, r3, r4, lsl #8
+		orr	r3, r3, r4, lsl #byte(1)
 		ldrb	r4, [r0]
-		orr	r3, r3, r4, lsl #16
+		orr	r3, r3, r4, lsl #byte(2)
 		ldrb	r4, [r0]
-		orr	r3, r3, r4, lsl #24
+		orr	r3, r3, r4, lsl #byte(3)
 		ldrb	r4, [r0]
+		mov	r4, r4, lsl #byte(0)
 		ldrb	r5, [r0]
-		orr	r4, r4, r5, lsl #8
+		orr	r4, r4, r5, lsl #byte(1)
 		ldrb	r5, [r0]
-		orr	r4, r4, r5, lsl #16
+		orr	r4, r4, r5, lsl #byte(2)
 		ldrb	r5, [r0]
-		orr	r4, r4, r5, lsl #24
+		orr	r4, r4, r5, lsl #byte(3)
 		ldrb	r5, [r0]
-		ldrb	r6, [r0]
-		orr	r5, r5, r6, lsl #8
-		ldrb	r6, [r0]
-		orr	r5, r5, r6, lsl #16
-		ldrb	r6, [r0]
-		orr	r5, r5, r6, lsl #24
-		ldrb	r6, [r0]
+		mov	r5, r5, lsl #byte(0)
 		ldrb	ip, [r0]
-		orr	r6, r6, ip, lsl #8
+		orr	r5, r5, ip, lsl #byte(1)
 		ldrb	ip, [r0]
-		orr	r6, r6, ip, lsl #16
+		orr	r5, r5, ip, lsl #byte(2)
 		ldrb	ip, [r0]
-		orr	r6, r6, ip, lsl #24
-		stmia	r1!, {r3 - r6}
+		orr	r5, r5, ip, lsl #byte(3)
+		ldrb	ip, [r0]
+		mov	ip, ip, lsl #byte(0)
+		ldrb	lr, [r0]
+		orr	ip, ip, lr, lsl #byte(1)
+		ldrb	lr, [r0]
+		orr	ip, ip, lr, lsl #byte(2)
+		ldrb	lr, [r0]
+		orr	ip, ip, lr, lsl #byte(3)
+		stmia	r1!, {r3 - r5, ip}
 
 		subs	r2, r2, #16
 		bpl	.insb_16_lp
 
 		tst	r2, #15
-		LOADREGS(eqfd, sp!, {r4 - r6, pc})
+		LOADREGS(eqfd, sp!, {r4, r5, pc})
 
 .insb_no_16:	tst	r2, #8
 		beq	.insb_no_8
 
 		ldrb	r3, [r0]
+		mov	r3, r3, lsl #byte(0)
 		ldrb	r4, [r0]
-		orr	r3, r3, r4, lsl #8
+		orr	r3, r3, r4, lsl #byte(1)
 		ldrb	r4, [r0]
-		orr	r3, r3, r4, lsl #16
+		orr	r3, r3, r4, lsl #byte(2)
 		ldrb	r4, [r0]
-		orr	r3, r3, r4, lsl #24
+		orr	r3, r3, r4, lsl #byte(3)
 		ldrb	r4, [r0]
+		mov	r4, r4, lsl #byte(0)
 		ldrb	r5, [r0]
-		orr	r4, r4, r5, lsl #8
+		orr	r4, r4, r5, lsl #byte(1)
 		ldrb	r5, [r0]
-		orr	r4, r4, r5, lsl #16
+		orr	r4, r4, r5, lsl #byte(2)
 		ldrb	r5, [r0]
-		orr	r4, r4, r5, lsl #24
+		orr	r4, r4, r5, lsl #byte(3)
 		stmia	r1!, {r3, r4}
 
 .insb_no_8:	tst	r2, #4
 		beq	.insb_no_4
 
 		ldrb	r3, [r0]
+		mov	r3, r3, lsl #byte(0)
 		ldrb	r4, [r0]
-		orr	r3, r3, r4, lsl #8
+		orr	r3, r3, r4, lsl #byte(1)
 		ldrb	r4, [r0]
-		orr	r3, r3, r4, lsl #16
+		orr	r3, r3, r4, lsl #byte(2)
 		ldrb	r4, [r0]
-		orr	r3, r3, r4, lsl #24
+		orr	r3, r3, r4, lsl #byte(3)
 		str	r3, [r1], #4
 
 .insb_no_4:	ands	r2, r2, #3
-		LOADREGS(eqfd, sp!, {r4 - r6, pc})
+		LOADREGS(eqfd, sp!, {r4, r5, pc})
 
 		cmp	r2, #2
 		ldrb	r3, [r0]
@@ -113,4 +119,4 @@
 		ldrgtb	r3, [r0]
 		strgtb	r3, [r1]
 
-		LOADREGS(fd, sp!, {r4 - r6, pc})
+		LOADREGS(fd, sp!, {r4, r5, pc})
diff -urN linux-2.4.29/arch/arm/lib/io-readsl-armv4.S linux-2.4.29-uc1/arch/arm/lib/io-readsl-armv4.S
--- linux-2.4.29/arch/arm/lib/io-readsl-armv4.S	2001-09-07 17:28:38.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/io-readsl-armv4.S	2005-06-14 02:11:00.000000000 +0100
@@ -9,7 +9,6 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-#include <asm/hardware.h>
 
 /*
  * Note that some reads can be aligned on half-word boundaries.
@@ -31,6 +30,10 @@
 		blt	4f
 		bgt	6f
 
+#ifndef	__ARMEB__
+
+		/* little endian code */
+
 		strh	ip, [r1], #2
 		mov	ip, ip, lsr #16
 3:		subs	r2, r2, #1
@@ -68,3 +71,48 @@
 		strb	ip, [r1]
 		mov	pc, lr
 
+#else
+
+		/* big endian code */
+
+
+		mov	r3, ip, lsr #16
+		strh	r3, [r1], #2
+3:		mov	r3, ip, lsl #16
+		subs	r2, r2, #1
+		ldrne	ip, [r0]
+		orrne	r3, r3, ip, lsr #16
+		strne	r3, [r1], #4
+		bne	3b
+ 		strh	ip, [r1], #2
+ 		mov	pc, lr
+
+4:		mov	r3, ip, lsr #24
+		strb	r3, [r1], #1
+		mov	r3, ip, lsr #8
+		strh	r3, [r1], #2
+5:		mov	r3, ip, lsl #24
+		subs	r2, r2, #1
+		ldrne	ip, [r0]
+		orrne	r3, r3, ip, lsr #8
+		strne	r3, [r1], #4
+		bne	5b
+		strb	ip, [r1], #1
+		mov	pc, lr
+
+6:		mov	r3, ip, lsr #24
+		strb	r3, [r1], #1
+7:		mov	r3, ip, lsl #8
+		subs	r2, r2, #1
+		ldrne	ip, [r0]
+		orrne	r3, r3, ip, lsr #24
+		strne	r3, [r1], #4
+		bne	7b
+		mov	r3, ip, lsr #8
+		strh	r3, [r1], #2
+		strb	ip, [r1], #1
+		mov	pc, lr
+
+#endif
+
+
diff -urN linux-2.4.29/arch/arm/lib/io-readsw-armv4.S linux-2.4.29-uc1/arch/arm/lib/io-readsw-armv4.S
--- linux-2.4.29/arch/arm/lib/io-readsw-armv4.S	2001-08-12 19:13:59.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/io-readsw-armv4.S	2005-06-14 02:10:59.000000000 +0100
@@ -9,7 +9,14 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-#include <asm/hardware.h>
+
+		.macro	pack, rd, hw1, hw2
+#ifndef __ARMEB__
+		orr	\rd, \hw1, \hw2, lsl #16
+#else
+		orr	\rd, \hw2, \hw1, lsl #16
+#endif
+		.endm
 
 .insw_bad_alignment:
 		adr	r0, .insw_bad_align_msg
@@ -41,19 +48,19 @@
 
 .insw_8_lp:	ldrh	r3, [r0]
 		ldrh	r4, [r0]
-		orr	r3, r3, r4, lsl #16
+		pack	r3, r3, r4
 
 		ldrh	r4, [r0]
 		ldrh	r5, [r0]
-		orr	r4, r4, r5, lsl #16
+		pack	r4, r4, r5
 
 		ldrh	r5, [r0]
 		ldrh	ip, [r0]
-		orr	r5, r5, ip, lsl #16
+		pack	r5, r5, ip
 
 		ldrh	ip, [r0]
 		ldrh	lr, [r0]
-		orr	ip, ip, lr, lsl #16
+		pack	ip, ip, lr
 
 		stmia	r1!, {r3 - r5, ip}
 
@@ -68,11 +75,11 @@
 
 		ldrh	r3, [r0]
 		ldrh	r4, [r0]
-		orr	r3, r3, r4, lsl #16
+		pack	r3, r3, r4
 
 		ldrh	r4, [r0]
 		ldrh	ip, [r0]
-		orr	r4, r4, ip, lsl #16
+		pack	r4, r4, ip
 
 		stmia	r1!, {r3, r4}
 
@@ -81,7 +88,7 @@
 
 		ldrh	r3, [r0]
 		ldrh	ip, [r0]
-		orr	r3, r3, ip, lsl #16
+		pack	r3, r3, ip
 
 		str	r3, [r1], #4
 
diff -urN linux-2.4.29/arch/arm/lib/io-writesb.S linux-2.4.29-uc1/arch/arm/lib/io-writesb.S
--- linux-2.4.29/arch/arm/lib/io-writesb.S	2001-08-12 19:13:59.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/io-writesb.S	2005-06-14 02:10:59.000000000 +0100
@@ -9,7 +9,26 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-#include <asm/hardware.h>
+
+		.macro	outword, rd
+#ifndef __ARMEB__
+		strb	\rd, [r0]
+		mov	\rd, \rd, lsr #8
+		strb	\rd, [r0]
+		mov	\rd, \rd, lsr #8
+		strb	\rd, [r0]
+		mov	\rd, \rd, lsr #8
+		strb	\rd, [r0]
+#else
+		mov	lr, \rd, lsr #24
+		strb	lr, [r0]
+		mov	lr, \rd, lsr #16
+		strb	lr, [r0]
+		mov	lr, \rd, lsr #8
+		strb	lr, [r0]
+		strb	\rd, [r0]
+#endif
+		.endm
 
 .outsb_align:	rsb	ip, ip, #4
 		cmp	ip, r2
@@ -30,86 +49,37 @@
 		ands	ip, r1, #3
 		bne	.outsb_align
 
-.outsb_aligned:	stmfd	sp!, {r4 - r6, lr}
+.outsb_aligned:	stmfd	sp!, {r4, r5, lr}
 
 		subs	r2, r2, #16
 		bmi	.outsb_no_16
 
-.outsb_16_lp:	ldmia	r1!, {r3 - r6}
-
-		strb	r3, [r0]
-		mov	r3, r3, lsr #8
-		strb	r3, [r0]
-		mov	r3, r3, lsr #8
-		strb	r3, [r0]
-		mov	r3, r3, lsr #8
-		strb	r3, [r0]
-
-		strb	r4, [r0]
-		mov	r4, r4, lsr #8
-		strb	r4, [r0]
-		mov	r4, r4, lsr #8
-		strb	r4, [r0]
-		mov	r4, r4, lsr #8
-		strb	r4, [r0]
-
-		strb	r5, [r0]
-		mov	r5, r5, lsr #8
-		strb	r5, [r0]
-		mov	r5, r5, lsr #8
-		strb	r5, [r0]
-		mov	r5, r5, lsr #8
-		strb	r5, [r0]
-
-		strb	r6, [r0]
-		mov	r6, r6, lsr #8
-		strb	r6, [r0]
-		mov	r6, r6, lsr #8
-		strb	r6, [r0]
-		mov	r6, r6, lsr #8
-		strb	r6, [r0]
-
+.outsb_16_lp:	ldmia	r1!, {r3, r4, r5, ip}
+		outword	r3
+		outword	r4
+		outword	r5
+		outword	ip
 		subs	r2, r2, #16
 		bpl	.outsb_16_lp
 
 		tst	r2, #15
-		LOADREGS(eqfd, sp!, {r4 - r6, pc})
+		LOADREGS(eqfd, sp!, {r4, r5, pc})
 
 .outsb_no_16:	tst	r2, #8
 		beq	.outsb_no_8
 
 		ldmia	r1!, {r3, r4}
-
-		strb	r3, [r0]
-		mov	r3, r3, lsr #8
-		strb	r3, [r0]
-		mov	r3, r3, lsr #8
-		strb	r3, [r0]
-		mov	r3, r3, lsr #8
-		strb	r3, [r0]
-
-		strb	r4, [r0]
-		mov	r4, r4, lsr #8
-		strb	r4, [r0]
-		mov	r4, r4, lsr #8
-		strb	r4, [r0]
-		mov	r4, r4, lsr #8
-		strb	r4, [r0]
+		outword	r3
+		outword	r4
 
 .outsb_no_8:	tst	r2, #4
 		beq	.outsb_no_4
 
 		ldr	r3, [r1], #4
-		strb	r3, [r0]
-		mov	r3, r3, lsr #8
-		strb	r3, [r0]
-		mov	r3, r3, lsr #8
-		strb	r3, [r0]
-		mov	r3, r3, lsr #8
-		strb	r3, [r0]
+		outword	r3
 
 .outsb_no_4:	ands	r2, r2, #3
-		LOADREGS(eqfd, sp!, {r4 - r6, pc})
+		LOADREGS(eqfd, sp!, {r4, r5, pc})
 
 		cmp	r2, #2
 		ldrb	r3, [r1], #1
@@ -119,4 +89,4 @@
 		ldrgtb	r3, [r1]
 		strgtb	r3, [r0]
 
-		LOADREGS(fd, sp!, {r4 - r6, pc})
+		LOADREGS(fd, sp!, {r4, r5, pc})
diff -urN linux-2.4.29/arch/arm/lib/io-writesl.S linux-2.4.29-uc1/arch/arm/lib/io-writesl.S
--- linux-2.4.29/arch/arm/lib/io-writesl.S	2001-09-07 17:28:38.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/io-writesl.S	2005-06-14 02:11:00.000000000 +0100
@@ -9,7 +9,6 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-#include <asm/hardware.h>
 
 ENTRY(__raw_writesl)
 		teq	r2, #0		@ do we have to check for the zero len?
@@ -29,25 +28,25 @@
 		bgt	4f
 		blt	5f
 
-3:		mov	ip, r3, lsr #16
+3:		mov	ip, r3, pull #16
 		ldr	r3, [r1], #4
-		orr	ip, ip, r3, lsl #16
+		orr	ip, ip, r3, push #16
 		str	ip, [r0]
 		subs	r2, r2, #1
 		bne	3b
 		mov	pc, lr
 
-4:		mov	ip, r3, lsr #24
+4:		mov	ip, r3, pull #24
 		ldr	r3, [r1], #4
-		orr	ip, ip, r3, lsl #8
+		orr	ip, ip, r3, push #8
 		str	ip, [r0]
 		subs	r2, r2, #1
 		bne	4b
 		mov	pc, lr
 
-5:		mov	ip, r3, lsr #8
+5:		mov	ip, r3, pull #8
 		ldr	r3, [r1], #4
-		orr	ip, ip, r3, lsl #24
+		orr	ip, ip, r3, push #24
 		str	ip, [r0]
 		subs	r2, r2, #1
 		bne	5b
diff -urN linux-2.4.29/arch/arm/lib/io-writesw-armv4.S linux-2.4.29-uc1/arch/arm/lib/io-writesw-armv4.S
--- linux-2.4.29/arch/arm/lib/io-writesw-armv4.S	2001-08-12 19:13:59.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/io-writesw-armv4.S	2005-06-14 02:10:59.000000000 +0100
@@ -9,7 +9,18 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-#include <asm/hardware.h>
+
+		.macro	outword, rd
+#ifndef __ARMEB__
+		strh	\rd, [r0]
+		mov	\rd, \rd, lsr #16
+		strh	\rd, [r0]
+#else
+		mov	lr, \rd, lsr #16
+		strh	lr, [r0]
+		strh	\rd, [r0]
+#endif
+		.endm
 
 .outsw_bad_alignment:
 		adr	r0, .outsw_bad_align_msg
@@ -40,20 +51,10 @@
 		bmi	.no_outsw_8
 
 .outsw_8_lp:	ldmia	r1!, {r3, r4, r5, ip}
-
-		strh	r3, [r0]
-		mov	r3, r3, lsr #16
-		strh	r3, [r0]
-		strh	r4, [r0]
-		mov	r4, r4, lsr #16
-		strh	r4, [r0]
-		strh	r5, [r0]
-		mov	r5, r5, lsr #16
-		strh	r5, [r0]
-		strh	ip, [r0]
-		mov	ip, ip, lsr #16
-		strh	ip, [r0]
-
+		outword	r3
+		outword	r4
+		outword	r5
+		outword	ip
 		subs	r2, r2, #8
 		bpl	.outsw_8_lp
 
@@ -64,20 +65,14 @@
 		beq	.no_outsw_4
 
 		ldmia	r1!, {r3, ip}
-		strh	r3, [r0]
-		mov	r3, r3, lsr #16
-		strh	r3, [r0]
-		strh	ip, [r0]
-		mov	ip, ip, lsr #16
-		strh	ip, [r0]
+		outword	r3
+		outword	ip
 
 .no_outsw_4:	tst	r2, #2
 		beq	.no_outsw_2
 
 		ldr	r3, [r1], #4
-		strh	r3, [r0]
-		mov	r3, r3, lsr #16
-		strh	r3, [r0]
+		outword	r3
 
 .no_outsw_2:	tst	r2, #1
 		ldrneh	r3, [r1]
diff -urN linux-2.4.29/arch/arm/lib/Makefile linux-2.4.29-uc1/arch/arm/lib/Makefile
--- linux-2.4.29/arch/arm/lib/Makefile	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/Makefile	2005-06-14 02:10:59.000000000 +0100
@@ -15,7 +15,8 @@
 		   strnlen_user.o strchr.o strrchr.o testchangebit.o  \
 		   testclearbit.o testsetbit.o uaccess.o getuser.o    \
 		   putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o   \
-		   ucmpdi2.o udivdi3.o lib1funcs.o
+		   ucmpdi2.o udivdi3.o lib1funcs.o adddf3.o floatsidf.o \
+		   divdi3.o
 obj-m		:=
 obj-n		:=
 
diff -urN linux-2.4.29/arch/arm/lib/memcpy.S linux-2.4.29-uc1/arch/arm/lib/memcpy.S
--- linux-2.4.29/arch/arm/lib/memcpy.S	2001-03-07 03:44:35.000000000 +0000
+++ linux-2.4.29-uc1/arch/arm/lib/memcpy.S	2005-06-14 02:10:59.000000000 +0100
@@ -99,24 +99,24 @@
 		cmp	r2, #12
 		blt	10f
 		sub	r2, r2, #12
-9:		mov	r3, r7, lsr #8
+9:		mov	r3, r7, pull #8
 		ldmia	r1!, {r4 - r7}
-		orr	r3, r3, r4, lsl #24
-		mov	r4, r4, lsr #8
-		orr	r4, r4, r5, lsl #24
-		mov	r5, r5, lsr #8
-		orr	r5, r5, r6, lsl #24
-		mov	r6, r6, lsr #8
-		orr	r6, r6, r7, lsl #24
+		orr	r3, r3, r4, push #24
+		mov	r4, r4, pull #8
+		orr	r4, r4, r5, push #24
+		mov	r5, r5, pull #8
+		orr	r5, r5, r6, push #24
+		mov	r6, r6, pull #8
+		orr	r6, r6, r7, push #24
 		stmia	r0!, {r3 - r6}
 		subs	r2, r2, #16
 		bge	9b
 		adds	r2, r2, #12
 		blt	100f
-10:		mov	r3, r7, lsr #8
+10:		mov	r3, r7, pull #8
 		ldr	r7, [r1], #4
 		subs	r2, r2, #4
-		orr	r3, r3, r7, lsl #24
+		orr	r3, r3, r7, push #24
 		str	r3, [r0], #4
 		bge	10b
 100:		sub	r1, r1, #3
@@ -125,24 +125,24 @@
 11:		cmp	r2, #12
 		blt	13f		/* */
 		sub	r2, r2, #12
-12:		mov	r3, r7, lsr #16
+12:		mov	r3, r7, pull #16
 		ldmia	r1!, {r4 - r7}
-		orr	r3, r3, r4, lsl #16
-		mov	r4, r4, lsr #16
-		orr	r4, r4, r5, lsl #16
-		mov	r5, r5, lsr #16
-		orr	r5, r5, r6, lsl #16
-		mov	r6, r6, lsr #16
-		orr	r6, r6, r7,LSL#16
+		orr	r3, r3, r4, push #16
+		mov	r4, r4, pull #16
+		orr	r4, r4, r5, push #16
+		mov	r5, r5, pull #16
+		orr	r5, r5, r6, push #16
+		mov	r6, r6, pull #16
+		orr	r6, r6, r7, push #16
 		stmia	r0!, {r3 - r6}
 		subs	r2, r2, #16
 		bge	12b
 		adds	r2, r2, #12
 		blt	14f
-13:		mov	r3, r7, lsr #16
+13:		mov	r3, r7, pull #16
 		ldr	r7, [r1], #4
 		subs	r2, r2, #4
-		orr	r3, r3, r7, lsl #16
+		orr	r3, r3, r7, push #16
 		str	r3, [r0], #4
 		bge	13b
 14:		sub	r1, r1, #2
@@ -151,24 +151,24 @@
 15:		cmp	r2, #12
 		blt	17f
 		sub	r2, r2, #12
-16:		mov	r3, r7, lsr #24
-		ldmia	r1!,{r4 - r7}
-		orr	r3, r3, r4, lsl #8
-		mov	r4, r4, lsr #24
-		orr	r4, r4, r5, lsl #8
-		mov	r5, r5, lsr #24
-		orr	r5, r5, r6, lsl #8
-		mov	r6, r6, lsr #24
-		orr	r6, r6, r7, lsl #8
+16:		mov	r3, r7, pull #24
+		ldmia	r1!, {r4 - r7}
+		orr	r3, r3, r4, push #8
+		mov	r4, r4, pull #24
+		orr	r4, r4, r5, push #8
+		mov	r5, r5, pull #24
+		orr	r5, r5, r6, push #8
+		mov	r6, r6, pull #24
+		orr	r6, r6, r7, push #8
 		stmia	r0!, {r3 - r6}
 		subs	r2, r2, #16
 		bge	16b
 		adds	r2, r2, #12
 		blt	18f
-17:		mov	r3, r7, lsr #24
+17:		mov	r3, r7, pull #24
 		ldr	r7, [r1], #4
 		subs	r2, r2, #4
-		orr	r3, r3, r7, lsl#8
+		orr	r3, r3, r7, push #8
 		str	r3, [r0], #4
 		bge	17b
 18:		sub	r1, r1, #1
@@ -240,24 +240,24 @@
 		cmp	r2, #12
 		blt	28f
 		sub	r2, r2, #12
-27:		mov	r7, r3, lsl #8
+27:		mov	r7, r3, push #8
 		ldmdb	r1!, {r3, r4, r5, r6}
-		orr	r7, r7, r6, lsr #24
-		mov	r6, r6, lsl #8
-		orr	r6, r6, r5, lsr #24
-		mov	r5, r5, lsl #8
-		orr	r5, r5, r4, lsr #24
-		mov	r4, r4, lsl #8
-		orr	r4, r4, r3, lsr #24
+		orr	r7, r7, r6, pull #24
+		mov	r6, r6, push #8
+		orr	r6, r6, r5, pull #24
+		mov	r5, r5, push #8
+		orr	r5, r5, r4, pull #24
+		mov	r4, r4, push #8
+		orr	r4, r4, r3, pull #24
 		stmdb	r0!, {r4, r5, r6, r7}
 		subs	r2, r2, #16
 		bge	27b
 		adds	r2, r2, #12
 		blt	29f
-28:		mov	ip, r3, lsl #8
+28:		mov	ip, r3, push #8
 		ldr	r3, [r1, #-4]!
 		subs	r2, r2, #4
-		orr	ip, ip, r3, lsr #24
+		orr	ip, ip, r3, pull #24
 		str	ip, [r0, #-4]!
 		bge	28b
 29:		add	r1, r1, #3
@@ -266,24 +266,24 @@
 30:		cmp	r2, #12
 		blt	32f
 		sub	r2, r2, #12
-31:		mov	r7, r3, lsl #16
+31:		mov	r7, r3, push #16
 		ldmdb	r1!, {r3, r4, r5, r6}
-		orr	r7, r7, r6, lsr #16
-		mov	r6, r6, lsl #16
-		orr	r6, r6, r5, lsr #16
-		mov	r5, r5, lsl #16
-		orr	r5, r5, r4, lsr #16
-		mov	r4, r4, lsl #16
-		orr	r4, r4, r3, lsr #16
+		orr	r7, r7, r6, pull #16
+		mov	r6, r6, push #16
+		orr	r6, r6, r5, pull #16
+		mov	r5, r5, push #16
+		orr	r5, r5, r4, pull #16
+		mov	r4, r4, push #16
+		orr	r4, r4, r3, pull #16
 		stmdb	r0!, {r4, r5, r6, r7}
 		subs	r2, r2, #16
 		bge	31b
 		adds	r2, r2, #12
 		blt	33f
-32:		mov	ip, r3, lsl #16
+32:		mov	ip, r3, push #16
 		ldr	r3, [r1, #-4]!
 		subs	r2, r2, #4
-		orr	ip, ip, r3, lsr #16
+		orr	ip, ip, r3, pull #16
 		str	ip, [r0, #-4]!
 		bge	32b
 33:		add	r1, r1, #2
@@ -292,24 +292,24 @@
 34:		cmp	r2, #12
 		blt	36f
 		sub	r2, r2, #12
-35:		mov	r7, r3, lsl #24
+35:		mov	r7, r3, push #24
 		ldmdb	r1!, {r3, r4, r5, r6}
-		orr	r7, r7, r6, lsr #8
-		mov	r6, r6, lsl #24
-		orr	r6, r6, r5, lsr #8
-		mov	r5, r5, lsl #24
-		orr	r5, r5, r4, lsr #8
-		mov	r4, r4, lsl #24
-		orr	r4, r4, r3, lsr #8
+		orr	r7, r7, r6, pull #8
+		mov	r6, r6, push #24
+		orr	r6, r6, r5, pull #8
+		mov	r5, r5, push #24
+		orr	r5, r5, r4, pull #8
+		mov	r4, r4, push #24
+		orr	r4, r4, r3, pull #8
 		stmdb	r0!, {r4, r5, r6, r7}
 		subs	r2, r2, #16
 		bge	35b
 		adds	r2, r2, #12
 		blt	37f
-36:		mov	ip, r3, lsl #24
+36:		mov	ip, r3, push #24
 		ldr	r3, [r1, #-4]!
 		subs	r2, r2, #4
-		orr	ip, ip, r3, lsr #8
+		orr	ip, ip, r3, pull #8
 		str	ip, [r0, #-4]!
 		bge	36b
 37:		add	r1, r1, #1
diff -urN linux-2.4.29/arch/arm/lib/putuser.S linux-2.4.29-uc1/arch/arm/lib/putuser.S
--- linux-2.4.29/arch/arm/lib/putuser.S	2001-10-11 17:04:57.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/putuser.S	2005-06-14 02:10:59.000000000 +0100
@@ -18,7 +18,7 @@
  * Inputs:	r0 contains the address
  *		r1, r2 contains the value
  * Outputs:	r0 is the error code
- *		lr corrupted
+ *		ip, lr corrupted
  *
  * No other registers must be altered.  (see include/asm-arm/uaccess.h
  * for specific ASM register usage).
@@ -30,11 +30,11 @@
 
 	.global	__put_user_1
 __put_user_1:
-	bic	r2, sp, #0x1f00
-	bic	r2, r2, #0x00ff
-	ldr	r2, [r2, #TSK_ADDR_LIMIT]
-	sub	r2, r2, #1
-	cmp	r0, r2
+	bic	ip, sp, #0x1f00
+	bic	ip, ip, #0x00ff
+	ldr	ip, [ip, #TSK_ADDR_LIMIT]
+	sub	ip, ip, #1
+	cmp	r0, ip
 1:	strlsbt	r1, [r0]
 	movls	r0, #0
 	movls	pc, lr
@@ -42,25 +42,33 @@
 
 	.global	__put_user_2
 __put_user_2:
-	bic	r2, sp, #0x1f00
-	bic	r2, r2, #0x00ff
-	ldr	r2, [r2, #TSK_ADDR_LIMIT]
-	sub	r2, r2, #2
-	cmp	r0, r2
+	bic	ip, sp, #0x1f00
+	bic	ip, ip, #0x00ff
+	ldr	ip, [ip, #TSK_ADDR_LIMIT]
+	sub	ip, ip, #2
+	cmp	r0, ip
+#ifndef __ARMEB__
 2:	strlsbt	r1, [r0], #1
 	movls	r1, r1, lsr #8
 3:	strlsbt	r1, [r0]
+#else
+2:	movls	ip, r1
+	movls	r1, r1, lsr #8
+	strlsbt r1, [r0], #1
+	movls	r1, ip
+3:	strlsbt	r1, [r0]
+#endif
 	movls	r0, #0
 	movls	pc, lr
 	b	__put_user_bad
 
 	.global	__put_user_4
 __put_user_4:
-	bic	r2, sp, #0x1f00
-	bic	r2, r2, #0x00ff
-	ldr	r2, [r2, #TSK_ADDR_LIMIT]
-	sub	r2, r2, #4
-	cmp	r0, r2
+	bic	ip, sp, #0x1f00
+	bic	ip, ip, #0x00ff
+	ldr	ip, [ip, #TSK_ADDR_LIMIT]
+	sub	ip, ip, #4
+	cmp	r0, ip
 4:	strlst	r1, [r0]
 	movls	r0, #0
 	movls	pc, lr
diff -urN linux-2.4.29/arch/arm/lib/setbit.S linux-2.4.29-uc1/arch/arm/lib/setbit.S
--- linux-2.4.29/arch/arm/lib/setbit.S	2000-09-18 23:15:25.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/setbit.S	2005-06-14 02:11:00.000000000 +0100
@@ -16,7 +16,9 @@
  * Prototype: int set_bit(int bit, void *addr)
  */
 
-ENTRY(set_bit)
+ENTRY(_set_bit_be)
+		eor	r0, r0, #0x18		@ big endian byte ordering
+ENTRY(_set_bit_le)
                 and     r2, r0, #7
                 mov     r3, #1
                 mov     r3, r3, lsl r2
diff -urN linux-2.4.29/arch/arm/lib/testchangebit.S linux-2.4.29-uc1/arch/arm/lib/testchangebit.S
--- linux-2.4.29/arch/arm/lib/testchangebit.S	2000-09-18 23:15:25.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/testchangebit.S	2005-06-14 02:10:59.000000000 +0100
@@ -11,7 +11,9 @@
 #include <asm/assembler.h>
                 .text
 
-ENTRY(test_and_change_bit)
+ENTRY(_test_and_change_bit_be)
+		eor	r0, r0, #0x18		@ big endian byte ordering
+ENTRY(_test_and_change_bit_le)
 		add	r1, r1, r0, lsr #3
 		and	r3, r0, #7
 		mov	r0, #1
diff -urN linux-2.4.29/arch/arm/lib/testclearbit.S linux-2.4.29-uc1/arch/arm/lib/testclearbit.S
--- linux-2.4.29/arch/arm/lib/testclearbit.S	2000-09-18 23:15:25.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/testclearbit.S	2005-06-14 02:11:00.000000000 +0100
@@ -11,7 +11,9 @@
 #include <asm/assembler.h>
                 .text
 
-ENTRY(test_and_clear_bit)
+ENTRY(_test_and_clear_bit_be)
+		eor	r0, r0, #0x18		@ big endian byte ordering
+ENTRY(_test_and_clear_bit_le)
 		add	r1, r1, r0, lsr #3	@ Get byte offset
 		and	r3, r0, #7		@ Get bit offset
 		mov	r0, #1
diff -urN linux-2.4.29/arch/arm/lib/testsetbit.S linux-2.4.29-uc1/arch/arm/lib/testsetbit.S
--- linux-2.4.29/arch/arm/lib/testsetbit.S	2000-09-18 23:15:25.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/testsetbit.S	2005-06-14 02:11:00.000000000 +0100
@@ -11,7 +11,9 @@
 #include <asm/assembler.h>
                 .text
 
-ENTRY(test_and_set_bit)
+ENTRY(_test_and_set_bit_be)
+		eor	r0, r0, #0x18		@ big endian byte ordering
+ENTRY(_test_and_set_bit_le)
 		add	r1, r1, r0, lsr #3	@ Get byte offset
 		and	r3, r0, #7		@ Get bit offset
 		mov	r0, #1
diff -urN linux-2.4.29/arch/arm/lib/uaccess.S linux-2.4.29-uc1/arch/arm/lib/uaccess.S
--- linux-2.4.29/arch/arm/lib/uaccess.S	2000-09-18 23:15:25.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/lib/uaccess.S	2005-06-14 02:11:00.000000000 +0100
@@ -115,9 +115,9 @@
 .c2u_1fupi:	subs	r2, r2, #4
 		addmi	ip, r2, #4
 		bmi	.c2u_1nowords
-		mov	r3, r7, lsr #8
+		mov	r3, r7, pull #8
 		ldr	r7, [r1], #4
-		orr	r3, r3, r7, lsl #24
+		orr	r3, r3, r7, push #24
 USER(		strt	r3, [r0], #4)			@ May fault
 		mov	ip, r0, lsl #32 - PAGE_SHIFT
 		rsb	ip, ip, #0
@@ -129,49 +129,49 @@
 		subs	ip, ip, #16
 		blt	.c2u_1rem8lp
 
-.c2u_1cpy8lp:	mov	r3, r7, lsr #8
+.c2u_1cpy8lp:	mov	r3, r7, pull #8
 		ldmia	r1!, {r4 - r7}
-		orr	r3, r3, r4, lsl #24
-		mov	r4, r4, lsr #8
-		orr	r4, r4, r5, lsl #24
-		mov	r5, r5, lsr #8
-		orr	r5, r5, r6, lsl #24
-		mov	r6, r6, lsr #8
-		orr	r6, r6, r7, lsl #24
+		orr	r3, r3, r4, push #24
+		mov	r4, r4, pull #8
+		orr	r4, r4, r5, push #24
+		mov	r5, r5, pull #8
+		orr	r5, r5, r6, push #24
+		mov	r6, r6, pull #8
+		orr	r6, r6, r7, push #24
 		stmia	r0!, {r3 - r6}			@ Shouldnt fault
 		subs	ip, ip, #16
 		bpl	.c2u_1cpy8lp
 .c2u_1rem8lp:	tst	ip, #8
-		movne	r3, r7, lsr #8
+		movne	r3, r7, pull #8
 		ldmneia	r1!, {r4, r7}
-		orrne	r3, r3, r4, lsl #24
-		movne	r4, r4, lsr #8
-		orrne	r4, r4, r7, lsl #24
+		orrne	r3, r3, r4, push #24
+		movne	r4, r4, pull #8
+		orrne	r4, r4, r7, push #24
 		stmneia	r0!, {r3 - r4}			@ Shouldnt fault
 		tst	ip, #4
-		movne	r3, r7, lsr #8
+		movne	r3, r7, pull #8
 		ldrne	r7, [r1], #4
-		orrne	r3, r3, r7, lsl #24
+		orrne	r3, r3, r7, push #24
 		strnet	r3, [r0], #4			@ Shouldnt fault
 		ands	ip, ip, #3
 		beq	.c2u_1fupi
-.c2u_1nowords:	mov	r3, r7, lsr #8
+.c2u_1nowords:	mov	r3, r7, lsr #byte(1)
 		teq	ip, #0
 		beq	.c2u_finished
 		cmp	ip, #2
 USER(		strbt	r3, [r0], #1)			@ May fault
-		movge	r3, r3, lsr #8
+		movge	r3, r7, lsr #byte(2)
 USER(		strgebt	r3, [r0], #1)			@ May fault
-		movgt	r3, r3, lsr #8
+		movgt	r3, r7, lsr #byte(3)
 USER(		strgtbt	r3, [r0], #1)			@ May fault
 		b	.c2u_finished
 
 .c2u_2fupi:	subs	r2, r2, #4
 		addmi	ip, r2, #4
 		bmi	.c2u_2nowords
-		mov	r3, r7, lsr #16
+		mov	r3, r7, pull #16
 		ldr	r7, [r1], #4
-		orr	r3, r3, r7, lsl #16
+		orr	r3, r3, r7, push #16
 USER(		strt	r3, [r0], #4)			@ May fault
 		mov	ip, r0, lsl #32 - PAGE_SHIFT
 		rsb	ip, ip, #0
@@ -183,38 +183,38 @@
 		subs	ip, ip, #16
 		blt	.c2u_2rem8lp
 
-.c2u_2cpy8lp:	mov	r3, r7, lsr #16
+.c2u_2cpy8lp:	mov	r3, r7, pull #16
 		ldmia	r1!, {r4 - r7}
-		orr	r3, r3, r4, lsl #16
-		mov	r4, r4, lsr #16
-		orr	r4, r4, r5, lsl #16
-		mov	r5, r5, lsr #16
-		orr	r5, r5, r6, lsl #16
-		mov	r6, r6, lsr #16
-		orr	r6, r6, r7, lsl #16
+		orr	r3, r3, r4, push #16
+		mov	r4, r4, pull #16
+		orr	r4, r4, r5, push #16
+		mov	r5, r5, pull #16
+		orr	r5, r5, r6, push #16
+		mov	r6, r6, pull #16
+		orr	r6, r6, r7, push #16
 		stmia	r0!, {r3 - r6}			@ Shouldnt fault
 		subs	ip, ip, #16
 		bpl	.c2u_2cpy8lp
 .c2u_2rem8lp:	tst	ip, #8
-		movne	r3, r7, lsr #16
+		movne	r3, r7, pull #16
 		ldmneia	r1!, {r4, r7}
-		orrne	r3, r3, r4, lsl #16
-		movne	r4, r4, lsr #16
-		orrne	r4, r4, r7, lsl #16
+		orrne	r3, r3, r4, push #16
+		movne	r4, r4, pull #16
+		orrne	r4, r4, r7, push #16
 		stmneia	r0!, {r3 - r4}			@ Shouldnt fault
 		tst	ip, #4
-		movne	r3, r7, lsr #16
+		movne	r3, r7, pull #16
 		ldrne	r7, [r1], #4
-		orrne	r3, r3, r7, lsl #16
+		orrne	r3, r3, r7, push #16
 		strnet	r3, [r0], #4			@ Shouldnt fault
 		ands	ip, ip, #3
 		beq	.c2u_2fupi
-.c2u_2nowords:	mov	r3, r7, lsr #16
+.c2u_2nowords:	mov	r3, r7, lsr #byte(2)
 		teq	ip, #0
 		beq	.c2u_finished
 		cmp	ip, #2
 USER(		strbt	r3, [r0], #1)			@ May fault
-		movge	r3, r3, lsr #8
+		movge	r3, r7, lsr #byte(3)
 USER(		strgebt	r3, [r0], #1)			@ May fault
 		ldrgtb	r3, [r1], #0
 USER(		strgtbt	r3, [r0], #1)			@ May fault
@@ -223,9 +223,9 @@
 .c2u_3fupi:	subs	r2, r2, #4
 		addmi	ip, r2, #4
 		bmi	.c2u_3nowords
-		mov	r3, r7, lsr #24
+		mov	r3, r7, pull #24
 		ldr	r7, [r1], #4
-		orr	r3, r3, r7, lsl #8
+		orr	r3, r3, r7, push #8
 USER(		strt	r3, [r0], #4)			@ May fault
 		mov	ip, r0, lsl #32 - PAGE_SHIFT
 		rsb	ip, ip, #0
@@ -237,40 +237,40 @@
 		subs	ip, ip, #16
 		blt	.c2u_3rem8lp
 
-.c2u_3cpy8lp:	mov	r3, r7, lsr #24
+.c2u_3cpy8lp:	mov	r3, r7, pull #24
 		ldmia	r1!, {r4 - r7}
-		orr	r3, r3, r4, lsl #8
-		mov	r4, r4, lsr #24
-		orr	r4, r4, r5, lsl #8
-		mov	r5, r5, lsr #24
-		orr	r5, r5, r6, lsl #8
-		mov	r6, r6, lsr #24
-		orr	r6, r6, r7, lsl #8
+		orr	r3, r3, r4, push #8
+		mov	r4, r4, pull #24
+		orr	r4, r4, r5, push #8
+		mov	r5, r5, pull #24
+		orr	r5, r5, r6, push #8
+		mov	r6, r6, pull #24
+		orr	r6, r6, r7, push #8
 		stmia	r0!, {r3 - r6}			@ Shouldnt fault
 		subs	ip, ip, #16
 		bpl	.c2u_3cpy8lp
 .c2u_3rem8lp:	tst	ip, #8
-		movne	r3, r7, lsr #24
+		movne	r3, r7, pull #24
 		ldmneia	r1!, {r4, r7}
-		orrne	r3, r3, r4, lsl #8
-		movne	r4, r4, lsr #24
-		orrne	r4, r4, r7, lsl #8
+		orrne	r3, r3, r4, push #8
+		movne	r4, r4, pull #24
+		orrne	r4, r4, r7, push #8
 		stmneia	r0!, {r3 - r4}			@ Shouldnt fault
 		tst	ip, #4
-		movne	r3, r7, lsr #24
+		movne	r3, r7, pull #24
 		ldrne	r7, [r1], #4
-		orrne	r3, r3, r7, lsl #8
+		orrne	r3, r3, r7, push #8
 		strnet	r3, [r0], #4			@ Shouldnt fault
 		ands	ip, ip, #3
 		beq	.c2u_3fupi
-.c2u_3nowords:	mov	r3, r7, lsr #24
+.c2u_3nowords:	mov	r3, r7, lsr #byte(3)
 		teq	ip, #0
 		beq	.c2u_finished
 		cmp	ip, #2
 USER(		strbt	r3, [r0], #1)			@ May fault
-		ldrge	r3, [r1], #0
+		ldrgeb	r3, [r1], #1
 USER(		strgebt	r3, [r0], #1)			@ May fault
-		movgt	r3, r3, lsr #8
+		ldrgtb	r3, [r1], #0
 USER(		strgtbt	r3, [r0], #1)			@ May fault
 		b	.c2u_finished
 
@@ -374,9 +374,9 @@
 .cfu_1fupi:	subs	r2, r2, #4
 		addmi	ip, r2, #4
 		bmi	.cfu_1nowords
-		mov	r3, r7, lsr #8
+		mov	r3, r7, pull #8
 USER(		ldrt	r7, [r1], #4)			@ May fault
-		orr	r3, r3, r7, lsl #24
+		orr	r3, r3, r7, push #24
 		str	r3, [r0], #4
 		mov	ip, r1, lsl #32 - PAGE_SHIFT
 		rsb	ip, ip, #0
@@ -388,49 +388,49 @@
 		subs	ip, ip, #16
 		blt	.cfu_1rem8lp
 
-.cfu_1cpy8lp:	mov	r3, r7, lsr #8
+.cfu_1cpy8lp:	mov	r3, r7, pull #8
 		ldmia	r1!, {r4 - r7}			@ Shouldnt fault
-		orr	r3, r3, r4, lsl #24
-		mov	r4, r4, lsr #8
-		orr	r4, r4, r5, lsl #24
-		mov	r5, r5, lsr #8
-		orr	r5, r5, r6, lsl #24
-		mov	r6, r6, lsr #8
-		orr	r6, r6, r7, lsl #24
+		orr	r3, r3, r4, push #24
+		mov	r4, r4, pull #8
+		orr	r4, r4, r5, push #24
+		mov	r5, r5, pull #8
+		orr	r5, r5, r6, push #24
+		mov	r6, r6, pull #8
+		orr	r6, r6, r7, push #24
 		stmia	r0!, {r3 - r6}
 		subs	ip, ip, #16
 		bpl	.cfu_1cpy8lp
 .cfu_1rem8lp:	tst	ip, #8
-		movne	r3, r7, lsr #8
+		movne	r3, r7, pull #8
 		ldmneia	r1!, {r4, r7}			@ Shouldnt fault
-		orrne	r3, r3, r4, lsl #24
-		movne	r4, r4, lsr #8
-		orrne	r4, r4, r7, lsl #24
+		orrne	r3, r3, r4, push #24
+		movne	r4, r4, pull #8
+		orrne	r4, r4, r7, push #24
 		stmneia	r0!, {r3 - r4}
 		tst	ip, #4
-		movne	r3, r7, lsr #8
+		movne	r3, r7, pull #8
 USER(		ldrnet	r7, [r1], #4)			@ May fault
-		orrne	r3, r3, r7, lsl #24
+		orrne	r3, r3, r7, push #24
 		strne	r3, [r0], #4
 		ands	ip, ip, #3
 		beq	.cfu_1fupi
-.cfu_1nowords:	mov	r3, r7, lsr #8
+.cfu_1nowords:	mov	r3, r7, lsr #byte(1)
 		teq	ip, #0
 		beq	.cfu_finished
 		cmp	ip, #2
 		strb	r3, [r0], #1
-		movge	r3, r3, lsr #8
+		movge	r3, r7, lsr #byte(2)
 		strgeb	r3, [r0], #1
-		movgt	r3, r3, lsr #8
+		movgt	r3, r7, lsr #byte(3)
 		strgtb	r3, [r0], #1
 		b	.cfu_finished
 
 .cfu_2fupi:	subs	r2, r2, #4
 		addmi	ip, r2, #4
 		bmi	.cfu_2nowords
-		mov	r3, r7, lsr #16
+		mov	r3, r7, pull #16
 USER(		ldrt	r7, [r1], #4)			@ May fault
-		orr	r3, r3, r7, lsl #16
+		orr	r3, r3, r7, push #16
 		str	r3, [r0], #4
 		mov	ip, r1, lsl #32 - PAGE_SHIFT
 		rsb	ip, ip, #0
@@ -442,38 +442,38 @@
 		subs	ip, ip, #16
 		blt	.cfu_2rem8lp
 
-.cfu_2cpy8lp:	mov	r3, r7, lsr #16
+.cfu_2cpy8lp:	mov	r3, r7, pull #16
 		ldmia	r1!, {r4 - r7}			@ Shouldnt fault
-		orr	r3, r3, r4, lsl #16
-		mov	r4, r4, lsr #16
-		orr	r4, r4, r5, lsl #16
-		mov	r5, r5, lsr #16
-		orr	r5, r5, r6, lsl #16
-		mov	r6, r6, lsr #16
-		orr	r6, r6, r7, lsl #16
+		orr	r3, r3, r4, push #16
+		mov	r4, r4, pull #16
+		orr	r4, r4, r5, push #16
+		mov	r5, r5, pull #16
+		orr	r5, r5, r6, push #16
+		mov	r6, r6, pull #16
+		orr	r6, r6, r7, push #16
 		stmia	r0!, {r3 - r6}
 		subs	ip, ip, #16
 		bpl	.cfu_2cpy8lp
 .cfu_2rem8lp:	tst	ip, #8
-		movne	r3, r7, lsr #16
+		movne	r3, r7, pull #16
 		ldmneia	r1!, {r4, r7}			@ Shouldnt fault
-		orrne	r3, r3, r4, lsl #16
-		movne	r4, r4, lsr #16
-		orrne	r4, r4, r7, lsl #16
+		orrne	r3, r3, r4, push #16
+		movne	r4, r4, pull #16
+		orrne	r4, r4, r7, push #16
 		stmneia	r0!, {r3 - r4}
 		tst	ip, #4
-		movne	r3, r7, lsr #16
+		movne	r3, r7, pull #16
 USER(		ldrnet	r7, [r1], #4)			@ May fault
-		orrne	r3, r3, r7, lsl #16
+		orrne	r3, r3, r7, push #16
 		strne	r3, [r0], #4
 		ands	ip, ip, #3
 		beq	.cfu_2fupi
-.cfu_2nowords:	mov	r3, r7, lsr #16
+.cfu_2nowords:	mov	r3, r7, lsr #byte(2)
 		teq	ip, #0
 		beq	.cfu_finished
 		cmp	ip, #2
 		strb	r3, [r0], #1
-		movge	r3, r3, lsr #8
+		movge	r3, r7, lsr #byte(3)
 		strgeb	r3, [r0], #1
 USER(		ldrgtbt	r3, [r1], #0)			@ May fault
 		strgtb	r3, [r0], #1
@@ -482,9 +482,9 @@
 .cfu_3fupi:	subs	r2, r2, #4
 		addmi	ip, r2, #4
 		bmi	.cfu_3nowords
-		mov	r3, r7, lsr #24
+		mov	r3, r7, pull #24
 USER(		ldrt	r7, [r1], #4)			@ May fault
-		orr	r3, r3, r7, lsl #8
+		orr	r3, r3, r7, push #8
 		str	r3, [r0], #4
 		mov	ip, r1, lsl #32 - PAGE_SHIFT
 		rsb	ip, ip, #0
@@ -496,40 +496,40 @@
 		subs	ip, ip, #16
 		blt	.cfu_3rem8lp
 
-.cfu_3cpy8lp:	mov	r3, r7, lsr #24
+.cfu_3cpy8lp:	mov	r3, r7, pull #24
 		ldmia	r1!, {r4 - r7}			@ Shouldnt fault
-		orr	r3, r3, r4, lsl #8
-		mov	r4, r4, lsr #24
-		orr	r4, r4, r5, lsl #8
-		mov	r5, r5, lsr #24
-		orr	r5, r5, r6, lsl #8
-		mov	r6, r6, lsr #24
-		orr	r6, r6, r7, lsl #8
+		orr	r3, r3, r4, push #8
+		mov	r4, r4, pull #24
+		orr	r4, r4, r5, push #8
+		mov	r5, r5, pull #24
+		orr	r5, r5, r6, push #8
+		mov	r6, r6, pull #24
+		orr	r6, r6, r7, push #8
 		stmia	r0!, {r3 - r6}
 		subs	ip, ip, #16
 		bpl	.cfu_3cpy8lp
 .cfu_3rem8lp:	tst	ip, #8
-		movne	r3, r7, lsr #24
+		movne	r3, r7, pull #24
 		ldmneia	r1!, {r4, r7}			@ Shouldnt fault
-		orrne	r3, r3, r4, lsl #8
-		movne	r4, r4, lsr #24
-		orrne	r4, r4, r7, lsl #8
+		orrne	r3, r3, r4, push #8
+		movne	r4, r4, pull #24
+		orrne	r4, r4, r7, push #8
 		stmneia	r0!, {r3 - r4}
 		tst	ip, #4
-		movne	r3, r7, lsr #24
+		movne	r3, r7, pull #24
 USER(		ldrnet	r7, [r1], #4)			@ May fault
-		orrne	r3, r3, r7, lsl #8
+		orrne	r3, r3, r7, push #8
 		strne	r3, [r0], #4
 		ands	ip, ip, #3
 		beq	.cfu_3fupi
-.cfu_3nowords:	mov	r3, r7, lsr #24
+.cfu_3nowords:	mov	r3, r7, lsr #byte(3)
 		teq	ip, #0
 		beq	.cfu_finished
 		cmp	ip, #2
 		strb	r3, [r0], #1
-USER(		ldrget	r3, [r1], #0)			@ May fault
+USER(		ldrgebt	r3, [r1], #1)			@ May fault
 		strgeb	r3, [r0], #1
-		movgt	r3, r3, lsr #8
+USER(		ldrgtbt	r3, [r1], #1)			@ May fault
 		strgtb	r3, [r0], #1
 		b	.cfu_finished
 
diff -urN linux-2.4.29/arch/arm/mach-adifcc/arch.c linux-2.4.29-uc1/arch/arm/mach-adifcc/arch.c
--- linux-2.4.29/arch/arm/mach-adifcc/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-adifcc/arch.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,61 @@
+/*
+ *  linux/arch/arm/mach-adifcc/arch.c
+ *
+ *  Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+
+static void __init
+fixup_adi(struct machine_desc *desc, struct param_struct *params,
+	      char **cmdline, struct meminfo *mi)
+{
+	if(machine_is_adi_evb())
+	{
+		mi->bank[0].start = 0xc0000000;
+		mi->bank[0].size  = (32*1024*1024);
+		mi->bank[0].node  = 0;
+		mi->nr_banks      = 1;
+	} 
+}
+
+extern void adi_map_io(void);
+
+#ifdef CONFIG_ARCH_ADI_EVB
+extern void xs80200_init_irq(void);
+
+MACHINE_START(ADI_EVB, "ADI 80200EVB Evaluation Board")
+	MAINTAINER("MontaVista Software, Inc.")
+	BOOT_MEM(0xc0000000, 0x00400000, 0xff400000)
+	FIXUP(fixup_adi)
+	MAPIO(adi_map_io)
+	INITIRQ(xs80200_init_irq)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_BRH
+extern void brh_init_irq(void);
+
+MACHINE_START(BRH, "ADI BRH")
+	MAINTAINER("MontaVista Software, Inc.")
+	BOOT_MEM(0xc0000000, 0x03000000, 0xff000000)
+	BOOT_PARAMS(0xc0000100)
+	FIXUP(fixup_adi)
+	MAPIO(adi_map_io)
+	INITIRQ(brh_init_irq)
+MACHINE_END
+#endif
+
diff -urN linux-2.4.29/arch/arm/mach-adifcc/brh-abort.c linux-2.4.29-uc1/arch/arm/mach-adifcc/brh-abort.c
--- linux-2.4.29/arch/arm/mach-adifcc/brh-abort.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-adifcc/brh-abort.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,463 @@
+/*
+ * arch/arm/mach-adiff/brh-pci.c
+ *
+ * PCI routines for ADI BRH board
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2000-2001 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/pci.h>
+#include <asm/arch/pci_auto.h>
+#include <asm/arch/pci-bridge.h>
+
+extern int (*external_fault)(unsigned long, struct pt_regs *);
+static int brh_pci_abort_handler(unsigned long, struct pt_regs *);
+
+// #define DEBUG
+
+#ifdef DEBUG
+#define DBG(x...)	printk(x)
+#else
+#define DBG(x...)
+#endif /* DEBUG */
+
+static int max_devid = 3;
+
+static int __init slot_setup(char *str)
+{
+	max_devid = 3;
+}
+
+static int __init noslot_setup(char *str)
+{
+		max_devid = 2;
+}
+
+static int error_ocurred;
+
+
+static u32* 
+brh_pci_config_setup(struct pci_dev *dev, int where)
+{
+	u32 *paddress;
+
+	error_ocurred = 0;
+
+	/* Must be dword aligned */
+
+	where &= ~3;
+
+	/*
+	 * For top bus, generate type 0, else type 1
+	 */
+	if(!dev->bus->number)
+	{
+		if(PCI_SLOT(dev->devfn) > max_devid)
+			return NULL;
+
+		*BRH_PCI_CONFIG_CTRL = 0;
+		paddress = ((0xfb000000) | (1 << (PCI_SLOT(dev->devfn)+11)) |
+				(PCI_FUNC(dev->devfn) << 8) | where);
+	
+	}
+	else
+	{
+		*BRH_PCI_CONFIG_CTRL = 1;
+		paddress = ((0xfb000000) | (dev->bus->number << 16) |
+				(PCI_SLOT(dev->devfn) << 11) | 
+				(PCI_FUNC(dev->devfn) << 8) | where | 1);
+	}
+
+	DBG("brh_pci_config_setup(%d:%d:%d:%d) returning %#10x\n", 
+			dev->bus->number, PCI_SLOT(dev->devfn), 
+			PCI_FUNC(dev->devfn), where, paddress);
+
+	return paddress;
+}
+
+
+int do_clean();
+
+static int
+brh_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	u32 *address;
+
+	DBG("config_read_byte %d from dev %d:%d:%d\n", where, 
+			dev->bus->number, PCI_SLOT(dev->devfn),
+				PCI_FUNC(dev->devfn));
+
+	printk("config_read_byte %#04x from dev %d:%d:%d\n",
+			where, dev->bus->number, PCI_SLOT(dev->devfn),
+				PCI_FUNC(dev->devfn));
+
+	address = brh_pci_config_setup(dev, where);
+
+	if(!address)
+		*value = 0xff;
+	else
+	{
+		cli();
+		*value = (u8)(((*address) >> ((where % 0x04) * 8)) & 0xff);
+		if(error_ocurred) *value = 0xff;
+		asm("nop\nnop\nnop\n");
+		sti();
+	}
+
+
+	printk("config_read_byte read %#4x\n", *value);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+brh_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	u32 *address;
+
+	printk("config_read_word %d from dev %d:%d:%d\n", where, 
+			dev->bus->number, PCI_SLOT(dev->devfn),
+				PCI_FUNC(dev->devfn));
+
+	address = brh_pci_config_setup(dev, where);
+
+	if(!address)
+		*value = 0xffff;
+	else
+	{	
+		cli();
+		*value = (u16)(((*address) >> ((where % 0x04) *8)) & 0xffff);
+		asm("nop\nnop\nnop\n");
+		if(error_ocurred) *value = 0xffff;
+		sti();
+	}
+
+	printk("config_read_word read %#6x\n", *value);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+brh_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	u32 *address;
+
+	printk("config_read_dword %d from dev %d:%d:%d\n", where, 
+			dev->bus->number, PCI_SLOT(dev->devfn),
+				PCI_FUNC(dev->devfn));
+
+	address = brh_pci_config_setup(dev, where);
+
+	if(!address)
+		*value = 0xffffffff;
+	else
+	{
+		cli();
+		*value = *address;
+		asm("nop\nnop\nnop\n");
+		if(error_ocurred) *value = 0xffffffff;
+		sti();
+	}
+
+	printk("config_read_dword read %#10x\n", *value);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * We don't do error checking on the address for writes.
+ * It's assumed that the user checked for the device existing first
+ * by doing a read first.
+ */
+static int 
+brh_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	u32 *address;
+	u32 mask;
+	u32 temp;
+
+	address = brh_pci_config_setup(dev, where);
+
+	mask = ~(0x000000ff << ((where % 0x4) * 8));
+	temp = (u32)(((u32)value) << ((where % 0x4) *8));
+	*address = (*address & mask) | temp;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int 
+brh_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	u32 *address;
+	u32 mask;
+	u32 temp;
+
+	address = brh_pci_config_setup(dev, where);
+
+	mask = ~(0x0000ffff << ((where % 0x4) * 8));
+	temp = (u32)(((u32)value) << ((where % 0x4) * 8));
+	*address = (*address & mask) | temp;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+brh_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	u32 *address;
+
+	address = brh_pci_config_setup(dev, where);
+
+	*address = value;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+struct pci_ops brh_ops = {
+	brh_read_config_byte,
+	brh_read_config_word,
+	brh_read_config_dword,
+	brh_write_config_byte,
+	brh_write_config_word,
+	brh_write_config_dword,
+};
+
+static struct pci_controller *hose;
+
+int
+brh_pci_abort_handler(unsigned long addr, struct pt_regs *regs) 
+{
+	u16 status;
+//	*BRH_PCI_CONFIG_CTRL = 0;
+
+	printk("\n");
+	printk("DATA ABORT ON %#010x\n", addr);
+
+	brh_read_config_word(fake_pci_dev(hose, 0, 0), 
+				PCI_STATUS,
+				&status);
+
+	printk("BRH_PCI_MAST_INT: %#010x\n", *BRH_PCI_MAST_INT);
+	printk("PCI_CFG_STATUS: %#010x\n", status);
+	printk("INT STATUS: %#010x\n", *BRH_INT_STAT);
+
+	/*
+	 * Clear Mast. Abort line
+	 */
+	*BRH_PCI_MAST_INT |= 0x8;
+
+	status |= PCI_STATUS_REC_MASTER_ABORT;
+	brh_write_config_word(fake_pci_dev(hose, 0, 0), 
+				PCI_STATUS,
+				status);
+/*
+	brh_read_config_word(fake_pci_dev(hose, 0, 0), 
+				PCI_STATUS,
+				&status);
+
+
+	printk("BRH_PCI_MAST_INT: %#010x\n", *BRH_PCI_MAST_INT);
+	printk("PCI_CFG_STATUS After: %#010x\n", status);
+	printk("INT STATUS After: %#010x\n", *BRH_INT_STAT);
+	printk("\n");
+*/
+
+	error_ocurred = 1;
+	
+	return 0;
+}
+
+
+void __init
+brh_pci_init(void *sysdata)
+{
+	struct pci_bus *bus;
+	struct pci_dev *dev;
+
+	if(max_devid == 2)
+		printk("BRH PCI: Skipping PCI Slot\n");
+
+	DBG("Allocating hose\n");
+
+	hose = pcibios_alloc_controller();
+	if(!hose)
+		panic("Could not allocate PCI hose");
+
+	/*
+	 * Setup two outbound PCI mem ATUs to be 1:1 mapped
+	 * along with the I/O ATU.
+	 */
+#ifndef __ARMEB__
+	*BRH_PCI_MEM_ATU1 = (unsigned int)0x0c000000;
+	*BRH_PCI_MEM_ATU2 = (unsigned int)0x0e000000;
+	*BRH_PCI_IO_ATU   = (unsigned int)0x0a000000;
+#else
+	*BRH_PCI_MEM_ATU1 = (unsigned int)0x0c000004;
+	*BRH_PCI_MEM_ATU2 = (unsigned int)0x0e000004;
+	*BRH_PCI_IO_ATU   = (unsigned int)0x0a000004;
+#endif
+
+	hose->first_busno = 0;
+	hose->last_busno = 0;
+	hose->io_space.start = 0x0a000000;
+	hose->io_space.end = 0x0bffffff;
+	hose->mem_space.start = 0x0c000000;
+	hose->mem_space.end = 0x0fffffff;
+
+	/*
+	 * See page 22 of BECC spec. We need to write something to
+	 * one of the BECC PCI registers b4 performing an access.
+	 * Since autoconfig skips over the host bridge (as it should),
+	 * we manually configure it before running autoconf.
+	 *
+	 * We setup the two inbound windows to be contigous from
+	 * 0xc0000000 to 0xc3ffffff.  This allows for 1:1 mapping of
+	 * phys to bus addresses. We also need to setup the inbound
+	 * translation registers to force the 1:1 mapping.
+	 */
+	brh_write_config_dword(fake_pci_dev(hose, 0, 0), 
+			PCI_BASE_ADDRESS_0, 0xc0000000);
+#ifndef __ARMEB__
+	*BRH_PCI_MEM0_XLATE = 0x00000000;
+#else
+	*BRH_PCI_MEM0_XLATE = 0x00000001;
+#endif
+
+	brh_write_config_dword(fake_pci_dev(hose, 0, 0),
+			PCI_BASE_ADDRESS_1, 0xc2000000);
+#ifndef __ARMEB__
+	*BRH_PCI_MEM1_XLATE = 0x02000000;
+#else
+	*BRH_PCI_MEM1_XLATE = 0x02000001;
+#endif
+	
+	brh_write_config_word(fake_pci_dev(hose, 0, 0), PCI_COMMAND,
+			PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER);
+
+	DBG("Calling autoconfig\n");
+
+	external_fault = brh_pci_abort_handler;
+
+	/*
+	 * Autoconfig the bus 
+	 */
+	hose->last_busno = pciauto_bus_scan(hose, 0);
+
+	DBG("Scanning the bus\n");
+	/* Scan the bus */
+	bus = pci_scan_bus(0, &brh_ops, sysdata);
+}
+
+#define	INTA	IRQ_BRH_PCI_INT_A
+#define	INTB	IRQ_BRH_PCI_INT_B
+#define	INTC	IRQ_BRH_PCI_INT_C
+#define	INTD	IRQ_BRH_PCI_INT_D
+
+static int __init
+brh_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	const long min_idsel = 1, max_idsel = 3, irqs_per_slot = 4;
+
+	static char pci_irq_table[][4] =
+		{
+			/*
+			 * PCI IDSEL/INTPIN -> INTLINE
+			 */
+			{INTB, INTB, INTB, INTB},	/* Enet 0 */
+			{INTC, INTC, INTC, INTC},	/* Enet 1 */
+			{INTA, INTB, INTC, INTD},	/* PCI Slot */
+		};
+
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+
+#define EARLY_PCI_OP(rw, size, type)					\
+int early_##rw##_config_##size(struct pci_controller *hose, int bus,	\
+		int devfn, int offset, type value)	\
+{									\
+	return brh_##rw##_config_##size(fake_pci_dev(hose, bus, devfn),	\
+			offset, value);			\
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
+
+struct hw_pci brh_pci __initdata = {
+	init:		brh_pci_init,
+	swizzle:	common_swizzle,
+	map_irq:	brh_map_irq,
+};
+
+__setup("slot", slot_setup);
+__setup("noslot", noslot_setup);
+
+int
+do_clean() 
+{
+	u16 status;
+
+	return 0;
+	
+	brh_read_config_word(fake_pci_dev(hose, 0, 0), 
+				PCI_STATUS,
+				&status);
+
+
+	if(*BRH_PCI_MAST_INT & 0x8)
+	{	
+		printk("BRH_PCI_MAST_INT: %#010x\n", *BRH_PCI_MAST_INT);
+		printk("PCI_CFG_STATUS: %#010x\n", status);
+		printk("INT STATUS: %#010x\n", *BRH_INT_STAT);
+
+		/*
+	 	* Clear Mast. Abort line
+	 	*/
+		*BRH_PCI_MAST_INT |= 0x8;
+	
+		status |= PCI_STATUS_REC_MASTER_ABORT;
+		brh_write_config_word(fake_pci_dev(hose, 0, 0), 
+					PCI_STATUS,
+					status);
+#if 0
+		brh_read_config_word(fake_pci_dev(hose, 0, 0), 
+					PCI_STATUS,
+					&status);
+	
+	
+		printk("BRH_PCI_MAST_INT: %#010x\n", *BRH_PCI_MAST_INT);
+		printk("PCI_CFG_STATUS After: %#010x\n", status);
+		printk("INT STATUS After: %#010x\n", *BRH_INT_STAT);
+		printk("\n");
+#endif
+
+		return 1;
+	}
+
+	return 0;
+}
diff -urN linux-2.4.29/arch/arm/mach-adifcc/brh-irq.c linux-2.4.29-uc1/arch/arm/mach-adifcc/brh-irq.c
--- linux-2.4.29/arch/arm/mach-adifcc/brh-irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-adifcc/brh-irq.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,137 @@
+/*
+ * arch/arm/mach-adifcc/brh.h
+ *
+ * Interrupt code for ADI BRH board
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/bitops.h>
+
+#include <asm/mach/irq.h>
+
+extern void xs80200_init_irq(void);
+
+static void brh_irq_mask(unsigned int irq)
+{
+	long intmask = *(BRH_INT_MASK);
+	
+	intmask |= (1 << (irq - NR_XS80200_IRQS));
+
+	*(BRH_INT_MASK) = intmask;
+}
+
+static void brh_irq_unmask(unsigned int irq)
+{
+	long intmask = *(BRH_INT_MASK);
+
+	intmask &= ~(1 << (irq - NR_XS80200_IRQS));
+
+	*(BRH_INT_MASK) = intmask;
+}
+
+extern void do_IRQ(int, struct pt_regs *);
+
+static void brh_irq_demux(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u32 irq_stat = *(BRH_INT_STAT);
+	u32 irq_mask = *(BRH_INT_MASK);
+	int irqno = 0;
+
+	irq_stat &= ~irq_mask;
+
+	if(irq_stat & 0x00000001)
+		irqno = IRQ_BRH_SWI;
+	else if(irq_stat & 0x00000002)
+		irqno = IRQ_BRH_TIMERA;
+	else if(irq_stat & 0x00000004)
+		irqno = IRQ_BRH_TIMERB;
+	else if(irq_stat & 0x00000008)
+		irqno = IRQ_BRH_ERROR;
+	else if(irq_stat & 0x00000010)
+		irqno = IRQ_BRH_DMA_EOT;
+	else if(irq_stat & 0x00000020)
+		irqno = IRQ_BRH_DMA_PARITY;
+	else if(irq_stat & 0x00000040)
+		irqno = IRQ_BRH_DMA_TABORT;
+	else if(irq_stat & 0x00000080)
+		irqno = IRQ_BRH_DMA_MABORT;
+	else if(irq_stat & 0x00010000)
+		irqno = IRQ_BRH_PCI_PERR;
+	else if(irq_stat & 0x00080000)
+		irqno = IRQ_BRH_PCI_SERR;
+	else if(irq_stat & 0x00100000)
+		irqno = IRQ_BRH_ATU_PERR;
+	else if(irq_stat & 0x00200000)
+		irqno = IRQ_BRH_ATU_TABORT;
+	else if(irq_stat & 0x00400000)
+		irqno = IRQ_BRH_ATU_MABORT;
+	else if(irq_stat & 0x01000000)
+		irqno = IRQ_BRH_UART_A;
+	else if(irq_stat & 0x02000000)
+		irqno = IRQ_BRH_UART_B;
+	else if(irq_stat & 0x04000000)
+		irqno = IRQ_BRH_PCI_INT_A;
+	else if(irq_stat & 0x08000000)
+		irqno = IRQ_BRH_PCI_INT_B;
+	else if(irq_stat & 0x10000000)
+		irqno = IRQ_BRH_PCI_INT_C;
+	else if(irq_stat & 0x20000000)
+		irqno = IRQ_BRH_PCI_INT_D;
+	else if(irq_stat & 0x40000000)
+		irqno = IRQ_BRH_SOFT_RESET;
+
+	if(!irqno)
+		printk(KERN_ERR "Error: Spurious BRH interrupt\n");
+
+//	printk("brh_irq_demux called: %d\n", irqno);
+	do_IRQ(irqno, regs);
+}
+
+static struct irqaction brh_irq = {
+	name:	"BRH IRQ",
+	handler: brh_irq_demux,
+	flags: SA_INTERRUPT
+};
+
+extern int setup_arm_irq(int, struct irqaction *);
+
+void __init brh_init_irq(void)
+{
+	int i = 0;
+
+	/*
+	 * Route all sources to IRQ instead of FIQ
+	 * Mask all sources
+	 */
+	*(BRH_INT_STEERING) = 0;
+	*(BRH_INT_MASK) = 0xffffffff;
+
+	for(i = NR_XS80200_IRQS; i < NR_IRQS; i++)
+	{
+		irq_desc[i].valid 	= 1;
+		irq_desc[i].probe_ok	= 0;
+		irq_desc[i].mask_ack	= brh_irq_mask;
+		irq_desc[i].mask	= brh_irq_mask;
+		irq_desc[i].unmask	= brh_irq_unmask;
+	}
+
+	xs80200_init_irq();
+
+	setup_arm_irq(IRQ_XS80200_EXTIRQ, &brh_irq);
+}
diff -urN linux-2.4.29/arch/arm/mach-adifcc/brh-pci.c linux-2.4.29-uc1/arch/arm/mach-adifcc/brh-pci.c
--- linux-2.4.29/arch/arm/mach-adifcc/brh-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-adifcc/brh-pci.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,442 @@
+/*
+ * arch/arm/mach-adiff/brh-pci.c
+ *
+ * PCI routines for ADI BRH board
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2000-2001 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/pci.h>
+#include <asm/arch/pci_auto.h>
+#include <asm/arch/pci-bridge.h>
+
+extern int (*external_fault)(unsigned long, struct pt_regs *);
+static int brh_pci_abort_handler(unsigned long, unsigned long, struct pt_regs *);
+
+//#define DEBUG
+
+#ifdef DEBUG
+#define DBG(x...)	printk(x)
+#else
+#define DBG(x...)
+#endif /* DEBUG */
+
+/*
+ * Used to check on status of bad config cycles
+ */
+static int error_ocurred;
+
+static u32* 
+brh_pci_config_setup(struct pci_dev *dev, int where)
+{
+	u32 *paddress;
+
+	error_ocurred = 0;
+
+	/* Must be dword aligned */
+
+	where &= ~3;
+
+	/*
+	 * For top bus, generate type 0, else type 1
+	 */
+	if(!dev->bus->number)
+	{
+		if(PCI_SLOT(dev->devfn) > 3)
+			return NULL;
+
+		*BRH_PCI_CONFIG_CTRL = 0x00000000;
+
+		paddress = ((0xfb000000) | (1 << (PCI_SLOT(dev->devfn)+11)) |
+				(PCI_FUNC(dev->devfn) << 8) | where);
+	
+	}
+	else
+	{
+		*BRH_PCI_CONFIG_CTRL = 0x00000001;
+
+		paddress = ((0xfb000000) | (dev->bus->number << 16) |
+				(PCI_SLOT(dev->devfn) << 11) | 
+				(PCI_FUNC(dev->devfn) << 8) | where);
+	}
+
+
+	DBG("brh_pci_config_setup(%d:%d:%d:%d) returning %#10x\n", 
+			dev->bus->number, PCI_SLOT(dev->devfn), 
+			PCI_FUNC(dev->devfn), where, paddress);
+
+	return paddress;
+}
+
+
+static int
+brh_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	u32 *address;
+
+	DBG("config_read_byte %d from dev %d:%d:%d\n", where, 
+			dev->bus->number, PCI_SLOT(dev->devfn),
+				PCI_FUNC(dev->devfn));
+
+	address = brh_pci_config_setup(dev, where);
+
+	if(!address)
+		*value = 0xff;
+	else
+	{
+		cli();
+		*value = (u8)(((*address) >> ((where % 0x04) * 8)) & 0xff);
+		if(error_ocurred) *value = 0xff;
+		sti();
+	}
+
+
+	DBG("config_read_byte read %#4x\n", *value);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+brh_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	u32 *address;
+
+	DBG("config_read_word %d from dev %d:%d:%d\n", where, 
+			dev->bus->number, PCI_SLOT(dev->devfn),
+				PCI_FUNC(dev->devfn));
+
+	address = brh_pci_config_setup(dev, where);
+
+	if(!address)
+		*value = 0xffff;
+	else
+	{	
+		cli();
+		*value = (u16)(((*address) >> ((where % 0x04) *8)) & 0xffff);
+		if(error_ocurred) *value = 0xffff;
+		sti();
+	}
+
+	DBG("config_read_word read %#6x\n", *value);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+brh_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	u32 *address;
+
+	DBG("config_read_dword %d from dev %d:%d:%d\n", where, 
+			dev->bus->number, PCI_SLOT(dev->devfn),
+				PCI_FUNC(dev->devfn));
+
+	address = brh_pci_config_setup(dev, where);
+
+	if(!address)
+		*value = 0xffffffff;
+	else
+	{
+		cli();
+		*value = *address;
+		if(error_ocurred) *value = 0xffffffff;
+		sti();
+	}
+
+	DBG("config_read_dword read %#10x\n", *value);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * We don't do error checking on the address for writes.
+ * It's assumed that the user checked for the device existing first
+ * by doing a read first.
+ */
+static int 
+brh_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	u32 *address;
+	u32 mask;
+	u32 temp;
+
+	address = brh_pci_config_setup(dev, where);
+
+	mask = ~(0x000000ff << ((where % 0x4) * 8));
+	temp = (u32)(((u32)value) << ((where % 0x4) *8));
+	*address = (*address & mask) | temp;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int 
+brh_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	u32 *address;
+	u32 mask;
+	u32 temp;
+
+	address = brh_pci_config_setup(dev, where);
+
+	mask = ~(0x0000ffff << ((where % 0x4) * 8));
+	temp = (u32)(((u32)value) << ((where % 0x4) * 8));
+	*address = (*address & mask) | temp;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+brh_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	u32 *address;
+
+	address = brh_pci_config_setup(dev, where);
+
+	*address = value;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+struct pci_ops brh_ops = {
+	brh_read_config_byte,
+	brh_read_config_word,
+	brh_read_config_dword,
+	brh_write_config_byte,
+	brh_write_config_word,
+	brh_write_config_dword,
+};
+
+static struct pci_controller *hose;
+
+static int
+brh_pci_abort_handler(unsigned long addr, unsigned long fsr, struct pt_regs *regs) 
+{
+	u16 status;
+
+	DBG("\n");
+	DBG("DATA ABORT ON %#010x\n", addr);
+
+	brh_read_config_word(fake_pci_dev(hose, 0, 0), 
+				PCI_STATUS,
+				&status);
+
+	DBG("BRH_PCI_MAST_INT: %#010x\n", *BRH_PCI_MAST_INT);
+	DBG("PCI_CFG_STATUS: %#010x\n", status);
+	DBG("INT STATUS: %#010x\n", *BRH_INT_STAT);
+
+	/*
+	 * Clear Mast. Abort line
+	 */
+	*BRH_PCI_MAST_INT |= 0x8;
+
+	status |= PCI_STATUS_REC_MASTER_ABORT;
+	brh_write_config_word(fake_pci_dev(hose, 0, 0), 
+				PCI_STATUS,
+				status);
+
+	error_ocurred = 1;
+
+	/*
+	 * If it was an imprecise abort, then we need to correct the
+	 * return address to be _after_ the instruction.
+	 */
+	if (fsr & (1 << 10))
+		regs->ARM_pc += 4;
+	
+	return 0;
+}
+
+static struct resource brh_mem = {
+	name: "BRH PCI Non-Prefetch Memory Space",
+	start: 0x0c000000,
+	end:   0x0fffffff,
+	flags: IORESOURCE_MEM
+};
+
+static struct resource brh_io = {
+	name: "BRH PCI I/O Space",
+	start: 0x0a000000,
+	end:   0x0bffffff,
+	flags: IORESOURCE_IO
+};
+
+void brh_pci_setup_resources(struct resource **res)
+{
+	if(request_resource(&ioport_resource, &brh_io))
+		panic("COULD NOT REQUEST I/O");
+
+	if(request_resource(&iomem_resource, &brh_mem))
+		panic("COULD NOT REQUEST MEM");
+
+	res[0] = &brh_io;
+	res[1] = &brh_mem;
+	res[2] = NULL;
+}
+
+void __init
+brh_pci_init(void *sysdata)
+{
+	struct pci_bus *bus;
+	struct pci_dev *dev;
+	u8 rev_id;
+
+	DBG("Allocating hose\n");
+
+	hose = pcibios_alloc_controller();
+	if(!hose)
+		panic("Could not allocate PCI hose");
+
+	brh_read_config_byte(fake_pci_dev(hose, 0, 0), 
+			PCI_REVISION_ID, &rev_id);
+
+	printk("PCI: BRH Revision is %#04x\n", rev_id);
+
+	system_rev = rev_id;
+
+	/*
+	 * RedBoot enables the PCI unit, but the PCI config can't
+	 * be updated while PCI is enabled.
+	 */
+	brh_write_config_word(fake_pci_dev(hose, 0, 0), PCI_COMMAND, 0);
+
+
+	/*
+	 * Setup two outbound PCI mem ATUs to be 1:1 mapped
+	 * along with the I/O ATU.
+	 */
+#ifndef __ARMEB__
+	*BRH_PCI_MEM_ATU1 = (unsigned int)0x0c000000;
+	*BRH_PCI_MEM_ATU2 = (unsigned int)0x0e000000;
+	*BRH_PCI_IO_ATU   = (unsigned int)0x0a000000;
+#else
+	*BRH_PCI_MEM_ATU1 = (unsigned int)0x0c000004;
+	*BRH_PCI_MEM_ATU2 = (unsigned int)0x0e000004;
+	*BRH_PCI_IO_ATU   = (unsigned int)0x0a000004;
+#endif
+
+	hose->first_busno = 0;
+	hose->last_busno = 0;
+	hose->io_space.start = 0x0a000000;
+	hose->io_space.end = 0x0bffffff;
+	hose->mem_space.start = 0x0c000000;
+	hose->mem_space.end = 0x0fffffff;
+
+	/*
+	 *
+	 * We setup the two inbound windows to be contigous from
+	 * 0xc0000000 to 0xc3ffffff.  This allows for 1:1 mapping of
+	 * phys to bus addresses. We also need to setup the inbound
+	 * translation registers to force the 1:1 mapping.
+	 */
+	if(!system_rev) {
+		brh_write_config_dword(fake_pci_dev(hose, 0, 0), 
+			PCI_BASE_ADDRESS_0, 0xc0000000);
+#ifndef __ARMEB__
+		*BRH_PCI_MEM0_XLATE = 0x00000000;
+#else
+		*BRH_PCI_MEM0_XLATE = 0x00000001;
+#endif
+	} else {
+
+		/*
+		 * Disable the two 32M windows
+		 */
+		brh_write_config_dword(fake_pci_dev(hose, 0, 0), 
+			PCI_BASE_ADDRESS_0, 0x00000000);
+		brh_write_config_dword(fake_pci_dev(hose, 0, 0), 
+			PCI_BASE_ADDRESS_1, 0x00000000);
+
+		brh_write_config_dword(fake_pci_dev(hose, 0, 0), 
+			PCI_BASE_ADDRESS_2, 0xc0000000);
+
+#ifndef __ARMEB__
+		*BRH_PCI_MEM2_XLATE = 0x00000000;
+#else
+		*BRH_PCI_MEM2_XLATE = 0x00000001;
+#endif
+	}
+	
+	brh_write_config_word(fake_pci_dev(hose, 0, 0), PCI_COMMAND,
+			PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER);
+
+	DBG("Calling autoconfig\n");
+
+	external_fault = brh_pci_abort_handler;
+
+	/*
+	 * Autoconfig the bus 
+	 */
+	hose->last_busno = pciauto_bus_scan(hose, 0);
+
+	DBG("Scanning the bus\n");
+	/* Scan the bus */
+	bus = pci_scan_bus(0, &brh_ops, sysdata);
+}
+
+#define	INTA	IRQ_BRH_PCI_INT_A
+#define	INTB	IRQ_BRH_PCI_INT_B
+#define	INTC	IRQ_BRH_PCI_INT_C
+#define	INTD	IRQ_BRH_PCI_INT_D
+
+static int __init
+brh_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	const long min_idsel = 1, max_idsel = 3, irqs_per_slot = 4;
+
+	static char pci_irq_table[][4] =
+		{
+			/*
+			 * PCI IDSEL/INTPIN -> INTLINE
+			 */
+			{INTB, INTB, INTB, INTB},	/* Enet 0 */
+			{INTC, INTC, INTC, INTC},	/* Enet 1 */
+			{INTA, INTB, INTC, INTD},	/* PCI Slot */
+		};
+
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+
+#define EARLY_PCI_OP(rw, size, type)					\
+int early_##rw##_config_##size(struct pci_controller *hose, int bus,	\
+		int devfn, int offset, type value)	\
+{									\
+	return brh_##rw##_config_##size(fake_pci_dev(hose, bus, devfn),	\
+			offset, value);			\
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
+
+struct hw_pci brh_pci __initdata = {
+	init:		brh_pci_init,
+	swizzle:	common_swizzle,
+	map_irq:	brh_map_irq,
+	setup_resources: brh_pci_setup_resources
+};
+
diff -urN linux-2.4.29/arch/arm/mach-adifcc/brh-time.c linux-2.4.29-uc1/arch/arm/mach-adifcc/brh-time.c
--- linux-2.4.29/arch/arm/mach-adifcc/brh-time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-adifcc/brh-time.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,82 @@
+/*
+ * arch/arm/mach-adifcc/brh-time.c
+ *
+ * Timer code for BECC onboard timer
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#ifndef CONFG_XSCALE_PMU_TIMER
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/timex.h>
+#include <asm/hardware.h>
+
+#include <asm/mach-types.h>
+
+
+static unsigned long brh_gettimeoffset(void)
+{
+	unsigned long elapsed, usec;
+
+	/* Elapsed timer ticks since last IRQ */
+	elapsed = LATCH - (*BRH_TIMERA_VALUE);
+
+	/* Conver to usec */
+	usec = (unsigned long)(elapsed * tick) / LATCH;
+
+	return usec;
+}
+
+static void brh_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	*BRH_TIMERA_CTRL |= BRH_TIMER_INTERRUPT;
+
+	/*
+	 * Hack...see IQ80310 timer for reasoning
+	 */
+	irq_exit(smp_processor_id(), irq);
+//	printk("calling do_timer\n");
+	do_timer(regs);
+	irq_enter(smp_processor_id(), irq);
+}
+
+static struct irqaction timer_irq = {
+	name: "timer",
+};
+
+extern unsigned long (*gettimeoffset)(void);
+extern int setup_arm_irq(int, struct irqaction *);
+
+void __init setup_timer(void)
+{
+	gettimeoffset = brh_gettimeoffset;
+	timer_irq.handler = brh_timer_interrupt;
+	setup_arm_irq(IRQ_BRH_TIMERA, &timer_irq);
+
+	*BRH_TIMERA_CTRL = 0;
+	*BRH_TIMERA_PRELOAD = LATCH;
+	*BRH_TIMERA_CTRL = BRH_TIMER_ENABLE | BRH_TIMER_CONTINOUS;
+}
+
+#endif // !CONFIG_XSCALE_PMU_TIMER
diff -urN linux-2.4.29/arch/arm/mach-adifcc/Makefile linux-2.4.29-uc1/arch/arm/mach-adifcc/Makefile
--- linux-2.4.29/arch/arm/mach-adifcc/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-adifcc/Makefile	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,23 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= adifcc.o
+
+# Object file lists.
+
+obj-y			:= arch.o xs80200-irq.o mm.o
+obj-m			:= csum.o
+obj-n			:=
+obj-			:=
+
+export-objs		:=
+
+obj-$(CONFIG_ARCH_BRH)	+= brh-irq.o brh-pci.o pci.o pci-auto.o brh-time.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/arm/mach-adifcc/mm.c linux-2.4.29-uc1/arch/arm/mach-adifcc/mm.c
--- linux-2.4.29/arch/arm/mach-adifcc/mm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-adifcc/mm.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,41 @@
+/*
+ *  linux/arch/arm/mach-xscale/mm.c
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+ 
+#include <asm/mach/map.h>
+
+static struct map_desc adi_evb_io_desc[] __initdata = {
+ /* virtual    physical    length      domain     r  w  c  b */ 
+ /* On-board devices */
+ { 0xff400000, 0x00400000, 0x00300000, DOMAIN_IO, 0, 1, 0, 0 },  
+ LAST_DESC
+};
+
+static struct map_desc brh_io_desc[] __initdata = {
+ /* virtual    physical    length      domain     r  w  c  b  */ 
+ /* PCI Config Window */
+ { 0xfb000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 },
+ /* PCI I/O Window */
+ { 0xfd000000, 0x0a000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 },
+ /* On board devices - UART 0 & 1, LED */
+ { 0xff000000, 0x03000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 },
+ /* BECC Configurations Registers */
+ { 0xff400000, 0x04000000, 0x00010000, DOMAIN_IO, 0, 1, 0, 0 },
+ LAST_DESC
+};
+
+void __init adi_map_io(void)
+{
+	if(machine_is_adi_evb())	
+		iotable_init(adi_evb_io_desc);
+	else if(machine_is_brh())
+		iotable_init(brh_io_desc);
+}
diff -urN linux-2.4.29/arch/arm/mach-adifcc/pci-auto.c linux-2.4.29-uc1/arch/arm/mach-adifcc/pci-auto.c
--- linux-2.4.29/arch/arm/mach-adifcc/pci-auto.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-adifcc/pci-auto.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,379 @@
+/*
+ * arch/arm/mach-iop310/pci-auto.c
+ * 
+ * PCI autoconfiguration library
+ *
+ * Author: Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/arch/pci-bridge.h>
+#include <asm/arch/pci.h>
+#include <asm/arch/pci_auto.h>
+
+// #define DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif /* DEBUG */
+
+static int pciauto_upper_iospc;
+static int pciauto_upper_memspc;
+
+void pciauto_setup_bars(struct pci_controller *hose,
+		int current_bus,
+		int pci_devfn,
+		int bar_limit)
+{
+	int bar_response, bar_size, bar_value;
+	int bar, addr_mask, bar_nr = 0;
+	int * upper_limit;
+	int found_mem64 = 0;
+
+	DBG("PCI Autoconfig: Found Bus %d, Device %d, Function %d\n",
+		current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn) );
+
+	for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4)
+	{
+		/* Tickle the BAR and get the response */
+		early_write_config_dword(hose,
+				current_bus,
+				pci_devfn,
+				bar,
+				0xffffffff);
+		early_read_config_dword(hose,
+				current_bus,
+				pci_devfn,
+				bar,
+				&bar_response);
+
+		/* If BAR is not implemented go to the next BAR */
+		if (!bar_response)
+			continue;
+
+		/* Check the BAR type and set our address mask */
+		if (bar_response & PCI_BASE_ADDRESS_SPACE)
+		{
+			addr_mask = PCI_BASE_ADDRESS_IO_MASK;
+			upper_limit = &pciauto_upper_iospc;
+			DBG("PCI Autoconfig: BAR %d, I/O, ", bar_nr);
+		}
+		else
+		{
+			if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+			PCI_BASE_ADDRESS_MEM_TYPE_64)
+				found_mem64 = 1;
+
+			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;		
+			upper_limit = &pciauto_upper_memspc;
+			DBG("PCI Autoconfig: BAR %d, Mem, ", bar_nr);
+		}
+
+		/* Calculate requested size */
+		bar_size = ~(bar_response & addr_mask) + 1;
+
+		/* Allocate a base address */
+		bar_value = (*upper_limit - bar_size) & ~(bar_size - 1);
+
+		/* Write it out and update our limit */
+		early_write_config_dword(hose,
+				current_bus,
+				pci_devfn,
+				bar,
+				bar_value);
+
+		*upper_limit = bar_value;
+
+		/*
+		 * If we are a 64-bit decoder then increment to the
+		 * upper 32 bits of the bar and force it to locate
+		 * in the lower 4GB of memory.
+		 */ 
+		if (found_mem64)
+		{
+			bar += 4;
+			early_write_config_dword(hose,
+					current_bus,
+					pci_devfn,
+					bar,
+					0x00000000);
+		}
+
+		bar_nr++;
+
+		DBG("size=0x%x, address=0x%x\n",
+			bar_size, bar_value);
+	}
+
+}
+
+void pciauto_prescan_setup_bridge(struct pci_controller *hose,
+		int current_bus,
+		int pci_devfn,
+		int sub_bus,
+		int *iosave,
+		int *memsave)
+{
+	/* Configure bus number registers */
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_PRIMARY_BUS,
+			current_bus);
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_SECONDARY_BUS,
+			sub_bus + 1);
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_SUBORDINATE_BUS,
+			0xff);
+
+	/* Round memory allocator to 1MB boundary */
+	pciauto_upper_memspc &= ~(0x100000 - 1);
+	*memsave = pciauto_upper_memspc;
+
+	/* Round I/O allocator to 4KB boundary */
+	pciauto_upper_iospc &= ~(0x1000 - 1);
+	*iosave = pciauto_upper_iospc;
+
+	/* Set up memory and I/O filter limits, assume 32-bit I/O space */
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_MEMORY_LIMIT,
+			((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_LIMIT,
+			((pciauto_upper_iospc - 1) & 0x0000f000) >> 8);
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_LIMIT_UPPER16,
+			((pciauto_upper_iospc - 1) & 0xffff0000) >> 16);
+}
+
+void pciauto_postscan_setup_bridge(struct pci_controller *hose,
+		int current_bus,
+		int pci_devfn,
+		int sub_bus,
+		int *iosave,
+		int *memsave)
+{
+	int cmdstat;
+
+	/* Configure bus number registers */
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_SUBORDINATE_BUS,
+			sub_bus);
+
+	/*
+	 * Round memory allocator to 1MB boundary.
+	 * If no space used, allocate minimum.
+	 */
+	pciauto_upper_memspc &= ~(0x100000 - 1);
+	if (*memsave == pciauto_upper_memspc)
+		pciauto_upper_memspc -= 0x00100000;
+
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_MEMORY_BASE,
+			pciauto_upper_memspc >> 16);
+
+	/* Allocate 1MB for pre-fretch */
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_PREF_MEMORY_LIMIT,
+			((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
+
+	pciauto_upper_memspc -= 0x100000;
+
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_PREF_MEMORY_BASE,
+			pciauto_upper_memspc >> 16);
+
+	/* Round I/O allocator to 4KB boundary */
+	pciauto_upper_iospc &= ~(0x1000 - 1);
+	if (*iosave == pciauto_upper_iospc)
+		pciauto_upper_iospc -= 0x1000;
+
+	DBG("PCI Autoconfig: Bridge %d. IO_FILTER = %#010x..%#010x\n",
+			current_bus, 
+			(pciauto_upper_iospc & 0x0000f000) >> 8,
+			pciauto_upper_iospc >> 16);
+
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_BASE,
+			(pciauto_upper_iospc & 0x0000f000) >> 8);
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_BASE_UPPER16,
+			pciauto_upper_iospc >> 16);
+	
+	/* Enable memory and I/O accesses, enable bus master */
+	early_read_config_dword(hose,
+			current_bus,
+			pci_devfn,
+			PCI_COMMAND,
+			&cmdstat);
+	early_write_config_dword(hose,
+			current_bus,
+			pci_devfn,
+			PCI_COMMAND,
+			cmdstat |
+			PCI_COMMAND_IO |
+			PCI_COMMAND_MEMORY |
+			PCI_COMMAND_MASTER);
+}
+
+int pciauto_bus_scan(struct pci_controller *hose, int current_bus)
+{
+	int sub_bus, pci_devfn, pci_class, cmdstat, found_multi=0;
+	unsigned short vid;
+	unsigned char header_type;
+
+	/*
+	 * Fetch our I/O and memory space upper boundaries used
+	 * to allocated base addresses on this hose.
+	 */
+	if (current_bus == hose->first_busno)
+	{
+		pciauto_upper_iospc = hose->io_space.end + 1;
+		pciauto_upper_memspc = hose->mem_space.end + 1;
+	}
+
+	sub_bus = current_bus;
+
+	for (pci_devfn=0; pci_devfn<0xff; pci_devfn++)
+	{
+		/* Skip our host bridge */
+		if ( (current_bus == hose->first_busno) && (pci_devfn == 0) )
+			continue;
+
+		if (PCI_FUNC(pci_devfn) && !found_multi)
+			continue;
+
+		/* If config space read fails from this device, move on */
+		if (early_read_config_byte(hose,
+				current_bus,
+				pci_devfn,
+				PCI_HEADER_TYPE,
+				&header_type))
+			continue;
+
+		if (!PCI_FUNC(pci_devfn))
+			found_multi = header_type & 0x80;
+
+		early_read_config_word(hose,
+				current_bus,
+				pci_devfn,
+				PCI_VENDOR_ID,
+				&vid);
+
+		if (vid != 0xffff)
+		{
+			early_read_config_dword(hose,
+					current_bus,
+					pci_devfn,
+					PCI_CLASS_REVISION, &pci_class);
+			if ( (pci_class >> 16) == PCI_CLASS_BRIDGE_PCI )
+			{
+				int iosave, memsave;
+
+				DBG("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_SLOT(pci_devfn));
+				/* Allocate PCI I/O and/or memory space */
+				pciauto_setup_bars(hose,
+						current_bus,
+						pci_devfn,
+						PCI_BASE_ADDRESS_1);
+
+				pciauto_prescan_setup_bridge(hose,
+						current_bus,
+						pci_devfn,
+						sub_bus,
+						&iosave,
+						&memsave);
+				sub_bus = pciauto_bus_scan(hose, sub_bus+1);
+				pciauto_postscan_setup_bridge(hose,
+						current_bus,
+						pci_devfn,
+						sub_bus,
+						&iosave,
+						&memsave);
+			}
+			else
+			{
+				if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE)
+				{
+					unsigned char prg_iface;
+
+					early_read_config_byte(hose,
+							current_bus,
+							pci_devfn,
+							PCI_CLASS_PROG,
+							&prg_iface);
+					if (!(prg_iface & PCIAUTO_IDE_MODE_MASK))
+					{
+						DBG("PCI Autoconfig: Skipping legacy mode IDE controller\n");
+						continue;
+					}
+				}
+
+				/*
+				 * Found a peripheral, enable some standard
+				 * settings
+				 */
+				early_read_config_dword(hose,
+						current_bus,
+						pci_devfn,
+						PCI_COMMAND,
+						&cmdstat);
+				early_write_config_dword(hose,
+						current_bus,
+						pci_devfn,
+						PCI_COMMAND,
+						cmdstat |
+						PCI_COMMAND_IO |
+						PCI_COMMAND_MEMORY |
+						PCI_COMMAND_MASTER);
+				early_write_config_byte(hose,
+						current_bus,
+						pci_devfn,
+						PCI_LATENCY_TIMER,
+						0x80);
+
+				/* Allocate PCI I/O and/or memory space */
+				pciauto_setup_bars(hose,
+						current_bus,
+						pci_devfn,
+						PCI_BASE_ADDRESS_5);
+			}
+		}
+	}
+	return sub_bus;
+}
diff -urN linux-2.4.29/arch/arm/mach-adifcc/pci.c linux-2.4.29-uc1/arch/arm/mach-adifcc/pci.c
--- linux-2.4.29/arch/arm/mach-adifcc/pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-adifcc/pci.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,250 @@
+/*
+ * arch/arm/mach-iop310/pci.c
+ *
+ * Generic PCI support functionality that should eventually move to
+ * arch/arm/kernel/bios32.c.  Derived from support in ppc and alpha.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/pci-bridge.h>
+
+#define DEBUG 
+
+#ifdef DEBUG
+#define  DBG(x...) printk(x)
+#else
+#define  DBG(x...)
+#endif
+
+struct pci_controller* hose_head;
+struct pci_controller** hose_tail = &hose_head;
+
+/*
+ * The following code swizzles for exactly one bridge.  The routine
+ * common_swizzle below handles multiple bridges.  But there are a
+ * some boards that don't follow the PCI spec's suggestion so we
+ * break this piece out separately.
+ */
+static inline u8
+bridge_swizzle(u8 pin, u8 slot)
+{
+	return (((pin-1) + slot) % 4) + 1;
+}
+
+u8 __init
+common_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	struct pci_controller *hose;
+	
+	hose = pci_bus_to_hose(dev->bus->number);
+
+	if (dev->bus->number != hose->first_busno) {
+		u8 pin = *pinp;
+		do {
+			pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+			/* Move up the chain of bridges. */
+			dev = dev->bus->self;
+		} while (dev->bus->self);
+		*pinp = pin;
+
+		/* The slot is the slot of the last bridge. */
+	}
+
+	return PCI_SLOT(dev->devfn);
+}
+
+/*
+ * Null PCI config access functions, for the case when we can't
+ * find a hose.
+ */
+#define NULL_PCI_OP(rw, size, type)					\
+static int								\
+null_##rw##_config_##size(struct pci_dev *dev, int offset, type val)	\
+{									\
+	return PCIBIOS_DEVICE_NOT_FOUND;    				\
+}
+
+	NULL_PCI_OP(read, byte, u8 *)
+	NULL_PCI_OP(read, word, u16 *)
+	NULL_PCI_OP(read, dword, u32 *)
+	NULL_PCI_OP(write, byte, u8)
+	NULL_PCI_OP(write, word, u16)
+NULL_PCI_OP(write, dword, u32)
+
+static struct pci_ops null_pci_ops =
+{
+	null_read_config_byte,
+	null_read_config_word,
+	null_read_config_dword,
+	null_write_config_byte,
+	null_write_config_word,
+	null_write_config_dword
+};
+
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+struct pci_dev *
+fake_pci_dev(struct pci_controller *hose, int busnr, int devfn)
+{
+	static struct pci_dev dev;
+	static struct pci_bus bus;
+
+	if (hose == 0) {
+		hose = pci_bus_to_hose(busnr);
+		if (hose == 0)
+			printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);
+	}
+	dev.bus = &bus;
+	dev.sysdata = hose;
+	dev.devfn = devfn;
+	bus.number = busnr;
+	bus.ops = hose? hose->ops: &null_pci_ops;
+	return &dev;
+}
+
+static int next_controller_index;
+
+struct pci_controller * __init
+pcibios_alloc_controller(void)
+{
+	struct pci_controller *hose;
+
+	hose = (struct pci_controller *)kmalloc(sizeof(*hose), GFP_KERNEL);
+	memset(hose, 0, sizeof(struct pci_controller));
+	
+	*hose_tail = hose;
+	hose_tail = &hose->next;
+
+	hose->index = next_controller_index++;
+
+	return hose;
+}
+	
+struct pci_controller *
+pci_bus_to_hose(int bus)
+{
+	struct pci_controller *hose = hose_head;
+
+	for (; hose; hose = hose->next)
+		if (bus >= hose->first_busno && bus <= hose->last_busno)
+			return hose;
+	return NULL;
+}
+
+void __init
+pci_exclude_device(unsigned char bus, unsigned char devfn)
+{
+	struct pci_dev *dev, *pdev = NULL;
+
+	/* Walk the pci device list */
+	pci_for_each_dev(dev)
+	{
+		if ((dev->bus->number == bus) && (dev->devfn == devfn))
+		{
+			/*
+			 * Remove the device from the global and
+			 * bus lists.
+			 */
+			list_del(&(dev->global_list));
+			list_del(&(dev->bus_list));
+
+			/* Free the pci_dev structure */
+			kfree(dev);
+
+			break;
+		}
+		pdev = dev;
+	}
+}
+
+static inline void __init alloc_resource(struct pci_dev *dev, int idx)
+{
+	struct resource *pr, *r = &dev->resource[idx];
+
+	pr = pci_find_parent_resource(dev, r);
+	if(!pr || request_resource(pr, r) < 0)
+	{
+		printk(KERN_ERR "PCI: Can not allocate resource region %d" \
+				" of device %s\n", idx, dev->slot_name);
+		r->end -= r->start;
+		r->start = 0;
+	}
+}
+
+void __init
+pcibios_allocate_bus_resources(struct list_head *bus_list)
+{
+	struct list_head *ln;
+	struct pci_bus *bus;
+	int i;
+	struct resource *res, *pr;
+
+	if(!bus_list) return; 
+
+	/* Depth-First Search on bus tree */
+	for (ln = bus_list->next; ln != bus_list; ln=ln->next) {
+		bus = pci_bus_b(ln);
+		pci_read_bridge_bases(bus);
+		for (i = 0; i < 4; ++i) {
+			if ((res = bus->resource[i]) == NULL || !res->flags)
+				continue;
+			if (bus->parent == NULL)
+				pr = (res->flags & IORESOURCE_IO)?
+					&ioport_resource: &iomem_resource;
+			else
+				pr = pci_find_parent_resource(bus->self, res);
+
+			if (pr && request_resource(pr, res) == 0)
+				continue;
+			printk(KERN_ERR "PCI: Can not allocate resource region "
+			       "%d of PCI bridge %d\n", i, bus->number);
+			DBG("PCI: resource is %lx..%lx (%lx)\n",
+					res->start, res->end, res->flags);
+		}
+		pcibios_allocate_bus_resources(&bus->children);
+	}
+}
+
+void __init pcibios_allocate_resources(void)
+{
+	struct pci_dev *dev;
+	int idx, disabled;
+	u16 command;
+	struct resource *r;
+
+	pci_for_each_dev(dev)
+	{
+		pci_read_config_word(dev, PCI_COMMAND, &command);
+		for(idx = 0; idx < 6; idx++)
+		{
+			r = &dev->resource[idx];
+
+			if(r->parent)
+				continue;
+			if(!r->start)
+				continue;
+
+			alloc_resource(dev, idx);
+		}
+	}
+}
+
+
diff -urN linux-2.4.29/arch/arm/mach-adifcc/xs80200-irq.c linux-2.4.29-uc1/arch/arm/mach-adifcc/xs80200-irq.c
--- linux-2.4.29/arch/arm/mach-adifcc/xs80200-irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-adifcc/xs80200-irq.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,68 @@
+/*
+ * linux/arch/arm/mach-adifcc/irq.c
+ * 
+ * Author:  Deepak Saxena
+ * Copyright:   (C) 2001 MontaVista Software Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+
+#include <asm/mach-types.h>
+
+void xs80200_irq_mask (unsigned int irq)
+{
+	long INTCTL;
+	asm ("mrc p13, 0, %0, c0, c0, 0" : "=r" (INTCTL));
+	switch (irq) {
+	    case IRQ_XS80200_BCU:     INTCTL &= ~(1<<3); break;
+	    case IRQ_XS80200_PMU:     INTCTL &= ~(1<<2); break;
+	    case IRQ_XS80200_EXTIRQ:  INTCTL &= ~(1<<1); break;
+	    case IRQ_XS80200_EXTFIQ:  INTCTL &= ~(1<<0); break;
+	}
+	asm ("mcr p13, 0, %0, c0, c0, 0" : : "r" (INTCTL));
+}
+
+void xs80200_irq_unmask (unsigned int irq)
+{
+	long INTCTL;
+	asm ("mrc p13, 0, %0, c0, c0, 0" : "=r" (INTCTL));
+	switch (irq) {
+	    case IRQ_XS80200_BCU:	INTCTL |= (1<<3); break;
+	    case IRQ_XS80200_PMU:	INTCTL |= (1<<2); break;
+	    case IRQ_XS80200_EXTIRQ:	INTCTL |= (1<<1); break;
+	    case IRQ_XS80200_EXTFIQ:	INTCTL |= (1<<0); break;
+	}
+	asm ("mcr p13, 0, %0, c0, c0, 0" : : "r" (INTCTL));
+}
+
+void __init xs80200_init_irq(void)
+{
+	int i;
+	unsigned long int_steer = 0x0;
+
+	/*
+	 * Steer interrupts to IRQ instead of FIQ
+	 */
+	asm ("mcr p13, 0, %0, c8, c0, 0" : : "r" (int_steer));
+
+	for (i = 0; i < NR_XS80200_IRQS; i++) {
+		irq_desc[i].valid	= 1;
+		irq_desc[i].probe_ok	= 0;
+		irq_desc[i].mask_ack	= xs80200_irq_mask;
+		irq_desc[i].mask	= xs80200_irq_mask;
+		irq_desc[i].unmask	= xs80200_irq_unmask;
+	}
+}
+
diff -urN linux-2.4.29/arch/arm/mach-at91rm9200/Makefile linux-2.4.29-uc1/arch/arm/mach-at91rm9200/Makefile
--- linux-2.4.29/arch/arm/mach-at91rm9200/Makefile	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-at91rm9200/Makefile	2005-06-14 02:10:59.000000000 +0100
@@ -18,4 +18,8 @@
 
 export-objs		:=
 
+# LEDs support
+leds-$(CONFIG_ARCH_AT91RM9200DK) += dk-leds.o
+obj-$(CONFIG_LEDS) += $(leds-y)
+
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/arm/mach-clps711x/edb7312.c linux-2.4.29-uc1/arch/arm/mach-clps711x/edb7312.c
--- linux-2.4.29/arch/arm/mach-clps711x/edb7312.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-clps711x/edb7312.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,108 @@
+/*
+ *  linux/arch/arm/mach-clps711x/edb7312.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it 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 <linux/config.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/setup.h>
+#include <asm/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/clps7111.h>
+#include <asm/io.h>
+ 
+extern void clps711x_init_irq(void);
+extern void clps711x_map_io(void); 
+
+#define MB1 1048576	/* one megabyte == size of an MMU section */
+
+/*
+ * The on-chip registers are given a size of 1MB so that a section can
+ * be used to map them; this saves a page table.  This is the place to
+ * add mappings for ROM, expansion memory, PCMCIA, etc.  (if static
+ * mappings are chosen for those areas).
+ *
+ * Here is a physical memory map (to be fleshed out later):
+ *
+ * Physical Address  Size  Description
+ * ----------------- ----- ---------------------------------
+ * c0000000-c001ffff 128KB reserved for video RAM [1]
+ * c0020000-c0023fff  16KB parameters (see Documentation/arm/Setup)
+ * c0024000-c0027fff  16KB swapper_pg_dir (task 0 page directory)
+ * c0028000-...            kernel image (TEXTADDR)
+ *
+ * [1] Unused pages should be given back to the VM; they are not yet.
+ *     The parameter block should also be released (not sure if this
+ *     happens).
+ */
+static struct map_desc edb7312_io_desc[] __initdata = {
+ /* virtual, physical, length, domain, r, w, c, b */
+
+ /* FLASH is 16 MB */
+ { EP7312_VIRT_CS0, CS0_PHYS_BASE, MB1 * 16, DOMAIN_IO, 0, 1, 0, 0 }, 
+ { EP7312_VIRT_CS1, CS1_PHYS_BASE, MB1, DOMAIN_IO, 0, 1, 0, 0 },
+ { EP7312_VIRT_CS2, CS2_PHYS_BASE, MB1, DOMAIN_IO, 0, 1, 0, 0 },
+ { EP7312_VIRT_CS3, CS3_PHYS_BASE, MB1, DOMAIN_IO, 0, 1, 0, 0 },
+ { EP7312_VIRT_CS4, CS4_PHYS_BASE, MB1, DOMAIN_IO, 0, 1, 0, 0 },
+ { EP7312_VIRT_CS5, CS5_PHYS_BASE, MB1, DOMAIN_IO, 0, 1, 0, 0 },
+ { EP7312_VIRT_CS6, CS6_PHYS_BASE, MB1, DOMAIN_IO, 0, 1, 0, 0 },
+ { EP7312_VIRT_CS7, CS7_PHYS_BASE, MB1, DOMAIN_IO, 0, 1, 0, 0 },
+
+ LAST_DESC
+};
+
+
+void __init edb7312_map_io(void)
+{
+        clps711x_map_io();
+        iotable_init(edb7312_io_desc);
+
+	/* set wait states and nCSx widths (IDE is default 16-bit) */
+	clps_writel(0x1F101710, MEMCFG1);
+	clps_writel(0x00001C03, MEMCFG2);
+
+	/* set EXCKEN = 1 */
+	clps_writel(clps_readl(SYSCON1) | 0x00040000, SYSCON1);
+#if 1
+	/* set PIO mode 3 timing - 180ns per access */
+	__raw_writeb (0, EDB7312_VIRT_IDE + 0x00010000);
+#endif
+
+	/* clear eventual "suspend change" interrupt */
+	__raw_writeb(0xF4, EDB7312_VIRT_PDIUSBD12 + 1);
+	__raw_readb(EP7312_VIRT_CS3 + 0x0004);
+	__raw_readb(EP7312_VIRT_CS3 + 0x0004);
+	__raw_readb(EDB7312_VIRT_PDIUSBD12 + 0);
+	__raw_readb(EP7312_VIRT_CS3 + 0x0004);
+	__raw_readb(EP7312_VIRT_CS3 + 0x0004);
+	__raw_readb(EDB7312_VIRT_PDIUSBD12 + 0);
+}
+
+MACHINE_START(EDB7312, "EDB7312")
+	MAINTAINER("Nucleus Systems, Ltd.")
+        BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
+	BOOT_PARAMS(0xc0030000)
+	MAPIO(edb7312_map_io)
+	INITIRQ(clps711x_init_irq)
+MACHINE_END
diff -urN linux-2.4.29/arch/arm/mach-clps711x/irq.c linux-2.4.29-uc1/arch/arm/mach-clps711x/irq.c
--- linux-2.4.29/arch/arm/mach-clps711x/irq.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-clps711x/irq.c	2005-06-14 02:10:59.000000000 +0100
@@ -96,6 +96,20 @@
 	clps_writel(intmr2, INTMR2);
 }
 
+void edb7312_enable_eint1(void)
+{
+	static int iCount = 0;
+
+	/*
+	 * Enable EINT1 after two enables (keyboard and USB).
+	 */
+	iCount++;
+	if(iCount == 2) {
+		irq_desc[IRQ_EINT1].disable_depth = 0;
+		irq_desc[IRQ_EINT1].unmask(IRQ_EINT1);
+	}
+}
+
 void __init clps711x_init_irq(void)
 {
 	unsigned int i;
@@ -122,6 +136,11 @@
 	}
 
 	/*
+	 * Disable auto-enable for the external interrupt 1.
+	 */
+	irq_desc[IRQ_EINT1].noautoenable = 1;
+
+	/*
 	 * Disable interrupts
 	 */
 	clps_writel(0, INTMR1);
@@ -138,4 +157,6 @@
 	clps_writel(0, UMSEOI);
 	clps_writel(0, SYNCIO);
 	clps_writel(0, KBDEOI);
+	
+	//init_FIQ();
 }
diff -urN linux-2.4.29/arch/arm/mach-clps711x/kgdb-serial.c linux-2.4.29-uc1/arch/arm/mach-clps711x/kgdb-serial.c
--- linux-2.4.29/arch/arm/mach-clps711x/kgdb-serial.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-clps711x/kgdb-serial.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,66 @@
+/*
+ * tiny serial helper routines for kgdb
+ *
+ *	(C) Copyright 2003 Nucleus Systems, Ltd. <petkan@nucleusys.com>
+ *	
+ *	Based on George G. Davis <gdavis@mvista.com> work.
+ */
+
+#include <linux/config.h>
+#include <asm/io.h>
+#include <asm/hardware/clps7111.h>
+
+
+
+
+#if defined(CONFIG_KGDB_UART0)
+#define KGDB_UART	UARTDR1
+#define KGDB_SYSFLG	SYSFLG1
+#define	KGDB_SYSCON	SYSCON1
+#define	KGDB_UBRLCR	UBRLCR1
+#elif defined(CONFIG_KGDB_UART1)
+#define KGDB_UART	UARTDR2
+#define	KGDB_SYSFLG	SYSFLG2
+#define	KGDB_SYSCON	SYSCON2
+#define	KGDB_UBRLCR	UBRLCR2
+#else
+#error "No kgdb serial port UART has been selected."
+#endif
+
+
+#if defined(CONFIG_KGDB_9600BAUD)
+#define  KGDB_SERIAL_BAUD_RATE   23
+#elif defined(CONFIG_KGDB_19200BAUD)
+#define  KGDB_SERIAL_BAUD_RATE   11
+#elif defined(CONFIG_KGDB_38400BAUD)
+#define  KGDB_SERIAL_BAUD_RATE   5
+#elif defined(CONFIG_KGDB_57600BAUD)
+#define  KGDB_SERIAL_BAUD_RATE   3
+#elif defined(CONFIG_KGDB_115200BAUD)
+#define  KGDB_SERIAL_BAUD_RATE   1
+#else
+#error "kgdb serial baud rate has not been specified."
+#endif
+
+#define	KGDB_UART_CFG	(0x70000 | KGDB_SERIAL_BAUD_RATE)
+
+
+void kgdb_serial_init(void)
+{
+	clps_writel(clps_readl(KGDB_SYSCON) | 0x100, KGDB_SYSCON);
+	clps_writel(0x70001, KGDB_UBRLCR);
+	printk("syscon and ubrlcr are: %08x and %08x\n",
+	       clps_readl(KGDB_SYSCON), clps_readl(KGDB_UBRLCR));
+}
+
+void kgdb_serial_putchar(unsigned char ch)
+{
+	while (clps_readl(KGDB_SYSFLG) & 0x00800000);
+	clps_writeb(ch, KGDB_UART);
+}
+
+unsigned char kgdb_serial_getchar(void)
+{
+	while (clps_readl(KGDB_SYSFLG) & 0x00400000);
+	return clps_readb(KGDB_UART);
+}
diff -urN linux-2.4.29/arch/arm/mach-clps711x/Makefile linux-2.4.29-uc1/arch/arm/mach-clps711x/Makefile
--- linux-2.4.29/arch/arm/mach-clps711x/Makefile	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-clps711x/Makefile	2005-06-14 02:10:59.000000000 +0100
@@ -22,10 +22,12 @@
 obj-$(CONFIG_ARCH_CDB89712) += cdb89712.o
 obj-$(CONFIG_ARCH_CLEP7312) += clep7312.o
 obj-$(CONFIG_ARCH_EDB7211) += edb7211-arch.o edb7211-mm.o
+obj-$(CONFIG_ARCH_EDB7312) += edb7312.o
 obj-$(CONFIG_ARCH_GUIDEA07) += guide-a07.o
 obj-$(CONFIG_ARCH_P720T) += p720t.o
 obj-$(CONFIG_ARCH_FORTUNET) += fortunet.o
 leds-$(CONFIG_ARCH_P720T) += p720t-leds.o
 obj-$(CONFIG_LEDS)	+= $(leds-y)
+obj-$(CONFIG_KGDB_SERIAL) += kgdb-serial.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/arm/mach-ep93xx/arch.c linux-2.4.29-uc1/arch/arm/mach-ep93xx/arch.c
--- linux-2.4.29/arch/arm/mach-ep93xx/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ep93xx/arch.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,151 @@
+/*
+ *  linux/arch/arm/mach-ep93xx/arch.c
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ * (c) Copyright 2002-2003 Cirrus Logic, Inc., Austin, Tx 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/config.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/utsname.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/memory.h>
+#include <asm/arch/platform.h>
+
+#include <asm/mach/arch.h>
+
+#include <asm/arch/ssp.h>
+
+extern void ep93xx_map_io(void);
+extern void ep93xx_init_irq(void);
+
+static int __init
+ep93xx_init(void)
+{
+#ifndef CONFIG_MACH_IPD
+	unsigned int uiTemp;
+	int SSP_Handle;
+
+	/*
+	 * Enable halt mode.
+	 */
+	uiTemp = inl(SYSCON_DEVCFG) | SYSCON_DEVCFG_SHena;
+	SysconSetLocked(SYSCON_DEVCFG, uiTemp);
+
+	/*
+	 * Set the bus priority.
+	 */
+	outl(BMAR_PRIORD_02, SYSCON_BMAR);
+
+	/*
+	 * Get the hostname from the SPI FLASH if it has been programmed.
+	 */
+	SSP_Handle = SSPDriver->Open(SERIAL_FLASH, 0);
+	if(SSP_Handle != -1) {
+		SSPDriver->Read( SSP_Handle, 0x1000, &uiTemp );
+		if (uiTemp == 0x43414d45) {
+			SSPDriver->Read( SSP_Handle, 0x1010, &uiTemp );
+			system_utsname.nodename[0] = uiTemp & 255;
+			system_utsname.nodename[1] = (uiTemp >> 8) & 255;
+			system_utsname.nodename[2] = (uiTemp >> 16) & 255;
+			system_utsname.nodename[3] = uiTemp >> 24;
+			SSPDriver->Read( SSP_Handle, 0x1014, &uiTemp );
+			system_utsname.nodename[4] = uiTemp & 255;
+			system_utsname.nodename[5] = (uiTemp >> 8) & 255;
+			system_utsname.nodename[6] = (uiTemp >> 16) & 255;
+			system_utsname.nodename[7] = uiTemp >> 24;
+			SSPDriver->Read( SSP_Handle, 0x1018, &uiTemp );
+			system_utsname.nodename[8] = uiTemp & 255;
+			system_utsname.nodename[9] = (uiTemp >> 8) & 255;
+			system_utsname.nodename[10] = (uiTemp >> 16) & 255;
+			system_utsname.nodename[11] = uiTemp >> 24;
+			SSPDriver->Read( SSP_Handle, 0x101c, &uiTemp );
+			system_utsname.nodename[12] = uiTemp & 255;
+			system_utsname.nodename[13] = (uiTemp >> 8) & 255;
+			system_utsname.nodename[14] = (uiTemp >> 16) & 255;
+			system_utsname.nodename[15] = uiTemp >> 24;
+			system_utsname.nodename[16] = 0;
+		}
+		SSPDriver->Close( SSP_Handle );
+	}
+#endif /* CONFIG_MACH_IPD */
+}
+
+__initcall(ep93xx_init);
+  
+/* Machine Descriptor created by macros in asm-arm/mach/arch.h
+    bootmem: phys ram base, phys io base, virt io base
+    bootpara: phys param base  */
+
+#ifdef CONFIG_ARCH_EDB9301
+  MACHINE_START(EDB9301, "edb9301")
+      MAINTAINER("Cirrus Logic")
+    BOOT_MEM( 0x00000000, 0x80000000, 0xff000000 )
+    BOOT_PARAMS( 0x00000100 )
+    MAPIO(ep93xx_map_io)
+    INITIRQ(ep93xx_init_irq)
+  MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_EDB9302
+  MACHINE_START(EDB9302, "edb9302")
+    MAINTAINER("Cirrus Logic")
+    BOOT_MEM( 0x00000000, 0x80000000, 0xff000000 )
+    BOOT_PARAMS( 0x00000100 )
+      MAPIO(ep93xx_map_io)
+      INITIRQ(ep93xx_init_irq)
+  MACHINE_END
+#endif
+  
+#ifdef CONFIG_ARCH_EDB9312
+  MACHINE_START(EDB9312, "edb9312")
+      MAINTAINER("Cirrus Logic")
+    BOOT_MEM( 0x00000000, 0x80000000, 0xff000000 )
+    BOOT_PARAMS( 0x00000100 )
+      MAPIO(ep93xx_map_io)
+      INITIRQ(ep93xx_init_irq)
+  MACHINE_END
+  #endif
+  
+#ifdef CONFIG_ARCH_EDB9315
+  MACHINE_START(EDB9315, "edb9315")
+      MAINTAINER("Cirrus Logic")
+    BOOT_MEM( 0x00000000, 0x80000000, 0xff000000 )
+    BOOT_PARAMS( 0x00000100 )
+      MAPIO(ep93xx_map_io)
+      INITIRQ(ep93xx_init_irq)
+  MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_IPD
+  MACHINE_START(IPD, "ipd")
+      MAINTAINER("Cyberguard Inc.")
+    BOOT_MEM( SDRAM_START, 0x80000000, 0xff000000 )
+    BOOT_PARAMS( SDRAM_START + 0x00000100 )
+      MAPIO(ep93xx_map_io)
+      INITIRQ(ep93xx_init_irq)
+  MACHINE_END
+#endif
+
diff -urN linux-2.4.29/arch/arm/mach-ep93xx/crunch.c linux-2.4.29-uc1/arch/arm/mach-ep93xx/crunch.c
--- linux-2.4.29/arch/arm/mach-ep93xx/crunch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ep93xx/crunch.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,321 @@
+/*
+ *	Cirrus MaverickCrunch support
+ *
+ *	Copyright (c) 2003 Petko Manolov <petkan@nucleusys.com>
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	version 2 as published by the Free Software Foundation;
+ */
+
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/arch/crunch.h>
+
+unsigned int read_dspsc_low(void)
+{
+	int res;
+
+	asm volatile (
+	"cdp        p4, 1, c15, c0, c0, 7\n\t"	// "cfmv32sc      mvdx15, dspsc\n\t"
+	"mrc        p5, 0, %0, c15, c0, 0"	// "cfmvr64l  %0, mvdx15"
+	:"=r" (res)
+	:
+	:"memory");
+
+	return res;
+}
+
+unsigned int read_dspsc_high(void)
+{
+	int res;
+
+	asm volatile (
+	"cdp        p4, 1, c15, c0, c0, 7\n\t"	// "cfmv32sc   mvdx15, dspsc\n\t"
+	"mrc        p5, 0, %0, c15, c0, 1"	// "cfmvr64h   %0, mvdx15"
+	:"=r" (res)
+	:
+	:"memory");
+
+	return res;
+}
+
+void write_dspsc(unsigned int dspsc)
+{
+	asm volatile (
+	"mcr        p5, 0, %0, c15, c0, 0\n\t"	// "cfmv64lr     mvdx15, %0\n\t"
+	"cdp        p4, 2, c15, c0, c0, 7"	// "cfmvsc32     dspsc, mvdx15"
+	:
+	:"r" (dspsc), "rN"(-1)
+	:"memory");
+}
+
+void crunch_init(void)
+{
+	write_dspsc(CRUNCH_INIT);
+	current->flags |= PF_USEDCRUNCH;
+}
+
+/*
+ * had to do it this way since "clf(); cli();" takes longer
+ */
+static inline void clear_fiq_irq(void)
+{
+	int cpsr;
+
+	asm volatile (
+	"mrs	%0, CPSR\n\t"
+	"orr	%0, %0, #192\n\t"
+	"msr	CPSR_c, %0"
+	:"=r" (cpsr)
+	:
+	:"memory");
+}
+
+/*
+ * had to do it this way since "stf(); sti();" takes (twice) longer
+ */
+
+static inline void restore_fiq_irq(void)
+{
+	int cpsr;
+
+	asm volatile (
+	"mrs	%0, CPSR\n\t"
+	"bic	%0, %0, #192\n\t"
+	"msr	CPSR_c, %0"
+	:"=r" (cpsr)
+	:
+	:"memory");
+}
+
+static inline void save_accumulators(struct task_struct *tsk)
+{
+	int tmp;
+	struct fp_crunch_struct *fp = &tsk->thread.fpstate.crunch;
+
+	/*
+	 * clear the IRQ & FIQ to avoid some of the bugs in the errata
+	 */
+	clear_fiq_irq();
+
+	asm volatile (
+	"cdp        p4, 1, c0, c0, c0, 2\n\t"	// "cfmv32al      mvfx0, mvax0\n\t"
+	"stc        p5, c0, [%0], #4\n\t"	// "cfstr32      mvfx0, [%0], 4\n\t"
+	"cdp        p4, 1, c1, c0, c0, 3\n\t"	// "cfmv32am      mvfx1, mvax0\n\t"
+	"stc        p5, c1, [%0], #4\n\t"	// "cfstr32      mvfx1, [%0], 4\n\t"
+	"cdp        p4, 1, c2, c0, c0, 4\n\t"	// "cfmv32ah      mvfx2, mvax0\n\t"
+	"stc        p5, c2, [%0], #4\n\t"	// "cfstr32      mvfx2, [%0], 4\n\t"
+	"cdp        p4, 1, c3, c1, c0, 2\n\t"	// "cfmv32al      mvfx3, mvax1\n\t"
+	"stc        p5, c3, [%0], #4\n\t"	// "cfstr32      mvfx3, [%0], 4\n\t"
+	"cdp        p4, 1, c4, c1, c0, 3\n\t"	// "cfmv32am      mvfx4, mvax1\n\t"
+	"stc        p5, c4, [%0], #4\n\t"	// "cfstr32      mvfx4, [%0], 4\n\t"
+	"cdp        p4, 1, c5, c1, c0, 4\n\t"	// "cfmv32ah      mvfx5, mvax1\n\t"
+	"stc        p5, c5, [%0], #4\n\t"	// "cfstr32      mvfx5, [%0], 4\n\t"
+	"cdp        p4, 1, c6, c2, c0, 2\n\t"	// "cfmv32al      mvfx6, mvax2\n\t"
+	"stc        p5, c6, [%0], #4\n\t"	// "cfstr32      mvfx6, [%0], 4\n\t"
+	"cdp        p4, 1, c7, c2, c0, 3\n\t"	// "cfmv32am      mvfx7, mvax2\n\t"
+	"stc        p5, c7, [%0], #4\n\t"	// "cfstr32      mvfx7, [%0], 4\n\t"
+	"cdp        p4, 1, c8, c2, c0, 4\n\t"	// "cfmv32ah      mvfx8, mvax2\n\t"
+	"stc        p5, c8, [%0], #4\n\t"	// "cfstr32      mvfx8, [%0], 4\n\t"
+	"cdp        p4, 1, c9, c3, c0, 2\n\t"	// "cfmv32al      mvfx9, mvax3\n\t"
+	"stc        p5, c9, [%0], #4\n\t"	// "cfstr32      mvfx9, [%0], 4\n\t"
+	"cdp        p4, 1, c10, c3, c0, 3\n\t"	// "cfmv32am     mvfx10, mvax3\n\t"
+	"stc        p5,c10, [%0], #4\n\t"	// "cfstr32      mvfx10, [%0], 4\n\t"
+	"cdp        p4, 1, c11, c3, c0, 4\n\t"	// "cfmv32ah     mvfx11, mvax3\n\t"
+	"stc        p5, c11, [%0, #0]"		// "cfstr32      mvfx11, [%0, #0]"
+	:"=&r" (tmp)
+	:"0" (&fp->acc0[0])
+	:"memory");
+
+	restore_fiq_irq();
+}
+
+static inline void restore_accumulators(struct task_struct *tsk)
+{
+	int tmp;
+	struct fp_crunch_struct *fp = &tsk->thread.fpstate.crunch;
+
+	/*
+	 * clear the IRQ & FIQ to avoid some of the bugs in the errata
+	 */
+	clear_fiq_irq();
+
+	asm volatile (
+	"ldc        p5, c0, [%0],#4\n\t"	// "cfldr32        mvfx0, [%0], 4\n\t"
+	"cdp        p4, 2, c0, c0, c0, 2\n\t"	// "cfmval32       mvax0, mvfx0\n\t"
+	"ldc        p5, c1, [%0],#4\n\t"	// "cfldr32        mvfx1, [%0], 4\n\t"
+	"cdp        p4, 2, c0, c1, c0, 3\n\t"	// "cfmvam32       mvax0, mvfx1\n\t"
+	"ldc        p5, c2, [%0],#4\n\t"	// "cfldr32        mvfx2, [%0], 4\n\t"
+	"cdp        p4, 2, c0, c2, c0, 4\n\t"	// "cfmvah32       mvax0, mvfx2\n\t"
+	"ldc        p5, c3, [%0],#4\n\t"	// "cfldr32        mvfx3, [%0], 4\n\t"
+	"cdp        p4, 2, c1, c3, c0, 2\n\t"	// "cfmval32       mvax1, mvfx3\n\t"
+	"ldc        p5, c4, [%0],#4\n\t"	// "cfldr32        mvfx4, [%0], 4\n\t"
+	"cdp        p4, 2, c1, c4, c0, 3\n\t"	// "cfmvam32       mvax1, mvfx4\n\t"
+	"ldc        p5, c5, [%0],#4\n\t"	// "cfldr32        mvfx5, [%0], 4\n\t"
+	"cdp        p4, 2, c1, c5, c0, 4\n\t"	// "cfmvah32       mvax1, mvfx5\n\t"
+	"ldc        p5, c6, [%0],#4\n\t"	// "cfldr32        mvfx6, [%0], 4\n\t"
+	"cdp        p4, 2, c2, c6, c0, 2\n\t"	// "cfmval32       mvax2, mvfx6\n\t"
+	"ldc        p5, c7, [%0],#4\n\t"	// "cfldr32        mvfx7, [%0], 4\n\t"
+	"cdp        p4, 2, c2, c7, c0, 3\n\t"	// "cfmvam32       mvax2, mvfx7\n\t"
+	"ldc        p5, c8, [%0],#4\n\t"	// "cfldr32        mvfx8, [%0], 4\n\t"
+	"cdp        p4, 2, c2, c8, c0, 4\n\t"	// "cfmvah32       mvax2, mvfx8\n\t"
+	"ldc        p5, c9, [%0],#4\n\t"	// "cfldr32        mvfx9, [%0], 4\n\t"
+	"cdp        p4, 2, c3, c9, c0, 2\n\t"	// "cfmval32       mvax3, mvfx9\n\t"
+	"ldc        p5, c10, [%0],#4\n\t"	// "cfldr32        mvfx10, [%0], 4\n\t"
+	"cdp        p4, 2, c3, c10, c0, 3\n\t"	// "cfmvam32       mvax3, mvfx10\n\t"
+	"ldc        p5, c11, [%0, #0]\n\t"	// "cfldr32        mvfx11, [%0, #0]\n\t"
+	"cdp        p4, 2, c3, c11, c0, 4"	// "cfmvah32       mvax3, mvfx11"
+	:"=&r" (tmp)
+	:"0" (&fp->acc0[0])
+	:"memory");
+
+	restore_fiq_irq();
+}
+
+void save_crunch(struct task_struct *tsk)
+{
+	int tmp;
+	struct fp_crunch_struct *fp = &tsk->thread.fpstate.crunch;
+
+	asm volatile (
+	"stcl       p5, c0, [%0],#8\n\t"	// "cfstr64        mvdx0, [%0], 8\n\t"
+	"stcl       p5, c1, [%0],#8\n\t"	// "cfstr64        mvdx1, [%0], 8\n\t"
+	"stcl       p5, c2, [%0],#8\n\t"	// "cfstr64        mvdx2, [%0], 8\n\t"
+	"stcl       p5, c3, [%0],#8\n\t"	// "cfstr64        mvdx3, [%0], 8\n\t"
+	"stcl       p5, c4, [%0],#8\n\t"	// "cfstr64        mvdx4, [%0], 8\n\t"
+	"stcl       p5, c5, [%0],#8\n\t"	// "cfstr64        mvdx5, [%0], 8\n\t"
+	"stcl       p5, c6, [%0],#8\n\t"	// "cfstr64        mvdx6, [%0], 8\n\t"
+	"stcl       p5, c7, [%0],#8\n\t"	// "cfstr64        mvdx7, [%0], 8\n\t"
+	"stcl       p5, c8, [%0],#8\n\t"	// "cfstr64        mvdx8, [%0], 8\n\t"
+	"stcl       p5, c9, [%0],#8\n\t"	// "cfstr64        mvdx9, [%0], 8\n\t"
+	"stcl       p5, c10, [%0],#8\n\t"	// "cfstr64        mvdx10, [%0], 8\n\t"
+	"stcl       p5, c11, [%0],#8\n\t"	// "cfstr64        mvdx11, [%0], 8\n\t"
+	"stcl       p5, c12, [%0],#8\n\t"	// "cfstr64        mvdx12, [%0], 8\n\t"
+	"stcl       p5, c13, [%0],#8\n\t"	// "cfstr64        mvdx13, [%0], 8\n\t"
+	"stcl       p5, c14, [%0],#8\n\t"	// "cfstr64        mvdx14, [%0], 8\n\t"
+	"stcl       p5, c15, [%0, #0]\n\t"	// "cfstr64        mvdx15, [%0, #0]\n\t"
+	"cdp        p4, 1, c15, c0, c0, 7\n\t"	// "cfmv32sc       mvdx15, dspsc\n\t"
+	"stc        p5, c15, [%2, #0]"		// "cfstr32        mvfx15, [%2, #0]"
+	:"=&r" (tmp)
+	:"0" (&fp->regs[0]), "r" (&fp->dspsc)
+	:"memory");
+#ifdef CONFIG_EP93XX_CRUNCH_ACC
+	/*
+	 * this call should be made exactly here since it's corrupting
+	 * the contents of most crunch registers ;-)
+	 */
+	save_accumulators(tsk);
+#endif
+}
+
+void restore_crunch(struct task_struct *tsk)
+{
+	int tmp;
+	struct fp_crunch_struct *fp = &tsk->thread.fpstate.crunch;
+#ifdef CONFIG_EP93XX_CRUNCH_ACC
+	/*
+	 * same as above, but reversed.  if you put the call below the 'asm'
+	 * code then you'll corrupt the 
+	 */
+	restore_accumulators(tsk);
+#endif
+	asm volatile (
+	"ldc        p5, c15, [%2, #0]\n\t"	// "cfldr32   mvfx15, [%2, #0]\n\t"
+	"cdp        p4, 2, c15, c0, c0, 7\n\t"	// "cfmvsc32  dspsc, mvdx15\n\t"
+	"ldcl       p5, c0, [%0],#8\n\t"	// "cfldr64   mvdx0, [%0], 8\n\t"
+	"ldcl       p5, c1, [%0],#8\n\t"	// "cfldr64   mvdx1, [%0], 8\n\t"
+	"ldcl       p5, c2, [%0],#8\n\t"	// "cfldr64   mvdx2, [%0], 8\n\t"
+	"ldcl       p5, c3, [%0],#8\n\t"	// "cfldr64   mvdx3, [%0], 8\n\t"
+	"ldcl       p5, c4, [%0],#8\n\t"	// "cfldr64   mvdx4, [%0], 8\n\t"
+	"ldcl       p5, c5, [%0],#8\n\t"	// "cfldr64   mvdx5, [%0], 8\n\t"
+	"ldcl       p5, c6, [%0],#8\n\t"	// "cfldr64   mvdx6, [%0], 8\n\t"
+	"ldcl       p5, c7, [%0],#8\n\t"	// "cfldr64   mvdx7, [%0], 8\n\t"
+	"ldcl       p5, c8, [%0],#8\n\t"	// "cfldr64   mvdx8, [%0], 8\n\t"
+	"ldcl       p5, c9, [%0],#8\n\t"	// "cfldr64   mvdx9, [%0], 8\n\t"
+	"ldcl       p5, c10, [%0],#8\n\t"	// "cfldr64   mvdx10, [%0], 8\n\t"
+	"ldcl       p5, c11, [%0],#8\n\t"	// "cfldr64   mvdx11, [%0], 8\n\t"
+	"ldcl       p5, c12, [%0],#8\n\t"	// "cfldr64   mvdx12, [%0], 8\n\t"
+	"ldcl       p5, c13, [%0],#8\n\t"	// "cfldr64   mvdx13, [%0], 8\n\t"
+	"ldcl       p5, c14, [%0],#8\n\t"	// "cfldr64   mvdx14, [%0], 8\n\t"
+	"ldcl       p5, c15, [%0, #0]"		// "cfldr64   mvdx15, [%0, #0]"
+	:"=&r" (tmp)
+	:"0" (&fp->regs[0]), "r" (&fp->dspsc)
+	:"memory");
+}
+
+void crunch_exception(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int sc, opc;
+
+	send_sig(SIGFPE, current, 1);
+	opc = read_dspsc_high();
+	sc = read_dspsc_low();
+	printk("%s: DSPSC_high=%08x, DSPSC_low=%08x\n", __FUNCTION__, opc, sc);
+	sc &= ~(1 << 21);	/* we recure without this */
+	write_dspsc(sc);
+}
+
+/*
+ * only register ep9312 default FPU handler...
+ */
+__init int setup_crunch(void)
+{
+	int res;
+
+	res = request_irq(CRUNCH_IRQ, crunch_exception, SA_INTERRUPT, "FPU", NULL);
+	if (res) {
+		printk("Crunch IRQ (%d) allocation failure\n", CRUNCH_IRQ);
+		return res;
+	}
+
+	return res;
+}
+
+static inline int insn_is_crunch(long insn)
+{
+	long tmp;
+
+	tmp = (insn >> 24) & 0x0e;
+	/* cdp, mcr, mrc */
+	if (tmp == 0x0e || tmp == 0x0c) {
+		tmp = (insn >> 8) & 0x0f;
+		if (tmp == 4)
+			return 1;
+		if (tmp == 5)
+			return 1;
+		if (tmp == 6)
+			return 1;
+	}
+
+	return 0;
+}
+
+int crunch_opcode(struct pt_regs *regs)
+{
+	int *insn;
+	struct task_struct *tsk = current;
+
+	insn = (int *) (instruction_pointer(regs) - 4);
+	if (!insn_is_crunch(*insn)) {
+		/*
+		 * not a crunch instruction, but might be another
+		 * (FPA/VFP) floating point one
+		 */
+		return 0;
+	}
+
+	crunch_enable();
+	regs->ARM_pc -= 4;	/* restart the Crunch instruction */
+	if (tsk->flags & PF_USEDCRUNCH) {
+		restore_crunch(tsk);
+	} else {
+		crunch_init();
+	}
+	tsk->flags |= PF_USEDFPU;
+
+	return 1;
+}
+
+__initcall(setup_crunch);
diff -urN linux-2.4.29/arch/arm/mach-ep93xx/dma.c linux-2.4.29-uc1/arch/arm/mach-ep93xx/dma.c
--- linux-2.4.29/arch/arm/mach-ep93xx/dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ep93xx/dma.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,36 @@
+/*
+ *  linux/arch/arm/mach-integrator/dma.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/dma.h>
+
+void __init arch_dma_init(dma_t *dma)
+{
+}
diff -urN linux-2.4.29/arch/arm/mach-ep93xx/dma_ep93xx.c linux-2.4.29-uc1/arch/arm/mach-ep93xx/dma_ep93xx.c
--- linux-2.4.29/arch/arm/mach-ep93xx/dma_ep93xx.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ep93xx/dma_ep93xx.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,2873 @@
+/******************************************************************************
+ * arch/arm/mach-ep9312/dma_ep93xx.c
+ *
+ * Support functions for the ep93xx internal DMA channels.
+ * (see also Documentation/arm/ep93xx/dma.txt)
+ *
+ * Copyright (C) 2003  Cirrus Logic
+ *
+ * A large portion of this file is based on the dma api implemented by
+ * Nicolas Pitre, dma-sa1100.c, copyrighted 2000.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/mach/dma.h>
+#include "dma_ep93xx.h"
+
+/*****************************************************************************
+ *
+ * Debugging macros
+ *
+ ****************************************************************************/
+#undef DEBUG
+//#define DEBUG   1
+#ifdef DEBUG
+#define DPRINTK( fmt, arg... )  printk( fmt, ##arg )
+#else
+#define DPRINTK( fmt, arg... )
+#endif
+
+/*****************************************************************************
+ *
+ * static global variables
+ *
+ ****************************************************************************/
+ep93xx_dma_t dma_chan[MAX_EP93XX_DMA_CHANNELS];
+
+/*
+ *  lock used to protect the list of dma channels while searching for a free
+ *  channel during dma_request.
+ */
+static spinlock_t dma_list_lock;
+
+/*****************************************************************************
+ *
+ *  Internal DMA processing functions.
+ *
+ ****************************************************************************/
+/*****************************************************************************
+ *
+ *  get_dma_channel_from_handle()
+ *
+ *  If Handle is valid, returns the DMA channel # (0 to 9 for channels 1-10)
+ *  If Handle is not valid, returns -1.
+ *
+ ****************************************************************************/
+static int
+dma_get_channel_from_handle(int handle)
+{
+	int channel;
+
+	/*
+	 *  Get the DMA channel # from the handle.
+	 */
+	channel = ((int)handle & DMA_HANDLE_SPECIFIER_MASK) >> 28;
+
+	/*
+	 *  See if this is a valid handle.
+	 */
+	if (dma_chan[channel].last_valid_handle != (int)handle) {
+		DPRINTK("DMA ERROR - invalid handle 0x%x \n", handle);
+		return(-1);
+	}
+
+	/*
+	 *  See if this instance is still open
+	 */
+	if (!dma_chan[channel].ref_count )
+		return(-1);
+
+	return(channel);
+}
+
+static void dma_m2m_transfer_done(ep93xx_dma_t *dma)
+{
+	unsigned int uiCONTROL;
+	unsigned int M2M_reg_base = dma->reg_base;
+	unsigned int read_back;
+
+	DPRINTK("1  ");
+
+	outl( 0, M2M_reg_base+M2M_OFFSET_INTERRUPT );
+
+	if (dma->total_buffers) {
+		/*
+		 * The current_buffer has already been tranfered, so add the
+		 * byte count to the total_bytes field.
+		 */
+		dma->total_bytes = dma->total_bytes +
+			dma->buffer_queue[dma->current_buffer].size;
+
+		/*
+		 * Mark the current_buffer as used.
+		 */
+		dma->buffer_queue[dma->current_buffer].used = TRUE;
+
+		/*
+		 * Increment the used buffer counter
+		 */
+		dma->used_buffers++;
+
+		DPRINTK("#%d", dma->current_buffer);
+
+		/*
+		 * Increment the current_buffer
+		 */
+		dma->current_buffer = (dma->current_buffer + 1) %
+				      MAX_EP93XX_DMA_BUFFERS;
+
+		/*
+		 * check if there's a new buffer to transfer.
+		 */
+		if (dma->new_buffers && dma->xfer_enable) {
+			/*
+			 * We have a new buffer to transfer so program in the
+			 * buffer values.  Since a STALL interrupt was
+			 * triggered, we program the buffer descriptor 0
+			 *
+			 * Set the SAR_BASE/DAR_BASE/BCR registers with values
+			 * from the next buffer in the queue.
+			 */
+			outl( dma->buffer_queue[dma->current_buffer].source,
+			      M2M_reg_base + M2M_OFFSET_SAR_BASE0 );
+
+			outl( dma->buffer_queue[dma->current_buffer].dest,
+			      M2M_reg_base + M2M_OFFSET_DAR_BASE0 );
+
+			outl( dma->buffer_queue[dma->current_buffer].size,
+			      M2M_reg_base + M2M_OFFSET_BCR0 );
+
+			DPRINTK("SAR_BASE0 - 0x%x\n", dma->buffer_queue[dma->current_buffer].source);
+			DPRINTK("DAR_BASE0 - 0x%x\n", dma->buffer_queue[dma->current_buffer].dest);
+			DPRINTK("BCR0 - 0x%x\n", dma->buffer_queue[dma->current_buffer].size);
+
+			/*
+			 * Decrement the new buffer counter
+			 */
+			dma->new_buffers--;
+
+			/*
+			 * If there's a second new buffer, we program the
+			 * second buffer descriptor.
+			 */
+			if (dma->new_buffers) {
+				outl( dma->buffer_queue[(dma->current_buffer + 1) %
+							MAX_EP93XX_DMA_BUFFERS].source,
+				      M2M_reg_base+M2M_OFFSET_SAR_BASE1 );
+
+				outl( dma->buffer_queue[(dma->current_buffer + 1) %
+							MAX_EP93XX_DMA_BUFFERS].dest,
+				      M2M_reg_base+M2M_OFFSET_DAR_BASE1 );
+
+				outl( dma->buffer_queue[(dma->current_buffer + 1) %
+							MAX_EP93XX_DMA_BUFFERS].size,
+				      M2M_reg_base+M2M_OFFSET_BCR1 );
+
+				uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+				uiCONTROL |= CONTROL_M2M_NFBINTEN;
+				outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+
+				dma->new_buffers--;
+			}
+		} else {
+			DPRINTK("2 \n");
+			/*
+			 * There's a chance we setup both buffer descriptors,
+			 * but didn't service the NFB quickly enough, causing
+			 * the channel to transfer both buffers, then enter the
+			 * stall state.  So, we need to be able to process the
+			 * second buffer.
+			 */
+			if ((dma->used_buffers + dma->new_buffers) < dma->total_buffers)
+			{
+				DPRINTK("3 ");
+
+				/*
+				 * The current_buffer has already been
+				 * tranferred, so add the byte count to the
+				 * total_bytes field.
+				 */
+				dma->total_bytes = dma->total_bytes +
+					dma->buffer_queue[dma->current_buffer].size;
+
+				/*
+				 * Mark the current_buffer as used.
+				 */
+				dma->buffer_queue[dma->current_buffer].used = TRUE;
+
+				/*
+				 * Increment the used buffer counter
+				 */
+				dma->used_buffers++;
+
+				DPRINTK("#%d", dma->current_buffer);
+
+				/*
+				 * Increment the current buffer pointer.
+				 */
+				dma->current_buffer = (dma->current_buffer + 1) %
+						      MAX_EP93XX_DMA_BUFFERS;
+
+			}
+
+			/*
+			 * No new buffers to transfer, so disable the channel.
+			 */
+			uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+			uiCONTROL &= ~CONTROL_M2M_ENABLE;
+			outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+
+			/*
+			 * Indicate that this channel is in the pause by
+			 * starvation state by setting the pause bit to true.
+			 */
+			dma->pause = TRUE;
+		}
+	} else {
+		/*
+		 * No buffers to transfer, or old buffers to mark as used,
+		 * so disable the channel
+		 */
+		uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+		uiCONTROL &= ~CONTROL_M2M_ENABLE;
+		outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+
+		/*
+		 * Must read the control register back after a write.
+		 */
+		read_back = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+
+		/*
+		 * Indicate that this channel is in the pause by
+		 * starvation state by setting the pause bit to true.
+		 */
+		dma->pause = TRUE;
+	}
+}
+
+static void dma_m2m_next_frame_buffer(ep93xx_dma_t *dma)
+{
+	int loop;
+	unsigned int uiCONTROL;
+	unsigned int M2M_reg_base = dma->reg_base;
+
+	DPRINTK("5  ");
+
+	if (dma->total_buffers) {
+		DPRINTK("6  ");
+		/*
+		 * The iCurrentBuffer has already been transfered.  so add the
+		 * byte count from the current buffer to the total byte count.
+		 */
+		dma->total_bytes = dma->total_bytes +
+			dma->buffer_queue[dma->current_buffer].size;
+
+		/*
+		 * Mark the Current Buffer as used.
+		 */
+		dma->buffer_queue[dma->current_buffer].used = TRUE;
+
+		/*
+		 * Increment the used buffer counter
+		 */
+		dma->used_buffers++;
+
+		DPRINTK("#%d", dma->current_buffer);
+
+		if ((dma->buffer_queue[
+		    (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].last) ||
+		    (dma->new_buffers == 0) || (dma->xfer_enable == FALSE)) {
+			DPRINTK("7  ");
+
+			/*
+			 * This is the last Buffer in this transaction, so
+			 * disable the NFB interrupt.  We shouldn't get an NFB
+			 * int when the FSM moves to the ON state where it
+			 * would typically get the NFB int indicating a new
+			 * buffer can be programmed.  Instead, once in the ON
+			 * state, the DMA will just proceed to complete the
+			 * transfer of the current buffer, move the FSB
+			 * directly to the STALL state where a STALL interrupt
+			 * will be generated.
+			 */
+			uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+			uiCONTROL &= ~CONTROL_M2M_NFBINTEN ;
+			outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+
+			/*
+			 * The current buffer has been transferred, so
+			 * increment the current buffer counter to reflect
+			 * this.
+			 */
+			dma->current_buffer = (dma->current_buffer + 1) %
+					      MAX_EP93XX_DMA_BUFFERS;
+
+			DPRINTK("End of NFB handling. \n");
+			DPRINTK("CONTROL - 0x%x \n",
+                                inl(M2M_reg_base+M2M_OFFSET_CONTROL) );
+			DPRINTK("STATUS - 0x%x \n",
+                                inl(M2M_reg_base+M2M_OFFSET_STATUS) );
+			DPRINTK("SAR_BASE0 - 0x%x \n",
+                                inl(M2M_reg_base+M2M_OFFSET_SAR_BASE0) );
+			DPRINTK("SAR_CUR0 - 0x%x \n",
+                                inl(M2M_reg_base+M2M_OFFSET_SAR_CURRENT0) );
+			DPRINTK("DAR_BASE0 - 0x%x \n",
+                                inl(M2M_reg_base+M2M_OFFSET_DAR_BASE0) );
+			DPRINTK("DAR_CUR0 - 0x%x \n",
+                                inl(M2M_reg_base+M2M_OFFSET_DAR_CURRENT0) );
+
+			DPRINTK("Buffer	buf_id	 source	   size	   last	   used \n");
+			for (loop = 0; loop < 32; loop ++)
+				DPRINTK("%d		0x%x		0x%x		 0x%x		%d		 %d \n",
+					loop, dma->buffer_queue[loop].buf_id,
+					dma->buffer_queue[loop].source,
+					dma->buffer_queue[loop].size,
+					dma->buffer_queue[loop].last,
+					dma->buffer_queue[loop].used);
+			DPRINTK("pause	 0x%x		0x%x		 0x%x		%d		 %d \n",
+				dma->pause_buf.buf_id, dma->pause_buf.source,
+				dma->pause_buf.size, dma->pause_buf.last,
+				dma->pause_buf.used);
+
+			DPRINTK("Pause - %d \n", dma->pause);
+			DPRINTK("xfer_enable - %d \n", dma->xfer_enable);
+			DPRINTK("total bytes - 0x%x \n", dma->total_bytes);
+			DPRINTK("total buffer - %d \n", dma->total_buffers);
+			DPRINTK("new buffers - %d \n", dma->new_buffers);
+			DPRINTK("current buffer - %d \n", dma->current_buffer);
+			DPRINTK("last buffer - %d \n", dma->last_buffer);
+			DPRINTK("used buffers - %d \n", dma->used_buffers);
+			DPRINTK("callback addr - 0x%p \n", dma->callback);
+
+		} else if (dma->new_buffers) {
+			DPRINTK("8  ");
+			/*
+			 * We have a new buffer, so increment the current
+			 * buffer to point to the next buffer, which is already
+			 * programmed into the DMA. Next time around, it'll be
+			 * pointing to the current buffer.
+			 */
+			dma->current_buffer = (dma->current_buffer + 1) %
+					      MAX_EP93XX_DMA_BUFFERS;
+
+			/*
+			 * We know we have a new buffer to program as the next
+			 * buffer, so check which set of SAR_BASE/DAR_BASE/BCR
+			 * registers to program.
+			 */
+			if ( inl(M2M_reg_base+M2M_OFFSET_STATUS) & STATUS_M2M_NB ) {
+				/*
+				 * Set the SAR_BASE1/DAR_BASE1/BCR1 registers
+				 * with values from the next buffer in the
+				 * queue.
+				 */
+				outl( dma->buffer_queue[(dma->current_buffer + 1) %
+							MAX_EP93XX_DMA_BUFFERS].source,
+				      M2M_reg_base+M2M_OFFSET_SAR_BASE1 );
+
+				outl( dma->buffer_queue[(dma->current_buffer + 1) %
+							MAX_EP93XX_DMA_BUFFERS].dest,
+				      M2M_reg_base+M2M_OFFSET_DAR_BASE1 );
+
+				outl( dma->buffer_queue[(dma->current_buffer + 1) %
+							MAX_EP93XX_DMA_BUFFERS].size,
+				      M2M_reg_base+M2M_OFFSET_BCR1 );
+			} else {
+				/*
+				 * Set the SAR_BASE0/DAR_BASE0/BCR0 registers
+				 * with values from the next buffer in the
+				 * queue.
+				 */
+				outl( dma->buffer_queue[(dma->current_buffer + 1) %
+							MAX_EP93XX_DMA_BUFFERS].source,
+				      M2M_reg_base+M2M_OFFSET_SAR_BASE0 );
+
+				outl( dma->buffer_queue[(dma->current_buffer + 1) %
+							MAX_EP93XX_DMA_BUFFERS].dest,
+				      M2M_reg_base+M2M_OFFSET_DAR_BASE0 );
+
+				outl( dma->buffer_queue[(dma->current_buffer + 1) %
+							MAX_EP93XX_DMA_BUFFERS].size,
+				      M2M_reg_base+M2M_OFFSET_BCR0 );
+			}
+
+			/*
+			 *  Decrement the new buffers counter
+			 */
+			dma->new_buffers--;
+		}
+	} else {
+		/*
+		 * Total number of buffers is 0 - really we should never get
+		 * here, but just in case.
+		 */
+		DPRINTK("9 \n");
+
+		/*
+		 *  No new buffers to transfer, so Disable the channel
+		 */
+		uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+		uiCONTROL &= ~CONTROL_M2M_ENABLE;
+		outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+
+		/*
+		 *  Indicate that the channel is paused by starvation.
+		 */
+		dma->pause = 1;
+	}
+}
+
+/*****************************************************************************
+ *
+ * dma_m2m_irq_handler
+ *
+ ****************************************************************************/
+static void
+dma_m2m_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	ep93xx_dma_t *dma = (ep93xx_dma_t *)dev_id;
+	unsigned int M2M_reg_base = dma->reg_base;
+	ep93xx_dma_dev_t dma_int = UNDEF_INT;
+	int status;
+
+//	printk("+m2m irq=%d\n", irq);
+
+	/*
+	 *  Determine what kind of dma interrupt this is.
+	 */
+	status = inl(M2M_reg_base + M2M_OFFSET_INTERRUPT);
+	if ( status & INTERRUPT_M2M_DONEINT )
+		dma_int = DONE; // we're done with a requested dma
+	else if ( status & INTERRUPT_M2M_NFBINT )
+		dma_int = NFB;  // we're done with one dma buffer
+
+	DPRINTK("IRQ: b=%#x st=%#x\n", (int)dma->current_buffer, dma_int);
+
+	switch (dma_int) {
+	/*
+	 *  Next Frame Buffer Interrupt.  If there's a new buffer program it
+	 *  Check if this is the last buffer in the transfer,
+	 *  and if it is, disable the NFB int to prevent being
+	 *  interrupted for another buffer when we know there won't be
+	 *  another.
+	 */
+	case NFB:
+		dma_m2m_next_frame_buffer(dma);
+		break;
+	/*
+	 *  Done interrupt generated, indicating that the transfer is complete.
+	 */
+	case DONE:
+		dma_m2m_transfer_done(dma);
+		break;
+
+	default:
+		break;
+	}
+
+	if ((dma_int != UNDEF_INT) && dma->callback)
+		dma->callback(dma_int, dma->device, dma->user_data);
+}
+
+/*****************************************************************************
+ *
+ * dma_m2p_irq_handler
+ *
+ *
+ *
+ ****************************************************************************/
+static void
+dma_m2p_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	ep93xx_dma_t *dma = (ep93xx_dma_t *) dev_id;
+	unsigned int M2P_reg_base = dma->reg_base;
+	unsigned int read_back;
+	ep93xx_dma_dev_t dma_int = UNDEF_INT;
+	unsigned int loop, uiCONTROL, uiINTERRUPT;
+
+	/*
+	 *  Determine what kind of dma interrupt this is.
+	 */
+	if ( inl(M2P_reg_base+M2P_OFFSET_INTERRUPT) & INTERRUPT_M2P_STALLINT )
+		dma_int = STALL;
+	else if ( inl(M2P_reg_base+M2P_OFFSET_INTERRUPT) & INTERRUPT_M2P_NFBINT )
+		dma_int = NFB;
+	else if ( inl(M2P_reg_base+M2P_OFFSET_INTERRUPT) & INTERRUPT_M2P_CHERRORINT )
+		dma_int = CHERROR;
+
+	/*
+	 *  Stall Interrupt: The Channel is stalled, meaning nothing is
+	 *  programmed to transfer right now.  So, we're back to the
+	 *  beginnning.  If there's a buffer to transfer, program it into
+	 *  max and base 0 registers.
+	 */
+	if (dma_int == STALL) {
+		DPRINTK("1  ");
+
+		if (dma->total_buffers) {
+			/*
+			 * The current_buffer has already been tranfered, so
+			 * add the byte count to the total_bytes field.
+			 */
+			dma->total_bytes = dma->total_bytes +
+				dma->buffer_queue[dma->current_buffer].size;
+
+			/*
+			 *  Mark the current_buffer as used.
+			 */
+			dma->buffer_queue[dma->current_buffer].used = TRUE;
+
+			/*
+			 *  Increment the used buffer counter
+			 */
+			dma->used_buffers++;
+
+			DPRINTK("#%d", dma->current_buffer);
+
+			/*
+			 *  Increment the current_buffer
+			 */
+			dma->current_buffer = (dma->current_buffer + 1) %
+					      MAX_EP93XX_DMA_BUFFERS;
+
+			/*
+			 *  check if there's a new buffer to transfer.
+			 */
+			if (dma->new_buffers && dma->xfer_enable) {
+				/*
+				 * We have a new buffer to transfer so program
+				 * in the buffer values.  Since a STALL
+				 * interrupt was triggered, we program the
+				 * base0 and maxcnt0
+				 *
+				 * Set the MAXCNT0 register with the buffer
+				 * size
+				 */
+				outl( dma->buffer_queue[dma->current_buffer].size,
+					  M2P_reg_base+M2P_OFFSET_MAXCNT0 );
+
+				/*
+				 * Set the BASE0 register with the buffer base
+				 * address
+				 */
+				outl( dma->buffer_queue[dma->current_buffer].source,
+					  M2P_reg_base+M2P_OFFSET_BASE0 );
+
+				/*
+				 *  Decrement the new buffer counter
+				 */
+				dma->new_buffers--;
+
+				if (dma->new_buffers) {
+					DPRINTK("A  ");
+					/*
+					 * Set the MAXCNT1 register with the
+					 * buffer size
+					 */
+					outl( dma->buffer_queue[(dma->current_buffer + 1) %
+											MAX_EP93XX_DMA_BUFFERS].size,
+						  M2P_reg_base+M2P_OFFSET_MAXCNT1 );
+
+					/*
+					 * Set the BASE1 register with the
+					 * buffer base address
+					 */
+					outl( dma->buffer_queue[dma->current_buffer + 1 %
+											MAX_EP93XX_DMA_BUFFERS].source,
+						  M2P_reg_base+M2P_OFFSET_BASE1 );
+
+					/*
+					 *  Decrement the new buffer counter
+					 */
+					dma->new_buffers--;
+
+					/*
+					 *  Enable the NFB Interrupt.
+					 */
+					uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
+					uiCONTROL |= CONTROL_M2P_NFBINTEN;
+					outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
+				}
+			} else {
+				/*
+				 *  No new buffers.
+				 */
+				DPRINTK("2 \n");
+
+				/*
+				 *  There's a chance we setup both buffer descriptors, but
+				 *  didn't service the NFB quickly enough, causing the channel
+				 *  to transfer both buffers, then enter the stall state.
+				 *  So, we need to be able to process the second buffer.
+				 */
+				if ((dma->used_buffers + dma->new_buffers) < dma->total_buffers) {
+					DPRINTK("3 ");
+
+					/*
+					 *  The current_buffer has already been tranfered, so add the
+					 *  byte count to the total_bytes field.
+					 */
+					dma->total_bytes = dma->total_bytes +
+						dma->buffer_queue[dma->current_buffer].size;
+
+					/*
+					 *  Mark the current_buffer as used.
+					 */
+					dma->buffer_queue[dma->current_buffer].used = TRUE;
+
+					/*
+					 *  Increment the used buffer counter
+					 */
+					dma->used_buffers++;
+
+					DPRINTK("#%d", dma->current_buffer);
+
+					/*
+					 *  Increment the current buffer pointer.
+					 */
+					dma->current_buffer = (dma->current_buffer + 1) %
+						MAX_EP93XX_DMA_BUFFERS;
+
+				}
+
+				/*
+				 *  No new buffers to transfer, so disable the channel.
+				 */
+				uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
+				uiCONTROL &= ~CONTROL_M2P_ENABLE;
+				outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
+
+				/*
+				 *  Indicate that this channel is in the pause by starvation
+				 *  state by setting the pause bit to true.
+				 */
+				dma->pause = TRUE;
+
+				DPRINTK("STATUS - 0x%x \n",	 inl(M2P_reg_base+M2P_OFFSET_STATUS) );
+				DPRINTK("CONTROL - 0x%x \n",	inl(M2P_reg_base+M2P_OFFSET_CONTROL) );
+				DPRINTK("REMAIN - 0x%x \n",	 inl(M2P_reg_base+M2P_OFFSET_REMAIN) );
+				DPRINTK("PPALLOC - 0x%x \n",	inl(M2P_reg_base+M2P_OFFSET_PPALLOC) );
+				DPRINTK("BASE0 - 0x%x \n",	  inl(M2P_reg_base+M2P_OFFSET_BASE0) );
+				DPRINTK("MAXCNT0 - 0x%x \n",	inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) );
+				DPRINTK("CURRENT0 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT0) );
+				DPRINTK("BASE1 - 0x%x \n",	  inl(M2P_reg_base+M2P_OFFSET_BASE1) );
+				DPRINTK("MAXCNT1 - 0x%x \n",	inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) );
+				DPRINTK("CURRENT1 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT1) );
+
+				DPRINTK("Buffer	buf_id	 source	   size	   last	   used \n");
+				for (loop = 0; loop < 32; loop ++)
+					DPRINTK("%d		0x%x		0x%x		 0x%x		%d		 %d \n",
+							loop, dma->buffer_queue[loop].buf_id, dma->buffer_queue[loop].source,
+							dma->buffer_queue[loop].size,
+							dma->buffer_queue[loop].last, dma->buffer_queue[loop].used);
+				DPRINTK("pause	 0x%x		0x%x		 0x%x		%d		 %d \n",
+						dma->pause_buf.buf_id, dma->pause_buf.source, dma->pause_buf.size,
+						dma->pause_buf.last, dma->pause_buf.used);
+
+				DPRINTK("Pause - %d \n", dma->pause);
+				DPRINTK("xfer_enable - %d \n", dma->xfer_enable);
+				DPRINTK("total bytes - 0x%x \n", dma->total_bytes);
+				DPRINTK("total buffer - %d \n", dma->total_buffers);
+				DPRINTK("new buffers - %d \n", dma->new_buffers);
+				DPRINTK("current buffer - %d \n", dma->current_buffer);
+				DPRINTK("last buffer - %d \n", dma->last_buffer);
+				DPRINTK("used buffers - %d \n", dma->used_buffers);
+				DPRINTK("callback addr - 0x%p \n", dma->callback);
+			}
+		} else {
+			/*
+			 *  No buffers to transfer, or old buffers to mark as used,
+			 *  so Disable the channel
+			 */
+			uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
+			uiCONTROL &= ~CONTROL_M2P_ENABLE;
+			outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
+
+			/*
+			 *  Must read the control register back after a write.
+			 */
+			read_back = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
+
+			/*
+			 *  Indicate that this channel is in the pause by
+			 *  starvation state by setting the pause bit to true.
+			 */
+			dma->pause = TRUE;
+		}
+	}
+
+	/*
+	 *  Next Frame Buffer Interrupt.  If there's a new buffer program it
+	 *  Check if this is the last buffer in the transfer,
+	 *  and if it is, disable the NFB int to prevent being
+	 *  interrupted for another buffer when we know there won't be
+	 *  another.
+	 */
+	if (dma_int == NFB) {
+		DPRINTK("5  ");
+
+		if (dma->total_buffers) {
+			DPRINTK("6  ");
+			/*
+			 *  The iCurrentBuffer has already been transfered.  so add the
+			 *  byte count from the current buffer to the total byte count.
+			 */
+			dma->total_bytes = dma->total_bytes +
+				dma->buffer_queue[dma->current_buffer].size;
+
+			/*
+			 *  Mark the Current Buffer as used.
+			 */
+			dma->buffer_queue[dma->current_buffer].used = TRUE;
+
+			/*
+			 *  Increment the used buffer counter
+			 */
+			dma->used_buffers++;
+
+			DPRINTK("#%d", dma->current_buffer);
+
+			if ((dma->buffer_queue[
+			    (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].last) ||
+			    (dma->new_buffers == 0) || (dma->xfer_enable == FALSE)) {
+				DPRINTK("7  ");
+
+				/*
+				 *  This is the last Buffer in this transaction, so disable
+				 *  the NFB interrupt.  We shouldn't get an NFB int when the
+				 *  FSM moves to the ON state where it would typically get the
+				 *  NFB int indicating a new buffer can be programmed.
+				 *  Instead, once in the ON state, the DMA will just proceed
+				 *  to complet the transfer of the current buffer, move the
+				 *  FSB directly to the STALL state where a STALL interrupt
+				 *  will be generated.
+				 */
+				uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
+				uiCONTROL &= ~CONTROL_M2P_NFBINTEN;
+				outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
+
+				/*
+				 *  The current buffer has been transferred, so increment
+				 *  the current buffer counter to reflect this.
+				 */
+				dma->current_buffer = (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS;
+
+				DPRINTK("End of NFB handling. \n");
+				DPRINTK("STATUS - 0x%x \n",	 inl(M2P_reg_base+M2P_OFFSET_STATUS) );
+				DPRINTK("CONTROL - 0x%x \n",	inl(M2P_reg_base+M2P_OFFSET_CONTROL) );
+				DPRINTK("REMAIN - 0x%x \n",	 inl(M2P_reg_base+M2P_OFFSET_REMAIN) );
+				DPRINTK("PPALLOC - 0x%x \n",	inl(M2P_reg_base+M2P_OFFSET_PPALLOC) );
+				DPRINTK("BASE0 - 0x%x \n",	  inl(M2P_reg_base+M2P_OFFSET_BASE0) );
+				DPRINTK("MAXCNT0 - 0x%x \n",	inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) );
+				DPRINTK("CURRENT0 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT0) );
+				DPRINTK("BASE1 - 0x%x \n",	  inl(M2P_reg_base+M2P_OFFSET_BASE1) );
+				DPRINTK("MAXCNT1 - 0x%x \n",	inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) );
+				DPRINTK("CURRENT1 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT1) );
+
+				DPRINTK("Buffer	buf_id	 source	   size	   last	   used \n");
+				for (loop = 0; loop < 32; loop ++)
+					DPRINTK("%d		0x%x		0x%x		 0x%x		%d		 %d \n",
+							loop, dma->buffer_queue[loop].buf_id, dma->buffer_queue[loop].source,
+							dma->buffer_queue[loop].size,
+							dma->buffer_queue[loop].last, dma->buffer_queue[loop].used);
+				DPRINTK("pause	 0x%x		0x%x		 0x%x		%d		 %d \n",
+						dma->pause_buf.buf_id, dma->pause_buf.source, dma->pause_buf.size,
+						dma->pause_buf.last, dma->pause_buf.used);
+
+				DPRINTK("Pause - %d \n", dma->pause);
+				DPRINTK("xfer_enable - %d \n", dma->xfer_enable);
+				DPRINTK("total bytes - 0x%x \n", dma->total_bytes);
+				DPRINTK("total buffer - %d \n", dma->total_buffers);
+				DPRINTK("new buffers - %d \n", dma->new_buffers);
+				DPRINTK("current buffer - %d \n", dma->current_buffer);
+				DPRINTK("last buffer - %d \n", dma->last_buffer);
+				DPRINTK("used buffers - %d \n", dma->used_buffers);
+				DPRINTK("callback addr - 0x%p \n", dma->callback);
+
+			} else if (dma->new_buffers) {
+				DPRINTK("8  ");
+				/*
+				 *  we have a new buffer, so increment the current buffer to
+				 *  point to the next buffer, which is already programmed into
+				 *  the DMA. Next time around, it'll be pointing to the
+				 *  current buffer.
+				 */
+				dma->current_buffer = (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS;
+
+				/*
+				 *  we know we have a new buffer to program as the next
+				 *  buffer, so check which set of MAXCNT and BASE registers
+				 *  to program.
+				 */
+				if ( inl(M2P_reg_base+M2P_OFFSET_STATUS) & STATUS_M2P_NEXTBUFFER ) {
+					/*
+					 *  Set the MAXCNT1 register with the buffer size
+					 */
+					outl( dma->buffer_queue[
+					      (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size,
+					      M2P_reg_base+M2P_OFFSET_MAXCNT1 );
+
+					/*
+					 *  Set the BASE1 register with the buffer base address
+					 */
+					outl( dma->buffer_queue[
+					      (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source,
+					      M2P_reg_base+M2P_OFFSET_BASE1 );
+				} else {
+					/*
+					 *  Set the MAXCNT0 register with the buffer size
+					 */
+					outl( dma->buffer_queue[
+					      (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size,
+					       M2P_reg_base+M2P_OFFSET_MAXCNT0 );
+
+					/*
+					 *  Set the BASE0 register with the buffer base address
+					 */
+					outl( dma->buffer_queue[
+					      (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source,
+					      M2P_reg_base+M2P_OFFSET_BASE0 );
+				}
+
+				/*
+				 *  Decrement the new buffers counter
+				 */
+				dma->new_buffers--;
+			}
+		} else {
+			/*
+			 *  Total number of buffers is 0 - really we should never get here,
+			 *  but just in case.
+			 */
+			DPRINTK("9 \n");
+
+			/*
+			 *  No new buffers to transfer, so Disable the channel
+			 */
+			uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
+			uiCONTROL &= ~CONTROL_M2P_ENABLE;
+			outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
+		}
+	}
+
+	/*
+	 *  Channel Error Interrupt, or perhipheral interrupt, specific to the
+	 *  memory to/from peripheral channels.
+	 */
+	if (dma_int == CHERROR) {
+		/*
+		 *  just clear the interrupt, it's really up to the peripheral
+		 *  driver to determine if any further action is necessary.
+		 */
+		uiINTERRUPT = inl(M2P_reg_base+M2P_OFFSET_INTERRUPT);
+		uiINTERRUPT &= ~INTERRUPT_M2P_CHERRORINT;
+		outl( uiINTERRUPT, M2P_reg_base+M2P_OFFSET_INTERRUPT );
+	}
+
+	/*
+	 *  Make sure the interrupt was valid, and if it was, then check
+	 *  if a callback function was installed for this DMA channel.  If a
+	 *  callback was installed call it.
+	 */
+	if ((dma_int != UNDEF_INT) && dma->callback)
+		dma->callback(dma_int, dma->device, dma->user_data);
+}
+
+/*****************************************************************************
+ *
+ * ep9312_dma_open_m2p(int device)
+ *
+ * Description: This function will attempt to open a M2P/P2M DMA channel.
+ *			  If the open is successful, the channel number is returned,
+ *			  otherwise a negative number is returned.
+ *
+ * Parameters:
+ *  device:	 device for which the dma channel is requested.
+ *
+ ****************************************************************************/
+static int
+dma_open_m2p(int device)
+{
+	int channel = -1;
+	unsigned int loop;
+	unsigned int M2P_reg_base;
+	unsigned int uiPWRCNT;
+	unsigned long flags;
+
+	DPRINTK("DMA Open M2P with hw dev %d\n", device);
+
+	/*
+	 *  Lock the dma channel list.
+	 */
+	spin_lock_irqsave(&dma_list_lock, flags);
+
+	DPRINTK("1\n");
+	/*
+	 * Verify that the device requesting DMA isn't already using a DMA channel
+	 */
+	if (device >= 10)
+		loop = 1;		 // Rx transfer requested
+	else
+		loop = 0;		 // Tx transfer requested
+
+	for (; loop < 10; loop = loop + 2)
+		/*
+		 *  Before checking for a matching device, check that the
+		 *  channel is in use, otherwise the device field is
+		 *  invalid.
+		 */
+		if (dma_chan[loop].ref_count)
+			if (device == dma_chan[loop].device) {
+				DPRINTK("DMA Open M2P - Error\n");
+				return(-1);
+			}
+
+	/*
+	 *  Get a DMA channel instance for the given hardware device.
+	 *  If this is a TX look for even numbered channels, else look for
+	 *  odd numbered channels
+	 */
+	if (device >= 10)
+		loop = 1;		 /* Rx transfer requested */
+	else
+		loop = 0;		 /* Tx transfer requested */
+
+	for (; loop < 10; loop = loop + 2)
+		if (!dma_chan[loop].ref_count) {
+			/*
+			 *  Capture the channel and increment the reference count.
+			 */
+			channel = loop;
+			dma_chan[channel].ref_count++;
+			break;
+		}
+
+	/*
+	 *  Unlock the dma channel list.
+	 */
+	spin_unlock_irqrestore(&dma_list_lock, flags);
+
+	/*
+	 *  See if we got a valid channel.
+	 */
+	if (channel < 0)
+		return(-1);
+
+	/*
+	 *  Point regs to the correct dma channel register base.
+	 */
+	M2P_reg_base = dma_chan[channel].reg_base;
+
+	/*
+	 *  Turn on the clock for the specified DMA channel
+	 *  TODO: need to use the correct register name for the
+	 *  power control register.
+	 */
+	uiPWRCNT = inl(SYSCON_PWRCNT);
+	switch (channel) {
+	case 0:
+		uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH0;
+		break;
+
+	case 1:
+		uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH1;
+		break;
+
+	case 2:
+		uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH2;
+		break;
+
+	case 3:
+		uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH3;
+		break;
+
+	case 4:
+		uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH4;
+		break;
+
+	case 5:
+		uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH5;
+		break;
+
+	case 6:
+		uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH6;
+		break;
+
+	case 7:
+		uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH7;
+		break;
+
+	case 8:
+		uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH8;
+		break;
+
+	case 9:
+		uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH9;
+		break;
+
+	default:
+		return(-1);
+	}
+	outl( uiPWRCNT, SYSCON_PWRCNT );
+
+	/*
+	 *  Clear out the control register before any further setup.
+	 */
+	outl( 0, M2P_reg_base+M2P_OFFSET_CONTROL );
+
+	/*
+	 *  Setup the peripheral port value in the DMA channel registers.
+	 */
+	if (device < 10)
+		outl( (unsigned int)device, M2P_reg_base+M2P_OFFSET_PPALLOC );
+	else
+		outl( (unsigned int)(device - 10), M2P_reg_base+M2P_OFFSET_PPALLOC );
+
+	/*
+	 *  Let's hold on to the value of the Hw device for comparison later.
+	 */
+	dma_chan[channel].device = device;
+
+	/*
+	 *  Success.
+	 */
+	return(channel);
+}
+
+/*****************************************************************************
+ *
+ * dma_open_m2m(int device)
+ *
+ * Description: This function will attempt to open a M2M DMA channel.
+ *			  If the open is successful, the channel number is returned,
+ *			  otherwise a negative number is returned.
+ *
+ * Parameters:
+ *  device:	 device for which the dma channel is requested.
+ *
+ ****************************************************************************/
+static int
+dma_open_m2m(int device)
+{
+	int channel = -1;
+	unsigned int loop;
+	unsigned int M2M_reg_base;
+	unsigned int uiPWRCNT, uiCONTROL;
+	unsigned long flags;
+
+	DPRINTK("DMA Open M2M with hw dev %d\n", device);
+
+	/*
+	 *  Lock the dma channel list.
+	 */
+	spin_lock_irqsave(&dma_list_lock, flags);
+
+	DPRINTK("1\n");
+
+	/*
+	 *  Check if this device is already allocated a channel.
+	 *  TODO: can one M2M device be allocated multiple channels?
+	 */
+	for (loop = DMA_MEMORY; loop < UNDEF; loop++)
+		/*
+		 *  Before checking for a matching device, check that the
+		 *  channel is in use, otherwise the device field is
+		 *  invalid.
+		 */
+		if (dma_chan[loop].ref_count)
+			if (device == dma_chan[loop].device) {
+				DPRINTK("Error - dma_open_m2m - already allocated channel\n");
+
+				/*
+				 *  Unlock the dma channel list.
+				 */
+				spin_unlock_irqrestore(&dma_list_lock, flags);
+
+				/*
+				 *  Fail.
+				 */
+				return(-1);
+			}
+
+	/*
+	 *  Get a DMA channel instance for the given hardware device.
+	 */
+	for (loop = 10; loop < 12; loop++)
+		if (!dma_chan[loop].ref_count) {
+			/*
+			 *  Capture the channel and increment the reference count.
+			 */
+			channel = loop;
+			dma_chan[channel].ref_count++;
+			break;
+		}
+
+	/*
+	 *  Unlock the dma channel list.
+	 */
+	spin_unlock(dma_list_lock);
+
+	/*
+	 *  See if we got a valid channel.
+	 */
+	if (channel < 0)
+		return(-1);
+
+	/*
+	 *  Point regs to the correct dma channel register base.
+	 */
+	M2M_reg_base = dma_chan[channel].reg_base;
+
+	/*
+	 *  Turn on the clock for the specified DMA channel
+	 *  TODO: need to use the correct register name for the
+	 *  power control register.
+	 */
+	uiPWRCNT = inl(SYSCON_PWRCNT);
+	switch (channel) {
+	case 10:
+		uiPWRCNT |= SYSCON_PWRCNT_DMA_M2MCH0;
+		break;
+
+	case 11:
+		uiPWRCNT |= SYSCON_PWRCNT_DMA_M2MCH1;
+		break;
+
+	default:
+		return(-1);
+	}
+	outl( uiPWRCNT, SYSCON_PWRCNT );
+
+	DPRINTK("DMA Open - power control: 0x%x \n", inl(SYSCON_PWRCNT) );
+
+	/*
+	 *  Clear out the control register before any further setup.
+	 */
+	outl( 0, M2M_reg_base+M2M_OFFSET_CONTROL );
+
+	/*
+	 *  Setup the transfer mode and the request source selection within
+	 *  the DMA M2M channel registers.
+	 */
+	switch (device) {
+	case DMA_MEMORY:
+		/*
+		 * Clear TM field, set RSS field to 0
+		 */
+		uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+		uiCONTROL &= ~(CONTROL_M2M_TM_MASK | CONTROL_M2M_RSS_MASK);
+		outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+		break;
+
+	case DMA_IDE:
+		/*
+		 * Set RSS field to 3, Set NO_HDSK, Set PW field to 1
+		 */
+		uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+		uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_PW_MASK);
+		uiCONTROL |= (3<<CONTROL_M2M_RSS_SHIFT) |
+			CONTROL_M2M_NO_HDSK |
+			(2<<CONTROL_M2M_PW_SHIFT);
+
+		uiCONTROL &= ~(CONTROL_M2M_ETDP_MASK);
+		uiCONTROL &= ~(CONTROL_M2M_DACKP);
+		uiCONTROL &= ~(CONTROL_M2M_DREQP_MASK);
+
+		outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+		inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+		break;
+
+	case DMARx_SSP:
+		/*
+		 * Set RSS field to 1, Set NO_HDSK, Set TM field to 2
+		 */
+		uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+		uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_TM_MASK);
+		uiCONTROL |= (1<<CONTROL_M2M_RSS_SHIFT) |
+			CONTROL_M2M_NO_HDSK |
+			(2<<CONTROL_M2M_TM_SHIFT);
+		outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+		break;
+
+	case DMATx_SSP:
+		/*
+		 * Set RSS field to 2, Set NO_HDSK, Set TM field to 1
+		 */
+		uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+		uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_TM_MASK);
+		uiCONTROL |= (2<<CONTROL_M2M_RSS_SHIFT) |
+			CONTROL_M2M_NO_HDSK |
+			(1<<CONTROL_M2M_TM_SHIFT);
+		outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+		break;
+
+	case DMATx_EXT_DREQ:
+		/*
+		 * Set TM field to 2, set RSS field to 0
+		 */
+		uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+		uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_TM_MASK);
+		uiCONTROL |= 1<<CONTROL_M2M_TM_SHIFT;
+		outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+		break;
+
+	case DMARx_EXT_DREQ:
+		/*
+		 * Set TM field to 2, set RSS field to 0
+		 */
+		uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+		uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_TM_MASK);
+		uiCONTROL |= 2<<CONTROL_M2M_TM_SHIFT;
+		outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+		break;
+
+	default:
+		return -1;
+	}
+
+	/*
+	 *  Let's hold on to the value of the Hw device for comparison later.
+	 */
+	dma_chan[channel].device = device;
+
+	/*
+	 *  Success.
+	 */
+	return(channel);
+}
+
+/*****************************************************************************
+ *
+ *  int dma_config_m2m(ep93xx_dma_t * dma, unsigned int flags_m2m,
+ *			   dma_callback callback, unsigned int user_data)
+ *
+ *  Description: Configure the DMA channel and install a callback function.
+ *			   This function will have to be called for every transfer
+ *
+ *  dma:		Pointer to the dma instance data for the M2M channel to
+ *			  configure.
+ *  flags_m2m   Flags used to configure an M2M dma channel and determine
+ *			  if a callback function and user_data information are included
+ *			  in this call.
+ *  callback	function pointer which is called near the end of the
+ *			  dma channel's irq handler.
+ *  user_data   defined by the calling driver.
+ *
+ ****************************************************************************/
+static int
+dma_config_m2m(ep93xx_dma_t * dma, unsigned int flags_m2m,
+			   dma_callback callback, unsigned int user_data)
+{
+	unsigned int flags;
+	unsigned int M2M_reg_base, uiCONTROL;
+
+	/*
+	 *  Make sure the channel is disabled before configuring the channel.
+	 *
+	 *  TODO: Is this correct??   Making a big change here...
+	 */
+	/* if (!dma->pause || (!dma->pause && dma->xfer_enable)) */
+	if (dma->xfer_enable) {
+		/*
+		 *  DMA channel is not paused, so we can't configure it.
+		 */
+		DPRINTK("DMA channel not paused, so can't configure! \n");
+		return(-1);
+	}
+
+	/*
+	 *  Mask interrupts.
+	 */
+	local_irq_save(flags);
+
+	/*
+	 *  Setup a pointer into the dma channel's register set.
+	 */
+	M2M_reg_base = dma->reg_base;
+
+	uiCONTROL = inl(M2M_reg_base + M2M_OFFSET_CONTROL);
+	outl(0, M2M_reg_base + M2M_OFFSET_CONTROL);
+	inl(M2M_reg_base + M2M_OFFSET_CONTROL);
+	outl(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL);
+
+	/*
+	 *  By default we disable the stall interrupt.
+	 */
+	uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+	uiCONTROL &= ~CONTROL_M2M_STALLINTEN;
+	outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+
+	/*
+	 *  By default we disable the done interrupt.
+	 */
+	uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+	uiCONTROL &= ~CONTROL_M2M_DONEINTEN;
+	outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+
+	/*
+	 *  Set up the transfer control fields based on values passed in
+	 *  the flags_m2m field.
+	 */
+	uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+
+	if ( flags_m2m & DESTINATION_HOLD )
+		uiCONTROL |= CONTROL_M2M_DAH;
+	else
+		uiCONTROL &= ~CONTROL_M2M_DAH;
+
+	if ( flags_m2m & SOURCE_HOLD )
+		uiCONTROL |= CONTROL_M2M_SAH;
+	else
+		uiCONTROL &= ~CONTROL_M2M_SAH;
+
+	uiCONTROL &= ~CONTROL_M2M_TM_MASK;
+	uiCONTROL |= (((flags_m2m & TRANSFER_MODE_MASK) >> TRANSFER_MODE_SHIFT) <<
+				  CONTROL_M2M_TM_SHIFT) & CONTROL_M2M_TM_MASK;
+
+	uiCONTROL &= ~CONTROL_M2M_PWSC_MASK;
+	uiCONTROL |= (((flags_m2m & WAIT_STATES_MASK) >> WAIT_STATES_SHIFT) <<
+				  CONTROL_M2M_PWSC_SHIFT) & CONTROL_M2M_PWSC_MASK;
+
+	outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+	inl(M2M_reg_base + M2M_OFFSET_CONTROL);
+
+	/*
+	 *  Save the callback function in the dma instance for this channel.
+	 */
+	dma->callback = callback;
+
+	/*
+	 *  Save the user data in the the dma instance for this channel.
+	 */
+	dma->user_data = user_data;
+
+	/*
+	 *  Put the dma instance into the pause state by setting the
+	 *  pause bit to true.
+	 */
+	dma->pause = TRUE;
+
+	local_irq_restore(flags);
+
+	/*
+	 *  Success.
+	 */
+	return(0);
+}
+
+/*****************************************************************************
+ *
+ *  int dma_start(int handle, unsigned int channels, unsigned int * handles)
+ *
+ *  Description: Initiate a transfer on up to 3 channels.
+ *
+ *  handle:	 handle for the channel to initiate transfer on.
+ *  channels:   number of channels to initiate transfers on.
+ *  handles:	pointer to an array of handles, one for each channel which
+ *			   is to be started.
+ *
+ ****************************************************************************/
+static int
+dma_start_m2m(int channel, ep93xx_dma_t * dma)
+{
+	unsigned int flags;
+	unsigned int M2M_reg_base = dma->reg_base;
+	unsigned int uiCONTROL;
+
+	/*
+	 *  Mask interrupts while we get this started.
+	 */
+	local_irq_save(flags);
+
+	/*
+	 *  Make sure the channel has at least one buffer in the queue.
+	 */
+	if (dma->new_buffers < 1) {
+		/*
+		 *  Unmask irqs
+		 */
+		local_irq_restore(flags);
+
+		DPRINTK("DMA Start: Channel starved.\n");
+
+		/*
+		 *  This channel does not have enough buffers queued up,
+		 *  so enter the pause by starvation state.
+		 */
+		dma->xfer_enable = TRUE;
+		dma->pause = TRUE;
+
+		/*
+		 *  Success.
+		 */
+		return(0);
+	}
+
+	/*
+	 *  Clear any pending interrupts.
+	 */
+	outl(0x0, M2M_reg_base+M2M_OFFSET_INTERRUPT);
+
+	/*
+	 *  Set up one or both buffer descriptors with values from the next one or
+	 *  two buffers in the queue.  By default disable the next frame buffer
+	 *  interrupt on the channel.
+	 */
+	uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+	uiCONTROL &= ~CONTROL_M2M_NFBINTEN;
+	outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+
+	/*
+	 * enable the done interrupt.
+	 */
+	uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+	uiCONTROL |= CONTROL_M2M_DONEINTEN;
+	outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+
+	/*
+	 *  Update the dma channel instance transfer state.
+	 */
+	dma->xfer_enable = TRUE;
+	dma->pause = FALSE;
+
+	/*
+	 *  Program up the first buffer descriptor with a source and destination
+	 *  and a byte count.
+	 */
+	outl( dma->buffer_queue[dma->current_buffer].source,
+	      M2M_reg_base+M2M_OFFSET_SAR_BASE0 );
+
+	outl( dma->buffer_queue[dma->current_buffer].dest,
+	      M2M_reg_base+M2M_OFFSET_DAR_BASE0 );
+
+	outl( dma->buffer_queue[dma->current_buffer].size,
+	      M2M_reg_base+M2M_OFFSET_BCR0 );
+
+	/*
+	 *  Decrement the new buffers counter.
+	 */
+	dma->new_buffers--;
+
+	/*
+	 * Set up the second buffer descriptor with a second buffer if we have
+	 * a second buffer.
+	 */
+	if (dma->new_buffers) {
+		outl( dma->buffer_queue[(dma->current_buffer + 1) %
+					MAX_EP93XX_DMA_BUFFERS].source,
+		      M2M_reg_base+M2M_OFFSET_SAR_BASE1 );
+
+		outl( dma->buffer_queue[(dma->current_buffer + 1) %
+					MAX_EP93XX_DMA_BUFFERS].dest,
+		      M2M_reg_base+M2M_OFFSET_DAR_BASE1 );
+
+		outl( dma->buffer_queue[(dma->current_buffer + 1) %
+					MAX_EP93XX_DMA_BUFFERS].size,
+		      M2M_reg_base+M2M_OFFSET_BCR1 );
+
+		uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+		uiCONTROL |= CONTROL_M2M_NFBINTEN;
+		outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+
+		dma->new_buffers--;
+	}
+
+	/*
+	 *  Now we enable the channel.  This initiates the transfer.
+	 */
+	uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+	uiCONTROL |= CONTROL_M2M_ENABLE;
+	outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+	inl(M2M_reg_base + M2M_OFFSET_CONTROL);
+
+	/*
+	 *  If this is a memory to memory transfer, we need to s/w trigger the
+	 *  transfer by setting the start bit within the control register.
+	 */
+	if (dma->device == DMA_MEMORY) {
+		uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+		uiCONTROL |= CONTROL_M2M_START;
+		outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+	}
+
+	DPRINTK("DMA - It's been started!!");
+	DPRINTK("CONTROL - 0x%x \n",	inl(M2M_reg_base+M2M_OFFSET_CONTROL) );
+	DPRINTK("STATUS - 0x%x \n",	 inl(M2M_reg_base+M2M_OFFSET_STATUS) );
+	DPRINTK("BCR0 - 0x%x \n",	   dma->buffer_queue[dma->current_buffer].size);
+	DPRINTK("SAR_BASE0 - 0x%x \n",  inl(M2M_reg_base+M2M_OFFSET_SAR_BASE0) );
+	DPRINTK("SAR_CUR0 - 0x%x \n",   inl(M2M_reg_base+M2M_OFFSET_SAR_CURRENT0) );
+	DPRINTK("DAR_BASE0 - 0x%x \n",  inl(M2M_reg_base+M2M_OFFSET_DAR_BASE0) );
+	DPRINTK("DAR_CUR0 - 0x%x \n",   inl(M2M_reg_base+M2M_OFFSET_DAR_CURRENT0) );
+
+	/*
+	 *  Unmask irqs
+	 */
+	local_irq_restore(flags);
+
+	/*
+	 *  Success.
+	 */
+	return(0);
+}
+
+/*****************************************************************************
+ *
+ *  DMA interface functions
+ *
+ ****************************************************************************/
+
+/*****************************************************************************
+ *
+ *  int dma_init(int handle, unsigned int flags_m2p, unsigned int flags_m2m,
+ *			   dma_callback callback, unsigned int user_data)
+ *
+ *  Description: Configure the DMA channel and install a callback function.
+ *
+ *  handle:	 Handle unique the each instance of the dma interface, used
+ *			  to verify this call.
+ *  flags_m2p   Flags used to configure an M2P/P2M dma channel and determine
+ *			  if a callback function and user_data information are included
+ *			  in this call. This field should be NULL if handle represents
+ *			  an M2M channel.
+ *  flags_m2m   Flags used to configure an M2M dma channel and determine
+ *			  if a callback function and user_data information are included
+ *			  in this call. This field should be NULL if handle represents
+ *			  an M2P/P2M channel.
+ *  callback	function pointer which is called near the end of the
+ *			  dma channel's irq handler.
+ *  user_data   defined by the calling driver.
+ *
+ ****************************************************************************/
+int
+ep93xx_dma_config(int handle, unsigned int flags_m2p, unsigned int flags_m2m,
+		  dma_callback callback, unsigned int user_data)
+{
+	int  channel;
+	ep93xx_dma_t * dma;
+	int flags;
+	unsigned int M2P_reg_base, uiCONTROL;
+
+	/*
+	 *  Get the DMA hw channel # from the handle.
+	 */
+	channel = dma_get_channel_from_handle(handle);
+
+	/*
+	 *  See if this is a valid handle.
+	 */
+	if (channel < 0) {
+		printk(KERN_ERR
+			   "DMA Config: Invalid dma handle.\n");
+		return(-EINVAL);
+	}
+
+	DPRINTK("DMA Config \n");
+
+	dma = &dma_chan[channel];
+
+	local_irq_save(flags);
+
+	/*
+	 *  Check if the channel is currently transferring.
+	 */
+	if (dma->xfer_enable) {
+		local_irq_restore(flags);
+		return(-EINVAL);
+	}
+
+	/*
+	 *  Check if this is an m2m function.
+	 */
+	if (channel >= 10) {
+		local_irq_restore(flags);
+
+		/*
+		 *  Call another function to handle m2m config.
+		 */
+		return(dma_config_m2m(dma, flags_m2m, callback, user_data));
+	}
+
+	/*
+	 *  Setup a pointer into the dma channel's register set.
+	 */
+	M2P_reg_base = dma->reg_base;
+
+	/*
+	 *  By default we enable the stall interrupt.
+	 */
+	uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
+	uiCONTROL |= CONTROL_M2P_STALLINTEN;
+	outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
+
+	/*
+	 *  Configure the channel for an error from the peripheral.
+	 */
+	uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
+	if ( flags_m2p && CHANNEL_ERROR_INT_ENABLE )
+		uiCONTROL |= CONTROL_M2P_CHERRORINTEN;
+	else
+		uiCONTROL &= ~CONTROL_M2P_CHERRORINTEN;
+	outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
+
+	uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
+	if ( flags_m2p && CHANNEL_ABORT )
+		uiCONTROL |= CONTROL_M2P_ABRT;
+	else
+		uiCONTROL &= ~CONTROL_M2P_ABRT;
+	outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
+
+	uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
+	if ( flags_m2p && IGNORE_CHANNEL_ERROR )
+		uiCONTROL |= CONTROL_M2P_ICE;
+	else
+		uiCONTROL &= ~CONTROL_M2P_ICE;
+	outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
+
+	/*
+	 *  Save the callback function in the dma instance for this channel.
+	 */
+	dma->callback = callback;
+
+	/*
+	 *  Save the user data in the the dma instance for this channel.
+	 */
+	dma->user_data = user_data;
+
+	/*
+	 *  Put the dma instance into the pause state by setting the
+	 *  pause bit to true.
+	 */
+	dma->pause = TRUE;
+
+	local_irq_restore(flags);
+
+	/*
+	 *  Success.
+	 */
+	return(0);
+}
+
+/*****************************************************************************
+ *
+ *  int dma_start(int handle, unsigned int channels, unsigned int * handles)
+ *
+ *  Description: Initiate a transfer on up to 3 channels.
+ *
+ *  handle:	 handle for the channel to initiate transfer on.
+ *  channels:   number of channels to initiate transfers on.
+ *  handles:	pointer to an array of handles, one for each channel which
+ *			   is to be started.
+ *
+ ****************************************************************************/
+int
+ep93xx_dma_start(int handle, unsigned int channels, unsigned int * handles)
+{
+	ep93xx_dma_t * dma_pointers[3];
+	unsigned int M2P_reg_bases[3];
+	unsigned int loop, flags, uiCONTROL;
+	int  channel;
+
+	/*
+	 *  Get the DMA hw channel # from the handle.
+	 */
+	channel = dma_get_channel_from_handle(handle);
+
+	/*
+	 *  See if this is a valid handle.
+	 */
+	if (channel < 0) {
+		printk(KERN_ERR "DMA Start: Invalid dma handle.\n");
+		return(-EINVAL);
+	}
+
+	if (channels < 1) {
+		printk(KERN_ERR "DMA Start: Invalid parameter.\n");
+		return(-EINVAL);
+	}
+
+	DPRINTK("DMA Start \n");
+
+	/*
+	 *  Mask off registers.
+	 */
+	local_irq_save(flags);
+
+	/*
+	 *  Check if this is a start multiple.
+	 */
+	if (channels > 1) {
+		DPRINTK("DMA ERROR: Start, multiple start not supported yet \n");
+		return(-1);
+	} else {
+		/*
+		 *  Check if this channel is already transferring.
+		 */
+		if (dma_chan[channel].xfer_enable && !dma_chan[channel].pause) {
+			printk(KERN_ERR
+				   "DMA Start: Invalid command for channel %d.\n", channel);
+
+			/*
+			 *  Unmask irqs
+			 */
+			local_irq_restore(flags);
+
+			/*
+			 *  This channel is already transferring, so return an error.
+			 */
+			return(-EINVAL);
+		}
+
+		/*
+		 *  If this is an M2M channel, call a different function.
+		 */
+		if (channel >= 10) {
+			/*
+			 *  Unmask irqs
+			 */
+			local_irq_restore(flags);
+
+			/*
+			 *  Call the m2m start function.  Only start one channel.
+			 */
+			return(dma_start_m2m(channel, &dma_chan[channel]));
+		}
+
+		/*
+		 *  Make sure the channel has at least one buffer in the queue.
+		 */
+		if (dma_chan[channel].new_buffers < 1) {
+			DPRINTK("DMA Start: Channel starved.\n");
+
+			/*
+			 *  This channel does not have enough buffers queued up,
+			 *  so enter the pause by starvation state.
+			 */
+			dma_chan[channel].xfer_enable = TRUE;
+			dma_chan[channel].pause = TRUE;
+
+			/*
+			 *  Unmask irqs
+			 */
+			local_irq_restore(flags);
+
+			/*
+			 *  Success.
+			 */
+			return(0);
+		}
+
+		/*
+		 *  Set up a dma instance pointer for this dma channel.
+		 */
+		dma_pointers[0] = &dma_chan[channel];
+
+		/*
+		 * Set up a pointer to the register set for this channel.
+		 */
+		M2P_reg_bases[0] = dma_pointers[0]->reg_base;
+	}
+
+	/*
+	 *  Setup both MAXCNT registers with values from the next two buffers
+	 *  in the queue, and enable the next frame buffer interrupt on the channel.
+	 */
+	for (loop = 0; loop < channels; loop++) {
+		/*
+		 *  By default we enable the next frame buffer interrupt.
+		 */
+		uiCONTROL = inl(M2P_reg_bases[loop]+M2P_OFFSET_CONTROL);
+		uiCONTROL |= CONTROL_M2P_NFBINTEN;
+		outl( uiCONTROL, M2P_reg_bases[loop]+M2P_OFFSET_CONTROL );
+
+		/*
+		 *  Check if we need to restore a paused transfer.
+		 */
+		if (dma_pointers[loop]->pause_buf.buf_id != -1)
+			outl( dma_pointers[loop]->pause_buf.size,
+			      M2P_reg_bases[loop]+M2P_OFFSET_MAXCNT0 );
+		else
+			outl( dma_pointers[loop]->buffer_queue[dma_pointers[loop]->current_buffer].size,
+			      M2P_reg_bases[loop]+M2P_OFFSET_MAXCNT0 );
+	}
+
+	for (loop = 0; loop < channels; loop++) {
+		/*
+		 *  Enable the specified dma channels.
+		 */
+		uiCONTROL = inl(M2P_reg_bases[loop]+M2P_OFFSET_CONTROL);
+		uiCONTROL |= CONTROL_M2P_ENABLE;
+		outl( uiCONTROL, M2P_reg_bases[loop]+M2P_OFFSET_CONTROL );
+
+		/*
+		 *  Update the dma channel instance transfer state.
+		 */
+		dma_pointers[loop]->xfer_enable = TRUE;
+		dma_pointers[loop]->pause = FALSE;
+
+		if (dma_pointers[loop]->pause_buf.buf_id == -1)
+			dma_pointers[loop]->new_buffers--;
+	}
+
+	/*
+	 *  Program up the BASE0 registers for all specified channels, this
+	 *  will initiate transfers on all specified channels.
+	 */
+	for (loop = 0; loop < channels; loop++)
+		/*
+		 *  Check if we need to restore a paused transfer.
+		 */
+		if (dma_pointers[loop]->pause_buf.buf_id != -1) {
+			outl( dma_pointers[loop]->pause_buf.source,
+			      M2P_reg_bases[loop]+M2P_OFFSET_BASE0 );
+
+			/*
+			 *  Set the pause buffer to NULL
+			 */
+			dma_pointers[loop]->pause_buf.buf_id = -1;
+			dma_pointers[loop]->pause_buf.size = 0;
+		} else
+			outl( dma_pointers[loop]->buffer_queue[
+				  dma_pointers[loop]->current_buffer].source,
+			      M2P_reg_bases[loop]+M2P_OFFSET_BASE0 );
+
+	/*
+	 *  Before restoring irqs setup the second MAXCNT/BASE
+	 *  register with a second buffer.
+	 */
+	for (loop = 0; loop < channels; loop++)
+		if (dma_pointers[loop]->new_buffers) {
+			outl( dma_pointers[loop]->buffer_queue[
+				  (dma_pointers[loop]->current_buffer + 1) %
+				  MAX_EP93XX_DMA_BUFFERS].size,
+			      M2P_reg_bases[loop]+M2P_OFFSET_MAXCNT1 );
+
+			outl( dma_pointers[loop]->buffer_queue[
+				  (dma_pointers[loop]->current_buffer + 1) %
+				  MAX_EP93XX_DMA_BUFFERS].source,
+			      M2P_reg_bases[loop]+M2P_OFFSET_BASE1 );
+		}
+
+	/*
+	  DPRINTK("DMA - It's been started!!");
+	  DPRINTK("STATUS - 0x%x \n",	 inl(M2P_reg_base+M2P_OFFSET_STATUS) );
+	  DPRINTK("CONTROL - 0x%x \n",	inl(M2P_reg_base+M2P_OFFSET_CONTROL) );
+	  DPRINTK("REMAIN - 0x%x \n",	 inl(M2P_reg_base+M2P_OFFSET_REMAIN) );
+	  DPRINTK("PPALLOC - 0x%x \n",	inl(M2P_reg_base+M2P_OFFSET_PPALLOC) );
+	  DPRINTK("BASE0 - 0x%x \n",	  inl(M2P_reg_base+M2P_OFFSET_BASE0) );
+	  DPRINTK("MAXCNT0 - 0x%x \n",	inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) );
+	  DPRINTK("CURRENT0 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT0) );
+	  DPRINTK("BASE1 - 0x%x \n",	  inl(M2P_reg_base+M2P_OFFSET_BASE1) );
+	  DPRINTK("MAXCNT1 - 0x%x \n",	inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) );
+	  DPRINTK("CURRENT1 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT1) );
+
+	  DPRINTK("Pause - %d \n", dma_pointers[0]->pause);
+	  DPRINTK("xfer_enable - %d \n", dma_pointers[0]->xfer_enable);
+	  DPRINTK("total bytes - 0x%x \n", dma_pointers[0]->total_bytes);
+	  DPRINTK("total buffer - %d \n", dma_pointers[0]->total_buffers);
+	  DPRINTK("new buffers - %d \n", dma_pointers[0]->new_buffers);
+	  DPRINTK("current buffer - %d \n", dma_pointers[0]->current_buffer);
+	  DPRINTK("last buffer - %d \n", dma_pointers[0]->last_buffer);
+	  DPRINTK("used buffers - %d \n", dma_pointers[0]->used_buffers);
+	*/
+	/*
+	 *  Unmask irqs
+	 */
+	local_irq_restore(flags);
+
+	/*
+	 *  Success.
+	 */
+	return(0);
+}
+
+/*****************************************************************************
+ *
+ *  int ep93xx_dma_add_buffer(int handle, unsigned int * address,
+ *						 unsigned int size, unsigned int last)
+ *
+ *  Description: Add a buffer entry to the DMA buffer queue.
+ *
+ *  handle:	 handle for the channel to add this buffer to.
+ *  address:	Pointer to an integer which is the start address of the
+ *			  buffer which is to be added to the queue.
+ *  size:	   size of the buffer in bytes.
+ *  last:	   1 if this is the last buffer in this stream, 0 otherwise.
+ *
+ ****************************************************************************/
+int
+ep93xx_dma_add_buffer(int handle, unsigned int source, unsigned int dest,
+		      unsigned int size, unsigned int last,
+		      unsigned int buf_id)
+{
+	unsigned int flags;
+	ep93xx_dma_t * dma;
+	int  channel;
+
+	/*
+	 *  Get the DMA hw channel # from the handle.
+	 */
+	channel = dma_get_channel_from_handle(handle);
+
+	/*
+	 *  See if this is a valid handle.
+	 */
+	if (channel < 0) {
+		printk(KERN_ERR
+			   "DMA Add Buffer: Invalid dma handle.\n");
+		return(-EINVAL);
+	}
+
+	/*
+	 *  Get a pointer to the dma instance.
+	 */
+	dma = &dma_chan[channel];
+
+	/*
+	 *  Mask interrupts and hold on to the original state.
+	 */
+	local_irq_save(flags);
+
+	/*
+	 *  If the buffer queue is full, last_buffer is the same as current_buffer and
+	 *  we're not tranfering, or last_buffer is pointing to a used buffer, then exit.
+	 *  TODO: do I need to do any more checks?
+	 */
+	if (dma->total_buffers >= MAX_EP93XX_DMA_BUFFERS) {
+		/*
+		 *  Restore the state of the irqs
+		 */
+		local_irq_restore(flags);
+
+		/*
+		 *  Fail.
+		 */
+		return(-1);
+	}
+
+	/*
+	 *  Add this buffer to the queue
+	 */
+	dma->buffer_queue[dma->last_buffer].source = source;
+	dma->buffer_queue[dma->last_buffer].dest = dest;
+	dma->buffer_queue[dma->last_buffer].size = size;
+	dma->buffer_queue[dma->last_buffer].last = last;
+	dma->buffer_queue[dma->last_buffer].buf_id = buf_id;
+
+	/*
+	 *  Reset the used field of the buffer structure.
+	 */
+	dma->buffer_queue[dma->last_buffer].used = FALSE;
+
+	/*
+	 *  Increment the End Item Pointer.
+	 */
+	dma->last_buffer = (dma->last_buffer + 1) % MAX_EP93XX_DMA_BUFFERS;
+
+	/*
+	 *  Increment the new buffers counter and the total buffers counter
+	 */
+	dma->new_buffers++;
+	dma->total_buffers++;
+
+	/*
+	 *  restore the interrupt state.
+	 */
+	local_irq_restore(flags);
+
+	/*
+	 *  Check if the channel was starved into a stopped state.
+	 */
+	if (dma->pause && dma->xfer_enable) {
+		if (dma->new_buffers >= 1) {
+			DPRINTK("DMA - calling start from add after starve. \n");
+
+			/*
+			 *  The channel was starved into a stopped state, and we've got
+			 *  2 new buffers, so start tranferring again.
+			 */
+			ep93xx_dma_start(handle, 1, 0);
+		}
+	}
+
+	/*
+	 *  Success.
+	 */
+	return(0);
+}
+
+/*****************************************************************************
+ *
+ *  int ep93xx_dma_remove_buffer(int handle, unsigned int * address,
+ *								unsigned int * size)
+ *
+ *  Description: Remove a buffer entry from the DMA buffer queue. If
+ *			   buffer was removed successfully, return 0, otherwise
+ *			   return -1.
+ *
+ *  handle:	 handle for the channel to remove a buffer from.
+ *  address:	Pointer to an integer which is filled in with the start
+ *			  address of the removed buffer.
+ *  size:	   Pointer to an integer which is filled in with the size in
+ *			  bytes of the removed buffer.
+ *
+ ****************************************************************************/
+int
+ep93xx_dma_remove_buffer(int handle, unsigned int * buf_id)
+{
+	unsigned int test;
+	unsigned int loop;
+	int return_val = -1;
+	unsigned int flags;
+	ep93xx_dma_t *dma;
+	int  channel;
+
+	/*
+	 *  Get the DMA hw channel # from the handle.
+	 */
+	channel = dma_get_channel_from_handle(handle);
+
+	/*
+	 *  See if this is a valid handle.
+	 */
+	if (channel < 0) {
+		printk(KERN_ERR
+			   "DMA Remove Buffer: Invalid dma handle.\n");
+		return(-EINVAL);
+	}
+
+	dma = &dma_chan[channel];
+
+	/*
+	 *  Mask interrupts and hold on to the original state.
+	 */
+	local_irq_save(flags);
+
+	/*
+	 *  Make sure there are used buffers to be returned.
+	 */
+	if (dma->used_buffers) {
+		test = dma->last_buffer;
+
+		for (loop = 0; loop < MAX_EP93XX_DMA_BUFFERS; loop++) {
+			if (dma->buffer_queue[test].used && (dma->buffer_queue[test].buf_id != -1)) {
+				/*DPRINTK("buffer %d used \n", test); */
+
+				/*
+				 *  This is a used buffer, fill in the buf_id pointer
+				 *  with the buf_id for this buffer.
+				 */
+				*buf_id = dma->buffer_queue[test].buf_id;
+
+				/*
+				 *  Reset this buffer structure
+				 */
+				dma->buffer_queue[test].buf_id = -1;
+
+				/*
+				 *  Decrement the used buffer counter, and the total buffer counter.
+				 */
+				dma->used_buffers--;
+				dma->total_buffers--;
+
+				/*
+				 *  Successful removal of a buffer, so set the return
+				 *  value to 0, then exit this loop.
+				 */
+				return_val = 0;
+				break;
+			}
+
+			/*
+			 *  This buffer isn't used, let's see if the next one is.
+			 */
+			test = (test + 1) % MAX_EP93XX_DMA_BUFFERS;
+		}
+	}
+
+	/*
+	 *  Restore interrupts.
+	 */
+	local_irq_restore(flags);
+
+	/*
+	 *  Success.
+	 */
+	return(return_val);
+}
+
+/*****************************************************************************
+ *
+ *  int ep93xx_dma_pause(int handle, unsigned int channels,
+ *					   unsigned int * handles)
+ *
+ *  Description: Disable any ongoing transfer for the given channel, retaining
+ *			   the state of the current buffer transaction so that upon
+ *			   resume, the dma will continue where it left off.
+ *
+ *  handle:	 Handle for the channel to be paused.  If this is a pause for
+ *			  for multiple channels, handle is a valid handle for one of
+ *			  the channels to be paused.
+ *  channels:   number of channel to pause transfers on.
+ *  handles:	Pointer to an array of handles, one for each channel which
+ *			  to be paused.  If this pause is intended only for one
+ *			  channel, this field should be set to NULL.
+ *
+ ****************************************************************************/
+int
+ep93xx_dma_pause(int handle, unsigned int channels, unsigned int * handles)
+{
+	unsigned int flags;
+	ep93xx_dma_t * dma;
+	int channel;
+
+	DPRINTK("ep93xx_dma_pause \n");
+
+	/*
+	 *  Mask interrupts and hold on to the original state.
+	 */
+	local_irq_save(flags);
+
+	/*
+	 *  Get the DMA hw channel # from the handle.
+	 */
+	channel = dma_get_channel_from_handle(handle);
+
+	/*
+	 *  See if this is a valid handle.
+	 */
+	if (channel < 0) {
+		/*
+		 *  restore interrupts.
+		 */
+		local_irq_restore(flags);
+
+		printk(KERN_ERR
+			   "DMA Pause: Invalid dma handle.\n");
+
+		/*
+		 *  Fail.
+		 */
+		return(-EINVAL);
+	}
+
+	DPRINTK("DMA %d: pause \n", channel);
+
+	/*
+	 *  Set up a pointer to the dma instance data.
+	 */
+	dma = &dma_chan[channel];
+
+	/*
+	 *  Check if we're already paused.
+	 */
+	if (dma->pause) {
+		/*
+		 *  We're paused, but are we stopped?
+		 */
+		if (dma->xfer_enable)
+			/*
+			 *  Put the channel in the stopped state.
+			 */
+			dma->xfer_enable = FALSE;
+
+		DPRINTK("DMA Pause - already paused.");
+	} else {
+		/*
+		 *  Put the channel into the stopped state.
+		 */
+		dma->xfer_enable = FALSE;
+		dma->pause = TRUE;
+	}
+
+	/*
+	 *  restore interrupts.
+	 */
+	local_irq_restore(flags);
+
+	/*
+	 *  Already paused, so exit.
+	 */
+	return(0);
+}
+
+/*****************************************************************************
+ *
+ *  void ep93xx_dma_flush(int handle)
+ *
+ *  Description: Flushes all queued buffers and transfers in progress
+ *			   for the given channel.  Return the buffer entries
+ *			   to the calling function.
+ *
+ *  handle:	 handle for the channel for which the flush is intended.
+ *
+ ****************************************************************************/
+int
+ep93xx_dma_flush(int handle)
+{
+	unsigned int loop, flags;
+	ep93xx_dma_t * dma;
+	int  channel;
+	unsigned int M2P_reg_base;
+
+	/*
+	 *  Get the DMA hw channel # from the handle.
+	 */
+	channel = dma_get_channel_from_handle(handle);
+
+	/*
+	 *  See if this is a valid handle.
+	 */
+	if (channel < 0) {
+		printk(KERN_ERR "DMA Flush: Invalid dma handle.\n");
+		return(-EINVAL);
+	}
+
+	DPRINTK("DMA %d: flush \n", channel);
+
+	/*
+	 *  Set up a pointer to the dma instance data for this channel
+	 */
+	dma = &dma_chan[channel];
+
+	/*
+	 *  Mask interrupts and hold on to the original state.
+	 */
+	local_irq_save(flags);
+
+	for (loop = 0; loop < MAX_EP93XX_DMA_BUFFERS; loop++)
+		dma->buffer_queue[loop].buf_id = -1;
+
+	/*
+	 *  Set the Current and Last item to zero.
+	 */
+	dma->current_buffer = 0;
+	dma->last_buffer = 0;
+
+	/*
+	 *  Reset the Buffer counters
+	 */
+	dma->used_buffers = 0;
+	dma->new_buffers = 0;
+	dma->total_buffers = 0;
+
+	/*
+	 *  reset the Total bytes counter.
+	 */
+	dma->total_bytes = 0;
+
+	M2P_reg_base = dma_chan[channel].reg_base;
+
+	/*
+	 *  restore interrupts.
+	 */
+	local_irq_restore(flags);
+
+	/*
+	 *  Success.
+	 */
+	return(0);
+}
+
+/*****************************************************************************
+ *
+ *  int ep93xx_dma_queue_full(int handle)
+ *
+ *  Description: Query to determine if the DMA queue of buffers for
+ *			  a given channel is full.
+ *			  0 = queue is full
+ *			  1 = queue is not full
+ *
+ *  handle:	 handle for the channel to query.
+ *
+ ****************************************************************************/
+int
+ep93xx_dma_queue_full(int handle)
+{
+	int list_full = 0;
+	unsigned int flags;
+	int  channel;
+
+	/*
+	 *  Get the DMA hw channel # from the handle.
+	 */
+	channel = dma_get_channel_from_handle(handle);
+
+	/*
+	 *  See if this is a valid handle.
+	 */
+	if (channel < 0) {
+		printk(KERN_ERR "DMA Queue Full: Invalid dma handle.\n");
+		return(-EINVAL);
+	}
+
+	DPRINTK("DMA %d: queue full \n", channel);
+
+	/*
+	 *  Mask interrupts and hold on to the original state.
+	 */
+	local_irq_save(flags);
+
+	/*
+	 *  If the last item is equal to the used item then
+	 *  the queue is full.
+	 */
+	if (dma_chan[channel].total_buffers < MAX_EP93XX_DMA_BUFFERS)
+		list_full =  FALSE;
+	else
+		list_full = TRUE;
+
+	/*
+	 *  restore interrupts.
+	 */
+	local_irq_restore(flags);
+
+	return(list_full);
+}
+
+/*****************************************************************************
+ *
+ *  int ep93xx_dma_get_position()
+ *
+ *  Description:  Takes two integer pointers and fills them with the start
+ *                and current address of the buffer currently transferring
+ *                on the specified DMA channel.
+ *
+ *  handle         handle for the channel to query.
+ *  *buf_id        buffer id for the current buffer transferring on the
+ *                 dma channel.
+ *  *total         total bytes transferred on the channel.  Only counts  
+ *                 whole buffers transferred.
+ *  *current_frac  number of bytes transferred so far in the current buffer.
+ ****************************************************************************/
+int
+ep93xx_dma_get_position(int handle, unsigned int * buf_id,
+                        unsigned int * total, unsigned int * current_frac )
+{
+	int  channel;
+	ep93xx_dma_t * dma;
+	unsigned int buf_id1, total1, current_frac1, buf_id2, total2;
+	unsigned int Status, NextBuffer, StateIsBufNext, M2P_reg_base=0;
+	unsigned int pause1, pause2;
+
+	/*
+	 *  Get the DMA hw channel # from the handle.  See if this is a 
+	 *  valid handle.
+	 */
+	channel = dma_get_channel_from_handle(handle);
+	if (channel < 0) {
+		printk(KERN_ERR "DMA Get Position: Invalid dma handle.\n");
+		return(-EINVAL);
+	}
+
+	dma = &dma_chan[channel];
+
+	/*
+	 * If DMA moves to a new buffer in the middle of us grabbing the 
+	 * buffer info, then do it over again.
+	 */
+	do{
+		buf_id1 = dma->buffer_queue[dma->current_buffer].buf_id;
+		total1  = dma->total_bytes;
+		pause1  = dma->pause;
+
+		if (channel < 10) {
+			// M2P
+			M2P_reg_base = dma->reg_base;
+
+			Status = inl(M2P_reg_base+M2P_OFFSET_STATUS);
+
+			NextBuffer = ((Status & STATUS_M2P_NEXTBUFFER) != 0);
+
+			StateIsBufNext = ((Status & STATUS_M2P_CURRENT_MASK) == 
+			                  STATUS_M2P_DMA_BUF_NEXT);
+			
+			if( NextBuffer ^ StateIsBufNext )
+				current_frac1 = inl(M2P_reg_base+M2P_OFFSET_CURRENT1) -
+				                inl(M2P_reg_base+M2P_OFFSET_BASE1);	
+			else
+				current_frac1 = inl(M2P_reg_base+M2P_OFFSET_CURRENT0) -
+				                inl(M2P_reg_base+M2P_OFFSET_BASE0);	
+			
+		} else { 
+			// M2M - TODO implement this for M2M
+			current_frac1 = 0;
+		}
+		
+		buf_id2 = dma->buffer_queue[dma->current_buffer].buf_id;
+		total2 = dma->total_bytes;
+		pause2  = dma->pause;
+
+	} while ( (buf_id1 != buf_id2) || (total1 != total2) || (pause1 != pause2) );
+
+	if (pause1)
+		current_frac1 = 0;
+
+	if (buf_id)
+		*buf_id = buf_id1;
+
+	if (total)
+		*total  = total1;
+
+	if (current_frac)
+		*current_frac = current_frac1;
+	
+//	DPRINTK("DMA buf_id %d, total %d, frac %d\n", buf_id1, total1, current_frac1);
+
+	/*
+	 *  Success.
+	 */
+	return(0);
+}
+
+/*****************************************************************************
+ *
+ *  int ep93xx_dma_get_total(int handle)
+ *
+ *  Description:	Returns the total number of bytes transferred on the
+ *			specified channel since the channel was requested.
+ *
+ *  handle:	 handle for the channel to query.
+ *
+ ****************************************************************************/
+int
+ep93xx_dma_get_total(int handle)
+{
+	int  channel;
+
+	/*
+	 *  Get the DMA hw channel # from the handle.
+	 */
+	channel = dma_get_channel_from_handle(handle);
+
+	/*
+	 *  See if this is a valid handle.
+	 */
+	if (channel < 0) {
+		printk(KERN_ERR "DMA Get Total: Invalid dma handle.\n");
+		return(-EINVAL);
+	}
+
+	DPRINTK("DMA %d: total: %d \n", channel, dma_chan[channel].total_bytes);
+
+	/*
+	 *  Return the total number of bytes transferred on this channel since
+	 *  it was requested.
+	 */
+	return(dma_chan[channel].total_bytes);
+}
+
+/*****************************************************************************
+ *
+ *  int ep93xx_dma_is_done(int handle)
+ *
+ *  Description:	Determines if the specified channel is done
+ *			transferring the requested data.
+ *
+ *  handle:	 handle for the channel to query.
+ *
+ ****************************************************************************/
+int
+ep93xx_dma_is_done(int handle)
+{
+	ep93xx_dma_t *dma;
+	int channel;
+
+	/*
+	 *  Get the DMA hw channel # from the handle.
+	 */
+	channel = dma_get_channel_from_handle(handle);
+
+	/*
+	 *  See if this is a valid handle.
+	 */
+	if (channel < 0) {
+		printk(KERN_ERR "ep93xx_dma_is_done: Invalid dma handle.\n");
+		return(-EINVAL);
+	}
+
+        /*
+         * Get a pointer to the DMA channel state structure.
+         */
+        dma = &dma_chan[channel];
+
+        /*
+         * See if there are any buffers remaining to be provided to the HW.
+         */
+        if (dma->new_buffers)
+            return 0;
+
+        /*
+         * See if this is a M2P or M2M channel.
+         */
+        if (channel < 10) {
+            /*
+             * If the bytes remaining register of the HW is not zero, then
+             * there is more work to be done.
+             */
+            if (inl(dma->reg_base + M2P_OFFSET_REMAIN) != 0)
+                return 0;
+        } else {
+            /*
+             * If either byte count register in the HW is not zero, then there
+             * is more work to be done.
+             */
+            if ((inl(dma->reg_base + M2M_OFFSET_BCR0) != 0) ||
+                (inl(dma->reg_base + M2M_OFFSET_BCR1) != 0))
+                return 0;
+        }
+
+        /*
+         * The DMA is complete.
+         */
+        return 1;
+}
+
+/*****************************************************************************
+ * ep93xx_dma_request
+ *
+ * Description: This function will allocate a DMA channel for a particular
+ * hardware peripheral.  Before initiating a transfer on the allocated
+ * channel, the channel must be set up and buffers have to queued up.
+ *
+ *  handle:	 pointer to an integer which is filled in with a unique
+ *			  handle for this instance of the dma interface.
+ *  device_id   string with the device name, primarily used by /proc.
+ *  device	  hardware device ID for which the requested dma channel will
+ *			  transfer data.
+ *
+ ****************************************************************************/
+int
+ep93xx_dma_request(int * handle, const char *device_id,
+				   ep93xx_dma_dev_t device)
+{
+	ep93xx_dma_t *dma = NULL;
+	int channel;
+	unsigned int error = 0;
+	unsigned int loop;
+	unsigned int M2P_reg_base;
+
+	/*
+	 *  Check if the device requesting a DMA channel is a valid device.
+	 */
+	if ((device >= UNDEF) || (device < 0))
+		return(-ENODEV);
+
+	/*
+	 *  We've got a valid hardware device requesting a DMA channel.
+	 *  Now check if the device should open an M2P or M2M channel
+	 */
+	if (device < 20)
+		channel = dma_open_m2p(device);
+	else
+		channel = dma_open_m2m(device);
+
+	/*
+	 *  Check if we successfully opened a DMA channel
+	 */
+	if (channel < 0) {
+		printk(KERN_ERR "%s: Could not open dma channel for this device.\n",
+			   device_id);
+		return(-EBUSY);
+	}
+
+	dma = &dma_chan[channel];
+
+	/*
+	 *  Request the appropriate IRQ for the specified channel
+	 */
+	if (channel < 10)
+		error = request_irq(dma->irq, dma_m2p_irq_handler,
+				    SA_INTERRUPT, device_id, (void *) dma);
+	else
+		error = request_irq(dma->irq, &dma_m2m_irq_handler,
+				    SA_INTERRUPT, device_id, (void *) dma);
+
+	/*
+	 *  Check for any errors during the irq request
+	 */
+	if (error) {
+		printk(KERN_ERR "%s: unable to request IRQ %d for DMA channel\n",
+			   device_id, dma->irq);
+		return(error);
+	}
+
+	/*
+	 *  Generate a valid handle and exit.
+	 *
+	 *  Increment the last valid handle.
+	 *  Check for wraparound (unlikely, but we like to be complete).
+	 */
+	dma->last_valid_handle++;
+
+	if ( (dma->last_valid_handle & DMA_HANDLE_SPECIFIER_MASK) !=
+	     (channel << 28) )
+		dma->last_valid_handle = (channel << 28) + 1;
+
+	/*
+	 *  Fill in the handle pointer with a valid handle for
+	 *  this dma channel instance.
+	 */
+	*handle = dma->last_valid_handle;
+
+	DPRINTK("Handle for channel %d: 0x%x\n", channel, *handle);
+
+	/*
+	 * Save the device ID and device name.
+	 */
+	dma->device = device;
+	dma->device_id = device_id;
+
+	/*
+	 *  Init all fields within the dma instance.
+	 */
+	for (loop = 0; loop < MAX_EP93XX_DMA_BUFFERS; loop++)
+		dma->buffer_queue[loop].buf_id = -1;
+
+	/*
+	 *  Initialize all buffer queue variables.
+	 */
+	dma->current_buffer = 0;
+	dma->last_buffer = 0;
+
+	dma->new_buffers = 0;
+	dma->used_buffers = 0;
+	dma->total_buffers = 0;
+
+	/*
+	 *  Initialize the total bytes variable
+	 */
+	dma->total_bytes = 0;
+
+	/*
+	 *  Initialize the transfer and pause state variables to 0.
+	 */
+	dma->xfer_enable = 0;
+
+	dma->pause = 0;
+
+	/*
+	 *  Initialize the pause buffer structure.
+	 */
+	dma->pause_buf.buf_id = -1;
+
+	/*
+	 *  Initialize the callback function and user data fields.
+	 */
+	dma->callback = NULL;
+
+	/*
+	 * User data used as a parameter for the Callback function.  The user
+	 * sets up the data and sends it with the callback function.
+	 */
+	dma->user_data = 0;
+
+	M2P_reg_base = dma_chan[channel].reg_base;
+
+	/*
+	 *  Debugging message.
+	 */
+	DPRINTK("Successfully requested dma channel %d\n", channel);
+	DPRINTK("STATUS - 0x%x \n",	 inl(M2P_reg_base+M2P_OFFSET_STATUS) );
+	DPRINTK("CONTROL - 0x%x \n",	inl(M2P_reg_base+M2P_OFFSET_CONTROL) );
+	DPRINTK("REMAIN - 0x%x \n",	 inl(M2P_reg_base+M2P_OFFSET_REMAIN) );
+	DPRINTK("PPALLOC - 0x%x \n",	inl(M2P_reg_base+M2P_OFFSET_PPALLOC) );
+	DPRINTK("BASE0 - 0x%x \n",	  inl(M2P_reg_base+M2P_OFFSET_BASE0) );
+	DPRINTK("MAXCNT0 - 0x%x \n",	inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) );
+	DPRINTK("CURRENT0 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT0) );
+	DPRINTK("BASE1 - 0x%x \n",	  inl(M2P_reg_base+M2P_OFFSET_BASE1) );
+	DPRINTK("MAXCNT1 - 0x%x \n",	inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) );
+	DPRINTK("CURRENT1 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT1) );
+
+	DPRINTK("Buffer	source	   size	   last	   used \n");
+	for (loop = 0; loop < 5; loop ++)
+		DPRINTK("%d		0x%x		 0x%x		%d		 %d \n",
+			loop, dma->buffer_queue[loop].source, dma->buffer_queue[loop].size,
+			dma->buffer_queue[loop].last, dma->buffer_queue[loop].used);
+	DPRINTK("pause	 0x%x		 0x%x		%d		 %d \n",
+		dma->pause_buf.source, dma->pause_buf.size,
+		dma->pause_buf.last, dma->pause_buf.used);
+
+	DPRINTK("Pause - %d \n", dma->pause);
+	DPRINTK("xfer_enable - %d \n", dma->xfer_enable);
+	DPRINTK("total bytes - 0x%x \n", dma->total_bytes);
+	DPRINTK("total buffer - %d \n", dma->total_buffers);
+	DPRINTK("new buffers - %d \n", dma->new_buffers);
+	DPRINTK("current buffer - %d \n", dma->current_buffer);
+	DPRINTK("last buffer - %d \n", dma->last_buffer);
+	DPRINTK("used buffers - %d \n", dma->used_buffers);
+
+	DPRINTK("CURRENT1 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT1) );
+	DPRINTK("VIC0IRQSTATUS - 0x%x, VIC0INTENABLE - 0x%x \n",
+		*(unsigned int *)(VIC0IRQSTATUS),
+		*(unsigned int *)(VIC0INTENABLE));
+
+	/*
+	 *  Success.
+	 */
+	return(0);
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_dma_free
+ *
+ * Description: This function will free the dma channel for future requests.
+ *
+ *  handle:	 handle for the channel to be freed.
+ *
+ ****************************************************************************/
+int
+ep93xx_dma_free(int handle)
+{
+	ep93xx_dma_t *dma;
+	unsigned int M2M_reg_base, M2P_reg_base, uiCONTROL;
+	int channel;
+
+	/*
+	 *  Get the DMA hw channel # from the handle.
+	 */
+	channel = dma_get_channel_from_handle(handle);
+
+	/*
+	 *  See if this is a valid handle.
+	 */
+	if (channel < 0) {
+		printk(KERN_ERR "DMA Free: Invalid dma handle.\n");
+		return(-EINVAL);
+	}
+
+	/*
+	 *  Get a pointer to the dma instance.
+	 */
+	dma = &dma_chan[channel];
+
+	/*
+	 *  Disable the dma channel
+	 */
+	if (channel < 10) {
+		/*
+		 *  M2P channel
+		 */
+		M2P_reg_base = dma->reg_base;
+
+		uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
+		uiCONTROL &= ~CONTROL_M2P_ENABLE;
+		outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
+	} else {
+		/*
+		 *  M2M channel
+		 */
+		M2M_reg_base = dma->reg_base;
+
+		uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
+		uiCONTROL &= ~CONTROL_M2M_ENABLE;
+		outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
+	}
+
+	/*
+	 *  Free the interrupt servicing this dma channel
+	 */
+	free_irq(dma->irq, (void *) dma);
+
+	/*
+	 *  Decrement the reference count for this instance of the dma interface
+	 */
+	dma->ref_count--;
+
+	/*
+	 *  Set the transfer and pause state variables to 0
+	 *  (unititialized state).
+	 */
+	dma->xfer_enable = 0;
+	dma->pause = 0;
+
+	/*
+	 *  Debugging message.
+	 */
+	DPRINTK("Successfully freed dma channel %d\n", channel);
+
+	/*
+	 *  Success.
+	 */
+	return(0);
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_dma_init(void)
+ *
+ * Description: This function is called during system initialization to
+ * setup the interrupt number and register set base address for each DMA
+ * channel.
+ *
+ ****************************************************************************/
+static int __init
+ep93xx_dma_init(void)
+{
+	int channel;
+
+	/*
+	 * Init some values in each dma instance.
+	 */
+	for (channel = 0; channel < MAX_EP93XX_DMA_CHANNELS; channel++) {
+		/*
+		 *  IRQ for the specified dma channel.
+		 */
+		dma_chan[channel].irq = IRQ_DMAM2P0 + channel;
+
+		/*
+		 *  Initial value of the dma channel handle.
+		 */
+		dma_chan[channel].last_valid_handle = channel << 28;
+
+		/*
+		 *  Give the instance a pointer to the dma channel register
+		 *  base.
+		 */
+		if (channel < 10)
+			dma_chan[channel].reg_base = DMAM2PChannelBase[channel];
+		else
+			dma_chan[channel].reg_base = DMAM2MChannelBase[channel - 10];
+
+		/*
+		 *  Initialize the reference count for this channel.
+		 */
+		dma_chan[channel].ref_count = 0;
+	}
+
+	DPRINTK("DMA Interface intitialization complete\n");
+
+	/*
+	 * Success
+	 */
+	return 0;
+}
+
+__initcall(ep93xx_dma_init);
diff -urN linux-2.4.29/arch/arm/mach-ep93xx/dma_ep93xx.h linux-2.4.29-uc1/arch/arm/mach-ep93xx/dma_ep93xx.h
--- linux-2.4.29/arch/arm/mach-ep93xx/dma_ep93xx.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ep93xx/dma_ep93xx.h	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,195 @@
+/*****************************************************************************
+ *
+ * arch/arm/mach-ep93xx/dma_ep93xx.h
+ *
+ * DESCRIPTION:    93XX DMA controller API private defintions.
+ *
+ * Copyright Cirrus Logic Corporation, 2003.  All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ ****************************************************************************/
+#ifndef _EP93XX_DMA_H_
+#define _EP93XX_DMA_H_
+
+#define MAX_EP93XX_DMA_BUFFERS      128
+
+#ifndef TRUE
+#define TRUE                        1
+#endif
+
+#ifndef FALSE
+#define FALSE                       0
+#endif
+
+#ifndef NULL
+#define NULL                        0
+#endif
+
+/*****************************************************************************
+ *
+ * DMA buffer structure type.
+ *
+ ****************************************************************************/
+typedef struct ep93xx_dma_buffer_s
+{
+    unsigned int    source;     /* buffer physical source address.          */
+    unsigned int    dest;       /* buffer physical destination address,     */
+                                /* only used with the 2 M2M channels.       */
+    unsigned int    size;       /* buffer size in bytes                     */
+    unsigned int    last;       /* 1 if this is the last buffer             */
+                                /* in this transaction.  If 1,              */
+                                /* disable the NFBint so we aren't          */
+                                /* interrupted for another buffer           */
+                                /* when we know there won't be another.     */
+    unsigned int    used;       /* This field is set to 1 by the DMA        */
+                                /* interface after the buffer is transferred*/
+    int    buf_id;              /* unique identifyer specified by the       */
+                                /* the driver which requested the dma       */
+} ep93xx_dma_buffer_t;
+
+typedef ep93xx_dma_buffer_t * ep93xx_dma_buffer_p;
+
+/*****************************************************************************
+ *
+ * Instance definition for the DMA interface.
+ *
+ ****************************************************************************/
+typedef struct ep9312_dma_s
+{
+    /*
+     *  This 1 when the instance is in use, and 0 when it's not.
+     */
+    unsigned int ref_count;
+
+    /*
+     * This is the last valid handle for this instance.  When giving out a
+     * new handle this will be incremented and given out.
+     */
+    int last_valid_handle;
+
+    /*
+     * device specifies one of the 20 DMA hardware ports this 
+     * DMA channel will service.
+     */
+    ep93xx_dma_dev_t device;
+
+    /*
+     * DMABufferQueue is the queue of buffer structure pointers which the
+     * dma channel will use to setup transfers.
+     */
+    ep93xx_dma_buffer_t buffer_queue[MAX_EP93XX_DMA_BUFFERS];
+
+    /*
+     * currnt_buffer : This is the buffer currently being transfered on 
+     *                 this channel.
+     * last_buffer : This is the last buffer for this transfer.
+     * Note: current_buffer + 1 is already programmed into the dma
+     *       channel as the next buffer to transfer. Don't write
+     *       over either entry.
+     */
+    int current_buffer;
+    int last_buffer;
+
+    /*
+     * The following 3 fields are buffer counters.
+     *
+     * iNewBuffers: Buffers in the queue which have not been transfered.
+     * iUsedBuffers: Buffers in the queue which have have been tranferred,
+     *               and are waiting to be returned.
+     * iTotalBuffers: Total number of buffers in the queue.
+     */  
+    int new_buffers;
+    int used_buffers;
+    int total_buffers;
+
+    /*
+     * uiTotalBytes has the total bytes transfered on the channel since the
+     * last flush.  This value does not include the bytes tranfered in the
+     * current buffer.  A byte count is only added after a complete buffer
+     * is tranfered. 
+     */
+    unsigned int total_bytes;
+
+    /*
+     *  Interrupt number for this channel
+     */
+    unsigned int irq;
+
+    /*
+     * Indicates whether or not the channel is currently enabled to transfer
+     * data.
+     */
+    unsigned int xfer_enable;
+    
+    /*
+     * pause indicates if the dma channel was paused by calling the pause
+     * ioctl.
+     */
+    unsigned int pause;
+    
+    /*
+     *  buffer structure used during a pause to capture the current
+     *  address and remaining bytes for the buffer actively being transferred
+     *  on the channel. This buffer will be used to reprogram the dma 
+     *  channel upon a resume.
+     */
+    ep93xx_dma_buffer_t pause_buf;
+    
+    /*
+     * DMACallback is a function pointer which the calling application can 
+     * use install a function to.  this fuction can be used to notify the 
+     * calling application of an interrupt.
+     */
+    dma_callback callback;
+
+    /*
+     * User data used as a parameter for the Callback function.  The user
+     * sets up the data and sends it with the callback function.
+     */
+    unsigned int user_data;
+    
+    /*
+     * A string representation of the device attached to the channel.
+     */
+    const char * device_id;
+    
+    /*
+     * The register base address for this dma channel.
+     */
+    unsigned int reg_base;
+    
+} ep93xx_dma_t;
+
+/*****************************************************************************
+ *
+ * DMA macros
+ *
+ ****************************************************************************/
+#define DMA_HANDLE_SPECIFIER_MASK   0xF0000000
+#define DMA_CH0_HANDLE_SPECIFIER    0x00000000
+#define DMA_CH1_HANDLE_SPECIFIER    0x10000000
+#define DMA_CH2_HANDLE_SPECIFIER    0x20000000
+#define DMA_CH3_HANDLE_SPECIFIER    0x30000000
+#define DMA_CH4_HANDLE_SPECIFIER    0x40000000
+#define DMA_CH5_HANDLE_SPECIFIER    0x50000000
+#define DMA_CH6_HANDLE_SPECIFIER    0x60000000
+#define DMA_CH7_HANDLE_SPECIFIER    0x70000000
+#define DMA_CH8_HANDLE_SPECIFIER    0x80000000
+#define DMA_CH9_HANDLE_SPECIFIER    0x90000000
+#define DMA_CH10_HANDLE_SPECIFIER   0xA0000000
+#define DMA_CH11_HANDLE_SPECIFIER   0xB0000000
+
+#endif // _DMADRV_H_
diff -urN linux-2.4.29/arch/arm/mach-ep93xx/ee.c linux-2.4.29-uc1/arch/arm/mach-ep93xx/ee.c
--- linux-2.4.29/arch/arm/mach-ep93xx/ee.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ep93xx/ee.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,21 @@
+/*
+ *  linux/arch/arm/mach-ep93xx/ee.c
+ *
+ *  Copyright (C) 2003 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+ 
+/* This file intentionally left blank */
diff -urN linux-2.4.29/arch/arm/mach-ep93xx/irq.c linux-2.4.29-uc1/arch/arm/mach-ep93xx/irq.c
--- linux-2.4.29/arch/arm/mach-ep93xx/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ep93xx/irq.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,94 @@
+/*
+ *  linux/arch/arm/mach-ep93xx/irq.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * (c) Copyright 2001 LynuxWorks, Inc., San Jose, CA.  All rights reserved.
+ *
+ *  Copyright (C) 2002-2003 Cirrus Logic, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+/********************************************************************
+ *	Interrupt functions are defined as machine specific here.
+ *
+ *	Note:
+ *		1.  Only normal interrupts are defined here.
+ *		FIQs are a separate class of interrupts and would
+ *		be slowed down if handled like normal interrupts.
+ *
+ *		2.  TBD Invalid interrupt numbers are not checked.
+ *		Some interrupt inputs are tied to GND, which means 
+ *		they will immediately activate when unmasked.
+ *		Which may be useful for some devices.
+ *
+ *		3.  TBD Edge triggered interrupts are not specially
+ *		handled.  The architecture should provide a way to
+ *		set up the edge trigger features and then a way to
+ *		control the acknowledge to the interrupt.
+ *
+ ************************************************************************/
+
+static void ep93xx_mask_irq1(unsigned int irq)
+{
+	outl( (1 << irq), VIC0INTENCLEAR );
+}
+
+static void ep93xx_unmask_irq1(unsigned int irq)
+{
+	outl( (1 << irq), VIC0INTENABLE );
+}
+ 
+static void ep93xx_mask_irq2(unsigned int irq)
+{
+	outl( (1 << (irq - 32)), VIC1INTENCLEAR );
+}
+
+static void ep93xx_unmask_irq2(unsigned int irq)
+{
+	outl( (1 << (irq - 32)), VIC1INTENABLE );
+}
+ 
+void __init ep93xx_init_irq(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < NR_IRQS; i++) {
+		if ((i < 32) && (INT1_IRQS & (1 << i))) {
+			irq_desc[i].valid	= 1;
+			irq_desc[i].probe_ok	= 1;
+			irq_desc[i].mask_ack	= ep93xx_mask_irq1;
+			irq_desc[i].mask	= ep93xx_mask_irq1;
+			irq_desc[i].unmask	= ep93xx_unmask_irq1;
+		}
+		if ((i >= 32) && (INT2_IRQS) & (1 << (i - 32))) {
+			irq_desc[i].valid	= 1;
+			irq_desc[i].probe_ok	= 1;
+			irq_desc[i].mask_ack	= ep93xx_mask_irq2;
+			irq_desc[i].mask	= ep93xx_mask_irq2;
+			irq_desc[i].unmask	= ep93xx_unmask_irq2;
+		}
+	}
+}
+
diff -urN linux-2.4.29/arch/arm/mach-ep93xx/kgdb-serial.c linux-2.4.29-uc1/arch/arm/mach-ep93xx/kgdb-serial.c
--- linux-2.4.29/arch/arm/mach-ep93xx/kgdb-serial.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ep93xx/kgdb-serial.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,64 @@
+/*
+ * tiny serial helper routines for kgdb
+ *
+ * Based on George G. Davis <gdavis@mvista.com> work.
+ */
+
+#include <linux/config.h>
+#include <asm/io.h>
+#include <asm/hardware/serial_amba.h>
+#include <asm/arch/regmap.h>
+#include <asm/arch/regs_syscon.h>
+
+#if defined(CONFIG_KGDB_UART0)
+#define KGDB_UART_BASE UART1_BASE
+#define KGDB_UART_ENABLE 0x00040000
+#elif defined(CONFIG_KGDB_UART1)
+#define KGDB_UART_BASE UART2_BASE
+#define KGDB_UART_ENABLE 0x00100000
+#elif defined(CONFIG_KGDB_UART2)
+#define KGDB_UART_BASE UART3_BASE
+#define KGDB_UART_ENABLE 0x01000000
+#else
+#error "No kgdb serial port UART has been selected."
+#endif
+
+#if defined(CONFIG_KGDB_9600BAUD)
+#define KGDB_SERIAL_BAUD_RATE ARM_BAUD_9600
+#elif defined(CONFIG_KGDB_19200BAUD)
+#define KGDB_SERIAL_BAUD_RATE ARM_BAUD_19200
+#elif defined(CONFIG_KGDB_38400BAUD)
+#define KGDB_SERIAL_BAUD_RATE ARM_BAUD_38400
+#elif defined(CONFIG_KGDB_57600BAUD)
+#define KGDB_SERIAL_BAUD_RATE ARM_BAUD_57600
+#elif defined(CONFIG_KGDB_115200BAUD)
+#define KGDB_SERIAL_BAUD_RATE ARM_BAUD_115200
+#else
+#error "kgdb serial baud rate has not been specified."
+#endif
+
+void kgdb_serial_init(void)
+{
+	unsigned int uiTemp;
+
+	uiTemp = inl(SYSCON_DEVCFG) | KGDB_UART_ENABLE;
+	outl(0xaa, SYSCON_SWLOCK);
+	outl(uiTemp, SYSCON_DEVCFG);
+	outl(KGDB_SERIAL_BAUD_RATE, KGDB_UART_BASE + AMBA_UARTLCR_L);
+	outl(0, KGDB_UART_BASE + AMBA_UARTLCR_M);
+	outl(AMBA_UARTLCR_H_WLEN_8 | AMBA_UARTLCR_H_FEN,
+	     KGDB_UART_BASE + AMBA_UARTLCR_H);
+	outl(AMBA_UARTCR_UARTEN, KGDB_UART_BASE + AMBA_UARTCR);
+}
+
+void kgdb_serial_putchar(unsigned char ch)
+{
+	while(inl(KGDB_UART_BASE + AMBA_UARTFR) & AMBA_UARTFR_TXFF);
+	outl(ch, KGDB_UART_BASE + AMBA_UARTDR);
+}
+
+unsigned char kgdb_serial_getchar(void)
+{
+	while(inl(KGDB_UART_BASE + AMBA_UARTFR) & AMBA_UARTFR_RXFE);
+	return(inl(KGDB_UART_BASE + AMBA_UARTDR) & 0xff);
+}
diff -urN linux-2.4.29/arch/arm/mach-ep93xx/Makefile linux-2.4.29-uc1/arch/arm/mach-ep93xx/Makefile
--- linux-2.4.29/arch/arm/mach-ep93xx/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ep93xx/Makefile	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,25 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+EXTRA_LDFLAGS		+= --no-warn-mismatch
+
+O_TARGET		:= ep93xx.o 
+
+# Object file lists.
+
+obj-y			:= arch.o irq.o mm.o time.o ssp.o dma_ep93xx.o pcmcia_io.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= pcipool.o
+
+obj-$(CONFIG_EP93XX_CRUNCH) += crunch.o
+obj-$(CONFIG_KGDB_SERIAL) += kgdb-serial.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/arm/mach-ep93xx/mm.c linux-2.4.29-uc1/arch/arm/mach-ep93xx/mm.c
--- linux-2.4.29/arch/arm/mach-ep93xx/mm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ep93xx/mm.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,57 @@
+/*
+ *  linux/arch/arm/mach-ep93xx/mm.c
+ *
+ *  Extra MM routines for the Cirrus EP93xx
+ *
+ *  Copyright (C) 1999,2000 Arm Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002-2003 Cirrus Logic, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/arch/bits.h> 
+#include <asm/sizes.h> 
+#include <asm/arch/platform.h> 
+ 
+#include <asm/mach/map.h>
+
+/*
+ *  IO Map for EP93xx:
+ *
+ *  8000 0000 - 807f ffff = AHB peripherals  (8 Meg)
+ *  8080 0000 - 809f ffff = APB peripherals  (2 Meg)
+ *  a000 0000 - b000 0000 = PCMCIA space
+ */ 
+static struct map_desc ep93xx_io_desc[] __initdata = 
+{
+    //
+    // Virtual Address                Physical Addresss    Size in Bytes  Domain     R  W  C  B Last
+    { IO_BASE_VIRT,                   IO_BASE_PHYS,        IO_SIZE,       DOMAIN_IO, 0, 1, 0, 0 },
+    { PCMCIA_BASE_VIRT,               PCMCIA_BASE_PHYS,    PCMCIA_SIZE,   DOMAIN_IO, 0, 1, 0, 0 },
+    LAST_DESC
+};
+
+void __init ep93xx_map_io(void)
+{
+	iotable_init(ep93xx_io_desc);
+}
+
diff -urN linux-2.4.29/arch/arm/mach-ep93xx/pcmcia_io.c linux-2.4.29-uc1/arch/arm/mach-ep93xx/pcmcia_io.c
--- linux-2.4.29/arch/arm/mach-ep93xx/pcmcia_io.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ep93xx/pcmcia_io.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,99 @@
+/*
+ *  linux/arch/arm/mach-ep93xx/pcmcia_io.c
+ *
+ * (c) Copyright 2004 Cirrus Logic, Inc., Austin, Tx 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/config.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/utsname.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/memory.h>
+#include <asm/arch/platform.h>
+
+#include <asm/mach/arch.h>
+
+#ifndef __EP93XX_PCMCIA_IDE_HACK__
+#define __EP93XX_PCMCIA_IDE_HACK__
+
+/*
+ * These routines are used to hack the default ide i/o routines in
+ * drivers/ide/ide-iops.h so they work with PCMCIA IDE.  Sad, but
+ * necessary.
+ */
+#define SET_PCMCIA_WIDTH_16_BIT \
+	unsigned long ulSMC_PCIO = inl( SMC_PCIO );	 \
+	if ( (ulSMC_PCIO & PCCONFIG_MW_16BIT)	== 0 ) {   \
+		outl( ulSMC_PCIO | PCCONFIG_MW_16BIT, SMC_PCIO ); \
+		ulSMC_PCIO = inl( SMC_PCIO ); \
+	}
+	
+#define SET_PCMCIA_WIDTH_8_BIT \
+	unsigned long ulSMC_PCIO = inl( SMC_PCIO );	\
+	if ( ulSMC_PCIO & PCCONFIG_MW_16BIT ) {		\
+		outl( ulSMC_PCIO & ~PCCONFIG_MW_16BIT, SMC_PCIO ); \
+		ulSMC_PCIO = inl( SMC_PCIO ); \
+	}
+
+
+inline u8 ep93xx_pcmcia_ide_inb (unsigned long port)
+{
+	SET_PCMCIA_WIDTH_8_BIT
+	return (u8) inb(port);
+}
+
+inline u16 ep93xx_pcmcia_ide_inw (unsigned long port)
+{
+	SET_PCMCIA_WIDTH_16_BIT
+	return (u16) inw(port);
+}
+
+inline void ep93xx_pcmcia_ide_insw (unsigned long port, void *addr, u32 count)
+{
+	SET_PCMCIA_WIDTH_16_BIT
+	return insw(port, addr, count);
+}
+
+inline void ep93xx_pcmcia_ide_outb (u8 addr, unsigned long port)
+{
+	SET_PCMCIA_WIDTH_8_BIT
+	outb(addr, port);
+	ulSMC_PCIO = inl( SMC_PCIO );
+}
+
+inline void ep93xx_pcmcia_ide_outw (u16 addr, unsigned long port)
+{
+	SET_PCMCIA_WIDTH_16_BIT
+	outw(addr, port);
+	ulSMC_PCIO = inl( SMC_PCIO );
+}
+
+inline void ep93xx_pcmcia_ide_outsw (unsigned long port, void *addr, u32 count)
+{
+	SET_PCMCIA_WIDTH_16_BIT
+	outsw(port, addr, count);
+	ulSMC_PCIO = inl( SMC_PCIO );
+}
+#endif /* __EP93XX_PCMCIA_IDE_HACK__ */
+
diff -urN linux-2.4.29/arch/arm/mach-ep93xx/ssp.c linux-2.4.29-uc1/arch/arm/mach-ep93xx/ssp.c
--- linux-2.4.29/arch/arm/mach-ep93xx/ssp.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ep93xx/ssp.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,964 @@
+/*
+ *  FILE:			ssp.c
+ *
+ *  DESCRIPTION:	SSP Interface Driver Module implementation
+ *
+ *  Copyright Cirrus Logic Corporation, 2001-2003.  All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ *  This driver provides a way to read and write devices on the SSP
+ *  interface.
+ *
+ *  For Tx devices, EGPIO7 is used as an address pin:
+ *  I2S Codec CS4228        = EGPIO7 == 1
+ *  Serial Flash AT25F1024  = EGPIO7 == 0
+ */
+#include <linux/delay.h>
+#include <asm/irq.h>
+
+#include <asm/semaphore.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/ssp.h>
+
+#undef DEBUG
+// #define DEBUG 1
+#ifdef DEBUG
+#define DPRINTK( x... )  printk( ##x )
+#else
+#define DPRINTK( x... )
+#endif
+
+
+#define EP93XX_KEY_TIMER_PERIOD_MSEC 20
+
+static int SSP_Open(SSPDeviceType Device, SSPDataCallback Callback);
+static int SSP_Close(int Handle);
+static int SSP_Read(int Handle, unsigned int Addr, unsigned int *pValue);
+static int SSP_Write(int Handle, unsigned int Addr, unsigned int Value);
+static int CheckHandle(int Handle);
+
+static void  SetSSPtoPS2(void);
+static void  SetSSPtoI2S(void);
+static void  SetSSPtoFLASH(void);
+static int  ReadIntoBuffer(void);
+
+static int SSP_Write_I2SCodec(int Handle, unsigned int RegAddr,unsigned int RegValue);
+
+/*
+ * Key buffer...
+ */
+#define KEYBUF_SIZE 256
+static unsigned int uiKeyBuffer[KEYBUF_SIZE];
+static spinlock_t ssp_spinlock = SPIN_LOCK_UNLOCKED;
+
+
+typedef enum{
+	SSP_MODE_UNKNOWN = 0,
+	SSP_MODE_PS2,
+	SSP_MODE_I2S,
+	SSP_MODE_FLASH,
+} SSPmodes_t;
+
+static struct timer_list g_KbdTimer;
+static SSPmodes_t gSSPmode = SSP_MODE_UNKNOWN;
+static SSPDataCallback gKeyCallback = 0;
+static int gHookedInterrupt = 0;
+
+/*
+ * Keep the last valid handle for SSP for kbd, i2s, and flash
+ */
+static int iLastValidHandle = -1;
+static int KeyboardHandle = 0;
+static int I2SHandle = 0;
+static int FlashHandle = 0;
+
+#define SSP_DEVICE_MASK    0xf0000000
+#define SSP_DEVICE_SHIFT	 28
+
+SSP_DRIVER_API SSPinstance =
+{
+	SSP_Open,
+	SSP_Read,
+	SSP_Write,
+	SSP_Close,
+};
+
+/*
+ * The only instance of this driver.
+ */
+SSP_DRIVER_API *SSPDriver = &SSPinstance;
+
+//=============================================================================
+// SSPIrqHandler
+//=============================================================================
+// This routine will get all of the keys out of the SPI FIFO.
+//=============================================================================
+void SSPIrqHandler( int irq, void *dev_id, struct pt_regs *regs)
+{
+	//
+	// Get key codes from SSP and send them to the keyboard callback.
+	//
+	ReadIntoBuffer();
+	
+	//
+	// Clear the interrupt.
+	//
+	outl( 0, SSPIIR );
+}
+
+//=============================================================================
+// TimerRoutine
+//=============================================================================
+// This function is called periodically to make sure that no keys are stuck in
+// the SPI FIFO.  This is necessary because the SPI only interrupts on half
+// full FIFO which can leave up to one keyboard event in the FIFO until another
+// key is pressed.
+//=============================================================================
+static void TimerRoutine(unsigned long Data)
+{
+	int keycount;
+
+	//
+	// Get key codes from SSP and send them to the keyboard callback.
+	//
+	keycount = ReadIntoBuffer();
+	
+	//
+	// If no keys were received, call the Data callback anyway so it can
+	// check for stuck keys.
+	//
+	if( (keycount==0) && gKeyCallback )
+	{
+		gKeyCallback(-1);
+	}
+	
+	//
+	// Reschedule our timer in another 20 mSec.
+	//
+	g_KbdTimer.expires = jiffies + MSECS_TO_JIFFIES( EP93XX_KEY_TIMER_PERIOD_MSEC );
+	add_timer(&g_KbdTimer);
+}
+
+/*
+ * HookInterrupt
+ *
+ * Requests SSP interrupt, sets up interrupt handler, sets up keyboard polling
+ * timer.
+ */
+static int HookInterrupt(void)
+{
+	if (gHookedInterrupt)
+	{
+		printk( KERN_ERR "SSP driver interrupt already hooked\n");
+		return(-1);
+	}
+
+
+	if (request_irq(IRQ_SSPRX, SSPIrqHandler, SA_INTERRUPT, "ep93xxsspd", 0))
+	{
+		printk( KERN_ERR "SSP driver failed to get IRQ handler\n");
+		return(-1);
+	}
+	
+	gHookedInterrupt = 1;
+
+	//
+	// Initialize the timer that we will use to poll the SPI.
+	//
+	init_timer(&g_KbdTimer);
+	g_KbdTimer.function = TimerRoutine;
+	g_KbdTimer.data = 1;
+	g_KbdTimer.expires = jiffies + MSECS_TO_JIFFIES( EP93XX_KEY_TIMER_PERIOD_MSEC );
+
+	add_timer(&g_KbdTimer);
+	
+	return(0);
+}
+
+static int SSP_Open(SSPDeviceType Device, SSPDataCallback Callback)
+{
+	int Handle;
+	
+	/*
+	 * Generate a handle and pass it back.
+	 *
+	 * Increment the last valid handle.
+	 * Check for wraparound (unlikely, but we like to be complete).
+	 */
+	iLastValidHandle++;
+	
+	if((iLastValidHandle & ~SSP_DEVICE_MASK) == 0)
+	{
+		/*
+		 * If we wrapped around start over.  Unlikely.
+		 */
+		iLastValidHandle = 1;
+	}
+	
+	Handle = iLastValidHandle | (Device << SSP_DEVICE_SHIFT);
+
+	switch (Device)
+	{
+		case PS2_KEYBOARD:
+		{
+			DPRINTK("SSP_Open - PS2_KEYBOARD\n");
+			if (KeyboardHandle)
+			{
+				return(-1);
+			}
+			else
+			{
+				DPRINTK("Handle:%08x  Callback:%08x  -- Success\n",
+					Handle, (unsigned int)Callback);
+
+				KeyboardHandle = Handle;
+				//
+				// Hook the interrupt if we have not yet.
+				//
+				HookInterrupt();
+				SetSSPtoPS2();
+				gKeyCallback = Callback;
+			}
+			break;
+		}
+		case I2S_CODEC:
+		{
+			DPRINTK("SSP_Open - I2S_CODEC\n");
+			if (I2SHandle)
+			{
+				return(-1);
+			}
+			else
+			{
+				DPRINTK("Handle:%08x  Callback:%08x  -- Success\n",
+					Handle, (unsigned int)Callback);
+
+				I2SHandle = Handle;
+			}
+			break;
+		}
+		case SERIAL_FLASH:
+		{
+			DPRINTK("SSP_Open - SERIAL_FLASH\n");
+			if (FlashHandle)
+			{
+				return(-1);
+			}
+			else
+			{
+				DPRINTK("Handle:%08x  Callback:%08x  -- Success\n",
+					Handle, (unsigned int)Callback);
+				FlashHandle = Handle;
+			}
+			break;
+		}
+		default:
+		{
+			return(-1);
+		}
+	}
+	
+	/*
+	 * Return the handle.
+	 */
+	return(Handle );
+}
+
+/*
+ * Release that Handle!
+ */
+static int SSP_Close(int Handle)
+{
+	//
+	// Find out which device this API was called for.
+	//
+	switch( CheckHandle(Handle) )
+	{
+		case PS2_KEYBOARD:
+		{
+			DPRINTK("SSP_Open - PS2_KEYBOARD\n");
+			del_timer(&g_KbdTimer);
+			free_irq(IRQ_SSPRX, 0);
+			gKeyCallback = 0;
+			KeyboardHandle = 0;
+			gHookedInterrupt = 0;
+			break;
+		}
+		case I2S_CODEC:
+		{
+			DPRINTK("SSP_Open - I2S_CODEC\n");
+			I2SHandle = 0;
+			break;
+		}
+		case SERIAL_FLASH:
+		{
+			DPRINTK("SSP_Open - SERIAL_FLASH\n");
+			FlashHandle = 0;
+			break;
+		}
+		default:
+		{
+			return(-1);
+		}
+	}
+	return 0;
+}
+
+static int SSP_Read_FLASH
+(
+	int Handle,
+	unsigned int RegAddr,
+	unsigned int *pValue
+)
+{
+	SSPmodes_t saved_mode;
+
+	DPRINTK("SSP_Read_FLASH\n");
+
+	spin_lock(&ssp_spinlock);
+
+	/*
+	 * Save the SSP mode.  Switch to FLASH mode if we're not
+	 * already in FLASH mode.
+	 */
+	saved_mode = gSSPmode;
+	SetSSPtoFLASH();
+
+	/*
+	 * Let TX fifo clear out.  Poll the Transmit Fifo Empty bit.
+	 */
+	while( !( inl(SSPSR) & SSPSR_TFE ) )
+		barrier();
+
+	/*
+	 * Write the SPI read command.
+	 */
+	outl( 0x03, SSPDR );
+	outl( (RegAddr >> 16) & 255, SSPDR );
+	outl( (RegAddr >> 8) & 255, SSPDR );
+	outl( RegAddr & 255, SSPDR );
+
+	/*
+	 * Delay long enough for one byte to be transmitted.  It takes 7.6uS to
+	 * write a single byte.
+	 */
+	udelay(10);
+
+	/*
+	 * Read a byte to make sure the FIFO doesn't overrun.
+	 */
+	while( !( inl(SSPSR) & SSPSR_RNE ) )
+		barrier();
+	inl( SSPDR );
+
+	/*
+	 * Write four more bytes so that we can read four bytes.
+	 */
+	outl( 0, SSPDR );
+	outl( 0, SSPDR );
+	outl( 0, SSPDR );
+	outl( 0, SSPDR );
+
+	/*
+	 * Delay long enough for three bytes to be transmitted.  It takes 7.6uS
+	 * to write a single byte.
+	 */
+	udelay(25);
+
+	/*
+	 * Read three and throw away the next tree bytes.
+	 */
+	while( !( inl(SSPSR) & SSPSR_RNE ) )
+		barrier();
+	inl( SSPDR );
+	while( !( inl(SSPSR) & SSPSR_RNE ) )
+		barrier();
+	inl( SSPDR );
+	while( !( inl(SSPSR) & SSPSR_RNE ) )
+		barrier();
+	inl( SSPDR );
+
+	/*
+	 * Delay long enough for four bytes to be transmitted.  It takes 7.6uS
+	 * to write a single byte.
+	 */
+	udelay(30);
+
+	/*
+	 * Read the data word.
+	 */
+	while( !( inl(SSPSR) & SSPSR_RNE ) )
+		barrier();
+	*pValue = inl( SSPDR );
+	while( !( inl(SSPSR) & SSPSR_RNE ) )
+		barrier();
+	*pValue |= inl( SSPDR ) << 8;
+	while( !( inl(SSPSR) & SSPSR_RNE ) )
+		barrier();
+	*pValue |= inl( SSPDR ) << 16;
+	while( !( inl(SSPSR) & SSPSR_RNE ) )
+		barrier();
+	*pValue |= inl( SSPDR ) << 24;
+
+	/*
+	 * Wait until the transmit buffer is empty (it should be...).
+	 */
+	while( !( inl(SSPSR) & SSPSR_TFE ) )
+		barrier();
+
+	/*
+	 * Read any residual bytes in the receive buffer.
+	 */
+	while( inl(SSPSR) & SSPSR_RNE )
+		inl( SSPDR );
+	
+	/*
+	 * If we were in PS2 mode, switch back to PS2 mode.
+	 * If we weren't in PS2 mode, that means we didn't compile in
+	 * the PS2 keyboard support, so no need to switch to PS2 mode.
+	 */
+	if( saved_mode == SSP_MODE_PS2 )
+		SetSSPtoPS2();
+
+	spin_unlock(&ssp_spinlock);
+
+	/*
+	 * Return success.
+	 */
+	return 0;
+}
+
+static int SSP_Read(int Handle, unsigned int Addr, unsigned int *pValue)
+{
+	DPRINTK("SSP_Read\n");
+
+	/*
+	 * Find out which device this API was called for.
+	 */
+	switch( CheckHandle(Handle) )
+	{
+		case SERIAL_FLASH:
+		{
+			return SSP_Read_FLASH(Handle, Addr, pValue);
+		}
+		default:
+		{
+			return -1;
+		}
+	}
+}
+
+static int SSP_Write(int Handle, unsigned int Addr, unsigned int Value)
+{
+	int iRet = 0;
+	// DPRINTK("SSP_Write - Handle:0x%08x  Addr:0x%08x  Value:0x%08x\n",
+	//    Handle, Addr, Value );
+	
+	//
+	// Find out which device this API was called for.
+	//
+	switch( CheckHandle(Handle) )
+	{
+		case PS2_KEYBOARD:
+		{
+			break;
+		}
+		case I2S_CODEC:
+		{
+			iRet = SSP_Write_I2SCodec( Handle, Addr, Value );
+			break;
+		}
+		case SERIAL_FLASH:
+		{
+			break;
+		}
+		default:
+		{
+			return(-1);
+		}
+	}
+
+	return iRet;
+}
+
+static void SetSSPtoPS2(void)
+{
+	unsigned int uiRegTemp;
+	
+	if( gSSPmode == SSP_MODE_PS2 )
+	{
+		return;
+	}
+
+	/*
+	 * Disable the SSP, disable interrupts
+	 */
+	outl( 0, SSPCR1 );
+
+	/*
+	 * It takes almost a millisecond for a key to come in so
+	 * make sure we have completed all transactions.
+	 */
+	mdelay(1);
+
+	//
+	// Set EGPIO7 to disable EEPROM device on EDB9301, EDB9312, and EDB9315.
+	//
+	uiRegTemp = inl(GPIO_PADDR);
+	outl( uiRegTemp | 0x80, GPIO_PADDR );
+
+	uiRegTemp = inl(GPIO_PADR);
+	outl( uiRegTemp | 0x80, GPIO_PADR );
+
+    /*
+     * Disable SFRM1 to I2S codec by setting EGPIO8 (port B, bit 0).
+     * The EDB9315 board needs this but is harmless on the EDB9312 board.
+     */
+#if defined(CONFIG_ARCH_EDB9312) || defined(CONFIG_ARCH_EDB9315)
+    uiRegTemp = inl(GPIO_PBDDR) | 0x01;
+    outl( uiRegTemp, GPIO_PBDDR );
+
+    uiRegTemp = inl(GPIO_PBDR) | 0x01;
+    outl( uiRegTemp, GPIO_PBDR );
+	
+	uiRegTemp = inl(GPIO_PBDR);
+#endif
+
+    /*
+     * Disable SFRM1 to I2S codec I2S by setting EGPIO6 (port A, bit 6).
+     * The EDB9301 board needs this
+     */
+#if defined(CONFIG_ARCH_EDB9301) || defined(CONFIG_ARCH_EDB9302)
+	uiRegTemp = inl(GPIO_PADDR);
+	outl( uiRegTemp | 0x40, GPIO_PADDR );
+
+	uiRegTemp = inl(GPIO_PADR);
+	outl( uiRegTemp | 0x40, GPIO_PADR );
+
+	uiRegTemp = inl(GPIO_PADR);
+#endif
+
+	/*
+	 * Still haven't enabled the keyboard.  So anything in
+	 * the rx fifo is garbage.  Time to take out the trash.
+	 */
+	while( inl(SSPSR) & SSPSR_RNE )
+	{
+		uiRegTemp = inl(SSPDR);
+	}
+
+	/*
+	 * SPICR0_SPO - SCLKOUT Polarity
+	 * SPICR0_SPH - SCLKOUT Phase
+	 * Motorola format, 11 bit, one start, 8 data, one bit for
+	 * parity, one stop bit.
+	 */
+	outl( (SSPCR0_FRF_MOTOROLA | SSPCR0_SPH | SSPCR0_SPO | SSPCR0_DSS_11BIT),
+	      SSPCR0 );
+	/*
+	 * Configure the device as a slave, Clear FIFO overrun interrupts,
+	 * enable interrupts and reset the device.
+	 */
+	outl( (SSPC1_MS | SSPC1_RIE | SSPC1_SOD), SSPCR1 );
+	outl( 0, SSPIIR );
+	outl( (SSPC1_MS | SSPC1_RIE | SSPC1_SOD | SSPC1_SSE), SSPCR1 );
+
+	/*
+	 * Configure EGPIO pins 12 and 14 as outputs because they are used
+	 * as buffer enables for the SPI interface to the ps2 keyboard.
+	 * Clear EGPIO pins 12 and 14, this will enable the SPI keyboard.
+	 */
+	uiRegTemp = inl(GPIO_PBDDR);
+	outl( uiRegTemp | 0x50, GPIO_PBDDR );
+
+	uiRegTemp = inl(GPIO_PBDR);
+	outl( uiRegTemp & ~0x50, GPIO_PBDR );
+
+	gSSPmode = SSP_MODE_PS2;
+}
+
+static void SetSSPtoI2S(void)
+{
+	unsigned int uiRegTemp;
+
+	if( gSSPmode == SSP_MODE_I2S )
+	{
+		return;
+	}
+	
+	/*
+	 * Disable recieve interrupts.
+	 */
+	outl( (SSPC1_MS | SSPC1_SSE), SSPCR1 );
+
+	/*
+	 * Set GPIO pins 12 and 14, this will bring the clock line low
+	 * which signals to the keyboard to buffer keystrokes.
+	 * Note that EGPIO 14 is the clock line and EGPIO 12 is data line.
+	 */
+	uiRegTemp = inl(GPIO_PBDR);
+	outl( 0x50 | uiRegTemp, GPIO_PBDR );
+
+	/*
+	 * It takes almost a millisecond for an partial keystrokes to come in.
+	 * Delay to make sure we have completed all transactions.
+	 */
+	mdelay(1);
+
+	/*
+	 * Anything we just recieved is garbage.  Time to take out the trash.
+	 */
+	while( inl(SSPSR) & SSPSR_RNE )
+	{
+		uiRegTemp = inl(SSPDR);
+	}
+	
+	/*
+	 * Disable the SSP and disable interrupts
+	 */
+	outl( 0, SSPCR1 );
+
+	/*
+	 * Clock will be 14.7 MHz divided by 4.
+	 */
+	outl( 2, SSPCPSR );
+
+	/*
+	 * Configure EGPIO7 as an output and set it.  This selects
+	 * I2S codec as the device on the SSP output instead of
+	 * the serial flash on EDB9312.  On EDB9301 and EDB9315 it
+	 * disables EEPROM but doesn't select anything.
+	 */
+	uiRegTemp = inl(GPIO_PADDR);
+	outl( uiRegTemp | 0x80, GPIO_PADDR );
+
+	uiRegTemp = inl(GPIO_PADR);
+	outl( uiRegTemp | 0x80, GPIO_PADR );
+
+    /*
+     * Enable SFRM1 to I2S codec by clearing EGPIO8 (port B, bit 0).
+     * The EDB9315 board needs this but is harmless on the EDB9312 board.
+     */
+#if defined(CONFIG_ARCH_EDB9312) || defined(CONFIG_ARCH_EDB9315)
+    uiRegTemp = inl(GPIO_PBDDR) | 0x01;
+    outl( uiRegTemp, GPIO_PBDDR );
+
+    uiRegTemp = inl(GPIO_PBDR) & 0xfe;
+    outl( uiRegTemp, GPIO_PBDR );
+	
+	uiRegTemp = inl(GPIO_PBDR);
+#endif
+
+    /*
+     * Enable SFRM1 to I2S codec I2S by clearing EGPIO6 (port A, bit 6).
+     * The EDB9301 board needs this
+     */
+#if defined(CONFIG_ARCH_EDB9301) || defined(CONFIG_ARCH_EDB9302)
+	uiRegTemp = inl(GPIO_PADDR);
+	outl( uiRegTemp | 0x40, GPIO_PADDR );
+
+	uiRegTemp = inl(GPIO_PADR);
+	outl( uiRegTemp & ~0x40, GPIO_PADR );
+
+	uiRegTemp = inl(GPIO_PADR);
+#endif
+
+	/*
+	 * Motorola format, 8 bit.
+	 */
+	outl( (SSPCR0_SPO | SSPCR0_SPH | SSPCR0_FRF_MOTOROLA | SSPCR0_DSS_8BIT),
+	      SSPCR0 );
+
+	/*
+	 * Configure the device as master, reenable the device.
+	 */
+	outl( SSPC1_SSE, SSPCR1 );
+
+	gSSPmode = SSP_MODE_I2S;
+
+	udelay(10);
+}
+
+static void SetSSPtoFLASH(void)
+{
+	unsigned int uiRegTemp;
+
+	if( gSSPmode == SSP_MODE_FLASH)
+		return;
+
+	/*
+	 * Disable recieve interrupts.
+	 */
+	outl( (SSPC1_MS | SSPC1_SSE), SSPCR1 );
+
+	/*
+	 * Set GPIO pins 12 and 14, this will bring the clock line low
+	 * which signals to the keyboard to buffer keystrokes.
+	 * Note that EGPIO 14 is the clock line and EGPIO 12 is data line.
+	 */
+	outl( inl(GPIO_PBDR) | 0x50, GPIO_PBDR );
+
+	/*
+	 * It takes almost a millisecond for an partial keystrokes to come in.
+	 * Delay to make sure we have completed all transactions.
+	 */
+	mdelay(1);
+
+	/*
+	 * Anything we just recieved is garbage.  Time to take out the trash.
+	 */
+	while( inl(SSPSR) & SSPSR_RNE )
+		inl(SSPDR);
+	
+	/*
+	 * Disable the SSP and disable interrupts
+	 */
+	outl( 0, SSPCR1 );
+
+	/*
+	 * Clock will be 14.7 MHz divided by 14.
+	 */
+	outl( 2, SSPCPSR );
+
+	/*
+	 * Configure EGPIO7 as an output and clear it.  This selects
+	 * serial flash as the device on the SSP output instead of
+	 * the I2S codec and is valid for EDB9301, EDB9312, and EDB9315.
+	 */
+	outl( inl(GPIO_PADDR) | 0x80, GPIO_PADDR );
+	outl( inl(GPIO_PADR) & ~0x80, GPIO_PADR );
+
+    /*
+     * Disable SFRM1 to I2S codec by setting EGPIO8 (port B, bit 0).
+     * The EDB9315 board needs this but is harmless on the EDB9312 board.
+     */
+#if defined(CONFIG_ARCH_EDB9312) || defined(CONFIG_ARCH_EDB9315)
+    uiRegTemp = inl(GPIO_PBDDR) | 0x01;
+    outl( uiRegTemp, GPIO_PBDDR );
+
+    uiRegTemp = inl(GPIO_PBDR) | 0x01;
+    outl( uiRegTemp, GPIO_PBDR );
+	
+	uiRegTemp = inl(GPIO_PBDR);
+#endif
+
+    /*
+     * Disable SFRM1 to I2S codec I2S by setting EGPIO6 (port A, bit 6).
+     * The EDB9301 board needs this
+     */
+#if defined(CONFIG_ARCH_EDB9301) || defined(CONFIG_ARCH_EDB9302)
+	uiRegTemp = inl(GPIO_PADDR);
+	outl( uiRegTemp | 0x40, GPIO_PADDR );
+
+	uiRegTemp = inl(GPIO_PADR);
+	outl( uiRegTemp | 0x40, GPIO_PADR );
+
+	uiRegTemp = inl(GPIO_PBDR);
+#endif
+
+	/*
+	 * Motorola format, 8 bit.
+	 */
+	outl( ((6 << SSPCR0_SCR_SHIFT) | SSPCR0_SPO | SSPCR0_SPH |
+	       SSPCR0_FRF_MOTOROLA | SSPCR0_DSS_8BIT),
+	      SSPCR0 );
+
+	/*
+	 * Configure the device as master, reenable the device.
+	 */
+	outl( SSPC1_SSE, SSPCR1 );
+
+	gSSPmode = SSP_MODE_FLASH;
+
+	udelay(10);
+}
+
+/*
+ *  CheckHandle
+ *
+ *  If Handle is valid, returns 0.  Otherwise it returns -1.
+ */
+static int CheckHandle(int Handle)
+{
+	int iRet;
+
+	if ((Handle != KeyboardHandle) &&
+	    (Handle != I2SHandle) &&
+	    (Handle != FlashHandle))
+	{
+		DPRINTK("OOPS! Invalid SSP Handle!\n");
+		return(-1);
+	}
+
+	/*
+	 * Get the SSP driver instance number from the handle.
+	 */
+	iRet = (((int)Handle & SSP_DEVICE_MASK) >> SSP_DEVICE_SHIFT);
+
+	return iRet;
+}
+
+/*
+ * ReadIntoBuffer
+ *
+ * Drains the SSP rx fifo into a buffer here.  If we overflow this buffer
+ * then something's wrong.
+ */
+static int ReadIntoBuffer(void)
+{
+	unsigned int count, index, saved_count, uiRegTemp;
+	
+	count = 0;
+	index = 0;
+
+
+	if( gSSPmode != SSP_MODE_PS2 )
+	{
+		return 0;
+	}
+	
+	/*
+	 * This spinlock will prevent I2S from grabbing the SSP to do a
+	 * write while we are using the SSP for PS2.
+	 *
+	 * There is a slight chance that we are in the beginning phase
+	 * of doing an I2S write but the mode flag hadn't yet switched
+	 * to I2S.  If that happens we will end up waiting on I2S to
+	 * finish a write.  Not great.
+	 */
+	spin_lock(&ssp_spinlock);
+
+	while( inl(SSPSR) & SSPSR_RNE)
+	{
+		/*
+		 * Read in the value from the SPI controller into
+		 * the partial key buffer.
+		 */
+		uiKeyBuffer[count] = inl(SSPDR);
+		if (((uiKeyBuffer[count] & 0x3fc) != 0x3e0) &&
+			((uiKeyBuffer[count] & 0x3fc) != 0x3c0))
+		{
+			/*
+			 * Set GPIO pins 12 and 14, this will bring the clock line low
+			 * which signals to the keyboard to buffer keystrokes.
+			 * Note that EGPIO 14 is the clock line and EGPIO 12 is data line.
+			 */
+			uiRegTemp = inl(GPIO_PBDR);
+			outl( 0x50 | uiRegTemp, GPIO_PBDR );
+
+			outl( 0, SSPCR1 );
+			outl( (SSPC1_MS | SSPC1_RIE | SSPC1_SSE), SSPCR1 );
+
+			/*
+			 * Clear EGPIO pins 12 and 14, this will enable the SPI keyboard.
+			 */
+			uiRegTemp = inl(GPIO_PBDR);
+			outl( uiRegTemp & ~0x50, GPIO_PBDR );
+
+			count++;
+			break;
+		}
+		count++;
+	}
+
+	saved_count = count;
+	index = 0;
+	while (count)
+	{
+		//
+		// No callback, dump data.
+		//
+		if (gKeyCallback)
+		{
+			gKeyCallback(uiKeyBuffer[index++]);
+		}
+		count--;
+	}
+
+	spin_unlock(&ssp_spinlock);
+
+	return saved_count;
+}
+
+/*
+ * SSP_Write_I2SCodec
+ *
+ */
+static int SSP_Write_I2SCodec
+(
+	int Handle,
+	unsigned int RegAddr,
+	unsigned int RegValue
+)
+{
+	SSPmodes_t saved_mode;
+
+	DPRINTK("SSP_Write_I2SCodec\n");
+
+	spin_lock(&ssp_spinlock);
+
+	/*
+	 * Save the SSP mode.  Switch to I2S mode if we're not
+	 * already in I2S mode.
+	 */
+	saved_mode = gSSPmode;
+	SetSSPtoI2S();
+
+	/*
+	 * Let TX fifo clear out.  Poll the Transmit Fifo Empty bit.
+	 */
+	while( !( inl(SSPSR) & SSPSR_TFE ) );
+	
+	/*
+	 * Write the data out to the tx fifo.
+	 */
+	outl( 0x20, SSPDR ); /* chip address for CS4228 */
+	outl( (RegAddr & 0xff), SSPDR );
+	outl( (RegValue & 0xff), SSPDR );
+
+	/*
+	 * Let TX fifo clear out.  Poll the Transmit Fifo Empty bit.
+	 */
+	while( !( inl(SSPSR) & SSPSR_TFE ) );
+
+	/*
+	 * Delay to let stuff make it out of the SR before doing
+	 * anthing else to the SSP.  It takes 6.8 uSec to do a
+	 * I2S codec register write.
+	 */
+	udelay(10);
+
+	/*
+	 * If we were in PS2 mode, switch back to PS2 mode.
+	 * If we weren't in PS2 mode, that means we didn't compile in
+	 * the PS2 keyboard support, so no need to switch to PS2 mode.
+	 */
+	if( saved_mode == SSP_MODE_PS2 )
+	{
+		SetSSPtoPS2();
+	}
+
+	spin_unlock(&ssp_spinlock);
+
+	/*
+	 * Return success.
+	 */
+	return 0;
+}
diff -urN linux-2.4.29/arch/arm/mach-ep93xx/time.c linux-2.4.29-uc1/arch/arm/mach-ep93xx/time.c
--- linux-2.4.29/arch/arm/mach-ep93xx/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ep93xx/time.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,44 @@
+/*
+ *  linux/arch/arm/mach-ep93xx/time.c
+ *
+ *  Copyright (C) 2000-2001 Deep Blue Solutions
+ *
+ * (c) Copyright 2001 LynuxWorks, Inc., San Jose, CA.  All rights reserved.
+ *  Copyright (C) 2002-2003 Cirrus Logic, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+extern unsigned long (*gettimeoffset)(void);
+
+/*
+ * gettimeoffset() returns time since last timer tick, in usecs.
+ *
+ * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy.
+ * 'tick' is usecs per jiffy.
+ */
+static unsigned long ep93xx_gettimeoffset(void)
+{
+	unsigned long hwticks;
+	hwticks = LATCH - (inl(TIMER1VALUE) & 0xffff);
+	return ((hwticks * tick) / LATCH);
+}
+
+void __init ep93xx_setup_timer(void)
+{
+	gettimeoffset = ep93xx_gettimeoffset;
+
+	outl(0, TIMER1CONTROL);
+	outl(LATCH - 1, TIMER1LOAD);
+	outl(0xc8, TIMER1CONTROL);
+
+	xtime.tv_sec = inl(RTCDR);
+}
diff -urN linux-2.4.29/arch/arm/mach-epxa/arch-epxa10db.c linux-2.4.29-uc1/arch/arm/mach-epxa/arch-epxa10db.c
--- linux-2.4.29/arch/arm/mach-epxa/arch-epxa10db.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-epxa/arch-epxa10db.c	2005-06-14 02:10:59.000000000 +0100
@@ -56,5 +56,5 @@
       	FIXUP(epxa10db_fixup)
 	MAPIO(epxa_map_io)
 	INITIRQ(epxa_init_irq)
-        BOOT_PARAMS(0x100)
+
 MACHINE_END
diff -urN linux-2.4.29/arch/arm/mach-epxa/irq.c linux-2.4.29-uc1/arch/arm/mach-epxa/irq.c
--- linux-2.4.29/arch/arm/mach-epxa/irq.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-epxa/irq.c	2005-06-14 02:10:59.000000000 +0100
@@ -18,10 +18,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
-#include <linux/stddef.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/io.h>
diff -urN linux-2.4.29/arch/arm/mach-integrator/kgdb-serial.c linux-2.4.29-uc1/arch/arm/mach-integrator/kgdb-serial.c
--- linux-2.4.29/arch/arm/mach-integrator/kgdb-serial.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-integrator/kgdb-serial.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,138 @@
+/*
+ * FILE NAME: arch/arm/mach-integrator/kgdb-serial.c
+ *
+ * BRIEF MODULE DESCRIPTION:
+ *  Provides low level kgdb serial support hooks for ARM Integrator.
+ *
+ * Author: George G. Davis <gdavis@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * Based on the AMBA serial port driver, filename drivers/char/serial_amba.c,
+ * Copyright 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE	LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/kgdb.h>
+#include <asm/hardware/serial_amba.h>
+
+
+
+#define UART_GET_INT_STATUS(p)	readb((p) + AMBA_UARTIIR)
+#define UART_PUT_ICR(p, c)	writel((c), (p) + AMBA_UARTICR)
+#define UART_GET_FR(p)		readb((p) + AMBA_UARTFR)
+#define UART_GET_CHAR(p)	readb((p) + AMBA_UARTDR)
+#define UART_PUT_CHAR(p, c)	writel((c), (p) + AMBA_UARTDR)
+#define UART_GET_RSR(p)		readb((p) + AMBA_UARTRSR)
+#define UART_GET_CR(p)		readb((p) + AMBA_UARTCR)
+#define UART_PUT_CR(p,c)	writel((c), (p) + AMBA_UARTCR)
+#define UART_GET_LCRL(p)	readb((p) + AMBA_UARTLCR_L)
+#define UART_PUT_LCRL(p,c)	writel((c), (p) + AMBA_UARTLCR_L)
+#define UART_GET_LCRM(p)	readb((p) + AMBA_UARTLCR_M)
+#define UART_PUT_LCRM(p,c)	writel((c), (p) + AMBA_UARTLCR_M)
+#define UART_GET_LCRH(p)	readb((p) + AMBA_UARTLCR_H)
+#define UART_PUT_LCRH(p,c)	writel((c), (p) + AMBA_UARTLCR_H)
+#define UART_RX_DATA(s)		(((s) & AMBA_UARTFR_RXFE) == 0)
+#define UART_TX_READY(s)	(((s) & AMBA_UARTFR_TXFF) == 0)
+#define UART_TX_EMPTY(p)	((UART_GET_FR(p) & AMBA_UARTFR_TMSK) == 0)
+
+#if	defined(CONFIG_KGDB_UART0)
+#	define	KGDB_SERIAL_PORT_BASE	INTEGRATOR_UART0_BASE
+#elif	defined(CONFIG_KGDB_UART1)
+#	define	KGDB_SERIAL_PORT_BASE	INTEGRATOR_UART1_BASE
+#else
+#	error "No kgdb serial port UART has been selected."
+#endif
+
+#if	defined(CONFIG_KGDB_9600BAUD)
+#	define	KGDB_SERIAL_BAUD_RATE	ARM_BAUD_9600
+#elif	defined(CONFIG_KGDB_19200BAUD)
+#	define	KGDB_SERIAL_BAUD_RATE	ARM_BAUD_19200
+#elif	defined(CONFIG_KGDB_38400BAUD)
+#	define	KGDB_SERIAL_BAUD_RATE	ARM_BAUD_38400
+#elif	defined(CONFIG_KGDB_57600BAUD)
+#	define	KGDB_SERIAL_BAUD_RATE	ARM_BAUD_57600
+#elif	defined(CONFIG_KGDB_115200BAUD)
+#	define	KGDB_SERIAL_BAUD_RATE	ARM_BAUD_115200
+#else
+#	error "kgdb serial baud rate has not been specified."
+#endif
+
+
+static volatile unsigned char *port = NULL;
+
+
+void
+kgdb_serial_init(void)
+{
+	port = (unsigned char *)(IO_ADDRESS(KGDB_SERIAL_PORT_BASE));
+
+	UART_PUT_CR(port, 0);
+
+	/* Set baud rate */
+	UART_PUT_LCRM(port, ((KGDB_SERIAL_BAUD_RATE & 0xf00) >> 8));
+	UART_PUT_LCRL(port, (KGDB_SERIAL_BAUD_RATE & 0xff));
+
+	/*
+	 * ----------v----------v----------v----------v-----
+	 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
+	 * ----------^----------^----------^----------^-----
+	 */
+	UART_PUT_LCRH(port, AMBA_UARTLCR_H_WLEN_8 | AMBA_UARTLCR_H_FEN);
+	UART_PUT_CR(port, AMBA_UARTCR_UARTEN);
+
+	return;
+}
+
+
+void
+kgdb_serial_putchar(unsigned char ch)
+{
+        unsigned int status;
+
+	do {
+		status = UART_GET_FR(port);
+	} while (!UART_TX_READY(status));
+
+	UART_PUT_CHAR(port, ch);
+}
+
+
+unsigned char
+kgdb_serial_getchar(void)
+{
+        unsigned int status;
+	unsigned char ch;
+
+	do {
+		status = UART_GET_FR(port);
+	} while (!UART_RX_DATA(status));
+
+	ch = UART_GET_CHAR(port);
+
+	return ch;
+}
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/aau.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/aau.c
--- linux-2.4.29/arch/arm/mach-iop3xx/aau.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/aau.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,950 @@
+/**************************************************************************
+ * arch/arm/mach-iop310/aau.c
+ *
+ * Support functions for the Intel 80310 AAU.
+ * (see also Documentation/arm/XScale/IOP310/aau.txt)
+ *
+ * Author: Dave Jiang (dave.jiang@intel.com)
+ * Copyright (C) 2001 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Todos:  Thorough Error handling
+ *          Do zero-size AAU transfer/channel at init
+ *              so all we have to do is chainining  
+ *
+ *
+ *  History:    (07/18/2001, DJ) Initial Creation
+ *              (08/22/2001, DJ) Changed spinlock calls to no save flags
+ *              (08/27/2001, DJ) Added irq threshold handling
+ *		(09/11/2001, DJ) Changed AAU to list data structure,
+ *			modified the user interface with embedded descriptors.
+ *
+ *************************************************************************/
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/tqueue.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <asm/system.h>
+#include <asm/types.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/arch/iq80310.h>
+#include <asm/arch/irqs.h>
+#include <asm/memory.h>
+
+#include <asm/arch/aau.h>
+
+#include "aau.h"
+
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#include <linux/module.h>
+#endif
+
+#undef DEBUG
+#ifdef DEBUG
+#define DPRINTK(s, args...) printk("80310AAU: " s, ## args)
+#else
+#define DPRINTK(s, args...)
+#endif
+
+/* globals */
+static iop310_aau_t aau_dev;	/* AAU device */
+static struct list_head free_stack;	/* free AAU desc stack */
+static spinlock_t free_lock;	/* free AAU stack lock */
+
+/* static prototypes */
+static int __init aau_init(void);
+static int aau_start(iop310_aau_t *, sw_aau_t *);
+static int aau_flush_all(u32);
+static void aau_process(iop310_aau_t *);
+static void aau_task(void *);
+static void aau_irq_handler(int, void *, struct pt_regs *);
+
+/*=======================================================================*/
+/*  Procedure:  aau_start()                                              */
+/*                                                                       */
+/*  Description:    This function starts the AAU. If the AAU             */
+/*                  has already started then chain resume will be done   */
+/*                                                                       */
+/*  Parameters:  aau: AAU device                                         */
+/*               aau_chain: AAU data chain to pass to the AAU            */
+/*                                                                       */
+/*  Returns:    int -- success: OK                                       */
+/*                     failure: -EBUSY                                   */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 07/18/01  Initial Creation                    */
+/*=======================================================================*/
+static int aau_start(iop310_aau_t * aau, sw_aau_t * aau_chain)
+{
+	u32 status;
+
+	/* get accelerator status */
+	status = *(IOP310_AAUASR);
+
+	/* check accelerator status error */
+	if(status & AAU_ASR_ERROR_MASK)
+	{
+		DPRINTK("start: Accelerator Error %x\n", status);
+		/* should clean the accelerator up then, or let int handle it? */
+		return -EBUSY;
+	}
+
+	/* if first time */
+	if(!(status & AAU_ASR_ACTIVE))
+	{
+		/* set the next descriptor address register */
+
+		*(IOP310_AAUANDAR) = aau_chain->aau_phys;
+
+		DPRINTK("Enabling accelerator now\n");
+		/* enable the accelerator */
+		*(IOP310_AAUACR) |= AAU_ACR_ENABLE;
+	}
+	else
+	{
+		DPRINTK("Resuming chain\n");
+		/* if active, chain up to last AAU chain */
+
+		aau->last_aau->aau_desc.NDA = aau_chain->aau_phys;
+
+		/* flush cache since we changed the field */
+		/* 32bit word long */
+		cpu_dcache_clean_range((u32)&aau->last_aau->aau_desc.NDA,
+			   (u32)(&aau->last_aau->aau_desc.NDA));
+
+		/* resume the chain */
+		*(IOP310_AAUACR) |= AAU_ACR_CHAIN_RESUME;
+	}
+
+	/* set the last accelerator descriptor to last descriptor in chain */
+	aau->last_aau = aau_chain->tail;
+
+	return 0;
+}
+
+
+/*=======================================================================*/
+/*  Procedure:  aau_request()                                            */
+/*                                                                       */
+/*  Description:    This function requests the AAU                       */
+/*                                                                       */
+/*  Parameters: aau_context: aau context				 */
+/*			     device_id -- unique device name             */
+/*                                                                       */
+/*  Returns:     0 - ok                                                  */
+/*               NULL -- failed                                          */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 07/18/01  Initial Creation                    */
+/*=======================================================================*/
+int aau_request(u32 * aau_context, const char *device_id)
+{
+	iop310_aau_t *aau = &aau_dev;
+
+	DPRINTK("Entering AAU request\n");
+	/* increment reference count */
+	atomic_inc(&aau->ref_count);
+
+	/* get interrupt if ref count is less than or equal to 1 */
+	if(atomic_read(&aau->ref_count) <= 1)
+	{
+		/* set device ID */
+		aau->dev_id = device_id;
+	}
+
+	DPRINTK("Assigning AAU\n");
+	*aau_context = (u32) aau;
+
+	return 0;
+}
+
+/*=======================================================================*/
+/*  Procedure:  aau_suspend()                                            */
+/*                                                                       */
+/*  Description:    This function suspends the AAU at the earliest       */
+/*                  instant it is capable of.                            */
+/*                                                                       */
+/*  Parameters:  aau: AAU device context                                */
+/*                                                                       */
+/*  Returns:     N/A                                                     */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 07/18/01  Initial Creation                    */
+/*=======================================================================*/
+void aau_suspend(u32 aau_context)
+{
+	iop310_aau_t *aau = (iop310_aau_t *) aau_context;
+	*(IOP310_AAUACR) &= ~AAU_ACR_ENABLE;
+}
+
+/*=======================================================================*/
+/*  Procedure:  aau_resume()                                             */
+/*                                                                       */
+/*  Description:    This function resumes the AAU operations             */
+/*                                                                       */
+/*  Parameters:  aau: AAU device context                                */
+/*                                                                       */
+/*  Returns:     N/A                                                     */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 07/18/01  Initial Creation                    */
+/*=======================================================================*/
+void aau_resume(u32 aau_context)
+{
+	iop310_aau_t *aau = (iop310_aau_t *) aau_context;
+	u32 status;
+
+	status = *(IOP310_AAUASR);
+
+	/* if it's already active */
+	if(status & AAU_ASR_ACTIVE)
+	{
+		DPRINTK("Accelerator already active\n");
+		return;
+	}
+	else if(status & AAU_ASR_ERROR_MASK)
+	{
+		printk("80310 AAU in error state! Cannot resume\n");
+		return;
+	}
+	else
+	{
+		*(IOP310_AAUACR) |= AAU_ACR_ENABLE;
+	}
+}
+
+/*=======================================================================*/
+/*  Procedure:  aau_queue_buffer()                                       */
+/*                                                                       */
+/*  Description:    This function creates an AAU buffer chain from the   */
+/*                  user supplied SGL chain. It also puts the AAU chain  */
+/*                  onto the processing queue. This then starts the AAU  */
+/*                                                                       */
+/*  Parameters:  aau: AAU device context                                */
+/*               listhead: User SGL                                      */
+/*                                                                       */
+/*  Returns:     int: success -- OK                                      */
+/*                    failed: -ENOMEM                                    */
+/*                                                                       */
+/*  Notes/Assumptions:  User SGL must point to kernel memory, not user   */
+/*                                                                       */
+/*  History:    Dave Jiang 07/18/01  Initial Creation                    */
+/*              Dave Jiang 07/20/01  Removed some junk code not suppose  */
+/*                  to be there that will cause infinite loop            */
+/*=======================================================================*/
+int aau_queue_buffer(u32 aau_context, aau_head_t * listhead)
+{
+	sw_aau_t *sw_desc = (sw_aau_t *) listhead->list;
+	sw_aau_t *prev_desc = NULL;
+	sw_aau_t *head = NULL;
+	aau_head_t *sgl_head = listhead;
+	int err = 0;
+	int i;
+	iop310_aau_t *aau = (iop310_aau_t *) aau_context;
+	DECLARE_WAIT_QUEUE_HEAD(wait_q);
+
+	DPRINTK("Entering aau_queue_buffer()\n");
+
+	/* scan through entire user SGL */
+	while(sw_desc)
+	{
+		sw_desc->sgl_head = (u32) listhead;
+
+		/* we clean the cache for previous descriptor in chain */
+		if(prev_desc)
+		{
+			prev_desc->aau_desc.NDA = sw_desc->aau_phys;
+			cpu_dcache_clean_range((u32)&prev_desc->aau_desc,
+			   (u32)&prev_desc->aau_desc + AAU_DESC_SIZE);
+		}
+		else
+		{
+			/* no previous descriptor, so we set this to be head */
+			head = sw_desc;
+		}
+
+		sw_desc->head = head;
+		/* set previous to current */
+		prev_desc = sw_desc;
+
+		/* put descriptor on process */
+		spin_lock_irq(&aau->process_lock);
+		list_add_tail(&sw_desc->link, &aau->process_q);
+		spin_unlock_irq(&aau->process_lock);
+
+		sw_desc = (sw_aau_t *)sw_desc->next;
+	}
+	DPRINTK("Done converting SGL to AAU Chain List\n");
+
+	/* if our tail exists */
+	if(prev_desc)
+	{
+		/* set the head pointer on tail */
+		prev_desc->head = head;
+		/* set the header pointer's tail to tail */
+		head->tail = prev_desc;
+		prev_desc->tail = prev_desc;
+
+		/* clean cache for tail */
+		cpu_dcache_clean_range((u32)&prev_desc->aau_desc, 
+			(u32)&prev_desc->aau_desc + AAU_DESC_SIZE);
+
+		DPRINTK("Starting AAU accelerator\n");
+		/* start the AAU */
+		DPRINTK("Starting at chain: 0x%x\n", (u32)head);
+		if((err = aau_start(aau, head)) >= 0)
+		{
+			DPRINTK("ASR: %#x\n", *IOP310_AAUASR);
+			if(!sgl_head->callback)
+			{
+				wait_event_interruptible(aau->wait_q, 
+					(sgl_head->status & AAU_COMPLETE));
+			}
+			return 0;
+		}
+		else
+		{
+			DPRINTK("AAU start failed!\n");
+			return err;
+		}
+	}
+
+	return -EINVAL;
+}
+
+/*=======================================================================*/
+/*  Procedure:  aau_flush_all()                                          */
+/*                                                                       */
+/*  Description:    This function flushes the entire process queue for   */
+/*                  the AAU. It also clears the AAU.                     */
+/*                                                                       */
+/*  Parameters:  aau: AAU device context                                 */
+/*                                                                       */
+/*  Returns:     int: success -- OK                                      */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 07/19/01  Initial Creation                    */
+/*=======================================================================*/
+static int aau_flush_all(u32 aau_context)
+{
+	iop310_aau_t *aau = (iop310_aau_t *) aau_context;
+	int flags;
+	sw_aau_t *sw_desc;
+
+	DPRINTK("Flushall is being called\n");
+
+	/* clear ACR */
+	/* read clear ASR */
+	*(IOP310_AAUACR) = AAU_ACR_CLEAR;
+	*(IOP310_AAUASR) |= AAU_ASR_CLEAR;
+
+	/* clean up processing Q */
+	while(!list_empty(&aau->hold_q))
+	{
+		spin_lock_irqsave(&aau->process_lock, flags);
+		sw_desc = SW_ENTRY(aau->process_q.next);
+		list_del(aau->process_q.next);
+		spin_unlock_irqrestore(&aau->process_lock, flags);
+
+		/* set status to be incomplete */
+		sw_desc->status |= AAU_INCOMPLETE;
+		/* put descriptor on holding queue */
+		spin_lock_irqsave(&aau->hold_lock, flags);
+		list_add_tail(&sw_desc->link, &aau->hold_q);
+		spin_unlock_irqrestore(&aau->hold_lock, flags);
+	}
+
+	return 0;
+}
+
+/*=======================================================================*/
+/*  Procedure:  aau_free()                                               */
+/*                                                                       */
+/*  Description:    This function frees the AAU from usage.              */
+/*                                                                       */
+/*  Parameters:  aau -- AAU device context                               */
+/*                                                                       */
+/*  Returns:     int: success -- OK                                      */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 07/19/01  Initial Creation                    */
+/*=======================================================================*/
+void aau_free(u32 aau_context)
+{
+	iop310_aau_t *aau = (iop310_aau_t *) aau_context;
+
+	atomic_dec(&aau->ref_count);
+
+	/* if ref count is 1 or less, you are the last owner */
+	if(atomic_read(&aau->ref_count) <= 1)
+	{
+		/* flush AAU channel */
+		aau_flush_all(aau_context);
+		/* flush holding queue */
+		aau_task(aau);
+
+		if(aau->last_aau)
+		{
+			aau->last_aau = NULL;
+		}
+
+		DPRINTK("Freeing IRQ %d\n", aau->irq);
+		/* free the IRQ */
+		free_irq(aau->irq, (void *)aau);
+	}
+
+	DPRINTK("freed\n");
+}
+
+/*=======================================================================*/
+/*  Procedure:  aau_irq_handler()                                        */
+/*                                                                       */
+/*  Description:    This function is the int handler for the AAU         */
+/*                  driver. It removes the done AAU descriptors from the */
+/*                  process queue and put them on the holding Q. it will */
+/*                  continue to process until process queue empty or the */
+/*                  current AAU desc on the accelerator is the one we    */
+/*                  are inspecting                                       */
+/*                                                                       */
+/*  Parameters:  irq:  IRQ activated                                     */
+/*               dev_id: device                                          */
+/*               regs:  registers                                        */
+/*                                                                       */
+/*  Returns:    NONE                                                     */
+/*                                                                       */
+/*  Notes/Assumptions: Interupt is masked                                */
+/*                                                                       */
+/*  History:    Dave Jiang 07/19/01  Initial Creation                    */
+/*              Dave Jiang 07/20/01  Check FIQ1 instead of ASR for INTs  */
+/*=======================================================================*/
+static void aau_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	iop310_aau_t *aau = (iop310_aau_t *) dev_id;
+	u32 int_status = 0;
+	u32 status = 0;
+	u32 thresh;
+
+	/* get FIQ1 status */
+	int_status = *(IOP310_FIQ1ISR);
+
+	DPRINTK("IRQ: irq=%d status=%#x\n", irq, status);
+
+	/* this is not our interrupt */
+	if(!(int_status & AAU_INT_MASK))
+	{
+		return;
+	}
+
+	/* get accelerator status */
+	status = *(IOP310_AAUASR);
+
+	/* get threshold */
+	thresh = atomic_read(&aau->irq_thresh);
+
+	/* process while we have INT */
+	while((int_status & AAU_INT_MASK) && thresh--)
+	{
+		/* clear ASR */
+		*(IOP310_AAUASR) &= AAU_ASR_MASK;
+
+		/* flush all with err condition */
+		if(status & AAU_ASR_DONE_MASK)
+		{
+			aau_process(aau);
+		}
+
+		/* read accelerator status */
+		status = *(IOP310_AAUASR);
+
+		/* get interrupt status */
+		int_status = *(IOP310_FIQ1ISR);
+	}
+
+	/* schedule bottom half */
+	aau->aau_task.data = (void *)aau;
+	/* task goes to the immediate task queue */
+	queue_task(&aau->aau_task, &tq_immediate);
+	/* mark IMMEDIATE BH for execute */
+	mark_bh(IMMEDIATE_BH);
+}
+
+
+/*=======================================================================*/
+/*  Procedure:  aau_process()                                            */
+/*                                                                       */
+/*  Description:    This function processes moves all the AAU desc in    */
+/*                  the processing queue that are considered done to the */
+/*                  holding queue. It is called by the int when the      */
+/*                  done INTs are asserted. It will continue until       */
+/*                  either the process Q is empty or current AAU desc    */
+/*                  equals to the one in the ADAR                        */
+/*                                                                       */
+/*  Parameters:  aau: AAU device as parameter                            */
+/*                                                                       */
+/*  Returns:    NONE                                                     */
+/*                                                                       */
+/*  Notes/Assumptions: Interrupt is masked                               */
+/*                                                                       */
+/*  History:    Dave Jiang 07/19/01  Initial Creation                    */
+/*=======================================================================*/
+static void aau_process(iop310_aau_t * aau)
+{
+	sw_aau_t *sw_desc;
+	u8 same_addr = 0;
+
+	DPRINTK("Entering aau_process()\n");
+
+	while(!same_addr && !list_empty(&aau->process_q))
+	{
+		spin_lock(&aau->process_lock);
+		sw_desc = SW_ENTRY(aau->process_q.next);
+		list_del(aau->process_q.next);
+		spin_unlock(&aau->process_lock);
+
+		if(sw_desc->head->tail->status & AAU_NEW_HEAD)
+		{
+			DPRINTK("Found new head\n");
+			sw_desc->tail->head = sw_desc;
+			sw_desc->head = sw_desc;
+			sw_desc->tail->status &= ~AAU_NEW_HEAD;
+		}
+
+		sw_desc->status |= AAU_DESC_DONE;
+
+		/* if we see end of chain, we set head status to DONE */
+		if(sw_desc->aau_desc.DC & AAU_DCR_IE)
+		{
+			if(sw_desc->status & AAU_END_CHAIN)
+			{
+				sw_desc->tail->status |= AAU_COMPLETE;
+			}
+			else
+			{
+				sw_desc->head->tail = sw_desc;
+				sw_desc->tail = sw_desc;
+				sw_desc->tail->status |= AAU_NEW_HEAD;
+			}
+			sw_desc->tail->status |= AAU_NOTIFY;
+		}
+
+		/* if descriptor equal same being proccessed, put it back */
+		if(((u32) sw_desc == *(IOP310_AAUADAR)
+		   ) && ( *(IOP310_AAUASR) & AAU_ASR_ACTIVE))
+		{
+			spin_lock(&aau->process_lock);
+			list_add(&sw_desc->link, &aau->process_q);
+			spin_unlock(&aau->process_lock);
+			same_addr = 1;
+		}
+		else
+		{
+			spin_lock(&aau->hold_lock);
+			list_add_tail(&sw_desc->link, &aau->hold_q);
+			spin_unlock(&aau->hold_lock);
+		}
+	}			
+	DPRINTK("Exit aau_process()\n");
+}
+
+/*=======================================================================*/
+/*  Procedure:  aau_task()                                               */
+/*                                                                       */
+/*  Description:    This func is the bottom half handler of the AAU INT  */
+/*                  handler. It is queued as an imm task on the imm      */
+/*                  task Q. It process all the complete AAU chain in the */
+/*                  holding Q and wakes up the user and frees the        */
+/*                  resource.                                            */
+/*                                                                       */
+/*  Parameters:  aau_dev: AAU device as parameter                        */
+/*                                                                       */
+/*  Returns:    NONE                                                     */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 07/19/01  Initial Creation                    */
+/*=======================================================================*/
+static void aau_task(void *aau_dev)
+{
+	iop310_aau_t *aau = (iop310_aau_t *) aau_dev;
+	u8 end_chain = 0;
+	sw_aau_t *sw_desc = NULL;
+	aau_head_t *listhead = NULL;	/* user list */
+
+	DPRINTK("Entering bottom half\n");
+
+	if(!list_empty(&aau->hold_q))
+	{
+		sw_desc = SW_ENTRY(aau->hold_q.next);
+		listhead = (aau_head_t *) sw_desc->sgl_head;
+	}
+	else
+		return;
+
+	/* process while AAU chain is complete */
+	while(sw_desc && (sw_desc->tail->status & (AAU_NOTIFY | AAU_INCOMPLETE)))
+	{
+		/* clean up until end of AAU chain */
+		while(!end_chain)
+		{
+			/* IE flag indicate end of chain */
+			if(sw_desc->aau_desc.DC & AAU_DCR_IE)
+			{
+				end_chain = 1;
+				listhead->status |= 
+					sw_desc->tail->status & AAU_USER_MASK;
+
+				sw_desc->status |= AAU_NOTIFY;
+
+				if(sw_desc->status & AAU_END_CHAIN)
+					listhead->status |= AAU_COMPLETE;
+			}
+
+			spin_lock_irq(&aau->hold_lock);
+			/* remove from holding queue */
+			list_del(&sw_desc->link);
+			spin_unlock_irq(&aau->hold_lock);
+
+			cpu_dcache_invalidate_range((u32)&sw_desc->aau_desc,
+				(u32)&sw_desc->aau_desc + AAU_DESC_SIZE);
+
+			if(!list_empty(&aau->hold_q))
+			{
+				sw_desc = SW_ENTRY(aau->hold_q.next);
+				listhead = (aau_head_t *) sw_desc->sgl_head;
+			}
+			else
+				sw_desc = NULL;
+		}
+
+		/* reset end of chain flag */
+		end_chain = 0;
+
+		/* wake up user function waiting for return */
+		/* or use callback if exist */
+		if(listhead->callback)
+		{
+			DPRINTK("Calling callback\n");
+			listhead->callback((void *)listhead);
+		}
+		else if(listhead->status & AAU_COMPLETE)
+			/* if(waitqueue_active(&aau->wait_q)) */
+		{
+			DPRINTK("Waking up waiting process\n");
+			wake_up_interruptible(&aau->wait_q);
+		}
+	}							/* end while */
+	DPRINTK("Exiting bottom task\n");
+}
+
+/*=======================================================================*/
+/*  Procedure:  aau_init()                                               */
+/*                                                                       */
+/*  Description:    This function initializes the AAU.                   */
+/*                                                                       */
+/*  Parameters:  NONE                                                    */
+/*                                                                       */
+/*  Returns:     int: success -- OK                                      */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 07/18/01  Initial Creation                    */
+/*=======================================================================*/
+static int __init aau_init(void)
+{
+	int i;
+	sw_aau_t *sw_desc;
+	int err;
+	void *desc = NULL;
+
+	printk("Intel 80310 AAU Copyright(c) 2001 Intel Corporation\n");
+	DPRINTK("Initializing...");
+
+	/* set the IRQ */
+	aau_dev.irq = IRQ_IOP310_AAU;
+
+	err = request_irq(aau_dev.irq, aau_irq_handler, SA_INTERRUPT,
+					  NULL, (void *)&aau_dev);
+	if(err < 0)
+	{
+		printk(KERN_ERR "unable to request IRQ %d for AAU: %d\n",
+			   aau_dev.irq, err);
+		return err;
+	}
+
+	/* init free stack */
+	INIT_LIST_HEAD(&free_stack);
+	/* init free stack spinlock */
+	spin_lock_init(&free_lock);
+
+
+	/* pre-alloc AAU descriptors */
+	for(i = 0; i < MAX_AAU_DESC; i++)
+	{
+		desc = kmalloc((sizeof(sw_aau_t) + 0x20), GFP_KERNEL);
+		memset(desc, 0, sizeof(sw_aau_t));
+		sw_desc = (sw_aau_t *) (((u32) desc & 0xffffffe0) + 0x20);
+		sw_desc->aau_phys = virt_to_phys((void *)sw_desc);
+		/* we keep track of original address before alignment adjust */
+		/* so we can free it later */
+		sw_desc->desc_addr = (u32) desc;
+
+		spin_lock_irq(&free_lock);
+		/* put the descriptors on the free stack */
+		list_add_tail(&sw_desc->link, &free_stack);
+		spin_unlock_irq(&free_lock);
+	}
+
+	/* set the register data structure to the mapped memory regs AAU */
+	aau_dev.regs = (aau_regs_t *) IOP310_AAUACR;
+
+	atomic_set(&aau_dev.ref_count, 0);
+
+	/* init process Q */
+	INIT_LIST_HEAD(&aau_dev.process_q);
+	/* init holding Q */
+	INIT_LIST_HEAD(&aau_dev.hold_q);
+	/* init locks for Qs */
+	spin_lock_init(&aau_dev.hold_lock);
+	spin_lock_init(&aau_dev.process_lock);
+
+	aau_dev.last_aau = NULL;
+
+	/* initialize BH task */
+	aau_dev.aau_task.sync = 0;
+	aau_dev.aau_task.routine = (void *)aau_task;
+
+	/* initialize wait Q */
+	init_waitqueue_head(&aau_dev.wait_q);
+
+	/* clear AAU channel control register */
+	*(IOP310_AAUACR) = AAU_ACR_CLEAR;
+	*(IOP310_AAUASR) = AAU_ASR_CLEAR;
+	*(IOP310_AAUANDAR) = 0;
+
+	/* set default irq threshold */
+	atomic_set(&aau_dev.irq_thresh, DEFAULT_AAU_IRQ_THRESH);
+	DPRINTK("Done!\n");
+
+	return 0;
+}	
+
+/*=======================================================================*/
+/*  Procedure:  aau_set_irq_threshold()                                  */
+/*                                                                       */
+/*  Description:  This function readjust the threshold for the irq.      */
+/*                                                                       */
+/*  Parameters:  aau: pointer to aau device descriptor                   */
+/*               value: value of new irq threshold                       */
+/*                                                                       */
+/*  Returns:     N/A                                                     */
+/*                                                                       */
+/*  Notes/Assumptions:  default is set at 10                             */
+/*                                                                       */
+/*  History:    Dave Jiang 08/27/01  Initial Creation                    */
+/*=======================================================================*/
+void aau_set_irq_threshold(u32 aau_context, int value)
+{
+	iop310_aau_t *aau = (iop310_aau_t *) aau_context;
+	atomic_set(&aau->irq_thresh, value);
+}								/* End of aau_set_irq_threshold() */
+
+
+/*=======================================================================*/
+/*  Procedure:  aau_get_buffer()                                         */
+/*                                                                       */
+/*  Description:    This function acquires an SGL element for the user   */
+/*                  and returns that. It will retry multiple times if no */
+/*                  descriptor is available.                             */
+/*                                                                       */
+/*  Parameters:  aau_context: AAU context                                */
+/*               num_buf:  number of descriptors                         */
+/*                                                                       */
+/*  Returns:     N/A                                                     */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 9/11/01  Initial Creation                     */
+/*		 Dave Jiang 10/04/01	Fixed list linking problem	  */
+/*=======================================================================*/
+aau_sgl_t *aau_get_buffer(u32 aau_context, int num_buf)
+{
+	sw_aau_t *sw_desc = NULL;
+	sw_aau_t *sw_head = NULL;
+	sw_aau_t *sw_prev = NULL;
+
+	int retry = 10;
+	int i;
+	DECLARE_WAIT_QUEUE_HEAD(wait_q);
+
+	if((num_buf > MAX_AAU_DESC) || (num_buf <= 0))
+	{
+		return NULL;
+	}
+
+	DPRINTK("Getting %d descriptors\n", num_buf);
+	for(i = num_buf; i > 0; i--)
+	{
+		spin_lock_irq(&free_lock);
+		if(!list_empty(&free_stack))
+		{
+			sw_desc = SW_ENTRY(free_stack.next);
+			list_del(free_stack.next);
+			spin_unlock_irq(&free_lock);
+		}
+		else
+		{
+			while(retry-- && !sw_desc)
+			{
+				spin_unlock_irq(&free_lock);
+				interruptible_sleep_on_timeout(&wait_q, SLEEP_TIME);
+				spin_lock_irq(&free_lock);
+				if(!list_empty(&free_stack))
+				{
+					sw_desc = SW_ENTRY(free_stack.next);
+					list_del(free_stack.next);
+				}
+				spin_unlock_irq(&free_lock);
+			}
+
+			sw_desc = sw_head;
+			spin_lock_irq(&free_lock);
+			while(sw_desc)
+			{
+				sw_desc->status = 0;
+				sw_desc->head = NULL;
+				sw_desc->tail = NULL;
+				list_add(&sw_desc->link, &free_stack);
+				sw_desc = (sw_aau_t *) sw_desc->next;
+			}					/* end while */
+			spin_unlock_irq(&dma_free_lock);
+			return NULL;
+		}						/* end else */
+
+		if(sw_prev)
+		{
+			sw_prev->next = (aau_sgl_t *) sw_desc;
+			sw_prev->aau_desc.NDA = sw_desc->aau_phys;
+		}
+		else
+		{
+			sw_head = sw_desc;
+		}
+
+		sw_prev = sw_desc;
+	}							/* end for */
+
+	sw_desc->aau_desc.NDA = 0;
+	sw_desc->next = NULL;
+	sw_desc->status = 0;
+	return (aau_sgl_t *) sw_head;
+}	
+
+
+/*=======================================================================*/
+/*  Procedure:  aau_return_buffer()                                      */
+/*                                                                       */
+/*  Description:    This function takes a list of SGL and return it to   */
+/*                  the free stack.                                      */
+/*                                                                       */
+/*  Parameters:  aau_context: AAU context                                */
+/*               list: SGL list to return to free stack                  */
+/*                                                                       */
+/*  Returns:     N/A                                                     */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 9/11/01  Initial Creation                     */
+/*=======================================================================*/
+void aau_return_buffer(u32 aau_context, aau_sgl_t * list)
+{
+	sw_aau_t *sw_desc = (sw_aau_t *) list;
+
+	spin_lock_irq(&free_lock);
+	while(sw_desc)
+		if(sw_desc)
+		{
+			list_add(&sw_desc->link, &free_stack);
+			sw_desc = (sw_aau_t *) sw_desc->next;
+		}
+	spin_unlock_irq(&free_lock);
+}
+
+/* no cache coherency done on data. user need to take care of that */
+int aau_memcpy(void *dest, void *src, u32 size)
+{
+	iop310_aau_t *aau = &aau_dev;
+	aau_head_t head;
+	aau_sgl_t *list;
+	int err;
+
+	head.total = size;
+	head.status = 0;
+	head.callback = NULL;
+
+	list = aau_get_buffer((u32) aau, 1);
+	if(list)
+	{
+		head.list = list;
+	}
+	else
+	{
+		return -ENOMEM;
+	}
+
+	while(list)
+	{
+		list->status = 0;
+		list->src[0] = src;
+		list->aau_desc.SAR[0] = (u32) virt_to_phys(src);
+		list->dest = dest;
+		list->aau_desc.DAR = (u32) virt_to_phys(dest);
+		list->aau_desc.BC = size;
+		list->aau_desc.DC = AAU_DCR_WRITE | AAU_DCR_BLKCTRL_1_DF;
+		if(!list->next)
+		{
+			list->aau_desc.DC |= AAU_DCR_IE;
+			list->status |= AAU_END_CHAIN;
+			break;
+		}
+		list = list->next;
+	}
+	err = aau_queue_buffer((u32) aau, &head);
+	aau_return_buffer((u32) aau, head.list);
+	return err;
+}	
+
+EXPORT_SYMBOL_NOVERS(aau_request);
+EXPORT_SYMBOL_NOVERS(aau_queue_buffer);
+EXPORT_SYMBOL_NOVERS(aau_suspend);
+EXPORT_SYMBOL_NOVERS(aau_resume);
+EXPORT_SYMBOL_NOVERS(aau_free);
+EXPORT_SYMBOL_NOVERS(aau_set_irq_threshold);
+EXPORT_SYMBOL_NOVERS(aau_get_buffer);
+EXPORT_SYMBOL_NOVERS(aau_return_buffer);
+EXPORT_SYMBOL_NOVERS(aau_memcpy);
+
+module_init(aau_init);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dave Jiang <dave.jiang@intel.com>");
+MODULE_DESCRIPTION("Driver for IOP3xx Application Accelerator Unit");
+
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/aau.h linux-2.4.29-uc1/arch/arm/mach-iop3xx/aau.h
--- linux-2.4.29/arch/arm/mach-iop3xx/aau.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/aau.h	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ * Private Definitions for XScale AAU 
+ *
+ * Author: Dave Jiang (dave.jiang@intel.com)
+ * Copyright (C) 2001 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _AAU_PRIVATE_H_
+#define _AAU_PRIVATE_H_
+
+#define SLEEP_TIME          50
+#define AAU_DESC_SIZE		48
+#define AAU_INT_MASK        0x0020
+
+#define AAU_ACR_CLEAR           0x00000000
+#define AAU_ACR_ENABLE          0x00000001
+#define AAU_ACR_CHAIN_RESUME    0x00000002
+#define AAU_ACR_512_BUFFER      0x00000004
+
+#define AAU_ASR_CLEAR           0x00000320
+#define AAU_ASR_MA_ABORT        0x00000020
+#define AAU_ASR_ERROR_MASK      AAU_ASR_MA_ABORT
+#define AAU_ASR_DONE_EOT        0x00000200
+#define AAU_ASR_DONE_EOC        0x00000100
+#define AAU_ASR_DONE_MASK       (AAU_ASR_DONE_EOT | AAU_ASR_DONE_EOC)
+#define AAU_ASR_ACTIVE          0x00000400
+#define AAU_ASR_MASK            (AAU_ASR_ERROR_MASK | AAU_ASR_DONE_MASK)
+
+/* software descriptor */
+typedef struct _sw_aau
+{
+	aau_desc_t aau_desc;		/* AAU HW Desc */
+	u32 status;
+	struct _aau_sgl *next;		/* pointer to next SG */
+	void *dest;					/* destination addr */
+	void *src[AAU_SAR_GROUP];	/* source addr[4] */
+	void *ext_src[AAU_SAR_GROUP];	/* ext src addr[4] */
+	u32 total_src;				/* total number of source */
+	struct list_head link;		/* Link to queue */
+	u32 aau_phys;				/* AAU Phys Addr (aligned) */
+	u32 desc_addr;				/* unaligned HWDESC virtual addr */
+	u32 sgl_head;
+	struct _sw_aau *head;		/* head of list */
+	struct _sw_aau *tail;		/* tail of list */
+} sw_aau_t;
+
+/* AAU registers */
+typedef struct _aau_regs_t
+{
+	volatile u32 ACR;			/* Accelerator Control Register */
+	volatile u32 ASR;			/* Accelerator Status Register */
+	volatile u32 ADAR;			/* Descriptor Address Register */
+	volatile u32 ANDAR;			/* Next Desc Address Register */
+	volatile u32 LSAR[AAU_SAR_GROUP];	/* source addrs */
+	volatile u32 LDAR;			/* local destination address register */
+	volatile u32 ABCR;			/* byte count */
+	volatile u32 ADCR;			/* Descriptor Control */
+	volatile u32 LSARE[AAU_SAR_GROUP];	/* extended src addrs */
+} aau_regs_t;
+
+
+/* device descriptor */
+typedef struct _iop310_aau_t
+{
+	const char *dev_id;			/* Device ID */
+	struct list_head process_q;	/* Process Q */
+	struct list_head hold_q;	/* Holding Q */
+	spinlock_t process_lock;	/* PQ spinlock */
+	spinlock_t hold_lock;		/* HQ spinlock */
+	aau_regs_t *regs;			/* AAU registers */
+	int irq;					/* IRQ number */
+	sw_aau_t *last_aau;			/* ptr to last AAU desc */
+	struct tq_struct aau_task;	/* AAU task entry */
+	wait_queue_head_t wait_q;	/* AAU wait queue */
+	atomic_t ref_count;			/* AAU ref count */
+	atomic_t irq_thresh;		/* IRQ threshold */
+} iop310_aau_t;
+
+#define SW_ENTRY(list) list_entry((list), sw_aau_t, link)
+
+#endif
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/arch.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/arch.c
--- linux-2.4.29/arch/arm/mach-iop3xx/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/arch.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,81 @@
+/*
+ * linux/arch/arm/mach-iop3xx/arch.c
+ *
+ * Author: Nicolas Pitre <nico@cam.org>
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#ifdef CONFIG_ARCH_IQ80310
+extern void iq80310_map_io(void);
+extern void iq80310_init_irq(void);
+#endif
+
+#ifdef CONFIG_ARCH_IQ80321
+extern void iq80321_map_io(void);
+extern void iop321_init_irq(void);
+#endif
+
+static void __init
+fixup_iop3xx(struct machine_desc *desc, struct param_struct *params,
+	      char **cmdline, struct meminfo *mi)
+{
+	/*
+	 * DIE DIE DIE
+	 *
+	 * This needs to go in the commandline or in the bootparams
+	 * from the bootloader
+	 */
+	if(machine_is_iq80310()) {
+		mi->bank[0].start = PHYS_OFFSET;
+		mi->bank[0].size  = (32*1024*1024);
+		mi->bank[0].node  = 0;
+		mi->nr_banks      = 1;
+	}
+	if(machine_is_iq80321()) {
+		mi->bank[0].start = PHYS_OFFSET;
+		mi->bank[0].size  = (128*1024*1024);
+		mi->bank[0].node  = 0;
+		mi->nr_banks      = 1;
+	}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	setup_ramdisk( 1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE );
+	setup_initrd( phys_to_virt(0xa0800000), 4*1024*1024 );
+#endif
+}
+
+#ifdef CONFIG_ARCH_IQ80310
+MACHINE_START(IQ80310, "Cyclone IQ80310")
+	MAINTAINER("MontaVista Software Inc.")
+	BOOT_MEM(0xa0000000, 0xfe000000, 0xfe000000)
+	FIXUP(fixup_iop3xx)
+	MAPIO(iq80310_map_io)
+	INITIRQ(iq80310_init_irq)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_IQ80321
+MACHINE_START(IQ80321, "Intel IQ80321")
+	MAINTAINER("MontaVista Software, Inc.")
+	BOOT_MEM(0xa0000000, 0xfe800000, 0xfe800000)
+	FIXUP(fixup_iop3xx)
+	MAPIO(iq80321_map_io)
+	INITIRQ(iop321_init_irq)
+MACHINE_END
+#endif
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/cache_test.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/cache_test.c
--- linux-2.4.29/arch/arm/mach-iop3xx/cache_test.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/cache_test.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,231 @@
+
+#include <linux/kernel.h>
+#include <linux/cache.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/hardware.h>
+#include <asm/cpu-single.h>
+#include <asm/xscale-lock.h>
+#include <asm/proc/cache.h>
+#include <asm/io.h>
+
+static __init u32 data_A = 0xDEADBEEF;
+static __init u32 data_B = 0xFACEFACE;
+
+static int __init cache_test(void)
+{
+	u32 *uncached_addr = 0;
+	u32 *real_uncached = 0;
+	dma_addr_t dma_handle;	
+	u32 *cached_alias = 0;
+	int i = 0;
+	u8 cached[128], cached1[128], uncached[128], uncached1[128] = {0};
+	u32 control;
+
+	real_uncached = (u32*)consistent_alloc(GFP_KERNEL, 136, &dma_handle);
+	cached_alias = (u32*)bus_to_virt(dma_handle);
+	uncached_addr = real_uncached + 4;
+	cached_alias += 4;
+
+	printk("TESTING XSCALE CACHE COHERENCY\n");
+	cli();
+	asm ("mrc p15, 0, %0, c1, c0, 0" : "=r" (control));
+	sti();
+	printk("Control = %#010x\n", control);
+	cli();
+	asm ("mrc p15, 0, %0, c1, c0, 1" : "=r" (control));
+	sti();
+	printk("Control1 = %#010x\n", control);
+	printk("uncached_addr @ %#010x\n", (u32)uncached_addr);
+	printk("dma_handle @ %#010x\n", dma_handle);
+	printk("cached alias & %#010x\n", (u32)cached_alias);
+	printk("data_A = %#010x\n", data_A);
+	printk("data_B = %#010x\n", data_B);
+
+	for(i = 0; i < 128/sizeof(u32); i++)
+		cached_alias[i] = uncached_addr[i] = 0;
+
+	cli();
+
+	cpu_cache_clean_invalidate_all();
+
+	/*
+	 * Force a cache preload since we read-allocate
+	 */
+	for(i = 0; i < 128/sizeof(u32); i++)
+		cached[i] = (u8)cached_alias[i];
+
+
+	for(i = 0; i < 128/sizeof(u32); i++)
+	{
+		uncached_addr[i] = data_A;
+		cached_alias[i] = data_B;
+	}
+
+	for(i = 0; i < 128/sizeof(u32); i++)
+	{
+		if(cached_alias[i] == data_B)
+			cached[i] = 0;
+		else if(cached_alias[i] == data_A)
+			cached[i] = 1;
+		else
+			panic("BAD");
+
+		if(uncached_addr[i] == data_B)
+			uncached[i] = 0;
+		else if(uncached_addr[i] == data_A)
+			uncached[i] = 1;
+		else
+			panic("BAD");
+	}
+
+	consistent_sync(cached_alias, 128, PCI_DMA_FROMDEVICE);
+
+	for(i = 0; i < 128/sizeof(u32); i++)
+	{
+		if(cached_alias[i] == data_B)
+			cached1[i] = 0;
+		else if(cached_alias[i] == data_A)
+			cached1[i] = 1;
+		else
+			panic("BAD");
+
+		if(uncached_addr[i] == data_B)
+			uncached1[i] = 0;
+		else if(uncached_addr[i] == data_A)
+			uncached1[i] = 1;
+		else
+			panic("BAD");
+	}
+
+	sti();
+
+	printk("Ran cache invalidation test\n");
+	printk("Pre-sync:\n");
+	for(i = 0; i < 128/sizeof(u32); i++)
+	{
+		if(uncached[i])
+			printk("   data_A in uncached_addr[%d]\n", i);
+		else
+			printk("   data_B in uncached_addr[%d]\n", i);
+		if(cached[i])
+			printk("   data_A in cached_alias[%d]\n", i);
+		else
+			printk("   data_B in cached_alias[%d]\n", i);
+	}
+
+	printk("Post-sync:\n");
+	for(i = 0; i < 128/sizeof(u32); i++)
+	{
+		if(uncached1[i])
+			printk("   data_A in uncached_addr[%d]\n", i);
+		else
+			printk("   data_B in uncached_addr[%d]\n", i);
+		if(cached1[i])
+			printk("   data_A in cached_alias[%d]\n", i);
+		else
+			printk("   data_B in cached_alias[%d]\n", i);
+	}
+
+	for(i = 0; i < 128/sizeof(u32); i++)
+	{
+		uncached_addr[i] = 0;
+		cached_alias[i] = 0;
+		cached[i] = 0;
+		uncached[i] = 0;
+		cached1[i] = 0;
+		uncached1[i] = 0;
+	}
+
+	cli();
+
+	cpu_cache_clean_invalidate_all();
+
+	/*
+	 * Force a cache preload since we read-allocate
+	 */
+	for(i = 0; i < 128/sizeof(u32); i++)
+		cached[i] = (u8)cached_alias[i];
+
+	for(i = 0; i < 128/sizeof(u32); i++)
+	{
+		cached_alias[i] = data_A;
+		uncached_addr[i] = data_B;
+	}
+
+	for(i = 0; i < 128/sizeof(u32); i++)
+	{
+		if(cached_alias[i] == data_A)
+			cached[i] = 1;
+		else if(cached_alias[i] == data_B)
+		  	cached[i] = 0;
+		else
+			panic("BAD");
+
+		if(uncached_addr[i] == data_A)
+			uncached[i] = 1;
+		else if(uncached_addr[i] == data_B)
+			uncached[i] = 0;
+		else
+			panic("BAD");
+	}
+
+	consistent_sync(cached_alias, 128, PCI_DMA_TODEVICE);
+
+	for(i = 0; i < 128/sizeof(u32); i++)
+	{
+		if(cached_alias[i] == data_A)
+			cached1[i] = 1;
+		else if(cached_alias[i] == data_B)
+		  	cached1[i] = 0;
+		else
+			panic("BAD");
+
+		if(uncached_addr[i] == data_A)
+			uncached1[i] = 1;
+		else if(uncached_addr[i] == data_B)
+			uncached1[i] = 0;
+		else
+			panic("BAD");
+	}
+
+	sti();
+
+	printk("Ran Cache Writeback test\n");
+	printk("Pre-sync:\n");
+	for(i = 0; i < 128/sizeof(u32); i++)
+	{
+		if(cached[i])
+			printk("   data_A in cached_alias[%d]\n", i);
+		else
+			printk("   data_B in cached_alias[%d]\n", i);
+
+		if(uncached[i])
+			printk("   data_A in uncached_addr[%d]\n", i);
+		else
+			printk("   data_B in uncached_addr[%d]\n", i);
+	}
+	printk("Post-sync:\n");
+	for(i = 0; i < 128/sizeof(u32); i++)
+	{
+		if(cached1[i])
+			printk("   data_A in cached_alias[%d]\n", i);
+		else
+			printk("   data_B in cached_alias[%d]\n", i);
+		if(uncached1[i])
+			printk("   data_A in uncached_addr[%d]\n", i);
+		else
+			printk("   data_B in uncached_addr[%d]\n", i);
+	}
+
+	consistent_free(real_uncached, 136, (u32)&dma_handle);
+
+	return 0;
+}
+
+// __initcall(cache_test);
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/dma.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/dma.c
--- linux-2.4.29/arch/arm/mach-iop3xx/dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/dma.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,977 @@
+/**************************************************************************
+ *
+ * arch/arm/mach-iop310/dma.c
+ *
+ * Support functions for the Intel 80312 DMA channels.
+ * (see also Documentation/arm/XScale/iop310/dma.txt)
+ *
+ * Design inspired by the SA1100 DMA code by Nicolas Pitre
+ * Generic DMA ATU setup sample code provided by Larry Stewart
+ *
+ * Author: Dave Jiang (dave.jiang@intel.com)
+ * Copyright (C) 2001 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Todos:  Thorough Error handling (no FIQ support yet)
+ *          Do zero-size DMA transfer/channel at init
+ *          so all we have to do is chainining  
+ *
+ *
+ *  History:    (06/26/2001, DJ) Initial Creation
+ *              (07/06/2001, DJ) Use __raw_(read/write)l() instead of 
+ *                 memory mapped register because they aren't working yet
+ *              (07/12/2001, DJ) Hooked DMA to INTD. Need their own INTs.
+ *                               (not anymore since 2.4.7-rmk3-iop310.1-dj1)
+ *              (07/19/2001, DJ) Fixed some logic stuff after doing AAU. 
+ *              (08/22/2001, DJ) Changed spinlock calls to no save flags
+ *              (08/27/2001, DJ) Added irq threshold handling
+ *		(09/07/2001, DJ) Added cached/non-cached support, changed
+ *		   data structure to use list.h from Linux kernel, the API
+ *		   sleep now instead of requiring user to. slight API
+ *		   interface changes. Added mid-chain int notification
+ *		   support. User can also select the appropriate PCI
+ *		   commands.
+ *		(09/10/2001, DJ) Made DMA descriptor embed in user SGL. 
+ *		   Removed significant amount of data copying. User
+ *		   procedures a bit more exposed to hardware operation in
+ *		   trade off of performance.
+ * 		(10/11/2001, DJ) Added cache invalidate before hardware touches
+ * 			it to prevent data corruption.
+ *************************************************************************/
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/tqueue.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <asm/types.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/memory.h>
+#include <linux/list.h>
+#include <asm/arch/dma.h>
+#include <asm/mach/dma.h>
+
+/*
+ * pick up local definitions
+ */
+#include "dma.h"
+
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#include <linux/module.h>
+#endif
+
+#undef DEBUG
+#ifdef DEBUG
+#define DPRINTK(s, args...) printk("80310DMA: " s, ## args)
+#else
+#define DPRINTK(s, args...)
+#endif
+
+/* globals */
+static iop310_dma_t dma_chan[MAX_IOP310_DMA_CHANNEL];	/* DMA channels */
+static struct list_head dma_free_stack;	/* free DMA descriptor stack */
+static spinlock_t dma_free_lock;	/* free DMA stack lock */
+
+/* static prototypes */
+static inline int dma_start(iop310_dma_t *, sw_dma_t *);
+static void dma_task(void *);
+static void dma_irq_handler(int, void *, struct pt_regs *);
+static void dma_process(iop310_dma_t *);
+
+/*=======================================================================*/
+/*  Procedure:  dma_start()                                              */
+/*                                                                       */
+/*  Description:    This function starts the DMA engine. If the DMA      */
+/*                  has already started then chain resume will be done   */
+/*                                                                       */
+/*  Parameters:  dma: DMA channel device                                 */
+/*               dma_chain: DMA data chain to pass to DMAC               */
+/*                                                                       */
+/*  Returns:    int -- success: 0                                       */
+/*                     failure: -EBUSY                                   */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 6/26/01  Initial Creation                     */
+/*=======================================================================*/
+static int dma_start(iop310_dma_t * dma, sw_dma_t * dma_chain)
+{
+	u32 status;
+
+	status = *(dma->reg_addr.CSR);
+
+	/* check channel status error */
+	if(status & DMA_CSR_ERR_MASK)
+	{
+		DPRINTK("start: Channel Error %x\n", status);
+		/* should clean the channel up then, or let int handle it? */
+		return -EBUSY;
+	}
+
+	/* if channel not active */
+	if(!(status & DMA_CSR_CH_ACTIVE))
+	{
+		/* set the next descriptor address register */
+		DPRINTK("Start at phys: %#x\n", dma_chain->dma_phys);
+		*(dma->reg_addr.NDAR) = dma_chain->dma_phys;
+
+		DPRINTK("Enabling channel now\n");
+
+		*(dma->reg_addr.CCR) = DMA_CCR_CHANNEL_ENABLE;
+	}
+	else
+	{
+		DPRINTK("Resuming chain\n");
+		/* if active, chain up to last DMA chain */
+
+		dma->last_desc->dma_desc.NDAR = (u32) dma_chain->dma_phys;
+
+		/* flush cache since we changed field */
+		cpu_dcache_clean_range((u32)&dma->last_desc->dma_desc.NDAR,
+			   (u32)(&dma->last_desc->dma_desc.NDAR + 1));
+
+		/* resume the chain */
+		*(dma->reg_addr.CCR) |= DMA_CCR_CHAIN_RESUME;
+	}
+
+	/* set the last channel descriptor to last descriptor in chain */
+	dma->last_desc = dma_chain->tail;
+
+	return 0;
+}
+
+/*=======================================================================*/
+/*  Procedure:  dma_task()                                               */
+/*                                                                       */
+/*  Description:    This function is the bottom half hdlr of the DMA INT */
+/*                  handler. It is queued as an imm task on the imm      */
+/*                  task Q. It process all the complete DMA chain in the */
+/*                  holding Q and wakes up the user and free the resource*/
+/*                                                                       */
+/*  Parameters:   data: DMA device as parameter                          */
+/*                                                                       */
+/*  Returns:    NONE                                                     */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 6/26/01  Initial Creation                     */
+/*=======================================================================*/
+static void dma_task(void *data)
+{
+	iop310_dma_t *dma = (iop310_dma_t *) data;
+	u8 end_chain = 0;
+	sw_dma_t *sw_desc = NULL;
+	dma_head_t *listhead = NULL;
+
+	DPRINTK("Entering dma_task()\n");
+	if(!list_empty(&dma->hold_q))
+	{
+		sw_desc = SW_ENTRY(dma->hold_q.next);
+		listhead = (dma_head_t *) sw_desc->sgl_head;
+	}
+	else
+	{
+		DPRINTK("List empty!\n");
+		return;
+	}
+
+	DPRINTK("SW Desc: %#x\n", (u32) sw_desc);
+	/* process while DMA chain is complete */
+	while(sw_desc && 
+		(sw_desc->tail->status & (DMA_NOTIFY | DMA_INCOMPLETE)))
+	{
+		/* clean up until end of DMA chain */
+		while(!end_chain)
+		{
+			/* IE indicates end of chain or int per user request */
+			/* DMA_COMPLETE denotes end of real chain */
+			if(sw_desc->dma_desc.DC & DMA_DCR_IE)
+			{
+				end_chain = 1;
+				/* set the user list status as done */
+				listhead->status |= 
+					sw_desc->tail->status & DMA_USER_MASK;
+				sw_desc->status |= DMA_NOTIFY;
+
+				if(sw_desc->status & DMA_END_CHAIN)
+				{
+					listhead->status |= DMA_COMPLETE;
+				}
+			}
+
+			DPRINTK("Remove from holding Q\n");
+			spin_lock_irq(&dma->hold_lock);
+			/* remove from holding queue */
+			list_del(&sw_desc->link);
+			spin_unlock_irq(&dma->hold_lock);
+
+			cpu_dcache_invalidate_range((u32)&sw_desc->dma_desc,
+				(u32)&sw_desc->dma_desc + DMA_DESC_SIZE);
+
+
+			DPRINTK("Cleaning up\n");
+			sw_desc->head = NULL;
+			sw_desc->tail = NULL;
+
+			DPRINTK("Look at another descriptor\n");
+			if(!list_empty(&dma->hold_q))
+			{
+				/* peek at next descriptor */
+				sw_desc = SW_ENTRY(dma->hold_q.next);
+				listhead = (dma_head_t *) sw_desc->sgl_head;
+			}
+			else
+			{
+				sw_desc = NULL;
+			}
+		}
+
+		/* reset chain */
+		end_chain = 0;
+
+		DPRINTK("----List status: %#x\n", listhead->status);
+		/* wake up user function waiting for return */
+		if(listhead->callback)
+		{
+			listhead->callback(listhead);
+		}
+		else if(listhead->status & DMA_COMPLETE)
+			/*if(waitqueue_active(&dma->wait_q)) */
+		{
+			DPRINTK("Waking up waiting process\n");
+			wake_up_interruptible(&dma->wait_q);
+		}
+	}							/* end while */
+
+	DPRINTK("Exiting DMA task\n");
+}
+
+/*=======================================================================*/
+/*  Procedure:  dma_irq_handler()                                        */
+/*                                                                       */
+/*  Description:    This function is the interrupt handler for the DMA   */
+/*                  driver. It removes the done DMA descriptors from the */
+/*                  process Q and put them on the holding Q. it will     */
+/*                  continue to process until process queue empty or the */
+/*                  current DMA desc on the DMAC is the one we are       */
+/*                  inspecting                                           */
+/*                                                                       */
+/*  Parameters:   irq: IRQ activated                                     */
+/*                dev_id: device                                         */
+/*                regs: registers                                        */
+/*                                                                       */
+/*  Returns:    NONE                                                     */
+/*                                                                       */
+/*  Notes/Assumptions: Interupt is masked. No error handling is done.    */
+/*		       Errors should be done with the FIQ handler, which */
+/*		       is not supported currently.			 */
+/*                                                                       */
+/*  History:    Dave Jiang 6/26/01  Initial Creation                     */
+/*              Dave Jiang 07/20/01 Check INT instead of CSR for more INT*/
+/*=======================================================================*/
+static void dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	iop310_dma_t *dma = (iop310_dma_t *) dev_id;
+	u32 irq_status = 0;
+	u32 status = 0;
+	u32 thresh;
+
+	irq_status = *(IOP310_FIQ1ISR);
+
+	if(!(irq_status & DMA_INT_MASK))
+	{
+		return;
+	}
+	DPRINTK("IRQ: irq=%d status=%#x\n", irq, irq_status);
+
+	status = *(dma->reg_addr.CSR);
+
+	thresh = atomic_read(&dma->irq_thresh);
+
+
+	DPRINTK("CSR: %#x\n", status);
+	DPRINTK("Thresh: %d\n", thresh);
+	/* while we continue to get DMA INTs */
+	while((irq_status & DMA_INT_MASK) && thresh--)
+	{
+		/* clear CSR */
+		*(dma->reg_addr.CSR) |= DMA_CSR_DONE_MASK;
+
+		dma_process(dma);
+
+		status = *(dma->reg_addr.CSR);
+		irq_status = *(IOP310_FIQ1ISR);
+	}
+
+	/* schedule bottom half */
+	dma->dma_task.data = (void *)dma;
+	/* task goes to the immediate task queue */
+	queue_task(&dma->dma_task, &tq_immediate);
+	/* mark IMMEDIATE BH for execute */
+	mark_bh(IMMEDIATE_BH);
+}
+
+/*=======================================================================*/
+/*  Procedure:  dma_process()                                            */
+/*                                                                       */
+/*  Description:    This function processes moves all the dma desc in    */
+/*                  the processing queue that are considered done to the */
+/*                  holding Q. It is called by the interrupt when the    */
+/*                  done INTs are asserted. It will continue to process  */
+/*                  until either the process queue is empty or current   */
+/*                  DMA desc equals to the one in the DMAC               */
+/*                                                                       */
+/*  Parameters:   dma: DMA device as parameter                           */
+/*                                                                       */
+/*  Returns:    NONE                                                     */
+/*                                                                       */
+/*  Notes/Assumptions: Interrupt is masked                               */
+/*                                                                       */
+/*  History:    Dave Jiang 6/26/01  Initial Creation                     */
+/*=======================================================================*/
+static void dma_process(iop310_dma_t * dma)
+{
+	sw_dma_t *sw_desc;
+	u8 same_addr = 0;
+
+	DPRINTK("Entering dma_process()\n");
+
+	while(!same_addr && !list_empty(&dma->process_q))
+	{
+		spin_lock(&dma->process_lock);
+		/* peek the head of the queue */
+		sw_desc = SW_ENTRY(dma->process_q.next);
+		list_del(dma->process_q.next);
+		spin_unlock(&dma->process_lock);
+
+		if(sw_desc->head->tail->status & DMA_NEW_HEAD)
+		{
+			DPRINTK("Process new head\n");
+			sw_desc->tail->head = sw_desc;
+			sw_desc->head = sw_desc;
+			sw_desc->tail->status &= ~DMA_NEW_HEAD;
+		}
+
+		sw_desc->status |= DMA_DESC_DONE;
+		/* if we see end of chain, we set head status to DONE */
+		if(sw_desc->dma_desc.DC & DMA_DCR_IE)
+		{
+			DPRINTK("INT flag found!\n");
+			if(sw_desc->status & DMA_END_CHAIN)
+			{
+				DPRINTK("chain complete\n");
+				sw_desc->tail->status |= DMA_COMPLETE;
+			}
+			else
+			{
+				DPRINTK("mid chain flag\n");
+				sw_desc->head->tail = sw_desc;
+				sw_desc->tail = sw_desc;
+				sw_desc->tail->status |= DMA_NEW_HEAD;
+			}
+			sw_desc->tail->status |= DMA_NOTIFY;
+		}
+
+		DPRINTK("Check if current processing\n");
+		/* if descriptor equal same being proccessed, put it back */
+		if(((u32) sw_desc == *(dma->reg_addr.DAR)) &&
+		   (*(dma->reg_addr.CSR) & DMA_CSR_CH_ACTIVE))
+		{
+			spin_lock(&dma->process_lock);
+			list_add(&sw_desc->link, &dma->process_q);
+			spin_unlock(&dma->process_lock);
+			same_addr = 1;
+		}
+		else
+		{
+			DPRINTK("Add descriptor: %#x\n", (u32) sw_desc);
+			spin_lock(&dma->hold_lock);
+			/* push descriptor in hold Q */
+			list_add_tail(&sw_desc->link, &dma->hold_q);
+			spin_unlock(&dma->hold_lock);
+		}
+	}
+
+	DPRINTK("Exiting dma_process()\n");
+}					
+
+/*=======================================================================*/
+/*  Procedure:  dma_request()                                            */
+/*                                                                       */
+/*  Description:    This function requests a DMA chan depend on the bus. */
+/*                  The bus could be primary PCI or secondary. Currently */
+/*                  this parameter acts as a DMA channel selector        */
+/*                                                                       */
+/*  Parameters:  channel: DMA channel                                    */
+/*               device_id: device ID                                    */
+/*                                                                       */
+/*  Returns:     int - channel #		                                 */
+/*               -EINVAL: no such DMA channel exist                      */
+/*				 -EBUSY: can't allocate irq								 */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 6/26/01  Initial Creation                     */
+/*				Dave Jiang 9/02/01	Interface changed					 */
+/*=======================================================================*/
+int dma_request(dmach_t channel, const char *device_id)
+{
+	iop310_dma_t *dma = NULL;
+	int ch = channel;
+	int err;
+
+	if(channel >= MAX_IOP310_DMA_CHANNEL)
+	{
+		return -EINVAL;
+	}
+
+	dma = &dma_chan[ch];
+	atomic_inc(&dma->ref_count);
+
+	/* get interrupt if ref count is less than or equal to 1 */
+	if(atomic_read(&dma->ref_count) <= 1)
+	{
+		/* request IRQ for the channel */
+		err = request_irq(dma->irq, dma_irq_handler, SA_INTERRUPT,
+						  device_id, (void *)dma);
+		if(err < 0)
+		{
+			printk(KERN_ERR "%s: unable to request IRQ %d for \
+	  			   DMA channel %d: %d\n", device_id, dma->irq, ch, err);
+			dma->lock = 0;
+			atomic_set(&dma->ref_count, 0);
+			return -EBUSY;
+		}
+		dma->device_id = device_id;
+	}
+
+	return ch;
+}
+
+/*=======================================================================*/
+/*  Procedure:  dma_queue_buffer()                                       */
+/*                                                                       */
+/*  Description:    This function creates a DMA buffer chain from the    */
+/*                  user supplied SGL chain. It also puts the DMA chain  */
+/*                  onto the processing queue. DMA enable will be called */
+/*                  by this func                                         */
+/*                                                                       */
+/*  Parameters:  channel: DMA channel                                    */
+/*               listhead: User SGL (kernel memory)		                 */
+/*                                                                       */
+/*  Returns:     int: success -- 0                                      */
+/*               dma_start() condition                                   */
+/*                                                                       */
+/*  Notes/Assumptions:  User SGL must point to kernel memory, not user   */
+/*                                                                       */
+/*  History:    Dave Jiang 6/26/01  Initial Creation                     */
+/*=======================================================================*/
+int dma_queue_buffer(dmach_t channel, dma_head_t * listhead)
+{
+	sw_dma_t *sw_desc = (sw_dma_t *) listhead->list;
+	sw_dma_t *prev_desc = NULL;
+	sw_dma_t *head = NULL;
+	dma_head_t *sgl_head = listhead;
+	int err = 0;
+	iop310_dma_t *dma = &dma_chan[channel];
+	DECLARE_WAIT_QUEUE_HEAD(wait_q);
+
+	/* scan through entire user SGL */
+	DPRINTK("Enter dma_queue_buffer()\n");
+	while(sw_desc)
+	{
+		DPRINTK("Putting descriptor in process Q\n");
+		/* get DMA descriptor */
+
+		DPRINTK("sw_desc: %#x\n", (u32) sw_desc);
+		sw_desc->sgl_head = (u32) listhead;
+
+		/* we clean the cache for previous descriptor in chain */
+		if(prev_desc)
+		{
+			/* prev_desc->dma_desc.NDAR = (u32)sw_desc->dma_phys; */
+			cpu_dcache_clean_range((u32)&prev_desc->dma_desc, 
+				(u32)&prev_desc->dma_desc + DMA_DESC_SIZE);
+			
+		}
+		else
+		{
+			/* no previous descriptor, so we set this to be head */
+			head = sw_desc;
+		}
+
+		sw_desc->head = head;
+		/* set previous to current */
+		prev_desc = sw_desc;
+
+		/* put descriptor on process Q */
+		DPRINTK("Adding swdesc: %#x\n", (u32) sw_desc);
+		spin_lock_irq(&dma->process_lock);
+		list_add_tail(&sw_desc->link, &dma->process_q);
+		spin_unlock_irq(&dma->process_lock);
+
+		/* go to next SGL */
+		sw_desc = (sw_dma_t *) sw_desc->next;
+	}
+	DPRINTK("Done setting up descriptor list\n");
+
+	/* if our tail exists */
+	if(prev_desc)
+	{
+		/* set the head pointer on tail */
+		prev_desc->head = head;
+		/* set the header pointer's tail to tail */
+		head->tail = prev_desc;
+		prev_desc->tail = prev_desc;
+
+		/* clean cache for tail */
+		cpu_dcache_clean_range((u32)&prev_desc->dma_desc,
+			   (u32)&prev_desc->dma_desc + DMA_DESC_SIZE);
+		
+		DPRINTK("Starting DMA engine\n");
+		/* start the DMA */
+		DPRINTK("Starting at chain: 0x%x\n", (u32) head);
+		if((err = dma_start(dma, head)) < 0)
+		{
+			DPRINTK("dma_start() failed\n");
+			return err;
+		}
+		else
+		{
+			if(!sgl_head->callback)
+			{
+				wait_event_interruptible(dma->wait_q,
+					 (sgl_head->status & DMA_COMPLETE));
+				DPRINTK("----W0EN: %#x\n", sgl_head->status);
+			}
+			return 0;
+		}
+	}
+	else
+	{
+		DPRINTK("What happened to the chain?\n");
+	}
+
+	return -EINVAL;
+}		
+
+
+/*=======================================================================*/
+/*  Procedure:  dma_suspend()                                            */
+/*                                                                       */
+/*  Description:    This function stops the DMA at the earliest instant  */
+/*                  it is capable of. It actually suspends operation.    */
+/*                                                                       */
+/*  Parameters:  channel: DMA channel                                    */
+/*                                                                       */
+/*  Returns:     int: success -- 0                                      */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 6/26/01  Initial Creation                     */
+/*=======================================================================*/
+int dma_suspend(dmach_t channel)
+{
+	iop310_dma_t *dma = &dma_chan[channel];
+
+	/* remove channel enable bit */
+	*(dma->reg_addr.CCR) &= ~DMA_CCR_CHANNEL_ENABLE;
+
+	return 0;
+}
+
+/*=======================================================================*/
+/*  Procedure:  dma_resume()                                             */
+/*                                                                       */
+/*  Description:    This function resumes the DMA operations             */
+/*                                                                       */
+/*  Parameters:  channel: DMA channel                                    */
+/*                                                                       */
+/*  Returns:     int: success -- 0                                      */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 6/26/01  Initial Creation                     */
+/*=======================================================================*/
+int dma_resume(dmach_t channel)
+{
+	iop310_dma_t *dma = &dma_chan[channel];
+
+	/* set channel enable bit */
+	*(dma->reg_addr.CCR) |= DMA_CCR_CHANNEL_ENABLE;
+	return 0;
+}
+
+/*=======================================================================*/
+/*  Procedure:  dma_flush_all()                                          */
+/*                                                                       */
+/*  Description:    This function flushes the entire process Q for the   */
+/*                  DMA channel in question. It also clears the DMAC.    */
+/*                                                                       */
+/*  Parameters:  channel: DMA channel                                    */
+/*                                                                       */
+/*  Returns:     int: success -- 0                                      */
+/*                                                                       */
+/*  Notes/Assumptions: Interrupt is masked unless called by app          */
+/*                                                                       */
+/*  History:    Dave Jiang 6/26/01  Initial Creation                     */
+/*=======================================================================*/
+int dma_flush_all(dmach_t channel)
+{
+	iop310_dma_t *dma = &dma_chan[channel];
+	int flags;
+	sw_dma_t *sw_desc;
+
+	DPRINTK("Flushalll is being called\n");
+	*(dma->reg_addr.CCR) = DMA_CCR_CLEAR;
+	*(dma->reg_addr.CSR) = (DMA_CSR_DONE_MASK | DMA_CSR_ERR_MASK);
+
+	while(!list_empty(&dma->hold_q))
+	{
+		spin_lock_irqsave(&dma->process_lock, flags);
+		sw_desc = SW_ENTRY(dma->process_q.next);
+		list_del(dma->process_q.next);
+		spin_unlock_irqrestore(&dma->process_lock, flags);
+
+		/* set status to be incomplete */
+		sw_desc->status |= DMA_INCOMPLETE;
+		/* put descriptor on holding queue */
+		spin_lock_irqsave(&dma->hold_lock, flags);
+		list_add_tail(&sw_desc->link, &dma->hold_q);
+		spin_unlock_irqrestore(&dma->hold_lock, flags);
+	}
+
+	return 0;
+}
+
+/*=======================================================================*/
+/*  Procedure:  dma_free()                                               */
+/*                                                                       */
+/*  Description:    This function frees the DMA channel from usage.      */
+/*                                                                       */
+/*  Parameters:  channel: DMA channel                                    */
+/*                                                                       */
+/*  Returns:     int: success -- 0                                      */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 6/26/01  Initial Creation                     */
+/*              Dave Jiang 7/20/01 Added more clean up code              */
+/*=======================================================================*/
+void dma_free(dmach_t channel)
+{
+	iop310_dma_t *dma = &dma_chan[channel];
+
+	atomic_dec(&dma->ref_count);
+
+	if(atomic_read(&dma->ref_count) <= 1)
+	{
+		/* flush DMA channel */
+		dma_flush_all(dma->channel);
+		dma_task((void *)dma);
+		dma->ready = 0;
+		dma->last_desc = NULL;
+
+		/* free the IRQ */
+		free_irq(dma->irq, (void *)dma);
+		dma->lock = 0;
+	}
+
+	DPRINTK("freed\n");
+}	
+
+/*=======================================================================*/
+/*  Procedure:  dma_init()                                               */
+/*                                                                       */
+/*  Description:    This function initializes all the DMA channels.      */
+/*                                                                       */
+/*  Parameters:  NONE                                                    */
+/*                                                                       */
+/*  Returns:     int: success -- 0                                      */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 6/26/01  Initial Creation                     */
+/*=======================================================================*/
+int __init dma_init(void)
+{
+	int channel;
+	int i;
+	sw_dma_t *sw_desc = NULL;
+	void *desc = NULL;
+
+	printk("Intel 80310 DMA Copyright(c) 2001 Intel Corporation\n");
+	DPRINTK("Initializing...\n");
+
+	/* init free stack */
+	INIT_LIST_HEAD(&dma_free_stack);
+	/* init free stack spinlock */
+	spin_lock_init(&dma_free_lock);
+
+	/* pre-alloc DMA descriptors */
+	for(i = 0; i < MAX_DMA_DESC; i++)
+	{
+		/* 
+		 * we keep track of original address before alignment 
+		 * adjust so we can free it later 
+		 */
+		desc = kmalloc((sizeof(sw_dma_t) + 0x20), GFP_KERNEL);
+		memset(desc, 0, sizeof(sw_dma_t) + 0x20);
+
+		/* 
+		 * hardware descriptors must be aligned on an 
+		 * 8-word boundary 
+		 */
+		sw_desc = (sw_dma_t *) (((u32) desc & 0xffffffe0) + 0x20);
+		sw_desc->desc_addr = (u32) desc;
+		sw_desc->dma_phys = (u32) virt_to_phys(sw_desc);
+
+
+		/* put the descriptors on the free stack */
+		spin_lock_irq(&dma_free_lock);
+		list_add(&sw_desc->link, &dma_free_stack);
+		spin_unlock_irq(&dma_free_lock);
+	}
+
+	dma_chan[0].reg_addr.CCR = IOP310_DMA0CCR;
+	dma_chan[0].reg_addr.CSR = IOP310_DMA0CSR;
+	dma_chan[0].reg_addr.DAR = IOP310_DMA0DAR;
+	dma_chan[0].reg_addr.NDAR = IOP310_DMA0NDAR;
+	dma_chan[0].reg_addr.PADR = IOP310_DMA0PADR;
+	dma_chan[0].reg_addr.PUADR = IOP310_DMA0PUADR;
+	dma_chan[0].reg_addr.LADR = IOP310_DMA0LADR;
+	dma_chan[0].reg_addr.BCR = IOP310_DMA0BCR;
+	dma_chan[0].reg_addr.DCR = IOP310_DMA0DCR;
+	dma_chan[1].reg_addr.CCR = IOP310_DMA1CCR;
+	dma_chan[1].reg_addr.CSR = IOP310_DMA1CSR;
+	dma_chan[1].reg_addr.DAR = IOP310_DMA1DAR;
+	dma_chan[1].reg_addr.NDAR = IOP310_DMA1NDAR;
+	dma_chan[1].reg_addr.PADR = IOP310_DMA1PADR;
+	dma_chan[1].reg_addr.PUADR = IOP310_DMA1PUADR;
+	dma_chan[1].reg_addr.LADR = IOP310_DMA1LADR;
+	dma_chan[1].reg_addr.BCR = IOP310_DMA1BCR;
+	dma_chan[1].reg_addr.DCR = IOP310_DMA1DCR;
+	dma_chan[2].reg_addr.CCR = IOP310_DMA2CCR;
+	dma_chan[2].reg_addr.CSR = IOP310_DMA2CSR;
+	dma_chan[2].reg_addr.DAR = IOP310_DMA2DAR;
+	dma_chan[2].reg_addr.NDAR = IOP310_DMA2NDAR;
+	dma_chan[2].reg_addr.PADR = IOP310_DMA2PADR;
+	dma_chan[2].reg_addr.PUADR = IOP310_DMA2PUADR;
+	dma_chan[2].reg_addr.LADR = IOP310_DMA2LADR;
+	dma_chan[2].reg_addr.BCR = IOP310_DMA2BCR;
+	dma_chan[2].reg_addr.DCR = IOP310_DMA2DCR;
+
+	/* set the IRQ */
+	dma_chan[0].irq = IRQ_IOP310_DMA0;
+	dma_chan[1].irq = IRQ_IOP310_DMA1;
+	dma_chan[2].irq = IRQ_IOP310_DMA2;
+
+	/* initialize all the channels */
+	for(channel = 0; channel < MAX_IOP310_DMA_CHANNEL; channel++)
+	{
+		/* init channel lock to 0 */
+		atomic_set(&dma_chan[channel].ref_count, 0);
+		dma_chan[channel].lock = 0;
+
+		atomic_set(&dma_chan[channel].irq_thresh, 
+				DEFAULT_DMA_IRQ_THRESH);
+
+		/* init process Q */
+		INIT_LIST_HEAD(&dma_chan[channel].process_q);
+		/* init holding Q */
+		INIT_LIST_HEAD(&dma_chan[channel].hold_q);
+		/* init locks for Qs */
+		spin_lock_init(&dma_chan[channel].hold_lock);
+		spin_lock_init(&dma_chan[channel].process_lock);
+
+		dma_chan[channel].last_desc = NULL;
+		/* set the channel for DMA struct */
+		dma_chan[channel].channel = channel;
+
+		/* initialize BH task */
+		dma_chan[channel].dma_task.sync = 0;
+		dma_chan[channel].dma_task.routine = (void *)dma_task;
+
+		/* initialize wait Q */
+		init_waitqueue_head(&dma_chan[channel].wait_q);
+		/* clear DMA channel control register */
+
+		*(dma_chan[channel].reg_addr.CCR) = DMA_CCR_CLEAR;
+		*(dma_chan[channel].reg_addr.CSR) |= 
+			(DMA_CSR_DONE_MASK | DMA_CSR_ERR_MASK);
+		*(dma_chan[channel].reg_addr.NDAR) = 0;
+	}
+
+	DPRINTK("DMA init Done!\n");
+	return 0;
+}				
+
+/*=======================================================================*/
+/*  Procedure:  dma_set_irq_threshold()                                  */
+/*                                                                       */
+/*  Description:    This function sets the threshold for irq service.    */
+/*                  this is how many times irq gets serviced before bail */
+/*                  so it wouldn't hog resources                         */
+/*                                                                       */
+/*  Parameters:  channel: DMA channel                                    */
+/*               value: threshold value                                  */
+/*                                                                       */
+/*  Returns:     N/A                                                     */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 8/27/01  Initial Creation                     */
+/*=======================================================================*/
+void dma_set_irq_threshold(dmach_t channel, int value)
+{
+	iop310_dma_t *dma = &dma_chan[channel];
+
+	atomic_set(&dma->irq_thresh, value);
+}								/* End oi dma_set_irq_threshold() */
+
+/*=======================================================================*/
+/*  Procedure:  dma_get_buffer()                                         */
+/*                                                                       */
+/*  Description:    This function acquires an SGL element for the user   */
+/*                  and returns that. It will retry multiple times if no */
+/*                  descriptor is available.                             */
+/*                                                                       */
+/*  Parameters:  channel: DMA channel                                    */
+/*               num_desc: number of descriptors                         */
+/*                                                                       */
+/*  Returns:     N/A                                                     */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 9/10/01  Initial Creation                     */
+/*				Dave Jiang 10/04/01 Fixed linking up of sgl list		 */
+/*=======================================================================*/
+dma_sgl_t *dma_get_buffer(dmach_t channel, int num_desc)
+{
+	sw_dma_t *sw_desc = NULL;
+	sw_dma_t *sw_head = NULL;
+	sw_dma_t *sw_prev = NULL;
+
+	int retry = 10;
+	DECLARE_WAIT_QUEUE_HEAD(wait_q);
+	int i;
+
+	if(num_desc > MAX_DMA_DESC)
+	{
+		DPRINTK("More descriptor requested than allocated\n");
+		return NULL;
+	}
+
+	for(i = num_desc; i > 0; i--)
+	{
+		spin_lock_irq(&dma_free_lock);
+		if(!list_empty(&dma_free_stack))
+		{
+			sw_desc = SW_ENTRY(dma_free_stack.next);
+			list_del(dma_free_stack.next);
+			spin_unlock_irq(&dma_free_lock);
+		}
+		else
+		{
+			while(retry-- && !sw_desc)
+			{
+				spin_unlock_irq(&dma_free_lock);
+				interruptible_sleep_on_timeout(&wait_q, SLEEP_TIME);
+				spin_lock_irq(&dma_free_lock);
+				if(!list_empty(&dma_free_stack))
+				{
+					sw_desc = SW_ENTRY(dma_free_stack.next);
+					list_del(dma_free_stack.next);
+				}
+				spin_unlock_irq(&dma_free_lock);
+			}
+
+			if(!sw_desc)
+			{
+				printk(KERN_WARNING "80310 DMA: No more DMA descriptors");
+				spin_lock_irq(&dma_free_lock);
+				if(sw_head)
+				{
+					sw_desc = sw_head;
+					while(sw_desc)
+					{
+						list_add(&sw_desc->link, &dma_free_stack);
+						sw_desc = (sw_dma_t *) sw_desc->next;
+					}
+				}
+				spin_unlock_irq(&dma_free_lock);
+				return NULL;
+			}
+		}
+
+		if(sw_prev)
+		{
+			sw_prev->next = (dma_sgl_t *) sw_desc;
+			sw_prev->dma_desc.NDAR = sw_desc->dma_phys;
+		}
+		else
+		{
+			sw_head = sw_desc;
+		}
+
+		sw_prev = sw_desc;
+	}
+
+	sw_desc->dma_desc.NDAR = 0;
+	sw_desc->next = NULL;
+	sw_desc->status = 0;
+
+	return (dma_sgl_t *) sw_head;
+}
+
+/*=======================================================================*/
+/*  Procedure:  dma_return_buffer()                                      */
+/*                                                                       */
+/*  Description:    This function takes a list of SGL and return it to   */
+/*                  the free stack.                                      */
+/*                                                                       */
+/*  Parameters:  channel: DMA channel                                    */
+/*               list: SGL list to return to free stack                  */
+/*                                                                       */
+/*  Returns:     N/A                                                     */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 9/10/01  Initial Creation                     */
+/*=======================================================================*/
+void dma_return_buffer(dmach_t channel, dma_sgl_t * list)
+{
+	sw_dma_t *sw_desc = (sw_dma_t *) list;
+
+	spin_lock_irq(&dma_free_lock);
+	while(sw_desc)
+	{
+		list_add(&sw_desc->link, &dma_free_stack);
+		sw_desc = (sw_dma_t *) sw_desc->next;
+	}
+	spin_unlock_irq(&dma_free_lock);
+
+}
+
+EXPORT_SYMBOL_NOVERS(dma_request);
+EXPORT_SYMBOL_NOVERS(dma_queue_buffer);
+EXPORT_SYMBOL_NOVERS(dma_suspend);
+EXPORT_SYMBOL_NOVERS(dma_resume);
+EXPORT_SYMBOL_NOVERS(dma_free);
+EXPORT_SYMBOL_NOVERS(dma_set_irq_threshold);
+EXPORT_SYMBOL_NOVERS(dma_get_buffer);
+EXPORT_SYMBOL_NOVERS(dma_return_buffer);
+
+module_init(dma_init);
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/dma.h linux-2.4.29-uc1/arch/arm/mach-iop3xx/dma.h
--- linux-2.4.29/arch/arm/mach-iop3xx/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/dma.h	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,130 @@
+/*
+ * Private Definitions for XScale DMA 
+ *
+ * Author: Dave Jiang (dave.jiang@intel.com)
+ * Copyright (C) 2001 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _DMA_PRIVATE_H_
+#define _DMA_PRIVATE_H_
+
+#define DEFAULT_DMA_IRQ_THRESH  10
+
+#define DMA_DESC_SIZE 24
+
+#define SLEEP_TIME          50
+
+#define DESC_DONE           DMA_DONE
+#define DESC_INCOMPLETE     DMA_INCOMPLETE
+#define DESC_HEAD           0x0010
+#define DESC_TAIL           0x0020
+
+#define DMA_INT_0       0x01
+#define DMA_INT_1       0x02
+#define DMA_INT_2       0x04
+#define DMA_INT_MASK    (DMA_INT_0 | DMA_INT_1 | DMA_INT_2)
+
+#define DMA_CCR_CLEAR               0x00000000
+#define DMA_CCR_CHANNEL_ENABLE      0x00000001
+#define DMA_CCR_CHAIN_RESUME        0x00000002
+
+#define DMA_CSR_PCI_PAR_ERROR       0x00000001
+#define DMA_CSR_PCI_TGT_ABORT       0x00000004
+#define DMA_CSR_PCI_MST_ABORT       0x00000008
+#define DMA_CSR_INT_MST_ABORT       0x00000020
+#define DMA_CSR_EOC_INT             0x00000100
+#define DMA_CSR_EOT_INT             0x00000200
+#define DMA_CSR_CH_ACTIVE           0x00000400
+#define DMA_CSR_DONE_MASK           (DMA_CSR_EOC_INT | DMA_CSR_EOT_INT)
+
+#define DMA_CSR_ERR_MASK            (DMA_CSR_PCI_PAR_ERROR | \
+									 DMA_CSR_PCI_TGT_ABORT | \
+                                     DMA_CSR_PCI_MST_ABORT | \
+									 DMA_CSR_INT_MST_ABORT)
+
+#define DMA_CSR_DONE_MASK           (DMA_CSR_EOC_INT | DMA_CSR_EOT_INT)
+
+/*
+ * DMA Software Descriptor
+ */
+typedef struct _sw_dma
+{
+	dma_desc_t dma_desc;		/* DMA descriptor pointer */
+	u32 status;
+	void *data;					/* local virt */
+	struct _dma_sgl *next;		/* next descriptor */
+	struct list_head link;
+	u32 sw_desc;				/* parent address */
+	u32 dma_phys;				/* Physical address of DMA */
+	u32 desc_addr;				/* desc unaligned alloc addr */
+	u32 sgl_head;				/* user SG head */
+	struct _sw_dma *tail;		/* chain tail */
+	struct _sw_dma *head;		/* chain head */
+} sw_dma_t;
+
+/*
+ * DMA control register structure
+ */
+typedef struct _dma_regs
+{
+	volatile u32 CCR;			/* channel control register */
+	volatile u32 CSR;			/* channel status register */
+	volatile u32 DAR;			/* descriptor address register */
+	volatile u32 NDAR;			/* next descriptor address register */
+	volatile u32 PADR;			/* PCI address register */
+	volatile u32 PUADR;			/* upper PCI address register */
+	volatile u32 LADR;			/* local address register */
+	volatile u32 BCR;			/* byte count register */
+	volatile u32 DCR;			/* descriptor control register */
+} dma_regs_t;
+
+
+/*
+ * DMA channel structure.
+ */
+
+typedef struct _dmac_ctrl_t
+{
+	dmach_t channel;			/* channel */
+	u32 lock;					/* Device is allocated */
+	struct list_head process_q;
+	struct list_head hold_q;
+	spinlock_t process_lock;	/* process queue lock */
+	spinlock_t hold_lock;		/* hold queue lock */
+	int ready;					/* 1 if DMA can occur */
+	int active;					/* 1 if DMA is processing data */
+	int irq;					/* IRQ used by the channel */
+	atomic_t ref_count;			/* resource count for DMA */
+#ifndef REGMAP
+	struct						/* register offset */
+	{
+		volatile u32 *CCR;		/* channel control register */
+		volatile u32 *CSR;		/* channel status register */
+		volatile u32 *DAR;		/* descriptor address register */
+		volatile u32 *NDAR;		/* next descriptor address register */
+		volatile u32 *PADR;		/* PCI address register */
+		volatile u32 *PUADR;	/* upper PCI address register */
+		volatile u32 *LADR;		/* local address register */
+		volatile u32 *BCR;		/* byte count register */
+		volatile u32 *DCR;		/* descriptor control register */
+	}
+	reg_addr;
+#endif
+	atomic_t last_dma_lock;		/* last DMA descriptor lock */
+	atomic_t irq_thresh;
+	wait_queue_head_t wait_q;	/* wait queue for user to sleep on */
+	struct tq_struct dma_task;	/* tasklet */
+	sw_dma_t *last_desc;		/* last descriptor for DMAC */
+	dma_regs_t *regs;			/* points to DMA registers */
+	const char *device_id;		/* Device name */
+} iop310_dma_t;
+
+#define SW_ENTRY(list) list_entry((list), sw_dma_t, link)
+
+#endif
+ /*EOF*/
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/iop310-irq.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/iop310-irq.c
--- linux-2.4.29/arch/arm/mach-iop3xx/iop310-irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/iop310-irq.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,110 @@
+/*
+ * linux/arch/arm/mach-iop3xx/iop310-irq.c
+ *
+ * Generic IOP310 IRQ handling functionality
+ * 
+ * Author:  Nicolas Pitre
+ * Copyright:   (C) 2001 MontaVista Software Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Added IOP310 chipset and IQ80310 board demuxing, masking code. - DS
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+
+#include <asm/mach-types.h>
+
+extern void xs80200_irq_mask(unsigned int);
+extern void xs80200_irq_unmask(unsigned int);
+extern void xs80200_init_irq(void);
+
+extern void do_IRQ(int, struct pt_regs *);
+
+u32 iop310_mask = 0;
+
+static void 
+iop310_irq_mask (unsigned int irq)
+{
+	iop310_mask |= (1 << (irq - IOP310_IRQ_OFS));
+
+	/*
+	 * No mask bits on the 80312, so we have to
+	 * mask everything from the outside!
+	 */
+	xs80200_irq_mask(IRQ_XS80200_EXTIRQ);
+}
+
+static void
+iop310_irq_unmask (unsigned int irq)
+{
+	iop310_mask &= ~(1 << (irq - IOP310_IRQ_OFS));
+
+	/*
+	 * Check if all 80312 sources are unmasked now
+	 */
+	if(!iop310_mask)
+	{
+		xs80200_irq_unmask(IRQ_XS80200_EXTIRQ);
+
+	}
+}
+
+void iop310_irq_demux(int irq, void *dev_id,
+                                   struct pt_regs *regs)
+{
+	u32 fiq1isr = *((volatile u32*)IOP310_FIQ1ISR);
+	u32 fiq2isr = *((volatile u32*)IOP310_FIQ2ISR);
+	unsigned int irqno = 0xdeadbeef;
+
+	if(fiq1isr)
+	{
+		if(fiq1isr & 0x1)
+			irqno = IRQ_IOP310_DMA0;
+		if(fiq1isr & 0x2)
+			irqno = IRQ_IOP310_DMA1;
+		if(fiq1isr & 0x4)
+			irqno = IRQ_IOP310_DMA2;
+		if(fiq1isr & 0x10)
+			irqno = IRQ_IOP310_PMON;
+		if(fiq1isr & 0x20)
+			irqno = IRQ_IOP310_AAU;
+	}
+	else
+	{
+		if(fiq2isr & 0x2)
+			irqno = IRQ_IOP310_I2C;
+		if(fiq2isr & 0x4)
+			irqno = IRQ_IOP310_MU;
+	}
+
+	if(irqno != 0xdeadbeef)
+		do_IRQ(irqno, regs);
+}
+
+void __init iop310_init_irq(void)
+{
+	int i;
+
+	for(i = IOP310_IRQ_OFS; i < NR_IOP310_IRQS; i++)
+	{
+		irq_desc[i].valid	= 1;
+		irq_desc[i].probe_ok	= 1;
+		irq_desc[i].mask_ack	= iop310_irq_mask;
+		irq_desc[i].mask	= iop310_irq_mask;
+		irq_desc[i].unmask	= iop310_irq_unmask;
+	}
+
+	xs80200_init_irq();
+}
+
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/iop310-pci.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/iop310-pci.c
--- linux-2.4.29/arch/arm/mach-iop3xx/iop310-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/iop310-pci.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,352 @@
+/*
+ * arch/arm/mach-iop3xx/iop310-pci.c
+ *
+ * PCI support for the Intel IOP310 chipset
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/hardware.h>
+
+#include <asm/arch/pci.h>
+#include <asm/arch/pci_auto.h>
+#include <asm/arch/pci-bridge.h>
+
+#undef DEBUG
+#ifdef DEBUG
+#define  DBG(x...) printk(x)
+#else
+#define  DBG(x...)
+#endif
+
+extern int (*external_fault)(unsigned long, struct pt_regs *);
+int iop310_pci_abort_handler(unsigned long, unsigned long, struct pt_regs *);
+
+int iop310_host;
+
+void iop310_init(void)
+{
+	DBG("PCI:  Intel 80312 PCI-to-PCI init code.\n");
+	DBG("\tATU secondary: IOP310_SOMWVR=0x%04x, IOP310_SOIOWVR=0x%04x\n", 
+			*IOP310_SOMWVR, 
+			*IOP310_SOIOWVR);
+	DBG("\tATU secondary: IOP310_ATUCR=0x%08x\n", *IOP310_ATUCR);
+	DBG("\tATU secondary: IOP310_SIABAR=0x%08x IOP310_SIALR=0x%08x IOP310_SIATVR=%08x\n", *IOP310_SIABAR, *IOP310_SIALR, *IOP310_SIATVR);
+
+	DBG("\tATU primary: IOP310_POMWVR=0x%04x, IOP310_POIOWVR=0x%04x\n", 
+			*IOP310_POMWVR, 
+			*IOP310_POIOWVR);
+	DBG("\tATU secondary: IOP310_PIABAR=0x%08x IOP310_PIALR=0x%08x IOP310_PIATVR=%08x\n", *IOP310_PIABAR, *IOP310_PIALR, *IOP310_PIATVR);
+
+	DBG("\tP2P: IOP310_PCR=0x%04x IOP310_BCR=0x%04x IOP310_EBCR=0x%04x\n", *IOP310_PCR, *IOP310_BCR, *IOP310_EBCR);
+
+	/*
+	 * Windows have to be carefully opened via a nice set of calls
+	 * here or just some direct register fiddling in the board
+	 * specific init when we want transactions to occur between the
+	 * two PCI hoses.
+	 *
+	 * To do this, we will have manage RETRY assertion between the
+	 * firmware and the kernel.  This will ensure that the host
+	 * system's enumeration code is held off until we have tweaked
+	 * the interrupt routing and public/private IDSELs.
+	 * 
+	 * For now we will simply default to disabling the integrated type
+	 * 81 P2P bridge.
+	 */
+	*IOP310_PCR &= 0xfff8;
+	
+	external_fault = iop310_pci_abort_handler;
+	
+}
+
+/*
+ * This routine builds either a type0 or type1 configuration command.  If the
+ * bus is on the 80312 then a type0 made, else a type1 is created.
+ */ 
+static inline u32 iop310_pci_config_setup(struct pci_dev *dev, int where)
+{
+	volatile u32 *paddress;
+	volatile u32 *pdata;
+	struct pci_controller *hose;
+
+	DBG("\tPCI: config_setup of bus %d\n", dev->bus->number);
+
+	/*
+	 * Get appropriate cfga/cfgd values from hose
+	 */
+	hose = pci_bus_to_hose(dev->bus->number);
+	paddress = (u32 *)hose->cfg_addr;
+	pdata = (u32 *)hose->cfg_data;
+
+	/* locations must be dword-aligned */
+	where &= ~3;
+
+	/*
+	 * For top bus generate a type 0 config,
+	 * all others use a type 1 config
+	 */
+	if (dev->bus->number == hose->first_busno)
+	{
+		*paddress = ( (1 << (PCI_SLOT(dev->devfn) + 16)) |
+				(PCI_FUNC(dev->devfn) << 8) | where | 0 );
+	}
+	else
+	{
+		*paddress = ( (dev->bus->number << 16) |
+				(PCI_SLOT(dev->devfn) << 11) | 
+				(PCI_FUNC(dev->devfn) << 8) | where | 1 );
+	}
+
+	return (u32)pdata;
+}
+
+/*
+ * This routine checks the status of the last configuration cycle.  If an error
+ * was detected it returns a 1, else it returns a 0.  The errors being checked
+ * are parity, master abort, target abort (master and target).  These types of
+ * errors occure during a config cycle where there is no device, like during
+ * the discovery stage.
+ */ 
+static int iop310_pci_config_cleanup(u8 bus)
+{
+	u32 status = 0, err = 0;
+	struct pci_controller *hose;
+
+	hose = pci_bus_to_hose(bus);
+
+	/*
+	 * If our hose is using the primary CFGA then check the
+	 * primary status registers, otherwise check the relevant
+	 * secondary status registers.
+	 */ 
+	if (hose->cfg_addr == (unsigned int *)IOP310_POCCAR) 
+	{
+		status = *IOP310_PATUSR;
+		if (status & 0xF900)
+		{
+			DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status);
+			err = 1;
+			*IOP310_PATUSR = status & 0xF980;
+		}
+		status = *IOP310_PATUISR;
+		if (status & 0x79F) 
+		{
+			DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status);
+			err = 1;
+			*IOP310_PATUISR = status & 0x79f;
+		}
+		status = *IOP310_PSR;
+		if (status & 0xF900) 
+		{
+			DBG("\t\t\tPCI: P2 - status = 0x%08x\n", status);
+			err = 1;
+			*IOP310_PSR = status & 0xF980;
+		}
+		status = *IOP310_PBISR;
+		if (status & 0x3F) 
+		{
+			DBG("\t\t\tPCI: P3 - status = 0x%08x\n", status);
+			err = 1;
+			*IOP310_PBISR = status & 0x3F;
+		}
+	} 
+	else 
+	{
+		status = *IOP310_SATUSR;
+		if (status & 0xF900) 
+		{
+			DBG("\t\t\tPCI: S0 - status = 0x%08x\n", status);
+			err = 1;
+			*IOP310_SATUSR = status & 0xF900;
+		}
+		status = *IOP310_SATUISR;
+		if (status & 0x69F) 
+		{
+			DBG("\t\t\tPCI: S1 - status = 0x%08x\n", status);
+			err = 1;
+			*IOP310_SATUISR= status & 0x69F;
+		}
+	}
+
+	return err;
+}
+
+/*
+ * The read routines must check the error status of the last configuration
+ * cycle.  If there was an error, the routine returns all hex f's.
+ */ 
+static int
+iop310_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	u32 *pdata;
+
+	cli();
+
+	pdata = (u32 *)iop310_pci_config_setup(dev, where);
+
+	*value = (u8) (((*pdata) >> ((where % 0x04) * 8)) & 0xff);
+
+	if( iop310_pci_config_cleanup(dev->bus->number) )
+	{
+		*value = 0xff;
+	} /* IF END */
+
+	sti();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+iop310_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	u32 *pdata;
+
+	cli();
+
+	pdata = (u32 *)iop310_pci_config_setup(dev, where);
+	*value = (u16) (((*pdata) >> ((where % 0x04) * 8)) & 0xffff);
+	if( iop310_pci_config_cleanup(dev->bus->number) )
+	{
+		*value = 0xffff;
+	} /* IF END */
+
+	sti();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+iop310_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	u32 *pdata;
+	u8 scratch_pad[5];  /* used to fix dword PCI problem */
+
+	cli();
+
+	pdata = (u32 *)iop310_pci_config_setup(dev, where);
+	*value =  *pdata;
+
+	/* Workaround for timing problem errata on 80312 */ 
+	sprintf(scratch_pad, "bugs");
+
+	if( iop310_pci_config_cleanup(dev->bus->number) )
+	{
+		*value = 0xffffffff;
+	} /* IF END */
+
+	sti();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+iop310_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	u32 *pdata;
+	u32 mask;
+	u32 temp;
+
+	cli();
+
+	pdata = (u32 *)iop310_pci_config_setup(dev, where);
+	mask = ~(0x000000ff << ((where % 0x4) * 8));
+	temp = (u32)(((u32)value) << ((where% 0x4) * 8));
+	*pdata = (*pdata & mask) | temp;
+
+	sti();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+iop310_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	u32 *pdata;
+	u32 mask;
+	u32 temp;
+
+	cli();
+
+	pdata = (u32 *)iop310_pci_config_setup(dev, where);
+	mask = ~(0x0000ffff << ((where % 0x4) * 8));
+	temp = (u32)(((u32)value) << ((where % 0x4) * 8));
+	*pdata = (*pdata & mask) | temp;
+
+	sti();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+iop310_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	u32 *pdata;
+
+	cli();
+	
+	pdata = (u32 *)iop310_pci_config_setup(dev, where);
+	*pdata = value;
+
+	sti();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops iop310_ops = {
+	iop310_read_config_byte,
+	iop310_read_config_word,
+	iop310_read_config_dword,
+	iop310_write_config_byte,
+	iop310_write_config_word,
+	iop310_write_config_dword,
+};
+
+/*
+ * When a PCI device does not exist during config cycles, the 80200 gets a 
+ * bus error instead of returning 0xffffffff. This handler simply returns.  
+ */ 
+int
+iop310_pci_abort_handler(unsigned long addr, unsigned long fsr, struct pt_regs *regs) 
+{
+	/*
+	 * If it was an imprecise abort, then we need to correct the
+	 * return address to be _after_ the instruction.
+	 */
+	if (fsr & (1 << 10))
+		regs->ARM_pc += 4;
+	
+	return 0;
+}
+
+#define EARLY_PCI_OP(rw, size, type)					\
+int early_##rw##_config_##size(struct pci_controller *hose, int bus,	\
+		int devfn, int offset, type value)	\
+{									\
+	return iop310_##rw##_config_##size(fake_pci_dev(hose, bus, devfn),	\
+			offset, value);			\
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/iop321-irq.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/iop321-irq.c
--- linux-2.4.29/arch/arm/mach-iop3xx/iop321-irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/iop321-irq.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,65 @@
+/*
+ * linux/arch/arm/mach-iop3xx/iop321-irq.c
+ *
+ * Generic IOP321 IRQ handling functionality
+ * 
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Added IOP3XX chipset and IQ80321 board masking code.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+
+#include <asm/mach-types.h>
+
+static u32 iop321_mask = 0;
+
+static void 
+iop321_irq_mask (unsigned int irq)
+{
+	
+	iop321_mask &= ~(1 << (irq - IOP321_IRQ_OFS));
+
+	intctl_write(iop321_mask);
+}
+
+static void
+iop321_irq_unmask (unsigned int irq)
+{
+	iop321_mask |= (1 << (irq - IOP321_IRQ_OFS));
+
+	intctl_write(iop321_mask);
+}
+
+void __init iop321_init_irq(void)
+{
+	int i;
+
+	intctl_write(0);		// disable all interrupts
+	intstr_write(0);		// treat all as IRQ
+	if(machine_is_iq80321()) 	// all interrupts are inputs to chip
+		*IOP321_PCIIRSR = 0x0f;	
+
+	for(i = IOP321_IRQ_OFS; i < NR_IOP321_IRQS; i++)
+	{
+		irq_desc[i].valid	= 1;
+		irq_desc[i].probe_ok	= 1;
+		irq_desc[i].mask_ack	= iop321_irq_mask;
+		irq_desc[i].mask	= iop321_irq_mask;
+		irq_desc[i].unmask	= iop321_irq_unmask;
+	}
+}
+
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/iop321-pci.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/iop321-pci.c
--- linux-2.4.29/arch/arm/mach-iop3xx/iop321-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/iop321-pci.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,312 @@
+/*
+ * arch/arm/mach-iop3xx/iop321-pci.c
+ *
+ * PCI support for the Intel IOP321 chipset
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/hardware.h>
+
+#include <asm/arch/pci.h>
+#include <asm/arch/pci_auto.h>
+#include <asm/arch/pci-bridge.h>
+
+// #define DEBUG
+
+#ifdef DEBUG
+#define  DBG(x...) printk(x)
+#else
+#define  DBG(x...)
+#endif
+
+extern int (*external_fault)(unsigned long, struct pt_regs *);
+int iop321_pci_abort_handler(unsigned long, unsigned long, struct pt_regs *);
+
+void iop321_init(void)
+{
+	DBG("PCI:  Intel 80321 PCI init code.\n");
+	DBG("\tATU: IOP321_ATUCMD=0x%04x\n", *IOP321_ATUCMD);
+	DBG("\tATU: IOP321_OMWTVR0=0x%04x, IOP321_OIOWTVR=0x%04x\n", 
+			*IOP321_OMWTVR0, 
+			*IOP321_OIOWTVR);
+	DBG("\tATU: IOP321_ATUCR=0x%08x\n", *IOP321_ATUCR);
+	DBG("\tATU: IOP321_IABAR0=0x%08x IOP321_IALR0=0x%08x IOP321_IATVR0=%08x\n", *IOP321_IABAR0, *IOP321_IALR0, *IOP321_IATVR0);
+	DBG("\tATU: IOP321_ERBAR=0x%08x IOP321_ERLR=0x%08x IOP321_ERTVR=%08x\n", *IOP321_ERBAR, *IOP321_ERLR, *IOP321_ERTVR);
+	DBG("\tATU: IOP321_IABAR2=0x%08x IOP321_IALR2=0x%08x IOP321_IATVR2=%08x\n", *IOP321_IABAR2, *IOP321_IALR2, *IOP321_IATVR2);
+	DBG("\tATU: IOP321_IABAR3=0x%08x IOP321_IALR3=0x%08x IOP321_IATVR3=%08x\n", *IOP321_IABAR3, *IOP321_IALR3, *IOP321_IATVR3);
+
+	external_fault = iop321_pci_abort_handler;
+}
+
+/*
+ * This routine builds either a type0 or type1 configuration command.  If the
+ * bus is on the 80321 then a type0 made, else a type1 is created.
+ */ 
+static inline u32 iop321_pci_config_setup(struct pci_dev *dev, int where)
+{
+	volatile u32 *paddress;
+	volatile u32 *pdata;
+	struct pci_controller *hose;
+
+	DBG("\tPCI: config_setup of bus %d\n", dev->bus->number);
+
+	/*
+	 * Get appropriate cfga/cfgd values from hose
+	 */
+	hose = pci_bus_to_hose(dev->bus->number);
+	paddress = (u32 *)hose->cfg_addr;
+	pdata = (u32 *)hose->cfg_data;
+
+	/* locations must be dword-aligned */
+	where &= ~3;
+
+	/*
+	 * For top bus generate a type 0 config,
+	 * all others use a type 1 config
+	 */
+	if (dev->bus->number == hose->first_busno)
+	{
+		*paddress = ( (1 << (PCI_SLOT(dev->devfn) + 16)) |
+				(PCI_FUNC(dev->devfn) << 8) | where | 0 );
+	}
+	else
+	{
+		*paddress = ( (dev->bus->number << 16) |
+				(PCI_SLOT(dev->devfn) << 11) | 
+				(PCI_FUNC(dev->devfn) << 8) | where | 1 );
+	}
+
+	return (u32)pdata;
+}
+
+/*
+ * This routine checks the status of the last configuration cycle.  If an error
+ * was detected it returns a 1, else it returns a 0.  The errors being checked
+ * are parity, master abort, target abort (master and target).  These types of
+ * errors occure during a config cycle where there is no device, like during
+ * the discovery stage.
+ */ 
+static int iop321_pci_config_cleanup(u8 bus)
+{
+	u32 status = 0, err = 0;
+	struct pci_controller *hose;
+
+	hose = pci_bus_to_hose(bus);
+
+	/*
+	 * Check the status registers.
+	 */ 
+	if (hose->cfg_addr == (unsigned int *)IOP321_OCCAR) 
+	{
+		status = *IOP321_ATUSR;
+		if (status & 0xF900)
+		{
+			DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status);
+			err = 1;
+			*IOP321_ATUSR = status & 0xF900;
+		}
+		status = *IOP321_ATUISR;
+		if (status & 0x679F) 
+		{
+			DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status);
+			err = 1;
+			*IOP321_ATUISR = status & 0x679f;
+		}
+	} 
+	return err;
+}
+
+/*
+ * The read routines must check the error status of the last configuration
+ * cycle.  If there was an error, the routine returns all hex f's.
+ */ 
+static int
+iop321_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	volatile u32 *pdata;
+
+	cli();
+
+	pdata = (u32 *)iop321_pci_config_setup(dev, where);
+	udelay(50);
+	*value = (u8) (((*pdata) >> ((where % 0x04) * 8)) & 0xff);
+	udelay(50);
+
+	if( iop321_pci_config_cleanup(dev->bus->number) )
+	{
+		*value = 0xff;
+	} /* IF END */
+
+	sti();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+iop321_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	volatile u32 *pdata;
+
+	cli();
+
+	pdata = (u32 *)iop321_pci_config_setup(dev, where);
+	udelay(50);
+	*value = (u16) (((*pdata) >> ((where % 0x04) * 8)) & 0xffff);
+	udelay(50);
+
+	if( iop321_pci_config_cleanup(dev->bus->number) )
+	{
+		*value = 0xffff;
+	} /* IF END */
+
+	sti();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+iop321_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	volatile u32 *pdata;
+
+	cli();
+
+	pdata = (u32 *)iop321_pci_config_setup(dev, where);
+	udelay(50);
+	*value =  *pdata;
+	udelay(50);
+
+	if( iop321_pci_config_cleanup(dev->bus->number) )
+	{
+		*value = 0xffffffff;
+	} /* IF END */
+
+	sti();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+iop321_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	volatile u32 *pdata;
+	u32 mask;
+	u32 temp;
+
+	cli();
+
+	pdata = (u32 *)iop321_pci_config_setup(dev, where);
+	udelay(50);
+	mask = ~(0x000000ff << ((where % 0x4) * 8));
+	temp = (u32)(((u32)value) << ((where% 0x4) * 8));
+	*pdata = (*pdata & mask) | temp;
+	udelay(50);
+
+	iop321_pci_config_cleanup(dev->bus->number);
+
+	sti();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+iop321_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	volatile u32 *pdata;
+	u32 mask;
+	u32 temp;
+
+	cli();
+
+	pdata = (u32 *)iop321_pci_config_setup(dev, where);
+	udelay(50);
+	mask = ~(0x0000ffff << ((where % 0x4) * 8));
+	temp = (u32)(((u32)value) << ((where % 0x4) * 8));
+	*pdata = (*pdata & mask) | temp;
+	udelay(50);
+
+	iop321_pci_config_cleanup(dev->bus->number);
+
+	sti();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+iop321_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	volatile u32 *pdata;
+
+	cli();
+	
+	pdata = (u32 *)iop321_pci_config_setup(dev, where);
+	udelay(50);
+	*pdata = value;
+	udelay(50);
+
+	iop321_pci_config_cleanup(dev->bus->number);
+
+	sti();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops iop321_ops = {
+	iop321_read_config_byte,
+	iop321_read_config_word,
+	iop321_read_config_dword,
+	iop321_write_config_byte,
+	iop321_write_config_word,
+	iop321_write_config_dword,
+};
+
+/*
+ * When a PCI device does not exist during config cycles, the 80200 gets a 
+ * bus error instead of returning 0xffffffff. This handler simply returns.  
+ */ 
+int
+iop321_pci_abort_handler(unsigned long addr, unsigned long fsr, struct pt_regs *regs) 
+{
+	/*
+	 * If it was an imprecise abort, then we need to correct the
+	 * return address to be _after_ the instruction.
+	 */
+	if (fsr & (1 << 10))
+		regs->ARM_pc += 4;
+	
+
+	return 0;
+}
+
+#define EARLY_PCI_OP(rw, size, type)					\
+int early_##rw##_config_##size(struct pci_controller *hose, int bus,	\
+		int devfn, int offset, type value)	\
+{									\
+	return iop321_##rw##_config_##size(fake_pci_dev(hose, bus, devfn),	\
+			offset, value);			\
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/iop321-time.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/iop321-time.c
--- linux-2.4.29/arch/arm/mach-iop3xx/iop321-time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/iop321-time.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,83 @@
+/*
+ * arch/arm/mach-iop3xx/iop321-time.c
+ *
+ * Timer code for IOP321 based systems
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/timex.h>
+#include <asm/hardware.h>
+
+#include <asm/mach-types.h>
+
+static unsigned long iop321_gettimeoffset(void)
+{
+	unsigned long elapsed, usec;
+
+	elapsed = *IOP321_TU_TCR0;
+
+	usec = (unsigned long)((LATCH - elapsed) * tick) / LATCH;
+
+	return usec;
+}
+
+static void iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u32 tisr;
+
+	asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr));
+
+	tisr |= 1;
+
+	asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr));
+
+	do_timer(regs);
+}
+
+extern unsigned long (*gettimeoffset)(void);
+
+static struct irqaction timer_irq = {
+	name: "timer",
+};
+
+extern int setup_arm_irq(int, struct irqaction*);
+
+void __init setup_timer(void)
+{
+	u32 timer_ctl;
+	u32 latch = LATCH;
+
+	gettimeoffset = iop321_gettimeoffset;
+	timer_irq.handler = iop321_timer_interrupt;
+	setup_arm_irq(IRQ_IOP321_TIMER0, &timer_irq);
+
+	timer_ctl = IOP321_TMR_EN | IOP321_TMR_PRIVILEGED | IOP321_TMR_RELOAD |
+			IOP321_TMR_RATIO_1_1;
+
+	asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (LATCH));
+
+	asm volatile("mcr p6, 0, %0, c0, c1, 0"	: : "r" (timer_ctl));
+}
+
+
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/iq80310-irq.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/iq80310-irq.c
--- linux-2.4.29/arch/arm/mach-iop3xx/iq80310-irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/iq80310-irq.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,170 @@
+/*
+ * linux/arch/arm/mach-iop3xx/iq80310-irq.c
+ *
+ * IRQ hadling/demuxing for IQ80310 board
+ * 
+ * Author:  Nicolas Pitre
+ * Copyright:   (C) 2001 MontaVista Software Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 2.4.7-rmk1-iop310.1
+ *     Moved demux from asm to C - DS
+ *     Fixes for various revision boards - DS
+ */
+
+#include <linux/config.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/hardware.h>
+#include <asm/system.h>
+
+#include <asm/mach-types.h>
+
+extern void xs80200_irq_mask(unsigned int);
+extern void xs80200_irq_unmask(unsigned int);
+extern void xs80200_init_irq(void);
+
+extern void do_IRQ(int, struct pt_regs *);
+
+extern u32 iop310_mask;
+
+extern void iop310_irq_demux(int, void *, struct pt_regs *);
+
+extern int iop310_init_irq(void);
+
+static void
+iq80310_irq_mask (unsigned int irq)
+{
+	volatile char *mask = (volatile char *)IQ80310_INT_MASK;
+	*mask |= (1 << (irq - IQ80310_IRQ_OFS));
+
+	/*
+	 * There's no mask for PCI INT A-C, so we just mask out all
+	 * external interrupts on the CPU.
+	 *
+	 * We set a bit of the iop310 mask so that the iop310_irq_mask 
+	 * function does not unmask EXTINT
+	 */
+    	if (irq > IRQ_IQ80310_INTD)
+    	{
+		xs80200_irq_mask(IRQ_XS80200_EXTIRQ);
+		iop310_mask |=  (0x80000000 >> (irq - IRQ_IQ80310_INTD));
+    	}
+}
+
+static void
+iq80310_irq_unmask (unsigned int irq)
+{
+	volatile char *mask = (volatile char *)IQ80310_INT_MASK;
+	*mask &= ~(1 << (irq - IQ80310_IRQ_OFS));
+
+	/*
+	 * See comment above
+	 */
+    	if (irq > IRQ_IQ80310_INTD)
+    	{
+		iop310_mask &= ~((0x80000000 >> (irq - IRQ_IQ80310_INTD)));
+		if(!iop310_mask)
+			xs80200_irq_unmask(IRQ_XS80200_EXTIRQ);
+    	}
+}
+
+static void iq80310_cpld_irq_demux(int irq, void *dev_id,
+                                   struct pt_regs *regs)
+{
+	u8 irq_stat = *((volatile u8*)IQ80310_INT_STAT);
+	u8 irq_mask = *((volatile u8*)IQ80310_INT_MASK);
+	unsigned int irqno = 0xffffffff;
+	unsigned long intsrc, intctl;
+
+	// Needed? If IRQ is masked, it shouldn't get through...
+	irq_stat &= ~irq_mask;
+
+	if(irq_stat & 0x01)
+		irqno = IRQ_IQ80310_TIMER;
+	else if(irq_stat & 0x02)
+		irqno = IRQ_IQ80310_I82559;
+	else if(irq_stat & 0x04)
+		irqno = IRQ_IQ80310_UART1;
+	else if(irq_stat & 0x08)
+		irqno = IRQ_IQ80310_UART2;
+	else if(irq_stat & 0x10)
+		irqno = IRQ_IQ80310_INTD;
+	else if(system_rev)
+	{
+		irq_stat = *((volatile u8*)IQ80310_PCI_INT_STAT) & 0xf;
+			
+		if(irq_stat & 0x1)
+			irqno = IRQ_IQ80310_INTA;
+		else if(irq_stat & 0x2)
+			irqno = IRQ_IQ80310_INTB;
+		else if(irq_stat & 0x4)
+			irqno = IRQ_IQ80310_INTC;
+	}
+	else	/* Running on a REV D.1 or older, assume PCI INTA */
+		irqno = IRQ_IQ80310_INTA;
+
+	/*
+	 * If we didn't read a CPLD interrupt, we assume it's from
+	 * a device on the chipset itself.
+	 */
+	if(irqno == 0xffffffff)
+	{
+		iop310_irq_demux(irq, dev_id, regs);
+		return;
+	}
+
+	/*
+	 * If on a REV D.1 or lower board, we just assumed INTA since
+	 * PCI is not routed, and it may actually be an on-chip interrupt.
+	 *
+	 * Note that we're giving on-chip interrupts slightly higher
+	 * priority than PCI by handling them first.
+	 */
+	if(irqno == IRQ_IQ80310_INTA && !system_rev)
+		iop310_irq_demux(irq, dev_id, regs);
+
+	do_IRQ(irqno, regs);
+}
+
+
+static struct irqaction iq80310_cpld_irq = {
+    name:       "CPLD_IRQ",
+    handler:    iq80310_cpld_irq_demux,
+    flags:      SA_NOMASK
+};
+
+extern int setup_arm_irq(int, struct irqaction *);
+
+void __init iq80310_init_irq(void)
+{
+	volatile char *mask = (volatile char *)IQ80310_INT_MASK;
+	unsigned int i;
+	
+	iop310_init_irq();
+
+	/*
+	 * Setup PIRSR to route PCI interrupts into xs80200
+	 */
+	*IOP310_PIRSR = 0xff;	
+	*mask = 0xff;  /* mask all sources */
+
+	for (i = IQ80310_IRQ_OFS; i < NR_IRQS; i++) {
+		irq_desc[i].valid	= 1;
+		irq_desc[i].probe_ok	= 0;
+		irq_desc[i].mask_ack	= iq80310_irq_mask;
+		irq_desc[i].mask	= iq80310_irq_mask;
+		irq_desc[i].unmask	= iq80310_irq_unmask;
+	}
+
+	setup_arm_irq(IRQ_XS80200_EXTIRQ, &iq80310_cpld_irq);
+}
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/iq80310-pci.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/iq80310-pci.c
--- linux-2.4.29/arch/arm/mach-iop3xx/iq80310-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/iq80310-pci.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,267 @@
+/*
+ * arch/arm/mach-iop3xx/iq80310-pci.c
+ *
+ * PCI support for the Intel IQ80310 reference board
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/pci.h>
+#include <asm/arch/pci_auto.h>
+#include <asm/arch/pci-bridge.h>
+#include <asm/arch/pci_iop310.h>
+
+#undef DEBUG
+#ifdef DEBUG
+#define  DBG(x...) printk(x)
+#else
+#define  DBG(x...)
+#endif
+
+static struct pci_controller *sec_hose, *pri_hose = NULL;
+static struct resource sec_mem, pri_mem, sec_io, pri_io;
+
+void __init
+iq80310_init(void *sysdata)
+{
+	struct pci_bus *bus;
+	struct pci_dev *dev;
+	int host = *(volatile u32*)IQ80310_BACKPLANE & 0x1;
+
+	system_rev = (*(volatile unsigned int*)0xfe830000) & 0x0f;
+
+	if(system_rev)
+		system_rev = 0xF;
+
+	if(host)
+		printk("PCI: IQ80310 is system controller\n");
+	else
+		printk("PCI: IQ80310 is agent\n");
+
+	/* IOP310 default setup */
+	iop310_init();
+
+	if(host)
+	{
+		pri_hose = pcibios_alloc_controller();
+
+		if(!pri_hose)
+			panic("Could not allocate PCI hose");
+
+		pri_hose->first_busno = 0;
+		pri_hose->last_busno = 0;
+		pri_hose->first_busno = 0;
+		pri_hose->last_busno = 0xff;
+		pri_hose->cfg_addr = (unsigned int *)IOP310_POCCAR;
+		pri_hose->cfg_data = (unsigned char *)IOP310_POCCDR;
+		pri_hose->io_space.start = IOP310_PCIPRI_LOWER_IO;
+		pri_hose->io_space.end = IOP310_PCIPRI_UPPER_IO;
+		pri_hose->mem_space.start = IOP310_PCIPRI_LOWER_MEM;
+		pri_hose->mem_space.end = IOP310_PCIPRI_UPPER_MEM;
+
+		pri_hose->mem_resources[0].start = IOP310_PCIPRI_LOWER_MEM;
+		pri_hose->mem_resources[0].end = IOP310_PCIPRI_UPPER_MEM;
+		pri_hose->mem_resources[0].flags = IORESOURCE_MEM;
+
+		pri_hose->io_resource.start = IOP310_PCIPRI_LOWER_IO;
+		pri_hose->io_resource.end = IOP310_PCIPRI_UPPER_IO;
+		pri_hose->io_resource.flags = IORESOURCE_IO;
+
+		/* Autoconfig the hose */
+		pri_hose->last_busno = pciauto_bus_scan(pri_hose, 0);
+
+		/* Scan the hose */
+		bus = pci_scan_bus(0, &iop310_ops, sysdata);
+
+		bus->resource[0] = &pri_hose->io_resource;
+		bus->resource[1] = &pri_hose->mem_resources[0];
+
+		pri_hose->mem_resources[0].name = "IOP310 PATU PCI Mem";
+		pri_hose->io_resource.name =  "IOP310 PATU PCI I/O";
+	}
+	else
+	{
+		/*
+		 * If we're running in agent mode, we remap the 
+		 * SATU window to be at the same PCI location as
+		 * the PATU window so that there are no collisions
+		 * between the SATU PCI space and the host memory
+		 * PCI space. This also allows us to have a single
+		 * bus_to_virt/virt_to_bus for both hoses.
+		 */
+
+		*IOP310_SIABAR = *IOP310_PIABAR;
+	}
+
+	/* Always scan 2ndary hose */
+
+	sec_hose = pcibios_alloc_controller();
+
+	if (!sec_hose)
+		panic("Couldn't allocate a PCI hose");
+
+	/*
+	 * Note that in agent mode, we can just tell the 2ndary
+	 * hose that it is at 0 since it's a private configuration
+	 * space from the primary bus.
+	 */
+	if(host)
+		sec_hose->first_busno = pri_hose->last_busno + 1;
+	else
+		sec_hose->first_busno = 0;
+
+	sec_hose->last_busno = 0xff;
+	sec_hose->cfg_addr = (unsigned int *)IOP310_SOCCAR;
+	sec_hose->cfg_data = (unsigned char *)IOP310_SOCCDR;
+	sec_hose->io_space.start = IOP310_PCISEC_LOWER_IO;
+	sec_hose->io_space.end = IOP310_PCISEC_UPPER_IO;
+	sec_hose->mem_space.start = IOP310_PCISEC_LOWER_MEM;
+	sec_hose->mem_space.end = IOP310_PCISEC_UPPER_MEM;
+	
+	sec_hose->mem_resources[0].start = IOP310_PCISEC_LOWER_MEM;
+	sec_hose->mem_resources[0].end = IOP310_PCISEC_UPPER_MEM;
+	sec_hose->mem_resources[0].flags = IORESOURCE_MEM;
+
+	sec_hose->io_resource.start = IOP310_PCISEC_LOWER_IO;
+	sec_hose->io_resource.end = IOP310_PCISEC_UPPER_IO;
+	sec_hose->io_resource.flags = IORESOURCE_IO;
+
+		/* Autoconfig the hose */
+	/* Autoconfig the hose */
+	sec_hose->last_busno = 
+		pciauto_bus_scan(sec_hose, sec_hose->first_busno);
+
+	/* Scan the hose */
+	bus = pci_scan_bus(sec_hose->first_busno, &iop310_ops, sysdata);
+
+	bus->resource[0] = &sec_hose->io_resource;
+	bus->resource[1] = &sec_hose->mem_resources[0];
+
+	sec_hose->mem_resources[0].name = "IOP310 SATU PCI Mem";
+	sec_hose->io_resource.name = "IOP310 SATU PCI I/O";
+
+	pcibios_allocate_bus_resources(&pci_root_buses);
+	pcibios_allocate_resources();
+}
+
+#define INTA	IRQ_IQ80310_INTA
+#define INTB	IRQ_IQ80310_INTB
+#define INTC	IRQ_IQ80310_INTC
+#define INTD	IRQ_IQ80310_INTD
+
+#define INTE	IRQ_IQ80310_I82559
+
+static inline int __init
+iq80310_pri_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	const long min_idsel = 2, max_idsel = 3, irqs_per_slot = 4;
+
+	/*
+	 * On a Rev D.1 and older board, INT A-C are not routed, so we
+	 * just fake it as INTA and than we take care of handling it
+	 * correctly in the IRQ demux routine.
+	 */
+	if(!system_rev)
+	{
+		static char pci_irq_table[ ][4] = 
+			{
+				/*
+	 	 	 	 * PCI IDSEL/INTPIN->INTLINE
+	 	 	 	 * A       B       C       D
+	 	 	 	 */
+				{INTA, INTD, INTA, INTA}, /*  PCI Slot J3 */
+				{INTD, INTA, INTA, INTA}, /*  PCI Slot J4 */
+			};
+		return PCI_IRQ_TABLE_LOOKUP;
+	}
+	else
+	{
+		static char pci_irq_table[ ][4] = 
+			{
+				/*
+	 	 	 	 * PCI IDSEL/INTPIN->INTLINE
+	 	 	 	 * A       B       C       D
+	 	 	 	 */
+				{INTC, INTD, INTA, INTB}, /*  PCI Slot J3 */
+				{INTD, INTA, INTB, INTC}, /*  PCI Slot J4 */
+			};
+		return PCI_IRQ_TABLE_LOOKUP;
+	}
+}
+
+
+static inline int __init
+iq80310_sec_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	const long min_idsel = 0, max_idsel = 2, irqs_per_slot = 4;
+
+	if(!system_rev)
+	{
+		static char pci_irq_table[ ][4] = 
+			{
+				/*
+	 		 	 * PCI IDSEL/INTPIN->INTLINE
+	 		 	 * A       B       C       D
+	 		 	 */
+				{INTA, INTA, INTA, INTD}, /*  PCI Slot J1 */
+				{INTA, INTA, INTD, INTA}, /*  PCI Slot J5 */
+				{INTE, INTE, INTE, INTE}, /*  P2P Bridge */
+			};
+		return PCI_IRQ_TABLE_LOOKUP;
+	}
+	else
+	{
+		static char pci_irq_table[ ][4] = 
+			{
+				/*
+	 		 	 * PCI IDSEL/INTPIN->INTLINE
+	 		 	 * A       B       C       D
+	 		 	 */
+				{INTA, INTB, INTC, INTD}, /* PCI Slot J1 */
+				{INTB, INTC, INTD, INTA}, /* PCI Slot J5 */
+				{INTE, INTE, INTE, INTE}, /* P2P Bridge */
+			};
+		return PCI_IRQ_TABLE_LOOKUP;
+	}
+
+}
+
+static inline int __init
+iq80310_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	struct pci_controller *hose;
+
+	hose = pci_bus_to_hose(dev->bus->number);
+
+	if(hose == pri_hose)
+		return iq80310_pri_map_irq(dev, idsel, pin);
+	else
+		return iq80310_sec_map_irq(dev, idsel, pin);
+}
+
+
+struct hw_pci iq80310_pci __initdata = {
+	init:		iq80310_init,
+	swizzle:	common_swizzle,
+	map_irq:	iq80310_map_irq,
+};
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/iq80310-time.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/iq80310-time.c
--- linux-2.4.29/arch/arm/mach-iop3xx/iq80310-time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/iq80310-time.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,125 @@
+/*
+ * linux/arch/arm/mach-iop310/time-iq80310.c
+ *
+ * Timer functions for IQ80310 onboard timer
+ * 
+ * Author:  Nicolas Pitre
+ * Copyright:   (C) 2001 MontaVista Software Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/timex.h>
+#include <asm/hardware.h>
+
+#include <asm/mach-types.h>
+
+static void iq80310_write_timer (u_long val)
+{
+	volatile u_char *la0 = (volatile u_char *)IQ80310_TIMER_LA0;
+	volatile u_char *la1 = (volatile u_char *)IQ80310_TIMER_LA1;
+	volatile u_char *la2 = (volatile u_char *)IQ80310_TIMER_LA2;
+	
+	*la0 = val;
+	*la1 = val >> 8;
+	*la2 = (val >> 16) & 0x3f;
+}
+	
+static u_long iq80310_read_timer (void)
+{
+	volatile u_char *la0 = (volatile u_char *)IQ80310_TIMER_LA0;
+	volatile u_char *la1 = (volatile u_char *)IQ80310_TIMER_LA1;
+	volatile u_char *la2 = (volatile u_char *)IQ80310_TIMER_LA2;
+	volatile u_char *la3 = (volatile u_char *)IQ80310_TIMER_LA3;
+	u_long b0, b1, b2, b3, val;
+	
+	b0 = *la0; b1 = *la1; b2 = *la2; b3 = *la3;
+	b0 = (((b0 & 0x20) >> 1) | (b0 & 0x1f));
+	b1 = (((b1 & 0x20) >> 1) | (b1 & 0x1f));
+	b2 = (((b2 & 0x20) >> 1) | (b2 & 0x1f));
+	b3 = (b3 & 0x0f);
+	val = ((b0 << 0) | (b1 << 6) | (b2 << 12) | (b3 << 18));
+	return val;
+}
+
+/* IRQs are disabled before entering here from do_gettimeofday() */
+static unsigned long iq80310_gettimeoffset (void)
+{
+	unsigned long elapsed, usec;
+
+	/* We need elapsed timer ticks since last interrupt */
+	elapsed = iq80310_read_timer();
+
+	/* Now convert them to usec */
+	usec = (unsigned long)(elapsed*tick)/LATCH;
+
+	return usec;
+}
+
+
+static void iq80310_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	volatile u_char *timer_en = (volatile u_char *)IQ80310_TIMER_EN;
+	
+	/* clear timer interrupt */
+	*timer_en &= ~2;
+	*timer_en |= 2;
+
+	/*
+	 * AHEM..HACK
+	 *
+	 * Since the timer interrupt is cascaded through the CPLD and
+	 * the 80312 and the demux code calls do_IRQ, the irq count is
+	 * going to be atleast 2 when we get here and this will cause the 
+	 * kernel to increment the system tick counter even if we're
+	 * idle. This causes it to look like there's always 100% system 
+	 * time, which is not the case.  To get around it, we just decrement 
+	 * the IRQ count before calling do_timer. We increment it again 
+	 * b/c otherwise it will go negative and than bad things happen.
+	 *
+	 * -DS
+	 */
+	irq_exit(smp_processor_id(), irq);
+	do_timer(regs);
+	irq_enter(smp_processor_id(), irq);
+}
+
+extern unsigned long (*gettimeoffset)(void);
+
+static struct irqaction timer_irq = {
+	name: "timer",
+};
+
+
+extern int setup_arm_irq(int, struct irqaction*);
+
+void __init setup_timer (void)
+{
+	volatile u_char *timer_en = (volatile u_char *)IQ80310_TIMER_EN;
+
+	gettimeoffset = iq80310_gettimeoffset;
+	timer_irq.handler = iq80310_timer_interrupt;
+	setup_arm_irq(IRQ_IQ80310_TIMER, &timer_irq);
+	*timer_en = 0;
+	iq80310_write_timer(LATCH);
+	*timer_en |= 2;
+	*timer_en |= 1;
+}
+
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/iq80321-pci.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/iq80321-pci.c
--- linux-2.4.29/arch/arm/mach-iop3xx/iq80321-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/iq80321-pci.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,121 @@
+/*
+ * arch/arm/mach-iop3xx/iq80321-pci.c
+ *
+ * PCI support for the Intel IQ80321 reference board
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/pci.h>
+#include <asm/arch/pci_auto.h>
+#include <asm/arch/pci-bridge.h>
+#include <asm/arch/pci_iop321.h>
+
+#undef DEBUG
+#ifdef DEBUG
+#define  DBG(x...) printk(x)
+#else
+#define  DBG(x...)
+#endif
+
+static struct pci_controller *hose = NULL;
+
+void __init
+iq80321_init(void *sysdata)
+{
+	struct pci_bus *bus;
+	struct resource *mem =
+		kmalloc(sizeof(struct resource), GFP_KERNEL);
+
+	if(!mem)
+		printk(KERN_ERR "Could not allocate PCI resource\n");
+
+	/* IOP321 default setup */
+	iop321_init();
+
+	hose = pcibios_alloc_controller();
+
+	if(!hose)
+		panic("Could not allocate PCI hose");
+
+	hose->first_busno = (*IOP321_PCIXSR >> 8) & 0xff;
+	if (hose->first_busno == 0xff)
+		hose->first_busno = 0;
+	hose->last_busno = 0xff;
+	hose->cfg_addr = (unsigned int *)IOP321_OCCAR;
+	hose->cfg_data = (unsigned char *)IOP321_OCCDR;
+	hose->io_space.start = IOP321_PCI_LOWER_IO;
+	hose->io_space.end = IOP321_PCI_UPPER_IO;
+	hose->mem_space.start = IOP321_PCI_LOWER_MEM;
+	hose->mem_space.end = IOP321_PCI_UPPER_MEM;
+
+	/* Autoconfig the hose */
+	hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
+
+	if(mem)
+	{
+		mem->flags = IORESOURCE_MEM;
+		mem->name = "IOP321 ATU";
+		allocate_resource(&iomem_resource, mem,
+					IOP321_PCI_WINDOW_SIZE,
+					IOP321_PCI_LOWER_MEM,
+					0xffffffff,
+					IOP321_PCI_LOWER_MEM 
+						& 0xff000000,
+					NULL, NULL);
+	}
+
+	/* Scan the hose */
+	bus = pci_scan_bus(hose->first_busno, &iop321_ops, sysdata);
+}
+
+#define INTA	IRQ_IQ80321_INTA
+#define INTB	IRQ_IQ80321_INTB
+#define INTC	IRQ_IQ80321_INTC
+#define INTD	IRQ_IQ80321_INTD
+
+#define INTE	IRQ_IQ80321_I82544
+
+static inline int __init
+iq80321_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	char ret;
+
+	static char pci_irq_table[3][4] = 
+		{
+			/*
+			 * PCI IDSEL/INTPIN->INTLINE
+			 * A       B       C       D
+			 */
+			{INTE, INTE, INTE, INTE}, /* Gig-E */
+			{INTD, INTC, INTD, INTA}, /* Unused */
+			{INTC, INTD, INTA, INTB}, /* PCI-X Slot */
+		};
+	ret = pci_irq_table[idsel%4][pin-1];
+	return ret;
+}
+
+struct hw_pci iq80321_pci __initdata = {
+	init:		iq80321_init,
+	swizzle:	common_swizzle,
+	map_irq:	iq80321_map_irq,
+};
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/Makefile linux-2.4.29-uc1/arch/arm/mach-iop3xx/Makefile
--- linux-2.4.29/arch/arm/mach-iop3xx/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/Makefile	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,42 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= iop3xx.o
+
+# Object file lists.
+
+obj-y			:= arch.o pci.o pci-auto.o
+
+obj-n			:=
+obj-			:=
+
+export-objs		:=
+
+obj-m			:=
+
+obj-$(CONFIG_ARCH_IOP310)  += xs80200-irq.o iop310-irq.o iop310-pci.o mm.o
+
+obj-$(CONFIG_ARCH_IQ80310) += iq80310-pci.o iq80310-irq.o 
+
+obj-$(CONFIG_ARCH_IOP321)  += iop321-irq.o iop321-pci.o mm-321.o iop321-time.o
+
+obj-$(CONFIG_ARCH_IQ80321) += iq80321-pci.o 
+
+ifeq ($(CONFIG_ARCH_IQ80310),y)
+   ifneq ($(CONFIG_XSCALE_PMU_TIMER),y)
+      obj-y			+= iq80310-time.o
+   endif
+endif
+
+obj-$(CONFIG_IOP3XX_AAU) += aau.o
+obj-$(CONFIG_IOP3XX_DMA) += dma.o
+obj-$(CONFIG_IOP3XX_MU) += message.o
+obj-$(CONFIG_IOP3XX_PMON) += pmon.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/message.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/message.c
--- linux-2.4.29/arch/arm/mach-iop3xx/message.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/message.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,1432 @@
+/**************************************************************************
+ * arch/arm/mach-iop310/message.c
+ *
+ * Support functions for the Intel 80310 MU.
+ * (see also Documentation/arm/XScale/IOP310/message.txt)
+ *
+ * Author: Dave Jiang (dave.jiang@intel.com)
+ * Copyright (C) 2001 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Todos:  Thorough Error handling
+ *
+ *  History:    (07/18/2001, DJ) Initial Creation
+ *              (08/22/2001, DJ) changed spinlock calls to no save flags
+ *              (08/27/2001, DJ) Added irq threshold handling
+ *		(10/11/2001, DJ) Tested with host side driver. Circular
+ *				   Queues working.
+ *		(10/12/2001, DJ) Rest of MU works now
+ *************************************************************************/
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/tqueue.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <asm/system.h>
+#include <asm/types.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/arch/iq80310.h>
+#include <asm/arch/irqs.h>
+#include <asm/memory.h>
+#include <asm/arch/message.h>
+#include <asm/arch/memory.h>
+
+#include "message.h"
+
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#include <linux/module.h>
+#endif
+
+#undef DEBUG
+#ifdef DEBUG
+#define DPRINTK(s, args...) printk("80310MU: " s, ## args)
+#else
+#define DPRINTK(s, args...)
+#endif
+
+void *mu_mem = NULL;
+
+/* globals */
+static iop310_mu_t mu_dev;
+
+/* static prototypes */
+static int __init mu_init(void);
+static void mu_irq_handler(int, void *, struct pt_regs *);
+static void mu_msg_irq_task(void *);
+static void mu_db_irq_task(void *);
+static void mu_cq_irq_task(void *);
+static void mu_ir_irq_task(void *);
+
+/*===========================MU Message Registers========================*/
+
+/*=======================================================================*/
+/*  Procedure:  mu_msg_request()                                         */
+/*                                                                       */
+/*  Description:    This function is used to request the ownership of    */
+/*                  MU Message Registers component ownership             */
+/*                                                                       */
+/*  Parameters:  *mu_context -- pass by reference int, written by API    */
+/*                                                                       */
+/*  Returns:     mu_context -- pointer to MU descriptor, ownership       */
+/*                                granted.                               */
+/*               NULL -- ownership denied                                */
+/*                                                                       */
+/*  Notes/Assumptions: The requester if successful will own the entire   */
+/*                     MU message registers mechanism.                   */
+/*                                                                       */
+/*  History:    Dave Jiang 08/17/01  Initial Creation                    */
+/*=======================================================================*/
+int mu_msg_request(u32 * mu_context)
+{
+	iop310_mu_t *mu = &mu_dev;
+	mu_msg_t *msg = &mu->msg_desc;
+	int i;
+	mu_msg_desc_t *msg_desc = NULL;
+
+	/* denied if already owned */
+	if(atomic_read(&msg->in_use))
+	{
+		return -EBUSY;
+	}
+
+	/* set ownership flag */
+	atomic_inc(&msg->in_use);
+
+	/* if we haven't allocated resources */
+	if(!atomic_read(&msg->res_init))
+	{
+		/* allocate message descriptors */
+		for(i = 0; i < MAX_MSG_DESC; i++)
+		{
+			/* allocate memory for message descriptor */
+			msg_desc = (mu_msg_desc_t *) kmalloc(sizeof(mu_msg_desc_t),
+												 GFP_KERNEL);
+			if(!msg_desc)
+			{
+				DPRINTK("Unable to allocate message descriptor for MU\n");
+				return -ENOMEM;
+			}
+
+			/* Init message descriptor */
+			msg_desc->message = 0;
+			msg_desc->reg_num = INBOUND_REG_UNDEF;
+
+			/* put descriptor on free stack */
+			spin_lock_irq(&msg->free_lock);
+			list_add(&msg_desc->link, &msg->free_stack);
+			spin_unlock_irq(&msg->free_lock);
+		}
+		/* set resource init flag */
+		atomic_inc(&msg->res_init);
+	}
+
+	/* Unmask outbound interrupts */
+	*(IOP310_MUOIMR) &= ~(MUOIMR_OBMSG_0_MASK | MUOIMR_OBMSG_1_MASK);
+
+	*mu_context = (u32)mu;
+	return 0;
+}								/* end of mu_msg_request() */
+
+/*=======================================================================*/
+/*  Procedure:  mu_msg_set_callback()                                    */
+/*                                                                       */
+/*  Description:  This function sets up the callback functions for the   */
+/*                Inbound message passing of the MR mechanism. The app   */
+/*                calls this can setup callback for either of the        */
+/*                inbound registers or have the same callback for both.  */
+/*                                                                       */
+/*                                                                       */
+/*  Parameters:  mu_context - context to MU descriptor                   */
+/*               reg - INBOUND_REG_BOTH, INBOUND_REG_0, INBOUND_REG_1    */
+/*               func - pointer to callback                              */
+/*                                                                       */
+/*  Returns:     0: SUCCESS                                              */
+/*               -EINVAL - invalid parameters passed in                  */
+/*                                                                       */
+/*  Notes/Assumptions: The app owns the message registers mechanism.     */
+/*                                                                       */
+/*  History:    Dave Jiang 08/17/01  Initial Creation                    */
+/*=======================================================================*/
+inline int mu_msg_set_callback(u32 mu_context, u8 reg, mu_msg_cb_t func)
+{
+	iop310_mu_t *mu = (iop310_mu_t *) mu_context;
+	mu_msg_t *msg = &mu->msg_desc;
+
+	/* make sure callback valid and the correct register number passed in */
+	if(!func || (!(reg & INBOUND_REG_0) && !(reg & INBOUND_REG_1)))
+	{
+		return -EINVAL;
+	}
+
+	switch (reg)
+	{
+	case INBOUND_REG_BOTH:		/* both inbound registers */
+		msg->callback_0 = func;
+		msg->callback_1 = func;
+		/* unmask inbound INTs */
+		*(IOP310_MUIIMR) &= ~(MUIIMR_IBMSG_0_MASK | MUIIMR_IBMSG_1_MASK);
+		break;
+	case INBOUND_REG_0:		/* inbound register 0 */
+		msg->callback_0 = func;
+		/* unmask inbound INT 0 */
+		*(IOP310_MUIIMR) &= ~MUIIMR_IBMSG_0_MASK;
+		break;
+	case INBOUND_REG_1:		/* inbound register 1 */
+		msg->callback_1 = func;
+		/* unmask inbound INT 1 */
+		*(IOP310_MUIIMR) &= ~MUIIMR_IBMSG_1_MASK;
+		break;
+	default:					/* this should never be executed */
+		printk("We should never get here\n");
+		BUG();
+		return -EINVAL;
+	}
+
+	return 0;
+}								/* End of mu_msg_set_callback() */
+
+/*=======================================================================*/
+/*  Procedure:  mu_msg_post()                                            */
+/*                                                                       */
+/*  Description: This function allows the app to post outbound messages  */
+/*               by the desired register.                                */
+/*                                                                       */
+/*                                                                       */
+/*  Parameters:  mu_context - context to MU device descriptor            */
+/*               val - message value to post                             */
+/*               cReg - OUTBOUND_REG_0, OUTBOUND_REG_1                   */
+/*                                                                       */
+/*  Returns:    0 - success                                              */
+/*              -EINVAL - invalid parameter                              */
+/*              -EBUSY - register busy                                   */
+/*                                                                       */
+/*  Notes/Assumptions: The app will figure out which reg to use. The app */
+/*                     must already own the message registers.           */
+/*                                                                       */
+/*  History:    Dave Jiang 08/17/01  Initial Creation                    */
+/*=======================================================================*/
+inline int mu_msg_post(u32 mu_context, u32 val, u8 reg)
+{
+	iop310_mu_t *mu = (iop310_mu_t *)mu_context;
+	/* check the parameters */
+	if((reg != OUTBOUND_REG_0) && (reg != OUTBOUND_REG_1))
+	{
+		DPRINTK("posting to wrong register\n");
+		return -EINVAL;
+	}
+
+	/* if we are posting on register 0 */
+	if(reg == OUTBOUND_REG_0)
+	{
+		/* if outbound INT bit still asserted, previous message has not */
+		/* been read. cannot write a new message */
+		if(*(IOP310_MUOISR) & MUOISR_OBMSG_0_INT)
+		{
+			DPRINTK("INT 0 for register still asserted\n");
+			return -EBUSY;
+		}
+
+		/* write message to register */
+		*(IOP310_MUOMR0) = val;
+	}
+	else						/* we are posting register 1 */
+	{
+		/* register busy */
+		if(*(IOP310_MUOISR) & MUOISR_OBMSG_1_INT)
+		{
+			DPRINTK("INT 1 for register still asserted\n");
+			return -EBUSY;
+		}
+
+		/* post message */
+		*(IOP310_MUOMR1) = val;
+	}
+	return 0;
+}								/* End of mu_msg_post() */
+
+/*=======================================================================*/
+/*  Procedure:  mu_msg_irq_task()                                        */
+/*                                                                       */
+/*  Description:  This function is the "bottom half" task of the irq     */
+/*                handler that handles the message registers inbound     */
+/*                messages. It will attempt to pass the message to the   */
+/*                app via the provided callback function                 */
+/*                                                                       */
+/*                                                                       */
+/*  Parameters:  dev - pointer to MU device descriptor                   */
+/*                                                                       */
+/*  Returns:     NONE                                                    */
+/*                                                                       */
+/*  Notes/Assumptions:  The app is responsible for providing a mechanism */
+/*                      to store the messages via the callback function  */
+/*                      when the task hands them off. This task is       */
+/*                      scheduled by the MU irq handler.                 */
+/*                                                                       */
+/*  History:    Dave Jiang 08/17/01  Initial Creation                    */
+/*=======================================================================*/
+static void mu_msg_irq_task(void *dev)
+{
+	iop310_mu_t *mu = (iop310_mu_t *) dev;
+	mu_msg_t *msg = &mu->msg_desc;
+	mu_msg_desc_t *msg_desc = NULL;
+
+	/* while we have message descriptors to process */
+	while(!list_empty(&msg->process_q))
+	{
+		/* get a message descriptor from process queue */
+		spin_lock_irq(&msg->process_lock);
+		msg_desc = MSG_ENTRY(msg->process_q.next);
+		list_del(&msg_desc->link);
+		spin_unlock_irq(&msg->process_lock);
+
+		/* if register 0 message */
+		if((msg_desc->reg_num == INBOUND_REG_0) && msg->callback_0)
+		{
+			msg->callback_0(msg_desc);
+		}
+		/* or register 1 message */
+		else if((msg_desc->reg_num == INBOUND_REG_1) && msg->callback_1)
+		{
+			msg->callback_1(msg_desc);
+		}
+
+		/* reinit message descriptors */
+		msg_desc->reg_num = INBOUND_REG_UNDEF;
+		msg_desc->message = 0;
+
+		/* put descriptor back on stack */
+		spin_lock_irq(&msg->free_lock);
+		list_add(&msg_desc->link, &msg->free_stack);
+		spin_unlock_irq(&msg->free_lock);
+	}
+}								/* End of msg_msg_irq_task() */
+
+/*=======================================================================*/
+/*  Procedure:  mu_msg_free()                                            */
+/*                                                                       */
+/*  Description:  This function is called to release the ownership of    */
+/*                the message registers mechanism. Resource is dealloc   */
+/*                if requested via parameter                             */
+/*                                                                       */
+/*  Parameters:  mu - pointer to MU device descriptor                    */
+/*               mode - MSG_FREE_SOFTMODE, MSG_FREE_HARDMODE             */
+/*                                                                       */
+/*  Returns:    0 - success                                             */
+/*              -EPERM - permissione denied                              */
+/*                                                                       */
+/*  Notes/Assumptions: Only the owner of the message mechanism shall     */
+/*                     call this function                                */
+/*                                                                       */
+/*  History:    Dave Jiang 08/17/01  Initial Creation                    */
+/*=======================================================================*/
+int mu_msg_free(u32 mu_context, u8 mode)
+{
+	iop310_mu_t *mu = (iop310_mu_t *) mu_context;
+	mu_msg_t *msg = &mu->msg_desc;
+	mu_msg_desc_t *msg_desc = NULL;
+
+	/* check ownership */
+	if(!atomic_read(&msg->in_use))
+	{
+		return -EPERM;
+	}
+
+	/* return all the descriptors to free stack */
+	while(!list_empty(&msg->process_q))
+	{
+		spin_lock_irq(&msg->process_lock);
+		msg_desc = MSG_ENTRY(msg->process_q.next);
+		list_del(&msg_desc->link);
+		spin_unlock_irq(&msg->process_lock);
+
+		msg_desc->reg_num = INBOUND_REG_UNDEF;
+		msg_desc->message = 0;
+
+		spin_lock_irq(&msg->free_lock);
+		list_add(&msg_desc->link, &msg->free_stack);
+		spin_unlock_irq(&msg->free_lock);
+	}
+
+	/* if hardmode we free all the descriptor memories */
+	if(mode == MSG_FREE_HARDMODE)
+	{
+		while(!list_empty(&msg->free_stack))
+		{
+			spin_lock_irq(&msg->free_lock);
+			msg_desc = MSG_ENTRY(msg->free_stack.next);
+			list_del(&msg_desc->link);
+			spin_unlock_irq(&msg->free_lock);
+			kfree(msg_desc);
+		}
+		/* unset resource init flag */
+		atomic_dec(&msg->res_init);
+	}
+
+	msg->callback_0 = NULL;
+	msg->callback_1 = NULL;
+
+	/* mask inbound/outbound INTs */
+	*(IOP310_MUIIMR) |= (MUIIMR_IBMSG_0_MASK | MUIIMR_IBMSG_1_MASK);
+	*(IOP310_MUOIMR) |= (MUOIMR_OBMSG_0_MASK | MUOIMR_OBMSG_1_MASK);
+
+	/* reset ownership flag */
+	atomic_dec(&msg->in_use);
+	return 0;
+}								/* End of mu_msg_free() */
+
+/*==========================MU Doorbell Registers========================*/
+
+/*=======================================================================*/
+/*  Procedure:  mu_db_request()                                          */
+/*                                                                       */
+/*  Description: This function is used to request the ownership of the   */
+/*               MU doorbell registers mechanism.                        */
+/*                                                                       */
+/*  Parameters:  NONE                                                    */
+/*                                                                       */
+/*  Returns:     iop310_mu_t * - success                                 */
+/*               NULL - failed                                           */
+/*                                                                       */
+/*  Notes/Assumptions: The requestor will own the entire MU db regs if   */
+/*                     successful.                                       */
+/*                                                                       */
+/*  History:    Dave Jiang 08/17/01  Initial Creation                    */
+/*=======================================================================*/
+inline int mu_db_request(u32 * mu_context)
+{
+	iop310_mu_t *mu = &mu_dev;
+	mu_db_t *db = &mu->db_desc;
+
+	/* check ownership flag */
+	if(atomic_read(&db->in_use))
+	{
+		/* already owned */
+		return -EBUSY;
+	}
+
+	/* set usage flag */
+	atomic_inc(&db->in_use);
+
+	/* unmask outbound int */
+	*(IOP310_MUOIMR) &= ~(MUOIMR_OBDB_MASK | MUOIMR_PCI_MASKA |
+						  MUOIMR_PCI_MASKB | MUOIMR_PCI_MASKC |
+						  MUOIMR_PCI_MASKD);
+
+	*mu_context = (u32) mu;
+	return 0;
+}	/* End of mu_db_request() */
+
+/*=======================================================================*/
+/*  Procedure:  mu_db_set_callback()                                     */
+/*                                                                       */
+/*  Description: This function sets up the callback func that will rcv   */
+/*               the inbound doorbell messages.                          */
+/*                                                                       */
+/*  Parameters:  mu - pointer to MU device descriptor                    */
+/*               func - pointer to callback function                     */
+/*                                                                       */
+/*  Returns:     -EINVAL - invalid parameter                             */
+/*                0 - success                                            */
+/*                                                                       */
+/*  Notes/Assumptions: The app owns the db mechanism.                    */
+/*                                                                       */
+/*  History:    Dave Jiang 08/17/01  Initial Creation                    */
+/*=======================================================================*/
+inline int mu_db_set_callback(u32 mu_context, mu_db_cb_t func)
+{
+	iop310_mu_t *mu = (iop310_mu_t *) mu_context;
+	mu_db_t *db = &mu->db_desc;
+
+	/* check parameter */
+	if(!func)
+	{
+		return -EINVAL;
+	}
+
+	/* set callback */
+	db->callback = func;
+
+	/* unmask inbound INTs */
+	*(IOP310_MUIIMR) &= ~(MUIIMR_IBDB_FIQ2_MASK | MUIIMR_IBDB_IRQ_MASK);
+
+	return 0;
+}	/* End of mu_db_set_callback() */
+
+/*=======================================================================*/
+/*  Procedure:  mu_db_ring()                                             */
+/*                                                                       */
+/*  Description: This funciton sets the outbound db reg bits requested   */
+/*               by the app                                              */
+/*                                                                       */
+/*  Parameters:  mu - pointer to MU device descriptor.                   */
+/*               mask - doorbell value to set                            */
+/*                                                                       */
+/*  Returns:     NONE                                                    */
+/*                                                                       */
+/*  Notes/Assumptions:                                                   */
+/*                                                                       */
+/*  History:    Dave Jiang 08/17/01  Initial Creation                    */
+/*=======================================================================*/
+inline void mu_db_ring(u32 mu_context, u32 mask)
+{
+	iop310_mu_t *mu = (iop310_mu_t *) mu_context;
+	/* set outbound db register */
+	*(IOP310_MUODR) |= mask;
+}	/* End of mu_db_ring() */
+
+/*=======================================================================*/
+/*  Procedure:  mu_db_irq_task()                                         */
+/*                                                                       */
+/*  Description: This function is the "bottom half" task for the irq hdl */
+/*               that will pass the inbound doorbell register value to   */
+/*               the app via callback.                                   */
+/*                                                                       */
+/*  Parameters:  dev - pointer to MU device descriptor                   */
+/*                                                                       */
+/*  Returns:     NONE                                                    */
+/*                                                                       */
+/*  Notes/Assumptions: The app is responsible for providing a mechanism  */
+/*                     to parse the doorbell register value after recv   */
+/*                     via callback.                                     */
+/*                                                                       */
+/*  History:    Dave Jiang 08/17/01  Initial Creation                    */
+/*=======================================================================*/
+static void mu_db_irq_task(void *dev)
+{
+	iop310_mu_t *mu = (iop310_mu_t *) dev;
+	mu_db_t *db = &mu->db_desc;
+	u32 value;
+
+	/* get latest inbound db value and reset hold var */
+	spin_lock_irq(&db->reg_lock);
+	value = db->reg_val;
+	db->reg_val = 0;
+	spin_unlock_irq(&db->reg_lock);
+
+	/* callback if exists */
+	if(db->callback)
+	{
+		db->callback(value);
+	}
+}	/* End of mu_db_irq_task() */
+
+/*=======================================================================*/
+/*  Procedure:  mu_db_free()                                             */
+/*                                                                       */
+/*  Description: This function releases ownership of the db registers.   */
+/*                                                                       */
+/*  Parameters:  mu - pointer to MU device descriptor.                   */
+/*                                                                       */
+/*  Returns:     0 - success                                            */
+/*               -EPERM - permission denied.                             */
+/*                                                                       */
+/*  Notes/Assumptions: Only the owner of db shall call this function.    */
+/*                                                                       */
+/*  History:    Dave Jiang 08/17/01  Initial Creation                    */
+/*=======================================================================*/
+inline int mu_db_free(u32 mu_context)
+{
+	iop310_mu_t *mu = (iop310_mu_t *) mu_context;
+	mu_db_t *db = &mu->db_desc;
+
+	/* check ownership */
+	if(!atomic_read(&db->in_use))
+	{
+		return -EPERM;
+	}
+
+	/* reset usage flag */
+	atomic_dec(&db->in_use);
+
+	db->callback = NULL;
+
+	/* reset store value */
+	spin_lock_irq(&db->reg_lock);
+	db->reg_val = 0;
+	spin_unlock_irq(&db->reg_lock);
+
+	/* mask inbound & outbound INTs */
+	*(IOP310_MUIIMR) |= (MUIIMR_IBDB_FIQ2_MASK | MUIIMR_IBDB_IRQ_MASK);
+	*(IOP310_MUOIMR) |= (MUOIMR_OBDB_MASK | MUOIMR_PCI_MASKA |
+						 MUOIMR_PCI_MASKB | MUOIMR_PCI_MASKC |
+						 MUOIMR_PCI_MASKD);
+	return 0;
+}								/* End of mu_db_free() */
+
+/*===========================MU Circular Queues==========================*/
+
+/*=======================================================================*/
+/*  Procedure:  mu_cq_request()                                          */
+/*                                                                       */
+/*  Description: This function is used to request the ownership of the   */
+/*               MU circular queues mechanism.                           */
+/*                                                                       */
+/*  Parameters:  q_size - MUCR_QUEUE_4K, MUCR_QUEUE_8K, MUCR_QUEUE_16K,  */
+/*                        MUCR_QUEUE_32K, MUCR_QUEUE_64K                 */
+/*                                                                       */
+/*  Returns:     iop310_mu_t * - success                                 */
+/*               NULL - permission denied                                */
+/*                                                                       */
+/*  Notes/Assumptions: The request shall own entire cq if successful.    */
+/*                                                                       */
+/*  History:    Dave Jiang 08/17/01  Initial Creation                    */
+/*=======================================================================*/
+int mu_cq_request(u32 * mu_context, u32 q_size)
+{
+	iop310_mu_t *mu = &mu_dev;
+	mu_cq_t *cq = &mu->cq_desc;
+	u32 entry_size = 0;
+	u32 queue_cmd = 0;
+	
+	/* check ownership */
+	if(atomic_read(&cq->in_use))
+	{
+		DPRINTK("Already owned\n");
+		return -EBUSY;
+	}
+	
+	/* set ownership flag */
+	atomic_inc(&cq->in_use);
+
+	/* set top of inbound free queue */	
+	cq->inb_free_q_top = virt_to_phys(mu_mem);
+	
+	/* set queue size */
+	cq->q_size = q_size;
+
+	/* set rest of queue pointers */
+	switch (q_size)
+	{
+	case MUCR_QUEUE_4K:
+		entry_size = QUEUE_16K;
+		queue_cmd = MUCR_QUEUE_4K;
+		cq->num_entries = ENTRY_4K;
+		break;
+	case MUCR_QUEUE_8K:
+		entry_size = QUEUE_32K;
+		queue_cmd = MUCR_QUEUE_8K;
+		cq->num_entries = ENTRY_8K;
+		break;
+	case MUCR_QUEUE_16K:
+		entry_size = QUEUE_64K;
+		queue_cmd = MUCR_QUEUE_16K;
+		cq->num_entries = ENTRY_16K;
+		break;
+	case MUCR_QUEUE_32K:
+		entry_size = QUEUE_128K;
+		queue_cmd = MUCR_QUEUE_32K;
+		cq->num_entries = ENTRY_32K;
+		break;
+	case MUCR_QUEUE_64K:
+		entry_size = QUEUE_256K;
+		queue_cmd = MUCR_QUEUE_64K;
+		cq->num_entries = ENTRY_64K;
+		break;
+	default:
+		/* wrong queue size from parameter */
+		return -EINVAL;
+	}
+	
+	cq->inb_post_q_top = entry_size;
+	cq->outb_post_q_top = entry_size * 2;
+	cq->outb_free_q_top = entry_size * 3;
+	cq->inb_free_q_end = cq->inb_post_q_top - 4;
+	cq->inb_post_q_end = cq->outb_post_q_top - 4;
+	cq->outb_post_q_end = cq->outb_free_q_top;
+	cq->outb_free_q_end = (entry_size * 4) - 4;
+	*(IOP310_MUMUCR) = queue_cmd;
+
+	cpu_dcache_clean_range((u32)mu_mem, ((u32)mu_mem + entry_size));
+
+	/* Set head pointers and tail pointers */
+	/* equal since they are empty */
+	*(IOP310_MUIFHPR) = cq->inb_free_q_top;
+	*(IOP310_MUIFTPR) = cq->inb_free_q_top;
+	*(IOP310_MUIPHPR) = cq->inb_post_q_top;
+	*(IOP310_MUIPTPR) = cq->inb_post_q_top;
+	*(IOP310_MUOPHPR) = cq->outb_post_q_top;
+	*(IOP310_MUOPTPR) = cq->outb_post_q_top;
+	*(IOP310_MUOFHPR) = cq->outb_free_q_top;
+	*(IOP310_MUOFTPR) = cq->outb_free_q_top;
+
+	*mu_context = (u32) mu;
+	return 0;
+}								/* End of mu_cq_request() */
+
+/*=======================================================================*/
+/*  Procedure:  mu_cq_inbound_init()                                     */
+/*                                                                       */
+/*  Description: This function sets up the inbound queues. The caller of */
+/*               the function will pass down a linked list of MFA addrs. */
+/*               The function will put all the mfa in the free ib queue. */
+/*                                                                       */
+/*  Parameters:  mu - pointer to MU device descriptor                    */
+/*               list - pointer to list of message frame address         */
+/*               size - number of entries in list                        */
+/*               func - pointer to callback function                     */
+/*                                                                       */
+/*  Returns:     0 - success                                             */
+/*               -EINVAL - invalid parameter                             */
+/*                                                                       */
+/*  Notes/Assumptions: Only to be called by owner of CQ.                 */
+/*                                                                       */
+/*  History:    Dave Jiang 08/20/01  Initial Creation                    */
+/*=======================================================================*/
+int mu_cq_inbound_init(u32 mu_context, mfa_list_t * list, u32 size,
+				   mu_cq_cb_t func)
+{
+	iop310_mu_t *mu = (iop310_mu_t *) mu_context;
+	mu_cq_t *cq = &mu->cq_desc;
+	mfa_list_t *tmp_list = list;
+	u32 mem_offset = 0;
+	u32 *mem = NULL;
+	u32 limit;
+	
+	/* check parameters */
+	if(!list || !func)
+	{
+		return -EINVAL;
+	}
+
+	/* if list size larger than queue size */
+	if(size > cq->num_entries)
+	{
+		DPRINTK("More MFA entries than inbound free queue can hold!\n");
+		return -EINVAL;
+	}
+
+	/* Get Address Limit */
+	limit = *(IOP310_PIALR);
+
+	/* put all MFA in list on free queue */
+	while(tmp_list)
+	{
+		mem_offset = *IOP310_MUIFHPR & 0xfffff;
+		mem = (u32 *)((u32)mu_mem + mem_offset);
+
+		/* The MFA value is the offset of the Primary Inbound ATU Base Address */
+		*mem = (u32)virt_to_phys(tmp_list->mfa) & ~limit;
+
+		/* move 32 bits to next pointer */
+		*(IOP310_MUIFHPR) += sizeof(u32);
+
+		/* if we are at top of queue wrap around */
+		if(*(IOP310_MUIFHPR) == cq->inb_free_q_end)
+		{
+			DPRINTK("wrap around\n");
+			*(IOP310_MUIFHPR) = cq->inb_free_q_top;
+		}
+
+		/* if the head and tail meet, we have no more space */
+		if(*(IOP310_MUIFHPR) == *(IOP310_MUIFTPR))
+		{
+			break;
+		}
+
+		tmp_list = tmp_list->next_list;
+	}							/* end of while */
+
+	/* set resource init flag */
+	atomic_inc(&cq->init_ref);
+	/* set callback */
+	cq->callback = func;
+
+	return 0;
+}								/* End of mu_cq_inbound_init() */
+
+/*=======================================================================*/
+/*  Procedure:  mu_cq_enable()                                           */
+/*                                                                       */
+/*  Description: This function enables the circular queues and unmask    */
+/*               the INTs.                                               */
+/*                                                                       */
+/*  Parameters:  mu - pointer to MU device descriptor.                   */
+/*                                                                       */
+/*  Returns:     -EPERM - permission denied                              */
+/*               0 - success                                            */
+/*                                                                       */
+/*  Notes/Assumptions: Only called after iq80310MuCqIbInit().            */
+/*                                                                       */
+/*  History:    Dave Jiang 08/20/01  Initial Creation                    */
+/*=======================================================================*/
+inline int mu_cq_enable(u32 mu_context)
+{
+	iop310_mu_t *mu = (iop310_mu_t *) mu_context;
+	mu_cq_t *cq = &mu->cq_desc;
+
+	/* if no resource init fail */
+	if(!atomic_read(&cq->init_ref) || !atomic_read(&cq->in_use))
+	{
+		DPRINTK("Resources not initialized\n");
+		return -EPERM;
+	}
+
+	/* enable circular queues */
+	*(IOP310_MUMUCR) |= MUCR_QUEUE_ENABLE;
+	/* unmask inbound ints */
+	*(IOP310_MUIIMR) &= ~(MUIIMR_IBPQ_MASK | MUIIMR_IBFQF_MASK);
+	/* unmask outbound ints */
+	/* the host should unmask this when it sends down */
+	/* message frames */
+	/* *(IOP310_MUOIMR) &= ~MUOIMR_OBPQ_MASK; */
+
+	/* enable PATU memory access response */	
+	*(IOP310_PATUCMD) |= 0x2;	
+
+	return 0;
+}
+
+/*=======================================================================*/
+/*  Procedure:  mu_cq_get_frame()                                        */
+/*                                                                       */
+/*  Description: This function will attempt to retrieve a free message   */
+/*               frame from the outbound free queue.                     */
+/*                                                                       */
+/*  Parameters:  mu - pointer to MU device descriptor                    */
+/*                                                                       */
+/*  Returns:     free frame address                                      */
+/*               0xFFFFFFFF - no frame available                         */
+/*                                                                       */
+/*  Notes/Assumptions: N/A                                               */
+/*                                                                       */
+/*  History:    Dave Jiang 08/20/01  Initial Creation                    */
+/*=======================================================================*/
+inline u32 mu_cq_get_frame(u32 mu_context)
+{
+	iop310_mu_t *mu = (iop310_mu_t *) mu_context;
+	mu_cq_t *cq = &mu->cq_desc;
+	u32 mem_offset = 0;
+	u32 *mfa_ptr = NULL;
+
+	spin_lock_irq(&cq->ob_free_lock);
+	if(*(IOP310_MUOFTPR) == *(IOP310_MUOFHPR))
+	{
+		DPRINTK("No outbound frames!\n");
+		spin_unlock_irq(&&cq->ob_free_lock);
+		return FULL_MASK;
+	}
+	/* get address from outbound free tail pointer register */
+	mem_offset = *(IOP310_MUOFTPR) & 0xfffff;
+	/* wrap around if need to */
+	*(IOP310_MUOFTPR) += sizeof(u32);
+	if(*(IOP310_MUOFTPR) == cq->outb_free_q_end)
+	{
+		*(IOP310_MUOFTPR) = cq->outb_free_q_top;
+	}
+	spin_unlock_irq(&cq->ob_free_lock);
+	
+	mfa_ptr = (u32 *)((u8 *)mu_mem + mem_offset);
+	cpu_dcache_invalidate_range((u32)mfa_ptr, (u32)mfa_ptr+4);
+
+	return *mfa_ptr;
+}
+
+/*=======================================================================*/
+/*  Procedure:  mu_cq_post_frame()                                       */
+/*                                                                       */
+/*  Description: This function attempt to post the message frame prov by */
+/*               the user onto the outbound post qeuue.                  */
+/*                                                                       */
+/*  Parameters:  mu - pointer to MU device descriptor                    */
+/*               nMfa - message frame address                            */
+/*                                                                       */
+/*  Returns:     -EBUSY - outbound queue full                            */
+/*               0 - success                                             */
+/*                                                                       */
+/*  Notes/Assumptions: Only the owner of cq shall call this function.    */
+/*                                                                       */
+/*  History:    Dave Jiang 08/20/01  Initial Creation                    */
+/*=======================================================================*/
+inline int mu_cq_post_frame(u32 mu_context, u32 mfa)
+{
+	iop310_mu_t *mu = (iop310_mu_t *)mu_context;
+	mu_cq_t *cq = &mu->cq_desc;
+	u32 irq_assert = 0;
+	u8 ptr_equal = 0;
+	u32 mem_offset = 0;
+	u32 *mem = NULL;
+	
+	spin_lock_irq(&cq->ob_post_lock);
+
+	/* see if queue full */
+	irq_assert = *(IOP310_MUOISR) & MUOISR_OBPQ_INT;
+	ptr_equal = (*(IOP310_MUOPHPR) == *(IOP310_MUOPTPR)) ? 1 : 0;
+
+	/* if queue full condition */
+	if(irq_assert && ptr_equal)
+	{
+		spin_unlock_irq(&cq->ob_post_lock);
+		return -EBUSY;
+	}
+
+	mem_offset = *IOP310_MUOPHPR & 0xfffff;
+	mem = (u32 *)((u8 *)mu_mem + mem_offset);
+	*mem = (u32)virt_to_bus(mfa);
+	cpu_dcache_clean_range((u32)mem, (u32)mem+4);
+	/* move 32 bits to next pointer */
+	*(IOP310_MUOPHPR) += sizeof(u32);
+
+	/* if we are at top of queue wrap around */
+	if(*(IOP310_MUOPHPR) == cq->outb_post_q_end)
+	{
+		DPRINTK("wrap around\n");
+		*(IOP310_MUOPHPR) = cq->outb_post_q_top;
+	}
+
+	spin_unlock_irq(&cq->ob_post_lock);
+	return 0;
+}
+
+/*=======================================================================*/
+/*  Procedure:  mu_cq_irq_task()                                         */
+/*                                                                       */
+/*  Description: This funciton is scheduled by the MU irq hdlr. It       */
+/*               removes all inbound message frames from the ib post q.  */
+/*               It then passes them to the app. Then it put the mfa     */
+/*               back on the free queue                                  */
+/*                                                                       */
+/*  Parameters:  dev - pointer to MU device descriptor                   */
+/*                                                                       */
+/*  Returns:     NONE                                                    */
+/*                                                                       */
+/*  Notes/Assumptions:  The content of message frame must be perserved   */
+/*                      by app when passed back. Once callback return    */
+/*                      the message frame is considered free.            */
+/*                                                                       */
+/*  History:    Dave Jiang 08/20/01  Initial Creation                    */
+/*=======================================================================*/
+static void mu_cq_irq_task(void *dev)
+{
+	iop310_mu_t *mu = (iop310_mu_t *)dev;
+	mu_cq_t *cq = &mu->cq_desc;
+	u32 *mfa_ptr = NULL;
+	u32 mem_offset = 0;
+	u32 *mem = NULL;
+	
+	DPRINTK("Entering cq irq task\n");
+
+	while(*(IOP310_MUIPTPR) != *(IOP310_MUIPHPR))
+	{
+		spin_lock_irq(&cq->ib_post_lock);
+		/* move tail pointer, wrap if neccesary */
+		/* remove MFA from post queue */
+		mem_offset = *IOP310_MUIPTPR & 0xfffff;
+		*(IOP310_MUIPTPR) += sizeof(u32);
+		if(*(IOP310_MUIPTPR) == mu->cq_desc.inb_post_q_end)
+		{
+			*(IOP310_MUIPTPR) = mu->cq_desc.inb_post_q_top;
+		}
+		spin_unlock_irq(&cq->ib_post_lock);
+
+		mfa_ptr = (u32 *)((u8 *)mu_mem + mem_offset);
+		cpu_dcache_invalidate_range((u32)mfa_ptr, (u32)mfa_ptr+4);
+		
+		if(cq->callback)
+		{
+			DPRINTK("Calling callback\n");
+			/* pass frame to app */
+			cq->callback(*mfa_ptr | *(IOP310_PIATVR));
+		}
+		
+		/* put frame back to free queue */
+		spin_lock_irq(&cq->ib_free_lock);
+		mem_offset = *IOP310_MUIFHPR & 0xfffff;
+		mem = (u32 *)((u32)mu_mem + mem_offset);
+		*mem = (u32)virt_to_bus(*mfa_ptr);
+		*(IOP310_MUIFHPR) += sizeof(u32);
+		if(*(IOP310_MUIFHPR) == cq->inb_free_q_end)
+		{
+			*(IOP310_MUIFHPR) = cq->inb_free_q_top;
+		}
+		spin_unlock_irq(&cq->ib_free_lock);
+	}
+
+	*(IOP310_MUIIMR) &= ~MUIIMR_IBPQ_MASK; 
+}
+
+/*=======================================================================*/
+/*  Procedure:  mu_cq_free()                                             */
+/*                                                                       */
+/*  Description: This function is called to release ownership of CQ.     */
+/*                                                                       */
+/*  Parameters:  mu - pointer to MU device descriptor.                   */
+/*                                                                       */
+/*  Returns:     0 - success                                            */
+/*               -EPERM - permission denied.                             */
+/*                                                                       */
+/*  Notes/Assumptions: Only the owner of CQ shall call this.             */
+/*                                                                       */
+/*  History:    Dave Jiang 08/20/01  Initial Creation                    */
+/*=======================================================================*/
+inline int mu_cq_free(u32 mu_context)
+{
+	iop310_mu_t *mu = (iop310_mu_t *)mu_context;
+	mu_cq_t *cq = &mu->cq_desc;
+	
+	/* check ownership */
+	if(!atomic_read(&cq->in_use))
+	{
+		return -EPERM;
+	}
+
+	/* reset variables */
+	atomic_dec(&cq->in_use);
+	atomic_dec(&cq->init_ref);
+	cq->callback = NULL;
+
+	/* disable CQ and mask inbound/outbound CQ INTs */
+	*(IOP310_MUMUCR) = NULL_MASK;
+	*(IOP310_MUIIMR) |= MUIIMR_IBPQ_MASK | MUIIMR_IBFQF_MASK;
+	*(IOP310_MUOIMR) |= MUOIMR_OBPQ_MASK;
+
+	return 0;
+}	
+
+
+/*===========================MU Index Registers==========================*/
+
+/*=======================================================================*/
+/*  Procedure:  mu_ir_request()                                          */
+/*                                                                       */
+/*  Description: This function is used to request the ownership of the   */
+/*               Index Registers mechanism.                              */
+/*                                                                       */
+/*  Parameters:  NONE                                                    */
+/*                                                                       */
+/*  Returns:     iop310_mu_t * - success                                 */
+/*               NULL - failed                                           */
+/*                                                                       */
+/*  Notes/Assumptions: The requestor will own IR mechanism if successful */
+/*                                                                       */
+/*  History:    Dave Jiang 08/20/01  Initial Creation                    */
+/*=======================================================================*/
+inline int mu_ir_request(u32 * mu_context)
+{
+	iop310_mu_t *mu = &mu_dev;
+	mu_ir_t *ir = &mu->ir_desc;
+
+	/* if onwed already */
+	if(atomic_read(&ir->in_use))
+	{
+		return -EBUSY;
+	}
+
+	/* set ownership */
+	atomic_inc(&ir->in_use);
+	*mu_context = (u32)mu;
+	return 0;
+}
+
+/*=======================================================================*/
+/*  Procedure:  mu_ir_set_callback()                                     */
+/*                                                                       */
+/*  Description: This function sets the callback function used to recv   */
+/*               incoming messages.                                      */
+/*                                                                       */
+/*  Parameters:  mu - pointer to MU device descriptor                    */
+/*               func - pointer to callback                              */
+/*                                                                       */
+/*  Returns:     0 - success                                            */
+/*               -EINVAL - invalid parameter                             */
+/*                                                                       */
+/*  Notes/Assumptions: called after claiming ownership of IR             */
+/*                                                                       */
+/*  History:    Dave Jiang 08/20/01  Initial Creation                    */
+/*=======================================================================*/
+inline int mu_ir_set_callback(u32 mu_context, mu_ir_cb_t func)
+{
+	iop310_mu_t *mu = (iop310_mu_t *) mu_context;
+	mu_ir_t *ir = &mu->ir_desc;
+
+	/* check parameter */
+	if(!func)
+	{
+		return -EINVAL;
+	}
+
+	/* set parameter */
+	ir->callback = func;
+
+	/* unmask INTs */
+	*(IOP310_MUIIMR) &= ~MUIIMR_IR_MASK;
+
+	return 0;
+}
+
+/*=======================================================================*/
+/*  Procedure:  mu_ir_irq_task()                                         */
+/*                                                                       */
+/*  Description: This function retrieves the offset from temp store in   */
+/*               the IR descriptor and computes the message address.     */
+/*               After passing the address it unmasks the INT bit.       */
+/*                                                                       */
+/*  Parameters:  dev - pointer to MU device descriptor                  */
+/*                                                                       */
+/*  Returns:     NONE                                                    */
+/*                                                                       */
+/*  Notes/Assumptions: NONE                                              */
+/*                                                                       */
+/*  History:    Dave Jiang 08/20/01  Initial Creation                    */
+/*=======================================================================*/
+inline static void mu_ir_irq_task(void *dev)
+{
+	iop310_mu_t *mu = (iop310_mu_t *)dev;
+	mu_ir_t *ir = &mu->ir_desc;
+	u32 addr_val = 0;
+	u32 *mem = NULL;
+
+	/* calculate message address */
+	/* start from Primary Inbound Address Translation Value Register */
+	addr_val = ir->offset + *(IOP310_PIATVR);
+
+	mem = phys_to_virt(addr_val);
+	/* pass value to callback */
+	if(ir->callback)
+	{
+		ir->callback(*mem);
+	}
+
+	/* Unmask the inbound INT */
+	*(IOP310_MUIIMR) &= ~MUIIMR_IR_MASK;
+}	
+
+/*=======================================================================*/
+/*  Procedure:  mu_ir_free()                                             */
+/*                                                                       */
+/*  Description: This function releases ownership of IR.                 */
+/*                                                                       */
+/*  Parameters:  mu - pointer to MU device descriptor                    */
+/*                                                                       */
+/*  Returns:     -EPERM - permission denied                              */
+/*               0 - success                                            */
+/*                                                                       */
+/*  Notes/Assumptions: Only called by the owner of IR.                   */
+/*                                                                       */
+/*  History:    Dave Jiang 08/20/01  Initial Creation                    */
+/*=======================================================================*/
+inline int mu_ir_free(u32 mu_context)
+{
+	iop310_mu_t *mu = (iop310_mu_t *)mu_context;
+	mu_ir_t *ir = &mu->ir_desc;
+
+	/* check ownership */
+	if(!atomic_read(&ir->in_use))
+	{
+		return -EPERM;
+	}
+
+	/* unset owner */
+	atomic_dec(&ir->in_use);
+
+
+	ir->callback = NULL;
+
+	/* mask INT */
+	*(IOP310_MUIIMR) |= MUIIMR_IR_MASK;
+
+	return 0;
+}
+
+
+/*===========================MU Common Functions=========================*/
+
+/*=======================================================================*/
+/*  Procedure:  mu_irq_handler()                                         */
+/*                                                                       */
+/*  Description: This function is the interrupt handler for MU. It       */
+/*               checks for MU int bit asserted and then schedules the   */
+/*               proper bottom half task to take care of the INTs.       */
+/*                                                                       */
+/*  Parameters:  irq - IRQ number (not used)                             */
+/*               dev_id - pointer to MU device descriptor                */
+/*               regs - CPU registers (not used)                         */
+/*                                                                       */
+/*  Returns:     NONE                                                    */
+/*                                                                       */
+/*  Notes/Assumptions: This function is only called by XScale IRQ hdlr.  */
+/*                                                                       */
+/*  History:    Dave Jiang 08/16/01  Initial Creation                    */
+/*=======================================================================*/
+static void mu_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	iop310_mu_t *mu = (iop310_mu_t *)dev_id;
+	u32 irq_status;
+	u32 iisr;
+	volatile u32 *reg_val_ptr;
+	u8 msg_reg = 0;
+	u32 mask = 0;
+	mu_msg_desc_t *msg_desc = NULL;
+	int thresh;
+
+	/* get inbound irq status */
+	iisr = *(IOP310_MUIISR);
+
+	thresh = atomic_read(&mu->irq_thresh);
+
+	do
+	{
+		/* if message registers INT */
+		if(iisr & (MUIISR_IBMSG_0_INT | MUIISR_IBMSG_1_INT))
+		{
+			if(!list_empty(&mu->msg_desc.free_stack))
+			{
+				/* get message descriptor from free stack */
+				spin_lock(&mu->msg_desc.free_lock);
+				msg_desc = MSG_ENTRY(mu->msg_desc.free_stack.next);
+				list_del(&msg_desc->link);
+				spin_unlock(&mu->msg_desc.free_lock);
+			}
+			else
+			{
+				DPRINTK("Out of message descriptors!\n");
+				return;
+			}
+
+			/* if inbound register 0 */
+			if(iisr & MUIISR_IBMSG_0_INT)
+			{
+				msg_reg = INBOUND_REG_0;
+				reg_val_ptr = IOP310_MUIMR0;
+				mask = MUIISR_IBMSG_0_INT;
+			}
+			else				/* or inbound register 1 */
+			{
+				msg_reg = INBOUND_REG_1;
+				reg_val_ptr = IOP310_MUIMR1;
+				mask = MUIISR_IBMSG_1_INT;
+			}
+
+			/* set register number */
+			msg_desc->reg_num = msg_reg;
+
+			/* record register value */
+			msg_desc->message = *(reg_val_ptr);
+
+			/* put message descriptor on process queue */
+			spin_lock(&mu->msg_desc.process_lock);
+			list_add_tail(&msg_desc->link, &mu->msg_desc.process_q);
+			spin_unlock(&mu->msg_desc.process_lock);
+
+			/* read/clear INT */
+			*(IOP310_MUIISR) |= ~mask;
+			/* schedule bottom half tasklet */
+			mu->msg_desc.msg_task.data = (void *)mu;
+			/* task goes to the immediate task queue */
+			queue_task(&mu->msg_desc.msg_task, &tq_immediate);
+		}
+
+		/* if doorbell INT */
+		if(iisr & (MUIISR_IBDB_FIQ2_INT | MUIISR_IBDB_IRQ_INT))
+		{
+			spin_lock(&mu->db_desc.reg_lock);
+			/* get register value */
+			mu->db_desc.reg_val |= *(IOP310_MUIDR);
+			/* read clear register, this clear INTs */
+			*(IOP310_MUIDR) |= mu->db_desc.reg_val;
+			spin_unlock(&mu->db_desc.reg_lock);
+
+			/* schedule bottom half tasklet */
+			mu->db_desc.db_task.data = (void *)mu;
+			/* task goes to the immediate task queue */
+			queue_task(&mu->db_desc.db_task, &tq_immediate);
+		}
+
+		/* if inbound post queue */
+		if(iisr & MUIISR_IBPQ_INT)
+		{
+			/* ack INT bit , read/clear */
+			*(IOP310_MUIISR) |= MUIISR_IBPQ_INT;
+			*(IOP310_MUIIMR) |= MUIIMR_IBPQ_MASK; 
+			/* schedule task */
+			mu->cq_desc.cq_task.data = (void *)mu;
+			queue_task(&mu->cq_desc.cq_task, &tq_immediate);
+		}
+
+		/* if inbound free queue full */
+		if(iisr & MUIISR_IBFQF_INT)
+		{
+			/* ack INT bit */
+			*(IOP310_MUIISR) &= ~(MUIISR_IBFQF_INT);
+		}
+
+		/* if index register */
+		if(iisr & MUIISR_IR_INT)
+		{
+			/* mask interrupt bit */
+			/* store offset */
+			/* read/clear interrupt status */
+			*(IOP310_MUIIMR) |= MUIIMR_IR_MASK;
+			mu->ir_desc.offset = *(IOP310_MUIAR);
+			/* read clear INT */
+			*(IOP310_MUIISR) |= MUIISR_IR_INT;
+			/* queue task */
+			mu->ir_desc.ir_task.data = (void *)mu;
+			queue_task(&mu->ir_desc.ir_task, &tq_immediate);
+		}
+
+		/* get int status */
+		iisr = *(IOP310_MUIISR);
+
+		/* get FIQ status */
+		irq_status = *(IOP310_FIQ2ISR);
+	}
+	while(irq_status && --thresh);
+
+	/* mark IMMEDIATE BH for execute */
+	mark_bh(IMMEDIATE_BH);
+}
+
+/*=======================================================================*/
+/*  Procedure:  mu_init()                                                */
+/*                                                                       */
+/*  Description:    This function initializes the MU to pre-own state.   */
+/*                                                                       */
+/*  Parameters:  NONE                                                    */
+/*                                                                       */
+/*  Returns:     0 - success                                             */
+/*               -ENOMEM - no memory allocated for circular queues       */
+/*               -EBUSY - cannot alloc irq                               */
+/*                                                                       */
+/*  Notes/Assumptions: This function is only called by kernel at init.   */
+/*                                                                       */
+/*  History:    Dave Jiang 08/16/01  Initial Creation                    */
+/*=======================================================================*/
+static int __init mu_init(void)
+{
+	iop310_mu_t *mu = &mu_dev;
+	int err = 0;
+
+	printk("Intel 80310 MU Copyright(c) 2001 Intel Corporation\n");
+
+	/* check to see if we allocated QBAR at 0x100000 align, 0x100000 size */
+	if(!mu_mem)
+	{
+		DPRINTK("No memory allocated for circular queue\n");
+		return -ENOMEM;
+	}
+
+#ifdef REGMAP
+	mu->regs = (mu_regs_t *)IOP310_MUIMR0;
+#endif
+
+	/* mask all INTs */
+	*(IOP310_MUIIMR) = FULL_MASK;
+	*(IOP310_MUOIMR) = FULL_MASK;
+
+	/* set irq */
+	mu->irq = IRQ_IOP310_MU;
+
+	/* setup message registers */
+	mu->msg_desc.callback_0 = NULL;
+	mu->msg_desc.callback_1 = NULL;
+	spin_lock_init(&mu->msg_desc.free_lock);
+	spin_lock_init(&mu->msg_desc.process_lock);
+	INIT_LIST_HEAD(&mu->msg_desc.free_stack);
+	INIT_LIST_HEAD(&mu->msg_desc.process_q);
+	atomic_set(&mu->msg_desc.res_init, 0);
+	atomic_set(&mu->msg_desc.in_use, 0);
+	mu->msg_desc.msg_task.sync = 0;
+	mu->msg_desc.msg_task.routine = mu_msg_irq_task;
+
+
+	/* setup doorbell registers */
+	mu->db_desc.reg_val = 0;
+	mu->db_desc.callback = NULL;
+	atomic_set(&mu->db_desc.in_use, 0);
+	spin_lock_init(&mu->db_desc.reg_lock);
+	mu->db_desc.db_task.sync = 0;
+	mu->db_desc.db_task.routine = mu_db_irq_task;
+
+	/* setup circular queues */
+	mu->cq_desc.q_size = 0;
+	mu->cq_desc.callback = NULL;
+	spin_lock_init(&mu->cq_desc.ib_free_lock);
+	spin_lock_init(&mu->cq_desc.ib_post_lock);
+	spin_lock_init(&mu->cq_desc.tObFreeQLock);
+	spin_lock_init(&mu->cq_desc.ob_post_lock);
+	atomic_set(&mu->cq_desc.init_ref, 0);
+	atomic_set(&mu->cq_desc.in_use, 0);
+	mu->cq_desc.cq_task.sync = 0;
+	mu->cq_desc.cq_task.routine = mu_cq_irq_task;
+
+	/* set QBAR */
+	*(IOP310_MUQBAR) = (u32)virt_to_phys(mu_mem);
+
+	/* setup index registers */
+	mu->ir_desc.offset = 0;
+	mu->ir_desc.callback = NULL;
+	atomic_set(&mu->ir_desc.in_use, 0);
+	mu->ir_desc.ir_task.sync = 0;
+	mu->ir_desc.ir_task.routine = mu_ir_irq_task;
+
+
+	/* request IRQ for the MU */
+	err = request_irq(mu->irq, mu_irq_handler, SA_INTERRUPT,
+					  "i80310 MU", (void *)mu);
+	if(err < 0)
+	{
+		printk(KERN_ERR "%s: unable to request IRQ %d for MU: %d\n",
+			   "i80310 MU", mu->irq, err);
+		/* reset ref count */
+		return -EBUSY;
+	}
+
+	/* set irq threshold */
+	atomic_set(&mu->irq_thresh, DEFAULT_MU_IRQ_THRESH);
+
+	return 0;
+}
+
+/*=======================================================================*/
+/*  Procedure:  mu_set_irq_threshold()                                   */
+/*                                                                       */
+/*  Description:  This function readjust the threshold for the irq.      */
+/*                                                                       */
+/*  Parameters:  mu: pointer to mu device descriptor                     */
+/*               value: value of new irq threshold                       */
+/*                                                                       */
+/*  Returns:     N/A                                                     */
+/*                                                                       */
+/*  Notes/Assumptions:  default is set at 10                             */
+/*                                                                       */
+/*  History:    Dave Jiang 08/27/01  Initial Creation                    */
+/*=======================================================================*/
+void mu_set_irq_threshold(u32 mu_context, int thresh)
+{
+	iop310_mu_t *mu = (iop310_mu_t *)mu_context;
+
+	atomic_set(&mu->irq_thresh, thresh);
+}/* End of mu_set_irq_threshold() */
+
+
+EXPORT_SYMBOL_NOVERS(mu_msg_request);
+EXPORT_SYMBOL_NOVERS(mu_msg_set_callback);
+EXPORT_SYMBOL_NOVERS(mu_msg_post);
+EXPORT_SYMBOL_NOVERS(mu_msg_free);
+EXPORT_SYMBOL_NOVERS(mu_db_request);
+EXPORT_SYMBOL_NOVERS(mu_db_set_callback);
+EXPORT_SYMBOL_NOVERS(mu_db_ring);
+EXPORT_SYMBOL_NOVERS(mu_db_free);
+EXPORT_SYMBOL_NOVERS(mu_cq_request);
+EXPORT_SYMBOL_NOVERS(mu_cq_inbound_init);
+EXPORT_SYMBOL_NOVERS(mu_cq_enable);
+EXPORT_SYMBOL_NOVERS(mu_cq_get_frame);
+EXPORT_SYMBOL_NOVERS(mu_cq_post_frame);
+EXPORT_SYMBOL_NOVERS(mu_cq_free);
+EXPORT_SYMBOL_NOVERS(mu_ir_request);
+EXPORT_SYMBOL_NOVERS(mu_ir_set_callback);
+EXPORT_SYMBOL_NOVERS(mu_ir_free);
+EXPORT_SYMBOL_NOVERS(mu_set_irq_threshold);
+
+module_init(mu_init);
+
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/message.h linux-2.4.29-uc1/arch/arm/mach-iop3xx/message.h
--- linux-2.4.29/arch/arm/mach-iop3xx/message.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/message.h	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,185 @@
+/*
+ * Private Definitions for IOP310 MU 
+ *
+ * Author: Dave Jiang (dave.jiang@intel.com)
+ * Copyright (C) 2001 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _MU_PRIVATE_H_
+#define _MU_PRIVATE_H_
+
+#include <asm/arch/message.h>
+
+#define DEFAULT_MU_IRQ_THRESH  10
+
+#define FULL_MASK       0xffffffff
+#define NULL_MASK       0x00000000
+
+#define MAX_MSG_DESC    32
+#define MAX_MFA_DESC	128
+
+#define FIQ2ISR_MU      0x00000004
+#define IRQISR_MU       0x00000100
+
+#define INBOUND_REG_UNDEF   0x00
+#define INBOUND_REG_0       0x01
+#define INBOUND_REG_1       0x02
+#define INBOUND_REG_BOTH    (INBOUND_REG_0 | INBOUND_REG_1)
+
+#define OUTBOUND_REG_0      0x01
+#define OUTBOUND_REG_1      0x02
+
+#define MSG_FREE_HARDMODE   0x01
+#define MSG_FREE_SOFTMODE   0x02
+
+#define MUIISR_IBMSG_0_INT      0x0001
+#define MUIISR_IBMSG_1_INT      0x0002
+#define MUIISR_IBDB_FIQ2_INT    0x0004
+#define MUIISR_IBDB_IRQ_INT     0x0008
+#define MUIISR_IBPQ_INT         0x0010
+#define MUIISR_IBFQF_INT        0x0020
+#define MUIISR_IR_INT           0x0040
+
+#define MUIIMR_IBMSG_0_MASK     0x0001
+#define MUIIMR_IBMSG_1_MASK     0x0002
+#define MUIIMR_IBDB_FIQ2_MASK   0x0004
+#define MUIIMR_IBDB_IRQ_MASK    0x0008
+#define MUIIMR_IBPQ_MASK        0x0010
+#define MUIIMR_IBFQF_MASK       0x0020
+#define MUIIMR_IR_MASK          0x0040
+
+#define MUOISR_OBMSG_0_INT      0x0001
+#define MUOISR_OBMSG_1_INT      0x0002
+#define MUOISR_OBDB_INT         0x0004
+#define MUOISR_OBPQ_INT         0x0008
+#define MUOISR_PCI_INTA         0x0010
+#define MUOISR_PCI_INTB         0x0020
+#define MUOISR_PCI_INTC         0x0040
+#define MUOISR_PCI_INTD         0x0080
+
+#define MUOIMR_OBMSG_0_MASK     0x0001
+#define MUOIMR_OBMSG_1_MASK     0x0002
+#define MUOIMR_OBDB_MASK        0x0004
+#define MUOIMR_OBPQ_MASK        0x0008
+#define MUOIMR_PCI_MASKA        0x0010
+#define MUOIMR_PCI_MASKB        0x0020
+#define MUOIMR_PCI_MASKC        0x0040
+#define MUOIMR_PCI_MASKD        0x0080
+
+/* MU hardware registers */
+typedef struct _mu_regs
+{
+	volatile u32 IMR0;
+	volatile u32 IMR1;
+	volatile u32 OMR0;
+	volatile u32 OMR1;
+	volatile u32 IDR;
+	volatile u32 IISR;
+	volatile u32 IIMR;
+	volatile u32 ODR;
+	volatile u32 OISR;
+	volatile u32 OIMR;
+	u32 reserved_0[7];
+	volatile u32 MUCR;
+	volatile u32 QBAR;
+	u32 reserved_1[3];
+	volatile u32 IFHPR;
+	volatile u32 IFTPR;
+	volatile u32 IPHPR;
+	volatile u32 IPTPR;
+	volatile u32 OFHPR;
+	volatile u32 OFTPR;
+	volatile u32 OPHPR;
+	volatile u32 OPTPR;
+	volatile u32 IAR;
+} mu_regs_t;
+
+/** MU Message Registers **/
+
+
+/* MU Message Registers Descriptor */
+typedef struct _mu_msgreg
+{
+	atomic_t in_use;			/* usage flag */
+	atomic_t res_init;			/* resource usage flag */
+	struct list_head free_stack;	/* free descriptor stack */
+	struct list_head process_q;	/* process queue */
+	spinlock_t free_lock;		/* free stack spinlock */
+	spinlock_t process_lock;	/* process queue spinlock */
+	mu_msg_cb_t callback_0;		/* callback for inbound 0 */
+	mu_msg_cb_t callback_1;		/* callback for inbound 1 */
+	struct tq_struct msg_task;	/* message task */
+} mu_msg_t;
+
+/** MU Doorbell Registers **/
+
+/* MU Doorbell Registers descriptor */
+typedef struct _mu_dbreg
+{
+	atomic_t in_use;			/* usage flag */
+	mu_db_cb_t callback;		/* callback */
+	u32 reg_val;				/* register value */
+	spinlock_t reg_lock;		/* register value spinlock */
+	struct tq_struct db_task;	/* doorbell task */
+} mu_db_t;
+
+/** Circular Queues registers **/
+
+/* MU circular queues registers descriptor */
+typedef struct _mu_cqreg
+{
+	atomic_t in_use;			/* usage flag */
+	atomic_t init_ref;			/* Initialization reference count */
+	u32 q_size;					/* Size of the queues */
+	u32 num_entries;			/* Number of entries in Q */
+	spinlock_t ib_free_lock;	/* spinlock for Inbound free queue */
+	spinlock_t ib_post_lock;	/* spinlock for Inbound free queue */
+	spinlock_t ob_free_lock;	/* spinlock for Outbound free queue */
+	spinlock_t ob_post_lock;	/* spinlock for Outbound post queue */
+	mu_cq_cb_t callback;		/* Inbound callback function */
+	struct tq_struct cq_task;	/* circular queues task */
+	u32 inb_free_q_top;			/* Inbound free queue top */
+	u32 inb_free_q_end;			/* Inbound free queue bottom */
+	u32 inb_post_q_top;			/* Inbound post queue top */
+	u32 inb_post_q_end;			/* Inbound post queue bottom */
+	u32 outb_free_q_top;		/* Outbound free queue top */
+	u32 outb_free_q_end;		/* Outbound free queue bottom */
+	u32 outb_post_q_top;		/* Outbound post queue top */
+	u32 outb_post_q_end;		/* Outbound post queue bottom */
+} mu_cq_t;
+
+/* MU Index Registers */
+
+/* MU Index Registers Descriptor */
+typedef struct _mu_ir_reg
+{
+	atomic_t in_use;			/* Usage flag */
+	mu_ir_cb_t callback;		/* callback function */
+	u32 offset;					/* offset of address */
+	struct tq_struct ir_task;	/* Index Registers task */
+} mu_ir_t;
+
+
+/* MU device descriptor */
+typedef struct _mu_desc
+{
+	u32 irq;					/* interrupt number */
+	mu_regs_t *regs;			/* MU local mapped registers */
+	atomic_t irq_thresh;		/* irq threshold */
+	mu_msg_t msg_desc;			/* MU Msg Register */
+	mu_db_t db_desc;			/* MU Doorbell registers */
+	mu_cq_t cq_desc;			/* MU Circular Queues Registers */
+	mu_ir_t ir_desc;			/* MU INDEX Registers */
+} iop310_mu_t;
+
+
+#define MSG_ENTRY(list) list_entry((list), mu_msg_desc_t, link)
+
+extern void *mu_mem;
+
+#endif
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/mm-321.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/mm-321.c
--- linux-2.4.29/arch/arm/mach-iop3xx/mm-321.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/mm-321.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,66 @@
+/*
+ * linux/arch/arm/mach-iop3xx/mm.c
+ *
+ * Low level memory intialization for IOP321 based systems
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+ 
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+
+
+/*
+ * Standard IO mapping for all IOP321 based systems
+ */
+static struct map_desc iop80321_std_desc[] __initdata = {
+ /* virtual     physical      length      domain     r  w  c  b */ 
+
+ /* mem mapped registers */ 
+ { 0xfff00000,  0xffffe000,   0x00002000,  DOMAIN_IO, 0, 1, 0, 0},  
+
+ /* PCI IO space */
+ { 0xfe000000,  0x90000000,   0x00020000,  DOMAIN_IO, 0, 1, 0, 0}, 
+ LAST_DESC
+};
+
+void __init iop321_map_io(void)
+{
+	iotable_init(iop80321_std_desc);
+}
+
+/*
+ * IQ80321 specific IO mappings
+ *
+ * We use RedBoot's setup for the onboard devices.
+ */
+#ifdef CONFIG_ARCH_IQ80321
+static struct map_desc iq80321_io_desc[] __initdata = {
+ /* virtual     physical      length        domain     r  w  c  b */ 
+
+ /* on-board devices */
+ { 0xfe800000,  0xfe800000,   0x00100000,   DOMAIN_IO, 0, 1, 0, 0}, 
+ LAST_DESC
+};
+
+void __init iq80321_map_io(void)
+{
+	iop321_map_io();
+
+	iotable_init(iq80321_io_desc);
+}
+#endif // CONFIG_ARCH_IQ80321
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/mm.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/mm.c
--- linux-2.4.29/arch/arm/mach-iop3xx/mm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/mm.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,71 @@
+/*
+ * linux/arch/arm/mach-iop310/mm.c
+ *
+ * Low level memory intialization for IOP310 based systems
+ *
+ * Author: Nicolas Pitre <npitre@mvista.com>
+ *
+ * Copyright 2000-2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+ 
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+
+#ifdef CONFIG_IOP310_MU
+#include "message.h"
+#endif
+
+/*
+ * Standard IO mapping for all IOP310 based systems
+ */
+static struct map_desc iop80310_std_desc[] __initdata = {
+ /* virtual     physical      length      domain     r  w  c  b */ 
+ // IOP310 Memory Mapped Registers
+ { 0xe8001000,  0x00001000,   0x00001000,  DOMAIN_IO, 0, 1, 0, 0 },
+ // PCI I/O Space
+ { 0xfe000000,  0x90000000,   0x00020000,  DOMAIN_IO, 0, 1, 0, 0 },
+ LAST_DESC
+};
+
+void __init iop310_map_io(void)
+{
+#ifdef CONFIG_IOP310_MU
+	/* acquiring 1MB of memory aligned on 1MB boundary for MU */
+	mu_mem = __alloc_bootmem(0x100000, 0x100000, 0);
+#endif
+
+	iotable_init(iop80310_std_desc);
+}
+
+/*
+ * IQ80310 specific IO mappings
+ */
+#ifdef CONFIG_ARCH_IQ80310
+static struct map_desc iq80310_io_desc[] __initdata = {
+ /* virtual     physical      length        domain     r  w  c  b */ 
+ // IQ80310 On-Board Devices
+ { 0xfe800000,  0xfe800000,   0x00100000,   DOMAIN_IO, 0, 1, 0, 0 },
+ LAST_DESC
+};
+
+void __init iq80310_map_io(void)
+{
+	iop310_map_io();
+
+	iotable_init(iq80310_io_desc);
+}
+#endif // CONFIG_ARCH_IQ80310
+
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/pci-auto.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/pci-auto.c
--- linux-2.4.29/arch/arm/mach-iop3xx/pci-auto.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/pci-auto.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,380 @@
+/*
+ * arch/arm/mach-iop310/pci-auto.c
+ * 
+ * PCI autoconfiguration library
+ *
+ * Author: Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/arch/pci-bridge.h>
+#include <asm/arch/pci.h>
+#include <asm/arch/pci_auto.h>
+
+// #define DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif /* DEBUG */
+
+static int pciauto_upper_iospc;
+static int pciauto_upper_memspc;
+
+void pciauto_setup_bars(struct pci_controller *hose,
+		int current_bus,
+		int pci_devfn,
+		int bar_limit)
+{
+	int bar_response, bar_size, bar_value;
+	int bar, addr_mask, bar_nr = 0;
+	int * upper_limit;
+	int found_mem64 = 0;
+
+	DBG("PCI Autoconfig: Found Bus %d, Device %d, Function %d\n",
+		current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn) );
+
+	for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4)
+	{
+		/* Tickle the BAR and get the response */
+		early_write_config_dword(hose,
+				current_bus,
+				pci_devfn,
+				bar,
+				0xffffffff);
+		early_read_config_dword(hose,
+				current_bus,
+				pci_devfn,
+				bar,
+				&bar_response);
+
+		/* If BAR is not implemented go to the next BAR */
+		if (!bar_response)
+			continue;
+
+		/* Check the BAR type and set our address mask */
+		if (bar_response & PCI_BASE_ADDRESS_SPACE)
+		{
+			addr_mask = PCI_BASE_ADDRESS_IO_MASK;
+			upper_limit = &pciauto_upper_iospc;
+			DBG("PCI Autoconfig: BAR %d, I/O, ", bar_nr);
+		}
+		else
+		{
+			if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+			PCI_BASE_ADDRESS_MEM_TYPE_64)
+				found_mem64 = 1;
+
+			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;		
+			upper_limit = &pciauto_upper_memspc;
+			DBG("PCI Autoconfig: BAR %d, Mem, ", bar_nr);
+		}
+
+		/* Calculate requested size */
+		bar_size = ~(bar_response & addr_mask) + 1;
+
+		/* Allocate a base address */
+		bar_value = (*upper_limit - bar_size) & ~(bar_size - 1);
+
+		/* Write it out and update our limit */
+		early_write_config_dword(hose,
+				current_bus,
+				pci_devfn,
+				bar,
+				bar_value);
+
+		*upper_limit = bar_value;
+
+		/*
+		 * If we are a 64-bit decoder then increment to the
+		 * upper 32 bits of the bar and force it to locate
+		 * in the lower 4GB of memory.
+		 */ 
+		if (found_mem64)
+		{
+			bar += 4;
+			early_write_config_dword(hose,
+					current_bus,
+					pci_devfn,
+					bar,
+					0x00000000);
+		}
+
+		bar_nr++;
+
+		DBG("size=0x%x, address=0x%x\n",
+			bar_size, bar_value);
+	}
+
+}
+
+void pciauto_prescan_setup_bridge(struct pci_controller *hose,
+		int current_bus,
+		int pci_devfn,
+		int sub_bus,
+		int *iosave,
+		int *memsave)
+{
+	/* Configure bus number registers */
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_PRIMARY_BUS,
+			current_bus);
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_SECONDARY_BUS,
+			sub_bus + 1);
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_SUBORDINATE_BUS,
+			0xff);
+
+	/* Round memory allocator to 1MB boundary */
+	pciauto_upper_memspc &= ~(0x100000 - 1);
+	*memsave = pciauto_upper_memspc;
+
+	/* Round I/O allocator to 4KB boundary */
+	pciauto_upper_iospc &= ~(0x1000 - 1);
+	*iosave = pciauto_upper_iospc;
+
+	/* Set up memory and I/O filter limits, assume 32-bit I/O space */
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_MEMORY_LIMIT,
+			((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_LIMIT,
+			((pciauto_upper_iospc - 1) & 0x0000f000) >> 8);
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_LIMIT_UPPER16,
+			((pciauto_upper_iospc - 1) & 0xffff0000) >> 16);
+}
+
+void pciauto_postscan_setup_bridge(struct pci_controller *hose,
+		int current_bus,
+		int pci_devfn,
+		int sub_bus,
+		int *iosave,
+		int *memsave)
+{
+	int cmdstat;
+
+	/* Configure bus number registers */
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_SUBORDINATE_BUS,
+			sub_bus);
+
+	/*
+	 * Round memory allocator to 1MB boundary.
+	 * If no space used, allocate minimum.
+	 */
+	pciauto_upper_memspc &= ~(0x100000 - 1);
+	if (*memsave == pciauto_upper_memspc)
+		pciauto_upper_memspc -= 0x00100000;
+
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_MEMORY_BASE,
+			pciauto_upper_memspc >> 16);
+
+	/* Allocate 1MB for pre-fretch */
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_PREF_MEMORY_LIMIT,
+			((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
+
+	pciauto_upper_memspc -= 0x100000;
+
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_PREF_MEMORY_BASE,
+			pciauto_upper_memspc >> 16);
+
+	/* Round I/O allocator to 4KB boundary */
+	pciauto_upper_iospc &= ~(0x1000 - 1);
+	if (*iosave == pciauto_upper_iospc)
+		pciauto_upper_iospc -= 0x1000;
+
+	DBG("PCI Autoconfig: Bridge %d. IO_FILTER = %#010x..%#010x\n",
+			current_bus, 
+			(pciauto_upper_iospc & 0x0000f000) >> 8,
+			pciauto_upper_iospc >> 16);
+
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_BASE,
+			(pciauto_upper_iospc & 0x0000f000) >> 8);
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_BASE_UPPER16,
+			pciauto_upper_iospc >> 16);
+	
+	/* Enable memory and I/O accesses, enable bus master */
+	early_read_config_dword(hose,
+			current_bus,
+			pci_devfn,
+			PCI_COMMAND,
+			&cmdstat);
+	early_write_config_dword(hose,
+			current_bus,
+			pci_devfn,
+			PCI_COMMAND,
+			cmdstat |
+			PCI_COMMAND_IO |
+			PCI_COMMAND_MEMORY |
+			PCI_COMMAND_MASTER);
+}
+
+int pciauto_bus_scan(struct pci_controller *hose, int current_bus)
+{
+	int sub_bus, pci_devfn, pci_class, cmdstat, found_multi=0;
+	unsigned short vid;
+	unsigned char header_type;
+
+	/*
+	 * Fetch our I/O and memory space upper boundaries used
+	 * to allocated base addresses on this hose.
+	 */
+	if (current_bus == hose->first_busno)
+	{
+		pciauto_upper_iospc = hose->io_space.end + 1;
+		pciauto_upper_memspc = hose->mem_space.end + 1;
+	}
+
+	sub_bus = current_bus;
+
+	for (pci_devfn=0; pci_devfn<0xff; pci_devfn++)
+	{
+		/* Skip our host bridge */
+		if ( (current_bus == hose->first_busno) && (pci_devfn == 0) )
+			continue;
+
+		if (PCI_FUNC(pci_devfn) && !found_multi)
+			continue;
+
+		/* If config space read fails from this device, move on */
+		if (early_read_config_byte(hose,
+				current_bus,
+				pci_devfn,
+				PCI_HEADER_TYPE,
+				&header_type))
+			continue;
+
+		if (!PCI_FUNC(pci_devfn))
+			found_multi = header_type & 0x80;
+
+		early_read_config_word(hose,
+				current_bus,
+				pci_devfn,
+				PCI_VENDOR_ID,
+				&vid);
+
+		DBG("Vendor id %#06x\n", vid);
+
+		if (vid != 0xffff)
+		{
+			early_read_config_dword(hose,
+					current_bus,
+					pci_devfn,
+					PCI_CLASS_REVISION, &pci_class);
+			if ( (pci_class >> 16) == PCI_CLASS_BRIDGE_PCI )
+			{
+				int iosave, memsave;
+
+				DBG("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_SLOT(pci_devfn));
+				/* Allocate PCI I/O and/or memory space */
+				pciauto_setup_bars(hose,
+						current_bus,
+						pci_devfn,
+						PCI_BASE_ADDRESS_1);
+
+				pciauto_prescan_setup_bridge(hose,
+						current_bus,
+						pci_devfn,
+						sub_bus,
+						&iosave,
+						&memsave);
+				sub_bus = pciauto_bus_scan(hose, sub_bus+1);
+				pciauto_postscan_setup_bridge(hose,
+						current_bus,
+						pci_devfn,
+						sub_bus,
+						&iosave,
+						&memsave);
+			}
+			else
+			{
+				if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE)
+				{
+					unsigned char prg_iface;
+
+					early_read_config_byte(hose,
+							current_bus,
+							pci_devfn,
+							PCI_CLASS_PROG,
+							&prg_iface);
+					if (!(prg_iface & PCIAUTO_IDE_MODE_MASK))
+					{
+						DBG("PCI Autoconfig: Skipping legacy mode IDE controller\n");
+						continue;
+					}
+				}
+				/*
+				 * Found a peripheral, enable some standard
+				 * settings
+				 */
+				early_read_config_dword(hose,
+						current_bus,
+						pci_devfn,
+						PCI_COMMAND,
+						&cmdstat);
+				early_write_config_dword(hose,
+						current_bus,
+						pci_devfn,
+						PCI_COMMAND,
+						cmdstat |
+						PCI_COMMAND_IO |
+						PCI_COMMAND_MEMORY |
+						PCI_COMMAND_MASTER);
+				early_write_config_byte(hose,
+						current_bus,
+						pci_devfn,
+						PCI_LATENCY_TIMER,
+						0x80);
+
+				/* Allocate PCI I/O and/or memory space */
+				pciauto_setup_bars(hose,
+						current_bus,
+						pci_devfn,
+						PCI_BASE_ADDRESS_5);
+			}
+		}
+	}
+	return sub_bus;
+}
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/pci.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/pci.c
--- linux-2.4.29/arch/arm/mach-iop3xx/pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/pci.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,250 @@
+/*
+ * arch/arm/mach-iop310/pci.c
+ *
+ * Generic PCI support functionality that should eventually move to
+ * arch/arm/kernel/bios32.c.  Derived from support in ppc and alpha.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/pci-bridge.h>
+
+#define DEBUG 
+
+#ifdef DEBUG
+#define  DBG(x...) printk(x)
+#else
+#define  DBG(x...)
+#endif
+
+struct pci_controller* hose_head;
+struct pci_controller** hose_tail = &hose_head;
+
+/*
+ * The following code swizzles for exactly one bridge.  The routine
+ * common_swizzle below handles multiple bridges.  But there are a
+ * some boards that don't follow the PCI spec's suggestion so we
+ * break this piece out separately.
+ */
+static inline u8
+bridge_swizzle(u8 pin, u8 slot)
+{
+	return (((pin-1) + slot) % 4) + 1;
+}
+
+u8 __init
+common_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	struct pci_controller *hose;
+	
+	hose = pci_bus_to_hose(dev->bus->number);
+
+	if (dev->bus->number != hose->first_busno) {
+		u8 pin = *pinp;
+		do {
+			pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+			/* Move up the chain of bridges. */
+			dev = dev->bus->self;
+		} while (dev->bus->self);
+		*pinp = pin;
+
+		/* The slot is the slot of the last bridge. */
+	}
+
+	return PCI_SLOT(dev->devfn);
+}
+
+/*
+ * Null PCI config access functions, for the case when we can't
+ * find a hose.
+ */
+#define NULL_PCI_OP(rw, size, type)					\
+static int								\
+null_##rw##_config_##size(struct pci_dev *dev, int offset, type val)	\
+{									\
+	return PCIBIOS_DEVICE_NOT_FOUND;    				\
+}
+
+	NULL_PCI_OP(read, byte, u8 *)
+	NULL_PCI_OP(read, word, u16 *)
+	NULL_PCI_OP(read, dword, u32 *)
+	NULL_PCI_OP(write, byte, u8)
+	NULL_PCI_OP(write, word, u16)
+NULL_PCI_OP(write, dword, u32)
+
+static struct pci_ops null_pci_ops =
+{
+	null_read_config_byte,
+	null_read_config_word,
+	null_read_config_dword,
+	null_write_config_byte,
+	null_write_config_word,
+	null_write_config_dword
+};
+
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+struct pci_dev *
+fake_pci_dev(struct pci_controller *hose, int busnr, int devfn)
+{
+	static struct pci_dev dev;
+	static struct pci_bus bus;
+
+	if (hose == 0) {
+		hose = pci_bus_to_hose(busnr);
+		if (hose == 0)
+			printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);
+	}
+	dev.bus = &bus;
+	dev.sysdata = hose;
+	dev.devfn = devfn;
+	bus.number = busnr;
+	bus.ops = hose? hose->ops: &null_pci_ops;
+	return &dev;
+}
+
+static int next_controller_index;
+
+struct pci_controller * __init
+pcibios_alloc_controller(void)
+{
+	struct pci_controller *hose;
+
+	hose = (struct pci_controller *)kmalloc(sizeof(*hose), GFP_KERNEL);
+	memset(hose, 0, sizeof(struct pci_controller));
+	
+	*hose_tail = hose;
+	hose_tail = &hose->next;
+
+	hose->index = next_controller_index++;
+
+	return hose;
+}
+	
+struct pci_controller *
+pci_bus_to_hose(int bus)
+{
+	struct pci_controller *hose = hose_head;
+
+	for (; hose; hose = hose->next)
+		if (bus >= hose->first_busno && bus <= hose->last_busno)
+			return hose;
+	return NULL;
+}
+
+void __init
+pci_exclude_device(unsigned char bus, unsigned char devfn)
+{
+	struct pci_dev *dev, *pdev = NULL;
+
+	/* Walk the pci device list */
+	pci_for_each_dev(dev)
+	{
+		if ((dev->bus->number == bus) && (dev->devfn == devfn))
+		{
+			/*
+			 * Remove the device from the global and
+			 * bus lists.
+			 */
+			list_del(&(dev->global_list));
+			list_del(&(dev->bus_list));
+
+			/* Free the pci_dev structure */
+			kfree(dev);
+
+			break;
+		}
+		pdev = dev;
+	}
+}
+
+static inline void __init alloc_resource(struct pci_dev *dev, int idx)
+{
+	struct resource *pr, *r = &dev->resource[idx];
+
+	pr = pci_find_parent_resource(dev, r);
+	if(!pr || request_resource(pr, r) < 0)
+	{
+		printk(KERN_ERR "PCI: Can not allocate resource region %d" \
+				" of device %s\n", idx, dev->slot_name);
+		r->end -= r->start;
+		r->start = 0;
+	}
+}
+
+void __init
+pcibios_allocate_bus_resources(struct list_head *bus_list)
+{
+	struct list_head *ln;
+	struct pci_bus *bus;
+	int i;
+	struct resource *res, *pr;
+
+	if(!bus_list) return; 
+
+	/* Depth-First Search on bus tree */
+	for (ln = bus_list->next; ln != bus_list; ln=ln->next) {
+		bus = pci_bus_b(ln);
+		pci_read_bridge_bases(bus);
+		for (i = 0; i < 4; ++i) {
+			if ((res = bus->resource[i]) == NULL || !res->flags)
+				continue;
+			if (bus->parent == NULL)
+				pr = (res->flags & IORESOURCE_IO)?
+					&ioport_resource: &iomem_resource;
+			else
+				pr = pci_find_parent_resource(bus->self, res);
+
+			if (pr && request_resource(pr, res) == 0)
+				continue;
+			printk(KERN_ERR "PCI: Can not allocate resource region "
+			       "%d of PCI bridge %d\n", i, bus->number);
+			DBG("PCI: resource is %lx..%lx (%lx)\n",
+					res->start, res->end, res->flags);
+		}
+		pcibios_allocate_bus_resources(&bus->children);
+	}
+}
+
+void __init pcibios_allocate_resources(void)
+{
+	struct pci_dev *dev;
+	int idx, disabled;
+	u16 command;
+	struct resource *r;
+
+	pci_for_each_dev(dev)
+	{
+		pci_read_config_word(dev, PCI_COMMAND, &command);
+		for(idx = 0; idx < 6; idx++)
+		{
+			r = &dev->resource[idx];
+
+			if(r->parent)
+				continue;
+			if(!r->start)
+				continue;
+
+			alloc_resource(dev, idx);
+		}
+	}
+}
+
+
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/pmon.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/pmon.c
--- linux-2.4.29/arch/arm/mach-iop3xx/pmon.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/pmon.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,285 @@
+/*
+ * linux/arch/arm/mach-iop310/pmon.c
+ *
+ * Support functions for the Intel 80312 Performance Monitor Unit
+ * See Documentation/arm/XScale/IOP310/pmon.txt for API
+ *
+ * Author: Chen Chen (chen.chen@intel.com)
+ * Copyright (C) 2001 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * History:	07/23/2001 Chen Chen 
+ * 			Initial Creation   
+ *              07/27/2001 Chen Chen 
+ *              	Add interrupt routine 
+ *              09/28/2001 dsaxena
+ *             		API and code cleanup, merge into iop310 tree 
+ *
+ *************************************************************************/
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <asm/atomic.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/pmon.h>
+
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#include <linux/module.h>
+#endif
+
+#undef DEBUG
+#ifdef DEBUG
+#define DPRINTK(s, args...) printk("80310PMON: " s, ## args)
+#else
+#define DPRINTK(s, args...)
+#endif
+
+#define ENABLE_INTERRUPT 0x00000001
+#define ENABLE_COUNTERS  0xFFFFFFFB
+#define OVERFLOW         0xFFFFFFFF
+#define NUM_OF_PECR      14
+#define EMISR_SHIFT      1
+#define EMISR_MASK       0x00000001
+#define PMON_INT_MASK    0x00000010
+
+static atomic_t usage;
+static int claim_id;
+iop310_pmon_res_t pmon_results;
+
+
+/* static prototypes */
+static void pmon_irq_handler(int, void *, struct pt_regs *);
+
+/*=======================================================================*/
+/*  Procedure:  pmon_irq_handler()                                       */
+/*                                                                       */
+/*  Description:   This function is the interrupt handler for the intel  */
+/*                 80312 PMON.  When overflow occurs in PECR and GTSR     */
+/*                 registers, an interrupt is generated to the intel     */
+/*                 80200 chip.  This function handles the interrupt.     */
+/*                 It increments the overflow counts and records it into */
+/*                 the device data structure.                            */
+/*                                                                       */
+/*  Parameters:    int nIrq -- not used                                  */
+/*                 void * pDevId -- not used                             */
+/*                 pt_regs * pRegs -- not used                           */
+/*                                                                       */
+/*  Returns:       void                                                  */
+/*                                                                       */
+/*  Notes/Assumptions: none                                              */
+/*                                                                       */
+/*  History:	Chen Chen 07/27/2001 					 */
+/*  			Initial Creation                 		 */
+/*		dsaxena   09/28/2001					 */
+/*			Removed looping and checking on FIQISR1		 */
+/*=======================================================================*/
+static void pmon_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u32 em_isr_status = 0;
+	u32 i = 0;
+
+	DPRINTK("enter pmon_irq_handler()\n");
+
+	/* get EMISR status */
+	em_isr_status = *(IOP310_PMONEMISR);
+
+	/* clear interrupts by writing back to it */
+	/* since this is a read-clear register */
+	*(IOP310_PMONEMISR) |= em_isr_status;
+
+	/* if global timer overflows, increment the counter */
+	if(em_isr_status & EMISR_MASK)
+	{
+		pmon_results.timestamp_overflow++;
+	}
+
+	/* shift register value to look at the next bit */
+	em_isr_status = em_isr_status >> 1;
+
+	/*loop to look at each PECR to see if overflow occurred */
+	for(i = 0; i < NUM_OF_PECR; i++)
+	{
+		/* if overflow occurred, increment the counter */
+		if(em_isr_status & EMISR_MASK)
+		{
+			pmon_results.event_overflow[i]++;
+		}
+		/* shift register value to look at the next bit */
+		em_isr_status = em_isr_status >> 1;
+	}
+
+	DPRINTK("exit pmon_irq_handler()\n");
+}
+
+/*=======================================================================*/
+/*  Procedure:  iop310_pmon_claim()                                      */
+/*                                                                       */
+/*  Description:   This function allows the user to claim the usage of   */
+/*                 PMON.  The function returns an identifier.  When the  */
+/*                 user is done using the PMON, the user has to          */
+/*                 call iop310_pmon_release with this identifier to      */
+/*                 release the PMON.                                     */
+/*                                                                       */
+/*  Parameters:    None                                                  */
+/*                                                                       */
+/*  Returns:       success: Int -- identifier being returned to the user */
+/*                 failure: -EBUSY                                       */
+/*                                                                       */
+/*  History:       Chen Chen 07/23/2001 Initial Creation                 */
+/*=======================================================================*/
+int iop310_pmon_claim(void)
+{
+	int err;
+
+	DPRINTK("enter pmon_claim()\n");
+
+	/* if unable to read the usage variable, return with busy */
+	if(atomic_read(&usage))
+	{
+		return -EBUSY;
+	}
+
+	/* increment the usage variable */
+	atomic_inc(&usage);
+
+	/* register the interrupt handler */
+	err = request_irq(IRQ_IOP310_PMON, pmon_irq_handler,
+				  SA_INTERRUPT, "IOP310 PMON", &pmon_results);
+
+	/* return if unable to register the interrupt handler */
+	if(err < 0)
+	{
+		DPRINTK(KERN_ERR "unable to request IRQ for PMON: %d\n", err);
+		return err;
+	}
+
+	memzero(&pmon_results, sizeof(pmon_results));
+
+	DPRINTK("exit pmon_claim()\n");
+
+	return ++claim_id;
+}
+
+/*=======================================================================*/
+/*  Procedure:  pmon_release()                                           */
+/*                                                                       */
+/*  Description:   When this function is called, it will release the PMON.*/
+/*                 When the user is done with the PMON, the user need to  */
+/*                 call this function with the identifier they got from  */
+/*                 calling the i80312PmuClaim() to release the PMON.      */
+/*                                                                       */
+/*  Parameters:    u32 nClaimId                                          */
+/*                 The identifier user got when calling i80312PmuClaim() */
+/*                                                                       */
+/*  Returns:       success:  0                                          */
+/*                 failure: -EPERM                                       */
+/*                                                                       */
+/*  Notes/Assumptions: The user will release the PMON when done monitoring*/
+/*                                                                       */
+/*  History:       Chen Chen 07/23/2001 Initial Creation                 */
+/*=======================================================================*/
+int iop310_pmon_release(int claim)
+{
+	DPRINTK("enter pmon_release()\n");
+
+	/* if the passed in id number doesn't match local id number, */
+	/* return with wrong parameter */
+	if(claim != claim_id)
+	{
+		return -EPERM;
+	}
+
+	atomic_dec(&usage);
+
+	/* un-register the interrupt handler */
+	free_irq(IRQ_IOP310_PMON, NULL);
+
+	DPRINTK("exit pmon_release()\n");
+
+	return 0;
+}
+
+/*=======================================================================*/
+/*  Procedure:  iop310_pmon_start()                                      */
+/*                                                                       */
+/*  Description:   Each mode allows the user to monitor a set of events. */
+/*                 The user need to call this function with a mode to    */
+/*                 start the PMON monitoring process.  There are eight   */
+/*                 monitored mode specified in the Event Select Register.*/
+/*                                                                       */
+/*  Parameters:    u32 nClaimID                                          */
+/*                 The identifier user got when calling i80312PmuClaim() */
+/*                 u32 nMode			                         */
+/*                 The mode user would like to monitor in                */
+/*                                                                       */
+/*  Returns:       success:  0                                           */
+/*                 failure:  -EPERM                                      */
+/*                                                                       */
+/*  Notes/Assumptions: None                                              */
+/*                                                                       */
+/*  History:       Chen Chen 07/23/2001 Initial Creation                 */
+/*                 Dave Jiang 08/27/01  Combied Int enable & counter     */
+/*=======================================================================*/
+int iop310_pmon_start(int claim, int mode)
+{
+	DPRINTK("enter pmon_start()\n");
+
+	if(claim != claim_id)
+	{
+		return -EPERM;
+	}
+
+	/* enable interrupt bit in Global Timer Mode Register */
+	/* enable all counters in Global Timer Mode Register */
+	*IOP310_PMONGTMR |= (ENABLE_INTERRUPT | ENABLE_COUNTERS);
+
+	/* set the Event Select Register to the appropriate mode */
+	/* (writing to ESR, also cause GTSR to reset to 0) */
+	*IOP310_PMONESR |= mode;
+
+	DPRINTK("exit pmon_start()\n");
+
+	return 0;
+}
+
+/*=======================================================================*/
+/*  Procedure:  pmon_stop()                                              */
+/*                                                                       */
+/*  Description:   When this function is called, the PMON will stop       */
+/*                 monitoring the events.  It will read all registers,   */
+/*                 and record them into pPmuResult.                      */
+/*                                                                       */
+/*  Parameters:    struct i80312PmuResults pPmuResult                    */
+/*                 the place to write the result back to                 */
+/*                                                                       */
+/*  Returns:       success:  0                                          */
+/*                                                                       */
+/*  Notes/Assumptions: None                                              */
+/*                                                                       */
+/*  History:       Chen Chen 07/23/2001 Initial Creation                 */
+/*=======================================================================*/
+int iop310_pmon_stop(iop310_pmon_res_t *pmon_result)
+{
+	DPRINTK("enter pmon_stop()\n");
+
+	memcpy(pmon_result, &pmon_results, sizeof(iop310_pmon_res_t));
+
+	/* reset the monitoring mode back to 0 -- disable monitor */
+	*IOP310_PMONESR = IOP310_PMON_MODE0;
+
+	DPRINTK("exit pmon_stop()\n");
+
+	return 0;
+}
+
+EXPORT_SYMBOL_NOVERS(iop310_pmon_claim);
+EXPORT_SYMBOL_NOVERS(iop310_pmon_release);
+EXPORT_SYMBOL_NOVERS(iop310_pmon_start);
+EXPORT_SYMBOL_NOVERS(iop310_pmon_stop);
+
diff -urN linux-2.4.29/arch/arm/mach-iop3xx/xs80200-irq.c linux-2.4.29-uc1/arch/arm/mach-iop3xx/xs80200-irq.c
--- linux-2.4.29/arch/arm/mach-iop3xx/xs80200-irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-iop3xx/xs80200-irq.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,69 @@
+/*
+ * linux/arch/arm/mach-iop310/xs80200-irq.c
+ *
+ * Generic IRQ handling for the XS80200 XScale core.
+ * 
+ * Author:  Nicolas Pitre
+ * Copyright:   (C) 2001 MontaVista Software Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+
+#include <asm/mach-types.h>
+
+void
+xs80200_irq_mask (unsigned int irq)
+{
+	long INTCTL;
+	asm ("mrc p13, 0, %0, c0, c0, 0" : "=r" (INTCTL));
+	switch (irq) {
+	    case IRQ_XS80200_BCU:     INTCTL &= ~(1<<3); break;
+	    case IRQ_XS80200_PMU:     INTCTL &= ~(1<<2); break;
+	    case IRQ_XS80200_EXTIRQ:  INTCTL &= ~(1<<1); break;
+	    case IRQ_XS80200_EXTFIQ:  INTCTL &= ~(1<<0); break;
+	}
+	asm ("mcr p13, 0, %0, c0, c0, 0" : : "r" (INTCTL));
+}
+
+void
+xs80200_irq_unmask (unsigned int irq)
+{
+	long INTCTL;
+	asm ("mrc p13, 0, %0, c0, c0, 0" : "=r" (INTCTL));
+	switch (irq) {
+	    case IRQ_XS80200_BCU:	INTCTL |= (1<<3); break;
+	    case IRQ_XS80200_PMU:	INTCTL |= (1<<2); break;
+	    case IRQ_XS80200_EXTIRQ:	INTCTL |= (1<<1); break;
+	    case IRQ_XS80200_EXTFIQ:	INTCTL |= (1<<0); break;
+	}
+	asm ("mcr p13, 0, %0, c0, c0, 0" : : "r" (INTCTL));
+}
+
+void __init xs80200_init_irq(void)
+{
+	int i;
+	long intstr;
+
+	for (i = 0; i < NR_XS80200_IRQS; i++) {
+		irq_desc[i].valid	= 1;
+		irq_desc[i].probe_ok	= 1;
+		irq_desc[i].mask_ack	= xs80200_irq_mask;
+		irq_desc[i].mask	= xs80200_irq_mask;
+		irq_desc[i].unmask	= xs80200_irq_unmask;
+	}
+
+	asm ("mcr p13, 0, %0, c0, c0, 0" : : "r" (0));
+}
+
+
diff -urN linux-2.4.29/arch/arm/mach-ixp1200/arch.c linux-2.4.29-uc1/arch/arm/mach-ixp1200/arch.c
--- linux-2.4.29/arch/arm/mach-ixp1200/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp1200/arch.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/mach-ixp1200/arch.c
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+extern void ixp1200_init_irq(void);
+extern void ixp1200_map_io(void);
+
+static void __init 
+fixup_ixp1200(struct machine_desc *dex, struct param_struct *params,
+		char **cmdline, struct meminfo *mi)
+{
+
+#ifdef defined(CONFIG_BLK_DEV_INITRD)
+	setup_ramdisk(1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE );
+	setup_initrd(phys_to_virt(INITRD_LOCATION), INITRD_SIZE);
+#endif
+
+	mi->nr_banks = 1;
+	mi->bank[0].node = 0;
+	mi->bank[0].start = CONFIG_IXP1200_SDRAM_BASE;
+	mi->bank[0].size = CONFIG_IXP1200_SDRAM_SIZE * 0x100000;
+}
+
+MACHINE_START(IXP1200, "Intel IXP1200-based platform")
+	MAINTAINER("MontaVista Software, Inc.")
+	BOOT_MEM(CONFIG_IXP1200_SDRAM_BASE, 0x90000000, 0xf0000000)
+	FIXUP(fixup_ixp1200)
+	MAPIO(ixp1200_map_io)
+	INITIRQ(ixp1200_init_irq)
+MACHINE_END
+
diff -urN linux-2.4.29/arch/arm/mach-ixp1200/irq.c linux-2.4.29-uc1/arch/arm/mach-ixp1200/irq.c
--- linux-2.4.29/arch/arm/mach-ixp1200/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp1200/irq.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,150 @@
+/*
+ * linux/arch/arm/mach-ixp1200/irq.c
+ *
+ * Generic IRQ handling for IXP1200 based systems. 
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (C) 1996-1998 Russell King
+ * Copyright (C) 2001 MontaVista Software, Inc
+ *
+ * Changelog:
+ *  16-Mar-2000 Uday N  Modified for IXP 1200 Eval Board
+ *  26-Sep-2001 dsaxena Move to 2.4.x kernel & cleanup
+ *  01-Mar-2002 dsaxena	More cleanup, added support for all IRQ sources
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+
+/*
+ * IXP1200 Interrupt registers 
+ */
+static volatile unsigned long* irq_reg[] = 
+	{	 
+		CSR_IREG,	/* uEngine	*/
+		CSR_IREG,	/* FBI (CINT)	*/
+		CSR_SRAM,	/* SRAM		*/
+		NULL,		/* UART		*/
+		CSR_RTC_DIV,	/* RTC		*/
+		CSR_SDRAM,	/* SDRAM	*/
+		CSR_IRQ_STATUS, /* SWI		*/
+		CSR_IRQ_STATUS,	/* TIMER1	*/
+		CSR_IRQ_STATUS,	/* TIMER2	*/
+		CSR_IRQ_STATUS,	/* TIMER3	*/
+		CSR_IRQ_STATUS,	/* TIMER4	*/
+		CSR_IRQ_STATUS, /* DOORBELL	*/
+		CSR_IRQ_STATUS,	/* DMA1		*/
+		CSR_IRQ_STATUS,	/* DMA2		*/
+		CSR_IRQ_STATUS,	/* PCI		*/
+		CSR_IRQ_STATUS, /* DMA1NB	*/
+		CSR_IRQ_STATUS,	/* DMA2NB	*/
+		CSR_IRQ_STATUS,	/* BIST		*/
+		CSR_IRQ_STATUS, /* I2O		*/
+		CSR_IRQ_STATUS, /* PWRM		*/
+		CSR_IRQ_STATUS	/* PCI Error	*/
+	};
+
+static unsigned long irq_mask[] = 
+	{
+
+		(1 << 30),     /* microengine interrupts */
+		(1 << 28),     /* FBI (CINT)  */
+		(1 << 3),      /* SRAM        */
+		0,             /* UART        */
+		(1 << 19),	/* RTC */
+		0,             /* Bug in documentation - ???  */
+		IRQ_MASK_SWI,
+		IRQ_MASK_TIMER1,
+		IRQ_MASK_TIMER2,
+		IRQ_MASK_TIMER3,
+		IRQ_MASK_TIMER4,
+		IRQ_MASK_DOORBELL,
+		IRQ_MASK_DMA1,
+		IRQ_MASK_DMA2,
+		IRQ_MASK_PCI,
+		IRQ_MASK_DMA1NB,
+		IRQ_MASK_DMA2NB,
+		IRQ_MASK_BIST,
+		IRQ_MASK_I2O,
+		IRQ_MASK_PWRM,
+		IRQ_MASK_PCI_ERR
+	};
+
+
+static void 
+ixp1200_mask_irq(unsigned int irq)
+{ 
+	volatile unsigned long* irqreg  = irq_reg[irq];
+	unsigned long irqmask = irq_mask[irq];
+
+	/* 
+	 * For certain devices, we let the drivers handle it as there
+	 * is no "mask" bit
+	 */
+	if (irqreg == 0) return;
+
+	if (irqreg == CSR_IRQ_STATUS)
+	{
+		/* 
+		 * For these interrupts we just set the appropriate bit in the
+		 * clear register.  The write has no effect on the bits not set
+		 */
+		  
+		*CSR_IRQ_DISABLE = irqmask;
+	}
+	else
+	{
+		/* 
+		 * Just set those bits to 0 NOTE:: For UENG and CINT,
+		 * the first 26 bits are write 1 to clear. So we dont want to
+		 * clear those.  
+		 */
+		if ( irqreg == CSR_IREG)
+			*irqreg &= (~irqmask & 0xf8000000);
+		else
+			*irqreg &= ~irqmask;
+	}
+
+}
+
+static void 
+ixp1200_unmask_irq(unsigned int irq)
+{
+	volatile unsigned long* irqreg  = irq_reg[irq];
+	unsigned long irqmask = irq_mask[irq];
+
+	if (irqreg == 0) return;
+
+
+	if (irqreg == CSR_IRQ_STATUS)
+		*CSR_IRQ_ENABLE = irqmask; 
+	else
+		*irqreg |= irqmask;
+}
+
+__init void 
+ixp1200_init_irq(void)
+{
+	int irq;
+
+	*CSR_IRQ_DISABLE = -1;
+	*CSR_FIQ_DISABLE = -1;
+ 
+	for (irq = 0; irq < NR_IRQS; irq++) 
+	{
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= ixp1200_mask_irq;
+		irq_desc[irq].mask	= ixp1200_mask_irq;
+		irq_desc[irq].unmask	= ixp1200_unmask_irq;
+	}
+}
+
diff -urN linux-2.4.29/arch/arm/mach-ixp1200/ixp-pci.c linux-2.4.29-uc1/arch/arm/mach-ixp1200/ixp-pci.c
--- linux-2.4.29/arch/arm/mach-ixp1200/ixp-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp1200/ixp-pci.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,467 @@
+/*
+ * arch/arm/mach-ixp1200/ixp1200-pci.c: 
+ *
+ * Generic PCI support for IXP1200 based systems
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ * Copyright (C) 1998-2000 Russell King, Phil Blundell
+ *
+ * May-27-2000: Uday Naik
+ * 	Initial port to IXP1200 based on dec21285 code.
+ *
+ * Sep-25-2001: dsaxena
+ * 	Port to 2.4.x kernel/massive rewrite
+ *
+ * TODO: Get rid of pci-auto
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+
+#include <asm/byteorder.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/pci.h>
+#include <asm/arch/pci-auto.h>
+#include <asm/arch/pci-bridge.h>
+
+#define MAX_SLOTS		14
+
+static unsigned long
+ixp1200_base_address(struct pci_dev *dev, int where)
+{
+	unsigned long addr = 0;
+	unsigned int devfn = dev->devfn;
+
+	if(dev->bus->number == 0)
+	{
+		if(PCI_SLOT(devfn) == 0) {
+			addr = PCI_CSR_BASE +  (where & ~0x3);
+		}
+		else if (devfn < PCI_DEVFN(MAX_SLOTS, 0))
+
+			addr = PCICFG0_BASE | (1 << PCI_SLOT(devfn) + 10) |
+				(PCI_FUNC(devfn) << 8) | (where & 0xFF);
+	}
+	else
+	{
+		addr = PCICFG1_BASE | (dev->bus->number << 16) | (devfn <<8) | where;
+	}
+
+	return addr;
+}
+
+static int
+ixp1200_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	unsigned long addr = ixp1200_base_address(dev, where);
+
+	if(!addr)
+		*value = 0xff;
+	else if((addr & PCI_CSR_BASE) != PCI_CSR_BASE)
+        	*value = *(u8 *)addr;
+	else {
+		u32 *local_addr = (u32*)addr;
+		*value = (u8)(((*local_addr) >> ((where % 0x04) * 8)) & 0xff);
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+
+}
+
+static int
+ixp1200_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	unsigned long addr = ixp1200_base_address(dev, where);
+
+	if(!addr)
+		*value = 0xffff;
+	else if((addr & PCI_CSR_BASE) != PCI_CSR_BASE)
+		*value = __le16_to_cpu((*(u16 *)addr));
+	else 
+	{
+		u32 *local_addr = (u32*)addr;
+		*value = (u16)(((*local_addr) >> ((where % 0x04) * 8)) & 0xffff);
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+
+}
+
+static int
+ixp1200_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	unsigned long addr = ixp1200_base_address(dev, where);
+
+	if(!addr)
+		*value = 0xffffffff;
+	else if((addr & PCI_CSR_BASE) != PCI_CSR_BASE)
+		*value = __le32_to_cpu((*(u32 *)addr));
+	else
+		*value = *((u32 *)addr);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+ixp1200_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	unsigned long addr = ixp1200_base_address(dev, where);
+
+	if((addr & PCI_CSR_BASE) != PCI_CSR_BASE) {
+		*(u8*)addr = value;
+	} else {
+		u32 mask = ~(0xff << ((where % 0x4) * 8));
+		u32 temp = value << ((where % 0x4) * 8);
+		u32 *local_addr = (u32*)addr;
+
+		*local_addr = (*(local_addr) & mask) | temp;
+	}	
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+ixp1200_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	unsigned long addr = ixp1200_base_address(dev, where);
+
+	if((addr & PCI_CSR_BASE) != PCI_CSR_BASE) {
+        	*(u16 *)addr= __cpu_to_le16(value);
+	} else {
+		u32 mask = ~(0xffff << ((where % 0x4) * 8));
+		u32 temp = (u32)(((u32)value) << ((where % 0x4) * 8));
+		u32 *local_addr = (u32*)addr;
+
+		*local_addr = (*local_addr & mask) | temp;
+	}	
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+ixp1200_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	unsigned long addr = ixp1200_base_address(dev, where);
+
+	if((addr & PCI_CSR_BASE) != PCI_CSR_BASE)
+        	*(u32 *)addr = __cpu_to_le32(value);
+	else
+        	*(u32 *)addr = value;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops ixp1200_ops = {
+	ixp1200_read_config_byte,
+	ixp1200_read_config_word,
+	ixp1200_read_config_dword,
+	ixp1200_write_config_byte,
+	ixp1200_write_config_word,
+	ixp1200_write_config_dword,
+};
+
+void __init ixp1200_setup_resources(struct resource **resource)
+{
+	struct resource *busmem, *busmempf;
+
+	busmem = kmalloc(sizeof(*busmem), GFP_KERNEL);
+	busmempf = kmalloc(sizeof(*busmempf), GFP_KERNEL);
+	memset(busmem, 0, sizeof(*busmem));
+	memset(busmempf, 0, sizeof(*busmempf));
+
+	busmem->flags = IORESOURCE_MEM;
+	busmem->name  = "PCI non-prefetch";
+
+	allocate_resource(&iomem_resource, busmem, 0x20000000,
+			  0x60000000, 0xffffffff, 0x20000000, NULL, NULL);
+
+	resource[0] = &ioport_resource;
+	resource[1] = busmem;
+}
+
+static struct pci_controller *hose = NULL;
+
+static int ixp_host = 0;
+
+static void report_pci_dev_error(void)
+{
+	struct pci_dev *dev;
+
+	pci_for_each_dev(dev) 
+	{
+		unsigned short status;
+
+		pci_read_config_word(dev, PCI_STATUS, &status);
+
+		if(status & 0xf900)
+		{
+			printk(KERN_ERR "    Bus %d:DevFn %04x Status = %x\n",
+					dev->bus->number, dev->devfn,
+					status & 0xf900);
+		}
+	}
+}
+
+static void pci_err_irq(int irqno, void *notused, struct pt_regs *regs)
+{
+	static unsigned long next_warn = 0;
+
+	unsigned long cmd = *CSR_PCICMD & 0x0000ffff;
+	unsigned long ctrl = *CSR_SA_CONTROL & 0xffffdeff;
+	unsigned long irqstatus = *CSR_IRQ_RAWSTATUS;
+
+	int warn = time_after_eq(jiffies, next_warn);
+	if(warn)
+	{
+		next_warn = jiffies + 3 * HZ;
+	}
+
+	if(irqstatus & IRQ_MASK_DPE)
+	{
+		if(warn)
+			printk(KERN_ERR "IXP1200 PCI: Detected Parity Error\n");
+		cmd |= PCI_STATUS_DETECTED_PARITY << 16;
+	}
+
+	if(irqstatus & IRQ_MASK_RTA)
+	{
+		if(warn)
+			printk(KERN_ERR "IXP1200 PCI: Received Target Abort\n");
+		cmd |= PCI_STATUS_REC_TARGET_ABORT << 16;
+	}
+
+	if(irqstatus & IRQ_MASK_RMA)
+	{
+		if(warn)
+			printk(KERN_ERR "IXP1200 PCI: Received Master Abort\n");
+		cmd |= PCI_STATUS_REC_MASTER_ABORT << 16;
+	}
+
+	if(irqstatus & IRQ_MASK_DPED)
+	{	
+		if(warn)
+			printk(KERN_ERR "IXP1200 PCI: Data Parity Error\n");
+		cmd |= PCI_STATUS_PARITY << 16;
+	}
+
+	if(irqstatus & IRQ_MASK_DTE)
+	{
+		if(warn)
+			printk(KERN_ERR "IXP1200 PCI: Discard timer Expired\n");
+		ctrl &= ~SA_CNTL_DISCARDTIMER;
+	}
+
+	if(irqstatus & IRQ_MASK_RSERR)
+	{
+		printk(KERN_ERR "IXP1200 PCI: Received System Error\n");
+		warn = 1;
+	}
+
+	/*
+	 * Only dump PCI error status if we are the host
+	 */
+	if(warn && ixp_host) report_pci_dev_error(); 
+
+	*CSR_PCICMD = cmd;
+	cmd = *CSR_PCICMD;
+
+	*CSR_SA_CONTROL = ctrl;
+	ctrl = *CSR_SA_CONTROL;
+}
+
+void __init ixp1200_pci_init(struct arm_pci_sysdata *sysdata)
+{
+	u32 dummy_read;
+	unsigned int pci_cmd = 	PCI_COMMAND_IO |
+				PCI_COMMAND_MEMORY |
+				PCI_COMMAND_MASTER |
+				PCI_COMMAND_INVALIDATE;
+		
+        unsigned int big_endian_cntl   = SA_CNTL_BE_BEO |
+					 SA_CNTL_BE_DEO |
+					 SA_CNTL_BE_BEI |
+                                         SA_CNTL_BE_DEI;
+	*CSR_PCIOUTBINTMASK = 0xc;
+	dummy_read = *CSR_SA_CONTROL;
+
+	/*
+	 * Disable doorbell int to PCI in doorbell mask register
+	 */
+	*CSR_DOORBELL_PCI = 0; 
+	dummy_read = *CSR_SA_CONTROL;
+
+	/*
+	 * Disable doorbell int to SA-110 in Doorbell SA-110 mask register
+	 */
+        *CSR_DOORBELL_SA = 0x0;
+	dummy_read = *CSR_SA_CONTROL;
+
+	/* 
+	 * Set PCI Address externsion reg to known state
+	 * 
+	 * We setup a 1:1 map of bus<->physical addresses
+	 */
+        *CSR_PCIADDR_EXTN = 0x54006000; 
+	dummy_read = *CSR_SA_CONTROL;
+
+#ifdef __ARMEB__
+	*CSR_SA_CONTROL |= big_endian_cntl; /* set swap bits for big endian*/
+	dummy_read = *CSR_SA_CONTROL;
+#endif
+
+	/*
+	 * We just map in the maximum SDRAM (256MB) into PCI space at 
+	 * location 0x00000000.  Even if the board has less RAM or if
+	 * Linux is only using part of it, this shouldn't be an issue
+	 * as long as drivers are well behaved.
+	 */
+	*CSR_SDRAMBASEMASK = (256 << 20) - 0x40000;
+	dummy_read = *CSR_SA_CONTROL;
+
+ 	*CSR_CSRBASEMASK = 0x000c0000; /*1 Mbyte*/
+	dummy_read = *CSR_SA_CONTROL;
+
+	/* Clear PCI command register*/
+        *CSR_PCICMD &= 0xffff0000; 
+	dummy_read = *CSR_SA_CONTROL;
+
+        *CSR_SA_CONTROL |= IXP1200_SA_CONTROL_PNR; /*Negate PCI reset*/
+	dummy_read = *CSR_SA_CONTROL;
+
+	udelay(1000);
+
+	/*
+	 * Host means whether or not the IXP should go out and
+	 * scan the bus. On the IXP12EB, this is determined through
+	 * looking at the PCF register.  On certain boards, the PCF
+	 * pin is not properly wired, so we can't determine whether
+	 * we are the controller or not.  In that case, we can use
+	 * the "ixphost" parameter to force the bus scan.
+	 */
+	if(!ixp_host)
+        	ixp_host = IXP1200_SA_CONTROL_PCF & *CSR_SA_CONTROL;
+
+        if(ixp_host)
+        {
+		printk("PCI: IXP1200 is system controller\n");
+		*CSR_PCICSRBASE = 0x40000000;
+		dummy_read = *CSR_SA_CONTROL;
+
+		*CSR_PCICSRIOBASE = 0x0000f000;
+		dummy_read = *CSR_SA_CONTROL; 
+
+		/*
+		 * SDRAM mapped at PCI addr 0
+		 */
+		*CSR_PCISDRAMBASE = 0; 
+		dummy_read = *CSR_SA_CONTROL;
+
+		*CSR_PCICMD = (*CSR_PCICMD & 0xFFFF0000)| pci_cmd;
+		dummy_read = *CSR_SA_CONTROL;
+
+        	*CSR_SA_CONTROL |= 0x00000001;
+		dummy_read = *CSR_SA_CONTROL;
+
+		*CSR_PCICACHELINESIZE = 0x00002008;
+		dummy_read = *CSR_SA_CONTROL;
+
+		hose = pcibios_alloc_controller();
+		if(!hose) panic("Could not allocate PCI hose!");
+
+		hose->first_busno = 0;
+		hose->last_busno = 0;
+		hose->io_space.start = 0x54000000;
+		hose->io_space.end = 0x5400ffff;
+		hose->mem_space.start = 0x60000000;
+		hose->mem_space.end = 0x7fffffff;
+
+		/* Re-Enumarate the bus since we don't trust cygmon */
+		hose->last_busno = pciauto_bus_scan(hose, 0);
+
+		/* Scan the bus */
+		pci_scan_bus(0, &ixp1200_ops, sysdata);
+	}
+	else 
+	{
+		/*
+		 * In agent mode we don't have to do anything.
+		 * We setup the window sizes above and it's up to
+		 * the host to properly configure us.
+		 */
+		printk("PCI: IXP1200 is agent\n");
+	}
+
+	/*
+	 * Request error IRQs so that we can report them to user
+	 */
+	request_irq(IXP1200_IRQ_PCI_ERR, pci_err_irq, 0, "PCI Error", NULL);
+}
+
+
+#define EARLY_PCI_OP(rw, size, type)					\
+int early_##rw##_config_##size(struct pci_controller *hose, int bus,	\
+		int devfn, int offset, type value)	\
+{									\
+	return ixp1200_##rw##_config_##size(fake_pci_dev(hose, bus, devfn),	\
+			offset, value);			\
+}
+
+static u8 __init ixp1200_swizzle(struct pci_dev *dev, u8 *pin)
+{
+	return PCI_SLOT(dev->devfn);
+}
+
+static int __init ixp1200_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if (dev->vendor == PCI_VENDOR_ID_INTEL &&
+		dev->device == PCI_DEVICE_ID_INTEL_IXP1200)
+		return 0;
+
+	return IXP1200_IRQ_PCI;
+}
+
+struct hw_pci ixp1200_pci __initdata = {
+	init: ixp1200_pci_init,
+	setup_resources: ixp1200_setup_resources,
+	swizzle: ixp1200_swizzle,
+	map_irq: ixp1200_map_irq,
+};
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
+
+static int __init ixphost_setup(char *__unused)
+{
+	ixp_host = 1;
+	return 0;
+}
+
+static int __init ixpagent_setup(char *__unused)
+{
+	ixp_host = 0;
+	return 0;
+}
+
+__setup("ixphost", ixphost_setup);
+__setup("ixpagent", ixpagent_setup);
+
diff -urN linux-2.4.29/arch/arm/mach-ixp1200/Makefile linux-2.4.29-uc1/arch/arm/mach-ixp1200/Makefile
--- linux-2.4.29/arch/arm/mach-ixp1200/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp1200/Makefile	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= ixp1200.o
+
+# Object file lists.
+
+obj-y			:= arch.o mm.o ixp-pci.o irq.o pci.o pci-auto.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= 
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/arm/mach-ixp1200/mm.c linux-2.4.29-uc1/arch/arm/mach-ixp1200/mm.c
--- linux-2.4.29/arch/arm/mach-ixp1200/mm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp1200/mm.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,103 @@
+/*
+ * arch/arm/mm/mm-ixp1200.c
+ *
+ * Low level memory initialization for IXP1200 based systems
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (C) 2000 Intel Corporation, Inc.
+ * Copyright (C) 2001-2002 MontaVista Software, Inc.
+ *
+ * Mar-27-2000 - Uday Naik
+ * 	Created for IXP1200 Eval board 
+ * Nov-11-2001 - Deepak Saxena
+ *      Massive cleanup, deleted SDRAM_PACKET mapping as we use all 
+ *      of SDRAM for the kernel by default.  If you want to reserve
+ *      a large chunk of SDRAM for the packet engines, run make
+ *      config and change the CONFIG_IXP1200_SDRAM_BASE and 
+ *      CONFIG_IXP1200_SDRAM_SIZE parameters to move the kernel
+ *      to upper memory.
+ *
+ * [Note: This is currently the same as the 2.3.99-pre3 code to allow
+ *  compatibility with existing code on the IXP1200, but will probably
+ *  drasticlly be rewritten in the near future.  For this reason,
+ *  only use the constansts in your code and do not the vaddrs themselves
+ *  to make your life easier when it does change]
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/map.h>
+
+struct map_desc ixp1200_io[] __initdata =
+{
+	/* Virtual   Physical     Length      Domain     R  W  C  B */
+
+	/* SRAM_BASE */
+	{ 0xf4000000, 0x10000000, 0x00800000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* PCICFG0_BASE */
+	{ 0xf1000000, 0x53000000, 0x01000000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* PCICFG1_BASE */
+	{ 0xf2000000, 0x52000000, 0x01000000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* ARMCSR_BASE */
+	{ 0xf0000000, 0x90000000, 0x00100000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* PCIIO_BASE */
+	{ 0xf0700000, 0x54000000, 0x00100000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* PCI_CSR_BASE */
+	{ 0xf0100000, 0x42000000, 0x00100000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* MICROENGINE_FBI_BASE */
+	{ 0xf0600000, 0xb0000000, 0x00100000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* SRAM_SLOW_PORT_BASE */
+	{ 0xf0800000, 0x38400000, 0x00300000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* SRAM_TEST_SET_BITS */
+	{ 0xf8000000, 0x19800000, 0x00800000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* SRAM_TEST_CLEAR_BITS */
+	{ 0xf7800000, 0x19000000, 0x00800000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* SRAM_SET_BITS */
+	{ 0xf7000000, 0x18800000, 0x00800000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* SRAM_CLEAR_BITS */
+	{ 0xf6800000, 0x18000000, 0x00800000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* SRAM_CAM_UNLOCK */
+	{ 0xf6000000, 0x16000000, 0x00800000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* SRAM_WRITE_UNLOCK */
+	{ 0xf5800000, 0x14000000, 0x00800000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* SRAM_READ_LOCK */
+	{ 0xf5000000, 0x12000000, 0x00800000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* SRAM_PUSH_POPQ_BASE */
+	{ 0xd0000000, 0x20000000, 0x08000000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* SRAM_CSR_BASE */
+	{ 0xf0200000, 0x38000000, 0x00100000, DOMAIN_IO, 1, 0, 0, 0 },
+
+	/* SDRAM_CSR_BASE */
+	{ 0xf0300000, 0xff000000, 0x00100000, DOMAIN_IO, 1, 0, 0, 0 },
+
+ 	LAST_DESC
+};
+
+void __init ixp1200_map_io(void)
+{
+	iotable_init(ixp1200_io);
+}
+
diff -urN linux-2.4.29/arch/arm/mach-ixp1200/pci-auto.c linux-2.4.29-uc1/arch/arm/mach-ixp1200/pci-auto.c
--- linux-2.4.29/arch/arm/mach-ixp1200/pci-auto.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp1200/pci-auto.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,340 @@
+/*
+ * arch/arm/mach-ixp1200/pci-auto.c
+ * 
+ * PCI autoconfiguration library
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/arch/pci-bridge.h>
+#include <asm/arch/pci.h>
+#include <asm/arch/pci-auto.h>
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif /* DEBUG */
+
+static int pciauto_upper_iospc;
+static int pciauto_upper_memspc;
+
+void pciauto_setup_bars(struct pci_controller *hose,
+		int current_bus,
+		int pci_devfn)
+{
+	int bar_response, bar_size, bar_value;
+	int bar, addr_mask, bar_nr = 0;
+	int * upper_limit;
+	int found_mem64 = 0;
+
+	DBG("PCI Autoconfig: Found Bus %d, Device %d, Function %d\n",
+		current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn) );
+
+	for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar+=4)
+	{
+		/* Tickle the BAR and get the response */
+		early_write_config_dword(hose,
+				current_bus,
+				pci_devfn,
+				bar,
+				0xffffffff);
+		early_read_config_dword(hose,
+				current_bus,
+				pci_devfn,
+				bar,
+				&bar_response);
+
+		/* If BAR is not implemented go to the next BAR */
+		if (!bar_response)
+			continue;
+
+		/* Check the BAR type and set our address mask */
+		if (bar_response & PCI_BASE_ADDRESS_SPACE)
+		{
+			addr_mask = PCI_BASE_ADDRESS_IO_MASK;
+			upper_limit = &pciauto_upper_iospc;
+			DBG("PCI Autoconfig: BAR %d, I/O, ", bar_nr);
+		}
+		else
+		{
+			if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+			PCI_BASE_ADDRESS_MEM_TYPE_64)
+				found_mem64 = 1;
+
+			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;		
+			upper_limit = &pciauto_upper_memspc;
+			DBG("PCI Autoconfig: BAR %d, Mem, ", bar_nr);
+		}
+
+		/* Calculate requested size */
+		bar_size = ~(bar_response & addr_mask) + 1;
+
+		/* Allocate a base address */
+		bar_value = (*upper_limit - bar_size) & ~(bar_size - 1);
+
+		/* Write it out and update our limit */
+		early_write_config_dword(hose,
+				current_bus,
+				pci_devfn,
+				bar,
+				bar_value);
+
+		*upper_limit = bar_value;
+
+		/*
+		 * If we are a 64-bit decoder then increment to the
+		 * upper 32 bits of the bar and force it to locate
+		 * in the lower 4GB of memory.
+		 */ 
+		if (found_mem64)
+		{
+			bar += 4;
+			early_write_config_dword(hose,
+					current_bus,
+					pci_devfn,
+					bar,
+					0x00000000);
+		}
+
+		bar_nr++;
+
+		DBG("size=0x%x, address=0x%x\n",
+			bar_size, bar_value);
+	}
+
+}
+
+void pciauto_prescan_setup_bridge(struct pci_controller *hose,
+		int current_bus,
+		int pci_devfn,
+		int sub_bus)
+{
+	int cmdstat;
+
+	/* Configure bus number registers */
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_PRIMARY_BUS,
+			current_bus);
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_SECONDARY_BUS,
+			sub_bus + 1);
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_SUBORDINATE_BUS,
+			0xff);
+
+	/* Round memory allocator to 1MB boundary */
+	pciauto_upper_memspc &= ~(0x100000 - 1);
+
+	/* Round I/O allocator to 4KB boundary */
+	pciauto_upper_iospc &= ~(0x1000 - 1);
+
+	/* Set up memory and I/O filter limits, assume 32-bit I/O space */
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_MEMORY_LIMIT,
+			((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_LIMIT,
+			((pciauto_upper_iospc - 1) & 0x0000f000) >> 8);
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_LIMIT_UPPER16,
+			((pciauto_upper_iospc - 1) & 0xffff0000) >> 16);
+
+	/* We don't support prefetchable memory for now, so disable */
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_PREF_MEMORY_BASE,
+			0x1000);
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_PREF_MEMORY_LIMIT,
+			0x1000);
+
+	/* Enable memory and I/O accesses, enable bus master */
+	early_read_config_dword(hose,
+			current_bus,
+			pci_devfn,
+			PCI_COMMAND,
+			&cmdstat);
+	early_write_config_dword(hose,
+			current_bus,
+			pci_devfn,
+			PCI_COMMAND,
+			cmdstat |
+			PCI_COMMAND_IO |
+			PCI_COMMAND_MEMORY |
+			PCI_COMMAND_MASTER);
+}
+
+void pciauto_postscan_setup_bridge(struct pci_controller *hose,
+		int current_bus,
+		int pci_devfn,
+		int sub_bus)
+{
+	/* Configure bus number registers */
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_SUBORDINATE_BUS,
+			sub_bus);
+
+	/* Round memory allocator to 1MB boundary */
+	pciauto_upper_memspc &= ~(0x100000 - 1);
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_MEMORY_BASE,
+			pciauto_upper_memspc >> 16);
+
+	/* Round I/O allocator to 4KB boundary */
+	pciauto_upper_iospc &= ~(0x1000 - 1);
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_BASE,
+			(pciauto_upper_iospc & 0x0000f000) >> 8);
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_BASE_UPPER16,
+			pciauto_upper_iospc >> 16);
+}
+
+int pciauto_bus_scan(struct pci_controller *hose, int current_bus)
+{
+	int sub_bus, pci_devfn, pci_class, cmdstat, found_multi=0;
+	unsigned short vid;
+	unsigned char header_type;
+
+	/*
+	 * Fetch our I/O and memory space upper boundaries used
+	 * to allocated base addresses on this hose.
+	 */
+	if (current_bus == hose->first_busno)
+	{
+		pciauto_upper_iospc = hose->io_space.end + 1;
+		pciauto_upper_memspc = hose->mem_space.end + 1;
+	}
+
+	sub_bus = current_bus;
+
+	for (pci_devfn=0; pci_devfn<0xff; pci_devfn++)
+	{
+		/* Skip our host bridge */
+		if ( (current_bus == hose->first_busno) && (pci_devfn == 0) )
+			continue;
+
+		if (PCI_FUNC(pci_devfn) && !found_multi)
+			continue;
+
+		/* If config space read fails from this device, move on */
+		if (early_read_config_byte(hose,
+				current_bus,
+				pci_devfn,
+				PCI_HEADER_TYPE,
+				&header_type))
+			continue;
+
+		if (!PCI_FUNC(pci_devfn))
+			found_multi = header_type & 0x80;
+
+		early_read_config_word(hose,
+				current_bus,
+				pci_devfn,
+				PCI_VENDOR_ID,
+				&vid);
+
+		if (vid != 0xffff)
+		{
+			early_read_config_dword(hose,
+					current_bus,
+					pci_devfn,
+					PCI_CLASS_REVISION, &pci_class);
+			if ( (pci_class >> 16) == PCI_CLASS_BRIDGE_PCI )
+			{
+				DBG("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_SLOT(pci_devfn));
+				pciauto_prescan_setup_bridge(hose,
+						current_bus,
+						pci_devfn,
+						sub_bus);
+				sub_bus = pciauto_bus_scan(hose, sub_bus+1);
+				pciauto_postscan_setup_bridge(hose,
+						current_bus,
+						pci_devfn,
+						sub_bus);
+			}
+			else
+			{
+				if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE)
+				{
+					unsigned char prg_iface;
+
+					early_read_config_byte(hose,
+							current_bus,
+							pci_devfn,
+							PCI_CLASS_PROG,
+							&prg_iface);
+					if (!(prg_iface & PCIAUTO_IDE_MODE_MASK))
+					{
+						DBG("PCI Autoconfig: Skipping legacy mode IDE controller\n");
+						continue;
+					}
+				}
+				/*
+				 * Found a peripheral, enable some standard
+				 * settings
+				 */
+				early_read_config_dword(hose,
+						current_bus,
+						pci_devfn,
+						PCI_COMMAND,
+						&cmdstat);
+				early_write_config_dword(hose,
+						current_bus,
+						pci_devfn,
+						PCI_COMMAND,
+						cmdstat |
+						PCI_COMMAND_IO |
+						PCI_COMMAND_MEMORY |
+						PCI_COMMAND_MASTER);
+				early_write_config_byte(hose,
+						current_bus,
+						pci_devfn,
+						PCI_LATENCY_TIMER,
+						0x80);
+
+				/* Allocate PCI I/O and/or memory space */
+				pciauto_setup_bars(hose,
+						current_bus,
+						pci_devfn);
+			}
+		}
+	}
+	return sub_bus;
+}
diff -urN linux-2.4.29/arch/arm/mach-ixp1200/pci.c linux-2.4.29-uc1/arch/arm/mach-ixp1200/pci.c
--- linux-2.4.29/arch/arm/mach-ixp1200/pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp1200/pci.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,176 @@
+/*
+ * arch/arm/mach-iop310/pci.c
+ *
+ * Generic PCI support functionality that should eventually move to
+ * arch/arm/kernel/bios32.c.  Derived from support in ppc and alpha.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm//hardware.h>
+#include <asm/arch/pci-bridge.h>
+
+#undef DEBUG 
+
+#ifdef DEBUG
+#define  DBG(x...) printk(x)
+#else
+#define  DBG(x...)
+#endif
+
+struct pci_controller* hose_head;
+struct pci_controller** hose_tail = &hose_head;
+
+/*
+ * The following code swizzles for exactly one bridge.  The routine
+ * common_swizzle below handles multiple bridges.  But there are a
+ * some boards that don't follow the PCI spec's suggestion so we
+ * break this piece out separately.
+ */
+static inline u8
+bridge_swizzle(u8 pin, u8 slot)
+{
+	return (((pin-1) + slot) % 4) + 1;
+}
+
+u8 __init
+common_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	struct pci_controller *hose;
+	
+	hose = pci_bus_to_hose(dev->bus->number);
+
+	if (dev->bus->number != hose->first_busno) {
+		u8 pin = *pinp;
+		do {
+			pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+			/* Move up the chain of bridges. */
+			dev = dev->bus->self;
+		} while (dev->bus->self);
+		*pinp = pin;
+
+		/* The slot is the slot of the last bridge. */
+	}
+
+	return PCI_SLOT(dev->devfn);
+}
+
+/*
+ * Null PCI config access functions, for the case when we can't
+ * find a hose.
+ */
+#define NULL_PCI_OP(rw, size, type)					\
+static int								\
+null_##rw##_config_##size(struct pci_dev *dev, int offset, type val)	\
+{									\
+	return PCIBIOS_DEVICE_NOT_FOUND;    				\
+}
+
+	NULL_PCI_OP(read, byte, u8 *)
+	NULL_PCI_OP(read, word, u16 *)
+	NULL_PCI_OP(read, dword, u32 *)
+	NULL_PCI_OP(write, byte, u8)
+	NULL_PCI_OP(write, word, u16)
+NULL_PCI_OP(write, dword, u32)
+
+static struct pci_ops null_pci_ops =
+{
+	null_read_config_byte,
+	null_read_config_word,
+	null_read_config_dword,
+	null_write_config_byte,
+	null_write_config_word,
+	null_write_config_dword
+};
+
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+struct pci_dev *
+fake_pci_dev(struct pci_controller *hose, int busnr, int devfn)
+{
+	static struct pci_dev dev;
+	static struct pci_bus bus;
+
+	if (hose == 0) {
+		hose = pci_bus_to_hose(busnr);
+		if (hose == 0)
+			printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);
+	}
+	dev.bus = &bus;
+	dev.sysdata = hose;
+	dev.devfn = devfn;
+	bus.number = busnr;
+	bus.ops = hose? hose->ops: &null_pci_ops;
+	return &dev;
+}
+
+static int next_controller_index;
+
+struct pci_controller * __init
+pcibios_alloc_controller(void)
+{
+	struct pci_controller *hose;
+
+	hose = (struct pci_controller *)kmalloc(sizeof(*hose), GFP_KERNEL);
+	memset(hose, 0, sizeof(struct pci_controller));
+	
+	*hose_tail = hose;
+	hose_tail = &hose->next;
+
+	hose->index = next_controller_index++;
+
+	return hose;
+}
+	
+struct pci_controller *
+pci_bus_to_hose(int bus)
+{
+	struct pci_controller *hose = hose_head;
+
+	for (; hose; hose = hose->next)
+		if (bus >= hose->first_busno && bus <= hose->last_busno)
+			return hose;
+	return NULL;
+}
+
+void __init
+pci_exclude_device(unsigned char bus, unsigned char devfn)
+{
+	struct pci_dev *dev, *pdev = NULL;
+
+	/* Walk the pci device list */
+	pci_for_each_dev(dev)
+	{
+		if ((dev->bus->number == bus) && (dev->devfn == devfn))
+		{
+			/*
+			 * Remove the device from the global and
+			 * bus lists.
+			 */
+			list_del(&(dev->global_list));
+			list_del(&(dev->bus_list));
+
+			/* Free the pci_dev structure */
+			kfree(dev);
+
+			break;
+		}
+		pdev = dev;
+	}
+}
diff -urN linux-2.4.29/arch/arm/mach-ixp2000/arch.c linux-2.4.29-uc1/arch/arm/mach-ixp2000/arch.c
--- linux-2.4.29/arch/arm/mach-ixp2000/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp2000/arch.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,63 @@
+/*
+ * linux/arch/arm/mach-ixp2000/arch.c
+ *
+ * Copyright (C) 2002 Intel Corp.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+
+
+static void __init
+fixup_ixp2000(struct machine_desc *desc, struct param_struct *params,
+	      char **cmdline, struct meminfo *mi)
+{
+
+	if(machine_is_ixdp2400() || machine_is_ixdp2800())
+	{
+		mi->bank[0].start = PHYS_SDRAM_BASE; 
+		mi->bank[0].size  = PHYS_SDRAM_SIZE;
+		mi->bank[0].node  = 0;
+		mi->nr_banks      = 1;
+	} 
+}
+
+#ifdef CONFIG_ARCH_IXDP2400
+extern void ixdp2400_map_io(void);
+extern void ixdp2400_init_irq(void);
+
+MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform")
+	MAINTAINER("MontaVista Software, Inc.")
+	BOOT_MEM(PHYS_SDRAM_BASE, 0xc0030000, IXP2000_UART_BASE)/*pram,pio,vio*/
+	FIXUP(fixup_ixp2000)
+	MAPIO(ixdp2400_map_io)
+	INITIRQ(ixdp2400_init_irq)
+MACHINE_END
+#elif defined (CONFIG_ARCH_IXDP2800)
+extern void ixdp2800_map_io(void);
+extern void ixdp2800_init_irq(void);
+
+MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform")
+	MAINTAINER("MontaVista Software, Inc.")
+	BOOT_MEM(PHYS_SDRAM_BASE, 0xc0030000, IXP2000_UART_BASE)/*pram,pio,vio*/
+	FIXUP(fixup_ixp2000)
+	MAPIO(ixdp2800_map_io)
+	INITIRQ(ixdp2800_init_irq)
+MACHINE_END
+#else
+#error No board defined!
+#endif
diff -urN linux-2.4.29/arch/arm/mach-ixp2000/ixasdk.c linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixasdk.c
--- linux-2.4.29/arch/arm/mach-ixp2000/ixasdk.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixasdk.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,167 @@
+/*
+ *  linux/arch/arm/mach-ixp2000/ixasdk.c
+ *
+ *  Copyright (C) 2002 Intel Corp
+ *
+ *  naeem.m.afzal@intel.com
+ * API used for IXASDK only
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+#include <asm/arch/hardware.h>
+
+#define MAX_QDR_CHANNEL         2
+
+struct EEPROM_CONTENT {
+        unsigned char   prom_fmt; //1
+    	unsigned char   dev_id;  //1
+        unsigned char   man_id[12]; //[CFG_MAN_ID_LEN]; //12
+        unsigned char   part_rev [2];//[CFG_PARTREV_LEN]; //2
+
+        unsigned char   part_num[10]; //[CFG_PARTNUM_LEN]; //10
+        unsigned char   serial_num[10]; //[CFG_SERIAL_NUM_LEN]; //10
+        unsigned char   model_id[12]; //[CFG_MODEL_ID_LEN]; //12
+
+        unsigned char   rsvd1[8]; //[CFG_RSVD1_LEN]; //8
+        unsigned char   passwd[8]; //[CFG_PASSWD_LEN]; //8
+
+        unsigned char   test_status;    //1
+        unsigned char   date[8]; //[CFG_DATE_LEN]; //8
+        unsigned char   chksum[4]; //[CFG_CHKSUM_LEN]; //4
+        unsigned char   rsvd2[3]; //[CFG_RSVD2_LEN]; //3
+        unsigned int    M_uart_baud; //4
+        unsigned char   M_ether_mac_addr[6]; //6
+        unsigned int    S_uart_baud; //4
+        unsigned char   S_ether_mac_addr[6]; //6
+        unsigned char   rsvd3[12]; //4
+};
+
+struct board_config
+{
+        struct EEPROM_CONTENT config_data;
+        int sdram_size;
+        int qdr_channel_size[MAX_QDR_CHANNEL];
+        int flash_size;
+        int config_valid;
+};
+
+#define VALID_STRING	0x12345678
+
+struct ixdp2000_sys_info {
+    int valid;
+    int sys; 		/* size of sdram used by  Linux OS*/
+    int sys_all;   	/* Total SDRAM size on system */
+    int sdram;   	/* Size of memory used by MicroEngines  */
+    int sram;      	/* Size of sram Total */
+    int sram0;		/* channel 0 sram size */
+    int sram1;		/* channel 1 sram size */
+    int sram2;		/* channel 2 sram size */
+    int sram3;		/* channel 3 sram size */
+    int flash;     	/* Size of Flash */
+};
+
+struct ixdp2000_sys_info *sz_info;
+
+static int __init ixdp2000_ixasdk_init(void)
+{
+	struct board_config *scratch;
+
+	scratch = (struct board_config *)__ioremap(PHY_SCRATCH, sizeof(struct board_config), 0);
+
+	if (!scratch) {
+                printk("Failed to ioremap\n");
+                goto out;
+        }
+
+	if (scratch->config_valid != VALID_STRING ) {
+		printk(KERN_WARNING"ixasdk.o: Invalid board config data\n");
+		printk(KERN_WARNING"ixasdk.o: Need to program I2C data for valid config data.\n");
+	}
+	sz_info =(struct ixdp2000_sys_info *)kmalloc(sizeof(struct ixdp2000_sys_info), GFP_KERNEL);
+
+	if (!sz_info) {
+		printk(KERN_WARNING" Cannot allocate memory for struct ixdp2000_sys_info.\n");
+		return -ENOMEM;
+	}
+
+	memset(sz_info,0, sizeof(struct ixdp2000_sys_info));
+
+	if (scratch->config_valid == VALID_STRING) {
+		sz_info->valid = 1;
+		sz_info->sys_all = scratch->sdram_size; /* total system sdram */
+		sz_info->sdram 	= scratch->sdram_size 
+				- PHYS_SDRAM_SIZE;/* sdram for uEngines */
+
+		sz_info->sys = PHYS_SDRAM_SIZE;
+		sz_info->sram = scratch->qdr_channel_size[0] 
+			+ scratch->qdr_channel_size[1];
+		sz_info->sram0 = scratch->qdr_channel_size[0];
+		sz_info->sram1 = scratch->qdr_channel_size[1];
+#if CONFIG_ARCH_IXDP2800
+		sz_info->sram2 = scratch->qdr_channel_size[2];
+		sz_info->sram2 = scratch->qdr_channel_size[3];
+#endif
+		sz_info->flash = scratch->flash_size;
+	} else { /* take some default values */
+		sz_info->valid = 0;
+		sz_info->sys_all = 0x20000000; /* total system sdram */
+		sz_info->sdram 	= 0x20000000 
+					- PHYS_SDRAM_SIZE;/* sdram for uEngines */
+		sz_info->sys = PHYS_SDRAM_SIZE;
+		sz_info->sram = 0x800000;
+		sz_info->sram0 = 0x400000;
+		sz_info->sram1 = 0x400000;
+#if CONFIG_ARCH_IXDP2800
+		sz_info->sram2 = 0x400000; 
+		sz_info->sram2 = 0x400000;
+#endif
+		sz_info->flash = 0x1000000;
+
+	}
+
+	__iounmap(scratch);
+
+	return 0;
+out:
+	return -1;
+ 
+}
+void sysMemVirtSize (
+	 unsigned int* sys, unsigned int* sys_all
+	,unsigned int* sdram,  unsigned int* sram
+	,unsigned int* sram0, unsigned int* sram1
+	,unsigned int* sram2, unsigned int* sram3
+	,unsigned int* flash )
+{
+
+	if (!sz_info->valid)
+		printk(KERN_WARNING "sysMemVirtSize(): System sizes are invalid.\n");
+	*sys = sz_info->sys;	
+	*sys_all = sz_info->sys_all;	
+	*sdram = sz_info->sdram;
+	*sram = sz_info->sram;
+	*sram0 = sz_info->sram0;
+	*sram1 = sz_info->sram1;
+#if CONFIG_ARCH_IXDP2800
+	*sram2 = sz_info->sram2;
+	*sram3 = sz_info->sram3;
+#endif
+	*flash = sz_info->flash;
+
+}
+__initcall(ixdp2000_ixasdk_init);
+
+EXPORT_SYMBOL(sysMemVirtSize);
diff -urN linux-2.4.29/arch/arm/mach-ixp2000/ixdp2400-irq.c linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixdp2400-irq.c
--- linux-2.4.29/arch/arm/mach-ixp2000/ixdp2400-irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixdp2400-irq.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,119 @@
+/*
+ * arch/arm/mach-ixp2000/ixdp2400-irq.c
+ *
+ * Interrupt code for IXDP2400 board
+ *
+ * Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ * Copyright 2002 Intel Corp.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
+#include <asm/arch/hardware.h>
+
+extern void do_IRQ(int, struct pt_regs *);
+extern int setup_arm_irq(int, struct irqaction *);
+extern void  ixp2000_init_irq(void);
+
+/*
+ * Slowport configuration for accessing CPLD registers
+ */
+static struct slowport_cfg slowport_cpld_cfg = {
+	CCR:	SLOWPORT_CCR_DIV_2,
+	WTC:	0x00000070,
+	RTC:	0x00000070,
+	PCR:	SLOWPORT_MODE_FLASH,
+	ADC:	SLOWPORT_ADDR_WIDTH_24 | SLOWPORT_DATA_WIDTH_8
+};
+
+static void ext_irq_mask(unsigned int irq)
+{
+	unsigned long dummy;
+
+	acquire_slowport(&slowport_cpld_cfg);
+	dummy = *IXDP2400_CPLD_INT_MASK;
+	ixp_reg_write(IXDP2400_CPLD_INT_MASK, dummy | (1 << (irq - NR_IXP2000_IRQS)));
+	release_slowport();
+}
+
+static void ext_irq_unmask(unsigned int irq)
+{
+	unsigned long dummy;
+
+	acquire_slowport(&slowport_cpld_cfg);
+	dummy = *IXDP2400_CPLD_INT_MASK;
+	ixp_reg_write(IXDP2400_CPLD_INT_MASK, dummy & ~(1 << (irq - NR_IXP2000_IRQS)));
+	release_slowport();
+}
+
+static void ext_irq_demux(int irq, void *dev_id, struct pt_regs *regs)
+{
+        volatile u32 ex_interrupt = 0;
+	int i;
+
+	acquire_slowport(&slowport_cpld_cfg);
+        ex_interrupt = *(IXDP2400_CPLD_INT) & 0xff;
+	release_slowport();
+
+	if(!ex_interrupt) {
+		printk(KERN_ERR "Spurious IXDP2400 CPLD interrupt!\n");
+		return;
+	}
+
+	for(i = 0; i < 8; i++) {
+		if(ex_interrupt & (1 << i)) 
+			do_IRQ(IRQ_IXDP2400(0) + i, regs);
+	}
+}
+
+static struct irqaction ext_irq = {
+	name:	"IXDP2400 CPLD",
+	handler: ext_irq_demux,
+	flags: SA_INTERRUPT
+};
+
+/*
+ * We only do anything if we are the master NPU on the board.
+ * The slave NPU only has the ethernet chip going directly to
+ * the PCIB interrupt input.
+ */
+void __init ixdp2400_init_irq(void)
+{
+	int i = 0;
+
+	/* initialize chip specific interrupts */
+	ixp2000_init_irq();
+
+	if (npu_is_master()) {
+
+		/* Disable all CPLD interrupts */
+		acquire_slowport(&slowport_cpld_cfg);
+		*IXDP2400_CPLD_INT_MASK = 0xff;
+		release_slowport();
+
+		for(i = NR_IXP2000_IRQS; i < NR_IXDP2400_IRQS; i++) {
+			irq_desc[i].valid 	= 1;
+			irq_desc[i].probe_ok	= 0;
+			irq_desc[i].mask_ack	= ext_irq_mask;
+			irq_desc[i].mask	= ext_irq_mask;
+			irq_desc[i].unmask	= ext_irq_unmask;
+		}
+
+		/* Hook into PCI interrupts */
+		setup_arm_irq(IRQ_IXP2000_PCIB, &ext_irq);
+	}
+}
diff -urN linux-2.4.29/arch/arm/mach-ixp2000/ixdp2400-pci.c linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixdp2400-pci.c
--- linux-2.4.29/arch/arm/mach-ixp2000/ixdp2400-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixdp2400-pci.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,151 @@
+/*
+ * arch/arm/mach-ixp2000/ixmb2400-pci.c
+ *
+ * PCI routines for IXDP2400 board
+ *
+ * Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ *
+ * Copyright 2002 Intel Corp.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/pci.h>
+#include <asm/arch/pci-bridge.h>
+
+//#define DEBUG 1
+
+#ifdef DEBUG 
+#define DBG(x...)	printk(x)
+#else
+#define DBG(x...)
+#endif /* DEBUG */
+
+extern void ixp2000_pci_init(void *);
+extern struct pci_ops ixp2000_ops;
+
+/*
+ * This board does not do normal PCI IRQ routing, or any
+ * sort of swizzling, so we just need to check where on the
+ * bus the device is and figure out what CPLD pin it's 
+ * being routed to.
+ */
+static int __init
+ixdp2400_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+
+	if (npu_is_master()) {
+
+		/*
+		 * Root bus devices.  Slave NPU is only one with interrupt.
+		 * Everything else, we just return -1 which is invalid.
+		 */
+		if(!dev->bus->self) {
+			if(dev->devfn == 0x0028 )
+					return IRQ_IXDP2400_INGRESS_NPU;
+
+			return -1;
+		}
+
+		/*
+		 * We have a bridge behind the PMC slot
+		 * NOTE: Only INTA from the PMC slot is routed.
+		 */
+		if(PCI_SLOT(dev->bus->self->devfn) == 0x7 &&
+			  PCI_SLOT(dev->bus->parent->self->devfn) == 0x4 &&
+				  !dev->bus->parent->self->bus->parent)
+				  return	IRQ_IXDP2400_PMC;
+
+		/*
+		 * Device behind the first bridge
+		 */
+		if(PCI_SLOT(dev->bus->self->devfn) == 0x4) {
+			switch(PCI_SLOT(dev->devfn)) {
+				case 0x4:	// Master ethernet
+					return IRQ_IXDP2400_METHERNET;	
+			
+				case 0x5:	// Media interface
+					return IRQ_IXDP2400_MEDIA_PCI;
+
+				case 0x6:	// Switch fabric
+					return IRQ_IXDP2400_SF_PCI;
+
+				case 0x7:	// PMC slot
+					return IRQ_IXDP2400_PMC;
+			}
+		}
+
+		return 0;
+
+	} else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */
+}
+
+extern void ixp2000_pci_init(void *);
+
+void __init ixdp2400_pci_init(void *sysdata)
+{
+	ixp2000_pci_init(sysdata);
+
+	/*
+	 * All I/O > 1MB, PCI MEM starting at 0.
+	 */
+	ixp_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000);
+
+	pci_scan_bus(0, &ixp2000_ops, sysdata);
+
+	/*
+	 * Exclude devices depending on whether we are the master
+	 * or slave NPU. Sigh...
+	 *
+	 * NOTE TO HW DESIGNERS: DO NOT PUT MULTIPLE PCI HOST CPUS
+	 * ON THE SAME BUS SEGMENT. THAT'S WHAT NON-TRANSPARENT 
+	 * BRIDGES ARE FOR.
+	 */
+	if (npu_is_master()) {
+		pci_exclude_device(0x01, 0x18); /* Remove slave's NIC*/
+		pci_exclude_device(0x0, 0x38); 	/* Remove self */
+	} else {
+		int i;
+
+		pci_exclude_device(0x01, 0x38);	/* Remove PMC site */
+		pci_exclude_device(0x01, 0x20);	/* Remove master NIC*/
+		pci_exclude_device(0x0, 0x20);	/* Remove remove 21154*/
+		pci_exclude_device(0x0, 0x30);	/* Remove 21555*/
+		pci_exclude_device(0x0, 0x28);	/* Remove Self */
+
+		/*
+		 * In case there's a bridge on the PMC, we remove everything
+		 * on bus 2.
+		 */
+		for(i = 0; i < 0xff; i++)
+			pci_exclude_device(0x2, i);
+	}
+}
+
+struct hw_pci ixdp2400_pci __initdata = {
+	init:		ixdp2400_pci_init,
+	swizzle:	no_swizzle,
+	map_irq:	ixdp2400_map_irq,
+	mem_offset:	0xe0000000
+};
+
+
diff -urN linux-2.4.29/arch/arm/mach-ixp2000/ixdp2800-irq.c linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixdp2800-irq.c
--- linux-2.4.29/arch/arm/mach-ixp2000/ixdp2800-irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixdp2800-irq.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,85 @@
+/*
+ * arch/arm/mach-ixp2000/ixdp2800-irq.c
+ *
+ * Interrupt code for IXDP2800 board
+ *
+ * Author: Jeff Daly <jeffrey.daly@intel.com>
+ * Copyright 2002 Intel Corp.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
+#include <asm/arch/hardware.h>
+
+extern void do_IRQ(int, struct pt_regs *);
+extern int setup_arm_irq(int, struct irqaction *);
+extern void  ixp2000_init_irq(void);
+
+static void ext_irq_mask(unsigned int irq)
+{
+	*IXDP2800_CPLD_INT_MASK &= ~(1 << (irq - NR_IXP2000_IRQS));
+}
+
+static void ext_irq_unmask(unsigned int irq)
+{
+	*IXDP2800_CPLD_INT_MASK |= (1 << (irq - NR_IXP2000_IRQS));
+}
+
+static void ext_irq_demux(int irq, void *dev_id, struct pt_regs *regs)
+{
+        volatile u32 ex_interrupt = 0;
+    	int irqno = 0, i = 0;
+
+        ex_interrupt = *(IXDP2800_CPLD_INT);
+
+	for(i = 0; i < 6; i++) {
+		if(ex_interrupt & (1 << i))
+			do_IRQ(IRQ_IXDP2800(i), regs);
+	}
+}
+
+static struct irqaction ext_irq = {
+	name:	"IXDP2800 CPLD",
+	handler: ext_irq_demux,
+	flags: SA_INTERRUPT
+};
+
+void __init ixdp2800_init_irq(void)
+{
+	int i = 0;
+	
+	*IXDP2800_CPLD_INT_MASK = 0;		/* turn off interrupts */
+
+	/* initialize chip specific interrupts */
+	ixp2000_init_irq();
+
+	/*
+	 * Slave only has NIC routed to it, so we don't init everything
+	 */
+	if (npu_is_master()) {
+		for(i = NR_IXP2000_IRQS; i < NR_IXDP2800_IRQS; i++) {
+			irq_desc[i].valid 	= 1;
+			irq_desc[i].probe_ok	= 0;
+			irq_desc[i].mask_ack	= ext_irq_mask;
+			irq_desc[i].mask	= ext_irq_mask;
+			irq_desc[i].unmask	= ext_irq_unmask;
+		}
+
+		/* init PCI interrupts */
+		setup_arm_irq(IRQ_IXP2000_PCIB, &ext_irq);
+	}
+}
diff -urN linux-2.4.29/arch/arm/mach-ixp2000/ixdp2800-leds.c linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixdp2800-leds.c
--- linux-2.4.29/arch/arm/mach-ixp2000/ixdp2800-leds.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixdp2800-leds.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,117 @@
+/*
+ * arch/arm/mach-ixp2000/ixdp2800-leds.c
+ *
+ * Code to manipulate led display on IXDP2800
+ *
+ * Author: Jeff Daly <jeffrey.daly@intel.com>
+ *	Modified from arch/arm/mach-footbridge/ebsa285-leds.c
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+#include <asm/system.h>
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+static char led_state;
+static char hw_led_state0;
+static char hw_led_state1 = 0x1;
+static char hw_led_state2 = ' ';
+static char hw_led_state3 = ' ';
+
+static char spinner[] = {'|','/','-','\\'};
+static int spincnt = 0;
+
+static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED;
+
+static void ixdp2800_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&leds_lock, flags);
+
+	switch (evt) {
+	case led_start:
+		led_state |= LED_STATE_ENABLED;
+		break;
+
+	case led_stop:
+		led_state &= ~LED_STATE_ENABLED;
+		break;
+
+	case led_claim:
+		led_state |= LED_STATE_CLAIMED;
+		break;
+
+	case led_release:
+		led_state &= ~LED_STATE_CLAIMED;
+		break;
+
+#ifdef CONFIG_LEDS_TIMER
+	case led_timer:
+		if (!(led_state & LED_STATE_CLAIMED))
+		{
+			hw_led_state0 = spinner[spincnt];
+			spincnt++;
+			spincnt %= 4;
+		}
+		break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+	case led_idle_start:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state1 = ' ';
+		break;
+
+	case led_idle_end:
+		if (!(led_state & LED_STATE_CLAIMED))
+		hw_led_state1 = '*';
+		break;
+#endif
+
+	case led_halted:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state0 = 'H';
+			hw_led_state1 = 'A';
+			hw_led_state2 = 'L';
+			hw_led_state3 = 'T';
+		break;
+
+	default:
+		break;
+	}
+
+	if  (led_state & LED_STATE_ENABLED)
+	{
+		*IXDP2800_LED0_REG = hw_led_state0;
+		*IXDP2800_LED1_REG = hw_led_state1;
+		*IXDP2800_LED2_REG = hw_led_state2;
+		*IXDP2800_LED3_REG = hw_led_state3;
+	}
+
+	spin_unlock_irqrestore(&leds_lock, flags);
+}
+
+static int __init leds_init(void)
+{
+	/* clear leds */
+	*IXDP2800_LED0_REG = ' ';
+	*IXDP2800_LED1_REG = ' ';
+	*IXDP2800_LED2_REG = ' ';
+	*IXDP2800_LED3_REG = ' ';
+
+	leds_event = ixdp2800_leds_event;
+
+	leds_event(led_start);
+
+	return 0;
+}
+
+__initcall(leds_init);
diff -urN linux-2.4.29/arch/arm/mach-ixp2000/ixdp2800-pci.c linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixdp2800-pci.c
--- linux-2.4.29/arch/arm/mach-ixp2000/ixdp2800-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixdp2800-pci.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,172 @@
+/*
+ * arch/arm/mach-ixp2000/ixmb2800-pci.c
+ *
+ * PCI routines for IXDP2800 board
+ *
+ * Author: Jeff Daly <jeffrey.daly@intel.com>
+ *
+ * Copyright 2002-2003 Intel Corp.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ * TODO: This is almost identical to IXDP2400..may consider merging the two.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/pci.h>
+#include <asm/arch/pci_auto.h>
+#include <asm/arch/pci-bridge.h>
+
+// #define DEBUG 
+#ifdef DEBUG 
+#define DBG(x...)	printk(x)
+#else
+#define DBG(x...)
+#endif /* DEBUG */
+
+extern void ixp2000_pci_init(void *);
+extern struct pci_ops ixp2000_ops;
+static struct pci_controller *hose;
+
+/*
+ * This board does not do normal PCI IRQ routing, or any
+ * sort of swizzling, so we just need to check where on the
+ * bus the device is and figure out what CPLD pin it's 
+ * being routed to.
+ */
+static int __init
+ixdp2800_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+
+	if (npu_is_master()) {
+
+		/*
+		 * Root bus devices.  Slave NPU is only one with interrupt.
+		 * Everything else, we just return -1 which is invalid.
+		 */
+		if(!dev->bus->self) {
+			if(dev->devfn == 0x0028 )
+				return IRQ_IXDP2800_INGRESS_NPU;
+
+			return -1;
+		}
+
+		/*
+		 * We have a bridge behind the PMC slot
+		 * NOTE: Only INTA from the PMC slot is routed.
+		 */
+		if(PCI_SLOT(dev->bus->self->devfn) == 0x7 &&
+			  PCI_SLOT(dev->bus->parent->self->devfn) == 0x4 &&
+				  !dev->bus->parent->self->bus->parent)
+				  return IRQ_IXDP2800_PMC_PCI;
+
+		/*
+		 * Device behind the first bridge
+		 */
+		if(PCI_SLOT(dev->bus->self->devfn) == 0x4) {
+			switch(PCI_SLOT(dev->devfn)) {
+				case 0x2:	// Master PMC
+					return IRQ_IXDP2800_PMC_PCI;	
+			
+				case 0x3:	// Ethernet
+					return IRQ_IXDP2800_EGRESS_NIC;
+
+				case 0x5:	// Switch fabric
+					return IRQ_IXDP2800_FABRIC;
+			}
+		}
+
+		return 0;
+
+	} else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */
+}
+
+extern void ixp2000_pci_init(void *);
+
+void __init ixdp2800_pci_init(void *sysdata)
+{
+	ixp2000_pci_init(sysdata);
+
+	*IXP2000_PCI_CMDSTAT = 0;
+	*IXP2000_PCI_ADDR_EXT = 0x0000e000;
+
+	*IXP2000_PCI_DRAM_BASE_ADDR_MASK = (0x20000000 - 1) & ~0xfffff;
+	*IXP2000_PCI_SRAM_BASE_ADDR_MASK = (0x2000000 - 1) & ~0x3ffff;
+
+	DBG("allocating hose\n");
+	hose = pcibios_alloc_controller();
+	if (!hose)
+		panic("Could not allocate PCI hose");
+
+	hose->first_busno = 0;
+	hose->last_busno = 0;
+	hose->io_space.start = 0x00000000;
+	hose->io_space.end = 0x0000ffff;
+	hose->mem_space.start = 0xe0000000;
+	hose->mem_space.end = 0xffffffff;
+
+	/*
+	 * Scan bus and exclude devices depending on whether we are the 
+	 * master or slave NPU. Sigh...
+	 *
+	 * NOTE TO HW DESIGNERS: DO NOT PUT MULTIPLE PCI HOST CPUS
+	 * ON THE SAME BUS SEGMENT. THAT'S WHAT NON-TRANSPARENT 
+	 * BRIDGES ARE FOR.
+	 */
+	if (npu_is_master()) {
+		*IXP2000_PCI_SDRAM_BAR = PHYS_OFFSET;
+
+		*IXP2000_PCI_CMDSTAT = (PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+		hose->last_busno = pciauto_bus_scan(hose, 0);
+
+		pci_scan_bus(0,&ixp2000_ops, sysdata);
+
+		pci_exclude_device(0x01, 0x20); /* Remove slave's NIC*/
+		pci_exclude_device(0x0, 0x38); 	/* Remove self XXX FIXME*/
+	} else {
+		int i;
+
+		/* Wait for the master NPU to enable us */
+		while(!(*IXP2000_PCI_CMDSTAT & PCI_COMMAND_MASTER));
+		pci_scan_bus(0, &ixp2000_ops, sysdata);
+
+		pci_exclude_device(0x01, 0x38);	/* Remove PMC site */
+		pci_exclude_device(0x01, 0x18);	/* Remove master NIC*/
+		pci_exclude_device(0x0, 0x20);	/* Remove remove 21154*/
+		pci_exclude_device(0x0, 0x30);	/* Remove 21555*/
+		pci_exclude_device(0x0, 0x28);	/* Remove Self XXX FIXME */
+
+		/*
+		 * In case there's a bridge on the PMC, we remove everything
+		 * on bus 2.
+		 */
+		for(i = 0; i < 0xff; i++)
+			pci_exclude_device(0x2, i);
+	}
+}
+
+struct hw_pci ixdp2800_pci __initdata = {
+	init:		ixdp2800_pci_init,
+	swizzle:	no_swizzle,
+	map_irq:	ixdp2800_map_irq,
+};
+
+
diff -urN linux-2.4.29/arch/arm/mach-ixp2000/ixp2000-irq.c linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixp2000-irq.c
--- linux-2.4.29/arch/arm/mach-ixp2000/ixp2000-irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixp2000-irq.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,197 @@
+/*
+ * arch/arm/mach-ixp2000/ixp2000-irq.c
+ *
+ * Interrupt code for IXDP2400 board
+ *
+ * Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (c) 2002 Intel Corp.
+ * Copyright (c) 2003 MontaVista Software, Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/bitops.h>
+
+#include <asm/mach/irq.h>
+
+extern void do_IRQ(int, struct pt_regs *);
+extern int setup_arm_irq(int, struct irqaction *);
+
+static void ixp_irq_mask(unsigned int irq)
+{
+	ixp_reg_write(IXP2000_IRQ_ENABLE_CLR, (1 << irq));
+}
+
+static void ixp_irq_unmask(unsigned int irq)
+{
+	ixp_reg_write(IXP2000_IRQ_ENABLE_SET,  (1 << irq));
+}
+
+/*
+ * Install handler for GPIO interrupts
+ */
+static void ixp_GPIO_demux(int irq, void *dev_id, struct pt_regs *regs)
+{                               
+	int i;
+		        
+	while ((irq = (*IXP2000_GPIO_INST & 0xff))) {
+		for (i = 0; i<=7;i++) {
+			if (irq & (1<<i)) {
+				do_IRQ(IRQ_IXP2000_GPIO0 + i,regs);
+			}
+		}
+	}
+}
+
+static struct irqaction GPIO_irq = {
+	name:           "GPIOs",
+	handler:        ixp_GPIO_demux,
+	flags:          SA_INTERRUPT
+};
+
+static void ixp_GPIO_irq_mask(unsigned int irq)
+{
+	ixp_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
+}
+
+static void ixp_GPIO_irq_unmask(unsigned int irq)
+{
+	ixp_reg_write(IXP2000_GPIO_INSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
+}
+
+static void ixp_PCI_irq_mask(unsigned int irq)
+{
+	unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE;
+	if (irq == IRQ_IXP2000_PCIA)
+		ixp_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 26)));
+	else if (irq == IRQ_IXP2000_PCIB)
+		ixp_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 27)));
+}
+
+static void ixp_PCI_irq_unmask(unsigned int irq)
+{
+	unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE;
+	if (irq == IRQ_IXP2000_PCIA)
+		ixp_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 26)));
+	else if (irq == IRQ_IXP2000_PCIB)
+		ixp_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 27)));
+}
+
+/*
+ * Error interrupts, this should be generic ixp2000 code
+ */
+static void ixp_err_demux(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int i;
+	while ((irq = (*IXP2000_IRQ_ERR_STATUS))) {
+		for (i=0; i<=26; i++) {
+			if (irq & (1 << i)) {
+				do_IRQ(IRQ_IXP2000_DRAM0_MIN_ERR + i, regs);
+			}
+		}
+	}
+}
+
+struct irqaction ERR_irq = {
+	name: "Error IRQs",
+	handler: ixp_err_demux,
+	flags: SA_INTERRUPT
+};
+
+static void ixp_ERR_irq_mask(unsigned int irq)
+{
+	*IXP2000_IRQ_ERR_ENABLE_CLR = (1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR));
+}
+
+static void ixp_ERR_irq_unmask(unsigned int irq)
+{
+	*IXP2000_IRQ_ERR_ENABLE_SET = (1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR));
+}
+
+
+void __init ixp2000_init_irq(void)
+{
+	int irq;
+
+	/*
+	 * Mask all sources
+	 */
+	ixp_reg_write(IXP2000_IRQ_ENABLE_CLR, 0xffffffff);
+	ixp_reg_write(IXP2000_FIQ_ENABLE_CLR, 0xffffffff);
+
+	/* clear all GPIO edge/level detects */
+	ixp_reg_write(IXP2000_GPIO_REDR, 0);
+	ixp_reg_write(IXP2000_GPIO_FEDR, 0);
+	ixp_reg_write(IXP2000_GPIO_LSHR, 0);
+	ixp_reg_write(IXP2000_GPIO_LSLR, 0);
+	ixp_reg_write(IXP2000_GPIO_INCR, -1);
+
+	/* clear PCI interrupt sources */
+	ixp_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, 0);
+
+	/*
+	 * Certain bits in the IRQ status register of the 
+	 * IXP2000 are reserved. Instead of trying to map
+	 * things non 1:1 from bit position to IRQ number,
+	 * we mark the reserved IRQs as invalid. This makes
+	 * our mask/unmask code much simpler.
+	 */
+	for (irq = IRQ_IXP2000_SWI; irq <= IRQ_IXP2000_THDB3; irq++) {
+		if((1 << irq) & IXP2000_VALID_IRQ_MASK) {
+			irq_desc[irq].valid     = 1;
+			irq_desc[irq].probe_ok  = 0;
+			irq_desc[irq].mask_ack  = ixp_irq_mask;
+			irq_desc[irq].mask      = ixp_irq_mask;
+			irq_desc[irq].unmask    = ixp_irq_unmask;
+		} else irq_desc[irq].valid = 0;
+	}
+	
+	/*
+	 * GPIO IRQs are invalid until someone sets the interrupt mode
+	 * by calling gpio_line_set();
+	 */
+	for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) {
+		irq_desc[irq].valid     = 0;
+		irq_desc[irq].probe_ok  = 1;
+		irq_desc[irq].mask_ack  = ixp_GPIO_irq_mask;
+		irq_desc[irq].mask      = ixp_GPIO_irq_mask;
+		irq_desc[irq].unmask    = ixp_GPIO_irq_unmask;
+	}
+	setup_arm_irq(IRQ_IXP2000_GPIO, &GPIO_irq);
+
+	/*
+	 * Enable PCI irq
+	 */
+	*(IXP2000_IRQ_ENABLE_SET) = (1 << IRQ_IXP2000_PCI);
+	for (irq = IRQ_IXP2000_PCIA; irq <= IRQ_IXP2000_PCIB; irq++) {
+		irq_desc[irq].valid     = 1;
+		irq_desc[irq].probe_ok  = 0;
+		irq_desc[irq].mask_ack  = ixp_PCI_irq_mask;
+		irq_desc[irq].mask      = ixp_PCI_irq_mask;
+		irq_desc[irq].unmask    = ixp_PCI_irq_unmask;
+	}
+
+	for (irq = IRQ_IXP2000_DRAM0_MIN_ERR; irq <= IRQ_IXP2000_SP_INT; irq++) {
+		irq_desc[irq].valid     = 1;
+		irq_desc[irq].probe_ok  = 0;
+		irq_desc[irq].mask_ack  = ixp_ERR_irq_mask;
+		irq_desc[irq].mask      = ixp_ERR_irq_mask;
+		irq_desc[irq].unmask    = ixp_ERR_irq_unmask;
+	}       
+	setup_arm_irq(IRQ_IXP2000_ERRSUM, &ERR_irq);
+
+}
diff -urN linux-2.4.29/arch/arm/mach-ixp2000/ixp2000-kgdb.c linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixp2000-kgdb.c
--- linux-2.4.29/arch/arm/mach-ixp2000/ixp2000-kgdb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixp2000-kgdb.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,108 @@
+/*
+ * arch/arm/mach-ixp2000/ixp2000-irq.c
+ *
+ * Low level kgdb code for the IXP2000 board
+ *
+ * Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ *
+ * Copyright 2002 Intel Corp.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+
+#include <asm/atomic.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+
+#include <asm/kgdb.h>
+#include <asm/serial.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+
+/* Standard COM flags */
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+#undef BASE_BAUD
+#undef RS_TABLE_SIZE  
+
+/*
+ * IXP2400 uses 50MHz clock for uart
+ */
+
+#define BASE_BAUD ( 50000000 / 16 )
+
+#define RS_TABLE_SIZE   1
+
+#define STD_SERIAL_PORT_DEFNS                           \
+        {                                               \
+          magic: 0,                                     \
+          baud_base: BASE_BAUD,                         \
+          irq: IRQ_IXP2000_UART,                        \
+          flags: STD_COM_FLAGS,                         \
+          iomem_base: IXP2000_UART_BASE,                     \
+          io_type: SERIAL_IO_MEM                        \
+        } /* ttyS0 */
+
+
+static struct serial_state ports[RS_TABLE_SIZE] = {
+	SERIAL_PORT_DFNS
+};
+
+static short port = 0;
+static volatile unsigned char *serial_base = NULL;
+
+void kgdb_serial_init(void)
+{
+
+	// TODO: Make port number a config or cmdline option
+	port = 1;
+
+	serial_base = ports[port].iomem_base;	
+
+	serial_base[UART_LCR] = 0x80; /* enable access to divisor reg */
+	serial_base[UART_DLL] = 0x36; /*divisor latch LSB baud rate 57600 */
+	serial_base[UART_DLM] = 0; /* divisor latch MSB */
+	serial_base[UART_LCR] = 0x03; /* 8 data, 1 stop bit, no parity */
+	serial_base[UART_FCR] = 0x07; /* turn FIFOs on */
+	serial_base[UART_IER] = 40; /* enable UART and disable interrupts */
+
+	return;
+}
+
+void kgdb_serial_putchar(unsigned char ch)
+{
+	unsigned char status;
+
+	do
+	{
+		status = serial_base[UART_LSR];
+	} while ((status & (UART_LSR_TEMT|UART_LSR_THRE)) !=
+			(UART_LSR_TEMT|UART_LSR_THRE));
+
+	*serial_base = ch;
+}
+
+unsigned char kgdb_serial_getchar(void)
+{
+	unsigned char ch;
+
+	while(!(serial_base[UART_LSR] & 0x1));
+
+	ch = *serial_base;
+
+	return ch;
+}
+
diff -urN linux-2.4.29/arch/arm/mach-ixp2000/ixp2000-pci.c linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixp2000-pci.c
--- linux-2.4.29/arch/arm/mach-ixp2000/ixp2000-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp2000/ixp2000-pci.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,307 @@
+/*
+ * arch/arm/mach-ixp2000/ixp2000-pci.c
+ *
+ * PCI routines for IXDP2400/IXDP2800 boards
+ *
+ * Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ *
+ * Copyright 2002 Intel Corp.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/pci.h>
+//#include <asm/arch/pci_auto.h>
+#include <asm/arch/pci-bridge.h>
+
+static int pci_master_aborts = 0;
+
+// #define DEBUG 1
+
+#ifdef DEBUG 
+#define DBG(x...)	printk(x)
+#else
+#define DBG(x...)
+#endif /* DEBUG */
+
+
+int clear_master_aborts(void);
+
+static u32* 
+ixp2000_pci_config_setup(struct pci_dev *dev, int where)
+{
+	u32 *paddress;
+
+	if ( PCI_SLOT(dev->devfn) > 7 ) 
+		return 0;
+
+	/* Must be dword aligned */
+
+	where &= ~3;
+
+	/*
+	 * For top bus, generate type 0, else type 1
+	 */
+	if(!dev->bus->number) {
+		/* only bits[23:16] are used for IDSEL */
+		paddress = (u32 *)(PCI_CFG0_VIRT_BASE 
+				| (1 << (PCI_SLOT(dev->devfn)+16)) 
+				| (PCI_FUNC(dev->devfn) << 8) | where);
+	} else {
+		paddress = (u32 *)(PCI_CFG1_VIRT_BASE 
+				| (dev->bus->number << 16) 
+				| (PCI_SLOT(dev->devfn) << 11) 
+				| (PCI_FUNC(dev->devfn) << 8) | where | 0);
+	}
+
+	return paddress;
+}
+
+static int
+ixp2000_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	u32 *address;
+
+	DBG("In config_read_byte %d from dev %d:%d:%d\n", where, 
+			dev->bus->number, PCI_SLOT(dev->devfn),
+				PCI_FUNC(dev->devfn));
+
+	address = ixp2000_pci_config_setup(dev, where);
+
+	if ( !address ) { 
+		*value = 0xff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	}
+
+	*value = (u8)(((*address) >> ((where % 0x04) * 8)) & 0xff);
+	if (pci_master_aborts) {
+		pci_master_aborts = 0;
+		*value = 0xff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+ixp2000_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	u32 *address;
+
+	DBG("config_read_word %d from dev %d:%d:%d\n", where, 
+			dev->bus->number, PCI_SLOT(dev->devfn),
+				PCI_FUNC(dev->devfn));
+
+	address = ixp2000_pci_config_setup(dev, where);
+
+	if ( !address ) { 
+		*value = 0xffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	}
+	*value = (u16)(((*address) >> ((where % 0x04) *8)) & 0xffff);
+	
+	if (pci_master_aborts) {
+		pci_master_aborts = 0;
+		*value = 0xffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+ixp2000_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	u32 *address;
+
+	DBG("config_read_dword %d from dev %d:%d:%d\n", where, 
+			dev->bus->number, PCI_SLOT(dev->devfn),
+				PCI_FUNC(dev->devfn));
+
+	address = ixp2000_pci_config_setup(dev, where);
+
+	if ( !address ) { 
+		*value = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	}
+	*value = *address;
+	
+	if (pci_master_aborts) {
+		pci_master_aborts = 0;
+		*value = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * We don't do error checking on the address for writes.
+ * It's assumed that the user checked for the device existing first
+ * by doing a read first.
+ */
+static int 
+ixp2000_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	u32 *address;
+	u32 mask;
+	u32 temp;
+
+	address = ixp2000_pci_config_setup(dev, where);
+
+	mask = ~(0x000000ff << ((where % 0x4) * 8));
+	temp = (u32)(((u32)value) << ((where % 0x4) *8));
+	*address = (*address & mask) | temp;
+
+	clear_master_aborts(); 
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int 
+ixp2000_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	u32 *address;
+	u32 mask;
+	u32 temp;
+
+	address = ixp2000_pci_config_setup(dev, where);
+
+	mask = ~(0x0000ffff << ((where % 0x4) * 8));
+	temp = (u32)(((u32)value) << ((where % 0x4) * 8));
+	*address = (*address & mask) | temp;
+
+	clear_master_aborts(); 
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+ixp2000_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	u32 *address;
+
+	address = ixp2000_pci_config_setup(dev, where);
+
+	*address = value;
+	clear_master_aborts(); 
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops ixp2000_ops = {
+	ixp2000_read_config_byte,
+	ixp2000_read_config_word,
+	ixp2000_read_config_dword,
+	ixp2000_write_config_byte,
+	ixp2000_write_config_word,
+	ixp2000_write_config_dword,
+};
+
+int
+abort_handler(unsigned long addr, unsigned long fsr, struct pt_regs *regs) 
+{
+      
+	volatile u32 temp;
+
+	pci_master_aborts = 1; 
+	
+	cli();
+	temp = *(IXP2000_PCI_CONTROL);
+	if (temp & ((1<<8) | (1<<5))) {  /* master abort and cmd tgt err */
+		*(IXP2000_PCI_CONTROL) = temp;
+	}
+
+	temp = *(IXP2000_PCI_CMDSTAT);
+	if (temp & (1<<29) ) {
+		while (temp & (1<<29) ) {/* Rx_MA recv abort with master*/
+			*(IXP2000_PCI_CMDSTAT) = temp;
+			temp = *(IXP2000_PCI_CMDSTAT);
+		}
+	}
+
+	/*
+	 * If it was an imprecise abort, then we need to correct the
+	 * return address to be _after_ the instruction.
+	 */
+	if (fsr & (1 << 10))
+		regs->ARM_pc += 4;
+
+	sti();
+
+	return 0;
+}
+
+
+int clear_master_aborts(void)
+{
+	volatile u32 temp;
+
+	cli();
+	temp = *(IXP2000_PCI_CONTROL);
+	if (temp & ((1<<8) | (1<<5))) {  /* master abort and cmd tgt err */
+		*(IXP2000_PCI_CONTROL) = temp;
+	}
+
+	temp = *(IXP2000_PCI_CMDSTAT);
+	if (temp & (1<<29) ) {
+		while (temp & (1<<29) ) {/* Rx_MA recv abort with master*/
+			*(IXP2000_PCI_CMDSTAT) = temp;
+			temp = *(IXP2000_PCI_CMDSTAT);
+		}
+	}
+	sti();
+
+	return 0;
+}
+
+void __init ixp2000_pci_init(void *sysdata)
+{
+	/* hook in our fault handler for PCI errors */
+	hook_fault_code(4, abort_handler, SIGBUS, "external abort on line fetch\n");
+	hook_fault_code(6, abort_handler, SIGBUS, "external abort on line fetch\n");
+	hook_fault_code(8, abort_handler, SIGBUS, "external abort on non-line fetch\n");
+	hook_fault_code(10, abort_handler, SIGBUS, "external abort on non-line fetch\n");
+	
+	DBG("ixp200_pci_init Done\n");
+}
+
+#define EARLY_PCI_OP(rw, size, type)					\
+int early_##rw##_config_##size(struct pci_controller *hose, int bus,	\
+		int devfn, int offset, type value)	\
+{									\
+	return ixp2000_##rw##_config_##size(fake_pci_dev(hose, bus, devfn),	\
+			offset, value);			\
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
+
diff -urN linux-2.4.29/arch/arm/mach-ixp2000/Makefile linux-2.4.29-uc1/arch/arm/mach-ixp2000/Makefile
--- linux-2.4.29/arch/arm/mach-ixp2000/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp2000/Makefile	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,29 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= ixp2000.o
+
+# Object file lists.
+
+obj-y			:= arch.o mm.o ixp2000-irq.o ixp2000-pci.o pci.o time.o slowport.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= ixasdk.o
+
+obj-$(CONFIG_ARCH_IXDP2400)	+= ixdp2400-irq.o ixdp2400-pci.o
+
+obj-$(CONFIG_ARCH_IXDP2800)	+= ixdp2800-irq.o ixdp2800-pci.o pci-auto.o
+
+obj-$(CONFIG_IXP2000_SLAVE)	+= ixmb2400-slave.o 
+
+obj-$(CONFIG_KGDB)      	+= ixp2000-kgdb.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/arm/mach-ixp2000/mm.c linux-2.4.29-uc1/arch/arm/mach-ixp2000/mm.c
--- linux-2.4.29/arch/arm/mach-ixp2000/mm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp2000/mm.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,137 @@
+/*
+ * linux/arch/arm/mach-ixp2000/mm.c
+ *
+ * Copyright (C) 2002 Intel Corp.
+ * Copyright (C) 2003 MontaVista Software, Inc.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+
+
+/*
+ * Chip specific mappings shared by all IXP2000 systems
+ */
+static struct map_desc ixp2000_io_desc[] __initdata = {
+	{
+		GLOBAL_REG_VIRT_BASE,
+		GLOBAL_REG_PHYS_BASE,
+		GLOBAL_REG_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0
+	},
+	{
+		GPIO_VIRT_BASE,
+		GPIO_PHYS_BASE,
+		GPIO_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0
+	},
+	{
+		TIMER_VIRT_BASE,
+		TIMER_PHYS_BASE,
+		TIMER_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0
+	},
+	{
+		UART_VIRT_BASE,
+		UART_PHYS_BASE,
+		UART_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0
+	},
+	{
+		SLOWPORT_CSR_VIRT_BASE,
+		SLOWPORT_CSR_PHYS_BASE,
+		SLOWPORT_CSR_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0
+	},
+	{
+		INTCTL_VIRT_BASE,
+		INTCTL_PHYS_BASE,
+		INTCTL_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0
+	},
+	{
+		PCI_CREG_VIRT_BASE,
+		PCI_CREG_PHYS_BASE,
+		PCI_CREG_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0
+	},
+	{
+		PCI_CSR_VIRT_BASE,
+		PCI_CSR_PHYS_BASE,
+		PCI_CSR_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0
+	},
+	{
+		PCI_CFG0_VIRT_BASE,
+		PCI_CFG0_PHYS_BASE,
+		PCI_CFG0_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0
+	},
+	{
+		PCI_CFG1_VIRT_BASE,
+		PCI_CFG1_PHYS_BASE,
+		PCI_CFG1_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0
+	},
+	{
+		PCI_IO_VIRT_BASE,
+		PCI_IO_PHYS_BASE,
+		PCI_IO_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0
+	},
+	LAST_DESC
+};
+
+
+/*
+ * Board specific mappings
+ */
+#ifdef CONFIG_ARCH_IXDP2400
+static struct map_desc ixdp2400_io_desc[] __initdata = {
+	{ 
+		IXDP2400_VIRT_CPLD_BASE, 
+		IXDP2400_PHY_CPLD_BASE,
+		IXDP2400_CPLD_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0 
+	},
+	LAST_DESC
+};
+
+void __init ixdp2400_map_io(void)
+{
+	iotable_init(ixp2000_io_desc);
+
+	iotable_init(ixdp2400_io_desc);
+}
+#endif
+
+#ifdef CONFIG_ARCH_IXDP2800
+static struct map_desc ixdp2800_io_desc[] __initdata = {
+	{
+		IXDP2800_VIRT_CPLD_BASE,
+		IXDP2800_PHY_CPLD_BASE,
+		IXDP2800_CPLD_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0
+	},
+	LAST_DESC
+};
+void __init ixdp2800_map_io(void)
+{
+	iotable_init(ixp2000_io_desc);
+
+	iotable_init(ixdp2800_io_desc);
+}
+#endif
diff -urN linux-2.4.29/arch/arm/mach-ixp2000/pci-auto.c linux-2.4.29-uc1/arch/arm/mach-ixp2000/pci-auto.c
--- linux-2.4.29/arch/arm/mach-ixp2000/pci-auto.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp2000/pci-auto.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,379 @@
+/*
+ * arch/arm/mach-ixp2000/pci-auto.c
+ * 
+ * PCI autoconfiguration library
+ *
+ * Author: Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/arch/pci-bridge.h>
+#include <asm/arch/pci.h>
+#include <asm/arch/pci_auto.h>
+
+// #define DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif /* DEBUG */
+
+static int pciauto_upper_iospc;
+static int pciauto_upper_memspc;
+
+void pciauto_setup_bars(struct pci_controller *hose,
+		int current_bus,
+		int pci_devfn,
+		int bar_limit)
+{
+	int bar_response, bar_size, bar_value;
+	int bar, addr_mask, bar_nr = 0;
+	int * upper_limit;
+	int found_mem64 = 0;
+
+	DBG("PCI Autoconfig: Found Bus %d, Device %d, Function %d\n",
+		current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn) );
+
+	for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4)
+	{
+		/* Tickle the BAR and get the response */
+		early_write_config_dword(hose,
+				current_bus,
+				pci_devfn,
+				bar,
+				0xffffffff);
+		early_read_config_dword(hose,
+				current_bus,
+				pci_devfn,
+				bar,
+				&bar_response);
+
+		/* If BAR is not implemented go to the next BAR */
+		if (!bar_response)
+			continue;
+
+		/* Check the BAR type and set our address mask */
+		if (bar_response & PCI_BASE_ADDRESS_SPACE)
+		{
+			addr_mask = PCI_BASE_ADDRESS_IO_MASK;
+			upper_limit = &pciauto_upper_iospc;
+			DBG("PCI Autoconfig: BAR %d, I/O, ", bar_nr);
+		}
+		else
+		{
+			if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+			PCI_BASE_ADDRESS_MEM_TYPE_64)
+				found_mem64 = 1;
+
+			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;		
+			upper_limit = &pciauto_upper_memspc;
+			DBG("PCI Autoconfig: BAR %d, Mem, ", bar_nr);
+		}
+
+		/* Calculate requested size */
+		bar_size = ~(bar_response & addr_mask) + 1;
+
+		/* Allocate a base address */
+		bar_value = (*upper_limit - bar_size) & ~(bar_size - 1);
+
+		/* Write it out and update our limit */
+		early_write_config_dword(hose,
+				current_bus,
+				pci_devfn,
+				bar,
+				bar_value);
+
+		*upper_limit = bar_value;
+
+		/*
+		 * If we are a 64-bit decoder then increment to the
+		 * upper 32 bits of the bar and force it to locate
+		 * in the lower 4GB of memory.
+		 */ 
+		if (found_mem64)
+		{
+			bar += 4;
+			early_write_config_dword(hose,
+					current_bus,
+					pci_devfn,
+					bar,
+					0x00000000);
+		}
+
+		bar_nr++;
+
+		DBG("size=0x%x, address=0x%x\n",
+			bar_size, bar_value);
+	}
+
+}
+
+void pciauto_prescan_setup_bridge(struct pci_controller *hose,
+		int current_bus,
+		int pci_devfn,
+		int sub_bus,
+		int *iosave,
+		int *memsave)
+{
+	/* Configure bus number registers */
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_PRIMARY_BUS,
+			current_bus);
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_SECONDARY_BUS,
+			sub_bus + 1);
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_SUBORDINATE_BUS,
+			0xff);
+
+	/* Round memory allocator to 1MB boundary */
+	pciauto_upper_memspc &= ~(0x100000 - 1);
+	*memsave = pciauto_upper_memspc;
+
+	/* Round I/O allocator to 4KB boundary */
+	pciauto_upper_iospc &= ~(0x1000 - 1);
+	*iosave = pciauto_upper_iospc;
+
+	/* Set up memory and I/O filter limits, assume 32-bit I/O space */
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_MEMORY_LIMIT,
+			((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_LIMIT,
+			((pciauto_upper_iospc - 1) & 0x0000f000) >> 8);
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_LIMIT_UPPER16,
+			((pciauto_upper_iospc - 1) & 0xffff0000) >> 16);
+}
+
+void pciauto_postscan_setup_bridge(struct pci_controller *hose,
+		int current_bus,
+		int pci_devfn,
+		int sub_bus,
+		int *iosave,
+		int *memsave)
+{
+	int cmdstat;
+
+	/* Configure bus number registers */
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_SUBORDINATE_BUS,
+			sub_bus);
+
+	/*
+	 * Round memory allocator to 1MB boundary.
+	 * If no space used, allocate minimum.
+	 */
+	pciauto_upper_memspc &= ~(0x100000 - 1);
+	if (*memsave == pciauto_upper_memspc)
+		pciauto_upper_memspc -= 0x00100000;
+
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_MEMORY_BASE,
+			pciauto_upper_memspc >> 16);
+
+	/* Allocate 1MB for pre-fretch */
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_PREF_MEMORY_LIMIT,
+			((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
+
+	pciauto_upper_memspc -= 0x100000;
+
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_PREF_MEMORY_BASE,
+			pciauto_upper_memspc >> 16);
+
+	/* Round I/O allocator to 4KB boundary */
+	pciauto_upper_iospc &= ~(0x1000 - 1);
+	if (*iosave == pciauto_upper_iospc)
+		pciauto_upper_iospc -= 0x1000;
+
+	DBG("PCI Autoconfig: Bridge %d. IO_FILTER = %#010x..%#010x\n",
+			current_bus, 
+			(pciauto_upper_iospc & 0x0000f000) >> 8,
+			pciauto_upper_iospc >> 16);
+
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_BASE,
+			(pciauto_upper_iospc & 0x0000f000) >> 8);
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_BASE_UPPER16,
+			pciauto_upper_iospc >> 16);
+	
+	/* Enable memory and I/O accesses, enable bus master */
+	early_read_config_dword(hose,
+			current_bus,
+			pci_devfn,
+			PCI_COMMAND,
+			&cmdstat);
+	early_write_config_dword(hose,
+			current_bus,
+			pci_devfn,
+			PCI_COMMAND,
+			cmdstat |
+			PCI_COMMAND_IO |
+			PCI_COMMAND_MEMORY |
+			PCI_COMMAND_MASTER);
+}
+
+int pciauto_bus_scan(struct pci_controller *hose, int current_bus)
+{
+	int sub_bus, pci_devfn, pci_class, cmdstat, found_multi=0;
+	unsigned short vid;
+	unsigned char header_type;
+
+	/*
+	 * Fetch our I/O and memory space upper boundaries used
+	 * to allocated base addresses on this hose.
+	 */
+	if (current_bus == hose->first_busno)
+	{
+		pciauto_upper_iospc = hose->io_space.end + 1;
+		pciauto_upper_memspc = hose->mem_space.end + 1;
+	}
+
+	sub_bus = current_bus;
+
+	for (pci_devfn=0; pci_devfn<0xff; pci_devfn++)
+	{
+		/* Skip our host bridge */
+		if ( (current_bus == hose->first_busno) && (pci_devfn == 0) )
+			continue;
+
+		if (PCI_FUNC(pci_devfn) && !found_multi)
+			continue;
+
+		/* If config space read fails from this device, move on */
+		if (early_read_config_byte(hose,
+				current_bus,
+				pci_devfn,
+				PCI_HEADER_TYPE,
+				&header_type))
+			continue;
+
+		if (!PCI_FUNC(pci_devfn))
+			found_multi = header_type & 0x80;
+
+		early_read_config_word(hose,
+				current_bus,
+				pci_devfn,
+				PCI_VENDOR_ID,
+				&vid);
+
+		if (vid != 0xffff)
+		{
+			early_read_config_dword(hose,
+					current_bus,
+					pci_devfn,
+					PCI_CLASS_REVISION, &pci_class);
+			if ( (pci_class >> 16) == PCI_CLASS_BRIDGE_PCI )
+			{
+				int iosave, memsave;
+
+				DBG("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_SLOT(pci_devfn));
+				/* Allocate PCI I/O and/or memory space */
+				pciauto_setup_bars(hose,
+						current_bus,
+						pci_devfn,
+						PCI_BASE_ADDRESS_1);
+
+				pciauto_prescan_setup_bridge(hose,
+						current_bus,
+						pci_devfn,
+						sub_bus,
+						&iosave,
+						&memsave);
+				sub_bus = pciauto_bus_scan(hose, sub_bus+1);
+				pciauto_postscan_setup_bridge(hose,
+						current_bus,
+						pci_devfn,
+						sub_bus,
+						&iosave,
+						&memsave);
+			}
+			else
+			{
+				if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE)
+				{
+					unsigned char prg_iface;
+
+					early_read_config_byte(hose,
+							current_bus,
+							pci_devfn,
+							PCI_CLASS_PROG,
+							&prg_iface);
+					if (!(prg_iface & PCIAUTO_IDE_MODE_MASK))
+					{
+						DBG("PCI Autoconfig: Skipping legacy mode IDE controller\n");
+						continue;
+					}
+				}
+
+				/*
+				 * Found a peripheral, enable some standard
+				 * settings
+				 */
+				early_read_config_dword(hose,
+						current_bus,
+						pci_devfn,
+						PCI_COMMAND,
+						&cmdstat);
+				early_write_config_dword(hose,
+						current_bus,
+						pci_devfn,
+						PCI_COMMAND,
+						cmdstat |
+						PCI_COMMAND_IO |
+						PCI_COMMAND_MEMORY |
+						PCI_COMMAND_MASTER);
+				early_write_config_byte(hose,
+						current_bus,
+						pci_devfn,
+						PCI_LATENCY_TIMER,
+						0x80);
+
+				/* Allocate PCI I/O and/or memory space */
+				pciauto_setup_bars(hose,
+						current_bus,
+						pci_devfn,
+						PCI_BASE_ADDRESS_5);
+			}
+		}
+	}
+	return sub_bus;
+}
diff -urN linux-2.4.29/arch/arm/mach-ixp2000/pci.c linux-2.4.29-uc1/arch/arm/mach-ixp2000/pci.c
--- linux-2.4.29/arch/arm/mach-ixp2000/pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp2000/pci.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,249 @@
+/*
+ * arch/arm/mach-ixdp2400/pci.c
+ *
+ * Generic PCI support functionality that should eventually move to
+ * arch/arm/kernel/bios32.c.  Derived from support in ppc and alpha.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/pci-bridge.h>
+
+#define DEBUG 1 
+
+#ifdef DEBUG
+#define  DBG(x...) printk(x)
+#else
+#define  DBG(x...)
+#endif
+
+struct pci_controller* hose_head;
+struct pci_controller** hose_tail = &hose_head;
+
+/*
+ * The following code swizzles for exactly one bridge.  The routine
+ * common_swizzle below handles multiple bridges.  But there are a
+ * some boards that don't follow the PCI spec's suggestion so we
+ * break this piece out separately.
+ */
+static inline u8
+bridge_swizzle(u8 pin, u8 slot)
+{
+	return (((pin-1) + slot) % 4) + 1;
+}
+
+u8 __init
+common_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	struct pci_controller *hose;
+	
+	hose = pci_bus_to_hose(dev->bus->number);
+
+	if (dev->bus->number != hose->first_busno) {
+		u8 pin = *pinp;
+		do {
+			pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+			/* Move up the chain of bridges. */
+			dev = dev->bus->self;
+		} while (dev->bus->self);
+		*pinp = pin;
+
+		/* The slot is the slot of the last bridge. */
+	}
+
+	return PCI_SLOT(dev->devfn);
+}
+
+/*
+ * Null PCI config access functions, for the case when we can't
+ * find a hose.
+ */
+#define NULL_PCI_OP(rw, size, type)					\
+static int								\
+null_##rw##_config_##size(struct pci_dev *dev, int offset, type val)	\
+{									\
+	return PCIBIOS_DEVICE_NOT_FOUND;    				\
+}
+
+	NULL_PCI_OP(read, byte, u8 *)
+	NULL_PCI_OP(read, word, u16 *)
+	NULL_PCI_OP(read, dword, u32 *)
+	NULL_PCI_OP(write, byte, u8)
+	NULL_PCI_OP(write, word, u16)
+NULL_PCI_OP(write, dword, u32)
+
+static struct pci_ops null_pci_ops =
+{
+	null_read_config_byte,
+	null_read_config_word,
+	null_read_config_dword,
+	null_write_config_byte,
+	null_write_config_word,
+	null_write_config_dword
+};
+
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+struct pci_dev *
+fake_pci_dev(struct pci_controller *hose, int busnr, int devfn)
+{
+	static struct pci_dev dev;
+	static struct pci_bus bus;
+
+	if (hose == 0) {
+		hose = pci_bus_to_hose(busnr);
+		if (hose == 0)
+			printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);
+	}
+	dev.bus = &bus;
+	dev.sysdata = hose;
+	dev.devfn = devfn;
+	bus.number = busnr;
+	bus.ops = hose? hose->ops: &null_pci_ops;
+	return &dev;
+}
+
+static int next_controller_index;
+
+struct pci_controller * __init
+pcibios_alloc_controller(void)
+{
+	struct pci_controller *hose;
+
+	hose = (struct pci_controller *)kmalloc(sizeof(*hose), GFP_KERNEL);
+	memset(hose, 0, sizeof(struct pci_controller));
+	
+	*hose_tail = hose;
+	hose_tail = &hose->next;
+
+	hose->index = next_controller_index++;
+
+	return hose;
+}
+	
+struct pci_controller *
+pci_bus_to_hose(int bus)
+{
+	struct pci_controller *hose = hose_head;
+
+	for (; hose; hose = hose->next)
+		if (bus >= hose->first_busno && bus <= hose->last_busno)
+			return hose;
+	return NULL;
+}
+
+void __init
+pci_exclude_device(unsigned char bus, unsigned char devfn)
+{
+	struct pci_dev *dev, *pdev = NULL;
+
+	/* Walk the pci device list */
+	pci_for_each_dev(dev)
+	{
+		if ((dev->bus->number == bus) && (dev->devfn == devfn))
+		{
+			/*
+			 * Remove the device from the global and
+			 * bus lists.
+			 */
+			list_del(&(dev->global_list));
+			list_del(&(dev->bus_list));
+
+			/* Free the pci_dev structure */
+			kfree(dev);
+
+			break;
+		}
+		pdev = dev;
+	}
+}
+
+static inline void __init alloc_resource(struct pci_dev *dev, int idx)
+{
+	struct resource *pr, *r = &dev->resource[idx];
+
+	pr = pci_find_parent_resource(dev, r);
+	if(!pr || request_resource(pr, r) < 0)
+	{
+		printk(KERN_ERR "PCI: Can not allocate resource region %d" \
+				" of device %s\n", idx, dev->slot_name);
+		r->end -= r->start;
+		r->start = 0;
+	}
+}
+
+void __init
+pcibios_allocate_bus_resources(struct list_head *bus_list)
+{
+	struct list_head *ln;
+	struct pci_bus *bus;
+	int i;
+	struct resource *res, *pr;
+
+	if(!bus_list) return; 
+
+	/* Depth-First Search on bus tree */
+	for (ln = bus_list->next; ln != bus_list; ln=ln->next) {
+		bus = pci_bus_b(ln);
+		pci_read_bridge_bases(bus);
+		for (i = 0; i < 4; ++i) {
+			if ((res = bus->resource[i]) == NULL || !res->flags)
+				continue;
+			if (bus->parent == NULL)
+				pr = (res->flags & IORESOURCE_IO)?
+					&ioport_resource: &iomem_resource;
+			else
+				pr = pci_find_parent_resource(bus->self, res);
+
+			if (pr && request_resource(pr, res) == 0)
+				continue;
+			printk(KERN_ERR "PCI: Can not allocate resource region "
+			       "%d of PCI bridge %d\n", i, bus->number);
+			DBG("PCI: resource is %lx..%lx (%lx)\n",
+					res->start, res->end, res->flags);
+		}
+		pcibios_allocate_bus_resources(&bus->children);
+	}
+}
+
+void __init pcibios_allocate_resources(void)
+{
+	struct pci_dev *dev;
+	int idx, disabled;
+	u16 command;
+	struct resource *r;
+
+	pci_for_each_dev(dev)
+	{
+		pci_read_config_word(dev, PCI_COMMAND, &command);
+		for(idx = 0; idx < 6; idx++)
+		{
+			r = &dev->resource[idx];
+
+			if(r->parent)
+				continue;
+			if(!r->start)
+				continue;
+
+			alloc_resource(dev, idx);
+		}
+	}
+}
+
diff -urN linux-2.4.29/arch/arm/mach-ixp2000/slowport.c linux-2.4.29-uc1/arch/arm/mach-ixp2000/slowport.c
--- linux-2.4.29/arch/arm/mach-ixp2000/slowport.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp2000/slowport.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,57 @@
+/*
+ * arch/arm/mach-ixp2000/slowport.c
+ *
+ * Slowport access functions.  We could make these inlines, but then
+ * we would have a global spinlock floating around and that's ugly.
+ *
+ * Copyright (c) 2002 MontaVista Software, Inc.
+ */
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <asm/system.h>
+#include <asm/hardware.h>
+
+static spinlock_t slowport_lock = SPIN_LOCK_UNLOCKED;
+static struct slowport_cfg old_cfg;
+static unsigned long flags;
+
+/*
+ * The only reason we need to save/restore the state is b/c
+ * the CCR register affects the state of both device 1 and
+ * device 2.  This means that we could really screw up the
+ * flash access if the CCR is not restored.
+ */
+void acquire_slowport(struct slowport_cfg *new_cfg)
+{
+	spin_lock_irqsave(&slowport_lock, flags);
+
+	old_cfg.CCR = *IXP2000_SLOWPORT_CCR;
+	old_cfg.WTC = *IXP2000_SLOWPORT_WTC2;
+	old_cfg.RTC = *IXP2000_SLOWPORT_RTC2;
+	old_cfg.PCR = *IXP2000_SLOWPORT_PCR;
+	old_cfg.ADC = *IXP2000_SLOWPORT_ADC;
+
+	ixp_reg_write(IXP2000_SLOWPORT_CCR, new_cfg->CCR);
+	ixp_reg_write(IXP2000_SLOWPORT_WTC2, new_cfg->WTC);
+	ixp_reg_write(IXP2000_SLOWPORT_RTC2, new_cfg->RTC);
+	ixp_reg_write(IXP2000_SLOWPORT_PCR, new_cfg->PCR);
+	ixp_reg_write(IXP2000_SLOWPORT_ADC, new_cfg->ADC);
+}
+
+void release_slowport(void)
+{
+	ixp_reg_write(IXP2000_SLOWPORT_CCR, old_cfg.CCR);
+	ixp_reg_write(IXP2000_SLOWPORT_WTC2, old_cfg.WTC);
+	ixp_reg_write(IXP2000_SLOWPORT_RTC2, old_cfg.RTC);
+	ixp_reg_write(IXP2000_SLOWPORT_PCR, old_cfg.PCR);
+	ixp_reg_write(IXP2000_SLOWPORT_ADC, old_cfg.ADC);
+
+	spin_unlock_irqrestore(&slowport_lock, flags);
+}
+
+
diff -urN linux-2.4.29/arch/arm/mach-ixp2000/time.c linux-2.4.29-uc1/arch/arm/mach-ixp2000/time.c
--- linux-2.4.29/arch/arm/mach-ixp2000/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp2000/time.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,108 @@
+/*
+ * arch/arm/mach-ixp2000/time.c
+ *
+ * Original Authors: Naeem M Afzal <naeem.m.afzal@intel.com>
+ *                   Jeff Daly <jeffrey.daly@intel.com
+ *
+ * IXP2000 timer code
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (c) 2002-2003 Intel Corp.
+ * Copyright (c) 2003 MontaVista Software, Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your 
+ *  option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/timex.h>
+#include <asm/hardware.h>
+
+#include <asm/mach-types.h>
+
+
+#ifdef CONFIG_LEDS_TIMER
+extern void do_leds(void);
+#endif
+
+static unsigned ticks_per_jiffy;
+static unsigned ticks_per_usec;
+
+static inline unsigned long ixdp2400_ext_oscillator(void)
+{
+	int numerator, denominator;
+	int denom_array[] = {2, 4, 8, 16, 1, 2, 4, 8};
+
+	numerator = (*(IXDP2400_CPLD_SYS_CLK_M) & 0xFF) *2;
+	denominator = denom_array[(*(IXDP2400_CPLD_SYS_CLK_N) & 0x7)];
+
+	return   ((3125000 * numerator) / (denominator));
+}
+
+static unsigned long ixp2000_gettimeoffset (void)
+{
+	unsigned long elapsed;
+
+	/* Get ticks since last perfect jiffy */
+	elapsed = ticks_per_jiffy - *IXP2000_T1_CSR;
+
+	return elapsed / ticks_per_usec;
+}
+static void ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long flags;
+
+	/* clear timer 1 */
+	ixp_reg_write(IXP2000_T1_CLR, 1);
+
+#ifdef CONFIG_LEDS_TIMER
+	do_leds();
+#endif
+	do_timer(regs);
+}
+
+static struct irqaction ixp2000_timer_irq = {
+
+	handler:ixp2000_timer_interrupt,
+	name:"timer tick",
+};
+
+extern unsigned long (*gettimeoffset)(void);
+extern int setup_arm_irq(int, struct irqaction *);
+
+void setup_timer (void)
+{
+	gettimeoffset = ixp2000_gettimeoffset;
+
+	ixp_reg_write(IXP2000_T1_CLR, 0);
+
+	if(machine_is_ixdp2800()) {		// Default 50MhZ APB
+		ticks_per_jiffy = LATCH;
+		ticks_per_usec = CLOCK_TICK_RATE / 1000000;
+	} else if (machine_is_ixdp2400()) {
+		ticks_per_jiffy = ((ixdp2400_ext_oscillator()/2) + HZ/2) / HZ;
+		ticks_per_usec = (ixdp2400_ext_oscillator()/2) / 1000000;
+	}
+
+	ixp_reg_write(IXP2000_T1_CLD, ticks_per_jiffy);
+	ixp_reg_write(IXP2000_T1_CTL, (1 << 7));
+
+	/* register for interrupt */
+	setup_arm_irq(IRQ_IXP2000_TIMER1, &ixp2000_timer_irq);
+}
+
diff -urN linux-2.4.29/arch/arm/mach-ixp425/arch.c linux-2.4.29-uc1/arch/arm/mach-ixp425/arch.c
--- linux-2.4.29/arch/arm/mach-ixp425/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/arch.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,180 @@
+/*
+ * arch/arm/mach-ixp425/arch.c 
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+extern void ixp425_map_io(void);
+extern void ixp425_init_irq(void);
+
+#ifdef CONFIG_ARCH_IXDP425
+MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
+	MAINTAINER("MontaVista Software, Inc.")
+	BOOT_MEM(PHYS_OFFSET, IXP425_PERIPHERAL_BASE_PHYS,
+		IXP425_PERIPHERAL_BASE_VIRT)
+	MAPIO(ixp425_map_io)
+	INITIRQ(ixp425_init_irq)
+	BOOT_PARAMS(0x0100)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_IXDP465
+MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
+	MAINTAINER("SnapGear Inc.")
+	BOOT_MEM(PHYS_OFFSET, IXP425_PERIPHERAL_BASE_PHYS,
+		IXP425_PERIPHERAL_BASE_VIRT)
+	MAPIO(ixp425_map_io)
+	INITIRQ(ixp425_init_irq)
+	BOOT_PARAMS(0x0100)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_IXCDP1100
+MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
+	MAINTAINER("MontaVista Software, Inc.")
+	BOOT_MEM(PHYS_OFFSET, IXP425_PERIPHERAL_BASE_PHYS,
+		IXP425_PERIPHERAL_BASE_VIRT)
+	MAPIO(ixp425_map_io)
+	INITIRQ(ixp425_init_irq)
+	BOOT_PARAMS(0x0100)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_PRPMC1100
+MACHINE_START(PRPMC1100, "Motorola PrPMC 1100")
+	MAINTAINER("MontaVista Software, Inc.")
+	BOOT_MEM(PHYS_OFFSET, IXP425_PERIPHERAL_BASE_PHYS,
+		IXP425_PERIPHERAL_BASE_VIRT)
+	MAPIO(ixp425_map_io)
+	INITIRQ(ixp425_init_irq)
+	BOOT_PARAMS(0x0100)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_ADI_COYOTE
+MACHINE_START(ADI_COYOTE, "ADI Coyote Residential Gateway")
+	MAINTAINER("MontaVista Software, Inc.")
+	BOOT_MEM(PHYS_OFFSET, IXP425_PERIPHERAL_BASE_PHYS,
+		IXP425_PERIPHERAL_BASE_VIRT)
+	MAPIO(ixp425_map_io)
+	INITIRQ(ixp425_init_irq)
+	BOOT_PARAMS(0x0100)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_SE4000
+MACHINE_START(SE4000, "SnapGear SE4000")
+	MAINTAINER("SnapGear - A CyberGuard Company")
+	BOOT_MEM(PHYS_OFFSET, IXP425_PERIPHERAL_BASE_PHYS,
+		IXP425_PERIPHERAL_BASE_VIRT)
+	MAPIO(ixp425_map_io)
+	INITIRQ(ixp425_init_irq)
+	BOOT_PARAMS(0x0100)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_SG560
+MACHINE_START(SG560, "CyberGuard/SG560")
+	MAINTAINER("CyberGuard Inc")
+	BOOT_MEM(PHYS_OFFSET, IXP425_PERIPHERAL_BASE_PHYS,
+		IXP425_PERIPHERAL_BASE_VIRT)
+	MAPIO(ixp425_map_io)
+	INITIRQ(ixp425_init_irq)
+	BOOT_PARAMS(0x0100)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_SG565
+MACHINE_START(SG565, "CyberGuard/SG565")
+	MAINTAINER("CyberGuard Inc")
+	BOOT_MEM(PHYS_OFFSET, IXP425_PERIPHERAL_BASE_PHYS,
+		IXP425_PERIPHERAL_BASE_VIRT)
+	MAPIO(ixp425_map_io)
+	INITIRQ(ixp425_init_irq)
+	BOOT_PARAMS(0x0100)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_SHIVA1100
+MACHINE_START(SHIVA1100, "Eicon/Shiva1100")
+	MAINTAINER("CyberGuard Inc")
+	BOOT_MEM(PHYS_OFFSET, IXP425_PERIPHERAL_BASE_PHYS,
+		IXP425_PERIPHERAL_BASE_VIRT)
+	MAPIO(ixp425_map_io)
+	INITIRQ(ixp425_init_irq)
+	BOOT_PARAMS(0x0100)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_SG580
+MACHINE_START(SG580, "CyberGuard/SG580")
+	MAINTAINER("CyberGuard Inc")
+	BOOT_MEM(PHYS_OFFSET, IXP425_PERIPHERAL_BASE_PHYS,
+		IXP425_PERIPHERAL_BASE_VIRT)
+	MAPIO(ixp425_map_io)
+	INITIRQ(ixp425_init_irq)
+	BOOT_PARAMS(0x0100)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_IVPN
+MACHINE_START(IVPN, "CyberGuard/iVPN")
+	MAINTAINER("CyberGuard Inc")
+	BOOT_MEM(PHYS_OFFSET, IXP425_PERIPHERAL_BASE_PHYS,
+		IXP425_PERIPHERAL_BASE_VIRT)
+	MAPIO(ixp425_map_io)
+	INITIRQ(ixp425_init_irq)
+	BOOT_PARAMS(0x0100)
+	FIXUP(ess710_memsize)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_ESS710
+extern void ess710_memsize(struct machine_desc *mdesc, struct param_struct *tags, char **cmdline, struct meminfo *mi);
+
+MACHINE_START(ESS710, "CyberGuard SG710")
+	MAINTAINER("CyberGuard Inc")
+	BOOT_MEM(PHYS_OFFSET, IXP425_PERIPHERAL_BASE_PHYS,
+		IXP425_PERIPHERAL_BASE_VIRT)
+	MAPIO(ixp425_map_io)
+	INITIRQ(ixp425_init_irq)
+	BOOT_PARAMS(0x0100)
+	FIXUP(ess710_memsize)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_MONTEJADE
+MACHINE_START(MONTEJADE, "Intel IXP425 Monte Jade Demonstration Platform")
+	MAINTAINER("CyberGuard Inc")
+	BOOT_MEM(PHYS_OFFSET, IXP425_PERIPHERAL_BASE_PHYS,
+		IXP425_PERIPHERAL_BASE_VIRT)
+	MAPIO(ixp425_map_io)
+	INITIRQ(ixp425_init_irq)
+	BOOT_PARAMS(0x0100)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_SE5100
+MACHINE_START(SE5100, "CyberGuard SE5100 VPN/Firewall/Router/VOIP")
+	MAINTAINER("CyberGuard Inc")
+	BOOT_MEM(PHYS_OFFSET, IXP425_PERIPHERAL_BASE_PHYS,
+		IXP425_PERIPHERAL_BASE_VIRT)
+	MAPIO(ixp425_map_io)
+	INITIRQ(ixp425_init_irq)
+	BOOT_PARAMS(0x0100)
+MACHINE_END
+#endif
diff -urN linux-2.4.29/arch/arm/mach-ixp425/coyote-pci.c linux-2.4.29-uc1/arch/arm/mach-ixp425/coyote-pci.c
--- linux-2.4.29/arch/arm/mach-ixp425/coyote-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/coyote-pci.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,60 @@
+/*
+ * arch/arm/mach-ixp425/coyote-pci.c 
+ *
+ * ADI Coyote PCI initialization
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <asm/mach/pci.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/arch/pci.h>
+
+
+/* PCI controller pin mappings */
+#define INTA_PIN	IXP425_GPIO_PIN_11
+#define INTB_PIN	IXP425_GPIO_PIN_6
+
+#define IXP425_PCI_RESET_GPIO   IXP425_GPIO_PIN_12
+#define IXP425_PCI_CLK_PIN      IXP425_GPIO_CLK_0
+#define IXP425_PCI_CLK_ENABLE   IXP425_GPIO_CLK0_ENABLE
+#define IXP425_PCI_CLK_TC_LSH   IXP425_GPIO_CLK0TC_LSH
+#define IXP425_PCI_CLK_DC_LSH   IXP425_GPIO_CLK0DC_LSH
+
+void __init coyote_pci_init(void *sysdata)
+{
+	gpio_line_config(INTA_PIN, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+	gpio_line_config(INTB_PIN, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+
+	gpio_line_isr_clear(INTA_PIN);
+	gpio_line_isr_clear(INTB_PIN);
+
+	ixp425_pci_init(sysdata);
+}
+
+static int __init coyote_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if(slot == 15)
+		return IRQ_COYOTE_PCI_INTA;
+	else if(slot == 14)
+		return IRQ_COYOTE_PCI_INTB;
+	else return -1;
+}
+
+struct hw_pci coyote_pci __initdata = {
+	init:		coyote_pci_init,
+	swizzle:	common_swizzle,
+	map_irq:	coyote_map_irq,
+};
+
diff -urN linux-2.4.29/arch/arm/mach-ixp425/ess710-pci.c linux-2.4.29-uc1/arch/arm/mach-ixp425/ess710-pci.c
--- linux-2.4.29/arch/arm/mach-ixp425/ess710-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/ess710-pci.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,94 @@
+/*
+ * arch/arm/mach-ixp425/ess-pci.c 
+ *
+ * (C) Copyright 2004, SnapGear - A CyberGuard Company.
+
+ * This code based on the coyote-pci.c code, which was:
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/hardware.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/arch/pci.h>
+
+
+/* PCI controller pin mappings */
+#define INTA_PIN	IXP425_GPIO_PIN_6
+#define INTB_PIN	IXP425_GPIO_PIN_7
+#define INTC_PIN	IXP425_GPIO_PIN_8
+
+#define IXP425_PCI_RESET_GPIO   IXP425_GPIO_PIN_12
+#define IXP425_PCI_CLK_PIN      IXP425_GPIO_CLK_0
+#define IXP425_PCI_CLK_ENABLE   IXP425_GPIO_CLK0_ENABLE
+#define IXP425_PCI_CLK_TC_LSH   IXP425_GPIO_CLK0TC_LSH
+#define IXP425_PCI_CLK_DC_LSH   IXP425_GPIO_CLK0DC_LSH
+
+void __init ess710_pci_init(void *sysdata)
+{
+	printk("PCI: reset bus...\n");
+	gpio_line_set(IXP425_GPIO_PIN_13, 0);
+	gpio_line_config(IXP425_GPIO_PIN_13, IXP425_GPIO_OUT);
+	gpio_line_set(IXP425_GPIO_PIN_13, 0);
+	mdelay(50);
+	gpio_line_set(IXP425_GPIO_PIN_13, 1);
+	mdelay(50);
+
+	gpio_line_config(INTA_PIN, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+	gpio_line_config(INTB_PIN, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+	gpio_line_config(INTC_PIN, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+
+	gpio_line_isr_clear(INTA_PIN);
+	gpio_line_isr_clear(INTB_PIN);
+	gpio_line_isr_clear(INTC_PIN);
+
+	ixp425_pci_init(sysdata);
+}
+
+static int __init ess710_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if (slot == 16)
+		return IRQ_ESS710_PCI_INTA;
+	else if (slot == 15)
+		return IRQ_ESS710_PCI_INTB;
+	else if (slot == 14)
+		return IRQ_ESS710_PCI_INTC;
+	else if (slot == 13)
+		return IRQ_ESS710_PCI_INTC;
+	else return -1;
+}
+
+struct hw_pci ess710_pci __initdata = {
+	init:		ess710_pci_init,
+	swizzle:	common_swizzle,
+	map_irq:	ess710_map_irq,
+};
+
+/*
+ *	Hard set the ESS710 memory size to be 128M. Early boot loaders
+ *	passed in 64MB in their boot tags, but now we really can use the
+ *	128M that the hardware has.
+ */
+void ess710_memsize(struct machine_desc *mdesc, struct param_struct *tags, char **cmdline, struct meminfo *mi)
+{
+	mi->nr_banks = 1;
+	mi->bank[0].start = PHYS_OFFSET;
+	mi->bank[0].size = (128*1024*1024);
+}
+
diff -urN linux-2.4.29/arch/arm/mach-ixp425/gpio.c linux-2.4.29-uc1/arch/arm/mach-ixp425/gpio.c
--- linux-2.4.29/arch/arm/mach-ixp425/gpio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/gpio.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,108 @@
+/*
+ * arch/arm/mach-ixp425/ixp425-gpio.c 
+ *
+ * GPIO configuration APIs for IXP425 based systems
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <asm/hardware.h>
+
+#define IXP425_GPIO_INTSTYLE_MASK	0x7C  /* Bits [6:2] define interrupt style */
+
+/* Interrupt styles, these refer to actual values used in reg */
+#define IXP425_GPIO_STYLE_ACTIVE_HIGH	0x0
+#define IXP425_GPIO_STYLE_ACTIVE_LOW	0x1
+#define IXP425_GPIO_STYLE_RISING_EDGE	0x2
+#define IXP425_GPIO_STYLE_FALLING_EDGE	0x3
+#define IXP425_GPIO_STYLE_TRANSITIONAL	0x4
+
+/* Mask used to clear interrupt styles */
+#define IXP425_GPIO_STYLE_CLEAR		0x7
+#define IXP425_GPIO_STYLE_SIZE		3
+
+void gpio_line_isr_clear(u8 line)
+{
+	*IXP425_GPIO_GPISR = BIT(line);
+}
+
+void gpio_line_get(u8 line, int *value)
+{
+	*value = (*IXP425_GPIO_GPINR >> line) & 0x1;
+}
+
+void gpio_line_set(u8 line, int value)
+{
+	if (value == IXP425_GPIO_HIGH)
+	    *IXP425_GPIO_GPOUTR |= BIT(line);
+	else if (value == IXP425_GPIO_LOW)
+	    *IXP425_GPIO_GPOUTR &= ~BIT(line);
+}
+
+void gpio_line_config(u8 line, u32 style)
+{
+	u32 enable;
+	volatile u32 *int_reg;
+	u32 int_style;
+
+	enable = *IXP425_GPIO_GPOER;
+
+	if (style & IXP425_GPIO_OUT) {
+		enable &= ~BIT(line);
+	} else if (style & IXP425_GPIO_IN) {
+		enable |= BIT(line);
+
+		switch (style & IXP425_GPIO_INTSTYLE_MASK)
+		{
+		case (IXP425_GPIO_ACTIVE_HIGH):
+			int_style = IXP425_GPIO_STYLE_ACTIVE_HIGH;
+			break;
+		case (IXP425_GPIO_ACTIVE_LOW):
+			int_style = IXP425_GPIO_STYLE_ACTIVE_LOW;
+			break;
+		case (IXP425_GPIO_RISING_EDGE):
+			int_style = IXP425_GPIO_STYLE_RISING_EDGE;
+			break;
+		case (IXP425_GPIO_FALLING_EDGE):
+			int_style = IXP425_GPIO_STYLE_FALLING_EDGE;
+			break;
+		case (IXP425_GPIO_TRANSITIONAL):
+			int_style = IXP425_GPIO_STYLE_TRANSITIONAL;
+			break;
+		default:
+			int_style = IXP425_GPIO_STYLE_ACTIVE_HIGH;
+			break;
+		}
+
+		if (line >= 8) {	/* pins 8-15 */ 
+			line -= 8;
+			int_reg = IXP425_GPIO_GPIT2R;
+		}
+		else {			/* pins 0-7 */
+			int_reg = IXP425_GPIO_GPIT1R;
+		}
+
+		/* Clear the style for the appropriate pin */
+		*int_reg &= ~(IXP425_GPIO_STYLE_CLEAR << 
+		    		(line * IXP425_GPIO_STYLE_SIZE));
+
+		/* Set the new style */
+		*int_reg |= (int_style << (line * IXP425_GPIO_STYLE_SIZE));
+	}
+
+	*IXP425_GPIO_GPOER = enable;
+}
+
+EXPORT_SYMBOL(gpio_line_config);
+EXPORT_SYMBOL(gpio_line_set);
+EXPORT_SYMBOL(gpio_line_get);
+EXPORT_SYMBOL(gpio_line_isr_clear);
+
diff -urN linux-2.4.29/arch/arm/mach-ixp425/ixdp425-pci.c linux-2.4.29-uc1/arch/arm/mach-ixp425/ixdp425-pci.c
--- linux-2.4.29/arch/arm/mach-ixp425/ixdp425-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/ixdp425-pci.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,92 @@
+/*
+ * arch/arm/mach-ixdp425/ixdp425-pci.c 
+ *
+ * IXDP425 PCI initialization
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <asm/mach/pci.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/arch/pci.h>
+
+
+/* PCI controller pin mappings */
+#define INTA_PIN	IXP425_GPIO_PIN_11
+#define INTB_PIN	IXP425_GPIO_PIN_10
+#define	INTC_PIN	IXP425_GPIO_PIN_9
+#define	INTD_PIN	IXP425_GPIO_PIN_8
+
+#define IXP425_PCI_RESET_GPIO   IXP425_GPIO_PIN_13
+#define IXP425_PCI_CLK_PIN      IXP425_GPIO_CLK_0
+#define IXP425_PCI_CLK_ENABLE   IXP425_GPIO_CLK0_ENABLE
+#define IXP425_PCI_CLK_TC_LSH   IXP425_GPIO_CLK0TC_LSH
+#define IXP425_PCI_CLK_DC_LSH   IXP425_GPIO_CLK0DC_LSH
+
+void __init ixdp425_pci_init(void *sysdata)
+{
+	gpio_line_config(INTA_PIN, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+	gpio_line_config(INTB_PIN, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+	gpio_line_config(INTC_PIN, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+	gpio_line_config(INTD_PIN, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+
+	gpio_line_isr_clear(INTA_PIN);
+	gpio_line_isr_clear(INTB_PIN);
+	gpio_line_isr_clear(INTC_PIN);
+	gpio_line_isr_clear(INTD_PIN);
+
+	ixp425_pci_init(sysdata);
+}
+
+
+/*
+ * Interrupt mapping
+ */
+#define INTA			IRQ_IXDP425_PCI_INTA
+#define INTB			IRQ_IXDP425_PCI_INTB
+#define INTC			IRQ_IXDP425_PCI_INTC
+#define INTD			IRQ_IXDP425_PCI_INTD
+
+#define IXP425_PCI_MAX_DEV      4
+#define IXP425_PCI_IRQ_LINES    4
+
+static int __init ixdp425_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	static int pci_irq_table[IXP425_PCI_MAX_DEV][IXP425_PCI_IRQ_LINES] = 
+	{
+		{INTA, INTB, INTC, INTD},
+		{INTB, INTC, INTD, INTA},
+		{INTC, INTD, INTA, INTB},
+		{INTD, INTA, INTB, INTC}
+	};
+
+	int irq = -1;
+
+	if (slot >= 1 && slot <= IXP425_PCI_MAX_DEV && 
+		pin >= 1 && pin <= IXP425_PCI_IRQ_LINES)
+	{
+		irq = pci_irq_table[slot-1][pin-1];
+	}
+
+	return irq;
+}
+
+struct hw_pci ixdp425_pci __initdata = {
+	init:		ixdp425_pci_init,
+	swizzle:	common_swizzle,
+	map_irq:	ixdp425_map_irq,
+};
+
diff -urN linux-2.4.29/arch/arm/mach-ixp425/ixp425-irq.c linux-2.4.29-uc1/arch/arm/mach-ixp425/ixp425-irq.c
--- linux-2.4.29/arch/arm/mach-ixp425/ixp425-irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/ixp425-irq.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,88 @@
+/*
+ * arch/arm/mach-ixp425/ixp425-irq.c 
+ *
+ * Generic IRQ routines for IXP425 based systems
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+ 
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/bitops.h>
+ 
+#include <asm/mach/irq.h>           
+
+#include <asm/hardware.h>
+
+static void ixp425_irq_mask(unsigned int irq)
+{
+	if (cpu_is_ixp46x() && irq >= 32)
+		*IXP425_ICMR2 &= ~BIT((irq-32));
+	else
+		*IXP425_ICMR &= ~BIT(irq);
+
+}
+
+static void ixp425_irq_mask_ack(unsigned int irq)
+{
+	static int irq2gpio[NR_IRQS] = {
+		-1, -1, -1, -1, -1, -1,  0,  1,
+		-1, -1, -1, -1, -1, -1, -1, -1,
+		-1, -1, -1,  2,  3,  4,  5,  6,
+		 7,  8,  9, 10, 11, 12, -1, -1,
+	};
+	int line = (irq >= 32) ? -1 : irq2gpio[irq];
+
+	if (line > 0)
+		gpio_line_isr_clear(line);
+	
+	ixp425_irq_mask(irq);
+}
+
+static void ixp425_irq_unmask(unsigned int irq)
+{
+	if (cpu_is_ixp46x() && irq >= 32)
+		*IXP425_ICMR2 |= BIT((irq - 32));
+	else
+		*IXP425_ICMR |= BIT(irq);
+}
+
+void __init ixp425_init_irq(void)
+{
+	int i = 0;
+
+	/* Route all sources to IRQ instead of FIQ */
+	*IXP425_ICLR = 0x0;
+	/* Disable all interrupt */
+	*IXP425_ICMR = 0x0; 
+
+	if (cpu_is_ixp46x()) {
+		/* Route all sources to IRQ instead of FIQ */
+		*IXP425_ICLR2 = 0x0;
+		/* Disable all interrupt */
+		*IXP425_ICMR2 = 0x0; 
+	}
+
+	for(i = 0; i < NR_IRQS; i++)
+	{
+		irq_desc[i].valid	= 1;
+		irq_desc[i].probe_ok	= 0;
+		irq_desc[i].mask_ack	= ixp425_irq_mask_ack;
+		irq_desc[i].mask	= ixp425_irq_mask;
+		irq_desc[i].unmask	= ixp425_irq_unmask;
+	}
+}
diff -urN linux-2.4.29/arch/arm/mach-ixp425/ixp425-pci.c linux-2.4.29-uc1/arch/arm/mach-ixp425/ixp425-pci.c
--- linux-2.4.29/arch/arm/mach-ixp425/ixp425-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/ixp425-pci.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,524 @@
+/*
+ * arch/arm/mach-ixp425/ixp425-pci.c 
+ *
+ * IXP425 PCI routines
+ *
+ * Maintainer: Deepak Saxena
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/hardware.h>
+#include <asm/arch/pci.h>
+#include <asm/arch/pci_auto.h>
+#include <asm/arch/pci-bridge.h>
+
+#ifdef DEBUG
+#  define DBG(x...) printk(__FILE__": "x)
+#else
+#  define DBG(x...)
+#endif
+
+int (*ixp425_pci_read)(u32 addr, u32 cmd, u32* data);
+
+/*
+ * PCI cfg an I/O routines are done by programming a 
+ * command/byte enable register, and then read/writing
+ * the data from a data regsiter. We need to ensure
+ * these transactions are atomic or we will end up
+ * with corrupt data on the bus or in a driver.
+ */
+static spinlock_t ixp425_pci_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * Read from PCI config space
+ */
+static void crp_read(u32 ad_cbe, u32 *data)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&ixp425_pci_lock, flags);
+	*PCI_CRP_AD_CBE = ad_cbe;
+	*data = *PCI_CRP_RDATA;
+	spin_unlock_irqrestore(&ixp425_pci_lock, flags);
+}
+
+/*
+ * Write to PCI config space
+ */
+static void crp_write(u32 ad_cbe, u32 data)
+{ 
+	unsigned long flags;
+	spin_lock_irqsave(&ixp425_pci_lock, flags);
+	*PCI_CRP_AD_CBE = CRP_AD_CBE_WRITE | ad_cbe;
+	*PCI_CRP_WDATA = data;
+	spin_unlock_irqrestore(&ixp425_pci_lock, flags);
+}
+
+static int local_read_config_byte(int where, u8 *value)
+{ 
+	u32 n, data;
+	DBG("local_read_config_byte from %d\n", where);
+	n = where % 4;
+	crp_read(where & ~3, &data);
+	*value = data >> (8*n);
+	DBG("local_read_config_byte read %#x\n", *value);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int local_read_config_word(int where, u16 *value)
+{
+	u32 n, data;
+	DBG("local_read_config_word from %d\n", where);
+	n = where % 4;
+	crp_read(where & ~3, &data);
+	*value = data >> (8*n);
+	DBG("local_read_config_word read %#x\n", *value);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int local_read_config_dword(int where, u32 *value)
+{
+	DBG("local_read_config_dword from %d\n", where);
+	crp_read(where & ~3, value);
+	DBG("local_read_config_dword read %#x\n", *value);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int local_write_config_byte(int where, u8 value)
+{
+	u32 n, byte_enables, data;
+	DBG("local_write_config_byte %#x to %d\n", value, where);
+	n = where % 4;
+	byte_enables = (0xf & ~BIT(n)) << CRP_AD_CBE_BESL;
+	data = value << (8*n);
+	crp_write((where & ~3) | byte_enables, data);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int local_write_config_word(int where, u16 value)
+{ 
+	u32 n, byte_enables, data;
+	DBG("local_write_config_word %#x to %d\n", value, where);
+	n = where % 4;
+	byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << CRP_AD_CBE_BESL;
+	data = value << (8*n);
+	crp_write((where & ~3) | byte_enables, data);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int local_write_config_dword(int where, u32 value)
+{
+	DBG("local_write_config_dword %#x to %d\n", value, where);
+	crp_write(where & ~3, value);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static inline int check_master_abort(void)
+{
+	/* check Master Abort bit after access */
+	unsigned long isr = *PCI_ISR;
+
+	if (isr & PCI_ISR_PFE)
+	{
+		/* make sure the Master Abort bit is reset */    
+		*PCI_ISR = PCI_ISR_PFE;
+		DBG(__FUNCTION__" failed\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+int ixp425_pci_read_errata(u32 addr, u32 cmd, u32* data)
+{
+	unsigned long flags;
+	int retval = 0;
+	int i;
+
+	spin_lock_irqsave(&ixp425_pci_lock, flags);
+
+	*PCI_NP_AD = addr;
+
+	/* 
+	 * PCI workaround  - only works if NP PCI space reads have 
+	 * no side effects!!! Read 8 times. last one will be good.
+	 */
+	for (i = 0; i < 8; i++)
+	{
+		*PCI_NP_CBE = cmd;
+		*data = *PCI_NP_RDATA;
+		*data = *PCI_NP_RDATA;
+	}
+
+	if(check_master_abort())
+		retval = 1;
+
+	spin_unlock_irqrestore(&ixp425_pci_lock, flags);
+	return retval;
+}
+
+int ixp425_pci_read_no_errata(u32 addr, u32 cmd, u32* data)
+{
+	unsigned long flags;
+	int retval = 0;
+
+	spin_lock_irqsave(&ixp425_pci_lock, flags);
+
+	*PCI_NP_AD = addr;
+
+	/* set up and execute the read */    
+	*PCI_NP_CBE = cmd;
+
+	/* the result of the read is now in NP_RDATA */
+	*data = *PCI_NP_RDATA; 
+
+	if(check_master_abort())
+		retval = 1;
+
+	spin_unlock_irqrestore(&ixp425_pci_lock, flags);
+	return retval;
+}
+
+int ixp425_pci_write(u32 addr, u32 cmd, u32 data)
+{    
+	unsigned long flags;
+	int retval = 0;
+
+	spin_lock_irqsave(&ixp425_pci_lock, flags);
+
+	*PCI_NP_AD = addr;
+
+	/* set up the write */
+	*PCI_NP_CBE = cmd;
+
+	/* execute the write by writing to NP_WDATA */
+	*PCI_NP_WDATA = data;
+
+	if(check_master_abort())
+		retval = 1;
+
+	spin_unlock_irqrestore(&ixp425_pci_lock, flags);
+	return retval;
+}
+
+static u32 ixp425_config_addr(u8 bus_num, u16 devfn, int where)
+{
+	u32 addr;
+	if (!bus_num)
+	{
+		/* type 0 */
+		addr = BIT(32-PCI_SLOT(devfn)) | ((PCI_FUNC(devfn)) << 8) | 
+		    (where & ~3);	
+	}
+	else
+	{
+		/* type 1 */
+		addr = (bus_num << 16) | ((PCI_SLOT(devfn)) << 11) | 
+			((PCI_FUNC(devfn)) << 8) | (where & ~3) | 1;
+	}
+	return addr;
+}
+
+static int read_config_byte(u8 bus_num, u16 devfn, int where, u8 *value)
+{
+	u32 n, byte_enables, addr, data;
+	DBG("read_config_byte from %d dev %d:%d:%d\n", where, bus_num, 
+		PCI_SLOT(devfn), PCI_FUNC(devfn));
+	n = where % 4;
+	byte_enables = (0xf & ~BIT(n)) << 4;
+	addr = ixp425_config_addr(bus_num, devfn, where);
+	if (ixp425_pci_read(addr, byte_enables | NP_CMD_CONFIGREAD, &data))
+	{
+		*value = 0xff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	*value = data >> (8*n);
+	DBG("read_config_byte read %#x\n", *value);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int read_config_word(u8 bus_num, u16 devfn, int where, u16 *value)
+{
+	u32 n, byte_enables, addr, data;
+	DBG("read_config_word from %d dev %d:%d:%d\n", where, bus_num, 
+		PCI_SLOT(devfn), PCI_FUNC(devfn));
+	n = where % 4;
+	byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << 4;
+	addr = ixp425_config_addr(bus_num, devfn, where);
+	if (ixp425_pci_read(addr, byte_enables | NP_CMD_CONFIGREAD, &data))
+	{
+		*value = 0xffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	*value = data >> (8*n);
+	DBG("read_config_word read %#x\n", *value);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int read_config_dword(u8 bus_num, u16 devfn, int where, u32 *value)
+{
+	u32 addr;
+	DBG("read_config_dword from %d dev %d:%d:%d\n", where, bus_num, 
+		PCI_SLOT(devfn), PCI_FUNC(devfn));
+	addr = ixp425_config_addr(bus_num, devfn, where);
+	if (ixp425_pci_read(addr, NP_CMD_CONFIGREAD, value))
+	{
+		*value = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	DBG("read_config_dword read %#x\n", *value);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int write_config_byte(u8 bus_num, u16 devfn, int where, u8 value)
+{
+	u32 n, byte_enables, addr, data;
+	DBG("write_config_byte %#x to %d dev %d:%d:%d\n", value, where, bus_num, 
+		PCI_SLOT(devfn), PCI_FUNC(devfn));
+	n = where % 4;
+	byte_enables = (0xf & ~BIT(n)) << 4;
+	addr = ixp425_config_addr(bus_num, devfn, where);
+	data = value << (8*n);
+	if (ixp425_pci_write(addr, byte_enables | NP_CMD_CONFIGWRITE, data))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int write_config_word(u8 bus_num, u16 devfn, int where, u16 value)
+{
+	u32 n, byte_enables, addr, data;
+	DBG("write_config_word %#x to %d dev %d:%d:%d\n", value, where, bus_num, 
+		PCI_SLOT(devfn), PCI_FUNC(devfn));
+	n = where % 4;
+	byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << 4;
+	addr = ixp425_config_addr(bus_num, devfn, where);
+	data = value << (8*n);
+	if (ixp425_pci_write(addr, byte_enables | NP_CMD_CONFIGWRITE, data))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int write_config_dword(u8 bus_num, u16 devfn, int where, u32 value)
+{
+	u32 addr;
+	DBG("write_config_dword %#x to %d dev %d:%d:%d\n", value, where, bus_num, 
+		PCI_SLOT(devfn), PCI_FUNC(devfn));
+	addr = ixp425_config_addr(bus_num, devfn, where);
+	if (ixp425_pci_write(addr, NP_CMD_CONFIGWRITE, value))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+/*
+ * We have different access functions for local (IXP425) and 
+ * bus devices.  This macro nicely hides that fact from the 
+ * layers above.
+ */
+#define IXP425_PCI_OP(rw, size, type)					\
+static int ixp425_##rw##_config_##size(struct pci_dev *dev, int where,	\
+	type value)							\
+{									\
+	if (!dev->bus->number && !PCI_SLOT(dev->devfn))			\
+		return local_##rw##_config_##size(where, value);	\
+	else								\
+		return rw##_config_##size(dev->bus->number, dev->devfn, where, value); \
+}
+
+IXP425_PCI_OP(read, byte, u8 *)
+IXP425_PCI_OP(read, word, u16 *)
+IXP425_PCI_OP(read, dword, u32 *)
+IXP425_PCI_OP(write, byte, u8)
+IXP425_PCI_OP(write, word, u16)
+IXP425_PCI_OP(write, dword, u32)
+
+struct pci_ops ixp425_ops = 
+{
+	ixp425_read_config_byte,
+	ixp425_read_config_word,
+	ixp425_read_config_dword,
+	ixp425_write_config_byte,
+	ixp425_write_config_word,
+	ixp425_write_config_dword,
+};
+
+/*
+ * PCI abort handler
+ */
+static int abort_handler(unsigned long addr, unsigned long fsr, struct pt_regs *regs)
+{
+	u32 isr;
+	u16 status;
+
+	isr = *PCI_ISR;
+	local_read_config_word(PCI_STATUS, &status);
+	printk("!!!abort_handler addr = %#lx, isr = %#x, status = %#x\n", addr, 
+		isr, status);
+
+	/* make sure the Master Abort bit is reset */    
+	*PCI_ISR = PCI_ISR_PFE;
+	status |= PCI_STATUS_REC_MASTER_ABORT;
+	local_write_config_word(PCI_STATUS,status);
+
+	/*
+	 * If it was an imprecise abort, then we need to correct the
+	 * return address to be _after_ the instruction.
+	 */
+	if (fsr & (1 << 10))
+		regs->ARM_pc += 4;
+
+	return 0;
+}
+
+static struct pci_controller *hose;
+
+int __init ixp425_pci_is_host(void)
+{
+	u32 csr;
+	
+	csr = *PCI_CSR;
+	return csr & PCI_CSR_HOST;
+}
+
+void __init ixp425_pci_init(void *sysdata)
+{  
+	unsigned long processor_id;
+
+	asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :);
+
+	if (!(processor_id & 0xf) && !cpu_is_ixp46x()) {
+		printk("IXP425 PCI: A0 silicon detected - PCI Non-Prefetch Workaround Enabled\n");
+		ixp425_pci_read = ixp425_pci_read_errata;
+	} else
+		ixp425_pci_read = ixp425_pci_read_no_errata;
+
+	/* hook in our fault handler for PCI errors */
+	hook_fault_code(4, abort_handler, SIGBUS, "external abort on line fetch\n");
+	hook_fault_code(6, abort_handler, SIGBUS, "external abort on line fetch\n");
+	hook_fault_code(8, abort_handler, SIGBUS, "external abort on non-line fetch\n");
+	hook_fault_code(10, abort_handler, SIGBUS, "external abort on non-line fetch\n");
+
+	/* 
+	 * We use identity AHB->PCI address translation
+	 * in the 0x48000000 address space
+	 */
+	DBG("setup PCI-AHB(inbound) and AHB-PCI(outbound) address mappings\n");
+	*PCI_PCIMEMBASE = 0x48494A4B;
+
+	/* 
+	 * We also use identity PCI->AHB address translation
+	 * in 4 16MB BARs that begin at the physical memory start
+	 */
+	*PCI_AHBMEMBASE = (PHYS_OFFSET & 0xFF000000) + 
+		((PHYS_OFFSET & 0xFF000000) >> 8) +
+		((PHYS_OFFSET & 0xFF000000) >> 16) +
+		((PHYS_OFFSET & 0xFF000000) >> 24) +
+		0x00010203;
+
+	if (ixp425_pci_is_host())
+	{
+		DBG("setup BARs in controller\n");
+
+		/*
+		 * We configure the PCI inbound memory windows to be 1:1 mapped to SDRAM
+		 */
+		local_write_config_dword(PCI_BASE_ADDRESS_0, PHYS_OFFSET + 0x00000000);
+		local_write_config_dword(PCI_BASE_ADDRESS_1, PHYS_OFFSET + 0x01000000);
+		local_write_config_dword(PCI_BASE_ADDRESS_2, PHYS_OFFSET + 0x02000000);
+		local_write_config_dword(PCI_BASE_ADDRESS_3, PHYS_OFFSET + 0x03000000);
+
+		/*
+		 * Disable our CSR and I/O windows from responding
+		 * to anything. Since we're the master, no one should
+		 * be fiddling with our internals.
+		 */
+		local_write_config_dword(PCI_BASE_ADDRESS_4, 0xffffffff);
+		local_write_config_dword(PCI_BASE_ADDRESS_5, 0xffffffff);
+	}
+
+	DBG("clear error bits in ISR\n");
+	*PCI_ISR = PCI_ISR_PSE | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE;
+
+	/*
+	 * Set Initialize Complete in PCI Control Register: allow IXP425 to
+	 * respond to PCI configuration cycles. Specify that the AHB bus is
+	 * operating in big endian mode. Set up byte lane swapping between 
+	 * little-endian PCI and the big-endian AHB bus 
+	 */
+	*PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS;
+
+	if (ixp425_pci_is_host())
+	{
+		local_write_config_word(PCI_COMMAND, PCI_COMMAND_MASTER | 
+			PCI_COMMAND_MEMORY);
+
+		DBG("allocating hose\n");
+		hose = pcibios_alloc_controller();
+		if (!hose)
+		panic("Could not allocate PCI hose");
+
+		hose->first_busno = 0;
+		hose->last_busno = 0;
+		hose->io_space.start = 0;
+		hose->io_space.end = 0xffffffff;
+		hose->mem_space.start = 0x48000000;
+		hose->mem_space.end = 0x4bffffff;
+
+		/* autoconfig the bus */ DBG("AUTOCONFIG\n");
+		hose->last_busno = pciauto_bus_scan(hose, 0);
+	    
+		/* scan the bus */
+		DBG("SCANNING THE BUS\n");
+		pci_scan_bus(0, &ixp425_ops, sysdata);
+	}
+
+	DBG("DONE\n");
+}
+
+#define EARLY_PCI_OP(rw, size, type)                                    \
+int early_##rw##_config_##size(struct pci_controller *hose, int bus,    \
+	int devfn, int offset, type value)                                  \
+{                                                                       \
+	return ixp425_##rw##_config_##size(fake_pci_dev(hose, bus, devfn),  \
+		offset, value);                                                 \
+}
+
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
+
+EXPORT_SYMBOL(ixp425_pci_read);
+EXPORT_SYMBOL(ixp425_pci_write);
+
diff -urN linux-2.4.29/arch/arm/mach-ixp425/ixp425-time.c linux-2.4.29-uc1/arch/arm/mach-ixp425/ixp425-time.c
--- linux-2.4.29/arch/arm/mach-ixp425/ixp425-time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/ixp425-time.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,95 @@
+/*
+ * arch/arm/mach-ixp425/ixp425-time.c
+ *
+ * Timer tick for IXP425 based sytems. We use OS timer1 on the CPU for
+ * the timer tick and the timestamp counter to account for missed jiffies.
+ *
+ * Author:  Peter Barry
+ * Copyright:   (C) 2001 Intel Corporation.
+ * 		(C) 2002-2003 MontaVista Software, Inc.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/timex.h>
+#include <asm/hardware.h>
+
+extern int setup_arm_irq(int, struct irqaction *);
+static unsigned volatile last_jiffy_time;
+
+#define	USEC_PER_SEC		1000000
+#define CLOCK_TICKS_PER_USEC	(CLOCK_TICK_RATE / USEC_PER_SEC)
+
+/* IRQs are disabled before entering here from do_gettimeofday() */
+static unsigned long ixp425_gettimeoffset(void)
+{
+	u32 elapsed, usec, curr, reload;
+	volatile u32 stat1, stat2;
+
+	elapsed = *IXP425_OSTS - last_jiffy_time;
+
+	return elapsed / CLOCK_TICKS_PER_USEC;
+}
+
+static void ixp425_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long flags;
+
+	/* Clear Pending Interrupt by writing '1' to it */
+	*IXP425_OSST = IXP425_OSST_TIMER_1_PEND;
+
+	/*
+	 * Catch up with the real idea of time
+	 */
+	while((*IXP425_OSTS - last_jiffy_time) > LATCH) {
+		do_timer(regs);
+		do_profile(regs);
+		last_jiffy_time += LATCH;
+	}		
+}
+
+extern unsigned long (*gettimeoffset)(void);
+
+static struct irqaction timer_irq = {
+	name: "Timer Tick",
+	flags: SA_INTERRUPT
+};
+
+void __init setup_timer(void)
+{
+	gettimeoffset = ixp425_gettimeoffset;
+	timer_irq.handler = ixp425_timer_interrupt;
+
+	/* Clear Pending Interrupt by writing '1' to it */
+	*IXP425_OSST = IXP425_OSST_TIMER_1_PEND;
+
+	/* Setup the Timer counter value */
+	*IXP425_OSRT1 = (LATCH & ~IXP425_OST_RELOAD_MASK) | IXP425_OST_ENABLE;
+
+	/* Reset time-stamp counter */
+	*IXP425_OSTS = 0;
+	last_jiffy_time = 0;
+
+	/* Connect the interrupt handler and enable the interrupt */
+	setup_arm_irq(IRQ_IXP425_TIMER1, &timer_irq);
+}
+
+
diff -urN linux-2.4.29/arch/arm/mach-ixp425/kgdb.c linux-2.4.29-uc1/arch/arm/mach-ixp425/kgdb.c
--- linux-2.4.29/arch/arm/mach-ixp425/kgdb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/kgdb.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,58 @@
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+
+#include <asm/atomic.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+
+#include <asm/kgdb.h>
+#include <asm/serial.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm-arm/arch/ixp425.h>
+#include <linux/serial_reg.h>
+
+#define UART_BASE ((volatile u32*)IXP425_UART2_BASE_VIRT)
+#define TX_DONE	(UART_LSR_TEMT|UART_LSR_THRE)
+
+void kgdb_serial_init(void)
+{
+	/* Enable access to DLL/DLM */
+	UART_BASE[UART_LCR] = 0x80;
+	/* Set baud rate devisors */
+	UART_BASE[UART_DLL] = IXP425_DEF_UART_BAUD_DLL;
+	UART_BASE[UART_DLM] = IXP425_DEF_UART_BAUD_DLM;
+	/* 8N1 */
+	UART_BASE[UART_LCR] = 0x3;
+	/* DMAE=0 (no DMA), UUE(Unit enble)=1 */
+	UART_BASE[UART_IER] = 0x40;
+	/* RESESTTF | RESESTRF | TRFIFOE 
+	 * - reset Tx&Rx and enable tx/rx FIFO
+	 */
+	UART_BASE[UART_FCR] = 0x7;
+	/* Enable interrupt */
+	UART_BASE[UART_MCR] = 0x8;
+	return;
+}
+
+void kgdb_serial_putchar(unsigned char ch)
+{
+	/* Check THRE and  TEMT bits before we transmit the character.
+	 */
+	while ((UART_BASE[UART_LSR] & TX_DONE) != TX_DONE); 
+	*UART_BASE = ch;
+}
+
+unsigned char kgdb_serial_getchar(void)
+{
+	/* Wait for incomming char */
+	while (!(UART_BASE[UART_LSR] & UART_LSR_DR));
+	return (u8)*UART_BASE;
+}
diff -urN linux-2.4.29/arch/arm/mach-ixp425/Makefile linux-2.4.29-uc1/arch/arm/mach-ixp425/Makefile
--- linux-2.4.29/arch/arm/mach-ixp425/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/Makefile	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,36 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= ixp425.o
+
+# Object file lists.
+
+obj-y			:= arch.o mm.o ixp425-irq.o ixp425-pci.o pci.o \
+				pci-auto.o gpio.o pci-io.o \
+				ixp425-time.o pcibuf.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= pcibuf.o pci-io.o gpio.o ixp425-pci.o
+
+obj-$(CONFIG_ARCH_IXDP425)	+= ixdp425-pci.o
+obj-$(CONFIG_MACH_IXDP465)	+= ixdp425-pci.o
+obj-$(CONFIG_ARCH_PRPMC1100)	+= prpmc1100-pci.o
+obj-$(CONFIG_ARCH_ADI_COYOTE)	+= coyote-pci.o
+obj-$(CONFIG_MACH_ESS710)	+= ess710-pci.o
+obj-$(CONFIG_MACH_SG565)	+= sg580-pci.o
+obj-$(CONFIG_MACH_SHIVA1100)	+= sg580-pci.o
+obj-$(CONFIG_MACH_SG580)	+= sg580-pci.o
+obj-$(CONFIG_MACH_MONTEJADE)	+= montejade-pci.o
+obj-$(CONFIG_MACH_SE5100)	+= montejade-pci.o
+
+obj-$(CONFIG_KGDB) 		+= kgdb.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/arm/mach-ixp425/mm.c linux-2.4.29-uc1/arch/arm/mach-ixp425/mm.c
--- linux-2.4.29/arch/arm/mach-ixp425/mm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/mm.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,70 @@
+/*
+ * arch/arm/mach-ixp425/mm.c 
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003 MontaVista Sofwtare, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+#include <asm/mach/map.h>
+#include <asm/hardware.h>
+
+/* See asm/arch/ixp425.h for a detailed memory map */
+
+/* Common mappings */
+static struct map_desc ixp425_io_desc[] __initdata = {
+	/* UART, Interrupt ctrl, GPIO, timers, NPEs, MACS, USB .... */
+	{
+		IXP425_PERIPHERAL_BASE_VIRT,
+		IXP425_PERIPHERAL_BASE_PHYS,
+		IXP425_PERIPHERAL_REGION_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0
+			/* r  w  c  b */
+	},
+	/* PCI Config Registers */
+	{
+		IXP425_PCI_CFG_BASE_VIRT,
+		IXP425_PCI_CFG_BASE_PHYS,
+		IXP425_PCI_CFG_REGION_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0
+			/* r  w  c  b */
+	},
+	/* Expansion Bus Config Registers */
+	{
+		IXP425_EXP_CFG_BASE_VIRT,
+		IXP425_EXP_CFG_BASE_PHYS,
+		IXP425_EXP_CFG_REGION_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0
+			/* r  w  c  b */
+	},
+	/* Queue Manager - Required for Intel CSR and NPE access */
+	{
+		IXP425_QMGR_BASE_VIRT,
+		IXP425_QMGR_BASE_PHYS,
+		IXP425_QMGR_REGION_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0
+			/* r  w  c  b */
+	},
+	LAST_DESC
+};
+
+
+
+void __init ixp425_map_io(void)
+{
+	/* Common Mapping */
+	iotable_init(ixp425_io_desc); 
+}
+
diff -urN linux-2.4.29/arch/arm/mach-ixp425/montejade-pci.c linux-2.4.29-uc1/arch/arm/mach-ixp425/montejade-pci.c
--- linux-2.4.29/arch/arm/mach-ixp425/montejade-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/montejade-pci.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,64 @@
+/*
+ * arch/arm/mach-ixp425/montejade-pci.c 
+ *
+ * (C) Copyright 2004, SnapGear - A CyberGuard Company.
+
+ * This code based on the coyote-pci.c code, which was:
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <asm/mach/pci.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/arch/pci.h>
+
+
+/* PCI controller pin mappings */
+#define INTA_PIN	IXP425_GPIO_PIN_6
+#define INTB_PIN	IXP425_GPIO_PIN_7
+
+void __init montejade_pci_init(void *sysdata)
+{
+	printk("PCI: reset bus...\n");
+	gpio_line_set(IXP425_GPIO_PIN_8, 0);
+	gpio_line_config(IXP425_GPIO_PIN_8, IXP425_GPIO_OUT);
+	gpio_line_set(IXP425_GPIO_PIN_8, 0);
+	mdelay(50);
+	gpio_line_set(IXP425_GPIO_PIN_8, 1);
+	mdelay(50);
+
+	gpio_line_config(INTA_PIN, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+	gpio_line_config(INTB_PIN, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+	gpio_line_isr_clear(INTA_PIN);
+	gpio_line_isr_clear(INTB_PIN);
+
+	ixp425_pci_init(sysdata);
+}
+
+static int __init montejade_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if (slot == 14)
+		return IRQ_MONTEJADE_PCI_INTA;
+	else if (slot == 12)
+		return IRQ_MONTEJADE_PCI_INTB;
+	else if (slot == 13)
+		return IRQ_MONTEJADE_PCI_INTB;
+	return -1;
+}
+
+struct hw_pci montejade_pci __initdata = {
+	init:		montejade_pci_init,
+	swizzle:	common_swizzle,
+	map_irq:	montejade_map_irq,
+};
+
diff -urN linux-2.4.29/arch/arm/mach-ixp425/pci-auto.c linux-2.4.29-uc1/arch/arm/mach-ixp425/pci-auto.c
--- linux-2.4.29/arch/arm/mach-ixp425/pci-auto.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/pci-auto.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,379 @@
+/*
+ * arch/arm/mach-iop310/pci-auto.c
+ * 
+ * PCI autoconfiguration library
+ *
+ * Author: Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/arch/pci-bridge.h>
+#include <asm/arch/pci.h>
+#include <asm/arch/pci_auto.h>
+
+#define DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif /* DEBUG */
+
+static int pciauto_upper_iospc;
+static int pciauto_upper_memspc;
+
+void pciauto_setup_bars(struct pci_controller *hose,
+		int current_bus,
+		int pci_devfn,
+		int bar_limit)
+{
+	int bar_response, bar_size, bar_value;
+	int bar, addr_mask, bar_nr = 0;
+	int * upper_limit;
+	int found_mem64 = 0;
+
+	DBG("PCI Autoconfig: Found Bus %d, Device %d, Function %d\n",
+		current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn) );
+
+	for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4)
+	{
+		/* Tickle the BAR and get the response */
+		early_write_config_dword(hose,
+				current_bus,
+				pci_devfn,
+				bar,
+				0xffffffff);
+		early_read_config_dword(hose,
+				current_bus,
+				pci_devfn,
+				bar,
+				&bar_response);
+
+		/* If BAR is not implemented go to the next BAR */
+		if (!bar_response)
+			continue;
+
+		/* Check the BAR type and set our address mask */
+		if (bar_response & PCI_BASE_ADDRESS_SPACE)
+		{
+			addr_mask = PCI_BASE_ADDRESS_IO_MASK;
+			upper_limit = &pciauto_upper_iospc;
+			DBG("PCI Autoconfig: BAR %d, I/O, ", bar_nr);
+		}
+		else
+		{
+			if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+			PCI_BASE_ADDRESS_MEM_TYPE_64)
+				found_mem64 = 1;
+
+			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;		
+			upper_limit = &pciauto_upper_memspc;
+			DBG("PCI Autoconfig: BAR %d, Mem, ", bar_nr);
+		}
+
+		/* Calculate requested size */
+		bar_size = ~(bar_response & addr_mask) + 1;
+
+		/* Allocate a base address */
+		bar_value = (*upper_limit - bar_size) & ~(bar_size - 1);
+
+		/* Write it out and update our limit */
+		early_write_config_dword(hose,
+				current_bus,
+				pci_devfn,
+				bar,
+				bar_value);
+
+		*upper_limit = bar_value;
+
+		/*
+		 * If we are a 64-bit decoder then increment to the
+		 * upper 32 bits of the bar and force it to locate
+		 * in the lower 4GB of memory.
+		 */ 
+		if (found_mem64)
+		{
+			bar += 4;
+			early_write_config_dword(hose,
+					current_bus,
+					pci_devfn,
+					bar,
+					0x00000000);
+		}
+
+		bar_nr++;
+
+		DBG("size=0x%x, address=0x%x\n",
+			bar_size, bar_value);
+	}
+
+}
+
+void pciauto_prescan_setup_bridge(struct pci_controller *hose,
+		int current_bus,
+		int pci_devfn,
+		int sub_bus,
+		int *iosave,
+		int *memsave)
+{
+	/* Configure bus number registers */
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_PRIMARY_BUS,
+			current_bus);
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_SECONDARY_BUS,
+			sub_bus + 1);
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_SUBORDINATE_BUS,
+			0xff);
+
+	/* Round memory allocator to 1MB boundary */
+	pciauto_upper_memspc &= ~(0x100000 - 1);
+	*memsave = pciauto_upper_memspc;
+
+	/* Round I/O allocator to 4KB boundary */
+	pciauto_upper_iospc &= ~(0x1000 - 1);
+	*iosave = pciauto_upper_iospc;
+
+	/* Set up memory and I/O filter limits, assume 32-bit I/O space */
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_MEMORY_LIMIT,
+			((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_LIMIT,
+			((pciauto_upper_iospc - 1) & 0x0000f000) >> 8);
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_LIMIT_UPPER16,
+			((pciauto_upper_iospc - 1) & 0xffff0000) >> 16);
+}
+
+void pciauto_postscan_setup_bridge(struct pci_controller *hose,
+		int current_bus,
+		int pci_devfn,
+		int sub_bus,
+		int *iosave,
+		int *memsave)
+{
+	int cmdstat;
+
+	/* Configure bus number registers */
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_SUBORDINATE_BUS,
+			sub_bus);
+
+	/*
+	 * Round memory allocator to 1MB boundary.
+	 * If no space used, allocate minimum.
+	 */
+	pciauto_upper_memspc &= ~(0x100000 - 1);
+	if (*memsave == pciauto_upper_memspc)
+		pciauto_upper_memspc -= 0x00100000;
+
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_MEMORY_BASE,
+			pciauto_upper_memspc >> 16);
+
+	/* Allocate 1MB for pre-fretch */
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_PREF_MEMORY_LIMIT,
+			((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
+
+	pciauto_upper_memspc -= 0x100000;
+
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_PREF_MEMORY_BASE,
+			pciauto_upper_memspc >> 16);
+
+	/* Round I/O allocator to 4KB boundary */
+	pciauto_upper_iospc &= ~(0x1000 - 1);
+	if (*iosave == pciauto_upper_iospc)
+		pciauto_upper_iospc -= 0x1000;
+
+	DBG("PCI Autoconfig: Bridge %d. IO_FILTER = %#010x..%#010x\n",
+			current_bus, 
+			(pciauto_upper_iospc & 0x0000f000) >> 8,
+			pciauto_upper_iospc >> 16);
+
+	early_write_config_byte(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_BASE,
+			(pciauto_upper_iospc & 0x0000f000) >> 8);
+	early_write_config_word(hose,
+			current_bus,
+			pci_devfn,
+			PCI_IO_BASE_UPPER16,
+			pciauto_upper_iospc >> 16);
+	
+	/* Enable memory and I/O accesses, enable bus master */
+	early_read_config_dword(hose,
+			current_bus,
+			pci_devfn,
+			PCI_COMMAND,
+			&cmdstat);
+	early_write_config_dword(hose,
+			current_bus,
+			pci_devfn,
+			PCI_COMMAND,
+			cmdstat |
+			PCI_COMMAND_IO |
+			PCI_COMMAND_MEMORY |
+			PCI_COMMAND_MASTER);
+}
+
+int pciauto_bus_scan(struct pci_controller *hose, int current_bus)
+{
+	int sub_bus, pci_devfn, pci_class, cmdstat, found_multi=0;
+	unsigned short vid;
+	unsigned char header_type;
+
+	/*
+	 * Fetch our I/O and memory space upper boundaries used
+	 * to allocated base addresses on this hose.
+	 */
+	if (current_bus == hose->first_busno)
+	{
+		pciauto_upper_iospc = hose->io_space.end + 1;
+		pciauto_upper_memspc = hose->mem_space.end + 1;
+	}
+
+	sub_bus = current_bus;
+
+	for (pci_devfn=0; pci_devfn<0xff; pci_devfn++)
+	{
+		/* Skip our host bridge */
+		if ( (current_bus == hose->first_busno) && (pci_devfn == 0) )
+			continue;
+
+		if (PCI_FUNC(pci_devfn) && !found_multi)
+			continue;
+
+		/* If config space read fails from this device, move on */
+		if (early_read_config_byte(hose,
+				current_bus,
+				pci_devfn,
+				PCI_HEADER_TYPE,
+				&header_type))
+			continue;
+
+		if (!PCI_FUNC(pci_devfn))
+			found_multi = header_type & 0x80;
+
+		early_read_config_word(hose,
+				current_bus,
+				pci_devfn,
+				PCI_VENDOR_ID,
+				&vid);
+
+		if (vid != 0xffff)
+		{
+			early_read_config_dword(hose,
+					current_bus,
+					pci_devfn,
+					PCI_CLASS_REVISION, &pci_class);
+			if ( (pci_class >> 16) == PCI_CLASS_BRIDGE_PCI )
+			{
+				int iosave, memsave;
+
+				DBG("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_SLOT(pci_devfn));
+				/* Allocate PCI I/O and/or memory space */
+				pciauto_setup_bars(hose,
+						current_bus,
+						pci_devfn,
+						PCI_BASE_ADDRESS_1);
+
+				pciauto_prescan_setup_bridge(hose,
+						current_bus,
+						pci_devfn,
+						sub_bus,
+						&iosave,
+						&memsave);
+				sub_bus = pciauto_bus_scan(hose, sub_bus+1);
+				pciauto_postscan_setup_bridge(hose,
+						current_bus,
+						pci_devfn,
+						sub_bus,
+						&iosave,
+						&memsave);
+			}
+			else
+			{
+				if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE)
+				{
+					unsigned char prg_iface;
+
+					early_read_config_byte(hose,
+							current_bus,
+							pci_devfn,
+							PCI_CLASS_PROG,
+							&prg_iface);
+					if (!(prg_iface & PCIAUTO_IDE_MODE_MASK))
+					{
+						DBG("PCI Autoconfig: Skipping legacy mode IDE controller\n");
+						continue;
+					}
+				}
+
+				/*
+				 * Found a peripheral, enable some standard
+				 * settings
+				 */
+				early_read_config_dword(hose,
+						current_bus,
+						pci_devfn,
+						PCI_COMMAND,
+						&cmdstat);
+				early_write_config_dword(hose,
+						current_bus,
+						pci_devfn,
+						PCI_COMMAND,
+						cmdstat |
+						PCI_COMMAND_IO |
+						PCI_COMMAND_MEMORY |
+						PCI_COMMAND_MASTER);
+				early_write_config_byte(hose,
+						current_bus,
+						pci_devfn,
+						PCI_LATENCY_TIMER,
+						0x80);
+
+				/* Allocate PCI I/O and/or memory space */
+				pciauto_setup_bars(hose,
+						current_bus,
+						pci_devfn,
+						PCI_BASE_ADDRESS_5);
+			}
+		}
+	}
+	return sub_bus;
+}
diff -urN linux-2.4.29/arch/arm/mach-ixp425/pcibuf.c linux-2.4.29-uc1/arch/arm/mach-ixp425/pcibuf.c
--- linux-2.4.29/arch/arm/mach-ixp425/pcibuf.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/pcibuf.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,238 @@
+/*
+ * arch/arm/mach-ixp425/ixp425-pcibuf.c 
+ *
+ * IXP425 PCI bounce buffer routines.  The IXP425 only has a 64MB inbound
+ * PCI window, but allows for up 256MB of SDRAM.  This means that if 
+ * running with > 64MB of memory, we need to bounce buffers between the
+ * safe and unsafe areas. An attempt was made to port the SA1111 bounce
+ * routines to this platform but that does not work due to the fact that
+ * EEPro100 (and probably others) PCI driver calls pci_map_single() while
+ * handling interrupts to refill Rx buffers.  The sa1111 implementation
+ * of bounce buffering uses pci_pools which call pci_alloc_consistent
+ * which calls consistent_alloc which is not interrupt safe on 2.4.
+ * We're basically doing the same, except that we are using our own
+ * object cache instead of relying on the PCI layer to take care of
+ * it for us.
+ *
+ * This file we be killed in 2.5 and replaced with the sa1111 style 
+ * implementation.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (C) 2003 MontaVista Software, Inc.
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware.h>
+#include <asm/sizes.h>
+
+// #define DEBUG
+#ifdef DEBUG
+#  define DBG(x...) printk(KERN_DEBUG __FILE__": "x)
+#else
+#  define DBG(x...)
+#endif
+
+/*
+ * From SA1111 implementation
+ */
+struct safe_buffer {
+	struct		list_head node;
+
+	/* Original request */
+	void		*ptr;
+	size_t		size;
+
+	/* Safe buffer information */
+	void		*safe;
+	dma_addr_t	safe_dma_addr;
+};
+
+LIST_HEAD(safe_buffers);
+
+static spinlock_t pcibuf_lock = SPIN_LOCK_UNLOCKED;
+
+static inline void *
+alloc_safe_buffer(void *unsafe, int size, dma_addr_t *dma_addr)
+{
+	struct safe_buffer *safe_buf;
+	unsigned long flags;
+
+	DBG("alloc_safe_buffer(size=%d)\n", size);
+
+	/*
+	 * This should really be it's own object cache...
+	 */
+	safe_buf = kmalloc(sizeof(*safe_buf), GFP_ATOMIC);
+	if(!safe_buf)
+		return 0;
+
+	safe_buf->safe = kmalloc(size, GFP_DMA | GFP_ATOMIC);
+
+	if (!safe_buf->safe) {
+		kfree(safe_buf);
+		return 0;
+	}
+
+	safe_buf->ptr = unsafe;
+	safe_buf->size = size;
+	*dma_addr = safe_buf->safe_dma_addr = virt_to_bus(safe_buf->safe);
+
+	spin_lock_irqsave(&pcibuf_lock, flags);
+	list_add(&safe_buf->node, &safe_buffers);
+	spin_unlock_irqrestore(&pcibuf_lock, flags);
+
+	return safe_buf->safe;
+}
+
+static inline void 
+free_safe_buffer(struct safe_buffer *safe_buf)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pcibuf_lock, flags);
+	list_del(&safe_buf->node);
+	kfree(safe_buf->safe);
+	kfree(safe_buf);
+	spin_unlock_irqrestore(&pcibuf_lock, flags);
+}
+
+static inline void*
+find_safe_buffer(dma_addr_t dma_addr, void **unsafe)
+{
+	struct list_head *entry;
+	struct safe_buffer *safe_buf; 
+	unsigned long flags;
+
+	spin_lock_irqsave(&pcibuf_lock, flags);
+	list_for_each(entry, &safe_buffers) {
+		safe_buf = list_entry(entry, struct safe_buffer, node);
+		
+		if(safe_buf->safe_dma_addr == dma_addr) {
+			*unsafe = safe_buf->ptr;
+			spin_unlock_irqrestore(&pcibuf_lock, flags);
+			return safe_buf;
+		}
+	}
+	spin_unlock_irqrestore(&pcibuf_lock, flags);
+
+	return 0;	    
+}
+
+dma_addr_t ixp425_map_single(void *virt, size_t size, int direction)
+{
+	dma_addr_t dma_addr;
+	unsigned long flags;
+	void *safe;
+
+	DBG("ixp425_map_single(virt=%p,size=%d,dir=%x)\n", 
+		virt, size, direction);
+
+	/*
+	 * FIX ME: We are assuming we are in host mode and therefore
+	 * the inbound BAR is set to 0.  
+	 *
+	 * Need to check (dma_addr + size ) > (BAR0 + SZ_64M)
+	 */
+	dma_addr = virt_to_bus(virt);
+
+	if((dma_addr+size) >= SZ_64M) {
+		safe = alloc_safe_buffer(virt, size, &dma_addr);
+		if (!safe) {
+			printk(KERN_ERR "%s: Could not allocate safe buffer",
+					__FILE__);
+			return 0;
+		}
+
+		DBG("unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", virt, 
+			(void *)virt_to_phys(virt), safe, (void *)dma_addr);
+
+		/*
+		 * Only need to copy if DMAing to device
+		 */
+		if((direction == PCI_DMA_TODEVICE) || 
+		   (direction == PCI_DMA_BIDIRECTIONAL)) {
+			memcpy(safe, virt, size);
+		}
+		consistent_sync(safe, size, direction);
+	}
+	else
+		consistent_sync(virt, size, direction);
+
+	return dma_addr;
+}
+
+void ixp425_unmap_single(dma_addr_t dma_addr, size_t size, int direction)
+{
+	void *safe, *unsafe;
+	unsigned long flags;
+	struct safe_buffer *safe_buf;
+
+	DBG("ixp425_unmap_single(ptr=%p, size=%d, dir=%x)\n",  
+		(void *)dma_addr, size, direction);
+
+	if ((safe_buf = find_safe_buffer(dma_addr, &unsafe))) {
+		if((direction == PCI_DMA_FROMDEVICE) ||
+		   (direction == PCI_DMA_BIDIRECTIONAL)) {
+			DBG("copyback unsafe %p, safe %p, size %d\n", unsafe, safe_buf->safe, size);
+			consistent_sync(safe_buf->safe, size, direction);
+			memcpy(unsafe, safe_buf->safe, size);
+		}
+	
+		free_safe_buffer(safe_buf);
+	} else {
+		/* 
+		 * Assume this is normal memory.  We have a possible
+		 * OOPs here if someone sends us a bad dma_addr_t.
+		 */
+		unsafe = bus_to_virt(dma_addr);
+		consistent_sync(unsafe, size, direction);
+	}
+}
+
+void ixp425_sync_single(dma_addr_t dma_addr, size_t size, int direction)
+{
+	void *safe, *unsafe;
+	unsigned long flags;
+	struct safe_buffer *safe_buf;
+
+	DBG("ixp425_sync_single(dma_addr=%p, size=%d, dir=%x)\n", 
+		(void *)dma_addr, size, direction);
+
+	if((safe_buf = find_safe_buffer(dma_addr, &unsafe))) {
+		DBG("copyback unsafe %p, safe %p, size %d\n", unsafe, safe_buf->safe, size);
+		switch(direction) {
+			case PCI_DMA_TODEVICE:
+				memcpy(safe_buf->safe, unsafe, size);
+				consistent_sync(safe_buf->safe, size, direction);
+				break;
+			case PCI_DMA_FROMDEVICE:
+				consistent_sync(safe_buf->safe, size, direction);
+				memcpy(unsafe, safe_buf->safe, size);
+				break;
+		}
+	} else {
+		/* assume this is normal memory */
+		unsafe = bus_to_virt(dma_addr);
+		consistent_sync(unsafe, size, direction);
+	}
+}
+
+
+EXPORT_SYMBOL(ixp425_map_single);
+EXPORT_SYMBOL(ixp425_unmap_single);
+EXPORT_SYMBOL(ixp425_sync_single);
+
+
diff -urN linux-2.4.29/arch/arm/mach-ixp425/pci.c linux-2.4.29-uc1/arch/arm/mach-ixp425/pci.c
--- linux-2.4.29/arch/arm/mach-ixp425/pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/pci.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,250 @@
+/*
+ * arch/arm/mach-iop310/pci.c
+ *
+ * Generic PCI support functionality that should eventually move to
+ * arch/arm/kernel/bios32.c.  Derived from support in ppc and alpha.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/pci-bridge.h>
+
+#define DEBUG 
+
+#ifdef DEBUG
+#define  DBG(x...) printk(x)
+#else
+#define  DBG(x...)
+#endif
+
+struct pci_controller* hose_head;
+struct pci_controller** hose_tail = &hose_head;
+
+/*
+ * The following code swizzles for exactly one bridge.  The routine
+ * common_swizzle below handles multiple bridges.  But there are a
+ * some boards that don't follow the PCI spec's suggestion so we
+ * break this piece out separately.
+ */
+static inline u8
+bridge_swizzle(u8 pin, u8 slot)
+{
+	return (((pin-1) + slot) % 4) + 1;
+}
+
+u8 __init
+common_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	struct pci_controller *hose;
+	
+	hose = pci_bus_to_hose(dev->bus->number);
+
+	if (dev->bus->number != hose->first_busno) {
+		u8 pin = *pinp;
+		do {
+			pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+			/* Move up the chain of bridges. */
+			dev = dev->bus->self;
+		} while (dev->bus->self);
+		*pinp = pin;
+
+		/* The slot is the slot of the last bridge. */
+	}
+
+	return PCI_SLOT(dev->devfn);
+}
+
+/*
+ * Null PCI config access functions, for the case when we can't
+ * find a hose.
+ */
+#define NULL_PCI_OP(rw, size, type)					\
+static int								\
+null_##rw##_config_##size(struct pci_dev *dev, int offset, type val)	\
+{									\
+	return PCIBIOS_DEVICE_NOT_FOUND;    				\
+}
+
+	NULL_PCI_OP(read, byte, u8 *)
+	NULL_PCI_OP(read, word, u16 *)
+	NULL_PCI_OP(read, dword, u32 *)
+	NULL_PCI_OP(write, byte, u8)
+	NULL_PCI_OP(write, word, u16)
+NULL_PCI_OP(write, dword, u32)
+
+static struct pci_ops null_pci_ops =
+{
+	null_read_config_byte,
+	null_read_config_word,
+	null_read_config_dword,
+	null_write_config_byte,
+	null_write_config_word,
+	null_write_config_dword
+};
+
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+struct pci_dev *
+fake_pci_dev(struct pci_controller *hose, int busnr, int devfn)
+{
+	static struct pci_dev dev;
+	static struct pci_bus bus;
+
+	if (hose == 0) {
+		hose = pci_bus_to_hose(busnr);
+		if (hose == 0)
+			printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);
+	}
+	dev.bus = &bus;
+	dev.sysdata = hose;
+	dev.devfn = devfn;
+	bus.number = busnr;
+	bus.ops = hose? hose->ops: &null_pci_ops;
+	return &dev;
+}
+
+static int next_controller_index;
+
+struct pci_controller * __init
+pcibios_alloc_controller(void)
+{
+	struct pci_controller *hose;
+
+	hose = (struct pci_controller *)kmalloc(sizeof(*hose), GFP_KERNEL);
+	memset(hose, 0, sizeof(struct pci_controller));
+	
+	*hose_tail = hose;
+	hose_tail = &hose->next;
+
+	hose->index = next_controller_index++;
+
+	return hose;
+}
+	
+struct pci_controller *
+pci_bus_to_hose(int bus)
+{
+	struct pci_controller *hose = hose_head;
+
+	for (; hose; hose = hose->next)
+		if (bus >= hose->first_busno && bus <= hose->last_busno)
+			return hose;
+	return NULL;
+}
+
+void __init
+pci_exclude_device(unsigned char bus, unsigned char devfn)
+{
+	struct pci_dev *dev, *pdev = NULL;
+
+	/* Walk the pci device list */
+	pci_for_each_dev(dev)
+	{
+		if ((dev->bus->number == bus) && (dev->devfn == devfn))
+		{
+			/*
+			 * Remove the device from the global and
+			 * bus lists.
+			 */
+			list_del(&(dev->global_list));
+			list_del(&(dev->bus_list));
+
+			/* Free the pci_dev structure */
+			kfree(dev);
+
+			break;
+		}
+		pdev = dev;
+	}
+}
+
+static inline void __init alloc_resource(struct pci_dev *dev, int idx)
+{
+	struct resource *pr, *r = &dev->resource[idx];
+
+	pr = pci_find_parent_resource(dev, r);
+	if(!pr || request_resource(pr, r) < 0)
+	{
+		printk(KERN_ERR "PCI: Can not allocate resource region %d" \
+				" of device %s\n", idx, dev->slot_name);
+		r->end -= r->start;
+		r->start = 0;
+	}
+}
+
+void __init
+pcibios_allocate_bus_resources(struct list_head *bus_list)
+{
+	struct list_head *ln;
+	struct pci_bus *bus;
+	int i;
+	struct resource *res, *pr;
+
+	if(!bus_list) return; 
+
+	/* Depth-First Search on bus tree */
+	for (ln = bus_list->next; ln != bus_list; ln=ln->next) {
+		bus = pci_bus_b(ln);
+		pci_read_bridge_bases(bus);
+		for (i = 0; i < 4; ++i) {
+			if ((res = bus->resource[i]) == NULL || !res->flags)
+				continue;
+			if (bus->parent == NULL)
+				pr = (res->flags & IORESOURCE_IO)?
+					&ioport_resource: &iomem_resource;
+			else
+				pr = pci_find_parent_resource(bus->self, res);
+
+			if (pr && request_resource(pr, res) == 0)
+				continue;
+			printk(KERN_ERR "PCI: Can not allocate resource region "
+			       "%d of PCI bridge %d\n", i, bus->number);
+			DBG("PCI: resource is %lx..%lx (%lx)\n",
+					res->start, res->end, res->flags);
+		}
+		pcibios_allocate_bus_resources(&bus->children);
+	}
+}
+
+void __init pcibios_allocate_resources(void)
+{
+	struct pci_dev *dev;
+	int idx, disabled;
+	u16 command;
+	struct resource *r;
+
+	pci_for_each_dev(dev)
+	{
+		pci_read_config_word(dev, PCI_COMMAND, &command);
+		for(idx = 0; idx < 6; idx++)
+		{
+			r = &dev->resource[idx];
+
+			if(r->parent)
+				continue;
+			if(!r->start)
+				continue;
+
+			alloc_resource(dev, idx);
+		}
+	}
+}
+
+
diff -urN linux-2.4.29/arch/arm/mach-ixp425/pci-io.c linux-2.4.29-uc1/arch/arm/mach-ixp425/pci-io.c
--- linux-2.4.29/arch/arm/mach-ixp425/pci-io.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/pci-io.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,127 @@
+/*
+ * arch/arm/mach-ixp425/ixp425-io.c 
+ *
+ * PCI I/O routines for IXP425.  IXP425 does not have an outbound 
+ * I/O window, so we need to manually convert each operation into
+ * a set of register acceses to configure the PCI byye lanes
+ * that we want enabled, and then do the transaction.
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * TODO: We probably want to at least inline these, and maybe
+ * even ix425_pci_write?
+ */
+
+#include <linux/module.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+void ixp425_outb(u8 v, u32 p)
+{
+	u32 n, byte_enables, data;
+	n = p % 4;
+	byte_enables = (0xf & ~BIT(n)) << IXP425_PCI_NP_CBE_BESL;
+	data = v << (8*n);
+	ixp425_pci_write(p, byte_enables | NP_CMD_IOWRITE, data);
+}
+
+void ixp425_outw(u16 v, u32 p)
+{
+	u32 n, byte_enables, data;
+	n = p % 4;
+	byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP425_PCI_NP_CBE_BESL;
+	data = v << (8*n);
+	ixp425_pci_write(p, byte_enables | NP_CMD_IOWRITE, data);
+}
+
+void ixp425_outl(u32 v, u32 p)
+{
+	ixp425_pci_write(p, NP_CMD_IOWRITE, v);
+}
+
+u8 ixp425_inb(u32 p)
+{
+	u32 n, byte_enables, data;
+	n = p % 4;
+	byte_enables = (0xf & ~BIT(n)) << IXP425_PCI_NP_CBE_BESL;
+	if (ixp425_pci_read(p, byte_enables | NP_CMD_IOREAD, &data))
+		return 0xff;
+
+	return data >> (8*n);
+}
+
+u16 ixp425_inw(u32 p)
+{
+	u32 n, byte_enables, data;
+	n = p % 4;
+	byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP425_PCI_NP_CBE_BESL;
+	if (ixp425_pci_read(p, byte_enables | NP_CMD_IOREAD, &data))
+		return 0xffff;
+
+	return data>>(8*n);
+}
+
+u32 ixp425_inl(u32 p)
+{
+	u32 data;
+	if (ixp425_pci_read(p, NP_CMD_IOREAD, &data))
+		return 0xffffffff;
+
+	return data;
+}
+
+void ixp425_outsb(u32 p, u8 *addr, u32 count)
+{
+	while (count--)
+		outb(*addr++, p);
+}
+
+void ixp425_outsw(u32 p, u16 *addr, u32 count)
+{
+	while (count--)
+		outw(*addr++, p);
+}
+
+void ixp425_outsl(u32 p, u32 *addr, u32 count)
+{
+	while (count--)
+		outl(*addr++, p);
+}
+
+void ixp425_insb(u32 p, u8 *addr, u32 count)
+{
+	while (count--)
+		*addr++ = inb(p);
+}
+
+void ixp425_insw(u32 p, u16 *addr, u32 count)
+{
+	while (count--)
+		*addr++ = inw(p);
+}
+
+void ixp425_insl(u32 p, u32 *addr, u32 count)
+{
+	while (count--)
+		*addr++ = inl(p);
+}
+
+EXPORT_SYMBOL(ixp425_outb);
+EXPORT_SYMBOL(ixp425_outw);
+EXPORT_SYMBOL(ixp425_outl);
+EXPORT_SYMBOL(ixp425_inb);
+EXPORT_SYMBOL(ixp425_inw);
+EXPORT_SYMBOL(ixp425_inl);
+EXPORT_SYMBOL(ixp425_outsb);
+EXPORT_SYMBOL(ixp425_outsw);
+EXPORT_SYMBOL(ixp425_outsl);
+EXPORT_SYMBOL(ixp425_insb);
+EXPORT_SYMBOL(ixp425_insw);
+EXPORT_SYMBOL(ixp425_insl);
+
diff -urN linux-2.4.29/arch/arm/mach-ixp425/prpmc1100-pci.c linux-2.4.29-uc1/arch/arm/mach-ixp425/prpmc1100-pci.c
--- linux-2.4.29/arch/arm/mach-ixp425/prpmc1100-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/prpmc1100-pci.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,93 @@
+/*
+ * arch/arm/mach-ixp425/prpmc1100-pci.c 
+ *
+ * PrPMC1100 PCI initialization
+ *
+ * Copyright (C) 2003 MontaVista Sofwtare, Inc. 
+ * Based on IXDP425 code originally (C) Intel Corporation
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * PrPMC1100 PCI init code.  GPIO usage is similar to that on 
+ * IXDP425, but the IRQ routing is completely different and
+ * depends on what carrier you are using. This code is written
+ * to work on the Motorola PrPMC800 ATX carrier board.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <asm/mach/pci.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/arch/pci.h>
+
+
+/* PCI controller pin mappings */
+#define INTA_PIN	IXP425_GPIO_PIN_11
+#define INTB_PIN	IXP425_GPIO_PIN_10
+#define	INTC_PIN	IXP425_GPIO_PIN_9
+#define	INTD_PIN	IXP425_GPIO_PIN_8
+
+#define IXP425_PCI_RESET_GPIO   IXP425_GPIO_PIN_13
+#define IXP425_PCI_CLK_PIN      IXP425_GPIO_CLK_0
+#define IXP425_PCI_CLK_ENABLE   IXP425_GPIO_CLK0_ENABLE
+#define IXP425_PCI_CLK_TC_LSH   IXP425_GPIO_CLK0TC_LSH
+#define IXP425_PCI_CLK_DC_LSH   IXP425_GPIO_CLK0DC_LSH
+
+void __init prpmc1100_pci_init(void *sysdata)
+{
+	gpio_line_config(INTA_PIN, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+	gpio_line_config(INTB_PIN, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+	gpio_line_config(INTC_PIN, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+	gpio_line_config(INTD_PIN, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+
+	gpio_line_isr_clear(INTA_PIN);
+	gpio_line_isr_clear(INTB_PIN);
+	gpio_line_isr_clear(INTC_PIN);
+	gpio_line_isr_clear(INTD_PIN);
+
+	ixp425_pci_init(sysdata);
+}
+
+
+/*
+ * Interrupt mapping
+ */
+#define INTA			IRQ_PRPMC1100_PCI_INTA
+#define INTB			IRQ_PRPMC1100_PCI_INTB
+#define INTC			IRQ_PRPMC1100_PCI_INTC
+#define INTD			IRQ_PRPMC1100_PCI_INTD
+
+static int __init prpmc1100_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
+{
+	const long min_idsel = 10, max_idsel = 16, irqs_per_slot = 4;
+
+	static int pci_irq_table[][4] = 
+	{
+		{INTD, INTA, INTB, INTC},	/* IDSEL 16 - PMC A1 */
+		{INTD, INTA, INTB, INTC},	/* IDSEL 17 - PRPMC-A-B */
+		{INTA, INTB, INTC, INTD},	/* IDSEL 18 - PMC A1-B */
+		{0, 0, 0, 0},			/* IDSEL 19 - Unused */
+		{INTA, INTB, INTC, INTD},	/* IDSEL 20 - P2P Bridge */
+		{INTC, INTD, INTA, INTB},	/* IDSEL 21 - PMC A2 */
+		{INTD, INTA, INTB, INTC},	/* IDSEL 22 - PMC A2-B */
+	};
+
+
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+
+struct hw_pci prpmc1100_pci __initdata = {
+	init:		prpmc1100_pci_init,
+	swizzle:	common_swizzle,
+	map_irq:	prpmc1100_map_irq,
+};
+
diff -urN linux-2.4.29/arch/arm/mach-ixp425/sg580-pci.c linux-2.4.29-uc1/arch/arm/mach-ixp425/sg580-pci.c
--- linux-2.4.29/arch/arm/mach-ixp425/sg580-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ixp425/sg580-pci.c	2005-06-14 02:11:00.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/mach-ixp425/sg580-pci.c 
+ *
+ * CyberGuard/SG580 PCI initialization
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <asm/mach/pci.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/arch/pci.h>
+
+
+/* PCI controller pin mappings */
+#define INTA_PIN	IXP425_GPIO_PIN_8
+
+void __init sg580_pci_init(void *sysdata)
+{
+	gpio_line_config(INTA_PIN, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+	gpio_line_isr_clear(INTA_PIN);
+	ixp425_pci_init(sysdata);
+}
+
+static int __init sg580_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if ((slot == 12) || (slot == 14))
+		return IRQ_SG580_PCI_INTA;
+	return -1;
+}
+
+struct hw_pci sg580_pci __initdata = {
+	init:		sg580_pci_init,
+	swizzle:	common_swizzle,
+	map_irq:	sg580_map_irq,
+};
+
diff -urN linux-2.4.29/arch/arm/mach-ks8695/arch.c linux-2.4.29-uc1/arch/arm/mach-ks8695/arch.c
--- linux-2.4.29/arch/arm/mach-ks8695/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ks8695/arch.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,106 @@
+/*
+ *  linux/arch/arm/mach-ks8695/arch.c
+ *
+ *  Copyright (C) 2002 Micrel Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/config.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/amba_kmi.h>
+#include <asm/arch/platform.h>
+
+extern void ks8695_map_io(void);
+extern void ks8695_init_irq(void);
+
+#ifdef CONFIG_KMI_KEYB
+static struct kmi_info ks8695_keyboard __initdata = {
+	base:	IO_ADDRESS(KMI0_BASE),
+	irq:	IRQ_KMIINT0,
+	divisor: 24 / 8 - 1,
+	type:	KMI_KEYBOARD,
+};
+
+static struct kmi_info ks8695_mouse __initdata = {
+	base:	IO_ADDRESS(KMI1_BASE),
+	irq:	IRQ_KMIINT1,
+	divisor: 24 / 8 - 1,
+	type:	KMI_MOUSE,
+};
+#endif
+
+static void __init
+ks8695_fixup(struct machine_desc *desc, struct param_struct *unused,
+		 char **cmdline, struct meminfo *mi)
+{
+#ifdef CONFIG_KMI_KEYB
+	register_kmi(&ks8695_keyboard);
+	register_kmi(&ks8695_mouse);
+#endif
+}
+
+#ifdef CONFIG_MACH_LITE300
+MACHINE_START(KS8695, "SnapGear-LITE300")
+	MAINTAINER("SnapGear Inc.")
+	BOOT_MEM(KS8695_MEM_START, KS8695_IO_BASE, 0xF0000000)
+	BOOT_PARAMS(0x00000100)
+	FIXUP(ks8695_fixup)
+	MAPIO(ks8695_map_io)
+	INITIRQ(ks8695_init_irq)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_CM4008
+MACHINE_START(KS8695, "OpenGear/CM4008")
+	MAINTAINER("OpenGear Inc.")
+	BOOT_MEM(KS8695_MEM_START, KS8695_IO_BASE, 0xF0000000)
+	BOOT_PARAMS(0x00000100)
+	FIXUP(ks8695_fixup)
+	MAPIO(ks8695_map_io)
+	INITIRQ(ks8695_init_irq)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_CM41xx
+MACHINE_START(KS8695, "OpenGear/CM41xx")
+	MAINTAINER("OpenGear Inc.")
+	BOOT_MEM(KS8695_MEM_START, KS8695_IO_BASE, 0xF0000000)
+	BOOT_PARAMS(0x00000100)
+	FIXUP(ks8695_fixup)
+	MAPIO(ks8695_map_io)
+	INITIRQ(ks8695_init_irq)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_KS8695
+MACHINE_START(KS8695, "Micrel-KS8695")
+	MAINTAINER("Micrel Inc.")
+	BOOT_MEM(KS8695_MEM_START, KS8695_IO_BASE, 0xF0000000)
+	BOOT_PARAMS(0x00000100)
+	FIXUP(ks8695_fixup)
+	MAPIO(ks8695_map_io)
+	INITIRQ(ks8695_init_irq)
+MACHINE_END
+#endif
diff -urN linux-2.4.29/arch/arm/mach-ks8695/cpu.c linux-2.4.29-uc1/arch/arm/mach-ks8695/cpu.c
--- linux-2.4.29/arch/arm/mach-ks8695/cpu.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ks8695/cpu.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,136 @@
+/*
+ *  linux/arch/arm/mach-ks8695/cpu.c
+ *
+ *  Copyright (C) 2002 Micrel Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * CPU support functions
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/cpufreq.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#define CM_ID  	(IO_ADDRESS(KS8695_HDR_BASE)+KS8695_HDR_ID_OFFSET)
+#define CM_OSC	(IO_ADDRESS(KS8695_HDR_BASE)+KS8695_HDR_OSC_OFFSET)
+#define CM_STAT (IO_ADDRESS(KS8695_HDR_BASE)+KS8695_HDR_STAT_OFFSET)
+#define CM_LOCK (IO_ADDRESS(KS8695_HDR_BASE)+KS8695_HDR_LOCK_OFFSET)
+
+struct vco {
+	unsigned char vdw;
+	unsigned char od;
+};
+
+/*
+ * Divisors for each OD setting.
+ */
+static unsigned char cc_divisor[8] = { 10, 2, 8, 4, 5, 7, 9, 6 };
+
+static unsigned int vco_to_freq(struct vco vco, int factor)
+{
+	return 2000 * (vco.vdw + 8) / cc_divisor[vco.od] / factor;
+}
+
+#ifdef CONFIG_CPU_FREQ
+/*
+ * Divisor indexes for in ascending divisor order
+ */
+static unsigned char s2od[] = { 1, 3, 4, 7, 5, 2, 6, 0 };
+
+static struct vco freq_to_vco(unsigned int freq_khz, int factor)
+{
+	struct vco vco = {0, 0};
+	unsigned int i, f;
+
+	freq_khz *= factor;
+
+	for (i = 0; i < 8; i++) {
+		f = freq_khz * cc_divisor[s2od[i]];
+		/* f must be between 10MHz and 320MHz */
+		if (f > 10000 && f <= 320000)
+			break;
+	}
+
+	vco.od  = s2od[i];
+	vco.vdw = f / 2000 - 8;
+
+	return vco;
+}
+
+/*
+ * Validate the speed in khz.  If it is outside our
+ * range, then return the lowest.
+ */
+unsigned int ks8695_validatespeed(unsigned int freq_khz)
+{
+	struct vco vco;
+
+	if (freq_khz < 12000)
+		freq_khz = 12000;
+	if (freq_khz > 160000)
+		freq_khz = 160000;
+
+	vco = freq_to_vco(freq_khz, 1);
+
+	if (vco.vdw < 4 || vco.vdw > 152)
+		return -EINVAL;
+
+	return vco_to_freq(vco, 1);
+}
+
+void ks8695_setspeed(unsigned int freq_khz)
+{
+	struct vco vco = freq_to_vco(freq_khz, 1);
+	u_int cm_osc;
+
+	cm_osc = __raw_readl(CM_OSC);
+	cm_osc &= 0xfffff800;
+	cm_osc |= vco.vdw | vco.od << 8;
+
+	__raw_writel(0xa05f, CM_LOCK);
+	__raw_writel(cm_osc, CM_OSC);
+	__raw_writel(0, CM_LOCK);
+}
+#endif
+
+static int __init cpu_init(void)
+{
+	u_int cm_osc, cm_stat, cpu_freq_khz, mem_freq_khz;
+	struct vco vco;
+
+#if 1
+	__asm__("nop");
+(*(volatile u_int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_DATA)) = 0xFF;
+#endif
+	cm_osc = __raw_readl(CM_OSC);
+
+	vco.od  = (cm_osc >> 20) & 7;
+	vco.vdw = (cm_osc >> 12) & 255;
+	mem_freq_khz = vco_to_freq(vco, 2);
+
+	printk(KERN_INFO "Memory clock = %d.%03d MHz\n",
+		mem_freq_khz / 1000, mem_freq_khz % 1000);
+
+	vco.od = (cm_osc >> 8) & 7;
+	vco.vdw = cm_osc & 255;
+	cpu_freq_khz = vco_to_freq(vco, 1);
+
+#ifdef CONFIG_CPU_FREQ
+	cpufreq_init(cpu_freq_khz);
+	cpufreq_setfunctions(ks8695_validatespeed, ks8695_setspeed);
+#endif
+
+	cm_stat = __raw_readl(CM_STAT);
+	printk("Module id: %d\n", cm_stat & 255);
+
+	return 0;
+}
+
+__initcall(cpu_init);
diff -urN linux-2.4.29/arch/arm/mach-ks8695/dma.c linux-2.4.29-uc1/arch/arm/mach-ks8695/dma.c
--- linux-2.4.29/arch/arm/mach-ks8695/dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ks8695/dma.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ *  linux/arch/arm/mach-ks8695/dma.c
+ *
+ *  Copyright (C) 2002 Micrel Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/dma.h>
+
+void __init arch_dma_init(dma_t *dma)
+{
+}
diff -urN linux-2.4.29/arch/arm/mach-ks8695/irq.c linux-2.4.29-uc1/arch/arm/mach-ks8695/irq.c
--- linux-2.4.29/arch/arm/mach-ks8695/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ks8695/irq.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,79 @@
+/*
+ *  linux/arch/arm/mach-ks8695/irq.c
+ *
+ *  Copyright (C) 2002 Micrel Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/ptrace.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/arch/irq.h>	/* pick up fixup_irq definition */
+#include <asm/mach/irq.h>
+
+extern void do_ks8695_IRQ(int, struct pt_regs *);
+
+/* 
+ * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
+ * is the (PA >> 12).
+ *
+ * Setup a VA for the KS8695 interrupt controller (for header #0,
+ * just for now).
+ */
+#define VA_IO_BASE  IO_ADDRESS(KS8695_IO_BASE) 
+
+static void sc_mask_irq(unsigned int irq)
+{
+    __raw_writel(__raw_readl(VA_IO_BASE + KS8695_INT_ENABLE) & ~(1 << irq), VA_IO_BASE + KS8695_INT_ENABLE);
+}
+
+static void sc_unmask_irq(unsigned int irq)
+{
+   if ( irq == 8 )
+        return ;
+   __raw_writel(__raw_readl(VA_IO_BASE + KS8695_INT_ENABLE) | (1 << irq), VA_IO_BASE + KS8695_INT_ENABLE);
+}
+
+/*
+ * to handle UART interrupt in a special way
+ */
+
+void __init ks8695_init_irq(void)
+{
+	unsigned int i;
+
+        for (i = 0; i < NR_IRQS; i++) 
+        {
+           if (((1 << i) && KS8695_SC_VALID_INT) != 0) 
+           {
+              irq_desc[i].valid       = 1;
+              irq_desc[i].probe_ok    = 1;
+              irq_desc[i].noautoenable = 0;
+              irq_desc[i].mask_ack    = sc_mask_irq;
+              irq_desc[i].mask        = sc_mask_irq;
+              irq_desc[i].unmask      = sc_unmask_irq;
+           }
+        }
+
+	/* Disable all interrupts initially. */
+	__raw_writel(0, VA_IO_BASE + KS8695_INT_CONTL);
+	__raw_writel(0, VA_IO_BASE + KS8695_INT_ENABLE);
+}
diff -urN linux-2.4.29/arch/arm/mach-ks8695/ks8695_io.h linux-2.4.29-uc1/arch/arm/mach-ks8695/ks8695_io.h
--- linux-2.4.29/arch/arm/mach-ks8695/ks8695_io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ks8695/ks8695_io.h	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ *  linux/arch/arm/mach-ks8695/ks895_io.c
+ *
+ *  Copyright (C) 2002 Micrel Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef	__KS8695_IO_H
+#define	__KS8695_IO_H
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#define KS8695_VA_IO_BASE  IO_ADDRESS(KS8695_IO_BASE) 
+
+#define	KS8695_WRITE(offset, v)	__raw_writel((v), KS8695_VA_IO_BASE + (offset))
+#define	KS8695_READ(offset)	__raw_readl(KS8695_VA_IO_BASE + (offset))
+
+#endif	/* __KS8695_IO_H */
diff -urN linux-2.4.29/arch/arm/mach-ks8695/ks8695p_pci.c linux-2.4.29-uc1/arch/arm/mach-ks8695/ks8695p_pci.c
--- linux-2.4.29/arch/arm/mach-ks8695/ks8695p_pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ks8695/ks8695p_pci.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,345 @@
+/*
+	Copyright (c) 2003, Micrel Semiconductors
+
+	Written 2003 by LIQUN RUAN
+
+	This software may be used and distributed according to the terms of 
+	the GNU General Public License (GPL), incorporated herein by reference.
+	Drivers based on or derived from this code fall under the GPL and must
+	retain the authorship, copyright and license notice. This file is not
+	a complete program and may only be used when the entire operating
+	system is licensed under the GPL.
+
+	The author can be reached as liqun.ruan@micrel.com
+	Micrel Semiconductors
+	1931 Fortune Drive
+	San Jose, CA 95131
+
+	This driver is for Micrel's KS8695P SOHO Router Chipset as PCI bridge driver.
+
+	Support and updates available at
+	www.kendin.com or www.micrel.com
+
+*/
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/hardware.h>
+
+#include "ks8695_io.h"
+
+void ks8695p_configure_interrupt(void);
+
+#define	KS8695_CRCFID		0x2000
+#define	KS8695_2000		0x2000
+#define	KS8695_CRCFCS		0x2004
+#define	KS8695_2004		0x2004
+#define	KS8695_CRCFRV		0x2008
+#define	KS8695_2008		0x2008
+#define	KS8695_CRCFLT		0x200c
+#define	KS8695_200C		0x200c
+#define	KS8695_CRCBMA		0x2010
+#define	KS8695_2010		0x2010
+#define	KS8695_CRCBA0		0x2014
+#define	KS8695_2014		0x2014
+
+#define	KS8695_CRCSID		0x202c
+#define	KS8695_202C		0x202c
+
+#define	KS8695_CRCFIT		0x203c
+#define	KS8695_203C		0x203c
+
+/* note that PCI configuration bits are defined in pci.h already */
+
+/* bridge configuration related registers */
+#define	KS8695_PBCA			0x2100
+#define	KS8695_2100			0x2100
+#define	KS8695_PBCD			0x2104
+#define	KS8695_2104			0x2104
+
+/* bridge mode related registers */
+#define	KS8695_PBM			0x2200
+#define	KS8695_2200			0x2200
+#define	KS8695_PBCS			0x2204
+#define	KS8695_2204			0x2204
+#define	KS8695_PMBA			0x2208
+#define	KS8695_2208			0x2208
+#define	KS8695_PMBAC			0x220c
+#define	KS8695_220C			0x220c
+#define	KS8695_PMBAM			0x2210
+#define	KS8695_2210			0x2210
+#define	KS8695_PMBAT			0x2214
+#define	KS8695_2214			0x2214
+#define	KS8695_PIOBA			0x2218
+#define	KS8695_2218			0x2218
+#define	KS8695_PIOBAC			0x221c
+#define	KS8695_221C			0x221c
+#define	KS8695_PIOBAM			0x2220
+#define	KS8695_2220			0x2220
+#define	KS8695_PIOBAT			0x2224
+#define	KS8695_2224			0x2224
+
+/* since there is no extra bridge in KS8695P reference board, we only need to support
+ * type 0 configuration space access, but not type 1.
+ *
+ * Also use:
+ *	IDSEL 16 for slot 1, 
+ *	IDSEL 17 for slot 2,
+ *	IDSEL 18 for bridge if it is configured as a guest device.
+ */
+#define CONFIG_CMD(dev, where)   (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & 0xfffffffc))
+
+static int 
+ks8695p_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	u32 reg, shift;
+
+#ifdef	DEBUG_THIS
+	printk(KERN_INFO "%s: bus=%d\n", __FUNCTION__, dev->bus->number);
+#endif
+
+	/*RLQ, actually there is not need to do shift since the caller will guarantee alignment */
+	shift = where & 0x00000003;
+	KS8695_WRITE(KS8695_2100, CONFIG_CMD(dev, where));
+	reg = KS8695_READ(KS8695_2104);
+	*value = (u8)(reg >> (shift * 8));
+
+#ifdef	DEBUG_THIS
+	printk(KERN_INFO "%s: value=0x%02x\n", __FUNCTION__, *value);
+#endif
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+ks8695p_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	u32 reg, shift;
+
+#ifdef	DEBUG_THIS
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+#endif
+
+	shift = where & 0x00000002;
+	KS8695_WRITE(KS8695_2100, CONFIG_CMD(dev, where));
+	reg = KS8695_READ(KS8695_2104);
+	*value = (u16)(reg >> (shift * 8));
+
+#ifdef	DEBUG_THIS
+	printk(KERN_INFO "%s: value=0x%04x\n", __FUNCTION__, *value);
+#endif
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+ks8695p_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+#ifdef	DEBUG_THIS
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+#endif
+
+	KS8695_WRITE(KS8695_2100, CONFIG_CMD(dev, where));
+	*value = KS8695_READ(KS8695_2104);
+	
+#ifdef	DEBUG_THIS
+	printk(KERN_INFO "%s: value=0x%08x\n", __FUNCTION__, *value);
+#endif
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+ks8695p_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	u32 reg, shift;
+
+#ifdef	DEBUG_THIS
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+#endif
+
+	shift = where & 0x00000003;
+	KS8695_WRITE(KS8695_2100, CONFIG_CMD(dev, where));
+	reg = KS8695_READ(KS8695_2104);
+	
+	switch (shift) {
+	case 3:
+		reg &= 0x00ffffff;
+		reg |= (u32)value << 24;
+		break;
+
+	case 2:
+		reg &= 0xff00ffff;
+		reg |= (u32)value << 16;
+		break;
+
+	case 1:
+		reg &= 0xffff00ff;
+		reg |= (u32)value << 8;
+		break;
+
+	default:
+		reg &= 0xffffff00;
+		reg |= (u32)value;
+		break;
+	}
+
+	KS8695_WRITE(KS8695_2100, CONFIG_CMD(dev, where));
+	KS8695_WRITE(KS8695_2104, reg);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+ks8695p_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	u32 reg, shift;
+
+#ifdef	DEBUG_THIS
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+#endif
+
+	shift = where & 0x00000002;
+	KS8695_WRITE(KS8695_2100, CONFIG_CMD(dev, where));
+	reg = KS8695_READ(KS8695_2104);
+	
+	switch (shift) {
+	case 2:
+		reg &= 0x0000ffff;
+		reg |= (u32)value << 16;
+		break;
+
+	default:
+		reg &= 0xffff0000;
+		reg |= (u32)value;
+		break;
+	}
+
+	KS8695_WRITE(KS8695_2100, CONFIG_CMD(dev, where));
+	KS8695_WRITE(KS8695_2104, reg);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+ks8695p_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+#ifdef	DEBUG_THIS
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+#endif
+	KS8695_WRITE(KS8695_2100, CONFIG_CMD(dev, where));
+	KS8695_WRITE(KS8695_2104, value);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops ks8695p_ops = {
+	ks8695p_read_config_byte,
+	ks8695p_read_config_word,
+	ks8695p_read_config_dword,
+	ks8695p_write_config_byte,
+	ks8695p_write_config_word,
+	ks8695p_write_config_dword,
+};
+
+static struct resource pci_mem = {
+name:	"PCI memory space",
+start:	KS8695P_PCI_MEM_BASE,
+end:	KS8695P_PCI_MEM_BASE + KS8695P_PCI_MEM_SIZE - 1,
+flags:	IORESOURCE_MEM,
+};
+
+static struct resource pci_io = {
+name:	"PCI IO space",
+start:	KS8695P_PCI_IO_BASE,
+end:	KS8695P_PCI_IO_BASE + KS8695P_PCI_IO_SIZE - 1,
+flags:	IORESOURCE_IO,
+};
+
+void __init ks8695p_setup_resources(struct resource **resource)
+{
+	if (request_resource(&iomem_resource, &pci_mem))
+		printk("%s: request_resource for pci memory space failed\n", __FUNCTION__);
+
+	if (request_resource(&ioport_resource, &pci_io))
+		printk("%s: request_resource for pci IO space failed\n", __FUNCTION__);
+
+	resource[0] = &pci_io;
+	resource[1] = &pci_mem;
+	resource[2] = NULL;
+	resource[3] = NULL;
+}
+
+void __init ks8695p_configure_interrupt(void)
+{
+	u32	uReg;
+
+#ifdef	DEBUG_THIS
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+#endif
+	uReg = KS8695_READ(KS8695_GPIO_MODE);
+	uReg |= 0x00000001;	/* set it to output first */
+	KS8695_WRITE(KS8695_GPIO_MODE, uReg);
+
+	uReg = KS8695_READ(KS8695_GPIO_CTRL);
+	uReg &= 0xfffffff8;	/* EXT0 is used as PCI bus interrupt source */
+				/* level detection (active low) */
+	uReg |= 0x8;
+	KS8695_WRITE(KS8695_GPIO_CTRL, uReg);
+
+	uReg = KS8695_READ(KS8695_GPIO_MODE);
+	uReg &= ~0x00000001;	/* reset it to input first */
+	KS8695_WRITE(KS8695_GPIO_MODE, uReg);
+
+#ifdef	DEBUG_THIS
+	printk(KERN_INFO "%s: OK\n", __FUNCTION__);
+#endif
+}
+
+void __init ks8695p_init(void *sysdata)
+{
+#ifdef	DEBUG_THIS
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+#endif
+
+#if defined(CONFIG_MACH_CM4008) || defined(CONFIG_MACH_CM41xx)
+	/* Enable PCI reset line as output */
+	*((volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_MODE)) |= 0x2;
+
+	*((volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_DATA)) &= ~0x2;
+	udelay(10000);
+	*((volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_DATA)) |= 0x2;
+#endif
+
+	/* note that we need a stage 1 initialization in .S file to set 0x202c, 
+	 * before the stage 2 initialization here 
+	 */
+	KS8695_WRITE(KS8695_202C, 0x00010001);	/* stage 1 initialization, subid, subdevice = 0x0001 */
+
+	/* stage 2 initialization */
+	KS8695_WRITE(KS8695_2204, 0x40000000);	/* prefetch limits with 16 words, retru enable */
+
+	/* configure memory mapping */
+	KS8695_WRITE(KS8695_2208, KS8695P_PCIBG_MEM_BASE);
+       //KS8695_WRITE(KS8695_220C, PMBAC_TRANS_ENABLE);		/* enable memory address translation */
+	KS8695_WRITE(KS8695_2210, KS8695P_PCI_MEM_MASK);	/* mask bits */
+	KS8695_WRITE(KS8695_2214, KS8695P_PCI_MEM_BASE);	/* physical memory address */
+
+	/* configure IO mapping */
+	KS8695_WRITE(KS8695_2218, KS8695P_PCIBG_IO_BASE);
+        //KS8695_WRITE(KS8695_221C, PMBAC_TRANS_ENABLE);		/* enable IO address translation */
+	KS8695_WRITE(KS8695_2220, KS8695P_PCI_IO_MASK);		/* mask bits */
+	KS8695_WRITE(KS8695_2224, KS8695P_PCI_IO_BASE);
+
+	ks8695p_configure_interrupt();
+
+	pci_scan_bus(0, &ks8695p_ops, sysdata);
+}
+
diff -urN linux-2.4.29/arch/arm/mach-ks8695/Makefile linux-2.4.29-uc1/arch/arm/mach-ks8695/Makefile
--- linux-2.4.29/arch/arm/mach-ks8695/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ks8695/Makefile	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,24 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= ks8695.o
+
+# Object file lists.
+
+obj-y			:= arch.o irq.o mm.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= leds.o
+
+obj-$(CONFIG_LEDS)	+= leds.o
+obj-$(CONFIG_PCI)       += ks8695p_pci.o pci.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/arm/mach-ks8695/mm.c linux-2.4.29-uc1/arch/arm/mach-ks8695/mm.c
--- linux-2.4.29/arch/arm/mach-ks8695/mm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ks8695/mm.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,138 @@
+/*
+ *  linux/arch/arm/mach-ks8695/mm.c
+ *
+ *  Extra MM routines for the ARM Integrator board
+ *
+ *  Copyright (C) 1999,2000 Arm Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+ 
+#include <asm/mach/map.h>
+
+/*
+ * Logical      Physical
+ * f0000000	03FF0000	IO registers
+ */
+#ifndef SZ_768K
+#define	SZ_768K		(SZ_512K+SZ_256K)
+#endif
+ 
+static struct map_desc ks8695_io_desc[] __initdata = {
+#ifdef CONFIG_PCI_KS8695P
+  { IO_ADDRESS(KS8695_IO_BASE),        KS8695_IO_BASE,         SZ_64K,  DOMAIN_IO, 0, 1},	 
+#else  
+  { IO_ADDRESS(KS8695_PCMCIA_IO_BASE), KS8695_PCMCIA_IO_BASE,  SZ_768K, DOMAIN_IO, 0, 1},
+  { IO_ADDRESS(KS8695_IO_BASE),        KS8695_IO_BASE,         SZ_64K,  DOMAIN_IO, 0, 1},
+#endif	
+   LAST_DESC
+};
+
+void __init ks8695_map_io(void)
+{
+	iotable_init(ks8695_io_desc);
+}
+
+/*
+ * KS8695's internal ethernet driver doesn't use PCI bus at all. As a resumt
+ * call these set of functions instead
+ */
+void *consistent_alloc_ex(int gfp, size_t size, dma_addr_t *dma_handle)
+{
+	struct page *page, *end, *free;
+	unsigned long order;
+	void *ret, *virt;
+
+	if (in_interrupt())
+		BUG();
+
+	size = PAGE_ALIGN(size);
+	order = get_order(size);
+
+	page = alloc_pages(gfp, order);
+	if (!page)
+		goto no_page;
+
+	/*
+	 * We could do with a page_to_phys here
+	 */
+	virt = page_address(page);
+	*dma_handle = virt_to_phys(virt);
+	ret = __ioremap(virt_to_phys(virt), size, 0);
+	if (!ret)
+		goto no_remap;
+
+	/*
+	 * free wasted pages.  We skip the first page since we know
+	 * that it will have count = 1 and won't require freeing.
+	 * We also mark the pages in use as reserved so that
+	 * remap_page_range works.
+	 */
+	page = virt_to_page(virt);
+	free = page + (size >> PAGE_SHIFT);
+	end  = page + (1 << order);
+
+	for (; page < end; page++) {
+		set_page_count(page, 1);
+		if (page >= free)
+			__free_page(page);
+		else
+			SetPageReserved(page);
+	}
+	return ret;
+
+no_remap:
+	__free_pages(page, order);
+no_page:
+	return NULL;
+}
+
+/*
+ * free a page as defined by the above mapping.  We expressly forbid
+ * calling this from interrupt context.
+ */
+void consistent_free_ex(void *vaddr, size_t size, dma_addr_t handle)
+{
+	struct page *page, *end;
+	void *virt;
+
+	if (in_interrupt())
+		BUG();
+
+	virt = phys_to_virt(handle);
+
+	/*
+	 * More messing around with the MM internals.  This is
+	 * sick, but then so is remap_page_range().
+	 */
+	size = PAGE_ALIGN(size);
+	page = virt_to_page(virt);
+	end = page + (size >> PAGE_SHIFT);
+
+	for (; page < end; page++)
+		ClearPageReserved(page);
+
+	__iounmap(vaddr);
+}
diff -urN linux-2.4.29/arch/arm/mach-ks8695/pci.c linux-2.4.29-uc1/arch/arm/mach-ks8695/pci.c
--- linux-2.4.29/arch/arm/mach-ks8695/pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-ks8695/pci.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,56 @@
+/*
+ *  linux/arch/arm/mach-ks8695/pci.c
+ *
+ *  PCI bios-type initialisation for PCI machines
+ *
+ *  Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/hardware.h>
+
+#define DEBUG_THIS
+
+extern void ks8695p_init(void *);
+extern void ks8695p_setup_resources(struct resource **);
+
+static int __init ks8695p_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+#ifdef	DEBUG_THIS
+	printk("%s: slot=%d, pin=%d\n", __FUNCTION__, slot, pin);
+#endif
+	
+	return 2;
+
+#if	0
+	if (dev->devfn) return 20;	/* we use GPIO0 for interrupt, but may use it simply as indicator? */
+	else
+		return 0;
+#endif
+}
+
+static u8 __init ks8695p_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	int	pin = *pinp;
+
+#ifdef	DEBUG_THIS
+	printk("%s: pin=%d\n", __FUNCTION__, pin);
+#endif
+	//if (0 == pin) {
+		*pinp = 1;
+	//}
+	
+	return PCI_SLOT(dev->devfn);
+}
+
+struct hw_pci ks8695p_pci __initdata = {
+	setup_resources:ks8695p_setup_resources,
+	init:		ks8695p_init,
+	mem_offset:	0,
+	swizzle:	ks8695p_swizzle,
+	map_irq:	ks8695p_map_irq,
+};
diff -urN linux-2.4.29/arch/arm/mach-omaha/core.c linux-2.4.29-uc1/arch/arm/mach-omaha/core.c
--- linux-2.4.29/arch/arm/mach-omaha/core.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-omaha/core.c	2005-06-14 02:10:59.000000000 +0100
@@ -23,8 +23,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
diff -urN linux-2.4.29/arch/arm/mach-sa1100/kgdb-serial.c linux-2.4.29-uc1/arch/arm/mach-sa1100/kgdb-serial.c
--- linux-2.4.29/arch/arm/mach-sa1100/kgdb-serial.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-sa1100/kgdb-serial.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,99 @@
+/*
+ * FILE NAME: arch/arm/mach-integrator/kgdb-serial.c
+ *
+ * BRIEF MODULE DESCRIPTION:
+ *  Provides low level kgdb serial support hooks for SA-11x0 targets.
+ *
+ *  Author: MontaVista Software, Inc.  <source@mvista.com>
+ *          George G. Davis <gdavis@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE	LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/kgdb.h>
+
+
+#if	defined(CONFIG_KGDB_UART1)
+#	define	KGDB_SERIAL_PORT_BASE	&Ser1UTCR0
+#elif	defined(CONFIG_KGDB_UART2)
+#	define	KGDB_SERIAL_PORT_BASE	&Ser2UTCR0
+#elif	defined(CONFIG_KGDB_UART3)
+#	define	KGDB_SERIAL_PORT_BASE	&Ser3UTCR0
+#else
+#	error "No kgdb serial port UART has been selected."
+#endif
+
+#if	defined(CONFIG_KGDB_9600BAUD)
+#	define	KGDB_SERIAL_BAUD_RATE	(3686400/(9600 * 16) - 1)
+#elif	defined(CONFIG_KGDB_19200BAUD)
+#	define	KGDB_SERIAL_BAUD_RATE	(3686400/(19200 * 16) - 1)
+#elif	defined(CONFIG_KGDB_38400BAUD)
+#	define	KGDB_SERIAL_BAUD_RATE	(3686400/(38400 * 16) - 1)
+#elif	defined(CONFIG_KGDB_57600BAUD)
+#	define	KGDB_SERIAL_BAUD_RATE	(3686400/(57600 * 16) - 1)
+#elif	defined(CONFIG_KGDB_115200BAUD)
+#	define	KGDB_SERIAL_BAUD_RATE	(3686400/(115200 * 16) - 1)
+#else
+#	error "kgdb serial baud rate has not been specified."
+#endif
+
+
+#define UART(x)		(*(volatile unsigned long *)(serial_port + (x)))
+
+
+static unsigned long serial_port = 0;
+
+
+void
+kgdb_serial_init(void)
+{
+	serial_port = (unsigned long)(KGDB_SERIAL_PORT_BASE);
+
+	UART(UTCR3) = 0; /* disable */
+	UART(UTSR0) = 0xff; /* clear sticky bits */
+	UART(UTCR0) = UTCR0_8BitData; /* format: 8n1 */
+	UART(UTCR1) = (KGDB_SERIAL_BAUD_RATE >> 8) & 0xf;
+	UART(UTCR2) = KGDB_SERIAL_BAUD_RATE & 0xff;
+	UART(UTCR3) = UTCR3_RXE | UTCR3_TXE; /* enable */
+}
+
+
+void
+kgdb_serial_putchar(unsigned char ch)
+{
+	while (!(UART(UTSR1) & UTSR1_TNF)) ;
+
+	UART(UTDR) = ch;
+}
+
+
+unsigned char
+kgdb_serial_getchar(void)
+{
+        while (!(UART(UTSR1) & UTSR1_RNE)) ;
+        return (unsigned char)UART(UTDR);
+}
diff -urN linux-2.4.29/arch/arm/mach-sa1100/sa1100_usb.h linux-2.4.29-uc1/arch/arm/mach-sa1100/sa1100_usb.h
--- linux-2.4.29/arch/arm/mach-sa1100/sa1100_usb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-sa1100/sa1100_usb.h	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,193 @@
+/*
+ * sa1100_usb.h
+ *
+ * Public interface to the sa1100 USB core. For use by client modules
+ * like usb-eth and usb-char.
+ *
+ */
+
+#ifndef _SA1100_USB_H
+#define _SA1100_USB_H
+#include <asm/byteorder.h>
+
+typedef void (*usb_callback_t)(int flag, int size);
+
+/* in usb_ctl.c (see also descriptor methods at bottom of file) */
+
+// Open the USB client for client and initialize data structures
+// to default values, but _do not_ start UDC.
+int sa1100_usb_open( const char * client_name );
+
+// Start UDC running
+int sa1100_usb_start( void );
+
+// Immediately stop udc, fire off completion routines w/-EINTR
+int sa1100_usb_stop( void ) ;
+
+// Disconnect client from usb core
+int sa1100_usb_close( void ) ;
+
+// set notify callback for when core reaches configured state
+// return previous pointer (if any)
+typedef void (*usb_notify_t)(void);
+usb_notify_t sa1100_set_configured_callback( usb_notify_t callback );
+
+/* in usb_send.c */
+int sa1100_usb_xmitter_avail( void );
+int sa1100_usb_send(char *buf, int len, usb_callback_t callback);
+void sa1100_usb_send_reset(void);
+
+/* in usb_recev.c */
+int sa1100_usb_recv(char *buf, int len, usb_callback_t callback);
+void sa1100_usb_recv_reset(void);
+
+//////////////////////////////////////////////////////////////////////////////
+// Descriptor Management
+//////////////////////////////////////////////////////////////////////////////
+
+#define DescriptorHeader \
+	__u8 bLength;        \
+	__u8 bDescriptorType
+
+
+// --- Device Descriptor -------------------
+
+typedef struct {
+	 DescriptorHeader;
+	 __u16 bcdUSB;		   	/* USB specification revision number in BCD */
+	 __u8  bDeviceClass;	/* USB class for entire device */
+	 __u8  bDeviceSubClass; /* USB subclass information for entire device */
+	 __u8  bDeviceProtocol; /* USB protocol information for entire device */
+	 __u8  bMaxPacketSize0; /* Max packet size for endpoint zero */
+	 __u16 idVendor;        /* USB vendor ID */
+	 __u16 idProduct;       /* USB product ID */
+	 __u16 bcdDevice;       /* vendor assigned device release number */
+	 __u8  iManufacturer;	/* index of manufacturer string */
+	 __u8  iProduct;        /* index of string that describes product */
+	 __u8  iSerialNumber;	/* index of string containing device serial number */
+	 __u8  bNumConfigurations; /* number fo configurations */
+} __attribute__ ((packed)) device_desc_t;
+
+// --- Configuration Descriptor ------------
+
+typedef struct {
+	 DescriptorHeader;
+	 __u16 wTotalLength;	    /* total # of bytes returned in the cfg buf 4 this cfg */
+	 __u8  bNumInterfaces;      /* number of interfaces in this cfg */
+	 __u8  bConfigurationValue; /* used to uniquely ID this cfg */
+	 __u8  iConfiguration;      /* index of string describing configuration */
+	 __u8  bmAttributes;        /* bitmap of attributes for ths cfg */
+	 __u8  MaxPower;		    /* power draw in 2ma units */
+} __attribute__ ((packed)) config_desc_t;
+
+// bmAttributes:
+enum { USB_CONFIG_REMOTEWAKE=0x20, USB_CONFIG_SELFPOWERED=0x40,
+	   USB_CONFIG_BUSPOWERED=0x80 };
+// MaxPower:
+#define USB_POWER( x)  ((x)>>1) /* convert mA to descriptor units of A for MaxPower */
+
+// --- Interface Descriptor ---------------
+
+typedef struct {
+	 DescriptorHeader;
+	 __u8  bInterfaceNumber;   /* Index uniquely identfying this interface */
+	 __u8  bAlternateSetting;  /* ids an alternate setting for this interface */
+	 __u8  bNumEndpoints;      /* number of endpoints in this interface */
+	 __u8  bInterfaceClass;    /* USB class info applying to this interface */
+	 __u8  bInterfaceSubClass; /* USB subclass info applying to this interface */
+	 __u8  bInterfaceProtocol; /* USB protocol info applying to this interface */
+	 __u8  iInterface;         /* index of string describing interface */
+} __attribute__ ((packed)) intf_desc_t;
+
+// --- Endpoint  Descriptor ---------------
+
+typedef struct {
+	 DescriptorHeader;
+	 __u8  bEndpointAddress;  /* 0..3 ep num, bit 7: 0 = 0ut 1= in */
+	 __u8  bmAttributes;      /* 0..1 = 0: ctrl, 1: isoc, 2: bulk 3: intr */
+	 __u16 wMaxPacketSize;    /* data payload size for this ep in this cfg */
+	 __u8  bInterval;         /* polling interval for this ep in this cfg */
+} __attribute__ ((packed)) ep_desc_t;
+
+// bEndpointAddress:
+enum { USB_OUT= 0, USB_IN=1 };
+#define USB_EP_ADDRESS(a,d) (((a)&0xf) | ((d) << 7))
+// bmAttributes:
+enum { USB_EP_CNTRL=0, USB_EP_BULK=2, USB_EP_INT=3 };
+
+// --- String Descriptor -------------------
+
+typedef struct {
+	 DescriptorHeader;
+	 __u16 bString[1];		  /* unicode string .. actaully 'n' __u16s */
+} __attribute__ ((packed)) string_desc_t;
+
+/*=======================================================
+ * Handy helpers when working with above
+ *
+ */
+// these are x86-style 16 bit "words" ...
+#define make_word_c( w ) __constant_cpu_to_le16(w)
+#define make_word( w )   __cpu_to_le16(w)
+
+// descriptor types
+enum { USB_DESC_DEVICE=1, USB_DESC_CONFIG=2, USB_DESC_STRING=3,
+	   USB_DESC_INTERFACE=4, USB_DESC_ENDPOINT=5 };
+
+
+/*=======================================================
+ * Default descriptor layout for SA-1100 and SA-1110 UDC
+ */
+
+/* "config descriptor buffer" - that is, one config,
+   ..one interface and 2 endpoints */
+struct cdb {
+	 config_desc_t cfg;
+	 intf_desc_t   intf;
+	 ep_desc_t     ep1;
+	 ep_desc_t     ep2;
+} __attribute__ ((packed));
+
+
+/* all SA device descriptors */
+typedef struct {
+	 device_desc_t dev;   /* device descriptor */
+	 struct cdb b;        /* bundle of descriptors for this cfg */
+} __attribute__ ((packed)) desc_t;
+
+
+/*=======================================================
+ * Descriptor API
+ */
+
+/* Get the address of the statically allocated desc_t structure
+   in the usb core driver. Clients can modify this between
+   the time they call sa1100_usb_open() and sa1100_usb_start()
+*/
+desc_t *
+sa1100_usb_get_descriptor_ptr( void );
+
+
+/* Set a pointer to the string descriptor at "index". The driver
+ ..has room for 8 string indicies internally. Index zero holds
+ ..a LANGID code and is set to US English by default. Inidices
+ ..1-7 are available for use in the config descriptors as client's
+ ..see fit. This pointer is assumed to be good as long as the
+ ..SA usb core is open (so statically allocate them). Returnes -EINVAL
+ ..if index out of range */
+int sa1100_usb_set_string_descriptor( int index, string_desc_t * p );
+
+/* reverse of above */
+string_desc_t *
+sa1100_usb_get_string_descriptor( int index );
+
+/* kmalloc() a string descriptor and convert "p" to unicode in it */
+string_desc_t *
+sa1100_usb_kmalloc_string_descriptor( const char * p );
+
+
+
+
+
+
+#endif /* _SA1100_USB_H */
diff -urN linux-2.4.29/arch/arm/mach-sa1100/sa1111-ohci.c linux-2.4.29-uc1/arch/arm/mach-sa1100/sa1111-ohci.c
--- linux-2.4.29/arch/arm/mach-sa1100/sa1111-ohci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-sa1100/sa1111-ohci.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,140 @@
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/mm.h>
+
+#ifdef CONFIG_USB_OHCI
+
+/*
+ * The SA-1111 errata says that the DMA hardware needs to be exercised
+ * before the clocks are turned on to work properly.  This code does
+ * a tiny dma transfer to prime to hardware.
+ *
+ *  What DMA errata?  I've checked October 1999 and February 2001, both
+ *  of which do not mention such a bug, let alone any details of this
+ *  work-around.
+ */
+static void __init sa1111_dma_setup(void)
+{
+	dma_addr_t dma_buf;
+	void * vbuf;
+
+	/* DMA init & setup */
+
+	/* WARNING: The SA-1111 L3 function is used as part of this
+	 * SA-1111 DMA errata workaround.
+	 *
+	 * N.B., When the L3 function is enabled, it uses GPIO_B<4:5>
+	 * and takes precedence over the PS/2 mouse and GPIO_B
+	 * functions. Refer to "Intel StrongARM SA-1111 Microprocessor
+	 * Companion Chip, Sect 10.2" for details.  So this "fix" may
+	 * "break" support of either PS/2 mouse or GPIO_B if
+	 * precautions are not taken to avoid collisions in
+	 * configuration and use of these pins. AFAIK, no precautions
+	 * are taken at this time. So it is likely that the action
+	 * taken here may cause problems in PS/2 mouse and/or GPIO_B
+	 * pin use elsewhere.
+	 *
+	 * But wait, there's more... What we're doing here is
+	 * obviously altogether a bad idea. We're indiscrimanately bit
+	 * flipping config for a few different functions here which
+	 * are "owned" by other drivers. This needs to be handled
+	 * better than it is being done here at this time.  */
+
+	/* prime the dma engine with a tiny dma */
+	SKPCR |= SKPCR_I2SCLKEN;
+	SKAUD |= SKPCR_L3CLKEN | SKPCR_SCLKEN;
+
+	SACR0 |= 0x00003305;
+	SACR1 = 0x00000000;
+
+	/*
+	 * We need memory below 1MB.
+	 *  NOTE: consistent_alloc gives you some random virtual
+	 *  address as its return value, and the DMA address via
+	 *  the dma_addr_t pointer.
+	 */
+	vbuf = consistent_alloc(GFP_KERNEL | GFP_DMA, 4, &dma_buf);
+
+	SADTSA = (unsigned long)dma_buf;
+	SADTCA = 4;
+
+	SADTCS |= 0x00000011;
+	SKPCR |= SKPCR_DCLKEN;
+
+	/* wait */
+	udelay(100);
+
+	/* clear reserved but, then disable SAC */
+	SACR0 &= ~(0x00000002);
+	SACR0 &= ~(0x00000001);
+
+	/* toggle bit clock direction */
+	SACR0 |= 0x00000004;
+	SACR0 &= ~(0x00000004);
+
+	SKAUD &= ~(SKPCR_L3CLKEN | SKPCR_SCLKEN);
+
+	SKPCR &= ~SKPCR_I2SCLKEN;
+
+	consistent_free(vbuf, 4, dma_buf);
+}
+
+/*
+ * reset the SA-1111 usb controller and turn on it's clocks
+ */
+int __init sa1111_ohci_hcd_init(void)
+{
+	unsigned int usb_reset = 0;
+
+	if (machine_is_xp860() ||
+	    machine_has_neponset() ||
+	    machine_is_pfs168() ||
+	    machine_is_badge4())
+		usb_reset = USB_RESET_PWRSENSELOW | USB_RESET_PWRCTRLLOW;
+
+	/*
+	 * turn on USB clocks
+	 */
+	SKPCR |= SKPCR_UCLKEN;
+	udelay(100);
+
+	/*
+	 * Force USB reset
+	 */
+	USB_RESET = USB_RESET_FORCEIFRESET;
+	USB_RESET |= USB_RESET_FORCEHCRESET;
+	udelay(100);
+
+	/*
+	 * Take out of reset
+	 */
+	USB_RESET = 0;
+
+	/*
+	 * set power sense and control lines (this from the diags code)
+	 */
+        USB_RESET = usb_reset;
+
+        /*
+         * Huh?  This is a _read only_ register --rmk
+         */
+	USB_STATUS = 0;
+
+	udelay(10);
+
+	/*
+	 * compensate for dma bug
+	 */
+	sa1111_dma_setup();
+
+	return 0;
+}
+
+void sa1111_ohci_hcd_cleanup(void)
+{
+	/* turn the USB clock off */
+	SKPCR &= ~SKPCR_UCLKEN;
+}
+
+#endif /* CONFIG_USB_OHCI */
diff -urN linux-2.4.29/arch/arm/mach-sa1100/usb-char.c linux-2.4.29-uc1/arch/arm/mach-sa1100/usb-char.c
--- linux-2.4.29/arch/arm/mach-sa1100/usb-char.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-sa1100/usb-char.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,723 @@
+/*
+ * (C) Copyright 2000-2001 Extenex Corporation
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2 of the License, or
+ *	(at your option) any later version.
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  usb-char.c
+ *
+ *  Miscellaneous character device interface for SA1100 USB function
+ *	driver.
+ *
+ *  Background:
+ *  The SA1100 function driver ported from the Compaq Itsy project
+ *  has an interface, usb-eth.c, to feed network packets over the
+ *  usb wire and into the Linux TCP/IP stack.
+ *
+ *  This file replaces that one with a simple character device
+ *  interface that allows unstructured "byte pipe" style reads and
+ *  writes over the USB bulk endpoints by userspace programs.
+ *
+ *  A new define, CONFIG_SA1100_USB_NETLINK, has been created that,
+ *  when set, (the default) causes the ethernet interface to be used.
+ *  When not set, this more pedestrian character interface is linked
+ *  in instead.
+ *
+ *  Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
+ *
+ *  ward.willats@extenex.com
+ *
+ *  To do:
+ *  - Can't dma into ring buffer directly with pci_map/unmap usb_recv
+ *    uses and get bytes out at the same time DMA is going on. Investigate:
+ *    a) changing usb_recv to use alloc_consistent() at client request; or
+ *    b) non-ring-buffer based data structures. In the meantime, I am using
+ *    a bounce buffer. Simple, but wasteful.
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/cache.h>
+#include <linux/poll.h>
+#include <linux/circ_buf.h>
+#include <linux/timer.h>
+
+#include <asm/io.h>
+#include <asm/semaphore.h>
+#include <asm/proc/page.h>
+#include <asm/mach-types.h>
+
+#include "usb-char.h"
+#include "sa1100_usb.h"
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Driver  Options
+//////////////////////////////////////////////////////////////////////////////
+
+#define VERSION 	"0.4"
+
+
+#define VERBOSITY 1
+
+#if VERBOSITY
+# define	PRINTK(x, a...)	printk (x, ## a)
+#else
+# define	PRINTK(x, a...)	/**/
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// Globals - Macros - Enums - Structures
+//////////////////////////////////////////////////////////////////////////////
+#ifndef MIN
+#define MIN( a, b ) ((a)<(b)?(a):(b))
+#endif
+
+typedef int bool; enum { false = 0, true = 1 };
+
+static const char pszMe[] = "usbchr: ";
+
+static wait_queue_head_t wq_read;
+static wait_queue_head_t wq_write;
+static wait_queue_head_t wq_poll;
+
+/* Serialze multiple writers onto the transmit hardware
+.. since we sleep the writer during transmit to stay in
+.. sync. (Multiple writers don't make much sense, but..) */
+static DECLARE_MUTEX( xmit_sem );
+
+// size of usb DATA0/1 packets. 64 is standard maximum
+// for bulk transport, though most hosts seem to be able
+// to handle larger.
+#define TX_PACKET_SIZE 64
+#define RX_PACKET_SIZE 64
+#define RBUF_SIZE  (4*PAGE_SIZE)
+
+static struct wcirc_buf {
+  char *buf;
+  int in;
+  int out;
+} rx_ring = { NULL, 0, 0 };
+
+static struct {
+	 unsigned long  cnt_rx_complete;
+	 unsigned long  cnt_rx_errors;
+	 unsigned long  bytes_rx;
+	 unsigned long  cnt_tx_timeouts;
+	 unsigned long  cnt_tx_errors;
+	 unsigned long  bytes_tx;
+} charstats;
+
+
+static char * tx_buf = NULL;
+static char * packet_buffer = NULL;
+static int sending = 0;
+static int usb_ref_count = 0;
+static int last_tx_result = 0;
+static int last_rx_result = 0;
+static int last_tx_size = 0;
+static struct timer_list tx_timer;
+
+//////////////////////////////////////////////////////////////////////////////
+// Prototypes
+//////////////////////////////////////////////////////////////////////////////
+static char * 	what_the_f( int e );
+static void 	free_txrx_buffers( void );
+static void     twiddle_descriptors( void );
+static void     free_string_descriptors( void ) ;
+static int      usbc_open( struct inode *pInode, struct file *pFile );
+static void     rx_done_callback_packet_buffer( int flag, int size );
+
+static void     tx_timeout( unsigned long );
+static void     tx_done_callback( int flag, int size );
+
+static ssize_t  usbc_read( struct file *, char *, size_t, loff_t * );
+static ssize_t  usbc_write( struct file *, const char *, size_t, loff_t * );
+static unsigned int usbc_poll( struct file *pFile, poll_table * pWait );
+static int usbc_ioctl( struct inode *pInode, struct file *pFile,
+                       unsigned int nCmd, unsigned long argument );
+static int      usbc_close( struct inode *pInode, struct file *pFile );
+
+#ifdef CONFIG_SA1100_EXTENEX1
+static void     extenex_configured_notify_proc( void );
+#endif
+//////////////////////////////////////////////////////////////////////////////
+// Private Helpers
+//////////////////////////////////////////////////////////////////////////////
+
+static char * what_the_f( int e )
+{
+	 char * p;
+	 switch( e ) {
+	 case 0:
+		  p = "noErr";
+		  break;
+	 case -ENODEV:
+		  p = "ENODEV - usb not in config state";
+		  break;
+	 case -EBUSY:
+		  p = "EBUSY - another request on the hardware";
+		  break;
+	 case -EAGAIN:
+		  p = "EAGAIN";
+		  break;
+	 case -EINTR:
+		  p = "EINTR - interrupted\n";
+		  break;
+	 case -EPIPE:
+		  p = "EPIPE - zero length xfer\n";
+		  break;
+	 default:
+		  p = "????";
+		  break;
+	 }
+	 return p;
+}
+
+static void free_txrx_buffers( void )
+{
+	 if ( rx_ring.buf != NULL ) {
+		  kfree( rx_ring.buf );
+		  rx_ring.buf = NULL;
+	 }
+	 if ( packet_buffer != NULL ) {
+		  kfree( packet_buffer );
+		  packet_buffer = NULL;
+	 }
+	 if ( tx_buf != NULL ) {
+		  kfree( tx_buf );
+		  tx_buf = NULL;
+	 }
+}
+
+/* twiddle_descriptors()
+ * It is between open() and start(). Setup descriptors.
+ */
+static void twiddle_descriptors( void )
+{
+	 desc_t * pDesc = sa1100_usb_get_descriptor_ptr();
+	 string_desc_t * pString;
+
+	 pDesc->b.ep1.wMaxPacketSize = make_word_c( RX_PACKET_SIZE );
+	 pDesc->b.ep1.bmAttributes   = USB_EP_BULK;
+	 pDesc->b.ep2.wMaxPacketSize = make_word_c( TX_PACKET_SIZE );
+	 pDesc->b.ep2.bmAttributes   = USB_EP_BULK;
+
+	 if ( machine_is_extenex1() ) {
+#ifdef CONFIG_SA1100_EXTENEX1
+		  pDesc->dev.idVendor = make_word_c( 0xC9F );
+		  pDesc->dev.idProduct = 1;
+		  pDesc->dev.bcdDevice = make_word_c( 0x0001 );
+		  pDesc->b.cfg.bmAttributes = USB_CONFIG_SELFPOWERED;
+		  pDesc->b.cfg.MaxPower = 0;
+
+		  pString = sa1100_usb_kmalloc_string_descriptor( "Extenex" );
+		  if ( pString ) {
+			   sa1100_usb_set_string_descriptor( 1, pString );
+			   pDesc->dev.iManufacturer = 1;
+		  }
+
+		  pString = sa1100_usb_kmalloc_string_descriptor( "Handheld Theater" );
+		  if ( pString ) {
+			   sa1100_usb_set_string_descriptor( 2, pString );
+			   pDesc->dev.iProduct = 2;
+		  }
+
+		  pString = sa1100_usb_kmalloc_string_descriptor( "00000000" );
+		  if ( pString ) {
+			   sa1100_usb_set_string_descriptor( 3, pString );
+			   pDesc->dev.iSerialNumber = 3;
+		  }
+
+		  pString = sa1100_usb_kmalloc_string_descriptor( "HHT Bulk Transfer" );
+		  if ( pString ) {
+			   sa1100_usb_set_string_descriptor( 4, pString );
+			   pDesc->b.intf.iInterface = 4;
+		  }
+		  sa1100_set_configured_callback( extenex_configured_notify_proc );
+#endif
+	 }
+}
+
+static void free_string_descriptors( void )
+{
+	 if ( machine_is_extenex1() ) {
+		  string_desc_t * pString;
+		  int i;
+		  for( i = 1 ; i <= 4 ; i++ ) {
+			   pString = sa1100_usb_get_string_descriptor( i );
+			   if ( pString )
+					kfree( pString );
+		  }
+	 }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// ASYNCHRONOUS
+//////////////////////////////////////////////////////////////////////////////
+static  void kick_start_rx( void )
+{
+	 if ( usb_ref_count ) {
+		  int total_space  = CIRC_SPACE( rx_ring.in, rx_ring.out, RBUF_SIZE );
+		  if ( total_space >= RX_PACKET_SIZE ) {
+			   sa1100_usb_recv( packet_buffer,
+								RX_PACKET_SIZE,
+								rx_done_callback_packet_buffer
+						      );
+		  }
+	 }
+}
+/*
+ * rx_done_callback_packet_buffer()
+ * We have completed a DMA xfer into the temp packet buffer.
+ * Move to ring.
+ *
+ * flag values:
+ * on init,  -EAGAIN
+ * on reset, -EINTR
+ * on RPE, -EIO
+ * on short packet -EPIPE
+ */
+static void
+rx_done_callback_packet_buffer( int flag, int size )
+{
+	 charstats.cnt_rx_complete++;
+
+	 if ( flag == 0 || flag == -EPIPE ) {
+		  size_t n;
+
+		  charstats.bytes_rx += size;
+
+		  n = CIRC_SPACE_TO_END( rx_ring.in, rx_ring.out, RBUF_SIZE );
+		  n = MIN( n, size );
+		  size -= n;
+
+		  memcpy( &rx_ring.buf[ rx_ring.in ], packet_buffer, n );
+		  rx_ring.in = (rx_ring.in + n) & (RBUF_SIZE-1);
+		  memcpy( &rx_ring.buf[ rx_ring.in ], packet_buffer + n, size );
+		  rx_ring.in = (rx_ring.in + size) & (RBUF_SIZE-1);
+
+		  wake_up_interruptible( &wq_read );
+		  wake_up_interruptible( &wq_poll );
+
+		  last_rx_result = 0;
+
+		  kick_start_rx();
+
+	 } else if ( flag != -EAGAIN ) {
+		  charstats.cnt_rx_errors++;
+		  last_rx_result = flag;
+		  wake_up_interruptible( &wq_read );
+		  wake_up_interruptible( &wq_poll );
+	 }
+	 else  /* init, start a read */
+		  kick_start_rx();
+}
+
+
+static void tx_timeout( unsigned long unused )
+{
+	printk( "%stx timeout\n", pszMe );
+	sa1100_usb_send_reset();
+	charstats.cnt_tx_timeouts++;
+}
+
+
+// on init, -EAGAIN
+// on reset, -EINTR
+// on TPE, -EIO
+static void tx_done_callback( int flags, int size )
+{
+	 if ( flags == 0 )
+		  charstats.bytes_tx += size;
+	 else
+		  charstats.cnt_tx_errors++;
+	 last_tx_size = size;
+	 last_tx_result = flags;
+	 sending = 0;
+	 wake_up_interruptible( &wq_write );
+	 wake_up_interruptible( &wq_poll );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Workers
+//////////////////////////////////////////////////////////////////////////////
+
+static int usbc_open( struct inode *pInode, struct file *pFile )
+{
+	 int retval = 0;
+
+	 PRINTK( KERN_DEBUG "%sopen()\n", pszMe );
+
+	 /* start usb core */
+	 retval = sa1100_usb_open( "usb-char" );
+	 if ( retval ) return retval;
+
+	 /* allocate memory */
+	 if ( usb_ref_count == 0 ) {
+		  tx_buf = (char*) kmalloc( TX_PACKET_SIZE, GFP_KERNEL | GFP_DMA );
+		  if ( tx_buf == NULL ) {
+			   printk( "%sARGHH! COULD NOT ALLOCATE TX BUFFER\n", pszMe );
+			   goto malloc_fail;
+		  }
+		  rx_ring.buf =
+			(char*) kmalloc( RBUF_SIZE, GFP_KERNEL );
+
+		  if ( rx_ring.buf == NULL ) {
+			   printk( "%sARGHH! COULD NOT ALLOCATE RX BUFFER\n", pszMe );
+			   goto malloc_fail;
+		  }
+
+		  packet_buffer =
+			(char*) kmalloc( RX_PACKET_SIZE, GFP_KERNEL | GFP_DMA  );
+
+		  if ( packet_buffer == NULL ) {
+			   printk( "%sARGHH! COULD NOT ALLOCATE RX PACKET BUFFER\n", pszMe );
+			   goto malloc_fail;
+		  }
+		  rx_ring.in = rx_ring.out = 0;
+		  memset( &charstats, 0, sizeof( charstats ) );
+		  sending = 0;
+		  last_tx_result = 0;
+		  last_tx_size = 0;
+	 }
+
+	 /* modify default descriptors */
+	 twiddle_descriptors();
+
+	 retval = sa1100_usb_start();
+	 if ( retval ) {
+		  printk( "%sAGHH! Could not USB core\n", pszMe );
+		  free_txrx_buffers();
+		  return retval;
+	 }
+	 usb_ref_count++;   /* must do _before_ kick_start() */
+	 MOD_INC_USE_COUNT;
+	 kick_start_rx();
+	 return 0;
+
+ malloc_fail:
+	 free_txrx_buffers();
+	 return -ENOMEM;
+}
+
+/*
+ * Read endpoint. Note that you can issue a read to an
+ * unconfigured endpoint. Eventually, the host may come along
+ * and configure underneath this module and data will appear.
+ */
+static ssize_t usbc_read( struct file *pFile, char *pUserBuffer,
+                        size_t stCount, loff_t *pPos )
+{
+	 ssize_t retval;
+	 int flags;
+	 DECLARE_WAITQUEUE( wait, current );
+
+	 PRINTK( KERN_DEBUG "%sread()\n", pszMe );
+
+	 local_irq_save( flags );
+	 if ( last_rx_result == 0 ) {
+		  local_irq_restore( flags );
+	 } else {  /* an error happended and receiver is paused */
+		  local_irq_restore( flags );
+		  last_rx_result = 0;
+		  kick_start_rx();
+	 }
+
+	 add_wait_queue( &wq_read, &wait );
+	 while( 1 ) {
+		  ssize_t bytes_avail;
+		  ssize_t bytes_to_end;
+
+		  set_current_state( TASK_INTERRUPTIBLE );
+
+		  /* snap ring buf state */
+		  local_irq_save( flags );
+		  bytes_avail  = CIRC_CNT( rx_ring.in, rx_ring.out, RBUF_SIZE );
+		  bytes_to_end = CIRC_CNT_TO_END( rx_ring.in, rx_ring.out, RBUF_SIZE );
+		  local_irq_restore( flags );
+
+		  if ( bytes_avail != 0 ) {
+			   ssize_t bytes_to_move = MIN( stCount, bytes_avail );
+			   retval = 0;		// will be bytes transfered
+			   if ( bytes_to_move != 0 ) {
+					size_t n = MIN( bytes_to_end, bytes_to_move );
+					if ( copy_to_user( pUserBuffer,
+									   &rx_ring.buf[ rx_ring.out ],
+									   n ) ) {
+						 retval = -EFAULT;
+						 break;
+					}
+					bytes_to_move -= n;
+ 					retval += n;
+					// might go 1 char off end, so wrap
+					rx_ring.out = ( rx_ring.out + n ) & (RBUF_SIZE-1);
+					if ( copy_to_user( pUserBuffer + n,
+									   &rx_ring.buf[ rx_ring.out ],
+									   bytes_to_move )
+						 ) {
+						 retval = -EFAULT;
+						 break;
+					}
+					rx_ring.out += bytes_to_move;		// cannot wrap
+					retval += bytes_to_move;
+					kick_start_rx();
+			   }
+			   break;
+		  }
+		  else if ( last_rx_result ) {
+			   retval = last_rx_result;
+			   break;
+		  }
+		  else if ( pFile->f_flags & O_NONBLOCK ) {  // no data, can't sleep
+			   retval = -EAGAIN;
+			   break;
+		  }
+		  else if ( signal_pending( current ) ) {   // no data, can sleep, but signal
+			   retval = -ERESTARTSYS;
+			   break;
+		  }
+		  schedule();					   			// no data, can sleep
+	 }
+	 set_current_state( TASK_RUNNING );
+	 remove_wait_queue( &wq_read, &wait );
+
+	 if ( retval < 0 )
+		  printk( "%sread error %d - %s\n", pszMe, retval, what_the_f( retval ) );
+	 return retval;
+}
+
+/*
+ * Write endpoint. This routine attempts to break the passed in buffer
+ * into usb DATA0/1 packet size chunks and send them to the host.
+ * (The lower-level driver tries to do this too, but easier for us
+ * to manage things here.)
+ *
+ * We are at the mercy of the host here, in that it must send an IN
+ * token to us to pull this data back, so hopefully some higher level
+ * protocol is expecting traffic to flow in that direction so the host
+ * is actually polling us. To guard against hangs, a 5 second timeout
+ * is used.
+ *
+ * This routine takes some care to only report bytes sent that have
+ * actually made it across the wire. Thus we try to stay in lockstep
+ * with the completion routine and only have one packet on the xmit
+ * hardware at a time. Multiple simultaneous writers will get
+ * "undefined" results.
+ *
+  */
+static ssize_t  usbc_write( struct file *pFile, const char * pUserBuffer,
+							 size_t stCount, loff_t *pPos )
+{
+	 ssize_t retval = 0;
+	 ssize_t stSent = 0;
+
+	 DECLARE_WAITQUEUE( wait, current );
+
+	 PRINTK( KERN_DEBUG "%swrite() %d bytes\n", pszMe, stCount );
+
+	 down( &xmit_sem );  // only one thread onto the hardware at a time
+
+	 while( stCount != 0 && retval == 0 ) {
+		  int nThisTime  = MIN( TX_PACKET_SIZE, stCount );
+		  copy_from_user( tx_buf, pUserBuffer, nThisTime );
+		  sending = nThisTime;
+ 		  retval = sa1100_usb_send( tx_buf, nThisTime, tx_done_callback );
+		  if ( retval < 0 ) {
+			   char * p = what_the_f( retval );
+			   printk( "%sCould not queue xmission. rc=%d - %s\n",
+					   pszMe, retval, p );
+			   sending = 0;
+			   break;
+		  }
+		  /* now have something on the diving board */
+		  add_wait_queue( &wq_write, &wait );
+		  tx_timer.expires = jiffies + ( HZ * 5 );
+		  add_timer( &tx_timer );
+		  while( 1 ) {
+			   set_current_state( TASK_INTERRUPTIBLE );
+			   if ( sending == 0 ) {  /* it jumped into the pool */
+					del_timer( &tx_timer );
+					retval = last_tx_result;
+					if ( retval == 0 ) {
+						 stSent		 += last_tx_size;
+						 pUserBuffer += last_tx_size;
+						 stCount     -= last_tx_size;
+					}
+					else
+						 printk( "%sxmission error rc=%d - %s\n",
+								 pszMe, retval, what_the_f(retval) );
+					break;
+			   }
+			   else if ( signal_pending( current ) ) {
+					del_timer( &tx_timer );
+					printk( "%ssignal\n", pszMe  );
+					retval = -ERESTARTSYS;
+					break;
+			   }
+			   schedule();
+		  }
+		  set_current_state( TASK_RUNNING );
+		  remove_wait_queue( &wq_write, &wait );
+	 }
+
+	 up( &xmit_sem );
+
+	 if ( 0 == retval )
+		  retval = stSent;
+	 return retval;
+}
+
+static unsigned int usbc_poll( struct file *pFile, poll_table * pWait )
+{
+	 unsigned int retval = 0;
+
+	 PRINTK( KERN_DEBUG "%poll()\n", pszMe );
+
+	 poll_wait( pFile, &wq_poll, pWait );
+
+	 if ( CIRC_CNT( rx_ring.in, rx_ring.out, RBUF_SIZE ) )
+		  retval |= POLLIN | POLLRDNORM;
+	 if ( sa1100_usb_xmitter_avail() )
+		  retval |= POLLOUT | POLLWRNORM;
+	 return retval;
+}
+
+static int usbc_ioctl( struct inode *pInode, struct file *pFile,
+                       unsigned int nCmd, unsigned long argument )
+{
+	 int retval = 0;
+
+	 switch( nCmd ) {
+
+	 case USBC_IOC_FLUSH_RECEIVER:
+		  sa1100_usb_recv_reset();
+		  rx_ring.in = rx_ring.out = 0;
+		  break;
+
+	 case USBC_IOC_FLUSH_TRANSMITTER:
+		  sa1100_usb_send_reset();
+		  break;
+
+	 case USBC_IOC_FLUSH_ALL:
+		  sa1100_usb_recv_reset();
+		  rx_ring.in = rx_ring.out = 0;
+		  sa1100_usb_send_reset();
+		  break;
+
+	 default:
+		  retval = -ENOIOCTLCMD;
+		  break;
+
+	 }
+	 return retval;
+}
+
+
+static int usbc_close( struct inode *pInode, struct file * pFile )
+{
+	PRINTK( KERN_DEBUG "%sclose()\n", pszMe );
+	if ( --usb_ref_count == 0 ) {
+		 down( &xmit_sem );
+		 sa1100_usb_stop();
+		 free_txrx_buffers();
+		 free_string_descriptors();
+		 del_timer( &tx_timer );
+		 sa1100_usb_close();
+		 up( &xmit_sem );
+	}
+    MOD_DEC_USE_COUNT;
+    return 0;
+}
+
+#ifdef CONFIG_SA1100_EXTENEX1
+#include "../../../drivers/char/ex_gpio.h"
+void extenex_configured_notify_proc( void )
+{
+	 if ( exgpio_play_string( "440,1:698,1" ) == -EAGAIN )
+		  printk( "%sWanted to BEEP but ex_gpio not open\n", pszMe );
+}
+#endif
+//////////////////////////////////////////////////////////////////////////////
+// Initialization
+//////////////////////////////////////////////////////////////////////////////
+
+static struct file_operations usbc_fops = {
+		owner:      THIS_MODULE,
+		open:		usbc_open,
+		read:		usbc_read,
+		write:		usbc_write,
+		poll:		usbc_poll,
+		ioctl:		usbc_ioctl,
+		release:	usbc_close,
+};
+
+static struct miscdevice usbc_misc_device = {
+    USBC_MINOR, "usb_char", &usbc_fops
+};
+
+/*
+ * usbc_init()
+ */
+
+int __init usbc_init( void )
+{
+	 int rc;
+
+#if !defined( CONFIG_ARCH_SA1100 )
+	 return -ENODEV;
+#endif
+
+	 if ( (rc = misc_register( &usbc_misc_device )) != 0 ) {
+		  printk( KERN_WARNING "%sCould not register device 10, "
+				  "%d. (%d)\n", pszMe, USBC_MINOR, rc );
+		  return -EBUSY;
+	 }
+
+	 // initialize wait queues
+	 init_waitqueue_head( &wq_read );
+	 init_waitqueue_head( &wq_write );
+	 init_waitqueue_head( &wq_poll );
+
+	 // initialize tx timeout timer
+	 init_timer( &tx_timer );
+	 tx_timer.function = tx_timeout;
+
+	  printk( KERN_INFO "USB Function Character Driver Interface"
+				  " - %s, (C) 2001, Extenex Corp.\n", VERSION
+		   );
+
+	 return rc;
+}
+
+void __exit usbc_exit( void )
+{
+}
+
+EXPORT_NO_SYMBOLS;
+
+module_init(usbc_init);
+module_exit(usbc_exit);
+
+
+
+// end: usb-char.c
+
+
+
diff -urN linux-2.4.29/arch/arm/mach-sa1100/usb-char.h linux-2.4.29-uc1/arch/arm/mach-sa1100/usb-char.h
--- linux-2.4.29/arch/arm/mach-sa1100/usb-char.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-sa1100/usb-char.h	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2001 Extenex Corporation
+ *
+ * usb-char.h
+ *
+ * Character device emulation client for SA-1100 client usb core.
+ *
+ *
+ *
+ */
+#ifndef _USB_CHAR_H
+#define _USB_CHAR_H
+
+#define USBC_MAJOR 10      /* miscellaneous character device */
+#define USBC_MINOR 240     /* in the "reserved for local use" range */
+
+#define USBC_MAGIC 0x8E
+
+/* zap everything in receive ring buffer */
+#define USBC_IOC_FLUSH_RECEIVER    _IO( USBC_MAGIC, 0x01 )
+
+/* reset transmitter */
+#define USBC_IOC_FLUSH_TRANSMITTER _IO( USBC_MAGIC, 0x02 )
+
+/* do both of above */
+#define USBC_IOC_FLUSH_ALL         _IO( USBC_MAGIC, 0x03 )
+
+
+
+
+
+
+#endif /* _USB_CHAR_H */
+
diff -urN linux-2.4.29/arch/arm/mach-sa1100/usb_ctl.c linux-2.4.29-uc1/arch/arm/mach-sa1100/usb_ctl.c
--- linux-2.4.29/arch/arm/mach-sa1100/usb_ctl.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-sa1100/usb_ctl.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,774 @@
+ /*
+ *	Copyright (C) Compaq Computer Corporation, 1998, 1999
+ *  Copyright (C) Extenex Corporation, 2001
+ *
+ *  usb_ctl.c
+ *
+ *  SA1100 USB controller core driver.
+ *
+ *  This file provides interrupt routing and overall coordination
+ *  of the three endpoints in usb_ep0, usb_receive (1),  and usb_send (2).
+ *
+ *  Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/tqueue.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include "sa1100_usb.h"
+#include "usb_ctl.h"
+
+//////////////////////////////////////////////////////////////////////////////
+// Prototypes
+//////////////////////////////////////////////////////////////////////////////
+
+int usbctl_next_state_on_event( int event );
+static void udc_int_hndlr(int, void *, struct pt_regs *);
+static void initialize_descriptors( void );
+static void soft_connect_hook( int enable );
+static void udc_disable(void);
+static void udc_enable(void);
+
+#if CONFIG_PROC_FS
+#define PROC_NODE_NAME "sausb"
+static int usbctl_read_proc(char *page, char **start, off_t off,
+							int count, int *eof, void *data);
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// Globals
+//////////////////////////////////////////////////////////////////////////////
+static const char pszMe[] = "usbctl: ";
+struct usb_info_t usbd_info;  /* global to ep0, usb_recv, usb_send */
+
+/* device descriptors */
+static desc_t desc;
+
+#define MAX_STRING_DESC 8
+static string_desc_t * string_desc_array[ MAX_STRING_DESC ];
+static string_desc_t sd_zero;  /* special sd_zero holds language codes */
+
+// called when configured
+static usb_notify_t configured_callback = NULL;
+
+enum {	kStateZombie  = 0,  kStateZombieSuspend  = 1,
+		kStateDefault = 2,  kStateDefaultSuspend = 3,
+		kStateAddr    = 4,  kStateAddrSuspend    = 5,
+		kStateConfig  = 6,  kStateConfigSuspend  = 7
+};
+
+static int device_state_machine[8][6] = {
+//                suspend               reset          resume     adddr config deconfig
+/* zombie */  {  kStateZombieSuspend,  kStateDefault, kError,    kError, kError, kError },
+/* zom sus */ {  kError, kStateDefault, kStateZombie, kError, kError, kError },
+/* default */ {  kStateDefaultSuspend, kError, kStateDefault, kStateAddr, kError, kError },
+/* def sus */ {  kError, kStateDefault, kStateDefault, kError, kError, kError },
+/* addr */    {  kStateAddrSuspend, kStateDefault, kError, kError, kStateConfig, kError },
+/* addr sus */{  kError, kStateDefault, kStateAddr, kError, kError, kError },
+/* config */  {  kStateConfigSuspend, kStateDefault, kError, kError, kError, kStateAddr },
+/* cfg sus */ {  kError, kStateDefault, kStateConfig, kError, kError, kError }
+};
+
+/* "device state" is the usb device framework state, as opposed to the
+   "state machine state" which is whatever the driver needs and is much
+   more fine grained
+*/
+static int sm_state_to_device_state[8] =
+//  zombie           zom suspend          default            default sus
+{ USB_STATE_POWERED, USB_STATE_SUSPENDED, USB_STATE_DEFAULT, USB_STATE_SUSPENDED,
+// addr              addr sus             config                config sus
+  USB_STATE_ADDRESS, USB_STATE_SUSPENDED, USB_STATE_CONFIGURED, USB_STATE_SUSPENDED
+};
+
+static char * state_names[8] =
+{ "zombie", "zombie suspended", "default", "default suspended",
+  "address", "address suspended", "configured", "config suspended"
+};
+
+static char * event_names[6] =
+{ "suspend", "reset", "resume",
+  "address assigned", "configure", "de-configure"
+};
+
+static char * device_state_names[] =
+{ "not attached", "attached", "powered", "default",
+  "address", "configured", "suspended" };
+
+static int sm_state = kStateZombie;
+
+//////////////////////////////////////////////////////////////////////////////
+// Async
+//////////////////////////////////////////////////////////////////////////////
+static void core_kicker(void);
+
+static inline void enable_resume_mask_suspend( void );
+static inline void enable_suspend_mask_resume(void);
+
+static void
+udc_int_hndlr(int irq, void *dev_id, struct pt_regs *regs)
+{
+  	__u32 status = Ser0UDCSR;
+
+	/* ReSeT Interrupt Request - UDC has been reset */
+	if ( status & UDCSR_RSTIR )
+	{
+		if ( usbctl_next_state_on_event( kEvReset ) != kError )
+		{
+			/* starting 20ms or so reset sequence now... */
+			printk("%sResetting\n", pszMe);
+			ep0_reset();  // just set state to idle
+			ep1_reset();  // flush dma, clear false stall
+			ep2_reset();  // flush dma, clear false stall
+		}
+		// mask reset ints, they flood during sequence, enable
+		// suspend and resume
+		Ser0UDCCR |= UDCCR_REM;    // mask reset
+		Ser0UDCCR &= ~(UDCCR_SUSIM | UDCCR_RESIM); // enable suspend and resume
+		UDC_flip(  Ser0UDCSR, status );	// clear all pending sources
+		return;		// <-- no reason to continue if resetting
+	}
+	// else we have done something other than reset, so be sure reset enabled
+	UDC_clear( Ser0UDCCR, UDCCR_REM );
+
+	/* RESume Interrupt Request */
+	if ( status & UDCSR_RESIR )
+	{
+		usbctl_next_state_on_event( kEvResume );
+		core_kicker();
+		enable_suspend_mask_resume();
+	}
+
+	/* SUSpend Interrupt Request */
+	if ( status & UDCSR_SUSIR )
+	{
+		usbctl_next_state_on_event( kEvSuspend );
+		enable_resume_mask_suspend();
+	}
+
+	UDC_flip(Ser0UDCSR, status); // clear all pending sources
+
+	if (status & UDCSR_EIR)
+		 ep0_int_hndlr();
+
+	if (status & UDCSR_RIR)
+		ep1_int_hndlr(status);
+
+	if (status & UDCSR_TIR)
+		ep2_int_hndlr(status);
+}
+
+static inline void enable_resume_mask_suspend( void )
+{
+	 int i = 0;
+
+	 while( 1 ) {
+		  Ser0UDCCR |= UDCCR_SUSIM; // mask future suspend events
+		  udelay( i );
+		  if ( (Ser0UDCCR & UDCCR_SUSIM) || (Ser0UDCSR & UDCSR_RSTIR) )
+			   break;
+		  if ( ++i == 50 ) {
+			   printk( "%senable_resume(): Could not set SUSIM %8.8X\n",
+					   pszMe, Ser0UDCCR );
+			   break;
+		  }
+	 }
+
+	 i = 0;
+	 while( 1 ) {
+		  Ser0UDCCR &= ~UDCCR_RESIM;
+		  udelay( i );
+		  if ( ( Ser0UDCCR & UDCCR_RESIM ) == 0
+			   ||
+			   (Ser0UDCSR & UDCSR_RSTIR)
+			 )
+			   break;
+		  if ( ++i == 50 ) {
+			   printk( "%senable_resume(): Could not clear RESIM %8.8X\n",
+					   pszMe, Ser0UDCCR );
+			   break;
+		  }
+	 }
+}
+
+static inline void enable_suspend_mask_resume(void)
+{
+	 int i = 0;
+	 while( 1 ) {
+		  Ser0UDCCR |= UDCCR_RESIM; // mask future resume events
+		  udelay( i );
+		  if ( Ser0UDCCR & UDCCR_RESIM || (Ser0UDCSR & UDCSR_RSTIR) )
+			   break;
+		  if ( ++i == 50 ) {
+			   printk( "%senable_suspend(): Could not set RESIM %8.8X\n",
+					   pszMe, Ser0UDCCR );
+			   break;
+		  }
+	 }
+	 i = 0;
+	 while( 1 ) {
+		  Ser0UDCCR &= ~UDCCR_SUSIM;
+		  udelay( i );
+		  if ( ( Ser0UDCCR & UDCCR_SUSIM ) == 0
+			   ||
+			   (Ser0UDCSR & UDCSR_RSTIR)
+			 )
+			   break;
+		  if ( ++i == 50 ) {
+			   printk( "%senable_suspend(): Could not clear SUSIM %8.8X\n",
+					   pszMe, Ser0UDCCR );
+			   break;
+		  }
+	 }
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Public Interface
+//////////////////////////////////////////////////////////////////////////////
+
+/* Open SA usb core on behalf of a client, but don't start running */
+
+int
+sa1100_usb_open( const char * client )
+{
+	 if ( usbd_info.client_name != NULL )
+		  return -EBUSY;
+
+	 usbd_info.client_name = (char*) client;
+	 memset(&usbd_info.stats, 0, sizeof(struct usb_stats_t));
+	 memset(string_desc_array, 0, sizeof(string_desc_array));
+
+	 /* hack to start in zombie suspended state */
+	 sm_state = kStateZombieSuspend;
+	 usbd_info.state = USB_STATE_SUSPENDED;
+
+	 /* create descriptors for enumeration */
+	 initialize_descriptors();
+
+	 printk( "%sOpened for %s\n", pszMe, client );
+	 return 0;
+}
+
+/* Start running. Must have called usb_open (above) first */
+int
+sa1100_usb_start( void )
+{
+	 if ( usbd_info.client_name == NULL ) {
+		  printk( "%s%s - no client registered\n",
+				  pszMe, __FUNCTION__ );
+		  return -EPERM;
+	 }
+
+	 /* start UDC internal machinery running */
+	 udc_enable();
+	 udelay( 100 );
+
+	 /* clear stall - receiver seems to start stalled? 19Jan01ww */
+	 /* also clear other stuff just to be thurough 22Feb01ww */
+	 UDC_clear(Ser0UDCCS1, UDCCS1_FST | UDCCS1_RPE | UDCCS1_RPC );
+	 UDC_clear(Ser0UDCCS2, UDCCS2_FST | UDCCS2_TPE | UDCCS2_TPC );
+
+	 /* mask everything */
+	 Ser0UDCCR = 0xFC;
+
+	 /* flush DMA and fire through some -EAGAINs */
+	 ep1_init( usbd_info.dmach_rx );
+	 ep2_init( usbd_info.dmach_tx );
+
+	 /* give endpoint notification we are starting */
+	 ep1_state_change_notify( USB_STATE_SUSPENDED );
+	 ep2_state_change_notify( USB_STATE_SUSPENDED );
+
+	 /* enable any platform specific hardware */
+	 soft_connect_hook( 1 );
+
+	/* clear all top-level sources */
+	 Ser0UDCSR = UDCSR_RSTIR | UDCSR_RESIR | UDCSR_EIR   |
+		         UDCSR_RIR   | UDCSR_TIR   | UDCSR_SUSIR ;
+
+	 /* EXERIMENT - a short line in the spec says toggling this
+	  ..bit diddles the internal state machine in the udc to
+	  ..expect a suspend */
+	 Ser0UDCCR  |= UDCCR_RESIM;
+	 /* END EXPERIMENT 10Feb01ww */
+
+	 /* enable any platform specific hardware */
+	 soft_connect_hook( 1 );
+
+	 /* enable interrupts. If you are unplugged you will
+	    immediately get a suspend interrupt. If you are plugged
+	    and have a soft connect-circuit, you will get a reset
+        If you are plugged without a soft-connect, I think you
+	    also get suspend. In short, start with suspend masked
+	    and everything else enabled */
+	 UDC_write( Ser0UDCCR, UDCCR_SUSIM );
+
+	 printk( "%sStarted for %s\n", pszMe, usbd_info.client_name );
+	 return 0;
+}
+
+/* Stop USB core from running */
+int
+sa1100_usb_stop( void )
+{
+	 if ( usbd_info.client_name == NULL ) {
+		  printk( "%s%s - no client registered\n",
+				  pszMe, __FUNCTION__ );
+		  return -EPERM;
+	 }
+	 /* mask everything */
+	 Ser0UDCCR = 0xFC;
+	 ep1_reset();
+	 ep2_reset();
+	 udc_disable();
+	 printk( "%sStopped\n", pszMe );
+	 return 0;
+}
+
+/* Tell SA core client is through using it */
+int
+sa1100_usb_close( void )
+{
+	 if ( usbd_info.client_name == NULL ) {
+		  printk( "%s%s - no client registered\n",
+				  pszMe, __FUNCTION__ );
+		  return -EPERM;
+	 }
+	 usbd_info.client_name = NULL;
+	 printk( "%sClosed\n", pszMe );
+	 return 0;
+}
+
+/* set a proc to be called when device is configured */
+usb_notify_t sa1100_set_configured_callback( usb_notify_t func )
+{
+	 usb_notify_t retval = configured_callback;
+	 configured_callback = func;
+	 return retval;
+}
+
+/*====================================================
+ * Descriptor Manipulation.
+ * Use these between open() and start() above to setup
+ * the descriptors for your device.
+ *
+ */
+
+/* get pointer to static default descriptor */
+desc_t *
+sa1100_usb_get_descriptor_ptr( void ) { return &desc; }
+
+/* optional: set a string descriptor */
+int
+sa1100_usb_set_string_descriptor( int i, string_desc_t * p )
+{
+	 int retval;
+	 if ( i < MAX_STRING_DESC ) {
+		  string_desc_array[i] = p;
+		  retval = 0;
+	 } else {
+		  retval = -EINVAL;
+	 }
+	 return retval;
+}
+
+/* optional: get a previously set string descriptor */
+string_desc_t *
+sa1100_usb_get_string_descriptor( int i )
+{
+	 return ( i < MAX_STRING_DESC )
+		    ? string_desc_array[i]
+		    : NULL;
+}
+
+
+/* optional: kmalloc and unicode up a string descriptor */
+string_desc_t *
+sa1100_usb_kmalloc_string_descriptor( const char * p )
+{
+	 string_desc_t * pResult = NULL;
+
+	 if ( p ) {
+		  int len = strlen( p );
+		  int uni_len = len * sizeof( __u16 );
+		  pResult = (string_desc_t*) kmalloc( uni_len + 2, GFP_KERNEL ); /* ugh! */
+		  if ( pResult != NULL ) {
+			   int i;
+			   pResult->bLength = uni_len + 2;
+			   pResult->bDescriptorType = USB_DESC_STRING;
+			   for( i = 0; i < len ; i++ ) {
+					pResult->bString[i] = make_word( (__u16) p[i] );
+			   }
+		  }
+	 }
+	 return pResult;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Exports to rest of driver
+//////////////////////////////////////////////////////////////////////////////
+
+/* called by the int handler here and the two endpoint files when interesting
+   .."events" happen */
+
+int
+usbctl_next_state_on_event( int event )
+{
+	int next_state = device_state_machine[ sm_state ][ event ];
+	if ( next_state != kError )
+	{
+		int next_device_state = sm_state_to_device_state[ next_state ];
+		printk( "%s%s --> [%s] --> %s. Device in %s state.\n",
+				pszMe, state_names[ sm_state ], event_names[ event ],
+				state_names[ next_state ], device_state_names[ next_device_state ] );
+
+		sm_state = next_state;
+		if ( usbd_info.state != next_device_state )
+		{
+			if ( configured_callback != NULL
+				 &&
+				 next_device_state == USB_STATE_CONFIGURED
+				 &&
+				 usbd_info.state != USB_STATE_SUSPENDED
+			   ) {
+			  configured_callback();
+			}
+			usbd_info.state = next_device_state;
+			ep1_state_change_notify( next_device_state );
+			ep2_state_change_notify( next_device_state );
+		}
+	}
+#if 0
+	else
+		printk( "%s%s --> [%s] --> ??? is an error.\n",
+				pszMe, state_names[ sm_state ], event_names[ event ] );
+#endif
+	return next_state;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Private Helpers
+//////////////////////////////////////////////////////////////////////////////
+
+/* setup default descriptors */
+
+static void
+initialize_descriptors(void)
+{
+	desc.dev.bLength               = sizeof( device_desc_t );
+	desc.dev.bDescriptorType       = USB_DESC_DEVICE;
+	desc.dev.bcdUSB                = 0x100; /* 1.0 */
+	desc.dev.bDeviceClass          = 0xFF;	/* vendor specific */
+	desc.dev.bDeviceSubClass       = 0;
+	desc.dev.bDeviceProtocol       = 0;
+	desc.dev.bMaxPacketSize0       = 8;	/* ep0 max fifo size */
+	desc.dev.idVendor              = 0;	/* vendor ID undefined */
+	desc.dev.idProduct             = 0; /* product */
+	desc.dev.bcdDevice             = 0; /* vendor assigned device release num */
+	desc.dev.iManufacturer         = 0;	/* index of manufacturer string */
+	desc.dev.iProduct              = 0; /* index of product description string */
+	desc.dev.iSerialNumber         = 0;	/* index of string holding product s/n */
+	desc.dev.bNumConfigurations    = 1;
+
+	desc.b.cfg.bLength             = sizeof( config_desc_t );
+	desc.b.cfg.bDescriptorType     = USB_DESC_CONFIG;
+	desc.b.cfg.wTotalLength        = make_word_c( sizeof(struct cdb) );
+	desc.b.cfg.bNumInterfaces      = 1;
+	desc.b.cfg.bConfigurationValue = 1;
+	desc.b.cfg.iConfiguration      = 0;
+	desc.b.cfg.bmAttributes        = USB_CONFIG_BUSPOWERED;
+	desc.b.cfg.MaxPower            = USB_POWER( 500 );
+
+	desc.b.intf.bLength            = sizeof( intf_desc_t );
+	desc.b.intf.bDescriptorType    = USB_DESC_INTERFACE;
+	desc.b.intf.bInterfaceNumber   = 0; /* unique intf index*/
+	desc.b.intf.bAlternateSetting  = 0;
+	desc.b.intf.bNumEndpoints      = 2;
+	desc.b.intf.bInterfaceClass    = 0xFF; /* vendor specific */
+	desc.b.intf.bInterfaceSubClass = 0;
+	desc.b.intf.bInterfaceProtocol = 0;
+	desc.b.intf.iInterface         = 0;
+
+	desc.b.ep1.bLength             = sizeof( ep_desc_t );
+	desc.b.ep1.bDescriptorType     = USB_DESC_ENDPOINT;
+	desc.b.ep1.bEndpointAddress    = USB_EP_ADDRESS( 1, USB_OUT );
+	desc.b.ep1.bmAttributes        = USB_EP_BULK;
+	desc.b.ep1.wMaxPacketSize      = make_word_c( 64 );
+	desc.b.ep1.bInterval           = 0;
+
+	desc.b.ep2.bLength             = sizeof( ep_desc_t );
+	desc.b.ep2.bDescriptorType     = USB_DESC_ENDPOINT;
+	desc.b.ep2.bEndpointAddress    = USB_EP_ADDRESS( 2, USB_IN );
+	desc.b.ep2.bmAttributes        = USB_EP_BULK;
+	desc.b.ep2.wMaxPacketSize      = make_word_c( 64 );
+	desc.b.ep2.bInterval           = 0;
+
+	/* set language */
+	/* See: http://www.usb.org/developers/data/USB_LANGIDs.pdf */
+	sd_zero.bDescriptorType = USB_DESC_STRING;
+	sd_zero.bLength         = sizeof( string_desc_t );
+	sd_zero.bString[0]      = make_word_c( 0x409 ); /* American English */
+	sa1100_usb_set_string_descriptor( 0, &sd_zero );
+}
+
+/* soft_connect_hook()
+ * Some devices have platform-specific circuitry to make USB
+ * not seem to be plugged in, even when it is. This allows
+ * software to control when a device 'appears' on the USB bus
+ * (after Linux has booted and this driver has loaded, for
+ * example). If you have such a circuit, control it here.
+ */
+static void
+soft_connect_hook( int enable )
+{
+#ifdef CONFIG_SA1100_EXTENEX1
+	 if (machine_is_extenex1() ) {
+		  if ( enable ) {
+			   PPDR |= PPC_USB_SOFT_CON;
+			   PPSR |= PPC_USB_SOFT_CON;
+		  } else {
+			   PPSR &= ~PPC_USB_SOFT_CON;
+			   PPDR &= ~PPC_USB_SOFT_CON;
+		  }
+	 }
+#endif
+}
+
+/* disable the UDC at the source */
+static void
+udc_disable(void)
+{
+	soft_connect_hook( 0 );
+	UDC_set( Ser0UDCCR, UDCCR_UDD );
+}
+
+
+/*  enable the udc at the source */
+static void
+udc_enable(void)
+{
+	UDC_clear(Ser0UDCCR, UDCCR_UDD);
+}
+
+// HACK DEBUG  3Mar01ww
+// Well, maybe not, it really seems to help!  08Mar01ww
+static void
+core_kicker( void )
+{
+	 __u32 car = Ser0UDCAR;
+	 __u32 imp = Ser0UDCIMP;
+	 __u32 omp = Ser0UDCOMP;
+
+	 UDC_set( Ser0UDCCR, UDCCR_UDD );
+	 udelay( 300 );
+	 UDC_clear(Ser0UDCCR, UDCCR_UDD);
+
+	 Ser0UDCAR = car;
+	 Ser0UDCIMP = imp;
+	 Ser0UDCOMP = omp;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Proc Filesystem Support
+//////////////////////////////////////////////////////////////////////////////
+
+#if CONFIG_PROC_FS
+
+#define SAY( fmt, args... )  p += sprintf(p, fmt, ## args )
+#define SAYV(  num )         p += sprintf(p, num_fmt, "Value", num )
+#define SAYC( label, yn )    p += sprintf(p, yn_fmt, label, yn )
+#define SAYS( label, v )     p += sprintf(p, cnt_fmt, label, v )
+
+static int usbctl_read_proc(char *page, char **start, off_t off,
+			    int count, int *eof, void *data)
+{
+	 const char * num_fmt   = "%25.25s: %8.8lX\n";
+	 const char * cnt_fmt   = "%25.25s: %lu\n";
+	 const char * yn_fmt    = "%25.25s: %s\n";
+	 const char * yes       = "YES";
+	 const char * no        = "NO";
+	 unsigned long v;
+	 char * p = page;
+	 int len;
+
+ 	 SAY( "SA1100 USB Controller Core\n" );
+	 SAY( "USB state: %s (%s) %d\n",
+		  device_state_names[ sm_state_to_device_state[ sm_state ] ],
+		  state_names[ sm_state ],
+		  sm_state );
+
+	 SAYS( "ep0 bytes read", usbd_info.stats.ep0_bytes_read );
+	 SAYS( "ep0 bytes written", usbd_info.stats.ep0_bytes_written );
+	 SAYS( "ep0 FIFO read failures", usbd_info.stats.ep0_fifo_write_failures );
+	 SAYS( "ep0 FIFO write failures", usbd_info.stats.ep0_fifo_write_failures );
+
+	 SAY( "\n" );
+
+	 v = Ser0UDCAR;
+	 SAY( "%25.25s: 0x%8.8lX - %ld\n", "Address Register", v, v );
+	 v = Ser0UDCIMP;
+	 SAY( "%25.25s: %ld (%8.8lX)\n", "IN  max packet size", v+1, v );
+	 v = Ser0UDCOMP;
+	 SAY( "%25.25s: %ld (%8.8lX)\n", "OUT max packet size", v+1, v );
+
+	 v = Ser0UDCCR;
+	 SAY( "\nUDC Mask Register\n" );
+	 SAYV( v );
+	 SAYC( "UDC Active",                ( v & UDCCR_UDA ) ? yes : no );
+	 SAYC( "Suspend interrupts masked", ( v & UDCCR_SUSIM ) ? yes : no );
+	 SAYC( "Resume interrupts masked",  ( v & UDCCR_RESIM ) ? yes : no );
+	 SAYC( "Reset interrupts masked",   ( v & UDCCR_REM ) ? yes : no );
+
+	 v = Ser0UDCSR;
+	 SAY( "\nUDC Interrupt Request Register\n" );
+	 SAYV( v );
+	 SAYC( "Reset pending",      ( v & UDCSR_RSTIR ) ? yes : no );
+	 SAYC( "Suspend pending",    ( v & UDCSR_SUSIR ) ? yes : no );
+	 SAYC( "Resume pending",     ( v & UDCSR_RESIR ) ? yes : no );
+	 SAYC( "ep0 pending",        ( v & UDCSR_EIR )   ? yes : no );
+	 SAYC( "receiver pending",   ( v & UDCSR_RIR )   ? yes : no );
+	 SAYC( "tramsitter pending", ( v & UDCSR_TIR )   ? yes : no );
+
+#ifdef CONFIG_SA1100_EXTENEX1
+	 SAYC( "\nSoft connect", (PPSR & PPC_USB_SOFT_CON) ? "Visible" : "Hidden" );
+#endif
+
+#if 0
+	 v = Ser0UDCCS0;
+	 SAY( "\nUDC Endpoint Zero Status Register\n" );
+	 SAYV( v );
+	 SAYC( "Out Packet Ready", ( v & UDCCS0_OPR ) ? yes : no );
+	 SAYC( "In Packet Ready",  ( v & UDCCS0_IPR ) ? yes : no );
+	 SAYC( "Sent Stall",       ( v & UDCCS0_SST ) ? yes : no );
+	 SAYC( "Force Stall",      ( v & UDCCS0_FST ) ? yes : no );
+	 SAYC( "Data End",         ( v & UDCCS0_DE )  ? yes : no );
+	 SAYC( "Data Setup End",   ( v & UDCCS0_SE )  ? yes : no );
+	 SAYC( "Serviced (SO)",    ( v & UDCCS0_SO )  ? yes : no );
+
+	 v = Ser0UDCCS1;
+	 SAY( "\nUDC Receiver Status Register\n" );
+	 SAYV( v );
+	 SAYC( "Receive Packet Complete", ( v & UDCCS1_RPC ) ? yes : no );
+	 SAYC( "Sent Stall",              ( v & UDCCS1_SST ) ? yes : no );
+	 SAYC( "Force Stall",             ( v & UDCCS1_FST ) ? yes : no );
+	 SAYC( "Receive Packet Error",    ( v & UDCCS1_RPE ) ? yes : no );
+	 SAYC( "Receive FIFO not empty",  ( v & UDCCS1_RNE ) ? yes : no );
+
+	 v = Ser0UDCCS2;
+	 SAY( "\nUDC Transmitter Status Register\n" );
+	 SAYV( v );
+	 SAYC( "FIFO has < 8 of 16 chars", ( v & UDCCS2_TFS ) ? yes : no );
+	 SAYC( "Transmit Packet Complete", ( v & UDCCS2_TPC ) ? yes : no );
+	 SAYC( "Transmit FIFO underrun",   ( v & UDCCS2_TUR ) ? yes : no );
+	 SAYC( "Transmit Packet Error",    ( v & UDCCS2_TPE ) ? yes : no );
+	 SAYC( "Sent Stall",               ( v & UDCCS2_SST ) ? yes : no );
+	 SAYC( "Force Stall",              ( v & UDCCS2_FST ) ? yes : no );
+#endif
+
+	 len = ( p - page ) - off;
+	 if ( len < 0 )
+		  len = 0;
+	 *eof = ( len <=count ) ? 1 : 0;
+	 *start = page + off;
+	 return len;
+}
+
+#endif  /* CONFIG_PROC_FS */
+
+//////////////////////////////////////////////////////////////////////////////
+// Module Initialization and Shutdown
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * usbctl_init()
+ * Module load time. Allocate dma and interrupt resources. Setup /proc fs
+ * entry. Leave UDC disabled.
+ */
+int __init usbctl_init( void )
+{
+	int retval = 0;
+
+	udc_disable();
+
+	memset( &usbd_info, 0, sizeof( usbd_info ) );
+
+#if CONFIG_PROC_FS
+	create_proc_read_entry ( PROC_NODE_NAME, 0, NULL, usbctl_read_proc, NULL);
+#endif
+
+	/* setup rx dma */
+	retval = sa1100_request_dma(&usbd_info.dmach_rx, "USB receive", DMA_Ser0UDCRd);
+	if (retval) {
+		printk("%sunable to register for rx dma rc=%d\n", pszMe, retval );
+		goto err_rx_dma;
+	}
+
+	/* setup tx dma */
+	retval = sa1100_request_dma(&usbd_info.dmach_tx, "USB transmit", DMA_Ser0UDCWr);
+	if (retval) {
+		printk("%sunable to register for tx dma rc=%d\n",pszMe,retval);
+		goto err_tx_dma;
+	}
+
+	/* now allocate the IRQ. */
+	retval = request_irq(IRQ_Ser0UDC, udc_int_hndlr, SA_INTERRUPT,
+			  "SA USB core", NULL);
+	if (retval) {
+		printk("%sCouldn't request USB irq rc=%d\n",pszMe, retval);
+		goto err_irq;
+	}
+
+	printk( "SA1100 USB Controller Core Initialized\n");
+	return 0;
+
+err_irq:
+	sa1100_free_dma(usbd_info.dmach_tx);
+	usbd_info.dmach_tx = 0;
+err_tx_dma:
+	sa1100_free_dma(usbd_info.dmach_rx);
+	usbd_info.dmach_rx = 0;
+err_rx_dma:
+	return retval;
+}
+/*
+ * usbctl_exit()
+ * Release DMA and interrupt resources
+ */
+void __exit usbctl_exit( void )
+{
+    printk("Unloading SA1100 USB Controller\n");
+
+	udc_disable();
+
+#if CONFIG_PROC_FS
+    remove_proc_entry ( PROC_NODE_NAME, NULL);
+#endif
+
+    sa1100_free_dma(usbd_info.dmach_rx);
+    sa1100_free_dma(usbd_info.dmach_tx);
+    free_irq(IRQ_Ser0UDC, NULL);
+}
+
+EXPORT_SYMBOL( sa1100_usb_open );
+EXPORT_SYMBOL( sa1100_usb_start );
+EXPORT_SYMBOL( sa1100_usb_stop );
+EXPORT_SYMBOL( sa1100_usb_close );
+
+
+EXPORT_SYMBOL( sa1100_usb_get_descriptor_ptr );
+EXPORT_SYMBOL( sa1100_usb_set_string_descriptor );
+EXPORT_SYMBOL( sa1100_usb_get_string_descriptor );
+EXPORT_SYMBOL( sa1100_usb_kmalloc_string_descriptor );
+
+
+module_init( usbctl_init );
+module_exit( usbctl_exit );
diff -urN linux-2.4.29/arch/arm/mach-sa1100/usb_ctl.h linux-2.4.29-uc1/arch/arm/mach-sa1100/usb_ctl.h
--- linux-2.4.29/arch/arm/mach-sa1100/usb_ctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-sa1100/usb_ctl.h	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,123 @@
+/*
+ *	Copyright (C)  Compaq Computer Corporation, 1998, 1999
+ *	Copyright (C)  Extenex Corporation 2001
+ *
+ *  usb_ctl.h
+ *
+ *  PRIVATE interface used to share info among components of the SA-1100 USB
+ *  core: usb_ctl, usb_ep0, usb_recv and usb_send. Clients of the USB core
+ *  should use sa1100_usb.h.
+ *
+ */
+
+#ifndef _USB_CTL_H
+#define _USB_CTL_H
+
+#include <asm/dma.h>  /* dmach_t */
+
+
+/*
+ * These states correspond to those in the USB specification v1.0
+ * in chapter 8, Device Framework.
+ */
+enum { USB_STATE_NOTATTACHED=0, USB_STATE_ATTACHED=1,USB_STATE_POWERED=2,
+	   USB_STATE_DEFAULT=3, USB_STATE_ADDRESS=4, USB_STATE_CONFIGURED=5,
+	   USB_STATE_SUSPENDED=6};
+
+struct usb_stats_t {
+	 unsigned long ep0_fifo_write_failures;
+	 unsigned long ep0_bytes_written;
+	 unsigned long ep0_fifo_read_failures;
+	 unsigned long ep0_bytes_read;
+};
+
+struct usb_info_t
+{
+	 char * client_name;
+	 dmach_t dmach_tx, dmach_rx;
+	 int state;
+	 unsigned char address;
+	 struct usb_stats_t stats;
+};
+
+/* in usb_ctl.c */
+extern struct usb_info_t usbd_info;
+
+/*
+ * Function Prototypes
+ */
+enum { kError=-1, kEvSuspend=0, kEvReset=1,
+	   kEvResume=2, kEvAddress=3, kEvConfig=4, kEvDeConfig=5 };
+int usbctl_next_state_on_event( int event );
+
+/* endpoint zero */
+void ep0_reset(void);
+void ep0_int_hndlr(void);
+
+/* receiver */
+void ep1_state_change_notify( int new_state );
+int  ep1_recv(void);
+int  ep1_init(int chn);
+void ep1_int_hndlr(int status);
+void ep1_reset(void);
+void ep1_stall(void);
+
+/* xmitter */
+void ep2_state_change_notify( int new_state );
+void ep2_reset(void);
+int  ep2_init(int chn);
+void ep2_int_hndlr(int status);
+void ep2_stall(void);
+
+#define UDC_write(reg, val) { \
+	int i = 10000; \
+	do { \
+	  	(reg) = (val); \
+		if (i-- <= 0) { \
+			printk( "%s [%d]: write %#x to %p (%#x) failed\n", \
+				__FUNCTION__, __LINE__, (val), &(reg), (reg)); \
+			break; \
+		} \
+	} while((reg) != (val)); \
+}
+
+#define UDC_set(reg, val) { \
+	int i = 10000; \
+	do { \
+		(reg) |= (val); \
+		if (i-- <= 0) { \
+			printk( "%s [%d]: set %#x of %p (%#x) failed\n", \
+				__FUNCTION__, __LINE__, (val), &(reg), (reg)); \
+			break; \
+		} \
+	} while(!((reg) & (val))); \
+}
+
+#define UDC_clear(reg, val) { \
+	int i = 10000; \
+	do { \
+		(reg) &= ~(val); \
+		if (i-- <= 0) { \
+			printk( "%s [%d]: clear %#x of %p (%#x) failed\n", \
+				__FUNCTION__, __LINE__, (val), &(reg), (reg)); \
+			break; \
+		} \
+	} while((reg) & (val)); \
+}
+
+#define UDC_flip(reg, val) { \
+	int i = 10000; \
+	(reg) = (val); \
+	do { \
+		(reg) = (val); \
+		if (i-- <= 0) { \
+			printk( "%s [%d]: flip %#x of %p (%#x) failed\n", \
+				__FUNCTION__, __LINE__, (val), &(reg), (reg)); \
+			break; \
+		} \
+	} while(((reg) & (val))); \
+}
+
+
+#define CHECK_ADDRESS { if ( Ser0UDCAR == 1 ) { printk("%s:%d I lost my address!!!\n",__FUNCTION__, __LINE__);}}
+#endif /* _USB_CTL_H */
diff -urN linux-2.4.29/arch/arm/mach-sa1100/usb_ep0.c linux-2.4.29-uc1/arch/arm/mach-sa1100/usb_ep0.c
--- linux-2.4.29/arch/arm/mach-sa1100/usb_ep0.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-sa1100/usb_ep0.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,911 @@
+/*
+ * Copyright (C) Extenex Corporation 2001
+ * Much folklore gleaned from original code:
+ *    Copyright (C) Compaq Computer Corporation, 1998, 1999
+ *
+ *  usb_ep0.c - SA1100 USB controller driver.
+ *              Endpoint zero management
+ *
+ *  Please see:
+ *    linux/Documentation/arm/SA1100/SA1100_USB
+ *  for details. (Especially since Intel docs are full of
+ *  errors about ep0 operation.) ward.willats@extenex.com.
+ *
+ * Intel also has a "Universal Serial Bus Client Device
+ * Validation for the StrongARM SA-1100 Microprocessor"
+ * document, which has flow charts and assembler test driver,
+ * but be careful, since it is just for validation and not
+ * a "real world" solution.
+ *
+ * A summary of three types of data-returning setups:
+ *
+ * 1. Setup request <= 8 bytes. That is, requests that can
+ *    be fullfilled in one write to the FIFO. DE is set
+ *    with IPR in queue_and_start_write(). (I don't know
+ *    if there really are any of these!)
+ *
+ * 2. Setup requests > 8 bytes (requiring more than one
+ *    IN to get back to the host), and we have at least
+ *    as much or more data than the host requested. In
+ *    this case we pump out everything we've got, and
+ *    when the final interrupt comes in due to the UDC
+ *    clearing the last IPR, we just set DE.
+ *
+ * 3. Setup requests > 8 bytes, but we don't have enough
+ *    data to satisfy the request. In this case, we send
+ *    everything we've got, and when the final interrupt
+ *    comes in due to the UDC clearing the last IPR
+ *    we write nothing to the FIFO and set both IPR and DE
+ *    so the UDC sends an empty packet and forces the host
+ *    to perform short packet retirement instead of stalling
+ *    out.
+ *
+ */
+
+#include <linux/delay.h>
+#include "sa1100_usb.h"  /* public interface */
+#include "usb_ctl.h"     /* private stuff */
+
+
+// 1 == lots of trace noise,  0 = only "important' stuff
+#define VERBOSITY 0
+
+enum { true = 1, false = 0 };
+typedef int bool;
+#ifndef MIN
+#define MIN( a, b ) ((a)<(b)?(a):(b))
+#endif
+
+#if 1 && !defined( ASSERT )
+#  define ASSERT(expr) \
+          if(!(expr)) { \
+          printk( "Assertion failed! %s,%s,%s,line=%d\n",\
+          #expr,__FILE__,__FUNCTION__,__LINE__); \
+          }
+#else
+#  define ASSERT(expr)
+#endif
+
+#if VERBOSITY
+#define PRINTKD(fmt, args...) printk( fmt , ## args)
+#else
+#define PRINTKD(fmt, args...)
+#endif
+
+/*================================================
+ * USB Protocol Stuff
+ */
+
+/* Request Codes   */
+enum { GET_STATUS=0,         CLEAR_FEATURE=1,     SET_FEATURE=3,
+	   SET_ADDRESS=5,        GET_DESCRIPTOR=6,	  SET_DESCRIPTOR=7,
+	   GET_CONFIGURATION=8,  SET_CONFIGURATION=9, GET_INTERFACE=10,
+	   SET_INTERFACE=11 };
+
+
+/* USB Device Requests */
+typedef struct
+{
+    __u8 bmRequestType;
+    __u8 bRequest;
+    __u16 wValue;
+    __u16 wIndex;
+    __u16 wLength;
+} usb_dev_request_t  __attribute__ ((packed));
+
+/***************************************************************************
+Prototypes
+***************************************************************************/
+/* "setup handlers" -- the main functions dispatched to by the
+   .. isr. These represent the major "modes" of endpoint 0 operaton */
+static void sh_setup_begin(void);				/* setup begin (idle) */
+static void sh_write( void );      				/* writing data */
+static void sh_write_with_empty_packet( void ); /* empty packet at end of xfer*/
+/* called before both sh_write routines above */
+static void common_write_preamble( void );
+
+/* other subroutines */
+static __u32  queue_and_start_write( void * p, int req, int act );
+static void write_fifo( void );
+static int read_fifo( usb_dev_request_t * p );
+static void get_descriptor( usb_dev_request_t * pReq );
+
+/* some voodo helpers  01Mar01ww */
+static void set_cs_bits( __u32 set_bits );
+static void set_de( void );
+static void set_ipr( void );
+static void set_ipr_and_de( void );
+static bool clear_opr( void );
+
+/***************************************************************************
+Inline Helpers
+***************************************************************************/
+
+/* Data extraction from usb_request_t fields */
+enum { kTargetDevice=0, kTargetInterface=1, kTargetEndpoint=2 };
+static inline int request_target( __u8 b ) { return (int) ( b & 0x0F); }
+
+static inline int windex_to_ep_num( __u16 w ) { return (int) ( w & 0x000F); }
+inline int type_code_from_request( __u8 by ) { return (( by >> 4 ) & 3); }
+
+/* following is hook for self-powered flag in GET_STATUS. Some devices
+   .. might like to override and return real info */
+static inline bool self_powered_hook( void ) { return true; }
+
+/* print string descriptor */
+static inline void psdesc( string_desc_t * p )
+{
+	 int i;
+	 int nchars = ( p->bLength - 2 ) / sizeof( __u16 );
+	 printk( "'" );
+	 for( i = 0 ; i < nchars ; i++ ) {
+		  printk( "%c", (char) p->bString[i] );
+	 }
+	 printk( "'\n" );
+}
+
+
+#if VERBOSITY
+/* "pcs" == "print control status" */
+static inline void pcs( void )
+{
+	 __u32 foo = Ser0UDCCS0;
+	 printk( "%8.8X: %s %s %s %s\n",
+			 foo,
+			 foo & UDCCS0_SE ? "SE" : "",
+			 foo & UDCCS0_OPR ? "OPR" : "",
+			 foo & UDCCS0_IPR ? "IPR" : "",
+			 foo & UDCCS0_SST ? "SST" : ""
+	 );
+}
+static inline void preq( usb_dev_request_t * pReq )
+{
+	 static char * tnames[] = { "dev", "intf", "ep", "oth" };
+	 static char * rnames[] = { "std", "class", "vendor", "???" };
+	 char * psz;
+	 switch( pReq->bRequest ) {
+	 case GET_STATUS: psz = "get stat"; break;
+	 case CLEAR_FEATURE: psz = "clr feat"; break;
+	 case SET_FEATURE: psz = "set feat"; break;
+	 case SET_ADDRESS: psz = "set addr"; break;
+	 case GET_DESCRIPTOR: psz = "get desc"; break;
+	 case SET_DESCRIPTOR: psz = "set desc"; break;
+	 case GET_CONFIGURATION: psz = "get cfg"; break;
+	 case SET_CONFIGURATION: psz = "set cfg"; break;
+	 case GET_INTERFACE: psz = "get intf"; break;
+	 case SET_INTERFACE: psz = "set intf"; break;
+	 default: psz = "unknown"; break;
+	 }
+	 printk( "- [%s: %s req to %s. dir=%s]\n", psz,
+			 rnames[ (pReq->bmRequestType >> 5) & 3 ],
+			 tnames[ pReq->bmRequestType & 3 ],
+			 ( pReq->bmRequestType & 0x80 ) ? "in" : "out" );
+}
+
+#else
+static inline void pcs( void ){}
+static inline void preq( void ){}
+#endif
+
+/***************************************************************************
+Globals
+***************************************************************************/
+static const char pszMe[] = "usbep0: ";
+
+/* pointer to current setup handler */
+static void (*current_handler)(void) = sh_setup_begin;
+
+/* global write struct to keep write
+   ..state around across interrupts */
+static struct {
+		unsigned char *p;
+		int bytes_left;
+} wr;
+
+/***************************************************************************
+Public Interface
+***************************************************************************/
+
+/* reset received from HUB (or controller just went nuts and reset by itself!)
+  so udc core has been reset, track this state here  */
+void
+ep0_reset(void)
+{
+	 /* reset state machine */
+	 current_handler = sh_setup_begin;
+	 wr.p = NULL;
+	 wr.bytes_left = 0;
+	 usbd_info.address=0;
+}
+
+/* handle interrupt for endpoint zero */
+void
+ep0_int_hndlr( void )
+{
+	 PRINTKD( "/\\(%d)\n", Ser0UDCAR );
+	 pcs();
+
+	 /* if not in setup begin, we are returning data.
+		execute a common preamble to both write handlers
+	 */
+	 if ( current_handler != sh_setup_begin )
+		  common_write_preamble();
+
+	 (*current_handler)();
+
+	 PRINTKD( "---\n" );
+	 pcs();
+	 PRINTKD( "\\/\n" );
+}
+
+/***************************************************************************
+Setup Handlers
+***************************************************************************/
+/*
+ * sh_setup_begin()
+ * This setup handler is the "idle" state of endpoint zero. It looks for OPR
+ * (OUT packet ready) to see if a setup request has been been received from the
+ * host. Requests without a return data phase are immediately handled. Otherwise,
+ * in the case of GET_XXXX the handler may be set to one of the sh_write_xxxx
+ * data pumpers if more than 8 bytes need to get back to the host.
+ *
+ */
+static void
+sh_setup_begin( void )
+{
+	 unsigned char status_buf[2];  /* returned in GET_STATUS */
+	 usb_dev_request_t req;
+	 int request_type;
+	 int n;
+	 __u32 cs_bits;
+	 __u32 address;
+	 __u32 cs_reg_in = Ser0UDCCS0;
+
+	 if (cs_reg_in & UDCCS0_SST) {
+		  PRINTKD( "%ssetup begin: sent stall. Continuing\n", pszMe );
+		  set_cs_bits( UDCCS0_SST );
+	}
+
+	 if ( cs_reg_in & UDCCS0_SE ) {
+		  PRINTKD( "%ssetup begin: Early term of setup. Continuing\n", pszMe );
+		  set_cs_bits( UDCCS0_SSE );  		 /* clear setup end */
+	 }
+
+	 /* Be sure out packet ready, otherwise something is wrong */
+	 if ( (cs_reg_in & UDCCS0_OPR) == 0 ) {
+		  /* we can get here early...if so, we'll int again in a moment  */
+		  PRINTKD( "%ssetup begin: no OUT packet available. Exiting\n", pszMe );
+		  goto sh_sb_end;
+	 }
+
+	 /* read the setup request */
+	 n = read_fifo( &req );
+	 if ( n != sizeof( req ) ) {
+		  printk( "%ssetup begin: fifo READ ERROR wanted %d bytes got %d. "
+				  " Stalling out...\n",
+				  pszMe, sizeof( req ), n );
+		  /* force stall, serviced out */
+		  set_cs_bits( UDCCS0_FST | UDCCS0_SO  );
+		  goto sh_sb_end;
+	 }
+
+	 /* Is it a standard request? (not vendor or class request) */
+	 request_type = type_code_from_request( req.bmRequestType );
+	 if ( request_type != 0 ) {
+		  printk( "%ssetup begin: unsupported bmRequestType: %d ignored\n",
+				  pszMe, request_type );
+		  set_cs_bits( UDCCS0_DE | UDCCS0_SO );
+		  goto sh_sb_end;
+	 }
+
+#if VERBOSITY
+	 {
+	 unsigned char * pdb = (unsigned char *) &req;
+	 PRINTKD( "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X ",
+			 pdb[0], pdb[1], pdb[2], pdb[3], pdb[4], pdb[5], pdb[6], pdb[7]
+		  );
+	 preq( &req );
+	 }
+#endif
+
+	 /* Handle it */
+	 switch( req.bRequest ) {
+
+		  /* This first bunch have no data phase */
+
+	 case SET_ADDRESS:
+		  address = (__u32) (req.wValue & 0x7F);
+		  /* when SO and DE sent, UDC will enter status phase and ack,
+			 ..propagating new address to udc core. Next control transfer
+			 ..will be on the new address. You can't see the change in a
+			 ..read back of CAR until then. (about 250us later, on my box).
+			 ..The original Intel driver sets S0 and DE and code to check
+			 ..that address has propagated here. I tried this, but it
+			 ..would only work sometimes! The rest of the time it would
+			 ..never propagate and we'd spin forever. So now I just set
+			 ..it and pray...
+		  */
+		  Ser0UDCAR = address;
+		  usbd_info.address = address;
+		  usbctl_next_state_on_event( kEvAddress );
+		  set_cs_bits( UDCCS0_SO | UDCCS0_DE );  /* no data phase */
+		  printk( "%sI have been assigned address: %d\n", pszMe, address );
+		  break;
+
+
+	 case SET_CONFIGURATION:
+		  if ( req.wValue == 1 ) {
+			   /* configured */
+			   if (usbctl_next_state_on_event( kEvConfig ) != kError){
+								/* (re)set the out and in max packet sizes */
+					desc_t * pDesc = sa1100_usb_get_descriptor_ptr();
+					__u32 out = __le16_to_cpu( pDesc->b.ep1.wMaxPacketSize );
+					__u32 in  = __le16_to_cpu( pDesc->b.ep2.wMaxPacketSize );
+					Ser0UDCOMP = ( out - 1 );
+					Ser0UDCIMP = ( in - 1 );
+					printk( "%sConfigured (OMP=%8.8X IMP=%8.8X)\n", pszMe, out, in );
+			   }
+		  } else if ( req.wValue == 0 ) {
+			   /* de-configured */
+			   if (usbctl_next_state_on_event( kEvDeConfig ) != kError )
+					printk( "%sDe-Configured\n", pszMe );
+		  } else {
+			   printk( "%ssetup phase: Unknown "
+					   "\"set configuration\" data %d\n",
+					   pszMe, req.wValue );
+		  }
+		  set_cs_bits( UDCCS0_SO | UDCCS0_DE );  /* no data phase */
+		  break;
+
+	 case CLEAR_FEATURE:
+		  /* could check data length, direction...26Jan01ww */
+		  if ( req.wValue == 0 ) { /* clearing ENDPOINT_HALT/STALL */
+			   int ep = windex_to_ep_num( req.wIndex );
+			   if ( ep == 1 ) {
+					printk( "%sclear feature \"endpoint halt\" "
+							" on receiver\n", pszMe );
+					ep1_reset();
+			   }
+			   else if ( ep == 2 ) {
+					printk( "%sclear feature \"endpoint halt\" "
+							"on xmitter\n", pszMe );
+					ep2_reset();
+			   } else {
+					printk( "%sclear feature \"endpoint halt\" "
+							"on unsupported ep # %d\n",
+							pszMe, ep );
+			   }
+		  } else {
+			   printk( "%sUnsupported feature selector (%d) "
+					   "in clear feature. Ignored.\n" ,
+					   pszMe, req.wValue );
+		  }
+		  set_cs_bits( UDCCS0_SO | UDCCS0_DE );  /* no data phase */
+		  break;
+
+	 case SET_FEATURE:
+		  if ( req.wValue == 0 ) { /* setting ENDPOINT_HALT/STALL */
+			   int ep = windex_to_ep_num( req.wValue );
+			   if ( ep == 1 ) {
+					printk( "%set feature \"endpoint halt\" "
+							"on receiver\n", pszMe );
+					ep1_stall();
+			   }
+			   else if ( ep == 2 ) {
+					printk( "%sset feature \"endpoint halt\" "
+							" on xmitter\n", pszMe );
+					ep2_stall();
+			   } else {
+					printk( "%sset feature \"endpoint halt\" "
+							"on unsupported ep # %d\n",
+							pszMe, ep );
+			   }
+		  }
+		  else {
+			   printk( "%sUnsupported feature selector "
+					   "(%d) in set feature\n",
+					   pszMe, req.wValue );
+		  }
+		  set_cs_bits( UDCCS0_SO | UDCCS0_DE );  /* no data phase */
+		  break;
+
+
+		  /* The rest have a data phase that writes back to the host */
+	 case GET_STATUS:
+		  /* return status bit flags */
+		  status_buf[0] = status_buf[1] = 0;
+		  n = request_target(req.bmRequestType);
+		  switch( n ) {
+		  case kTargetDevice:
+			   if ( self_powered_hook() )
+					status_buf[0] |= 1;
+			   break;
+		  case kTargetInterface:
+			   break;
+		  case kTargetEndpoint:
+			   /* return stalled bit */
+			   n = windex_to_ep_num( req.wIndex );
+			   if ( n == 1 )
+					status_buf[0] |= (Ser0UDCCS1 & UDCCS1_FST) >> 4;
+			   else if ( n == 2 )
+					status_buf[0] |= (Ser0UDCCS2 & UDCCS2_FST) >> 5;
+			   else {
+					printk( "%sUnknown endpoint (%d) "
+							"in GET_STATUS\n", pszMe, n );
+			   }
+			   break;
+		  default:
+			   printk( "%sUnknown target (%d) in GET_STATUS\n",
+					   pszMe, n );
+			   /* fall thru */
+			   break;
+		  }
+		  cs_bits  = queue_and_start_write( status_buf,
+											req.wLength,
+											sizeof( status_buf ) );
+		  set_cs_bits( cs_bits );
+		  break;
+	 case GET_DESCRIPTOR:
+		  get_descriptor( &req );
+		  break;
+
+	 case GET_CONFIGURATION:
+		  status_buf[0] = (usbd_info.state ==  USB_STATE_CONFIGURED)
+			   ? 1
+			   : 0;
+		  cs_bits = queue_and_start_write( status_buf, req.wLength, 1 );
+		  set_cs_bits( cs_bits );
+		  break;
+	 case GET_INTERFACE:
+		  printk( "%sfixme: get interface not supported\n", pszMe );
+		  cs_bits = queue_and_start_write( NULL, req.wLength, 0 );
+		  set_cs_bits( cs_bits );
+		  break;
+	 case SET_INTERFACE:
+		  printk( "%sfixme: set interface not supported\n", pszMe );
+		  set_cs_bits( UDCCS0_DE | UDCCS0_SO );
+		  break;
+	 default :
+		  printk("%sunknown request 0x%x\n", pszMe, req.bRequest);
+		  break;
+	 } /* switch( bRequest ) */
+
+sh_sb_end:
+	 return;
+
+}
+/*
+ * common_wrtie_preamble()
+ * Called before execution of sh_write() or sh_write_with_empty_packet()
+ * Handles common abort conditions.
+ *
+ */
+static void common_write_preamble( void )
+{
+	 /* If "setup end" has been set, the usb controller has
+		..terminated a setup transaction before we set DE. This
+		..happens during enumeration with some hosts. For example,
+		..the host will ask for our device descriptor and specify
+		..a return of 64 bytes. When we hand back the first 8, the
+		..host will know our max packet size and turn around and
+		..issue a new setup immediately. This causes the UDC to auto-ack
+		..the new setup and set SE. We must then "unload" (process)
+		..the new setup, which is what will happen after this preamble
+		..is finished executing.
+	 */
+	 __u32 cs_reg_in = Ser0UDCCS0;
+
+	 if ( cs_reg_in & UDCCS0_SE ) {
+		  PRINTKD( "%swrite_preamble(): Early termination of setup\n", pszMe );
+		  Ser0UDCCS0 =  UDCCS0_SSE;  		 /* clear setup end */
+		  current_handler = sh_setup_begin;
+	 }
+
+	 if ( cs_reg_in & UDCCS0_SST ) {
+		  PRINTKD( "%swrite_preamble(): UDC sent stall\n", pszMe );
+		  Ser0UDCCS0 = UDCCS0_SST;  		 /* clear setup end */
+		  current_handler = sh_setup_begin;
+	 }
+
+	 if ( cs_reg_in & UDCCS0_OPR ) {
+		  PRINTKD( "%swrite_preamble(): see OPR. Stopping write to "
+				   "handle new SETUP\n", pszMe );
+		  /* very rarely, you can get OPR and leftover IPR. Try to clear */
+		  UDC_clear( Ser0UDCCS0, UDCCS0_IPR );
+		  current_handler = sh_setup_begin;
+	 }
+}
+
+/*
+ * sh_write()
+ * This is the setup handler when we are in the data return phase of
+ * a setup request and have as much (or more) data than the host
+ * requested. If we enter this routine and bytes left is zero, the
+ * last data packet has gone (int is because IPR was just cleared)
+ * so we just set DE and reset. Otheriwse, we write another packet
+ * and set IPR.
+ */
+static void sh_write()
+{
+	 PRINTKD( "W\n" );
+
+	 if ( Ser0UDCCS0 & UDCCS0_IPR ) {
+		  PRINTKD( "%ssh_write(): IPR set, exiting\n", pszMe );
+		  return;
+	 }
+
+	 /* If bytes left is zero, we are coming in on the
+		..interrupt after the last packet went out. And
+		..we know we don't have to empty packet this transfer
+		..so just set DE and we are done */
+
+	 if ( 0 == wr.bytes_left ) {
+		  /* that's it, so data end  */
+		  set_de();
+		  wr.p = NULL;  				/* be anal */
+		  current_handler = sh_setup_begin;
+	 } else {
+		  /* Otherwise, more data to go */
+		  write_fifo();
+		  set_ipr();
+	 }
+}
+/*
+ * sh_write_with_empty_packet()
+ * This is the setup handler when we don't have enough data to
+ * satisfy the host's request. After we send everything we've got
+ * we must send an empty packet (by setting IPR and DE) so the
+ * host can perform "short packet retirement" and not stall.
+ *
+ */
+static void sh_write_with_empty_packet( void )
+{
+	 __u32 cs_reg_out = 0;
+	 PRINTKD( "WE\n" );
+
+	 if ( Ser0UDCCS0 & UDCCS0_IPR ) {
+		  PRINTKD( "%ssh_write(): IPR set, exiting\n", pszMe );
+		  return;
+	 }
+
+	 /* If bytes left is zero, we are coming in on the
+		..interrupt after the last packet went out.
+		..we must do short packet suff, so set DE and IPR
+	 */
+
+	 if ( 0 == wr.bytes_left ) {
+		  set_ipr_and_de();
+		  wr.p = NULL;
+		  current_handler = sh_setup_begin;
+		  PRINTKD( "%ssh_write empty() Sent empty packet \n", pszMe );
+	 }  else {
+		  write_fifo();				/* send data */
+		  set_ipr();				/* flag a packet is ready */
+	 }
+	 Ser0UDCCS0 = cs_reg_out;
+}
+
+/***************************************************************************
+Other Private Subroutines
+***************************************************************************/
+/*
+ * queue_and_start_write()
+ * p == data to send
+ * req == bytes host requested
+ * act == bytes we actually have
+ * Returns: bits to be flipped in ep0 control/status register
+ *
+ * Called from sh_setup_begin() to begin a data return phase. Sets up the
+ * global "wr"-ite structure and load the outbound FIFO with data.
+ * If can't send all the data, set appropriate handler for next interrupt.
+ *
+ */
+static __u32  queue_and_start_write( void * in, int req, int act )
+{
+	 __u32 cs_reg_bits = UDCCS0_IPR;
+	 unsigned char * p = (unsigned char*) in;
+
+	 PRINTKD( "Qr=%d a=%d\n",req,act );
+
+	/* thou shalt not enter data phase until the serviced OUT is clear */
+	 if ( ! clear_opr() ) {
+		  printk( "%sSO did not clear OPR\n", pszMe );
+		  return ( UDCCS0_DE | UDCCS0_SO ) ;
+	 }
+	 wr.p = p;
+	 wr.bytes_left = MIN( act, req );
+
+	 write_fifo();
+
+	 if ( 0 == wr.bytes_left ) {
+		  cs_reg_bits |= UDCCS0_DE;	/* out in 1 so data end */
+		  wr.p = NULL;  				/* be anal */
+	 }
+	 else if ( act < req )   /* we are going to short-change host */
+		  current_handler = sh_write_with_empty_packet; /* so need nul to not stall */
+	 else /* we have as much or more than requested */
+		  current_handler = sh_write;
+
+	 return cs_reg_bits; /* note: IPR was set uncondtionally at start of routine */
+}
+/*
+ * write_fifo()
+ * Stick bytes in the 8 bytes endpoint zero FIFO.
+ * This version uses a variety of tricks to make sure the bytes
+ * are written correctly. 1. The count register is checked to
+ * see if the byte went in, and the write is attempted again
+ * if not. 2. An overall counter is used to break out so we
+ * don't hang in those (rare) cases where the UDC reverses
+ * direction of the FIFO underneath us without notification
+ * (in response to host aborting a setup transaction early).
+ *
+ */
+static void write_fifo( void )
+{
+	int bytes_this_time = MIN( wr.bytes_left, 8 );
+	int bytes_written = 0;
+	int i=0;
+
+	PRINTKD( "WF=%d: ", bytes_this_time );
+
+	while( bytes_this_time-- ) {
+		 PRINTKD( "%2.2X ", *wr.p );
+		 i = 0;
+		 do {
+			  Ser0UDCD0 = *wr.p;
+			  udelay( 20 );  /* voodo 28Feb01ww */
+			  i++;
+		 } while( Ser0UDCWC == bytes_written && i < 10 );
+		 if ( i == 50 ) {
+			  printk( "%swrite_fifo: write failure\n", pszMe );
+			  usbd_info.stats.ep0_fifo_write_failures++;
+		 }
+
+		 wr.p++;
+		 bytes_written++;
+	}
+	wr.bytes_left -= bytes_written;
+
+	/* following propagation voodo so maybe caller writing IPR in
+	   ..a moment might actually get it to stick 28Feb01ww */
+	udelay( 300 );
+
+	usbd_info.stats.ep0_bytes_written += bytes_written;
+	PRINTKD( "L=%d WCR=%8.8X\n", wr.bytes_left, Ser0UDCWC );
+}
+/*
+ * read_fifo()
+ * Read 1-8 bytes out of FIFO and put in request.
+ * Called to do the initial read of setup requests
+ * from the host. Return number of bytes read.
+ *
+ * Like write fifo above, this driver uses multiple
+ * reads checked agains the count register with an
+ * overall timeout.
+ *
+ */
+static int
+read_fifo( usb_dev_request_t * request )
+{
+	int bytes_read = 0;
+	int fifo_count;
+	int i;
+
+	unsigned char * pOut = (unsigned char*) request;
+
+	fifo_count = ( Ser0UDCWC & 0xFF );
+
+	ASSERT( fifo_count <= 8 );
+	PRINTKD( "RF=%d ", fifo_count );
+
+	while( fifo_count-- ) {
+		 i = 0;
+		 do {
+			  *pOut = (unsigned char) Ser0UDCD0;
+			  udelay( 10 );
+		 } while( ( Ser0UDCWC & 0xFF ) != fifo_count && i < 10 );
+		 if ( i == 10 ) {
+			  printk( "%sread_fifo(): read failure\n", pszMe );
+			  usbd_info.stats.ep0_fifo_read_failures++;
+		 }
+		 pOut++;
+		 bytes_read++;
+	}
+
+	PRINTKD( "fc=%d\n", bytes_read );
+	usbd_info.stats.ep0_bytes_read++;
+	return bytes_read;
+}
+
+/*
+ * get_descriptor()
+ * Called from sh_setup_begin to handle data return
+ * for a GET_DESCRIPTOR setup request.
+ */
+static void get_descriptor( usb_dev_request_t * pReq )
+{
+	 __u32 cs_bits = 0;
+	 string_desc_t * pString;
+	 ep_desc_t * pEndpoint;
+
+	 desc_t * pDesc = sa1100_usb_get_descriptor_ptr();
+	 int type = pReq->wValue >> 8;
+	 int idx  = pReq->wValue & 0xFF;
+
+	 switch( type ) {
+	 case USB_DESC_DEVICE:
+		  cs_bits =
+			   queue_and_start_write( &pDesc->dev,
+									  pReq->wLength,
+									  pDesc->dev.bLength );
+		  break;
+
+		  // return config descriptor buffer, cfg, intf, 2 ep
+	 case USB_DESC_CONFIG:
+		  cs_bits =
+			   queue_and_start_write( &pDesc->b,
+									  pReq->wLength,
+									  sizeof( struct cdb ) );
+		  break;
+
+		  // not quite right, since doesn't do language code checking
+	 case USB_DESC_STRING:
+		  pString = sa1100_usb_get_string_descriptor( idx );
+		  if ( pString ) {
+			   if ( idx != 0 ) {  // if not language index
+					printk( "%sReturn string %d: ", pszMe, idx );
+					psdesc( pString );
+			   }
+			   cs_bits =
+					queue_and_start_write( pString,
+										   pReq->wLength,
+										   pString->bLength );
+		  }
+		  else {
+			   printk("%sunkown string index %d Stall.\n", pszMe, idx );
+			   cs_bits = ( UDCCS0_DE | UDCCS0_SO | UDCCS0_FST );
+		  }
+		  break;
+
+	 case USB_DESC_INTERFACE:
+		  if ( idx == pDesc->b.intf.bInterfaceNumber ) {
+			   cs_bits =
+					queue_and_start_write( &pDesc->b.intf,
+										   pReq->wLength,
+										   pDesc->b.intf.bLength );
+		  }
+		  break;
+
+	 case USB_DESC_ENDPOINT: /* correct? 21Feb01ww */
+		  if ( idx == 1 )
+			   pEndpoint = &pDesc->b.ep1;
+		  else if ( idx == 2 )
+			   pEndpoint = &pDesc->b.ep2;
+		  else
+			   pEndpoint = NULL;
+		  if ( pEndpoint ) {
+			   cs_bits =
+					queue_and_start_write( pEndpoint,
+										   pReq->wLength,
+										   pEndpoint->bLength );
+		  } else {
+			   printk("%sunkown endpoint index %d Stall.\n", pszMe, idx );
+			   cs_bits = ( UDCCS0_DE | UDCCS0_SO | UDCCS0_FST );
+		  }
+		  break;
+
+
+	 default :
+		  printk("%sunknown descriptor type %d. Stall.\n", pszMe, type );
+		  cs_bits = ( UDCCS0_DE | UDCCS0_SO | UDCCS0_FST );
+		  break;
+
+	 }
+	 set_cs_bits( cs_bits );
+}
+
+
+/* some voodo I am adding, since the vanilla macros just aren't doing it  1Mar01ww */
+
+#define ABORT_BITS ( UDCCS0_SST | UDCCS0_SE )
+#define OK_TO_WRITE (!( Ser0UDCCS0 & ABORT_BITS ))
+#define BOTH_BITS (UDCCS0_IPR | UDCCS0_DE)
+
+static void set_cs_bits( __u32 bits )
+{
+	 if ( bits & ( UDCCS0_SO | UDCCS0_SSE | UDCCS0_FST ) )
+		  Ser0UDCCS0 = bits;
+	 else if ( (bits & BOTH_BITS) == BOTH_BITS )
+		  set_ipr_and_de();
+	 else if ( bits & UDCCS0_IPR )
+		  set_ipr();
+	 else if ( bits & UDCCS0_DE )
+		  set_de();
+}
+
+static void set_de( void )
+{
+	 int i = 1;
+	 while( 1 ) {
+		  if ( OK_TO_WRITE ) {
+				Ser0UDCCS0 |= UDCCS0_DE;
+		  } else {
+			   PRINTKD( "%sQuitting set DE because SST or SE set\n", pszMe );
+			   break;
+		  }
+		  if ( Ser0UDCCS0 & UDCCS0_DE )
+			   break;
+		  udelay( i );
+		  if ( ++i == 50  ) {
+			   printk( "%sDangnabbbit! Cannot set DE! (DE=%8.8X CCS0=%8.8X)\n",
+					   pszMe, UDCCS0_DE, Ser0UDCCS0 );
+			   break;
+		  }
+	 }
+}
+
+static void set_ipr( void )
+{
+	 int i = 1;
+	 while( 1 ) {
+		  if ( OK_TO_WRITE ) {
+				Ser0UDCCS0 |= UDCCS0_IPR;
+		  } else {
+			   PRINTKD( "%sQuitting set IPR because SST or SE set\n", pszMe );
+			   break;
+		  }
+		  if ( Ser0UDCCS0 & UDCCS0_IPR )
+			   break;
+		  udelay( i );
+		  if ( ++i == 50  ) {
+			   printk( "%sDangnabbbit! Cannot set IPR! (IPR=%8.8X CCS0=%8.8X)\n",
+					   pszMe, UDCCS0_IPR, Ser0UDCCS0 );
+			   break;
+		  }
+	 }
+}
+
+
+
+static void set_ipr_and_de( void )
+{
+	 int i = 1;
+	 while( 1 ) {
+		  if ( OK_TO_WRITE ) {
+			   Ser0UDCCS0 |= BOTH_BITS;
+		  } else {
+			   PRINTKD( "%sQuitting set IPR/DE because SST or SE set\n", pszMe );
+			   break;
+		  }
+		  if ( (Ser0UDCCS0 & BOTH_BITS) == BOTH_BITS)
+			   break;
+		  udelay( i );
+		  if ( ++i == 50  ) {
+			   printk( "%sDangnabbbit! Cannot set DE/IPR! (DE=%8.8X IPR=%8.8X CCS0=%8.8X)\n",
+					   pszMe, UDCCS0_DE, UDCCS0_IPR, Ser0UDCCS0 );
+			   break;
+		  }
+	 }
+}
+
+static bool clear_opr( void )
+{
+	 int i = 10000;
+	 bool is_clear;
+	 do {
+		  Ser0UDCCS0 = UDCCS0_SO;
+		  is_clear  = ! ( Ser0UDCCS0 & UDCCS0_OPR );
+		  if ( i-- <= 0 ) {
+			   printk( "%sclear_opr(): failed\n", pszMe );
+			   break;
+		  }
+	 } while( ! is_clear );
+	 return is_clear;
+}
+
+
+
+
+
+/* end usb_ep0.c */
+
diff -urN linux-2.4.29/arch/arm/mach-sa1100/usb-eth.c linux-2.4.29-uc1/arch/arm/mach-sa1100/usb-eth.c
--- linux-2.4.29/arch/arm/mach-sa1100/usb-eth.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-sa1100/usb-eth.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,447 @@
+ /*
+ * Ethernet driver for the SA1100 USB client function
+ * Copyright (c) 2001 by Nicolas Pitre
+ *
+ * This code was loosely inspired by the original initial ethernet test driver
+ * Copyright (c) Compaq Computer Corporation, 1999
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This is still work in progress...
+ *
+ * 19/02/2001 - Now we are compatible with generic usbnet driver. green@iXcelerator.com
+ * 09/03/2001 - Dropped 'framing' scheme, as it seems to cause a lot of problems with little benefit.
+ *		Now, since we do not know what size of packet we are receiving
+ *		last usb packet in sequence will always be less than max packet
+ *		receive endpoint can accept.
+ *		Now the only way to check correct start of frame is to compare
+ *		MAC address. Also now we are stalling on each receive error.
+ *
+ * 15/03/2001 - Using buffer to get data from UDC. DMA needs to have 8 byte
+ *		aligned buffer, but this breaks IP code (unaligned access).
+ *
+ * 01/04/2001 - stall endpoint operations appeared to be very unstable, so
+ *              they are disabled now.
+ *
+ * 03/06/2001 - Readded "zerocopy" receive path (tunable).
+ *
+ */
+
+// Define DMA_NO_COPY if you want data to arrive directly into the
+// receive network buffers, instead of arriving into bounce buffer
+// and then get copied to network buffer.
+// This does not work correctly right now.
+#undef DMA_NO_COPY
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/timer.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/random.h>
+
+#include "sa1100_usb.h"
+
+
+#define ETHERNET_VENDOR_ID 0x49f
+#define ETHERNET_PRODUCT_ID 0x505A
+#define MAX_PACKET 32768
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+// Should be global, so that insmod can change these
+int usb_rsize=64;
+int usb_wsize=64;
+
+static struct usbe_info_t {
+  struct net_device *dev;
+  u16 packet_id;
+  struct net_device_stats stats;
+} usbe_info;
+
+static char usb_eth_name[16] = "usbf";
+static struct net_device usb_eth_device;
+static struct sk_buff *cur_tx_skb, *next_tx_skb;
+static struct sk_buff *cur_rx_skb, *next_rx_skb;
+static volatile int terminating;
+#ifndef DMA_NO_COPY
+static char *dmabuf; // we need that, as dma expect it's buffers to be aligned on 8 bytes boundary
+#endif
+
+static int usb_change_mtu (struct net_device *net, int new_mtu)
+{
+	if (new_mtu <= sizeof (struct ethhdr) || new_mtu > MAX_PACKET)
+		return -EINVAL;
+	// no second zero-length packet read wanted after mtu-sized packets
+	if (((new_mtu + sizeof (struct ethhdr)) % usb_rsize) == 0)
+		return -EDOM;
+
+	net->mtu = new_mtu;
+	return 0;
+}
+
+static struct sk_buff *
+usb_new_recv_skb(void)
+{
+	struct sk_buff *skb = alloc_skb( 2 + sizeof (struct ethhdr) + usb_eth_device.mtu,GFP_ATOMIC);
+
+	if (skb) {
+		skb_reserve(skb, 2);
+	}
+	return skb;
+}
+
+static u8 bcast_hwaddr[ETH_ALEN]={0xff,0xff,0xff,0xff,0xff,0xff};
+static void
+usb_recv_callback(int flag, int size)
+{
+	struct sk_buff *skb;
+
+	if (terminating)
+		return;
+
+	skb = cur_rx_skb;
+
+	/* flag validation */
+	if (flag == 0) {
+		if ( skb_tailroom (skb) < size ) { // hey! we are overloaded!!!
+			usbe_info.stats.rx_over_errors++;
+			goto error;
+		}
+#ifndef DMA_NO_COPY
+		memcpy(skb->tail,dmabuf,size);
+#endif
+		skb_put(skb, size);
+	} else {
+		if (flag == -EIO) {
+			usbe_info.stats.rx_errors++;
+		}
+		goto error;
+	}
+
+	/* validate packet length */
+	if (size == usb_rsize ) {
+		/* packet not complete yet */
+		skb = NULL;
+	}
+
+	/*
+	 * At this point skb is non null if we have a complete packet.
+	 * If so take a fresh skb right away and restart USB receive without
+	 * further delays, then process the packet.  Otherwise resume USB
+	 * receive on the current skb and exit.
+	 */
+
+	if (skb)
+		cur_rx_skb = next_rx_skb;
+#ifndef DMA_NO_COPY
+	sa1100_usb_recv(dmabuf, usb_rsize,
+			usb_recv_callback);
+#else
+	sa1100_usb_recv(cur_rx_skb->tail, MIN(usb_rsize, skb_tailroom (cur_rx_skb)),
+			usb_recv_callback);
+#endif
+	if (!skb)
+		return;
+
+	next_rx_skb = usb_new_recv_skb();
+	if (!next_rx_skb) {
+		/*
+		 * We can't aford loosing buffer space...
+		 * So we drop the current packet and recycle its skb.
+		 */
+		printk("%s: can't allocate new skb\n", __FUNCTION__);
+		usbe_info.stats.rx_dropped++;
+		skb_trim(skb, 0);
+		next_rx_skb = skb;
+		return;
+	}
+	if ( skb->len >= sizeof(struct ethhdr)) {
+		if (memcmp(skb->data,usb_eth_device.dev_addr,ETH_ALEN) && memcmp(skb->data,bcast_hwaddr,ETH_ALEN) ) {
+			// This frame is not for us. nor it is broadcast
+			usbe_info.stats.rx_frame_errors++;
+			kfree_skb(skb);
+			goto error;
+		}
+	}
+
+	if (skb->len) {
+		int     status;
+// FIXME: eth_copy_and_csum "small" packets to new SKB (small < ~200 bytes) ?
+
+		skb->dev = &usb_eth_device;
+		skb->protocol = eth_type_trans (skb, &usb_eth_device);
+		usbe_info.stats.rx_packets++;
+		usbe_info.stats.rx_bytes += skb->len;
+		skb->ip_summed = CHECKSUM_NONE;
+		status = netif_rx (skb);
+		if (status != NET_RX_SUCCESS)
+			printk("netif_rx failed with code %d\n",status);
+	} else {
+error:
+		/*
+		 * Error due to HW addr mismatch, or IO error.
+		 * Recycle the current skb and reset USB reception.
+		 */
+		skb_trim(cur_rx_skb, 0);
+//		if ( flag == -EINTR || flag == -EAGAIN ) // only if we are coming out of stall
+#ifndef DMA_NO_COPY
+			sa1100_usb_recv(dmabuf, usb_rsize, usb_recv_callback);
+#else
+			sa1100_usb_recv(cur_rx_skb->tail, MIN(usb_rsize, skb_tailroom (cur_rx_skb)), usb_recv_callback);
+#endif
+	}
+}
+
+
+static void
+usb_send_callback(int flag, int size)
+{
+	struct net_device *dev = usbe_info.dev;
+	struct net_device_stats *stats;
+	struct sk_buff *skb=cur_tx_skb;
+	int ret;
+
+	if (terminating)
+		return;
+
+	stats = &usbe_info.stats;
+	switch (flag) {
+	    case 0:
+		stats->tx_packets++;
+		stats->tx_bytes += size;
+		break;
+	    case -EIO:
+		stats->tx_errors++;
+		break;
+	    default:
+		stats->tx_dropped++;
+		break;
+	}
+
+	cur_tx_skb = next_tx_skb;
+	next_tx_skb = NULL;
+	dev_kfree_skb_irq(skb);
+	if (!cur_tx_skb)
+		return;
+
+	dev->trans_start = jiffies;
+	ret = sa1100_usb_send(cur_tx_skb->data, cur_tx_skb->len, usb_send_callback);
+	if (ret) {
+		/* If the USB core can't accept the packet, we drop it. */
+		dev_kfree_skb_irq(cur_tx_skb);
+		cur_tx_skb = NULL;
+		usbe_info.stats.tx_carrier_errors++;
+	}
+	netif_wake_queue(dev);
+}
+
+static int
+usb_eth_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	int ret;
+	unsigned long flags;
+
+	if (next_tx_skb) {
+		printk("%s: called with next_tx_skb != NULL\n", __FUNCTION__);
+		return 1;
+	}
+
+	if (skb_shared (skb)) {
+		struct sk_buff  *skb2 = skb_unshare(skb, GFP_ATOMIC);
+		if (!skb2) {
+			usbe_info.stats.tx_dropped++;
+			dev_kfree_skb(skb);
+			return 1;
+		}
+		skb = skb2;
+	}
+
+	if ((skb->len % usb_wsize) == 0) {
+		skb->len++; // other side will ignore this one, anyway.
+	}
+
+	local_irq_save(flags);
+	if (cur_tx_skb) {
+		next_tx_skb = skb;
+		netif_stop_queue(dev);
+	} else {
+		cur_tx_skb = skb;
+		dev->trans_start = jiffies;
+		ret = sa1100_usb_send(skb->data, skb->len, usb_send_callback);
+		if (ret) {
+			/* If the USB core can't accept the packet, we drop it. */
+			dev_kfree_skb(skb);
+			cur_tx_skb = NULL;
+			usbe_info.stats.tx_carrier_errors++;
+		}
+	}
+	local_irq_restore(flags);
+	return 0;
+}
+
+static void
+usb_xmit_timeout(struct net_device *dev )
+{
+	sa1100_usb_send_reset();
+	dev->trans_start = jiffies;
+	netif_wake_queue(dev);
+}
+
+
+static int
+usb_eth_open(struct net_device *dev)
+{
+	terminating = 0;
+	cur_tx_skb = next_tx_skb = NULL;
+	cur_rx_skb = usb_new_recv_skb();
+	next_rx_skb = usb_new_recv_skb();
+	if (!cur_rx_skb || !next_rx_skb) {
+		printk("%s: can't allocate new skb\n", __FUNCTION__);
+		if (cur_rx_skb)
+			kfree_skb(cur_rx_skb);
+		if (next_rx_skb)
+			kfree_skb(next_rx_skb);
+		return -ENOMEM;;
+	}
+
+	MOD_INC_USE_COUNT;
+#ifndef DMA_NO_COPY
+	sa1100_usb_recv(dmabuf, usb_rsize, usb_recv_callback);
+#else
+	sa1100_usb_recv(cur_rx_skb->tail, MIN(usb_rsize, skb_tailroom (cur_rx_skb)),
+			usb_recv_callback);
+#endif
+	return 0;
+}
+
+static int
+usb_eth_release(struct net_device *dev)
+{
+	terminating = 1;
+	sa1100_usb_send_reset();
+	sa1100_usb_recv_reset();
+	if (cur_tx_skb)
+		kfree_skb(cur_tx_skb);
+	if (next_tx_skb)
+		kfree_skb(next_tx_skb);
+	if (cur_rx_skb)
+		kfree_skb(cur_rx_skb);
+	if (next_rx_skb)
+		kfree_skb(next_rx_skb);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static struct net_device_stats *
+usb_eth_stats(struct net_device *dev)
+{
+	struct usbe_info_t *priv =  (struct usbe_info_t*) dev->priv;
+	struct net_device_stats *stats=NULL;
+
+	if (priv)
+		stats = &priv->stats;
+	return stats;
+}
+
+static int
+usb_eth_probe(struct net_device *dev)
+{
+	u8 node_id [ETH_ALEN];
+
+	get_random_bytes (node_id, sizeof node_id);
+	node_id [0] &= 0xfe;    // clear multicast bit
+
+	/*
+	 * Assign the hardware address of the board:
+	 * generate it randomly, as there can be many such
+	 * devices on the bus.
+	 */
+	memcpy (dev->dev_addr, node_id, sizeof node_id);
+
+	dev->open = usb_eth_open;
+	dev->change_mtu = usb_change_mtu;
+	dev->stop = usb_eth_release;
+	dev->hard_start_xmit = usb_eth_xmit;
+	dev->get_stats = usb_eth_stats;
+	dev->watchdog_timeo = 1*HZ;
+	dev->tx_timeout = usb_xmit_timeout;
+	dev->priv = &usbe_info;
+
+	usbe_info.dev = dev;
+
+	/* clear the statistics */
+	memset(&usbe_info.stats, 0, sizeof(struct net_device_stats));
+
+	ether_setup(dev);
+	dev->flags &= ~IFF_MULTICAST;
+	dev->flags &= ~IFF_BROADCAST;
+	//dev->flags |= IFF_NOARP;
+
+	return 0;
+}
+
+#ifdef MODULE
+MODULE_PARM(usb_rsize, "1i");
+MODULE_PARM_DESC(usb_rsize, "number of bytes in packets from host to sa1100");
+MODULE_PARM(usb_wsize, "1i");
+MODULE_PARM_DESC(usb_wsize, "number of bytes in packets from sa1100 to host");
+#endif
+
+static int __init
+usb_eth_init(void)
+{
+	int rc;
+
+#ifndef DMA_NO_COPY
+	dmabuf = kmalloc( usb_rsize, GFP_KERNEL | GFP_DMA );
+	if (!dmabuf)
+		return -ENOMEM;
+#endif
+	strncpy(usb_eth_device.name, usb_eth_name, IFNAMSIZ);
+	usb_eth_device.init = usb_eth_probe;
+	if (register_netdev(&usb_eth_device) != 0)
+		return -EIO;
+
+	rc = sa1100_usb_open( "usb-eth" );
+	if ( rc == 0 ) {
+		 string_desc_t * pstr;
+		 desc_t * pd = sa1100_usb_get_descriptor_ptr();
+
+		 pd->b.ep1.wMaxPacketSize = make_word( usb_rsize );
+		 pd->b.ep2.wMaxPacketSize = make_word( usb_wsize );
+		 pd->dev.idVendor	  = ETHERNET_VENDOR_ID;
+		 pd->dev.idProduct     = ETHERNET_PRODUCT_ID;
+		 pstr = sa1100_usb_kmalloc_string_descriptor( "SA1100 USB NIC" );
+		 if ( pstr ) {
+			  sa1100_usb_set_string_descriptor( 1, pstr );
+			  pd->dev.iProduct = 1;
+		 }
+		 rc = sa1100_usb_start();
+	}
+	return rc;
+}
+
+module_init(usb_eth_init);
+
+static void __exit
+usb_eth_cleanup(void)
+{
+	string_desc_t * pstr;
+	sa1100_usb_stop();
+	sa1100_usb_close();
+	if ( (pstr = sa1100_usb_get_string_descriptor(1)) != NULL )
+		kfree( pstr );
+#ifndef DMA_NO_COPY
+	kfree(dmabuf);
+#endif
+	unregister_netdev(&usb_eth_device);
+}
+
+module_exit(usb_eth_cleanup);
diff -urN linux-2.4.29/arch/arm/mach-sa1100/usb_recv.c linux-2.4.29-uc1/arch/arm/mach-sa1100/usb_recv.c
--- linux-2.4.29/arch/arm/mach-sa1100/usb_recv.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-sa1100/usb_recv.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,205 @@
+/*
+ * Generic receive layer for the SA1100 USB client function
+ * Copyright (c) 2001 by Nicolas Pitre
+ *
+ * This code was loosely inspired by the original version which was
+ * Copyright (c) Compaq Computer Corporation, 1998-1999
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This is still work in progress...
+ *
+ * Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <asm/dma.h>
+#include <asm/system.h>
+
+#include "sa1100_usb.h"
+#include "usb_ctl.h"
+
+
+static char *ep1_buf;
+static int ep1_len;
+static usb_callback_t ep1_callback;
+static char *ep1_curdmabuf;
+static dma_addr_t ep1_curdmapos;
+static int ep1_curdmalen;
+static int ep1_remain;
+static int dmachn_rx;
+static int rx_pktsize;
+
+static int naking;
+
+static void
+ep1_start(void)
+{
+	sa1100_dma_flush_all(dmachn_rx);
+	if (!ep1_curdmalen) {
+	  	ep1_curdmalen = rx_pktsize;
+		if (ep1_curdmalen > ep1_remain)
+			ep1_curdmalen = ep1_remain;
+		ep1_curdmapos = pci_map_single(NULL, ep1_curdmabuf, ep1_curdmalen,
+					       PCI_DMA_FROMDEVICE);
+	}
+	sa1100_dma_queue_buffer(dmachn_rx, NULL, ep1_curdmapos, ep1_curdmalen);
+	if ( naking ) {
+		/* turn off NAK of OUT packets, if set */
+		UDC_flip( Ser0UDCCS1, UDCCS1_RPC );
+		naking = 0;
+	}
+}
+
+static void
+ep1_done(int flag)
+{
+	int size = ep1_len - ep1_remain;
+
+	if (!ep1_len)
+		return;
+	if (ep1_curdmalen)
+		pci_unmap_single(NULL, ep1_curdmapos, ep1_curdmalen,
+				 PCI_DMA_FROMDEVICE);
+	ep1_len = ep1_curdmalen = 0;
+	if (ep1_callback) {
+		ep1_callback(flag, size);
+	}
+}
+
+void
+ep1_state_change_notify( int new_state )
+{
+
+}
+
+void
+ep1_stall( void )
+{
+	/* SET_FEATURE force stall at UDC */
+	UDC_set( Ser0UDCCS1, UDCCS1_FST );
+}
+
+int
+ep1_init(int chn)
+{
+	desc_t * pd = sa1100_usb_get_descriptor_ptr();
+	rx_pktsize = __le16_to_cpu( pd->b.ep1.wMaxPacketSize );
+	dmachn_rx = chn;
+	sa1100_dma_flush_all(dmachn_rx);
+	ep1_done(-EAGAIN);
+	return 0;
+}
+
+void
+ep1_reset(void)
+{
+	desc_t * pd = sa1100_usb_get_descriptor_ptr();
+	rx_pktsize = __le16_to_cpu( pd->b.ep1.wMaxPacketSize );
+	sa1100_dma_flush_all(dmachn_rx);
+	UDC_clear(Ser0UDCCS1, UDCCS1_FST);
+	ep1_done(-EINTR);
+}
+
+void
+ep1_int_hndlr(int udcsr)
+{
+	dma_addr_t dma_addr;
+	unsigned int len;
+	int status = Ser0UDCCS1;
+
+	if ( naking ) printk( "%sEh? in ISR but naking = %d\n", "usbrx: ", naking );
+
+	if (status & UDCCS1_RPC) {
+
+		if (!ep1_curdmalen) {
+			printk("usb_recv: RPC for non-existent buffer\n");
+			naking=1;
+			return;
+		}
+
+		sa1100_dma_stop(dmachn_rx);
+
+		if (status & UDCCS1_SST) {
+			printk("usb_recv: stall sent OMP=%d\n",Ser0UDCOMP);
+			UDC_flip(Ser0UDCCS1, UDCCS1_SST);
+			ep1_done(-EIO); // UDC aborted current transfer, so we do
+			return;
+		}
+
+		if (status & UDCCS1_RPE) {
+		    printk("usb_recv: RPError %x\n", status);
+			UDC_flip(Ser0UDCCS1, UDCCS1_RPC);
+			ep1_done(-EIO);
+			return;
+		}
+
+		sa1100_dma_get_current(dmachn_rx, NULL, &dma_addr);
+		pci_unmap_single(NULL, ep1_curdmapos, ep1_curdmalen,
+				 PCI_DMA_FROMDEVICE);
+		len = dma_addr - ep1_curdmapos;
+		if (len < ep1_curdmalen) {
+			char *buf = ep1_curdmabuf + len;
+			while (Ser0UDCCS1 & UDCCS1_RNE) {
+				if (len >= ep1_curdmalen) {
+					printk("usb_recv: too much data in fifo\n");
+					break;
+				}
+				*buf++ = Ser0UDCDR;
+				len++;
+			}
+		} else if (Ser0UDCCS1 & UDCCS1_RNE) {
+			printk("usb_recv: fifo screwed, shouldn't contain data\n");
+			len = 0;
+		}
+		ep1_curdmalen = 0;  /* dma unmap already done */
+		ep1_remain -= len;
+		naking = 1;
+		ep1_done((len) ? 0 : -EPIPE);
+	}
+	/* else, you can get here if we are holding NAK */
+}
+
+int
+sa1100_usb_recv(char *buf, int len, usb_callback_t callback)
+{
+	int flags;
+
+	if (ep1_len)
+		return -EBUSY;
+
+	local_irq_save(flags);
+	ep1_buf = buf;
+	ep1_len = len;
+	ep1_callback = callback;
+	ep1_remain = len;
+	ep1_curdmabuf = buf;
+	ep1_curdmalen = 0;
+	ep1_start();
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(sa1100_usb_recv);
+
+void
+sa1100_usb_recv_reset(void)
+{
+	ep1_reset();
+}
+
+EXPORT_SYMBOL(sa1100_usb_recv_reset);
+
+void
+sa1100_usb_recv_stall(void)
+{
+	ep1_stall();
+}
+
+EXPORT_SYMBOL(sa1100_usb_recv_stall);
+
diff -urN linux-2.4.29/arch/arm/mach-sa1100/usb_send.c linux-2.4.29-uc1/arch/arm/mach-sa1100/usb_send.c
--- linux-2.4.29/arch/arm/mach-sa1100/usb_send.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mach-sa1100/usb_send.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,205 @@
+/*
+ * Generic xmit layer for the SA1100 USB client function
+ * Copyright (c) 2001 by Nicolas Pitre
+ *
+ * This code was loosely inspired by the original version which was
+ * Copyright (c) Compaq Computer Corporation, 1998-1999
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This is still work in progress...
+ *
+ * Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
+ * 15/03/2001 - ep2_start now sets UDCAR to overcome something that is hardware
+ * 		bug, I think. green@iXcelerator.com
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/delay.h> // for the massive_attack hack 28Feb01ww
+#include <asm/hardware.h>
+#include <asm/dma.h>
+#include <asm/system.h>
+#include <asm/byteorder.h>
+
+#include "sa1100_usb.h"
+#include "usb_ctl.h"
+
+
+static char *ep2_buf;
+static int ep2_len;
+static usb_callback_t ep2_callback;
+static dma_addr_t ep2_dma;
+static dma_addr_t ep2_curdmapos;
+static int ep2_curdmalen;
+static int ep2_remain;
+static int dmachn_tx;
+static int tx_pktsize;
+
+/* device state is changing, async */
+void
+ep2_state_change_notify( int new_state )
+{
+}
+
+/* set feature stall executing, async */
+void
+ep2_stall( void )
+{
+	UDC_set( Ser0UDCCS2, UDCCS2_FST );  /* force stall at UDC */
+}
+
+static void
+ep2_start(void)
+{
+	if (!ep2_len)
+		return;
+
+	ep2_curdmalen = tx_pktsize;
+	if (ep2_curdmalen > ep2_remain)
+		ep2_curdmalen = ep2_remain;
+
+	/* must do this _before_ queue buffer.. */
+	UDC_flip( Ser0UDCCS2,UDCCS2_TPC );  /* stop NAKing IN tokens */
+	UDC_write( Ser0UDCIMP, ep2_curdmalen-1 );
+
+	/* Remove if never seen...8Mar01ww */
+	{
+		 int massive_attack = 20;
+		 while ( Ser0UDCIMP != ep2_curdmalen-1 && massive_attack-- ) {
+			  printk( "usbsnd: Oh no you don't! Let me spin..." );
+			  udelay( 500 );
+			  printk( "and try again...\n" );
+			  UDC_write( Ser0UDCIMP, ep2_curdmalen-1 );
+		 }
+		 if ( massive_attack != 20 ) {
+			  if ( Ser0UDCIMP != ep2_curdmalen-1 )
+				   printk( "usbsnd: Massive attack FAILED :-( %d\n",
+						   20 - massive_attack );
+			  else
+				   printk( "usbsnd: Massive attack WORKED :-) %d\n",
+						   20 - massive_attack );
+		 }
+	}
+	/* End remove if never seen... 8Mar01ww */
+
+	Ser0UDCAR = usbd_info.address; // fighting stupid silicon bug
+	sa1100_dma_queue_buffer(dmachn_tx, NULL, ep2_curdmapos, ep2_curdmalen);
+}
+
+static void
+ep2_done(int flag)
+{
+	int size = ep2_len - ep2_remain;
+	if (ep2_len) {
+		pci_unmap_single(NULL, ep2_dma, ep2_len, PCI_DMA_TODEVICE);
+		ep2_len = 0;
+		if (ep2_callback)
+			ep2_callback(flag, size);
+	}
+}
+
+int
+ep2_init(int chn)
+{
+	desc_t * pd = sa1100_usb_get_descriptor_ptr();
+	tx_pktsize = __le16_to_cpu( pd->b.ep2.wMaxPacketSize );
+	dmachn_tx = chn;
+	sa1100_dma_flush_all(dmachn_tx);
+	ep2_done(-EAGAIN);
+	return 0;
+}
+
+void
+ep2_reset(void)
+{
+	desc_t * pd = sa1100_usb_get_descriptor_ptr();
+	tx_pktsize = __le16_to_cpu( pd->b.ep2.wMaxPacketSize );
+	UDC_clear(Ser0UDCCS2, UDCCS2_FST);
+	sa1100_dma_flush_all(dmachn_tx);
+	ep2_done(-EINTR);
+}
+
+void
+ep2_int_hndlr(int udcsr)
+{
+	int status = Ser0UDCCS2;
+
+	if (Ser0UDCAR != usbd_info.address) // check for stupid silicon bug.
+		Ser0UDCAR = usbd_info.address;
+
+	UDC_flip(Ser0UDCCS2, UDCCS2_SST);
+
+	if (status & UDCCS2_TPC) {
+		sa1100_dma_flush_all(dmachn_tx);
+
+		if (status & (UDCCS2_TPE | UDCCS2_TUR)) {
+			printk("usb_send: transmit error %x\n", status);
+			ep2_done(-EIO);
+		} else {
+#if 1 // 22Feb01ww/Oleg
+			ep2_curdmapos += ep2_curdmalen;
+			ep2_remain -= ep2_curdmalen;
+#else
+			ep2_curdmapos += Ser0UDCIMP + 1; // this is workaround
+			ep2_remain -= Ser0UDCIMP + 1;    // for case when setting of Ser0UDCIMP was failed
+#endif
+
+			if (ep2_remain != 0) {
+				ep2_start();
+			} else {
+				ep2_done(0);
+			}
+		}
+	} else {
+		printk("usb_send: Not TPC: UDCCS2 = %x\n", status);
+	}
+}
+
+int
+sa1100_usb_send(char *buf, int len, usb_callback_t callback)
+{
+	int flags;
+
+	if (usbd_info.state != USB_STATE_CONFIGURED)
+		return -ENODEV;
+
+	if (ep2_len)
+		return -EBUSY;
+
+	local_irq_save(flags);
+	ep2_buf = buf;
+	ep2_len = len;
+	ep2_dma = pci_map_single(NULL, buf, len, PCI_DMA_TODEVICE);
+	ep2_callback = callback;
+	ep2_remain = len;
+	ep2_curdmapos = ep2_dma;
+	ep2_start();
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+
+void
+sa1100_usb_send_reset(void)
+{
+	ep2_reset();
+}
+
+int sa1100_usb_xmitter_avail( void )
+{
+	if (usbd_info.state != USB_STATE_CONFIGURED)
+		return -ENODEV;
+	if (ep2_len)
+		return -EBUSY;
+	return 0;
+}
+
+
+EXPORT_SYMBOL(sa1100_usb_xmitter_avail);
+EXPORT_SYMBOL(sa1100_usb_send);
+EXPORT_SYMBOL(sa1100_usb_send_reset);
diff -urN linux-2.4.29/arch/arm/Makefile linux-2.4.29-uc1/arch/arm/Makefile
--- linux-2.4.29/arch/arm/Makefile	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/Makefile	2005-06-14 02:10:59.000000000 +0100
@@ -16,19 +16,33 @@
 CFLAGS		:=$(CFLAGS:-fomit-frame-pointer=-mapcs -mno-sched-prolog)
 endif
 
-CFLAGS		:=$(CFLAGS:-O2=-Os)
+CFLAGS		:=$(CFLAGS:-O2=-O)
 
 ifeq ($(CONFIG_DEBUG_INFO),y)
 CFLAGS		+=-g
 endif
 
+ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
+CC		+= -mbig-endian
+AS		+= -EB
+LD		+= -EB
+endif
+
+
+#
+# Determine GCC version for proper compiler options
+#
+GCC_VERSION	:= $(shell $(CROSS_COMPILE)gcc  -v 2>&1 | grep version | cut -f3 -d' ' | cut -f1 -d.)
+
+check_gcc = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
+
 # Select CPU dependent flags.  Note that order of declaration is important;
 # the options further down the list override previous items.
 #
 # Note!  For APCS-26 YOU MUST HAVE AN APCS-26 LIBGCC.A
 #
 apcs-y				:=-mapcs-32
-apcs-$(CONFIG_CPU_26)		:=-mapcs-26 -mcpu=arm3 -Os
+apcs-$(CONFIG_CPU_26)		:=-mapcs-26 -mcpu=arm3 -O
 
 # This selects which instruction set is used.
 # Note that GCC is lame - it doesn't numerically define an
@@ -38,6 +52,13 @@
 arch-$(CONFIG_CPU_32v3)		:=-D__LINUX_ARM_ARCH__=3 -march=armv3
 arch-$(CONFIG_CPU_32v4)		:=-D__LINUX_ARM_ARCH__=4 -march=armv4
 arch-$(CONFIG_CPU_32v5)		:=-D__LINUX_ARM_ARCH__=5 -march=armv5
+ifeq ($(GCC_VERSION),3)
+  # The -march=armv5te doesn't seem to really enable XScale features... Why?
+  #arch-$(CONFIG_CPU_XSCALE)    :=-D__LINUX_ARM_ARCH__=5 -march=armv5te
+  arch-$(CONFIG_CPU_XSCALE)     :=-D__LINUX_ARM_ARCH__=5 -mcpu=xscale
+else
+  arch-$(CONFIG_CPU_XSCALE)     :=-D__LINUX_ARM_ARCH__=5 -march=armv4 -Wa,-mxscale
+endif
 
 # This selects how we optimise for the processor.
 tune-y				:=
@@ -49,10 +70,17 @@
 tune-$(CONFIG_CPU_ARM926T)	:=-mtune=arm9tdmi
 tune-$(CONFIG_CPU_SA110)	:=-mtune=strongarm110
 tune-$(CONFIG_CPU_SA1100)	:=-mtune=strongarm1100
+ifeq ($(GCC_VERSION),3)
+  tune-$(CONFIG_CPU_XSCALE)	:=-mtune=xscale
+else
+  tune-$(CONFIG_CPU_XSCALE)	:=-mtune=strongarm
+endif
 
-CFLAGS_BOOT	:=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm
-CFLAGS		+=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm
-AFLAGS		+=$(apcs-y) $(arch-y) -mno-fpu -msoft-float
+load-y				:= $(call check_gcc,-mshort-load-bytes,-malignment-traps)
+
+CFLAGS_BOOT	:=$(apcs-y) $(arch-y) $(tune-y) $(load-y) -msoft-float -Uarm
+CFLAGS		+=$(apcs-y) $(arch-y) $(tune-y) $(load-y) -msoft-float -Uarm
+AFLAGS		+=$(apcs-y) $(arch-y) -msoft-float
 
 ifeq ($(CONFIG_CPU_26),y)
 PROCESSOR	:= armo
@@ -68,7 +96,7 @@
 
 ifeq ($(CONFIG_CPU_32),y)
 PROCESSOR	 = armv
-TEXTADDR	 = 0xC0008000
+TEXTADDR	 = 0x$(shell echo $(CONFIG_KERNEL_START)|sed -e's/0000$$/8000/'|sed -e's/^0x//')
 LDSCRIPT	 = arch/arm/vmlinux-armv.lds.in
 endif
 
@@ -135,6 +163,10 @@
 MACHINE		 = integrator
 endif
 
+ifeq ($(CONFIG_ARCH_KS8695),y)
+MACHINE		 = ks8695
+endif
+
 ifeq ($(CONFIG_ARCH_AT91RM9200),y)
 MACHINE		 = at91rm9200
 endif
@@ -152,6 +184,35 @@
 MACHINE		 = clps711x
 endif
 
+ifeq ($(CONFIG_ARCH_EDB7312),y)
+TEXTADDR	 = 0xc0038000
+endif
+
+ifeq ($(CONFIG_ARCH_EDB9301),y)
+TEXTADDR	 = 0xc0008000
+MACHINE		 = ep93xx
+endif
+
+ifeq ($(CONFIG_ARCH_EDB9302),y)
+TEXTADDR	 = 0xc0008000
+MACHINE		 = ep93xx
+endif
+
+ifeq ($(CONFIG_ARCH_EDB9312),y)
+TEXTADDR	 = 0xc0008000
+MACHINE		 = ep93xx
+endif
+
+ifeq ($(CONFIG_ARCH_EDB9315),y)
+TEXTADDR	 = 0xc0008000
+MACHINE		 = ep93xx
+endif
+
+ifeq ($(CONFIG_MACH_IPD),y)
+TEXTADDR	 = 0xc0218000
+MACHINE		 = ep93xx
+endif
+
 ifeq ($(CONFIG_ARCH_FORTUNET),y)
 TEXTADDR	 = 0xc0208000
 endif
@@ -164,6 +225,26 @@
 MACHINE                = omaha
 endif
 
+ifeq ($(CONFIG_ARCH_IOP3XX),y)
+MACHINE		= iop3xx
+endif
+
+ifeq ($(CONFIG_ARCH_IXP1200),y)
+MACHINE		= ixp1200
+endif
+
+ifeq ($(CONFIG_ARCH_ADIFCC),y)
+MACHINE		= adifcc
+endif
+
+ifeq ($(CONFIG_ARCH_IXP425),y)
+MACHINE		= ixp425
+endif
+
+ifeq ($(CONFIG_ARCH_IXP2000),y)
+MACHINE		= ixp2000
+endif
+
 export	MACHINE PROCESSOR TEXTADDR GZFLAGS CFLAGS_BOOT OBJCOPYFLAGS
 
 # Only set INCDIR if its not already defined above
@@ -202,12 +283,13 @@
 endif
 endif
 
-ifeq ($(findstring y,$(CONFIG_USB_OHCI_SA1111) $(CONFIG_USB_OHCI_AT91)),y)
+ifeq ($(findstring y,$(CONFIG_USB_OHCI_SA1111) $(CONFIG_USB_OHCI_AT91) $(CONFIG_USB_OHCI_EP93XX)),y)
    SUBDIRS	+=arch/arm/common
    CORE_FILES	+=arch/arm/common/nopci.o
 endif
 
-ifeq ($(findstring y,$(CONFIG_ARCH_CLPS7500) $(CONFIG_ARCH_L7200)),y)
+#ifeq ($(findstring y,$(CONFIG_ARCH_CLPS7500) $(CONFIG_ARCH_L7200)),y)
+ifeq ($(CONFIG_ARCH_L7200),y)
 SUBDIRS		+=drivers/acorn/char
 DRIVERS		+=drivers/acorn/char/acorn-char.o
 endif
@@ -266,10 +348,18 @@
 	@echo '  Generating $@'
 	@sed 's/TEXTADDR/$(TEXTADDR)/;s/DATAADDR/$(DATAADDR)/' $(LDSCRIPT) >$@
 
+#
+# If you want the kernel build to build modules outside of the tree
+# then define this and pass it to the main linux makefile
+#
+ifdef EXTRA_MODULE_DIRS
+SUBDIRS += $(EXTRA_MODULE_DIRS)
+endif
+
 arch/arm/kernel arch/arm/mm arch/arm/lib: dummy
 	$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@)
 
-bzImage zImage zinstall Image bootpImage install: vmlinux
+bzImage zImage zinstall Image bootpImage install zsrec %.swap: vmlinux
 	@$(MAKEBOOT) $@
 
 CLEAN_FILES	+= \
diff -urN linux-2.4.29/arch/arm/mm/alignment.c linux-2.4.29-uc1/arch/arm/mm/alignment.c
--- linux-2.4.29/arch/arm/mm/alignment.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/alignment.c	2005-06-14 02:10:59.000000000 +0100
@@ -11,7 +11,6 @@
 #include <linux/config.h>
 #include <linux/compiler.h>
 #include <linux/signal.h>
-#include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
@@ -19,7 +18,6 @@
 #include <linux/ptrace.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
-#include <linux/interrupt.h>
 #include <linux/proc_fs.h>
 #include <linux/bitops.h>
 #include <linux/init.h>
@@ -30,9 +28,7 @@
 #include <asm/pgtable.h>
 #include <asm/unaligned.h>
 
-extern void
-do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr,
-	    int error_code, struct pt_regs *regs);
+#include "fault.h"
 
 /*
  * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998
@@ -130,31 +126,6 @@
 	return count;
 }
 
-/*
- * This needs to be done after sysctl_init, otherwise sys/ will be
- * overwritten.  Actually, this shouldn't be in sys/ at all since
- * it isn't a sysctl, and it doesn't contain sysctl information.
- * We now locate it in /proc/cpu/alignment instead.
- */
-static int __init alignment_init(void)
-{
-	struct proc_dir_entry *res;
-
-	res = proc_mkdir("cpu", NULL);
-	if (!res)
-		return -ENOMEM;
-
-	res = create_proc_entry("alignment", S_IWUSR | S_IRUGO, res);
-	if (!res)
-		return -ENOMEM;
-
-	res->read_proc = proc_alignment_read;
-	res->write_proc = proc_alignment_write;
-
-	return 0;
-}
-
-__initcall(alignment_init);
 #endif /* CONFIG_PROC_FS */
 
 union offset_union {
@@ -167,6 +138,18 @@
 #define TYPE_LDST	2
 #define TYPE_DONE	3
 
+#ifdef __ARMEB__
+#define	BE		1
+#define FIRST_BYTE_16	"mov	%1, %1, ror #8\n"
+#define FIRST_BYTE_32	"mov	%1, %1, ror #24\n"
+#define NEXT_BYTE	"ror #24"
+#else
+#define BE		0
+#define FIRST_BYTE_16
+#define FIRST_BYTE_32
+#define NEXT_BYTE	"lsr #8"
+#endif
+
 #define __get8_unaligned_check(ins,val,addr,err)	\
 	__asm__(					\
 	"1:	"ins"	%1, [%2], #1\n"			\
@@ -186,9 +169,10 @@
 #define __get16_unaligned_check(ins,val,addr)			\
 	do {							\
 		unsigned int err = 0, v, a = addr;		\
-		__get8_unaligned_check(ins,val,a,err);		\
 		__get8_unaligned_check(ins,v,a,err);		\
-		val |= v << 8;					\
+		val =  v << ((BE) ? 8 : 0);			\
+		__get8_unaligned_check(ins,v,a,err);		\
+		val |= v << ((BE) ? 0 : 8);			\
 		if (err)					\
 			goto fault;				\
 	} while (0)
@@ -202,13 +186,14 @@
 #define __get32_unaligned_check(ins,val,addr)			\
 	do {							\
 		unsigned int err = 0, v, a = addr;		\
-		__get8_unaligned_check(ins,val,a,err);		\
 		__get8_unaligned_check(ins,v,a,err);		\
-		val |= v << 8;					\
+		val =  v << ((BE) ? 24 :  0);			\
 		__get8_unaligned_check(ins,v,a,err);		\
-		val |= v << 16;					\
+		val |= v << ((BE) ? 16 :  8);			\
 		__get8_unaligned_check(ins,v,a,err);		\
-		val |= v << 24;					\
+		val |= v << ((BE) ?  8 : 16);			\
+		__get8_unaligned_check(ins,v,a,err);		\
+		val |= v << ((BE) ?  0 : 24);			\
 		if (err)					\
 			goto fault;				\
 	} while (0)
@@ -222,9 +207,9 @@
 #define __put16_unaligned_check(ins,val,addr)			\
 	do {							\
 		unsigned int err = 0, v = val, a = addr;	\
-		__asm__(					\
+		__asm__( FIRST_BYTE_16				\
 		"1:	"ins"	%1, [%2], #1\n"			\
-		"	mov	%1, %1, lsr #8\n"		\
+		"	mov	%1, %1, "NEXT_BYTE"\n"		\
 		"2:	"ins"	%1, [%2]\n"			\
 		"3:\n"						\
 		"	.section .fixup,\"ax\"\n"		\
@@ -252,13 +237,13 @@
 #define __put32_unaligned_check(ins,val,addr)			\
 	do {							\
 		unsigned int err = 0, v = val, a = addr;	\
-		__asm__(					\
+		__asm__( FIRST_BYTE_32				\
 		"1:	"ins"	%1, [%2], #1\n"			\
-		"	mov	%1, %1, lsr #8\n"		\
+		"	mov	%1, %1, "NEXT_BYTE"\n"		\
 		"2:	"ins"	%1, [%2], #1\n"			\
-		"	mov	%1, %1, lsr #8\n"		\
+		"	mov	%1, %1, "NEXT_BYTE"\n"		\
 		"3:	"ins"	%1, [%2], #1\n"			\
-		"	mov	%1, %1, lsr #8\n"		\
+		"	mov	%1, %1, "NEXT_BYTE"\n"		\
 		"4:	"ins"	%1, [%2]\n"			\
 		"5:\n"						\
 		"	.section .fixup,\"ax\"\n"		\
@@ -429,7 +414,7 @@
 	 * For alignment faults on the ARM922T/ARM920T the MMU  makes
 	 * the FSR (and hence addr) equal to the updated base address
 	 * of the multiple access rather than the restored value.
-	 * Switch this messsage off if we've got a ARM92[02], otherwise
+	 * Switch this message off if we've got a ARM92[02], otherwise
 	 * [ls]dm alignment faults are noisy!
 	 */
 #if !(defined CONFIG_CPU_ARM922T)  && !(defined CONFIG_CPU_ARM920T)
@@ -486,7 +471,10 @@
 	return TYPE_ERROR;
 }
 
-int do_alignment(unsigned long addr, int error_code, struct pt_regs *regs)
+static int handle_unaligned_notify_count = 10;
+
+static int
+do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
 	union offset_union offset;
 	unsigned long instr, instrptr;
@@ -541,7 +529,7 @@
 			case SHIFT_RORRRX:
 				if (shiftval == 0) {
 					offset.un >>= 1;
-					if (regs->ARM_cpsr & CC_C_BIT)
+					if (regs->ARM_cpsr & PSR_C_BIT)
 						offset.un |= 1 << 31;
 				} else
 					offset.un = offset.un >> shiftval |
@@ -577,7 +565,7 @@
 	/*
 	 * We got a fault - fix it up, or die.
 	 */
-	do_bad_area(current, current->mm, addr, error_code, regs);
+	do_bad_area(current, current->mm, addr, fsr, regs);
 	return 0;
 
  bad:
@@ -592,10 +580,13 @@
  user:
 	ai_user += 1;
 
-	if (ai_usermode & 1)
+	/* shout about the first ten userspace fixups */
+	if ((ai_usermode & 1) && handle_unaligned_notify_count > 0) { 
+		handle_unaligned_notify_count--;
 		printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%08lx "
-		       "Address=0x%08lx Code 0x%02x\n", current->comm,
-			current->pid, instrptr, instr, addr, error_code);
+		       "Address=0x%08lx FSR 0x%03x\n", current->comm,
+			current->pid, instrptr, instr, addr, fsr);
+	}
 
 	if (ai_usermode & 2)
 		goto fixup;
@@ -607,3 +598,34 @@
 
 	return 0;
 }
+
+/*
+ * This needs to be done after sysctl_init, otherwise sys/ will be
+ * overwritten.  Actually, this shouldn't be in sys/ at all since
+ * it isn't a sysctl, and it doesn't contain sysctl information.
+ * We now locate it in /proc/cpu/alignment instead.
+ */
+static int __init alignment_init(void)
+{
+#ifdef CONFIG_PROC_FS
+	struct proc_dir_entry *res;
+
+	res = proc_mkdir("cpu", NULL);
+	if (!res)
+		return -ENOMEM;
+
+	res = create_proc_entry("alignment", S_IWUSR | S_IRUGO, res);
+	if (!res)
+		return -ENOMEM;
+
+	res->read_proc = proc_alignment_read;
+	res->write_proc = proc_alignment_write;
+#endif
+
+	hook_fault_code(1, do_alignment, SIGILL, "alignment exception");
+	hook_fault_code(3, do_alignment, SIGILL, "alignment exception");
+
+	return 0;
+}
+
+__initcall(alignment_init);
diff -urN linux-2.4.29/arch/arm/mm/consistent.c linux-2.4.29-uc1/arch/arm/mm/consistent.c
--- linux-2.4.29/arch/arm/mm/consistent.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/consistent.c	2005-06-14 02:10:59.000000000 +0100
@@ -103,8 +103,11 @@
 #if defined(CONFIG_PCI) || defined(CONFIG_SA1111)
 	if ((hwdev) == NULL || dev_is_sa1111(hwdev) ||
 	    (hwdev)->dma_mask != 0xffffffff)
-#endif
 		gfp |= GFP_DMA;
+#endif
+#ifdef CONFIG_ARCH_IXP425
+	gfp |= GFP_DMA;
+#endif
 
 	return consistent_alloc(gfp, size, handle);
 }
diff -urN linux-2.4.29/arch/arm/mm/cpd.c linux-2.4.29-uc1/arch/arm/mm/cpd.c
--- linux-2.4.29/arch/arm/mm/cpd.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/cpd.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,1070 @@
+/*
+* Filename:    arch/arm/mm/cpd.c
+* Description: Caching Page Directory (CPD) functions for Fast Address Space
+*              Switching (FASS) in ARM Linux.
+*
+* Created:     20/06/2001
+* Changes:     14/10/2001 - Added code to deal with ARM PID reloation in
+*              cpd_load() and the cpd_*_flush_(page/range)() code.
+*              19/02/2002 - Modified arch_get_unmapped_area() to be more
+*              intelligent and added support functions to bring this about.
+*              22/02/2002 - Modifed domain manipulation to add cpd_stats house
+*              keeping information. cpd_deallocate_domain() moved to list
+*              traversal of CPD.
+*              19/03/2002 - Start of modifications to support shared domains.
+*              25/04/2002 - Changed cpd_allocate_domain() to simply use a
+*              round-robin algorithm on the third pass, ie no clean domains.
+*              This improved performance during domain thrashing to better then*
+*              normal linux.
+*              26/04/2002 - Change per address-space domain disabling, via the
+*              DACR, to be lazy rather then diabling all domains on a context
+*              switch. Now all domains only diabled if a cache/tlb clean event
+*              occured since the address-space last ran or if a domain was
+*              deallocated.
+*              28/04/2002 - Replaced round-robin domain recycling algorithm
+*              with a clock algorithm.
+* Copyright:   (C) 2001, 2002 Adam Wiggins <awiggins@cse.unsw.edu.au>
+*		(C) 2004 National ICT Australia and UNSW
+*******************************************************************************
+*
+* Notes:
+*   - Cache/TLB flushes don't do anything if no domain is allocated since no
+*     user memory can be touched without a domain, similarly if the allocated
+*     domain is marked as clean.
+*
+*******************************************************************************
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public Licence version 2 as
+* published by the Free Software Foundation.
+*
+*/
+
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <asm/proc/cpd.h>
+#include <asm/proc/pid.h>
+#include <asm/proc/cache.h>
+#include <asm/proc/pgtable.h>
+
+
+/* Used to lazily update address-space DACRs */
+static unsigned long long domain_clock;
+
+/* The next domain to be allocated in when domain thrashing */
+static int next_domain = DOMAIN_START;
+
+/* The next 1MB region for mmap()s. Hack for now */
+static int next_unmapped = PAGE_ALIGN(CPD_UNMAPPED_BASE);
+
+/* Domain TLB/Cache dirty bits, Cleared when coherent */
+unsigned long domain_tlb_coherence = DIRTY;
+unsigned long domain_dcache_coherence = DIRTY;
+unsigned long domain_icache_coherence = DIRTY;
+
+EXPORT_SYMBOL(domain_tlb_coherence);
+EXPORT_SYMBOL(domain_dcache_coherence);
+EXPORT_SYMBOL(domain_icache_coherence);
+
+unsigned long domain_touched = DIRTY; /* Used by domain recycling clock algo */
+
+/* Array of domain_structs for ARM's 16 domains */
+static struct domain_struct domains[DOMAIN_MAX] = {
+	{.number = 0},
+	{.number = 1},
+	{.number = 2},
+	{.number = 3},
+	{.number = 4},
+	{.number = 5},
+	{.number = 6},
+	{.number = 7},
+	{.number = 8},
+	{.number = 9},
+	{.number = 10},
+	{.number = 11},
+	{.number = 12},
+	{.number = 13},
+	{.number = 14},
+	{.number = 15}
+};
+
+/* Statistics on CPD entries */
+struct cpd_struct cpd_stats[USER_PTRS_PER_PGD];
+
+
+/* cpd_switch_mm: This function switches address-space contexts.
+ *
+ * Notes:
+ *   - At the moment all domains are disabled on a context switch and reenabled
+ *     via the domain faults. This might need to be changed as the cost is
+ *     noticable, if small. The problem with simply setting it to enable only
+ *     dirty domains means we don't test if a domain has been deallocated,
+ *     reallocated and touched. It either needs to be tested here or revoked
+ *     from all address spaces at deallocation time. Need to think about it a
+ *     little more.
+ */
+void
+cpd_switch_mm(struct mm_struct* mm_p)
+{
+
+#if LAZY_DISABLE
+
+	if (mm_p->context.domain_timestamp != domain_clock) {
+		//printk("** cpd_switch: tlb 0x%x icache 0x%x dcache 0x%x dacr 0x%x**\n",
+		//	   domain_tlb_coherence, domain_icache_coherence, domain_dcache_coherence,
+		//	   get_dacr());
+      
+
+		/* Disable 'mm_p's domains that are clean or recycled */
+		mm_p->context.dacr = 0; /* disables all domains */
+		mm_p->context.domain_timestamp = domain_clock;
+	}
+
+#else
+
+	/* Disable 'mm_p's domains that are clean or recycled */
+	mm_p->context.dacr = 0; /* disables all domains */
+
+#endif
+
+#if CLOCK_RECYCLE
+	domain_touched |= mm_p->context.dacr;
+#endif
+
+}
+
+/* cpd_load: This function loads a Page Directory Entry 'pmd' from the 'current'
+ *   process into the CPD. It simply takes 'pmd' and tags it with the domain
+ *   allocated to the region it is associated with. The result is then loaded
+ *   into the required CPD entry. The function updates the cpd_count of the
+ *   domain and does a coherence check if the CPD entry is being replaced, 
+ *   i.e., it was previously allocated to another region.
+ *
+ * Notes:
+ *   - mv_addr is the ARM PID relocated Modifed Virtual Address (MVA) seen by
+ *     the FASS part of the kernel. Since the CPD is the only pg_dir walked by
+ *     the hardware it is the only pg_dir that needs to do ARM PID relocation.
+ */
+void
+cpd_load(pmd_t pmd, unsigned long mv_addr)
+{
+	struct domain_struct* domain_p =
+		cpd_get_domain(current->mm, mva_to_va(mv_addr, current->mm));
+	pmd_t* cpd_p = pmd_offset(pgd_offset_k(mv_addr), mv_addr);
+	unsigned int index = CPD_P_TO_INDEX(cpd_p);
+	int old_domain = pmd_domain(*cpd_p);
+
+#if 0
+	printk("** cpd_load: i %d old %d new %d , v_addr %lx, mv_addr %lx**\n", index, old_domain,
+	       domain_p->number, mva_to_va(mv_addr, current->mm), mv_addr);
+#endif
+	if (old_domain) { /* CPD entry being replaced, TLB/Cache coherence needed */
+		if (old_domain == domain_p->number)
+		{
+			printk("Arrgh.  cpd_load called from %p\b", __builtin_return_address(0));
+			printk("        pmd_count = %d, pmd_val(pmd)= 0x%lx\n",
+			       domain_p->cpd_count,
+			       pmd_val(pmd));
+		}
+		fassert(old_domain != domain_p->number);
+    
+		/* update cpd_stats[] */
+		cpd_stats[index].collisions++;
+		cpd_stats_del(old_domain, cpd_stats + index);
+    
+		/* update domains[] */
+		domains[old_domain].cpd_count--;    
+
+		if (!cpd_is_domain_cache_coherent(old_domain)) {
+      			cpd_cache_clean();
+		} /* The cache clean is not required for ARM9, see cpd.h Notes */
+    
+		//if (!cpd_is_domain_tlb_coherent(old_domain)) {
+		// This should be made into a targeted TLB flush.
+		cpd_tlb_clean();
+		//}
+	}
+
+	/* Update domains[] */
+  
+	domain_p->cpd_count++;
+	cpd_stats_add(domain_p, cpd_stats + index);
+
+	/* Update CPD */
+	pmd_val(pmd) |= PMD_DOMAIN(domain_p->number); /* Tag CPD entry */
+	cpu_set_pmd(cpd_p, pmd);
+}
+
+/*
+ * cpd_allocate_region: ?
+ */
+struct region_struct*
+cpd_allocate_region(void)
+{
+	struct region_struct* region_p = kmalloc(sizeof(struct region_struct),
+						 GFP_KERNEL); /* Is this correct? */
+	if (region_p) {
+		region_p->mm_count = 1;
+		region_p->domain_p = NULL;
+		region_p->next = NULL;
+	}
+
+	return region_p;
+
+}
+
+/* cpd_deallocate_region: Frees a region.
+ *
+ * Notes:
+ *   - Using the non-lazy cache/tlb flushing because the lazy versions crash
+ *     the kernel, have to come back and have a look at this later.
+ */
+void
+cpd_deallocate_region(struct region_struct* region_p)
+{
+	struct domain_struct* domain_p = region_p->domain_p;
+
+	/* Free domain if we have one */
+	if (domain_p) {
+ 
+		/* Make domain coherent */
+		if (!cpd_is_domain_cache_coherent(domain_p->number)) {
+			cpu_cache_clean_invalidate_all(); /* avoiding lazy flush, see below */
+		}
+    
+		if (!cpd_is_domain_tlb_coherent(domain_p->number)) {
+			cpu_tlb_invalidate_all(); /* avoiding lazy flush because it crashes */
+		}
+
+		/* Deallocate domain */
+		cpd_deallocate_domain(domain_p);
+	}
+
+	kfree(region_p);
+}
+
+/*
+ * cpd_get_region: This function retrieves the region allocated to the
+ *   address-space at v_addr.
+ */
+struct region_struct*
+cpd_get_region(struct mm_struct* mm_p, unsigned int v_addr)
+{
+	struct vm_area_struct* vma_p = find_vma(mm_p, v_addr);
+
+	if (vma_p && (v_addr >= vma_p->vm_start) && vma_p->vm_sharing_data)
+		return vma_p->vm_sharing_data;
+		
+	return mm_p->context.region_p;
+}
+
+/*
+ * cpd_get_active_domain: This function simply returns the domain number
+ *   allocated to 'mm_p' in the region covered by 'v_addr'. If no domain is
+ *   allocated 0 is returned. 'v_addr' == NULL requests the private domain of
+ *   'mm_p'.
+ *
+ * Notes: 
+ *   * Currently just returns the private domain, needs fixing.
+ */
+int
+cpd_get_active_domain(struct mm_struct* mm_p, unsigned int v_addr)
+{
+	struct region_struct* region_p;
+
+	if (mm_p) {
+		region_p = cpd_get_region(mm_p, v_addr);
+
+		return region_p->domain_p ? region_p->domain_p->number : 0;
+	}
+		
+	return 0;
+}
+
+/*
+ * cpd_get_domain: This function retrieves the domain currently
+ * allocated to the given region. If there is none, then one is
+ * allocated, possibly preempted from another region.
+ *
+ * Notes: 
+ *   * Currently just returns the private domain, needs fixing.
+ */
+struct domain_struct*
+cpd_get_domain(struct mm_struct* mm_p, unsigned int v_addr)
+{
+	struct region_struct* region_p = cpd_get_region(mm_p, v_addr);
+
+	return region_p->domain_p ? region_p->domain_p :
+		cpd_allocate_domain(region_p);
+
+}
+
+/*
+ * cpd_allocate_domain: This function finds a free domain or preempts a used
+ *   one. A victim domain is selected with the following criteria:
+ *   - The first deallocated domain is used. OR
+ *   - The domain with the least CPD entries, which doesn't require a cache/TLB
+ *     flush. OR
+ *   - The domain with the least CPD entries.
+ * Notes:
+ *   - A policy of replacing the domain with the least CPD entries might not be
+ *     the best. A round robbin or other policy may be more appropriate. This
+ *     needs further thought and investigation.
+ */
+struct domain_struct*
+cpd_allocate_domain(struct region_struct* region_p)
+{
+	int i;
+	int new_domain;
+	struct domain_struct* domain_p;
+
+	/* First pass to find an deallocated domain */
+	for (i = DOMAIN_START; i <= DOMAIN_END; i++) {
+		if (!domains[i].region_p) {
+			domain_p = domains + i;
+			goto allocate;
+		}
+	}
+
+#if CLOCK_RECYCLE
+	/* First run of the clock domain_usage might not equal zero */
+clock:
+	/* Second pass to find a clean domain with the least entries in the CPD */
+	for (i = DOMAIN_START; i <= DOMAIN_END; i++) {
+		new_domain = next_domain;
+		(next_domain == DOMAIN_END) ? (next_domain = DOMAIN_START) : next_domain++;
+
+		if (cpd_is_domain_coherent(next_domain) &&
+		    !cpd_domain_touched(next_domain)) {
+			domain_p = domains + next_domain;
+
+			goto deallocate;
+		}
+	}
+
+	/* Third pass to find a domain using clock scheme */
+	for (i = DOMAIN_START; i <= DOMAIN_END; i++) {
+		new_domain = next_domain;
+		(next_domain == DOMAIN_END) ? (next_domain = DOMAIN_START) : next_domain++;
+
+		if (!cpd_domain_touched(next_domain)) {
+			domain_p = domains + next_domain;
+
+			goto flush;
+		}
+
+		cpd_clear_domain_touched(next_domain);
+	}
+
+	/* Now, domain_usage == 0 */
+	goto clock;
+
+	/* Deallocated domain needs to be made coherent */
+flush:
+ 
+	/* 
+	 *The old third pass leads to very poor behaviour in the case
+	 * that domains are thrashing, ie about 3-4 times the number
+	 * of domains in processes are heavily thrashing.
+	 */
+	/* Third pass to find a domain with the fewest entries in the CPD */
+	//for(i = new_domain = DOMAIN_START; i <= DOMAIN_END; i++) {
+	//  if(domains[i].cpd_count < domains[new_domain].cpd_count) {
+	//    new_domain = i;
+	//  }
+	//}
+
+#else /* Round-robin recycling algorithm */
+
+	/* Second pass to find a clean domain with the least entries in the CPD */
+	for (i = new_domain = DOMAIN_START; i <= DOMAIN_END; i++) {
+		if (cpd_is_domain_coherent(i) &&
+		    ((domains[i].cpd_count * domains[i].region_p->mm_count) <
+		     (domains[new_domain].cpd_count * domains[i].region_p->mm_count))) {
+
+			domain_p = domains + i;
+
+			goto deallocate;
+		}
+	}
+
+	/* Third pass to find a domain in round-robin scheme when thrashing. */ 
+  
+	new_domain = next_domain;
+	(next_domain == DOMAIN_END) ? next_domain = DOMAIN_START : next_domain++;
+
+#endif
+	domain_p = domains + new_domain;
+	/* Domain has entries in CPD, clean caches and TLB */
+	if (!cpd_is_domain_cache_coherent(new_domain)) {
+		cpd_cache_clean();
+	}
+
+	if (!cpd_is_domain_tlb_coherent(new_domain)) {
+		cpd_tlb_clean();
+	}
+
+deallocate:
+	cpd_deallocate_domain(domain_p);
+  
+allocate:
+
+	domain_p->region_p = region_p;
+	region_p->domain_p = domain_p;
+
+	//printk("** cpd_allocate_domain: %d **\n", domain_p->number);
+
+	return domain_p;
+}
+
+/* cpd_deallocate_domain: Insures all CPD entries owned by 'domain_p' are
+ *   removed from CPD and the domain is deallocated.
+ * Assumptions:
+ *   - domain_p != NULL.
+ *   - domain_p->region_p != NULL;
+ *   - TLBs coherent, ie no TLB entries tagged with this domain.
+ * Notes:
+ *   - Should domain and region pointer updates be atomic?
+ */
+void
+cpd_deallocate_domain(struct domain_struct* domain_p)
+{
+	int i;
+	pmd_t* cpd_p = pmd_offset(pgd_offset_k(0), 0); /* Get CPD Address */
+	struct cpd_struct* cpd_stat_p;
+
+	//printk("** cpd_deallocate_domain: %d **\n", domain_p->number);
+
+	/* Loop through CPD entries used by this domain */
+	for (cpd_stat_p = domain_p->cpd_head; cpd_stat_p != NULL;
+	     cpd_stat_p = cpd_stat_p->cpd_next) {
+
+		i = STATS_P_TO_INDEX(cpd_stat_p);
+
+		/* Update CPD */
+		cpu_set_pmd(cpd_p + i, __pmd(0));
+
+		/* Update domain_p */
+		domain_p->cpd_count--;
+	}
+
+	/* Remove deallocate domain from address-space context */
+
+	domain_p->cpd_head = NULL;
+	domain_p->region_p->domain_p = NULL;
+	domain_p->region_p = NULL;
+
+#if LAZY_DISABLE
+	/* Update the domain clock since we deallocated a domain */
+	domain_clock++;
+#endif
+
+	//dump_cpd(1);
+
+	set_dacr(current->thread.dacr);
+     
+}
+
+void
+arch_remove_shared_vm_struct(struct vm_area_struct* vma_p)
+{
+	struct region_struct* region_p;
+
+	/* If we have a region assigned update the count */
+	region_p = (struct region_struct*)vma_p->vm_sharing_data;
+	if (region_p == NULL)
+		return;
+
+	/* Free the shared region if this is the last user */
+	if (0 == --(region_p->mm_count)) {
+		cpd_deallocate_region(region_p);
+	}
+
+}
+
+/* arch_get_unmapped_area: To minimise conflicts in the CPD, hence minimise
+ *   cache/TLB flushes. Mappings are split into two categories and the relevant
+ *   handler is called to allocate an address:
+ *   - Shared mappings.
+ *   - Private mappings.
+ */
+unsigned long
+arch_get_unmapped_area(struct file *file_p, unsigned long addr,
+		       unsigned long len, unsigned long pgoff,
+		       unsigned long flags)
+{
+	if (len > (TASK_SIZE - CPD_UNMAPPED_BASE))
+		return -ENOMEM;
+
+	/*
+	 * If the caller passed in a hint, try to give it what it 
+	 * asked for
+	 */
+	if (addr) {
+		struct vm_area_struct *vma;
+
+		addr = PAGE_ALIGN(addr);
+		vma = find_vma(current->mm, addr);
+		if (TASK_SIZE - len >= addr &&
+		    (!vma || addr + len <= vma->vm_start)) {
+			return addr;
+		}
+	}
+
+	if (flags & MAP_SHARED) {
+		return cpd_get_shared_area(file_p, addr, len, pgoff, flags);
+	}
+	return cpd_get_private_area(file_p, addr, len, pgoff, flags);
+}
+
+/*
+ * cpd_next_area: Allocates a starting point to search from.
+ * Notes:
+ *  - Currently ignores the addr argument, might remove.
+ */
+static inline unsigned long
+cpd_next_area(unsigned long given_addr)
+{
+	unsigned long addr = next_unmapped;
+
+	next_unmapped = (next_unmapped >= (TASK_SIZE - MEGABYTE(1)) ?
+			 PAGE_ALIGN(CPD_UNMAPPED_BASE) : next_unmapped + MEGABYTE(1));
+
+	return addr;
+}
+
+/* cpd_get_shared_area: This function tries to allocate the shared mapping to
+ *   the same address it is allocated to in other address spaces. If it cannot
+ *   or this is the first instance of the shared mapping it will allocate a new
+ *   unique area.
+ * Notes:
+ *   - Not sure if we need to check file_p. Can we have shared mappings without
+ *     a file linking them?
+ *   - If shared domains are used this will promote the situation where the
+ *     shared mappings are at the same memory location which is what we want to
+ *     avoid aliases.
+ *   - This will lead to incorrect behaviour as really to be truely sharing
+ *     the length of the new and existing mappings have to be the same and the
+ *     perms have to be the same otherwise one of the address-spaces gets to see
+ *     more or get to do more with it. This is limited by max len/permissions of
+ *     the set of address-spaces sharing the mapping at this VA.
+ */
+unsigned long
+cpd_get_shared_area(struct file *file_p, unsigned long addr, unsigned long len,
+		    unsigned long pgoff, unsigned long flags)
+{
+	struct vm_area_struct* vma_priv_p; /* VMA in current address-space */
+	struct vm_area_struct* vma_shrd_p; /* VMA of address-space sharing mapping */
+
+	if (file_p) {
+		for (vma_shrd_p = file_p->f_dentry->d_inode->i_mapping->i_mmap_shared;
+		     vma_shrd_p; vma_shrd_p = vma_shrd_p->vm_next_share) {
+			/* Check we are looking at the 'same' part of the file */
+			if (vma_shrd_p->vm_pgoff == pgoff) {
+				addr = vma_shrd_p->vm_start;
+				vma_priv_p = find_vma(current->mm, addr);
+
+				/* Will it fit in current address space? */
+				if (!vma_priv_p || ((addr + len) <= vma_priv_p->vm_start)) {
+					/* It does so use the same virtual address */
+					return addr;
+				}
+			}
+		}
+
+		/* This is the first mapping for the file so allocate a unique area */
+		return cpd_get_unique_area(file_p, addr, len, pgoff, flags);
+	}
+
+	/* Can't share so simply map private */
+	return cpd_get_private_area(file_p, addr, len, pgoff, flags);
+
+}
+
+/*
+ *  cpd_get_unique_area: This function allocates a unique 1MB region for the
+ *			 allocation in the processes address space. It tries 
+ *			 to allocate a region which will not lead to CPD 
+ *			 conflicts.
+ * Notes:
+ *   - Currently it simply cycles through 1MB regions between CPD_UNMAPPED_BASE
+ *     and TASK_SIZE. This should be made smarter to take into account the
+ *     following:
+ *     * The contention of the 1MB region. A 1MB region already allocated to
+ *       another task is probably a bad idea since it will lead to CPD
+ *       conflicts.
+ */
+unsigned long
+cpd_get_unique_area(struct file *file_p, unsigned long addr, unsigned long len,
+		    unsigned long pgoff, unsigned long flags)
+{
+	char wrap = 0;
+	char dense = 0;
+	unsigned long start = cpd_next_area(addr);
+	struct vm_area_struct *vma_p;
+  
+	addr = start;
+
+	for (vma_p = find_vma(current->mm, addr);;
+	     addr = vma_p->vm_end, vma_p = vma_p->vm_next) {
+		/* At this point:  (!vma || addr < vma->vm_end). */
+		if ((TASK_SIZE - len) < addr) { /* Wrap around */
+			addr = PAGE_ALIGN(CPD_UNMAPPED_BASE);
+			wrap = 1;
+		}
+    
+		if (wrap && ((start - len) < addr)) {
+			if(dense) { /* Mapping doesn't fit */
+				return -ENOMEM;
+			}
+      
+			wrap = 0;
+			dense = 1; /* Start 2nd run, buddy up in 1MB slots already being used */
+		}
+
+		if (!dense && vma_p &&
+		    (MASK_MEGABYTE(addr, 1) == MASK_MEGABYTE(vma_p->vm_start, 1))) {
+			continue; /* First run try keep mapping in a unique 1MB slot */
+		}
+
+		if (!vma_p || addr + len <= vma_p->vm_start) {
+			return addr;
+		}
+	}
+}
+
+/* cpd_get_private_area: This function attempts to allocate an address inside
+ *   the process 32MB relocated area of its address space. If no suitable
+ *   region is found cpd_get_alloced_area() is called.
+ *
+ * Notes:
+ *   - vma_p will never be NULL as a 4KB dummy VMA is mapped at 31MB.
+ *   - vma__prev_p will never be NULL as the brk vm_area is there or the loop
+ *     invarient has failed.
+ */
+unsigned long
+cpd_get_private_area(struct file *file_p, unsigned long addr, unsigned long len,
+		     unsigned long pgoff, unsigned long flags)
+{
+	unsigned int start, end;
+	struct vm_area_struct* vma_p;
+	struct vm_area_struct* vma_prev_p;
+
+	if (len < ARMPID_BRK_LIMIT) {
+		/* Loop till we hit brk */
+		for (start = end = ARMPID_BRK_LIMIT; 
+		     start >= PAGE_SIZE && len < end;
+		     end = vma_prev_p->vm_start) {
+      
+			start = end - len;
+			vma_p = find_vma_prev(current->mm, end, &vma_prev_p);
+      
+			if (start >= vma_prev_p->vm_end) {
+				return start;
+			}
+
+			if (!vma_prev_p) {
+				break;
+			}
+		}
+	}
+	return cpd_get_alloced_area(file_p, addr, len, pgoff, flags);
+}
+
+/* cpd_get_alloced_area: This function attempts to allocate a 1MB region already
+ *   in use by the process that the new mapping fits into. If no suitable
+ *   region is found a unique one is allocated.
+ */
+unsigned long
+cpd_get_alloced_area(struct file *file_p, unsigned long addr, unsigned long len,
+		     unsigned long pgoff, unsigned long flags)
+{
+	unsigned long slot; /* 1MB slot being checked */
+	struct vm_area_struct* vma_p;
+
+	if (len <= MEGABYTE(1)) { /* Allocations of 1MB or more get a unique area */
+		addr = CPD_UNMAPPED_BASE;
+
+		/* For each vm_area see if we can buddy up */
+		for (vma_p = find_vma(current->mm, addr); vma_p;
+		     addr = vma_p->vm_end, vma_p = vma_p->vm_next) {
+			slot = MASK_MEGABYTE(vma_p->vm_start, 1); /* vm_area's 1MB start slot */
+			if (addr < slot) { /* Seek to 1MB's slots start if not already in it */
+				addr = slot;
+			}
+      
+			/* Try to allocate in the 1MB the vm_area starts in */
+			if ((addr + len) <= vma_p->vm_start) { /* Fits */
+				return addr;
+			}
+		}
+	}
+
+	return cpd_get_unique_area(file_p, addr, len, pgoff, flags);
+
+}
+     
+/* cpd_set_pmd: Insures coherence of CPD with user pmd modifications.
+ * Assumptions:
+ *   - CPD contains kernel mappings which are always coherent.
+ *   - User changes are coherent if the old entry is not in the CPD.
+ *   - The pmd being set belongs to 'current->mm'. I haven't verified this
+ *     though. Please let me know if this assumption is (in)correct.
+ * Action:
+ *   - If the CPD entry coresponding to 'pmd_p' is tagged with the same domain 
+ *     as 'pmd_p's region then update it. If current->mm doesn't exist the CPD
+ *     is uneffected.
+ * Notes:
+ *   - This function is a bit of a mess, could do with a clean up.
+ *   - The TLBs/Caches are flushed here because the CPD entry is zero'd.
+ *   - Not totally sure the cache flush is needed as an unmapping would probably
+ *     have already flushed the cache. However that marks it clean so this flush
+ *     would be avoided...
+ *   - zero'ing the CPD entry could be replaced with actually updating it. Would
+ *     require an extra check. However this function is only going to be used
+ *     when a new pmd is (un)allocated, in one case it couldn't have been in the
+ *     CPD and in the other it is removed from the CPD anyway.
+ */
+void
+cpd_set_pmd(pmd_t* pmd_p, pmd_t pmd)
+{
+	pmd_t* cpd_p;
+	int domain_cpd, domain_pmd;
+	struct mm_struct* mm_p = current->mm;
+	unsigned long index = CPD_P_TO_INDEX(pmd_p);
+             
+	if (index > USER_PTRS_PER_PGD) { /* If pmd is kernel space mapping */
+		cpu_set_pmd(pmd_p, pmd);
+	} else { /* Must make CPD coherent */
+		if (index < ARMPID_PTRS_PER_PGD && mm_p) {/* Adjust for ARM PID relocation */
+			index = index + ARMPID_CPD_OFFSET(mm_p->context.pid);
+		}
+
+		cpd_p = pmd_offset(pgd_offset_k(0), 0) + index;
+		domain_cpd = pmd_domain(*cpd_p);
+		domain_pmd = cpd_get_active_domain(mm_p, MEGABYTE(index));
+
+		if (domain_cpd && (domain_cpd == domain_pmd)) {
+			/* update cpd_stats[] */
+			cpd_stats[index].collisions++; /* Not really a collision */
+			cpd_stats_del(domain_cpd, cpd_stats + index);
+			domains[domain_cpd].cpd_count--;
+
+			if (!cpd_is_domain_cache_coherent(domain_cpd)) {
+				cpd_cache_clean();
+			}
+
+			cpu_set_pmd(cpd_p, __pmd(0));
+
+			if (!cpd_is_domain_tlb_coherent(domain_cpd)) {
+				cpd_tlb_clean();
+			}
+		}
+		*pmd_p = pmd; /* Hardware never accesses user pg_dirs, only cpd code does */
+	}
+}
+
+/* cpd_tlb_flush_all: Insures coherence of all TLB entries owned by the kernel,
+ *   ie addresses above PAGE_OFFSET.
+ * Assumptions:
+ *   - Only used to make kernel mappings coherent.
+ *   - Kernel mappings in CPD are always coherent since it is the master pg_dir.
+ *   - Kernel mappings are not coherent with respect to the TLB.
+ * Action:
+ *   - Flush all TLB entries.
+ */
+void
+cpd_tlb_flush_all(void)
+{
+	cpd_tlb_clean();
+}
+
+/* cpd_tlb_flush_mm: Insures coherence of all TLB entries entries owned by
+ *   'mm_p' with its page table.
+ * Assumptions:
+ *   - No kernel mapping changed so TLB coherent with respect to them.
+ *   - User TLB entries covered by CPD entries owned by 'mm_p' are not coherent.
+ *   - CPD entries are updated if required via set_pmd().
+ * Action:
+ *   - If any CPD entries are tagged with 'mm_p's domain, if any, flush all TLB
+ *     entries.
+ */
+void
+cpd_tlb_flush_mm(struct mm_struct* mm_p)
+{
+	if (!cpd_is_mm_tlb_coherent(mm_p)) {
+		cpd_tlb_clean();
+	}
+}
+
+/* cpd_tlb_flush_range: Insures coherence of all TLB entries owned by 'mm_p' in
+ *   the range 'va_start' to 'va_end'.
+ * Assumptions:
+ *   - No kernel mappings effected so TLB coherent with respect to them.
+ *   - CPD coherent with task pg_dir entries, via set_pmd().
+ *   - TLB entries covered by CPD entries owned by 'mm_p' are not coherent over
+ *     the range.
+ * Action:
+ *   - If any entries in the CPD covered by the range are tagged with 'mm_p's
+ *     domain, clean TLBs.
+ * Notes:
+ *   - cpd_tlb_clean() is used instead of cpu_tlb_invalidate_range() since it
+ *     can mark the TLBs as clean. This should maybe be changed to only do
+ *     cpd_tlb_clean() if the range is a significant portion of the TLB
+ *     coverage.
+ *   - The range is specified in VA's while the flushing call and CPD accesses
+ *     use MVA's.
+ */
+void
+cpd_tlb_flush_range(struct mm_struct* mm_p,
+                    unsigned long va_start, unsigned long va_end)
+{
+	int domain;
+	unsigned long mva_start = va_to_mva(va_start, mm_p);
+	unsigned long mva_end = va_to_mva(va_end, mm_p);
+	pmd_t* cpd_end_p = pmd_offset(pgd_offset_k(mva_end), mva_end);
+	pmd_t* cpd_start_p = pmd_offset(pgd_offset_k(mva_start), mva_start);
+
+	if (!cpd_is_mm_tlb_coherent(mm_p)) { /* 'mm_p' has dirty CPD entries */
+		while (cpd_start_p <= cpd_end_p) {
+			domain = pmd_domain(*cpd_start_p);
+
+			if (!cpd_is_domain_tlb_coherent(domain) &&
+			   domain_active(mm_p->context.dacr, domain)) {
+
+				cpd_tlb_clean();
+				return; /* Flush TLB only once */
+			}
+			cpd_start_p++;
+		}
+	}
+}
+
+/* cpd_tlb_flush_page: Insures coherence of TLB entry owned by 'vma_p's mm for
+ *   'va_page'.
+ * Assumptions:
+ *   - Mapping is not a kernel one so TLB is coherent with respect to kernel
+ *     mappins.
+ *   - User CPD entry coherent, via set_pmd() and only a single page effected.
+ *   - TLB entry mapping 'va_page' is not coherent iff covered by a CPD entry
+ *     owned by the mm associated with 'vma_p'.
+ * Action:
+ *   - if CPD covering 'va_page' is owned by 'vma_p's mm, invalidate TLB
+ *     entries.
+ * Notes:
+ *   - The page is specified by a VA while the flushing call and CPD access
+ *     uses a MVA.
+ */
+void
+cpd_tlb_flush_page(struct vm_area_struct* vma_p, unsigned long va_page)
+{
+	pmd_t cpd;
+	int domain;
+	unsigned long mva_page = va_to_mva(va_page, vma_p->vm_mm);
+
+	/* Does 'vma_p's mm have any incoherencies? */
+	if (!cpd_is_mm_tlb_coherent(vma_p->vm_mm)) {
+		cpd = *pmd_offset(pgd_offset_k(mva_page), mva_page);
+		domain = pmd_domain(cpd);
+
+		/* 
+		 * Is CPD entry's domain incoherent and active in
+		 * 'vma_p's mm?
+		 */
+		if (!cpd_is_domain_tlb_coherent(domain) &&
+		    domain_active(vma_p->vm_mm->context.dacr, domain)) {
+			cpu_tlb_invalidate_page(mva_page, vma_p->vm_flags & VM_EXEC);
+		}
+	}
+}
+
+/* cpd_cache_flush_all: Insures coherence of all cache entries owned by the
+ *   kernel, ie addresses above PAGE_OFFSET.
+ * Assumptions:
+ *   - Only use to make kernel memory coherent.
+ * Action:
+ *   - Clean/Flush all caches.
+ */
+void
+cpd_cache_flush_all(void)
+{
+	cpd_cache_clean();
+}
+
+/* cpd_cache_flush_mm: Insures coherence of all cache entries owned by 'mm_p'.
+ * Assumptions:
+ *   - Kernel memory coherent with caches.
+ *   - User memory covered by CPD entries owned by 'mm_p' are not coherent with
+ *     caches.
+ * Action;
+ *   - If any CPD entries are tagged with 'mm_p's domain, if any, clean/flush
+ *     all cache entries.
+ */
+void
+cpd_cache_flush_mm(struct mm_struct* mm_p)
+{
+	if (!cpd_is_mm_cache_coherent(mm_p)) {
+		cpd_cache_clean();
+	}
+}
+
+/* 
+ * cpd_cache_flush_range: Ensures coherence of all cache entries owned
+ *                        by 'mm_p' in the range 'va_start' to 'va_end'.
+ * Assumptions:
+ *   - Kernel memory coherent with caches.
+ *   - Cache entries covered by CPD entries owned by 'mm_p' are not coherent
+ *     over the range.
+ * Action:
+ *   - If any entries in the CPD covered by the range are tagged with 'mm_p's
+ *     domain, clean/flush all cache entries.
+ * Notes:
+ *   - cpd_cache_clean() is used instead of cpu_cache_clean_invalidate_range()
+ *     since it can mark the caches as clean. This should maybe be changed to 
+ *     only do cpd_cache_clean() if the range is a significant portion of the
+ *     cache.
+ *   - The range is specified in VA's while the flushing call and CPD accesses
+ *     use MVA's.
+ */
+void
+cpd_cache_flush_range(struct mm_struct* mm_p,
+                      unsigned long va_start, unsigned long va_end)
+{
+	int domain;
+	unsigned long mva_start = va_to_mva(va_start, mm_p);
+	unsigned long mva_end = va_to_mva(va_end, mm_p);
+	pmd_t* cpd_end_p = pmd_offset(pgd_offset_k(mva_end), mva_end);
+	pmd_t* cpd_start_p = pmd_offset(pgd_offset_k(mva_start), mva_start);
+
+	if (!cpd_is_mm_cache_coherent(mm_p)) { /* 'mm_p' has dirty CPD entries */ 
+		while (cpd_start_p <= cpd_end_p) {
+
+			domain = pmd_domain(*cpd_start_p);
+
+			if (!cpd_is_domain_cache_coherent(domain) &&
+			    domain_active(mm_p->context.dacr, domain)) {
+
+				cpd_cache_clean();
+				return; /* Flush caches only once */
+			}
+			cpd_start_p++;
+		}
+	}
+}
+
+/* 
+ * cpd_cache_flush_page: Ensures coherency of cache entries owned 
+ *			 by 'vma_p's mm for 'va_page'.
+ * Assumptions:
+ *   - Kernel memory coherent with caches.
+ *   - User caches entries covered by 'va_page' are not coherent iff covered by
+ *     a CPD entry owned by the mm associated with 'vma_p'.
+ * Action:
+ *   - if CPD covering 'va_page' is owned by 'vma_p's mm, invalidate caches
+ *     entries.
+ * Notes:
+ *   - The page is specified by a VA while the flushing call and CPD access
+ *     uses a MVA.
+ */
+void
+cpd_cache_flush_page(struct vm_area_struct* vma_p, unsigned long va_page)
+{
+	pmd_t cpd;
+	int domain;
+	unsigned long mva_page = va_to_mva(va_page, vma_p->vm_mm);
+
+	/* Does 'vma_p's mm have any incoherencies? */
+	if (!cpd_is_mm_cache_coherent(vma_p->vm_mm)) {
+		cpd = *pmd_offset(pgd_offset_k(mva_page), mva_page);
+		domain = pmd_domain(cpd);
+
+		/* Is CPD entry's domain incoherent and active in 'vma_p's mm? */
+		if (!cpd_is_domain_cache_coherent(domain) &&
+		    domain_active(vma_p->vm_mm->context.dacr, domain)) {
+			cpu_cache_clean_invalidate_range(mva_page, mva_page + PAGE_SIZE,
+							 vma_p->vm_flags & VM_EXEC);
+		}
+	}
+}
+
+/*
+ * dump_cpd: Dumps the entire CPD for debugging.
+ *
+ * Notes:
+ *   - user = 0, all entries dumped; user = 1 only user entries dumped.
+ *     user = -1, dump domain 0 entries only
+ */
+void
+dump_cpd(int user)
+{
+	int i;
+	int domain;
+	pmd_t *cpd_p = pmd_offset(pgd_offset_k(0), 0); /* Get CPD Address */
+
+	for (i = 0; i < PTRS_PER_PGD; i++) {
+		domain = pmd_domain(cpd_p[i]);
+		if ((user == -1) && (domain == 0) && pmd_val(cpd_p[i])) {
+			printk("** dump_cpd() cpd[%d] 0x%x domain 0 **\n",
+			       i, (unsigned int)pmd_val(cpd_p[i]));
+			continue;
+		}
+		if (!user || (domain >= DOMAIN_START && domain <= DOMAIN_END)) {
+			printk("** dump_cpd() cpd[%d] 0x%x domain tag %d **\n",
+			       i, (unsigned int)pmd_val(cpd_p[i]), domain);
+		}
+	}
+	printk("\n");
+}
+
+/* dump_cpd_stat: Dumps info from a cpd_struct */
+void
+dump_cpd_stat(struct cpd_struct* cpd_stat_p)
+{
+	printk("** dump_cpd_stat: cpd_stat_p 0x%x collisions %d **\n",
+	       (unsigned int)cpd_stat_p, (unsigned int)cpd_stat_p->collisions);
+	printk("** dump_cpd_stat: cpd_next 0x%x cpd_prev 0x%x **\n",
+	       (unsigned int)cpd_stat_p->cpd_next,
+	       (unsigned int)cpd_stat_p->cpd_prev);
+
+}
+
+/* dump_cpd_stats: Dump all cpd_stats associated with a domain */
+void
+dump_cpd_stats(int domain)
+{
+	struct cpd_struct* cpd_stat_p = domains[domain].cpd_head;
+
+	printk("** dump_cpd_stats: domain %d **\n", domain);
+
+	while (cpd_stat_p != NULL) {
+		dump_cpd_stat(cpd_stat_p);
+
+		cpd_stat_p = cpd_stat_p->cpd_next;
+	}
+}
+
+/* dump_vma_single: Dumps info for a vm_area struct. */
+void
+dump_vma_single(struct vm_area_struct* vma_p)
+{
+	fassert(vma_p);
+
+	printk("** dump_vma_single: start 0x%x end 0x%x **\n",
+	       (unsigned int)vma_p->vm_start, (unsigned int)vma_p->vm_end);
+
+}
+
+/* dump_vma: Dump all vma's in a address-space */
+void
+dump_vma(struct mm_struct* mm_p)
+{
+	struct vm_area_struct* vma_p;
+
+	printk("** dump_vma: mm_p 0x%x **\n", (unsigned int)mm_p);
+	fassert(mm_p);
+
+	for (vma_p = mm_p->mmap; vma_p; vma_p = vma_p->vm_next) {
+		dump_vma_single(vma_p);
+	}
+
+}
diff -urN linux-2.4.29/arch/arm/mm/fault-armv.c linux-2.4.29-uc1/arch/arm/mm/fault-armv.c
--- linux-2.4.29/arch/arm/mm/fault-armv.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/fault-armv.c	2005-06-14 02:10:59.000000000 +0100
@@ -2,150 +2,333 @@
  *  linux/arch/arm/mm/fault-armv.c
  *
  *  Copyright (C) 1995  Linus Torvalds
- *  Modifications for ARM processor (c) 1995-2001 Russell King
+ *  Modifications for ARM processor (c) 1995-2003 Russell King
+ *  Modifications for FASS (C) 2001-2003 Adam Wiggins and John Zaitseff
+ *
+ * FASS Notes:
+ *   - The Modified Virtual Address (MVA) is changed into a Virtual Address (VA
+ *     with ARM PID relocation removed) before being forwarded to the
+ *     do_*_fault() handlers. Only the FASS handlers do_(cpd/domain)_fault()
+ *     are aware of the ARM PID relocaiton.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/config.h>
-#include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
 #include <linux/types.h>
 #include <linux/ptrace.h>
-#include <linux/mman.h>
 #include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/proc_fs.h>
 #include <linux/bitops.h>
 #include <linux/init.h>
 
-#include <asm/system.h>
-#include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
+#include <asm/proc/cpd.h>
+#include <asm/proc/pid.h>
 
-extern void show_pte(struct mm_struct *mm, unsigned long addr);
-extern int do_page_fault(unsigned long addr, int error_code,
-			 struct pt_regs *regs);
-extern int do_translation_fault(unsigned long addr, int error_code,
-				struct pt_regs *regs);
-extern void do_bad_area(struct task_struct *tsk, struct mm_struct *mm,
-			unsigned long addr, int error_code,
-			struct pt_regs *regs);
-
-#ifdef CONFIG_ALIGNMENT_TRAP
-extern int do_alignment(unsigned long addr, int error_code, struct pt_regs *regs);
-#else
-#define do_alignment do_bad
-#endif
-
+#include "fault.h"
 
 /*
  * Some section permission faults need to be handled gracefully.
  * They can happen due to a __{get,put}_user during an oops.
  */
 static int
-do_sect_fault(unsigned long addr, int error_code, struct pt_regs *regs)
+do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
 	struct task_struct *tsk = current;
-	do_bad_area(tsk, tsk->active_mm, addr, error_code, regs);
+	do_bad_area(tsk, tsk->active_mm, addr, fsr, regs);
 	return 0;
 }
 
 /*
- * Hook for things that need to trap external faults.  Note that
- * we don't guarantee that this will be the final version of the
- * interface.
+ * This abort handler always returns "fault".
  */
-int (*external_fault)(unsigned long addr, struct pt_regs *regs);
-
 static int
-do_external_fault(unsigned long addr, int error_code, struct pt_regs *regs)
+do_bad(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
-	if (external_fault)
-		return external_fault(addr, regs);
 	return 1;
 }
 
-/*
- * This abort handler always returns "fault".
+#ifdef CONFIG_ARM_FASS
+/* awiggins
+ * do_cpd_fault: Handle Caching Page Directory 'invalid' entry miss (ie CPD
+ *   entry is invalid) or a conflict miss (ie another process is using the CPD
+ *   entry).
+ * Reason:
+ *   (1) CPD entry is just empty, ie not allocate to any process.
+ *   (2) 'current' processes mm context has no section entry (ie no mapping).
+ *   (3) CPD entry is tagged with another processes domain.
+ * Action:
+ *   (1) Load the section entry from the pg_dir of 'current' process.
+ *   (2) Call do_translation_fault() and add entry if any mapping is granted,
+ *       else the kernel will raise a seg fault.
+ *   (3) Same as (1)/(2) depending on if 'current' process has a mapping in it's
+ *       pg_dir or not.
  */
 static int
-do_bad(unsigned long addr, int error_code, struct pt_regs *regs)
+do_cpd_fault(unsigned long v_addr, unsigned int fsr, struct pt_regs *regs)
 {
-	return 1;
+	int fault;
+	unsigned long mv_addr = va_to_mva(v_addr, current->mm);
+	pmd_t pmd = *pmd_offset(pgd_offset(current->mm, v_addr), v_addr);
+
+//	printk("** do_cpd_fault: **\n");
+
+	/* 
+	 * if there is a valid entry in the pg_dir of 'current' load
+	 * it into CPD
+	 */
+	if (!pmd_none(pmd)) {
+		goto success;
+	} 
+
+	/* Else take the page fault. and try again */
+	if ((fault = do_translation_fault(v_addr, fsr, regs)))
+		return fault;
+
+	pmd = *pmd_offset(pgd_offset(current->mm, v_addr), v_addr);
+
+	if (pmd_none(pmd))
+		return fault;
+
+success:
+	cpd_load(pmd, mv_addr);
+
+	return 0; /* Success */
+
+}
+
+/* awiggins
+ * do_domain_fault: Handle domain faults, these are generated by conflict 
+ *   misses or threads touching their currently allocated domain for the first
+ *   time.
+ * Reason:
+ *   (1) CPD entry is tagged with the wrong domain.
+ *   (2) A domain is allocated but it hasn't been activated.
+ * Action:
+ *   (1) Call do_cpd_fault() to handle the conflict miss.
+ *   (2) Activate allocated domain in the CPU DACR and return.
+ */
+static int
+do_domain_fault(unsigned long v_addr, unsigned int fsr, struct pt_regs *regs)
+{
+	int domain = cpd_get_active_domain(current->mm, v_addr);
+
+
+	if (domain && !domain_active(get_dacr(), domain)) { 
+		update_dacr(domain); /* modified */
+     
+		return 0; /* Success */
+	}
+
+//	printk("** do_domain_fault: called from %p **\n", __builtin_return_address(0));
+	return do_cpd_fault(v_addr, fsr, regs);
+}
+
+/* do_domain_fixup: This is required to fixup page translation faults on a
+ *   shared domain.
+ */
+static int
+do_domain_fixup(unsigned long v_addr, unsigned int fsr, struct pt_regs *regs)
+{
+	unsigned long mv_addr = va_to_mva(v_addr, current->mm); /* Modified VA */
+	pmd_t* cpd_p = pmd_offset(pgd_offset_k(mv_addr), mv_addr); 
+	pmd_t pmd = *pmd_offset(pgd_offset(current->mm, v_addr), v_addr);
+
+	/* This needs to be cleaned up a little */
+	if ((pmd_val(*cpd_p) >> 10) != (pmd_val(pmd) >> 10)) {
+		//printk("** do_domain_fixup: **\n");
+		pmd_val(pmd) |= PMD_DOMAIN(pmd_domain(*cpd_p)); /* Tag CPD entry */
+		cpu_set_pmd(cpd_p, pmd);
+	}
+  
+	return do_page_fault(v_addr, fsr, regs);
+
 }
+#else
+/*
+ * Map functions for non-fass use.
+ */
+#define	do_cpd_fault	do_translation_fault
+#define	do_domain_fixup	do_page_fault
+#define	do_domain_fault	do_bad
+#endif /* CONFIG_ARM_FASS */
 
-static const struct fsr_info {
-	int	(*fn)(unsigned long addr, int error_code, struct pt_regs *regs);
+static struct fsr_info {
+	int	(*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
 	int	sig;
 	const char *name;
 } fsr_info[] = {
 	{ do_bad,		SIGSEGV, "vector exception"		   },
-	{ do_alignment,		SIGILL,	 "alignment exception"		   },
+	{ do_bad,		SIGILL,	 "alignment exception"		   },
 	{ do_bad,		SIGKILL, "terminal exception"		   },
-	{ do_alignment,		SIGILL,	 "alignment exception"		   },
-	{ do_external_fault,	SIGBUS,	 "external abort on linefetch"	   },
-	{ do_translation_fault,	SIGSEGV, "section translation fault"	   },
-	{ do_external_fault,	SIGBUS,	 "external abort on linefetch"	   },
-	{ do_page_fault,	SIGSEGV, "page translation fault"	   },
-	{ do_external_fault,	SIGBUS,	 "external abort on non-linefetch" },
-	{ do_bad,		SIGSEGV, "section domain fault"		   },
-	{ do_external_fault,	SIGBUS,	 "external abort on non-linefetch" },
-	{ do_bad,		SIGSEGV, "page domain fault"		   },
+	{ do_bad,		SIGILL,	 "alignment exception"		   },
+	{ do_bad,		SIGBUS,	 "external abort on linefetch"	   },
+	{ do_cpd_fault,		SIGSEGV, "section translation fault"	   },
+	{ do_bad,		SIGBUS,	 "external abort on linefetch"	   },
+	{ do_domain_fixup,	SIGSEGV, "page translation fault"	   },
+	{ do_bad,		SIGBUS,	 "external abort on non-linefetch" },
+	{ do_domain_fault,	SIGSEGV, "section domain fault"		   },
+	{ do_bad,		SIGBUS,	 "external abort on non-linefetch" },
+	{ do_domain_fault,	SIGSEGV, "page domain fault"		   },
 	{ do_bad,		SIGBUS,	 "external abort on translation"   },
 	{ do_sect_fault,	SIGSEGV, "section permission fault"	   },
 	{ do_bad,		SIGBUS,	 "external abort on translation"   },
-	{ do_page_fault,	SIGSEGV, "page permission fault"	   }
+	{ do_page_fault,	SIGSEGV, "page permission fault"	   },
 };
 
+
+void __init
+hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *),
+		int sig, const char *name)
+{
+	if (nr >= 0 && nr < ARRAY_SIZE(fsr_info)) {
+		fsr_info[nr].fn   = fn;
+		fsr_info[nr].sig  = sig;
+		fsr_info[nr].name = name;
+	}
+}
+
 /*
  * Dispatch a data abort to the relevant handler.
  */
+/* awiggins
+ *
+ * do_DataAbort: Modified to check for a translation fault on a page
+ *	 that should be classed as a domain fault on a
+ *	 page. Translation faults have a higher priority then domain
+ *	 fault. What can happen is  that the CPD entry a process
+ *	 touches is not its own and the 2nd  level page table has no
+ *	 entry for the faulting address, so you get a translation
+ *	 fault on a page even though you're not accessing your own
+ *	 pg_dir entry because the domain tag will be ignored.  In this
+ *	 case we need to flag the fault as a domain fault on a page
+ *	 to produce the correct behaviour of replacing the CPD entry
+ *	 to one owned by the current process.
+ * Notes:
+ *   - For data aborts the faulting address is supplied by the ARM 
+ *     Fault Address Register (FAR) as it is a Modified Virtual
+ *     Address (MVA), NOT the Virtual Address (VA) as seen by the core
+ *     and the programs.
+ */
+
 asmlinkage void
-do_DataAbort(unsigned long addr, int error_code, struct pt_regs *regs, int fsr)
+do_DataAbort(unsigned long mv_addr, unsigned int fsr, struct pt_regs *regs)
 {
+#ifdef CONFIG_ARM_FASS
+	unsigned long addr = mva_to_va(mv_addr, current->mm); /* Unmodified VA */
+	pmd_t cpd = *pmd_offset(pgd_offset_k(mv_addr), mv_addr);
+#else
+	unsigned long addr = mv_addr;
+#endif
 	const struct fsr_info *inf = fsr_info + (fsr & 15);
 
-	if (!inf->fn(addr, error_code, regs))
+#ifdef CONFIG_KGDB
+	if(kgdb_fault_expected)
+		kgdb_handle_bus_error();
+#endif
+
+#ifdef CONFIG_ARM_FASS
+	/* 
+	 * The following code does the translation fault on a page to
+	 * domain fault on a page check/conversion. Could be cleaned
+	 * up probably
+	 */
+	if ((pmd_domain(cpd) >= DOMAIN_START) &&
+	    !domain_active(get_dacr(), pmd_domain(cpd)) &&
+	    ((fsr & 15) == 7)) { /* 7 is translation fault on page */
+		inf = fsr_info + 9;   /* 9 is domain fault on page */
+	}
+
+
+#if 0
+	switch (fsr & 0xf) {
+	case 0xB:
+	case 0x9:
+		if ((((fsr & 0xF0) >> 4) != pmd_domain(cpd)) 
+		    && (get_dacr() != 0x15)) {
+			printk("** do_DataAbort: VA 0x%lx MVA 0x%lx fsr 0x%x %d dacr 0x%lx **\n",
+			       addr, mv_addr, fsr & 0xF, (fsr & 0xF0) >> 4, get_dacr());
+			dump_cpd(1);
+		}
+		break;
+
+	default:
+		break;
+	}
+#endif
+#endif /* CONFIG_ARM_FASS */
+
+	if (!inf->fn(addr, fsr, regs))
 		return;
 
-	printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n",
-		inf->name, fsr, addr);
+	printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at va 0x%08lx mva 0x%08lx\n",
+	       inf->name, fsr, addr, mv_addr);
 	force_sig(inf->sig, current);
 	show_pte(current->mm, addr);
+
+#ifdef CONFIG_KGDB
+	if(!user_mode(regs))
+		do_kgdb(regs, inf->sig);
+#endif
+
 	die_if_kernel("Oops", regs, 0);
 }
 
+/* awiggins
+ * do_prefetchAbort: Modified to check if the reason for the abort and call
+ *   one of the following functions:
+ *   - do_cpd_fault():         Fault due to invalid CPD entry.
+ *   - do_domain_fault():      Fault due to inactive domain.
+ *   - do_translation_fault(): All other cases.
+ * Notes:
+ *   - For prefetch aborts the faulting address is calculated by the kernel not
+ *     supplied by the ARM Fault Address Register (FAR) so it is a Virtual
+ *     Address (VA), NOT a Modified Virtual Address (MVA).
+ */
 asmlinkage void
 do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
 {
+#ifdef CONFIG_ARM_FASS
+	unsigned long mv_addr = va_to_mva(addr, current->mm); /* MVA */
+	pmd_t cpd = *pmd_offset(pgd_offset_k(mv_addr), mv_addr);
+
+	if (pmd_none(cpd)) {
+		do_cpd_fault(addr, 0, regs);
+	}
+	else if(!domain_active(get_dacr(), pmd_domain(cpd))) {
+		do_domain_fault(addr, 0, regs);
+	}
+	else {
+		do_translation_fault(addr, 0, regs);
+	}
+#else
 	do_translation_fault(addr, 0, regs);
+#endif
 }
 
 /*
  * We take the easy way out of this problem - we make the
  * PTE uncacheable.  However, we leave the write buffer on.
  */
-static void adjust_pte(struct vm_area_struct *vma, unsigned long address)
+static int adjust_pte(struct vm_area_struct *vma, unsigned long address)
 {
 	pgd_t *pgd;
 	pmd_t *pmd;
 	pte_t *pte, entry;
+	int ret = 0;
 
 	pgd = pgd_offset(vma->vm_mm, address);
 	if (pgd_none(*pgd))
-		return;
+		goto no_pgd;
 	if (pgd_bad(*pgd))
 		goto bad_pgd;
 
 	pmd = pmd_offset(pgd, address);
 	if (pmd_none(*pmd))
-		return;
+		goto no_pmd;
 	if (pmd_bad(*pmd))
 		goto bad_pmd;
 
@@ -155,28 +338,41 @@
 	/*
 	 * If this page isn't present, or is already setup to
 	 * fault (ie, is old), we can safely ignore any issues.
+         *
+         * FASS: Marked as unbufferable too otherwise we could miss an update
+         *   that is still in the write-buffer.
 	 */
-	if (pte_present(entry) && pte_val(entry) & L_PTE_CACHEABLE) {
+#ifdef CONFIG_ARM_FASS
+#define	BUFFERABLE	L_PTE_BUFFERABLE
+#else
+#define	BUFFERABLE	(0)
+#endif
+	if (pte_present(entry) && pte_val(entry) &
+            (L_PTE_CACHEABLE | BUFFERABLE)) {
 		flush_cache_page(vma, address);
-		pte_val(entry) &= ~L_PTE_CACHEABLE;
+		pte_val(entry) &= ~(L_PTE_CACHEABLE | BUFFERABLE);
 		set_pte(pte, entry);
 		flush_tlb_page(vma, address);
+		ret = 1;
 	}
-	return;
+	return ret;
 
 bad_pgd:
 	pgd_ERROR(*pgd);
 	pgd_clear(pgd);
-	return;
+no_pgd:
+	return 0;
 
 bad_pmd:
 	pmd_ERROR(*pmd);
 	pmd_clear(pmd);
-	return;
+no_pmd:
+	return 0;
 }
 
+/* awiggins: Not using this as I'm too lazy to properly patch things for now */
 static void
-make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page)
+make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page, int dirty)
 {
 	struct vm_area_struct *mpnt;
 	struct mm_struct *mm = vma->vm_mm;
@@ -210,43 +406,225 @@
 		if (off >= (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT)
 			continue;
 
+		off = mpnt->vm_start + (off << PAGE_SHIFT);
+
 		/*
 		 * Ok, it is within mpnt.  Fix it up.
 		 */
-		adjust_pte(mpnt, mpnt->vm_start + (off << PAGE_SHIFT));
-		aliases ++;
+		aliases += adjust_pte(mpnt, off);
 	}
 	if (aliases)
 		adjust_pte(vma, addr);
+	else if (dirty)
+		flush_cache_page(vma, addr);
+}
+
+#ifdef CONFIG_ARM_FASS
+/* writable_pte: Tests if a page is writable. */
+static int
+writable_pte(struct vm_area_struct *vma, unsigned long address)
+{
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte, entry;
+
+	pgd = pgd_offset(vma->vm_mm, address);
+	if (pgd_none(*pgd)) {
+		return 0;
+	}
+
+	pmd = pmd_offset(pgd, address);
+	if (pmd_none(*pmd)) {
+		return 0;
+	}
+
+	pte = pte_offset(pmd, address);
+	entry = *pte;
+
+	//printk("** writable_pte: entry = 0x%x **\n", entry);
+
+	if (pte_present(entry)) {
+		//printk("** writable_pte: entry 0x%x writable %x **\n",
+		//	   entry, pte_write(entry));
+
+		return pte_write(entry);
+	}
+	return 0;
 }
+#endif /* CONFIG_ARM_FASS */
 
 /*
  * Take care of architecture specific things when placing a new PTE into
- * a page table, or changing an existing PTE.  Basically, there are two
+ * a page table, or changing an existing PTE.  Basically, there are three
  * things that we need to take care of:
  *
  *  1. If PG_dcache_dirty is set for the page, we need to ensure
  *     that any cache entries for the kernels virtual memory
  *     range are written back to the page.
  *  2. If we have multiple shared mappings of the same space in
- *     an object, we need to deal with the cache aliasing issues.
+ *     an object, we need to deal with the cache synonym issues.
+ *  3. If the page is part of a shared vma, here we check if vm_shared_data has
+ *     a region_struct allocated. If not a suitable one is set.
  *
  * Note that the page_table_lock will be held.
+ *
+ * FASS Notes:
+ *   - Since we do not flush the cache on every context switch shared
+ *     mappings that map to different virtual addresses cause synonyms in the
+ *     cache, these synonyms independent of whether the shared mapping is within
+ *     the same or between different address-spaces. There are two possible
+ *     solutions:
+ * 
+ *     1) Mark the shared mappings as uncachable and unbufferable. This reduces
+ *        the performance of every access of a shared mapping, infact this is
+ *        only needed if the mappings map to different virtual addresses. This
+ *        is how ARM Linux currently handles shared mapping, ie synonyms, within
+ *        the same address-space.
+ *
+ *     2) Only one shared mapping is enabled at a time. This can infact be
+ *        extented to only one set of mappings that map the shared physical
+ *        frame to the same virtual page are enabled at a time. The performance
+ *        lost here is a page fault every time a disabled mapping is re-enabled
+ *        and the synonym at different addresses are disabled. This solution is
+ *        also independed with regard to the whether the synonym is within the
+ *        same address-space or between address-spaces. An additional problem
+ *        with this solution is any shared mappings within the PID relocated
+ *        area, ie the first 32MB will not flag as synonyms when it will be if
+ *        the sharing address-spaces have different PID's. This could be checked
+ *        for easily enough though.
+ *
+ *     I want to benchmark the performance of both solutions but for now I'll
+ *     use 1) since it is ARM Linux's original solution. I'm also going to add
+ *     a check to only mark the pages un(cacheable/bufferable) iff at least one
+ *     or more mappings are writable. Otherwise the mappings will always be
+ *     consistent.
+ *  - The checks to use the same region are technically incorrect, if we have a
+ *    process sharing a mapping read-only and another one sharing it read-write
+ *    both will have read-write access to it. Checks needed to be added here to
+ *    make sure both the access rights and the size of the shared mapping are
+ *    the same. If they a new region must be allocated.
  */
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
 {
 	unsigned long pfn = pte_pfn(pte);
 	struct page *page;
+#ifdef CONFIG_ARM_FASS
+	struct vm_area_struct *mpnt;
+	struct mm_struct *mm;
+	unsigned long pgoff;
+	int synonyms, writable;
 
 	if (!pfn_valid(pfn))
 		return;
 	page = pfn_to_page(pfn);
+
+	if (!page->mapping)
+		return;
+
+	/* region_struct updates */
+	if ((vma->vm_flags & VM_SHARED) && !vma->vm_sharing_data) {
+
+		/* Check for existing region to use */
+		for (mpnt = page->mapping->i_mmap_shared; mpnt;
+		     mpnt = mpnt->vm_next_share) {
+
+			/* If we have a shared vma of the same access type */
+			if (mpnt->vm_sharing_data &&
+			    (vma->vm_start == mpnt->vm_start) &&
+			    (vma->vm_pgoff == mpnt->vm_pgoff)) {
+
+				vma->vm_sharing_data = mpnt->vm_sharing_data;
+				((struct region_struct*)vma->vm_sharing_data)->mm_count++;
+
+				break;
+			}
+		}
+
+		/* First vma of the shared set */
+		if (!vma->vm_sharing_data) {
+			vma->vm_sharing_data = cpd_allocate_region();
+		}
+	}
+
+	{
+		int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
+
+		if (dirty) {
+			unsigned long kvirt = (unsigned long)page_address(page);
+			cpu_cache_clean_invalidate_range(kvirt, kvirt + PAGE_SIZE, 0);
+		}
+	}
+	mm = vma->vm_mm;
+	pgoff = (addr - vma->vm_start) >> PAGE_SHIFT;
+
+	writable = writable_pte(vma, addr);
+	synonyms = 0;
+
+	/* Need to first check for writable synonyms */
+	for (mpnt = page->mapping->i_mmap_shared; mpnt && ~writable;
+	    mpnt = mpnt->vm_next_share) {
+		unsigned long off;
+
+		/* If the shared mapping has the same region it isn't a synonym */
+		if (vma->vm_sharing_data &&
+		    (vma->vm_sharing_data == mpnt->vm_sharing_data))
+			continue;
+
+		/*
+		 * If the page isn't in this VMA, we can also ignore it.
+		 */
+		if (pgoff < mpnt->vm_pgoff)
+			continue;
+	  
+		off = pgoff - mpnt->vm_pgoff;
+		if (off >= (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT)
+			continue;
+
+		writable = writable_pte(mpnt, mpnt->vm_start + (off << PAGE_SHIFT));
+		synonyms++;
+	}
+
+	/* If there are synonyms or they are all read-only do nothing */ 
+	if (!synonyms || !writable) {
+		return;
+	}
+
+	printk("** update_mmu_cache: Mark writable synonym uncachable **\n");
+
+	/* Mark all synonyms as uncachable */
+	for (mpnt = page->mapping->i_mmap_shared; mpnt;
+	     mpnt = mpnt->vm_next_share) {
+		unsigned long off;
+	  
+		/*
+		 * If the page isn't in this VMA, we can also ignore it.
+		 */
+		if (pgoff < mpnt->vm_pgoff)
+			continue;
+	  
+		off = pgoff - mpnt->vm_pgoff;
+		if (off >= (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT)
+			continue;
+	  
+		/*
+		 * Ok, it is within mpnt.  Fix it up.
+		 */
+		adjust_pte(mpnt, mpnt->vm_start + (off << PAGE_SHIFT));
+	}
+	adjust_pte(vma, addr);
+#else
+	if (!pfn_valid(pfn))
+		return;
+	page = pfn_to_page(pfn);
 	if (page->mapping) {
-		if (test_and_clear_bit(PG_dcache_dirty, &page->flags)) {
+		int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
+
+		if (dirty) {
 			unsigned long kvirt = (unsigned long)page_address(page);
 			cpu_cache_clean_invalidate_range(kvirt, kvirt + PAGE_SIZE, 0);
 		}
 
-		make_coherent(vma, addr, page);
+		make_coherent(vma, addr, page, dirty);
 	}
+#endif /* CONFIG_ARM_FASS */
 }
diff -urN linux-2.4.29/arch/arm/mm/fault-common.c linux-2.4.29-uc1/arch/arm/mm/fault-common.c
--- linux-2.4.29/arch/arm/mm/fault-common.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/fault-common.c	2005-06-14 02:10:59.000000000 +0100
@@ -11,21 +11,18 @@
 #include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/types.h>
 #include <linux/ptrace.h>
-#include <linux/mman.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
-#include <linux/proc_fs.h>
 #include <linux/init.h>
 
 #include <asm/system.h>
-#include <asm/uaccess.h>
 #include <asm/pgtable.h>
-#include <asm/unaligned.h>
+#include <asm/uaccess.h>
+#include <asm/kgdb.h>
+
+#include "fault.h"
 
 #ifdef CONFIG_CPU_26
 #define FAULT_CODE_WRITE	0x02
@@ -34,13 +31,11 @@
 #define READ_FAULT(m)		(!((m) & FAULT_CODE_WRITE))
 #else
 /*
- * On 32-bit processors, we define "mode" to be zero when reading,
- * non-zero when writing.  This now ties up nicely with the polarity
- * of the 26-bit machines, and also means that we avoid the horrible
- * gcc code for "int val = !other_val;".
+ * "code" is actually the FSR register.  Bit 11 set means the
+ * instruction was performing a write.
  */
-#define DO_COW(m)		(m)
-#define READ_FAULT(m)		(!(m))
+#define DO_COW(code)		((code) & (1 << 11))
+#define READ_FAULT(code)	(!DO_COW(code))
 #endif
 
 /*
@@ -54,16 +49,17 @@
 	if (!mm)
 		mm = &init_mm;
 
-	printk(KERN_ALERT "mm = %p pgd = %p\n", mm, mm->pgd);
-
 	fs = get_fs();
 	set_fs(get_ds());
+
 	do {
-		pgd_t pg, *pgd = pgd_offset(mm, addr);
+		pgd_t pg, *pgd;
 		pmd_t pm, *pmd;
 		pte_t pt, *pte;
 
-		printk(KERN_ALERT "*pgd = ");
+		printk(KERN_ALERT "pgd = %p\n", mm->pgd);
+		pgd = pgd_offset(mm, addr);
+		printk(KERN_ALERT "[%08lx] *pgd=", addr);
 
 		if (__get_user(pgd_val(pg), (unsigned long *)pgd)) {
 			printk("(faulted)");
@@ -122,7 +118,7 @@
  * Oops.  The kernel tried to access some page that wasn't present.
  */
 static void
-__do_kernel_fault(struct mm_struct *mm, unsigned long addr, int error_code,
+__do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
 		  struct pt_regs *regs)
 {
 	unsigned long fixup;
@@ -148,7 +144,12 @@
 		"paging request", addr);
 
 	show_pte(mm, addr);
-	die("Oops", regs, error_code);
+
+#ifdef	CONFIG_KGDB
+	do_kgdb(regs, SIGKILL);
+#endif
+	die("Oops", regs, fsr);
+
 	do_exit(SIGKILL);
 }
 
@@ -157,20 +158,20 @@
  * User mode accesses just cause a SIGSEGV
  */
 static void
-__do_user_fault(struct task_struct *tsk, unsigned long addr, int error_code,
-		int code, struct pt_regs *regs)
+__do_user_fault(struct task_struct *tsk, unsigned long addr,
+		unsigned int fsr, int code, struct pt_regs *regs)
 {
 	struct siginfo si;
 
 #ifdef CONFIG_DEBUG_USER
 	printk(KERN_DEBUG "%s: unhandled page fault at pc=0x%08lx, "
 	       "lr=0x%08lx (bad address=0x%08lx, code %d)\n",
-	       tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, error_code);
+	       tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, fsr);
 	show_regs(regs);
 #endif
 
 	tsk->thread.address = addr;
-	tsk->thread.error_code = error_code;
+	tsk->thread.error_code = fsr;
 	tsk->thread.trap_no = 14;
 	si.si_signo = SIGSEGV;
 	si.si_errno = 0;
@@ -181,25 +182,31 @@
 
 void
 do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr,
-	    int error_code, struct pt_regs *regs)
+	    unsigned int fsr, struct pt_regs *regs)
 {
 	/*
 	 * If we are in kernel mode at this point, we
 	 * have no context to handle this fault with.
 	 */
 	if (user_mode(regs))
-		__do_user_fault(tsk, addr, error_code, SEGV_MAPERR, regs);
+		__do_user_fault(tsk, addr, fsr, SEGV_MAPERR, regs);
 	else
-		__do_kernel_fault(mm, addr, error_code, regs);
+		__do_kernel_fault(mm, addr, fsr, regs);
 }
 
 static int
-__do_page_fault(struct mm_struct *mm, unsigned long addr, int error_code,
+__do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
 		struct task_struct *tsk)
 {
 	struct vm_area_struct *vma;
 	int fault, mask;
 
+#if defined(CONFIG_KGDB)
+	/* REVISIT: This one may not be required? */
+	if (kgdb_fault_expected)
+		kgdb_handle_bus_error();
+#endif
+
 	vma = find_vma(mm, addr);
 	fault = -2; /* bad map area */
 	if (!vma)
@@ -212,7 +219,7 @@
 	 * memory access, so we can handle it.
 	 */
 good_area:
-	if (READ_FAULT(error_code)) /* read? */
+	if (READ_FAULT(fsr)) /* read? */
 		mask = VM_READ|VM_EXEC;
 	else
 		mask = VM_WRITE;
@@ -227,7 +234,7 @@
 	 * than endlessly redo the fault.
 	 */
 survive:
-	fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(error_code));
+	fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(fsr));
 
 	/*
 	 * Handle the "normal" cases first - successful and sigbus
@@ -260,12 +267,17 @@
 	return fault;
 }
 
-int do_page_fault(unsigned long addr, int error_code, struct pt_regs *regs)
+int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
 	struct task_struct *tsk;
 	struct mm_struct *mm;
 	int fault;
 
+#if defined(CONFIG_KGDB)
+	if (kgdb_fault_expected)
+		kgdb_handle_bus_error();
+#endif
+
 	tsk = current;
 	mm  = tsk->mm;
 
@@ -277,7 +289,7 @@
 		goto no_context;
 
 	down_read(&mm->mmap_sem);
-	fault = __do_page_fault(mm, addr, error_code, tsk);
+	fault = __do_page_fault(mm, addr, fsr, tsk);
 	up_read(&mm->mmap_sem);
 
 	/*
@@ -308,7 +320,7 @@
 		printk("VM: killing process %s\n", tsk->comm);
 		do_exit(SIGKILL);
 	} else
-		__do_user_fault(tsk, addr, error_code, fault == -1 ?
+		__do_user_fault(tsk, addr, fsr, fault == -1 ?
 				SEGV_ACCERR : SEGV_MAPERR, regs);
 	return 0;
 
@@ -323,7 +335,7 @@
 	 * or user mode.
 	 */
 	tsk->thread.address = addr;
-	tsk->thread.error_code = error_code;
+	tsk->thread.error_code = fsr;
 	tsk->thread.trap_no = 14;
 	force_sig(SIGBUS, tsk);
 #ifdef CONFIG_DEBUG_USER
@@ -336,10 +348,14 @@
 		return 0;
 
 no_context:
-	__do_kernel_fault(mm, addr, error_code, regs);
+	__do_kernel_fault(mm, addr, fsr, regs);
 	return 0;
 }
 
+#if __LINUX_ARM_ARCH__ == 3
+unsigned long g_pgd;
+#endif
+
 /*
  * First Level Translation Fault Handler
  *
@@ -357,21 +373,23 @@
  * interrupt or a critical region, and should only copy the information
  * from the master page table, nothing more.
  */
-int do_translation_fault(unsigned long addr, int error_code, struct pt_regs *regs)
+int do_translation_fault(unsigned long addr, unsigned int fsr,
+			 struct pt_regs *regs)
 {
 	struct task_struct *tsk;
-	struct mm_struct *mm;
 	int offset;
 	pgd_t *pgd, *pgd_k;
 	pmd_t *pmd, *pmd_k;
 
 	if (addr < TASK_SIZE)
-		return do_page_fault(addr, error_code, regs);
+		return do_page_fault(addr, fsr, regs);
 
 	offset = __pgd_offset(addr);
 
 	/*
 	 * FIXME: CP15 C1 is write only on ARMv3 architectures.
+	 * You really need to read the value in the page table
+	 * register, not a copy.
 	 */
 	pgd = cpu_get_pgd() + offset;
 	pgd_k = init_mm.pgd + offset;
@@ -395,8 +413,7 @@
 
 bad_area:
 	tsk = current;
-	mm  = tsk->active_mm;
 
-	do_bad_area(tsk, mm, addr, error_code, regs);
+	do_bad_area(tsk, tsk->active_mm, addr, fsr, regs);
 	return 0;
 }
diff -urN linux-2.4.29/arch/arm/mm/fault.h linux-2.4.29-uc1/arch/arm/mm/fault.h
--- linux-2.4.29/arch/arm/mm/fault.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/fault.h	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,9 @@
+void do_bad_area(struct task_struct *tsk, struct mm_struct *mm,
+		 unsigned long addr, unsigned int fsr, struct pt_regs *regs);
+
+void show_pte(struct mm_struct *mm, unsigned long addr);
+
+int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
+
+int do_translation_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
+
diff -urN linux-2.4.29/arch/arm/mm/init.c linux-2.4.29-uc1/arch/arm/mm/init.c
--- linux-2.4.29/arch/arm/mm/init.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/init.c	2005-06-14 02:10:59.000000000 +0100
@@ -9,7 +9,6 @@
  */
 #include <linux/config.h>
 #include <linux/signal.h>
-#include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
@@ -18,7 +17,6 @@
 #include <linux/mman.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
-#include <linux/swapctl.h>
 #include <linux/smp.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
@@ -374,6 +372,11 @@
 	 */
 	if (machine_is_integrator())
 		reserve_bootmem_node(pgdat, 0, __pa(swapper_pg_dir));
+	if (machine_is_edb9301() || machine_is_edb9312() || machine_is_edb9315() ||
+			machine_is_ipd())
+		reserve_bootmem_node(pgdat, PHYS_OFFSET,
+				(__pa(swapper_pg_dir) - PHYS_OFFSET));
+
 	/*
 	 * These should likewise go elsewhere.  They pre-reserve
 	 * the screen memory region at the start of main system
@@ -383,6 +386,8 @@
 		reserve_bootmem_node(pgdat, 0x02000000, 0x00080000);
 	if (machine_is_edb7211() || machine_is_fortunet())
 		reserve_bootmem_node(pgdat, 0xc0000000, 0x00020000);
+	if (machine_is_edb7312())
+		reserve_bootmem_node(pgdat, 0xc0000000, 0x00020000);
 	if (machine_is_p720t())
 		reserve_bootmem_node(pgdat, PHYS_OFFSET, 0x00014000);
 #ifdef CONFIG_SA1111
@@ -499,11 +504,13 @@
 	/*
 	 * allocate the zero page.  Note that we count on this going ok.
 	 */
+	printk("alloc_bootmem_low\n");
 	zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
 
 	/*
 	 * initialise the page tables.
 	 */
+	printk("memtable_init\n");
 	memtable_init(mi);
 	if (mdesc->map_io)
 		mdesc->map_io();
diff -urN linux-2.4.29/arch/arm/mm/Makefile linux-2.4.29-uc1/arch/arm/mm/Makefile
--- linux-2.4.29/arch/arm/mm/Makefile	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/Makefile	2005-06-14 02:10:59.000000000 +0100
@@ -17,11 +17,12 @@
 obj-m		:=
 obj-n		:=
 obj-		:=
-export-objs	:= proc-syms.o discontig.o
+export-objs	:= proc-syms.o discontig.o cpd.o
 
 ifeq ($(CONFIG_CPU_32),y)
 obj-y		+= consistent.o fault-armv.o ioremap.o mm-armv.o
 obj-$(CONFIG_MODULES) += proc-syms.o
+obj-$(CONFIG_ARM_FASS) += cpd.o pid.o
 endif
 
 obj-$(CONFIG_CPU_26) += fault-armo.o mm-armo.o small_page.o
@@ -42,6 +43,7 @@
 p-$(CONFIG_CPU_ARM1026)	+= proc-arm1026.o
 p-$(CONFIG_CPU_SA110)	+= proc-sa110.o
 p-$(CONFIG_CPU_SA1100)	+= proc-sa110.o
+p-$(CONFIG_CPU_XSCALE)	+= proc-xscale.o xscale-lock.o
 
 # Integrator follows "new style"
 # Soon, others will do too, and we can get rid of this
diff -urN linux-2.4.29/arch/arm/mm/mm-armo.c linux-2.4.29-uc1/arch/arm/mm/mm-armo.c
--- linux-2.4.29/arch/arm/mm/mm-armo.c	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-uc1/arch/arm/mm/mm-armo.c	2005-06-14 02:10:59.000000000 +0100
@@ -104,7 +104,6 @@
 no_pte:
 	spin_unlock(&mm->page_table_lock);
 	pmd_free(new_pmd);
-	check_pgt_cache();
 	free_pgd_slow(new_pgd);
 	return NULL;
 
diff -urN linux-2.4.29/arch/arm/mm/mm-armv.c linux-2.4.29-uc1/arch/arm/mm/mm-armv.c
--- linux-2.4.29/arch/arm/mm/mm-armv.c	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-uc1/arch/arm/mm/mm-armv.c	2005-06-14 02:10:59.000000000 +0100
@@ -9,7 +9,6 @@
  *
  *  Page table sludge for ARM v3 and v4 processor architectures.
  */
-#include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
@@ -123,7 +122,6 @@
 no_pte:
 	spin_unlock(&mm->page_table_lock);
 	pmd_free(new_pmd);
-	check_pgt_cache();
 	free_pages((unsigned long)new_pgd, 2);
 	return NULL;
 
@@ -158,7 +156,6 @@
 	pmd_clear(pmd);
 	pte_free(pte);
 	pmd_free(pmd);
-	check_pgt_cache();
 free:
 	free_pages((unsigned long) pgd, 2);
 }
@@ -207,7 +204,6 @@
 
 /*
  * Clear any PGD mapping.  On a two-level page table system,
- * the clearance is done by the middle-level functions (pmd)
  * rather than the top-level (pgd) functions.
  */
 static inline void clear_mapping(unsigned long virt)
@@ -224,7 +220,7 @@
 static void __init create_mapping(struct map_desc *md)
 {
 	unsigned long virt, length;
-	int prot_sect, prot_pte;
+	unsigned int prot_sect, prot_pte;
 	long off;
 
 	if (md->prot_read && md->prot_write &&
@@ -327,7 +323,6 @@
 		p->prot_write = 1;
 		p->cacheable  = 1;
 		p->bufferable = 1;
-
 		p ++;
 	}
 
@@ -340,7 +335,6 @@
 	p->prot_write = 0;
 	p->cacheable  = 1;
 	p->bufferable = 1;
-
 	p ++;
 #endif
 
@@ -353,7 +347,6 @@
 	p->prot_write = 0;
 	p->cacheable  = 1;
 	p->bufferable = 0;
-
 	p ++;
 #endif
 
@@ -383,13 +376,20 @@
 	init_maps->physical   = virt_to_phys(init_maps);
 	init_maps->virtual    = vectors_base();
 	init_maps->length     = PAGE_SIZE;
+#ifdef CONFIG_ARM_FASS
+	init_maps->domain     = DOMAIN_KERNEL; /* awiggins for FASS */
+#else
 	init_maps->domain     = DOMAIN_USER;
+#endif
 	init_maps->prot_read  = 0;
 	init_maps->prot_write = 0;
 	init_maps->cacheable  = 1;
 	init_maps->bufferable = 0;
 
 	create_mapping(init_maps);
+
+	flush_cache_all();
+	flush_tlb_all();
 }
 
 /*
@@ -399,8 +399,9 @@
 {
 	int i;
 
-	for (i = 0; io_desc[i].last == 0; i++)
+	for (i = 0; io_desc[i].last == 0; i++) {
 		create_mapping(io_desc + i);
+	}
 }
 
 static inline void free_memmap(int node, unsigned long start, unsigned long end)
diff -urN linux-2.4.29/arch/arm/mm/pid.c linux-2.4.29-uc1/arch/arm/mm/pid.c
--- linux-2.4.29/arch/arm/mm/pid.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/pid.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,275 @@
+/*
+* Filename:    arch/arm/mm/pid.c
+* Description: ARM Process ID (PID) functions for Fast Address Space Switching
+*              (FASS) in ARM Linux.
+* Created:     14/10/2001
+* Changes:     19/02/2002 - arm_pid_allocate() modifed to create dummy vmas.
+*              29/02/2002 - Fixed arm_pid_allocate() to update the CPU PID
+*              register only when the current task is the one receiving the
+*              PID.
+* Copyright:   (C) 2001, 2002 Adam Wiggins <awiggins@cse.unsw.edu.au>
+********************************************************************************
+* Notes:
+*   - Even with processors that have 128 pids we might want to limit the
+*     relocation to the first 64 so we have seperate area's for the text,data,
+*     bss, stack, etc relocation and arch_get_unmapped_area() area's for
+*     non-MAP_FIXED mmap()'s
+*   - This is evily hardcoded anyway, really some arch specific mm code should
+*     do the initialision.
+********************************************************************************
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public Licence version 2 as
+* published by the Free Software Foundation.
+*******************************************************************************/
+
+#include <linux/mm.h>
+#include <asm/pgalloc.h>
+
+#include <asm/proc/pid.h>
+
+extern void dump_vma(struct mm_struct *mm_p);
+
+
+#if PID_SIMPLE
+/* The next PID to be allocated. Hack for now */
+static int next_pid_num = ARMPID_START;
+#endif
+
+/* Array of pid_structs for StrongARM's 64 pids */
+/* (Initialise at run time, depending on StrongARM or XSCALE) */
+
+static struct pid_struct pids[ARMPID_MAX] = {
+	{.number = 0, .mm_count = 0},
+	{.number = 1, .mm_count = 0},
+	{.number = 2, .mm_count = 0},
+	{.number = 3, .mm_count = 0},
+	{.number = 4, .mm_count = 0},
+	{.number = 5, .mm_count = 0},
+	{.number = 6, .mm_count = 0},
+	{.number = 7, .mm_count = 0},
+	{.number = 8, .mm_count = 0},
+	{.number = 9, .mm_count = 0},
+	{.number = 10, .mm_count = 0},
+	{.number = 11, .mm_count = 0},
+	{.number = 12, .mm_count = 0},
+	{.number = 13, .mm_count = 0},
+	{.number = 14, .mm_count = 0},
+	{.number = 15, .mm_count = 0},
+	{.number = 16, .mm_count = 0},
+	{.number = 17, .mm_count = 0},
+	{.number = 18, .mm_count = 0},
+	{.number = 19, .mm_count = 0},
+	{.number = 20, .mm_count = 0},
+	{.number = 21, .mm_count = 0},
+	{.number = 22, .mm_count = 0},
+	{.number = 23, .mm_count = 0},
+	{.number = 24, .mm_count = 0},
+	{.number = 25, .mm_count = 0},
+	{.number = 26, .mm_count = 0},
+	{.number = 27, .mm_count = 0},
+	{.number = 28, .mm_count = 0},
+	{.number = 29, .mm_count = 0},
+	{.number = 30, .mm_count = 0},
+	{.number = 31, .mm_count = 0},
+	{.number = 32, .mm_count = 0},
+	{.number = 33, .mm_count = 0},
+	{.number = 34, .mm_count = 0},
+	{.number = 35, .mm_count = 0},
+	{.number = 36, .mm_count = 0},
+	{.number = 37, .mm_count = 0},
+	{.number = 38, .mm_count = 0},
+	{.number = 39, .mm_count = 0},
+	{.number = 40, .mm_count = 0},
+	{.number = 41, .mm_count = 0},
+	{.number = 42, .mm_count = 0},
+	{.number = 43, .mm_count = 0},
+	{.number = 44, .mm_count = 0},
+	{.number = 45, .mm_count = 0},
+	{.number = 46, .mm_count = 0},
+	{.number = 47, .mm_count = 0},
+	{.number = 48, .mm_count = 0},
+	{.number = 49, .mm_count = 0},
+	{.number = 50, .mm_count = 0},
+	{.number = 51, .mm_count = 0},
+	{.number = 52, .mm_count = 0},
+	{.number = 53, .mm_count = 0},
+	{.number = 54, .mm_count = 0},
+	{.number = 55, .mm_count = 0},
+	{.number = 56, .mm_count = 0},
+	{.number = 57, .mm_count = 0},
+	{.number = 58, .mm_count = 0},
+	{.number = 59, .mm_count = 0},
+	{.number = 60, .mm_count = 0},
+	{.number = 61, .mm_count = 0},
+	{.number = 62, .mm_count = 0},
+	{.number = 63, .mm_count = 0},
+};
+
+
+/* arm_pid_allocate: Allocates an ARM PID to 'mm_p' address-space iff
+ *   the address-space is marked as relocatable. The location of the
+ *   stack dictates this relocatability. If the stack is within the
+ *   32MB relocation area the address-space will be allocated a ARM
+ *   PID, otherwise the zero PID.  If a pid is selected, two dummy,
+ *   that is unaccessable, vm_areas are added. The first covers the
+ *   32MB relocation synonym to stop that area from being
+ *   mmap()'able. The second tries to protection from the stack
+ *   overrunning into the bss segment or visa versa.  These dummy
+ *   va_areas are not copied by fork(). On fork(), a new PID will be
+ *   allocated as well as the new dummy vm_areas to go with it.
+ *
+ * Notes:
+
+ *   - This function is only called by
+ *     arch/arm/mmu_context.c:init_new_context() which is in turn called
+ *     by fs/exec.c:exec_mmap() and kernel/fork.c:copy_mm()
+
+ *   - fs/exec.c:exec_mmap() seems to have no way of indicating to
+ *     init_new_context()/allocate_pid() any information to decide if
+ *     a newly exec'ed process should have an ARM PID allocated or
+ *     not. We need some way to indicate to the STACK_TOP macro
+ *     whether a task should be relocated or not.
+ *
+ *   - Simply allocates ARM PIDs from 1 through to 63. A loop selects
+ *     a PID with the least count, that is least number of processes
+ *     allocated to it. This should be reexamined to see if a more
+ *     appropriate method is avaliable.  ie, we might want to make sure
+ *     on fork() that the new childs ARM PID is different to the parents
+ *     one.
+ */
+void
+arm_pid_allocate(struct task_struct *task_p, struct mm_struct *mm_p)
+{
+	int i;
+	int pid_num = 0;
+	unsigned long vm_flags;
+	struct vm_area_struct *vma_p;
+
+#if DEBUG_FASS
+	printk("** arm_pid_allocate: mm_p 0x%p vmas %d **\n", mm_p, mm_p->map_count);
+	dump_vma(mm_p);
+#endif
+#if PID_ENABLE
+	if (mm_p->start_stack > ARMPID_TASK_SIZE) { 
+		/* No pid allocated to parent */
+		goto allocate; /* so PID remains zero */
+	}
+
+#else
+	goto allocate;
+#endif
+
+	/* Select an ARM PID for allocation */
+#if PID_SIMPLE
+	/* Just round robin between the PIDs */
+	pid_num = next_pid_num;
+	next_pid_num = (next_pid_num >= (ARMPID_MAX - 1) ?
+			  ARMPID_START : next_pid_num + 1);
+#else
+	/* Select the PID with fewest users */
+	for (i = pid_num = 1; i < ARMPID_MAX; i++) {
+		if (pids[i].mm_count == 0) {
+			pid_num = i;
+			break;
+		}
+		if (pids[pid_num].mm_count > pids[i].mm_count) {
+			pid_num = i;
+		}
+	}
+#endif
+
+#ifdef DEBUG_FASS
+	printk("** arm_pid_allocate: about to mmap dummy regions **\n");
+#endif
+
+	/* Map 4KB dummy vma into area between stack and bss. */ 
+	vm_flags = VM_DONTEXPAND | VM_DONTCOPY; /* Stops fork copying */
+	vma_p = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+
+	fassert(vma_p);
+
+	down_write(&mm_p->mmap_sem);
+	vma_p->vm_mm = mm_p;
+	vma_p->vm_start = ARMPID_BRK_LIMIT;
+	vma_p->vm_end = ARMPID_BRK_LIMIT + PAGE_SIZE;
+	vma_p->vm_flags = vm_flags;
+	vma_p->vm_page_prot = protection_map[vm_flags & 0x0f];
+	vma_p->vm_ops = NULL;
+	vma_p->vm_pgoff = 0;
+	vma_p->vm_file = NULL;
+	vma_p->vm_private_data = NULL;
+	vma_p->vm_sharing_data = NULL;
+	vma_p->vm_raend = 0;
+
+	insert_vm_struct(mm_p, vma_p);
+	up_write(&mm_p->mmap_sem);
+
+	mm_p->total_vm++; /* Add a page */
+
+
+#ifdef DEBUG_FASS
+	printk("** arm_pid_allocate: Managed first mmap at 0x%lx **\n",
+		 ARMPID_TASK_SIZE - MEGABYTE(1));
+#endif
+	/* Map 32MB dummy vma into relocation point of addres-space */
+	vm_flags = VM_DONTEXPAND | VM_DONTCOPY; /* Stops fork copying */ 
+
+	vma_p = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+
+	fassert(vma_p);
+
+	down_write(&mm_p->mmap_sem);
+	vma_p->vm_mm = mm_p;
+	vma_p->vm_start = PIDNUM_TO_PID(pid_num);
+	vma_p->vm_end = vma_p->vm_start + ARMPID_TASK_SIZE;
+	vma_p->vm_flags = vm_flags;
+	vma_p->vm_page_prot = protection_map[vm_flags & 0x0f];
+	vma_p->vm_ops = NULL;
+	vma_p->vm_pgoff = 0;
+	vma_p->vm_file = NULL;
+	vma_p->vm_private_data = NULL;
+	vma_p->vm_sharing_data = NULL;
+	vma_p->vm_raend = 0;
+  
+	insert_vm_struct(mm_p, vma_p);
+	up_write(&mm_p->mmap_sem);
+
+	mm_p->total_vm += ARMPID_TASK_SIZE >> PAGE_SHIFT;
+
+#ifdef DEBUG_FASS
+	printk("** arm_pid_allocate: Managed second mmap at 0x%x**\n",
+		 PIDNUM_TO_PID(pid_num));
+#endif
+
+	/* Allocate ARM PID to address-space */
+allocate:
+
+	mm_p->context.pid_p = &pids[pid_num];
+	mm_p->context.pid = PIDNUM_TO_PID(pid_num);
+	pids[pid_num].mm_count++;
+  
+	if (current == task_p) { /* If this task is getting the new mm set pid */
+		set_armpid(mm_p->context.pid);  
+	}
+
+#ifdef DEBUG_FASS
+	printk("** arm_pid_allocate: allocated ARM PID %d to mm_p 0x%p**\n",
+	      PID_TO_PIDNUM(get_armpid()), mm_p);
+	dump_vma(mm_p);
+#endif
+}
+
+/* arm_pid_unallocate: Simply deallocates an ARM PID from an address space.
+ */
+void
+arm_pid_unallocate(struct pid_struct* pid_p)
+{
+	fassert(pid_p->mm_count > 0);
+	//printk("** arm_unallocate_pid: unallocating ARM PID %d **\n",
+	//	 PID_TO_PIDNUM(get_armpid()));
+
+	pid_p->mm_count--;
+
+	set_armpid(0x0);
+
+}
diff -urN linux-2.4.29/arch/arm/mm/proc-arm1020.S linux-2.4.29-uc1/arch/arm/mm/proc-arm1020.S
--- linux-2.4.29/arch/arm/mm/proc-arm1020.S	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/proc-arm1020.S	2005-06-14 02:10:59.000000000 +0100
@@ -65,18 +65,21 @@
  *
  * Returns:
  *  r0 = address of abort
- *  r1 != 0 if writing
- *  r3 = FSR
+ *  r1 = FSR
+ *  r3 = corrupted
  *  r4 = corrupted
  */
 	.align	5
 ENTRY(cpu_arm1020_data_abort)
-	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
+	mrc	p15, 0, r1, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
-	ldr	r1, [r2]			@ read aborted instruction
-	and	r3, r3, #255
-	tst	r1, r1, lsr #21 		@ C = bit 20
-	sbc	r1, r1, r1			@ r1 = C - 1
+	tst	r3, #PSR_T_BIT
+	ldrneh	r3, [r2]			@ read aborted thumb instruction
+	ldreq	r3, [r2]			@ read aborted ARM instruction
+	bic	r1, r1, #1 << 11 | 1 << 10	@ clear bits 11 and 10 of FSR
+	movne	r3, r3, lsl #(21 - 12)		@ move thumb bit 11 to ARM bit 20
+	tst	r3, #1 << 20			@ check write
+	orreq	r1, r1, #1 << 11
 	mov	pc, lr
 
 /*
@@ -170,10 +173,10 @@
 #endif
 	subs	r3, r3, #1
 	cmp	r3, #0
-	bge	2b				@ entries 3F to 0
+	bhs	2b				@ entries 3F to 0
 	subs	r1, r1, #1
 	cmp	r1, #0
-	bge	1b				@ segments 7 to 0
+	bhs	1b				@ segments 7 to 0
 #endif
         
 #ifndef CONFIG_CPU_ICACHE_DISABLE
@@ -201,7 +204,7 @@
 	bic	r0, r0, #DCACHELINESIZE - 1
 	sub	r3, r1, r0
 	cmp	r3, #MAX_AREA_SIZE
-	bgt	cpu_arm1020_cache_clean_invalidate_all_r2
+	bhi	cpu_arm1020_cache_clean_invalidate_all_r2
 	mcr	p15, 0, r3, c7, c10, 4
 #ifndef CONFIG_CPU_DCACHE_DISABLE
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
@@ -214,7 +217,7 @@
 #endif
 	add	r0, r0, #DCACHELINESIZE
 	cmp	r0, r1
-	blt	1b
+	blo	1b
 #endif
 
 #ifndef CONFIG_CPU_ICACHE_DISABLE
@@ -302,7 +305,7 @@
 #endif
 	add	r0, r0, #DCACHELINESIZE
 	cmp	r0, r1
-	blt	1b
+	blo	1b
 #else
 	/* D cache off, but still drain the write buffer */
 	mcr	p15, 0, r0, c7, c10, 4		@ Drain write buffer
@@ -328,7 +331,7 @@
 	bic	r0, r0, #DCACHELINESIZE - 1
 	sub	r3, r1, r0
 	cmp	r3, #MAX_AREA_SIZE
-	bgt	cpu_arm1020_cache_clean_invalidate_all_r2
+	bhi	cpu_arm1020_cache_clean_invalidate_all_r2
 	mcr	p15, 0, r3, c7, c10, 4
 #ifndef CONFIG_CPU_DCACHE_DISABLE
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
@@ -341,7 +344,7 @@
 #endif
 	add	r0, r0, #DCACHELINESIZE
 	cmp	r0, r1
-	blt	1b
+	blo	1b
 #endif
 
 #ifndef CONFIG_CPU_BPREDICT_DISABLE
@@ -488,7 +491,7 @@
 	mov	r0, r0
 #endif
 	cmp	r0, r1
-	blt	1b
+	blo	1b
 	mov	pc, lr
 
 /*
@@ -541,10 +544,10 @@
 #endif
 	subs	r3, r3, #1
 	cmp	r3, #0
-	bge	2b				@ entries 3F to 0
+	bhs	2b				@ entries 3F to 0
 	subs	r1, r1, #1
 	cmp	r1, #0
-	bge	1b				@ segments 15 to 0
+	bhs	1b				@ segments 15 to 0
 
 #endif
 	mov	r1, #0
@@ -603,7 +606,7 @@
 	bic	r2, r2, #3
 	orr	r2, r2, #HPTE_TYPE_SMALL
 
-	tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+	tst	r1, #LPTE_USER			@ User?
 	orrne	r2, r2, #HPTE_AP_READ
 
 	tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
diff -urN linux-2.4.29/arch/arm/mm/proc-arm1026.S linux-2.4.29-uc1/arch/arm/mm/proc-arm1026.S
--- linux-2.4.29/arch/arm/mm/proc-arm1026.S	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/proc-arm1026.S	2005-06-14 02:10:59.000000000 +0100
@@ -66,15 +66,17 @@
  *
  * Returns:
  *  r0 = address of abort
- *  r1 != 0 if writing
- *  r3 = FSR
+ *  r1 = FSR, bit 11 set if writing
+ *  r3 = corrupted
  *  r4 = corrupted
  */
 	.align	5
 ENTRY(cpu_arm1026_data_abort)
-	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
-	and	r2, r3, #0b1101			@ Check for translation error
-	sub	r1, r2, #0b0101
+	mrc	p15, 0, r1, c5, c0, 0		@ get FSR
+	bic	r1, r1, #1 << 11 | 1 << 10
+	and	r2, r1, #0b1101			@ Check for translation error
+	teq	r1, r2, #0b1101
+	orrne	r1, r1, #1 << 11		@ set write bit
 
 	and	r3, r3, #255
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
@@ -494,7 +496,7 @@
 	bic	r2, r2, #3
 	orr	r2, r2, #HPTE_TYPE_SMALL
 
-	tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+	tst	r1, #LPTE_USER			@ User?
 	orrne	r2, r2, #HPTE_AP_READ
 
 	tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
diff -urN linux-2.4.29/arch/arm/mm/proc-arm6,7.S linux-2.4.29-uc1/arch/arm/mm/proc-arm6,7.S
--- linux-2.4.29/arch/arm/mm/proc-arm6,7.S	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/proc-arm6,7.S	2005-06-14 02:10:59.000000000 +0100
@@ -33,12 +33,12 @@
 ENTRY(cpu_arm7_icache_invalidate_range)
 ENTRY(cpu_arm6_icache_invalidate_page)
 ENTRY(cpu_arm7_icache_invalidate_page)
-ENTRY(cpu_arm6_dcache_clean_range)
-ENTRY(cpu_arm7_dcache_clean_range)
 ENTRY(cpu_arm6_dcache_invalidate_range)
 ENTRY(cpu_arm7_dcache_invalidate_range)
 		mov	r0, #0
 		mcr	p15, 0, r0, c7, c0, 0		@ flush cache
+ENTRY(cpu_arm6_dcache_clean_range)
+ENTRY(cpu_arm7_dcache_clean_range)
 ENTRY(cpu_arm6_dcache_clean_page)
 ENTRY(cpu_arm7_dcache_clean_page)
 ENTRY(cpu_arm6_dcache_clean_entry)
@@ -72,7 +72,7 @@
 1:		mcr	p15, 0, r0, c6, c0, 0		@ purge TLB
 		add	r0, r0, #4096
 		cmp	r0, r1
-		blt	1b
+		blo	1b
 		mov	pc, lr
 
 ENTRY(cpu_arm7_tlb_invalidate_range)
@@ -81,11 +81,11 @@
 		mcr	p15, 0, r0, c5, c0, 0		@ flush TLB
 		mov	pc, lr
 #else
-                @ arm 7 tbl purge reg is bits 14 - 31
+                @ arm 7 tbl purge reg is bits 12 - 31
 1:		mcr	p15, 0, r0, c6, c0, 0		@ purge TLB
-		add	r0, r0, #0x4000
+		add	r0, r0, #0x1000
 		cmp	r0, r1
-		blt	1b
+		blo	1b
 		mov	pc, lr
 #endif
 
@@ -110,15 +110,13 @@
  * Purpose : obtain information about current aborted instruction
  *
  * Returns : r0 = address of abort
- *	   : r1 != 0 if writing
- *	   : r3 = FSR
+ *	   : r1 = FSR, bit 11 set if writing
+ *	   : r3 = corrupted
  *	   : sp = pointer to registers
  */
 
 ENTRY(cpu_arm6_data_abort)
 		ldr	r4, [r0]			@ read instruction causing problem
-		tst	r4, r4, lsr #21			@ C = bit 20
-		sbc	r1, r1, r1			@ r1 = C - 1
 		and	r2, r4, #14 << 24
 		teq	r2, #8 << 24			@ was it ldm/stm
 		bne	Ldata_simple
@@ -144,14 +142,14 @@
 		addeq	r7, r0, r7, lsl #2		@ Do correction (signed)
 Ldata_saver7:	str	r7, [sp, r5, lsr #14]		@ Put register
 Ldata_simple:	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
-		mrc	p15, 0, r3, c5, c0, 0		@ get FSR
-		and	r3, r3, #255
+		mrc	p15, 0, r1, c5, c0, 0		@ get FSR
+		bic	r1, r1, #1 << 11 | 1 << 10
+		tst	r4, #1 << 20
+		orreq	r1, r1, #1 << 11
 		mov	pc, lr
 
 ENTRY(cpu_arm7_data_abort)
 		ldr	r4, [r0]			@ read instruction causing problem
-		tst	r4, r4, lsr #21			@ C = bit 20
-		sbc	r1, r1, r1			@ r1 = C - 1
 		and	r2, r4, #15 << 24
 		add	pc, pc, r2, lsr #22		@ Now branch to the relevent processing routine
 		movs	pc, lr
@@ -268,6 +266,7 @@
 		msr	cpsr_c, r0
 		mov	r0, #0x31			@ ....S..DP...M
 		mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+		mcr	p15, 0, r0, c7, c0, 0		@ invalidate cache
 		mov	pc, lr
 
 ENTRY(cpu_arm6_do_idle)
@@ -336,7 +335,7 @@
 		bic	r2, r2, #3
 		orr	r2, r2, #HPTE_TYPE_SMALL
 
-		tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+		tst	r1, #LPTE_USER			@ User?
 		orrne	r2, r2, #HPTE_AP_READ
 
 		tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
diff -urN linux-2.4.29/arch/arm/mm/proc-arm720.S linux-2.4.29-uc1/arch/arm/mm/proc-arm720.S
--- linux-2.4.29/arch/arm/mm/proc-arm720.S	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/proc-arm720.S	2005-06-14 02:10:59.000000000 +0100
@@ -59,7 +59,6 @@
 ENTRY(cpu_arm720_dcache_invalidate_range)
 		mov	r0, #0
 		mcr	p15, 0, r0, c7, c7, 0		@ flush cache
-		mov	pc, lr
 
 /*
  * These just expect cache lines to be cleaned.  Since we have a writethrough
@@ -97,7 +96,7 @@
 1:		mcr	p15, 0, r0, c8, c7, 1		@ flush TLB (v4)
 		add	r0, r0, #PAGESIZE
 		cmp	r0, r1
-		blt	1b
+		blo	1b
 		mov	pc, lr
 
 /*
@@ -124,8 +123,8 @@
  * picture.  Unfortunately, this does happen.  We live with it.
  *
  * Returns : r0 = address of abort
- *	   : r1 != 0 if writing
- *	   : r3 = FSR
+ *	   : r1 = FSR, bit 11 set if writing
+ *	   : r3 = corrupted
  *	   : sp = pointer to registers
  */
 
@@ -150,16 +149,16 @@
 		addeq	r7, r0, r7, lsl #2		@ Do correction (signed)
 Ldata_saver7:	str	r7, [sp, r5, lsr #14]		@ Put register
 Ldata_simple:	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
-		mrc	p15, 0, r3, c5, c0, 0		@ get FSR
-		and	r3, r3, #255
+		mrc	p15, 0, r1, c5, c0, 0		@ get FSR
+		bic	r1, r1, #1 << 11 | 1 << 10
+		tst	r4, #1 << 20
+		orreq	r1, r1, #1 << 11
 		mov	pc, lr
 
 ENTRY(cpu_arm720_data_abort)
-		tst	r3, #T_BIT
+		tst	r3, #PSR_T_BIT
 		bne	.data_thumb_abort
 		ldr	r4, [r0]			@ read instruction causing problem
-		tst	r4, r4, lsr #21			@ C = bit 20
-		sbc	r1, r1, r1			@ r1 = C - 1
 		and	r2, r4, #15 << 24
 		add	pc, pc, r2, lsr #22		@ Now branch to the relevent processing routine
 		movs	pc, lr
@@ -271,8 +270,8 @@
 
 .data_thumb_abort:
 		ldrh	r4, [r0]			@ read instruction
-		tst	r4, r4, lsr #12			@ C = bit 11
-		sbc	r1, r1, r1			@ r1 = C - 1
+		tst	r4, #1 << 11
+		orrne	r4, r4, #1 << 20
 		and	r2, r4, #15 << 12
 		add	pc, pc, r2, lsr #10		@ lookup in table
 		nop
@@ -418,7 +417,7 @@
 		bic	r2, r2, #3
 		orr	r2, r2, #HPTE_TYPE_SMALL
 
-		tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+		tst	r1, #LPTE_USER			@ User?
 		orrne	r2, r2, #HPTE_AP_READ
 
 		tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
diff -urN linux-2.4.29/arch/arm/mm/proc-arm920.S linux-2.4.29-uc1/arch/arm/mm/proc-arm920.S
--- linux-2.4.29/arch/arm/mm/proc-arm920.S	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/proc-arm920.S	2005-06-14 02:10:59.000000000 +0100
@@ -71,12 +71,16 @@
  */
 	.align	5
 ENTRY(cpu_arm920_data_abort)
-	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
+	mrc	p15, 0, r1, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
-	ldr	r1, [r2]			@ read aborted instruction
-	and	r3, r3, #255
-	tst	r1, r1, lsr #21			@ C = bit 20
-	sbc	r1, r1, r1			@ r1 = C - 1
+
+	tst	r3, #PSR_T_BIT
+	ldrneh	r3, [r2]			@ read aborted thumb instruction
+	ldreq	r3, [r2]			@ read aborted ARM instruction
+	bic	r1, r1, #1 << 11 | 1 << 10	@ clear bits 11 and 10 of FSR
+	movne	r3, r3, lsl #(21 - 12)		@ move thumb bit 11 to ARM bit 20
+	tst	r3, #1 << 20			@ check write
+	orreq	r1, r1, #1 << 11
 	mov	pc, lr
 	
 /*
@@ -189,7 +193,7 @@
 	bic	r1, r1, #DCACHELINESIZE - 1     @ && added by DHM
 	sub	r3, r1, r0
 	cmp	r3, #MAX_AREA_SIZE
-	bgt	cpu_arm920_cache_clean_invalidate_all_r2
+	bhi	cpu_arm920_cache_clean_invalidate_all_r2
 1:	teq	r2, #0
 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
@@ -207,7 +211,7 @@
 	add	r0, r0, #DCACHELINESIZE
 #endif
 	cmp	r0, r1
-	blt	1b
+	blo	1b
 
 	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
 	mov	pc, lr
@@ -264,7 +268,7 @@
 1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	add	r0, r0, #DCACHELINESIZE
 	cmp	r0, r1
-	blt	1b
+	blo	1b
 	mov	pc, lr
 
 /*
@@ -284,7 +288,7 @@
 	sub	r1, r1, r0
 	cmp	r1, #MAX_AREA_SIZE
 	mov	r2, #0
-	bgt	cpu_arm920_cache_clean_invalidate_all_r2
+	bhi	cpu_arm920_cache_clean_invalidate_all_r2
 
 	bic	r1, r1, #DCACHELINESIZE -1
 	add	r1, r1, #DCACHELINESIZE
@@ -365,7 +369,7 @@
 	bic	r0, r0, #ICACHELINESIZE - 1	@ Safety check
 	sub	r1, r1, r0
 	cmp	r1, #MAX_AREA_SIZE
-	bgt	cpu_arm920_cache_clean_invalidate_all_r2
+	bhi	cpu_arm920_cache_clean_invalidate_all_r2
 
 	bic	r1, r1, #ICACHELINESIZE - 1
 	add	r1, r1, #ICACHELINESIZE
@@ -424,7 +428,7 @@
 	mcr	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
 	add	r0, r0, #PAGESIZE
 	cmp	r0, r1
-	blt	1b
+	blo	1b
 	mov	pc, lr
 
 /*
@@ -457,7 +461,6 @@
 ENTRY(cpu_arm920_set_pgd)
 	mov	ip, #0
 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	/* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */
 	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
 #else
 @ && 'Clean & Invalidate whole DCache'
@@ -514,7 +517,7 @@
 	bic	r2, r2, #3
 	orr	r2, r2, #HPTE_TYPE_SMALL
 
-	tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+	tst	r1, #LPTE_USER			@ User or Exec?
 	orrne	r2, r2, #HPTE_AP_READ
 
 	tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
diff -urN linux-2.4.29/arch/arm/mm/proc-arm922.S linux-2.4.29-uc1/arch/arm/mm/proc-arm922.S
--- linux-2.4.29/arch/arm/mm/proc-arm922.S	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/proc-arm922.S	2005-06-14 02:10:59.000000000 +0100
@@ -62,17 +62,20 @@
  *
  * Returns:
  *  r0 = address of abort
- *  r1 != 0 if writing
- *  r3 = FSR
+ *  r1 = FSR, bit 11 set if writing
+ *  r3 = corrupted
  */
 	.align	5
 ENTRY(cpu_arm922_data_abort)
-	ldr	r1, [r0]			@ read aborted instruction
+	mrc	p15, 0, r1, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
-	tst	r1, r1, lsr #21			@ C = bit 20
-	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
-	sbc	r1, r1, r1			@ r1 = C - 1
-	and	r3, r3, #255
+	tst	r3, #PSR_T_BIT
+	ldrneh	r3, [r2]			@ read aborted thumb instruction
+	ldreq	r3, [r2]			@ read aborted ARM instruction
+	bic	r1, r1, #1 << 11 | 1 << 10	@ clear bits 11 and 10 of FSR
+	movne	r3, r3, lsl #(21 - 12)		@ move thumb bit 11 to ARM bit 20
+	tst	r3, #1 << 20			@ check write
+	orreq	r1, r1, #1 << 11
 	mov	pc, lr
 	
 /*
@@ -185,7 +188,7 @@
 	bic	r1, r1, #DCACHELINESIZE - 1     @ && added by DHM
 	sub	r3, r1, r0
 	cmp	r3, #MAX_AREA_SIZE
-	bgt	cpu_arm922_cache_clean_invalidate_all_r2
+	bhi	cpu_arm922_cache_clean_invalidate_all_r2
 1:	teq	r2, #0
 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
@@ -203,7 +206,7 @@
 	add	r0, r0, #DCACHELINESIZE
 #endif
 	cmp	r0, r1
-	blt	1b
+	blo	1b
 
 	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
 	mov	pc, lr
@@ -260,7 +263,7 @@
 1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	add	r0, r0, #DCACHELINESIZE
 	cmp	r0, r1
-	blt	1b
+	blo	1b
 	mov	pc, lr
 
 /*
@@ -280,7 +283,7 @@
 	sub	r1, r1, r0
 	cmp	r1, #MAX_AREA_SIZE
 	mov	r2, #0
-	bgt	cpu_arm922_cache_clean_invalidate_all_r2
+	bhi	cpu_arm922_cache_clean_invalidate_all_r2
 
 	bic	r1, r1, #DCACHELINESIZE -1
 	add	r1, r1, #DCACHELINESIZE
@@ -361,7 +364,7 @@
 	bic	r0, r0, #ICACHELINESIZE - 1	@ Safety check
 	sub	r1, r1, r0
 	cmp	r1, #MAX_AREA_SIZE
-	bgt	cpu_arm922_cache_clean_invalidate_all_r2
+	bhi	cpu_arm922_cache_clean_invalidate_all_r2
 
 	bic	r1, r1, #ICACHELINESIZE - 1
 	add	r1, r1, #ICACHELINESIZE
@@ -420,7 +423,7 @@
 	mcr	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
 	add	r0, r0, #PAGESIZE
 	cmp	r0, r1
-	blt	1b
+	blo	1b
 	mov	pc, lr
 
 /*
@@ -510,7 +513,7 @@
 	bic	r2, r2, #3
 	orr	r2, r2, #HPTE_TYPE_SMALL
 
-	tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+	tst	r1, #LPTE_USER			@ User?
 	orrne	r2, r2, #HPTE_AP_READ
 
 	tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
diff -urN linux-2.4.29/arch/arm/mm/proc-arm925.S linux-2.4.29-uc1/arch/arm/mm/proc-arm925.S
--- linux-2.4.29/arch/arm/mm/proc-arm925.S	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/proc-arm925.S	2005-06-14 02:10:59.000000000 +0100
@@ -69,24 +69,24 @@
  *
  * Returns:
  *  r0 = address of abort
- *  r1 != 0 if writing
- *  r3 = FSR
+ *  r1 = FSR, bit 11 set if writing
+ *  r3 = corrupted
  *  r4 = corrupted
  */
 	.align	5
 ENTRY(cpu_arm925_data_abort)
+	mrc	p15, 0, r1, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
-	mrc	p15, 0, r4, c5, c0, 0		@ get FSR
-
-	tst	r3, #1<<5			@ Check for Thumb-bit (NE -> found)
-	ldrneh	r1, [r2]			@ Read aborted Thumb instruction
-	tstne	r1, r1, lsr #12 		@ C = bit 11
-
-	ldreq	r1, [r2]			@ Read aborted ARM instruction
-	tsteq	r1, r1, lsr #21 		@ C = bit 20
-
-	sbc	r1, r1, r1			@ r1 = C - 1
-	and	r3, r4, #255
+	bic	r1, r1, #1 << 11 | 1 << 10	@ clear bits 11 and 10 of FSR
+	tst	r3, #PSR_J_BIT			@ Java?
+	orrne	r1, r1, #1 << 11		@ always assume write
+	movne	pc, lr
+	tst	r3, #PSR_T_BIT			@ Thumb?
+	ldrneh	r3, [r2]			@ read aborted thumb instruction
+	ldreq	r3, [r2]			@ read aborted ARM instruction
+	movne	r3, r3, lsl #(21 - 12)		@ move thumb bit 11 to ARM bit 20
+	tst	r3, #1 << 20			@ L = 0 -> write
+	orreq	r1, r1, #1 << 11		@ yes.
 	mov	pc, lr
 
 /*
@@ -207,7 +207,7 @@
 	bic	r1, r1, #DCACHELINESIZE - 1     @ && added by DHM
 	sub	r3, r1, r0
 	cmp	r3, #MAX_AREA_SIZE
-	bgt	cpu_arm925_cache_clean_invalidate_all_r2
+	bhi	cpu_arm925_cache_clean_invalidate_all_r2
 1:	teq	r2, #0
 #ifdef CONFIG_CPU_ARM925_WRITETHROUGH
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
@@ -225,7 +225,7 @@
 	add	r0, r0, #DCACHELINESIZE
 #endif
 	cmp	r0, r1
-	blt	1b
+	blo	1b
 
 	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
 	mov	pc, lr
@@ -282,7 +282,7 @@
 1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	add	r0, r0, #DCACHELINESIZE
 	cmp	r0, r1
-	blt	1b
+	blo	1b
 	mov	pc, lr
 
 /*
@@ -302,7 +302,7 @@
 	sub	r1, r1, r0
 	cmp	r1, #MAX_AREA_SIZE
 	mov	r2, #0
-	bgt	cpu_arm925_cache_clean_invalidate_all_r2
+	bhi	cpu_arm925_cache_clean_invalidate_all_r2
 
 	bic	r1, r1, #DCACHELINESIZE -1
 	add	r1, r1, #DCACHELINESIZE
@@ -383,7 +383,7 @@
 	bic	r0, r0, #ICACHELINESIZE - 1	@ Safety check
 	sub	r1, r1, r0
 	cmp	r1, #MAX_AREA_SIZE
-	bgt	cpu_arm925_cache_clean_invalidate_all_r2
+	bhi	cpu_arm925_cache_clean_invalidate_all_r2
 
 	bic	r1, r1, #ICACHELINESIZE - 1
 	add	r1, r1, #ICACHELINESIZE
@@ -443,7 +443,7 @@
 	mcr	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
 	add	r0, r0, #PAGESIZE
 	cmp	r0, r1
-	blt	1b
+	blo	1b
 	mov	pc, lr
 
 /*
@@ -532,7 +532,7 @@
 	bic	r2, r2, #3
 	orr	r2, r2, #HPTE_TYPE_SMALL
 
-	tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+	tst	r1, #LPTE_USER			@ User?
 	orrne	r2, r2, #HPTE_AP_READ
 
 	tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
diff -urN linux-2.4.29/arch/arm/mm/proc-arm926.S linux-2.4.29-uc1/arch/arm/mm/proc-arm926.S
--- linux-2.4.29/arch/arm/mm/proc-arm926.S	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/proc-arm926.S	2005-06-14 02:10:59.000000000 +0100
@@ -66,28 +66,24 @@
  *
  * Returns:
  *  r0 = address of abort
- *  r1 != 0 if writing
- *  r3 = FSR
+ *  r1 = FSR, bit 11 set if writing
+ *  r3 = corrupted
  *  r4 = corrupted
  */
 	.align	5
 ENTRY(cpu_arm926_data_abort)
+	mrc	p15, 0, r1, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
-	mrc	p15, 0, r4, c5, c0, 0		@ get FSR
-
-	tst	r3, #1<<24			@ Check for Jbit (NE -> found)
-	movne	r3, #-1 			@ Mark as writing
-	bne	2f
-
-	tst	r3, #1<<5			@ Check for Thumb-bit (NE -> found)
-	ldrneh	r1, [r2]			@ Read aborted Thumb instruction        
-	ldreq	r1, [r2]			@ Read aborted ARM instruction
-	movne	r1, r1, lsl #(20-12)		@ shift thumb bit 10 to ARM bit 20
-	tsteq	r1, r1, lsr #21 		@ C = bit 20
-
-	sbc	r1, r1, r1			@ r1 = C - 1
-2:
-	and	r3, r4, #255
+	bic	r1, r1, #1 << 11 | 1 << 10	@ clear bits 11 and 10 of FSR
+	tst	r3, #PSR_J_BIT			@ Java?
+	orrne	r1, r1, #1 << 11		@ always assume write
+	movne	pc, lr
+	tst	r3, #PSR_T_BIT			@ Thumb?
+	ldrneh	r3, [r2]			@ read aborted thumb instruction
+	ldreq	r3, [r2]			@ read aborted ARM instruction
+	movne	r3, r3, lsl #(21 - 12)		@ move thumb bit 11 to ARM bit 20
+	tst	r3, #1 << 20			@ L = 0 -> write
+	orreq	r1, r1, #1 << 11		@ yes.
 	mov	pc, lr
 
 /*
@@ -503,7 +499,7 @@
 	bic	r2, r2, #3
 	orr	r2, r2, #HPTE_TYPE_SMALL
 
-	tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+	tst	r1, #LPTE_USER			@ User?
 	orrne	r2, r2, #HPTE_AP_READ
 
 	tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
diff -urN linux-2.4.29/arch/arm/mm/proc-sa110.S linux-2.4.29-uc1/arch/arm/mm/proc-sa110.S
--- linux-2.4.29/arch/arm/mm/proc-sa110.S	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/proc-sa110.S	2005-06-14 02:10:59.000000000 +0100
@@ -551,7 +551,7 @@
 	bic	r2, r2, #3
 	orr	r2, r2, #HPTE_TYPE_SMALL
 
-	tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+	tst	r1, #LPTE_USER			@ User?
 	orrne	r2, r2, #HPTE_AP_READ
 
 	tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
@@ -573,6 +573,8 @@
 	.asciz	"StrongARM-1100"
 cpu_sa1110_name:
 	.asciz	"StrongARM-1110"
+cpu_ixp1200_name:
+	.asciz	"IXP12xx"
 	.align
 
 	.section ".text.init", #alloc, #execinstr
@@ -699,6 +701,11 @@
 	.long	cpu_sa1110_name
 	.size	cpu_sa1110_info, . - cpu_sa1110_info
 
+cpu_ixp1200_info:
+	.long	0
+	.long	cpu_ixp1200_name
+	.size	cpu_ixp_1200_info, . - cpu_ixp1200_info
+
 	.type	cpu_arch_name, #object
 cpu_arch_name:
 	.asciz	"armv4"
@@ -750,3 +757,16 @@
 	.long	cpu_sa1110_info
 	.long	sa1100_processor_functions
 	.size	__sa1110_proc_info, . - __sa1110_proc_info
+
+	.type	__ixp1200_proc_info,#object
+__ixp1200_proc_info:
+	.long	0x6901c120
+	.long	0xfffffff0
+	.long	0x00000c0e
+	b	__sa110_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
+	.long	cpu_ixp1200_info
+	.long	sa110_processor_functions
+	.size	__ixp1200_proc_info, . - __ixp1200_proc_info
diff -urN linux-2.4.29/arch/arm/mm/proc-xscale.S linux-2.4.29-uc1/arch/arm/mm/proc-xscale.S
--- linux-2.4.29/arch/arm/mm/proc-xscale.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/proc-xscale.S	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,1176 @@
+/*
+ *  linux/arch/arm/mm/proc-xscale.S
+ *
+ *  Author:	Nicolas Pitre
+ *  Created:	November 2000
+ *  Copyright:	(C) 2000, 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * MMU functions for the Intel XScale CPUs
+ *
+ * 2001 Aug 21:	
+ *	some contributions by Brett Gaines <brett.w.gaines@intel.com>
+ *	Copyright 2001 by Intel Corp.
+ *
+ * 2001 Sep 08:
+ *	Completely revisited, many important fixes
+ *	Nicolas Pitre <nico@cam.org>
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+#include <asm/hardware.h>
+#include <asm/proc/pgtable.h>
+
+/*
+ * Some knobs for cache allocation policy.
+ * Allocate on write may or may not be beneficial depending on the memory
+ * usage pattern of your main application.  Write through cache is definitely
+ * a performance loss in most cases, but might be used for special purposes.
+ */
+#ifdef CONFIG_XSCALE_XBIT
+#define PMD_CACHE_WRITE_ALLOCATE 1
+#define PTE_CACHE_WRITE_ALLOCATE 1
+#else
+#define PMD_CACHE_WRITE_ALLOCATE 0
+#define PTE_CACHE_WRITE_ALLOCATE 0
+#endif
+
+#define CACHE_WRITE_THROUGH 0
+
+/*
+ * Ther are errata that says that dirty status bits in the cache may get
+ * corrupted.  The workaround significantly affects performances, and the bug
+ * _might_ just not be that visible or critical to you, so it is configurable.
+ * Let's hope a future core revision will tell us this was only a bad dream.
+ * But in the mean time the risk and tradeoff is yours to decide....
+ */
+#ifdef CONFIG_XSCALE_CACHE_ERRATA
+#undef CACHE_WRITE_THROUGH
+#define CACHE_WRITE_THROUGH 1
+#endif
+
+/* 
+ * This is the maximum size of an area which will be flushed.  If the area
+ * is larger than this, then we flush the whole cache
+ */
+#define MAX_AREA_SIZE	32768
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define CACHELINESIZE	32
+
+/*
+ * the size of the data cache
+ */
+#define CACHESIZE	32768
+
+/*
+ * and the page size
+ */
+#define PAGESIZE	4096
+
+/*
+ * Virtual address used to allocate the cache when flushed
+ *
+ * This must be an address range which is _never_ used.  It should 
+ * apparently have a mapping in the corresponding page table for 
+ * compatibility with future CPUs that _could_ require it.  For instance we
+ * don't care.
+ *
+ * This must be aligned on a 2*CACHESIZE boundary.  The code selects one of
+ * the 2 areas in alternance each time the clean_d_cache macro is used.
+ * Without this the XScale core exhibits cache eviction problems and no one
+ * knows why.  
+ *
+ * Reminder: the vector table is located at 0xffff0000-0xffff0fff.
+ */
+#define CLEAN_ADDR	0xfffe0000
+
+/*
+ * This macro is used to wait for a CP15 write and is needed
+ * when we have to ensure that the last operation to the co-pro
+ * was completed before continuing with operation.
+ */
+	.macro	cpwait, rd
+	mrc	p15, 0, \rd, c2, c0, 0		@ arbitrary read of cp15
+	mov	\rd, \rd			@ wait for completion
+	sub 	pc, pc, #4			@ flush instruction pipeline
+	.endm	
+
+	.macro	cpwait_ret, lr, rd
+	mrc	p15, 0, \rd, c2, c0, 0		@ arbitrary read of cp15
+	sub	pc, \lr, \rd, LSR #32		@ wait for completion and
+						@ flush instruction pipeline
+	.endm
+
+#if !CACHE_WRITE_THROUGH
+
+/*
+ * This macro cleans the entire dcache using line allocate.
+ * The main loop has been unrolled to reduce loop overhead.
+ * rd and rs are two scratch registers.
+ */
+	.macro  clean_d_cache, rd, rs
+	ldr	\rs, =clean_addr
+	ldr	\rd, [\rs]
+	eor	\rd, \rd, #CACHESIZE
+	str	\rd, [\rs]
+	add	\rs, \rd, #CACHESIZE
+1:	mcr	p15, 0, \rd, c7, c2, 5		@ allocate D cache line
+	add	\rd, \rd, #CACHELINESIZE
+	mcr	p15, 0, \rd, c7, c2, 5		@ allocate D cache line
+	add	\rd, \rd, #CACHELINESIZE
+	mcr	p15, 0, \rd, c7, c2, 5		@ allocate D cache line
+	add	\rd, \rd, #CACHELINESIZE
+	mcr	p15, 0, \rd, c7, c2, 5		@ allocate D cache line
+	add	\rd, \rd, #CACHELINESIZE
+	teq	\rd, \rs
+	bne	1b
+	.endm
+
+	.macro	clean_d_line,	rd
+	mcr	p15, 0, \rd, c7, c10, 1
+	.endm
+
+	.data
+clean_addr:	.word	CLEAN_ADDR
+
+#else
+
+/*
+ * If cache is write-through, there is no need to clean it.
+ * Simply invalidating will do.
+ */
+
+	.macro  clean_d_cache, rd, rs
+	mcr	p15, 0, \rd, c7, c6, 0
+	.endm
+
+	/* let's try to skip this needless operations at least within loops */
+	.macro	clean_d_line,	rd
+	.endm
+
+#endif
+
+	.text
+
+/*
+ * cpu_xscale_data_abort()
+ *
+ * obtain information about current aborted instruction.
+ * Note: we read user space.  This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture.  Unfortunately, this does happen.  We live with it.
+ *
+ *  r2 = address of aborted instruction
+ *  r3 = cpsr
+ *
+ * Returns:
+ *  r0 = address of abort
+ *  r1 != 0 if writing
+ *  r3 = FSR
+ *  r4 = corrupted
+ */
+	.align	5
+ENTRY(cpu_xscale_data_abort)
+	mrc     p15, 0, r1, c5, c0, 0           @ get FSR
+	mrc     p15, 0, r0, c6, c0, 0           @ get FAR
+	ldr     r3, [r2]                        @ read aborted instruction
+	bic     r1, r1, #1 << 11		@ clear bits 11 and 10 of FSR
+	tst     r3, #1 << 20                    @ C = bit 20
+	orreq   r1, r1, #1 << 11
+	mov     pc, lr
+
+/*
+ * cpu_xscale_check_bugs()
+ */
+ENTRY(cpu_xscale_check_bugs)
+	mrs	ip, cpsr
+	bic	ip, ip, #F_BIT
+	msr	cpsr, ip
+	mov	pc, lr
+
+#ifndef CONFIG_XSCALE_CACHE_ERRATA
+/*
+ * cpu_xscale_proc_init()
+ *
+ * Nothing too exciting at the moment
+ */
+ENTRY(cpu_xscale_proc_init)
+	mov	pc, lr
+#else
+/*
+ * We enable the cache here, but we make sure all the status bits for dirty
+ * lines are cleared as well (see PXA250 erratum #120).
+ */
+ENTRY(cpu_xscale_proc_init)
+	@ enable data cache
+	ldr	r0, cr_p
+	ldmia	r0, {r1, r2}
+	orr	r1, r1, #0x4
+	orr	r2, r2, #0x4
+	stmia	r0, {r1, r2}
+	mcr	p15, 0, r1, c1, c0, 0
+	cpwait	r0
+
+	@ invalidate data cache
+	mcr	p15, 0, r0, c7, c6, 0
+
+	@ fill main cache with write-through lines
+	bic	r0, pc, #0x1f
+	add	r1, r0, #CACHESIZE
+1:	ldr	r2, [r0], #32
+	cmp	r0, r1
+	bne	1b
+
+	@ enable test feature to force all fills to the mini-cache
+	mov	r1, #0x8
+	mcr	p15, 0, r1, c15, c15, 3
+
+	@ fill mini-cache with write-through lines (2kbytes, 64 lines)
+	add	r1, r0, #2048
+2:	ldr	r2, [r0], #32
+	cmp	r0, r1
+	bne	2b
+
+	@ disable test feature to force all fills to the mini-cache
+	mov	r1, #0x0
+	mcr	p15, 0, r1, c15, c15, 3
+
+	@ invalidate data cache again
+	mcr	p15, 0, r1, c7, c6, 0
+	mov	pc, lr
+
+cr_p:	.long	SYMBOL_NAME(cr_alignment)
+#endif
+
+/*
+ * cpu_xscale_proc_fin()
+ */
+ENTRY(cpu_xscale_proc_fin)
+	str	lr, [sp, #-4]!
+	mov	r0, #F_BIT|I_BIT|SVC_MODE
+	msr	cpsr_c, r0
+	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
+	bic	r0, r0, #0x1800			@ ...IZ...........
+	bic	r0, r0, #0x0006			@ .............CA.
+	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+	bl	cpu_xscale_cache_clean_invalidate_all	@ clean caches
+	ldr	pc, [sp], #4
+
+/*
+ * cpu_xscale_reset(loc)
+ *
+ * Perform a soft reset of the system.  Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+	.align	5
+ENTRY(cpu_xscale_reset)
+	mov	r1, #F_BIT|I_BIT|SVC_MODE
+	msr	cpsr_c, r1			@ reset CPSR
+	mrc	p15, 0, r1, c1, c0, 0		@ ctrl register
+	bic	r1, r1, #0x0086			@ ........B....CA.
+	bic	r1, r1, #0x3900			@ ...IZ..S........
+	mcr	p15, 0, r1, c1, c0, 0		@ ctrl register
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches & BTB
+	bic	r1, r1, #0x0001			@ ...............M
+	mcr	p15, 0, r1, c1, c0, 0		@ ctrl register
+	@ CAUTION: MMU turned off from this point. We count on the pipeline 
+	@ already containing those two last instructions to survive.
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, r0
+
+/*
+ * cpu_xscale_do_idle(type)
+ *
+ * Cause the processor to idle
+ *
+ * type: 
+ *   0 = slow idle
+ *   1 = fast idle
+ *   2 = switch to slow processor clock
+ *   3 = switch to fast processor clock
+ *
+ * For now we do nothing but go to idle mode for every case
+ *
+ * XScale supports clock switching, but using idle mode support
+ * allows external hardware to react to system state changes.
+ */
+	.align	5
+
+ENTRY(cpu_xscale_do_idle)
+	mov	r0, #1
+	mcr	p14, 0, r0, c7, c0, 0		@ Go to IDLE
+	mov	pc, lr
+
+/* ================================= CACHE ================================ */
+
+/*
+ * cpu_xscale_cache_clean_invalidate_all (void)
+ *
+ * clean and invalidate all cache lines
+ *
+ * Note:
+ *  1. We should preserve r0 at all times.
+ *  2. Even if this function implies cache "invalidation" by its name,
+ *     we don't need to actually use explicit invalidation operations
+ *     since the goal is to discard all valid references from the cache
+ *     and the cleaning of it already has that effect.
+ *  3. Because of 2 above and the fact that kernel space memory is always
+ *     coherent across task switches there is no need to worry about
+ *     inconsistencies due to interrupts, ence no irq disabling.
+ */
+	.align	5
+ENTRY(cpu_xscale_cache_clean_invalidate_all)
+	mov	r2, #1
+cpu_xscale_cache_clean_invalidate_all_r2:
+	clean_d_cache r0, r1
+	teq	r2, #0
+	mcrne	p15, 0, ip, c7, c5, 0		@ Invalidate I cache & BTB
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	mov	pc, lr
+
+/*
+ * cpu_xscale_cache_clean_invalidate_range(start, end, flags)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * start: Area start address
+ * end:   Area end address
+ * flags: nonzero for I cache as well
+ */
+	.align	5
+ENTRY(cpu_xscale_cache_clean_invalidate_range)
+	bic	r0, r0, #CACHELINESIZE - 1	@ round down to cache line
+	sub	r3, r1, r0
+	cmp	r3, #MAX_AREA_SIZE
+	bhi	cpu_xscale_cache_clean_invalidate_all_r2
+1:	clean_d_line r0				@ Clean D cache line
+	mcr	p15, 0, r0, c7, c6, 1		@ Invalidate D cache line
+	add	r0, r0, #CACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+	teq	r2, #0
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	moveq	pc, lr
+	sub	r0, r0, r3
+1:	mcr	p15, 0, r0, c7, c5, 1		@ Invalidate I cache line
+	add	r0, r0, #CACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, ip, c7, c5, 6		@ Invalidate BTB
+	mov	pc, lr
+
+/*
+ * cpu_xscale_flush_ram_page(page)
+ *
+ * clean all cache lines associated with this memory page
+ *
+ * page: page to clean
+ */
+	.align	5
+ENTRY(cpu_xscale_flush_ram_page)
+#if !CACHE_WRITE_THROUGH
+	mov	r1, #PAGESIZE
+1:	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line
+	add	r0, r0, #CACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line
+	add	r0, r0, #CACHELINESIZE
+	subs	r1, r1, #2 * CACHELINESIZE
+	bne	1b
+#endif
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	mov	pc, lr
+
+/* ================================ D-CACHE =============================== */
+
+/*
+ * cpu_xscale_dcache_invalidate_range(start, end)
+ *
+ * throw away all D-cached data in specified region without an obligation
+ * to write them back.  Note however that on XScale we must clean all
+ * entries also due to hardware errata (80200 A0 & A1 only).
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_xscale_dcache_invalidate_range)
+	mrc	p15, 0, r2, c0, c0, 0		@ Read part no.
+	eor	r2, r2, #0x69000000
+	eor	r2, r2, #0x00052000		@ 80200 XX part no.
+	bics	r2, r2, #0x1			@ Clear LSB in revision field
+	moveq	r2, #0
+	beq	cpu_xscale_cache_clean_invalidate_range	@ An 80200 A0 or A1
+
+	tst	r0, #CACHELINESIZE - 1
+	mcrne	p15, 0, r0, c7, c10, 1		@ Clean D cache line
+	tst	r1, #CACHELINESIZE - 1
+	mcrne	p15, 0, r1, c7, c10, 1		@ Clean D cache line
+	bic	r0, r0, #CACHELINESIZE - 1	@ round down to cache line
+1:	mcr	p15, 0, r0, c7, c6, 1		@ Invalidate D cache line
+	add	r0, r0, #CACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	pc, lr
+
+/*
+ * cpu_xscale_dcache_clean_range(start, end)
+ *
+ * For the specified virtual address range, ensure that all caches contain
+ * clean data, such that peripheral accesses to the physical RAM fetch
+ * correct data.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_xscale_dcache_clean_range)
+#if !CACHE_WRITE_THROUGH
+	bic	r0, r0, #CACHELINESIZE - 1
+	sub	r2, r1, r0
+	cmp	r2, #MAX_AREA_SIZE
+	movhi	r2, #0
+	bhi	cpu_xscale_cache_clean_invalidate_all_r2
+
+1:	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line
+	add	r0, r0, #CACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line
+	add	r0, r0, #CACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+#endif
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	mov	pc, lr
+
+/*
+ * cpu_xscale_clean_dcache_page(page)
+ *
+ * Cleans a single page of dcache so that if we have any future aliased
+ * mappings, they will be consistent at the time that they are created.
+ *
+ * Note:
+ *  1. we don't need to flush the write buffer in this case. [really? -Nico]
+ *  2. we don't invalidate the entries since when we write the page
+ *     out to disk, the entries may get reloaded into the cache.
+ */
+	.align	5
+ENTRY(cpu_xscale_dcache_clean_page)
+#if !CACHE_WRITE_THROUGH
+	mov	r1, #PAGESIZE
+1:	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line
+	add	r0, r0, #CACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line
+	add	r0, r0, #CACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line
+	add	r0, r0, #CACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line
+	add	r0, r0, #CACHELINESIZE
+	subs	r1, r1, #4 * CACHELINESIZE
+	bne	1b
+#endif
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	mov	pc, lr
+
+/*
+ * cpu_xscale_dcache_clean_entry(addr)
+ *
+ * Clean the specified entry of any caches such that the MMU
+ * translation fetches will obtain correct data.
+ *
+ * addr: cache-unaligned virtual address
+ */
+	.align	5
+ENTRY(cpu_xscale_dcache_clean_entry)
+	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	mov	pc, lr
+
+/* ================================ I-CACHE =============================== */
+
+/*
+ * cpu_xscale_icache_invalidate_range(start, end)
+ *
+ * invalidate a range of virtual addresses from the Icache
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ *
+ * Note1: This is vaguely defined as supposed to bring the dcache and the 
+ *       icache in sync by the way this function is used.
+ *
+ * Note2: single I-cache line invalidation isn't used here since
+ *        it also trashes the mini I-cache used by JTAG debuggers.
+ */
+	.align	5
+ENTRY(cpu_xscale_icache_invalidate_range)
+	bic	r0, r0, #CACHELINESIZE - 1
+1:	clean_d_line r0				@ Clean D cache line
+	add	r0, r0, #CACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, ip, c7, c5, 0		@ Invalidate I cache & BTB
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	mov	pc, lr
+
+/*
+ * cpu_xscale_icache_invalidate_page(page)
+ *
+ * invalidate all Icache lines associated with this area of memory
+ *
+ * page: page to invalidate
+ */
+	.align	5
+ENTRY(cpu_xscale_icache_invalidate_page)
+	mov	r1, #PAGESIZE
+1:	mcr	p15, 0, r0, c7, c5, 1		@ Invalidate I cache line
+	add	r0, r0, #CACHELINESIZE
+	mcr	p15, 0, r0, c7, c5, 1		@ Invalidate I cache line
+	add	r0, r0, #CACHELINESIZE
+	mcr	p15, 0, r0, c7, c5, 1		@ Invalidate I cache line
+	add	r0, r0, #CACHELINESIZE
+	mcr	p15, 0, r0, c7, c5, 1		@ Invalidate I cache line
+	add	r0, r0, #CACHELINESIZE
+	subs	r1, r1, #4 * CACHELINESIZE
+	bne	1b
+	mcr	p15, 0, r0, c7, c5, 6		@ Invalidate BTB
+	mov	pc, lr
+
+/* ================================ CACHE LOCKING============================ 
+ *
+ * The XScale MicroArchitecture implements support for locking entries into
+ * the data and instruction cache.  The following functions implement the core
+ * low level instructions needed to accomplish the locking.  The developer's
+ * manual states that the code that performs the locking must be in non-cached
+ * memory.  To accomplish this, the code in xscale-cache-lock.c copies the
+ * following functions from the cache into a non-cached memory region that
+ * is allocated through consistent_alloc().
+ *
+ */
+	.align	5
+/*
+ * xscale_icache_lock
+ *
+ * r0: starting address to lock
+ * r1: end address to lock
+ */
+ENTRY(xscale_icache_lock)
+
+iLockLoop:
+	bic	r0, r0, #CACHELINESIZE - 1
+	mcr	p15, 0, r0, c9, c1, 0	@ lock into cache
+	cmp	r0, r1			@ are we done?
+	add	r0, r0, #CACHELINESIZE	@ advance to next cache line
+	bls	iLockLoop
+	mov	pc, lr
+
+/*
+ * xscale_icache_unlock
+ */
+ENTRY(xscale_icache_unlock)
+	mcr	p15, 0, r0, c9, c1, 1	@ Unlock icache
+	mov	pc, lr
+	
+/*
+ * xscale_dcache_lock
+ *
+ * r0: starting address to lock
+ * r1: end address to lock
+ */
+ENTRY(xscale_dcache_lock)
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	mov	r2, #1
+	mcr	p15, 0, r2, c9, c2, 0	@ Put dcache in lock mode
+	cpwait	ip			@ Wait for completion
+
+	mrs	r2, cpsr
+	orr	r3, r2, #F_BIT | I_BIT
+dLockLoop:
+	msr	cpsr_c, r3
+	mcr	p15, 0, r0, c7, c10, 1	@ Write back line if it is dirty 
+	mcr	p15, 0, r0, c7, c6, 1	@ Flush/invalidate line
+	msr	cpsr_c, r2
+	ldr	ip, [r0], #CACHELINESIZE @ Preload 32 bytes into cache from 
+					@ location [r0]. Post-increment
+					@ r3 to next cache line
+	cmp	r0, r1			@ Are we done?
+	bls	dLockLoop
+
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	mov	r2, #0
+	mcr	p15, 0, r2, c9, c2, 0	@ Get out of lock mode
+	cpwait_ret lr, ip
+
+/*
+ * xscale_dcache_unlock
+ */
+ENTRY(xscale_dcache_unlock)
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	mcr	p15, 0, ip, c9, c2, 1	@ Unlock cache
+	mov	pc, lr
+
+/*
+ * Needed to determine the length of the code that needs to be copied.
+ */
+	.align	5
+ENTRY(xscale_cache_dummy)
+	mov	pc, lr
+
+/* ================================== TLB ================================= */
+
+/*
+ * cpu_xscale_tlb_invalidate_all()
+ *
+ * Invalidate all TLB entries
+ */
+	.align	5
+ENTRY(cpu_xscale_tlb_invalidate_all)
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	cpwait_ret lr, ip
+
+/*
+ * cpu_xscale_tlb_invalidate_range(start, end)
+ *
+ * invalidate TLB entries covering the specified range
+ *
+ * start: range start address
+ * end:   range end address
+ */
+	.align	5
+ENTRY(cpu_xscale_tlb_invalidate_range)
+	bic	r0, r0, #(PAGESIZE - 1) & 0x00ff
+	bic	r0, r0, #(PAGESIZE - 1) & 0xff00
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+1:	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
+	mcr	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
+	add	r0, r0, #PAGESIZE
+	cmp	r0, r1
+	blo	1b
+	cpwait_ret lr, ip
+
+/*
+ * cpu_xscale_tlb_invalidate_page(page, flags)
+ *
+ * invalidate the TLB entries for the specified page.
+ *
+ * page:  page to invalidate
+ * flags: non-zero if we include the I TLB
+ */
+	.align	5
+ENTRY(cpu_xscale_tlb_invalidate_page)
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	teq	r1, #0
+	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
+	mcrne	p15, 0, r3, c8, c5, 1		@ invalidate I TLB entry
+	cpwait_ret lr, ip
+
+/* ================================ TLB LOCKING==============================
+ *
+ * The XScale MicroArchitecture implements support for locking entries into
+ * the Instruction and Data TLBs.  The following functions provide the
+ * low level support for supporting these under Linux.  xscale-lock.c 
+ * implements some higher level management code.  Most of the following
+ * is taken straight out of the Developer's Manual.
+ */
+
+/*
+ * Lock I-TLB entry
+ *
+ * r0: Virtual address to translate and lock
+ */
+	.align	5
+ENTRY(xscale_itlb_lock)
+	mrs	r2, cpsr
+	orr	r3, r2, #F_BIT | I_BIT
+	msr	cpsr_c, r3			@ Disable interrupts
+	mcr	p15, 0, r0, c8, c5, 1		@ Invalidate I-TLB entry
+	mcr	p15, 0, r0, c10, c4, 0		@ Translate and lock
+	msr	cpsr_c, r2			@ Restore interrupts
+	cpwait_ret lr, ip
+
+/*
+ * Lock D-TLB entry
+ *
+ * r0: Virtual address to translate and lock
+ */
+	.align	5
+ENTRY(xscale_dtlb_lock)
+	mrs	r2, cpsr
+	orr	r3, r2, #F_BIT | I_BIT
+	msr	cpsr_c, r3			@ Disable interrupts
+	mcr	p15, 0, r0, c8, c6, 1		@ Invalidate D-TLB entry
+	mcr	p15, 0, r0, c10, c8, 0		@ Translate and lock
+	msr	cpsr_c, r2			@ Restore interrupts
+	cpwait_ret lr, ip
+
+/*
+ * Unlock all I-TLB entries
+ */
+	.align	5
+ENTRY(xscale_itlb_unlock)
+	mcr	p15, 0, ip, c10, c4, 1		@ Unlock I-TLB
+	mcr	p15, 0, ip, c8, c5, 0		@ Invalidate I-TLB
+	cpwait_ret lr, ip
+
+/*
+ * Unlock all D-TLB entries
+ */
+ENTRY(xscale_dtlb_unlock)
+	mcr	p15, 0, ip, c10, c8, 1		@ Unlock D-TBL
+	mcr	p15, 0, ip, c8, c6, 0		@ Invalidate D-TLB
+	cpwait_ret lr, ip
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_xscale_set_pgd(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+	.align	5
+ENTRY(cpu_xscale_set_pgd)
+	clean_d_cache r1, r2
+	mcr	p15, 0, ip, c7, c5, 0		@ Invalidate I cache & BTB
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	cpwait_ret lr, ip
+
+/*
+ * cpu_xscale_set_pmd(pmdp, pmd)
+ *
+ * Set a level 1 translation table entry, and clean it out of
+ * any caches such that the MMUs can load it correctly.
+ *
+ * pmdp: pointer to PMD entry
+ * pmd:  PMD value to store
+ */
+	.align	5
+ENTRY(cpu_xscale_set_pmd)
+#if PMD_CACHE_WRITE_ALLOCATE && !CACHE_WRITE_THROUGH
+	and	r2, r1, #PMD_TYPE_MASK|PMD_SECT_CACHEABLE|PMD_SECT_BUFFERABLE
+	cmp	r2, #PMD_TYPE_SECT|PMD_SECT_CACHEABLE|PMD_SECT_BUFFERABLE
+	orreq	r1, r1, #PMD_SECT_TEX(1)
+#elif CACHE_WRITE_THROUGH
+	and	r2, r1, #PMD_TYPE_MASK|PMD_SECT_CACHEABLE|PMD_SECT_BUFFERABLE
+	cmp	r2, #PMD_TYPE_SECT|PMD_SECT_CACHEABLE|PMD_SECT_BUFFERABLE
+	biceq	r1, r1, #PMD_SECT_BUFFERABLE
+#endif
+#if defined(CONFIG_ARCH_IXDP2400) || defined(CONFIG_ARCH_IXDP2401)
+      tst    r1, #PMD_SECT_TEX(1)
+      andeq  r2, r1,  #PMD_TYPE_MASK | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE
+      cmpeq  r2, #PMD_TYPE_SECT
+      orreq  r1, r1, #PMD_SECT_TEX(1)
+      orreq  r1, r1, #PMD_SECT_BUFFERABLE
+#endif
+
+	str	r1, [r0]
+	mov	ip, #0
+	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	mov	pc, lr
+
+/*
+ * cpu_xscale_set_pte(ptep, pte)
+ *
+ * Set a PTE and flush it out
+ *
+ * Errata 40: must set memory to write-through for user read-only pages.
+ */
+	.align	5
+ENTRY(cpu_xscale_set_pte)
+	str	r1, [r0], #-1024		@ linux version
+
+	bic	r2, r1, #0xff0
+	orr	r2, r2, #PTE_TYPE_EXT		@ extended page
+
+	eor	r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+
+	tst	r3, #L_PTE_USER | L_PTE_EXEC	@ User or Exec?
+	orrne	r2, r2, #PTE_EXT_AP_URO_SRW	@ yes -> user r/o, system r/w
+
+	tst	r3, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
+	orreq	r2, r2, #PTE_EXT_AP_UNO_SRW	@ yes -> user n/a, system r/w
+						@ combined with user -> user r/w
+
+	@
+	@ Handle the X bit.  We want to set this bit for the minicache
+	@ (U = E = B = W = 0, C = 1) or when write allocate is enabled,
+	@ and we have a writeable, cacheable region.  If we ignore the
+	@ U and E bits, we can allow user space to use the minicache as
+	@ well.
+	@
+	@  X = C & ~W & ~B
+	@      | C & W & B & write_allocate
+	@
+	eor	ip, r1, #L_PTE_CACHEABLE
+	tst	ip, #L_PTE_CACHEABLE | L_PTE_WRITE | L_PTE_BUFFERABLE
+#if PTE_CACHE_WRITE_ALLOCATE && !CACHE_WRITE_THROUGH
+	eorne	ip, r1, #L_PTE_CACHEABLE | L_PTE_WRITE | L_PTE_BUFFERABLE
+	tstne	ip, #L_PTE_CACHEABLE | L_PTE_WRITE | L_PTE_BUFFERABLE
+#endif
+	orreq	r2, r2, #PTE_EXT_TEX(1)
+
+#if CACHE_WRITE_THROUGH
+	bic	r2, r2, #L_PTE_BUFFERABLE
+#else
+	@
+	@ Errata 40: The B bit must be cleared for a user read-only
+	@ cacheable page.
+	@
+	@  B = B & ~((U|E) & C & ~W)
+	@
+	and	ip, r1, #L_PTE_USER | L_PTE_EXEC | L_PTE_WRITE | L_PTE_CACHEABLE
+	teq	ip, #L_PTE_USER | L_PTE_CACHEABLE
+	teqne	ip, #L_PTE_EXEC | L_PTE_CACHEABLE
+	teqne	ip, #L_PTE_USER | L_PTE_EXEC | L_PTE_CACHEABLE
+	biceq	r2, r2, #PTE_BUFFERABLE
+#endif
+
+#if defined(CONFIG_ARCH_IXDP2400) || defined(CONFIG_ARCH_IXDP2401)
+      and    ip, r2, #PTE_TYPE_MASK | PTE_EXT_TEX(1) | L_PTE_CACHEABLE | L_PTE_BUFFERABLE
+      cmp    ip, #PTE_TYPE_EXT
+      orreq  r2, r2, #PTE_EXT_TEX(1) | L_PTE_BUFFERABLE
+#endif
+
+	tst	r3, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
+	movne	r2, #0				@ no -> fault
+
+	str	r2, [r0]			@ hardware version
+
+ 	@ We try to map 64K page entries when possible.  
+ 	@ We do that for kernel space only since the usage pattern from
+ 	@ the setting of VM area is quite simple.  User space is not worth
+ 	@ the implied complexity because of ever randomly changing PTEs 
+ 	@ (page aging, swapout, etc) requiring constant coherency checks.
+ 	@ Since PTEs are usually set in increasing order, we test the
+ 	@ possibility for a large page only when given the last PTE of a
+ 	@ 64K boundary.
+ 	tsteq	r1, #L_PTE_USER
+ 	andeq	r1, r0, #(15 << 2)
+ 	teqeq	r1, #(15 << 2)
+ 	beq	1f
+
+	mov	r0, r0
+	mov	ip, #0
+	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	mov	pc, lr
+
+ 	@ See if we have 16 identical PTEs but with consecutive base addresses
+ 1:	bic	r3, r2, #0x0000f000
+ 	mov	r1, #0x0000f000
+ 2:	eor	r2, r2, r3
+	teq	r2, r1
+ 	bne	4f
+ 	subs	r1, r1, #0x00001000
+ 	ldr	r2, [r0, #-4]!
+ 	bne	2b
+ 	eors	r2, r2, r3
+ 	bne	4f
+ 
+ 	@ Now create our LARGE PTE from the current EXT one.
+ 	bic	r3, r3, #PTE_TYPE_MASK
+ 	orr	r3, r3, #PTE_TYPE_LARGE
+ 	and	r2, r3, #0x30			@ EXT_AP --> LARGE_AP0
+ 	orr	r2, r2, r2, lsl #2		@ add LARGE_AP1
+ 	orr	r2, r2, r2, lsl #4		@ add LARGE_AP3 + LARGE_AP2
+ 	and	r1, r3, #0x3c0			@ EXT_TEX
+ 	bic	r3, r3, #0x3c0
+ 	orr	r2, r2, r1, lsl #(12 - 6)	@ --> LARGE_TEX
+ 	orr	r2, r2, r3			@ add remaining bits
+ 
+ 	@ then put it in the pagetable
+ 	mov	r3, r2
+ 3:	strd	r2, [r0], #8
+ 	tst	r0, #(15 << 2)
+ 	bne	3b
+ 
+ 	@ Then sync the 2 corresponding cache lines
+ 	sub	r0, r0, #(16 << 2)
+ 	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line
+ 4:	orr	r0, r0, #(15 << 2)
+ 	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line
+ 	mov	ip, #0
+ 	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+ 	mov	pc, lr
+
+	.ltorg
+
+cpu_manu_name:
+	.asciz	"Intel"
+
+cpu_80200_name:
+	.asciz	"XScale-80200"
+
+cpu_80321_name:
+	.asciz	"XScale-IOP80321"
+
+cpu_pxa250_name:
+	.asciz	"XScale-PXA250"
+
+cpu_ixp425_name:
+	.asciz	"XScale-IXP4xx/IXC11xx"
+
+cpu_ixp2400_name:
+	.asciz	"XScale-IXP2400"
+
+cpu_ixp2800_name:
+	.asciz	"XScale-IXP2800"
+
+	.align
+
+	.section ".text.init", #alloc, #execinstr
+
+__xscale_setup:
+	mov	r0, #F_BIT|I_BIT|SVC_MODE
+	msr	cpsr_c, r0
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I, D caches & BTB
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I, D TLBs
+	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
+	mov	r0, #0x1f			@ Domains 0, 1 = client
+	mcr	p15, 0, r0, c3, c0, 0		@ load domain access register
+	mov	r0, #1				@ Allow access to CP0
+	orr	r0, r0, #1 << 13		@ and CP13
+	orr	r0, r0, #1 << 6			@ cp6 for IOP3xx 
+	mcr	p15, 0, r0, c15, c1, 0		
+#if CACHE_WRITE_THROUGH
+	mov	r0, #0x20
+#else
+	mov	r0, #0x00
+#endif
+	mcr	p15, 0, r0, c1, c1, 0		@ set auxiliary control reg
+	mrc	p15, 0, r0, c1, c0, 0		@ get control register
+	bic	r0, r0, #0x0200			@ ......R.........
+	bic	r0, r0, #0x0002			@ ..............A.
+	orr	r0, r0, #0x0005			@ .............C.M
+	orr	r0, r0, #0x3900			@ ..VIZ..S........
+#ifdef CONFIG_XSCALE_CACHE_ERRATA
+	bic	r0, r0, #0x0004			@ see cpu_xscale_proc_init
+#endif
+	mov	pc, lr
+
+	.text
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+
+	.type	xscale_processor_functions, #object
+ENTRY(xscale_processor_functions)
+	.word	cpu_xscale_data_abort
+	.word	cpu_xscale_check_bugs
+	.word	cpu_xscale_proc_init
+	.word	cpu_xscale_proc_fin
+	.word	cpu_xscale_reset
+	.word	cpu_xscale_do_idle
+
+	/* cache */
+	.word	cpu_xscale_cache_clean_invalidate_all
+	.word	cpu_xscale_cache_clean_invalidate_range
+	.word	cpu_xscale_flush_ram_page
+
+	/* dcache */
+	.word	cpu_xscale_dcache_invalidate_range
+	.word	cpu_xscale_dcache_clean_range
+	.word	cpu_xscale_dcache_clean_page
+	.word	cpu_xscale_dcache_clean_entry
+
+	/* icache */
+	.word	cpu_xscale_icache_invalidate_range
+	.word	cpu_xscale_icache_invalidate_page
+
+	/* tlb */
+	.word	cpu_xscale_tlb_invalidate_all
+	.word	cpu_xscale_tlb_invalidate_range
+	.word	cpu_xscale_tlb_invalidate_page
+
+	/* pgtable */
+	.word	cpu_xscale_set_pgd
+	.word	cpu_xscale_set_pmd
+	.word	cpu_xscale_set_pte
+	.size	xscale_processor_functions, . - xscale_processor_functions
+
+	.type	cpu_80200_info, #object
+cpu_80200_info:
+	.long	cpu_manu_name
+	.long	cpu_80200_name
+	.size	cpu_80200_info, . - cpu_80200_info
+
+	.type	cpu_80321_info, #object
+cpu_80321_info:
+	.long	cpu_manu_name
+	.long	cpu_80321_name
+	.size	cpu_80321_info, . - cpu_80321_info
+
+	.type	cpu_pxa250_info, #object
+cpu_pxa250_info:
+	.long	cpu_manu_name
+	.long	cpu_pxa250_name
+	.size	cpu_pxa250_info, . - cpu_pxa250_info
+
+cpu_ixp425_info:
+	.long	cpu_manu_name
+	.long	cpu_ixp425_name
+	.size	cpu_ixp425_info, . - cpu_ixp425_info
+
+        .type   cpu_ixp2400_info, #object
+cpu_ixp2400_info:
+        .long   cpu_manu_name
+        .long   cpu_ixp2400_name
+        .size   cpu_ixp2400_info, . - cpu_ixp2400_info
+
+	.type	cpu_ixp2800_info, #object
+cpu_ixp2800_info:
+	.long	cpu_manu_name
+	.long	cpu_ixp2800_name
+	.size	cpu_ixp2800_info, . - cpu_ixp2800_info
+
+	.type	cpu_arch_name, #object
+cpu_arch_name:
+	.asciz	"armv5"
+	.size	cpu_arch_name, . - cpu_arch_name
+
+	.type	cpu_elf_name, #object
+cpu_elf_name:
+	.asciz	"v5"
+	.size	cpu_elf_name, . - cpu_elf_name
+	.align
+
+	.section ".proc.info", #alloc, #execinstr
+
+	.type	__80200_proc_info,#object
+__80200_proc_info:
+	.long	0x69052000
+	.long	0xffffe3f0
+#if CACHE_WRITE_THROUGH
+	.long	0x00000c0a
+#else
+	.long	0x00000c0e
+#endif
+	b	__xscale_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long	cpu_80200_info
+	.long	xscale_processor_functions
+	.size	__80200_proc_info, . - __80200_proc_info
+
+	.type	__80321_proc_info,#object
+__80321_proc_info:
+	.long	0x69052420
+	.long	0xfffff7e0
+#if CACHE_WRITE_THROUGH
+	.long	0x00000c0a
+#else
+	.long	0x00000c0e
+#endif
+	b	__xscale_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long	cpu_80321_info
+	.long	xscale_processor_functions
+	.size	__80321_proc_info, . - __80321_proc_info
+ 
+	.type	__pxa250_proc_info,#object
+__pxa250_proc_info:
+	.long	0x69052100
+	.long	0xfffff7f0
+#if CACHE_WRITE_THROUGH
+	.long	0x00000c0a
+#else
+	.long	0x00000c0e
+#endif
+	b	__xscale_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long	cpu_pxa250_info
+	.long	xscale_processor_functions
+	.size	__pxa250_proc_info, . - __pxa250_proc_info
+
+	.type	__ixp425_proc_info, #object
+__ixp425_proc_info:
+	.long   0x690541c0
+	.long   0xffffffc0
+#if CACHE_WRITE_THROUGH
+	.long   0x00000c0a
+#else
+	.long   0x00000c0e
+#endif        
+	b       __xscale_setup
+	.long   cpu_arch_name
+	.long   cpu_elf_name
+	.long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long   cpu_ixp425_info
+	.long   xscale_processor_functions
+	.size   __ixp425_proc_info, . - __ixp425_proc_info                
+
+	.type	__ixp465_proc_info, #object
+__ixp465_proc_info:
+	.long   0x69054200
+	.long   0xffffff00
+#if CACHE_WRITE_THROUGH
+	.long   0x00000c0a
+#else
+	.long   0x00000c0e
+#endif        
+	b       __xscale_setup
+	.long   cpu_arch_name
+	.long   cpu_elf_name
+	.long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long   cpu_ixp425_info
+	.long   xscale_processor_functions
+	.size   __ixp465_proc_info, . - __ixp465_proc_info                
+
+       .type   __ixp2400_proc_info,#object
+__ixp2400_proc_info:
+        .long   0x69054190
+        .long   0xfffffff0
+#if CACHE_WRITE_THROUGH
+	.long	0x00000c0a
+#else
+	.long	0x00000c0e
+#endif
+        b       __xscale_setup
+        .long   cpu_arch_name
+        .long   cpu_elf_name
+        .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+        .long   cpu_ixp2400_info
+        .long   xscale_processor_functions
+        .size   __ixp2400_proc_info, . - __ixp2400_proc_info
+#
+	.type	__ixp2800_proc_info,#object
+__ixp2800_proc_info:
+	.long	0x690541a0
+	.long	0xfffffff0
+#if CACHE_WRITE_THROUGH
+	.long	0x00000c0a
+#else
+	.long	0x00000c0e
+#endif
+	b	__xscale_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long	cpu_ixp2800_info
+	.long	xscale_processor_functions
+	.size	__ixp2800_proc_info, . - __ixp2800_proc_info
+
diff -urN linux-2.4.29/arch/arm/mm/xscale-lock.c linux-2.4.29-uc1/arch/arm/mm/xscale-lock.c
--- linux-2.4.29/arch/arm/mm/xscale-lock.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/mm/xscale-lock.c	2005-06-14 02:10:59.000000000 +0100
@@ -0,0 +1,472 @@
+/*
+ * xscale-lock.c
+ *
+ * This file implements the APIs that can be used by kernel developers 
+ * to lock entries into the caches and TLBs on processors based on 
+ * Intel's XScale * Microarchitecture.  For information on using the APIs see 
+ * Documentation/arm/XScale/cache-lock.txt and tlb_lock.txt.
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/cache.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/hardware.h>
+#include <asm/cpu-single.h>
+#include <asm/xscale-lock.h>
+#include <asm/proc/cache.h>
+
+
+extern void* consistent_alloc(int, size_t, dma_addr_t);
+
+#undef DEBUG 
+#ifdef DEBUG
+#define DBG_LEVEL 3
+#define DBG(n, args...) do { if (DBG_LEVEL>=(n)) printk(args); } while (0)
+#else
+#define DBG(n, args...) do { } while (0)
+#endif
+
+/*
+ * Future XScale cores may have different cache sizes
+ */
+#define CACHE_SIZE 32
+#define CACHE_LOCK 28
+#define CACHE_LINES CACHE_LOCK * 1024 / L1_CACHE_BYTES
+
+#define TLB_ENTRIES 28
+
+
+/*
+ * Cache Locking Implementation
+ */
+
+static dma_addr_t dma_handle;
+static void *low_level_page = NULL;
+
+/*
+ * Internal structure used to track cache usage
+ */
+struct cache_entry
+{
+	void *addr;
+	int lines;
+	struct cache_entry *next;
+	struct cache_entry *prev;
+};
+
+static struct cache_capabilities cache =
+{
+	CACHE_LOCKABLE,
+	CACHE_SIZE,
+	CACHE_LOCK
+};
+
+static int cache_lock_init(void);
+
+static int cache_lines[2] = { CACHE_LINES, CACHE_LINES };
+static struct cache_entry *cache_data[2] = {NULL, NULL};
+
+static int alloc_cache_entry(void *, int, u8);
+static struct cache_entry* unlink_cache_entry(void *, u8);
+
+extern int xscale_icache_lock(void*, int);
+extern int xscale_dcache_lock(void*, int);
+extern int xscale_icache_unlock(void);
+extern int xscale_dcache_unlock(void);
+extern void xscale_cache_dummy(void);
+
+typedef int (*cache_lock_fn)(void *, int);
+typedef int (*cache_unlock_fn)(void);
+
+static cache_lock_fn icache_lock_fn;
+static cache_lock_fn dcache_lock_fn;
+static cache_unlock_fn icache_unlock_fn;
+static cache_unlock_fn dcache_unlock_fn;
+
+static cache_lock_fn lock_fns[2];
+static cache_unlock_fn unlock_fns[2];
+
+/*
+ * Cache Lock API functions
+ */
+
+int cache_query_capabilities(u8 cache_type, struct cache_capabilities *pcap)
+{
+	if(!pcap)
+		return -EINVAL;
+
+	/*
+	 * Both caches are same on current xscale 
+	 */
+	memcpy(pcap, &cache, sizeof(struct cache_capabilities));
+
+	return 0;
+}
+
+int cache_lock(void *addr, u32 len, u8 cache_type, const char *desc)
+{
+	u32 address = (u32)addr;
+
+	DBG(1, "cache_lock entered\n");
+	DBG(2, "   Addr: %#10x\n", (u32)addr);
+	DBG(2, "   Type: %s\n", cache_type == ICACHE ? "ICACHE" : "DCACHE");
+	DBG(2, "    Len: %#6x\n", len);
+
+
+	if(address & (L1_CACHE_BYTES - 1)) {
+		DBG(1, "   Non-aligned lock request: %p\n", addr);
+		return -EINVAL;	
+	}
+
+	DBG(1, "   calling alloc_cache_entry\n");
+	return alloc_cache_entry(addr, len, cache_type);
+}
+
+int cache_unlock(void *addr)
+{
+	struct cache_entry *entry;
+	u8 cache_type;
+
+	DBG(1, "cache_unlock entered\n");
+
+	if((entry = unlink_cache_entry(addr, ICACHE)))
+		cache_type = ICACHE;
+	else if((entry = unlink_cache_entry(addr, DCACHE)))
+		cache_type = DCACHE;
+	else 
+	{
+		DBG(1, "   No entry!\n");
+		return -ENOENT;
+	}
+
+	DBG(2, "   Addr: %#10x\n", (u32)addr);
+	DBG(2, "   Type: %s\n", cache_type == ICACHE ? "ICACHE" : "DCACHE");
+	DBG(2, "    Len: %#6x\n", entry->lines);
+
+	cache_lines[cache_type] += entry->lines;
+	kfree(entry);
+
+	/*
+	 * Unlock
+	 * Invalidate
+	 * Relock
+	 */
+	DBG(2, "   Calling unlock_fn\n");
+	unlock_fns[cache_type]();
+	DBG(2, "   unlock_fn returned\n");
+	cpu_cache_clean_invalidate_all();
+
+
+	for(entry = cache_data[cache_type]; entry; entry = entry->next)
+	{
+		DBG(2, "   Invalidating DCACHE\n");
+		cpu_cache_clean_invalidate_all();
+		DBG(2, "   Cleaning DCACHE\n");
+
+		DBG(2, "   Calling lock_fn\n");
+		lock_fns[cache_type](entry->addr, 
+			(u32)(entry->addr + entry->lines * L1_CACHE_BYTES));
+		DBG(2, "   lock_fn returned\n");
+	}
+
+	DBG(1, "   cache_unlock exit\n");
+	return 0;
+}
+
+/*
+ * Cache Lock internals
+ */
+
+static struct cache_entry* unlink_cache_entry(void *addr, u8 cache_type)
+{
+	struct cache_entry *p;
+
+	p = cache_data[cache_type];
+
+	if(!p) return NULL;
+
+	if(p->addr == addr)
+	{
+		cache_data[cache_type] = p->next;
+		if(p->next)
+			p->next->prev = NULL;
+		return p;
+	}
+
+	for(p = cache_data[cache_type]; p; p = p->next)
+	{
+		if(p->addr == addr)
+		{
+			if(p->prev)
+				p->prev->next = p->next;
+			if(p->next)
+				p->next->prev = p->prev;
+			break;
+		}
+	}
+
+	return p;
+}
+
+
+static int alloc_cache_entry(void *addr, int len, u8 cache_type)
+{
+	struct cache_entry *new = NULL; 
+	u32 end = L1_CACHE_ALIGN((u32)addr + len);
+	int lines = 0;
+
+	DBG(2, "   addr: %#10x\n", (u32)addr);
+	DBG(2, "    len: %#6x\n", len);
+	DBG(2, "   type: %s\n", cache_type == ICACHE ? "ICACHE" : "DCACHE");
+
+	new = kmalloc(sizeof(struct cache_entry), GFP_ATOMIC);
+	DBG(1, "alloc_cache_entry entered\n");
+	if(!new)
+	{
+		DBG(2, "   Could not allocate cache_entry\n");
+		return -ENOMEM;
+	}
+
+	lines = ((u32)end - (u32)addr) / L1_CACHE_BYTES;
+	if(lines > cache_lines[cache_type]) 
+	{
+		DBG(2, "   No space left in cache\n");
+		return -ENOSPC;	
+	}
+
+	new->addr = addr;
+	new->lines = lines;
+	new->next = NULL;
+	new->prev = NULL;
+
+	if(cache_data[cache_type] == NULL) 
+	{
+		cache_data[cache_type] = new;
+	}
+	else
+	{
+		new->next = cache_data[cache_type];
+		cache_data[cache_type]->prev = new;
+		new->prev = NULL;
+		cache_data[cache_type] = new;
+	}
+
+	cache_lines[cache_type] -= lines;
+
+	DBG(2, "   Invalidating/cleaning caches\n");
+	cpu_cache_clean_invalidate_all();
+	DBG(2, "   Invalidate/clean complete\n");
+
+	DBG(2, "   Calling lock_fn @ %#10x\n", (u32)lock_fns[cache_type]);
+	DBG(3, "      start: %#10x end: %#10x\n", (u32)addr, (u32)end);
+	lock_fns[cache_type](addr, end);
+	DBG(2, "   lock_fn returned\n");
+	DBG(1, "alloc_cache_entry exit\n");
+
+	return 0;
+}
+
+
+/*
+ * This function basically sets up the cache locking code so
+ * it meets the requirements in section 4.3.4 of the 80200
+ * manual.
+ *
+ * 1) The routine used to lock cache can't be cacheble
+ * 2) Code used to do locking not reside closer than 128 bytes
+ *    to a cache/non-cache boundary.
+ *
+ * Since the compiler has no understanding of such things, we 
+ * allocate uncacheble memory by calling consistent_alloc and 
+ * copy the relavent low level code to the new memory and than
+ * create pointers into this memory. Ick.
+ *
+ */
+static int __init cache_lock_init(void)
+{
+	u32 len;
+
+	DBG(1, "XScale cache_lock_init called\n");
+	len = (u32)xscale_cache_dummy - (u32)xscale_icache_lock + 256;
+
+	/*
+	 * This is an ugly way to get a non-cached page
+	 */
+	DBG(1, "   Calling consistent alloc\n");
+	low_level_page = consistent_alloc(GFP_KERNEL, len, (u32)&dma_handle);
+	DBG(1, "   low_level_page initialized\n");
+
+	if(!low_level_page)
+	{
+		printk(KERN_ERR 
+			"   Could not allocate memory for cache locking\n");
+		printk(KERN_ERR "   Cache locking disabled\n");
+
+		return -1;
+	}
+
+	memcpy(low_level_page + 128, xscale_icache_lock, len - 256);
+
+	DBG(1, "   low_level_page @ %#10x\n", (u32)low_level_page);
+	icache_lock_fn = (cache_lock_fn)(low_level_page + 128);
+	dcache_lock_fn = 
+		(cache_lock_fn)(low_level_page + 128 + 
+				((u32)xscale_dcache_lock - (u32)xscale_icache_lock));
+
+	DBG(1, "      icache_lock_fn @ %#10x\n", (u32)icache_lock_fn);
+	DBG(1, "      dcache_lock_fn @ %#10x\n", (u32)dcache_lock_fn);
+	lock_fns[ICACHE] = icache_lock_fn;
+	lock_fns[DCACHE] = dcache_lock_fn;
+
+	icache_unlock_fn = (cache_unlock_fn)(low_level_page + 128 +
+				((u32)xscale_icache_unlock - (u32)xscale_icache_lock));
+	dcache_unlock_fn = (cache_unlock_fn)(low_level_page + 128 +
+				((u32)xscale_dcache_unlock - (u32)xscale_icache_lock));
+
+	DBG(1, "      icache_unlock_fn @ %#10x\n", (u32)icache_unlock_fn);
+	DBG(1, "      dcache_unlock_fn @ %#10x\n", (u32)dcache_unlock_fn);
+	unlock_fns[ICACHE] = icache_unlock_fn;
+	unlock_fns[DCACHE] = dcache_unlock_fn;
+
+	return 0;
+}
+
+
+/*
+ * TLB Locking Implementation
+ */
+
+static u32 tlb_entries[TLB_ENTRIES][TLB_ENTRIES];
+static u32 tlb_count[2] = {TLB_ENTRIES, TLB_ENTRIES};
+
+extern void xscale_itlb_lock(u32);
+extern void xscale_dtlb_lock(u32);
+
+extern void xscale_itlb_unlock(void);
+extern void xscale_dtlb_unlock(void);
+
+typedef void (*tlb_lock)(u32);
+typedef void (*tlb_unlock)(void);
+
+static tlb_lock tlb_lock_fn[2]  = 
+	{xscale_itlb_lock, xscale_dtlb_lock};
+
+static tlb_unlock tlb_unlock_fn[2] = 
+	{xscale_itlb_unlock, xscale_dtlb_unlock};
+
+int xscale_tlb_lock(u8 tlb_type, u32 addr)
+{
+	int i = 0;
+
+	if(tlb_type != ITLB && tlb_type != DTLB)
+		return -EIO;
+
+	if(!tlb_count[tlb_type])
+		return -ENOSPC;
+
+	if(addr & 0xff)
+		return -EINVAL;
+
+	tlb_lock_fn[tlb_type](addr);
+
+	for(i = 0; i < TLB_ENTRIES; i++)
+	{
+		if(tlb_entries[tlb_type][i] == 0xDEADBEEF)
+		{
+			tlb_entries[tlb_type][i] = addr;	
+			break;
+		}
+	}
+
+	tlb_count[tlb_type]--;
+					
+	return 0;
+}
+
+int xscale_tlb_unlock(u8 tlb_type, u32 addr)
+{
+	int i = 0;
+
+	if(tlb_type != ITLB && tlb_type != DTLB)
+		return -EIO;
+
+	for(i = 0; i < TLB_ENTRIES; i++)
+	{
+		if(tlb_entries[tlb_type][i] == addr)
+		{
+			tlb_entries[tlb_type][i] = 0xDEADBEEF;
+			break;
+		}
+	}
+
+	if(i == TLB_ENTRIES)
+		return -ENOENT;
+
+	/*
+	 * There's no unlock 1 entry command on XScale.  So we unlock
+	 * the whole tlb and than lock each entry in again.
+	 */
+	tlb_unlock_fn[tlb_type]();
+
+	for(i = 0; i < TLB_ENTRIES; i++)
+	{
+		if(tlb_entries[tlb_type][i] != 0xDEADBEEF)
+			tlb_lock_fn[tlb_type](addr);
+	}
+
+	return 0;
+}
+
+
+static void __init tlb_lock_init(void)
+{
+	int i = 0;
+
+	DBG(1, "Initializing TLB locking\n");
+	for(i = 0; i < TLB_ENTRIES; i++)
+		tlb_entries[ITLB][i] = tlb_entries[DTLB][i] = 0xDEADBEEF;
+	DBG(1, "TLB locking initialized\n");
+}	
+
+
+/*
+ * Initialization code
+ */
+void __init xscale_locking_init(void)
+{
+	printk(KERN_INFO "XScale Cache/TLB Locking Copyright(c) 2001 MontaVista Software, Inc.\n");
+
+	if(cache_lock_init())
+		return;
+
+	tlb_lock_init();
+}
diff -urN linux-2.4.29/arch/arm/nwfpe/double_cpdo.c linux-2.4.29-uc1/arch/arm/nwfpe/double_cpdo.c
--- linux-2.4.29/arch/arm/nwfpe/double_cpdo.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/nwfpe/double_cpdo.c	2005-06-14 02:10:59.000000000 +0100
@@ -75,7 +75,11 @@
 	union float64_components u;
 
 	u.f64 = rFm;
+#ifdef __ARMEB__
+	u.i[0] ^= 0x80000000;
+#else
 	u.i[1] ^= 0x80000000;
+#endif
 
 	return u.f64;
 }
@@ -85,7 +89,11 @@
 	union float64_components u;
 
 	u.f64 = rFm;
+#ifdef __ARMEB__
+	u.i[0] &= 0x7fffffff;
+#else
 	u.i[1] &= 0x7fffffff;
+#endif
 
 	return u.f64;
 }
diff -urN linux-2.4.29/arch/arm/nwfpe/fpa11_cpdt.c linux-2.4.29-uc1/arch/arm/nwfpe/fpa11_cpdt.c
--- linux-2.4.29/arch/arm/nwfpe/fpa11_cpdt.c	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/nwfpe/fpa11_cpdt.c	2005-06-14 02:10:59.000000000 +0100
@@ -41,8 +41,13 @@
 	unsigned int *p;
 	p = (unsigned int *) &fpa11->fpreg[Fn].fDouble;
 	fpa11->fType[Fn] = typeDouble;
+#ifdef __ARMEB__
+	get_user(p[0], &pMem[0]);
+	get_user(p[1], &pMem[1]);	/* sign & exponent */
+#else
 	get_user(p[0], &pMem[1]);
 	get_user(p[1], &pMem[0]);	/* sign & exponent */
+#endif
 }
 
 #ifdef CONFIG_FPE_NWFPE_XP
@@ -53,8 +58,13 @@
 	p = (unsigned int *) &fpa11->fpreg[Fn].fExtended;
 	fpa11->fType[Fn] = typeExtended;
 	get_user(p[0], &pMem[0]);	/* sign & exponent */
+#ifdef __ARMEB__
+	get_user(p[1], &pMem[1]);	/* ls bits */
+	get_user(p[2], &pMem[2]);	/* ms bits */
+#else
 	get_user(p[1], &pMem[2]);	/* ls bits */
 	get_user(p[2], &pMem[1]);	/* ms bits */
+#endif
 }
 #endif
 
@@ -81,8 +91,13 @@
 #ifdef CONFIG_FPE_NWFPE_XP
 	case typeExtended:
 		{
+#ifdef __ARMEB__
+			get_user(p[1], &pMem[1]);
+			get_user(p[2], &pMem[2]);	/* msw */
+#else
 			get_user(p[1], &pMem[2]);
 			get_user(p[2], &pMem[1]);	/* msw */
+#endif
 			p[0] = (x & 0x80003fff);
 		}
 		break;
@@ -134,8 +149,13 @@
 	default:
 		val = fpa11->fpreg[Fn].fDouble;
 	}
+#ifdef __ARMEB__
+	put_user(p[0], &pMem[0]);	/* msw */
+	put_user(p[1], &pMem[1]);	/* lsw */
+#else
 	put_user(p[1], &pMem[0]);	/* msw */
 	put_user(p[0], &pMem[1]);	/* lsw */
+#endif
 }
 
 #ifdef CONFIG_FPE_NWFPE_XP
@@ -159,8 +179,13 @@
 	}
 
 	put_user(p[0], &pMem[0]);	/* sign & exp */
+#ifdef __ARMEB__
+	put_user(p[1], &pMem[1]);	/* msw */
+	put_user(p[2], &pMem[2]);
+#else
 	put_user(p[1], &pMem[2]);
 	put_user(p[2], &pMem[1]);	/* msw */
+#endif
 }
 #endif
 
@@ -185,8 +210,13 @@
 #ifdef CONFIG_FPE_NWFPE_XP
 	case typeExtended:
 		{
+#ifdef __ARMEB__
+			put_user(p[1], &pMem[1]);	/* msw */
+			put_user(p[2], &pMem[2]);
+#else
 			put_user(p[2], &pMem[1]);	/* msw */
 			put_user(p[1], &pMem[2]);
+#endif
 			put_user((p[0] & 0x80003fff) | (nType << 14), &pMem[0]);
 		}
 		break;
diff -urN linux-2.4.29/arch/arm/tools/getconstants.c linux-2.4.29-uc1/arch/arm/tools/getconstants.c
--- linux-2.4.29/arch/arm/tools/getconstants.c	2001-10-11 17:04:57.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/tools/getconstants.c	2005-06-14 02:10:59.000000000 +0100
@@ -25,6 +25,8 @@
 #endif
 
 #define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n)
+#define BOFF_TSK(n) ((unsigned long)&(((struct task_struct *)0)->n))+1
+#define OFF_MM(n) (unsigned long)&(((struct mm_struct *)0)->n)
 
 #define DEFN(name,off) asm("\n#define "name" %0" :: "I" (off))
 
@@ -34,13 +36,18 @@
 DEFN("TSK_ADDR_LIMIT",		OFF_TSK(addr_limit));
 DEFN("TSK_NEED_RESCHED",	OFF_TSK(need_resched));
 DEFN("TSK_PTRACE",		OFF_TSK(ptrace));
+
 DEFN("TSK_USED_MATH",		OFF_TSK(used_math));
 
 DEFN("TSS_SAVE",		OFF_TSK(thread.save));
 DEFN("TSS_FPESAVE",		OFF_TSK(thread.fpstate.soft.save));
 
 #ifdef CONFIG_CPU_32
+#ifdef CONFIG_ARM_FASS
+DEFN("TSS_DACR",		OFF_TSK(thread.dacr));
+#else
 DEFN("TSS_DOMAIN",		OFF_TSK(thread.domain));
+#endif
 
 DEFN("HPTE_TYPE_SMALL",		PTE_TYPE_SMALL);
 DEFN("HPTE_AP_READ",		PTE_AP_READ);
@@ -54,6 +61,12 @@
 DEFN("LPTE_WRITE",		L_PTE_WRITE);
 DEFN("LPTE_EXEC",		L_PTE_EXEC);
 DEFN("LPTE_DIRTY",		L_PTE_DIRTY);
+
+DEFN("TSK_MM",			OFF_TSK(mm));
+#ifdef CONFIG_ARM_FASS
+DEFN("MM_CONTEXT_DACR",		OFF_MM(context.dacr));
+DEFN("MM_CONTEXT_PID",		OFF_MM(context.pid));
+#endif
 #endif
 
 #ifdef CONFIG_CPU_26
diff -urN linux-2.4.29/arch/arm/tools/mach-types linux-2.4.29-uc1/arch/arm/tools/mach-types
--- linux-2.4.29/arch/arm/tools/mach-types	2003-08-25 12:44:39.000000000 +0100
+++ linux-2.4.29-uc1/arch/arm/tools/mach-types	2005-06-14 02:10:59.000000000 +0100
@@ -6,7 +6,7 @@
 # To add an entry into this database, please see Documentation/arm/README,
 # or contact rmk@arm.linux.org.uk
 #
-# Last update: Sat Jun 28 12:10:54 2003
+# Last update: Fri Feb 25 00:42:48 2005
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -202,7 +202,7 @@
 fester			SA1100_FESTER		FESTER			191
 gpi			ARCH_GPI		GPI			192
 smdk2410		ARCH_SMDK2410		SMDK2410		193
-premium			ARCH_PREMIUM		PREMIUM			194
+i519			ARCH_I519		I519			194
 nexio			SA1100_NEXIO		NEXIO			195
 bitbox			SA1100_BITBOX		BITBOX			196
 g200			SA1100_G200		G200			197
@@ -226,9 +226,9 @@
 pnp1110			SA1100_PNP1110		PNP1110			215
 csb226			ARCH_CSB226		CSB226			216
 arnold			SA1100_ARNOLD		ARNOLD			217
-psiboard		SA1100_PSIBOARD		PSIBOARD		218
+voiceblue		MACH_VOICEBLUE		VOICEBLUE		218
 jz8028			ARCH_JZ8028		JZ8028			219
-h5400			ARCH_IPAQ3		IPAQ3			220
+h5400			ARCH_H5400		H5400			220
 forte			SA1100_FORTE		FORTE			221
 acam			SA1100_ACAM		ACAM			222
 abox			SA1100_ABOX		ABOX			223
@@ -242,7 +242,7 @@
 yoho			ARCH_YOHO		YOHO			231
 jasper			ARCH_JASPER		JASPER			232
 dsc25			ARCH_DSC25		DSC25			233
-innovator		ARCH_INNOVATOR		INNOVATOR		234
+omap_innovator		MACH_OMAP_INNOVATOR	OMAP_INNOVATOR		234
 ramses			ARCH_RAMSES		RAMSES			235
 s28x			ARCH_S28X		S28X			236
 mport3			ARCH_MPORT3		MPORT3			237
@@ -250,8 +250,8 @@
 pdb			ARCH_PDB		PDB			239
 blue_2g			SA1100_BLUE_2G		BLUE_2G			240
 bluearch		SA1100_BLUEARCH		BLUEARCH		241
-ixdp2400		ARCH_IXMB2400		IXMB2400		242
-ixdp2800		ARCH_IXMB2800		IXMB2800		243
+ixdp2400		ARCH_IXDP2400		IXDP2400		242
+ixdp2800		ARCH_IXDP2800		IXDP2800		243
 explorer		SA1100_EXPLORER		EXPLORER		244
 ixdp425			ARCH_IXDP425		IXDP425			245
 chimp			ARCH_CHIMP		CHIMP			246
@@ -259,7 +259,7 @@
 stork_egg		ARCH_STORK_EGG		STORK_EGG		248
 wismo			SA1100_WISMO		WISMO			249
 ezlinx			ARCH_EZLINX		EZLINX			250
-at91rm9200		ARCH_AT91		AT91			251
+at91rm9200		ARCH_AT91RM9200		AT91RM9200		251
 orion			ARCH_ORION		ORION			252
 neptune			ARCH_NEPTUNE		NEPTUNE			253
 hackkit			SA1100_HACKKIT		HACKKIT			254
@@ -295,12 +295,12 @@
 adsbitsyplus		SA1100_ADSBITSYPLUS	ADSBITSYPLUS		284
 adsagc			SA1100_ADSAGC		ADSAGC			285
 stp7312			ARCH_STP7312		STP7312			286
-nx_phnx			ARCH_PXA255		PXA255			287
+nx_phnx			MACH_NX_PHNX		NX_PHNX			287
 wep_ep250		ARCH_WEP_EP250		WEP_EP250		288
 inhandelf3		ARCH_INHANDELF3		INHANDELF3		289
 adi_coyote		ARCH_ADI_COYOTE		ADI_COYOTE		290
 iyonix			ARCH_IYONIX		IYONIX			291
-damicam_sa1110		ARCH_DAMICAM_SA1110	DAMICAM_SA1110		292
+damicam1		ARCH_DAMICAM_SA1110	DAMICAM_SA1110		292
 meg03			ARCH_MEG03		MEG03			293
 pxa_whitechapel		ARCH_PXA_WHITECHAPEL	PXA_WHITECHAPEL		294
 nwsc			ARCH_NWSC		NWSC			295
@@ -356,3 +356,348 @@
 seedpxa_c2		ARCH_SEEDPXA_C2		SEEDPXA_C2		345
 ixp4xx_mguardpci	ARCH_IXP4XX_MGUARD_PCI	IXP4XX_MGUARD_PCI	346
 h1940			ARCH_H1940		H1940			347
+scorpio			ARCH_SCORPIO		SCORPIO			348
+viva			ARCH_VIVA		VIVA			349
+pxa_xcard		ARCH_PXA_XCARD		PXA_XCARD		350
+csb335			ARCH_CSB335		CSB335			351
+ixrd425			ARCH_IXRD425		IXRD425			352
+iq80315			ARCH_IQ80315		IQ80315			353
+nmp7312			ARCH_NMP7312		NMP7312			354
+cx861xx			ARCH_CX861XX		CX861XX			355
+enp2611			ARCH_ENP2611		ENP2611			356
+xda			SA1100_XDA		XDA			357
+csir_ims		ARCH_CSIR_IMS		CSIR_IMS		358
+ixp421_dnaeeth		ARCH_IXP421_DNAEETH	IXP421_DNAEETH		359
+pocketserv9200		ARCH_POCKETSERV9200	POCKETSERV9200		360
+toto			ARCH_TOTO		TOTO			361
+s3c2440			ARCH_S3C2440		S3C2440			362
+ks8695p			ARCH_KS8695P		KS8695P			363
+se4000			ARCH_SE4000		SE4000			364
+quadriceps		ARCH_QUADRICEPS		QUADRICEPS		365
+bronco			ARCH_BRONCO		BRONCO			366
+esl_wireless_tab	ARCH_ESL_WIRELESS_TABLETESL_WIRELESS_TABLET	367
+esl_sofcomp		ARCH_ESL_SOFCOMP	ESL_SOFCOMP		368
+s5c7375			ARCH_S5C7375		S5C7375			369
+spearhead		ARCH_SPEARHEAD		SPEARHEAD		370
+pantera			ARCH_PANTERA		PANTERA			371
+prayoglite		ARCH_PRAYOGLITE		PRAYOGLITE		372
+gumstix			ARCH_GUMSTIK		GUMSTIK			373
+rcube			ARCH_RCUBE		RCUBE			374
+rea_olv			ARCH_REA_OLV		REA_OLV			375
+pxa_iphone		ARCH_PXA_IPHONE		PXA_IPHONE		376
+s3c3410			ARCH_S3C3410		S3C3410			377
+espd_4510b		ARCH_ESPD_4510B		ESPD_4510B		378
+mp1x			ARCH_MP1X		MP1X			379
+at91rm9200tb		ARCH_AT91RM9200TB	AT91RM9200TB		380
+adsvgx			ARCH_ADSVGX		ADSVGX			381
+omap_h2			MACH_OMAP_H2		OMAP_H2			382
+pelee			ARCH_PELEE		PELEE			383
+e740			MACH_E740		E740			384
+iq80331			ARCH_IQ80331		IQ80331			385
+versatile_pb		ARCH_VERSATILE_PB	VERSATILE_PB		387
+kev7a400		MACH_KEV7A400		KEV7A400		388
+lpd7a400		MACH_LPD7A400		LPD7A400		389
+lpd7a404		MACH_LPD7A404		LPD7A404		390
+fujitsu_camelot		ARCH_FUJITSU_CAMELOT	FUJITSU_CAMELOT		391
+janus2m			ARCH_JANUS2M		JANUS2M			392
+embtf			MACH_EMBTF		EMBTF			393
+hpm			MACH_HPM		HPM			394
+smdk2410tk		MACH_SMDK2410TK		SMDK2410TK		395
+smdk2410aj		MACH_SMDK2410AJ		SMDK2410AJ		396
+streetracer		MACH_STREETRACER	STREETRACER		397
+eframe			MACH_EFRAME		EFRAME			398
+csb337			MACH_CSB337		CSB337			399
+pxa_lark		MACH_PXA_LARK		PXA_LARK		400
+pxa_pnp2110		MACH_PNP2110		PNP2110			401
+tcc72x			MACH_TCC72X		TCC72X			402
+altair			MACH_ALTAIR		ALTAIR			403
+kc3			MACH_KC3		KC3			404
+sinteftd		MACH_SINTEFTD		SINTEFTD		405
+mainstone		MACH_MAINSTONE		MAINSTONE		406
+aday4x			MACH_ADAY4X		ADAY4X			407
+lite300			MACH_LITE300		LITE300			408
+s5c7376			MACH_S5C7376		S5C7376			409
+mt02			MACH_MT02		MT02			410
+mport3s			MACH_MPORT3S		MPORT3S			411
+ra_alpha		MACH_RA_ALPHA		RA_ALPHA		412
+xcep			MACH_XCEP		XCEP			413
+arcom_mercury		MACH_ARCOM_MERCURY	ARCOM_MERCURY		414
+stargate		MACH_STARGATE		STARGATE		415
+armadilloj		MACH_ARMADILLOJ		ARMADILLOJ		416
+elroy_jack		MACH_ELROY_JACK		ELROY_JACK		417
+backend			MACH_BACKEND		BACKEND			418
+s5linbox		MACH_S5LINBOX		S5LINBOX		419
+nomadik			MACH_NOMADIK		NOMADIK			420
+ia_cpu_9200		MACH_IA_CPU_9200	IA_CPU_9200		421
+at91_bja1		MACH_AT91_BJA1		AT91_BJA1		422
+corgi			MACH_CORGI		CORGI			423
+poodle			MACH_POODLE		POODLE			424
+ten			MACH_TEN		TEN			425
+roverp5p		MACH_ROVERP5P		ROVERP5P		426
+sc2700			MACH_SC2700		SC2700			427
+ex_eagle		MACH_EX_EAGLE		EX_EAGLE		428
+nx_pxa12		MACH_NX_PXA12		NX_PXA12		429
+nx_pxa5			MACH_NX_PXA5		NX_PXA5			430
+blackboard2		MACH_BLACKBOARD2	BLACKBOARD2		431
+i819			MACH_I819		I819			432
+ixmb995e		MACH_IXMB995E		IXMB995E		433
+skyrider		MACH_SKYRIDER		SKYRIDER		434
+skyhawk			MACH_SKYHAWK		SKYHAWK			435
+enterprise		MACH_ENTERPRISE		ENTERPRISE		436
+dep2410			MACH_DEP2410		DEP2410			437
+armcore			MACH_ARMCORE		ARMCORE			438
+hobbit			MACH_HOBBIT		HOBBIT			439
+h7210			MACH_H7210		H7210			440
+pxa_netdcu5		MACH_PXA_NETDCU5	PXA_NETDCU5		441
+acc			MACH_ACC		ACC			442
+esl_sarva		MACH_ESL_SARVA		ESL_SARVA		443
+xm250			MACH_XM250		XM250			444
+t6tc1xb			MACH_T6TC1XB		T6TC1XB			445
+ess710			MACH_ESS710		ESS710			446
+mx3ads			MACH_MX3ADS		MX3ADS			447
+himalaya		MACH_HIMALAYA		HIMALAYA		448
+bolfenk			MACH_BOLFENK		BOLFENK			449
+at91rm9200kr		MACH_AT91RM9200KR	AT91RM9200KR		450
+edb9312			MACH_EDB9312		EDB9312			451
+omap_generic		MACH_OMAP_GENERIC	OMAP_GENERIC		452
+aximx3			MACH_AXIMX3		AXIMX3			453
+eb67xdip		MACH_EB67XDIP		EB67XDIP		454
+webtxs			MACH_WEBTXS		WEBTXS			455
+hawk			MACH_HAWK		HAWK			456
+ccat91sbc001		MACH_CCAT91SBC001	CCAT91SBC001		457
+expresso		MACH_EXPRESSO		EXPRESSO		458
+h4000			MACH_H4000		H4000			459
+dino			MACH_DINO		DINO			460
+ml675k			MACH_ML675K		ML675K			461
+edb9301			MACH_EDB9301		EDB9301			462
+edb9315			MACH_EDB9315		EDB9315			463
+reciva_tt		MACH_RECIVA_TT		RECIVA_TT		464
+cstcb01			MACH_CSTCB01		CSTCB01			465
+cstcb1			MACH_CSTCB1		CSTCB1			466
+shadwell		MACH_SHADWELL		SHADWELL		467
+goepel263		MACH_GOEPEL263		GOEPEL263		468
+acq100			MACH_ACQ100		ACQ100			469
+mx1fs2			MACH_MX1FS2		MX1FS2			470
+hiptop_g1		MACH_HIPTOP_G1		HIPTOP_G1		471
+sparky			MACH_SPARKY		SPARKY			472
+ns9750			MACH_NS9750		NS9750			473
+phoenix			MACH_PHOENIX		PHOENIX			474
+vr1000			MACH_VR1000		VR1000			475
+deisterpxa		MACH_DEISTERPXA		DEISTERPXA		476
+bcm1160			MACH_BCM1160		BCM1160			477
+pcm022			MACH_PCM022		PCM022			478
+adsgcx			MACH_ADSGCX		ADSGCX			479
+dreadnaught		MACH_DREADNAUGHT	DREADNAUGHT		480
+dm320			MACH_DM320		DM320			481
+markov			MACH_MARKOV		MARKOV			482
+cos7a400		MACH_COS7A400		COS7A400		483
+milano			MACH_MILANO		MILANO			484
+ue9328			MACH_UE9328		UE9328			485
+uex255			MACH_UEX255		UEX255			486
+ue2410			MACH_UE2410		UE2410			487
+a620			MACH_A620		A620			488
+ocelot			MACH_OCELOT		OCELOT			489
+cheetah			MACH_CHEETAH		CHEETAH			490
+omap_perseus2		MACH_OMAP_PERSEUS2	OMAP_PERSEUS2		491
+zvue			MACH_ZVUE		ZVUE			492
+roverp1			MACH_ROVERP1		ROVERP1			493
+asidial2		MACH_ASIDIAL2		ASIDIAL2		494
+s3c24a0			MACH_S3C24A0		S3C24A0			495
+e800			MACH_E800		E800			496
+e750			MACH_E750		E750			497
+s3c5500			MACH_S3C5500		S3C5500			498
+smdk5500		MACH_SMDK5500		SMDK5500		499
+signalsync		MACH_SIGNALSYNC		SIGNALSYNC		500
+nbc			MACH_NBC		NBC			501
+kodiak			MACH_KODIAK		KODIAK			502
+netbookpro		MACH_NETBOOKPRO		NETBOOKPRO		503
+hw90200			MACH_HW90200		HW90200			504
+condor			MACH_CONDOR		CONDOR			505
+cup			MACH_CUP		CUP			506
+kite			MACH_KITE		KITE			507
+scb9328			MACH_SCB9328		SCB9328			508
+omap_h3			MACH_OMAP_H3		OMAP_H3			509
+omap_h4			MACH_OMAP_H4		OMAP_H4			510
+n10			MACH_N10		N10			511
+montejade		MACH_MONTEJADE		MONTEJADE		512
+sg560			MACH_SG560		SG560			513
+dp1000			MACH_DP1000		DP1000			514
+omap_osk		MACH_OMAP_OSK		OMAP_OSK		515
+rg100v3			MACH_RG100V3		RG100V3			516
+mx2ads			MACH_MX2ADS		MX2ADS			517
+pxa_kilo		MACH_PXA_KILO		PXA_KILO		518
+ixp4xx_eagle		MACH_IXP4XX_EAGLE	IXP4XX_EAGLE		519
+tosa			MACH_TOSA		TOSA			520
+mb2520f			MACH_MB2520F		MB2520F			521
+emc1000			MACH_EMC1000		EMC1000			522
+tidsc25			MACH_TIDSC25		TIDSC25			523
+akcpmxl			MACH_AKCPMXL		AKCPMXL			524
+av3xx			MACH_AV3XX		AV3XX			525
+avila			MACH_AVILA		AVILA			526
+pxa_mpm10		MACH_PXA_MPM10		PXA_MPM10		527
+pxa_kyanite		MACH_PXA_KYANITE	PXA_KYANITE		528
+sgold			MACH_SGOLD		SGOLD			529
+oscar			MACH_OSCAR		OSCAR			530
+epxa4usb2		MACH_EPXA4USB2		EPXA4USB2		531
+xsengine		MACH_XSENGINE		XSENGINE		532
+ip600			MACH_IP600		IP600			533
+mcan2			MACH_MCAN2		MCAN2			534
+ddi_blueridge		MACH_DDI_BLUERIDGE	DDI_BLUERIDGE		535
+skyminder		MACH_SKYMINDER		SKYMINDER		536
+lpd79520		MACH_LPD79520		LPD79520		537
+edb9302			MACH_EDB9302		EDB9302			538
+hw90340			MACH_HW90340		HW90340			539
+cip_box			MACH_CIP_BOX		CIP_BOX			540
+ivpn			MACH_IVPN		IVPN			541
+rsoc2			MACH_RSOC2		RSOC2			542
+husky			MACH_HUSKY		HUSKY			543
+boxer			MACH_BOXER		BOXER			544
+shepherd		MACH_SHEPHERD		SHEPHERD		545
+aml42800aa		MACH_AML42800AA		AML42800AA		546
+ml674001		MACH_MACH_TYPE_ML674001	MACH_TYPE_ML674001	547
+lpc2294			MACH_LPC2294		LPC2294			548
+switchgrass		MACH_SWITCHGRASS	SWITCHGRASS		549
+ens_cmu			MACH_ENS_CMU		ENS_CMU			550
+mm6_sdb			MACH_MM6_SDB		MM6_SDB			551
+saturn			MACH_SATURN		SATURN			552
+argonplusevb		MACH_ARGONPLUSEVB	ARGONPLUSEVB		553
+scma11evb		MACH_SCMA11EVB		SCMA11EVB		554
+smdk2800		MACH_SMDK2800		SMDK2800		555
+mtwilson		MACH_MTWILSON		MTWILSON		556
+ziti			MACH_ZITI		ZITI			557
+grandfather		MACH_GRANDFATHER	GRANDFATHER		558
+tengine			MACH_TENGINE		TENGINE			559
+s3c2460			MACH_S3C2460		S3C2460			560
+pdm			MACH_PDM		PDM			561
+h4700			MACH_H4700		H4700			562
+h6300			MACH_H6300		H6300			563
+rz1700			MACH_RZ1700		RZ1700			564
+a716			MACH_A716		A716			565
+estk2440a		MACH_ESTK2440A		ESTK2440A		566
+atwixp425		MACH_ATWIXP425		ATWIXP425		567
+csb336			MACH_CSB336		CSB336			568
+rirm2			MACH_RIRM2		RIRM2			569
+cx23518			MACH_CX23518		CX23518			570
+cx2351x			MACH_CX2351X		CX2351X			571
+computime		MACH_COMPUTIME		COMPUTIME		572
+izarus			MACH_IZARUS		IZARUS			573
+pxa_rts			MACH_RTS		RTS			574
+se5100			MACH_SE5100		SE5100			575
+s3c2510			MACH_S3C2510		S3C2510			576
+csb437tl		MACH_CSB437TL		CSB437TL		577
+slauson			MACH_SLAUSON		SLAUSON			578
+pearlriver		MACH_PEARLRIVER		PEARLRIVER		579
+tdc_p210		MACH_TDC_P210		TDC_P210		580
+sg580			MACH_SG580		SG580			581
+wrsbcarm7		MACH_WRSBCARM7		WRSBCARM7		582
+ipd			MACH_IPD		IPD			583
+pxa_dnp2110		MACH_PXA_DNP2110	PXA_DNP2110		584
+xaeniax			MACH_XAENIAX		XAENIAX			585
+somn4250		MACH_SOMN4250		SOMN4250		586
+pleb2			MACH_PLEB2		PLEB2			587
+cornwallis		MACH_CORNWALLIS		CORNWALLIS		588
+gurney_drv		MACH_GURNEY_DRV		GURNEY_DRV		589
+chaffee			MACH_CHAFFEE		CHAFFEE			590
+rms101			MACH_RMS101		RMS101			591
+rx3715			MACH_RX3715		RX3715			592
+swift			MACH_SWIFT		SWIFT			593
+roverp7			MACH_ROVERP7		ROVERP7			594
+pr818s			MACH_PR818S		PR818S			595
+trxpro			MACH_TRXPRO		TRXPRO			596
+nslu2			MACH_NSLU2		NSLU2			597
+e400			MACH_E400		E400			598
+trab			MACH_TRAB		TRAB			599
+cmc_pu2			MACH_CMC_PU2		CMC_PU2			600
+fulcrum			MACH_FULCRUM		FULCRUM			601
+netgate42x		MACH_NETGATE42X		NETGATE42X		602
+str710			MACH_STR710		STR710			603
+ixdpg425		MACH_IXDPG425		IXDPG425		604
+tomtomgo		MACH_TOMTOMGO		TOMTOMGO		605
+versatile_ab		MACH_VERSATILE_AB	VERSATILE_AB		606
+edb9307			MACH_EDB9307		EDB9307			607
+sg565			MACH_SG565		SG565			608
+lpd79524		MACH_LPD79524		LPD79524		609
+lpd79525		MACH_LPD79525		LPD79525		610
+rms100			MACH_RMS100		RMS100			611
+kb9200			MACH_KB9200		KB9200			612
+sx1			MACH_SX1		SX1			613
+hms39c7092		MACH_HMS39C7092		HMS39C7092		614
+armadillo		MACH_ARMADILLO		ARMADILLO		615
+ipcu			MACH_IPCU		IPCU			616
+loox720			MACH_LOOX720		LOOX720			617
+ixdp465			MACH_IXDP465		IXDP465			618
+ixdp2351		MACH_IXDP2351		IXDP2351		619
+adsvix			MACH_ADSVIX		ADSVIX			620
+dm270			MACH_DM270		DM270			621
+socltplus		MACH_SOCLTPLUS		SOCLTPLUS		622
+ecia			MACH_ECIA		ECIA			623
+cm4008			MACH_CM4008		CM4008			624
+p2001			MACH_P2001		P2001			625
+twister			MACH_TWISTER		TWISTER			626
+mudshark		MACH_MUDSHARK		MUDSHARK		627
+hb2			MACH_HB2		HB2			628
+iq80332			MACH_IQ80332		IQ80332			629
+sendt			MACH_SENDT		SENDT			630
+mx2jazz			MACH_MX2JAZZ		MX2JAZZ			631
+multiio			MACH_MULTIIO		MULTIIO			632
+hrdisplay		MACH_HRDISPLAY		HRDISPLAY		633
+scma11bb		MACH_SCMA11BB		SCMA11BB		634
+trizeps3		MACH_TRIZEPS3		TRIZEPS3		635
+zefeerdza		MACH_ZEFEERDZA		ZEFEERDZA		636
+zefeerdzb		MACH_ZEFEERDZB		ZEFEERDZB		637
+zefeerdzg		MACH_ZEFEERDZG		ZEFEERDZG		638
+zefeerdzn		MACH_ZEFEERDZN		ZEFEERDZN		639
+zefeerdzq		MACH_ZEFEERDZQ		ZEFEERDZQ		640
+gtwx5715		MACH_GTWX5715		GTWX5715		641
+unknown			MACH_VL420		VL420			642
+astro_jack		MACH_ASTRO_JACK		ASTRO_JACK		643
+tip03			MACH_TIP03		TIP03			644
+a9200ec			MACH_A9200EC		A9200EC			645
+pnx0105			MACH_PNX0105		PNX0105			646
+adcpoecpu		MACH_ADCPOECPU		ADCPOECPU		647
+csb637			MACH_CSB637		CSB637			648
+ml69q6203		MACH_ML69Q6203		ML69Q6203		649
+mb9200			MACH_MB9200		MB9200			650
+kulun			MACH_KULUN		KULUN			651
+snapper			MACH_SNAPPER		SNAPPER			652
+optima			MACH_OPTIMA		OPTIMA			653
+dlhsbc			MACH_DLHSBC		DLHSBC			654
+x30			MACH_X30		X30			655
+n30			MACH_N30		N30			656
+manga_ks8695		MACH_MANGA_KS8695	MANGA_KS8695		657
+ajax			MACH_AJAX		AJAX			658
+nec_mp900		MACH_NEC_MP900		NEC_MP900		659
+vvtk1000		MACH_VVTK1000		VVTK1000		661
+kafa			MACH_KAFA		KAFA			662
+vvtk3000		MACH_VVTK3000		VVTK3000		663
+pimx1			MACH_PIMX1		PIMX1			664
+ollie			MACH_OLLIE		OLLIE			665
+skymax			MACH_SKYMAX		SKYMAX			666
+jazz			MACH_JAZZ		JAZZ			667
+tel_t3			MACH_TEL_T3		TEL_T3			668
+aisino_fcr255		MACH_AISINO_FCR255	AISINO_FCR255		669
+btweb			MACH_BTWEB		BTWEB			670
+dbg_lh79520		MACH_DBG_LH79520	DBG_LH79520		671
+cm41xx			MACH_CM41XX		CM41XX			672
+ts72xx			MACH_TS72XX		TS72XX			673
+nggpxa			MACH_NGGPXA		NGGPXA			674
+csb535			MACH_CSB535		CSB535			675
+csb536			MACH_CSB536		CSB536			676
+pxa_trakpod		MACH_PXA_TRAKPOD	PXA_TRAKPOD		677
+praxis			MACH_PRAXIS		PRAXIS			678
+lh75411			MACH_LH75411		LH75411			679
+otom			MACH_OTOM		OTOM			680
+nexcoder_2440		MACH_NEXCODER_2440	NEXCODER_2440		681
+loox410			MACH_LOOX410		LOOX410			682
+westlake		MACH_WESTLAKE		WESTLAKE		683
+nsb			MACH_NSB		NSB			684
+esl_sarva_stn		MACH_ESL_SARVA_STN	ESL_SARVA_STN		685
+esl_sarva_tft		MACH_ESL_SARVA_TFT	ESL_SARVA_TFT		686
+esl_sarva_iad		MACH_ESL_SARVA_IAD	ESL_SARVA_IAD		687
+esl_sarva_acc		MACH_ESL_SARVA_ACC	ESL_SARVA_ACC		688
+typhoon			MACH_TYPHOON		TYPHOON			689
+cnav			MACH_CNAV		CNAV			690
+a730			MACH_A730		A730			691
+netstar			MACH_NETSTAR		NETSTAR			692
+supercon		MACH_PHASEFALE_SUPERCON	PHASEFALE_SUPERCON	693
+shiva1100		MACH_SHIVA1100		SHIVA1100		694
diff -urN linux-2.4.29/arch/armnommu/boot/bootp/bootp.lds linux-2.4.29-uc1/arch/armnommu/boot/bootp/bootp.lds
--- linux-2.4.29/arch/armnommu/boot/bootp/bootp.lds	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/bootp/bootp.lds	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ *  linux/arch/arm/boot/bootp/bootp.lds
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+  . = 0;
+  _text = .;
+  .text : {
+   _stext = .;
+   _start = .;
+   init.o(.start)
+   kernel_start = .;
+   kernel.o
+   kernel_len = . - kernel_start;
+   . = ALIGN(32);
+   *(.text)
+   initrd_start = .;
+   initrd.o
+   initrd_len = . - initrd_start;
+   . = ALIGN(32);
+   _etext = .;
+  }
+  
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+}
diff -urN linux-2.4.29/arch/armnommu/boot/bootp/init.S linux-2.4.29-uc1/arch/armnommu/boot/bootp/init.S
--- linux-2.4.29/arch/armnommu/boot/bootp/init.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/bootp/init.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,92 @@
+/*
+ *  linux/arch/arm/boot/bootp/init.S
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Header file for splitting kernel + initrd.  Note that we pass
+ *  r0 through to r3 straight through.
+ */
+		.section .start,#alloc,#execinstr
+		.type	_entry, #function
+_entry:		adr	r10, initdata
+		ldr	r11, initdata
+		sub	r11, r10, r11		@ work out exec offset
+		b	splitify
+		.size	_entry,. - _entry
+
+		.type	initdata, #object
+initdata:	.word	initdata		@ compiled address of this
+		.size	initdata,. - initdata
+
+		.text
+splitify:	adr	r13, data
+		ldmia	r13!, {r4-r6}		@ move the initrd
+		add	r4, r4, r11		@ correction
+		bl	move
+
+		ldmia	r13!, {r4-r6}		@ then the kernel
+		mov	r12, r5
+		add	r4, r4, r11		@ correction
+		bl	move
+
+/*
+ * Setup the initrd parameters to pass to the kernel.  This can either be
+ * passed in via a param_struct or a tag list.  We spot the param_struct
+ * method by looking at the first word; this should either indicate a page
+ * size of 4K, 16K or 32K.
+ */
+		ldmia	r13, {r5-r8}		@ get size and addr of initrd
+						@ r5 = ATAG_INITRD
+						@ r6 = initrd start
+						@ r7 = initrd end
+						@ r8 = param_struct address
+		ldr	r9, [r8, #0]		@ no param struct?
+		teq	r9, #0x1000		@ 4K?
+		teqne	r9, #0x4000		@ 16K?
+		teqne	r9, #0x8000		@ 32K?
+		beq	no_taglist
+
+/*
+ * find the end of the tag list, and then add an INITRD tag on the end.
+ */
+taglist:	ldr	r9, [r8, #0]		@ tag length
+		teq	r9, #0			@ last tag?
+		addne	r8, r8, r9
+		bne	taglist
+
+		mov	r4, #16			@ length of initrd tag
+		mov	r9, #0			@ end of tag list terminator
+		stmia	r8, {r4, r5, r6, r7, r9}
+		mov	pc, r12			@ call kernel
+
+no_taglist:	add	r8, r8, #16*4
+		stmia	r8, {r6,r7}		@ save in param_struct
+		mov	pc, r12			@ call kernel
+
+move:		ldmia	r4!, {r7 - r10}		@ move 32-bytes at a time
+		stmia	r5!, {r7 - r10}
+		ldmia	r4!, {r7 - r10}
+		stmia	r5!, {r7 - r10}
+		subs	r6, r6, #8 * 4
+		bcs	move
+		mov	pc, lr
+
+data:		.word	initrd_start
+		.word	initrd_addr
+		.word	initrd_len
+
+		.word	kernel_start
+		.word	kernel_addr
+		.word	kernel_len
+
+		.word	0x54410005		@ r5 = ATAG_INITRD
+		.word	initrd_virt		@ r6
+		.word	initrd_len		@ r7
+		.word	params			@ r8
+
+		.type	kernel_start,#object
+		.type	initrd_start,#object
diff -urN linux-2.4.29/arch/armnommu/boot/bootp/Makefile linux-2.4.29-uc1/arch/armnommu/boot/bootp/Makefile
--- linux-2.4.29/arch/armnommu/boot/bootp/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/bootp/Makefile	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,27 @@
+#
+# linux/arch/arm/boot/bootp/Makefile
+#
+
+ZSYSTEM		=$(TOPDIR)/arch/arm/boot/zImage
+INITRD		=$(ZSYSTEM)
+ZLDFLAGS	=-p -X -T bootp.lds \
+		 --defsym initrd_addr=$(INITRD_PHYS) \
+		 --defsym initrd_virt=$(INITRD_VIRT) \
+		 --defsym params=$(PARAMS_PHYS) \
+		 --defsym kernel_addr=$(ZTEXTADDR)
+
+all:		bootp
+
+# Note that bootp.lds picks up kernel.o and initrd.o
+bootp:		init.o kernel.o initrd.o bootp.lds
+		$(LD) $(ZLDFLAGS) -o $@ init.o
+
+kernel.o:	$(ZSYSTEM)
+		$(LD) -r -s -o $@ -b binary $(ZSYSTEM)
+
+initrd.o:	$(INITRD)
+		$(LD) -r -s -o $@ -b binary $(INITRD)
+
+.PHONY:		$(INITRD) $(ZSYSTEM)
+
+clean:;		$(RM) bootp
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/head-clps7500.S linux-2.4.29-uc1/arch/armnommu/boot/compressed/head-clps7500.S
--- linux-2.4.29/arch/armnommu/boot/compressed/head-clps7500.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/head-clps7500.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,87 @@
+/*
+ * linux/arch/arm/boot/compressed/head.S
+ *
+ * Copyright (C) 1999, 2000, 2001 Nexus Electronics Ltd
+ */
+
+#include <linux/config.h>
+
+		/* There are three different ways the kernel can be
+		   booted on a 7500 system: from Angel (loaded in RAM), from
+		   16-bit ROM or from 32-bit Flash.  Luckily, a single kernel
+		   image does for them all. */
+		/* This branch is taken if the CPU memory width matches the
+		   actual device in use.  The default at power on is 16 bits
+		   so we must be prepared for a mismatch. */
+		.section ".start", #alloc, #execinstr
+2:
+		b	1f
+		.word	0xffff
+		.word	0xb632		@ mov r11, #0x03200000
+		.word	0xe3a0
+		.word	0x0000		@ mov r0, #0
+		.word	0xe3a0
+		.word	0x0080		@ strb r0, [r11, #0x80]
+		.word	0xe5cb
+		.word	0xf000		@ mov pc, #0
+		.word	0xe3a0
+1:
+		adr	r1, 2b
+		teq	r1, #0
+		bne	.Langel
+		/* This is a direct-from-ROM boot.  Copy the kernel into 
+		   RAM and run it there. */
+		mov	r0, #0x30
+		mcr	p15, 0, r0, c1, c0, 0
+		mov	r0, #0x13
+		msr	cpsr, r0
+		mov	r12, #0x03000000	@ point to LEDs
+		orr	r12, r12, #0x00020000
+		orr	r12, r12, #0xba00
+		mov	r0, #0x5500
+		str	r0, [r12]
+		mov	r0, #0x10000000
+		orr	r0, r0, #0x8000
+		mov	r4, r0
+		ldr	r2, =_end
+2:
+		ldr	r3, [r1], #4
+		str	r3, [r0], #4
+		teq	r0, r2
+		bne	2b
+		mov	r0, #0xff00
+		str	r0, [r12]
+1:	
+		mov	r12, #0x03000000	@ point to LEDs
+		orr	r12, r12, #0x00020000
+		orr	r12, r12, #0xba00
+		mov	r0, #0xfe00
+		str	r0, [r12]
+
+		adr	lr, 1f
+		mov	r0, #0
+		mov	r1, #14		/* MACH_TYPE_CLPS7500 */
+		mov	pc, lr
+.Langel:
+#ifdef CONFIG_ANGELBOOT
+		/* Call Angel to switch into SVC mode. */
+		mov	r0, #0x17
+		swi	0x123456
+#endif
+		/* Ensure all interrupts are off and MMU disabled */
+		mrs	r0, cpsr
+		orr	r0, r0, #0xc0
+		msr	cpsr, r0
+
+		adr	lr, 1b
+		orr	lr, lr, #0x10000000
+		mov	r0, #0x30		@ MMU off
+		mcr	p15, 0, r0, c1, c0, 0
+		mov	r0, r0
+	 	mov	pc, lr
+
+		.ltorg
+
+1:
+/* And the rest */
+#include "head.S"
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/head-ftvpci.S linux-2.4.29-uc1/arch/armnommu/boot/compressed/head-ftvpci.S
--- linux-2.4.29/arch/armnommu/boot/compressed/head-ftvpci.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/head-ftvpci.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,47 @@
+/* 
+ * linux/arch/arm/boot/compressed/head-ftvpci.S
+ * 
+ * Copyright (C) 2000 FutureTV Labs Ltd.
+ * 
+ * Special startup code for FTV PCI board.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+	.section        ".start", #alloc, #execinstr
+ftv_start:
+	mcr	p15, 0, r0, c7, c5, 0		@ flush I cache
+	mrc	p15, 0, r0, c1, c0
+	orr	r0, r0, #1 << 12
+	mcr	p15, 0, r0, c1, c0		@ enable I cache
+	mov	r0, #0
+	mcreq	p15, 0, r0, c15, c1, 2		@ enable clock switching
+
+	/* check to see if the kernel must be relocated */
+	ldr	ip, =ftv_start
+	adr	sl, ftv_start
+	teq	ip, sl
+	beq	2f				@ no need to copy
+
+	/* in the wrong place -> presumably, executing out of ROM */
+	sub	ip, ip, sl			@ displacement
+	ldr	lr, =_start			@ destination
+	sub	sp, lr, ip			@ source
+	ldr	fp, =_edata			@ end of copied area
+1:	ldmia	sp!, {r0, r1, r2, r3, r4, r5, r6, r10}
+	stmia	lr!, {r0, r1, r2, r3, r4, r5, r6, r10}
+	cmp	lr, fp
+	ble	1b
+
+2:
+	mov	r8, #0
+	mov	r7, #3
+	b	1f
+.ltorg
+1:
+	/* fall back into head.S */
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/head-integrator.S linux-2.4.29-uc1/arch/armnommu/boot/compressed/head-integrator.S
--- linux-2.4.29/arch/armnommu/boot/compressed/head-integrator.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/head-integrator.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,4 @@
+#include <asm/mach-types.h>
+
+		.section	".start", #alloc, #execinstr
+		mov	r7, #MACH_TYPE_INTEGRATOR
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/head-isil.S linux-2.4.29-uc1/arch/armnommu/boot/compressed/head-isil.S
--- linux-2.4.29/arch/armnommu/boot/compressed/head-isil.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/head-isil.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,542 @@
+/* $Header$
+ * linux/arch/arm/boot/compressed/head-poldhu.S
+ *
+ * Copyright (C) 1996-1999 Russell King
+ * Copyright (C) 2002 Intersil Americas Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * 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 <linux/linkage.h>
+#include <linux/config.h>
+
+/* 
+ * The 3893 has a problem with LDMs that cross a 4 kbyte boundary. Therefore
+ * we need to make all LDMs single LDRs.
+ */
+#define ISL3893_NO_LDM
+
+		.section ".start", #alloc, #execinstr
+/*
+ * NOTE: All code in the 'start' section should be position independent
+ *       Code in this section relocates the decompression code
+ *       to the address it is linked on.
+ */
+		.align
+start:
+		.type	start,#function
+		.long	0x59414B4F		@ "OKAY" to identify an image
+		b	relocate
+		.long	0x54535953		@ "SYST"
+		.long	1			@ length = 1
+		.long	3			@ flash status, prefered + valid
+
+/*
+ * Between the .start and the .main section, the boot record
+ * area is located. This is defined in the file bootrec.c and
+ * is linked to the correct location as defined in the linker
+ * script vmlinux.lds.in
+ */
+
+		.section ".main", #alloc, #execinstr
+
+/*
+ * Memory Layout of a compressed kernel image:
+ *
+ * _start ----------------> *=======================* -+
+ * (CONFIG_ZIMAGE_TEXTADDR) |     section "start"   |  |
+ *                          |-----------------------|  |
+ *                          |   Boot Record Area    |  | Position Independent Code
+ * relocate --------------> |-----------------------|  |
+ *                          |    relocation code    |  |
+ * _piggy_start ----------> |-----------------------| -+
+ *                          |                       |
+ *                          |                       |
+ *                          |   Compressed Linux    |
+ *                          |    Image ("piggy")    |
+ *                          |                       |
+ *                          |                       |
+ * _piggy_end ------------> |-----------------------|
+ * _reloc_start-----------> |-----------------------| -+
+ *                          |   decompression code  |  | NOT Position Independent
+ * _reloc_end  -----------> *=======================* -+
+ *
+ * The entry point is at _start + 4. _start is the address that the compressed
+ * kernel image is linked to, but this can be different from the address that
+ * we are currently executing (we can be anywhere in memory). Our real start address
+ * is passed in r0. So (_start - r0) is the offset between where we are executing and
+ * where we are linked. This offset can be used to find out where the code is really
+ * located (in flash or SDRAM). So to find where _piggy_end really is we calculate
+ * _piggy_end - (the offset) = _piggy_end - (_start - r0) = _piggy_end - _start + r0.
+ * NB r0 is stored in r7 in the code below.
+ *
+ * The decompression code is the only part that is not Position Independent (PIC).
+ * Therefore, it must be relocated. Note that we get an error if our real
+ * start address would be larger that our link start address. In that case, the
+ * relocated decompression code would overwrite our "piggy".
+ *
+ * The kernel is eventually decompressed to the link address of the kernel itself
+ * (TEXTADDR), which is defined in arch/armnommu/Makefile.
+ */
+
+
+/*
+ * r0 (saved r7): Our own start address
+ * r1 (saved r8): Address of boot struct
+ * r2 (saved r9): Address of boot parameter block
+ */
+ 
+relocate:
+		mov	r7, r0			@ Save r0, r1, r2
+		mov	r8, r1
+		mov	r9, r2
+		bl	init_uart
+
+	mov	r0, #'O'
+	bl	printch
+
+		ldr	r0, [r8]
+		ldr	r1, =0x59414B4F		@ Check for Boot Magic "OKAY"
+		cmp	r0, r1
+		beq	boot_magic_ok
+		ldr	r1, =0x32765342		@ Check for Boot Magic "BSv2"
+		cmp	r0, r1
+		beq	boot_magic_ok
+		b	boot_magic_error
+
+boot_magic_ok:
+		mov r0, #'K'
+		bl printch
+		adr	r1, LC0
+#ifdef ISL3893_NO_LDM
+		ldr	r2, [r1], #4
+		ldr	r3, [r1], #4
+		ldr	r4, [r1], #4
+		ldr	lr, [r1], #4
+#else
+		ldmia	r1, {r2, r3, r4, lr}
+#endif
+/* r2 = _start
+ * r3 = _reloc_start
+ * r4 = _reloc_end
+ * lr = decomp_entry label
+ */
+
+		cmp	r2, r7			@ Do not relocate if _start == our own start addr
+		moveq	pc, lr
+/* Check if the relocated code overwrites the image that might be stored
+ * in SDRAM (i.e. same address space as where the relocated code ends up).
+ * For the following two conditions we have an error because the relocation
+ * code overwrites the image.
+ * a) If the end of the relocation code < the real image start address
+ *    we can start the relocation code without problems
+ * b) Otherwise if the start of the relocation code <= the real image end
+ *    the relocation code will overwrite the image so jump to reloc error
+ *    otherwise fall through to the relocation code.
+ * For a) the calculation is if reloc_end < _start - ( _start - r0 ) 
+ * with results in if reloc_end < r0 then goto the relocation code
+ * For b) the calculation is if reloc_start <= _reloc_end - ( _start - r0 )
+ * or rewritten as reloc_start <= _reloc_end - _start + r0 then goto the
+ * relocation error code otherwise: start the relocation code.
+ */
+		cmp	r4, r7			@ NB: reloc_end == r4
+		blo	reloc			@ r4 < r0 goto relocation code
+		sub	r5, r4, r2		@ reloc_end - _start
+		add	r5, r5, r7		@ + r0
+		cmp	r4, r5			@ If reloc_start <=
+		bls	reloc_error		@ goto reloc_error
+
+reloc:		sub	r5, r4, r2		@ source of relocation: 
+		add	r5, r5, r7		@ _reloc_end - _start + real_start
+
+1:		.rept	4
+#ifdef ISL3893_NO_LDM
+		ldr	sp, [r5, #-4]!
+		ldr	r12, [r5, #-4]!
+		ldr	r11, [r5, #-4]!
+		ldr	r10, [r5, #-4]!
+		str	sp, [r4, #-4]!
+		str	r12, [r4, #-4]!
+		str	r11, [r4, #-4]!
+		str	r10, [r4, #-4]!
+#else
+		ldmdb	r5!, {r10 - r12, sp}	@ relocate code, 64 bytes each time
+		stmdb	r4!, {r10 - r12, sp}
+#endif
+		.endr
+		sub	r6, r4, r3
+		cmp	r6, #64
+		bgt	1b
+#ifdef ISL3893_NO_LDM
+1:		ldr	r6, [r5, #-4]!
+		str	r6, [r4, #-4]!
+#else
+1:		ldmdb	r5!, {r6}		@ copy the remaining bytes
+		stmdb	r4!, {r6}
+#endif
+		cmp	r4, r3
+		bgt	1b
+
+		mov	pc, lr			@ call relocated code
+
+reloc_error:
+		mov	r4, r0
+		adr	r0, Reloc_Err
+		bl	printascii
+
+		mov	r0, r4			@ Print our real start address
+		bl	printhex8
+loop:		b	loop
+
+LC0:		.word	_start			@ linker generated start address
+		.word	_reloc_start		@ destination for relocation
+		.word	_reloc_end		@ end of relocation
+		.word	decomp_entry
+
+Reloc_Err:	.ascii	"\nFatal error: Relocation overwrites compressed kernel image. r0: 0x\0"
+		.align
+
+		.text
+/*
+ * Now we are relocated to the correct address, so we can set up BSS, stack and
+ * malloc area for the code that is going to decompress the kernel.
+ */
+decomp_entry:
+		mov r0, #'A'
+		bl printch
+
+		mrc	p15, 0, r6, c0, c0	@ get processor ID
+
+		adr	r1, LC1
+
+#ifdef ISL3893_NO_LDM
+		ldr	r2, [r1], #4
+		ldr	r3, [r1], #4
+		ldr	r4, [r1], #4
+		ldr	r5, [r1], #4
+		ldr	sp, [r1], #4
+#else
+		ldmia	r1, {r2, r3, r4, r5, sp}
+#endif
+/*
+ * r2	= __bss_start
+ * r3	= _end
+ * r4	= _load_addr
+ * r5	= _start
+ * sp	= user_stack+4096
+ */
+
+		mov	r0, #0
+1:		str	r0, [r2], #4		@ clear bss
+		str	r0, [r2], #4
+		str	r0, [r2], #4
+		str	r0, [r2], #4
+		cmp	r2, r3
+		blt	1b
+
+/* Calculate the real start and end address of our compressed kernel and store that
+ * in the input_data variables for the decompression algorithm. This should be done
+ * after zeroing BSS!
+ * 	input_data = _piggy_start - link_address of _start label + load_address of _start label
+ */
+		ldr	r1, =input_data
+		ldr	r2, =_piggy_start
+		sub	r2, r2, r5
+		add	r2, r2, r7
+		str	r2, [r1]
+
+		ldr	r1, =input_data_end
+		ldr	r2, =_piggy_end
+		sub	r2, r2, r5
+		add	r2, r2, r7
+		str	r2, [r1]
+
+/* Boot struct:
+ * {
+ * 	unsigned long Magic = "OKAY";
+ * 	unsigned long RAMbase;
+ *	unsigned long RAMsize;
+ * }
+ * Boot struct v2:
+ * {
+ * 	unsigned long Magic = "BSv2";
+ *	void 	    (*reset)(void);
+ *	int	     *BIS_info;
+ * 	unsigned long RAMbase;
+ *	unsigned long RAMsize;
+ * }
+ */
+
+		ldr	r0, [r8]
+		ldr	r1, =0x59414B4F		@ Check for Boot Magic "OKAY"
+		cmp	r0, r1
+		beq	bootstruct_v1
+		ldr	r1, =0x32765342		@ Check for Boot Magic "BSv2"
+		cmp	r0, r1
+		beq	bootstruct_v2
+		b	boot_magic_error
+
+bootstruct_v1:
+		add	r5, r8, #4		@ pointer to RAM base
+		add	r6, r8, #8		@ pointer to RAM size
+		b	1f
+
+bootstruct_v2:
+		add	r5, r8, #12		@ pointer to RAM base
+		add	r6, r8, #16		@ pointer to RAM size
+
+1:		ldr	r0, [r5]		@ get RAM Base
+		ldr	r1, [r6]		@ get RAM size
+
+		cmp	r4, r0			@ Compare load address with RAM Base
+		beq	1f
+		blo	loader_error		@ If the actual load address is before RAM Base
+						@ we're in trouble!
+
+		subs	r0, r4, r0		@ We load ourselfs higher than the RAM
+		subs	r1, r1, r0		@ Base address, so we have less RAM size
+		str	r4, [r5]		@ Store the new RAM base (ie. our load address)
+		str	r1, [r6]		@ Store the new RAM size
+
+1:		add	r2, r4, r1		@ malloc space ends at highest free RAM adress
+		mov	r1, sp			@ malloc space starts above stack
+
+		mov	r0, r4
+		ldr	r3, =_reloc_start
+
+/*
+ * Parameters for 'decompress kernel'
+ * r0   = startaddress for decompressed kernel
+ * r1   = start of malloc area
+ * r2   = end of malloc area
+ * r3   = highest allowed end address for decompressed kernel. This is the start address
+ *	  of this loader, to make sure that we don't overwrite ourselves.
+ * return:
+ * r0	= decompressed kernel length
+ */
+
+		bl	SYMBOL_NAME(decompress_kernel)
+
+/*
+ * Kernel Calling Convention:
+ * r0	= Address where the kernel is loaded
+ * r1	= Pointer to the boot structure
+ * r2   = Pointer to the boot parameter block
+ */
+
+call_kernel:	mov	r0, r4
+		mov	r1, r8			@ restore pointer to boot structure
+		mov	r2, r9			@ restore pointer to boot parameter block
+		mov	pc, r4			@ call kernel
+
+loader_error:	mov	r5, r0			@ r4 = load_addr, r5 = RAM base, r6 = RAM size
+		mov	r6, r1
+		adr	r0, Fatal_1
+		bl	printascii
+		mov	r0, r4			@ load address
+		bl	printhex8
+		mov	r0, #' '
+		bl	printch
+		mov	r0, r5			@ RAM base
+		bl	printhex8
+		mov	r0, #' '
+		bl	printch
+		mov	r0, r6			@ RAM size
+		bl	printhex8
+
+		b	loop_forever
+
+boot_magic_error:
+		mov	r4, r0
+		adr	r0, Boot_Magic_Err
+		bl	printascii
+		mov	r0, r4
+		bl	printhex8
+		b	loop_forever
+
+loop_forever:
+		mov r0, #'?'
+		bl printch
+		b	loop_forever
+
+/*
+ * DEBUGGING SUPPORT. Stolen from arch/armnommu/kernel/debug-armv.S
+ */
+#if defined(CONFIG_ARCH_POLDHU)
+#include <asm/arch/hardware.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/serial.h>
+ENTRY(init_uart)
+        mov     r1, #PERIPH_BASE
+        mov     r0, #0x18
+        orr     r0, r0, r0, lsl #16
+        str     r0, [r1, #uGPIOFSEL - PERIPH_BASE]
+	mov	r0, #0
+	str	r0, [r1, #uUARTCR - PERIPH_BASE]
+	mov	r0, #47					@ baud_div & UARTLCR_LMask
+	str	r0, [r1, #uUARTLCR_L - PERIPH_BASE]
+	mov	r0, #0					@ (baud_div >> 8) & UARTLCR_MMask;
+	str	r0, [r1, #uUARTLCR_M - PERIPH_BASE]
+	mov	r0, #96					@ (3 << UARTLCR_HWLENShift);
+	str	r0, [r1, #uUARTLCR_H - PERIPH_BASE]
+	mov	r0, #UARTCRUARTEN
+	str	r0, [r1, #uUARTCR - PERIPH_BASE]
+        mov     pc, lr
+
+	.macro	addruart,rx
+	mov	\rx, #PERIPH_BASE
+	.endm
+
+	.macro	senduart,rd,rx
+	str	\rd, [\rx, #uUARTDR - PERIPH_BASE]
+	.endm
+
+	.macro	waituart,rd,rx
+1001:	ldr	\rd, [\rx, #uUARTFR - PERIPH_BASE]
+	tst	\rd, #UARTFRTXF
+	bne	1001b
+	.endm
+
+	.macro	busyuart,rd,rx
+1002:	ldr	\rd, [\rx, #uUARTFR - PERIPH_BASE]
+	tst	\rd, #UARTFRBUSY
+	bne	1002b
+	.endm
+#elif defined(CONFIG_ARCH_ISL3893)
+#include <asm/arch/hardware.h>
+#include <asm/arch/serial.h>
+#ifdef ISL3893_SIMSONLY
+/* We only use the Tube here */
+ENTRY(init_uart)
+	/* Nothing to do */
+        mov     pc, lr
+
+	.macro	addruart,rx
+	ldr	\rx, =uTUBEData
+	.endm
+
+	.macro	senduart,rd,rx
+	strb	\rd, [\rx]
+	.endm
+
+	.macro	waituart,rd,rx
+	/* Nothing to do here */
+	.endm
+
+	.macro	busyuart,rd,rx
+	/* Nothing to do here */
+	.endm
+#else /* ISL3893_SIMSONLY */
+ENTRY(init_uart)
+	/* FIXME: Need to fill this in !! */
+        mov     pc, lr
+
+	.macro	addruart,rx
+	mov	\rx, #PERIPH_BASE
+	.endm
+
+	.macro	senduart,rd,rx
+	str	\rd, [\rx, #aUARTRegister0]
+	.endm
+
+	.macro	waituart,rd,rx
+1001:		ldr	\rd, [\rx, #aUARTLineStatus]
+	tst	\rd, #UARTLineStatusTHRE
+	beq	1001b
+	.endm
+
+	.macro	busyuart,rd,rx
+	/* Nothing to do here */
+	.endm
+#endif /* ISL3893_SIMSONLY */
+#else
+#error Unknown architecture
+#endif
+
+/*
+ * Useful debugging routines
+ */
+ENTRY(printhex8)
+		mov	r1, #8
+		b	printhex
+
+ENTRY(printhex4)
+		mov	r1, #4
+		b	printhex
+
+ENTRY(printhex2)
+		mov	r1, #2
+printhex:	ldr	r2, =hexbuf
+		add	r3, r2, r1
+		mov	r1, #0
+		strb	r1, [r3]
+1:		and	r1, r0, #15
+		mov	r0, r0, lsr #4
+		cmp	r1, #10
+		addlt	r1, r1, #'0'
+		addge	r1, r1, #'a' - 10
+		strb	r1, [r3, #-1]!
+		teq	r3, r2
+		bne	1b
+		mov	r0, r2
+		b	printascii
+
+		.ltorg
+
+ENTRY(printascii)
+		addruart r3
+		b	2f
+1:		waituart r2, r3
+		senduart r1, r3
+		busyuart r2, r3
+		teq	r1, #'\n'
+		moveq	r1, #'\r'
+		beq	1b
+2:		teq	r0, #0
+		ldrneb	r1, [r0], #1
+		teqne	r1, #0
+		bne	1b
+		mov	pc, lr
+
+ENTRY(printch)
+		addruart r3
+		mov	r1, r0
+		mov	r0, #0
+		b	1b
+
+hexbuf:		.space 32
+
+
+LC1:		.word	__bss_start
+		.word	_end
+		.word	_load_addr
+		.word	_start
+		.word	user_stack+4096
+		.align
+
+Fatal_1:	.ascii	"\nFatal error: Kernel start address is not in free RAM area. \0"
+		.align
+
+Boot_Magic_Err:	.ascii	"\nFatal error: Bootstruct has wrong Magic: 0x\0"
+		.align
+
+		.section	".stack"
+/* ISL3893_NO_LDM
+ * Need to align the stack on a 4k boundary because of LDM problem
+ * when crossing a 4k boundary
+ */
+		.align	12
+user_stack:	.space	4096
+
+
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/head-l7200.S linux-2.4.29-uc1/arch/armnommu/boot/compressed/head-l7200.S
--- linux-2.4.29/arch/armnommu/boot/compressed/head-l7200.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/head-l7200.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,29 @@
+/* 
+ * linux/arch/arm/boot/compressed/head-l7200.S
+ * 
+ * Copyright (C) 2000 Steve Hill <sjhill@cotw.com>
+ * 
+ * Some code borrowed from Nicolas Pitre's 'head-sa1100.S' file. This
+ * is merged with head.S by the linker.
+ */
+
+#include <linux/config.h>
+
+#ifndef CONFIG_ARCH_L7200
+#error What am I doing here...
+#endif
+
+		.section        ".start", #alloc, #execinstr
+
+__L7200_start:
+		mov	r0, #0x00100000		@ FLASH address of initrd
+		mov	r2, #0xf1000000		@ RAM address of initrd
+		add	r3, r2, #0x00700000	@ Size of initrd 
+1:
+		ldmia   r0!, {r4, r5, r6, r7}
+		stmia   r2!, {r4, r5, r6, r7}
+		cmp	r2, r3
+		ble	1b
+
+		mov	r8, #0			@ Zero it out
+		mov	r7, #19			@ Set architecture ID
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/head-netwinder.S linux-2.4.29-uc1/arch/armnommu/boot/compressed/head-netwinder.S
--- linux-2.4.29/arch/armnommu/boot/compressed/head-netwinder.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/head-netwinder.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ *  linux/arch/arm/boot/compressed/head-netwinder.S
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define K(a,b,c)	((a) << 24 | (b) << 12 | (c))
+
+		.section	".start", #alloc, #execinstr
+
+		/*
+		 * check to see if we are running from the correct address.
+		 * If not, we move ourselves in a two stage process.  Firstly,
+		 * we copy the start of the kernel (which includes this code)
+		 * to 0x8000, and then jump to this code to continue with the
+		 * rest (since this code will get overwritten).
+		 */
+		adr	r2, 1f
+		ldmdb	r2, {r9, r10}
+		and	r3, r2, #0xc000
+		teq	r3, #0x8000	@ correctly located?
+		beq	2f		@ skip this code
+		bic	r3, r2, #0xc000
+		orr	r3, r3, #0x8000
+		mov	r0, r3		@ new address if '1'
+		mov	r4, #64		@ number of bytes to copy
+		sub	r5, r10, r9	@ total number of bytes to copy
+		b	1f
+
+		.word	_start
+		.word	__bss_start
+
+1:
+		.rept	4
+		ldmia	r2!, {r6, r9, r10, r11}
+		stmia	r3!, {r6, r9, r10, r11}
+		.endr
+		subs	r4, r4, #64
+		bcs	1b
+		movs	r4, r5		@ remaining length
+		mov	r5, #0		@ no more to copy
+		movne	pc, r0		@ jump back to 1 (in the newly copied
+					@ code)
+		mov	r7, #5		@ only here to fix NeTTroms which dont
+		mov	r8, #2 << 24		@ scheduled for removal in 2.5.xx
+		orr	r8, r8, #5 << 12
+2:
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/head.S linux-2.4.29-uc1/arch/armnommu/boot/compressed/head.S
--- linux-2.4.29/arch/armnommu/boot/compressed/head.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/head.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,638 @@
+/*
+ *  linux/arch/arm/boot/compressed/head.S
+ *
+ *  Copyright (C) 1996-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/linkage.h>
+
+#if defined(CONFIG_BOARD_SNDS100) || defined(CONFIG_ARCH_DM270)
+#include <asm/hardware.h>
+#endif
+
+/*
+ * Debugging stuff
+ *
+ * Note that these macros must not contain any code which is not
+ * 100% relocatable.  Any attempt to do so will result in a crash.
+ * Please select one of the following when turning on debugging.
+ */
+#ifdef DEBUG
+#if 0 /* DC21285-type */
+		.macro	loadsp,	rb
+		mov	\rb, #0x7c000000
+		.endm
+		.macro	writeb,	rb
+		strb	\rb, [r3, #0x3f8]
+		.endm
+#elif 0 /* RiscPC-type */
+		.macro	loadsp,	rb
+		mov	\rb, #0x03000000
+		orr	\rb, \rb, #0x00010000
+		.endm
+		.macro	writeb,	rb
+		strb	\rb, [r3, #0x3f8 << 2]
+		.endm
+#elif 0 /* integrator-type */
+		.macro	loadsp, rb
+		mov	\rb, #0x16000000
+		.endm
+		.macro	writeb, rb
+		strb	\rb, [r3, #0]
+		.endm
+#else
+#error no serial architecture defined
+#endif
+#endif
+
+		.macro	kputc,val
+		mov	r0, \val
+		bl	putc
+		.endm
+
+		.macro	kphex,val,len
+		mov	r0, \val
+		mov	r1, #\len
+		bl	phex
+		.endm
+
+		.macro	debug_reloc_start
+#ifdef DEBUG
+		kputc	#'\n'
+		kphex	r6, 8		/* processor id */
+		kputc	#':'
+		kphex	r7, 8		/* architecture id */
+		kputc	#':'
+		mrc	p15, 0, r0, c1, c0
+		kphex	r0, 8		/* control reg
+		kputc	#'\n'
+		kphex	r5, 8		/* decompressed kernel start */
+		kputc	#'-'
+		kphex	r8, 8		/* decompressed kernel end  */
+		kputc	#'>'
+		kphex	r4, 8		/* kernel execution address */
+		kputc	#'\n'
+#endif
+		.endm
+
+		.macro	debug_reloc_end
+#ifdef DEBUG
+		kphex	r5, 8		/* end of kernel */
+		kputc	#'\n'
+		mov	r0, r4
+		bl	memdump		/* dump 256 bytes at start of kernel */
+#endif
+		.endm
+
+		.section ".start", #alloc, #execinstr
+/*
+ * sort out different calling conventions
+ */
+		.align
+start:
+		.type	start,#function
+		.rept	8
+		mov	r0, r0
+		.endr
+
+		b	1f
+		.word	0x016f2818		@ Magic numbers to help the loader
+		.word	start			@ absolute load/run zImage address
+		.word	_edata			@ zImage end address
+1:		mov	r7, r1			@ save architecture ID
+		mov	r8, #0			@ save r0
+
+#ifndef __ARM_ARCH_2__
+		/*
+		 * Booting from Angel - need to enter SVC mode and disable
+		 * FIQs/IRQs (numeric definitions from angel arm.h source).
+		 * We only do this if we were in user mode on entry.
+		 */
+		mrs	r0, cpsr		@ get current mode
+		tst	r0, #3			@ not user?
+		bne	not_angel
+		mov	r0, #0x17		@ angel_SWIreason_EnterSVC
+		swi	0x123456		@ angel_SWI_ARM
+not_angel:
+		mrs	r0, cpsr		@ turn off interrupts to
+		orr	r0, r0, #0xc0		@ prevent angel from running
+		msr	cpsr_c, r0
+#else
+		teqp	pc, #0x0c000003		@ turn off interrupts
+#endif
+
+		/*
+		 * Note that some cache flushing and other stuff may
+		 * be needed here - is there an Angel SWI call for this?
+		 */
+
+		/*
+		 * some architecture specific code can be inserted
+		 * by the linker here, but it should preserve r7 and r8.
+		 */
+
+		.text
+#if defined(CONFIG_BOARD_SNDS100) && !defined(CONFIG_ZYXEL_BOOTEXT)
+		/* set system parameters */
+		ldr	r0, =SYSCFG
+		ldr	r1, =rSYSCFG
+		str	r1, [r0]
+
+		/* set reset memory map */
+		adr	r0, SDRAM_SYSINIT_RESET
+		ldmia	r0, {r1-r12}
+		ldr	r0, =SYS_INIT_BASE
+		stmia	r0, {r1-r12}
+
+		/* light led */
+		ldr	r0, =IOPMOD
+		ldr	r1, =0xFF
+		str	r1, [r0]
+
+		ldr	r0, =IOPDATA
+		ldr	r1, =0xEF
+		str	r1, [r0]
+
+		/* copy image to ram */
+		ldr	r0, =0x0
+		ldr	r1, =0x200000		/* 2M */
+		ldr	r2, =0x1000000
+
+rom2ram_copy_loop:
+		ldr	r3, [r0], #4
+		str	r3, [r2], #4
+		subs	r1, r1, #4
+		bne	rom2ram_copy_loop
+
+		/* set boot memroy map */
+		adr	r0, SDRAM_SYSINIT_BOOT
+		ldmia	r0, {r1-r12}
+		ldr	r0, =SYS_INIT_BASE
+		stmia	r0, {r1-r12}
+#endif
+
+1:		adr	r2, LC0
+		ldmia	r2, {r2, r3, r4, r5, sp}
+
+		mov	r0, #0
+1:		str	r0, [r2], #4		@ clear bss
+		str	r0, [r2], #4
+		str	r0, [r2], #4
+		str	r0, [r2], #4
+		cmp	r2, r3
+		blt	1b
+
+#ifdef CONFIG_CPU_WITH_CACHE
+#ifdef CONFIG_BOARD_SNDS100
+		/* cache/write buffer on */
+		ldr	r0, =SYSCFG
+		ldr	r2, [r0]
+		orr	r2, r2, #6
+		str	r2, [r0]
+#elif defined(CONFIG_ARCH_DM270)
+		/*
+		 * Turn on instruction cache
+		 * 1. Disable cache (write "0" to ICAENB)
+		 * 2. Clear cache (write "1" to ICACLR)
+		 * 3. Wait cache clear completion (wait until ICACLR is "0")
+		 * 4. Enable cache (write "1" to ICAENB)
+		 */
+		ldr	r1, =DM270_ICACHE_BASE
+		mov	r0, #0
+		strh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ldr	r0, =(DM270_ICACHE_ICAMODE_ICACLR)
+		strh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+1:		ldrh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ands	r0, r0, #DM270_ICACHE_ICAMODE_ICACLR
+		bne	1b
+		ldr	r0, =(DM270_ICACHE_ICAMODE_ICAENB | DM270_ICACHE_ICAMODE_REQ4W)
+		strh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+#else
+		mrc	p15, 0, r6, c0, c0	@ get processor ID
+		bl	cache_on
+#endif
+#endif	
+
+		mov	r1, sp			@ malloc space above stack
+		add	r2, sp, #0x10000	@ 64k max
+
+#ifdef CONFIG_BOARD_SNDS100
+		mov	r5, r2			@ decompress after image
+#else
+		teq	r4, r5			@ will we overwrite ourselves?
+		moveq	r5, r2			@ decompress after image
+		movne	r5, r4			@ decompress to final location
+#endif
+		mov	r0, r5
+		mov	r3, r7			@ r7 is arch id
+		bl	SYMBOL_NAME(decompress_kernel)
+
+		teq	r4, r5			@ do we need to relocate
+		beq	call_kernel		@ the kernel?
+
+		add	r0, r0, #127
+		bic	r0, r0, #127		@ align the kernel length
+/*
+ * r0     = decompressed kernel length
+ * r1-r3  = unused
+ * r4     = kernel execution address
+ * r5     = decompressed kernel start
+ * r6     = processor ID
+ * r7     = architecture ID
+ * r8-r14 = unused
+ */
+		add	r1, r5, r0		@ end of decompressed kernel
+		adr	r2, reloc_start
+		adr	r3, reloc_end
+1:		ldmia	r2!, {r8 - r13}		@ copy relocation code
+		stmia	r1!, {r8 - r13}
+		ldmia	r2!, {r8 - r13}
+		stmia	r1!, {r8 - r13}
+		cmp	r2, r3
+		blt	1b
+
+#ifdef CONFIG_CPU_WITH_CACHE
+		bl	cache_clean_flush
+#endif
+		add	pc, r5, r0		@ call relocation code
+
+		.type	LC0, #object
+LC0:		.word	__bss_start
+		.word	_end
+		.word	_load_addr
+		.word	_start
+		.word	user_stack+4096
+		.size	LC0, . - LC0
+
+#if defined(CONFIG_BOARD_SNDS100) && !defined(CONFIG_ZYXEL_BOOTEXT)
+SDRAM_SYSINIT_RESET:	.word	rEXTDBWTH
+			.word	rROMCON0_R
+			.word	rROMCON1
+			.word	rROMCON2
+			.word	rROMCON3
+			.word	rROMCON4
+			.word	rROMCON5
+			.word	rSDRAMCON0_R
+			.word	rSDRAMCON1
+			.word	rSDRAMCON2
+			.word	rSDRAMCON3
+			.word	rREFEXTCON
+
+SDRAM_SYSINIT_BOOT:	.word	rEXTDBWTH
+			.word	rROMCON0_B
+			.word	rROMCON1
+			.word	rROMCON2
+			.word	rROMCON3
+			.word	rROMCON4
+			.word	rROMCON5
+			.word	rSDRAMCON0_B
+			.word	rSDRAMCON1
+			.word	rSDRAMCON2
+			.word	rSDRAMCON3
+			.word	rREFEXTCON
+#endif
+
+/*
+ * Turn on the cache.  We need to setup some page tables so that we
+ * can have both the I and D caches on.
+ *
+ * We place the page tables 16k down from the kernel execution address,
+ * and we hope that nothing else is using it.  If we're using it, we
+ * will go pop!
+ *
+ * On entry,
+ *  r4 = kernel execution address
+ *  r6 = processor ID
+ *  r7 = architecture number
+ *  r8 = run-time address of "start"
+ * On exit,
+ *  r0, r1, r2, r3, r8, r9 corrupted
+ * This routine must preserve:
+ *  r4, r5, r6, r7
+ */
+		.align	5
+cache_on:	ldr	r1, proc_sa110_type
+		eor	r1, r1, r6
+		movs	r1, r1, lsr #5		@ catch SA110 and SA1100
+		beq	1f
+		ldr     r1, proc_sa1110_type
+		eor	r1, r1, r6
+		movs	r1, r1, lsr #4
+		movne	pc, lr
+1:
+		sub	r3, r4, #16384		@ Page directory size
+		bic	r3, r3, #0xff		@ Align the pointer
+		bic	r3, r3, #0x3f00
+/*
+ * Initialise the page tables, turning on the cacheable and bufferable
+ * bits for the RAM area only.
+ */
+		mov	r0, r3
+		mov	r8, r0, lsr #18
+		mov	r8, r8, lsl #18		@ start of RAM
+		add	r9, r8, #0x10000000	@ a reasonable RAM size
+		mov	r1, #0x12
+		orr	r1, r1, #3 << 10
+		add	r2, r3, #16384
+1:		cmp	r1, r8			@ if virt > start of RAM
+		orrge	r1, r1, #0x0c		@ set cacheable, bufferable
+		cmp	r1, r9			@ if virt > end of RAM
+		bicge	r1, r1, #0x0c		@ clear cacheable, bufferable
+		str	r1, [r0], #4		@ 1:1 mapping
+		add	r1, r1, #1048576
+		teq	r0, r2
+		bne	1b
+/*
+ * If ever we are running from Flash, then we surely want the cache
+ * to be enabled also for our execution instance...  We map 2MB of it
+ * so there is no map overlap problem for up to 1 MB compressed kernel.
+ * If the execution is in RAM then we would only be duplicating the above.
+ */
+		mov	r1, #0x1e
+		orr	r1, r1, #3 << 10
+		mov	r2, pc, lsr #20
+		orr	r1, r1, r2, lsl #20
+		add	r0, r3, r2, lsl #2
+		str	r1, [r0], #4
+		add	r1, r1, #1048576
+		str	r1, [r0]
+
+		mov	r0, #0
+		mcr	p15, 0, r0, c7, c10, 4	@ drain write buffer
+		mcr	p15, 0, r0, c8, c7	@ flush I,D TLBs
+		mcr	p15, 0, r3, c2, c0	@ load page table pointer
+		mov	r0, #-1
+		mcr	p15, 0, r0, c3, c0	@ load domain access register
+		mrc	p15, 0, r0, c1, c0
+		orr	r0, r0, #0x1000		@ I-cache enable
+#ifndef DEBUG
+		orr	r0, r0, #0x003d		@ Write buffer, mmu
+#endif
+		mcr	p15, 0, r0, c1, c0
+		mov	pc, lr
+
+/*
+ * This code is relocatable.  It is relocated by the above code to the end
+ * of the kernel and executed there.  During this time, we have no stacks.
+ *
+ * r0     = decompressed kernel length
+ * r1-r3  = unused
+ * r4     = kernel execution address
+ * r5     = decompressed kernel start
+ * r6     = processor ID
+ * r7     = architecture ID
+ * r8-r14 = unused
+ */
+		.align	5
+reloc_start:	add	r8, r5, r0
+		debug_reloc_start
+		mov	r1, r4
+1:
+		.rept	4
+		ldmia	r5!, {r0, r2, r3, r9 - r13}	@ relocate kernel
+		stmia	r1!, {r0, r2, r3, r9 - r13}
+		.endr
+
+		cmp	r5, r8
+		blt	1b
+		debug_reloc_end
+
+call_kernel:	
+#ifdef CONFIG_CPU_WITH_CACHE
+		bl	cache_clean_flush
+		bl	cache_off
+#endif
+		mov	r0, #0
+		mov	r1, r7			@ restore architecture number
+		mov	pc, r4			@ call kernel
+
+/*
+ * Here follow the relocatable cache support functions for
+ * the various processors.
+ */
+
+		.type	proc_sa110_type,#object
+proc_sa110_type:
+		.word	0x4401a100
+		.size	proc_sa110_type, . - proc_sa110_type
+
+		.type	proc_sa1110_type,#object
+proc_sa1110_type:
+		.word	0x6901b110
+		.size	proc_sa1110_type, . - proc_sa1110_type
+
+
+#ifdef CONFIG_CPU_WITH_CACHE
+/*
+ * Turn off the Cache and MMU.  ARMv3 does not support
+ * reading the control register, but ARMv4 does.
+ *
+ * On entry,  r6 = processor ID
+ * On exit,   r0, r1 corrupted
+ * This routine must preserve: r4, r6, r7
+ */
+		.align	5
+cache_off:
+#ifdef CONFIG_BOARD_SNDS100
+		ldr	r0, =SYSCFG
+		ldr	r1, [r0]
+		bic	r1, r1, #6
+		str	r1, [r0]
+		mov	pc, lr
+#elif defined(CONFIG_ARCH_DM270)
+		/*
+		 * Turn off instruction cache
+		 * 1. Disable cache (write "0" to ICAENB)
+		 * 2. Clear cache (write "1" to ICACLR)
+		 * 3. Wait cache clear completion (wait until ICACLR is "0")
+		 */
+		ldr	r1, =DM270_ICACHE_BASE
+		mov	r0, #0
+		strh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ldr	r0, =(DM270_ICACHE_ICAMODE_ICACLR)
+		strh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+1:		ldrh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ands	r0, r0, #DM270_ICACHE_ICAMODE_ICACLR
+		bne	1b
+
+		mov	pc, lr
+#else
+#ifdef CONFIG_CPU_ARM610
+		eor	r1, r6, #0x41000000
+		eor	r1, r1, #0x00560000
+		bic	r1, r1, #0x0000001f
+		teq	r1, #0x00000600
+		mov	r0, #0x00000060		@ ARM6 control reg.
+		beq	__armv3_cache_off
+#endif
+#ifdef CONFIG_CPU_ARM710
+		eor	r1, r6, #0x41000000
+		bic	r1, r1, #0x00070000
+		bic	r1, r1, #0x000000ff
+		teq	r1, #0x00007000		@ ARM7
+		teqne	r1, #0x00007100		@ ARM710
+		mov	r0, #0x00000070		@ ARM7 control reg.
+		beq	__armv3_cache_off
+#endif
+		mrc	p15, 0, r0, c1, c0
+		bic	r0, r0, #0x000d
+		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
+		mov	r0, #0
+		mcr	p15, 0, r0, c7, c7	@ invalidate whole cache v4
+		mcr	p15, 0, r0, c8, c7	@ invalidate whole TLB v4
+		mov	pc, lr
+
+__armv3_cache_off:
+		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
+		mov	r0, #0
+		mcr	p15, 0, r0, c7, c0	@ invalidate whole cache v3
+		mcr	p15, 0, r0, c5, c0	@ invalidate whole TLB v3
+		mov	pc, lr
+#endif
+/*
+ * Clean and flush the cache to maintain consistency.
+ *
+ * On entry,
+ *  r6 = processor ID
+ * On exit,
+ *  r1, r2, r12 corrupted
+ * This routine must preserve:
+ *  r4, r6, r7
+ */
+		.align	5
+cache_clean_flush:
+#ifdef CONFIG_BOARD_SNDS100
+		ldr	r1, =TAG_BASE
+		mov	r2, #0
+		mov	r12, #256
+
+cache_flush_loop:
+		str	r2, [r1], #4
+		subs	r12, r12, #1
+		bne	cache_flush_loop
+		mov	pc, lr
+#elif defined(CONFIG_ARCH_DM270)
+		/*
+		 * Clean and flush instruction cache
+		 * 1. Save cache state
+		 * 2. Disable cache (write "0" to ICAENB)
+		 * 3. Clear cache (write "1" to ICACLR)
+		 * 4. Wait cache clear completion (wait until ICACLR is "0")
+		 * 5. Restore previous cache state
+		 */
+		ldr	r1, =DM270_ICACHE_BASE
+		ldrh	r2, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ldr	r12, =(DM270_ICACHE_ICAMODE_ICAENB | DM270_ICACHE_ICAMODE_REQ4W)
+		and	r2, r2, r12
+		mov	r12, #0
+		strh	r12, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ldr	r12, =(DM270_ICACHE_ICAMODE_ICACLR)
+		strh	r12, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+1:		ldrh	r12, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ands	r12, r12, #DM270_ICACHE_ICAMODE_ICACLR
+		bne	1b
+		strh	r2, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+
+		mov	pc, lr
+#else
+		ldr	r1, proc_sa110_type
+		eor	r1, r1, r6
+		movs	r1, r1, lsr #5		@ catch SA110 and SA1100
+		beq	1f
+		ldr	r1, proc_sa1110_type
+		eor	r1, r1, r6
+		movs	r1, r1, lsr #4
+		movne	pc, lr
+1:
+		bic	r1, pc, #31
+		add	r2, r1, #32768
+1:		ldr	r12, [r1], #32		@ s/w flush D cache
+		teq	r1, r2
+		bne	1b
+
+		mcr	p15, 0, r1, c7, c7, 0	@ flush I cache
+		mcr	p15, 0, r1, c7, c10, 4	@ drain WB
+		mov	pc, lr
+#endif
+#endif
+/*
+ * Various debugging routines for printing hex characters and
+ * memory, which again must be relocatable.
+ */
+#ifdef DEBUG
+		.type	phexbuf,#object
+phexbuf:	.space	12
+		.size	phexbuf, . - phexbuf
+
+phex:		adr	r3, phexbuf
+		mov	r2, #0
+		strb	r2, [r3, r1]
+1:		subs	r1, r1, #1
+		movmi	r0, r3
+		bmi	puts
+		and	r2, r0, #15
+		mov	r0, r0, lsr #4
+		cmp	r2, #10
+		addge	r2, r2, #7
+		add	r2, r2, #'0'
+		strb	r2, [r3, r1]
+		b	1b
+
+puts:		loadsp	r3
+1:		ldrb	r2, [r0], #1
+		teq	r2, #0
+		moveq	pc, lr
+2:		writeb	r2
+		mov	r1, #0x00020000
+3:		subs	r1, r1, #1
+		bne	3b
+		teq	r2, #'\n'
+		moveq	r2, #'\r'
+		beq	2b
+		teq	r0, #0
+		bne	1b
+		mov	pc, lr
+putc:
+		mov	r2, r0
+		mov	r0, #0
+		loadsp	r3
+		b	2b
+
+memdump:	mov	r12, r0
+		mov	r10, lr
+		mov	r11, #0
+2:		mov	r0, r11, lsl #2
+		add	r0, r0, r12
+		mov	r1, #8
+		bl	phex
+		mov	r0, #':'
+		bl	putc
+1:		mov	r0, #' '
+		bl	putc
+		ldr	r0, [r12, r11, lsl #2]
+		mov	r1, #8
+		bl	phex
+		and	r0, r11, #7
+		teq	r0, #3
+		moveq	r0, #' '
+		bleq	putc
+		and	r0, r11, #7
+		add	r11, r11, #1
+		teq	r0, #7
+		bne	1b
+		mov	r0, #'\n'
+		bl	putc
+		cmp	r11, #64
+		blt	2b
+		mov	pc, r10
+#endif
+
+reloc_end:
+
+		.align
+		.section	".stack"
+user_stack:	.space	4096
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/head-sa1100.S linux-2.4.29-uc1/arch/armnommu/boot/compressed/head-sa1100.S
--- linux-2.4.29/arch/armnommu/boot/compressed/head-sa1100.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/head-sa1100.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,63 @@
+/* 
+ * linux/arch/arm/boot/compressed/head-sa1100.S
+ * 
+ * Copyright (C) 1999 Nicolas Pitre <nico@cam.org>
+ * 
+ * SA1100 specific tweaks.  This is merged into head.S by the linker.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/mach-types.h>
+
+		.section        ".start", #alloc, #execinstr
+
+__SA1100_start:
+
+		@ Preserve r8/r7 i.e. kernel entry values
+
+#ifdef CONFIG_SA1100_VICTOR
+		teq	r7, #MACH_TYPE_VICTOR
+		bne	10f
+
+		@ Copy cmdline to 0xc0000000
+		mov	r1, #0xc0000000
+		cmp	r0, #0
+		moveq	r2, #0
+1:		ldrneb	r2, [r0], #1
+		cmpne	r2, #0
+		strb	r2, [r1], #1
+		bne	1b
+10:
+#endif
+
+		@ Data cache might be active.
+		@ Be sure to flush kernel binary out of the cache,
+		@ whatever state it is, before it is turned off.
+		@ This is done by fetching through currently executed
+		@ memory to be sure we hit the same cache.
+		bic	r2, pc, #0x1f
+		add	r3, r2, #0x4000		@ 16 kb is quite enough...
+1:		ldr	r0, [r2], #32
+		teq	r2, r3
+		bne	1b
+		mcr	p15, 0, r0, c7, c10, 4	@ drain WB
+		mcr	p15, 0, r0, c7, c7, 0	@ flush I & D caches
+
+		@ disabling MMU and caches
+		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
+		bic	r0, r0, #0x0d		@ clear WB, DC, MMU
+		bic	r0, r0, #0x1000		@ clear Icache
+		mcr	p15, 0, r0, c1, c0, 0
+
+#ifdef CONFIG_ANGELBOOT
+/*
+ * Pause for a short time so that we give enough time
+ * for the host to start a terminal up.
+ */
+		mov	r0, #0x00200000
+1:		subs	r0, r0, #1
+		bne	1b
+#endif
+
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/head-shark.S linux-2.4.29-uc1/arch/armnommu/boot/compressed/head-shark.S
--- linux-2.4.29/arch/armnommu/boot/compressed/head-shark.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/head-shark.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,115 @@
+/* The head-file for the Shark
+ * by Alexander Schulz <aschulz@netwinder.org>
+ *
+ * Does the following:
+ * - get the memory layout from firmware. This can only be done as long as the mmu
+ *   is still on.
+ * - switch the mmu off, so we have physical addresses
+ * - copy the kernel to 0x08508000. This is done to have a fixed address where the
+ *   C-parts (misc.c) are executed. This address must be known at compile-time,
+ *   but the load-address of the kernel depends on how much memory is installed.
+ * - Jump to this location.
+ * - Set r8 with 0, r7 with the architecture ID for head.S
+ */
+
+#include <linux/linkage.h>
+
+#include <asm/assembler.h>
+	
+		.section	".start", #alloc, #execinstr
+
+		b	__beginning
+	
+__ofw_data:	.long	0				@ the number of memory blocks
+		.space  128				@ (startaddr,size) ...
+		.space  128				@ bootargs
+		.align
+
+__beginning:	mov	r4, r0				@ save the entry to the firmware
+
+		mov	r0, #0xC0			@ disable irq and fiq
+		mov	r1, r0
+		mrs	r3, cpsr
+		bic	r2, r3, r0
+		eor	r2, r2, r1
+		msr	cpsr_c, r2
+
+		mov	r0, r4				@ get the Memory layout from firmware
+		adr	r1, __ofw_data
+		add	r2, r1, #4
+		mov	lr, pc
+		b	SYMBOL_NAME(ofw_init)
+		mov	r1, #0
+
+		adr	r2, __mmu_off			@ calculate physical address
+		sub	r2, r2, #0xf0000000		@ openprom maps us at f000 virt, 0e50 phys
+		adr	r0, __ofw_data
+		ldr	r0, [r0, #4]
+		add	r2, r2, r0
+		add	r2, r2, #0x00500000
+
+		mrc	p15, 0, r3, c1, c0
+		bic	r3, r3, #0xC			@ Write Buffer and DCache
+		bic	r3, r3, #0x1000			@ ICache
+		mcr	p15, 0, r3, c1, c0		@ disabled
+
+		mov	r0, #0
+		mcr	p15, 0, r0, c7, c7		@ flush I,D caches on v4
+		mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
+		mcr	p15, 0, r0, c8, c7		@ flush I,D TLBs on v4
+
+		bic	r3, r3, #0x1			@ MMU
+		mcr	p15, 0, r3, c1, c0		@ disabled
+
+		mov	pc, r2
+
+__copy_target:	.long	0x08508000
+__copy_end:	.long	0x08608000
+		
+		.word	_start
+		.word	__bss_start
+
+		.align
+__temp_stack:	.space 128
+
+__mmu_off:
+		adr	r0, __ofw_data
+		ldr	r0, [r0, #4]
+		orr	r0, r0, #0x00600000
+	
+		ldr	r1, __copy_end
+		ldr	r3, __copy_target
+
+/* r0 = 0x0e600000 (current end of kernelcode)
+ * r3 = 0x08508000 (where it should begin)
+ * r1 = 0x08608000 (end of copying area, 1MB)
+ * The kernel is compressed, so 1 MB should be enough.
+ * copy the kernel to the beginning of physical memory
+ * We start from the highest address, so we can copy
+ * from 0x08500000 to 0x08508000 if we have only 8MB
+ */
+
+	
+__Copy:		ldr	r2, [r0], #-4
+		str	r2, [r1], #-4
+		teq	r1, r3
+		bne	__Copy
+		/* and jump to it */
+		adr	r2, __go_on
+		adr	r0, __ofw_data
+		ldr	r0, [r0, #4]
+		sub	r2, r2, r0
+		sub	r2, r2, #0x00500000
+		ldr	r0, __copy_target
+		add	r2, r2, r0
+		mov	pc, r2
+
+__go_on:
+		adr	sp, __temp_stack
+		add	sp, sp, #128
+		adr	r0, __ofw_data
+		mov	lr, pc
+		b	SYMBOL_NAME(create_params)
+	
+		mov	r8, #0
+		mov	r7, #15
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/hw-bse.c linux-2.4.29-uc1/arch/armnommu/boot/compressed/hw-bse.c
--- linux-2.4.29/arch/armnommu/boot/compressed/hw-bse.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/hw-bse.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,74 @@
+/*
+ * Bright Star Engineering Inc.
+ *
+ * code for readng parameters from the
+ * parameter blocks of the boot block
+ * flash memory
+ *
+ */
+
+static int strcmp(const char *s1, const char *s2)
+{
+  while (*s1 != '\0' && *s1 == *s2)
+    {
+      s1++;
+      s2++;
+    }
+
+  return (*(unsigned char *) s1) - (*(unsigned char *) s2);
+}
+
+struct pblk_t {
+  char type;
+  unsigned short size;
+};
+
+static char *bse_getflashparam(char *name) {
+  unsigned int esize;
+  char *q,*r;
+  unsigned char *p,*e;
+  struct pblk_t *thepb = (struct pblk_t *) 0x00004000;
+  struct pblk_t *altpb = (struct pblk_t *) 0x00006000;  
+  if (thepb->type&1) {
+    if (altpb->type&1) {
+      /* no valid param block */ 
+      return (char*)0;
+    } else {
+      /* altpb is valid */
+      struct pblk_t *tmp;
+      tmp = thepb;
+      thepb = altpb;
+      altpb = tmp;
+    }
+  }
+  p = (char*)thepb + sizeof(struct pblk_t);
+  e = p + thepb->size; 
+  while (p < e) {
+    q = p;
+    esize = *p;
+    if (esize == 0xFF) break;
+    if (esize == 0) break;
+    if (esize > 127) {
+      esize = (esize&0x7F)<<8 | p[1];
+      q++;
+    }
+    q++;
+    r=q;
+    if (*r && ((name == 0) || (!strcmp(name,r)))) {
+      while (*q++) ;
+      return q;
+    }
+    p+=esize;
+  }
+  return (char*)0;
+}
+
+void bse_setup(void) {
+  /* extract the linux cmdline from flash */
+  char *name=bse_getflashparam("linuxboot");
+  char *x = (char *)0xc0000100;
+  if (name) { 
+    while (*name) *x++=*name++;
+  }
+  *x=0;
+}
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/ll_char_wr.S linux-2.4.29-uc1/arch/armnommu/boot/compressed/ll_char_wr.S
--- linux-2.4.29/arch/armnommu/boot/compressed/ll_char_wr.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/ll_char_wr.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,162 @@
+/*
+ *  linux/arch/arm/lib/ll_char_wr.S
+ *
+ *  Copyright (C) 1995, 1996 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Speedups & 1bpp code (C) 1996 Philip Blundell & Russell King.
+ *
+ *  10-04-96	RMK	Various cleanups & reduced register usage.
+ *  08-04-98	RMK	Shifts re-ordered
+ */
+
+@ Regs: [] = corruptible
+@       {} = used
+@       () = do not use
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+		.text
+
+#define BOLD            0x01
+#define ITALIC          0x02
+#define UNDERLINE       0x04
+#define FLASH           0x08
+#define INVERSE         0x10
+
+LC0:		.word	SYMBOL_NAME(bytes_per_char_h)
+		.word	SYMBOL_NAME(video_size_row)
+		.word	SYMBOL_NAME(acorndata_8x8)
+		.word	SYMBOL_NAME(con_charconvtable)
+
+ENTRY(ll_write_char)
+		stmfd	sp!, {r4 - r7, lr}
+@
+@ Smashable regs: {r0 - r3}, [r4 - r7], (r8 - fp), [ip], (sp), [lr], (pc)
+@
+		eor	ip, r1, #UNDERLINE << 9
+/*
+ * calculate colours
+ */
+		tst	r1, #INVERSE << 9
+		moveq	r2, r1, lsr #16
+		moveq	r3, r1, lsr #24
+		movne	r2, r1, lsr #24
+		movne	r3, r1, lsr #16
+		and	r3, r3, #255
+		and	r2, r2, #255
+/*
+ * calculate offset into character table
+ */
+		mov	r1, r1, lsl #23
+		mov	r1, r1, lsr #20
+/*
+ * calculate offset required for each row [maybe I should make this an argument to this fn.
+ * Have to see what the register usage is like in the calling routines.
+ */
+		adr	r4, LC0
+		ldmia	r4, {r4, r5, r6, lr}
+		ldr	r4, [r4]
+		ldr	r5, [r5]
+/*
+ * Go to resolution-dependent routine...
+ */
+		cmp	r4, #4
+		blt	Lrow1bpp
+		eor	r2, r3, r2			@ Create eor mask to change colour from bg
+		orr	r3, r3, r3, lsl #8		@ to fg.
+		orr	r3, r3, r3, lsl #16
+		add	r0, r0, r5, lsl #3		@ Move to bottom of character
+		add	r1, r1, #7
+		ldrb	r7, [r6, r1]
+		tst	ip, #UNDERLINE << 9
+		eoreq	r7, r7, #255
+		teq	r4, #8
+		beq	Lrow8bpplp
+@
+@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
+@
+		orr	r3, r3, r3, lsl #4
+Lrow4bpplp:	ldr	r7, [lr, r7, lsl #2]
+		mul	r7, r2, r7
+		tst	r1, #7				@ avoid using r7 directly after
+		eor	ip, r3, r7
+		str	ip, [r0, -r5]!
+		LOADREGS(eqfd, sp!, {r4 - r7, pc})
+		sub	r1, r1, #1
+		ldrb	r7, [r6, r1]
+		ldr	r7, [lr, r7, lsl #2]
+		mul	r7, r2, r7
+		tst	r1, #7				@ avoid using r7 directly after
+		eor	ip, r3, r7
+		str	ip, [r0, -r5]!
+		subne	r1, r1, #1
+		ldrneb	r7, [r6, r1]
+		bne	Lrow4bpplp
+		LOADREGS(fd, sp!, {r4 - r7, pc})
+
+@
+@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
+@
+Lrow8bpplp:	mov	ip, r7, lsr #4
+		ldr	ip, [lr, ip, lsl #2]
+		mul	r4, r2, ip
+		and	ip, r7, #15			@ avoid r4
+		ldr	ip, [lr, ip, lsl #2]		@ avoid r4
+		mul	ip, r2, ip			@ avoid r4
+		eor	r4, r3, r4			@ avoid ip
+		tst	r1, #7				@ avoid ip
+		sub	r0, r0, r5			@ avoid ip
+		eor	ip, r3, ip
+		stmia	r0, {r4, ip}
+		LOADREGS(eqfd, sp!, {r4 - r7, pc})
+		sub	r1, r1, #1
+		ldrb	r7, [r6, r1]
+		mov	ip, r7, lsr #4
+		ldr	ip, [lr, ip, lsl #2]
+		mul	r4, r2, ip
+		and	ip, r7, #15			@ avoid r4
+		ldr	ip, [lr, ip, lsl #2]		@ avoid r4
+		mul	ip, r2, ip			@ avoid r4
+		eor	r4, r3, r4			@ avoid ip
+		tst	r1, #7				@ avoid ip
+		sub	r0, r0, r5			@ avoid ip
+		eor	ip, r3, ip
+		stmia	r0, {r4, ip}
+		subne	r1, r1, #1
+		ldrneb	r7, [r6, r1]
+		bne	Lrow8bpplp
+		LOADREGS(fd, sp!, {r4 - r7, pc})
+
+@
+@ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc)
+@
+Lrow1bpp:	add	r6, r6, r1
+		ldmia	r6, {r4, r7}
+		tst	ip, #INVERSE << 9
+		mvnne	r4, r4
+		mvnne	r7, r7
+		strb	r4, [r0], r5
+		mov	r4, r4, lsr #8
+		strb	r4, [r0], r5
+		mov	r4, r4, lsr #8
+		strb	r4, [r0], r5
+		mov	r4, r4, lsr #8
+		strb	r4, [r0], r5
+		strb	r7, [r0], r5
+		mov	r7, r7, lsr #8
+		strb	r7, [r0], r5
+		mov	r7, r7, lsr #8
+		strb	r7, [r0], r5
+		mov	r7, r7, lsr #8
+		tst	ip, #UNDERLINE << 9
+		mvneq	r7, r7
+		strb	r7, [r0], r5
+		LOADREGS(fd, sp!, {r4 - r7, pc})
+
+		.bss
+ENTRY(con_charconvtable)
+		.space	1024
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/Makefile linux-2.4.29-uc1/arch/armnommu/boot/compressed/Makefile
--- linux-2.4.29/arch/armnommu/boot/compressed/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/Makefile	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,112 @@
+#
+# linux/arch/arm/boot/compressed/Makefile
+#
+# create a compressed vmlinuz image from the original vmlinux
+#
+# Note! SYSTEM, ZTEXTADDR, ZBSSADDR and ZRELADDR are now exported
+# from arch/arm/boot/Makefile
+#
+
+HEAD		 = head.o
+OBJS		 = misc.o
+
+CFLAGS		 = $(CPPFLAGS) -O2 -DSTDC_HEADERS $(CFLAGS_PROC) -msoft-float -D__linux__
+
+FONTC		 = $(TOPDIR)/drivers/video/font_acorn_8x8.c
+ZLDFLAGS	 = -p -X -T $(LINUX).lds
+
+ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
+  CFLAGS += -mbig-endian
+  ZLDFLAGS += -EB
+  PIGOFLAGS += -EB
+endif
+
+#
+# Architecture dependencies
+#
+ifeq ($(CONFIG_ARCH_ACORN),y)
+OBJS		+= ll_char_wr.o font.o
+ZLDFLAGS	+= -defsym params=$(PARAMS_PHYS)
+endif
+
+ifeq ($(CONFIG_ARCH_NETWINDER),y)
+OBJS		+= head-netwinder.o
+endif
+
+ifeq ($(CONFIG_ARCH_SHARK),y)
+OBJS		+= head-shark.o ofw-shark.o
+endif
+
+ifeq ($(CONFIG_ARCH_INTEGRATOR),y)
+OBJS		+= head-integrator.o
+endif
+
+ifeq ($(CONFIG_ARCH_FTVPCI),y)
+OBJS		+= head-ftvpci.o
+endif
+
+ifeq ($(CONFIG_ARCH_L7200),y)
+OBJS		+= head-l7200.o
+endif
+
+ifeq ($(CONFIG_ARCH_CLPS7500),y)
+HEAD		= head-clps7500.o
+endif
+
+ifeq ($(CONFIG_ARCH_P720T),y)
+# Borrow this code from SA1100
+OBJS		+= head-sa1100.o
+endif
+
+ifeq ($(CONFIG_ARCH_SA1100),y)
+OBJS		+= head-sa1100.o setup-sa1100.o
+ifeq ($(CONFIG_SA1100_NANOENGINE),y)
+  OBJS += hw-bse.o
+endif
+endif
+
+ifeq ($(CONFIG_ARCH_INL),y)
+HEAD		= head-isil.o
+endif
+
+ifeq ($(CONFIG_ARCH_VC547X),y)
+HEAD		= 
+OBJS		=
+endif
+
+SEDFLAGS	= s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;
+
+ifneq ($(ZBSSADDR),)
+SEDFLAGS	+= s/BSS_START/$(ZBSSADDR)/
+else
+SEDFLAGS	+= s/BSS_START/ALIGN(4)/
+endif
+
+all:		$(LINUX)
+
+$(LINUX):	$(HEAD) $(OBJS) piggy.o $(LINUX).lds
+		$(LD) $(ZLDFLAGS) $(HEAD) $(OBJS) piggy.o -o $(LINUX)
+
+$(HEAD): 	$(HEAD:.o=.S)
+		$(CC) $(AFLAGS) -traditional -c $(HEAD:.o=.S)
+
+piggy.o:	$(SYSTEM)
+		$(OBJCOPY) -O binary -R .note -R .comment -S $(SYSTEM) piggy
+		gzip $(GZFLAGS) < piggy > linux.gz
+		$(LD) -r $(PIGOFLAGS) -o $@ -b binary linux.gz
+		rm -f piggy #piggy.gz
+
+font.o:		$(FONTC)
+		$(CC) $(CFLAGS) -Dstatic= -c -o $@ $(FONTC)
+
+$(LINUX).lds:	vmlinux.lds.in
+		@sed "$(SEDFLAGS)" < vmlinux.lds.in > $@
+
+clean:;		rm -f $(LINUX) core piggy* $(LINUX).lds
+
+.PHONY:	$(LINUX).lds clean
+
+misc.o: misc.c $(TOPDIR)/include/asm/arch/uncompress.h $(TOPDIR)/lib/inflate.c
+
+%.o: %.S
+	$(CC) $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$@) -c -o $@ $<
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/Makefile.debug linux-2.4.29-uc1/arch/armnommu/boot/compressed/Makefile.debug
--- linux-2.4.29/arch/armnommu/boot/compressed/Makefile.debug	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/Makefile.debug	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,23 @@
+#
+# linux/arch/arm/boot/compressed/Makefile
+#
+# create a compressed vmlinux image from the original vmlinux
+#
+
+COMPRESSED_EXTRA=../../lib/ll_char_wr.o
+OBJECTS=misc-debug.o ll_char_wr.aout.o
+
+CFLAGS=-D__KERNEL__ -O2 -DSTDC_HEADERS -DSTANDALONE_DEBUG -Wall -I../../../../include -c
+
+test-gzip: piggy.aout.o $(OBJECTS)
+	$(CC) -o $@ $(OBJECTS) piggy.aout.o
+
+misc-debug.o: misc.c
+	$(CC) $(CFLAGS) -o $@ misc.c
+
+piggy.aout.o: piggy.o
+	arm-linuxelf-objcopy --change-leading-char -I elf32-arm -O arm-aout32-linux piggy.o piggy.aout.o
+
+ll_char_wr.aout.o: $(COMPRESSED_EXTRA)
+	arm-linuxelf-objcopy --change-leading-char -I elf32-arm -O arm-aout32-linux $(COMPRESSED_EXTRA) ll_char_wr.aout.o
+
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/misc.c linux-2.4.29-uc1/arch/armnommu/boot/compressed/misc.c
--- linux-2.4.29/arch/armnommu/boot/compressed/misc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/misc.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,329 @@
+/*
+ * misc.c
+ * 
+ * This is a collection of several routines from gzip-1.0.3 
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Modified for ARM Linux by Russell King
+ *
+ * Nicolas Pitre <nico@visuaide.com>  1999/04/14 :
+ *  For this code to run directly from Flash, all constant variables must
+ *  be marked with 'const' and all other variables initialized at run-time 
+ *  only.  This way all non constant variables will end up in the bss segment,
+ *  which should point to addresses in RAM and cleared to 0 on start.
+ *  This allows for a much quicker boot time.
+ */
+
+unsigned int __machine_arch_type;
+
+#include <asm/uaccess.h>
+#include <asm/hardware.h>
+#include <asm/arch/uncompress.h>
+#include <asm/proc/uncompress.h>
+
+
+#ifdef STANDALONE_DEBUG
+#define puts printf
+#endif
+
+#define __ptr_t void *
+
+/*
+ * Optimised C version of memzero for the ARM.
+ */
+void __memzero (__ptr_t s, size_t n)
+{
+	union { void *vp; unsigned long *ulp; unsigned char *ucp; } u;
+	int i;
+
+	u.vp = s;
+
+	for (i = n >> 5; i > 0; i--) {
+		*u.ulp++ = 0;
+		*u.ulp++ = 0;
+		*u.ulp++ = 0;
+		*u.ulp++ = 0;
+		*u.ulp++ = 0;
+		*u.ulp++ = 0;
+		*u.ulp++ = 0;
+		*u.ulp++ = 0;
+	}
+
+	if (n & 1 << 4) {
+		*u.ulp++ = 0;
+		*u.ulp++ = 0;
+		*u.ulp++ = 0;
+		*u.ulp++ = 0;
+	}
+
+	if (n & 1 << 3) {
+		*u.ulp++ = 0;
+		*u.ulp++ = 0;
+	}
+
+	if (n & 1 << 2)
+		*u.ulp++ = 0;
+
+	if (n & 1 << 1) {
+		*u.ucp++ = 0;
+		*u.ucp++ = 0;
+	}
+
+	if (n & 1)
+		*u.ucp++ = 0;
+}
+
+extern __inline__ __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
+			    size_t __n)
+{
+	int i = 0;
+	unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
+
+	for (i = __n >> 3; i > 0; i--) {
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+	}
+
+	if (__n & 1 << 2) {
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+	}
+
+	if (__n & 1 << 1) {
+		*d++ = *s++;
+		*d++ = *s++;
+	}
+
+	if (__n & 1)
+		*d++ = *s++;
+
+	return __dest;
+}
+
+/*
+ * gzip delarations
+ */
+#define OF(args)  args
+#define STATIC static
+
+typedef unsigned char  uch;
+typedef unsigned short ush;
+typedef unsigned long  ulg;
+
+#define WSIZE 0x8000		/* Window size must be at least 32k, */
+				/* and a power of two */
+
+static uch *inbuf;		/* input buffer */
+static uch window[WSIZE];	/* Sliding window buffer */
+
+static unsigned insize;		/* valid bytes in inbuf */
+static unsigned inptr;		/* index of next byte to be processed in inbuf */
+static unsigned outcnt;		/* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
+#define RESERVED     0xC0 /* bit 6,7:   reserved */
+
+#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  define Assert(cond,msg) {if(!(cond)) error(msg);}
+#  define Trace(x) fprintf x
+#  define Tracev(x) {if (verbose) fprintf x ;}
+#  define Tracevv(x) {if (verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+static int  fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+extern char input_data[];
+extern char input_data_end[];
+
+static uch *output_data;
+static ulg output_ptr;
+static ulg bytes_out;
+
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+static void puts(const char *);
+
+extern int end;
+static ulg free_mem_ptr;
+static ulg free_mem_ptr_end;
+
+#define HEAP_SIZE 0x2000
+
+#include "../../../../lib/inflate.c"
+
+#ifdef CONFIG_SERIAL_ATMEL_CONSOLE
+static void puts(const char *s)
+{
+char c;
+  while (c=*s++){
+	if (c=='\n') putc('\r');
+	putc(c);
+  }
+}
+#endif
+
+#ifndef STANDALONE_DEBUG
+static void *malloc(int size)
+{
+	void *p;
+
+	if (size <0) error("Malloc error\n");
+	if (free_mem_ptr <= 0) error("Memory error\n");
+
+	free_mem_ptr = (free_mem_ptr + 3) & ~3;	/* Align */
+
+	p = (void *)free_mem_ptr;
+	free_mem_ptr += size;
+
+	if (free_mem_ptr >= free_mem_ptr_end)
+		error("Out of memory");
+	return p;
+}
+
+static void free(void *where)
+{ /* gzip_mark & gzip_release do the free */
+}
+
+static void gzip_mark(void **ptr)
+{
+	arch_decomp_wdog();
+	*ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+	arch_decomp_wdog();
+	free_mem_ptr = (long) *ptr;
+}
+#else
+static void gzip_mark(void **ptr)
+{
+}
+
+static void gzip_release(void **ptr)
+{
+}
+#endif
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+int fill_inbuf(void)
+{
+	if (insize != 0)
+		error("ran out of input data\n");
+
+	inbuf = input_data;
+	insize = &input_data_end[0] - &input_data[0];
+
+	inptr = 1;
+	return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+void flush_window(void)
+{
+	ulg c = crc;
+	unsigned n;
+	uch *in, *out, ch;
+
+	in = window;
+	out = &output_data[output_ptr];
+	for (n = 0; n < outcnt; n++) {
+		ch = *out++ = *in++;
+		c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+	}
+	crc = c;
+	bytes_out += (ulg)outcnt;
+	output_ptr += (ulg)outcnt;
+	outcnt = 0;
+	puts(".");
+}
+
+static void error(char *x)
+{
+	int ptr;
+
+	puts("\n\n");
+	puts(x);
+	puts("\n\n -- System halted");
+
+	while(1);	/* Halt */
+}
+
+#ifndef STANDALONE_DEBUG
+
+ulg
+decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
+		  int arch_id)
+{
+	output_data		= (uch *)output_start;	/* Points to kernel start */
+	free_mem_ptr		= free_mem_ptr_p;
+	free_mem_ptr_end	= free_mem_ptr_end_p;
+	__machine_arch_type	= arch_id;
+
+	proc_decomp_setup();
+	arch_decomp_setup();
+
+	makecrc();
+	puts("Uncompressing Linux...");
+	gunzip();
+	puts(" done, booting the kernel.\n");
+	return output_ptr;
+}
+#else
+
+char output_buffer[1500*1024];
+
+int main()
+{
+	output_data = output_buffer;
+
+	makecrc();
+	puts("Uncompressing Linux...");
+	gunzip();
+	puts("done.\n");
+	return 0;
+}
+#endif
+	
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/ofw-shark.c linux-2.4.29-uc1/arch/armnommu/boot/compressed/ofw-shark.c
--- linux-2.4.29/arch/armnommu/boot/compressed/ofw-shark.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/ofw-shark.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,217 @@
+/*
+ * linux/arch/arm/boot/compressed/ofw-shark.c
+ *
+ * by Alexander Schulz <aschulz@netwinder.org>
+ *
+ * This file is used to get some basic information
+ * about the memory layout of the shark we are running
+ * on. Memory is usually divided in blocks a 8 MB.
+ * And bootargs are copied from OpenFirmware.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+
+
+asmlinkage void
+create_params (unsigned long *buffer)
+{
+	/* Is there a better address? Also change in mach-shark/arch.c */
+	struct param_struct *params = (struct param_struct *) 0x08003000;
+	int j,i,m,k,nr_banks,size;
+
+	for (j=0;j<256;j++) params->u1.unused[j]=0;
+
+	size=0;
+	nr_banks=(unsigned int) buffer[0];
+	if (nr_banks > NR_BANKS) nr_banks = NR_BANKS;
+	for (j=0;j<nr_banks;j++){
+		/* search the lowest address and put it into the next entry   */
+		/* not a fast sort algorithm, but there are at most 8 entries */
+		/* and this is used only once anyway                          */
+		m=0xffffffff;
+		for (i=0;i<(unsigned int) buffer[0];i++){
+			if (buffer[2*i+1]<m) {
+				m=buffer[2*i+1];
+				k=i;
+			}
+		}
+	  
+		/* using pages_in_bank for startaddress and size               */
+		/* start is in bytes, size in pages and not bigger than 0x2000 */
+		/* This is decoded in fixup_shark in arch/arm/kernel/arch.c    */
+		params->u1.s.pages_in_bank[j]=buffer[2*k+1]|(buffer[2*k+2]/PAGE_SIZE);
+		size += buffer[2*k+2];
+
+		buffer[2*k+1]=0xffffffff;                    /* mark as copied             */
+	}
+	
+	params->u1.s.page_size = PAGE_SIZE;
+	params->u1.s.nr_pages  = size/PAGE_SIZE;
+	params->u1.s.flags     = FLAG_READONLY;
+	
+	/* Copy over the bootargs */
+	for (j=0;j<128/4;j++) {
+		((unsigned long *) params->commandline)[j]=buffer[33+j];
+	}
+}
+
+
+typedef int (*ofw_handle_t)(void *);
+
+/* Everything below is called with a wrong MMU setting.
+ * This means: no string constants, no initialization of
+ * arrays, no global variables! This is ugly but I didn't
+ * want to write this in assembler :-)
+ */
+
+int
+of_decode_int(const unsigned char *p)
+{
+	unsigned int i = *p++ << 8;
+	i = (i + *p++) << 8;
+	i = (i + *p++) << 8;
+	return (i + *p);
+}
+  
+int
+OF_finddevice(ofw_handle_t openfirmware, char *name)
+{
+	unsigned int args[8];
+	char service[12];
+
+	service[0]='f';
+	service[1]='i';
+	service[2]='n';
+	service[3]='d';
+	service[4]='d';
+	service[5]='e';
+	service[6]='v';
+	service[7]='i';
+	service[8]='c';
+	service[9]='e';
+	service[10]='\0';
+
+	args[0]=(unsigned int)service;
+	args[1]=1;
+	args[2]=1;
+	args[3]=(unsigned int)name;
+
+	if (openfirmware(args) == -1)
+		return -1;
+	return args[4];
+}
+
+int
+OF_getproplen(ofw_handle_t openfirmware, int handle, char *prop)
+{
+	unsigned int args[8];
+	char service[12];
+
+	service[0]='g';
+	service[1]='e';
+	service[2]='t';
+	service[3]='p';
+	service[4]='r';
+	service[5]='o';
+	service[6]='p';
+	service[7]='l';
+	service[8]='e';
+	service[9]='n';
+	service[10]='\0';
+
+	args[0] = (unsigned int)service;
+	args[1] = 2;
+	args[2] = 1;
+	args[3] = (unsigned int)handle;
+	args[4] = (unsigned int)prop;
+
+	if (openfirmware(args) == -1)
+		return -1;
+	return args[5];
+}
+  
+int
+OF_getprop(ofw_handle_t openfirmware, int handle, char *prop, void *buf, unsigned int buflen)
+{
+	unsigned int args[8];
+	char service[8];
+
+	service[0]='g';
+	service[1]='e';
+	service[2]='t';
+	service[3]='p';
+	service[4]='r';
+	service[5]='o';
+	service[6]='p';
+	service[7]='\0';
+
+	args[0] = (unsigned int)service;
+	args[1] = 4;
+	args[2] = 1;
+	args[3] = (unsigned int)handle;
+	args[4] = (unsigned int)prop;
+	args[5] = (unsigned int)buf;
+	args[6] = buflen;
+
+	if (openfirmware(args) == -1)
+		return -1;
+	return args[7];
+}
+  
+asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer)
+{
+	int phandle,i,mem_len,buffer[32];
+	char temp[12];
+  
+	temp[0]='/';
+	temp[1]='m';
+	temp[2]='e';
+	temp[3]='m';
+	temp[4]='o';
+	temp[5]='r';
+	temp[6]='y';
+	temp[7]='\0';
+
+	phandle=OF_finddevice(o,temp);
+
+	temp[0]='r';
+	temp[1]='e';
+	temp[2]='g';
+	temp[3]='\0';
+
+	mem_len = OF_getproplen(o,phandle, temp);
+	OF_getprop(o,phandle, temp, buffer, mem_len);
+	*nomr=mem_len >> 3;
+
+	for (i=0; i<=mem_len/4; i++) pointer[i]=of_decode_int((const unsigned char *)&buffer[i]);
+
+	temp[0]='/';
+	temp[1]='c';
+	temp[2]='h';
+	temp[3]='o';
+	temp[4]='s';
+	temp[5]='e';
+	temp[6]='n';
+	temp[7]='\0';
+
+	phandle=OF_finddevice(o,temp);
+
+	temp[0]='b';
+	temp[1]='o';
+	temp[2]='o';
+	temp[3]='t';
+	temp[4]='a';
+	temp[5]='r';
+	temp[6]='g';
+	temp[7]='s';
+	temp[8]='\0';
+
+	mem_len = OF_getproplen(o,phandle, temp);
+	OF_getprop(o,phandle, temp, buffer, mem_len);
+	for (i=0; i<=mem_len/4; i++) pointer[i+32]=buffer[i];
+  
+}
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/setup-sa1100.S linux-2.4.29-uc1/arch/armnommu/boot/compressed/setup-sa1100.S
--- linux-2.4.29/arch/armnommu/boot/compressed/setup-sa1100.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/setup-sa1100.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,163 @@
+/*
+ * linux/arch/arm/boot/compressed/setup-sa1100.S
+ *
+ * Copyright (C) 2000 Nicolas Pitre <nico@cam.org>
+ *
+ * SA1100 setup routines, to be used after BSS has been cleared.
+ *
+ * John G Dorsey <john+@cs.cmu.edu>  2000/05/25 :
+ *  Runtime test for Neponset added.
+ */
+
+#include <linux/linkage.h>
+#include <linux/config.h>
+#include <asm/mach-types.h>
+
+		.text
+
+GPIO_BASE:	.long	0x90040000
+#define GPLR		0x00
+#define GPDR		0x04
+#define GPSR		0x08
+#define GAFR		0x1c
+
+PPC_BASE:	.long	0x90060000
+#define PPAR		0x08
+
+IC_BASE:	.long	0x90050000
+#define ICMR		0x04
+
+UART1_BASE:	.long	0x80010000
+UART3_BASE:	.long	0x80050000
+#define UTCR0           0x00
+#define UTCR1           0x04
+#define UTCR2           0x08
+#define UTCR3           0x0c
+#define UTSR0           0x1c
+#define UTSR1           0x20
+
+#ifndef CONFIG_SA1100_DEFAULT_BAUDRATE
+#define CONFIG_SA1100_DEFAULT_BAUDRATE	9600
+#endif
+
+#define BAUD_DIV	((230400/CONFIG_SA1100_DEFAULT_BAUDRATE)-1)
+
+SCR_loc:	.long	SYMBOL_NAME(SCR_value)
+#define GPIO_2_9	0x3fc
+
+
+/*
+ * void sa1100_setup( int arch_id );
+ *
+ * This is called from decompress_kernel() with the arch_decomp_setup() macro.
+ */
+
+ENTRY(sa1100_setup)
+		mov	r3, r0			@ keep machine type in r3
+
+		@ Clear all interrupt sources
+		ldr	r0, IC_BASE
+		mov	r1, #0
+		str	r1, [r0, #ICMR]
+
+@ Read System Configuration "Register" for Assabet.
+@ (taken from "Intel StrongARM SA-1110 Microprocessor Development Board
+@ User's Guide," p.4-9)
+
+		teq	r3, #MACH_TYPE_ASSABET
+		bne	skip_SCR
+
+		ldr	r0, GPIO_BASE
+		ldr	r1, [r0, #GPDR]
+		and	r1, r1, #GPIO_2_9
+		str	r1, [r0, #GPDR]
+		mov	r1, #GPIO_2_9
+		str	r1, [r0, #GPSR]
+		ldr	r1, [r0, #GPDR]
+		bic	r1, r1, #GPIO_2_9
+		str	r1, [r0, #GPDR]
+
+		mov	r2, #100
+1:		ldr	r1, [r0, #GPLR]
+		subs	r2, r2, #1
+		bne	1b
+
+		and	r2, r1, #GPIO_2_9
+		ldr	r1, SCR_loc
+		str	r2, [r1]
+
+		ldr	r1, [r0, #GPDR]
+		and	r1, r1, #GPIO_2_9
+		str	r1, [r0, #GPDR]
+
+skip_SCR:
+
+		@ Initialize UART (if bootloader has not done it yet)...
+		teq	r3, #MACH_TYPE_BRUTUS
+		teqne	r3, #MACH_TYPE_ASSABET
+		teqne   r3, #MACH_TYPE_ITSY
+		teqne   r3, #MACH_TYPE_OMNIMETER
+		teqne   r3, #MACH_TYPE_JORNADA720
+		teqne	r3, #MACH_TYPE_GRAPHICSCLIENT
+		teqne	r3, #MACH_TYPE_FLEXANET
+		bne	skip_uart
+
+		@ UART3 if Assabet is used with Neponset
+		teq	r3, #MACH_TYPE_ASSABET	@ if Assabet 
+		tsteq	r2, #(1 << 9)		@ ... and Neponset present
+		ldreq	r0, UART3_BASE
+		beq	uart_init
+
+		@ UART3 on GraphicsClient
+		teq	r3, #MACH_TYPE_GRAPHICSCLIENT
+		ldreq	r0, UART3_BASE
+		beq	uart_init
+
+		@ At least for Brutus, the UART1 is used through
+		@ the alternate GPIO function...
+		teq	r3, #MACH_TYPE_BRUTUS
+		bne	uart1
+
+alt_GPIO_uart:	ldr	r0, GPIO_BASE
+		ldr	r1, [r0, #GPDR]
+		bic	r1, r1, #1<<15
+		orr	r1, r1, #1<<14
+		str	r1, [r0, #GPDR]
+		ldr	r1, [r0, #GAFR]
+		orr	r1, r1, #(1<<15)|(1<<14)
+		str	r1, [r0, #GAFR]
+		ldr	r0, PPC_BASE
+		ldr	r1, [r0, #PPAR]
+		orr	r1, r1, #1<<12
+		str	r1, [r0, #PPAR]
+
+uart1:		ldr	r0, UART1_BASE
+
+uart_init:
+1:		ldr	r1, [r0, #UTSR1]
+		tst	r1, #1<<0		@ TBY
+		bne	1b
+		mov	r1, #0
+		str	r1, [r0, #UTCR3]
+		mov	r1, #0x08		@ 8N1
+		str	r1, [r0, #UTCR0]
+		mov	r1, #BAUD_DIV
+		str	r1, [r0, #UTCR2]
+		mov	r1, r1, lsr #8
+		str	r1, [r0, #UTCR1]
+		mov	r1, #0x03		@ RXE + TXE
+		str	r1, [r0, #UTCR3]
+		mov	r1, #0xff		@ flush status reg
+		str	r1, [r0, #UTSR0]
+skip_uart:
+
+		@ Extra specific setup calls
+		@ The machine type is passed in r0
+		mov	r0, r3
+#ifdef CONFIG_SA1100_NANOENGINE
+		teq	r0, #MACH_TYPE_NANOENGINE
+		beq	SYMBOL_NAME(bse_setup)
+#endif
+
+out:		mov	pc, lr
+
diff -urN linux-2.4.29/arch/armnommu/boot/compressed/vmlinux.lds.in linux-2.4.29-uc1/arch/armnommu/boot/compressed/vmlinux.lds.in
--- linux-2.4.29/arch/armnommu/boot/compressed/vmlinux.lds.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/compressed/vmlinux.lds.in	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,63 @@
+/*
+ *  linux/arch/arm/boot/compressed/vmlinux.lds.in
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+  . = LOAD_ADDR;
+  _load_addr = .;
+
+  . = TEXT_START;
+  _text = .;
+
+  .text : {
+    _start = .;
+    *(.start)
+    *(.text)
+    *(.fixup)
+    *(.gnu.warning)
+    *(.rodata)
+    *(.rodata.*)
+    *(.glue_7)
+    *(.glue_7t)
+    input_data = .;
+    piggy.o
+    input_data_end = .;
+    . = ALIGN(4);
+  }
+
+  _etext = .;
+
+  .data : {
+    *(.data)
+  }
+
+  _edata = .;
+
+  . = BSS_START;
+  __bss_start = .;
+  .bss : {
+    *(.bss)
+  }
+  _end = .;
+
+  .stack : {
+    *(.stack)
+  }
+
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+}
+
diff -urN linux-2.4.29/arch/armnommu/boot/install.sh linux-2.4.29-uc1/arch/armnommu/boot/install.sh
--- linux-2.4.29/arch/armnommu/boot/install.sh	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/install.sh	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,61 @@
+#!/bin/sh
+#
+# arch/arm/boot/install.sh
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+# Adapted from code in arch/i386/boot/install.sh by Russell King
+#
+# "make install" script for arm architecture
+#
+# Arguments:
+#   $1 - kernel version
+#   $2 - kernel image file
+#   $3 - kernel map file
+#   $4 - default install path (blank if root directory)
+#
+
+# User may have a custom install script
+
+if [ -x /sbin/installkernel ]; then
+  exec /sbin/installkernel "$@"
+fi
+
+if [ "$2" = "zImage" ]; then
+# Compressed install
+  echo "Installing compressed kernel"
+  if [ -f $4/vmlinuz-$1 ]; then
+    mv $4/vmlinuz-$1 $4/vmlinuz.old
+  fi
+
+  if [ -f $4/System.map-$1 ]; then
+    mv $4/System.map-$1 $4/System.old
+  fi
+
+  cat $2 > $4/vmlinuz-$1
+  cp $3 $4/System.map-$1
+else
+# Normal install
+  echo "Installing normal kernel"
+  if [ -f $4/vmlinux-$1 ]; then
+    mv $4/vmlinux-$1 $4/vmlinux.old
+  fi
+
+  if [ -f $4/System.map ]; then
+    mv $4/System.map $4/System.old
+  fi
+
+  cat $2 > $4/vmlinux-$1
+  cp $3 $4/System.map
+fi
+
+if [ -x /sbin/loadmap ]; then
+  /sbin/loadmap --rdev /dev/ima
+else
+  echo "You have to install it yourself"
+fi
diff -urN linux-2.4.29/arch/armnommu/boot/Makefile linux-2.4.29-uc1/arch/armnommu/boot/Makefile
--- linux-2.4.29/arch/armnommu/boot/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/boot/Makefile	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,183 @@
+#
+# arch/arm/boot/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995-2000 Russell King
+#
+
+SYSTEM	=$(TOPDIR)/$(LINUX)
+
+ifeq ($(CONFIG_CPU_26),y)
+ZTEXTADDR	 = 0x02080000
+PARAMS_PHYS	 = 0x0207c000
+INITRD_PHYS	 = 0x02180000
+INITRD_VIRT	 = 0x02180000
+endif
+
+ifeq ($(CONFIG_ARCH_RPC),y)
+ZTEXTADDR	 = 0x10008000
+PARAMS_PHYS	 = 0x10000100
+INITRD_PHYS	 = 0x18000000
+INITRD_VIRT	 = 0xc8000000
+endif
+
+ifeq ($(CONFIG_ARCH_CLPS7500),y)
+ZTEXTADDR	 = 0x10008000
+endif
+
+ifeq ($(CONFIG_ARCH_EBSA110),y)
+ZTEXTADDR	 = 0x00008000
+PARAMS_PHYS	 = 0x00000400
+INITRD_PHYS	 = 0x00800000
+INITRD_VIRT	 = 0xc0800000
+endif
+
+ifeq ($(CONFIG_ARCH_SHARK),y)
+ZTEXTADDR	 = 0x08508000
+ZRELADDR	 = 0x08008000
+endif
+
+ifeq ($(CONFIG_FOOTBRIDGE),y)
+ZTEXTADDR	 = 0x00008000
+PARAMS_PHYS	 = 0x00000100
+INITRD_PHYS	 = 0x00800000
+INITRD_VIRT	 = 0xc0800000
+endif
+
+ifeq ($(CONFIG_ARCH_INTEGRATOR),y)
+ZTEXTADDR	 = 0x00008000
+PARAMS_PHYS	 = 0x00000100
+INITRD_PHYS	 = 0x00800000
+INITRD_VIRT	 = 0xc0800000
+endif
+
+ifeq ($(CONFIG_ARCH_NEXUSPCI),y)
+ZTEXTADDR	 = 0x40008000
+endif
+
+ifeq ($(CONFIG_ARCH_L7200),y)
+# RAM based kernel
+#ZTEXTADDR	 = 0xf0400000
+#ZRELADDR	 = 0xf0008000
+
+# FLASH based kernel
+ZTEXTADDR	 = 0x00010000
+ZRELADDR	 = 0xf0008000
+ZBSSADDR	 = 0xf03e0000
+endif
+
+ifeq ($(CONFIG_ARCH_P720T),y)
+ZTEXTADDR	 = 0xc0018000
+PARAMS_PHYS	 = 0xc0000100
+INITRD_PHYS	 = 0xc0400000
+INITRD_VIRT	 = 0xc0400000
+endif
+
+ifeq ($(CONFIG_ARCH_SA1100),y)
+ZTEXTADDR	 = 0xc0008000
+ZRELADDR	 = 0xc0008000
+ifeq ($(CONFIG_SA1100_VICTOR),y)
+  ZTEXTADDR	 = 0x00002000
+  ZBSSADDR	 = 0xc0200000
+endif
+ifeq ($(CONFIG_SA1100_SHERMAN),y)
+  ZTEXTADDR      = 0x00050000   
+  ZBSSADDR       = 0xc0200000
+endif
+ifeq ($(CONFIG_SA1100_GRAPHICSCLIENT),y)
+  ZTEXTADDR	 = 0xC0200000
+endif
+ifeq ($(CONFIG_SA1100_YOPY),y)
+  ZTEXTADDR      = 0x00080000
+  ZBSSADDR       = 0xc0200000
+endif
+ifeq ($(CONFIG_SA1111),y)
+  ZRELADDR	 = 0xc0208000
+endif
+endif
+
+ifeq ($(CONFIG_ARCH_ANAKIN),y)
+ZTEXTADDR	 = 0x20008000
+endif
+
+ifeq ($(CONFIG_ARCH_ATMEL),y)
+ZTEXTADDR	= 0x1200000
+ZRELADDR	= 0x1000000
+endif
+
+ifeq ($(CONFIG_ARCH_DM270),y)
+ZTEXTADDR	= 0x01600000
+ZRELADDR	= 0x01200000
+endif
+
+ifeq ($(CONFIG_BOARD_SNDS100),y)
+ZRELADDR	 = 0x00008000
+ifeq ($(CONFIG_ZYXEL_BOOTEXT),y)
+ZTEXTADDR	 = 0x00020000
+else
+ZTEXTADDR	 = 0x00000000
+endif
+endif
+
+ifeq ($(CONFIG_ARCH_INL),y)
+ZTEXTADDR	= 0x$(CONFIG_ZIMAGE_TEXTADDR)
+ZRELADDR	= $(TEXTADDR)
+endif
+
+ifeq ($(CONFIG_ARCH_VC547X),y)
+ZTEXTADDR	 = 0x10000000
+endif
+
+#
+# If you don't define ZRELADDR above,
+# then it defaults to ZTEXTADDR
+#
+ifeq ($(ZRELADDR),)
+ZRELADDR	= $(ZTEXTADDR)
+endif
+
+export	SYSTEM ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS INITRD_VIRT PARAMS_PHYS
+
+Image:	$(CONFIGURE) $(SYSTEM)
+	$(OBJCOPY) -O binary -R .note -R .comment -S $(SYSTEM) $@
+ifeq ($(MACH_IPOD),)
+	@mv $@ $@.tmp
+	@$(AS) -o ../mach-ipod/pad.o ../mach-ipod/pad.S
+	@$(OBJCOPY) -O binary ../mach-ipod/pad.o pad.bin
+	@cat pad.bin $@.tmp > $@
+	@$(RM) $@.tmp pad.bin
+endif
+
+bzImage: zImage
+
+zImage:	$(CONFIGURE) compressed/$(LINUX)
+	$(OBJCOPY) -O binary -R .note -R .comment -S compressed/$(LINUX) $@
+
+bootpImage: bootp/bootp
+	$(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@
+
+compressed/$(LINUX): $(TOPDIR)/$(LINUX) dep
+	@$(MAKE) -C compressed $(LINUX)
+
+bootp/bootp: zImage initrd
+	@$(MAKE) -C bootp bootp
+
+initrd:
+	@test "$(INITRD_VIRT)" != "" || (echo This architecture does not support INITRD; exit -1)
+	@test "$(INITRD)" != "" || (echo You must specify INITRD; exit -1)
+
+install: $(CONFIGURE) Image
+	sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
+
+zinstall: $(CONFIGURE) zImage
+	sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
+
+clean:
+	$(RM) Image zImage bootpImage
+	@$(MAKE) -C compressed clean
+	@$(MAKE) -C bootp clean
+
+dep:
diff -urN linux-2.4.29/arch/armnommu/config.in linux-2.4.29-uc1/arch/armnommu/config.in
--- linux-2.4.29/arch/armnommu/config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/config.in	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,852 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+#
+# Additional changes:
+#  (c) Copyright 2001-2002 - S3C4530 by Arcturus Networks Inc.
+#  (c) Copyright 2002-2003 - S3C2500 by Arcturus Networks Inc.
+#
+mainmenu_name "Linux Kernel Configuration"
+
+define_bool CONFIG_ARM y
+define_bool CONFIG_SBUS n
+define_bool CONFIG_UID16 y
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
+
+# Begin uclinux additions -----------------------------------------------------
+define_bool CONFIG_UCLINUX y
+define_bool MAGIC_ROM_PTR y
+# End uclinux additions -------------------------------------------------------
+
+#------------------------------------------------------------------------------
+#                         C o d e    m a t u r i t y
+#------------------------------------------------------------------------------
+
+mainmenu_option next_comment
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+bool 'Prompt for obsolete code/drivers' CONFIG_OBSOLETE
+endmenu
+
+#------------------------------------------------------------------------------
+#                      L o a d a b l e    M o d u l e
+#------------------------------------------------------------------------------
+
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+#------------------------------------------------------------------------------
+#                               S y s t e m
+#------------------------------------------------------------------------------
+
+mainmenu_option next_comment
+comment 'System Type'
+choice 'ARM system type' \
+	 "TI-DSC21		CONFIG_ARCH_DSC21 \
+	  TI-VC547X		CONFIG_ARCH_VC547X \
+	  TI-DM270		CONFIG_ARCH_DM270 \
+	  Conexant		CONFIG_ARCH_CNXT \
+	  NET+ARM		CONFIG_ARCH_NETARM \
+	  Triscend-A7S		CONFIG_ARCH_TA7S \
+	  Triscend-A7V		CONFIG_ARCH_TA7V \
+	  SWARM			CONFIG_ARCH_SWARM \
+	  Intersil		CONFIG_ARCH_INL \
+	  Samsung		CONFIG_ARCH_SAMSUNG \
+	  Atmel			CONFIG_ARCH_ATMEL \
+	  iPod			CONFIG_ARCH_IPOD" TI-DSC21
+
+if [ "$CONFIG_ARCH_TA7V" = "y" ]; then
+   choice ' Triscend A7V Derivative' \
+   	" A7VL		CONFIG_ARCH_TA7VL \
+	  A7VE 		CONFIG_ARCH_TA7VE \
+	  A7VC 		CONFIG_ARCH_TA7VC \
+	  A7VT		CONFIG_ARCH_TA7VT" A7VT
+fi
+
+if [ "$CONFIG_ARCH_TA7S" != "y" -a "$CONFIG_ARCH_TA7V" != "y" ]; then
+   bool 'Generate big endian code' CONFIG_CPU_BIG_ENDIAN
+fi
+
+if [ "$CONFIG_ARCH_CNXT" = "y" ]; then
+   choice ' Conexant/Mindspeed architecture' \
+   	" P52xxCtrl		CONFIG_ARCH_P52 \
+	  sp_CN9414 		CONFIG_ARCH_SPIPE \
+	  CX821xxCtrl		CONFIG_ARCH_CX821XX" CX821xxCtrl 
+
+   if [ "$CONFIG_ARCH_P52" = "y" ]; then
+      choice ' P52xx board implementation' \
+	" IAD_EVM		CONFIG_IAD_EVM \
+	  JSCHornet		CONFIG_HORNET" IAD_EVM
+   fi
+
+   if [ "$CONFIG_ARCH_CX821XX" = "y" ] ; then
+      choice ' Board Support Package' \
+        " HASBANI		CONFIG_BD_HASBANI \
+	  HUMBER		CONFIG_BD_HUMBER \
+	  GOLDENGATE		CONFIG_BD_GOLDENGATE \
+	  MACKINAC		CONFIG_BD_MACKINAC \
+	  RUSHMORE		CONFIG_BD_RUSHMORE \
+	  TIBURON		CONFIG_BD_TIBURON" MACKINAC
+      if [ "$CONFIG_BD_HASBANI" = "y" ]; then
+         define_bool CONFIG_CHIP_P52 y
+      fi
+      if [ "$CONFIG_BD_GOLDENGATE" = "y" -o "$CONFIG_BD_HUMBER" = "y" ]; then
+         define_bool CONFIG_CHIP_CX82100 y
+      fi
+      if [ "$CONFIG_BD_MACKINAC" = "y" ]; then
+         define_bool CONFIG_CHIP_CX82110 y
+      fi
+      if [ "$CONFIG_BD_RUSHMORE" = "y" ]; then
+         define_bool CONFIG_CHIP_CX82110 y
+      fi
+      if [ "$CONFIG_BD_TIBURON" = "y" ]; then
+         define_bool CONFIG_CHIP_CX82100 y
+         define_bool CONFIG_CMDLINE_BOOL y
+         define_string CONFIG_CMDLINE "root=/dev/mtdblock2 init=/linuxrc"
+      fi
+   fi
+fi
+if [ "$CONFIG_ARCH_NETARM" = "y" ]; then
+   choice ' NET+ARM Processor type' \
+   	" NET+15	CONFIG_NETARM_NET15 \
+   	  NET+40	CONFIG_NETARM_NET40 \
+   	  NET+50	CONFIG_NETARM_NET50 \
+	  NS7520	CONFIG_NETARM_NS7520" NET+40
+   if [ "$CONFIG_NETARM_NS7520" = "y" ]; then
+      bool '  Forth-Systeme UNC20 Board Support ' CONFIG_BOARD_UNC20
+      if [ "$CONFIG_BOARD_UNC20" = "y" ]; then
+         bool '   UNC20 Evaluation baseboard support ' CONFIG_BOARD_UNC20_BAS0
+      fi
+   fi
+	bool '  NET+Lx bootloader output on second serial port ' CONFIG_NETARM_BOOTLOADER_SECOND_SERIAL
+	bool '  NET+Lx bootloader debug output on ' CONFIG_NETARM_BOOTLOADER_DEBUG_OUTPUT
+	bool '  NET+Lx bootloader debugger support ' CONFIG_NETARM_BOOTLOADER_DEBUG_DEBUGGER
+	bool '  NET+Lx bootloader memory ramp test ' CONFIG_NETARM_BOOTLOADER_DEBUG_RAMPTEST
+fi
+
+if [ "$CONFIG_ARCH_TA7S" = "y" ]; then
+  choice 'Triscend development board' \
+    "A7DB		CONFIG_BOARD_A7DB \
+     DevA7		CONFIG_BOARD_DevA7" DevA7
+fi
+
+if [ "$CONFIG_ARCH_TA7V" = "y" ]; then
+  choice 'Triscend development board' \
+    "A7VxDB		CONFIG_BOARD_A7VXDB \
+     TA7VT05_RevA	CONFIG_BOARD_TA7VT05_RevA" A7VxDB
+fi
+
+if [ "$CONFIG_ARCH_TA7S" = "y" -o "$CONFIG_ARCH_TA7V" = "y" ]; then
+  bool 'Include A7HAL drivers' CONFIG_USE_A7HAL
+  bool 'System clock comes from external oscillator' CONFIG_USE_OSC
+  if [ "$CONFIG_USE_OSC" = "y" ]; then
+      int 'Oscillator frequency (Hz)' CONFIG_OSC_FREQ 25000000
+  fi
+fi
+
+bool 'Set flash/sdram size and base addr' CONFIG_SET_MEM_PARAM
+if [ "$CONFIG_SET_MEM_PARAM" = "y" ]; then
+   hex '(S)DRAM Base Address' DRAM_BASE 0x00800000
+   hex '(S)DRAM Size ' DRAM_SIZE 0x00800000
+   hex 'FLASH Base Address ' FLASH_MEM_BASE 0x00400000
+   hex 'FLASH Size ' FLASH_SIZE 0x00400000
+fi
+
+if [ "$CONFIG_ARCH_TA7S" != "y" -a "$CONFIG_ARCH_TA7V" != "y" ]; then
+choice 'Kernel executes from' \
+   " RAM	CONFIG_RAMKERNEL \
+     ROM	CONFIG_ROMKERNEL" ROM
+fi
+
+# ARM940T
+if [ "$CONFIG_ARCH_CNXT" = "y" ]; then
+   define_bool CONFIG_CPU_32 y
+   define_bool CONFIG_CPU_26 n
+   define_bool CONFIG_CPU_ARM940T y
+   define_bool CONFIG_NO_PGT_CACHE y
+   define_bool CONFIG_CPU_WITH_CACHE y
+   define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION y
+   if [ "$CONFIG_SET_MEM_PARAM" = "n" ]; then
+      if [ "$CONFIG_BD_TIBURON" = "y" ]; then
+         define_hex DRAM_BASE 0x00800000
+         define_hex DRAM_SIZE 0x00780000
+         define_hex FLASH_MEM_BASE 0x00400000
+         define_hex FLASH_SIZE 0x00200000
+      else
+         define_hex DRAM_BASE 0x00800000
+         define_hex DRAM_SIZE 0x00800000
+         define_hex FLASH_MEM_BASE 0x00400000
+         define_hex FLASH_SIZE 0x00400000
+      fi
+   fi
+
+   bool '  ARM940T CPU idle' CONFIG_CPU_ARM940_CPU_IDLE
+   bool '  ARM940T I-Cache on' CONFIG_CPU_ARM940_I_CACHE_ON
+   bool '  ARM940T D-Cache on' CONFIG_CPU_ARM940_D_CACHE_ON
+   if [ "$CONFIG_CPU_ARM940_D_CACHE_ON" = "y" ] ; then
+      bool '  Force write through caches on ARM940T' CONFIG_CPU_ARM940_WRITETHROUGH
+   fi
+fi
+
+
+if [ "$CONFIG_ARCH_DSC21" = "y" ]; then
+   define_bool CONFIG_CPU_ARM710 y
+   define_bool CONFIG_CPU_32 y
+   define_bool CONFIG_CPU_26 n
+   define_bool CONFIG_NO_PGT_CACHE y
+   define_bool CONFIG_CPU_WITH_CACHE y
+   define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION y
+   if [ "$CONFIG_SET_MEM_PARAM" = "n" ]; then
+      define_hex DRAM_BASE 0x08000000
+      define_hex DRAM_SIZE 0x00200000
+      define_hex FLASH_MEM_BASE 0x08400000
+      define_hex FLASH_SIZE 0x00200000
+   fi
+   define_bool CONFIG_DUMMY_CONSOLE y
+fi
+
+if [ "$CONFIG_ARCH_VC547X" = "y" ]; then
+   define_bool CONFIG_CPU_ARM710 y
+   define_bool CONFIG_CPU_ARM7TDMI y
+   define_bool CONFIG_CPU_32 y
+   define_bool CONFIG_CPU_32v4 y
+   define_bool CONFIG_CPU_26 n
+   define_bool CONFIG_NO_PGT_CACHE y
+   define_bool CONFIG_CPU_WITH_CACHE y
+   define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION n
+   if [ "$CONFIG_SET_MEM_PARAM" = "n" ]; then
+      define_hex DRAM_BASE 0x10000000
+      define_hex DRAM_SIZE 0x01000000
+      define_hex FLASH_MEM_BASE 0x00000000
+      define_hex FLASH_SIZE 0x00800000
+   fi
+   define_bool CONFIG_DUMMY_CONSOLE y
+fi
+
+if [ "$CONFIG_ARCH_DM270" = "y" ]; then
+   define_bool CONFIG_CPU_ARM710 y
+   define_bool CONFIG_CPU_ARM7TDMI y
+   define_bool CONFIG_CPU_32 y
+   define_bool CONFIG_CPU_32v4 y
+   define_bool CONFIG_CPU_26 n
+   define_bool CONFIG_NO_PGT_CACHE y
+   define_bool CONFIG_CPU_WITH_CACHE y
+   define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION n
+   define_bool CONFIG_SERIAL_DM270 y
+  
+   int  'CPU clock frequency' CONFIG_ARM_CLK 87750000 
+   int  'Timer prescale' CONFIG_DM270_TIMER_PRESCALE 351 
+   bool 'Serial Console' CONFIG_SERIAL_DM270_CONSOLE
+
+   if [ "$CONFIG_SET_MEM_PARAM" = "n" ]; then
+      define_hex DRAM_BASE 0x01200000
+      define_hex DRAM_SIZE 0x02000000
+      define_hex FLASH_MEM_BASE 0x00100000
+      define_hex FLASH_SIZE 0x00200000
+   fi
+   define_bool CONFIG_DUMMY_CONSOLE y
+fi
+
+if [ "$CONFIG_ARCH_SWARM" = "y" ]; then
+#  define_bool CONFIG_CPU_ARM610 y
+   define_bool CONFIG_CPU_32 y
+   define_bool CONFIG_CPU_26 n
+   define_bool CONFIG_CPU_32v3 y
+   define_bool CONFIG_CPU_ARM7V3 y
+   define_bool CONFIG_NO_PGT_CACHE y
+   define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION y
+   define_hex FLASH_MEM_BASE 0x00000000
+   define_hex FLASH_SIZE 0x00100000
+fi
+
+if [ "$CONFIG_ARCH_ATMEL" = "y" ]; then
+   define_bool CONFIG_NO_PGT_CACHE y
+   define_bool CONFIG_CPU_ARM710 y
+   define_bool CONFIG_CPU_32 y
+   define_bool CONFIG_CPU_32v4 y
+   define_bool CONFIG_CPU_WITH_CACHE n
+   define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION n
+   define_bool CONFIG_SERIAL_ATMEL y
+  
+   int  'CPU clock frequency' CONFIG_ARM_CLK 40000000 
+   bool 'Serial Console' CONFIG_SERIAL_ATMEL_CONSOLE
+
+   if [ "$CONFIG_SET_MEM_PARAM" = "n" ]; then
+      define_hex DRAM_BASE 0x01000000
+      define_hex DRAM_SIZE 0x00600000
+      define_hex FLASH_MEM_BASE 0x01600000
+      define_hex FLASH_SIZE 0x00200000
+   fi
+	
+   hex 'Memory mapped 16-bit io base' CONFIG_MEM16_BASE 0x03000000
+   hex 'Memory mapped 8-bit io base' CONFIG_MEM8_BASE 0x03000000
+   hex '16-bit io base' CONFIG_IO16_BASE 0x02000000
+   hex '8-bit io base' CONFIG_IO8_BASE 0x02000000
+	
+   choice ' Atmel CPU' \
+   	" AT91x40		CONFIG_CPU_AT91X40 \
+	  AT91x63 		CONFIG_CPU_AT91X63" AT91x40
+
+   bool 'Atmel Kernel-Debug hack' CONFIG_ATMEL_DEBUG
+   if [ "$CONFIG_ATMEL_DEBUG" = "y" ]; then
+      hex 'Debug buffer address' AT91_DEBUG_BASE 0x01400000
+   fi
+fi
+
+if [ "$CONFIG_ARCH_NETARM" = "y" ]; then
+   define_bool CONFIG_CPU_ARM710 y
+   define_bool CONFIG_CPU_ARM7TDMI y
+   define_bool CONFIG_CPU_32 y
+   define_bool CONFIG_CPU_32v4 y
+   define_bool CONFIG_CPU_26 n
+   if [ "$CONFIG_NETARM_NS7520" = "y" ]; then
+      define_bool CONFIG_CPU_WITH_CACHE n
+      define_bool CONFIG_NETARM_PLL_BYPASS y
+      if [ "$CONFIG_BOARD_UNC20_BAS0" = "y" ]; then
+         define_bool CONFIG_CMDLINE_BOOL y
+         define_bool CONFIG_NETARM_BOOTLOADER_SECOND_SERIAL y
+         define_string CONFIG_CMDLINE "console=ttyS1"
+      fi
+   else
+      define_bool CONFIG_CPU_WITH_CACHE y
+   fi
+   define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION n
+   define_bool CONFIG_NO_PGT_CACHE y   
+   if [ "$CONFIG_NETARM_NET40" = "y" ]; then
+      bool 'NET+ARM NET+40 Rev2' CONFIG_NETARM_NET40_REV2
+      if [ "$CONFIG_NETARM_NET40_REV2" = "n" ]; then
+         bool 'NET+ARM NET+40 Rev4' CONFIG_NETARM_NET40_REV4
+      fi
+      bool 'NET+ARM PLL Bypass Patch' CONFIG_NETARM_PLL_BYPASS
+      bool 'NET+ARM EMLIN Board' CONFIG_NETARM_EMLIN
+   fi
+#  default memory configuration for Net40 and EMLIN boards
+   if [ "$CONFIG_SET_MEM_PARAM" = "n" ]; then
+      if [ "$CONFIG_NETARM_NS7520" = "y" ]; then
+	 # This should work for the UNC20, at least
+         define_hex DRAM_BASE 0x00000000
+         define_hex FLASH_MEM_BASE 0x01000000
+         define_hex DRAM_SIZE 0x00800000
+         define_hex FLASH_SIZE 0x00400000
+      else
+         define_hex DRAM_BASE 0x00000000
+         define_hex FLASH_MEM_BASE 0x10000000
+         if [ "$CONFIG_NETARM_EMLIN" = "y" ]; then
+            define_hex DRAM_SIZE 0x01000000
+            define_hex FLASH_SIZE 0x00200000
+         else
+            define_hex DRAM_SIZE 0x02000000
+            define_hex FLASH_SIZE 0x00800000
+            define_bool CONFIG_NETARM_EEPROM y
+         fi
+      fi
+   fi
+fi
+
+if [ "$CONFIG_ARCH_SAMSUNG" = "y" ]; then
+   choice 'Board Implementation' \
+      " S3C3410-SMDK40100	CONFIG_BOARD_SMDK40100 \
+        S3C44B0X-MBA44  	CONFIG_BOARD_MBA44 \
+        S3C4530-HEI		CONFIG_BOARD_EVS3C4530HEI \
+        S3C2500-REF-RGP		CONFIG_BOARD_S3C2500REFRGP \
+        SMDK2500		CONFIG_BOARD_SMDK2500 \
+        S3C4510-SNDS100		CONFIG_BOARD_SNDS100" S3C4510-SNDS100
+
+   if [ "$CONFIG_BOARD_SMDK40100" = "y" ]; then
+       define_string CONFIG_CPU_NAME "S3C3410X"
+       define_bool CONFIG_CPU_S3C3410          y
+       define_bool CONFIG_CPU_ARM710           y
+       define_bool CONFIG_CPU_32v4             y
+       define_bool CONFIG_CPU_32               y
+       define_bool CONFIG_CPU_26               n
+       define_bool CONFIG_NO_PGT_CACHE         y
+       define_bool CONFIG_CPU_WITH_CACHE       y
+       define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION n
+       define_int  CONFIG_ARM_CLK              40000000
+       define_bool CONFIG_SERIAL_S3C3410       y
+       define_int  CONFIG_FORCE_MAX_ZONEORDER  5
+       if [ "$CONFIG_SET_MEM_PARAM" = "n" ]; then
+          define_hex DRAM_BASE      0x00000000
+          define_hex DRAM_SIZE      0x00800000
+          define_hex FLASH_MEM_BASE 0x01000000
+          define_hex FLASH_SIZE     0x00200000
+       fi
+   fi
+
+   if [ "$CONFIG_BOARD_MBA44" = "y" ]; then
+       define_string CONFIG_SPU_NAME "S3C44B0X"
+       define_bool CONFIG_CPU_S3C44B0X         y
+       define_bool CONFIG_CPU_ARM710           y
+       define_bool CONFIG_CPU_32v4             y
+       define_bool CONFIG_CPU_32               y
+       define_bool CONFIG_CPU_26               n
+       define_bool CONFIG_NO_PGT_CACHE         y
+       define_bool CONFIG_CPU_WITH_CACHE       y
+       define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION n
+       define_int  CONFIG_ARM_CLK              60000000
+       define_bool CONFIG_SERIAL_S3C44B0X      y
+       define_int  CONFIG_FORCE_MAX_ZONEORDER  5
+       if [ "$CONFIG_SET_MEM_PARAM" = "n" ]; then
+          define_hex DRAM_BASE      0x00000000
+          define_hex DRAM_SIZE      0x00800000
+          define_hex FLASH_MEM_BASE 0x01000000
+          define_hex FLASH_SIZE     0x00200000
+       fi
+   fi
+
+   if [ "$CONFIG_BOARD_EVS3C4530HEI" = "y" ]; then
+       define_bool CONFIG_ARCTURUS		y
+       define_string CONFIG_CPU_NAME "S3C4530A01-Q"
+       bool ' Enable uCbootloader support' CONFIG_UCBOOTSTRAP
+       define_bool CONFIG_CPU_S3C4530      y
+       define_bool CONFIG_CPU_ARM710       y
+       define_bool CONFIG_CPU_32           y
+       define_bool CONFIG_CPU_26           n
+       define_bool CONFIG_NO_PGT_CACHE     y
+       define_bool CONFIG_CPU_WITH_CACHE   y
+       define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION n
+       define_int  CONFIG_ARM_CLK          50000000
+       define_hex  DRAM_BASE               0x00000000
+       define_hex  DRAM_SIZE               0x007F0000
+       define_hex  FLASH_MEM_BASE          0x01000000
+       define_hex  FLASH_SIZE              0x00200000
+       define_hex  FLASH1_MEM_BASE         0x01200000
+       define_hex  FLASH1_SIZE             0x00200000
+   fi
+
+   if [ "$CONFIG_BOARD_SNDS100" = "y" ]; then
+      define_bool CONFIG_NO_PGT_CACHE y
+      define_bool CONFIG_CPU_32 y
+      define_bool CONFIG_CPU_32v4 y
+      define_bool CONFIG_CPU_26 n
+      define_bool CONFIG_CPU_S3C4510 y
+      define_bool CONFIG_CPU_ARM710 y
+      define_bool CONFIG_CPU_WITH_CACHE y
+      define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION n
+      if [ "$CONFIG_SET_MEM_PARAM" = "n" ]; then
+        define_hex DRAM_BASE 0x00000000
+        define_hex DRAM_SIZE 0x00800000
+        define_hex FLASH_MEM_BASE 0x01000000
+        define_hex FLASH_SIZE 0x00200000
+      fi
+      if [ "$CONFIG_RAMKERNEL" = "y" ]; then
+        bool 'Support ZyXEL BootExtension' CONFIG_ZYXEL_BOOTEXT
+      fi
+   fi
+
+   if [ "$CONFIG_BOARD_SMDK2500" = "y" ]; then
+       define_bool CONFIG_ARCTURUS		y
+       define_string	CONFIG_CPU_NAME "S3C2500"
+       bool ' Enable uCbootloader support' CONFIG_UCBOOTSTRAP
+       define_bool	CONFIG_CPU_S3C2500	y
+       define_bool	CONFIG_CPU_ARM940T 	y
+       define_bool	CONFIG_CPU_32 		y
+       define_bool	CONFIG_CPU_26 		n
+       define_bool	CONFIG_NO_PGT_CACHE 	y
+       define_bool	CONFIG_CPU_WITH_CACHE 	y
+       define_bool	CONFIG_CPU_WITH_MCR_INSTRUCTION y
+       define_hex	DRAM_BASE 		0x00000000
+       define_hex	DRAM_SIZE 		0x02000000
+       define_hex	SRAM_BASE 		0x83000000
+       define_hex	SRAM_SIZE 		0x00100000
+       define_hex	FLASH_MEM_BASE 		0x80000000
+       define_hex	FLASH_SIZE 		0x00080000
+       define_hex	FLASH1_MEM_BASE		0x81000000
+       define_hex	FLASH1_SIZE 		0x00200000
+	    
+       if [ "$CONFIG_UCBOOTSTRAP" != "y" ]; then
+          bool 'Coprocessor futures' CONFIG_CPU_ARM940_COPROCESSOR
+          if [ "$CONFIG_CPU_ARM940_COPROCESSOR" = "y" ] ; then
+	     bool ' Low-power mode' CONFIG_CPU_ARM940_CPU_IDLE
+	     bool ' I-Cache' CONFIG_CPU_ARM940_I_CACHE_ON
+	     bool ' D-Cache' CONFIG_CPU_ARM940_D_CACHE_ON
+	     if [ "$CONFIG_CPU_ARM940_D_CACHE_ON" = "y" ] ; then
+	        bool '  Force write through D-Cache' CONFIG_CPU_ARM940_FORCE_WRITE_THROUGH
+	     fi
+	   fi
+       else 
+	   define_bool CONFIG_CPU_ARM940_CPU_IDLE y
+       fi
+   fi
+
+   if [ "$CONFIG_BOARD_S3C2500REFRGP" = "y" ]; then
+       define_bool CONFIG_ARCTURUS		y
+       define_string	CONFIG_CPU_NAME "S3C2500"
+       bool ' Enable uCbootloader support' CONFIG_UCBOOTSTRAP
+       define_bool	CONFIG_CPU_S3C2500	y
+       define_bool	CONFIG_CPU_ARM940T 	y
+       define_bool	CONFIG_CPU_32 		y
+       define_bool	CONFIG_CPU_26 		n
+       define_bool	CONFIG_NO_PGT_CACHE 	y
+       define_bool	CONFIG_CPU_WITH_CACHE 	y
+       define_bool	CONFIG_CPU_WITH_MCR_INSTRUCTION y
+       define_hex	DRAM_BASE 		0x00000000
+       define_hex	DRAM_SIZE 		0x01000000
+       define_hex	FLASH_MEM_BASE 		0x80000000
+       define_hex	FLASH_SIZE 		0x00400000
+
+       if [ "$CONFIG_UCBOOTSTRAP" != "y" ]; then
+          bool 'Coprocessor futures' CONFIG_CPU_ARM940_COPROCESSOR
+          if [ "$CONFIG_CPU_ARM940_COPROCESSOR" = "y" ] ; then
+	     bool ' Low-power mode' CONFIG_CPU_ARM940_CPU_IDLE
+	     bool ' I-Cache' CONFIG_CPU_ARM940_I_CACHE_ON
+	     bool ' D-Cache' CONFIG_CPU_ARM940_D_CACHE_ON
+	     if [ "$CONFIG_CPU_ARM940_D_CACHE_ON" = "y" ] ; then
+	        bool '  Force write through D-Cache' CONFIG_CPU_ARM940_FORCE_WRITE_THROUGH
+	     fi
+	   fi
+       else 
+	   define_bool CONFIG_CPU_ARM940_CPU_IDLE y
+       fi
+   fi
+fi
+
+if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
+   define_bool CONFIG_NO_PGT_CACHE y
+   define_bool CONFIG_CPU_ARM740T y
+   define_bool CONFIG_CPU_32 y
+   define_bool CONFIG_CPU_WITH_CACHE y
+   define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION y
+   define_hex DRAM_BASE 0
+   define_hex DRAM_SIZE 0x04000000
+   define_hex FLASH_MEM_BASE 0x25000000
+   define_hex FLASH_SIZE 0x02000000
+fi
+
+if [ "$CONFIG_ARCH_IPOD" = "y" ]; then
+   define_bool CONFIG_NO_PGT_CACHE y
+   define_bool CONFIG_CPU_ARM710 y
+   define_bool CONFIG_CPU_ARM7TDMI y
+   define_bool CONFIG_CPU_32 y
+   define_bool CONFIG_CPU_26 n
+   define_hex DRAM_BASE 0x28000000
+   define_hex DRAM_SIZE 0x02000000
+   define_hex FLASH_MEM_BASE 0x10000000
+   define_hex FLASH_SIZE 0x00100000
+fi
+
+if [ "$CONFIG_ARCH_TA7S" = "y" -o "$CONFIG_ARCH_TA7V" = "y" ]; then
+   define_bool CONFIG_CPU_ARM710 y
+   define_bool CONFIG_CPU_ARM7TDMI y
+   define_bool CONFIG_CPU_32 y
+   define_bool CONFIG_NO_PGT_CACHE y   
+   define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION n
+
+   if [ "$CONFIG_SET_MEM_PARAM" = "n" ]; then
+     if [ "$CONFIG_BOARD_A7DB" = "y" ]; then
+       define_hex DRAM_BASE 0x00000000
+       define_hex DRAM_SIZE 0x02000000
+       define_hex FLASH_MEM_BASE 0xd0000000
+       define_hex FLASH_SIZE 0x00200000
+     fi
+     if [ "$CONFIG_BOARD_DevA7" = "y" -o \
+          "$CONFIG_BOARD_TA7VT05_RevA" = "y" ]; then
+       define_hex DRAM_BASE 0x00000000
+       define_hex DRAM_SIZE 0x02000000
+       define_hex FLASH_MEM_BASE 0xd0000000
+       define_hex FLASH_SIZE 0x00800000
+     fi
+     if [ "$CONFIG_BOARD_A7VXDB" = "y" ]; then
+       define_hex DRAM_BASE 0x00000000
+       define_hex DRAM_SIZE 0x04000000
+       define_hex FLASH_MEM_BASE 0xd0000000
+       define_hex FLASH_SIZE 0x01000000
+     fi
+   fi
+fi
+
+if [ "$CONFIG_ARCH_INL" = "y" ]; then
+   define_bool CONFIG_CPU_32 y
+   define_bool CONFIG_NO_PGT_CACHE y
+   define_bool MAGIC_ROM_PTR y
+   define_bool CONFIG_CPU_WITH_CACHE y
+   define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION y
+
+   comment 'Intersil Specific Settings'
+   bool 'SIDED support' CONFIG_INL_SIDED y
+   bool 'Use ARM9 Memory Protection Unit (MPU)' CONFIG_ARM9_MPU y
+   # FIXME Turn on bzip2 compression and change zImage Textaddress to 0x08400000
+   # so that bunzip2 has enough heap memory. This requires change in the bootloader!!!!
+   bool 'Use bzip2 instead of gzip for kernel compression' CONFIG_KERNEL_COMPRESS_BZIP2 n
+
+   comment 'MAC Controller related settings'
+   choice 'Intersil MAC Chip'	\
+	 " ISL3856-Poldhu		CONFIG_ARCH_POLDHU \
+	   ISL3893			CONFIG_ARCH_ISL3893"
+
+
+   if [ "$CONFIG_ARCH_POLDHU" = "y" ]; then
+      define_bool CONFIG_CPU_ARM940T y
+      bool 'Enable MVC DEBUG device' CONFIG_MVC_DEBUG n
+      dep_bool '  Enable Console on MVC DEBUG device' CONFIG_MVC_DEBUG_CONSOLE $CONFIG_MVC_DEBUG
+      bool 'Test DualBand driver on POLDHU platform?' CONFIG_POLDHU_TEST_DB_DRIVER y
+      bool 'Free WLAN pins for UART' CONFIG_FREE_WLAN_PINS n
+   fi
+
+   if [ "$CONFIG_ARCH_ISL3893" = "y" ]; then
+      define_bool CONFIG_CPU_ARM946T y
+      bool 'Enable MVC DEBUG device' CONFIG_MVC_DEBUG y
+      bool 'Enable PCI device' CONFIG_PCI n
+      dep_bool 'Enable micro AP device module' CONFIG_ISL_UAP $CONFIG_MODULES
+      if [ "$CONFIG_ISL_UAP" = "y" ]; then
+         define_bool CONFIG_ISL_UAP_MOD m
+         define_bool CONFIG_ISIL_UAP y
+      fi
+      dep_bool '  Enable Console on MVC DEBUG device' CONFIG_MVC_DEBUG_CONSOLE $CONFIG_MVC_DEBUG
+	  # bool 'Build for Simulator Environment?' ISL3893_SIMSONLY n
+	  bool 'Standalone Operation (No bootloader or MVC)?' ISL3893_STANDALONE y
+   fi
+
+   hex '  SDRAM Base Address' DRAM_BASE $DRAM_BASE
+   hex '  Compressed Kernel Link Address' CONFIG_ZIMAGE_TEXTADDR $CONFIG_ZIMAGE_TEXTADDR
+   bool 'Expert settings?' CONFIG_EXPERT_INL n
+   if [ "$CONFIG_EXPERT_INL" = "y" ]; then
+      int '  Asyncronous Clock Frequency' CONFIG_ARM_CLK 88000000 44000000 160000000
+      int '  Syncronous Clock Frequency' CONFIG_A_O_CLK 88000000 44000000 160000000
+   else
+      define_int CONFIG_ARM_CLK 88000000
+      define_int CONFIG_A_O_CLK 88000000
+   fi
+fi
+
+endmenu
+
+#------------------------------------------------------------------------------
+#                             G e n e r a l
+#------------------------------------------------------------------------------
+
+mainmenu_option next_comment
+comment 'General setup'
+source drivers/pci/Config.in
+bool 'Support hot-pluggable devices' CONFIG_HOTPLUG
+if [ "$CONFIG_HOTPLUG" = "y" ]; then
+   source drivers/pcmcia/Config.in
+else
+   define_bool CONFIG_PCMCIA n
+fi
+bool 'Networking support' CONFIG_NET
+bool 'System V IPC' CONFIG_SYSVIPC
+bool 'Reduced memory footprint' CONFIG_REDUCED_MEMORY
+bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'Sysctl support' CONFIG_SYSCTL
+tristate 'NWFPE math emulation' CONFIG_NWFPE
+choice 'Kernel core (/proc/kcore) format' \
+	"ELF		CONFIG_KCORE_ELF \
+	 A.OUT		CONFIG_KCORE_AOUT" ELF
+tristate 'Support uClinux FLAT format binaries' CONFIG_BINFMT_FLAT
+dep_bool '  Support FLAT format compressed binaries' CONFIG_BINFMT_ZFLAT $CONFIG_BINFMT_FLAT
+define_bool CONFIG_KERNEL_ELF y
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   bool 'Power Management support' CONFIG_PM
+fi
+
+if [ "$CONFIG_CPU_32" = "y" ]; then
+   tristate 'RISC OS personality' CONFIG_ARTHUR
+fi
+if [ "$CONFIG_ARCH_EBSA110" = "y" -o \
+     "$CONFIG_ARCH_SA1100" = "y" -o \
+     "$CONFIG_ARCH_CLPS7500" = "y" -o \
+     "$CONFIG_ARCH_PERSONAL_SERVER" = "y" -o \
+     "$CONFIG_ARCH_CATS" = "y" -o \
+     "$CONFIG_ARCH_ATMEL" = "y" -o \
+     "$CONFIG_ARCH_NETARM" = "y" -o \
+     "$CONFIG_ARCH_DM270" = "y" -o \
+     "$CONFIG_ARCH_SAMSUNG" = "y" -o \
+     "$CONFIG_ARCH_TA7S" = "y" -o \
+     "$CONFIG_ARCH_TA7V" = "y" -o \
+     "$CONFIG_ARCH_IPOD" = "y" ]; then
+   bool 'Compiled-in Kernel Boot Parameter' CONFIG_CMDLINE_BOOL
+   if [ "$CONFIG_CMDLINE_BOOL" = "y" ]; then
+      string 'Default kernel command string' CONFIG_CMDLINE ""
+   fi
+fi
+if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \
+     "$CONFIG_ARCH_EBSA110" = "y" -o   \
+     "$CONFIG_ARCH_EBSA285" = "y" -o   \
+     "$CONFIG_ARCH_CO285" = "y" -o     \
+     "$CONFIG_ARCH_SA1100" = "y" ]; then
+   bool 'Timer and CPU usage LEDs' CONFIG_LEDS
+   if [ "$CONFIG_LEDS" = "y" ]; then
+      if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \
+	   "$CONFIG_ARCH_EBSA285" = "y" -o   \
+	   "$CONFIG_ARCH_CO285" = "y" -o     \
+	   "$CONFIG_ARCH_SA1100" = "y" ]; then
+         bool '  Timer LED' CONFIG_LEDS_TIMER
+         bool '  CPU usage LED' CONFIG_LEDS_CPU
+      fi
+   fi
+   if [ "$CONFIG_ARCH_EBSA110" = "y" ]; then
+      define_bool CONFIG_LEDS_TIMER y
+   fi
+fi
+if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" -a "$CONFIG_ARCH_TA7S" != "y" -a "$CONFIG_ARCH_TA7V" != "y" ]; then
+   bool 'Kernel-mode alignment trap handler' CONFIG_ALIGNMENT_TRAP
+fi
+
+if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
+   bool 'PCI support' CONFIG_PCI_INTEGRATOR
+   define_bool CONFIG_PCI $CONFIG_PCI_INTEGRATOR
+else
+   define_bool CONFIG_PCI n
+fi
+bool 'm68knommu-style attached romfs in RAM support' CONFIG_RAM_ATTACHED_ROMFS
+endmenu
+
+#------------------------------------------------------------------------------
+#                           N e t    D e v i c e s
+#------------------------------------------------------------------------------
+
+if [ "$CONFIG_NET" = "y" ]; then
+   source net/Config.in
+   mainmenu_option next_comment
+   comment 'Network device support'
+   bool 'Network device support?' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+   fi
+   endmenu
+   source net/ax25/Config.in
+   source net/irda/Config.in
+fi
+
+#------------------------------------------------------------------------------
+#                               A T E / I D E
+#------------------------------------------------------------------------------
+
+mainmenu_option next_comment
+comment 'ATA/IDE/MFM/RLL support'
+tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+if [ "$CONFIG_IDE" != "n" ]; then
+  source drivers/ide/Config.in
+else
+  define_bool CONFIG_BLK_DEV_HD n
+fi
+endmenu
+
+#------------------------------------------------------------------------------
+#                                  S C S I
+#------------------------------------------------------------------------------
+
+mainmenu_option next_comment
+comment 'SCSI support'
+tristate 'SCSI support?' CONFIG_SCSI
+if [ "$CONFIG_SCSI" != "n" ]; then
+   source drivers/scsi/Config.in
+fi
+endmenu
+
+#------------------------------------------------------------------------------
+#                                  I S D N
+#------------------------------------------------------------------------------
+
+mainmenu_option next_comment
+comment 'ISDN subsystem'
+tristate 'ISDN support' CONFIG_ISDN
+if [ "$CONFIG_ISDN" != "n" ]; then
+   source drivers/isdn/Config.in
+fi
+endmenu
+
+#------------------------------------------------------------------------------
+#                              C o n s o l e
+#------------------------------------------------------------------------------
+
+if [ "$CONFIG_VT" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Console drivers'
+   if [ "$CONFIG_ARCH_ACORN" != "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then
+      bool 'VGA text console' CONFIG_VGA_CONSOLE
+   fi
+   bool 'Support Frame buffer devices' CONFIG_FB
+   source drivers/video/Config.in
+   endmenu
+fi
+
+#------------------------------------------------------------------------------
+#                        M i s c    D r i v e r s
+#------------------------------------------------------------------------------
+
+if [ "$CONFIG_ARCH_TA7S" = "y" -o "$CONFIG_ARCH_TA7V" = "y" ]; then
+   source drivers/misc/Config.in
+fi
+source drivers/parport/Config.in
+source drivers/mtd/Config.in
+source drivers/pnp/Config.in
+source drivers/block/Config.in
+source fs/Config.in
+source drivers/input/Config.in
+
+source drivers/char/Config.in
+source drivers/usb/Config.in
+source drivers/ieee1394/Config.in
+source drivers/message/i2o/Config.in
+
+if [ "$CONFIG_ARCH_IPOD" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'iPod Stuff'
+   tristate "iPod Audio" CONFIG_AUDIO_IPOD
+   tristate "iPod Keypad support" CONFIG_KB_IPOD
+   dep_tristate "iPod Remote support" CONFIG_REMOTE_IPOD $CONFIG_INPUT_KEYBDEV
+   endmenu
+fi
+
+#------------------------------------------------------------------------------
+#                     K e r n e l    H a c k i n g
+#------------------------------------------------------------------------------
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+define_bool CONFIG_FRAME_POINTER y
+bool 'Find REVISITS' CONFIG_REVISIT
+bool 'Verbose kernel error messages' CONFIG_DEBUG_ERRORS
+bool 'Verbose user fault messages' CONFIG_DEBUG_USER
+bool 'Include debugging information in kernel binary' CONFIG_DEBUG_INFO
+dep_bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ $CONFIG_VT
+if [ "$CONFIG_CPU_26" = "y" ]; then
+   bool 'Disable pgtable cache' CONFIG_NO_PGT_CACHE
+fi
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   bool 'Kernel low-level debugging functions' CONFIG_DEBUG_LL
+   if [ "$CONFIG_DEBUG_LL" = "y" ]; then
+      if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
+         bool 'Kernel low-level debugging messages via footbridge serial port' CONFIG_DEBUG_DC21285_PORT
+      fi
+      if [ "$CONFIG_ARCH_DM270" = "y" ]; then
+         bool 'Kernel low-level debugging messages via UART1 (default UART0)' CONFIG_DEBUG_DM270_UART1
+      fi
+   fi
+   bool 'Non power-of-2 kernel allocator (EXPERIMENTAL)' CONFIG_CONTIGUOUS_PAGE_ALLOC
+   dep_bool '  Include /proc/mem_map' CONFIG_MEM_MAP $CONFIG_CONTIGUOUS_PAGE_ALLOC
+   if [ "$CONFIG_CONTIGUOUS_PAGE_ALLOC" = "y" ]; then
+      if [ "$CONFIG_CPU_ARM940T" = "y" ]; then
+        bool '  UnCached Memory Support' CONFIG_UNCACHED_MEM
+	if [ "$CONFIG_UNCACHED_MEM" = "y" ]; then
+         choice 'UnCached Memory Size (KByte)' \
+	  "256KB	CONFIG_UNCACHED_256 \
+	   512KB	CONFIG_UNCACHED_512 \
+	  1024KB	CONFIG_UNCACHED_1024 \
+	  2048KB	CONFIG_UNCACHED_2048 \
+	  4096KB	CONFIG_UNCACHED_4096 \
+	  8192KB	CONFIG_UNCACHED_8192" 1024KB
+       fi
+     fi
+   fi
+   if [ "$CONFIG_CONTIGUOUS_PAGE_ALLOC" != "y" ]; then
+       bool 'Allow allocating large blocks (> 1MB) of memory' CONFIG_NO_MMU_LARGE_ALLOCS
+   fi
+fi
+
+endmenu
+
+source crypto/Config.in
+source lib/Config.in
+
diff -urN linux-2.4.29/arch/armnommu/def-configs/atmel linux-2.4.29-uc1/arch/armnommu/def-configs/atmel
--- linux-2.4.29/arch/armnommu/def-configs/atmel	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/def-configs/atmel	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,229 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_SBUS is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_UCLINUX=y
+MAGIC_ROM_PTR=y
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_DSC21 is not set
+# CONFIG_ARCH_CNXT is not set
+CONFIG_ARCH_ATMEL=y
+CONFIG_NO_PGT_CACHE=y
+CONFIG_CPU_ARM710=y
+CONFIG_CPU_32=y
+DRAM_BASE=0x01000000
+CONFIG_CPU_AT91X40=y
+DRAM_SIZE=0x00200000
+FLASH_MEM_BASE=0x08400000
+FLASH_SIZE=0x00200000
+CONFIG_SERIAL_ATMEL=y
+CONFIG_ATMEL_DEBUG=y
+AT91_DEBUG_BASE=01400000
+
+#
+# General setup
+#
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_NET is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_REDUCED_MEMORY is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+# CONFIG_NWFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_FLAT=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_ARTHUR is not set
+# CONFIG_ALIGNMENT_TRAP is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_BLKMEM is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_PROC_FS is not set
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_EXT2_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Character devices
+#
+# CONFIG_LEDMAN is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_REVISIT is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_MAGIC_SYSRQ is not set
diff -urN linux-2.4.29/arch/armnommu/def-configs/cx821xx linux-2.4.29-uc1/arch/armnommu/def-configs/cx821xx
--- linux-2.4.29/arch/armnommu/def-configs/cx821xx	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/def-configs/cx821xx	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,444 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_SBUS is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_UCLINUX=y
+MAGIC_ROM_PTR=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ATMEL is not set
+CONFIG_ARCH_CNXT=y
+# CONFIG_ARCH_DSC21 is not set
+# CONFIG_ARCH_S3C4 is not set
+# CONFIG_ARCH_P52 is not set
+# CONFIG_ARCH_SPIPE is not set
+CONFIG_ARCH_CX821XX=y
+# CONFIG_BD_HASBANI is not set
+CONFIG_BD_GOLDENGATE=y
+# CONFIG_BD_MACKINAC is not set
+# CONFIG_BD_RUSHMORE is not set
+CONFIG_CHIP_CX82100=y
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+CONFIG_CPU_ARM940T=y
+CONFIG_NO_PGT_CACHE=y
+# CONFIG_SET_MEM_PARAM is not set
+DRAM_BASE=0x00800000
+DRAM_SIZE=0x00780000
+FLASH_MEM_BASE=0x00400000
+FLASH_SIZE=0x00400000
+CONFIG_CPU_ARM940_CPU_IDLE=y
+CONFIG_CPU_ARM940_I_CACHE_ON=y
+CONFIG_CPU_ARM940_D_CACHE_ON=y
+CONFIG_CPU_ARM940_WRITETHROUGH=y
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+# CONFIG_UCBOOTSTRAP is not set
+
+#
+# General setup
+#
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_REDUCED_MEMORY is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_NWFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+# CONFIG_ALIGNMENT_TRAP is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#  
+#
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_ATM_CLIP is not set
+# CONFIG_ATM_LANE is not set
+# CONFIG_ATM_BR2684 is not set
+# CONFIG_ATM_BR2684_IPFILTER is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+CONFIG_BRIDGE=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SAMSUNG_S3C is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+CONFIG_CNXT_EMAC=y
+# CONFIG_NUM_ETHERNET_IS_1 is not set
+CONFIG_NUM_ETHERNET_IS_2=y
+# CONFIG_NUM_ETHERNET_IS_3 is not set
+# CONFIG_NUM_ETHERNET_IS_4 is not set
+# CONFIG_FEC is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_UCCS8900 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_NET_ADSL is not set
+
+#
+# Conexant ADSL
+#
+# CONFIG_CNXT_ADSL is not set
+# CONFIG_CNXT_ADSL_TERMINAL is not set
+
+#
+# Conexant ATM driver
+#
+# CONFIG_CNXT_ATM is not set
+
+#
+# Conexant SoftSAR
+#
+# CONFIG_CNXT_SOFTSAR is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# VOIP support
+#
+# CONFIG_CNXT_VOIP is not set
+# CONFIG_CNXT_VOIP_1LGPIO is not set
+# CONFIG_CNXT_VOIP_GL is not set
+# CONFIG_CNXT_VOIP_SPI_GL is not set
+# CONFIG_CNXT_VOIP_SPI_NG is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_BLKMEM=y
+# CONFIG_BLK_DEV_BLKMEM_RAM is not set
+CONFIG_BLK_DEV_BLKMEM_ROM=y
+CONFIG_BLK_DEV_BLKMEM_ROM_STATIC=y
+CONFIG_BLK_DEV_BLKMEM_OFFSET=500000
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Character devices
+#
+# CONFIG_LEDMAN is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_SERIAL_CNXT=y
+# CONFIG_SERIAL_SPIPE is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_CNXT is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_REVISIT is not set
+# CONFIG_FRAME_POINTER is not set
+CONFIG_NO_FRAME_POINTER=y
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_LL is not set
diff -urN linux-2.4.29/arch/armnommu/def-configs/dm270 linux-2.4.29-uc1/arch/armnommu/def-configs/dm270
--- linux-2.4.29/arch/armnommu/def-configs/dm270	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/def-configs/dm270	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,408 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_SBUS is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_UCLINUX=y
+MAGIC_ROM_PTR=y
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_DSC21 is not set
+# CONFIG_ARCH_C5471 is not set
+CONFIG_ARCH_DM270=y
+# CONFIG_ARCH_CNXT is not set
+# CONFIG_ARCH_NETARM is not set
+# CONFIG_ARCH_TA7S is not set
+# CONFIG_ARCH_TA7V is not set
+# CONFIG_ARCH_SWARM is not set
+# CONFIG_ARCH_SAMSUNG is not set
+# CONFIG_ARCH_ATMEL is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+# CONFIG_SET_MEM_PARAM is not set
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+CONFIG_CPU_ARM710=y
+CONFIG_CPU_ARM7TDMI=y
+CONFIG_CPU_32=y
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_26 is not set
+CONFIG_NO_PGT_CACHE=y
+CONFIG_CPU_WITH_CACHE=y
+# CONFIG_CPU_WITH_MCR_INSTRUCTION is not set
+CONFIG_SERIAL_DM270=y
+CONFIG_ARM_CLK=87750000
+CONFIG_DM270_TIMER_PRESCALE=351
+CONFIG_SERIAL_DM270_CONSOLE=y
+DRAM_BASE=0x01200000
+DRAM_SIZE=0x02000000
+FLASH_MEM_BASE=0x00100000
+FLASH_SIZE=0x00200000
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# General setup
+#
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_REDUCED_MEMORY is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_NWFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+CONFIG_KERNEL_ELF=y
+# CONFIG_ARTHUR is not set
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_ALIGNMENT_TRAP is not set
+CONFIG_RAM_ATTACHED_ROMFS=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_ARP_LIMIT is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_IPSEC is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FEC is not set
+CONFIG_CS89x0=y
+# CONFIG_UCCS8900 is not set
+# CONFIG_UCCS89x0_HW_SWAP is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_BLKMEM=y
+# CONFIG_NOFLASH is not set
+CONFIG_AMDFLASH=y
+# CONFIG_INTELFLASH is not set
+CONFIG_FLASHAUTO=y
+# CONFIG_FLASH128KB is not set
+# CONFIG_FLASH1MB is not set
+# CONFIG_FLASH2MB is not set
+# CONFIG_FLASH4MB is not set
+# CONFIG_FLASH6MB is not set
+# CONFIG_FLASH8MB is not set
+# CONFIG_FLASH16MB is not set
+CONFIG_FLASHAUTOBIT=y
+# CONFIG_FLASH8BIT is not set
+# CONFIG_FLASH16BIT is not set
+# CONFIG_FLASH32bit is not set
+# CONFIG_EXTRA_FLASH is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFSD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Character devices
+#
+# CONFIG_SERIAL_SAMSUNG is not set
+CONFIG_SERIAL_DM270=y
+CONFIG_SERIAL_DM270_CONSOLE=y
+# CONFIG_LEDMAN is not set
+# CONFIG_DS1302 is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_SERIO is not set
+
+#
+# Joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Controller Area Network Cards/Chips
+#
+# CONFIG_CAN4LINUX is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+
+#
+# Direct Rendering Manager (XFree86 DRI support)
+#
+# CONFIG_DRM is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Support for USB gadgets
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_REVISIT is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.29/arch/armnommu/def-configs/dsc21 linux-2.4.29-uc1/arch/armnommu/def-configs/dsc21
--- linux-2.4.29/arch/armnommu/def-configs/dsc21	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/def-configs/dsc21	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,225 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_SBUS is not set
+CONFIG_UID16=y
+CONFIG_UCLINUX=y
+MAGIC_ROM_PTR=y
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# System Type
+#
+CONFIG_ARCH_DSC21=y
+CONFIG_CPU_ARM710=y
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+CONFIG_NO_PGT_CACHE=y
+DRAM_BASE=0x08000000
+DRAM_SIZE=0x01000000
+FLASH_MEM_BASE=0x02000000
+FLASH_SIZE=0x00200000
+# CONFIG_ARCH_ATMEL is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# General setup
+#
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_NET is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_REDUCED_MEMORY is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+# CONFIG_NWFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_FLAT=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_ARTHUR is not set
+# CONFIG_ALIGNMENT_TRAP is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_BLKMEM=y
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_PROC_FS is not set
+# CONFIG_DEVPTS_FS is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ACORN_PARTITION=y
+# CONFIG_ACORN_PARTITION_ICS is not set
+CONFIG_ACORN_PARTITION_ADFS=y
+# CONFIG_ACORN_PARTITION_POWERTEC is not set
+# CONFIG_ACORN_PARTITION_RISCIX is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Character devices
+#
+# CONFIG_LEDMAN is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_SERIAL_DSC21=y
+CONFIG_SERIAL_DSC21_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+CONFIG_SOFT_WATCHDOG=y
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_I810_TCO is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_REVISIT is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
diff -urN linux-2.4.29/arch/armnommu/def-configs/ipod linux-2.4.29-uc1/arch/armnommu/def-configs/ipod
--- linux-2.4.29/arch/armnommu/def-configs/ipod	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/def-configs/ipod	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,735 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_SBUS is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_UCLINUX=y
+MAGIC_ROM_PTR=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_DSC21 is not set
+# CONFIG_ARCH_C5471 is not set
+# CONFIG_ARCH_CNXT is not set
+# CONFIG_ARCH_NETARM is not set
+# CONFIG_ARCH_TA7S is not set
+# CONFIG_ARCH_TA7V is not set
+# CONFIG_ARCH_SWARM is not set
+# CONFIG_ARCH_SAMSUNG is not set
+# CONFIG_ARCH_ATMEL is not set
+CONFIG_ARCH_IPOD=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+# CONFIG_SET_MEM_PARAM is not set
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+CONFIG_NO_PGT_CACHE=y
+CONFIG_CPU_ARM710=y
+CONFIG_CPU_ARM7TDMI=y
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+DRAM_BASE=0x28000000
+DRAM_SIZE=0x02000000
+FLASH_MEM_BASE=0x10000000
+FLASH_SIZE=0x00100000
+
+#
+# General setup
+#
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_REDUCED_MEMORY is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_NWFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+CONFIG_KERNEL_ELF=y
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="root=/dev/hda3 rw"
+# CONFIG_ALIGNMENT_TRAP is not set
+# CONFIG_PCI is not set
+# CONFIG_RAM_ATTACHED_ROMFS is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_ARP_LIMIT is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+
+#
+#    SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FEC is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_UCCS8900 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_BLK_DEV_UCLINUX_IDE is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_SII is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=m
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_SD_EXTRA_DEVS=40
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_DEBUG_QUEUES=y
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FB=y
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_ACORN is not set
+# CONFIG_FB_CLPS711X is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_SA1100 is not set
+CONFIG_FB_IPOD=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_VIRTUAL_SMALL is not set
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+CONFIG_FBCON_CFB2=y
+# CONFIG_FBCON_CFB4 is not set
+# CONFIG_FBCON_CFB8 is not set
+# CONFIG_FBCON_CFB16 is not set
+# CONFIG_FBCON_CFB24 is not set
+# CONFIG_FBCON_CFB32 is not set
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_CISS_MONITOR_THREAD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_RAMDISK_DATA is not set
+# CONFIG_BLK_DEV_BLKMEM is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+CONFIG_HFSPLUS_FS=y
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_UMSDOS_FS=y
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=m
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_LEDMAN is not set
+# CONFIG_DS1302 is not set
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+CONFIG_INPUT_SERIO=y
+CONFIG_INPUT_SERPORT=y
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Controller Area Network Cards/Chips
+#
+# CONFIG_CAN4LINUX is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+
+#
+# Direct Rendering Manager (XFree86 DRI support)
+#
+# CONFIG_DRM is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Support for USB gadgets
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+CONFIG_IEEE1394=y
+
+#
+# Device Drivers
+#
+
+#
+#   Texas Instruments PCILynx requires I2C bit-banging
+#
+# CONFIG_IEEE1394_OHCI1394 is not set
+CONFIG_IEEE1394_IPOD=m
+
+#
+# Protocol Drivers
+#
+# CONFIG_IEEE1394_VIDEO1394 is not set
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_SBP2_PHYS_DMA=y
+CONFIG_IEEE1394_ETH1394=m
+# CONFIG_IEEE1394_DV1394 is not set
+# CONFIG_IEEE1394_RAWIO is not set
+# CONFIG_IEEE1394_CMP is not set
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+# CONFIG_IEEE1394_OUI_DB is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# iPod Stuff
+#
+CONFIG_AUDIO_IPOD=y
+CONFIG_KB_IPOD=y
+CONFIG_REMOTE_IPOD=y
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_REVISIT is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_LL is not set
+CONFIG_CONTIGUOUS_PAGE_ALLOC=y
+CONFIG_MEM_MAP=y
+CONFIG_NO_MMU_LARGE_ALLOCS=y
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.29/arch/armnommu/def-configs/isl3893 linux-2.4.29-uc1/arch/armnommu/def-configs/isl3893
--- linux-2.4.29/arch/armnommu/def-configs/isl3893	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/def-configs/isl3893	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,566 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_SBUS is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_UCLINUX=y
+MAGIC_ROM_PTR=y
+CONFIG_BINFMT_ZFLAT=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_DSC21 is not set
+# CONFIG_ARCH_CNXT is not set
+# CONFIG_ARCH_NETARM is not set
+# CONFIG_ARCH_SWARM is not set
+CONFIG_ARCH_INL=y
+# CONFIG_ARCH_SAMSUNG is not set
+# CONFIG_ARCH_ATMEL is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+# CONFIG_SET_MEM_PARAM is not set
+CONFIG_CPU_32=y
+CONFIG_NO_PGT_CACHE=y
+MAGIC_ROM_PTR=y
+CONFIG_CPU_WITH_CACHE=y
+CONFIG_CPU_WITH_MCR_INSTRUCTION=y
+# CONFIG_POLDHU_TEST_DB_DRIVER is not set
+CONFIG_INL_SIDED=y
+# CONFIG_ARM9_MPU is not set
+# CONFIG_KERNEL_COMPRESS_BZIP2 is not set
+# CONFIG_ARCH_POLDHU is not set
+CONFIG_ARCH_ISL3893=y
+CONFIG_CPU_ARM946T=y
+# CONFIG_PCI is not set
+# ISL3893_SIMSONLY is not set
+ISL3893_STANDALONE=y
+DRAM_BASE=00000000
+CONFIG_ZIMAGE_TEXTADDR=00420000
+# CONFIG_EXPERT_INL is not set
+CONFIG_ARM_CLK=88000000
+CONFIG_A_O_CLK=88000000
+
+#
+# General setup
+#
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+# CONFIG_SYSVIPC is not set
+CONFIG_REDUCED_MEMORY=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_NWFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_FLAT=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+# CONFIG_ALIGNMENT_TRAP is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_TOS is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+# CONFIG_IP_ROUTE_LARGE_TABLES is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=y
+CONFIG_IP_NF_FTP=y
+CONFIG_IP_NF_IRC=y
+CONFIG_IP_NF_PPTP=y
+# CONFIG_IP_NF_PPTP_DEBUG is not set
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_USERINDEX=y
+CONFIG_IP_NF_MATCH_LIMIT=y
+# CONFIG_IP_NF_MATCH_MAC is not set
+# CONFIG_IP_NF_MATCH_MARK is not set
+# CONFIG_IP_NF_MATCH_MULTIPORT is not set
+# CONFIG_IP_NF_MATCH_TOS is not set
+# CONFIG_IP_NF_MATCH_AH_ESP is not set
+# CONFIG_IP_NF_MATCH_LENGTH is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+# CONFIG_IP_NF_MATCH_TCPMSS is not set
+# CONFIG_IP_NF_MATCH_STATE is not set
+# CONFIG_IP_NF_MATCH_UNCLEAN is not set
+# CONFIG_IP_NF_MATCH_OWNER is not set
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+# CONFIG_IP_NF_TARGET_MIRROR is not set
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+# CONFIG_IP_NF_TARGET_REDIRECT is not set
+# CONFIG_IP_NF_NAT_LOCAL is not set
+# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
+CONFIG_IP_NF_NAT_IRC=y
+CONFIG_IP_NF_NAT_FTP=y
+# CONFIG_IP_NF_MANGLE is not set
+CONFIG_IP_NF_TARGET_LOG=y
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_IP_NF_TARGET_TCPMSS=y
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+CONFIG_BRIDGE=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ISIL_MVCDRIVER is not set
+# CONFIG_ISL3893_ETHERNET is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FEC is not set
+# CONFIG_CS89x0 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPPOE=y
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_BOOTLDR_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0
+CONFIG_MTD_PHYSMAP_LEN=400000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=1
+# CONFIG_MTD_DRAGONIX is not set
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_NETteluC is not set
+# CONFIG_MTD_KeyTechnology is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_RAMDISK_DATA is not set
+CONFIG_BLK_DEV_BLKMEM=y
+CONFIG_NOFLASH=y
+# CONFIG_AMDFLASH is not set
+# CONFIG_INTELFLASH is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS_FS=y
+CONFIG_JFFS_FS_VERBOSE=0
+CONFIG_JFFS_PROC_FS=y
+CONFIG_JFFS_SMALL_PARTITIONS=y
+# CONFIG_JFFS_GC_DAEMON is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_EXT2_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=y
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Character devices
+#
+# CONFIG_LEDMAN is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_REVISIT is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_CONTIGUOUS_PAGE_ALLOC is not set
+# CONFIG_MEM_MAP is not set
diff -urN linux-2.4.29/arch/armnommu/def-configs/netarm linux-2.4.29-uc1/arch/armnommu/def-configs/netarm
--- linux-2.4.29/arch/armnommu/def-configs/netarm	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/def-configs/netarm	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,474 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_SBUS is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_UCLINUX=y
+MAGIC_ROM_PTR=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_OBSOLETE=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_DSC21 is not set
+# CONFIG_ARCH_CNXT is not set
+CONFIG_ARCH_NETARM=y
+# CONFIG_ARCH_SWARM is not set
+# CONFIG_ARCH_SAMSUNG is not set
+# CONFIG_ARCH_ATMEL is not set
+# CONFIG_NETARM_NET15 is not set
+CONFIG_NETARM_NET40=y
+# CONFIG_NETARM_NET50 is not set
+# CONFIG_SET_MEM_PARAM is not set
+CONFIG_CPU_ARM710=y
+CONFIG_CPU_ARM7TDMI=y
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+CONFIG_CPU_WITH_CACHE=y
+# CONFIG_CPU_WITH_MCR_INSTRUCTION is not set
+CONFIG_NO_PGT_CACHE=y
+# CONFIG_NETARM_NET40_REV2 is not set
+CONFIG_NETARM_NET40_REV4=y
+CONFIG_NETARM_PLL_BYPASS=y
+# CONFIG_NETARM_EMLIN is not set
+DRAM_BASE=0x00000000
+FLASH_MEM_BASE=0x10000000
+DRAM_SIZE=0x02000000
+FLASH_SIZE=0x00800000
+CONFIG_NETARM_EEPROM=y
+
+#
+# General setup
+#
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_REDUCED_MEMORY is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_NWFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_FLAT=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+# CONFIG_ALIGNMENT_TRAP is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FEC is not set
+# CONFIG_CS89x0 is not set
+CONFIG_ETHER_NETARM=y
+NETARM_OUI=0040AF
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=3
+# CONFIG_MTD_PARTITIONS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_B1 is not set
+# CONFIG_MTD_CFI_B2 is not set
+CONFIG_MTD_CFI_B4=y
+# CONFIG_MTD_CFI_I1 is not set
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x10000000
+CONFIG_MTD_PHYSMAP_LEN=0x00800000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=4
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_IQ80310 is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_RAMDISK_DATA=y
+# CONFIG_BLK_DEV_BLKMEM is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_EXT2_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFSD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Character devices
+#
+# CONFIG_LEDMAN is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_SERIAL_NETARM=y
+CONFIG_SERIAL_NETARM_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_SERIO is not set
+
+#
+# Joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+
+#
+# USB Device Class drivers
+#
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+# USB Imaging devices
+#
+
+#
+# USB Multimedia devices
+#
+
+#
+# USB Network adaptors
+#
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+
+#
+# USB Miscellaneous drivers
+#
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_REVISIT is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_LL is not set
+# CONFIG_CONTIGUOUS_PAGE_ALLOC is not set
diff -urN linux-2.4.29/arch/armnommu/def-configs/poldhu linux-2.4.29-uc1/arch/armnommu/def-configs/poldhu
--- linux-2.4.29/arch/armnommu/def-configs/poldhu	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/def-configs/poldhu	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,652 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_SBUS is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_UCLINUX=y
+MAGIC_ROM_PTR=y
+CONFIG_BINFMT_ZFLAT=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_DSC21 is not set
+# CONFIG_ARCH_CNXT is not set
+# CONFIG_ARCH_SWARM is not set
+CONFIG_ARCH_INL=y
+# CONFIG_ARCH_ATMEL is not set
+CONFIG_ARCH_POLDHU=y
+# CONFIG_ARCH_ISL3893 is not set
+CONFIG_CPU_ARM940T=y
+CONFIG_CPU_32=y
+CONFIG_NO_PGT_CACHE=y
+MAGIC_ROM_PTR=y
+CONFIG_CPU_WITH_CACHE=y
+CONFIG_CPU_WITH_MCR_INSTRUCTION=y
+# CONFIG_EXPERT_INL is not set
+CONFIG_INL_SIDED=y
+CONFIG_ARM9_MPU=y
+# CONFIG_KERNEL_COMPRESS_BZIP2 is not set
+CONFIG_ARM_CLK=88000000
+CONFIG_A_O_CLK=88000000
+DRAM_BASE=08000000
+CONFIG_ZIMAGE_TEXTADDR=08510000
+
+#
+# General setup
+#
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+# CONFIG_SYSVIPC is not set
+CONFIG_REDUCED_MEMORY=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_NWFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_FLAT=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+# CONFIG_ALIGNMENT_TRAP is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_TOS is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+# CONFIG_IP_ROUTE_LARGE_TABLES is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=y
+CONFIG_IP_NF_FTP=y
+CONFIG_IP_NF_IRC=y
+CONFIG_IP_NF_PPTP=y
+# CONFIG_IP_NF_PPTP_DEBUG is not set
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_USERINDEX=y
+CONFIG_IP_NF_MATCH_LIMIT=y
+# CONFIG_IP_NF_MATCH_MAC is not set
+# CONFIG_IP_NF_MATCH_MARK is not set
+# CONFIG_IP_NF_MATCH_MULTIPORT is not set
+# CONFIG_IP_NF_MATCH_TOS is not set
+# CONFIG_IP_NF_MATCH_LENGTH is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+# CONFIG_IP_NF_MATCH_TCPMSS is not set
+# CONFIG_IP_NF_MATCH_STATE is not set
+# CONFIG_IP_NF_MATCH_UNCLEAN is not set
+# CONFIG_IP_NF_MATCH_OWNER is not set
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+# CONFIG_IP_NF_TARGET_MIRROR is not set
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+# CONFIG_IP_NF_TARGET_REDIRECT is not set
+# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
+CONFIG_IP_NF_NAT_IRC=y
+CONFIG_IP_NF_NAT_FTP=y
+# CONFIG_IP_NF_MANGLE is not set
+CONFIG_IP_NF_TARGET_LOG=y
+# CONFIG_IP_NF_TARGET_TCPMSS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+CONFIG_BRIDGE=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+CONFIG_POLDHU_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FEC is not set
+# CONFIG_CS89x0 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_BOOTLDR_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0
+CONFIG_MTD_PHYSMAP_LEN=400000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=1
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_NETteluC is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_BLKMEM=y
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS_FS=y
+CONFIG_JFFS_FS_VERBOSE=0
+CONFIG_JFFS_PROC_FS=y
+CONFIG_JFFS_SMALL_PARTITIONS=y
+# CONFIG_JFFS_GC_DAEMON is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_EXT2_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Character devices
+#
+# CONFIG_LEDMAN is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+# CONFIG_USB_HID is not set
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_REVISIT is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_CONTIGUOUS_PAGE_ALLOC is not set
+# CONFIG_MEM_MAP is not set
+
+#
+# Intersil debugging options
+#
+POLDEBUG_ENABLE=y
+# POLDEBUG_PRINTK is not set
+# FREE_WLAN_PINS is not set
diff -urN linux-2.4.29/arch/armnommu/def-configs/s3c2500refrgp linux-2.4.29-uc1/arch/armnommu/def-configs/s3c2500refrgp
--- linux-2.4.29/arch/armnommu/def-configs/s3c2500refrgp	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/def-configs/s3c2500refrgp	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,509 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_SBUS is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_UCLINUX=y
+MAGIC_ROM_PTR=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_DSC21 is not set
+# CONFIG_ARCH_CNXT is not set
+# CONFIG_ARCH_NETARM is not set
+# CONFIG_ARCH_TA7S is not set
+# CONFIG_ARCH_SWARM is not set
+CONFIG_ARCH_SAMSUNG=y
+# CONFIG_ARCH_ATMEL is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+# CONFIG_SET_MEM_PARAM is not set
+# CONFIG_RAMKERNEL is not set
+CONFIG_ROMKERNEL=y
+# CONFIG_BOARD_SMDK40100 is not set
+# CONFIG_BOARD_EVS3C4530HEI is not set
+CONFIG_BOARD_S3C2500REFRGP=y
+# CONFIG_BOARD_SMDK2500 is not set
+# CONFIG_BOARD_SNDS100 is not set
+CONFIG_ARCTURUS=y
+CONFIG_CPU_NAME="S3C2500"
+# CONFIG_UCBOOTSTRAP is not set
+CONFIG_CPU_S3C2500=y
+CONFIG_CPU_ARM940T=y
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+CONFIG_NO_PGT_CACHE=y
+CONFIG_CPU_WITH_CACHE=y
+CONFIG_CPU_WITH_MCR_INSTRUCTION=y
+DRAM_BASE=0x00000000
+DRAM_SIZE=0x01000000
+FLASH_MEM_BASE=0x80000000
+FLASH_SIZE=0x00400000
+CONFIG_CPU_ARM940_COPROCESSOR=y
+CONFIG_CPU_ARM940_CPU_IDLE=y
+CONFIG_CPU_ARM940_I_CACHE_ON=y
+CONFIG_CPU_ARM940_D_CACHE_ON=y
+# CONFIG_CPU_ARM940_FORCE_WRITE_THROUGH is not set
+
+#
+# General setup
+#
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+# CONFIG_SYSVIPC is not set
+CONFIG_REDUCED_MEMORY=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_NWFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_FLAT=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+# CONFIG_ALIGNMENT_TRAP is not set
+# CONFIG_RAM_ATTACHED_ROMFS is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_ARP_LIMIT is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_ETH_S3C2500=y
+S3C2500_HWADDR="00:00:00:00:00:00"
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FEC is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_UCCS8900 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_RAMDISK_DATA is not set
+CONFIG_BLK_DEV_BLKMEM=y
+CONFIG_NOFLASH=y
+# CONFIG_AMDFLASH is not set
+# CONFIG_INTELFLASH is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_EXT2_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Character devices
+#
+CONFIG_SERIAL_S3C2500=y
+# CONFIG_CONSOLE_NULL is not set
+CONFIG_CONSOLE_CUART=y
+# CONFIG_CONSOLE_HUART0 is not set
+# CONFIG_CONSOLE_HUART1 is not set
+CONFIG_SERIAL_S3C2500_CONSOLE=y
+CONFIG_INIT_CONSOLE_SPEED=9600
+# CONFIG_LEDMAN is not set
+# CONFIG_DS1302 is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Controller Area Network Cards/Chips
+#
+# CONFIG_CAN4LINUX is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_REVISIT is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_LL is not set
+CONFIG_CONTIGUOUS_PAGE_ALLOC=y
+CONFIG_MEM_MAP=y
+CONFIG_UNCACHED_MEM=y
+# CONFIG_UNCACHED_256 is not set
+# CONFIG_UNCACHED_512 is not set
+# CONFIG_UNCACHED_1024 is not set
+CONFIG_UNCACHED_2048=y
+# CONFIG_UNCACHED_4096 is not set
+# CONFIG_UNCACHED_8192 is not set
+# CONFIG_NO_MMU_LARGE_ALLOCS is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff -urN linux-2.4.29/arch/armnommu/def-configs/smdk2500 linux-2.4.29-uc1/arch/armnommu/def-configs/smdk2500
--- linux-2.4.29/arch/armnommu/def-configs/smdk2500	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/def-configs/smdk2500	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,513 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_SBUS is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_UCLINUX=y
+MAGIC_ROM_PTR=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_DSC21 is not set
+# CONFIG_ARCH_CNXT is not set
+# CONFIG_ARCH_NETARM is not set
+# CONFIG_ARCH_TA7S is not set
+# CONFIG_ARCH_SWARM is not set
+CONFIG_ARCH_SAMSUNG=y
+# CONFIG_ARCH_ATMEL is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+# CONFIG_SET_MEM_PARAM is not set
+# CONFIG_RAMKERNEL is not set
+CONFIG_ROMKERNEL=y
+# CONFIG_BOARD_SMDK40100 is not set
+# CONFIG_BOARD_EVS3C4530HEI is not set
+# CONFIG_BOARD_S3C2500REFRGP is not set
+CONFIG_BOARD_SMDK2500=y
+# CONFIG_BOARD_SNDS100 is not set
+CONFIG_ARCTURUS=y
+CONFIG_CPU_NAME="S3C2500"
+# CONFIG_UCBOOTSTRAP is not set
+CONFIG_CPU_S3C2500=y
+CONFIG_CPU_ARM940T=y
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+CONFIG_NO_PGT_CACHE=y
+CONFIG_CPU_WITH_CACHE=y
+CONFIG_CPU_WITH_MCR_INSTRUCTION=y
+DRAM_BASE=0x00000000
+DRAM_SIZE=0x02000000
+SRAM_BASE=0x83000000
+SRAM_SIZE=0x00100000
+FLASH_MEM_BASE=0x80000000
+FLASH_SIZE=0x00080000
+FLASH1_MEM_BASE=0x81000000
+FLASH1_SIZE=0x00200000
+CONFIG_CPU_ARM940_COPROCESSOR=y
+CONFIG_CPU_ARM940_CPU_IDLE=y
+CONFIG_CPU_ARM940_I_CACHE_ON=y
+CONFIG_CPU_ARM940_D_CACHE_ON=y
+# CONFIG_CPU_ARM940_FORCE_WRITE_THROUGH is not set
+
+#
+# General setup
+#
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+# CONFIG_SYSVIPC is not set
+CONFIG_REDUCED_MEMORY=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_NWFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_FLAT=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+# CONFIG_ALIGNMENT_TRAP is not set
+# CONFIG_RAM_ATTACHED_ROMFS is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_ARP_LIMIT is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_ETH_S3C2500=y
+S3C2500_HWADDR="00:00:00:00:00:00"
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FEC is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_UCCS8900 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_RAMDISK_DATA is not set
+CONFIG_BLK_DEV_BLKMEM=y
+CONFIG_NOFLASH=y
+# CONFIG_AMDFLASH is not set
+# CONFIG_INTELFLASH is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_EXT2_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Character devices
+#
+CONFIG_SERIAL_S3C2500=y
+# CONFIG_CONSOLE_NULL is not set
+CONFIG_CONSOLE_CUART=y
+# CONFIG_CONSOLE_HUART0 is not set
+# CONFIG_CONSOLE_HUART1 is not set
+CONFIG_SERIAL_S3C2500_CONSOLE=y
+CONFIG_INIT_CONSOLE_SPEED=9600
+# CONFIG_LEDMAN is not set
+# CONFIG_DS1302 is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Controller Area Network Cards/Chips
+#
+# CONFIG_CAN4LINUX is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_REVISIT is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_LL is not set
+CONFIG_CONTIGUOUS_PAGE_ALLOC=y
+CONFIG_MEM_MAP=y
+CONFIG_UNCACHED_MEM=y
+# CONFIG_UNCACHED_256 is not set
+# CONFIG_UNCACHED_512 is not set
+# CONFIG_UNCACHED_1024 is not set
+# CONFIG_UNCACHED_2048 is not set
+CONFIG_UNCACHED_4096=y
+# CONFIG_UNCACHED_8192 is not set
+# CONFIG_NO_MMU_LARGE_ALLOCS is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff -urN linux-2.4.29/arch/armnommu/def-configs/TriscendA7_DevA7 linux-2.4.29-uc1/arch/armnommu/def-configs/TriscendA7_DevA7
--- linux-2.4.29/arch/armnommu/def-configs/TriscendA7_DevA7	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/def-configs/TriscendA7_DevA7	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,568 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_SBUS is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_UCLINUX=y
+MAGIC_ROM_PTR=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_DSC21 is not set
+# CONFIG_ARCH_CNXT is not set
+# CONFIG_ARCH_NETARM is not set
+CONFIG_ARCH_TA7S=y
+# CONFIG_ARCH_SWARM is not set
+# CONFIG_ARCH_SAMSUNG is not set
+# CONFIG_ARCH_ATMEL is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+# CONFIG_BOARD_A7DB is not set
+CONFIG_BOARD_DevA7=y
+# CONFIG_USE_A7HAL is not set
+# CONFIG_SET_MEM_PARAM is not set
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+CONFIG_CPU_ARM710=y
+CONFIG_CPU_ARM7TDMI=y
+CONFIG_CPU_32=y
+CONFIG_NO_PGT_CACHE=y
+# CONFIG_CPU_WITH_MCR_INSTRUCTION is not set
+DRAM_BASE=0x00000000
+DRAM_SIZE=0x02000000
+FLASH_MEM_BASE=0xd0000000
+FLASH_SIZE=0x00800000
+
+#
+# General setup
+#
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_REDUCED_MEMORY is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+# CONFIG_NWFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_FLAT=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FEC is not set
+CONFIG_CS89x0=y
+# CONFIG_UCCS89x0_HW_SWAP is not set
+# CONFIG_UCCS8900 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_BOOTLDR_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_B1 is not set
+# CONFIG_MTD_CFI_B2 is not set
+CONFIG_MTD_CFI_B4=y
+# CONFIG_MTD_CFI_I1 is not set
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=d0200000
+CONFIG_MTD_PHYSMAP_LEN=400000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=4
+# CONFIG_MTD_UCLINUX is not set
+# CONFIG_MTD_DRAGONIX is not set
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_NETteluC is not set
+# CONFIG_MTD_KeyTechnology is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_RAMDISK_DATA=y
+# CONFIG_BLK_DEV_BLKMEM is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS_FS=y
+CONFIG_JFFS_FS_VERBOSE=0
+CONFIG_JFFS_PROC_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_EXT2_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_SMB_FS=y
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_SMB_NLS=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Character devices
+#
+# CONFIG_LEDMAN is not set
+# CONFIG_DS1302 is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+CONFIG_SERIAL_TA7=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_REVISIT is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_CONTIGUOUS_PAGE_ALLOC is not set
+# CONFIG_MEM_MAP is not set
+CONFIG_NO_MMU_LARGE_ALLOCS=y
+
+#
+# Library routines
+#
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff -urN linux-2.4.29/arch/armnommu/fastfpe/config.h linux-2.4.29-uc1/arch/armnommu/fastfpe/config.h
--- linux-2.4.29/arch/armnommu/fastfpe/config.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/fastfpe/config.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,31 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Corel Computer Corporation, 1998
+
+    Direct questions, comments to Scott Bambrough <scottb@corelcomputer.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#if 1
+#define C_SYMBOL_NAME(foo)	foo
+#else
+#define C_SYMBOL_NAME(foo)	_##foo
+#endif
+
+#endif
diff -urN linux-2.4.29/arch/armnommu/fastfpe/CPDO.S linux-2.4.29-uc1/arch/armnommu/fastfpe/CPDO.S
--- linux-2.4.29/arch/armnommu/fastfpe/CPDO.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/fastfpe/CPDO.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,423 @@
+/*
+Inside the emulator the FP numbers are kept with 32 bit accuracy for both
+mantissa and exponent. The FP structure has 4 words reserved for each
+register, the first is used just for the sign in bit 31, the second is the
+mantissa (unsigned integer) and the third is the exponent (signed integer).
+
+The functions do actually only work properly for normalized values, and if
+no overflow occurs. Hopfully most programs are not disturbed by this, and it
+will probably be improved in future versions.
+
+The parameters to these functions are r0=destination pointer, r1 and r2
+source pointers. r4 is the instruction. They may use r0-r7. The return address
+is in r14, except CPDO_rnf_core which expects the return address in r5 to
+save memory accesses.
+*/
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_adf
+CPDO_adf:
+	ldmia	r1,{r1,r3,r5}
+	ldmia	r2,{r2,r4,r6}
+	cmp	r1,r2
+	bne	CPDO_suf_s
+
+CPDO_adf_s:
+	subs	r2,r5,r6
+	bge	CPDO_adf_1
+	
+	rsb	r2,r2,#0
+	mov	r5,r6
+	adds	r3,r4,r3,lsr r2
+	b	CPDO_adf_2
+	
+CPDO_adf_1:
+	adds	r3,r3,r4,lsr r2
+
+CPDO_adf_2:
+	addcs	r5,r5,#1
+	movcss	r3,r3,rrx
+	beq	CPDO_zero
+	stmia	r0,{r1,r3,r5}
+	
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_suf
+CPDO_suf:
+	ldmia	r1,{r1,r3,r5}
+	ldmia	r2,{r2,r4,r6}
+
+CPDO_suf_l:
+	cmp	r1,r2
+	bne	CPDO_adf_s
+
+CPDO_suf_s:	
+	subs	r2,r5,r6
+	bge	CPDO_suf_1
+	
+	rsb	r2,r2,#0
+	mov	r5,r6
+	rsbs	r3,r4,r3,lsr r2
+	b	CPDO_suf_2
+	
+CPDO_suf_1:
+	subs	r3,r3,r4,lsr r2
+	
+CPDO_suf_2:
+        beq	CPDO_zero
+	
+	eorcc	r1,r1,#0x80000000
+	rsbcc	r3,r3,#0
+	
+	cmp	r3,#0x00010000
+	movcc	r3,r3,lsl#16
+	subcc	r5,r5,#16
+	
+	cmp	r3,#0x01000000
+	movcc	r3,r3,lsl#8
+	subcc	r5,r5,#8
+	
+	cmp	r3,#0x10000000
+	movcc	r3,r3,lsl#4
+	subcc	r5,r5,#4
+	
+	cmp	r3,#0x40000000
+	movcc	r3,r3,lsl#2
+	subcc	r5,r5,#2
+	
+	cmp	r3,#0x80000000
+	movcc	r3,r3,lsl#1
+	subcc	r5,r5,#1
+	
+	stmia	r0,{r1,r3,r5}
+	
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl CPDO_rsf
+CPDO_rsf:
+	mov	r3,r2
+	ldmia	r1,{r2,r4,r6}
+	ldmia	r3,{r1,r3,r5}
+	b	CPDO_suf_l
+	
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_muf
+CPDO_muf:
+	ldmia	r1,{r1,r3,r5}
+	ldmia	r2,{r2,r4,r6}
+	
+	eor	r1,r1,r2
+	add	r6,r5,r6
+	umulls	r2,r5,r4,r3
+	beq	CPDO_zero
+	bpl	CPDO_muf_norm
+	
+	add	r6,r6,#1
+	stmia	r0,{r1,r5,r6}
+	mov	pc,r14
+
+CPDO_muf_norm:
+	adds	r2,r2,r2
+	adcs	r5,r5,r5
+	
+	stmia	r0,{r1,r5,r6}
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+/* Divison ignores the LSB in both mantissa, but needs only ~110 cycles.     */
+
+	.globl	CPDO_dvf
+CPDO_dvf:
+	ldmia	r1,{r1,r3,r5}
+	ldmia	r2,{r2,r4,r6}
+
+CPDO_dvf_l:
+	eor	r1,r1,r2
+	sub	r6,r5,r6
+
+	movs	r3,r3,lsr#1
+	beq	CPDO_zero
+	mov	r4,r4,lsr#1
+	rsb	r4,r4,#0
+	
+	.macro	div_step
+	adcs	r3,r4,r3,lsl#1
+	subcc	r3,r3,r4
+	adc	r5,r5,r5
+	.endm
+	
+	adds	r3,r4,r3
+	adc	r5,r5,r5
+	bcs	CPDO_dvf_b
+
+	subcc	r3,r3,r4
+	add	r3,r4,r3,lsl#1
+	mov	r5,#1
+	sub	r6,r6,#1
+	
+CPDO_dvf_b:	
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	div_step
+	
+CPDO_dvf_e:	
+	stmia	r0,{r1,r5,r6}
+	mov	pc,r14
+	
+CPDO_zero:
+	mov	r1,#0
+	mov	r2,#0
+	mov	r3,#0x80000000
+	stmia	r0,{r1-r3}
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_rdf
+CPDO_rdf:
+	mov	r3,r2
+	ldmia	r1,{r2,r4,r6}
+	ldmia	r3,{r1,r3,r5}
+	b	CPDO_dvf_l
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_rmf
+CPDO_rmf:
+	mov	pc,r14
+	
+/*---------------------------------------------------------------------------*/
+
+
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_mvf
+CPDO_mvf:
+	ldmia	r2,{r1,r2,r3}
+	stmia	r0,{r1,r2,r3}
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_mnf
+CPDO_mnf:
+	ldmia	r2,{r1,r2,r3}
+	eor	r1,r1,#0x80000000
+	stmia	r0,{r1,r2,r3}
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_abs
+CPDO_abs:
+	ldmia	r2,{r1,r2,r3}
+	bic	r1,r1,#0x80000000
+	stmia	r0,{r1,r2,r3}
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+	
+	.globl	CPDO_sqt
+CPDO_sqt:
+	ldmia	r2,{r1,r2,r4}
+	
+	and	r5,r4,#1
+	movs	r2,r2,lsl r5
+	
+	mov	r3,#0x80000000
+	sub	r2,r2,#0x80000000
+
+	.macro sqrt_step,N
+	add	r5,r3,#(0x40000000>>\N)
+	cmpcc	r2,r5
+	addcs	r3,r3,#(0x80000000>>\N)
+	subcs	r2,r2,r5
+	movs	r2,r2,lsl#1
+	.endm
+	
+	sqrt_step 1
+	sqrt_step 2
+	sqrt_step 3
+	sqrt_step 4
+	sqrt_step 5
+	sqrt_step 6
+	sqrt_step 7
+	sqrt_step 8
+	sqrt_step 9
+	sqrt_step 10
+	sqrt_step 11
+	sqrt_step 12
+	sqrt_step 13
+	sqrt_step 14
+	sqrt_step 15
+	sqrt_step 16
+	sqrt_step 17
+	sqrt_step 18
+	sqrt_step 19
+	sqrt_step 20
+	sqrt_step 21
+	sqrt_step 22
+	sqrt_step 23
+	sqrt_step 24
+	sqrt_step 25
+	sqrt_step 26
+	sqrt_step 27
+	sqrt_step 28
+	sqrt_step 29
+	sqrt_step 30 
+	sqrt_step 31 
+	
+	mov	r4,r4,asr#1
+	stmia	r0,{r1,r3,r4}
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+	
+	.globl	CPDO_rnd
+CPDO_rnd:
+	adr	r5,CPDO_rnd_store
+	b	CPDO_rnd_core
+
+CPDO_rnd_store:
+	stmia	r0,{r1,r2,r3}
+    	mov	pc,r14
+	
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDO_rnd_core
+CPDO_rnd_core:
+	ldmia	r2,{r1,r2,r3}
+	and	r4,r4,#0x00000060
+	add	pc,pc,r4,lsr#3
+	mov	r0,r0
+	b	CPDO_rnd_N
+	b	CPDO_rnd_P
+	b	CPDO_rnd_M
+	b	CPDO_rnd_Z
+	
+CPDO_rnd_N:
+	cmp	r3,#-1
+	blt	CPDO_rnd_zero
+	cmp	r3,#31
+	bge	CPDO_rnd_end
+	
+	rsb	r4,r3,#30
+	mov	r2,r2,lsr r4
+	add	r2,r2,#1
+	bic	r2,r2,#1
+	movs	r2,r2,lsl r4
+	addcs	r3,r3,#1
+	movcs	r2,r2,rrx
+	
+	mov	pc,r5
+
+CPDO_rnd_P:
+	cmp	r3,#0
+	blt	CPDO_rnd_P_small
+	cmp	r3,#31
+	movge	pc,r5
+	
+	tst	r1,#0x80000000
+	bne	CPDO_rnd_end
+	
+	mov	r4,#0x80000000
+	sub	r4,r4,#1
+	adds	r2,r2,r4,lsr r3
+	addcs	r3,r3,#1
+	movcs	r2,r2,rrx
+
+	b	CPDO_rnd_end
+	
+CPDO_rnd_P_small:
+	cmp	r2,#0	
+	beq	CPDO_rnd_zero
+	tst	r1,#0x80000000
+	bne	CPDO_rnd_zero
+	b	CPDO_rnd_one
+	
+	
+CPDO_rnd_M:
+	cmp	r3,#0
+	blt	CPDO_rnd_M_small
+	cmp	r3,#31
+	movge	pc,r5
+	
+	tst	r1,#0x80000000
+	beq	CPDO_rnd_end
+	
+	mov	r4,#0x80000000
+	sub	r4,r4,#1
+	adds	r2,r2,r4,lsr r3
+	addcs	r3,r3,#1
+	movcs	r2,r2,rrx
+
+	b	CPDO_rnd_end
+	
+CPDO_rnd_M_small:
+	cmp	r2,#0	
+	beq	CPDO_rnd_zero
+	tst	r1,#0x80000000
+	beq	CPDO_rnd_zero
+	b	CPDO_rnd_one
+	
+CPDO_rnd_Z:
+	cmp	r3,#0
+	blt	CPDO_rnd_zero
+	cmp	r3,#31
+	movge	pc,r5
+	
+	b	CPDO_rnd_end
+
+CPDO_rnd_one:
+	mov	r2,#0x80000000
+	mov	r3,#0
+	mov	pc,r5
+	
+CPDO_rnd_zero:
+	mov	r1,#0
+	mov	r2,#0
+	mov	r3,#0x80000000
+	mov	pc,r5
+
+CPDO_rnd_end:
+	rsb	r4,r3,#31
+	mov	r2,r2,lsr r4
+	mov	r2,r2,lsl r4
+	mov	pc,r5
+	
+/*---------------------------------------------------------------------------*/
diff -urN linux-2.4.29/arch/armnommu/fastfpe/CPDT.S linux-2.4.29-uc1/arch/armnommu/fastfpe/CPDT.S
--- linux-2.4.29/arch/armnommu/fastfpe/CPDT.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/fastfpe/CPDT.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,229 @@
+/*
+Inside the emulator the FP numbers are kept with 32 bit accuracy for both
+mantissa and exponent. The FP structure has 4 words reserved for each
+register, the first is used just for the sign in bit 31, the second is the
+mantissa (unsigned integer) and the third is the exponent (signed integer).
+
+The functions do actually only work properly for normalized values, and if
+no overflow occurs. Hopfully most programs are not disturbed by this, and it
+will probably be improved in future versions.
+
+Decimal and packed decimal numbers are not supported so yet.
+*/
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_load_single
+CPDT_load_single:
+	ldr	r1,[r6]
+	
+	bics	r2,r1,#0x80000000
+	beq	CPDT_load_zero		@ test for 0
+	
+	mov	r2,r1,lsl#8
+	orr	r2,r2,#0x80000000	@ insert leading 1
+
+	mov     r3,r1,lsr#23
+	bic     r3,r3,#0x100
+	sub     r3,r3,#127		@ subtract normalized bias
+
+	and	r1,r1,#0x80000000	@ only sign
+
+	stmia	r0,{r1-r3}
+	mov	pc,r14
+
+CPDT_load_zero:
+	mov	r1,#0
+	mov	r2,#0
+	mov	r3,#0x80000000
+	stmia	r0,{r1-r3}
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_load_double
+CPDT_load_double:
+	ldr	r2,[r6,#4]
+	ldr	r1,[r6]
+
+	bics	r3,r1,#0x80000000
+	cmpeq	r2,#0
+	beq	CPDT_load_zero		@ test for 0
+	
+	mov	r2,r2,lsr#21
+	orr	r2,r2,r1,lsl#11
+	orr	r2,r2,#0x80000000	@ insert leading 1
+
+	mov     r3,r1,lsr#20
+	bic     r3,r3,#0x800
+	sub     r3,r3,#1024
+	add	r3,r3,#1		@ subtract normalized bias
+
+	and	r1,r1,#0x80000000
+
+	cmp	r2,#0
+	beq	CPDT_load_zero
+	
+	stmia   r0,{r1-r3}
+	mov     pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_load_extended
+CPDT_load_extended:
+	ldr	r2,[r6,#4]
+	ldr	r1,[r6]
+	
+	cmp	r2,#0
+	bics	r3,r1,#0x80000000
+	beq	CPDT_load_zero		@ test for 0
+
+	orr	r2,r2,#0x80000000	@ insert leading 1
+
+	bic     r3,r1,#0x80000000
+	sub     r3,r3,#16384
+	add	r3,r3,#1		@ subtract normalized bias
+
+	and	r1,r1,#0x80000000
+	
+	cmp	r2,#0
+	beq	CPDT_load_zero	
+
+	stmia   r0,{r1-r3}
+	mov     pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_load_decimal
+CPDT_load_decimal:
+	
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_store_single
+CPDT_store_single:
+	ldmia	r0,{r1-r3}
+	
+	cmp	r2,#0
+	beq	CPDT_store_single_zero
+
+	adds	r3,r3,#127
+	ble	CPDT_store_single_zero
+	
+	bic	r3,r3,#0x100
+	orr	r1,r1,r3,lsl#23
+	
+	bic	r2,r2,#0x80000000
+	orr	r1,r1,r2,lsr#8
+
+	str	r1,[r6]
+	mov	pc,r14
+
+CPDT_store_single_zero:
+	mov	r1,#0
+	str	r1,[r6]
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_store_double
+CPDT_store_double:
+	ldmia	r0,{r1-r3}
+	
+	cmp	r2,#0
+	beq	CPDT_store_double_zero
+
+	adds	r3,r3,#1024
+	ble	CPDT_store_double_zero
+	
+	sub	r3,r3,#1
+	bic	r3,r3,#0x800
+	orr	r1,r1,r3,lsl#20
+	
+	bic	r2,r2,#0x80000000
+	orr	r1,r1,r2,lsr#11
+
+	mov	r2,r2,lsl#21
+
+	stmia	r6,{r1-r2}
+	mov	pc,r14
+
+CPDT_store_double_zero:
+	mov	r1,#0
+	mov	r2,#0
+	stmia	r6,{r1-r2}
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_store_extended
+CPDT_store_extended:
+	ldmia	r0,{r1-r3}
+	
+	cmp	r2,#0
+	beq	CPDT_store_extended_zero
+
+	adds	r3,r3,#16384
+	ble	CPDT_store_extended_zero
+	
+	sub	r3,r3,#1
+	mov	r3,r3,lsl#17
+	orr	r1,r1,r3,lsr#17
+
+	mov	r3,#0
+
+	stmia	r6,{r1-r3}
+	mov	pc,r14
+	
+CPDT_store_extended_zero:
+	mov	r1,#0
+	mov	r2,#0
+	mov	r3,#0
+	stmia	r6,{r1-r3}
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_store_decimal
+CPDT_store_decimal:
+
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_sfm
+CPDT_sfm:
+	add	r2,r10,r0,lsr#8
+	ldr	r3,[r2],#4
+	str	r3,[r6],#4
+	ldr	r3,[r2],#4
+	str	r3,[r6],#4
+	ldr	r3,[r2],#4
+	str	r3,[r6],#4
+
+	add	r0,r0,#1<<12
+	and	r0,r0,#7<<12
+	subs	r1,r1,#1
+	bne	CPDT_sfm
+	mov	pc,r14
+	
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPDT_lfm
+CPDT_lfm:
+	add	r2,r10,r0,lsr#8
+	ldr	r3,[r6],#4
+	str	r3,[r2],#4
+	ldr	r3,[r6],#4
+	str	r3,[r2],#4
+	ldr	r3,[r6],#4
+	str	r3,[r2],#4
+
+	add	r0,r0,#1<<12
+	and	r0,r0,#7<<12
+	subs	r1,r1,#1
+	bne	CPDT_lfm
+	mov	pc,r14
+	
+/*---------------------------------------------------------------------------*/
diff -urN linux-2.4.29/arch/armnommu/fastfpe/CPRT.S linux-2.4.29-uc1/arch/armnommu/fastfpe/CPRT.S
--- linux-2.4.29/arch/armnommu/fastfpe/CPRT.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/fastfpe/CPRT.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,149 @@
+/*---------------------------------------------------------------------------*/
+
+	.text
+	.globl	CPRT_flt
+CPRT_flt:
+	add	r0,r13,r0,lsr#10
+	ldr	r3,[r0]
+	cmp	r3,#0
+	beq	CPRT_zero
+	
+	ands	r2,r3,#0x80000000
+	rsbne	r3,r3,#0
+	mov	r4,#31
+	
+	cmp	r3,#0x00010000
+	movcc	r3,r3,lsl#16
+	subcc	r4,r4,#16
+	
+	cmp	r3,#0x01000000
+	movcc	r3,r3,lsl#8
+	subcc	r4,r4,#8
+	
+	cmp	r3,#0x10000000
+	movcc	r3,r3,lsl#4
+	subcc	r4,r4,#4
+	
+	cmp	r3,#0x40000000
+	movcc	r3,r3,lsl#2
+	subcc	r4,r4,#2
+	
+	cmp	r3,#0x80000000
+	movcc	r3,r3,lsl#1
+	subcc	r4,r4,#1
+
+	stmia	r1,{r2,r3,r4}
+	mov	pc,r14
+
+CPRT_zero:
+	mov	r2,#0
+	mov	r3,#0
+	mov	r4,#0x80000000
+	stmia	r1,{r2,r3,r4}
+	mov	pc,r14
+	
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPRT_fix
+CPRT_fix:
+	adr	r5,CPRT_back
+	b	CPDO_rnd_core
+	
+CPRT_back:
+	add	r0,r13,r0,lsr#10
+	cmp	r3,#0
+	blt	CPRT_int_zero
+	cmp	r3,#30
+	bgt	CPRT_overflow
+	
+	rsb	r3,r3,#31
+	mov	r2,r2,lsr r3
+	tst	r1,#0x80000000
+	rsbne	r2,r2,#0
+	
+	str	r2,[r0]
+	mov	pc,r14
+
+CPRT_int_zero:
+	mov	r2,#0
+	str	r2,[r0]
+	mov	pc,r14
+
+CPRT_overflow:
+	mov	r2,#0x80000000
+	tst	r1,#0x80000000
+	subeq	r2,r2,#1
+	str	r2,[r0]
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPRT_wfs
+CPRT_wfs:
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPRT_rfs
+CPRT_rfs:
+	add	r0,r13,r0,lsr#10
+	mov	r1,#0x02000000		@ Software Emulation, not Acorn FPE
+	str	r1,[r0]
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPRT_cmf
+CPRT_cmf:
+	ldmia	r1,{r1,r3,r5}
+	ldmia	r2,{r2,r4,r6}
+
+CPRT_cmf_e:
+	ldr	r0,[r13,#16*4]
+	bic	r0,r0,#0xf0000000
+	
+	cmp	r1,r2
+	beq	CPRT_cmf_equalsign
+	b	CPRT_cmf_sign
+
+CPRT_cmf_equalsign:
+	cmp	r5,r6
+	beq	CPRT_cmf_equalexponent
+	bgt	CPRT_cmf_sign
+	b	CPRT_cmf_signb	
+
+CPRT_cmf_equalexponent:
+	cmp	r3,r4
+	beq	CPRT_cmf_equal
+	bgt	CPRT_cmf_sign
+	b	CPRT_cmf_signb
+
+CPRT_cmf_sign:
+	tst	r1,#0x80000000
+	orreq	r0,r0,#0x20000000
+	orrne	r0,r0,#0x80000000
+	str	r0,[r13,#16*4]
+	mov	pc,r14
+
+CPRT_cmf_signb:
+	tst	r1,#0x80000000
+	orrne	r0,r0,#0x20000000
+	orreq	r0,r0,#0x80000000
+	str	r0,[r13,#16*4] 
+	mov	pc,r14
+
+CPRT_cmf_equal:
+	orr	r0,r0,#0x60000000
+	str	r0,[r13,#16*4]
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+	.globl	CPRT_cnf
+CPRT_cnf:
+	ldmia	r1,{r1,r3,r5}
+	ldmia	r2,{r2,r4,r6}
+	eor	r2,r2,#0x80000000
+	b	CPRT_cmf_e
+
+/*---------------------------------------------------------------------------*/
diff -urN linux-2.4.29/arch/armnommu/fastfpe/entry.S linux-2.4.29-uc1/arch/armnommu/fastfpe/entry.S
--- linux-2.4.29/arch/armnommu/fastfpe/entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/fastfpe/entry.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,308 @@
+/*
+At entry the registers contain the following information:
+
+r14	return address for undefined exception return
+r9	return address for return from exception
+r13	user registers on stack, offset 0 up to offset 4*15 contains
+	registers r0..15, then the psr
+r10	FP workspace 35 words (init, reg[8][4], fpsr, fpcr)
+ 
+*/
+
+/*---------------------------------------------------------------------------*/
+
+	.data
+fp_const:
+	.word	0, 0x00000000, 0x80000000, 0	@ 0
+	.word	0, 0x80000000, 		0, 0	@ 1
+	.word	0, 0x80000000, 		1, 0	@ 2
+	.word	0, 0xc0000000, 		1, 0	@ 3
+	.word	0, 0x80000000, 		2, 0	@ 4
+	.word	0, 0xa0000000, 		2, 0	@ 5
+	.word	0, 0x80000000,	       -1, 0	@ 0.5
+	.word	0, 0xa0000000, 		3, 0	@ 10
+fp_undef:
+	.word	0
+fp_cond:
+	.word	0xf0f0	@ eq
+	.word	0x0f0f	@ ne
+	.word	0xcccc	@ cs
+	.word	0x3333	@ cc
+	.word	0xff00	@ mi
+	.word	0x00ff	@ pl
+	.word	0xaaaa	@ vs
+	.word	0x5555	@ vc
+	.word	0x0c0c	@ hi
+	.word	0xf3f3	@ ls
+	.word	0xaa55	@ ge
+	.word	0x55aa	@ lt
+	.word	0x0a05	@ gt
+	.word	0xf5fa	@ le
+	.word	0xffff	@ al
+	.word	0x0000	@ nv
+	
+/*---------------------------------------------------------------------------*/
+	
+	.text
+	.globl	fastfpe_enter
+fastfpe_enter:
+	ldr	r4,=fp_undef
+	str	r14,[r4]		@ to free one register
+	add	r10,r10,#4		@ to make the code simpler
+	ldr	r4,[r13,#60]		@ r4=saved PC
+	ldr	r4,[r4,#-4]		@ r4=trapped instruction
+	and	r1,r4,#0x00000f00	@ r1=coprocessor << 8
+next_enter:
+	cmp	r1,#1<<8		@ copro 1 ?
+	beq	copro_1
+	cmp	r1,#2<<8
+	movne	pc,r14
+
+copro_2:
+	and	r1,r4,#0x0f000000
+	cmp	r1,#0x0c000000          @ CPDT with post indexing
+        cmpne   r1,#0x0d000000          @ CPDT with pre indexing
+        beq     CPDT_M_enter
+	mov	pc,r14
+
+copro_1:
+	and	r1,r4,#0x0f000000
+	cmp	r1,#0x0e000000		@ CPDO
+	beq	CPDO_CPRT_enter
+	cmp	r1,#0x0c000000		@ CPDT with post indexing
+	cmpne	r1,#0x0d000000		@ CPDT with pre indexing
+	beq	CPDT_1_enter
+	mov	pc,r14
+
+/*---------------------------------------------------------------------------*/
+
+finish:
+	ldr	r5,[r13,#60]
+next_after_cond:
+__x1:
+	ldrt	r4,[r5],#4
+	
+	ldr	r0,=fp_cond		@ check condition of next instruction
+	ldr	r1,[r13,#64]		@ psr containing flags
+	mov	r2,r4,lsr#28
+	mov	r1,r1,lsr#28
+	ldr	r0,[r0,r2,lsl#2]
+	mov	r0,r0,lsr r1
+	tst	r0,#1
+	beq	next_after_cond		@ must not necessarily have been an
+					@ FP instruction !
+	and	r1,r4,#0x0f000000	@ Test for copro instruction
+	cmp	r1,#0x0c000000
+	rsbgts	r0,r1,#0x0e000000	@ cmpgt #0x0e000000,r1
+	movlt	pc,r9			@ next is no copro instruction, return
+	
+	ands	r1,r4,#0x00000f00	@ r1 = coprocessor << 8
+	cmpne	r1,#3<<8
+	movge	pc,r9			@ copro = 0 or >=3, return
+		
+	str	r5,[r13,#60]		@ save updated pc
+	b	next_enter
+
+/*---------------------------------------------------------------------------*/
+
+undefined:
+	ldr	r4,=fp_undef
+	ldr	pc,[r4]	
+
+/*---------------------------------------------------------------------------*/
+
+CPDT_1_enter:
+	and	r5,r4,#0x000f0000	@ r5=base register number << 16
+	ldr	r6,[r13,r5,lsr#14]	@ r6=base address
+	cmp	r5,#0x000f0000		@ base register = pc ?
+	addeq	r6,r6,#4
+	and	r7,r4,#0x000000ff	@ r7=offset value
+
+	tst	r4,#0x00800000		@ up or down?
+	addne	r7,r6,r7,lsl#2
+	subeq	r7,r6,r7,lsl#2		@ r6=base address +/- offset
+	tst	r4,#0x01000000		@ preindexing ?
+	movne	r6,r7
+
+	and	r0,r4,#0x00007000	@ r0=fp register number << 12
+	add	r0,r10,r0,lsr#8		@ r0=address of fp register
+	mov	r1,#0
+	tst	r4,#0x00008000
+	orrne	r1,r1,#1		@ T0
+	tst	r4,#0x00400000
+	orrne	r1,r1,#2		@ T1
+	tst	r4,#0x00100000
+	orrne	r1,r1,#4		@ L/S
+
+	adr	r14,CPDT_1_writeback	@ for being able to "call" something
+	add	pc,pc,r1,lsl#2
+	mov	r0,r0
+	b	CPDT_store_single	@ these functions get 
+	b	CPDT_store_double	@ r0=address of fp register
+	b	CPDT_store_extended	@ r6=address of data
+	b	undefined		@ CPDT_store_decimal	@ and may modify r0-r3
+        b       CPDT_load_single
+        b       CPDT_load_double
+        b       CPDT_load_extended
+        b       undefined		@ CPDT_load_decimal
+
+CPDT_1_writeback:
+	tst	r4,#0x00200000		@ write back ?
+	cmpne	r5,#0x000f0000		@ base register = pc ?
+        beq	finish
+
+	str	r7,[r13,r5,lsr#14]
+	b	finish
+
+/*---------------------------------------------------------------------------*/
+
+CPDT_M_enter:
+	and	r5,r4,#0x000f0000	@ r5=base register number << 16
+	ldr	r6,[r13,r5,lsr#14]	@ r6=base address
+	cmp	r5,#0x000f0000		@ base register = pc ?
+	addeq	r6,r6,#4
+	and	r7,r4,#0x000000ff	@ r7=offset value
+
+	tst	r4,#0x00800000		@ up or down?
+	addne	r7,r6,r7,lsl#2
+	subeq	r7,r6,r7,lsl#2		@ r7=base address +/- offset
+	tst	r4,#0x01000000		@ preindexing ?
+	movne	r6,r7
+
+	and	r0,r4,#0x00007000	@ r0=fp register number << 12
+	and	r1,r4,#0x00008000
+	mov	r1,r1,lsr#15		@ N0
+	and	r2,r4,#0x00400000
+	orrs	r1,r1,r2,lsr#21		@ N1
+	addeq	r1,r1,#4		@ r1=register count
+
+	adr	r14,CPDT_M_writeback	@ for being able to "call" something	
+	tst	r4,#0x00100000		@ load/store
+	beq	CPDT_sfm
+	b	CPDT_lfm
+
+CPDT_M_writeback:
+	tst	r4,#0x00200000		@ write back ?
+	cmpne	r5,#0x000f0000		@ base register = pc ?
+        beq	finish
+
+	str	r7,[r13,r5,lsr#14]
+	b	finish
+
+/*---------------------------------------------------------------------------*/
+
+CPDO_CPRT_enter:
+	tst	r4,#0x00000010
+	bne	CPRT_enter
+	
+	and	r0,r4,#0x00007000
+	add	r0,r10,r0,lsr#8		@ r0=address of Fd
+	and	r1,r4,#0x00070000
+	add	r1,r10,r1,lsr#12	@ r1=address of Fn
+	tst	r4,#0x00000008
+	bne	CPDO_const
+	and	r2,r4,#0x00000007
+	add	r2,r10,r2,lsl#4		@ r2=address of Fm
+	
+CPDO_constback:
+	and	r3,r4,#0x00f00000
+	tst	r4,#0x00008000
+	orrne	r3,r3,#0x01000000
+		
+	adr	r14,finish		@ call return address
+	add	pc,pc,r3,lsr#18
+	mov	r0,r0
+	b	CPDO_adf
+	b	CPDO_muf
+	b	CPDO_suf
+	b	CPDO_rsf
+	b	CPDO_dvf
+	b	CPDO_rdf
+	b	undefined
+	b	undefined
+	b	undefined		@ CPDO_rmf
+	b	CPDO_muf
+	b	CPDO_dvf
+	b	CPDO_rdf
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	CPDO_mvf
+	b	CPDO_mnf
+	b	CPDO_abs
+	b	CPDO_rnd
+	b	CPDO_sqt
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	CPDO_rnd
+	b	finish
+
+CPDO_const:
+	ldr	r2,=fp_const
+	and	r3,r4,#0x00000007
+	add	r2,r2,r3,lsl#4	
+	b	CPDO_constback
+	
+/*---------------------------------------------------------------------------*/
+
+CPRT_enter:
+	and	r0,r4,#0x0000f000	@ r0=Rd<<12
+	and	r1,r4,#0x00070000
+	add	r1,r10,r1,lsr#12	@ r1=address of Fn
+	tst	r4,#0x00000008
+	bne	CPRT_const
+	and	r2,r4,#0x00000007
+	add	r2,r10,r2,lsl#4		@ r2=address of Fm
+	
+CPRT_constback:
+	and	r3,r4,#0x00f00000
+		
+	adr	r14,finish		@ call return address
+	add	pc,pc,r3,lsr#18
+	mov	r0,r0
+	b	CPRT_flt
+	b	CPRT_fix
+	b	CPRT_wfs
+	b	CPRT_rfs
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	undefined
+	b	CPRT_cmf
+	b	undefined
+	b	CPRT_cnf
+	b	undefined
+	b	CPRT_cmf
+	b	undefined
+	b	CPRT_cnf
+
+CPRT_const:
+	ldr	r2,=fp_const
+	and	r3,r4,#0x00000007
+	add	r2,r2,r3,lsl#4	
+	b	CPRT_constback
+	
+/*---------------------------------------------------------------------------*/
+
+	@ The fetch of the next instruction to emulate could fault
+
+	.section .fixup,"ax"
+	.align
+__f1:
+	mov	pc,r9
+	.previous
+	.section __ex_table,"a"
+	.align 3
+	.long	__x1,__f1
+	.previous
+	
+/*---------------------------------------------------------------------------*/
\ No newline at end of file
diff -urN linux-2.4.29/arch/armnommu/fastfpe/Makefile linux-2.4.29-uc1/arch/armnommu/fastfpe/Makefile
--- linux-2.4.29/arch/armnommu/fastfpe/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/fastfpe/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,23 @@
+#
+# linux/arch/arm/fastfpe/Makefile
+#
+# Copyright (C) Peter Teichmann
+#
+
+O_TARGET := fast-math-emu.o
+
+obj-y	:=
+obj-m	:=
+obj-n	:=
+obj-	:=
+
+fastfpe-objs := module.o entry.o CPDO.o CPRT.o CPDT.o
+
+list-multi := fastfpe.o
+
+obj-$(CONFIG_FPE_FASTFPE) += fastfpe.o
+
+include $(TOPDIR)/Rules.make
+
+fastfpe.o: $(fastfpe-objs)
+	 $(LD) -r -o $@ $(fastfpe-objs)
diff -urN linux-2.4.29/arch/armnommu/fastfpe/module.c linux-2.4.29-uc1/arch/armnommu/fastfpe/module.c
--- linux-2.4.29/arch/armnommu/fastfpe/module.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/fastfpe/module.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,78 @@
+/*
+    Fast Floating Point Emulator
+    (c) Peter Teichmann <teich-p@rcs.urz.tu-dresden.de>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#ifndef MODULE
+#define kern_fp_enter	fp_enter
+
+extern char fpe_type[];
+#endif
+
+static void (*orig_fp_enter)(void);	/* old kern_fp_enter value */
+extern void (*kern_fp_enter)(void);	/* current FP handler */
+extern void fastfpe_enter(void);	/* forward declarations */
+
+#ifdef MODULE
+/*
+ * Return 0 if we can be unloaded.  This can only happen if
+ * kern_fp_enter is still pointing at fastfpe_enter
+ */
+static int fpe_unload(void)
+{
+  return (kern_fp_enter == fastfpe_enter) ? 0 : 1;
+}
+#endif
+
+static int __init fpe_init(void)
+{
+#ifdef MODULE
+  if (!mod_member_present(&__this_module, can_unload))
+    return -EINVAL;
+  __this_module.can_unload = fpe_unload;
+#else
+  if (fpe_type[0] && strcmp(fpe_type, "fastfpe"))
+    return 0;
+#endif
+
+  printk("Fast Floating Point Emulator V0.0 (c) Peter Teichmann.\n");
+
+  /* Save pointer to the old FP handler and then patch ourselves in */
+  orig_fp_enter = kern_fp_enter;
+  kern_fp_enter = fastfpe_enter;
+
+  return 0;
+}
+
+static void __exit fpe_exit(void)
+{
+  /* Restore the values we saved earlier. */
+  kern_fp_enter = orig_fp_enter;
+}
+
+module_init(fpe_init);
+module_exit(fpe_exit);
+
+MODULE_AUTHOR("Peter Teichmann <teich-p@rcs.urz.tu-dresden.de>");
+MODULE_DESCRIPTION("Fast floating point emulator");
diff -urN linux-2.4.29/arch/armnommu/kernel/arch.c linux-2.4.29-uc1/arch/armnommu/kernel/arch.c
--- linux-2.4.29/arch/armnommu/kernel/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/arch.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,404 @@
+/*
+ *  linux/arch/armnommu/kernel/arch.c
+ *
+ *  Architecture specific fixups.
+ */
+#include <linux/config.h>
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+
+#include <asm/elf.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/hardware/dec21285.h>
+
+extern void genarch_init_irq(void);
+
+unsigned int vram_size;
+
+#ifdef CONFIG_ARCH_ACORN
+
+unsigned int memc_ctrl_reg;
+unsigned int number_mfm_drives;
+
+static int __init parse_tag_acorn(const struct tag *tag)
+{
+	memc_ctrl_reg = tag->u.acorn.memc_control_reg;
+	number_mfm_drives = tag->u.acorn.adfsdrives;
+
+	switch (tag->u.acorn.vram_pages) {
+	case 512:
+		vram_size += PAGE_SIZE * 256;
+	case 256:
+		vram_size += PAGE_SIZE * 256;
+	default:
+		break;
+	}
+#if 0
+	if (vram_size) {
+		desc->video_start = 0x02000000;
+		desc->video_end   = 0x02000000 + vram_size;
+	}
+#endif
+	return 0;
+}
+
+__tagtable(ATAG_ACORN, parse_tag_acorn);
+
+#ifdef CONFIG_ARCH_RPC
+static void __init
+fixup_riscpc(struct machine_desc *desc, struct param_struct *unusd,
+	    char **cmdline, struct meminfo *mi)
+{
+	/*
+	 * RiscPC can't handle half-word loads and stores
+	 */
+	elf_hwcap &= ~HWCAP_HALF;
+}
+
+extern void __init rpc_map_io(void);
+
+MACHINE_START(RISCPC, "Acorn-RiscPC")
+	MAINTAINER("Russell King")
+	BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
+	BOOT_PARAMS(0x10000100)
+	DISABLE_PARPORT(0)
+	DISABLE_PARPORT(1)
+	FIXUP(fixup_riscpc)
+	MAPIO(rpc_map_io)
+	INITIRQ(genarch_init_irq)
+MACHINE_END
+#endif
+#ifdef CONFIG_ARCH_ARC
+MACHINE_START(ARCHIMEDES, "Acorn-Archimedes")
+	MAINTAINER("Dave Gilbert")
+	BOOT_PARAMS(0x0207c000)
+	INITIRQ(genarch_init_irq)
+MACHINE_END
+#endif
+#ifdef CONFIG_ARCH_A5K
+MACHINE_START(A5K, "Acorn-A5000")
+	MAINTAINER("Russell King")
+	BOOT_PARAMS(0x0207c000)
+	INITIRQ(genarch_init_irq)
+MACHINE_END
+#endif
+#endif
+
+#ifdef CONFIG_ARCH_L7200
+extern void __init l7200_map_io(void);
+
+static void __init
+fixup_l7200(struct machine_desc *desc, struct param_struct *unused,
+             char **cmdline, struct meminfo *mi)
+{
+        mi->nr_banks      = 1;
+        mi->bank[0].start = PHYS_OFFSET;
+        mi->bank[0].size  = (32*1024*1024);
+        mi->bank[0].node  = 0;
+
+        ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+        setup_ramdisk( 1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE);
+        setup_initrd( __phys_to_virt(0xf1000000), 0x005dac7b);
+
+        /* Serial Console COM2 and LCD */
+	strcpy( *cmdline, "console=tty0 console=ttyLU1,115200");
+
+        /* Serial Console COM1 and LCD */
+	//strcpy( *cmdline, "console=tty0 console=ttyLU0,115200");
+
+        /* Console on LCD */
+	//strcpy( *cmdline, "console=tty0");
+}
+
+MACHINE_START(L7200, "LinkUp Systems L7200")
+	MAINTAINER("Steve Hill / Scott McConnell")
+	BOOT_MEM(0xf0000000, 0x80040000, 0xd0000000)
+	FIXUP(fixup_l7200)
+	MAPIO(l7200_map_io)
+	INITIRQ(genarch_init_irq)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_NEXUSPCI
+
+extern void __init nexuspci_map_io(void);
+
+MACHINE_START(NEXUSPCI, "FTV/PCI")
+	MAINTAINER("Philip Blundell")
+	BOOT_MEM(0x40000000, 0x10000000, 0xe0000000)
+	MAPIO(nexuspci_map_io)
+	INITIRQ(genarch_init_irq)
+MACHINE_END
+#endif
+#ifdef CONFIG_ARCH_TBOX
+
+extern void __init tbox_map_io(void);
+
+MACHINE_START(TBOX, "unknown-TBOX")
+	MAINTAINER("Philip Blundell")
+	BOOT_MEM(0x80000000, 0x00400000, 0xe0000000)
+	MAPIO(tbox_map_io)
+	INITIRQ(genarch_init_irq)
+MACHINE_END
+#endif
+#ifdef CONFIG_ARCH_CLPS7110
+MACHINE_START(CLPS7110, "CL-PS7110")
+	MAINTAINER("Werner Almesberger")
+	INITIRQ(genarch_init_irq)
+MACHINE_END
+#endif
+#ifdef CONFIG_ARCH_ETOILE
+MACHINE_START(ETOILE, "Etoile")
+	MAINTAINER("Alex de Vries")
+	INITIRQ(genarch_init_irq)
+MACHINE_END
+#endif
+#ifdef CONFIG_ARCH_LACIE_NAS
+MACHINE_START(LACIE_NAS, "LaCie_NAS")
+	MAINTAINER("Benjamin Herrenschmidt")
+	INITIRQ(genarch_init_irq)
+MACHINE_END
+#endif
+#ifdef CONFIG_ARCH_CLPS7500
+
+extern void __init clps7500_map_io(void);
+
+MACHINE_START(CLPS7500, "CL-PS7500")
+	MAINTAINER("Philip Blundell")
+	BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
+	MAPIO(clps7500_map_io)
+	INITIRQ(genarch_init_irq)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_NETARM
+#include <asm/arch/netarm_registers.h>
+#include <asm/arch/netarm_mmap.h>
+#include <asm/arch/netarm_nvram.h>
+static void __init
+fixup_netarm(struct machine_desc *desc, struct param_struct *params,
+             char **cmdline, struct meminfo *mi)
+{
+	extern void __ramdisk_data, __ramdisk_data_end, _text;
+
+	/* code from 2.0.38 by J.deBlaquiere:  --rp */
+	printk("fixup_netarm: Kernel memory start 0x%08lx end 0x%08lx\n",
+	       (unsigned long)&_text, (unsigned long)&_end_kernel);
+
+#ifdef CONFIG_ETHER_NETARM
+#ifdef CONFIG_NETARM_EEPROM
+	/* copy MAC address from NVRAM to Ethernet controller */
+	{
+		NA_dev_board_params_t *pParams;
+		unsigned int *pUint;
+		unsigned int uItmp;
+		unsigned int serno;
+		unsigned int csum;
+		
+		pParams = (NA_dev_board_params_t *)(NETARM_MMAP_EEPROM_BASE) ;
+		csum = compute_checksum(pParams) ;
+		
+		if (csum == 0)
+		{
+			/* valid checksum... parse chars */
+			int i,j ;
+		
+			serno = 0;
+			for ( i = 0 ; i < 8 ; i++ )
+			{
+				j = parse_decimal(pParams->serialNumber[i]);
+				if (j < 0)
+				{
+					/* invalid digits - pretend csum bad */
+					csum = 1 ;
+					break;
+				}
+				serno *= 10 ;
+				serno += j;
+			}
+		} else {
+			/* (csum != 0): use default serial number */
+			serno = 99335 ;
+		}
+		/* multiply serno by 8 to calc MAC */
+		serno <<= 3 ;
+		
+		uItmp = serno & 0xFF ;
+		uItmp <<= 8 ;
+		uItmp += ( serno >> 8 ) & 0xFF ;
+		pUint = (unsigned int *)get_eth_reg_addr(NETARM_ETH_SAL_STATION_ADDR_3);
+		*pUint = uItmp;
+
+		uItmp = ( serno >> 16 ) & 0xFF ;
+		uItmp <<= 8 ;
+		uItmp += NETARM_OUI_BYTE3 ;
+		pUint = (unsigned int *)get_eth_reg_addr(NETARM_ETH_SAL_STATION_ADDR_2);
+		*pUint = uItmp;
+
+		uItmp = NETARM_OUI_BYTE2 ;
+		uItmp <<= 8 ;
+		uItmp += NETARM_OUI_BYTE1 ;
+		pUint = (unsigned int *)get_eth_reg_addr(NETARM_ETH_SAL_STATION_ADDR_1);
+		*pUint = uItmp;
+	}
+#else
+	/* no EEPROM: generate MAC address from GEN_ID */
+	{
+		unsigned int *pUint;
+		unsigned int uItmp;
+		unsigned int serno;
+		
+		pUint = (unsigned int *)get_gen_reg_addr(NETARM_GEN_STATUS_CONTROL);
+		serno = *pUint & 0x7FF;
+
+		uItmp = serno & 0xFF ;
+		uItmp <<= 8 ;
+		uItmp += ( serno >> 8 ) & 0xFF ;
+		pUint = get_eth_reg_addr(NETARM_ETH_SAL_STATION_ADDR_3);
+		*pUint = uItmp;
+
+		uItmp = ( serno >> 16 ) & 0xFF ;
+		uItmp <<= 8 ;
+		uItmp += NETARM_OUI_BYTE3 ;
+		pUint = get_eth_reg_addr(NETARM_ETH_SAL_STATION_ADDR_2);
+		*pUint = uItmp;
+
+		uItmp = NETARM_OUI_BYTE2 ;
+		uItmp <<= 8 ;
+		uItmp += NETARM_OUI_BYTE1 ;
+		pUint = get_eth_reg_addr(NETARM_ETH_SAL_STATION_ADDR_1);
+		*pUint = uItmp;
+	}
+#endif
+#endif
+
+#ifdef CONFIG_BLK_DEV_RAMDISK_DATA
+	setup_ramdisk(1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE);
+        setup_initrd((int)&__ramdisk_data, 
+	             (int)&__ramdisk_data_end - (int)&__ramdisk_data);
+#endif
+} /* fixup_netarm() */
+
+MACHINE_START(NETARM, "NET+ARM")
+	MAINTAINER("Rolf Peukert")
+	FIXUP(fixup_netarm)
+	BOOT_PARAMS(0x800)
+	INITIRQ(genarch_init_irq)
+MACHINE_END
+#endif
+
+#if defined( CONFIG_ARCH_TA7S ) || defined( CONFIG_ARCH_TA7V )
+#include <asm/arch/arch.h>
+
+#ifdef CONFIG_BLK_DEV_RAMDISK_DATA
+extern void __ramdisk_data, __ramdisk_data_end;
+#endif
+
+extern void _text;
+
+static void __init
+fixup_ta7(struct machine_desc *desc, struct param_struct *params,
+             char **cmdline, struct meminfo *mi)
+{
+	ta7_arch_init();
+
+#ifdef CONFIG_BLK_DEV_RAMDISK_DATA
+	strcpy( *cmdline, "root=/dev/ram rw");
+	setup_ramdisk(1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE);
+        setup_initrd((int)&__ramdisk_data, 
+	             (int)&__ramdisk_data_end - (int)&__ramdisk_data);
+#endif
+} /* fixup_ta7s() */
+
+#if defined(CONFIG_ARCH_TA7S)
+MACHINE_START(TA7S, "Triscend-A7S")
+	MAINTAINER("Craig Hackney (craig@triscend.com)")
+	FIXUP(fixup_ta7)
+	INITIRQ(genarch_init_irq)
+MACHINE_END
+#elif defined(CONFIG_ARCH_TA7V)
+MACHINE_START(TA7V, "Triscend-A7V")
+	MAINTAINER("Craig Hackney (craig@triscend.com)")
+	FIXUP(fixup_ta7)
+	INITIRQ(genarch_init_irq)
+MACHINE_END
+#endif
+
+
+#endif
+
+
+
+#ifdef CONFIG_ARCH_SWARM
+
+static void __init
+fixup_swarm(struct machine_desc *desc, struct param_struct *params,
+             char **cmdline, struct meminfo *mi)
+{
+	
+	printk("ARM for SWARM by C Hanish Menon [www.hanishkvc.com] - 9 Sep 2001 \n");				
+	mi->nr_banks      = 1;
+	/* Note: PHYS_OFFSET set to start after the kernel code and data */
+	mi->bank[0].start = PHYS_OFFSET; 
+	mi->bank[0].size  = (10*1024*1024);
+	mi->bank[0].node  = 0;
+				
+#if 0
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+	setup_ramdisk( 1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE);
+	/* Initial ramdisk in the last 2 MB of Memory */
+	setup_initrd( __phys_to_virt(0x00800000), 0x00200000);
+#endif
+
+	/* Serial Console COM2 and LCD */
+	strcpy( *cmdline, "console=tty0");
+
+}
+
+MACHINE_START(SWARM, "SWARM")
+	MAINTAINER("C Hanish Menon [www.hanishkvc.com]")
+	BOOT_MEM(0x00000000, 0x90000000, 0x90000000)
+	FIXUP(fixup_swarm)
+	INITIRQ(genarch_init_irq)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_VC547X
+#include <linux/sched.h>       /* For union task_union */
+#include <linux/personality.h> /* For PER_LINUX_32BIT */
+
+extern long C5471tags;
+
+static void __init
+fixup_c5471(struct machine_desc *desc, struct param_struct *params,
+            char **cmdline, struct meminfo *mi)
+{
+	struct tag *t = (struct param_struct *)C5471tags;
+
+  /* This is probably not necessary for the init process. But, all
+   * normal C5471 processes must be marked as 32-bit processes. */
+
+  init_task_union.task.personality = PER_LINUX_32BIT;
+
+	for (; t->hdr.size; t = tag_next(t)) 
+	{
+		if (t->hdr.tag == ATAG_CMDLINE)
+		{
+			strncpy(*cmdline, t->u.cmdline.cmdline, COMMAND_LINE_SIZE);
+			*cmdline[COMMAND_LINE_SIZE - 1] = '\0';
+		}
+	}
+}
+
+MACHINE_START(VC547X, "VC547X")
+        MAINTAINER("Todd Fischer <todd.fischer@cadenux.com>")
+        FIXUP(fixup_c5471)
+        INITIRQ(genarch_init_irq)
+MACHINE_END
+#endif
diff -urN linux-2.4.29/arch/armnommu/kernel/armksyms.c linux-2.4.29-uc1/arch/armnommu/kernel/armksyms.c
--- linux-2.4.29/arch/armnommu/kernel/armksyms.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/armksyms.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,255 @@
+/*
+ *  linux/arch/arm/kernel/armksyms.c
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/user.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+#include <linux/vt_kern.h>
+
+#include <asm/byteorder.h>
+#include <asm/elf.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pgalloc.h>
+#include <asm/proc-fns.h>
+#include <asm/processor.h>
+#include <asm/semaphore.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/checksum.h>
+#include <asm/mach-types.h>
+
+extern void dump_thread(struct pt_regs *, struct user *);
+extern int dump_fpu(struct pt_regs *, struct user_fp_struct *);
+extern void inswb(unsigned int port, void *to, int len);
+extern void outswb(unsigned int port, const void *to, int len);
+
+extern void __bad_xchg(volatile void *ptr, int size);
+
+/*
+ * syscalls
+ */
+extern int sys_write(int, const char *, int);
+extern int sys_read(int, char *, int);
+extern int sys_lseek(int, off_t, int);
+extern int sys_exit(int);
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler...  (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __gcc_bcmp(void);
+extern void __ashldi3(void);
+extern void __ashrdi3(void);
+extern void __cmpdi2(void);
+extern void __divdi3(void);
+extern void __divsi3(void);
+extern void __lshrdi3(void);
+extern void __moddi3(void);
+extern void __modsi3(void);
+extern void __muldi3(void);
+extern void __negdi2(void);
+extern void __ucmpdi2(void);
+extern void __udivdi3(void);
+extern void __udivmoddi4(void);
+extern void __udivsi3(void);
+extern void __umoddi3(void);
+extern void __umodsi3(void);
+
+extern void ret_from_exception(void);
+extern void fpundefinstr(void);
+extern void fp_enter(void);
+
+#define EXPORT_SYMBOL_ALIAS(sym,orig)		\
+ const char __kstrtab_##sym##[]			\
+  __attribute__((section(".kstrtab"))) =	\
+    __MODULE_STRING(sym);			\
+ const struct module_symbol __ksymtab_##sym	\
+  __attribute__((section("__ksymtab"))) =	\
+    { (unsigned long)&##orig, __kstrtab_##sym };
+
+/*
+ * floating point math emulator support.
+ * These symbols will never change their calling convention...
+ */
+EXPORT_SYMBOL_ALIAS(kern_fp_enter,fp_enter);
+EXPORT_SYMBOL_ALIAS(fp_printk,printk);
+EXPORT_SYMBOL_ALIAS(fp_send_sig,send_sig);
+
+#ifdef CONFIG_CPU_26
+EXPORT_SYMBOL(fpundefinstr);
+EXPORT_SYMBOL(ret_from_exception);
+#endif
+
+#ifdef CONFIG_VT
+EXPORT_SYMBOL(kd_mksound);
+#endif
+
+	/* platform dependent support */
+EXPORT_SYMBOL(dump_thread);
+EXPORT_SYMBOL(dump_fpu);
+EXPORT_SYMBOL(udelay);
+#ifdef CONFIG_CPU_32
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(__iounmap);
+#endif
+EXPORT_SYMBOL(kernel_thread);
+EXPORT_SYMBOL(system_rev);
+EXPORT_SYMBOL(system_serial_low);
+EXPORT_SYMBOL(system_serial_high);
+EXPORT_SYMBOL(__bug);
+EXPORT_SYMBOL(__bad_xchg);
+EXPORT_SYMBOL(__readwrite_bug);
+EXPORT_SYMBOL(enable_irq);
+EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(pm_idle);
+EXPORT_SYMBOL(pm_power_off);
+
+	/* processor dependencies */
+EXPORT_SYMBOL(__machine_arch_type);
+
+	/* networking */
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
+EXPORT_SYMBOL(__csum_ipv6_magic);
+
+	/* io */
+#ifndef __raw_readsb
+EXPORT_SYMBOL_NOVERS(__raw_readsb);
+#endif
+#ifndef __raw_readsw
+EXPORT_SYMBOL_NOVERS(__raw_readsw);
+#endif
+#ifndef __raw_readsl
+EXPORT_SYMBOL_NOVERS(__raw_readsl);
+#endif
+#ifndef __raw_writesb
+EXPORT_SYMBOL_NOVERS(__raw_writesb);
+#endif
+#ifndef __raw_writesw
+EXPORT_SYMBOL_NOVERS(__raw_writesw);
+#endif
+#ifndef __raw_writesl
+EXPORT_SYMBOL_NOVERS(__raw_writesl);
+#endif
+
+	/* address translation */
+#ifndef __virt_to_phys__is_a_macro
+EXPORT_SYMBOL(__virt_to_phys);
+#endif
+#ifndef __phys_to_virt__is_a_macro
+EXPORT_SYMBOL(__phys_to_virt);
+#endif
+#ifndef __virt_to_bus__is_a_macro
+EXPORT_SYMBOL(__virt_to_bus);
+#endif
+#ifndef __bus_to_virt__is_a_macro
+EXPORT_SYMBOL(__bus_to_virt);
+#endif
+
+#ifndef CONFIG_NO_PGT_CACHE
+EXPORT_SYMBOL(quicklists);
+#endif
+
+	/* string / mem functions */
+EXPORT_SYMBOL_NOVERS(strcpy);
+EXPORT_SYMBOL_NOVERS(strncpy);
+EXPORT_SYMBOL_NOVERS(strcat);
+EXPORT_SYMBOL_NOVERS(strncat);
+EXPORT_SYMBOL_NOVERS(strcmp);
+EXPORT_SYMBOL_NOVERS(strncmp);
+EXPORT_SYMBOL_NOVERS(strchr);
+EXPORT_SYMBOL_NOVERS(strlen);
+EXPORT_SYMBOL_NOVERS(strnlen);
+EXPORT_SYMBOL_NOVERS(strpbrk);
+EXPORT_SYMBOL_NOVERS(strtok);
+EXPORT_SYMBOL_NOVERS(strrchr);
+EXPORT_SYMBOL_NOVERS(strstr);
+EXPORT_SYMBOL_NOVERS(memset);
+EXPORT_SYMBOL_NOVERS(memcpy);
+EXPORT_SYMBOL_NOVERS(memmove);
+EXPORT_SYMBOL_NOVERS(memcmp);
+EXPORT_SYMBOL_NOVERS(memscan);
+EXPORT_SYMBOL_NOVERS(__memzero);
+
+	/* user mem (segment) */
+#if defined(CONFIG_CPU_32)
+EXPORT_SYMBOL(__arch_copy_from_user);
+EXPORT_SYMBOL(__arch_copy_to_user);
+EXPORT_SYMBOL(__arch_clear_user);
+EXPORT_SYMBOL(__arch_strnlen_user);
+
+	/* consistent area handling */
+EXPORT_SYMBOL(pci_alloc_consistent);
+EXPORT_SYMBOL(consistent_alloc);
+EXPORT_SYMBOL(consistent_free);
+EXPORT_SYMBOL(consistent_sync);
+
+#elif defined(CONFIG_CPU_26)
+EXPORT_SYMBOL(uaccess_kernel);
+EXPORT_SYMBOL(uaccess_user);
+#endif
+
+	/* gcc lib functions */
+EXPORT_SYMBOL_NOVERS(__gcc_bcmp);
+EXPORT_SYMBOL_NOVERS(__ashldi3);
+EXPORT_SYMBOL_NOVERS(__ashrdi3);
+EXPORT_SYMBOL_NOVERS(__cmpdi2);
+EXPORT_SYMBOL_NOVERS(__divdi3);
+EXPORT_SYMBOL_NOVERS(__divsi3);
+EXPORT_SYMBOL_NOVERS(__lshrdi3);
+EXPORT_SYMBOL_NOVERS(__moddi3);
+EXPORT_SYMBOL_NOVERS(__modsi3);
+EXPORT_SYMBOL_NOVERS(__muldi3);
+EXPORT_SYMBOL_NOVERS(__negdi2);
+EXPORT_SYMBOL_NOVERS(__ucmpdi2);
+EXPORT_SYMBOL_NOVERS(__udivdi3);
+EXPORT_SYMBOL_NOVERS(__udivmoddi4);
+EXPORT_SYMBOL_NOVERS(__udivsi3);
+EXPORT_SYMBOL_NOVERS(__umoddi3);
+EXPORT_SYMBOL_NOVERS(__umodsi3);
+
+	/* bitops */
+EXPORT_SYMBOL(set_bit);
+EXPORT_SYMBOL(test_and_set_bit);
+EXPORT_SYMBOL(clear_bit);
+EXPORT_SYMBOL(test_and_clear_bit);
+EXPORT_SYMBOL(change_bit);
+EXPORT_SYMBOL(test_and_change_bit);
+EXPORT_SYMBOL(find_first_zero_bit);
+EXPORT_SYMBOL(find_next_zero_bit);
+
+	/* elf */
+EXPORT_SYMBOL(elf_platform);
+EXPORT_SYMBOL(elf_hwcap);
+
+	/* syscalls */
+EXPORT_SYMBOL(sys_write);
+EXPORT_SYMBOL(sys_read);
+EXPORT_SYMBOL(sys_lseek);
+EXPORT_SYMBOL(sys_open);
+EXPORT_SYMBOL(sys_exit);
+EXPORT_SYMBOL(sys_wait4);
+
+	/* semaphores */
+EXPORT_SYMBOL_NOVERS(__down_failed);
+EXPORT_SYMBOL_NOVERS(__down_interruptible_failed);
+EXPORT_SYMBOL_NOVERS(__down_trylock_failed);
+EXPORT_SYMBOL_NOVERS(__up_wakeup);
+
+EXPORT_SYMBOL(get_wchan);
diff -urN linux-2.4.29/arch/armnommu/kernel/arthur.c linux-2.4.29-uc1/arch/armnommu/kernel/arthur.c
--- linux-2.4.29/arch/armnommu/kernel/arthur.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/arthur.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,92 @@
+/*
+ *  linux/arch/arm/kernel/arthur.c
+ *
+ *  Copyright (C) 1998, 1999, 2000 Philip Blundell
+ *
+ * Arthur personality
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/personality.h>
+#include <linux/stddef.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+
+/* Arthur doesn't have many signals, and a lot of those that it does
+   have don't map easily to any Linux equivalent.  Never mind.  */
+
+#define ARTHUR_SIGABRT		1
+#define ARTHUR_SIGFPE		2
+#define ARTHUR_SIGILL		3
+#define ARTHUR_SIGINT		4
+#define ARTHUR_SIGSEGV		5
+#define ARTHUR_SIGTERM		6
+#define ARTHUR_SIGSTAK		7
+#define ARTHUR_SIGUSR1		8
+#define ARTHUR_SIGUSR2		9
+#define ARTHUR_SIGOSERROR	10
+
+static unsigned long arthur_to_linux_signals[32] = {
+	0,	1,	2,	3,	4,	5,	6,	7,
+	8,	9,	10,	11,	12,	13,	14,	15,
+	16,	17,	18,	19,	20,	21,	22,	23,
+	24,	25,	26,	27,	28,	29,	30,	31
+};
+
+static unsigned long linux_to_arthur_signals[32] = {
+	0,		-1,		ARTHUR_SIGINT,	-1,
+       	ARTHUR_SIGILL,	5,		ARTHUR_SIGABRT,	7,
+	ARTHUR_SIGFPE,	9,		ARTHUR_SIGUSR1,	ARTHUR_SIGSEGV,	
+	ARTHUR_SIGUSR2,	13,		14,		ARTHUR_SIGTERM,
+	16,		17,		18,		19,
+	20,		21,		22,		23,
+	24,		25,		26,		27,
+	28,		29,		30,		31
+};
+
+static void arthur_lcall7(int nr, struct pt_regs *regs)
+{
+	struct siginfo info;
+	info.si_signo = SIGSWI;
+	info.si_code = nr;
+	/* Bounce it to the emulator */
+	send_sig_info(SIGSWI, &info, current);
+}
+
+static struct exec_domain arthur_exec_domain = {
+	"Arthur",	/* name */
+	(lcall7_func)arthur_lcall7,
+	PER_RISCOS, PER_RISCOS,
+	arthur_to_linux_signals,
+	linux_to_arthur_signals,
+	THIS_MODULE,
+	NULL		/* Nothing after this in the list. */
+};
+
+/*
+ * We could do with some locking to stop Arthur being removed while
+ * processes are using it.
+ */
+
+int __init arthur_init(void)
+{
+	return register_exec_domain(&arthur_exec_domain);
+}
+
+void __exit arthur_exit(void)
+{
+	unregister_exec_domain(&arthur_exec_domain);
+}
+
+module_init(arthur_init);
+module_exit(arthur_exit);
diff -urN linux-2.4.29/arch/armnommu/kernel/bios32.c linux-2.4.29-uc1/arch/armnommu/kernel/bios32.c
--- linux-2.4.29/arch/armnommu/kernel/bios32.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/bios32.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,591 @@
+/*
+ *  linux/arch/arm/kernel/bios32.c
+ *
+ *  PCI bios-type initialisation for PCI machines
+ *
+ *  Bits taken from various places.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+#include <asm/page.h> /* for BUG() */
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/pci.h>
+
+static int debug_pci;
+int have_isa_bridge;
+
+struct pci_sys_data {
+	/*
+	 * The hardware we are attached to
+	 */
+	struct hw_pci	*hw;
+
+	unsigned long	mem_offset;
+
+	/*
+	 * These are the resources for the root bus.
+	 */
+	struct resource *resource[3];
+};
+
+void pcibios_report_status(u_int status_mask, int warn)
+{
+	struct pci_dev *dev;
+
+	pci_for_each_dev(dev) {
+		u16 status;
+
+		/*
+		 * ignore host bridge - we handle
+		 * that separately
+		 */
+		if (dev->bus->number == 0 && dev->devfn == 0)
+			continue;
+
+		pci_read_config_word(dev, PCI_STATUS, &status);
+
+		status &= status_mask;
+		if (status == 0)
+			continue;
+
+		/* clear the status errors */
+		pci_write_config_word(dev, PCI_STATUS, status);
+
+		if (warn)
+			printk("(%02x:%02x.%d: %04X) ", dev->bus->number,
+				PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
+				status);
+	}
+}
+
+/*
+ * We don't use this to fix the device, but initialisation of it.
+ * It's not the correct use for this, but it works.
+ * Note that the arbiter/ISA bridge appears to be buggy, specifically in
+ * the following area:
+ * 1. park on CPU
+ * 2. ISA bridge ping-pong
+ * 3. ISA bridge master handling of target RETRY
+ *
+ * Bug 3 is responsible for the sound DMA grinding to a halt.  We now
+ * live with bug 2.
+ */
+static void __init pci_fixup_83c553(struct pci_dev *dev)
+{
+	/*
+	 * Set memory region to start at address 0, and enable IO
+	 */
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_SPACE_MEMORY);
+	pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_IO);
+
+	dev->resource[0].end -= dev->resource[0].start;
+	dev->resource[0].start = 0;
+
+	/*
+	 * All memory requests from ISA to be channelled to PCI
+	 */
+	pci_write_config_byte(dev, 0x48, 0xff);
+
+	/*
+	 * Enable ping-pong on bus master to ISA bridge transactions.
+	 * This improves the sound DMA substantially.  The fixed
+	 * priority arbiter also helps (see below).
+	 */
+	pci_write_config_byte(dev, 0x42, 0x01);
+
+	/*
+	 * Enable PCI retry
+	 */
+	pci_write_config_byte(dev, 0x40, 0x22);
+
+	/*
+	 * We used to set the arbiter to "park on last master" (bit
+	 * 1 set), but unfortunately the CyberPro does not park the
+	 * bus.  We must therefore park on CPU.  Unfortunately, this
+	 * may trigger yet another bug in the 553.
+	 */
+	pci_write_config_byte(dev, 0x83, 0x02);
+
+	/*
+	 * Make the ISA DMA request lowest priority, and disable
+	 * rotating priorities completely.
+	 */
+	pci_write_config_byte(dev, 0x80, 0x11);
+	pci_write_config_byte(dev, 0x81, 0x00);
+
+	/*
+	 * Route INTA input to IRQ 11, and set IRQ11 to be level
+	 * sensitive.
+	 */
+	pci_write_config_word(dev, 0x44, 0xb000);
+	outb(0x08, 0x4d1);
+}
+
+static void __init pci_fixup_unassign(struct pci_dev *dev)
+{
+	dev->resource[0].end -= dev->resource[0].start;
+	dev->resource[0].start = 0;
+}
+
+/*
+ * Prevent the PCI layer from seeing the resources allocated to this device
+ * if it is the host bridge by marking it as such.  These resources are of
+ * no consequence to the PCI layer (they are handled elsewhere).
+ */
+static void __init pci_fixup_dec21285(struct pci_dev *dev)
+{
+	int i;
+
+	if (dev->devfn == 0) {
+		dev->class &= 0xff;
+		dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			dev->resource[i].start = 0;
+			dev->resource[i].end   = 0;
+			dev->resource[i].flags = 0;
+		}
+	}
+}
+
+/*
+ * PCI IDE controllers use non-standard I/O port
+ * decoding, respect it.
+ */
+static void __init pci_fixup_ide_bases(struct pci_dev *dev)
+{
+	struct resource *r;
+	int i;
+
+	if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
+		return;
+
+	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+		r = dev->resource + i;
+		if ((r->start & ~0x80) == 0x374) {
+			r->start |= 2;
+			r->end = r->start;
+		}
+	}
+}
+
+/*
+ * Put the DEC21142 to sleep
+ */
+static void __init pci_fixup_dec21142(struct pci_dev *dev)
+{
+	pci_write_config_dword(dev, 0x40, 0x80000000);
+}
+
+struct pci_fixup pcibios_fixups[] = {
+	{
+		PCI_FIXUP_HEADER,
+		PCI_VENDOR_ID_DEC,	PCI_DEVICE_ID_DEC_21285,
+		pci_fixup_dec21285
+	}, {
+		PCI_FIXUP_HEADER,
+		PCI_VENDOR_ID_WINBOND,	PCI_DEVICE_ID_WINBOND_83C553,
+		pci_fixup_83c553
+	}, {
+		PCI_FIXUP_HEADER,
+		PCI_VENDOR_ID_WINBOND2,	PCI_DEVICE_ID_WINBOND2_89C940F,
+		pci_fixup_unassign
+	}, {
+		PCI_FIXUP_HEADER,
+		PCI_ANY_ID,		PCI_ANY_ID,
+		pci_fixup_ide_bases
+	}, {
+		PCI_FIXUP_HEADER,
+		PCI_VENDOR_ID_DEC,	PCI_DEVICE_ID_DEC_21142,
+		pci_fixup_dec21142
+	}, { 0 }
+};
+
+void __init
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			struct resource *res, int resource)
+{
+	struct pci_sys_data *sys = dev->sysdata;
+	u32 val, check;
+	int reg;
+
+#ifdef CONFIG_ARCH_ISL3893
+	return;
+#endif
+
+	if (debug_pci)
+		printk("PCI: Assigning %3s %08lx to %s\n",
+			res->flags & IORESOURCE_IO ? "IO" : "MEM",
+			res->start, dev->name);
+
+	if (resource < 6) {
+		reg = PCI_BASE_ADDRESS_0 + 4*resource;
+	} else if (resource == PCI_ROM_RESOURCE) {
+		reg = dev->rom_base_reg;
+	} else {
+		/* Somebody might have asked allocation of a
+		 * non-standard resource.
+		 */
+		return;
+	}
+
+	val = res->start;
+	if (res->flags & IORESOURCE_MEM)
+		val -= sys->mem_offset;
+	val |= res->flags & PCI_REGION_FLAG_MASK;
+
+	pci_write_config_dword(dev, reg, val);
+	pci_read_config_dword(dev, reg, &check);
+	if ((val ^ check) & ((val & PCI_BASE_ADDRESS_SPACE_IO) ?
+	    PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
+		printk(KERN_ERR "PCI: Error while updating region "
+			"%s/%d (%08x != %08x)\n", dev->slot_name,
+			resource, val, check);
+	}
+}
+
+void __init pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+	if (debug_pci)
+		printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name);
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
+
+/*
+ * If the bus contains any of these devices, then we must not turn on
+ * parity checking of any kind.  Currently this is CyberPro 20x0 only.
+ */
+static inline int pdev_bad_for_parity(struct pci_dev *dev)
+{
+	return (dev->vendor == PCI_VENDOR_ID_INTERG &&
+		(dev->device == PCI_DEVICE_ID_INTERG_2000 ||
+		 dev->device == PCI_DEVICE_ID_INTERG_2010));
+}
+
+/*
+ * Adjust the device resources from bus-centric to Linux-centric.
+ */
+static void __init
+pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev)
+{
+	int i;
+
+	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+		if (dev->resource[i].start == 0)
+			continue;
+		if (dev->resource[i].flags & IORESOURCE_MEM) {
+			dev->resource[i].start += root->mem_offset;
+			dev->resource[i].end   += root->mem_offset;
+		}
+	}
+}
+
+static void __init
+pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root)
+{
+	struct pci_dev *dev = bus->self;
+	int i;
+
+	if (dev) {
+		for (i = 0; i < 3; i++) {
+			if(root->resource[i]) {
+				bus->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
+				bus->resource[i]->end  = root->resource[i]->end;
+				bus->resource[i]->name = bus->name;
+			}
+		}
+		bus->resource[0]->flags |= pci_bridge_check_io(dev);
+		bus->resource[1]->flags |= IORESOURCE_MEM;
+
+		if (root->resource[2])
+			bus->resource[2]->flags = root->resource[2]->flags;
+		else {
+			/* no prefetchable memory region - disable it */
+			bus->resource[2]->start = 1024*1024;
+			bus->resource[2]->end   = bus->resource[2]->start - 1;
+		}
+	} else {
+		/*
+		 * Assign root bus resources.
+		 */
+		for (i = 0; i < 3; i++)
+			bus->resource[i] = root->resource[i];
+	}
+}
+
+/*
+ * pcibios_fixup_bus - Called after each bus is probed,
+ * but before its children are examined.
+ */
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct pci_sys_data *root = bus->sysdata;
+	struct list_head *walk;
+	u16 features = PCI_COMMAND_SERR | PCI_COMMAND_PARITY;
+	u16 all_status = -1;
+
+	pbus_assign_bus_resources(bus, root);
+
+	/*
+	 * Walk the devices on this bus, working out what we can
+	 * and can't support.
+	 */
+	for (walk = bus->devices.next; walk != &bus->devices; walk = walk->next) {
+		struct pci_dev *dev = pci_dev_b(walk);
+		u16 status;
+
+#ifndef CONFIG_ARCH_ISL3893
+		pdev_fixup_device_resources(root, dev);
+#endif
+
+		pci_read_config_word(dev, PCI_STATUS, &status);
+		all_status &= status;
+
+		if (pdev_bad_for_parity(dev))
+			features &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+
+		/*
+		 * If this device is an ISA bridge, set the have_isa_bridge
+		 * flag.  We will then go looking for things like keyboard,
+		 * etc
+		 */
+		if (dev->class >> 8 == PCI_CLASS_BRIDGE_ISA ||
+		    dev->class >> 8 == PCI_CLASS_BRIDGE_EISA)
+			have_isa_bridge = !0;
+	}
+
+	/*
+	 * If any device on this bus does not support fast back to back
+	 * transfers, then the bus as a whole is not able to support them.
+	 * Having fast back to back transfers on saves us one PCI cycle
+	 * per transaction.
+	 */
+	if (all_status & PCI_STATUS_FAST_BACK)
+		features |= PCI_COMMAND_FAST_BACK;
+
+	/*
+	 * Now walk the devices again, this time setting them up.
+	 */
+	for (walk = bus->devices.next; walk != &bus->devices; walk = walk->next) {
+		struct pci_dev *dev = pci_dev_b(walk);
+		u16 cmd;
+
+#ifndef CONFIG_ARCH_ISL3893
+		pci_read_config_word(dev, PCI_COMMAND, &cmd);
+		cmd |= features;
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+#endif
+	}
+
+	/*
+	 * Report what we did for this bus
+	 */
+	printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n",
+		bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
+}
+
+/*
+ * Convert from Linux-centric to bus-centric addresses for bridge devices.
+ */
+void __init
+pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
+{
+	struct pci_sys_data *root = bus->sysdata;
+
+	ranges->mem_start -= root->mem_offset;
+	ranges->mem_end -= root->mem_offset;
+	ranges->prefetch_start -= root->mem_offset;
+	ranges->prefetch_end -= root->mem_offset;
+}
+
+u8 __init no_swizzle(struct pci_dev *dev, u8 *pin)
+{
+	return 0;
+}
+
+extern struct hw_pci ebsa285_pci;
+extern struct hw_pci cats_pci;
+extern struct hw_pci netwinder_pci;
+extern struct hw_pci personal_server_pci;
+extern struct hw_pci ftv_pci;
+extern struct hw_pci shark_pci;
+extern struct hw_pci integrator_pci;
+extern struct hw_pci isl38xx_pci;
+
+void __init pcibios_init(void)
+{
+	struct pci_sys_data *root;
+	struct hw_pci *hw = NULL;
+
+	do {
+#ifdef CONFIG_ARCH_EBSA285
+		if (machine_is_ebsa285()) {
+			hw = &ebsa285_pci;
+			break;
+		}
+#endif
+#ifdef CONFIG_ARCH_SHARK
+		if (machine_is_shark()) {
+			hw = &shark_pci;
+			break;
+		}
+#endif
+#ifdef CONFIG_ARCH_CATS
+		if (machine_is_cats()) {
+			hw = &cats_pci;
+			break;
+		}
+#endif
+#ifdef CONFIG_ARCH_NETWINDER
+		if (machine_is_netwinder()) {
+			hw = &netwinder_pci;
+			break;
+		}
+#endif
+#ifdef CONFIG_ARCH_PERSONAL_SERVER
+		if (machine_is_personal_server()) {
+			hw = &personal_server_pci;
+			break;
+		}
+#endif
+#ifdef CONFIG_ARCH_FTVPCI
+		if (machine_is_ftvpci()) {
+			hw = &ftv_pci;
+			break;
+		}
+#endif
+#ifdef CONFIG_ARCH_INTEGRATOR
+		if (machine_is_integrator()) {
+			hw = &integrator_pci;
+			break;
+		}
+#endif
+#ifdef CONFIG_ARCH_POLDHU
+		if (machine_is_poldhu()) {
+			hw = &isl38xx_pci;
+			break;
+		}
+#endif
+#ifdef CONFIG_ARCH_ISL3893
+		if (machine_is_isl3893()) {
+			hw = &isl38xx_pci;
+			break;
+		}
+#endif
+	} while (0);
+
+	if (hw == NULL)
+		return;
+
+	root = kmalloc(sizeof(*root), GFP_KERNEL);
+	if (!root)
+		panic("PCI: unable to allocate root data!");
+
+	root->hw = hw;
+	root->mem_offset = hw->mem_offset;
+
+	memset(root->resource, 0, sizeof(root->resource));
+
+	/*
+	 * Setup the resources for this bus.
+	 *   resource[0] - IO ports
+	 *   resource[1] - non-prefetchable memory
+	 *   resource[2] - prefetchable memory
+	 */
+	if (root->hw->setup_resources)
+		root->hw->setup_resources(root->resource);
+	else {
+		root->resource[0] = &ioport_resource;
+		root->resource[1] = &iomem_resource;
+		root->resource[2] = NULL;
+	}
+
+	/*
+	 * Set up the host bridge, and scan the bus.
+	 */
+	root->hw->init(root);
+
+	/*
+	 * Assign any unassigned resources.
+	 */
+	pci_assign_unassigned_resources();
+	pci_fixup_irqs(root->hw->swizzle, root->hw->map_irq);
+}
+
+char * __init pcibios_setup(char *str)
+{
+	if (!strcmp(str, "debug")) {
+		debug_pci = 1;
+		return NULL;
+	}
+	return str;
+}
+
+/*
+ * From arch/i386/kernel/pci-i386.c:
+ *
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ *
+ * Why? Because some silly external IO cards only decode
+ * the low 10 bits of the IO address. The 0x00-0xff region
+ * is reserved for motherboard devices that decode all 16
+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+ * but we want to try to avoid allocating at 0x2900-0x2bff
+ * which might be mirrored at 0x0100-0x03ff..
+ */
+void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		if (start & 0x300)
+			res->start = (start + 0x3ff) & ~0x3ff;
+	}
+}
+
+/**
+ * pcibios_set_master - Setup device for bus mastering.
+ * @dev: PCI device to be setup
+ */
+void pcibios_set_master(struct pci_dev *dev)
+{
+}
+
+/**
+ * pcibios_enable_device - Enable I/O and memory.
+ * @dev: PCI device to be enabled
+ */
+int pcibios_enable_device(struct pci_dev *dev)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for (idx = 0; idx < 6; idx++) {
+		r = dev->resource + idx;
+		if (!r->start && r->end) {
+			printk(KERN_ERR "PCI: Device %s not available because"
+			       " of resource collisions\n", dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (cmd != old_cmd) {
+		printk("PCI: enabling device %s (%04x -> %04x)\n",
+		       dev->slot_name, old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/calls.S linux-2.4.29-uc1/arch/armnommu/kernel/calls.S
--- linux-2.4.29/arch/armnommu/kernel/calls.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/calls.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,244 @@
+/*
+ *  linux/arch/arm/lib/calls.h
+ *
+ *  Copyright (C) 1995-1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  This file is included twice in entry-common.S
+ */
+#ifndef NR_syscalls
+#define NR_syscalls 256
+#else
+
+__syscall_start:
+/* 0 */		.long	SYMBOL_NAME(sys_ni_syscall)
+		.long	SYMBOL_NAME(sys_exit)
+		.long	SYMBOL_NAME(sys_fork_wrapper)
+		.long	SYMBOL_NAME(sys_read)
+		.long	SYMBOL_NAME(sys_write)
+/* 5 */		.long	SYMBOL_NAME(sys_open)
+		.long	SYMBOL_NAME(sys_close)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_waitpid */
+		.long	SYMBOL_NAME(sys_creat)
+		.long	SYMBOL_NAME(sys_link)
+/* 10 */	.long	SYMBOL_NAME(sys_unlink)
+		.long	SYMBOL_NAME(sys_execve_wrapper)
+		.long	SYMBOL_NAME(sys_chdir)
+		.long	SYMBOL_NAME(sys_time)			/* used by libc4 */
+		.long	SYMBOL_NAME(sys_mknod)
+/* 15 */	.long	SYMBOL_NAME(sys_chmod)
+		.long	SYMBOL_NAME(sys_lchown16)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_break */
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_stat */
+		.long	SYMBOL_NAME(sys_lseek)
+/* 20 */	.long	SYMBOL_NAME(sys_getpid)
+		.long	SYMBOL_NAME(sys_mount)
+		.long	SYMBOL_NAME(sys_oldumount)		/* used by libc4 */
+		.long	SYMBOL_NAME(sys_setuid16)
+		.long	SYMBOL_NAME(sys_getuid16)
+/* 25 */	.long	SYMBOL_NAME(sys_stime)
+		.long	SYMBOL_NAME(sys_ptrace)
+		.long	SYMBOL_NAME(sys_alarm)			/* used by libc4 */
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_fstat */
+		.long	SYMBOL_NAME(sys_pause)
+/* 30 */	.long	SYMBOL_NAME(sys_utime)			/* used by libc4 */
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_stty */
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_getty */
+		.long	SYMBOL_NAME(sys_access)
+		.long	SYMBOL_NAME(sys_nice)
+/* 35 */	.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_ftime */
+		.long	SYMBOL_NAME(sys_sync)
+		.long	SYMBOL_NAME(sys_kill)
+		.long	SYMBOL_NAME(sys_rename)
+		.long	SYMBOL_NAME(sys_mkdir)
+/* 40 */	.long	SYMBOL_NAME(sys_rmdir)
+		.long	SYMBOL_NAME(sys_dup)
+		.long	SYMBOL_NAME(sys_pipe)
+		.long	SYMBOL_NAME(sys_times)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_prof */
+/* 45 */	.long	SYMBOL_NAME(sys_brk)
+		.long	SYMBOL_NAME(sys_setgid16)
+		.long	SYMBOL_NAME(sys_getgid16)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_signal */
+		.long	SYMBOL_NAME(sys_geteuid16)
+/* 50 */	.long	SYMBOL_NAME(sys_getegid16)
+		.long	SYMBOL_NAME(sys_acct)
+		.long	SYMBOL_NAME(sys_umount)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_lock */
+		.long	SYMBOL_NAME(sys_ioctl)
+/* 55 */	.long	SYMBOL_NAME(sys_fcntl)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_mpx */
+		.long	SYMBOL_NAME(sys_setpgid)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_ulimit */
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_olduname */
+/* 60 */	.long	SYMBOL_NAME(sys_umask)
+		.long	SYMBOL_NAME(sys_chroot)
+		.long	SYMBOL_NAME(sys_ustat)
+		.long	SYMBOL_NAME(sys_dup2)
+		.long	SYMBOL_NAME(sys_getppid)
+/* 65 */	.long	SYMBOL_NAME(sys_getpgrp)
+		.long	SYMBOL_NAME(sys_setsid)
+		.long	SYMBOL_NAME(sys_sigaction)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_sgetmask */
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_ssetmask */
+/* 70 */	.long	SYMBOL_NAME(sys_setreuid16)
+		.long	SYMBOL_NAME(sys_setregid16)
+		.long	SYMBOL_NAME(sys_sigsuspend_wrapper)
+		.long	SYMBOL_NAME(sys_sigpending)
+		.long	SYMBOL_NAME(sys_sethostname)
+/* 75 */	.long	SYMBOL_NAME(sys_setrlimit)
+		.long	SYMBOL_NAME(sys_old_getrlimit)		/* used by libc4 */
+		.long	SYMBOL_NAME(sys_getrusage)
+		.long	SYMBOL_NAME(sys_gettimeofday)
+		.long	SYMBOL_NAME(sys_settimeofday)
+/* 80 */	.long	SYMBOL_NAME(sys_getgroups16)
+		.long	SYMBOL_NAME(sys_setgroups16)
+		.long	SYMBOL_NAME(old_select)			/* used by libc4 */
+		.long	SYMBOL_NAME(sys_symlink)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_lstat */
+/* 85 */	.long	SYMBOL_NAME(sys_readlink)
+		.long	SYMBOL_NAME(sys_uselib)
+		.long	SYMBOL_NAME(sys_swapon)
+		.long	SYMBOL_NAME(sys_reboot)
+		.long	SYMBOL_NAME(old_readdir)		/* used by libc4 */
+/* 90 */	.long	SYMBOL_NAME(old_mmap)			/* used by libc4 */
+		.long	SYMBOL_NAME(sys_munmap)
+		.long	SYMBOL_NAME(sys_truncate)
+		.long	SYMBOL_NAME(sys_ftruncate)
+		.long	SYMBOL_NAME(sys_fchmod)
+/* 95 */	.long	SYMBOL_NAME(sys_fchown16)
+		.long	SYMBOL_NAME(sys_getpriority)
+		.long	SYMBOL_NAME(sys_setpriority)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_profil */
+		.long	SYMBOL_NAME(sys_statfs)
+/* 100 */	.long	SYMBOL_NAME(sys_fstatfs)
+		.long	SYMBOL_NAME(sys_ni_syscall)
+		.long	SYMBOL_NAME(sys_socketcall)
+		.long	SYMBOL_NAME(sys_syslog)
+		.long	SYMBOL_NAME(sys_setitimer)
+/* 105 */	.long	SYMBOL_NAME(sys_getitimer)
+		.long	SYMBOL_NAME(sys_newstat)
+		.long	SYMBOL_NAME(sys_newlstat)
+		.long	SYMBOL_NAME(sys_newfstat)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_uname */
+/* 110 */	.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_iopl */
+		.long	SYMBOL_NAME(sys_vhangup)
+		.long	SYMBOL_NAME(sys_ni_syscall)
+		.long	SYMBOL_NAME(sys_syscall)		/* call a syscall */
+		.long	SYMBOL_NAME(sys_wait4)
+/* 115 */	.long	SYMBOL_NAME(sys_swapoff)
+		.long	SYMBOL_NAME(sys_sysinfo)
+		.long	SYMBOL_NAME(sys_ipc)
+		.long	SYMBOL_NAME(sys_fsync)
+		.long	SYMBOL_NAME(sys_sigreturn_wrapper)
+/* 120 */	.long	SYMBOL_NAME(sys_clone_wapper)
+		.long	SYMBOL_NAME(sys_setdomainname)
+		.long	SYMBOL_NAME(sys_newuname)
+		.long	SYMBOL_NAME(sys_ni_syscall)
+		.long	SYMBOL_NAME(sys_adjtimex)
+/* 125 */	.long	SYMBOL_NAME(sys_mprotect)
+		.long	SYMBOL_NAME(sys_sigprocmask)
+		.long	SYMBOL_NAME(sys_create_module)
+		.long	SYMBOL_NAME(sys_init_module)
+		.long	SYMBOL_NAME(sys_delete_module)
+/* 130 */	.long	SYMBOL_NAME(sys_get_kernel_syms)
+		.long	SYMBOL_NAME(sys_quotactl)
+		.long	SYMBOL_NAME(sys_getpgid)
+		.long	SYMBOL_NAME(sys_fchdir)
+		.long	SYMBOL_NAME(sys_bdflush)
+/* 135 */	.long	SYMBOL_NAME(sys_sysfs)
+		.long	SYMBOL_NAME(sys_personality)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* .long	_sys_afs_syscall */
+		.long	SYMBOL_NAME(sys_setfsuid16)
+		.long	SYMBOL_NAME(sys_setfsgid16)
+/* 140 */	.long	SYMBOL_NAME(sys_llseek)
+		.long	SYMBOL_NAME(sys_getdents)
+		.long	SYMBOL_NAME(sys_select)
+		.long	SYMBOL_NAME(sys_flock)
+		.long	SYMBOL_NAME(sys_msync)
+/* 145 */	.long	SYMBOL_NAME(sys_readv)
+		.long	SYMBOL_NAME(sys_writev)
+		.long	SYMBOL_NAME(sys_getsid)
+		.long	SYMBOL_NAME(sys_fdatasync)
+		.long	SYMBOL_NAME(sys_sysctl)
+/* 150 */	.long	SYMBOL_NAME(sys_mlock)
+		.long	SYMBOL_NAME(sys_munlock)
+		.long	SYMBOL_NAME(sys_mlockall)
+		.long	SYMBOL_NAME(sys_munlockall)
+		.long	SYMBOL_NAME(sys_sched_setparam)
+/* 155 */	.long	SYMBOL_NAME(sys_sched_getparam)
+		.long	SYMBOL_NAME(sys_sched_setscheduler)
+		.long	SYMBOL_NAME(sys_sched_getscheduler)
+		.long	SYMBOL_NAME(sys_sched_yield)
+		.long	SYMBOL_NAME(sys_sched_get_priority_max)
+/* 160 */	.long	SYMBOL_NAME(sys_sched_get_priority_min)
+		.long	SYMBOL_NAME(sys_sched_rr_get_interval)
+		.long	SYMBOL_NAME(sys_nanosleep)
+		.long	SYMBOL_NAME(sys_arm_mremap)
+		.long	SYMBOL_NAME(sys_setresuid16)
+/* 165 */	.long	SYMBOL_NAME(sys_getresuid16)
+		.long	SYMBOL_NAME(sys_ni_syscall)
+		.long	SYMBOL_NAME(sys_query_module)
+		.long	SYMBOL_NAME(sys_poll)
+		.long	SYMBOL_NAME(sys_nfsservctl)
+/* 170 */	.long	SYMBOL_NAME(sys_setresgid16)
+		.long	SYMBOL_NAME(sys_getresgid16)
+		.long	SYMBOL_NAME(sys_prctl)
+		.long	SYMBOL_NAME(sys_rt_sigreturn_wrapper)
+		.long	SYMBOL_NAME(sys_rt_sigaction)
+/* 175 */	.long	SYMBOL_NAME(sys_rt_sigprocmask)
+		.long	SYMBOL_NAME(sys_rt_sigpending)
+		.long	SYMBOL_NAME(sys_rt_sigtimedwait)
+		.long	SYMBOL_NAME(sys_rt_sigqueueinfo)
+		.long	SYMBOL_NAME(sys_rt_sigsuspend_wrapper)
+/* 180 */	.long	SYMBOL_NAME(sys_pread)
+		.long	SYMBOL_NAME(sys_pwrite)
+		.long	SYMBOL_NAME(sys_chown16)
+		.long	SYMBOL_NAME(sys_getcwd)
+		.long	SYMBOL_NAME(sys_capget)
+/* 185 */	.long	SYMBOL_NAME(sys_capset)
+		.long	SYMBOL_NAME(sys_sigaltstack_wrapper)
+		.long	SYMBOL_NAME(sys_sendfile)
+		.long	SYMBOL_NAME(sys_ni_syscall)
+		.long	SYMBOL_NAME(sys_ni_syscall)
+/* 190 */	.long	SYMBOL_NAME(sys_vfork_wrapper)
+		.long	SYMBOL_NAME(sys_getrlimit)
+		.long	SYMBOL_NAME(sys_mmap2)
+		.long	SYMBOL_NAME(sys_truncate64)
+		.long	SYMBOL_NAME(sys_ftruncate64)
+/* 195 */	.long	SYMBOL_NAME(sys_stat64)
+		.long	SYMBOL_NAME(sys_lstat64)
+		.long	SYMBOL_NAME(sys_fstat64)
+		.long	SYMBOL_NAME(sys_lchown)
+		.long	SYMBOL_NAME(sys_getuid)
+/* 200 */	.long	SYMBOL_NAME(sys_getgid)
+		.long	SYMBOL_NAME(sys_geteuid)
+		.long	SYMBOL_NAME(sys_getegid)
+		.long	SYMBOL_NAME(sys_setreuid)
+		.long	SYMBOL_NAME(sys_setregid)
+/* 205 */	.long	SYMBOL_NAME(sys_getgroups)
+		.long	SYMBOL_NAME(sys_setgroups)
+		.long	SYMBOL_NAME(sys_fchown)
+		.long	SYMBOL_NAME(sys_setresuid)
+		.long	SYMBOL_NAME(sys_getresuid)
+/* 210 */	.long	SYMBOL_NAME(sys_setresgid)
+		.long	SYMBOL_NAME(sys_getresgid)
+		.long	SYMBOL_NAME(sys_chown)
+		.long	SYMBOL_NAME(sys_setuid)
+		.long	SYMBOL_NAME(sys_setgid)
+/* 215 */	.long	SYMBOL_NAME(sys_setfsuid)
+		.long	SYMBOL_NAME(sys_setfsgid)
+		.long	SYMBOL_NAME(sys_getdents64)
+		.long	SYMBOL_NAME(sys_pivot_root)
+		.long	SYMBOL_NAME(sys_mincore)
+/* 220 */	.long	SYMBOL_NAME(sys_madvise)
+		.long	SYMBOL_NAME(sys_fcntl64)
+__syscall_end:
+
+		.rept	NR_syscalls - (__syscall_end - __syscall_start) / 4
+			.long	SYMBOL_NAME(sys_ni_syscall)
+		.endr
+#endif
diff -urN linux-2.4.29/arch/armnommu/kernel/compat.c linux-2.4.29-uc1/arch/armnommu/kernel/compat.c
--- linux-2.4.29/arch/armnommu/kernel/compat.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/compat.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,143 @@
+/*
+ *  linux/arch/arm/kernel/compat.c
+ *
+ *  Copyright (C) 2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * We keep the old params compatibility cruft in one place (here)
+ * so we don't end up with lots of mess around other places.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+
+#include <asm/mach/arch.h>
+
+static struct tag * __init memtag(struct tag *tag, unsigned long start, unsigned long size)
+{
+	tag = tag_next(tag);
+	tag->hdr.tag = ATAG_MEM;
+	tag->hdr.size = tag_size(tag_mem32);
+	tag->u.mem.size = size;
+	tag->u.mem.start = start;
+
+	return tag;
+}
+
+static void __init build_tag_list(struct param_struct *params, void *taglist)
+{
+	struct tag *tag = taglist;
+
+	if (params->u1.s.page_size != PAGE_SIZE) {
+		printk(KERN_WARNING "Warning: bad configuration page, "
+		       "trying to continue\n");
+		return;
+	}
+
+	printk(KERN_DEBUG "Converting old-style param struct to taglist\n");
+
+	tag->hdr.tag  = ATAG_CORE;
+	tag->hdr.size = tag_size(tag_core);
+	tag->u.core.flags = params->u1.s.flags & FLAG_READONLY;
+	tag->u.core.pagesize = params->u1.s.page_size;
+	tag->u.core.rootdev = params->u1.s.rootdev;
+
+	tag = tag_next(tag);
+	tag->hdr.tag = ATAG_RAMDISK;
+	tag->hdr.size = tag_size(tag_ramdisk);
+	tag->u.ramdisk.flags = (params->u1.s.flags & FLAG_RDLOAD ? 1 : 0) |
+			       (params->u1.s.flags & FLAG_RDPROMPT ? 2 : 0);
+	tag->u.ramdisk.size  = params->u1.s.ramdisk_size;
+	tag->u.ramdisk.start = params->u1.s.rd_start;
+
+	tag = tag_next(tag);
+	tag->hdr.tag = ATAG_INITRD;
+	tag->hdr.size = tag_size(tag_initrd);
+	tag->u.initrd.start = params->u1.s.initrd_start;
+	tag->u.initrd.size  = params->u1.s.initrd_size;
+
+	tag = tag_next(tag);
+	tag->hdr.tag = ATAG_SERIAL;
+	tag->hdr.size = tag_size(tag_serialnr);
+	tag->u.serialnr.low = params->u1.s.system_serial_low;
+	tag->u.serialnr.high = params->u1.s.system_serial_high;
+
+	tag = tag_next(tag);
+	tag->hdr.tag = ATAG_REVISION;
+	tag->hdr.size = tag_size(tag_revision);
+	tag->u.revision.rev = params->u1.s.system_rev;
+
+#ifdef CONFIG_ARCH_ACORN
+	if (machine_is_riscpc()) {
+		int i;
+		for (i = 0; i < 4; i++)
+			tag = memtag(tag, PHYS_OFFSET + (i << 26),
+				 params->u1.s.pages_in_bank[i] * PAGE_SIZE);
+	} else
+#endif
+	if (machine_is_shark()) {
+		int i;
+		for (i = 0; i < 4; i++) {
+			unsigned int val = params->u1.s.pages_in_bank[i];
+			if (!val)
+				continue;
+			tag = memtag(tag, val & 0xffff0000,
+					(val & 0xffff) * PAGE_SIZE);
+		}
+	} else
+	tag = memtag(tag, PHYS_OFFSET, params->u1.s.nr_pages * PAGE_SIZE);
+
+#ifdef CONFIG_FOOTBRIDGE
+	if (params->u1.s.mem_fclk_21285) {
+		tag = tag_next(tag);
+		tag->hdr.tag = ATAG_MEMCLK;
+		tag->hdr.size = tag_size(tag_memclk);
+		tag->u.memclk.fmemclk = params->u1.s.mem_fclk_21285;
+	}
+#endif
+
+#ifdef CONFIG_ARCH_ACORN
+	tag = tag_next(tag);
+	tag->hdr.tag = ATAG_ACORN;
+	tag->hdr.size = tag_size(tag_acorn);
+	tag->u.acorn.memc_control_reg = params->u1.s.memc_control_reg;
+	tag->u.acorn.vram_pages       = params->u1.s.pages_in_vram;
+	tag->u.acorn.sounddefault     = params->u1.s.sounddefault;
+	tag->u.acorn.adfsdrives       = params->u1.s.adfsdrives;
+#endif
+
+	tag = tag_next(tag);
+	tag->hdr.tag = ATAG_CMDLINE;
+	tag->hdr.size = (strlen(params->commandline) + 3 +
+			 sizeof(struct tag_header)) >> 2;
+	strcpy(tag->u.cmdline.cmdline, params->commandline);
+
+	tag = tag_next(tag);
+	tag->hdr.tag = ATAG_NONE;
+	tag->hdr.size = 0;
+
+	memmove(params, taglist, ((int)tag) - ((int)taglist) +
+				 sizeof(struct tag_header));
+}
+
+void __init convert_to_tag_list(struct tag *tags)
+{
+	struct param_struct *params = (struct param_struct *)tags;
+	build_tag_list(params, &params->u2);
+}
+
+void __init squash_mem_tags(struct tag *tag)
+{
+	for (; tag->hdr.size; tag = tag_next(tag))
+		if (tag->hdr.tag == ATAG_MEM)
+			tag->hdr.tag = ATAG_NONE;
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/debug-armo.S linux-2.4.29-uc1/arch/armnommu/kernel/debug-armo.S
--- linux-2.4.29/arch/armnommu/kernel/debug-armo.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/debug-armo.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,90 @@
+/*
+ *  linux/arch/arm/kernel/debug-armo.S
+ *
+ *  Copyright (C) 1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  26-bit debugging code
+ */
+#include <linux/linkage.h>
+
+		.macro	addruart,rx
+		mov	\rx, #0x03000000
+		orr	\rx, \rx, #0x00010000
+		orr	\rx, \rx, #0x00000fe0
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldrb	\rd, [\rx, #0x14]
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		bne	1002b
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldrb	\rd, [\rx, #0x18]
+		tst	\rd, #0x10
+		beq	1001b
+		.endm
+
+		.text
+/*
+ * Useful debugging routines
+ */
+ENTRY(printhex8)
+		mov	r1, #8
+		b	printhex
+
+ENTRY(printhex4)
+		mov	r1, #4
+		b	printhex
+
+ENTRY(printhex2)
+		mov	r1, #2
+printhex:	ldr	r2, =hexbuf
+		add	r3, r2, r1
+		mov	r1, #0
+		strb	r1, [r3]
+1:		and	r1, r0, #15
+		mov	r0, r0, lsr #4
+		cmp	r1, #10
+		addlt	r1, r1, #'0'
+		addge	r1, r1, #'a' - 10
+		strb	r1, [r3, #-1]!
+		teq	r3, r2
+		bne	1b
+		mov	r0, r2
+		b	printascii
+
+		.ltorg
+
+ENTRY(printascii)
+		addruart r3
+		b	2f
+1:		waituart r2, r3
+		senduart r1, r3
+		busyuart r2, r3
+		teq	r1, #'\n'
+		moveq	r1, #'\r'
+		beq	1b
+2:		teq	r0, #0
+		ldrneb	r1, [r0], #1
+		teqne	r1, #0
+		bne	1b
+		mov	pc, lr
+
+ENTRY(printch)
+		addruart r3
+		mov	r1, r0
+		mov	r0, #0
+		b	1b
+
+		.bss
+hexbuf:		.space 16
diff -urN linux-2.4.29/arch/armnommu/kernel/debug-armv.S linux-2.4.29-uc1/arch/armnommu/kernel/debug-armv.S
--- linux-2.4.29/arch/armnommu/kernel/debug-armv.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/debug-armv.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,477 @@
+/*
+ *  linux/arch/arm/kernel/debug-armv.S
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  32-bit debugging code
+ */
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/hardware.h>
+
+		.text
+
+/*
+ * Some debugging routines (useful if you've got MM problems and
+ * printk isn't working).  For DEBUGGING ONLY!!!  Do not leave
+ * references to these in a production kernel!
+ */
+#if defined(CONFIG_ARCH_RPC)
+		.macro	addruart,rx
+		mov	\rx, #0xe0000000
+		orr	\rx, \rx, #0x00010000
+		orr	\rx, \rx, #0x00000fe0
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldrb	\rd, [\rx, #0x14]
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		bne	1001b
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldrb	\rd, [\rx, #0x18]
+		tst	\rd, #0x10
+		beq	1001b
+		.endm
+
+#elif defined(CONFIG_ARCH_EBSA110)
+		.macro	addruart,rx
+		mov	\rx, #0xf0000000
+		orr	\rx, \rx, #0x00000be0
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldrb	\rd, [\rx, #0x14]
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		bne	1002b
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldrb	\rd, [\rx, #0x18]
+		tst	\rd, #0x10
+		beq	1001b
+		.endm
+ 	
+#elif defined(CONFIG_ARCH_SHARK)
+		.macro	addruart,rx
+		mov	\rx, #0xe0000000
+		orr	\rx, \rx, #0x000003f8
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+		mov	\rd, #0
+1001:		add	\rd, \rd, #1
+		teq	\rd, #0x10000
+		bne	1001b
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
+
+#elif defined(CONFIG_FOOTBRIDGE)
+
+#include <asm/hardware/dec21285.h>
+
+#ifndef CONFIG_DEBUG_DC21285_PORT
+	/* For NetWinder debugging */
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0x7c000000	@ physical
+		movne	\rx, #0xff000000	@ virtual
+		orr	\rx, \rx, #0x000003f8
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldrb	\rd, [\rx, #0x5]
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		bne	1002b
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldrb	\rd, [\rx, #0x6]
+		tst	\rd, #0x10
+		beq	1001b
+		.endm
+#else
+	/* For EBSA285 debugging */
+		.equ	dc21285_high, ARMCSR_BASE & 0xff000000
+		.equ	dc21285_low,  ARMCSR_BASE & 0x00ffffff
+
+		.macro	addruart,rx
+		mov	\rx, #dc21285_high
+		.if	dc21285_low
+		orr	\rx, \rx, #dc21285_low
+		.endif
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0x160]	@ UARTDR
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldr	\rd, [\rx, #0x178]	@ UARTFLG
+		tst	\rd, #1 << 3
+		bne	1001b
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
+#endif
+#elif defined(CONFIG_ARCH_FTVPCI)
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		movne	\rx, #0xe0000000
+		moveq	\rx, #0x10000000
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0xc]
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldr	\rd, [\rx, #0x4]
+		tst	\rd, #1 << 2
+		beq	1001b
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
+
+#elif defined(CONFIG_ARCH_SA1100)
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0x80000000	@ physical base address
+		movne	\rx, #0xf8000000	@ virtual address
+		@add	\rx, \rx, #0x00050000	@ Ser3
+		add	\rx, \rx, #0x00010000	@ Ser1
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0x14]	@ UTDR
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldr	\rd, [\rx, #0x20]	@ UTSR1
+		tst	\rd, #1 << 2		@ UTSR1_TNF
+		beq	1001b
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldr	\rd, [\rx, #0x20]	@ UTSR1
+		tst	\rd, #1 << 0		@ UTSR1_TBY
+		bne	1001b
+		.endm
+
+#elif defined(CONFIG_ARCH_CLPS7500)
+		.macro	addruart,rx
+		mov	\rx, #0xe0000000
+		orr	\rx, \rx, #0x00010000
+		orr	\rx, \rx, #0x00000be0
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldrb	\rd, [\rx, #0x14]
+		tst	\rd, #0x20
+		beq	1001b
+		.endm
+
+#elif defined(CONFIG_ARCH_L7200)
+
+		.equ	io_virt, IO_BASE
+		.equ	io_phys, IO_START
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #io_phys		@ physical base address
+		movne	\rx, #io_virt		@ virtual address
+		add	\rx, \rx, #0x00044000	@ UART1
+@		add	\rx, \rx, #0x00045000	@ UART2
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0x0]	@ UARTDR
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
+		tst	\rd, #1 << 5		@ UARTFLGUTXFF - 1 when full
+		bne	1001b
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
+		tst	\rd, #1 << 3		@ UARTFLGUBUSY - 1 when busy
+		bne	1001b
+		.endm
+
+#elif defined(CONFIG_ARCH_INTEGRATOR)
+
+#include <asm/hardware/serial_amba.h>
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0x16000000	@ physical base address
+		movne	\rx, #0xf0000000	@ virtual base
+		addne	\rx, \rx, #0x16000000 >> 4
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx, #AMBA_UARTDR]
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
+		tst	\rd, #1 << 5		@ UARTFLGUTXFF - 1 when full
+		bne	1001b
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
+		tst	\rd, #1 << 3		@ UARTFLGUBUSY - 1 when busy
+		bne	1001b
+		.endm
+
+#elif defined(CONFIG_ARCH_CLPS711X)
+
+#include <asm/hardware/clps7111.h>
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #CLPS7111_PHYS_BASE
+		movne	\rx, #CLPS7111_VIRT_BASE
+#ifndef CONFIG_DEBUG_CLPS711X_UART2
+		add	\rx, \rx, #0x0000	@ UART1
+#else
+		add	\rx, \rx, #0x1000	@ UART2
+#endif
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0x0480]	@ UARTDR
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldr	\rd, [\rx, #0x0140]	@ SYSFLGx
+		tst	\rd, #1 << 11		@ UBUSYx
+		bne	1001b
+		.endm
+
+		.macro	busyuart,rd,rx
+		tst	\rx, #0x1000		@ UART2 does not have CTS here
+		bne	1002f
+1001:		ldr	\rd, [\rx, #0x0140]	@ SYSFLGx
+		tst	\rd, #1 << 8		@ CTS
+		bne	1001b
+1002:
+		.endm
+
+#elif defined(CONFIG_ARCH_ANAKIN)
+
+#include <asm/arch/serial_reg.h>
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #IO_START
+		movne	\rx, #IO_BASE
+		add	\rx, \rx, #UART0
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0x14]	@ tx
+		ldr	\rd, [\rx, #0x18]
+		orr	\rd, \rd, #SENDREQUEST
+		str	\rd, [\rx, #0x18]
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldr	\rd, [\rx, #0x10]
+		tst	\rd, #TXEMPTY
+		beq	1001b
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldr	\rd, [\rx, #0x10]
+		tst	\rd, #CTS
+		bne	1001b
+		.endm
+
+#elif defined(CONFIG_ARCH_VC547X)
+
+                .macro  addruart,rx
+                ldr     \rx, =0xffff1000        @ UART Modem base
+                .endm
+
+                .macro  senduart,rd,rx
+                str     \rd, [\rx, #0x04]       @ UART_THR
+                .endm
+
+                .macro  waituart,rd,rx
+1001:           ldr     \rd, [\rx, #0x18]       @ UART_SSR
+                tst     \rd, #0x00000001        @ 1=TX fifo full
+                bne     1001b                   @ loop til clear
+                .endm
+
+                .macro  busyuart,rd,rx
+1002:           ldr     \rd, [\rx, #0x14]       @ UART_LSR
+                tst     \rd, #0x00000020        @ 1=THR is empty
+                beq     1002b                   @ Loop til set
+                .endm
+
+#elif defined(CONFIG_ARCH_DM270)
+
+                .macro  addruart,rx
+# ifdef CONFIG_DEBUG_DM270_UART1
+                ldr     \rx, =DM270_UART1_BASE
+# else
+                ldr     \rx, =DM270_UART0_BASE
+# endif
+                .endm
+
+                .macro  senduart,rd,rx
+                str     \rd, [\rx, #DM270_UART_DTRR]
+                .endm
+
+                .macro  waituart,rd,rx
+1001:           ldr     \rd, [\rx, #DM270_UART_SR]
+                tst     \rd, #DM270_UART_SR_TFEF
+                beq     1001b
+                .endm
+
+                .macro  busyuart,rd,rx
+1002:           ldr     \rd, [\rx, #DM270_UART_SR]
+                tst     \rd, #DM270_UART_SR_TFTI
+                beq     1002b
+                .endm
+
+#elif defined(CONFIG_ARCH_ISL3893)
+#include <asm/arch/serial.h>
+#ifdef ISL3893_SIMSONLY
+/* We only use the Tube here */
+		.macro	addruart,rx
+		ldr	\rx, =uTUBEData
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	waituart,rd,rx
+		/* Nothing to do here */
+		.endm
+
+		.macro	busyuart,rd,rx
+		/* Nothing to do here */
+		.endm
+#else /* ISL3893_SIMSONLY */
+		.macro	addruart,rx
+		mov	\rx, #PERIPH_BASE
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #aUARTRegister0]
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldr	\rd, [\rx, #aUARTLineStatus]
+		tst	\rd, #UARTLineStatusTHRE
+		beq	1001b
+		.endm
+
+		.macro	busyuart,rd,rx
+		/* Nothing to do here */
+		.endm
+#endif /* ISL3893_SIMSONLY */
+#else
+#error Unknown architecture
+#endif
+
+/*
+ * Useful debugging routines
+ */
+ENTRY(printhex8)
+		mov	r1, #8
+		b	printhex
+
+ENTRY(printhex4)
+		mov	r1, #4
+		b	printhex
+
+ENTRY(printhex2)
+		mov	r1, #2
+printhex:	adr	r2, hexbuf
+		add	r3, r2, r1
+		mov	r1, #0
+		strb	r1, [r3]
+1:		and	r1, r0, #15
+		mov	r0, r0, lsr #4
+		cmp	r1, #10
+		addlt	r1, r1, #'0'
+		addge	r1, r1, #'a' - 10
+		strb	r1, [r3, #-1]!
+		teq	r3, r2
+		bne	1b
+		mov	r0, r2
+		b	printascii
+
+		.ltorg
+
+ENTRY(printascii)
+		addruart r3
+		b	2f
+1:		waituart r2, r3
+		senduart r1, r3
+		busyuart r2, r3
+		teq	r1, #'\n'
+		moveq	r1, #'\r'
+		beq	1b
+2:		teq	r0, #0
+		ldrneb	r1, [r0], #1
+		teqne	r1, #0
+		bne	1b
+		mov	pc, lr
+
+ENTRY(printch)
+		addruart r3
+		mov	r1, r0
+		mov	r0, #0
+		b	1b
+
+hexbuf:		.space 16
diff -urN linux-2.4.29/arch/armnommu/kernel/debug.c linux-2.4.29-uc1/arch/armnommu/kernel/debug.c
--- linux-2.4.29/arch/armnommu/kernel/debug.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/debug.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,56 @@
+#include "linux/config.h"
+
+static unsigned long *out_size;
+static unsigned long out_pos;
+
+//#define AT91_DEBUG_BASE 0x1400000L
+
+void at91_debug_init()
+{
+  at91_debug_init_adr(AT91_DEBUG_BASE);
+}
+
+void at91_debug_init_adr(unsigned long adr)
+{
+  out_size =  (unsigned long*) adr;
+  *out_size = 0;
+  out_pos=0;
+  at91_debug_str("AT91 debugging initialized\n");
+}
+
+void at91_debug_str(char *s)
+{
+char *p;
+
+  p = (char*)  out_size+4;
+  p += out_pos;
+  while (*s){ 
+        *p++ = *s++;
+        out_pos++;
+  } 
+  *out_size = (out_pos+3)>>2;   // nr. of words
+  *p++='\n';
+  *p++='\n';
+  *p++='\n';
+}
+
+void at91_debug_putn(char *s,int n)
+{
+char v[2];
+v[1]=0;
+  while(n--) {
+	v[0]=*s++; at91_debug_str(v);
+  }
+}
+
+at91_mark_a()
+{
+  at91_debug_str("mark A\n");
+}
+
+
+void at91_sv(long x, long *px)
+{
+*px=x;
+}
+
diff -urN linux-2.4.29/arch/armnommu/kernel/dec21285.c linux-2.4.29-uc1/arch/armnommu/kernel/dec21285.c
--- linux-2.4.29/arch/armnommu/kernel/dec21285.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/dec21285.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,382 @@
+/*
+ *  linux/arch/arm/kernel/dec21285.c: PCI functions for DC21285
+ *
+ *  Copyright (C) 1998-2000 Russell King, Phil Blundell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/hardware/dec21285.h>
+
+#define MAX_SLOTS		21
+
+#define PCICMD_ERROR_BITS ((PCI_STATUS_DETECTED_PARITY | \
+			PCI_STATUS_REC_MASTER_ABORT | \
+			PCI_STATUS_REC_TARGET_ABORT | \
+			PCI_STATUS_PARITY) << 16)
+
+extern int setup_arm_irq(int, struct irqaction *);
+extern void pcibios_report_status(u_int status_mask, int warn);
+extern void register_isa_ports(unsigned int, unsigned int, unsigned int);
+
+static unsigned long
+dc21285_base_address(struct pci_dev *dev)
+{
+	unsigned long addr = 0;
+	unsigned int devfn = dev->devfn;
+
+	if (dev->bus->number == 0) {
+		if (PCI_SLOT(devfn) == 0)
+			/*
+			 * For devfn 0, point at the 21285
+			 */
+			addr = ARMCSR_BASE;
+		else {
+			devfn -= 1 << 3;
+
+			if (devfn < PCI_DEVFN(MAX_SLOTS, 0))
+				addr = PCICFG0_BASE | 0xc00000 | (devfn << 8);
+		}
+	} else
+		addr = PCICFG1_BASE | (dev->bus->number << 16) | (devfn << 8);
+
+	return addr;
+}
+
+static int
+dc21285_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	unsigned long addr = dc21285_base_address(dev);
+	u8 v;
+
+	if (addr)
+		asm("ldr%?b	%0, [%1, %2]"
+			: "=r" (v) : "r" (addr), "r" (where));
+	else
+		v = 0xff;
+
+	*value = v;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+dc21285_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	unsigned long addr = dc21285_base_address(dev);
+	u16 v;
+
+	if (addr)
+		asm("ldr%?h	%0, [%1, %2]"
+			: "=r" (v) : "r" (addr), "r" (where));
+	else
+		v = 0xffff;
+
+	*value = v;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+dc21285_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	unsigned long addr = dc21285_base_address(dev);
+	u32 v;
+
+	if (addr)
+		asm("ldr%?	%0, [%1, %2]"
+			: "=r" (v) : "r" (addr), "r" (where));
+	else
+		v = 0xffffffff;
+
+	*value = v;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+dc21285_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	unsigned long addr = dc21285_base_address(dev);
+
+	if (addr)
+		asm("str%?b	%0, [%1, %2]"
+			: : "r" (value), "r" (addr), "r" (where));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+dc21285_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	unsigned long addr = dc21285_base_address(dev);
+
+	if (addr)
+		asm("str%?h	%0, [%1, %2]"
+			: : "r" (value), "r" (addr), "r" (where));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+dc21285_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	unsigned long addr = dc21285_base_address(dev);
+
+	if (addr)
+		asm("str%?	%0, [%1, %2]"
+			: : "r" (value), "r" (addr), "r" (where));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops dc21285_ops = {
+	dc21285_read_config_byte,
+	dc21285_read_config_word,
+	dc21285_read_config_dword,
+	dc21285_write_config_byte,
+	dc21285_write_config_word,
+	dc21285_write_config_dword,
+};
+
+static struct timer_list serr_timer;
+static struct timer_list perr_timer;
+
+static void dc21285_enable_error(unsigned long __data)
+{
+	switch (__data) {
+	case IRQ_PCI_SERR:
+		del_timer(&serr_timer);
+		break;
+
+	case IRQ_PCI_PERR:
+		del_timer(&perr_timer);
+		break;
+	}
+
+	enable_irq(__data);
+}
+
+/*
+ * Warn on PCI errors.
+ */
+static void dc21285_abort_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int cmd;
+	unsigned int status;
+
+	cmd = *CSR_PCICMD;
+	status = cmd >> 16;
+	cmd = cmd & 0xffff;
+
+	if (status & PCI_STATUS_REC_MASTER_ABORT) {
+		printk(KERN_DEBUG "PCI: master abort: ");
+		pcibios_report_status(PCI_STATUS_REC_MASTER_ABORT, 1);
+		printk("\n");
+
+		cmd |= PCI_STATUS_REC_MASTER_ABORT << 16;
+	}
+
+	if (status & PCI_STATUS_REC_TARGET_ABORT) {
+		printk(KERN_DEBUG "PCI: target abort: ");
+		pcibios_report_status(PCI_STATUS_SIG_TARGET_ABORT, 1);
+		printk("\n");
+
+		cmd |= PCI_STATUS_REC_TARGET_ABORT << 16;
+	}
+
+	*CSR_PCICMD = cmd;
+}
+
+static void dc21285_serr_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct timer_list *timer = dev_id;
+	unsigned int cntl;
+
+	printk(KERN_DEBUG "PCI: system error received: ");
+	pcibios_report_status(PCI_STATUS_SIG_SYSTEM_ERROR, 1);
+	printk("\n");
+
+	cntl = *CSR_SA110_CNTL & 0xffffdf07;
+	*CSR_SA110_CNTL = cntl | SA110_CNTL_RXSERR;
+
+	/*
+	 * back off this interrupt
+	 */
+	disable_irq(irq);
+	timer->expires = jiffies + HZ;
+	add_timer(timer);
+}
+
+static void dc21285_discard_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	printk(KERN_DEBUG "PCI: discard timer expired\n");
+	*CSR_SA110_CNTL &= 0xffffde07;
+}
+
+static void dc21285_dparity_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int cmd;
+
+	printk(KERN_DEBUG "PCI: data parity error detected: ");
+	pcibios_report_status(PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY, 1);
+	printk("\n");
+
+	cmd = *CSR_PCICMD & 0xffff;
+	*CSR_PCICMD = cmd | 1 << 24;
+}
+
+static void dc21285_parity_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct timer_list *timer = dev_id;
+	unsigned int cmd;
+
+	printk(KERN_DEBUG "PCI: parity error detected: ");
+	pcibios_report_status(PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY, 1);
+	printk("\n");
+
+	cmd = *CSR_PCICMD & 0xffff;
+	*CSR_PCICMD = cmd | 1 << 31;
+
+	/*
+	 * back off this interrupt
+	 */
+	disable_irq(irq);
+	timer->expires = jiffies + HZ;
+	add_timer(timer);
+}
+
+void __init dc21285_setup_resources(struct resource **resource)
+{
+	struct resource *busmem, *busmempf;
+
+	busmem = kmalloc(sizeof(*busmem), GFP_KERNEL);
+	busmempf = kmalloc(sizeof(*busmempf), GFP_KERNEL);
+	memset(busmem, 0, sizeof(*busmem));
+	memset(busmempf, 0, sizeof(*busmempf));
+
+	busmem->flags = IORESOURCE_MEM;
+	busmem->name  = "Footbridge non-prefetch";
+	busmempf->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
+	busmempf->name  = "Footbridge prefetch";
+
+	allocate_resource(&iomem_resource, busmempf, 0x20000000,
+			  0x80000000, 0xffffffff, 0x20000000, NULL, NULL);
+	allocate_resource(&iomem_resource, busmem, 0x40000000,
+			  0x80000000, 0xffffffff, 0x40000000, NULL, NULL);
+
+	resource[0] = &ioport_resource;
+	resource[1] = busmem;
+	resource[2] = busmempf;
+}
+
+void __init dc21285_init(void *sysdata)
+{
+	unsigned int mem_size, mem_mask;
+	int cfn_mode;
+
+	mem_size = (unsigned int)high_memory - PAGE_OFFSET;
+	for (mem_mask = 0x00100000; mem_mask < 0x10000000; mem_mask <<= 1)
+		if (mem_mask >= mem_size)
+			break;		
+
+	/*
+	 * These registers need to be set up whether we're the
+	 * central function or not.
+	 */
+	*CSR_SDRAMBASEMASK    = (mem_mask - 1) & 0x0ffc0000;
+	*CSR_SDRAMBASEOFFSET  = 0;
+	*CSR_ROMBASEMASK      = 0x80000000;
+	*CSR_CSRBASEMASK      = 0;
+	*CSR_CSRBASEOFFSET    = 0;
+	*CSR_PCIADDR_EXTN     = 0;
+
+	cfn_mode = __footbridge_cfn_mode();
+
+	printk(KERN_INFO "PCI: DC21285 footbridge, revision %02lX, in "
+		"%s mode\n", *CSR_CLASSREV & 0xff, cfn_mode ?
+		"central function" : "addin");
+
+	if (cfn_mode) {
+		static struct resource csrmem, csrio;
+
+		csrio.flags  = IORESOURCE_IO;
+		csrio.name   = "Footbridge";
+		csrmem.flags = IORESOURCE_MEM;
+		csrmem.name  = "Footbridge";
+
+		allocate_resource(&ioport_resource, &csrio, 128,
+				  0xff00, 0xffff, 128, NULL, NULL);
+		allocate_resource(&iomem_resource, &csrmem, 128,
+				  0xf4000000, 0xf8000000, 128, NULL, NULL);
+
+		/*
+		 * Map our SDRAM at a known address in PCI space, just in case
+		 * the firmware had other ideas.  Using a nonzero base is
+		 * necessary, since some VGA cards forcefully use PCI addresses
+		 * in the range 0x000a0000 to 0x000c0000. (eg, S3 cards).
+		 */
+		*CSR_PCICSRBASE       = csrmem.start;
+		*CSR_PCICSRIOBASE     = csrio.start;
+		*CSR_PCISDRAMBASE     = __virt_to_bus(PAGE_OFFSET);
+		*CSR_PCIROMBASE       = 0;
+		*CSR_PCICMD = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+			      PCI_COMMAND_INVALIDATE | PCICMD_ERROR_BITS;
+
+		pci_scan_bus(0, &dc21285_ops, sysdata);
+
+		/*
+		 * Clear any existing errors - we aren't
+		 * interested in historical data...
+		 */
+		*CSR_SA110_CNTL	= (*CSR_SA110_CNTL & 0xffffde07) |
+				  SA110_CNTL_RXSERR;
+		*CSR_PCICMD = (*CSR_PCICMD & 0xffff) | PCICMD_ERROR_BITS;
+	} else if (footbridge_cfn_mode() != 0) {
+		/*
+		 * If we are not compiled to accept "add-in" mode, then
+		 * we are using a constant virt_to_bus translation which
+		 * can not hope to cater for the way the host BIOS  has
+		 * set up the machine.
+		 */
+		panic("PCI: this kernel is compiled for central "
+			"function mode only");
+	}
+
+	/*
+	 * Initialise PCI error IRQ after we've finished probing
+	 */
+	request_irq(IRQ_PCI_ABORT,     dc21285_abort_irq,   SA_INTERRUPT, "PCI abort",       NULL);
+	request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, SA_INTERRUPT, "Discard timer",   NULL);
+	request_irq(IRQ_PCI_DPERR,     dc21285_dparity_irq, SA_INTERRUPT, "PCI data parity", NULL);
+
+	init_timer(&serr_timer);
+	init_timer(&perr_timer);
+
+	serr_timer.data = IRQ_PCI_SERR;
+	serr_timer.function = dc21285_enable_error;
+	perr_timer.data = IRQ_PCI_PERR;
+	perr_timer.function = dc21285_enable_error;
+
+	request_irq(IRQ_PCI_SERR, dc21285_serr_irq, SA_INTERRUPT,
+		    "PCI system error", &serr_timer);
+	request_irq(IRQ_PCI_PERR, dc21285_parity_irq, SA_INTERRUPT,
+		    "PCI parity error", &perr_timer);
+
+	register_isa_ports(DC21285_PCI_MEM, DC21285_PCI_IO, 0);
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/dma-arc.c linux-2.4.29-uc1/arch/armnommu/kernel/dma-arc.c
--- linux-2.4.29/arch/armnommu/kernel/dma-arc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/dma-arc.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,208 @@
+/*
+ *  linux/arch/arm/kernel/dma-arc.c
+ *
+ *  Copyright (C) 1998-1999 Dave Gilbert / Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  DMA functions specific to Archimedes and A5000 architecture
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/dma.h>
+#include <asm/fiq.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/dma.h>
+
+#define DPRINTK(x...) printk(KERN_DEBUG x)
+
+#if defined(CONFIG_BLK_DEV_FD1772) || defined(CONFIG_BLK_DEV_FD1772_MODULE)
+static void arc_floppy_data_enable_dma(dmach_t channel, dma_t *dma)
+{
+	DPRINTK("arc_floppy_data_enable_dma\n");
+	switch (dma->dma_mode) {
+	case DMA_MODE_READ: { /* read */
+		extern unsigned char fdc1772_dma_read, fdc1772_dma_read_end;
+		extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
+		unsigned long flags;
+		DPRINTK("enable_dma fdc1772 data read\n");
+		save_flags(flags);
+		clf();
+			
+		memcpy ((void *)0x1c, (void *)&fdc1772_dma_read,
+			&fdc1772_dma_read_end - &fdc1772_dma_read);
+		fdc1772_setupdma(dma->buf.length, dma->buf.address); /* Sets data pointer up */
+		enable_fiq(FIQ_FLOPPYDATA);
+		restore_flags(flags);
+	   }
+	   break;
+
+	case DMA_MODE_WRITE: { /* write */
+		extern unsigned char fdc1772_dma_write, fdc1772_dma_write_end;
+		extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
+		unsigned long flags;
+		DPRINTK("enable_dma fdc1772 data write\n");
+		save_flags(flags);
+		clf();
+		memcpy ((void *)0x1c, (void *)&fdc1772_dma_write,
+			&fdc1772_dma_write_end - &fdc1772_dma_write);
+		fdc1772_setupdma(dma->buf.length, dma->buf.address); /* Sets data pointer up */
+		enable_fiq(FIQ_FLOPPYDATA;
+
+		restore_flags(flags);
+	    }
+	    break;
+	default:
+		printk ("enable_dma: dma%d not initialised\n", channel);
+	}
+}
+
+static int arc_floppy_data_get_dma_residue(dmach_t channel, dma_t *dma)
+{
+	extern unsigned int fdc1772_bytestogo;
+
+	/* 10/1/1999 DAG - I presume its the number of bytes left? */
+	return fdc1772_bytestogo;
+}
+
+static void arc_floppy_cmdend_enable_dma(dmach_t channel, dma_t *dma)
+{
+	/* Need to build a branch at the FIQ address */
+	extern void fdc1772_comendhandler(void);
+	unsigned long flags;
+
+	DPRINTK("arc_floppy_cmdend_enable_dma\n");
+	/*printk("enable_dma fdc1772 command end FIQ\n");*/
+	save_flags(flags);
+	clf();
+	
+	/* B fdc1772_comendhandler */
+	*((unsigned int *)0x1c)=0xea000000 |
+			(((unsigned int)fdc1772_comendhandler-(0x1c+8))/4);
+
+	restore_flags(flags);
+}
+
+static int arc_floppy_cmdend_get_dma_residue(dmach_t channel, dma_t *dma)
+{
+	/* 10/1/1999 DAG - Presume whether there is an outstanding command? */
+	extern unsigned int fdc1772_fdc_int_done;
+
+	* Explicit! If the int done is 0 then 1 int to go */
+	return (fdc1772_fdc_int_done==0)?1:0;
+}
+
+static void arc_disable_dma(dmach_t channel, dma_t *dma)
+{
+	disable_fiq(dma->dma_irq);
+}
+
+static struct dma_ops arc_floppy_data_dma_ops = {
+	type:		"FIQDMA",
+	enable:		arc_floppy_data_enable_dma,
+	disable:	arc_disable_dma,
+	residue:	arc_floppy_data_get_dma_residue,
+};
+
+static struct dma_ops arc_floppy_cmdend_dma_ops = {
+	type:		"FIQCMD",
+	enable:		arc_floppy_cmdend_enable_dma,
+	disable:	arc_disable_dma,
+	residue:	arc_floppy_cmdend_get_dma_residue,
+};
+#endif
+
+#ifdef CONFIG_ARCH_A5K
+static struct fiq_handler fh = {
+	name:	"floppydata"
+};
+
+static int a5k_floppy_get_dma_residue(dmach_t channel, dma_t *dma)
+{
+	struct pt_regs regs;
+	get_fiq_regs(&regs);
+	return regs.ARM_r9;
+}
+
+static void a5k_floppy_enable_dma(dmach_t channel, dma_t *dma)
+{
+	struct pt_regs regs;
+	void *fiqhandler_start;
+	unsigned int fiqhandler_length;
+	extern void floppy_fiqsetup(unsigned long len, unsigned long addr,
+				     unsigned long port);
+
+	if (dma->dma_mode == DMA_MODE_READ) {
+		extern unsigned char floppy_fiqin_start, floppy_fiqin_end;
+		fiqhandler_start = &floppy_fiqin_start;
+		fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start;
+	} else {
+		extern unsigned char floppy_fiqout_start, floppy_fiqout_end;
+		fiqhandler_start = &floppy_fiqout_start;
+		fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
+	}
+	if (claim_fiq(&fh)) {
+		printk("floppydma: couldn't claim FIQ.\n");
+		return;
+	}
+	memcpy((void *)0x1c, fiqhandler_start, fiqhandler_length);
+	regs.ARM_r9 = dma->buf.length;
+	regs.ARM_r10 = (unsigned long)dma->buf.address;
+	regs.ARM_fp = FLOPPYDMA_BASE;
+	set_fiq_regs(&regs);
+	enable_fiq(dma->dma_irq);
+}
+
+static void a5k_floppy_disable_dma(dmach_t channel, dma_t *dma)
+{
+	disable_fiq(dma->dma_irq);
+	release_fiq(&fh);
+}
+
+static struct dma_ops a5k_floppy_dma_ops = {
+	type:		"FIQDMA",
+	enable:		a5k_floppy_enable_dma,
+	disable:	a5k_floppy_disable_dma,
+	residue:	a5k_floppy_get_dma_residue,
+};
+#endif
+
+/*
+ * This is virtual DMA - we don't need anything here
+ */
+static void sound_enable_disable_dma(dmach_t channel, dma_t *dma)
+{
+}
+
+static struct dma_ops sound_dma_ops = {
+	type:		"VIRTUAL",
+	enable:		sound_enable_disable_dma,
+	disable:	sound_enable_disable_dma,
+};
+
+void __init arch_dma_init(dma_t *dma)
+{
+#if defined(CONFIG_BLK_DEV_FD1772) || defined(CONFIG_BLK_DEV_FD1772_MODULE)
+	if (machine_is_archimedes()) {
+		dma[DMA_VIRTUAL_FLOPPY0].dma_irq = FIQ_FLOPPYDATA;
+		dma[DMA_VIRTUAL_FLOPPY0].d_ops   = &arc_floppy_data_dma_ops;
+		dma[DMA_VIRTUAL_FLOPPY1].dma_irq = 1;
+		dma[DMA_VIRTUAL_FLOPPY1].d_ops   = &arc_floppy_cmdend_dma_ops;
+	}
+#endif
+#ifdef CONFIG_ARCH_A5K
+	if (machine_is_a5k()) {
+		dma[DMA_VIRTUAL_FLOPPY0].dma_irq = FIQ_FLOPPYDATA;
+		dma[DMA_VIRTUAL_FLOPPY0].d_ops   = &a5k_floppy_dma_ops;
+	}
+#endif
+	dma[DMA_VIRTUAL_SOUND].d_ops = &sound_dma_ops;
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/dma.c linux-2.4.29-uc1/arch/armnommu/kernel/dma.c
--- linux-2.4.29/arch/armnommu/kernel/dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/dma.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,286 @@
+/*
+ *  linux/arch/arm/kernel/dma.c
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Front-end to the DMA handling.  This handles the allocation/freeing
+ *  of DMA channels, and provides a unified interface to the machines
+ *  DMA facilities.
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/dma.h>
+
+#include <asm/mach/dma.h>
+
+spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED;
+
+#if MAX_DMA_CHANNELS > 0
+
+static dma_t dma_chan[MAX_DMA_CHANNELS];
+
+/*
+ * Get dma list for /proc/dma
+ */
+int get_dma_list(char *buf)
+{
+	dma_t *dma;
+	char *p = buf;
+	int i;
+
+	for (i = 0, dma = dma_chan; i < MAX_DMA_CHANNELS; i++, dma++)
+		if (dma->lock)
+			p += sprintf(p, "%2d: %14s %s\n", i,
+				     dma->d_ops->type, dma->device_id);
+
+	return p - buf;
+}
+
+/*
+ * Request DMA channel
+ *
+ * On certain platforms, we have to allocate an interrupt as well...
+ */
+int request_dma(dmach_t channel, const char *device_id)
+{
+	dma_t *dma = dma_chan + channel;
+	int ret;
+
+	if (channel >= MAX_DMA_CHANNELS || !dma->d_ops)
+		goto bad_dma;
+
+	if (xchg(&dma->lock, 1) != 0)
+		goto busy;
+
+	dma->device_id = device_id;
+	dma->active    = 0;
+	dma->invalid   = 1;
+
+	ret = 0;
+	if (dma->d_ops->request)
+		ret = dma->d_ops->request(channel, dma);
+
+	if (ret)
+		xchg(&dma->lock, 0);
+
+	return ret;
+
+bad_dma:
+	printk(KERN_ERR "dma: trying to allocate DMA%d\n", channel);
+	return -EINVAL;
+
+busy:
+	return -EBUSY;
+}
+
+/*
+ * Free DMA channel
+ *
+ * On certain platforms, we have to free interrupt as well...
+ */
+void free_dma(dmach_t channel)
+{
+	dma_t *dma = dma_chan + channel;
+
+	if (channel >= MAX_DMA_CHANNELS || !dma->d_ops)
+		goto bad_dma;
+
+	if (dma->active) {
+		printk(KERN_ERR "dma%d: freeing active DMA\n", channel);
+		dma->d_ops->disable(channel, dma);
+		dma->active = 0;
+	}
+
+	if (xchg(&dma->lock, 0) != 0) {
+		if (dma->d_ops->free)
+			dma->d_ops->free(channel, dma);
+		return;
+	}
+
+	printk(KERN_ERR "dma%d: trying to free free DMA\n", channel);
+	return;
+
+bad_dma:
+	printk(KERN_ERR "dma: trying to free DMA%d\n", channel);
+}
+
+/* Set DMA Scatter-Gather list
+ */
+void set_dma_sg (dmach_t channel, struct scatterlist *sg, int nr_sg)
+{
+	dma_t *dma = dma_chan + channel;
+
+	dma->sg = sg;
+	dma->sgcount = nr_sg;
+	dma->using_sg = 1;
+	dma->invalid = 1;
+}
+
+/* Set DMA address
+ *
+ * Copy address to the structure, and set the invalid bit
+ */
+void set_dma_addr (dmach_t channel, unsigned long physaddr)
+{
+	dma_t *dma = dma_chan + channel;
+
+	if (dma->active)
+		printk(KERN_ERR "dma%d: altering DMA address while "
+		       "DMA active\n", channel);
+
+	dma->sg = &dma->buf;
+	dma->sgcount = 1;
+	dma->buf.address = bus_to_virt(physaddr);
+	dma->using_sg = 0;
+	dma->invalid = 1;
+}
+
+/* Set DMA byte count
+ *
+ * Copy address to the structure, and set the invalid bit
+ */
+void set_dma_count (dmach_t channel, unsigned long count)
+{
+	dma_t *dma = dma_chan + channel;
+
+	if (dma->active)
+		printk(KERN_ERR "dma%d: altering DMA count while "
+		       "DMA active\n", channel);
+
+	dma->sg = &dma->buf;
+	dma->sgcount = 1;
+	dma->buf.length = count;
+	dma->using_sg = 0;
+	dma->invalid = 1;
+}
+
+/* Set DMA direction mode
+ */
+void set_dma_mode (dmach_t channel, dmamode_t mode)
+{
+	dma_t *dma = dma_chan + channel;
+
+	if (dma->active)
+		printk(KERN_ERR "dma%d: altering DMA mode while "
+		       "DMA active\n", channel);
+
+	dma->dma_mode = mode;
+	dma->invalid = 1;
+}
+
+/* Enable DMA channel
+ */
+void enable_dma (dmach_t channel)
+{
+	dma_t *dma = dma_chan + channel;
+
+	if (!dma->lock)
+		goto free_dma;
+
+	if (dma->active == 0) {
+		dma->active = 1;
+		dma->d_ops->enable(channel, dma);
+	}
+	return;
+
+free_dma:
+	printk(KERN_ERR "dma%d: trying to enable free DMA\n", channel);
+	BUG();
+}
+
+/* Disable DMA channel
+ */
+void disable_dma (dmach_t channel)
+{
+	dma_t *dma = dma_chan + channel;
+
+	if (!dma->lock)
+		goto free_dma;
+
+	if (dma->active == 1) {
+		dma->active = 0;
+		dma->d_ops->disable(channel, dma);
+	}
+	return;
+
+free_dma:
+	printk(KERN_ERR "dma%d: trying to disable free DMA\n", channel);
+	BUG();
+}
+
+void set_dma_page(dmach_t channel, char pagenr)
+{
+	printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel);
+}
+
+void set_dma_speed(dmach_t channel, int cycle_ns)
+{
+	dma_t *dma = dma_chan + channel;
+	int ret = 0;
+
+	if (dma->d_ops->setspeed)
+		ret = dma->d_ops->setspeed(channel, dma, cycle_ns);
+	dma->speed = ret;
+}
+
+int get_dma_residue(dmach_t channel)
+{
+	dma_t *dma = dma_chan + channel;
+	int ret = 0;
+
+	if (dma->d_ops->residue)
+		ret = dma->d_ops->residue(channel, dma);
+
+	return ret;
+}
+
+void __init init_dma(void)
+{
+	arch_dma_init(dma_chan);
+}
+
+#else
+
+int request_dma(dmach_t channel, const char *device_id)
+{
+	return -EINVAL;
+}
+
+int get_dma_residue(dmach_t channel)
+{
+	return 0;
+}
+
+#define GLOBAL_ALIAS(_a,_b) asm (".set " #_a "," #_b "; .globl " #_a)
+GLOBAL_ALIAS(disable_dma, get_dma_residue);
+GLOBAL_ALIAS(enable_dma, get_dma_residue);
+GLOBAL_ALIAS(free_dma, get_dma_residue);
+GLOBAL_ALIAS(get_dma_list, get_dma_residue);
+GLOBAL_ALIAS(set_dma_mode, get_dma_residue);
+GLOBAL_ALIAS(set_dma_page, get_dma_residue);
+GLOBAL_ALIAS(set_dma_count, get_dma_residue);
+GLOBAL_ALIAS(set_dma_addr, get_dma_residue);
+GLOBAL_ALIAS(set_dma_sg, get_dma_residue);
+GLOBAL_ALIAS(set_dma_speed, get_dma_residue);
+GLOBAL_ALIAS(init_dma, get_dma_residue);
+
+#endif
+
+EXPORT_SYMBOL(enable_dma);
+EXPORT_SYMBOL(disable_dma);
+EXPORT_SYMBOL(set_dma_addr);
+EXPORT_SYMBOL(set_dma_count);
+EXPORT_SYMBOL(set_dma_mode);
+EXPORT_SYMBOL(set_dma_page);
+EXPORT_SYMBOL(get_dma_residue);
+EXPORT_SYMBOL(set_dma_sg);
+EXPORT_SYMBOL(set_dma_speed);
diff -urN linux-2.4.29/arch/armnommu/kernel/dma-footbridge.c linux-2.4.29-uc1/arch/armnommu/kernel/dma-footbridge.c
--- linux-2.4.29/arch/armnommu/kernel/dma-footbridge.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/dma-footbridge.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,55 @@
+/*
+ *  linux/arch/arm/kernel/dma-ebsa285.c
+ *
+ *  Copyright (C) 1998 Phil Blundell
+ *
+ * DMA functions specific to EBSA-285/CATS architectures
+ *
+ *  Changelog:
+ *   09-Nov-1998 RMK	Split out ISA DMA functions to dma-isa.c
+ *   17-Mar-1999 RMK	Allow any EBSA285-like architecture to have
+ *			ISA DMA controllers.
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/dma.h>
+#include <asm/io.h>
+
+#include <asm/mach/dma.h>
+#include <asm/hardware/dec21285.h>
+
+#if 0
+static int fb_dma_request(dmach_t channel, dma_t *dma)
+{
+	return -EINVAL;
+}
+
+static void fb_dma_enable(dmach_t channel, dma_t *dma)
+{
+}
+
+static void fb_dma_disable(dmach_t channel, dma_t *dma)
+{
+}
+
+static struct dma_ops fb_dma_ops = {
+	type:		"fb",
+	request:	fb_dma_request,
+	enable:		fb_dma_enable,
+	disable:	fb_dma_disable,
+};
+#endif
+
+void __init arch_dma_init(dma_t *dma)
+{
+#if 0
+	dma[_DC21285_DMA(0)].d_ops = &fb_dma_ops;
+	dma[_DC21285_DMA(1)].d_ops = &fb_dma_ops;
+#endif
+#ifdef CONFIG_ISA_DMA
+	if (footbridge_cfn_mode())
+		isa_init_dma(dma + _ISA_DMA(0));
+#endif
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/dma-isa.c linux-2.4.29-uc1/arch/armnommu/kernel/dma-isa.c
--- linux-2.4.29/arch/armnommu/kernel/dma-isa.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/dma-isa.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,202 @@
+/*
+ *  linux/arch/arm/kernel/dma-isa.c
+ *
+ *  Copyright (C) 1999-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  ISA DMA primitives
+ *  Taken from various sources, including:
+ *   linux/include/asm/dma.h: Defines for using and allocating dma channels.
+ *     Written by Hennus Bergman, 1992.
+ *     High DMA channel support & info by Hannu Savolainen and John Boyd,
+ *     Nov. 1992.
+ *   arch/arm/kernel/dma-ebsa285.c
+ *   Copyright (C) 1998 Phil Blundell
+ */
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/dma.h>
+#include <asm/io.h>
+
+#include <asm/mach/dma.h>
+
+#define ISA_DMA_MODE_READ	0x44
+#define ISA_DMA_MODE_WRITE	0x48
+#define ISA_DMA_MODE_CASCADE	0xc0
+#define ISA_DMA_AUTOINIT	0x10
+
+#define ISA_DMA_MASK		0
+#define ISA_DMA_MODE		1
+#define ISA_DMA_CLRFF		2
+#define ISA_DMA_PGHI		3
+#define ISA_DMA_PGLO		4
+#define ISA_DMA_ADDR		5
+#define ISA_DMA_COUNT		6
+
+static unsigned int isa_dma_port[8][7] = {
+	/* MASK   MODE   CLRFF  PAGE_HI PAGE_LO ADDR COUNT */
+	{  0x0a,  0x0b,  0x0c,  0x487,  0x087,  0x00, 0x01 },
+	{  0x0a,  0x0b,  0x0c,  0x483,  0x083,  0x02, 0x03 },
+	{  0x0a,  0x0b,  0x0c,  0x481,  0x081,  0x04, 0x05 },
+	{  0x0a,  0x0b,  0x0c,  0x482,  0x082,  0x06, 0x07 },
+	{  0xd4,  0xd6,  0xd8,  0x000,  0x000,  0xc0, 0xc2 },
+	{  0xd4,  0xd6,  0xd8,  0x48b,  0x08b,  0xc4, 0xc6 },
+	{  0xd4,  0xd6,  0xd8,  0x489,  0x089,  0xc8, 0xca },
+	{  0xd4,  0xd6,  0xd8,  0x48a,  0x08a,  0xcc, 0xce }
+};
+
+static int isa_get_dma_residue(dmach_t channel, dma_t *dma)
+{
+	unsigned int io_port = isa_dma_port[channel][ISA_DMA_COUNT];
+	int count;
+
+	count = 1 + inb(io_port);
+	count |= inb(io_port) << 8;
+
+	return channel < 4 ? count : (count << 1);
+}
+
+static void isa_enable_dma(dmach_t channel, dma_t *dma)
+{
+	if (dma->invalid) {
+		unsigned long address, length;
+		unsigned int mode, direction;
+
+		mode = channel & 3;
+		switch (dma->dma_mode & DMA_MODE_MASK) {
+		case DMA_MODE_READ:
+			mode |= ISA_DMA_MODE_READ;
+			direction = PCI_DMA_FROMDEVICE;
+			break;
+
+		case DMA_MODE_WRITE:
+			mode |= ISA_DMA_MODE_WRITE;
+			direction = PCI_DMA_TODEVICE;
+			break;
+
+		case DMA_MODE_CASCADE:
+			mode |= ISA_DMA_MODE_CASCADE;
+			direction = PCI_DMA_BIDIRECTIONAL;
+			break;
+
+		default:
+			break;
+		}
+
+		if (!dma->using_sg) {
+			/*
+			 * Cope with ISA-style drivers which expect cache
+			 * coherence.
+			 */
+			dma->buf.dma_address = pci_map_single(NULL,
+				dma->buf.address, dma->buf.length,
+				direction);
+		}
+
+		address = dma->buf.dma_address;
+		length  = dma->buf.length - 1;
+
+		outb(address >> 16, isa_dma_port[channel][ISA_DMA_PGLO]);
+		outb(address >> 24, isa_dma_port[channel][ISA_DMA_PGHI]);
+
+		if (channel >= 4) {
+			address >>= 1;
+			length >>= 1;
+		}
+
+		outb(0, isa_dma_port[channel][ISA_DMA_CLRFF]);
+
+		outb(address, isa_dma_port[channel][ISA_DMA_ADDR]);
+		outb(address >> 8, isa_dma_port[channel][ISA_DMA_ADDR]);
+
+		outb(length, isa_dma_port[channel][ISA_DMA_COUNT]);
+		outb(length >> 8, isa_dma_port[channel][ISA_DMA_COUNT]);
+
+		if (dma->dma_mode & DMA_AUTOINIT)
+			mode |= ISA_DMA_AUTOINIT;
+
+		outb(mode, isa_dma_port[channel][ISA_DMA_MODE]);
+		dma->invalid = 0;
+	}
+	outb(channel & 3, isa_dma_port[channel][ISA_DMA_MASK]);
+}
+
+static void isa_disable_dma(dmach_t channel, dma_t *dma)
+{
+	outb(channel | 4, isa_dma_port[channel][ISA_DMA_MASK]);
+}
+
+static struct dma_ops isa_dma_ops = {
+	type:		"ISA",
+	enable:		isa_enable_dma,
+	disable:	isa_disable_dma,
+	residue:	isa_get_dma_residue,
+};
+
+static struct resource dma_resources[] = {
+	{ "dma1",		0x0000, 0x000f },
+	{ "dma low page", 	0x0080, 0x008f },
+	{ "dma2",		0x00c0, 0x00df },
+	{ "dma high page",	0x0480, 0x048f }
+};
+
+void __init isa_init_dma(dma_t *dma)
+{
+	int dmac_found;
+
+	outb(0xff, 0x0d);
+	outb(0xff, 0xda);
+
+	outb(0x55, 0x00);
+	outb(0xaa, 0x00);
+
+	dmac_found = inb(0x00) == 0x55 && inb(0x00) == 0xaa;
+
+	if (dmac_found) {
+		int channel, i;
+
+		for (channel = 0; channel < 8; channel++) {
+			dma[channel].d_ops = &isa_dma_ops;
+			isa_disable_dma(channel, NULL);
+		}
+
+		outb(0x40, 0x0b);
+		outb(0x41, 0x0b);
+		outb(0x42, 0x0b);
+		outb(0x43, 0x0b);
+
+		outb(0xc0, 0xd6);
+		outb(0x41, 0xd6);
+		outb(0x42, 0xd6);
+		outb(0x43, 0xd6);
+
+		outb(0, 0xd4);
+
+		outb(0x10, 0x08);
+		outb(0x10, 0xd0);
+
+		/*
+		 * Is this correct?  According to my documentation, it
+		 * doesn't appear to be.  It should be:
+		 *  outb(0x3f, 0x40b); outb(0x3f, 0x4d6);
+		 */
+		outb(0x30, 0x40b);
+		outb(0x31, 0x40b);
+		outb(0x32, 0x40b);
+		outb(0x33, 0x40b);
+		outb(0x31, 0x4d6);
+		outb(0x32, 0x4d6);
+		outb(0x33, 0x4d6);
+
+		request_dma(DMA_ISA_CASCADE, "cascade");
+
+		for (i = 0; i < sizeof(dma_resources) / sizeof(dma_resources[0]); i++)
+			request_resource(&ioport_resource, dma_resources + i);
+	}
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/dma-rpc.c linux-2.4.29-uc1/arch/armnommu/kernel/dma-rpc.c
--- linux-2.4.29/arch/armnommu/kernel/dma-rpc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/dma-rpc.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,371 @@
+/*
+ *  linux/arch/arm/kernel/dma-rpc.c
+ *
+ *  Copyright (C) 1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  DMA functions specific to RiscPC architecture
+ */
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/page.h>
+#include <asm/dma.h>
+#include <asm/fiq.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/uaccess.h>
+
+#include <asm/mach/dma.h>
+#include <asm/hardware/iomd.h>
+
+#if 0
+typedef enum {
+	dma_size_8	= 1,
+	dma_size_16	= 2,
+	dma_size_32	= 4,
+	dma_size_128	= 16
+} dma_size_t;
+
+typedef struct {
+	dma_size_t	transfersize;
+} dma_t;
+#endif
+
+#define TRANSFER_SIZE	2
+
+#define CURA	(0)
+#define ENDA	(IOMD_IO0ENDA - IOMD_IO0CURA)
+#define CURB	(IOMD_IO0CURB - IOMD_IO0CURA)
+#define ENDB	(IOMD_IO0ENDB - IOMD_IO0CURA)
+#define CR	(IOMD_IO0CR - IOMD_IO0CURA)
+#define ST	(IOMD_IO0ST - IOMD_IO0CURA)
+
+#define state_prog_a	0
+#define state_wait_a	1
+#define state_wait_b	2
+
+static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma)
+{
+	unsigned long end, offset, flags = 0;
+
+	if (dma->sg) {
+		sg->dma_address = dma->sg->dma_address;
+		offset = sg->dma_address & ~PAGE_MASK;
+
+		end = offset + dma->sg->length;
+
+		if (end > PAGE_SIZE)
+			end = PAGE_SIZE;
+
+		if (offset + (int) TRANSFER_SIZE > end)
+			flags |= DMA_END_L;
+
+		sg->length = end - TRANSFER_SIZE;
+
+		dma->sg->length -= end - offset;
+		dma->sg->dma_address += end - offset;
+
+		if (dma->sg->length == 0) {
+			if (dma->sgcount > 1) {
+				dma->sg++;
+				dma->sgcount--;
+			} else {
+				dma->sg = NULL;
+				flags |= DMA_END_S;
+			}
+		}
+	} else {
+		flags = DMA_END_S | DMA_END_L;
+		sg->dma_address = 0;
+		sg->length = 0;
+	}
+
+	sg->length |= flags;
+}
+
+static inline void iomd_setup_dma_a(struct scatterlist *sg, dma_t *dma)
+{
+	iomd_writel(sg->dma_address, dma->dma_base + CURA);
+	iomd_writel(sg->length, dma->dma_base + ENDA);
+}
+
+static inline void iomd_setup_dma_b(struct scatterlist *sg, dma_t *dma)
+{
+	iomd_writel(sg->dma_address, dma->dma_base + CURB);
+	iomd_writel(sg->length, dma->dma_base + ENDB);
+}
+
+static void iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
+{
+	dma_t *dma = (dma_t *)dev_id;
+	unsigned int status = 0, no_buffer = dma->sg == NULL;
+
+	do {
+		switch (dma->state) {
+		case state_prog_a:
+			iomd_get_next_sg(&dma->cur_sg, dma);
+			iomd_setup_dma_a(&dma->cur_sg, dma);
+			dma->state = state_wait_a;
+
+		case state_wait_a:
+			status = iomd_readb(dma->dma_base + ST);
+			switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) {
+			case DMA_ST_OFL|DMA_ST_INT:
+				iomd_get_next_sg(&dma->cur_sg, dma);
+				iomd_setup_dma_a(&dma->cur_sg, dma);
+				break;
+
+			case DMA_ST_INT:
+				iomd_get_next_sg(&dma->cur_sg, dma);
+				iomd_setup_dma_b(&dma->cur_sg, dma);
+				dma->state = state_wait_b;
+				break;
+
+			case DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB:
+				iomd_setup_dma_b(&dma->cur_sg, dma);
+				dma->state = state_wait_b;
+				break;
+			}
+			break;
+
+		case state_wait_b:
+			status = iomd_readb(dma->dma_base + ST);
+			switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) {
+			case DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB:
+				iomd_get_next_sg(&dma->cur_sg, dma);
+				iomd_setup_dma_b(&dma->cur_sg, dma);
+				break;
+
+			case DMA_ST_INT|DMA_ST_AB:
+				iomd_get_next_sg(&dma->cur_sg, dma);
+				iomd_setup_dma_a(&dma->cur_sg, dma);
+				dma->state = state_wait_a;
+				break;
+
+			case DMA_ST_OFL|DMA_ST_INT:
+				iomd_setup_dma_a(&dma->cur_sg, dma);
+				dma->state = state_wait_a;
+				break;
+			}
+			break;
+		}
+	} while (dma->sg && (status & DMA_ST_INT));
+
+	if (no_buffer)
+		disable_irq(irq);
+}
+
+static int iomd_request_dma(dmach_t channel, dma_t *dma)
+{
+	return request_irq(dma->dma_irq, iomd_dma_handle,
+			   SA_INTERRUPT, dma->device_id, dma);
+}
+
+static void iomd_free_dma(dmach_t channel, dma_t *dma)
+{
+	free_irq(dma->dma_irq, dma);
+}
+
+static void iomd_enable_dma(dmach_t channel, dma_t *dma)
+{
+	unsigned long dma_base = dma->dma_base;
+	unsigned int ctrl = TRANSFER_SIZE | DMA_CR_E;
+
+	if (dma->invalid) {
+		dma->invalid = 0;
+
+		/*
+		 * Cope with ISA-style drivers which expect cache
+		 * coherence.
+		 */
+		if (!dma->using_sg) {
+			dma->buf.dma_address = pci_map_single(NULL,
+				dma->buf.address, dma->buf.length,
+				dma->dma_mode == DMA_MODE_READ ?
+				PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+		}
+
+		iomd_writeb(DMA_CR_C, dma_base + CR);
+		dma->state = state_prog_a;
+	}
+		
+	if (dma->dma_mode == DMA_MODE_READ)
+		ctrl |= DMA_CR_D;
+
+	iomd_writeb(ctrl, dma_base + CR);
+	enable_irq(dma->dma_irq);
+}
+
+static void iomd_disable_dma(dmach_t channel, dma_t *dma)
+{
+	unsigned long dma_base = dma->dma_base;
+	unsigned int ctrl;
+
+	disable_irq(dma->dma_irq);
+	ctrl = iomd_readb(dma_base + CR);
+	iomd_writeb(ctrl & ~DMA_CR_E, dma_base + CR);
+}
+
+static int iomd_set_dma_speed(dmach_t channel, dma_t *dma, int cycle)
+{
+	int tcr, speed;
+
+	if (cycle < 188)
+		speed = 3;
+	else if (cycle <= 250)
+		speed = 2;
+	else if (cycle < 438)
+		speed = 1;
+	else
+		speed = 0;
+
+	tcr = iomd_readb(IOMD_DMATCR);
+	speed &= 3;
+
+	switch (channel) {
+	case DMA_0:
+		tcr = (tcr & ~0x03) | speed;
+		break;
+
+	case DMA_1:
+		tcr = (tcr & ~0x0c) | (speed << 2);
+		break;
+
+	case DMA_2:
+		tcr = (tcr & ~0x30) | (speed << 4);
+		break;
+
+	case DMA_3:
+		tcr = (tcr & ~0xc0) | (speed << 6);
+		break;
+
+	default:
+		break;
+	}
+
+	iomd_writeb(tcr, IOMD_DMATCR);
+
+	return speed;
+}
+
+static struct dma_ops iomd_dma_ops = {
+	type:		"IOMD",
+	request:	iomd_request_dma,
+	free:		iomd_free_dma,
+	enable:		iomd_enable_dma,
+	disable:	iomd_disable_dma,
+	setspeed:	iomd_set_dma_speed,
+};
+
+static struct fiq_handler fh = {
+	name: "floppydma"
+};
+
+static void floppy_enable_dma(dmach_t channel, dma_t *dma)
+{
+	void *fiqhandler_start;
+	unsigned int fiqhandler_length;
+	struct pt_regs regs;
+
+	if (dma->dma_mode == DMA_MODE_READ) {
+		extern unsigned char floppy_fiqin_start, floppy_fiqin_end;
+		fiqhandler_start = &floppy_fiqin_start;
+		fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start;
+	} else {
+		extern unsigned char floppy_fiqout_start, floppy_fiqout_end;
+		fiqhandler_start = &floppy_fiqout_start;
+		fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
+	}
+
+	regs.ARM_r9  = dma->buf.length;
+	regs.ARM_r10 = (unsigned long)dma->buf.address;
+	regs.ARM_fp  = FLOPPYDMA_BASE;
+
+	if (claim_fiq(&fh)) {
+		printk("floppydma: couldn't claim FIQ.\n");
+		return;
+	}
+
+	set_fiq_handler(fiqhandler_start, fiqhandler_length);
+	set_fiq_regs(&regs);
+	enable_fiq(dma->dma_irq);
+}
+
+static void floppy_disable_dma(dmach_t channel, dma_t *dma)
+{
+	disable_fiq(dma->dma_irq);
+	release_fiq(&fh);
+}
+
+static int floppy_get_residue(dmach_t channel, dma_t *dma)
+{
+	struct pt_regs regs;
+	get_fiq_regs(&regs);
+	return regs.ARM_r9;
+}
+
+static struct dma_ops floppy_dma_ops = {
+	type:		"FIQDMA",
+	enable:		floppy_enable_dma,
+	disable:	floppy_disable_dma,
+	residue:	floppy_get_residue,
+};
+
+/*
+ * This is virtual DMA - we don't need anything here.
+ */
+static void sound_enable_disable_dma(dmach_t channel, dma_t *dma)
+{
+}
+
+static struct dma_ops sound_dma_ops = {
+	type:		"VIRTUAL",
+	enable:		sound_enable_disable_dma,
+	disable:	sound_enable_disable_dma,
+};
+
+void __init arch_dma_init(dma_t *dma)
+{
+	iomd_writeb(0, IOMD_IO0CR);
+	iomd_writeb(0, IOMD_IO1CR);
+	iomd_writeb(0, IOMD_IO2CR);
+	iomd_writeb(0, IOMD_IO3CR);
+
+	iomd_writeb(0xa0, IOMD_DMATCR);
+
+	dma[DMA_0].dma_base		= IOMD_IO0CURA;
+	dma[DMA_0].dma_irq		= IRQ_DMA0;
+	dma[DMA_0].d_ops		= &iomd_dma_ops;
+	dma[DMA_1].dma_base		= IOMD_IO1CURA;
+	dma[DMA_1].dma_irq		= IRQ_DMA1;
+	dma[DMA_1].d_ops		= &iomd_dma_ops;
+	dma[DMA_2].dma_base		= IOMD_IO2CURA;
+	dma[DMA_2].dma_irq		= IRQ_DMA2;
+	dma[DMA_2].d_ops		= &iomd_dma_ops;
+	dma[DMA_3].dma_base		= IOMD_IO3CURA;
+	dma[DMA_3].dma_irq		= IRQ_DMA3;
+	dma[DMA_3].d_ops		= &iomd_dma_ops;
+	dma[DMA_S0].dma_base		= IOMD_SD0CURA;
+	dma[DMA_S0].dma_irq		= IRQ_DMAS0;
+	dma[DMA_S0].d_ops		= &iomd_dma_ops;
+	dma[DMA_S1].dma_base		= IOMD_SD1CURA;
+	dma[DMA_S1].dma_irq		= IRQ_DMAS1;
+	dma[DMA_S1].d_ops		= &iomd_dma_ops;
+	dma[DMA_VIRTUAL_FLOPPY].dma_irq	= FIQ_FLOPPYDATA;
+	dma[DMA_VIRTUAL_FLOPPY].d_ops	= &floppy_dma_ops;
+	dma[DMA_VIRTUAL_SOUND].d_ops	= &sound_dma_ops;
+
+	/*
+	 * Setup DMA channels 2,3 to be for podules
+	 * and channels 0,1 for internal devices
+	 */
+	iomd_writeb(DMA_EXT_IO3|DMA_EXT_IO2, IOMD_DMAEXT);
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/ecard.c linux-2.4.29-uc1/arch/armnommu/kernel/ecard.c
--- linux-2.4.29/arch/armnommu/kernel/ecard.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/ecard.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,1097 @@
+/*
+ *  linux/arch/arm/kernel/ecard.c
+ *
+ *  Copyright 1995-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Find all installed expansion cards, and handle interrupts from them.
+ *
+ *  Created from information from Acorns RiscOS3 PRMs
+ *
+ *  08-Dec-1996	RMK	Added code for the 9'th expansion card - the ether
+ *			podule slot.
+ *  06-May-1997	RMK	Added blacklist for cards whose loader doesn't work.
+ *  12-Sep-1997	RMK	Created new handling of interrupt enables/disables
+ *			- cards can now register their own routine to control
+ *			interrupts (recommended).
+ *  29-Sep-1997	RMK	Expansion card interrupt hardware not being re-enabled
+ *			on reset from Linux. (Caused cards not to respond
+ *			under RiscOS without hard reset).
+ *  15-Feb-1998	RMK	Added DMA support
+ *  12-Sep-1998	RMK	Added EASI support
+ *  10-Jan-1999	RMK	Run loaders in a simulated RISC OS environment.
+ *  17-Apr-1999	RMK	Support for EASI Type C cycles.
+ */
+#define ECARD_C
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/notifier.h>
+#include <linux/init.h>
+
+#include <asm/dma.h>
+#include <asm/ecard.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pgalloc.h>
+#include <asm/mmu_context.h>
+#include <asm/mach/irq.h>
+
+#ifndef CONFIG_ARCH_RPC
+#define HAVE_EXPMASK
+#endif
+
+enum req {
+	req_readbytes,
+	req_reset_all
+};
+
+struct ecard_request {
+	enum req	req;
+	ecard_t		*ec;
+	unsigned int	address;
+	unsigned int	length;
+	unsigned int	use_loader;
+	void		*buffer;
+};
+
+struct expcard_blacklist {
+	unsigned short	 manufacturer;
+	unsigned short	 product;
+	const char	*type;
+};
+
+static ecard_t *cards;
+static ecard_t *slot_to_expcard[MAX_ECARDS];
+static unsigned int ectcr;
+#ifdef HAS_EXPMASK
+static unsigned int have_expmask;
+#endif
+
+/* List of descriptions of cards which don't have an extended
+ * identification, or chunk directories containing a description.
+ */
+static struct expcard_blacklist __initdata blacklist[] = {
+	{ MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1" }
+};
+
+asmlinkage extern int
+ecard_loader_reset(volatile unsigned char *pa, loader_t loader);
+asmlinkage extern int
+ecard_loader_read(int off, volatile unsigned char *pa, loader_t loader);
+extern int setup_arm_irq(int, struct irqaction *);
+extern void do_ecard_IRQ(int, struct pt_regs *);
+
+
+static void
+ecard_irq_noexpmask(int intr_no, void *dev_id, struct pt_regs *regs);
+
+static struct irqaction irqexpansioncard = {
+	ecard_irq_noexpmask, SA_INTERRUPT, 0, "expansion cards", NULL, NULL
+};
+
+static inline unsigned short
+ecard_getu16(unsigned char *v)
+{
+	return v[0] | v[1] << 8;
+}
+
+static inline signed long
+ecard_gets24(unsigned char *v)
+{
+	return v[0] | v[1] << 8 | v[2] << 16 | ((v[2] & 0x80) ? 0xff000000 : 0);
+}
+
+static inline ecard_t *
+slot_to_ecard(unsigned int slot)
+{
+	return slot < MAX_ECARDS ? slot_to_expcard[slot] : NULL;
+}
+
+/* ===================== Expansion card daemon ======================== */
+/*
+ * Since the loader programs on the expansion cards need to be run
+ * in a specific environment, create a separate task with this
+ * environment up, and pass requests to this task as and when we
+ * need to.
+ *
+ * This should allow 99% of loaders to be called from Linux.
+ *
+ * From a security standpoint, we trust the card vendors.  This
+ * may be a misplaced trust.
+ */
+#define BUS_ADDR(x) ((((unsigned long)(x)) << 2) + IO_BASE)
+#define POD_INT_ADDR(x)	((volatile unsigned char *)\
+			 ((BUS_ADDR((x)) - IO_BASE) + IO_START))
+
+static inline void ecard_task_reset(void)
+{
+	ecard_t *ec;
+
+	for (ec = cards; ec; ec = ec->next)
+		if (ec->loader)
+			ecard_loader_reset(POD_INT_ADDR(ec->podaddr),
+					   ec->loader);
+}
+
+static void
+ecard_task_readbytes(struct ecard_request *req)
+{
+	unsigned char *buf = (unsigned char *)req->buffer;
+	volatile unsigned char *base_addr =
+		(volatile unsigned char *)POD_INT_ADDR(req->ec->podaddr);
+	unsigned int len = req->length;
+	unsigned int off = req->address;
+
+	if (req->ec->slot_no == 8) {
+		/*
+		 * The card maintains an index which increments the address
+		 * into a 4096-byte page on each access.  We need to keep
+		 * track of the counter.
+		 */
+		static unsigned int index;
+		unsigned int page;
+
+		page = (off >> 12) * 4;
+		if (page > 256 * 4)
+			return;
+
+		off &= 4095;
+
+		/*
+		 * If we are reading offset 0, or our current index is
+		 * greater than the offset, reset the hardware index counter.
+		 */
+		if (off == 0 || index > off) {
+			*base_addr = 0;
+			index = 0;
+		}
+
+		/*
+		 * Increment the hardware index counter until we get to the
+		 * required offset.  The read bytes are discarded.
+		 */
+		while (index < off) {
+			unsigned char byte;
+			byte = base_addr[page];
+			index += 1;
+		}
+
+		while (len--) {
+			*buf++ = base_addr[page];
+			index += 1;
+		}
+	} else {
+
+		if (!req->use_loader || !req->ec->loader) {
+			off *= 4;
+			while (len--) {
+				*buf++ = base_addr[off];
+				off += 4;
+			}
+		} else {
+			while(len--) {
+				/*
+				 * The following is required by some
+				 * expansion card loader programs.
+				 */
+				*(unsigned long *)0x108 = 0;
+				*buf++ = ecard_loader_read(off++, base_addr,
+							   req->ec->loader);
+			}
+		}
+	}
+
+}
+
+static void ecard_do_request(struct ecard_request *req)
+{
+	switch (req->req) {
+	case req_readbytes:
+		ecard_task_readbytes(req);
+		break;
+
+	case req_reset_all:
+		ecard_task_reset();
+		break;
+	}
+}
+
+#ifdef CONFIG_CPU_32
+static pid_t ecard_pid;
+static wait_queue_head_t ecard_wait;
+static struct ecard_request *ecard_req;
+
+static DECLARE_MUTEX_LOCKED(ecard_done_sem);
+
+/*
+ * Set up the expansion card daemon's page tables.
+ */
+static void ecard_init_pgtables(struct mm_struct *mm)
+{
+	/* We want to set up the page tables for the following mapping:
+	 *  Virtual	Physical
+	 *  0x03000000	0x03000000
+	 *  0x03010000	unmapped
+	 *  0x03210000	0x03210000
+	 *  0x03400000	unmapped
+	 *  0x08000000	0x08000000
+	 *  0x10000000	unmapped
+	 *
+	 * FIXME: we don't follow this 100% yet.
+	 */
+	pgd_t *src_pgd, *dst_pgd;
+	unsigned int dst_addr = IO_START;
+
+	src_pgd = pgd_offset(mm, IO_BASE);
+	dst_pgd = pgd_offset(mm, dst_addr);
+
+	while (dst_addr < IO_START + IO_SIZE) {
+		*dst_pgd++ = *src_pgd++;
+		dst_addr += PGDIR_SIZE;
+	}
+
+	dst_addr = EASI_START;
+	src_pgd = pgd_offset(mm, EASI_BASE);
+	dst_pgd = pgd_offset(mm, dst_addr);
+
+	while (dst_addr < EASI_START + EASI_SIZE) {
+		*dst_pgd++ = *src_pgd++;
+		dst_addr += PGDIR_SIZE;
+	}
+
+	flush_tlb_range(mm, IO_START, IO_START + IO_SIZE);
+	flush_tlb_range(mm, EASI_START, EASI_START + EASI_SIZE);
+}
+
+static int ecard_init_mm(void)
+{
+	struct mm_struct * mm = mm_alloc();
+	struct mm_struct *active_mm = current->active_mm;
+
+	if (!mm)
+		return -ENOMEM;
+
+	current->mm = mm;
+	current->active_mm = mm;
+	activate_mm(active_mm, mm);
+	mmdrop(active_mm);
+	ecard_init_pgtables(mm);
+	return 0;
+}
+
+static int
+ecard_task(void * unused)
+{
+	struct task_struct *tsk = current;
+
+	/*
+	 * We don't want /any/ signals, not even SIGKILL
+	 */
+	sigfillset(&tsk->blocked);
+	sigemptyset(&tsk->pending.signal);
+	recalc_sigpending(tsk);
+	strcpy(tsk->comm, "kecardd");
+	daemonize();
+
+	/*
+	 * Allocate a mm.  We're not a lazy-TLB kernel task since we need
+	 * to set page table entries where the user space would be.  Note
+	 * that this also creates the page tables.  Failure is not an
+	 * option here.
+	 */
+	if (ecard_init_mm())
+		panic("kecardd: unable to alloc mm\n");
+
+	while (1) {
+		struct ecard_request *req;
+
+		do {
+			req = xchg(&ecard_req, NULL);
+
+			if (req == NULL) {
+				sigemptyset(&tsk->pending.signal);
+				interruptible_sleep_on(&ecard_wait);
+			}
+		} while (req == NULL);
+
+		ecard_do_request(req);
+		up(&ecard_done_sem);
+	}
+}
+
+/*
+ * Wake the expansion card daemon to action our request.
+ *
+ * FIXME: The test here is not sufficient to detect if the
+ * kcardd is running.
+ */
+static void
+ecard_call(struct ecard_request *req)
+{
+	/*
+	 * Make sure we have a context that is able to sleep.
+	 */
+	if (current == &init_task || in_interrupt())
+		BUG();
+
+	if (ecard_pid <= 0)
+		ecard_pid = kernel_thread(ecard_task, NULL,
+				CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+
+	ecard_req = req;
+	wake_up(&ecard_wait);
+
+	/*
+	 * Now wait for kecardd to run.
+	 */
+	down(&ecard_done_sem);
+}
+#else
+/*
+ * On 26-bit processors, we don't need the kcardd thread to access the
+ * expansion card loaders.  We do it directly.
+ */
+#define ecard_call(req)	ecard_do_request(req)
+#endif
+
+/* ======================= Mid-level card control ===================== */
+
+/*
+ * This function is responsible for resetting the expansion cards to a
+ * sensible state immediately prior to rebooting the system.  This function
+ * has process state (keventd), so we can sleep.
+ *
+ * Possible "val" values here:
+ *  SYS_RESTART   -  restarting system
+ *  SYS_HALT      - halting system
+ *  SYS_POWER_OFF - powering down system
+ *
+ * We ignore all calls, unless it is a SYS_RESTART call - power down/halts
+ * will be followed by a SYS_RESTART if ctrl-alt-del is pressed again.
+ */
+static int ecard_reboot(struct notifier_block *me, unsigned long val, void *v)
+{
+	struct ecard_request req;
+
+	if (val != SYS_RESTART)
+		return 0;
+
+	/*
+	 * Disable the expansion card interrupt
+	 */
+	disable_irq(IRQ_EXPANSIONCARD);
+
+	/*
+	 * If we have any expansion card loader code which will handle
+	 * the reset for us, call it now.
+	 */
+	req.req = req_reset_all;
+	ecard_call(&req);
+
+	/*
+	 * Disable the expansion card interrupt again, just to be sure.
+	 */
+	disable_irq(IRQ_EXPANSIONCARD);
+
+	/*
+	 * Finally, reset the expansion card interrupt mask to
+	 * all enable (RISC OS doesn't set this)
+	 */
+#ifdef HAS_EXPMASK
+	have_expmask = ~0;
+	__raw_writeb(have_expmask, EXPMASK_ENABLE);
+#endif
+	return 0;
+}
+
+static struct notifier_block ecard_reboot_notifier = {
+	notifier_call:	ecard_reboot,
+};
+
+
+
+static void
+ecard_readbytes(void *addr, ecard_t *ec, int off, int len, int useld)
+{
+	struct ecard_request req;
+
+	req.req		= req_readbytes;
+	req.ec		= ec;
+	req.address	= off;
+	req.length	= len;
+	req.use_loader	= useld;
+	req.buffer	= addr;
+
+	ecard_call(&req);
+}
+
+int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num)
+{
+	struct ex_chunk_dir excd;
+	int index = 16;
+	int useld = 0;
+
+	if (!ec->cid.cd)
+		return 0;
+
+	while(1) {
+		ecard_readbytes(&excd, ec, index, 8, useld);
+		index += 8;
+		if (c_id(&excd) == 0) {
+			if (!useld && ec->loader) {
+				useld = 1;
+				index = 0;
+				continue;
+			}
+			return 0;
+		}
+		if (c_id(&excd) == 0xf0) { /* link */
+			index = c_start(&excd);
+			continue;
+		}
+		if (c_id(&excd) == 0x80) { /* loader */
+			if (!ec->loader) {
+				ec->loader = (loader_t)kmalloc(c_len(&excd),
+							       GFP_KERNEL);
+				if (ec->loader)
+					ecard_readbytes(ec->loader, ec,
+							(int)c_start(&excd),
+							c_len(&excd), useld);
+				else
+					return 0;
+			}
+			continue;
+		}
+		if (c_id(&excd) == id && num-- == 0)
+			break;
+	}
+
+	if (c_id(&excd) & 0x80) {
+		switch (c_id(&excd) & 0x70) {
+		case 0x70:
+			ecard_readbytes((unsigned char *)excd.d.string, ec,
+					(int)c_start(&excd), c_len(&excd),
+					useld);
+			break;
+		case 0x00:
+			break;
+		}
+	}
+	cd->start_offset = c_start(&excd);
+	memcpy(cd->d.string, excd.d.string, 256);
+	return 1;
+}
+
+/* ======================= Interrupt control ============================ */
+
+static void ecard_def_irq_enable(ecard_t *ec, int irqnr)
+{
+#ifdef HAS_EXPMASK
+	if (irqnr < 4 && have_expmask) {
+		have_expmask |= 1 << irqnr;
+		__raw_writeb(have_expmask, EXPMASK_ENABLE);
+	}
+#endif
+}
+
+static void ecard_def_irq_disable(ecard_t *ec, int irqnr)
+{
+#ifdef HAS_EXPMASK
+	if (irqnr < 4 && have_expmask) {
+		have_expmask &= ~(1 << irqnr);
+		__raw_writeb(have_expmask, EXPMASK_ENABLE);
+	}
+#endif
+}
+
+static int ecard_def_irq_pending(ecard_t *ec)
+{
+	return !ec->irqmask || ec->irqaddr[0] & ec->irqmask;
+}
+
+static void ecard_def_fiq_enable(ecard_t *ec, int fiqnr)
+{
+	panic("ecard_def_fiq_enable called - impossible");
+}
+
+static void ecard_def_fiq_disable(ecard_t *ec, int fiqnr)
+{
+	panic("ecard_def_fiq_disable called - impossible");
+}
+
+static int ecard_def_fiq_pending(ecard_t *ec)
+{
+	return !ec->fiqmask || ec->fiqaddr[0] & ec->fiqmask;
+}
+
+static expansioncard_ops_t ecard_default_ops = {
+	ecard_def_irq_enable,
+	ecard_def_irq_disable,
+	ecard_def_irq_pending,
+	ecard_def_fiq_enable,
+	ecard_def_fiq_disable,
+	ecard_def_fiq_pending
+};
+
+/*
+ * Enable and disable interrupts from expansion cards.
+ * (interrupts are disabled for these functions).
+ *
+ * They are not meant to be called directly, but via enable/disable_irq.
+ */
+static void ecard_enableirq(unsigned int irqnr)
+{
+	ecard_t *ec = slot_to_ecard(irqnr - 32);
+
+	if (ec) {
+		if (!ec->ops)
+			ec->ops = &ecard_default_ops;
+
+		if (ec->claimed && ec->ops->irqenable)
+			ec->ops->irqenable(ec, irqnr);
+		else
+			printk(KERN_ERR "ecard: rejecting request to "
+				"enable IRQs for %d\n", irqnr);
+	}
+}
+
+static void ecard_disableirq(unsigned int irqnr)
+{
+	ecard_t *ec = slot_to_ecard(irqnr - 32);
+
+	if (ec) {
+		if (!ec->ops)
+			ec->ops = &ecard_default_ops;
+
+		if (ec->ops && ec->ops->irqdisable)
+			ec->ops->irqdisable(ec, irqnr);
+	}
+}
+
+void ecard_enablefiq(unsigned int fiqnr)
+{
+	ecard_t *ec = slot_to_ecard(fiqnr);
+
+	if (ec) {
+		if (!ec->ops)
+			ec->ops = &ecard_default_ops;
+
+		if (ec->claimed && ec->ops->fiqenable)
+			ec->ops->fiqenable(ec, fiqnr);
+		else
+			printk(KERN_ERR "ecard: rejecting request to "
+				"enable FIQs for %d\n", fiqnr);
+	}
+}
+
+void ecard_disablefiq(unsigned int fiqnr)
+{
+	ecard_t *ec = slot_to_ecard(fiqnr);
+
+	if (ec) {
+		if (!ec->ops)
+			ec->ops = &ecard_default_ops;
+
+		if (ec->ops->fiqdisable)
+			ec->ops->fiqdisable(ec, fiqnr);
+	}
+}
+
+static void
+ecard_dump_irq_state(ecard_t *ec)
+{
+	printk("  %d: %sclaimed, ",
+	       ec->slot_no,
+	       ec->claimed ? "" : "not ");
+
+	if (ec->ops && ec->ops->irqpending &&
+	    ec->ops != &ecard_default_ops)
+		printk("irq %spending\n",
+		       ec->ops->irqpending(ec) ? "" : "not ");
+	else
+		printk("irqaddr %p, mask = %02X, status = %02X\n",
+		       ec->irqaddr, ec->irqmask, *ec->irqaddr);
+}
+
+static void
+ecard_check_lockup(void)
+{
+	static int last, lockup;
+	ecard_t *ec;
+
+	/*
+	 * If the timer interrupt has not run since the last million
+	 * unrecognised expansion card interrupts, then there is
+	 * something seriously wrong.  Disable the expansion card
+	 * interrupts so at least we can continue.
+	 *
+	 * Maybe we ought to start a timer to re-enable them some time
+	 * later?
+	 */
+	if (last == jiffies) {
+		lockup += 1;
+		if (lockup > 1000000) {
+			printk(KERN_ERR "\nInterrupt lockup detected - "
+			       "disabling all expansion card interrupts\n");
+
+			disable_irq(IRQ_EXPANSIONCARD);
+
+			printk("Expansion card IRQ state:\n");
+
+			for (ec = cards; ec; ec = ec->next)
+				ecard_dump_irq_state(ec);
+		}
+	} else
+		lockup = 0;
+
+	/*
+	 * If we did not recognise the source of this interrupt,
+	 * warn the user, but don't flood the user with these messages.
+	 */
+	if (!last || time_after(jiffies, last + 5*HZ)) {
+		last = jiffies;
+		printk(KERN_WARNING "Unrecognised interrupt from backplane\n");
+	}
+}
+
+static void
+ecard_irq_noexpmask(int intr_no, void *dev_id, struct pt_regs *regs)
+{
+	ecard_t *ec;
+	int called = 0;
+
+	for (ec = cards; ec; ec = ec->next) {
+		int pending;
+
+		if (!ec->claimed || ec->irq == NO_IRQ || ec->slot_no == 8)
+			continue;
+
+		if (ec->ops && ec->ops->irqpending)
+			pending = ec->ops->irqpending(ec);
+		else
+			pending = ecard_default_ops.irqpending(ec);
+
+		if (pending) {
+			do_ecard_IRQ(ec->irq, regs);
+			called ++;
+		}
+	}
+	cli();
+
+	if (called == 0)
+		ecard_check_lockup();
+}
+
+#ifdef HAS_EXPMASK
+static unsigned char priority_masks[] =
+{
+	0xf0, 0xf1, 0xf3, 0xf7, 0xff, 0xff, 0xff, 0xff
+};
+
+static unsigned char first_set[] =
+{
+	0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+	0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00
+};
+
+static void
+ecard_irq_expmask(int intr_no, void *dev_id, struct pt_regs *regs)
+{
+	const unsigned int statusmask = 15;
+	unsigned int status;
+
+	status = __raw_readb(EXPMASK_STATUS) & statusmask;
+	if (status) {
+		unsigned int slot;
+		ecard_t *ec;
+again:
+		slot = first_set[status];
+		ec = slot_to_ecard(slot);
+		if (ec->claimed) {
+			unsigned int oldexpmask;
+			/*
+			 * this ugly code is so that we can operate a
+			 * prioritorising system:
+			 *
+			 * Card 0 	highest priority
+			 * Card 1
+			 * Card 2
+			 * Card 3	lowest priority
+			 *
+			 * Serial cards should go in 0/1, ethernet/scsi in 2/3
+			 * otherwise you will lose serial data at high speeds!
+			 */
+			oldexpmask = have_expmask;
+			have_expmask &= priority_masks[slot];
+			__raw_writeb(have_expmask, EXPMASK_ENABLE);
+			sti();
+			do_ecard_IRQ(ec->irq, regs);
+			cli();
+			have_expmask = oldexpmask;
+			__raw_writeb(have_expmask, EXPMASK_ENABLE);
+			status = __raw_readb(EXPMASK_STATUS) & statusmask;
+			if (status)
+				goto again;
+		} else {
+			printk(KERN_WARNING "card%d: interrupt from unclaimed "
+			       "card???\n", slot);
+			have_expmask &= ~(1 << slot);
+			__raw_writeb(have_expmask, EXPMASK_ENABLE);
+		}
+	} else
+		printk(KERN_WARNING "Wild interrupt from backplane (masks)\n");
+}
+
+static void __init
+ecard_probeirqhw(void)
+{
+	ecard_t *ec;
+	int found;
+
+	__raw_writeb(0x00, EXPMASK_ENABLE);
+	__raw_writeb(0xff, EXPMASK_STATUS);
+	found = (__raw_readb(EXPMASK_STATUS) & 15) == 0;
+	__raw_writeb(0xff, EXPMASK_ENABLE);
+
+	if (!found)
+		return;
+
+	printk(KERN_DEBUG "Expansion card interrupt "
+	       "management hardware found\n");
+
+	irqexpansioncard.handler = ecard_irq_expmask;
+
+	/* for each card present, set a bit to '1' */
+	have_expmask = 0x80000000;
+
+	for (ec = cards; ec; ec = ec->next)
+		have_expmask |= 1 << ec->slot_no;
+
+	__raw_writeb(have_expmask, EXPMASK_ENABLE);
+}
+#else
+#define ecard_probeirqhw()
+#endif
+
+#ifndef IO_EC_MEMC8_BASE
+#define IO_EC_MEMC8_BASE 0
+#endif
+
+unsigned int ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
+{
+	unsigned long address = 0;
+	int slot = ec->slot_no;
+
+	if (ec->slot_no == 8)
+		return IO_EC_MEMC8_BASE;
+
+	ectcr &= ~(1 << slot);
+
+	switch (type) {
+	case ECARD_MEMC:
+		if (slot < 4)
+			address = IO_EC_MEMC_BASE + (slot << 12);
+		break;
+
+	case ECARD_IOC:
+		if (slot < 4)
+			address = IO_EC_IOC_BASE + (slot << 12);
+#ifdef IO_EC_IOC4_BASE
+		else
+			address = IO_EC_IOC4_BASE + ((slot - 4) << 12);
+#endif
+		if (address)
+			address +=  speed << 17;
+		break;
+
+#ifdef IO_EC_EASI_BASE
+	case ECARD_EASI:
+		address = IO_EC_EASI_BASE + (slot << 22);
+		if (speed == ECARD_FAST)
+			ectcr |= 1 << slot;
+		break;
+#endif
+	default:
+		break;
+	}
+
+#ifdef IOMD_ECTCR
+	iomd_writeb(ectcr, IOMD_ECTCR);
+#endif
+	return address;
+}
+
+static int ecard_prints(char *buffer, ecard_t *ec)
+{
+	char *start = buffer;
+
+	buffer += sprintf(buffer, "  %d: %s ", ec->slot_no,
+			  ec->type == ECARD_EASI ? "EASI" : "    ");
+
+	if (ec->cid.id == 0) {
+		struct in_chunk_dir incd;
+
+		buffer += sprintf(buffer, "[%04X:%04X] ",
+			ec->cid.manufacturer, ec->cid.product);
+
+		if (!ec->card_desc && ec->cid.cd &&
+		    ecard_readchunk(&incd, ec, 0xf5, 0)) {
+			ec->card_desc = kmalloc(strlen(incd.d.string)+1, GFP_KERNEL);
+
+			if (ec->card_desc)
+				strcpy((char *)ec->card_desc, incd.d.string);
+		}
+
+		buffer += sprintf(buffer, "%s\n", ec->card_desc ? ec->card_desc : "*unknown*");
+	} else
+		buffer += sprintf(buffer, "Simple card %d\n", ec->cid.id);
+
+	return buffer - start;
+}
+
+static int get_ecard_dev_info(char *buf, char **start, off_t pos, int count)
+{
+	ecard_t *ec = cards;
+	off_t at = 0;
+	int len, cnt;
+
+	cnt = 0;
+	while (ec && count > cnt) {
+		len = ecard_prints(buf, ec);
+		at += len;
+		if (at >= pos) {
+			if (!*start) {
+				*start = buf + (pos - (at - len));
+				cnt = at - pos;
+			} else
+				cnt += len;
+			buf += len;
+		}
+		ec = ec->next;
+	}
+	return (count > cnt) ? cnt : count;
+}
+
+static struct proc_dir_entry *proc_bus_ecard_dir = NULL;
+
+static void ecard_proc_init(void)
+{
+	proc_bus_ecard_dir = proc_mkdir("ecard", proc_bus);
+	create_proc_info_entry("devices", 0, proc_bus_ecard_dir,
+		get_ecard_dev_info);
+}
+
+/*
+ * Probe for an expansion card.
+ *
+ * If bit 1 of the first byte of the card is set, then the
+ * card does not exist.
+ */
+static int __init
+ecard_probe(int slot, card_type_t type)
+{
+	ecard_t **ecp;
+	ecard_t *ec;
+	struct ex_ecid cid;
+	int i, rc = -ENOMEM;
+
+	ec = kmalloc(sizeof(ecard_t), GFP_KERNEL);
+	if (!ec)
+		goto nomem;
+
+	memset(ec, 0, sizeof(ecard_t));
+
+	ec->slot_no	= slot;
+	ec->type	= type;
+	ec->irq		= NO_IRQ;
+	ec->fiq		= NO_IRQ;
+	ec->dma		= NO_DMA;
+	ec->card_desc	= NULL;
+	ec->ops		= &ecard_default_ops;
+
+	rc = -ENODEV;
+	if ((ec->podaddr = ecard_address(ec, type, ECARD_SYNC)) == 0)
+		goto nodev;
+
+	cid.r_zero = 1;
+	ecard_readbytes(&cid, ec, 0, 16, 0);
+	if (cid.r_zero)
+		goto nodev;
+
+	ec->cid.id	= cid.r_id;
+	ec->cid.cd	= cid.r_cd;
+	ec->cid.is	= cid.r_is;
+	ec->cid.w	= cid.r_w;
+	ec->cid.manufacturer = ecard_getu16(cid.r_manu);
+	ec->cid.product = ecard_getu16(cid.r_prod);
+	ec->cid.country = cid.r_country;
+	ec->cid.irqmask = cid.r_irqmask;
+	ec->cid.irqoff  = ecard_gets24(cid.r_irqoff);
+	ec->cid.fiqmask = cid.r_fiqmask;
+	ec->cid.fiqoff  = ecard_gets24(cid.r_fiqoff);
+	ec->fiqaddr	=
+	ec->irqaddr	= (unsigned char *)ioaddr(ec->podaddr);
+
+	if (ec->cid.is) {
+		ec->irqmask = ec->cid.irqmask;
+		ec->irqaddr += ec->cid.irqoff;
+		ec->fiqmask = ec->cid.fiqmask;
+		ec->fiqaddr += ec->cid.fiqoff;
+	} else {
+		ec->irqmask = 1;
+		ec->fiqmask = 4;
+	}
+
+	for (i = 0; i < sizeof(blacklist) / sizeof(*blacklist); i++)
+		if (blacklist[i].manufacturer == ec->cid.manufacturer &&
+		    blacklist[i].product == ec->cid.product) {
+			ec->card_desc = blacklist[i].type;
+			break;
+		}
+
+	ec->irq = 32 + slot;
+#ifdef IO_EC_MEMC8_BASE
+	if (slot == 8)
+		ec->irq = 11;
+#endif
+	/*
+	 * hook the interrupt handlers
+	 */
+	if (ec->irq != 0 && ec->irq >= 32) {
+		irq_desc[ec->irq].mask_ack = ecard_disableirq;
+		irq_desc[ec->irq].mask     = ecard_disableirq;
+		irq_desc[ec->irq].unmask   = ecard_enableirq;
+		irq_desc[ec->irq].valid    = 1;
+	}
+
+#ifdef CONFIG_ARCH_RPC
+	/* On RiscPC, only first two slots have DMA capability */
+	if (slot < 2)
+		ec->dma = 2 + slot;
+#endif
+
+	for (ecp = &cards; *ecp; ecp = &(*ecp)->next);
+
+	*ecp = ec;
+	slot_to_expcard[slot] = ec;
+	return 0;
+
+nodev:
+	kfree(ec);
+nomem:
+	return rc;
+}
+
+static ecard_t *finding_pos;
+
+void ecard_startfind(void)
+{
+	finding_pos = NULL;
+}
+
+ecard_t *ecard_find(int cid, const card_ids *cids)
+{
+	if (!finding_pos)
+		finding_pos = cards;
+	else
+		finding_pos = finding_pos->next;
+
+	for (; finding_pos; finding_pos = finding_pos->next) {
+		if (finding_pos->claimed)
+			continue;
+
+		if (!cids) {
+			if ((finding_pos->cid.id ^ cid) == 0)
+				break;
+		} else {
+			unsigned int manufacturer, product;
+			int i;
+
+			manufacturer = finding_pos->cid.manufacturer;
+			product = finding_pos->cid.product;
+
+			for (i = 0; cids[i].manufacturer != 65535; i++)
+				if (manufacturer == cids[i].manufacturer &&
+				    product == cids[i].product)
+					break;
+
+			if (cids[i].manufacturer != 65535)
+				break;
+		}
+	}
+
+	return finding_pos;
+}
+
+static void __init ecard_free_all(void)
+{
+	ecard_t *ec, *ecn;
+
+	for (ec = cards; ec; ec = ecn) {
+		ecn = ec->next;
+
+		kfree(ec);
+	}
+
+	cards = NULL;
+
+	memset(slot_to_expcard, 0, sizeof(slot_to_expcard));
+}
+
+/*
+ * Initialise the expansion card system.
+ * Locate all hardware - interrupt management and
+ * actual cards.
+ */
+void __init ecard_init(void)
+{
+	int slot;
+
+	/*
+	 * Register our reboot notifier
+	 */
+	register_reboot_notifier(&ecard_reboot_notifier);
+
+#ifdef CONFIG_CPU_32
+	init_waitqueue_head(&ecard_wait);
+#endif
+
+	printk("Probing expansion cards\n");
+
+	for (slot = 0; slot < 8; slot ++) {
+		if (ecard_probe(slot, ECARD_EASI) == -ENODEV)
+			ecard_probe(slot, ECARD_IOC);
+	}
+
+#ifdef IO_EC_MEMC8_BASE
+	ecard_probe(8, ECARD_IOC);
+#endif
+
+	ecard_probeirqhw();
+
+	if (setup_arm_irq(IRQ_EXPANSIONCARD, &irqexpansioncard)) {
+		printk(KERN_ERR "Unable to claim IRQ%d for expansion cards\n",
+		       IRQ_EXPANSIONCARD);
+		ecard_free_all();
+	}
+
+	ecard_proc_init();
+}
+
+EXPORT_SYMBOL(ecard_startfind);
+EXPORT_SYMBOL(ecard_find);
+EXPORT_SYMBOL(ecard_readchunk);
+EXPORT_SYMBOL(ecard_address);
diff -urN linux-2.4.29/arch/armnommu/kernel/entry-armo.S linux-2.4.29-uc1/arch/armnommu/kernel/entry-armo.S
--- linux-2.4.29/arch/armnommu/kernel/entry-armo.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/entry-armo.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,632 @@
+/*
+ *  linux/arch/arm/kernel/entry-armo.S
+ *
+ *  Copyright (C) 1995,1996,1997,1998 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Low-level vector interface routines
+ *
+ *  Design issues:
+ *   - We have several modes that each vector can be called from,
+ *     each with its own set of registers.  On entry to any vector,
+ *     we *must* save the registers used in *that* mode.
+ *
+ *   - This code must be as fast as possible.
+ *
+ *  There are a few restrictions on the vectors:
+ *   - the SWI vector cannot be called from *any* non-user mode
+ *
+ *   - the FP emulator is *never* called from *any* non-user mode undefined
+ *     instruction.
+ *
+ *  Ok, so this file may be a mess, but its as efficient as possible while
+ *  adhering to the above criteria.
+ */
+#include <linux/config.h>
+#include "entry-header.S"
+
+		.text
+
+#ifdef IOC_BASE
+/* IOC / IOMD based hardware */
+		.equ	ioc_base_high, IOC_BASE & 0xff000000
+		.equ	ioc_base_low, IOC_BASE & 0x00ff0000
+		.macro	disable_fiq
+		mov	r12, #ioc_base_high
+		.if	ioc_base_low
+		orr	r12, r12, #ioc_base_low
+		.endif
+		strb	r12, [r12, #0x38]	@ Disable FIQ register
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, base
+		mov	r4, #ioc_base_high		@ point at IOC
+		.if	ioc_base_low
+		orr	r4, r4, #ioc_base_low
+		.endif
+		ldrb	\irqnr, [r4, #0x24]		@ get high priority first
+		adr	\base, irq_prio_h
+		teq	\irqnr, #0
+		ldreqb	\irqnr, [r4, #0x14]		@ get low priority
+		adreq	\base, irq_prio_l
+		.endm
+
+/*
+ * Interrupt table (incorporates priority)
+ */
+		.macro	irq_prio_table
+irq_prio_l:	.byte	 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
+		.byte	 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
+		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+		.byte	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
+		.byte	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
+		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+irq_prio_h:	.byte	 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.endm
+#else
+#error Unknown architecture
+#endif
+
+/*=============================================================================
+ * For entry-common.S
+ */
+
+#if 0
+/*
+ * Uncomment these if you wish to get more debugging into about data aborts.
+ */
+#define FAULT_CODE_LDRSTRPOST	0x80
+#define FAULT_CODE_LDRSTRPRE	0x40
+#define FAULT_CODE_LDRSTRREG	0x20
+#define FAULT_CODE_LDMSTM	0x10
+#define FAULT_CODE_LDCSTC	0x08
+#endif
+#define FAULT_CODE_PREFETCH	0x04
+#define FAULT_CODE_WRITE	0x02
+#define FAULT_CODE_FORCECOW	0x01
+
+#define SVC_SAVE_ALL				\
+		str	sp, [sp, #-16]!		;\
+		str	lr, [sp, #8]		;\
+		str	lr, [sp, #4]		;\
+		stmfd	sp!, {r0 - r12}		;\
+		mov	r0, #-1			;\
+		str	r0, [sp, #S_OLD_R0]	;\
+		zero_fp
+
+#define SVC_IRQ_SAVE_ALL			\
+		str	sp, [sp, #-16]!		;\
+		str	lr, [sp, #4]		;\
+		ldr	lr, .LCirq		;\
+		ldr	lr, [lr]		;\
+		str	lr, [sp, #8]		;\
+		stmfd	sp!, {r0 - r12}		;\
+		mov	r0, #-1			;\
+		str	r0, [sp, #S_OLD_R0]	;\
+		zero_fp
+
+#define SVC_RESTORE_ALL				\
+		ldmfd	sp, {r0 - pc}^
+		
+/*=============================================================================
+ * Undefined FIQs
+ *-----------------------------------------------------------------------------
+ */
+_unexp_fiq:	ldr	sp, .LCfiq
+		mov	r12, #IOC_BASE
+		strb	r12, [r12, #0x38]	@ Disable FIQ register
+		teqp	pc, #0x0c000003
+		mov	r0, r0
+		stmfd	sp!, {r0 - r3, ip, lr}
+		adr	r0, Lfiqmsg
+		bl	SYMBOL_NAME(printk)
+		ldmfd	sp!, {r0 - r3, ip, lr}
+		teqp	pc, #0x0c000001
+		mov	r0, r0
+		movs	pc, lr
+
+Lfiqmsg:	.ascii	"*** Unexpected FIQ\n\0"
+		.align
+
+.LCfiq:		.word	__temp_fiq
+.LCirq:		.word	__temp_irq
+
+/*=============================================================================
+ * Undefined instruction handler
+ *-----------------------------------------------------------------------------
+ * Handles floating point instructions
+ */
+vector_undefinstr:
+		tst	lr,#3
+		bne	__und_svc
+		save_user_regs
+		zero_fp
+		teqp	pc, #I_BIT | MODE_SVC
+.Lbug_undef:
+		ldr	r4, .LC2
+		ldr	pc, [r4]			@ Call FP module USR entry point
+
+		.globl	SYMBOL_NAME(fpundefinstr)
+SYMBOL_NAME(fpundefinstr):				@ Called by FP module on undefined instr
+		mov	r0, lr
+		mov	r1, sp
+		teqp	pc, #MODE_SVC
+		bl	SYMBOL_NAME(do_undefinstr)
+		b	ret_from_exception		@ Normal FP exit
+
+__und_svc:	SVC_SAVE_ALL				@ Non-user mode
+		mask_pc	r0, lr
+		and	r2, lr, #3
+		sub	r0, r0, #4
+		mov	r1, sp
+		bl	SYMBOL_NAME(do_undefinstr)
+		SVC_RESTORE_ALL
+
+#if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE
+		/* The FPE is always present */
+		.equ	fpe_not_present, 0
+#else
+/* We get here if an undefined instruction happens and the floating
+ * point emulator is not present.  If the offending instruction was
+ * a WFS, we just perform a normal return as if we had emulated the
+ * operation.  This is a hack to allow some basic userland binaries
+ * to run so that the emulator module proper can be loaded. --philb
+ */
+fpe_not_present:
+		adr	r10, wfs_mask_data
+		ldmia	r10, {r4, r5, r6, r7, r8}
+		ldr	r10, [sp, #S_PC]		@ Load PC
+		sub	r10, r10, #4
+		mask_pc	r10, r10
+		ldrt	r10, [r10]			@ get instruction
+		and	r5, r10, r5
+		teq	r5, r4				@ Is it WFS?
+		beq	ret_from_exception
+		and	r5, r10, r8
+		teq	r5, r6				@ Is it LDF/STF on sp or fp?
+		teqne	r5, r7
+		bne	fpundefinstr
+		tst	r10, #0x00200000		@ Does it have WB
+		beq	ret_from_exception
+		and	r4, r10, #255			@ get offset
+		and	r6, r10, #0x000f0000
+		tst	r10, #0x00800000		@ +/-
+		ldr	r5, [sp, r6, lsr #14]		@ Load reg
+		rsbeq	r4, r4, #0
+		add	r5, r5, r4, lsl #2
+		str	r5, [sp, r6, lsr #14]		@ Save reg
+		b	ret_from_exception
+
+wfs_mask_data:	.word	0x0e200110			@ WFS/RFS
+		.word	0x0fef0fff
+		.word	0x0d0d0100			@ LDF [sp]/STF [sp]
+		.word	0x0d0b0100			@ LDF [fp]/STF [fp]
+		.word	0x0f0f0f00
+#endif
+
+.LC2:		.word	SYMBOL_NAME(fp_enter)
+
+/*=============================================================================
+ * Prefetch abort handler
+ *-----------------------------------------------------------------------------
+ */
+
+vector_prefetch:
+		sub	lr, lr, #4
+		tst	lr, #3
+		bne	__pabt_invalid
+		save_user_regs
+		teqp	pc, #0x00000003		@ NOT a problem - doesnt change mode
+		mask_pc	r0, lr			@ Address of abort
+		mov	r1, sp			@ Tasks registers
+		bl	SYMBOL_NAME(do_PrefetchAbort)
+		teq	r0, #0			@ If non-zero, we believe this abort..
+		bne	ret_from_exception
+#ifdef DEBUG_UNDEF
+		adr	r0, t
+		bl	SYMBOL_NAME(printk)
+#endif
+		ldr	lr, [sp,#S_PC]		@ program to test this on.  I think its
+		b	.Lbug_undef		@ broken at the moment though!)
+
+__pabt_invalid:	SVC_SAVE_ALL
+		mov	r0, sp				@ Prefetch aborts are definitely *not*
+		mov	r1, #BAD_PREFETCH		@ allowed in non-user modes.  We cant
+		and	r2, lr, #3			@ recover from this problem.
+		b	SYMBOL_NAME(bad_mode)
+
+#ifdef DEBUG_UNDEF
+t:		.ascii "*** undef ***\r\n\0"
+		.align
+#endif
+
+/*=============================================================================
+ * Address exception handler
+ *-----------------------------------------------------------------------------
+ * These aren't too critical.
+ * (they're not supposed to happen).
+ * In order to debug the reason for address exceptions in non-user modes,
+ * we have to obtain all the registers so that we can see what's going on.
+ */
+
+vector_addrexcptn:
+		sub	lr, lr, #8
+		tst	lr, #3
+		bne	Laddrexcptn_not_user
+		save_user_regs
+		teq	pc, #0x00000003
+		mask_pc	r0, lr			@ Point to instruction
+		mov	r1, sp			@ Point to registers
+		mov	r2, #0x400
+		mov	lr, pc
+		bl	SYMBOL_NAME(do_excpt)
+		b	ret_from_exception
+
+Laddrexcptn_not_user:
+		SVC_SAVE_ALL
+		and	r2, lr, #3
+		teq	r2, #3
+		bne	Laddrexcptn_illegal_mode
+		teqp	pc, #0x00000003		@ NOT a problem - doesnt change mode
+		mask_pc	r0, lr
+		mov	r1, sp
+		orr	r2, r2, #0x400
+		bl	SYMBOL_NAME(do_excpt)
+		ldmia	sp, {r0 - lr}		@ I cant remember the reason I changed this...
+		add	sp, sp, #15*4
+		movs	pc, lr
+
+Laddrexcptn_illegal_mode:
+		mov	r0, sp
+		str	lr, [sp, #-4]!
+		orr	r1, r2, #0x0c000000
+		teqp	r1, #0			@ change into mode (wont be user mode)
+		mov	r0, r0
+		mov	r1, r8			@ Any register from r8 - r14 can be banked
+		mov	r2, r9
+		mov	r3, r10
+		mov	r4, r11
+		mov	r5, r12
+		mov	r6, r13
+		mov	r7, r14
+		teqp	pc, #0x04000003		@ back to svc
+		mov	r0, r0
+		stmfd	sp!, {r1-r7}
+		ldmia	r0, {r0-r7}
+		stmfd	sp!, {r0-r7}
+		mov	r0, sp
+		mov	r1, #BAD_ADDREXCPTN
+		b	SYMBOL_NAME(bad_mode)
+
+/*=============================================================================
+ * Interrupt (IRQ) handler
+ *-----------------------------------------------------------------------------
+ * Note: if in user mode, then *no* kernel routine is running, so do not have
+ *       to save svc lr
+ * (r13 points to irq temp save area)
+ */
+
+vector_IRQ:	ldr	r13, .LCirq			@ I will leave this one in just in case...
+		sub	lr, lr, #4
+		str	lr, [r13]
+		tst	lr, #3
+		bne	__irq_svc
+		teqp	pc, #0x08000003
+		mov	r0, r0
+		ldr	lr, .LCirq
+		ldr	lr, [lr]
+		save_user_regs
+
+1:		get_irqnr_and_base r6, r5
+		teq	r6, #0
+		ldrneb	r0, [r5, r6]			@ get IRQ number
+		movne	r1, sp
+		@
+		@ routine called with r0 = irq number, r1 = struct pt_regs *
+		@
+		adr	lr, 1b
+		orr	lr, lr, #0x08000003		@ Force SVC
+		bne	do_IRQ
+
+		mov	why, #0
+		get_current_task r5
+		b	ret_to_user
+
+		irq_prio_table
+
+__irq_svc:	teqp	pc, #0x08000003
+		mov	r0, r0
+		SVC_IRQ_SAVE_ALL
+                and	r2, lr, #3
+		teq	r2, #3
+		bne	__irq_invalid
+1:		get_irqnr_and_base r6, r5
+		teq	r6, #0
+		ldrneb	r0, [r5, r6]			@ get IRQ number
+		movne	r1, sp
+		@
+		@ routine called with r0 = irq number, r1 = struct pt_regs *
+		@
+		adr	lr, 1b
+		orr	lr, lr, #0x08000003		@ Force SVC
+		bne	do_IRQ				@ Returns to 1b
+		SVC_RESTORE_ALL
+
+__irq_invalid:	mov	r0, sp
+		mov	r1, #BAD_IRQ
+		b	SYMBOL_NAME(bad_mode)
+
+/*=============================================================================
+ * Data abort handler code
+ *-----------------------------------------------------------------------------
+ *
+ * This handles both exceptions from user and SVC modes, computes the address
+ *  range of the problem, and does any correction that is required.  It then
+ *  calls the kernel data abort routine.
+ *
+ * This is where I wish that the ARM would tell you which address aborted.
+ */
+
+vector_data:	sub	lr, lr, #8		@ Correct lr
+		tst	lr, #3
+		bne	Ldata_not_user
+		save_user_regs
+		teqp	pc, #0x00000003		@ NOT a problem - doesnt change mode
+		mask_pc	r0, lr
+		bl	Ldata_do
+		b	ret_from_exception
+
+Ldata_not_user:
+		SVC_SAVE_ALL
+		and	r2, lr, #3
+		teq	r2, #3
+		bne	Ldata_illegal_mode
+		tst	lr, #0x08000000
+		teqeqp	pc, #0x00000003		@ NOT a problem - doesnt change mode
+		mask_pc	r0, lr
+		bl	Ldata_do
+		SVC_RESTORE_ALL
+
+Ldata_illegal_mode:
+		mov	r0, sp
+		mov	r1, #BAD_DATA
+		b	SYMBOL_NAME(bad_mode)
+
+Ldata_do:	mov	r3, sp
+		ldr	r4, [r0]		@ Get instruction
+		mov	r2, #0
+		tst	r4, #1 << 20		@ Check to see if it is a write instruction
+		orreq	r2, r2, #FAULT_CODE_WRITE @ Indicate write instruction
+		mov	r1, r4, lsr #22		@ Now branch to the relevent processing routine
+		and	r1, r1, #15 << 2
+		add	pc, pc, r1
+		movs	pc, lr
+		b	Ldata_unknown
+		b	Ldata_unknown
+		b	Ldata_unknown
+		b	Ldata_unknown
+		b	Ldata_ldrstr_post	@ ldr	rd, [rn], #m
+		b	Ldata_ldrstr_numindex	@ ldr	rd, [rn, #m]	@ RegVal
+		b	Ldata_ldrstr_post	@ ldr	rd, [rn], rm
+		b	Ldata_ldrstr_regindex	@ ldr	rd, [rn, rm]
+		b	Ldata_ldmstm		@ ldm*a	rn, <rlist>
+		b	Ldata_ldmstm		@ ldm*b	rn, <rlist>
+		b	Ldata_unknown
+		b	Ldata_unknown
+		b	Ldata_ldrstr_post	@ ldc	rd, [rn], #m	@ Same as ldr	rd, [rn], #m
+		b	Ldata_ldcstc_pre	@ ldc	rd, [rn, #m]
+		b	Ldata_unknown
+Ldata_unknown:	@ Part of jumptable
+		mov	r0, r1
+		mov	r1, r4
+		mov	r2, r3
+		b	baddataabort
+
+Ldata_ldrstr_post:
+		mov	r0, r4, lsr #14		@ Get Rn
+		and	r0, r0, #15 << 2	@ Mask out reg.
+		teq	r0, #15 << 2
+		ldr	r0, [r3, r0]		@ Get register
+		biceq	r0, r0, #PCMASK
+		mov	r1, r0
+#ifdef FAULT_CODE_LDRSTRPOST
+		orr	r2, r2, #FAULT_CODE_LDRSTRPOST
+#endif
+		b	SYMBOL_NAME(do_DataAbort)
+
+Ldata_ldrstr_numindex:
+		mov	r0, r4, lsr #14		@ Get Rn
+		and	r0, r0, #15 << 2	@ Mask out reg.
+		teq	r0, #15 << 2
+		ldr	r0, [r3, r0]		@ Get register
+		mov	r1, r4, lsl #20
+		biceq	r0, r0, #PCMASK
+		tst	r4, #1 << 23
+		addne	r0, r0, r1, lsr #20
+		subeq	r0, r0, r1, lsr #20
+		mov	r1, r0
+#ifdef FAULT_CODE_LDRSTRPRE
+		orr	r2, r2, #FAULT_CODE_LDRSTRPRE
+#endif
+		b	SYMBOL_NAME(do_DataAbort)
+
+Ldata_ldrstr_regindex:
+		mov	r0, r4, lsr #14		@ Get Rn
+		and	r0, r0, #15 << 2	@ Mask out reg.
+		teq	r0, #15 << 2
+		ldr	r0, [r3, r0]		@ Get register
+		and	r7, r4, #15
+		biceq	r0, r0, #PCMASK
+		teq	r7, #15			@ Check for PC
+		ldr	r7, [r3, r7, lsl #2]	@ Get Rm
+		and	r8, r4, #0x60		@ Get shift types
+		biceq	r7, r7, #PCMASK
+		mov	r9, r4, lsr #7		@ Get shift amount
+		and	r9, r9, #31
+		teq	r8, #0
+		moveq	r7, r7, lsl r9
+		teq	r8, #0x20		@ LSR shift
+		moveq	r7, r7, lsr r9
+		teq	r8, #0x40		@ ASR shift
+		moveq	r7, r7, asr r9
+		teq	r8, #0x60		@ ROR shift
+		moveq	r7, r7, ror r9
+		tst	r4, #1 << 23
+		addne	r0, r0, r7
+		subeq	r0, r0, r7		@ Apply correction
+		mov	r1, r0
+#ifdef FAULT_CODE_LDRSTRREG
+		orr	r2, r2, #FAULT_CODE_LDRSTRREG
+#endif
+		b	SYMBOL_NAME(do_DataAbort)
+
+Ldata_ldmstm:
+		mov	r7, #0x11
+		orr	r7, r7, r7, lsl #8
+		and	r0, r4, r7
+		and	r1, r4, r7, lsl #1
+		add	r0, r0, r1, lsr #1
+		and	r1, r4, r7, lsl #2
+		add	r0, r0, r1, lsr #2
+		and	r1, r4, r7, lsl #3
+		add	r0, r0, r1, lsr #3
+		add	r0, r0, r0, lsr #8
+		add	r0, r0, r0, lsr #4
+		and	r7, r0, #15		@ r7 = no. of registers to transfer.
+		mov	r5, r4, lsr #14		@ Get Rn
+		and	r5, r5, #15 << 2
+		ldr	r0, [r3, r5]		@ Get reg
+		eor	r6, r4, r4, lsl #2
+		tst	r6, #1 << 23		@ Check inc/dec ^ writeback
+		rsbeq	r7, r7, #0
+		add	r7, r0, r7, lsl #2	@ Do correction (signed)
+		subne	r1, r7, #1
+		subeq	r1, r0, #1
+		moveq	r0, r7
+		tst	r4, #1 << 21		@ Check writeback
+		strne	r7, [r3, r5]
+		eor	r6, r4, r4, lsl #1
+		tst	r6, #1 << 24		@ Check Pre/Post ^ inc/dec
+		addeq	r0, r0, #4
+		addeq	r1, r1, #4
+		teq	r5, #15*4		@ CHECK FOR PC
+		biceq	r1, r1, #PCMASK
+		biceq	r0, r0, #PCMASK
+#ifdef FAULT_CODE_LDMSTM
+		orr	r2, r2, #FAULT_CODE_LDMSTM
+#endif
+		b	SYMBOL_NAME(do_DataAbort)
+
+Ldata_ldcstc_pre:
+		mov	r0, r4, lsr #14		@ Get Rn
+		and	r0, r0, #15 << 2	@ Mask out reg.
+		teq	r0, #15 << 2
+		ldr	r0, [r3, r0]		@ Get register
+		mov	r1, r4, lsl #24		@ Get offset
+		biceq	r0, r0, #PCMASK
+		tst	r4, #1 << 23
+		addne	r0, r0, r1, lsr #24
+		subeq	r0, r0, r1, lsr #24
+		mov	r1, r0
+#ifdef FAULT_CODE_LDCSTC
+		orr	r2, r2, #FAULT_CODE_LDCSTC
+#endif
+		b	SYMBOL_NAME(do_DataAbort)
+
+
+/*
+ * This is the return code to user mode for abort handlers
+ */
+ENTRY(ret_from_exception)
+		get_current_task tsk
+		mov	why, #0
+		b	ret_to_user
+
+		.data
+ENTRY(fp_enter)
+		.word	fpe_not_present
+		.text
+/*
+ * Register switch for older 26-bit only ARMs
+ */
+ENTRY(__switch_to)
+		stmfd	sp!, {r4 - sl, fp, lr}		@ Store most regs on stack
+		str	sp, [r0, #TSS_SAVE]		@ Save sp_SVC
+		ldr	sp, [r1, #TSS_SAVE]		@ Get saved sp_SVC
+		ldmfd	sp!, {r4 - sl, fp, pc}^		@ Load all regs saved previously
+
+/*
+ *=============================================================================
+ *		Low-level interface code
+ *-----------------------------------------------------------------------------
+ *		Trap initialisation
+ *-----------------------------------------------------------------------------
+ *
+ * Note - FIQ code has changed.  The default is a couple of words in 0x1c, 0x20
+ * that call _unexp_fiq.  Nowever, we now copy the FIQ routine to 0x1c (removes
+ * some excess cycles).
+ *
+ * What we need to put into 0-0x1c are branches to branch to the kernel.
+ */
+
+		.section ".text.init",#alloc,#execinstr
+
+.Ljump_addresses:
+		swi	SYS_ERROR0
+		.word	vector_undefinstr	- 12
+		.word	vector_swi		- 16
+		.word	vector_prefetch		- 20
+		.word	vector_data		- 24
+		.word	vector_addrexcptn	- 28
+		.word	vector_IRQ		- 32
+		.word	_unexp_fiq		- 36
+		b	. + 8
+/*
+ * initialise the trap system
+ */
+ENTRY(__trap_init)
+		stmfd	sp!, {r4 - r7, lr}
+		adr	r1, .Ljump_addresses
+		ldmia	r1, {r1 - r7, ip, lr}
+		orr	r2, lr, r2, lsr #2
+		orr	r3, lr, r3, lsr #2
+		orr	r4, lr, r4, lsr #2
+		orr	r5, lr, r5, lsr #2
+		orr	r6, lr, r6, lsr #2
+		orr	r7, lr, r7, lsr #2
+		orr	ip, lr, ip, lsr #2
+		mov	r0, #0
+		stmia	r0, {r1 - r7, ip}
+		ldmfd	sp!, {r4 - r7, pc}^
+
+		.bss
+__temp_irq:	.space	4				@ saved lr_irq
+__temp_fiq:	.space	128
diff -urN linux-2.4.29/arch/armnommu/kernel/entry-armv.S linux-2.4.29-uc1/arch/armnommu/kernel/entry-armv.S
--- linux-2.4.29/arch/armnommu/kernel/entry-armv.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/entry-armv.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,1974 @@
+/*
+ *  linux/arch/armnommu/kernel/entry-armv.S [Kernel 2.4.x]
+ *
+ *  Copyright (C) 1996,1997,1998 Russell King.
+ *  ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Low-level vector interface routines
+ *
+ *  Note:  there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes
+ *  it to save wrong values...  Be aware!
+ *
+ * added some NET+ARM code by Joe deBlaquiere  --rp
+ * added S3C4510 code by Mac Wang
+ * added S3C4530 code by Arcturus Networks Inc.
+ * added TI TMS320DM270 code by Chee Tim Loh <cheetim_loh@innomedia.com.sg>
+ *
+ */
+#include <linux/config.h>
+#include "entry-header.S"
+
+#ifdef IOC_BASE
+/* IOC / IOMD based hardware */
+#include <asm/hardware/iomd.h>
+
+		.equ	ioc_base_high, IOC_BASE & 0xff000000
+		.equ	ioc_base_low, IOC_BASE & 0x00ff0000
+		.macro	disable_fiq
+		mov	r12, #ioc_base_high
+		.if	ioc_base_low
+		orr	r12, r12, #ioc_base_low
+		.endif
+		strb	r12, [r12, #0x38]	@ Disable FIQ register
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	r4, #ioc_base_high		@ point at IOC
+		.if	ioc_base_low
+		orr	r4, r4, #ioc_base_low
+		.endif
+		ldrb	\irqstat, [r4, #IOMD_IRQREQB]	@ get high priority first
+		ldr	\base, =irq_prio_h
+		teq	\irqstat, #0
+#ifdef IOMD_BASE
+		ldreqb	\irqstat, [r4, #IOMD_DMAREQ]	@ get dma
+		addeq	\base, \base, #256		@ irq_prio_h table size
+		teqeq	\irqstat, #0
+		bne	2406f
+#endif
+		ldreqb	\irqstat, [r4, #IOMD_IRQREQA]	@ get low priority
+		addeq	\base, \base, #256		@ irq_prio_d table size
+		teqeq	\irqstat, #0
+#ifdef IOMD_IRQREQC
+		ldreqb	\irqstat, [r4, #IOMD_IRQREQC]
+		addeq	\base, \base, #256		@ irq_prio_l table size
+		teqeq	\irqstat, #0
+#endif
+#ifdef IOMD_IRQREQD
+		ldreqb	\irqstat, [r4, #IOMD_IRQREQD]
+		addeq	\base, \base, #256		@ irq_prio_lc table size
+		teqeq	\irqstat, #0
+#endif
+2406:		ldrneb	\irqnr, [\base, \irqstat]	@ get IRQ number
+		.endm
+
+/*
+ * Interrupt table (incorporates priority).  Please note that we
+ * rely on the order of these tables (see above code).
+ */
+		.macro	irq_prio_table
+irq_prio_h:	.byte	 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+#ifdef IOMD_BASE
+irq_prio_d:	.byte	 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+#endif
+irq_prio_l:	.byte	 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
+		.byte	 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
+		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+		.byte	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
+		.byte	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
+		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+#ifdef IOMD_IRQREQC
+irq_prio_lc:	.byte	24,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
+		.byte	28,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
+		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
+		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
+		.byte	30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
+		.byte	30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
+		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
+		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+#endif
+#ifdef IOMD_IRQREQD
+irq_prio_ld:	.byte	40,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
+		.byte	44,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
+		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
+		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
+		.byte	46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
+		.byte	46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
+		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
+		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+#endif
+		.endm
+
+#elif defined(CONFIG_ARCH_EBSA110)
+
+#define IRQ_STAT		0xff000000	/* read */
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, stat, base, tmp
+		mov	\base, #IRQ_STAT
+		ldrb	\stat, [\base]			@ get interrupts
+		mov	\irqnr, #0
+		tst	\stat, #15
+		addeq	\irqnr, \irqnr, #4
+		moveq	\stat, \stat, lsr #4
+		tst	\stat, #3
+		addeq	\irqnr, \irqnr, #2
+		moveq	\stat, \stat, lsr #2
+		tst	\stat, #1
+		addeq	\irqnr, \irqnr, #1
+		moveq	\stat, \stat, lsr #1
+		tst	\stat, #1			@ bit 0 should be set
+		.endm
+
+		.macro	irq_prio_table
+		.endm
+
+#elif defined(CONFIG_ARCH_SHARK)
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	r4, #0xe0000000
+		orr	r4, r4, #0x20
+
+		mov	\irqstat, #0x0C
+		strb	\irqstat, [r4]			@outb(0x0C, 0x20) /* Poll command */
+		ldrb	\irqnr, [r4]			@irq = inb(0x20) & 7
+		and	\irqstat, \irqnr, #0x80
+		teq	\irqstat, #0
+		beq	43f
+		and	\irqnr, \irqnr, #7
+		teq	\irqnr, #2
+		bne	44f
+43:		mov	\irqstat, #0x0C
+		strb	\irqstat, [r4, #0x80]		@outb(0x0C, 0xA0) /* Poll command */
+		ldrb	\irqnr, [r4, #0x80]		@irq = (inb(0xA0) & 7) + 8
+		and	\irqstat, \irqnr, #0x80
+		teq	\irqstat, #0
+		beq	44f
+		and	\irqnr, \irqnr, #7
+		add	\irqnr, \irqnr, #8
+44:		teq	\irqstat, #0
+		.endm
+
+		.macro	irq_prio_table
+		.endm
+
+#elif defined(CONFIG_FOOTBRIDGE)
+#include <asm/hardware/dec21285.h>
+
+		.macro	disable_fiq
+		.endm
+
+		.equ	dc21285_high, ARMCSR_BASE & 0xff000000
+		.equ	dc21285_low, ARMCSR_BASE & 0x00ffffff
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	r4, #dc21285_high
+		.if	dc21285_low
+		orr	r4, r4, #dc21285_low
+		.endif
+		ldr	\irqstat, [r4, #0x180]		@ get interrupts
+
+		mov	\irqnr, #IRQ_SDRAMPARITY
+		tst	\irqstat, #IRQ_MASK_SDRAMPARITY
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_UART_RX
+		movne	\irqnr, #IRQ_CONRX
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_DMA1
+		movne	\irqnr, #IRQ_DMA1
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_DMA2
+		movne	\irqnr, #IRQ_DMA2
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_IN0
+		movne	\irqnr, #IRQ_IN0
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_IN1
+		movne	\irqnr, #IRQ_IN1
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_IN2
+		movne	\irqnr, #IRQ_IN2
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_IN3
+		movne	\irqnr, #IRQ_IN3
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_PCI
+		movne	\irqnr, #IRQ_PCI
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_DOORBELLHOST
+		movne	\irqnr, #IRQ_DOORBELLHOST
+		bne     1001f
+	
+		tst	\irqstat, #IRQ_MASK_I2OINPOST
+		movne	\irqnr, #IRQ_I2OINPOST
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_TIMER1
+		movne	\irqnr, #IRQ_TIMER1
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_TIMER2
+		movne	\irqnr, #IRQ_TIMER2
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_TIMER3
+		movne	\irqnr, #IRQ_TIMER3
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_UART_TX
+		movne	\irqnr, #IRQ_CONTX
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_PCI_ABORT
+		movne	\irqnr, #IRQ_PCI_ABORT
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_PCI_SERR
+		movne	\irqnr, #IRQ_PCI_SERR
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_DISCARD_TIMER
+		movne	\irqnr, #IRQ_DISCARD_TIMER
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_PCI_DPERR
+		movne	\irqnr, #IRQ_PCI_DPERR
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_PCI_PERR
+		movne	\irqnr, #IRQ_PCI_PERR
+1001:
+		.endm
+
+		.macro	irq_prio_table
+		.endm
+
+#elif defined(CONFIG_ARCH_NEXUSPCI)
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\irqstat, =INTCONT_BASE
+		ldr	\base, =soft_irq_mask
+		ldr	\irqstat, [\irqstat]		@ get interrupts
+		ldr	\base, [\base]
+		mov	\irqnr, #0
+		and	\irqstat, \irqstat, \base	@ mask out disabled ones
+1001:		tst	\irqstat, #1
+		addeq	\irqnr, \irqnr, #1
+		moveq	\irqstat, \irqstat, lsr #1
+		tsteq	\irqnr, #32
+		beq	1001b
+		teq	\irqnr, #32
+		.endm
+
+		.macro	irq_prio_table
+		.ltorg
+		.bss
+ENTRY(soft_irq_mask)
+		.word	0
+		.text
+		.endm
+
+#elif defined(CONFIG_ARCH_TBOX)
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\irqstat, =0xffff7000
+		ldr	\irqstat, [\irqstat]		@ get interrupts
+		ldr	\base, =soft_irq_mask
+		ldr	\base, [\base]
+		mov	\irqnr, #0
+		and	\irqstat, \irqstat, \base	@ mask out disabled ones
+1001:		tst	\irqstat, #1
+		addeq	\irqnr, \irqnr, #1
+		moveq	\irqstat, \irqstat, lsr #1
+		tsteq	\irqnr, #32
+		beq	1001b
+		teq	\irqnr, #32
+		.endm
+
+		.macro	irq_prio_table
+		.ltorg
+		.bss
+ENTRY(soft_irq_mask)
+		.word	0
+		.text
+		.endm
+
+#elif defined(CONFIG_ARCH_SA1100)
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	r4, #0xfa000000			@ ICIP = 0xfa050000
+		add	r4, r4, #0x00050000
+		ldr	\irqstat, [r4]			@ get irqs
+		ldr	\irqnr, [r4, #4]		@ ICMR = 0xfa050004
+		ands	\irqstat, \irqstat, \irqnr
+		mov	\irqnr, #0
+		beq	1001f
+		tst	\irqstat, #0xff
+		moveq	\irqstat, \irqstat, lsr #8
+		addeq	\irqnr, \irqnr, #8
+		tsteq	\irqstat, #0xff
+		moveq	\irqstat, \irqstat, lsr #8
+		addeq	\irqnr, \irqnr, #8
+		tsteq	\irqstat, #0xff
+		moveq	\irqstat, \irqstat, lsr #8
+		addeq	\irqnr, \irqnr, #8
+		tst	\irqstat, #0x0f
+		moveq	\irqstat, \irqstat, lsr #4
+		addeq	\irqnr, \irqnr, #4
+		tst	\irqstat, #0x03
+		moveq	\irqstat, \irqstat, lsr #2
+		addeq	\irqnr, \irqnr, #2
+		tst	\irqstat, #0x01
+		addeqs	\irqnr, \irqnr, #1
+1001:
+		.endm
+
+		.macro	irq_prio_table
+		.endm
+
+#elif defined(CONFIG_ARCH_L7200)
+	
+		.equ	irq_base_addr,	IO_BASE_2
+
+		.macro  disable_fiq
+		.endm
+ 
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov     \irqstat, #irq_base_addr		@ Virt addr IRQ regs
+		add	\irqstat, \irqstat, #0x00001000		@ Status reg
+		ldr     \irqstat, [\irqstat, #0]		@ get interrupts
+		mov     \irqnr, #0
+1001:		tst     \irqstat, #1
+		addeq   \irqnr, \irqnr, #1
+		moveq   \irqstat, \irqstat, lsr #1
+		tsteq   \irqnr, #32
+		beq     1001b
+		teq     \irqnr, #32
+		.endm
+
+		.macro  irq_prio_table
+		.endm
+
+#elif defined(CONFIG_ARCH_INTEGRATOR)
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+/* FIXME: should not be using soo many LDRs here */
+		ldr	\irqnr, =IO_ADDRESS(INTEGRATOR_IC_BASE)
+		ldr	\irqstat, [\irqnr, #IRQ_STATUS]		@ get masked status
+		ldr	\irqnr, =IO_ADDRESS(INTEGRATOR_HDR_BASE)
+		ldr	\irqnr, [\irqnr, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)]
+		orr	\irqstat, \irqstat, \irqnr, lsl #INTEGRATOR_CM_INT0
+
+		mov	\irqnr, #0
+1001:		tst	\irqstat, #1
+		bne	1002f
+		add	\irqnr, \irqnr, #1
+		mov	\irqstat, \irqstat, lsr #1
+		cmp	\irqnr, #22
+		bcc	1001b
+1002:		/* EQ will be set if we reach 22 */
+		.endm
+
+		.macro	irq_prio_table
+		.endm
+
+#elif defined(CONFIG_ARCH_CLPS711X)
+
+#include <asm/hardware/clps7111.h>
+
+		.macro	disable_fiq
+		.endm
+
+#if (INTSR2 - INTSR1) != (INTMR2 - INTMR1)
+#error INTSR stride != INTMR stride
+#endif
+
+		.macro	get_irqnr_and_base, irqnr, stat, base, mask
+		mov	\base, #CLPS7111_BASE
+		ldr	\stat, [\base, #INTSR1]
+		ldr	\mask, [\base, #INTMR1]
+		mov	\irqnr, #4
+		mov	\mask, \mask, lsl #16
+		and	\stat, \stat, \mask, lsr #16
+		movs	\stat, \stat, lsr #4
+		bne	1001f
+
+		add	\base, \base, #INTSR2 - INTSR1
+		ldr	\stat, [\base, #INTSR1]
+		ldr	\mask, [\base, #INTMR1]
+		mov	\irqnr, #16
+		mov	\mask, \mask, lsl #16
+		and	\stat, \stat, \mask, lsr #16
+
+1001:		tst	\stat, #255
+		addeq	\irqnr, \irqnr, #8
+		moveq	\stat, \stat, lsr #8
+		tst	\stat, #15
+		addeq	\irqnr, \irqnr, #4
+		moveq	\stat, \stat, lsr #4
+		tst	\stat, #3
+		addeq	\irqnr, \irqnr, #2
+		moveq	\stat, \stat, lsr #2
+		tst	\stat, #1
+		addeq	\irqnr, \irqnr, #1
+		moveq	\stat, \stat, lsr #1
+		tst	\stat, #1			@ bit 0 should be set
+		.endm
+
+		.macro	irq_prio_table
+		.endm
+
+#elif defined(CONFIG_ARCH_ANAKIN)
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	\base, #IO_BASE
+		mov	\irqstat, #INTERRUPT_CONTROLLER
+		ldr	\tmp, =anakin_irq_mask
+		ldr	\irqstat, [\base, \irqstat]
+		ldr	\tmp, [\tmp]
+		ands	\irqstat, \irqstat, \tmp
+		ldrne	\tmp, =anakin_active_irqs
+		strne	\irqstat, [\tmp]
+		movne	\irqnr, #IRQ_ANAKIN
+		.endm
+
+		.macro	irq_prio_table
+		.ltorg
+		.bss
+ENTRY(anakin_irq_mask)
+		.word	0
+ENTRY(anakin_active_irqs)
+		.space	4
+		.text
+		.endm
+
+#elif defined(CONFIG_ARCH_CNXT)
+
+		.macro	disable_fiq
+		.endm
+
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+#ifdef CONFIG_ARCH_P52
+	
+		ldr	r4, =P52INT_STATUS_M	
+		ldr	\irqstat, [r4]
+
+
+		tst	\irqstat, #P52INT_MASK_TIMER_1 
+		movne	\irqnr, #P52INT_LVL_TIMER_1
+		bne	1001f
+	
+		tst	\irqstat, #P52INT_MASK_TIMER_2
+		movne	\irqnr, #P52INT_LVL_TIMER_2
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_TIMER_3
+		movne	\irqnr, #P52INT_LVL_TIMER_3
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_TIMER_4
+		movne	\irqnr, #P52INT_LVL_TIMER_4
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_USB 
+		movne	\irqnr, #P52INT_LVL_USB 
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_HOST
+		movne	\irqnr, #P52INT_LVL_HOST
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_HOST_ERR
+		movne	\irqnr, #P52INT_LVL_HOST_ERR
+		bne	1001f
+	
+		tst	\irqstat, #P52INT_MASK_DMA8 
+		movne	\irqnr, #P52INT_LVL_DMA8 
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_DMA6
+		movne	\irqnr, #P52INT_LVL_DMA6
+		bne     1001f
+	
+		tst	\irqstat, #P52INT_MASK_DMA5
+		movne	\irqnr, #P52INT_LVL_DMA5
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_DMA4
+		movne	\irqnr, #P52INT_LVL_DMA4
+		bne	1001f
+	
+		tst	\irqstat, #P52INT_MASK_DMA3
+		movne	\irqnr, #P52INT_LVL_DMA3
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_DMA2
+		movne	\irqnr, #P52INT_LVL_DMA2
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_DMA1
+		movne	\irqnr, #P52INT_LVL_DMA1
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_DMA_ERR 
+		movne	\irqnr, #P52INT_LVL_DMA_ERR 
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_E2_ERR
+		movne	\irqnr, #P52INT_LVL_E2_ERR
+		bne	1001f
+       
+		tst	\irqstat, #P52INT_MASK_E1_ERR 
+		movne	\irqnr, #P52INT_LVL_E1_ERR 
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_DSL
+		movne	\irqnr, #P52INT_LVL_DSL
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_GPIO 
+		movne	\irqnr, #P52INT_LVL_GPIO 
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_COMMTX
+		movne	\irqnr, #P52INT_LVL_COMMTX
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_COMMRX
+		movne	\irqnr, #P52INT_LVL_COMMRX
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_SW1 
+		movne	\irqnr, #P52INT_LVL_SW1
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_SW2
+		movne	\irqnr, #P52INT_LVL_SW2
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_SW3
+		movne	\irqnr, #P52INT_LVL_SW3
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_SW4
+		movne	\irqnr, #P52INT_LVL_SW4
+
+	
+1001:
+
+#endif
+
+#ifdef CONFIG_ARCH_CX821XX
+	
+		ldr	r4, =CNXT_INT_STATUS_M	
+		ldr	\irqstat, [r4]
+
+
+		tst	\irqstat, #CNXT_INT_MASK_TIMER_1 
+		movne	\irqnr, #CNXT_INT_LVL_TIMER_1
+		bne	1001f
+	
+		tst	\irqstat, #CNXT_INT_MASK_TIMER_2
+		movne	\irqnr, #CNXT_INT_LVL_TIMER_2
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_TIMER_3
+		movne	\irqnr, #CNXT_INT_LVL_TIMER_3
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_TIMER_4
+		movne	\irqnr, #CNXT_INT_LVL_TIMER_4
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_USB 
+		movne	\irqnr, #CNXT_INT_LVL_USB 
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_HOST
+		movne	\irqnr, #CNXT_INT_LVL_HOST
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_HOST_ERR
+		movne	\irqnr, #CNXT_INT_LVL_HOST_ERR
+		bne	1001f
+	
+		tst	\irqstat, #CNXT_INT_MASK_DMA8 
+		movne	\irqnr, #CNXT_INT_LVL_DMA8 
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_DMA6
+		movne	\irqnr, #CNXT_INT_LVL_DMA6
+		bne     1001f
+	
+		tst	\irqstat, #CNXT_INT_MASK_DMA5
+		movne	\irqnr, #CNXT_INT_LVL_DMA5
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_DMA4
+		movne	\irqnr, #CNXT_INT_LVL_DMA4
+		bne	1001f
+	
+		tst	\irqstat, #CNXT_INT_MASK_DMA3
+		movne	\irqnr, #CNXT_INT_LVL_DMA3
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_DMA2
+		movne	\irqnr, #CNXT_INT_LVL_DMA2
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_DMA1
+		movne	\irqnr, #CNXT_INT_LVL_DMA1
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_DMA_ERR 
+		movne	\irqnr, #CNXT_INT_LVL_DMA_ERR 
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_E2_ERR
+		movne	\irqnr, #CNXT_INT_LVL_E2_ERR
+		bne	1001f
+       
+		tst	\irqstat, #CNXT_INT_MASK_E1_ERR 
+		movne	\irqnr, #CNXT_INT_LVL_E1_ERR 
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_DSL
+		movne	\irqnr, #CNXT_INT_LVL_DSL
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_GPIO 
+		movne	\irqnr, #CNXT_INT_LVL_GPIO 
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_COMMTX
+		movne	\irqnr, #CNXT_INT_LVL_COMMTX
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_COMMRX
+		movne	\irqnr, #CNXT_INT_LVL_COMMRX
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_SW1 
+		movne	\irqnr, #CNXT_INT_LVL_SW1
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_SW2
+		movne	\irqnr, #CNXT_INT_LVL_SW2
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_SW3
+		movne	\irqnr, #CNXT_INT_LVL_SW3
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_SW4
+		movne	\irqnr, #CNXT_INT_LVL_SW4
+
+	
+1001:
+
+#endif
+
+#ifdef CONFIG_ARCH_SPIPE
+		@
+		@ not been tested 
+		@	
+		ldr	r4, =0x350044
+		ldr	\irqnr, [r4]	
+		
+		mov r5,#0
+icloopusr:
+		cmp r5,#31
+		ble icshftusr
+		b icendusr
+icshftusr:
+		mov r4,r6,lsr r5		@ shift untill we get one
+		and r0,r4,#1			@ int priority is in the status
+		cmp r0,#0
+		beq incicusr
+		b icendusr
+incicusr:
+		add r5,r5,#1
+		b icloopusr
+		
+icendusr:		 
+		mov	r0, r5
+#endif
+
+		.endm
+
+		.macro	irq_prio_table
+		.endm
+	
+#elif defined(CONFIG_ARCH_ATMEL)
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	r4, =AIC_IVR
+		ldr	\irqnr, [r4]		@ignore value
+		ldr	r4, =AIC_ISR		@read interrupt nr.
+		ldr	\irqnr, [r4]
+		teq	\irqnr, #0
+		.endm
+
+		.macro	irq_prio_table
+		.endm
+
+#elif defined(CONFIG_ARCH_TA7S) || defined(CONFIG_ARCH_TA7V)
+#include <asm/arch/arch.h>
+
+		.macro	disable_fiq
+		mrs	r13, spsr
+		orr	r13, r13, #F_BIT
+		msr	spsr_c, r13
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, stat, base, temp
+		ldr 	\irqnr, =INT_IRQ_STATUS_REG
+
+		ldr	\base, [\irqnr, #0]	@ stash ISTATUS
+		mov	\irqnr, #0
+1001:		
+		cmp	\base, #0		@ no flags set?
+		beq	1002f			@ keep "eq" status when finishing!
+		tst	\base, #1		@ lsb set?
+		addeq	\irqnr, \irqnr, #1	@ if not, incr IRQ#
+		moveq	\base, \base, LSR #1	@ r = r >> 1 
+		beq	1001b
+1002:
+		adr	\base, irq_prio_ta7
+		.endm
+		
+		.macro	irq_prio_table
+irq_prio_ta7:
+		.byte   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+		.byte   16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
+		.endm
+
+#elif defined(CONFIG_ARCH_NETARM)
+#include <asm/arch/netarm_gen_module.h>
+
+		.macro	disable_fiq
+		mrs	r13, spsr
+		orr	r13, r13, #F_BIT
+		msr	spsr_c, r13
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, stat, base, temp
+		ldr 	\irqnr, =(NETARM_GEN_MODULE_BASE+NETARM_GEN_INTR_STATUS_EN)
+
+		ldr	\base, [\irqnr, #0]	@ stash ISTATUS
+		mov	\irqnr, #0
+1001:		
+		cmp	\base, #0		@ no flags set?
+		beq	1002f			@ keep "eq" status when finishing!
+		tst	\base, #1		@ lsb set?
+		addeq	\irqnr, \irqnr, #1	@ if not, incr IRQ#
+		moveq	\base, \base, LSR #1	@ r = r >> 1 
+		beq	1001b
+
+		cmp	\irqnr, #32		@ IRQ# too big?
+		blge	_netarm_led_FAIL2
+1002:
+		adr	\base, irq_prio_netarm
+		.endm
+		
+		.macro	irq_prio_table
+irq_prio_netarm:
+		.byte   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+		.byte   16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
+		.endm
+
+#elif defined(CONFIG_CPU_S3C4510) || defined(CONFIG_CPU_S3C4530)
+
+		.macro disable_fiq
+		.endm
+
+		.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\base, =INTOSET_IRQ
+		ldr	\irqnr, [\base]
+		mov	\irqnr, \irqnr, lsr #2
+		teq	\irqnr, #NR_IRQS
+		.endm
+
+		.macro irq_prio_table
+		.endm
+
+#elif defined(CONFIG_CPU_S3C2500)
+
+		.macro disable_fiq
+		.endm
+
+		.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\base, =INTOFFSET_IRQ
+		ldr	\irqnr, [\base]
+		teq	\irqnr, #NR_IRQS
+		.endm
+
+		.macro irq_prio_table
+		.endm
+
+
+#elif defined(CONFIG_CPU_S3C3410)
+
+		.macro disable_fiq
+		.endm
+
+		.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+		
+		ldr	\irqstat, =.LCintpnd	@ load address of interrupt pending
+		ldr	\irqstat, [\irqstat]	@ register INTPND
+		ldr	\irqnr, [\irqstat]	@ \irqnr = INTPND
+		add	\irqstat, \irqstat, #(S3C3410X_INTMSK-S3C3410X_INTPND)
+		ldr	\irqstat, [\irqstat]	@ \irqstat = INTMSK
+		and	\irqstat, \irqnr, \irqstat @ \irqstat = (INTPND & INTMSK)
+
+		mov     \irqnr, #0
+1001:
+		tst     \irqstat, #1
+		bne     1002f
+		add     \irqnr, \irqnr, #1
+		mov     \irqstat, \irqstat, lsr #1
+		cmp     \irqnr, #32
+		bcc     1001b
+1002:		/* EQ will be set if we reach 32 */
+		.endm
+		.macro irq_prio_table
+		.endm
+
+#elif defined(CONFIG_CPU_S3C44B0X)
+
+		.macro disable_fiq
+		.endm
+
+		.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\irqstat, =.LCint_ispr	 	@ load address of pending interrupt service register
+		ldr	\base, [\irqstat]	    	@ load address of ISPR
+		ldr	\irqstat, [\base]	    	@ \irqnr = INT_ISPR
+		mov     \irqnr, #0
+1001:
+		tst	\irqstat, #1
+		bne	1002f
+		add	\irqnr, \irqnr, #1
+		cmp	\irqnr, #32
+		movcc	\irqstat, \irqstat, lsr #1
+		bcc     1001b
+1002:		/* EQ will be set if we reach 32 */
+                .endm
+
+		.macro irq_prio_table
+		.endm
+
+#elif defined(CONFIG_ARCH_SWARM)
+
+		.macro  disable_fiq
+		.endm
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr     \irqstat, =SWARM_INT_IRQ_STATUS
+		ldr     \irqstat, [\irqstat]            @ get interrupts
+
+		mov     \irqnr, #0
+1001:
+		tst     \irqstat, #1
+		bne     1002f
+		add     \irqnr, \irqnr, #1
+		mov     \irqstat, \irqstat, lsr #1
+		cmp     \irqnr, #32
+		bcc     1001b
+1002:		/* EQ will be set if we reach 32 */
+		.endm
+
+		.macro  irq_prio_table
+irq_prio_swarm:
+		.byte   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
+		.endm
+
+#elif defined(CONFIG_ARCH_IPOD)
+
+#include <asm/arch/irqs.h>
+
+#define IDE_INT0_MASK	(1 << IDE_INT0_IRQ)
+#define SER0_MASK	(1 << SER0_IRQ)
+#define I2S_MASK	(1 << I2S_IRQ)
+#define SER1_MASK	(1 << SER1_IRQ)
+#define TIMER1_MASK	(1 << TIMER1_IRQ)
+#define GPIO_MASK	(1 << GPIO_IRQ)
+#define DMA_OUT_MASK	(1 << DMA_OUT_IRQ)
+
+		.macro	disable_fiq
+.ifdef NOTDEF
+		mrs	r13, spsr
+		orr	r13, r13, #F_BIT
+		msr	spsr_c, r13
+.endif
+		ldr	pc, cop_fiq_loc
+
+cop_fiq_loc:	.word	cop_fiq
+
+		.endm
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+		ldr 	\base, =(0xcf001000)
+		ldr	\irqstat, [\base]
+
+#if 1
+		tst	\irqstat, #DMA_OUT_MASK
+		movne	\irqnr, #DMA_OUT_IRQ
+		bne	1001f
+
+		tst	\irqstat, #GPIO_MASK
+		movne	\irqnr, #GPIO_IRQ
+		bne	1001f
+
+		tst	\irqstat, #IDE_INT0_MASK
+		movne	\irqnr, #IDE_INT0_IRQ
+		bne	1001f
+
+		tst	\irqstat, #SER1_MASK
+		movne	\irqnr, #SER1_IRQ
+		bne	1001f
+
+		tst	\irqstat, #I2S_MASK
+		movne	\irqnr, #I2S_IRQ
+		bne	1001f
+
+		tst	\irqstat, #SER0_MASK
+		movne	\irqnr, #SER0_IRQ
+		bne	1001f
+
+		tst	\irqstat, #TIMER1_MASK
+		movne	\irqnr, #TIMER1_IRQ
+		bne	1001f
+
+1001:
+
+#else
+		mov     \irqnr, #0
+1001:
+		tst     \irqstat, #1
+		bne     1002f
+		add     \irqnr, \irqnr, #1
+		mov     \irqstat, \irqstat, lsr #1
+		cmp     \irqnr, #32
+		bcc     1001b
+1002:		/* EQ will be set if we reach 32 */
+
+#endif
+		.endm
+
+		.macro irq_prio_table
+		.endm
+
+#elif defined(CONFIG_ARCH_VC547X)
+#include <asm/arch/hardware.h>
+                .macro  disable_fiq
+                .endm
+
+                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+                ldr     \irqstat, =SRC_IRQ_REG
+                ldr     \irqstat, [\irqstat]            @ Get Source IRQ Reg
+                mov     \irqnr, #0                      @ Assume IRQ0_IRQ set
+1001:
+                tst     \irqstat, #1                    @ Is IRQ set?
+                bne     1002f                           @ Yes... exit with NEQ
+                add     \irqnr, \irqnr, #1              @ Assume next IRQ set
+                mov     \irqstat, \irqstat, lsr #1      @ Shift right one
+                cmp     \irqnr, #16                     @ Only 16 valid bits
+                bcc     1001b                           @ Exit EQ if past 15
+1002:
+                .endm
+
+                .macro  irq_prio_table
+                .endm
+
+#elif defined(CONFIG_ARCH_DM270)
+
+		.macro disable_fiq
+		.endm
+
+		.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\base, =DM270_INTC_IRQENTRY0    @ Assume default interrupt priority and
+		ldrh	\irqnr, [\base]                 @ Interrupt Entry Table is located within 64K-byte boundary
+		mov     \irqnr, \irqnr, lsr #2          @ at address 0 & size of each entry is 4
+		teq	\irqnr, #0
+		sub	\irqnr, \irqnr, #1		@ 1st entry is dummy
+		.endm
+
+		.macro irq_prio_table
+		.endm
+
+#elif defined( CONFIG_ARCH_POLDHU )
+
+/*
+ * The Poldhu has 23 interrupt sources, each represented by a status
+ * bit in uIRQStatus.  
+ */
+		.macro  disable_fiq
+		.endm
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov     \irqstat, #PERIPH_BASE
+		ldr     \irqstat, [\irqstat, #uIRQStatus - PERIPH_BASE]
+		movs	\irqnr, \irqstat, lsr #16             @ check high 
+		adrne	\base, irq_prio_poldhu_h	    @ 
+		bne	    1001f				                @ found high 
+		movs	\irqnr, \irqstat, lsr #8	            @ check middle
+		adrne	\base, irq_prio_poldhu_m
+		moveq	\irqnr, \irqstat
+		adreq	\base, irq_prio_poldhu_l	    @ get low
+		teq     \irqnr, #0                      @ clear Zero flag if interrupt present
+1001:
+		ldrneb  \irqnr, [\base, \irqnr]         @ determine in irq_nr
+		.endm
+                
+		.macro  irq_prio_table
+
+irq_prio_poldhu_l:
+		.byte	 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+		.byte	 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+		.byte	 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+		.byte	 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+		.byte	 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+		.byte	 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+		.byte	 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+		.byte	 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+		.byte	 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+		.byte	 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+		.byte	 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+		.byte	 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+		.byte	 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+		.byte	 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+		.byte	 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+		.byte	 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+
+irq_prio_poldhu_m:
+		.byte	 0, 8, 9, 8,10, 8, 9, 8,11, 8, 9, 8,10, 8, 9, 8
+		.byte	12, 8, 9, 8,10, 8, 9, 8,11, 8, 9, 8,10, 8, 9, 8
+		.byte	13, 8, 9, 8,10, 8, 9, 8,11, 8, 9, 8,10, 8, 9, 8
+		.byte	12, 8, 9, 8,10, 8, 9, 8,11, 8, 9, 8,10, 8, 9, 8
+		.byte	14, 8, 9, 8,10, 8, 9, 8,11, 8, 9, 8,10, 8, 9, 8
+		.byte	12, 8, 9, 8,10, 8, 9, 8,11, 8, 9, 8,10, 8, 9, 8
+		.byte	13, 8, 9, 8,10, 8, 9, 8,11, 8, 9, 8,10, 8, 9, 8
+		.byte	12, 8, 9, 8,10, 8, 9, 8,11, 8, 9, 8,10, 8, 9, 8
+		.byte	15, 8, 9, 8,10, 8, 9, 8,11, 8, 9, 8,10, 8, 9, 8
+		.byte	12, 8, 9, 8,10, 8, 9, 8,11, 8, 9, 8,10, 8, 9, 8
+		.byte	13, 8, 9, 8,10, 8, 9, 8,11, 8, 9, 8,10, 8, 9, 8
+		.byte	12, 8, 9, 8,10, 8, 9, 8,11, 8, 9, 8,10, 8, 9, 8
+		.byte	14, 8, 9, 8,10, 8, 9, 8,11, 8, 9, 8,10, 8, 9, 8
+		.byte	12, 8, 9, 8,10, 8, 9, 8,11, 8, 9, 8,10, 8, 9, 8
+		.byte	13, 8, 9, 8,10, 8, 9, 8,11, 8, 9, 8,10, 8, 9, 8
+		.byte	12, 8, 9, 8,10, 8, 9, 8,11, 8, 9, 8,10, 8, 9, 8
+
+irq_prio_poldhu_h:
+		.byte	 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+
+		.endm
+
+#elif defined( CONFIG_ARCH_ISL3893 )
+
+/*
+ * The ISL3893 has 25 (NR_IRQS) interrupt sources, each represented by a status
+ * bit in aIRQStatus
+ * We walk from bit 0 up. The lowest interrupt numbers have priority over the
+ * higher ones.
+ */
+		.macro  disable_fiq
+		.endm
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov     \irqstat, #PERIPH_BASE
+		ldr     \irqstat, [\irqstat, #aIRQStatus]
+
+		mov     \irqnr, #0
+1001:
+		tst     \irqstat, #1
+		bne     1002f
+		add     \irqnr, \irqnr, #1
+		mov     \irqstat, \irqstat, lsr #1
+		cmp     \irqnr, #NR_IRQS
+		bcc     1001b
+1002:
+		.endm
+
+		.macro  irq_prio_table
+		.endm
+
+#else
+#error Unknown architecture
+#endif
+
+/*
+ * Invalid mode handlers
+ */
+__pabt_invalid:	sub	sp, sp, #S_FRAME_SIZE		@ Allocate frame size in one go
+		stmia	sp, {r0 - lr}			@ Save XXX r0 - lr
+		ldr	r4, .LCabt
+		mov	r1, #BAD_PREFETCH
+		b	1f
+
+__dabt_invalid:	sub	sp, sp, #S_FRAME_SIZE
+		stmia	sp, {r0 - lr}			@ Save SVC r0 - lr [lr *should* be intact]
+		ldr	r4, .LCabt
+		mov	r1, #BAD_DATA
+		b	1f
+
+__irq_invalid:	sub	sp, sp, #S_FRAME_SIZE		@ Allocate space on stack for frame
+		stmfd	sp, {r0 - lr}			@ Save r0 - lr
+		ldr	r4, .LCirq
+		mov	r1, #BAD_IRQ
+		b	1f
+
+__und_invalid:	sub	sp, sp, #S_FRAME_SIZE
+		stmia	sp, {r0 - lr}
+		ldr	r4, .LCund
+		mov	r1, #BAD_UNDEFINSTR		@ int reason
+
+1:		zero_fp
+		ldmia	r4, {r5 - r7}			@ Get XXX pc, cpsr, old_r0
+		add	r4, sp, #S_PC
+		stmia	r4, {r5 - r7}			@ Save XXX pc, cpsr, old_r0
+		mov	r0, sp
+		and	r2, r6, #31			@ int mode
+		b	SYMBOL_NAME(bad_mode)
+
+#if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE
+		/* The FPE is always present */
+		.equ	fpe_not_present, 0
+#else
+wfs_mask_data:	.word	0x0e200110			@ WFS/RFS
+		.word	0x0fef0fff
+		.word	0x0d000100			@ LDF [sp]/STF [sp]
+		.word	0x0d000100			@ LDF [fp]/STF [fp]
+		.word	0x0f000f00
+
+/* We get here if an undefined instruction happens and the floating
+ * point emulator is not present.  If the offending instruction was
+ * a WFS, we just perform a normal return as if we had emulated the
+ * operation.  This is a hack to allow some basic userland binaries
+ * to run so that the emulator module proper can be loaded. --philb
+ */
+fpe_not_present:
+		adr	r10, wfs_mask_data
+		ldmia	r10, {r4, r5, r6, r7, r8}
+		ldr	r10, [sp, #S_PC]		@ Load PC
+		sub	r10, r10, #4
+		mask_pc	r10, r10
+		ldrt	r10, [r10]			@ get instruction
+		and	r5, r10, r5
+		teq	r5, r4				@ Is it WFS?
+		moveq	pc, r9
+		and	r5, r10, r8
+		teq	r5, r6				@ Is it LDF/STF on sp or fp?
+		teqne	r5, r7
+		movne	pc, lr
+		tst	r10, #0x00200000		@ Does it have WB
+		moveq	pc, r9
+		and	r4, r10, #255			@ get offset
+		and	r6, r10, #0x000f0000
+		tst	r10, #0x00800000		@ +/-
+		ldr	r5, [sp, r6, lsr #14]		@ Load reg
+		rsbeq	r4, r4, #0
+		add	r5, r5, r4, lsl #2
+		str	r5, [sp, r6, lsr #14]		@ Save reg
+		mov	pc, r9
+#endif
+
+/*
+ * SVC mode handlers
+ */
+		.align	5
+__dabt_svc:	sub	sp, sp, #S_FRAME_SIZE
+		stmia	sp, {r0 - r12}			@ save r0 - r12
+		ldr	r2, .LCabt
+		add	r0, sp, #S_FRAME_SIZE
+		ldmia	r2, {r2 - r4}			@ get pc, cpsr
+		add	r5, sp, #S_SP
+		mov	r1, lr
+		stmia	r5, {r0 - r4}			@ save sp_SVC, lr_SVC, pc, cpsr, old_ro
+		mrs	r9, cpsr			@ Enable interrupts if they were
+		tst	r3, #I_BIT
+		biceq	r9, r9, #I_BIT			@ previously
+		mov	r0, r2
+/*
+ * This routine must not corrupt r9
+ */
+#ifdef MULTI_CPU
+		ldr	r2, .LCprocfns
+		mov	lr, pc
+		ldr	pc, [r2]			@ call processor specific code
+#else
+		bl	cpu_data_abort
+#endif
+		msr	cpsr_c, r9
+		mov	r2, sp
+		bl	SYMBOL_NAME(do_DataAbort)
+		mrs	r0, cpsr
+		bic	r0, r0, #MODE_MASK
+		orr	r0, r0, #I_BIT | MODE_SVC	@ preserve FIQ bit
+		msr	cpsr_c, r0
+		ldr	r0, [sp, #S_PSR]
+		msr	spsr, r0
+		ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
+
+		.align	5
+		
+__irq_svc:	sub	sp, sp, #S_FRAME_SIZE
+		stmia	sp, {r0 - r12}			@ save r0 - r12
+		ldr	r7, .LCirq
+		add	r5, sp, #S_FRAME_SIZE
+		ldmia	r7, {r7 - r9}
+		add	r4, sp, #S_SP
+		mov	r6, lr
+		stmia	r4, {r5, r6, r7, r8, r9}	@ save sp_SVC, lr_SVC, pc, cpsr, old_ro
+1:		get_irqnr_and_base r0, r6, r5, lr
+		movne	r1, sp
+		@
+		@ routine called with r0 = irq number, r1 = struct pt_regs *
+		@
+#ifdef CONFIG_ARCH_ATMEL
+                adrsvc  ne, lr, 2f
+                bne     do_IRQ
+2:		ldr     r0, =AIC_EOICR
+                str     r0, [r0]
+#else
+		adrsvc	ne, lr, 3f  	    	    	@ 1b
+		bne	do_IRQ
+#endif
+3:
+		ldr	r0, [sp, #S_PSR]		@ irqs are already disabled
+		msr	spsr, r0
+		ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
+
+		.align	5
+__und_svc:	sub	sp, sp, #S_FRAME_SIZE
+		stmia	sp, {r0 - r12}			@ save r0 - r12
+		ldr	r7, .LCund
+		mov	r6, lr
+		ldmia	r7, {r7 - r9}
+		add	r5, sp, #S_FRAME_SIZE
+		add	r4, sp, #S_SP
+		stmia	r4, {r5 - r9}			@ save sp_SVC, lr_SVC, pc, cpsr, old_ro
+
+		adrsvc	al, r9, 1f			@ r9  = normal FP return
+		bl	call_fpe			@ lr  = undefined instr return
+
+		mov	r0, r5				@ unsigned long pc
+		mov	r1, sp				@ struct pt_regs *regs
+		bl	SYMBOL_NAME(do_undefinstr)
+
+1:		mrs	r0, cpsr
+		bic	r0, r0, #MODE_MASK		@ preserve F-bit
+		orr	r0, r0, #I_BIT | MODE_SVC
+		msr	cpsr_c, r0
+		ldr	lr, [sp, #S_PSR]		@ Get SVC cpsr
+		msr	spsr, lr
+		ldmia	sp, {r0 - pc}^			@ Restore SVC registers
+
+		.align	5
+__pabt_svc:	sub	sp, sp, #S_FRAME_SIZE
+		stmia	sp, {r0 - r12}			@ save r0 - r12
+		ldr	r2, .LCabt
+		add	r0, sp, #S_FRAME_SIZE
+		ldmia	r2, {r2 - r4}			@ get pc, cpsr
+		add	r5, sp, #S_SP
+		mov	r1, lr
+		stmia	r5, {r0 - r4}			@ save sp_SVC, lr_SVC, pc, cpsr, old_ro
+		mrs	r9, cpsr			@ Enable interrupts if they were
+		tst	r3, #I_BIT
+		biceq	r9, r9, #I_BIT			@ previously
+		msr	cpsr_c, r9
+		mov	r0, r2				@ address (pc)
+		mov	r1, sp				@ regs
+		bl	SYMBOL_NAME(do_PrefetchAbort)	@ call abort handler
+		mrs	r0, cpsr
+		bic	r0, r0, #MODE_MASK		@ preserve F-bit
+		orr	r0, r0, #I_BIT | MODE_SVC
+		msr	cpsr_c, r0
+		ldr	r0, [sp, #S_PSR]
+		msr	spsr, r0
+		ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
+
+		.align	5
+.LCirq:		.word	__temp_irq
+.LCund:		.word	__temp_und
+.LCabt:		.word	__temp_abt
+#ifdef MULTI_CPU
+.LCprocfns:	.word	SYMBOL_NAME(processor)
+#endif
+.LCfp:		.word	SYMBOL_NAME(fp_enter)
+#ifdef CONFIG_CPU_S3C3410
+.LCintpnd:	.word 	S3C3410X_INTPND
+#endif
+#ifdef CONFIG_CPU_S3C44B0X
+.LCint_ispr:	.word 	S3C44B0X_I_ISPR
+#endif
+		irq_prio_table
+
+/*
+ * User mode handlers
+ */
+		.align	5
+__dabt_usr:	sub	sp, sp, #S_FRAME_SIZE		@ Allocate frame size in one go
+		stmia	sp, {r0 - r12}			@ save r0 - r12
+		ldr	r4, .LCabt
+		add	r3, sp, #S_PC
+		ldmia	r4, {r0 - r2}			@ Get USR pc, cpsr
+		stmia	r3, {r0 - r2}			@ Save USR pc, cpsr, old_r0
+		stmdb	r3, {sp, lr}^
+		alignment_trap r4, r7, __temp_abt
+		zero_fp
+#ifdef MULTI_CPU
+		ldr	r2, .LCprocfns
+		mov	lr, pc
+		ldr	pc, [r2]			@ call processor specific code
+#else
+		bl	cpu_data_abort
+#endif
+		mrs	r2, cpsr
+		bic	r2, r2, #I_BIT | MODE_MASK	@ preserve F-bit
+		orr	r2, r2, #MODE_SVC
+		msr	cpsr_c, r2			@ Enable interrupts
+		mov	r2, sp
+		adrsvc	al, lr, ret_from_exception
+		b	SYMBOL_NAME(do_DataAbort)
+
+		.align	5
+__irq_usr:	sub	sp, sp, #S_FRAME_SIZE
+		stmia	sp, {r0 - r12}			@ save r0 - r12
+		ldr	r4, .LCirq
+		add	r8, sp, #S_PC
+		ldmia	r4, {r5 - r7}			@ get saved PC, SPSR
+		stmia	r8, {r5 - r7}			@ save pc, psr, old_r0
+		stmdb	r8, {sp, lr}^
+		alignment_trap r4, r7, __temp_irq
+		zero_fp
+1:		get_irqnr_and_base r0, r6, r5, lr
+		movne	r1, sp
+		@
+		@ routine called with r0 = irq number, r1 = struct pt_regs *
+		@
+#ifdef CONFIG_ARCH_ATMEL
+		adrsvc  ne, lr, 2f
+		bne	do_IRQ
+
+2:		ldr     r0, =AIC_EOICR
+                str     r0, [r0]
+#else
+		adrsvc	ne, lr, 1b
+		bne	do_IRQ
+#endif
+		mov	why, #0
+		get_current_task tsk
+		b	ret_to_user
+
+		.align	5
+__und_usr:	sub	sp, sp, #S_FRAME_SIZE		@ Allocate frame size in one go
+		stmia	sp, {r0 - r12}			@ Save r0 - r12
+		ldr	r4, .LCund
+		add	r8, sp, #S_PC
+		ldmia	r4, {r5 - r7}
+		stmia	r8, {r5 - r7}			@ Save USR pc, cpsr, old_r0
+		stmdb	r8, {sp, lr}^			@ Save user sp, lr
+		alignment_trap r4, r7, __temp_und
+		zero_fp
+		adrsvc	al, r9, ret_from_exception	@ r9  = normal FP return
+		adrsvc	al, lr, fpundefinstr		@ lr  = undefined instr return
+
+call_fpe:	get_current_task r10
+		mov	r8, #1
+		strb	r8, [r10, #TSK_USED_MATH]	@ set current->used_math
+		ldr	r4, .LCfp
+		add	r10, r10, #TSS_FPESAVE		@ r10 = workspace
+		ldr	pc, [r4]			@ Call FP module USR entry point
+
+fpundefinstr:	mrs	r0, cpsr
+		bic	r0, r0, #MODE_MASK | I_BIT	@ preserve F-bit
+		orr	r0, r0, #MODE_SVC
+		msr	cpsr_c, r0			@ Enable interrupts
+		mov	r0, lr
+		mov	r1, sp
+		adrsvc	al, lr, ret_from_exception
+		b	SYMBOL_NAME(do_undefinstr)
+
+		.align	5
+__pabt_usr:	sub	sp, sp, #S_FRAME_SIZE		@ Allocate frame size in one go
+		stmia	sp, {r0 - r12}			@ Save r0 - r12
+		ldr	r4, .LCabt
+		add	r8, sp, #S_PC
+		ldmia	r4, {r5 - r7}			@ Get USR pc, cpsr
+		stmia	r8, {r5 - r7}			@ Save USR pc, cpsr, old_r0
+		stmdb	r8, {sp, lr}^			@ Save sp_usr lr_usr
+		alignment_trap r4, r7, __temp_abt
+		zero_fp
+		mrs	r0, cpsr
+		bic	r0, r0, #MODE_MASK | I_BIT	@ preserve F-bit
+		orr	r0, r0, #MODE_SVC
+		msr	cpsr_c, r0			@ Enable interrupts
+		mov	r0, r5				@ address (pc)
+		mov	r1, sp				@ regs
+		bl	SYMBOL_NAME(do_PrefetchAbort)	@ call abort handler
+		/* fall through */
+/*
+ * This is the return code to user mode for abort handlers
+ */
+ENTRY(ret_from_exception)
+		get_current_task tsk
+		mov	why, #0
+		b	ret_to_user
+
+		.data
+ENTRY(fp_enter)
+		.word	fpe_not_present
+		.text
+/*
+ * Register switch for ARMv3 and ARMv4 processors
+ * r0 = previous, r1 = next, return previous.
+ * previous and next are guaranteed not to be the same.
+ */
+ENTRY(__switch_to)
+		stmfd	sp!, {r4 - sl, fp, lr}		@ Store most regs on stack
+		mrs	ip, cpsr
+		str	ip, [sp, #-4]!			@ Save cpsr_SVC
+		str	sp, [r0, #TSS_SAVE]		@ Save sp_SVC
+		ldr	sp, [r1, #TSS_SAVE]		@ Get saved sp_SVC
+#ifndef CONFIG_UCLINUX
+		ldr	r2, [r1, #TSS_DOMAIN]
+		mcr	p15, 0, r2, c3, c0		@ Set domain register
+#endif
+		ldr	ip, [sp], #4
+		msr	spsr, ip			@ Save tasks CPSR into SPSR for this return
+		ldmfd	sp!, {r4 - sl, fp, pc}^		@ Load all regs saved previously
+
+		.section ".text.init",#alloc,#execinstr
+/*
+ * Vector stubs.  NOTE that we only align 'vector_IRQ' to a cache line boundary,
+ * and we rely on each stub being exactly 48 (1.5 cache lines) in size.  This
+ * means that we only ever load two cache lines for this code, or one if we're
+ * lucky.  We also copy this code to 0x200 so that we can use branches in the
+ * vectors, rather than ldr's.
+ */
+		.align	5
+__stubs_start:
+/*
+ * Interrupt dispatcher
+ * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
+ */
+ENTRY(vector_IRQ)
+    		@
+		@ save mode specific registers
+		@
+		ldr	r13, .LCsirq
+		sub	lr, lr, #4
+		str	lr, [r13]			@ save lr_IRQ
+		mrs	lr, spsr
+		str	lr, [r13, #4]			@ save spsr_IRQ
+		@
+		@ now branch to the relevent MODE handling routine
+		@
+		mrs	r13, spsr			@ switch to SVC_32 mode
+		bic	r13, r13, #MODE_MASK		@ preserve F and T bits
+		orr	r13, r13, #MODE_SVC|I_BIT
+		msr	spsr_c, r13			@ switch to SVC_32 mode
+
+		and	lr, lr, #15
+		ldr	lr, [pc, lr, lsl #2]
+		movs	pc, lr				@ Changes mode and branches
+
+.LCtab_irq:	.word	__irq_usr			@  0  (USR_26 / USR_32)
+		.word	__irq_invalid			@  1  (FIQ_26 / FIQ_32)
+		.word	__irq_invalid			@  2  (IRQ_26 / IRQ_32)
+		.word	__irq_svc			@  3  (SVC_26 / SVC_32)
+		.word	__irq_invalid			@  4
+		.word	__irq_invalid			@  5
+		.word	__irq_invalid			@  6
+		.word	__irq_invalid			@  7
+		.word	__irq_invalid			@  8
+		.word	__irq_invalid			@  9
+		.word	__irq_invalid			@  a
+		.word	__irq_invalid			@  b
+		.word	__irq_invalid			@  c
+		.word	__irq_invalid			@  d
+		.word	__irq_invalid			@  e
+		.word	__irq_invalid			@  f
+
+		.align	5
+
+/*
+ * Data abort dispatcher - dispatches it to the correct handler for the processor mode
+ * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
+ */
+ENTRY(vector_data)
+    		@
+		@ save mode specific registers
+		@
+		ldr	r13, .LCsabt
+		sub	lr, lr, #8
+		str	lr, [r13]
+		mrs	lr, spsr
+		str	lr, [r13, #4]
+		@
+		@ now branch to the relevent MODE handling routine
+		@
+		mrs	r13, spsr
+		bic	r13, r13, #MODE_MASK		@ preserve F and T bits
+		orr	r13, r13, #I_BIT | MODE_SVC
+		msr	spsr_c, r13			@ switch to SVC_32 mode
+
+		and	lr, lr, #15
+		ldr	lr, [pc, lr, lsl #2]
+		movs	pc, lr				@ Changes mode and branches
+
+.LCtab_dabt:	.word	__dabt_usr			@  0  (USR_26 / USR_32)
+		.word	__dabt_invalid			@  1  (FIQ_26 / FIQ_32)
+		.word	__dabt_invalid			@  2  (IRQ_26 / IRQ_32)
+		.word	__dabt_svc			@  3  (SVC_26 / SVC_32)
+		.word	__dabt_invalid			@  4
+		.word	__dabt_invalid			@  5
+		.word	__dabt_invalid			@  6
+		.word	__dabt_invalid			@  7
+		.word	__dabt_invalid			@  8
+		.word	__dabt_invalid			@  9
+		.word	__dabt_invalid			@  a
+		.word	__dabt_invalid			@  b
+		.word	__dabt_invalid			@  c
+		.word	__dabt_invalid			@  d
+		.word	__dabt_invalid			@  e
+		.word	__dabt_invalid			@  f
+
+		.align	5
+
+/*
+ * Prefetch abort dispatcher - dispatches it to the correct handler for the processor mode
+ * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
+ */
+ENTRY(vector_prefetch)
+		@
+		@ save mode specific registers
+		@
+		ldr	r13, .LCsabt
+		sub	lr, lr, #4
+		str	lr, [r13]			@ save lr_ABT
+		mrs	lr, spsr
+		str	lr, [r13, #4]			@ save spsr_ABT
+		@
+		@ now branch to the relevent MODE handling routine
+		@
+		mrs	r13, spsr
+		bic	r13, r13, #MODE_MASK		@ preserve F and T bits
+		orr	r13, r13, #I_BIT | MODE_SVC
+		msr	spsr_c, r13			@ switch to SVC_32 mode
+
+		ands	lr, lr, #15
+		ldr	lr, [pc, lr, lsl #2]
+		movs	pc, lr
+
+.LCtab_pabt:	.word	__pabt_usr			@  0 (USR_26 / USR_32)
+		.word	__pabt_invalid			@  1 (FIQ_26 / FIQ_32)
+		.word	__pabt_invalid			@  2 (IRQ_26 / IRQ_32)
+		.word	__pabt_svc			@  3 (SVC_26 / SVC_32)
+		.word	__pabt_invalid			@  4
+		.word	__pabt_invalid			@  5
+		.word	__pabt_invalid			@  6
+		.word	__pabt_invalid			@  7
+		.word	__pabt_invalid			@  8
+		.word	__pabt_invalid			@  9
+		.word	__pabt_invalid			@  a
+		.word	__pabt_invalid			@  b
+		.word	__pabt_invalid			@  c
+		.word	__pabt_invalid			@  d
+		.word	__pabt_invalid			@  e
+		.word	__pabt_invalid			@  f
+
+		.align	5
+
+/*
+ * Undef instr entry dispatcher - dispatches it to the correct handler for the processor mode
+ * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
+ */
+ENTRY(vector_undefinstr)
+		@
+		@ save mode specific registers
+		@
+		ldr	r13, .LCsund
+		str	lr, [r13]			@ save lr_UND
+		mrs	lr, spsr
+		str	lr, [r13, #4]			@ save spsr_UND
+		@
+		@ now branch to the relevent MODE handling routine
+		@
+		mrs	r13, spsr
+		bic	r13, r13, #MODE_MASK		@ preserve F and T bits
+		orr	r13, r13, #I_BIT | MODE_SVC
+		msr	spsr_c, r13			@ switch to SVC_32 mode
+
+		and	lr, lr, #15
+		ldr	lr, [pc, lr, lsl #2]
+		movs	pc, lr				@ Changes mode and branches
+
+.LCtab_und:	.word	__und_usr			@  0 (USR_26 / USR_32)
+		.word	__und_invalid			@  1 (FIQ_26 / FIQ_32)
+		.word	__und_invalid			@  2 (IRQ_26 / IRQ_32)
+		.word	__und_svc			@  3 (SVC_26 / SVC_32)
+		.word	__und_invalid			@  4
+		.word	__und_invalid			@  5
+		.word	__und_invalid			@  6
+		.word	__und_invalid			@  7
+		.word	__und_invalid			@  8
+		.word	__und_invalid			@  9
+		.word	__und_invalid			@  a
+		.word	__und_invalid			@  b
+		.word	__und_invalid			@  c
+		.word	__und_invalid			@  d
+		.word	__und_invalid			@  e
+		.word	__und_invalid			@  f
+
+		.align	5
+
+/*=============================================================================
+ * Undefined FIQs
+ *-----------------------------------------------------------------------------
+ * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC
+ * MUST PRESERVE SVC SPSR, but need to switch to SVC mode to show our msg.
+ * Basically to switch modes, we *HAVE* to clobber one register...  brain
+ * damage alert!  I don't think that we can execute any code in here in any
+ * other mode than FIQ...  Ok you can switch to another mode, but you can't
+ * get out of that mode without clobbering one register.
+ */
+ENTRY(vector_FIQ)
+    		disable_fiq
+		subs	pc, lr, #4
+
+/*=============================================================================
+ * Address exception handler
+ *-----------------------------------------------------------------------------
+ * These aren't too critical.
+ * (they're not supposed to happen, and won't happen in 32-bit data mode).
+ */
+
+ENTRY(vector_addrexcptn)
+		b	vector_addrexcptn
+
+/*
+ * We group all the following data together to optimise
+ * for CPUs with separate I & D caches.
+ */
+		.align	5
+
+.LCvswi:	.word	vector_swi
+
+.LCsirq:	.word	__temp_irq
+.LCsund:	.word	__temp_und
+.LCsabt:	.word	__temp_abt
+
+#if defined(CONFIG_CPU_S3C3410) || defined(CONFIG_CPU_S3C3410)
+.INTPRIO0:	.word	S3C3410X_INTPRI0
+#endif
+#if defined(CONFIG_CPU_S3C44B0X)
+.INTPRIO_M:  	.word	S3C44B0X_I_PSLV
+.INTPRIO_S:  	.word	S3C44B0X_I_PMST
+.INTCON:    	.word	S3C44B0X_INTCON
+#endif
+
+__stubs_end:
+#if defined(CONFIG_ARCH_VC547X)
+                /* Since C5471 normally has flash down at the
+                   low end of the memory map we won't be able
+                   to plug in our interrupt vectors at run time. */
+
+.LCvectors:     .word   0
+                .word   vector_undefinstr
+                .word   vector_swi
+                .word   vector_prefetch
+                .word   vector_data
+                .word   vector_addrexcptn
+                .word   vector_IRQ
+                .word   vector_FIQ
+
+ENTRY(__trap_init)
+                stmfd   sp !,{r4 - r9, lr}      @ Save link register
+
+                mrs     r0, cpsr
+                bic     r0, r0, #MODE_MASK  @ clear Thumb and mode bits
+                orr     r0, r0, #I_BIT|F_BIT|MODE_SVC  @ +SVC mode -IRQ/FIQ
+                msr     cpsr, r0
+                ldr     r0, =C5471_IRAM_START @ addr of RAM based vector table.
+                adr     r1, .LCvectors
+                ldmia   r1, {r1 - r8}    @ Read our ISR vectors
+                stmia   r0, {r1 - r8}    @ Write vectors in special RAM table.
+                ldmfd   sp!, {r4 - r9, pc}
+#else
+		/* Normal case:  lower memory is writable. */
+		.equ	__real_stubs_start, .LCvectors + 0x200
+
+.LCvectors:
+		swi	SYS_ERROR0
+		b	__real_stubs_start + (vector_undefinstr - __stubs_start)
+		ldr	pc, __real_stubs_start + (.LCvswi - __stubs_start)
+		b	__real_stubs_start + (vector_prefetch - __stubs_start)
+		b	__real_stubs_start + (vector_data - __stubs_start)
+		b	__real_stubs_start + (vector_addrexcptn - __stubs_start)
+		b	__real_stubs_start + (vector_IRQ - __stubs_start)
+		b	__real_stubs_start + (vector_FIQ - __stubs_start)
+		
+#ifdef CONFIG_CPU_S3C44B0X  	/* one jump for non-vectored mode */
+    	    	b   	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+#endif
+
+#ifdef CONFIG_CPU_S3C3410
+		/* 32 interrupt vectors @ 0x0000.0080 */
+		/* preset to the global default handler vector_IRQ */
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+		b	__real_stubs_start + (vector_IRQ - __stubs_start) - 0x60
+#endif
+
+ENTRY(__trap_init)
+		stmfd	sp!, {r4 - r9, lr}
+
+		mrs	r1, cpsr		@ code from 2.0.38
+		bic	r1, r1, #MODE_MASK	@ clear mode bits
+		orr	r1, r1, #I_BIT|F_BIT|MODE_SVC	@ set SVC mode, disable IRQ,FIQ
+		msr	cpsr, r1
+
+#ifdef CONFIG_CPU_S3C3410
+		/* 
+		 * make sure that interrupt priority is not used. Otherwise
+		 * the IRQ and FIQ vector addresses are not writeable
+		 */
+		adr	r1, .INTPRIO0
+		ldr	r1, [r1]
+		ldr	r2, [r1]
+		and	r2, r2, #0x1FFFFFFF
+		str	r2, [r1]
+#endif /* CONFIG_CPU_S3C3410 */
+
+#ifdef CONFIG_CPU_S3C44B0X
+		/** @todo all this priority crap !!
+		 * make sure that interrupt priority is not used. Otherwise
+		 * the IRQ and FIQ vector addresses are not writeable
+		 */
+/*		adr	r1, .INTPRIO_M / .INTPRIO_S */
+/*		ldr	r1, [r1]    	    	    */
+/*		ldr	r2, [r1]    	    	    */
+/*		and	r2, r2, #0x1FFFFFFF 	    */
+/*		str	r2, [r1]    	    	    */
+#endif /* CONFIG_CPU_S3C44B0X */
+		
+		adr	r1, .LCvectors			@ set up the vectors
+		ldmia	r1, {r2, r3, r4, r5, r6, r7, r8, r9}
+		stmia	r0, {r2, r3, r4, r5, r6, r7, r8, r9}
+
+#ifdef CONFIG_CPU_S3C3410
+		/*
+		 * Enable the vector table based interrupt mode
+		 */
+		adr	r4, .INTPRIO0		
+		ldr	r4, [r4]		
+		ldr	r3, [r4]		
+		orr	r3, r3, #0xE0000000	@ bit 31...29 must be set for this
+		str	r3, [r4]
+		
+		mov	r4, r0
+		mov 	r0, #(0x0080)		@ R0 = 0x0080 (RAM)
+		add	r1, r1, #(8*4)		@ R1 = start of vectors (ROM)
+		add	r2, r1, #(32*4)		@ R2 = end of vectors (ROM)
+2:		ldr	r3, [r1], #4
+		str	r3, [r0], #4
+		cmp	r1, r2
+		blt	2b
+		mov	r0, r4
+#endif /* CONFIG_CPU_S3C3410 */
+
+#ifdef CONFIG_CPU_S3C44B0X
+		/*
+		 * Initialize the IRQ-Controller to use non-vectored mode
+		 * We will use the S3C44B0X_I_ISPR register to determine
+		 * the current interrupt to be serviced.
+		 */
+		adr	r4, .INTCON
+		ldr	r4, [r4]		
+		/* non-vectored and enable FIQ/IRQ controlling */
+		ldr	r3, =0x4
+		str	r3, [r4]
+		
+		mov	r4, r0
+		mov 	r0, #(0x0080)		@ R0 = 0x0080 (RAM)
+		add	r1, r1, #(8*4)		@ R1 = start of vectors (ROM)
+		add	r2, r1, #(32*4)		@ R2 = end of vectors (ROM)
+2:		ldr	r3, [r1], #4
+		str	r3, [r0], #4
+		cmp	r1, r2
+		blt	2b
+		mov	r0, r4
+#endif /* CONFIG_CPU_S3C44B0X */
+
+		add	r2, r0, #0x200
+		adr	r0, __stubs_start		@ copy stubs to 0x200
+		adr	r1, __stubs_end
+1:		ldr	r3, [r0], #4
+		str	r3, [r2], #4
+		cmp	r0, r1
+		blt	1b
+		LOADREGS(fd, sp!, {r4 - r9, pc})
+#endif /* defined(CONFIG_ARCH_VC547X) */
+
+		.data
+
+/*
+ * Do not reorder these, and do not insert extra data between...
+ */
+
+__temp_irq:	.word	0				@ saved lr_irq
+		.word	0				@ saved spsr_irq
+		.word	-1				@ old_r0
+__temp_und:	.word	0				@ Saved lr_und
+		.word	0				@ Saved spsr_und
+		.word	-1				@ old_r0
+__temp_abt:	.word	0				@ Saved lr_abt
+		.word	0				@ Saved spsr_abt
+		.word	-1				@ old_r0
+
+		.globl	SYMBOL_NAME(cr_alignment)
+		.globl	SYMBOL_NAME(cr_no_alignment)
+SYMBOL_NAME(cr_alignment):
+		.space	4
+SYMBOL_NAME(cr_no_alignment):
+		.space	4
diff -urN linux-2.4.29/arch/armnommu/kernel/entry-common.S linux-2.4.29-uc1/arch/armnommu/kernel/entry-common.S
--- linux-2.4.29/arch/armnommu/kernel/entry-common.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/entry-common.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,271 @@
+/*
+ *  linux/arch/arm/kernel/entry-common.S
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include "entry-header.S"
+
+/* 
+ * We rely on the fact that R0 is at the bottom of the stack (due to
+ * slow/fast restore user regs).
+ */
+#if S_R0 != 0
+#error "Please fix"
+#endif
+
+/*
+ * Our do_softirq out of line code.  See include/asm-arm/softirq.h for
+ * the calling assembly.
+ */
+	.section ".text.lock","ax"
+ENTRY(__do_softirq)
+	stmfd	sp!, {r0 - r3, ip, lr}
+	bl	do_softirq
+	ldmfd	sp!, {r0 - r3, ip, pc}
+	.previous
+
+	.align	5
+/*
+ * This is the fast syscall return path.  We do as little as
+ * possible here, and this includes saving r0 back into the SVC
+ * stack.
+ */
+ret_fast_syscall:
+	ldr	r1, [tsk, #TSK_NEED_RESCHED]
+	ldr	r2, [tsk, #TSK_SIGPENDING]
+	teq	r1, #0				@ need_resched || sigpending
+	teqeq	r2, #0
+	bne	slow
+	fast_restore_user_regs
+
+/*
+ * Ok, we need to do extra processing, enter the slow path.
+ */
+slow:	str	r0, [sp, #S_R0+S_OFF]!	@ returned r0
+	b	1f
+
+/*
+ * "slow" syscall return path.  "why" tells us if this was a real syscall.
+ */
+reschedule:
+	bl	SYMBOL_NAME(schedule)
+ENTRY(ret_to_user)
+ret_slow_syscall:
+	ldr	r1, [tsk, #TSK_NEED_RESCHED]
+	ldr	r2, [tsk, #TSK_SIGPENDING]
+1:	teq	r1, #0				@ need_resched => schedule()
+	bne	reschedule
+	teq	r2, #0				@ sigpending => do_signal()
+	blne	__do_signal
+	restore_user_regs
+
+__do_signal:
+	mov	r0, #0				@ NULL 'oldset'
+	mov	r1, sp				@ 'regs'
+	mov	r2, why				@ 'syscall'
+	b	SYMBOL_NAME(do_signal)		@ note the bl above sets lr
+
+/*
+ * This is how we return from a fork.  __switch_to will be calling us
+ * with r0 pointing at the previous task that was running (ready for
+ * calling schedule_tail).
+ */
+ENTRY(ret_from_fork)
+	bl	SYMBOL_NAME(schedule_tail)
+	get_current_task tsk
+	ldr	ip, [tsk, #TSK_PTRACE]		@ check for syscall tracing
+	mov	why, #1
+	tst	ip, #PT_TRACESYS		@ are we tracing syscalls?
+	beq	ret_slow_syscall
+	mov	r1, sp
+	mov	r0, #1				@ trace exit [IP = 1]
+	bl	SYMBOL_NAME(syscall_trace)
+	b	ret_slow_syscall
+	
+
+#include "calls.S"
+
+/*=============================================================================
+ * SWI handler
+ *-----------------------------------------------------------------------------
+ */
+
+	/* If we're optimising for StrongARM the resulting code won't 
+	   run on an ARM7 and we can save a couple of instructions.  
+								--pb */
+#ifdef CONFIG_CPU_ARM710
+	.macro	arm710_bug_check, instr, temp
+	and	\temp, \instr, #0x0f000000	@ check for SWI
+	teq	\temp, #0x0f000000
+	bne	.Larm700bug
+	.endm
+
+.Larm700bug:
+	ldr	r0, [sp, #S_PSR]		@ Get calling cpsr
+	sub	lr, lr, #4
+	str	lr, [r8]
+	msr	spsr, r0
+	ldmia	sp, {r0 - lr}^			@ Get calling r0 - lr
+	mov	r0, r0
+	ldr	lr, [sp, #S_PC]			@ Get PC
+	add	sp, sp, #S_FRAME_SIZE
+	movs	pc, lr
+#else
+	.macro	arm710_bug_check, instr, temp
+	.endm
+#endif
+
+	.align	5
+ENTRY(vector_swi)
+#if defined(CONFIG_ARCH_VC547X)
+        /* The C5471 has its vector table in flash.
+           For the case of the SWI, all registers have to be
+           preserved, so we use the stack to hold the register
+           contents of the register used to locate the
+           the kernel interrupt routine.  We recover from this
+           mucking here. */
+
+        ldr     r14,[sp,#-0x4]
+#endif
+	save_user_regs
+	mask_pc	lr, lr
+	zero_fp
+	ldr	scno, [lr, #-4]			@ get SWI instruction
+	arm710_bug_check scno, ip
+
+#ifdef CONFIG_ALIGNMENT_TRAP
+	ldr	ip, __cr_alignment
+	ldr	ip, [ip]
+	mcr	p15, 0, ip, c1, c0		@ update control register
+#endif
+	enable_irqs ip
+
+	str	r4, [sp, #-S_OFF]!		@ push fifth arg
+
+	get_current_task tsk
+	ldr	ip, [tsk, #TSK_PTRACE]		@ check for syscall tracing
+	bic	scno, scno, #0xff000000		@ mask off SWI op-code
+	eor	scno, scno, #OS_NUMBER << 20	@ check OS number
+	adr	tbl, sys_call_table		@ load syscall table pointer
+	tst	ip, #PT_TRACESYS		@ are we tracing syscalls?
+	bne	__sys_trace
+
+	adrsvc	al, lr, ret_fast_syscall	@ return address
+	cmp	scno, #NR_syscalls		@ check upper syscall limit
+	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
+
+	add	r1, sp, #S_OFF
+2:	mov	why, #0				@ no longer a real syscall
+	cmp	scno, #ARMSWI_OFFSET
+	eor	r0, scno, #OS_NUMBER << 20	@ put OS number back
+	bcs	SYMBOL_NAME(arm_syscall)	
+	b	SYMBOL_NAME(sys_ni_syscall)	@ not private func
+
+	/*
+	 * This is the really slow path.  We're going to be doing
+	 * context switches, and waiting for our parent to respond.
+	 */
+__sys_trace:
+	add	r1, sp, #S_OFF
+	mov	r0, #0				@ trace entry [IP = 0]
+	bl	SYMBOL_NAME(syscall_trace)
+
+	adrsvc	al, lr, __sys_trace_return	@ return address
+	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
+	cmp	scno, #NR_syscalls		@ check upper syscall limit
+	ldmccia	r1, {r0 - r3}			@ have to reload r0 - r3
+	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
+	b	2b
+
+__sys_trace_return:
+	str	r0, [sp, #S_R0 + S_OFF]!	@ save returned r0
+	mov	r1, sp
+	mov	r0, #1				@ trace exit [IP = 1]
+	bl	SYMBOL_NAME(syscall_trace)
+	b	ret_slow_syscall
+
+	.align	5
+#ifdef CONFIG_ALIGNMENT_TRAP
+	.type	__cr_alignment, #object
+__cr_alignment:
+	.word	SYMBOL_NAME(cr_alignment)
+#endif
+
+	.type	sys_call_table, #object
+ENTRY(sys_call_table)
+#include "calls.S"
+
+/*============================================================================
+ * Special system call wrappers
+ */
+@ r0 = syscall number
+@ r5 = syscall table
+		.type	sys_syscall, #function
+SYMBOL_NAME(sys_syscall):
+		eor	scno, r0, #OS_NUMBER << 20
+		cmp	scno, #NR_syscalls	@ check range
+		stmleia	sp, {r5, r6}		@ shuffle args
+		movle	r0, r1
+		movle	r1, r2
+		movle	r2, r3
+		movle	r3, r4
+		ldrle	pc, [tbl, scno, lsl #2]
+		b	sys_ni_syscall
+
+sys_fork_wrapper:
+		add	r0, sp, #S_OFF
+		b	SYMBOL_NAME(sys_fork)
+
+sys_vfork_wrapper:
+		add	r0, sp, #S_OFF
+		b	SYMBOL_NAME(sys_vfork)
+
+sys_execve_wrapper:
+		add	r3, sp, #S_OFF
+		b	SYMBOL_NAME(sys_execve)
+
+sys_clone_wapper:
+		add	r2, sp, #S_OFF
+		b	SYMBOL_NAME(sys_clone)
+
+sys_sigsuspend_wrapper:
+		add	r3, sp, #S_OFF
+		b	SYMBOL_NAME(sys_sigsuspend)
+
+sys_rt_sigsuspend_wrapper:
+		add	r2, sp, #S_OFF
+		b	SYMBOL_NAME(sys_rt_sigsuspend)
+
+sys_sigreturn_wrapper:
+		add	r0, sp, #S_OFF
+		b	SYMBOL_NAME(sys_sigreturn)
+
+sys_rt_sigreturn_wrapper:
+		add	r0, sp, #S_OFF
+		b	SYMBOL_NAME(sys_rt_sigreturn)
+
+sys_sigaltstack_wrapper:
+		ldr	r2, [sp, #S_OFF + S_SP]
+		b	do_sigaltstack
+
+/*
+ * Note: off_4k (r5) is always units of 4K.  If we can't do the requested
+ * offset, we return EINVAL.
+ */
+sys_mmap2:
+#if PAGE_SHIFT > 12
+		tst	r5, #PGOFF_MASK
+		moveq	r5, r5, lsr #PAGE_SHIFT - 12
+		streq	r5, [sp, #4]
+		beq	do_mmap2
+		mov	r0, #-EINVAL
+		RETINSTR(mov,pc, lr)
+#else
+		str	r5, [sp, #4]
+		b	do_mmap2
+#endif
diff -urN linux-2.4.29/arch/armnommu/kernel/entry-header.S linux-2.4.29-uc1/arch/armnommu/kernel/entry-header.S
--- linux-2.4.29/arch/armnommu/kernel/entry-header.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/entry-header.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,201 @@
+#include <linux/config.h> /* for CONFIG_ARCH_xxxx */
+#include <linux/linkage.h>
+
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/errno.h>
+#include <asm/hardware.h>
+#include <asm/arch/irqs.h>
+#include <asm/proc-fns.h>
+
+#ifndef MODE_SVC
+#define MODE_SVC 0x13
+#endif
+
+		.macro	zero_fp
+#ifndef CONFIG_NO_FRAME_POINTER
+		mov	fp, #0
+#endif
+		.endm
+
+		.text
+
+@ Bad Abort numbers
+@ -----------------
+@
+#define BAD_PREFETCH	0
+#define BAD_DATA	1
+#define BAD_ADDREXCPTN	2
+#define BAD_IRQ		3
+#define BAD_UNDEFINSTR	4
+
+#define PT_TRACESYS	0x00000002
+
+@ OS version number used in SWIs
+@  RISC OS is 0
+@  RISC iX is 8
+@
+#define OS_NUMBER	9
+#define ARMSWI_OFFSET	0x000f0000
+
+@
+@ Stack format (ensured by USER_* and SVC_*)
+@
+#define S_FRAME_SIZE	72
+#ifdef CONFIG_CPU_32
+#define S_OLD_R0	68
+#define S_PSR		64
+#else
+#define S_OLD_R0	64
+#define S_PSR		60
+#define S_PC		60
+#endif
+
+#define S_PC		60
+#define S_LR		56
+#define S_SP		52
+#define S_IP		48
+#define S_FP		44
+#define S_R10		40
+#define S_R9		36
+#define S_R8		32
+#define S_R7		28
+#define S_R6		24
+#define S_R5		20
+#define S_R4		16
+#define S_R3		12
+#define S_R2		8
+#define S_R1		4
+#define S_R0		0
+#define S_OFF		8
+
+#ifdef CONFIG_CPU_32
+		.macro	save_user_regs
+		sub	sp, sp, #S_FRAME_SIZE
+		stmia	sp, {r0 - r12}			@ Calling r0 - r12
+		add	r8, sp, #S_PC
+		stmdb	r8, {sp, lr}^			@ Calling sp, lr
+		mrs	r7, spsr
+		str	lr, [sp, #S_PC]			@ Save calling PC
+		str	r7, [sp, #S_PSR]		@ Save CPSR
+		str	r0, [sp, #S_OLD_R0]		@ Save OLD_R0
+		.endm
+
+		.macro	restore_user_regs
+		ldr	r0, [sp, #S_PSR]		@ Get calling cpsr
+		mov	ip, #I_BIT | MODE_SVC
+		msr	cpsr_c, ip			@ disable IRQs
+		msr	spsr, r0			@ save in spsr_svc
+		ldr	lr, [sp, #S_PC]			@ Get PC
+		ldmia	sp, {r0 - lr}^			@ Get calling r0 - lr
+		mov	r0, r0
+		add	sp, sp, #S_FRAME_SIZE
+		movs	pc, lr				@ return & move spsr_svc into cpsr
+		.endm
+
+		.macro	fast_restore_user_regs
+		mov	ip, #I_BIT | MODE_SVC
+		msr	cpsr_c, ip			@ disable IRQs
+		ldr	r1, [sp, #S_OFF + S_PSR]	@ get calling cpsr
+		ldr	lr, [sp, #S_OFF + S_PC]!	@ get pc
+ 		msr	spsr, r1			@ save in spsr_svc
+		ldmdb	sp, {r1 - lr}^			@ get calling r1 - lr
+		mov	r0, r0
+		add	sp, sp, #S_FRAME_SIZE - S_PC
+		movs	pc, lr				@ return & move spsr_svc into cpsr
+		.endm
+
+		.macro	mask_pc, rd, rm
+		.endm
+
+		.macro	enable_irqs, temp
+		mov	\temp, #MODE_SVC
+		msr	cpsr_c, \temp
+		.endm
+
+		.macro	get_current_task, rd
+		mov	\rd, sp, lsr #13
+		mov	\rd, \rd, lsl #13
+		.endm
+
+		/*
+		 * Like adr, but force SVC mode (if required)
+		 */
+		.macro	adrsvc, cond, reg, label
+		adr\cond	\reg, \label
+		.endm
+
+		.macro	alignment_trap, rbase, rtemp, sym
+#ifdef CONFIG_ALIGNMENT_TRAP
+#define OFF_CR_ALIGNMENT(x)	cr_alignment - x
+
+		ldr	\rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)]
+		mcr	p15, 0, \rtemp, c1, c0
+#endif
+		.endm
+
+#else
+		.macro	save_user_regs
+		str	r0, [sp, #-4]!
+		str	lr, [sp, #-4]!
+		sub	sp, sp, #15*4
+		stmia	sp, {r0 - lr}^
+		mov	r0, r0
+		.endm
+
+		.macro	restore_user_regs
+		ldmia	sp, {r0 - lr}^
+		mov	r0, r0
+		ldr	lr, [sp, #15*4]
+		add	sp, sp, #15*4+8
+		movs	pc, lr
+		.endm
+
+		.macro	fast_restore_user_regs
+		add	sp, sp, #S_OFF
+		ldmib	sp, {r1 - lr}^
+		mov	r0, r0
+		ldr	lr, [sp, #15*4]
+		add	sp, sp, #15*4+8
+		movs	pc, lr
+		.endm
+
+		.macro	mask_pc, rd, rm
+		bic	\rd, \rm, #PCMASK
+		.endm
+
+		.macro	enable_irqs, temp
+		teqp	pc, #0x00000003
+		.endm
+
+		.macro	initialise_traps_extra
+		.endm
+
+		.macro	get_current_task, rd
+		mov	\rd, sp, lsr #13
+		mov	\rd, \rd, lsl #13
+		.endm
+
+		/*
+		 * Like adr, but force SVC mode (if required)
+		 */
+		.macro	adrsvc, cond, reg, label
+		adr\cond	\reg, \label
+		orr\cond	\reg, \reg, #0x08000003
+		.endm
+
+#endif
+
+/*
+ * These are the registers used in the syscall handler, and allow us to
+ * have in theory up to 7 arguments to a function.  Note that tbl == why
+ * is intentional.
+ *
+ * We must set at least "tsk" and "why" when calling ret_with_reschedule.
+ */
+scno	.req	r9				@ syscall number
+tbl	.req	r8				@ syscall table pointer
+why	.req	r8				@ Linux syscall (!= 0)
+tsk	.req	r7				@ current task
+
+
diff -urN linux-2.4.29/arch/armnommu/kernel/fiq.c linux-2.4.29-uc1/arch/armnommu/kernel/fiq.c
--- linux-2.4.29/arch/armnommu/kernel/fiq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/fiq.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,241 @@
+/*
+ *  linux/arch/arm/kernel/fiq.c
+ *
+ *  Copyright (C) 1998 Russell King
+ *  Copyright (C) 1998, 1999 Phil Blundell
+ *
+ *  FIQ support written by Philip Blundell <philb@gnu.org>, 1998.
+ *
+ *  FIQ support re-written by Russell King to be more generic
+ *
+ * We now properly support a method by which the FIQ handlers can
+ * be stacked onto the vector.  We still do not support sharing
+ * the FIQ vector itself.
+ *
+ * Operation is as follows:
+ *  1. Owner A claims FIQ:
+ *     - default_fiq relinquishes control.
+ *  2. Owner A:
+ *     - inserts code.
+ *     - sets any registers,
+ *     - enables FIQ.
+ *  3. Owner B claims FIQ:
+ *     - if owner A has a relinquish function.
+ *       - disable FIQs.
+ *       - saves any registers.
+ *       - returns zero.
+ *  4. Owner B:
+ *     - inserts code.
+ *     - sets any registers,
+ *     - enables FIQ.
+ *  5. Owner B releases FIQ:
+ *     - Owner A is asked to reacquire FIQ:
+ *	 - inserts code.
+ *	 - restores saved registers.
+ *	 - enables FIQ.
+ *  6. Goto 3
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+
+#include <asm/fiq.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pgalloc.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#define FIQ_VECTOR (vectors_base() + 0x1c)
+
+static unsigned long no_fiq_insn;
+
+#ifdef CONFIG_CPU_32
+static inline void unprotect_page_0(void)
+{
+	modify_domain(DOMAIN_USER, DOMAIN_MANAGER);
+}
+
+static inline void protect_page_0(void)
+{
+	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
+}
+#else
+
+#define unprotect_page_0()
+#define protect_page_0()
+
+#endif
+
+/* Default reacquire function
+ * - we always relinquish FIQ control
+ * - we always reacquire FIQ control
+ */
+static int fiq_def_op(void *ref, int relinquish)
+{
+	if (!relinquish) {
+		unprotect_page_0();
+		*(unsigned long *)FIQ_VECTOR = no_fiq_insn;
+		protect_page_0();
+		flush_icache_range(FIQ_VECTOR, FIQ_VECTOR + 4);
+	}
+
+	return 0;
+}
+
+static struct fiq_handler default_owner = {
+	name:	"default",
+	fiq_op:	fiq_def_op,
+};
+
+static struct fiq_handler *current_fiq = &default_owner;
+
+int get_fiq_list(char *buf)
+{
+	char *p = buf;
+
+	if (current_fiq != &default_owner)
+		p += sprintf(p, "FIQ:              %s\n",
+			     current_fiq->name);
+
+	return p - buf;
+}
+
+void set_fiq_handler(void *start, unsigned int length)
+{
+	unprotect_page_0();
+
+	memcpy((void *)FIQ_VECTOR, start, length);
+
+	protect_page_0();
+	flush_icache_range(FIQ_VECTOR, FIQ_VECTOR + length);
+}
+
+/*
+ * Taking an interrupt in FIQ mode is death, so both these functions
+ * disable irqs for the duration. 
+ */
+void set_fiq_regs(struct pt_regs *regs)
+{
+	register unsigned long tmp, tmp2;
+	__asm__ volatile (
+#ifdef CONFIG_CPU_26
+	"mov	%0, pc
+	bic	%1, %0, #0x3
+	orr	%1, %1, %3
+	teqp	%1, #0		@ select FIQ mode
+	mov	r0, r0
+	ldmia	%2, {r8 - r14}
+	teqp	%0, #0		@ return to SVC mode
+	mov	r0, r0"
+#endif
+#ifdef CONFIG_CPU_32
+	"mrs	%0, cpsr
+	mov	%1, %3
+	msr	cpsr_c, %1	@ select FIQ mode
+	mov	r0, r0
+	ldmia	%2, {r8 - r14}
+	msr	cpsr_c, %0	@ return to SVC mode
+	mov	r0, r0"
+#endif
+	: "=&r" (tmp), "=&r" (tmp2)
+	: "r" (&regs->ARM_r8), "I" (I_BIT | F_BIT | FIQ_MODE)
+	/* These registers aren't modified by the above code in a way
+	   visible to the compiler, but we mark them as clobbers anyway
+	   so that GCC won't put any of the input or output operands in
+	   them.  */
+	: "r8", "r9", "r10", "r11", "r12", "r13", "r14");
+}
+
+void get_fiq_regs(struct pt_regs *regs)
+{
+	register unsigned long tmp, tmp2;
+	__asm__ volatile (
+#ifdef CONFIG_CPU_26
+	"mov	%0, pc
+	bic	%1, %0, #0x3
+	orr	%1, %1, %3
+	teqp	%1, #0		@ select FIQ mode
+	mov	r0, r0
+	stmia	%2, {r8 - r14}
+	teqp	%0, #0		@ return to SVC mode
+	mov	r0, r0"
+#endif
+#ifdef CONFIG_CPU_32
+	"mrs	%0, cpsr
+	mov	%1, %3
+	msr	cpsr_c, %1	@ select FIQ mode
+	mov	r0, r0
+	stmia	%2, {r8 - r14}
+	msr	cpsr_c, %0	@ return to SVC mode
+	mov	r0, r0"
+#endif
+	: "=&r" (tmp), "=&r" (tmp2)
+	: "r" (&regs->ARM_r8), "I" (I_BIT | F_BIT | FIQ_MODE)
+	/* These registers aren't modified by the above code in a way
+	   visible to the compiler, but we mark them as clobbers anyway
+	   so that GCC won't put any of the input or output operands in
+	   them.  */
+	: "r8", "r9", "r10", "r11", "r12", "r13", "r14");
+}
+
+int claim_fiq(struct fiq_handler *f)
+{
+	int ret = 0;
+
+	if (current_fiq) {
+		ret = -EBUSY;
+
+		if (current_fiq->fiq_op != NULL)
+			ret = current_fiq->fiq_op(current_fiq->dev_id, 1);
+	}
+
+	if (!ret) {
+		f->next = current_fiq;
+		current_fiq = f;
+	}
+
+	return ret;
+}
+
+void release_fiq(struct fiq_handler *f)
+{
+	if (current_fiq != f) {
+		printk(KERN_ERR "%s FIQ trying to release %s FIQ\n",
+		       f->name, current_fiq->name);
+#ifdef CONFIG_DEBUG_ERRORS
+		__backtrace();
+#endif
+		return;
+	}
+
+	do
+		current_fiq = current_fiq->next;
+	while (current_fiq->fiq_op(current_fiq->dev_id, 0));
+}
+
+void enable_fiq(int fiq)
+{
+	enable_irq(fiq + FIQ_START);
+}
+
+void disable_fiq(int fiq)
+{
+	disable_irq(fiq + FIQ_START);
+}
+
+EXPORT_SYMBOL(set_fiq_handler);
+EXPORT_SYMBOL(set_fiq_regs);
+EXPORT_SYMBOL(get_fiq_regs);
+EXPORT_SYMBOL(claim_fiq);
+EXPORT_SYMBOL(release_fiq);
+EXPORT_SYMBOL(enable_fiq);
+EXPORT_SYMBOL(disable_fiq);
+
+void __init init_FIQ(void)
+{
+	no_fiq_insn = *(unsigned long *)FIQ_VECTOR;
+	set_fs(get_fs());
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/ftv-pci.c linux-2.4.29-uc1/arch/armnommu/kernel/ftv-pci.c
--- linux-2.4.29/arch/armnommu/kernel/ftv-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/ftv-pci.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,51 @@
+/*
+ *  linux/arch/arm/kernel/ftv-pci.c
+ *
+ *  PCI bios-type initialisation for PCI machines
+ *
+ *  Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+
+/*
+ * Owing to a PCB cockup, issue A backplanes are wired thus:
+ *
+ * Slot 1    2    3    4    5   Bridge   S1    S2    S3    S4
+ * IRQ  D    C    B    A    A            C     B     A     D
+ *      A    D    C    B    B            D     C     B     A
+ *      B    A    D    C    C            A     D     C     B
+ *      C    B    A    D    D            B     A     D     C
+ *
+ * ID A31  A30  A29  A28  A27   A26      DEV4  DEV5  DEV6  DEV7
+ *
+ * Actually, this isn't too bad, because with the processor card
+ * in slot 5 on the primary bus, the IRQs rotate on both sides
+ * as you'd expect.
+ */
+
+static int irqmap_ftv[] __initdata = { IRQ_PCI_D, IRQ_PCI_C, IRQ_PCI_B, IRQ_PCI_A };
+
+static int __init ftv_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if (slot > 0x10)
+		slot--;
+	return irqmap_ftv[(slot - pin) & 3];
+}
+
+static u8 __init ftv_swizzle(struct pci_dev *dev, u8 *pin)
+{
+	return PCI_SLOT(dev->devfn);
+}
+
+/* ftv host-specific stuff */
+struct hw_pci ftv_pci __initdata = {
+	init:		plx90x0_init,
+	swizzle:	ftv_swizzle,
+	map_irq:	ftv_map_irq,
+};
+
diff -urN linux-2.4.29/arch/armnommu/kernel/head-arm-dsc21.S linux-2.4.29-uc1/arch/armnommu/kernel/head-arm-dsc21.S
--- linux-2.4.29/arch/armnommu/kernel/head-arm-dsc21.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/head-arm-dsc21.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,237 @@
+/*
+ * head-arm-dsc21.S
+ *
+ * Derived from head-arm-atmel.S and Boot.asm
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *          stevej@ridgerun.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>        
+#include <asm/mach-types.h>
+	                                
+/*
+        This is the define to put us into service mode.
+*/
+#define ARM_MODE_SVC 0x13
+
+/*
+        We need a place for our stack.  For now, let's put it at the end of RAM.
+*/
+#define IRAM_END 0x8000
+                        
+        .text
+        .align
+
+        .globl	__entry,_entry
+        .globl	__stext,_stext
+        .globl _start,start   
+
+start:
+_start:
+_stext:
+_entry:             
+__stext:
+__entry:
+ENTRY(stext)
+
+        /*  turn off IRQ/FIQ and put into service mode, then define top of stack */
+        mov	r0, #(ARM_MODE_SVC | I_BIT | F_BIT )
+        msr	cpsr, r0
+
+        /* don't bother to set stack here.  It will get set after sdram_ini
+        ldr r13, =IRAM_END
+        */
+        
+        /*  Initialize the various clock(pll) registers to TI values */
+        
+        bl clock_ini
+
+        @ wait for a while (for SDRAM)
+        mov	r1, #0xFF00
+wloop:	subs r1, r1, #1
+        bne	wloop
+
+        /*  Initialize the SDRAM controller so we can talk with the 16MB SDRAM */
+
+        bl sdram_ini
+
+#define MEMORY_CLEAR        
+#ifdef MEMORY_CLEAR
+        /*  Write memory test to IRAM */
+        ldr r8, =0x8000
+        ldr r5, =0x0
+        ldr r4, MEMTEST_DATA
+1:      cmp r5, r8 
+        strcc r4, [r5], #4
+        bcc 1b       
+        
+        /*  Write memory test to SDRAM */
+        ldr r8, =0x8200000
+        ldr r5, =0x8000000
+        ldr r4, MEMTEST_DATA
+1:      cmp r5, r8 
+        strcc r4, [r5], #4
+        bcc 1b       
+        
+#endif
+        
+        adr	r5, LC0
+        ldmia	r5, {r5, r6, r8, r9, sp}			@ Setup stack
+
+        /*  Copy data sections to their new home.  */
+
+
+        /*  Clear BSS */
+        mov	r4, #0
+1:      cmp	r5, r8					
+        strcc	r4, [r5],#4
+        bcc	1b
+
+        /*  Put initial values into stack.  This would normally be done
+        by sched_init() in kernel/sched.c, but that would overwrite the
+        stack we're already using.  That would be bad.
+        */
+        mov r5, sp
+        sub r5, r5, #0x2000
+        ldr r4, L_STACK_MAGIC
+        str r4, [r5], #4
+        ldr r4, L_STACK_UNTOUCHED_MAGIC
+1:      cmp r5, sp
+        strcc r4, [r5], #4
+        bcc 1b
+
+        /*  Pretend we know what our processor code is (for arm_id)   */
+	ldr     r2, =0x41007000
+	str     r2, [r6]
+	mov     r2, #MACH_TYPE_DSC21
+	str     r2, [r9]
+
+        mov fp, #0
+        b	start_kernel
+        
+LC0:	.long	__bss_start
+        .long	processor_id
+        .long	_end
+	.long   __machine_arch_type
+        .long	init_task_union+8192
+
+/*
+        Local functions.
+*/
+        
+        .macro regw, reg_add, reg_data
+        ldr r0, \reg_add
+        ldr r1, \reg_data
+        strh r1, [r0]       
+        .endm
+
+        
+                
+/*******************************************************************
+;* CLOCK controller initialize
+;*******************************************************************/
+clock_ini:
+	regw	CLOCKC_PLLARM, PLLARM_DATA
+	regw	CLOCKC_ARMCLK1, ARMCLK_DATA1
+	regw	CLOCKC_ARMCLK2, ARMCLK_DATA2
+	regw	CLOCKC_ARMCLK3, ARMCLK_DATA3
+	regw	CLOCKC_PLLDSP, PLLDSP_DATA
+	regw	CLOCKC_DSPCLK, DSPCLK_DATA
+	regw	CLOCKC_PLLSDR, PLLSDR_DATA
+	regw	CLOCKC_SDRCLK, SDRCLK_DATA
+	regw	CLOCKC_ENCCLK, ENCCLK_DATA
+	regw	CLOCKC_USBCLK, USBCLK_DATA
+	regw	CLOCKC_CCDCLK, CCDCLK_DATA
+
+	mov		pc, lr
+        
+        
+/*******************************************************************
+         SDRAM initialize  (and SDRAM precharge)
+
+        Obviously, there's a lot of redundant work
+        being done here.  Reloading r0 and r1 with values they
+        already have looks silly.  But I don't know if the
+        precharge of the RAM will work if I hammer it 8
+        times in a row without the intervening reads.  So
+        I'll keep TI's timing.
+*******************************************************************/
+sdram_ini:
+	regw	SDRAMC_MODE, SDMODE_DATA
+	regw	SDRAMC_REFCTL, SDREF_DATA
+	regw	SDRAMC_MODE, SDCNT_DATA1
+	regw	SDRAMC_MODE, SDCNT_DATA2
+	regw	SDRAMC_MODE, SDCNT_DATA2
+	regw	SDRAMC_MODE, SDCNT_DATA2
+	regw	SDRAMC_MODE, SDCNT_DATA2
+	regw	SDRAMC_MODE, SDCNT_DATA2
+	regw	SDRAMC_MODE, SDCNT_DATA2
+	regw	SDRAMC_MODE, SDCNT_DATA2
+	regw	SDRAMC_MODE, SDCNT_DATA2
+	regw	SDRAMC_MODE, SDCNT_DATA3
+	mov		pc, lr
+
+
+CLOCKC_PLLARM:    .word	0x30A80
+CLOCKC_ARMCLK1: 	.word	0x30A82
+CLOCKC_ARMCLK2: 	.word	0x30A84
+CLOCKC_ARMCLK3: 	.word	0x30A86
+CLOCKC_PLLDSP:  	.word	0x30A88
+CLOCKC_DSPCLK:  	.word	0x30A8A
+CLOCKC_PLLSDR:  	.word	0x30A8C
+CLOCKC_SDRCLK:  	.word	0x30A8E
+CLOCKC_ENCCLK:  	.word	0x30A90
+CLOCKC_USBCLK:  	.word	0x30A92
+CLOCKC_CCDCLK:  	.word	0x30A94
+
+PLLARM_DATA:   		.word	0x2F80			@ ARM CLK is 37.125MHz
+ARMCLK_DATA1:   	.word	0x7300
+ARMCLK_DATA2:   	.word	0x7E1F
+ARMCLK_DATA3:   	.word	0x3C78
+PLLDSP_DATA:   		.word	0x0C00			@ DSP CLK is 81MHz
+DSPCLK_DATA:   		.word	0x0607
+PLLSDR_DATA:   		.word	0x0800			@ SDRAM CLK is 54MHz
+SDRCLK_DATA:   		.word	0x017E
+ENCCLK_DATA:   		.word	0x475F
+USBCLK_DATA:   		.word	0x0003
+CCDCLK_DATA:   		.word	0x0087
+
+        
+SDRAMC_MODE:      .word	0x309A6
+SDRAMC_REFCTL:    .word	0x309A8
+SDMODE_DATA:      .word	0x0500
+SDREF_DATA:       .word	0x0140
+SDCNT_DATA1:      .word	0x0502
+SDCNT_DATA2:      .word	0x0504
+SDCNT_DATA3:      .word	0x0501
+
+MEMTEST_DATA:   .long 0xa5a5a5a5
+
+        /*  These values should stay in sync with linux/kernel.h */
+        
+L_STACK_MAGIC:  .long 0xdeadbeef
+L_STACK_UNTOUCHED_MAGIC:        .long 0xfeef1ef0
diff -urN linux-2.4.29/arch/armnommu/kernel/head-arm-ipod.S linux-2.4.29-uc1/arch/armnommu/kernel/head-arm-ipod.S
--- linux-2.4.29/arch/armnommu/kernel/head-arm-ipod.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/head-arm-ipod.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,251 @@
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+
+#include <asm/assembler.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+	.equ	C_PROCESSOR_ID, 0xc4000000
+	.equ	C_CPU_SLEEP, 0xca
+	.equ	C_CPU_ID, 0x55
+	.equ	C_CFG_COPROC, 0xcf004058
+
+/*
+ * Reset condition :
+ *      R14_svc         = unknown
+ *      SPSR_svc        = CPSR
+ *      CPSR            = 0b1101_0011 ; not IRQ, no FIQ, SVC mode
+ *      PC              = 0x0
+ */
+	.section ".text.init",#alloc,#execinstr
+	.type   stext, #function
+ENTRY(stext)
+	mov     r0, #0xd3
+	msr     CPSR_c, r0
+
+.ifdef NOTDEF
+	ldr	r1, L_0xcf00502c
+	mov	r0, #0
+	str	r0, [r1]
+
+	ldr	r1, L_0xcf004024
+	mov	r0, #0
+	str	r0, [r1]
+
+	ldr	r1, L_0xcf005000
+	ldr	r0, L_0xb9f
+	str	r0, [r1]
+
+	ldr	r1, L_0xcf005004
+	mov	r0, #0x35
+	str	r0, [r1]
+.endif
+
+	/* clear and mask all interrupts */
+	ldr	r1, L_0xcf00101c
+	mov	r0, #-1
+	str	r0, [r1]
+
+	ldr	r1, L_0xcf001028
+	mov	r0, #-1
+	str	r0, [r1]
+
+	ldr	r1, L_0xcf001038
+	mov	r0, #-1
+	str	r0, [r1]
+
+	/* clear timers */
+	ldr	r1, L_0xcf001100
+	mov	r0, #0
+	str	r0, [r1]
+
+	ldr	r1, L_0xcf001104
+	ldr	r1, [r1]
+
+	ldr	r1, L_0xcf001108
+	mov	r0, #0
+	str	r0, [r1]
+
+	ldr	r1, L_0xcf00110c
+	ldr	r1, [r1]
+
+	/* setup memory mapping */
+	ldr	r1, C_0x40010000
+	ldr	r2, L_install_reloc_start
+	ldr	r3, L_install_reloc_end
+
+	/* copy the code to 0x40010000 */
+1:
+	ldr	r4, [r2], #4
+	str	r4, [r1], #4
+	cmp	r2, r3
+	ble	1b
+
+	ldr	r3, C_0x28003f84
+	ldr	r2, C_0xf000f014
+	mov	r1, #0x3b00
+	ldr	r0, C_0xf000f010
+	ldr	r4, C_0x40010000
+	mov	pc, r4
+
+install_reloc_start:
+	str	r1, [r0]
+	str	r3, [r2]
+	ldr	r0, L_post_reloc_start
+	mov	pc, r0
+
+L_post_reloc_start:	.word post_reloc_start
+
+install_reloc_end:
+
+post_reloc_start:
+	/* check if we are cpu or co-processor */
+	mov	r0, #C_PROCESSOR_ID
+	ldr	r0, [r0]
+	and	r0, r0, #0xff
+	cmp	r0, #C_CPU_ID
+	beq	cpu_startup
+
+	/* we are the co-processor, go to sleep until cpu wakes us up */
+	ldr	r0, L_CFG_COPROC
+	mov	r1, #C_CPU_SLEEP
+	str	r1, [r0]
+
+	/* set stack pointer for FIQ mode */
+	mov	r0, #0xd1
+	msr	CPSR_c, r0
+	ldr	sp, fiq_sp
+
+	/* set stack pointer for SVC mode */
+	mov	r0, #0xd3
+	msr	CPSR_c, r0
+	ldr	sp, svc_sp
+
+.ifdef NOTDEF
+	/* copy our FIQ code to 0x4000000 */
+	mov	r1, #0x40000000
+	ldr	r2, L_cop_start
+	ldr	r3, L_cop_end
+
+	/* copy the code to 0x40000000 */
+1:
+	ldr	r4, [r2], #4
+	str	r4, [r1], #4
+	cmp	r2, r3
+	ble	1b
+.endif
+
+.ifdef NOTDEF
+	/* install our FIQ handler */
+	mov	r1, #0x1c
+	ldr	r2, cop_fiq_vec
+	ldr	r2, [r2]
+	str	r2, [r1]
+.endif
+
+	bl	ipod_init_cache
+
+	/* jump to our idle loop */
+	b	cop_idle
+
+cop_fiq_vec:
+	mov	pc, #0x40000000
+
+svc_sp:		.word cop_svc_stack
+fiq_sp:		.word cop_fiq_stack
+
+L_cop_start:	.word cop_fiq
+L_cop_end:	.word cop_end
+
+L_0xcf00502c:	.word 0xcf00502c
+L_0xcf004024:	.word 0xcf004024
+L_0xcf005000:	.word 0xcf005000
+L_0xb9f:	.word 0xb9f
+L_0xcf005004:	.word 0xcf005004
+L_0xcf00101c:	.word 0xcf00101c
+L_0xcf001028:	.word 0xcf001028
+L_0xcf001038:	.word 0xcf001038
+L_0xcf001100:	.word 0xcf001100
+L_0xcf001104:	.word 0xcf001104
+L_0xcf001108:	.word 0xcf001108
+L_0xcf00110c:	.word 0xcf00110c
+
+cpu_startup:
+	/* get important "magic" values */
+	adr	r5, LC0
+	ldmia	r5, {r5, r6, r8, r9, sp}
+
+	/* initialise bss */
+	mov	r4, #0
+1:
+	cmp	r5, r8
+	strcc	r4, [r5], #4
+	bcc	1b
+
+	bl	ipod_init_cache
+	bl	ipod_set_cpu_speed
+	bl	ipod_set_sys_info
+
+	/* put initial values into stack?? */
+	mov	r5, sp
+	sub	r5, r5, #0x1000
+	ldr	r4, L_STACK_MAGIC
+	str	r4, [r5], #4
+	ldr	r4, L_STACK_UNTOUCHED_MAGIC
+1:
+	cmp	r5, sp
+	strcc	r4, [r5], #4
+	bcc	1b
+
+	/* hard code the ARMID */
+	ldr	r2, L_ARMID
+	str	r2, [r6]
+
+	/* hard code the processor code */
+	mov	r2, #MACH_TYPE_IPOD
+	str	r2, [r9]
+
+	/* jump to the kernel */
+	mov	fp, #0x0
+	b	SYMBOL_NAME(start_kernel)
+
+/*  These values should stay in sync with linux/kernel.h */
+L_STACK_MAGIC:
+		.long 0xdeadbeef
+L_STACK_UNTOUCHED_MAGIC:
+		.long 0xfeef1ef0
+
+L_ARMID:	.long 0x41007700
+
+
+C_0x40010000:	.word 0x40010000
+
+L_install_reloc_start:	.word install_reloc_start
+L_install_reloc_end:	.word install_reloc_end
+
+C_0x28003f84:	.word 0x28003f84
+C_0xf000f014:	.word 0xf000f014
+C_0xf000f010:	.word 0xf000f010
+
+L_CFG_COPROC:	.word C_CFG_COPROC
+
+	.align 8
+LC0:	.long	SYMBOL_NAME(__bss_start)
+	.long	SYMBOL_NAME(processor_id)
+	.long	SYMBOL_NAME(_end)
+	.long	SYMBOL_NAME(__machine_arch_type)
+	.long	SYMBOL_NAME(init_task_union)+8192
+
+#ifdef CONFIG_BLK_DEV_RAM
+	.global __ramdisk_data
+	.global __ramdisk_data_end
+
+	.align 12
+__ramdisk_data:
+	.incbin "../../../initrd"
+__ramdisk_data_end:
+	.align
+
+#endif
+
diff -urN linux-2.4.29/arch/armnommu/kernel/head-arm-netarm.S linux-2.4.29-uc1/arch/armnommu/kernel/head-arm-netarm.S
--- linux-2.4.29/arch/armnommu/kernel/head-arm-netarm.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/head-arm-netarm.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,1556 @@
+/*
+ * =================== STARTUP CODE, Kernel 2.4.x =====================
+ *
+ * linux/arch/armnommu/kernel/head-arm-netarm.S
+ *
+ * Copyright (C) 2000, 2001 NETsilicon, Inc.
+ * Copyright (C) 2000, 2001 Red Hat, Inc.
+ *
+ * This software is copyrighted by Red Hat. LICENSEE agrees that
+ * it will not delete this copyright notice, trademarks or protective
+ * notices from any copy made by LICENSEE.
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall Red Hat
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : Joe deBlaquiere
+ *
+ * Adapted for NS7520 (and some legacy code removed) by Art Shipkowski
+ *
+ * NS7520 improved code RAM copy from FS Forth-Systeme GmbH's fork.
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/mach-types.h>
+#include <asm/arch/netarm_registers.h>
+#include <asm/arch/netarm_mmap.h>
+
+#define	NETARM_INIT_CPSR	(CPSR_I_BIT | CPSR_F_BIT | CPSR_SVC_MODE)
+
+/*
+ * Define which output pin to use for NET+ARM development board blink routine
+ */
+#define NA_YELLOW_LED 0x04
+#define NA_GREEN_LED  0x02
+
+#ifdef CONFIG_NETARM_EMLIN
+/* The (one) green LED is on bit 6 (0x40) */
+#define NA_BLINK_LED 0x40
+#define NA_FAIL_LED  0x40
+#else
+/* Use green and yellow LEDs */
+#define NA_BLINK_LED NA_YELLOW_LED
+#define NA_FAIL_LED NA_GREEN_LED
+#endif
+
+/*
+ * This define is used to determine the number of wait states needed
+ * for the 90 ns flash used on the NET+ARM reference board.  The macro
+ * is only valid for 90 ns flash.  To get this value, the following
+ * calculation was used:
+ *
+ *   ceil(90 / ((1 / FSYSCLK) * 1000)) - 1
+ *
+ * This define gives the same value as the above calculation, but based
+ * on the PLLCNT (instead of on the FSYSCLK).
+*/
+#define FLASH_90ns_WAIT_STATES	((NETARM_PLL_COUNT_VAL + 2) / 3)
+
+		.text
+		.align	12
+
+/*
+ * Reset condition : 
+ *	R14_svc 	= unknown
+ *	SPSR_svc 	= CPSR
+ *	CPSR		= 0b1101_0011 ; not IRQ, no FIQ, SVC mode
+ *	PC		= 0x0
+ */
+
+		.section ".text.init",#alloc,#execinstr
+		.type	stext, #function
+ENTRY(stext)
+  b _reset /* Reset Vector */
+  b _undef /* Undefined Vector */
+  b _swi		/* Software Interrupt */
+  b _abortprefetch /* Abort (Prefetch) */
+  b _abortdata		  /* Abort (Data) */
+  b _reserved				/* Reserved vector */
+  b _irq						  /* IRQ vector */
+  b _firq						 /* Fast IRQ vector */
+
+.global _undef
+_undef:
+	mov	r0, #'#'
+	bl	_printch
+	mov	r0, #'u'
+	bl	_printch
+	mov	r0, lr		
+  bl  _printhex8
+1:
+  b 1b
+
+.global _swi
+_swi:
+	mov	r0, #'#'
+	bl	_printch
+	mov	r0, #'s'
+	bl	_printch
+	mov	r0, lr		
+  bl  _printhex8
+1:
+  b 1b
+
+.global _abortprefetch
+_abortprefetch:
+	mov	r0, #'#'
+	bl	_printch
+	mov	r0, #'p'
+	bl	_printch
+	mov	r0, lr		
+  bl  _printhex8
+1:
+  b 1b
+
+
+.global _abortdata
+_abortdata:
+	mov	r4, r14
+  mov r5, sp
+	mov	r0, #'\n'
+	bl	_printch
+	mov	r0, #'#'
+	bl	_printch
+	mov	r0, #'d'
+	bl	_printch
+	mov	r0, r4
+  bl  _printhex8
+	mov	r0, #'\n'
+	bl	_printch
+	mov	r0, r5
+  bl  _printhex8
+1:
+  b 1b
+
+.global _reserved
+_reserved:
+	mov	r0, #'#'
+	bl	_printch
+	mov	r0, #'r'
+	bl	_printch
+	mov	r0, lr		
+  bl  _printhex8
+1:
+  b 1b
+
+
+.global _irq
+_irq:
+	mov	r0, #'#'
+	bl	_printch
+	mov	r0, #'i'
+	bl	_printch
+	mov	r0, lr		
+  bl  _printhex8
+1:
+  b 1b
+
+
+.global _firq
+_firq:
+	mov	r0, #'#'
+	bl	_printch
+	mov	r0, #'f'
+	bl	_printch
+	mov	r0, lr		
+  bl  _printhex8
+1:
+  b 1b
+
+
+
+.global _reset
+_reset:
+				 		mov	r0, #NETARM_INIT_CPSR
+		msr	cpsr, r0
+#if CONFIG_NETARM_BOOTLOADER_DEBUG_DEBUGGER
+/* delay (0x10000) to allow developer to attach debugger before boot */
+		mov	r1, #0x10000
+1:
+		subs	r1, r1, #1
+		bge	1b	
+#endif 
+/*
+ * prior to software reset : need to set pin PORTC4 to be *HRESET
+ */
+
+		ldr	r4, =NETARM_GEN_MODULE_BASE
+
+		ldr	r1, =( NETARM_GEN_PORT_MODE(0x10) | \
+		               NETARM_GEN_PORT_DIR(0x10) )
+		str	r1, [r4, #+NETARM_GEN_PORTC]		
+
+/*
+ * software reset : see HW Ref. Guide 8.2.4 : Software Service Register
+ *                  for an explanation of this process
+ */
+
+		ldr	r4, =NETARM_GEN_MODULE_BASE
+
+		ldr	r1, =NETARM_GEN_SW_SVC_RESETA
+		str	r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
+		
+		ldr	r1, =NETARM_GEN_SW_SVC_RESETB
+		str	r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
+		
+		ldr	r1, =NETARM_GEN_SW_SVC_RESETA
+		str	r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
+		
+		ldr	r1, =NETARM_GEN_SW_SVC_RESETB
+		str	r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
+
+/*
+ * set up PLL and System Config
+ */
+
+@ r4 already set
+		ldr	r4, =NETARM_GEN_MODULE_BASE
+#ifdef	CONFIG_NETARM_NET40_REV2
+		ldr	r1, =( NETARM_GEN_SYS_CFG_LENDIAN |	\
+			       NETARM_GEN_SYS_CFG_BUSFULL |	\
+			       NETARM_GEN_SYS_CFG_USER_EN |	\
+			       NETARM_GEN_SYS_CFG_ALIGN_ABORT | \
+		               NETARM_GEN_SYS_CFG_BUSARB_INT )
+#else
+		ldr	r1, [r4, #+NETARM_GEN_SYSTEM_CONTROL]
+		ldr	r2, =( NETARM_GEN_SYS_CFG_LENDIAN |	\
+			       NETARM_GEN_SYS_CFG_BUSFULL |	\
+			       NETARM_GEN_SYS_CFG_USER_EN |	\
+		               NETARM_GEN_SYS_CFG_ALIGN_ABORT |	\
+			       NETARM_GEN_SYS_CFG_BUSARB_INT |	\
+							 NETARM_GEN_SYS_CFG_BUSMON_EN )
+		orr	r1, r1, r2
+#endif
+		str	r1, [r4, #+NETARM_GEN_SYSTEM_CONTROL]
+
+#ifndef CONFIG_NETARM_PLL_BYPASS		 
+		ldr	r1, =NETARM_GEN_PLL_CTL_PLLCNT(NETARM_PLL_COUNT_VAL)
+		str	r1, [r4, #+NETARM_GEN_PLL_CONTROL ]
+#endif
+
+/*
+ * initialize both serial ports
+ */
+		
+		bl	_netarm_debug_serial_init
+
+		mov	r0, #'A'
+		bl	_printch
+		
+/*
+ *	if CS0 is already mapped high, assume it's mapped correctly
+ */
+
+		ldr	r4, =NETARM_MEM_MODULE_BASE
+		ldr	r1, [r4, #NETARM_MEM_CS0_BASE_ADDR]
+		ldr	r2, =NETARM_MEM_BAR_BASE_MASK
+		and	r1, r1, r2
+		cmp	r1, #0
+		bne	_exec_in_RAM
+		
+		mov	r0, #'B'
+		bl	_printch
+
+/*		b	_netarm_led_FAIL2 */
+
+/*
+ *	since the system boots without knowing the size of the ROM
+ *	the code is mirrored on every page... so we'll jump to
+ *	a page way up where we're moving the PROM to
+ */
+		
+		ldr	pc, =(_jump_to_high + NETARM_MMAP_CS0_BASE)
+
+/*
+ *	either we now set up the RAM or we were always running from RAM
+ *	and we didn't change the memory settings...
+ */
+
+_jump_to_high:
+
+		mov	r0, #'C'
+		bl	_printch
+		
+/*
+ * test point - jump to blink
+ */
+/*
+ * The NS7520 has a different method of chip select configuration
+ */
+
+		ldr	r4, =NETARM_MEM_MODULE_BASE
+
+#ifndef CONFIG_NETARM_NS7520
+#ifndef CONFIG_NETARM_EMLIN
+/* Settings for NetSilicon's development boards (NET+40, NET+50, ...) */
+
+/* mem config */
+		ldr	r1, =( NETARM_MEM_REFR_PERIOD_USEC(16) | \
+			       NETARM_MEM_CFG_REFRESH_EN | \
+			       NETARM_MEM_CFG_REFR_CYCLE_5CLKS )
+		str	r1, [r4, #NETARM_MEM_MODULE_CONFIG]
+		
+@		mov	r0, #'D'
+@		bl	_printch
+		
+/* CS0 */
+		
+		ldr	r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS0_BASE) | 	\
+			       NETARM_MEM_BAR_DRAM_FP |			\
+			       NETARM_MEM_BAR_DRAM_MUX_INT |		\
+			       NETARM_MEM_BAR_DRAM_MUX_BAL |		\
+			       NETARM_MEM_BAR_VALID )
+		str	r1, [r4, #NETARM_MEM_CS0_BASE_ADDR]
+
+@		mov	r0, #'E'
+@		bl	_printch
+		
+		/* trust that the bus size for flash was strapped correctly */
+		/* this saves the bus width in r2 and then ORs it back in */
+		/* it's a pretty safe assumption, otherwise it wouldn't boot */
+
+		ldr	r2, [r4, #NETARM_MEM_CS0_OPTIONS]
+		and	r2, r2, #NETARM_MEM_OPT_BUS_SIZE_MASK
+
+/*		just a test: assume 32 bit flash mem --rp */
+/*		mov	r2, #NETARM_MEM_OPT_32BIT */
+
+		ldr	r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS0_MASK) |	\
+			       NETARM_MEM_OPT_WAIT_STATES(FLASH_90ns_WAIT_STATES) |		\
+			       NETARM_MEM_OPT_BCYC_2 |			\
+			       NETARM_MEM_OPT_BSIZE_4 | 		\
+			       NETARM_MEM_OPT_READ_ASYNC | 		\
+			       NETARM_MEM_OPT_WRITE_ASYNC )
+		orr	r1, r1, r2
+		str	r1, [r4, #NETARM_MEM_CS0_OPTIONS]
+
+@		mov	r0, #'F'
+@		bl	_printch
+
+#ifdef	CONFIG_NETARM_NET40_REV2
+/* CS1 */
+		ldr	r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS1_MASK) |	\
+			       NETARM_MEM_OPT_BCYC_2 |			\
+			       NETARM_MEM_OPT_BSIZE_16 | 		\
+			       NETARM_MEM_OPT_WAIT_STATES(0) | 		\
+			       NETARM_MEM_OPT_32BIT | 			\
+			       NETARM_MEM_OPT_READ_ASYNC | 		\
+			       NETARM_MEM_OPT_WRITE_ASYNC )
+		str	r1, [r4, #NETARM_MEM_CS1_OPTIONS]
+
+@		mov	r0, #'G'
+@		bl	_printch
+		
+		ldr	r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS1_BASE) | 	\
+			       NETARM_MEM_BAR_DRAM_SYNC |		\
+			       NETARM_MEM_BAR_DRAM_MUX_INT |		\
+			       NETARM_MEM_BAR_DRAM_MUX_UNBAL |		\
+			       NETARM_MEM_BAR_DRAM_SEL |		\
+			       NETARM_MEM_BAR_BURST_EN |		\
+			       NETARM_MEM_BAR_VALID )
+		str	r1, [r4, #NETARM_MEM_CS1_BASE_ADDR]
+
+@		mov	r0, #'H'
+@		bl	_printch
+
+/* CS2 */
+		ldr	r1, =( 0 )
+		str	r1, [r4, #NETARM_MEM_CS2_BASE_ADDR]
+
+@		mov	r0, #'I'
+@		bl	_printch
+
+		ldr	r1, =( 0 )
+		str	r1, [r4, #NETARM_MEM_CS2_OPTIONS]
+
+@		mov	r0, #'J'
+@		bl	_printch
+#else
+/* CS1 */
+		ldr	r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS1_MASK) |	\
+			       NETARM_MEM_OPT_BCYC_3 |			\
+			       NETARM_MEM_OPT_BSIZE_4 | 		\
+			       NETARM_MEM_OPT_WAIT_STATES(0) | 		\
+			       NETARM_MEM_OPT_32BIT | 			\
+			       NETARM_MEM_OPT_READ_ASYNC | 		\
+			       NETARM_MEM_OPT_WRITE_ASYNC )
+		str	r1, [r4, #NETARM_MEM_CS1_OPTIONS]
+
+@		mov	r0, #'G'
+@		bl	_printch
+		
+		ldr	r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS1_BASE) | 	\
+			       NETARM_MEM_BAR_DRAM_FP |		\
+			       NETARM_MEM_BAR_DRAM_MUX_INT |		\
+			       NETARM_MEM_BAR_DRAM_MUX_BAL |		\
+			       NETARM_MEM_BAR_DRAM_SEL |		\
+			       NETARM_MEM_BAR_BURST_EN |		\
+			       NETARM_MEM_BAR_VALID )
+		str	r1, [r4, #NETARM_MEM_CS1_BASE_ADDR]
+
+@		mov	r0, #'H'
+@		bl	_printch
+		
+/* CS2 */
+		ldr	r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS2_MASK) |	\
+			       NETARM_MEM_OPT_BCYC_3 |			\
+			       NETARM_MEM_OPT_BSIZE_4 | 		\
+			       NETARM_MEM_OPT_WAIT_STATES(0) | 		\
+			       NETARM_MEM_OPT_32BIT | 			\
+			       NETARM_MEM_OPT_READ_ASYNC | 		\
+			       NETARM_MEM_OPT_WRITE_ASYNC )
+		str	r1, [r4, #NETARM_MEM_CS2_OPTIONS]
+
+@		mov	r0, #'I'
+@		bl	_printch
+		
+		ldr	r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS2_BASE) | 	\
+			       NETARM_MEM_BAR_DRAM_FP |		\
+			       NETARM_MEM_BAR_DRAM_MUX_INT |		\
+			       NETARM_MEM_BAR_DRAM_MUX_BAL |		\
+			       NETARM_MEM_BAR_DRAM_SEL |		\
+			       NETARM_MEM_BAR_BURST_EN |		\
+			       NETARM_MEM_BAR_VALID )
+		str	r1, [r4, #NETARM_MEM_CS2_BASE_ADDR]
+
+@		mov	r0, #'J'
+@		bl	_printch
+#endif
+
+/* CS3 */
+#ifdef CONFIG_NETARM_EEPROM
+		ldr	r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS3_MASK) |	\
+			       NETARM_MEM_OPT_BCYC_1 |\
+			       NETARM_MEM_OPT_BSIZE_2 | \
+			       NETARM_MEM_OPT_WAIT_STATES(10) | \
+			       NETARM_MEM_OPT_8BIT | \
+			       NETARM_MEM_OPT_READ_ASYNC | \
+			       NETARM_MEM_OPT_WRITE_ASYNC )
+#else
+		ldr	r1, =( 0 )
+#endif
+		str	r1, [r4, #NETARM_MEM_CS3_OPTIONS]
+
+@		mov	r0, #'K'
+@		bl	_printch
+		
+#ifdef CONFIG_NETARM_EEPROM
+		ldr	r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS3_BASE) | 	\
+			       NETARM_MEM_BAR_DRAM_FP |			\
+			       NETARM_MEM_BAR_DRAM_MUX_INT |		\
+			       NETARM_MEM_BAR_DRAM_MUX_BAL |		\
+			       NETARM_MEM_BAR_VALID )
+#else
+		ldr	r1, =( 0 )
+#endif
+		str	r1, [r4, #NETARM_MEM_CS3_BASE_ADDR]
+
+@		mov	r0, #'L'
+@		bl	_printch
+		
+/* CS4 */
+		ldr	r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS4_MASK) |	\
+			       NETARM_MEM_OPT_32BIT_EXT_ACK | \
+			       NETARM_MEM_OPT_READ_ASYNC | \
+			       NETARM_MEM_OPT_WRITE_ASYNC )
+		str	r1, [r4, #NETARM_MEM_CS4_OPTIONS]
+
+		ldr	r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS4_BASE) | 	\
+			       NETARM_MEM_BAR_DRAM_FP |			\
+			       NETARM_MEM_BAR_DRAM_MUX_INT |		\
+			       NETARM_MEM_BAR_DRAM_MUX_BAL |		\
+			       NETARM_MEM_BAR_VALID )
+		str	r1, [r4, #NETARM_MEM_CS4_BASE_ADDR]
+
+#else
+/* Settings for IMMS' EMLIN board */
+/* mem config */
+		ldr	r1, =( NETARM_MEM_REFR_PERIOD_USEC(15) | \
+			       NETARM_MEM_CFG_REFRESH_EN | \
+			       NETARM_MEM_CFG_REFR_CYCLE_8CLKS )
+		str	r1, [r4, #NETARM_MEM_MODULE_CONFIG]
+		
+		mov	r0, #'D'
+		bl	_printch
+		
+/* CS0 (Flash) */
+		ldr	r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS0_BASE) | 	\
+			       NETARM_MEM_BAR_DRAM_FP |			\
+			       NETARM_MEM_BAR_DRAM_MUX_INT |		\
+			       NETARM_MEM_BAR_DRAM_MUX_BAL |		\
+			       NETARM_MEM_BAR_VALID )
+		str	r1, [r4, #NETARM_MEM_CS0_BASE_ADDR]
+
+		mov	r0, #'E'
+		bl	_printch
+		
+		/* trust that the bus size for flash was strapped correctly */
+		/* this saves the bus width in r2 and then ORs it back in */
+		/* it's a pretty safe assumption, otherwise it wouldn't boot */
+
+		ldr	r2, [r4, #NETARM_MEM_CS0_OPTIONS]
+		and	r2, r2, #NETARM_MEM_OPT_BUS_SIZE_MASK
+
+		ldr	r1, =( NETARM_MEM_OPT_BASE_USE(0xFFC00000) |	\
+			       NETARM_MEM_OPT_WAIT_STATES(FLASH_90ns_WAIT_STATES) |		\
+			       NETARM_MEM_OPT_BCYC_2 |			\
+			       NETARM_MEM_OPT_BSIZE_4 | 		\
+			       NETARM_MEM_OPT_READ_ASYNC | 		\
+			       NETARM_MEM_OPT_WRITE_ASYNC )
+		orr	r1, r1, r2
+		str	r1, [r4, #NETARM_MEM_CS0_OPTIONS]
+
+		mov	r0, #'F'
+		bl	_printch
+
+/* CS1 (SDRAM - optional) */
+		ldr	r1, =( NETARM_MEM_OPT_BASE_USE(0xFF000000) |	\
+			       NETARM_MEM_OPT_BCYC_2 |			\
+			       NETARM_MEM_OPT_BSIZE_8 | 		\
+			       NETARM_MEM_OPT_WAIT_STATES(0) | 		\
+			       NETARM_MEM_OPT_32BIT | 			\
+			       NETARM_MEM_OPT_READ_ASYNC | 		\
+			       NETARM_MEM_OPT_WRITE_ASYNC )
+		str	r1, [r4, #NETARM_MEM_CS1_OPTIONS]
+
+		mov	r0, #'G'
+		bl	_printch
+		
+		ldr	r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS2_BASE) | 	\
+			       NETARM_MEM_BAR_DRAM_SYNC |		\
+			       NETARM_MEM_BAR_DRAM_MUX_INT |		\
+			       NETARM_MEM_BAR_DRAM_MUX_UNBAL |		\
+			       NETARM_MEM_BAR_DRAM_SEL )
+		str	r1, [r4, #NETARM_MEM_CS1_BASE_ADDR]
+
+		mov	r0, #'H'
+		bl	_printch
+
+/* CS2 (mainboard SDRAM) */
+		ldr	r1, =( NETARM_MEM_OPT_BASE_USE(0xFF000000) |	\
+			       NETARM_MEM_OPT_BCYC_2 |			\
+			       NETARM_MEM_OPT_BSIZE_8 | 		\
+			       NETARM_MEM_OPT_WAIT_STATES(0) | 		\
+			       NETARM_MEM_OPT_32BIT | 			\
+			       NETARM_MEM_OPT_READ_ASYNC | 		\
+			       NETARM_MEM_OPT_WRITE_ASYNC )
+		str	r1, [r4, #NETARM_MEM_CS2_OPTIONS]
+
+		mov	r0, #'I'
+		bl	_printch
+		
+		ldr	r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS1_BASE) | 	\
+			       NETARM_MEM_BAR_DRAM_SYNC |		\
+			       NETARM_MEM_BAR_DRAM_MUX_INT |		\
+			       NETARM_MEM_BAR_DRAM_MUX_UNBAL |		\
+			       NETARM_MEM_BAR_DRAM_SEL |		\
+			       NETARM_MEM_BAR_VALID )
+		str	r1, [r4, #NETARM_MEM_CS2_BASE_ADDR]
+
+		mov	r0, #'J'
+		bl	_printch
+
+/* CS3 (Peripherals) */
+		ldr	r1, =( NETARM_MEM_OPT_BASE_USE(0xFFF00000) |	\
+			       NETARM_MEM_OPT_BCYC_4 |\
+			       NETARM_MEM_OPT_BSIZE_2 | \
+			       NETARM_MEM_OPT_WAIT_STATES(15) | \
+			       NETARM_MEM_OPT_16BIT | \
+			       NETARM_MEM_OPT_READ_SYNC | \
+			       NETARM_MEM_OPT_WRITE_SYNC )
+		str	r1, [r4, #NETARM_MEM_CS3_OPTIONS]
+
+		mov	r0, #'K'
+		bl	_printch
+		
+		ldr	r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS3_BASE) | 	\
+			       NETARM_MEM_BAR_DRAM_FP |			\
+			       NETARM_MEM_BAR_DRAM_MUX_INT |		\
+			       NETARM_MEM_BAR_1BCLK_IDLE |		\
+			       NETARM_MEM_BAR_DRAM_MUX_BAL |		\
+			       NETARM_MEM_BAR_VALID )
+		str	r1, [r4, #NETARM_MEM_CS3_BASE_ADDR]
+
+		mov	r0, #'L'
+		bl	_printch
+
+/* CS4 (FPGA) */
+		ldr	r1, =( NETARM_MEM_OPT_BASE_USE(0xFFFFF000) |	\
+			       NETARM_MEM_OPT_WAIT_STATES(15) | \
+			       NETARM_MEM_OPT_32BIT | \
+			       NETARM_MEM_OPT_READ_SYNC | \
+			       NETARM_MEM_OPT_WRITE_SYNC )
+		str	r1, [r4, #NETARM_MEM_CS4_OPTIONS]
+
+		ldr	r1, =( 0x30000000 | 	\
+			       NETARM_MEM_BAR_DRAM_FP |			\
+			       NETARM_MEM_BAR_DRAM_MUX_INT |		\
+			       NETARM_MEM_BAR_1BCLK_IDLE |		\
+			       NETARM_MEM_BAR_DRAM_MUX_BAL |		\
+			       NETARM_MEM_BAR_VALID )
+		str	r1, [r4, #NETARM_MEM_CS4_BASE_ADDR]
+
+#endif
+#else
+
+#ifdef CONFIG_BOARD_UNC20
+/* mem config  (0xFFC0 0000)*/
+  	ldr	r1, =( 0x0d000000 | \
+	  					 NETARM_MEM_CFG_REFRESH_EN )
+  	str	r1, [r4, #NETARM_MEM_MODULE_CONFIG]
+  	mov	r0, #'D'
+  	bl	_printch
+/* CS0 FLASH */
+
+
+  /* We are running already from flash, so changing the option register is not a
+     good idea before adjusting base address as the size of chip is stored there.
+     The flash should also be writeable - necessary for probing */
+  	ldr	r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS0_BASE) | 	\
+		         NETARM_MEM_BAR_DRAM_FP |			\
+		         NETARM_MEM_BAR_DRAM_MUX_INT |		\
+		         NETARM_MEM_BAR_DRAM_MUX_BAL |		\
+	  	       NETARM_MEM_BAR_VALID )
+  	str	r1, [r4, #NETARM_MEM_CS0_BASE_ADDR]
+
+  	mov	r0, #'E'
+  	bl	_printch
+  	ldr	r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS0_MASK) |	\
+      NETARM_MEM_OPT_WAIT_STATES(8) | 		\
+      NETARM_MEM_OPT_16BIT | 			\
+      NETARM_MEM_OPT_READ_ASYNC | 		\
+      NETARM_MEM_OPT_WRITE_ASYNC )
+  	str	r1, [r4, #NETARM_MEM_CS0_OPTIONS]
+
+  	ldr	r1, =( NETARM_MEM_OPTB_SYNC_1_STAGE | \
+      NETARM_MEM_OPTB_BCYC_PLUS0 | \
+      NETARM_MEM_OPTB_WAIT_PLUS0 )
+  	str	r1, [r4, #NETARM_MEM_CS0_OPTIONS_B]
+
+	mov	r0, #'F'
+	bl	_printch
+	
+/* CS1 SDRAM*/
+	ldr	r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS1_MASK) |	\
+		       NETARM_MEM_OPT_BCYC_2 |			\
+		       NETARM_MEM_OPT_BSIZE_16 | 		\
+		       NETARM_MEM_OPT_WAIT_STATES(0) | 		\
+		       NETARM_MEM_OPT_32BIT | 			\
+		       NETARM_MEM_OPT_READ_ASYNC | 		\
+		       NETARM_MEM_OPT_WRITE_ASYNC )
+	str	r1, [r4, #NETARM_MEM_CS1_OPTIONS]
+
+	ldr	r1, =( NETARM_MEM_OPTB_SYNC_1_STAGE | \
+		       NETARM_MEM_OPTB_BCYC_PLUS0 | \
+		       NETARM_MEM_OPTB_WAIT_PLUS0 )
+	str	r1, [r4, #NETARM_MEM_CS1_OPTIONS_B]
+
+	ldr	r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS1_BASE) | 	\
+		       NETARM_MEM_BAR_DRAM_SYNC |		\
+		       NETARM_MEM_BAR_DRAM_MUX_INT |		\
+		       NETARM_MEM_BAR_DRAM_MUX_UNBAL |		\
+		       NETARM_MEM_BAR_DRAM_SEL |		\
+		       NETARM_MEM_BAR_BURST_EN |		\
+		       NETARM_MEM_BAR_VALID )
+	str	r1, [r4, #NETARM_MEM_CS1_BASE_ADDR]
+
+	mov	r0, #'G'
+	bl	_printch
+#endif
+
+#endif /* !CONFIG_NETARM_NS7520 */
+
+	/* Wait 8 refresh cycles off SDRAM 120uS */
+
+	ldr	r1,=6600
+_waitsdram:
+	subs	r1,r1,#1
+	bne	_waitsdram
+
+#ifdef CONFIG_NETARM_BOOTLOADER_DEBUG_RAMPTEST
+/* ramp test RAM */
+	mov r0, #'H'
+	bl _printch
+	mov r1, #NETARM_MMAP_RAM_BASE;
+  mov r7, #0x00800000;
+  mov r5, #0x0
+1:
+	str r5, [r1], #4
+	add r5, r5, #0x1
+	subs r7, r7, #4
+	bgt 1b
+
+	mov r6, #NETARM_MMAP_RAM_BASE;
+	mov r7, #0x00800000;
+	mov r5, #0x0
+1:
+	ldr r4, [r6], #4
+	teq r5, r4
+	beq 2f
+	mov r0, #'\n'
+	bl _printch
+	mov r0, #'A'
+	bl _printch
+	mov r0, #' '
+	bl _printch
+	mov r0, r6
+  sub r0, r0, #4 /* r6 auto-post-increments */
+	bl _printhex8
+	mov r0, #'\n'
+	bl _printch
+	mov r0, #'W'
+	bl _printch
+	mov r0, #' '
+	bl _printch
+	mov r0, r5
+	bl _printhex8
+	mov r0, #' '
+	bl _printch
+	mov r0, #'G'
+	bl _printch
+	mov r0, #' '
+	bl _printch
+	mov r0, r4
+	bl _printhex8
+2:
+	add r5, r5, #0x1
+	subs r7, r7, #4
+	bgt 1b
+#endif
+
+/* copy to RAM */
+	mov	r0, #'H'
+	bl	_printch
+
+		mov	r1, #NETARM_MMAP_RAM_BASE;
+		mov	r0, #NETARM_MMAP_FLASH_BASE;
+		mov	r2, #NETARM_MMAP_FLASH_COPY_SIZE;
+1:
+		ldmia	r0!,{r3,r4,r5,r6,r7,r8,r9,r10}
+		stmia	r1!,{r3,r4,r5,r6,r7,r8,r9,r10}
+		subs	r2, r2, #0x20
+		bgt	1b
+
+
+
+_exec_in_RAM:
+		mov	r0, #'N'
+		bl	_printch
+		
+ 		ldr	pc, =(__zentry)
+__zentry:
+
+/*
+ * print bootloaded hello and current PC
+ */
+
+		/* Now we are in RAM */
+		mov	r0, #'O'
+		bl	_printch
+
+/*
+ * Copy ROMFS for use. 
+ */
+#ifdef CONFIG_RAM_ATTACHED_ROMFS 
+		ldr	r5, =LC1
+		ldmia	r5, {r5, r8}  /* r5 = _edata, r8 = _ebss */
+
+		mov r0, r5
+		mov r1, r8
+  
+		ldr r2, [r0, #+8] /* Big-endian Size */
+		mov r3, #0				 /* Init result */
+		and r4, r2, #0x000000ff
+		orr r3, r3, r4, lsl #24
+		and r4, r2, #0x0000ff00
+		orr r3, r3, r4, lsl #8
+		and r4, r2, #0x00ff0000
+		orr r3, r3, r4, lsr #8
+		and r4, r2, #0xff000000
+		orr r3, r3, r4, lsr #24
+		mov r2, r3
+		
+		add r2, r2, #8
+		and r2, r2, #0xfffffffc
+		
+		add r0, r0, r2 /* Copy from end */
+		add r1, r1, r2
+		ldr r3, =_ramstart
+		str r1, [r3]
+
+_copy_romfs:
+		ldr r3,[r0,#-4]!		  /* Copy dword */
+		str r3,[r1,#-4]!
+		cmp r0, r5				/* Check if at end */
+		bne _copy_romfs
+		
+		mov r0, r2
+		bl _printhex8
+		
+		mov	r0, #'P'
+		bl	_printch
+#endif  
+/*
+ * print banner message
+ */
+		mov	r0, #'@'
+		bl	_printch
+
+		mov	r0, pc
+		bl 	_printhex8
+
+		mov	r0, #'\n'
+		bl	_printch
+		
+		ldr	r0, =_hello_world
+		bl 	_printascii
+
+		mov	r0, #'\n'
+		bl	_printch
+
+#if CONFIG_NETARM_BOOTLOADER_DEBUG_OUTPUT	
+/*
+ * dump serial and memory control registers
+ */
+
+		bl	_netarm_debug_serial_dump
+		bl	_netarm_debug_mem_ctl_dump		
+	
+/*
+ * count down to boot...
+ */
+
+		mov	r8, #15
+
+1:		
+		mov	r0, r8
+		bl 	_printhex2
+
+		mov	r0, #'\r'
+		bl	_printch
+
+		mov	r2, #0x20000
+2:
+		subs	r2, r2, #1
+		bgt	2b
+		
+		subs	r8, r8, #1
+		bgt	1b
+
+/*
+ * test point - jump to blink
+ */
+
+/*		b	_netarm_led_blink */
+
+#endif	
+	
+/*
+ * set up initial stack 
+ */
+
+		ldr	r5, =LC0
+		ldmia	r5, {r5, r6, r8, r9, sp}
+
+/* clear BSS segment */
+		mov	r4, #0
+1:		cmp	r5, r8
+		strcc	r4, [r5], #4
+		bcc	1b
+
+        /*  Put initial values into stack.  This would normally be done
+        by sched_init() in kernel/sched.c, but that would overwrite the
+        stack we're already using.  That would be bad.
+        (code from the DSC21 head file by Steve Johnson) 
+	Only fill half the task_union area, because the task list starts
+	in the lower part. --rp */
+        	mov r5, sp
+        	sub r5, r5, #0x1000
+        	ldr r4, L_STACK_MAGIC
+        	str r4, [r5], #4
+        	ldr r4, L_STACK_UNTOUCHED_MAGIC
+1:      	cmp r5, sp
+        	strcc r4, [r5], #4
+        	bcc 1b
+
+/*
+ * Stob in the ARMID - since we don't have CP15 to query... 
+ */
+
+		ldr	r2, =0x41007700
+		str	r2, [r6]
+/*  Pretend we know what our processor code is (for arm_id)   */
+		mov     r2, #MACH_TYPE_NETARM
+		str     r2, [r9]
+
+/*
+ * Jump to linux
+ */
+
+		mov	fp, #0
+		b	start_kernel
+
+
+/*
+ * NET+ARM development board blink routine - turns led on and then off
+ * approx one second on, one second off.
+ * NET+40 board: The RED led is on bit 2 (0x04)
+ */
+
+		.globl	_netarm_led_blink
+_netarm_led_blink:
+
+/*
+ * config C1 as GPIO output
+ */
+		ldr	r4, =NETARM_GEN_MODULE_BASE
+		ldr	r1, [r4, #+NETARM_GEN_PORTC]
+		ldr	r2, =((0xFFFFFFFF) ^ (NETARM_GEN_PORT_MODE(NA_BLINK_LED) | \
+			                      NETARM_GEN_PORT_DIR(NA_BLINK_LED)))
+		and	r1, r1, r2
+		ldr	r2, =(NETARM_GEN_PORT_DIR(NA_BLINK_LED))
+		orr	r1, r1, r2
+		str	r1, [r4, #+NETARM_GEN_PORTC]
+/*
+ * turn the LED off ( output high )
+ */
+1:
+		eor	r1, r1, #(NA_BLINK_LED)
+		str	r1, [r4, #+NETARM_GEN_PORTC]
+/*
+ * wait a bit - million iterations, give or take
+ */
+		mov	r2, #0x100000
+2:
+		subs	r2, r2, #1
+		bgt	2b
+
+		b 	1b		
+
+		.globl	_netarm_led_FAIL
+_netarm_led_FAIL:
+
+		mov	r0, lr
+		bl	_printhex8
+
+/*
+ * config port C pins as GPIO output
+ */
+		ldr	r4, =NETARM_GEN_MODULE_BASE
+		ldr	r1, [r4, #+NETARM_GEN_PORTC]
+		ldr	r2, =((0xFFFFFFFF) ^ \
+		                (NETARM_GEN_PORT_MODE(NA_BLINK_LED | NA_FAIL_LED) | \
+			         NETARM_GEN_PORT_DIR(NA_BLINK_LED | NA_FAIL_LED)))
+		and	r1, r1, r2
+		ldr	r2, =(NETARM_GEN_PORT_DIR(0x06))
+		orr	r1, r1, r2
+		orr	r1, r1, #(NA_BLINK_LED | NA_FAIL_LED)
+		eor	r1, r1, #NA_FAIL_LED
+		str	r1, [r4, #+NETARM_GEN_PORTC]
+/*
+ * turn the LED off ( output high )
+ */
+1:
+		eor	r1, r1, #(NA_BLINK_LED | NA_FAIL_LED)
+		str	r1, [r4, #+NETARM_GEN_PORTC]
+/*
+ * wait a bit - million iterations, give or take
+ */
+		mov	r2, #0x20000
+2:
+		subs	r2, r2, #1
+		bgt	2b
+
+		b 	1b		
+
+		.globl	_netarm_led_FAIL2
+_netarm_led_FAIL2:
+
+		mov	r0, lr
+		bl	_printhex8
+
+/*
+ * config port C "blink" pin as GPIO output
+ */
+		ldr	r4, =NETARM_GEN_MODULE_BASE
+		ldr	r1, [r4, #+NETARM_GEN_PORTC]
+		ldr	r2, =((0xFFFFFFFF) ^ (NETARM_GEN_PORT_MODE(NA_BLINK_LED) | \
+			                      NETARM_GEN_PORT_DIR(NA_BLINK_LED)))
+		and	r1, r1, r2
+		ldr	r2, =(NETARM_GEN_PORT_DIR(NA_BLINK_LED))
+		orr	r1, r1, r2
+		orr	r1, r1, #(NA_BLINK_LED | NA_FAIL_LED)
+		eor	r1, r1, #NA_FAIL_LED
+		str	r1, [r4, #+NETARM_GEN_PORTC]
+/*
+ * turn the LED off ( output high )
+ */
+1:
+		eor	r1, r1, #(NA_BLINK_LED)
+		str	r1, [r4, #+NETARM_GEN_PORTC]
+/*
+ * wait a bit - 64k iterations, give or take
+ */
+		mov	r2, #0x10000
+2:
+		subs	r2, r2, #1
+		bgt	2b
+
+		b 	1b		
+
+_netarm_debug_serial_init:
+/* 
+ * step 0... make sure pins are configured for serial without losing any
+ * settings 
+ */
+		ldr	r4, =NETARM_GEN_MODULE_BASE
+		
+		ldr	r1, =( NETARM_GEN_PORT_MODE(0x88) | \
+							 NETARM_GEN_PORT_DIR(0x80) )
+		ldr	r2, [r4, #+NETARM_GEN_PORTA]
+		orr	r1, r1, r2
+		str	r1, [r4, #+NETARM_GEN_PORTA]
+#ifdef CONFIG_NETARM_NS7520
+		 /* NS7520 has a CSF field that needs to be set */
+		ldr	r1, =( NETARM_GEN_PORT_MODE(0x88) | \
+							 NETARM_GEN_PORT_DIR(0x80) | \
+								 NETARM_GEN_PORT_CSF(0x88) )
+		ldr	r2, [r4, #+NETARM_GEN_PORTC]
+		orr	r1, r1, r2
+		str	r1, [r4, #+NETARM_GEN_PORTC]
+#else
+		str	r1, [r4, #+NETARM_GEN_PORTB]
+#endif
+		ldr	r4, =NETARM_SER_MODULE_BASE
+		
+/* first turn em off */
+		mov	r1, #0
+		str	r1, [r4, #+NETARM_SER_CH1_CTRL_A]
+		str	r1, [r4, #+NETARM_SER_CH2_CTRL_A]
+		
+/* clear match register */
+		str	r1, [r4, #+NETARM_SER_CH1_RX_MATCH]
+		str	r1, [r4, #+NETARM_SER_CH2_RX_MATCH]
+
+/* setup bit rate generator */
+		ldr	r1, =NETARM_SER_BR_X16(DEFAULT_BAUD_RATE)
+		str	r1, [r4, #+NETARM_SER_CH1_BITRATE]
+		str	r1, [r4, #+NETARM_SER_CH2_BITRATE]
+
+/* setup rx buffer gap timer */
+		ldr	r1, =NETARM_SER_RXGAP(DEFAULT_BAUD_RATE)
+		str	r1, [r4, #+NETARM_SER_CH1_RX_BUF_TMR]
+		str	r1, [r4, #+NETARM_SER_CH2_RX_BUF_TMR]
+
+/* setup port mode */		
+		mov	r1, #NETARM_SER_CTLB_UART_MODE
+		str	r1, [r4, #+NETARM_SER_CH1_CTRL_B]
+		str	r1, [r4, #+NETARM_SER_CH2_CTRL_B]
+
+		ldr	r1, =( NETARM_SER_CTLA_ENABLE |		\
+			       NETARM_SER_CTLA_P_NONE |		\
+			       NETARM_SER_CTLA_2STOP | 		\
+			       NETARM_SER_CTLA_8BITS |		\
+			       NETARM_SER_CTLA_DTR_EN |		\
+			       NETARM_SER_CTLA_RTS_EN)
+		str	r1, [r4, #+NETARM_SER_CH1_CTRL_A]
+		str	r1, [r4, #+NETARM_SER_CH2_CTRL_A]
+
+		mov	pc, lr		
+
+#if CONFIG_NETARM_BOOTLOADER_DEBUG_OUTPUT	
+_netarm_debug_serial_dump:
+		ldr	r9, =NETARM_SER_MODULE_BASE
+		mov	r10, lr
+		
+		ldr	r0, =_serial_hdr
+		bl	_printascii
+
+		mov	r0, #'\n'
+		bl	_printch
+
+/* read control A */
+		ldr	r0, =_serial_ctla
+		bl	_printascii
+
+		ldr	r0, [r9, #+NETARM_SER_CH1_CTRL_A]
+		bl	_printhex8
+		mov	r0, #' '
+		bl	_printch
+		
+		ldr	r0, [r9, #+NETARM_SER_CH2_CTRL_A]
+		bl	_printhex8
+		mov	r0, #'\n'
+		bl	_printch
+
+/* read control A */
+		ldr	r0, =_serial_ctlb
+		bl	_printascii
+
+		ldr	r0, [r9, #+NETARM_SER_CH1_CTRL_B]
+		bl	_printhex8
+		mov	r0, #' '
+		bl	_printch
+		
+		ldr	r0, [r9, #+NETARM_SER_CH2_CTRL_B]
+		bl	_printhex8
+		mov	r0, #'\n'
+		bl	_printch
+
+/* read match register */
+		ldr	r0, =_serial_mr
+		bl	_printascii
+
+		ldr	r0, [r9, #+NETARM_SER_CH1_RX_MATCH]
+		bl	_printhex8
+		mov	r0, #' '
+		bl	_printch
+
+		ldr	r0, [r9, #+NETARM_SER_CH2_RX_MATCH]
+		bl	_printhex8
+		mov	r0, #'\n'
+		bl	_printch
+
+/* bit rate generator */
+		ldr	r0, =_serial_brr
+		bl	_printascii
+
+		ldr	r0, [r9, #+NETARM_SER_CH1_BITRATE]
+		bl	_printhex8
+		mov	r0, #' '
+		bl	_printch
+		
+		ldr	r0, [r9, #+NETARM_SER_CH2_BITRATE]
+		bl	_printhex8
+		mov	r0, #'\n'
+		bl	_printch
+		
+/* rx buffer gap timer */
+		ldr	r0, =_serial_bgt
+		bl	_printascii
+
+		ldr	r0, [r9, #+NETARM_SER_CH1_RX_BUF_TMR]
+		bl	_printhex8
+		mov	r0, #' '
+		bl	_printch
+
+		ldr	r0, [r9, #+NETARM_SER_CH2_RX_BUF_TMR]
+		bl	_printhex8
+		mov	r0, #'\n'
+		bl	_printch
+
+		mov	lr, r10
+		mov	pc, lr		
+
+_netarm_debug_mem_ctl_dump:
+		ldr	r9, =NETARM_MEM_MODULE_BASE
+		mov	r10, lr
+		
+		ldr	r0, =_memctl_hdr
+		bl	_printascii
+
+/* MMCR */
+		ldr	r0, [r9, #+NETARM_MEM_MODULE_CONFIG]
+		bl	_printhex8
+
+		mov	r0, #'\n'
+		bl	_printch
+		
+/* CS0 BAR */
+		ldr	r0, =_memctl_bar1
+		bl	_printascii
+
+		mov	r0, #0
+		bl	_printhex2
+
+		ldr	r0, =_memctl_bar2
+		bl	_printascii
+
+		ldr	r0, [r9, #+NETARM_MEM_CS0_BASE_ADDR]
+		bl	_printhex8
+		
+		mov	r0, #'\n'
+		bl	_printch
+		
+/* CS0 OPT */
+		ldr	r0, =_memctl_opt1
+		bl	_printascii
+
+		mov	r0, #0
+		bl	_printhex2
+
+		ldr	r0, =_memctl_opt2
+		bl	_printascii
+
+		ldr	r0, [r9, #+NETARM_MEM_CS0_OPTIONS]
+		bl	_printhex8
+		
+		mov	r0, #'\n'
+		bl	_printch
+		
+/* CS1 BAR */
+		ldr	r0, =_memctl_bar1
+		bl	_printascii
+
+		mov	r0, #1
+		bl	_printhex2
+
+		ldr	r0, =_memctl_bar2
+		bl	_printascii
+
+		ldr	r0, [r9, #+NETARM_MEM_CS1_BASE_ADDR]
+		bl	_printhex8
+		
+		mov	r0, #'\n'
+		bl	_printch
+		
+/* CS1 OPT */
+		ldr	r0, =_memctl_opt1
+		bl	_printascii
+
+		mov	r0, #1
+		bl	_printhex2
+
+		ldr	r0, =_memctl_opt2
+		bl	_printascii
+
+		ldr	r0, [r9, #+NETARM_MEM_CS1_OPTIONS]
+		bl	_printhex8
+		
+		mov	r0, #'\n'
+		bl	_printch
+		
+/* CS2 BAR */
+		ldr	r0, =_memctl_bar1
+		bl	_printascii
+
+		mov	r0, #2
+		bl	_printhex2
+
+		ldr	r0, =_memctl_bar2
+		bl	_printascii
+
+		ldr	r0, [r9, #+NETARM_MEM_CS2_BASE_ADDR]
+		bl	_printhex8
+		
+		mov	r0, #'\n'
+		bl	_printch
+		
+/* CS2 OPT */
+		ldr	r0, =_memctl_opt1
+		bl	_printascii
+
+		mov	r0, #2
+		bl	_printhex2
+
+		ldr	r0, =_memctl_opt2
+		bl	_printascii
+
+		ldr	r0, [r9, #+NETARM_MEM_CS2_OPTIONS]
+		bl	_printhex8
+		
+		mov	r0, #'\n'
+		bl	_printch
+		
+/* CS3 BAR */
+		ldr	r0, =_memctl_bar1
+		bl	_printascii
+
+		mov	r0, #3
+		bl	_printhex2
+
+		ldr	r0, =_memctl_bar2
+		bl	_printascii
+
+		ldr	r0, [r9, #+NETARM_MEM_CS3_BASE_ADDR]
+		bl	_printhex8
+		
+		mov	r0, #'\n'
+		bl	_printch
+		
+/* CS3 OPT */
+		ldr	r0, =_memctl_opt1
+		bl	_printascii
+
+		mov	r0, #3
+		bl	_printhex2
+
+		ldr	r0, =_memctl_opt2
+		bl	_printascii
+
+		ldr	r0, [r9, #+NETARM_MEM_CS3_OPTIONS]
+		bl	_printhex8
+		
+		mov	r0, #'\n'
+		bl	_printch
+		
+/* CS4 BAR */
+		ldr	r0, =_memctl_bar1
+		bl	_printascii
+
+		mov	r0, #4
+		bl	_printhex2
+
+		ldr	r0, =_memctl_bar2
+		bl	_printascii
+
+		ldr	r0, [r9, #+NETARM_MEM_CS4_BASE_ADDR]
+		bl	_printhex8
+		
+		mov	r0, #'\n'
+		bl	_printch
+		
+/* CS4 OPT */
+		ldr	r0, =_memctl_opt1
+		bl	_printascii
+
+		mov	r0, #4
+		bl	_printhex2
+
+		ldr	r0, =_memctl_opt2
+		bl	_printascii
+
+		ldr	r0, [r9, #+NETARM_MEM_CS4_OPTIONS]
+		bl	_printhex8
+		
+		mov	r0, #'\n'
+		bl	_printch
+		
+/* return */
+
+		mov	lr, r10
+		mov	pc, lr		
+
+#endif // CONFIG_NETARM_BOOTLOADER_DEBUG_OUTPUT
+/*
+ * Useful debugging routines
+ */
+		.globl	_printhex8
+_printhex8:	mov	r1, #8
+		b	printhex
+
+		.globl	_printhex4
+_printhex4:	mov	r1, #4
+		b	printhex
+
+		.globl	_printhex2
+_printhex2:	mov	r1, #2
+printhex:	ldr	r2, =hexbuf
+		add	r3, r2, r1
+		mov	r1, #0
+		strb	r1, [r3]
+1:		and	r1, r0, #15
+		mov	r0, r0, lsr #4
+		cmp	r1, #10
+		addlt	r1, r1, #'0'
+		addge	r1, r1, #'a' - 10
+		strb	r1, [r3, #-1]!
+		teq	r3, r2
+		bne	1b
+		mov	r0, r2
+
+		.globl	_printascii
+_printascii:
+		ldr	r3, =NETARM_SER_MODULE_BASE
+		b	3f
+1:		
+#ifndef CONFIG_NETARM_BOOTLOADER_SECOND_SERIAL    
+		ldr	r2, [r3, #+(NETARM_SER_CH1_STATUS_A)]
+#else
+		ldr	r2, [r3, #+(NETARM_SER_CH2_STATUS_A)]
+#endif
+		tst	r2, #NETARM_SER_STATA_TX_RDY
+		beq	1b
+#ifndef CONFIG_NETARM_BOOTLOADER_SECOND_SERIAL    
+		strb	r1, [r3, #+(NETARM_SER_CH1_FIFO)]
+#else
+		strb	r1, [r3, #+(NETARM_SER_CH2_FIFO)]
+#endif
+		teq	r1, #'\n'
+		moveq	r1, #'\r'
+		beq	1b
+3:		teq	r0, #0
+		ldrneb	r1, [r0], #1
+		teqne	r1, #0
+		bne	1b
+		mov	pc, lr
+
+		.globl	_printch
+_printch:
+		ldr	r3, =NETARM_SER_MODULE_BASE
+		mov	r1, r0
+		mov	r0, #0
+		b	1b
+
+/*
+ * Useful debugging routine: List first 8 words
+ */
+#if CONFIG_NETARM_BOOTLOADER_DEBUG_OUTPUT 
+		.globl	_printexcvectors
+_printexcvectors:
+		mov	r10, lr
+		ldr	r0, =_excvec_hdr
+		bl	_printascii
+
+		mov	r9,#0
+1:		ldr	r0, [r9], #4
+		bl	_printhex8
+		mov	r0, #'\n'
+		bl	_printch
+		cmp	r9, #32
+		bne	1b
+
+		mov	lr, r10
+		mov	pc,lr
+#endif
+/*
+ * Useful debugging routines
+ */
+		.globl	_printhex8
+_printhex8_b:	mov	r1, #8
+		b	printhex
+
+		.globl	_printhex4
+_printhex4_b:	mov	r1, #4
+		b	printhex
+
+		.globl	_printhex2
+_printhex2_b:	mov	r1, #2
+printhex_b:	ldr	r2, =hexbuf
+		add	r3, r2, r1
+		mov	r1, #0
+		strb	r1, [r3]
+1:		and	r1, r0, #15
+		mov	r0, r0, lsr #4
+		cmp	r1, #10
+		addlt	r1, r1, #'0'
+		addge	r1, r1, #'a' - 10
+		strb	r1, [r3, #-1]!
+		teq	r3, r2
+		bne	1b
+		mov	r0, r2
+
+		.globl	_printascii_b
+_printascii_b:
+		ldr	r3, =NETARM_SER_MODULE_BASE
+		b	3f
+1:		
+#ifndef CONFIG_NETARM_BOOTLOADER_SECOND_SERIAL    
+		ldr	r2, [r3, #+(NETARM_SER_CH1_STATUS_A)]
+#else
+		ldr	r2, [r3, #+(NETARM_SER_CH2_STATUS_A)]
+#endif
+		tst	r2, #NETARM_SER_STATA_TX_RDY
+		beq	1b
+#ifndef CONFIG_NETARM_BOOTLOADER_SECOND_SERIAL    
+		strb	r1, [r3, #+(NETARM_SER_CH1_FIFO)]
+#else
+		strb	r1, [r3, #+(NETARM_SER_CH2_FIFO)]
+#endif
+		teq	r1, #'\n'
+		moveq	r1, #'\r'
+		beq	1b
+3:		teq	r0, #0
+		ldrneb	r1, [r0], #1
+		teqne	r1, #0
+		bne	1b
+		mov	pc, lr
+
+		.globl	_printch
+_printch_b:
+		ldr	r3, =NETARM_SER_MODULE_BASE
+		mov	r1, r0
+		mov	r0, #0
+		b	1b
+
+
+/*  These values should stay in sync with linux/kernel.h */
+L_STACK_MAGIC:
+		.long 0xdeadbeef
+L_STACK_UNTOUCHED_MAGIC:
+		.long 0xfeef1ef0
+
+		.data
+		.align	12
+_hello_world:	.ascii	"NET+Lx Bootloader v0.9\n\0"
+#if CONFIG_NETARM_BOOTLOADER_DEBUG_OUTPUT
+_serial_hdr:	.ascii	"Serial Configuration:\n"
+		.ascii	"Channel               01       02\0"
+_serial_ctla:	.ascii	"Serial Control A : \0"
+_serial_ctlb:	.ascii	"Serial Control B : \0"
+_serial_bgt:	.ascii	"Buffer Gap Timer : \0"
+_serial_brr:	.ascii	"Bit Rate Control : \0"
+_serial_mr:	.ascii	"Match Register   : \0"
+_memctl_hdr:	.ascii	"Memory Control Module Configuration:\n"
+		.ascii	"Mem Config Reg   : \0"
+_memctl_bar1:	.ascii	"BAR\0"
+_memctl_bar2:	.ascii	"            : \0"
+_memctl_opt1:	.ascii	"OPT\0"
+_memctl_opt2:	.ascii	"            : \0"
+_excvec_hdr:	.ascii	"Exception vectors (0x00-0x1C):\n\0"
+#endif
+
+#ifdef	CONFIG_BLK_DEV_RAMDISK_DATA
+
+		.align	12
+		.globl	__ramdisk_data
+__ramdisk_data:
+#include "ramdisk.inc"
+		.globl	__ramdisk_data_end
+__ramdisk_data_end:
+		.align
+	
+#endif
+#ifdef CONFIG_RAM_ATTACHED_ROMFS 
+.global	_ramstart
+_ramstart:
+.long	0
+#endif
+
+		.align	8
+LC0:		.long	__bss_start
+        	.long	processor_id
+        	.long	_end
+		.long   __machine_arch_type
+        	.long	init_task_union+8192
+#ifdef CONFIG_RAM_ATTACHED_ROMFS 
+LC1:		.long	_edata
+        .long	_ebss
+#endif        
+
+		.section	.rodata
+		.align	12
+__zzzz:		.space	16
+		.align
+
+		.bss
+		.align	12
+hexbuf:		.space 16
+		.align
+
diff -urN linux-2.4.29/arch/armnommu/kernel/head-armo.S linux-2.4.29-uc1/arch/armnommu/kernel/head-armo.S
--- linux-2.4.29/arch/armnommu/kernel/head-armo.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/head-armo.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,92 @@
+/*
+ *  linux/arch/arm/kernel/head-armo.S
+ *
+ *  Copyright (C) 1994-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  26-bit kernel startup code
+ */
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/mach-types.h>
+
+		.globl	SYMBOL_NAME(swapper_pg_dir)
+		.equ	SYMBOL_NAME(swapper_pg_dir),	0x0207d000
+
+/*
+ * Entry point.
+ */
+		.section ".text.init",#alloc,#execinstr
+ENTRY(stext)
+__entry:	cmp	pc, #0x02000000
+		ldrlt	pc, LC0			@ if 0x01800000, call at 0x02080000
+		teq	r0, #0			@ Check for old calling method
+		blne	oldparams		@ Move page if old
+		adr	r0, LC0
+		ldmib	r0, {r2-r5, sp}		@ Setup stack
+		mov	r0, #0
+1:		cmp	r2, r3			@ Clear BSS
+		strcc	r0, [r2], #4
+		bcc	1b
+
+		bl	detect_proc_type
+		str	r0, [r4]
+		bl	detect_arch_type
+		str	r0, [r5]
+
+		mov	fp, #0
+		b	SYMBOL_NAME(start_kernel)
+
+LC0:		.word	SYMBOL_NAME(_stext)
+		.word	SYMBOL_NAME(__bss_start)		@ r2
+		.word	SYMBOL_NAME(_end)			@ r3
+		.word	SYMBOL_NAME(processor_id)		@ r4
+		.word	SYMBOL_NAME(__machine_arch_type)	@ r5
+		.word	SYMBOL_NAME(init_task_union)+8192	@ sp
+arm2_id:	.long	0x41560200
+arm250_id:	.long	0x41560250
+		.align
+
+oldparams:	mov	r4, #0x02000000
+		add	r3, r4, #0x00080000
+		add	r4, r4, #0x0007c000
+1:		ldmia	r0!, {r5 - r12}
+		stmia	r4!, {r5 - r12}
+		cmp	r4, r3
+		blt	1b
+		mov	pc, lr
+
+/*
+ * We need some way to automatically detect the difference between
+ * these two machines.  Unfortunately, it is not possible to detect
+ * the presence of the SuperIO chip, because that will hang the old
+ * Archimedes machines solid.
+ */
+/* DAG: Outdated, these have been combined !!!!!!! */
+detect_arch_type:
+#if defined(CONFIG_ARCH_ARC)
+		mov	r0, #MACH_TYPE_ARCHIMEDES
+#elif defined(CONFIG_ARCH_A5K)
+		mov	r0, #MACH_TYPE_A5K
+#endif
+		mov	pc, lr
+
+detect_proc_type:
+		mov	ip, lr
+		mov	r2, #0xea000000		@ Point undef instr to continuation
+		adr	r0, continue - 12
+		orr	r0, r2, r0, lsr #2
+		mov	r1, #0
+		str	r0, [r1, #4]
+		ldr	r0, arm2_id
+		swp	r2, r2, [r1]		@ check for swp (ARM2 cant)
+		ldr	r0, arm250_id
+		mrc	15, 0, r3, c0, c0	@ check for CP#15 (ARM250 cant)
+		mov	r0, r3
+continue:	mov	r2, #0xeb000000		@ Make undef vector loop
+		sub	r2, r2, #2
+		str	r2, [r1, #4]
+		mov	pc, ip
diff -urN linux-2.4.29/arch/armnommu/kernel/head-arm-vc547x.S linux-2.4.29-uc1/arch/armnommu/kernel/head-arm-vc547x.S
--- linux-2.4.29/arch/armnommu/kernel/head-arm-vc547x.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/head-arm-vc547x.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,589 @@
+/***********************************************************************
+ * linux/arch/armnommu/kernel/head-arm-vc5471.S
+ *
+ *   Copyright (C) 2003 Cadenux, LLC. All rights reserved.
+ *   todd.fischer@cadenux.com  <www.cadenux.com>
+ *
+ *   Copyright (C) 2001 RidgeRun, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#include <linux/linkage.h>
+#include <linux/autoconf.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+#define UART_115K_DIV         0x0000019c
+#define UART_BAUD_115200      0x00000001
+#define UART_M0D8_NOPRTY_STP1 0x00000003
+
+
+/* This is the defines to put us into service mode. */
+
+#define I_BIT        0x80
+#define F_BIT        0x40           
+#define ARM_MODE_SVC 0x13
+
+/* Pretend we know what our processor type code is */
+
+#define ARM_PROCESSOR_ID 0x41007700
+
+/* Size of the initial stack.   Thit init_task_union is the union of
+ * a struct task_struct that is pre-initialized and a size arrary of
+ * size 2048*sizeof(long) == 8192 (see include/linux/sched.h).
+ * We want to write initial values to the stack for crash analysis,
+ * but we don't want to clobber the initialized task_struct,
+ * so we define: */
+
+#define INIT_TASK_OFFSET  8192
+#define INIT_TASK_RESERVE 1024
+#define INITIAL_STACK_SIZE (INIT_TASK_OFFSET-INIT_TASK_RESERVE)
+
+/* Register usage: */
+
+#define ARG1        r0
+
+#define TMP1        r0
+#define TMP2        r1
+#define TMP3        r2
+#define TMP4        r3
+
+#define SBSS        r4
+#define EBSS        r5
+
+#define COMPAT      r4
+#define PROCID      r5
+#define MACHID      r6
+#define CFGALN      r7
+
+#define DATA_SROM   TMP1
+#define DATA_SRAM   TMP2
+#define DATA_ERAM   TMP3
+#define DATA_TMP    TMP4
+#define DATA_FIRST  r3
+#define DATA_LAST   r10
+
+#define INT_VECTOR_TABLE (C5471_IRAM_START)
+#define VECT_UNDEFINSTR  (INT_VECTOR_TABLE+0x4)
+#define VECT_SWI         (INT_VECTOR_TABLE+0x8)
+#define VECT_PREFETCH    (INT_VECTOR_TABLE+0xC)
+#define VECT_DATA        (INT_VECTOR_TABLE+0x10)
+#define VECT_ADDREXCPTN  (INT_VECTOR_TABLE+0x14)
+#define VECT_IRQ         (INT_VECTOR_TABLE+0x18)
+#define VECT_FIQ         (INT_VECTOR_TABLE+0x1C)
+                                         
+/* These are checkpoint values */
+
+#define INITIAL_ENTRY     #'A'
+#define ENTRY_VERIFY      #'B'
+#define BSS_CLEARED       #'C'
+#define DATA_INITIALIZED  #'D'
+#define STACK_INITIALIZED #'E'
+#define CALL_START_KERNEL #'F'
+#define END_CHECKPOINT    #'\n'
+
+/* These macros are used to output debug status on the serial console.
+ * These macros can be used only after a C stack has been initialized.
+ *
+ * These macros (incl. printch/hex8) use R0-R3 and lr.
+ *
+ */
+
+#ifdef CONFIG_DEBUG_LL
+	.globl	printch
+	.type	printch, #function
+
+	.macro	checkpoint, ch
+	mov	ARG1, \ch
+	bl	printch
+	.endm
+
+	.globl	printhex8
+	.type	printhex8, #function
+
+	.macro	showvalue, addr, tmp
+	ldr	\tmp, =addr
+	mov	ARG1, \tmp
+	bl	printhex8
+	.endm
+#else
+	.macro	checkpoint, ch
+	.endm
+	.macro	showvalue, addr, tmp
+	.endm
+#endif /* CONFIG_DEBUG_LL */
+
+        .text
+        .align
+        .global reset_logic
+
+/* The lower portion (low addresses) of the IRAM are used
+ * to hold the interrupt vector table. This table will be
+ * loaded as part of early bootup and contains
+ * the addresses of the various interrupt handlers
+ * assigned to each GPP interrupt. This is necessary since
+ * most C5471 devices have flash down at the low end of
+ * the memory map where the real interrupt vector logic is
+ * expected to reside. Meaning that the kernel won't be
+ * able to plug in its interrupt vectors at run time (the
+ * flash being read-only as far as the kernel is
+ * concerned).  Instead, we'll assume that flash starts
+ * at address 0x0000000 and this file will put the necessary
+ * logic in place to use the RAM based vector table.
+ * When an interrupt occurs this code at the flash based interrupt
+ * location will pick up the addresses deposited in the
+ * RAM table then branch to that specific
+ * routine itemized in the table.
+ */
+
+/* Note: reset_logic must have an address of 0x00000000 */
+        
+reset_logic:    
+/*        b start_hw_setup*/     /* address 0x00 */
+		b start_from_ram	/* HK: */
+IVectors:
+        b Vector_undefinstr  /* address 0x04 */
+        b Vector_swi         /* address 0x08 */
+        b Vector_prefetch    /* address 0x0c */
+        b Vector_data /* address 0x10 */
+        b Vector_addrexcptn /* address 0x14 */
+        b Vector_IRQ /* address 0x18 */
+        b Vector_fiq /* address 0x1c */
+
+        nop  
+        nop  
+        nop  
+        nop
+        nop  /* force the logic down a few addresses */
+        nop  
+        nop  
+        nop  
+        nop
+
+Vector_undefinstr:
+        ldr r13, =VECT_UNDEFINSTR
+        ldr pc, [r13]
+Vector_swi:
+/* Note: a little different than the others in that we
+ *       have to honor all current register values.
+ */
+        str r14,[sp,#-0x4]   /* preserve r14 so we have a scratch reg. */
+        ldr r14, =VECT_SWI   /* get address of Kernel int routine. */
+        ldr pc, [r14]        /* jump to it. (starts by popping r14 value) */
+Vector_prefetch:
+        ldr r13, =VECT_PREFETCH
+        ldr pc, [r13]
+Vector_data:
+        ldr r13, =VECT_DATA
+        ldr pc, [r13]
+Vector_addrexcptn:
+        ldr r13, =VECT_ADDREXCPTN
+        ldr pc, [r13]
+Vector_IRQ:
+        ldr r13, =VECT_IRQ
+        ldr pc, [r13]
+Vector_fiq:
+        ldr r13, =VECT_FIQ
+        ldr pc, [r13]
+        
+/* -------------------- Stage One Init ---------------------- */
+
+        .global start
+	.type	start, #function
+        .global stext
+	.type	stext, #function
+        .global _start
+	.type	_start, #function
+        .global _stext
+	.type	_stext, #function
+        .global _entry
+	.type	_entry, #function
+        .global __stext
+	.type	__stext, #function
+        .global __entry
+	.type	__entry, #function
+start:
+stext:
+_start:
+_stext:
+_entry:
+__stext:
+__entry:
+        
+start_hw_setup: /* Called by reset vector; Running from Flash. */
+
+/* Turn off IRQ/FIQ and put into service mode. */
+        mov r0, #(ARM_MODE_SVC | I_BIT | F_BIT)
+        msr cpsr, r0
+
+#if (ETHERNET_PHY == ETHERNET_PHY_LU3X31T_T64)
+/* Assert the C5471's nRESET_out line to *external* peripherals.
+ * Note: | This pin doesn't reset the processor but rather is a
+ *       | reset line being sourced by the processor and feeds
+ *       | external logic surrounding it like ethernet transciever 
+ *       | chip(s), etc.                                
+ */
+        ldr r0,clkm_ctl_rst_reg
+        mov r1,#0x02
+        str r1,[r0] /* nRESET_out asserted and DSP reset asserted. */
+        ldr r2,=0x000000ff
+hold:  
+        subs r2,r2,#0x1
+        bne hold
+        mov r1,#0x00
+        str r1,[r0] /* nRESET_out de-asserted, DSP reset de-asserted. */
+#endif
+
+/* init Memory I/F (MEMINT) */
+
+        ldr r0,CS0_reg
+        ldr r1,=0x00001eaf
+        str r1,[r0]
+        
+        ldr r0,CS1_reg
+        ldr r1,=0x00001eaf
+        str r1,[r0]
+ 
+        ldr r0,CS2_reg
+        ldr r1,=0x000013db
+        str r1,[r0]
+        
+        ldr r0,CS3_reg
+        ldr r1,=0x000013c2
+        str r1,[r0]
+
+/* init PLL */
+
+        ldr r0,clkm_stop_reg
+        ldr r1,=0x00000c00
+        str r1,[r0]
+        
+        ldr r0,clkm_wakeup_reg
+        ldr r1,=0x00000c00
+        str r1,[r0]
+
+        ldr r0,arm_pll_reg
+        ldr r1,=0x00000000
+        str r1,[r0]
+
+        ldr r0,=0x0000ffff
+loop:  
+        subs r0,r0,#0x1
+        bne loop
+
+        ldr r0,arm_pll_reg        
+        ldr r1,=0x00001014  /* Set ARM frequency to 47.5 Mhz */
+        str r1,[r0]
+
+        ldr r0,clkm_dsp_reg
+        ldr r1,[r0]
+        orr r1,r1,#0x0038
+        str r1,[r0]
+        
+        ldr r0,arm_pll_reg
+        ldr r1,[r0]
+        orr r1,r1,#0x0002
+        str r1,[r0]
+
+loop1:
+        ldr r0,arm_pll_reg
+        ldr r1,[r0]      
+        ldr r2,=0x000007f8
+        ands r1,r1,r2
+        bne loop1
+        
+/* switch clock module from test mode to normal mode. */
+
+        ldr r0,clkm_low_power_reg
+        ldr r1,=0x00000000
+        str r1,[r0]
+
+        ldr r0,clkm_dsp_reg
+        ldr r1,[r0]
+        orr r1,r1,#0x40
+        str r1,[r0]
+        
+        ldr r0,clkm_dsp_reg
+        ldr r1,[r0]
+        orr r1,r1,#0x80
+        str r1,[r0]
+                
+/* GPIO Clocks init */
+
+        ldr r0,gpio_kbcio_reg
+        ldr r1,=0x00000000
+        str r1,[r0]
+	
+        ldr r0,gpio_keybrd_reg
+        ldr r2,[r0]
+        ldr r1,=0x00003fff
+        and r1,r2,r1
+        str r1,[r0]
+
+/* init SDRAM I/F */
+
+        ldr r0,gpio_mux_select_reg 
+        ldr r1,=0xffffffdf
+        str r1,[r0]
+
+        ldr r0,sdram_reg
+        ldr r1,=0x0000000E
+        str r1,[r0]
+
+        ldr r0,sdram_BS_reg
+        ldr r1,=0x02000000
+        str r1,[r0]
+
+        ldr r0,sdram_config
+        ldr r1,sdram_config_data
+        str r1,[r0]
+        
+        ldr r0,sdram_ref_count
+        ldr r1,=0x00000320
+        str r1,[r0]
+        
+        ldr r0,sdram_init_config
+        ldr r1,=0x00021388
+        str r1,[r0]
+
+        ldr r0,sdram_cntl
+        ldr r1,=0x00000001
+        str r1,[r0]
+loop2:
+        ldr r0,sdram_cntl
+        ldr r1,[r0]
+        ands r1,r1,#0x2
+        beq loop2
+
+/* Setup UART for early debug output */
+
+        ldr r0,=UART_MODEM_MDR
+        ldr r1,=0x00000007 /* reset mode. */
+        str r1,[r0]
+        ldr r2,=0x00010000
+loop3:  
+        subs r2,r2,#0x1
+        bne loop3
+        
+        ldr r0,=UART_MODEM_MDR
+        ldr r1,=0x00000000 /* normal mode. */
+        str r1,[r0]
+        ldr r0,=UART_MODEM_115K_DIV
+        ldr r1,=UART_115K_DIV
+        str r1,[r0]
+        ldr r2,=0x00010000
+loop4:  
+        subs r2,r2,#0x1
+        bne loop4
+          
+        ldr r0,=UART_MODEM_FCR
+        ldr r1,=0x0006          /* clear RX and TX fifos */
+        str r1,[r0]
+        ldr r0,=UART_MODEM_FCR
+        ldr r1,=0x0001          /* enable RX and TX fifos */
+        str r1,[r0]
+        ldr r0,=UART_MODEM_DIV
+        ldr r1,=UART_BAUD_115200
+        str r1,[r0]
+        ldr r0,=UART_MODEM_SER_LCR
+        ldr r1,=UART_M0D8_NOPRTY_STP1
+        str r1,[r0]
+
+/* Next, Some of the GPIO pins on the C5472 chip are
+ * routed internally to the GPIO block as well as the Uart
+ * block depending on how the internal mux is setup.  In
+ * these cases you pick what you want the pins to route
+ * to. Here we route them to the Uart block to give that
+ * block a connection to the outside world. The chip pins of
+ * interest here are the ones that are physically wired
+ * to the c547X EVM's external serial port.
+ */
+        ldr r0,gpio_mux_select_reg
+        ldr r1,[r0]
+        ldr r2,=0xffffe0ff /* gpio pins of interest are pins 8,9,10,11,12 */
+        and r1,r1,r2
+        str r1,[r0]
+
+        ldr r0,gpio_cio_reg
+        ldr r1,[r0]
+        ldr r2,=0xfffbffff
+        and r1,r1,r2
+        str r1,[r0]
+
+        ldr r0,gpio_io_reg
+        ldr r1,[r0]
+        ldr r2,=0x00040000
+        orr r1,r1,r2
+        str r1,[r0]
+
+start_from_ram:
+/* save r2 (tags) */
+/*	b start_from_ram*/
+    ldr r4,=C5471tags
+    str r2,[r4]
+
+/* Setup kernel stack (and get the BSS range) */
+
+	adr	TMP1, LC0
+	ldmia   TMP1, {SBSS, EBSS, sp}
+
+	checkpoint INITIAL_ENTRY /* Indicates that we have started */
+	checkpoint ENTRY_VERIFY  /* Proves that printch works */
+
+/* Clear kernel BSS section */
+
+	mov	TMP1, #0
+1:	cmp	SBSS, EBSS                                  
+	strcc	TMP1, [SBSS], #4
+	bcc	1b
+
+	checkpoint BSS_CLEARED   /* Indicates survived BSS clear */
+
+#if defined(CONFIG_ROMKERNEL)
+        
+/* Copy kernel's .data sections to new home in RAM. */
+
+	adr	DATA_TMP, LC2
+	ldmia	DATA_TMP, {DATA_SROM, DATA_SRAM, DATA_ERAM}
+
+1:	ldmia	DATA_SROM!, {DATA_FIRST - DATA_LAST}
+	stmia	DATA_SRAM!, {DATA_FIRST - DATA_LAST}
+	cmp	DATA_SRAM, DATA_ERAM
+	blt	1b
+
+	checkpoint DATA_INITIALIZED   /* Indicates survived DATA init */
+#endif
+  
+/* Get more memory references */
+	
+	adr	TMP1, LC1
+	ldmia   TMP1, {COMPAT, PROCID, MACHID}
+
+/* Initialize Kernel Stack Contents */
+
+	mov	TMP2, sp
+	sub	TMP2, TMP2, #INITIAL_STACK_SIZE
+	ldr	TMP1, L_STACK_MAGIC
+	str	TMP1, [TMP2], #4
+	ldr	TMP1, L_STACK_UNTOUCHED_MAGIC
+1:      cmp	TMP2, sp
+        strcc	TMP1, [TMP2], #4
+        bcc	1b
+
+	checkpoint STACK_INITIALIZED   /* Indicates survived stack init */
+
+/* Setup parameters for start_kernel... */
+/* Suppress messages about compatibility... */
+
+	mov	TMP1, #0
+	str	TMP1, [COMPAT]
+
+/* Pretend we know what our processor code is */
+
+	ldr	TMP1, =ARM_PROCESSOR_ID
+	str	TMP1, [PROCID]
+
+	mov	TMP1, #MACH_TYPE_VC547X
+	str	TMP1, [MACHID]
+
+/* Jump to kernel entry */
+
+	checkpoint CALL_START_KERNEL   /* Indicates start_kernel called */
+	checkpoint END_CHECKPOINT      /* (for cosmetic reasons) */
+
+	mov	fp, #0
+	b	start_kernel
+
+/* Variables */
+
+sdram_config_data:
+        .long 0x001486a2 /* 32 Mbytes memory */
+        
+LC0:	.long	SYMBOL_NAME(__bss_start)
+	.long	SYMBOL_NAME(_end)
+	.long	SYMBOL_NAME(init_task_union)+INIT_TASK_OFFSET
+
+LC1:	.long	SYMBOL_NAME(compat)
+	.long	SYMBOL_NAME(processor_id)
+	.long	SYMBOL_NAME(__machine_arch_type)
+ 
+#if 1
+LC2:	
+//	.long	__RONLY_end  /* Flash .data defaults location */
+	.long	_etext  /* Flash .data defaults location */
+	.long	__data_start /* Target SDRAM .data location */
+//	.long	__data_end
+	.long	_edata
+#endif
+
+        .global C5471tags
+/*	.type	__entry, #function*/
+C5471tags:	.long	0x00000000
+
+L_STACK_UNTOUCHED_MAGIC:
+        .long 0xfeef1ef0
+L_STACK_MAGIC:
+        .long 0xdeadbeef
+gpio_io_reg:
+        .word 0xffff2800
+gpio_cio_reg:
+        .word 0xffff2804      
+gpio_mux_select_reg:
+        .word 0xffff2814
+gpio_keybrd_reg:
+        .word 0xffff2914
+gpio_kbcio_reg:
+        .word 0xffff2904        
+CS0_reg:
+        .word 0xffff2e00
+CS1_reg:
+        .word 0xffff2e04
+CS2_reg:
+        .word 0xffff2e08
+CS3_reg:
+        .word 0xffff2e0c
+sdram_reg:
+        .word 0xffff2e18
+sdram_BS_reg:
+        .word 0xffff2e1C
+clkm_stop_reg:
+        .word 0xffff2f00
+clkm_dsp_reg:
+        .word 0xffff2f04
+clkm_wakeup_reg:
+        .word 0xffff2f08
+clkm_ctl_rst_reg:
+        .word 0xffff2f10
+clkm_low_power_reg:
+        .word 0xffff2f1c
+sdram_config:
+        .word 0xffff3000
+sdram_ref_count:
+        .word 0xffff3004
+sdram_cntl:
+        .word 0xffff3008
+sdram_init_config:
+        .word 0xffff300c
+arm_pll_reg:
+        .word 0xffff3200
diff -urN linux-2.4.29/arch/armnommu/kernel/head-armv.S linux-2.4.29-uc1/arch/armnommu/kernel/head-armv.S
--- linux-2.4.29/arch/armnommu/kernel/head-armv.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/head-armv.S	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,878 @@
+/*
+ *  linux/arch/arm/kernel/head-armv.S
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  32-bit kernel startup code for all architectures
+ *
+ * added S3C4510 code by Mac Wang
+ * added S3C4530 code by Arcturus Networks Inc.
+ * added S3C2500 code by Arcturus Networks Inc.
+ * added TI TMS320DM270 code by Chee Tim Loh <cheetim_loh@innomedia.com.sg>.
+ *
+ */
+#include <linux/config.h>
+#include <linux/linkage.h>
+
+#include <asm/assembler.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#define K(a,b,c)	((a) << 24 | (b) << 12 | (c))
+
+/*
+ * We place the page tables 16K below TEXTADDR.  Therefore, we must make sure
+ * that TEXTADDR is correctly set.  Currently, we expect the least significant
+ * "short" to be 0x8000, but we could probably relax this restriction to
+ * TEXTADDR > PAGE_OFFSET + 0x4000
+ *
+ * Note that swapper_pg_dir is the virtual address of the page tables, and
+ * pgtbl gives us a position-independent reference to these tables.  We can
+ * do this because stext == TEXTADDR
+ *
+ * swapper_pg_dir, pgtbl and krnladr are all closely related.
+ */
+
+#ifndef CONFIG_UCLINUX
+		.globl	SYMBOL_NAME(swapper_pg_dir)
+		.equ	SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x4000
+		.macro	pgtbl, reg, rambase
+		adr	\reg, stext
+		sub	\reg, \reg, #0x4000
+		.endm
+
+/*
+ * Since the page table is closely related to the kernel start address, we
+ * can convert the page table base address to the base address of the section
+ * containing both.
+ */
+		.macro	krnladr, rd, pgtable, rambase
+		bic	\rd, \pgtable, #0x000ff000
+		.endm
+#endif
+
+/*
+ *  Kernel startup entry point.
+ *
+ * The rules are:
+ *  r0      - should be 0
+ *  r1      - unique architecture number
+ *  MMU     - off
+ *  I-cache - on or off
+ *  D-cache - off
+ *
+ * See linux/arch/arm/tools/mach-types for the complete list of numbers
+ * for r1.
+ */
+
+
+.section ".text.init",#alloc,#execinstr
+		.type	stext, #function
+ENTRY(stext)
+#if defined(CONFIG_CPU_S3C44B0X)
+/*
+ * We assume that there is a bootloader that has jump instructions at all
+ * exception vectors that lead to their position shifted to the start of
+ * RAM. Further on we assume that the following code gets linked to the
+ * start of RAM, so that all jumps match again.
+ */
+		b   	99f			/* 0x00 reset vector */
+		b	vector_undefinstr	/* 0x04 undefined instruction  */
+		b	vector_swi		/* 0x08 software interrupt */
+		b	vector_prefetch		/* 0x0C prefetch abort */
+		b	vector_data		/* 0x10 data abort */
+		b	vector_addrexcptn	/* 0x14 address exception */
+		b	vector_IRQ		/* 0x18 IRQ */
+		b	vector_FIQ		/* 0x1C FIQ */
+99:
+#endif
+                mov	r12, r0
+/*
+ * NOTE!  Any code which is placed here should be done for one of
+ * the following reasons:
+ *
+ *  1. Compatability with old production boot firmware (ie, users
+ *     actually have and are booting the kernel with the old firmware)
+ *     and therefore will be eventually removed.
+ *  2. Cover the case when there is no boot firmware.  This is not
+ *     ideal, but in this case, it should ONLY set r0 and r1 to the
+ *     appropriate value.
+ */
+
+#if defined(CONFIG_ARCH_INL)
+/* Intersil uClinux kernel.
+ * Parameters that are passed by the loader:
+ *   r0 = start of system image in flash
+ *   r1 = address of boot_area/boot_struct (at end of ram)
+ *   r2 = address of boot parameter block
+ */
+		ldr	r3, BOOTSTRUCT
+		str	r1, [r3]
+
+		ldr	r3, BOOTPARAM
+		str	r2, [r3]
+
+		bl	init_mpu_sections		@ init MPU areas. Trashes r0/r1
+		b	mach_init
+
+BOOTSTRUCT: .long bootstruct
+BOOTPARAM: .long boot_param_block
+
+#if defined(CONFIG_ARCH_POLDHU)
+#include <asm/arch/gpio.h>
+#include <asm/arch/hardware.h>
+
+mach_init:
+		mov     r1, #PERIPH_BASE	@ initialize the UART
+		mov     r0, #0x18
+		orr     r0, r0, r0, lsl #16
+		str     r0, [r1, #uGPIOFSEL - PERIPH_BASE]
+		
+		mov	r1, #MACH_TYPE_POLDHU	@ Set machine type
+
+#endif @CONFIG_ARCH_POLDHU
+
+#if defined(CONFIG_ARCH_ISL3893)
+
+mach_init:
+		mov	r1, #MACH_TYPE_ISL3893	@ Set machine type
+
+#endif @CONFIG_ARCH_ISL3893
+
+#endif @CONFIG_ARCH_INL
+
+#if defined(CONFIG_ARCH_NETWINDER)
+/*
+ * Compatability cruft for old NetWinder NeTTroms.  This
+ * code is currently scheduled for destruction in 2.5.xx
+ */
+		.rept	8
+		mov	r0, r0
+		.endr
+
+		adr	r2, 1f
+		ldmdb	r2, {r7, r8}
+		and	r3, r2, #0xc000
+		teq	r3, #0x8000
+		beq	__entry
+		bic	r3, r2, #0xc000
+		orr	r3, r3, #0x8000
+		mov	r0, r3
+		mov	r4, #64
+		sub	r5, r8, r7
+		b	1f
+
+		.word	_stext
+		.word	__bss_start
+
+1:
+		.rept	4
+		ldmia	r2!, {r6, r7, r8, r9}
+		stmia	r3!, {r6, r7, r8, r9}
+		.endr
+		subs	r4, r4, #64
+		bcs	1b
+		movs	r4, r5
+		mov	r5, #0
+		movne	pc, r0
+
+		mov	r1, #MACH_TYPE_NETWINDER	@ (will go in 2.5)
+		mov	r12, #2 << 24			@ scheduled for removal in 2.5.xx
+		orr	r12, r12, #5 << 12
+__entry:
+#endif
+#if defined(CONFIG_ARCH_L7200)
+/*
+ * FIXME - No bootloader, so manually set 'r1' with our architecture number.
+ */
+		mov	r1, #MACH_TYPE_L7200
+#elif defined(CONFIG_ARCH_INTEGRATOR)
+		mov	r1, #MACH_TYPE_INTEGRATOR
+#elif defined(CONFIG_ARCH_P52)
+		mov	r1, #MACH_TYPE_P52
+#elif defined(CONFIG_ARCH_CX821XX)
+		mov	r1, #MACH_TYPE_CX821XX
+#elif defined(CONFIG_ARCH_SWARM)
+		mov	r1, #MACH_TYPE_SWARM
+#elif defined(CONFIG_BOARD_SNDS100)
+		mov	r1, #MACH_TYPE_SNDS100
+#elif defined (CONFIG_BOARD_SMDK40100)
+		mov	r1, #MACH_TYPE_S3C3410
+#elif defined (CONFIG_BOARD_MBA44)
+		mov	r1, #MACH_TYPE_S3C44B0X
+#elif defined(CONFIG_BOARD_SMDK2500)
+		mov     r1, #MACH_TYPE_SMDK2500
+#elif defined(CONFIG_BOARD_S3C2500REFRGP)
+		mov	r1, #MACH_TYPE_S3C2500REFRGP
+#endif
+
+		mov	r0, #F_BIT | I_BIT | MODE_SVC	@ make sure svc mode
+		msr	cpsr_c, r0			@ and all irqs disabled
+
+#if defined(CONFIG_ARCH_ATMEL)
+
+        adr	r5, LC0
+        ldmia	r5, {r5, r6, r8, r9, sp}			@ Setup stack
+
+        /*  Copy data sections to their new home.  */
+
+
+        /*  Clear BSS */
+        mov	r4, #0
+1:      cmp	r5, r8					
+        strcc	r4, [r5],#4
+        bcc	1b
+
+/* FIXME */
+#if 0
+        /*  Put initial values into stack.  This would normally be done
+        by sched_init() in kernel/sched.c, but that would overwrite the
+        stack we're already using.  That would be bad.
+        */
+        mov r5, sp
+        sub r5, r5, #0x2000
+        ldr r4, L_STACK_MAGIC
+        str r4, [r5], #4
+        ldr r4, L_STACK_UNTOUCHED_MAGIC
+1:      cmp r5, sp
+        strcc r4, [r5], #4
+        bcc 1b
+#endif
+        /*  Pretend we know what our processor code is (for arm_id)   */
+
+@@@	ldr     r2, =0x41000000
+@@@	orr	r2, r2, #0x7000		@ FIXME --> 0x41007000
+
+	ldr	r2, L_AT91_SF_CIDR
+	ldr	r2, [r2]		@ read processor id
+
+	str     r2, [r6]
+	mov     r2, #MACH_TYPE_ATMEL
+	str     r2, [r9]
+
+        mov fp, #0
+        b	start_kernel
+        
+LC0:	.long	__bss_start
+        .long	processor_id
+        .long	_end
+	.long   __machine_arch_type
+        .long	init_task_union+8192
+#endif
+
+#if defined(CONFIG_BOARD_SNDS100)
+
+        adr	r5, LC0
+        ldmia	r5, {r5, r6, r8, r9, sp}			@ Setup stack
+
+        /*  Copy data sections to their new home.  */
+
+
+        /*  Clear BSS */
+        mov	r4, #0
+1:      cmp	r5, r8					
+        strcc	r4, [r5],#4
+        bcc	1b
+
+        /*  Pretend we know what our processor code is (for arm_id)   */
+
+	ldr	r2, S3C4510B_PROCESSOR_TYPE
+
+	str     r2, [r6]
+	mov     r2, #MACH_TYPE_SNDS100
+	str     r2, [r9]
+
+        mov fp, #0
+        b	start_kernel
+        
+LC0:	.long	__bss_start
+        .long	processor_id
+        .long	_end
+	.long   __machine_arch_type
+        .long	init_task_union+8192
+	
+S3C4510B_PROCESSOR_TYPE:
+	.long	0x36365036
+#endif
+
+#if defined(CONFIG_ARCH_TA7S) || defined(CONFIG_ARCH_TA7V)
+	b	a7Start
+
+	.globl a7Start
+	.org 0x1000
+a7Start:
+	/*
+	 * Setup a temp. SP and then call the SDRAM init function.
+	 */
+	ldr     sp, L_INIT_SP
+	bl	a7hal_sdram_init
+
+	/*
+	 * If the kernel needs to run from SDRAM
+	 * we copy it from FLASH to SDRAM here.
+	 */
+#ifdef USE_A7HAL
+	mov	r0,#0x00000000
+	mov	r1,#0xc0000000
+	ldr	r2, LC0
+	mov	r3,#0
+	BL	a7hal_dma_pollTransfer
+#else
+	mov	r0,#0x00000000
+	mov	r1,#0xc0000000
+	ldr	r2, LC0
+copy_loop:
+	ldr	r3,[r0],#4
+	str	r3,[r1],#4
+	cmp	r0,r2
+	blt	copy_loop
+#endif
+	/*
+	 * Jump up to the physical execution address so we can
+	 * change the alias.
+	 */
+	ldr	pc, L_HIGH_JUMP
+
+_jump_to_high:
+	/*
+	 * Map the SDRAM to address zero
+	 */
+	ldr	r4, L_REMAP_ALIAS_REG
+	mov	r2, #0x08
+	str	r2,[r4,#0]
+
+ 	ldr	pc, L_LOW_JUMP
+__zentry:
+
+        adr	r5, LC0
+        ldmia	r5, {r5, r6, r8, r9, sp}			@ Setup stack
+
+        /*  Clear BSS */
+        mov	r4, #0
+1:      cmp	r5, r8					
+        strcc	r4, [r5],#4
+        bcc	1b
+
+
+	ldr	r2, L_REMAP_IDENT_REG
+	ldr	r2, [r2]
+	str	r2, [r6]
+	ldr     r2, mach_type_ta7
+	ldr	r2, [r2]
+	/*
+	 * r1 should hold the processor type when start_kernel
+	 * is called.
+	 */
+	mov	r1,r2
+	str     r2, [r9]
+
+
+	mov	fp, #0
+	b	start_kernel
+
+mach_type_ta7:
+#if defined(CONFIG_ARCH_TA7S)
+	.long	MACH_TYPE_TA7S
+#elif defined(CONFIG_ARCH_TA7V)
+	.long	MACH_TYPE_TA7V
+#endif
+
+L_REMAP_IDENT_REG:
+	.long	0xd1010410
+L_INIT_SP:
+	.long	0xd1034000
+L_HIGH_JUMP:
+	.long	(_jump_to_high + 0xc0000000)
+L_LOW_JUMP:
+	.long	__zentry
+L_REMAP_ALIAS_REG:
+	.long	0xd1010440
+L_END_KERNEL:
+	.long	_end_kernel
+
+LC0:	.long	__bss_start
+       	.long	processor_id
+       	.long	_end
+	.long   __machine_arch_type
+       	.long	init_task_union+8192
+
+#endif /* CONFIG_ARCH_TA7S || CONFIG_ARCH_TA7V */
+
+#if defined(CONFIG_CPU_S3C3410) || defined(CONFIG_CPU_S3C4530) || defined(CONFIG_CPU_S3C44B0X)
+
+                adr     r2, LC0
+
+#if     defined(CONFIG_ROMKERNEL)
+                @  Copy data sections to their new home
+                ldmia   r2, {r4-r11,sp}
+                cmp     r9, r11
+                beq     2f
+1:              cmp     r11, r10
+                ldrcc   r3, [r9], #4
+                strcc   r3, [r11], #4
+                bcc     1b
+#else
+                ldmia   r2, {r4-r8,sp}
+#endif
+
+		@ clear BSS
+2:              mov     r3, #0
+3:              cmp     r7, r8
+                strcc   r3, [r7], #4
+                bcc     3b
+
+#if     defined(CONFIG_CPU_S3C3410)
+		ldr	r3, S3C3410_PROCESSOR_TYPE
+		str	r3, [r5]
+		
+		mov	r3, #MACH_TYPE_S3C3410
+		str	r3, [r6]
+#endif
+#if     defined(CONFIG_CPU_S3C44B0X)
+		ldr	r3, S3C44B0X_PROCESSOR_TYPE
+		str	r3, [r5]
+		
+		mov	r3, #MACH_TYPE_S3C44B0X
+		str	r3, [r6]
+#endif
+#if     defined(CONFIG_CPU_S3C4530)
+                ldr     r3, [r4]                @ read system configuration register
+                bic     r3, r3, #0x83FFFFFF     @ get product identifier
+                str     r3, [r5]                @ store it
+#endif
+#if     defined(CONFIG_BOARD_EVS3C4530HEI)
+                mov     r3, #MACH_TYPE_EVS3C4530HEI
+                str     r3, [r6]
+#endif
+                mov     fp, #0
+                b       start_kernel
+
+#if defined(CONFIG_CPU_S3C3410)
+S3C3410_PROCESSOR_TYPE:
+		.long	0x34103410
+#endif
+#if defined(CONFIG_CPU_S3C44B0X)
+S3C44B0X_PROCESSOR_TYPE:
+		.long	0x44B044B0
+#endif
+		
+LC0:
+#if             defined(CONFIG_CPU_S3C4530)
+                .long   0x3ff0000               @ r4
+#endif
+#if             defined(CONFIG_CPU_S3C3410) || defined (CONFIG_CPU_S3C44B0X)
+                .long   0x07ff0000              @ r4
+#endif
+                .long   processor_id            @ r5
+                .long   __machine_arch_type     @ r6
+                .long   __bss_start             @ r7   bss start
+                .long   _end                    @ r8   bss end
+
+#if     defined (CONFIG_ROMKERNEL)
+#if     defined (CONFIG_BOARD_SMDK40100) || defined (CONFIG_BOARD_MBA44)
+                .long   _etext                  @ r9   data start in ROM (src)
+#else
+                .long   _end_romfs              @ r9   data start in ROM (src)
+#endif
+                .long   _edata                  @ r10  data end in RAM
+                .long   __data_start            @ r11  data start in RAM (dst)
+#endif  /* CONFIG_ROMKERNEL */
+                .long   init_task_union+8192    @ sp
+#endif  /* CONFIG_ARCH_SAMSUNG */
+
+#if	defined(CONFIG_BOARD_S3C2500REFRGP) || \
+	defined(CONFIG_BOARD_SMDK2500)
+		bl	get_system_clock
+#endif		
+
+		bl	__lookup_processor_type
+		teq	r10, #0				@ invalid processor?
+		moveq	r0, #'p'			@ yes, error 'p'
+		beq	__error
+		bl	__lookup_architecture_type
+#if !defined(CONFIG_ARCTURUS) && !defined(CONFIG_ARCH_DM270)
+		teq	r7, #0				@ invalid architecture?
+		moveq	r0, #'a'			@ yes, error 'a'
+		beq	__error
+#endif
+#ifndef CONFIG_UCLINUX
+		bl	__create_page_tables
+#endif
+#if defined(CONFIG_ARCH_POLDHU) || defined(CONFIG_ARCH_ISL3893)
+		mrc	p15, 0, r0, c1, c0		@ We do not want to overwrite the control
+		b	__mmap_switched			@ register, so get the current CR and 
+							@ jump over the init processor stuff.
+#endif
+		adr	lr, __ret			@ return address
+		add	pc, r10, #12			@ initialise processor
+							@ (return control reg)
+
+__switch_data:	.long	__mmap_switched
+		.long	SYMBOL_NAME(compat)
+		.long	SYMBOL_NAME(__bss_start)
+		.long	SYMBOL_NAME(_end)
+		.long	SYMBOL_NAME(processor_id)
+		.long	SYMBOL_NAME(__machine_arch_type)
+		.long	SYMBOL_NAME(cr_alignment)
+		.long	SYMBOL_NAME(init_task_union)+8192
+
+__ret:		ldr	lr, __switch_data
+#ifdef CONFIG_CPU_WITH_CACHE
+# ifdef CONFIG_CPU_WITH_MCR_INSTRUCTION
+		mcr	p15, 0, r0, c1, c0
+		mov	r0, r0
+		mov	r0, r0
+		mov	r0, r0
+# else
+#  warning 	"FIXME: Enable Cache, Other settings without MCR Instruction"
+		@ Note r0 is initialized suitably to enable Cache
+		@ and additional settings if any in proc_armX.S file
+		@ A possible code here
+		@ldr	r2, CACHE_CONTROL_MEM_LOCATION
+		@str	r0, [r2]
+# endif
+#endif
+		mov	pc, lr
+
+		/*
+		 * This code follows on after the page
+		 * table switch and jump above.
+		 *
+		 * r0  = processor control register
+		 * r1  = machine ID
+		 * r9  = processor ID
+		 */
+		.align	5
+__mmap_switched:
+		adr	r3, __switch_data + 4
+		ldmia	r3, {r2, r4, r5, r6, r7, r8, sp}@ r2 = compat
+							@ sp = stack pointer
+		str	r12, [r2]
+
+#ifdef CONFIG_RAM_ATTACHED_ROMFS 
+# ifdef CONFIG_ARCH_DM270
+/*
+ *	Move ROM filesystem above bss :-)
+ */
+		ldr r3, L_DM270_ROMFS			@ Get end of data
+
+		ldr r10, [r3, #8]			@ Get size of ROMFS (big-endian)
+#ifndef CONFIG_CPU_BIG_ENDIAN
+		mov r2, #0				@ Convert to little-endian
+		and fp, r10, #0x000000ff
+		orr r2, r2, fp, lsl #24
+		and fp, r10, #0x0000ff00
+		orr r2, r2, fp, lsl #8
+		and fp, r10, #0x00ff0000
+		orr r2, r2, fp, lsr #8
+		and fp, r10, #0xff000000
+		orr r2, r2, fp, lsr #24
+		mov r10, r2
+#endif
+		add r10, r10, #8			@ Allow for rounding
+		bic r10, r10, #3			@ Whole words
+
+		ldr fp, L_DM270_ROMFS + 4		@ Set up destination
+		mov r2, r3				@ Copy of _edata
+
+		add r3, r3, r10				@ Copy from end
+		add fp, fp, r10
+		ldr r10, L_DM270_RAMSTART
+		str fp, [r10]
+		
+_copy_romfs:
+		ldr r10, [r3, #-4]!			@ Copy dword
+		str r10, [fp, #-4]!
+		cmp r3, r2				@ Check if at end
+		bne _copy_romfs
+# endif
+#endif
+
+		mov	fp, #0				@ Clear BSS (and zero fp)
+1:		cmp	r4, r5
+		strcc	fp, [r4],#4
+		bcc	1b
+
+		str	r9, [r6]			@ Save processor ID
+		str	r1, [r7]			@ Save machine type
+#ifdef CONFIG_ALIGNMENT_TRAP
+		orr	r0, r0, #2			@ ...........A.
+#endif
+		bic	r2, r0, #2			@ Clear 'A' bit
+		stmia	r8, {r0, r2}			@ Save control register values
+		b	SYMBOL_NAME(start_kernel)
+
+
+#ifndef CONFIG_UCLINUX
+/*
+ * Setup the initial page tables.  We only setup the barest
+ * amount which are required to get the kernel running, which
+ * generally means mapping in the kernel code.
+ *
+ * We only map in 4MB of RAM, which should be sufficient in
+ * all cases.
+ *
+ * r5 = physical address of start of RAM
+ * r6 = physical IO address
+ * r7 = byte offset into page tables for IO
+ * r8 = page table flags
+ */
+__create_page_tables:
+		pgtbl	r4, r5				@ page table address
+
+		/*
+		 * Clear the 16K level 1 swapper page table
+		 */
+		mov	r0, r4
+		mov	r3, #0
+		add	r2, r0, #0x4000
+1:		str	r3, [r0], #4
+		str	r3, [r0], #4
+		str	r3, [r0], #4
+		str	r3, [r0], #4
+		teq	r0, r2
+		bne	1b
+
+		/*
+		 * Create identity mapping for first MB of kernel to
+		 * cater for the MMU enable.  This identity mapping
+		 * will be removed by paging_init()
+		 */
+		krnladr	r2, r4, r5			@ start of kernel
+		add	r3, r8, r2			@ flags + kernel base
+		str	r3, [r4, r2, lsr #18]		@ identity mapping
+
+		/*
+		 * Now setup the pagetables for our kernel direct
+		 * mapped region.  We round TEXTADDR down to the
+		 * nearest megabyte boundary.
+		 */
+		add	r0, r4, #(TEXTADDR & 0xff000000) >> 18 @ start of kernel
+		add	r0, r0, #(TEXTADDR & 0x00f00000) >> 18
+		str	r3, [r0], #4			@ PAGE_OFFSET + 0MB
+		add	r3, r3, #1 << 20
+		str	r3, [r0], #4			@ PAGE_OFFSET + 1MB
+		add	r3, r3, #1 << 20
+		str	r3, [r0], #4			@ PAGE_OFFSET + 2MB
+		add	r3, r3, #1 << 20
+		str	r3, [r0], #4			@ PAGE_OFFSET + 3MB
+
+		/*
+		 * Ensure that the first section of RAM is present.
+		 * we assume that:
+		 *  1. the RAM is aligned to a 256MB boundary
+		 *  2. the kernel is executing in the same 256MB chunk
+		 *     as the start of RAM.
+		 */
+		bic	r0, r0, #0x0ff00000 >> 18	@ round down
+		and	r2, r5, #0xf0000000		@ round down
+		add	r3, r8, r2			@ flags + rambase
+		str	r3, [r0]
+
+		bic	r8, r8, #0x0c			@ turn off cacheable
+							@ and bufferable bits
+#ifdef CONFIG_DEBUG_LL
+		/*
+		 * Map in IO space for serial debugging.
+		 * This allows debug messages to be output
+		 * via a serial console before paging_init.
+		 */
+		add	r0, r4, r7
+		rsb	r3, r7, #0x4000	@ PTRS_PER_PGD*sizeof(long)
+		cmp	r3, #0x0800
+		addge	r2, r0, #0x0800
+		addlt	r2, r0, r3
+		orr	r3, r6, r8
+1:		str	r3, [r0], #4
+		add	r3, r3, #1 << 20
+		teq	r0, r2
+		bne	1b
+#ifdef CONFIG_ARCH_NETWINDER
+		/*
+		 * If we're using the NetWinder, we need to map in
+		 * the 16550-type serial port for the debug messages
+		 */
+		teq	r1, #MACH_TYPE_NETWINDER
+		bne	1f
+		add	r0, r4, #0x3fc0
+		mov	r3, #0x7c000000
+		orr	r3, r3, r8
+		str	r3, [r0], #4
+		add	r3, r3, #1 << 20
+		str	r3, [r0], #4
+1:
+#endif
+#endif
+#ifdef CONFIG_ARCH_RPC
+		/*
+		 * Map in screen at 0x02000000 & SCREEN2_BASE
+		 * Similar reasons here - for debug.  This is
+		 * only for Acorn RiscPC architectures.
+		 */
+		add	r0, r4, #0x80			@ 02000000
+		mov	r3, #0x02000000
+		orr	r3, r3, r8
+		str	r3, [r0]
+		add	r0, r4, #0x3600			@ d8000000
+		str	r3, [r0]
+#endif
+		mov	pc, lr
+#endif
+
+
+/*
+ * Exception handling.  Something went wrong and we can't
+ * proceed.  We ought to tell the user, but since we
+ * don't have any guarantee that we're even running on
+ * the right architecture, we do virtually nothing.
+ * r0 = ascii error character:
+ *	a = invalid architecture
+ *	p = invalid processor
+ *	i = invalid calling convention
+ *
+ * Generally, only serious errors cause this.
+ */
+__error:
+#ifdef CONFIG_DEBUG_LL
+		mov	r8, r0				@ preserve r0
+		adr	r0, err_str
+		bl	printascii
+		mov	r0, r8
+		bl	printch
+#endif
+#ifdef CONFIG_ARCH_RPC
+/*
+ * Turn the screen red on a error - RiscPC only.
+ */
+		mov	r0, #0x02000000
+		mov	r3, #0x11
+		orr	r3, r3, r3, lsl #8
+		orr	r3, r3, r3, lsl #16
+		str	r3, [r0], #4
+		str	r3, [r0], #4
+		str	r3, [r0], #4
+		str	r3, [r0], #4
+#endif
+1:		mov	r0, r0
+		b	1b
+
+#ifdef CONFIG_DEBUG_LL
+err_str:	.asciz	"\nError: "
+		.align
+#endif
+
+/*
+ * Read processor ID register (CP#15, CR0), and look up in the linker-built
+ * supported processor list.  Note that we can't use the absolute addresses
+ * for the __proc_info lists since we aren't running with the MMU on
+ * (and therefore, we are not in the correct address space).  We have to
+ * calculate the offset.
+ *
+ * Returns:
+ *	r5, r6, r7 corrupted
+ *	r8  = page table flags
+ *	r9  = processor ID
+ *	r10 = pointer to processor structure
+ */
+__lookup_processor_type:
+		adr	r5, 2f
+		ldmia	r5, {r7, r9, r10}
+		sub	r5, r5, r10			@ convert addresses
+		add	r7, r7, r5			@ to our address space
+		add	r10, r9, r5
+#ifdef CONFIG_CPU_WITH_MCR_INSTRUCTION
+		mrc	p15, 0, r9, c0, c0		@ get processor id
+#else
+# warning 	"FIXME: Get Processor ID without MCR Instruction"
+		@ A possible code
+		@ldr	r9, PROCESSOR_ID_MEM_LOCATION
+		@ldr	r9, [r9]
+#ifdef CONFIG_ARCH_DM270
+		ldr	r9, L_DM270_PID
+#endif
+#endif
+1:		ldmia	r10, {r5, r6, r8}		@ value, mask, mmuflags
+		and	r6, r6, r9			@ mask wanted bits
+		teq	r5, r6
+		moveq	pc, lr
+		add	r10, r10, #36			@ sizeof(proc_info_list)
+		cmp	r10, r7
+		blt	1b
+		mov	r10, #0				@ unknown processor
+		mov	pc, lr
+
+/*
+ * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
+ * more information about the __proc_info and __arch_info structures.
+ */
+2:		.long	__proc_info_end
+		.long	__proc_info_begin
+		.long	2b
+		.long	__arch_info_begin
+		.long	__arch_info_end
+
+/*
+ * Lookup machine architecture in the linker-build list of architectures.
+ * Note that we can't use the absolute addresses for the __arch_info
+ * lists since we aren't running with the MMU on (and therefore, we are
+ * not in the correct address space).  We have to calculate the offset.
+ *
+ *  r1 = machine architecture number
+ * Returns:
+ *  r2, r3, r4 corrupted
+ *  r5 = physical start address of RAM
+ *  r6 = physical address of IO
+ *  r7 = byte offset into page tables for IO
+ */
+__lookup_architecture_type:
+		adr	r4, 2b
+		ldmia	r4, {r2, r3, r5, r6, r7}	@ throw away r2, r3
+		sub	r5, r4, r5			@ convert addresses
+		add	r4, r6, r5			@ to our address space
+		add	r7, r7, r5
+1:		ldr	r5, [r4]			@ get machine type
+		teq	r5, r1
+		beq	2f
+		add	r4, r4, #SIZEOF_MACHINE_DESC
+		cmp	r4, r7
+		blt	1b
+		mov	r7, #0				@ unknown architecture
+		mov	pc, lr
+2:		ldmib	r4, {r5, r6, r7}		@ found, get results
+		mov	r7, r7, lsr #18			@ pagetable byte offset
+		mov	pc, lr
+
+L_AT91_SF_CIDR: .long	0xfff00000
+
+#ifdef CONFIG_ARCH_DM270
+L_DM270_PID:	.long	0xd2700000
+
+# ifdef CONFIG_RAM_ATTACHED_ROMFS 
+.global	_ramstart
+_ramstart:	.long	0
+
+L_DM270_ROMFS:	.long	_edata
+		.long	_ebss
+
+L_DM270_RAMSTART:
+		.long	_ramstart
+# endif
+#endif
+
+#if defined(CONFIG_ARCH_TA7S) || defined(CONFIG_ARCH_TA7V)
+#ifdef	CONFIG_BLK_DEV_RAMDISK_DATA
+.section ".rodata"
+	.align	12
+	.globl	__ramdisk_data
+__ramdisk_data:
+#include "ramdisk.inc"
+	.globl	__ramdisk_data_end
+__ramdisk_data_end:
+	.align	
+#endif
+#endif
+
diff -urN linux-2.4.29/arch/armnommu/kernel/init_task.c linux-2.4.29-uc1/arch/armnommu/kernel/init_task.c
--- linux-2.4.29/arch/armnommu/kernel/init_task.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/init_task.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ *  linux/arch/arm/kernel/init_task.c
+ */
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS;
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+/*
+ * Initial task structure.
+ *
+ * We need to make sure that this is 8192-byte aligned due to the
+ * way process stacks are handled. This is done by making sure
+ * the linker maps this in the .text segment right after head.S,
+ * and making head.S ensure the proper alignment.
+ *
+ * The things we do for performance..
+ */
+union task_union init_task_union __attribute__((__section__(".init.task"))) =
+		{ INIT_TASK(init_task_union.task) };
diff -urN linux-2.4.29/arch/armnommu/kernel/io.c linux-2.4.29-uc1/arch/armnommu/kernel/io.c
--- linux-2.4.29/arch/armnommu/kernel/io.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/io.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,49 @@
+#include <linux/module.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+
+/*
+ * Copy data from IO memory space to "real" memory space.
+ * This needs to be optimized.
+ */
+void _memcpy_fromio(void * to, unsigned long from, size_t count)
+{
+	while (count) {
+		count--;
+		*(char *) to = readb(from);
+		((char *) to)++;
+		from++;
+	}
+}
+
+/*
+ * Copy data from "real" memory space to IO memory space.
+ * This needs to be optimized.
+ */
+void _memcpy_toio(unsigned long to, const void * from, size_t count)
+{
+	while (count) {
+		count--;
+		writeb(*(char *) from, to);
+		((char *) from)++;
+		to++;
+	}
+}
+
+/*
+ * "memset" on IO memory space.
+ * This needs to be optimized.
+ */
+void _memset_io(unsigned long dst, int c, size_t count)
+{
+	while (count) {
+		count--;
+		writeb(c, dst);
+		dst++;
+	}
+}
+
+EXPORT_SYMBOL(_memcpy_fromio);
+EXPORT_SYMBOL(_memcpy_toio);
+EXPORT_SYMBOL(_memset_io);
diff -urN linux-2.4.29/arch/armnommu/kernel/irq-arch.c linux-2.4.29-uc1/arch/armnommu/kernel/irq-arch.c
--- linux-2.4.29/arch/armnommu/kernel/irq-arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/irq-arch.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,40 @@
+/*
+ *  linux/arch/arm/kernel/irq-arch.c
+ *
+ *  Copyright (C) 1995-2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  We contain the architecture-specific parts of interrupt handling
+ *  in this file.  In 2.5, it will move into the various arch/arm/mach-*
+ *  directories.
+ */
+#include <linux/ptrace.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/random.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#include <asm/mach/irq.h>
+
+/*
+ * Get architecture specific interrupt handlers
+ * and interrupt initialisation.
+ */
+#include <asm/arch/irq.h>
+
+void __init genarch_init_irq(void)
+{
+	irq_init_irq();
+}
+
diff -urN linux-2.4.29/arch/armnommu/kernel/irq.c linux-2.4.29-uc1/arch/armnommu/kernel/irq.c
--- linux-2.4.29/arch/armnommu/kernel/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/irq.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,532 @@
+/*
+ *  linux/arch/arm/kernel/irq.c
+ *
+ *  Copyright (C) 1992 Linus Torvalds
+ *  Modifications for ARM processor Copyright (C) 1995-2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  This file contains the code used by various IRQ handling routines:
+ *  asking for different IRQ's should be done through these routines
+ *  instead of just grabbing them. Thus setups with different IRQ numbers
+ *  shouldn't result in any weird surprises, and installing new handlers
+ *  should be easier.
+ *
+ *  IRQ's are in fact implemented a bit like signal handlers for the kernel.
+ *  Naturally it's not a 1:1 relation, but there are similarities.
+ */
+#include <linux/config.h>
+#include <linux/ptrace.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/irq.h>	/* pick up fixup_irq definition */
+
+/*
+ * Maximum IRQ count.  Currently, this is arbitary.  However, it should
+ * not be set too low to prevent false triggering.  Conversely, if it
+ * is set too high, then you could miss a stuck IRQ.
+ *
+ * Maybe we ought to set a timer and re-enable the IRQ at a later time?
+ */
+#define MAX_IRQ_CNT	100000
+
+static volatile unsigned long irq_err_count;
+static spinlock_t irq_controller_lock;
+
+struct irqdesc irq_desc[NR_IRQS];
+void (*init_arch_irq)(void) __initdata = NULL;
+
+/*
+ * Dummy mask/unmask handler
+ */
+static void dummy_mask_unmask_irq(unsigned int irq)
+{
+}
+
+/**
+ *	disable_irq - disable an irq and wait for completion
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line.
+ *
+ *	This function may be called - with care - from IRQ context.
+ */
+void disable_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&irq_controller_lock, flags);
+	irq_desc[irq].enabled = 0;
+	irq_desc[irq].mask(irq);
+	spin_unlock_irqrestore(&irq_controller_lock, flags);
+}
+
+/**
+ *	enable_irq - enable interrupt handling on an irq
+ *	@irq: Interrupt to enable
+ *
+ *	Re-enables the processing of interrupts on this IRQ line
+ *
+ *	This function may be called from IRQ context.
+ */
+void enable_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&irq_controller_lock, flags);
+	irq_desc[irq].probing = 0;
+	irq_desc[irq].triggered = 0;
+	irq_desc[irq].enabled = 1;
+	irq_desc[irq].unmask(irq);
+	spin_unlock_irqrestore(&irq_controller_lock, flags);
+}
+
+int get_irq_list(char *buf)
+{
+	int i;
+	struct irqaction * action;
+	char *p = buf;
+
+	for (i = 0 ; i < NR_IRQS ; i++) {
+	    	action = irq_desc[i].action;
+		if (!action)
+			continue;
+		p += sprintf(p, "%3d: %10u ", i, kstat_irqs(i));
+		p += sprintf(p, "  %s", action->name);
+		for (action = action->next; action; action = action->next) {
+			p += sprintf(p, ", %s", action->name);
+		}
+		*p++ = '\n';
+	}
+
+#ifdef CONFIG_ARCH_ACORN
+	p += get_fiq_list(p);
+#endif
+	p += sprintf(p, "Err: %10lu\n", irq_err_count);
+	return p - buf;
+}
+
+/*
+ * IRQ lock detection.
+ *
+ * Hopefully, this should get us out of a few locked situations.
+ * However, it may take a while for this to happen, since we need
+ * a large number if IRQs to appear in the same jiffie with the
+ * same instruction pointer (or within 2 instructions).
+ */
+static void check_irq_lock(struct irqdesc *desc, int irq, struct pt_regs *regs)
+{
+	unsigned long instr_ptr = instruction_pointer(regs);
+
+	if (desc->lck_jif == jiffies &&
+	    desc->lck_pc >= instr_ptr && desc->lck_pc < instr_ptr + 8) {
+		desc->lck_cnt += 1;
+
+		if (desc->lck_cnt > MAX_IRQ_CNT) {
+			printk(KERN_ERR "IRQ LOCK: IRQ%d is locking the system, disabled\n", irq);
+			disable_irq(irq);
+		}
+	} else {
+		desc->lck_cnt = 0;
+		desc->lck_pc  = instruction_pointer(regs);
+		desc->lck_jif = jiffies;
+	}
+}
+
+/*
+ * do_IRQ handles all normal device IRQ's
+ */
+asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
+{
+	struct irqdesc * desc;
+	struct irqaction * action;
+	int cpu;
+
+#ifdef CONFIG_BOARD_SNDS100
+        /*
+         * FIXME: This is not the best place to put this work around. 
+         */
+	CLEAR_PEND_INT(irq);
+#endif
+
+	irq = fixup_irq(irq);
+
+	/*
+	 * Some hardware gives randomly wrong interrupts.  Rather
+	 * than crashing, do something sensible.
+	 */
+	if (irq >= NR_IRQS)
+		goto bad_irq;
+
+	desc = irq_desc + irq;
+
+	spin_lock(&irq_controller_lock);
+	desc->mask_ack(irq);
+	spin_unlock(&irq_controller_lock);
+
+	cpu = smp_processor_id();
+	irq_enter(cpu, irq);
+	kstat.irqs[cpu][irq]++;
+	desc->triggered = 1;
+
+	/* Return with this interrupt masked if no action */
+	action = desc->action;
+
+	if (action) {
+		int status = 0;
+
+		if (desc->nomask) {
+			spin_lock(&irq_controller_lock);
+			desc->unmask(irq);
+			spin_unlock(&irq_controller_lock);
+		}
+
+		if (!(action->flags & SA_INTERRUPT))
+			__sti();
+
+		do {
+			status |= action->flags;
+			action->handler(irq, action->dev_id, regs);
+			action = action->next;
+		} while (action);
+
+		if (status & SA_SAMPLE_RANDOM)
+			add_interrupt_randomness(irq);
+		__cli();
+
+		if (!desc->nomask && desc->enabled) {
+			spin_lock(&irq_controller_lock);
+			desc->unmask(irq);
+			spin_unlock(&irq_controller_lock);
+		}
+	}
+
+	/*
+	 * Debug measure - hopefully we can continue if an
+	 * IRQ lockup problem occurs...
+	 */
+	check_irq_lock(desc, irq, regs);
+
+	irq_exit(cpu, irq);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+	return;
+
+bad_irq:
+	irq_err_count += 1;
+	printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
+	return;
+}
+
+#ifdef CONFIG_ARCH_ACORN
+void do_ecard_IRQ(int irq, struct pt_regs *regs)
+{
+	struct irqdesc * desc;
+	struct irqaction * action;
+	int cpu;
+
+	desc = irq_desc + irq;
+
+	cpu = smp_processor_id();
+	kstat.irqs[cpu][irq]++;
+	desc->triggered = 1;
+
+	action = desc->action;
+
+	if (action) {
+		do {
+			action->handler(irq, action->dev_id, regs);
+			action = action->next;
+		} while (action);
+	} else {
+		spin_lock(&irq_controller_lock);
+		desc->mask(irq);
+		spin_unlock(&irq_controller_lock);
+	}
+}
+#endif
+
+int setup_arm_irq(int irq, struct irqaction * new)
+{
+	int shared = 0;
+	struct irqaction *old, **p;
+	unsigned long flags;
+	struct irqdesc *desc;
+
+	/*
+	 * Some drivers like serial.c use request_irq() heavily,
+	 * so we have to be careful not to interfere with a
+	 * running system.
+	 */
+	if (new->flags & SA_SAMPLE_RANDOM) {
+		/*
+		 * This function might sleep, we want to call it first,
+		 * outside of the atomic block.
+		 * Yes, this might clear the entropy pool if the wrong
+		 * driver is attempted to be loaded, without actually
+		 * installing a new handler, but is this really a problem,
+		 * only the sysadmin is able to do this.
+		 */
+	        rand_initialize_irq(irq);
+	}
+
+	/*
+	 * The following block of code has to be executed atomically
+	 */
+	desc = irq_desc + irq;
+	spin_lock_irqsave(&irq_controller_lock, flags);
+	p = &desc->action;
+	if ((old = *p) != NULL) {
+		/* Can't share interrupts unless both agree to */
+		if (!(old->flags & new->flags & SA_SHIRQ)) {
+			spin_unlock_irqrestore(&irq_controller_lock, flags);
+			return -EBUSY;
+		}
+
+		/* add new interrupt at end of irq queue */
+		do {
+			p = &old->next;
+			old = *p;
+		} while (old);
+		shared = 1;
+	}
+
+	*p = new;
+
+	if (!shared) {
+		desc->nomask = (new->flags & SA_IRQNOMASK) ? 1 : 0;
+		desc->probing = 0;
+		if (!desc->noautoenable) {
+			desc->enabled = 1;
+			desc->unmask(irq);
+		}
+	}
+
+	spin_unlock_irqrestore(&irq_controller_lock, flags);
+	return 0;
+}
+
+/**
+ *	request_irq - allocate an interrupt line
+ *	@irq: Interrupt line to allocate
+ *	@handler: Function to be called when the IRQ occurs
+ *	@irqflags: Interrupt type flags
+ *	@devname: An ascii name for the claiming device
+ *	@dev_id: A cookie passed back to the handler function
+ *
+ *	This call allocates interrupt resources and enables the
+ *	interrupt line and IRQ handling. From the point this
+ *	call is made your handler function may be invoked. Since
+ *	your handler function must clear any interrupt the board
+ *	raises, you must take care both to initialise your hardware
+ *	and to set up the interrupt handler in the right order.
+ *
+ *	Dev_id must be globally unique. Normally the address of the
+ *	device data structure is used as the cookie. Since the handler
+ *	receives this value it makes sense to use it.
+ *
+ *	If your interrupt is shared you must pass a non NULL dev_id
+ *	as this is required when freeing the interrupt.
+ *
+ *	Flags:
+ *
+ *	SA_SHIRQ		Interrupt is shared
+ *
+ *	SA_INTERRUPT		Disable local interrupts while processing
+ *
+ *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
+ *
+ */
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+		 unsigned long irq_flags, const char * devname, void *dev_id)
+{
+	unsigned long retval;
+	struct irqaction *action;
+
+	if (irq >= NR_IRQS || !irq_desc[irq].valid || !handler ||
+	    (irq_flags & SA_SHIRQ && !dev_id))
+		return -EINVAL;
+
+	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irq_flags;
+	action->mask = 0;
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_arm_irq(irq, action);
+
+	if (retval)
+		kfree(action);
+	return retval;
+}
+
+/**
+ *	free_irq - free an interrupt
+ *	@irq: Interrupt line to free
+ *	@dev_id: Device identity to free
+ *
+ *	Remove an interrupt handler. The handler is removed and if the
+ *	interrupt line is no longer in use by any driver it is disabled.
+ *	On a shared IRQ the caller must ensure the interrupt is disabled
+ *	on the card it drives before calling this function.
+ *
+ *	This function may be called from interrupt context.
+ */
+void free_irq(unsigned int irq, void *dev_id)
+{
+	struct irqaction * action, **p;
+	unsigned long flags;
+
+	if (irq >= NR_IRQS || !irq_desc[irq].valid) {
+		printk(KERN_ERR "Trying to free IRQ%d\n",irq);
+#ifdef CONFIG_DEBUG_ERRORS
+		__backtrace();
+#endif
+		return;
+	}
+
+	spin_lock_irqsave(&irq_controller_lock, flags);
+	for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) {
+		if (action->dev_id != dev_id)
+			continue;
+
+	    	/* Found it - now free it */
+		*p = action->next;
+		kfree(action);
+		goto out;
+	}
+	printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
+#ifdef CONFIG_DEBUG_ERRORS
+	__backtrace();
+#endif
+out:
+	spin_unlock_irqrestore(&irq_controller_lock, flags);
+}
+
+/* Start the interrupt probing.  Unlike other architectures,
+ * we don't return a mask of interrupts from probe_irq_on,
+ * but return the number of interrupts enabled for the probe.
+ * The interrupts which have been enabled for probing is
+ * instead recorded in the irq_desc structure.
+ */
+unsigned long probe_irq_on(void)
+{
+	unsigned int i, irqs = 0;
+	unsigned long delay;
+
+	/*
+	 * first snaffle up any unassigned but
+	 * probe-able interrupts
+	 */
+	spin_lock_irq(&irq_controller_lock);
+	for (i = 0; i < NR_IRQS; i++) {
+		if (!irq_desc[i].valid ||
+		    !irq_desc[i].probe_ok ||
+		    irq_desc[i].action)
+			continue;
+
+		irq_desc[i].probing = 1;
+		irq_desc[i].triggered = 0;
+		irq_desc[i].unmask(i);
+		irqs += 1;
+	}
+	spin_unlock_irq(&irq_controller_lock);
+
+	/*
+	 * wait for spurious interrupts to mask themselves out again
+	 */
+	for (delay = jiffies + HZ/10; time_before(jiffies, delay); )
+		/* min 100ms delay */;
+
+	/*
+	 * now filter out any obviously spurious interrupts
+	 */
+	spin_lock_irq(&irq_controller_lock);
+	for (i = 0; i < NR_IRQS; i++) {
+		if (irq_desc[i].probing &&
+		    irq_desc[i].triggered) {
+			irq_desc[i].probing = 0;
+			irqs -= 1;
+		}
+	}
+	spin_unlock_irq(&irq_controller_lock);
+
+	/* now filter out any obviously spurious interrupts */
+	return irqs;
+}
+
+/*
+ * Possible return values:
+ *  >= 0 - interrupt number
+ *    -1 - no interrupt/many interrupts
+ */
+int probe_irq_off(unsigned long irqs)
+{
+	unsigned int i;
+	int irq_found = NO_IRQ;
+
+	/*
+	 * look at the interrupts, and find exactly one
+	 * that we were probing has been triggered
+	 */
+	spin_lock_irq(&irq_controller_lock);
+	for (i = 0; i < NR_IRQS; i++) {
+		if (irq_desc[i].probing &&
+		    irq_desc[i].triggered) {
+			if (irq_found != NO_IRQ) {
+				irq_found = NO_IRQ;
+				goto out;
+			}
+			irq_found = i;
+		}
+	}
+
+	if (irq_found == -1)
+		irq_found = NO_IRQ;
+out:
+	spin_unlock_irq(&irq_controller_lock);
+
+	return irq_found;
+}
+
+void __init init_irq_proc(void)
+{
+}
+
+void __init init_IRQ(void)
+{
+	extern void init_dma(void);
+	int irq;
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		irq_desc[irq].probe_ok = 0;
+		irq_desc[irq].valid    = 0;
+		irq_desc[irq].noautoenable = 0;
+		irq_desc[irq].mask_ack = dummy_mask_unmask_irq;
+		irq_desc[irq].mask     = dummy_mask_unmask_irq;
+		irq_desc[irq].unmask   = dummy_mask_unmask_irq;
+	}
+
+	init_arch_irq();
+	init_dma();
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/isa.c linux-2.4.29-uc1/arch/armnommu/kernel/isa.c
--- linux-2.4.29/arch/armnommu/kernel/isa.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/isa.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,53 @@
+/*
+ *  linux/arch/arm/kernel/isa.c
+ *
+ *  Copyright (C) 1999 Phil Blundell
+ *
+ *  ISA shared memory and I/O port support
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/* 
+ * Nothing about this is actually ARM specific.  One day we could move
+ * it into kernel/resource.c or some place like that.  
+ */
+
+#include <linux/stddef.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/sysctl.h>
+#include <linux/init.h>
+
+static unsigned int isa_membase, isa_portbase, isa_portshift;
+
+static ctl_table ctl_isa_vars[4] = {
+	{BUS_ISA_MEM_BASE, "membase", &isa_membase, 
+	 sizeof(isa_membase), 0444, NULL, &proc_dointvec},
+	{BUS_ISA_PORT_BASE, "portbase", &isa_portbase, 
+	 sizeof(isa_portbase), 0444, NULL, &proc_dointvec},
+	{BUS_ISA_PORT_SHIFT, "portshift", &isa_portshift, 
+	 sizeof(isa_portshift), 0444, NULL, &proc_dointvec},
+	{0}
+};
+
+static struct ctl_table_header *isa_sysctl_header;
+
+static ctl_table ctl_isa[2] = {{BUS_ISA, "isa", NULL, 0, 0555, ctl_isa_vars},
+			       {0}};
+static ctl_table ctl_bus[2] = {{CTL_BUS, "bus", NULL, 0, 0555, ctl_isa},
+			       {0}};
+
+void __init
+register_isa_ports(unsigned int membase, unsigned int portbase, unsigned int portshift)
+{
+	isa_membase = membase;
+	isa_portbase = portbase;
+	isa_portshift = portshift;
+	isa_sysctl_header = register_sysctl_table(ctl_bus, 0);
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/leds-ftvpci.c linux-2.4.29-uc1/arch/armnommu/kernel/leds-ftvpci.c
--- linux-2.4.29/arch/armnommu/kernel/leds-ftvpci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/leds-ftvpci.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,31 @@
+/*
+ *  linux/arch/arm/kernel/leds-ftvpci.c
+ *
+ *  Copyright (C) 1999 FutureTV Labs Ltd
+ */
+
+#include <linux/module.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+static void ftvpci_leds_event(led_event_t ledevt)
+{
+	static int led_state = 0;
+
+	switch(ledevt) {
+	case led_timer:
+		led_state ^= 1;
+		raw_writeb(0x1a | led_state, INTCONT_BASE);
+		break;
+
+	default:
+		break;
+	}
+}
+
+void (*leds_event)(led_event_t) = ftvpci_leds_event;
+
+EXPORT_SYMBOL(leds_event);
diff -urN linux-2.4.29/arch/armnommu/kernel/Makefile linux-2.4.29-uc1/arch/armnommu/kernel/Makefile
--- linux-2.4.29/arch/armnommu/kernel/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/Makefile	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,92 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+HEAD_OBJ  = head-$(PROCESSOR).o
+ENTRY_OBJ = entry-$(PROCESSOR).o
+
+ifeq ($(CONFIG_ARCH_NETARM),y)
+HEAD_OBJ  = head-arm-netarm.o
+AFLAGS_head-arm-netarm.o = -DTEXTADDR=$(TEXTADDR)
+endif
+
+ifeq ($(CONFIG_ARCH_DSC21),y)
+HEAD_OBJ  = head-arm-dsc21.o
+AFLAGS_head-arm-dsc21.o = -DTEXTADDR=$(TEXTADDR)
+endif
+
+ifeq ($(CONFIG_ARCH_IPOD),y)
+HEAD_OBJ  = head-arm-ipod.o
+AFLAGS_head-arm-ipod.o = -DTEXTADDR=$(TEXTADDR)
+endif
+
+ifeq ($(CONFIG_ARCH_VC547X), y)
+HEAD_OBJ  = head-arm-vc547x.o
+endif
+
+AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR)
+AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR)
+
+# This is depreciated.
+O_OBJS_arc        = dma-arc.o oldlatches.o
+O_OBJS_rpc        = dma-rpc.o
+O_OBJS_footbridge = dma-footbridge.o isa.o
+O_OBJS_l7200      = fiq.o
+
+pci-ftvpci	  = plx90x0.o
+pci-footbridge	  = dec21285.o
+pci-shark	  = via82c505.o
+
+# this is here to allow us to eventually move it out to mach-ftvpci
+pci-$(CONFIG_ARCH_FTVPCI) += ftv-pci.o
+
+
+O_TARGET := kernel.o
+
+# Object file lists.
+
+obj-y		:= arch.o compat.o dma.o $(ENTRY_OBJ) entry-common.o irq.o   \
+		   process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
+		   time.o traps.o $(O_OBJS_$(MACHINE))
+obj-m		:=
+obj-n		:=
+obj-		:=
+
+export-objs	:= armksyms.o dma.o ecard.o fiq.o io.o oldlatches.o time.o
+
+no-irq-arch	:= $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) \
+		   $(CONFIG_ARCH_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \
+		   $(CONFIG_ARCH_SA1100) $(CONFIG_ARCH_IPOD)
+
+ifneq ($(findstring y,$(no-irq-arch)),y)
+  obj-y		+= irq-arch.o
+endif
+
+obj-$(CONFIG_ARCH_ACORN) += ecard.o fiq.o time-acorn.o
+obj-$(CONFIG_ARCH_CLPS7500) += time-acorn.o
+obj-$(CONFIG_DEBUG_LL)	+= debug-$(PROCESSOR).o
+obj-$(CONFIG_MODULES)	+= armksyms.o
+obj-$(CONFIG_ARTHUR)	+= arthur.o
+obj-$(CONFIG_ISA_DMA)	+= dma-isa.o
+obj-$(CONFIG_PCI)	+= bios32.o $(pci-$(MACHINE)) $(pci-y)
+obj-$(CONFIG_ATMEL_DEBUG)	+= debug.o
+
+ifneq ($(MACHINE),ebsa110)
+  obj-y		+= io.o
+endif
+
+all: kernel.o $(HEAD_OBJ) init_task.o
+
+include $(TOPDIR)/Rules.make
+
+# Spell out some dependencies that `make dep' doesn't spot
+entry-armv.o: entry-header.S $(TOPDIR)/include/asm/constants.h
+entry-armo.o: entry-header.S $(TOPDIR)/include/asm/constants.h
+entry-common.o: entry-header.S calls.S $(TOPDIR)/include/asm/constants.h
+head-arm-netarm.o: head-arm-netarm.S $(TOPDIR)/include/asm/constants.h
+
diff -urN linux-2.4.29/arch/armnommu/kernel/oldlatches.c linux-2.4.29-uc1/arch/armnommu/kernel/oldlatches.c
--- linux-2.4.29/arch/armnommu/kernel/oldlatches.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/oldlatches.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,66 @@
+/*
+ *  linux/arch/arm/kernel/oldlatches.c
+ *
+ *  Copyright (C) David Alan Gilbert 1995/1996,2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Support for the latches on the old Archimedes which control the floppy,
+ *  hard disc and printer
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/arch/oldlatches.h>
+
+static unsigned char latch_a_copy;
+static unsigned char latch_b_copy;
+
+/* newval=(oldval & ~mask)|newdata */
+void oldlatch_aupdate(unsigned char mask,unsigned char newdata)
+{
+	if (machine_is_archimedes()) {
+		latch_a_copy = (latch_a_copy & ~mask) | newdata;
+
+		printk("Latch: A = 0x%02x\n", latch_a_copy);
+
+		__raw_writeb(latch_a_copy, LATCHA_BASE);
+	} else
+		BUG();
+}
+
+
+/* newval=(oldval & ~mask)|newdata */
+void oldlatch_bupdate(unsigned char mask,unsigned char newdata)
+{
+	if (machine_is_archimedes()) {
+		latch_b_copy = (latch_b_copy & ~mask) | newdata;
+
+		printk("Latch: B = 0x%02x\n", latch_b_copy);
+
+		__raw_writeb(latch_b_copy, LATCHB_BASE);
+	} else
+		BUG();
+}
+
+static int __init oldlatch_init(void)
+{
+	if (machine_is_archimedes()) {
+		oldlatch_aupdate(0xff, 0xff);
+		/* Thats no FDC reset...*/
+		oldlatch_bupdate(0xff, LATCHB_FDCRESET);
+	}
+	return 0;
+}
+
+__initcall(oldlatch_init);
+
+EXPORT_SYMBOL(oldlatch_aupdate);
+EXPORT_SYMBOL(oldlatch_bupdate);
diff -urN linux-2.4.29/arch/armnommu/kernel/plx90x0.c linux-2.4.29-uc1/arch/armnommu/kernel/plx90x0.c
--- linux-2.4.29/arch/armnommu/kernel/plx90x0.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/plx90x0.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,198 @@
+/* 
+ * Driver for PLX Technology PCI9000-series host bridge.
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000 FutureTV Labs Ltd
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/ptrace.h>
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+
+/*
+ * Since the following functions are all very similar, the common parts
+ * are pulled out into these macros.
+ */
+
+#define PLX_CLEAR_CONFIG						\
+	__raw_writel(0, PLX_BASE + 0xac);				\
+	local_irq_restore(flags); }
+
+#define PLX_SET_CONFIG							\
+	{ unsigned long flags;						\
+	local_irq_save(flags);						\
+	__raw_writel((1<<31 | (dev->bus->number << 16)			\
+		| (dev->devfn << 8) | (where & ~3)			\
+		| ((dev->bus->number == 0)?0:1)), PLX_BASE + 0xac);	\
+
+#define PLX_CONFIG_WRITE(size)						\
+	PLX_SET_CONFIG							\
+	__raw_write##size(value, PCIO_BASE + (where & 3));		\
+	if (__raw_readw(PLX_BASE + 0x6) & 0x2000)			\
+		__raw_writew(0x2000, PLX_BASE + 0x6);			\
+	PLX_CLEAR_CONFIG						\
+	return PCIBIOS_SUCCESSFUL;
+
+#define PLX_CONFIG_READ(size)						\
+	PLX_SET_CONFIG							\
+	*value = __raw_read##size(PCIO_BASE + (where & 3));		\
+	if (__raw_readw(PLX_BASE + 0x6) & 0x2000) {			\
+		__raw_writew(0x2000, PLX_BASE + 0x6);			\
+		*value = 0xffffffffUL;					\
+	}								\
+	PLX_CLEAR_CONFIG						\
+	return PCIBIOS_SUCCESSFUL;
+
+/* Configuration space access routines */
+
+static int
+plx90x0_read_config_byte (struct pci_dev *dev,
+			  int where, u8 *value)
+{
+	PLX_CONFIG_READ(b)
+}
+
+static int
+plx90x0_read_config_word (struct pci_dev *dev,
+			  int where, u16 *value)
+{
+	PLX_CONFIG_READ(w)
+}
+
+static int 
+plx90x0_read_config_dword (struct pci_dev *dev,
+			   int where, u32 *value)
+{
+	PLX_CONFIG_READ(l)
+}
+
+static int 
+plx90x0_write_config_byte (struct pci_dev *dev,
+			   int where, u8 value)
+{
+	PLX_CONFIG_WRITE(b)
+}
+
+static int 
+plx90x0_write_config_word (struct pci_dev *dev,
+			   int where, u16 value)
+{
+	PLX_CONFIG_WRITE(w)
+}
+
+static int 
+plx90x0_write_config_dword (struct pci_dev *dev,
+			    int where, u32 value)
+{
+	PLX_CONFIG_WRITE(l)
+}
+
+static void 
+plx_syserr_handler(int irq, void *handle, struct pt_regs *regs)
+{
+	printk("PLX90x0: machine check %04x (pc=%08lx)\n", 
+	       readw(PLX_BASE + 6), regs->ARM_pc);
+	__raw_writew(0xf000, PLX_BASE + 6);
+}
+
+static struct pci_ops 
+plx90x0_ops = 
+{
+	plx90x0_read_config_byte,
+	plx90x0_read_config_word,
+	plx90x0_read_config_dword,
+	plx90x0_write_config_byte,
+	plx90x0_write_config_word,
+	plx90x0_write_config_dword,
+};
+
+/*
+ * Initialise the PCI system.
+ */
+
+void __init
+plx90x0_init(struct arm_sysdata *sysdata)
+{
+	static const unsigned long int base = PLX_BASE;
+	char *what;
+	unsigned long bar = (unsigned long)virt_to_bus((void *)PAGE_OFFSET);
+	unsigned int pci_cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+				PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
+
+	/* Have a sniff around and see which PLX device is present. */
+	unsigned long id = __raw_readl(base + 0xf0);
+	
+#if 0
+	/* This check was a good idea, but can fail.  The PLX9060 puts no
+	   default value in these registers unless NB# is asserted (which it
+	   isn't on these cards).  */
+	if ((id & 0xffff) != PCI_VENDOR_ID_PLX)
+		return;		/* Nothing found */
+#endif
+
+	/* Found one - now work out what it is. */
+	switch (id >> 16) {
+	case 0:		/* PCI_DEVICE_ID_PLX_9060 */
+		what = "PCI9060";
+		break;
+	case PCI_DEVICE_ID_PLX_9060ES:
+		what = "PCI9060ES";
+		break;
+	case PCI_DEVICE_ID_PLX_9060SD:
+		what = "PCI9060SD";		/* uhuhh.. */
+		break;
+	case PCI_DEVICE_ID_PLX_9080:
+		what = "PCI9080";
+		break;
+	default:
+		printk("PCI: Unknown PLX device %04lx found -- ignored.\n",
+		       id >> 16);
+		return;
+	}
+	
+	printk("PCI: PLX Technology %s host bridge found.\n", what);
+	
+	/* Now set it up for both master and slave accesses. */
+	__raw_writel(0xffff0147,	base + 0x4);
+	__raw_writeb(32,		base + 0xd);
+	__raw_writel(0x8 | bar,		base + 0x18);
+	__raw_writel(0xf8000008,	base + 0x80);
+	__raw_writel(0x40000001,	base + 0x84);
+	__raw_writel(0,			base + 0x88);
+	__raw_writel(0,			base + 0x8c);
+	__raw_writel(0x11,		base + 0x94);
+	__raw_writel(0xC3 + (4 << 28)
+		+ (8 << 11) + (1 << 10)
+		     + (1 << 24),	base + 0x98);
+	__raw_writel(0xC0000000,	base + 0x9c);
+	__raw_writel(PLX_MEM_START,	base + 0xa0);
+	__raw_writel(PLX_IO_START,	base + 0xa4);
+	__raw_writel(0x3,		base + 0xa8);
+	__raw_writel(0,			base + 0xac);
+	__raw_writel(0x10001,		base + 0xe8);
+	__raw_writel(0x8000767e,	base + 0xec);
+	
+	request_irq(IRQ_SYSERR, plx_syserr_handler, 0, 
+		    "system error", NULL);
+
+	pci_scan_bus(0, &plx90x0_ops, sysdata);
+
+	pci_cmd |= sysdata->bus[0].features;
+
+	printk("PCI: Fast back to back transfers %sabled\n",
+	       (sysdata->bus[0].features & PCI_COMMAND_FAST_BACK) ?
+	       "en" : "dis");
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/process.c linux-2.4.29-uc1/arch/armnommu/kernel/process.c
--- linux-2.4.29/arch/armnommu/kernel/process.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/process.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,433 @@
+/*
+ *  linux/arch/arm/kernel/process.c
+ *
+ *  Copyright (C) 1996-2000 Russell King - Converted to ARM.
+ *  Origional Copyright (C) 1995  Linus Torvalds
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <stdarg.h>
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/uaccess.h>
+
+/*
+ * Values for cpu_do_idle()
+ */
+#define IDLE_WAIT_SLOW	0
+#define IDLE_WAIT_FAST	1
+#define IDLE_CLOCK_SLOW	2
+#define IDLE_CLOCK_FAST	3
+
+extern const char *processor_modes[];
+extern void setup_mm_for_reboot(char mode);
+
+static volatile int hlt_counter;
+
+#include <asm/arch/system.h>
+
+void disable_hlt(void)
+{
+	hlt_counter++;
+}
+
+void enable_hlt(void)
+{
+	hlt_counter--;
+}
+
+static int __init nohlt_setup(char *__unused)
+{
+	hlt_counter = 1;
+	return 1;
+}
+
+static int __init hlt_setup(char *__unused)
+{
+	hlt_counter = 0;
+	return 1;
+}
+
+__setup("nohlt", nohlt_setup);
+__setup("hlt", hlt_setup);
+
+/*
+ * The following aren't currently used.
+ */
+void (*pm_idle)(void);
+void (*pm_power_off)(void);
+
+/*
+ * The idle thread.  We try to conserve power, while trying to keep
+ * overall latency low.  The architecture specific idle is passed
+ * a value to indicate the level of "idleness" of the system.
+ */
+void cpu_idle(void)
+{
+	/* endless idle loop with no priority at all */
+	init_idle();
+	current->nice = 20;
+	current->counter = -100;
+ 
+	while (1) {
+		void (*idle)(void) = pm_idle;
+		if (!idle)
+			idle = arch_idle;
+		leds_event(led_idle_start);
+		while (!current->need_resched)
+			idle();
+		leds_event(led_idle_end);
+		schedule();
+#ifndef CONFIG_NO_PGT_CACHE
+		check_pgt_cache();
+#endif
+	}
+}
+
+static char reboot_mode = 'h';
+
+int __init reboot_setup(char *str)
+{
+	reboot_mode = str[0];
+	return 1;
+}
+
+__setup("reboot=", reboot_setup);
+
+void machine_halt(void)
+{
+	leds_event(led_halted);
+}
+
+void machine_power_off(void)
+{
+	leds_event(led_halted);
+	if (pm_power_off)
+		pm_power_off();
+}
+
+void machine_restart(char * __unused)
+{
+	/*
+	 * Clean and disable cache, and turn off interrupts
+	 */
+	cpu_proc_fin();
+
+	/*
+	 * Tell the mm system that we are going to reboot -
+	 * we may need it to insert some 1:1 mappings so that
+	 * soft boot works.
+	 */
+	setup_mm_for_reboot(reboot_mode);
+
+	/*
+	 * Now call the architecture specific reboot code.
+	 */
+	arch_reset(reboot_mode);
+
+	/*
+	 * Whoops - the architecture was unable to reboot.
+	 * Tell the user!
+	 */
+	mdelay(1000);
+	printk("Reboot failed -- System halted\n");
+	while (1);
+}
+
+void show_regs(struct pt_regs * regs)
+{
+	unsigned long flags;
+
+	flags = condition_codes(regs);
+
+	printk("pc : [<%08lx>]    lr : [<%08lx>]    %s\n"
+	       "sp : %08lx  ip : %08lx  fp : %08lx\n",
+		instruction_pointer(regs),
+		regs->ARM_lr, print_tainted(), regs->ARM_sp,
+		regs->ARM_ip, regs->ARM_fp);
+	printk("r10: %08lx  r9 : %08lx  r8 : %08lx\n",
+		regs->ARM_r10, regs->ARM_r9,
+		regs->ARM_r8);
+	printk("r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
+		regs->ARM_r7, regs->ARM_r6,
+		regs->ARM_r5, regs->ARM_r4);
+	printk("r3 : %08lx  r2 : %08lx  r1 : %08lx  r0 : %08lx\n",
+		regs->ARM_r3, regs->ARM_r2,
+		regs->ARM_r1, regs->ARM_r0);
+	printk("Flags: %c%c%c%c",
+		flags & CC_N_BIT ? 'N' : 'n',
+		flags & CC_Z_BIT ? 'Z' : 'z',
+		flags & CC_C_BIT ? 'C' : 'c',
+		flags & CC_V_BIT ? 'V' : 'v');
+	printk("  IRQs %s  FIQs %s  Mode %s%s  Segment %s\n",
+		interrupts_enabled(regs) ? "on" : "off",
+		fast_interrupts_enabled(regs) ? "on" : "off",
+		processor_modes[processor_mode(regs)],
+		thumb_mode(regs) ? " (T)" : "",
+		get_fs() == get_ds() ? "kernel" : "user");
+/* We are interested only if we have cache related or CPU Control info */
+#if defined(CONFIG_CPU_32)
+	{
+		int ctrl, transbase, dac;
+		  __asm__ (
+#ifdef CONFIG_CPU_WITH_MCR_INSTRUCTION				  
+		"	mrc p15, 0, %0, c1, c0\n"
+#else
+# warning		"FIXME: Get CPU control info if any without MCR Instruction"
+		"	mov %0, #0 @ Dummy for now\n"
+#endif
+#ifndef NO_MM
+		"	mrc p15, 0, %1, c2, c0\n"
+		"	mrc p15, 0, %2, c3, c0\n"
+		: "=r" (ctrl), "=r" (transbase), "=r" (dac));
+		printk("Control: %04X  Table: %08X  DAC: %08X\n",
+		  	ctrl, transbase, dac);
+#else
+		: "=r" (ctrl));
+		printk("Control: %X\n", ctrl);
+#endif		
+	}
+#endif
+}
+
+void show_fpregs(struct user_fp *regs)
+{
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		unsigned long *p;
+		char type;
+
+		p = (unsigned long *)(regs->fpregs + i);
+
+		switch (regs->ftype[i]) {
+			case 1: type = 'f'; break;
+			case 2: type = 'd'; break;
+			case 3: type = 'e'; break;
+			default: type = '?'; break;
+		}
+		if (regs->init_flag)
+			type = '?';
+
+		printk("  f%d(%c): %08lx %08lx %08lx%c",
+			i, type, p[0], p[1], p[2], i & 1 ? '\n' : ' ');
+	}
+			
+
+	printk("FPSR: %08lx FPCR: %08lx\n",
+		(unsigned long)regs->fpsr,
+		(unsigned long)regs->fpcr);
+}
+
+/*
+ * Task structure and kernel stack allocation.
+ */
+static struct task_struct *task_struct_head;
+static unsigned int nr_task_struct;
+
+#ifdef CONFIG_CPU_32
+#define EXTRA_TASK_STRUCT	4
+#else
+#define EXTRA_TASK_STRUCT	0
+#endif
+
+struct task_struct *alloc_task_struct(void)
+{
+	struct task_struct *tsk;
+
+	if (EXTRA_TASK_STRUCT)
+		tsk = task_struct_head;
+	else
+		tsk = NULL;
+
+	if (tsk) {
+		task_struct_head = tsk->next_task;
+		nr_task_struct -= 1;
+	} else
+		tsk = ll_alloc_task_struct();
+
+#ifdef CONFIG_SYSRQ
+	/*
+	 * The stack must be cleared if you want SYSRQ-T to
+	 * give sensible stack usage information
+	 */
+	if (tsk) {
+		char *p = (char *)tsk;
+		memzero(p+KERNEL_STACK_SIZE, KERNEL_STACK_SIZE);
+	}
+#endif
+	return tsk;
+}
+
+void __free_task_struct(struct task_struct *p)
+{
+	if (EXTRA_TASK_STRUCT && nr_task_struct < EXTRA_TASK_STRUCT) {
+		p->next_task = task_struct_head;
+		task_struct_head = p;
+		nr_task_struct += 1;
+	} else
+		ll_free_task_struct(p);
+}
+
+/*
+ * Free current thread data structures etc..
+ */
+void exit_thread(void)
+{
+}
+
+void flush_thread(void)
+{
+	memset(&current->thread.debug, 0, sizeof(struct debug_info));
+	memset(&current->thread.fpstate, 0, sizeof(union fp_state));
+	current->used_math = 0;
+	current->flags &= ~PF_USEDFPU;
+}
+
+void release_thread(struct task_struct *dead_task)
+{
+}
+
+asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+
+int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
+	unsigned long unused,
+	struct task_struct * p, struct pt_regs * regs)
+{
+	struct pt_regs * childregs;
+	struct context_save_struct * save;
+
+	atomic_set(&p->thread.refcount, 1);
+
+	childregs = ((struct pt_regs *)((unsigned long)p + 8192)) - 1;
+	*childregs = *regs;
+	childregs->ARM_r0 = 0;
+#ifdef NO_MM
+	if (esp) childregs->ARM_sp = esp;
+#else
+	childregs->ARM_sp = esp;
+#endif
+	save = ((struct context_save_struct *)(childregs)) - 1;
+	*save = INIT_CSS;
+	save->pc |= (unsigned long)ret_from_fork;
+
+	p->thread.save = save;
+
+	return 0;
+}
+
+/*
+ * fill in the fpe structure for a core dump...
+ */
+int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
+{
+	if (current->used_math)
+		memcpy(fp, &current->thread.fpstate.soft, sizeof (*fp));
+
+	return current->used_math;
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs * regs, struct user * dump)
+{
+	struct task_struct *tsk = current;
+
+	dump->magic = CMAGIC;
+	dump->start_code = tsk->mm->start_code;
+	dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1);
+
+	dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT;
+	dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	dump->u_ssize = 0;
+
+	dump->u_debugreg[0] = tsk->thread.debug.bp[0].address;
+	dump->u_debugreg[1] = tsk->thread.debug.bp[1].address;
+	dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn;
+	dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn;
+	dump->u_debugreg[4] = tsk->thread.debug.nsaved;
+
+	if (dump->start_stack < 0x04000000)
+		dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT;
+
+	dump->regs = *regs;
+	dump->u_fpvalid = dump_fpu (regs, &dump->u_fp);
+}
+
+/*
+ * This is the mechanism for creating a new kernel thread.
+ *
+ * NOTE! Only a kernel-only process(ie the swapper or direct descendants
+ * who haven't done an "execve()") should use this: it will work within
+ * a system call from a "real" process, but the process memory space will
+ * not be free'd until both the parent and the child have exited.
+ */
+pid_t arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+{
+	pid_t __ret;
+
+	__asm__ __volatile__(					   
+	"orr	r0, %1, %2	@ kernel_thread sys_clone	   \n\
+	mov	r1, #0						   \n\
+	"__syscall(clone)"					   \n\
+	movs	%0, r0		@ if we are the child		   \n\
+	bne	1f						   \n\
+	mov	fp, #0		@ ensure that fp is zero	   \n\
+	mov	r0, %4						   \n\
+	mov	lr, pc						   \n\
+	mov	pc, %3						   \n\
+	b	sys_exit					   \n\
+1:	"							   
+        : "=r" (__ret)						   
+        : "Ir" (flags), "I" (CLONE_VM), "r" (fn), "r" (arg)	   
+	: "r0", "r1", "lr");
+	return __ret;
+}
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+#define first_sched	((unsigned long) scheduling_functions_start_here)
+#define last_sched	((unsigned long) scheduling_functions_end_here)
+
+unsigned long get_wchan(struct task_struct *p)
+{
+	unsigned long fp, lr;
+	unsigned long stack_page;
+	int count = 0;
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	stack_page = 4096 + (unsigned long)p;
+	fp = get_css_fp(&p->thread);
+	do {
+		if (fp < stack_page || fp > 4092+stack_page)
+			return 0;
+		lr = pc_pointer (((unsigned long *)fp)[-1]);
+		if (lr < first_sched || lr > last_sched)
+			return lr;
+		fp = *(unsigned long *) (fp - 12);
+	} while (count ++ < 16);
+	return 0;
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/ptrace.c linux-2.4.29-uc1/arch/armnommu/kernel/ptrace.c
--- linux-2.4.29/arch/armnommu/kernel/ptrace.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/ptrace.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,714 @@
+/*
+ *  linux/arch/arm/kernel/ptrace.c
+ *
+ *  By Ross Biro 1/23/92
+ * edited by Linus Torvalds
+ * ARM modifications Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+
+#include "ptrace.h"
+
+#define REG_PC	15
+#define REG_PSR	16
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/*
+ * Breakpoint SWI instruction: SWI &9F0001
+ */
+#define BREAKINST_ARM	0xef9f0001
+/* fill this in later */
+#define BREAKINST_THUMB	0xdf00
+
+/*
+ * Get the address of the live pt_regs for the specified task.
+ * These are saved onto the top kernel stack when the process
+ * is not running.
+ */
+static inline struct pt_regs *
+get_user_regs(struct task_struct *task)
+{
+	return (struct pt_regs *)
+		((unsigned long)task + 8192 - sizeof(struct pt_regs));
+}
+
+/*
+ * this routine will get a word off of the processes privileged stack.
+ * the offset is how far from the base addr as stored in the THREAD.
+ * this routine assumes that all the privileged stacks are in our
+ * data space.
+ */
+static inline long get_stack_long(struct task_struct *task, int offset)
+{
+	return get_user_regs(task)->uregs[offset];
+}
+
+/*
+ * this routine will put a word on the processes privileged stack.
+ * the offset is how far from the base addr as stored in the THREAD.
+ * this routine assumes that all the privileged stacks are in our
+ * data space.
+ */
+static inline int
+put_stack_long(struct task_struct *task, int offset, long data)
+{
+	struct pt_regs newregs, *regs = get_user_regs(task);
+	int ret = -EINVAL;
+
+	newregs = *regs;
+	newregs.uregs[offset] = data;
+	
+	if (valid_user_regs(&newregs)) {
+		regs->uregs[offset] = data;
+		ret = 0;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_ARM_THUMB
+static inline int
+read_tsk16(struct task_struct *child, unsigned long addr, unsigned short *res)
+{
+	int copied;
+
+	copied = access_process_vm(child, addr, res, sizeof(*res), 0);
+
+	return copied != sizeof(*res) ? -EIO : 0;
+}
+
+static inline int
+write_tsk16(struct task_struct *child, unsigned long addr, unsigned short val)
+{
+	int copied;
+
+	copied = access_process_vm(child, addr, &val, sizeof(val), 1);
+
+	return copied != sizeof(val) ? -EIO : 0;
+}
+
+static int
+add_breakpoint_thumb(struct task_struct *child, struct debug_info *dbg, u32 addr)
+{
+	int nr = dbg->nsaved;
+	int res = -EINVAL;
+
+	if (nr < 2) {
+		u16 insn;
+
+		res = read_tsk16(child, addr, &insn);
+		if (res == 0)
+			res = write_tsk16(child, addr, BREAK_THUMB);
+
+		if (res == 0) {
+			dbg->bp[nr].address = addr;
+			dbg->bp[nr].insn = insn;
+			dbg->nsaved += 1;
+		}
+	} else
+		printk(KERN_ERR "ptrace: too many breakpoints\n");
+
+	return res;
+}
+#endif
+
+static inline int
+read_tsk_long(struct task_struct *child, unsigned long addr, unsigned long *res)
+{
+	int copied;
+
+	copied = access_process_vm(child, addr, res, sizeof(*res), 0);
+
+	return copied != sizeof(*res) ? -EIO : 0;
+}
+
+static inline int
+write_tsk_long(struct task_struct *child, unsigned long addr, unsigned long val)
+{
+	int copied;
+
+	copied = access_process_vm(child, addr, &val, sizeof(val), 1);
+
+	return copied != sizeof(val) ? -EIO : 0;
+}
+
+/*
+ * Get value of register `rn' (in the instruction)
+ */
+static unsigned long
+ptrace_getrn(struct task_struct *child, unsigned long insn)
+{
+	unsigned int reg = (insn >> 16) & 15;
+	unsigned long val;
+
+	val = get_stack_long(child, reg);
+	if (reg == 15)
+		val = pc_pointer(val + 8);
+
+	return val;
+}
+
+/*
+ * Get value of operand 2 (in an ALU instruction)
+ */
+static unsigned long
+ptrace_getaluop2(struct task_struct *child, unsigned long insn)
+{
+	unsigned long val;
+	int shift;
+	int type;
+
+	if (insn & 1 << 25) {
+		val = insn & 255;
+		shift = (insn >> 8) & 15;
+		type = 3;
+	} else {
+		val = get_stack_long (child, insn & 15);
+
+		if (insn & (1 << 4))
+			shift = (int)get_stack_long (child, (insn >> 8) & 15);
+		else
+			shift = (insn >> 7) & 31;
+
+		type = (insn >> 5) & 3;
+	}
+
+	switch (type) {
+	case 0:	val <<= shift;	break;
+	case 1:	val >>= shift;	break;
+	case 2:
+		val = (((signed long)val) >> shift);
+		break;
+	case 3:
+ 		val = (val >> shift) | (val << (32 - shift));
+		break;
+	}
+	return val;
+}
+
+/*
+ * Get value of operand 2 (in a LDR instruction)
+ */
+static unsigned long
+ptrace_getldrop2(struct task_struct *child, unsigned long insn)
+{
+	unsigned long val;
+	int shift;
+	int type;
+
+	val = get_stack_long(child, insn & 15);
+	shift = (insn >> 7) & 31;
+	type = (insn >> 5) & 3;
+
+	switch (type) {
+	case 0:	val <<= shift;	break;
+	case 1:	val >>= shift;	break;
+	case 2:
+		val = (((signed long)val) >> shift);
+		break;
+	case 3:
+ 		val = (val >> shift) | (val << (32 - shift));
+		break;
+	}
+	return val;
+}
+
+static unsigned long
+get_branch_address(struct task_struct *child, unsigned long pc, unsigned long insn)
+{
+	unsigned long alt = 0;
+
+	switch (insn & 0x0e000000) {
+	case 0x00000000:
+	case 0x02000000: {
+		/*
+		 * data processing
+		 */
+		long aluop1, aluop2, ccbit;
+
+		if ((insn & 0xf000) != 0xf000)
+			break;
+
+		aluop1 = ptrace_getrn(child, insn);
+		aluop2 = ptrace_getaluop2(child, insn);
+		ccbit  = get_stack_long(child, REG_PSR) & CC_C_BIT ? 1 : 0;
+
+		switch (insn & 0x01e00000) {
+		case 0x00000000: alt = aluop1 & aluop2;		break;
+		case 0x00200000: alt = aluop1 ^ aluop2;		break;
+		case 0x00400000: alt = aluop1 - aluop2;		break;
+		case 0x00600000: alt = aluop2 - aluop1;		break;
+		case 0x00800000: alt = aluop1 + aluop2;		break;
+		case 0x00a00000: alt = aluop1 + aluop2 + ccbit;	break;
+		case 0x00c00000: alt = aluop1 - aluop2 + ccbit;	break;
+		case 0x00e00000: alt = aluop2 - aluop1 + ccbit;	break;
+		case 0x01800000: alt = aluop1 | aluop2;		break;
+		case 0x01a00000: alt = aluop2;			break;
+		case 0x01c00000: alt = aluop1 & ~aluop2;	break;
+		case 0x01e00000: alt = ~aluop2;			break;
+		}
+		break;
+	}
+
+	case 0x04000000:
+	case 0x06000000:
+		/*
+		 * ldr
+		 */
+		if ((insn & 0x0010f000) == 0x0010f000) {
+			unsigned long base;
+
+			base = ptrace_getrn(child, insn);
+			if (insn & 1 << 24) {
+				long aluop2;
+
+				if (insn & 0x02000000)
+					aluop2 = ptrace_getldrop2(child, insn);
+				else
+					aluop2 = insn & 0xfff;
+
+				if (insn & 1 << 23)
+					base += aluop2;
+				else
+					base -= aluop2;
+			}
+			if (read_tsk_long(child, base, &alt) == 0)
+				alt = pc_pointer(alt);
+		}
+		break;
+
+	case 0x08000000:
+		/*
+		 * ldm
+		 */
+		if ((insn & 0x00108000) == 0x00108000) {
+			unsigned long base;
+			unsigned int nr_regs;
+
+			if (insn & (1 << 23)) {
+				nr_regs = insn & 65535;
+
+				nr_regs = (nr_regs & 0x5555) + ((nr_regs & 0xaaaa) >> 1);
+				nr_regs = (nr_regs & 0x3333) + ((nr_regs & 0xcccc) >> 2);
+				nr_regs = (nr_regs & 0x0707) + ((nr_regs & 0x7070) >> 4);
+				nr_regs = (nr_regs & 0x000f) + ((nr_regs & 0x0f00) >> 8);
+				nr_regs <<= 2;
+
+				if (!(insn & (1 << 24)))
+					nr_regs -= 4;
+			} else {
+				if (insn & (1 << 24))
+					nr_regs = -4;
+				else
+					nr_regs = 0;
+			}
+
+			base = ptrace_getrn(child, insn);
+
+			if (read_tsk_long(child, base + nr_regs, &alt) == 0)
+				alt = pc_pointer (alt);
+			break;
+		}
+		break;
+
+	case 0x0a000000: {
+		/*
+		 * bl or b
+		 */
+		signed long displ;
+		/* It's a branch/branch link: instead of trying to
+		 * figure out whether the branch will be taken or not,
+		 * we'll put a breakpoint at both locations.  This is
+		 * simpler, more reliable, and probably not a whole lot
+		 * slower than the alternative approach of emulating the
+		 * branch.
+		 */
+		displ = (insn & 0x00ffffff) << 8;
+		displ = (displ >> 6) + 8;
+		if (displ != 0 && displ != 4)
+			alt = pc + displ;
+	    }
+	    break;
+	}
+
+	return alt;
+}
+
+static int
+add_breakpoint_arm(struct task_struct *child, struct debug_info *dbg, unsigned long addr)
+{
+	int nr = dbg->nsaved;
+	int res = -EINVAL;
+
+	if (nr < 2) {
+		res = read_tsk_long(child, addr, &dbg->bp[nr].insn);
+		if (res == 0)
+			res = write_tsk_long(child, addr, BREAKINST_ARM);
+
+		if (res == 0) {
+			dbg->bp[nr].address = addr;
+			dbg->nsaved += 1;
+		}
+	} else
+		printk(KERN_ERR "ptrace: too many breakpoints\n");
+
+	return res;
+}
+
+int ptrace_set_bpt(struct task_struct *child)
+{
+	struct pt_regs *regs;
+	unsigned long pc, insn;
+	int res;
+
+	regs = get_user_regs(child);
+	pc = instruction_pointer(regs);
+
+	res = read_tsk_long(child, pc, &insn);
+	if (!res) {
+		struct debug_info *dbg = &child->thread.debug;
+		unsigned long alt;
+
+		dbg->nsaved = 0;
+
+		alt = get_branch_address(child, pc, insn);
+		if (alt)
+			res = add_breakpoint_arm(child, dbg, alt);
+
+		/*
+		 * Note that we ignore the result of setting the above
+		 * breakpoint since it may fail.  When it does, this is
+		 * not so much an error, but a forewarning that we may
+		 * be receiving a prefetch abort shortly.
+		 *
+		 * If we don't set this breakpoint here, then we can
+		 * loose control of the thread during single stepping.
+		 */
+		if (!alt || predicate(insn) != PREDICATE_ALWAYS)
+			res = add_breakpoint_arm(child, dbg, pc + 4);
+	}
+
+	return res;
+}
+
+/*
+ * Ensure no single-step breakpoint is pending.  Returns non-zero
+ * value if child was being single-stepped.
+ */
+void __ptrace_cancel_bpt(struct task_struct *child)
+{
+	struct debug_info *dbg = &child->thread.debug;
+	int i, nsaved = dbg->nsaved;
+
+	dbg->nsaved = 0;
+
+	if (nsaved > 2) {
+		printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
+		nsaved = 2;
+	}
+
+	for (i = 0; i < nsaved; i++) {
+		unsigned long tmp;
+
+		read_tsk_long(child, dbg->bp[i].address, &tmp);
+		write_tsk_long(child, dbg->bp[i].address, dbg->bp[i].insn);
+		if (tmp != BREAKINST_ARM)
+			printk(KERN_ERR "ptrace_cancel_bpt: weirdness\n");
+	}
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure the single step bit is not set.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+	__ptrace_cancel_bpt(child);
+}
+
+static int do_ptrace(int request, struct task_struct *child, long addr, long data)
+{
+	unsigned long tmp;
+	int ret;
+
+	switch (request) {
+		/*
+		 * read word at location "addr" in the child process.
+		 */
+		case PTRACE_PEEKTEXT:
+		case PTRACE_PEEKDATA:
+			ret = read_tsk_long(child, addr, &tmp);
+			if (!ret)
+				ret = put_user(tmp, (unsigned long *) data);
+			break;
+
+		/*
+		 * read the word at location "addr" in the user registers.
+		 */
+		case PTRACE_PEEKUSR:
+			ret = -EIO;
+			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
+				break;
+
+			tmp = 0;  /* Default return condition */
+			if (addr < sizeof(struct pt_regs)) {
+				tmp = get_stack_long(child, (int)addr >> 2);
+			} else if (addr == 4*49) {
+				tmp = child->mm->start_code;
+			} else if (addr == 4*50) {
+				tmp = child->mm->start_data;
+			} else if (addr == 4*51) {
+				tmp = child->mm->end_code;
+			} else if (addr == 4*52) {
+				tmp = child->mm->end_data;
+			}
+			ret = put_user(tmp, (unsigned long *)data);
+			break;
+
+		/*
+		 * write the word at location addr.
+		 */
+		case PTRACE_POKETEXT:
+		case PTRACE_POKEDATA:
+			ret = write_tsk_long(child, addr, data);
+			break;
+
+		/*
+		 * write the word at location addr in the user registers.
+		 */
+		case PTRACE_POKEUSR:
+			ret = -EIO;
+			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
+				break;
+
+			if (addr < sizeof(struct pt_regs))
+				ret = put_stack_long(child, (int)addr >> 2, data);
+			break;
+
+		/*
+		 * continue/restart and stop at next (return from) syscall
+		 */
+		case PTRACE_SYSCALL:
+		case PTRACE_CONT:
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				break;
+			if (request == PTRACE_SYSCALL)
+				child->ptrace |= PT_TRACESYS;
+			else
+				child->ptrace &= ~PT_TRACESYS;
+			child->exit_code = data;
+			/* make sure single-step breakpoint is gone. */
+			__ptrace_cancel_bpt(child);
+			wake_up_process(child);
+			ret = 0;
+			break;
+
+		/*
+		 * make the child exit.  Best I can do is send it a sigkill.
+		 * perhaps it should be put in the status that it wants to
+		 * exit.
+		 */
+		case PTRACE_KILL:
+			/* already dead */
+			ret = 0;
+			if (child->state == TASK_ZOMBIE)
+				break;
+			child->exit_code = SIGKILL;
+			/* make sure single-step breakpoint is gone. */
+			__ptrace_cancel_bpt(child);
+			wake_up_process(child);
+			ret = 0;
+			break;
+
+		/*
+		 * execute single instruction.
+		 */
+		case PTRACE_SINGLESTEP:
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				break;
+			child->thread.debug.nsaved = -1;
+			child->ptrace &= ~PT_TRACESYS;
+			child->exit_code = data;
+			/* give it a chance to run. */
+			wake_up_process(child);
+			ret = 0;
+			break;
+
+		/*
+		 * detach a process that was attached.
+		 */
+		case PTRACE_DETACH:
+			ret = ptrace_detach(child, data);
+			break;
+
+		/*
+		 * Get all gp regs from the child.
+		 */
+		case PTRACE_GETREGS: {
+			struct pt_regs *regs = get_user_regs(child);
+
+			ret = 0;
+			if (copy_to_user((void *)data, regs,
+					 sizeof(struct pt_regs)))
+				ret = -EFAULT;
+
+			break;
+		}
+
+		/*
+		 * Set all gp regs in the child.
+		 */
+		case PTRACE_SETREGS: {
+			struct pt_regs newregs;
+
+			ret = -EFAULT;
+			if (copy_from_user(&newregs, (void *)data,
+					   sizeof(struct pt_regs)) == 0) {
+				struct pt_regs *regs = get_user_regs(child);
+
+				ret = -EINVAL;
+				if (valid_user_regs(&newregs)) {
+					*regs = newregs;
+					ret = 0;
+				}
+			}
+			break;
+		}
+
+		/*
+		 * Get the child FPU state.
+		 */
+		case PTRACE_GETFPREGS:
+			ret = -EIO;
+			if (!access_ok(VERIFY_WRITE, (void *)data, sizeof(struct user_fp)))
+				break;
+
+			/* we should check child->used_math here */
+			ret = __copy_to_user((void *)data, &child->thread.fpstate,
+					     sizeof(struct user_fp)) ? -EFAULT : 0;
+			break;
+		
+		/*
+		 * Set the child FPU state.
+		 */
+		case PTRACE_SETFPREGS:
+			ret = -EIO;
+			if (!access_ok(VERIFY_READ, (void *)data, sizeof(struct user_fp)))
+				break;
+
+			child->used_math = 1;
+			ret = __copy_from_user(&child->thread.fpstate, (void *)data,
+					   sizeof(struct user_fp)) ? -EFAULT : 0;
+			break;
+
+		default:
+			ret = -EIO;
+			break;
+	}
+
+	return ret;
+}
+
+asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	int ret;
+
+	lock_kernel();
+	ret = -EPERM;
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED)
+			goto out;
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		ret = 0;
+		goto out;
+	}
+	ret = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		goto out;
+
+	ret = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out_tsk;
+
+	if (request == PTRACE_ATTACH) {
+		ret = ptrace_attach(child);
+		goto out_tsk;
+	}
+	ret = -ESRCH;
+	if (!(child->ptrace & PT_PTRACED))
+		goto out_tsk;
+	if (child->state != TASK_STOPPED && request != PTRACE_KILL)
+		goto out_tsk;
+	if (child->p_pptr != current)
+		goto out_tsk;
+
+	ret = do_ptrace(request, child, addr, data);
+
+out_tsk:
+	free_task_struct(child);
+out:
+	unlock_kernel();
+	return ret;
+}
+
+asmlinkage void syscall_trace(int why, struct pt_regs *regs)
+{
+	unsigned long ip;
+
+	if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
+			!= (PT_PTRACED|PT_TRACESYS))
+		return;
+
+	/*
+	 * Save IP.  IP is used to denote syscall entry/exit:
+	 *  IP = 0 -> entry, = 1 -> exit
+	 */
+	ip = regs->ARM_ip;
+	regs->ARM_ip = why;
+
+	/* the 0x80 provides a way for the tracing parent to distinguish
+	   between a syscall stop and SIGTRAP delivery */
+	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+					? 0x80 : 0);
+	current->state = TASK_STOPPED;
+	notify_parent(current, SIGCHLD);
+	schedule();
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+	regs->ARM_ip = ip;
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/ptrace.h linux-2.4.29-uc1/arch/armnommu/kernel/ptrace.h
--- linux-2.4.29/arch/armnommu/kernel/ptrace.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/ptrace.h	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ *  linux/arch/arm/kernel/ptrace.h
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+extern void __ptrace_cancel_bpt(struct task_struct *);
+extern int ptrace_set_bpt(struct task_struct *);
+
+/*
+ * Clear a breakpoint, if one exists.
+ */
+static inline int ptrace_cancel_bpt(struct task_struct *tsk)
+{
+	int nsaved = tsk->thread.debug.nsaved;
+
+	if (nsaved)
+		__ptrace_cancel_bpt(tsk);
+
+	return nsaved;
+}
+
diff -urN linux-2.4.29/arch/armnommu/kernel/semaphore.c linux-2.4.29-uc1/arch/armnommu/kernel/semaphore.c
--- linux-2.4.29/arch/armnommu/kernel/semaphore.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/semaphore.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,258 @@
+/*
+ *  ARM semaphore implementation, taken from
+ *
+ *  i386 semaphore implementation.
+ *
+ *  (C) Copyright 1999 Linus Torvalds
+ *
+ *  Modified for ARM by Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+
+#include <asm/semaphore.h>
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to acquire the semaphore, while the "sleeping"
+ * variable is a count of such acquires.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * "sleeping" and the contention routine ordering is
+ * protected by the semaphore spinlock.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+
+/*
+ * Logic:
+ *  - only on a boundary condition do we need to care. When we go
+ *    from a negative count to a non-negative, we wake people up.
+ *  - when we go from a non-negative count to a negative do we
+ *    (a) synchronize with the "sleeper" count and (b) make sure
+ *    that we're on the wakeup list before we synchronize so that
+ *    we cannot lose wakeup events.
+ */
+
+void __up(struct semaphore *sem)
+{
+	wake_up(&sem->wait);
+}
+
+static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED;
+
+void __down(struct semaphore * sem)
+{
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+	tsk->state = TASK_UNINTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	spin_lock_irq(&semaphore_lock);
+	sem->sleepers++;
+	for (;;) {
+		int sleepers = sem->sleepers;
+
+		/*
+		 * Add "everybody else" into it. They aren't
+		 * playing, because we own the spinlock.
+		 */
+		if (!atomic_add_negative(sleepers - 1, &sem->count)) {
+			sem->sleepers = 0;
+			break;
+		}
+		sem->sleepers = 1;	/* us - see -1 above */
+		spin_unlock_irq(&semaphore_lock);
+
+		schedule();
+		tsk->state = TASK_UNINTERRUPTIBLE;
+		spin_lock_irq(&semaphore_lock);
+	}
+	spin_unlock_irq(&semaphore_lock);
+	remove_wait_queue(&sem->wait, &wait);
+	tsk->state = TASK_RUNNING;
+	wake_up(&sem->wait);
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+	int retval = 0;
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+	tsk->state = TASK_INTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	spin_lock_irq(&semaphore_lock);
+	sem->sleepers ++;
+	for (;;) {
+		int sleepers = sem->sleepers;
+
+		/*
+		 * With signals pending, this turns into
+		 * the trylock failure case - we won't be
+		 * sleeping, and we* can't get the lock as
+		 * it has contention. Just correct the count
+		 * and exit.
+		 */
+		if (signal_pending(current)) {
+			retval = -EINTR;
+			sem->sleepers = 0;
+			atomic_add(sleepers, &sem->count);
+			break;
+		}
+
+		/*
+		 * Add "everybody else" into it. They aren't
+		 * playing, because we own the spinlock. The
+		 * "-1" is because we're still hoping to get
+		 * the lock.
+		 */
+		if (!atomic_add_negative(sleepers - 1, &sem->count)) {
+			sem->sleepers = 0;
+			break;
+		}
+		sem->sleepers = 1;	/* us - see -1 above */
+		spin_unlock_irq(&semaphore_lock);
+
+		schedule();
+		tsk->state = TASK_INTERRUPTIBLE;
+		spin_lock_irq(&semaphore_lock);
+	}
+	spin_unlock_irq(&semaphore_lock);
+	tsk->state = TASK_RUNNING;
+	remove_wait_queue(&sem->wait, &wait);
+	wake_up(&sem->wait);
+	return retval;
+}
+
+/*
+ * Trylock failed - make sure we correct for
+ * having decremented the count.
+ *
+ * We could have done the trylock with a
+ * single "cmpxchg" without failure cases,
+ * but then it wouldn't work on a 386.
+ */
+int __down_trylock(struct semaphore * sem)
+{
+	int sleepers;
+	unsigned long flags;
+
+	spin_lock_irqsave(&semaphore_lock, flags);
+	sleepers = sem->sleepers + 1;
+	sem->sleepers = 0;
+
+	/*
+	 * Add "everybody else" and us into it. They aren't
+	 * playing, because we own the spinlock.
+	 */
+	if (!atomic_add_negative(sleepers, &sem->count))
+		wake_up(&sem->wait);
+
+	spin_unlock_irqrestore(&semaphore_lock, flags);
+	return 1;
+}
+
+/*
+ * The semaphore operations have a special calling sequence that
+ * allow us to do a simpler in-line version of them. These routines
+ * need to convert that sequence back into the C sequence when
+ * there is contention on the semaphore.
+ *
+ * ip contains the semaphore pointer on entry. Save the C-clobbered
+ * registers (r0 to r3 and lr), but not ip, as we use it as a return
+ * value in some cases..
+ */
+#ifdef CONFIG_CPU_26
+asm("	.section	.text.lock, \"ax\"     \n\
+	.align	5			       \n\
+	.globl	__down_failed		       \n\
+__down_failed:				       \n\
+	stmfd	sp!, {r0 - r3, lr}	       \n\
+	mov	r0, ip			       \n\
+	bl	__down			       \n\
+	ldmfd	sp!, {r0 - r3, pc}^	       \n\
+					       \n\
+	.align	5			       \n\
+	.globl	__down_interruptible_failed    \n\
+__down_interruptible_failed:		       \n\
+	stmfd	sp!, {r0 - r3, lr}	       \n\
+	mov	r0, ip			       \n\
+	bl	__down_interruptible	       \n\
+	mov	ip, r0			       \n\
+	ldmfd	sp!, {r0 - r3, pc}^	       \n\
+					       \n\
+	.align	5			       \n\
+	.globl	__down_trylock_failed	       \n\
+__down_trylock_failed:			       \n\
+	stmfd	sp!, {r0 - r3, lr}	       \n\
+	mov	r0, ip			       \n\
+	bl	__down_trylock		       \n\
+	mov	ip, r0			       \n\
+	ldmfd	sp!, {r0 - r3, pc}^	       \n\
+					       \n\
+	.align	5			       \n\
+	.globl	__up_wakeup		       \n\
+__up_wakeup:				       \n\
+	stmfd	sp!, {r0 - r3, lr}	       \n\
+	mov	r0, ip			       \n\
+	bl	__up			       \n\
+	ldmfd	sp!, {r0 - r3, pc}^	       \n\
+					       \n\
+	.previous			       \n\
+	");
+
+#else
+/* 32 bit version */
+asm("	.section	.text.lock, \"ax\"    \n\
+	.align	5			      \n\
+	.globl	__down_failed		      \n\
+__down_failed:				      \n\
+	stmfd	sp!, {r0 - r3, lr}	      \n\
+	mov	r0, ip			      \n\
+	bl	__down			      \n\
+	ldmfd	sp!, {r0 - r3, pc}	      \n\
+					      \n\
+	.align	5			      \n\
+	.globl	__down_interruptible_failed   \n\
+__down_interruptible_failed:		      \n\
+	stmfd	sp!, {r0 - r3, lr}	      \n\
+	mov	r0, ip			      \n\
+	bl	__down_interruptible	      \n\
+	mov	ip, r0			      \n\
+	ldmfd	sp!, {r0 - r3, pc}	      \n\
+					      \n\
+	.align	5			      \n\
+	.globl	__down_trylock_failed	      \n\
+__down_trylock_failed:			      \n\
+	stmfd	sp!, {r0 - r3, lr}	      \n\
+	mov	r0, ip			      \n\
+	bl	__down_trylock		      \n\
+	mov	ip, r0			      \n\
+	ldmfd	sp!, {r0 - r3, pc}	      \n\
+					      \n\
+	.align	5			      \n\
+	.globl	__up_wakeup		      \n\
+__up_wakeup:				      \n\
+	stmfd	sp!, {r0 - r3, lr}	      \n\
+	mov	r0, ip			      \n\
+	bl	__up			      \n\
+	ldmfd	sp!, {r0 - r3, pc}	      \n\
+					      \n\
+	.previous			      \n\
+	");
+
+#endif
diff -urN linux-2.4.29/arch/armnommu/kernel/setup.c linux-2.4.29-uc1/arch/armnommu/kernel/setup.c
--- linux-2.4.29/arch/armnommu/kernel/setup.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/setup.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,691 @@
+/*
+ *  linux/arch/arm/kernel/setup.c
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/utsname.h>
+#include <linux/blk.h>
+#include <linux/console.h>
+#include <linux/bootmem.h>
+#include <linux/init.h>
+#include <linux/seq_file.h>
+
+#include <asm/elf.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/procinfo.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+
+#ifndef MEM_SIZE
+
+//#define MEM_SIZE	(64*1024*1024)
+//#define MEM_SIZE	(8*1024*1024)
+#define MEM_SIZE (END_MEM-PAGE_OFFSET)	// FIXME
+
+#endif
+
+#ifndef CONFIG_CMDLINE
+#define CONFIG_CMDLINE "root=/dev/rom0"
+#endif
+  
+#ifdef CONFIG_ARCH_NETARM
+#include <asm/arch/netarm_registers.h>
+#include <asm/arch/netarm_mmap.h>
+#include <asm/arch/netarm_nvram.h>
+
+extern void _netarm_led_blink(void);
+#endif
+ 
+extern void paging_init(struct meminfo *, struct machine_desc *desc);
+extern void convert_to_tag_list(struct tag *tags);
+extern void squash_mem_tags(struct tag *tag);
+extern void bootmem_init(struct meminfo *);
+extern void reboot_setup(char *str);
+extern unsigned long long memparse(char *ptr, char **retptr);
+extern unsigned long _end_kernel;
+#ifdef CONFIG_RAM_ATTACHED_ROMFS
+extern unsigned long _ramstart;
+#endif
+
+extern int root_mountflags;
+extern int _stext, _text, _etext, _edata, _end;
+
+unsigned int processor_id;
+unsigned int compat;
+unsigned int __machine_arch_type;
+unsigned int system_rev;
+unsigned int system_serial_low;
+unsigned int system_serial_high;
+unsigned int mem_fclk_21285 = 50000000;
+unsigned int elf_hwcap;
+
+#ifdef MULTI_CPU
+struct processor processor;
+#endif
+  
+struct drive_info_struct { char dummy[32]; } drive_info;
+
+struct screen_info screen_info = {
+ orig_video_lines:	30,
+ orig_video_cols:	80,
+ orig_video_mode:	0,
+ orig_video_ega_bx:	0,
+ orig_video_isVGA:	1,
+ orig_video_points:	8
+};
+
+unsigned char aux_device_present;
+char elf_platform[ELF_PLATFORM_SIZE];
+char saved_command_line[COMMAND_LINE_SIZE];
+
+static struct meminfo meminfo __initdata = { 0, };
+static struct proc_info_item proc_info;
+static const char *machine_name;
+static char command_line[COMMAND_LINE_SIZE] = "root=/dev/rom0";
+
+static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
+static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
+#define ENDIANNESS ((char)endian_test.l)
+
+/*
+ * Standard memory resources
+ */
+static struct resource mem_res[] = {
+	{ "Video RAM",   0,     0,     IORESOURCE_MEM			},
+	{ "Kernel code", 0,     0,     IORESOURCE_MEM			},
+	{ "Kernel data", 0,     0,     IORESOURCE_MEM			}
+};
+
+#define video_ram   mem_res[0]
+#define kernel_code mem_res[1]
+#define kernel_data mem_res[2]
+
+static struct resource io_res[] = {
+	{ "reserved",    0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY },
+	{ "reserved",    0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY },
+	{ "reserved",    0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY }
+};
+
+#define lp0 io_res[0]
+#define lp1 io_res[1]
+#define lp2 io_res[2]
+
+static void __init setup_processor(void)
+{
+	extern struct proc_info_list __proc_info_begin, __proc_info_end;
+	struct proc_info_list *list;
+
+	/*
+	 * locate processor in the list of supported processor
+	 * types.  The linker builds this table for us from the
+	 * entries in arch/arm/mm/proc-*.S
+	 */
+	for (list = &__proc_info_begin; list < &__proc_info_end ; list++)
+		if ((processor_id & list->cpu_mask) == list->cpu_val)
+			break;
+
+	/*
+	 * If processor type is unrecognised, then we
+	 * can do nothing...
+	 */
+	if (list >= &__proc_info_end) {
+		printk("CPU configuration botched (ID %08x), unable "
+		       "to continue.\n", processor_id);
+		while (1);
+	}
+
+	proc_info = *list->info;
+
+#ifdef MULTI_CPU
+	processor = *list->proc;
+#endif
+
+	printk("Processor: %s %s revision %d\n",
+	       proc_info.manufacturer, proc_info.cpu_name,
+	       (int)processor_id & 15);
+
+	sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
+	sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
+	elf_hwcap = list->elf_hwcap;
+
+	cpu_proc_init();
+}
+
+static struct machine_desc * __init setup_architecture(unsigned int nr)
+{
+	extern struct machine_desc __arch_info_begin, __arch_info_end;
+	struct machine_desc *list;
+
+	/*
+	 * locate architecture in the list of supported architectures.
+	 */
+	for (list = &__arch_info_begin; list < &__arch_info_end; list++)
+		if (list->nr == nr)
+			break;
+
+	/*
+	 * If the architecture type is not recognised, then we
+	 * can do nothing...
+	 */
+	if (list >= &__arch_info_end) {
+		printk("Architecture configuration botched (nr %d), unable "
+		       "to continue.\n", nr);
+		while (1);
+	}
+
+	printk("Architecture: %s\n", list->name);
+	if (compat)
+		printk(KERN_WARNING "Using compatibility code "
+			"scheduled for removal in v%d.%d.%d\n",
+			compat >> 24, (compat >> 12) & 0x3ff,
+			compat & 0x3ff);
+
+	return list;
+}
+
+/*
+ * Initial parsing of the command line.  We need to pick out the
+ * memory size.  We look for mem=size@start, where start and size
+ * are "size[KkMm]"
+ */
+static void __init
+parse_cmdline(struct meminfo *mi, char **cmdline_p, char *from)
+{
+	char c = ' ', *to = command_line;
+	int usermem = 0, len = 0;
+
+	for (;;) {
+		if (c == ' ' && !memcmp(from, "mem=", 4)) {
+			unsigned long start;
+			unsigned long long size;
+
+			if (to != command_line)
+				to -= 1;
+
+			/*
+			 * If the user specifies memory size, we
+			 * blow away any automatically generated
+			 * size.
+			 */
+			if (usermem == 0) {
+				usermem = 1;
+				mi->nr_banks = 0;
+			}
+
+			start = PHYS_OFFSET;
+			size  = memparse(from + 4, &from);
+			if (*from == '@')
+				start = memparse(from + 1, &from);
+
+			mi->bank[mi->nr_banks].start = start;
+			mi->bank[mi->nr_banks].size  = size;
+			mi->bank[mi->nr_banks].node  = 0;
+			mi->nr_banks += 1;
+#ifdef CONFIG_BLK_DEV_INITRD
+		} else if (c == ' ' && !memcmp(from, "initrd=", 7)) {
+			unsigned long start, size;
+
+			/*
+			 * Remove space character
+			 */
+			if (to != command_line)
+				to -= 1;
+
+			start = memparse(from + 7, &from);
+			if (*from == ',') {
+				size = memparse(from + 1, &from);
+
+				initrd_start = start;
+				initrd_end   = start + size;
+			}
+#endif /* CONFIG_BLK_DEV_INITRD */
+		}
+		c = *from++;
+		if (!c)
+			break;
+		if (COMMAND_LINE_SIZE <= ++len)
+			break;
+		*to++ = c;
+	}
+	*to = '\0';
+	*cmdline_p = command_line;
+}
+
+void __init
+setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
+{
+#ifdef CONFIG_BLK_DEV_RAM
+	extern int rd_doload, rd_prompt, rd_image_start, rd_size;
+
+	rd_image_start = image_start;
+	rd_prompt = prompt;
+	rd_doload = doload;
+
+	if (rd_sz)
+		rd_size = rd_sz;
+#endif
+}
+
+/*
+ * initial ram disk
+ */
+void __init setup_initrd(unsigned int start, unsigned int size)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (start == 0)
+		size = 0;
+	initrd_start = start;
+	initrd_end   = start + size;
+#endif
+}
+
+static void __init
+request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
+{
+	struct resource *res;
+	int i;
+
+	kernel_code.start  = __virt_to_bus(init_mm.start_code);
+	kernel_code.end    = __virt_to_bus(init_mm.end_code - 1);
+	kernel_data.start  = __virt_to_bus(init_mm.end_code);
+	kernel_data.end    = __virt_to_bus(init_mm.brk - 1);
+
+	for (i = 0; i < mi->nr_banks; i++) {
+		unsigned long virt_start, virt_end;
+
+		if (mi->bank[i].size == 0)
+			continue;
+
+		virt_start = __phys_to_virt(mi->bank[i].start);
+		virt_end   = virt_start + mi->bank[i].size - 1;
+
+		res = alloc_bootmem_low(sizeof(*res));
+		res->name  = "System RAM";
+		res->start = __virt_to_bus(virt_start);
+		res->end   = __virt_to_bus(virt_end);
+		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+		request_resource(&iomem_resource, res);
+
+		if (kernel_code.start >= res->start &&
+		    kernel_code.end <= res->end)
+			request_resource(res, &kernel_code);
+		if (kernel_data.start >= res->start &&
+		    kernel_data.end <= res->end)
+			request_resource(res, &kernel_data);
+	}
+
+	if (mdesc->video_start) {
+		video_ram.start = mdesc->video_start;
+		video_ram.end   = mdesc->video_end;
+		request_resource(&iomem_resource, &video_ram);
+	}
+
+	/*
+	 * Some machines don't have the possibility of ever
+	 * possessing lp0, lp1 or lp2
+	 */
+	if (mdesc->reserve_lp0)
+		request_resource(&ioport_resource, &lp0);
+	if (mdesc->reserve_lp1)
+		request_resource(&ioport_resource, &lp1);
+	if (mdesc->reserve_lp2)
+		request_resource(&ioport_resource, &lp2);
+}
+
+/*
+ *  Tag parsing.
+ *
+ * This is the new way of passing data to the kernel at boot time.  Rather
+ * than passing a fixed inflexible structure to the kernel, we pass a list
+ * of variable-sized tags to the kernel.  The first tag must be a ATAG_CORE
+ * tag for the list to be recognised (to distinguish the tagged list from
+ * a param_struct).  The list is terminated with a zero-length tag (this tag
+ * is not parsed in any way).
+ */
+static int __init parse_tag_core(const struct tag *tag)
+{
+	if ((tag->u.core.flags & 1) == 0)
+		root_mountflags &= ~MS_RDONLY;
+	ROOT_DEV = to_kdev_t(tag->u.core.rootdev);
+	return 0;
+}
+
+__tagtable(ATAG_CORE, parse_tag_core);
+
+static int __init parse_tag_mem32(const struct tag *tag)
+{
+	if (meminfo.nr_banks >= NR_BANKS) {
+		printk(KERN_WARNING
+		       "Ignoring memory bank 0x%08x size %dKB\n",
+			tag->u.mem.start, tag->u.mem.size / 1024);
+		return -EINVAL;
+	}
+	meminfo.bank[meminfo.nr_banks].start = tag->u.mem.start;
+	meminfo.bank[meminfo.nr_banks].size  = tag->u.mem.size;
+	meminfo.bank[meminfo.nr_banks].node  = 0;
+	meminfo.nr_banks += 1;
+
+	return 0;
+}
+
+__tagtable(ATAG_MEM, parse_tag_mem32);
+
+static int __init parse_tag_videotext(const struct tag *tag)
+{
+	screen_info.orig_x            = tag->u.videotext.x;
+	screen_info.orig_y            = tag->u.videotext.y;
+	screen_info.orig_video_page   = tag->u.videotext.video_page;
+	screen_info.orig_video_mode   = tag->u.videotext.video_mode;
+	screen_info.orig_video_cols   = tag->u.videotext.video_cols;
+	screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
+	screen_info.orig_video_lines  = tag->u.videotext.video_lines;
+	screen_info.orig_video_isVGA  = tag->u.videotext.video_isvga;
+	screen_info.orig_video_points = tag->u.videotext.video_points;
+	return 0;
+}
+
+__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
+
+static int __init parse_tag_ramdisk(const struct tag *tag)
+{
+	setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
+		      (tag->u.ramdisk.flags & 2) == 0,
+		      tag->u.ramdisk.start, tag->u.ramdisk.size);
+	return 0;
+}
+
+__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
+
+static int __init parse_tag_initrd(const struct tag *tag)
+{
+	setup_initrd(tag->u.initrd.start, tag->u.initrd.size);
+	return 0;
+}
+
+__tagtable(ATAG_INITRD, parse_tag_initrd);
+
+static int __init parse_tag_initrd2(const struct tag *tag)
+{
+	setup_initrd(tag->u.initrd.start, tag->u.initrd.size);
+	return 0;
+}
+
+__tagtable(ATAG_INITRD2, parse_tag_initrd2);
+
+static int __init parse_tag_serialnr(const struct tag *tag)
+{
+	system_serial_low = tag->u.serialnr.low;
+	system_serial_high = tag->u.serialnr.high;
+	return 0;
+}
+
+__tagtable(ATAG_SERIAL, parse_tag_serialnr);
+
+static int __init parse_tag_revision(const struct tag *tag)
+{
+	system_rev = tag->u.revision.rev;
+	return 0;
+}
+
+__tagtable(ATAG_REVISION, parse_tag_revision);
+
+static int __init parse_tag_cmdline(const struct tag *tag)
+{
+	strncpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
+	default_command_line[COMMAND_LINE_SIZE - 1] = '\0';
+	return 0;
+}
+
+__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
+
+/*
+ * Scan one tag table for this tag, and call its parse function.
+ * The tag table is built by the linker from all the __tagtable
+ * declarations.
+ */
+static int __init parse_tag(const struct tag *tag)
+{
+	extern struct tagtable __tagtable_begin, __tagtable_end;
+	struct tagtable *t;
+
+	for (t = &__tagtable_begin; t < &__tagtable_end; t++)
+		if (tag->hdr.tag == t->tag) {
+			t->parse(tag);
+			break;
+		}
+
+	return t < &__tagtable_end;
+}
+
+/*
+ * Parse all tags in the list, checking both the global and architecture
+ * specific tag tables.
+ */
+static void __init parse_tags(const struct tag *t)
+{
+	for (; t->hdr.size; t = tag_next(t)) 
+		if (!parse_tag(t))
+			printk(KERN_WARNING
+				"Ignoring unrecognised tag 0x%08x\n", 
+				t->hdr.tag);
+}
+
+static struct init_tags {
+	struct tag_header hdr1;
+	struct tag_core   core;
+	struct tag_header hdr2;
+	struct tag_mem32  mem;
+	struct tag_header hdr3;
+} init_tags __initdata = {
+	{ tag_size(tag_core), ATAG_CORE },
+	{ 1, PAGE_SIZE, 0xff },
+	{ tag_size(tag_mem32), ATAG_MEM },
+	{ MEM_SIZE, PHYS_OFFSET },
+	{ 0, ATAG_NONE }
+};
+
+void __init setup_arch(char **cmdline_p)
+{
+	struct tag *tags = (struct tag *)&init_tags;
+	struct machine_desc *mdesc;
+	char *from = default_command_line;
+	int bootmap_size;
+#ifndef CONFIG_RAM_ATTACHED_ROMFS  
+	unsigned long memory_start = (unsigned long)&_end_kernel;
+#else
+	unsigned long memory_start = PAGE_ALIGN(_ramstart);
+#endif  
+	extern  void    config_BSP(void);
+#ifdef  CONFIG_UCBOOTSTRAP
+	extern  char    *getbenv(char * a);
+#endif
+#ifdef CONFIG_ARCH_CNXT
+	unsigned long memory_end = END_MEM;
+#endif
+	
+	ROOT_DEV = MKDEV(0, 255);
+
+#if 	defined(CONFIG_BOARD_EVS3C4530HEI) || \
+	defined(CONFIG_BOARD_SMDK2500)     || \
+	defined(CONFIG_BOARD_S3C2500REFRGP)
+	
+	config_BSP();
+#endif
+
+#ifdef	CONFIG_UCBOOTSTRAP
+	from = (char *) getbenv("KERNEL_ARGS");
+	if  ( from == NULL )
+	    from = default_command_line;
+#endif
+
+#ifdef CONFIG_ARCH_CNXT
+	syshwinit();
+#endif
+
+	setup_processor();
+	mdesc = setup_architecture(machine_arch_type);
+	machine_name = mdesc->name;
+
+	if (mdesc->soft_reboot)
+		reboot_setup("s");
+
+	if (mdesc->param_offset)
+		tags = phys_to_virt(mdesc->param_offset);
+
+	/*
+	 * Do the machine-specific fixups before we parse the
+	 * parameters or tags.
+	 */
+	if (mdesc->fixup)
+		mdesc->fixup(mdesc, (struct param_struct *)tags,
+			     &from, &meminfo);
+
+	/*
+	 * If we have the old style parameters, convert them to
+	 * a tag list.
+	 */
+	if (tags->hdr.tag != ATAG_CORE)
+		convert_to_tag_list(tags);
+
+	if (tags->hdr.tag == ATAG_CORE) {
+		if (meminfo.nr_banks != 0)
+			squash_mem_tags(tags);
+		parse_tags(tags);
+	}
+
+	if (meminfo.nr_banks == 0) {
+		meminfo.nr_banks      = 1;
+		meminfo.bank[0].start = PAGE_OFFSET;//PHYS_OFFSET;
+		meminfo.bank[0].size  = MEM_SIZE;
+	}
+
+	init_mm.start_code = (unsigned long) &_text;
+	init_mm.end_code   = (unsigned long) &_etext;
+#ifndef CONFIG_RAM_ATTACHED_ROMFS  
+	init_mm.end_data   = (unsigned long) &_edata;
+	init_mm.brk	   = (unsigned long) &_end;
+#else
+	init_mm.end_data   = (unsigned long) _ramstart;
+	init_mm.brk	   = (unsigned long) _ramstart;
+#endif
+
+	memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
+	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
+	parse_cmdline(&meminfo, cmdline_p, from);
+
+#if 1
+	bootmem_init(&meminfo);
+#else
+	bootmap_size= init_bootmem_node(
+			  NODE_DATA(0),
+			  memory_start >> PAGE_SHIFT,
+			  PAGE_OFFSET >> PAGE_SHIFT,
+			  END_MEM >> PAGE_SHIFT);
+ 
+	free_bootmem(memory_start, END_MEM - memory_start);
+	reserve_bootmem(memory_start, bootmap_size);
+#endif
+	paging_init(&meminfo, mdesc);		// mem_map is set up here! 
+	request_standard_resources(&meminfo, mdesc);
+
+	/*
+	 * Set up various architecture-specific pointers
+	 */
+	init_arch_irq = mdesc->init_irq;
+
+#ifdef CONFIG_VT
+#if defined(CONFIG_VGA_CONSOLE)
+	conswitchp = &vga_con;
+#elif defined(CONFIG_DUMMY_CONSOLE)
+	conswitchp = &dummy_con;
+#endif
+#endif
+}
+
+int get_cpuinfo(char * buffer)
+{
+	char *p = buffer;
+
+	p += sprintf(p, "Processor\t: %s %s rev %d (%s)\n",
+		     proc_info.manufacturer, proc_info.cpu_name,
+		     (int)processor_id & 15, elf_platform);
+
+	p += sprintf(p, "BogoMIPS\t: %lu.%02lu\n",
+		     loops_per_jiffy / (500000/HZ),
+		     (loops_per_jiffy / (5000/HZ)) % 100);
+
+	p += sprintf(p, "Hardware\t: %s\n", machine_name);
+
+	p += sprintf(p, "Revision\t: %04x\n",
+		     system_rev);
+
+	p += sprintf(p, "Serial\t\t: %08x%08x\n",
+		     system_serial_high,
+		     system_serial_low);
+
+	return p - buffer;
+}
+
+
+/*
+ *	Get CPU information for use by the procfs.
+ */
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+	seq_printf(m, "Processor\t: %s %s rev %d (%s)\n",
+		     proc_info.manufacturer, proc_info.cpu_name,
+		     (int)processor_id & 15, elf_platform);
+
+	seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
+		     loops_per_jiffy / (500000/HZ),
+		     (loops_per_jiffy / (5000/HZ)) % 100);
+
+	seq_printf(m, "Hardware\t: %s\n", machine_name);
+
+	seq_printf(m, "Revision\t: %04x\n",
+		     system_rev);
+
+	seq_printf(m, "Serial\t\t: %08x%08x\n",
+		     system_serial_high,
+		     system_serial_low);
+
+	return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+	start:	c_start,
+	next:	c_next,
+	stop:	c_stop,
+	show:	show_cpuinfo,
+};
+
diff -urN linux-2.4.29/arch/armnommu/kernel/signal.c linux-2.4.29-uc1/arch/armnommu/kernel/signal.c
--- linux-2.4.29/arch/armnommu/kernel/signal.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/signal.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,657 @@
+/*
+ *  linux/arch/arm/kernel/signal.c
+ *
+ *  Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/tty.h>
+#include <linux/personality.h>
+
+#include <asm/pgalloc.h>
+#include <asm/ucontext.h>
+#include <asm/uaccess.h>
+
+#include "ptrace.h"
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+#define SWI_SYS_SIGRETURN	(0xef000000|(__NR_sigreturn))
+#define SWI_SYS_RT_SIGRETURN	(0xef000000|(__NR_rt_sigreturn))
+
+/* fill these in later */
+#define SWI_THUMB_SIGRETURN	(0xdf00)
+#define SWI_THUMB_RT_SIGRETURN	(0xdf00)
+
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
+
+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
+{
+	int err = -EFAULT;;
+
+	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+		goto out;
+
+	if (from->si_code < 0)
+		return __copy_to_user(to, from, sizeof(siginfo_t));
+
+	/* If you change siginfo_t structure, please be sure
+	   this code is fixed accordingly.
+	   It should never copy any pad contained in the structure
+	   to avoid security leaks, but must copy the generic
+	   3 ints plus the relevant union member.  */
+	err = __put_user(from->si_signo, &to->si_signo);
+	err |= __put_user(from->si_errno, &to->si_errno);
+	err |= __put_user((short)from->si_code, &to->si_code);
+	/* First 32bits of unions are always present.  */
+	err |= __put_user(from->si_pid, &to->si_pid);
+	switch (from->si_code >> 16) {
+	case __SI_FAULT >> 16:
+		break;
+	case __SI_CHLD >> 16:
+		err |= __put_user(from->si_utime, &to->si_utime);
+		err |= __put_user(from->si_stime, &to->si_stime);
+		err |= __put_user(from->si_status, &to->si_status);
+	default:
+		err |= __put_user(from->si_uid, &to->si_uid);
+		break;
+	/* case __SI_RT: This is not generated by the kernel as of now.  */
+	}
+out:
+	return err;
+}
+
+/*
+ * atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs)
+{
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+	regs->ARM_r0 = -EINTR;
+
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs, 0))
+			return regs->ARM_r0;
+	}
+}
+
+asmlinkage int
+sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, struct pt_regs *regs)
+{
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's. */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+	regs->ARM_r0 = -EINTR;
+
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs, 0))
+			return regs->ARM_r0;
+	}
+}
+
+asmlinkage int 
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+struct sigframe
+{
+	struct sigcontext sc;
+	unsigned long extramask[_NSIG_WORDS-1];
+	unsigned long retcode;
+};
+
+struct rt_sigframe
+{
+	struct siginfo *pinfo;
+	void *puc;
+	struct siginfo info;
+	struct ucontext uc;
+	unsigned long retcode;
+};
+
+static int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+{
+	int err = 0;
+
+	__get_user_error(regs->ARM_r0, &sc->arm_r0, err);
+	__get_user_error(regs->ARM_r1, &sc->arm_r1, err);
+	__get_user_error(regs->ARM_r2, &sc->arm_r2, err);
+	__get_user_error(regs->ARM_r3, &sc->arm_r3, err);
+	__get_user_error(regs->ARM_r4, &sc->arm_r4, err);
+	__get_user_error(regs->ARM_r5, &sc->arm_r5, err);
+	__get_user_error(regs->ARM_r6, &sc->arm_r6, err);
+	__get_user_error(regs->ARM_r7, &sc->arm_r7, err);
+	__get_user_error(regs->ARM_r8, &sc->arm_r8, err);
+	__get_user_error(regs->ARM_r9, &sc->arm_r9, err);
+	__get_user_error(regs->ARM_r10, &sc->arm_r10, err);
+	__get_user_error(regs->ARM_fp, &sc->arm_fp, err);
+	__get_user_error(regs->ARM_ip, &sc->arm_ip, err);
+	__get_user_error(regs->ARM_sp, &sc->arm_sp, err);
+	__get_user_error(regs->ARM_lr, &sc->arm_lr, err);
+	__get_user_error(regs->ARM_pc, &sc->arm_pc, err);
+#ifdef CONFIG_CPU_32
+	__get_user_error(regs->ARM_cpsr, &sc->arm_cpsr, err);
+#endif
+
+	err |= !valid_user_regs(regs);
+
+	return err;
+}
+
+asmlinkage int sys_sigreturn(struct pt_regs *regs)
+{
+	struct sigframe *frame;
+	sigset_t set;
+
+	/*
+	 * Since we stacked the signal on a word boundary,
+	 * then 'sp' should be word aligned here.  If it's
+	 * not, then the user is trying to mess with us.
+	 */
+	if (regs->ARM_sp & 3)
+		goto badframe;
+
+	frame = (struct sigframe *)regs->ARM_sp;
+
+	if (verify_area(VERIFY_READ, frame, sizeof (*frame)))
+		goto badframe;
+	if (__get_user(set.sig[0], &frame->sc.oldmask)
+	    || (_NSIG_WORDS > 1
+	        && __copy_from_user(&set.sig[1], &frame->extramask,
+				    sizeof(frame->extramask))))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigcontext(regs, &frame->sc))
+		goto badframe;
+
+	/* Send SIGTRAP if we're single-stepping */
+	if (ptrace_cancel_bpt(current))
+		send_sig(SIGTRAP, current, 1);
+
+	return regs->ARM_r0;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+	sigset_t set;
+
+	/*
+	 * Since we stacked the signal on a word boundary,
+	 * then 'sp' should be word aligned here.  If it's
+	 * not, then the user is trying to mess with us.
+	 */
+	if (regs->ARM_sp & 3)
+		goto badframe;
+
+	frame = (struct rt_sigframe *)regs->ARM_sp;
+
+	if (verify_area(VERIFY_READ, frame, sizeof (*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
+		goto badframe;
+
+	/* Send SIGTRAP if we're single-stepping */
+	if (ptrace_cancel_bpt(current))
+		send_sig(SIGTRAP, current, 1);
+
+	return regs->ARM_r0;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+static int
+setup_sigcontext(struct sigcontext *sc, /*struct _fpstate *fpstate,*/
+		 struct pt_regs *regs, unsigned long mask)
+{
+	int err = 0;
+
+	__put_user_error(regs->ARM_r0, &sc->arm_r0, err);
+	__put_user_error(regs->ARM_r1, &sc->arm_r1, err);
+	__put_user_error(regs->ARM_r2, &sc->arm_r2, err);
+	__put_user_error(regs->ARM_r3, &sc->arm_r3, err);
+	__put_user_error(regs->ARM_r4, &sc->arm_r4, err);
+	__put_user_error(regs->ARM_r5, &sc->arm_r5, err);
+	__put_user_error(regs->ARM_r6, &sc->arm_r6, err);
+	__put_user_error(regs->ARM_r7, &sc->arm_r7, err);
+	__put_user_error(regs->ARM_r8, &sc->arm_r8, err);
+	__put_user_error(regs->ARM_r9, &sc->arm_r9, err);
+	__put_user_error(regs->ARM_r10, &sc->arm_r10, err);
+	__put_user_error(regs->ARM_fp, &sc->arm_fp, err);
+	__put_user_error(regs->ARM_ip, &sc->arm_ip, err);
+	__put_user_error(regs->ARM_sp, &sc->arm_sp, err);
+	__put_user_error(regs->ARM_lr, &sc->arm_lr, err);
+	__put_user_error(regs->ARM_pc, &sc->arm_pc, err);
+#ifdef CONFIG_CPU_32
+	__put_user_error(regs->ARM_cpsr, &sc->arm_cpsr, err);
+#endif
+
+	__put_user_error(current->thread.trap_no, &sc->trap_no, err);
+	__put_user_error(current->thread.error_code, &sc->error_code, err);
+	__put_user_error(current->thread.address, &sc->fault_address, err);
+	__put_user_error(mask, &sc->oldmask, err);
+
+	return err;
+}
+
+static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+				 unsigned long framesize)
+{
+	unsigned long sp = regs->ARM_sp;
+
+	/*
+	 * This is the X/Open sanctioned signal stack switching.
+	 */
+	if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(sp))
+		sp = current->sas_ss_sp + current->sas_ss_size;
+
+	/*
+	 * No matter what happens, 'sp' must be word
+	 * aligned otherwise nasty things could happen
+	 */
+	/* ATPCS B01 mandates 8-byte alignment */
+	return (void *)((sp - framesize) & ~7);
+}
+
+static void setup_frame(int sig, struct k_sigaction *ka,
+			sigset_t *set, struct pt_regs *regs)
+{
+	struct sigframe *frame;
+	unsigned long retcode;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+		goto segv_and_exit;
+
+	err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
+
+	if (_NSIG_WORDS > 1) {
+		err |= __copy_to_user(frame->extramask, &set->sig[1],
+				      sizeof(frame->extramask));
+	}
+
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		retcode = (unsigned long)ka->sa.sa_restorer;
+	} else {
+		unsigned int code;
+		retcode = (unsigned long)&frame->retcode;
+		if (thumb_mode(regs))
+			code = SWI_THUMB_SIGRETURN;
+		else
+			code = SWI_SYS_SIGRETURN;
+		__put_user_error(code, &frame->retcode, err);
+		flush_icache_range(retcode, retcode + 4);
+	}
+
+	if (err)
+		goto segv_and_exit;
+
+	if (current->exec_domain && current->exec_domain->signal_invmap && sig < 32)
+		regs->ARM_r0 = current->exec_domain->signal_invmap[sig];
+	else
+		regs->ARM_r0 = sig;
+	regs->ARM_sp = (unsigned long)frame;
+	regs->ARM_lr = retcode;
+	regs->ARM_pc = (unsigned long)ka->sa.sa_handler;
+#if defined(CONFIG_CPU_32)
+	/* Maybe we need to deliver a 32-bit signal to a 26-bit task. */
+	if (ka->sa.sa_flags & SA_THIRTYTWO)
+		regs->ARM_cpsr = USR_MODE;
+#endif
+	if (valid_user_regs(regs))
+		return;
+
+segv_and_exit:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+			   sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+	unsigned long retcode;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+		goto segv_and_exit;
+
+	__put_user_error(&frame->info, &frame->pinfo, err);
+	__put_user_error(&frame->uc, &frame->puc, err);
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	/* Clear all the bits of the ucontext we don't use.  */
+	err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
+
+	err |= setup_sigcontext(&frame->uc.uc_mcontext, /*&frame->fpstate,*/
+				regs, set->sig[0]);
+	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		retcode = (unsigned long)ka->sa.sa_restorer;
+	} else {
+		unsigned int code;
+		retcode = (unsigned long)&frame->retcode;
+		if (thumb_mode(regs))
+			code = SWI_THUMB_RT_SIGRETURN;
+		else
+			code = SWI_SYS_RT_SIGRETURN;
+		__put_user_error(code, &frame->retcode, err);
+		flush_icache_range(retcode, retcode + 4);
+	}
+
+	if (err)
+		goto segv_and_exit;
+
+	if (current->exec_domain && current->exec_domain->signal_invmap && sig < 32)
+		regs->ARM_r0 = current->exec_domain->signal_invmap[sig];
+	else
+		regs->ARM_r0 = sig;
+
+	/*
+	 * For realtime signals we must also set the second and third
+	 * arguments for the signal handler.
+	 *   -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
+	 */
+	regs->ARM_r1 = (unsigned long)frame->pinfo;
+	regs->ARM_r2 = (unsigned long)frame->puc;
+
+	regs->ARM_sp = (unsigned long)frame;
+	regs->ARM_lr = retcode;
+	regs->ARM_pc = (unsigned long)ka->sa.sa_handler;
+#if defined(CONFIG_CPU_32)
+	/* Maybe we need to deliver a 32-bit signal to a 26-bit task. */
+	if (ka->sa.sa_flags & SA_THIRTYTWO)
+		regs->ARM_cpsr = USR_MODE;
+#endif
+	if (valid_user_regs(regs))
+		return;
+
+segv_and_exit:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+/*
+ * OK, we're invoking a handler
+ */	
+static void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+	      siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
+{
+	/* Set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sigmask_lock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending(current);
+		spin_unlock_irq(&current->sigmask_lock);
+	}
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals that
+ * the kernel can handle, and then we build all the user-level signal handling
+ * stack-frames in one go after that.
+ */
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
+{
+	struct k_sigaction *ka;
+	siginfo_t info;
+	int single_stepping;
+
+	/*
+	 * We want the common case to go fast, which
+	 * is why we may in certain cases get here from
+	 * kernel mode. Just return without doing anything
+	 * if so.
+	 */
+	if (!user_mode(regs))
+		return 0;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	single_stepping = ptrace_cancel_bpt(current);
+
+	for (;;) {
+		unsigned long signr;
+
+		spin_lock_irq (&current->sigmask_lock);
+		signr = dequeue_signal(&current->blocked, &info);
+		spin_unlock_irq (&current->sigmask_lock);
+
+		if (!signr)
+			break;
+
+		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			/* Let the debugger run.  */
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			notify_parent(current, SIGCHLD);
+			schedule();
+			single_stepping |= ptrace_cancel_bpt(current);
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code))
+				continue;
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				continue;
+
+			/* Update the siginfo structure.  Is this good? */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+
+			/* Init gets no signals it doesn't want.  */
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD: case SIGWINCH:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP:
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+					notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGABRT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				sigaddset(&current->pending.signal, signr);
+				recalc_sigpending(current);
+				current->flags |= PF_SIGNALED;
+				do_exit(exit_code);
+				/* NOTREACHED */
+			}
+		}
+
+		/* Are we from a system call? */
+		if (syscall) {
+			switch (regs->ARM_r0) {
+			case -ERESTARTNOHAND:
+				regs->ARM_r0 = -EINTR;
+				break;
+
+			case -ERESTARTSYS:
+				if (!(ka->sa.sa_flags & SA_RESTART)) {
+					regs->ARM_r0 = -EINTR;
+					break;
+				}
+				/* fallthrough */
+			case -ERESTARTNOINTR:
+				regs->ARM_r0 = regs->ARM_ORIG_r0;
+				regs->ARM_pc -= 4;
+			}
+		}
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(signr, ka, &info, oldset, regs);
+		if (single_stepping)
+		    	ptrace_set_bpt(current);
+		return 1;
+	}
+
+	if (syscall &&
+	    (regs->ARM_r0 == -ERESTARTNOHAND ||
+	     regs->ARM_r0 == -ERESTARTSYS ||
+	     regs->ARM_r0 == -ERESTARTNOINTR)) {
+		regs->ARM_r0 = regs->ARM_ORIG_r0;
+		regs->ARM_pc -= 4;
+	}
+	if (single_stepping)
+		ptrace_set_bpt(current);
+	return 0;
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/sys_arm.c linux-2.4.29-uc1/arch/armnommu/kernel/sys_arm.c
--- linux-2.4.29/arch/armnommu/kernel/sys_arm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/sys_arm.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,288 @@
+/*
+ *  linux/arch/arm/kernel/sys_arm.c
+ *
+ *  Copyright (C) People who wrote linux/arch/i386/kernel/sys_i386.c
+ *  Copyright (C) 1995, 1996 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  This file contains various random system calls that
+ *  have a non-standard calling sequence on the Linux/arm
+ *  platform.
+ */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+
+#include <asm/uaccess.h>
+#include <asm/ipc.h>
+
+extern unsigned long do_mremap(unsigned long addr, unsigned long old_len,
+			       unsigned long new_len, unsigned long flags,
+			       unsigned long new_addr);
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+asmlinkage int sys_pipe(unsigned long * fildes)
+{
+	int fd[2];
+	int error;
+
+	error = do_pipe(fd);
+	if (!error) {
+		if (copy_to_user(fildes, fd, 2*sizeof(int)))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+/* common code for old and new mmaps */
+inline long do_mmap2(
+	unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	int error = -EINVAL;
+	struct file * file = NULL;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	/*
+	 * If we are doing a fixed mapping, and address < PAGE_SIZE,
+	 * then deny it.
+	 */
+	if (flags & MAP_FIXED && addr < PAGE_SIZE && vectors_base() == 0)
+		goto out;
+
+	error = -EBADF;
+	if (!(flags & MAP_ANONYMOUS)) {
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+
+struct mmap_arg_struct {
+	unsigned long addr;
+	unsigned long len;
+	unsigned long prot;
+	unsigned long flags;
+	unsigned long fd;
+	unsigned long offset;
+};
+
+asmlinkage int old_mmap(struct mmap_arg_struct *arg)
+{
+	int error = -EFAULT;
+	struct mmap_arg_struct a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		goto out;;
+
+	error = -EINVAL;
+	if (a.offset & ~PAGE_MASK)
+		goto out;
+
+	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+out:
+	return error;
+}
+
+asmlinkage unsigned long
+sys_arm_mremap(unsigned long addr, unsigned long old_len,
+	       unsigned long new_len, unsigned long flags,
+	       unsigned long new_addr)
+{
+	unsigned long ret = -EINVAL;
+#ifndef CONFIG_UCLINUX
+	/*
+	 * If we are doing a fixed mapping, and address < PAGE_SIZE,
+	 * then deny it.
+	 */
+	if (flags & MREMAP_FIXED && new_addr < PAGE_SIZE &&
+	    vectors_base() == 0)
+		goto out;
+
+	down_write(&current->mm->mmap_sem);
+	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+	up_write(&current->mm->mmap_sem);
+
+out:
+#else
+	return ret;
+#endif
+}
+
+/*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls.
+ */
+extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+
+struct sel_arg_struct {
+	unsigned long n;
+	fd_set *inp, *outp, *exp;
+	struct timeval *tvp;
+};
+
+asmlinkage int old_select(struct sel_arg_struct *arg)
+{
+	struct sel_arg_struct a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+	/* sys_select() does the appropriate kernel locking */
+	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
+}
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	switch (call) {
+	case SEMOP:
+		return sys_semop (first, (struct sembuf *)ptr, second);
+	case SEMGET:
+		return sys_semget (first, second, third);
+	case SEMCTL: {
+		union semun fourth;
+		if (!ptr)
+			return -EINVAL;
+		if (get_user(fourth.__pad, (void **) ptr))
+			return -EFAULT;
+		return sys_semctl (first, second, third, fourth);
+	}
+
+	case MSGSND:
+		return sys_msgsnd (first, (struct msgbuf *) ptr, 
+				   second, third);
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
+			if (!ptr)
+				return -EINVAL;
+			if (copy_from_user(&tmp,(struct ipc_kludge *) ptr,
+					   sizeof (tmp)))
+				return -EFAULT;
+			return sys_msgrcv (first, tmp.msgp, second,
+					   tmp.msgtyp, third);
+		}
+		default:
+			return sys_msgrcv (first,
+					   (struct msgbuf *) ptr,
+					   second, fifth, third);
+		}
+	case MSGGET:
+		return sys_msgget ((key_t) first, second);
+	case MSGCTL:
+		return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+
+	case SHMAT:
+		switch (version) {
+		default: {
+			ulong raddr;
+			ret = sys_shmat (first, (char *) ptr, second, &raddr);
+			if (ret)
+				return ret;
+			return put_user (raddr, (ulong *) third);
+		}
+		case 1:	/* iBCS2 emulator entry point */
+			if (!segment_eq(get_fs(), get_ds()))
+				return -EINVAL;
+			return sys_shmat (first, (char *) ptr,
+					  second, (ulong *) third);
+		}
+	case SHMDT: 
+		return sys_shmdt ((char *)ptr);
+	case SHMGET:
+		return sys_shmget (first, second, third);
+	case SHMCTL:
+		return sys_shmctl (first, second,
+				   (struct shmid_ds *) ptr);
+	default:
+		return -EINVAL;
+	}
+}
+
+/* Fork a new task - this creates a new program thread.
+ * This is called indirectly via a small wrapper
+ */
+asmlinkage int sys_fork(struct pt_regs *regs)
+{
+	return do_fork(SIGCHLD, regs->ARM_sp, regs, 0);
+}
+
+/* Clone a task - this clones the calling program thread.
+ * This is called indirectly via a small wrapper
+ */
+asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, struct pt_regs *regs)
+{
+	if (!newsp)
+		newsp = regs->ARM_sp;
+	return do_fork(clone_flags, newsp, regs, 0);
+}
+
+asmlinkage int sys_vfork(struct pt_regs *regs)
+{
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs, 0);
+}
+
+/* sys_execve() executes a new program.
+ * This is called indirectly via a small wrapper
+ */
+asmlinkage int sys_execve(char *filenamei, char **argv, char **envp, struct pt_regs *regs)
+{
+	int error;
+	char * filename;
+
+	filename = getname(filenamei);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+	error = do_execve(filename, argv, envp, regs);
+	putname(filename);
+#ifdef NO_MM
+	/* if execve is suceeding, we really want to return argc to the exec'd prcess */
+	if (0 == error) return regs->ARM_r0;
+#endif
+out:
+	return error;
+}
+
+asmlinkage int sys_pause(void)
+{
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	return -ERESTARTNOHAND;
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/time-acorn.c linux-2.4.29-uc1/arch/armnommu/kernel/time-acorn.c
--- linux-2.4.29/arch/armnommu/kernel/time-acorn.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/time-acorn.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,75 @@
+/*
+ *  linux/arch/arm/kernel/time-acorn.c
+ *
+ *  Copyright (c) 1996-2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Changelog:
+ *   24-Sep-1996	RMK	Created
+ *   10-Oct-1996	RMK	Brought up to date with arch-sa110eval
+ *   04-Dec-1997	RMK	Updated for new arch/arm/time.c
+ */
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware/ioc.h>
+
+extern unsigned long (*gettimeoffset)(void);
+
+static unsigned long ioctime_gettimeoffset(void)
+{
+	unsigned int count1, count2, status1, status2;
+	unsigned long offset = 0;
+
+	status1 = ioc_readb(IOC_IRQREQA);
+	barrier ();
+	ioc_writeb (0, IOC_T0LATCH);
+	barrier ();
+	count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
+	barrier ();
+	status2 = ioc_readb(IOC_IRQREQA);
+	barrier ();
+	ioc_writeb (0, IOC_T0LATCH);
+	barrier ();
+	count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
+
+	if (count2 < count1) {
+		/*
+		 * This means that we haven't just had an interrupt
+		 * while reading into status2.
+		 */
+		if (status2 & (1 << 5))
+			offset = tick;
+		count1 = count2;
+	} else if (count2 > count1) {
+		/*
+		 * We have just had another interrupt while reading
+		 * status2.
+		 */
+		offset += tick;
+		count1 = count2;
+	}
+
+	count1 = LATCH - count1;
+	/*
+	 * count1 = number of clock ticks since last interrupt
+	 */
+	offset += count1 * tick / LATCH;
+	return offset;
+}
+
+void __init ioctime_init(void)
+{
+	ioc_writeb(LATCH & 255, IOC_T0LTCHL);
+	ioc_writeb(LATCH >> 8, IOC_T0LTCHH);
+	ioc_writeb(0, IOC_T0GO);
+
+	gettimeoffset = ioctime_gettimeoffset;
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/time.c linux-2.4.29-uc1/arch/armnommu/kernel/time.c
--- linux-2.4.29/arch/armnommu/kernel/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/time.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,227 @@
+/*
+ *  linux/arch/arm/kernel/time.c
+ *
+ *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *  Modifications for ARM (C) 1994, 1995, 1996,1997 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  This file contains the ARM-specific time handling details:
+ *  reading the RTC at bootup, etc...
+ *
+ *  1994-07-02  Alan Modra
+ *              fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
+ *  1998-12-20  Updated NTP code according to technical memorandum Jan '96
+ *              "A Kernel Model for Precision Timekeeping" by Dave Mills
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/timex.h>
+#include <asm/hardware.h>
+
+extern int setup_arm_irq(int, struct irqaction *);
+extern void setup_timer(void);
+extern rwlock_t xtime_lock;
+extern unsigned long wall_jiffies;
+
+/* change this if you have some constant time drift */
+#define USECS_PER_JIFFY	(1000000/HZ)
+
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
+#endif
+
+static int dummy_set_rtc(void)
+{
+	return 0;
+}
+
+/*
+ * hook for setting the RTC's idea of the current time.
+ */
+int (*set_rtc)(void) = dummy_set_rtc;
+
+static unsigned long dummy_gettimeoffset(void)
+{
+	return 0;
+}
+
+/*
+ * hook for getting the time offset.  Note that it is
+ * always called with interrupts disabled.
+ */
+unsigned long (*gettimeoffset)(void) = dummy_gettimeoffset;
+
+/*
+ * Handle kernel profile stuff...
+ */
+static inline void do_profile(struct pt_regs *regs)
+{
+	if (!user_mode(regs) &&
+	    prof_buffer &&
+	    current->pid) {
+		unsigned long pc = instruction_pointer(regs);
+		extern int _stext;
+
+		pc -= (unsigned long)&_stext;
+
+		pc >>= prof_shift;
+
+		if (pc >= prof_len)
+			pc = prof_len - 1;
+
+		prof_buffer[pc] += 1;
+	}
+}
+
+static long next_rtc_update;
+
+/*
+ * If we have an externally synchronized linux clock, then update
+ * CMOS clock accordingly every ~11 minutes.  set_rtc() has to be
+ * called as close as possible to 500 ms before the new second
+ * starts.
+ */
+static inline void do_set_rtc(void)
+{
+	if (time_status & STA_UNSYNC || set_rtc == NULL)
+		return;
+
+	if (next_rtc_update &&
+	    time_before(xtime.tv_sec, next_rtc_update))
+		return;
+
+	if (xtime.tv_usec < 50000 - (tick >> 1) &&
+	    xtime.tv_usec >= 50000 + (tick >> 1))
+		return;
+
+	if (set_rtc())
+		/*
+		 * rtc update failed.  Try again in 60s
+		 */
+		next_rtc_update = xtime.tv_sec + 60;
+	else
+		next_rtc_update = xtime.tv_sec + 660;
+}
+
+#ifdef CONFIG_LEDS
+
+#include <asm/leds.h>
+
+static void dummy_leds_event(led_event_t evt)
+{
+}
+
+void (*leds_event)(led_event_t) = dummy_leds_event;
+
+#ifdef CONFIG_MODULES
+EXPORT_SYMBOL(leds_event);
+#endif
+#endif
+
+#ifdef CONFIG_LEDS_TIMER
+static void do_leds(void)
+{
+	static unsigned int count = 50;
+
+	if (--count == 0) {
+		count = 50;
+		leds_event(led_timer);
+	}
+}
+#else
+#define do_leds()
+#endif
+
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned long flags;
+	unsigned long usec, sec;
+
+	read_lock_irqsave(&xtime_lock, flags);
+	usec = gettimeoffset();
+	{
+		unsigned long lost = jiffies - wall_jiffies;
+
+		if (lost)
+			usec += lost * USECS_PER_JIFFY;
+	}
+	sec = xtime.tv_sec;
+	usec += xtime.tv_usec;
+	read_unlock_irqrestore(&xtime_lock, flags);
+
+	/* usec may have gone up a lot: be safe */
+	while (usec >= 1000000) {
+		usec -= 1000000;
+		sec++;
+	}
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	write_lock_irq(&xtime_lock);
+	/* This is revolting. We need to set the xtime.tv_usec
+	 * correctly. However, the value in this location is
+	 * is value at the last tick.
+	 * Discover what correction gettimeofday
+	 * would have done, and then undo it!
+	 */
+	tv->tv_usec -= gettimeoffset();
+	tv->tv_usec -= (jiffies - wall_jiffies) * USECS_PER_JIFFY;
+
+	while (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+
+	xtime = *tv;
+	time_adjust = 0;		/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+	write_unlock_irq(&xtime_lock);
+}
+
+static struct irqaction timer_irq = {
+	name: "timer",
+	flags: SA_INTERRUPT,
+};
+
+/*
+ * Include architecture specific code
+ */
+#include <asm/arch/time.h>
+
+/*
+ * This must cause the timer to start ticking.
+ * It doesn't have to set the current time though
+ * from an RTC - it can be done later once we have
+ * some buses initialised.
+ */
+void __init time_init(void)
+{
+	xtime.tv_usec = 0;
+	xtime.tv_sec  = 0;
+
+	setup_timer();
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/traps.c linux-2.4.29-uc1/arch/armnommu/kernel/traps.c
--- linux-2.4.29/arch/armnommu/kernel/traps.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/traps.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,595 @@
+/*
+ *  linux/arch/arm/kernel/traps.c
+ *
+ *  Copyright (C) 1995, 1996 Russell King
+ *  Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  'traps.c' handles hardware exceptions after we have saved some state in
+ *  'linux/arch/arm/lib/traps.S'.  Mostly a debugging aid, but will probably
+ *  kill the offending process.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/personality.h>
+#include <linux/ptrace.h>
+#include <linux/elf.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/atomic.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+
+#include "ptrace.h"
+
+extern void c_backtrace (unsigned long fp, int pmode);
+extern void show_pte(struct mm_struct *mm, unsigned long addr);
+
+const char *processor_modes[]=
+{ "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
+  "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
+  "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" ,
+  "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
+};
+
+static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
+
+/*
+ * Stack pointers should always be within the kernels view of
+ * physical memory.  If it is not there, then we can't dump
+ * out any information relating to the stack.
+ */
+static int verify_stack(unsigned long sp)
+{
+	if (sp < PAGE_OFFSET || sp > (unsigned long)high_memory)
+		return -EFAULT;
+
+	return 0;
+}
+
+/*
+ * Dump out the contents of some memory nicely...
+ */
+void dump_mem(unsigned long bottom, unsigned long top)
+{
+	unsigned long p = bottom & ~31;
+	int i;
+
+	for (p = bottom & ~31; p < top;) {
+		printk("%08lx: ", p);
+
+		for (i = 0; i < 8; i++, p += 4) {
+			unsigned int val;
+
+			if (p < bottom || p >= top)
+				printk("         ");
+			else {
+				__get_user(val, (unsigned long *)p);
+				printk("%08x ", val);
+			}
+			if (i == 3)
+				printk(" ");
+		}
+		printk ("\n");
+	}
+}
+
+/*
+ * These constants are for searching for possible module text
+ * segments.  VMALLOC_OFFSET comes from mm/vmalloc.c; MODULE_RANGE is
+ * a guess of how much space is likely to be vmalloced.
+ */
+#define VMALLOC_OFFSET (8*1024*1024)
+#define MODULE_RANGE (8*1024*1024)
+
+static void dump_instr(struct pt_regs *regs)
+{
+	unsigned long addr = instruction_pointer(regs);
+	const int thumb = thumb_mode(regs);
+	const int width = thumb ? 4 : 8;
+	int i;
+
+	printk("Code: ");
+	for (i = -2; i < 3; i++) {
+		unsigned int val, bad;
+
+		if (thumb)
+			bad = __get_user(val, &((u16 *)addr)[i]);
+		else
+			bad = __get_user(val, &((u32 *)addr)[i]);
+
+		if (!bad)
+			printk(i == 0 ? "(%0*x) " : "%0*x ", width, val);
+		else {
+			printk("bad PC value.");
+			break;
+		}
+	}
+	printk("\n");
+}
+
+static void dump_tsk_stack(struct task_struct *tsk, unsigned long sp)
+{
+	printk("Stack:\n");
+	dump_mem(sp - 16, 8192+(unsigned long)tsk);
+}
+
+static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
+{
+	unsigned int fp;
+	int ok = 1;
+
+	printk("Backtrace: ");
+	fp = regs->ARM_fp;
+	if (!fp) {
+		printk("no frame pointer");
+		ok = 0;
+	} else if (verify_stack(fp)) {
+		printk("invalid frame pointer 0x%08x", fp);
+		ok = 0;
+	} else if (fp < 4096+(unsigned long)tsk)
+		printk("frame pointer underflow");
+	printk("\n");
+
+	if (ok)
+		c_backtrace(fp, processor_mode(regs));
+}
+
+/*
+ * This is called from SysRq-T (show_task) to display the current
+ * call trace for each process.  Very useful.
+ */
+void show_trace_task(struct task_struct *tsk)
+{
+	if (tsk != current) {
+		unsigned int fp = tsk->thread.save->fp;
+		c_backtrace(fp, 0x10);
+	}
+}
+
+spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * This function is protected against re-entrancy.
+ */
+NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
+{
+	struct task_struct *tsk = current;
+
+	console_verbose();
+	spin_lock_irq(&die_lock);
+
+	printk("Internal error: %s: %x\n", str, err);
+	printk("CPU: %d\n", smp_processor_id());
+	show_regs(regs);
+	printk("Process %s (pid: %d, stackpage=%08lx)\n",
+		current->comm, current->pid, 4096+(unsigned long)tsk);
+
+	if (!user_mode(regs) || in_interrupt()) {
+		mm_segment_t fs;
+
+		/*
+		 * We need to switch to kernel mode so that we can
+		 * use __get_user to safely read from kernel space.
+		 * Note that we now dump the code first, just in case
+		 * the backtrace kills us.
+		 */
+		fs = get_fs();
+		set_fs(KERNEL_DS);
+
+		dump_tsk_stack(tsk, (unsigned long)(regs + 1));
+		dump_backtrace(regs, tsk);
+		dump_instr(regs);
+
+		set_fs(fs);
+	}
+
+	spin_unlock_irq(&die_lock);
+	do_exit(SIGSEGV);
+}
+
+void die_if_kernel(const char *str, struct pt_regs *regs, int err)
+{
+	if (user_mode(regs))
+    		return;
+
+    	die(str, regs, err);
+}
+
+asmlinkage void do_undefinstr(int address, struct pt_regs *regs, int mode)
+{
+	unsigned long *pc;
+	siginfo_t info;
+
+	/*
+	 * According to the ARM ARM, PC is 2 or 4 bytes ahead, depending
+	 * whether we're in Thumb mode or not.
+	 */
+	regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
+	pc = (unsigned long *)instruction_pointer(regs);
+
+#ifdef CONFIG_DEBUG_USER
+	printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
+		current->comm, current->pid, pc);
+	dump_instr(regs);
+#endif
+
+	current->thread.error_code = 0;
+	current->thread.trap_no = 6;
+
+	info.si_signo = SIGILL;
+	info.si_errno = 0;
+	info.si_code  = ILL_ILLOPC;
+	info.si_addr  = pc;
+
+	force_sig_info(SIGILL, &info, current);
+
+	die_if_kernel("Oops - undefined instruction", regs, mode);
+}
+
+#ifdef CONFIG_CPU_26
+asmlinkage void do_excpt(int address, struct pt_regs *regs, int mode)
+{
+	siginfo_t info;
+
+#ifdef CONFIG_DEBUG_USER
+	printk(KERN_INFO "%s (%d): address exception: pc=%08lx\n",
+		current->comm, current->pid, instruction_pointer(regs));
+	dump_instr(regs);
+#endif
+
+	current->thread.error_code = 0;
+	current->thread.trap_no = 11;
+
+	info.si_signo = SIGBUS;
+	info.si_errno = 0;
+	info.si_code  = BUS_ADRERR;
+	info.si_addr  = (void *)address;
+
+	force_sig_info(SIGBUS, &info, current);
+
+	die_if_kernel("Oops - address exception", regs, mode);
+}
+#endif
+
+asmlinkage void do_unexp_fiq (struct pt_regs *regs)
+{
+#ifndef CONFIG_IGNORE_FIQ
+	printk("Hmm.  Unexpected FIQ received, but trying to continue\n");
+	printk("You may have a hardware problem...\n");
+#endif
+}
+
+/*
+ * bad_mode handles the impossible case in the vectors.  If you see one of
+ * these, then it's extremely serious, and could mean you have buggy hardware.
+ * It never returns, and never tries to sync.  We hope that we can at least
+ * dump out some state information...
+ */
+asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
+{
+	unsigned int vectors = vectors_base();
+	mm_segment_t fs;
+
+	console_verbose();
+
+	printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n",
+		handler[reason], processor_modes[proc_mode]);
+
+	/*
+	 * We need to switch to kernel mode so that we can
+	 * use __get_user to safely read from kernel space.
+	 * Note that we now dump the code first, just in case
+	 * the backtrace kills us.
+	 */
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+
+	/*
+	 * Dump out the vectors and stub routines.  Maybe a better solution
+	 * would be to dump them out only if we detect that they are corrupted.
+	 */
+	printk(KERN_CRIT "Vectors:\n");
+	dump_mem(vectors, 0x40);
+	printk(KERN_CRIT "Stubs:\n");
+	dump_mem(vectors + 0x200, 0x4b8);
+
+	set_fs(fs);
+
+	die("Oops", regs, 0);
+	cli();
+	panic("bad mode");
+}
+
+static int bad_syscall(int n, struct pt_regs *regs)
+{
+	siginfo_t info;
+
+	/* You might think just testing `handler' would be enough, but PER_LINUX
+	 * points it to no_lcall7 to catch undercover SVr4 binaries.  Gutted.
+	 */
+	if (current->personality != PER_LINUX && current->exec_domain->handler) {
+		/* Hand it off to iBCS.  The extra parameter and consequent type 
+		 * forcing is necessary because of the weird ARM calling convention.
+		 */
+		current->exec_domain->handler(n, regs);
+		return regs->ARM_r0;
+	}
+
+#ifdef CONFIG_DEBUG_USER
+	printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
+		current->pid, current->comm, n);
+	dump_instr(regs);
+#endif
+
+	info.si_signo = SIGILL;
+	info.si_errno = 0;
+	info.si_code  = ILL_ILLTRP;
+	info.si_addr  = (void *)instruction_pointer(regs) -
+			 (thumb_mode(regs) ? 2 : 4);
+
+	force_sig_info(SIGILL, &info, current);
+	die_if_kernel("Oops", regs, n);
+	return regs->ARM_r0;
+}
+
+/*
+ * Handle all unrecognised system calls.
+ *  0x9f0000 - 0x9fffff are some more esoteric system calls
+ */
+#define NR(x) ((__ARM_NR_##x) - __ARM_NR_BASE)
+asmlinkage int arm_syscall(int no, struct pt_regs *regs)
+{
+	siginfo_t info;
+
+	if ((no >> 16) != 0x9f)
+		return bad_syscall(no, regs);
+
+	switch (no & 0xffff) {
+	case 0: /* branch through 0 */
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		info.si_code  = SEGV_MAPERR;
+		info.si_addr  = NULL;
+
+		force_sig_info(SIGSEGV, &info, current);
+
+		die_if_kernel("branch through zero", regs, 0);
+		return 0;
+
+	case NR(breakpoint): /* SWI BREAK_POINT */
+		/*
+		 * The PC is always left pointing at the next
+		 * instruction.  Fix this.
+		 */
+		regs->ARM_pc -= 4;
+		__ptrace_cancel_bpt(current);
+
+		info.si_signo = SIGTRAP;
+		info.si_errno = 0;
+		info.si_code  = TRAP_BRKPT;
+		info.si_addr  = (void *)instruction_pointer(regs) -
+				 (thumb_mode(regs) ? 2 : 4);
+
+		force_sig_info(SIGTRAP, &info, current);
+		return regs->ARM_r0;
+
+#ifdef CONFIG_CPU_32
+	/*
+	 * Flush a region from virtual address 'r0' to virtual address 'r1'
+	 * _inclusive_.  There is no alignment requirement on either address;
+	 * user space does not need to know the hardware cache layout.
+	 *
+	 * r2 contains flags.  It should ALWAYS be passed as ZERO until it
+	 * is defined to be something else.  For now we ignore it, but may
+	 * the fires of hell burn in your belly if you break this rule. ;)
+	 *
+	 * (at a later date, we may want to allow this call to not flush
+	 * various aspects of the cache.  Passing '0' will guarantee that
+	 * everything necessary gets flushed to maintain consistency in
+	 * the specified region).
+	 */
+	case NR(cacheflush):
+		cpu_cache_clean_invalidate_range(regs->ARM_r0, regs->ARM_r1, 1);
+		return 0;
+
+	case NR(usr26):
+		if (!(elf_hwcap & HWCAP_26BIT))
+			break;
+		regs->ARM_cpsr &= ~0x10;
+		return regs->ARM_r0;
+
+	case NR(usr32):
+		if (!(elf_hwcap & HWCAP_26BIT))
+			break;
+		regs->ARM_cpsr |= 0x10;
+		return regs->ARM_r0;
+#else
+	case NR(cacheflush):
+		return 0;
+
+	case NR(usr26):
+	case NR(usr32):
+		break;
+#endif
+
+	default:
+		/* Calls 9f00xx..9f07ff are defined to return -ENOSYS
+		   if not implemented, rather than raising SIGILL.  This
+		   way the calling program can gracefully determine whether
+		   a feature is supported.  */
+		if (no <= 0x7ff)
+			return -ENOSYS;
+		break;
+	}
+#ifdef CONFIG_DEBUG_USER
+	/*
+	 * experience shows that these seem to indicate that
+	 * something catastrophic has happened
+	 */
+	printk("[%d] %s: arm syscall %d\n", current->pid, current->comm, no);
+	dump_instr(regs);
+	if (user_mode(regs)) {
+		show_regs(regs);
+		c_backtrace(regs->ARM_fp, processor_mode(regs));
+	}
+#endif
+	info.si_signo = SIGILL;
+	info.si_errno = 0;
+	info.si_code  = ILL_ILLTRP;
+	info.si_addr  = (void *)instruction_pointer(regs) -
+			 (thumb_mode(regs) ? 2 : 4);
+
+	force_sig_info(SIGILL, &info, current);
+	die_if_kernel("Oops", regs, no);
+	return 0;
+}
+
+void __bad_xchg(volatile void *ptr, int size)
+{
+	printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
+		__builtin_return_address(0), ptr, size);
+	BUG();
+}
+
+/*
+ * A data abort trap was taken, but we did not handle the instruction.
+ * Try to abort the user program, or panic if it was the kernel.
+ */
+asmlinkage void
+baddataabort(int code, unsigned long instr, struct pt_regs *regs)
+{
+	unsigned long addr = instruction_pointer(regs);
+	siginfo_t info;
+
+#ifdef CONFIG_DEBUG_USER
+	printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
+		current->pid, current->comm, code, instr);
+	dump_instr(regs);
+	show_pte(current->mm, addr);
+#endif
+
+	info.si_signo = SIGILL;
+	info.si_errno = 0;
+	info.si_code  = ILL_ILLOPC;
+	info.si_addr  = (void *)addr;
+
+	force_sig_info(SIGILL, &info, current);
+	die_if_kernel("unknown data abort code", regs, instr);
+}
+
+void __bug(const char *file, int line, void *data)
+{
+	printk(KERN_CRIT"kernel BUG at %s:%d!", file, line);
+	if (data)
+		printk(KERN_CRIT" - extra data = %p", data);
+	printk("\n");
+	*(int *)0 = 0;
+}
+
+void __readwrite_bug(const char *fn)
+{
+	printk("%s called, but not implemented", fn);
+	BUG();
+}
+
+void __pte_error(const char *file, int line, unsigned long val)
+{
+	printk("%s:%d: bad pte %08lx.\n", file, line, val);
+}
+
+void __pmd_error(const char *file, int line, unsigned long val)
+{
+	printk("%s:%d: bad pmd %08lx.\n", file, line, val);
+}
+
+void __pgd_error(const char *file, int line, unsigned long val)
+{
+	printk("%s:%d: bad pgd %08lx.\n", file, line, val);
+}
+
+asmlinkage void __div0(void)
+{
+	printk("Division by zero in kernel.\n");
+	__backtrace();
+}
+
+void abort(void)
+{
+	void *lr = __builtin_return_address(0);
+
+	printk(KERN_CRIT "abort() called from %p!  (Please "
+	       "report to rmk@arm.linux.org.uk)\n", lr);
+
+	BUG();
+
+	/* if that doesn't kill us, halt */
+	panic("Oops failed to kill thread");
+}
+
+void __init trap_init(void)
+{
+#if defined(CONFIG_ARCH_POLDHU) || defined(CONFIG_ARCH_ISL3893)
+#ifdef ISL3893_NO_MVC
+	extern void __trap_init(void *);
+
+	printk("3893: Initializing Vectors at address 0...");
+	/* Put the vectors at address 0 */
+	__trap_init((void *)0);
+	printk("Done\n");
+#else /* ISL3893_NO_MVC */
+	/*
+	 * this is put into the MAC Virtual Coprocessor
+	 */
+	extern void(*vector_undefinstr)(void);
+	extern void(*vector_swi)(void);
+	extern void(*vector_prefetch)(void);
+	extern void(*vector_data)(void);
+	extern void(*vector_IRQ)(void);
+
+	int ret;
+	static struct msg_init blob_init_msg;
+
+	blob_init_msg.und_handler = (void(*)(void))&vector_undefinstr;
+	blob_init_msg.swi_handler = (void(*)(void))&vector_swi;
+	blob_init_msg.prf_handler = (void(*)(void))&vector_prefetch;
+	blob_init_msg.dat_handler = (void(*)(void))&vector_data;
+	blob_init_msg.irq_handler = (void(*)(void))&vector_IRQ;
+
+	ret = blob_init(&blob_init_msg);
+	if(ret < 0) {
+		printk(KERN_CRIT "Could not initialize MVC (code %d)\n", ret);
+		panic("MVC init failed");
+	}
+#endif /* ISL3893_NO_MVC */
+
+#else /* !POLDHU/ISL3893 */
+	extern void __trap_init(void *);
+
+	__trap_init((void *)vectors_base());
+	if (vectors_base() != 0)
+		printk(KERN_DEBUG "Relocating machine vectors to 0x%08x\n",
+			vectors_base());
+#endif /* POLDHU/ISL3893 */
+
+#ifdef CONFIG_CPU_32
+	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
+#endif
+
+#ifdef	CONFIG_UCBOOTSTRAP
+	*(volatile unsigned int *)4 = 0xE59FF038;
+#endif
+
+}
diff -urN linux-2.4.29/arch/armnommu/kernel/via82c505.c linux-2.4.29-uc1/arch/armnommu/kernel/via82c505.c
--- linux-2.4.29/arch/armnommu/kernel/via82c505.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/kernel/via82c505.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,178 @@
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+
+#include <asm/mach/pci.h>
+
+#define MAX_SLOTS		7
+
+#define CONFIG_CMD(dev, where)   (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3))
+
+static int
+via82c505_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	outl(CONFIG_CMD(dev,where),0xCF8);
+	*value=inb(0xCFC + (where&3));
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+via82c505_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	outl(CONFIG_CMD(dev,where),0xCF8);
+	*value=inw(0xCFC + (where&2));
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+via82c505_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	outl(CONFIG_CMD(dev,where),0xCF8);
+	*value=inl(0xCFC);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+via82c505_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	outl(CONFIG_CMD(dev,where),0xCF8);
+	outb(value, 0xCFC + (where&3));
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+via82c505_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	outl(CONFIG_CMD(dev,where),0xCF8);
+	outw(value, 0xCFC + (where&2));
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+via82c505_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	outl(CONFIG_CMD(dev,where),0xCF8);
+	outl(value, 0xCFC);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops via82c505_ops = {
+	via82c505_read_config_byte,
+	via82c505_read_config_word,
+	via82c505_read_config_dword,
+	via82c505_write_config_byte,
+	via82c505_write_config_word,
+	via82c505_write_config_dword,
+};
+
+#ifdef CONFIG_ARCH_SHARK
+
+static char size_wanted;
+
+static int
+dummy_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	*value=0;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+dummy_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	*value=0;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+dummy_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	if (dev->devfn != 0) *value = 0;
+	else
+	  switch(where) {
+	  case PCI_VENDOR_ID:
+	    *value = PCI_VENDOR_ID_INTERG | PCI_DEVICE_ID_INTERG_2010 << 16;
+	    break;
+	  case PCI_CLASS_REVISION:
+	    *value = PCI_CLASS_DISPLAY_VGA << 16;
+	    break;
+	  case PCI_BASE_ADDRESS_0:
+	    if (size_wanted) {
+	      /* 0x00900000 bytes long (0xff700000) */
+	      *value = 0xff000000;
+	      size_wanted = 0;
+	    } else {
+	      *value = FB_START;
+	    }
+	    break;
+	  case PCI_INTERRUPT_LINE:
+	    *value = 6;
+	    break;
+	  default:
+	    *value = 0;
+	  }
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+dummy_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+dummy_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+dummy_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	if ((dev->devfn == 0) && (where == PCI_BASE_ADDRESS_0) && (value == 0xffffffff))
+	  size_wanted = 1;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops dummy_ops = {
+	dummy_read_config_byte,
+	dummy_read_config_word,
+	dummy_read_config_dword,
+	dummy_write_config_byte,
+	dummy_write_config_word,
+	dummy_write_config_dword,
+};
+#endif
+
+void __init via82c505_init(struct arm_pci_sysdata *sysdata)
+{
+	struct pci_bus *bus;
+
+	printk(KERN_DEBUG "PCI: VIA 82c505\n");
+	request_region(0xA8,2,"via config");
+	request_region(0xCF8,8,"pci config");
+
+	/* Enable compatible Mode */
+	outb(0x96,0xA8);
+	outb(0x18,0xA9);
+	outb(0x93,0xA8);
+	outb(0xd0,0xA9);
+
+	pci_scan_bus(0, &via82c505_ops, sysdata);
+
+#ifdef CONFIG_ARCH_SHARK
+	/* 
+	 * Initialize a fake pci-bus number 1 for the CyberPro
+         * on the vlbus
+	 */
+	bus = pci_scan_bus(1, &dummy_ops, sysdata);
+#endif
+}
diff -urN linux-2.4.29/arch/armnommu/lib/backtrace.S linux-2.4.29-uc1/arch/armnommu/lib/backtrace.S
--- linux-2.4.29/arch/armnommu/lib/backtrace.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/backtrace.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,122 @@
+/*
+ *  linux/arch/arm/lib/backtrace.S
+ *
+ *  Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+		.text
+
+@ fp is 0 or stack frame
+
+#define frame	r4
+#define next	r5
+#define save	r6
+#define mask	r7
+#define offset	r8
+
+ENTRY(__backtrace)
+		mov	r1, #0x10
+		mov	r0, fp
+
+ENTRY(c_backtrace)
+
+#ifdef CONFIG_NO_FRAME_POINTER
+		mov	pc, lr
+#else
+
+		stmfd	sp!, {r4 - r8, lr}	@ Save an extra register so we have a location...
+#ifdef CONFIG_CPU_32
+		tst	r1, #0x10		@ 26 or 32-bit?
+		moveq	mask, #0xfc000003
+		movne	mask, #0
+#else
+		mov	mask, #0xfc000003
+#endif
+		tst	mask, r0
+		movne	r0, #0
+		movs	frame, r0
+1:		moveq	r0, #-2
+		LOADREGS(eqfd, sp!, {r4 - r8, pc})
+
+2:		stmfd	sp!, {pc}			@ calculate offset of PC in STMIA instruction
+		ldr	r0, [sp], #4
+		adr	r1, 2b - 4
+		sub	offset, r0, r1
+
+3:		tst	frame, mask			@ Check for address exceptions...
+		bne	1b
+
+		ldmda	frame, {r0, r1, r2, r3}		@ fp, sp, lr, pc
+		mov	next, r0
+
+		sub	save, r3, offset		@ Correct PC for prefetching
+		bic	save, save, mask
+		adr	r0, .Lfe
+		mov	r1, save
+		bic	r2, r2, mask
+		bl	SYMBOL_NAME(printk)
+
+		sub	r0, frame, #16
+		ldr	r1, [save, #4]
+		mov	r3, r1, lsr #10
+		ldr	r2, .Ldsi+4
+		teq	r3, r2			@ Check for stmia sp!, {args}
+		addeq	save, save, #4		@ next instruction
+		bleq	.Ldumpstm
+
+		ldr	r1, [save, #4]		@ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction
+		mov	r3, r1, lsr #10
+		ldr	r2, .Ldsi
+		teq	r3, r2
+		bleq	.Ldumpstm
+
+		teq	frame, next
+		movne	frame, next
+		teqne	frame, #0
+		bne	3b
+		LOADREGS(fd, sp!, {r4 - r8, pc})
+
+
+#define instr r4
+#define reg   r5
+#define stack r6
+
+.Ldumpstm:	stmfd	sp!, {instr, reg, stack, r7, lr}
+		mov	stack, r0
+		mov	instr, r1
+		mov	reg, #9
+		mov	r7, #0
+1:		mov	r3, #1
+		tst	instr, r3, lsl reg
+		beq	2f
+		add	r7, r7, #1
+		teq	r7, #4
+		moveq	r7, #0
+		moveq	r3, #'\n'
+		movne	r3, #' '
+		ldr	r2, [stack], #-4
+		mov	r1, reg
+		adr	r0, .Lfp
+		bl	SYMBOL_NAME(printk)
+2:		subs	reg, reg, #1
+		bpl	1b
+		teq	r7, #0
+		adrne	r0, .Lcr
+		blne	SYMBOL_NAME(printk)
+		mov	r0, stack
+		LOADREGS(fd, sp!, {instr, reg, stack, r7, pc})
+
+.Lfe:		.asciz	"Function entered at [<%p>] from [<%p>]\n"
+.Lfp:		.asciz	" r%d = %08X%c"
+.Lcr:		.asciz	"\n"
+		.align
+.Ldsi:		.word	0x00e92dd8 >> 2
+		.word	0x00e92d00 >> 2
+
+#endif
diff -urN linux-2.4.29/arch/armnommu/lib/changebit.S linux-2.4.29-uc1/arch/armnommu/lib/changebit.S
--- linux-2.4.29/arch/armnommu/lib/changebit.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/changebit.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,29 @@
+/*
+ *  linux/arch/arm/lib/changebit.S
+ *
+ *  Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+                .text
+
+/* Purpose  : Function to change a bit
+ * Prototype: int change_bit(int bit, void *addr)
+ */
+ENTRY(change_bit)
+#ifdef __ARMEB__
+		eor	r0, r0, #0x18		@ big endian byte ordering
+#endif
+		and	r2, r0, #7
+		mov	r3, #1
+		mov	r3, r3, lsl r2
+		save_and_disable_irqs ip, r2
+		ldrb	r2, [r1, r0, lsr #3]
+		eor	r2, r2, r3
+		strb	r2, [r1, r0, lsr #3]
+		restore_irqs ip
+		RETINSTR(mov,pc,lr)
diff -urN linux-2.4.29/arch/armnommu/lib/clearbit.S linux-2.4.29-uc1/arch/armnommu/lib/clearbit.S
--- linux-2.4.29/arch/armnommu/lib/clearbit.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/clearbit.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ *  linux/arch/arm/lib/clearbit.S
+ *
+ *  Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+                .text
+
+/*
+ * Purpose  : Function to clear a bit
+ * Prototype: int clear_bit(int bit, void *addr)
+ */
+
+ENTRY(clear_bit)
+#ifdef __ARMEB__
+		eor	r0, r0, #0x18		@ big endian byte ordering
+#endif
+		and	r2, r0, #7
+		mov	r3, #1
+		mov	r3, r3, lsl r2
+		save_and_disable_irqs ip, r2
+		ldrb	r2, [r1, r0, lsr #3]
+		bic	r2, r2, r3
+		strb	r2, [r1, r0, lsr #3]
+		restore_irqs ip
+		RETINSTR(mov,pc,lr)
+
+
diff -urN linux-2.4.29/arch/armnommu/lib/copy_page.S linux-2.4.29-uc1/arch/armnommu/lib/copy_page.S
--- linux-2.4.29/arch/armnommu/lib/copy_page.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/copy_page.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,38 @@
+/*
+ *  linux/arch/arm/lib/copypage.S
+ *
+ *  Copyright (C) 1995-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  ASM optimised string functions
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+
+		.text
+		.align	5
+/*
+ * StrongARM optimised copy_page routine
+ * now 1.78bytes/cycle, was 1.60 bytes/cycle (50MHz bus -> 89MB/s)
+ * Note that we probably achieve closer to the 100MB/s target with
+ * the core clock switching.
+ */
+ENTRY(copy_page)
+		stmfd	sp!, {r4, lr}			@	2
+		mov	r2, #PAGE_SZ/64			@	1
+		ldmia	r1!, {r3, r4, ip, lr}		@	4+1
+1:		stmia	r0!, {r3, r4, ip, lr}		@	4
+		ldmia	r1!, {r3, r4, ip, lr}		@	4+1
+		stmia	r0!, {r3, r4, ip, lr}		@	4
+		ldmia	r1!, {r3, r4, ip, lr}		@	4+1
+		stmia	r0!, {r3, r4, ip, lr}		@	4
+		ldmia	r1!, {r3, r4, ip, lr}		@	4
+		subs	r2, r2, #1			@	1
+		stmia	r0!, {r3, r4, ip, lr}		@	4
+		ldmneia	r1!, {r3, r4, ip, lr}		@	4
+		bne	1b				@	1
+		LOADREGS(fd, sp!, {r4, pc})		@	3
diff -urN linux-2.4.29/arch/armnommu/lib/csumipv6.S linux-2.4.29-uc1/arch/armnommu/lib/csumipv6.S
--- linux-2.4.29/arch/armnommu/lib/csumipv6.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/csumipv6.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ *  linux/arch/arm/lib/csumipv6.S
+ *
+ *  Copyright (C) 1995-1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+		.text
+
+ENTRY(__csum_ipv6_magic)
+		str	lr, [sp, #-4]!
+		adds	ip, r2, r3
+		ldmia	r1, {r1 - r3, lr}
+		adcs	ip, ip, r1
+		adcs	ip, ip, r2
+		adcs	ip, ip, r3
+		adcs	ip, ip, lr
+		ldmia	r0, {r0 - r3}
+		adcs	r0, ip, r0
+		adcs	r0, r0, r1
+		adcs	r0, r0, r2
+		ldr	r2, [sp, #4]
+		adcs	r0, r0, r3
+		adcs	r0, r0, r2
+		adcs	r0, r0, #0
+		LOADREGS(fd, sp!, {pc})
+
diff -urN linux-2.4.29/arch/armnommu/lib/csumpartialcopygeneric.S linux-2.4.29-uc1/arch/armnommu/lib/csumpartialcopygeneric.S
--- linux-2.4.29/arch/armnommu/lib/csumpartialcopygeneric.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/csumpartialcopygeneric.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,411 @@
+/*
+ *  linux/arch/arm/lib/csumpartialcopygeneric.S
+ *
+ *  Copyright (C) 1995-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * - added big endian stuff (Daniel Versick - 2002)
+ */
+
+/*
+ * unsigned int
+ * csum_partial_copy_xxx(const char *src, char *dst, int len, int sum, )
+ *  r0 = src, r1 = dst, r2 = len, r3 = sum
+ *  Returns : r0 = checksum
+ *
+ * Note that 'tst' and 'teq' preserve the carry flag.
+ */
+
+src	.req	r0
+dst	.req	r1
+len	.req	r2
+sum	.req	r3
+
+.zero:		mov	r0, sum
+		load_regs	ea
+
+		/*
+		 * Align an unaligned destination pointer.  We know that
+		 * we have >= 8 bytes here, so we don't need to check
+		 * the length.  Note that the source pointer hasn't been
+		 * aligned yet.
+		 */
+.dst_unaligned:	tst	dst, #1
+		beq	.dst_16bit
+
+		load1b	ip
+		sub	len, len, #1
+#ifndef __ARMEB__
+		adcs	sum, sum, ip, lsl #8	@ update checksum
+#else
+		adcs	sum, sum, ip		@ update checksum
+#endif
+		strb	ip, [dst], #1
+		tst	dst, #2
+		moveq	pc, lr			@ dst is now 32bit aligned
+
+.dst_16bit:	load2b	r8, ip
+		sub	len, len, #2
+#ifndef __ARMEB__
+		adcs	sum, sum, r8
+		strb	r8, [dst], #1
+		adcs	sum, sum, ip, lsl #8
+#else
+		adcs	sum, sum, r8, lsl #8
+		strb	r8, [dst], #1
+		adcs	sum, sum, ip
+#endif
+		strb	ip, [dst], #1
+		mov	pc, lr			@ dst is now 32bit aligned
+
+		/*
+		 * Handle 0 to 7 bytes, with any alignment of source and
+		 * destination pointers.  Note that when we get here, C = 0
+		 */
+.less8:		teq	len, #0			@ check for zero count
+		beq	.zero
+
+		/* we must have at least one byte. */
+		tst	dst, #1			@ dst 16-bit aligned
+		beq	.less8_aligned
+
+		/* Align dst */
+		load1b	ip
+		sub	len, len, #1
+#ifndef __ARMEB__
+		adcs	sum, sum, ip, lsl #8	@ update checksum
+#else
+		adcs	sum, sum, ip		@ update checksum
+#endif
+		strb	ip, [dst], #1
+		tst	len, #6
+		beq	.less8_byteonly
+
+1:		load2b	r8, ip
+		sub	len, len, #2
+#ifndef __ARMEB__
+		adcs	sum, sum, r8
+		strb	r8, [dst], #1
+		adcs	sum, sum, ip, lsl #8
+#else
+		adcs	sum, sum, r8, lsl #8
+		strb	r8, [dst], #1
+		adcs	sum, sum, ip
+#endif
+		strb	ip, [dst], #1
+.less8_aligned:	tst	len, #6
+		bne	1b
+.less8_byteonly:
+		tst	len, #1
+		beq	.done
+		load1b	r8
+#ifndef __ARMEB__
+		adcs	sum, sum, r8		@ update checksum
+#else
+		adcs	sum, sum, r8, lsl #8	@ update checksum
+#endif
+		strb	r8, [dst], #1
+		b	.done
+
+FN_ENTRY
+		mov	ip, sp
+		save_regs
+		sub	fp, ip, #4
+
+		cmp	len, #8			@ Ensure that we have at least
+		blo	.less8			@ 8 bytes to copy.
+
+		adds	sum, sum, #0		@ C = 0
+		tst	dst, #3			@ Test destination alignment
+		blne	.dst_unaligned		@ align destination, return here
+
+		/*
+		 * Ok, the dst pointer is now 32bit aligned, and we know
+		 * that we must have more than 4 bytes to copy.  Note
+		 * that C contains the carry from the dst alignment above.
+		 */
+
+		tst	src, #3			@ Test source alignment
+		bne	.src_not_aligned
+
+		/* Routine for src & dst aligned */
+
+		bics	ip, len, #15
+		beq	2f
+
+1:		load4l	r4, r5, r6, r7
+		stmia	dst!, {r4, r5, r6, r7}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		adcs	sum, sum, r6
+		adcs	sum, sum, r7
+		sub	ip, ip, #16
+		teq	ip, #0
+		bne	1b
+
+2:		ands	ip, len, #12
+		beq	4f
+		tst	ip, #8
+		beq	3f
+		load2l	r4, r5
+		stmia	dst!, {r4, r5}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		tst	ip, #4
+		beq	4f
+
+3:		load1l	r4
+		str	r4, [dst], #4
+		adcs	sum, sum, r4
+
+4:		ands	len, len, #3
+		beq	.done
+		load1l	r4
+		tst	len, #2
+		beq	.exit
+#ifndef __ARMEB__
+		adcs	sum, sum, r4, lsl #16
+		strb	r4, [dst], #1
+		mov	r4, r4, lsr #8
+		strb	r4, [dst], #1
+		mov	r4, r4, lsr #8
+#else
+		mov	r5, r4, lsr #16
+		mov	r5, r5, lsl #16
+		adcs	sum, sum, r5
+		mov	r4, r4, ror #24
+		strb	r4, [dst], #1
+		bic	r4, r4, #255
+		mov	r4, r4, ror #24
+		strb	r4, [dst], #1
+#endif
+.exit:
+#ifdef	__ARMEB__
+		bic	r4, r4, #255
+		mov	r4, r4, ror #24
+#endif
+		tst	len, #1
+		strneb	r4, [dst], #1
+		andne	r4, r4, #255
+#ifndef __ARMEB__
+		adcnes	sum, sum, r4
+#else
+		adcnes	sum, sum, r4, lsl #8	@ TODO: check this
+#endif
+
+		/*
+		 * If the dst pointer was not 16-bit aligned, we
+		 * need to rotate the checksum here to get around
+		 * the inefficient byte manipulations in the
+		 * architecture independent code.
+		 */
+.done:		adc	r0, sum, #0
+		ldr	sum, [sp, #0]		@ dst
+		tst	sum, #1
+		movne	sum, r0, lsl #8
+		orrne	r0, sum, r0, lsr #24
+		load_regs	ea
+
+.src_not_aligned:
+		adc	sum, sum, #0		@ include C from dst alignment
+		and	ip, src, #3
+		bic	src, src, #3
+		load1l	r4
+		cmp	ip, #2
+		beq	.src2_aligned
+		bhi	.src3_aligned
+		mov	r4, r4, pull #8		@ C = 0
+		bics	ip, len, #15
+		beq	2f
+1:		load4l	r5, r6, r7, r8
+		orr	r4, r4, r5, push #24
+		mov	r5, r5, pull #8
+		orr	r5, r5, r6, push #24
+		mov	r6, r6, pull #8
+		orr	r6, r6, r7, push #24
+		mov	r7, r7, pull #8
+		orr	r7, r7, r8, push #24
+		stmia	dst!, {r4, r5, r6, r7}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		adcs	sum, sum, r6
+		adcs	sum, sum, r7
+		mov	r4, r8, pull #8
+		sub	ip, ip, #16
+		teq	ip, #0
+		bne	1b
+2:		ands	ip, len, #12
+		beq	4f
+		tst	ip, #8
+		beq	3f
+		load2l	r5, r6
+		orr	r4, r4, r5, push #24
+		mov	r5, r5, pull #8
+		orr	r5, r5, r6, push #24
+		stmia	dst!, {r4, r5}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		mov	r4, r6, pull #8
+		tst	ip, #4
+		beq	4f
+3:		load1l	r5
+		orr	r4, r4, r5, push #24
+		str	r4, [dst], #4
+		adcs	sum, sum, r4
+		mov	r4, r5, pull #8
+4:		ands	len, len, #3
+		beq	.done
+		tst	len, #2
+		beq	.exit
+#ifndef __ARMEB__
+		adcs	sum, sum, r4, lsl #16
+		strb	r4, [dst], #1
+		mov	r4, r4, lsr #8
+		strb	r4, [dst], #1
+		mov	r4, r4, lsr #8
+#else
+		mov	r5, r4, lsr #16
+		mov	r5, r5, lsl #16
+		adcs	sum, sum, r5
+		mov	r4, r4, ror #24
+		strb	r4, [dst], #1
+		bic	r4, r4, #255
+		mov	r4, r4, ror #24
+		strb	r4, [dst], #1
+#endif
+		b	.exit
+
+.src2_aligned:
+		mov	r4, r4, pull #16
+		adds	sum, sum, #0
+		bics	ip, len, #15
+		beq	2f
+1:		load4l	r5, r6, r7, r8
+		orr	r4, r4, r5, push #16
+		mov	r5, r5, pull #16
+		orr	r5, r5, r6, push #16
+		mov	r6, r6, pull #16
+		orr	r6, r6, r7, push #16
+		mov	r7, r7, pull #16
+		orr	r7, r7, r8, push #16
+		stmia	dst!, {r4, r5, r6, r7}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		adcs	sum, sum, r6
+		adcs	sum, sum, r7
+		mov	r4, r8, pull #16
+		sub	ip, ip, #16
+		teq	ip, #0
+		bne	1b
+2:		ands	ip, len, #12
+		beq	4f
+		tst	ip, #8
+		beq	3f
+		load2l	r5, r6
+		orr	r4, r4, r5, push #16
+		mov	r5, r5, pull #16
+		orr	r5, r5, r6, push #16
+		stmia	dst!, {r4, r5}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		mov	r4, r6, pull #16
+		tst	ip, #4
+		beq	4f
+3:		load1l	r5
+		orr	r4, r4, r5, push #16
+		str	r4, [dst], #4
+		adcs	sum, sum, r4
+		mov	r4, r5, pull #16
+4:		ands	len, len, #3
+		beq	.done
+		tst	len, #2
+		beq	.exit
+#ifndef __ARMEB__
+		adcs	sum, sum, r4, lsl #16
+		strb	r4, [dst], #1
+		mov	r4, r4, lsr #8
+		strb	r4, [dst], #1
+#else
+		mov	r5, r4, lsr #16
+		mov	r5, r5, lsl #16
+		adcs	sum, sum, r5
+		mov	r4, r4, ror #24
+		strb	r4, [dst], #1
+		bic	r4, r4, #255
+		mov	r4, r4, ror #24
+		strb	r4, [dst], #1
+#endif
+		tst	len, #1
+		beq	.done
+		load1b	r4
+		b	.exit
+
+.src3_aligned:
+		mov	r4, r4, pull #24
+		adds	sum, sum, #0
+		bics	ip, len, #15
+		beq	2f
+1:		load4l	r5, r6, r7, r8
+		orr	r4, r4, r5, push #8
+		mov	r5, r5, pull #24
+		orr	r5, r5, r6, push #8
+		mov	r6, r6, pull #24
+		orr	r6, r6, r7, push #8
+		mov	r7, r7, pull #24
+		orr	r7, r7, r8, push #8
+		stmia	dst!, {r4, r5, r6, r7}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		adcs	sum, sum, r6
+		adcs	sum, sum, r7
+		mov	r4, r8, pull #24
+		sub	ip, ip, #16
+		teq	ip, #0
+		bne	1b
+2:		ands	ip, len, #12
+		beq	4f
+		tst	ip, #8
+		beq	3f
+		load2l	r5, r6
+		orr	r4, r4, r5, push #8
+		mov	r5, r5, pull #24
+		orr	r5, r5, r6, push #8
+		stmia	dst!, {r4, r5}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		mov	r4, r6, pull #24
+		tst	ip, #4
+		beq	4f
+3:		load1l	r5
+		orr	r4, r4, r5, push #8
+		str	r4, [dst], #4
+		adcs	sum, sum, r4
+		mov	r4, r5, pull #24
+4:		ands	len, len, #3
+		beq	.done
+		tst	len, #2
+		beq	.exit
+#ifndef __ARMEB__
+		adcs	sum, sum, r4, lsl #16
+		strb	r4, [dst], #1
+		load1l	r4
+		strb	r4, [dst], #1
+		adcs	sum, sum, r4, lsl #24
+		mov	r4, r4, lsr #8
+#else
+		mov	r5, r4, lsr #16
+		mov	r5, r5, lsl #16
+		adcs	sum, sum, r5
+		mov	r4, r4, ror #24
+		strb	r4, [dst], #1
+		load1l	r4
+		mov	r4, r4, lsl #24
+		adcs	sum, sum, r4		/* TODO: check this again */
+		mov	r4, r4, ror #24
+		strb	r4, [dst], #1
+		bic	r4, r4, #255
+#endif
+		b	.exit
diff -urN linux-2.4.29/arch/armnommu/lib/csumpartialcopy.S linux-2.4.29-uc1/arch/armnommu/lib/csumpartialcopy.S
--- linux-2.4.29/arch/armnommu/lib/csumpartialcopy.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/csumpartialcopy.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,52 @@
+/*
+ *  linux/arch/arm/lib/csumpartialcopy.S
+ *
+ *  Copyright (C) 1995-1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+		.text
+
+/* Function: __u32 csum_partial_copy_nocheck(const char *src, char *dst, int len, __u32 sum)
+ * Params  : r0 = src, r1 = dst, r2 = len, r3 = checksum
+ * Returns : r0 = new checksum
+ */
+
+		.macro	save_regs
+		stmfd	sp!, {r1, r4 - r8, fp, ip, lr, pc}
+		.endm
+
+		.macro	load_regs,flags
+		LOADREGS(\flags,fp,{r1, r4 - r8, fp, sp, pc})
+		.endm
+
+		.macro	load1b, reg1
+		ldrb	\reg1, [r0], #1
+		.endm
+
+		.macro	load2b, reg1, reg2
+		ldrb	\reg1, [r0], #1
+		ldrb	\reg2, [r0], #1
+		.endm
+
+		.macro	load1l, reg1
+		ldr	\reg1, [r0], #4
+		.endm
+
+		.macro	load2l, reg1, reg2
+		ldr	\reg1, [r0], #4
+		ldr	\reg2, [r0], #4
+		.endm
+
+		.macro	load4l, reg1, reg2, reg3, reg4
+		ldmia	r0!, {\reg1, \reg2, \reg3, \reg4}
+		.endm
+
+#define FN_ENTRY	ENTRY(csum_partial_copy_nocheck)
+
+#include "csumpartialcopygeneric.S"
diff -urN linux-2.4.29/arch/armnommu/lib/csumpartialcopyuser.S linux-2.4.29-uc1/arch/armnommu/lib/csumpartialcopyuser.S
--- linux-2.4.29/arch/armnommu/lib/csumpartialcopyuser.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/csumpartialcopyuser.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,184 @@
+/*
+ *  linux/arch/arm/lib/csumpartialcopyuser.S
+ *
+ *  Copyright (C) 1995-1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/errno.h>
+#include <asm/constants.h>
+
+		.text
+
+#if defined(CONFIG_CPU_32)
+
+		.macro	save_regs
+		stmfd	sp!, {r1 - r2, r4 - r8, fp, ip, lr, pc}
+		.endm
+
+		.macro	load_regs,flags
+		ldm\flags	fp, {r1, r2, r4-r8, fp, sp, pc}
+		.endm
+
+		.macro	load1b,	reg1
+9999:		ldrbt	\reg1, [r0], $1
+		.section __ex_table, "a"
+		.align	3
+		.long	9999b, 6001f
+		.previous
+		.endm
+
+		.macro	load2b, reg1, reg2
+9999:		ldrbt	\reg1, [r0], $1
+9998:		ldrbt	\reg2, [r0], $1
+		.section __ex_table, "a"
+		.long	9999b, 6001f
+		.long	9998b, 6001f
+		.previous
+		.endm
+
+		.macro	load1l, reg1
+9999:		ldrt	\reg1, [r0], $4
+		.section __ex_table, "a"
+		.align	3
+		.long	9999b, 6001f
+		.previous
+		.endm
+
+		.macro	load2l, reg1, reg2
+9999:		ldrt	\reg1, [r0], $4
+9998:		ldrt	\reg2, [r0], $4
+		.section __ex_table, "a"
+		.long	9999b, 6001f
+		.long	9998b, 6001f
+		.previous
+		.endm
+
+		.macro	load4l, reg1, reg2, reg3, reg4
+9999:		ldrt	\reg1, [r0], $4
+9998:		ldrt	\reg2, [r0], $4
+9997:		ldrt	\reg3, [r0], $4
+9996:		ldrt	\reg4, [r0], $4
+		.section __ex_table, "a"
+		.long	9999b, 6001f
+		.long	9998b, 6001f
+		.long	9997b, 6001f
+		.long	9996b, 6001f
+		.previous
+		.endm
+
+#elif defined(CONFIG_CPU_26)
+
+		.macro	save_regs
+		stmfd	sp!, {r1 - r2, r4 - r9, fp, ip, lr, pc}
+		mov	r9, sp, lsr #13
+		mov	r9, r9, lsl #13
+		ldr	r9, [r9, #TSK_ADDR_LIMIT]
+		mov	r9, r9, lsr #24
+		.endm
+
+		.macro	load_regs,flags
+		ldm\flags	fp, {r1, r2, r4-r9, fp, sp, pc}^
+		.endm
+
+		.macro	load1b,	reg1
+		tst	r9, #0x01
+9999:		ldreqbt	\reg1, [r0], #1
+		ldrneb	\reg1, [r0], #1
+		.section __ex_table, "a"
+		.align	3
+		.long	9999b, 6001f
+		.previous
+		.endm
+
+		.macro	load2b, reg1, reg2
+		tst	r9, #0x01
+9999:		ldreqbt	\reg1, [r0], #1
+		ldrneb	\reg1, [r0], #1
+9998:		ldreqbt	\reg2, [r0], #1
+		ldrneb	\reg2, [r0], #1
+		.section __ex_table, "a"
+		.long	9999b, 6001f
+		.long	9998b, 6001f
+		.previous
+		.endm
+
+		.macro	load1l, reg1
+		tst	r9, #0x01
+9999:		ldreqt	\reg1, [r0], #4
+		ldrne	\reg1, [r0], #4
+		.section __ex_table, "a"
+		.align	3
+		.long	9999b, 6001f
+		.previous
+		.endm
+
+		.macro	load2l, reg1, reg2
+		tst	r9, #0x01
+		ldmneia	r0!, {\reg1, \reg2}
+9999:		ldreqt	\reg1, [r0], #4
+9998:		ldreqt	\reg2, [r0], #4
+		.section __ex_table, "a"
+		.long	9999b, 6001f
+		.long	9998b, 6001f
+		.previous
+		.endm
+
+		.macro	load4l, reg1, reg2, reg3, reg4
+		tst	r9, #0x01
+		ldmneia	r0!, {\reg1, \reg2, \reg3, \reg4}
+9999:		ldreqt	\reg1, [r0], #4
+9998:		ldreqt	\reg2, [r0], #4
+9997:		ldreqt	\reg3, [r0], #4
+9996:		ldreqt	\reg4, [r0], #4
+		.section __ex_table, "a"
+		.long	9999b, 6001f
+		.long	9998b, 6001f
+		.long	9997b, 6001f
+		.long	9996b, 6001f
+		.previous
+		.endm
+
+#else
+#error Unknown CPU architecture
+#endif
+
+/*
+ * unsigned int
+ * csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *err_ptr)
+ *  r0 = src, r1 = dst, r2 = len, r3 = sum, [sp] = *err_ptr
+ *  Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT
+ */
+
+#define FN_ENTRY	ENTRY(csum_partial_copy_from_user)
+
+#include "csumpartialcopygeneric.S"
+
+/*
+ * FIXME: minor buglet here
+ * We don't return the checksum for the data present in the buffer.  To do
+ * so properly, we would have to add in whatever registers were loaded before
+ * the fault, which, with the current asm above is not predictable.
+ */
+#if defined(CONFIG_CPU_32)
+		.section .fixup,"ax"
+#endif
+		.align	4
+6001:		mov	r4, #-EFAULT
+		ldr	r5, [fp, #4]		@ *err_ptr
+		str	r4, [r5]
+		ldmia	sp, {r1, r2}		@ retrieve dst, len
+		add	r2, r2, r1
+		mov	r0, #0			@ zero the buffer
+6002:		teq	r2, r1
+		strneb	r0, [r1], #1
+		bne	6002b
+		load_regs	ea
+#if defined(CONFIG_CPU_32)
+		.previous
+#endif
diff -urN linux-2.4.29/arch/armnommu/lib/csumpartial.S linux-2.4.29-uc1/arch/armnommu/lib/csumpartial.S
--- linux-2.4.29/arch/armnommu/lib/csumpartial.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/csumpartial.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,153 @@
+/*
+ *  linux/arch/arm/lib/csumpartial.S
+ *
+ *  Copyright (C) 1995-1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * - added big endian support (Daniel Versick - Sep 2002)
+ *
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+		.text
+
+/*
+ * Function: __u32 csum_partial(const char *src, int len, __u32 sum)
+ * Params  : r0 = buffer, r1 = len, r2 = checksum
+ * Returns : r0 = new checksum
+ */
+
+buf	.req	r0
+len	.req	r1
+sum	.req	r2
+td0	.req	r3
+td1	.req	r4	@ save before use
+td2	.req	r5	@ save before use
+td3	.req	lr
+
+.zero:		mov	r0, sum
+		add	sp, sp, #4
+		ldr	pc, [sp], #4
+
+		/*
+		 * Handle 0 to 7 bytes, with any alignment of source and
+		 * destination pointers.  Note that when we get here, C = 0
+		 */
+.less8:		teq	len, #0			@ check for zero count
+		beq	.zero
+
+		/* we must have at least one byte. */
+		tst	buf, #1			@ odd address?
+		ldrneb	td0, [buf], #1
+		subne	len, len, #1
+#ifndef __ARMEB__
+		adcnes	sum, sum, td0, lsl #8
+#else
+		adcnes	sum, sum, td0
+#endif
+
+.less4:		tst	len, #6
+		beq	.less8_byte
+
+		/* we are now half-word aligned */
+
+.less8_wordlp:
+#ifdef __ARM_ARCH_4__
+		ldrh	td0, [buf], #2
+		sub	len, len, #2
+#else
+		ldrb	td0, [buf], #1
+		ldrb	td3, [buf], #1
+		sub	len, len, #2
+# ifndef __ARMEB__
+		orr	td0, td0, td3, lsl #8
+# else
+		orr	td0, td3, td0, lsl #8
+# endif
+#endif
+		adcs	sum, sum, td0
+		tst	len, #6
+		bne	.less8_wordlp
+
+.less8_byte:	tst	len, #1			@ odd number of bytes
+		ldrneb	td0, [buf], #1		@ include last byte
+#ifndef __ARMEB__
+		adcnes	sum, sum, td0		@ update checksum
+#else
+		adcnes	sum, sum, td0, lsl #8   @update checksum
+#endif
+
+.done:		adc	r0, sum, #0		@ collect up the last carry
+		ldr	td0, [sp], #4
+		tst	td0, #1			@ check buffer alignment
+		movne	td0, r0, lsl #8		@ rotate checksum by 8 bits
+		orrne	r0, td0, r0, lsr #24
+		ldr	pc, [sp], #4		@ return
+
+.not_aligned:	tst	buf, #1			@ odd address
+		ldrneb	td0, [buf], #1		@ make even
+		subne	len, len, #1
+#ifndef __ARMEB__
+		adcnes	sum, sum, td0, lsl #8	@ update checksum
+#else
+		adcnes	sum, sum, td0		@ update checksum
+#endif
+
+		tst	buf, #2			@ 32-bit aligned?
+#ifdef __ARM_ARCH_4__
+		ldrneh	td0, [buf], #2		@ make 32-bit aligned
+		subne	len, len, #2
+#else
+		ldrneb	td0, [buf], #1
+		ldrneb	ip, [buf], #1
+		subne	len, len, #2
+# ifndef __ARMEB__
+		orrne	td0, td0, ip, lsl #8
+# else
+		orrne	td0, ip, td0, lsl #8
+# endif
+#endif
+		adcnes	sum, sum, td0		@ update checksum
+		mov	pc, lr
+
+ENTRY(csum_partial)
+		stmfd	sp!, {buf, lr}
+		cmp	len, #8			@ Ensure that we have at least
+		blo	.less8			@ 8 bytes to copy.
+
+		adds	sum, sum, #0		@ C = 0
+		tst	buf, #3			@ Test destination alignment
+		blne	.not_aligned		@ aligh destination, return here
+
+1:		bics	ip, len, #31
+		beq	3f
+
+		stmfd	sp!, {r4 - r5}
+2:		ldmia	buf!, {td0, td1, td2, td3}
+		adcs	sum, sum, td0
+		adcs	sum, sum, td1
+		adcs	sum, sum, td2
+		adcs	sum, sum, td3
+		ldmia	buf!, {td0, td1, td2, td3}
+		adcs	sum, sum, td0
+		adcs	sum, sum, td1
+		adcs	sum, sum, td2
+		adcs	sum, sum, td3
+		sub	ip, ip, #32
+		teq	ip, #0
+		bne	2b
+		ldmfd	sp!, {r4 - r5}
+
+3:		tst	len, #0x1c		@ should not change C
+		beq	.less4
+
+4:		ldr	td0, [buf], #4
+		sub	len, len, #4
+		adcs	sum, sum, td0
+		tst	len, #0x1c
+		bne	4b
+		b	.less4
diff -urN linux-2.4.29/arch/armnommu/lib/delay.S linux-2.4.29-uc1/arch/armnommu/lib/delay.S
--- linux-2.4.29/arch/armnommu/lib/delay.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/delay.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,57 @@
+/*
+ *  linux/arch/arm/lib/delay.S
+ *
+ *  Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+		.text
+
+LC0:		.word	SYMBOL_NAME(loops_per_jiffy)
+
+/*
+ * 0 <= r0 <= 2000
+ */
+ENTRY(udelay)
+		mov	r2,     #0x6800
+		orr	r2, r2, #0x00db
+		mul	r1, r0, r2
+		ldr	r2, LC0
+		ldr	r2, [r2]
+		mov	r1, r1, lsr #11
+		mov	r2, r2, lsr #11
+		mul	r0, r1, r2
+		movs	r0, r0, lsr #6
+		RETINSTR(moveq,pc,lr)
+
+/*
+ * loops = (r0 * 0x10c6 * 100 * loops_per_jiffy) / 2^32
+ *
+ * Oh, if only we had a cycle counter...
+ */
+
+@ Delay routine
+ENTRY(__delay)
+		subs	r0, r0, #1
+#if 0
+		RETINSTR(movls,pc,lr)
+		subs	r0, r0, #1
+		RETINSTR(movls,pc,lr)
+		subs	r0, r0, #1
+		RETINSTR(movls,pc,lr)
+		subs	r0, r0, #1
+		RETINSTR(movls,pc,lr)
+		subs	r0, r0, #1
+		RETINSTR(movls,pc,lr)
+		subs	r0, r0, #1
+		RETINSTR(movls,pc,lr)
+		subs	r0, r0, #1
+		RETINSTR(movls,pc,lr)
+		subs	r0, r0, #1
+#endif
+		bhi	SYMBOL_NAME(__delay)
+		RETINSTR(mov,pc,lr)
diff -urN linux-2.4.29/arch/armnommu/lib/ecard.S linux-2.4.29-uc1/arch/armnommu/lib/ecard.S
--- linux-2.4.29/arch/armnommu/lib/ecard.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/ecard.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+ *  linux/arch/arm/lib/ecard.S
+ *
+ *  Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h> /* for CONFIG_CPU_nn */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+#if defined(CONFIG_CPU_26)
+#define CPSR2SPSR(rt)
+#else
+#define CPSR2SPSR(rt) \
+		mrs	rt, cpsr; \
+		msr	spsr, rt
+#endif
+
+@ Purpose: call an expansion card loader to read bytes.
+@ Proto  : char read_loader(int offset, char *card_base, char *loader);
+@ Returns: byte read
+
+ENTRY(ecard_loader_read)
+		stmfd	sp!, {r4 - r12, lr}
+		mov	r11, r1
+		mov	r1, r0
+		CPSR2SPSR(r0)
+		mov	lr, pc
+		mov	pc, r2
+		LOADREGS(fd, sp!, {r4 - r12, pc})
+
+@ Purpose: call an expansion card loader to reset the card
+@ Proto  : void read_loader(int card_base, char *loader);
+@ Returns: byte read
+
+ENTRY(ecard_loader_reset)
+		stmfd	sp!, {r4 - r12, lr}
+		mov	r11, r0
+		CPSR2SPSR(r0)
+		mov	lr, pc
+		add	pc, r1, #8
+		LOADREGS(fd, sp!, {r4 - r12, pc})
+
diff -urN linux-2.4.29/arch/armnommu/lib/findbit.S linux-2.4.29-uc1/arch/armnommu/lib/findbit.S
--- linux-2.4.29/arch/armnommu/lib/findbit.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/findbit.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ *  linux/arch/arm/lib/findbit.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+                .text
+
+#ifndef __ARMEB__
+
+/*
+ * Purpose  : Find a 'zero' bit
+ * Prototype: int find_first_zero_bit(void *addr, int maxbit);
+ */
+ENTRY(find_first_zero_bit)
+		mov	r2, #0
+1:		ldrb	r3, [r0, r2, lsr #3]
+		eors	r3, r3, #0xff		@ invert bits
+		bne	.found			@ any now set - found zero bit
+		add	r2, r2, #8		@ next bit pointer
+		cmp	r2, r1			@ any more?
+		bcc	1b
+		add	r0, r1, #1		@ no free bits
+		RETINSTR(mov,pc,lr)
+
+/*
+ * Purpose  : Find next 'zero' bit
+ * Prototype: int find_next_zero_bit(void *addr, int maxbit, int offset)
+ */
+ENTRY(find_next_zero_bit)
+		ands	ip, r2, #7
+		beq	1b			@ If new byte, goto old routine
+		ldrb	r3, [r0, r2, lsr#3]
+		eor	r3, r3, #0xff		@ now looking for a 1 bit
+		movs	r3, r3, lsr ip		@ shift off unused bits
+		bne	.found
+		orr	r2, r2, #7		@ if zero, then no bits here
+		add	r2, r2, #1		@ align bit pointer
+		b	1b			@ loop for next bit
+
+#else /* __ARMEB__ */
+
+ENTRY(find_first_zero_bit)
+		mov	r2, #0
+1:		eor	r3, r2, #0x18		@ big endian byte ordering
+		ldrb	r3, [r0, r3, lsr #3]
+		eors	r3, r3, #0xff		@ invert bits
+		bne	.found			@ any now set - found zero bit
+		add	r2, r2, #8		@ next bit pointer
+		cmp	r2, r1			@ any more?
+		bcc	1b
+		add	r0, r1, #1		@ no free bits
+		RETINSTR(mov,pc,lr)
+
+ENTRY(find_next_zero_bit)
+		ands	ip, r2, #7
+		beq	1b			@ If new byte, goto old routine
+		eor	r3, r2, #0x18		@ big endian byte ordering
+		ldrb	r3, [r0, r3, lsr#3]
+		eor	r3, r3, #0xff		@ now looking for a 1 bit
+		movs	r3, r3, lsr ip		@ shift off unused bits
+		orreq	r2, r2, #7		@ if zero, then no bits here
+		addeq	r2, r2, #1		@ align bit pointer
+		beq	1b			@ loop for next bit
+
+#endif /* __ARMEB__ */
+
+/*
+ * One or more bits in the LSB of r3 are assumed to be set.
+ */
+.found:		tst	r3, #0x0f
+		addeq	r2, r2, #4
+		movne	r3, r3, lsl #4
+		tst	r3, #0x30
+		addeq	r2, r2, #2
+		movne	r3, r3, lsl #2
+		tst	r3, #0x40
+		addeq	r2, r2, #1
+		mov	r0, r2
+		RETINSTR(mov,pc,lr)
+
diff -urN linux-2.4.29/arch/armnommu/lib/floppydma.S linux-2.4.29-uc1/arch/armnommu/lib/floppydma.S
--- linux-2.4.29/arch/armnommu/lib/floppydma.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/floppydma.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ *  linux/arch/arm/lib/floppydma.S
+ *
+ *  Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+		.text
+
+		.global	SYMBOL_NAME(floppy_fiqin_end)
+ENTRY(floppy_fiqin_start)
+		subs	r9, r9, #1
+		ldrgtb	r12, [r11, #-4]
+		ldrleb	r12, [r11], #0
+		strb	r12, [r10], #1
+		subs	pc, lr, #4
+SYMBOL_NAME(floppy_fiqin_end):
+
+		.global	SYMBOL_NAME(floppy_fiqout_end)
+ENTRY(floppy_fiqout_start)
+		subs	r9, r9, #1
+		ldrgeb	r12, [r10], #1
+		movlt	r12, #0
+		strleb	r12, [r11], #0
+		subles	pc, lr, #4
+		strb	r12, [r11, #-4]
+		subs	pc, lr, #4
+SYMBOL_NAME(floppy_fiqout_end):
diff -urN linux-2.4.29/arch/armnommu/lib/io-acorn.S linux-2.4.29-uc1/arch/armnommu/lib/io-acorn.S
--- linux-2.4.29/arch/armnommu/lib/io-acorn.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/io-acorn.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,106 @@
+/*
+ *  linux/arch/arm/lib/io-acorn.S
+ *
+ *  Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h> /* for CONFIG_CPU_nn */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+		.text
+		.align
+
+		.equ	diff_pcio_base, PCIO_BASE - IO_BASE
+
+		.macro	outw2	rd
+		mov	r8, \rd, lsl #16
+		orr	r8, r8, r8, lsr #16
+		str	r8, [r3, r0, lsl #2]
+		mov	r8, \rd, lsr #16
+		orr	r8, r8, r8, lsl #16
+		str	r8, [r3, r0, lsl #2]
+		.endm
+
+		.macro	inw2	rd, mask, temp
+		ldr	\rd, [r0]
+		and	\rd, \rd, \mask
+		ldr	\temp, [r0]
+		orr	\rd, \rd, \temp, lsl #16
+		.endm
+
+		.macro	addr	rd
+		tst	\rd, #0x80000000
+		mov	\rd, \rd, lsl #2
+		add	\rd, \rd, #IO_BASE
+		addeq	\rd, \rd, #diff_pcio_base
+		.endm
+
+.iosl_warning:
+		.ascii	"<4>insl/outsl not implemented, called from %08lX\0"
+		.align
+
+/*
+ * These make no sense on Acorn machines.
+ * Print a warning message.
+ */
+ENTRY(insl)
+ENTRY(outsl)
+		adr	r0, .iosl_warning
+		mov	r1, lr
+		b	SYMBOL_NAME(printk)
+
+/* Purpose: read a block of data from a hardware register to memory.
+ * Proto  : void insw(int from_port, void *to, int len_in_words);
+ * Notes  : increment to, 'to' must be 16-bit aligned
+ */
+
+ENTRY(insw)
+		addr	r0
+		teq	r2, #0
+		bne	__raw_readsw
+		RETINSTR(mov, pc, lr)
+
+ENTRY(insb)
+		addr	r0
+		teq	r2, #0
+		bne	__raw_readsb
+		RETINSTR(mov, pc, lr)
+
+@ Purpose: write a block of data from memory to a hardware register.
+@ Proto  : outsw(int to_reg, void *from, int len_in_words);
+@ Notes  : increments from
+
+ENTRY(outsw)
+		addr	r0
+		teq	r2, #0
+		bne	__raw_writesw
+		RETINSTR(mov, pc, lr)
+
+ENTRY(outsb)
+		addr	r0
+		teq	r2, #0
+		bne	__raw_writesb
+		RETINSTR(mov, pc, lr)
+
+@ Purpose: write a memc register
+@ Proto  : void memc_write(int register, int value);
+@ Returns: nothing
+
+#if defined(CONFIG_CPU_26)
+ENTRY(memc_write)
+		cmp	r0, #7
+		RETINSTR(movgt,pc,lr)
+		mov	r0, r0, lsl #17
+		mov	r1, r1, lsl #15
+		mov	r1, r1, lsr #17
+		orr	r0, r0, r1, lsl #2
+		add	r0, r0, #0x03600000
+		strb	r0, [r0]
+		RETINSTR(mov,pc,lr)
+#endif
+
diff -urN linux-2.4.29/arch/armnommu/lib/io.c linux-2.4.29-uc1/arch/armnommu/lib/io.c
--- linux-2.4.29/arch/armnommu/lib/io.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/io.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,50 @@
+#include <linux/module.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+
+/*
+ * Copy data from IO memory space to "real" memory space.
+ * This needs to be optimized.
+ */
+void _memcpy_fromio(void * to, unsigned long from, size_t count)
+{
+	while (count) {
+		count--;
+		*(char *) to = readb(from);
+		((char *) to)++;
+		from++;
+	}
+}
+
+/*
+ * Copy data from "real" memory space to IO memory space.
+ * This needs to be optimized.
+ */
+void _memcpy_toio(unsigned long to, const void * from, size_t count)
+{
+	while (count) {
+		count--;
+		writeb(*(char *) from, to);
+		((char *) from)++;
+		to++;
+	}
+}
+
+/*
+ * "memset" on IO memory space.
+ * This needs to be optimized.
+ */
+void _memset_io(unsigned long dst, int c, size_t count)
+{
+	while (count) {
+		count--;
+		writeb(c, dst);
+		dst++;
+	}
+}
+
+EXPORT_SYMBOL(_memcpy_fromio);
+EXPORT_SYMBOL(_memcpy_toio);
+EXPORT_SYMBOL(_memset_io);
+
diff -urN linux-2.4.29/arch/armnommu/lib/io-pcio.S linux-2.4.29-uc1/arch/armnommu/lib/io-pcio.S
--- linux-2.4.29/arch/armnommu/lib/io-pcio.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/io-pcio.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,50 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+		.equ	pcio_high, PCIO_BASE & 0xff000000
+		.equ	pcio_low,  PCIO_BASE & 0x00ffffff
+
+		.macro	ioaddr, rd,rn
+		add	\rd, \rn, #pcio_high
+		.if	pcio_low
+		add	\rd, \rd, #pcio_low
+		.endif
+		.endm
+
+ENTRY(insl)
+		ioaddr	r0, r0
+		teq	r2, #0
+		bne	__arch_readsl
+		RETINSTR(mov, pc, lr)
+
+ENTRY(outsl)
+		ioaddr	r0, r0
+		teq	r2, #0
+		bne	__arch_writesl
+		RETINSTR(mov, pc, lr)
+
+ENTRY(outsw)
+		ioaddr	r0, r0
+		teq	r2, #0
+		bne	__arch_writesw
+		RETINSTR(mov, pc, lr)
+
+ENTRY(insw)
+		ioaddr	r0, r0
+		teq	r2, #0
+		bne	__arch_readsw
+		RETINSTR(mov, pc, lr)
+
+ENTRY(insb)
+		ioaddr	r0, r0
+		teq	r2, #0
+		bne	__arch_readsb
+		RETINSTR(mov, pc, lr)
+
+ENTRY(outsb)
+		ioaddr	r0, r0
+		teq	r2, #0
+		bne	__arch_writesb
+		RETINSTR(mov, pc, lr)
+
diff -urN linux-2.4.29/arch/armnommu/lib/io-readsb.S linux-2.4.29-uc1/arch/armnommu/lib/io-readsb.S
--- linux-2.4.29/arch/armnommu/lib/io-readsb.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/io-readsb.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,122 @@
+/*
+ *  linux/arch/arm/lib/io-readsb.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+.insb_align:	rsb	ip, ip, #4
+		cmp	ip, r2
+		movgt	ip, r2
+		cmp	ip, #2
+		ldrb	r3, [r0]
+		strb	r3, [r1], #1
+		ldrgeb	r3, [r0]
+		strgeb	r3, [r1], #1
+		ldrgtb	r3, [r0]
+		strgtb	r3, [r1], #1
+		subs	r2, r2, ip
+		bne	.insb_aligned
+
+ENTRY(__raw_readsb)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
+		ands	ip, r1, #3
+		bne	.insb_align
+
+.insb_aligned:	stmfd	sp!, {r4, r5, lr}
+
+		subs	r2, r2, #16
+		bmi	.insb_no_16
+
+.insb_16_lp:	ldrb	r3, [r0]
+		mov	r3, r3, lsl #byte(0)
+		ldrb	r4, [r0]
+		orr	r3, r3, r4, lsl #byte(1)
+		ldrb	r4, [r0]
+		orr	r3, r3, r4, lsl #byte(2)
+		ldrb	r4, [r0]
+		orr	r3, r3, r4, lsl #byte(3)
+		ldrb	r4, [r0]
+		mov	r4, r4, lsl #byte(0)
+		ldrb	r5, [r0]
+		orr	r4, r4, r5, lsl #byte(1)
+		ldrb	r5, [r0]
+		orr	r4, r4, r5, lsl #byte(2)
+		ldrb	r5, [r0]
+		orr	r4, r4, r5, lsl #byte(3)
+		ldrb	r5, [r0]
+		mov	r5, r5, lsl #byte(0)
+		ldrb	ip, [r0]
+		orr	r5, r5, ip, lsl #byte(1)
+		ldrb	ip, [r0]
+		orr	r5, r5, ip, lsl #byte(2)
+		ldrb	ip, [r0]
+		orr	r5, r5, ip, lsl #byte(3)
+		ldrb	ip, [r0]
+		mov	ip, ip, lsl #byte(0)
+		ldrb	lr, [r0]
+		orr	ip, ip, lr, lsl #byte(1)
+		ldrb	lr, [r0]
+		orr	ip, ip, lr, lsl #byte(2)
+		ldrb	lr, [r0]
+		orr	ip, ip, lr, lsl #byte(3)
+		stmia	r1!, {r3 - r5, ip}
+
+		subs	r2, r2, #16
+		bpl	.insb_16_lp
+
+		tst	r2, #15
+		LOADREGS(eqfd, sp!, {r4, r5, pc})
+
+.insb_no_16:	tst	r2, #8
+		beq	.insb_no_8
+
+		ldrb	r3, [r0]
+		mov	r3, r3, lsl #byte(0)
+		ldrb	r4, [r0]
+		orr	r3, r3, r4, lsl #byte(1)
+		ldrb	r4, [r0]
+		orr	r3, r3, r4, lsl #byte(2)
+		ldrb	r4, [r0]
+		orr	r3, r3, r4, lsl #byte(3)
+		ldrb	r4, [r0]
+		mov	r4, r4, lsl #byte(0)
+		ldrb	r5, [r0]
+		orr	r4, r4, r5, lsl #byte(1)
+		ldrb	r5, [r0]
+		orr	r4, r4, r5, lsl #byte(2)
+		ldrb	r5, [r0]
+		orr	r4, r4, r5, lsl #byte(3)
+		stmia	r1!, {r3, r4}
+
+.insb_no_8:	tst	r2, #4
+		beq	.insb_no_4
+
+		ldrb	r3, [r0]
+		mov	r3, r3, lsl #byte(0)
+		ldrb	r4, [r0]
+		orr	r3, r3, r4, lsl #byte(1)
+		ldrb	r4, [r0]
+		orr	r3, r3, r4, lsl #byte(2)
+		ldrb	r4, [r0]
+		orr	r3, r3, r4, lsl #byte(3)
+		str	r3, [r1], #4
+
+.insb_no_4:	ands	r2, r2, #3
+		LOADREGS(eqfd, sp!, {r4, r5, pc})
+
+		cmp	r2, #2
+		ldrb	r3, [r0]
+		strb	r3, [r1], #1
+		ldrgeb	r3, [r0]
+		strgeb	r3, [r1], #1
+		ldrgtb	r3, [r0]
+		strgtb	r3, [r1]
+
+		LOADREGS(fd, sp!, {r4, r5, pc})
diff -urN linux-2.4.29/arch/armnommu/lib/io-readsl-armv3.S linux-2.4.29-uc1/arch/armnommu/lib/io-readsl-armv3.S
--- linux-2.4.29/arch/armnommu/lib/io-readsl-armv3.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/io-readsl-armv3.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,78 @@
+/*
+ *  linux/arch/arm/lib/io-readsl-armv3.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+/*
+ * Note that some reads can be aligned on half-word boundaries.
+ */
+ENTRY(__raw_readsl)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
+		ands	ip, r1, #3
+		bne	2f
+
+1:		ldr	r3, [r0]
+		str	r3, [r1], #4
+		subs	r2, r2, #1
+		bne	1b
+		mov	pc, lr
+
+2:		cmp	ip, #2
+		ldr	ip, [r0]
+		blt	4f
+		bgt	6f
+
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+3:		subs	r2, r2, #1
+		ldrne	r3, [r0]
+		orrne	ip, ip, r3, lsl #16
+		strne	ip, [r1], #4
+		movne	ip, r3, lsr #16
+		bne	3b
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	pc, lr
+
+4:		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+5:		subs	r2, r2, #1
+		ldrne	r3, [r0]
+		orrne	ip, ip, r3, lsl #8
+		strne	ip, [r1], #4
+		movne	ip, r3, lsr #24
+		bne	5b
+		strb	ip, [r1], #1
+		mov	pc, lr
+
+6:		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+7:		subs	r2, r2, #1
+		ldrne	r3, [r0]
+		orrne	ip, ip, r3, lsl #24
+		strne	ip, [r1], #4
+		movne	ip, r3, lsr #8
+		bne	7b
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	pc, lr
+
diff -urN linux-2.4.29/arch/armnommu/lib/io-readsl-armv4.S linux-2.4.29-uc1/arch/armnommu/lib/io-readsl-armv4.S
--- linux-2.4.29/arch/armnommu/lib/io-readsl-armv4.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/io-readsl-armv4.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,115 @@
+/*
+ *  linux/arch/arm/lib/io-readsl-armv4.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Note that some reads can be aligned on half-word boundaries.
+ */
+ENTRY(__raw_readsl)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
+		ands	ip, r1, #3
+		bne	2f
+
+1:		ldr	r3, [r0]
+		str	r3, [r1], #4
+		subs	r2, r2, #1
+		bne	1b
+		mov	pc, lr
+
+2:		cmp	ip, #2
+		ldr	ip, [r0]
+		blt	4f
+		bgt	6f
+
+#ifndef __ARMEB__
+
+		/* little endian code */
+
+		strh	ip, [r1], #2
+		mov	ip, ip, lsr #16
+3:		subs	r2, r2, #1
+		ldrne	r3, [r0]
+		orrne	ip, ip, r3, lsl #16
+		strne	ip, [r1], #4
+		movne	ip, r3, lsr #16
+		bne	3b
+		strh	ip, [r1], #2
+		mov	pc, lr
+
+4:		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strh	ip, [r1], #2
+		mov	ip, ip, lsr #16
+5:		subs	r2, r2, #1
+		ldrne	r3, [r0]
+		orrne	ip, ip, r3, lsl #8
+		strne	ip, [r1], #4
+		movne	ip, r3, lsr #24
+		bne	5b
+		strb	ip, [r1], #1
+		mov	pc, lr
+
+6:		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+7:		subs	r2, r2, #1
+		ldrne	r3, [r0]
+		orrne	ip, ip, r3, lsl #24
+		strne	ip, [r1], #4
+		movne	ip, r3, lsr #8
+		bne	7b
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strh	ip, [r1], #2
+		mov	pc, lr
+
+#else
+
+		/* big endian code */
+
+		mov	r3, ip, lsr #16
+		strh	r3, [r1], #2
+3:		mov	r3, ip, lsl #16
+		subs	r2, r2, #1
+		ldrne	ip, [r0]
+		orrne	r3, r3, ip, lsr #16
+		strne	r3, [r1], #4
+		bne	3b
+		strh	ip, [r1], #2
+		mov	pc, lr
+
+4:		mov	r3, ip, lsr #24
+		strb	r3, [r1], #1
+		mov	r3, ip, lsr #8
+		strh	r3, [r1], #2
+5:		mov	r3, ip, lsl #24
+		subs	r2, r2, #1
+		ldrne	ip, [r0]
+		orrne	r3, r3, ip, lsr #8
+		strne	r3, [r1], #4
+		bne	5b
+		strb	ip, [r1], #1
+		mov	pc, lr
+
+6:		mov	r3, ip, lsr #24
+		strb	r3, [r1], #1
+7:		mov	r3, ip, lsl #8
+		subs	r2, r2, #1
+		ldrne	ip, [r0]
+		orrne	r3, r3, ip, lsr #24
+		strne	r3, [r1], #4
+		bne	7b
+		mov	r3, ip, lsr #8
+		strh	r3, [r1], #2
+		strb	ip, [r1], #1
+		mov	pc, lr
+
+#endif
diff -urN linux-2.4.29/arch/armnommu/lib/io-readsw-armv3.S linux-2.4.29-uc1/arch/armnommu/lib/io-readsw-armv3.S
--- linux-2.4.29/arch/armnommu/lib/io-readsw-armv3.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/io-readsw-armv3.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,107 @@
+/*
+ *  linux/arch/arm/lib/io-readsw-armv3.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+.insw_bad_alignment:
+		adr	r0, .insw_bad_align_msg
+		mov	r2, lr
+		b	SYMBOL_NAME(panic)
+.insw_bad_align_msg:
+		.asciz	"insw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
+		.align
+
+.insw_align:	tst	r1, #1
+		bne	.insw_bad_alignment
+
+		ldr	r3, [r0]
+		strb	r3, [r1], #1
+		mov	r3, r3, lsr #8
+		strb	r3, [r1], #1
+
+		subs	r2, r2, #1
+		RETINSTR(moveq, pc, lr)
+
+ENTRY(__raw_readsw)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
+		tst	r1, #3
+		bne	.insw_align
+
+.insw_aligned:	mov	ip, #0xff
+		orr	ip, ip, ip, lsl #8
+		stmfd	sp!, {r4, r5, r6, lr}
+
+		subs	r2, r2, #8
+		bmi	.no_insw_8
+
+.insw_8_lp:	ldr	r3, [r0]
+		and	r3, r3, ip
+		ldr	r4, [r0]
+		orr	r3, r3, r4, lsl #16
+
+		ldr	r4, [r0]
+		and	r4, r4, ip
+		ldr	r5, [r0]
+		orr	r4, r4, r5, lsl #16
+
+		ldr	r5, [r0]
+		and	r5, r5, ip
+		ldr	r6, [r0]
+		orr	r5, r5, r6, lsl #16
+
+		ldr	r6, [r0]
+		and	r6, r6, ip
+		ldr	lr, [r0]
+		orr	r6, r6, lr, lsl #16
+
+		stmia	r1!, {r3 - r6}
+
+		subs	r2, r2, #8
+		bpl	.insw_8_lp
+
+		tst	r2, #7
+		LOADREGS(eqfd, sp!, {r4, r5, r6, pc})
+
+.no_insw_8:	tst	r2, #4
+		beq	.no_insw_4
+
+		ldr	r3, [r0]
+		and	r3, r3, ip
+		ldr	r4, [r0]
+		orr	r3, r3, r4, lsl #16
+
+		ldr	r4, [r0]
+		and	r4, r4, ip
+		ldr	r5, [r0]
+		orr	r4, r4, r5, lsl #16
+
+		stmia	r1!, {r3, r4}
+
+.no_insw_4:	tst	r2, #2
+		beq	.no_insw_2
+
+		ldr	r3, [r0]
+		and	r3, r3, ip
+		ldr	r4, [r0]
+		orr	r3, r3, r4, lsl #16
+
+		str	r3, [r1], #4
+
+.no_insw_2:	tst	r2, #1
+		ldrne	r3, [r0]
+		strneb	r3, [r1], #1
+		movne	r3, r3, lsr #8
+		strneb	r3, [r1]
+
+		LOADREGS(fd, sp!, {r4, r5, r6, pc})
+
+
diff -urN linux-2.4.29/arch/armnommu/lib/io-readsw-armv4.S linux-2.4.29-uc1/arch/armnommu/lib/io-readsw-armv4.S
--- linux-2.4.29/arch/armnommu/lib/io-readsw-armv4.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/io-readsw-armv4.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,99 @@
+/*
+ *  linux/arch/arm/lib/io-readsw-armv4.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+		.macro	pack, rd, hw1, hw2
+#ifndef __ARMEB__
+		orr	\rd, \hw1, \hw2, lsl #16
+#else
+		orr	\rd, \hw2, \hw1, lsl #16
+#endif
+		.endm
+
+.insw_bad_alignment:
+		adr	r0, .insw_bad_align_msg
+		mov	r2, lr
+		b	SYMBOL_NAME(panic)
+.insw_bad_align_msg:
+		.asciz	"insw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
+		.align
+
+.insw_align:	tst	r1, #1
+		bne	.insw_bad_alignment
+
+		ldrh	r3, [r0]
+		strh	r3, [r1], #2
+
+		subs	r2, r2, #1
+		RETINSTR(moveq, pc, lr)
+
+ENTRY(__raw_readsw)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
+		tst	r1, #3
+		bne	.insw_align
+
+		stmfd	sp!, {r4, r5, lr}
+
+		subs	r2, r2, #8
+		bmi	.no_insw_8
+
+.insw_8_lp:	ldrh	r3, [r0]
+		ldrh	r4, [r0]
+		pack	r3, r3, r4
+
+		ldrh	r4, [r0]
+		ldrh	r5, [r0]
+		pack	r4, r4, r5
+
+		ldrh	r5, [r0]
+		ldrh	ip, [r0]
+		pack	r5, r5, ip
+
+		ldrh	ip, [r0]
+		ldrh	lr, [r0]
+		pack	ip, ip, lr
+
+		stmia	r1!, {r3 - r5, ip}
+
+		subs	r2, r2, #8
+		bpl	.insw_8_lp
+
+		tst	r2, #7
+		LOADREGS(eqfd, sp!, {r4, r5, pc})
+
+.no_insw_8:	tst	r2, #4
+		beq	.no_insw_4
+
+		ldrh	r3, [r0]
+		ldrh	r4, [r0]
+		pack	r3, r3, r4
+
+		ldrh	r4, [r0]
+		ldrh	ip, [r0]
+		pack	r4, r4, ip
+
+		stmia	r1!, {r3, r4}
+
+.no_insw_4:	tst	r2, #2
+		beq	.no_insw_2
+
+		ldrh	r3, [r0]
+		ldrh	ip, [r0]
+		pack	r3, r3, ip
+
+		str	r3, [r1], #4
+
+.no_insw_2:	tst	r2, #1
+		ldrneh	r3, [r0]
+		strneh	r3, [r1]
+
+		LOADREGS(fd, sp!, {r4, r5, pc})
diff -urN linux-2.4.29/arch/armnommu/lib/io-shark.c linux-2.4.29-uc1/arch/armnommu/lib/io-shark.c
--- linux-2.4.29/arch/armnommu/lib/io-shark.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/io-shark.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,83 @@
+/*
+ *  linux/arch/arm/lib/io-shark.c
+ *
+ *  by Alexander Schulz <aschulz@netwinder.org>
+ *
+ * derived from:
+ * linux/arch/arm/lib/io-ebsa.S
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+
+#include <asm/io.h>
+
+void print_warning(void)
+{
+	printk(KERN_WARNING "ins?/outs? not implemented on this architecture\n");
+}
+
+void insl(unsigned int port, void *to, int len)
+{
+	print_warning();
+}
+
+void insb(unsigned int port, void *to, int len)
+{
+	print_warning();
+}
+
+void outsl(unsigned int port, const void *from, int len)
+{
+	print_warning();
+}
+
+void outsb(unsigned int port, const void *from, int len)
+{
+	print_warning();
+}
+
+/* these should be in assembler again */
+
+/*
+ * Purpose: read a block of data from a hardware register to memory.
+ * Proto  : insw(int from_port, void *to, int len_in_words);
+ * Proto  : inswb(int from_port, void *to, int len_in_bytes);
+ * Notes  : increment to
+ */
+
+void insw(unsigned int port, void *to, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		((unsigned short *) to)[i] = inw(port);
+}
+
+void inswb(unsigned int port, void *to, int len)
+{
+	insw(port, to, len >> 2);
+}
+
+/*
+ * Purpose: write a block of data from memory to a hardware register.
+ * Proto  : outsw(int to_reg, void *from, int len_in_words);
+ * Proto  : outswb(int to_reg, void *from, int len_in_bytes);
+ * Notes  : increments from
+ */
+
+void outsw(unsigned int port, const void *from, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		outw(((unsigned short *) from)[i], port);
+}
+
+void outswb(unsigned int port, const void *from, int len)
+{
+	outsw(port, from, len >> 2);
+}
diff -urN linux-2.4.29/arch/armnommu/lib/io-writesb.S linux-2.4.29-uc1/arch/armnommu/lib/io-writesb.S
--- linux-2.4.29/arch/armnommu/lib/io-writesb.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/io-writesb.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,92 @@
+/*
+ *  linux/arch/arm/lib/io-writesb.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+		.macro	outword, rd
+#ifndef __ARMEB__
+		strb	\rd, [r0]
+		mov	\rd, \rd, lsr #8
+		strb	\rd, [r0]
+		mov	\rd, \rd, lsr #8
+		strb	\rd, [r0]
+		mov	\rd, \rd, lsr #8
+		strb	\rd, [r0]
+#else
+		mov	lr, \rd, lsr #24
+		strb	lr, [r0]
+		mov	lr, \rd, lsr #16
+		strb	lr, [r0]
+		mov	lr, \rd, lsr #8
+		strb	lr, [r0]
+		strb	\rd, [r0]
+#endif
+		.endm
+
+.outsb_align:	rsb	ip, ip, #4
+		cmp	ip, r2
+		movgt	ip, r2
+		cmp	ip, #2
+		ldrb	r3, [r1], #1
+		strb	r3, [r0]
+		ldrgeb	r3, [r1], #1
+		strgeb	r3, [r0]
+		ldrgtb	r3, [r1], #1
+		strgtb	r3, [r0]
+		subs	r2, r2, ip
+		bne	.outsb_aligned
+
+ENTRY(__raw_writesb)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
+		ands	ip, r1, #3
+		bne	.outsb_align
+
+.outsb_aligned:	stmfd	sp!, {r4, r5, lr}
+
+		subs	r2, r2, #16
+		bmi	.outsb_no_16
+
+.outsb_16_lp:	ldmia	r1!, {r3, r4, r5, ip}
+		outword	r3
+		outword	r4
+		outword	r5
+		outword	ip
+		subs	r2, r2, #16
+		bpl	.outsb_16_lp
+
+		tst	r2, #15
+		LOADREGS(eqfd, sp!, {r4, r5, pc})
+
+.outsb_no_16:	tst	r2, #8
+		beq	.outsb_no_8
+
+		ldmia	r1!, {r3, r4}
+		outword	r3
+		outword	r4
+
+.outsb_no_8:	tst	r2, #4
+		beq	.outsb_no_4
+
+		ldr	r3, [r1], #4
+		outword	r3
+
+.outsb_no_4:	ands	r2, r2, #3
+		LOADREGS(eqfd, sp!, {r4, r5, pc})
+
+		cmp	r2, #2
+		ldrb	r3, [r1], #1
+		strb	r3, [r0]
+		ldrgeb	r3, [r1], #1
+		strgeb	r3, [r0]
+		ldrgtb	r3, [r1]
+		strgtb	r3, [r0]
+
+		LOADREGS(fd, sp!, {r4, r5, pc})
diff -urN linux-2.4.29/arch/armnommu/lib/io-writesl.S linux-2.4.29-uc1/arch/armnommu/lib/io-writesl.S
--- linux-2.4.29/arch/armnommu/lib/io-writesl.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/io-writesl.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,57 @@
+/*
+ *  linux/arch/arm/lib/io-writesl.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+ENTRY(__raw_writesl)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
+		ands	ip, r1, #3
+		bne	2f
+
+1:		ldr	r3, [r1], #4
+		str	r3, [r0]
+		subs	r2, r2, #1
+		bne	1b
+		mov	pc, lr
+
+2:		bic	r1, r1, #3
+		cmp	ip, #2
+		ldr	ip, [r1], #4
+		mov	ip, ip, lsr #16
+		blt	4f
+		bgt	5f
+
+3:		ldr	r3, [r1], #4
+		orr	ip, ip, r3, push #16
+		str	ip, [r0]
+		mov	ip, r3, pull #16
+		subs	r2, r2, #1
+		bne	3b
+		mov	pc, lr
+
+4:		ldr	r3, [r1], #4
+		orr	ip, ip, r3, push #8
+		str	ip, [r0]
+		mov	ip, r3, pull #24
+		subs	r2, r2, #1
+		bne	4b
+		mov	pc, lr
+
+5:		ldr	r3, [r1], #4
+		orr	ip, ip, r3, push #24
+		str	ip, [r0]
+		mov	ip, r3, pull #8
+		subs	r2, r2, #1
+		bne	5b
+		mov	pc, lr
+
+
diff -urN linux-2.4.29/arch/armnommu/lib/io-writesw-armv3.S linux-2.4.29-uc1/arch/armnommu/lib/io-writesw-armv3.S
--- linux-2.4.29/arch/armnommu/lib/io-writesw-armv3.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/io-writesw-armv3.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,127 @@
+/*
+ *  linux/arch/arm/lib/io-writesw-armv3.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+.outsw_bad_alignment:
+		adr	r0, .outsw_bad_align_msg
+		mov	r2, lr
+		b	SYMBOL_NAME(panic)
+.outsw_bad_align_msg:
+		.asciz	"outsw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
+		.align
+
+.outsw_align:	tst	r1, #1
+		bne	.outsw_bad_alignment
+
+		add	r1, r1, #2
+
+		ldr	r3, [r1, #-4]
+		mov	r3, r3, lsr #16
+		orr	r3, r3, r3, lsl #16
+		str	r3, [r0]
+		subs	r2, r2, #1
+		RETINSTR(moveq, pc, lr)
+
+ENTRY(__raw_writesw)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
+		tst	r1, #3
+		bne	.outsw_align
+
+.outsw_aligned:	stmfd	sp!, {r4, r5, r6, lr}
+
+		subs	r2, r2, #8
+		bmi	.no_outsw_8
+
+.outsw_8_lp:	ldmia	r1!, {r3, r4, r5, r6}
+
+		mov	ip, r3, lsl #16
+		orr	ip, ip, ip, lsr #16
+		str	ip, [r0]
+
+		mov	ip, r3, lsr #16
+		orr	ip, ip, ip, lsl #16
+		str	ip, [r0]
+
+		mov	ip, r4, lsl #16
+		orr	ip, ip, ip, lsr #16
+		str	ip, [r0]
+
+		mov	ip, r4, lsr #16
+		orr	ip, ip, ip, lsl #16
+		str	ip, [r0]
+
+		mov	ip, r5, lsl #16
+		orr	ip, ip, ip, lsr #16
+		str	ip, [r0]
+
+		mov	ip, r5, lsr #16
+		orr	ip, ip, ip, lsl #16
+		str	ip, [r0]
+
+		mov	ip, r6, lsl #16
+		orr	ip, ip, ip, lsr #16
+		str	ip, [r0]
+
+		mov	ip, r6, lsr #16
+		orr	ip, ip, ip, lsl #16
+		str	ip, [r0]
+
+		subs	r2, r2, #8
+		bpl	.outsw_8_lp
+
+		tst	r2, #7
+		LOADREGS(eqfd, sp!, {r4, r5, r6, pc})
+
+.no_outsw_8:	tst	r2, #4
+		beq	.no_outsw_4
+
+		ldmia	r1!, {r3, r4}
+
+		mov	ip, r3, lsl #16
+		orr	ip, ip, ip, lsr #16
+		str	ip, [r0]
+
+		mov	ip, r3, lsr #16
+		orr	ip, ip, ip, lsl #16
+		str	ip, [r0]
+
+		mov	ip, r4, lsl #16
+		orr	ip, ip, ip, lsr #16
+		str	ip, [r0]
+
+		mov	ip, r4, lsr #16
+		orr	ip, ip, ip, lsl #16
+		str	ip, [r0]
+
+.no_outsw_4:	tst	r2, #2
+		beq	.no_outsw_2
+
+		ldr	r3, [r1], #4
+
+		mov	ip, r3, lsl #16
+		orr	ip, ip, ip, lsr #16
+		str	ip, [r0]
+
+		mov	ip, r3, lsr #16
+		orr	ip, ip, ip, lsl #16
+		str	ip, [r0]
+
+.no_outsw_2:	tst	r2, #1
+
+		ldrne	r3, [r1]
+
+		movne	ip, r3, lsl #16
+		orrne	ip, ip, ip, lsr #16
+		strne	ip, [r0]
+
+		LOADREGS(fd, sp!, {r4, r5, r6, pc})
diff -urN linux-2.4.29/arch/armnommu/lib/io-writesw-armv4.S linux-2.4.29-uc1/arch/armnommu/lib/io-writesw-armv4.S
--- linux-2.4.29/arch/armnommu/lib/io-writesw-armv4.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/io-writesw-armv4.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,81 @@
+/*
+ *  linux/arch/arm/lib/io-writesw-armv4.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+		.macro	outword, rd
+#ifndef __ARMEB__
+		strh	\rd, [r0]
+		mov	\rd, \rd, lsr #16
+		strh	\rd, [r0]
+#else
+		mov	lr, \rd, lsr #16
+		strh	lr, [r0]
+		strh	\rd, [r0]
+#endif
+		.endm
+
+.outsw_bad_alignment:
+		adr	r0, .outsw_bad_align_msg
+		mov	r2, lr
+		b	SYMBOL_NAME(panic)
+.outsw_bad_align_msg:
+		.asciz	"outsw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
+		.align
+
+.outsw_align:	tst	r1, #1
+		bne	.outsw_bad_alignment
+
+		ldrh	r3, [r1], #2
+		strh	r3, [r0]
+
+		subs	r2, r2, #1
+		RETINSTR(moveq, pc, lr)
+
+ENTRY(__raw_writesw)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
+		tst	r1, #3
+		bne	.outsw_align
+
+		stmfd	sp!, {r4, r5, lr}
+
+		subs	r2, r2, #8
+		bmi	.no_outsw_8
+
+.outsw_8_lp:	ldmia	r1!, {r3, r4, r5, ip}
+		outword	r3
+		outword	r4
+		outword	r5
+		outword	ip
+		subs	r2, r2, #8
+		bpl	.outsw_8_lp
+
+		tst	r2, #7
+		LOADREGS(eqfd, sp!, {r4, r5, pc})
+
+.no_outsw_8:	tst	r2, #4
+		beq	.no_outsw_4
+
+		ldmia	r1!, {r3, ip}
+		outword	r3
+		outword	ip
+
+.no_outsw_4:	tst	r2, #2
+		beq	.no_outsw_2
+
+		ldr	r3, [r1], #4
+		outword	r3
+
+.no_outsw_2:	tst	r2, #1
+		ldrneh	r3, [r1]
+		strneh	r3, [r0]
+
+		LOADREGS(fd, sp!, {r4, r5, pc})
diff -urN linux-2.4.29/arch/armnommu/lib/Makefile linux-2.4.29-uc1/arch/armnommu/lib/Makefile
--- linux-2.4.29/arch/armnommu/lib/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,49 @@
+#
+# linux/arch/arm/lib/Makefile
+#
+# Copyright (C) 1995-2000 Russell King
+#
+
+USE_STANDARD_AS_RULE := true
+
+L_TARGET	:= lib.a
+
+obj-y		:= backtrace.o changebit.o csumipv6.o csumpartial.o   \
+		   csumpartialcopy.o csumpartialcopyuser.o clearbit.o \
+		   copy_page.o delay.o findbit.o memchr.o memcpy.o    \
+		   memset.o memzero.o setbit.o strncpy_from_user.o    \
+		   strnlen_user.o strchr.o strrchr.o testchangebit.o  \
+		   testclearbit.o testsetbit.o uaccess.o
+obj-m		:=
+obj-n		:=
+
+obj-arc		:= ecard.o io-acorn.o floppydma.o
+obj-rpc		:= ecard.o io-acorn.o floppydma.o
+obj-clps7500	:= io-acorn.o
+obj-l7200     	:= io-acorn.o
+obj-shark	:= io-shark.o
+
+obj-y		+= $(obj-$(MACHINE))
+
+ifeq ($(CONFIG_CPU_32v4),y)
+  v3		:= n
+  v4		:= y
+else
+  v3		:= y
+  v4		:= n
+endif
+
+obj-y		+= io-readsb.o io-writesb.o
+obj-$(v3)	+= io-readsw-armv3.o io-writesw-armv3.o io-readsl-armv3.o
+obj-$(v4)	+= io-readsw-armv4.o io-writesw-armv4.o io-readsl-armv4.o
+obj-y		+= io-writesl.o
+
+ifeq ($(PROCESSOR),armo)
+  obj-y		+= uaccess-armo.o
+endif
+
+include $(TOPDIR)/Rules.make
+
+csumpartialcopy.o: csumpartialcopygeneric.S
+csumpartialcopyuser.o: csumpartialcopygeneric.S
+
diff -urN linux-2.4.29/arch/armnommu/lib/memchr.S linux-2.4.29-uc1/arch/armnommu/lib/memchr.S
--- linux-2.4.29/arch/armnommu/lib/memchr.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/memchr.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ *  linux/arch/arm/lib/memchr.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  ASM optimised string functions
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+	.text
+	.align	5
+ENTRY(memchr)
+1:	ldrb	r3, [r0], #1
+	teq	r3, r1
+	beq	2f
+	subs	r2, r2, #1
+	bpl	1b
+2:	movne	r0, #0
+	subeq	r0, r0, #1
+	RETINSTR(mov,pc,lr)
diff -urN linux-2.4.29/arch/armnommu/lib/memcpy.S linux-2.4.29-uc1/arch/armnommu/lib/memcpy.S
--- linux-2.4.29/arch/armnommu/lib/memcpy.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/memcpy.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,318 @@
+/*
+ *  linux/arch/arm/lib/memcpy.S
+ *
+ *  Copyright (C) 1995-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  ASM optimised string functions
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+		.text
+
+#define ENTER	\
+		mov	ip,sp	;\
+		stmfd	sp!,{r4-r9,fp,ip,lr,pc}	;\
+		sub	fp,ip,#4
+
+#define EXIT	\
+		LOADREGS(ea, fp, {r4 - r9, fp, sp, pc})
+
+#define EXITEQ	\
+		LOADREGS(eqea, fp, {r4 - r9, fp, sp, pc})
+
+/*
+ * Prototype: void memcpy(void *to,const void *from,unsigned long n);
+ * ARM3: cant use memcopy here!!!
+ */
+ENTRY(memcpy)
+ENTRY(memmove)
+		ENTER
+		cmp	r1, r0
+		bcc	19f
+		subs	r2, r2, #4
+		blt	6f
+		ands	ip, r0, #3
+		bne	7f
+		ands	ip, r1, #3
+		bne	8f
+
+1:		subs	r2, r2, #8
+		blt	5f
+		subs	r2, r2, #0x14
+		blt	3f
+2:		ldmia	r1!,{r3 - r9, ip}
+		stmia	r0!,{r3 - r9, ip}
+		subs	r2, r2, #32
+		bge	2b
+		cmn	r2, #16
+		ldmgeia	r1!, {r3 - r6}
+		stmgeia	r0!, {r3 - r6}
+		subge	r2, r2, #0x10
+3:		adds	r2, r2, #0x14
+4:		ldmgeia	r1!, {r3 - r5}
+		stmgeia	r0!, {r3 - r5}
+		subges	r2, r2, #12
+		bge	4b
+5:		adds	r2, r2, #8
+		blt	6f
+		subs	r2, r2, #4
+		ldrlt	r3, [r1], #4
+		ldmgeia	r1!, {r4, r5}
+		strlt	r3, [r0], #4
+		stmgeia	r0!, {r4, r5}
+		subge	r2, r2, #4
+
+6:		adds	r2, r2, #4
+		EXITEQ
+		cmp	r2, #2
+		ldrb	r3, [r1], #1
+		ldrgeb	r4, [r1], #1
+		ldrgtb	r5, [r1], #1
+		strb	r3, [r0], #1
+		strgeb	r4, [r0], #1
+		strgtb	r5, [r0], #1
+		EXIT
+
+7:		rsb	ip, ip, #4
+		cmp	ip, #2
+		ldrb	r3, [r1], #1
+		ldrgeb	r4, [r1], #1
+		ldrgtb	r5, [r1], #1
+		strb	r3, [r0], #1
+		strgeb	r4, [r0], #1
+		strgtb	r5, [r0], #1
+		subs	r2, r2, ip
+		blt	6b
+		ands	ip, r1, #3
+		beq	1b
+
+8:		bic	r1, r1, #3
+		ldr	r7, [r1], #4
+		cmp	ip, #2
+		bgt	15f
+		beq	11f
+		cmp	r2, #12
+		blt	10f
+		sub	r2, r2, #12
+9:		mov	r3, r7, pull #8
+		ldmia	r1!, {r4 - r7}
+		orr	r3, r3, r4, push #24
+		mov	r4, r4, pull #8
+		orr	r4, r4, r5, push #24
+		mov	r5, r5, pull #8
+		orr	r5, r5, r6, push #24
+		mov	r6, r6, pull #8
+		orr	r6, r6, r7, push #24
+		stmia	r0!, {r3 - r6}
+		subs	r2, r2, #16
+		bge	9b
+		adds	r2, r2, #12
+		blt	100f
+10:		mov	r3, r7, pull #8
+		ldr	r7, [r1], #4
+		subs	r2, r2, #4
+		orr	r3, r3, r7, push #24
+		str	r3, [r0], #4
+		bge	10b
+100:		sub	r1, r1, #3
+		b	6b
+
+11:		cmp	r2, #12
+		blt	13f		/* */
+		sub	r2, r2, #12
+12:		mov	r3, r7, pull #16
+		ldmia	r1!, {r4 - r7}
+		orr	r3, r3, r4, push #16
+		mov	r4, r4, pull #16
+		orr	r4, r4, r5, push #16
+		mov	r5, r5, pull #16
+		orr	r5, r5, r6, push #16
+		mov	r6, r6, pull #16
+		orr	r6, r6, r7, push #16
+		stmia	r0!, {r3 - r6}
+		subs	r2, r2, #16
+		bge	12b
+		adds	r2, r2, #12
+		blt	14f
+13:		mov	r3, r7, pull #16
+		ldr	r7, [r1], #4
+		subs	r2, r2, #4
+		orr	r3, r3, r7, push #16
+		str	r3, [r0], #4
+		bge	13b
+14:		sub	r1, r1, #2
+		b	6b
+
+15:		cmp	r2, #12
+		blt	17f
+		sub	r2, r2, #12
+16:		mov	r3, r7, pull #24
+		ldmia	r1!, {r4 - r7}
+		orr	r3, r3, r4, push #8
+		mov	r4, r4, pull #24
+		orr	r4, r4, r5, push #8
+		mov	r5, r5, pull #24
+		orr	r5, r5, r6, push #8
+		mov	r6, r6, pull #24
+		orr	r6, r6, r7, push #8
+		stmia	r0!, {r3 - r6}
+		subs	r2, r2, #16
+		bge	16b
+		adds	r2, r2, #12
+		blt	18f
+17:		mov	r3, r7, pull #24
+		ldr	r7, [r1], #4
+		subs	r2, r2, #4
+		orr	r3, r3, r7, push #8
+		str	r3, [r0], #4
+		bge	17b
+18:		sub	r1, r1, #1
+		b	6b
+
+
+19:		add	r1, r1, r2
+		add	r0, r0, r2
+		subs	r2, r2, #4
+		blt	24f
+		ands	ip, r0, #3
+		bne	25f
+		ands	ip, r1, #3
+		bne	26f
+
+20:		subs	r2, r2, #8
+		blt	23f
+		subs	r2, r2, #0x14
+		blt	22f
+21:		ldmdb	r1!, {r3 - r9, ip}
+		stmdb	r0!, {r3 - r9, ip}
+		subs	r2, r2, #32
+		bge	21b
+22:		cmn	r2, #16
+		ldmgedb	r1!, {r3 - r6}
+		stmgedb	r0!, {r3 - r6}
+		subge	r2, r2, #16
+		adds	r2, r2, #20
+		ldmgedb	r1!, {r3 - r5}
+		stmgedb	r0!, {r3 - r5}
+		subge	r2, r2, #12
+23:		adds	r2, r2, #8
+		blt	24f
+		subs	r2, r2, #4
+		ldrlt	r3, [r1, #-4]!
+		ldmgedb	r1!, {r4, r5}
+		strlt	r3, [r0, #-4]!
+		stmgedb	r0!, {r4, r5}
+		subge	r2, r2, #4
+
+24:		adds	r2, r2, #4
+		EXITEQ
+		cmp	r2, #2
+		ldrb	r3, [r1, #-1]!
+		ldrgeb	r4, [r1, #-1]!
+		ldrgtb	r5, [r1, #-1]!
+		strb	r3, [r0, #-1]!
+		strgeb	r4, [r0, #-1]!
+		strgtb	r5, [r0, #-1]!
+		EXIT
+
+25:		cmp	ip, #2
+		ldrb	r3, [r1, #-1]!
+		ldrgeb	r4, [r1, #-1]!
+		ldrgtb	r5, [r1, #-1]!
+		strb	r3, [r0, #-1]!
+		strgeb	r4, [r0, #-1]!
+		strgtb	r5, [r0, #-1]!
+		subs	r2, r2, ip
+		blt	24b
+		ands	ip, r1, #3
+		beq	20b
+
+26:		bic	r1, r1, #3
+		ldr	r3, [r1], #0
+		cmp	ip, #2
+		blt	34f
+		beq	30f
+		cmp	r2, #12
+		blt	28f
+		sub	r2, r2, #12
+27:		mov	r7, r3, push #8
+		ldmdb	r1!, {r3, r4, r5, r6}
+		orr	r7, r7, r6, pull #24
+		mov	r6, r6, push #8
+		orr	r6, r6, r5, pull #24
+		mov	r5, r5, push #8
+		orr	r5, r5, r4, pull #24
+		mov	r4, r4, push #8
+		orr	r4, r4, r3, pull #24
+		stmdb	r0!, {r4, r5, r6, r7}
+		subs	r2, r2, #16
+		bge	27b
+		adds	r2, r2, #12
+		blt	29f
+28:		mov	ip, r3, push #8
+		ldr	r3, [r1, #-4]!
+		subs	r2, r2, #4
+		orr	ip, ip, r3, pull #24
+		str	ip, [r0, #-4]!
+		bge	28b
+29:		add	r1, r1, #3
+		b	24b
+
+30:		cmp	r2, #12
+		blt	32f
+		sub	r2, r2, #12
+31:		mov	r7, r3, push #16
+		ldmdb	r1!, {r3, r4, r5, r6}
+		orr	r7, r7, r6, pull #16
+		mov	r6, r6, push #16
+		orr	r6, r6, r5, pull #16
+		mov	r5, r5, push #16
+		orr	r5, r5, r4, pull #16
+		mov	r4, r4, push #16
+		orr	r4, r4, r3, pull #16
+		stmdb	r0!, {r4, r5, r6, r7}
+		subs	r2, r2, #16
+		bge	31b
+		adds	r2, r2, #12
+		blt	33f
+32:		mov	ip, r3, push #16
+		ldr	r3, [r1, #-4]!
+		subs	r2, r2, #4
+		orr	ip, ip, r3, pull #16
+		str	ip, [r0, #-4]!
+		bge	32b
+33:		add	r1, r1, #2
+		b	24b
+
+34:		cmp	r2, #12
+		blt	36f
+		sub	r2, r2, #12
+35:		mov	r7, r3, push #24
+		ldmdb	r1!, {r3, r4, r5, r6}
+		orr	r7, r7, r6, pull #8
+		mov	r6, r6, push #24
+		orr	r6, r6, r5, pull #8
+		mov	r5, r5, push #24
+		orr	r5, r5, r4, pull #8
+		mov	r4, r4, push #24
+		orr	r4, r4, r3, pull #8
+		stmdb	r0!, {r4, r5, r6, r7}
+		subs	r2, r2, #16
+		bge	35b
+		adds	r2, r2, #12
+		blt	37f
+36:		mov	ip, r3, push #24
+		ldr	r3, [r1, #-4]!
+		subs	r2, r2, #4
+		orr	ip, ip, r3, pull #8
+		str	ip, [r0, #-4]!
+		bge	36b
+37:		add	r1, r1, #1
+		b	24b
+
+		.align
diff -urN linux-2.4.29/arch/armnommu/lib/memset.S linux-2.4.29-uc1/arch/armnommu/lib/memset.S
--- linux-2.4.29/arch/armnommu/lib/memset.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/memset.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,80 @@
+/*
+ *  linux/arch/arm/lib/memset.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  ASM optimised string functions
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+	.text
+	.align	5
+	.word	0
+
+1:	subs	r2, r2, #4		@ 1 do we have enough
+	blt	5f			@ 1 bytes to align with?
+	cmp	r3, #2			@ 1
+	strltb	r1, [r0], #1		@ 1
+	strleb	r1, [r0], #1		@ 1
+	strb	r1, [r0], #1		@ 1
+	add	r2, r2, r3		@ 1 (r2 = r2 - (4 - r3))
+/*
+ * The pointer is now aligned and the length is adjusted.  Try doing the
+ * memzero again.
+ */
+
+ENTRY(memset)
+	ands	r3, r0, #3		@ 1 unaligned?
+	bne	1b			@ 1
+/*
+ * we know that the pointer in r0 is aligned to a word boundary.
+ */
+	orr	r1, r1, r1, lsl #8
+	orr	r1, r1, r1, lsl #16
+	mov	r3, r1
+	cmp	r2, #16
+	blt	4f
+/*
+ * We need an extra register for this loop - save the return address and
+ * use the LR
+ */
+	str	lr, [sp, #-4]!
+	mov	ip, r1
+	mov	lr, r1
+
+2:	subs	r2, r2, #64
+	stmgeia	r0!, {r1, r3, ip, lr}	@ 64 bytes at a time.
+	stmgeia	r0!, {r1, r3, ip, lr}
+	stmgeia	r0!, {r1, r3, ip, lr}
+	stmgeia	r0!, {r1, r3, ip, lr}
+	bgt	2b
+	LOADREGS(eqfd, sp!, {pc})	@ Now <64 bytes to go.
+/*
+ * No need to correct the count; we're only testing bits from now on
+ */
+	tst	r2, #32
+	stmneia	r0!, {r1, r3, ip, lr}
+	stmneia	r0!, {r1, r3, ip, lr}
+	tst	r2, #16
+	stmneia	r0!, {r1, r3, ip, lr}
+	ldr	lr, [sp], #4
+
+4:	tst	r2, #8
+	stmneia	r0!, {r1, r3}
+	tst	r2, #4
+	strne	r1, [r0], #4
+/*
+ * When we get here, we've got less than 4 bytes to zero.  We
+ * may have an unaligned pointer as well.
+ */
+5:	tst	r2, #2
+	strneb	r1, [r0], #1
+	strneb	r1, [r0], #1
+	tst	r2, #1
+	strneb	r1, [r0], #1
+	RETINSTR(mov,pc,lr)
diff -urN linux-2.4.29/arch/armnommu/lib/memzero.S linux-2.4.29-uc1/arch/armnommu/lib/memzero.S
--- linux-2.4.29/arch/armnommu/lib/memzero.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/memzero.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,80 @@
+/*
+ *  linux/arch/arm/lib/memzero.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+	.text
+	.align	5
+	.word	0
+/*
+ * Align the pointer in r0.  r3 contains the number of bytes that we are
+ * mis-aligned by, and r1 is the number of bytes.  If r1 < 4, then we
+ * don't bother; we use byte stores instead.
+ */
+1:	subs	r1, r1, #4		@ 1 do we have enough
+	blt	5f			@ 1 bytes to align with?
+	cmp	r3, #2			@ 1
+	strltb	r2, [r0], #1		@ 1
+	strleb	r2, [r0], #1		@ 1
+	strb	r2, [r0], #1		@ 1
+	add	r1, r1, r3		@ 1 (r1 = r1 - (4 - r3))
+/*
+ * The pointer is now aligned and the length is adjusted.  Try doing the
+ * memzero again.
+ */
+
+ENTRY(__memzero)
+	mov	r2, #0			@ 1
+	ands	r3, r0, #3		@ 1 unaligned?
+	bne	1b			@ 1
+/*
+ * r3 = 0, and we know that the pointer in r0 is aligned to a word boundary.
+ */
+	cmp	r1, #16			@ 1 we can skip this chunk if we
+	blt	4f			@ 1 have < 16 bytes
+/*
+ * We need an extra register for this loop - save the return address and
+ * use the LR
+ */
+	str	lr, [sp, #-4]!		@ 1
+	mov	ip, r2			@ 1
+	mov	lr, r2			@ 1
+
+3:	subs	r1, r1, #64		@ 1 write 32 bytes out per loop
+	stmgeia	r0!, {r2, r3, ip, lr}	@ 4
+	stmgeia	r0!, {r2, r3, ip, lr}	@ 4
+	stmgeia	r0!, {r2, r3, ip, lr}	@ 4
+	stmgeia	r0!, {r2, r3, ip, lr}	@ 4
+	bgt	3b			@ 1
+	LOADREGS(eqfd, sp!, {pc})	@ 1/2 quick exit
+/*
+ * No need to correct the count; we're only testing bits from now on
+ */
+	tst	r1, #32			@ 1
+	stmneia	r0!, {r2, r3, ip, lr}	@ 4
+	stmneia	r0!, {r2, r3, ip, lr}	@ 4
+	tst	r1, #16			@ 1 16 bytes or more?
+	stmneia	r0!, {r2, r3, ip, lr}	@ 4
+	ldr	lr, [sp], #4		@ 1
+
+4:	tst	r1, #8			@ 1 8 bytes or more?
+	stmneia	r0!, {r2, r3}		@ 2
+	tst	r1, #4			@ 1 4 bytes or more?
+	strne	r2, [r0], #4		@ 1
+/*
+ * When we get here, we've got less than 4 bytes to zero.  We
+ * may have an unaligned pointer as well.
+ */
+5:	tst	r1, #2			@ 1 2 bytes or more?
+	strneb	r2, [r0], #1		@ 1
+	strneb	r2, [r0], #1		@ 1
+	tst	r1, #1			@ 1 a byte left over
+	strneb	r2, [r0], #1		@ 1
+	RETINSTR(mov,pc,lr)		@ 1
diff -urN linux-2.4.29/arch/armnommu/lib/setbit.S linux-2.4.29-uc1/arch/armnommu/lib/setbit.S
--- linux-2.4.29/arch/armnommu/lib/setbit.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/setbit.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ *  linux/arch/arm/lib/setbit.S
+ *
+ *  Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+                .text
+
+/*
+ * Purpose  : Function to set a bit
+ * Prototype: int set_bit(int bit, void *addr)
+ */
+
+ENTRY(set_bit)
+#ifdef __ARMEB__
+		eor	r0, r0, #0x18		@ big endian byte ordering
+#endif
+		and     r2, r0, #7
+		mov     r3, #1
+		mov     r3, r3, lsl r2
+		save_and_disable_irqs ip, r2
+		ldrb	r2, [r1, r0, lsr #3]
+		orr	r2, r2, r3
+		strb	r2, [r1, r0, lsr #3]
+		restore_irqs ip
+		RETINSTR(mov,pc,lr)
+
+
diff -urN linux-2.4.29/arch/armnommu/lib/strchr.S linux-2.4.29-uc1/arch/armnommu/lib/strchr.S
--- linux-2.4.29/arch/armnommu/lib/strchr.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/strchr.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ *  linux/arch/arm/lib/strchr.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  ASM optimised string functions
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+		.text
+		.align	5
+ENTRY(strchr)
+1:		ldrb	r2, [r0], #1
+		teq	r2, r1
+		teqne	r2, #0
+		bne	1b
+		teq	r2, #0
+		moveq	r0, #0
+		subne	r0, r0, #1
+		RETINSTR(mov,pc,lr)
diff -urN linux-2.4.29/arch/armnommu/lib/strncpy_from_user.S linux-2.4.29-uc1/arch/armnommu/lib/strncpy_from_user.S
--- linux-2.4.29/arch/armnommu/lib/strncpy_from_user.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/strncpy_from_user.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,43 @@
+/*
+ *  linux/arch/arm/lib/strncpy_from_user.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/errno.h>
+
+	.text
+	.align	5
+
+/*
+ * Copy a string from user space to kernel space.
+ *  r0 = dst, r1 = src, r2 = byte length
+ * returns the number of characters copied (strlen of copied string),
+ *  -EFAULT on exception, or "len" if we fill the whole buffer
+ */
+ENTRY(__arch_strncpy_from_user)
+	save_lr
+	mov	ip, r1
+1:	subs	r2, r2, #1
+USER(	ldrplbt	r3, [r1], #1)
+	bmi	2f
+	strb	r3, [r0], #1
+	teq	r3, #0
+	bne	1b
+	sub	r1, r1, #1	@ take NUL character out of count
+2:	sub	r0, r1, ip
+	restore_pc
+
+	.section .fixup,"ax"
+	.align	0
+9001:	mov	r3, #0
+	strb	r3, [r0, #0]	@ null terminate
+	mov	r0, #-EFAULT
+	restore_pc
+	.previous
+
diff -urN linux-2.4.29/arch/armnommu/lib/strnlen_user.S linux-2.4.29-uc1/arch/armnommu/lib/strnlen_user.S
--- linux-2.4.29/arch/armnommu/lib/strnlen_user.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/strnlen_user.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,40 @@
+/*
+ *  linux/arch/arm/lib/strnlen_user.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/errno.h>
+
+	.text
+	.align	5
+
+/* Prototype: unsigned long __arch_strnlen_user(const char *str, long n)
+ * Purpose  : get length of a string in user memory
+ * Params   : str - address of string in user memory
+ * Returns  : length of string *including terminator*
+ *	      or zero on exception, or n + 1 if too long
+ */
+ENTRY(__arch_strnlen_user)
+	save_lr
+	mov	r2, r0
+1:
+USER(	ldrbt	r3, [r0], #1)
+	teq	r3, #0
+	beq	2f
+	subs	r1, r1, #1
+	bne	1b
+	add	r0, r0, #1
+2:	sub	r0, r0, r2
+	restore_pc
+
+	.section .fixup,"ax"
+	.align	0
+9001:	mov	r0, #0
+	restore_pc
+	.previous
diff -urN linux-2.4.29/arch/armnommu/lib/strrchr.S linux-2.4.29-uc1/arch/armnommu/lib/strrchr.S
--- linux-2.4.29/arch/armnommu/lib/strrchr.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/strrchr.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ *  linux/arch/arm/lib/strrchr.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  ASM optimised string functions
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+		.text
+		.align	5
+ENTRY(strrchr)
+		mov	r3, #0
+1:		ldrb	r2, [r0], #1
+		teq	r2, r1
+		subeq	r3, r0, #1
+		teq	r2, #0
+		bne	1b
+		mov	r0, r3
+		RETINSTR(mov,pc,lr)
diff -urN linux-2.4.29/arch/armnommu/lib/testchangebit.S linux-2.4.29-uc1/arch/armnommu/lib/testchangebit.S
--- linux-2.4.29/arch/armnommu/lib/testchangebit.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/testchangebit.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ *  linux/arch/arm/lib/testchangebit.S
+ *
+ *  Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+                .text
+
+ENTRY(test_and_change_bit)
+#ifdef __ARMEB__
+		eor	r0, r0, #0x18		@ big endian byte ordering
+#endif
+		add	r1, r1, r0, lsr #3
+		and	r3, r0, #7
+		mov	r0, #1
+		save_and_disable_irqs ip, r2
+		ldrb	r2, [r1]
+		tst	r2, r0, lsl r3
+		eor	r2, r2, r0, lsl r3
+		strb	r2, [r1]
+		restore_irqs ip
+		moveq	r0, #0
+		RETINSTR(mov,pc,lr)
+
+
diff -urN linux-2.4.29/arch/armnommu/lib/testclearbit.S linux-2.4.29-uc1/arch/armnommu/lib/testclearbit.S
--- linux-2.4.29/arch/armnommu/lib/testclearbit.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/testclearbit.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ *  linux/arch/arm/lib/testclearbit.S
+ *
+ *  Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+                .text
+
+ENTRY(test_and_clear_bit)
+#ifdef __ARMEB__
+		eor	r0, r0, #0x18		@ big endian byte ordering
+#endif
+		add	r1, r1, r0, lsr #3	@ Get byte offset
+		and	r3, r0, #7		@ Get bit offset
+		mov	r0, #1
+		save_and_disable_irqs ip, r2
+		ldrb	r2, [r1]
+		tst	r2, r0, lsl r3
+		bic	r2, r2, r0, lsl r3
+		strb	r2, [r1]
+		restore_irqs ip
+		moveq	r0, #0
+		RETINSTR(mov,pc,lr)
+
+
diff -urN linux-2.4.29/arch/armnommu/lib/testsetbit.S linux-2.4.29-uc1/arch/armnommu/lib/testsetbit.S
--- linux-2.4.29/arch/armnommu/lib/testsetbit.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/testsetbit.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ *  linux/arch/arm/lib/testsetbit.S
+ *
+ *  Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+                .text
+
+ENTRY(test_and_set_bit)
+#ifdef __ARMEB__
+		eor	r0, r0, #0x18		@ big endian byte ordering
+#endif
+		add	r1, r1, r0, lsr #3	@ Get byte offset
+		and	r3, r0, #7		@ Get bit offset
+		mov	r0, #1
+		save_and_disable_irqs ip, r2
+		ldrb	r2, [r1]
+		tst	r2, r0, lsl r3
+		orr	r2, r2, r0, lsl r3
+		strb	r2, [r1]
+		restore_irqs ip
+		moveq	r0, #0
+		RETINSTR(mov,pc,lr)
+
+
diff -urN linux-2.4.29/arch/armnommu/lib/uaccess-armo.S linux-2.4.29-uc1/arch/armnommu/lib/uaccess-armo.S
--- linux-2.4.29/arch/armnommu/lib/uaccess-armo.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/uaccess-armo.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,231 @@
+/*
+ *  linux/arch/arm/lib/uaccess-armo.S
+ *
+ *  Copyright (C) 1998 Russell King
+ *
+ *  Note!  Some code fragments found in here have a special calling
+ *  convention - they are not APCS compliant!
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+		.text
+
+		.globl	SYMBOL_NAME(uaccess_user)
+SYMBOL_NAME(uaccess_user):
+		.word	uaccess_user_put_byte
+		.word	uaccess_user_get_byte
+		.word	uaccess_user_put_half
+		.word	uaccess_user_get_half
+		.word	uaccess_user_put_word
+		.word	uaccess_user_get_word
+		.word	__arch_copy_from_user
+		.word	__arch_copy_to_user
+		.word	__arch_clear_user
+		.word	__arch_strncpy_from_user
+		.word	__arch_strnlen_user
+
+
+@ In : r0 = x, r1 = addr, r2 = error
+@ Out: r2 = error
+uaccess_user_put_byte:
+		stmfd	sp!, {lr}
+USER(		strbt	r0, [r1])
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = x, r1 = addr, r2 = error
+@ Out: r2 = error
+uaccess_user_put_half:
+		stmfd	sp!, {lr}
+USER(		strbt	r0, [r1], #1)
+		mov	r0, r0, lsr #8
+USER(		strbt	r0, [r1])
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = x, r1 = addr, r2 = error
+@ Out: r2 = error
+uaccess_user_put_word:
+		stmfd	sp!, {lr}
+USER(		strt	r0, [r1])
+		ldmfd	sp!, {pc}^
+
+9001:		mov	r2, #-EFAULT
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = addr, r1 = error
+@ Out: r0 = x, r1 = error
+uaccess_user_get_byte:
+		stmfd	sp!, {lr}
+USER(		ldrbt	r0, [r0])
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = addr, r1 = error
+@ Out: r0 = x, r1 = error
+uaccess_user_get_half:
+		stmfd	sp!, {lr}
+USER(		ldrt	r0, [r0])
+		mov	r0, r0, lsl #16
+		mov	r0, r0, lsr #16
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = addr, r1 = error
+@ Out: r0 = x, r1 = error
+uaccess_user_get_word:
+		stmfd	sp!, {lr}
+USER(		ldrt	r0, [r0])
+		ldmfd	sp!, {pc}^
+
+9001:		mov	r1, #-EFAULT
+		ldmfd	sp!, {pc}^
+
+
+
+		.globl	SYMBOL_NAME(uaccess_kernel)
+SYMBOL_NAME(uaccess_kernel):
+		.word	uaccess_kernel_put_byte
+		.word	uaccess_kernel_get_byte
+		.word	uaccess_kernel_put_half
+		.word	uaccess_kernel_get_half
+		.word	uaccess_kernel_put_word
+		.word	uaccess_kernel_get_word
+		.word	uaccess_kernel_copy
+		.word	uaccess_kernel_copy
+		.word	uaccess_kernel_clear
+		.word	uaccess_kernel_strncpy_from
+		.word	uaccess_kernel_strnlen
+
+@ In : r0 = x, r1 = addr, r2 = error
+@ Out: r2 = error
+uaccess_kernel_put_byte:
+		stmfd	sp!, {lr}
+		strb	r0, [r1]
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = x, r1 = addr, r2 = error
+@ Out: r2 = error
+uaccess_kernel_put_half:
+		stmfd	sp!, {lr}
+		strb	r0, [r1]
+		mov	r0, r0, lsr #8
+		strb	r0, [r1, #1]
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = x, r1 = addr, r2 = error
+@ Out: r2 = error
+uaccess_kernel_put_word:
+		stmfd	sp!, {lr}
+		str	r0, [r1]
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = addr, r1 = error
+@ Out: r0 = x, r1 = error
+uaccess_kernel_get_byte:
+		stmfd	sp!, {lr}
+		ldrb	r0, [r0]
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = addr, r1 = error
+@ Out: r0 = x, r1 = error
+uaccess_kernel_get_half:
+		stmfd	sp!, {lr}
+		ldr	r0, [r0]
+		mov	r0, r0, lsl #16
+		mov	r0, r0, lsr #16
+		ldmfd	sp!, {pc}^
+
+@ In : r0 = addr, r1 = error
+@ Out: r0 = x, r1 = error
+uaccess_kernel_get_word:
+		stmfd	sp!, {lr}
+		ldr	r0, [r0]
+		ldmfd	sp!, {pc}^
+
+
+/* Prototype: int uaccess_kernel_copy(void *to, const char *from, size_t n)
+ * Purpose  : copy a block to kernel memory from kernel memory
+ * Params   : to   - kernel memory
+ *          : from - kernel memory
+ *          : n    - number of bytes to copy
+ * Returns  : Number of bytes NOT copied.
+ */
+uaccess_kernel_copy:
+		stmfd	sp!, {lr}
+		bl	SYMBOL_NAME(memcpy)
+		mov	r0, #0
+		ldmfd	sp!, {pc}^
+
+/* Prototype: int uaccess_kernel_clear(void *addr, size_t sz)
+ * Purpose  : clear some kernel memory
+ * Params   : addr - kernel memory address to clear
+ *          : sz   - number of bytes to clear
+ * Returns  : number of bytes NOT cleared
+ */
+uaccess_kernel_clear:
+		stmfd	sp!, {lr}
+		mov	r2, #0
+		cmp	r1, #4
+		blt	2f
+		ands	ip, r0, #3
+		beq	1f
+		cmp	ip, #1
+		strb	r2, [r0], #1
+		strleb	r2, [r0], #1
+		strltb	r2, [r0], #1
+		rsb	ip, ip, #4
+		sub	r1, r1, ip		@  7  6  5  4  3  2  1
+1:		subs	r1, r1, #8		@ -1 -2 -3 -4 -5 -6 -7
+		bmi	2f
+		str	r2, [r0], #4
+		str	r2, [r0], #4
+		b	1b
+2:		adds	r1, r1, #4		@  3  2  1  0 -1 -2 -3
+		strpl	r2, [r0], #4
+		tst	r1, #2			@ 1x 1x 0x 0x 1x 1x 0x
+		strneb	r2, [r0], #1
+		strneb	r2, [r0], #1
+		tst	r1, #1			@ x1 x0 x1 x0 x1 x0 x1
+		strneb	r2, [r0], #1
+		mov	r0, #0
+		ldmfd	sp!, {pc}^
+
+/* Prototype: size_t uaccess_kernel_strncpy_from(char *dst, char *src, size_t len)
+ * Purpose  : copy a string from kernel memory to kernel memory
+ * Params   : dst - kernel memory destination
+ *          : src - kernel memory source
+ *          : len - maximum length of string
+ * Returns  : number of characters copied
+ */
+uaccess_kernel_strncpy_from:
+		stmfd	sp!, {lr}
+		mov	ip, r2
+1:		subs	r2, r2, #1
+		bmi	2f
+		ldrb	r3, [r1], #1
+		strb	r3, [r0], #1
+		teq	r3, #0
+		bne	1b
+2:		subs	r0, ip, r2
+		ldmfd	sp!, {pc}^
+
+/* Prototype: int uaccess_kernel_strlen(char *str, long n)
+ * Purpose  : get length of a string in kernel memory
+ * Params   : str - address of string in kernel memory
+ * Returns  : length of string *including terminator*,
+ *            or zero on exception, or n + 1 if too long
+ */
+uaccess_kernel_strnlen:
+		stmfd	sp!, {lr}
+		mov	r2, r0
+1:		ldrb	r1, [r0], #1
+		teq	r1, #0
+		beq	2f
+		subs	r1, r1, #1
+		bne	1b
+		add	r0, r0, #1
+2:		sub	r0, r0, r2
+		ldmfd	sp!, {pc}^
+
diff -urN linux-2.4.29/arch/armnommu/lib/uaccess.S linux-2.4.29-uc1/arch/armnommu/lib/uaccess.S
--- linux-2.4.29/arch/armnommu/lib/uaccess.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/lib/uaccess.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,939 @@
+/*
+ *  linux/arch/arm/lib/uaccess.S
+ *
+ *  Copyright (C) 1995, 1996,1997,1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Routines to block copy data to/from user memory
+ *   These are highly optimised both for the 4k page size
+ *   and for various alignments.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/errno.h>
+
+		.text
+
+#define PAGE_SHIFT 12
+
+/* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n)
+ * Purpose  : copy a block to user memory from kernel memory
+ * Params   : to   - user memory
+ *          : from - kernel memory
+ *          : n    - number of bytes to copy
+ * Returns  : Number of bytes NOT copied.
+ */
+
+.c2u_dest_not_aligned:
+		rsb	ip, ip, #4
+		cmp	ip, #2
+		ldrb	r3, [r1], #1
+USER(		strbt	r3, [r0], #1)			@ May fault
+		ldrgeb	r3, [r1], #1
+USER(		strgebt	r3, [r0], #1)			@ May fault
+		ldrgtb	r3, [r1], #1
+USER(		strgtbt	r3, [r0], #1)			@ May fault
+		sub	r2, r2, ip
+		b	.c2u_dest_aligned
+
+ENTRY(__arch_copy_to_user)
+		stmfd	sp!, {r2, r4 - r7, lr}
+		cmp	r2, #4
+		blt	.c2u_not_enough
+		ands	ip, r0, #3
+		bne	.c2u_dest_not_aligned
+.c2u_dest_aligned:
+
+		ands	ip, r1, #3
+		bne	.c2u_src_not_aligned
+/*
+ * Seeing as there has to be at least 8 bytes to copy, we can
+ * copy one word, and force a user-mode page fault...
+ */
+
+.c2u_0fupi:	subs	r2, r2, #4
+		addmi	ip, r2, #4
+		bmi	.c2u_0nowords
+		ldr	r3, [r1], #4
+USER(		strt	r3, [r0], #4)			@ May fault
+		mov	ip, r0, lsl #32 - PAGE_SHIFT	@ On each page, use a ld/st??t instruction
+		rsb	ip, ip, #0
+		movs	ip, ip, lsr #32 - PAGE_SHIFT
+		beq	.c2u_0fupi
+/*
+ * ip = max no. of bytes to copy before needing another "strt" insn
+ */
+		cmp	r2, ip
+		movlt	ip, r2
+		sub	r2, r2, ip
+		subs	ip, ip, #32
+		blt	.c2u_0rem8lp
+
+.c2u_0cpy8lp:	ldmia	r1!, {r3 - r6}
+		stmia	r0!, {r3 - r6}			@ Shouldnt fault
+		ldmia	r1!, {r3 - r6}
+		stmia	r0!, {r3 - r6}			@ Shouldnt fault
+		subs	ip, ip, #32
+		bpl	.c2u_0cpy8lp
+.c2u_0rem8lp:	cmn	ip, #16
+		ldmgeia	r1!, {r3 - r6}
+		stmgeia	r0!, {r3 - r6}			@ Shouldnt fault
+		tst	ip, #8
+		ldmneia	r1!, {r3 - r4}
+		stmneia	r0!, {r3 - r4}			@ Shouldnt fault
+		tst	ip, #4
+		ldrne	r3, [r1], #4
+		strnet	r3, [r0], #4			@ Shouldnt fault
+		ands	ip, ip, #3
+		beq	.c2u_0fupi
+.c2u_0nowords:	teq	ip, #0
+		beq	.c2u_finished
+.c2u_nowords:	cmp	ip, #2
+		ldrb	r3, [r1], #1
+USER(		strbt	r3, [r0], #1)			@ May fault
+		ldrgeb	r3, [r1], #1
+USER(		strgebt	r3, [r0], #1)			@ May fault
+		ldrgtb	r3, [r1], #1
+USER(		strgtbt	r3, [r0], #1)			@ May fault
+		b	.c2u_finished
+
+.c2u_not_enough:
+		movs	ip, r2
+		bne	.c2u_nowords
+.c2u_finished:	mov	r0, #0
+		LOADREGS(fd,sp!,{r2, r4 - r7, pc})
+
+#ifndef __ARMEB__
+
+.c2u_src_not_aligned:
+		bic	r1, r1, #3
+		ldr	r7, [r1], #4
+		cmp	ip, #2
+		bgt	.c2u_3fupi
+		beq	.c2u_2fupi
+.c2u_1fupi:	subs	r2, r2, #4
+		addmi	ip, r2, #4
+		bmi	.c2u_1nowords
+		mov	r3, r7, pull #8
+		ldr	r7, [r1], #4
+		orr	r3, r3, r7, push #24
+USER(		strt	r3, [r0], #4)			@ May fault
+		mov	ip, r0, lsl #32 - PAGE_SHIFT
+		rsb	ip, ip, #0
+		movs	ip, ip, lsr #32 - PAGE_SHIFT
+		beq	.c2u_1fupi
+		cmp	r2, ip
+		movlt	ip, r2
+		sub	r2, r2, ip
+		subs	ip, ip, #16
+		blt	.c2u_1rem8lp
+
+.c2u_1cpy8lp:	mov	r3, r7, pull #8
+		ldmia	r1!, {r4 - r7}
+		orr	r3, r3, r4, push #24
+		mov	r4, r4, pull #8
+		orr	r4, r4, r5, push #24
+		mov	r5, r5, pull #8
+		orr	r5, r5, r6, push #24
+		mov	r6, r6, pull #8
+		orr	r6, r6, r7, push #24
+		stmia	r0!, {r3 - r6}			@ Shouldnt fault
+		subs	ip, ip, #16
+		bpl	.c2u_1cpy8lp
+.c2u_1rem8lp:	tst	ip, #8
+		movne	r3, r7, pull #8
+		ldmneia	r1!, {r4, r7}
+		orrne	r3, r3, r4, push #24
+		movne	r4, r4, pull #8
+		orrne	r4, r4, r7, push #24
+		stmneia	r0!, {r3 - r4}			@ Shouldnt fault
+		tst	ip, #4
+		movne	r3, r7, pull #8
+		ldrne	r7, [r1], #4
+		orrne	r3, r3, r7, push #24
+		strnet	r3, [r0], #4			@ Shouldnt fault
+		ands	ip, ip, #3
+		beq	.c2u_1fupi
+.c2u_1nowords:	mov	r3, r7, lsr #byte(1)
+		teq	ip, #0
+		beq	.c2u_finished
+		cmp	ip, #2
+USER(		strbt	r3, [r0], #1)			@ May fault
+		movge	r3, r7, lsr #byte(2)
+USER(		strgebt	r3, [r0], #1)			@ May fault
+		movgt	r3, r7, lsr #byte(3)
+USER(		strgtbt	r3, [r0], #1)			@ May fault
+		b	.c2u_finished
+
+.c2u_2fupi:	subs	r2, r2, #4
+		addmi	ip, r2, #4
+		bmi	.c2u_2nowords
+		mov	r3, r7, pull #16
+		ldr	r7, [r1], #4
+		orr	r3, r3, r7, push #16
+USER(		strt	r3, [r0], #4)			@ May fault
+		mov	ip, r0, lsl #32 - PAGE_SHIFT
+		rsb	ip, ip, #0
+		movs	ip, ip, lsr #32 - PAGE_SHIFT
+		beq	.c2u_2fupi
+		cmp	r2, ip
+		movlt	ip, r2
+		sub	r2, r2, ip
+		subs	ip, ip, #16
+		blt	.c2u_2rem8lp
+
+.c2u_2cpy8lp:	mov	r3, r7, pull #16
+		ldmia	r1!, {r4 - r7}
+		orr	r3, r3, r4, push #16
+		mov	r4, r4, pull #16
+		orr	r4, r4, r5, push #16
+		mov	r5, r5, pull #16
+		orr	r5, r5, r6, push #16
+		mov	r6, r6, pull #16
+		orr	r6, r6, r7, push #16
+		stmia	r0!, {r3 - r6}			@ Shouldnt fault
+		subs	ip, ip, #16
+		bpl	.c2u_2cpy8lp
+.c2u_2rem8lp:	tst	ip, #8
+		movne	r3, r7, pull #16
+		ldmneia	r1!, {r4, r7}
+		orrne	r3, r3, r4, push #16
+		movne	r4, r4, pull #16
+		orrne	r4, r4, r7, push #16
+		stmneia	r0!, {r3 - r4}			@ Shouldnt fault
+		tst	ip, #4
+		movne	r3, r7, pull #16
+		ldrne	r7, [r1], #4
+		orrne	r3, r3, r7, push #16
+		strnet	r3, [r0], #4			@ Shouldnt fault
+		ands	ip, ip, #3
+		beq	.c2u_2fupi
+.c2u_2nowords:	mov	r3, r7, lsr #byte(2)
+		teq	ip, #0
+		beq	.c2u_finished
+		cmp	ip, #2
+USER(		strbt	r3, [r0], #1)			@ May fault
+		movge	r3, r7, lsr #byte(3)
+USER(		strgebt	r3, [r0], #1)			@ May fault
+		ldrgtb	r3, [r1], #0
+USER(		strgtbt	r3, [r0], #1)			@ May fault
+		b	.c2u_finished
+
+.c2u_3fupi:	subs	r2, r2, #4
+		addmi	ip, r2, #4
+		bmi	.c2u_3nowords
+		mov	r3, r7, pull #24
+		ldr	r7, [r1], #4
+		orr	r3, r3, r7, push #8
+USER(		strt	r3, [r0], #4)			@ May fault
+		mov	ip, r0, lsl #32 - PAGE_SHIFT
+		rsb	ip, ip, #0
+		movs	ip, ip, lsr #32 - PAGE_SHIFT
+		beq	.c2u_3fupi
+		cmp	r2, ip
+		movlt	ip, r2
+		sub	r2, r2, ip
+		subs	ip, ip, #16
+		blt	.c2u_3rem8lp
+
+.c2u_3cpy8lp:	mov	r3, r7, pull #24
+		ldmia	r1!, {r4 - r7}
+		orr	r3, r3, r4, push #8
+		mov	r4, r4, pull #24
+		orr	r4, r4, r5, push #8
+		mov	r5, r5, pull #24
+		orr	r5, r5, r6, push #8
+		mov	r6, r6, pull #24
+		orr	r6, r6, r7, push #8
+		stmia	r0!, {r3 - r6}			@ Shouldnt fault
+		subs	ip, ip, #16
+		bpl	.c2u_3cpy8lp
+.c2u_3rem8lp:	tst	ip, #8
+		movne	r3, r7, pull #24
+		ldmneia	r1!, {r4, r7}
+		orrne	r3, r3, r4, push #8
+		movne	r4, r4, pull #24
+		orrne	r4, r4, r7, push #8
+		stmneia	r0!, {r3 - r4}			@ Shouldnt fault
+		tst	ip, #4
+		movne	r3, r7, pull #24
+		ldrne	r7, [r1], #4
+		orrne	r3, r3, r7, push #8
+		strnet	r3, [r0], #4			@ Shouldnt fault
+		ands	ip, ip, #3
+		beq	.c2u_3fupi
+.c2u_3nowords:	mov	r3, r7, lsr #byte(3)
+		teq	ip, #0
+		beq	.c2u_finished
+		cmp	ip, #2
+USER(		strbt	r3, [r0], #1)			@ May fault
+		ldrgeb	r3, [r1], #1
+USER(		strgebt	r3, [r0], #1)			@ May fault
+		ldrgtb	r3, [r1], #0
+USER(		strgtbt	r3, [r0], #1)			@ May fault
+		b	.c2u_finished
+
+#else
+		@ and now the BIG endian part ....
+
+.c2u_src_not_aligned:
+		bic     r1, r1, #3
+		ldr     r7, [r1], #4
+		cmp     ip, #2
+		bgt     .c2u_3fupi
+		beq     .c2u_2fupi
+.c2u_1fupi:	subs    r2, r2, #4
+		addmi   ip, r2, #4
+		bmi     .c2u_1nowords
+		mov     r3, r7, lsl #8
+		ldr     r7, [r1], #4
+		orr     r3, r3, r7, lsr #24
+USER(		strt    r3, [r0], #4)                   @ May fault
+		mov     ip, r0, lsl #32 - PAGE_SHIFT
+		rsb     ip, ip, #0
+		movs    ip, ip, lsr #32 - PAGE_SHIFT
+		beq     .c2u_1fupi
+		cmp     r2, ip
+		movlt   ip, r2
+		sub     r2, r2, ip
+		subs    ip, ip, #16
+		blt     .c2u_1rem8lp
+
+.c2u_1cpy8lp:	mov     r3, r7, lsl #8
+		ldmia   r1!, {r4 - r7}
+		orr     r3, r3, r4, lsr #24
+		mov     r4, r4, lsl #8
+		orr     r4, r4, r5, lsr #24
+		mov     r5, r5, lsl #8
+		orr     r5, r5, r6, lsr #24
+		mov     r6, r6, lsl #8
+		orr     r6, r6, r7, lsr #24
+		stmia   r0!, {r3 - r6}                  @ Shouldnt fault
+		subs    ip, ip, #16
+		bpl     .c2u_1cpy8lp
+.c2u_1rem8lp:	tst     ip, #8
+		movne   r3, r7, lsl #8
+		ldmneia r1!, {r4, r7}
+		orrne   r3, r3, r4, lsr #24
+		movne   r4, r4, lsl #8
+		orrne   r4, r4, r7, lsr #24
+		stmneia r0!, {r3 - r4}                  @ Shouldnt fault
+		tst     ip, #4
+		movne   r3, r7, lsl #8
+		ldrne   r7, [r1], #4
+		orrne   r3, r3, r7, lsr #24
+		strnet  r3, [r0], #4                    @ Shouldnt fault
+		ands    ip, ip, #3
+		beq     .c2u_1fupi
+.c2u_1nowords:	mov     r3, r7, lsr #16   @ and careful around the corners ....
+		teq     ip, #0
+		beq     .c2u_finished
+		cmp     ip, #2
+USER(		strbt   r3, [r0], #1)                   @ May fault
+		movge   r3, r7, lsr #8
+USER(		strgebt r3, [r0], #1)                   @ May fault
+		movgt   r3, r7
+USER(		strgtbt r3, [r0], #1)                   @ May fault
+		b       .c2u_finished
+
+.c2u_2fupi:	subs    r2, r2, #4
+		addmi   ip, r2, #4
+		bmi     .c2u_2nowords
+		mov     r3, r7, lsl #16
+		ldr     r7, [r1], #4
+		orr     r3, r3, r7, lsr #16
+USER(		strt    r3, [r0], #4)                   @ May fault
+		mov     ip, r0, lsl #32 - PAGE_SHIFT
+		rsb     ip, ip, #0
+		movs    ip, ip, lsr #32 - PAGE_SHIFT
+		beq     .c2u_2fupi
+		cmp     r2, ip
+		movlt   ip, r2
+		sub     r2, r2, ip
+		subs    ip, ip, #16
+		blt     .c2u_2rem8lp
+
+.c2u_2cpy8lp:	mov     r3, r7, lsl #16
+		ldmia   r1!, {r4 - r7}
+		orr     r3, r3, r4, lsr #16
+		mov     r4, r4, lsl #16
+		orr     r4, r4, r5, lsr #16
+		mov     r5, r5, lsl #16
+		orr     r5, r5, r6, lsr #16
+		mov     r6, r6, lsl #16
+		orr     r6, r6, r7, lsr #16
+		stmia   r0!, {r3 - r6}                  @ Shouldnt fault
+		subs    ip, ip, #16
+		bpl     .c2u_2cpy8lp
+.c2u_2rem8lp:	tst     ip, #8
+		movne   r3, r7, lsl #16
+		ldmneia r1!, {r4, r7}
+		orrne   r3, r3, r4, lsr #16
+		movne   r4, r4, lsl #16
+		orrne   r4, r4, r7, lsr #16
+		stmneia r0!, {r3 - r4}                  @ Shouldnt fault
+		tst     ip, #4
+		movne   r3, r7, lsl #16
+		ldrne   r7, [r1], #4
+		orrne   r3, r3, r7, lsr #16
+		strnet  r3, [r0], #4                    @ Shouldnt fault
+		ands    ip, ip, #3
+		beq     .c2u_2fupi
+.c2u_2nowords:	mov     r3, r7, lsr #8
+		teq     ip, #0
+		beq     .c2u_finished
+		cmp     ip, #2
+USER(		strbt   r3, [r0], #1)                   @ May fault
+		movge   r3, r7
+USER(		strgebt r3, [r0], #1)                   @ May fault
+		ldrgtb  r3, [r1], #0
+USER(		strgtbt r3, [r0], #1)                   @ May fault
+		b       .c2u_finished
+
+.c2u_3fupi:	subs    r2, r2, #4
+		addmi   ip, r2, #4
+		bmi     .c2u_3nowords
+		mov     r3, r7, lsl #24
+		ldr     r7, [r1], #4
+		orr     r3, r3, r7, lsr #8
+USER(		strt    r3, [r0], #4)                   @ May fault
+		mov     ip, r0, lsl #32 - PAGE_SHIFT
+		rsb     ip, ip, #0
+		movs    ip, ip, lsr #32 - PAGE_SHIFT
+		beq     .c2u_3fupi
+		cmp     r2, ip
+		movlt   ip, r2
+		sub     r2, r2, ip
+		subs    ip, ip, #16
+		blt     .c2u_3rem8lp
+
+.c2u_3cpy8lp:	mov     r3, r7, lsl #24
+		ldmia   r1!, {r4 - r7}
+		orr     r3, r3, r4, lsr #8
+		mov     r4, r4, lsl #24
+		orr     r4, r4, r5, lsr #8
+		mov     r5, r5, lsl #24
+		orr     r5, r5, r6, lsr #8
+		mov     r6, r6, lsl #24
+		orr     r6, r6, r7, lsr #8
+		stmia   r0!, {r3 - r6}                  @ Shouldnt fault
+		subs    ip, ip, #16
+		bpl     .c2u_3cpy8lp
+.c2u_3rem8lp:	tst     ip, #8
+		movne   r3, r7, lsl #24
+		ldmneia r1!, {r4, r7}
+		orrne   r3, r3, r4, lsr #8
+		movne   r4, r4, lsl #24
+		orrne   r4, r4, r7, lsr #8
+		stmneia r0!, {r3 - r4}                  @ Shouldnt fault
+		tst     ip, #4
+		movne   r3, r7, lsl #24
+		ldrne   r7, [r1], #4
+		orrne   r3, r3, r7, lsr #8
+		strnet  r3, [r0], #4                    @ Shouldnt fault
+		ands    ip, ip, #3
+		beq     .c2u_3fupi
+.c2u_3nowords:	mov     r3, r7
+		teq     ip, #0
+		beq     .c2u_finished
+		cmp     ip, #2
+
+USER(		strbt   r3, [r0], #1)                   @ May fault
+		ldrgeb  r3, [r1], #1
+USER(		strgebt r3, [r0], #1)                   @ May fault
+		ldrgtb  r3, [r1], #1
+USER(		strgtbt r3, [r0], #1)                   @ May fault
+		b       .c2u_finished
+
+#endif
+
+		.section .fixup,"ax"
+		.align	0
+9001:		LOADREGS(fd,sp!, {r0, r4 - r7, pc})
+		.previous
+
+/* Prototype: unsigned long __arch_copy_from_user(void *to,const void *from,unsigned long n);
+ * Purpose  : copy a block from user memory to kernel memory
+ * Params   : to   - kernel memory
+ *          : from - user memory
+ *          : n    - number of bytes to copy
+ * Returns  : Number of bytes NOT copied.
+ */
+.cfu_dest_not_aligned:
+		rsb	ip, ip, #4
+		cmp	ip, #2
+USER(		ldrbt	r3, [r1], #1)			@ May fault
+		strb	r3, [r0], #1
+USER(		ldrgebt	r3, [r1], #1)			@ May fault
+		strgeb	r3, [r0], #1
+USER(		ldrgtbt	r3, [r1], #1)			@ May fault
+		strgtb	r3, [r0], #1
+		sub	r2, r2, ip
+		b	.cfu_dest_aligned
+
+ENTRY(__arch_copy_from_user)
+		stmfd	sp!, {r0, r2, r4 - r7, lr}
+		cmp	r2, #4
+		blt	.cfu_not_enough
+		ands	ip, r0, #3
+		bne	.cfu_dest_not_aligned
+.cfu_dest_aligned:
+		ands	ip, r1, #3
+		bne	.cfu_src_not_aligned
+/*
+ * Seeing as there has to be at least 8 bytes to copy, we can
+ * copy one word, and force a user-mode page fault...
+ */
+
+.cfu_0fupi:	subs	r2, r2, #4
+		addmi	ip, r2, #4
+		bmi	.cfu_0nowords
+USER(		ldrt	r3, [r1], #4)
+		str	r3, [r0], #4
+		mov	ip, r1, lsl #32 - PAGE_SHIFT	@ On each page, use a ld/st??t instruction
+		rsb	ip, ip, #0
+		movs	ip, ip, lsr #32 - PAGE_SHIFT
+		beq	.cfu_0fupi
+/*
+ * ip = max no. of bytes to copy before needing another "strt" insn
+ */
+		cmp	r2, ip
+		movlt	ip, r2
+		sub	r2, r2, ip
+		subs	ip, ip, #32
+		blt	.cfu_0rem8lp
+
+.cfu_0cpy8lp:	ldmia	r1!, {r3 - r6}			@ Shouldnt fault
+		stmia	r0!, {r3 - r6}
+		ldmia	r1!, {r3 - r6}			@ Shouldnt fault
+		stmia	r0!, {r3 - r6}
+		subs	ip, ip, #32
+		bpl	.cfu_0cpy8lp
+.cfu_0rem8lp:	cmn	ip, #16
+		ldmgeia	r1!, {r3 - r6}			@ Shouldnt fault
+		stmgeia	r0!, {r3 - r6}
+		tst	ip, #8
+		ldmneia	r1!, {r3 - r4}			@ Shouldnt fault
+		stmneia	r0!, {r3 - r4}
+		tst	ip, #4
+		ldrnet	r3, [r1], #4			@ Shouldnt fault
+		strne	r3, [r0], #4
+		ands	ip, ip, #3
+		beq	.cfu_0fupi
+.cfu_0nowords:	teq	ip, #0
+		beq	.cfu_finished
+.cfu_nowords:	cmp	ip, #2
+USER(		ldrbt	r3, [r1], #1)			@ May fault
+		strb	r3, [r0], #1
+USER(		ldrgebt	r3, [r1], #1)			@ May fault
+		strgeb	r3, [r0], #1
+USER(		ldrgtbt	r3, [r1], #1)			@ May fault
+		strgtb	r3, [r0], #1
+		b	.cfu_finished
+
+.cfu_not_enough:
+		movs	ip, r2
+		bne	.cfu_nowords
+.cfu_finished:	mov	r0, #0
+		add	sp, sp, #8
+		LOADREGS(fd,sp!,{r4 - r7, pc})
+
+#ifndef __ARMEB__
+
+.cfu_src_not_aligned:
+		bic	r1, r1, #3
+USER(		ldrt	r7, [r1], #4)			@ May fault
+		cmp	ip, #2
+		bgt	.cfu_3fupi
+		beq	.cfu_2fupi
+.cfu_1fupi:	subs	r2, r2, #4
+		addmi	ip, r2, #4
+		bmi	.cfu_1nowords
+		mov	r3, r7, pull #8
+USER(		ldrt	r7, [r1], #4)			@ May fault
+		orr	r3, r3, r7, push #24
+		str	r3, [r0], #4
+		mov	ip, r1, lsl #32 - PAGE_SHIFT
+		rsb	ip, ip, #0
+		movs	ip, ip, lsr #32 - PAGE_SHIFT
+		beq	.cfu_1fupi
+		cmp	r2, ip
+		movlt	ip, r2
+		sub	r2, r2, ip
+		subs	ip, ip, #16
+		blt	.cfu_1rem8lp
+
+.cfu_1cpy8lp:	mov	r3, r7, pull #8
+		ldmia	r1!, {r4 - r7}			@ Shouldnt fault
+		orr	r3, r3, r4, push #24
+		mov	r4, r4, pull #8
+		orr	r4, r4, r5, push #24
+		mov	r5, r5, pull #8
+		orr	r5, r5, r6, push #24
+		mov	r6, r6, pull #8
+		orr	r6, r6, r7, push #24
+		stmia	r0!, {r3 - r6}
+		subs	ip, ip, #16
+		bpl	.cfu_1cpy8lp
+.cfu_1rem8lp:	tst	ip, #8
+		movne	r3, r7, pull #8
+		ldmneia	r1!, {r4, r7}			@ Shouldnt fault
+		orrne	r3, r3, r4, push #24
+		movne	r4, r4, pull #8
+		orrne	r4, r4, r7, push #24
+		stmneia	r0!, {r3 - r4}
+		tst	ip, #4
+		movne	r3, r7, pull #8
+USER(		ldrnet	r7, [r1], #4)			@ May fault
+		orrne	r3, r3, r7, push #24
+		strne	r3, [r0], #4
+		ands	ip, ip, #3
+		beq	.cfu_1fupi
+.cfu_1nowords:	mov	r3, r7, lsr #byte(1)
+		teq	ip, #0
+		beq	.cfu_finished
+		cmp	ip, #2
+		strb	r3, [r0], #1
+		movge	r3, r7, lsr #byte(2)
+		strgeb	r3, [r0], #1
+		movgt	r3, r7, lsr #byte(3)
+		strgtb	r3, [r0], #1
+		b	.cfu_finished
+
+.cfu_2fupi:	subs	r2, r2, #4
+		addmi	ip, r2, #4
+		bmi	.cfu_2nowords
+		mov	r3, r7, pull #16
+USER(		ldrt	r7, [r1], #4)			@ May fault
+		orr	r3, r3, r7, push #16
+		str	r3, [r0], #4
+		mov	ip, r1, lsl #32 - PAGE_SHIFT
+		rsb	ip, ip, #0
+		movs	ip, ip, lsr #32 - PAGE_SHIFT
+		beq	.cfu_2fupi
+		cmp	r2, ip
+		movlt	ip, r2
+		sub	r2, r2, ip
+		subs	ip, ip, #16
+		blt	.cfu_2rem8lp
+
+.cfu_2cpy8lp:	mov	r3, r7, pull #16
+		ldmia	r1!, {r4 - r7}			@ Shouldnt fault
+		orr	r3, r3, r4, push #16
+		mov	r4, r4, pull #16
+		orr	r4, r4, r5, push #16
+		mov	r5, r5, pull #16
+		orr	r5, r5, r6, push #16
+		mov	r6, r6, pull #16
+		orr	r6, r6, r7, push #16
+		stmia	r0!, {r3 - r6}
+		subs	ip, ip, #16
+		bpl	.cfu_2cpy8lp
+.cfu_2rem8lp:	tst	ip, #8
+		movne	r3, r7, pull #16
+		ldmneia	r1!, {r4, r7}			@ Shouldnt fault
+		orrne	r3, r3, r4, push #16
+		movne	r4, r4, pull #16
+		orrne	r4, r4, r7, push #16
+		stmneia	r0!, {r3 - r4}
+		tst	ip, #4
+		movne	r3, r7, pull #16
+USER(		ldrnet	r7, [r1], #4)			@ May fault
+		orrne	r3, r3, r7, push #16
+		strne	r3, [r0], #4
+		ands	ip, ip, #3
+		beq	.cfu_2fupi
+.cfu_2nowords:	mov	r3, r7, lsr #byte(2)
+		teq	ip, #0
+		beq	.cfu_finished
+		cmp	ip, #2
+		strb	r3, [r0], #1
+		movge	r3, r7, lsr #byte(3)
+		strgeb	r3, [r0], #1
+USER(		ldrgtbt	r3, [r1], #0)			@ May fault
+		strgtb	r3, [r0], #1
+		b	.cfu_finished
+
+.cfu_3fupi:	subs	r2, r2, #4
+		addmi	ip, r2, #4
+		bmi	.cfu_3nowords
+		mov	r3, r7, pull #24
+USER(		ldrt	r7, [r1], #4)			@ May fault
+		orr	r3, r3, r7, push #8
+		str	r3, [r0], #4
+		mov	ip, r1, lsl #32 - PAGE_SHIFT
+		rsb	ip, ip, #0
+		movs	ip, ip, lsr #32 - PAGE_SHIFT
+		beq	.cfu_3fupi
+		cmp	r2, ip
+		movlt	ip, r2
+		sub	r2, r2, ip
+		subs	ip, ip, #16
+		blt	.cfu_3rem8lp
+
+.cfu_3cpy8lp:	mov	r3, r7, pull #24
+		ldmia	r1!, {r4 - r7}			@ Shouldnt fault
+		orr	r3, r3, r4, push #8
+		mov	r4, r4, pull #24
+		orr	r4, r4, r5, push #8
+		mov	r5, r5, pull #24
+		orr	r5, r5, r6, push #8
+		mov	r6, r6, pull #24
+		orr	r6, r6, r7, push #8
+		stmia	r0!, {r3 - r6}
+		subs	ip, ip, #16
+		bpl	.cfu_3cpy8lp
+.cfu_3rem8lp:	tst	ip, #8
+		movne	r3, r7, pull #24
+		ldmneia	r1!, {r4, r7}			@ Shouldnt fault
+		orrne	r3, r3, r4, push #8
+		movne	r4, r4, pull #24
+		orrne	r4, r4, r7, push #8
+		stmneia	r0!, {r3 - r4}
+		tst	ip, #4
+		movne	r3, r7, pull #24
+USER(		ldrnet	r7, [r1], #4)			@ May fault
+		orrne	r3, r3, r7, push #8
+		strne	r3, [r0], #4
+		ands	ip, ip, #3
+		beq	.cfu_3fupi
+.cfu_3nowords:	mov	r3, r7, lsr #byte(3)
+		teq	ip, #0
+		beq	.cfu_finished
+		cmp	ip, #2
+		strb	r3, [r0], #1
+USER(		ldrgebt	r3, [r1], #1)			@ May fault
+		strgeb	r3, [r0], #1
+USER(		ldrgtbt	r3, [r1], #1)			@ May fault
+		strgtb	r3, [r0], #1
+		b	.cfu_finished
+
+#else
+		@ and now the BIG endian part
+.cfu_src_not_aligned:
+		bic     r1, r1, #3
+USER(		ldrt    r7, [r1], #4)                   @ May fault
+		cmp     ip, #2
+		bgt     .cfu_3fupi
+		beq     .cfu_2fupi
+		.cfu_1fupi:   subs    r2, r2, #4
+		addmi   ip, r2, #4
+		bmi     .cfu_1nowords
+		mov     r3, r7, lsl #8
+USER(		ldrt    r7, [r1], #4)                   @ May fault
+		orr     r3, r3, r7, lsr #24
+		str     r3, [r0], #4
+		mov     ip, r1, lsl #32 - PAGE_SHIFT
+		rsb     ip, ip, #0
+		movs    ip, ip, lsr #32 - PAGE_SHIFT
+		beq     .cfu_1fupi
+		cmp     r2, ip
+		movlt   ip, r2
+		sub     r2, r2, ip
+		subs    ip, ip, #16
+		blt     .cfu_1rem8lp
+
+.cfu_1cpy8lp:	mov     r3, r7, lsl #8
+		ldmia   r1!, {r4 - r7}                  @ Shouldnt fault
+		orr     r3, r3, r4, lsr #24
+		mov     r4, r4, lsl #8
+		orr     r4, r4, r5, lsr #24
+		mov     r5, r5, lsl #8
+		orr     r5, r5, r6, lsr #24
+		mov     r6, r6, lsl #8
+		orr     r6, r6, r7, lsr #24
+		stmia   r0!, {r3 - r6}
+		subs    ip, ip, #16
+		bpl     .cfu_1cpy8lp
+.cfu_1rem8lp:	tst     ip, #8
+		movne   r3, r7, lsl #8
+		ldmneia r1!, {r4, r7}                   @ Shouldnt fault
+		orrne   r3, r3, r4, lsr #24
+		movne   r4, r4, lsl #8
+		orrne   r4, r4, r7, lsr #24
+		stmneia r0!, {r3 - r4}
+		tst     ip, #4
+		movne   r3, r7, lsl #8
+USER(		ldrnet  r7, [r1], #4)                   @ May fault
+		orrne   r3, r3, r7, lsr #24
+		strne   r3, [r0], #4
+		ands    ip, ip, #3
+		beq     .cfu_1fupi
+.cfu_1nowords:	mov     r3, r7, lsr #16                 @ and careful
+		teq     ip, #0
+		beq     .cfu_finished
+		cmp     ip, #2
+		strb    r3, [r0], #1
+		movge   r3, r7, lsr #8
+		strgeb  r3, [r0], #1
+		movgt   r3, r7
+		strgtb  r3, [r0], #1
+		b       .cfu_finished
+
+.cfu_2fupi:	subs    r2, r2, #4
+		addmi   ip, r2, #4
+		bmi     .cfu_2nowords
+		mov     r3, r7, lsl #16
+USER(		ldrt    r7, [r1], #4)                   @ May fault
+		orr     r3, r3, r7, lsr #16
+		str     r3, [r0], #4
+		mov     ip, r1, lsl #32 - PAGE_SHIFT
+		rsb     ip, ip, #0
+		movs    ip, ip, lsr #32 - PAGE_SHIFT
+		beq     .cfu_2fupi
+		cmp     r2, ip
+		movlt   ip, r2
+		sub     r2, r2, ip
+		subs    ip, ip, #16
+		blt     .cfu_2rem8lp
+
+.cfu_2cpy8lp:	mov     r3, r7, lsl #16
+		ldmia   r1!, {r4 - r7}                  @ Shouldnt fault
+		orr     r3, r3, r4, lsr #16
+		mov     r4, r4, lsl #16
+		orr     r4, r4, r5, lsr #16
+		mov     r5, r5, lsl #16
+		orr     r5, r5, r6, lsr #16
+		mov     r6, r6, lsl #16
+		orr     r6, r6, r7, lsr #16
+		stmia   r0!, {r3 - r6}
+		subs    ip, ip, #16
+		bpl     .cfu_2cpy8lp
+.cfu_2rem8lp:	tst     ip, #8
+		movne   r3, r7, lsl #16
+		ldmneia r1!, {r4, r7}                   @ Shouldnt fault
+		orrne   r3, r3, r4, lsr #16
+		movne   r4, r4, lsl #16
+		orrne   r4, r4, r7, lsr #16
+		stmneia r0!, {r3 - r4}
+		tst     ip, #4
+		movne   r3, r7, lsl #16
+USER(		ldrnet  r7, [r1], #4)                   @ May fault
+		orrne   r3, r3, r7, lsr #16
+		strne   r3, [r0], #4
+		ands    ip, ip, #3
+		beq     .cfu_2fupi
+.cfu_2nowords:	mov     r3, r7, lsr #8                  @ and careful ..
+		teq     ip, #0
+		beq     .cfu_finished
+		cmp     ip, #2
+		strb    r3, [r0], #1
+		movge   r3, r7
+		strgeb  r3, [r0], #1
+USER(		ldrgtbt r3, [r1], #0)                   @ May fault
+		strgtb  r3, [r0], #1
+		b       .cfu_finished
+
+.cfu_3fupi:	subs    r2, r2, #4
+		addmi   ip, r2, #4
+		bmi     .cfu_3nowords
+		mov     r3, r7, lsl #24
+USER(		ldrt    r7, [r1], #4)                   @ May fault
+		orr     r3, r3, r7, lsr #8
+		str     r3, [r0], #4
+		mov     ip, r1, lsl #32 - PAGE_SHIFT
+		rsb     ip, ip, #0
+		movs    ip, ip, lsr #32 - PAGE_SHIFT
+		beq     .cfu_3fupi
+		cmp     r2, ip
+		movlt   ip, r2
+		sub     r2, r2, ip
+		subs    ip, ip, #16
+		blt     .cfu_3rem8lp
+
+.cfu_3cpy8lp:	mov     r3, r7, lsl #24
+		ldmia   r1!, {r4 - r7}                  @ Shouldnt fault
+		orr     r3, r3, r4, lsr #8
+		mov     r4, r4, lsl #24
+		orr     r4, r4, r5, lsr #8
+		mov     r5, r5, lsl #24
+		orr     r5, r5, r6, lsr #8
+		mov     r6, r6, lsl #24
+		orr     r6, r6, r7, lsr #8
+		stmia   r0!, {r3 - r6}
+		subs    ip, ip, #16
+		bpl     .cfu_3cpy8lp
+.cfu_3rem8lp:	tst     ip, #8
+		movne   r3, r7, lsl #24
+		ldmneia r1!, {r4, r7}                   @ Shouldnt fault
+		orrne   r3, r3, r4, lsr #8
+		movne   r4, r4, lsl #24
+		orrne   r4, r4, r7, lsr #8
+		stmneia r0!, {r3 - r4}
+		tst     ip, #4
+		movne   r3, r7, lsl #24
+USER(		ldrnet  r7, [r1], #4)                   @ May fault
+		orrne   r3, r3, r7, lsr #8
+		strne   r3, [r0], #4
+		ands    ip, ip, #3
+		beq     .cfu_3fupi
+.cfu_3nowords:	mov     r3, r7                          @ and careful ...
+		teq     ip, #0
+		beq     .cfu_finished
+		cmp     ip, #2
+		strb    r3, [r0], #1
+USER(		ldrgebt r3, [r1], #1)                   @ May fault
+		strgeb  r3, [r0], #1
+USER(		ldrgtbt r3, [r1], #1)                   @ May fault
+		strgtb  r3, [r0], #1
+		b       .cfu_finished
+
+#endif
+
+		.section .fixup,"ax"
+		.align	0
+		/*
+		 * We took an exception.  r0 contains a pointer to
+		 * the byte not copied.
+		 */
+9001:		ldr	r2, [sp], #4			@ void *to
+		sub	r2, r0, r2			@ bytes copied
+		ldr	r1, [sp], #4			@ unsigned long count
+		subs	r4, r1, r2			@ bytes left to copy
+		movne	r1, r4
+		blne	SYMBOL_NAME(__memzero)
+		mov	r0, r4
+		LOADREGS(fd,sp!, {r4 - r7, pc})
+		.previous
+
+/* Prototype: int __arch_clear_user(void *addr, size_t sz)
+ * Purpose  : clear some user memory
+ * Params   : addr - user memory address to clear
+ *          : sz   - number of bytes to clear
+ * Returns  : number of bytes NOT cleared
+ */
+ENTRY(__arch_clear_user)
+		stmfd	sp!, {r1, lr}
+		mov	r2, #0
+		cmp	r1, #4
+		blt	2f
+		ands	ip, r0, #3
+		beq	1f
+		cmp	ip, #2
+USER(		strbt	r2, [r0], #1)
+USER(		strlebt	r2, [r0], #1)
+USER(		strltbt	r2, [r0], #1)
+		rsb	ip, ip, #4
+		sub	r1, r1, ip		@  7  6  5  4  3  2  1
+1:		subs	r1, r1, #8		@ -1 -2 -3 -4 -5 -6 -7
+USER(		strplt	r2, [r0], #4)
+USER(		strplt	r2, [r0], #4)
+		bpl	1b
+		adds	r1, r1, #4		@  3  2  1  0 -1 -2 -3
+USER(		strplt	r2, [r0], #4)
+2:		tst	r1, #2			@ 1x 1x 0x 0x 1x 1x 0x
+USER(		strnebt	r2, [r0], #1)
+USER(		strnebt	r2, [r0], #1)
+		tst	r1, #1			@ x1 x0 x1 x0 x1 x0 x1
+USER(		strnebt	r2, [r0], #1)
+		mov	r0, #0
+		LOADREGS(fd,sp!, {r1, pc})
+
+		.section .fixup,"ax"
+		.align	0
+9001:		LOADREGS(fd,sp!, {r0, pc})
+		.previous
+
diff -urN linux-2.4.29/arch/armnommu/mach-atmel/arch.c linux-2.4.29-uc1/arch/armnommu/mach-atmel/arch.c
--- linux-2.4.29/arch/armnommu/mach-atmel/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-atmel/arch.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,26 @@
+/*
+ *  linux/arch/arm/mach-p52/arch.c
+ *
+ *  Architecture specific fixups.  This is where any
+ *  parameters in the params struct are fixed up, or
+ *  any additional architecture specific information
+ *  is pulled from the params struct.
+ */
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+
+#include <asm/elf.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+extern void genarch_init_irq(void);
+
+MACHINE_START(ATMEL, "EB01")
+       MAINTAINER("Erwin Authried")
+       INITIRQ(genarch_init_irq)
+MACHINE_END
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-atmel/irq.c linux-2.4.29-uc1/arch/armnommu/mach-atmel/irq.c
--- linux-2.4.29/arch/armnommu/mach-atmel/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-atmel/irq.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,136 @@
+/*
+ *  linux/arch/arm/mach-integrator/irq.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/init.h>
+
+#include <asm/mach/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+extern struct irqdesc irq_desc[];
+
+ /* Internal Sources */
+#define LevelSensitive              (0<<5)
+#define EdgeTriggered               (1<<5)
+
+ /* External Sources */
+#define LowLevel                    (0<<5)
+#define NegativeEdge                (1<<5)
+#define HighLevel                   (2<<5)
+#define PositiveEdge                (3<<5)
+
+static unsigned char eb01_irq_prtable[32] = {
+        7 << 5, /* FIQ */
+        0 << 5, /* SWIRQ */
+        0 << 5, /* US0IRQ */
+        0 << 5, /* US1IRQ */
+        2 << 5, /* TC0IRQ */
+        2 << 5, /* TC1IRQ */
+        2 << 5, /* TC2IRQ */
+        0 << 5, /* WDIRQ */
+        0 << 5, /* PIOAIRQ */
+        0 << 5, /* reserved */
+        0 << 5, /* reserved */
+        0 << 5, /* reserved */
+        0 << 5, /* reserved */
+        0 << 5, /* reserved */
+        0 << 5, /* reserved */
+        0 << 5, /* reserved */
+        1 << 5, /* IRQ0 */
+	0 << 5, /* IRQ1 */
+        0 << 5, /* IRQ2 */
+};
+
+static unsigned char eb01_irq_type[32] = {
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+
+        EdgeTriggered,	/* IRQ0 = neg. edge */
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+        EdgeTriggered,
+};
+
+void at91_mask_irq(unsigned int irq)
+{
+	unsigned long mask = 1 << (irq);
+	__arch_putl(mask, AIC_IDCR);
+}	
+
+void at91_unmask_irq(unsigned int irq)
+{
+	unsigned long mask = 1 << (irq);
+	__arch_putl(mask, AIC_IECR);
+}
+
+void at91_mask_ack_irq(unsigned int irq)
+{
+	at91_mask_irq(irq);
+}
+
+void at91_init_aic()
+{
+        int irqno;
+
+        /* Disable all interrupts */
+        __arch_putl(0xFFFFFFFF, AIC_IDCR);
+
+        /* Clear all interrupts	*/
+        __arch_putl(0xFFFFFFFF, AIC_ICCR);
+
+        for ( irqno = 0 ; irqno < 32 ; irqno++ )
+        {
+                __arch_putl(irqno, AIC_EOICR);
+        }
+
+        for ( irqno = 0 ; irqno < 32 ; irqno++ )
+        {
+            __arch_putl((eb01_irq_prtable[irqno] >> 5) | eb01_irq_type[irqno],
+		 AIC_SMR(irqno));
+        }
+}
+
diff -urN linux-2.4.29/arch/armnommu/mach-atmel/Makefile linux-2.4.29-uc1/arch/armnommu/mach-atmel/Makefile
--- linux-2.4.29/arch/armnommu/mach-atmel/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-atmel/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= atmel.o
+
+# Object file lists.
+
+obj-y			:= $(patsubst %.c, %.o, $(wildcard *.c))
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= 
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/arch.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/arch.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/arch.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,56 @@
+/****************************************************************************
+*
+*	Name:			arch.c
+*
+*	Description:	Architecture specific fixups.  This is where any
+*  					parameters in the params struct are fixed up, or
+*  					any additional architecture specific information
+*  					is pulled from the params struct.
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:22:06  $
+****************************************************************************/
+
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+
+#include <asm/elf.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+extern void cnxt_map_io(void);
+extern void cnxt_init_irq(void);
+extern void genarch_init_irq(void);
+
+
+MACHINE_START(CX821XX, "CNXT CX821XX")
+       BOOT_MEM(0xabcd1234, 0x56789abc, 0x12345678)
+       MAINTAINER("Conexant")
+       INITIRQ(genarch_init_irq)
+MACHINE_END
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/cacheenb.S linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cacheenb.S
--- linux-2.4.29/arch/armnommu/mach-cx821xx/cacheenb.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cacheenb.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,101 @@
+/****************************************************************************
+*
+*	Name:			sysalib.S
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:22:06  $
+****************************************************************************/
+
+/*
+NOTE
+The routines in this module don't use the "C" frame pointer %r11@ ! or
+establish a stack frame.
+
+*/
+
+
+#define _ASMLANGUAGE
+
+#include <asm/proc/assembler.h>
+
+/* internals */
+
+
+	.globl  cache_on
+	.globl  cache_off
+
+	.text
+	.balign 4
+
+
+/* No args */
+
+	.code	16	
+	.balign	4	
+	.thumb_func	
+	
+
+cache_on:
+	BX	pc	
+	NOP		
+	.code	32	
+
+	mrc	p15, 0, r0, c1, c0		@ read control register
+	orr	r0, r0, #0x0004			@ Enable D cache
+	orr	r0, r0, #0x1000			@ I Cache on
+	mcr	p15, 0, r0, c1, c0		@ update control register
+
+
+#if	((CPU == ARM7TDMI_T) || (CPU == ARMARCH4_T))
+	BX	lr
+#else
+	MOV	pc, lr
+#endif	/* (CPU == ARM7TDMI_T) */
+
+
+
+
+cache_off:
+	BX	pc	
+	NOP		
+	.code	32	
+
+
+	mrc	p15, 0, r0, c1, c0		@ read control register
+	bic	r0, r0, #0x0004			@ DCache
+	bic	r0, r0, #0x1000			@ ICache
+	mcr	p15, 0, r0, c1, c0		@ disabled
+
+	
+#if	((CPU == ARM7TDMI_T) || (CPU == ARMARCH4_T))
+	BX	lr
+#else
+	MOV	pc, lr
+#endif	/* (CPU == ARM7TDMI_T) */
+
+
+
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/cnxtadsl.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cnxtadsl.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/cnxtadsl.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cnxtadsl.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,413 @@
+/****************************************************************************
+*
+*	Name:				CNXTADSL.C
+*
+*
+*	Copyright:		(c) 2001 - 2003  Conexant Systems Inc.
+*
+*****************************************************************************
+*	$Author:   lewisrc  $
+*	$Revision:   1.2  $
+*	$Modtime:   Jul 17 2003 15:27:50  $
+****************************************************************************/
+
+#include    <linux/kernel.h>
+#include    <linux/types.h>
+#include    <linux/sched.h>
+#include    <linux/unistd.h>
+#include    "OsTools.h"
+#include    <linux/module.h>
+#include    <linux/init.h>
+
+#if defined (CONFIG_CNXT_ADSL)  ||  defined (CONFIG_CNXT_ADSL_MODULE) || defined (CONFIG_CNXT_GSHDSL) || defined (CONFIG_CNXT_GSHDSL_MODULE)
+#include    "bsptypes.h"
+#include    "bspcfg.h"
+
+#include    "gpio.h"
+#include    "ostimer.h"
+#include	"gptimer.h"
+#include    "cnxtirq.h"
+#include    "cnxtbsp.h"
+#include    "pwrmanag.h"
+#include    "dmasrv.h"
+#include    "syslib.h"
+
+#include    "cardinfo.h"
+#include    "dsl.h"
+#include    "dsl.h"
+#include    "dslbase.h"
+#include    "hwio.h"
+
+#include    "cnxtadsl.h"
+
+#define MAX_SHOWTIME_PARMS_ARRAY_SIZE 18
+static UINT32 ShowtimeParmsLastIndex= 0;
+static CARDPARAM ShowtimeParms[MAX_SHOWTIME_PARMS_ARRAY_SIZE];
+
+static int GetDataLastIndex = 0;
+static void CardGetInfo0(PCARDDATA pCardData);
+static void CardGetInfo1(PCARDDATA pCardData);
+static void CardGetInfo2(PCARDDATA pCardData);
+
+#define LED_DELAY_PERIOD   250 /* 250 ms */
+
+void CnxtAdslLEDTask(void *sem)
+{
+	BOOL HandShakeLED;
+	BOOL ShowtimeLED;
+
+	struct task_struct *tsk = current ;
+	tsk->session = 1 ;
+	tsk->pgrp = 1 ;
+#if defined (CONFIG_CNXT_GSHDSL) || defined (CONFIG_CNXT_GSHDSL_MODULE)
+	strcpy ( tsk->comm, "CnxtGshdslLEDTask" ) ;
+#else
+	strcpy ( tsk->comm, "CnxtAdslLEDTask" ) ;
+#endif
+
+	/* sigstop and sigcont will stop and wakeup kupdate */
+	spin_lock_irq(&tsk->sigmask_lock);
+	sigfillset(&tsk->blocked);
+	siginitsetinv(&current->blocked, sigmask(SIGCONT) | sigmask(SIGSTOP));
+	recalc_sigpending(tsk);
+	spin_unlock_irq(&tsk->sigmask_lock);
+
+	up((struct semaphore *)sem);
+
+	TaskDelayConnect ( GP_TIMER_DMT_LED ) ;
+	
+	while(1)
+	{
+		/* Condensed Showtime State to two Booleans - In Showtime and In Training */
+		ShowtimeLED= FALSE;
+		HandShakeLED= FALSE;
+
+		switch (HWSTATE.dwLineStatus)
+		{
+			case HW_IO_MODEM_STATUS_ACTIVATED:
+				ShowtimeLED= TRUE;
+				break;
+
+			case HW_IO_MODEM_STATUS_CHANNEL_ANALYSIS:
+			case HW_IO_MODEM_STATUS_TRANSCEIVER_TRAINING:
+			case HW_IO_MODEM_STATUS_EXCHANGE:
+			case HW_IO_MODEM_STATUS_ACTIVATION:
+				HandShakeLED= TRUE;
+				break;
+		}
+
+		/* Blink Showtime LED if in Training */
+		if (ShowtimeLED || HandShakeLED)
+		{
+			WriteGPIOData( GPOUT_SHOWTIME_LED,LED_ON );
+		}
+
+		/* This logic is for a blinking Showtime LED */
+		if (!ShowtimeLED)
+		{
+			WriteGPIOData( GPOUT_SHOWTIME_LED,LED_OFF );
+		}
+
+		TaskDelayMsec(LED_DELAY_PERIOD);
+
+	}
+}
+
+
+/* Initialization called from Showtime initialization */
+BOOL ADSL_Init(void)
+{
+    HWSTATE.eADSLLineState = ADSL_HW_INIT ;
+	return HWSTATE.eADSLLineState == ADSL_HW_INIT ? TRUE : FALSE;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+/* CP request for a new state */
+BOOL ADSL_RequestedLineState(BOOL Up)
+{
+	switch (HWSTATE.eADSLLineState)
+	{
+		case ADSL_SHOWTIME_UP:
+		case ADSL_SHOWTIME_DOWN:
+		case ADSL_HW_INIT:
+			HWSTATE.eADSLRequestLineState =
+			   Up ? ADSL_REQUEST_SHOWTIME_UP : ADSL_REQUEST_SHOWTIME_DOWN;
+			return TRUE;
+
+		default:
+			return FALSE;
+	}
+}
+
+/****************************************************************
+ ****************************************************************/
+
+/* Task 4 gets requested state */
+UINT32 ADSL_GetRequestedLineState(void)
+{
+	return HWSTATE.eADSLRequestLineState;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+UINT32 ADSL_LinkStatus(void)
+{
+	return HWSTATE.dwLineStatus;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+UINT32 ADSL_GetDownstreamDataRate(void)
+{
+	return HWSTATE.dwADSLDownRate;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+UINT32 ADSL_GetUpstreamDataRate(void)
+{
+	return HWSTATE.dwADSLUpRate;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+/* State machine for current ADSL state */
+UINT32 ADSL_UpdateState
+(
+	BOOL InShowtime,
+	UINT32 dwADSLDownRate,
+	UINT32 dwADSLUpRate,
+	UINT32 dwLineStatus,
+	PHW_IO_TRANSCEIVER_STATUS_T		pHwIoTransceiverStatus
+)
+{
+	UINT32 bReturn = TRUE;
+
+	/* Update BSP's state description of the Showtime code */
+	HWSTATE.dwADSLDownRate 				= dwADSLDownRate;
+	HWSTATE.dwADSLUpRate				= dwADSLUpRate;
+	HWSTATE.dwLineStatus				= dwLineStatus;
+
+	HWSTATE.Transmit_State				= pHwIoTransceiverStatus->Transmit_State;
+	HWSTATE.Receive_State				= pHwIoTransceiverStatus->Receive_State;
+	HWSTATE.Process_State				= pHwIoTransceiverStatus->Process_State;
+	HWSTATE.Up_SNR_Margin_Cur			= pHwIoTransceiverStatus->Up_SNR_Margin.Mar_Cur;
+	HWSTATE.Up_SNR_Margin_Min			= pHwIoTransceiverStatus->Up_SNR_Margin.Mar_Min;
+	HWSTATE.Up_SNR_Margin_MinBin		= pHwIoTransceiverStatus->Up_SNR_Margin.Mar_Min_Bin;
+	HWSTATE.Down_SNR_Margin_Cur			= pHwIoTransceiverStatus->Down_SNR_Margin.Mar_Cur;
+	HWSTATE.Down_SNR_Margin_Min			= pHwIoTransceiverStatus->Down_SNR_Margin.Mar_Min;
+	HWSTATE.Down_SNR_Margin_Min_Bin		= pHwIoTransceiverStatus->Down_SNR_Margin.Mar_Min_Bin;
+	HWSTATE.Up_Attn						= pHwIoTransceiverStatus->Up_Attn;
+	HWSTATE.Down_Attn					= pHwIoTransceiverStatus->Down_Attn;
+	HWSTATE.Tx_Power					= pHwIoTransceiverStatus->Tx_Power;
+	HWSTATE.Up_Bits_Per_Frame			= pHwIoTransceiverStatus->Up_Bits_Per_Frame;
+	HWSTATE.Down_Bits_Per_Frame			= pHwIoTransceiverStatus->Down_Bits_Per_Frame;
+	HWSTATE.Startup_Attempts			= pHwIoTransceiverStatus->Startup_Attempts;
+	HWSTATE.Up_CRC_Errors				= pHwIoTransceiverStatus->Up_CRC_Errors;
+	HWSTATE.Down_CRC_Errors				= pHwIoTransceiverStatus->Down_CRC_Errors;
+	HWSTATE.Up_FEC_Errors				= pHwIoTransceiverStatus->Up_FEC_Errors;
+	HWSTATE.Down_FEC_Errors				= pHwIoTransceiverStatus->Down_FEC_Errors;
+	HWSTATE.Up_HEC_Errors				= pHwIoTransceiverStatus->Up_HEC_Errors;
+	HWSTATE.Down_HEC_Errors				= pHwIoTransceiverStatus->Down_HEC_Errors;
+	HWSTATE.Retrain_Attempts			= pHwIoTransceiverStatus->Retrain_Attempts;
+
+	/*
+	** Request should be processed already so it is safe to clear request.
+	** For a request ADSL_DISABLE means "no request".
+	*/
+	HWSTATE.eADSLRequestLineState = ADSL_DISABLE;
+
+	switch (HWSTATE.eADSLLineState)
+	{
+		case ADSL_DISABLE:
+			break;
+
+		case ADSL_HW_INIT:
+			if (InShowtime)
+			{
+				/* If HWSTATE.eADSLLineState != ADSL_SHOWTIME_UP then DSL */
+				/* DMA will not be enabled. */
+				HWSTATE.eADSLLineState = ADSL_SHOWTIME_UP;
+				DmaOpenChannel(DMA_CHANNEL_DSL_TX);
+				DmaOpenChannel(DMA_CHANNEL_DSL_RX);
+				#if CONFIG_CNXT_SOFTSAR
+					//FrameALLineUp( SSpDrvCtrl );
+				#endif
+			}
+			break;
+
+		case ADSL_SHOWTIME_UP:
+			if (!InShowtime)
+			{
+				HWSTATE.eADSLLineState = ADSL_SHOWTIME_DOWN;
+				HWSTATE.dwADSLDownRate = 0;
+				HWSTATE.dwADSLUpRate = 0;
+
+				// NOTE: The order of the calls to DmaCloseChannel for the
+				// DSL channels must be in the exact reverse order as the
+				// calls to DmaOpenChannel.  This is because of a currently
+				// unsophisticated memory alloc/dealloc scheme in the 
+				// sysmem.c source file.
+				DmaCloseChannel(DMA_CHANNEL_DSL_RX);
+				DmaCloseChannel(DMA_CHANNEL_DSL_TX);
+				#if CONFIG_CNXT_SOFTSAR
+					//FrameALLineDown(  SSpDrvCtrl );
+				#endif
+			}
+			break;
+
+		case ADSL_SHOWTIME_DOWN:
+			if (InShowtime)
+			{
+				HWSTATE.eADSLLineState = ADSL_SHOWTIME_UP;
+				DmaOpenChannel(DMA_CHANNEL_DSL_TX);
+				DmaOpenChannel(DMA_CHANNEL_DSL_RX);
+				#if CONFIG_CNXT_SOFTSAR
+					//FrameALLineUp(  SSpDrvCtrl );
+				#endif
+			}
+			break;
+
+		default:
+			break;
+	}
+
+	return bReturn;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+void CardGetInfo0(PCARDDATA pCardData)
+{
+	pCardData->dwCount= 6;
+
+	pCardData->Param[0].dwIndex=CC_CFG_DOWNRATE;
+	pCardData->Param[0].dwValue=HWSTATE.dwADSLDownRate;
+
+	pCardData->Param[1].dwIndex=CC_CFG_UPRATE;
+	pCardData->Param[1].dwValue=HWSTATE.dwADSLUpRate;
+
+	pCardData->Param[2].dwIndex=CC_CFG_LINKSTATUS;
+	pCardData->Param[2].dwValue=HWSTATE.eADSLLineState;
+
+	pCardData->Param[3].dwIndex=CC_CFG_LINESTATUS;
+	pCardData->Param[3].dwValue=HWSTATE.dwLineStatus;
+
+	pCardData->Param[4].dwIndex=CC_CFG_MACADDRHIGH;
+	pCardData->Param[4].dwValue=HWSTATE.dwMACAddressHigh;
+
+	pCardData->Param[5].dwIndex=CC_CFG_MACADDRLOW;
+	pCardData->Param[5].dwValue=HWSTATE.dwMACAddressLow;
+}
+
+void CardGetInfo1(PCARDDATA pCardData)
+{
+#if 0
+	pCardData->dwCount= 7;
+
+	pCardData->Param[0].dwIndex=CC_CFG_CAPOCCUPATIONDNSTR;
+	pCardData->Param[0].dwValue=HWSTATE.R_relCapacityOccupationDnstr;
+
+	pCardData->Param[1].dwIndex=CC_CFG_NOISEMARGINDNSTR;
+	pCardData->Param[1].dwValue=HWSTATE.R_noiseMarginDnstr;
+
+	pCardData->Param[2].dwIndex=CC_CFG_OUTPUTPOWERDNSTR;
+	pCardData->Param[2].dwValue=HWSTATE.R_outputPowerDnstr;
+
+	pCardData->Param[3].dwIndex=CC_CFG_ATTENDNSTR;
+	pCardData->Param[3].dwValue=HWSTATE.R_attenuationDnstr;
+
+	pCardData->Param[4].dwIndex=CC_CFG_CAPOCCUPATIONUPSTR;
+	pCardData->Param[4].dwValue=HWSTATE.R_relCapacityOccupationUpstr;
+
+	pCardData->Param[5].dwIndex=CC_CFG_NOISEMARGINUPSTR;
+	pCardData->Param[5].dwValue=HWSTATE.R_noiseMarginUpstr;
+
+	pCardData->Param[6].dwIndex=CC_CFG_OUTPUTPOWERUPSTR;
+	pCardData->Param[6].dwValue=HWSTATE.R_outputPowerUpstr;
+#endif
+}
+
+void CardGetInfo2(PCARDDATA pCardData)
+{
+#if 0
+	pCardData->dwCount= 1;
+
+	pCardData->Param[0].dwIndex=CC_CFG_ATTENUPSTR;
+	pCardData->Param[0].dwValue=HWSTATE.R_attenuationUpstr;
+#endif
+}
+
+void CardGetInfo(PCARDDATA pCardData)
+{
+	switch (GetDataLastIndex)
+	{
+	case 0:
+		CardGetInfo0(pCardData);
+		GetDataLastIndex++;
+		break;
+
+	case 1:
+		CardGetInfo1(pCardData);
+		GetDataLastIndex++;
+		break;
+
+	default:
+		CardGetInfo2(pCardData);
+		GetDataLastIndex=0;
+		break;
+	}
+}
+
+/****************************************************************
+ ****************************************************************/
+
+void ADSL_GetShowtimeParm(UINT32 index, UINT32* pdwValue)
+{
+	register UINT32 i;
+
+	for (i=0; i<ShowtimeParmsLastIndex; ++i)
+		if (index == ShowtimeParms[i].dwIndex)
+		{
+//			*pdwValue= ShowtimeParms[i].dwValue;
+			break;
+		}
+}
+
+/****************************************************************
+ ****************************************************************/
+														  
+/* USB sends over the parm data and the following routines
+   save the data until Showtime is ready for the data.  This
+   code assumes that new entries are added at the end. */
+void CardPutData(PCARDDATA pCardData)
+{
+	register UINT32 ic,js;
+	register UINT32 NumberOfEntries= pCardData->dwCount;
+	register PCARDPARAM pdwData= pCardData->Param;
+
+	for (ic=0; ic < NumberOfEntries; ++ic)
+	{
+		for (js=0; js < ShowtimeParmsLastIndex; ++js)
+			if (ShowtimeParms[js].dwIndex == pdwData[ic].dwIndex)
+			{
+				ShowtimeParms[js].dwValue= pdwData[ic].dwValue;
+				break;
+			}
+		if (js >= ShowtimeParmsLastIndex && js < MAX_SHOWTIME_PARMS_ARRAY_SIZE)
+			ShowtimeParms[ShowtimeParmsLastIndex++]= pdwData[ic];
+	}
+}
+
+EXPORT_SYMBOL(ADSL_Init);
+EXPORT_SYMBOL(ADSL_GetRequestedLineState);
+EXPORT_SYMBOL(ADSL_UpdateState);
+EXPORT_SYMBOL(ADSL_RequestedLineState);
+#endif	//if defined (CONFIG_CNXT_ADSL)  ||  defined (CONFIG_CNXT_ADSL_MODULE) || defined (CONFIG_CNXT_GSHDSL) || defined (CONFIG_CNXT_GSHDSL_MODULE)
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/cnxtbsp.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cnxtbsp.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/cnxtbsp.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cnxtbsp.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,240 @@
+/****************************************************************************
+*
+*	Name:				CNXTBSP.C
+*
+*	Description:	Application Manager Application routines implementation.
+*
+*	Copyright:		(c) 2001 - 2003  Conexant Systems Inc.
+*
+*****************************************************************************
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+*****************************************************************************
+*	$Author:   davidsdj  $
+*	$Revision:   1.5  $
+*	$Modtime:   Aug 05 2003 15:21:16  $
+****************************************************************************/
+
+#define __KERNEL_SYSCALLS__
+
+#include    <linux/kernel.h>
+#include    <linux/types.h>
+#include    <linux/sched.h>
+#include    <linux/unistd.h>
+#include    <linux/module.h>
+#include    <linux/init.h>
+
+#include    <asm/arch/bsptypes.h>
+#include    <asm/arch/bspcfg.h>
+#include    <asm/arch/gpio.h>
+#include    <asm/arch/cnxtirq.h>
+#include    <asm/arch/cnxtbsp.h>
+#include    <asm/arch/pwrmanag.h>
+
+#if CONFIG_CNXT_SOFTSAR || CONFIG_CNXT_SOFTSAR_MODULE
+#include    <asm/arch/dmasrv.h>
+#endif
+
+#include    <asm/arch/syslib.h>
+#include    <asm/arch/OsTools.h>
+#include    <asm/arch/gptimer.h>
+#include    <asm/arch/ostimer.h>
+
+#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE || CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE
+#include    <asm/arch/dslisr.h>
+#include    <asm/arch/cnxtadsl.h>
+#endif
+
+#define LED_DELAY_PERIOD   250 /* 250 ms */
+
+HWSTATESTRUCT HWSTATE;
+
+#ifdef GPOUT_TASKRDY_LED
+void CnxtBspLEDTask(void *sem)
+{
+
+	// This code does not seem to be necessary. Copied from linux/fs/buffer.c.
+	// Does not seem to hurt. Might even work in 2.0.38 but not tested there.
+	struct task_struct *tsk = current ;
+	tsk->session = 1 ;
+	tsk->pgrp = 1 ;
+	strcpy ( tsk->comm, "CnxtBspLEDTask" ) ;
+
+	up((struct semaphore *)sem);
+
+	TaskDelayConnect ( GP_TIMER_BSP_LED ) ;
+	
+	while(1)
+	{
+
+		/* Update Ready GPIO */
+		WriteGPIOData(GPOUT_TASKRDY_LED, LED_ON);
+		TaskDelayMsec(LED_DELAY_PERIOD);
+		WriteGPIOData(GPOUT_TASKRDY_LED, LED_OFF);
+
+		TaskDelayMsec(LED_DELAY_PERIOD);
+
+	}
+}
+#endif
+
+static STATUS CnxtBspInitTasks( void )
+{
+	DECLARE_MUTEX_LOCKED( sem );
+
+#ifdef GPOUT_TASKRDY_LED
+	kernel_thread( (void *)CnxtBspLEDTask, &sem, CLONE_FS | CLONE_FILES  );
+	down(&sem);
+#endif
+
+#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE || CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE
+	kernel_thread( (void *)CnxtAdslLEDTask, &sem, CLONE_FS | CLONE_FILES  );
+	down(&sem);
+#endif
+	return OK;
+}
+
+
+static int __init CnxtBspInit(void)
+{
+	sysHwInit2();
+
+	CnxtBspInitTasks();
+	
+	return 0;
+}
+
+
+/******************************************************************************
+|
+|  Function:	CnxtBsp_Get_Random_Byte
+|
+|  Description:	Used to get a somewhat random byte that is used by the
+|				CnxtBsp_Get_Mac_Address function for the last byte of 
+|				a mac address when it has to create one because the flash
+|				device did not have one programmed into it.
+|
+|  Returns:   unsigned char 
+|
+*******************************************************************************/
+
+unsigned char CnxtBsp_Get_Random_Byte( void )
+{
+	/* Read System timer 1, which was turned on at power-on. */
+	DWORD uTimerValue = *(UINT16 *)0x350020;
+
+	return uTimerValue & 0xff;
+}
+
+
+/******************************************************************************
+|
+|  Function:	CnxtBsp_Get_Mac_Address
+|
+|  Description:	Used to either retrieve the mac addresses programmed into
+|				the flash device or to generate a valid Conexant mac address
+|				with a somewhat random last byte for the mac address.
+|
+|  Returns:		NONE 
+|
+*******************************************************************************/
+
+void CnxtBsp_Get_Mac_Address( int emac_num, char *mac_addr_array )
+{
+	// Return a hardcoded mac address for now until
+	// we have functionality to program/retrieve mac
+	// addresses from the flash.
+	*mac_addr_array++ = 0x00;
+	*mac_addr_array++ = 0x30;
+	*mac_addr_array++ = 0xcd;
+	*mac_addr_array++ = 0x00;
+	*mac_addr_array++ = 0x02;
+#ifdef CONFIG_BD_TIBURON
+	*mac_addr_array = 0xcc+emac_num;
+#else
+	*mac_addr_array = CnxtBsp_Get_Random_Byte();
+#endif
+}
+
+/******************************************************************************
+|
+|  Function:    CnxtBsp_Mac_MutEx_Chk
+|
+|  Description: Used to determine whether or not this device requires
+|                       mutually exclusive operation on the emac transmitters
+|
+|  Returns:             NONE
+|
+*******************************************************************************/
+
+BOOLEAN CnxtBsp_Mac_MutEx_Chk( void )
+{
+        switch( _sysGetDeviceType() )
+        {
+                case 0:
+                        return TRUE;
+                        break;
+                default:
+                        return FALSE;
+                        break;
+        }
+}
+
+
+#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE || CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE
+
+/****************************************************************************
+ *
+ *  Name:			void DSL_RX_DMA_ISR(void)
+ *
+ *  Description:	DSL RX DMA interrupt service routine
+ *
+ *  Inputs:			(int irq, void *dev_id, struct pt_regs * regs)
+	*
+ *  Outputs:		none
+ *
+	NOTES:
+		Linux specific interrupt handler interface to DSL receive isr.
+		
+ ***************************************************************************/
+ 
+void DSL_RX_DMA_ISR(int irq, void *dev_id, struct pt_regs * regs)
+{
+   register UINT32 OldLevel; 
+
+   OldLevel = intLock(); 
+   DSL_RX_Handler();
+   intUnlock(OldLevel); 
+}
+
+void DSL_ERR_ISR(int irq, void *dev_id, struct pt_regs * regs)
+{
+   register UINT32 OldLevel; 
+
+   OldLevel = intLock(); 
+   DSL_ERR_Handler();
+   intUnlock(OldLevel); 
+}
+
+#endif
+
+module_init(CnxtBspInit)
+
+EXPORT_SYMBOL(CnxtBsp_Get_Mac_Address);
+
+#if CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE
+EXPORT_SYMBOL(HWSTATE);
+#endif
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/cnxtflash.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cnxtflash.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/cnxtflash.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cnxtflash.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,1285 @@
+/****************************************************************************
+ *
+ *  Name:		cnxtflash.c
+ *
+ *  Description:	P52/Cx8211x flash programmer.
+ *			Programs the Intel 28F320B3 and related flashes on board
+ *
+ *  Copyright (c) 1999-2002 Conexant Systems, Inc.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License version 2 as
+ *	published by the Free Software Foundation.
+ *
+ *
+ ***************************************************************************/
+
+/*---------------------------------------------------------------------------
+ *  Include Files
+ *-------------------------------------------------------------------------*/
+#include <asm/arch/bsptypes.h>
+#include "cnxtflash.h"
+#include <asm/arch/hardware.h>
+#include <linux/kernel.h> // for printk
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h> // for memcpy
+#include <asm/system.h>
+#include <linux/spinlock.h>
+
+#define SUPPORT_SST_FLASH
+#define CNXT_FLASH_TOTAL_SIZE		0x4000		// Total amount of reserved flash (16 Kbytes)
+#ifdef CONFIG_BD_TIBURON
+#define CNXT_FLASH_WRITE_START		0x0404000	// starting address
+#else
+#define CNXT_FLASH_WRITE_START		0x040C000	// starting address
+#endif
+#ifdef CONFIG_BD_TIBURON
+#define CNXT_FLASH_MAX_SEGMENTS		8		// Number of segments
+#else
+#define CNXT_FLASH_MAX_SEGMENTS		16		// Number of segments
+#endif
+#define UNUSED __attribute__((unused))
+#define CNXT_FLASH_DRIVER_VERSION	"001"
+#ifndef SUPPORT_SST_FLASH
+#define CNXT_FLASH_MIN_BLOCK_SIZE	0x2000	 	// Smallest writable area (8 Kbytes)
+#else 
+static unsigned long CNXT_FLASH_MIN_BLOCK_SIZE=0x2000;	 	// Smallest writable area (8 Kbytes)
+#endif /* SUPPORT_SST_FLASH */
+#define CNXT_FLASH_BLOCK_OFFSET		(CNXT_FLASH_TOTAL_SIZE / CNXT_FLASH_MIN_BLOCK_SIZE)
+
+#if 0
+#define DPRINTK(format, args...) printk("cnxtflash.c: " format, ##args)
+#else
+#define DPRINTK(format, args...)
+#endif
+
+/*---------------------------------------------------------------------------
+ *  Module Function Prototypes
+ *-------------------------------------------------------------------------*/
+BOOL CnxtFlashWrite( UINT16 * pflashStartAddr, UINT16 * psdramStartAddr, UINT32 size );
+BOOL CnxtFlashRead( UINT16 * pflashStartAddr, UINT16 * psdramStartAddr, UINT32 size );
+BOOL CnxtFlashProg( UINT16* pSrcAddr, UINT16* pDestAddr, UINT32 uBytes );
+BOOL CnxtFlashVerifyDeviceID( UINT16 *uDeviceID );
+BOOL CnxtFlashEraseBlock( volatile UINT16* pBlockAddr, UINT16 *uDeviceID );
+BOOL CnxtFlashProgramLocation( volatile UINT16* pSrcAddr, volatile UINT16* pDestAddr, UINT16 *uDeviceIDofFLASH );
+void CnxtFlashClearStatusReg( void );
+BOOL CnxtFlashWaitForDone( BOOL );
+BOOL CnxtFlashVerifyMemory( UINT16* pSrcAddr, UINT16* pDestAddr, UINT32 uBytes );
+void CnxtFlashSetupSST ( void );
+void CnxtFlashToggleBit ( void ); 
+DWORD CnxtFlashCalcCRC32( BYTE *pData, DWORD dataLength );
+
+#if 0
+static CNXT_FLASH_SEGMENT_T cnxtFlashSegments[CNXT_FLASH_MAX_SEGMENTS];
+static BYTE cnxtFlashBuffer[CNXT_FLASH_MIN_BLOCK_SIZE];
+static BOOL cnxtFlashLocked[CNXT_FLASH_MAX_SEGMENTS];
+#else
+CNXT_FLASH_SEGMENT_T cnxtFlashSegments[CNXT_FLASH_MAX_SEGMENTS];
+#ifdef SUPPORT_SST_FLASH
+BYTE cnxtFlashBuffer[0x2000];   //0X2000 must be the max in the min block sizes
+#else
+BYTE cnxtFlashBuffer[CNXT_FLASH_MIN_BLOCK_SIZE];
+#endif /* SUPPORT_SST_FLASH */
+
+BOOL cnxtFlashLocked[CNXT_FLASH_MAX_SEGMENTS];
+#endif
+
+#ifdef SUPPORT_SST_FLASH
+/*
+ *  set    CNXT_FLASH_MIN_BLOCK_SIZE according to the flash id
+*/
+void __init setBootsectorBlocksize( void )
+{
+	UINT16 uDeviceID;
+	UINT16 uMfrId;
+    UINT16 DeviceIDofFLASH;
+    UINT16 *uDeviceIDofFLASH=&DeviceIDofFLASH;
+
+	/* Go into "read identifer" mode for the Intel type part*/
+	*pCUIReg = READ_IDENTIFIER;
+
+	uDeviceID = *pDeviceIDReg;
+	uMfrId	  = *pMfrIDReg;
+
+	/*Check to see if it is an Intel or Sharp flash*/
+	switch ( uDeviceID )
+	{
+		case DEVICE_ID_INTELB3_BB_2M: 
+		case DEVICE_ID_INTELC3_BB_2M: 
+		case DEVICE_ID_INTELB3_BB_4M: 
+		case DEVICE_ID_INTELC3_BB_4M:
+		case DEVICE_ID_INTELB3_BB_1M:
+			*uDeviceIDofFLASH = INTEL_TYPE_FLASH_BB;
+			*pCUIReg = READ_ARRAY_INTEL;
+			break;
+		
+		case DEVICE_ID_SHARP_BB_2M:
+			*uDeviceIDofFLASH = SHARP_TYPE_FLASH_BB_2M;
+			*pCUIReg = READ_ARRAY_INTEL;
+			break;
+
+		case DEVICE_ID_INTELB3_TB_2M: case DEVICE_ID_INTELC3_TB_2M:
+			*uDeviceIDofFLASH = INTEL_TYPE_FLASH_TB_2M;
+			*pCUIReg = READ_ARRAY_INTEL;
+			break;
+			
+		default:
+			*uDeviceIDofFLASH = UNSUPPORTED_FLASH;
+			*pCUIReg = READ_ARRAY_INTEL;
+			break;
+	}
+
+	if( *uDeviceIDofFLASH == UNSUPPORTED_FLASH )
+	{
+
+    	*pCUIReg = READ_ARRAY_SST;
+    	CnxtFlashSetupSST();
+    	*p5555Reg = READ_IDENTIFIER;
+    	
+    	uDeviceID = *pDeviceIDReg;
+    	uMfrId	  = *pMfrIDReg;
+    		/* Check to see if it is an SST, ST-Micro, AMD or MXIC flash */
+    	switch ( uDeviceID )
+    	{
+    		case DEVICE_ID_SST_2M:
+    			DPRINTK("SST 2MB FLASH device!\n");
+#ifdef SUPPORT_SST_FLASH
+                CNXT_FLASH_MIN_BLOCK_SIZE = 0x1000;
+#endif /* SUPPORT_SST_FLASH */
+    			*uDeviceIDofFLASH = SST_TYPE_FLASH_BB_2M;
+    			*pCUIReg = READ_ARRAY_SST;    	
+    			break;
+    		
+            case DEVICE_ID_STM_TB_2M:
+    			*uDeviceIDofFLASH = STM_TYPE_FLASH_TB_2M;
+    			*pCUIReg = READ_ARRAY_SST;    	
+    			break;
+    
+    		case DEVICE_ID_STM_BB_2M:
+    			if ( uMfrId == MFR_ID_MXIC)
+    				*uDeviceIDofFLASH = MXIC_TYPE_FLASH_BB_2M;
+    			else	 
+    				*uDeviceIDofFLASH = STM_TYPE_FLASH_BB_2M;
+    			*pCUIReg = READ_ARRAY_SST;    	
+    			break;
+    
+    		case DEVICE_ID_AMD_BB_4M:
+    			*uDeviceIDofFLASH = AMD_TYPE_FLASH_BB_4M;
+    			*pCUIReg = READ_ARRAY_SST;    	
+    			break;
+    
+    		case DEVICE_ID_HYNIX_BB_4M:
+    			*uDeviceIDofFLASH = HYNIX_TYPE_FLASH_BB_4M;
+    			*pCUIReg = READ_ARRAY_SST;    	
+    			break;
+    
+    		case DEVICE_ID_MXIC_BB_4M:
+    			*uDeviceIDofFLASH = MXIC_TYPE_FLASH_BB_4M;
+    			*pCUIReg = READ_ARRAY_SST;    	
+    			break;
+    					
+    	// Derek 8.20.2002
+    		case DEVICE_ID_ATMEL_BB_2M:
+    			*uDeviceIDofFLASH = ATMEL_TYPE_FLASH_BB_2M;
+    			*pCUIReg = READ_ARRAY_SST;    	
+    			break;
+    
+    		default:
+    			*uDeviceIDofFLASH = UNSUPPORTED_FLASH;
+    	    	*pCUIReg = READ_ARRAY_SST;    	
+    			break;
+    	}
+	}
+
+	if(*uDeviceIDofFLASH == UNSUPPORTED_FLASH) 
+	{
+		printk("Unsupported FLASH device!\n");
+	}
+}
+#endif /* SUPPORT_SST_FLASH */
+
+static int __init UNUSED CnxtFlashInit( void )
+{
+	int Status = 0;
+	int i;
+	BYTE  * startOfSegmentAddress = (BYTE *)CNXT_FLASH_WRITE_START;
+	DWORD	headerCRC;
+	DWORD	headerSize = sizeof( CNXT_FLASH_SEGMENT_T );
+
+	// Substract out the dataLength, headerCRC and dataCRC from CRC32 calulations
+	DWORD 	headerDataSize = headerSize - sizeof( DWORD ) - sizeof( DWORD ) - sizeof(DWORD);
+	
+	printk("Conexant Flash Driver version: %s\n", CNXT_FLASH_DRIVER_VERSION );
+
+	for( i = 0; i < CNXT_FLASH_MAX_SEGMENTS; i++ )
+	{
+
+		// Mark each segment as locked.
+		cnxtFlashLocked[i] = TRUE;
+		
+		// Load flash segment headers 
+		memcpy( 
+			&cnxtFlashSegments[i], 
+			startOfSegmentAddress,
+			headerSize
+		);	
+		
+		headerCRC = CnxtFlashCalcCRC32( (BYTE *) &cnxtFlashSegments[i], headerDataSize );
+
+		if( headerCRC != cnxtFlashSegments[i].headerCRC )
+		{
+			printk("Initializing Flash Segment %d\n", i + 1);
+
+			cnxtFlashSegments[i].segmentNumber = i;	
+			cnxtFlashSegments[i].segmentSize   = CNXT_FLASH_SEGMENT_SIZE;
+			cnxtFlashSegments[i].startFlashAddress = (DWORD)startOfSegmentAddress;
+			cnxtFlashSegments[i].startDataAddress = (DWORD)startOfSegmentAddress + headerSize;
+			cnxtFlashSegments[i].owner = i;					
+			printk("Initializing Flash data Segment %d,  %lX  \n", i + 1,cnxtFlashSegments[i].startDataAddress);
+
+			// Calculate the new headerCRC and save it.
+			headerCRC = CnxtFlashCalcCRC32( (BYTE *) &cnxtFlashSegments[i], headerDataSize );
+			cnxtFlashSegments[i].headerCRC = headerCRC;
+			
+			// Store new header info. along with headerCRC to the flash segment.
+			CnxtFlashWrite( 
+				(UINT16 *)startOfSegmentAddress, 
+				(UINT16 *)&cnxtFlashSegments[i], 
+				headerSize
+			); 
+
+		} 
+
+		startOfSegmentAddress += CNXT_FLASH_SEGMENT_SIZE;
+
+	}
+
+	return Status;
+}
+
+static void __exit UNUSED CnxtFlashExit( void )
+{
+}
+
+// Add CnxtFlashInit to the '__initcall' list so it will
+// be called at startup
+module_init( CnxtFlashInit );
+module_exit( CnxtFlashExit );
+/****************************************************************************
+ *
+ *  Name:		BOOL CnxtFlashOpen
+ *
+ *  Description:	Opens the specified flash segment only if 'owner'
+ *			is correct for the segment and data actually
+ *			exist.
+ *
+ *  Inputs:		
+ *			
+ *  Outputs:		
+ *
+ ***************************************************************************/
+CNXT_FLASH_STATUS_E CnxtFlashOpen( CNXT_FLASH_SEGMENT_E segment )
+{
+	CNXT_FLASH_STATUS_E Status = CNXT_FLASH_SUCCESS;
+	DWORD	headerSize = sizeof( CNXT_FLASH_SEGMENT_T );
+	DWORD   dataCRC;
+	ULONG  	offset;
+
+	// Check for a valid segment number.
+   	if( segment < CNXT_FLASH_SEGMENT_1 || segment > CNXT_FLASH_SEGMENT_16 )
+	{
+		printk("Incorrect Flash Segment number!\n" );
+		return CNXT_FLASH_DATA_ERROR;
+	}
+
+	// Check for owner
+	if( segment != cnxtFlashSegments[segment].owner )
+	{
+		printk("Incorrect owner for Flash Segment!\n" );
+		return CNXT_FLASH_OWNER_ERROR;
+	}
+	
+	DPRINTK(
+		"CnxtFlashOpen: &cnxtFlashSegments[%d] = %x\n", 
+		segment, 
+		&cnxtFlashSegments[segment]
+	);
+	DPRINTK(
+		"cnxtFlashSegments[%d].startFlashAddress = %x\n", 
+		segment,
+		cnxtFlashSegments[segment].startFlashAddress
+	);
+
+	// Copy the header from flash.
+	memcpy( 
+		(UINT16*)&cnxtFlashSegments[segment], 
+		(UINT16*)cnxtFlashSegments[segment].startFlashAddress,
+		headerSize
+	);	
+	
+
+	if( cnxtFlashSegments[segment].dataLength > CNXT_FLASH_SEGMENT_SIZE )
+		cnxtFlashSegments[segment].dataLength = CNXT_FLASH_SEGMENT_SIZE;
+#ifdef SUPPORT_SST_FLASH
+    offset = ((segment * CNXT_FLASH_SEGMENT_SIZE)/ CNXT_FLASH_MIN_BLOCK_SIZE + 1) * 
+        CNXT_FLASH_MIN_BLOCK_SIZE - CNXT_FLASH_SEGMENT_SIZE;
+
+    if( cnxtFlashSegments[segment].startDataAddress > ( CNXT_FLASH_WRITE_START + offset ) ) {
+        return CNXT_FLASH_DATA_ERROR;	
+    }
+    else {
+        // Calculate the new segment data CRC.
+        dataCRC = CnxtFlashCalcCRC32( 
+            (BYTE *) cnxtFlashSegments[segment].startDataAddress, 
+            cnxtFlashSegments[segment].dataLength 
+        );
+    }
+#else
+	if( segment > CNXT_FLASH_SEGMENT_8 )
+	{	
+		offset = CNXT_FLASH_BLOCK_OFFSET * CNXT_FLASH_MIN_BLOCK_SIZE - CNXT_FLASH_SEGMENT_SIZE;
+		
+		DPRINTK("CNXT_FLASH_BLOCK_OFFSET: %x\n", CNXT_FLASH_BLOCK_OFFSET);
+		DPRINTK("CNXT_FLASH_MIN_BLOCK_SIZE: %x\n", CNXT_FLASH_MIN_BLOCK_SIZE);
+
+		DPRINTK("offset: %lx\n", offset);
+		DPRINTK("cnxtFlashSegments[segment].startDataAddress: %lx\n",cnxtFlashSegments[segment].startDataAddress);
+		DPRINTK("cnxtFlashSegments[segment].startFlashAddress: %lx\n", cnxtFlashSegments[segment].startFlashAddress);
+		DPRINTK("CNXT_FLASH_WRITE_START + offset: %lx\n", CNXT_FLASH_WRITE_START + offset);
+
+		if( cnxtFlashSegments[segment].startFlashAddress > (CNXT_FLASH_WRITE_START + offset) ) {
+			return CNXT_FLASH_DATA_ERROR;		
+        }
+		else {
+			// Calculate the new segment data CRC.
+			dataCRC = CnxtFlashCalcCRC32( 
+				(BYTE *) cnxtFlashSegments[segment].startDataAddress, 
+				cnxtFlashSegments[segment].dataLength 
+			);
+		}
+
+	} else {
+        if( cnxtFlashSegments[segment].startDataAddress > ( CNXT_FLASH_WRITE_START + offset ) ) {
+			return CNXT_FLASH_DATA_ERROR;	
+        }
+		else {
+			// Calculate the new segment data CRC.
+			dataCRC = CnxtFlashCalcCRC32( 
+				(BYTE *) cnxtFlashSegments[segment].startDataAddress, 
+				cnxtFlashSegments[segment].dataLength 
+			);
+
+		}
+	}
+#endif /* SUPPORT_SST_FLASH */
+	DPRINTK(
+		"cnxtFlashSegments[%d].dataCRC = %x        dataCRC = %x\n",
+		segment,
+		cnxtFlashSegments[segment].dataCRC,
+		dataCRC
+	);
+
+	// Check the data CRC
+	if( cnxtFlashSegments[segment].dataCRC != dataCRC ){
+		#ifdef CONFIG_BD_TIBURON
+		printk("Flash data crc error\n");
+		Status = CNXT_FLASH_DATA_CRC_ERROR;
+		#else
+		Status = CNXT_FLASH_DATA_ERROR;
+		#endif
+	}
+
+	// Mark the segment as unmarked.
+	cnxtFlashLocked[segment] = FALSE;
+	return Status;
+}
+/****************************************************************************
+ *
+ *  Name:		BOOL CnxtFlashReadRequest
+ *
+ *  Description:	Read Flash API.
+ *
+ *  Inputs:		
+ *
+ *  Outputs:		
+ *
+ ***************************************************************************/
+BOOL CnxtFlashReadRequest( 
+	CNXT_FLASH_SEGMENT_E segment, 
+	UINT16 * psdramStartAddr, 
+	UINT32 size 
+)
+{
+
+// Make sure data pointer is not NULL.
+	if( !psdramStartAddr )
+		return FALSE;
+
+	// Make sure maximum size is not exceeded.
+	if( size > CNXT_FLASH_SEGMENT_SIZE - sizeof( CNXT_FLASH_SEGMENT_T ) )
+#ifdef CONFIG_BD_TIBURON	
+		size=CNXT_FLASH_SEGMENT_SIZE - sizeof( CNXT_FLASH_SEGMENT_T );
+#else
+		return FALSE;
+#endif
+	// Check for a valid segment number.
+	if( segment < CNXT_FLASH_SEGMENT_1 || segment > CNXT_FLASH_SEGMENT_16 )
+	{
+		return FALSE;
+	} else {
+		// Copy the data from flash.
+		memcpy( 
+			(UINT16*)psdramStartAddr, 
+			(UINT16*)cnxtFlashSegments[segment].startDataAddress,
+			size
+		);	
+
+		return TRUE;		
+	}
+}
+/****************************************************************************
+ *
+ *  Name:		BOOL CnxtFlashWriteRequest
+ *
+ *  Description:	Write Flash API.
+ *
+ *  Inputs:		
+ *
+ *  Outputs:		
+ *
+ ***************************************************************************/
+BOOL CnxtFlashWriteRequest( 
+	CNXT_FLASH_SEGMENT_E segment, 
+	UINT16 * psdramStartAddr, 
+	UINT32 size 
+)
+{
+	DWORD dataCRC;
+	DWORD headerSize = sizeof( CNXT_FLASH_SEGMENT_T );
+	DWORD flashBlockOffset;
+	DWORD flashBlock;
+	BOOL bSuccess = FALSE;
+
+    // Make sure data pointer is not NULL.
+	if( !psdramStartAddr ) {
+		return bSuccess;
+	}
+
+	// Make sure there is enough room for the data.
+	if( size > CNXT_FLASH_SEGMENT_SIZE - sizeof( CNXT_FLASH_SEGMENT_T ) )
+	{
+#ifdef CONFIG_BD_TIBURON	
+		size=CNXT_FLASH_SEGMENT_SIZE - sizeof( CNXT_FLASH_SEGMENT_T );
+#else
+		return bSuccess;
+#endif
+	}
+
+	// Check for a valid segment number.
+	if( segment < CNXT_FLASH_SEGMENT_1 || segment > CNXT_FLASH_SEGMENT_16 )
+	{
+		return bSuccess;
+	} else {
+
+		// Make sure the segment is not locked.
+    	if( cnxtFlashLocked[segment] ) {
+			printk( "Flash Segment Locked! (Try opening it first)\n" );
+			return FALSE;
+		}
+    
+		if( size > CNXT_FLASH_SEGMENT_SIZE - headerSize )
+			return FALSE;
+		else
+			cnxtFlashSegments[segment].dataLength = size;
+	
+		// Calculate the new segment data CRC.
+		dataCRC = CnxtFlashCalcCRC32( 
+			(BYTE *) psdramStartAddr, 
+			size 
+		);
+
+		cnxtFlashSegments[segment].dataCRC = dataCRC;
+		
+		DPRINTK(
+			"cnxtFlashSegments[%d].dataCRC = %x\n", 
+			segment,
+			cnxtFlashSegments[segment].dataCRC
+		);
+		DPRINTK(
+			"headerSize = %x\n",
+			headerSize
+		);
+
+
+		if( segment > CNXT_FLASH_SEGMENT_8 )
+		{
+			flashBlock = CNXT_FLASH_SEGMENT_9;
+			flashBlockOffset = (segment * CNXT_FLASH_SEGMENT_SIZE) - CNXT_FLASH_MIN_BLOCK_SIZE;
+		}
+		else
+		{
+			flashBlock = CNXT_FLASH_SEGMENT_1;
+			flashBlockOffset = (segment * CNXT_FLASH_SEGMENT_SIZE);
+		}
+
+		DPRINTK("flashBlock = %d\n", flashBlock	);
+#ifdef SUPPORT_SST_FLASH
+        if (CNXT_FLASH_SEGMENT_SIZE == CNXT_FLASH_MIN_BLOCK_SIZE) {
+            flashBlock = segment; 
+            flashBlockOffset = 0;
+        }
+        else {
+            //flashblock        - the first segment num of the block which this segment is in
+            //flashBlockOffset  - the offset of this segment in the block
+            int num_block;   //start from 0   segment start from 0
+            int segs_per_block;
+
+            segs_per_block = CNXT_FLASH_MIN_BLOCK_SIZE / (CNXT_FLASH_SEGMENT_SIZE);
+            num_block = (segment * CNXT_FLASH_SEGMENT_SIZE)/ CNXT_FLASH_MIN_BLOCK_SIZE;
+            flashBlock = num_block * segs_per_block;
+			flashBlockOffset = segment * (CNXT_FLASH_SEGMENT_SIZE) -
+                num_block * CNXT_FLASH_MIN_BLOCK_SIZE;
+/*            printk ("flashBlock2 = %ld, %ld seg=%ld, %ld, %ld, m/s=%ld, %ld\n", flashBlock,  flashBlockOffset,
+                    segment, CNXT_FLASH_SEGMENT_SIZE, CNXT_FLASH_MIN_BLOCK_SIZE, 
+                    num_block, 
+                    segs_per_block);*/
+        }
+#endif /* SUPPORT_SST_FLASH */
+		// Read in the minimum flash block size (8kbytes)
+		memcpy
+		(
+			&cnxtFlashBuffer[0],
+			(BYTE *)cnxtFlashSegments[flashBlock].startFlashAddress,
+			CNXT_FLASH_MIN_BLOCK_SIZE	
+		);
+
+		// Copy the flash segment header
+		DPRINTK("flashBlockOffset = %x\n", flashBlockOffset	);
+
+		memcpy
+		(
+			&cnxtFlashBuffer[flashBlockOffset], 
+			&cnxtFlashSegments[segment], 
+			headerSize
+		);
+
+		// Copy the data
+		memcpy
+		( 
+			&cnxtFlashBuffer[flashBlockOffset + headerSize],
+			psdramStartAddr,
+			size
+		);			
+		
+		DPRINTK(
+			"cnxtFlashSegments[%d].startFlashAddress = %x\n",
+			flashBlock,
+			cnxtFlashSegments[flashBlock].startFlashAddress
+		);
+		DPRINTK(
+			"CNXT_FLASH_MIN_BLOCK_SIZE: %x\n",
+			CNXT_FLASH_MIN_BLOCK_SIZE
+		);
+
+		bSuccess = CnxtFlashWrite( 
+				(UINT16 *)cnxtFlashSegments[flashBlock].startFlashAddress, 
+				(UINT16 *)&cnxtFlashBuffer[0], 
+				CNXT_FLASH_MIN_BLOCK_SIZE
+		); 
+
+		if( !bSuccess )  {
+
+			return FALSE;
+		}
+
+	}
+
+	return TRUE;
+}
+
+/****************************************************************************
+ *
+ *  Name:		BOOL CnxtFlashWrite
+ *
+ *  Description:	Writes data to flash.
+ *
+ *  Inputs:		
+ *
+ *  Outputs:		
+ *
+ ***************************************************************************/
+BOOL CnxtFlashWrite( UINT16 * pflashStartAddr, UINT16 * psdramStartAddr, UINT32 size )
+{
+
+	
+	BOOL 		bSuccess;
+
+	bSuccess = CnxtFlashProg(
+			psdramStartAddr,	// Location of data SDRAM
+			pflashStartAddr,	// Location to place data in flash
+			size			// The size in bytes
+	);
+
+	DPRINTK( "CnxtFlashProg: bSuccess = %d\n", bSuccess );
+
+	return bSuccess;
+}
+
+
+/****************************************************************************
+ *
+ *  Name:		BOOL CnxtFlashProg( UINT16* pSrcAddr, UINT16* pDestAddr, UINT32 uBytes )
+ *
+ *  Description:	Programs the flash
+ *
+ *  Inputs:		UINT16* pSrcAddr = where data to program is
+ *			UINT16* pDestAddr = where to start programming the flash
+ *			UINT32 uBytes = number of bytes to program
+ *
+ *  Outputs:		Returns TRUE if programming is successful, FALSE if not
+ *
+ ***************************************************************************/
+
+BOOL CnxtFlashProg( UINT16* pSrcAddr, UINT16* pDestAddr, UINT32 uBytes )
+{
+	BOOL bSuccess;
+	UINT16* pSrcAddrChk;
+	UINT16* pDestAddrChk;
+	UINT32 uBytesChk;
+	UINT16 uDeviceID;
+
+    printk ("CnxtFlashProg src=%x, dst=%x, size=%d\n", 
+            pSrcAddr, pDestAddr, uBytes);
+	/* Save the addresses and byte count for later validation */
+	pSrcAddrChk = pSrcAddr;
+	pDestAddrChk = pDestAddr;
+	uBytesChk = uBytes;
+
+	/* Make sure the right device is installed */
+	bSuccess = CnxtFlashVerifyDeviceID( &uDeviceID );
+   	
+	// Erase a 8kbyte block beginning at pDestAddr
+	bSuccess &= CnxtFlashEraseBlock( pDestAddr, &uDeviceID );
+
+	/* While we haven't finished all locations and there hasn't been an error... */
+	while( uBytes && bSuccess )
+	{
+
+		/* Program a location */
+		bSuccess = CnxtFlashProgramLocation( pSrcAddr, pDestAddr, &uDeviceID );
+
+		/* Update memory pointers and byte counter */
+		++pSrcAddr;
+		++pDestAddr;
+		uBytes -= 2;
+	}
+	
+	/* Verify the data */
+	if(bSuccess) bSuccess = CnxtFlashVerifyMemory( pSrcAddrChk, pDestAddrChk, uBytesChk );
+	
+	return bSuccess;
+}
+
+
+/****************************************************************************
+ *
+ *  Name:			BOOL CnxtFlashVerifyDeviceID( void )
+ *
+ *  Description:	Verifies the device ID
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		Returns TRUE if the correct device is installed, FALSE if not
+ *
+ ***************************************************************************/
+BOOL CnxtFlashVerifyDeviceID( UINT16 *uDeviceIDofFLASH )
+{
+	UINT16 uDeviceID;
+	UINT16 uMfrId;
+	BOOL   bSuccess;
+
+	/* Go into "read identifer" mode for the Intel type part*/
+	*pCUIReg = READ_IDENTIFIER;
+
+	uDeviceID = *pDeviceIDReg;
+	uMfrId	  = *pMfrIDReg;
+
+	/*Check to see if it is an Intel or Sharp flash*/
+	switch ( uDeviceID )
+	{
+		case DEVICE_ID_INTELB3_BB_2M: 
+		case DEVICE_ID_INTELC3_BB_2M: 
+		case DEVICE_ID_INTELB3_BB_4M: 
+		case DEVICE_ID_INTELC3_BB_4M:
+		case DEVICE_ID_INTELB3_BB_1M:
+			*uDeviceIDofFLASH = INTEL_TYPE_FLASH_BB;
+			*pCUIReg = READ_ARRAY_INTEL;
+			break;
+		
+		case DEVICE_ID_SHARP_BB_2M:
+			*uDeviceIDofFLASH = SHARP_TYPE_FLASH_BB_2M;
+			*pCUIReg = READ_ARRAY_INTEL;
+			break;
+
+		case DEVICE_ID_INTELB3_TB_2M: case DEVICE_ID_INTELC3_TB_2M:
+			*uDeviceIDofFLASH = INTEL_TYPE_FLASH_TB_2M;
+			*pCUIReg = READ_ARRAY_INTEL;
+			break;
+			
+		default:
+			*uDeviceIDofFLASH = UNSUPPORTED_FLASH;
+			*pCUIReg = READ_ARRAY_INTEL;
+			break;
+	}
+
+	if( *uDeviceIDofFLASH == UNSUPPORTED_FLASH )
+	{
+
+	*pCUIReg = READ_ARRAY_SST;
+	CnxtFlashSetupSST();
+	*p5555Reg = READ_IDENTIFIER;
+	
+	uDeviceID = *pDeviceIDReg;
+	uMfrId	  = *pMfrIDReg;
+	
+		/* Check to see if it is an SST, ST-Micro, AMD or MXIC flash */
+	switch ( uDeviceID )
+	{
+		case DEVICE_ID_SST_2M:
+			DPRINTK("SST 2MB FLASH device!\n");
+			*uDeviceIDofFLASH = SST_TYPE_FLASH_BB_2M;
+			*pCUIReg = READ_ARRAY_SST;    	
+			break;
+		
+		case DEVICE_ID_STM_TB_2M:
+			*uDeviceIDofFLASH = STM_TYPE_FLASH_TB_2M;
+			*pCUIReg = READ_ARRAY_SST;    	
+			break;
+
+		case DEVICE_ID_STM_BB_2M:
+			if ( uMfrId == MFR_ID_MXIC)
+				*uDeviceIDofFLASH = MXIC_TYPE_FLASH_BB_2M;
+			else	 
+				*uDeviceIDofFLASH = STM_TYPE_FLASH_BB_2M;
+			*pCUIReg = READ_ARRAY_SST;    	
+			break;
+
+		case DEVICE_ID_AMD_BB_4M:
+			*uDeviceIDofFLASH = AMD_TYPE_FLASH_BB_4M;
+			*pCUIReg = READ_ARRAY_SST;    	
+			break;
+
+		case DEVICE_ID_HYNIX_BB_4M:
+			*uDeviceIDofFLASH = HYNIX_TYPE_FLASH_BB_4M;
+			*pCUIReg = READ_ARRAY_SST;    	
+			break;
+
+		case DEVICE_ID_MXIC_BB_4M:
+			*uDeviceIDofFLASH = MXIC_TYPE_FLASH_BB_4M;
+			*pCUIReg = READ_ARRAY_SST;    	
+			break;
+					
+	// Derek 8.20.2002
+		case DEVICE_ID_ATMEL_BB_2M:
+			*uDeviceIDofFLASH = ATMEL_TYPE_FLASH_BB_2M;
+			*pCUIReg = READ_ARRAY_SST;    	
+			break;
+
+		default:
+			*uDeviceIDofFLASH = UNSUPPORTED_FLASH;
+	    	*pCUIReg = READ_ARRAY_SST;    	
+			break;
+	}
+	}
+
+	if(*uDeviceIDofFLASH == UNSUPPORTED_FLASH) 
+	{
+	 	bSuccess = FALSE;
+		printk("Unsupported FLASH device!\n");
+	} else
+		bSuccess = TRUE;
+	
+	return bSuccess;
+}
+
+
+/****************************************************************************
+ *
+ *  Name:			BOOL CnxtFlashEraseBlock( UINT16* pBlockAddr )
+ *
+ *  Description:	Erases a block of the flash
+ *
+ *  Inputs:			UINT16* pBlockAddr = address of the start of the block
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+
+BOOL CnxtFlashEraseBlock( volatile UINT16* pBlockAddr, UINT16 *uDeviceIDofFLASH )
+{
+	BOOL bSuccess=TRUE;
+	eFlashErase EraseProcedure = DONT_ERASE;
+
+	switch ( *uDeviceIDofFLASH )
+	{
+		case INTEL_TYPE_FLASH_BB:
+		case SHARP_TYPE_FLASH_BB_2M:
+			if(	(pBlockAddr < BOOT_BLOCK_END) && (((UINT32)pBlockAddr & 0x1fff) == 0x0) )
+				EraseProcedure = INTEL;
+			else if ( 0x0000 == ( (UINT32)pBlockAddr & 0xffff ) )
+				EraseProcedure = INTEL;
+
+			break;	
+		
+		case MXIC_TYPE_FLASH_BB_4M:
+		case AMD_TYPE_FLASH_BB_4M:
+			if(	(pBlockAddr < BOOT_BLOCK_END) && (((UINT32)pBlockAddr & 0x1fff) == 0x0) )
+				EraseProcedure = STM;		 
+			else if ( 0x0000 == ( (UINT32)pBlockAddr & 0xffff ) )
+				EraseProcedure = STM;
+
+			break;		
+
+		case SST_TYPE_FLASH_BB_2M:
+			DPRINTK("SST_TYPE_FLASH: pBlockAddr = %x\n", pBlockAddr );
+
+			if(	(pBlockAddr < BOOT_BLOCK_END) && (((UINT32)pBlockAddr & 0xfff) == 0x0) )
+			{
+				DPRINTK("Selecting SST EraseProcedure.\n");
+				EraseProcedure = SST;
+
+			} else { 
+				if ( 0x0000 == ( (UINT32)pBlockAddr & 0xffff ) )
+				{
+					DPRINTK("Selecting SST EraseProcedure.\n");
+					EraseProcedure = SST;		
+				}
+			}
+			
+			break;
+		
+		case STM_TYPE_FLASH_BB_2M:
+		case MXIC_TYPE_FLASH_BB_2M:
+		case HYNIX_TYPE_FLASH_BB_4M:
+			if( ( ((pBlockAddr < BOOT_BLOCK_END) && ( ( (UINT32)pBlockAddr == (UINT32)0x406000) 
+				|| ( ( UINT32 )pBlockAddr == ( UINT32 )0x404000 ) 
+				|| ( ( UINT32 )pBlockAddr == ( UINT32 )0x408000 ) )) 
+				|| (((UINT32)pBlockAddr & 0xffff) == 0x0000) ) )
+				EraseProcedure = STM;
+
+			break;
+
+		case ATMEL_TYPE_FLASH_BB_2M:
+			if(	(pBlockAddr < BOOT_BLOCK_END) && (((UINT32)pBlockAddr & 0x1fff) == 0x0) )
+				EraseProcedure = STM;
+			else if ( 0x418000 == (UINT32)pBlockAddr )
+				EraseProcedure = STM;
+			else if ( 0x0000 == ( (UINT32)pBlockAddr & 0xffff ) )
+				EraseProcedure = STM;		
+
+			break;
+
+		default:
+			break;
+	}
+
+	switch (EraseProcedure)
+	{
+		case INTEL:
+		{
+
+#if 0
+			/*  To unlock the blocks of memory in Intel C3 flash */  
+			*pBlockAddr = UNLOCK_SETUP;
+			*pBlockAddr = ERASE_CONFIRM_INTEL;
+			
+			*pCUIReg = READ_ARRAY_INTEL;
+			/* Clear the status register */
+			CnxtFlashClearStatusReg();
+
+			if( *uDeviceIDofFLASH == SHARP_TYPE_FLASH_BB_2M )
+				bSuccess = CnxtFlashWaitForDone(0);
+			
+			/* Write erase setup, erase confirm, and block address */
+			*pBlockAddr = ERASE_SETUP_INTEL;
+			*pBlockAddr = ERASE_CONFIRM_INTEL;
+
+			/* Wait for erase complete */
+			bSuccess &= CnxtFlashWaitForDone(0);
+
+			/* Return to "read array" mode */
+			*pCUIReg = READ_ARRAY_INTEL;
+#else
+			/* Clear the status register */
+			CnxtFlashClearStatusReg();
+
+			/*  To unlock the blocks of memory in Intel C3 flash */  
+			*pCUIReg = UNLOCK_SETUP;
+			*pBlockAddr = ERASE_CONFIRM_INTEL;
+			
+			if( *uDeviceIDofFLASH == SHARP_TYPE_FLASH_BB_2M )
+				bSuccess = CnxtFlashWaitForDone(0);
+			
+			/* Write erase setup, erase confirm, and block address */
+			*pCUIReg = ERASE_SETUP_INTEL;
+			*pBlockAddr = ERASE_CONFIRM_INTEL;
+			*pCUIReg = ERASE_CONFIRM_INTEL;
+
+			/* Wait for erase complete */
+			bSuccess &= CnxtFlashWaitForDone(0);
+
+			/* Return to "read array" mode */
+			*pCUIReg = READ_ARRAY_INTEL;
+
+#endif		
+		}
+		break;
+
+		case SST:
+		{
+			CnxtFlashSetupSST();
+			*p5555Reg = ERASE_SETUP_SST;
+			CnxtFlashSetupSST();
+
+			if(	pBlockAddr >= BOOT_BLOCK_END )
+			{
+				DPRINTK("SST BLOCK_ERASE_CONFIRM.\n");
+				*pBlockAddr = BLOCK_ERASE_CONFIRM;
+
+			} else {
+				DPRINTK("SST SECTOR_ERASE_CONFIRM.\n");
+				*pBlockAddr = SECTOR_ERASE_CONFIRM;	
+				
+			}
+			while(!(*pBlockAddr & DQ7));
+			
+			//CnxtFlashToggleBit();
+
+			DPRINTK("SST returning to read array mode.\n");
+			/* Return to "read array" mode */
+			*pCUIReg = READ_ARRAY_SST;
+		}
+		break;
+
+		case STM:
+		{
+			CnxtFlashSetupSST();
+			*p5555Reg = ERASE_SETUP_SST;
+			CnxtFlashSetupSST();
+			
+			*pBlockAddr = SECTOR_ERASE_CONFIRM;	
+				
+			while(!(*pBlockAddr & DQ7));
+			//ToggleBit();
+			
+			/* Return to "read array" mode */
+			*pCUIReg = READ_ARRAY_SST;
+		}
+		break;
+		
+		default:
+			break;	
+		
+	}
+
+	return bSuccess;
+}
+
+
+/****************************************************************************
+ *
+ *  Name:		BOOL CnxtFlashProgramLocation( UINT16*, UINT16* pDestAddr )
+ *
+ *  Description:	Programs a location in the flash
+ *
+ *  Inputs:		UINT16* pSrcAddr = address of where to get the data
+ *			UINT16* pDestAddr = flash address to program
+ *
+ *  Outputs:		Returns TRUE if programming successful, FALSE if not
+ *
+ ***************************************************************************/
+BOOL CnxtFlashProgramLocation( volatile UINT16* pSrcAddr, volatile UINT16* pDestAddr, UINT16 *uDeviceIDofFLASH )
+{
+	BOOL bSuccess=TRUE;
+			
+	if( *uDeviceIDofFLASH == INTEL_TYPE_FLASH_BB 
+	|| *uDeviceIDofFLASH == SHARP_TYPE_FLASH_BB_2M 
+	|| *uDeviceIDofFLASH == INTEL_TYPE_FLASH_TB_2M  )
+	{	/* Clear status register */
+		CnxtFlashClearStatusReg();
+
+		if( *uDeviceIDofFLASH == SHARP_TYPE_FLASH_BB_2M )
+			/* Wait for reading of status reg */
+			bSuccess = CnxtFlashWaitForDone(0);
+			
+		/* Write program setup */
+		*pCUIReg = PROGRAM_SETUP_INTEL;
+
+		/* Program the location */
+		*pDestAddr = *pSrcAddr;
+		
+		/* Wait for program complete */
+		bSuccess &= CnxtFlashWaitForDone(0);
+
+		/* Return to "read array" mode */
+		*pCUIReg = READ_ARRAY_INTEL;
+	}
+	else
+	{
+	
+		CnxtFlashSetupSST();
+		*p5555Reg = PROGRAM_SETUP_SST;
+		*pDestAddr = *pSrcAddr;
+
+		while( *pDestAddr != *pSrcAddr );
+		//CnxtFlashToggleBit();
+
+		*pCUIReg = READ_ARRAY_SST;
+	
+		
+	}
+
+	return bSuccess;
+}
+
+
+/****************************************************************************
+ *
+ *  Name:			void CnxtFlashClearStatusReg( void )
+ *
+ *  Description:	Clears the status register
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void CnxtFlashClearStatusReg( void )
+{
+	*pCUIReg = CLEAR_STATUS_REG;
+	return;
+}
+
+/****************************************************************************
+ *
+ *  Name:			BOOL CnxtFlashWaitForDone( BOOL )
+ *
+ *  Description:	Waits for a process to complete, and checks results
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		Returns TRUE if process successful
+ *
+ ***************************************************************************/
+BOOL CnxtFlashWaitForDone( BOOL debugON )
+{
+	BOOL bSuccess=TRUE;
+	UINT16 uStatus;
+
+	/* Write the "read status register" command */
+	*pCUIReg = READ_STATUS_REG;
+
+	/* Wait for the operation to finish */
+	do
+	{
+		/* Read the status register */
+		uStatus = *pCUIReg;
+
+		/* Wait for the "state machine ready" bit */
+	} while( !( uStatus & WSMS_READY ) );
+
+
+	if( debugON ) 
+	{
+
+		printk(
+			"uStatus = %x\n",
+			uStatus
+		);
+
+		uStatus = *pCUIReg;
+		
+		printk(
+			"uStatus = %x\n",
+			uStatus
+		);
+
+	} 
+
+	/* Check for errors */
+	if ( !( uStatus & FLASH_ERR ) )
+	{
+		bSuccess = TRUE;
+	}
+
+	else
+	{
+		bSuccess = FALSE;
+	}
+
+	return bSuccess;
+}
+
+void CnxtFlashToggleBit(void)
+{
+	UINT16 uFirst_Read, uSecond_Read;
+	do
+	{
+		/* Read the status register */
+		uFirst_Read = *pCUIReg;
+		uSecond_Read = *pCUIReg;
+
+		/* Wait for the "state machine ready" bit */
+	} while( ( uFirst_Read & TOGGLE_BIT ) != ( uSecond_Read & TOGGLE_BIT ) );
+
+	return;
+}
+
+/****************************************************************************
+ *
+ *  Name:		BOOL CnxtFlashVerifyMemory( UINT16* pSrcAddr, UINT16* pDestAddr, UINT32 uBytes )
+ *
+ *  Description:	Compares memory locations
+ *
+ *  Inputs:		UINT16* pSrcAddr = source address
+ *			UINT16* pDestAddr = destination address
+ *			UINT32 uBytes = number of bytes to check
+ *
+ *  Outputs:		Returns BOOL TRUE if memories are the same, FALSE if not
+ *
+ ***************************************************************************/
+
+BOOL CnxtFlashVerifyMemory( UINT16* pSrcAddr, UINT16* pDestAddr, UINT32 uBytes )
+{
+	BOOL bSuccess;
+	bSuccess = TRUE;
+
+	while( uBytes && bSuccess )
+	{
+		if ( *pDestAddr++ != *pSrcAddr++ )
+		{
+			bSuccess = FALSE;
+		}
+
+		uBytes -= 2;
+	}
+
+	return bSuccess;
+}
+
+/****************************************************************************
+ *
+ *  Name:		DWORD CnxtFlashCalcCRC32
+ *
+ *  Description:	Performs a 32 bit CRC on pData
+ *
+ *  Inputs:		DWORD		 crc32_val,		
+ *			BYTE		*pData,
+ *			DWORD		dataLength	
+ *			
+ *
+ *  Outputs:		Returns the calculated CRC value.
+ *
+ ***************************************************************************/
+// CRC32 Lookup Table generated from Charles Michael
+//  Heard's CRC-32 code
+static DWORD crc32_tbl[256] =
+{
+0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
+0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
+0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
+0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
+0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
+0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
+0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
+0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
+0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
+0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
+0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
+0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
+0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
+0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
+0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
+0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
+0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
+0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
+0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
+0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
+0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
+0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
+0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
+0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
+0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
+0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
+0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
+0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
+0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
+0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
+0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
+0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
+0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
+0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
+0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
+0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
+0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
+0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
+0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
+0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
+0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
+0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
+0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
+0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
+0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
+0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
+0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
+0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
+0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
+0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
+0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
+0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
+0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
+0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
+0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
+0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
+0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
+0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
+0xf0a5bd1d, 0xf464a0aa797, 0xf9278673, 0xfde69bc4,
+0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
+0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
+0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
+0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
+};
+
+#define INITIAL_CRC_VAL		0xffffffff  // negative one
+
+DWORD CnxtFlashCalcCRC32
+(
+	BYTE		*pData,
+	DWORD		dataLength	
+)
+{
+	DWORD	crc32_val = INITIAL_CRC_VAL; 
+
+    // Calculate a CRC32 value
+	while ( dataLength-- )
+	{
+		crc32_val = ( crc32_val << 8 ) ^ crc32_tbl[(( crc32_val >> 24) ^ *pData++ ) & 0xff];
+	}
+	
+	return (crc32_val);
+
+}
+
+void CnxtFlashSetupSST(void)
+{
+	*p5555Reg = CMD_AA;
+	*p2AAAReg = CMD_55;
+
+	return;
+}
+
+EXPORT_SYMBOL( CnxtFlashWriteRequest );
+EXPORT_SYMBOL( CnxtFlashReadRequest );
+EXPORT_SYMBOL( CnxtFlashOpen );
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/cnxtflash.h linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cnxtflash.h
--- linux-2.4.29/arch/armnommu/mach-cx821xx/cnxtflash.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cnxtflash.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,157 @@
+/****************************************************************************
+ *
+ *  Name:		cnxtflash.h
+ *
+ *  Description:	Flash programmer header file
+ *
+ *  Copyright (c) 1999-2002 Conexant Systems, Inc.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License version 2 as
+ *	published by the Free Software Foundation.
+ *
+ *
+ ***************************************************************************/
+#ifndef _CNXTFLASH_H_
+#define _CNXTFLASH_H_
+
+#define START_SIZE				0x50000
+#define MAC_SIZE				0xfc		// 180 bytes
+#define PARMS_SIZE				0x2000
+#define BSP_SIZE				0x170000
+#define FFS_SIZE				0x1b0000
+#define	READ_ARRAY_INTEL		( UINT16 )0xff
+#define PROGRAM_SETUP_INTEL		( UINT16 )0x40
+#define ERASE_SETUP_INTEL		( UINT16 )0x20
+#define UNLOCK_SETUP			( UINT16 )0x60
+#define ERASE_CONFIRM_INTEL		( UINT16 )0xd0
+#define READ_STATUS_REG			( UINT16 )0x70
+#define CLEAR_STATUS_REG		( UINT16 )0x50
+#define WSMS_READY				( UINT16 )( 1 << 7 )
+#define ERASE_ERR				( UINT16 )( 1 << 5 )
+#define PROG_ERR				( UINT16 )( 1 << 4 )
+#define Vpp_ERR					( UINT16 )( 1 << 3 )
+#define BLOCK_LOCK_ERR			( UINT16 )( 1 << 1 )
+
+#define FLASH_START_ADDR		( UINT16* )0x400000
+#define FLASH_MAC_ADDR			( UINT16* )0x440000
+#define FLASH_PARMS_ADDR		( UINT16* )0x40c000
+#define FLASH_BSP_ADDR			( UINT16* )0x410000
+#define FLASH_FFS_ADDR			( UINT16* )0x450000
+#define FLASH_NVRAM_ADDR		( UINT16* )0x450000
+#define NVRAM_BLOCK				(UINT32)	0x0
+#define FLASH_CHECKSUM_ADDR		( UINT16* )0x450000
+#define CHECKSUM_SIZE			(UINT32)	0x0
+
+
+//These are used for the SST version of Flash
+#define p5555Reg				( volatile UINT16* ) 0x40aaaa
+#define p2AAAReg				( volatile UINT16* ) 0x405554
+#define READ_ARRAY_SST			( UINT16 ) 0xf0
+#define ERASE_SETUP_SST			( UINT16 ) 0x80
+#define SECTOR_ERASE_CONFIRM	( UINT16 ) 0x30
+#define BLOCK_ERASE_CONFIRM		( UINT16 ) 0x50
+#define PROGRAM_SETUP_SST		( UINT16 ) 0xa0
+#define CMD_AA					( UINT16 ) 0xaa
+#define CMD_55					( UINT16 ) 0x55
+#define DQ7						( UINT16 ) 0x80
+#define TOGGLE_BIT				( UINT16 )( 1 << 6 )
+
+#define MFR_ID_INTEL				0x0089
+#define DEVICE_ID_INTELB3_BB_2M		0x8891
+#define DEVICE_ID_INTELB3_BB_4M 	0x8897
+#define DEVICE_ID_INTELC3_BB_4M 	0x88c5
+#define DEVICE_ID_INTELB3_TB_2M		0x8890
+#define DEVICE_ID_INTELC3_BB_2M  	0x88c3
+#define DEVICE_ID_INTELC3_TB_2M  	0x88c2
+#define DEVICE_ID_INTELB3_BB_1M 	0x8893
+
+#define MFR_ID_SST					0x00bf
+#define DEVICE_ID_SST_2M			0x2782
+
+#define MFR_ID_AMD					0x0001
+#define DEVICE_ID_AMD_TB_2M			0x22c4
+#define DEVICE_ID_AMD_BB_2M			0x2249
+#define DEVICE_ID_AMD_BB_4M			0x22F9
+
+#define MFR_ID_MXIC					0x00c2
+#define DEVICE_ID_MXIC_BB_2M		0x2249
+#define DEVICE_ID_MXIC_BB_4M  		0x22A8
+
+#define MFR_ID_FUJITSU				0x0004
+#define DEVICE_ID_FUJITSU_BB_2M		0x2249
+
+#define MFR_ID_STM					0x0020
+#define DEVICE_ID_STM_TB_2M			0x22c4
+#define DEVICE_ID_STM_BB_2M			0x2249
+
+#define MFR_ID_SHARP				0x00b0
+#define DEVICE_ID_SHARP_BB_2M		0x00e9
+
+#define MFR_ID_ATMEL				0x001f
+#define DEVICE_ID_ATMEL_BB_2M		0x00c0
+
+#define MFR_ID_HYNIX				0x00AD
+#define DEVICE_ID_HYNIX_BB_4M		0x227D
+
+typedef enum
+{
+	INTEL_TYPE_FLASH_BB,		
+	SST_TYPE_FLASH_BB_2M,		
+	SHARP_TYPE_FLASH_BB_2M,		
+	INTEL_TYPE_FLASH_TB_2M,		
+	STM_TYPE_FLASH_BB_2M,
+	MXIC_TYPE_FLASH_BB_2M,		
+	STM_TYPE_FLASH_TB_2M,				
+	ATMEL_TYPE_FLASH_BB_2M,
+	AMD_TYPE_FLASH_BB_4M,
+	MXIC_TYPE_FLASH_BB_4M,
+	HYNIX_TYPE_FLASH_BB_4M,
+	UNSUPPORTED_FLASH
+	
+} eFlash;
+
+typedef enum
+{
+	INTEL,
+	SST,
+	STM,
+	MXIC,
+	DONT_ERASE		
+} eFlashErase;
+
+#define READ_IDENTIFIER			( UINT16 )0x90
+
+#define SDRAM_START_ADDR		( UINT16* )0x800000
+#define SDRAM_MAC_ADDR			( UINT16* )0x840000
+#define SDRAM_PARMS_ADDR		( UINT16* )0x80c000
+#define SDRAM_BSP_ADDR			( UINT16* )0x810000
+#define SDRAM_FFS_ADDR			( UINT16* )0x850000
+#define SDRAM_CHECKSUM_ADDR		( UINT16* )0x820000
+
+#define BOOT_BLOCK_END			( UINT16* )0x410000
+#define SECOND_BOOT_BLOCK_END	( UINT16* )0x420000
+#define MAIN_BLOCK_END			( UINT16* ) 0x5f0000
+
+#define NUM_BOOT_BLOCKS			8
+
+#define pMfrIDReg				( volatile UINT16* )( FLASH_START_ADDR )
+#define pDeviceIDReg			( volatile UINT16* )0x400002
+#define pCUIReg					( volatile UINT16* )0x400000
+
+#define WSMS_READY				( UINT16 )( 1 << 7 )
+#define ERASE_ERR				( UINT16 )( 1 << 5 )
+#define PROG_ERR				( UINT16 )( 1 << 4 )
+#define Vpp_ERR					( UINT16 )( 1 << 3 )
+#define BLOCK_LOCK_ERR			( UINT16 )( 1 << 1 )
+
+#define FLASH_ERR	( UINT16 )( ERASE_ERR | PROG_ERR | Vpp_ERR | BLOCK_LOCK_ERR )
+#ifdef CONFIG_BD_TIBURON
+#define CNXT_FLASH_SEGMENT_SIZE		2*1024
+#else
+#define CNXT_FLASH_SEGMENT_SIZE		1024
+#endif
+
+#include <asm/arch/cnxtflash.h>
+
+#endif
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/cnxtflashio.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cnxtflashio.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/cnxtflashio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cnxtflashio.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,279 @@
+/****************************************************************************
+ *
+ *  Name:		cnxtflashio.c
+ *
+ *  Description:	Flash read/write support driver for applications.
+ *			
+ *
+ *  Copyright (c) 1999-2002 Conexant Systems, Inc.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License version 2 as
+ *	published by the Free Software Foundation.
+ *
+ *
+ ***************************************************************************/
+
+/*---------------------------------------------------------------------------
+ *  Include Files
+ *-------------------------------------------------------------------------*/
+#include <asm/arch/bsptypes.h>
+#include "cnxtflash.h"
+#include <asm/arch/hardware.h>
+#include <linux/kernel.h> 
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <asm/system.h>
+#include <linux/spinlock.h>
+#include <linux/fs.h>
+#include <linux/compatmac.h>
+
+#define UNUSED __attribute__((unused))
+
+#define CNXTFLASHIO_MAJOR		61
+
+#if 0
+#define DPRINTK(format, args...) printk("cnxtflashio.c: " format, ##args)
+#else
+#define DPRINTK(format, args...)
+#endif
+
+UINT16 AppFlashSegment[CNXT_FLASH_SEGMENT_SIZE];
+
+static int CnxtFlashIORead( CNXT_FLASH_SEGMENT_E segment, int count );
+static int CnxtFlashIOWrite( CNXT_FLASH_SEGMENT_E segment, int count );
+
+static int cnxtflashio_open(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static int cnxtflashio_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static ssize_t cnxtflashio_read(struct file *file, char *usrbuf, size_t count, loff_t *ppos)
+{
+
+	// The device minor number represents the flash segment to be accessed
+	CNXT_FLASH_SEGMENT_E minor_num;
+	minor_num = (CNXT_FLASH_SEGMENT_E) MINOR( file->f_dentry->d_inode->i_rdev );
+
+	if (count > CNXT_FLASH_SEGMENT_SIZE)
+		return -EFAULT;
+			
+	if(CnxtFlashIORead( minor_num, count ))
+	{
+		return -EFAULT;
+	}
+	else 
+	{
+		if (copy_to_user(usrbuf, &AppFlashSegment, count))
+			return -EFAULT;
+	}
+
+	return 0;
+}
+
+static ssize_t cnxtflashio_write(struct file *file, const char *usrbuf, size_t count, loff_t *ppos)
+{
+
+	// The device minor number represents the flash segment to be accessed
+	CNXT_FLASH_SEGMENT_E minor_num;
+	minor_num = (CNXT_FLASH_SEGMENT_E) MINOR( file->f_dentry->d_inode->i_rdev );
+
+	if (count > CNXT_FLASH_SEGMENT_SIZE)
+		return -EFAULT;
+	
+	// This updates are local copy of the flash segment as well.
+	if(copy_from_user( &AppFlashSegment[0], usrbuf, count))
+			return -EFAULT;
+	
+	if(CnxtFlashIOWrite( minor_num, count ) == -1)
+		return -EFAULT;
+	else
+		return 0;
+}
+
+static struct file_operations cnxtflashio_fops = {
+	owner: THIS_MODULE,
+	llseek: NULL,
+	open: cnxtflashio_open,
+	release: cnxtflashio_release,
+	ioctl: NULL,
+	read: cnxtflashio_read,
+	write: cnxtflashio_write,
+	poll: NULL,
+	mmap: NULL,
+	flush: NULL,
+	fsync: NULL,
+	fasync: NULL,
+};
+
+/*---------------------------------------------------------------------------
+ *  Module Function Prototypes
+ *-------------------------------------------------------------------------*/
+static int __init UNUSED CnxtFlashIOInit( void )
+{
+
+	if (register_chrdev(CNXTFLASHIO_MAJOR, "flashio", &cnxtflashio_fops)) {
+		printk("Unable to register cnxtflashio driver on %d\n", CNXTFLASHIO_MAJOR);
+		return -1;
+	}
+
+	// Check the 'application' flash segment. Write 1 byte if its empty
+	// (just to calculate a CRC on the segment).
+	//CnxtFlashIORead( 1 );
+
+	return 0;
+}
+/*******************************************************************************
+FUNCTION NAME:
+	CnxtFlashIOWrite
+
+ABSTRACT:	
+	Stores the data into the flash storage segment.
+
+RETURN:
+	Status
+
+DETAILS:
+*******************************************************************************/
+static int CnxtFlashIOWrite( CNXT_FLASH_SEGMENT_E segment, int count )
+{
+
+	CNXT_FLASH_STATUS_E flashStatus;
+
+	int Status;
+
+	// Open the flash segment for writing.
+	flashStatus = CnxtFlashOpen( segment );
+	
+#ifdef DEBUG
+	printk("AppFlashSegment: %x  &AppFlashSegment: %x\n", 
+			AppFlashSegment, &AppFlashSegment
+	);
+	printk("AppFlashSegment[0]: %x  &AppFlashSegment[0]: %x\n", 
+			AppFlashSegment[0], &AppFlashSegment[0]
+	);
+#endif
+
+	switch( flashStatus )
+	{
+		// Either a bad CRC or segment is empty, if empty initialize.
+		case CNXT_FLASH_DATA_ERROR:
+
+
+			flashStatus = CnxtFlashWriteRequest( 
+				segment, 
+				(UINT16 *)&AppFlashSegment[0],
+				count
+			);
+			break;
+
+		case CNXT_FLASH_OWNER_ERROR:
+			printk("Wrong owner for requested Flash Segment!\n");
+			Status = - 1;
+
+			break;
+
+		default:
+
+			flashStatus = CnxtFlashWriteRequest( 
+				segment, 
+				(UINT16 *)AppFlashSegment,
+				count
+			);
+
+
+			break;
+	}
+
+			
+	if( flashStatus == CNXT_FLASH_SUCCESS )
+	{
+		Status = 0;	
+		printk("Flash Data Success: CNXT_FLASH_SEGMENT_%d\n", segment+1 );
+
+	} else {
+		Status = -1;
+		printk("Flash Data Failed: CNXT_FLASH_SEGMENT_%d\n", segment+1 );
+	}
+
+	return Status;
+}
+/*******************************************************************************
+FUNCTION NAME:
+	CnxtFlashIORead
+
+ABSTRACT:	
+	Get the data from the flash storage segment.
+
+RETURN:
+	Status
+
+DETAILS:
+*******************************************************************************/
+static int CnxtFlashIORead( CNXT_FLASH_SEGMENT_E segment, int count )
+{
+
+	CNXT_FLASH_STATUS_E flashStatus;
+
+	int Status = 0;
+
+	flashStatus = CnxtFlashOpen( segment );
+
+	switch( flashStatus )
+	{
+		// Either a bad CRC or segment is empty, if empty initialize.
+		case CNXT_FLASH_DATA_ERROR:
+
+			printk("Flash Data Error: CNXT_FLASH_SEGMENT_%d\n", segment+1 );
+#if 0
+			flashStatus = CnxtFlashWriteRequest( 
+				segment, 
+				(UINT16 *)&AppFlashSegment[0],
+				count
+			);
+#else
+			Status = - 1;
+#endif
+			break;
+
+		case CNXT_FLASH_OWNER_ERROR:
+			printk("Wrong owner for requested Flash Segment!\n");
+			Status = - 1;
+
+			break;
+
+		default:
+			printk("Flash Data Success: CNXT_FLASH_SEGMENT_%d\n", segment+1 );
+
+			CnxtFlashReadRequest( 
+				segment, 
+				(UINT16 *)&AppFlashSegment[0],
+				count
+			);
+
+
+			break;
+	}
+
+	return Status;
+}
+
+static void __exit UNUSED CnxtFlashIOExit( void )
+{
+	unregister_chrdev(CNXTFLASHIO_MAJOR, "cnxtflashio");
+}
+
+module_init( CnxtFlashIOInit );
+module_exit( CnxtFlashIOExit );
+
+
+
+
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/cnxtirq.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cnxtirq.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/cnxtirq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cnxtirq.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,68 @@
+/****************************************************************************
+*
+*	Name:			cnxtirq.c
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:22:06  $
+****************************************************************************/
+
+/* cnxtirq.c - CNXT interrupt stuff */
+
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/bspcfg.h>
+#include <asm/arch/cnxtbsp.h>
+#include <asm/arch/OsTools.h>
+
+#include <asm/system.h>
+#include <linux/module.h>
+
+void intUnlock( UINT32 oldlevel )
+{
+  // Enables ARM IRQ interrupt
+  restore_flags( oldlevel );
+}
+
+UINT32 intLock( void )
+{
+  // Disables ARM IRQ interrupt
+
+  UINT32	irqlevel;
+  save_flags_cli(irqlevel);
+  return irqlevel;
+}
+
+BOOL intContext( void )
+{
+	return FALSE;
+}
+
+
+void PICClearIntStatus(UINT32 IntSource)
+{
+   HW_REG_WRITE (PIC_TOP_ISR_IRQ, (1 <<IntSource) );
+}
+
+EXPORT_SYMBOL(intLock);
+EXPORT_SYMBOL(intUnlock);
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/cnxtsio.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cnxtsio.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/cnxtsio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cnxtsio.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,618 @@
+/****************************************************************************
+****	Copyright (c) 2001, 2002
+****	Conexant Systems Inc. (formerly Rockwell Semiconductor Systems)
+****
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************/
+/***************************************************************************
+**
+**	MODULE NAME:
+**		cnxtsio (Conexant Serial Input/Output)
+**
+**	FILE NAME:            
+**		cnxtsio.c
+**
+**	ABSTRACT:
+**		This serial driver is totally invisible to Linux. It is used solely by
+**		the ADSL DMT Dumb and Smart Terminal debug interfaces. It interfaces to
+**		the BSP via sysserial.c.
+**
+*******************************************************************************/
+
+/******************************************************************************
+** $Archive:   S:/Embedded/archives/Linux/BSP_CX821xx/uClinux2.4.6/linux/arch/armnommu/mach-cx821xx/cnxtsio.c-arc  $
+** $Revision:   1.1  $
+** $Date:   Jul 18 2003 15:57:54  $
+*******************************************************************************/
+
+
+
+//*********************************
+// Includes
+//*********************************
+#include	<linux/module.h>
+#include	<linux/init.h>
+
+#if defined (CONFIG_CNXT_ADSL)  ||  defined (CONFIG_CNXT_ADSL_MODULE)
+#include <asm/errno.h>
+#include "bsptypes.h"
+#include "bspcfg.h"
+#include "syslib.h"
+#include "cnxtbsp.h"
+#include "cnxtsio.h"
+#include "OsTools.h"
+#include "ostimer.h"
+#include "cnxtirq.h"
+
+
+
+//*********************************
+// Externs
+//*********************************
+extern CNXT_UART spUartChan[1];
+
+
+
+//*********************************
+// Register Addresses
+//*********************************
+//	Read Mode
+#define Ser_RHR					0x0		// Rx Hold Register (FIFO)
+#define Ser_ISR					0x2		// Interrupt Status Register
+#define	Ser_LSR					0x5		// Line Status Register
+#define	Ser_MSR					0x6		// Modem Status Register
+
+// Write Mode
+#define Ser_THR 				0x0		// Tx Hold Register (FIFO)
+#define Ser_FCR					0x2		// FIFO Control Register
+
+//	Read/Write Mode
+#define Ser_DLL					0x0		// Baud Rate Generator LSB (LCR & 0x80 == 0x80
+#define Ser_DLM					0x1		// Baud Rate Generator MSB (LCR & 0x80 == 0x80
+#define Ser_IER					0x1		// Interrupt Enable Register
+#define Ser_LCR					0x3		// Line Control Register
+#define Ser_MCR					0x4		// Modem Control Register
+#define Ser_SPR					0x7		// Scratchpad Register
+
+
+
+//*********************************
+// Register Masks
+//*********************************
+
+// Interrupt Enable Register masks
+#define IER_RDR					0x01
+#define IER_THR					0x02
+
+// Interrupt Status Register masks
+#define ISR_REG_MASK			0x0f
+#define ISR_RDA					0x04
+#define ISR_RTO					0x0C
+#define ISR_THR					0x02
+#define ISR_NONE				0x01
+
+// Interrupt Status Register masks
+
+// Line Status Register masks
+#define LSR_THE					0x20
+#define LSR_RDA					0x01
+#define LSR_OVRN				0x02
+
+
+
+//*********************************
+// Data Configuration values
+//*********************************
+
+// Baud Rate
+#define BAUD_RATE				57600
+#define MSB_BAUD				((115200/BAUD_RATE)>>8)
+#define LSB_BAUD				((115200/BAUD_RATE)&0xFF)
+#define LCR_DIVISOR_LATCH		0x80
+
+// Parity and Word Length
+#define LCR_8N1					0x03
+
+
+
+//*********************************
+// Register Access Macros
+//*********************************
+#define SPUART_REG_READ(pChan, reg, result) \
+	result = (*(volatile unsigned short *)((UINT32)pChan->regs + (reg*pChan->regAddr)))
+
+#define SPUART_REG_WRITE(pChan, reg, data) \
+	(*(volatile unsigned short *)((UINT32)pChan->regs + (reg*pChan->regAddr)))	 = (data)
+
+
+
+
+//*********************************
+// Local Prototypes
+//*********************************
+BOOLEAN uart_fifo_get_char
+(
+	UART_FIFO_T	*FifoCtx,
+	BYTE		*charbuf	// Place to put data retrieved from the fifo
+);
+
+UINT16 uart_fifo_put_chars
+(
+	UART_FIFO_T	*FifoCtx,
+	BYTE		*charbuf,	// Pointer to data to be put on fifo
+	UINT16		charbufsize	// Number of characters to be put on fifo
+) ;
+
+
+
+/*******************************************************************************
+*
+* spUartDevInit - initialise an SPUART channel
+*
+* This routine initialises some CNXT_SIO function pointers and then resets
+* the chip in a quiescent state.  Before this routine is called, the BSP
+* must already have initialised all the device addresses, etc. in the
+* CNXT_UART structure.
+*
+* RETURNS: N/A
+*******************************************************************************/
+eUARTType spUartDevInit ( CNXT_UART *pUARTChan )
+{
+	static eUARTType spUartInitChannel(CNXT_UART *pUARTChan)  ;
+
+	eUARTType eStatus;
+
+	UINT32 oldlevel = intLock();
+
+	HWSTATE.g_pUARTChan = pUARTChan;
+
+	/* reset the chip */
+	eStatus = spUartInitChannel(pUARTChan);
+
+	pUARTChan->xmtr_uart_fifo.get_idx = 0;
+	pUARTChan->xmtr_uart_fifo.put_idx = 0;
+	pUARTChan->xmtr_uart_fifo.entry_cnt = 0;
+
+	pUARTChan->rcvr_uart_fifo.get_idx = 0;
+	pUARTChan->rcvr_uart_fifo.put_idx = 0;
+	pUARTChan->rcvr_uart_fifo.entry_cnt = 0;
+
+	intUnlock(oldlevel);
+
+	return(eStatus);
+}
+
+/*******************************************************************************
+*
+* spUartInitChannel - initialise UART
+*
+* This routine performs hardware initialisation of the UART channel.
+*
+* RETURNS: N/A
+*******************************************************************************/
+
+static eUARTType spUartInitChannel(CNXT_UART *pUARTChan)
+{
+	UINT8	ichar;
+	UINT32	i;
+
+	/* Check to see if external UART is present */
+	SPUART_REG_READ(pUARTChan,Ser_LSR, ichar);
+	if ( (ichar == 0xFF) || ( (ichar & 0x60) != 0x60 ) )
+	{
+		return(NO_UART);
+	}
+
+	/* Enable and reset FIFO */
+	// Rx FIFO interrupt at 8 chars (.694 ms at 115200 bps)
+	SPUART_REG_WRITE(pUARTChan, Ser_FCR, 0x87);
+
+	/* Set up baud rate and character format */
+	SPUART_REG_WRITE(pUARTChan, Ser_LCR, LCR_DIVISOR_LATCH);
+	SPUART_REG_WRITE(pUARTChan, Ser_DLL, LSB_BAUD);
+	SPUART_REG_WRITE(pUARTChan, Ser_DLM, MSB_BAUD);
+	SPUART_REG_WRITE(pUARTChan, Ser_LCR, LCR_8N1);
+
+	/* Empty out Rx FIFO of junk */
+	for (i = 60000; i > 0; i--)
+	{
+		SPUART_REG_READ(pUARTChan, Ser_LSR, ichar);
+		if((ichar & LSR_RDA) == 0x00)
+		{
+			break;
+		}
+
+		SPUART_REG_READ(pUARTChan,Ser_RHR, ichar);
+	}
+
+	// Did we fail?
+	if (i == 0)
+	{
+		return (NO_UART);
+	}
+
+	// Configure Modem Control Reg for DTR=0, RTS=0, 
+	SPUART_REG_WRITE(pUARTChan, Ser_MCR, 0x0B);
+
+	// Read Line Status Reg because ...?
+	SPUART_REG_READ(pUARTChan, Ser_LSR, ichar);
+	
+	// Enable RX interrupt
+	SPUART_REG_WRITE(pUARTChan, Ser_IER, IER_RDR);
+
+	return(HW_UART);
+}
+
+
+/******************************************************************************
+*
+* spUartInt - interrupt level processing
+*
+* This routine handles interrupts from the UART.
+*
+* RETURNS: N/A
+******************************************************************************/
+void spUartInt(CNXT_UART *pUARTChan)	/* ptr to struct describing channel */
+{
+
+	UINT8	intStatus;
+
+	// Get the copy of the uart ISR register
+	SPUART_REG_READ( pUARTChan, Ser_ISR, intStatus );
+	intStatus &= ISR_REG_MASK;
+
+	while ( intStatus != ISR_NONE )
+	{
+		/* process all pending interrupts */
+
+		// NOTE: The first character write to the tx
+		// fifo should clear out the ISR_THR bit.
+		if ( intStatus == ISR_THR )
+		{
+			char	outChar;
+			UINT32	i;
+
+			for ( i = 0; i < 16; i++)
+			{
+				// Get a character to transmit from the fifo
+				if ( uart_fifo_get_char (&pUARTChan->xmtr_uart_fifo, &outChar) == TRUE )
+				{
+					SPUART_REG_WRITE( pUARTChan, Ser_THR, outChar);
+				}
+				else
+				{
+					// Since there are no more characters in the xmit
+					// fifo to transmit then disable the xmit fifo empty
+					// interrupt bit because we are not concerned now
+					// when it goes empty.	The next time characters are
+					// written to the fifo it will be reenabled.
+
+					UINT8	IERStatus = 0;
+
+					SPUART_REG_READ( pUARTChan, Ser_IER, IERStatus );
+					IERStatus &= ~IER_THR;
+					SPUART_REG_WRITE(pUARTChan, Ser_IER, IERStatus );
+
+					// No more characters in the xmtr fifo so
+					// exit the for loop now.
+					break;
+				}
+			}
+		}
+
+		// if RX Data Ready or Rx Data Timeout
+		else if( (intStatus == ISR_RDA) || (intStatus == ISR_RTO) )
+		{
+			#define SIZE_OF_RXBUF 20 // HW FIFO size + a few spares
+			char RxBuf [SIZE_OF_RXBUF] ;
+			UINT16 CharCnt = 0 ;
+			UINT8 lsrStatus ;
+			char rcvChar ;
+
+			// Do forever
+			while (1)
+			{
+				// if there is RX FIFO overrun
+				SPUART_REG_READ(pUARTChan, Ser_LSR, lsrStatus);
+				if ( ( lsrStatus & LSR_OVRN ) != 0x00 )
+				{
+					printk ("ADSL Serial Port Overrun!\n" ) ;
+				}
+
+				// if there is NO data in RX FIFO
+				if ( (lsrStatus & LSR_RDA) == 0x00 )
+				{
+					// exit loop
+					break;
+				}
+
+				// Read a Char
+				SPUART_REG_READ(pUARTChan, Ser_RHR, rcvChar);
+				
+				// Stuff in local Rx buffer
+				RxBuf [CharCnt++] = rcvChar ;
+				
+				// If local Rx buffer full
+				if ( CharCnt == SIZE_OF_RXBUF )
+				{
+					uart_fifo_put_chars ( &pUARTChan->rcvr_uart_fifo, &RxBuf[0], CharCnt ) ;
+					CharCnt = 0 ;
+				}
+			}
+			
+			// If we still have unqueued RX Data
+			if ( CharCnt != 0 )
+			{
+				// Queue it
+				uart_fifo_put_chars ( &pUARTChan->rcvr_uart_fifo, &RxBuf[0], CharCnt ) ;
+			}
+		}
+		else
+		{
+			printk ("Unknown Status: %x\n", intStatus ) ;
+		}
+
+		// read ISR for next iteration
+		SPUART_REG_READ( pUARTChan, Ser_ISR, intStatus);
+		intStatus &= ISR_REG_MASK;
+	}
+}
+
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		uart_fifo_get_char
+
+ABSTRACT:
+		Get a character from the fifo
+
+DETAILS:
+		Returns TRUE if successful, FALSE if not successful.
+
+*******************************************************************************/
+
+BOOLEAN uart_fifo_get_char
+(
+	UART_FIFO_T	*FifoCtx,
+	BYTE		*charbuf	// Place to put data retrieved from the fifo
+)
+{
+	// Protect the fifo manipulation operations from interrupts
+	UINT32 oldlevel = intLock();
+
+	// Is there data on the fifo?
+	if ( FifoCtx->entry_cnt > 0 )
+	{
+		// Get data from the fifo context given to us
+		*charbuf = FifoCtx->fifo[ FifoCtx->get_idx++ ];
+
+		// Process the get index to account for queue wrapping
+		if(	FifoCtx->get_idx >= SIZE_OF_UART_FIFO )
+		{
+			FifoCtx->get_idx = 0;
+		}
+
+		// Indicate an entry was removed from the queue
+		FifoCtx->entry_cnt--;
+
+		// Response successfully dequeued
+		intUnlock(oldlevel);
+		return TRUE;
+	}
+	else
+	{
+		// No response to remove from the queue.
+		intUnlock(oldlevel);
+		return FALSE;
+	}
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		uart_fifo_put_char
+
+ABSTRACT:
+		Put characters into the fifo
+
+DETAILS:
+		Returns number of characters not put on fifo.
+
+*******************************************************************************/
+
+UINT16 uart_fifo_put_chars
+(
+	UART_FIFO_T	*FifoCtx,
+	BYTE		*charbuf,	// Pointer to data to be put on fifo
+	UINT16		charbufsize	// Number of characters to be put on fifo
+)
+{
+	UINT32	oldlevel;
+	CHAR	*pbuf;
+	UINT16	index;
+	UINT16	numcharsput;
+
+	// Protect the fifo manipulation operations from interrupts
+	oldlevel = intLock();
+
+	pbuf = charbuf;
+
+	// Is there room for all of the data on the queue?
+	if ( (SIZE_OF_UART_FIFO - FifoCtx->entry_cnt) > charbufsize )
+	{
+		index = charbufsize;
+		numcharsput = charbufsize;
+	}
+	else
+	{
+		index = (SIZE_OF_UART_FIFO - FifoCtx->entry_cnt);
+		numcharsput = index;
+	}
+
+	while( index > 0 )
+	{
+		// Put the character into the fifo
+		FifoCtx->fifo[ FifoCtx->put_idx++ ] = *pbuf++;
+
+		// Process the put index to account for queue wrapping
+		if(	FifoCtx->put_idx >= SIZE_OF_UART_FIFO )
+		{
+			FifoCtx->put_idx = 0;
+		}
+
+		// Indicate an entry was placed on the queue
+		FifoCtx->entry_cnt++;
+		index--;
+	}
+
+	// All of some of the characters successfully put on fifo
+	intUnlock(oldlevel);
+	return numcharsput;
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		uart_xmtr_fifo_put_chars
+
+ABSTRACT:
+		Put characters into the xmtr fifo
+
+DETAILS:
+		Returns TRUE if successful, FALSE if not successful.
+
+*******************************************************************************/
+
+BOOLEAN uart_xmtr_fifo_put_chars
+(
+	BYTE		*charbuf,	// Pointer to data to be put on fifo
+	UINT16		charbufsize	// Number of characters to be put on fifo
+)
+{
+
+	BYTE		*pChar;
+	UINT16		numcharsput;
+	UINT16		numcharsleft;
+	CNXT_UART	*pUARTChan = &spUartChan[0];
+
+	numcharsleft = charbufsize;
+	pChar = charbuf;
+
+	while( 1 )
+	{
+		UINT8 IERStatus ;
+
+		// Put the characters into the transmitter fifo
+		numcharsput = uart_fifo_put_chars( &pUARTChan->xmtr_uart_fifo, pChar, numcharsleft );
+
+		//adjust the character pointer and the character count.
+		pChar += numcharsput;
+		numcharsleft -= numcharsput;
+
+		// Is the transmit interrupt disabled?
+		// (It gets disabled in the ISR when it empties the FIFO)
+		if
+		(
+			( HW_UART == HWSTATE.eUARTState)
+		&&
+			
+			( ! (SPUART_REG_READ( pUARTChan, Ser_IER, IERStatus ) & IER_THR ) )
+		)
+		{
+			// Put the first character into the uart
+			// to start the interrupt driven draining process
+
+			UINT8 IERStatus ;
+			char outChar ;
+
+			// (There may be no chars if ISR has already drained the FIFO between
+			// the time we put them in and the time we reach this statement)
+			if ( uart_fifo_get_char(&pUARTChan->xmtr_uart_fifo, &outChar) )
+			{
+				// output first char
+				SPUART_REG_WRITE(pUARTChan, Ser_THR, outChar);
+
+				// Reenable tx interrupt since ISR disables it when it
+				// empties software FIFO and that must be the case if the
+				// HW TX FIFO (aka Tx Hold Reg) is empty.
+				SPUART_REG_READ( pUARTChan, Ser_IER, IERStatus );
+				IERStatus |= IER_THR;
+				SPUART_REG_WRITE(pUARTChan, Ser_IER, IERStatus );
+			}
+		}
+
+		// Did the xmtr fifo accept all of the characters?
+		if ( numcharsleft == 0)
+		{
+			// Then we are through.
+			return TRUE;
+		}
+
+		// It did not so delay a while
+		// and try again.
+		TaskDelayMsec(10);
+	}
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		uart_rcvr_fifo_get_char
+
+ABSTRACT:
+		Gets a character from the rcvr fifo
+
+DETAILS:
+		Returns TRUE if there was a character, FALSE if not.
+
+*******************************************************************************/
+
+BOOLEAN uart_rcvr_fifo_get_char
+(
+	BYTE		*charbuf	// Place to put character from fifo
+)
+{
+	CNXT_UART	*pUARTChan = &spUartChan[0];
+	int		status;
+	BYTE	data;
+
+	status = uart_fifo_get_char ( &pUARTChan->rcvr_uart_fifo, &data ) ;
+
+	if ( status )
+	{
+		 // We got a character.
+		 *charbuf = data;
+		 return TRUE;
+	}
+	else
+	{
+		// Either there was no received characters
+		// OR an error occured.
+		return FALSE;
+	}
+}
+
+EXPORT_SYMBOL(uart_xmtr_fifo_put_chars);
+EXPORT_SYMBOL(uart_rcvr_fifo_get_char);
+
+#endif	//if defined (CONFIG_CNXT_ADSL)  ||  defined (CONFIG_CNXT_ADSL_MODULE)
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/cnxttimer.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cnxttimer.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/cnxttimer.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/cnxttimer.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,295 @@
+/****************************************************************************
+*
+*	Name:			cnxttimer.c
+*
+*	Description:	CNXT timer driver
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   lewisrc  $
+*  $Revision:   1.3  $
+*  $Modtime:   Jul 18 2003 13:29:16  $
+****************************************************************************/
+
+/*
+DESCRIPTION
+This library contains routines to manipulate the timer functions on a 
+CNXT timer. This file implements low level timer hardware access.
+
+There are 4 programmable timers available with a range up to 65ms.
+The timers are based on 16-bit counters that increment at a 1.0MHz rate.
+This gives a resolution of 1 microsecond.  The third timer is also used
+as a system watchdog.  If the interrupt for this timer is not cleared
+before the next interrupt event a reset occurs.
+
+The timers increment from 0 up to a limit value.  The limit value is
+is programmed into the TM_LMT1 register for timer 1, TM_LMT2 for timer 2
+and TM_LMT3 for timer 3.  When the timer reaches the limit value, it resets
+back to zero and sets a corresponding interrupt.  If TM_LMT is set to zero,
+then TM_CNT stays reset and never causes an interrupt.  TM_CNT is reset to
+zero whenever the TM_LMT register is written to.
+
+The timer is loaded by writing to TM_LMT register, and then, if
+enabled, the timer register TM_CNT will count up to the limit value set 
+in TM_LMT. 
+
+At any time, the current timer value may be read from the TM_CNT register.
+
+
+REGISTERS:
+
+Note: x used in for example, TM_CNT(x) represents timers 1,2,3,4  There
+are a total of 8 timer registers for the 4 timers.
+
+TM_CNT(x): (read only)  Current count value of the timer.  The timer
+                        increments every 1 uS from 0 to the limit
+                        value, then resets to 0 and counts again. TM_CNT
+                        is reset whenever TM_LMT is written.
+
+TM_LMT(x): (read/write) When the current count value of the timer reaches
+                        the limit value, an interrupt INT_TM is set. 
+                        the periodic timer interrupt event rate is = 
+                        1 MHz / (TM_LMT + 1).  If TM_LMT is set to 0, 
+                        TM_CNT remains reset.  TM_CNT is reset whenever
+                        TM_LMT is written.
+
+
+BSP
+Apart from defining such macros described above as are needed, the BSP
+will need to connect the interrupt handlers (typically in sysHwInit2()).
+
+SEE ALSO:
+.I "CX82100 Silicon System Design Engineering Specification"
+*/
+
+#include <linux/config.h>
+
+#include <linux/sched.h>
+#include <asm/arch/irq.h>
+
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/bspcfg.h>
+#include <asm/arch/cnxtbsp.h>
+#include <asm/arch/cnxttimer.h>
+#include <asm/arch/gptimer.h>
+#include <asm/arch/cnxtirq.h>
+
+/* register definitions */
+#ifdef DEVICE_YELLOWSTONE
+	#define TIMER_BASE					0x00601400
+	#define HW_TIMER_LIMIT_BASE			(TIMER_BASE + 0x108)
+	#define HW_TIMER_COUNT_BASE			(TIMER_BASE + 0x10C)
+	#define HW_TIMER_REG_OFFSET			0xC
+#else
+	#define HW_TIMER_COUNT_BASE			0x00350020
+	#define HW_TIMER_LIMIT_BASE			(HW_TIMER_COUNT_BASE + 0x10)
+	#define HW_TIMER_REG_OFFSET			4
+#endif
+
+#define STOP 			0
+
+typedef void (* P_TIMER_HANDLER) ( WORD ElapsedTime, void *pContext ) ;
+
+typedef struct
+{
+	HW_TIMER_T		 Index ;			// Quick reference to our index
+	BOOLEAN			 Enabled ;			// flag
+	PTMR_CALLBACK	 pCallback ;		// Callback Handler
+	void			*pCallbackContext ;	// arg to callback
+	WORD			 TimerLimit ;		// cache of readonly timer limit
+
+	// Precomputed hardware constants
+	DWORD			 TimerStatus ;		// INT_TM1 etc.
+	DWORD			 TimerIrq ; 		// INT_LVL_TIMER_1 etc
+	DWORD volatile	*pTimerLimit ;		// Address of hardware timer's limit
+	DWORD volatile	*pTimerCount ;		// Address of hardware timer's count
+} PROG_HW_TIMER ;
+
+PROG_HW_TIMER TimerContext [NUM_PROG_HW_TIMERS] ;
+
+/******************************************************************************
+FUNCTION:	CnxtTimerEnable
+ABSTRACT:	Enables programmable timer
+DETAILS:
+*******************************************************************************/
+int CnxtTimerEnable ( HW_TIMER_T TimerIndex, PTMR_CALLBACK pCallback )
+{
+	PROG_HW_TIMER *pTimer = &TimerContext[TimerIndex] ;
+	int Error ;
+
+	void CnxtTimerIsr ( int irq, void *dev_id, struct pt_regs * regs ) ;
+
+	// precompute constants
+	pTimer->pTimerLimit = (DWORD *)(((char *)HW_TIMER_LIMIT_BASE) + TimerIndex * HW_TIMER_REG_OFFSET ) ;
+	pTimer->pTimerCount = (DWORD *)(((char *)HW_TIMER_COUNT_BASE) + TimerIndex * HW_TIMER_REG_OFFSET ) ;
+	pTimer->TimerStatus = INT_TM1 << TimerIndex ;
+	pTimer->TimerIrq	= INT_LVL_TIMER_1 + TimerIndex ;
+	pTimer->pCallback	= pCallback ;
+
+	// Stop the timer
+	*pTimer->pTimerLimit = STOP ;
+
+	// Clear out the timer interrupt
+	* ( (UINT32 *) INT_STAT) = pTimer->TimerStatus ;
+
+	// Register IRQ and enable it
+	Error = request_irq ( pTimer->TimerIrq, CnxtTimerIsr, 0, "Timer ISR", pTimer ) ;
+	if ( Error )
+	{
+		printk ( "Conexant Hardware Timer IRQ enable failed. Error=%d\n", Error ) ;
+		return Error ;
+	} 
+	cnxt_unmask_irq ( pTimer->TimerIrq );
+
+	printk ( "Conexant hardware timer %d enabled\n", TimerIndex+1 ) ;
+
+	// Note enabled
+	pTimer->Enabled = TRUE ;
+
+	return 0 ;
+}
+
+
+
+/******************************************************************************
+FUNCTION:	CnxtTimerDisable
+ABSTRACT:	Disables programmable timer
+DETAILS:
+*******************************************************************************/
+int CnxtTimerDisable ( HW_TIMER_T TimerIndex )
+{
+	PROG_HW_TIMER *pTimer = &TimerContext[TimerIndex] ;
+
+	printk ( "Conexant hardware timer %d disabled\n", TimerIndex ) ;
+
+	// disable & free interrupt
+	cnxt_mask_irq ( pTimer->TimerIrq );
+	free_irq ( pTimer->TimerIrq, pTimer ) ;
+
+	// Note disabled
+	pTimer->Enabled = FALSE ;
+
+	return 0 ;
+}
+
+
+
+/******************************************************************************
+FUNCTION:	CnxtTimerIsr
+ABSTRACT:	Cnxt Timer Interrupt Service Routine
+DETAILS:
+*******************************************************************************/
+void CnxtTimerIsr ( int irq, void *dev_id, struct pt_regs * regs )
+{
+	PROG_HW_TIMER *pTimer = (PROG_HW_TIMER *) dev_id ;
+ 
+	// Clear out the timer2 interrupt
+	* ( (UINT32 *) INT_STAT) = pTimer->TimerStatus ;
+
+	// Notify timer handler of how much time has elapsed (namely our timer limit value)
+	pTimer->pCallback ( pTimer->TimerLimit, pTimer->pCallbackContext ) ;
+}	
+
+
+
+
+/******************************************************************************
+FUNCTION:	CnxtTimerStart
+ABSTRACT:	Starts timer running
+DETAILS:	Starts the timer from 0 to the given TimerValue. The timer automatically
+			resets to 0 and begins incrementing again when the value reaches
+			the limit TimerValue.
+*******************************************************************************/
+int CnxtTimerStart ( HW_TIMER_T TimerIndex, WORD TimerValue, void *pContext )
+{
+	PROG_HW_TIMER *pTimer = &TimerContext[TimerIndex] ;
+
+	if ( ! pTimer->Enabled )
+	{
+		printk ( "Tried to start disabled Conexant timer!\n" ) ;
+		return -ETMRNRDY ;
+	}
+
+	// Start the timer with the desired timeout
+	*pTimer->pTimerLimit = TimerValue ;
+
+	// Save the time that will be expired when timer ISR runs
+	pTimer->TimerLimit = TimerValue ;
+
+	// Save the context
+	pTimer->pCallbackContext = pContext ;
+
+
+	return 0 ;
+}
+
+
+
+/******************************************************************************
+FUNCTION:	CnxtTimerStop
+ABSTRACT:	Stops timer
+DETAILS:	
+*******************************************************************************/
+int CnxtTimerStop ( HW_TIMER_T TimerIndex )
+{
+	PROG_HW_TIMER *pTimer = &TimerContext[TimerIndex] ;
+
+	if ( ! pTimer->Enabled )
+	{
+		printk ( "Tried to stop disabled Conexant timer!\n" ) ;
+		return -ETMRNRDY ;
+	}
+
+	// Stop the timer
+	*pTimer->pTimerLimit = STOP ;
+
+	// Clear out the timer interrupt
+	* ( (UINT32 *) INT_STAT) = pTimer->TimerStatus ;
+
+	return 0 ;
+}
+
+
+
+/******************************************************************************
+FUNCTION:	CnxtTimerRead
+ABSTRACT:	Reads the running timer
+DETAILS:	If timer has expired and reloaded, the returned time will reflect
+			this and thus may exceed the timer limit.
+*******************************************************************************/
+LONG CnxtTimerRead ( HW_TIMER_T TimerIndex )
+{
+	PROG_HW_TIMER *pTimer = &TimerContext[TimerIndex] ;
+	DWORD TimerValue ;
+
+	// If we have an interrupt pending
+	if ( * ( (UINT32 *) INT_STAT) & pTimer->TimerStatus )
+	{
+		// Time has restarted. Use the full limit value + current value
+		TimerValue = *pTimer->pTimerCount + *pTimer->pTimerLimit ;
+	}
+	else
+	{
+		// Return current timer value
+		TimerValue = *pTimer->pTimerCount ;
+	}
+
+	return TimerValue ;
+}
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/defeepromdata.h linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/defeepromdata.h
--- linux-2.4.29/arch/armnommu/mach-cx821xx/defeepromdata.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/defeepromdata.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,276 @@
+/****************************************************************************
+*
+*	Name:			defeepromdata.h
+*
+*	Description:	Default USB enummeration data, in case the EEPROM's
+*					not programmed
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:22:06  $
+****************************************************************************/
+
+#ifndef DEFEEPROMDATA_H
+#define DEFEEPROMDATA_H
+
+/* String lengths */
+#define  LANG_ID_STR_LEN			4
+#define  MFR_ID_STR_LEN          4
+#define  PROD_ID_STR_LEN			30
+#define  SERIAL_NUM_STR_LEN		18
+#define  MAC_ADDRESS_STR_LEN		6
+
+/* WARNING - THESE SIZES MUST BE DWORD ALIGNED */
+#define TBL_HEADER_SIZE          32
+#define	DESC_TBL_SIZE			   20
+#define	DEV_TBL_SIZE			   68
+#define	LANG_ID_TBL_SIZE		   4
+#define	MFR_ID_TBL_SIZE			4
+#define	PROD_ID_TBL_SIZE		   32
+#define	SERIAL_NUM_TBL_SIZE		20
+#define	MAC_ADDRESS_TBL_SIZE		8
+
+/* WARNING - THESE OFFSETS MUST BE DWORD ALIGNED */
+#define DESC_TBL_START  			( TBL_HEADER_SIZE )
+#define DEV_TBL_START	   		( DESC_TBL_START + DESC_TBL_SIZE )
+#define LANG_ID_TBL_START	   	( DEV_TBL_START + DEV_TBL_SIZE )
+#define MFR_ID_TBL_START		   ( LANG_ID_TBL_START + LANG_ID_TBL_SIZE )
+#define PROD_ID_TBL_START		   ( MFR_ID_TBL_START + MFR_ID_TBL_SIZE )
+#define SERIAL_NUM_TBL_START	   ( PROD_ID_TBL_START + PROD_ID_TBL_SIZE )
+#define MAC_ADDRESS_TBL_START	   ( SERIAL_NUM_TBL_START + SERIAL_NUM_TBL_SIZE )
+
+struct DefEEPROMDataStruct
+{
+	UINT32 uSig;
+	UINT8* pPtrs[ 7 ];
+	UINT8  uData[ 480 ];
+};
+
+static struct DefEEPROMDataStruct DefEEPROMData =
+{
+   EEPROM_SIG,
+
+   /* Pointers to the descriptor, config, language, and string tables */
+   {
+	   ( UINT8* )DESC_TBL_START,			/* Device dexcriptor table */
+	   ( UINT8* )DEV_TBL_START,			/* Device configuration table */
+	   ( UINT8* )LANG_ID_TBL_START,		/* Language ID table */
+	   ( UINT8* )MFR_ID_TBL_START,	   /* Manufacturer string */
+	   ( UINT8* )PROD_ID_TBL_START,		/* Product string */
+	   ( UINT8* )SERIAL_NUM_TBL_START,	/* Serial number string */
+	   ( UINT8* )MAC_ADDRESS_TBL_START	/* Mac Address string */
+   },
+
+   { 
+      /* DEVICE DESCRIPTOR TABLE */
+      DEV_DESC_LENGTH,	               /* size in bytes */
+	   DESC_TYPE_DEV,		               /* device type */
+	   (UINT8)USB_SPEC_110,	            /* USB version 1.1 */
+	   (UINT8)(USB_SPEC_110>>8),  
+	   P50_DEV_CLASS,					      /* Device Class */
+	   P50_DEV_SUBCLASS,				      /* Subclass */
+	   P50_DEV_PROTOCOL,				      /* Device protocol */
+	   USB_MAX_PACKET_SIZE,		         /* Maximum packet size */
+	   (UINT8)CONEXANT_VENDOR_ID,			/* Conexant Vendor ID */
+	   (UINT8)(CONEXANT_VENDOR_ID>>8),
+	   (UINT8)P50_PRODUCT_ID,				/* Product ID */
+	   (UINT8)(P50_PRODUCT_ID>>8),
+	   (UINT8)P50_DEV_ID,				   /* Device Ver 1.0 */
+	   (UINT8)(P50_DEV_ID>>8),
+	   DESC_STRING_MANUFACTURER,
+	   DESC_STRING_PRODUCT,
+	   DESC_STRING_SERIAL,
+	   MAX_NUM_CONFIG,					   /* Number of Configuration */
+	   
+      0, 0,                            /* Padding for DWORD alignment */
+
+	   /* DEVICE CONFIGURATION TABLE */
+      /* Config descriptor section: 9 bytes*/
+      CONFIG_DESC_LENGTH,					/* size in bytes */
+      DESC_TYPE_CONFIG,	               /* Config type */
+      (UINT8) (CONFIG_DESC_LENGTH + INTER_DESC_LENGTH + (EP_DESC_LENGTH * (MAX_NUM_ENDPOINT - 2))),
+      (UINT8) ((CONFIG_DESC_LENGTH + INTER_DESC_LENGTH + (EP_DESC_LENGTH * (MAX_NUM_ENDPOINT - 2))) >> 8),
+      NUM_OF_INTERFACE,    				/* Total # of Interface */
+      CONFIG_VALUE,   				      /* Config ID */
+      CONFIG_STR,   				         /* Config str. index */
+      CONFIG_ATTRIBUTES,  				   /* Attribute => bus power,remote wake up */
+      MAX_POWER_CONSUME,   				/* Max power = 500 mA */
+     
+      /* Interface descriptor section: 9 bytes*/
+      INTER_DESC_LENGTH,					/* Length */
+      DESC_TYPE_INTER ,                /* Interface type */
+      INTER_NUM,        					/* Interface ID */
+      ALT_SETTING,					      /* Alt Interface for this one */
+      MAX_NUM_ENDPOINT - 2,				/* Number of physical endpoints used by this interface */
+      INTER_CLASS,					      /* Class code */
+      INTER_SUBCLASS,   					/* Sub Class code */
+      INTER_PROTOCOL,   					/* Protocol */
+      INTER_STR,					         /* Str. index */
+           
+      /* Endpoint descriptor section: 7 bytes  */
+      EP_DESC_LENGTH,					   /* Length */
+      DESC_TYPE_EP,		               /* EP type  */
+      0x80 | ENDPOINT1,	               /* EP1 IN */
+      EP_BULK,			                  /* EP type */
+      (UINT8) BULK_MAX_PACKET_SIZE,		/* LSB Max Packet size */
+      (UINT8) (BULK_MAX_PACKET_SIZE >> 8),  /* MSB Max Packet size */
+      BULK_POLL_INTERVAL,					/* Polling Interval */
+
+      EP_DESC_LENGTH,					   /* Length  */
+      DESC_TYPE_EP,		               /* EP type */
+      0x00 | ENDPOINT1,	               /* EP1 OUT */
+      EP_BULK,			                  /* EP type */
+      (UINT8) BULK_MAX_PACKET_SIZE,		/* LSB Max Packet size */
+      (UINT8) (BULK_MAX_PACKET_SIZE >> 8),  /* MSB Max Packet size */
+      BULK_POLL_INTERVAL,					/* Polling Interval */
+
+      EP_DESC_LENGTH,					   /* Length  */
+      DESC_TYPE_EP,		               /* EP type */
+      0x80 | ENDPOINT2,	               /* EP2 IN  */
+      EP_BULK,			                  /* EP type */
+      (UINT8) BULK_MAX_PACKET_SIZE,		/* LSB Max Packet size */
+      (UINT8) (BULK_MAX_PACKET_SIZE >> 8),  /* MSB Max Packet size */
+      BULK_POLL_INTERVAL,					/* Polling Interval */
+
+      EP_DESC_LENGTH,					   /* Length  */
+      DESC_TYPE_EP,		               /* EP type */
+      0x00 | ENDPOINT2,	               /* EP2 OUT */
+      EP_BULK,			                  /* EP type */
+      (UINT8) BULK_MAX_PACKET_SIZE,		/* LSB Max Packet size */
+      (UINT8) (BULK_MAX_PACKET_SIZE >> 8),  /* MSB Max Packet size */
+      BULK_POLL_INTERVAL,					/* Polling Interval */
+
+      EP_DESC_LENGTH,					   /* Length  */
+      DESC_TYPE_EP,		               /* EP type */
+      0x80 | ENDPOINT3,	               /* EP3 IN  */
+      EP_BULK,			                  /* EP type */
+      (UINT8) BULK_MAX_PACKET_SIZE,		/* LSB Max Packet size */
+      (UINT8) (BULK_MAX_PACKET_SIZE >> 8),  /* MSB Max Packet size */
+      BULK_POLL_INTERVAL,					/* Polling Interval */
+
+      EP_DESC_LENGTH,					   /* Length  */
+      DESC_TYPE_EP,		               /* EP type */
+      0x00 | ENDPOINT3,	               /* EP3 OUT */
+      EP_BULK,			                  /* EP type */
+      (UINT8) BULK_MAX_PACKET_SIZE,		/* LSB Max Packet size */
+      (UINT8) (BULK_MAX_PACKET_SIZE >> 8),  /* MSB Max Packet size */
+      BULK_POLL_INTERVAL,					/* Polling Interval */
+
+      EP_DESC_LENGTH,					   /* Length  */
+      DESC_TYPE_EP,		               /* EP type */
+      0x80 | ENDPOINT4,	               /* EP4 IN  */
+      EP_INTERRUPT,		               /* EP type */
+      (UINT8) INT_MAX_PACKET_SIZE,     /* LSB Max packet size */
+      (UINT8) (INT_MAX_PACKET_SIZE >> 8), /* MSB Max packet size */
+      INT_POLL_INTERVAL,
+
+      0,					                  /* Padding, for DWORD alignment */
+
+      /* LANGUAGE ID TABLE */
+      LANG_ID_STR_LEN,	               /* Total size in bytes */
+      DESC_TYPE_STRING,	               /* String type */
+      (UINT8) USB_MS_ENGLISH_ID,		   /* LSB Language ID code */
+      (UINT8) (USB_MS_ENGLISH_ID >> 8),/* MSB Language ID code */
+
+	   /* MANUFACTURER STRING TABLE */
+	   MFR_ID_STR_LEN,		            /* Total size in bytes */
+	   DESC_TYPE_STRING,	               /* String type */
+
+		/* The actual string, in unicode.  Number of bytes must match size */
+	   0x00, '-',
+
+	   /* PRODUCT ID STRING */
+	   PROD_ID_STR_LEN,	               /* Total size in bytes */
+	   DESC_TYPE_STRING,	               /* String type */
+
+	   /* The actual string, in unicode.  Number of bytes must match size */
+	   'A', 0x00, 'D', 0x00, 'S', 0x00, 'L', 0x00, ' ',
+	   0x00, 'U', 0x00, 'S', 0x00, 'B', 0x00, ' ',
+	   0x00, 'M', 0x00, 'O', 0x00, 'D', 0x00, 'E', 0x00, 'M', 0x00,
+	   0x00, 0x00,		                  /* Padding for DWORD alignment */
+
+	   /* SERIAL NUMBER STRING */
+	   SERIAL_NUM_STR_LEN,	            /* Total size in bytes */
+	   DESC_TYPE_STRING,  	            /* String type */
+
+	   /* The actual string, in unicode.  Number of bytes must match size */
+	   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	   0x00, 0x00,		                  /* Padding for DWORD alignment */
+
+	   /* MAC ADDRESS STRING */
+		/* This is a dummy value */
+		0x00,	0x50,	0x00,	0xCD,	0x30,	0x02,	0x00,	0x00
+   }
+};
+
+#endif
+
+/****************************************************************************
+ *
+ *  $Log:   S:/Embedded/archives/Linux/BSP_CX821xx/uClinux2.4.6/linux/arch/armnommu/mach-cx821xx/defeepromdata.h-arc  $
+ * 
+ *    Rev 1.0   Mar 19 2003 13:21:56   davidsdj
+ * Initial revision.
+ * 
+ * 2     2/28/02 8:26a Richarjc
+ * Added Conexant ownership and GPL notices.
+ * 
+ * 1     2/22/02 11:47a Palazzjd
+ * Lineo Beta
+ *  Revision 1.1  2001/12/12 14:26:32  oleks
+ *  OZH: Added Conexant "Golden Gate" support.
+ *
+ * 
+ * 1     6/13/01 8:56a Richarjc
+ * Initial checkin of the Linux kernel and BSP source code for the Golden
+ * Gate development board based upon the CX82100 Home Networking
+ * Processor.
+ * 
+ *    Rev 1.4   27 Jul 2000 17:00:32   nguyenpa
+ * The pointer offset in the default SW 
+ * eeprom table was not correct.
+ * 
+ *    Rev 1.3   20 Jul 2000 13:40:36   nguyenpa
+ * Change the default MAC address in case
+ * the EEPROM is not present.
+ * 
+ *    Rev 1.2   Jul 18 2000 17:03:28   nguyenpa
+ * Add code to read EMAC address from
+ * EEPROM into BSP HW structure.
+ * 
+ * 
+ *    Rev 1.1   Jun 29 2000 11:13:26   nguyenpa
+ * Change the byte reversal problem
+ * with PRODUCT ID STRING 
+ * 
+ *    Rev 1.0   Mar 28 2000 16:34:16   nguyenpa
+ *  
+ * 
+ *    Rev 1.1   03 Mar 2000 15:05:22   blackldk
+ * More default value changes
+ * 
+ *    Rev 1.0   28 Feb 2000 17:15:50   blackldk
+ * Bootloader ARM project
+ * 
+ ***************************************************************************/
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/dma.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/dma.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/dma.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,155 @@
+/****************************************************************************
+*
+*	Name:			dma.c
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 - 2003  Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   belljl  $
+*  $Revision:   1.2  $
+*  $Modtime:   Jun 27 2003 17:44:06  $
+****************************************************************************/
+
+#include	<linux/module.h>
+#include    <linux/init.h>
+#if defined (CONFIG_CNXT_ADSL)  ||  defined (CONFIG_CNXT_ADSL_MODULE) || defined (CONFIG_CNXT_GSHDSL) || defined (CONFIG_CNXT_GSHDSL_MODULE)
+#include "bsptypes.h"
+#include "bspcfg.h" 
+
+#include "dmasrv.h"
+#include "cnxtirq.h"
+#include "cnxtbsp.h"
+
+#if DSL_DMA
+	#include "dsl.h"
+	extern EPINFOSTRUCT DSLInfo;
+#endif
+
+BOOL AddDMABufferList ( UINT32 uDMACh,UINT32* pSBuff,UINT32 uBuffSize)
+{
+   UINT32 OldLevel;
+   register BOOL bReturn;
+   
+   /* Note : uBuffSize from BM must be <= 64 */
+   if ( (pSBuff == 0) || (uBuffSize > BULK_MAX_PACKET_SIZE) )
+      return FALSE;
+
+   /* Initialize variables to error and no BM operation (pEPBM = 0) */
+   bReturn = FALSE;
+
+   OldLevel = INTLOCK();
+
+   switch ( uDMACh )
+   {
+
+  #if DSL_DMA
+      case DMA_CHANNEL_DSL_TX :			/* 5 */
+		bReturn = DSLWriteBuffer(pSBuff,uBuffSize);
+		if (bReturn == 0)
+		{
+			DSLInfo.TxRejectCnt += 1;
+		}
+		break;
+  #endif
+
+      case DMA_CHANNEL_USB_TX_EP1 :   /* 11 */
+      case DMA_CHANNEL_USB_TX_EP2 :   /* 10 */
+      case DMA_CHANNEL_USB_TX_EP3	:  /* 9  */
+      case DMA_CHANNEL_USB_TX_EP0 :   /* 13 */
+      case DMA_CHANNEL_EMAC1_TX :
+      case DMA_CHANNEL_EMAC2_TX :
+      default :
+         break;
+   }
+
+   INTUNLOCK(OldLevel);
+   return bReturn;
+} 		
+
+
+BOOL DMAFlushChannelBuff(UINT32 uDMACh)
+{
+   UINT32 OldLevel = 0;
+   register BOOL bReturn = FALSE;
+
+   /* Need to turn off interrupts here since background task is modifying a */
+   /* variable that is accessible also from interrupt context. */
+   OldLevel = INTLOCK();
+
+   switch ( uDMACh )
+   {
+      case DMA_CHANNEL_USB_TX_EP0 : /* 13 */
+      case DMA_CHANNEL_USB_TX_EP1 : /* 11 */
+      case DMA_CHANNEL_USB_TX_EP3 : /* 9  */
+      case DMA_CHANNEL_USB_TX_EP2 : /* 10 */
+      case DMA_CHANNEL_USB_RX_EP0 :
+      case DMA_CHANNEL_USB_RX_EP1 :
+      case DMA_CHANNEL_USB_RX_EP2 :
+      case DMA_CHANNEL_USB_RX_EP3 :
+         break;
+
+      case DMA_CHANNEL_M2M_IN :
+      case DMA_CHANNEL_M2M_OUT:
+         break;
+
+  #if DSL_DMA
+     case DMA_CHANNEL_DSL_TX :			/* 5 */
+        if (DSLInfo.bTXWA)
+        {
+           if ( (DSLInfo.TxPendingInc != 0) && (DSLInfo.bTxSendMode == FALSE) )
+           {
+              DSLInfo.TxTotalPending += DSLInfo.TxPendingInc;
+              *pDSL_TXCC_DMA = DSLInfo.TxPendingInc;	/* # of TX block  to be sent */
+              DSLInfo.TxPendingInc = 0;
+	            DSLInfo.bTxSendMode = TRUE;
+	            bReturn = TRUE;
+           }
+        }
+
+        else if (DSLInfo.TxPendingInc)
+        {
+           DSLInfo.TxTotalPending += DSLInfo.TxPendingInc;
+           *pDSL_TXCC_DMA = DSLInfo.TxPendingInc;	/* # of TX block  to be sent */
+           DSLInfo.TxPendingInc = 0;
+           DSLInfo.bTxSendMode = TRUE;
+           bReturn = TRUE;
+        }
+        break;
+
+     case DMA_CHANNEL_DSL_RX :
+  #endif
+
+      case DMA_CHANNEL_EMAC1_TX :
+      case DMA_CHANNEL_EMAC2_TX :
+      case DMA_CHANNEL_EMAC1_RX :
+      case DMA_CHANNEL_EMAC2_RX :
+      default :
+         break;
+   }
+
+   INTUNLOCK(OldLevel);
+   return bReturn;
+}
+
+
+EXPORT_SYMBOL(DMAFlushChannelBuff);
+EXPORT_SYMBOL(AddDMABufferList);
+#endif	//if defined (CONFIG_CNXT_ADSL)  ||  defined (CONFIG_CNXT_ADSL_MODULE) || defined (CONFIG_CNXT_GSHDSL) || defined (CONFIG_CNXT_GSHDSL_MODULE)
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/dmasrv.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/dmasrv.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/dmasrv.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/dmasrv.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,386 @@
+/****************************************************************************
+*
+*	Name:			dmasrv.c
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 - 2003  Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   belljl  $
+*  $Revision:   1.1  $
+*  $Modtime:   Jun 27 2003 17:46:26  $
+****************************************************************************/
+
+/*---------------------------------------------------------------------------
+ *  Include Files
+ *-------------------------------------------------------------------------*/
+
+#include	<linux/module.h>
+#include    <linux/init.h>
+#if defined (CONFIG_CNXT_ADSL)  ||  defined (CONFIG_CNXT_ADSL_MODULE) || defined (CONFIG_CNXT_GSHDSL) || defined (CONFIG_CNXT_GSHDSL_MODULE)
+#include "bsptypes.h"
+//#include "epic_bsptypes.h"
+#include "bspcfg.h"
+#include "dmasrv.h"
+#include <asm/arch/dma.h>
+#include "cnxtbsp.h"
+
+#if DSL_DMA
+	#include "dsl.h"
+#endif
+
+
+/* DMA channel structures */
+DMA_CHANNEL DmaChannelTbl[ DMA_CHANNEL_MAX ];
+
+
+/****************************************************************************
+ *
+ *  Name:         void DMAInit( void )
+ *
+ *  Description:  DMA initialization
+ *
+ *  Inputs:       none
+ *
+ *  Outputs:      none
+ *
+ ***************************************************************************/
+void DmaInit( void )
+{
+   register int uDMACh;
+
+   /* For all DMA channels */
+   for ( uDMACh = 0; uDMACh < DMA_CHANNEL_MAX; uDMACh++ )
+   {
+      /* Mark channel closed */
+      DmaChannelTbl[ uDMACh ].bOpen = FALSE;
+
+      /* Mark channel disabled */
+      DmaChannelTbl[ uDMACh ].bEnabled = FALSE;
+
+      /* Set callback function pointer and parameter to NULL */
+      DmaChannelTbl[ uDMACh ].pDMACallback = 0;
+      DmaChannelTbl[ uDMACh ].pUserData = 0;
+   }
+}
+
+BOOL DmaSendBuffer
+(
+	UINT32		uDMACh, 
+	UINT32*		pBuffer,
+	UINT32		uBufferSize
+)
+{
+	BOOL	bSuccess	= FALSE;
+
+    bSuccess = ((pBuffer == NULL) ? 
+      DMAFlushChannelBuff(uDMACh) : 
+      AddDMABufferList(uDMACh, pBuffer, uBufferSize));
+
+	return bSuccess;
+}
+
+/****************************************************************************
+ *
+ *  Name:         BOOL DmaResetChannel( UINT32 uDMACh )
+ *
+ *  Description:  Resets a DMA channel
+ *
+ *  Inputs:       UINT8 uDMACh = DMA channel number
+ *
+ *  Outputs:      Returns TRUE if successful, FALSE if not
+ *
+ ***************************************************************************/
+static BOOL DmaResetChannel( UINT32 uDMACh )
+{
+   BOOL bSuccess= FALSE;
+   BOOL bState = FALSE;
+
+   /* Make sure the channel number is valid */
+   if ( uDMACh < DMA_CHANNEL_MAX)
+   {
+      /* Disable DMA channel before resetting */
+      if ( DmaChannelTbl[ uDMACh ].bOpen &&
+           DmaChannelTbl[ uDMACh ].bEnabled)
+      {
+         bState = TRUE;
+         DmaDisableChannel(uDMACh);
+      }
+
+      switch (uDMACh)
+      {
+         case DMA_CHANNEL_EMAC1_TX:
+         case DMA_CHANNEL_EMAC1_RX:
+         case DMA_CHANNEL_EMAC2_TX:
+         case DMA_CHANNEL_EMAC2_RX:
+         case DMA_CHANNEL_M2M_IN:
+         case DMA_CHANNEL_M2M_OUT:
+         case DMA_CHANNEL_DSL_TX:
+         case DMA_CHANNEL_DSL_RX:
+         case DMA_CHANNEL_USB_TX_EP3:
+         case DMA_CHANNEL_USB_TX_EP2:
+         case DMA_CHANNEL_USB_TX_EP1:
+         case DMA_CHANNEL_USB_TX_EP0:
+         case DMA_CHANNEL_USB_RX_EP3:
+         case DMA_CHANNEL_USB_RX_EP2:
+         case DMA_CHANNEL_USB_RX_EP1:
+         case DMA_CHANNEL_USB_RX_EP0:
+         default:
+            break;
+      }
+
+      if (bState)
+      {
+         /* Restore channel state to Open */
+         DmaEnableChannel(uDMACh);
+      }
+
+      bSuccess = TRUE;
+   }
+
+   return bSuccess;
+}
+
+/****************************************************************************
+ *
+ *  Name:         BOOL DmaEnableChannel( UINT32 uDMACh )
+ *
+ *  Description:  Enables a DMA channel
+ *
+ *  Inputs:       UINT8 uDMACh = DMA channel number
+ *
+ *  Outputs:      Returns TRUE if successful, FALSE if not
+ *
+ ***************************************************************************/
+BOOL DmaEnableChannel( UINT32 uDMACh )
+{
+   BOOL bSuccess = FALSE;
+
+   if (DmaChannelTbl[ uDMACh ].bEnabled != TRUE)
+   {
+      /* Make sure DMA channel is completely reset before enabling */
+      DmaResetChannel(uDMACh);
+
+      /* Make sure the channel number is valid */
+      if ( uDMACh < DMA_CHANNEL_MAX )
+      {
+         /* Need to enable DMA interface if applicable */
+         switch (uDMACh)
+         {
+            case DMA_CHANNEL_EMAC1_TX:
+            case DMA_CHANNEL_EMAC1_RX:
+            case DMA_CHANNEL_EMAC2_TX:
+            case DMA_CHANNEL_EMAC2_RX:
+            case DMA_CHANNEL_M2M_IN:
+            case DMA_CHANNEL_M2M_OUT:
+               break;
+
+		#if DSL_DMA
+		    case DMA_CHANNEL_DSL_TX:
+			   DSL_ClearStatus(DMA_CHANNEL_DSL_TX);
+			   DSL_DMAEnable(DMA_CHANNEL_DSL_TX);
+  			   DSL_EnableInterface(DMA_CHANNEL_DSL_TX);
+               break;
+            case DMA_CHANNEL_DSL_RX:
+			   DSL_ClearStatus(DMA_CHANNEL_DSL_RX);
+               DSL_DMAEnable(DMA_CHANNEL_DSL_RX);
+  			   DSL_EnableInterface(DMA_CHANNEL_DSL_RX);
+               break;
+		#endif
+
+            case DMA_CHANNEL_USB_TX_EP3:
+            case DMA_CHANNEL_USB_TX_EP2:
+            case DMA_CHANNEL_USB_TX_EP1:
+            case DMA_CHANNEL_USB_TX_EP0:
+            case DMA_CHANNEL_USB_RX_EP3:
+            case DMA_CHANNEL_USB_RX_EP2:
+            case DMA_CHANNEL_USB_RX_EP1:
+            case DMA_CHANNEL_USB_RX_EP0:
+               break;
+
+            default:
+               return bSuccess;
+         }
+
+         /* Need to enable DMA interrupt if applicable */
+
+         /* Mark the channel as enabled */
+         DmaChannelTbl[ uDMACh ].bEnabled = TRUE;
+         bSuccess = TRUE;
+      }
+   }
+
+   return bSuccess;
+}
+
+/****************************************************************************
+ *
+ *  Name:         BOOL DmaDisableChannel( UINT8 uDMACh )
+ *
+ *  Description:  Disables a DMA channel
+ *
+ *  Inputs:       UINT8 uDMACh = DMA channel number
+ *
+ *  Outputs:      Returns TRUE if successful, FALSE if not
+ *
+ ***************************************************************************/
+BOOL DmaDisableChannel( UINT32 uDMACh )
+{
+   BOOL bSuccess = FALSE;
+
+   /* Make sure the channel number is valid */
+   if ( uDMACh < DMA_CHANNEL_MAX )
+   {
+
+      /* Need to disable DMA interface if applicable */
+      switch (uDMACh)
+      {
+         case DMA_CHANNEL_EMAC1_TX:
+         case DMA_CHANNEL_EMAC1_RX:
+         case DMA_CHANNEL_EMAC2_TX:
+         case DMA_CHANNEL_EMAC2_RX:
+         case DMA_CHANNEL_M2M_IN:
+         case DMA_CHANNEL_M2M_OUT:
+            break;
+
+	#if DSL_DMA
+         case DMA_CHANNEL_DSL_TX:
+            DSL_DMADisable(DMA_CHANNEL_DSL_TX);
+			DSL_ClearStatus(DMA_CHANNEL_DSL_TX);
+            break;
+         case DMA_CHANNEL_DSL_RX:
+            DSL_DMADisable(DMA_CHANNEL_DSL_RX);
+			DSL_ClearStatus(DMA_CHANNEL_DSL_RX);
+            break;
+	#endif
+
+         case DMA_CHANNEL_USB_TX_EP3:
+         case DMA_CHANNEL_USB_TX_EP2:
+         case DMA_CHANNEL_USB_TX_EP1:
+         case DMA_CHANNEL_USB_TX_EP0:
+         case DMA_CHANNEL_USB_RX_EP3:
+         case DMA_CHANNEL_USB_RX_EP2:
+         case DMA_CHANNEL_USB_RX_EP1:
+         case DMA_CHANNEL_USB_RX_EP0:
+            break;
+
+         default:
+            return bSuccess;
+      }
+
+      /* Mark the channel as disabled */
+      DmaChannelTbl[ uDMACh ].bEnabled = FALSE;
+      bSuccess = TRUE;
+   }
+
+   return bSuccess;
+}
+
+BOOL DmaOpenChannel(UINT32 uDMACh)
+{
+   BOOL bSuccess= FALSE;
+
+   /* Make sure the channel number is valid */
+   if ( uDMACh < DMA_CHANNEL_MAX )
+   {
+      /* For now always attempt to enable DMA channel. */
+      /* Return SUCCESS regardless of whether DMA      */
+      /* channel was enabled.                          */
+      DmaEnableChannel(uDMACh);
+
+      /* Mark the channel as open and enabled */
+      DmaChannelTbl[ uDMACh ].bOpen = TRUE;
+
+	  bSuccess= TRUE;
+   }
+
+   return (bSuccess);
+}
+
+/****************************************************************************
+ *
+ *  Name:         BOOL DmaCloseChannel( UINT8 uDMACh )
+ *
+ *  Description:  Closes a DMA channel
+ *
+ *  Inputs:       UINT8 uDMACh = DMA channel number
+ *
+ *  Outputs:      Returns TRUE if successful, FALSE if not
+ *
+ ***************************************************************************/
+BOOL DmaCloseChannel( UINT32 uDMACh )
+{
+   BOOL bSuccess = FALSE;
+
+   /* Make sure the channel number is valid */
+   if ( uDMACh < DMA_CHANNEL_MAX )
+   {
+      bSuccess = DmaDisableChannel(uDMACh);
+
+      /* Mark the channel as closed */
+      if (bSuccess == TRUE)
+         DmaChannelTbl[ uDMACh ].bOpen = FALSE;
+
+   }
+
+   return (bSuccess);
+}
+
+
+/****************************************************************************
+ *
+ *  Name:         BOOL DMASetCallback( UINT8 uDMACh, void ( *pDMACallback )( void ) )
+ *
+ *  Description:  Sets the callback function pointer for DMA interrupts
+ *
+ *  Inputs:       UINT8 uDMACh = DMA channel number
+ *             void ( *pDMACallback )( void ) = callback function pointer
+ *
+ *  Outputs:      Returns TRUE if successful, FALSE if not
+ *
+ ***************************************************************************/
+BOOL DMASetCallback( UINT8 uDMACh, PDMACALLBACK pDMACallback, void* pUserData )
+{
+   BOOL bSuccess;
+
+   /* Make sure the channel number is valid */
+   if ( uDMACh < DMA_CHANNEL_MAX )
+   {
+      /* Store the callback function pointer */
+      DmaChannelTbl[ uDMACh ].pDMACallback = pDMACallback;
+      DmaChannelTbl[ uDMACh ].pUserData = pUserData;
+
+      bSuccess = TRUE;
+   }
+
+   else
+   {
+      bSuccess = FALSE;
+   }
+
+   return bSuccess;
+}
+
+
+EXPORT_SYMBOL(DMASetCallback);
+EXPORT_SYMBOL(DmaOpenChannel);
+EXPORT_SYMBOL(DmaChannelTbl);
+#endif	//if defined (CONFIG_CNXT_ADSL)  ||  defined (CONFIG_CNXT_ADSL_MODULE) || defined (CONFIG_CNXT_GSHDSL) || defined (CONFIG_CNXT_GSHDSL_MODULE)
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/dslbase.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/dslbase.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/dslbase.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/dslbase.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,600 @@
+/****************************************************************************
+ *
+ *  Name:			DSLBASE.C
+ *
+ *  Description:	Basic DSL routines for DMT pump control
+ *
+ *  Copyright:		(c) 2001 - 2003  Conexant Systems Inc.
+ *
+ ****************************************************************************
+ *
+ *  $Author:   belljl  $
+ *  $Revision:   1.3  $
+ *  $Modtime:   Jun 27 2003 18:00:24  $
+ *
+ *
+ ***************************************************************************/
+
+/*---------------------------------------------------------------------------
+ *  Include Files
+ *-------------------------------------------------------------------------*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#if defined (CONFIG_CNXT_ADSL)  ||  defined (CONFIG_CNXT_ADSL_MODULE) || defined (CONFIG_CNXT_GSHDSL) || defined (CONFIG_CNXT_GSHDSL_MODULE)
+#include "bsptypes.h"
+#include "bspcfg.h"
+#include "gpio.h"
+#include "dslbase.h"
+#include "cnxtbsp.h"
+#include "OsTools.h"
+#include "cnxttimer.h"
+#include "cnxtirq.h"
+
+#if defined (CONFIG_CNXT_ADSL)  ||  defined (CONFIG_CNXT_ADSL_MODULE)
+extern void *pFalconContext ;
+extern void ( *pF2_IRQ1_ISR ) ( void * ) ;
+extern void ( *pF2_IRQ2_ISR ) ( void * ) ;
+
+/****************************************************************
+ ****************************************************************/
+
+static BOOL FalconScanEnableCache ;
+void FalconScanEnable ( BOOL State ) 
+{
+	WriteGPIOData ( GPOUT_F2_SCANEN, State ) ;	/* GPIO30 ( P50 ) , GPIO26 ( ZIG ) */
+	FalconScanEnableCache = State ;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+BOOL ReadFalconScanEnable ( void ) 
+{
+	//return ReadGPIOData ( GPOUT_F2_SCANEN ) ;	/* GPIO30 ( P50 ) , GPIO26 ( ZIG ) */
+	return FalconScanEnableCache ;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+/* Showtime in F2 IRQ handlers */
+/* GPIO26 for Pyramid, GPIO19 for Ziggy */
+void SetGPIOF2PInt ( BOOL value ) 
+{
+	//WriteGPIOData ( GPOUT_TXD_LED, ! value ) ;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+/* Showtime in critical section */
+void SetGPIOF2PCS ( BOOL value ) 
+{
+	// GPIO27 for Pyramid, GPIO20 for Ziggy
+	// WriteGPIOData ( GPOUT_RXD_LED, ! value ) ;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+static BOOL LinedriverPowerCache ;
+void LinedriverPower ( BOOL State ) 
+{
+	/* GPIO13 */	
+	WriteGPIOData ( GPOUT_LDRVPWR, State ) ;
+	LinedriverPowerCache = State ;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+BOOL ReadLinedriverPower ( void ) 
+{
+	/* GPIO13 */	
+	// return ReadGPIOData ( GPOUT_LDRVPWR ) ;
+	return LinedriverPowerCache ;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+static BOOL AFEResetCache ;
+void AFEReset ( BOOL State ) 
+{
+	/* GPIO8 */	
+	WriteGPIOData ( GPOUT_AFERESET, ! State ) ;
+	AFEResetCache = State ;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+BOOL ReadAFEReset ( void ) 
+{
+	/* GPIO8 */	
+	//return ! ReadGPIOData ( GPOUT_AFERESET ) ;
+	return AFEResetCache ;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+static BOOL FalconResetCache ;
+void FalconReset ( BOOL State ) 
+{
+	/* GPIO6 ( P46 ) , GPIO9 ( P50 ) */	
+	WriteGPIOData ( GPOUT_F2RESET, State ) ;
+	FalconResetCache = State ;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+BOOL ReadFalconReset ( void ) 
+{
+	/* GPIO6 ( P46 ) , GPIO9 ( P50 ) */	
+	//return ReadGPIOData ( GPOUT_F2RESET ) ;
+	return FalconResetCache ;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+static BOOL FalconPowerDownCache ;
+void FalconPowerDown ( BOOL State ) 
+{
+	/* GPIO0 ( P46 ) , GPIO12 ( P50 ) */
+	WriteGPIOData ( GPOUT_F2PWRDWN, State ) ;
+	FalconPowerDownCache = State ;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+BOOL ReadFalconPowerDown ( void ) 
+{
+	/* GPIO0 ( P46 ) , GPIO12 ( P50 ) */
+	//return ReadGPIOData ( GPOUT_F2PWRDWN ) ;
+	return FalconPowerDownCache ;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+/* Showtime code registers callbacks */
+void SetF2Interrupts ( void ( * ( pIRQ1 ) ) ( void * ) , void ( * ( pIRQ2 ) ) ( void * ) , void *pContext ) 
+{
+	UINT32 OldLevel = 0 ;
+
+	OldLevel = intLock ( ) ;
+
+	pFalconContext = pContext ;
+	if ( pIRQ1 ) 
+	{
+		pF2_IRQ1_ISR = pIRQ1 ;
+
+		GPIO_SetGPIOIRQRoutine ( GPIOINT_F2_IRQ1, GPIOB10_Handler ) ;
+		SetGPIOInputEnable ( GPIOINT_F2_IRQ1, GP_INPUTON ) ;
+
+		SetGPIOIntEnable ( GPIOINT_F2_IRQ1, IRQ_OFF ) ;
+		#ifdef LEVEL_MODE_ADSL
+			SetGPIOIntMode ( GPIOINT_F2_IRQ1, GP_IRQ_MODE_LEVEL ) ;
+		#endif
+		SetGPIOIntPolarity ( GPIOINT_F2_IRQ1, GP_IRQ_POL_NEGATIVE ) ;
+		SetGPIOIntEnable ( GPIOINT_F2_IRQ1, IRQ_ON ) ;
+	}
+	else
+	{
+		SetGPIOIntEnable ( GPIOINT_F2_IRQ1, IRQ_OFF ) ;
+		ClearGPIOIntStatus ( GPIOINT_F2_IRQ1 ) ;
+		pF2_IRQ1_ISR = pIRQ1 ;
+	}
+
+	if ( pIRQ2 ) 
+	{
+		pF2_IRQ2_ISR = pIRQ2 ;
+
+		GPIO_SetGPIOIRQRoutine ( GPIOINT_F2_IRQ2, GPIOB11_Handler ) ;
+		SetGPIOInputEnable ( GPIOINT_F2_IRQ2, GP_INPUTON ) ;
+
+		SetGPIOIntEnable ( GPIOINT_F2_IRQ2, IRQ_OFF ) ;
+		#ifdef LEVEL_MODE_ADSL
+			SetGPIOIntMode ( GPIOINT_F2_IRQ2, GP_IRQ_MODE_LEVEL ) ;
+		#endif
+		SetGPIOIntPolarity ( GPIOINT_F2_IRQ2, GP_IRQ_POL_NEGATIVE ) ;
+		SetGPIOIntEnable ( GPIOINT_F2_IRQ2, IRQ_ON ) ;
+	}
+	else
+	{
+		SetGPIOIntEnable ( GPIOINT_F2_IRQ2, IRQ_OFF ) ;
+		ClearGPIOIntStatus ( GPIOINT_F2_IRQ2 ) ;
+		pF2_IRQ2_ISR = pIRQ2 ;
+	}
+
+	intUnlock ( OldLevel ) ;
+
+}
+
+/****************************************************************
+ ****************************************************************/
+
+#ifndef LEVEL_MODE_ADSL
+	static int oldValue[32] ;
+#endif
+
+static int DisableInterruptCount = 0 ;
+
+/****************************************************************
+ ****************************************************************/
+
+void ADSL_CS_Init ( void ) 
+{
+	DisableInterruptCount = 0 ;
+	pF2_IRQ1_ISR = 0 ;
+	pF2_IRQ2_ISR = 0 ;
+}
+
+/****************************************************************
+ ****************************************************************/
+
+void ADSL_EnableIRQ1_2 ( void ) 
+{
+	register UINT32 temp ;
+
+	if ( pF2_IRQ1_ISR == 0
+	  && pF2_IRQ2_ISR == 0 ) 
+	{
+		return ;
+	}
+
+	temp = intLock ( ) ;
+
+	#ifdef LEVEL_MODE_ADSL
+
+		if ( DisableInterruptCount ) 
+		{
+			DisableInterruptCount-- ;
+		}
+		if ( DisableInterruptCount == 0 ) 
+		{
+			/* Indicate out of critical section for debug */
+			SetGPIOF2PCS ( FALSE ) ;
+
+			if ( pF2_IRQ1_ISR ) 
+			{
+				SetGPIOIntEnable ( GPIOINT_F2_IRQ1, 1 ) ;
+			}
+			if ( pF2_IRQ2_ISR ) 
+			{
+				SetGPIOIntEnable ( GPIOINT_F2_IRQ2, 1 ) ;
+			}
+		}
+
+		intUnlock ( temp ) ;
+
+	#else /* LEVEL_MODE_ADSL */
+
+		if ( DisableInterruptCount == 0 ) 
+		{
+			intUnlock ( temp ) ;
+			return ;
+		}
+
+		DisableInterruptCount -- ;
+		if ( DisableInterruptCount == 0 ) 
+		{
+			/* Indicate out of critical section for debug */
+			SetGPIOF2PCS ( FALSE ) ;
+		}
+
+		/* Allow for nesting, push values onto a stack */
+		intUnlock ( temp ) ;
+		intUnlock ( oldValue[DisableInterruptCount] ) ;
+
+	#endif /* LEVEL_MODE_ADSL */
+}
+
+/****************************************************************
+ ****************************************************************/
+
+void ADSL_DisableIRQ1_2 ( void ) 
+{
+	register UINT32 temp ;
+
+	if ( pF2_IRQ1_ISR == 0 
+	  && pF2_IRQ2_ISR == 0 ) 
+	{
+		return ;
+	}
+
+	temp = intLock ( ) ;
+
+	#ifdef LEVEL_MODE_ADSL
+
+		DisableInterruptCount++ ;
+		if ( pF2_IRQ1_ISR ) 
+		{
+			SetGPIOIntEnable ( GPIOINT_F2_IRQ1, 0 ) ;
+		}
+		if ( pF2_IRQ2_ISR ) 
+		{
+			SetGPIOIntEnable ( GPIOINT_F2_IRQ2, 0 ) ;
+		}
+
+		/* Indicate start of critical section for debug */
+		SetGPIOF2PCS ( TRUE ) ;
+
+		intUnlock ( temp ) ;
+
+	#else /* LEVEL_MODE_ADSL */
+
+		oldValue [DisableInterruptCount] = temp ;
+		if ( DisableInterruptCount == 0 ) 
+		{
+			/* Indicate start of critical section for debug */
+			SetGPIOF2PCS ( TRUE ) ;
+		}
+		DisableInterruptCount++ ;
+
+	#endif /* LEVEL_MODE_ADSL */
+}
+
+
+/****************************************************************
+ ****************************************************************/
+
+void ADSL_EnableIRQ2 ( void ) 
+{
+	register UINT32 temp ;
+
+	if ( pF2_IRQ2_ISR == 0 ) 
+	{
+		return ;
+	}
+
+	temp = intLock ( ) ;
+
+	#ifdef LEVEL_MODE_ADSL
+
+		if ( DisableInterruptCount ) 
+		{
+			DisableInterruptCount-- ;
+		}
+
+		if ( DisableInterruptCount == 0 ) 
+		{
+			/* Indicate out of critical section for debug */
+			SetGPIOF2PCS ( FALSE ) ;
+
+			if ( pF2_IRQ2_ISR ) 
+			{
+				SetGPIOIntEnable ( GPIOINT_F2_IRQ2, 1 ) ;
+			}
+		}
+
+		intUnlock ( temp ) ;
+
+	#else /* LEVEL_MODE_ADSL */
+
+		if ( DisableInterruptCount == 0 ) 
+		{
+			intUnlock ( temp ) ;
+			return ;
+		}
+
+		DisableInterruptCount-- ;
+		if ( DisableInterruptCount == 0 ) 
+		{
+			/* Indicate out of critical section for debug */
+			SetGPIOF2PCS ( FALSE ) ;
+		}
+
+		/* Allow for nesting, push values onto a stack */
+		intUnlock ( temp ) ;
+		intUnlock ( oldValue [DisableInterruptCount] ) ;
+
+	#endif /* LEVEL_MODE_ADSL */
+}
+
+/****************************************************************
+ ****************************************************************/
+
+void ADSL_DisableIRQ2 ( void ) 
+{
+	register UINT32 temp ;
+
+	if ( pF2_IRQ2_ISR == 0 ) 
+	{
+		return ;
+	}
+
+	temp = intLock ( ) ;
+
+	#ifdef LEVEL_MODE_ADSL
+
+		DisableInterruptCount++ ;
+		if ( pF2_IRQ2_ISR ) 
+		{
+			SetGPIOIntEnable ( GPIOINT_F2_IRQ2, 0 ) ;
+		}
+
+		/* Indicate start of critical section for debug */
+		SetGPIOF2PCS ( TRUE ) ;
+
+		intUnlock ( temp ) ;
+
+	#else /* LEVEL_MODE_ADSL */
+
+		oldValue[DisableInterruptCount] = temp ;
+		if ( DisableInterruptCount == 0 ) 
+		{
+			/* Indicate start of critical section for debug */
+			SetGPIOF2PCS ( TRUE ) ;
+		}
+
+		DisableInterruptCount++ ;
+
+	#endif /* LEVEL_MODE_ADSL */
+}
+
+
+/*********************************************************************************
+    Function     : void DpResetWiring ( SYS_WIRING_TYPE wire_pair ) 
+    Description  : This routine will deenergize the relay used for wire switching.
+**********************************************************************************/
+
+void DpResetWiring ( void )	
+{
+	// Outer pair
+	WriteGPIOData ( GPOUT_OUTER_PAIR, 0 ) ;
+
+	// Inner pair
+	WriteGPIOData ( GPOUT_INNER_PAIR, 0 ) ;
+
+	// Short/Long loop switch
+	WriteGPIOData ( GPOUT_SHORTLOOPSW, 1 ) ;
+
+}
+
+
+/*********************************************************************************
+    Function     : void DpSetAFEHybridSelect ( UINT8	 Select_Line, BOOLEAN State ) 
+    Description  : This routine will deenergize the relay used for wire switching.
+**********************************************************************************/
+static BOOL DpSetAFEHybridSelectCache[2] ;
+void DpSetAFEHybridSelect
+( 
+ 	UINT8					  Select_Line, 
+	BOOL					  State
+) 
+{
+	switch ( Select_Line ) 
+	{
+		case 1:
+			WriteGPIOData ( GPOUT_SHORTLOOPSW, State ) ;
+			DpSetAFEHybridSelectCache[Select_Line-1] = State ;
+			break ;
+		case 2:
+			DpSetAFEHybridSelectCache[Select_Line-1] = State ;
+			break ;
+	}
+}
+
+/*********************************************************************************
+    Function     : void DpSetAFEHybridSelect ( UINT8	 Select_Line, BOOLEAN State ) 
+    Description  : This routine will deenergize the relay used for wire switching.
+**********************************************************************************/
+BOOL DpReadAFEHybridSelect
+( 
+ 	UINT8					  Select_Line
+) 
+{
+	BOOL State ;
+
+	switch ( Select_Line ) 
+	{
+		case 1:
+			//State = ReadGPIOData ( GPOUT_SHORTLOOPSW ) ;
+			State = DpSetAFEHybridSelectCache[Select_Line-1] ;
+			break ;
+		case 2:
+			//State = 0 ;
+			State = DpSetAFEHybridSelectCache [Select_Line-1] ;
+			break ;
+		default:
+			State = 0 ;
+	}
+	return State ;
+}
+
+/*********************************************************************************
+    Function     : BOOL DpQueryAnnexPin ( void ) 
+    Description  : This routine reads hardware circuitry to indicate annex mode
+**********************************************************************************/
+BOOL DpQueryAnnexPin ( void ) 
+{
+	#ifdef CONFIG_BD_RUSHMORE
+		BOOL AnnexPinValue ;
+
+		// Set to input then read
+		SetGPIODir ( GPOUT_SHORTLOOPSW, GP_INPUT ) ;
+		AnnexPinValue = ReadGPIOData ( GPOUT_SHORTLOOPSW ) ;
+
+		// Restore to output, write out the same value that was read.
+		SetGPIODir ( GPOUT_SHORTLOOPSW, GP_OUTPUT ) ;
+		WriteGPIOData ( GPOUT_SHORTLOOPSW, AnnexPinValue ) ;
+
+		return AnnexPinValue ;
+	#else
+		return TRUE ;
+	#endif
+}
+
+
+
+/*********************************************************************************
+    Function     : void DpSwitchHookStateEnq ( UINT8	 Select_Line, BOOLEAN State ) 
+    Description  : This routine reads remote off-hook hardware circuitry
+**********************************************************************************/
+BOOL DpSwitchHookStateEnq ( void ) 
+{
+	return ( ReadGPIOData ( GPIN_OH_DET ) ) ;
+}
+
+
+#endif	//if defined ( CONFIG_CNXT_ADSL )  ||  defined ( CONFIG_CNXT_ADSL_MODULE ) 
+
+
+
+/****************************************************************
+ ****************************************************************/
+
+/* DSL Rx */
+void SetDslRxDataInd ( BOOL value ) 
+{
+   #if COMMON_TX_RX_INDICATION
+	   WriteGPIOData ( GPOUT_TXD_LED, ! value ) ;
+   #else
+	   WriteGPIOData ( GPOUT_RXD_LED, ! value ) ;
+   #endif
+}
+
+/****************************************************************
+ ****************************************************************/
+
+/* DSL Tx */
+void SetDslTxDataInd ( BOOL value ) 
+{
+   WriteGPIOData ( GPOUT_TXD_LED, ! value ) ;
+}
+
+
+#if defined (CONFIG_CNXT_ADSL)  ||  defined (CONFIG_CNXT_ADSL_MODULE)
+EXPORT_SYMBOL ( DpResetWiring ) ;
+EXPORT_SYMBOL ( FalconReset ) ;
+EXPORT_SYMBOL ( FalconPowerDown ) ;
+EXPORT_SYMBOL ( SetF2Interrupts ) ;
+EXPORT_SYMBOL ( ADSL_CS_Init ) ;
+EXPORT_SYMBOL ( ADSL_EnableIRQ1_2 ) ;
+EXPORT_SYMBOL ( ADSL_DisableIRQ1_2 ) ;
+EXPORT_SYMBOL ( DpSetAFEHybridSelect ) ;
+EXPORT_SYMBOL ( DpQueryAnnexPin ) ;
+EXPORT_SYMBOL ( DpSwitchHookStateEnq ) ;
+EXPORT_SYMBOL ( FalconScanEnable ) ;
+EXPORT_SYMBOL ( ADSL_DisableIRQ2 ) ;
+EXPORT_SYMBOL ( ADSL_EnableIRQ2 ) ;
+EXPORT_SYMBOL ( AFEReset ) ;
+EXPORT_SYMBOL ( LinedriverPower ) ;
+EXPORT_SYMBOL ( ReadFalconReset ) ;
+EXPORT_SYMBOL ( ReadFalconPowerDown ) ;
+EXPORT_SYMBOL ( ReadFalconScanEnable ) ;
+EXPORT_SYMBOL ( ReadAFEReset ) ;
+EXPORT_SYMBOL ( ReadLinedriverPower ) ;
+EXPORT_SYMBOL ( DpReadAFEHybridSelect ) ;
+#endif	//if defined ( CONFIG_CNXT_ADSL )  ||  defined ( CONFIG_CNXT_ADSL_MODULE ) 
+
+#endif	//if defined ( CONFIG_CNXT_ADSL )  ||  defined ( CONFIG_CNXT_ADSL_MODULE ) || defined (CONFIG_CNXT_GSHDSL) || defined (CONFIG_CNXT_GSHDSL_MODULE)
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/dsl.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/dsl.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/dsl.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/dsl.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,670 @@
+/****************************************************************************
+ *
+ *  Name:			DSL.c
+ *
+ *  Description:	DSL routines
+ *
+ *  Copyright:		(c) 1999 - 2003  Conexant Systems Inc.
+ *
+ ****************************************************************************
+ *
+ *  $Author:   belljl  $
+ *  $Revision:   1.2  $
+ *  $Modtime:   Jun 27 2003 17:48:52  $
+ *
+ *
+ ***************************************************************************/
+
+/*---------------------------------------------------------------------------
+ *  Include Files
+ *-------------------------------------------------------------------------*/
+
+#include	<linux/module.h>
+#if defined (CONFIG_CNXT_ADSL) || defined (CONFIG_CNXT_ADSL_MODULE) || defined (CONFIG_CNXT_GSHDSL) || defined (CONFIG_CNXT_GSHDSL_MODULE)
+#include "bspcfg.h"
+#include "bsptypes.h"
+
+#include "cnxtbsp.h"
+#include "cnxtirq.h"
+#include "dsl.h"
+#include "dmasrv.h"
+#include "dslisr.h"
+#include <asm/arch/dma.h>
+
+extern UINT32 GetRxTimeOutValue(UINT32 usTime);
+extern BOOL sysTimerDelay( UINT32 uMicroSec );
+
+/*---------------------------------------------------------------------------
+ *  Module Function Prototypes
+ *-------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+ *  Module Variable Definitions
+ *-------------------------------------------------------------------------*/
+
+extern EPINFOSTRUCT DSLInfo;
+
+/* DSL local variable definition */
+
+UINT32 DSL_ISR_img;
+UINT32 DSL_IER_img;
+UINT32 DSL_CTRL_img;
+UINT32 DSLPacketSize;
+
+/* all DSL type definition */
+DSL_PACKET_RXBLK Dsl_Packet_Rxblk[DSL_MAX_RX_BUFF];
+
+RXBUFFERSTRUCT DslRxBuffer;
+RXBUFFERSTRUCT DslTxBuffer;
+
+/****************************************************************************
+ *
+ *  Name:			void DSL_init( void )
+ *
+ *  Description:	Initializes the DSL with DSL RX enable
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+
+void DSL_init(void)
+{
+
+	/* Reset the ADSL interface */
+	*pDSL_CTRL = DSLCTR_SRESET;
+	sysTimerDelay(100);  /* 100us */
+	*pDSL_CTRL = 0;
+
+	/* Set IDLE , no operation and no interrupts */
+	DSL_CTRL_img = 0;
+	*pDSL_CTRL = DSL_CTRL_img;
+
+	DSL_IER_img  = 0;
+	*pDSL_IER = DSL_IER_img;
+
+	DSL_ClearStatus(DMA_CHANNEL_DSL_TX);
+	DSL_ClearStatus(DMA_CHANNEL_DSL_RX);
+	return ;
+}
+
+
+void InitDSLTxBuffer(void)
+{
+	register UINT32 i, uBlkNum;
+	register volatile UINT32 * ptr; 	
+
+	/* Init TX DMA link list buffer */
+	ptr = pDSL_DMA_TX_BUFF;
+
+	for( uBlkNum = 0; uBlkNum < DSL_MAX_TX_BUFF; uBlkNum++ )
+	{
+		/* Prefill buffer with pattern */
+		for ( i = 0; i < DSL_DMA_BLOCK_DWORDS; i++ )
+		{
+			*ptr++ = 0x11223344;
+		}
+
+		/* Init Tx buffer link informations to make a circular TX block */
+      /* If last Tx block then points back to the top Tx block */
+		if ( uBlkNum  == (DSL_MAX_TX_BUFF - 1) )
+		{
+	    	*ptr = (UINT32)pDSL_DMA_TX_BUFF;
+		}
+      	/* Else points to next block */
+		else
+		{
+			*ptr = (UINT32) (ptr + 2);
+		}
+		    
+		ptr++;
+
+		/* Init the size of the next block, in QWORDS */
+		*ptr++ = DSL_DMA_BLOCK_QWORDS;
+	}
+
+ 	/* Init DSL TX buffer structure */
+	DslTxBuffer.pdwRxStart = pDSL_DMA_TX_BUFF;
+	DslTxBuffer.pdwRxPtr   = pDSL_DMA_TX_BUFF;
+	DslTxBuffer.pdwRxEnd   = (volatile UINT32 *) ((UINT8 *) pDSL_DMA_TX_BUFF + DSL_TXBUFF_SIZE);
+	DslTxBuffer.pcData     = (volatile UINT8 *)  pDSL_DMA_TX_BUFF;
+	DslTxBuffer.BuffSize   = DSL_TXBUFF_SIZE;
+
+	DSLInfo.pTxHead = DslTxBuffer.pdwRxStart;
+	DSLInfo.pTxTail = DslTxBuffer.pdwRxEnd;
+	DSLInfo.pTxCurr = DslTxBuffer.pdwRxPtr;
+
+	DSLInfo.bTXWA = TRUE;
+
+	DSLInfo.TxTotalPending = 0;
+	DSLInfo.TxPendingInc = 0;
+	DSLInfo.TxUnderrun = 0;
+	DSLInfo.TxIRQCount = 0;
+	DSLInfo.TxRejectCnt = 0;
+	DSLInfo.TxPacket = 0;
+	DSLInfo.bTxSendMode = FALSE;
+	DSLInfo.bTxEnable = TRUE;
+	DSLInfo.TxBufferSize = DslTxBuffer.BuffSize;
+
+   /* Init DSL Tx DMA registers */
+	*DMA5_PTR1 = (UINT32)DslTxBuffer.pdwRxStart;	/* Set start of buffer pointers */
+	*DMA5_CNT1 = DSL_DMA_BLOCK_QWORDS;					/* Fixed TX buffer size to start */
+	*pDSL_TXCC_DMA = 0 ;								   /* TX block size to be sent */
+}
+
+
+void InitDSLRxBuffer(void)
+{
+	register UINT32 i;
+
+	/* And the DSL RX buffer structure */
+	DslRxBuffer.pdwRxStart = pDSL_DMA_RX_BUFF;
+	DslRxBuffer.pdwRxPtr = pDSL_DMA_RX_BUFF;
+   
+	if (DSL_RXBUFF_SIZE > DSL_MAX_RXBUFF_SIZE)
+	{
+		DslRxBuffer.BuffSize = DSL_MAX_RXBUFF_SIZE;
+	}
+	else
+	{
+		DslRxBuffer.BuffSize = DSL_RXBUFF_SIZE;
+	}
+   
+	DslRxBuffer.pdwRxEnd = (volatile UINT32 *) ((UINT8 *) pDSL_DMA_RX_BUFF + DslRxBuffer.BuffSize);
+	DslRxBuffer.pcData   = (volatile UINT8 *) pDSL_DMA_RX_BUFF;
+
+	memset((UINT32 *)DslRxBuffer.pdwRxStart, 0x96, DslRxBuffer.BuffSize);
+
+	for (i = 0; i < (DslRxBuffer.BuffSize/DSL_MAX_PACKET_SIZE); i++)
+	{ 
+ 		Dsl_Packet_Rxblk[i].ptr = DslRxBuffer.pdwRxStart + (DSL_DMA_BLOCK_DWORDS * i) ;
+ 		Dsl_Packet_Rxblk[i].ID = i;
+	}
+
+	DSLInfo.RxOverrun = 0;
+	DSLInfo.RxIRQCount = 0;
+	DSLInfo.RxIRQThresh = 0;
+	DSLInfo.RxTimeOut = 0;
+	DSLInfo.RxPacket = 0;
+	DSLInfo.RxBadPacket = 0;
+	DSLInfo.RxTotalPending = 0;
+	DSLInfo.bRxEnable = TRUE;
+
+	/* Init DSL Rx DMA registers */
+	*DMA6_PTR1 = (UINT32)pDSL_DMA_RX_BUFF;
+	*DMA6_CNT1 = DSL_MAX_RX_BUFF * DSL_DMA_BLOCK_QWORDS;
+	
+	/* Indicated RX block size available to DSL */
+	*pDSL_RXCC_DMA = (DSL_MAX_RX_BUFF) << 16;		
+}
+
+
+/****************************************************************************
+ *
+ *  Name:			BOOL DSLWriteBuffer(volatile UINT32* RxBuff,UINT32 ByteCount)
+ *
+ *  Description:	Buffer DSL with data and enable TX
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		return TRUE if OK
+ *
+ ***************************************************************************/
+
+BOOL DSLWriteBuffer(volatile UINT32* RxBuff,UINT32 ByteCount)
+{
+   register UINT32 i;
+   volatile UINT8 * bpDSLPtr = (volatile UINT8 *)DslTxBuffer.pdwRxPtr;
+   UINT8 * bpRxBuff = (UINT8 *)RxBuff; 
+   register UINT32 DSLTXCurrentPending = 0;
+   register UINT32 DSLTXCurrentPendingInc = 1;
+
+   /* Parms checking */
+   if ( (bpDSLPtr == 0) || (RxBuff == 0) || (ByteCount == 0) )
+      return FALSE;
+
+   DSLTXCurrentPending = (((*pDSL_TXCC_DMA) & 0x0000ff00 ) >> 8);
+
+   /* Check if TX buffer is overflowed */
+	/* Make sure TX buffer is completely empty in the case of single packet mode */
+	if (
+        ((DSLTXCurrentPending + DSLInfo.TxPendingInc + (ByteCount/DSL_MAX_PACKET_SIZE)) > DSL_MAX_TX_BUFF)
+      )
+	{
+   	   return FALSE;
+	}
+
+   /* Error checking related to DSL work around.  Must wait until */
+   /* finish sending before accepting new packets */
+	if ( (DSLInfo.bTXWA == TRUE) && (DSLInfo.bTxSendMode == TRUE) )
+   {
+      return FALSE;
+   }
+
+	/* Turn DSL TX LED on */
+	SetDslTxDataInd(TRUE);
+
+	/* For now we assume there is no packing of 53-bytes ATM cell into 64-bytes */
+	/* USB packet from the host driver.  Thus we will transfer exactly 56 bytes */
+	/* at a time. If this is a full ATM cell then do the quick copy. */
+	if (ByteCount == DSL_MAX_PACKET_SIZE)
+	{
+	  memcpy(DslTxBuffer.pdwRxPtr, RxBuff, ByteCount);
+	}
+	else
+	{
+		ByteCount = DSL_DMA_DATA;
+
+		/*	Prepare data for DSL TX buffer */
+		for (i=0;i<ByteCount;i++)
+		{
+			*bpDSLPtr++ = *bpRxBuff++; 
+
+			if ( !( (i+1) % (DSL_DMA_DATA) ) )
+			{
+				bpDSLPtr += 11;  				/* To next TX block after 3 dummy bytes and LINK fields */
+				if ( bpDSLPtr >= (volatile UINT8 * )DslTxBuffer.pdwRxEnd)
+				{
+					bpDSLPtr = (volatile UINT8 *) DslTxBuffer.pdwRxStart; 
+				}
+				if ( (i+1) < ByteCount )
+				{
+					/* Assume TX buffer are contiguous memory */
+					DSLTXCurrentPendingInc +=1;
+				}
+			}
+		}
+	}
+
+	/* Update next DSL TX pointers */
+	for ( i = 0 ; i < DSLTXCurrentPendingInc ; i++ )
+	{ 
+		/* Get next TX buffer pointer from embedded link list */
+	 	DslTxBuffer.pdwRxPtr = (UINT32 *)(*(DslTxBuffer.pdwRxPtr + DSL_DMA_BLOCK_DWORDS) );
+	} 
+
+   DSLInfo.pTxCurr = DslTxBuffer.pdwRxPtr;
+   
+   DSLInfo.TxPendingInc += DSLTXCurrentPendingInc;
+
+   /* If there is a handle then let hight layer decides when to flush. */
+   if (DmaChannelTbl[DMA_CHANNEL_DSL_TX].pUserData)
+   {
+		/* Only auto-flush if the max packet size is reached. */ 
+		if ( (DSLTXCurrentPending + DSLInfo.TxPendingInc) >= DSL_MAX_TX_BUFF )
+		{
+			DMAFlushChannelBuff(DMA_CHANNEL_DSL_TX);
+		}
+   }
+
+   else
+   {
+      if (DSLInfo.bTXWA)
+      {
+         DMAFlushChannelBuff(DMA_CHANNEL_DSL_TX);
+      }
+   
+      else
+      {
+         DSLInfo.TxTotalPending += DSLTXCurrentPendingInc;
+         *pDSL_TXCC_DMA = DSLTXCurrentPendingInc  ;	/* # of TX block  to be sent */
+      }
+   }
+
+	/* Turn DSL TX LED off */
+	SetDslTxDataInd(FALSE);
+
+   return TRUE;
+}
+
+
+/****************************************************************************
+ *
+ *  Name:			void DSL_DMADisable()
+ *
+ *  Description:	Disable DSL DMA and interrupts.  Interrupts vectors left
+ *					   in place.   
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+
+UINT32 DSL_DMADisable(UINT8 uDMACh)
+{
+   register int OldLevel;
+   register UINT32 bReturn;
+
+   bReturn = FALSE;
+
+   OldLevel = intLock();
+
+   switch (uDMACh)
+   {
+      case DMA_CHANNEL_DSL_TX:
+         DSL_Disable_Int(DMA_CHANNEL_DSL_TX);
+	      /* Clear any pending DMA tranfers */
+	      *pDSL_CTRL_DMA = (DSLCTRDMA_TX_CLRQWCNT | DSLCTRDMA_TX_CLRPEND);
+         bReturn = TRUE;
+         break;
+   
+      case DMA_CHANNEL_DSL_RX:
+         DSL_Disable_Int(DMA_CHANNEL_DSL_RX);
+	      /* Clear any pending DMA tranfers */
+	      *pDSL_CTRL_DMA = (DSLCTRDMA_RX_CLRQWCNT | DSLCTRDMA_RX_CLRPEND);
+         bReturn = TRUE;
+         break;
+
+      default:
+         break;
+   }
+
+   intUnlock(OldLevel); 
+   return (bReturn);
+}
+
+
+/****************************************************************************
+ *
+ *  Name:			void DSL_DMAEnable()
+ *
+ *  Description:	Enable DSL DMA and interrupts.  Interrupts vectors left
+ *					   in place.   
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+
+UINT32 DSL_DMAEnable(UINT8 uDMACh)
+{
+   register UINT32 OldLevel;
+   register UINT32 bReturn;
+
+   bReturn = FALSE;
+
+   OldLevel = intLock();
+
+   switch (uDMACh)
+   {
+      case DMA_CHANNEL_DSL_TX:
+         InitDSLTxBuffer();
+         DSL_Enable_Int(DMA_CHANNEL_DSL_TX);
+         bReturn = TRUE;
+         break;
+   
+      case DMA_CHANNEL_DSL_RX:
+         InitDSLRxBuffer();
+         DSL_Enable_Int(DMA_CHANNEL_DSL_RX);
+         bReturn = TRUE;
+         break;
+
+      default:
+         break;
+   }
+
+   intUnlock(OldLevel); 
+   return (bReturn);
+}
+
+
+void DSL_EnableInterface(UINT8 uDMACh)
+{
+   switch (uDMACh)
+   {
+      case DMA_CHANNEL_DSL_TX:
+         /* Configure TX DSL to start sending */
+         DSL_CTRL_img |= DSLCTR_TXENABLE ;
+         *pDSL_CTRL = DSL_CTRL_img;
+         break;
+   
+      case DMA_CHANNEL_DSL_RX:
+         /* Init DSL control register for normal operation */
+         DSL_CTRL_img |= DSLCTR_RXENABLE | DSLCTR_AIE | DSLCTR_IDLE_INSERT ;  
+         *pDSL_CTRL = DSL_CTRL_img;
+         break;
+
+      default:
+         break;
+   }
+}
+
+
+void DSL_ClearStatus(UINT8 uDMACh)
+{
+	register UINT32 OldLevel;
+
+	/* Disable all DSL related interrupts */
+	OldLevel = intLock(); 
+
+	switch (uDMACh)
+	{
+		case DMA_CHANNEL_DSL_TX:
+			/* clear tx status bits if set */
+			*pDSL_ISR = 0x000040F0;
+			DSL_ISR_img	= *pDSL_ISR;
+
+			/* Clear any pending DMA tranfers */
+			*pDSL_CTRL_DMA = ( DSLCTRDMA_TX_CLRQWCNT | DSLCTRDMA_TX_CLRPEND);
+
+			/* Clear DSL global tx interrupts if set */
+			*((UINT32*)INT_STAT) = (INT_DMA5 | INT_ADSL_ERR);
+			break;
+
+		case DMA_CHANNEL_DSL_RX:
+			/* clear rx status bits if set */
+			*pDSL_ISR = 0x0003800F;
+			DSL_ISR_img	= *pDSL_ISR;
+
+			/* Clear any pending rx DMA tranfers */
+			*pDSL_CTRL_DMA = (DSLCTRDMA_RX_CLRQWCNT | DSLCTRDMA_RX_CLRPEND );
+
+			/* Clear DSL global rx interrupts if set */
+			*((UINT32*)INT_STAT) = (INT_DMA6 | INT_ADSL_ERR);
+			break;
+
+		default:
+			break;
+	}
+				   
+	intUnlock(OldLevel); 
+}
+
+
+/****************************************************************************
+ *
+ *  Name:			void SetDSLInterrupts(void)
+ *
+ *  Description:	Enable DSL RX and interrupts,also TX interrupts 
+ *  call by external task init
+ *  to start DSL RX flow   
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+
+void DSL_Enable_Int(UINT8 uDMACh)
+{
+   register UINT32 OldLevel;
+
+   OldLevel = intLock();
+
+   switch (uDMACh)
+   {
+      case DMA_CHANNEL_DSL_TX:
+         /* Since we are using DSL Tx Underrun to terminate transmission, */
+         /* there is no need to enable INT_DMA5 and DSLINT_TX_PKTXFRDONE  */
+         /* interrupts . */
+         /* Enable DSL TX interrupt */
+         /*DSL_TX_Int(IRQ_ON);*/
+         DSL_TXUnderrun_Int(IRQ_ON);
+         break;
+   
+      case DMA_CHANNEL_DSL_RX:
+		/* Enable DSL RX Packet Done and Overrun interrupts */
+		DSL_RX_Int(IRQ_ON);
+		DSL_RXOverrun_Int(IRQ_ON);
+
+		DSLInitRxTimer();
+
+		DSL_RXTimeout_Int(IRQ_ON);
+
+		/* Setup RX threshold level */
+		DSL_RXThresh_Int(IRQ_ON, 10);
+		break;
+
+      default:
+         break;
+   }
+
+   intUnlock(OldLevel); 
+}
+
+
+void DSL_Disable_Int(UINT8 uDMACh)
+{
+   register UINT32 OldLevel;
+
+   OldLevel = intLock();
+
+   switch (uDMACh)
+   {
+      case DMA_CHANNEL_DSL_TX:
+         DSL_TX_Int(IRQ_OFF);
+         DSL_TXUnderrun_Int(IRQ_OFF);
+         break;
+   
+      case DMA_CHANNEL_DSL_RX:
+         DSL_RXThresh_Int(IRQ_OFF, 0);
+         DSL_RXTimeout_Int(IRQ_OFF);
+         DSL_RX_Int(IRQ_OFF);
+         DSL_RXOverrun_Int(IRQ_OFF);
+         break;
+
+      default:
+         break;
+   }
+
+   intUnlock(OldLevel); 
+}
+
+
+void DSL_TX_Int(UINT8 IntState)
+{
+   if (IntState == IRQ_ON)
+   {
+      DSL_IER_img |= DSLINT_TX_PKTXFRDONE ;
+      *pDSL_IER  = DSL_IER_img;
+   }
+   else
+   {
+      DSL_IER_img &= (~DSLINT_TX_PKTXFRDONE) ;
+      *pDSL_IER  = DSL_IER_img;
+   }
+}
+
+
+void DSL_TXUnderrun_Int(UINT8 IntState)
+{
+   if (IntState == IRQ_ON)
+   {
+      DSL_IER_img |= DSLINT_TX_UNDERRUN ;
+      *pDSL_IER  = DSL_IER_img;
+   }
+   else
+   {
+      DSL_IER_img &= (~DSLINT_TX_UNDERRUN) ;
+      *pDSL_IER  = DSL_IER_img;
+   }
+}
+
+
+void DSL_RXOverrun_Int(UINT8 IntState)
+{
+   if (IntState == IRQ_ON)
+   {
+      DSL_IER_img |= DSLINT_RX_OVERRUN ;
+      *pDSL_IER  = DSL_IER_img;
+   }
+   else
+   {
+      DSL_IER_img &= (~DSLINT_RX_OVERRUN) ;
+      *pDSL_IER  = DSL_IER_img;
+   }
+}
+
+
+void DSL_RX_Int(UINT8 IntState)
+{
+   if (IntState == IRQ_ON)
+   {
+      DSL_IER_img |= DSLINT_RX_PKTXFRDONE ;
+      *pDSL_IER  = DSL_IER_img;
+   }
+   else
+   {
+      DSL_IER_img &= (~DSLINT_RX_PKTXFRDONE) ;
+      *pDSL_IER  = DSL_IER_img;
+   }
+}
+
+void DSLInitRxTimer(void)
+{
+	UINT32 TimerValue;
+
+	/* Setup DSL Receive WATCHDOG timer */
+	UINT32 usTime = 0;
+	TimerValue = 0x0;
+
+	if (HWSTATE.dwADSLDownRate)
+	{
+		/* Convert from Kbits/sec to packet/sec */
+		usTime = (HWSTATE.dwADSLDownRate * 1000)/(8 * 56);
+		
+		/* Convert to time/packet in us unit.  We want time out to be */
+		/* 3 packet-time at a particular line rate. */
+		usTime = (DSL_TIMEOUT_PACKET_TIME * 1000000)/usTime;
+		if (usTime)
+		{
+		    TimerValue = GetRxTimeOutValue(usTime);
+		}
+	}
+
+	*pDSL_RXTIMER = TimerValue;
+}
+
+void DSL_RXTimeout_Int(UINT8 IntState)
+{
+   if (IntState == IRQ_ON)
+   {
+      DSL_IER_img  |= (DSLINT_RX_WATCHDOG);
+      *pDSL_IER  = DSL_IER_img;
+   }
+   else
+   {
+      DSL_IER_img  &= (~DSLINT_RX_WATCHDOG);
+      *pDSL_IER  = DSL_IER_img;
+   }
+}
+
+void DSL_RXThresh_Int(UINT8 IntState, UINT32 ThresholdLevel)
+{
+   if (IntState == IRQ_ON)
+   {
+      *pDSL_RXCC_DMA2 = ThresholdLevel;
+      DSL_IER_img  |= (DSLINT_RX_THRESHOLD);
+      *pDSL_IER  = DSL_IER_img;
+   }
+   else
+   {
+      DSL_IER_img  &= (~DSLINT_RX_THRESHOLD);
+      *pDSL_IER  = DSL_IER_img;
+      *pDSL_RXCC_DMA2 = ThresholdLevel;
+   }
+}
+#endif	//if defined (CONFIG_CNXT_ADSL)  ||  defined (CONFIG_CNXT_ADSL_MODULE) || defined (CONFIG_CNXT_GSHDSL) || defined (CONFIG_CNXT_GSHDSL_MODULE)
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/dslisr.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/dslisr.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/dslisr.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/dslisr.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,369 @@
+/****************************************************************************
+ *
+ *  Name:			DSLISR.c
+ *
+ *  Description:	DSL Interrupt handler routines
+ *
+ *  Copyright:		(c) 2001 - 2003  Conexant Systems Inc.
+ *
+ ****************************************************************************
+ *
+ *  $Author:   belljl  $
+ *  $Revision:   1.2  $
+ *  $Modtime:   Jun 27 2003 18:02:04  $
+ *
+ *	
+ ***************************************************************************/
+
+/*---------------------------------------------------------------------------
+ *  Include Files
+ *-------------------------------------------------------------------------*/
+
+#include <linux/module.h>
+#if defined (CONFIG_CNXT_ADSL)  ||  defined (CONFIG_CNXT_ADSL_MODULE) || defined (CONFIG_CNXT_GSHDSL) || defined (CONFIG_CNXT_GSHDSL_MODULE)
+#include "bspcfg.h"
+#include "bsptypes.h"
+#include "cnxtbsp.h"
+#include "cnxtirq.h"
+#include "dmasrv.h"
+#include "dsl.h"
+#include "dslisr.h"
+#include <asm/arch/dma.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+
+#define DSL_DMA_RX_DEBUG 0
+#define DSL_DMA_TX_DEBUG 0
+
+extern void SetDslRxDataInd(BOOL value);
+extern void SetDslTxDataInd(BOOL value);
+
+EPINFOSTRUCT DSLInfo;
+
+#if DSL_DMA_RX_DEBUG
+UINT32 rxpendtbl[RX_PENDING_ITEM];
+UINT32 rxpendoffset=0;
+#endif
+
+#if DSL_DMA_TX_DEBUG
+/* Check for pointer1  */
+UINT32 Dma5_ptr1=0xffffffff;
+UINT32 Dma5_ptr1_soft=0xffffffff;
+UINT32 Dma5_cnt1=0xffffffff;
+UINT32 Dma5_cnt1_good = 0xffffffff;	
+
+UINT32 Dma5_ptr1_nequal_cnt=0;
+#endif
+
+/***************************************************************************/
+/***************************************************************************/
+void DSL_RX_Handler( void);
+#ifdef USE_RX_TASKLET
+DECLARE_TASKLET( dsl_rx_tasklet, DSL_RX_Handler, 0 );
+#endif
+
+void DSL_RX_Handler( void)
+{
+   register UINT32 PreviousTotalRxPending, NewRxPending;
+   register UINT32 ByteMove;
+
+   DSLInfo.RxIRQCount += 1;
+
+   /* Clear RX packet done status */
+   *pDSL_ISR = DSLINT_RX_PKTXFRDONE;
+
+   /* Turn ADSL RX Data Indication on */
+   SetDslRxDataInd(TRUE);
+
+   /* Calculate number of new pending ATM cells */
+   PreviousTotalRxPending = DSLInfo.RxTotalPending;
+   DSLInfo.RxTotalPending = ((*pDSL_RXCC_DMA & DSL_RX_PENDING_FLD ) >> DSL_RX_PENDING_SHIFT);
+   NewRxPending = DSLInfo.RxTotalPending - PreviousTotalRxPending;
+   DSLInfo.RxPacket += NewRxPending;
+
+   #if DSL_DMA_RX_DEBUG
+   /* write the pending cell to structure for observation */
+   if ( ( rxpendoffset += 1 ) >= RX_PENDING_ITEM )
+      rxpendoffset=0;
+
+   rxpendtbl[rxpendoffset] = NewRxPending;
+   #endif
+
+   if (DmaChannelTbl[DMA_CHANNEL_DSL_RX].pDMACallback != NULL)
+   {
+      ByteMove = 0;
+
+      /* If Timeout has occurred then read out all data from DSL Rx buffer. */
+	   while (DSLInfo.RxTotalPending > ByteMove)
+	   { 
+         if (DmaChannelTbl[DMA_CHANNEL_DSL_RX].pDMACallback( DmaChannelTbl[DMA_CHANNEL_DSL_RX].pUserData,
+                                                             (UINT32 *)DslRxBuffer.pdwRxPtr,
+                                                             56
+                                                           ) )
+         {
+            DSLRxBufferUpdate();
+         }
+         else
+         {
+            goto fini;
+         }
+      }
+   }
+   
+fini:
+   /* Turn ADSL RX Data Indication off */
+   SetDslRxDataInd(FALSE);
+
+}
+
+
+void DSLRxBufferUpdate(void)
+{
+   /* Update next DSL RX pointers */
+   DslRxBuffer.pdwRxPtr += DSL_DMA_BLOCK_DWORDS;
+   if ( DslRxBuffer.pdwRxPtr >= DslRxBuffer.pdwRxEnd ) 	
+      DslRxBuffer.pdwRxPtr= DslRxBuffer.pdwRxStart ;
+
+   /* Decrement Rx total pending */
+   DSLInfo.RxTotalPending -= 1;
+   *pDSL_RXCC_DMA = (UINT32)((DSL_MAX_RX_BUFF) << DSL_RXBUFFSIZE_SHIFT) | (UINT32)1;	
+}
+
+
+/****************************************************************************
+ *
+ *  Name:			void DSL_TX_DMA_ISR( void )
+ *
+ *  Description:	DSL TX DMA interrupt service routine
+ *
+ *  Inputs:			IntStat
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void DSL_TX_DMA_ISR(void )
+{
+    register UINT32 OldLevel; 
+
+	OldLevel=INTLOCK(); 
+
+	DSLInfo.TxIRQCount += 1;
+
+	*pDSL_ISR =  DSLINT_TX_PKTXFRDONE;
+   *((UINT32*)INT_STAT) = Int_DSL_TX_DMA;
+
+	INTUNLOCK(OldLevel);
+}
+
+/****************************************************************************
+ *
+ *  Name:			void DSL_ERR_Handler( void )
+ *
+ *  Description:	DSL error ISR
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+
+void DSL_ERR_Handler( void)
+{
+   /* Check for Over/under run interrupt */
+   register UINT32 IsrStat;		
+   register UINT32 OldLevel; 
+
+   OldLevel=intLock(); 
+
+   IsrStat = (*pDSL_ISR & *pDSL_IER & DSLINT_STATUS_MASK);
+   
+   while (IsrStat)
+   {
+		if ( IsrStat & DSLINT_RX_WATCHDOG )
+		{	
+			/* clear DSL RX TIMEOUT pending interrupt */
+			*pDSL_ISR = DSLINT_RX_WATCHDOG;
+			
+			/* clear global interrupt	*/
+			*((UINT32*)INT_STAT) = Int_DSL;
+
+			DSLInfo.RxTimeOut += 1;
+
+#ifndef USE_RX_TASKLET
+			DSL_RX_Handler();				
+#else
+			tasklet_schedule( &dsl_rx_tasklet );
+#endif
+
+		}
+
+		if ( IsrStat & DSLINT_RX_THRESHOLD )
+		{
+			DSLInfo.RxIRQThresh += 1;
+			
+			/* clear DSL RX TIMEOUT pending interrupt */
+			*pDSL_ISR = DSLINT_RX_THRESHOLD;
+			
+			/* clear global interrupt	*/
+			*((UINT32*)INT_STAT) = Int_DSL;
+
+#ifndef USE_RX_TASKLET
+			DSL_RX_Handler();				
+#else			
+			tasklet_schedule( &dsl_rx_tasklet );
+#endif
+
+		}
+		
+		if ( IsrStat &  DSLINT_TX_PKTXFRDONE )
+		{
+
+			if (DmaChannelTbl[DMA_CHANNEL_DSL_TX].pUserData)
+			{
+				if (DmaChannelTbl[DMA_CHANNEL_DSL_TX].pDMACallback != NULL)
+				{
+			   		//DmaChannelTbl[DMA_CHANNEL_DSL_TX].pDMACallback( DmaChannelTbl[DMA_CHANNEL_DSL_TX].pUserData, 0, 0);
+					printk("DSLINT_TX_PKTFRDONE\n");
+				}
+			}
+		}
+
+		if ( IsrStat &  DSLINT_TX_UNDERRUN )
+		{
+
+			DSL_TX_Underrun_ISR();
+
+			if (DmaChannelTbl[DMA_CHANNEL_DSL_TX].pUserData)
+			{
+				if (DmaChannelTbl[DMA_CHANNEL_DSL_TX].pDMACallback != NULL)
+				{
+			   		DmaChannelTbl[DMA_CHANNEL_DSL_TX].pDMACallback( DmaChannelTbl[DMA_CHANNEL_DSL_TX].pUserData, 0, 0);
+				}
+			}
+		}
+
+		if ( IsrStat &  DSLINT_RX_OVERRUN )
+		{
+			DSL_RX_Overrun_ISR();
+		}
+
+		IsrStat = (*pDSL_ISR & *pDSL_IER & DSLINT_STATUS_MASK);
+	}
+
+	intUnlock(OldLevel);
+}
+
+/****************************************************************************
+ *
+ *  Name:			void DSL_TX_Underrun_ISR( void )
+ *
+ *  Description:	DSL TX underrun ISR
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void DSL_TX_Underrun_ISR( void )
+{
+   UINT32 PacketSent = 0;
+
+   DSLInfo.TxUnderrun += 1;
+
+	*pDSL_ISR =  DSLINT_TX_UNDERRUN;
+	*((UINT32*)INT_STAT) = Int_DSL;
+
+   /* Read current pending TX register */
+   PacketSent = DSLInfo.TxTotalPending - (((*pDSL_TXCC_DMA) & 0x0000ff00 ) >> 8);
+   if (DSLInfo.TxTotalPending >= PacketSent)
+      DSLInfo.TxTotalPending -= PacketSent;
+   DSLInfo.TxPacket += PacketSent ;
+
+   if (DSLInfo.TxTotalPending == 0)
+   {
+      if (DSLInfo.bTxSendMode == TRUE)
+      {
+         #if DSL_DMA_TX_DEBUG
+         /* Check if current HW pointer1 matches SW pointer */
+         if ( *DMA5_PTR1 != (UINT32)DslTxBuffer.pdwRxPtr ) 
+         {
+	         Dma5_ptr1 = *DMA5_PTR1;
+	         Dma5_cnt1 = *DMA5_CNT1;	
+	         Dma5_ptr1_soft = (UINT32)DslTxBuffer.pdwRxPtr;
+	         Dma5_ptr1_nequal_cnt++;
+         }
+         else
+	         Dma5_cnt1_good = *DMA5_CNT1;	
+         #endif
+		 
+         /* This fix the DSL data shift problem */
+         if (DSLInfo.bTXWA)
+         {
+            *DMA5_PTR1 = (UINT32)DslTxBuffer.pdwRxPtr;   /* Set start of buffer pointers */
+            *DMA5_CNT1 = DSL_DMA_BLOCK_QWORDS;		     /* Fixed TX buffer size to start */
+         }
+          
+         DSLInfo.bTxSendMode = FALSE;
+      }
+   }
+}
+
+/****************************************************************************
+ *
+ *  Name:			void DSL_RX_Overrun_ISR(void )
+ *
+ *  Description:	DSL RX overrun ISR
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void DSL_RX_Overrun_ISR( void )
+{
+   DSLInfo.RxOverrun += 1;
+
+   /* Disable DSL receiver */
+   DSL_CTRL_img &= ~(DSLCTR_RXENABLE);  
+   *pDSL_CTRL = DSL_CTRL_img;
+
+   /* Wait for DSL receiver to go into idle state */
+   while ( !(*pDSL_CTRL & DSLCTR_RX_IDLE) );
+
+	/* Clear any pending Rx DMA tranfers */
+	*pDSL_CTRL_DMA = (DSLCTRDMA_RX_CLRQWCNT | DSLCTRDMA_RX_CLRPEND);
+
+   /* Clear Rx overrun interrupt status */
+   *pDSL_ISR =  DSLINT_RX_OVERRUN;
+   *((UINT32*)INT_STAT) = Int_DSL;
+
+   /* clear DSL RX TIMEOUT pending interrupt */
+	*pDSL_ISR = DSLINT_RX_THRESHOLD;
+   
+   /* clear DSL RX TIMEOUT pending interrupt */
+	*pDSL_ISR = DSLINT_RX_WATCHDOG;
+
+   /* clear global interrupt	*/
+   *((UINT32*)INT_STAT) = Int_DSL;
+
+   /* Now DSL receiver is idle, we can reset DMA registers */
+   *DMA6_PTR1 = (UINT32)pDSL_DMA_RX_BUFF;
+   *DMA6_CNT1 = DSL_MAX_RX_BUFF * DSL_DMA_BLOCK_QWORDS;
+   DslRxBuffer.pdwRxPtr=pDSL_DMA_RX_BUFF; 
+   DSLInfo.RxTotalPending = 0;
+
+   /* Reenable DSL receiver */
+   DSL_CTRL_img |= DSLCTR_RXENABLE;  
+   *pDSL_CTRL = DSL_CTRL_img;
+
+   /* Kick start DSL receiver out of idle */
+   DSL_CTRL_img |= DSLCTR_RX_KICK ;  
+   *pDSL_CTRL = DSL_CTRL_img;
+   DSL_CTRL_img &= ~(DSLCTR_RX_KICK) ;
+
+}
+
+
+
+#endif	//if defined (CONFIG_CNXT_ADSL)  ||  defined (CONFIG_CNXT_ADSL_MODULE) || defined (CONFIG_CNXT_GSHDSL) || defined (CONFIG_CNXT_GSHDSL_MODULE)
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/eeprom.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/eeprom.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/eeprom.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/eeprom.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,1072 @@
+/****************************************************************************
+*
+*	Name:			eeprom.c
+*
+*	Description:	EEPROM access routines
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   lewisrc  $
+*  $Revision:   1.1  $
+*  $Modtime:   Jul 16 2003 09:28:12  $
+****************************************************************************/
+
+/*---------------------------------------------------------------------------
+ *  Include Files
+ *-------------------------------------------------------------------------*/
+
+#include <linux/ptrace.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <asm/arch/bspcfg.h>
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/usbdef.h>
+#include "eeprom.h"
+#include "defeepromdata.h"
+#include <asm/arch/OsTools.h>
+#include <asm/arch/cnxttimer.h>
+
+//#include "typedef.h"
+
+/* EEPROM data table containing USB enumeration infos */
+/* Holds all the tables read from the EEPROM */
+UINT8 EEPROMTbl[ EEPROM_TBL_SIZE_DB ];
+
+/* Pointers to tables within EERPOM table */
+UINT8* Dev_Desc_Tbl;			/* Device descriptor data */
+UINT8* Dev_Cfg_Tbl;          /* Device configuration data */
+UINT8* LanguageID_Str_Tbl;	/* Language ID */
+UINT8* Manufacturer_Str_Tbl;	/* Manufacturer string */
+UINT8* Product_Str_Tbl;		/* Product String */
+UINT8* Serial_Str_Tbl;			/* Serial Number String */
+UINT8* Mac_Address_Str_Tbl;  /* Mac Address String */
+
+UINT32 HostSigValue;
+
+
+/*---------------------------------------------------------------------------
+ *  Module Function Prototypes
+ *-------------------------------------------------------------------------*/
+void InitI2CEEPROMIf( void );
+void IssueSTART( void );
+void IssueSTOP( void );
+void IssueACK( void );
+BOOL WaitForACK( void );
+void WriteEEPROMByte( UINT8 uData );
+void WriteEEPROMBit( BOOL bBit );
+UINT8 ReadEEPROMByte( void );
+BOOL ReadEEPROMBit( void );
+
+/****************************************************************************
+ *
+ *  Name:			BOOL ReadEEPROM( UINT8 uSlaveAddr, 
+ *									 UINT8 uWordAddr, 
+ *									 UINT8* pRAMAddr, 
+ *									 UINT16 uBytes )
+ *
+ *  Description:	Reads data from the EEPROM and stores it in RAM
+ *
+ *  Inputs:			UINT8 uSlaveAddr = EEPROM slave address (should be 1010000 for Euphrates)
+ *					UINT8 uWordAddr = Starting address of data in the EEPROM
+ *					UINT8* pRAMAddr = Starting address of where to store the data in RAM
+ *					UINT16 uBytes = Number of bytes to read
+ *
+ *  Outputs:		Returns TRUE if successful, FALSE if not
+ *
+ ***************************************************************************/
+BOOL ReadEEPROM( UINT8 uSlaveAddr, UINT8 uWordAddr, UINT8* pRAMAddr, UINT16 uBytes )
+{
+	BOOL bSuccess;
+
+	/* Assume we fail */
+	bSuccess = FALSE;
+
+	/* according to EEPROM datasheet, slave address must be 1010xxyz, where */
+	/*  x is address on board     */
+	/*  y is page block address   */
+	/*  z is read/write bit       */
+	/*assert( 0xA0 == (uSlaveAddr & 0xF0) );
+	assert( uBytes <= PAGE_BLOCK_BYTES );*/
+
+	/* Init. the GPIO pins used for the serial interface */
+	InitI2CEEPROMIf();
+
+	/* Issue the "START" command */
+	IssueSTART();
+
+	/* Write the device slave address, as a dummy write cycle */
+	WriteEEPROMByte( uSlaveAddr & EEPROM_WRITE );
+
+	/* Wait for the device to ACK */
+	if ( WaitForACK() )
+	{
+		/* Write the starting word address */
+		WriteEEPROMByte( uWordAddr );
+
+		/* Wait for the device to ACK */
+		if ( WaitForACK() )
+		{
+			/* Issue the "START" command for the random read procedure */
+			IssueSTART();
+
+			/* Write the device slave address, for reading this time */
+			WriteEEPROMByte( uSlaveAddr | EEPROM_READ );
+
+			/* Wait for the device to ACK */
+			if ( WaitForACK() )
+			{
+				/* While we haven't read all the desired bytes */
+				while ( uBytes )
+				{
+					/* Read a byte from the EEPROM and store it */
+					*pRAMAddr = ReadEEPROMByte();
+
+					/*  ACK the byte except for the last one */
+					if ( 1 != uBytes )
+						IssueACK();
+
+					/* Update the RAM address and byte counter */
+					++pRAMAddr;
+					--uBytes;
+				}
+
+				/* Tell the EEPROM we're done */
+				IssueSTOP();
+
+				/* Flag a success */
+				bSuccess = TRUE;
+			}
+		}
+	}
+
+	return bSuccess;
+}
+
+/****************************************************************************
+ *
+ *  Name:			BOOL ProgramEEPROM( UINT8 uSlaveAddr, UINT8* pRAMAddr, UINT16 uBytes )
+ *
+ *  Description:	Programs an EEPROM page block.  Page block number is 
+ *					spec'd in the slave address.
+ *
+ *  Inputs:			UINT8 uSlaveAddr = EEPROM slave address (should be 1010111 for Euphrates)
+ *					UINT8* pRAMAddr = Starting address in RAM of where to get the data
+ *					UINT16 uBytes = Number of bytes to write
+ *
+ *  Outputs:		Returns TRUE if successful, FALSE if not
+ *
+ ***************************************************************************/
+BOOL ProgramEEPROM( UINT8 uSlaveAddr, UINT8* pRAMAddr, UINT16 uBytes )
+{
+	BOOL bSuccess;		/* Whether it worked or not */
+	UINT8 uWordAddr;	/* Address of data in the EEPROM page block */
+	UINT8 uPageBytes;	/* Number of bytes in the current page to program */
+
+	bSuccess = TRUE;
+
+	/*assert( uBytes <= PAGE_BLOCK_BYTES );*/
+
+	/* Start from the beginning of the EEPROM */
+	uWordAddr = 0;
+
+	/* While there are bytes to program and there's been no error */
+	while( uBytes && bSuccess )
+	{
+		/* See if there's a full page left to program */
+		if ( uBytes >= 16 )
+		{
+			uPageBytes = 16;
+		}
+
+		else
+		{
+			uPageBytes = uBytes;
+		}
+
+		/* Program a page */
+		bSuccess = WriteEEPROM( uSlaveAddr, uWordAddr, pRAMAddr, uPageBytes );
+
+		/* If the page was programmed correctly... */
+		if ( bSuccess )
+		{
+			/* Update the byte count and addresses */
+			uWordAddr += uPageBytes;
+			pRAMAddr += uPageBytes;
+			uBytes -= uPageBytes;
+
+			/* Delay 15 msec (15000 microsec ) until the EEPROM is ready */
+			sysTimerDelay( WRITE_CYCLE_TIME );
+		}
+	}
+	
+	return bSuccess;
+}
+
+/****************************************************************************
+ *
+ *  Name:			BOOL WriteEEPROM( UINT8 uSlaveAddr, 
+ *									 UINT8 uWordAddr, 
+ *									 UINT8* pRAMAddr, 
+ *									 UINT8 uBytes )
+ *
+ *  Description:	Writes data to the EEPROM from RAM
+ *
+ *  Inputs:			UINT8 uSlaveAddr = EEPROM slave address (should be 1010111 for Euphrates)
+ *					UINT8 uWordAddr = Starting address of data in the EEPROM
+ *					UINT8* pRAMAddr = Starting address in RAM of where to get the data
+ *					UINT8 uBytes = Number of bytes to write
+ *
+ *  Outputs:		Returns TRUE if successful, FALSE if not
+ *
+ ***************************************************************************/
+BOOL WriteEEPROM( UINT8 uSlaveAddr, UINT8 uWordAddr, UINT8* pRAMAddr, UINT8 uBytes )
+{
+	BOOL bSuccess;
+
+	/* Assume we fail */
+	bSuccess = FALSE;
+
+	/* according to EEPROM datasheet, slave address must be 1010xxyz, where */
+	/*  x is address on board */
+	/*  y is page block address */
+	/*  z is read/write bit */
+	/*assert( 0xA0 == (uSlaveAddr & 0xF0) );*/
+
+	/* only allow 16 bytes max since this is limit of page write mode */
+	/*assert( uBytes <= 16 );*/
+
+	/* Init. the GPIO pins used for the serial interface */
+	InitI2CEEPROMIf();
+
+	/* Issue the "START" command */
+	IssueSTART();
+
+	/* Write the device slave address */
+	WriteEEPROMByte( uSlaveAddr & EEPROM_WRITE );
+
+	/* Wait for the device to ACK */
+	if ( WaitForACK() )
+	{
+		/* Write the starting word address */
+		WriteEEPROMByte( uWordAddr );
+
+		/* Wait for the device to ACK */
+		if ( WaitForACK() )
+		{
+			/* While we haven't written all the desired bytes */
+			while ( uBytes )
+			{
+				/* Write a byte to the EEPROM */
+				WriteEEPROMByte( *pRAMAddr );
+
+				/* Wait for the device to ACK */
+				if ( WaitForACK() ==  FALSE )
+				{
+					uBytes=0;	/* force loop exit with bSuccess remaining FALSE */
+				}
+				else
+				{
+				 	/* Update the RAM address and byte counter */
+					++pRAMAddr;
+					--uBytes;
+					bSuccess = TRUE;
+				}
+			}
+			/* Tell the EEPROM we're done */
+			IssueSTOP();
+		}
+	}
+
+	return bSuccess;
+}
+
+/****************************************************************************
+ *
+ *  Name:			void InitEEPROMIf( void )
+ *
+ *  Description:	Initializes the pins used as a serial interface to the EEPROM
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void InitI2CEEPROMIf( void )
+{
+	/* Drive the clock high and make it an output */
+	WriteGPIOData( SCL, 1 );
+	SetGPIODir( SCL, GP_OUTPUT );
+
+   /* This ugly sequence is to make sure that the EEPROM*/
+   /* is forced back to know default state. */
+	/* Issue 7 clk pulses, then IssueSTOP. */
+	sysTimerDelay( SCL_HIGH_TIME );
+	WriteGPIOData ( SCL, 0 );
+	sysTimerDelay( SCL_LOW_TIME );
+	WriteGPIOData( SCL, 1 );
+
+	sysTimerDelay( SCL_HIGH_TIME );
+	WriteGPIOData ( SCL, 0 );
+	sysTimerDelay( SCL_LOW_TIME );
+	WriteGPIOData( SCL, 1 );
+
+	sysTimerDelay( SCL_HIGH_TIME );
+	WriteGPIOData ( SCL, 0 );
+	sysTimerDelay( SCL_LOW_TIME );
+	WriteGPIOData( SCL, 1 );
+
+	sysTimerDelay( SCL_HIGH_TIME );
+	WriteGPIOData ( SCL, 0 );
+	sysTimerDelay( SCL_LOW_TIME );
+	WriteGPIOData( SCL, 1 );
+
+	sysTimerDelay( SCL_HIGH_TIME );
+	WriteGPIOData ( SCL, 0 );
+	sysTimerDelay( SCL_LOW_TIME );
+
+	WriteGPIOData( SCL, 1 );
+	sysTimerDelay( SCL_HIGH_TIME );
+	WriteGPIOData ( SCL, 0 );
+	sysTimerDelay( SCL_LOW_TIME );
+	WriteGPIOData( SCL, 1 );
+
+	sysTimerDelay( SCL_HIGH_TIME );
+	WriteGPIOData ( SCL, 0 );
+	sysTimerDelay( SCL_LOW_TIME );
+	WriteGPIOData( SCL, 1 );
+ 
+	IssueSTOP ();
+
+	/* Make sure the data pin an input for now */
+	SetGPIODir( SDA, GP_INPUT );
+
+	return;
+}
+/****************************************************************************
+ *
+ *  Name:			void IssueSTART( void )
+ *
+ *  Description:	Issue a START command to the EEPROM
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void IssueSTART( void )
+{
+	/* Drive SCL high */
+	WriteGPIOData( SCL, 1 );
+
+	/* Drive SDA high */
+	WriteGPIOData( SDA, 1 );
+	
+	/* Make SDA an output */
+	SetGPIODir( SDA, GP_OUTPUT );
+
+	/* SysTimerDelay for START setup time */
+	sysTimerDelay( START_SETUP_TIME );
+
+	/* Drive SDA low */
+	WriteGPIOData( SDA, 0 );
+
+	/* SysTimer1Delay for START hold time  */
+	sysTimerDelay( START_HOLD_TIME );
+	
+	/* Drive SCL low */
+	WriteGPIOData( SCL, 0 );
+
+	return;
+}
+
+/****************************************************************************
+ *
+ *  Name:			void IssueSTOP( void )
+ *
+ *  Description:	Issue a STOP command to the EEPROM
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void IssueSTOP( void )
+{
+	/* Drive SCL low */
+	WriteGPIOData( SCL, 0 );
+
+	/* Make SDA an output */
+	SetGPIODir( SDA, GP_OUTPUT );
+
+	/* Drive SDA low */
+	WriteGPIOData( SDA, 0 );
+	
+	/* SysTimer1Delay for STOP setup time */
+	sysTimerDelay( STOP_SETUP_TIME );
+
+	/* Drive SCL high */
+	WriteGPIOData( SCL, 1 );
+
+	/* SysTimer1Delay for STOP setup time */
+	sysTimerDelay( STOP_SETUP_TIME );
+
+	/* Drive SDA high */
+	WriteGPIOData( SDA, 1 );
+
+	/* SysTimer1Delay for write cycle time */
+	sysTimerDelay( WRITE_CYCLE_TIME );
+	
+	return;
+}
+
+/****************************************************************************
+ *
+ *  Name:			void IssueACK( void )
+ *
+ *  Description:	Issue an ACK to the EEPROM
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void IssueACK( void )
+{
+	/* Write a 0 out to the EEPROM */
+	WriteEEPROMBit( 0 );
+
+	return;
+}
+
+/****************************************************************************
+ *
+ *  Name:			BOOL WaitForACK( void )
+ *
+ *  Description:	Waits for an ACK from the EEPROM
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		Returns TRUE if ACK received, FALSE if not
+ *
+ ***************************************************************************/
+BOOL WaitForACK( void )
+{
+	BOOL bSuccess;
+
+	/* Read a bit from the EEPROM and check that it's a 0 */
+	if ( !ReadEEPROMBit() )
+	{
+		bSuccess = TRUE;
+	}
+
+	else
+	{
+		bSuccess = FALSE;
+	}
+
+	return bSuccess;
+}
+
+/****************************************************************************
+ *
+ *  Name:			void WriteEEPROMByte( UINT8 uData )
+ *
+ *  Description:	Writes a byte out to the EEPROM
+ *
+ *  Inputs:			UINT8 uData = byte to write
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void WriteEEPROMByte( UINT8 uData )
+{
+	UINT8 uBitCnt;
+
+	for ( uBitCnt = 8; uBitCnt > 0; uBitCnt-- )
+	{
+		/* Data is written MSB first */
+		if ( uData & 0x80 )
+		{
+			WriteEEPROMBit( 1 );
+		}
+
+		else
+		{
+			WriteEEPROMBit( 0 );
+		}
+
+		uData <<= 1;
+	}
+
+	return;
+}
+
+/****************************************************************************
+ *
+ *  Name:			void WriteEEPROMBit( BOOL bBit )
+ *
+ *  Description:	Writes a bit out to the EEPROM
+ *
+ *  Inputs:			BOOL bBit = bit to write
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void WriteEEPROMBit( BOOL bBit )
+{
+	/* SysTimer1Delay 1/2 clock low time */
+	sysTimerDelay( SCL_LOW_TIME_DIVIDEBY2 );
+
+	/* Make SDA an output */
+	SetGPIODir( SDA, GP_OUTPUT );
+
+	/* Drive SDA to the desired bit state */
+	WriteGPIOData( SDA, bBit );
+
+	/* SysTimer1Delay 1/2 clock low time  */
+	sysTimerDelay( SCL_LOW_TIME_DIVIDEBY2 );
+	
+	/* Drive SCL high */
+	WriteGPIOData( SCL, 1 );
+
+	/* SysTimer1Delay clock high time */
+	sysTimerDelay( SCL_HIGH_TIME );
+
+	/* Drive SCL low */
+	WriteGPIOData( SCL, 0 );
+
+	return;
+}
+
+/****************************************************************************
+ *
+ *  Name:			UINT8 ReadEEPROMByte( void )
+ *
+ *  Description:	Reads a byte from the EEPROM
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		Returns UINT8 the byte read
+ *
+ ***************************************************************************/
+UINT8 ReadEEPROMByte( void )
+{
+	UINT8 uData;
+	UINT8 uBitCnt;
+
+	uData = 0;
+
+	for ( uBitCnt = 8; uBitCnt > 0; uBitCnt-- )
+	{
+		/* Data is read MSB first */
+		uData <<= 1;
+
+		/* Read a bit and put it into the byte  */
+		uData |= ReadEEPROMBit();
+	}
+
+	return uData;
+}
+
+/****************************************************************************
+ *
+ *  Name:			BOOL ReadEEPROMBit( void )
+ *
+ *  Description:	Reads a bit from the EEPROM
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		Returns BOOL bit read
+ *
+ ***************************************************************************/
+BOOL ReadEEPROMBit( void )
+{
+	BOOL bBit;
+
+	/* Make SDA an input */
+	SetGPIODir( SDA, GP_INPUT );
+
+	/* SysTimer1Delay clock low time */
+	sysTimerDelay( SCL_LOW_TIME );
+
+	/* Drive SCL high */
+	WriteGPIOData( SCL, 1 );
+
+	/* Wait since this routine used for sensing acknowledge */
+	sysTimerDelay( SCL_HIGH_TIME );
+
+	/* Bit value = SDA state */
+	bBit = ReadGPIOData( SDA );
+
+	/* Drive SCL low */
+	WriteGPIOData( SCL, 0 );
+
+	/* SysTimer1Delay clock high time */
+	/*sysTimerDelay( SCL_HIGH_TIME ); */
+
+	return bBit;
+}
+/****************************************************************************
+ *
+ *  Name:			BOOL EEPROMTest ( void )
+ *
+ *  Description:	Test for verifying writing/reading of EEPROM using GPIOs
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		Returns BOOL write/read success
+ *
+ ***************************************************************************/
+ BOOL EEPROMTest( void )
+{
+	BOOL   bSuccess;
+	UINT8  uSlaveAddr, uWordAddr, uBytes, i;
+	static UINT8 uReadData[NUM_TEST_BYTES];
+	static UINT8 uWriteData[NUM_TEST_BYTES];
+
+	bSuccess = FALSE;
+
+	/********************************
+	 * Write/read to the last addresses so as not to overwrite potential data.
+	 *  EEPROM size is in EEPROM.h and is a byte address.
+	 *******************************/
+
+	/* Use first page - page block number is bit 7 of the slave address, 2K page size */
+	uSlaveAddr = SLAVE_ADDRESS;
+	uWordAddr = EEPROM_ADDRESS - NUM_TEST_BYTES;
+	uBytes = NUM_TEST_BYTES;
+
+	/* initialize write and read buffers   */
+	for (i=0; i<NUM_TEST_BYTES; i++)
+	{
+		uWriteData[i] = 0x55 + i;
+		uReadData[i] = 0;
+	}
+	
+
+	/* Write and read data, then do the same to verify the write was successful */
+	if ( WriteEEPROM( uSlaveAddr, uWordAddr, &uWriteData[0], uBytes ) == TRUE )
+	{
+	 	if ( ReadEEPROM( uSlaveAddr, uWordAddr, &uReadData[0], uBytes ) == TRUE )
+		{
+			/* entire test is successful if gotten to this point.  Assume data matches. */
+		  	bSuccess = TRUE;
+		  	for (i=0; i<NUM_TEST_BYTES; i++)
+			{
+				if (uWriteData[i] != uReadData[i])
+				{
+					bSuccess = FALSE;
+				}
+			}
+		}
+	}
+
+	if ( TRUE == bSuccess )
+	{
+		/* assume second set of write/reads fail */
+		bSuccess = FALSE;
+		/* initialize write and read buffers */
+		for (i=0; i<NUM_TEST_BYTES; i++)
+		{
+			uWriteData[i] = 0xAA + i;
+			uReadData[i] = 0;
+		}
+
+		if ( WriteEEPROM( uSlaveAddr, uWordAddr, &uWriteData[0], uBytes ) == TRUE )
+		{
+		 	if ( ReadEEPROM( uSlaveAddr, uWordAddr, &uReadData[0], uBytes ) == TRUE )
+			{
+				/* entire test is successful if gotten to this point.  Assume data matches. */
+			  	bSuccess = TRUE;
+			  	for (i=0; i<NUM_TEST_BYTES; i++)
+				{
+					if (uWriteData[i] != uReadData[i])
+					{
+						bSuccess = FALSE;
+					}
+				}
+			}
+		}
+	}
+	return bSuccess;
+}
+
+
+ /****************************************************************************
+ *
+ *  Name:			static void InitEEPROM(UINT8* pRomTable)
+ *
+ *  Description:	Programs the EEPROM with the device descriptor and configuration
+ *					tables.
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void InitEEPROM(UINT8* pRomTable)
+{
+	/* Init the tables with default values */
+	CopyDefaultData(pRomTable);
+
+   /* Only attempt to program EEPROM from BSP if not building for production */
+   /* to catch EEPROM corruption problem. */
+   #ifdef EEPROM_WRITE
+	/* Program the EEPROM, if it exists */
+	if ( HWSTATE.bEEPROMState )
+	{
+		ProgramEEPROM( SLAVE_ADDRESS | PAGE_BLOCK_0, pRomTable, PAGE_BLOCK_BYTES );
+		ProgramEEPROM( SLAVE_ADDRESS | PAGE_BLOCK_1, (pRomTable + PAGE_BLOCK_BYTES), ( EEPROM_TBL_SIZE_DB - PAGE_BLOCK_BYTES ) );
+	}
+   #endif
+
+	return;
+}
+
+/****************************************************************************
+ *
+ *  Name:			static void CopyDefaultData(UINT8* pRomTable)
+ *
+ *  Description:	Copies default EEPROM data into the data table
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void CopyDefaultData(UINT8* pRomTable)
+{
+	UINT32 i;
+	UINT8* pDefPtr;
+
+	pDefPtr = ( UINT8* )&DefEEPROMData;
+
+	for ( i = 0; i < EEPROM_TBL_SIZE_DB; i++ )
+	{
+		pRomTable[ i ] = *pDefPtr++;
+	}
+			
+	return;
+}
+
+
+
+void sysSerialCheck( void )
+{
+   CheckSerialNum(EEPROMTbl, Serial_Str_Tbl);
+}
+
+/****************************************************************************
+ *
+ *  Name:			static void CheckSerialNum(UINT8* pRomTable, UINT8* pSerialStrTable)
+ *
+ *  Description:	Checks that the serial number string is valid,
+ *					and generates and saves a random one if not
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void CheckSerialNum(UINT8* pRomTable, UINT8* pSerialStrTable)
+{
+	/* If the serial number is not valid. */
+	if ( !IsSerialNumValid(pSerialStrTable) )
+	{
+		/* Generate a random one and store it in the RAM table. */
+		GenValidSerialNum(pSerialStrTable);
+
+		/* If the EEPROM exists, program it. */
+		if (HWSTATE.bEEPROMState)
+		{
+			/* Program the EEPROM, so we have the same serial number next time. */
+			ProgramEEPROM( SLAVE_ADDRESS | PAGE_BLOCK_0, pRomTable, PAGE_BLOCK_BYTES );
+			ProgramEEPROM( SLAVE_ADDRESS | PAGE_BLOCK_1, (pRomTable + PAGE_BLOCK_BYTES), ( EEPROM_TBL_SIZE_DB - PAGE_BLOCK_BYTES ) );
+		}
+	}
+
+	return;
+}
+
+/****************************************************************************
+ *
+ *  Name:			static BOOL IsSerialNumValid(UINT8* pRomTable, UINT8* pSerialStrTable)
+ *
+ *  Description:	Checks to see if the serial number string is valid
+ *					The string is unicode.  All 0xff's is considered invalid
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		Returns TRUE if the string is valid, FALSE if not
+ *
+ ***************************************************************************/
+BOOL IsSerialNumValid(UINT8* pSerialStrTable)
+{
+	BOOL bValid;		/* Whether the string is valid or not */
+	UINT8 uByteCnt;	/* Number of bytes in the string */
+	UINT8* pStrPtr;	/* Pointer to string bytes */
+
+	bValid = FALSE;
+
+	/* First byte of the serial number string table is the byte count, including 2 byte header. */
+	uByteCnt = *pSerialStrTable - 2;
+	pStrPtr = pSerialStrTable + 2;
+
+	/* Check if all string bytes are 0xff. */
+	while( uByteCnt && !bValid )
+	{
+		if ( *pStrPtr != 0xff )
+		{
+			bValid = TRUE;
+		}
+
+		uByteCnt--;
+		pStrPtr++;
+	}
+
+	return bValid;
+}
+
+/****************************************************************************
+ *
+ *  Name:			static void GenValidSerialNum(UINT8* pSerialStrTable)
+ *
+ *  Description:	
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void GenValidSerialNum(UINT8* pSerialStrTable)
+{
+	UINT8* pStrPtr;		/* Pointer to string bytes */
+	UINT16 uTimerValue;	/* Timer 1 is used to generate a random number */
+
+	/* Hex-to-unicode table for lower 4 characters. */
+	static UINT8 uLowTbl[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5' };
+
+	/* Hex-to-unicode table for higher 4 characters. */
+	static UINT8 uHiTbl[] = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '2', '3', '4', '5', '6' };
+
+	int i;
+
+	/* We will generate a 16-byte string, plus a 2-byte header. */
+	*pSerialStrTable = SERIAL_NUM_STR_LEN;
+	*( pSerialStrTable + 1 ) = DESC_TYPE_STRING;
+
+	pStrPtr = pSerialStrTable + 2;
+
+	/* Init. the string to all 0's. */
+	for ( i = 0; i < ( SERIAL_NUM_STR_LEN - 2 ); i += 2 )
+	{
+		pStrPtr[ i ] = 0;
+		pStrPtr[ i + 1 ] = '0';
+	}
+
+	/* If the EEPROM exists, generate a random serial number.  Otherwise, just go with 0's. */
+	if (HWSTATE.bEEPROMState)
+	{
+		/* Read System timer 1, which was turned on at power-on. */
+		uTimerValue = *(UINT16 *)0x350020;
+
+		/* Each nibble of the 16-bit timer value is used to generate 2 characters of the */
+		/* serial number string. */
+		for ( i = 1; i < ( ( SERIAL_NUM_STR_LEN - 2 ) / 2 ); i += 2 )
+		{
+			pStrPtr[ i ] = uLowTbl[ uTimerValue & 0xf ];
+			pStrPtr[ i + 8 ] = uHiTbl[ uTimerValue & 0xf ];
+
+			uTimerValue >>= 4;
+		}
+	}
+	
+	return;
+}
+
+/****************************************************************************
+ *
+ *  Name:			void InitEEPROMImage( void )
+ *
+ *  Description:	Initializes the device description and configuration
+ *					   tables from EEPROM.  If this fails, it uses default values
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+
+void InitEEPROMImage( void )
+{
+	UINT32* pAddr = 0;
+
+	/* Read device descriptor and configuration information from the EEPROM */
+	if ( ReadEEPROM( SLAVE_ADDRESS | PAGE_BLOCK_0, 0, EEPROMTbl, PAGE_BLOCK_BYTES ) )
+	{
+		HWSTATE.bEEPROMState = TRUE;
+		ReadEEPROM( SLAVE_ADDRESS | PAGE_BLOCK_1, 0, EEPROMTbl + PAGE_BLOCK_BYTES, ( EEPROM_TBL_SIZE_DB - PAGE_BLOCK_BYTES ) );
+	}
+
+   /* EEPROM is not present */
+	else
+	{
+		HWSTATE.bEEPROMState = FALSE;
+	}
+
+	/* If the EEPROM signature is not present, init the EEPROM and tables with default values from code. */
+	if ( *( UINT32* )EEPROMTbl != EEPROM_SIG )
+	{
+		InitEEPROM(EEPROMTbl);
+	}
+
+	/* Init the table pointers */
+	pAddr = ( UINT32* )EEPROMTbl;
+	Dev_Desc_Tbl = &EEPROMTbl[ 0 ] + pAddr[ 1 ];
+	Dev_Cfg_Tbl = &EEPROMTbl[ 0 ] + pAddr[ 2 ];
+	LanguageID_Str_Tbl = &EEPROMTbl[ 0 ] + pAddr[ 3 ];
+	Manufacturer_Str_Tbl = &EEPROMTbl[ 0 ] + pAddr[ 4 ];
+	Product_Str_Tbl = &EEPROMTbl[ 0 ] + pAddr[ 5 ];
+	Serial_Str_Tbl = &EEPROMTbl[ 0 ] + pAddr[ 6 ];
+   Mac_Address_Str_Tbl = &EEPROMTbl[ 0 ] + pAddr[ 7 ];
+
+   /* Build the host signature pattern from CONEXANT_VENDOR_ID and P5X_PRODUCT_ID. */
+   HostSigValue = (UINT32)(*(Dev_Desc_Tbl+11) << 24);
+   HostSigValue |= (UINT32)(*(Dev_Desc_Tbl+10) << 16);
+   HostSigValue |= (UINT32)(*(Dev_Desc_Tbl+9) << 8);
+   HostSigValue |= (UINT32)(*(Dev_Desc_Tbl+8));
+
+   /* Determine whether board is self or bus powered */
+   HWSTATE.HWPowerMode = (UINT32)(*(Dev_Cfg_Tbl+7) & (BUS_POWERED_ATTRIB | SELF_POWERED_ATTRIB));
+   /* Store MAC address to report to host later */
+   HWSTATE.dwMACAddressLow = *((UINT32 *)Mac_Address_Str_Tbl);
+   HWSTATE.dwMACAddressHigh = *((UINT32 *)(Mac_Address_Str_Tbl + 4));
+
+	return;
+}
+
+EXPORT_SYMBOL(ReadEEPROM);
+
+
+/*************************************************************
+ *  Parser data from USBDeviceConfiguration table to
+ *  format understand by USB SANDCORE
+ *  INPUT :     Device Descriptor Table pointer
+ *              Device Configuration Table pointer
+ *              USB Endpoints Info Struct Pointer
+ *              USB General Info struct Pointer
+ *       
+ *  RETURN :    P50 ERR status 
+ *************************************************************/
+
+/****************************************************************************
+ *
+ *  $Log:   S:/Embedded/archives/Linux/BSP_CX821xx/uClinux2.4.6/linux/arch/armnommu/mach-cx821xx/eeprom.c-arc  $
+ * 
+ *    Rev 1.1   Jul 18 2003 15:57:58   lewisrc
+ * changed include of cnxttimer.h to ostimer.h
+ * 
+ *    Rev 1.0   Mar 19 2003 13:21:58   davidsdj
+ * Initial revision.
+ * 
+ * 6     8/12/02 7:27a Richarjc
+ * Added missing include to remove a compiler warning.
+ * 
+ * 5     7/08/02 5:43p Webstejm
+ * Changed references to LnxTools.h to OsTools.h
+ * 
+ * 4     5/28/02 8:49a Richarjc
+ * The dma code needs to be made more modular to support an Epic "dma
+ * module".
+ * 
+ * 3     4/08/02 2:09p Richarjc
+ * Modified to make the Conexant emac driver a loadable module so as to
+ * keep the source code proprietary.
+ * 
+ * 2     2/28/02 8:26a Richarjc
+ * Added Conexant ownership and GPL notices.
+ * 
+ * 1     2/22/02 11:47a Palazzjd
+ * Lineo Beta
+ *  Revision 1.1  2001/12/12 14:26:32  oleks
+ *  OZH: Added Conexant "Golden Gate" support.
+ *
+ * 
+ * 3     10/10/01 4:32p Lewisrc
+ * rename #include of lnxtools.h to LnxTools.h because we now use the
+ * mixed case form because we are now sharing it with Linux Tigris and
+ * that is how it is in that project.
+ * 
+ * 2     8/28/01 2:47p Lewisrc
+ * Merging Hasbani P52 codebase - changing CX82100 type names to generic
+ * CNXT or CX821XX
+ * Swapping Console and Dumb Terminal to console on first UART to match
+ * GoldenGate
+ * Updating kernel compiler from 2.91 to 2.96 to match app compiler
+ * 
+ * renamed include files from p52*.h to cnxt*.h
+ * 
+ * 1     6/13/01 8:56a Richarjc
+ * Initial checkin of the Linux kernel and BSP source code for the Golden
+ * Gate development board based upon the CX82100 Home Networking
+ * Processor.
+ * 
+ *    Rev 1.5   Aug 29 2000 16:30:02   nguyenpa
+ * Use EEPROM_WRITE define to control
+ * whether BSP will write to EEPROM or not.
+ * Default is NO.
+ * 
+ *    Rev 1.4   15 Aug 2000 14:25:28   nguyenpa
+ * For release build no longer attempt to
+ * write to EEPROM.
+ * 
+ *    Rev 1.3   14 Aug 2000 16:19:50   nguyenpa
+ * Port init changes which will force the EEPROM
+ * to known default state at start up.
+ * 
+ *    Rev 1.2   09 Aug 2000 14:37:56   nguyenpa
+ * Changes to DMA API and BM initialization
+ * for HDC.
+ * 
+ *    Rev 1.1   Jul 18 2000 17:01:32   nguyenpa
+ * Add code to read EMAC address from
+ * EEPROM into BSP HW structure.
+ * 
+ *    Rev 1.0   Mar 28 2000 16:15:44   nguyenpa
+ *  
+ * 
+ *    Rev 1.0   28 Feb 2000 17:15:58   blackldk
+ * Bootloader ARM project
+ * 
+ *    Rev 1.2   11 Jan 2000 17:19:02   braun
+ * EEPROM access now functional. Added EEPROM test to
+ * POST code.
+ * 
+ *    Rev 1.1   30 Sep 1999 07:15:34   braun
+ * SysTimerDelay call change only
+ * 
+ *    Rev 1.0   22 Sep 1999 16:58:34   chen2p
+ *  First merge of Host IF, GPIO,Memory, and
+ *  Timer tests.
+ *
+ ***************************************************************************/
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/eeprom.h linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/eeprom.h
--- linux-2.4.29/arch/armnommu/mach-cx821xx/eeprom.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/eeprom.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,144 @@
+/****************************************************************************
+*
+*	Name:			eeprom.h
+*
+*	Description:	EEPROM access routines header file
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:22:08  $
+****************************************************************************/
+
+#ifndef EEPROM_H
+#define EEPROM_H
+
+#define EEPROM_WRITE	0xFE
+#define EEPROM_READ		0x01
+
+#define SDA						   GPIO15
+#define SCL						   GPIO16
+#define NUM_TEST_BYTES			4
+#define EEPROM_ADDRESS			0x100						   /* assume using end of page */
+#define SLAVE_ADDRESS			0xA0						   /* bit 1 is page block number */
+#define PAGE_BLOCK_0			   0
+#define PAGE_BLOCK_1			   2
+#define PAGE_BLOCK_BYTES		256
+#define EEPROM_TBL_SIZE_DB		(2 * PAGE_BLOCK_BYTES)  /* EEPROM USB tables are 2 page blocks */
+#define EEPROM_SIG				( UINT32 )0x55555555		/* Signature, to see if the EEPROM has been programmed */
+
+#ifdef IKOS
+#define START_SETUP_TIME		0
+#define START_HOLD_TIME			0
+#define STOP_SETUP_TIME			0
+#define STOP_HOLD_TIME			0
+#define SCL_HIGH_TIME			0
+#define SCL_LOW_TIME			   0
+#define SCL_LOW_TIME_DIVIDEBY2	0
+#define WRITE_CYCLE_TIME		0
+
+#else
+#define START_SETUP_TIME		5							   /* all are in microseconds */
+#define START_HOLD_TIME			4
+#define STOP_SETUP_TIME			5
+#define STOP_HOLD_TIME			START_SETUP_TIME
+#define SCL_HIGH_TIME			4
+#define SCL_LOW_TIME			   (10-SCL_HIGH_TIME)		/* assume 100 KHz clock frequency */
+#define SCL_LOW_TIME_DIVIDEBY2	(SCL_LOW_TIME >> 1)  /* don't divide by 2 */
+#define WRITE_CYCLE_TIME		15000						   /* cycle time is 15 msec max */
+#endif
+
+
+extern UINT8 EEPROMTbl[ EEPROM_TBL_SIZE_DB ];
+
+/* Pointers to tables within EERPOM table */
+extern UINT8* Dev_Desc_Tbl;			/* Device descriptor data */
+extern UINT8* Dev_Cfg_Tbl;          /* Device configuration data */
+extern UINT8* LanguageID_Str_Tbl;	/* Language ID */
+extern UINT8* Manufacturer_Str_Tbl;	/* Manufacturer string */
+extern UINT8* Product_Str_Tbl;		/* Product String */
+extern UINT8* Serial_Str_Tbl;			/* Serial Number String */
+extern UINT8* Mac_Address_Str_Tbl;  /* Mac Address String */
+
+extern UINT32 HostSigValue;
+
+
+BOOL EEPROMTest( void );
+BOOL ReadEEPROM( UINT8 uSlaveAddr, UINT8 uWordAddr, UINT8* pRAMAddr, UINT16 uBytes );
+BOOL WriteEEPROM( UINT8 uSlaveAddr, UINT8 uWordAddr, UINT8* pRAMAddr, UINT8 uBytes );
+BOOL ProgramEEPROM( UINT8 uSlaveAddr, UINT8* pRAMAddr, UINT16 uBytes );
+
+void InitEEPROM(UINT8* pRomTable);
+void CopyDefaultData(UINT8* pRomTable);
+
+/* Serial Number related functions */
+void CheckSerialNum(UINT8* pRomTable, UINT8* pSerialStrTable);
+BOOL IsSerialNumValid(UINT8* pSerialStrTable);
+void GenValidSerialNum(UINT8* pSerialStrTable);
+
+void InitEEPROMImage( void );
+  #if 0
+  void sysSerialCheck();
+  #endif
+#endif
+
+/****************************************************************************
+ *
+ *  $Log:   S:/Embedded/archives/Linux/BSP_CX821xx/uClinux2.4.6/linux/arch/armnommu/mach-cx821xx/eeprom.h-arc  $
+ * 
+ *    Rev 1.0   Mar 19 2003 13:22:00   davidsdj
+ * Initial revision.
+ * 
+ * 2     2/28/02 8:26a Richarjc
+ * Added Conexant ownership and GPL notices.
+ * 
+ * 1     2/22/02 11:47a Palazzjd
+ * Lineo Beta
+ *  Revision 1.1  2001/12/12 14:26:32  oleks
+ *  OZH: Added Conexant "Golden Gate" support.
+ *
+ * 
+ * 1     6/13/01 8:56a Richarjc
+ * Initial checkin of the Linux kernel and BSP source code for the Golden
+ * Gate development board based upon the CX82100 Home Networking
+ * Processor.
+ * 
+ *    Rev 1.1   Jul 18 2000 17:03:28   nguyenpa
+ * Add code to read EMAC address from
+ * EEPROM into BSP HW structure.
+ * 
+ * 
+ *    Rev 1.0   Mar 28 2000 16:33:18   nguyenpa
+ * Add EEPROM support into BSP.
+ * 
+ *    Rev 1.0   28 Feb 2000 17:16:02   blackldk
+ * Bootloader ARM project
+ * 
+ *    Rev 1.1   11 Jan 2000 17:19:04   braun
+ * EEPROM access now functional. Added EEPROM test to
+ * POST code.
+ * 
+ *    Rev 1.0   22 Sep 1999 16:58:46   chen2p
+ *  First merge of Host IF, GPIO,Memory, and
+ *  Timer tests.
+ *
+ ***************************************************************************/
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/gpio.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/gpio.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/gpio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/gpio.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,1211 @@
+/****************************************************************************
+*
+*	Name:			gpio.c
+*
+*	Description:	This module contains the General Purpose I/O (GPIO) functions.
+*
+*	Copyright:		(c) 2002 - 2003  Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   belljl  $
+*  $Revision:   1.3  $
+*  $Modtime:   Aug 07 2003 11:44:42  $
+****************************************************************************/
+
+/*
+| Module Name:  gpio.c
+| Language:     ARM C
+|
+| Description:  This module is the General Purpose I/O (GPIO) functions.
+|
+|               GPIO pins and register interface have two modes.
+|               The default mode consists of each set of 8 pins being
+|               controlled by an individual GP{X}_IO regiser.
+|
+|        The GPIO register map are:
+|
+|        GP0_IO =  0x00350010
+|        GP1_IO =  0x00350014
+|        GP2_IO =  0x00350018
+|        GP3_IO =  0x0035001C
+|
+|        Bits       Type     Default    Name        Description
+|        [29:28]    RW       0          GP3_ECM     Event Counter Mode for Timer #4:
+|                                                   00 = normal GPIO[22]
+|                                                   01 = posedge event cntr for
+|                                                        GPIO[22] input.
+|                                                   10 = negedge event cntr for
+|                                                        GPIO[22] input.
+|                                                   11 = timer sq-wave output on
+|                                                        GPIO[22].
+|        [27]       RW       0          GP3_ISM     GPIO interrupt sensitivity mode:
+|                                                   0 = active-lo level-sensitive.
+|                                                   1 = negative (hi-to-lo) edge-sensitive
+|                                                   This control bit affects the mode
+|                                                   for all GPIO[25:23] interrupt inputs.
+|        [26]       RW       0          GP3_RFP     A value of 1 enables GPIO[13:7]
+|                                                   to be driven with internal RF
+|                                                   power control signals from CUP.
+|        [25]       RW       0          GP3_MODE    A value of 0 enables the GPIO
+|                                                   register interface in default
+|                                                   mode where each set of 8 pins
+|                                                   are controlled by a GP{x}_IO
+|                                                   register. A value of 1 enables
+|                                                   all 32 GPIO and/or GPOE bits to
+|                                                   be read/write simultaneously.
+|        [24]      RW        0          GP3_I2C     A value of 1 enables GPIO[31:30]
+|                                                   {SDA, SCL} to meet I2C transceiver
+|                                                   electrical requirements.
+|        [23:16]   Wd                   GP{X}_BWE   If this field is equal to 0x00,
+|                                                   then the whole GPIO byte register
+|                                                   operates in normal RW mode. If any
+|                                                   bit is set, then the corresponding
+|                                                   GP_OE and GP_IO bit locations are
+|                                                   enabled for writing. If the bit
+|                                                   write enable is not set, the
+|                                                   corresponding GPIO bits will be
+|                                                   unaffected.
+|        [15:8]    RW        0          GP{x}_OE    A value of 1 enables corresponding
+|                                                   GP_IO bit to be output on the GPIO
+|                                                   pin.
+|        [7:0]     RW        0          GP{x}_IO    Writing provides data for GPIO
+|                                                   output pin drivers. Reading accesses
+|                                                   data directly from input pin buffers.
+|
+|        GPIO =  0x00350010
+|
+|        Bits      Type      Default    Name        Description
+|        [31:0]    RW        0x00000000 GP_IO       Writing provides data for GPIO output
+|                                                   pin drivers. Reading accesses data
+|                                                   directly from input pin buffers.
+|
+|        GPOE = 0x00350014
+|
+|        Bits      Type      Default    Name        Description
+|        [31:0]    RW        0x00000000 GP_OE       A value of 1 enables corresponding GP_IO
+|                                                   bit to be output on the GPIO pin.
+|
+|
+| Included Subprograms:
+|        GPIO_STATUS GPIO_Init(void)
+|        GPIO_STATUS GPIO_Config(GPIO_MODE eMode)
+|        GPIO_STATUS GPIO_32Bit_Write(UINT32 ulData, UINT32 ulOEnable)
+|        UINT32      GPIO_32Bit_Read(UINT32 ulDisableOE)
+|        GPIO_STATUS GPIO_8Bit_Write(volatile UINT32 *pulReg, UINT32 ulData, UINT8 ucOEnable)
+|        UINT8       GPIO_8Bit_Read(volatile UINT32 *pulReg, UINT8 ucDisableOE)
+|        GPIO_STATUS GPIO_Timer4_Event_Counter_Mode (TIMER4_EVENT_COUNTER_MODE eMode)
+|        GPIO_STATUS GPIO_Int_Sensitivity_Mode (GPIO_INT_SENSITIVITY_MODE eMode)
+|        GPIO_STATUS GPIO_RF_Power_Control (RF_POWER_CNTRL_MODE eMode)
+|        GPIO_STATUS GPIO_I2C_Mode (I2C_MODE eMode)
+|
++==========================================================================+
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <asm/arch/bspcfg.h>
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/cnxtirq.h>
+#include <asm/arch/cnxtbsp.h>
+#include <asm/arch/syslib.h>
+
+#ifdef CONFIG_CNXT_WLAN
+#include "../../../drivers/net/wireless/wlan.h"
+#endif
+
+/* Exported Global Variable Declaration */
+
+/* Local Global Variable Declaration */
+
+/* Local Function Prototypes Declaration */
+
+/*
++==========================================================================+
+|                            CONEXANT SYSTEMS                              |
+|                           SUBPROGRAM HEADER                              |
++==========================================================================+
+|
+| Name:         GPIO_Init
+|
+| Description:  This routine initializes the GPIO registers.
+|
+| Parameters:   None.
+|
+| Return:       GPIO_STATUS - GPIO_STATUS_OK.
+|                             GPIO_STATUS_ERROR.
+|
++==========================================================================+
+*/
+GPIO_STATUS GPIO_Init(void)
+{
+	signed int	int_lvl;
+	static unsigned char GpioCallCnt = 0;
+
+#ifdef DEVICE_YELLOWSTONE
+    *p_GRP3_INT_MASK       = 0xFFFF0000;
+    *p_GRP3_OUTPUT_ENABLE  = 0xFFFF0000;
+    *p_GRP3_INPUT_ENABLE   = 0xFFFF0000;
+    *p_GRP3_DATA_OUT       = 0xFFFF0000;
+    *p_GRP3_INT_EVENT_TYPE = 0xFFFF0000;
+    *p_GRP3_INT_ENABLE_POS = 0xFFFF0000;
+    *p_GRP3_INT_ENABLE_NEG = 0xFFFF0000;
+    *p_GRP3_INT_STAT_POS   = 0xFFFF;
+    *p_GRP3_INT_STAT_NEG   = 0xFFFF;
+    *p_GRP3_INT_STAT       = 0xFFFF;
+    *p_GRP3_INT_ASSIGN_A   = 0xFFFF0000;
+    *p_GRP3_INT_ASSIGN_B   = 0xFFFF0000;
+    *p_GRP3_INT_ASSIGN_C   = 0xFFFF0000;
+    *p_GRP3_INT_ASSIGN_D   = 0xFFFF0000;
+
+    *p_GRP2_INT_MASK       = 0xFFFF0000;
+    *p_GRP2_OUTPUT_ENABLE  = 0xFFFF0000;
+    *p_GRP2_INPUT_ENABLE   = 0xFFFF0000;
+    *p_GRP2_DATA_OUT       = 0xFFFF0000;
+    *p_GRP2_INT_EVENT_TYPE = 0xFFFF0000;
+    *p_GRP2_INT_ENABLE_POS = 0xFFFF0000;
+    *p_GRP2_INT_ENABLE_NEG = 0xFFFF0000;
+    *p_GRP2_INT_STAT_POS   = 0xFFFF;
+    *p_GRP2_INT_STAT_NEG   = 0xFFFF;
+    *p_GRP2_INT_STAT       = 0xFFFF;
+    *p_GRP2_INT_ASSIGN_A   = 0xFFFF0000;
+    *p_GRP2_INT_ASSIGN_B   = 0xFFFF0000;
+    *p_GRP2_INT_ASSIGN_C   = 0xFFFF0000;
+    *p_GRP2_INT_ASSIGN_D   = 0xFFFF0000;
+
+    *p_GRP1_INT_MASK       = 0xFFFF0000;
+    *p_GRP1_OUTPUT_ENABLE  = 0xFFFF0000;
+    *p_GRP1_INPUT_ENABLE   = 0xFFFF0000;
+    *p_GRP1_DATA_OUT       = 0xFFFF0000;
+    *p_GRP1_INT_EVENT_TYPE = 0xFFFF0000;
+    *p_GRP1_INT_ENABLE_POS = 0xFFFF0000;
+    *p_GRP1_INT_ENABLE_NEG = 0xFFFF0000;
+    *p_GRP1_INT_STAT_POS   = 0xFFFF;
+    *p_GRP1_INT_STAT_NEG   = 0xFFFF;
+    *p_GRP1_INT_STAT       = 0xFFFF;
+    *p_GRP1_INT_ASSIGN_A   = 0xFFFF0000;
+    *p_GRP1_INT_ASSIGN_B   = 0xFFFF0000;
+    *p_GRP1_INT_ASSIGN_C   = 0xFFFF0000;
+    *p_GRP1_INT_ASSIGN_D   = 0xFFFF0000;
+
+    *p_GRP0_INT_MASK       = 0xFFFF0000;
+    *p_GRP0_OUTPUT_ENABLE  = 0xFFFF0000;
+    *p_GRP0_INPUT_ENABLE   = 0xFFFF0000;
+    *p_GRP0_DATA_OUT       = 0xFFFF0000;
+    *p_GRP0_INT_EVENT_TYPE = 0xFFFF0000;
+    *p_GRP0_INT_ENABLE_POS = 0xFFFF0000;
+    *p_GRP0_INT_ENABLE_NEG = 0xFFFF0000;
+    *p_GRP0_INT_STAT_POS   = 0xFFFF;
+    *p_GRP0_INT_STAT_NEG   = 0xFFFF;
+    *p_GRP0_INT_STAT       = 0xFFFF;
+    *p_GRP0_INT_ASSIGN_A   = 0xFFFF0000;
+    *p_GRP0_INT_ASSIGN_B   = 0xFFFF0000;
+    *p_GRP0_INT_ASSIGN_C   = 0xFFFF0000;
+    *p_GRP0_INT_ASSIGN_D   = 0xFFFF0000;
+
+#else
+   register UINT32 i = 0;
+   UINT32 reset_delay;
+   UINT32 wlan_reset_gpio;
+   UINT32 cpu_type;
+
+   /* Should come from EEPROM in the future */
+   UINT32 uGPIODefaultValue[RUSHMORE_NUM_GPIODEFAULT] =
+   {
+      0x00000000, /*p_GRP0_ISM0: default to level IRQ*/
+      0x00000000, /*p_GRP0_ISM1: default to level IRQ*/
+      0x00000000, /*p_GRP0_ISM2: default to level IRQ*/
+
+      #if defined(CONFIG_CHIP_P52) || defined(CONFIG_CHIP_CX82110)
+           #if CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE
+               0x00000040,	/* GPIO_OPT: Enable all GPIO except GPIO38.  HCS4 (GPIO37 CS for UART1), HCS2 (GPIO34 CS for 8975), HCS1 (GPIO33 CS for UART2) */
+               0x0000ffbf,	/* p_GRP0_OUTPUT_ENABLE */  /* All output for testing except: GPIO14 (used for BOPT) */
+               0x0000bdff,	/* p_GRP1_OUTPUT_ENABLE */  /* GPIO31 (8975 Reset). All output for testing except: GPIO25 (UART1 IRQ), GPIO30 (UART2 IRQ) */
+               0x000000ff,	/* p_GRP2_OUTPUT_ENABLE */  /* All output for testing */
+               0xffff3300,	/* p_GRP0_DATA_OUT */
+               0xfffffff1,	/* p_GRP1_DATA_OUT */
+               0xffff007f,	/* p_GRP2_DATA_OUT */
+          #else
+               0x00000042,	/* GPIO_OPT: Enable all chip selects except GPIO 33 for outer relay */
+               0x00003380,	/* p_GRP0_OUTPUT_ENABLE */
+               0x000084bd,	/* p_GRP1_OUTPUT_ENABLE */	   /* 0x49C GPIO 21 output for inner relay */
+               0x0000007F,	/* p_GRP2_OUTPUT_ENABLE */      /* GPIO38 output */
+               0xffff3040,	/* p_GRP0_DATA_OUT */
+               0xffff049C,	/* p_GRP1_DATA_OUT, 18, 19, and 20 LED OFF */
+               0xffff003F,	/* p_GRP2_DATA_OUT */
+          #endif
+      #endif
+      #ifdef CONFIG_CHIP_CX82100
+	      0x000000c0, /*GPIO_OPT: Enable all chip selects */
+
+	      0x000001e0, /*p_GRP0_OUTPUT_ENABLE */	
+	      0x0000011d, /*p_GRP1_OUTPUT_ENABLE */	
+	      0x00000000, /*p_GRP2_OUTPUT_ENABLE */	
+	      0xffff01e0, /*p_GRP0_DATA_OUT */	
+	      0xffff011c, /*p_GRP1_DATA_OUT */	
+	      0xffff003F, /*p_GRP2_DATA_OUT */
+      #endif
+
+
+		0xffffffff,	/*p_GRP0_INT_STAT */
+		0xffffffff,	/*p_GRP1_INT_STAT */
+		0xffffffff,	/*p_GRP2_INT_STAT */
+		0xffff0000,	/*p_GRP0_INT_MASK */
+		0xffff0000,	/*p_GRP1_INT_MASK */
+        0xffff0000, /*p_GRP2_INT_MASK */
+		0xffff0000,	/*GPIO_IPC1 */
+		0xffff0000,	/*GPIO_IPC2 */
+		0xffff0000,	/*GPIO_IPC3 */
+
+        /*RUSHMORE*/
+		0x00000000,	/*p_GRP0_INPUT_ENABLE */
+		0x00000240,	/*p_GRP1_INPUT_ENABLE */
+		0x00000080,	/*p_GRP2_INPUT_ENABLE */
+
+	};
+
+	volatile UINT32 *pGPIODefaultReg[RUSHMORE_NUM_GPIODEFAULT] =
+	{
+      p_GRP0_ISM0,
+      p_GRP0_ISM1,
+      p_GRP0_ISM2,
+
+      GPIO_OPT,
+      p_GRP0_OUTPUT_ENABLE,
+      p_GRP1_OUTPUT_ENABLE,
+      p_GRP2_OUTPUT_ENABLE,
+      p_GRP0_DATA_OUT,
+      p_GRP1_DATA_OUT,
+      p_GRP2_DATA_OUT,
+      p_GRP0_INT_STAT,
+      p_GRP1_INT_STAT,
+      p_GRP2_INT_STAT,
+      p_GRP0_INT_MASK,
+      p_GRP1_INT_MASK,
+      p_GRP2_INT_MASK,
+      GPIO_IPC1,
+      GPIO_IPC2,
+      GPIO_IPC3,
+
+      /* RUSHMORE GPIO Registers. These are here even if device is not
+	     Rushmore, but in that case, they are not initialized */
+      p_GRP0_INPUT_ENABLE,
+      p_GRP1_INPUT_ENABLE,
+      p_GRP2_INPUT_ENABLE,
+    };
+
+    GpioCallCnt++;
+
+	if (HWSTATE.eDeviceType >= DEVICE_RUSHMORE)
+	{
+		if( GpioCallCnt >=2 )
+		{
+			if( SYS_bDUALEMAC_Support() == TRUE )
+			{
+				int_lvl = intLock ();
+				*GPIO_OPT = 0x00000042;
+				*p_GRP0_DATA_OUT = 0xffff30E0;
+				HWSTATE.p_GRP0_INPUT_ENABLE_Image = *p_GRP0_OUTPUT_ENABLE = 0x000033E0;
+				( void ) intUnlock ( int_lvl );
+			}
+		}
+		else
+		{
+			for (i = 0; i < RUSHMORE_NUM_GPIODEFAULT; i++ )
+			{
+				*pGPIODefaultReg[i] = uGPIODefaultValue[i];
+
+				/* In Rushmore the 3 new GIO_IE register cannot be read. */
+				/* Thus we have keep an image of each to write to them   */
+				/* without overwritten the previous value.               */
+				switch ((UINT32) pGPIODefaultReg[i])
+				{
+					case  (UINT32) p_GRP0_INPUT_ENABLE:
+						HWSTATE.p_GRP0_INPUT_ENABLE_Image = uGPIODefaultValue[i];
+						break;
+
+					case  (UINT32) p_GRP1_INPUT_ENABLE:
+						HWSTATE.p_GRP1_INPUT_ENABLE_Image = uGPIODefaultValue[i];
+						break;
+
+					case  (UINT32) p_GRP2_INPUT_ENABLE:
+						HWSTATE.p_GRP2_INPUT_ENABLE_Image = uGPIODefaultValue[i];
+						break;
+
+					default:
+						break;
+				}
+			}
+		}
+	}
+	else /* eDeviceType < RUSHMORE */
+	{
+		if( GpioCallCnt >=2 )
+		{
+			if( SYS_bDUALEMAC_Support() == TRUE )
+			{
+				int_lvl = intLock ();
+				*GPIO_OPT = 0x00000042 & ( ~0x2 );
+				*p_GRP0_DATA_OUT = 0xffff30E0;
+				*p_GRP0_OUTPUT_ENABLE = 0x000033E0;
+				( void ) intUnlock ( int_lvl );
+			}
+		}
+		else
+		{
+			for (i = 0; i < NUM_OF_GPIODEFAULT; i++)
+			{
+				if ( (UINT32 )GPIO_OPT == pGPIODefaultReg[i] && HWSTATE.eDeviceType != DEVICE_P5200X10)
+					*pGPIODefaultReg[i] = uGPIODefaultValue[i] & ( ~0x2 );
+				else
+					*pGPIODefaultReg[i] = uGPIODefaultValue[i];
+			}
+		}
+	}
+
+	#if defined(BOARD_BRONX_MACKINAC)
+	if ( ( SYS_bADSL_Support() == FALSE ) &&
+		 ( SYS_bGshdsl_Support() == FALSE ) )
+	{
+		/* Set GPIO31 as output port, OE2 */
+		*((UINT32*)0x3500b8) = *((UINT32*)0x3500b8) | 0x80008000;
+
+		/* Out 1 to GPIO31 to reset PCMCIA */
+		*((UINT32*)0x3500d0) = 0xffff841C;
+		for(i=0;i<0x30ffff;i++);
+		/* Out 0 to GPIO31 to release reset */
+		*((UINT32*)0x3500d0) = 0xffff041C;
+		for(i=0;i<0x30ffff;i++);
+	}
+	#endif   /* End of BOARD_BRONX_MACKINAC */
+
+    #ifdef CONFIG_CNXT_WLAN
+
+    // Change per APP. Note Rev. D
+    cpu_type = WLANGetCpuType();
+    if (cpu_type == CX82310_FAMILY)
+    {
+        *p_GRP2_OUTPUT_ENABLE |= BIT(1);    // GPIO33 for WLAN reset
+        *p_GRP1_OUTPUT_ENABLE &= ~BIT(10);
+
+        HWSTATE.p_GRP0_INPUT_ENABLE_Image |= BIT(14);
+        *p_GRP1_INPUT_ENABLE = HWSTATE.p_GRP0_INPUT_ENABLE_Image;
+        HWSTATE.p_GRP1_INPUT_ENABLE_Image |= (BIT(1) | BIT(9) | BIT(10));
+        *p_GRP1_INPUT_ENABLE = HWSTATE.p_GRP1_INPUT_ENABLE_Image;
+
+        wlan_reset_gpio = GPIO33;
+    }
+    else    // CX82110-51 or Cx82100-41
+    {
+        if (cpu_type == CX82110_51_FAMILY)
+        {
+            *GPIO_OPT |= BIT(4);                // GPIO36 set to GPIO
+            *p_GRP2_OUTPUT_ENABLE |= BIT(4);    // GPIO36 for WLAN reset
+            wlan_reset_gpio = GPIO36;
+        }
+
+        if (cpu_type == CX82100_41_FAMILY)
+        {
+            *p_GRP1_OUTPUT_ENABLE |= BIT(1);    // GPIO17 for WLAN reset
+            wlan_reset_gpio = GPIO17;
+        }
+    }
+
+    // Mask GPIO INT if CX-82110-51 or CX82100-41
+    if (cpu_type == CX82110_51_FAMILY || cpu_type == CX82100_41_FAMILY)
+    {
+        *p_GRP1_OUTPUT_ENABLE &= ~BIT(5);       // GPIO21 for WLAN INT (input)
+        *p_GRP1_INT_MASK &= ~BIT(21);           // Disable GPIO21 INT for WLAN
+    }
+    // Reset wireless card
+    if (cpu_type == CX82310_FAMILY || cpu_type == CX82110_51_FAMILY || cpu_type == CX82100_41_FAMILY)
+    {
+        WriteGPIOData(wlan_reset_gpio,1);
+        for(reset_delay=0;reset_delay<0x100000;reset_delay++);
+        WriteGPIOData(wlan_reset_gpio,0);
+        for(reset_delay=0;reset_delay<0x100000;reset_delay++);
+    }
+    #endif // CONFIG_CNXT_WLAN
+
+#endif
+
+   return (GPIO_STATUS_OK);
+}
+
+/****************************************************************************
+ *
+ *  Name:			void SetGPIOUsage( UINT8 uGPIOPin, BOOL bOpt )
+ *
+ *  Description:	Sets the GPIO Usage via the option register
+ *
+ *  Inputs:			UINT8 uGPIOPin = which GPIO
+ *					BOOL bOpt = option
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void SetGPIOUsage( UINT8 uGPIOPin, BOOL bOpt )
+{
+#ifndef DEVICE_YELLOWSTONE
+	/*assert ( (uGPIOPin > 31) && (uGPIOPin < NUM_OF_GPIOS) );*/
+
+	if (uGPIOPin > 31)	/*only GPIOs 32-39 have options available */
+	{
+		if ( 0 == bOpt )
+		{
+			*GPIO_OPT &= ~( 1 << (uGPIOPin - 32));
+		}
+		else
+		{
+			*GPIO_OPT |= ( 1 << (uGPIOPin - 32));
+		}
+	}
+#endif
+}
+
+
+/****************************************************************************
+ *
+ *  Name:			void SetGPIODir( UINT8 uGPIOPin, BOOL bDir )
+ *
+ *  Description:	Sets the GPIO direction
+ *
+ *  Inputs:			UINT8 uGPIOPin = which GPIO
+ *					   BOOL bDir = direction
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void SetGPIODir( UINT8 uGPIOPin, BOOL bDir )
+{
+	UINT32 uBitPos = 0;
+   UINT32 uValue;
+	volatile	UINT32* pGPIOOutPtr = 0;
+	volatile	UINT32* pGPIOInPtr = 0;
+	volatile	UINT32* pImagePtr = 0;
+   UINT32           ByteOffSet = 0;
+
+   if (uGPIOPin < NUM_OF_GPIOS)
+   {
+      ByteOffSet = ((uGPIOPin / NUM_GPIOS_PER_REGISTER) * GRP_REG_OFFSET);
+
+      // Calculate corresponding GPIO Output Enable register.  Use byte pointer addition
+      // to match HW register definitions.
+      pGPIOOutPtr = (volatile UINT32 *) ((volatile UINT8 *)(p_GRP0_OUTPUT_ENABLE) + ByteOffSet);
+
+      if (HWSTATE.eDeviceType >= DEVICE_RUSHMORE)
+      {
+         // Calculate corresponding GPIO Output Enable register.  Use byte pointer addition
+         // to match HW register definitions.
+         pGPIOInPtr = (volatile UINT32 *) ((volatile UINT8 *)(p_GRP0_INPUT_ENABLE) + ByteOffSet);
+
+         pImagePtr = (&HWSTATE.p_GRP0_INPUT_ENABLE_Image) + (uGPIOPin / NUM_GPIOS_PER_REGISTER);
+      }
+
+      // Calculate bit position within the register.
+      uBitPos  = (uGPIOPin % NUM_GPIOS_PER_REGISTER);
+
+      /************************/
+      #ifdef DEVICE_YELLOWSTONE
+      /************************/
+
+      // Upper WORD of register is the write mask to access
+      // the desired bit in the lower WORD of register.
+      // So first set the write mask for the desired bit.
+      uValue =  1 << (uBitPos + 16);
+
+      if ( GP_INPUT == bDir )
+      {
+         // Disable GPIO output driver bit by writing 0 to lower WORD
+         HW_REG_WRITE(pGPIOOutPtr, uValue);
+
+         if (pGPIOInPtr)
+         {
+            // Keep same mask and enable GPIO input receiver bit by writing 1
+            // to lower WORD
+   		   uValue |= (1 << uBitPos);
+            HW_REG_WRITE(pGPIOInPtr, uValue);
+         }
+      }
+
+      else
+      {
+         if (pGPIOInPtr)
+         {
+            // Disable GPIO input receiver bit by writing 0 to lower WORD
+            HW_REG_WRITE(pGPIOInPtr, uValue);
+         }
+
+         // Keep same mask and enable GPIO output driver bit by writing 1
+         // to lower WORD
+  		   uValue |= (1 << uBitPos);
+         HW_REG_WRITE(pGPIOOutPtr, uValue);
+      }
+
+      /************************/
+      #else
+      /************************/
+
+      uValue =  1 << uBitPos;
+
+	   if ( GP_INPUT == bDir )
+	   {
+         // Disable GPIO output driver
+         *pGPIOOutPtr &= ~uValue;
+
+         if (pGPIOInPtr)
+         {
+		#if 0
+            // Enable GPIO input receiver
+            *pGPIOInPtr  |= uValue;
+            // Update SW image of GPIO Input Enable register
+            *pImagePtr    = *pGPIOInPtr;
+		#else
+            // Enable GPIO input receiver
+            // Update SW image of GPIO Input Enable register
+            *pImagePtr  |= uValue;
+
+            // Update GPIO Input Enable register
+            *pGPIOInPtr = *pImagePtr;
+		#endif
+         }
+	   }
+
+	   else
+	   {
+         if (pGPIOInPtr)
+         {
+		#if 0
+            // Disable GPIO input receiver
+            *pGPIOInPtr  &= ~uValue;
+            // Update SW image of GPIO Input Enable register
+            *pImagePtr    = *pGPIOInPtr;
+		#else
+            // Disable GPIO input receiver
+            // Update SW image of GPIO Input Enable register
+            *pImagePtr   &= ~uValue;
+			
+            // Update GPIO Input Enable register
+            *pGPIOInPtr = *pImagePtr;
+		#endif
+         }
+
+         // Enable GPIO output driver
+         *pGPIOOutPtr |= uValue;
+	   }
+      #endif
+   }
+}
+
+
+
+/****************************************************************************
+ *
+ *  Name:			void SetGPIOInputEnable( UINT8 uGPIOPin, BOOL bState )
+ *
+ *  Description:	Sets the GPIO direction
+ *
+ *  Inputs:			UINT8 uGPIOPin = which GPIO
+ *					BOOL bDir = direction
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void SetGPIOInputEnable( UINT8 uGPIOPin, BOOL bState )
+{
+   /* New register in Rushmore and OldFaithful devices to enable input. */
+   UINT32 uBitPos;
+   UINT32 uValue;
+   UINT32 ByteOffSet = 0;
+   volatile	UINT32* pGPIOInPtr;
+   volatile	UINT32* pImagePtr;
+
+   if ( (HWSTATE.eDeviceType >= DEVICE_RUSHMORE) && (uGPIOPin < NUM_OF_GPIOS) )
+   {
+      ByteOffSet = ((uGPIOPin / NUM_GPIOS_PER_REGISTER) * GRP_REG_OFFSET);
+      // Calculate corresponding GPIO Output Enable register.  Use byte pointer addition
+      // to match HW register definitions.
+      pGPIOInPtr = (volatile UINT32 *) ((volatile UINT8 *)(p_GRP0_INPUT_ENABLE) + ByteOffSet);
+      pImagePtr = (&HWSTATE.p_GRP0_INPUT_ENABLE_Image) + (uGPIOPin / NUM_GPIOS_PER_REGISTER);
+
+      // Calculate bit position within the register.
+      uBitPos  = (uGPIOPin % NUM_GPIOS_PER_REGISTER);
+
+      /************************/
+      #ifdef DEVICE_YELLOWSTONE
+      /************************/
+
+      // Upper WORD of register is the write mask to access
+      // the desired bit in the lower WORD of register.
+      // So first set the write mask for the desired bit.
+      uValue =  1 << (uBitPos + 16);
+
+	   if ( GP_INPUTON == bState )
+	   {
+          // Keep same mask and enable GPIO input receiver bit by writing 1
+         // to lower WORD
+         uValue |= (1 << uBitPos);
+         HW_REG_WRITE(pGPIOInPtr, uValue);
+      }
+
+      else
+      {
+         // Disable GPIO input receiver bit by writing 0 to lower WORD
+         uValue &= (~(1 << uBitPos));
+         HW_REG_WRITE(pGPIOInPtr, uValue);
+      }
+
+      /************************/
+      #else
+      /************************/
+
+      uValue =  (1 << uBitPos);
+
+      if ( GP_INPUTON == bState )
+      {
+         *pImagePtr |= uValue;
+      }
+
+      else
+      {
+         *pImagePtr &= ~uValue;
+      }
+
+      *pGPIOInPtr = *pImagePtr;
+
+      #endif
+   }  /*End if DEVICE_RUSHMORE*/
+}
+
+
+/****************************************************************************
+ *
+ *  Name:			void WriteGPIOData( UINT8 uGPIOPin, BOOL bState )
+ *
+ *  Description:	Sets the state of a GPIO output pin
+ *
+ *  Inputs:			UINT8 uGPIOPin = which GPIO
+ *					BOOL bState = pin state
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+
+/* The register bit position setting/resetting.
+ * Note that only mask bit is important since it should "mask"
+ * off setting/resetting of other bits in the register
+ * value to write to register for direction
+ */
+void WriteGPIOData( UINT8 uGPIOPin, BOOL bState )
+{
+   UINT32 uBitPos = 0;
+   UINT32 uValue = 0;
+   UINT32 ByteOffSet = 0;
+   volatile UINT32* pGPIOOutPtr = 0;
+   int    OldLevel = 0;
+
+
+   if (uGPIOPin < NUM_OF_GPIOS)
+   {
+      ByteOffSet = ((uGPIOPin / NUM_GPIOS_PER_REGISTER) * GRP_REG_OFFSET);
+
+      // Calculate corresponding GPIO Output Enable register.  Use byte pointer addition
+      // to match HW register definitions.
+      pGPIOOutPtr = (volatile UINT32 *) ((volatile UINT8 *)(p_GRP0_DATA_OUT) + ByteOffSet);
+
+      // Calculate bit position within the register.
+      uBitPos  = (uGPIOPin % NUM_GPIOS_PER_REGISTER);
+
+      /************************/
+      #ifdef DEVICE_YELLOWSTONE
+      /************************/
+
+      // Upper WORD of register is the write mask to access
+      // the desired bit in the lower WORD of register.
+      // So first set the write mask for the desired bit.
+      uValue =  1 << (uBitPos + 16);
+
+      if ( 0 != bState )
+      {
+         uValue |= (1 << uBitPos);
+      }
+
+      else
+      {
+         uValue &= (~(1 << uBitPos));
+      }
+
+      HW_REG_WRITE(pGPIOOutPtr, uValue);
+
+      /************************/
+      #else
+      /************************/
+
+      /* Set all mask bits and do read-modify-write due to register 2 mask bug */
+      OldLevel = intLock();
+      HW_REG_READ(pGPIOOutPtr, uValue);
+      uValue |= 0xFFFF0000;
+
+      if ( 0 != bState )		/*uValue  0 in lower 16 bits, only check for positive*/
+      {
+         uValue |= (1 << uBitPos);
+      }
+      else
+      {
+         uValue &= ~(1 << uBitPos);
+      }
+
+      HW_REG_WRITE(pGPIOOutPtr, uValue);
+      intUnlock(OldLevel);
+      #endif
+   }
+}
+
+
+/****************************************************************************
+ *
+ *  Name:			BOOL ReadGPIOData( UINT8 uGPIOPin )
+ *
+ *  Description:	Reads a GPIO input pin
+ *
+ *  Inputs:			UINT8 uGPIOPin = which GPIO
+ *
+ *  Outputs:		Returns BOOL pin state
+ *
+ ***************************************************************************/
+BOOL ReadGPIOData( UINT8 uGPIOPin )
+{
+	UINT32 uBitPos = 0;
+	UINT32 uValue = 0;
+	volatile UINT32* pGPIOInPtr = 0;
+	UINT32 ByteOffSet = 0;
+
+	if (uGPIOPin < NUM_OF_GPIOS)
+	{
+		ByteOffSet = ((uGPIOPin / NUM_GPIOS_PER_REGISTER) * GRP_REG_OFFSET);
+
+		// Calculate corresponding GPIO Output Enable register.  Use byte pointer addition
+		// to match HW register definitions.
+		pGPIOInPtr = (volatile UINT32 *) ((volatile UINT8 *)(p_GRP0_DATA_IN) + ByteOffSet);
+
+		// Calculate bit position within the register.
+		uBitPos  = (uGPIOPin % NUM_GPIOS_PER_REGISTER);
+
+		HW_REG_READ(pGPIOInPtr, uValue);
+
+		if( uValue & (1 << uBitPos) )
+		{
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+/****************************************************************************
+ *
+ *  Name:			BOOL ReadGPIOIntStatus( UINT8 uGPIOPin )
+ *
+ *  Description:	Reads a GPIO pin interrupt status bit
+ *
+ *  Inputs:			UINT8 uGPIOPin = which GPIO
+ *
+ *  Outputs:		Returns BOOL interrupt status
+ *
+ ***************************************************************************/
+BOOL ReadGPIOIntStatus( UINT8 uGPIOPin )
+{
+	register UINT32 uBitPos;
+	register volatile UINT32* pGPIOPtr;
+	register BOOL  bIntState = 0;
+
+	if (uGPIOPin < NUM_OF_GPIOS)
+   {
+	   if (uGPIOPin > 31)
+	   {
+		   uBitPos = uGPIOPin - 32;
+		   pGPIOPtr = p_GRP2_INT_STAT;
+	   }
+	   else if (uGPIOPin > 15)
+	   {
+		   uBitPos = uGPIOPin - 16;
+		   pGPIOPtr = p_GRP1_INT_STAT;
+	   }
+	   else
+	   {
+		   uBitPos = uGPIOPin;
+		   pGPIOPtr = p_GRP0_INT_STAT;
+	   }
+
+	   if ( *pGPIOPtr & (1 << uBitPos) )
+	   {
+		   bIntState = 1;
+	   }
+	   else
+	   {
+		   bIntState = 0;
+	   }
+   }
+
+	return bIntState;
+}
+
+/****************************************************************************
+ *
+ *  Name:			void ClearGPIOIntStatus( UINT8 uGPIOPin )
+ *
+ *  Description:	Clears the interrupt associated with the GPIO
+ *
+ *  Inputs:			UINT8 uGPIOPin = which GPIO
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void ClearGPIOIntStatus( UINT8 uGPIOPin )
+{
+	UINT32 uBitPos;
+   UINT32 ByteOffSet; 
+   volatile UINT32* pGPIOStatPtr;
+
+	if (uGPIOPin < NUM_OF_GPIOS)
+   {
+      ByteOffSet = ((uGPIOPin / NUM_GPIOS_PER_REGISTER) * GRP_REG_OFFSET);
+
+      // Calculate corresponding GPIO Output Enable register.  Use byte pointer addition
+      // to match HW register definitions.
+      pGPIOStatPtr = (volatile UINT32 *) ((volatile UINT8 *)(p_GRP0_INT_STAT) + ByteOffSet);
+
+      // Calculate bit position within the register.
+      uBitPos  = (uGPIOPin % NUM_GPIOS_PER_REGISTER);
+
+      HW_REG_WRITE(pGPIOStatPtr, (1 << uBitPos));    /* writing a 1 clears the status */
+   }
+}
+
+/****************************************************************************
+ *
+ *  Name:			void SetGPIOIntPolarity( UINT8 uGPIOPin, BOOL bPolarity )
+ *
+ *  Description:	Sets GPIO interrupt polarity
+ *
+ *  Inputs:			UINT8 uGPIOPin = which GPIO
+ *					BOOL bPolarity = polarity (1 = rising edge,
+ *											   0 = falling edge)
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void SetGPIOIntPolarity( UINT8 uGPIOPin, BOOL bPolarity )
+{
+#ifndef DEVICE_YELLOWSTONE
+
+	register UINT32  uBitPos;
+	register UINT32 uValue;
+	register volatile UINT32* pGPIOPtr;
+    register int OldLevel;
+
+	uValue = 0;
+
+	/*assert ( (uGPIOPin > =0) && (uGPIOPin < NUM_OF_GPIOS) );*/
+
+	if (uGPIOPin > 31)
+	{
+		uBitPos = uGPIOPin - 32;
+		pGPIOPtr = GPIO_IPC3;
+	}
+	else if (uGPIOPin > 15)
+	{
+		uBitPos = uGPIOPin - 16;
+		pGPIOPtr = GPIO_IPC2;
+	}
+	else
+	{
+		uBitPos = uGPIOPin;
+		pGPIOPtr = GPIO_IPC1;
+	}
+
+
+    /* Upper word is the IPC bit mask */
+    /* Lower work is the IPC bit level polarity */
+	/* Set all mask bits and do read-modify-write due to register mask bug */
+    OldLevel = intLock();
+	uValue = *pGPIOPtr | 0xFFFF0000;
+
+	if ( GP_IRQ_POL_POSITIVE ==  bPolarity )	/*uValue  0 in lower 16 bits, only check for positive */
+	{
+		uValue |= (1 << uBitPos);
+	}
+
+   else
+	{
+		uValue &= ~(1 << uBitPos);
+	}
+
+	*pGPIOPtr = uValue;
+    intUnlock(OldLevel);
+#endif
+}
+
+/****************************************************************************
+ *
+ *  Name:			BOOL ReadGPIOIntPolarity( UINT8 uGPIOPin )
+ *
+ *  Description:	Reads a GPIO pin interrupt polarity control bit
+ *
+ *  Inputs:			UINT8 uGPIOPin = which GPIO
+ *
+ *  Outputs:		Returns BOOL polarity control state
+ *
+ ***************************************************************************/
+BOOL ReadGPIOIntPolarity( UINT8 uGPIOPin )
+{
+	register BOOL  bIntState = 0;
+#ifndef DEVICE_YELLOWSTONE
+	register UINT32 uBitPos;
+	register volatile UINT32* pGPIOPtr;
+
+	/*assert ( (uGPIOPin >= 0) && (uGPIOPin < NUM_OF_GPIOS) );*/
+
+	if (uGPIOPin > 31)
+	{
+		uBitPos = uGPIOPin - 32;
+		pGPIOPtr = GPIO_IPC3;
+	}
+	else if (uGPIOPin > 15)
+	{
+		uBitPos = uGPIOPin - 16;
+		pGPIOPtr = GPIO_IPC2;
+	}
+	else
+	{
+		uBitPos = uGPIOPin;
+		pGPIOPtr = GPIO_IPC1;
+	}
+
+    /* Only look at lower 16-bits.  Top 16-bits are function masks */
+	if ( (*pGPIOPtr & 0xFFFF) & (1 << uBitPos) )
+	{
+		bIntState = 1;
+	}
+	else
+	{
+		bIntState = 0;
+	}
+
+#endif
+
+	return bIntState;
+}
+
+
+
+/****************************************************************************
+ *
+ *  Name:			void SetGPIOIntMode( UINT8 uGPIOIntS, BOOL bState )
+ *
+ *  Description:	Enables or disables the particular GPIO interrupt
+ *					   and enables the global interrupt if necessary
+ *
+ *  Inputs:			UINT8 uGPIOPin = which GPIO
+ *					   BOOL bState = pin state
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void SetGPIOIntMode( UINT8 uGPIOPin, BOOL bPolarity )
+{
+#ifndef DEVICE_YELLOWSTONE
+   UINT32 uBitPos;
+   UINT32 ByteOffSet; 
+   UINT32 uValue = 0;
+   volatile UINT32* pGPIOIntModePtr;
+   register int OldLevel;
+
+   if (uGPIOPin<NUM_OF_GPIOS)
+   {
+      ByteOffSet = ((uGPIOPin / NUM_GPIOS_PER_REGISTER) * GRP_REG_OFFSET);
+
+      // Calculate corresponding GPIO Output Enable register.  Use byte pointer addition
+      // to match HW register definitions.
+      pGPIOIntModePtr = (volatile UINT32 *) ((volatile UINT8 *)(p_GRP0_ISM0) + ByteOffSet);
+
+      // Calculate bit position within the register.
+      uBitPos  = (uGPIOPin % NUM_GPIOS_PER_REGISTER);
+
+      /* Upper word is the IER bit mask */
+      /* Lower work is the IER bit enable */
+	   /* Set all mask bits and do read-modify-write due to register mask bug */
+      OldLevel = intLock();
+
+      HW_REG_READ(pGPIOIntModePtr, uValue);
+      uValue |= 0xFFFF0000;
+
+      if ( 0 != bPolarity  )
+      {
+         uValue |= (1 << uBitPos);
+      }
+
+      else
+      {
+         uValue &= ~(1 << uBitPos);
+      }
+
+      HW_REG_WRITE(pGPIOIntModePtr, uValue);
+      intUnlock(OldLevel);
+   }
+#endif
+}
+
+
+/****************************************************************************
+ *
+ *  Name:			void SetGPIOIntEnable( UINT8 uGPIOIntE, BOOL bState )
+ *
+ *  Description:	Enables or disables the particular GPIO interrupt
+ *					and enables the global interrupt if necessary
+ *
+ *  Inputs:			UINT8 uGPIOPin = which GPIO
+ *					BOOL bState = pin state
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void SetGPIOIntEnable( UINT8 uGPIOPin, BOOL bState )
+{
+#ifndef DEVICE_YELLOWSTONE
+   UINT32 uBitPos;
+   UINT32 ByteOffSet; 
+   UINT32 uValue = 0;
+   volatile UINT32* pGPIOIntMaskPtr;
+   register int OldLevel;
+
+	if (uGPIOPin < NUM_OF_GPIOS)
+   {
+      ByteOffSet = ((uGPIOPin / NUM_GPIOS_PER_REGISTER) * GRP_REG_OFFSET);
+
+      // Calculate corresponding GPIO Output Enable register.  Use byte pointer addition
+      // to match HW register definitions.
+      pGPIOIntMaskPtr = (volatile UINT32 *) ((volatile UINT8 *)(p_GRP0_INT_MASK) + ByteOffSet);
+
+      // Calculate bit position within the register.
+      uBitPos  = (uGPIOPin % NUM_GPIOS_PER_REGISTER);
+
+      /* Upper word is the IER bit mask */
+      /* Lower work is the IER bit enable */
+
+      /*************************/
+      #ifdef DEVICE_YELLOWSTONE
+      /*************************/
+
+      uValue =  1 << (uBitPos + 16);
+
+	   if ( IRQ_ON == bState  )
+	   {
+		   uValue |= (1 << uBitPos);
+	   }
+
+      else
+	   {
+		   uValue &= (~(1 << uBitPos));
+	   }
+
+      HW_REG_WRITE(pGPIOIntMaskPtr, uValue);
+
+      /*************************/
+      #else
+      /*************************/
+
+	   /* Set all mask bits and do read-modify-write due to register mask bug */
+      OldLevel = intLock();
+      HW_REG_READ(pGPIOIntMaskPtr, uValue);
+      uValue |= 0xFFFF0000;
+
+      if ( IRQ_ON == bState  )
+      {
+         uValue |= (1 << uBitPos);
+      }
+
+      else
+      {
+         uValue &= (~(1 << uBitPos));
+      }
+
+      /* Before enabling the interrupt, must clear the status to not get initial interrupt */
+      ClearGPIOIntStatus ( uGPIOPin );
+
+      HW_REG_WRITE(pGPIOIntMaskPtr, uValue);
+
+      intUnlock(OldLevel);
+      #endif
+
+   }
+#endif
+}
+
+
+/****************************************************************************
+ *
+ *  Name:			BOOL ReadGPIOIntEnable( UINT8 uGPIOPin )
+ *
+ *  Description:	Reads a GPIO pin interrupt status bit
+ *
+ *  Inputs:			UINT8 uGPIOPin = which GPIO
+ *
+ *  Outputs:		Returns BOOL interrupt status
+ *
+ ***************************************************************************/
+BOOL ReadGPIOIntEnable( UINT8 uGPIOPin )
+{
+   UINT32 Value = 0;
+   UINT32 uBitPos;
+   UINT32 ByteOffSet; 
+   volatile UINT32* pGPIOIntMaskPtr;
+
+   if (uGPIOPin < NUM_OF_GPIOS)
+   {
+      ByteOffSet = ((uGPIOPin / NUM_GPIOS_PER_REGISTER) * GRP_REG_OFFSET);
+
+      // Calculate corresponding GPIO Output Enable register.  Use byte pointer addition
+      // to match HW register definitions.
+      pGPIOIntMaskPtr = (volatile UINT32 *) ((volatile UINT8 *)(p_GRP0_INT_MASK) + ByteOffSet);
+
+      // Calculate bit position within the register.
+      uBitPos  = (uGPIOPin % NUM_GPIOS_PER_REGISTER);
+
+      HW_REG_READ(pGPIOIntMaskPtr, Value);
+
+      Value &= (1 << uBitPos);
+   }
+
+   return (Value);  
+}
+
+EXPORT_SYMBOL(SetGPIODir);
+EXPORT_SYMBOL(SetGPIOUsage);
+EXPORT_SYMBOL(WriteGPIOData);
+EXPORT_SYMBOL(ReadGPIOData);
+EXPORT_SYMBOL(ReadGPIOIntStatus);
+EXPORT_SYMBOL(ClearGPIOIntStatus);
+EXPORT_SYMBOL(SetGPIOIntPolarity);
+EXPORT_SYMBOL(ReadGPIOIntPolarity);
+EXPORT_SYMBOL(SetGPIOIntMode);
+EXPORT_SYMBOL(SetGPIOIntEnable);
+EXPORT_SYMBOL(SetGPIOInputEnable);
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/gpioisr.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/gpioisr.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/gpioisr.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/gpioisr.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,324 @@
+/****************************************************************************
+*
+*	Name:			gpioisr.c
+*
+*	Description:	This module contains the GPIO interrupt handling functions.
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author: shell $
+*  $Revision: 1.3 $
+*  $Modtime:   Jun 30 2003 15:25:18  $
+****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/bspcfg.h>
+#include <asm/arch/syslib.h>
+#include <asm/arch/cnxtbsp.h>
+#include <asm/arch/cnxtirq.h>
+#include <asm/arch/OsTools.h>
+#include <asm/arch/gpio.h>
+
+
+#if CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE
+    void (*pHostPort_ISR)(void *) = 0;
+	void *pHostPortContext;
+#elif CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+    void (*pF2_IRQ1_ISR)(void *)= 0;
+    void (*pF2_IRQ2_ISR)(void *)= 0;
+	void *pFalconContext ;
+#endif
+
+
+/*
+** GPIOISRxHandler_Tbl contains hooks for applications that want to
+** to do the entire interrupt for the given GPIO.  These routines
+** must execute ClearGPIOIntStatus(GpioNumber) at the end.
+*/
+static void (*GPIOISR1Handler_Tbl[16])(int) = {0};
+static void (*GPIOISR2Handler_Tbl[16])(int) = {0};
+static void (*GPIOISR3Handler_Tbl[8])(int) = {0};
+
+/*
+** GPIO_SetGPIOIRQCallback is the usual callback. Applications
+** need not know about GPIOs.
+*/
+static void ((*(pGPIO_ISR)[NUM_OF_GPIOS])(int)) = {0};
+
+/*
+** Set the usual callback.  DMT datapump uses this function.
+*/
+void GPIO_SetGPIOIRQCallback(int gpio,void (*(pISR))(int))
+{
+	if (gpio >= 0 && gpio < NUM_OF_GPIOS)
+		pGPIO_ISR[gpio]= pISR;
+}
+
+/*
+** Get the usual callback.  DMT datapump uses this function for
+** critical sections.
+*/
+void *GPIO_GetGPIOIRQCallback(int gpio)
+{
+	if (gpio >= 0 && gpio < NUM_OF_GPIOS)
+		return pGPIO_ISR[gpio];
+
+	return 0;
+}
+
+/*
+** Set the irq handler.  USB plug/unplug uses this.
+*/
+void GPIO_SetGPIOIRQRoutine(int gpio,void (*(pISR))(int))
+{
+	if (gpio < 16)
+		GPIOISR1Handler_Tbl[gpio]= pISR;
+	else
+		if (gpio < 32)
+			GPIOISR2Handler_Tbl[gpio-16]= pISR;
+		else
+			if (gpio < NUM_OF_GPIOS)
+				GPIOISR3Handler_Tbl[gpio-32]= pISR;
+}
+
+/*
+** Get the irq handler.  USB plug/unplug uses this.
+*/
+void *GPIO_GetGPIOIRQRoutine(int gpio)
+{
+	if (gpio < 16)
+		return GPIOISR1Handler_Tbl[gpio];
+
+	if (gpio < 32)
+		return GPIOISR2Handler_Tbl[gpio-16];
+
+	if (gpio < NUM_OF_GPIOS)
+		return GPIOISR3Handler_Tbl[gpio-32];
+
+	return 0;
+}
+
+/*
+** The actual handware interrupt goes here for processing.
+*/
+void GPIOHandler(int irq, void *dev_id, struct pt_regs * regs)
+{
+
+   register UINT32 i;
+   register UINT32 dwGPIO1Stat, dwGPIO2Stat, dwGPIO3Stat;
+   register UINT32 BitPosition;
+
+   register int oldlevel; 
+
+#ifdef INSTRUMENTATION
+   register int oldTskGPIO;
+#endif /* INSTRUMENTATION */
+
+   oldlevel = INTLOCK(); 
+
+#ifdef INSTRUMENTATION
+   oldTskGPIO= ReadGPIOData(GPOUT_TASKRDY_LED);
+   WriteGPIOData(GPOUT_TASKRDY_LED, LED_ON);
+#endif /* INSTRUMENTATION */
+
+   while (1)
+   {
+      /* Each GPIO ISR only contains 16 bits */
+      dwGPIO1Stat = (*p_GRP0_INT_STAT & *p_GRP0_INT_MASK) & 0xFFFF;
+      dwGPIO2Stat = (*p_GRP1_INT_STAT & *p_GRP1_INT_MASK) & 0xFFFF;
+      dwGPIO3Stat = (*p_GRP2_INT_STAT & *p_GRP2_INT_MASK) & 0xFFFF;
+      
+      if ( (dwGPIO1Stat | dwGPIO2Stat | dwGPIO3Stat) == 0)
+         break;
+
+      for (i = 0, BitPosition = 1; dwGPIO1Stat; i++, BitPosition<<=1)
+         if (dwGPIO1Stat & BitPosition)
+         {
+            if (GPIOISR1Handler_Tbl[i] != 0)
+   	           (*GPIOISR1Handler_Tbl[i])(i);
+            else
+			   {
+	           if (pGPIO_ISR[i] != 0)
+   				  (*(pGPIO_ISR)[i])(i);
+
+               HW_REG_WRITE (p_GRP0_INT_STAT, BitPosition);
+			   }
+
+		      dwGPIO1Stat &= ~(BitPosition); 
+         }
+
+      for (i = 0, BitPosition = 1; dwGPIO2Stat; i++, BitPosition<<=1)
+         if (dwGPIO2Stat & BitPosition)
+            {
+            if (GPIOISR2Handler_Tbl[i] != 0)
+   	           (*GPIOISR2Handler_Tbl[i])(i+16);
+            else
+			   {
+	           if (pGPIO_ISR[i+16] != 0)
+   				  (*(pGPIO_ISR)[i+16])(i+16);
+
+               HW_REG_WRITE (p_GRP1_INT_STAT, BitPosition);
+			   }
+
+		 dwGPIO2Stat &= ~(BitPosition); 
+         }
+
+      for (i = 0, BitPosition = 1; dwGPIO3Stat; i++, BitPosition<<=1)
+	     if (dwGPIO3Stat & BitPosition)
+            {
+            if (GPIOISR3Handler_Tbl[i] != 0)
+   	         (*GPIOISR3Handler_Tbl[i])(i+32);
+            else
+			   {
+	           if (pGPIO_ISR[i+32] != 0)
+   				  (*(pGPIO_ISR)[i+32])(i+32);
+
+               HW_REG_WRITE (p_GRP2_INT_STAT, BitPosition);
+			   }
+
+		 dwGPIO3Stat &= ~(BitPosition); 
+         }
+   }
+
+#ifdef INSTRUMENTATION
+   WriteGPIOData(GPOUT_TASKRDY_LED, oldTskGPIO);
+#endif /* INSTRUMENTATION */
+
+   HW_REG_WRITE (PIC_TOP_ISR_IRQ, INT_GPIO);
+   INTUNLOCK(oldlevel);
+}
+
+
+void GPIOB10_Handler( int gpio_num )
+{
+   #if CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE
+      if (pHostPort_ISR != 0)
+      {
+          pHostPort_ISR(pHostPortContext);
+      }
+
+      ClearGPIOIntStatus(GPIOINT_HP_INT);
+   #elif CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+      if (pF2_IRQ1_ISR == 0)
+      {
+         ClearGPIOIntStatus(GPIOINT_F2_IRQ1);
+         return;
+      }
+
+      /* Clearing level */
+      pF2_IRQ1_ISR(pFalconContext);
+      ClearGPIOIntStatus(GPIOINT_F2_IRQ1);
+   #else
+      ClearGPIOIntStatus(GPIO10);
+   #endif
+}
+
+void GPIOB11_Handler( int gpio_num )
+{
+   #if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+      if (pF2_IRQ2_ISR == 0)
+      {
+         ClearGPIOIntStatus(GPIOINT_F2_IRQ2);
+         return;
+      }
+
+      /* Clearing level */
+      pF2_IRQ2_ISR(pFalconContext);
+      ClearGPIOIntStatus(GPIOINT_F2_IRQ2);
+   #else
+      ClearGPIOIntStatus(GPIO11);
+   #endif
+}
+
+
+void GPIOB14_Handler( int gpio_num )
+{
+	#ifdef CONFIG_BD_RUSHMORE
+		#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+		/* Clearing level */
+		if ( (HWSTATE.eUARTState == HW_UART) && (HWSTATE.g_pUARTChan) )
+		{
+			// Smart/Dumb Terminal
+			spUartInt(HWSTATE.g_pUARTChan);
+		}
+		ClearGPIOIntStatus(GPIOINT_UART2);
+        #else
+		ClearGPIOIntStatus(GPIO14);
+		#endif
+	#else		
+		ClearGPIOIntStatus(GPIO14);
+	#endif
+}
+    
+
+void GPIOB24_Handler( int gpio_num )
+{
+	#ifdef CONFIG_BD_HASBANI
+		#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+		/* Clearing level */
+		if ( (HWSTATE.eUARTState == HW_UART) && (HWSTATE.g_pUARTChan) )
+		{
+			// Smart/Dumb Terminal
+			spUartInt(HWSTATE.g_pUARTChan);
+		}
+		ClearGPIOIntStatus(GPIOINT_UART2);
+        #else
+		ClearGPIOIntStatus(GPIO24);
+		#endif
+	#else		
+		ClearGPIOIntStatus(GPIO24);
+	#endif
+}
+    
+
+void GPIOB25_Handler(int gpio_num)
+{
+      //Linux Console
+   #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+	   void rs_interrupt(int irq, void * dev_id, struct pt_regs * regs) ;
+	   rs_interrupt( GPIOINT_UART1, NULL, NULL ) ;
+   #endif
+   ClearGPIOIntStatus(GPIOINT_UART1);  
+}
+
+void GPIOB30_Handler( int gpio_num )
+{
+	#ifdef CONFIG_BD_MACKINAC
+		#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+		/* Clearing level */
+		if ( (HWSTATE.eUARTState == HW_UART) && (HWSTATE.g_pUARTChan) )
+		{
+			// Smart/Dumb Terminal
+			spUartInt(HWSTATE.g_pUARTChan);
+		}
+		ClearGPIOIntStatus(GPIOINT_UART2);
+        #else
+		ClearGPIOIntStatus(GPIO30);
+		#endif
+	#else
+		ClearGPIOIntStatus(GPIO30);
+	#endif
+}
+
+EXPORT_SYMBOL(GPIO_SetGPIOIRQCallback);
+EXPORT_SYMBOL(GPIO_SetGPIOIRQRoutine);
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/gptimer.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/gptimer.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/gptimer.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/gptimer.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,589 @@
+/****************************************************************************
+*
+*	Name:			gptimer.c
+*
+*	Description:	General Purpose timing functions
+*
+*	Copyright:		(c) 2003 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   lewisrc  $
+*  $Revision:   1.0  $
+*  $Modtime:   Jul 18 2003 14:26:10  $
+****************************************************************************/
+
+
+#include <linux/config.h>
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/bspcfg.h>
+#include <asm/arch/cnxtbsp.h>
+#include <asm/arch/cnxttimer.h>
+#include <asm/arch/gptimer.h>
+#include <asm/arch/cnxtirq.h>
+#include <asm/arch/list.h>
+
+#define MIN_TIMER_RELOAD 1		// Minimum value we ever allow for the timer reload.
+								// Too low a value and we might miss interrupts due to latency.
+								// The size of this value will cause some timers to expire late
+								// by this amount, although repeating timers will NOT
+								// accumulate this delay.
+#define MAX_TIMER_RELOAD 0xFFFF	// Maximum value we allow for reload due to hardware timer limit
+
+
+typedef struct GP_TIMER_T
+{
+	LIST_LINK_T	 Link ;			// links for listing
+	WORD		 Index ;		// Index
+	BOOLEAN		 Running ;		// Flag to indicate whether timer is currently running
+	PGPCALLBACK	 pCallback;		// Routine to call when timer expires
+	void		*pContext ;		// Pointer to context passed to Callback
+	LONG		 Delta ;		// Delta time remaining
+	LONG		 Period ;		// Period of timer
+	BOOLEAN		 Repeats;		// TRUE = periodic, FALSE = one_shot
+} GP_TIMER_T;
+
+static GP_TIMER_T	GPTimers[NUMBER_OF_GP_TIMERS];	// Array of all timers
+static LIST_LINK_T	GPTimerList ;					// Anchor for ordered chain of running timers
+static LIST_LINK_T	GPCallbackList ;				// Anchor for ordered chain of callbacks
+static spinlock_t	GPTimerLock ;					// Spinlock for critical areas
+
+
+/******************************************************************************
+FUNCTION:	GPTimerInit
+ABSTRACT:	Initializes structures that support gp timers
+RETURN:		
+*******************************************************************************/
+#if 0
+GP_TIMER_T LINK_TO_TIMER ( LIST_LINK_T pLink ) {}
+#endif
+#define LINK_TO_TIMER(pLink) ( (GP_TIMER_T *) ( pLink - offsetof ( GP_TIMER_T, Link ) ) )
+
+
+
+/******************************************************************************
+FUNCTION:	GPTimerInit
+ABSTRACT:	Initializes structures that support gp timers
+RETURN:		
+*******************************************************************************/
+void GPTimerInit
+(
+	void
+)
+{
+	int Index ;
+
+	printk ( "Conexant General Purpose timers initialized\n" ) ;
+
+	// Initialize our list of chained timers and callbacks(empty to begin with)
+	ListInit ( &GPTimerList ) ;
+	ListInit ( &GPCallbackList ) ;
+
+	// Initialize our lock
+	spin_lock_init ( &GPTimerLock ) ;
+
+	// initialize index member of each timer
+	for ( Index = 0  ; Index < NUMBER_OF_GP_TIMERS ; Index++ )
+	{
+		GPTimers [Index].Index = Index ;
+	}
+
+	// Enable the programmable hardware timer
+	{
+		void GPTimerExpired
+		(
+			WORD ElapsedTime,
+			void *pContext
+		) ;
+
+		CnxtTimerEnable ( HW_PROG_TIMER_GP, GPTimerExpired ) ;
+	}
+}
+
+
+
+/******************************************************************************
+FUNCTION:	GPTimerConnect
+ABSTRACT:	Connects a function to the timer that will be called when the timer
+			expires
+RETURN:		TRUE = function connected
+			FALSE = function not connected
+*******************************************************************************/
+int GPTimerConnect
+(
+	WORD		TimerIndex,
+	PGPCALLBACK	pCallback,
+	void		*pContext
+)
+{
+	GP_TIMER_T	*pGPTimer = &GPTimers[TimerIndex];
+	
+	// Is there already a connected callback?
+	if ( pGPTimer->pCallback != NULL )
+	{
+		return -ETMRBUSY;
+	}
+	else
+	{
+		pGPTimer->pCallback	= pCallback;
+		pGPTimer->pContext	= pContext;
+		pGPTimer->Running	= FALSE ;
+
+		return 0;
+	}
+}	 
+
+
+
+/******************************************************************************
+FUNCTION:	GPTimerDisconnect
+ABSTRACT:	Disconnects a callback from the timer.
+RETURN:		TRUE = function disconnected
+			FALSE = function not disconnected
+*******************************************************************************/
+int GPTimerDisconnect
+(
+	WORD		TimerIndex
+)
+{
+	BOOLEAN		Return ;
+	GP_TIMER_T	*pGPTimer = &GPTimers[TimerIndex];
+	
+	// Is this timer already disconnected?
+	if ( pGPTimer->pCallback == NULL )
+	{
+		Return = -ETMRIDLE ;
+	}
+	else
+	{
+		// if this timer is still running
+		if ( pGPTimer->Running )
+		{
+			// stop it
+			GPTimerStop ( TimerIndex ) ;
+		}
+
+		// Clear the connection between timer and callback
+		pGPTimer->pCallback	= NULL ;
+
+		// clear timer members to lessen confusion
+		pGPTimer->pContext	= NULL ;
+		pGPTimer->Delta		= 0 ;
+		pGPTimer->Period	= 0 ;
+		pGPTimer->Repeats	= FALSE ;
+
+		Return = 0 ;
+	}
+
+	// return
+	return Return ;
+}
+
+
+
+/******************************************************************************
+FUNCTION:	gpTimerStartIrq
+ABSTRACT:	Starts the general purpose timer without spinlocks
+DETAILS:	This is used by the GPTimerExpired when it handles a repeating timer
+			because it already has the spin lock and doesn't want to release it
+			to restart a repeating timer.
+*******************************************************************************/
+static int gpTimerStartIrq
+(
+	WORD		TimerIndex,
+	LONG		Period,
+	BOOLEAN		Repeats,		// If TRUE, we must restart this timer automatically after it expires
+	BOOLEAN		Restart			// If TRUE, this is a restarted repeating timer
+)
+{
+	LIST_LINK_T *pLink ;
+	GP_TIMER_T	*pGPTimer = &GPTimers[TimerIndex];
+	LONG		TotalDeltas = 0 ;
+	BOOLEAN		Return ;
+	
+	// Is this timer unconnected?
+	if ( pGPTimer->pCallback == NULL )
+	{
+		printk ( "%s: GPTimer started without being connected\n", __FILE__ ) ;
+		Return = -ETMRNRDY ;
+	}
+
+	// Is this timer already running
+	else if ( pGPTimer->Running )
+	{
+		printk ( "%s: GPTimer started while already running\n", __FILE__ ) ;
+		Return = -ETMRBUSY ;
+	}
+	else
+	{
+		GP_TIMER_T	*pChainedGPTimer = NULL ;
+
+		// Save the args
+		pGPTimer->Period = Period ;
+		pGPTimer->Repeats = Repeats ;
+
+		// If this is an automatic restart of a repeating timer
+		if ( Restart )
+		{
+			// Add existing HW timer value to our new timer's delay in order
+			// that the time that has already been run off the HW timer is
+			// accounted for
+			Period += CnxtTimerRead ( HW_PROG_TIMER_GP ) ;
+		}
+
+		// search the timer on each position of the chain of timers for the
+		// point where this new one should be inserted.
+		for
+		(
+			pLink = ListNext ( &GPTimerList ) ;	// beginning of timer chain
+			pLink != &GPTimerList ;				// do until we reach end of chain
+			pLink = ListNext (pLink)			// advance search to next timer on chain
+		)
+		{
+			// Convert new search position link to timer
+			pChainedGPTimer = LINK_TO_TIMER ( pLink ) ;
+
+			// if this new timer's period is smaller than search position's remaining time (cumulative)
+			if ( Period < ( TotalDeltas + pChainedGPTimer->Delta ) )
+			{
+				// done
+				break ;
+			}
+			else
+			{
+				// add search position's timer to the total deltas to this point
+				TotalDeltas += pChainedGPTimer->Delta ;
+			}
+
+			// Next search position may be the end of the list (an anchor)
+			// rather than a timer. Clear pointer to search position timer
+			// since it is not yet valid and may not be.
+			pChainedGPTimer = NULL ;
+		}
+
+		// add this new timer prior to the final search position
+		// (even if the final search position is the anchor)
+		ListInsertPrev ( pLink, &pGPTimer->Link ) ;
+
+		// Mark the new timer as running
+		pGPTimer->Running = TRUE ;
+
+		// Compute the delta of the new timer based on the total deltas 
+		// of all preceeding timers
+		pGPTimer->Delta = Period - TotalDeltas ;
+
+		// if the search position is a timer and not an anchor
+		if ( pChainedGPTimer )
+		{
+			// adjust period of the search position's timer by new timer's delta
+			pChainedGPTimer->Delta -= pGPTimer->Delta ;
+		}
+
+		// If our new timer is the head of the chained timers
+		if ( ListNext ( &GPTimerList ) == &pGPTimer->Link )
+		{
+			LONG CnxtTimer ;	// Snapshot of the HW timer
+
+			// Read the hardware timer
+			CnxtTimer = CnxtTimerRead ( HW_PROG_TIMER_GP ) ;
+
+			// We are about to reload the HW timer and that will discard
+			// any time built up in the HW timer. Reflect this discarded
+			// time in the new timer's delta
+			pGPTimer->Delta -= CnxtTimer ;
+
+			// If our new timer has already expired
+			if ( pGPTimer->Delta <= CnxtTimer )
+			{
+				// Setup timer to expire "immediately" so our expired
+				// timer will be serviced.
+				CnxtTimerStart ( HW_PROG_TIMER_GP, MIN_TIMER_RELOAD, (void *)(DWORD)pGPTimer->Index ) ;
+			}
+			else
+			{
+				LONG Timeout ;		// Make it long and signed to account for negative values
+
+				// New HW timeout is new timer's new delta
+				Timeout = pGPTimer->Delta ;
+
+				// MIN_TIMER_RELOAD <= Timeout <= MAX_TIMER_RELOAD
+				Timeout = max ( MIN_TIMER_RELOAD, Timeout ) ;
+				Timeout = min ( Timeout, MAX_TIMER_RELOAD ) ;
+
+				// Set HW timer
+				CnxtTimerStart ( HW_PROG_TIMER_GP, (WORD)Timeout, (void *)(DWORD)pGPTimer->Index ) ;
+			}
+		}
+
+		// Success	
+		Return = 0;
+	}
+	
+	return Return ;
+}
+
+
+
+/******************************************************************************
+FUNCTION:	GPTimerStart
+ABSTRACT:	Starts the general purpose timer
+DETAILS:
+*******************************************************************************/
+int GPTimerStart
+(
+	WORD		TimerIndex,
+	LONG		Period,
+	BOOLEAN		Repeats
+)
+{
+	unsigned long int	Flags ;
+	BOOLEAN				Return ;
+	
+	// Begin Critical Area
+	spin_lock_irqsave  ( &GPTimerLock, Flags ) ;
+
+	Return = gpTimerStartIrq ( TimerIndex, Period, Repeats, FALSE ) ;
+
+	// End Critical Area
+	spin_unlock_irqrestore  ( &GPTimerLock, Flags ) ;
+
+	// Return
+	return Return ;
+}
+
+
+
+/******************************************************************************
+FUNCTION:	GPTimerStop
+ABSTRACT:	Stops the general purpose timer
+DETAILS:
+*******************************************************************************/
+int GPTimerStop
+(
+	WORD TimerIndex
+)
+{
+	GP_TIMER_T	*pGPTimer = &GPTimers[TimerIndex];
+	BOOLEAN		Return ;
+	
+	// Is this timer disconnected?
+	if ( pGPTimer->pCallback == NULL )
+	{
+		// Failure
+		Return = -ETMRNRDY;
+	}
+	else
+	{
+		unsigned long int Flags ;
+		GP_TIMER_T	*pChainedGPTimer ;
+
+		// Begin Critical Area
+		spin_lock_irqsave  ( &GPTimerLock, Flags ) ;
+
+			// Get pointer to following timer
+			pChainedGPTimer = LINK_TO_TIMER ( ListNext ( &pGPTimer->Link ) ) ;
+
+			// remove the desired timer from the chain
+			ListRemove ( &pGPTimer->Link ) ;
+			pGPTimer->Running = FALSE ;
+
+			// if the following timer is a timer and not an anchor
+			if ( &pChainedGPTimer->Link != &GPTimerList )
+			{
+				// Add the removed timer's delta period into following chained
+				// timer's delta period.
+				pChainedGPTimer->Delta += pGPTimer->Delta ;
+			}
+
+			// If following timer is now the head of the chained timers
+			if ( ListNext ( &GPTimerList ) == &pChainedGPTimer->Link )
+			{
+				LONG Timeout ;		// Make it long and signed to account for negative values
+				LONG CnxtTimer ;	// Snapshot of the HW timer
+
+				// Read the hardware timer
+				CnxtTimer = CnxtTimerRead ( HW_PROG_TIMER_GP ) ;
+
+				// New HW timer timeout is HW timer's time left (Old first timer - HW Timer)
+				// plus new head timer's delta
+				Timeout = ( pGPTimer->Delta - CnxtTimer ) + pChainedGPTimer->Delta ;
+
+				// MIN_TIMER_RELOAD <= Timeout <= MAX_TIMER_RELOAD
+				Timeout = max ( MIN_TIMER_RELOAD, Timeout ) ;
+				Timeout = min ( Timeout, MAX_TIMER_RELOAD ) ;
+
+				// Set HW timer
+				CnxtTimerStart ( HW_PROG_TIMER_GP, (WORD) Timeout, (void *)(DWORD)pChainedGPTimer->Index ) ;
+			}
+
+		// End Critical Area
+		spin_unlock_irqrestore  ( &GPTimerLock, Flags ) ;
+
+		// Success	
+		Return = 0;
+	}
+
+	// Return
+	return Return ;
+}
+
+
+
+/******************************************************************************
+FUNCTION:	GPTimerExpired
+ABSTRACT:	Called by ISR when hardware timer expires
+DETAILS:	If the ISR is delayed by interrupt latency, the timer might have
+			expired again (it auto reloads). The ISR detects this and includes
+			this time in the Elapsed time and so the value can exceed the 16 bit
+			capacity of the time and hence we use a LONG.
+*******************************************************************************/
+void GPTimerExpired
+(
+	WORD ElapsedTime,
+	void *pContext
+)
+{
+	WORD		TimerIndex ;
+	LIST_LINK_T *pLink ;
+	LIST_LINK_T *pNext ;
+	GP_TIMER_T	*pGPTimer ;
+	GP_TIMER_T	*pChainedGPTimer = NULL ;
+
+	TimerIndex = (WORD)(DWORD)pContext ;
+	pGPTimer = &GPTimers[TimerIndex];
+
+	// Begin Critical Area
+	spin_lock ( &GPTimerLock ) ;
+
+		// search the timer on each position of the chain of timers for the
+		// point where this new one should be inserted.
+		for
+		(
+			pLink = ListNext ( &GPTimerList ) ;	// beginning of timer chain
+			pLink != &GPTimerList ;				// do until we reach end of chain
+			pLink = pNext						// advance search to next timer on chain
+		)
+		{
+			// Get snapshot of next timer on list
+			pNext = ListNext (pLink) ;
+
+			// Convert link to timer
+			pChainedGPTimer = LINK_TO_TIMER ( pLink ) ;
+
+			// if Elapsed time < search position's timer
+			if ( ElapsedTime < pChainedGPTimer->Delta )
+			{
+				// Subtract ElapsedTime from this delta
+				pChainedGPTimer->Delta -= ElapsedTime ;
+
+				// done
+				break ;
+			}
+			else
+			{
+				// Subtrace the timer's delta from ElapseTime and zero out timer's delta
+				ElapsedTime -= pChainedGPTimer->Delta ;
+				pChainedGPTimer->Delta = 0 ;
+
+				// Remove timer from chained list
+				ListRemove ( pLink ) ;
+
+				// Put timer on chained list of callbacks to do before we return
+				ListEnqueue ( &GPCallbackList, pLink ) ;
+
+				// Mark timer as not running
+				pChainedGPTimer->Running = FALSE ;
+			}
+
+			// Next search position may be the end of the list (an anchor)
+			// rather than a timer. Clear pointer to timer since it is not yet
+			// valid and may not be.
+			pChainedGPTimer = NULL ;
+		}
+
+		if ( ListIsEmpty ( &GPTimerList ) )
+		{
+			// stop HW timer
+			CnxtTimerStop ( HW_PROG_TIMER_GP ) ;
+		}
+		else
+		{
+			LONG Timeout ;
+
+			// Look at first chained timer
+			pLink = ListNext ( &GPTimerList ) ;
+
+			// Convert link to timer
+			pChainedGPTimer = LINK_TO_TIMER ( pLink ) ;
+
+			// HW Timer timeout will be first chained timer's delta
+			Timeout = pChainedGPTimer->Delta ;
+
+			// MIN_TIMER_RELOAD <= Timeout <= MAX_TIMER_RELOAD
+			Timeout = max ( MIN_TIMER_RELOAD, Timeout ) ;
+			Timeout = min ( Timeout, MAX_TIMER_RELOAD ) ;
+
+			// Start HW timer
+			CnxtTimerStart ( HW_PROG_TIMER_GP, (WORD)Timeout, (void *)(DWORD)pChainedGPTimer->Index ) ;
+		}
+
+	// End Critical Area
+	spin_unlock ( &GPTimerLock ) ;
+
+	// search the timer on each position of the chain of timers for the
+	// point where this new one should be inserted.
+	for
+	(
+		pLink = ListNext ( &GPCallbackList ) ;	// beginning of callback chain
+		pLink != &GPCallbackList ;					// do until we reach end of chain
+		pLink = pNext							// advance search to next callback on chain
+	)
+	{
+		// Get snapshot of next timer on list
+		pNext = ListNext (pLink) ;
+
+		// Remove timer from chained list
+		ListRemove ( pLink ) ;
+
+		// Convert link to timer
+		pChainedGPTimer = LINK_TO_TIMER ( pLink ) ;
+
+		// Call the timer's callback function
+		pChainedGPTimer->pCallback ( pChainedGPTimer->pContext ) ;
+
+		// if timer is a repeating timer
+		if ( pChainedGPTimer->Repeats )
+		{
+			LONG Timeout ;
+
+			Timeout = pChainedGPTimer->Period + ElapsedTime + CnxtTimerRead ( HW_PROG_TIMER_GP ) ;
+			gpTimerStartIrq ( pChainedGPTimer->Index, Timeout, TRUE, FALSE ) ;
+		}
+	}
+}
+
+
+
+EXPORT_SYMBOL(GPTimerConnect);
+EXPORT_SYMBOL(GPTimerDisconnect);
+EXPORT_SYMBOL(GPTimerStart);
+EXPORT_SYMBOL(GPTimerStop);
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/hstif.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/hstif.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/hstif.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/hstif.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,180 @@
+/****************************************************************************
+*
+*	Name:			hstif.c
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 - 2003  Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   belljl  $
+*  $Revision:   1.1  $
+*  $Modtime:   Jun 30 2003 15:29:32  $
+****************************************************************************/
+
+/*---------------------------------------------------------------------------
+ *  Include Files
+ *-------------------------------------------------------------------------*/
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/hstif.h>
+
+/****************************************************************************
+ *
+ *  Name:			void HSTInit( void )
+ *
+ *  Description:	Initializes the host interface
+ *
+ *  Inputs:			none
+ *
+ *  Outputs:		none
+ *
+ ***************************************************************************/
+void HSTInit( void )
+{
+
+	#if CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE
+
+		/* Read wait states */
+		*pHST_RwstReg  = 0x01ffffff;
+
+		/* Write wait states */
+		*pHST_WwstReg  = 0x01ffffff;
+
+		/* All chip selects use separate read and writes */
+		*pHST_Xfer_CntlReg = 0;
+
+		/* Read chip select setup and hold timers */
+		*pHST_Read_Cntl1Reg = 0xffffffff;
+
+		/* Read address setup and hold timers */
+		*pHST_Read_Cntl2Reg = 0xffffffff;
+
+		/* Write chip select setup and hold timers */
+		*pHST_Write_Cntl1Reg = 0xffffffff;
+
+		/* Write address setup and hold timers */
+		*pHST_Write_Cntl2Reg = 0xffffffff;
+
+		/* Only for HCS2 ( access to the 8975 ) being set as 8 bits */
+		*pMSTR_Intf_WidthReg = 0x00000004;
+
+		*pMSTR_HandshakeReg = 0x0;
+
+	#elif CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+
+		/* Read wait states */
+		*pHST_RwstReg  = ( 7 << FLASH_WS ) |
+						 ( 7 << HCS1_WS ) |
+						 ( 17 << FALCON_WS ) |  // old 20  new 17
+						 ( 7 << V90_WS ) |
+						 ( 7 << UART_WS );
+
+		/* Write wait states */
+		*pHST_WwstReg  = ( 7 << FLASH_WS ) |
+						 ( 7 << HCS1_WS ) |
+						 ( 5 << FALCON_WS ) |	// old 20  new 5
+						 ( 7 << V90_WS ) |
+						 ( 7 << UART_WS );
+
+		/* All chip selects use separate read and writes */
+		*pHST_Xfer_CntlReg = 0;
+
+		/* Read chip select setup and hold timers */
+		*pHST_Read_Cntl1Reg = ( 2 << HCS1_TCH ) |
+							  ( 2 << FALCON_TCH ) |  // old 15  new 2
+							  ( 0 << V90_TCH ) |
+							  ( 1 << UART_TCH ) |
+							  ( 2 << HCS1_TCS ) |
+							  ( 2 << FALCON_TCS ) |  // old 15  new 2
+							  ( 0 << V90_TCS ) |
+							  ( 1 << UART_TCS );
+
+		/* Read address setup and hold timers */
+		*pHST_Read_Cntl2Reg = ( 2 << HCS1_TAH ) |
+							  ( 1 << FALCON_TAH ) | // old 15  new 1
+							  ( 0 << V90_TAH ) |
+							  ( 1 << UART_TAH ) |
+							  ( 2 << HCS1_TAS ) |
+							  ( 1 << FALCON_TAS ) | // old 15  new 1
+							  ( 0 << V90_TAS ) |
+							  ( 1 << UART_TAS );
+
+		/* Write chip select setup and hold timers */
+		*pHST_Write_Cntl1Reg = ( 2 << HCS1_TCH ) |
+							  ( 2 << FALCON_TCH ) | // old 15  new 2
+							  ( 0 << V90_TCH ) |
+							  ( 1 << UART_TCH ) |
+							  ( 2 << HCS1_TCS ) |
+							  ( 2 << FALCON_TCS ) | // old 15  new 2
+							  ( 0 << V90_TCS ) |
+							  ( 1 << UART_TCS );
+
+		/* Write address setup and hold timers */
+		*pHST_Write_Cntl2Reg = ( 2 << HCS1_TAH ) |
+							  ( 6 << FALCON_TAH ) | // old 15  new 6
+							  ( 0 << V90_TAH ) |
+							  ( 1 << UART_TAH ) |
+							  ( 2 << HCS1_TAS ) |
+							  ( 1 << FALCON_TAS ) | // old 15  new 1
+							  ( 0 << V90_TAS ) |
+							  ( 1 << UART_TAS );
+
+	#else
+		/* Read wait states */
+		*pHST_RwstReg  = ( 7 << FLASH_WS ) |
+				 ( 7 << HCS1_WS ) |
+			       	 ( 7 << UART_WS );
+
+		/* Write wait states */
+		*pHST_WwstReg  = ( 7 << FLASH_WS ) |
+				 ( 7 << HCS1_WS ) |
+			       	 ( 7 << UART_WS );
+
+		/* All chip selects use separate read and writes */
+		*pHST_Xfer_CntlReg = 0;
+
+		/* Read chip select setup and hold timers */
+		*pHST_Read_Cntl1Reg = ( 2 << HCS1_TCH ) |
+				      ( 1 << UART_TCH ) |
+		                      ( 2 << HCS1_TCS ) |
+				      ( 1 << UART_TCS );
+
+		/* Read address setup and hold timers */
+		*pHST_Read_Cntl2Reg = ( 2 << HCS1_TAH ) |
+				      ( 1 << UART_TAH ) |
+				      ( 2 << HCS1_TAS ) |
+				      ( 1 << UART_TAS );
+
+		/* Write chip select setup and hold timers */
+		*pHST_Write_Cntl1Reg = ( 2 << HCS1_TCH ) |
+				       ( 1 << UART_TCH ) |
+				       ( 2 << HCS1_TCS ) |
+				       ( 1 << UART_TCS );
+
+		/* Write address setup and hold timers */
+		*pHST_Write_Cntl2Reg = ( 2 << HCS1_TAH ) |
+				       ( 1 << UART_TAH ) |
+				       ( 2 << HCS1_TAS ) |
+				       ( 1 << UART_TAS );
+	#endif // #ifdef CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE || CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE #else
+
+	return;
+}
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/io.S linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/io.S
--- linux-2.4.29/arch/armnommu/mach-cx821xx/io.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/io.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,65 @@
+/*
+ *  linux/arch/arm/mach-ebsa110/io.S
+ *
+ *  Copyright (C) 1995 - 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+		.text
+
+/*
+ * These make no sense on these machines.  Print a warning message.
+ */
+ENTRY(insl)
+		adr	r1, .insl_name
+		b	.warn
+
+ENTRY(outsl)
+		adr	r1, .outsl_name
+.warn:		adr	r0, .io_warning
+		mov	r2, lr
+		b	SYMBOL_NAME(printk)
+
+.insl_name:	.asciz	"insl"
+.insw_name:	.asciz	"insw"
+.outsl_name:	.asciz	"outsl"
+.outsw_name:	.asciz	"outsw"
+.io_warning:	.asciz	"<4>%s: not implemented on this architecture (lr = 0x%p)"
+		.align
+
+@ These are mainly to satisfy the parport code
+
+ENTRY(insb)
+		cmp	r0, #0x00c00000
+		movge	r3, #0
+		movlt	r3, #0xf0000000
+		add	r0, r3, r0, lsl #2
+		b	__arch_readsb
+
+ENTRY(outsb)
+		cmp	r0, #0x00c00000
+		movge	r3, #0
+		movlt	r3, #0xf0000000
+		add	r0, r3, r0, lsl #2
+		b	__arch_writesb
+
+@ And these for the imm/ppa code
+
+ENTRY(insw)
+		cmp	r0, #0x00c00000
+		movge	r3, #0
+		movlt	r3, #0xf0000000
+		add	r0, r3, r0, lsl #2
+		b	__arch_readsw
+
+ENTRY(outsw)
+		cmp	r0, #0x00c00000
+		movge	r3, #0
+		movlt	r3, #0xf0000000
+		add	r0, r3, r0, lsl #2
+		b	__arch_writesw
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/irq.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/irq.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/irq.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,85 @@
+/****************************************************************************
+*
+*	Name:			irq.c
+*
+*	Description:	Interrupt control functions
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:22:08  $
+****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <asm/mach/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+ 
+inline void cnxt_irq_ack(int irq)
+{
+	*CNXT_INT_STATUS = (1 << irq);
+}
+
+  
+inline void cnxt_mask_irq(unsigned int irq)
+{
+  /* reset cooresponding bit in the 32bit Int mask register */ 
+  *CNXT_INT_MASK &= ~(1 << irq);
+}
+
+
+inline void cnxt_unmask_irq(unsigned int irq)
+{
+  /* set cooresponding bit in the 32bit Int mask register */ 
+  *CNXT_INT_MASK |= (1 << irq);
+}
+ 
+
+inline void cnxt_mask_ack_irq(unsigned int irq)
+{
+	cnxt_mask_irq(irq);
+	/* this is ok if int source is not hooked on GPIO */
+	*CNXT_INT_STATUS = (1 << irq);
+}
+
+int cnxt_irq_mask_state_chk( unsigned int irq_num )
+{
+	if( *CNXT_INT_MASK & ( 1 << irq_num ))
+	{
+		// IRQ is enabled
+		return 1;
+	}
+	// IRQ is disabled
+	return 0;
+}
+
+
+EXPORT_SYMBOL(cnxt_unmask_irq);
+EXPORT_SYMBOL(cnxt_mask_irq);
+EXPORT_SYMBOL(cnxt_irq_mask_state_chk);
+
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/iterate.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/iterate.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/iterate.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/iterate.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,261 @@
+/****************************************************************************
+*
+*	Name:			iterate.c
+*
+*	Description:	Runs iterations through a timeing loop for CPU utilization
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:22:08  $
+****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <timex.h>		// CLOCK_TICK_RATE
+#include <asm/param.h>	// HZ
+#include <asm/system.h>	// save_flags
+#include <sched.h>		// jiffies
+#include "Common.h"		// BOOLEAN
+
+volatile unsigned long cnxt_gettimeoffset(void);
+
+/****************************************************************************
+	Function		: Iterate
+	Description		: Performs as many iterations as possible in the given time.
+	Abstract:		: This routine is used to measure how busy the CPU is.
+					: It runs for a fixed period (measured by looking at the
+					: timer register and/or jiffies count) and sees how many
+					: iterrations of looping, incrementing a counter and watching
+					: for clock edges it can get done in the fixed period of time.
+					: Thus the returned count is a function of how much it is
+					: preempted and the number of CPU cycles to perform one
+					: iteration. This latter factor is a constant and basically
+					: arbitrary so only use the returned numbers as ratios since
+					: the number is not a MIP or any other standard measure and
+					: could change in the future.
+					: Use this routine by calling once with DisableInts set to get a
+					: maximum. Then call with with DisableInts cleared to see
+					: how many iterations are possible when preemption occurs.
+					: Then divide the latter number by the former to get a ratio
+					: of CPU loading.
+					: Call both times using the same setting for DisableCache
+					: for the ratio to be meaningful.
+					: The ARM940T has 4KB Data and 4KB Instruction cache. Depending
+					: on the task size and behavior under consideration for 
+					: insertion into the spare cycles, you may wish to take your
+					: two measurements with or without cacheing.
+	Details			: This routine is required to detect clock timer rollover
+					: (edges) with interrupts off or on. Furthermore the paths
+					: for each case must be the same since this detection is a
+					: considerable part of the busyness of the measurement.
+					: With interrupts enabled, we may be preempted and so we
+					: cannot guarantee that we will see every clock increment.
+					: Without seeing every clock increment, we are forced to
+					: alternate between looking for the rollover and the halfway
+					: point. Of course we cannot be guaranteed of seeing either of
+					: these with interrupts enabled, so we watch the jiffies count
+					: which is incremented by the interrupt. With interrupts off,
+					: it is not incremented, but we will see every clock tick. 
+					: This does result in a slightly different path when the interrupt
+					: enabled version misses an edge, it will instead see a jiffie
+					: change which the disabled version never takes. But this slightly
+					: longer path can will not occur often and can be attributed to
+					: the overhead of preemption.
+	Notes:			: The time period should not exceed approximately 2 seconds
+					: or the busyness counter may overflow. This time period can
+					: be extended by artificially extending the cycles consumed
+					: in each iteration.
+					: The time period will be converted to the nearest jiffie.
+	Notes:			: We assume cache is normally on
+****************************************************************************/
+void cache_off ( void ) ;
+void cache_on (void ) ;
+unsigned long int Iterate ( unsigned short int MSecs, BOOLEAN DisableInts, BOOLEAN DisableCache )
+{
+	int State  ;						// Tracks which edge (0 or 1/2) we are looking for
+	unsigned long int elapsedjiffies ;	// Count of jiffies that have elapsed since we started looping
+	unsigned long int lastjiffie ;		// Value of jiffies when we last saw a 0 edige
+	unsigned long int jiffieinc ;		// Indicates whether we should increment lastjiffied upon detecting a 0 edige
+    unsigned long int busycounter = 0 ;	// Counts number of iterations we manage in the given period
+    unsigned long int jiffielimit ;		// Amount of time in jiffies to loop
+	unsigned long flags = 0 ;			// Status flags saved when we disable interrupts
+    
+	//*************************************************************************
+	// If we are supposed to disable interrupts or cache?
+	//*************************************************************************
+	if ( DisableInts )
+	{
+		// disable interrupts
+		save_flags (flags) ;
+		cli () ;
+	}
+
+	if ( DisableCache )
+	{
+		cache_off () ;
+	}
+	
+	
+	//*************************************************************************
+	//* initialize
+	//*************************************************************************
+	
+	// disable interrupts
+	{
+		unsigned long flags = 0 ;
+		
+		save_flags (flags) ;
+		cli () ;
+		
+		// wait on an edge
+		while ( cnxt_gettimeoffset() != 0 )
+		{
+			;
+		}
+		
+		// initialize elapsed jiffies
+		elapsedjiffies = 0 ;
+		
+		// initialize lastjiffie
+		lastjiffie = jiffies ;
+		
+		// if interrupts are disabled, don't increment lastjiffie when measuring
+		if ( DisableInts )
+		{
+			jiffieinc = 0 ;
+		}
+		else
+		{
+			jiffieinc = 1 ;
+		}
+		
+		// state is initialize to look for half point of cycle since we just saw 0 edge
+		State = 1;
+
+		// enable interrupts
+		restore_flags (flags) ;
+	}
+    
+    
+    
+    //*************************************************************************
+    //* Measure
+    //*************************************************************************
+    
+    // loop for given period
+    jiffielimit = ( MSecs * HZ ) / 1000L ;
+    while ( elapsedjiffies <  jiffielimit )
+    {
+	    // looking for CLOCK_TICK_RATE to 0 edge
+	    if ( State == 0 )
+	    {
+	    	// check for edge before checking for miss since when interrupts are
+	    	// enabled, it will always look like we missed 1 when it rolls over.
+	    	
+	    	// if we passed CLOCK_TICK_RATE to 0 edge
+	    	if ( cnxt_gettimeoffset() < (CLOCK_TICK_RATE/2) )
+	    	{
+	    		// update elapsed counter
+	    		elapsedjiffies ++ ;
+
+	    		// update lastjiffie (if interrupts are not disabled) so that we catch next edge
+	    		lastjiffie += jiffieinc ;
+	    		
+	    		// change to state of looking for CLOCK_TICK_RATE/2 edge
+	    		State = 1 ;
+	    	}
+
+	    	// if we missed this edge (and the following CLOCK_TICK_RATE/2 edge)
+	    	else if ( lastjiffie != jiffies )
+	    	{
+	    		//  elapsed counter
+	    		elapsedjiffies ++ ;
+
+	    		// update lastjiffie (if interrupts are not disabled) so that we catch next edge
+	    		lastjiffie += jiffieinc ;
+	    		
+	    		// change to state of looking for CLOCK_TICK_RATE/2 edge
+	    		State = 1 ;
+	    	}
+	    }
+	    else
+	    // looking for CLOCK_TICK_RATE/2 edge
+	    {
+	    	// if we passed CLOCK_TICK_RATE/2 edge
+	    	if ( cnxt_gettimeoffset() > (CLOCK_TICK_RATE/2) )
+	    	{
+	    		// change to state of looking for CLOCK_TICK_RATE/0 edge
+	    		State = 0 ;
+	    	}
+
+	    	// if we missed this edge (and the following CLOCK_TICK_RATE to 0 edge)
+	    	else if ( lastjiffie != jiffies )
+	    	{
+	    		// change to state of looking for CLOCK_TICK_RATE/0 edge
+	    		State = 0 ;
+	    	}
+	    }
+    	
+    	// bump busyness counter for each pass through loop
+    	busycounter++ ;
+    }
+    
+    //*************************************************************************
+    // enable interrupts or cache if disabled
+	//*************************************************************************
+	if ( DisableCache )
+	{
+		cache_on () ;
+	}
+	
+	
+	if ( DisableInts )
+	{
+		restore_flags (flags) ;
+	}
+	
+	return busycounter ;
+}
+
+EXPORT_SYMBOL(Iterate);
+
+/***************************************************************************
+ $Log:   S:/Embedded/archives/Linux/BSP_CX821xx/uClinux2.4.6/linux/arch/armnommu/mach-cx821xx/iterate.c-arc  $
+ * 
+ *    Rev 1.0   Mar 19 2003 13:22:02   davidsdj
+ * Initial revision.
+ * 
+ * 4     8/13/02 9:58a Palazzjd
+ * Exported symbol Iterate for when building ADSL driver stack as modules.
+ * 
+ * 3     6/10/02 1:55p Lewisrc
+ * Enable Cache support
+ * 
+ * 2     6/06/02 10:46a Lewisrc
+ * Add include of Common.h so BOOLEAN is defined.
+ * 
+ * 1     6/05/02 3:05p Lewisrc
+ * Added iterate.o
+****************************************************************************/
+/***** end of file $Workfile:   iterate.c  $ *****/
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/leds.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/leds.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/leds.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/leds.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,56 @@
+/****************************************************************************
+*
+*	Name:			leds.c
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:22:08  $
+****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+static spinlock_t leds_lock;
+
+
+static int __init leds_init(void)
+{
+	return 0;
+}
+
+__initcall(leds_init);
+
+
+
+
+
+
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/LnxTools.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/LnxTools.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/LnxTools.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/LnxTools.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,156 @@
+/****************************************************************************
+*
+*	Name:			LnxTools.c
+*
+*	Description:	Provides OS independent kernel functions
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:22:08  $
+****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <asm/arch/OsTools.h>
+
+void INIT_EVENT( EVENT_HNDL* pEvent )
+{
+	pEvent->SetFlag = 0;
+	pEvent->WaitCnt = 0;
+	init_waitqueue_head( &pEvent->WaitQue);
+	INIT_SPIN_LOCK( &pEvent->FlagLock );
+}
+
+int WAIT_EVENT( EVENT_HNDL* pEvent, ULONG msecDelay )
+{
+	long int TimeRemain;
+	unsigned long flags ;
+
+	// wait on the queue
+	// Round up to next jiffie for low Linux 100 Hz resolution and
+	// add 1 jiffie for unsynchronized timers
+	// and add 1 more jiffie for timer rate differences
+	// and add 2 more jiffie because unknown factors are causing timeouts
+	TimeRemain = ((msecDelay+49) * HZ) / 1000;
+
+	// if no wait time then just return failure
+	if ( ! msecDelay )
+	{
+		return 0;
+	}
+
+	// atomically sleep if event is not set - we must protect the window between
+	// finding out if the flag is already set and sleeping as if an interrupt
+	// occurs in the window and calls SET_EVENT, SET_EVENT will signal the wait
+	// queue before we get placed on it and we will miss this signal.
+	save_flags (flags) ;
+	cli () ;
+
+	// indicate that I am waiting
+	pEvent->WaitCnt++;
+
+	if ( ! pEvent->SetFlag )
+	{
+		#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+			while ( !pEvent->SetFlag && TimeRemain )
+			{
+				// safe to call sleep with interrupts off as kernel will re-enable
+				// interrupts after placing us on the queue and before calling schedule
+				TimeRemain = interruptible_sleep_on_timeout ( &pEvent->WaitQue,  TimeRemain );
+			}
+		#else
+			while ( !pEvent->SetFlag )
+			{
+				// safe to call sleep with interrupts off as kernel will re-enable
+				// interrupts after placing us on the queue and before calling schedule
+				interruptible_sleep_on ( &pEvent->WaitQue );
+			}
+		#endif
+	}
+	// remove wait indication
+	pEvent->WaitCnt--;
+
+	restore_flags (flags) ;
+
+	// return setflag
+	return pEvent->SetFlag;
+}
+
+void SET_EVENT( EVENT_HNDL* pEvent )
+{
+	DWORD LockFlag;
+
+	// if the event is cleared then
+	// set the flag, wake up all waiting tasks.
+	ACQUIRE_LOCK( &pEvent->FlagLock, LockFlag );
+	if ( !pEvent->SetFlag )
+	{
+		int cnt;
+		pEvent->SetFlag = TRUE;
+		for  ( cnt=0; cnt<pEvent->WaitCnt; cnt++ )
+		{
+			wake_up_interruptible ( &pEvent->WaitQue  );
+		}
+	}
+	RELEASE_LOCK( &pEvent->FlagLock, LockFlag );
+}
+
+void SET_EVENT_FROM_ISR( EVENT_HNDL* pEvent )
+{
+	// if the event is cleared then
+	// set the flag, wake up all waiting tasks.
+	ACQUIRE_LOCK_AT_ISR( &pEvent->FlagLock );
+	if ( !pEvent->SetFlag )
+	{
+		int cnt;
+		pEvent->SetFlag = TRUE;
+		for  ( cnt=0; cnt<pEvent->WaitCnt; cnt++ )
+		{
+			wake_up_interruptible ( &pEvent->WaitQue  );
+		}
+	}
+	RELEASE_LOCK_AT_ISR( &pEvent->FlagLock );
+}
+
+void RESET_EVENT( EVENT_HNDL* pEvent )
+{
+	DWORD LockFlag;
+
+	// clear the event flag
+	ACQUIRE_LOCK( &pEvent->FlagLock, LockFlag );
+	pEvent->SetFlag = FALSE;
+
+	// empty out the queue
+	while ( waitqueue_active( &pEvent->WaitQue ) )
+		interruptible_sleep_on( &pEvent->WaitQue );
+
+	RELEASE_LOCK( &pEvent->FlagLock, LockFlag );
+}
+
+
+EXPORT_SYMBOL(INIT_EVENT);
+EXPORT_SYMBOL(WAIT_EVENT);
+EXPORT_SYMBOL(SET_EVENT);
+EXPORT_SYMBOL(SET_EVENT_FROM_ISR);
+EXPORT_SYMBOL(RESET_EVENT);
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/Makefile linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/Makefile
--- linux-2.4.29/arch/armnommu/mach-cx821xx/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,50 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET	:= cx821xx.o
+
+# Object file lists.
+
+obj-y		:= arch.o cnxtbsp.o cnxttimer.o cnxtirq.o \
+		   eeprom.o gpio.o gpioisr.o hstif.o irq.o LnxTools.o \
+		   pwrmanag.o sysalib.o sysdev.o syslib.o sysmem.o time.o \
+		   ostimer.o gptimer.o 
+ifeq ($(CONFIG_CNXT_FLASH),y)
+obj-y		+= cnxtflash.o cnxtflashio.o
+endif
+ifneq ($(CONFIG_CNXT_ADSL),)
+obj-y		+= cacheenb.o cnxtadsl.o cnxtsio.o dma.o dmasrv.o \
+		   dsl.o dslbase.o dslisr.o iterate.o sysserial.o
+endif
+ifneq ($(CONFIG_CNXT_GSHDSL),)
+obj-y		+= cacheenb.o cnxtadsl.o cnxtsio.o dma.o dmasrv.o \
+		   dsl.o dslbase.o dslisr.o iterate.o sysserial.o
+endif
+ifeq ($(CONFIG_BD_TIBURON),y)
+obj-y		+= tiburon-softreset.o
+endif
+obj-m		:=
+obj-n		:=
+obj-		:=
+
+export-objs	:= cnxtbsp.o cnxttimer.o cnxtirq.o eeprom.o gpio.o gpioisr.o irq.o \
+	           LnxTools.o pwrmanag.o ostimer.o gptimer.o
+ifeq ($(CONFIG_CNXT_FLASH),y)
+export-objs	+= cnxtflash.o
+endif
+ifneq ($(CONFIG_CNXT_ADSL),)
+export-objs	+= cnxtadsl.o cnxtsio.o dma.o dmasrv.o dslbase.o iterate.o
+endif
+ifneq ($(CONFIG_CNXT_GSHDSL),)
+export-objs	+= cnxtadsl.o cnxtsio.o dma.o dmasrv.o dslbase.o iterate.o
+endif
+
+obj-$(CONFIG_LEDS) += leds.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/mm.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/mm.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/mm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/mm.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,41 @@
+/*
+ *  linux/arch/arm/mach-ebsa110/mm.c
+ *
+ *  Copyright (C) 1998-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Extra MM routines for the EBSA-110 architecture
+ */
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+#include <asm/mach/map.h>
+ 
+static struct map_desc cnxt_io_desc[] __initdata = {
+	/*
+	 * sparse external-decode ISAIO space
+	 */
+	{ IRQ_STAT,    TRICK4_PHYS, PGDIR_SIZE,  DOMAIN_IO, 0, 1, 0, 0 }, /* IRQ_STAT/IRQ_MCLR */
+	{ IRQ_MASK,    TRICK3_PHYS, PGDIR_SIZE,  DOMAIN_IO, 0, 1, 0, 0 }, /* IRQ_MASK/IRQ_MSET */
+	{ SOFT_BASE,   TRICK1_PHYS, PGDIR_SIZE,  DOMAIN_IO, 0, 1, 0, 0 }, /* SOFT_BASE */
+	{ PIT_BASE,    TRICK0_PHYS, PGDIR_SIZE,  DOMAIN_IO, 0, 1, 0, 0 }, /* PIT_BASE */
+
+	/*
+	 * self-decode ISAIO space
+	 */
+	{ ISAIO_BASE,  ISAIO_PHYS,  ISAIO_SIZE,  DOMAIN_IO, 0, 1, 0, 0 },
+	{ ISAMEM_BASE, ISAMEM_PHYS, ISAMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
+	LAST_DESC
+};
+
+void __init cnxt_map_io(void)
+{
+	iotable_init(cnxt_io_desc);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/ostimer.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/ostimer.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/ostimer.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/ostimer.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,233 @@
+/****************************************************************************
+*
+*	Name:			ostimer.c
+*
+*	Description:	OS specific timing functions
+*
+*	Copyright:		(c) 2003 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   lewisrc  $
+*  $Revision:   1.0  $
+*  $Modtime:   Jul 18 2003 14:03:40  $
+****************************************************************************/
+
+#include <linux/config.h>
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/bspcfg.h>
+#include <asm/arch/cnxtbsp.h>
+#include <asm/arch/OsTools.h>
+#include <asm/arch/ostimer.h>
+#include <asm/arch/gptimer.h>
+//#include "cnxtirq.h"
+//#include "gpio.h"
+//#include "ListP.h"
+
+static EVENT_HNDL taskdelayEventTbl[NUMBER_OF_GP_TIMERS];	// Array of all delay events
+static int taskdelayPidTbl [NUMBER_OF_GP_TIMERS];			// Array of PIDs of each task delay
+/******************************************************************************
+FUNCTION:	sysClkRateGet
+ABSTRACT:
+DETAILS:
+*******************************************************************************/
+int sysClkRateGet ( void )
+{
+	return HZ ;
+}	
+
+
+/******************************************************************************
+FUNCTION:	CnxtGetTime
+ABSTRACT:	Returns the a running time value in milliseconds
+DETAILS:	
+*******************************************************************************/
+DWORD CnxtGetTime ( void )
+{
+	return jiffies * (1000/HZ) ;
+}	
+
+
+/******************************************************************************
+FUNCTION:	tickGet
+ABSTRACT:
+DETAILS:
+*******************************************************************************/
+ULONG tickGet ( void )
+{
+	return jiffies ;
+}
+
+
+/******************************************************************************
+FUNCTION:	SysTimerDelay
+ABSTRACT:
+INPUTS:		UINT32 uMicroSec = number of microseconds to delay minus 1
+OUTPUTS:	TRUE = delay succeeded,  FALSE = delay failed.
+DETAILS:	Do not use in the task or interrupt context, this is for HW delay loop.
+*******************************************************************************/
+int sysTimerDelay ( UINT32 uMicroSec )
+{
+
+	/* Don't allow a delay any longer than 65535 useconds */
+	if ( (uMicroSec > 0xFFFF) || (uMicroSec == 0) )
+	{
+		return FALSE ;
+	}
+
+	udelay ( uMicroSec ) ;
+	return TRUE ;
+}
+
+
+
+/******************************************************************************
+FUNCTION:	taskdelayCallback
+ABSTRACT:	Callback routine that runs when delay timer expires
+*******************************************************************************/
+static void taskdelayCallback ( void *pContext )
+{
+	EVENT_HNDL	*pTaskDelayEvent = (EVENT_HNDL *) pContext ;
+
+	SET_EVENT_FROM_ISR ( pTaskDelayEvent );
+}
+
+
+
+/******************************************************************************
+FUNCTION:	TaskDelayConnect
+ABSTRACT:	Connects the desired timer to the delay function
+DETAILS:	You must use a different timer for each task.
+RETURN:		TRUE = function connected
+			FALSE = function not connected
+*******************************************************************************/
+int TaskDelayConnect
+(
+	WORD		TimerIndex
+)
+{
+	// Initialize event
+	INIT_EVENT ( &taskdelayEventTbl[TimerIndex] ) ; 
+
+	// Associate PID with this task delay
+	taskdelayPidTbl [TimerIndex] = current->pid ;
+
+	// Connect timer and delay
+	return GPTimerConnect ( TimerIndex, taskdelayCallback, &taskdelayEventTbl[TimerIndex] ) ;
+}
+
+
+
+/******************************************************************************
+FUNCTION:	TaskDelayMsec
+ABSTRACT:	
+DETAILS:	If duration passed in is smaller than current system 
+			timer resolution than by default it will be forced   
+			to current resolution.
+RETURN:
+*******************************************************************************/
+int TaskDelayMsec
+(
+	DWORD	TimeDuration
+)
+{
+	WORD	TimerIndex ;
+
+	// If the delay is zero then just give any other
+	// waiting tasks a chance to run.
+	if ( TimeDuration < 1 )
+	{
+		schedule ();
+	}
+	else
+	{
+		// find this task's TimerIndex
+		for ( TimerIndex = 0 ; TimerIndex < NUMBER_OF_GP_TIMERS ; TimerIndex++ )
+		{
+			// if found
+			if ( taskdelayPidTbl [TimerIndex] == current->pid )
+			{
+				break ;
+			}
+		}
+
+		// if we have a GP timer to use
+		if ( TimerIndex < NUMBER_OF_GP_TIMERS )
+		{
+			int Error ;
+
+			// Reset the event before we start the timer that will set it.
+			RESET_EVENT ( &taskdelayEventTbl[TimerIndex] ) ;
+
+			// start gp timer
+			Error = GPTimerStart ( TimerIndex,  (TimeDuration * 1000), FALSE ) ;
+			if ( Error )
+			{
+				printk ( KERN_DEBUG "cnxttimer.c: General Purpose timer did not start.\n") ;
+				GPTimerStop ( TimerIndex ) ; 
+				return Error ;
+			}
+			
+			// Wait on event to be set or timeout to expire
+			if ( ! WAIT_EVENT ( &taskdelayEventTbl[TimerIndex], TimeDuration + 100 ) )
+			{
+				printk ( KERN_DEBUG "cnxttimer.c: Delay expired without event being signaled.\n") ;
+				GPTimerStop ( TimerIndex ) ; 
+			}
+		}
+		else // otherwise use OS
+		{
+			if ( TimeDuration < 1 )
+			{
+				schedule () ;
+			}
+			else
+			{
+				int NumTickDelay;
+
+				// Add 999 to round up to the closest ticks
+				NumTickDelay = ( ((TimeDuration * HZ) + 999) / 1000) ;
+
+				// Add one to guarantee at least 1 tick delay
+				if ( NumTickDelay < 1 )
+				{
+					NumTickDelay++ ;
+				}
+
+				current->state = TASK_INTERRUPTIBLE ;
+				schedule_timeout ( NumTickDelay ) ;
+			}
+			
+		}
+	}
+
+	return 0 ;
+}
+
+
+EXPORT_SYMBOL(sysClkRateGet);
+EXPORT_SYMBOL(CnxtGetTime);
+EXPORT_SYMBOL(tickGet);
+EXPORT_SYMBOL(sysTimerDelay);
+EXPORT_SYMBOL(TaskDelayConnect);
+EXPORT_SYMBOL(TaskDelayMsec);
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/plldef.h linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/plldef.h
--- linux-2.4.29/arch/armnommu/mach-cx821xx/plldef.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/plldef.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,74 @@
+/****************************************************************************
+*
+*	Name:			plldef.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002, 2003 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************/
+
+#ifndef PLLDEF_H
+#define PLLDEF_H
+
+/* Setup the PLL defines  */
+#define PLL_F		0x350068
+#define PLL_B		0x35006C
+
+/* PLL bit definitions */
+#define P52_PLL_CR_SLOW  BIT28
+#define P52_PLL_CLK_RATE (BIT25 | BIT24)
+
+#define RUSHMORE_PLL_CR_SLOW     BIT3
+#define RUSHMORE_PLL_CLK_RATE    (BIT2 | BIT1 | BIT0)
+
+/* P52 FCLK/UCLK defines */
+/* ARM and USB */
+#define P52_PLL_FAST_168MHZ		0x03dc8859
+#define P52_PLL_FAST_144MHZ 	0x02D874DF  /* Divide by 3, F=144Mhz, U=72Mhz */
+#define P52_PLL_FAST_120MHZ   0x01D46164  /* Divide by 3, F=120Mhz, U=60Mhz */
+#define P52_PLL_FAST_96MHZ    0x0095BD38  /* Divide by 4, F=96Mhz,  U=48Mhz */
+
+#define P52_PLL_SLOW_144MHZ 	0x12D874DF  /* Slow down FCLK, divide by 3, F=72Mhz, U=72Mhz */
+#define P52_PLL_SLOW_120MHZ   0x11D46164  /* Slow down FCLK, divide by 3, F=60Mhz, U=60Mhz */
+#define P52_PLL_SLOW_96MHZ    0x1095BD38  /* Slow down FCLK, divide by 4, F=48Mhz, U=48Mhz */
+
+/* BCLK/PCLK defines */
+/* ASB and APB */
+#define P52_PLL_FAST_125MHZ 	0x02D53AC8  /* Divide by 3, B=125Mhz, P=62.5Mhz */
+#define P52_PLL_FAST_100MHZ 	0x0196A51A  /* Divide by 4, B=100Mhz, P=50Mhz   */
+#define P52_PLL_FAST_75MHZ    0x0090FBD4  /* Divide by 4, B=75Mhz,  P=37.5Mhz */
+
+#define P52_PLL_SLOW_125MHZ 	0x12D53AC8  /* Divide by 3, B=62.5Mhz, P=31.25Mhz */
+#define P52_PLL_SLOW_100MHZ 	0x1196A51A  /* Divide by 4, B=50Mhz,   P=25Mhz   */
+
+/* Rushmore FCLK/UCLK defines */
+/* ARM and USB */
+#define RUSHMORE_PLL_FAST_168MHZ	0x7
+#define RUSHMORE_PLL_FAST_144MHZ    0x5  /* Divide by 3, F=144Mhz, U=48Mhz */
+#define RUSHMORE_PLL_FAST_120MHZ    0x4  /* Divide by 3, F=120Mhz, U=48Mhz */
+#define RUSHMORE_PLL_FAST_96MHZ     0x3  /* Divide by 3, F=96Mhz,  U=48Mhz */
+
+/* BCLK/PCLK defines */
+/* ASB and APB */
+#define RUSHMORE_PLL_FAST_125MHZ    0x4  /* Divide by 3, B=125Mhz, P=62.5Mhz */
+#define RUSHMORE_PLL_FAST_100MHZ 	0x3  /* Divide by 3, B=100Mhz, P=50Mhz   */
+#define RUSHMORE_PLL_FAST_75MHZ     0x2  /* Divide by 3, B=75Mhz,  P=37.5Mhz */
+
+#endif	/* PLLDEF_H */
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/project.h linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/project.h
--- linux-2.4.29/arch/armnommu/mach-cx821xx/project.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/project.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,37 @@
+/****************************************************************************
+*
+*	Name:			project.h
+*
+*	Description:	This header file contains all project specific parameters
+*					for the system.
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:22:08  $
+****************************************************************************/
+
+#ifndef PROJECT_H
+
+// define if the processor is little or big endian orientation
+#define LITTLE_ENDIAN_MEMORY
+
+#endif
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/pwrmanag.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/pwrmanag.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/pwrmanag.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/pwrmanag.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,264 @@
+/****************************************************************************
+*
+*	Name:			pwrmanag.c
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 - 2003  Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   lewisrc  $
+*  $Revision:   1.2  $
+*  $Modtime:   Jul 16 2003 09:30:42  $
+****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/ptrace.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/bspcfg.h>
+#include <asm/arch/syslib.h>
+#include <asm/arch/pwrmanag.h>
+#include "plldef.h"
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/cnxtbsp.h>
+#include <asm/arch/OsTools.h>
+#include <asm/arch/cnxttimer.h>
+#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+#include <asm/arch/hwio.h>
+#include <asm/arch/cardinfo.h>
+#endif
+
+void sysDevicePowerCtl(eHWDevice eDeviceType, eHWPowerState ePowerState)
+{
+   switch (eDeviceType)
+   {
+      case DEVICE_ARMCORE:
+         sysARMCOREPwrCtl(ePowerState);
+         break;
+
+      case DEVICE_SDRAM:
+         sysSDRAMPwrCtl(ePowerState);
+         break;
+
+      #if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+         case DEVICE_FALCON:
+            sysFALCONPwrCtl(ePowerState);
+            break;
+
+         case DEVICE_AFE:
+            sysAFEPwrCtl(ePowerState);
+            break;
+      #endif //CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+
+      case DEVICE_EPHY:
+            sysEPHYPwrCtl(ePowerState);
+            break;
+
+      default:
+         break;
+   }
+}
+
+
+void sysARMCOREPwrCtl(eHWPowerState ePowerState)
+{
+   UINT32 volatile *pCtlRegF = 0;
+   UINT32 volatile *pCtlRegB = 0;
+
+   pCtlRegF = (UINT32 volatile *) PLL_F;
+   pCtlRegB = (UINT32 volatile *) PLL_B;
+
+   switch (ePowerState)
+   {
+      case DEVICE_SLOW_SPEED:
+         *pCtlRegF |= PLL_CR_SLOW;
+         sysTimerDelay(10000);
+         *pCtlRegB |= PLL_CR_SLOW;
+         sysTimerDelay(10000);
+         break;
+
+      case DEVICE_NORMAL_SPEED:
+         *pCtlRegF &= (~PLL_CR_SLOW);
+         sysTimerDelay(10000);
+         *pCtlRegB &= (~PLL_CR_SLOW);
+         sysTimerDelay(10000);
+         break;
+
+      case DEVICE_OFF:
+      case DEVICE_SLEEP:
+      case DEVICE_RESET:
+      default:
+         break;
+   }
+}
+
+
+void sysSDRAMPwrCtl(eHWPowerState ePowerState)
+{
+   UINT32 volatile *pCtlReg = 0;
+
+   pCtlReg = (UINT32 volatile *) EXT_MEM_CTL;
+
+   switch (ePowerState)
+   {
+      case DEVICE_ON:
+         *pCtlReg |= EXT_SDRAM_ENA;
+         HWSTATE.bSDRAMState = TRUE;
+         sysTimerDelay(10000);
+         break;
+
+      case DEVICE_OFF:
+         *pCtlReg &= (~EXT_SDRAM_ENA);
+         HWSTATE.bSDRAMState = FALSE;
+         sysTimerDelay(10000);
+         break;
+
+      case DEVICE_SLEEP:
+      case DEVICE_RESET:
+      default:
+         break;
+   }
+}
+
+
+#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+void sysFALCONPwrCtl(eHWPowerState ePowerState)
+{
+	switch (ePowerState)
+	{
+		case DEVICE_ON:
+			/* Enable Falcon Power */
+			WriteGPIOData( GPOUT_F2PWRDWN, 0 );
+			sysTimerDelay(10000);
+
+			/* Remove Falcon Reset */
+			WriteGPIOData( GPOUT_F2RESET, 1 );
+			sysTimerDelay(10000);
+			break;
+
+		case DEVICE_OFF:
+			/* Disable Falcon Power */
+			WriteGPIOData( GPOUT_F2PWRDWN, 1 );
+
+			/* Put Falcon in Reset */
+			WriteGPIOData( GPOUT_F2RESET, 0 );
+			WriteGPIOData( GPOUT_F2_SCANEN, 1 );
+
+			WriteGPIOData( GPOUT_OUTER_PAIR, 0 );
+			// Inner pair
+			WriteGPIOData( GPOUT_INNER_PAIR, 0 );
+
+			HWSTATE.eADSLLineState = ADSL_DISABLE;
+			HWSTATE.eADSLRequestLineState= ADSL_DISABLE; 
+			HWSTATE.dwLineStatus= HW_IO_MODEM_STATUS_DOWN;
+			break;
+
+		case DEVICE_RESET:
+			/* Put Falcon in Reset */
+			WriteGPIOData( GPOUT_F2RESET, 0);
+			sysTimerDelay(100000);
+			/* Take Falcon out of Reset */
+			WriteGPIOData( GPOUT_F2RESET, 1 );
+			sysTimerDelay(100000);
+			break;
+
+		case DEVICE_SLEEP:
+			default:
+			break;
+	}
+}
+
+#endif // CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+
+#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+
+void sysAFEPwrCtl(eHWPowerState ePowerState)
+{
+   switch (ePowerState)
+   {
+      case DEVICE_ON:
+          /* Power up Line Driver */
+         #ifdef DL10_D325_003
+            WriteGPIOData( GPOUT_LDRVPWR, 1 );
+         #else
+            WriteGPIOData( GPOUT_LDRVPWR, 0 );
+         #endif
+         sysTimerDelay(10000);
+
+         /* Take AFE out of Reset*/
+         WriteGPIOData( GPOUT_AFERESET, 1 );
+         sysTimerDelay(10000);
+         break;
+
+      case DEVICE_OFF:
+         /* Power down Line Driver */
+         #ifdef DL10_D325_003 
+            WriteGPIOData( GPOUT_LDRVPWR, 0 );
+         #else
+            WriteGPIOData( GPOUT_LDRVPWR, 1 );
+         #endif
+
+         /* Place AFE in Reset*/
+         WriteGPIOData( GPOUT_AFERESET, 0 );
+         break;
+
+      case DEVICE_RESET:
+         /* Place AFE in Reset */
+         WriteGPIOData( GPOUT_AFERESET, 0 );
+         /* Hold reset for some time */
+         sysTimerDelay(100000);
+         /* Take AFE out of Reset*/
+         WriteGPIOData( GPOUT_AFERESET, 1 );
+         sysTimerDelay(100000);
+         break;
+
+      case DEVICE_SLEEP:
+      default:
+         break;
+   }
+}
+
+#endif // CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+
+void sysEPHYPwrCtl(eHWPowerState ePowerState)
+{
+   switch (ePowerState)
+   {
+      case DEVICE_ON:
+         break;
+
+      case DEVICE_OFF:
+         break;
+
+      case DEVICE_RESET:
+         #if DL10_D325_003 || CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE
+          WriteGPIOData( GPOUT_EMACRESET, 0 );
+          WriteGPIOData( GPOUT_EMACRESET, 1 );
+          sysTimerDelay(2000);  /* 2 ms */
+         #endif
+   }
+}
+
+
+EXPORT_SYMBOL(sysDevicePowerCtl);
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/ramlinux.lds linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/ramlinux.lds
--- linux-2.4.29/arch/armnommu/mach-cx821xx/ramlinux.lds	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/ramlinux.lds	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,122 @@
+/* ld script to make ARM Linux kernel
+ * taken from the i386 version by Russell King
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ */
+/*INCLUDE arch/armnommu/mach-cx821xx/romfs.ld*/
+OUTPUT_ARCH(arm)
+ENTRY(stext)
+SECTIONS
+{
+
+	. = 0x800000;
+	.init : {			/* Init code and data		*/
+		_stext = .;
+		__init_begin = .;
+			*(.text.init)
+		__proc_info_begin = .;
+			*(.proc.info)
+		__proc_info_end = .;
+		__arch_info_begin = .;
+			*(.arch.info)
+		__arch_info_end = .;
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		__initcall_end = .;
+		. = ALIGN(4096);
+		__init_end = .;
+	}
+
+	/DISCARD/ : {			/* Exit code and data		*/
+		*(.text.exit)
+		*(.data.exit)
+		*(.exitcall.exit)
+	}
+
+	.text : {			/* Real text segment		*/
+		_text = .;		/* Text and read-only data	*/
+			*(.text)
+			*(.fixup)
+			*(.gnu.warning)
+			*(.text.lock)	/* out-of-line lock text */
+			*(.rodata)
+			*(.glue_7)
+			*(.glue_7t)
+			*(.kstrtab)
+		. = ALIGN(16);
+		__start___ex_table = .;	/* Exception table		*/
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;	/* Kernel symbol table		*/
+			*(__ksymtab)
+		__stop___ksymtab = .;
+
+		__start___kallsyms = .; /* All kernel symbols           */
+			*(__kallsyms)
+		__stop___kallsyms = .;
+
+
+		*(.got)			/* Global offset table		*/
+
+		_etext = .;		/* End of text section		*/
+	}
+
+	. = ALIGN(8192);
+
+	__data_start = .;
+	__data_rom_start = .;
+	.data : {
+		/*
+		 * first, the init task union, aligned
+		 * to an 8192 byte boundary.
+		 */
+		*(.init.task)
+
+		/*
+		 * then the cacheline aligned data
+		 */
+		. = ALIGN(32);
+		*(.data.cacheline_aligned)
+
+		/*
+		 * and the usual data section
+		 */
+		*(.data)
+		CONSTRUCTORS
+
+		. = ALIGN(32);	/* To be sure to align .fs . OZH */
+		_edata = .;
+		
+	}
+
+	.fs :	{
+		_romfs = ABSOLUTE (.);
+		/*. = . + romfs_size;*/
+		. = . + 802816;
+		_end_romfs = ABSOLUTE (.);
+		}
+
+	.bss : {
+		__bss_start = .;	/* BSS				*/
+		*(.bss)
+		*(COMMON)
+		_end = . ;
+	}
+
+	. = ALIGN(8192);
+	_end_kernel = . ;
+
+					/* Stabs debugging sections.	*/
+	.stab 0 : { *(.stab) }
+	.stabstr 0 : { *(.stabstr) }
+	.stab.excl 0 : { *(.stab.excl) }
+	.stab.exclstr 0 : { *(.stab.exclstr) }
+	.stab.index 0 : { *(.stab.index) }
+	.stab.indexstr 0 : { *(.stab.indexstr) }
+	.comment 0 : { *(.comment) }
+}
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/sysalib.S linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/sysalib.S
--- linux-2.4.29/arch/armnommu/mach-cx821xx/sysalib.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/sysalib.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,177 @@
+/****************************************************************************
+*
+*	Name:			sysalib.S
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:22:08  $
+****************************************************************************/
+
+/*
+NOTE
+The routines in this module don't use the "C" frame pointer %r11@ ! or
+establish a stack frame.
+
+*/
+
+
+#define _ASMLANGUAGE
+
+#include <linux/linkage.h>
+#include <linux/config.h>
+#include <asm/proc/assembler.h>
+#include <asm/proc/ptrace.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+#include <asm/hardware.h>
+#include <asm/arch/bspcfg.h>
+#include <asm/arch/cnxtbsp.h>
+#include <asm/arch/hstif.h>
+#include "plldef.h"
+
+/* internals */
+
+
+	.globl	_sysInit		/* start of system code */
+    .globl  _sysCacheEnable
+    .globl  _sysCacheDisable
+    .globl  _sysGetDeviceType
+
+	.text
+	.balign 4
+
+
+/*******************************************************************************
+*
+* sysInit 
+*
+* NOTE:
+*
+* RETURNS:	N/A
+*
+*******************************************************************************/
+
+ENTRY(sysInit)
+
+	STMDB	R13!, { R0-R4, LR }
+
+	/* Disable device interrupts */
+	LDR	r2, =PIC_TOP_IMR_IRQ       /* R2->interrupt controller */
+	LDR	r1, =PIC_DISABLE_MASK
+	STR	r1, [r2]
+
+	/* Return value is in R0, do not care if R14 is changed */
+
+#ifndef DEVICE_YELLOWSTONE
+	BL _sysGetDeviceType
+	MOV R3,R0
+	BL _sysGetBusModeForDevice
+
+	/* Initial MMU value is fastbus */
+	MOV	r2, #MMU_INIT_VALUE
+
+	/* Setup MMU Control Register */
+	/* r0 contains the bus mode (async or fast bus) */
+	ORR	r2, r2, r0					@ asynchronous clock mode
+	MCR	p15, 0, r2, c1, c0, 0		@ Write to MMU CR
+#endif
+
+#ifndef DEVICE_YELLOWSTONE
+	BL  _sysCacheDisable
+
+	#if PLL_CONTROL
+	    MOV R0, R3						@ Pass in device type
+	    BL _sysGetPLLFValForDevice
+
+	 	LDR	r2, =PLL_F
+		STR	r0, [r2]
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+
+	    MOV R0, R3					@ Pass in device type
+	    BL _sysGetPLLBValForDevice
+	    LDR	r2, =PLL_B
+		STR	r0, [r2]
+
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+    #endif  /* PLL_CONTROL */
+
+	#if HOSTINTERFACE_CONTROL
+		/* Switch boot map to run map (RAM at address 0000),*/
+	    /* and set SDRAM size appropriately. */
+		LDR	r2, =HST_CTRL
+	    
+		#if (PHYS_SDRAM_SIZE == 8)
+			MOV	r1, #HSTCTRL_RUN_MAP | HSTCTRL_8MEG
+		#elif (PHYS_SDRAM_SIZE == 4)
+			MOV	r1, #HSTCTRL_RUN_MAP | HSTCTRL_4MEG
+		#else
+			MOV	r1, #HSTCTRL_RUN_MAP
+	    #endif
+
+	    STR r1, [r2]
+		NOP								@ just in case
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+		NOP
+	#endif /* end of HOSTINTERFACE_CONTROL */
+
+	BL  _sysGetCacheType	@ R0 contains cache type when function returns
+    BL  _sysCacheEnable
+
+#endif	/* end of DEVICE_YELLOWSTONE */
+	LDMIA	R13!, { R0-R4, PC }
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/sysdev.S linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/sysdev.S
--- linux-2.4.29/arch/armnommu/mach-cx821xx/sysdev.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/sysdev.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,555 @@
+/****************************************************************************
+*
+*	Name:			SYSDEV.S
+*
+*	Description:	
+*
+*	Copyright:		(c) 1999 Conexant Systems Inc.
+*
+*****************************************************************************
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+*****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:22:10  $
+****************************************************************************/
+
+#define _ASMLANGUAGE
+
+#include <linux/linkage.h>
+#include <asm/proc/assembler.h>
+#include <asm/arch/bspcfg.h>
+#include <asm/arch/cnxtbsp.h>
+#include <asm/arch/hstif.h>
+#include "plldef.h"
+
+        .data
+    .globl  _sysCacheEnable
+    .globl  _sysCacheDisable
+    .globl  _sysGetDeviceType
+	.globl  _sysGetBusModeForDevice
+    .globl  _sysGetPLLBValForDevice
+    .globl  _sysGetPLLFValForDevice
+    .globl  _sysGetCacheType
+	.globl	_sysSoftReset
+	.text
+	.balign 4
+
+/*******************************************************************************
+*
+* sysGetDeviceType - determines device type
+*
+* This function determines the device type and stores it in R3
+* NOTE:		This routine should not be called by the user.
+*
+* RETURNS:	N/A
+*******************************************************************************/
+
+#define P5X00_DEV_ID_MASK			0xF000000F
+#define RUSH_X10_45_DEV_ID_MASK		0xFFFF0000
+
+#define CACHE_WT 0
+#if 1
+	#define CACHE_WB 1
+#else
+	#define CACHE_WB 0
+#endif
+
+#define   DEVICE_P5200X10		0
+#define   DEVICE_P5200X180		1
+#define   DEVICE_P5300			2
+#define   DEVICE_RUSHMORE		3
+#define   DEVICE_RUSHMORE_X45	4
+#define   DEVICE_RUSHMORE_X50	5
+#define   DEVICE_OLDFAITHFUL    6
+
+	/*
+    ******************************************************************************
+    ** This routine must have the device in the run-time map mode to work properly
+    ******************************************************************************
+    */
+
+ENTRY(_sysGetDeviceType)
+#ifdef DEVICE_YELLOWSTONE
+	MOV R0,#DEVICE_OLDFAITHFUL		/* 6 */
+#else
+	LDR	r2, =DEVICE_ID_REG
+	LDR	r3, [r2]
+
+	MOV R0,#DEVICE_P5200X10			/* 0 */
+	LDR r2,=P5X00_DEV_ID_MASK
+	AND r2,r3,r2
+	LDR R1,=P5200X10_DEV_ID
+	CMP	R1,R2
+	BEQ finish
+
+	MOV R0,#DEVICE_P5200X180		/* 1 */
+	LDR r2,=P5X00_DEV_ID_MASK
+	AND r2,r3,r2
+	LDR R1,=P5200X180_DEV_ID
+	CMP	R1,R2
+	BEQ finish
+
+	MOV R0,#DEVICE_P5300		    /* 2 */
+	LDR r2,=P5X00_DEV_ID_MASK
+	AND r2,r3,r2
+	LDR R1,=P5300_DEV_ID
+	CMP	R1,R2
+	BEQ finish
+
+	LDR r2,=RUSH_X10_45_DEV_ID_MASK
+	AND r2,r3,r2
+	LDR R1,=RUSH_X10_45_DEV_ID
+	CMP	R1,R2
+	BNE checkRush50
+	LDR	r1, =ROM_DEVICE_ID_REG
+	LDR	r2, [r1]
+	MOV R1,#0
+	MOV R0,#DEVICE_RUSHMORE		    /* 3 */
+	CMP	R1,R2
+	BEQ finish
+	MOV R0,#DEVICE_RUSHMORE_X45		/* 4 */
+	B finish
+
+checkRush50:
+	MOV R0,#DEVICE_RUSHMORE_X50		/* 5 */
+#endif
+
+finish:
+	MOV	pc, lr
+
+/*********************************************************************
+ *********************************************************************/
+/* Device type required in R0 */
+ENTRY(_sysCacheEnable)
+
+	STMDB	R13!, { R0-R4, LR }
+
+#if defined(CONFIG_ARCH_CX821XX) || defined(CONFIG_ARCH_P52)
+
+    /*
+     * Cache type for device already determined at this point. R0 contains
+	 * either CACHE_WB or CACHE_WT. Move it to r3
+	 */
+	
+	MOV 	r3, r0
+
+    ldr     R1,=0x0000003F     @ ; Cacheable 0x00000000 ~ 0xFFFFFFFF (4 GB)
+    mcr     p15,0,R1,c6,c0,1   @ ; Inst Region 0 (C0)
+
+    ldr     R1,=0x0000003F     @ ; non-Cacheable 0x00000000 ~ 0xFFFFFFFF (4Gb) Background region
+    mcr     p15,0,R1,c6,c0,0   @ ; Data Region 0 (C0)
+
+	/*
+	* Control GBd bit (set to 0)
+	*
+	* Enable data bufferable enables write-back when cache is enabled,
+	* and disable data bufferable enables write-through when cache is enabled.
+	*/
+	mrc     p15,0,R0,c3,c0,0
+	and		r0,r0,#0xFD		   @ ; Mask off the data region 1 bit
+	mov		r1,r3,LSL #1	   @ ; R3 contains WB or WT 	
+	orr     R0,R0,R1		   @ ; Data region 1, enable data bufferable
+	mcr     p15,0,R0,c3,c0,0
+
+	/*
+	* Region size encodings
+	* 0x23 = 0.25M
+	* 0x25 = 0.5M
+	* 0x27 = 1M
+	* 0x29 = 2M
+	* 0x2B = 4M
+	* 0x2D = 8M
+	*
+	* NOTE: The higher the region number the higher the priority of it's
+	*		attribute settings.  For example if the entire 8Mb of SDRAM is
+	* 		set to be cacheable by the region 1 settings, but the region
+	*		2 settings make 512k of some address of the 8Mb non-cacheable, then
+	*		those settings override those of region 1 for that specified address
+	*		range.
+	*/
+
+
+    ldr     R1,=0x0080002D	   @ ; Cacheable 0x00800000 ~ 0x0FFFFFF (8Mb) 
+    mcr     p15,0,R1,c6,c1,0   @ ; Data Region 1 (C1)
+
+#if 0
+    ldr     R1,=0x00FC0023     @ ; non-Cacheable 0x00FC0000 ~ 0x00FFFFFF (256kb)
+#else
+    ldr     R1,=0x00F80025     @ ; non-Cacheable 0x00F80000 ~ 0x00FFFFFF (512kb)
+#endif
+    mcr     p15,0,R1,c6,c2,0   @ ; Data Region 2 (C2)
+
+    mov     R1,#0x01           @ ; (C0 means nothing here)
+    mcr     p15,0,R1,c2,c0,1   @ ; enable Inst Region 0 , disable Region 1~7
+
+	mov     R1,#0x02
+    mcr     p15,0,R1,c2,c0,0   @ ; enable caching Data regions 1, disable caching regions 0,2-7
+
+    mov     R1,#0x3
+    mcr     p15,0,R1,c5,c0,1   @ ; enable full access on Inst Region 0 
+
+    mov     R1,#0x3F
+    mcr     p15,0,R1,c5,c0,0   @ ; enable full access on Data Regions 0~2
+
+/* Read, Modify, and Write the control register now */
+
+	mrc     p15, 0, R0, c1, c0, 0	@ get control register
+	orr		r0, r0, #0x0001			@ Enable Protection Unit
+		
+	#ifdef CONFIG_CPU_ARM940_D_CACHE_ON
+		orr	r0, r0, #0x0004			@ Enable D cache
+	#endif
+
+	#ifdef CONFIG_CPU_ARM940_I_CACHE_ON
+		orr	r0, r0, #0x1000			@ I Cache on
+	#endif
+
+	mcr	p15, 0, r0, c1, c0		@ Update the control register now
+								@ with all of the new settings
+#endif
+
+	LDMIA	R13!, { R0-R4, PC }
+
+/***************************************************************************
+ * sysCacheDisable - Flush and disable I and D caches
+ **************************************************************************/
+ENTRY(_sysCacheDisable)
+	/*
+	* We would like to discard the contents of the Write-Buffer
+	* altogether, but there is no facility to do this. Failing that,
+	* we do not want any pending writes to happen at a later stage,
+	* so drain the Write-Buffer, i.e. force any pending writes to
+	* happen now. Then flush, i.e. invalidate, all cache(s).
+	*/
+	LDR	r1, =SYSTEM_CACHE_UNCACHED_ADRS	/* R1 -> uncached area */
+	LDR	r1, [r1]						/* drain write-buffer  */
+
+    /*********************************/
+	/* Clean and flush D cache       */
+    /*********************************/
+	MOV	r1, #0					/* Initalize line counter, r1 */
+Flushouter_loop:
+	MOV	r0, #0					/* Initialize segment counter, r0 */
+Flushinner_loop:
+	ORR	r2, r1, r0				/* Make segement and line address */
+	MCR	p15, 0, r2, c7, c14, 1	/* Clean and flash that line */
+	ADD	r0, r0, #0x10			/* Increment segment counter */
+	CMP	r0, #0x40				/* Completed all four segments? */
+	BNE	Flushinner_loop
+	ADD	r1, r1, #0x04000000		/* Increment line counter */
+	CMP	r1, #0x0				/* Completed all lines? */
+	BNE	Flushouter_loop
+
+    /*********************************/
+	/* Disable D cache			     */
+    /*********************************/
+	MRC     p15, 0, R0, c1, c0, 0
+	BIC     R0, R0, #0x4
+	MCR     p15, 0, R0, c1, c0, 0
+
+    /*********************************/
+	/* Flush I cache			     */
+    /*********************************/
+	MOV	r1, #0
+	MCR	p15, 0, r1, c7, c5, 0
+
+    /*********************************/
+	/* Disable I cache			     */
+    /*********************************/
+	MRC     p15, 0, R0, c1, c0, 0
+	BIC     R0, R0, #0x1000
+	MCR     p15, 0, R0, c1, c0, 0 
+
+    NOP
+    NOP
+    NOP
+    NOP
+    NOP
+    NOP
+
+    /*********************************/
+	/* Disable Protection unit       */
+    /*********************************/
+	MRC     p15, 0, R0, c1, c0, 0
+	BIC     R0, R0, #0x1
+	MCR     p15, 0, R0, c1, c0, 0
+
+    /*********************************/
+	/* Disable all memory areas	     */
+    /*********************************/
+	MOV	r0, #0
+	MCR     p15,0,R0,c6,c0,1		/* instruction, area 0 */
+	MCR     p15,0,R0,c6,c0,0		/* data, area 0 */
+	MCR     p15,0,R0,c6,c1,1		/* instruction, area 1 */
+	MCR     p15,0,R0,c6,c1,0		/* data, area 1 */
+	MCR     p15,0,R0,c6,c2,1		/* instruction, area 2 */
+	MCR     p15,0,R0,c6,c2,0		/* data, area 2 */
+	MCR     p15,0,R0,c6,c3,1		/* instruction, area 3 */
+	MCR     p15,0,R0,c6,c3,0		/* data, area 3 */
+	MCR     p15,0,R0,c6,c4,1		/* instruction, area 4 */
+	MCR     p15,0,R0,c6,c4,0		/* data, area 4 */
+	MCR     p15,0,R0,c6,c5,1		/* instruction, area 5 */
+	MCR     p15,0,R0,c6,c5,0		/* data, area 5 */
+	MCR     p15,0,R0,c6,c6,1		/* instruction, area 6 */
+	MCR     p15,0,R0,c6,c6,0		/* data, area 6 */
+	MCR     p15,0,R0,c6,c7,1		/* instruction, area 7 */
+	MCR     p15,0,R0,c6,c7,0		/* data, area 7 */
+
+	MOV	pc, lr
+
+/***************************************************************************
+ * sysGetCacheType - Gets the data cache type (Writethrough or Writeback)
+ *					 for the device in R0
+ **************************************************************************/
+ENTRY(_sysGetCacheType)
+
+/*
+ * !!!!W A R N I N G!!!!!
+ * DO NOT TRY TO OPTIMIZE THIS BY MAKING IT INTO A TABLE
+ * VARIABLES WILL NOT WORK HERE!
+ */
+
+   /*
+    * Add 1 to device type in R0. Keep subtracting 1 later, when difference
+	* reaches zero, we have found our device.
+	*/
+   ADD r1, r0, #1
+
+   /* Assume Cache Writethrough as the default type */
+   MOV r0, #CACHE_WT
+
+#ifdef BUILD_BOOTROM
+   /* If we are building the boot rom, then return writethrough no matter which device */
+   B GetCacheTypeExit
+#else
+
+   SUBS r1, r1, #1				/* Device == 0, P52 CACHE_WT */
+   BEQ GetCacheTypeExit
+
+   SUBS r1, r1, #1				/* Device == 1, P52-X18 CACHE_WT */
+   BEQ GetCacheTypeExit
+
+   SUBS r1, r1, #1				/* Device == 2, P53 CACHE_WB*/
+   MOVEQ r0, #CACHE_WB
+   BEQ GetCacheTypeExit
+
+   SUBS r1, r1, #1				/* Device == 3, RUSHMORE CACHE_WB */
+   MOVEQ r0, #CACHE_WB
+   BEQ GetCacheTypeExit
+
+   SUBS r1, r1, #1				/* Device == 4, RUSHMORE X4.5 CACHE_WB */
+   MOVEQ r0, #CACHE_WB
+   BEQ GetCacheTypeExit
+
+   SUBS r1, r1, #1				/* Device == 5, RUSHMORE X5 CACHE_WB */
+   MOVEQ r0, #CACHE_WB
+   BEQ GetCacheTypeExit
+
+#endif /* BUILD_BOOTROM */
+   
+GetCacheTypeExit:
+	MOV	pc, lr
+
+
+/********************************************************************************
+ * sysGetBusModeForDevice: Pass in device type, this translates it and returns
+ *                         the correspoding bus mode for that device
+ *******************************************************************************/
+ENTRY(_sysGetBusModeForDevice)
+
+/*
+ * !!!!W A R N I N G!!!!!
+ * DO NOT TRY TO OPTIMIZE THIS BY MAKING IT INTO A TABLE 
+ * VARIABLES WILL NOT WORK HERE!
+ */
+ 
+   /*
+    * Add 1 to device type in R0. Keep subtracting 1 later, when difference
+	* reaches zero, we have found our device.
+	*/
+
+   ADD r1,r0,#1
+
+   /* Assume MMUCR_ASYNC mode since that is the majority. Only Rushmore uses Fastbus for now */
+   MOV r0,#MMUCR_ASYNC
+
+   SUBS r1,r1,#1		    /* Was Device Type equal to 0? */
+   BEQ GetBusModeExit
+
+   SUBS r1,r1,#1     		/* Was Device Type equal to 1? */
+   BEQ GetBusModeExit
+
+   SUBS r1,r1,#1    		/* Was Device Type equal to 2? */
+   BEQ GetBusModeExit
+
+   SUBS r1,r1,#1
+   MOVEQ r0,#MMUCR_FB		/* Was Device Type equal to 3? */
+   BEQ GetBusModeExit
+
+   SUBS r1,r1,#1    		/* Was Device Type equal to 4? */
+   BEQ GetBusModeExit
+
+   SUBS r1,r1,#1    		/* Must've been 5 then		   */
+   BEQ GetBusModeExit
+
+   /* Default to FastBus */
+   MOV r0, #MMUCR_FB
+
+GetBusModeExit:
+	MOV	pc, lr
+
+/********************************************************************************
+ * sysGetPLLFValForDevice: Pass in device type, this translates it and returns
+ *                         the correspoding PLL_F Register divisor for that device
+ *******************************************************************************/
+ENTRY(_sysGetPLLFValForDevice)
+
+/*
+ * !!!!W A R N I N G!!!!!
+ * DO NOT TRY TO OPTIMIZE THIS BY MAKING IT INTO A TABLE
+ * VARIABLES WILL NOT WORK HERE!
+ */
+
+   /*
+    * Add 1 to device type in R0. Keep subtracting 1 later, when difference
+	* reaches zero, we have found our device.
+	*/
+   ADD r1,r0,#1
+   SUBS r1,r1,#1
+
+   LDREQ r0,=P52_PLL_FAST_144MHZ			/* Was Device Type equal to 0? */
+   BEQ GetPLLFExit
+
+   SUBS r1,r1,#1
+   LDREQ r0,=P52_PLL_FAST_168MHZ			/* Was Device Type equal to 1? */
+   BEQ GetPLLFExit
+
+   SUBS r1,r1,#1
+   LDREQ r0,=P52_PLL_FAST_168MHZ			/* Was Device Type equal to 2? */
+   BEQ GetPLLFExit
+
+   SUBS r1,r1,#1
+   LDREQ r0,=RUSHMORE_PLL_FAST_96MHZ		/* Was Device Type equal to 3? */
+   BEQ GetPLLFExit
+
+   SUBS r1,r1,#1
+   LDREQ r0,=RUSHMORE_PLL_FAST_168MHZ		/* Was Device Type equal to 4? */
+   BEQ GetPLLFExit
+
+   SUBS r1,r1,#1
+   LDREQ r0,=RUSHMORE_PLL_FAST_168MHZ		/* Must've been 5 then		   */
+   BEQ GetPLLFExit
+
+   /* Default = ERROR!!*/
+   MOV r0, #0x0 
+GetPLLFExit:
+	MOV	pc, lr
+
+/********************************************************************************
+ * sysGetPLLBValForDevice: Pass in device type, this translates it and returns
+ *                         the correspoding PLL_B Register divisor for that device
+ *******************************************************************************/
+ENTRY(_sysGetPLLBValForDevice)
+
+/*
+ * !!!!W A R N I N G!!!!!
+ * DO NOT TRY TO OPTIMIZE THIS BY MAKING IT INTO A TABLE
+ * VARIABLES WILL NOT WORK HERE!
+ */
+ 
+   /*
+    * Add 1 to device type in R0. Keep subtracting 1 later, when difference
+	* reaches zero, we have found our device.
+	*/
+
+   ADD r1,r0,#1
+
+   /* For each P5x device, we set to 100MHZ */
+   LDR r0,=P52_PLL_FAST_100MHZ
+
+   SUBS r1,r1,#1                			/* Was Device Type equal to 0? */
+   BEQ GetPLLBExit
+
+   SUBS r1,r1,#1							/* Was Device Type equal to 1? */
+   BEQ GetPLLBExit
+
+   SUBS r1,r1,#1							/* Was Device Type equal to 2? */
+   BEQ GetPLLBExit
+
+   /* Wasn't P5x, so it's Rushmore. All Rushmores are also 100MHZ */
+   LDR r0,=RUSHMORE_PLL_FAST_100MHZ
+
+   SUBS r1,r1,#1							/* Was Device Type equal to 3? */
+   BEQ GetPLLBExit
+
+   SUBS r1,r1,#1							/* Was Device Type equal to 4? */
+   BEQ GetPLLBExit
+
+   SUBS r1,r1,#1							/* Must've been 5 then		   */
+   BEQ GetPLLBExit
+
+   /* Default = ERROR!!*/
+   MOV r0, #0x0
+  
+GetPLLBExit:
+	MOV	pc, lr
+
+/***************************************************************************
+ * sysSoftReset - Switch from Run Map to Boot Map then force SW reset
+ *
+ **************************************************************************/
+ENTRY(_sysSoftReset)
+	/* Switch run map to boot map */
+	LDR	r2, =HST_CTRL
+    
+	#if (PHYS_SDRAM_SIZE == 8)
+		MOV	r1, #HSTCTRL_8MEG
+	#elif (PHYS_SDRAM_SIZE == 4)
+		MOV	r1, #HSTCTRL_4MEG
+	#else
+		MOV	r1, #0x00
+    #endif
+
+    STR r1, [r2]
+
+    /* Wait for system to stabilize to be safe */
+	NOP
+	NOP
+	NOP
+	NOP
+	NOP
+	NOP
+	NOP
+	NOP
+	NOP
+	NOP
+	NOP
+	NOP
+
+    BL _sysCacheDisable
+
+    /* Force jump back to Reset vector */
+	MOV r0, #0x0
+  	MOV	pc, r0
+
+
+
+
+
+
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/syslib.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/syslib.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/syslib.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/syslib.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,321 @@
+/****************************************************************************
+*
+*	Name:			   syslib.c
+*
+*	Description:	ARM system-dependent routines
+*
+*	Copyright:		(c) 2001 - 2003  Conexant Systems Inc.
+*
+*****************************************************************************
+*  $Author:   lewisrc  $
+*  $Revision:   1.3  $
+*  $Modtime:   Jul 18 2003 11:07:22  $
+****************************************************************************/
+
+
+/*
+modification history
+--------------------
+01a,21jul98,gar  created based on ARM PID 01a
+*/
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+
+#include <asm/arch/bspcfg.h>
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/cnxtbsp.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/cnxtirq.h>
+#include <asm/arch/hstif.h>
+#include <asm/arch/pwrmanag.h>
+#include "eeprom.h"
+#include <asm/arch/OsTools.h>
+#include <asm/arch/cnxttimer.h>
+
+#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+#include <asm/arch/dsl.h>
+#include <asm/arch/cardinfo.h>
+#include <asm/arch/irq.h>
+#include <asm/arch/dslisr.h>
+#endif
+#include "plldef.h"
+
+extern void DSL_RX_DMA_ISR(int irq, void *dev_id, struct pt_regs * regs);
+extern void DSL_ERR_ISR(int irq, void *dev_id, struct pt_regs * regs);
+
+void sysSerialCheck ( void ) ;
+
+/* imports */
+
+int	sysProcNum;    /* processor number of this cpu */
+
+
+/* locals */
+
+/* PCLK = BCLK/2 */
+/* Since timer value is 16-bit we will not attempt to support  */
+/* BCLK values of 150Mhz and higher since these values is more */
+/* than 16-bit long. */
+
+UINT32 RUSHMORE_PCLKNormalRate_Table[RUSHMORE_MAX_NUM_BLCK] =
+   { 12500,   /* BCLK = 25Mhz */
+     25000,   /* BCLK = 50Mhz */
+     37500,   /* BCLK = 75Mhz */
+     50000,   /* BCLK = 100Mhz */
+     62500    /* BCLK = 125Mhz */
+   };
+
+
+UINT32 P52_PCLKNormalRate_Table[P52_MAX_NUM_BLCK] =
+   { 37500,   /* BCLK = 75Mhz */
+     50000,   /* BCLK = 100Mhz */
+     62500    /* BCLK = 125Mhz */
+   };
+
+
+UINT32 P52_PCLKSlowRate_Table[P52_MAX_NUM_BLCK] =
+   { 12500,
+     25000,
+     31250
+   };
+
+
+
+/* globals */
+
+
+/* forward LOCAL functions declarations */
+
+
+
+
+/*******************************************************************************
+*
+* sysHwInit - initialize the CPU board hardware
+*
+* This routine initializes various features of the hardware.
+* Normally, it is called from usrInit() in usrConfig.c.
+*
+* NOTE: This routine should not be called directly by the user.
+*
+* RETURNS: N/A
+*/
+
+void syshwinit (void)
+{
+	UINT32 *pHostSig = 0;
+
+	// Initialize PLL regs, I and D caches
+	sysInit();
+	
+	/* Get Device Type.  For now return either P52 or Rushmore. */
+	HWSTATE.eDeviceType = _sysGetDeviceType();
+
+	/* Initialize the GPIO device */
+	GPIO_Init();
+
+	HSTInit();
+
+#ifndef DEVICE_YELLOWSTONE
+	#ifdef CONFIG_BD_HASBANI
+		#ifdef DL10_D325_003
+			// Toggles the reset line for the PHY device
+			// NOTE: The DL10-D325-003 version of the Hasbani
+			// hardware requires that the reset line of the EMAC
+			// device be toggled because there is no longer an RC
+			// network on the line to do it for us.
+			sysDevicePowerCtl(DEVICE_EPHY, DEVICE_RESET);
+		#endif		
+
+		#ifdef POWER_CTRL
+			#ifndef DL10_D325_003
+				/* Shut off Flash once code is executing from SDRAM to save power */
+				sysDevicePowerCtl(DEVICE_FLASH, DEVICE_OFF);
+			#endif
+			
+			#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+				/* Shut off ADSL interfaces */
+				sysDevicePowerCtl(DEVICE_AFE, DEVICE_OFF);
+				sysDevicePowerCtl(DEVICE_FALCON, DEVICE_OFF);
+			#endif
+		#endif
+	#else
+		#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE && defined ( POWER_CTRL )
+			/* Shut off ADSL interfaces */
+			sysDevicePowerCtl(DEVICE_AFE, DEVICE_OFF);
+			sysDevicePowerCtl(DEVICE_FALCON, DEVICE_OFF);
+		#endif
+
+		#if CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE
+			// Toggles the reset line for the PHY device on Starfire platforms
+			sysDevicePowerCtl(DEVICE_EPHY, DEVICE_RESET);
+		#endif
+
+	#endif
+#endif
+
+	#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+		HWSTATE.eADSLLineState = ADSL_DISABLE;
+		HWSTATE.eADSLRequestLineState= ADSL_DISABLE; 
+		HWSTATE.dwADSLDownRate = 0;
+		HWSTATE.dwADSLUpRate = 0;
+		HWSTATE.eADSLLineState = ADSL_DISABLE;
+		HWSTATE.bSRAMState = TRUE;
+		HWSTATE.bSDRAMState = TRUE;
+		HWSTATE.bEEPROMState = FALSE;
+		HWSTATE.eUARTState = NO_UART;
+		HWSTATE.g_pUARTChan = 0;
+		/* Assume self-test passed */
+		HWSTATE.bSelfTestState = TRUE;
+		HWSTATE.dwMACAddressLow  = 0x0;
+		HWSTATE.dwMACAddressHigh = 0x0;
+		
+		/* initialise serial data structure */
+		HWSTATE.eUARTState = OursysSerialHwInit ();
+
+	#else
+		HWSTATE.bSRAMState = TRUE;
+		HWSTATE.bSDRAMState = TRUE;
+		HWSTATE.bEEPROMState = FALSE;
+		HWSTATE.eUARTState = NO_UART;
+		HWSTATE.g_pUARTChan = 0;
+		/* Assume self-test passed */
+		HWSTATE.bSelfTestState = TRUE;
+		HWSTATE.dwMACAddressLow  = 0x0;
+		HWSTATE.dwMACAddressHigh = 0x0;
+		
+	#endif
+
+
+	/* Init the device descritor and configuration tables independent of */
+	/* whether we will configure USB core or not. */
+	InitEEPROMImage();
+
+	pHostSig = (UINT32 *) HOST_SIGNATURE;
+
+
+   /* Do Serial number check after System clock is running since */
+   /* we rely on the timer to randomly generate a serial number  */
+   /* as needed. */
+	sysSerialCheck();
+}
+
+
+/*******************************************************************************
+*
+* sysHwInit2 - additional system configuration and initialization
+*
+* This routine connects system interrupts and does any additional
+* configuration necessary.
+*
+* RETURNS: N/A
+*
+* NOMANUAL
+*
+* Note: this is called from sysClkConnect() in the timer driver.
+*/
+
+void sysHwInit2 (void)
+{
+	// Initialize General Purpose Timer
+	GPTimerInit () ;
+
+#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE || CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE
+
+	DmaInit();
+
+	DSL_init();
+
+	/* Connect DSL error interrupt */
+	if( request_irq( INT_LVL_ADSL_ERR, &DSL_ERR_ISR, 0, "dsl error isr", 0 ))
+	{
+	 // What do we do if the interrupt does not connect
+	} 
+	cnxt_unmask_irq (INT_LVL_ADSL_ERR);
+
+#endif
+
+	// setup overall GPIO interrupt handler
+	request_irq( INT_LVL_GPIO, GPIOHandler, 0, "gpio isr", 0 ) ;
+	
+#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+	/* Setup serial port GPIO interrupt */
+	sysSerialHwInit2();
+#endif
+}
+
+/******************************************************************************
+
+FUNCTION NAME:
+		GetRxTimeOutValue
+
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+UINT32 GetRxTimeOutValue(UINT32 usTime)
+{
+   UINT32 volatile *pPLLreg = 0;
+   UINT32 TimerValue = 0;
+   UINT32 value = 0;
+
+   pPLLreg = (UINT32 volatile *) PLL_B;
+   value = *pPLLreg;
+
+   if (HWSTATE.eDeviceType >= DEVICE_RUSHMORE)
+   {
+      /* If in slow mode return 0 to turn off both USB and DLS RX */
+      /* time out features. */
+      if (value & RUSHMORE_PLL_CR_SLOW)
+         TimerValue = 0;
+
+      else
+      {
+         value = (value & RUSHMORE_PLL_CLK_RATE);
+         /* If value is too large for timer 16-bit value, we will also  */
+         /* return 0 to turn off both USB and DSL RX time out features. */
+         if (value >= RUSHMORE_MAX_NUM_BLCK)
+            TimerValue = 0;
+
+         else
+         {
+            TimerValue = (usTime * RUSHMORE_PCLKNormalRate_Table[value])/1000;
+            TimerValue = (TimerValue >> 8);
+         }
+      }
+   }
+
+   else
+   {
+      if (value & P52_PLL_CR_SLOW)
+      {
+         value = ((value & P52_PLL_CLK_RATE) >> 24);
+         TimerValue = (usTime * P52_PCLKSlowRate_Table[value])/1000;
+         /* Shift down by 8 to accommodate the mapping of the    */
+         /* 16-bit Timer Register into the 24-bit Timer Counter. */
+         TimerValue = (TimerValue >> 8);
+      }
+
+      else
+      {
+         /* TimerValue = 0x124 for 75Mhz */
+         value = ((value & P52_PLL_CLK_RATE) >> 24);
+         TimerValue = (usTime * P52_PCLKNormalRate_Table[value])/1000;
+         TimerValue = (TimerValue >> 8);
+      }
+   }
+
+   return (TimerValue);
+}
+
+
+BOOL SYS_bDUALEMAC_Support( void )
+{
+	// Basically a stub for now
+	return FALSE;
+}
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/sysmem.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/sysmem.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/sysmem.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/sysmem.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,252 @@
+/****************************************************************************
+* $Header: /cvs/sw/linux-2.4.x/arch/armnommu/mach-cx821xx/sysmem.c,v 1.1 2005/02/18 04:21:50 gerg Exp $
+*
+*  Copyright(c)2002  Conexant Systems
+*
+*****************************************************************************/
+
+// SYSMEM: Unformatted system (nonCache) memory (SRAM or SDRAM) manager
+// This module provide the services to allocate and free a block of system memory.
+//  The services are slow, the idea is client allocate a block of memory and 
+// manage it by itself.
+// Depend on the implementation it can be OS_DEPENDENT or OS_INDEPENDENT
+
+// Consideration:
+//  DMA buffer must be at 8-byte aligned, we make it at 16-byte aligned now
+// Requirement:
+//      Begin and Length of SRAM 
+//      Begin and Length of SDRAM 
+// 
+
+#define SYSMEM_MODULE
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/bspcfg.h>
+#include <linux/config.h>
+#include <asm/arch/cnxtbsp.h>
+
+#include <asm/arch/sysmem.h>
+#include <linux/string.h>
+#include <asm/memory.h>
+#include <linux/kernel.h>
+
+#define BYTE16_ALIGN_PTR(x)                      \
+{                                               \
+    ( unsigned long) x = ((( unsigned long) x + 0xF ) & 0xFFFFFFF0 );   \
+}
+#define	DRAM_8M_SIZE		0x800000
+
+
+//SYSMEM APIs
+
+static UINT32   SRAMMemTopPtr = SRAMSTART;
+static UINT32   nonCachedSDRAMMemTopPtr = END_MEM;
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		SYSMEM_GeneralInit
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+void SYSMEM_GeneralInit(void)
+{
+	// Stub
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		SYSMEM_GeneralClose
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+void SYSMEM_GeneralClose( void)
+{
+	// Stub
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		SYSMEM_Allocate_BlockMemory
+		
+ABSTRACT:
+		
+DETAILS:
+
+	!!!!!!!!!!!! WARNING WARNING WARNING WARNING !!!!!!!!!!!!!!
+
+	THIS MEMORY ALLOCATION FUNCTION IS NOT VERY SOPHISTICATED.
+	IT IS SIMPLY A POINTER TO MEMORY THAT GETS ADVANCED BY THE
+	REQUESTED BLOCK SIZE FOR EACH MEMORY REQUEST.  THEREFOR, ANY
+	RELEASE OF THE BLOCKS OF MEMORY ALLOCATED BY THIS FUNCTION
+	MUST COME IN THE REVERSE ORDER OF WHAT THEY WERE ALLOCATED.
+
+	!!!!!!!!!!!! WARNING WARNING WARNING WARNING !!!!!!!!!!!!!!
+
+*******************************************************************************/
+
+unsigned char * SYSMEM_Allocate_BlockMemory( int ifSram, int sysMemSize, int alignment )
+{
+    void	*pMem;
+    UINT32	totalSize = 0;
+
+	// Make the request increments of 16 bytes
+	if( sysMemSize & 0xF )
+	{
+		totalSize = 16;
+	}
+
+	// Which kind of ram is being requested?
+	switch( ifSram )
+    {
+		case 0:
+			// SDRAM
+			// Is the SDRAM memory request greater than what is remaining?
+			if( sysMemSize > ( (DRAM_BASE + DRAM_8M_SIZE) - nonCachedSDRAMMemTopPtr ) )
+			{
+		        pMem = NULL;
+			}
+			else
+			{
+				totalSize += ( sysMemSize & 0xFFFF0 );
+				pMem = ( void * )( nonCachedSDRAMMemTopPtr );
+				if ((( char * ) pMem + totalSize ) < ( char * )( DRAM_BASE + DRAM_8M_SIZE ))
+			    {
+			        nonCachedSDRAMMemTopPtr += totalSize;
+			        memset (( char * ) pMem, 0, totalSize );
+			    }
+			    else
+			    {
+			        pMem = NULL;
+			    }
+			}
+			printk( KERN_DEBUG "SDRAM start %lx end %lx\n", pMem, nonCachedSDRAMMemTopPtr );
+			break;
+
+		case 1:
+			// SRAM
+			// Is the SRAM memory request greater than what is remaining?
+			if( sysMemSize > ( SRAMEND - SRAMMemTopPtr ) )
+			{
+		        pMem = NULL;
+			}
+			else
+			{
+				totalSize += ( sysMemSize & 0x7FF0 );
+				pMem = ( void * )( SRAMMemTopPtr );
+				if ((( char * ) pMem + totalSize ) < ( char * )( SRAMEND ))
+			    {
+			        SRAMMemTopPtr += totalSize;
+			        memset (( char * ) pMem, 0, totalSize );
+			    }
+			    else
+			    {
+			        pMem = NULL;
+			    }
+			}
+			printk( KERN_DEBUG "SRAM start %lx end %lx\n", pMem, SRAMMemTopPtr );
+			break;
+
+		default:
+	        pMem = NULL;
+			break;
+	}
+
+	return ( pMem  );
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		SYSMEM_Release_BlockMemory
+		
+ABSTRACT:
+		
+DETAILS:
+
+	!!!!!!!!!!!! WARNING WARNING WARNING WARNING !!!!!!!!!!!!!!
+
+	THIS MEMORY RELEASE FUNCTION IS NOT VERY SOPHISTICATED.
+	IT IS SIMPLY A POINTER TO MEMORY THAT GETS SET TO THE
+	POINTER VALUE THAT IS BEING PASSED TO IT.  THEREFOR, ANY
+	RELEASE OF THE BLOCKS OF MEMORY ALLOCATED BY THE ALLOC FUNCTION
+	MUST COME IN THE REVERSE ORDER OF WHAT THEY WERE ALLOCATED.
+
+	!!!!!!!!!!!! WARNING WARNING WARNING WARNING !!!!!!!!!!!!!!
+
+*******************************************************************************/
+
+int SYSMEM_Release_BlockMemory( int ifSram, unsigned char *sysMemPtr )
+{
+    UINT32	totalSize = 0;
+
+	switch( ifSram )
+    {
+		case 0:
+			// SDRAM
+			nonCachedSDRAMMemTopPtr = sysMemPtr;
+			printk( KERN_DEBUG "ReleaseMem SDRAM ");
+			printk( KERN_DEBUG "%lx\n", nonCachedSDRAMMemTopPtr );
+			break;
+		case 1:
+			// SRAM
+			SRAMMemTopPtr = sysMemPtr;
+			printk( KERN_DEBUG "ReleaseMem SRAM ");
+			printk( KERN_DEBUG "%lx\n", SRAMMemTopPtr );
+			break;
+
+		default:
+			break;
+	}
+	return 0;
+}
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		SYSMEM_QueryMemory
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+unsigned long SYSMEM_QueryMemory( int ifSram )
+{
+	UINT32	remaining_mem;
+	 
+	switch( ifSram )
+    {
+		case 0:
+			// SDRAM
+			remaining_mem = ((DRAM_BASE + DRAM_8M_SIZE) - nonCachedSDRAMMemTopPtr);
+			printk( KERN_DEBUG "QueryMem SDRAM ");
+			break;
+		case 1:
+			// SRAM
+			remaining_mem = ( SRAMEND - SRAMMemTopPtr);
+			printk( KERN_DEBUG "QueryMem SRAM ");
+			break;
+
+		default:
+			remaining_mem = 0;
+			break;
+	}
+	printk( KERN_DEBUG "%lx\n", remaining_mem );
+	return remaining_mem;
+}
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/sysserial.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/sysserial.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/sysserial.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/sysserial.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,157 @@
+/****************************************************************************
+*
+*	Name:			sysserial.c
+*
+*	Description:	CX82100 serial device initialization
+*
+*	Copyright:		(c) 2001 Conexant Systems Inc.
+*
+*****************************************************************************/
+
+/*
+modification history
+--------------------
+01a,31aug98,mbp  written.
+*/
+
+/*
+DESCRIPTION
+This file contains the board-specific routines for serial channel
+initialization of the CX82100 Development environment.
+
+SEE ALSO:
+.I "CX82100 Silicon System Design Engineering Specification"
+*/
+
+#include <linux/module.h>
+#if defined (CONFIG_CNXT_ADSL)  ||  defined (CONFIG_CNXT_ADSL_MODULE)
+
+#include "bsptypes.h"
+#include "bspcfg.h"
+#include "syslib.h"
+#include <asm/io.h>
+//#include <asm/arch/cnxthw.h>
+#include "cnxtbsp.h"
+
+#include "cnxtirq.h"
+#include "gpio.h"
+#include <asm/arch/irq.h>
+
+#include "OsTools.h"
+#include "cnxtsio.h"
+
+/* device initialization structure */
+
+typedef struct
+{
+	UINT	vector;
+	UINT8	*baseAdrs;
+	UINT	regSpace;
+	UINT	intLevel;
+} CNXT_SPUART_CHAN_PARAS;
+
+
+/* Local data structures */
+
+static CNXT_SPUART_CHAN_PARAS devParas[] =
+{
+	{
+		INT_VEC_GPIO,
+		(UINT8 *)SERIALPORT1,
+		UART_REG_ADDR_INTERVAL,
+		INT_LVL_GPIO
+	}
+};
+ 
+CNXT_UART spUartChan[1];
+
+
+/* forward declarations */
+
+/******************************************************************************
+*
+* sysSerialHwInit - initialize the BSP serial devices to a quiesent state
+*
+* This routine initializes the BSP serial device descriptors and puts the
+* devices in a quiesent state.  It is called from sysHwInit() with
+* interrupts locked.
+*
+* RETURNS: N/A
+*
+* SEE ALSO: sysHwInit()
+*/
+
+BOOL OursysSerialHwInit (void)
+{
+	#if DEBUG_CONSOLE_ON_UART_2
+		return TRUE;
+	#else
+		spUartChan[0].regAddr 	= devParas[0].regSpace;
+		spUartChan[0].regs 	= devParas[0].baseAdrs;
+
+		/*
+		* Initialise UART
+		*/
+
+		return ( spUartDevInit ( &spUartChan[0] ) );
+	#endif
+}
+
+/******************************************************************************
+*
+* sysSerialHwInit2 - connect BSP serial device interrupts
+*
+* This routine connects the BSP serial device interrupts.  It is called from
+* sysHwInit2().  Serial device interrupts could not be connected in
+* sysSerialHwInit() because the kernel memory allocator was not initialized
+* at that point, and intConnect() may call malloc(). 
+* 
+* RETURNS: N/A 
+*
+* SEE ALSO: sysHwInit2()
+*/
+
+void sysSerialHwInit2 (void)
+{
+   int oldlevel;
+
+	oldlevel = intLock();
+
+	#if DEBUG_CONSOLE_ON_UART_2
+		// Do nothing
+	#else
+		#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+
+			#ifdef CONFIG_BD_RUSHMORE
+				GPIO_SetGPIOIRQRoutine(GPIOINT_UART2, GPIOB14_Handler);
+			#endif
+
+			#ifdef CONFIG_BD_HASBANI
+				GPIO_SetGPIOIRQRoutine(GPIOINT_UART2, GPIOB24_Handler);
+			#endif
+
+			#ifdef CONFIG_BD_MACKINAC
+				GPIO_SetGPIOIRQRoutine(GPIOINT_UART2, GPIOB30_Handler);
+			#endif
+
+			SetGPIODir( GPIOINT_UART2, GP_INPUT );
+			SetGPIOInputEnable( GPIOINT_UART2, GP_INPUTON );
+
+			SetGPIOIntEnable(GPIOINT_UART2, IRQ_OFF);
+
+			#if 1
+				SetGPIOIntPolarity (GPIOINT_UART2, GP_IRQ_POL_POSITIVE);
+			#else
+				SetGPIOIntMode (GPIOINT_UART2, GP_IRQ_MODE_LEVEL);
+				SetGPIOIntPolarity (GPIOINT_UART2, GP_IRQ_POL_NEGATIVE);
+			#endif
+
+			SetGPIOIntEnable(GPIOINT_UART2, IRQ_ON);
+
+		#endif
+	#endif
+
+	intUnlock(oldlevel);
+}
+
+#endif	//if defined (CONFIG_CNXT_ADSL)  ||  defined (CONFIG_CNXT_ADSL_MODULE)
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/tiburon-softreset.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/tiburon-softreset.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/tiburon-softreset.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/tiburon-softreset.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,169 @@
+/*
+ * (C) 2005, Johann Hanne, GPL
+ *
+ * The Actiontec Dual PC Modem (aka DPCM and Tiburon) has a
+ * reset button which must be software controlled; it is
+ * connected to GPIO line 27
+ *
+ * This module implements an interrupt handler for it which
+ * is limited to 1 interrupt per second (this is done by disabling
+ * the interrupt as soon as one arrives and launching a timer
+ * which enables it again); for each interrupt that occurs, a
+ * SIGINT is sent to pid 1 (which should be an init process); note that 
+ * it's left to the pid 1 process what to do; it could for example 
+ * execute /sbin/reboot; it could also reset the configuration to 
+ * factory defaults if the button remeins pressed for some seconds
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/mtd/compatmac.h>
+#include <linux/mtd/mtd.h>
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/cnxtflash.h>
+#include <asm/arch/gpio.h>
+#include <asm/io.h>
+
+static struct timer_list tiburon_softreset_reenable_GPIOB27_timerlist;
+
+static void tiburon_softreset_reenable_GPIOB27(unsigned long arg) {
+  SetGPIOIntEnable(GPIO27, 1);
+}
+
+void tiburon_softreset_GPIOB27_Handler(int gpio_num)
+{
+  /* Send a SIGINT to pid 1 (the init process) */
+  kill_proc(1, SIGINT, 1);
+
+  SetGPIOIntEnable(GPIO27, 0);
+  /* WriteGPIOData(GPIO27, 1); */
+  ClearGPIOIntStatus(GPIO27);
+
+  /* Send a SIGINT to pid 1 every second as long
+     as the button is pressed */
+  tiburon_softreset_reenable_GPIOB27_timerlist.expires = jiffies + HZ;
+  add_timer(&tiburon_softreset_reenable_GPIOB27_timerlist);
+}
+
+static void __exit cleanup_tiburon_softreset(void)
+{
+  if (tiburon_softreset_reenable_GPIOB27_timerlist.expires) {
+    del_timer(&tiburon_softreset_reenable_GPIOB27_timerlist);
+  }
+
+  SetGPIOIntEnable(GPIO27, 0);
+  ClearGPIOIntStatus(GPIO27);
+}
+
+int __init init_tiburon_softreset(void)
+{
+  SetGPIOIntEnable(GPIO27, 0);
+  SetGPIODir(GPIO27, GP_INPUT);
+  SetGPIOIntPolarity(GPIO27, GP_IRQ_POL_NEGATIVE);
+  SetGPIOInputEnable(GPIO27, GP_INPUTON);
+  GPIO_SetGPIOIRQRoutine(GPIO27, tiburon_softreset_GPIOB27_Handler);
+  SetGPIOIntEnable(GPIO27, 1);
+
+  tiburon_softreset_reenable_GPIOB27_timerlist.function = 
+    tiburon_softreset_reenable_GPIOB27;
+  tiburon_softreset_reenable_GPIOB27_timerlist.data = 0;
+  tiburon_softreset_reenable_GPIOB27_timerlist.expires = 0;
+
+  return 0;
+}
+
+module_init(init_tiburon_softreset);
+module_exit(cleanup_tiburon_softreset);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Johann Hanne");
+MODULE_DESCRIPTION("Monitor the soft-reset button on the Tiburon (Actiontec DPCM)");
+/*
+ * (C) 2005, Johann Hanne, GPL
+ *
+ * The Actiontec Dual PC Modem (aka DPCM and Tiburon) has a
+ * reset button which must be software controlled; it is
+ * connected to GPIO line 27
+ *
+ * This module implements an interrupt handler for it which
+ * is limited to 1 interrupt per second (this is done by disabling
+ * the interrupt as soon as one arrives and launching a timer
+ * which enables it again); for each interrupt that occurs, a
+ * SIGINT is sent to pid 1 (which should be an init process); note that 
+ * it's left to the pid 1 process what to do; it could for example 
+ * execute /sbin/reboot; it could also reset the configuration to 
+ * factory defaults if the button remeins pressed for some seconds
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/mtd/compatmac.h>
+#include <linux/mtd/mtd.h>
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/cnxtflash.h>
+#include <asm/arch/gpio.h>
+#include <asm/io.h>
+
+static struct timer_list tiburon_softreset_reenable_GPIOB27_timerlist;
+
+static void tiburon_softreset_reenable_GPIOB27(unsigned long arg) {
+  SetGPIOIntEnable(GPIO27, 1);
+}
+
+void tiburon_softreset_GPIOB27_Handler(int gpio_num)
+{
+
+printk(KERN_DEBUG "HICKS GPIOB27_Handler\n");
+
+  /* Send a SIGINT to pid 1 (the init process) */
+  kill_proc(1, SIGINT, 1);
+
+  SetGPIOIntEnable(GPIO27, 0);
+  /* WriteGPIOData(GPIO27, 1); */
+  ClearGPIOIntStatus(GPIO27);
+
+  /* Send a SIGINT to pid 1 every second as long
+     as the button is pressed */
+  tiburon_softreset_reenable_GPIOB27_timerlist.expires = jiffies + HZ;
+  add_timer(&tiburon_softreset_reenable_GPIOB27_timerlist);
+}
+
+static void __exit cleanup_tiburon_softreset(void)
+{
+  if (tiburon_softreset_reenable_GPIOB27_timerlist.expires) {
+    del_timer(&tiburon_softreset_reenable_GPIOB27_timerlist);
+  }
+
+  SetGPIOIntEnable(GPIO27, 0);
+  ClearGPIOIntStatus(GPIO27);
+}
+
+int __init init_tiburon_softreset(void)
+{
+  SetGPIOIntEnable(GPIO27, 0);
+  SetGPIODir(GPIO27, GP_INPUT);
+  SetGPIOIntPolarity(GPIO27, GP_IRQ_POL_NEGATIVE);
+  SetGPIOInputEnable(GPIO27, GP_INPUTON);
+  GPIO_SetGPIOIRQRoutine(GPIO27, tiburon_softreset_GPIOB27_Handler);
+  SetGPIOIntEnable(GPIO27, 1);
+
+  tiburon_softreset_reenable_GPIOB27_timerlist.function = 
+    tiburon_softreset_reenable_GPIOB27;
+  tiburon_softreset_reenable_GPIOB27_timerlist.data = 0;
+  tiburon_softreset_reenable_GPIOB27_timerlist.expires = 0;
+
+  return 0;
+}
+
+module_init(init_tiburon_softreset);
+module_exit(cleanup_tiburon_softreset);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Johann Hanne");
+MODULE_DESCRIPTION("Monitor the soft-reset button on the Tiburon (Actiontec DPCM)");
diff -urN linux-2.4.29/arch/armnommu/mach-cx821xx/time.c linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/time.c
--- linux-2.4.29/arch/armnommu/mach-cx821xx/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-cx821xx/time.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,66 @@
+/****************************************************************************
+*
+*	Name:			time.c
+*
+*	Description:	Timer ISR and query functions
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:22:10  $
+****************************************************************************/
+
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+extern unsigned long cnxt_gettimeoffset(void)
+{
+#if 0
+	u16 elapsed;
+
+	/* 
+	 * Compute the elapsed count. The current count tells us how
+	 * many counts remain until the next interrupt. LATCH tells us
+	 * how many counts total occur between interrupts. Subtract to
+	 * get the counts since the last interrupt.
+	 */
+	elapsed = LATCH - inb(CX821xx_TIMBase_Addr);
+
+	/* 
+	 * Convert the elapsed count to usecs. I guess there are 'tick' usecs
+	 * between every interrupt. 
+	 */
+	return (unsigned long)((elapsed * tick) / LATCH);
+#endif
+	return (unsigned long)(inl(CX821xx_TIMBase_Addr));
+}
+
+void cnxt_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	*CNXT_INT_STATUS = (1 << irq);
+	do_timer(regs);
+}
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-dm270/arch.c linux-2.4.29-uc1/arch/armnommu/mach-dm270/arch.c
--- linux-2.4.29/arch/armnommu/mach-dm270/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-dm270/arch.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,31 @@
+/*
+ *  arch/arm/mach-dm270/arch.c
+ *
+ *   Derived from arch/armnommu/mach-atmel/arch.c
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ *  Architecture specific fixups.  This is where any
+ *  parameters in the params struct are fixed up, or
+ *  any additional architecture specific information
+ *  is pulled from the params struct.
+ */
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+
+#include <asm/elf.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+extern void genarch_init_irq(void);
+
+MACHINE_START(DM270, "TI TMS320DM270")
+	MAINTAINER("Chee Tim Loh <cheetim_loh@innomedia.com.sg>")
+	BOOT_MEM(0x01200000, 0x00000000, 0x00000000)
+	BOOT_PARAMS(0x00000100)
+	INITIRQ(genarch_init_irq)
+MACHINE_END
diff -urN linux-2.4.29/arch/armnommu/mach-dm270/dma.c linux-2.4.29-uc1/arch/armnommu/mach-dm270/dma.c
--- linux-2.4.29/arch/armnommu/mach-dm270/dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-dm270/dma.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,42 @@
+/***********************************************************************
+ * arch/arm/mach-dm270/dma.c
+ *
+ *   Derived from arch/armnommu/mach-c5471/dma.c
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/dma.h>
+
+void __init arch_dma_init(dma_t *dma)
+{
+  /* No special initial setup is required for the dm270.
+   */
+}
diff -urN linux-2.4.29/arch/armnommu/mach-dm270/irq.c linux-2.4.29-uc1/arch/armnommu/mach-dm270/irq.c
--- linux-2.4.29/arch/armnommu/mach-dm270/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-dm270/irq.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,123 @@
+/***********************************************************************
+ * arch/armnommu/mach-dm270/irq.c
+ *
+ *   TI TMS320DM270 IRQ mask, unmask & ack routines.
+ *
+ *   Derived from arch/armnommu/mach-c5471/irq.c
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <asm/arch/irq.h>
+#include <asm/arch/hardware.h>
+
+/* Acknowlede the IRQ. */
+
+static inline void irq_ack(unsigned int irq)
+{
+	outw((1<<DM270_INTC_IRQ_SHIFT(irq)), DM270_INTC_IRQ(irq));
+}
+
+/* Acknowledge the FIQ. */
+
+static inline void fiq_ack(unsigned int irq)
+{
+	outw((1<<DM270_INTC_FIQ_SHIFT(irq)), DM270_INTC_FIQ(irq));
+}
+
+/* Mask the IRQ. */
+
+void dm270_mask_irq(unsigned int irq)
+{
+	u_int32_t eint;
+	u_int16_t mask;
+
+	eint = DM270_INTC_EINT(irq);
+	mask = inw(eint);
+	mask &= ~(1<<DM270_INTC_EINT_SHIFT(irq));
+	outw(mask, eint);
+}
+
+/* Unmask the IRQ. */
+
+void dm270_unmask_irq(unsigned int irq)
+{
+	u_int32_t eint;
+	u_int16_t mask;
+
+	eint = DM270_INTC_EINT(irq);
+	mask = inw(eint);
+	mask |= (1<<DM270_INTC_EINT_SHIFT(irq));
+	outw(mask, eint);
+}
+
+/* Mask the IRQ and acknowledge it. */
+
+void dm270_mask_ack_irq(unsigned int irq)
+{
+	u_int32_t eint;
+	u_int16_t mask;
+
+	eint = DM270_INTC_EINT(irq);
+	mask = inw(eint);
+	mask &= ~(1<<DM270_INTC_EINT_SHIFT(irq));
+	outw(mask, eint);
+
+	outw((1<<DM270_INTC_IRQ_SHIFT(irq)), DM270_INTC_IRQ(irq));
+}
+
+void dm270_init_irq(void)
+{
+	/* Disable all interrupts */
+
+	outw(0, DM270_INTC_EINT0);
+	outw(0, DM270_INTC_EINT1);
+	outw(0, DM270_INTC_EINT2);
+
+	/* Set all to IRQ mode, not FIQ */
+
+	outw(0, DM270_INTC_FISEL0);
+	outw(0, DM270_INTC_FISEL1);
+	outw(0, DM270_INTC_FISEL2);
+
+	/* Clear any pending interrupts */
+
+	outw(0xffff, DM270_INTC_IRQ0);
+	outw(0xffff, DM270_INTC_IRQ1);
+	outw(0xff, DM270_INTC_IRQ2);
+	outw(0xffff, DM270_INTC_FIQ0);
+	outw(0xffff, DM270_INTC_FIQ1);
+	outw(0xff, DM270_INTC_FIQ2);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-dm270/Makefile linux-2.4.29-uc1/arch/armnommu/mach-dm270/Makefile
--- linux-2.4.29/arch/armnommu/mach-dm270/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-dm270/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= dm270.o
+
+# Object file lists.
+
+obj-y			:= $(patsubst %.c, %.o, $(wildcard *.c))
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= 
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-dm270/time.c linux-2.4.29-uc1/arch/armnommu/mach-dm270/time.c
--- linux-2.4.29/arch/armnommu/mach-dm270/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-dm270/time.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,126 @@
+/***********************************************************************
+ * arch/armnommu/mach-dm270/time.c
+ *
+ *   Derived from arch/armnommu/mach-c5471/time.c
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+/* Included Files */
+
+#include <linux/param.h>     /* For HZ */
+
+#include <linux/spinlock.h>  /* spinlock_t needed by linux/interrupt.h */
+#include <asm/system.h>      /* smp_mb() needed by linux/interrupt.h */
+#include <linux/interrupt.h> /* For struct irqaction */
+
+#include <linux/sched.h>     /* For do_timer() */
+
+#include <asm/io.h>          /* For IO macros */
+#include <asm/hardware.h>    /* For TI TMS320DM270 register definitions */
+#include <asm/irq.h>         /* For IRQ_TIMER */
+
+#include <asm/mach/irq.h>    /* For setup_arm_irq */
+
+/* Definitions */
+
+#define COUNTS_PER_INTERRUPT (CONFIG_ARM_CLK / (CONFIG_DM270_TIMER_PRESCALE*HZ))
+#define USECS_PER_COUNT      ((1000000*CONFIG_DM270_TIMER_PRESCALE + (CONFIG_ARM_CLK >> 1))/CONFIG_ARM_CLK)
+
+/* Global data */
+
+extern unsigned long (*gettimeoffset)(void);
+
+static unsigned long dm270_gettimeoffset(void)
+{
+	/* Compute the elapsed count since the last interrupt.
+	 * Our counter counts up starting at 0.
+	 */
+
+	/* Convert the elapsed count to usecs. */
+	return (unsigned long)(inw(DM270_TMR0_TMCNT)*USECS_PER_COUNT);
+}
+
+static void dm270_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	do_timer(regs);
+}
+
+void dm270_setup_timer(struct irqaction *timer_irq)
+{
+	u_int16_t reg;
+
+	/* Configure timer.c so that dm270_gettimeoffset will be used
+	 * to get the elapsed microseconds between interrupts.
+	 */
+
+	gettimeoffset = dm270_gettimeoffset;
+
+	/* Capture the interrupt through dm270_timer_interrupt */
+
+	timer_irq->handler = dm270_timer_interrupt;
+	setup_arm_irq(IRQ_TIMER, timer_irq);
+
+	/* Start the general purpose timer 0 running in auto-reload mode
+	 * so that an interrupt is generated at the rate of HZ (param.h)
+	 * which typically is set to 100HZ.
+	 * When HZ is set to 100 then COUNTS_PER_INTERRUPT should be
+	 * established to reflect timer counts that occur every 10ms
+	 * (giving you 100 of them per second -- 100HZ). DM270's clock
+	 * is 87.75MHz and we're using a timer prescalar divide value
+	 * of 350 (350 == divide input clock frequency by 351) which then
+	 * yields a 16 bit COUNTS_PER_INTERRUPT value of 2500. Prescaler
+	 * divide value is chosen as 350 since DM270's clock is an
+	 * integer multiple of 351.
+	 */
+
+	/* Disable clock to timer 0 */
+	reg = inw(DM270_CLKC_MOD2);
+	outw((reg & ~(DM270_CLKC_MOD2_RSV_MASK | DM270_CLKC_MOD2_CTMR0)), DM270_CLKC_MOD2);
+
+	/* Select CLK_ARM as timer 0 clock source */
+	reg = inw(DM270_CLKC_CLKC);
+	outw((reg & ~(DM270_CLKC_CLKC_CTM0S)), DM270_CLKC_CLKC);
+
+	/* Enable clock to timer 0 */
+	reg = inw(DM270_CLKC_MOD2);
+	reg &= ~(DM270_CLKC_MOD2_RSV_MASK);
+	outw((reg | DM270_CLKC_MOD2_CTMR0), DM270_CLKC_MOD2);
+
+	/* Stop timer 0 */
+	reg = inw(DM270_TMR0_TMMD);
+	outw((reg & ~(DM270_TMR_TMMD_MODE_MASK | DM270_TMR_TMMD_TEST_MASK | DM270_TMR_TMMD_RSV_MASK)), DM270_TMR0_TMMD);
+
+	/* Wait till timer 0 stops??? */
+
+	/* Set timer 0 counter */
+	outw(((CONFIG_DM270_TIMER_PRESCALE - 1) & DM270_TMR_TMPRSCL_PRSCL_MASK), DM270_TMR0_TMPRSCL);
+	outw((u_int16_t)((COUNTS_PER_INTERRUPT - 1) & 0xffff), DM270_TMR0_TMVAL);
+
+	/* Set free run mode for timer 0 */
+	reg = inw(DM270_TMR0_TMMD);
+	reg &= ~(DM270_TMR_TMMD_MODE_MASK | DM270_TMR_TMMD_TEST_MASK | DM270_TMR_TMMD_RSV_MASK);
+	outw((reg | DM270_TMR_TMMD_MODE_FREERUN), DM270_TMR0_TMMD);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-dsc21/io.c linux-2.4.29-uc1/arch/armnommu/mach-dsc21/io.c
--- linux-2.4.29/arch/armnommu/mach-dsc21/io.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-dsc21/io.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,93 @@
+/*
+ *  linux/arch/arm/lib/io-ti925.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *   io functions
+ *
+ * Copyright (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * Author: RidgeRun, Inc.
+ *         Greg Lonnon (glonnon@ridgerun.com) or info@ridgerun.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <asm/io.h>
+
+void insl(unsigned int port, void *to, int len)
+{
+	int i;
+	for (i = 0; i < len; i++)
+		((unsigned long *)to)[i] = inl(port);
+}
+
+void insw(unsigned int port, void *to, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		((unsigned short *) to)[i] = inw(port);
+}
+
+void insb(unsigned int port, void *to, int len)
+{
+	int i;
+	for (i = 0; i < len; i++)
+		((unsigned char *)to)[i] = inb(port);
+}
+
+void outsw(unsigned int port, const void *from, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		outw(((unsigned short *) from)[i], port);
+}
+
+void outsl(unsigned int port, const void *from, int len)
+{
+	int i;
+	
+	for (i = 0; i < len; i++) 
+		outl(((unsigned long *) from)[i], port);
+}
+
+void outsb(unsigned int port, const void *from, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		outb(((unsigned char *) from)[i], port);
+}
+
+void outswb(unsigned int port, const void *from, int len)
+{
+	outsw(port, from, len >> 2);
+}
+
+void inswb(unsigned int port, void *to, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		((unsigned short *) to)[i] = inb(port);
+}
+
diff -urN linux-2.4.29/arch/armnommu/mach-dsc21/irq.c linux-2.4.29-uc1/arch/armnommu/mach-dsc21/irq.c
--- linux-2.4.29/arch/armnommu/mach-dsc21/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-dsc21/irq.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ * irq.c:
+ *         dsc21 IRQ mask, unmask & ack routines.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/types.h>
+#include <asm/arch/irq.h>
+
+void dsc21_mask_irq(unsigned int irq)
+{
+	if (irq > 15) *((u16*)DSC21_IRQ1_ENABLE) &= ~(1 << (irq - 16));
+	else *((u16*)DSC21_IRQ0_ENABLE) &= ~(1 << irq);
+}	
+
+void dsc21_unmask_irq(unsigned int irq)
+{
+	if (irq > 15)  *((u16*)DSC21_IRQ1_ENABLE) |= (1 << (irq - 16));
+	else *((u16*)DSC21_IRQ0_ENABLE) |= (1 << irq);
+}
+
+void dsc21_mask_ack_irq(unsigned int irq)
+{
+	dsc21_mask_irq(irq);
+	if (irq > 15) *((u16*)DSC21_IRQ1_STATUS) |= (0x01 << (irq - 16));
+	else *((u16*)DSC21_IRQ0_STATUS) |= (0x01 << irq);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-dsc21/Makefile linux-2.4.29-uc1/arch/armnommu/mach-dsc21/Makefile
--- linux-2.4.29/arch/armnommu/mach-dsc21/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-dsc21/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,23 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= dsc21.o
+
+# Object file lists.
+
+obj-y			:= $(patsubst %.c, %.o, $(wildcard *.c))
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= 
+
+#obj-$(CONFIG_LEDS)	+= leds.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-dsc21/mm.c linux-2.4.29-uc1/arch/armnommu/mach-dsc21/mm.c
--- linux-2.4.29/arch/armnommu/mach-dsc21/mm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-dsc21/mm.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,51 @@
+#ifdef CONFIG_REVISIT
+#error Move this to mach-dsc21?
+#endif
+/*
+ *  linux/arch/arm/mm/mm-dsc21.c
+ *
+ *  Copyright (C) 1998-1999 Russell King
+ *  Copyright (C) 1999 Hugo Fiennes
+ *  Copyright (C) 2001 RidgeRun, Inc
+ *
+ *  Extra MM routines for the SA1100 architecture
+ *
+ *  1999/12/04 Nicolas Pitre <nico@cam.org>
+ *	Converted memory definition for struct meminfo initialisations.
+ *	Memory is listed physically now.
+ *
+ *  2000/04/07 Nicolas Pitre <nico@cam.org>
+ *	Reworked for run-time selection of memory definitions
+ *
+ *  2001/02/19 Gordon McNutt <gmcnutt@ridgerun.com>
+ *      Modified mm-sa1100.c to make this, mm-dsc21.c.
+ *
+ */
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/map.h>
+ 
+#ifdef CONFIG_DISCONTIGMEM
+
+/*
+ * Our node_data structure for discontigous memory.
+ * There is 4 possible nodes i.e. the 4 SA1100 RAM banks.
+ */
+
+static bootmem_data_t node_bootmem_data[4];
+
+pg_data_t dsc21_node_data[4] =
+{ { bdata: &node_bootmem_data[0] },
+  { bdata: &node_bootmem_data[1] },
+  { bdata: &node_bootmem_data[2] },
+  { bdata: &node_bootmem_data[3] } };
+
+#endif
diff -urN linux-2.4.29/arch/armnommu/mach-dsc21/setup.c linux-2.4.29-uc1/arch/armnommu/mach-dsc21/setup.c
--- linux-2.4.29/arch/armnommu/mach-dsc21/setup.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-dsc21/setup.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,118 @@
+/*
+ * setup-dsc21.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *   This has additional initialiation needed by the DSC21.
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *          stevej@ridgerun.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <linux/console.h>
+
+const unsigned int _end_kernel_image;
+
+static const char welcome[] = "\nWelcome to the RidgeRun DSC21 Linux port.\n";
+
+void dsc21_console_write(struct console *con, const char *buf, unsigned len)
+{
+	int i;
+
+	for (i = 0; i < len; i++) {
+		if (buf[i] == '\n') {
+			while(!(inw(DSC21_UART1_SR) & 0x0400));
+			outb('\r', DSC21_UART1_DTRR);
+		}
+		while(!(inw(DSC21_UART1_SR) & 0x0400));
+		outb(buf[i], DSC21_UART1_DTRR);		
+	}
+}
+
+static struct console dsc21_console = {
+	name: "dsc21con",
+	write: dsc21_console_write
+};
+
+static void dsc21_external_bus_init(void)
+{
+	/* reset */
+	outw(1, DSC21_EXTBUS_RESET);
+	outw(0, DSC21_EXTBUS_RESET);
+
+	/* 
+	 * write wait cycle = 5 * 21ns
+	 * read wait cycle = 4 * 21ns 
+	 * flash wait cycle = 2 * 21ns 
+	 * type = 0 (CFC)
+	 * mode = 0 (memory mapped) 
+	 */
+	outw(0x5420, DSC21_EXTBUS_MODE);
+
+	/* enable 'flash ready' interrupt */
+	outw(0, DSC21_EXTBUS_INTEN);
+}
+
+static void dsc21_uart_init(void)
+{
+	/* disable ints */
+	outw(0, DSC21_UART0_MSR);
+	outw(0, DSC21_UART1_MSR);
+
+	/* clear fifos */
+	outw(0x8000, DSC21_UART0_RFCR);
+	outw(0x8000, DSC21_UART0_TFCR);
+	outw(0x8000, DSC21_UART1_RFCR);
+	outw(0x8000, DSC21_UART1_TFCR);
+
+	/* no breaks */
+	outw(0, DSC21_UART0_LCR);
+	outw(0, DSC21_UART1_LCR);
+
+	/* Now, setup UART1 for use as a printk console while we boot. */
+
+	/* 115200 baud */
+	outw(0x0013, DSC21_UART1_BRSR);
+
+	/* 8E1 & enable rcv interrupt */
+	outw(0x8010, DSC21_UART1_MSR);
+
+	/* 1 byte rcv fifo trigger */
+	outw(0, DSC21_UART1_RFCR);
+
+	/* 16 byte xmt fifo trigger */
+	outw(0x0300, DSC21_UART1_TFCR);
+}
+
+
+void setup_dsc21(void)
+{
+	extern void register_console(struct console *);
+
+	dsc21_external_bus_init();
+//	dsc21_uart_init();
+//	dsc21_console_write(&dsc21_console, welcome, sizeof(welcome));
+//	register_console(&dsc21_console);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-dsc21/time.c linux-2.4.29-uc1/arch/armnommu/mach-dsc21/time.c
--- linux-2.4.29/arch/armnommu/mach-dsc21/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-dsc21/time.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,60 @@
+/*
+ * time.c  Timer functions for the DSC21.
+ *         
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+extern unsigned long dsc21_gettimeoffset(void)
+{
+	u16 elapsed;
+
+	/* 
+	 * Compute the elapsed count. The current count tells us how
+	 * many counts remain until the next interrupt. LATCH tells us
+	 * how many counts total occur between interrupts. Subtract to
+	 * get the counts since the last interrupt.
+	 */
+	elapsed = LATCH - inb(DSC21_TIMER0_CNT);
+
+	/* 
+	 * Convert the elapsed count to usecs. I guess there are 'tick' usecs
+	 * between every interrupt. 
+	 */
+	return (unsigned long)((elapsed * tick) / LATCH);
+}
+
+void dsc21_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	do_timer(regs);
+}
+
diff -urN linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/arch.c linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/arch.c
--- linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/arch.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ *  uClinux/arch/arm/mach/arch.c
+ *
+ *  Architecture specific fixups.  This is where any
+ *  parameters in the params struct are fixed up, or
+ *  any additional architecture specific information
+ *  is pulled from the params struct.
+ */
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+
+#include <asm/elf.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+extern void genarch_init_irq(void);
+
+MACHINE_START(EVS3C4530HEI, "EV-S3C4530-HEI")
+       MAINTAINER("Oleksandr Zhadan")
+       INITIRQ(genarch_init_irq)
+MACHINE_END
+
+
+void	arch_hard_reset ()
+{
+while (1){};
+}
\ No newline at end of file
diff -urN linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/config.c linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/config.c
--- linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/config.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,89 @@
+/*
+ *  linux/arch/armnommu/$(MACHINE)/config.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999-2003 D. Jeff Dionne <jeff@uClinux.org>
+ *  Copyright (C) 2001-2003 Arcturus Networks Inc. 
+ *                          by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <asm/uCbootstrap.h>
+
+#undef CONFIG_DEBUG
+
+unsigned char *sn;
+
+char S3C4530_HWADDR[]="00:ca:ca:00:00:01";
+char CS8900A_HWADDR[]="00:ca:ca:00:00:02";
+
+#if defined(CONFIG_UCBOOTSTRAP)
+    int	ConTTY = 0;
+    static int errno;
+    _bsc0(char *, getserialnum)
+    _bsc1(unsigned char *, gethwaddr, int, a)
+    _bsc1(char *, getbenv, char *, a)
+#endif
+
+unsigned char *get_MAC_address(char *);
+
+void config_BSP()
+{
+#if defined(CONFIG_UCBOOTSTRAP)
+    printk("uCbootloader: Copyright (C) 2001,2002 Arcturus Networks Inc.\n");
+    printk("uCbootloader system calls are initialized.\n");
+#else
+  sn = (unsigned char *)"123456789012345";
+# ifdef	CONFIG_DEBUG
+    printk("Serial number [%s]\n",sn);
+# endif  
+#endif
+
+}
+
+unsigned char *get_MAC_address(char *devname)
+{
+    char *devnum  = devname + (strlen(devname)-1);
+    char varname[sizeof("HWADDR0")];
+    char *varnum  = varname + (strlen(varname)-1);
+    static unsigned char tmphwaddr[6] = {0, 0, 0, 0, 0, 0};
+    char *ret;
+    int	 i;
+
+    strcpy ( varname, "HWADDR" );
+    strcat ( varname, devnum );
+
+#if defined(CONFIG_UCBOOTSTRAP)
+    ret = getbenv(varname);
+#else
+    if	 ( !strcmp(varname, "HWADDR0") )
+	 ret = (char *)S3C4530_HWADDR;
+    else ret = (char *)CS8900A_HWADDR;
+#endif    
+    memset(tmphwaddr, 0, 6);
+    if	(ret && strlen(ret) == 17)
+	for (i=0; i<6; i++) {
+	    ret[(i+1) * 3 - 1] = 0;
+	    tmphwaddr[i] = simple_strtoul(ret + i*3, 0, 16); 
+	    }
+    return(tmphwaddr);
+}
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff -urN linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/dma.c linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/dma.c
--- linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/dma.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ *  uClinux/arch/arm/mach/dma.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/sched.h>
+#include <linux/malloc.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach/dma.h>
+
+void arch_dma_init(dma_t *dma)
+{
+}
diff -urN linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/io.c linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/io.c
--- linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/io.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/io.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,95 @@
+/*
+ * arch/armnommu/mach/io.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *   io functions
+ *
+ * Copyright (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * Author: RidgeRun, Inc.
+ *         Greg Lonnon (glonnon@ridgerun.com) or info@ridgerun.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  OZH, 2002
+ */
+
+#include <linux/kernel.h>
+#include <asm/io.h>
+#if 0
+void __inline__ insl(unsigned int port, void *to, int len)
+{
+	int i;
+	for (i = 0; i < len; i++)
+		((unsigned long *)to)[i] = inl(port);
+}
+
+void __inline__ insw(unsigned int port, void *to, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		((unsigned short *) to)[i] = inw(port);
+}
+
+void __inline__ insb(unsigned int port, void *to, int len)
+{
+	int i;
+	for (i = 0; i < len; i++)
+		((unsigned char *)to)[i] = inb(port);
+}
+
+void __inline__ outsw(unsigned int port, const void *from, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		outw(((unsigned short *) from)[i], port);
+}
+
+void __inline__ outsl(unsigned int port, const void *from, int len)
+{
+	int i;
+	
+	for (i = 0; i < len; i++) 
+		outl(((unsigned long *) from)[i], port);
+}
+
+void __inline__ outsb(unsigned int port, const void *from, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		outb(((unsigned char *) from)[i], port);
+}
+
+void __inline__ outswb(unsigned int port, const void *from, int len)
+{
+	outsw(port, from, len >> 2);
+}
+
+void __inline__ inswb(unsigned int port, void *to, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		((unsigned short *) to)[i] = inb(port);
+}
+#endif
diff -urN linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/irq.c linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/irq.c
--- linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/irq.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,42 @@
+/*
+ *  arch/armnommu/mach/irq.c
+ *  2001, Oleksandr Zhadan
+ */
+ 
+#include <linux/init.h>
+
+#include <asm/mach/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+
+void __inline__ s3c4530_mask_irq(unsigned int irq)
+{
+    unsigned long mask;
+
+    mask = inl(INTMSK);
+    mask |= ( 1<<irq );
+    outl(mask, INTMSK);
+}	
+
+void __inline__ s3c4530_unmask_irq(unsigned int irq)
+{
+    unsigned long mask;
+    
+    mask = inl(INTMSK);
+    mask &= ~(1<<(irq));
+    mask &= ~(1<<(_GLOBAL));
+    outl(mask, INTMSK);
+}
+
+void __inline__ s3c4530_mask_ack_irq(unsigned int irq)
+{
+    s3c4530_mask_irq( irq);
+}
+
+void __inline__ s3c4530_clear_pb(unsigned int irq)
+{
+    outl( (1<<irq), INTPND);
	/* Clear pending bit */
+}
diff -urN linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/Makefile linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/Makefile
--- linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= evS3C4530HEI.o
+
+# Object file lists.
+
+obj-y			:= $(patsubst %.c, %.o, $(wildcard *.c))
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= 
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/ramlinux.lds linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/ramlinux.lds
--- linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/ramlinux.lds	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/ramlinux.lds	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,116 @@
+/* ld script to make ARM Linux kernel
+ * taken from the i386 version by Russell King
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ */
+INCLUDE arch/armnommu/mach-evS3C4530HEI/romfs.ld 
+OUTPUT_ARCH(arm)
+ENTRY(stext)
+SECTIONS
+{
+
+	. = 0x20000;
+	.init : {			/* Init code and data		*/
+		_stext = .;
+		__init_begin = .;
+			*(.text.init)
+		__proc_info_begin = .;
+			*(.proc.info)
+		__proc_info_end = .;
+		__arch_info_begin = .;
+			*(.arch.info)
+		__arch_info_end = .;
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		__initcall_end = .;
+		. = ALIGN(4096);
+		__init_end = .;
+	}
+
+	/DISCARD/ : {			/* Exit code and data		*/
+		*(.text.exit)
+		*(.data.exit)
+		*(.exitcall.exit)
+	}
+
+	.text : {			/* Real text segment		*/
+		_text = .;		/* Text and read-only data	*/
+			*(.text)
+			*(.fixup)
+			*(.gnu.warning)
+			*(.text.lock)	/* out-of-line lock text */
+			*(.rodata)
+			*(.glue_7)
+			*(.glue_7t)
+			*(.kstrtab)
+		. = ALIGN(16);
+		__start___ex_table = .;	/* Exception table		*/
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;	/* Kernel symbol table		*/
+			*(__ksymtab)
+		__stop___ksymtab = .;
+
+		__start___kallsyms = .; /* All kernel symbols           */
+			*(__kallsyms)
+		__stop___kallsyms = .;
+
+
+		*(.got)			/* Global offset table		*/
+
+		_etext = .;		/* End of text section		*/
+	}
+
+	. = ALIGN(8192);
+
+	__data_start = .;
+	__data_rom_start = .;
+	.data : {
+		/*
+		 * first, the init task union, aligned
+		 * to an 8192 byte boundary.
+		 */
+		*(.init.task)
+
+		/*
+		 * then the cacheline aligned data
+		 */
+		. = ALIGN(32);
+		*(.data.cacheline_aligned)
+
+		/*
+		 * and the usual data section
+		 */
+		*(.data)
+		CONSTRUCTORS
+
+		. = ALIGN(32);	/* To be sure to align .fs . OZH */
+		_edata = .;
+		
+	}
+
+	.bss : {
+		__bss_start = .;	/* BSS				*/
+		*(.bss)
+		*(COMMON)
+		__bss_end = .;
+		_end = . ;
+	}
+
+	. = ALIGN(8192);
+	_end_kernel = . ;
+
+					/* Stabs debugging sections.	*/
+	.stab 0 : { *(.stab) }
+	.stabstr 0 : { *(.stabstr) }
+	.stab.excl 0 : { *(.stab.excl) }
+	.stab.exclstr 0 : { *(.stab.exclstr) }
+	.stab.index 0 : { *(.stab.index) }
+	.stab.indexstr 0 : { *(.stab.indexstr) }
+	.comment 0 : { *(.comment) }
+}
diff -urN linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/romfs.default.ld linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/romfs.default.ld
--- linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/romfs.default.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/romfs.default.ld	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1 @@
+romfs_size =  0;
diff -urN linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/romfs.ld linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/romfs.ld
--- linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/romfs.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/romfs.ld	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1 @@
+romfs_size =  0;
diff -urN linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/romlinux.lds linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/romlinux.lds
--- linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/romlinux.lds	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/romlinux.lds	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,139 @@
+/* ld script to make ARM Linux kernel
+ * taken from the i386 version by Russell King
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *
+ * Added ram/rom parts by O.Zhadan <oleks@arcturusnetworks.com>
+ */
+
+MEMORY
+{
+    ram : ORIGIN = 0x20000, LENGTH = 0x7debfc
+    rom : ORIGIN = 0x1020000, LENGTH = 0x1dfffc
+}
+
+INCLUDE arch/armnommu/mach-cx821xx/romfs.ld
+OUTPUT_ARCH(arm)
+ENTRY(stext)
+SECTIONS
+{
+	.text 0x1020000 :
+	{			/* Real text segment		*/
+		_text = .;		/* Text and read-only data	*/
+		_stext = .;
+			*(.text.init)
+			*(.text)
+			*(.fixup)
+			*(.gnu.warning)
+			*(.text.lock)	/* out-of-line lock text */
+			*(.rodata)
+			*(.glue_7)
+			*(.glue_7t)
+			*(.kstrtab)
+		. = ALIGN(16);
+		__start___ex_table = .;	/* Exception table		*/
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;	/* Kernel symbol table		*/
+			*(__ksymtab)
+		__stop___ksymtab = .;
+
+		__start___kallsyms = .; /* All kernel symbols           */
+			*(__kallsyms)
+		__stop___kallsyms = .;
+
+
+		*(.got)			/* Global offset table		*/
+
+		_etext = .;		/* End of text section		*/
+		
+		. = ALIGN(32);
+	} > rom
+
+	.fs :	
+	{
+		_romfs = ABSOLUTE (.);
+		. = . + romfs_size;
+		_end_romfs = ABSOLUTE (.);
+	} > rom
+
+	
+	.init 0x20000 :
+	AT ( _end_romfs )
+	{			/* Init code and data		*/
+		
+		__init_begin = ABSOLUTE(.);
+		__proc_info_begin = ABSOLUTE(.);
+			*(.proc.info)
+		PROVIDE(__proc_info_end = .);
+		__arch_info_begin = ABSOLUTE(.);
+			*(.arch.info)
+		PROVIDE(__arch_info_end = .);
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = ABSOLUTE(.);
+			*(.setup.init)
+		PROVIDE(__setup_end = .);
+		__initcall_start = ABSOLUTE(.);
+			*(.initcall.init)
+		PROVIDE(__initcall_end = .);
+		. = ALIGN(4096);
+		PROVIDE(__init_end = .);
+	} > ram
+
+	/DISCARD/ : 
+	{			/* Exit code and data		*/
+		*(.text.exit)
+		*(.data.exit)
+		*(.exitcall.exit)
+	} > ram
+
+	
+	.data : 
+	AT ( _end_romfs + SIZEOF (.init))
+	{
+		. = ALIGN(8192);
+		__data_start = ABSOLUTE(.);
+		__data_rom_start = ABSOLUTE(.);
+		/*
+		 * first, the init task union, aligned
+		 * to an 8192 byte boundary.
+		 */
+		*(.init.task)
+
+		/*
+		 * then the cacheline aligned data
+		 */
+		. = ALIGN(32);
+		*(.data.cacheline_aligned)
+
+		/*
+		 * and the usual data section
+		 */
+		*(.data)
+		CONSTRUCTORS
+
+		PROVIDE(_edata = .);
+		
+	} > ram
+
+	.bss : {
+		__bss_start = ABSOLUTE(.);	/* BSS				*/
+		PROVIDE(bss_start = .);
+		*(.bss)
+		*(COMMON)
+		PROVIDE(_end = .);
+		__bss_end = ABSOLUTE(.);
+		. = ALIGN(8192);
+		PROVIDE(_end_kernel = .);
+	} > ram
+
+					/* Stabs debugging sections.	*/
+	.stab 0 : { *(.stab) }
+	.stabstr 0 : { *(.stabstr) }
+	.stab.excl 0 : { *(.stab.excl) }
+	.stab.exclstr 0 : { *(.stab.exclstr) }
+	.stab.index 0 : { *(.stab.index) }
+	.stab.indexstr 0 : { *(.stab.indexstr) }
+	.comment 0 : { *(.comment) }
+}
diff -urN linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/time.c linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/time.c
--- linux-2.4.29/arch/armnommu/mach-evS3C4530HEI/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-evS3C4530HEI/time.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ * time.c  Timer functions for evS3C4530HEI
+ * OZH, 2001 Oleksandr Zhadan
+ */
+
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+#define CLOCKS_PER_USEC	50	/* (ARM_CLK/1000000) */
+
+unsigned long s3c4530_gettimeoffset (void)
+{
+    struct s3c4530_timer* tt = (struct s3c4530_timer*) (TIMER_BASE);
+#if 	( KERNEL_TIMER==0 ) 
+    return ((tt->tdr0 - tt->tcr0) / CLOCKS_PER_USEC);
+#elif	( KERNEL_TIMER==1 ) 
+    return ((tt->tdr1 - tt->tcr1) / CLOCKS_PER_USEC);
+#else
+#error Weird -- KERNEL_TIMER does not seem to be defined...
+#endif	
+}
+
+void s3c4530_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+    do_timer(regs);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-integrator/arch.c linux-2.4.29-uc1/arch/armnommu/mach-integrator/arch.c
--- linux-2.4.29/arch/armnommu/mach-integrator/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-integrator/arch.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,70 @@
+/*
+ *  linux/arch/arm/mach-integrator/arch.c
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/config.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/amba_kmi.h>
+
+extern void integrator_map_io(void);
+extern void integrator_init_irq(void);
+
+#ifdef CONFIG_KMI_KEYB
+static struct kmi_info integrator_keyboard __initdata = {
+	base:	IO_ADDRESS(KMI0_BASE),
+	irq:	IRQ_KMIINT0,
+	divisor: 24 / 8 - 1,
+	type:	KMI_KEYBOARD,
+};
+
+static struct kmi_info integrator_mouse __initdata = {
+	base:	IO_ADDRESS(KMI1_BASE),
+	irq:	IRQ_KMIINT1,
+	divisor: 24 / 8 - 1,
+	type:	KMI_MOUSE,
+};
+#endif
+
+static void __init
+integrator_fixup(struct machine_desc *desc, struct param_struct *unused,
+		 char **cmdline, struct meminfo *mi)
+{
+#ifdef CONFIG_KMI_KEYB
+	register_kmi(&integrator_keyboard);
+	register_kmi(&integrator_mouse);
+#endif
+}
+
+MACHINE_START(INTEGRATOR, "ARM-Integrator")
+	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
+	BOOT_MEM(0x00000000, 0x16000000, 0x16000000)
+	BOOT_PARAMS(0x00000100)
+	FIXUP(integrator_fixup)
+	MAPIO(integrator_map_io)
+	INITIRQ(integrator_init_irq)
+MACHINE_END
diff -urN linux-2.4.29/arch/armnommu/mach-integrator/cpu.c linux-2.4.29-uc1/arch/armnommu/mach-integrator/cpu.c
--- linux-2.4.29/arch/armnommu/mach-integrator/cpu.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-integrator/cpu.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,132 @@
+/*
+ *  linux/arch/arm/mach-integrator/cpu.c
+ *
+ *  Copyright (C) 2001 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * CPU support functions
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/cpufreq.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#define CM_ID  	(IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_ID_OFFSET)
+#define CM_OSC	(IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_OSC_OFFSET)
+#define CM_STAT (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_STAT_OFFSET)
+#define CM_LOCK (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET)
+
+struct vco {
+	unsigned char vdw;
+	unsigned char od;
+};
+
+/*
+ * Divisors for each OD setting.
+ */
+static unsigned char cc_divisor[8] = { 10, 2, 8, 4, 5, 7, 9, 6 };
+
+static unsigned int vco_to_freq(struct vco vco, int factor)
+{
+	return 2000 * (vco.vdw + 8) / cc_divisor[vco.od] / factor;
+}
+
+#ifdef CONFIG_CPU_FREQ
+/*
+ * Divisor indexes for in ascending divisor order
+ */
+static unsigned char s2od[] = { 1, 3, 4, 7, 5, 2, 6, 0 };
+
+static struct vco freq_to_vco(unsigned int freq_khz, int factor)
+{
+	struct vco vco = {0, 0};
+	unsigned int i, f;
+
+	freq_khz *= factor;
+
+	for (i = 0; i < 8; i++) {
+		f = freq_khz * cc_divisor[s2od[i]];
+		/* f must be between 10MHz and 320MHz */
+		if (f > 10000 && f <= 320000)
+			break;
+	}
+
+	vco.od  = s2od[i];
+	vco.vdw = f / 2000 - 8;
+
+	return vco;
+}
+
+/*
+ * Validate the speed in khz.  If it is outside our
+ * range, then return the lowest.
+ */
+unsigned int integrator_validatespeed(unsigned int freq_khz)
+{
+	struct vco vco;
+
+	if (freq_khz < 12000)
+		freq_khz = 12000;
+	if (freq_khz > 160000)
+		freq_khz = 160000;
+
+	vco = freq_to_vco(freq_khz, 1);
+
+	if (vco.vdw < 4 || vco.vdw > 152)
+		return -EINVAL;
+
+	return vco_to_freq(vco, 1);
+}
+
+void integrator_setspeed(unsigned int freq_khz)
+{
+	struct vco vco = freq_to_vco(freq_khz, 1);
+	u_int cm_osc;
+
+	cm_osc = __raw_readl(CM_OSC);
+	cm_osc &= 0xfffff800;
+	cm_osc |= vco.vdw | vco.od << 8;
+
+	__raw_writel(0xa05f, CM_LOCK);
+	__raw_writel(cm_osc, CM_OSC);
+	__raw_writel(0, CM_LOCK);
+}
+#endif
+
+static int __init cpu_init(void)
+{
+	u_int cm_osc, cm_stat, cpu_freq_khz, mem_freq_khz;
+	struct vco vco;
+
+	cm_osc = __raw_readl(CM_OSC);
+
+	vco.od  = (cm_osc >> 20) & 7;
+	vco.vdw = (cm_osc >> 12) & 255;
+	mem_freq_khz = vco_to_freq(vco, 2);
+
+	printk(KERN_INFO "Memory clock = %d.%03d MHz\n",
+		mem_freq_khz / 1000, mem_freq_khz % 1000);
+
+	vco.od = (cm_osc >> 8) & 7;
+	vco.vdw = cm_osc & 255;
+	cpu_freq_khz = vco_to_freq(vco, 1);
+
+#ifdef CONFIG_CPU_FREQ
+	cpufreq_init(cpu_freq_khz);
+	cpufreq_setfunctions(integrator_validatespeed, integrator_setspeed);
+#endif
+
+	cm_stat = __raw_readl(CM_STAT);
+	printk("Module id: %d\n", cm_stat & 255);
+
+	return 0;
+}
+
+__initcall(cpu_init);
diff -urN linux-2.4.29/arch/armnommu/mach-integrator/dma.c linux-2.4.29-uc1/arch/armnommu/mach-integrator/dma.c
--- linux-2.4.29/arch/armnommu/mach-integrator/dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-integrator/dma.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,36 @@
+/*
+ *  linux/arch/arm/mach-integrator/dma.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/dma.h>
+
+void __init arch_dma_init(dma_t *dma)
+{
+}
diff -urN linux-2.4.29/arch/armnommu/mach-integrator/irq.c linux-2.4.29-uc1/arch/armnommu/mach-integrator/irq.c
--- linux-2.4.29/arch/armnommu/mach-integrator/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-integrator/irq.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,71 @@
+/*
+ *  linux/arch/arm/mach-integrator/irq.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/irq.h>
+
+/* 
+ * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
+ * is the (PA >> 12).
+ *
+ * Setup a VA for the Integrator interrupt controller (for header #0,
+ * just for now).
+ */
+#define VA_IC_BASE              IO_ADDRESS(INTEGRATOR_IC_BASE) 
+#define VA_CMIC_BASE            IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET
+
+#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) ) 
+
+static void sc_mask_irq(unsigned int irq)
+{
+        __raw_writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+}
+
+static void sc_unmask_irq(unsigned int irq)
+{
+        __raw_writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET);
+}
+ 
+void __init integrator_init_irq(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < NR_IRQS; i++) {
+	        if (((1 << i) && INTEGRATOR_SC_VALID_INT) != 0) {
+		        irq_desc[i].valid	= 1;
+			irq_desc[i].probe_ok	= 1;
+			irq_desc[i].mask_ack	= sc_mask_irq;
+			irq_desc[i].mask	= sc_mask_irq;
+			irq_desc[i].unmask	= sc_unmask_irq;
+		}
+	}
+
+	/* Disable all interrupts initially. */
+	/* Do the core module ones */
+	__raw_writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+
+	/* do the header card stuff next */
+	__raw_writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+	__raw_writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-integrator/leds.c linux-2.4.29-uc1/arch/armnommu/mach-integrator/leds.c
--- linux-2.4.29/arch/armnommu/mach-integrator/leds.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-integrator/leds.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,94 @@
+/*
+ *  linux/arch/arm/mach-integrator/leds.c
+ *
+ *  Integrator LED control routines
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+static int saved_leds;
+
+static void integrator_leds_event(led_event_t ledevt)
+{
+	unsigned long flags;
+	const unsigned int dbg_base = IO_ADDRESS(INTEGRATOR_DBG_BASE);
+	const unsigned int hdr_ctrl = IO_ADDRESS(INTEGRATOR_HDR_BASE) +
+					INTEGRATOR_HDR_CTRL_OFFSET;
+	unsigned int ctrl;
+	unsigned int update_alpha_leds;
+	
+	// yup, change the LEDs
+	local_irq_save(flags);
+	update_alpha_leds = 0;
+
+	switch(ledevt) {
+	case led_idle_start:
+		ctrl = __raw_readl(hdr_ctrl);
+		ctrl &= ~INTEGRATOR_HDR_CTRL_LED;
+		__raw_writel(ctrl, hdr_ctrl);
+		break;
+
+	case led_idle_end:
+		ctrl = __raw_readl(hdr_ctrl);
+		ctrl |= INTEGRATOR_HDR_CTRL_LED;
+		__raw_writel(ctrl, hdr_ctrl);
+		break;
+
+	case led_timer:
+		saved_leds ^= GREEN_LED;
+		update_alpha_leds = 1;
+		break;
+
+	case led_red_on:
+		saved_leds |= RED_LED;
+		update_alpha_leds = 1;
+		break;
+
+	case led_red_off:
+		saved_leds &= ~RED_LED;
+		update_alpha_leds = 1;
+		break;
+
+	default:
+		break;
+	}
+
+	if (update_alpha_leds) {
+		while (__raw_readl(dbg_base + INTEGRATOR_DBG_ALPHA_OFFSET) & 1);
+		__raw_writel(saved_leds, dbg_base + INTEGRATOR_DBG_LEDS_OFFSET);
+	}
+	local_irq_restore(flags);
+}
+
+static int __init leds_init(void)
+{
+	if (machine_is_integrator())
+		leds_event = integrator_leds_event;
+
+	return 0;
+}
+
+__initcall(leds_init);
diff -urN linux-2.4.29/arch/armnommu/mach-integrator/Makefile linux-2.4.29-uc1/arch/armnommu/mach-integrator/Makefile
--- linux-2.4.29/arch/armnommu/mach-integrator/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-integrator/Makefile	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,24 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= integrator.o
+
+# Object file lists.
+
+obj-y			:= arch.o cpu.o irq.o mm.o time.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= leds.o
+
+obj-$(CONFIG_LEDS)	+= leds.o
+obj-$(CONFIG_PCI)	+= pci_v3.o pci.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-integrator/mm.c linux-2.4.29-uc1/arch/armnommu/mach-integrator/mm.c
--- linux-2.4.29/arch/armnommu/mach-integrator/mm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-integrator/mm.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,78 @@
+/*
+ *  linux/arch/arm/mach-integrator/mm.c
+ *
+ *  Extra MM routines for the ARM Integrator board
+ *
+ *  Copyright (C) 1999,2000 Arm Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+ 
+#include <asm/mach/map.h>
+
+/*
+ * Logical      Physical
+ * e8000000	40000000	PCI memory
+ * ec000000	62000000	PCI config space
+ * ed000000	61000000	PCI V3 regs
+ * ee000000	60000000	PCI IO
+ * ef000000			Cache flush
+ * f1000000	10000000	Core module registers
+ * f1100000	11000000	System controller registers
+ * f1200000	12000000	EBI registers
+ * f1300000	13000000	Counter/Timer
+ * f1400000	14000000	Interrupt controller
+ * f1500000	15000000	RTC
+ * f1600000	16000000	UART 0
+ * f1700000	17000000	UART 1
+ * f1800000	18000000	Keyboard
+ * f1900000	19000000	Mouse
+ * f1a00000	1a000000	Debug LEDs
+ * f1b00000	1b000000	GPIO
+ */
+ 
+static struct map_desc integrator_io_desc[] __initdata = {
+ { IO_ADDRESS(INTEGRATOR_HDR_BASE),   INTEGRATOR_HDR_BASE,   SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_SC_BASE),    INTEGRATOR_SC_BASE,    SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_EBI_BASE),   INTEGRATOR_EBI_BASE,   SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_CT_BASE),    INTEGRATOR_CT_BASE,    SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_IC_BASE),    INTEGRATOR_IC_BASE,    SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_RTC_BASE),   INTEGRATOR_RTC_BASE,   SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_KBD_BASE),   INTEGRATOR_KBD_BASE,   SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_MOUSE_BASE), INTEGRATOR_MOUSE_BASE, SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_DBG_BASE),   INTEGRATOR_DBG_BASE,   SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_GPIO_BASE),  INTEGRATOR_GPIO_BASE,  SZ_4K     , DOMAIN_IO, 0, 1},
+ { PCI_MEMORY_VADDR,                  PHYS_PCI_MEM_BASE,     SZ_16M    , DOMAIN_IO, 0, 1},
+ { PCI_CONFIG_VADDR,                  PHYS_PCI_CONFIG_BASE,  SZ_16M    , DOMAIN_IO, 0, 1},
+ { PCI_V3_VADDR,                      PHYS_PCI_V3_BASE,      SZ_512K   , DOMAIN_IO, 0, 1},
+ { PCI_IO_VADDR,                      PHYS_PCI_IO_BASE,      SZ_64K    , DOMAIN_IO, 0, 1},
+ LAST_DESC
+};
+
+void __init integrator_map_io(void)
+{
+	iotable_init(integrator_io_desc);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-integrator/pci.c linux-2.4.29-uc1/arch/armnommu/mach-integrator/pci.c
--- linux-2.4.29/arch/armnommu/mach-integrator/pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-integrator/pci.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,122 @@
+/*
+ *  linux/arch/arm/mach-integrator/pci-integrator.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *
+ *  PCI functions for Integrator
+ */
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+
+/* 
+ * A small note about bridges and interrupts.  The DECchip 21050 (and
+ * later) adheres to the PCI-PCI bridge specification.  This says that
+ * the interrupts on the other side of a bridge are swizzled in the
+ * following manner:
+ *
+ * Dev    Interrupt   Interrupt 
+ *        Pin on      Pin on 
+ *        Device      Connector
+ *
+ *   4    A           A
+ *        B           B
+ *        C           C
+ *        D           D
+ * 
+ *   5    A           B
+ *        B           C
+ *        C           D
+ *        D           A
+ *
+ *   6    A           C
+ *        B           D
+ *        C           A
+ *        D           B
+ *
+ *   7    A           D
+ *        B           A
+ *        C           B
+ *        D           C
+ *
+ * Where A = pin 1, B = pin 2 and so on and pin=0 = default = A.
+ * Thus, each swizzle is ((pin-1) + (device#-4)) % 4
+ *
+ * The following code swizzles for exactly one bridge.  
+ */
+static inline int bridge_swizzle(int pin, unsigned int slot) 
+{
+	return (pin + slot) & 3;
+}
+
+/*
+ * This routine handles multiple bridges.
+ */
+static u8 __init integrator_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	int pin = *pinp;
+
+	if (pin == 0)
+		pin = 1;
+
+	pin -= 1;
+	while (dev->bus->self) {
+		pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+		/*
+		 * move up the chain of bridges, swizzling as we go.
+		 */
+		dev = dev->bus->self;
+	}
+	*pinp = pin + 1;
+
+	return PCI_SLOT(dev->devfn);
+}
+
+static int irq_tab[4] __initdata = {
+	IRQ_PCIINT0,	IRQ_PCIINT1,	IRQ_PCIINT2,	IRQ_PCIINT3
+};
+
+/*
+ * map the specified device/slot/pin to an IRQ.  This works out such
+ * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
+ */
+static int __init integrator_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int intnr = ((slot - 9) + (pin - 1)) & 3;
+
+	return irq_tab[intnr];
+}
+
+extern void pci_v3_setup_resources(struct resource **res);
+extern void pci_v3_init(void *);
+
+struct hw_pci integrator_pci __initdata = {
+	setup_resources:	pci_v3_setup_resources,
+	init:			pci_v3_init,
+	mem_offset:		0x40000000,
+	swizzle:		integrator_swizzle,
+	map_irq:		integrator_map_irq,
+};
diff -urN linux-2.4.29/arch/armnommu/mach-integrator/pci_v3.c linux-2.4.29-uc1/arch/armnommu/mach-integrator/pci_v3.c
--- linux-2.4.29/arch/armnommu/mach-integrator/pci_v3.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-integrator/pci_v3.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,574 @@
+/*
+ *  linux/arch/arm/mach-integrator/pci_v3.c
+ *
+ *  PCI functions for V3 host PCI bridge
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+
+#include <asm/hardware/pci_v3.h>
+
+/*
+ * The V3 PCI interface chip in Integrator provides several windows from
+ * local bus memory into the PCI memory areas.   Unfortunately, there
+ * are not really enough windows for our usage, therefore we reuse 
+ * one of the windows for access to PCI configuration space.  The
+ * memory map is as follows:
+ * 
+ * Local Bus Memory         Usage
+ * 
+ * 40000000 - 4FFFFFFF      PCI memory.  256M non-prefetchable
+ * 50000000 - 5FFFFFFF      PCI memory.  256M prefetchable
+ * 60000000 - 60FFFFFF      PCI IO.  16M
+ * 68000000 - 68FFFFFF      PCI Configuration. 16M
+ * 
+ * There are three V3 windows, each described by a pair of V3 registers.
+ * These are LB_BASE0/LB_MAP0, LB_BASE1/LB_MAP1 and LB_BASE2/LB_MAP2.
+ * Base0 and Base1 can be used for any type of PCI memory access.   Base2
+ * can be used either for PCI I/O or for I20 accesses.  By default, uHAL
+ * uses this only for PCI IO space.
+ * 
+ * PCI Memory is mapped so that assigned addresses in PCI Memory match
+ * local bus memory addresses.  In other words, if a PCI device is assigned
+ * address 80200000 then that address is a valid local bus address as well
+ * as a valid PCI Memory address.  PCI IO addresses are mapped to start
+ * at zero.  This means that local bus address 60000000 maps to PCI IO address
+ * 00000000 and so on.   Device driver writers need to be aware of this 
+ * distinction.
+ * 
+ * Normally these spaces are mapped using the following base registers:
+ * 
+ * Usage Local Bus Memory         Base/Map registers used
+ * 
+ * Mem   40000000 - 4FFFFFFF      LB_BASE0/LB_MAP0
+ * Mem   50000000 - 5FFFFFFF      LB_BASE1/LB_MAP1
+ * IO    60000000 - 60FFFFFF      LB_BASE2/LB_MAP2
+ * Cfg   68000000 - 68FFFFFF      
+ * 
+ * This means that I20 and PCI configuration space accesses will fail.
+ * When PCI configuration accesses are needed (via the uHAL PCI 
+ * configuration space primitives) we must remap the spaces as follows:
+ * 
+ * Usage Local Bus Memory         Base/Map registers used
+ * 
+ * Mem   40000000 - 4FFFFFFF      LB_BASE0/LB_MAP0
+ * Mem   50000000 - 5FFFFFFF      LB_BASE0/LB_MAP0
+ * IO    60000000 - 60FFFFFF      LB_BASE2/LB_MAP2
+ * Cfg   68000000 - 68FFFFFF      LB_BASE1/LB_MAP1
+ * 
+ * To make this work, the code depends on overlapping windows working.
+ * The V3 chip translates an address by checking its range within 
+ * each of the BASE/MAP pairs in turn (in ascending register number
+ * order).  It will use the first matching pair.   So, for example,
+ * if the same address is mapped by both LB_BASE0/LB_MAP0 and
+ * LB_BASE1/LB_MAP1, the V3 will use the translation from 
+ * LB_BASE0/LB_MAP0.
+ * 
+ * To allow PCI Configuration space access, the code enlarges the
+ * window mapped by LB_BASE0/LB_MAP0 from 256M to 512M.  This occludes
+ * the windows currently mapped by LB_BASE1/LB_MAP1 so that it can
+ * be remapped for use by configuration cycles.
+ * 
+ * At the end of the PCI Configuration space accesses, 
+ * LB_BASE1/LB_MAP1 is reset to map PCI Memory.  Finally the window
+ * mapped by LB_BASE0/LB_MAP0 is reduced in size from 512M to 256M to
+ * reveal the now restored LB_BASE1/LB_MAP1 window.
+ * 
+ * NOTE: We do not set up I2O mapping.  I suspect that this is only
+ * for an intelligent (target) device.  Using I2O disables most of
+ * the mappings into PCI memory.
+ */
+
+// V3 access routines
+#define v3_writeb(o,v) __raw_writeb(v, PCI_V3_VADDR + (unsigned int)(o))
+#define v3_readb(o)    (__raw_readb(PCI_V3_VADDR + (unsigned int)(o)))
+
+#define v3_writew(o,v) __raw_writew(v, PCI_V3_VADDR + (unsigned int)(o))
+#define v3_readw(o)    (__raw_readw(PCI_V3_VADDR + (unsigned int)(o)))
+
+#define v3_writel(o,v) __raw_writel(v, PCI_V3_VADDR + (unsigned int)(o))
+#define v3_readl(o)    (__raw_readl(PCI_V3_VADDR + (unsigned int)(o)))
+
+/*============================================================================
+ *
+ * routine:	uHALir_PCIMakeConfigAddress()
+ *
+ * parameters:	bus = which bus
+ *              device = which device
+ *              function = which function
+ *		offset = configuration space register we are interested in
+ *
+ * description:	this routine will generate a platform dependant config
+ *		address.
+ *
+ * calls:	none
+ *
+ * returns:	configuration address to play on the PCI bus
+ *
+ * To generate the appropriate PCI configuration cycles in the PCI 
+ * configuration address space, you present the V3 with the following pattern 
+ * (which is very nearly a type 1 (except that the lower two bits are 00 and
+ * not 01).   In order for this mapping to work you need to set up one of
+ * the local to PCI aperatures to 16Mbytes in length translating to
+ * PCI configuration space starting at 0x0000.0000.
+ *
+ * PCI configuration cycles look like this:
+ *
+ * Type 0:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *	31:11	Device select bit.
+ * 	10:8	Function number
+ * 	 7:2	Register number
+ *
+ * Type 1:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *	31:24	reserved
+ *	23:16	bus number (8 bits = 128 possible buses)
+ *	15:11	Device number (5 bits)
+ *	10:8	function number
+ *	 7:2	register number
+ *  
+ */
+static spinlock_t v3_lock = SPIN_LOCK_UNLOCKED;
+
+#define PCI_BUS_NONMEM_START	0x00000000
+#define PCI_BUS_NONMEM_SIZE	0x10000000
+
+#define PCI_BUS_PREMEM_START	0x10000000
+#define PCI_BUS_PREMEM_SIZE	0x10000000
+
+#if PCI_BUS_NONMEM_START & 0x000fffff
+#error PCI_BUS_NONMEM_START must be megabyte aligned
+#endif
+#if PCI_BUS_PREMEM_START & 0x000fffff
+#error PCI_BUS_PREMEM_START must be megabyte aligned
+#endif
+
+#undef V3_LB_BASE_PREFETCH
+#define V3_LB_BASE_PREFETCH 0
+
+static unsigned long v3_open_config_window(struct pci_dev *dev, int offset)
+{
+	unsigned int address, mapaddress, busnr;
+
+	busnr = dev->bus->number;
+
+	/*
+	 * Trap out illegal values
+	 */
+	if (offset > 255)
+		BUG();
+	if (busnr > 255)
+		BUG();
+	if (dev->devfn > 255)
+		BUG();
+
+	if (busnr == 0) {
+		int slot = PCI_SLOT(dev->devfn);
+
+		/*
+		 * local bus segment so need a type 0 config cycle
+		 *
+		 * build the PCI configuration "address" with one-hot in
+		 * A31-A11
+		 *
+		 * mapaddress:
+		 *  3:1 = config cycle (101)
+		 *  0   = PCI A1 & A0 are 0 (0)
+		 */
+		address = PCI_FUNC(dev->devfn) << 8;
+		mapaddress = V3_LB_MAP_TYPE_CONFIG;
+
+		if (slot > 12)
+			/*
+			 * high order bits are handled by the MAP register
+			 */
+			mapaddress |= 1 << (slot - 5);
+		else
+			/*
+			 * low order bits handled directly in the address
+			 */
+			address |= 1 << (slot + 11);
+	} else {
+        	/*
+		 * not the local bus segment so need a type 1 config cycle
+		 *
+		 * address:
+		 *  23:16 = bus number
+		 *  15:11 = slot number (7:3 of devfn)
+		 *  10:8  = func number (2:0 of devfn)
+		 *
+		 * mapaddress:
+		 *  3:1 = config cycle (101)
+		 *  0   = PCI A1 & A0 from host bus (1)
+		 */
+		mapaddress = V3_LB_MAP_TYPE_CONFIG | V3_LB_MAP_AD_LOW_EN;
+		address = (busnr << 16) | (dev->devfn << 8);
+	}
+
+	/*
+	 * Set up base0 to see all 512Mbytes of memory space (not
+	 * prefetchable), this frees up base1 for re-use by
+	 * configuration memory
+	 */
+	v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
+			V3_LB_BASE_ADR_SIZE_512MB | V3_LB_BASE_ENABLE);
+
+	/*
+	 * Set up base1/map1 to point into configuration space.
+	 */
+	v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_CONFIG_BASE) |
+			V3_LB_BASE_ADR_SIZE_16MB | V3_LB_BASE_ENABLE);
+	v3_writew(V3_LB_MAP1, mapaddress);
+
+	return PCI_CONFIG_VADDR + address + offset;
+}
+
+static void v3_close_config_window(void)
+{
+	/*
+	 * Reassign base1 for use by prefetchable PCI memory
+	 */
+	v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) |
+			V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
+			V3_LB_BASE_ENABLE);
+	v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) |
+			V3_LB_MAP_TYPE_MEM_MULTIPLE);
+
+	/*
+	 * And shrink base0 back to a 256M window (NOTE: MAP0 already correct)
+	 */
+	v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
+			V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
+}
+
+static int v3_read_config_byte(struct pci_dev *dev, int where, u8 *val)
+{
+	unsigned long addr;
+	unsigned long flags;
+	u8 v;
+
+	spin_lock_irqsave(&v3_lock, flags);
+	addr = v3_open_config_window(dev, where);
+
+	v = __raw_readb(addr);
+
+	v3_close_config_window();
+	spin_unlock_irqrestore(&v3_lock, flags);
+
+	*val = v;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int v3_read_config_word(struct pci_dev *dev, int where, u16 *val)
+{
+	unsigned long addr;
+	unsigned long flags;
+	u16 v;
+
+	spin_lock_irqsave(&v3_lock, flags);
+	addr = v3_open_config_window(dev, where);
+
+	v = __raw_readw(addr);
+
+	v3_close_config_window();
+	spin_unlock_irqrestore(&v3_lock, flags);
+
+	*val = v;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int v3_read_config_dword(struct pci_dev *dev, int where, u32 *val)
+{
+	unsigned long addr;
+	unsigned long flags;
+	u32 v;
+
+	spin_lock_irqsave(&v3_lock, flags);
+	addr = v3_open_config_window(dev, where);
+
+	v = __raw_readl(addr);
+
+	v3_close_config_window();
+	spin_unlock_irqrestore(&v3_lock, flags);
+
+	*val = v;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int v3_write_config_byte(struct pci_dev *dev, int where, u8 val)
+{
+	unsigned long addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&v3_lock, flags);
+	addr = v3_open_config_window(dev, where);
+
+	__raw_writeb(val, addr);
+	__raw_readb(addr);
+	
+	v3_close_config_window();
+	spin_unlock_irqrestore(&v3_lock, flags);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int v3_write_config_word(struct pci_dev *dev, int where, u16 val)
+{
+	unsigned long addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&v3_lock, flags);
+	addr = v3_open_config_window(dev, where);
+
+	__raw_writew(val, addr);
+	__raw_readw(addr);
+
+	v3_close_config_window();
+	spin_unlock_irqrestore(&v3_lock, flags);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int v3_write_config_dword(struct pci_dev *dev, int where, u32 val)
+{
+	unsigned long addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&v3_lock, flags);
+	addr = v3_open_config_window(dev, where);
+
+	__raw_writel(val, addr);
+	__raw_readl(addr);
+
+	v3_close_config_window();
+	spin_unlock_irqrestore(&v3_lock, flags);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_v3_ops = {
+	read_byte:	v3_read_config_byte,
+	read_word:	v3_read_config_word,
+	read_dword:	v3_read_config_dword,
+	write_byte:	v3_write_config_byte,
+	write_word:	v3_write_config_word,
+	write_dword:	v3_write_config_dword,
+};
+
+static struct resource non_mem = {
+	name:	"PCI non-prefetchable",
+	start:	0x40000000 + PCI_BUS_NONMEM_START,
+	end:	0x40000000 + PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE - 1,
+	flags:	IORESOURCE_MEM,
+};
+
+static struct resource pre_mem = {
+	name:	"PCI prefetchable",
+	start:	0x40000000 + PCI_BUS_PREMEM_START,
+	end:	0x40000000 + PCI_BUS_PREMEM_START + PCI_BUS_PREMEM_SIZE - 1,
+	flags:	IORESOURCE_MEM | IORESOURCE_PREFETCH,
+};
+
+void __init pci_v3_setup_resources(struct resource **resource)
+{
+	if (request_resource(&iomem_resource, &non_mem))
+		printk("PCI: unable to allocate non-prefetchable memory region\n");
+	if (request_resource(&iomem_resource, &pre_mem))
+		printk("PCI: unable to allocate prefetchable memory region\n");
+
+	/*
+	 * bus->resource[0] is the IO resource for this bus
+	 * bus->resource[1] is the mem resource for this bus
+	 * bus->resource[2] is the prefetch mem resource for this bus
+	 */
+	resource[0] = &ioport_resource;
+	resource[1] = &non_mem;
+	resource[2] = &pre_mem;
+}
+
+/*
+ * These don't seem to be implemented on the Integrator I have, which
+ * means I can't get additional information on the reason for the pm2fb
+ * problems.  I suppose I'll just have to mind-meld with the machine. ;)
+ */
+#define SC_PCI     (IO_ADDRESS(INTEGRATOR_SC_PCIENABLE))
+#define SC_LBFADDR (IO_ADDRESS(INTEGRATOR_SC_BASE+0x20))
+#define SC_LBFCODE (IO_ADDRESS(INTEGRATOR_SC_BASE+0x24))
+
+static int v3_fault(unsigned long addr, struct pt_regs *regs)
+{
+	unsigned long pc = instruction_pointer(regs);
+	unsigned long instr = *(unsigned long *)pc;
+
+	printk("V3 fault: address=0x%08lx, pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n",
+		addr, pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255,
+		v3_readb(V3_LB_ISTAT));
+
+	v3_writeb(V3_LB_ISTAT, 0);
+	__raw_writel(3, SC_PCI);
+
+	/*
+	 * If the instruction being executed was a read,
+	 * make it look like it read all-ones.
+	 */
+	if ((instr & 0x0c100000) == 0x04100000) {
+		int reg = (instr >> 12) & 15;
+		unsigned long val;
+
+		if (instr & 0x00400000)
+			val = 255;
+		else
+			val = -1;
+
+		regs->uregs[reg] = val;
+		regs->ARM_pc += 4;
+		return 0;
+	}
+
+	return 1;
+}
+
+static void v3_irq(int irq, void *devid, struct pt_regs *regs)
+{
+	unsigned long pc = instruction_pointer(regs);
+	unsigned long instr = *(unsigned long *)pc;
+	char buf[128];
+
+	sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n", irq,
+		pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255,
+		v3_readb(V3_LB_ISTAT));
+	printascii(buf);
+
+	v3_writeb(V3_LB_ISTAT, 0);
+	__raw_writel(3, SC_PCI);
+
+	/*
+	 * If the instruction being executed was a read,
+	 * make it look like it read all-ones.
+	 */
+	if ((instr & 0x0c100000) == 0x04100000) {
+		int reg = (instr >> 16) & 15;
+		sprintf(buf, "   reg%d = %08lx\n", reg, regs->uregs[reg]);
+		printascii(buf);
+	}
+}
+
+static struct irqaction v3_int = {
+	name: "V3",
+	handler: v3_irq,
+};
+static struct irqaction v3_int2 = {
+	name: "V3TM",
+	handler: v3_irq,
+};
+
+extern int (*external_fault)(unsigned long addr, struct pt_regs *regs);
+
+/*
+ * V3_LB_BASE? - local bus address
+ * V3_LB_MAP?  - pci bus address
+ */
+void __init pci_v3_init(void *sysdata)
+{
+	unsigned int pci_cmd;
+	unsigned long flags;
+
+	/*
+	 * Hook in our fault handler for PCI errors
+	 */
+	external_fault = v3_fault;
+
+	spin_lock_irqsave(&v3_lock, flags);
+
+	/*
+	 * Setup window 0 - PCI non-prefetchable memory
+	 *  Local: 0x40000000 Bus: 0x00000000 Size: 256MB
+	 */
+	v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
+			V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
+	v3_writew(V3_LB_MAP0, v3_addr_to_lb_map(PCI_BUS_NONMEM_START) |
+			V3_LB_MAP_TYPE_MEM);
+
+	/*
+	 * Setup window 1 - PCI prefetchable memory
+	 *  Local: 0x50000000 Bus: 0x10000000 Size: 256MB
+	 */
+	v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) |
+			V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
+			V3_LB_BASE_ENABLE);
+	v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) |
+			V3_LB_MAP_TYPE_MEM_MULTIPLE);
+
+	/*
+	 * Setup window 2 - PCI IO
+	 */
+	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(PHYS_PCI_IO_BASE) |
+			V3_LB_BASE_ENABLE);
+	v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0));
+
+	spin_unlock_irqrestore(&v3_lock, flags);
+
+	pci_scan_bus(0, &pci_v3_ops, sysdata);
+
+	pci_cmd = PCI_COMMAND_MEMORY |
+		  PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
+
+	v3_writew(V3_PCI_CMD, pci_cmd);
+
+	/*
+	 * Clear any error conditions.
+	 */
+	__raw_writel(3, SC_PCI);
+	v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10));
+	v3_writeb(V3_LB_ISTAT, 0);
+	v3_writeb(V3_LB_IMASK, 0x68);
+
+	printk("LB_CFG: %04x LB_ISTAT: %02x LB_IMASK: %02x\n",
+		v3_readw(V3_LB_CFG),
+		v3_readb(V3_LB_ISTAT),
+		v3_readb(V3_LB_IMASK));
+	setup_arm_irq(IRQ_V3INT, &v3_int);
+//	setup_arm_irq(IRQ_LBUSTIMEOUT, &v3_int2);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-integrator/time.c linux-2.4.29-uc1/arch/armnommu/mach-integrator/time.c
--- linux-2.4.29/arch/armnommu/mach-integrator/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-integrator/time.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,46 @@
+/*
+ *  linux/arch/arm/mach-integrator/time.c
+ *
+ *  Copyright (C) 2000-2001 Deep Blue Solutions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#define RTC_DR		(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 0)
+#define RTC_MR		(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 4)
+#define RTC_STAT	(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 8)
+#define RTC_EOI		(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 8)
+#define RTC_LR		(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 12)
+#define RTC_CR		(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 16)
+
+#define RTC_CR_MIE	0x00000001
+
+extern int (*set_rtc)(void);
+
+static int integrator_set_rtc(void)
+{
+	__raw_writel(xtime.tv_sec, RTC_LR);
+	return 1;
+}
+
+static int integrator_rtc_init(void)
+{
+	__raw_writel(0, RTC_CR);
+	__raw_writel(0, RTC_EOI);
+
+	xtime.tv_sec = __raw_readl(RTC_DR);
+
+	set_rtc = integrator_set_rtc;
+
+	return 0;
+}
+
+__initcall(integrator_rtc_init);
diff -urN linux-2.4.29/arch/armnommu/mach-ipod/arch.c linux-2.4.29-uc1/arch/armnommu/mach-ipod/arch.c
--- linux-2.4.29/arch/armnommu/mach-ipod/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ipod/arch.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ * arch.c - architecture definition for iPod
+ *
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/irq.h>
+#include <asm/mach/arch.h>
+
+static void __init
+ipod_fixup(struct machine_desc *desc, struct param_struct *params,
+	char **cmdline, struct meminfo *mi)
+{
+}
+
+MACHINE_START(IPOD, "iPod")
+	MAINTAINER("Bernard Leach")
+	BOOT_MEM(0x28000000, 0xc0000000, 0x00000000)
+	INITIRQ(ipod_init_irq)
+	FIXUP(ipod_fixup)
+MACHINE_END
+
diff -urN linux-2.4.29/arch/armnommu/mach-ipod/audio.c linux-2.4.29-uc1/arch/armnommu/mach-ipod/audio.c
--- linux-2.4.29/arch/armnommu/mach-ipod/audio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ipod/audio.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,494 @@
+/*
+ * ipod_audio.c - audio driver for iPod
+ *
+ * Copyright (c) 2003,2004 Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/major.h>
+#include <linux/delay.h>
+#include <linux/soundcard.h>
+#include <linux/sound.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/hardware.h>
+
+
+#define D2A_POWER_OFF   1
+#define D2A_POWER_SB    2
+#define D2A_POWER_ON    3
+
+/* locations for our shared variables */
+#define DMA_READ_OFF	0x40000000
+#define DMA_WRITE_OFF	0x40000004
+#define DMA_ACTIVE	0x40000008
+#define DMA_BASE	0x4000000c
+
+/* length of shared buffer in half-words (starting at DMA_BASE) */
+#define BUF_LEN		(46*1024)
+
+/* volumes in dB */
+#define MAX_VOLUME      6
+#define MIN_VOLUME      -73
+
+#define LRHPBOTH        0x100
+#define ZERO_DB         0x79
+
+static int ipodaudio_isopen;
+static int ipodaudio_power_state;
+static unsigned ipod_hw_ver;
+static devfs_handle_t devfs_handle;
+
+static void
+set_clock_enb(unsigned short clks, int on)
+{
+	if ( on ) {
+		outw(inw(0xcf005000) | clks, 0xcf005000);
+	}
+	else {
+		outw(inw(0xcf005000) & ~clks, 0xcf005000);
+	}
+}
+
+static void
+d2a_set_active(int active)
+{
+	// set active to 0x0 or 0x1
+	if ( active == 0 ) {
+		ipod_i2c_send(0x1a, 0x12, 0x00);
+
+	} else {
+		ipod_i2c_send(0x1a, 0x12, 0x01);
+	}
+}
+
+static void
+d2a_set_power(int new_state)
+{
+	if ( ipodaudio_power_state == new_state) {
+		return;
+	}
+
+	if ( new_state != D2A_POWER_OFF ) {
+		set_clock_enb((1<<1), 0x1);
+	}
+
+	if ( new_state == D2A_POWER_ON ) {
+		// set power register to POWER_OFF=0 on OUTPD=0, DACPD=0
+		ipod_i2c_send(0x1a, 0xc, 0x67);
+
+		// de-activate the d2a
+		d2a_set_active(0x0);
+
+		// set DACSEL=1
+		if (ipod_hw_ver == 0x3) {
+			ipod_i2c_send(0x1a, 0x8, 0x18);
+		} else {
+			ipod_i2c_send(0x1a, 0x8, 0x10);
+		}
+
+		// set DACMU=0 DEEMPH=0
+		ipod_i2c_send(0x1a, 0xa, 0x00);
+
+		// set BCLKINV=0(Dont invert BCLK) MS=1(Enable Master) LRSWAP=0 LRP=0 IWL=10(24 bit) FORMAT=10(I2S format)
+		ipod_i2c_send(0x1a, 0xe, 0x4a);
+
+		// set CLKIDIV2=0 SR=1000 BOSR=1 USB/NORM=1
+		//cmd[0] = 0x10; cmd[1] = 0x23;
+
+		// set CLKIDIV2=1 SR=1000 BOSR=1 (272fs) USB/NORM=1 (USB)
+		ipod_i2c_send(0x1a, 0x10, 0x63);
+
+		// set CLKIDIV2=1 SR=0011 BOSR=0 (fs) USB/NORM=1 (USB)
+		//ipod_i2c_send(0x1a, 0x10, 0x4d);
+
+		// activate the d2a
+		d2a_set_active(0x1);
+	}
+	else {
+		/* power off or standby the audio chip */
+
+		// set DACMU=1 DEEMPH=0
+		ipod_i2c_send(0x1a, 0xa, 0x8);
+
+		// set DACSEL=0
+		ipod_i2c_send(0x1a, 0x8, 0x0);
+
+		// set POWEROFF=0 OUTPD=0 DACPD=1
+		ipod_i2c_send(0x1a, 0xc, 0x6f);
+
+		if ( new_state == D2A_POWER_OFF ) {
+			/* power off the chip */
+
+			// set POWEROFF=1 OUTPD=1 DACPD=1
+			ipod_i2c_send(0x1a, 0xc, 0xff);
+
+			set_clock_enb((1<<1), 0x0);
+		}
+		else {
+			/* standby the chip */
+
+			// set POWEROFF=0 OUTPD=1 DACPD=1
+			ipod_i2c_send(0x1a, 0xc, 0x7f);
+		}
+	}
+
+	ipodaudio_power_state = new_state;
+}
+
+static void d2a_set_vol(int vol)
+{
+	unsigned int v;
+
+	if ( vol > MAX_VOLUME ) {
+		vol = MAX_VOLUME;
+	}
+
+	if ( vol < MIN_VOLUME ) {
+		vol = MIN_VOLUME;
+	}
+
+	v = (vol + ZERO_DB) | LRHPBOTH;
+
+	// set volume
+	ipod_i2c_send(0x1a, 0x4 | (v >> 8), v);
+}
+
+static void ipodaudio_process_dma(void)
+{
+	volatile int *r_off = (int *)DMA_READ_OFF;
+	volatile int *w_off = (int *)DMA_WRITE_OFF;
+	volatile int *dma_active = (int *)DMA_ACTIVE;
+	volatile unsigned short *dma_buf = (unsigned short *)DMA_BASE;
+
+	inl(0xcf001040);
+	outl(inl(0xc000251c) & ~(1<<9), 0xc000251c);
+
+	while ( *r_off != *w_off ) {
+		while ( (inl(0xc000251c) & 0x7800000) == 0 ) {
+		}
+
+		outl(((unsigned)dma_buf[*r_off]) << 16, 0xc0002540);
+
+		*r_off = (*r_off + 1) % BUF_LEN;
+	}
+
+	*dma_active = 0;
+}
+
+static int ipodaudio_open(struct inode *inode, struct file *filep)
+{
+	if ( ipodaudio_isopen ) {
+		return -EBUSY;
+	}
+
+	ipodaudio_isopen = 1;
+
+	d2a_set_power(D2A_POWER_ON);
+
+	// set the volument to -6dB
+	d2a_set_vol(-20);
+
+	if (ipod_hw_ver == 0x3) {
+		/* 3g */
+		outl(inl(0xcf004048) & ~0x1, 0xcf004048);
+
+		outl(inl(0xcf004040) | 0x400, 0xcf004040);
+		outl(inl(0xcf004040) & ~0x800, 0xcf004040);
+
+		outl(inl(0xcf000004) & ~0xf, 0xcf000004);
+	}
+	else {
+		/* 1g, 2g */
+		outl(inl(0xcf004040) & ~0x400, 0xcf004040);
+		outl(inl(0xcf004040) | 0x800, 0xcf004040);
+	}
+
+	outl(inl(0xcf00000c) | 0x40, 0xcf00000c);
+	outl(inl(0xcf00001c) & ~0x40, 0xcf00001c);
+
+	/* cop setup */
+	ipod_set_process_dma(ipodaudio_process_dma);
+	outl(inl(0xcf00103c) | (1 << DMA_OUT_IRQ) , 0xcf00103c);
+	outl((1 << DMA_OUT_IRQ), 0xcf001034);
+
+	return 0;
+}
+
+static void ipodaudio_txdrain(void)
+{
+	while ( (inl(0xc000251c) & (1<<0)) == 0 ) {
+		// empty
+	}
+}
+
+static int ipodaudio_close(struct inode *inode, struct file *filp)
+{
+	ipodaudio_txdrain();
+
+	d2a_set_power(D2A_POWER_OFF);
+
+	ipodaudio_isopen = 0;
+
+	return 0;
+}
+
+
+static ssize_t ipodaudio_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
+{
+	unsigned short *bufsp;
+	size_t rem;
+
+	volatile int *r_off = (int *)DMA_READ_OFF;
+	volatile int *w_off = (int *)DMA_WRITE_OFF;
+	int write_off_current, write_off_next, read_off_current;
+	volatile int *dma_active = (int *)DMA_ACTIVE;
+	volatile unsigned short *dma_buf = (unsigned short *)DMA_BASE;
+
+	if ( count <= 0 ) {
+		return 0;
+	}
+
+	bufsp = (unsigned short *)buf;
+	rem = count/2;
+
+	write_off_current = *w_off;
+
+	while ( rem > 0 ) {
+		int cnt;
+
+		write_off_next = (write_off_current + 1);
+		if ( write_off_next > BUF_LEN ) write_off_next = 0;
+
+		read_off_current = *r_off;
+
+		if ( read_off_current < write_off_current ) {
+			cnt = BUF_LEN - 1 - write_off_current;
+
+			if ( cnt > 0 )  {
+				if ( cnt > rem ) cnt = rem;
+
+				memcpy((void*)&dma_buf[write_off_next], bufsp, cnt<<1);
+
+				rem -= cnt;
+				bufsp += cnt;
+
+				if ( read_off_current > 0 && rem > 0 ) {
+					int n;
+
+					if ( rem > read_off_current ) {
+						n = read_off_current;
+					}
+					else {
+						n = rem;
+					}
+
+					memcpy((void*)&dma_buf[0], bufsp, n<<1);
+
+					rem -= n;
+					bufsp += n;
+
+					write_off_current = n - 1;
+				}
+				else {
+					write_off_current += cnt;
+				}
+			}
+		}
+		else if ( read_off_current > write_off_current ) {
+			cnt = read_off_current - 1 - write_off_current;
+			if ( cnt > rem ) cnt = rem;
+
+			memcpy((void*)&dma_buf[write_off_next], bufsp, cnt<<1);
+
+			bufsp += cnt;
+			rem -= cnt;
+
+			write_off_current += cnt;
+		}
+		else {
+			/* buffer is empty */
+			if ( rem < BUF_LEN ) {
+				cnt = rem;
+			}
+			else {
+				cnt = BUF_LEN;
+			}
+			memcpy((void*)&dma_buf[0], bufsp, cnt<<1);
+
+			bufsp += cnt;
+			rem -= cnt;
+
+			write_off_current = cnt - 1;
+
+			/* we have copied to the start of the buffer */
+			*r_off = 0;
+		}
+
+		if ( !*dma_active ) {
+			*dma_active = 1;
+
+			*w_off = write_off_current;
+
+			outl(inl(0xc000251c)|(1<<9), 0xc000251c);
+
+			/* dummy write to start things */
+			outl(0x0, 0xc0002540);
+		}
+	}
+
+	*w_off = write_off_current;
+
+	return count;
+}
+
+static int ipodaudio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	int rc = 0;
+	unsigned long val;
+
+	switch (cmd) {
+	case SNDCTL_DSP_SPEED:
+		rc = verify_area(VERIFY_READ, (void *) arg, sizeof(val));
+		if ( rc == 0 ) {
+			get_user(val, (unsigned long *) arg);
+			if ( val != 44100 ) {
+				put_user(44100, (long *) arg);
+			}
+		}
+		break;
+
+	case SNDCTL_DSP_GETFMTS:
+		rc = verify_area(VERIFY_READ, (void *) arg, sizeof(val));
+		if ( rc == 0 ) {
+			put_user(AFMT_S16_LE, (long *) arg);
+		}
+
+	case SNDCTL_DSP_SETFMT:
+	/* case SNDCTL_DSP_SAMPLESIZE: */
+		rc = verify_area(VERIFY_READ, (void *) arg, sizeof(val));
+		if ( rc == 0 ) {
+			get_user(val, (unsigned long *) arg);
+			if ( val != AFMT_S16_LE ) {
+				put_user(AFMT_S16_LE, (long *) arg);
+			}
+		}
+		break;
+
+	case SNDCTL_DSP_STEREO:
+		rc = verify_area(VERIFY_READ, (void *) arg, sizeof(val));
+		if ( rc == 0 ) {
+			get_user(val, (unsigned long *) arg);
+			if ( val != 1 ) {
+				put_user(1, (long *) arg);
+			}
+		}
+		break;
+
+	case SNDCTL_DSP_GETBLKSIZE:
+		rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
+		if ( rc == 0 ) {
+			put_user(BUF_LEN/2, (long *) arg);
+		}
+		break;
+
+	case SNDCTL_DSP_SYNC:
+		ipodaudio_txdrain();
+		break;
+	}
+
+	return rc;
+}
+
+static struct file_operations  ipodaudio_fops = {
+	open: ipodaudio_open,
+	release: ipodaudio_close,
+	write: ipodaudio_write,
+	ioctl: ipodaudio_ioctl,
+};
+
+static int __init ipodaudio_init(void)
+{
+	volatile int *r_off = (int *)DMA_READ_OFF;
+	volatile int *w_off = (int *)DMA_WRITE_OFF;
+	volatile int *dma_active = (int *)DMA_ACTIVE;
+
+	printk("ipodaudio: (c) Copyright 2003,2004 Bernard Leach (leachbj@bouncycastle.org)\n\n");
+
+	devfs_handle = devfs_register(NULL, "dsp", DEVFS_FL_DEFAULT,
+			SOUND_MAJOR, SND_DEV_DSP,
+			S_IFCHR | S_IWUSR | S_IRUSR,
+			&ipodaudio_fops, NULL);
+	if (devfs_handle < 0) {
+		printk(KERN_WARNING "SOUND: failed to register major %d\n",
+			SOUND_MAJOR);
+		return 0;
+	}
+	if (devfs_register_chrdev(SOUND_MAJOR, "dsp", &ipodaudio_fops) < 0) {
+		printk(KERN_WARNING "SOUND: failed to register major %d\n",
+			SOUND_MAJOR);
+		devfs_unregister(devfs_handle);
+		return 0;
+	}
+
+
+	/* initialise shared variables */
+	*r_off = 0;
+	*w_off = 0;
+	*dma_active = 0;
+
+	ipod_hw_ver = ipod_get_hw_version() >> 16;
+	if (ipod_hw_ver == 0x3) {
+		outl(inl(0xcf005030) | (1<<8), 0xcf005030);
+		outl(inl(0xcf005030) & ~(1<<8), 0xcf005030);
+
+		outl(inl(0xcf005000) | (1<<1), 0xcf005000);
+
+		outl(inl(0xc000251c) | 0x10000, 0xc000251c);
+		outl(inl(0xc000251c) & ~0x10000, 0xc000251c);
+
+		outl(0xd, 0xc0002500);
+
+		outl(inl(0xcf00000c) | 0x40, 0xcf00000c);
+		outl(inl(0xcf00001c) & ~0x40, 0xcf00001c);
+	}
+	else {
+		outl(inl(0xcf005000) | (1<<1), 0xcf005000);
+
+		outl(inl(0xc000251c) | 0x10000, 0xc000251c);
+		outl(inl(0xc000251c) & ~0x10000, 0xc000251c);
+
+		outl(0x5, 0xc0002500);
+
+		outl(inl(0xcf00000c) | 0x40, 0xcf00000c);
+		outl(inl(0xcf00001c) & ~0x40, 0xcf00001c);
+	}
+
+	return 0;
+}
+
+static void __exit ipodaudio_exit(void)
+{
+	ipod_set_process_dma(0);
+
+	devfs_unregister_chrdev(SOUND_MAJOR, "dsp");
+	devfs_unregister(devfs_handle);
+}
+
+module_init(ipodaudio_init);
+module_exit(ipodaudio_exit);
+
+MODULE_AUTHOR("Bernard Leach <leachbj@bouncycastle.org>");
+MODULE_DESCRIPTION("Audio driver for IPod");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/arch/armnommu/mach-ipod/cop.S linux-2.4.29-uc1/arch/armnommu/mach-ipod/cop.S
--- linux-2.4.29/arch/armnommu/mach-ipod/cop.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ipod/cop.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,83 @@
+/*
+ * cop.S - coprocessor code
+ *
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+	.global cop_fiq
+	.global cop_end
+	.global cop_idle
+
+	.equ C_PROCESSOR_ID, 0xc4000000
+	.equ C_CPU_ID, 0x55
+
+	.equ C_CFG_COPROC, 0xcf004058
+	.equ C_CPU_SLEEP, 0xca
+
+cop_fiq:
+	stmdb   sp!, {r0, lr}
+
+.ifdef NOTDEF
+	ldr	r0, L_lcd_base
+	ldr	r1, [r0]
+	orr	r1, r1, #0x2
+	str	r1, [r0]
+.endif
+	ldr	r0, L_C_PROCESSOR_ID
+	ldr	r0, [r0]
+	and	r0, r0, #0xff
+	cmp	r0, #C_CPU_ID
+	beq	1f
+
+	mov	lr, pc
+	ldr	pc, L_ipod_handle_dma
+
+	nop
+	nop
+	nop
+
+1:
+	ldmia   sp!, {r0, lr}
+	subs	pc, lr, #4
+
+L_C_PROCESSOR_ID:	.word C_PROCESSOR_ID
+
+cop_fiq_end:
+
+cop_idle:
+	/* enable FIQ */
+	mrs     r0, cpsr
+	bic     r0, r0, #0x40
+	msr     cpsr_c, r0
+
+cop_sleep:
+	/* put us (co-processor) to sleep */
+	ldr	r4, L_CFG_COPROC
+	mov	r3, #C_CPU_SLEEP
+	strh	r3, [r4]
+
+	nop
+	nop
+
+	b	cop_sleep
+
+	.global cop_fiq_stack
+	.global cop_svc_stack
+
+	.lcomm cop_fiq_stack, 1024
+	.lcomm cop_svc_stack, 1024
+
+L_CFG_COPROC:	.word C_CFG_COPROC
+
+L_ipod_handle_dma:.word ipod_handle_dma
+
+L_lcd_base:	.word 0xc0001000
+
+/* these must match those in audio.c */
+L_DMA_READ_OFF:	.word 0x40000000
+L_DMA_WRITE_OFF:.word 0x40000004
+L_DMA_ACTIVE:	.word 0x40000008
+L_DMA_BASE:	.word 0x4000000c
+
+cop_end:
+
diff -urN linux-2.4.29/arch/armnommu/mach-ipod/dma.c linux-2.4.29-uc1/arch/armnommu/mach-ipod/dma.c
--- linux-2.4.29/arch/armnommu/mach-ipod/dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ipod/dma.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,14 @@
+/*
+ * dma.c - dma driver for iPod
+ *
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#include <linux/init.h>
+#include <asm/dma.h>
+#include <asm/mach/dma.h>
+
+void __init arch_dma_init(dma_t *dma)
+{
+}
+
diff -urN linux-2.4.29/arch/armnommu/mach-ipod/fb.c linux-2.4.29-uc1/arch/armnommu/mach-ipod/fb.c
--- linux-2.4.29/arch/armnommu/mach-ipod/fb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ipod/fb.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,775 @@
+/*
+ * fb.c - Frame-buffer driver for iPod
+ *
+ * Copyright (c) 2003,2004 Bernard Leach (leachbj@bouncycastle.org)
+ *
+ * The LCD uses the HD66753 controller from Hitachi (now owned by Renesas).
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-cfb2.h>
+
+/* the ID returned by the controller */
+#define HD66753_ID	0x5307
+
+#define IPOD_LCD_BASE	0xc0001000
+#define IPOD_RTC	0xcf001110
+
+#define IPOD_LCD_WIDTH	160
+#define IPOD_LCD_HEIGHT	128
+
+/* allow for 2bpp */
+static char ipod_scr[IPOD_LCD_HEIGHT * (IPOD_LCD_WIDTH/4)];
+
+
+/* get current usec counter */
+static int
+timer_get_current(void)
+{
+	return inl(IPOD_RTC);
+}
+
+/* check if number of useconds has past */
+static int
+timer_check(int clock_start, int usecs)
+{
+	if ( (inl(IPOD_RTC) - clock_start) >= usecs ) {
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+/* wait for LCD with timeout */
+static void
+lcd_wait_write(void)
+{
+	if ( (inl(IPOD_LCD_BASE) & 0x1) != 0 ) {
+		int start = timer_get_current();
+
+		do {
+			if ( (inl(IPOD_LCD_BASE) & (unsigned int)0x8000) == 0 ) break;
+		} while ( timer_check(start, 1000) == 0 );
+	}
+}
+
+
+/* send LCD data */
+static void
+lcd_send_data(int data_lo, int data_hi)
+{
+	lcd_wait_write();
+	outl(data_lo, 0xc0001010);
+	lcd_wait_write();
+	outl(data_hi, 0xc0001010);
+}
+
+/* send LCD command */
+static void
+lcd_prepare_cmd(int cmd)
+{
+	lcd_wait_write();
+	outl(0x0, 0xc0001008);
+	lcd_wait_write();
+	outl(cmd, 0xc0001008);
+}
+
+/* send LCD command and data */
+static void
+lcd_cmd_and_data(int cmd, int data_lo, int data_hi)
+{
+	lcd_prepare_cmd(cmd);
+
+	lcd_send_data(data_lo, data_hi);
+}
+
+static unsigned
+get_contrast(void)
+{
+	unsigned data_lo, data_hi;
+
+	/* data_lo has the scan line */
+	lcd_wait_write();
+	data_lo = inl(0xc0001008);
+	/* data_hi has the contrast */
+	lcd_wait_write();
+	data_hi = inl(0xc0001008);
+
+	return data_hi & 0xff;
+}
+
+static void
+set_contrast(int contrast)
+{
+	lcd_cmd_and_data(0x4, 0x4, contrast);
+}
+
+static int
+get_backlight(void)
+{
+	return inl(IPOD_LCD_BASE) & 0x2 ? 1 : 0;
+}
+
+static void
+set_backlight(int on)
+{
+	int lcd_state = inl(IPOD_LCD_BASE);
+
+	if (on) {
+		lcd_state = lcd_state | 0x2;
+		outl(lcd_state, IPOD_LCD_BASE);
+
+		/* display control (1 00 0 1) */
+		/* GSH=01 -> 2/3 level grayscale control */
+		/* GSL=00 -> 1/4 level grayscale control */
+		/* REV=0 -> don't reverse */
+		/* D=1 -> display on */
+		lcd_cmd_and_data(0x7, 0x0, 0x11 /* | 0x2 */);
+	}
+	else {
+		lcd_state = lcd_state & ~0x2;
+		outl(lcd_state, IPOD_LCD_BASE);
+
+		/* display control (10 0 1) */
+		/* GSL=10 -> 2/4 level grayscale control */
+		/* REV=0 -> don't reverse */
+		/* D=1 -> display on */
+		lcd_cmd_and_data(0x7, 0x0, 0x9 /* | 0x2 */);
+	}
+}
+
+static unsigned
+read_controller_id(void)
+{
+	unsigned data_lo, data_hi;
+
+	/* read the Start Osciallation register -> it gives us a id */
+	lcd_prepare_cmd(0x0);
+
+	lcd_wait_write();
+	data_lo = inl(0xc0001010);
+	lcd_wait_write();
+	data_hi = inl(0xc0001010);
+
+	return ((data_hi & 0xff) << 8) | (data_lo & 0xff);
+}
+
+/* initialise the LCD */
+static void
+init_lcd(void)
+{
+	if ( read_controller_id() != HD66753_ID )  {
+		printk(KERN_ERR "Unknown LCD controller ID: 0x%x id?\n", read_controller_id());
+	}
+
+	/* driver output control - 168x128 -> we use 160x128 */
+	/* CMS=0, SGS=1 */
+	lcd_cmd_and_data(0x1, 0x1, 0xf);
+
+	/* ID=1 -> auto decrement address counter */
+	/* AM=00 -> data is continuously written in parallel */
+	/* LG=00 -> no logical operation */
+	lcd_cmd_and_data(0x5, 0x0, 0x10);
+
+	/* backlight off & set grayscale */
+	set_backlight(0);
+}
+
+
+void contrast_up(void)
+{
+	int contrast = get_contrast();
+	if ( contrast < 0xff ) {
+		contrast++; 
+		lcd_cmd_and_data(0x4, 0x4, contrast);
+
+#if 0
+		printk("ctrst=0x%x\n", get_contrast());
+#endif
+	}
+}
+
+void contrast_down(void)
+{
+	int contrast = get_contrast();
+	if ( contrast > 0 ) {
+		contrast--; 
+		lcd_cmd_and_data(0x4, 0x4, contrast);
+
+#if 0
+		printk("ctrst=0x%x\n", get_contrast());
+#endif
+	}
+}
+
+static void ipod_update_display(struct display *p, int sx, int sy, int mx, int my)
+{
+	unsigned short cursor_pos;
+	unsigned short y;
+
+	cursor_pos = sx + (sy * fontheight(p) * 0x20);
+
+	for ( y = sy * fontheight(p); y < my * fontheight(p); y++ ) {
+		unsigned char *img_data;
+		unsigned char x;
+
+		/* move the cursor */
+		lcd_cmd_and_data(0x11, cursor_pos >> 8, cursor_pos & 0xff);
+
+		/* setup for printing */
+		lcd_prepare_cmd(0x12);
+
+		/* cursor pos * image data width */
+		img_data = &ipod_scr[y * p->line_length + sx * 2];
+
+		/* 160/8 -> 20 == loops 20 times */
+		for ( x = sx; x < mx; x++ ) {
+			/* display a character */
+			lcd_send_data(*(img_data + 1), *img_data);
+
+			img_data += 2;
+		}
+
+		/* update cursor pos counter */
+		cursor_pos += 0x20;
+	}
+}
+
+struct ipodfb_info {
+	/*
+	 *  Choose _one_ of the two alternatives:
+	 *
+	 *    1. Use the generic frame buffer operations (fbgen_*).
+	 */
+	struct fb_info_gen gen;
+
+#if 0
+	/*
+	 *    2. Provide your own frame buffer operations.
+	 */
+	struct fb_info info;
+#endif
+
+	/* Here starts the frame buffer device dependent part */
+	/* You can use this to store e.g. the board number if you support */
+	/* multiple boards */
+};
+
+
+struct ipodfb_par {
+	/*
+	 *  The hardware specific data in this structure uniquely defines a video
+	 *  mode.
+	 *
+	 *  If your hardware supports only one video mode, you can leave it empty.
+	 */
+};
+
+
+void ipod_fb_setup(struct display *p)
+{
+	fbcon_cfb2.setup(p);
+}
+
+void ipod_fb_bmove(struct display *p, int sy, int sx, int dy, int dx,
+		     int height, int width)
+{
+	fbcon_cfb2.bmove(p, sy, sx, dy, dx, height, width);
+	ipod_update_display(p, 0, 0, IPOD_LCD_WIDTH/8, IPOD_LCD_HEIGHT/fontheight(p));
+}
+
+void ipod_fb_clear(struct vc_data *conp, struct display *p, int sy, int sx,
+		     int height, int width)
+{
+	fbcon_cfb2.clear(conp, p, sy, sx, height, width);
+	ipod_update_display(p, sx, sy, sx+width, sy+height);
+}
+
+void ipod_fb_putc(struct vc_data *conp, struct display *p, int c, int yy,
+		    int xx)
+{
+	fbcon_cfb2.putc(conp, p, c, yy, xx);
+	ipod_update_display(p, xx, yy, xx+1, yy+1);
+}
+
+void ipod_fb_putcs(struct vc_data *conp, struct display *p, 
+		     const unsigned short *s, int count, int yy, int xx)
+{
+	fbcon_cfb2.putcs(conp, p, s, count, yy, xx);
+	ipod_update_display(p, xx, yy, xx+count, yy+1);
+}
+
+void ipod_fb_revc(struct display *p, int xx, int yy)
+{
+	fbcon_cfb2.revc(p, xx, yy);
+	ipod_update_display(p, xx, yy, xx+1, yy+1);
+}
+
+
+/*
+ *  `switch' for the low level operations
+ */
+
+struct display_switch fbcon_ipod = {
+	setup:		ipod_fb_setup,
+	bmove:		ipod_fb_bmove,
+	clear:		ipod_fb_clear,
+	putc:		ipod_fb_putc,
+	putcs:		ipod_fb_putcs,
+	revc:		ipod_fb_revc,
+	fontwidthmask:	FONTWIDTH(8)
+};
+
+static struct ipodfb_info fb_info;
+static struct ipodfb_par current_par;
+static int current_par_valid = 0;
+static struct display disp;
+
+static struct fb_var_screeninfo default_var;
+
+int ipodfb_init(void);
+int ipodfb_setup(char*);
+
+/* ------------------- chipset specific functions -------------------------- */
+
+static void ipod_get_par(struct ipodfb_par *, const struct fb_info *);
+static int ipod_encode_var(struct fb_var_screeninfo *, struct ipodfb_par *, const struct fb_info *);
+
+static void ipod_detect(void)
+{
+	/*
+	 *  This function should detect the current video mode settings and store
+	 *  it as the default video mode
+	 */
+
+	struct ipodfb_par par;
+
+	ipod_get_par(&par, NULL);
+	ipod_encode_var(&default_var, &par, NULL);
+}
+
+static int ipod_encode_fix(struct fb_fix_screeninfo *fix, struct ipodfb_par *par,
+			  const struct fb_info *info)
+{
+	/*
+	 *  This function should fill in the 'fix' structure based on the values
+	 *  in the `par' structure.
+	 */
+
+	memset(fix, 0x0, sizeof(*fix));
+
+	strcpy(fix->id, "iPod");
+	/* required for mmap() */
+	fix->smem_start = ipod_scr;
+	fix->smem_len = IPOD_LCD_HEIGHT * (IPOD_LCD_WIDTH/4);
+
+	fix->type= FB_TYPE_PACKED_PIXELS;
+
+	fix->visual = FB_VISUAL_PSEUDOCOLOR;	/* fixed visual */
+	fix->line_length = IPOD_LCD_WIDTH >> 2;	/* cfb2 default */
+
+	fix->xpanstep = 0;	/* no hardware panning */
+	fix->ypanstep = 0;	/* no hardware panning */
+	fix->ywrapstep = 0;	/* */
+
+	fix->accel = FB_ACCEL_NONE;
+
+	return 0;
+}
+
+static int ipod_decode_var(struct fb_var_screeninfo *var, struct ipodfb_par *par,
+			  const struct fb_info *info)
+{
+	/*
+	 *  Get the video params out of 'var'. If a value doesn't fit, round it up,
+	 *  if it's too big, return -EINVAL.
+	 *
+	 *  Suggestion: Round up in the following order: bits_per_pixel, xres,
+	 *  yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
+	 *  bitfields, horizontal timing, vertical timing.
+	 */
+
+	if ( var->xres > IPOD_LCD_WIDTH ||
+		var->yres > IPOD_LCD_HEIGHT ||
+		var->xres_virtual != var->xres ||
+		var->yres_virtual != var->yres ||
+		var->xoffset != 0 ||
+		var->yoffset != 0 ) {
+		return -EINVAL;
+	}
+
+	if ( var->bits_per_pixel != 2 ) {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int ipod_encode_var(struct fb_var_screeninfo *var, struct ipodfb_par *par,
+			  const struct fb_info *info)
+{
+	/*
+	 *  Fill the 'var' structure based on the values in 'par' and maybe other
+	 *  values read out of the hardware.
+	 */
+
+	var->xres = IPOD_LCD_WIDTH;
+	var->yres = IPOD_LCD_HEIGHT;
+	var->xres_virtual = var->xres;
+	var->yres_virtual = var->yres;
+	var->xoffset = 0;
+	var->yoffset = 0;
+
+	var->bits_per_pixel = 2;
+	var->grayscale = 1;
+
+	return 0;
+}
+
+static void ipod_get_par(struct ipodfb_par *par, const struct fb_info *info)
+{
+	/*
+	 *  Fill the hardware's 'par' structure.
+	 */
+
+	if ( current_par_valid ) {
+		*par = current_par;
+	}
+	else {
+		/* ... */
+	}
+}
+
+static void ipod_set_par(struct ipodfb_par *par, const struct fb_info *info)
+{
+	/*
+	 *  Set the hardware according to 'par'.
+	 */
+
+	current_par = *par;
+	current_par_valid = 1;
+
+	/* ... */
+}
+
+static int ipod_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+			 unsigned *blue, unsigned *transp,
+			 const struct fb_info *info)
+{
+	/*
+	 *  Read a single color register and split it into colors/transparent.
+	 *  The return values must have a 16 bit magnitude.
+	 *  Return != 0 for invalid regno.
+	 */
+
+	/* ... */
+	return 0;
+}
+
+static int ipod_setcolreg(unsigned regno, unsigned red, unsigned green,
+			 unsigned blue, unsigned transp,
+			 const struct fb_info *info)
+{
+	/*
+	 *  Set a single color register. The values supplied have a 16 bit
+	 *  magnitude.
+	 *  Return != 0 for invalid regno.
+	 */
+
+	/* ... */
+	return 0;
+}
+
+static int ipod_pan_display(struct fb_var_screeninfo *var,
+			   struct ipodfb_par *par, const struct fb_info *info)
+{
+	/*
+	 *  Pan (or wrap, depending on the `vmode' field) the display using the
+	 *  `xoffset' and `yoffset' fields of the `var' structure.
+	 *  If the values don't fit, return -EINVAL.
+	 */
+
+	/* ... */
+	return -EINVAL;
+}
+
+static int ipod_blank(int blank_mode, const struct fb_info *info)
+{
+	static int backlight_on = -1;
+
+	switch (blank_mode) {
+	case VESA_NO_BLANKING:
+		/* printk(KERN_ERR "VESA_NO_BLANKING\n"); */
+
+		/* start oscillation
+		 * wait 10ms
+		 * cancel standby
+		 * turn on LCD power
+		 */
+		lcd_cmd_and_data(0x0, 0x0, 0x1);
+		udelay(10000);
+		lcd_cmd_and_data(0x3, 0x15, 0x0);
+		lcd_cmd_and_data(0x3, 0x15, 0xc);
+
+		if (backlight_on != -1) {
+			set_backlight(backlight_on);
+		}
+		backlight_on = -1;
+		break;
+
+	case VESA_VSYNC_SUSPEND:
+	case VESA_HSYNC_SUSPEND:
+		/* printk(KERN_ERR "VESA_XSYNC_BLANKING\n"); */
+		if (backlight_on == -1) {
+			backlight_on = get_backlight();
+			set_backlight(0);
+		}
+
+		/* go to SLP = 1 */
+		/* 10101 00001100 */
+		lcd_cmd_and_data(0x3, 0x15, 0x0);
+		lcd_cmd_and_data(0x3, 0x15, 0x2);
+		break;
+
+	case VESA_POWERDOWN:
+		/* printk(KERN_ERR "VESA_POWERDOWN\n"); */
+		if (backlight_on == -1) {
+			backlight_on = get_backlight();
+			set_backlight(0);
+		}
+
+		/* got to standby */
+		lcd_cmd_and_data(0x3, 0x15, 0x1);
+		break;
+
+	default:
+		/* printk(KERN_ERR "unknown blank value %d\n", blank_mode); */
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void ipod_set_disp(const void *par, struct display *disp,
+			 struct fb_info_gen *info)
+{
+	/*
+	 *  Fill in a pointer with the virtual address of the mapped frame buffer.
+	 *  Fill in a pointer to appropriate low level text console operations (and
+	 *  optionally a pointer to help data) for the video mode `par' of your
+	 *  video hardware. These can be generic software routines, or hardware
+	 *  accelerated routines specifically tailored for your hardware.
+	 *  If you don't have any appropriate operations, you must fill in a
+	 *  pointer to dummy operations, and there will be no text output.
+	 */
+
+	disp->screen_base = ipod_scr;
+	disp->dispsw = &fbcon_ipod;
+}
+
+
+/* ------------ Interfaces to hardware functions ------------ */
+
+
+struct fbgen_hwswitch ipod_switch = {
+	detect:		ipod_detect,
+	encode_fix:	ipod_encode_fix,
+	decode_var:	ipod_decode_var,
+	encode_var:	ipod_encode_var,
+	get_par:	ipod_get_par,
+	set_par:	ipod_set_par,
+	getcolreg:	ipod_getcolreg,
+	setcolreg:	ipod_setcolreg,
+	pan_display:	ipod_pan_display,
+	blank:		ipod_blank,
+	set_disp:	ipod_set_disp,
+};
+
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ *  Frame buffer operations
+ */
+
+static int ipod_fp_open(const struct fb_info *info, int user)
+{
+	return 0;
+}
+
+#define FBIOGET_CONTRAST	_IOR('F', 0x22, int)
+#define FBIOPUT_CONTRAST	_IOW('F', 0x23, int)
+
+#define FBIOGET_BACKLIGHT	_IOR('F', 0x24, int)
+#define FBIOPUT_BACKLIGHT	_IOW('F', 0x25, int)
+
+#define IPOD_MIN_CONTRAST 0
+#define IPOD_MAX_CONTRAST 0x7f
+
+static int ipod_fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+	u_long arg, int con, struct fb_info *info)
+
+{
+	int val;
+
+	switch (cmd) {
+	case FBIOGET_CONTRAST:
+		val = get_contrast();
+		if (put_user(val, (int *)arg))
+			return -EFAULT;
+		break;
+
+	case FBIOPUT_CONTRAST:
+		val = (int)arg;
+		if (val < IPOD_MIN_CONTRAST || val > IPOD_MAX_CONTRAST)
+			return -EINVAL;
+		set_contrast(val);
+		break;
+
+	case FBIOGET_BACKLIGHT:
+		val = get_backlight();
+		if (put_user(val, (int *)arg))
+			return -EFAULT;
+		break;
+
+	case FBIOPUT_BACKLIGHT:
+		val = (int)arg;
+		set_backlight(val);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+/*
+ *  In most cases the `generic' routines (fbgen_*) should be satisfactory.
+ *  However, you're free to fill in your own replacements.
+ */
+
+static struct fb_ops ipodfb_ops = {
+	owner:		THIS_MODULE,
+	fb_open:	ipod_fp_open,
+	fb_get_fix:	fbgen_get_fix,
+	fb_get_var:	fbgen_get_var,
+	fb_set_var:	fbgen_set_var,
+	fb_get_cmap:	fbgen_get_cmap,
+	fb_set_cmap:	fbgen_set_cmap,
+	fb_pan_display:	fbgen_pan_display,
+	fb_ioctl:	ipod_fb_ioctl,
+};
+
+
+/* ------------ Hardware Independent Functions ------------ */
+
+
+/*
+ *  Initialization
+ */
+
+int __init ipodfb_init(void)
+{
+	fb_info.gen.fbhw = &ipod_switch;
+
+	fb_info.gen.fbhw->detect();
+
+	strcpy(fb_info.gen.info.modename, "iPod");
+
+	fb_info.gen.info.changevar = NULL;
+	fb_info.gen.info.node = -1;
+	fb_info.gen.info.fbops = &ipodfb_ops;
+	fb_info.gen.info.disp = &disp;
+	fb_info.gen.info.switch_con = &fbgen_switch;
+	fb_info.gen.info.updatevar = &fbgen_update_var;
+	fb_info.gen.info.blank = &fbgen_blank;
+	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
+
+	/* This should give a reasonable default video mode */
+	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
+	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
+	fbgen_set_disp(-1, &fb_info.gen);
+	fbgen_install_cmap(0, &fb_info.gen);
+
+	if ( register_framebuffer(&fb_info.gen.info) < 0 ) {
+		return -EINVAL;
+	}
+
+	init_lcd();
+
+	printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.gen.info.node), fb_info.gen.info.modename);
+
+	/* uncomment this if your driver cannot be unloaded */
+	/* MOD_INC_USE_COUNT; */
+	return 0;
+}
+
+
+/*
+ *  Cleanup
+ */
+
+void ipodfb_cleanup(struct fb_info *info)
+{
+	/*
+	 *  If your driver supports multiple boards, you should unregister and
+	 *  clean up all instances.
+	 */
+
+	unregister_framebuffer(info);
+	/* ... */
+}
+
+
+/*
+ *  Setup
+ */
+
+int __init ipodfb_setup(char *options)
+{
+	/* Parse user speficied options (`video=ipodfb:') */
+	return 0;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ *  Modularization
+ */
+
+#ifdef MODULE
+MODULE_LICENSE("GPL");
+int init_module(void)
+{
+	return ipodfb_init();
+}
+
+void cleanup_module(void)
+{
+	ipodfb_cleanup(void);
+}
+#endif /* MODULE */
+
diff -urN linux-2.4.29/arch/armnommu/mach-ipod/hardware.c linux-2.4.29-uc1/arch/armnommu/mach-ipod/hardware.c
--- linux-2.4.29/arch/armnommu/mach-ipod/hardware.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ipod/hardware.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,439 @@
+/*
+ * hardware.c - special hardware routines for iPod
+ *
+ * Copyright (c) 2003,2004 Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/system.h>
+
+#define SYSINFO_TAG     (unsigned char *)0x40017f18
+#define SYSINFO_PTR     (struct sysinfo_t **)0x40017f1c
+
+static struct sysinfo_t ipod_sys_info;
+static int ipod_sys_info_set;
+
+void ipod_set_sys_info(void);
+
+/*
+ * 3rd generation (docking) 0x30000, 0x30001
+ * 2nd generation (touch wheel) 0x20000, 0x20001
+ * 1st generation (scroll wheel) iPods 0x10000, 0x10001, 0x10002
+ * failed 0x0
+ */
+unsigned ipod_get_hw_version(void)
+{
+	if (!ipod_sys_info_set) {
+		ipod_set_sys_info();
+	}
+
+	if (ipod_sys_info_set > 0) {
+		return ipod_sys_info.boardHwSwInterfaceRev;
+	}
+
+	return 0x0;
+}
+
+struct sysinfo_t *ipod_get_sysinfo(void)
+{
+	if (!ipod_sys_info_set) {
+		ipod_set_sys_info();
+	}
+
+	if (ipod_sys_info_set > 0) {
+		return &ipod_sys_info;
+	}
+
+	return 0x0;
+}
+
+void ipod_set_sys_info(void)
+{
+	if (!ipod_sys_info_set) {
+		if ( *(unsigned *)SYSINFO_TAG == *(unsigned *)"IsyS" 
+				&& (*SYSINFO_PTR)->IsyS ==  *(unsigned *)"IsyS" ) {
+			memcpy(&ipod_sys_info, *SYSINFO_PTR, sizeof(struct sysinfo_t));
+			ipod_sys_info_set = 1;
+			system_rev = ipod_sys_info.boardHwSwInterfaceRev;
+		}
+		else {
+			ipod_sys_info_set = -1;
+		}
+	}
+}
+
+void ipod_hard_reset(void)
+{
+	outl(inl(0xcf005030) | 0x4, 0xcf005030);
+}
+
+/* make startup piezo noise */
+void ipod_startup_noise(void)
+{
+	int i1, i2;
+
+	outl(0x80, 0xc000604c);
+
+	/* set divisor low word */
+	outl(0xd, 0xc0006040);
+
+	outl(0x3, 0xc000604c);
+
+	outl(0x3, 0xc0006050);
+	outl(0x7, 0xc0006048);
+
+	for ( i1 = 0; i1 < 500; i1++ ) {
+		outl(0x0, 0xc0006040);
+
+		/* delay for a bit */
+		for ( i2 = 0; i2 < i1; i2++ ) {
+			/* empty */
+		}
+	}
+}
+
+/* wait for action button to be pressed and then released */
+void
+wait_for_action(void)
+{
+	/* wait for press */
+	do {
+		inl(0xcf000030);
+	} while ( (inl(0xcf000030) & 0x2) != 0 );
+
+	/* wait for release */
+	do {
+		inl(0xcf000030);
+	} while ( (inl(0xcf000030) & 0x2) == 0 );
+}
+
+void
+ipod_init_cache(void)
+{
+	unsigned i;
+
+	outl(inl(0xcf004050) & ~0x700, 0xcf004050);
+	outl(0x4000, 0xcf004020);
+
+	outl(0x2, 0xcf004024);
+
+	/* PP5002 has 8KB cache */
+	for (i = 0xf0004000; i < 0xf0006000; i += 16) {
+		outl(0x0, i);
+	}
+
+	outl(0x0, 0xf000f020);
+	outl(0x3fc0, 0xf000f024);
+
+	outl(0x3, 0xcf004024);
+}
+
+void
+ipod_set_cpu_speed(void)
+{
+	outl(0x02, 0xcf005008);
+
+	outl(0x55, 0xcf00500c);
+	outl(0x6000, 0xcf005010);
+
+#if 1
+	// 75  MHz (24/24 * 75) (default)
+	outl(24, 0xcf005018);
+	outl(75, 0xcf00501c);
+#endif
+
+#if 0
+	// 66 MHz (24/3 * 8)
+	outl(3, 0xcf005018);
+	outl(8, 0xcf00501c);
+#endif
+
+	outl(0xe000, 0xcf005010);
+
+	udelay(2000);
+
+	outl(0xa8, 0xcf00500c);
+}
+
+static void
+set_boot_variable(unsigned *dest, char *src, unsigned len)
+{
+	if ( !(((unsigned)dest | (unsigned)src) & 0x3 ) ) {
+
+		unsigned lr = 0x01010101;
+
+		unsigned ip;
+		unsigned t;
+
+		do {
+			if ( len < 4 ) break;
+
+			ip = *(unsigned *)src;
+			*dest = ip;
+
+			dest ++;
+			src += 4;
+			len -= 4;
+
+			/* this magic checks for embedded nulls */
+			t = ip - lr;
+			t = t & ~ip;
+		} while ( (t & (lr << 7)) == 0 );
+	}
+
+	if ( len == 0 ) return;
+
+	{
+		char ip;
+
+		do {
+			ip = *src++;
+			*((char *)dest)++ = ip;
+			if ( ip == 0 ) break;
+			len--;
+		} while ( len != 0 );
+
+		if ( len <= 1 ) return;
+	}
+
+	len --;
+
+	do {
+		*((unsigned char *)dest)++ = '\0';
+		len--;
+	} while ( len != 0 );
+}
+
+void
+ipod_reboot_to_diskmode(void)
+{
+	/* select new mode and icon to show during boot */
+	set_boot_variable((unsigned *)0x40017f00, "diskmode", 8);
+	set_boot_variable((unsigned *)0x40017f08, "hotstuff", 8);
+
+	/* do special startup? */
+	outl(0x1, 0x40017f10);
+
+	/* reset */
+	outl(inl(0xcf005030) | 0x4, 0xcf005030);
+}
+
+#define IPOD_I2C_CTRL	0xc0008000
+#define IPOD_I2C_ADDR	0xc0008004
+#define IPOD_I2C_DATA0	0xc000800c
+#define IPOD_I2C_DATA1	0xc0008010
+#define IPOD_I2C_DATA2	0xc0008014
+#define IPOD_I2C_DATA3	0xc0008018
+#define IPOD_I2C_STATUS	0xc000801c
+
+/* IPOD_I2C_CTRL bit definitions */
+#define IPOD_I2C_SEND	0x80
+
+/* IPOD_I2C_STATUS bit definitions */
+#define IPOD_I2C_BUSY	(1<<6)
+
+#define POLL_TIMEOUT (HZ)
+
+static int
+ipod_i2c_wait_not_busy(void)
+{
+	unsigned long timeout;
+
+	timeout = jiffies + POLL_TIMEOUT;
+	while (time_before(jiffies, timeout)) {
+		if (!(inb(IPOD_I2C_STATUS) & IPOD_I2C_BUSY)) {
+			return 0;
+		}
+		yield();
+	}
+
+	return -ETIMEDOUT;
+}
+
+int
+ipod_i2c_send_bytes(unsigned int addr, unsigned int len, unsigned char *data)
+{
+	int data_addr;
+	int i;
+
+	if (len < 1 || len > 4) {
+		return -EINVAL;
+	}
+
+	if (ipod_i2c_wait_not_busy() < 0) {
+		return -ETIMEDOUT;
+	}
+
+	// clear top 15 bits, left shift 1
+	outb((addr << 17) >> 16, IPOD_I2C_ADDR);
+
+	outb(inb(IPOD_I2C_CTRL) & ~0x20, IPOD_I2C_CTRL);
+
+	data_addr = IPOD_I2C_DATA0;
+	for ( i = 0; i < len; i++ ) {
+		outb(*data++, data_addr);
+
+		data_addr += 4;
+	}
+
+	outb((inb(IPOD_I2C_CTRL) & ~0x26) | ((len-1) << 1), IPOD_I2C_CTRL);
+
+	outb(inb(IPOD_I2C_CTRL) | IPOD_I2C_SEND, IPOD_I2C_CTRL);
+
+	return 0x0;
+}
+
+int
+ipod_i2c_send(unsigned int addr, int data0, int data1)
+{
+	unsigned char data[2];
+											
+	data[0] = data0;
+	data[1] = data1;
+
+	return ipod_i2c_send_bytes(addr, 2, data);
+}
+
+void
+ipod_serial_init(void)
+{
+	int hw_ver = ipod_get_hw_version() >> 16;
+
+	/* enable ttyS1 (piezo) */
+	outl(inl(0xcf004040) & ~0x1000, 0xcf004040);
+	if (hw_ver == 0x3) {
+		/* port c, bit 0 and 3 disabled */
+		outl(inl(0xcf00000c) & ~((1<<0)|(1<<3)), 0xcf00000c);
+	}
+
+	if (hw_ver == 0x3) {
+		/* 100100010001, 11,8,4,0 */
+		// outl(0x911, 0xcf004040);
+		/* 1000000000011100, 16,4,3,2 */
+		// outl(0x801c, 0xcf004048);
+
+		outl((inl(0xcf004040) & ~(1<<10)) | (1<<11) | (1<<8) | (1<<4), 0xcf004040);
+		outl(0x801c, 0xcf004048);
+	}
+	else {
+		/* 011110010001, 10,9,8,7,4,0 */
+		// outl(0x791, 0xcf004040);
+	}
+
+	/* enable ttyS0 (remote) */
+	if (hw_ver == 0x3) {
+#if 0
+		outl(inl(0xcf00000c) | 0x10, 0xcf00000c);
+		outl(inl(0xcf00001c) & ~0x10, 0xcf00001c);
+
+		// sub_0_28001CE4(0)
+		outl(inl(0xcf004048) & ~0x8, 0xcf004048);
+
+		// sub_0_28001C9C(0)
+		outl(inl(0xcf00000c) | 0x20, 0xcf00000c);
+		outl(inl(0xcf00001c) | 0x20, 0xcf00001c);
+		outl(inl(0xcf00002c) & ~0x20, 0xcf00001c);
+
+		// sub_0_28001C58(0)
+		outl(inl(0xcf004040) | 0x400, 0xcf004040);
+		outl(inl(0xcf004040) & ~0x800, 0xcf004040);
+		outl(inl(0xcf004048) & ~0x2, 0xcf004048);
+
+		// sub_0_28001C58(1)
+		outl(inl(0xcf004040) | 0x400, 0xcf004040);
+		outl(inl(0xcf004040) & ~0x800, 0xcf004040);
+		outl(inl(0xcf004048) | 0x2, 0xcf004048);
+
+		// sub_0_28001C10(0)
+		outl(inl(0xcf000008) | 0x40, 0xcf000008);
+		outl(inl(0xcf000018) | 0x40, 0xcf000018);
+		outl(inl(0xcf000028) & ~0x40, 0xcf000028);
+
+		udelay(1); /* Hold reset for at least 1000ns */
+
+		// sub_0_28001C10(1)
+		outl(inl(0xcf000008) | 0x40, 0xcf000008);
+		outl(inl(0xcf000018) | 0x40, 0xcf000018);
+		outl(inl(0xcf000028) | 0x40, 0xcf000028);
+
+		// sub_0_2800AB2C
+		outl(inl(0xcf005030) | 0x100, 0xcf005030);
+		outl(inl(0xcf005030) & ~0x100, 0xcf005030);
+
+		outl(0x1, 0xc0008020);
+		outl(0x0, 0xc0008030);
+		outl(0x51, 0xc000802c);
+		outl(0x0, 0xc000803c);
+
+		outl(inl(0xcf005000) | 0x2, 0xcf005000);
+
+		outl(inl(0xc000251c) | 0x10000, 0xc000251c);
+		outl(inl(0xc000251c) & ~0x10000, 0xc000251c);
+		outl(inl(0xc000251c) | 0x30000, 0xc000251c);
+		outl(0x15, 0xc0002500);
+
+		outl(inl(0xcf00000c) | 0x40, 0xcf00000c);
+		outl(inl(0xcf00001c) & ~0x40, 0xcf00000c);
+
+		outl(0x7, 0xc0008034);
+		outl(0x0, 0xc0008038);
+		// end sub_0_2800AB2C
+#endif
+	}
+	else {
+		outl(inl(0xcf00000c) & ~0x8, 0xcf00000c);
+	}
+
+	/* 3g ttyS0 init */
+	if (hw_ver == 0x3) {
+		ipod_i2c_send(0x8, 0x24, 0xf5);
+		ipod_i2c_send(0x8, 0x25, 0xf8);
+		ipod_i2c_send(0x8, 0x26, 0xf5);
+		ipod_i2c_send(0x8, 0x34, 0x02);
+		ipod_i2c_send(0x8, 0x1b, 0xf9);
+
+		// sub_0_2800147C(0)
+		outl(inl(0xcf004044) | (1<<4), 0xcf004044);
+		outl(inl(0xcf004048) & ~(1<<4), 0xcf004048);
+
+		/* port c bit 3 output 1 */
+		// sub_0_28001434(1)
+		outl(inl(0xcf000008) | (1<<3), 0xcf000008);
+		outl(inl(0xcf000018) | (1<<3), 0xcf000018);
+		outl(inl(0xcf000028) | (1<<3), 0xcf000028);
+
+		// rmt_uart_init
+		outl(inl(0xcf00000c) & ~0x1, 0xcf00000c);
+		outl(inl(0xcf00000c) & ~0x8, 0xcf00000c);
+	}
+}
+
+static ipod_dma_handler_t ipod_dma_handler;
+
+void ipod_set_process_dma(ipod_dma_handler_t new_handler)
+{
+	ipod_dma_handler = new_handler;
+}
+
+void ipod_handle_dma(void)
+{
+	if (ipod_dma_handler != 0) {
+		ipod_dma_handler();
+	}
+}
+
+EXPORT_SYMBOL(ipod_get_hw_version);
+EXPORT_SYMBOL(ipod_get_sysinfo);
+EXPORT_SYMBOL(ipod_i2c_send_bytes);
+EXPORT_SYMBOL(ipod_i2c_send);
+EXPORT_SYMBOL(ipod_serial_init);
+EXPORT_SYMBOL(ipod_set_process_dma);
+
diff -urN linux-2.4.29/arch/armnommu/mach-ipod/ipodremote.c linux-2.4.29-uc1/arch/armnommu/mach-ipod/ipodremote.c
--- linux-2.4.29/arch/armnommu/mach-ipod/ipodremote.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ipod/ipodremote.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,236 @@
+/*
+ * ipodremote.c - remote control line dicipline for iPod
+ *
+ * Copyright (c) 2003,2004 Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+#include <asm/hardware.h>
+
+/*
+ * This driver allows input from the remote control to be directed
+ * to the console as key input.
+ *
+ * Once this driver is loaded use the inputattach program to redirect
+ * the serial input to this driver.
+ *
+ * For the third generation iPods:
+ * 	inputattach -ipod3 /dev/ttyS0
+ * For original "scroll-wheel" or second generation "touch-wheel" iPods:
+ * 	inputattach -ipod /dev/ttyS0
+ */
+
+/*
+ * 1g and 2g iPod remotes communicate at 9600 Baud 8N1.  When a
+ * button is pressed on the remote the 4 bytes are generated:
+ *
+ * 0xff 0xfd n 0x00
+ *
+ * The n value varies depending on which button is pressed.  This sequence
+ * will continue until the button is released at which point a single
+ * sequence of:
+ *
+ * 0xff 0xfd 0xf0 0x00
+ *
+ * is sent.
+ *
+ * The possible n values are: 0xf1 -> play/pause, 0xf2 -> volume up,
+ * 0xf3 -> volume down, 0xf4 -> fast forward, 0xf5 -> rewind and
+ * 0xf0 -> no key down.
+ */
+
+/*
+ * 3g iPod remotes comminicate at 19,200 Baud 8N1.  When a button
+ * is pressed or released a stream of bytes is send.  Whilst the button
+ * is held down 7 bytes will be repeated sent in the form:
+ *
+ * 0xff 0x55 0x03 0x02 0x00 n 0xfa
+ *
+ * Where n is either 0x01, 0x02, 0x04, 0x08 or 0x10.  These represent
+ * play/pause, volume up, volume down, fast forward and rewind respectively.
+ *
+ * When the button is released the following bytes will be written one
+ * or more times.
+ *
+ * 0Xff 0X55 0x03 0x02 0x00 0x00 0xfb
+ */
+
+#define IPOD_REMOTE_12G_MAX_LEN	4
+#define IPOD_REMOTE_3G_MAX_LEN	7
+#define N_BUTTONS	5
+
+static int ipod_remote_buttons[] = {
+	KEY_1, KEY_2, KEY_3, KEY_4, KEY_5
+};
+
+struct ipod_remote {
+	struct input_dev dev;
+	struct serio *serio;
+
+	unsigned hw_ver;
+	int idx;
+	unsigned char data[IPOD_REMOTE_3G_MAX_LEN];
+};
+
+static void ipod_remote_process_input_12g(struct ipod_remote *ipod)
+{
+	static int last_button = 0;
+
+	if ( ipod->data[2] == 0xf0 ) {
+		input_report_key(&ipod->dev, last_button, 0);
+	}
+	else {
+		int pos = ipod->data[2] - 0xf1;
+		if ( pos >= 0  && pos < 5 ) {
+			last_button = ipod_remote_buttons[pos];
+			input_report_key(&ipod->dev, last_button, 1);
+		}
+	}
+}
+
+static void ipod_remote_process_input_3g(struct ipod_remote *ipod)
+{
+	static int last_button = -1;
+
+	if ( ipod->data[6] == 0xfb ) {
+		if (last_button >= 0) {
+			input_report_key(&ipod->dev, last_button, 0);
+			last_button = -1;
+		}
+	}
+	else {
+		int pos = -1;
+
+		switch (ipod->data[5]) {
+		case 0x1:
+			pos = 0;
+			break;
+		case 0x2:
+			pos = 1;
+			break;
+		case 0x4:
+			pos = 2;
+			break;
+		case 0x8:
+			pos = 3;
+			break;
+		case 0x10:
+			pos = 4;
+			break;
+		}
+
+		if ( pos >= 0  && pos < 5 ) {
+			last_button = ipod_remote_buttons[pos];
+			input_report_key(&ipod->dev, last_button, 1);
+		}
+	}
+}
+
+static void ipod_remote_connect(struct serio *serio, struct serio_dev *dev)
+{
+	struct ipod_remote *ipod;
+	int i;
+
+	if (serio->type != (SERIO_RS232 | SERIO_IPOD_REM)) {
+		printk(KERN_ERR "ipod_remote: invalid serio->type 0x%lx\n", serio->type);
+		return;
+	}
+                                                                                
+	ipod = kmalloc(sizeof(struct ipod_remote), GFP_KERNEL);
+	if ( !ipod ) {
+		printk(KERN_ERR "ipod_remote: out of memory\n");
+		return;
+	}
+	memset(ipod, 0x0, sizeof(struct ipod_remote));
+
+	ipod->serio = serio;
+	ipod->serio->private = ipod;
+	ipod->dev.private = ipod;
+
+	ipod->hw_ver = ipod_get_hw_version() >> 16;
+	ipod->dev.name = "ipod-remote";
+	ipod->dev.idbus = BUS_RS232;
+	ipod->dev.idvendor = SERIO_IPOD_REM;
+	ipod->dev.idproduct = 0x0001;
+	ipod->dev.idversion = 0x0001;
+
+	ipod->dev.evbit[0] = BIT(EV_KEY);
+	for (i = 0; i < N_BUTTONS; i++) {
+		set_bit(ipod_remote_buttons[i], &ipod->dev.keybit);
+	}
+
+	if ( serio_open(serio, dev) ) {
+		printk(KERN_ERR "ipod_remote: serio_open failed\n");
+		kfree(ipod);
+		return;
+	}
+
+	input_register_device(&ipod->dev);
+	printk("ipod_remote: input%d: registered\n", ipod->dev.number);
+}
+
+static void ipod_remote_disconnect(struct serio *serio)
+{
+	struct ipod_remote *ipod;
+
+	ipod = serio->private;
+
+	input_unregister_device(&ipod->dev);
+	serio_close(serio);
+	kfree(ipod);
+}
+
+static void ipod_remote_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+{
+	struct ipod_remote *ipod;
+
+	ipod = serio->private;
+
+	ipod->data[ipod->idx++] = data;
+	if (ipod->hw_ver == 0x1 || ipod->hw_ver == 0x2) {
+		if ( ipod->idx == IPOD_REMOTE_12G_MAX_LEN ) {
+			ipod->idx = 0;
+			ipod_remote_process_input_12g(ipod);
+		}
+	}
+	else {
+		if ( ipod->idx == IPOD_REMOTE_3G_MAX_LEN ) {
+			ipod->idx = 0;
+			ipod_remote_process_input_3g(ipod);
+		}
+	}
+}
+
+
+static struct serio_dev ipod_remote_dev = {
+	connect:	ipod_remote_connect,
+	disconnect:	ipod_remote_disconnect,
+	interrupt:	ipod_remote_interrupt,
+};
+
+static int __init ipod_remote_init(void)
+{
+	printk("ipod_remote: $Id: ipodremote.c,v 1.2 2004/03/02 22:41:44 leachbj Exp $\n");
+
+	serio_register_device(&ipod_remote_dev);
+
+	return 0;
+}
+
+static void __exit ipod_remote_exit(void)
+{
+	serio_unregister_device(&ipod_remote_dev);
+}
+
+module_init(ipod_remote_init);
+module_exit(ipod_remote_exit);
+
+MODULE_AUTHOR("Bernard Leach <leachbj@bouncycastle.org>");
+MODULE_DESCRIPTION("line driver for remote control for the iPod");
+MODULE_LICENSE("GPL");
+
diff -urN linux-2.4.29/arch/armnommu/mach-ipod/irq.c linux-2.4.29-uc1/arch/armnommu/mach-ipod/irq.c
--- linux-2.4.29/arch/armnommu/mach-ipod/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ipod/irq.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,75 @@
+/*
+ * irq.c - irq processing for iPod
+ *
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+
+static void ipod_unmask_irq(unsigned int irq)
+{
+	/* unmask the interrupt */
+	outl((1 << irq), 0xcf001024);
+	/* route it to IRQ not FIQ */
+	outl(inl(0xcf00102c) & ~(1 << irq), 0xcf00102c);
+}
+
+static void ipod_mask_irq(unsigned int irq)
+{
+	/* mask the interrupt */
+	outl((1 << irq), 0xcf001028);
+}
+
+static void ipod_mask_ack_irq(unsigned int irq)
+{
+
+	/* there is no general IRQ ack, we have to do it at the source */
+	switch (irq) {
+	case IDE_INT0_IRQ:
+		/* clear FIFO interrupt status */
+		outl(0xff, 0xc0003020);
+		outl(inl(0xc0003024) | (1<<4) | (1<<5), 0xc0003024);
+		break;
+
+	case TIMER1_IRQ:
+		inl(0xcf001104);
+		break;
+	}
+
+	ipod_mask_irq(irq);
+}
+
+int ipod_init_irq(void)
+{
+	unsigned int irq;
+
+	/* disable all interrupts */
+	outl(-1, 0xcf00101c);
+	outl(-1, 0xcf001028);
+	outl(-1, 0xcf001038);
+
+	/* clear all interrupts */
+	for ( irq = 0; irq < NR_IRQS; irq++ ) {
+
+		if (!VALID_IRQ(irq)) continue;
+
+		irq_desc[irq].valid     = 1;
+		irq_desc[irq].probe_ok  = 1;
+		irq_desc[irq].mask_ack  = ipod_mask_ack_irq;
+		irq_desc[irq].mask      = ipod_mask_irq;
+		irq_desc[irq].unmask    = ipod_unmask_irq;
+	}
+
+	/*
+	 * since the interrupt vectors at 0x0 are now installed
+	 * we can wake up the COP safely
+	 */
+	outl(0xce, 0xcf004058);
+
+        return 0;
+}
+
diff -urN linux-2.4.29/arch/armnommu/mach-ipod/keyboard.c linux-2.4.29-uc1/arch/armnommu/mach-ipod/keyboard.c
--- linux-2.4.29/arch/armnommu/mach-ipod/keyboard.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ipod/keyboard.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,244 @@
+/*
+ * keyboard.c - keyboard driver for iPod
+ *
+ * Copyright (c) 2003,2004 Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/kbd_ll.h>
+#include <linux/mm.h>
+#include <linux/kbd_kern.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/arch/irqs.h>
+#include <asm/keyboard.h>
+#include <asm/hardware.h>
+
+/* undefine these to produce keycodes from left/right/up/down */
+#undef DO_SCROLLBACK
+#undef DO_CONTRAST
+#undef USE_ARROW_KEYS
+
+/* we use the keycodes and translation is 1 to 1 */
+#define R_SC		19	/* 'r' */
+#define L_SC		38	/* 'l' */
+
+#if defined(USE_ARROW_KEYS)
+#define UP_SC		103
+#define LEFT_SC		105
+#define RIGHT_SC	106
+#define DOWN_SC		108
+#else
+#define UP_SC		50	/* 'm' */
+#define LEFT_SC		17	/* 'w' */
+#define RIGHT_SC	33	/* 'f' */
+#define DOWN_SC		32	/* 'd' */
+#endif
+
+#define ACTION_SC	28	/* '\n' */
+
+/* send ^S and ^Q for the hold switch */
+#define LEFT_CTRL_SC	29
+#define Q_SC		16
+#define S_SC		31
+
+/* need to pass something becuase we use a shared irq */
+#define KEYBOARD_DEV_ID	0x4b455942
+
+static unsigned ipod_hw_ver;
+
+static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	static int prev_scroll = -1;
+	unsigned char source, state;
+	static int was_hold = 0;
+
+	/* we need some delay for g3, cause hold generates several interrupts,
+	 * some of them delayed
+	 */
+	if (ipod_hw_ver == 0x3) {
+		udelay(250);
+	}
+
+	/* get source of interupts */
+	source = inb(0xcf000040);
+	if ( source == 0 ) {
+		return; 	/* not for us */
+	}
+
+	/* get current keypad status */
+	state = inb(0xcf000030);
+	outb(~state, 0xcf000060);
+
+	if (ipod_hw_ver == 0x3) {
+		if (was_hold && source == 0x40 && state == 0xbf) {
+			/* ack any active interrupts */
+			outb(source, 0xcf000070);
+			return;
+		}
+		was_hold = 0;
+	}
+
+#ifdef CONFIG_VT
+	kbd_pt_regs = regs;
+
+	if ( source & 0x20 ) {
+		if ((ipod_hw_ver == 0x3 && (state & 0x20) == 0 ) || 
+				(state & 0x20)) {
+			/* CTRL-S down */
+			handle_scancode(LEFT_CTRL_SC, 1);
+			handle_scancode(S_SC, 1);
+
+			/* CTRL-S up */
+			handle_scancode(S_SC, 0);
+			handle_scancode(LEFT_CTRL_SC, 0);
+		}
+		else {
+			/* CTRL-Q down */
+			handle_scancode(LEFT_CTRL_SC, 1);
+			handle_scancode(Q_SC, 1);
+
+			/* CTRL-Q up */
+			handle_scancode(Q_SC, 0);
+			handle_scancode(LEFT_CTRL_SC, 0);
+			if (ipod_hw_ver == 0x3) {
+				was_hold = 1;
+			}
+		}
+		/* hold switch on 3g causes all outputs to go low */
+		/* we shouldn't interpret these as key presses */
+		if (ipod_hw_ver == 0x3) {
+			goto done;
+		}
+	}
+
+	if ( source & 0x1 ) {
+		if ( state & 0x1 ) {
+#if defined(DO_SCROLLBACK)
+			scrollfront(0);
+#else
+			handle_scancode(RIGHT_SC, 0);
+#endif
+		}
+#if !defined(DO_SCROLLBACK)
+		else {
+			handle_scancode(RIGHT_SC, 1);
+		}
+#endif
+	}
+	if ( source & 0x2 ) {
+		if ( state & 0x2 ) {
+			handle_scancode(ACTION_SC, 0);
+		}
+		else {
+			handle_scancode(ACTION_SC, 1);
+		}
+	}
+
+	if ( source & 0x4 ) {
+		if ( state & 0x4 ) {
+#if defined(DO_CONTRAST)
+			contrast_down();
+#else
+			handle_scancode(DOWN_SC, 0);
+#endif
+		}
+#if !defined(DO_CONTRAST)
+		else {
+			handle_scancode(DOWN_SC, 1);
+		}
+#endif
+	}
+	if ( source & 0x8 ) {
+		if ( state & 0x8 ) {
+#if defined(DO_SCROLLBACK)
+			scrollback(0);
+#else
+			handle_scancode(LEFT_SC, 0);
+#endif
+		}
+#if !defined(DO_SCROLLBACK)
+		else {
+			handle_scancode(LEFT_SC, 1);
+		}
+#endif
+	}
+	if ( source & 0x10 ) {
+		if ( state & 0x10 ) {
+#if defined(DO_CONTRAST)
+			contrast_up();
+#else
+			handle_scancode(UP_SC, 0);
+#endif
+		}
+#if !defined(DO_CONTRAST)
+		else {
+			handle_scancode(UP_SC, 1);
+		}
+#endif
+	}
+
+	if ( source & 0xc0 ) {
+		static int scroll_state[4][4] = {
+			{0, 1, -1, 0},
+			{-1, 0, 0, 1},
+			{1, 0, 0, -1},
+			{0, -1, 1, 0}
+		};
+		unsigned now_scroll = (state & 0xc0) >> 6;
+						
+		if ( prev_scroll == -1 ) {
+			prev_scroll = now_scroll;
+		}
+		else {
+			switch (scroll_state[prev_scroll][now_scroll]) {
+			case 1:
+				/* 'l' keypress */
+				handle_scancode(L_SC, 1);
+				handle_scancode(L_SC, 0);
+				break;
+			case -1:
+				/* 'r' keypress */
+				handle_scancode(R_SC, 1);
+				handle_scancode(R_SC, 0);
+				break;
+			default:
+				/* only happens if we get out of sync */
+			}
+		}
+
+		prev_scroll = now_scroll;
+	}
+done:
+
+	tasklet_schedule(&keyboard_tasklet);
+#endif /* CONFIG_VT */
+
+	/* ack any active interrupts */
+	outb(source, 0xcf000070);
+}
+
+void __init ipodkb_init_hw(void)
+{
+	outb(~inb(0xcf000030), 0xcf000060);
+	outb(inb(0xcf000040), 0xcf000070);
+
+	outb(inb(0xcf000004) | 0x1, 0xcf000004);
+	outb(inb(0xcf000014) | 0x1, 0xcf000014);
+	outb(inb(0xcf000024) | 0x1, 0xcf000024);
+
+	if ( request_irq(GPIO_IRQ, keyboard_interrupt, SA_SHIRQ, "keyboard", KEYBOARD_DEV_ID) ) {
+		printk("ipodkb: IRQ %d failed\n", GPIO_IRQ);
+	}
+
+	outb(0xff, 0xcf000050);
+
+	/* get our hardware type */
+	ipod_hw_ver = ipod_get_hw_version() >> 16;
+}
+
diff -urN linux-2.4.29/arch/armnommu/mach-ipod/Makefile linux-2.4.29-uc1/arch/armnommu/mach-ipod/Makefile
--- linux-2.4.29/arch/armnommu/mach-ipod/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ipod/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,24 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= ipod.o
+
+# Object file lists.
+
+obj-y += arch.o cop.o dma.o hardware.o irq.o time.o
+
+obj-$(CONFIG_AUDIO_IPOD)	+= audio.o
+obj-$(CONFIG_FB_IPOD)		+= fb.o
+obj-$(CONFIG_IEEE1394_IPOD)	+= tsb43aa82.o
+obj-$(CONFIG_KB_IPOD)		+= keyboard.o
+obj-$(CONFIG_REMOTE_IPOD)	+= ipodremote.o
+
+export-objs		:= audio.o fb.o tsb43aa82.o keyboard.o ipodremote.o hardware.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-ipod/pad.S linux-2.4.29-uc1/arch/armnommu/mach-ipod/pad.S
--- linux-2.4.29/arch/armnommu/mach-ipod/pad.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ipod/pad.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,21 @@
+/*
+ * This file is needed to pad out the start of the kernel to
+ * leave room for the IRQ stubs.
+ */
+
+	b	stext
+	b	unexpected
+	b	unexpected
+	b	unexpected
+	b	unexpected
+	b	unexpected
+	b	unexpected
+	b	unexpected
+
+unexpected:
+	b	unexpected
+
+	/* Leave room for the IRQ stubs to get copied to */
+	.space 32768-(9*4)
+
+stext:
diff -urN linux-2.4.29/arch/armnommu/mach-ipod/time.c linux-2.4.29-uc1/arch/armnommu/mach-ipod/time.c
--- linux-2.4.29/arch/armnommu/mach-ipod/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ipod/time.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ * time.c - timer support for iPod
+ *
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <asm/io.h>
+
+
+#define IPOD_TIMER_STATUS 0xcf001110
+
+/*
+ * Set the RTC
+ */
+extern int ipod_set_rtc(void)
+{
+	return (0);
+}
+
+
+extern unsigned long ipod_gettimeoffset(void)
+{
+	return inl(IPOD_TIMER_STATUS);
+}
+
+extern void ipod_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+        do_timer(regs);
+}
+
diff -urN linux-2.4.29/arch/armnommu/mach-ipod/tsb43aa82.c linux-2.4.29-uc1/arch/armnommu/mach-ipod/tsb43aa82.c
--- linux-2.4.29/arch/armnommu/mach-ipod/tsb43aa82.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ipod/tsb43aa82.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,1202 @@
+/*
+ * tsb43aa82.c - ieee1394 driver for iPod
+ *
+ * Copyright (c) 2003,2004 Bernard Leach (leachbj@bouncycastle.org)
+ *
+ * IEEE1394 controller is the TSB43AA82 (iSphyx II) from Texas Instruments.
+ *
+ * Derived from ohci1394.c the driver for OHCI 1394 boards
+ * Copyright (C)1999,2000 Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>
+ *                        Gord Peters <GordPeters@smarttech.com>
+ *              2001      Ben Collins <bcollins@debian.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+
+#include "../../../drivers/ieee1394/ieee1394.h"
+#include "../../../drivers/ieee1394/ieee1394_types.h"
+#include "../../../drivers/ieee1394/hosts.h"
+#include "../../../drivers/ieee1394/ieee1394_core.h"
+
+#include "tsb43aa82.h"
+
+/***************************************************************
+ * FIFO size definition
+ * Async Command FIFOs = 378 quads - MTQ(3) - MRF(15) = 360 quads
+ * ATF+ARF+CTQ+CRF <= 360 quads
+ ***************************************************************/
+#if 0
+#define COMMAND_TX_QUE_SIZE   16
+#define COMMAND_RX_FIFO_SIZE  64
+#define ASYNC_TX_FIFO_SIZE    80
+#endif
+#define COMMAND_TX_QUE_SIZE   0
+#define COMMAND_RX_FIFO_SIZE  0
+#define ASYNC_TX_FIFO_SIZE    180
+#define ASYNC_RX_FIFO_SIZE    (360 - COMMAND_TX_QUE_SIZE - \
+                              COMMAND_RX_FIFO_SIZE - ASYNC_TX_FIFO_SIZE)
+/* DxF Size Register 0x98 */
+/* DTF+DRF <= (1182 quads / 4) units (ie 295) */
+#define DMA_DXF_TOTAL_QUADS   (1180ul / 4) /*In units of 4 quads */
+#define DMA_DXF_MAX_SIZE      (1052ul / 4)
+#define DMA_DXF_MIN_SIZE      (DMA_DXF_TOTAL_QUADS - DMA_DXF_MAX_SIZE)
+#define DMA_READ_FIFO_SIZE    (DMA_DXF_TOTAL_QUADS / 2)
+#define DMA_WRITE_FIFO_SIZE   (DMA_DXF_TOTAL_QUADS - DMA_READ_FIFO_SIZE)
+
+#define DXF_PG_ENTRY   4      /* # of Page Table Elements to retrieve */
+
+static struct hpsb_host *ipod_host;
+
+struct ti_ipod {
+	/* buffer for csr config rom */
+	quadlet_t *csr_config_rom_cpu;
+	dma_addr_t csr_config_rom_bus;
+	int csr_config_rom_length;
+
+	/* protect access to the PHY register */
+	spinlock_t phy_reg_lock;
+
+	struct tasklet_struct tx_tasklet;
+
+	struct list_head tx_list;
+	spinlock_t tx_list_lock;
+
+	spinlock_t tx_lock;
+#define TX_READY	0
+#define TX_BUSY		1
+#define TX_END		2
+	int tx_state;
+#define RX_READY	0
+#define RX_BUSY		1
+	int rx_state;
+
+	struct hpsb_packet *packet;
+
+	/* IEEE-1394 part follows */
+	struct hpsb_host *host;
+};
+
+static u16 ohci_crc16(u32 *ptr, int length)
+{
+	int shift;
+	u32 crc, sum, data;
+
+	crc = 0;
+	for (; length > 0; length--) {
+		data = be32_to_cpu(*ptr++);
+		for (shift = 28; shift >= 0; shift -= 4) {
+			sum = ((crc >> 12) ^ (data >> shift)) & 0x000f;
+			crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ sum;
+		}
+		crc &= 0xffff;
+	}
+	return crc;
+}
+
+/* Config ROM macro implementation influenced by NetBSD OHCI driver */
+/* taken from the OHCI driver */
+
+struct config_rom_unit {
+	u32 *start;
+	u32 *refer;
+	int length;
+	int refunit;
+};
+
+struct config_rom_ptr {
+	u32 *data;
+	int unitnum;
+	struct config_rom_unit unitdir[10];
+};
+
+#define cf_put_1quad(cr, q) (((cr)->data++)[0] = cpu_to_be32(q))
+
+#define cf_put_4bytes(cr, b1, b2, b3, b4) \
+	(((cr)->data++)[0] = cpu_to_be32(((b1) << 24) | ((b2) << 16) | ((b3) << 8) | (b4)))
+
+#define cf_put_keyval(cr, key, val) (((cr)->data++)[0] = cpu_to_be32(((key) << 24) | (val)))
+
+static inline void cf_put_str(struct config_rom_ptr *cr, const char *str)
+{
+	int t;
+	char fourb[4];
+
+	while (str[0]) {
+		memset(fourb, 0, 4);
+		for (t = 0; t < 4 && str[t]; t++) {
+			fourb[t] = str[t];
+		}
+		cf_put_4bytes(cr, fourb[0], fourb[1], fourb[2], fourb[3]);
+		str += strlen(str) < 4 ? strlen(str) : 4;
+	}
+	return;
+}
+
+static inline void cf_put_crc16(struct config_rom_ptr *cr, int unit)
+{
+	*cr->unitdir[unit].start =
+		cpu_to_be32((cr->unitdir[unit].length << 16) |
+			    ohci_crc16(cr->unitdir[unit].start + 1,
+				       cr->unitdir[unit].length));
+}
+
+static inline void cf_unit_begin(struct config_rom_ptr *cr, int unit)
+{
+	if (cr->unitdir[unit].refer != NULL) {
+		*cr->unitdir[unit].refer |=
+			cpu_to_be32(cr->data - cr->unitdir[unit].refer);
+		cf_put_crc16(cr, cr->unitdir[unit].refunit);
+	}
+	cr->unitnum = unit;
+	cr->unitdir[unit].start = cr->data++;
+}
+
+static inline void cf_put_refer(struct config_rom_ptr *cr, char key, int unit)
+{
+	cr->unitdir[unit].refer = cr->data;
+	cr->unitdir[unit].refunit = cr->unitnum;
+	(cr->data++)[0] = cpu_to_be32(key << 24);
+}
+
+static inline void cf_unit_end(struct config_rom_ptr *cr)
+{
+	cr->unitdir[cr->unitnum].length = cr->data -
+		(cr->unitdir[cr->unitnum].start + 1);
+	cf_put_crc16(cr, cr->unitnum);
+}
+
+/* End of NetBSD derived code.  */
+
+/* read 32 bit value from firewire chip */
+static unsigned fw_reg_read(int addr)
+{
+	/* read from little endian controller */
+	return (inw(0x30000000 + (addr * 2) + 0) & 0xff)
+		| ((inw(0x30000000 + (addr * 2) + 2) & 0xff) << 8)
+		| ((inw(0x30000000 + (addr * 2) + 4) & 0xff) << 16)
+		| ((inw(0x30000000 + (addr * 2) + 6) & 0xff) << 24);
+}
+
+/* write 32 bit value to firewire chip */
+static void fw_reg_write(int addr, unsigned val)
+{
+	/* write to little endian controller */
+	outw(val, 0x30000000 + (addr * 2) + 0);
+	outw(val >> 8, 0x30000000 + (addr * 2) + 2);
+	outw(val >> 16, 0x30000000 + (addr * 2) + 4);
+	outw(val >> 24, 0x30000000 + (addr * 2) + 6);
+}
+
+#define IPOD_LOOP_COUNT	100	/* Number of loops for reg read waits */
+
+static u8 get_phy_reg(struct ti_ipod *ipod, u8 addr)
+{
+	int i;
+	unsigned long flags;
+	quadlet_t r;
+
+	spin_lock_irqsave(&ipod->phy_reg_lock, flags);
+
+	fw_reg_write(LYNX_PHYACCESS, addr << 24 | 0x80000000);
+
+	for (i = 0; i < IPOD_LOOP_COUNT; i++) {
+		if ( !(fw_reg_read(LYNX_PHYACCESS) & 0x80000000) )
+			break;
+
+		mdelay(1);
+	}
+
+	r = fw_reg_read(LYNX_PHYACCESS);
+
+	if ( i == IPOD_LOOP_COUNT ) {
+		printk(KERN_ERR "Get PHY Reg timeout [0x%08x]\n", r);
+	}
+
+	spin_unlock_irqrestore(&ipod->phy_reg_lock, flags);
+
+	return r & 0xff;
+}
+
+static void set_phy_reg(struct ti_ipod *ipod, u8 addr, u8 data)
+{
+	int i;
+	unsigned long flags;
+	u32 r = 0;
+
+	spin_lock_irqsave(&ipod->phy_reg_lock, flags);
+
+	fw_reg_write(LYNX_PHYACCESS, (addr << 24) | (data << 16) | 0x40000000);
+
+	for (i = 0; i < IPOD_LOOP_COUNT; i++) {
+		r = fw_reg_read(LYNX_PHYACCESS);
+		if (!(r & 0x40000000))
+			break;
+
+		mdelay(1);
+	}
+
+	if (i == IPOD_LOOP_COUNT) {
+		printk(KERN_ERR "Set PHY Reg timeout [0x%08x]\n", r);
+	}
+
+	spin_unlock_irqrestore(&ipod->phy_reg_lock, flags);
+
+	return;
+}
+
+static void set_phy_reg_mask(struct ti_ipod *ipod, u8 addr, u8 data)
+{
+	u8 old;
+
+	old = get_phy_reg(ipod, addr);
+	old |= data;
+	set_phy_reg(ipod, addr, old);
+
+	return;
+}
+
+/* this is the maximum length */
+#define CONFIG_ROM_LEN	1024
+
+static void init_config_rom(struct ti_ipod *ipod)
+{
+	struct config_rom_ptr cr;
+	int i;
+
+	memset(&cr, 0, sizeof(cr));
+	memset(ipod->csr_config_rom_cpu, 0, sizeof (ipod->csr_config_rom_cpu));
+
+	cr.data = ipod->csr_config_rom_cpu;
+
+	/* Bus info block */
+	cf_unit_begin(&cr, 0);
+	cf_put_1quad(&cr, 0x31333934);	/* Bus ID == "1394" */
+	cf_put_1quad(&cr, 0x40ff6002);	/* Bus options (based iPod f/w) */
+					/* 6 -> 2^7 == max_rec */
+	cf_put_1quad(&cr, 0x00000000);	/* vendor id, chip id high */
+	cf_put_1quad(&cr, 0x024f3638);	/* chip id low */
+	cf_unit_end(&cr);
+
+	/* IEEE P1212 suggests the initial ROM header CRC should only
+	 * cover the header itself (and not the entire ROM). Since we do
+	 * this, then we can make our bus_info_len the same as the CRC
+	 * length.  */
+	ipod->csr_config_rom_cpu[0] |= cpu_to_be32(
+		(be32_to_cpu(ipod->csr_config_rom_cpu[0]) & 0x00ff0000) << 8);
+
+	/* Root directory */
+	cf_unit_begin(&cr, 1);
+	/* Vendor ID */
+	cf_put_keyval(&cr, 0x03, 0x0);		/* Vendor ID == 0x0 */
+	cf_put_refer(&cr, 0x81, 2);		/* Textual description unit */
+	cf_put_keyval(&cr, 0x0c, 0x0083c0);	/* Node capabilities */
+	/* NOTE: Add other unit referers here, and append at bottom */
+	cf_unit_end(&cr);
+
+	/* Textual description - "Linux iPod-1394" */
+	cf_unit_begin(&cr, 2);
+	cf_put_keyval(&cr, 0, 0);
+	cf_put_1quad(&cr, 0);
+	cf_put_str(&cr, "Linux iPod-1394");
+	cf_unit_end(&cr);
+
+	ipod->csr_config_rom_length = cr.data - ipod->csr_config_rom_cpu;
+
+	/*
+         * set AR_CSR_Size and CSR_Size (multiplies by 4 to get bytes)
+	 */
+	fw_reg_write(LYNX_CFR_CTRL, ipod->csr_config_rom_length << 18 | ipod->csr_config_rom_length << 2);
+
+	/*
+	 * Setup write to CSR
+	 */
+	fw_reg_write(LYNX_LOG_ROM_CTRL, LYNX_ROM_CTRL_XLOG|LYNX_ROM_CTRL_ROM_ADDR);
+
+	for (i = 0; i < ipod->csr_config_rom_length; i++) {
+		/* log data register, write the ROM data */
+		fw_reg_write(LYNX_LOG_ROM_DATA, be32_to_cpu(ipod->csr_config_rom_cpu[i]));
+	}
+
+	/* Set XLOG & ROMvalid to Valid Config-ROM data */
+	fw_reg_write(LYNX_LOG_ROM_CTRL, (fw_reg_read(LYNX_LOG_ROM_CTRL) & 0xFFFF7FFF)|LYNX_ROM_CTRL_VALID);
+}
+
+/* This function must store a pointer to the configuration ROM into the
+ * location referenced to by pointer and return the size of the ROM. It
+ * may not fail.  If any allocation is required, it must be done
+ * earlier.
+ */
+static size_t ipod_1394_get_rom(struct hpsb_host *host, quadlet_t **ptr)
+{
+	struct ti_ipod *ipod = host->hostdata;
+
+	*ptr = ipod->csr_config_rom_cpu;
+
+	return ipod->csr_config_rom_length * 4;
+}
+
+static int tx_packet(struct ti_ipod *ipod, struct hpsb_packet *packet)
+{
+	/* write to ATF (& hold timer) */
+	/* TODO: this doesnt seem to set the hold tr 0x4 like it should? */
+	fw_reg_write(LYNX_TXTIMER_CTRL, 0x20);
+
+	if (packet->tcode == TCODE_WRITEQ || packet->tcode == TCODE_READQ_RESPONSE) {
+		cpu_to_be32s(&packet->header[3]);
+	}
+
+	fw_reg_write(LYNX_WRITE_FIRST, (packet->speed_code << 16) | (packet->header[0] & 0xffff));
+	fw_reg_write(LYNX_WRITE_CONTINUE, (packet->header[0] & 0xffff0000) | (packet->header[1] & 0xffff));
+
+	if (packet->data_size) {
+		size_t data_len;
+		quadlet_t *q;
+
+		fw_reg_write(LYNX_WRITE_CONTINUE, packet->header[2]);
+		if (packet->header_size == 16) {
+			fw_reg_write(LYNX_WRITE_CONTINUE, packet->header[3]);
+		}
+
+		data_len = packet->data_size / 4;
+		q = packet->data;
+		while (data_len-- > 1) {
+			fw_reg_write(LYNX_WRITE_CONTINUE, cpu_to_be32(*q));
+			q++;
+		}
+		fw_reg_write(LYNX_WRITE_UPDATE, cpu_to_be32(*q));
+	}
+	else {
+		if (packet->header_size == 12) {
+			fw_reg_write(LYNX_WRITE_UPDATE, packet->header[2]);
+		}
+		else {
+			fw_reg_write(LYNX_WRITE_CONTINUE, packet->header[2]);
+			fw_reg_write(LYNX_WRITE_UPDATE, packet->header[3]);
+		}
+	}
+
+	/* write to ATF & release timer */
+	/* TODO: is this not required? */
+	/* fw_reg_write(LYNX_TXTIMER_CTRL,  (fw_reg_read(LYNX_TXTIMER_CTRL) & ~0xff) | 0x26); */
+
+	return 1;
+}
+
+static int tx_raw_packet(struct ti_ipod *ipod, struct hpsb_packet *packet)
+{
+	/* write to ATF (& hold timer) */
+	/* TODO: this doesnt seem to set the hold tr 0x4 like it should? */
+	fw_reg_write(LYNX_TXTIMER_CTRL, 0x20);
+
+	/* bits 24,25,26 are always 1 in both quads */
+	fw_reg_write(LYNX_WRITE_FIRST, packet->header[0] | 0x00e0);
+	fw_reg_write(LYNX_WRITE_UPDATE, packet->header[1] | 0x00e0);
+
+	/* write to ATF & release timer */
+	/* TODO: is this not required? */
+	/* fw_reg_write(LYNX_TXTIMER_CTRL,  (fw_reg_read(LYNX_TXTIMER_CTRL) & ~0xff) | 0x26); */
+
+	return 1;
+}
+
+static int rx_packet(struct ti_ipod *ipod)
+{
+	quadlet_t data = 0;
+	static quadlet_t pkt[1024];
+	unsigned status;
+	int packet_acked;
+	int tcode;
+	int i;
+
+	status = fw_reg_read(LYNX_ARF_STATUS);
+	if ((status & LYNX_XXFSTAT_EMPTY) == LYNX_XXFSTAT_EMPTY) {
+		printk(KERN_ERR "rx_packet ARF Empty\n");
+		return 0;
+	}
+
+	/* ensure at the beginning of a packet */
+	while ((status & LYNX_XRFSTAT_PKT_CD) != LYNX_XRFSTAT_PKT_CD) {
+		data = fw_reg_read(LYNX_ARF_DATA);
+		status = fw_reg_read(LYNX_ARF_STATUS);
+
+		if ((status & LYNX_XXFSTAT_EMPTY) == LYNX_XXFSTAT_EMPTY) {
+			printk(KERN_ERR "rx_packet cant find pkt start\n");
+			return 0;
+		}
+	}
+
+	/* ensure next quad is not bogus */
+	while ((status & LYNX_XRFSTAT_PKT_CD) == LYNX_XRFSTAT_PKT_CD) {
+		data = fw_reg_read(LYNX_ARF_DATA);
+		status = fw_reg_read(LYNX_ARF_STATUS);
+
+		if ((status & LYNX_XXFSTAT_EMPTY) == LYNX_XXFSTAT_EMPTY) {
+			printk(KERN_ERR "rx_packet skipped crap\n");
+			return 0;
+		}
+	}
+
+	packet_acked = ((data & 0x0f) == ACK_COMPLETE) ? 1 : 0;
+
+	for (i = 0; i < 3; i++) {
+		pkt[i] = fw_reg_read(LYNX_ARF_DATA);
+	}
+
+	tcode = (pkt[0] >> 4) & 0xf;
+	if (tcode == TCODE_WRITEQ || tcode == TCODE_READQ_RESPONSE) {
+		pkt[3] = cpu_to_be32(fw_reg_read(LYNX_ARF_DATA));
+		hpsb_packet_received(ipod->host, pkt, 16, packet_acked);
+	}
+	else if (tcode == TCODE_READB) {
+		pkt[3] = fw_reg_read(LYNX_ARF_DATA);
+		hpsb_packet_received(ipod->host, pkt, 16, packet_acked);
+	}
+	else if (tcode == TCODE_READQ || tcode == TCODE_WRITE_RESPONSE) {
+		hpsb_packet_received(ipod->host, pkt, 12, packet_acked);
+	}
+	else if (tcode == TCODE_WRITEB || tcode == TCODE_READB_RESPONSE)
+	{
+		int block_len;
+
+		pkt[3] = fw_reg_read(LYNX_ARF_DATA);
+		block_len = pkt[3] >> 16;
+
+		for (i = 0; i < (block_len + 3) / 4; i++) {
+			if (fw_reg_read(LYNX_ARF_STATUS) & LYNX_XXFSTAT_EMPTY) {
+				printk(KERN_ERR "ARF empty\n");
+				return 0;
+			}
+			pkt[4+i] = cpu_to_be32(fw_reg_read(LYNX_ARF_DATA));
+		}
+
+		hpsb_packet_received(ipod->host, pkt, 16 + block_len, packet_acked);
+	}
+	else {
+		printk(KERN_ERR "Unknown tcode 0x%x\n", tcode);
+	}
+
+	status = fw_reg_read(LYNX_ARF_STATUS);
+	return (status & LYNX_XXFSTAT_EMPTY) != LYNX_XXFSTAT_EMPTY;
+}
+
+static void tx_packet_end(struct ti_ipod *ipod)
+{
+	unsigned ack;
+
+	ack = (fw_reg_read(LYNX_ACK) & 0xf0) >> 4;
+
+	if (fw_reg_read(LYNX_TXTIMER_CTRL) & LYNX_TXTIMER_ATERR) {
+		printk(KERN_ERR "LYNX_TXTIMER_ATERR\n");
+		hpsb_packet_sent(ipod->host, ipod->packet, ACKX_SEND_ERROR);
+
+		return;
+	}
+
+	/* broadcast messages don't get a response */
+	if ((ipod->packet->node_id & NODE_MASK) == NODE_MASK) {
+		if (ack != ACK_COMPLETE) {
+			/* TODO: check this */
+			printk(KERN_ERR "broadcast without ACK_COMPLETE\n");
+		}
+		hpsb_packet_sent(ipod->host, ipod->packet, ACK_COMPLETE);
+
+		return;
+	}
+
+	/* mark the message as sent */
+	hpsb_packet_sent(ipod->host, ipod->packet, ack);
+
+	/* are we expecting a reponse and is it there? */
+	if (ipod->packet->expect_response && ack == ACK_PENDING) {
+		/* read response packet */
+		rx_packet(ipod);
+	}
+}
+
+static void tx_tasklet(unsigned long data)
+{
+	struct ti_ipod *ipod = (struct ti_ipod *)data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ipod->tx_lock, flags);
+
+	if (ipod->tx_state == TX_END) {
+		ipod->tx_state = TX_READY;
+		tasklet_schedule(&ipod->tx_tasklet);
+
+		tx_packet_end(ipod);
+	}
+
+	if (ipod->rx_state == RX_BUSY) {
+		ipod->rx_state = RX_READY;
+
+		while (rx_packet(ipod)) ;
+	}
+
+	if (ipod->tx_state == TX_READY) {
+		struct hpsb_packet *packet = 0;
+
+		spin_lock(&ipod->tx_list_lock);
+		if (!list_empty(&ipod->tx_list)) {
+			packet = driver_packet(ipod->tx_list.next);
+			list_del(&packet->driver_list);
+		}
+		spin_unlock(&ipod->tx_list_lock);
+
+		if (packet) {
+			ipod->packet = packet;
+			ipod->tx_state = TX_BUSY;
+
+			if (packet->type == hpsb_async) {
+				tx_packet(ipod, packet);
+			}
+			else if (packet->type == hpsb_raw) {
+				tx_raw_packet(ipod, packet);
+			}
+		}
+	}
+
+	spin_unlock_irqrestore(&ipod->tx_lock, flags);
+}
+
+/* This function shall implement packet transmission based on
+ * packet->type.  It shall CRC both parts of the packet (unless
+ * packet->type == raw) and do byte-swapping as necessary or instruct
+ * the hardware to do so.  It can return immediately after the packet
+ * was queued for sending.  After sending, hpsb_sent_packet() has to be
+ * called.  Return 0 for failure.
+ * NOTE: The function must be callable in interrupt context.
+ */
+static int ipod_1394_transmit_packet(struct hpsb_host *host, struct hpsb_packet *packet)
+{
+	struct ti_ipod *ipod = host->hostdata;
+
+	switch (packet->type) {
+	case hpsb_async:
+	case hpsb_raw:
+		break;
+
+	case hpsb_iso:
+	default:
+		printk(KERN_ERR "cannot do pkt type 0x%x\n", packet->type);
+		return 0;
+	}
+
+	if (packet->data_size > (fw_reg_read(LYNX_ATF_STATUS)&0x1ff)) {
+		printk(KERN_ERR "Transmit packet size %d is too large",
+			packet->data_size);
+		return 0;
+	}
+
+	spin_lock(&ipod->tx_list_lock);
+	list_add_tail(&packet->driver_list, &ipod->tx_list);
+	tasklet_schedule(&ipod->tx_tasklet);
+	spin_unlock(&ipod->tx_list_lock);
+
+	return 1;
+}
+
+/* This function requests miscellaneous services from the driver, see
+ * above for command codes and expected actions.  Return -1 for unknown
+ * command, though that should never happen.
+ */
+static int ipod_1394_devctl(struct hpsb_host *host, enum devctl_cmd command, int arg)
+{
+	struct ti_ipod *ipod = host->hostdata;
+	int retval = 0;
+	int phy_reg;
+
+	switch (command) {
+	case RESET_BUS:
+		switch (arg)
+		{
+		case SHORT_RESET:
+			set_phy_reg_mask(ipod, 5, 0x40); /* set ISBR */
+			break;
+		case LONG_RESET:
+			set_phy_reg_mask(ipod, 1, 0x40); /* set IBR */
+			break;
+
+		case SHORT_RESET_NO_FORCE_ROOT:
+			phy_reg = get_phy_reg(ipod, 1);
+			if (phy_reg & 0x80) {
+				phy_reg &= ~0x80;
+				set_phy_reg(ipod, 1, phy_reg); /* clear RHB */
+			}
+
+			phy_reg = get_phy_reg(ipod, 5);
+			phy_reg |= 0x40;
+			set_phy_reg(ipod, 5, phy_reg); /* set ISBR */
+			break;
+
+		case LONG_RESET_NO_FORCE_ROOT:
+			phy_reg = get_phy_reg(ipod, 1);
+			phy_reg &= ~0x80;
+			phy_reg |= 0x40;
+			set_phy_reg(ipod, 1, phy_reg); /* clear RHB, set IBR */
+			break;
+
+		case SHORT_RESET_FORCE_ROOT:
+			phy_reg = get_phy_reg(ipod, 1);
+			if (!(phy_reg & 0x80)) {
+				phy_reg |= 0x80;
+				set_phy_reg(ipod, 1, phy_reg); /* set RHB */
+			}
+
+			phy_reg = get_phy_reg(ipod, 5);
+			phy_reg |= 0x40;
+			set_phy_reg(ipod, 5, phy_reg); /* set ISBR */
+			break;
+
+		case LONG_RESET_FORCE_ROOT:
+			phy_reg = get_phy_reg(ipod, 1);
+			phy_reg |= 0xc0;
+			set_phy_reg(ipod, 1, phy_reg); /* set RHB and IBR */
+			break;
+
+		default:
+			set_phy_reg_mask(ipod, 1, 0x40);
+			break;
+		}
+
+		break;
+
+	case GET_CYCLE_COUNTER:
+		retval = fw_reg_read(LYNX_CYCLE_TIMER);
+		break;
+
+	case SET_CYCLE_COUNTER:
+		fw_reg_write(LYNX_CYCLE_TIMER, arg);
+		break;
+
+	case SET_BUS_ID:
+		printk(KERN_ERR "devctl command SET_BUS_ID err\n");
+		break;
+
+	case ACT_CYCLE_MASTER:
+		if (arg) {
+			/* enable cyclemaster */
+			fw_reg_write(LYNX_CTRL, fw_reg_read(LYNX_CTRL)|LYNX_CTRL_CYCLE_MASTER);
+		}
+		else {
+			/* disable cyclemaster */
+			fw_reg_write(LYNX_CTRL, fw_reg_read(LYNX_CTRL)&~LYNX_CTRL_CYCLE_MASTER);
+		}
+		break;
+
+	case CANCEL_REQUESTS:
+		/* TODO: implement this */
+		break;
+
+	case MODIFY_USAGE:
+		if (arg) {
+			MOD_INC_USE_COUNT;
+		} else {
+			MOD_DEC_USE_COUNT;
+		}
+		retval = 1;
+		break;
+
+	case ISO_LISTEN_CHANNEL:
+	case ISO_UNLISTEN_CHANNEL:
+	default:
+		printk(KERN_ERR "unknown devctl cmd %d\n", command);
+		break;
+	}
+
+	return retval;
+}
+
+
+#define IPOD_1394_DRIVER_NAME	"ipod1394"
+
+static struct hpsb_host_driver ipod_1394_driver = {
+	.name = IPOD_1394_DRIVER_NAME,
+	.get_rom = ipod_1394_get_rom,
+	.transmit_packet = ipod_1394_transmit_packet,
+	.devctl = ipod_1394_devctl,
+};
+
+#define SELF_ID_BEGIN        0x000000e0ul
+#define SELF_ID_END          0x00000001ul
+#define SELF_ID_VALID        0x80000000ul
+
+/*
+ * The self-id packet stream looks like:
+ * 0xe0
+ * 0x80xxxxxx
+ * 0x81xxxxxx
+ * 0x1
+ * 0xe0
+ * 0xe0
+ * 0xe0
+ */
+static void handle_selfid(struct ti_ipod *ipod, struct hpsb_host *host)
+{
+	quadlet_t q0 = 0;
+	size_t size;
+	int num_nodes;
+	int phyid;
+	int isroot;
+
+	/* Check the DRF for available data in FIFO */
+	size = fw_reg_read(LYNX_DXF_AVAIL) & 0x7ff;
+	if (size == 0) {
+		printk(KERN_ERR "No self-id data in FIFO\n");
+		/* TODO, need to initiate bus reset */
+		return;
+	}
+
+	while (size > 0) {
+		/* scan through DRF data for start of self-id data */
+		do {
+			q0 = fw_reg_read(LYNX_DRF_DATA);	/* read from DRF */
+			size = fw_reg_read(LYNX_DXF_AVAIL) & 0x7ff;
+		} while (q0 == SELF_ID_BEGIN && size > 0);
+
+		if (size == 0) {
+			/* TODO, this is an error if we havent seen any nodes */
+			if (host->selfid_count == 0) {
+				printk(KERN_ERR "No self-ids seen\n");
+			}
+			break;
+		}
+
+		if (fw_reg_read(LYNX_INTERRUPT) & LYNX_INTERRUPT_BusRst ) {
+			printk(KERN_ERR "Bus reset pending\n");
+			return;
+		}
+
+		num_nodes = (fw_reg_read(LYNX_BUS_RESET) >> 6) & 0x003f;
+		host->selfid_count = 0;	/* reset if we are doing this again */
+
+		while (num_nodes > 0) {
+			if ((q0 & 0xc0000000) == SELF_ID_VALID) {
+				printk(KERN_DEBUG "SelfID packet 0x%x received\n", q0);
+
+				hpsb_selfid_received(host, cpu_to_be32(q0));
+
+				if (!(q0 & 0x1)) {
+					num_nodes--;
+				}
+			}
+			else if (q0 == SELF_ID_END) {
+				break;
+			}
+			q0 = fw_reg_read(LYNX_DRF_DATA);	/* read from DRF */
+			size = fw_reg_read(LYNX_DXF_AVAIL) & 0x7ff;
+		}
+	}
+
+	phyid = (fw_reg_read(LYNX_BUS_RESET) >> 16) & 0x3f;
+	isroot = (fw_reg_read(LYNX_ACK) & 0x8000) != 0;
+
+	printk(KERN_DEBUG "SelfID complete %x(%d)\n", phyid, (isroot?1:0));
+
+	hpsb_selfid_complete(host, phyid, isroot);
+}
+
+static void ipod_1394_fw_int(int irq, struct ti_ipod *ipod)
+{
+	struct hpsb_host *host = ipod->host;
+	unsigned fw_src;
+
+	/* interrupt source */
+	fw_src = fw_reg_read(LYNX_INTERRUPT);
+	if (fw_src) {
+		/* ack the interrupt */
+		fw_reg_write(LYNX_INTERRUPT, fw_src);
+
+		if (fw_src & LYNX_INTERRUPT_BusRst) {
+			if (!host->in_bus_reset) {
+				printk(KERN_ERR "irq: bus reset requested\n");
+				hpsb_bus_reset(host);
+			}
+		}
+		if (fw_src & LYNX_INTERRUPT_SelfIDEnd) {
+			if (host->in_bus_reset) {
+				quadlet_t bus_reset;
+				int BRFErr_Code;
+
+				bus_reset = (fw_reg_read(LYNX_BUS_RESET) & LYNX_BUSRESET_ERRCODE) >> 12;
+				BRFErr_Code = (bus_reset & LYNX_BUSRESET_ERRCODE) >> 12;
+				/* ignore gap count errors */
+				if (BRFErr_Code == 0x0 || BRFErr_Code == 0xf)
+				{
+					/* TODO: this should be outside isr! */
+					handle_selfid(ipod, host);
+				}
+				else
+				{
+					printk(KERN_ERR "Bus reset err 0x%x\n", BRFErr_Code);
+					/* TODO, initiate bus reset */
+				}
+			}
+			else {
+				printk(KERN_ERR "irq: selfid outside bus reset\n");
+			}
+		}
+
+		if (fw_src & LYNX_INTERRUPT_ATFEnd) {
+			unsigned long flags;
+
+			spin_lock_irqsave(&ipod->tx_lock, flags);
+			ipod->tx_state = TX_END;
+			tasklet_schedule(&ipod->tx_tasklet);
+			spin_unlock_irqrestore(&ipod->tx_lock, flags);
+		}
+
+		if (fw_src & LYNX_INTERRUPT_RxARF) {
+			unsigned long flags;
+
+			spin_lock_irqsave(&ipod->tx_lock, flags);
+			ipod->rx_state = RX_BUSY;
+			tasklet_schedule(&ipod->tx_tasklet);
+			spin_unlock_irqrestore(&ipod->tx_lock, flags);
+		}
+
+#if 0
+		// we handle these
+		fw_src &= ~(LYNX_INTERRUPT_BusRst|LYNX_INTERRUPT_SelfIDEnd|LYNX_INTERRUPT_ATFEnd|LYNX_INTERRUPT_RxARF);
+
+		fw_src &= ~( LYNX_INTERRUPT_Int | LYNX_INTERRUPT_FairGap | LYNX_INTERRUPT_TxRdy | LYNX_INTERRUPT_CySec| LYNX_INTERRUPT_CyStart| LYNX_INTERRUPT_CyDne| LYNX_INTERRUPT_CyPending| LYNX_INTERRUPT_CyLost| LYNX_INTERRUPT_CyArbFail );
+		if (host->in_bus_reset) {
+			fw_src &= ~( LYNX_INTERRUPT_PhyPkt | LYNX_INTERRUPT_RxPhyReg | LYNX_INTERRUPT_UpdDRFHdr | LYNX_INTERRUPT_DRFEnd );
+		}
+		if (fw_src) {
+			printk("fw_src %04x\n", fw_src);
+		}
+#endif
+	}
+}
+
+static void ipod_1394_interrupt(int irq, void *dev_id, struct pt_regs *regs_are_unused)
+{
+	struct ti_ipod *ipod = (struct ti_ipod *)dev_id;
+	unsigned source;
+
+	/* get source of interupts */
+	source = inb(0xcf000048);
+	if (source) {
+		outb(source, 0xcf000078);
+
+		if (source & (1<<4) ) {
+			/* get current status port c */
+			unsigned state = inb(0xcf000038);
+
+			if (state & (1<<4)) {
+				printk(KERN_ERR "fw pwr +\n");
+			}
+			else {
+				printk(KERN_ERR "fw pwr -\n");
+			}
+
+			outb(~state, 0xcf000068);
+		}
+
+		if (source & (1<<5)) {
+			ipod_1394_fw_int(irq, ipod);
+		}
+
+		if (source & ~(1<<4 | 1<<5)) {
+			printk(KERN_ERR "src=0x%x\n", source);
+		}
+	}
+}
+
+static __devinit void ipod_1394_hw_init(void)
+{
+	unsigned ipod_hw_ver;
+
+	ipod_hw_ver = ipod_get_hw_version() >> 16;
+
+	/* MIO setup? */
+	outl((inl(0xcf004040) & ~(1<<6)) | (1<<7), 0xcf004040);
+	outl(0x00001f1f, 0xcf00401c);
+	outl(0xffff, 0xcf004020);
+
+	/* this is the 1g and 2g init */
+	if (ipod_hw_ver == 0x1 || ipod_hw_ver == 0x2)
+	{
+		/* port D enable, PD(4) power down and LPS(5) link power staus, and(7?) */
+		outl(inl(0xcf00000c) | (1<<4)|(1<<5)|(1<<7), 0xcf00000c);
+
+		/* port D output enable */
+		outl(inl(0xcf00001c) | (1<<4)|(1<<5)|(1<<7), 0xcf00001c);
+
+		/* port D output value ~10000 | 100000 */
+		/* set PD (power down) to low and LPS to high (see 12.4) */
+		outl((inl(0xcf00002c) & ~(1<<4)) | (1<<5), 0xcf00002c);
+
+		udelay(20);
+	}
+
+	/* this is 1g only */
+	if (ipod_hw_ver == 0x1)
+	{
+		/* Reset TSB43AA82 link and PHY (see section 12.5) */
+		outl(inl(0xcf00000c) | (1<<1) | (1<<2) , 0xcf00000c);
+		outl(inl(0xcf00001c) | (1<<1) | (1<<2), 0xcf00001c);
+		outl(inl(0xcf00002c) | (1<<1) | (1<<2), 0xcf00002c);
+
+		udelay(0x14);
+
+		/* XRESETL */
+		outl(inl(0xcf00002c) & ~(1<<1), 0xcf00002c);
+		/* XRESETP */
+		outl(inl(0xcf00002c) & ~(1<<2), 0xcf00002c);
+
+		udelay(0x14);
+
+		outl(inl(0xcf00002c) | (1<<1), 0xcf00002c);
+		udelay(0x1);
+		outl(inl(0xcf00002c) | (1<<2), 0xcf00002c);
+
+		mdelay(10);
+	}
+
+	/* this is 2g only */
+	if (ipod_hw_ver == 0x2)
+	{
+		unsigned r2;
+
+		/* Port E Bit 2 Enable */
+		outl(inl(0xcf004048) | (1<<2), 0xcf004048);
+
+		r2 = inl(0xcf004044);
+
+		/* Port E Bit 4 output high */
+		outl(inl(0xcf004048) | (1<<4), 0xcf004048);
+
+		udelay(0x14);
+
+		/* Port E Bit 2 output low */
+		outl(inl(0xcf004048) & ~(1<<2), 0xcf004048);
+		/* Port E Bit 4 output low */
+		outl(inl(0xcf004048) & ~(1<<4), 0xcf004048);
+
+		udelay(0x14);
+
+		/* Port E Bit 2 output high */
+		outl(inl(0xcf004048) | (1<<2), 0xcf004048);
+		udelay(0x1);
+		/* Port E Bit 2 output high */
+		outl(inl(0xcf004048) | (1<<4), 0xcf004048);
+
+		udelay(0x14);
+
+		outl(r2 | (1<<4), 0xcf004044);
+	}
+
+	/* this is 3g */
+	if (ipod_hw_ver == 0x3)
+	{
+		/* reset device i2c */
+		outl(inl(0xcf005030) | (1<<8), 0xcf005030);
+		outl(inl(0xcf005030) & ~(1<<8), 0xcf005030);
+
+		/* some i2c magic */
+		ipod_i2c_send(0x8, 0x39, 0);
+		ipod_i2c_send(0x8, 0x3a, 0);
+		ipod_i2c_send(0x8, 0x3b, 0);
+		ipod_i2c_send(0x8, 0x3c, 0);
+		ipod_i2c_send(0x8, 0x39, 7);
+		ipod_i2c_send(0x8, 0x3a, 0);
+		ipod_i2c_send(0x8, 0x3b, 7);
+		ipod_i2c_send(0x8, 0x3c, 7);
+		ipod_i2c_send(0x8, 0x3b, 0);
+		ipod_i2c_send(0x8, 0x3c, 0);
+
+		/* don't enable GPIO port D bit 7 & set it to low
+		 * this seems to enable firewire DMA which messes
+		 * with the ide driver
+		 */
+		/*
+		outl(inl(0xcf00000c) | (1<<7), 0xcf00000c);
+		outl(inl(0xcf00001c) | (1<<7), 0xcf00001c);
+		outl(inl(0xcf00002c) & ~(1<<7), 0xcf00002c);
+		*/
+	}
+
+	if (fw_reg_read(LYNX_VERSION) != LYNX_VERSION_CHIP_ID) {
+		printk(KERN_ERR "ipod_1394: invalid chip revsion 0x%x\n", fw_reg_read(LYNX_VERSION));
+	}
+}
+
+static int __devinit ipod_1394_init(void)
+{
+	struct ti_ipod *ipod;
+
+	printk("ipod_1394: $Id: tsb43aa82.c,v 1.4 2004/03/02 23:18:38 leachbj Exp $\n");
+
+	ipod_host = hpsb_alloc_host(&ipod_1394_driver, sizeof(struct ti_ipod));
+	if (!ipod_host) {
+		printk(KERN_ERR "ipod_1394: failed to allocate control structure\n");
+		return -ENOMEM;
+	}
+
+	ipod = ipod_host->hostdata;
+	ipod->host = ipod_host;
+	ipod->csr_config_rom_cpu = kmalloc(CONFIG_ROM_LEN, GFP_KERNEL);
+	if (ipod->csr_config_rom_cpu == NULL) {
+		printk(KERN_ERR "ipod_1394: Failed to allocate buffer config rom");
+	}
+
+	spin_lock_init(&ipod->phy_reg_lock);
+	spin_lock_init(&ipod->tx_lock);
+	spin_lock_init(&ipod->tx_list_lock);
+	INIT_LIST_HEAD(&ipod->tx_list);
+
+	tasklet_init(&ipod->tx_tasklet, tx_tasklet, (unsigned long)ipod);
+
+	if (request_irq(GPIO_IRQ, ipod_1394_interrupt, SA_SHIRQ, IPOD_1394_DRIVER_NAME, ipod)) {
+		printk(KERN_ERR "ipod_1394: IRQ %d failed\n", GPIO_IRQ);
+	}
+
+	ipod_1394_hw_init();
+
+
+	/* Busy off until ready */
+	fw_reg_write(LYNX_CTRL, LYNX_CTRL_ACK_BUSY_X|LYNX_CTRL_CYCLE_TIMER_ENABLE);
+
+	/* Set FIFO sizes to inital values */
+	fw_reg_write(LYNX_DXF_SIZE,
+		  ((DMA_WRITE_FIFO_SIZE /* Set DTF size */
+		| (LYNX_DTFDRF_PTBUF_SIZE(DXF_PG_ENTRY)*2) << 10) << 16)  /* Set DTF PgTbl Quads */
+		| DMA_READ_FIFO_SIZE /* Set DRF size */
+		| (LYNX_DTFDRF_PTBUF_SIZE(DXF_PG_ENTRY)*2) << 10);  /*Set DRF PgTbl Quads */
+
+	fw_reg_write(LYNX_DMA_CTRL,
+		 DMA_CTRL_DRF_PAGE_FETCH_04     /* Set PgTbl Fetch size */
+		|DMA_CTRL_DTF_PAGE_FETCH_04);
+	fw_reg_write(LYNX_ATF_STATUS, ASYNC_TX_FIFO_SIZE);
+	fw_reg_write(LYNX_ARF_STATUS, ASYNC_RX_FIFO_SIZE);
+	fw_reg_write(LYNX_CTQ_STATUS, COMMAND_TX_QUE_SIZE);
+	fw_reg_write(LYNX_CRF_STATUS, COMMAND_RX_FIFO_SIZE);
+                                                                                
+	init_config_rom(ipod);
+
+	/* Initialize ASYNC FIFO's */
+	fw_reg_write(LYNX_ATF_STATUS, 0x1000|ASYNC_TX_FIFO_SIZE);
+	fw_reg_write(LYNX_ARF_STATUS, 0x1000|ASYNC_RX_FIFO_SIZE);
+	fw_reg_write(LYNX_MTQ_STATUS, 0x1000);
+	fw_reg_write(LYNX_MRF_STATUS, 0x1000);
+	fw_reg_write(LYNX_CTQ_STATUS, 0x1000|COMMAND_TX_QUE_SIZE);
+	fw_reg_write(LYNX_CRF_STATUS, 0x1000|COMMAND_RX_FIFO_SIZE);
+
+	/* Set Split Timeout, Retry Interval and Retry limit */
+	fw_reg_write(LYNX_TIMELIMIT, LYNX_TIMELIMIT_INIT_VALUE);
+
+	/* Initialize DMA FIFO's */
+	fw_reg_write(LYNX_DMA_CTRL, fw_reg_read(LYNX_DMA_CTRL)|DMA_CTRL_DRF_CLEAR|DMA_CTRL_DTF_CLEAR);
+	/* Ensure DMA FIFOs have cleared */
+	while ( fw_reg_read(LYNX_DMA_CTRL) & (DMA_CTRL_DRF_CLEAR|DMA_CTRL_DTF_CLEAR) );
+
+	fw_reg_write(LYNX_DMA_CTRL, (fw_reg_read(LYNX_DMA_CTRL) & 0xfc00)
+		| DMA_CTRL_DRF_ENABLE | DMA_CTRL_DTF_ENABLE
+		/* | DMA_CTRL_DRF_PKTZ_ENABLE | DMA_CTRL_DTF_PKTZ_ENABLE */
+		| DMA_CTRL_CONF_SINGL_PKT );
+		/* | DMA_CTRL_CHECK_PAGE_TABLE | DMA_CTRL_AUTO_PAGING */
+
+	/* Initialize Bulky IF Control register, Baseline */
+	fw_reg_write(LYNX_BI_CTRL, BDI_CTRL_AUTO_PAD_ENABL|BDI_CTRL_RCV_PAD_ENABLE );
+
+	fw_reg_write(LYNX_CTRL,
+		 LYNX_CTRL_ACK_BUSY_X	/* still busy */
+		|LYNX_CTRL_SELFID_RX_ENABLE
+		|LYNX_CTRL_SELFID_TO_DRF
+		|LYNX_CTRL_TRANS_ENABLE 
+		|LYNX_CTRL_ACCELARATED_ARB
+		|LYNX_CTRL_RESET_TRANS
+		|LYNX_CTRL_SPLIT_TRANS_ENABLE
+		|LYNX_CTRL_RETRY_ENABLE
+		|LYNX_CTRL_ACK_PENDING
+		|LYNX_CTRL_CYCLE_MASTER
+		|LYNX_CTRL_CYCLE_TIMER_ENABLE
+		|LYNX_CTRL_DMA_CLEAR	/* ensure DMA state machines ready */
+		|LYNX_CTRL_RCV_UNEXPECT_PKT);
+		// LYNX_CTRL_UNEXPECT_PKT_TO_DRF // receive packets to DRF not ATF
+
+	/* Clear DMAClear (this is a bug in ES1, it should automatically clear) */
+	fw_reg_write(LYNX_CTRL, fw_reg_read(LYNX_CTRL) & ~LYNX_CTRL_DMA_CLEAR);
+
+	/* Disable interrupt mask bits */
+	fw_reg_write(LYNX_IMASK, 0);
+
+	/* Clear interrupts */
+	fw_reg_write(LYNX_INTERRUPT, LYNX_INTERRUPT_ALL_CLEAR);
+
+	/*
+	 * disable the dynamic power consumption, this fixes a bug with
+	 * receiving broadcast messages.
+	 */
+	fw_reg_write(LYNX_RESERVED, POWER_CONSUMPTION_DIS);
+
+	/* setup firewire power (4) and firewire (5) interrupts */
+	{
+		/* enable port c bits 4 & 5 */
+		outb(inb(0xcf000008) | (1<<4) | (1<<5), 0xcf000008);
+
+		/* pin 4 & 5 is input */
+		outb(inl(0xcf000018) & ~((1<<4) | (1<<5)), 0xcf000018);
+
+		outb(~inb(0xcf000038), 0xcf000068);
+		outb(inb(0xcf000068) & ~(1<<5), 0xcf000068);
+
+		outb(inb(0xcf000048), 0xcf000078);
+		outb((1<<4)|(1<<5), 0xcf000058);
+	}
+
+	/* Disable interrupt mask bits */
+	fw_reg_write(LYNX_IMASK, LYNX_INTERRUPT_BusRst|LYNX_INTERRUPT_SelfIDEnd|LYNX_INTERRUPT_ATFEnd|LYNX_INTERRUPT_RxARF);
+
+	/* ready to process packets now */
+	fw_reg_write(LYNX_CTRL, fw_reg_read(LYNX_CTRL) & ~LYNX_CTRL_ACK_BUSY_X);
+
+	hpsb_add_host(ipod_host);
+
+	return 0;
+}
+
+static void __exit ipod_1394_exit(void)
+{
+	struct ti_ipod *ipod = ipod_host->hostdata;
+
+	hpsb_remove_host(ipod->host);
+
+	/* free the IRQ */
+	free_irq(GPIO_IRQ, ipod);
+
+        /* Wait and kill tasklet */
+        tasklet_kill(&ipod->tx_tasklet);
+
+	kfree(ipod->csr_config_rom_cpu);
+
+	hpsb_unref_host(ipod_host);
+	ipod_host = 0;
+
+	/* XXX power down the TI chip */
+}
+
+module_init(ipod_1394_init);
+module_exit(ipod_1394_exit);
+
+MODULE_AUTHOR("Bernard Leach <leachbj@bouncycastle.org>");
+MODULE_DESCRIPTION("driver for Texas Instruments IEEE-1394 controller in the iPod");
+MODULE_LICENSE("GPL");
+
diff -urN linux-2.4.29/arch/armnommu/mach-ipod/tsb43aa82.h linux-2.4.29-uc1/arch/armnommu/mach-ipod/tsb43aa82.h
--- linux-2.4.29/arch/armnommu/mach-ipod/tsb43aa82.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ipod/tsb43aa82.h	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,416 @@
+
+/*
+ * Copyright (c) 2004 Bernard Leach (leachbj@bouncycastle.org)
+ */
+ 
+#ifndef __TSB43AA82_H__
+#define __TSB43AA82_H__
+
+/**** Lynx internal register addresses ****/
+
+#define LYNX_VERSION          0x00
+#define LYNX_ACK              0x04
+#define LYNX_CTRL             0x08
+#define LYNX_INTERRUPT        0x0C
+#define LYNX_IMASK            0x10
+#define LYNX_CYCLE_TIMER      0x14
+#define LYNX_DIAGNOSTIC       0x18
+#define LYNX_RESERVED         0x1c
+#define LYNX_PHYACCESS        0x20
+#define LYNX_BUS_RESET        0x24
+#define LYNX_TIMELIMIT        0x28
+#define LYNX_ATF_STATUS       0x2C
+#define LYNX_ARF_STATUS       0x30
+#define LYNX_MTQ_STATUS       0x34
+#define LYNX_MRF_STATUS       0x38
+#define LYNX_CTQ_STATUS       0x3C
+#define LYNX_CRF_STATUS       0x40
+#define LYNX_ORB_FETCH_CTRL   0x44
+#define LYNX_MANAGEMENT_AGENT 0x48
+#define LYNX_COMMAND_AGENT    0x4C
+#define LYNX_AGENT_CTRL       0x50
+#define LYNX_ORB_PTR1         0x54
+#define LYNX_ORB_PTR2         0x58
+#define LYNX_AGENT_STATUS     0x5C
+#define LYNX_TXTIMER_CTRL     0x60
+#define LYNX_TXTIMER_STATUS1  0x64
+#define LYNX_TXTIMER_STATUS2  0x68
+#define LYNX_TXTIMER_STATUS3  0x6C
+#define LYNX_WRITE_FIRST      0x70
+#define LYNX_WRITE_CONTINUE   0x74
+#define LYNX_WRITE_UPDATE     0x78
+
+#define LYNX_ARF_DATA         0x80
+#define LYNX_MRF_DATA         0x84
+#define LYNX_CRF_DATA         0x88
+#define LYNX_CFR_CTRL         0x8C
+#define LYNX_DMA_CTRL         0x90
+#define LYNX_BI_CTRL          0x94
+#define LYNX_DXF_SIZE         0x98
+#define LYNX_DXF_AVAIL        0x9C
+#define LYNX_DXF_ACK          0xA0
+#define LYNX_DTF_1ST_CONTINUE 0xA4
+#define LYNX_DTF_UPDATE       0xA8
+#define LYNX_DRF_DATA         0xAC
+#define LYNX_DTF_CTRL0        0xB0
+#define LYNX_DTF_CTRL1        0xB4
+#define LYNX_DTF_CTRL2        0xB8
+#define LYNX_DTF_CTRL3        0xBC
+#define LYNX_DRF_CTRL0        0xC0
+#define LYNX_DRF_CTRL1        0xC4
+#define LYNX_DRF_CTRL2        0xC8
+#define LYNX_DRF_CTRL3        0xCC
+#define LYNX_DRF_HDR0         0xD0
+#define LYNX_DRF_HDR1         0xD4
+#define LYNX_DRF_HDR2         0xD8
+#define LYNX_DRF_HDR3         0xDC
+#define LYNX_DRF_TAILER       0xE0
+#define LYNX_DXF_EXPCTD_VALUE 0xE4
+#define LYNX_DXF_HDRSTAT0     0xE8
+#define LYNX_DXF_HDRSTAT1     0xEC
+#define LYNX_DXF_HDRSTAT2     0xF0
+#define LYNX_DXF_HDRSTAT3     0xF4
+#define LYNX_LOG_ROM_CTRL     0xF8
+#define LYNX_LOG_ROM_DATA     0xFC
+
+/************************************************************************/
+/*      PHY register offsets for 43AA82                          */
+/************************************************************************/
+#define PHY_ID_R_CPS        0x00
+#define PHY_RHB_IBR_GC      0x01
+#define PHY_NUMPORTS        0x02
+#define PHY_SPD_DELAY       0x03
+#define PHY_LC_C_JITTER_PWR 0x04
+#define PHY_RPIE_ETC        0x05
+#define PHY_PAGE_PORT       0x07
+
+
+
+/************************************************************************/
+/*      bit definition for LYNX_VERSION (0x00)                          */
+/************************************************************************/
+#define LYNX_VERSION_CHIP_ID      0x43008203ul
+#define LYNX_VERSION_BIG_ENDIAN   0xFFFFFFFFul
+
+/************************************************************************/
+/*      bit definition for LYNX_CTRL(0x08)                              */
+/************************************************************************/
+#define LYNX_CTRL_ID_VALID            0x80000000ul
+#define LYNX_CTRL_SELFID_RX_ENABLE    0x40000000ul
+#define LYNX_CTRL_SELFID_TO_DRF       0x20000000ul
+#define LYNX_CTRL_ACK_BUSY_X          0x08000000ul
+#define LYNX_CTRL_TRANS_ENABLE        0x04000000ul
+#define LYNX_CTRL_ACCELARATED_ARB     0x01000000ul
+#define LYNX_CTRL_CONCAT_ENABLE       0x00800000ul
+#define LYNX_CTRL_RESET_TRANS         0x00200000ul
+#define LYNX_CTRL_SEND_RESP_ERROR     0x00020000ul
+#define LYNX_CTRL_STORE_ERROR_PKT     0x00010000ul
+#define LYNX_CTRL_SPLIT_TRANS_ENABLE  0x00008000ul
+#define LYNX_CTRL_RETRY_ENABLE        0x00004000ul
+#define LYNX_CTRL_ACK_PENDING         0x00002000ul
+#define LYNX_CTRL_CYCLE_MASTER        0x00000800ul
+#define LYNX_CTRL_CYCLE_TIMER_ENABLE  0x00000200ul
+#define LYNX_CTRL_DMA_CLEAR           0x00000100ul
+#define LYNX_CTRL_RCV_UNEXPECT_PKT    0x00000080ul
+#define LYNX_CTRL_UNEXPECT_PKT_TO_DRF 0x00000040ul
+
+/************************************************************************/
+/*      bit definition for LYNX_INTERRUPT(0x0C), LYNX_IMASK(0x10)       */
+/************************************************************************/
+#define LYNX_INTERRUPT_ALL_CLEAR  0xFFFFFFFFul
+#define LYNX_INTERRUPT_Int        0x80000000ul
+#define LYNX_INTERRUPT_PhyInt     0x40000000ul
+#define LYNX_INTERRUPT_BusRst     0x20000000ul
+#define LYNX_INTERRUPT_CmdRst     0x10000000ul
+#define LYNX_INTERRUPT_SelfIDEnd  0x08000000ul
+#define LYNX_INTERRUPT_PhyPkt     0x04000000ul
+#define LYNX_INTERRUPT_SntRj      0x00800000ul
+#define LYNX_INTERRUPT_RxPhyReg   0x00400000ul
+#define LYNX_INTERRUPT_InvFAcc    0x00200000ul
+#define LYNX_INTERRUPT_HdErr      0x00100000ul
+#define LYNX_INTERRUPT_TCErr      0x00080000ul
+#define LYNX_INTERRUPT_CySec      0x00040000ul
+#define LYNX_INTERRUPT_CyStart    0x00020000ul
+#define LYNX_INTERRUPT_UpdDRFHdr  0x00008000ul
+#define LYNX_INTERRUPT_FairGap    0x00004000ul
+#define LYNX_INTERRUPT_TxRdy      0x00002000ul
+#define LYNX_INTERRUPT_CyDne      0x00001000ul
+#define LYNX_INTERRUPT_CyPending  0x00000800ul
+#define LYNX_INTERRUPT_CyLost     0x00000400ul
+#define LYNX_INTERRUPT_CyArbFail  0x00000200ul
+#define LYNX_INTERRUPT_ATFEnd     0x00000080ul
+#define LYNX_INTERRUPT_RxARF      0x00000040ul
+#define LYNX_INTERRUPT_MgtORBEnd  0x00000020ul
+#define LYNX_INTERRUPT_CmdORBEnd  0x00000010ul
+#define LYNX_INTERRUPT_DTFEnd     0x00000008ul
+#define LYNX_INTERRUPT_DRFEnd     0x00000004ul
+#define LYNX_INTERRUPT_TxExpr     0x00000002ul
+#define LYNX_INTERRUPT_AgntWr     0x00000001ul
+
+/************************************************************************/
+/*      bit definition for LYNX_RESERVED (0x1C)                         */
+/************************************************************************/
+#define POWER_CONSUMPTION_DIS     0x80000000
+
+/************************************************************************/
+/*      bit definition for LYNX_PHYACCESS (0x20)                        */
+/************************************************************************/
+#define LYNX_PHYACCESS_BUS_RESET  0x417F0000ul
+
+/* Bits for Bus Reset register :  */
+/************************************************************************/
+/*      bit definition for LYNX_BUS_RESET  (0x24)                       */
+/************************************************************************/
+#define LYNX_BUSRESET_BUSNUMBER   0xFFC00000ul
+#define LYNX_BUSRESET_NODENUM     0x003F0000ul
+#define LYNX_BUSRESET_ERRCODE     0x0000F000ul
+#define LYNX_BUSRESET_NODESUM     0x00000FC0ul
+#define LYNX_BUSRESET_IRMNODE     0x0000003Ful
+
+/************************************************************************/
+/*      bit definition for LYNX_TIMELIMIT (0x28)                        */
+/************************************************************************/
+//#define LYNX_TIMELIMIT_INIT_VALUE  0x3E8008E0ul /* SplTO Intrvl RtryLmt */
+                                                /* 2secs  1msec    14   */
+//#define LYNX_TIMELIMIT_INIT_VALUE  0x032008E0ul /* SplTO Intrvl   RtryLmt */
+                                                /* 0secs  100msec    14   */
+
+#define LYNX_TIMELIMIT_INIT_VALUE  0x0FA008E0ul /* SplTO Intrvl   RtryLmt */
+                                                /* 1secs    0msec    14   */
+
+/************************************************************************/
+/*      bit definition for LYNX_XXX_STATUS(0x2C-0x40)                   */
+/************************************************************************/
+#define LYNX_XXFSTAT_FULL     0x80000000ul  //FIFO FULL
+#define LYNX_XXFSTAT_ALMFULL  0x40000000ul  //FIFO ALMOST FULL
+#define LYNX_XXFSTAT_ALMEMPTY 0x20000000ul  //FIFO ALMOST EMPTY
+#define LYNX_XXFSTAT_EMPTY    0x10000000ul  //FIFO EMPTY
+
+#define LYNX_XXFSTAT_CLEAR    0x00001000ul  //FIFO CLEAR
+#define LYNX_XRFSTAT_PKT_CD   0x00008000ul  //
+
+
+/************************************************************************/
+/*      bit definition for LYNX_ORB_FETCH_CTRL(0x44)                    */
+/************************************************************************/
+#define LYNX_ORB_FETC_MGT_VALID       0x80000000ul
+#define LYNX_ORB_FETC_MGT_BUSY        0x40000000ul
+#define LYNX_ORB_FETC_MGT_SHORT_FMT   0x10000000ul
+#define LYNX_ORB_FETC_MGT_ORB_PRIO_0  0x00000000ul
+#define LYNX_ORB_FETC_MGT_ORB_PRIO_1  0x01000000ul
+#define LYNX_ORB_FETC_MGT_ORB_PRIO_2  0x02000000ul
+#define LYNX_ORB_FETC_MGT_ORB_PRIO_3  0x03000000ul
+#define LYNX_ORB_FETC_MGT_ORB_PRIO_4  0x04000000ul
+#define LYNX_ORB_FETC_MGT_ORB_PRIO_5  0x05000000ul
+#define LYNX_ORB_FETC_MGT_ORB_PRIO_6  0x06000000ul
+#define LYNX_ORB_FETC_MGT_ORB_PRIO_7  0x07000000ul
+#define LYNX_ORB_FETC_MGT_ORB_PRIO_8  0x08000000ul
+#define LYNX_ORB_FETC_MGT_ORB_PRIO_9  0x09000000ul
+#define LYNX_ORB_FETC_MGT_ORB_PRIO_A  0x0A000000ul
+#define LYNX_ORB_FETC_MGT_ORB_PRIO_B  0x0B000000ul
+#define LYNX_ORB_FETC_MGT_ORB_PRIO_C  0x0C000000ul
+#define LYNX_ORB_FETC_MGT_ORB_PRIO_D  0x0D000000ul
+#define LYNX_ORB_FETC_MGT_ORB_PRIO_E  0x0E000000ul
+#define LYNX_ORB_FETC_MGT_ORB_PRIO_F  0x0F000000ul
+#define LYNX_ORB_FETC_CMD_AGENT0_VLD  0x00008000ul
+#define LYNX_ORB_FETC_CMD_AGENT1_VLD  0x00004000ul
+#define LYNX_ORB_FETC_CMD_AGENT2_VLD  0x00002000ul
+#define LYNX_ORB_FETC_CMD_AGENT3_VLD  0x00001000ul
+#define LYNX_ORB_FETC_DRBELL_SNP      0x00000800ul
+#define LYNX_ORB_FETC_DRBELL_FETCH    0x00000400ul
+#define LYNX_ORB_FETC_NEXT_CMD_FETCH  0x00000200ul
+#define LYNX_ORB_FETC_CMD_SHORT_FMT   0x00000100ul
+#define LYNX_ORB_FETC_CMD_AGENT0_RDY  0x00000080ul
+#define LYNX_ORB_FETC_CMD_AGENT1_RDY  0x00000040ul
+#define LYNX_ORB_FETC_CMD_AGENT2_RDY  0x00000020ul
+#define LYNX_ORB_FETC_CMD_AGENT3_RDY  0x00000010ul
+#define LYNX_ORB_FETC_CMD_ORB_PRIO_0  0x00000000ul
+#define LYNX_ORB_FETC_CMD_ORB_PRIO_1  0x00000001ul
+#define LYNX_ORB_FETC_CMD_ORB_PRIO_2  0x00000002ul
+#define LYNX_ORB_FETC_CMD_ORB_PRIO_3  0x00000003ul
+#define LYNX_ORB_FETC_CMD_ORB_PRIO_4  0x00000004ul
+#define LYNX_ORB_FETC_CMD_ORB_PRIO_5  0x00000005ul
+#define LYNX_ORB_FETC_CMD_ORB_PRIO_6  0x00000006ul
+#define LYNX_ORB_FETC_CMD_ORB_PRIO_7  0x00000007ul
+#define LYNX_ORB_FETC_CMD_ORB_PRIO_8  0x00000008ul
+#define LYNX_ORB_FETC_CMD_ORB_PRIO_9  0x00000009ul
+#define LYNX_ORB_FETC_CMD_ORB_PRIO_A  0x0000000Aul
+#define LYNX_ORB_FETC_CMD_ORB_PRIO_B  0x0000000Bul
+#define LYNX_ORB_FETC_CMD_ORB_PRIO_C  0x0000000Cul
+#define LYNX_ORB_FETC_CMD_ORB_PRIO_D  0x0000000Dul
+#define LYNX_ORB_FETC_CMD_ORB_PRIO_E  0x0000000Eul
+#define LYNX_ORB_FETC_CMD_ORB_PRIO_F  0x0000000Ful
+
+
+/************************************************************************/
+/*      bit definition for LYNX_AGENT_CTRL (0x50)                       */
+/************************************************************************/
+#define LYNX_AGENTCTRL_USTLEN   0x00100000ul
+#define LYNX_AGENTCTRL_VALID    0x00080000ul
+#define LYNX_AGENTCTRL_WR_ID    0x00020000ul
+#define LYNX_AGENTCTRL_RD_ID    0x00010000ul
+
+/************************************************************************/
+/*      bit definition for LYNX_TXTIMER_CTRL (0x60)                     */
+/************************************************************************/
+#define LYNX_TXTIMER_DTTXEND    0x80000000ul
+#define LYNX_TXTIMER_DRTXEND    0x40000000ul
+#define LYNX_TXTIMER_ATTXEND    0x20000000ul
+#define LYNX_TXTIMER_MTTXEND    0x10000000ul
+#define LYNX_TXTIMER_CTTXEND    0x08000000ul
+#define LYNX_TXTIMER_ARTXEND    0x02000000ul
+#define LYNX_TXTIMER_DTERR      0x00800000ul
+#define LYNX_TXTIMER_DRERR      0x00400000ul
+#define LYNX_TXTIMER_ATERR      0x00200000ul
+#define LYNX_TXTIMER_MTERR      0x00100000ul
+#define LYNX_TXTIMER_CTERR      0x00080000ul
+#define LYNX_TXTIMER_ARERR      0x00020000ul
+
+/************************************************************************/
+/*      bit definition for LYNX_DMA_CTRL(0x90)                          */
+/************************************************************************/
+#define DMA_CTRL_DMA_WRITE_ENABLE  0x80000000ul // bit 0
+#define DMA_CTRL_DRF_ENABLE        0x20000000ul // bit 2
+#define DMA_CTRL_DTF_ENABLE        0x10000000ul // bit 3
+#define DMA_CTRL_DRF_PKTZ_ENABLE   0x08000000ul // bit 4
+#define DMA_CTRL_DTF_PKTZ_ENABLE   0x04000000ul // bit 5
+#define DMA_CTRL_DRF_SPLIT_DISABLE 0x02000000ul // bit 6
+#define DMA_CTRL_DTF_SPLIT_DISABLE 0x01000000ul // bit 7
+#define DMA_CTRL_HEADER_SEL_0      0x00000000ul // bit 8:9
+#define DMA_CTRL_HEADER_SEL_1      0x00400000ul // bit 8:9
+#define DMA_CTRL_HEADER_SEL_2      0x00800000ul // bit 8:9
+#define DMA_CTRL_HEADER_SEL_3      0x00C00000ul // bit 8:9
+#define DMA_CTRL_CONF_SINGL_PKT    0x00200000ul // bit 10
+#define DMA_CTRL_LONG_BLOCK        0x00100000ul // bit 11
+#define DMA_CTRL_QUAD_SEND         0x00080000ul // bit 12
+#define DMA_CTRL_QUAD_BOUNDARY     0x00040000ul // bit 13
+#define DMA_CTRL_CHECK_PAGE_TABLE  0x00020000ul // bit 14
+#define DMA_CTRL_AUTO_PAGING       0x00010000ul // bit 15
+
+//How many PageTable ENTRIES to be fetched, must be Power of 2
+#define DMA_CTRL_DRF_PAGE_FETCH_01  0x00000000ul // bit 16:18
+#define DMA_CTRL_DRF_PAGE_FETCH_02  0x00002000ul // bit 16:18
+#define DMA_CTRL_DRF_PAGE_FETCH_04  0x00004000ul // bit 16:18
+#define DMA_CTRL_DRF_PAGE_FETCH_08  0x00006000ul // bit 16:18
+#define DMA_CTRL_DRF_PAGE_FETCH_16  0x00008000ul // bit 16:18
+#define DMA_CTRL_DRF_PAGE_FETCH_32  0x0000A000ul // bit 16:18
+#define DMA_CTRL_DRF_PAGE_FETCH_64  0x0000C000ul // bit 16:18
+#define DMA_CTRL_DRF_PAGE_FETCH_128 0x0000E000ul // bit 16:18
+
+//How many PageTable ENTRIES to be fetched, must be Power of 2
+#define DMA_CTRL_DTF_PAGE_FETCH_01  0x00000000ul // bit 19:21
+#define DMA_CTRL_DTF_PAGE_FETCH_02  0x00000400ul // bit 19:21
+#define DMA_CTRL_DTF_PAGE_FETCH_04  0x00000800ul // bit 19:21
+#define DMA_CTRL_DTF_PAGE_FETCH_08  0x00000C00ul // bit 19:21
+#define DMA_CTRL_DTF_PAGE_FETCH_16  0x00001000ul // bit 19:21
+#define DMA_CTRL_DTF_PAGE_FETCH_32  0x00001400ul // bit 19:21
+#define DMA_CTRL_DTF_PAGE_FETCH_64  0x00001800ul // bit 19:21
+#define DMA_CTRL_DTF_PAGE_FETCH_128 0x00001C00ul // bit 19:21
+
+#define DMA_CTRL_ACK_PENDING       0x00000200ul // bit 22
+#define DMA_CTRL_COMPLETE_RESP     0x00000100ul // bit 23
+#define DMA_CTRL_DTF_HEADER_INSERT 0x00000080ul // bit 24
+#define DMA_CTRL_DRF_PAUSE         0x00000040ul // bit 25
+#define DMA_CTRL_DRF_AUTOPAUSE     0x00000020ul // bit 26
+#define DMA_CTRL_DRF_HEADER_STRIP  0x00000010ul // bit 27
+#define DMA_CTRL_DRD_SELECT        0x00000008ul // bit 28
+#define DMA_CTRL_DTD_SELECT        0x00000004ul // bit 29
+#define DMA_CTRL_DRF_CLEAR         0x00000002ul // bit 30
+#define DMA_CTRL_DTF_CLEAR         0x00000001ul // bit 31
+
+
+/************************************************************************/
+/*      bit definition for LYNX_BI_CTRL(0x94)                           */
+/************************************************************************/
+
+#define BDI_CTRL_MTR_BUF_SIZE_0   0x00000000ul // bit 3:5
+#define BDI_CTRL_MTR_BUF_SIZE_2   0x04000000ul // bit 3:5
+#define BDI_CTRL_MTR_BUF_SIZE_4   0x08000000ul // bit 3:5
+#define BDI_CTRL_MTR_BUF_SIZE_6   0x0C000000ul // bit 3:5
+#define BDI_CTRL_MTR_BUF_SIZE_8   0x10000000ul // bit 3:5
+#define BDI_CTRL_MTR_BUF_SIZE_10  0x14000000ul // bit 3:5
+#define BDI_CTRL_MTR_BUF_SIZE_12  0x18000000ul // bit 3:5
+#define BDI_CTRL_MTR_BUF_SIZE_14  0x1C000000ul // bit 3:5
+
+#define BDI_CTRL_MTT_BUF_SIZE_0   0x00000000ul // bit 6:8
+#define BDI_CTRL_MTT_BUF_SIZE_2   0x00800000ul // bit 6:8
+#define BDI_CTRL_MTT_BUF_SIZE_4   0x01000000ul // bit 6:8
+#define BDI_CTRL_MTT_BUF_SIZE_6   0x01800000ul // bit 6:8
+#define BDI_CTRL_MTT_BUF_SIZE_8   0x02000000ul // bit 6:8
+#define BDI_CTRL_MTT_BUF_SIZE_10  0x02800000ul // bit 6:8
+#define BDI_CTRL_MTT_BUF_SIZE_12  0x03000000ul // bit 6:8
+#define BDI_CTRL_MTT_BUF_SIZE_14  0x03800000ul // bit 6:8
+
+#define BDI_CTRL_BDACK_HI_ENABLE     0x00400000ul // bit 9
+#define BDI_CTRL_ATACK_HI_ENABLE     0x00100000ul // bit 11
+#define BDI_CTRL_BDI_BUSY_HI_ENABLE  0x00080000ul // bit 12
+#define BDI_CTRL_BDO_AVAIL_HI_ENABLE 0x00040000ul // bit 13
+#define BDI_CTRL_BDOEN_HI_ENABLE     0x00020000ul // bit 14
+#define BDI_CTRL_BDIEN_HI_ENABLE     0x00010000ul // bit 15
+#define BDI_CTRL_LITTLE_ENDIAN       0x00008000ul // bit 16
+#define BDI_CTRL_AUTO_PAD_ENABL      0x00004000ul // bit 17
+
+#define BDI_CTRL_BD0_DELAY_0  0x00000000ul // bit 18:19
+#define BDI_CTRL_BD0_DELAY_1  0x00001000ul // bit 18:19
+#define BDI_CTRL_BD0_DELAY_2  0x00002000ul // bit 18:19
+#define BDI_CTRL_BD0_DELAY_3  0x00003000ul // bit 18:19
+#define BDI_CTRL_BDI_DELAY_0  0x00000000ul // bit 20:21
+#define BDI_CTRL_BDI_DELAY_1  0x00000400ul // bit 20:21
+#define BDI_CTRL_BDI_DELAY_2  0x00000800ul // bit 20:21
+#define BDI_CTRL_BDI_DELAY_3  0x00000C00ul // bit 20:21
+
+#define BDI_CTRL_DMA_MODE_MASK 0x370 // (bit 22:23,25:27) mask for DMA mode bits
+#define BDI_CTRL_DMA_MODE_A  0      // sync 8bit parallel in/out
+#define BDI_CTRL_DMA_MODE_B  0x110  // async 8bit parallel in/out
+#define BDI_CTRL_DMA_MODE_C  0x120  // async 8bit bi-directional
+#define BDI_CTRL_DMA_MODE_D  0x230  // sync 8bit bi-directional
+#define BDI_CTRL_DMA_MODE_E  0x340  // async 8bit bi-directional (scsi)
+#define BDI_CTRL_DMA_MODE_F  0x150  // async 16bit bi-directional
+#define BDI_CTRL_DMA_MODE_G  0x260  // sync 16bit bi-directional
+#define BDI_CTRL_DMA_MODE_H  0x370  // async 16bit bi-directional (scsi)
+
+#define BDI_CTRL_BURST_ENABLE   0x00000080ul // bit 24
+#define BDI_CTRL_RCV_PAD_ENABLE 0x00000008ul // bit 28
+#define BDI_CTRL_BDO_RESET      0x00000004ul // bit 29
+#define BDI_CTRL_BDI_RESET      0x00000002ul // bit 30
+#define BDI_CTRL_BD0_DISABLE    0x00000001ul // bit 31
+
+#define BDI_SIGNALS_ALLOWED  0x007FFC89ul
+
+/************************************************************************
+ *  bit definition for LYNX_DTFDRF_SIZE(0x98)
+ *
+ *  These reflect the values set in the DMA Control (0x90)
+ *  for Page table Fetch Size
+ *
+ *  (0x90) FetSize is # of PgTbl Entries to get (ie 2^((FetSize-1)+3) BYTES)
+ ************************************************************************/
+#define LYNX_DTFDRF_PTBUF_SIZE(NumEntries)  (2 * NumEntries)  //In Quadlets
+/*
+#define LYNX_DTFDRF_PTBUF_SIZE_1 0x0800  // 1 PgTbl entries (  8 bytes)
+#define LYNX_DTFDRF_PTBUF_SIZE_2 0x1000  // 2 PgTbl entries ( 16 bytes)
+#define LYNX_DTFDRF_PTBUF_SIZE_3 0x1800  // 3 PgTbl entries ( 24 bytes)
+#define LYNX_DTFDRF_PTBUF_SIZE_4 0x2000  // 4 PgTbl entries ( 32 bytes)
+#define LYNX_DTFDRF_PTBUF_SIZE_5 0x2800  // 5 PgTbl entries ( 40 bytes)
+#define LYNX_DTFDRF_PTBUF_SIZE_6 0x3000  // 6 PgTbl entries ( 48 bytes)
+#define LYNX_DTFDRF_PTBUF_SIZE_7 0x3800  // 7 PgTbl entries ( 56 bytes)
+*/
+
+/************************************************************************/
+/*  bit definition for LYNX_DXF_CTRL0 (0xB0 & 0xC0)                     */
+/************************************************************************/
+#define LYNX_DXFC0_START      0x80000000ul
+#define LYNX_DXFC0_INITSTART  0xC0000000ul
+#define LYNX_DXFC0_ABORT      0x40000000ul
+#define LYNX_DXFC0_DXFCLR     0x20000000ul
+
+
+/************************************************************************/
+/*      bit definition for LYNX_LOG_ROM_CTRL (0xF8)                     */
+/************************************************************************/
+#define LYNX_ROM_CTRL_XLOG      0x00008000ul
+#define LYNX_ROM_CTRL_VALID     0x00004000ul
+#define LYNX_ROM_CTRL_ROM_ADDR  0x00000400ul
+
+#endif
+
diff -urN linux-2.4.29/arch/armnommu/mach-isl3893/arch.c linux-2.4.29-uc1/arch/armnommu/mach-isl3893/arch.c
--- linux-2.4.29/arch/armnommu/mach-isl3893/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-isl3893/arch.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,104 @@
+/*  $Header$
+ *
+ *  linux/arch/arm/mach-isl3893/arch.c
+ *
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  Architecture specific fixups.  This is where any
+ *  parameters in the params struct are fixed up, or
+ *  any additional architecture specific information
+ *  is pulled from the params struct.
+ */
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+
+#include <asm/elf.h>
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/arch/serial.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/blobcalls.h>
+
+extern void genarch_init_irq(void);
+extern void init_ram_mpu_area(unsigned long , unsigned long );
+
+/* These are initialized in head-armv.S */
+struct boot_struct *bootstruct = NULL;
+struct boot_parms *boot_param_block = NULL;
+
+struct param_struct common_params = { { {
+	page_size:		4096,
+	nr_pages:		0,
+	flags:    		FLAG_RDLOAD,
+	rootdev:		0
+} } };
+
+static void __init
+fixup_isl3893(struct machine_desc *desc, struct param_struct *params,
+             char **cmdline, struct meminfo *mi)
+{
+#ifdef CONFIG_DEBUG_LL
+	uart_initialize();
+#endif
+
+	// MTHU: debugging - remove
+	printk("Boot Struct at %p\n", bootstruct);
+	printk("Boot parameter block at %p\n", boot_param_block);
+    // MTHU: debugging - remove
+
+    /* The bootrom uses Ethernet buffers in the area 0x07ff7b40 to 0x08000000
+     * When these buffers are flushed by the MVC, this memory should not be used
+     * by the kernel
+     */
+    if((bootstruct->sram_size & 0xffff) > 0x7b40) {
+        bootstruct->sram_size = (bootstruct->sram_size & 0xffff0000) + 0x7b40;
+    }
+    printk("SRAM size 0x%lx\n", bootstruct->sram_size);
+
+#ifndef ISL3893_NO_MVC
+	if(!bootstruct || bootstruct->magic != BOOTMAGIC_BSv2) {
+		printk("Invalid bootstruct %p (magic %lx)\n", bootstruct, bootstruct->magic);
+		panic("Invalid Bootstruct");
+	}
+	params->u1.s.nr_pages = bootstruct->sram_size >> PAGE_SHIFT;
+
+	if(!boot_param_block || boot_param_block->magic != BOOTMAGIC_PARM) {
+		printk("Invalid Boot Parameter Block %p (magic %lx)\n",
+			boot_param_block, boot_param_block->magic);
+	}
+#endif
+
+	/* The bank should start at the physical start of RAM, while our
+	 * sram_base is the start of RAM that is available after MVC init.
+	 */
+	mi->nr_banks      = 1;
+	mi->bank[0].start = PHYS_OFFSET;
+#ifdef ISL3893_NO_MVC
+	mi->bank[0].size  = 0x00800000;	// for now set to 8MByte
+#else
+	mi->bank[0].size  = bootstruct->sram_base + bootstruct->sram_size - PHYS_OFFSET;
+#endif /* ISL3893_NO_MVC */
+	mi->bank[0].node  = 0;
+	mi->end = mi->bank[0].start + mi->bank[0].size;
+
+#ifndef ISL3893_SIMSONLY
+	/* Initialize an MPU area for the Entire RAM */
+	init_ram_mpu_area(mi->bank[0].start, mi->bank[0].size);
+	/* Switch to KERNEL_DS. We switch to USER_DS when the first app is started */
+	set_fs(get_ds());
+#endif
+}
+
+MACHINE_START(ISL3893, "ISL3893")
+	BOOT_MEM(PHYS_OFFSET, 0x12345678, 0x12345678)	// phys RAM, phys IO, virt IO
+	MAINTAINER("TBD")
+	INITIRQ(genarch_init_irq)
+	BOOT_PARAMS((unsigned int)&common_params)
+	FIXUP(fixup_isl3893)
+MACHINE_END
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-isl3893/debug.c linux-2.4.29-uc1/arch/armnommu/mach-isl3893/debug.c
--- linux-2.4.29/arch/armnommu/mach-isl3893/debug.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-isl3893/debug.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,88 @@
+/*  $Header$
+ *
+ *  linux/arch/arm/mach-isl3893/debug.c
+ *
+ *  Copyright (C) 2003 Intersil Americas Inc.
+ *
+ *  Architecture specific debug.
+ */
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <asm/arch/blobcalls.h>
+
+/* This is initialized in head-armv.S */
+extern struct boot_parms *boot_param_block;
+
+struct printf_entry {
+	char *format;
+	char *param1;
+	char *param2;
+	char *param3;
+};
+
+#define MAX_PRINTF_ENTRIES	1
+#define PRINTF_ENTRY_SIZE	(sizeof(struct printf_entry) / sizeof(long))
+
+static long printf_buffer[2 + (MAX_PRINTF_ENTRIES * PRINTF_ENTRY_SIZE)];
+
+/* We setup a debug printf queue that is printed by the bootrom when we have
+ * an uncontrolled reset. We only use 1 printf queue: the kernel printk queue
+ */
+extern int get_printk_log_buf(char **buf);
+
+static int setup_debug_queues(void)
+{
+	struct printf_buf *my_printf_buf;
+	struct printf_entry *my_printf_entry;
+	struct printf_info *printf_info, *my_printf_info;
+	char *printk_log_buf;
+	unsigned long printf_buf_count;
+
+	if(!boot_param_block || boot_param_block->magic != BOOTMAGIC_PARM) {
+		printk("Invalid Boot Parameter Block %p (magic %lx)\n",
+			boot_param_block, boot_param_block->magic);
+		return 0;
+	}
+
+	/* Allocate 1 extra printf info struct after the currently existing ones */
+	printf_buf_count = boot_param_block->printf_buf_count;
+	/* Paranoia? */
+	if(printf_buf_count > 32)
+		return 0;
+
+	printf_info = kmalloc((printf_buf_count + 1) * sizeof(struct printf_info), GFP_KERNEL);
+
+	if(printf_buf_count > 0) {
+		/* Copy the current printf_info array */
+		memcpy(printf_info, boot_param_block->printf_info,
+			printf_buf_count * sizeof(struct printf_info));
+	}
+
+
+	/* Fill my printf buffer with 1 entry */
+	my_printf_buf = (struct printf_buf *)printf_buffer;
+	my_printf_buf->head = 0;
+	my_printf_buf->tail = 0;
+	my_printf_entry = (struct printf_entry *)(my_printf_buf->queue);
+
+	get_printk_log_buf(&printk_log_buf);
+	my_printf_entry->format = printk_log_buf;
+	my_printf_entry->param1 = NULL;
+	my_printf_entry->param2 = NULL;
+	my_printf_entry->param3 = NULL;
+
+	my_printf_info = printf_info + printf_buf_count;
+	my_printf_info->size = MAX_PRINTF_ENTRIES * PRINTF_ENTRY_SIZE;
+	my_printf_info->buf = my_printf_buf;
+
+	/* Update the boot parameter block */
+	boot_param_block->printf_info = printf_info;
+	boot_param_block->printf_buf_count = printf_buf_count + 1;
+
+	return 0;
+}
+
+/* We need to setup the debug queues after the memory is initialized because
+ * we need kmalloc. Therefore, we use an __initcall
+ */
+__initcall(setup_debug_queues);
diff -urN linux-2.4.29/arch/armnommu/mach-isl3893/irq.c linux-2.4.29-uc1/arch/armnommu/mach-isl3893/irq.c
--- linux-2.4.29/arch/armnommu/mach-isl3893/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-isl3893/irq.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,38 @@
+/*
+ *  linux/arch/arm/mach-isl3893/irq.c
+ */
+#include <linux/init.h>
+
+#include <asm/mach/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+inline void isl3893_irq_ack(int irq)
+{
+}
+
+
+void __inline__ isl3893_mask_irq(unsigned int irq)
+{
+	/* reset corresponding bit in the 32bit Int mask register */
+	uIRQ->EnableClear = (1 << (irq & 0x1f));
+}
+
+
+void __inline__ isl3893_unmask_irq(unsigned int irq)
+{
+	/* set corresponding bit in the 32bit Int mask register */
+	uIRQ->EnableSet = (1 << (irq & 0x1f));
+}
+
+
+inline void isl3893_mask_ack_irq(unsigned int irq)
+{
+}
+
+
+
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-isl3893/Makefile linux-2.4.29-uc1/arch/armnommu/mach-isl3893/Makefile
--- linux-2.4.29/arch/armnommu/mach-isl3893/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-isl3893/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= isl3893.o
+
+# Object file lists.
+
+obj-y			:= $(patsubst %.c, %.o, $(wildcard *.c)) $(patsubst %.S, %.o, $(wildcard *.S))
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= pci.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-isl3893/mm.c linux-2.4.29-uc1/arch/armnommu/mach-isl3893/mm.c
--- linux-2.4.29/arch/armnommu/mach-isl3893/mm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-isl3893/mm.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,48 @@
+/* $Header$
+ *
+ * arch/arm/mm/mm-isl3893.c
+ *
+ * Extra MPU routines for the ISL3893 architecture
+ *
+ * Copyright (C) 2002 Intersil Americas Inc.
+ */
+
+
+#include <linux/config.h>
+#include <linux/mman.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+
+#ifdef CONFIG_ARM9_MPU
+void print_mpu_areas( void )
+{
+	int i;
+	unsigned long mpu_regs[8];
+	unsigned long mpu_dperm;
+	unsigned long mpu_iperm;
+
+	/* Read MPU area definitions */
+	__asm__ __volatile__ ( "mrc p15, 0, %0, c6, c0, 0 " : "=r" (mpu_regs[0]) :);
+	__asm__ __volatile__ ( "mrc p15, 0, %0, c6, c1, 0 " : "=r" (mpu_regs[1]) :);
+	__asm__ __volatile__ ( "mrc p15, 0, %0, c6, c2, 0 " : "=r" (mpu_regs[2]) :);
+	__asm__ __volatile__ ( "mrc p15, 0, %0, c6, c3, 0 " : "=r" (mpu_regs[3]) :);
+	__asm__ __volatile__ ( "mrc p15, 0, %0, c6, c4, 0 " : "=r" (mpu_regs[4]) :);
+	__asm__ __volatile__ ( "mrc p15, 0, %0, c6, c5, 0 " : "=r" (mpu_regs[5]) :);
+	__asm__ __volatile__ ( "mrc p15, 0, %0, c6, c6, 0 " : "=r" (mpu_regs[6]) :);
+	__asm__ __volatile__ ( "mrc p15, 0, %0, c6, c7, 0 " : "=r" (mpu_regs[7]) :);
+
+	/* Read MPU Access Permissions */
+	__asm__ __volatile__ ( "mrc p15, 0, %0, c5, c0, 2 " : "=r" (mpu_dperm) :); // Data
+	__asm__ __volatile__ ( "mrc p15, 0, %0, c5, c0, 3 " : "=r" (mpu_iperm) :); // Instr
+
+	printk("MPU register contents:\n");
+	for (i = 0; i < 8; i++) {
+		printk("%d: Area (0x%.8lx-0x%.8lx) En=%d, DataPerm=%lx, InstrPerm=%lx\n", i,
+			ARM_MPU_AREA_START(mpu_regs[i]),
+			ARM_MPU_AREA_END(mpu_regs[i]),
+			ARM_MPU_REGION_ENABLED(mpu_regs[i]),
+			(mpu_dperm >> (i * 4)) & 0xf,
+			(mpu_iperm >> (i * 4)) & 0xf);
+	}
+}
+#endif /* CONFIG_ARM9_MPU */
diff -urN linux-2.4.29/arch/armnommu/mach-isl3893/mpu.S linux-2.4.29-uc1/arch/armnommu/mach-isl3893/mpu.S
--- linux-2.4.29/arch/armnommu/mach-isl3893/mpu.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-isl3893/mpu.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,148 @@
+/*
+ *  linux/arch/armnommu/mach-isl3893/mpu.S
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/memory.h>
+
+/*
+ * ARM9 MPU area definitions
+ */
+
+#define Size_4KB	(0x0b << 1)
+#define Size_8KB	(0x0c << 1)
+#define Size_16KB	(0x0d << 1)
+#define Size_32KB	(0x0e << 1)
+#define Size_64KB	(0x0f << 1)
+#define Size_128KB	(0x10 << 1)
+#define Size_256KB	(0x11 << 1)
+#define Size_512KB	(0x12 << 1)
+#define Size_1MB	(0x13 << 1)
+#define Size_2MB	(0x14 << 1)
+#define Size_4MB	(0x15 << 1)
+#define Size_8MB	(0x16 << 1)
+#define Size_16MB	(0x17 << 1)
+#define Size_32MB	(0x18 << 1)
+#define Size_64MB	(0x19 << 1)
+#define Size_128MB	(0x1a << 1)
+#define Size_256MB	(0x1b << 1)
+#define Size_512MB	(0x1c << 1)
+#define Size_1GB	(0x1d << 1)
+#define Size_2GB	(0x1e << 1)
+#define Size_4GB	(0x1f << 1)
+
+#define Area_disable	0
+#define Area_enable	1
+
+/* ARM946 (Extended) MPU Access Permissions
+ * Coding: MPU_PERM_<priviliged>_<user>
+ *	NA: No Access
+ *	RO: Read Only
+ *	RW: Read/Write
+ */
+#define	MPU_PERM_NA_NA	0x0
+#define	MPU_PERM_RW_NA	0x1
+#define	MPU_PERM_RW_RO	0x2
+#define	MPU_PERM_RW_RW	0x3
+#define	MPU_PERM_RO_NA	0x5
+#define	MPU_PERM_RO_RO	0x6
+
+.section ".text.init",#alloc,#execinstr
+		.type	init_mpu_sections, #function 
+
+/*
+ * Configure memory protection unit and the caches
+ *
+ * Area 4, 5, 6 and 7 are used for memory protection.
+ * If memory protection is disabled, we use area 4 to
+ * give full access to the entire RAM area.
+ *
+ * Trashes r0 and r1
+ */
+ENTRY(init_mpu_sections)
+
+@ First disable all areas. We can then set the access permissions freely.
+	ldr		r0, =0x00000000 + Size_4GB + Area_disable
+	mcr     	p15, 0, r0, c6, c4, 0	@ area 4
+	mcr     	p15, 0, r0, c6, c5, 0	@ area 5
+	mcr     	p15, 0, r0, c6, c6, 0	@ area 6
+	mcr     	p15, 0, r0, c6, c7, 0	@ area 7
+
+
+	mrc		p15, 0, r0, c5, c0, 2	@ read data extended access permissions
+#ifdef CONFIG_ARM9_MPU
+						@ Area 4 (read only) is used for text mapping
+	ldr		r1, =(MPU_PERM_RW_RO << 16) + (MPU_PERM_RW_RW << 20) + (MPU_PERM_RW_RW << 24) + (MPU_PERM_RW_RW << 28)
+#else /* CONFIG_ARM9_MPU */
+	ldr		r1, =(MPU_PERM_RW_RW << 16)	@ Full access for area 4
+#endif
+	orr		r0, r0, r1
+#ifdef ISL3893_NO_MVC
+	/* This is only when the MPU areas are initialized by the bootrom.
+	 * We need to make the "All Memory" area (area 0) as Not Accessible for User Space
+	 */
+	and		r0, r0, #0xfffffff0
+	orr		r0, r0, #MPU_PERM_RW_NA
+#endif
+	mcr		p15, 0, r0, c5, c0, 2	@ set data extended access permissions
+
+
+	mrc		p15, 0, r0, c5, c0, 3	@ read instruction extended access permissions
+#ifdef CONFIG_ARM9_MPU
+						@ Full access for areas 4, 5, 6, 7
+	ldr		r1, =(MPU_PERM_RW_RW << 16) + (MPU_PERM_RW_RW << 20) + (MPU_PERM_RW_RW << 24) + (MPU_PERM_RW_RW << 28)
+#else
+	ldr		r1, =(MPU_PERM_RW_RW << 16)	@ Full access for area 4
+#endif
+	orr		r0, r0, r1
+#ifdef ISL3893_NO_MVC
+	/* This is only when the MPU areas are initialized by the bootrom.
+	 * We need to make the "All Memory" area (area 0) as Not Accessible for User Space
+	 */
+	and		r0, r0, #0xfffffff0
+	orr		r0, r0, #MPU_PERM_RW_NA
+#endif
+	mcr		p15, 0, r0, c5, c0, 3	@ set instruction extended access permissions
+
+.ltorg
+
+
+/* If the MPU is enabled, we leave all areas disabled. They are set when they are needed
+ * for memory protection. If the MPU is disabled, we use area 4 for the entire RAM and leave
+ * the rest disabled.
+ */
+
+#ifndef CONFIG_ARM9_MPU
+	mov		r0, #PHYS_OFFSET
+	add		r0, r0, #Size_16MB + Area_enable
+
+	mcr     	p15, 0, r0, c6, c4, 0	@ area 4
+#endif
+
+/*
+ * define cacheable data areas
+ */
+	mrc		p15, 0, r0, c2, c0, 0	                @ read cacheable data settings
+	orr		r0, r0, #(1 << 4) + (1 << 5) + (1 << 6) + (1 << 7)	@ enable for area 4, 5, 6, 7
+	mcr		p15, 0, r0, c2, c0, 0	                @ cacheable data
+
+
+/*
+ * define bufferable data areas
+ */
+	mrc		p15, 0, r0, c3, c0, 0                   @ read bufferable data settings
+	and		r0, r0, #0xffffff0f			@ disable for area 5, 6, 7
+	mcr		p15, 0, r0, c3, c0, 0                   @ bufferable data
+ 
+
+/*
+ * define cacheable code areas
+ */
+	mrc		p15, 0, r0, c2, c0, 1	                @ read cacheable code settings
+	orr		r0, r0, #(1 << 4) + (1 << 5) + (1 << 6) + (1 << 7)	@ enable for area 4, 5, 6, 7
+	mcr		p15, 0, r0, c2, c0, 1	                @ cacheable code 
+
+	mov		pc, lr
diff -urN linux-2.4.29/arch/armnommu/mach-isl3893/pci.c linux-2.4.29-uc1/arch/armnommu/mach-isl3893/pci.c
--- linux-2.4.29/arch/armnommu/mach-isl3893/pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-isl3893/pci.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,646 @@
+/*  $Header$
+ *
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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 <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/pci.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/dma.h>
+
+#ifdef CONFIG_PCI
+
+#define WORD_SIZE               4   /* bytes */
+
+#define HOST_PCI_BASE           (PCIO_BASE)
+#define HOST_MEM_OFFSET         0x00001000
+#define HOST_MEM_WINDOW         0x00001000
+#define HOST_MEM_MASK          (HOST_MEM_WINDOW-1)
+
+#define HOST_BASE_DMA           0xc0000000
+#define HOST_TX_DMA             0xF00
+#define HOST_RX_DMA             0xF20
+
+#define HOST_PCI_MAP	        (PCIO_BASE)
+#define HOST_MEM_MAP	        (HOST_PCI_MAP + HOST_MEM_OFFSET)
+
+#define PCI_ARCH_MEM_READ       0x06
+#define PCI_ARCH_MEM_WRITE      0x07
+#define PCI_ARCH_CONFIG_READ	0x0a    // 0xfa
+#define PCI_ARCH_CONFIG_WRITE   0x0b    // 0xfb
+
+#define DEBUG_                  0x01
+#define DEBUG_CONFIG            0x02
+#define DEBUG_IO                0x04
+#define DEBUG_RW                0x08
+
+unsigned long pci_debug_mask = DEBUG_;
+
+#define DEBUG
+#ifdef DEBUG
+#define DBG( mask, pr... )   if ( mask & pci_debug_mask ) { printk( pr ); }
+#else
+#define DBG( mask, pr... )
+#endif
+
+int pci_arch_master_wait( int size );
+void pci_arch_master_setup( int addr, int size, int mode );
+
+int pci_arch_read( int offset );
+int pci_arch_write( int offset, int value );
+
+int pci_arch_read_config( int offset );
+int pci_arch_write_config( int offset, int value );
+
+/*
+u8 pci_read_byte( int where );
+u16 pci_read_word( int where );
+u32 pci_read_dword( int where );
+void pci_arch_write_byte( int where, u8 v8 );
+void pci_arch_write_word(int where, u16 v16);
+void pci_arch_write_dword(int where, u32 v32);
+*/
+
+static int __init pci_arch_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return IRQ_PCIINT;
+    //return IRQ_GP1IRQINT;
+}
+
+static void __init pci_arch_setup_resources(struct resource **resource);
+
+static void pci_arch_init( void * );
+static void pci_arch_reset ( void );
+
+struct hw_pci isl38xx_pci __initdata = {
+	setup_resources:	pci_arch_setup_resources,
+    init:			    pci_arch_init,
+	mem_offset:		    PCIO_BASE,
+	swizzle:		    no_swizzle,
+	map_irq:		    pci_arch_map_irq
+};
+
+static spinlock_t pci_arch_lock = SPIN_LOCK_UNLOCKED;
+
+int pci_arch_master_wait( int size )
+{
+    int timeout = 0x80*size;
+
+    while( !(uPCI->ARMIntReg & PCIARMIntRegMASTERCOMPLETE) )
+    {
+        if( --timeout <= 0 ) {
+            return( -1 );
+        }
+    }
+    return( 0 );
+}
+
+void pci_arch_master_setup( int addr, int size, int mode )
+{
+   uPCI->ARMIntAckReg = PCIARMIntAckRegMASTERCOMPLETE;
+   uPCI->MasHostMemAddr = addr;
+   uPCI->MasLenReg = size;
+   uPCI->MasControlReg = mode;		// ignore length
+}
+
+int pci_arch_read( int offset)
+{
+    int value;
+
+    uPCI->MasOptReg = PCIMasOptRegOPTIONENABLE | PCI_ARCH_MEM_READ;
+    pci_arch_master_setup( offset, 1 , PCIMasControlRegENABLE
+    		             | PCIMasControlRegUSEDATAREG );
+    pci_arch_master_wait( 1 );
+    value = uPCI->MasDataReg;
+    uPCI->MasOptReg = 0;
+
+    return( value );
+}
+
+int pci_arch_write( int offset, int value )
+{
+    uPCI->MasOptReg = PCIMasOptRegOPTIONENABLE | PCI_ARCH_MEM_WRITE;
+    uPCI->MasDataReg = value;
+    pci_arch_master_setup( offset, 1, PCIMasControlRegENABLE
+            | PCIMasControlRegUSEDATAREG | PCIMasControlRegTOHOST );
+    return( pci_arch_master_wait( 1 ) );
+}
+
+int pci_arch_read_config( int offset )
+{
+    int value;
+
+    uPCI->MasOptReg = PCIMasOptRegOPTIONENABLE | PCI_ARCH_CONFIG_READ;
+    pci_arch_master_setup( offset, 1 , PCIMasControlRegENABLE | PCIMasControlRegUSEDATAREG );
+    pci_arch_master_wait( 1 );
+    value = uPCI->MasDataReg;
+    uPCI->MasOptReg = 0;
+
+    return( value );
+}
+
+int pci_arch_write_config( int offset, int value )
+{
+    int error;
+
+    uPCI->MasOptReg  = PCIMasOptRegOPTIONENABLE | PCI_ARCH_CONFIG_WRITE;
+    uPCI->MasDataReg = value;
+    pci_arch_master_setup( offset, 1, PCIMasControlRegENABLE | PCIMasControlRegUSEDATAREG
+                           | PCIMasControlRegTOHOST );
+    error = pci_arch_master_wait( 1 );
+    uPCI->MasOptReg = 0;
+
+    return( error );
+}
+
+/***********************************************************************/
+
+u8 pci_read_byte( int where )
+{
+	unsigned int  offset;
+    unsigned int  align;
+	u32           v32;
+    u8            v8;
+
+    offset = where & (~0x3);
+    align  = where & 0x3;
+
+    v32 = pci_arch_read( offset );
+    v8 = (u8)(v32 >> (8*align)) & 0xFF ;
+
+    DBG( DEBUG_IO, "read_byte : %08x %02x\n", where, v8 );
+
+    return v8;
+}
+
+u16 pci_read_word( int where )
+{
+	unsigned long offset;
+    unsigned int  align;
+	u32           v32;
+    u16           v16;
+
+    offset = where & (~0x3);
+    align  = where & 0x3;
+
+    v32 = pci_arch_read( offset );
+    v16 = (u16)(v32 >> (8*align)) & 0xFFFF ;
+
+    DBG( DEBUG_IO, "read_word : %08x %04x\n", where, v16 );
+
+    return v16;
+}
+
+u32 pci_read_dword( int where )
+{
+	unsigned long offset;
+    unsigned int  align;
+	u32           v32;
+
+    offset = where & (~0x3);
+    align  = where & 0x3;
+
+    v32 = pci_arch_read( offset );
+
+    DBG( DEBUG_IO, "read_dword : %08x %08x\n", where, v32 );
+
+    return v32;
+}
+
+void pci_write_byte( int where, u8 v8 )
+{
+	unsigned long flags;
+	unsigned int  offset;
+    unsigned int  align;
+	u32           v32;
+
+    offset = where & (~0x3);
+    align  = where & 0x3;
+
+	spin_lock_irqsave(&pci_arch_lock, flags);
+
+    v32 = pci_arch_read( offset );
+
+    v32 &= ~(0xFF << (8*align));
+    v32 |= v8 << (8*align);
+
+    pci_arch_write( offset, v32 );
+
+    spin_unlock_irqrestore(&pci_arch_lock, flags);
+
+    DBG( DEBUG_IO, "write_byte : %08x %02x\n", where, v8 );
+}
+
+void pci_write_word(int where, u16 v16)
+{
+	unsigned long flags;
+	unsigned int  offset;
+    unsigned int  align;
+	u32           v32;
+
+    offset = where & (~0x3);
+    align  = where & 0x3;
+
+	spin_lock_irqsave(&pci_arch_lock, flags);
+
+    v32 = pci_arch_read( offset );
+
+    v32 &= ~(0xFFFF << (8*align));
+    v32 |= v16 << (8*align);
+
+    pci_arch_write( offset, v32 );
+
+    spin_unlock_irqrestore(&pci_arch_lock, flags);
+
+    DBG( DEBUG_IO, "write_word : %08x %04x\n", where, v16 );
+}
+
+void pci_write_dword(int where, u32 v32)
+{
+	unsigned long flags;
+	unsigned int  offset;
+    unsigned int  align;
+
+    offset = where & (~0x3);
+    align  = where & 0x3;
+
+	spin_lock_irqsave(&pci_arch_lock, flags);
+
+    pci_arch_write( offset, v32 );
+
+    spin_unlock_irqrestore(&pci_arch_lock, flags);
+
+    DBG( DEBUG_IO, "write_dword : %08x %08x\n", where, v32 );
+}
+
+/***********************************************************************/
+
+int pci_arch_read_config_byte(struct pci_dev *dev, int where, u8 *pv8)
+{
+	unsigned long flags;
+	unsigned int  offset;
+    unsigned int  align;
+	u32           v32;
+
+    if ( dev->devfn != 0 ) { return -1; }
+
+    offset = where & (~0x3);
+    align  = where & 0x3;
+
+	spin_lock_irqsave(&pci_arch_lock, flags);
+
+    v32 = pci_arch_read_config( offset );
+
+    spin_unlock_irqrestore(&pci_arch_lock, flags);
+
+    *pv8 = (u8)(v32 >> (8*align)) & 0xFF ;
+
+    DBG( DEBUG_CONFIG, "read_config_byte : %08x %02x\n", where, *pv8 );
+
+    return PCIBIOS_SUCCESSFUL;
+}
+
+int pci_arch_read_config_word(struct pci_dev *dev, int where, u16 *pv16)
+{
+	unsigned long offset;
+	unsigned long flags;
+    unsigned int  align;
+	u32           v32;
+
+    if ( dev->devfn != 0 ) { return -1; }
+
+    offset = where & (~0x3);
+    align  = where & 0x3;
+
+	spin_lock_irqsave(&pci_arch_lock, flags);
+
+    v32 = pci_arch_read_config( offset );
+
+    spin_unlock_irqrestore(&pci_arch_lock, flags);
+
+    *pv16 = (u16)(v32 >> (8*align)) & 0xFFFF ;
+
+    DBG( DEBUG_CONFIG, "read_config_word : %08x %04x\n", where, *pv16 );
+
+    return PCIBIOS_SUCCESSFUL;
+}
+
+int pci_arch_read_config_dword(struct pci_dev *dev, int where, u32 *pv32)
+{
+	unsigned long offset;
+	unsigned long flags;
+    unsigned int  align;
+
+    if ( dev->devfn != 0 ) { return -1; }
+
+    offset = where & (~0x3);
+    align  = where & 0x3;
+
+	spin_lock_irqsave(&pci_arch_lock, flags);
+
+    *pv32 = pci_arch_read_config( offset );
+
+    spin_unlock_irqrestore(&pci_arch_lock, flags);
+
+    DBG( DEBUG_CONFIG, "read_config_dword : %08x %08x\n", where, *pv32 );
+
+    return PCIBIOS_SUCCESSFUL;
+}
+
+int pci_arch_write_config_byte(struct pci_dev *dev, int where, u8 v8 )
+{
+	unsigned long flags;
+	unsigned int  offset;
+    unsigned int  align;
+	u32           v32;
+
+    if ( dev->devfn != 0 ) { return -1; }
+
+    offset = where & (~0x3);
+    align  = where & 0x3;
+
+	spin_lock_irqsave(&pci_arch_lock, flags);
+
+    v32 = pci_arch_read_config( offset );
+
+    v32 &= ~(0xFF << (8*align));
+    v32 |= v8 << (8*align);
+
+    pci_arch_write_config( offset, v32 );
+
+    spin_unlock_irqrestore(&pci_arch_lock, flags);
+
+    DBG( DEBUG_CONFIG, "write_config_byte : %08x %02x\n", where, v8 );
+
+    return PCIBIOS_SUCCESSFUL;
+}
+
+int pci_arch_write_config_word(struct pci_dev *dev, int where, u16 v16)
+{
+	unsigned long flags;
+	unsigned int  offset;
+    unsigned int  align;
+	u32           v32;
+
+    if ( dev->devfn != 0 ) { return -1; }
+
+    offset = where & (~0x3);
+    align  = where & 0x3;
+    // assert ( align == 0x00 || align == 0x10 );
+
+	spin_lock_irqsave(&pci_arch_lock, flags);
+
+    v32 = pci_arch_read_config( offset );
+
+    v32 &= ~(0xFFFF << (8*align));
+    v32 |= v16 << (8*align);
+
+    pci_arch_write_config( offset, v32 );
+
+    spin_unlock_irqrestore(&pci_arch_lock, flags);
+
+    DBG( DEBUG_CONFIG, "write_config_word : %08x %04x\n", where, v16 );
+
+    return PCIBIOS_SUCCESSFUL;
+}
+
+int pci_arch_write_config_dword(struct pci_dev *dev, int where, u32 v32)
+{
+	unsigned long flags;
+	unsigned int  offset;
+    unsigned int  align;
+
+    if ( dev->devfn != 0 ) { return -1; }
+
+    offset = where & (~0x3);
+    align  = where & 0x3;
+    // assert ( align == 0x00 );
+
+	spin_lock_irqsave(&pci_arch_lock, flags);
+
+    pci_arch_write_config( offset, v32 );
+
+    spin_unlock_irqrestore(&pci_arch_lock, flags);
+
+    DBG( DEBUG_CONFIG, "write_config_dword : %08x %08x\n", where, v32 );
+
+    return PCIBIOS_SUCCESSFUL;
+}
+
+/***********************************************************************/
+
+#if 0
+
+// Target DMA write broken: -during first transfer word 0 is copied in word 9
+//                          -every subsequent transfer first word contains bogus, all word copies are
+//                           shifted by 4, last word not copied
+// Fix: - dummy first copy
+//      - shift down to address one word
+//      - copy one extra word
+
+int pci_arch_block_write ( void *to, void *from, int size )
+{
+    int flags;
+    int words = (size + (WORD_SIZE-1) + ((int) from & (WORD_SIZE-1)) ) >> 2; /* div WORD_SIZE optimized */
+
+    DBG( DEBUG_IO, "pci_arch_dma_write(%p, %p, %d)\n", to, from, size );
+
+    ((int *)to)--; size += WORD_SIZE;
+
+    pci_arch_write( HOST_PCI_BASE + PCIDevStatReg, 0 );
+
+    /*** setup target DMA ***/
+
+    // 2 word FIFO in target PCI controller; program twice to make sure everything reaches the DMA controller
+
+    pci_arch_write( HOST_PCI_BASE + PCIDirectMemBase, HOST_BASE_DMA );
+
+    pci_arch_write( HOST_PCI_BASE + HOST_MEM_OFFSET + HOST_RX_DMA + DMACONTROL, DMACONTROLEnable );
+    pci_arch_write( HOST_PCI_BASE + HOST_MEM_OFFSET + HOST_RX_DMA + DMAMAXCNT,  words << 2 ); /* bytes */
+    pci_arch_write( HOST_PCI_BASE + HOST_MEM_OFFSET + HOST_RX_DMA + DMABASE,    (int)to );
+
+    pci_arch_write( HOST_PCI_BASE + PCIDirectMemBase, HOST_BASE_DMA );
+
+    pci_arch_write( HOST_PCI_BASE + HOST_MEM_OFFSET + HOST_RX_DMA + DMACONTROL, DMACONTROLEnable );
+    pci_arch_write( HOST_PCI_BASE + HOST_MEM_OFFSET + HOST_RX_DMA + DMAMAXCNT,  words << 2 ); /* bytes */
+    pci_arch_write( HOST_PCI_BASE + HOST_MEM_OFFSET + HOST_RX_DMA + DMABASE,    (int)to );
+
+    pci_arch_write( HOST_PCI_BASE + PCIDevStatReg, PCIDevStatRegSetTargetDMA );
+
+    /*** setup my DMA ***/
+    uHostTxDma->CONTROL = DMACONTROLEnable;
+    uHostTxDma->MAXCNT  = words << 2;   /* bytes */
+    uHostTxDma->BASE    = (int) from;
+
+    /*** Load DMA ***/
+    uPCI->MasOptReg      = 0;
+    uPCI->ARMIntAckReg   = PCIARMIntAckRegMASTERCOMPLETE;
+    uPCI->MasHostMemAddr = HOST_PCI_MAP + HOST_MEM_OFFSET;
+    uPCI->MasLenReg      = words;
+    uPCI->MasControlReg  = PCIMasControlRegENABLE | PCIMasControlRegTOHOST;
+
+    while( !(uPCI->ARMIntReg & PCIARMIntRegMASTERCOMPLETE) );
+    //while ( !(uHostTxDma->STATUS & DMASTATUSStallInt) );
+
+    pci_arch_write( HOST_PCI_BASE + PCIDevStatReg, 0 ); // Turn off PCIDevStatRegSetTargetDMA
+    pci_arch_write( HOST_PCI_BASE + PCIDevStatReg, 0 ); // Since the PCI/DMA fsm writes the first
+                                                        // word to the data stream a 2nd write is needed
+    return( (int)from & (WORD_SIZE-1) );
+}
+
+#else
+
+int pci_arch_block_write( void *to, void *from, int size )
+{
+    int offset, *word;
+    int words = (size + (WORD_SIZE-1) + ((int) from & (WORD_SIZE-1)) ) >> 2; /* div WORD_SIZE optimized */
+
+    DBG( DEBUG_IO, "pci_arch_block_write(%p, %p, %d)\n", to, from, size );
+
+    pci_arch_write( HOST_PCI_BASE + PCIDevStatReg, 0 );     // Turn off PCIDevStatRegSetTargetDMA
+                                                            // set the Direct Memory Base Register on the host
+    // 2 word FIFO in target PCI controller; program twice to make sure address reaches the register
+    pci_arch_write( HOST_PCI_BASE + PCIDirectMemBase, (int) to & ~HOST_MEM_MASK );
+    pci_arch_write( HOST_PCI_BASE + PCIDirectMemBase, (int) to & ~HOST_MEM_MASK );
+
+    for( word=(int *)from, offset=((int)to & HOST_MEM_MASK); words > 0; offset=(offset+WORD_SIZE) & HOST_MEM_MASK, word++, words-- )
+    {
+        pci_arch_write( HOST_PCI_BASE + HOST_MEM_OFFSET + offset, *word );
+
+        if( offset == (HOST_MEM_WINDOW-WORD_SIZE) )
+        {
+            pci_arch_write( HOST_PCI_BASE + PCIDirectMemBase, ((int) to + HOST_MEM_WINDOW) & ~HOST_MEM_MASK );
+        }
+    }
+
+    return( (int)from & (WORD_SIZE-1) );
+}
+
+#endif
+
+/***********************************************************************/
+
+static struct resource pci_arch_ioport = {
+	name:	"PCI isl38xx ioport",
+	start:	PCIO_BASE,
+	end:	PCIO_BASE + PCIO_MEM_SIZE,
+	flags:	IORESOURCE_IO,
+};
+
+static struct resource pci_arch_iomem = {
+	name:	"PCI isl38xx iomem",
+	start:	PCIO_MEM,
+	end:	PCIO_MEM + PCIO_MEM_SIZE,
+	flags:	IORESOURCE_MEM,
+};
+
+/***********************************************************************/
+
+static void __init pci_arch_setup_resources(struct resource **resource)
+{
+
+	if (request_resource(&ioport_resource, &pci_arch_ioport))
+		printk("PCI: unable to allocate non-prefetchable io region\n");
+
+	if (request_resource(&iomem_resource, &pci_arch_iomem))
+		printk("PCI: unable to allocate non-prefetchable memory region\n");
+
+    resource[0] = &ioport_resource;         /* the io resource for this bus */
+    resource[1] = &iomem_resource;          /* the mem resource for this bus */
+	resource[2] = NULL;                     /* the prefetch mem resource for this bus */
+}
+
+static struct pci_ops isl38xx_ops = {
+	read_byte:	pci_arch_read_config_byte,
+	read_word:	pci_arch_read_config_word,
+	read_dword:	pci_arch_read_config_dword,
+	write_byte:	pci_arch_write_config_byte,
+	write_word:	pci_arch_write_config_word,
+	write_dword:    pci_arch_write_config_dword,
+};
+
+/***********************************************************************/
+
+static void __init pci_arch_init(void *sysdata)     /* struct pci_sys_data sysdata  */
+{
+	DBG( DEBUG_, "pci_arch_init: %08x\n", (unsigned int)sysdata );
+
+    /* Initialize local controller  */
+
+    uGPIO3->DDR   = gpio_set( 0x80 );
+    uGPIO3->DR    = gpio_set( 0x80 );    /* GP 3_7 de-assert reset */
+
+    //uGPIO1->DDR   = gpio_clr( 0x08 );    /* GP 1_3 input */
+    //uGPIO1->INTCL = gpio_set( 0x08 );    /* GP 1_3 interrupt clear */
+
+    //uGPIO1->EENR  = gpio_set( 0x08 );    /* GP 1_3 interrupt edge triggered */
+    //uGPIO1->SNR   = gpio_set( 0x08 );    /* GP 1_3 trigger on falling edge */
+
+    //uGPIO1->EENR  = gpio_clr( 0x08 );    /* GP 1_3 interrupt level triggered */
+    //uGPIO1->SNR   = gpio_set( 0x08 );    /* GP 1_3 trigger active low */
+
+    //uGPIO1->IRQ   = gpio_set( 0x08 );    /* GP 1_3 interrupt mask */
+
+    DBG( DEBUG_, "pci_arch_init : %08x\n", uGPIO1->IRQ );
+
+    uPCI->ConfigLoadReg = 0x80000000;    /* enable device   */
+
+    uPCI->ARMIntAckReg = PCIARMIntAckRegPCI_FATAL_ERROR;
+    uPCI->ARMIntAckReg = PCIARMIntAckRegPCI_PARITY_ERROR;
+
+    /* set Memory Space / Bus Master bits */
+    pci_arch_write_config( PCI_COMMAND,
+        pci_arch_read_config( PCI_COMMAND ) | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER );
+    pci_arch_write_config( PCI_TRDY_TIMEOUT_VALUE,  0xFF );
+    pci_arch_write_config( PCI_RETRY_TIMEOUT_VALUE, 0xFF );
+    pci_arch_write_config( PCI_BASE_ADDRESS_0, PCIO_BASE ) ; /* set Base Address Register 0 to PCIO_BASE  */
+
+    pci_scan_bus (0, &isl38xx_ops, sysdata);
+}
+
+static void pci_arch_reset ( void )
+{
+    u32 v32;
+
+    v32 = pci_arch_read( PCIO_BASE + PCIDevStatReg );
+	DBG( DEBUG_, "pci_arch_reset(%x)\n", v32 );
+    pci_arch_write( PCIO_BASE + PCIDevStatReg, v32 | PCIDevStatRegSetHostReset );
+    udelay(10);
+    pci_arch_write( PCIO_BASE + PCIDevStatReg, v32 ) ;
+    udelay(50000);
+}
+
+EXPORT_SYMBOL(pci_read_dword);
+EXPORT_SYMBOL(pci_write_dword);
+
+#endif
+
diff -urN linux-2.4.29/arch/armnommu/mach-isl3893/time.c linux-2.4.29-uc1/arch/armnommu/mach-isl3893/time.c
--- linux-2.4.29/arch/armnommu/mach-isl3893/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-isl3893/time.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,23 @@
+/*
+ * time.c  Timer functions for isl3893
+ */
+
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/time.h>
+
+unsigned long isl3893_gettimeoffset (void)
+{
+	// We don't sync our time yet.
+	return(0);
+}
+
+void isl3893_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	if( reset_timer () )
+        	do_timer(regs);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-netarm/irq.c linux-2.4.29-uc1/arch/armnommu/mach-netarm/irq.c
--- linux-2.4.29/arch/armnommu/mach-netarm/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-netarm/irq.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,308 @@
+/*
+ * arch/armnommu/mach-netarm/irq.c:
+ *
+ * NET+ARM  IRQ mask, unmask & init routines.
+ *
+ * (C) 2001 IMMS gGmbH (http://www.imms.de)
+ * author(s): Rolf Peukert (rolf.peukert@imms.de)
+ *
+ * partially based on work by Gordon McNutt and Joe deBlaquiere
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/module.h>	        // EXPORT_SYMBOL
+#include <linux/config.h>
+#include <asm/arch/irq.h>
+#include <asm/arch/netarm_registers.h>
+
+#ifdef CONFIG_SERIAL_NETARM
+
+/* Mask & Acknowledge function for serial channel 1, RX and TX interrupts */
+extern void nas_mask_ack_serial1_irq( unsigned int irq );
+/* dto. for serial channel 2, both defined in drivers/char/serial_netarm.c */
+extern void nas_mask_ack_serial2_irq( unsigned int irq );
+
+#else
+/* minimal Mask & Acknowledge functions */
+void nas_mask_ack_serial1_irq( unsigned int irq )
+{
+	volatile unsigned long int *mask = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_INTR_ENABLE_CLR);
+	volatile unsigned long int *stat_a =
+		(volatile unsigned long *)(NETARM_SER_MODULE_BASE +
+		NETARM_SER_CH1_STATUS_A);
+	
+	if ((irq == IRQ_SER1_TX) || (irq == IRQ_SER1_RX))
+	{
+		*mask  	= (1 << irq);	/* set mask bit */
+		*stat_a	= 0xFFFF;	/* clear all IRQ pending bits */
+	}
+}
+void nas_mask_ack_serial2_irq( unsigned int irq )
+{
+	volatile unsigned long int *mask = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_INTR_ENABLE_CLR);
+	volatile unsigned long int *stat_a =
+		(volatile unsigned long *)(NETARM_SER_MODULE_BASE +
+		NETARM_SER_CH2_STATUS_A);
+
+	if ((irq == IRQ_SER2_TX) || (irq == IRQ_SER2_RX))
+	{
+		*mask  	= (1 << irq);	/* set mask bit */
+		*stat_a	= 0xFFFF;	/* clear all IRQ pending bits */
+	}
+}
+#endif /* if CONFIG_SERIAL_NETARM... */
+
+
+/* Generic Mask IRQ function */
+void netarm_mask_irq(unsigned int irq)
+{
+	volatile unsigned long int *mask = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_INTR_ENABLE_CLR) ;
+	
+	if (32 > irq) *mask = ( 1 << irq );
+}
+
+/* Generic Unmask IRQ function */
+void netarm_unmask_irq(unsigned int irq)
+{
+	volatile unsigned long int *set = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_INTR_ENABLE_SET) ;
+	
+	if (32 > irq) *set = ( 1 << irq );
+}
+
+/* Dummy Mask&Ack function */
+void netarm_mask_ack_irq(unsigned int irq)
+{
+	netarm_mask_irq(irq);
+        /* The NET+ARM doesn't implement a general IRQ status register
+	   like the DSC21 -> we need individual mask_ack_routines */
+}
+
+/* Mask & Acknowledge function for Timer 1 IRQ */
+void netarm_mask_ack_t1_irq(unsigned int irq)
+{
+	volatile unsigned long int *mask = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_INTR_ENABLE_CLR) ;
+	volatile unsigned long int *stat = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_TIMER1_STATUS) ;
+
+	if (irq == IRQ_TIMER1)
+	{
+		*mask = (1 << IRQ_TIMER1);	/* constant, should be calculated at compile time */
+		*stat = NETARM_GEN_TSTAT_INTPEN;/* this clears the IRQ pending bit */
+	}
+}
+
+/* Mask & Acknowledge function for Timer 2 IRQ */
+void netarm_mask_ack_t2_irq(unsigned int irq)
+{
+	volatile unsigned long int *mask = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_INTR_ENABLE_CLR) ;
+	volatile unsigned long int *stat = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_TIMER2_STATUS) ;
+
+	if (irq == IRQ_TIMER2)
+	{
+		*mask = (1 << IRQ_TIMER2);	/* = 0x00000100, bit 4 set */
+		*stat = NETARM_GEN_TSTAT_INTPEN;/* clear IRQ pending bit */
+	}
+}
+
+/* Mask & Acknowledge function for Port C Bit 0..3 IRQs */
+void netarm_mask_ack_portc_irq(unsigned int irq)
+{
+	int 	irq_bit;
+	volatile unsigned long int *mask = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_INTR_ENABLE_CLR) ;
+	volatile unsigned long int *portc = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_PORTC) ;
+
+	if (irq <= IRQ_PORTC3) /* Interrupts 0..3 correspond to Port C bits 0..3 */
+	{
+		irq_bit = 1 << irq;
+		*mask   = irq_bit;		/* set mask bit */
+		*portc  = *portc | irq_bit;	/* acknowledge IRQ */
+	}
+}
+
+/* Mask & Acknowledge function for DMA channel 1 IRQ */
+void netarm_mask_ack_dma1_irq(unsigned int irq)
+{
+	volatile unsigned long int *mask = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_INTR_ENABLE_CLR) ;
+	volatile unsigned long int *dmastata = 
+    get_dma_reg_addr(NETARM_DMA_CHANNEL_1A, NETARM_DMA_STATUS);
+	volatile unsigned long int *dmastatb = 
+    get_dma_reg_addr(NETARM_DMA_CHANNEL_1B, NETARM_DMA_STATUS);
+	volatile unsigned long int *dmastatc = 
+    get_dma_reg_addr(NETARM_DMA_CHANNEL_1C, NETARM_DMA_STATUS);
+	volatile unsigned long int *dmastatd = 
+    get_dma_reg_addr(NETARM_DMA_CHANNEL_1D, NETARM_DMA_STATUS);
+
+	if (IRQ_DMA01 == irq)
+	{
+		*mask   = (1 << IRQ_DMA01);	/* set mask bit */
+		/* A better irq routine should differentiate between the 16 possible
+		   IRQ sources. But for now we just acknowledge all IRQ sources */
+		*dmastata = NETARM_DMA_STATUS_IP_MA;
+		*dmastatb = NETARM_DMA_STATUS_IP_MA;
+		*dmastatc = NETARM_DMA_STATUS_IP_MA;
+		*dmastatd = NETARM_DMA_STATUS_IP_MA;
+	}
+}
+
+/* Mask & Acknowledge function for DMA channels 2..10 IRQs */
+void netarm_mask_ack_dmax_irq(unsigned int irq)
+{
+	int	channel;
+	volatile unsigned long int *mask = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_INTR_ENABLE_CLR) ;
+	volatile unsigned long int *dmastat;
+
+	/* Interrupts 30..22 correspond to DMA channels 2..10
+	   Note the "reverse" numbering scheme (HW Reference 4.4) */
+	if ((IRQ_DMA02 >= irq) && (irq >= IRQ_DMA10))
+	{
+		*mask   = (1 << irq);		/* set mask bit */
+		channel = 32 - irq;		/* DMA channel, 1..10 */
+		dmastat = get_dma_reg_addr(NETARM_DMA_CHANNEL_2 + ((channel - 2) * 0x20), NETARM_DMA_STATUS);
+		/* A better irq routine should differentiate between the four possible
+		   IRQ sources. But as a quick workaround, we acknowledge all sources */
+		*dmastat = NETARM_DMA_STATUS_IP_MA;
+	}
+}
+
+/* setup IRQ descriptor array */
+void irq_init_irq(void)
+{
+	int irq;
+	unsigned long flags;
+	volatile unsigned long int *mask = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_INTR_ENABLE_CLR) ;
+	volatile unsigned long int *set = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_INTR_ENABLE_SET) ;
+	volatile unsigned long int *ie = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_INTR_ENABLE) ;
+
+	for (irq = 0; irq < NR_IRQS; irq++)
+	{
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+
+		switch (irq)
+		{
+			case IRQ_PORTC0:
+			case IRQ_PORTC1:
+			case IRQ_PORTC2:
+			case IRQ_PORTC3:
+					irq_desc[irq].mask_ack = netarm_mask_ack_portc_irq;
+					break;
+			case IRQ_TIMER2:
+					irq_desc[irq].mask_ack = netarm_mask_ack_t2_irq;
+					break;
+			case IRQ_TIMER1:
+					irq_desc[irq].mask_ack = netarm_mask_ack_t1_irq;
+					break;
+			case IRQ_SER1_TX:
+			case IRQ_SER1_RX:
+					irq_desc[irq].mask_ack = nas_mask_ack_serial1_irq;
+					break;			
+			case IRQ_SER2_TX:
+			case IRQ_SER2_RX:
+					irq_desc[irq].mask_ack = nas_mask_ack_serial2_irq;
+					break;			
+			case IRQ_DMA10:
+			case IRQ_DMA09:
+			case IRQ_DMA08:
+			case IRQ_DMA07:
+			case IRQ_DMA06:
+			case IRQ_DMA05:
+			case IRQ_DMA04:
+			case IRQ_DMA03:
+					irq_desc[irq].mask_ack = netarm_mask_ack_dmax_irq;
+					break;
+#ifdef CONFIG_ETHER_NETARM
+			/* The IRQ routines in netarmeth.c do their own acknowledge,
+			   so don't clear the pending bits here */
+			case IRQ_DMA02:
+					irq_desc[irq].mask_ack = netarm_mask_irq;
+					break;
+			case IRQ_DMA01:
+					irq_desc[irq].mask_ack = netarm_mask_irq;
+					break;
+#else
+			/* Use our Mask-Ack functions, just for the case... */
+			case IRQ_DMA02:
+					irq_desc[irq].mask_ack = netarm_mask_ack_dmax_irq;
+					break;
+			case IRQ_DMA01:
+					irq_desc[irq].mask_ack = netarm_mask_ack_dma1_irq;
+					break;
+#endif /* CONFIG_ETHER_NETARM... */
+			default:
+					irq_desc[irq].mask_ack = netarm_mask_ack_irq;
+					break;
+		};
+		irq_desc[irq].mask	= netarm_mask_irq;
+		irq_desc[irq].unmask	= netarm_unmask_irq;
+		irq_desc[irq].action	= NULL;
+	}
+	/* clear all status * disable all */
+	save_flags_cli (flags);
+	*mask = 0xffffffff;
+	*set = 0x5aa55aa5;
+	*set = 0x00000000;
+	if (*ie != 0x5aa55aa5)
+		 _netarm_led_FAIL();
+	*mask = 0xffffffff;		/* clear all interrupt enables */
+	restore_flags (flags);
+}
+
+EXPORT_SYMBOL( netarm_mask_irq );
+EXPORT_SYMBOL( netarm_unmask_irq );
+EXPORT_SYMBOL( netarm_mask_ack_irq );
+EXPORT_SYMBOL( netarm_mask_ack_t1_irq );
+EXPORT_SYMBOL( netarm_mask_ack_t2_irq );
+EXPORT_SYMBOL( netarm_mask_ack_portc_irq );
+EXPORT_SYMBOL( netarm_mask_ack_dma1_irq );
+EXPORT_SYMBOL( netarm_mask_ack_dmax_irq );
+EXPORT_SYMBOL( irq_init_irq );
+
diff -urN linux-2.4.29/arch/armnommu/mach-netarm/Makefile linux-2.4.29-uc1/arch/armnommu/mach-netarm/Makefile
--- linux-2.4.29/arch/armnommu/mach-netarm/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-netarm/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,23 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= netarm.o
+
+# Object file lists.
+
+obj-y			:= $(patsubst %.c, %.o, $(wildcard *.c))
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= irq.o
+
+#obj-$(CONFIG_LEDS)	+= leds.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-netarm/time.c linux-2.4.29-uc1/arch/armnommu/mach-netarm/time.c
--- linux-2.4.29/arch/armnommu/mach-netarm/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-netarm/time.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,60 @@
+/*
+ * time.c  Timer functions for the NET+ARM.
+ *         
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * authors: Gordon McNutt <gmcnutt@ridgerun.com>
+ *          Joe deBlaquiere
+ *          Rolf Peukert
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/netarm_registers.h>
+
+unsigned long netarm_gettimeoffset (void)
+{
+	volatile unsigned int *timer_status = 
+		(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_TIMER2_STATUS) ;
+
+	/* convert milliseconds to microseconds */
+	return  ( NETARM_GEN_TIMER_MSEC_P(*timer_status) * 1000 ) ;
+}
+
+void netarm_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	do_timer(regs);
+
+/* in version 2.0.38:
+	if (reset_timer ())
+		do_timer(regs);
+	update_rtc ();
+*/
+}
+
diff -urN linux-2.4.29/arch/armnommu/mach-p52/arch.c linux-2.4.29-uc1/arch/armnommu/mach-p52/arch.c
--- linux-2.4.29/arch/armnommu/mach-p52/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-p52/arch.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,31 @@
+/*
+ *  linux/arch/arm/mach-p52/arch.c
+ *
+ *  Architecture specific fixups.  This is where any
+ *  parameters in the params struct are fixed up, or
+ *  any additional architecture specific information
+ *  is pulled from the params struct.
+ */
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+
+#include <asm/elf.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+extern void p52_map_io(void);
+extern void p52_init_irq(void);
+extern void genarch_init_irq(void);
+
+
+MACHINE_START(P52, "CNXT P5200")
+       BOOT_MEM(0xabcd1234, 0x56789abc, 0x12345678)
+       MAINTAINER("Mindspeed")
+       INITIRQ(genarch_init_irq)
+MACHINE_END
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-p52/io.S linux-2.4.29-uc1/arch/armnommu/mach-p52/io.S
--- linux-2.4.29/arch/armnommu/mach-p52/io.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-p52/io.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,65 @@
+/*
+ *  linux/arch/arm/mach-ebsa110/io.S
+ *
+ *  Copyright (C) 1995 - 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+		.text
+
+/*
+ * These make no sense on these machines.  Print a warning message.
+ */
+ENTRY(insl)
+		adr	r1, .insl_name
+		b	.warn
+
+ENTRY(outsl)
+		adr	r1, .outsl_name
+.warn:		adr	r0, .io_warning
+		mov	r2, lr
+		b	SYMBOL_NAME(printk)
+
+.insl_name:	.asciz	"insl"
+.insw_name:	.asciz	"insw"
+.outsl_name:	.asciz	"outsl"
+.outsw_name:	.asciz	"outsw"
+.io_warning:	.asciz	"<4>%s: not implemented on this architecture (lr = 0x%p)"
+		.align
+
+@ These are mainly to satisfy the parport code
+
+ENTRY(insb)
+		cmp	r0, #0x00c00000
+		movge	r3, #0
+		movlt	r3, #0xf0000000
+		add	r0, r3, r0, lsl #2
+		b	__arch_readsb
+
+ENTRY(outsb)
+		cmp	r0, #0x00c00000
+		movge	r3, #0
+		movlt	r3, #0xf0000000
+		add	r0, r3, r0, lsl #2
+		b	__arch_writesb
+
+@ And these for the imm/ppa code
+
+ENTRY(insw)
+		cmp	r0, #0x00c00000
+		movge	r3, #0
+		movlt	r3, #0xf0000000
+		add	r0, r3, r0, lsl #2
+		b	__arch_readsw
+
+ENTRY(outsw)
+		cmp	r0, #0x00c00000
+		movge	r3, #0
+		movlt	r3, #0xf0000000
+		add	r0, r3, r0, lsl #2
+		b	__arch_writesw
+
diff -urN linux-2.4.29/arch/armnommu/mach-p52/irq.c linux-2.4.29-uc1/arch/armnommu/mach-p52/irq.c
--- linux-2.4.29/arch/armnommu/mach-p52/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-p52/irq.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,44 @@
+/*
+ *  linux/arch/arm/mach-p52/irq.c
+ *  2001 Mindspeed
+ */
+#include <linux/init.h>
+
+#include <asm/mach/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+ 
+inline void p52_irq_ack(int irq)
+{
+  *((unsigned long *)P52INT_STATUS) |= (1 << irq);
+}
+
+  
+void p52_mask_irq(unsigned int irq)
+{
+  /* reset cooresponding bit in the 32bit Int mask register */ 
+  *((unsigned long *)P52INT_MASK) &= ~(1 << irq);
+}
+
+
+void p52_unmask_irq(unsigned int irq)
+{
+  /* set cooresponding bit in the 32bit Int mask register */ 
+  *((unsigned long *)P52INT_MASK) |= (1 << irq);
+}
+ 
+
+void p52_mask_ack_irq(unsigned int irq)
+{
+  p52_mask_irq(irq);
+  /* this is ok if int source is not hooked on GPIO */
+  *((unsigned long *)P52INT_STATUS) |= (1 << irq);
+}
+
+
+
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-p52/leds.c linux-2.4.29-uc1/arch/armnommu/mach-p52/leds.c
--- linux-2.4.29/arch/armnommu/mach-p52/leds.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-p52/leds.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ *  linux/arch/arm/mach-p52/leds.c
+ *  TBD
+ */
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+static spinlock_t leds_lock;
+
+
+static int __init leds_init(void)
+{
+	return 0;
+}
+
+__initcall(leds_init);
+
+
+
+
+
+
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-p52/Makefile linux-2.4.29-uc1/arch/armnommu/mach-p52/Makefile
--- linux-2.4.29/arch/armnommu/mach-p52/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-p52/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,23 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= p52.o
+
+# Object file lists.
+
+obj-y			:= arch.o  irq.o time.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:=
+
+obj-$(CONFIG_LEDS)	+= leds.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-p52/mm.c linux-2.4.29-uc1/arch/armnommu/mach-p52/mm.c
--- linux-2.4.29/arch/armnommu/mach-p52/mm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-p52/mm.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,41 @@
+/*
+ *  linux/arch/arm/mach-ebsa110/mm.c
+ *
+ *  Copyright (C) 1998-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Extra MM routines for the EBSA-110 architecture
+ */
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+#include <asm/mach/map.h>
+ 
+static struct map_desc p52_io_desc[] __initdata = {
+	/*
+	 * sparse external-decode ISAIO space
+	 */
+	{ IRQ_STAT,    TRICK4_PHYS, PGDIR_SIZE,  DOMAIN_IO, 0, 1, 0, 0 }, /* IRQ_STAT/IRQ_MCLR */
+	{ IRQ_MASK,    TRICK3_PHYS, PGDIR_SIZE,  DOMAIN_IO, 0, 1, 0, 0 }, /* IRQ_MASK/IRQ_MSET */
+	{ SOFT_BASE,   TRICK1_PHYS, PGDIR_SIZE,  DOMAIN_IO, 0, 1, 0, 0 }, /* SOFT_BASE */
+	{ PIT_BASE,    TRICK0_PHYS, PGDIR_SIZE,  DOMAIN_IO, 0, 1, 0, 0 }, /* PIT_BASE */
+
+	/*
+	 * self-decode ISAIO space
+	 */
+	{ ISAIO_BASE,  ISAIO_PHYS,  ISAIO_SIZE,  DOMAIN_IO, 0, 1, 0, 0 },
+	{ ISAMEM_BASE, ISAMEM_PHYS, ISAMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
+	LAST_DESC
+};
+
+void __init p52_map_io(void)
+{
+	iotable_init(p52_io_desc);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-p52/time.c linux-2.4.29-uc1/arch/armnommu/mach-p52/time.c
--- linux-2.4.29/arch/armnommu/mach-p52/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-p52/time.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,40 @@
+/*
+ * time.c  Timer functions for the P52
+ * 2001 Mindspeed
+ */
+
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+extern unsigned long p52_gettimeoffset(void)
+{
+#if 0
+	u16 elapsed;
+
+	/* 
+	 * Compute the elapsed count. The current count tells us how
+	 * many counts remain until the next interrupt. LATCH tells us
+	 * how many counts total occur between interrupts. Subtract to
+	 * get the counts since the last interrupt.
+	 */
+	elapsed = LATCH - inb(P52TIMBase_Addr);
+
+	/* 
+	 * Convert the elapsed count to usecs. I guess there are 'tick' usecs
+	 * between every interrupt. 
+	 */
+	return (unsigned long)((elapsed * tick) / LATCH);
+#endif
+	return (unsigned long)(inl(P52TIMBase_Addr));
+}
+
+void p52_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	do_timer(regs);
+}
+
+
diff -urN linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/arch.c linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/arch.c
--- linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/arch.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ *  uClinux/arch/armnommu/$(MACHINE)/arch.c
+ *
+ *  Architecture specific fixups.  This is where any
+ *  parameters in the params struct are fixed up, or
+ *  any additional architecture specific information
+ *  is pulled from the params struct.
+ */
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+
+#include <asm/elf.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+extern void genarch_init_irq(void);
+
+MACHINE_START(S3C2500REFRGP, "S3C2500-REF-RGP")
+       MAINTAINER("Oleksandr Zhadan")
+       INITIRQ(genarch_init_irq)
+MACHINE_END
+
+
+void	arch_hard_reset ()
+{
+while (1){};
+}
diff -urN linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/config.c linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/config.c
--- linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/config.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,280 @@
+/*
+ *  linux/arch/armnommu/$(MACHINE)/config.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999-2003 D. Jeff Dionne <jeff@uClinux.org>
+ *  Copyright (C) 2001-2003 Arcturus Networks Inc. 
+ *                          by Oleksandr Zhadan <www.ArcturusNetworks.com> 
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <asm/uCbootstrap.h>
+#include <asm/arch/hardware.h>
+
+#undef CONFIG_DEBUG
+
+unsigned char *sn;
+
+#if defined(CONFIG_UCBOOTSTRAP)
+    int	ConTTY = 0;
+    static int errno;
+    _bsc0(char *, getserialnum)
+    _bsc1(unsigned char *, gethwaddr, int, a)
+    _bsc1(char *, getbenv, char *, a)
+#endif
+
+extern unsigned int arm940_get_creg_0(void);
+extern unsigned int arm940_get_creg_1(void);
+extern unsigned int arm940_get_creg_2(unsigned int);
+extern unsigned int arm940_get_creg_3(void);
+extern unsigned int arm940_get_creg_5(unsigned int);
+extern unsigned int arm940_get_creg_6_0(void);
+extern unsigned int arm940_get_creg_6_1(void);
+extern unsigned int arm940_get_creg_6_2(void);
+extern unsigned int arm940_get_creg_6_3(void);
+extern unsigned int arm940_get_creg_6_4(void);
+extern unsigned int arm940_get_creg_6_5(void);
+extern unsigned int arm940_get_creg_6_6(void);
+extern unsigned int arm940_get_creg_6_7(void);
+extern void arm940_uncache_region_4(unsigned int, unsigned int);
+extern void arm940_uncache_region_5(unsigned int, unsigned int);
+extern void arm940_uncache_region_6(unsigned int, unsigned int);
+extern void arm940_uncache_region_7(unsigned int, unsigned int);
+
+unsigned char *get_MAC_address(char *);
+
+unsigned int CPU_CLOCK=0;  		/* CPU clock	*/
+unsigned int SYS_CLOCK=0;  		/* System clock	*/
+unsigned int CONFIG_ARM_CLK=0;
+
+char S3C2500_HWADDR0[]="00:ca:ca:00:00:01";
+char S3C2500_HWADDR1[]="00:ca:ca:00:00:02";
+
+void	get_system_clock(void)
+{
+    unsigned int status = *(unsigned int *)CLKST;
+    unsigned int pll = *(unsigned int *)SYSCFG;
+
+    if	 ( pll & 0x80000000 ) {
+	 CPU_CLOCK = (*(unsigned int *)CPLL & 0xff)+8;
+         switch (status>>30) {
+		case 0:	    SYS_CLOCK = CPU_CLOCK;
+			    break;
+		case 1:
+		case 2:	    SYS_CLOCK = CPU_CLOCK >> 1;
+			    break;
+		case 3:	    SYS_CLOCK = (*(unsigned int *)SPLL & 0xff)+8;
+			    break;
+		}
+	 }
+    else {
+	 pll = (status & 0x00000fff);
+	 CPU_CLOCK += ((pll&0xF00)>>8)*100;
+	 CPU_CLOCK += ((pll&0x0F0)>>4)*10;
+	 CPU_CLOCK += ((pll&0x00F)>>0)*1;
+
+	 switch (status>>30) {
+		case 0:	    SYS_CLOCK = CPU_CLOCK;
+			    break;
+		case 1:
+		case 2:	    SYS_CLOCK = CPU_CLOCK >> 1;
+			    break;
+		case 3:	    pll = ((status & 0x00fff000)>>12);
+			    SYS_CLOCK += ((pll&0xF00)>>8)*100;
+			    SYS_CLOCK += ((pll&0x0F0)>>4)*10;
+			    SYS_CLOCK += ((pll&0x00F)>>0)*1;
+			    break;
+		}
+	}
+
+    CONFIG_ARM_CLK = (SYS_CLOCK*1000000);
+    asm("nop");
+}
+
+void config_BSP()
+{
+#if defined(CONFIG_UCBOOTSTRAP)
+    printk("uCbootloader: Copyright (C) 2001-2003 Arcturus Networks Inc.\n");
+    printk("uCbootloader system calls are initialized.\n");
+#else
+  sn = (unsigned char *)"123456789012345";
+# ifdef	CONFIG_DEBUG
+    printk("Serial number [%s]\n",sn);
+# endif
+#endif
+
+#ifdef CONFIG_UNCACHED_MEM
+    {
+    extern void set_top_uncached_region(void);
+    set_top_uncached_region();
+    }
+#endif
+}
+
+unsigned char *get_MAC_address(char *devname)
+{
+    char *devnum  = devname + (strlen(devname)-1);
+    char varname[sizeof("HWADDR0")];
+    char *varnum  = varname + (strlen(varname)-1);
+    static unsigned char tmphwaddr[6] = {0, 0, 0, 0, 0, 0};
+    char *ret;
+    int	 i;
+
+    strcpy ( varname, "HWADDR" );
+    strcat ( varname, devnum );
+
+#if defined(CONFIG_UCBOOTSTRAP)
+    ret = getbenv(varname);
+#else
+    if	 ( !strcmp(varname, "HWADDR0") )
+	 ret = (char *)S3C2500_HWADDR0;
+    else ret = (char *)S3C2500_HWADDR1;
+#endif    
+    memset(tmphwaddr, 0, 6);
+    if	(ret && strlen(ret) == 17)
+	for (i=0; i<6; i++) {
+	    ret[(i+1) * 3 - 1] = 0;
+	    tmphwaddr[i] = simple_strtoul(ret + i*3, 0, 16); 
+	    }
+    return(tmphwaddr);
+}
+
+unsigned int reg_map[8] = { 1, 1, 1, 1, 0, 0, 0, 0 };
+
+int	ask_s3c2500_uncache_region( void *addr, unsigned int size, unsigned int flag)
+{
+    static unsigned int reg_map[8] = { 1, 1, 1, 1, 0, 0, 0, 0 };
+    unsigned int i, j, n;
+    unsigned int baseandsize=0;
+    
+    if	((unsigned int)addr & (size-1))
+	return	-1;				/* addr is not alligned */
+	
+    for ( n = 4; n < 8; n++ )
+	if  ( !reg_map[n] ) {
+	    for	( i = 11, j=0x1000; i < 31; i++, j<<=1 )
+		if  ( j == size ) {
+		    baseandsize = (i << 1);		/* Area size	 */
+		    baseandsize |= ((unsigned int)addr);/* Base address  */
+		    baseandsize |= 1;			/* Enable region */
+		    switch ( n ) {
+			    case 4 :	arm940_uncache_region_4(baseandsize, flag);
+					break;
+			    case 5 :	arm940_uncache_region_5(baseandsize, flag);
+					break;
+			    case 6 :	arm940_uncache_region_6(baseandsize, flag);
+					break;
+			    case 7 :	arm940_uncache_region_7(baseandsize, flag);
+					break;
+			    default :	return -1;
+			    }
+		    reg_map[n] = 1;
+		    return 0;
+		    }
+	    return -2;	/* Size is not correct */
+	    }
+    return -3;		/* No free region found */
+}
+
+#ifdef CONFIG_UNCACHED_MEM
+
+void	set_top_uncached_region()
+{
+#ifdef CONFIG_UNCACHED_256
+unsigned int val = 0x23 | (END_MEM-0x40000);
+#endif
+
+#ifdef CONFIG_UNCACHED_512
+unsigned int val = 0x25 | (END_MEM-0x80000);
+#endif
+
+#ifdef CONFIG_UNCACHED_1024
+unsigned int val = 0x27 | (END_MEM-0x100000);
+#endif
+
+#ifdef CONFIG_UNCACHED_2048
+unsigned int val = 0x29 | (END_MEM-0x200000);
+#endif
+
+#ifdef CONFIG_UNCACHED_4096
+unsigned int val = 0x2B | (END_MEM-0x400000);
+#endif
+
+#ifdef CONFIG_UNCACHED_8192
+unsigned int val = 0x2D | (END_MEM-0x800000);
+#endif
+
+    arm940_uncache_region_7(val, 0);
+    reg_map[7] = 1;
+}
+
+#endif	/* CONFIG_UNCACHED_MEM */
+
+
+void crinfo(void)
+{
+    unsigned int tmp, size, i;
+    printk("\nCoprocessor register info:\n");
+    
+    tmp = arm940_get_creg_0();
+    printk("ID code                  : %8x\n", tmp);
+    
+    tmp = arm940_get_creg_1();
+    printk("Control register         : %8x\n", tmp);
+
+    tmp = arm940_get_creg_2(0);
+    printk("Data cacheable register  : %8x\n", tmp);
+
+    tmp = arm940_get_creg_2(1);
+    printk("Inst cacheable register  : %8x\n", tmp);
+
+    tmp = arm940_get_creg_3();
+    printk("Write buffer register    : %8x\n", tmp);
+
+    tmp = arm940_get_creg_5(0);
+    printk("Data access register     : %8x\n", tmp);
+
+    tmp = arm940_get_creg_5(1);
+    printk("Inst access register     : %8x\n", tmp);
+
+    for	(i=0; i < 8; i++ ) {
+	switch (i) {
+	    case 0 :	tmp = arm940_get_creg_6_0();	break;
+	    case 1 :	tmp = arm940_get_creg_6_1();	break;
+	    case 2 :	tmp = arm940_get_creg_6_2();	break;
+	    case 3 :	tmp = arm940_get_creg_6_3();	break;
+	    case 4 :	tmp = arm940_get_creg_6_4();	break;
+	    case 5 :	tmp = arm940_get_creg_6_5();	break;
+	    case 6 :	tmp = arm940_get_creg_6_6();	break;
+	    case 7 :	tmp = arm940_get_creg_6_7();	break;
+	    }
+	printk("Region%d: addr=%8x, ", i, (tmp & 0xfffff000));
+	size = tmp>>1;
+	size &= 0x1f;
+	size -= 0xb;
+	printk("size=%dK, ", (0x4<<size));
+	if 	( tmp & 1 )	printk("enabled\n");
+	else			printk("disabled\n");
+	}
+}
+
+EXPORT_SYMBOL(ask_s3c2500_uncache_region);
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff -urN linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/dma.c linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/dma.c
--- linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/dma.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ *  uClinux/arch/armnommu/$(MACHINE)/dma.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/sched.h>
+#include <linux/malloc.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach/dma.h>
+
+void arch_dma_init(dma_t *dma)
+{
+}
diff -urN linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/io.c linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/io.c
--- linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/io.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/io.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,31 @@
+/*
+ * uClinux/arch/armnommu/$(MACHINE)/io.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *   io functions
+ *
+ * Copyright (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * Author: RidgeRun, Inc.
+ *         Greg Lonnon (glonnon@ridgerun.com) or info@ridgerun.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
diff -urN linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/irq.c linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/irq.c
--- linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/irq.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,68 @@
+/*
+ * uClinux/arch/armnommu/$(MACHINE)/irq.c 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc. 
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ */
+
+#include <linux/init.h>
+
+#include <asm/mach/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+void __inline__ s3c2500_mask_irq(unsigned int irq)
+{
+    unsigned long mask;
+
+    if	 ( irq >= NR_EXT_IRQS ) {
+	 mask = inl(INTMASK);
+	 mask |= ( 1 << (irq - NR_EXT_IRQS));
+	 outl(mask, INTMASK);
+	 } 
+    else {
+	 mask = inl(EXTMASK);
+	 mask |= ( 1 << irq);
+	 outl(mask, EXTMASK);
+	} 
+}	
+
+void __inline__ s3c2500_unmask_irq(unsigned int irq)
+{
+    unsigned long mask;
+
+    if	 ( irq >= NR_EXT_IRQS ) {
+	 mask = inl(INTMASK);
+	 mask &= ~( 1 << (irq - NR_EXT_IRQS));
+	 outl(mask, INTMASK);
+	 } 
+    else {
+	 mask = inl(EXTMASK);
+	 mask &= ~( 1 << irq);
+	 outl(mask, EXTMASK);
+	} 
+}
+
+void __inline__ s3c2500_mask_global(void)
+{
+    unsigned long mask;
+    mask = inl(EXTMASK);
+    mask |= MASK_IRQ_GLOBAL;
+    outl(mask, EXTMASK);
+}
+
+void __inline__ s3c2500_unmask_global(void)
+{
+    unsigned long mask;
+    mask = inl(EXTMASK);
+    mask &= ~(MASK_IRQ_GLOBAL);
+    outl(mask, EXTMASK);
+}
+
+void __inline__ s3c2500_mask_ack_irq(unsigned int irq)
+{
+    s3c2500_mask_irq (irq);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/Makefile linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/Makefile
--- linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= S3C2500REFRGP.o
+
+# Object file lists.
+
+obj-y			:= $(patsubst %.c, %.o, $(wildcard *.c))
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= 
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/ramlinux.lds linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/ramlinux.lds
--- linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/ramlinux.lds	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/ramlinux.lds	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,125 @@
+/* ld script to make ARM Linux kernel
+ * taken from the i386 version by Russell King
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ * Additional changes:
+ *  Copyright (c) 2002 Arcturus Networks Inc.
+ *                     by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ */
+INCLUDE arch/armnommu/mach-S3C2500REFRGP/romfs.ld 
+OUTPUT_ARCH(arm)
+ENTRY(stext)
+SECTIONS
+{
+
+	. = 0x20000;
+	.init : {			/* Init code and data		*/
+		_stext = .;
+		__init_begin = .;
+			*(.text.init)
+		__proc_info_begin = .;
+			*(.proc.info)
+		__proc_info_end = .;
+		__arch_info_begin = .;
+			*(.arch.info)
+		__arch_info_end = .;
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		__initcall_end = .;
+		. = ALIGN(4096);
+		__init_end = .;
+	}
+
+	/DISCARD/ : {			/* Exit code and data		*/
+		*(.text.exit)
+		*(.data.exit)
+		*(.exitcall.exit)
+	}
+
+	.text : {			/* Real text segment		*/
+		_text = .;		/* Text and read-only data	*/
+			*(.text)
+			*(.fixup)
+			*(.gnu.warning)
+			*(.text.lock)	/* out-of-line lock text */
+			*(.rodata)
+			*(.glue_7)
+			*(.glue_7t)
+			*(.kstrtab)
+		. = ALIGN(16);
+		__start___ex_table = .;	/* Exception table		*/
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;	/* Kernel symbol table		*/
+			*(__ksymtab)
+		__stop___ksymtab = .;
+
+		__start___kallsyms = .; /* All kernel symbols           */
+			*(__kallsyms)
+		__stop___kallsyms = .;
+
+
+		*(.got)			/* Global offset table		*/
+
+		_etext = .;		/* End of text section		*/
+	}
+
+	. = ALIGN(8192);
+
+	__data_start = .;
+	__data_rom_start = .;
+	.data : {
+		/*
+		 * first, the init task union, aligned
+		 * to an 8192 byte boundary.
+		 */
+		*(.init.task)
+
+		/*
+		 * then the cacheline aligned data
+		 */
+		. = ALIGN(32);
+		*(.data.cacheline_aligned)
+
+		/*
+		 * and the usual data section
+		 */
+		*(.data)
+		CONSTRUCTORS
+
+		. = ALIGN(32);	/* To be sure to align .fs . OZH */
+		_edata = .;
+		
+	}
+
+	.fs :	{
+		_romfs = ABSOLUTE (.);
+		. = . + romfs_size;
+		_end_romfs = ABSOLUTE (.);
+		}
+
+	.bss : {
+		__bss_start = .;	/* BSS				*/
+		*(.bss)
+		*(COMMON)
+		__bss_end = .;
+		_end = . ;
+	}
+
+	. = ALIGN(8192);
+	_end_kernel = . ;
+
+					/* Stabs debugging sections.	*/
+	.stab 0 : { *(.stab) }
+	.stabstr 0 : { *(.stabstr) }
+	.stab.excl 0 : { *(.stab.excl) }
+	.stab.exclstr 0 : { *(.stab.exclstr) }
+	.stab.index 0 : { *(.stab.index) }
+	.stab.indexstr 0 : { *(.stab.indexstr) }
+	.comment 0 : { *(.comment) }
+}
diff -urN linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/romfs.ld linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/romfs.ld
--- linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/romfs.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/romfs.ld	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1 @@
+romfs_size =  534528;
diff -urN linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/romlinux.lds linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/romlinux.lds
--- linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/romlinux.lds	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/romlinux.lds	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,141 @@
+/* ld script to make ARM Linux kernel
+ * taken from the i386 version by Russell King
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *
+ * Additional changes: 
+ *  Copyright (C) 2001-2003 Arcturus Networks Inc.
+ *                          by O.Zhadan <www.ArcturusNetworks.com>
+ */
+
+MEMORY
+{
+    ram : ORIGIN = 0x20000, LENGTH = 0x7debfc
+    rom : ORIGIN = 0x1020000, LENGTH = 0x1dfffc
+}
+
+INCLUDE arch/armnommu/mach-S3C2500REFRGP/romfs.ld
+OUTPUT_ARCH(arm)
+ENTRY(stext)
+SECTIONS
+{
+	.text 0x1020000 :
+	{			/* Real text segment		*/
+		_text = .;		/* Text and read-only data	*/
+		_stext = .;
+			*(.text.init)
+			*(.text)
+			*(.fixup)
+			*(.gnu.warning)
+			*(.text.lock)	/* out-of-line lock text */
+			*(.rodata)
+			*(.glue_7)
+			*(.glue_7t)
+			*(.kstrtab)
+		. = ALIGN(16);
+		__start___ex_table = .;	/* Exception table		*/
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;	/* Kernel symbol table		*/
+			*(__ksymtab)
+		__stop___ksymtab = .;
+
+		__start___kallsyms = .; /* All kernel symbols           */
+			*(__kallsyms)
+		__stop___kallsyms = .;
+
+
+		*(.got)			/* Global offset table		*/
+
+		_etext = .;		/* End of text section		*/
+		
+		. = ALIGN(32);
+	} > rom
+
+	.fs :	
+	{
+		_romfs = ABSOLUTE (.);
+		. = . + romfs_size;
+		_end_romfs = ABSOLUTE (.);
+	} > rom
+
+	
+	.init 0x20000 :
+	AT ( _end_romfs )
+	{			/* Init code and data		*/
+		
+		__init_begin = ABSOLUTE(.);
+		__proc_info_begin = ABSOLUTE(.);
+			*(.proc.info)
+		PROVIDE(__proc_info_end = .);
+		__arch_info_begin = ABSOLUTE(.);
+			*(.arch.info)
+		PROVIDE(__arch_info_end = .);
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = ABSOLUTE(.);
+			*(.setup.init)
+		PROVIDE(__setup_end = .);
+		__initcall_start = ABSOLUTE(.);
+			*(.initcall.init)
+		PROVIDE(__initcall_end = .);
+		. = ALIGN(4096);
+		PROVIDE(__init_end = .);
+	} > ram
+
+	/DISCARD/ : 
+	{			/* Exit code and data		*/
+		*(.text.exit)
+		*(.data.exit)
+		*(.exitcall.exit)
+	} > ram
+
+	
+	.data : 
+	AT ( _end_romfs + SIZEOF (.init))
+	{
+		. = ALIGN(8192);
+		__data_start = ABSOLUTE(.);
+		__data_rom_start = ABSOLUTE(.);
+		/*
+		 * first, the init task union, aligned
+		 * to an 8192 byte boundary.
+		 */
+		*(.init.task)
+
+		/*
+		 * then the cacheline aligned data
+		 */
+		. = ALIGN(32);
+		*(.data.cacheline_aligned)
+
+		/*
+		 * and the usual data section
+		 */
+		*(.data)
+		CONSTRUCTORS
+
+		PROVIDE(_edata = .);
+		
+	} > ram
+
+	.bss : {
+		__bss_start = ABSOLUTE(.);	/* BSS				*/
+		PROVIDE(bss_start = .);
+		*(.bss)
+		*(COMMON)
+		PROVIDE(_end = .);
+		__bss_end = ABSOLUTE(.);
+		. = ALIGN(8192);
+		PROVIDE(_end_kernel = .);
+	} > ram
+
+					/* Stabs debugging sections.	*/
+	.stab 0 : { *(.stab) }
+	.stabstr 0 : { *(.stabstr) }
+	.stab.excl 0 : { *(.stab.excl) }
+	.stab.exclstr 0 : { *(.stab.exclstr) }
+	.stab.index 0 : { *(.stab.index) }
+	.stab.indexstr 0 : { *(.stab.indexstr) }
+	.comment 0 : { *(.comment) }
+}
diff -urN linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/time.c linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/time.c
--- linux-2.4.29/arch/armnommu/mach-S3C2500REFRGP/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C2500REFRGP/time.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,39 @@
+/* 
+ * time.c Timer functions for S3C2500
+ *
+ * Copyright (C) 2002 Arcturus Networks Inc.
+ *                    by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ */
+
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+#define HZMSEC	10000	/* (HZ*100) */
+
+unsigned long s3c2500_gettimeoffset (void)
+{
+    struct s3c2500_timer *tt = (struct s3c2500_timer *) (TIMER_BASE);
+    return ((tt->td[2*KERNEL_TIMER] - tt->td[2*KERNEL_TIMER+1]) / (tt->td[2*KERNEL_TIMER]/HZMSEC));
+}
+
+void s3c2500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+    static int mS;
+    static int led;
+    if  (mS++ > 49) {
+	led = Vol32(0xf003001c);
+	if   ( led & 0x08000000 )
+	     Vol32(0xf003001c) = led & 0xf7ffffff;
+	else
+	     Vol32(0xf003001c) = led | 0x08000000;
+	mS = 0;
+	}
+
+    REG_WRITE(IC, (1<<(irq-31)));
+    do_timer(regs);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-S3C3410/arch.c linux-2.4.29-uc1/arch/armnommu/mach-S3C3410/arch.c
--- linux-2.4.29/arch/armnommu/mach-S3C3410/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C3410/arch.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ *  uClinux/arch/arm/mach/arch.c
+ *
+ *  Architecture specific fixups.  This is where any
+ *  parameters in the params struct are fixed up, or
+ *  any additional architecture specific information
+ *  is pulled from the params struct.
+ */
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+
+#include <asm/elf.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+extern void genarch_init_irq(void);
+
+MACHINE_START(S3C3410, "S3C3410")
+       MAINTAINER("Thomas Eschenbacher")
+       INITIRQ(genarch_init_irq)
+MACHINE_END
+
+void arch_hard_reset(void)
+{
+	/*
+	 * @todo activate the hardware reset
+	 */
+	while (1){};
+}
diff -urN linux-2.4.29/arch/armnommu/mach-S3C3410/dma.c linux-2.4.29-uc1/arch/armnommu/mach-S3C3410/dma.c
--- linux-2.4.29/arch/armnommu/mach-S3C3410/dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C3410/dma.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,29 @@
+/*
+ *  uClinux/arch/arm/mach/dma.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/page.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <asm/mach/dma.h>
+
+void arch_dma_init(dma_t *dma)
+{
+}
diff -urN linux-2.4.29/arch/armnommu/mach-S3C3410/irq.c linux-2.4.29-uc1/arch/armnommu/mach-S3C3410/irq.c
--- linux-2.4.29/arch/armnommu/mach-S3C3410/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C3410/irq.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ * linux/arch/armnommu/mach-S3C3410/irq.c
+ *
+ * 2003, Thomas Eschenbacher <thomas.eschenbacher@gmx.de>
+ *
+ * S3C3410X interrupt flag and mask handling
+ *
+ */
+ 
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+void __inline__ s3c3410_mask_irq(unsigned int irq)
+{
+	outl( inl(S3C3410X_INTMSK) & ~( 1 << irq ), S3C3410X_INTMSK);
+}
+
+void __inline__ s3c3410_unmask_irq(unsigned int irq)
+{
+	outl( inl(S3C3410X_INTMSK) | ( 1 << irq ), S3C3410X_INTMSK);
+}
+
+/* Clear pending bit */
+void __inline__ s3c3410_clear_pb(unsigned int irq)
+{
+	outl( ~(1 << irq), S3C3410X_INTPND);
+}
+
+void __inline__ s3c3410_mask_ack_irq(unsigned int irq)
+{
+	s3c3410_mask_irq(irq);
+	s3c3410_clear_pb(irq);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-S3C3410/Makefile linux-2.4.29-uc1/arch/armnommu/mach-S3C3410/Makefile
--- linux-2.4.29/arch/armnommu/mach-S3C3410/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C3410/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= S3C3410.o
+
+# Object file lists.
+
+obj-y			:= $(patsubst %.c, %.o, $(wildcard *.c))
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= 
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-S3C3410/time.c linux-2.4.29-uc1/arch/armnommu/mach-S3C3410/time.c
--- linux-2.4.29/arch/armnommu/mach-S3C3410/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C3410/time.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/armnommu/mach-S3C3410/time.c
+ *
+ * 2003, Thomas Eschenbacher <thomas.eschenbacher@gmx.de>
+ *
+ * S3C3410X timer interrupt handler and gettimeoffset
+ *
+ */
+
+#include <linux/time.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+#define CLOCKS_PER_USEC	(CONFIG_ARM_CLK/1000000)
+
+#if ((CLOCKS_PER_USEC*1000000) != CONFIG_ARM_CLK)
+#warning "clock rate is not in whole MHz, gettimeoffset will give wrong results"
+#endif
+
+unsigned long s3c3410_gettimeoffset (void)
+{
+	return (inw(S3C3410X_TCNT0) / CLOCKS_PER_USEC);
+}
+
+void s3c3410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	do_timer(regs);
+}
+
diff -urN linux-2.4.29/arch/armnommu/mach-S3C44B0X/arch.c linux-2.4.29-uc1/arch/armnommu/mach-S3C44B0X/arch.c
--- linux-2.4.29/arch/armnommu/mach-S3C44B0X/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C44B0X/arch.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ *  linux/arch/armnommu/mach-S3C44B0X/arch.c
+ *
+ *  Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ *  Architecture specific fixups.  This is where any
+ *  parameters in the params struct are fixed up, or
+ *  any additional architecture specific information
+ *  is pulled from the params struct.
+ */
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+
+#include <asm/elf.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+extern void genarch_init_irq(void);
+
+MACHINE_START(S3C44B0X, "S3C44B0X")
+       MAINTAINER("Thomas Eschenbacher")
+       INITIRQ(genarch_init_irq)
+MACHINE_END
+
+
+void arch_hard_reset(void)
+{
+	/*
+	 * @todo activate the hardware reset
+	 */
diff -urN linux-2.4.29/arch/armnommu/mach-S3C44B0X/dma.c linux-2.4.29-uc1/arch/armnommu/mach-S3C44B0X/dma.c
--- linux-2.4.29/arch/armnommu/mach-S3C44B0X/dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C44B0X/dma.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,29 @@
+/*
+ *  uClinux/arch/arm/mach/dma.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/page.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <asm/mach/dma.h>
+
+void arch_dma_init(dma_t *dma)
+{
+}
diff -urN linux-2.4.29/arch/armnommu/mach-S3C44B0X/irq.c linux-2.4.29-uc1/arch/armnommu/mach-S3C44B0X/irq.c
--- linux-2.4.29/arch/armnommu/mach-S3C44B0X/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C44B0X/irq.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ * linux/arch/armnommu/mach-S3C44B0X/irq.c
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@gmx.de>
+ *
+ * S3C44B0X interrupt flag and mask handling
+ *
+ */
+ 
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+void __inline__ s3c44b0x_mask_irq(unsigned int irq)
+{
+	outl( inl(S3C44B0X_INTMSK) | ( 1 << irq ), S3C44B0X_INTMSK);
+}
+
+void __inline__ s3c44b0x_unmask_irq(unsigned int irq)
+{
+	outl( inl(S3C44B0X_INTMSK) & ~( 1 << irq ), S3C44B0X_INTMSK);
+}
+
+/* Clear pending bit */
+void __inline__ s3c44b0x_clear_pb(unsigned int irq)
+{
+	outl( (1 << irq), S3C44B0X_I_ISPC);
+}
+
+void __inline__ s3c44b0x_mask_ack_irq(unsigned int irq)
+{
+	s3c44b0x_mask_irq(irq);
+	s3c44b0x_clear_pb(irq);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-S3C44B0X/Makefile linux-2.4.29-uc1/arch/armnommu/mach-S3C44B0X/Makefile
--- linux-2.4.29/arch/armnommu/mach-S3C44B0X/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C44B0X/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,23 @@
+#
+# Makefile for the linux kernel.
+#
+# Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= S3C44B0X.o
+
+# Object file lists.
+
+obj-y			:= $(patsubst %.c, %.o, $(wildcard *.c))
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= 
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-S3C44B0X/time.c linux-2.4.29-uc1/arch/armnommu/mach-S3C44B0X/time.c
--- linux-2.4.29/arch/armnommu/mach-S3C44B0X/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-S3C44B0X/time.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/armnommu/mach-S3C44B0X/time.c
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ * S3C44B0X timer interrupt handler and gettimeoffset
+ *
+ */
+
+#include <linux/time.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+#define CLOCKS_PER_USEC	(CONFIG_ARM_CLK/1000000)
+
+#if ((CLOCKS_PER_USEC*1000000) != CONFIG_ARM_CLK)
+#warning "clock rate is not in whole MHz, gettimeoffset will give wrong results"
+#endif
+
+unsigned long s3c44b0x_gettimeoffset (void)
+{
+	return (inw(S3C44B0X_TCNTB5) / CLOCKS_PER_USEC);
+}
+
+void s3c44b0x_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	do_timer(regs);
+}
+
diff -urN linux-2.4.29/arch/armnommu/mach-SMDK2500/arch.c linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/arch.c
--- linux-2.4.29/arch/armnommu/mach-SMDK2500/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/arch.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ *  uClinux/arch/arm/mach/arch.c
+ *
+ *  Architecture specific fixups.  This is where any
+ *  parameters in the params struct are fixed up, or
+ *  any additional architecture specific information
+ *  is pulled from the params struct.
+ */
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+
+#include <asm/elf.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+extern void genarch_init_irq(void);
+
+MACHINE_START(SMDK2500, "SMDK2500-AN")
+	MAINTAINER("Oleksandr Zhadan")
+	BOOT_PARAMS(0x00000100)
+	INITIRQ(genarch_init_irq)
+	SOFT_REBOOT
+MACHINE_END
+
+
+void	arch_hard_reset ()
+{
+while (1){};
+}
diff -urN linux-2.4.29/arch/armnommu/mach-SMDK2500/config.c linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/config.c
--- linux-2.4.29/arch/armnommu/mach-SMDK2500/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/config.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,313 @@
+/*
+ *  linux/arch/armnommu/$(MACHINE)/config.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999-2003 D. Jeff Dionne <jeff@uClinux.org>
+ *  Copyright (C) 2001-2003 Arcturus Networks Inc.
+ *                          by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <asm/uCbootstrap.h>
+#include <asm/arch/hardware.h>
+
+#include <asm/elf.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#undef CONFIG_DEBUG
+
+unsigned char *sn;
+
+#if defined(CONFIG_UCBOOTSTRAP)
+    int	ConTTY = 0;
+    static int errno;
+    _bsc0(char *, getserialnum)
+    _bsc1(unsigned char *, gethwaddr, int, a)
+    _bsc1(char *, getbenv, char *, a)
+#endif
+
+extern unsigned int arm940_get_creg_0(void);
+extern unsigned int arm940_get_creg_1(void);
+extern unsigned int arm940_get_creg_2(unsigned int);
+extern unsigned int arm940_get_creg_3(void);
+extern unsigned int arm940_get_creg_5(unsigned int);
+extern unsigned int arm940_get_creg_6_0(void);
+extern unsigned int arm940_get_creg_6_1(void);
+extern unsigned int arm940_get_creg_6_2(void);
+extern unsigned int arm940_get_creg_6_3(void);
+extern unsigned int arm940_get_creg_6_4(void);
+extern unsigned int arm940_get_creg_6_5(void);
+extern unsigned int arm940_get_creg_6_6(void);
+extern unsigned int arm940_get_creg_6_7(void);
+extern void arm940_uncache_region_4(unsigned int, unsigned int);
+extern void arm940_uncache_region_5(unsigned int, unsigned int);
+extern void arm940_uncache_region_6(unsigned int, unsigned int);
+extern void arm940_uncache_region_7(unsigned int, unsigned int);
+
+unsigned char *get_MAC_address(char *);
+
+unsigned int CPU_CLOCK=0;  		/* CPU clock	*/
+unsigned int SYS_CLOCK=0;  		/* System clock	*/
+unsigned int CONFIG_ARM_CLK=0;
+
+char S3C2500_HWADDR0[]="00:ca:ca:00:00:01";
+char S3C2500_HWADDR1[]="00:ca:ca:00:00:02";
+
+void	get_system_clock(void)
+{
+    unsigned int status = *(unsigned int *)CLKST;
+    unsigned int pll = *(unsigned int *)SYSCFG;
+
+    if	 ( pll & 0x80000000 ) {
+	 CPU_CLOCK = (*(unsigned int *)CPLL & 0xff)+8;
+         switch (status>>30) {
+		case 0:	    SYS_CLOCK = CPU_CLOCK;
+			    break;
+		case 1:
+		case 2:	    SYS_CLOCK = CPU_CLOCK >> 1;
+			    break;
+		case 3:	    SYS_CLOCK = (*(unsigned int *)SPLL & 0xff)+8;
+			    break;
+		}
+	 }
+    else {
+	 pll = (status & 0x00000fff);
+	 CPU_CLOCK += ((pll&0xF00)>>8)*100;
+	 CPU_CLOCK += ((pll&0x0F0)>>4)*10;
+	 CPU_CLOCK += ((pll&0x00F)>>0)*1;
+
+	 switch (status>>30) {
+		case 0:	    SYS_CLOCK = CPU_CLOCK;
+			    break;
+		case 1:
+		case 2:	    SYS_CLOCK = CPU_CLOCK >> 1;
+			    break;
+		case 3:	    pll = ((status & 0x00fff000)>>12);
+			    SYS_CLOCK += ((pll&0xF00)>>8)*100;
+			    SYS_CLOCK += ((pll&0x0F0)>>4)*10;
+			    SYS_CLOCK += ((pll&0x00F)>>0)*1;
+			    break;
+		}
+	}
+
+    CONFIG_ARM_CLK = (SYS_CLOCK*1000000);
+    asm("nop");
+}
+
+void config_BSP()
+{
+#if defined(CONFIG_UCBOOTSTRAP)
+    printk("uCbootloader: Copyright (C) 2001-2003 Arcturus Networks Inc.\n");
+    printk("uCbootloader system calls are initialized.\n");
+#else
+  sn = (unsigned char *)"123456789012345";
+# ifdef	CONFIG_DEBUG
+    printk("Serial number [%s]\n",sn);
+# endif
+#endif
+
+#ifdef CONFIG_UNCACHED_MEM
+    {
+    extern void set_top_uncached_region(void);
+    set_top_uncached_region();
+    }
+#endif
+}
+
+#define ATAG_HWADDR (ATAG_CORE+50) /* FIXME: Unreserved */
+
+struct atag_hwaddr {
+	char	name[10];       /* device name (ie: eth0) */
+	char	hwaddr[6];
+};
+
+static int __init parse_tag_hwaddr(const struct tag *tag)
+{
+	char *dest;
+	int i;
+	struct atag_hwaddr *hwaddr = (struct atag_hwaddr *) &tag->u.core;
+
+	if (!strcmp("eth0", hwaddr->name))
+		dest = S3C2500_HWADDR0;
+	else if (!strcmp("eth1", hwaddr->name))
+		dest = S3C2500_HWADDR1;
+	else return 0;
+
+	for (i = 0; i < 5; i++)
+		dest += sprintf(dest, "%02x:", hwaddr->hwaddr[i]);
+	sprintf(dest, "%02x", hwaddr->hwaddr[i]);
+
+	return 0;
+}
+
+__tagtable(ATAG_HWADDR, parse_tag_hwaddr);
+
+unsigned char *get_MAC_address(char *devname)
+{
+    char *devnum  = devname + (strlen(devname)-1);
+    char varname[sizeof("HWADDR0")];
+    char *varnum  = varname + (strlen(varname)-1);
+    static unsigned char tmphwaddr[6] = {0, 0, 0, 0, 0, 0};
+    char *ret;
+    int	 i;
+
+    strcpy ( varname, "HWADDR" );
+    strcat ( varname, devnum );
+
+#if defined(CONFIG_UCBOOTSTRAP)
+    ret = getbenv(varname);
+#else
+    if	 ( !strcmp(varname, "HWADDR0") )
+	 ret = (char *)S3C2500_HWADDR0;
+    else ret = (char *)S3C2500_HWADDR1;
+#endif    
+    memset(tmphwaddr, 0, 6);
+    if	(ret && strlen(ret) == 17)
+	for (i=0; i<6; i++) {
+	    ret[(i+1) * 3 - 1] = 0;
+	    tmphwaddr[i] = simple_strtoul(ret + i*3, 0, 16); 
+	    }
+    return(tmphwaddr);
+}
+
+unsigned int reg_map[8] = { 1, 1, 1, 1, 0, 0, 0, 0 };
+
+int	ask_s3c2500_uncache_region( void *addr, unsigned int size, unsigned int flag)
+{
+    static unsigned int reg_map[8] = { 1, 1, 1, 1, 0, 0, 0, 0 };
+    unsigned int i, j, n;
+    unsigned int baseandsize=0;
+    
+    if	((unsigned int)addr & (size-1))
+	return	-1;				/* addr is not alligned */
+	
+    for ( n = 4; n < 8; n++ )
+	if  ( !reg_map[n] ) {
+	    for	( i = 11, j=0x1000; i < 31; i++, j<<=1 )
+		if  ( j == size ) {
+		    baseandsize = (i << 1);		/* Area size	 */
+		    baseandsize |= ((unsigned int)addr);/* Base address  */
+		    baseandsize |= 1;			/* Enable region */
+		    switch ( n ) {
+			    case 4 :	arm940_uncache_region_4(baseandsize, flag);
+					break;
+			    case 5 :	arm940_uncache_region_5(baseandsize, flag);
+					break;
+			    case 6 :	arm940_uncache_region_6(baseandsize, flag);
+					break;
+			    case 7 :	arm940_uncache_region_7(baseandsize, flag);
+					break;
+			    default :	return -1;
+			    }
+		    reg_map[n] = 1;
+		    return 0;
+		    }
+	    return -2;	/* Size is not correct */
+	    }
+    return -3;		/* No free region found */
+}
+
+#ifdef CONFIG_UNCACHED_MEM
+
+void	set_top_uncached_region()
+{
+#ifdef CONFIG_UNCACHED_256
+unsigned int val = 0x23 | (END_MEM-0x40000);
+#endif
+
+#ifdef CONFIG_UNCACHED_512
+unsigned int val = 0x25 | (END_MEM-0x80000);
+#endif
+
+#ifdef CONFIG_UNCACHED_1024
+unsigned int val = 0x27 | (END_MEM-0x100000);
+#endif
+
+#ifdef CONFIG_UNCACHED_2048
+unsigned int val = 0x29 | (END_MEM-0x200000);
+#endif
+
+#ifdef CONFIG_UNCACHED_4096
+unsigned int val = 0x2B | (END_MEM-0x400000);
+#endif
+
+#ifdef CONFIG_UNCACHED_8192
+unsigned int val = 0x2D | (END_MEM-0x800000);
+#endif
+
+    arm940_uncache_region_7(val, 0);
+    reg_map[7] = 1;
+}
+
+#endif	/* CONFIG_UNCACHED_MEM */
+
+
+void crinfo(void)
+{
+    unsigned int tmp, size, i;
+    printk("\nCoprocessor register info:\n");
+    
+    tmp = arm940_get_creg_0();
+    printk("ID code                  : %8x\n", tmp);
+    
+    tmp = arm940_get_creg_1();
+    printk("Control register         : %8x\n", tmp);
+
+    tmp = arm940_get_creg_2(0);
+    printk("Data cacheable register  : %8x\n", tmp);
+
+    tmp = arm940_get_creg_2(1);
+    printk("Inst cacheable register  : %8x\n", tmp);
+
+    tmp = arm940_get_creg_3();
+    printk("Write buffer register    : %8x\n", tmp);
+
+    tmp = arm940_get_creg_5(0);
+    printk("Data access register     : %8x\n", tmp);
+
+    tmp = arm940_get_creg_5(1);
+    printk("Inst access register     : %8x\n", tmp);
+
+    for	(i=0; i < 8; i++ ) {
+	switch (i) {
+	    case 0 :	tmp = arm940_get_creg_6_0();	break;
+	    case 1 :	tmp = arm940_get_creg_6_1();	break;
+	    case 2 :	tmp = arm940_get_creg_6_2();	break;
+	    case 3 :	tmp = arm940_get_creg_6_3();	break;
+	    case 4 :	tmp = arm940_get_creg_6_4();	break;
+	    case 5 :	tmp = arm940_get_creg_6_5();	break;
+	    case 6 :	tmp = arm940_get_creg_6_6();	break;
+	    case 7 :	tmp = arm940_get_creg_6_7();	break;
+	    }
+	printk("Region%d: addr=%8x, ", i, (tmp & 0xfffff000));
+	size = tmp>>1;
+	size &= 0x1f;
+	size -= 0xb;
+	printk("size=%dK, ", (0x4<<size));
+	if 	( tmp & 1 )	printk("enabled\n");
+	else			printk("disabled\n");
+	}
+}
+
+EXPORT_SYMBOL(ask_s3c2500_uncache_region);
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff -urN linux-2.4.29/arch/armnommu/mach-SMDK2500/dma.c linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/dma.c
--- linux-2.4.29/arch/armnommu/mach-SMDK2500/dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/dma.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ *  uClinux/arch/arm/mach/dma.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/sched.h>
+#include <linux/malloc.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach/dma.h>
+
+void arch_dma_init(dma_t *dma)
+{
+}
diff -urN linux-2.4.29/arch/armnommu/mach-SMDK2500/io.c linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/io.c
--- linux-2.4.29/arch/armnommu/mach-SMDK2500/io.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/io.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,97 @@
+/*
+ * arch/armnommu/mach/io.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *   io functions
+ *
+ * Copyright (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * Author: RidgeRun, Inc.
+ *         Greg Lonnon (glonnon@ridgerun.com) or info@ridgerun.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Additional changes:
+ *   Copyright (C) 2001-2003 Arcturus Networks Inc.
+ *                          by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ */
+
+#include <linux/kernel.h>
+#include <asm/io.h>
+#if 0
+void __inline__ insl(unsigned int port, void *to, int len)
+{
+	int i;
+	for (i = 0; i < len; i++)
+		((unsigned long *)to)[i] = inl(port);
+}
+
+void __inline__ insw(unsigned int port, void *to, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		((unsigned short *) to)[i] = inw(port);
+}
+
+void __inline__ insb(unsigned int port, void *to, int len)
+{
+	int i;
+	for (i = 0; i < len; i++)
+		((unsigned char *)to)[i] = inb(port);
+}
+
+void __inline__ outsw(unsigned int port, const void *from, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		outw(((unsigned short *) from)[i], port);
+}
+
+void __inline__ outsl(unsigned int port, const void *from, int len)
+{
+	int i;
+	
+	for (i = 0; i < len; i++) 
+		outl(((unsigned long *) from)[i], port);
+}
+
+void __inline__ outsb(unsigned int port, const void *from, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		outb(((unsigned char *) from)[i], port);
+}
+
+void __inline__ outswb(unsigned int port, const void *from, int len)
+{
+	outsw(port, from, len >> 2);
+}
+
+void __inline__ inswb(unsigned int port, void *to, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		((unsigned short *) to)[i] = inb(port);
+}
+#endif
diff -urN linux-2.4.29/arch/armnommu/mach-SMDK2500/irq.c linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/irq.c
--- linux-2.4.29/arch/armnommu/mach-SMDK2500/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/irq.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,67 @@
+/*
+ * irq.c 
+ *
+ *  Copyright (C) 2001-2003 Arcturus Networks Inc.
+ *                          by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ */
+
+#include <linux/init.h>
+
+#include <asm/mach/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+void __inline__ s3c2500_mask_irq(unsigned int irq)
+{
+    unsigned long mask;
+
+    if	 ( irq >= NR_EXT_IRQS ) {
+	 mask = inl(INTMASK);
+	 mask |= ( 1 << (irq - NR_EXT_IRQS));
+	 outl(mask, INTMASK);
+	 } 
+    else {
+	 mask = inl(EXTMASK);
+	 mask |= ( 1 << irq);
+	 outl(mask, EXTMASK);
+	} 
+}	
+
+void __inline__ s3c2500_unmask_irq(unsigned int irq)
+{
+    unsigned long mask;
+
+    if	 ( irq >= NR_EXT_IRQS ) {
+	 mask = inl(INTMASK);
+	 mask &= ~( 1 << (irq - NR_EXT_IRQS));
+	 outl(mask, INTMASK);
+	 } 
+    else {
+	 mask = inl(EXTMASK);
+	 mask &= ~( 1 << irq);
+	 outl(mask, EXTMASK);
+	} 
+}
+
+void __inline__ s3c2500_mask_global(void)
+{
+    unsigned long mask;
+    mask = inl(EXTMASK);
+    mask |= MASK_IRQ_GLOBAL;
+    outl(mask, EXTMASK);
+}
+
+void __inline__ s3c2500_unmask_global(void)
+{
+    unsigned long mask;
+    mask = inl(EXTMASK);
+    mask &= ~(MASK_IRQ_GLOBAL);
+    outl(mask, EXTMASK);
+}
+
+void __inline__ s3c2500_mask_ack_irq(unsigned int irq)
+{
+    s3c2500_mask_irq (irq);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-SMDK2500/Makefile linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/Makefile
--- linux-2.4.29/arch/armnommu/mach-SMDK2500/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= SMDK2500.o
+
+# Object file lists.
+
+obj-y			:= $(patsubst %.c, %.o, $(wildcard *.c))
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= 
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-SMDK2500/ramlinux.lds linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/ramlinux.lds
--- linux-2.4.29/arch/armnommu/mach-SMDK2500/ramlinux.lds	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/ramlinux.lds	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,126 @@
+/* ld script to make ARM Linux kernel
+ * taken from the i386 version by Russell King
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *
+ * Additional changes:
+ *  Copyright (C) 2001-2003 Arcturus Networks Inc.
+ *                          by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ */
+INCLUDE arch/armnommu/mach-SMDK2500/romfs.ld 
+OUTPUT_ARCH(arm)
+ENTRY(stext)
+SECTIONS
+{
+
+	. = 0x20000;
+	.init : {			/* Init code and data		*/
+		_stext = .;
+		__init_begin = .;
+			*(.text.init)
+		__proc_info_begin = .;
+			*(.proc.info)
+		__proc_info_end = .;
+		__arch_info_begin = .;
+			*(.arch.info)
+		__arch_info_end = .;
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		__initcall_end = .;
+		. = ALIGN(4096);
+		__init_end = .;
+	}
+
+	/DISCARD/ : {			/* Exit code and data		*/
+		*(.text.exit)
+		*(.data.exit)
+		*(.exitcall.exit)
+	}
+
+	.text : {			/* Real text segment		*/
+		_text = .;		/* Text and read-only data	*/
+			*(.text)
+			*(.fixup)
+			*(.gnu.warning)
+			*(.text.lock)	/* out-of-line lock text */
+			*(.rodata)
+			*(.glue_7)
+			*(.glue_7t)
+			*(.kstrtab)
+		. = ALIGN(16);
+		__start___ex_table = .;	/* Exception table		*/
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;	/* Kernel symbol table		*/
+			*(__ksymtab)
+		__stop___ksymtab = .;
+
+		__start___kallsyms = .; /* All kernel symbols           */
+			*(__kallsyms)
+		__stop___kallsyms = .;
+
+
+		*(.got)			/* Global offset table		*/
+
+		_etext = .;		/* End of text section		*/
+	}
+
+	. = ALIGN(8192);
+
+	__data_start = .;
+	__data_rom_start = .;
+	.data : {
+		/*
+		 * first, the init task union, aligned
+		 * to an 8192 byte boundary.
+		 */
+		*(.init.task)
+
+		/*
+		 * then the cacheline aligned data
+		 */
+		. = ALIGN(32);
+		*(.data.cacheline_aligned)
+
+		/*
+		 * and the usual data section
+		 */
+		*(.data)
+		CONSTRUCTORS
+
+		. = ALIGN(32);	/* To be sure to align .fs . OZH */
+		_edata = .;
+		
+	}
+
+	.fs :	{
+		_romfs = ABSOLUTE (.);
+		. = . + romfs_size;
+		_end_romfs = ABSOLUTE (.);
+		}
+
+	.bss : {
+		__bss_start = .;	/* BSS				*/
+		*(.bss)
+		*(COMMON)
+		__bss_end = .;
+		_end = . ;
+	}
+
+	. = ALIGN(8192);
+	_end_kernel = . ;
+
+					/* Stabs debugging sections.	*/
+	.stab 0 : { *(.stab) }
+	.stabstr 0 : { *(.stabstr) }
+	.stab.excl 0 : { *(.stab.excl) }
+	.stab.exclstr 0 : { *(.stab.exclstr) }
+	.stab.index 0 : { *(.stab.index) }
+	.stab.indexstr 0 : { *(.stab.indexstr) }
+	.comment 0 : { *(.comment) }
+}
diff -urN linux-2.4.29/arch/armnommu/mach-SMDK2500/romfs.ld linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/romfs.ld
--- linux-2.4.29/arch/armnommu/mach-SMDK2500/romfs.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/romfs.ld	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1 @@
+romfs_size =  534528;
diff -urN linux-2.4.29/arch/armnommu/mach-SMDK2500/romlinux.lds linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/romlinux.lds
--- linux-2.4.29/arch/armnommu/mach-SMDK2500/romlinux.lds	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/romlinux.lds	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,141 @@
+/* ld script to make ARM Linux kernel
+ * taken from the i386 version by Russell King
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *
+ * Additional Changes:
+ *  Copyright (C) 2001-2003 Arcturus Networks Inc.
+ *                          by Oleksandr Zhadan <www.ArcturusNetworks.com> 
+ */
+
+MEMORY
+{
+    ram : ORIGIN = 0x20000, LENGTH = 0x7debfc
+    rom : ORIGIN = 0x1020000, LENGTH = 0x1dfffc
+}
+
+INCLUDE arch/armnommu/mach-cx821xx/romfs.ld
+OUTPUT_ARCH(arm)
+ENTRY(stext)
+SECTIONS
+{
+	.text 0x1020000 :
+	{			/* Real text segment		*/
+		_text = .;		/* Text and read-only data	*/
+		_stext = .;
+			*(.text.init)
+			*(.text)
+			*(.fixup)
+			*(.gnu.warning)
+			*(.text.lock)	/* out-of-line lock text */
+			*(.rodata)
+			*(.glue_7)
+			*(.glue_7t)
+			*(.kstrtab)
+		. = ALIGN(16);
+		__start___ex_table = .;	/* Exception table		*/
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;	/* Kernel symbol table		*/
+			*(__ksymtab)
+		__stop___ksymtab = .;
+
+		__start___kallsyms = .; /* All kernel symbols           */
+			*(__kallsyms)
+		__stop___kallsyms = .;
+
+
+		*(.got)			/* Global offset table		*/
+
+		_etext = .;		/* End of text section		*/
+		
+		. = ALIGN(32);
+	} > rom
+
+	.fs :	
+	{
+		_romfs = ABSOLUTE (.);
+		. = . + romfs_size;
+		_end_romfs = ABSOLUTE (.);
+	} > rom
+
+	
+	.init 0x20000 :
+	AT ( _end_romfs )
+	{			/* Init code and data		*/
+		
+		__init_begin = ABSOLUTE(.);
+		__proc_info_begin = ABSOLUTE(.);
+			*(.proc.info)
+		PROVIDE(__proc_info_end = .);
+		__arch_info_begin = ABSOLUTE(.);
+			*(.arch.info)
+		PROVIDE(__arch_info_end = .);
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = ABSOLUTE(.);
+			*(.setup.init)
+		PROVIDE(__setup_end = .);
+		__initcall_start = ABSOLUTE(.);
+			*(.initcall.init)
+		PROVIDE(__initcall_end = .);
+		. = ALIGN(4096);
+		PROVIDE(__init_end = .);
+	} > ram
+
+	/DISCARD/ : 
+	{			/* Exit code and data		*/
+		*(.text.exit)
+		*(.data.exit)
+		*(.exitcall.exit)
+	} > ram
+
+	
+	.data : 
+	AT ( _end_romfs + SIZEOF (.init))
+	{
+		. = ALIGN(8192);
+		__data_start = ABSOLUTE(.);
+		__data_rom_start = ABSOLUTE(.);
+		/*
+		 * first, the init task union, aligned
+		 * to an 8192 byte boundary.
+		 */
+		*(.init.task)
+
+		/*
+		 * then the cacheline aligned data
+		 */
+		. = ALIGN(32);
+		*(.data.cacheline_aligned)
+
+		/*
+		 * and the usual data section
+		 */
+		*(.data)
+		CONSTRUCTORS
+
+		PROVIDE(_edata = .);
+		
+	} > ram
+
+	.bss : {
+		__bss_start = ABSOLUTE(.);	/* BSS				*/
+		PROVIDE(bss_start = .);
+		*(.bss)
+		*(COMMON)
+		PROVIDE(_end = .);
+		__bss_end = ABSOLUTE(.);
+		. = ALIGN(8192);
+		PROVIDE(_end_kernel = .);
+	} > ram
+
+					/* Stabs debugging sections.	*/
+	.stab 0 : { *(.stab) }
+	.stabstr 0 : { *(.stabstr) }
+	.stab.excl 0 : { *(.stab.excl) }
+	.stab.exclstr 0 : { *(.stab.exclstr) }
+	.stab.index 0 : { *(.stab.index) }
+	.stab.indexstr 0 : { *(.stab.indexstr) }
+	.comment 0 : { *(.comment) }
+}
diff -urN linux-2.4.29/arch/armnommu/mach-SMDK2500/time.c linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/time.c
--- linux-2.4.29/arch/armnommu/mach-SMDK2500/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-SMDK2500/time.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+ * time.c Timer functions for SMDK2500-AN
+ *
+ * Copyright (C) 2002 Arcturus Networks Inc. 
+ *                    by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ */
+
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+#define HZMSEC	10000	/* (HZ*100) */
+
+unsigned long s3c2500_gettimeoffset (void)
+{
+    struct s3c2500_timer *tt = (struct s3c2500_timer *) (TIMER_BASE);
+    return ((tt->td[2*KERNEL_TIMER] - tt->td[2*KERNEL_TIMER+1]) / (tt->td[2*KERNEL_TIMER]/HZMSEC));
+}
+
+void s3c2500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+    static int mS;
+    static int led;
+    static int sec, on;
+    
+    if  (mS++ > 49) {
+	if  ( on ) {
+	     Vol32(0xf0030000) &= 0xffffff00;	
+	     Vol32(0xf003001c) = (255-sec);
+	     if  (sec++ > 255) sec = 0;
+	     on = 0;
+	     }
+	else {
+	     Vol32(0xf0030000) |= 0x000000ff;
+	     on = 1;
+	     }
+	mS = 0;
+	}
+    	
+    REG_WRITE(IC, (1<<(irq-31)));
+    
+    do_timer(regs);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-snds100/arch.c linux-2.4.29-uc1/arch/armnommu/mach-snds100/arch.c
--- linux-2.4.29/arch/armnommu/mach-snds100/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-snds100/arch.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+ *  linux/arch/arm/mach-snds100/arch.c
+ *
+ *  Architecture specific fixups.  This is where any
+ *  parameters in the params struct are fixed up, or
+ *  any additional architecture specific information
+ *  is pulled from the params struct.
+ */
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+
+#include <asm/elf.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+extern void genarch_init_irq(void);
+
+MACHINE_START(SNDS100, "SNDS100")
+       MAINTAINER("Mac Wang")
+       INITIRQ(genarch_init_irq)
+MACHINE_END
diff -urN linux-2.4.29/arch/armnommu/mach-snds100/irq.c linux-2.4.29-uc1/arch/armnommu/mach-snds100/irq.c
--- linux-2.4.29/arch/armnommu/mach-snds100/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-snds100/irq.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+*  linux/arch/armnommu/mach-snds100/irq.c
+*  2001 Mac Wang <mac@os.nctu.edu.tw>
+*/
+#include <linux/init.h>
+
+#include <asm/mach/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+void s3c4510b_mask_irq(unsigned int irq)
+{
+	INT_DISABLE(irq);
+}
+
+void s3c4510b_unmask_irq(unsigned int irq)
+{
+	INT_ENABLE(irq);
+}
+
+void s3c4510b_mask_ack_irq(unsigned int irq)
+{
+	INT_DISABLE(irq);
+}
+
+void s3c4510b_int_init()
+{
+	IntPend = 0x1FFFFF;
+	IntMode = INT_MODE_IRQ;
+	INT_ENABLE(INT_GLOBAL);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-snds100/Makefile linux-2.4.29-uc1/arch/armnommu/mach-snds100/Makefile
--- linux-2.4.29/arch/armnommu/mach-snds100/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-snds100/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= snds100.o
+
+# Object file lists.
+
+obj-y			:= $(patsubst %.c, %.o, $(wildcard *.c))
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= 
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-snds100/time.c linux-2.4.29-uc1/arch/armnommu/mach-snds100/time.c
--- linux-2.4.29/arch/armnommu/mach-snds100/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-snds100/time.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,20 @@
+/*
+ * time.c  Timer functions for Samsung 4510B
+ */
+
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+unsigned long samsung_gettimeoffset (void)
+{
+	return 0;
+}
+
+void samsung_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+        do_timer(regs);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-spipe/arch.c linux-2.4.29-uc1/arch/armnommu/mach-spipe/arch.c
--- linux-2.4.29/arch/armnommu/mach-spipe/arch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-spipe/arch.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,70 @@
+/*
+ *  linux/arch/arm/mach-integrator/arch.c
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/config.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/amba_kmi.h>
+
+extern void integrator_map_io(void);
+extern void integrator_init_irq(void);
+
+#ifdef CONFIG_KMI_KEYB
+static struct kmi_info integrator_keyboard __initdata = {
+	base:	IO_ADDRESS(KMI0_BASE),
+	irq:	IRQ_KMIINT0,
+	divisor: 24 / 8 - 1,
+	type:	KMI_KEYBOARD,
+};
+
+static struct kmi_info integrator_mouse __initdata = {
+	base:	IO_ADDRESS(KMI1_BASE),
+	irq:	IRQ_KMIINT1,
+	divisor: 24 / 8 - 1,
+	type:	KMI_MOUSE,
+};
+#endif
+
+static void __init
+integrator_fixup(struct machine_desc *desc, struct param_struct *params,
+		 char **cmdline, struct meminfo *mi)
+{
+#ifdef CONFIG_KMI_KEYB
+	register_kmi(&integrator_keyboard);
+	register_kmi(&integrator_mouse);
+#endif
+}
+
+MACHINE_START(INTEGRATOR, "ARM-Integrator")
+	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
+	BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
+	BOOT_PARAMS(0x00000100)
+	FIXUP(integrator_fixup)
+	MAPIO(integrator_map_io)
+	INITIRQ(integrator_init_irq)
+MACHINE_END
diff -urN linux-2.4.29/arch/armnommu/mach-spipe/dma.c linux-2.4.29-uc1/arch/armnommu/mach-spipe/dma.c
--- linux-2.4.29/arch/armnommu/mach-spipe/dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-spipe/dma.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,36 @@
+/*
+ *  linux/arch/arm/mach-integrator/dma.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/sched.h>
+#include <linux/malloc.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/dma.h>
+
+void __init arch_dma_init(dma_t *dma)
+{
+}
diff -urN linux-2.4.29/arch/armnommu/mach-spipe/irq.c linux-2.4.29-uc1/arch/armnommu/mach-spipe/irq.c
--- linux-2.4.29/arch/armnommu/mach-spipe/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-spipe/irq.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,71 @@
+/*
+ *  linux/arch/arm/mach-integrator/irq.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/irq.h>
+
+/* 
+ * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
+ * is the (PA >> 12).
+ *
+ * Setup a VA for the Integrator interrupt controller (for header #0,
+ * just for now).
+ */
+#define VA_IC_BASE              IO_ADDRESS(INTEGRATOR_IC_BASE) 
+#define VA_CMIC_BASE            IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET
+
+#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) ) 
+
+static void sc_mask_irq(unsigned int irq)
+{
+        __raw_writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+}
+
+static void sc_unmask_irq(unsigned int irq)
+{
+        __raw_writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET);
+}
+ 
+void __init integrator_init_irq(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < NR_IRQS; i++) {
+	        if (((1 << i) && INTEGRATOR_SC_VALID_INT) != 0) {
+		        irq_desc[i].valid	= 1;
+			irq_desc[i].probe_ok	= 1;
+			irq_desc[i].mask_ack	= sc_mask_irq;
+			irq_desc[i].mask	= sc_mask_irq;
+			irq_desc[i].unmask	= sc_unmask_irq;
+		}
+	}
+
+	/* Disable all interrupts initially. */
+	/* Do the core module ones */
+	__raw_writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+
+	/* do the header card stuff next */
+	__raw_writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+	__raw_writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-spipe/leds.c linux-2.4.29-uc1/arch/armnommu/mach-spipe/leds.c
--- linux-2.4.29/arch/armnommu/mach-spipe/leds.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-spipe/leds.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,94 @@
+/*
+ *  linux/arch/arm/mach-integrator/leds.c
+ *
+ *  Integrator LED control routines
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+static int saved_leds;
+
+static void integrator_leds_event(led_event_t ledevt)
+{
+	unsigned long flags;
+	const unsigned int dbg_base = IO_ADDRESS(INTEGRATOR_DBG_BASE);
+	const unsigned int hdr_ctrl = IO_ADDRESS(INTEGRATOR_HDR_BASE) +
+					INTEGRATOR_HDR_CTRL_OFFSET;
+	unsigned int ctrl;
+	unsigned int update_alpha_leds;
+	
+	// yup, change the LEDs
+	local_irq_save(flags);
+	update_alpha_leds = 0;
+
+	switch(ledevt) {
+	case led_idle_start:
+		ctrl = __raw_readl(hdr_ctrl);
+		ctrl &= ~INTEGRATOR_HDR_CTRL_LED;
+		__raw_writel(ctrl, hdr_ctrl);
+		break;
+
+	case led_idle_end:
+		ctrl = __raw_readl(hdr_ctrl);
+		ctrl |= INTEGRATOR_HDR_CTRL_LED;
+		__raw_writel(ctrl, hdr_ctrl);
+		break;
+
+	case led_timer:
+		saved_leds ^= GREEN_LED;
+		update_alpha_leds = 1;
+		break;
+
+	case led_red_on:
+		saved_leds |= RED_LED;
+		update_alpha_leds = 1;
+		break;
+
+	case led_red_off:
+		saved_leds &= ~RED_LED;
+		update_alpha_leds = 1;
+		break;
+
+	default:
+		break;
+	}
+
+	if (update_alpha_leds) {
+		while (__raw_readl(dbg_base + INTEGRATOR_DBG_ALPHA_OFFSET) & 1);
+		__raw_writel(saved_leds, dbg_base + INTEGRATOR_DBG_LEDS_OFFSET);
+	}
+	local_irq_restore(flags);
+}
+
+static int __init leds_init(void)
+{
+	if (machine_is_integrator())
+		leds_event = integrator_leds_event;
+
+	return 0;
+}
+
+__initcall(leds_init);
diff -urN linux-2.4.29/arch/armnommu/mach-spipe/Makefile linux-2.4.29-uc1/arch/armnommu/mach-spipe/Makefile
--- linux-2.4.29/arch/armnommu/mach-spipe/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-spipe/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,24 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= integrator.o
+
+# Object file lists.
+
+obj-y			:= arch.o irq.o mm.o time.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= leds.o
+
+obj-$(CONFIG_LEDS)	+= leds.o
+obj-$(CONFIG_PCI)	+= pci_v3.o pci.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-spipe/mm.c linux-2.4.29-uc1/arch/armnommu/mach-spipe/mm.c
--- linux-2.4.29/arch/armnommu/mach-spipe/mm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-spipe/mm.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,78 @@
+/*
+ *  linux/arch/arm/mach-integrator/mm.c
+ *
+ *  Extra MM routines for the ARM Integrator board
+ *
+ *  Copyright (C) 1999,2000 Arm Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+ 
+#include <asm/mach/map.h>
+
+/*
+ * Logical      Physical
+ * e8000000	40000000	PCI memory
+ * ec000000	62000000	PCI config space
+ * ed000000	61000000	PCI V3 regs
+ * ee000000	60000000	PCI IO
+ * ef000000			Cache flush
+ * f1000000	10000000	Core module registers
+ * f1100000	11000000	System controller registers
+ * f1200000	12000000	EBI registers
+ * f1300000	13000000	Counter/Timer
+ * f1400000	14000000	Interrupt controller
+ * f1500000	15000000	RTC
+ * f1600000	16000000	UART 0
+ * f1700000	17000000	UART 1
+ * f1800000	18000000	Keyboard
+ * f1900000	19000000	Mouse
+ * f1a00000	1a000000	Debug LEDs
+ * f1b00000	1b000000	GPIO
+ */
+ 
+static struct map_desc integrator_io_desc[] __initdata = {
+ { IO_ADDRESS(INTEGRATOR_HDR_BASE),   INTEGRATOR_HDR_BASE,   SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_SC_BASE),    INTEGRATOR_SC_BASE,    SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_EBI_BASE),   INTEGRATOR_EBI_BASE,   SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_CT_BASE),    INTEGRATOR_CT_BASE,    SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_IC_BASE),    INTEGRATOR_IC_BASE,    SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_RTC_BASE),   INTEGRATOR_RTC_BASE,   SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_KBD_BASE),   INTEGRATOR_KBD_BASE,   SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_MOUSE_BASE), INTEGRATOR_MOUSE_BASE, SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_DBG_BASE),   INTEGRATOR_DBG_BASE,   SZ_4K     , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_GPIO_BASE),  INTEGRATOR_GPIO_BASE,  SZ_4K     , DOMAIN_IO, 0, 1},
+ { PCI_MEMORY_VADDR,                  PHYS_PCI_MEM_BASE,     SZ_16M    , DOMAIN_IO, 0, 1},
+ { PCI_CONFIG_VADDR,                  PHYS_PCI_CONFIG_BASE,  SZ_16M    , DOMAIN_IO, 0, 1},
+ { PCI_V3_VADDR,                      PHYS_PCI_V3_BASE,      SZ_512K   , DOMAIN_IO, 0, 1},
+ { PCI_IO_VADDR,                      PHYS_PCI_IO_BASE,      SZ_64K    , DOMAIN_IO, 0, 1},
+ LAST_DESC
+};
+
+void __init integrator_map_io(void)
+{
+	iotable_init(integrator_io_desc);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-spipe/pci.c linux-2.4.29-uc1/arch/armnommu/mach-spipe/pci.c
--- linux-2.4.29/arch/armnommu/mach-spipe/pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-spipe/pci.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,119 @@
+/*
+ *  linux/arch/arm/mach-integrator/pci-integrator.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *
+ *  PCI functions for Integrator
+ */
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+
+/* 
+ * A small note about bridges and interrupts.  The DECchip 21050 (and
+ * later) adheres to the PCI-PCI bridge specification.  This says that
+ * the interrupts on the other side of a bridge are swizzled in the
+ * following manner:
+ *
+ * Dev    Interrupt   Interrupt 
+ *        Pin on      Pin on 
+ *        Device      Connector
+ *
+ *   4    A           A
+ *        B           B
+ *        C           C
+ *        D           D
+ * 
+ *   5    A           B
+ *        B           C
+ *        C           D
+ *        D           A
+ *
+ *   6    A           C
+ *        B           D
+ *        C           A
+ *        D           B
+ *
+ *   7    A           D
+ *        B           A
+ *        C           B
+ *        D           C
+ *
+ * Where A = pin 1, B = pin 2 and so on and pin=0 = default = A.
+ * Thus, each swizzle is ((pin-1) + (device#-4)) % 4
+ *
+ * The following code swizzles for exactly one bridge.  
+ */
+static inline int bridge_swizzle(int pin, unsigned int slot) 
+{
+	return (pin + slot) & 3;
+}
+
+/*
+ * This routine handles multiple bridges.
+ */
+static u8 __init integrator_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	int pin = *pinp;
+
+	if (pin == 0)
+		pin = 1;
+
+	pin -= 1;
+	while (dev->bus->self) {
+		pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+		/*
+		 * move up the chain of bridges, swizzling as we go.
+		 */
+		dev = dev->bus->self;
+	}
+	*pinp = pin + 1;
+
+	return PCI_SLOT(dev->devfn);
+}
+
+static int irq_tab[4] __initdata = {
+	IRQ_PCIINT0,	IRQ_PCIINT1,	IRQ_PCIINT2,	IRQ_PCIINT3
+};
+
+/*
+ * map the specified device/slot/pin to an IRQ.  This works out such
+ * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
+ */
+static int __init integrator_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int intnr = ((slot - 9) + (pin - 1)) & 3;
+
+	return irq_tab[intnr];
+}
+
+extern void pci_v3_init(struct arm_pci_sysdata *);
+
+struct hw_pci integrator_pci __initdata = {
+	init:		pci_v3_init,
+	swizzle:	integrator_swizzle,
+	map_irq:	integrator_map_irq,
+};
diff -urN linux-2.4.29/arch/armnommu/mach-spipe/pci_v3.c linux-2.4.29-uc1/arch/armnommu/mach-spipe/pci_v3.c
--- linux-2.4.29/arch/armnommu/mach-spipe/pci_v3.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-spipe/pci_v3.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,460 @@
+/*
+ *  linux/arch/arm/mach-integrator/pci_v3.c
+ *
+ *  PCI functions for V3 host PCI bridge
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/malloc.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+
+#include <asm/hardware/pci_v3.h>
+
+/*
+ * The V3 PCI interface chip in Integrator provides several windows from
+ * local bus memory into the PCI memory areas.   Unfortunately, there
+ * are not really enough windows for our usage, therefore we reuse 
+ * one of the windows for access to PCI configuration space.  The
+ * memory map is as follows:
+ * 
+ * Local Bus Memory         Usage
+ * 
+ * 40000000 - 4FFFFFFF      PCI memory.  256M non-prefetchable
+ * 50000000 - 5FFFFFFF      PCI memory.  256M prefetchable
+ * 60000000 - 60FFFFFF      PCI IO.  16M
+ * 68000000 - 68FFFFFF      PCI Configuration. 16M
+ * 
+ * There are three V3 windows, each described by a pair of V3 registers.
+ * These are LB_BASE0/LB_MAP0, LB_BASE1/LB_MAP1 and LB_BASE2/LB_MAP2.
+ * Base0 and Base1 can be used for any type of PCI memory access.   Base2
+ * can be used either for PCI I/O or for I20 accesses.  By default, uHAL
+ * uses this only for PCI IO space.
+ * 
+ * PCI Memory is mapped so that assigned addresses in PCI Memory match
+ * local bus memory addresses.  In other words, if a PCI device is assigned
+ * address 80200000 then that address is a valid local bus address as well
+ * as a valid PCI Memory address.  PCI IO addresses are mapped to start
+ * at zero.  This means that local bus address 60000000 maps to PCI IO address
+ * 00000000 and so on.   Device driver writers need to be aware of this 
+ * distinction.
+ * 
+ * Normally these spaces are mapped using the following base registers:
+ * 
+ * Usage Local Bus Memory         Base/Map registers used
+ * 
+ * Mem   40000000 - 4FFFFFFF      LB_BASE0/LB_MAP0
+ * Mem   50000000 - 5FFFFFFF      LB_BASE1/LB_MAP1
+ * IO    60000000 - 60FFFFFF      LB_BASE2/LB_MAP2
+ * Cfg   68000000 - 68FFFFFF      
+ * 
+ * This means that I20 and PCI configuration space accesses will fail.
+ * When PCI configuration accesses are needed (via the uHAL PCI 
+ * configuration space primitives) we must remap the spaces as follows:
+ * 
+ * Usage Local Bus Memory         Base/Map registers used
+ * 
+ * Mem   40000000 - 4FFFFFFF      LB_BASE0/LB_MAP0
+ * Mem   50000000 - 5FFFFFFF      LB_BASE0/LB_MAP0
+ * IO    60000000 - 60FFFFFF      LB_BASE2/LB_MAP2
+ * Cfg   68000000 - 68FFFFFF      LB_BASE1/LB_MAP1
+ * 
+ * To make this work, the code depends on overlapping windows working.
+ * The V3 chip translates an address by checking its range within 
+ * each of the BASE/MAP pairs in turn (in ascending register number
+ * order).  It will use the first matching pair.   So, for example,
+ * if the same address is mapped by both LB_BASE0/LB_MAP0 and
+ * LB_BASE1/LB_MAP1, the V3 will use the translation from 
+ * LB_BASE0/LB_MAP0.
+ * 
+ * To allow PCI Configuration space access, the code enlarges the
+ * window mapped by LB_BASE0/LB_MAP0 from 256M to 512M.  This occludes
+ * the windows currently mapped by LB_BASE1/LB_MAP1 so that it can
+ * be remapped for use by configuration cycles.
+ * 
+ * At the end of the PCI Configuration space accesses, 
+ * LB_BASE1/LB_MAP1 is reset to map PCI Memory.  Finally the window
+ * mapped by LB_BASE0/LB_MAP0 is reduced in size from 512M to 256M to
+ * reveal the now restored LB_BASE1/LB_MAP1 window.
+ * 
+ * NOTE: We do not set up I2O mapping.  I suspect that this is only
+ * for an intelligent (target) device.  Using I2O disables most of
+ * the mappings into PCI memory.
+ */
+
+// V3 access routines
+#define _V3Write16(o,v) __raw_writew(v, PCI_V3_VADDR + (unsigned int)(o))
+#define _V3Read16(o)    (__raw_readw(PCI_V3_VADDR + (unsigned int)(o)))
+
+#define _V3Write32(o,v) __raw_writel(v, PCI_V3_VADDR + (unsigned int)(o))
+#define _V3Read32(o)    (__raw_readl(PCI_V3_VADDR + (unsigned int)(o)))
+
+/*============================================================================
+ *
+ * routine:	uHALir_PCIMakeConfigAddress()
+ *
+ * parameters:	bus = which bus
+ *              device = which device
+ *              function = which function
+ *		offset = configuration space register we are interested in
+ *
+ * description:	this routine will generate a platform dependant config
+ *		address.
+ *
+ * calls:	none
+ *
+ * returns:	configuration address to play on the PCI bus
+ *
+ * To generate the appropriate PCI configuration cycles in the PCI 
+ * configuration address space, you present the V3 with the following pattern 
+ * (which is very nearly a type 1 (except that the lower two bits are 00 and
+ * not 01).   In order for this mapping to work you need to set up one of
+ * the local to PCI aperatures to 16Mbytes in length translating to
+ * PCI configuration space starting at 0x0000.0000.
+ *
+ * PCI configuration cycles look like this:
+ *
+ * Type 0:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *	31:11	Device select bit.
+ * 	10:8	Function number
+ * 	 7:2	Register number
+ *
+ * Type 1:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *	31:24	reserved
+ *	23:16	bus number (8 bits = 128 possible buses)
+ *	15:11	Device number (5 bits)
+ *	10:8	function number
+ *	 7:2	register number
+ *  
+ */
+static spinlock_t v3_lock = SPIN_LOCK_UNLOCKED;
+
+#define PCI_BUS_NONMEM_START	0x00000000
+#define PCI_BUS_NONMEM_SIZE	0x10000000
+
+#define PCI_BUS_PREMEM_START	0x10000000
+#define PCI_BUS_PREMEM_SIZE	0x10000000
+
+#if PCI_BUS_NONMEM_START & 0x000fffff
+#error PCI_BUS_NONMEM_START must be megabyte aligned
+#endif
+#if PCI_BUS_PREMEM_START & 0x000fffff
+#error PCI_BUS_PREMEM_START must be megabyte aligned
+#endif
+
+static unsigned long v3_open_config_window(struct pci_dev *dev, int offset)
+{
+	unsigned int address, mapaddress, busnr;
+
+	busnr = dev->bus->number;
+
+	/*
+	 * Trap out illegal values
+	 */
+	if (offset > 255)
+		BUG();
+	if (busnr > 255)
+		BUG();
+	if (dev->devfn > 255)
+		BUG();
+
+	if (busnr == 0) {
+		int slot = PCI_SLOT(dev->devfn);
+
+		/*
+		 * local bus segment so need a type 0 config cycle
+		 *
+		 * build the PCI configuration "address" with one-hot in
+		 * A31-A11
+		 *
+		 * mapaddress:
+		 *  3:1 = config cycle (101)
+		 *  0   = PCI A1 & A0 are 0 (0)
+		 */
+		address = PCI_FUNC(dev->devfn) << 8;
+		mapaddress = 0x0a;
+
+		if (slot > 12)
+			/*
+			 * high order bits are handled by the MAP register
+			 */
+			mapaddress |= 1 << (slot - 4);
+		else
+			/*
+			 * low order bits handled directly in the address
+			 */
+			address |= 1 << (slot + 11);
+	} else {
+        	/*
+		 * not the local bus segment so need a type 1 config cycle
+		 *
+		 * address:
+		 *  23:16 = bus number
+		 *  15:11 = slot number (7:3 of devfn)
+		 *  10:8  = func number (2:0 of devfn)
+		 *
+		 * mapaddress:
+		 *  3:1 = config cycle (101)
+		 *  0   = PCI A1 & A0 from host bus (1)
+		 */
+		mapaddress = 0x0b;
+		address = (busnr << 16) | (dev->devfn << 8);
+	}
+
+	/*
+	 * Set up base0 to see all 512Mbytes of memory space (not prefetchable), this
+	 * frees up base1 for re-use by configuration memory
+	 */
+	_V3Write32(V3_LB_BASE0, (PHYS_PCI_MEM_BASE & 0xFFF00000) | 0x90 | V3_LB_BASE_M_ENABLE);
+
+	/*
+	 * Set up base1/map1 to point into configuration space.
+	 */
+	_V3Write32(V3_LB_BASE1, (PHYS_PCI_CONFIG_BASE & 0xFFF00000) | 0x40 | V3_LB_BASE_M_ENABLE);
+        _V3Write16(V3_LB_MAP1, mapaddress);
+
+	return PCI_CONFIG_VADDR + address + offset;
+}
+
+static void v3_close_config_window(void)
+{
+	/*
+	 * Reassign base1 for use by prefetchable PCI memory
+	 */
+	_V3Write32(V3_LB_BASE1, ((PHYS_PCI_MEM_BASE + SZ_256M) & 0xFFF00000) | 0x84 | V3_LB_BASE_M_ENABLE);
+	_V3Write16(V3_LB_MAP1, ((PCI_BUS_PREMEM_START & 0xFFF00000) >> 16) | 0x0006);
+
+	/*
+	 * And shrink base0 back to a 256M window (NOTE: MAP0 already correct)
+	 */
+	_V3Write32(V3_LB_BASE0, (PHYS_PCI_MEM_BASE & 0xFFF00000) | 0x80 | V3_LB_BASE_M_ENABLE);
+}
+
+static int v3_read_config_byte(struct pci_dev *dev, int where, u8 *val)
+{
+	unsigned long addr;
+	unsigned long flags;
+	u8 v;
+
+	spin_lock_irqsave(&v3_lock, flags);
+	addr = v3_open_config_window(dev, where);
+
+	v = __raw_readb(addr);
+
+	v3_close_config_window();
+	spin_unlock_irqrestore(&v3_lock, flags);
+
+	*val = v;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int v3_read_config_word(struct pci_dev *dev, int where, u16 *val)
+{
+	unsigned long addr;
+	unsigned long flags;
+	u16 v;
+
+	spin_lock_irqsave(&v3_lock, flags);
+	addr = v3_open_config_window(dev, where);
+
+	v = __raw_readw(addr);
+
+	v3_close_config_window();
+	spin_unlock_irqrestore(&v3_lock, flags);
+
+	*val = v;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int v3_read_config_dword(struct pci_dev *dev, int where, u32 *val)
+{
+	unsigned long addr;
+	unsigned long flags;
+	u32 v;
+
+	spin_lock_irqsave(&v3_lock, flags);
+	addr = v3_open_config_window(dev, where);
+
+	v = __raw_readl(addr);
+
+	v3_close_config_window();
+	spin_unlock_irqrestore(&v3_lock, flags);
+
+	*val = v;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int v3_write_config_byte(struct pci_dev *dev, int where, u8 val)
+{
+	unsigned long addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&v3_lock, flags);
+	addr = v3_open_config_window(dev, where);
+
+	__raw_writeb(val, addr);
+	__raw_readb(addr);
+	
+	v3_close_config_window();
+	spin_unlock_irqrestore(&v3_lock, flags);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int v3_write_config_word(struct pci_dev *dev, int where, u16 val)
+{
+	unsigned long addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&v3_lock, flags);
+	addr = v3_open_config_window(dev, where);
+
+	__raw_writew(val, addr);
+	__raw_readw(addr);
+
+	v3_close_config_window();
+	spin_unlock_irqrestore(&v3_lock, flags);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int v3_write_config_dword(struct pci_dev *dev, int where, u32 val)
+{
+	unsigned long addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&v3_lock, flags);
+	addr = v3_open_config_window(dev, where);
+
+	__raw_writel(val, addr);
+	__raw_readl(addr);
+
+	v3_close_config_window();
+	spin_unlock_irqrestore(&v3_lock, flags);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_v3_ops = {
+	read_byte:	v3_read_config_byte,
+	read_word:	v3_read_config_word,
+	read_dword:	v3_read_config_dword,
+	write_byte:	v3_write_config_byte,
+	write_word:	v3_write_config_word,
+	write_dword:	v3_write_config_dword,
+};
+
+static struct resource non_mem = {
+	name:	"PCI non-prefetchable",
+	start:	PCI_BUS_NONMEM_START,
+	end:	PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE - 1,
+	flags:	IORESOURCE_MEM,
+};
+
+static struct resource pre_mem = {
+	name:	"PCI prefetchable",
+	start:	PCI_BUS_PREMEM_START,
+	end:	PCI_BUS_PREMEM_START + PCI_BUS_PREMEM_SIZE - 1,
+	flags:	IORESOURCE_MEM | IORESOURCE_PREFETCH,
+};
+
+/*
+ * V3_LB_BASE? - local bus address
+ * V3_LB_MAP?  - pci bus address
+ */
+void __init pci_v3_init(struct arm_pci_sysdata *sysdata)
+{
+	struct pci_bus *bus;
+	unsigned int pci_cmd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&v3_lock, flags);
+
+	/*
+	 * Setup window 0 - PCI non-prefetchable memory
+	 *  Local: 0x40000000 Bus: 0x00000000 Size: 256MB
+	 */
+	_V3Write32(V3_LB_BASE0, (PHYS_PCI_MEM_BASE & 0xfff00000) | 0x80 | V3_LB_BASE_M_ENABLE);
+	_V3Write16(V3_LB_MAP0, (PCI_BUS_NONMEM_START >> 16) | 0x0006);
+
+	/*
+	 * Setup window 1 - PCI prefetchable memory
+	 *  Local: 0x50000000 Bus: 0x10000000 Size: 256MB
+	 */
+	_V3Write32(V3_LB_BASE1, ((PHYS_PCI_MEM_BASE + SZ_256M) & 0xFFF00000) | 0x84 | V3_LB_BASE_M_ENABLE);
+	_V3Write16(V3_LB_MAP1, (PCI_BUS_PREMEM_START >> 16) | 0x0006);
+
+	/*
+	 * Setup window 2 - PCI IO
+	 */
+//	_V3Write32(V3_LB_BASE2, (PHYS_PCI_IO_BASE & 0xff000000) | V3_LB_BASE_M_ENABLE);
+//	_V3Write16(V3_LB_MAP2, 0);
+
+	spin_unlock_irqrestore(&v3_lock, flags);
+
+	bus = pci_scan_bus(0, &pci_v3_ops, sysdata);
+
+	if (request_resource(&iomem_resource, &non_mem))
+		printk("PCI: unable to allocate non-prefetchable memory region");
+	if (request_resource(&iomem_resource, &pre_mem))
+		printk("PCI: unable to allocate prefetchable memory region");
+
+	/*
+	 * bus->resource[0] is the IO resource for this bus
+	 * bus->resource[1] is the mem resource for this bus
+	 * bus->resource[2] is the prefetch mem resource for this bus
+	 */
+	bus->resource[1] = &non_mem;
+	bus->resource[2] = &pre_mem;
+
+	pci_cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+		  PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
+
+	pci_cmd |= sysdata->bus[0].features;
+
+	_V3Write16(V3_PCI_CMD, pci_cmd);
+
+	printk("PCI: Fast back to back transfers %sabled\n",
+	       (sysdata->bus[0].features & PCI_COMMAND_FAST_BACK) ?
+		"en" : "dis");
+}
diff -urN linux-2.4.29/arch/armnommu/mach-spipe/time.c linux-2.4.29-uc1/arch/armnommu/mach-spipe/time.c
--- linux-2.4.29/arch/armnommu/mach-spipe/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-spipe/time.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,45 @@
+/*
+ *  linux/arch/arm/mach-integrator/time.c
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+
+#define RTC_DR		(*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 0))
+#define RTC_MR		(*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 4))
+#define RTC_STAT	(*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 8))
+#define RTC_EOI		(*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 8))
+#define RTC_LR		(*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 12))
+#define RTC_CR		(*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 16))
+
+#define RTC_CR_MIE	0x00000001
+
+extern int (*set_rtc)(void);
+
+static int integrator_set_rtc(void)
+{
+	RTC_LR = xtime.tv_sec;
+	return 1;
+}
+
+static int integrator_rtc_init(void)
+{
+	RTC_CR = 0;
+	RTC_EOI = 0;
+
+	xtime.tv_sec = RTC_DR;
+
+	set_rtc = integrator_set_rtc;
+
+	return 0;
+}
+
+__initcall(integrator_rtc_init);
diff -urN linux-2.4.29/arch/armnommu/mach-ta7s/arch_init.c linux-2.4.29-uc1/arch/armnommu/mach-ta7s/arch_init.c
--- linux-2.4.29/arch/armnommu/mach-ta7s/arch_init.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ta7s/arch_init.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,209 @@
+/*
+ * arch_init.c	Generic Triscend A7S initialization functions
+ *         
+ * copyright:
+ *         (C) 2003 Triscend Corp. (www.triscend.com)
+ * authors: Craig Hackney (craig@triscend.com)
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/config.h>
+#include <asm/arch/arch.h>
+#include <asm/dma.h>
+#include <asm/mach/dma.h>
+#ifdef CONFIG_USE_A7HAL
+#include <asm/arch/a7hal/uart.h>
+#include <asm/arch/a7hal/timer.h>
+#include <asm/arch/a7hal/clock.h>
+#include <asm/arch/a7hal/mpu.h>
+#include <asm/arch/a7hal/dma.h>
+
+static a7hal_mpu_map myMap[] = {
+/*
+ *   base            size               permissions     cacheEnable
+ */
+  {0x00000000, 0, 0, NO},	/* Empty */
+  {0x00000000, 0, 0, NO},	/* Empty */
+  {0x00000000, 0, 0, NO},	/* Empty */
+  {0x00000000, 0, 0, NO},	/* Empty */
+  {0x00000000, A7HAL_SIZE_4GB, A7HAL_SUP_RW_USR_RW, NO},/* Enable access to all memory */
+  {0xd0000000, A7HAL_SIZE_8MB, A7HAL_SUP_RW_USR_RW, YES},/* FLASH	*/
+  {0xd1010000, A7HAL_SIZE_64KB, A7HAL_SUP_RW_USR_NO, NO},/* Config regs	*/
+  {0x00000000, A7HAL_SIZE_32MB, A7HAL_SUP_RW_USR_RW, YES}/* SDRAM	*/
+};
+
+#else
+
+#define PIPELINE_ENABLE        0x00008000
+#define DMA_BUFFERS_ENABLE     0x00ff0000
+
+extern unsigned long a7hal_clock_getFreq (int noRAM);
+
+void
+a7hal_sdram_init (void)
+{
+  unsigned long refresh;
+  unsigned long freq;
+
+  freq = a7hal_clock_getFreq (1);
+  refresh = (unsigned long) ((0.064 / 4096) * freq);
+
+  refresh <<= 16;
+  refresh &= 0x0fff0000;
+
+  refresh |= 0x00000003;
+
+#if defined(A7VE) || defined(A7VC) || defined(A7VT) || defined(A7VL)
+  refresh |= (1<<REF_EN_BIT);
+#endif
+
+  /* Set the SDRAM refresh rate */
+  *((volatile unsigned long *) MSS_SDR_CTRL_REG) = refresh;
+
+  /* Read the value back to flush the CSI pipeline */
+  refresh = *((volatile unsigned long *) MSS_SDR_CTRL_REG);
+
+  /*
+   * If the clock frequency is greater than 40MHz
+   * enable the memory pipeline.
+   */
+  if (freq > 40000000)
+    *((unsigned long *) MSS_CONFIG_REG) |= PIPELINE_ENABLE;
+
+  /* Enable the DMA buffers */
+  *((unsigned long *) MSS_CONFIG_REG) |= DMA_BUFFERS_ENABLE;
+}
+
+void
+a7hal_uart_setBaud (int port, int baudRate)
+{
+  int oldLineControl;
+  int baud;
+
+  baud = (a7hal_clock_getFreq (0) / (baudRate * 16)) - 1;
+
+  if (port == 0)
+    {
+      oldLineControl = A7_REG (UART0_LINE_CONTROL_REG);
+      A7_REG (UART0_LINE_CONTROL_REG) = (1L << DLAB_BIT);
+      A7_REG (UART0_DIVISOR_MSB_REG) = ((baud >> 8) & 0xff);
+      A7_REG (UART0_DIVISOR_LSB_REG) = (baud & 0xff);
+      A7_REG (UART0_LINE_CONTROL_REG) = oldLineControl;
+    }
+  else
+    {
+      oldLineControl = A7_REG (UART1_LINE_CONTROL_REG);
+      A7_REG (UART1_LINE_CONTROL_REG) = (1L << DLAB_BIT);
+      A7_REG (UART1_DIVISOR_MSB_REG) = ((baud >> 8) & 0xff);
+      A7_REG (UART1_DIVISOR_LSB_REG) = (baud & 0xff);
+      A7_REG (UART1_LINE_CONTROL_REG) = oldLineControl;
+    }
+}
+
+void
+a7hal_uart_init (void)
+{
+  A7_REG (UART0_CONTROL_REG) = (1L << PRESCALE_EN_BIT);
+  A7_REG (UART1_CONTROL_REG) = (1L << PRESCALE_EN_BIT);
+
+  a7hal_uart_setBaud (0, 115200);
+  a7hal_uart_setBaud (1, 115200);
+
+  /*
+   * Set the UARTs to no parity, 8 data, 1 stop
+   */
+  A7_REG (UART0_LINE_CONTROL_REG) = 0x03;
+  A7_REG (UART1_LINE_CONTROL_REG) = 0x03;
+}
+
+
+void
+a7hal_lancs8900_reset (int interface)
+{
+  int n;
+
+  A7_REG (0x10000020) = 0x01;
+
+  for (n = 0; n < 0x100000; n++);
+
+  A7_REG (0x10000020) = 0x00;
+
+  A7_REG (0x10000020) = 0x02;
+  A7_REG (0x10000020) = 0x00;
+  A7_REG (0x10000020) = 0x02;
+  A7_REG (0x10000020) = 0x00;
+}
+
+int
+a7hal_lancs8900_init (const unsigned long *params)
+{
+  a7hal_lancs8900_reset (0);
+  return (0);
+}
+
+#endif
+
+/*
+ * Defines the base address and IRQ to used for
+ * the CS8900.
+ */
+const unsigned long cs8900Params[] = { 0x10000000, 11 };
+
+void
+ta7_arch_init (void)
+{
+  a7hal_uart_init ();
+#ifdef CONFIG_CS89x0
+  a7hal_lancs8900_init (cs8900Params);
+#endif
+
+#ifdef CONFIG_USE_A7HAL
+  a7hal_icu_init ();
+  a7hal_clock_init ();
+  a7hal_timer_init ();
+  a7hal_mpu_init ();
+  a7hal_mpu_setMap (myMap);
+  a7hal_mpu_enableMap ();
+#endif
+}
+
+static struct dma_ops dma_operation = {
+  type:"TA7"
+};
+
+/*
+ * Minimum DMA support, just initialize the d_ops
+ * for each channel so that kernel level drivers
+ * can call request_dma and free_dma.
+ */
+void
+arch_dma_init (dma_t dma_chan[])
+{
+#ifdef CONFIG_USE_A7HAL
+  int n;
+
+  a7hal_dma_init (1);
+
+  for (n = 0; n < MAX_DMA_CHANNELS; n++)
+    dma_chan[n].d_ops = &dma_operation;
+#endif
+}
diff -urN linux-2.4.29/arch/armnommu/mach-ta7s/coproc.S linux-2.4.29-uc1/arch/armnommu/mach-ta7s/coproc.S
--- linux-2.4.29/arch/armnommu/mach-ta7s/coproc.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ta7s/coproc.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,207 @@
+/*
+ * coproc.S	Functions to read and write CP15
+ *         
+ * copyright:
+ *         (C) 2003 Triscend Corp. (www.triscend.com)
+ * authors: Craig Hackney (craig@triscend.com)
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+    .align
+
+    .globl  __writeCPR
+__writeCPR:
+    CMP     R0, #0
+    BNE     reg1
+    MCR     p15,0, R1, c0, c0
+    B       done
+reg1:
+    CMP     R0, #1
+    BNE     reg2
+    MCR     p15,0, R1, c1, c0
+    B       done
+reg2:
+    CMP     R0, #2
+    BNE     reg3
+    MCR     p15,0, R1, c2, c0
+    B       done
+reg3:
+    CMP     R0, #3
+    BNE     reg4
+    MCR     p15,0, R1, c3, c0
+    B       done
+reg4:
+    CMP     R0, #4
+    BNE     reg5
+    MCR     p15,0, R1, c4, c0
+    B       done
+reg5:
+    CMP     R0, #5
+    BNE     reg6
+    MCR     p15,0, R1, c5, c0
+    B       done
+reg6:
+    CMP     R0, #6
+    BNE     reg7
+    MCR     p15,0, R1, c6, c0
+    B       done
+reg7:
+    CMP     R0, #7
+    BNE     done
+    MCR     p15,0, R1, c7, c0
+done:
+#ifdef __THUMB__
+    BX      LR
+#else
+    MOV     PC,LR
+#endif
+
+    .globl  __readCPR
+__readCPR:
+    CMP     R0, #0
+    BNE     readreg1
+    MRC     p15,0, R0, c0, c0
+    B       done
+readreg1:
+    CMP     R0, #1
+    BNE     readreg2
+    MRC     p15,0, R0, c1, c0
+    B       done
+readreg2:
+    CMP     R0, #2
+    BNE     readreg3
+    MRC     p15,0, R0, c2, c0
+    B       done
+readreg3:
+    CMP     R0, #3
+    BNE     readreg4
+    MRC     p15,0, R0, c3, c0
+    B       done
+readreg4:
+    CMP     R0, #4
+    BNE     readreg5
+    MRC     p15,0, R0, c4, c0
+    B       done
+readreg5:
+    CMP     R0, #5
+    BNE     readreg6
+    MRC     p15,0, R0, c5, c0
+    B       done
+readreg6:
+    CMP     R0, #6
+    BNE     readreg7
+    MRC     p15,0, R0, c6, c0
+    B       done
+readreg7:
+    CMP     R0, #7
+    BNE     readregdone
+    MRC     p15,0, R0, c7, c0
+readregdone:
+    B       done
+
+    .globl  __writeCPRSub
+__writeCPRSub:
+    CMP     R1, #0
+    BNE     writesubreg1
+    MCR     p15,0, R2, c6, c0
+    B       done
+writesubreg1:
+    CMP     R1, #1
+    BNE     writesubreg2
+    MCR     p15,0, R2, c6, c1
+    B       done
+writesubreg2:
+    CMP     R1, #2
+    BNE     writesubreg3
+    MCR     p15,0, R2, c6, c2
+    B       done
+writesubreg3:
+    CMP     R1, #3
+    BNE     writesubreg4
+    MCR     p15,0, R2, c6, c3
+    B       done
+writesubreg4:
+    CMP     R1, #4
+    BNE     writesubreg5
+    MCR     p15,0, R2, c6, c4
+    B       done
+writesubreg5:
+    CMP     R1, #5
+    BNE     writesubreg6
+    MCR     p15,0, R2, c6, c5
+    B       done
+writesubreg6:
+    CMP     R1, #6
+    BNE     writesubreg7
+    MCR     p15,0, R2, c6, c6
+    B       done
+writesubreg7:
+    CMP     R1, #7
+    BNE     writesubdone
+    MCR     p15,0, R2, c6, c7
+writesubdone:
+    B       done
+
+    .globl  __readCPRSub
+__readCPRSub:
+    CMP     R1, #0
+    BNE     readsubreg1
+    MRC     p15,0, R0, c6, c0
+    B       done
+readsubreg1:
+    CMP     R1, #1
+    BNE     readsubreg2
+    MRC     p15,0, R0, c6, c1
+    B       done
+readsubreg2:
+    CMP     R1, #2
+    BNE     readsubreg3
+    MRC     p15,0, R0, c6, c2
+    B       done
+readsubreg3:
+    CMP     R1, #3
+    BNE     readsubreg4
+    MRC     p15,0, R0, c6, c3
+    B       done
+readsubreg4:
+    CMP     R1, #4
+    BNE     readsubreg5
+    MRC     p15,0, R0, c6, c4
+    B       done
+readsubreg5:
+    CMP     R1, #5
+    BNE     readsubreg6
+    MRC     p15,0, R0, c6, c5
+    B       done
+readsubreg6:
+    CMP     R1, #6
+    BNE     readsubreg7
+    MRC     p15,0, R0, c6, c6
+    B       done
+readsubreg7:
+    CMP     R1, #7
+    BNE     readsubdone
+    MRC     p15,0, R0, c6, c7
+readsubdone:
+    B       done
+
diff -urN linux-2.4.29/arch/armnommu/mach-ta7s/Makefile linux-2.4.29-uc1/arch/armnommu/mach-ta7s/Makefile
--- linux-2.4.29/arch/armnommu/mach-ta7s/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ta7s/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,39 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= ta7s.o
+
+
+# Object file lists.
+
+obj-y			:= $(patsubst %.c, %.o, $(wildcard *.c)) \
+			   $(patsubst %.S, %.o, $(wildcard *.S))
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= 
+
+ifeq ($(CONFIG_USE_A7HAL),y)
+obj-y			+= \
+			   a7hal/clock.o \
+			   a7hal/dma.o \
+			   a7hal/icu.o \
+			   a7hal/led.o \
+			   a7hal/mpu.o \
+			   a7hal/sdram.o \
+			   a7hal/timer.o \
+			   a7hal/uart.o \
+			   a7hal/watchdog.o \
+			   a7hal/soft/lancs.o
+endif
+
+#obj-$(CONFIG_LEDS)	+=
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-ta7s/time.c linux-2.4.29-uc1/arch/armnommu/mach-ta7s/time.c
--- linux-2.4.29/arch/armnommu/mach-ta7s/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-ta7s/time.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,145 @@
+/*
+ * time.c  Timer functions for the Triscend A7S.
+ *         
+ * copyright:
+ *         (C) 2003 Triscend Corp. (www.triscend.com)
+ * authors: Craig Hackney (craig@triscend.com)
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/autoconf.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <asm/arch/arch.h>
+
+#ifndef CONFIG_OSC_FREQ
+  #define CONFIG_OSC_FREQ	25000000
+#endif
+
+#ifdef CONFIG_USE_A7HAL
+#include <asm/arch/a7hal/clock.h>
+#include <asm/arch/a7hal/timer.h>
+#else
+
+/*
+ * Calculate the cpu speed based on the PLL, if the PLL
+ * is not being used, this function will return 0
+ */
+unsigned long
+a7hal_clock_getFreq (int noRAM)
+{
+  unsigned int freq = 0;
+#if defined(A7VE) || defined(A7VC) || defined(A7VT) || defined(A7VL)
+  unsigned long feedbackDivider;
+  unsigned long outputDivider;
+  unsigned long referenceDivider;
+#else
+  unsigned int scale;
+#endif
+
+  if (GET_BIT (SYS_CLOCK_CONTROL_REG, CLK_SEL_BIT))
+    {
+      if (GET_BIT (SYS_CLOCK_CONTROL_REG, PLL_SEL_BIT))
+	{
+#if defined(A7VE) || defined(A7VC) || defined(A7VT) || defined(A7VL)
+	  feedbackDivider = GET_FIELD (SYS_PLL_CONTROL_REG,
+				       PLL_CLKF_FIELD, NBITS_PLL_CLKF) + 1;
+
+	  outputDivider = GET_FIELD (SYS_PLL_CONTROL_REG,
+				     PLL_CLKOD_FIELD, NBITS_PLL_CLKOD) + 1;
+
+	  referenceDivider = GET_FIELD (SYS_PLL_CONTROL_REG,
+					PLL_CLKR_FIELD, NBITS_PLL_CLKR) + 1;
+
+
+          /*
+           * Is the input to the PLL the 32KHz xtal or the external osc.
+           */
+          if ( GET_BIT( SYS_PLL_CONTROL_REG, PLL_REFSEL_BIT ) )
+          {
+            freq = ( CONFIG_OSC_FREQ * feedbackDivider ) /
+                ( referenceDivider * outputDivider );
+          }
+          else
+          {
+              freq = ( 32768 * feedbackDivider ) /
+                  ( referenceDivider * outputDivider );
+          }
+
+#else
+	  freq = 32768 * GET_FIELD (SYS_CLOCK_CONTROL_REG,
+				    PLL_DIV_FIELD, NBITS_PLL_DIV);
+	  scale =
+	    GET_FIELD (SYS_CLOCK_CONTROL_REG, PLL_SCALE_FIELD,
+		       NBITS_PLL_SCALE);
+	  while (scale)
+	    {
+	      freq >>= 1;
+	      scale >>= 1;
+	    }
+#endif
+	}
+      else
+	{
+	  freq = CONFIG_OSC_FREQ;
+	}
+    }
+
+  return freq;
+}
+
+void
+a7hal_timer_start (unsigned short count, int whichTimer,
+		   unsigned long control)
+{
+  A7_REG (TIMER0_LOAD_REG) = count;
+  A7_REG (TIMER0_CONTROL_REG) = (1L << TIM_ENABLE_BIT) | control;
+}
+
+void
+a7hal_timer_clearInt (int whichTimer)
+{
+  A7_REG (TIMER0_CLEAR_REG) = (1L << TIM_INT_CLEAR_BIT);
+}
+
+unsigned short
+a7hal_timer_read (int whichTimer)
+{
+  return (A7_REG (TIMER0_VALUE_REG));
+}
+
+#endif
+
+unsigned long
+ta7_gettimeoffset (void)
+{
+  return (a7hal_timer_read (0) * (1000000) / (a7hal_clock_getFreq (0) / 16));
+}
+
+void
+ta7_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
+{
+  do_timer (regs);
+  a7hal_timer_clearInt (0);
+}
diff -urN linux-2.4.29/arch/armnommu/mach-vc547x/dma.c linux-2.4.29-uc1/arch/armnommu/mach-vc547x/dma.c
--- linux-2.4.29/arch/armnommu/mach-vc547x/dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-vc547x/dma.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,42 @@
+/***********************************************************************
+ *  linux/arch/arm/mach-c5471/dma.c
+ *
+ *   Copyright (C) 2003 Cadenux, LLC. All rights reserved.
+ *   todd.fischer@cadenux.com  <www.cadenux.com>
+ *
+ *   Copyright (C) 2001 RidgeRun, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/dma.h>
+
+void __init arch_dma_init(dma_t *dma)
+{
+  /* No special initial setup is required for the c5471.
+   */
+}
diff -urN linux-2.4.29/arch/armnommu/mach-vc547x/irq.c linux-2.4.29-uc1/arch/armnommu/mach-vc547x/irq.c
--- linux-2.4.29/arch/armnommu/mach-vc547x/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-vc547x/irq.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,139 @@
+/***********************************************************************
+ *  linux/arch/armnommu/mach-c5471/irq.c
+ *
+ *   C5471 IRQ mask, unmask & ack routines.
+ *
+ *   Copyright (C) 2003 Cadenux, LLC. All rights reserved.
+ *   todd.fischer@cadenux.com  <www.cadenux.com>
+ *
+ *   Copyright (C) 2001 RidgeRun, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <asm/arch/irq.h>
+#include <asm/arch/hardware.h>
+
+#define EdgeSensitive 0x00000020
+#define Priority      0x0000001E
+
+#define REG32(addr) *((volatile unsigned long*)(addr))
+
+/* Acknowlede the IRQ.
+ *
+ * Bit 0 of the Interrupt Control Rigster ==  New IRQ agreement (NEW_IRQ_AGR).
+ * Reset IRQ output. Clear source IRQ register. Enables a new IRQ
+ * generation. Reset by internal logic.
+ */
+
+static inline void irq_ack(unsigned int irq)
+{
+  unsigned long reg;
+  reg = REG32(SRC_IRQ_REG);          /* Insure appropriate IT_REG bit clears */
+  REG32(INT_CTRL_REG) |= 0x00000001; /* write the NEW_IRQ_AGR bit. */
+}
+
+/* Acknowledge the FIQ.
+ *
+ * Bit 1 of the Interrupt Control Rigster ==  New FIQ agreement (NEW_FIQ_AGR).
+ * Reset FIQ output. Clear source FIQ register. Enables a new FIQ
+ * generation. Reset by internal logic.
+ */
+
+static inline void fiq_ack(unsigned int irq)
+{
+  unsigned long reg;
+  reg = REG32(SRC_FIQ_REG);          /* Insure appropriate IT_REG bit clears */
+  REG32(INT_CTRL_REG) |= 0x00000002; /* write the NEW_FIQ_AGR bit. */
+}
+
+/* Mask the IRQ. */
+
+void c5471_mask_irq(unsigned int irq)
+{
+  REG32(MASK_IT_REG) |= (1 << irq);
+}
+
+/* Unmask the IRQ */
+
+void c5471_unmask_irq(unsigned int irq)
+{
+  REG32(MASK_IT_REG) &= ~(1 << irq);
+}
+
+/* Mask the IRQ and acknowledge it.
+ * 
+ * Bit 0 of the Interrupt Control Rigster ==  New IRQ agreement (NEW_IRQ_AGR).
+ * Reset IRQ output. Clear source IRQ register. Enables a new IRQ
+ * generation. Reset by internal logic.
+ *
+ * IRQ (FIQ) output and SRC_IRQ_REG and SRC_IRQ_BIN_REG
+ * (SRC_FIQ_REG) registers are reset only if the bit in the
+ * Interrupt register (IT_REG) corresponding to the interrupt
+ * having requested MCU action is already cleared or masked.
+ *
+ * For an edge-sensitive interrupt, the Interrupt register bit is
+ * deactivated when reading the SRC_IRQ_REG or SRC_IRQ_BIN_REG
+ * (SRC_FIQ_REG) registers.
+ */
+
+void c5471_mask_ack_irq(unsigned int irq)
+{
+  REG32(MASK_IT_REG)  |= (1 << irq); /* Make sure the interrupt is masked. */
+  REG32(INT_CTRL_REG) |= 0x00000001; /* write the NEW_IRQ_AGR bit. */
+}
+
+void c5471_init_irq(void)
+{
+  /* Disable all interrupts. */
+
+  REG32(MASK_IT_REG) = 0x0000ffff;
+
+  /* Clear any pending interrupts */
+
+  irq_ack(0);
+  fiq_ack(0);
+  REG32(IT_REG) = 0x00000000;
+
+  /* Override hardware defaults */
+
+  REG32(ILR_IRQ2_REG)  = EdgeSensitive | Priority;
+  REG32(ILR_IRQ4_REG)  = EdgeSensitive | Priority;
+  REG32(ILR_IRQ6_REG)  = Priority;
+  REG32(ILR_IRQ15_REG) = EdgeSensitive | Priority;
+
+  /* Finally, be a good citizen and do what it takes to insure
+   * the user gets accurate info if they type "cat /proc/ioports"
+   */
+
+  request_region(INT_FIRST_IO, INT_IO_RANGE, "interrupt controller");
+}
diff -urN linux-2.4.29/arch/armnommu/mach-vc547x/Makefile linux-2.4.29-uc1/arch/armnommu/mach-vc547x/Makefile
--- linux-2.4.29/arch/armnommu/mach-vc547x/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-vc547x/Makefile	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= vc547x.o
+
+# Object file lists.
+
+obj-y			:= $(patsubst %.c, %.o, $(wildcard *.c))
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= 
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/armnommu/mach-vc547x/mm.c linux-2.4.29-uc1/arch/armnommu/mach-vc547x/mm.c
--- linux-2.4.29/arch/armnommu/mach-vc547x/mm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-vc547x/mm.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,77 @@
+/***********************************************************************
+ * linux/arch/armnommu/mach-c5471/mm.c
+ *
+ * Based on linux/drivers/net/isa-skeleton.c from the linux-2.4.17
+ * and on the linux/drivers/net/skeleton.c from the linux 2.0.38
+ * distribution:
+ *
+ *  Copyright (C) 1998-1999 Russell King
+ *  Copyright (C) 1999 Hugo Fiennes
+ *  Copyright (C) 2001 RidgeRun, Inc
+ *  Copyright (C) 2003 Cadenux, LLC.
+ *
+ *  Extra MM routines for the SA1100 architecture
+ *
+ *  1999/12/04 Nicolas Pitre <nico@cam.org>
+ *	Converted memory definition for struct meminfo initialisations.
+ *	Memory is listed physically now.
+ *
+ *  2000/04/07 Nicolas Pitre <nico@cam.org>
+ *	Reworked for run-time selection of memory definitions
+ *
+ *  2001/02/19 Gordon McNutt <gmcnutt@ridgerun.com>
+ *      Modified mm-sa1100.c to make this, mm-dsc21.c.
+ *
+ *  2002 Gregory Nutt <greg.nutt@cadenux.com>
+ *      Modified mm-dsc21.c for the c5471
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/map.h>
+ 
+#ifdef CONFIG_DISCONTIGMEM
+
+/*
+ * Our node_data structure for discontigous memory.
+ * There is 4 possible nodes i.e. the 4 SA1100 RAM banks.
+ */
+
+static bootmem_data_t node_bootmem_data[4];
+
+pg_data_t c5471_node_data[4] =
+{ { bdata: &node_bootmem_data[0] },
+  { bdata: &node_bootmem_data[1] },
+  { bdata: &node_bootmem_data[2] },
+  { bdata: &node_bootmem_data[3] } };
+
+#endif
diff -urN linux-2.4.29/arch/armnommu/mach-vc547x/time.c linux-2.4.29-uc1/arch/armnommu/mach-vc547x/time.c
--- linux-2.4.29/arch/armnommu/mach-vc547x/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mach-vc547x/time.c	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,118 @@
+/***********************************************************************
+ * linux/arch/armnommu/mach-c5471/time.c
+ *
+ *   Copyright (C) 2003 Cadenux, LLC. All rights reserved.
+ *   todd.fischer@cadenux.com  <www.cadenux.com>
+ *
+ *   Copyright (C) 2001 RidgeRun, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+/* Included Files */
+
+#include <linux/spinlock.h>  /* spinlock_t needed by linux/interrupt.h */
+#include <asm/system.h>      /* smp_mb() needed by linux/interrupt.h */
+#include <linux/interrupt.h> /* For struct irqaction */
+
+#include <linux/ioport.h>    /* For request_region */
+#include <linux/time.h>      /* struct timeval needed by linux/timex.h */
+#include <linux/timex.h>     /* For tick */
+#include <linux/sched.h>     /* For do_timer() */
+
+#include <asm/io.h>          /* For IO macros */
+#include <asm/hardware.h>    /* For c547x "Orion" register definitions */
+#include <asm/irq.h>         /* For IRQ_TIMER */
+
+#include <asm/mach/irq.h>    /* For setup_arm_irq */
+
+/* Definitions */
+
+#define COUNTS_PER_INTERRUPT 29687
+#define CNTL_TIMER2 ((volatile unsigned long *)0xffff2c00)
+#define COUNTS_PER_INTERRUPT_field_shift 5
+#define AR  0x00000010
+#define ST  0x00000008
+#define PTV 0x00000003
+
+unsigned int test_bss = 0x12345;
+
+/* Global data */
+
+extern unsigned long (*gettimeoffset)(void);
+
+static unsigned long c5471_gettimeoffset(void)
+{
+  unsigned long elapsed;
+
+  /* Compute the elapsed count since the last interrupt.
+   * Our counter counts down starting at COUNTS_PER_INTERRUPT.
+   */
+
+  elapsed = COUNTS_PER_INTERRUPT - inl(C5471_TIMER2_CNT);
+  
+   /* Convert the elapsed count to usecs. 'tick' is assigned in sched.c.
+    * Normally it's 10,000 -- the # of usecs/interrupt.
+    */
+
+  return (unsigned long)((elapsed * tick) / COUNTS_PER_INTERRUPT);
+}
+
+static void c5471_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+  do_timer(regs);
+}
+
+void c5471_setup_timer(struct irqaction *timer_irq)
+{
+  /* Configure timer.c so that c5471_gettimeoffset will be used
+   * to get the elapsed microseconds between interrupts.
+   */
+
+  gettimeoffset = c5471_gettimeoffset;
+
+  /* Capture the interrupt through c5471_timer_interrupt */
+
+  timer_irq->handler = c5471_timer_interrupt;
+  setup_arm_irq(IRQ_TIMER, timer_irq);
+
+  /* Start the general purpose timer running in auto-reload mode
+   * so that an interrupt is generated at the rate of HZ (param.h)
+   * which typically is set to 100HZ.
+   * When HZ is set to 100 then COUNTS_PER_INTERRUPT should be
+   * established to reflect timer counts that occur every 10ms
+   * (giving you 100 of them per second -- 100HZ). Orion's clock
+   * is 47.5MHz and we're using a timer PTV value of 3 (3 == divide
+   * incoming frequency by 16) which then yields a 16 bit
+   * COUNTS_PER_INTERRUPT value of 29687.
+   */
+
+  *CNTL_TIMER2 = (((COUNTS_PER_INTERRUPT-1)<<COUNTS_PER_INTERRUPT_field_shift) | AR | ST | PTV);
+
+  /* Finally, be a good citizen and do what it takes to insure
+   * the user gets accurate info if they type "cat /proc/ioports"
+   */
+
+  request_region((unsigned long)CNTL_TIMER2, 0x8, "system timer (TIMER2)");
+}
+
+
diff -urN linux-2.4.29/arch/armnommu/Makefile linux-2.4.29-uc1/arch/armnommu/Makefile
--- linux-2.4.29/arch/armnommu/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,422 @@
+#
+# arch/armnommu/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995-2001 by Russell King
+# Addition of
+#  (c) Copyright 2001-2002 - S3C4530 by Arcturus Networks Inc.
+#  (c) Copyright 2002-2003 - S3C2500 by Arcturus Networks Inc.
+#  
+
+LINKFLAGS	:=-p -X -T arch/armnommu/vmlinux.lds
+GZFLAGS		:=-9
+CFLAGS		+=-fno-common -pipe -fno-builtin -D__linux__
+
+ifneq ($(CONFIG_NO_FRAME_POINTER),y)
+CFLAGS		:=$(CFLAGS:-fomit-frame-pointer=)
+endif
+
+ifeq ($(CONFIG_DEBUG_INFO),y)
+CFLAGS		+=-g
+endif
+
+CFLAGS += -DNO_MM
+AFLAGS += -DNO_MM
+
+# Select CPU dependent flags.  Note that order of declaration is important;
+# the options further down the list override previous items.
+#
+apcs-$(CONFIG_CPU_26)		:=-mapcs-26 -mcpu=arm3 -Os
+apcs-$(CONFIG_CPU_32)		:=-mapcs-32
+
+arch-$(CONFIG_CPU_32v3)		:=-march=armv3
+arch-$(CONFIG_CPU_32v4)		:=-march=armv4
+arch-$(CONFIG_CPU_32v5)		:=-march=armv5
+
+proc-$(CONFIG_CPU_32v3)		:=-march=armv3m
+proc-$(CONFIG_CPU_32v4)		:=-march=armv4
+proc-$(CONFIG_CPU_32v5)		:=-march=armv5
+
+tune-$(CONFIG_CPU_ARM7V3)	:=-mtune=arm610
+tune-$(CONFIG_CPU_ARM610)	:=-mtune=arm610
+#tune-$(CONFIG_CPU_ARM710)	:=-mtune=arm710
+tune-$(CONFIG_CPU_ARM710)	:=-mtune=arm7tdmi
+tune-$(CONFIG_CPU_ARM720T)	:=-mtune=arm7tdmi
+tune-$(CONFIG_CPU_ARM740T)	:=-mtune=arm7tdmi
+tune-$(CONFIG_CPU_ARM920T)	:=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_SA110)	:=-mtune=strongarm110
+tune-$(CONFIG_CPU_SA1100)	:=-mtune=strongarm1100
+
+ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
+CFLAGS    	+= -mbig-endian
+AFLAGS		+= -mbig-endian
+LINKFLAGS	+= -EB
+LDFLAGS		+= -EB
+endif
+
+CFLAGS		+= $(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float
+AFLAGS		+= $(apcs-y) $(proc-y) -msoft-float -mno-fpu
+
+LIBGCC		:= $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
+
+ifeq ($(CONFIG_CPU_26),y)
+PROCESSOR	 = armo
+TEXTADDR	 = 0x02080000
+endif
+
+ifeq ($(CONFIG_CPU_32),y)
+PROCESSOR	 = armv
+TEXTADDR	 = 0xC0008000
+endif
+
+ifeq ($(CONFIG_ARCH_ARCA5K),y)
+MACHINE		 = arc
+endif
+
+ifeq ($(CONFIG_ARCH_RPC),y)
+MACHINE		 = rpc
+endif
+
+ifeq ($(CONFIG_ARCH_EBSA110),y)
+MACHINE		 = ebsa110
+endif
+
+ifeq ($(CONFIG_ARCH_CLPS7500),y)
+MACHINE		 = clps7500
+INCDIR		 = cl7500
+endif
+
+ifeq ($(CONFIG_FOOTBRIDGE),y)
+MACHINE		 = footbridge
+INCDIR		 = ebsa285
+endif
+
+ifeq ($(CONFIG_ARCH_CO285),y)
+TEXTADDR	 = 0x60008000
+MACHINE		 = footbridge
+INCDIR		 = ebsa285
+endif
+
+ifeq ($(CONFIG_ARCH_NEXUSPCI),y)
+MACHINE		 = nexuspci
+endif
+
+ifeq ($(CONFIG_ARCH_SHARK),y)
+MACHINE		 = shark
+endif
+
+ifeq ($(CONFIG_ARCH_SA1100),y)
+ifeq ($(CONFIG_SA1111),y)
+# SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory
+TEXTADDR	 = 0xc0208000
+endif
+MACHINE		 = sa1100
+endif
+
+ifeq ($(CONFIG_ARCH_L7200),y)
+MACHINE		 = l7200
+endif
+
+ifeq ($(CONFIG_ARCH_INTEGRATOR),y)
+MACHINE		 = integrator
+TEXTADDR	 = 0x00008000
+endif
+
+ifeq ($(CONFIG_ARCH_CLPS711X),y)
+TEXTADDR	 = 0xc0018000
+MACHINE		 = clps711x
+endif
+
+ifeq ($(CONFIG_ARCH_DSC21),y)
+MACHINE 	 = dsc21
+TEXTADDR	 = 0x02000000
+DATAADDR	 = 0x08000000
+INCDIR		 = dsc21
+#LINKFLAGS	 = -X -T arch/armnommu/vmlinux.lds
+endif
+
+ifeq ($(CONFIG_ARCH_P52),y)
+TEXTADDR	 = 0x900000
+MACHINE		 = p52
+CFLAGS		+= -DNO_MM -DMAGIC_ROM_PTR
+endif
+
+ifeq ($(CONFIG_ARCH_CX821XX),y)
+MACHINE		= cx821xx
+TEXTADDR	= 0x800000
+CFLAGS		+= -DNO_MM -DMAGIC_ROM_PTR
+#LINKFLAGS	+= -T arch/armnommu/mach-$(MACHINE)/ramlinux.lds
+endif
+
+ifeq ($(CONFIG_ARCH_SPIPE),y)
+TEXTADDR	 = 0x808000
+MACHINE		 = spipe
+endif
+
+ifeq ($(CONFIG_ARCH_ATMEL),y)
+TEXTADDR	= 0x1000000
+MACHINE		= atmel
+endif
+
+ifeq ($(CONFIG_ARCH_NETARM),y)
+MACHINE 	 = netarm
+# This allows it to use the internal bootloader.
+TEXTADDR	 = 0x00000000
+INCDIR  	 = netarm
+CFLAGS		+= -mcpu=arm7tdmi
+#LINKFLAGS	 = -X -T arch/armnommu/vmlinux.lds
+endif
+
+ifeq ($(CONFIG_ARCH_TA7S),y)
+  ifeq ($(CONFIG_USE_A7HAL),y)
+    CFLAGS += -I$(HPATH)/asm/arch/a7hal \
+	  -I$(HPATH)/asm/arch/a7hal/soft
+  endif
+  PROCESSOR	 = armv
+  MACHINE 	 = ta7s
+  TEXTADDR	 = 0x00000000
+  INCDIR  	 = ta7s
+endif
+
+ifeq ($(CONFIG_ARCH_TA7V),y)
+  ifeq ($(CONFIG_ARCH_TA7VL),y)
+	CFLAGS += -DA7VL
+  endif
+  ifeq ($(CONFIG_ARCH_TA7VE),y)
+	CFLAGS += -DA7VE
+  endif
+  ifeq ($(CONFIG_ARCH_TA7VC),y)
+	CFLAGS += -DA7VC
+  endif
+  ifeq ($(CONFIG_ARCH_TA7VT),y)
+	CFLAGS += -DA7VT
+  endif
+  ifeq ($(CONFIG_USE_A7HAL),y)
+    CFLAGS += -I$(HPATH)/asm/arch/a7hal \
+	  -I$(HPATH)/asm/arch/a7hal/soft
+  endif
+  PROCESSOR	 = armv
+  MACHINE 	 = ta7s
+  TEXTADDR	 = 0x00000000
+  INCDIR  	 = ta7s
+endif
+
+ifeq ($(CONFIG_ARCH_SWARM),y)
+MACHINE    = swarm
+TEXTADDR   = 0x00008000
+endif
+
+ifeq ($(CONFIG_BOARD_SNDS100),y)
+TEXTADDR   	 = 0x00008000
+MACHINE    	 = snds100
+endif
+
+ifeq ($(CONFIG_BOARD_EVS3C4530HEI),y)
+TEXTADDR         = 0x00020000
+MACHINE          = evS3C4530HEI
+#INCDIR           = $(MACHINE)
+endif
+
+ifeq ($(CONFIG_BOARD_SMDK2500),y)
+MACHINE		= SMDK2500
+#INCDIR		= $(MACHINE)
+TEXTADDR	= 0x20000
+endif
+
+ifeq ($(CONFIG_BOARD_S3C2500REFRGP),y)
+MACHINE		= S3C2500REFRGP
+#INCDIR		= $(MACHINE)
+TEXTADDR	= 0x20000
+endif
+
+ifeq ($(CONFIG_BOARD_SMDK40100),y)
+TEXTADDR   	 = 0x01020000
+MACHINE          = S3C3410
+INCDIR           = $(MACHINE)
+endif
+
+ifeq ($(CONFIG_BOARD_MBA44),y)
+TEXTADDR   	 = 0x0c000000
+MACHINE          = S3C44B0X
+INCDIR           = $(MACHINE)
+CORE_FILES	:= $(CORE_FILES) romfs.o
+endif
+
+ifeq ($(CONFIG_ARCH_VC547X), y)
+TEXTADDR	= 0x10000000
+MACHINE         = vc547x
+endif
+
+ifeq ($(CONFIG_ARCH_DM270), y)
+TEXTADDR	= 0x01230000
+MACHINE		= dm270
+endif
+
+ifeq ($(CONFIG_ARCH_POLDHU),y)
+TEXTADDR	= 0x08040000
+MACHINE		= poldhu
+endif
+                                                                                
+ifeq ($(CONFIG_ARCH_ISL3893),y)
+TEXTADDR	= 0x00040000
+MACHINE		= isl3893
+endif
+
+ifeq ($(CONFIG_ARCH_IPOD),y)
+MACHINE		 = ipod
+TEXTADDR	 = 0x28008000
+endif
+
+export	LDFLAGS LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS
+
+# Only set INCDIR if its not already defined above
+# Grr, ?= doesn't work as all the other assignment operators do.  Make bug?
+ifeq ($(origin INCDIR), undefined)
+INCDIR		:= $(MACHINE)
+endif
+
+# If we have a machine-specific directory, then include it in the build.
+MACHDIR		:= arch/armnommu/mach-$(MACHINE)
+ifeq ($(MACHDIR),$(wildcard $(MACHDIR)))
+SUBDIRS		+= $(MACHDIR)
+CORE_FILES	:= $(MACHDIR)/$(MACHINE).o $(CORE_FILES)
+endif
+
+HEAD		:= arch/armnommu/kernel/head-$(PROCESSOR).o
+ifeq ($(CONFIG_ARCH_DSC21),y)
+HEAD		:= arch/armnommu/kernel/head-arm-dsc21.o
+endif
+ifeq ($(CONFIG_ARCH_VC547X),y)
+HEAD		:= arch/armnommu/kernel/head-arm-vc547x.o
+endif
+HEAD		+= arch/armnommu/kernel/init_task.o
+
+SUBDIRS		+= arch/armnommu/kernel arch/armnommu/mm arch/armnommu/lib arch/armnommu/nwfpe
+CORE_FILES	:= arch/armnommu/kernel/kernel.o arch/armnommu/mm/mm.o $(CORE_FILES)
+LIBS		:= arch/armnommu/lib/lib.a $(LIBS) $(LIBGCC)
+
+ifeq ($(CONFIG_NWFPE),y)
+LIBS		:= arch/armnommu/nwfpe/math-emu.o $(LIBS)
+endif
+
+ifeq ($(CONFIG_ARCH_CLPS7500),y)
+SUBDIRS		+= drivers/acorn/char
+DRIVERS		+= drivers/acorn/char/acorn-char.o
+endif
+
+ifeq ($(CONFIG_ARCH_NETARM),y)
+HEAD		:= arch/armnommu/kernel/head-arm-netarm.o \
+		   arch/armnommu/kernel/init_task.o
+endif
+
+ifeq ($(CONFIG_ARCH_IPOD),y)
+HEAD		:= arch/armnommu/kernel/head-arm-ipod.o \
+		   arch/armnommu/kernel/init_task.o
+endif
+
+#
+# If you want the kernel build to build modules outside of the tree
+# then define this and pass it to the main linux makefile
+#
+ifdef EXTRA_MODULE_DIRS
+SUBDIRS += $(EXTRA_MODULE_DIRS)
+endif
+
+MAKEBOOT	 = $(MAKE) -C arch/$(ARCH)/boot LINUX=$(LINUX)
+MAKETOOLS	 = $(MAKE) -C arch/$(ARCH)/tools LINUX=$(LINUX)
+
+# The following is a hack to get 'constants.h' up
+# to date before starting compilation
+
+$(patsubst %,_dir_%, $(SUBDIRS)): maketools
+$(patsubst %,_modsubdir_%,$(MOD_DIRS)): maketools
+
+symlinks: archsymlinks
+
+archsymlinks:
+	$(RM) include/asm-armnommu/arch include/asm-armnommu/proc
+	(cd include/asm-armnommu; ln -sf arch-$(INCDIR) arch; ln -sf proc-$(PROCESSOR) proc)
+
+$(LINUX): arch/armnommu/vmlinux.lds
+
+arch/armnommu/vmlinux.lds: arch/armnommu/vmlinux-$(PROCESSOR).lds.in dummy
+ifeq ($(CONFIG_ARCH_DSC21),y)
+	@sed 's/TEXTADDR/$(TEXTADDR)/' <$< >tmp.ld
+	@sed 's/DATAADDR/$(DATAADDR)/' <tmp.ld >$@
+	$(RM) tmp.ld
+else
+ifeq ($(CONFIG_ARCH_VC547X),y)
+#HK:	@sed 's/TEXTADDR/$(FLASH_MEM_BASE)/;s/DATAADDR/$(DRAM_BASE)/' <$< >$@
+	@sed 's/TEXTADDR/$(TEXTADDR)/;s/DATAADDR/$(DRAM_BASE)/' <$< >$@
+else
+	@sed 's/TEXTADDR/$(TEXTADDR)/' <$< >$@
+endif
+endif
+
+arch/armnommu/kernel arch/armnommu/mm arch/armnommu/lib: dummy
+	$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@)
+
+bzImage zImage zinstall Image bootpImage install: $(LINUX)
+	@$(MAKEBOOT) $@
+
+CLEAN_FILES	+= \
+	arch/armnommu/vmlinux.lds \
+	include/asm-armnommu/constants.h* \
+	include/asm-armnommu/mach-types.h
+
+MRPROPER_FILES	+= \
+	include/asm-armnommu/arch \
+	include/asm-armnommu/proc
+
+# We use MRPROPER_FILES and CLEAN_FILES now
+archmrproper:
+	@/bin/true
+
+archclean:
+	@$(MAKEBOOT) clean
+
+archdep: scripts/mkdep archsymlinks
+	@$(MAKETOOLS) dep
+	@$(MAKEBOOT) dep
+
+maketools: checkbin
+	@$(MAKETOOLS) all
+
+# Ensure this is ld "2.9.4" or later
+NEW_LINKER	:= $(shell $(LD) --gc-sections --version >/dev/null 2>&1; echo $$?)
+
+ifneq ($(NEW_LINKER),0)
+checkbin:
+	@echo '*** ${VERSION}.${PATCHLEVEL} kernels no longer build correctly with old versions of binutils.'
+	@echo '*** Please upgrade your binutils to 2.9.5.'
+	@false
+else
+checkbin:
+	@true
+endif
+
+# My testing targets (that short circuit a few dependencies)
+zImg:;	@$(MAKEBOOT) zImage
+Img:;	@$(MAKEBOOT) Image
+i:;	@$(MAKEBOOT) install
+zi:;	@$(MAKEBOOT) zinstall
+bp:;	@$(MAKEBOOT) bootpImage
+
+#
+# Configuration targets.  Use these to select a
+# configuration for your architecture
+%_config:
+	@( \
+	CFG=$(@:_config=); \
+	if [ -f arch/armnommu/def-configs/$$CFG ]; then \
+	  $(RM) arch/armnommu/defconfig; \
+	  cp arch/armnommu/def-configs/$$CFG arch/armnommu/defconfig; \
+	  echo "*** Default configuration for $$CFG installed"; \
+	  echo "*** Next, you may run 'make oldconfig'"; \
+	else \
+	  echo "$$CFG does not exist"; \
+	fi; \
+	)
diff -urN linux-2.4.29/arch/armnommu/mm/consistent.c linux-2.4.29-uc1/arch/armnommu/mm/consistent.c
--- linux-2.4.29/arch/armnommu/mm/consistent.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/consistent.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,161 @@
+/*
+ *  linux/arch/arm/mm/consistent.c
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Dynamic DMA mapping support.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+
+/*
+ * This allocates one page of cache-coherent memory space and returns
+ * both the virtual and a "dma" address to that space.  It is not clear
+ * whether this could be called from an interrupt context or not.  For
+ * now, we expressly forbid it, especially as some of the stuff we do
+ * here is not interrupt context safe.
+ *
+ * Note that this does *not* zero the allocated area!
+ */
+void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
+{
+	struct page *page, *end, *free;
+	unsigned long order;
+	void *ret, *virt;
+
+	if (in_interrupt())
+		BUG();
+
+	size = PAGE_ALIGN(size);
+	order = get_order(size);
+
+	page = alloc_pages(gfp, order);
+	if (!page)
+		goto no_page;
+
+	/*
+	 * We could do with a page_to_phys and page_to_bus here.
+	 */
+	virt = page_address(page);
+	*dma_handle = virt_to_bus(virt);
+	ret = __ioremap(virt_to_phys(virt), size, 0);
+	if (!ret)
+		goto no_remap;
+
+#if 0 /* ioremap_does_flush_cache_all */
+	/*
+	 * we need to ensure that there are no cachelines in use, or
+	 * worse dirty in this area.  Really, we don't need to do
+	 * this since __ioremap does a flush_cache_all() anyway. --rmk
+	 */
+	invalidate_dcache_range(virt, virt + size);
+#endif
+
+	/*
+	 * free wasted pages.  We skip the first page since we know
+	 * that it will have count = 1 and won't require freeing.
+	 * We also mark the pages in use as reserved so that
+	 * remap_page_range works.
+	 */
+	page = virt_to_page(virt);
+	free = page + (size >> PAGE_SHIFT);
+	end  = page + (1 << order);
+
+	for (; page < end; page++) {
+		set_page_count(page, 1);
+		if (page >= free)
+			__free_page(page);
+		else
+			SetPageReserved(page);
+	}
+	return ret;
+
+no_remap:
+	__free_pages(page, order);
+no_page:
+	return NULL;
+}
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *handle)
+{
+	void *__ret;
+	int __gfp = GFP_KERNEL;
+
+#ifndef CONFIG_ARCH_ISL3893
+#ifdef CONFIG_PCI
+	if ((hwdev) == NULL ||
+	    (hwdev)->dma_mask != 0xffffffff)
+#endif
+		__gfp |= GFP_DMA;
+#endif
+
+	__ret = consistent_alloc(__gfp, (size),
+				 (handle));
+	return __ret;
+}
+
+/*
+ * free a page as defined by the above mapping.  We expressly forbid
+ * calling this from interrupt context.
+ */
+void consistent_free(void *vaddr, size_t size, dma_addr_t handle)
+{
+	struct page *page, *end;
+	void *virt;
+
+	if (in_interrupt())
+		BUG();
+
+	virt = bus_to_virt(handle);
+
+	/*
+	 * More messing around with the MM internals.  This is
+	 * sick, but then so is remap_page_range().
+	 */
+	size = PAGE_ALIGN(size);
+	page = virt_to_page(virt);
+	end = page + (size >> PAGE_SHIFT);
+
+	for (; page < end; page++)
+		ClearPageReserved(page);
+
+	__iounmap(vaddr);
+}
+
+/*
+ * make an area consistent.
+ */
+void consistent_sync(void *vaddr, size_t size, int direction)
+{
+	unsigned long start = (unsigned long)vaddr;
+	unsigned long end   = start + size;
+
+	switch (direction) {
+	case PCI_DMA_NONE:
+		BUG();
+	case PCI_DMA_FROMDEVICE:	/* invalidate only */
+		invalidate_dcache_range(start, end);
+		break;
+	case PCI_DMA_TODEVICE:		/* writeback only */
+		clean_dcache_range(start, end);
+		break;
+	case PCI_DMA_BIDIRECTIONAL:	/* writeback and invalidate */
+		flush_dcache_range(start, end);
+		break;
+	}
+}
diff -urN linux-2.4.29/arch/armnommu/mm/csumpartialcopygeneric.S linux-2.4.29-uc1/arch/armnommu/mm/csumpartialcopygeneric.S
--- linux-2.4.29/arch/armnommu/mm/csumpartialcopygeneric.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/csumpartialcopygeneric.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,327 @@
+/*
+ *  linux/arch/arm/lib/csumpartialcopygeneric.S
+ *
+ *  Copyright (C) 1995-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * unsigned int
+ * csum_partial_copy_xxx(const char *src, char *dst, int len, int sum, )
+ *  r0 = src, r1 = dst, r2 = len, r3 = sum
+ *  Returns : r0 = checksum
+ *
+ * Note that 'tst' and 'teq' preserve the carry flag.
+ */
+
+src	.req	r0
+dst	.req	r1
+len	.req	r2
+sum	.req	r3
+
+.zero:		mov	r0, sum
+		load_regs	ea
+
+		/*
+		 * Align an unaligned destination pointer.  We know that
+		 * we have >= 8 bytes here, so we don't need to check
+		 * the length.  Note that the source pointer hasn't been
+		 * aligned yet.
+		 */
+.dst_unaligned:	tst	dst, #1
+		beq	.dst_16bit
+
+		load1b	ip
+		sub	len, len, #1
+		adcs	sum, sum, ip, lsl #8	@ update checksum
+		strb	ip, [dst], #1
+		tst	dst, #2
+		moveq	pc, lr			@ dst is now 32bit aligned
+
+.dst_16bit:	load2b	r8, ip
+		sub	len, len, #2
+		adcs	sum, sum, r8
+		strb	r8, [dst], #1
+		adcs	sum, sum, ip, lsl #8
+		strb	ip, [dst], #1
+		mov	pc, lr			@ dst is now 32bit aligned
+
+		/*
+		 * Handle 0 to 7 bytes, with any alignment of source and
+		 * destination pointers.  Note that when we get here, C = 0
+		 */
+.less8:		teq	len, #0			@ check for zero count
+		beq	.zero
+
+		/* we must have at least one byte. */
+		tst	dst, #1			@ dst 16-bit aligned
+		beq	.less8_aligned
+
+		/* Align dst */
+		load1b	ip
+		sub	len, len, #1
+		adcs	sum, sum, ip, lsl #8	@ update checksum
+		strb	ip, [dst], #1
+		tst	len, #6
+		beq	.less8_byteonly
+
+1:		load2b	r8, ip
+		sub	len, len, #2
+		adcs	sum, sum, r8
+		strb	r8, [dst], #1
+		adcs	sum, sum, ip, lsl #8
+		strb	ip, [dst], #1
+.less8_aligned:	tst	len, #6
+		bne	1b
+.less8_byteonly:
+		tst	len, #1
+		beq	.done
+		load1b	r8
+		adcs	sum, sum, r8		@ update checksum
+		strb	r8, [dst], #1
+		b	.done
+
+FN_ENTRY
+		mov	ip, sp
+		save_regs
+		sub	fp, ip, #4
+
+		cmp	len, #8			@ Ensure that we have at least
+		blo	.less8			@ 8 bytes to copy.
+
+		adds	sum, sum, #0		@ C = 0
+		tst	dst, #3			@ Test destination alignment
+		blne	.dst_unaligned		@ align destination, return here
+
+		/*
+		 * Ok, the dst pointer is now 32bit aligned, and we know
+		 * that we must have more than 4 bytes to copy.  Note
+		 * that C contains the carry from the dst alignment above.
+		 */
+
+		tst	src, #3			@ Test source alignment
+		bne	.src_not_aligned
+
+		/* Routine for src & dst aligned */
+
+		bics	ip, len, #15
+		beq	2f
+
+1:		load4l	r4, r5, r6, r7
+		stmia	dst!, {r4, r5, r6, r7}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		adcs	sum, sum, r6
+		adcs	sum, sum, r7
+		sub	ip, ip, #16
+		teq	ip, #0
+		bne	1b
+
+2:		ands	ip, len, #12
+		beq	4f
+		tst	ip, #8
+		beq	3f
+		load2l	r4, r5
+		stmia	dst!, {r4, r5}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		tst	ip, #4
+		beq	4f
+
+3:		load1l	r4
+		str	r4, [dst], #4
+		adcs	sum, sum, r4
+
+4:		ands	len, len, #3
+		beq	.done
+		load1l	r4
+		tst	len, #2
+		beq	.exit
+		adcs	sum, sum, r4, lsl #16
+		strb	r4, [dst], #1
+		mov	r4, r4, lsr #8
+		strb	r4, [dst], #1
+		mov	r4, r4, lsr #8
+.exit:		tst	len, #1
+		strneb	r4, [dst], #1
+		andne	r4, r4, #255
+		adcnes	sum, sum, r4
+
+		/*
+		 * If the dst pointer was not 16-bit aligned, we
+		 * need to rotate the checksum here to get around
+		 * the inefficient byte manipulations in the
+		 * architecture independent code.
+		 */
+.done:		adc	r0, sum, #0
+		ldr	sum, [sp, #0]		@ dst
+		tst	sum, #1
+		movne	sum, r0, lsl #8
+		orrne	r0, sum, r0, lsr #24
+		load_regs	ea
+
+.src_not_aligned:
+		adc	sum, sum, #0		@ include C from dst alignment
+		and	ip, src, #3
+		bic	src, src, #3
+		load1l	r4
+		cmp	ip, #2
+		beq	.src2_aligned
+		bhi	.src3_aligned
+		mov	r4, r4, lsr #8		@ C = 0
+		bics	ip, len, #15
+		beq	2f
+1:		load4l	r5, r6, r7, r8
+		orr	r4, r4, r5, lsl #24
+		mov	r5, r5, lsr #8
+		orr	r5, r5, r6, lsl #24
+		mov	r6, r6, lsr #8
+		orr	r6, r6, r7, lsl #24
+		mov	r7, r7, lsr #8
+		orr	r7, r7, r8, lsl #24
+		stmia	dst!, {r4, r5, r6, r7}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		adcs	sum, sum, r6
+		adcs	sum, sum, r7
+		mov	r4, r8, lsr #8
+		sub	ip, ip, #16
+		teq	ip, #0
+		bne	1b
+2:		ands	ip, len, #12
+		beq	4f
+		tst	ip, #8
+		beq	3f
+		load2l	r5, r6
+		orr	r4, r4, r5, lsl #24
+		mov	r5, r5, lsr #8
+		orr	r5, r5, r6, lsl #24
+		stmia	dst!, {r4, r5}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		mov	r4, r6, lsr #8
+		tst	ip, #4
+		beq	4f
+3:		load1l	r5
+		orr	r4, r4, r5, lsl #24
+		str	r4, [dst], #4
+		adcs	sum, sum, r4
+		mov	r4, r5, lsr #8
+4:		ands	len, len, #3
+		beq	.done
+		tst	len, #2
+		beq	.exit
+		adcs	sum, sum, r4, lsl #16
+		strb	r4, [dst], #1
+		mov	r4, r4, lsr #8
+		strb	r4, [dst], #1
+		mov	r4, r4, lsr #8
+		b	.exit
+
+.src2_aligned:	mov	r4, r4, lsr #16
+		adds	sum, sum, #0
+		bics	ip, len, #15
+		beq	2f
+1:		load4l	r5, r6, r7, r8
+		orr	r4, r4, r5, lsl #16
+		mov	r5, r5, lsr #16
+		orr	r5, r5, r6, lsl #16
+		mov	r6, r6, lsr #16
+		orr	r6, r6, r7, lsl #16
+		mov	r7, r7, lsr #16
+		orr	r7, r7, r8, lsl #16
+		stmia	dst!, {r4, r5, r6, r7}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		adcs	sum, sum, r6
+		adcs	sum, sum, r7
+		mov	r4, r8, lsr #16
+		sub	ip, ip, #16
+		teq	ip, #0
+		bne	1b
+2:		ands	ip, len, #12
+		beq	4f
+		tst	ip, #8
+		beq	3f
+		load2l	r5, r6
+		orr	r4, r4, r5, lsl #16
+		mov	r5, r5, lsr #16
+		orr	r5, r5, r6, lsl #16
+		stmia	dst!, {r4, r5}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		mov	r4, r6, lsr #16
+		tst	ip, #4
+		beq	4f
+3:		load1l	r5
+		orr	r4, r4, r5, lsl #16
+		str	r4, [dst], #4
+		adcs	sum, sum, r4
+		mov	r4, r5, lsr #16
+4:		ands	len, len, #3
+		beq	.done
+		tst	len, #2
+		beq	.exit
+		adcs	sum, sum, r4, lsl #16
+		strb	r4, [dst], #1
+		mov	r4, r4, lsr #8
+		strb	r4, [dst], #1
+		tst	len, #1
+		beq	.done
+		load1b	r4
+		b	.exit
+
+.src3_aligned:	mov	r4, r4, lsr #24
+		adds	sum, sum, #0
+		bics	ip, len, #15
+		beq	2f
+1:		load4l	r5, r6, r7, r8
+		orr	r4, r4, r5, lsl #8
+		mov	r5, r5, lsr #24
+		orr	r5, r5, r6, lsl #8
+		mov	r6, r6, lsr #24
+		orr	r6, r6, r7, lsl #8
+		mov	r7, r7, lsr #24
+		orr	r7, r7, r8, lsl #8
+		stmia	dst!, {r4, r5, r6, r7}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		adcs	sum, sum, r6
+		adcs	sum, sum, r7
+		mov	r4, r8, lsr #24
+		sub	ip, ip, #16
+		teq	ip, #0
+		bne	1b
+2:		ands	ip, len, #12
+		beq	4f
+		tst	ip, #8
+		beq	3f
+		load2l	r5, r6
+		orr	r4, r4, r5, lsl #8
+		mov	r5, r5, lsr #24
+		orr	r5, r5, r6, lsl #8
+		stmia	dst!, {r4, r5}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		mov	r4, r6, lsr #24
+		tst	ip, #4
+		beq	4f
+3:		load1l	r5
+		orr	r4, r4, r5, lsl #8
+		str	r4, [dst], #4
+		adcs	sum, sum, r4
+		mov	r4, r5, lsr #24
+4:		ands	len, len, #3
+		beq	.done
+		tst	len, #2
+		beq	.exit
+		adcs	sum, sum, r4, lsl #16
+		strb	r4, [dst], #1
+		load1l	r4
+		strb	r4, [dst], #1
+		adcs	sum, sum, r4, lsl #24
+		mov	r4, r4, lsr #8
+		b	.exit
diff -urN linux-2.4.29/arch/armnommu/mm/discontig.c linux-2.4.29-uc1/arch/armnommu/mm/discontig.c
--- linux-2.4.29/arch/armnommu/mm/discontig.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/discontig.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,36 @@
+/*
+ * linux/arch/arm/mm/discontig.c
+ *
+ * Discontiguous memory support.
+ *
+ * Initial code: Copyright (C) 1999-2000 Nicolas Pitre
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#if NR_NODES != 4
+#error Fix Me Please
+#endif
+
+/*
+ * Our node_data structure for discontigous memory.
+ */
+
+static bootmem_data_t node_bootmem_data[NR_NODES];
+
+pg_data_t discontig_node_data[NR_NODES] = {
+  { bdata: &node_bootmem_data[0] },
+  { bdata: &node_bootmem_data[1] },
+  { bdata: &node_bootmem_data[2] },
+  { bdata: &node_bootmem_data[3] }
+};
+
+EXPORT_SYMBOL(discontig_node_data);
+
diff -urN linux-2.4.29/arch/armnommu/mm/extable.c linux-2.4.29-uc1/arch/armnommu/mm/extable.c
--- linux-2.4.29/arch/armnommu/mm/extable.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/extable.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,55 @@
+/*
+ *  linux/arch/arm/mm/extable.c
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+extern const struct exception_table_entry __start___ex_table[];
+extern const struct exception_table_entry __stop___ex_table[];
+
+static inline unsigned long
+search_one_table(const struct exception_table_entry *first,
+		 const struct exception_table_entry *last,
+		 unsigned long value)
+{
+        while (first <= last) {
+		const struct exception_table_entry *mid;
+		long diff;
+
+		mid = (last - first) / 2 + first;
+		diff = mid->insn - value;
+                if (diff == 0)
+                        return mid->fixup;
+                else if (diff < 0)
+                        first = mid+1;
+                else
+                        last = mid-1;
+        }
+        return 0;
+}
+
+unsigned long
+search_exception_table(unsigned long addr)
+{
+	unsigned long ret;
+
+#ifndef CONFIG_MODULES
+	/* There is only the kernel to search.  */
+	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
+	if (ret) return ret;
+#else
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (mp->ex_table_start == NULL)
+			continue;
+		ret = search_one_table(mp->ex_table_start,
+				       mp->ex_table_end - 1, addr);
+		if (ret) return ret;
+	}
+#endif
+
+	return 0;
+}
diff -urN linux-2.4.29/arch/armnommu/mm/fault-armo.c linux-2.4.29-uc1/arch/armnommu/mm/fault-armo.c
--- linux-2.4.29/arch/armnommu/mm/fault-armo.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/fault-armo.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,66 @@
+/*
+ *  linux/arch/arm/mm/fault-armo.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Modifications for ARM processor (c) 1995-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+#define FAULT_CODE_LDRSTRPOST	0x80
+#define FAULT_CODE_LDRSTRPRE	0x40
+#define FAULT_CODE_LDRSTRREG	0x20
+#define FAULT_CODE_LDMSTM	0x10
+#define FAULT_CODE_LDCSTC	0x08
+#define FAULT_CODE_PREFETCH	0x04
+#define FAULT_CODE_WRITE	0x02
+#define FAULT_CODE_FORCECOW	0x01
+
+#define DO_COW(m)		((m) & (FAULT_CODE_WRITE|FAULT_CODE_FORCECOW))
+#define READ_FAULT(m)		(!((m) & FAULT_CODE_WRITE))
+
+extern int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs);
+extern void show_pte(struct mm_struct *mm, unsigned long addr);
+
+/*
+ * Handle a data abort.  Note that we have to handle a range of addresses
+ * on ARM2/3 for ldm.  If both pages are zero-mapped, then we have to force
+ * a copy-on-write.  However, on the second page, we always force COW.
+ */
+asmlinkage void
+do_DataAbort(unsigned long min_addr, unsigned long max_addr, int mode, struct pt_regs *regs)
+{
+	do_page_fault(min_addr, mode, regs);
+
+	if ((min_addr ^ max_addr) >> PAGE_SHIFT)
+		do_page_fault(max_addr, mode | FAULT_CODE_FORCECOW, regs);
+}
+
+asmlinkage int
+do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
+{
+#if 0
+	if (the memc mapping for this page exists) {
+		printk ("Page in, but got abort (undefined instruction?)\n");
+		return 0;
+	}
+#endif
+	do_page_fault(addr, FAULT_CODE_PREFETCH, regs);
+	return 1;
+}
diff -urN linux-2.4.29/arch/armnommu/mm/fault-armv.c linux-2.4.29-uc1/arch/armnommu/mm/fault-armv.c
--- linux-2.4.29/arch/armnommu/mm/fault-armv.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/fault-armv.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,645 @@
+/*
+ *  linux/arch/arm/mm/fault-armv.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Modifications for ARM processor (c) 1995-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/unaligned.h>
+
+extern void die_if_kernel(const char *str, struct pt_regs *regs, int err);
+extern void show_pte(struct mm_struct *mm, unsigned long addr);
+extern int do_page_fault(unsigned long addr, int error_code,
+			 struct pt_regs *regs);
+extern int do_translation_fault(unsigned long addr, int error_code,
+				struct pt_regs *regs);
+extern void do_bad_area(struct task_struct *tsk, struct mm_struct *mm,
+			unsigned long addr, int error_code,
+			struct pt_regs *regs);
+
+#ifdef CONFIG_ALIGNMENT_TRAP
+/*
+ * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998
+ * /proc/sys/debug/alignment, modified and integrated into
+ * Linux 2.1 by Russell King
+ *
+ * Speed optimisations and better fault handling by Russell King.
+ *
+ * *** NOTE ***
+ * This code is not portable to processors with late data abort handling.
+ */
+#define CODING_BITS(i)	(i & 0x0e000000)
+
+#define LDST_I_BIT(i)	(i & (1 << 26))		/* Immediate constant	*/
+#define LDST_P_BIT(i)	(i & (1 << 24))		/* Preindex		*/
+#define LDST_U_BIT(i)	(i & (1 << 23))		/* Add offset		*/
+#define LDST_W_BIT(i)	(i & (1 << 21))		/* Writeback		*/
+#define LDST_L_BIT(i)	(i & (1 << 20))		/* Load			*/
+
+#define LDST_P_EQ_U(i)	((((i) ^ ((i) >> 1)) & (1 << 23)) == 0)
+
+#define LDSTH_I_BIT(i)	(i & (1 << 22))		/* half-word immed	*/
+#define LDM_S_BIT(i)	(i & (1 << 22))		/* write CPSR from SPSR	*/
+
+#define RN_BITS(i)	((i >> 16) & 15)	/* Rn			*/
+#define RD_BITS(i)	((i >> 12) & 15)	/* Rd			*/
+#define RM_BITS(i)	(i & 15)		/* Rm			*/
+
+#define REGMASK_BITS(i)	(i & 0xffff)
+#define OFFSET_BITS(i)	(i & 0x0fff)
+
+#define IS_SHIFT(i)	(i & 0x0ff0)
+#define SHIFT_BITS(i)	((i >> 7) & 0x1f)
+#define SHIFT_TYPE(i)	(i & 0x60)
+#define SHIFT_LSL	0x00
+#define SHIFT_LSR	0x20
+#define SHIFT_ASR	0x40
+#define SHIFT_RORRRX	0x60
+
+static unsigned long ai_user;
+static unsigned long ai_sys;
+static unsigned long ai_skipped;
+static unsigned long ai_half;
+static unsigned long ai_word;
+static unsigned long ai_multi;
+
+#ifdef CONFIG_SYSCTL
+static int proc_alignment_read(char *page, char **start, off_t off,
+			       int count, int *eof, void *data)
+{
+	char *p = page;
+	int len;
+
+	p += sprintf(p, "User:\t\t%li\n", ai_user);
+	p += sprintf(p, "System:\t\t%li\n", ai_sys);
+	p += sprintf(p, "Skipped:\t%li\n", ai_skipped);
+	p += sprintf(p, "Half:\t\t%li\n", ai_half);
+	p += sprintf(p, "Word:\t\t%li\n", ai_word);
+	p += sprintf(p, "Multi:\t\t%li\n", ai_multi);
+
+	len = (p - page) - off;
+	if (len < 0)
+		len = 0;
+
+	*eof = (len <= count) ? 1 : 0;
+	*start = page + off;
+
+	return len;
+}
+
+/*
+ * This needs to be done after sysctl_init, otherwise sys/
+ * will be overwritten.
+ */
+static int __init alignment_init(void)
+{
+	create_proc_read_entry("sys/debug/alignment", 0, NULL,
+				proc_alignment_read, NULL);
+	return 0;
+}
+
+__initcall(alignment_init);
+#endif /* CONFIG_SYSCTL */
+
+union offset_union {
+	unsigned long un;
+	  signed long sn;
+};
+
+#define TYPE_ERROR	0
+#define TYPE_FAULT	1
+#define TYPE_LDST	2
+#define TYPE_DONE	3
+
+#define get8_unaligned_check(val,addr,err)		\
+	__asm__(					\
+	"1:	ldrb	%1, [%2], #1\n"			\
+	"2:\n"						\
+	"	.section .fixup,\"ax\"\n"		\
+	"	.align	2\n"				\
+	"3:	mov	%0, #1\n"			\
+	"	b	2b\n"				\
+	"	.previous\n"				\
+	"	.section __ex_table,\"a\"\n"		\
+	"	.align	3\n"				\
+	"	.long	1b, 3b\n"			\
+	"	.previous\n"				\
+	: "=r" (err), "=&r" (val), "=r" (addr)		\
+	: "0" (err), "2" (addr))
+
+#define get8t_unaligned_check(val,addr,err)		\
+	__asm__(					\
+	"1:	ldrbt	%1, [%2], #1\n"			\
+	"2:\n"						\
+	"	.section .fixup,\"ax\"\n"		\
+	"	.align	2\n"				\
+	"3:	mov	%0, #1\n"			\
+	"	b	2b\n"				\
+	"	.previous\n"				\
+	"	.section __ex_table,\"a\"\n"		\
+	"	.align	3\n"				\
+	"	.long	1b, 3b\n"			\
+	"	.previous\n"				\
+	: "=r" (err), "=&r" (val), "=r" (addr)		\
+	: "0" (err), "2" (addr))
+
+#define get16_unaligned_check(val,addr)				\
+	do {							\
+		unsigned int err = 0, v, a = addr;		\
+		get8_unaligned_check(val,a,err);		\
+		get8_unaligned_check(v,a,err);			\
+		val |= v << 8;					\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define put16_unaligned_check(val,addr)				\
+	do {							\
+		unsigned int err = 0, v = val, a = addr;	\
+		__asm__(					\
+		"1:	strb	%1, [%2], #1\n"			\
+		"	mov	%1, %1, lsr #8\n"		\
+		"2:	strb	%1, [%2]\n"			\
+		"3:\n"						\
+		"	.section .fixup,\"ax\"\n"		\
+		"	.align	2\n"				\
+		"4:	mov	%0, #1\n"			\
+		"	b	3b\n"				\
+		"	.previous\n"				\
+		"	.section __ex_table,\"a\"\n"		\
+		"	.align	3\n"				\
+		"	.long	1b, 4b\n"			\
+		"	.long	2b, 4b\n"			\
+		"	.previous\n"				\
+		: "=r" (err), "=&r" (v), "=&r" (a)		\
+		: "0" (err), "1" (v), "2" (a));			\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define __put32_unaligned_check(ins,val,addr)			\
+	do {							\
+		unsigned int err = 0, v = val, a = addr;	\
+		__asm__(					\
+		"1:	"ins"	%1, [%2], #1\n"			\
+		"	mov	%1, %1, lsr #8\n"		\
+		"2:	"ins"	%1, [%2], #1\n"			\
+		"	mov	%1, %1, lsr #8\n"		\
+		"3:	"ins"	%1, [%2], #1\n"			\
+		"	mov	%1, %1, lsr #8\n"		\
+		"4:	"ins"	%1, [%2]\n"			\
+		"5:\n"						\
+		"	.section .fixup,\"ax\"\n"		\
+		"	.align	2\n"				\
+		"6:	mov	%0, #1\n"			\
+		"	b	5b\n"				\
+		"	.previous\n"				\
+		"	.section __ex_table,\"a\"\n"		\
+		"	.align	3\n"				\
+		"	.long	1b, 6b\n"			\
+		"	.long	2b, 6b\n"			\
+		"	.long	3b, 6b\n"			\
+		"	.long	4b, 6b\n"			\
+		"	.previous\n"				\
+		: "=r" (err), "=&r" (v), "=&r" (a)		\
+		: "0" (err), "1" (v), "2" (a));			\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define get32_unaligned_check(val,addr)				\
+	do {							\
+		unsigned int err = 0, v, a = addr;		\
+		get8_unaligned_check(val,a,err);		\
+		get8_unaligned_check(v,a,err);			\
+		val |= v << 8;					\
+		get8_unaligned_check(v,a,err);			\
+		val |= v << 16;					\
+		get8_unaligned_check(v,a,err);			\
+		val |= v << 24;					\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define put32_unaligned_check(val,addr)	 \
+	__put32_unaligned_check("strb", val, addr)
+
+#define get32t_unaligned_check(val,addr)			\
+	do {							\
+		unsigned int err = 0, v, a = addr;		\
+		get8t_unaligned_check(val,a,err);		\
+		get8t_unaligned_check(v,a,err);			\
+		val |= v << 8;					\
+		get8t_unaligned_check(v,a,err);			\
+		val |= v << 16;					\
+		get8t_unaligned_check(v,a,err);			\
+		val |= v << 24;					\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define put32t_unaligned_check(val,addr) \
+	__put32_unaligned_check("strbt", val, addr)
+
+static void
+do_alignment_finish_ldst(unsigned long addr, unsigned long instr, struct pt_regs *regs, union offset_union offset)
+{
+	if (!LDST_U_BIT(instr))
+		offset.un = -offset.un;
+
+	if (!LDST_P_BIT(instr))
+		addr += offset.un;
+
+	if (!LDST_P_BIT(instr) || LDST_W_BIT(instr))
+		regs->uregs[RN_BITS(instr)] = addr;
+}
+
+static int
+do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *regs)
+{
+	unsigned int rd = RD_BITS(instr);
+
+	if ((instr & 0x01f00ff0) == 0x01000090)
+		goto swp;
+
+	if ((instr & 0x90) != 0x90 || (instr & 0x60) == 0)
+		goto bad;
+
+	ai_half += 1;
+
+	if (LDST_L_BIT(instr)) {
+		unsigned long val;
+		get16_unaligned_check(val, addr);
+
+		/* signed half-word? */
+		if (instr & 0x40)
+			val = (signed long)((signed short) val);
+
+		regs->uregs[rd] = val;
+	} else
+		put16_unaligned_check(regs->uregs[rd], addr);
+
+	return TYPE_LDST;
+
+swp:
+	printk(KERN_ERR "Alignment trap: not handling swp instruction\n");
+bad:
+	return TYPE_ERROR;
+
+fault:
+	return TYPE_FAULT;
+}
+
+static int
+do_alignment_ldrstr(unsigned long addr, unsigned long instr, struct pt_regs *regs)
+{
+	unsigned int rd = RD_BITS(instr);
+
+	ai_word += 1;
+
+	if (!LDST_P_BIT(instr) && LDST_W_BIT(instr))
+		goto trans;
+
+	if (LDST_L_BIT(instr))
+		get32_unaligned_check(regs->uregs[rd], addr);
+	else
+		put32_unaligned_check(regs->uregs[rd], addr);
+	return TYPE_LDST;
+
+trans:
+	if (LDST_L_BIT(instr))
+		get32t_unaligned_check(regs->uregs[rd], addr);
+	else
+		put32t_unaligned_check(regs->uregs[rd], addr);
+	return TYPE_LDST;
+
+fault:
+	return TYPE_FAULT;
+}
+
+/*
+ * LDM/STM alignment handler.
+ *
+ * There are 4 variants of this instruction:
+ *
+ * B = rn pointer before instruction, A = rn pointer after instruction
+ *              ------ increasing address ----->
+ *	        |    | r0 | r1 | ... | rx |    |
+ * PU = 01             B                    A
+ * PU = 11        B                    A
+ * PU = 00        A                    B
+ * PU = 10             A                    B
+ */
+static int
+do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *regs)
+{
+	unsigned int rd, rn, correction, nr_regs, regbits;
+	unsigned long eaddr, newaddr;
+
+	if (LDM_S_BIT(instr))
+		goto bad;
+
+	correction = 4; /* processor implementation defined */
+	regs->ARM_pc += correction;
+
+	ai_multi += 1;
+
+	/* count the number of registers in the mask to be transferred */
+	for (regbits = REGMASK_BITS(instr), nr_regs = 0; regbits; regbits >>= 1)
+		nr_regs += 4;
+
+	rn = RN_BITS(instr);
+	newaddr = eaddr = regs->uregs[rn];
+
+	if (!LDST_U_BIT(instr))
+		nr_regs = -nr_regs;
+	newaddr += nr_regs;
+	if (!LDST_U_BIT(instr))
+		eaddr = newaddr;
+
+	if (LDST_P_EQ_U(instr))	/* U = P */
+		eaddr += 4;
+
+	/*
+	 * This is a "hint" - we already have eaddr worked out by the
+	 * processor for us.
+	 */
+	if (addr != eaddr)
+		printk(KERN_ERR "LDMSTM: PC = %08lx, instr = %08lx, "
+			"addr = %08lx, eaddr = %08lx\n",
+			 instruction_pointer(regs), instr, addr, eaddr);
+
+	for (regbits = REGMASK_BITS(instr), rd = 0; regbits; regbits >>= 1, rd += 1)
+		if (regbits & 1) {
+			if (LDST_L_BIT(instr))
+				get32_unaligned_check(regs->uregs[rd], eaddr);
+			else
+				put32_unaligned_check(regs->uregs[rd], eaddr);
+			eaddr += 4;
+		}
+
+	if (LDST_W_BIT(instr))
+		regs->uregs[rn] = newaddr;
+	if (!LDST_L_BIT(instr) || !(REGMASK_BITS(instr) & (1 << 15)))
+		regs->ARM_pc -= correction;
+	return TYPE_DONE;
+
+fault:
+	regs->ARM_pc -= correction;
+	return TYPE_FAULT;
+
+bad:
+	printk(KERN_ERR "Alignment trap: not handling ldm with s-bit set\n");
+	return TYPE_ERROR;
+}
+
+static int
+do_alignment(unsigned long addr, int error_code, struct pt_regs *regs)
+{
+	union offset_union offset;
+	unsigned long instr, instrptr;
+	int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
+	unsigned int type;
+
+	if (user_mode(regs))
+		goto user;
+
+	ai_sys += 1;
+
+	instrptr = instruction_pointer(regs);
+	instr = *(unsigned long *)instrptr;
+
+	regs->ARM_pc += 4;
+
+	switch (CODING_BITS(instr)) {
+	case 0x00000000:	/* ldrh or strh */
+		if (LDSTH_I_BIT(instr))
+			offset.un = (instr & 0xf00) >> 4 | (instr & 15);
+		else
+			offset.un = regs->uregs[RM_BITS(instr)];
+		handler = do_alignment_ldrhstrh;
+		break;
+
+	case 0x04000000:	/* ldr or str immediate */
+		offset.un = OFFSET_BITS(instr);
+		handler = do_alignment_ldrstr;
+		break;
+
+	case 0x06000000:	/* ldr or str register */
+		offset.un = regs->uregs[RM_BITS(instr)];
+
+		if (IS_SHIFT(instr)) {
+			unsigned int shiftval = SHIFT_BITS(instr);
+
+			switch(SHIFT_TYPE(instr)) {
+			case SHIFT_LSL:
+				offset.un <<= shiftval;
+				break;
+
+			case SHIFT_LSR:
+				offset.un >>= shiftval;
+				break;
+
+			case SHIFT_ASR:
+				offset.sn >>= shiftval;
+				break;
+
+			case SHIFT_RORRRX:
+				if (shiftval == 0) {
+					offset.un >>= 1;
+					if (regs->ARM_cpsr & CC_C_BIT)
+						offset.un |= 1 << 31;
+				} else
+					offset.un = offset.un >> shiftval |
+							  offset.un << (32 - shiftval);
+				break;
+			}
+		}
+		handler = do_alignment_ldrstr;
+		break;
+
+	case 0x08000000:	/* ldm or stm */
+		handler = do_alignment_ldmstm;
+		break;
+
+	default:
+		goto bad;
+	}
+
+	type = handler(addr, instr, regs);
+
+	if (type == TYPE_ERROR || type == TYPE_FAULT)
+		goto bad_or_fault;
+
+	if (type == TYPE_LDST)
+		do_alignment_finish_ldst(addr, instr, regs, offset);
+
+	return 0;
+
+bad_or_fault:
+	if (type == TYPE_ERROR)
+		goto bad;
+	regs->ARM_pc -= 4;
+	/*
+	 * We got a fault - fix it up, or die.
+	 */
+	do_bad_area(current, current->mm, addr, error_code, regs);
+	return 0;
+
+bad:
+	/*
+	 * Oops, we didn't handle the instruction.
+	 */
+	printk(KERN_ERR "Alignment trap: not handling instruction "
+		"%08lx at [<%08lx>]", instr, instrptr);
+	ai_skipped += 1;
+	return 1;
+
+user:
+	set_cr(cr_no_alignment);
+	ai_user += 1;
+	return 0;
+}
+
+#else
+
+#define do_alignment NULL
+
+#endif
+
+/*
+ * Some section permission faults need to be handled gracefully, for
+ * instance, when they happen due to a __{get,put}_user during an oops).
+ */
+static int
+do_sect_fault(unsigned long addr, int error_code, struct pt_regs *regs)
+{
+	struct task_struct *tsk = current;
+	do_bad_area(tsk, tsk->active_mm, addr, error_code, regs);
+	return 0;
+}
+
+/*
+ * Hook for things that need to trap external faults.  Note that
+ * we don't guarantee that this will be the final version of the
+ * interface.
+ */
+int (*external_fault)(unsigned long addr, struct pt_regs *regs);
+
+static int
+do_external_fault(unsigned long addr, int error_code, struct pt_regs *regs)
+{
+	if (external_fault)
+		return external_fault(addr, regs);
+	return 1;
+}
+
+static const struct fsr_info {
+	int	(*fn)(unsigned long addr, int error_code, struct pt_regs *regs);
+	int	sig;
+	char	*name;
+} fsr_info[] = {
+	{ NULL,			SIGSEGV, "vector exception"		   },
+	{ do_alignment,		SIGILL,	 "alignment exception"		   },
+	{ NULL,			SIGKILL, "terminal exception"		   },
+	{ do_alignment,		SIGILL,	 "alignment exception"		   },
+	{ do_external_fault,	SIGBUS,	 "external abort on linefetch"	   },
+	{ do_translation_fault,	SIGSEGV, "section translation fault"	   },
+	{ do_external_fault,	SIGBUS,	 "external abort on linefetch"	   },
+	{ do_page_fault,	SIGSEGV, "page translation fault"	   },
+	{ do_external_fault,	SIGBUS,	 "external abort on non-linefetch" },
+	{ NULL,			SIGSEGV, "section domain fault"		   },
+	{ do_external_fault,	SIGBUS,	 "external abort on non-linefetch" },
+	{ NULL,			SIGSEGV, "page domain fault"		   },
+	{ NULL,			SIGBUS,	 "external abort on translation"   },
+	{ do_sect_fault,	SIGSEGV, "section permission fault"	   },
+	{ NULL,			SIGBUS,	 "external abort on translation"   },
+	{ do_page_fault,	SIGSEGV, "page permission fault"	   }
+};
+
+/*
+ * Currently dropped down to debug level
+ */
+asmlinkage void
+do_DataAbort(unsigned long addr, int error_code, struct pt_regs *regs, int fsr)
+{
+	const struct fsr_info *inf = fsr_info + (fsr & 15);
+
+#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100) || defined(CONFIG_DEBUG_ERRORS)
+	if (addr == regs->ARM_pc)
+		goto sa1_weirdness;
+#endif
+
+	if (!inf->fn)
+		goto bad;
+
+	if (!inf->fn(addr, error_code, regs))
+		return;
+bad:
+	force_sig(inf->sig, current);
+	printk(KERN_ALERT "Unhandled fault: %s (%X) at 0x%08lx\n",
+		inf->name, fsr, addr);
+	show_pte(current->mm, addr);
+	die_if_kernel("Oops", regs, 0);
+	return;
+
+#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100) || defined(CONFIG_DEBUG_ERRORS)
+sa1_weirdness:
+	if (user_mode(regs)) {
+		static int first = 1;
+		if (first) {
+			printk(KERN_DEBUG "Fixing up bad data abort at %08lx\n", addr);
+			show_pte(current->mm, addr);
+		}
+		first = 0;
+		return;
+	}
+
+	if (!inf->fn || inf->fn(addr, error_code, regs))
+		goto bad;
+	return;
+#endif
+}
+
+asmlinkage void
+do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
+{
+	do_translation_fault(addr, 0, regs);
+}
+
+/*
+ * if PG_dcache_dirty is set for the page, we need to ensure that any
+ * cache entries for the kernels virtual memory range are written
+ * back to the page.
+ */
+void check_pgcache_dirty(struct page *page)
+{
+#ifndef CONFIG_UCLINUX
+	if (VALID_PAGE(page) && page->mapping &&
+	    test_and_clear_bit(PG_dcache_dirty, &page->flags)) {
+		unsigned long kvirt = (unsigned long)page_address(page);
+		cpu_cache_clean_invalidate_range(kvirt, kvirt + PAGE_SIZE, 0);
+	}
+#endif
+}
diff -urN linux-2.4.29/arch/armnommu/mm/fault-armv-s3c.c linux-2.4.29-uc1/arch/armnommu/mm/fault-armv-s3c.c
--- linux-2.4.29/arch/armnommu/mm/fault-armv-s3c.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/fault-armv-s3c.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,245 @@
+/*
+ *  linux/arch/arm/mm/fault-s3c.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Modifications for ARM processor (c) 1995-2001 Russell King
+ *  Modifications for Samsung ARM processors (c) 2002 Oleksandr Zhadan
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/unaligned.h>
+
+extern void die_if_kernel(const char *str, struct pt_regs *regs, int err);
+extern void show_pte(struct mm_struct *mm, unsigned long addr);
+extern int do_page_fault(unsigned long addr, int error_code,
+			 struct pt_regs *regs);
+extern int do_translation_fault(unsigned long addr, int error_code,
+				struct pt_regs *regs);
+extern void do_bad_area(struct task_struct *tsk, struct mm_struct *mm,
+			unsigned long addr, int error_code,
+			struct pt_regs *regs);
+
+
+#if defined(CONFIG_CPU_S3C45x0_ALIGNMENT_PROCFS) && defined(CONFIG_SYSCTL)
+
+struct align {
+	struct align *next;
+	unsigned int  addr;
+	unsigned int  offset;
+	unsigned int  count;
+	unsigned char name[16];
+	};
+
+struct align root_align;
+
+static int proc_alignment_read(char *page, char **start, off_t off,
+			       int count, int *eof, void *data)
+{
+	char *p = page;
+	int len;
+	struct align *ptr;
+
+	for ( ptr=&root_align; ptr != NULL; ptr = ptr->next ) {
+	    if   ((unsigned int)ptr == (unsigned int)&root_align)
+		 p += sprintf(p, "Address(Offset)\t\tCounter\t\tName\n");
+	    else p += sprintf(p, "0x%08x(0x%08x)\t%6d\t\t%s\n", ptr->addr, ptr->offset,
+								ptr->count, ptr->name);
+	    }
+
+	len = (p - page) - off;
+	if (len < 0)
+		len = 0;
+
+	*eof = (len <= count) ? 1 : 0;
+	*start = page + off;
+
+	return len;
+}
+
+/*
+ * This needs to be done after sysctl_init, otherwise sys/
+ * will be overwritten.
+ */
+static int __init alignment_init(void)
+{
+	create_proc_read_entry("sys/debug/alignment", 0, NULL,
+				proc_alignment_read, NULL);
+				
+	root_align.next   = NULL;
+	root_align.addr   = 0;
+	root_align.offset = 0;
+	root_align.count  = 0;
+	memset(root_align.name, 0, sizeof(root_align.name));
+	return 0;
+}
+
+__initcall(alignment_init);
+#endif
+
+static int
+do_alignment(unsigned long addr, int error_code, struct pt_regs *regs)
+{
+#if defined(CONFIG_CPU_S3C45x0_ALIGNMENT_PROCFS) && defined(CONFIG_SYSCTL)
+	unsigned int instrptr;
+	struct align *ptr;
+	
+        instrptr = instruction_pointer(regs) - 4; 
+
+	if   ( user_mode(regs) )
+	     for ( ptr=&root_align; ptr != NULL; ptr = ptr->next ) {
+		 if  ( !strcmp (ptr->name, current->comm) )
+		     if  ( ptr->addr == instrptr ) {
+			 ptr->count += 1;
+			 return 0;
+			 }
+		 if  ( !ptr->next ) 
+		     break;
+		}
+	else for ( ptr=&root_align; ptr != NULL; ptr = ptr->next ) {
+		 if  ( ptr->addr == instrptr ) {
+		     ptr->count += 1;
+		     return 0;
+		     }
+		 if  ( !ptr->next ) 
+		     break;
+		 }	
+	    
+	ptr->next = kmalloc(sizeof(struct align), GFP_KERNEL);
+	if  (!ptr->next)
+	    panic("do_alignment: unable to allocate memory!");
+	memset(ptr->next->name, 0, sizeof(ptr->next->name));
+
+	ptr->next->next   = 0;
+	ptr->next->addr   = instrptr;
+	ptr->next->count  = 1;
+	
+	if   ( user_mode(regs) ) {
+	     ptr->next->offset = ptr->next->addr - current->mm->start_code;
+	     strncpy(ptr->next->name, current->comm, 15);
+	     }
+	else {
+	     ptr->next->offset = ptr->next->addr;
+	     strcpy(ptr->next->name, "_KERNEL_");
+	     }
+#endif
+
+#if defined(CONFIG_CPU_S3C45x0_ALIGNMENT_TRAP)
+	return 0;
+#else
+	return 1;
+#endif		
+}
+
+
+/*
+ * Some section permission faults need to be handled gracefully, for
+ * instance, when they happen due to a __{get,put}_user during an oops).
+ */
+static int
+do_sect_fault(unsigned long addr, int error_code, struct pt_regs *regs)
+{
+	struct task_struct *tsk = current;
+	do_bad_area(tsk, tsk->active_mm, addr, error_code, regs);
+	return 0;
+}
+
+/*
+ * Hook for things that need to trap external faults.  Note that
+ * we don't guarantee that this will be the final version of the
+ * interface.
+ */
+int (*external_fault)(unsigned long addr, struct pt_regs *regs);
+
+static int
+do_external_fault(unsigned long addr, int error_code, struct pt_regs *regs)
+{
+	if (external_fault)
+		return external_fault(addr, regs);
+	return 1;
+}
+
+/*
+ * This abort handler always returns "fault".
+ */
+static int
+do_bad(unsigned long addr, int fsr, struct pt_regs *regs)
+{
+	return 1;
+}
+
+static const struct fsr_info {
+	int	(*fn)(unsigned long addr, int error_code, struct pt_regs *regs);
+	int	sig;
+	char	*name;
+} fsr_info[] = {
+	{ do_bad,		SIGSEGV, "vector exception"		   },
+	{ do_alignment,		SIGILL,	 "alignment exception"		   },
+	{ do_bad,		SIGKILL, "terminal exception"		   },
+	{ do_bad,		SIGILL,	 "alignment exception"		   },
+	{ do_bad,		SIGBUS,	 "external abort on linefetch"	   },
+	{ do_bad,		SIGSEGV, "section translation fault"	   },
+	{ do_bad,		SIGBUS,	 "external abort on linefetch"	   },
+	{ do_bad,		SIGSEGV, "page translation fault"	   },
+	{ do_bad,		SIGBUS,	 "external abort on non-linefetch" },
+	{ do_bad,		SIGSEGV, "section domain fault"		   },
+	{ do_bad,		SIGBUS,	 "external abort on non-linefetch" },
+	{ do_bad,		SIGSEGV, "page domain fault"		   },
+	{ do_bad,		SIGBUS,	 "external abort on translation"   },
+	{ do_bad,		SIGSEGV, "section permission fault"	   },
+	{ do_bad,		SIGBUS,	 "external abort on translation"   },
+	{ do_bad,		SIGSEGV, "page permission fault"	   }
+};
+
+/*
+ * Currently dropped down to debug level
+ */
+asmlinkage void
+do_DataAbort(unsigned long addr, int error_code, struct pt_regs *regs, int fsr)
+{
+	const struct fsr_info *inf = fsr_info + (fsr & 15);
+
+	if (!inf->fn(addr, error_code, regs))
+		return;
+
+	force_sig(inf->sig, current);
+	printk(KERN_ALERT "Unhandled fault: %s (%X) at 0x%08lx\n",
+		inf->name, fsr, addr);
+	show_pte(current->mm, addr);
+	die_if_kernel("Oops", regs, 0);
+	return;
+}
+
+asmlinkage void
+do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
+{
+	do_translation_fault(addr, 0, regs);
+}
+
+/*
+ * if PG_dcache_dirty is set for the page, we need to ensure that any
+ * cache entries for the kernels virtual memory range are written
+ * back to the page.
+ */
+void check_pgcache_dirty(struct page *page)
+{
+}
diff -urN linux-2.4.29/arch/armnommu/mm/fault-common.c linux-2.4.29-uc1/arch/armnommu/mm/fault-common.c
--- linux-2.4.29/arch/armnommu/mm/fault-common.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/fault-common.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,390 @@
+/*
+ *  linux/arch/arm/mm/fault-common.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Modifications for ARM processor (c) 1995-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/unaligned.h>
+
+#ifdef CONFIG_CPU_26
+#define FAULT_CODE_WRITE	0x02
+#define FAULT_CODE_FORCECOW	0x01
+#define DO_COW(m)		((m) & (FAULT_CODE_WRITE|FAULT_CODE_FORCECOW))
+#define READ_FAULT(m)		(!((m) & FAULT_CODE_WRITE))
+#else
+/*
+ * On 32-bit processors, we define "mode" to be zero when reading,
+ * non-zero when writing.  This now ties up nicely with the polarity
+ * of the 26-bit machines, and also means that we avoid the horrible
+ * gcc code for "int val = !other_val;".
+ */
+#define DO_COW(m)		(m)
+#define READ_FAULT(m)		(!(m))
+#endif
+
+NORET_TYPE void die(const char *msg, struct pt_regs *regs, int err) ATTRIB_NORET;
+
+/*
+ * This is useful to dump out the page tables associated with
+ * 'addr' in mm 'mm'.
+ */
+void show_pte(struct mm_struct *mm, unsigned long addr)
+{
+#ifndef CONFIG_UCLINUX
+	pgd_t *pgd;
+
+	if (!mm)
+		mm = &init_mm;
+
+	printk(KERN_ALERT "pgd = %p\n", mm->pgd);
+	pgd = pgd_offset(mm, addr);
+	printk(KERN_ALERT "*pgd = %08lx", pgd_val(*pgd));
+
+	do {
+		pmd_t *pmd;
+		pte_t *pte;
+
+		if (pgd_none(*pgd))
+			break;
+
+		if (pgd_bad(*pgd)) {
+			printk("(bad)");
+			break;
+		}
+
+		pmd = pmd_offset(pgd, addr);
+		printk(", *pmd = %08lx", pmd_val(*pmd));
+
+		if (pmd_none(*pmd))
+			break;
+
+		if (pmd_bad(*pmd)) {
+			printk("(bad)");
+			break;
+		}
+
+		pte = pte_offset(pmd, addr);
+		printk(", *pte = %08lx", pte_val(*pte));
+#ifdef CONFIG_CPU_32
+		printk(", *ppte = %08lx", pte_val(pte[-PTRS_PER_PTE]));
+#endif
+	} while(0);
+
+	printk("\n");
+#else
+	printk("%s(%d): start_code=0x%x, start_stack=0x%x)\n",
+		__FILE__,__LINE__, mm->start_code, mm->start_stack);
+#endif
+}
+
+/*
+ * Oops.  The kernel tried to access some page that wasn't present.
+ */
+static void
+__do_kernel_fault(struct mm_struct *mm, unsigned long addr, int error_code,
+		  struct pt_regs *regs)
+{
+	unsigned long fixup;
+
+	/*
+	 * Are we prepared to handle this kernel fault?
+	 */
+	if ((fixup = search_exception_table(instruction_pointer(regs))) != 0) {
+#ifdef DEBUG
+		printk(KERN_DEBUG "%s: Exception at [<%lx>] addr=%lx (fixup: %lx)\n",
+			tsk->comm, regs->ARM_pc, addr, fixup);
+#endif
+		regs->ARM_pc = fixup;
+		return;
+	}
+
+	/*
+	 * No handler, we'll have to terminate things with extreme prejudice.
+	 */
+	printk(KERN_ALERT
+		"Unable to handle kernel %s at virtual address %08lx\n",
+		(addr < PAGE_SIZE) ? "NULL pointer dereference" :
+		"paging request", addr);
+
+	show_pte(mm, addr);
+	die("Oops", regs, error_code);
+	do_exit(SIGKILL);
+}
+
+/*
+ * Something tried to access memory that isn't in our memory map..
+ * User mode accesses just cause a SIGSEGV
+ */
+static void
+__do_user_fault(struct task_struct *tsk, unsigned long addr, int error_code,
+		int code, struct pt_regs *regs)
+{
+	struct siginfo si;
+
+#ifdef CONFIG_DEBUG_USER
+	printk(KERN_DEBUG "%s: unhandled page fault at pc=0x%08lx, "
+	       "lr=0x%08lx (bad address=0x%08lx, code %d)\n",
+	       tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, error_code);
+#endif
+
+	tsk->thread.address = addr;
+	tsk->thread.error_code = error_code;
+	tsk->thread.trap_no = 14;
+	si.si_signo = SIGSEGV;
+	si.si_errno = 0;
+	si.si_code = code;
+	si.si_addr = (void *)addr;
+	force_sig_info(SIGSEGV, &si, tsk);
+}
+
+void
+do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr,
+	    int error_code, struct pt_regs *regs)
+{
+	/*
+	 * If we are in kernel mode at this point, we
+	 * have no context to handle this fault with.
+	 */
+	if (user_mode(regs))
+		__do_user_fault(tsk, addr, error_code, SEGV_MAPERR, regs);
+	else
+		__do_kernel_fault(mm, addr, error_code, regs);
+}
+
+static int
+__do_page_fault(struct mm_struct *mm, unsigned long addr, int error_code,
+		struct task_struct *tsk)
+{
+#ifndef CONFIG_UCLINUX
+	struct vm_area_struct *vma;
+	int fault, mask;
+
+	vma = find_vma(mm, addr);
+	fault = -2; /* bad map area */
+	if (!vma)
+		goto out;
+	if (vma->vm_start > addr)
+		goto check_stack;
+
+	/*
+	 * Ok, we have a good vm_area for this
+	 * memory access, so we can handle it.
+	 */
+good_area:
+	if (READ_FAULT(error_code)) /* read? */
+		mask = VM_READ|VM_EXEC;
+	else
+		mask = VM_WRITE;
+
+	fault = -1; /* bad access type */
+	if (!(vma->vm_flags & mask))
+		goto out;
+
+	/*
+	 * If for any reason at all we couldn't handle
+	 * the fault, make sure we exit gracefully rather
+	 * than endlessly redo the fault.
+	 */
+survive:
+	fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(error_code));
+
+	/*
+	 * Handle the "normal" cases first - successful and sigbus
+	 */
+	switch (fault) {
+	case 2:
+		tsk->maj_flt++;
+		return fault;
+	case 1:
+		tsk->min_flt++;
+	case 0:
+		return fault;
+	}
+
+	fault = -3; /* out of memory */
+	if (tsk->pid != 1)
+		goto out;
+
+	/*
+	 * If we are out of memory for pid1,
+	 * sleep for a while and retry
+	 */
+	tsk->policy |= SCHED_YIELD;
+	schedule();
+	goto survive;
+
+check_stack:
+	if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr))
+		goto good_area;
+out:
+	return fault;
+#else
+	printk("%s %d\n",__FILE__,__LINE__);
+	return 0;
+#endif
+}
+
+int do_page_fault(unsigned long addr, int error_code, struct pt_regs *regs)
+{
+#ifdef CONFIG_UCLINUX
+	struct task_struct *tsk;
+	struct mm_struct *mm;
+	int fault;
+
+	tsk = current;
+	mm  = tsk->mm;
+
+	/*
+	 * If we're in an interrupt or have no user
+	 * context, we must not take the fault..
+	 */
+	if (in_interrupt() || !mm)
+		goto no_context;
+
+	down_read(&mm->mmap_sem);
+	fault = __do_page_fault(mm, addr, error_code, tsk);
+	up_read(&mm->mmap_sem);
+
+	/*
+	 * Handle the "normal" case first
+	 */
+	if (fault > 0)
+		return 0;
+
+	/*
+	 * We had some memory, but were unable to
+	 * successfully fix up this page fault.
+	 */
+	if (fault == 0)
+		goto do_sigbus;
+
+	/*
+	 * If we are in kernel mode at this point, we
+	 * have no context to handle this fault with.
+	 */
+	if (!user_mode(regs))
+		goto no_context;
+
+	if (fault == -3) {
+		/*
+		 * We ran out of memory, or some other thing happened to
+		 * us that made us unable to handle the page fault gracefully.
+		 */
+		printk("VM: killing process %s\n", tsk->comm);
+		do_exit(SIGKILL);
+	} else
+		__do_user_fault(tsk, addr, error_code, fault == -1 ?
+				SEGV_ACCERR : SEGV_MAPERR, regs);
+	return 0;
+
+
+/*
+ * We ran out of memory, or some other thing happened to us that made
+ * us unable to handle the page fault gracefully.
+ */
+do_sigbus:
+	/*
+	 * Send a sigbus, regardless of whether we were in kernel
+	 * or user mode.
+	 */
+	tsk->thread.address = addr;
+	tsk->thread.error_code = error_code;
+	tsk->thread.trap_no = 14;
+	force_sig(SIGBUS, tsk);
+
+	/* Kernel mode? Handle exceptions or die */
+	if (user_mode(regs))
+		return 0;
+
+no_context:
+	__do_kernel_fault(mm, addr, error_code, regs);
+	return 0;
+#else
+	printk("%s %d\n",__FILE__,__LINE__);
+	return 0;
+#endif
+}
+
+/*
+ * First Level Translation Fault Handler
+ *
+ * We enter here because the first level page table doesn't contain
+ * a valid entry for the address.
+ *
+ * If the address is in kernel space (>= TASK_SIZE), then we are
+ * probably faulting in the vmalloc() area.
+ *
+ * If the init_task's first level page tables contains the relevant
+ * entry, we copy the it to this task.  If not, we send the process
+ * a signal, fixup the exception, or oops the kernel.
+ *
+ * NOTE! We MUST NOT take any locks for this case. We may be in an
+ * interrupt or a critical region, and should only copy the information
+ * from the master page table, nothing more.
+ */
+int do_translation_fault(unsigned long addr, int error_code, struct pt_regs *regs)
+{
+#ifndef CONFIG_UCLINUX
+	struct task_struct *tsk;
+	struct mm_struct *mm;
+	int offset;
+	pgd_t *pgd, *pgd_k;
+	pmd_t *pmd, *pmd_k;
+
+	if (addr < TASK_SIZE)
+		return do_page_fault(addr, error_code, regs);
+
+	tsk = current;
+	mm  = tsk->active_mm;
+
+	offset = __pgd_offset(addr);
+
+	pgd_k = init_mm.pgd + offset;
+	pgd   = mm->pgd + offset;
+
+	if (pgd_none(*pgd_k))
+		goto bad_area;
+
+#if 0	/* note that we are two-level */
+	if (!pgd_present(*pgd))
+		set_pgd(pgd, *pgd_k);
+#endif
+
+	pmd_k = pmd_offset(pgd_k, addr);
+	pmd   = pmd_offset(pgd, addr);
+
+	if (pmd_none(*pmd_k))
+		goto bad_area;
+
+	set_pmd(pmd, *pmd_k);
+	return 0;
+
+bad_area:
+	do_bad_area(tsk, mm, addr, error_code, regs);
+	return 0;
+#else
+	printk("%s %d\n",__FILE__,__LINE__);
+	return 0;
+#endif
+}
diff -urN linux-2.4.29/arch/armnommu/mm/init.c linux-2.4.29-uc1/arch/armnommu/mm/init.c
--- linux-2.4.29/arch/armnommu/mm/init.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/init.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,710 @@
+/*
+ *  linux/arch/arm/mm/init.c
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/swapctl.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/blk.h>
+
+#include <asm/segment.h>
+#include <asm/mach-types.h>
+#include <asm/pgalloc.h>
+#include <asm/dma.h>
+#include <asm/hardware.h>
+#include <asm/setup.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#ifndef CONFIG_DISCONTIGMEM
+#define NR_NODES	1
+#else
+#define NR_NODES	4
+#endif
+
+#ifdef CONFIG_CPU_32
+#define TABLE_OFFSET	(PTRS_PER_PTE)
+#else
+#define TABLE_OFFSET	0
+#endif
+
+#define TABLE_SIZE	((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(void *))
+
+static unsigned long totalram_pages;
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+extern char _stext, _text, _etext, _end, __init_begin, __init_end;
+#ifdef CONFIG_RAM_ATTACHED_ROMFS
+extern unsigned int _ramstart;
+#endif
+/*
+ * The sole use of this is to pass memory configuration
+ * data from paging_init to mem_init.
+ */
+static struct meminfo meminfo __initdata = { 0, };
+
+/*
+ * empty_zero_page is a special page that is used for
+ * zero-initialized data and COW.
+ */
+struct page *empty_zero_page;
+
+#ifndef CONFIG_NO_PGT_CACHE
+struct pgtable_cache_struct quicklists;
+
+int do_check_pgt_cache(int low, int high)
+{
+	int freed = 0;
+
+	if(pgtable_cache_size > high) {
+		do {
+			if(pgd_quicklist) {
+				free_pgd_slow(get_pgd_fast());
+				freed++;
+			}
+			if(pmd_quicklist) {
+				pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
+				freed++;
+			}
+			if(pte_quicklist) {
+				pte_free_slow(pte_alloc_one_fast(NULL, 0));
+				freed++;
+			}
+		} while(pgtable_cache_size > low);
+	}
+	return freed;
+}
+#else
+int do_check_pgt_cache(int low, int high)
+{
+	return 0;
+}
+#endif
+
+void show_mem(void)
+{
+	int free = 0, total = 0, reserved = 0;
+	int shared = 0, cached = 0, node;
+
+	printk("Mem-info:\n");
+	show_free_areas();
+	printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+
+	for (node = 0; node < numnodes; node++) {
+		struct page *page, *end;
+
+		page = NODE_MEM_MAP(node);
+		end  = page + NODE_DATA(node)->node_size;
+
+		do {
+/* This is currently broken
+ * PG_skip is used on sparc/sparc64 architectures to "skip" certain
+ * parts of the address space.
+ *
+ * #define PG_skip	10
+ * #define PageSkip(page) (machine_is_riscpc() && test_bit(PG_skip, &(page)->flags))
+ *			if (PageSkip(page)) {
+ *				page = page->next_hash;
+ *				if (page == NULL)
+ *					break;
+ *			}
+ */
+			total++;
+			if (PageReserved(page))
+				reserved++;
+			else if (PageSwapCache(page))
+				cached++;
+			else if (!page_count(page))
+				free++;
+			else
+				shared += atomic_read(&page->count) - 1;
+			page++;
+		} while (page < end);
+	}
+
+	printk("%d pages of RAM\n", total);
+	printk("%d free pages\n", free);
+	printk("%d reserved pages\n", reserved);
+	printk("%d pages shared\n", shared);
+	printk("%d pages swap cached\n", cached);
+#ifndef CONFIG_NO_PGT_CACHE
+	printk("%ld page tables cached\n", pgtable_cache_size);
+#endif
+	show_buffers();
+}
+
+struct node_info {
+	unsigned int start;
+	unsigned int end;
+	int bootmap_pages;
+};
+
+#define O_PFN_DOWN(x)	((x) >> PAGE_SHIFT)
+#define V_PFN_DOWN(x)	O_PFN_DOWN(__pa(x))
+
+#define O_PFN_UP(x)	(PAGE_ALIGN(x) >> PAGE_SHIFT)
+#define V_PFN_UP(x)	O_PFN_UP(__pa(x))
+
+#define PFN_SIZE(x)	((x) >> PAGE_SHIFT)
+#define PFN_RANGE(s,e)	PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \
+				(((unsigned long)(s)) & PAGE_MASK))
+
+/*
+ * FIXME: We really want to avoid allocating the bootmap bitmap
+ * over the top of the initrd.  Hopefully, this is located towards
+ * the start of a bank, so if we allocate the bootmap bitmap at
+ * the end, we won't clash.
+ */
+static unsigned int __init
+find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
+{
+	unsigned int start_pfn, bank, bootmap_pfn;
+
+#ifndef CONFIG_RAM_ATTACHED_ROMFS
+	start_pfn   = V_PFN_UP(&_end);
+#else	
+	start_pfn   = V_PFN_UP(_ramstart);
+#endif  
+	bootmap_pfn = 0;
+
+	for (bank = 0; bank < mi->nr_banks; bank ++) {
+		unsigned int start, end;
+
+		if (mi->bank[bank].node != node)
+			continue;
+
+		start = O_PFN_UP(mi->bank[bank].start);
+		end   = O_PFN_DOWN(mi->bank[bank].size +
+				   mi->bank[bank].start);
+
+		if (end < start_pfn)
+			continue;
+
+		if (start < start_pfn)
+			start = start_pfn;
+
+		if (end <= start)
+			continue;
+
+		if (end - start >= bootmap_pages) {
+			bootmap_pfn = start;
+			break;
+		}
+	}
+
+	if (bootmap_pfn == 0)
+		BUG();
+
+	return bootmap_pfn;
+}
+
+/*
+ * Scan the memory info structure and pull out:
+ *  - the end of memory
+ *  - the number of nodes
+ *  - the pfn range of each node
+ *  - the number of bootmem bitmap pages
+ */
+static unsigned int __init
+find_memend_and_nodes(struct meminfo *mi, struct node_info *np)
+{
+	unsigned int i, bootmem_pages = 0, memend_pfn = 0;
+
+	for (i = 0; i < NR_NODES; i++) {
+		np[i].start = -1U;
+		np[i].end = 0;
+		np[i].bootmap_pages = 0;
+	}
+
+	for (i = 0; i < mi->nr_banks; i++) {
+		unsigned long start, end;
+		int node;
+
+		if (mi->bank[i].size == 0) {
+			/*
+			 * Mark this bank with an invalid node number
+			 */
+			mi->bank[i].node = -1;
+			continue;
+		}
+
+		node = mi->bank[i].node;
+
+		if (node >= numnodes) {
+			numnodes = node + 1;
+
+			/*
+			 * Make sure we haven't exceeded the maximum number
+			 * of nodes that we have in this configuration.  If
+			 * we have, we're in trouble.  (maybe we ought to
+			 * limit, instead of bugging?)
+			 */
+			if (numnodes > NR_NODES)
+				BUG();
+		}
+
+		/*
+		 * Get the start and end pfns for this bank
+		 */
+		start = O_PFN_UP(mi->bank[i].start);
+		end   = O_PFN_DOWN(mi->bank[i].start + mi->bank[i].size);
+
+		if (np[node].start > start)
+			np[node].start = start;
+
+		if (np[node].end < end)
+			np[node].end = end;
+
+		if (memend_pfn < end)
+			memend_pfn = end;
+	}
+
+	/*
+	 * Calculate the number of pages we require to
+	 * store the bootmem bitmaps.
+	 */
+	for (i = 0; i < numnodes; i++) {
+		if (np[i].end == 0)
+			continue;
+
+		np[i].bootmap_pages = bootmem_bootmap_pages(np[i].end -
+							    np[i].start);
+		bootmem_pages += np[i].bootmap_pages;
+	}
+
+	/*
+	 * This doesn't seem to be used by the Linux memory
+	 * manager any more.  If we can get rid of it, we
+	 * also get rid of some of the stuff above as well.
+	 */
+	max_low_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
+	mi->end = memend_pfn << PAGE_SHIFT;
+
+	return bootmem_pages;
+}
+
+static int __init check_initrd(struct meminfo *mi)
+{
+	int initrd_node = -2;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	/*
+	 * Make sure that the initrd is within a valid area of
+	 * memory.
+	 */
+	if (initrd_start) {
+		unsigned long phys_initrd_start, phys_initrd_end;
+		unsigned int i;
+
+		phys_initrd_start = __pa(initrd_start);
+		phys_initrd_end   = __pa(initrd_end);
+
+		for (i = 0; i < mi->nr_banks; i++) {
+			unsigned long bank_end;
+
+			bank_end = mi->bank[i].start + mi->bank[i].size;
+
+			if (mi->bank[i].start <= phys_initrd_start &&
+			    phys_initrd_end <= bank_end)
+				initrd_node = mi->bank[i].node;
+		}
+	}
+
+	if (initrd_node == -1) {
+		printk(KERN_ERR "initrd (0x%08lx - 0x%08lx) extends beyond "
+		       "physical memory - disabling initrd\n",
+		       initrd_start, initrd_end);
+		initrd_start = initrd_end = 0;
+	}
+#endif
+
+	return initrd_node;
+}
+
+/*
+ * Reserve the various regions of node 0
+ */
+static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int bootmap_pages)
+{
+	pg_data_t *pgdat = NODE_DATA(0);
+
+	/*
+	 * Register the kernel text and data with bootmem.
+	 * Note that this can only be in node 0.
+	 */
+#ifndef CONFIG_RAM_ATTACHED_ROMFS
+	reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext);
+#else
+  reserve_bootmem_node(pgdat, __pa(&_stext), _ramstart - ((unsigned int)(&_stext)));
+#endif
+#if defined(CONFIG_CPU_32) && !defined(CONFIG_UCLINUX)
+	/*
+	 * Reserve the page tables.  These are already in use,
+	 * and can only be in node 0.
+	 */
+	reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
+			     PTRS_PER_PGD * sizeof(void *));
+#endif
+	/*
+	 * And don't forget to reserve the allocator bitmap,
+	 * which will be freed later.
+	 */
+	reserve_bootmem_node(pgdat, bootmap_pfn << PAGE_SHIFT,
+			     bootmap_pages << PAGE_SHIFT);
+
+	/*
+	 * Hmm... This should go elsewhere, but we really really
+	 * need to stop things allocating the low memory; we need
+	 * a better implementation of GFP_DMA which does not assume
+	 * that DMA-able memory starts at zero.
+	 */
+
+	if (machine_is_integrator() || machine_is_snds100() || machine_is_dm270() ||
+	    machine_is_netarm()    || machine_is_evS3C4530HEI() ||
+	    machine_is_smdk2500() || machine_is_S3C2500REFRGP() )
+		reserve_bootmem_node(pgdat, 0, __pa(&_stext));
+
+
+	/*
+	 * These should likewise go elsewhere.  They pre-reserve
+	 * the screen memory region at the start of main system
+	 * memory.
+	 */
+	if (machine_is_archimedes() || machine_is_a5k())
+		reserve_bootmem_node(pgdat, 0x02000000, 0x00080000);
+	if (machine_is_p720t())
+		reserve_bootmem_node(pgdat, PAGE_OFFSET, 0x00014000);
+
+	/*
+	 * We reserve the first 32k for the interrupt handlers.  A little
+	 * excessive?  Yes.
+	 */
+	if (machine_is_ipod())
+		reserve_bootmem_node(pgdat, PAGE_OFFSET, 0x00008000);
+}
+
+/*
+ * Register all available RAM in this node with the bootmem allocator.
+ */
+static inline void free_bootmem_node_bank(int node, struct meminfo *mi)
+{
+	pg_data_t *pgdat = NODE_DATA(node);
+	int bank;
+
+	for (bank = 0; bank < mi->nr_banks; bank++)
+		if (mi->bank[bank].node == node)
+			free_bootmem_node(pgdat, mi->bank[bank].start,
+					  mi->bank[bank].size);
+}
+
+/*
+ * Initialise the bootmem allocator for all nodes.  This is called
+ * early during the architecture specific initialisation.
+ */
+void __init bootmem_init(struct meminfo *mi)
+{
+	struct node_info node_info[NR_NODES], *np = node_info;
+	unsigned int bootmap_pages, bootmap_pfn, map_pg;
+	int node, initrd_node;
+
+	bootmap_pages = find_memend_and_nodes(mi, np);
+	bootmap_pfn   = find_bootmap_pfn(0, mi, bootmap_pages);
+	initrd_node   = check_initrd(mi);
+
+	map_pg = bootmap_pfn;
+
+	/*
+	 * Initialise the bootmem nodes.
+	 *
+	 * What we really want to do is:
+	 *
+	 *   unmap_all_regions_except_kernel();
+	 *   for_each_node_in_reverse_order(node) {
+	 *     map_node(node);
+	 *     allocate_bootmem_map(node);
+	 *     init_bootmem_node(node);
+	 *     free_bootmem_node(node);
+	 *   }
+	 *
+	 * but this is a 2.5-type change.  For now, we just set
+	 * the nodes up in reverse order.
+	 *
+	 * (we could also do with rolling bootmem_init and paging_init
+	 * into one generic "memory_init" type function).
+	 */
+	np += numnodes - 1;
+	for (node = numnodes - 1; node >= 0; node--, np--) {
+		/*
+		 * If there are no pages in this node, ignore it.
+		 * Note that node 0 must always have some pages.
+		 */
+		if (np->end == 0) {
+			if (node == 0)
+				BUG();
+			continue;
+		}
+
+		/*
+		 * Initialise the bootmem allocator.
+		 */
+		init_bootmem_node(NODE_DATA(node), map_pg, np->start, np->end);
+		free_bootmem_node_bank(node, mi);
+		map_pg += np->bootmap_pages;
+
+		/*
+		 * If this is node 0, we need to reserve some areas ASAP -
+		 * we may use bootmem on node 0 to setup the other nodes.
+		 */
+		if (node == 0)
+			reserve_node_zero(bootmap_pfn, bootmap_pages);
+	}
+
+
+#ifdef CONFIG_BLK_DEV_INITRD
+/*
+ * For arches that compile in the ramdisk data we do not need
+ * to reserve the memory. Memory for the initrd device will be
+ * reserved with the kernel data section.
+ */
+#if !defined(CONFIG_BLK_DEV_RAMDISK_DATA)
+	if (initrd_node >= 0)
+		reserve_bootmem_node(NODE_DATA(initrd_node), __pa(initrd_start),
+				     initrd_end - initrd_start);
+#endif
+#endif
+
+	if (map_pg != bootmap_pfn + bootmap_pages)
+		BUG();
+}
+
+/*
+ * paging_init() sets up the page tables, initialises the zone memory
+ * maps, and sets up the zero page, bad page and bad page tables.
+ */
+void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
+{
+	void *zero_page;
+	int node;
+
+	memcpy(&meminfo, mi, sizeof(meminfo));
+
+	/*
+	 * allocate the zero page.  Note that we count on this going ok.
+	 */
+	zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
+#ifndef CONFIG_UCLINUX
+	/*
+	 * initialise the page tables.
+	 */
+	memtable_init(mi);
+	if (mdesc->map_io)
+		mdesc->map_io();
+	flush_tlb_all();
+
+	/*
+	 * initialise the zones within each node
+	 */
+	for (node = 0; node < numnodes; node++) {
+		unsigned long zone_size[MAX_NR_ZONES];
+		unsigned long zhole_size[MAX_NR_ZONES];
+		struct bootmem_data *bdata;
+		pg_data_t *pgdat;
+		int i;
+
+		/*
+		 * Initialise the zone size information.
+		 */
+		for (i = 0; i < MAX_NR_ZONES; i++) {
+			zone_size[i]  = 0;
+			zhole_size[i] = 0;
+		}
+
+		pgdat = NODE_DATA(node);
+		bdata = pgdat->bdata;
+
+		/*
+		 * The size of this node has already been determined.
+		 * If we need to do anything fancy with the allocation
+		 * of this memory to the zones, now is the time to do
+		 * it.
+		 */
+		zone_size[0] = bdata->node_low_pfn -
+				(bdata->node_boot_start >> PAGE_SHIFT);
+
+		/*
+		 * For each bank in this node, calculate the size of the
+		 * holes.  holes = node_size - sum(bank_sizes_in_node)
+		 */
+		zhole_size[0] = zone_size[0];
+		for (i = 0; i < mi->nr_banks; i++) {
+			if (mi->bank[i].node != node)
+				continue;
+
+			zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT;
+		}
+
+		free_area_init_node(node, pgdat, 0, zone_size,
+				bdata->node_boot_start, zhole_size);
+	}
+#else
+	{
+	  unsigned long zone_size[MAX_NR_ZONES] = {0,0,0};
+
+	  zone_size[ZONE_DMA] = 0;
+	  zone_size[ZONE_NORMAL] = (END_MEM - PAGE_OFFSET) >> PAGE_SHIFT;
+
+	  free_area_init_node(0, NULL, NULL, zone_size, PAGE_OFFSET, NULL);
+	}
+#endif
+	/*
+	 * finish off the bad pages once
+	 * the mem_map is initialised
+	 */
+	memzero(zero_page, PAGE_SIZE);
+	empty_zero_page = virt_to_page(zero_page);
+	flush_dcache_page(empty_zero_page);
+}
+
+/*
+ * mem_init() marks the free areas in the mem_map and tells us how much
+ * memory is free.  This is done after various parts of the system have
+ * claimed their memory after the kernel image.
+ */
+void __init mem_init(void)
+{
+	unsigned int codepages, datapages, initpages;
+	int i, node;
+
+	codepages = &_etext - &_text;
+#ifndef CONFIG_RAM_ATTACHED_ROMFS
+	datapages = &_end - &_etext;
+#else 
+	datapages = _ramstart - ((unsigned int)&_etext);
+#endif  
+	initpages = &__init_end - &__init_begin;
+
+	high_memory = (void *)__va(meminfo.end);
+	max_mapnr   = virt_to_page(high_memory) - mem_map;
+
+	/*
+	 * We may have non-contiguous memory.
+	 */
+	if (meminfo.nr_banks != 1)
+		create_memmap_holes(&meminfo);
+
+	/* this will put all unused low memory onto the freelists */
+	for (node = 0; node < numnodes; node++)
+		totalram_pages += free_all_bootmem_node(NODE_DATA(node));
+
+	//	SetPageReserved(virt_to_page(PAGE_OFFSET));
+	/*
+	 * Since our memory may not be contiguous, calculate the
+	 * real number of pages we have in this system
+	 */
+	printk(KERN_INFO "Memory:");
+
+	num_physpages = 0;
+	for (i = 0; i < meminfo.nr_banks; i++) {
+		num_physpages += meminfo.bank[i].size >> PAGE_SHIFT;
+		printk(" %ldMB", meminfo.bank[i].size >> 20);
+	}
+
+	printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
+	printk(KERN_NOTICE "Memory: %luKB available (%dK code, "
+		"%dK data, %dK init)\n",
+		(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+		codepages >> 10, datapages >> 10, initpages >> 10);
+
+	if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
+		extern int sysctl_overcommit_memory;
+		/*
+		 * On a machine this small we won't get
+		 * anywhere without overcommit, so turn
+		 * it on by default.
+		 */
+		sysctl_overcommit_memory = 1;
+	}
+}
+
+static inline void free_area(unsigned long addr, unsigned long end, char *s)
+{
+	unsigned int size = (end - addr) >> 10;
+
+	for (; addr < end; addr += PAGE_SIZE) {
+		struct page *page = virt_to_page(addr);
+		ClearPageReserved(page);
+		set_page_count(page, 1);
+		free_page(addr);
+		totalram_pages++;
+	}
+
+	if (size)
+		printk("Freeing %s memory: %dK\n", s, size);
+}
+
+void free_initmem(void)
+{
+	if (!machine_is_integrator() &&
+	    !machine_is_p52() &&
+	    !machine_is_cx821xx() &&
+	    !machine_is_atmel() &&
+	    !machine_is_netarm() &&
+	    !machine_is_dm270() &&
+	    !machine_is_ta7v() &&
+	    !machine_is_vc547x() &&
+	    !machine_is_ta7s()) {
+		free_area((unsigned long)(&__init_begin),
+			  (unsigned long)(&__init_end),
+			  "init");
+	}
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+
+static int keep_initrd;
+
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	if (!keep_initrd)
+		free_area(start, end, "initrd");
+}
+
+static int __init keepinitrd_setup(char *__unused)
+{
+	keep_initrd = 1;
+	return 1;
+}
+
+__setup("keepinitrd", keepinitrd_setup);
+#endif
+
+void si_meminfo(struct sysinfo *val)
+{
+	val->totalram  = totalram_pages;
+	val->sharedram = 0;
+	val->freeram   = nr_free_pages();
+	val->bufferram = atomic_read(&buffermem_pages);
+	val->totalhigh = 0;
+	val->freehigh  = 0;
+	val->mem_unit  = PAGE_SIZE;
+}
+
+
+
diff -urN linux-2.4.29/arch/armnommu/mm/ioremap.c linux-2.4.29-uc1/arch/armnommu/mm/ioremap.c
--- linux-2.4.29/arch/armnommu/mm/ioremap.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/ioremap.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,26 @@
+/*
+ *  linux/arch/arm/mm/ioremap.c
+ *
+ * Re-map IO memory to kernel address space so that we can access it.
+ *
+ * (C) Copyright 1995 1996 Linus Torvalds
+ *
+ * Hacked for ARM by Phil Blundell <philb@gnu.org>
+ * Hacked to allow all architectures to build, and various cleanups
+ * by Russell King
+ * Hacked for uClinux by Gordon Mcnutt <gmcnutt@ridgerun.com>
+ */
+#include <linux/types.h>
+
+/*
+ * No MMU? No problem.
+ * --gmcnutt
+ */
+void * __ioremap(unsigned long phys_addr, size_t size, unsigned long flags)
+{
+	return (void *)phys_addr;
+}
+
+void __iounmap(void *addr)
+{
+}
diff -urN linux-2.4.29/arch/armnommu/mm/Makefile linux-2.4.29-uc1/arch/armnommu/mm/Makefile
--- linux-2.4.29/arch/armnommu/mm/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,75 @@
+#
+# Makefile for the linux arm-specific parts of the memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+#
+# Additional changes:
+#  (c) Copyright 2001-2002 - S3C4530 by Arcturus Networks Inc.
+#  (c) Copyright 2002-2003 - S3C2500 by Arcturus Networks Inc.
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET	:= mm.o
+
+# Object file lists.
+
+obj-y		:= init.o
+obj-m		:=
+obj-n		:=
+obj-		:=
+export-objs	:= proc-syms.o discontig.o
+
+cpu32-y		:= consistent.o ioremap.o mm-armv.o
+
+ifeq ($(CONFIG_CPU_S3C4530),y)
+    cpu32-y	+= fault-armv-s3c.o
+else
+    cpu32-y	+= fault-armv.o
+endif
+
+cpu32-$(CONFIG_MODULES) += proc-syms.o
+
+obj-y		+= extable.o fault-common.o
+obj-$(CONFIG_CPU_26) += fault-armo.o mm-armo.o small_page.o
+obj-$(CONFIG_CPU_32) += $(cpu32-y)
+
+obj-$(CONFIG_DISCONTIGMEM) += discontig.o
+
+obj-$(MAGIC_ROM_PTR) += memory.o
+
+# Select the processor-specific files
+p-$(CONFIG_CPU_26)	+= proc-arm2,3.o
+p-$(CONFIG_CPU_ARM7V3)	+= proc-arm6,7.o
+p-$(CONFIG_CPU_ARM610)	+= proc-arm6,7.o
+p-$(CONFIG_CPU_ARM710)	+= proc-arm6,7.o
+p-$(CONFIG_CPU_ARM720T)	+= proc-arm720.o
+p-$(CONFIG_CPU_ARM740T) += proc-arm740.o
+p-$(CONFIG_CPU_ARM920T)	+= proc-arm920.o
+
+ifeq ($(CONFIG_CPU_S3C2500),y)
+ p-$(CONFIG_CPU_ARM940T) += proc-arm940T.o
+else
+ p-$(CONFIG_CPU_ARM940T) += proc-arm940.o
+endif
+
+p-$(CONFIG_CPU_ARM1020)	+= proc-arm1020.o
+p-$(CONFIG_CPU_SA110)	+= proc-sa110.o
+p-$(CONFIG_CPU_SA1100)	+= proc-sa110.o
+
+# Integrator follows "new style"
+# Soon, others will do too, and we can get rid of this
+MMMACH		:= mm-$(MACHINE).c
+ifeq ($(MMMACH),$(wildcard $(MMMACH)))
+obj-$(CONFIG_CPU_32)	+= $(MMMACH:.c=.o)
+endif
+
+obj-y		+= $(sort $(p-y))
+
+include $(TOPDIR)/Rules.make
+
+# Special dependencies
+$(p-y):	$(TOPDIR)/include/asm/constants.h
diff -urN linux-2.4.29/arch/armnommu/mm/memory.c linux-2.4.29-uc1/arch/armnommu/mm/memory.c
--- linux-2.4.29/arch/armnommu/mm/memory.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/memory.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,11 @@
+#include <linux/config.h>
+#include <linux/mm.h>
+
+#ifdef MAGIC_ROM_PTR
+int is_in_rom(unsigned long addr) {
+	if ( FLASH_MEM_BASE <= addr && addr < (FLASH_MEM_BASE+FLASH_SIZE) )
+		return 1;
+	else 
+		return 0;
+}
+#endif
diff -urN linux-2.4.29/arch/armnommu/mm/mm-armv.c linux-2.4.29-uc1/arch/armnommu/mm/mm-armv.c
--- linux-2.4.29/arch/armnommu/mm/mm-armv.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/mm-armv.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,519 @@
+/*
+ *  linux/arch/arm/mm/mm-armv.c
+ *
+ *  Copyright (C) 1998-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Page table sludge for ARM v3 and v4 processor architectures.
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+
+#include <asm/mach/map.h>
+
+/*
+ * These are useful for identifing cache coherency
+ * problems by allowing the cache or the cache and
+ * writebuffer to be turned off.  (Note: the write
+ * buffer should not be on and the cache off).
+ */
+static int __init nocache_setup(char *__unused)
+{
+	cr_alignment &= ~4;
+	cr_no_alignment &= ~4;
+	flush_cache_all();
+	set_cr(cr_alignment);
+	return 1;
+}
+
+static int __init nowrite_setup(char *__unused)
+{
+	cr_alignment &= ~(8|4);
+	cr_no_alignment &= ~(8|4);
+	flush_cache_all();
+	set_cr(cr_alignment);
+	return 1;
+}
+
+static int __init noalign_setup(char *__unused)
+{
+	cr_alignment &= ~2;
+	cr_no_alignment &= ~2;
+	set_cr(cr_alignment);
+	return 1;
+}
+
+__setup("noalign", noalign_setup);
+__setup("nocache", nocache_setup);
+__setup("nowb", nowrite_setup);
+
+#define FIRST_KERNEL_PGD_NR	(FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
+
+#define clean_cache_area(start,size) \
+	cpu_cache_clean_invalidate_range((unsigned long)start, ((unsigned long)start) + size, 0);
+
+
+/*
+ * need to get a 16k page for level 1
+ */
+pgd_t *get_pgd_slow(struct mm_struct *mm)
+{
+#ifndef CONFIG_UCLINUX
+	pgd_t *new_pgd, *init_pgd;
+	pmd_t *new_pmd, *init_pmd;
+	pte_t *new_pte, *init_pte;
+
+	new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2);
+	if (!new_pgd)
+		goto no_pgd;
+
+	memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t));
+
+	init_pgd = pgd_offset_k(0);
+
+	if (vectors_base() == 0) {
+		init_pmd = pmd_offset(init_pgd, 0);
+		init_pte = pte_offset(init_pmd, 0);
+
+		/*
+		 * This lock is here just to satisfy pmd_alloc and pte_lock
+		 */
+		spin_lock(&mm->page_table_lock);
+
+		/*
+		 * On ARM, first page must always be allocated since it
+		 * contains the machine vectors.
+		 */
+		new_pmd = pmd_alloc(mm, new_pgd, 0);
+		if (!new_pmd)
+			goto no_pmd;
+
+		new_pte = pte_alloc(mm, new_pmd, 0);
+		if (!new_pte)
+			goto no_pte;
+
+		set_pte(new_pte, *init_pte);
+
+		spin_unlock(&mm->page_table_lock);
+	}
+
+	/*
+	 * Copy over the kernel and IO PGD entries
+	 */
+	memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
+		       (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
+
+	/*
+	 * FIXME: this should not be necessary
+	 */
+	clean_cache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t));
+
+	return new_pgd;
+
+no_pte:
+	spin_unlock(&mm->page_table_lock);
+	pmd_free(new_pmd);
+	free_pages((unsigned long)new_pgd, 2);
+	return NULL;
+
+no_pmd:
+	spin_unlock(&mm->page_table_lock);
+	free_pages((unsigned long)new_pgd, 2);
+	return NULL;
+
+no_pgd:
+	return NULL;
+#else
+	return NULL;
+#endif
+
+}
+
+void free_pgd_slow(pgd_t *pgd)
+{
+#ifndef CONFIG_UCLINUX
+	pmd_t *pmd;
+	pte_t *pte;
+
+	if (!pgd)
+		return;
+
+	/* pgd is always present and good */
+	pmd = (pmd_t *)pgd;
+	if (pmd_none(*pmd))
+		goto free;
+	if (pmd_bad(*pmd)) {
+		pmd_ERROR(*pmd);
+		pmd_clear(pmd);
+		goto free;
+	}
+
+	pte = pte_offset(pmd, 0);
+	pmd_clear(pmd);
+	pte_free(pte);
+	pmd_free(pmd);
+free:
+	free_pages((unsigned long) pgd, 2);
+#else
+	printk("%s %i\n",__FILE__,__LINE__);
+#endif
+}
+
+/*
+ * Create a SECTION PGD between VIRT and PHYS in domain
+ * DOMAIN with protection PROT
+ */
+static inline void
+alloc_init_section(unsigned long virt, unsigned long phys, int prot)
+{
+#ifndef CONFIG_UCLINUX
+	pmd_t pmd;
+
+	pmd_val(pmd) = phys | prot;
+
+	set_pmd(pmd_offset(pgd_offset_k(virt), virt), pmd);
+#else
+	printk("%s %i\n",__FILE__,__LINE__);
+#endif
+}
+
+/*
+ * Add a PAGE mapping between VIRT and PHYS in domain
+ * DOMAIN with protection PROT.  Note that due to the
+ * way we map the PTEs, we must allocate two PTE_SIZE'd
+ * blocks - one for the Linux pte table, and one for
+ * the hardware pte table.
+ */
+static inline void
+alloc_init_page(unsigned long virt, unsigned long phys, int domain, int prot)
+{
+#ifndef CONFIG_UCLINUX
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	pmdp = pmd_offset(pgd_offset_k(virt), virt);
+
+	if (pmd_none(*pmdp)) {
+		pte_t *ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
+						      sizeof(pte_t));
+
+		ptep += PTRS_PER_PTE;
+
+		set_pmd(pmdp, __mk_pmd(ptep, PMD_TYPE_TABLE | PMD_DOMAIN(domain)));
+	}
+	ptep = pte_offset(pmdp, virt);
+
+	set_pte(ptep, mk_pte_phys(phys, __pgprot(prot)));
+#else
+	printk("%s %i\n",__FILE__,__LINE__);
+#endif
+}
+
+/*
+ * Clear any PGD mapping.  On a two-level page table system,
+ * the clearance is done by the middle-level functions (pmd)
+ * rather than the top-level (pgd) functions.
+ */
+static inline void clear_mapping(unsigned long virt)
+{
+#ifndef CONFIG_UCLINUX
+	pmd_clear(pmd_offset(pgd_offset_k(virt), virt));
+#else
+	printk("%s %i\n",__FILE__,__LINE__);
+#endif
+}
+
+/*
+ * Create the page directory entries and any necessary
+ * page tables for the mapping specified by `md'.  We
+ * are able to cope here with varying sizes and address
+ * offsets, and we take full advantage of sections.
+ */
+static void __init create_mapping(struct map_desc *md)
+{
+#ifndef CONFIG_UCLINUX
+	unsigned long virt, length;
+	int prot_sect, prot_pte;
+	long off;
+
+	prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+		   (md->prot_read  ? L_PTE_USER       : 0) |
+		   (md->prot_write ? L_PTE_WRITE      : 0) |
+		   (md->cacheable  ? L_PTE_CACHEABLE  : 0) |
+		   (md->bufferable ? L_PTE_BUFFERABLE : 0);
+
+	prot_sect = PMD_TYPE_SECT | PMD_DOMAIN(md->domain) |
+		    (md->prot_read  ? PMD_SECT_AP_READ    : 0) |
+		    (md->prot_write ? PMD_SECT_AP_WRITE   : 0) |
+		    (md->cacheable  ? PMD_SECT_CACHEABLE  : 0) |
+		    (md->bufferable ? PMD_SECT_BUFFERABLE : 0);
+
+	virt   = md->virtual;
+	off    = md->physical - virt;
+	length = md->length;
+
+	while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) {
+		alloc_init_page(virt, virt + off, md->domain, prot_pte);
+
+		virt   += PAGE_SIZE;
+		length -= PAGE_SIZE;
+	}
+
+	while (length >= PGDIR_SIZE) {
+		alloc_init_section(virt, virt + off, prot_sect);
+
+		virt   += PGDIR_SIZE;
+		length -= PGDIR_SIZE;
+	}
+
+	while (length >= PAGE_SIZE) {
+		alloc_init_page(virt, virt + off, md->domain, prot_pte);
+
+		virt   += PAGE_SIZE;
+		length -= PAGE_SIZE;
+	}
+#else
+	printk("%s %i\n",__FILE__,__LINE__);
+#endif
+}
+
+/*
+ * In order to soft-boot, we need to insert a 1:1 mapping in place of
+ * the user-mode pages.  This will then ensure that we have predictable
+ * results when turning the mmu off
+ */
+void setup_mm_for_reboot(char mode)
+{
+#ifndef CONFIG_UCLINUX
+	pgd_t *pgd;
+	pmd_t pmd;
+	int i;
+
+	if (current->mm && current->mm->pgd)
+		pgd = current->mm->pgd;
+	else
+		pgd = init_mm.pgd;
+
+	for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++) {
+		pmd_val(pmd) = (i << PGDIR_SHIFT) |
+			PMD_SECT_AP_WRITE | PMD_SECT_AP_READ |
+			PMD_TYPE_SECT;
+		set_pmd(pmd_offset(pgd + i, i << PGDIR_SHIFT), pmd);
+	}
+#else
+	printk("%s %i\n",__FILE__,__LINE__);
+#endif
+}
+
+/*
+ * Setup initial mappings.  We use the page we allocated for zero page to hold
+ * the mappings, which will get overwritten by the vectors in traps_init().
+ * The mappings must be in virtual address order.
+ */
+void __init memtable_init(struct meminfo *mi)
+{
+	struct map_desc *init_maps, *p, *q;
+	unsigned long address = 0;
+	int i;
+
+	init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE);
+
+	for (i = 0; i < mi->nr_banks; i++) {
+		if (mi->bank[i].size == 0)
+			continue;
+
+		p->physical   = mi->bank[i].start;
+		p->virtual    = __phys_to_virt(p->physical);
+		p->length     = mi->bank[i].size;
+		p->domain     = DOMAIN_KERNEL;
+		p->prot_read  = 0;
+		p->prot_write = 1;
+		p->cacheable  = 1;
+		p->bufferable = 1;
+
+		p ++;
+	}
+
+#ifdef FLUSH_BASE
+	p->physical   = FLUSH_BASE_PHYS;
+	p->virtual    = FLUSH_BASE;
+	p->length     = PGDIR_SIZE;
+	p->domain     = DOMAIN_KERNEL;
+	p->prot_read  = 1;
+	p->prot_write = 0;
+	p->cacheable  = 1;
+	p->bufferable = 1;
+
+	p ++;
+#endif
+
+#ifdef FLUSH_BASE_MINICACHE
+	p->physical   = FLUSH_BASE_PHYS + PGDIR_SIZE;
+	p->virtual    = FLUSH_BASE_MINICACHE;
+	p->length     = PGDIR_SIZE;
+	p->domain     = DOMAIN_KERNEL;
+	p->prot_read  = 1;
+	p->prot_write = 0;
+	p->cacheable  = 1;
+	p->bufferable = 0;
+
+	p ++;
+#endif
+
+	/*
+	 * Go through the initial mappings, but clear out any
+	 * pgdir entries that are not in the description.
+	 */
+	q = init_maps;
+	do {
+		if (address < q->virtual || q == p) {
+			clear_mapping(address);
+			address += PGDIR_SIZE;
+		} else {
+			create_mapping(q);
+
+			address = q->virtual + q->length;
+			address = (address + PGDIR_SIZE - 1) & PGDIR_MASK;
+
+			q ++;
+		}
+	} while (address != 0);
+
+	/*
+	 * Create a mapping for the machine vectors at virtual address 0
+	 * or 0xffff0000.  We should always try the high mapping.
+	 */
+	init_maps->physical   = virt_to_phys(init_maps);
+#ifndef CONFIG_UCLINUX
+	init_maps->virtual    = vectors_base();
+#endif
+	init_maps->length     = PAGE_SIZE;
+	init_maps->domain     = DOMAIN_USER;
+	init_maps->prot_read  = 0;
+	init_maps->prot_write = 0;
+	init_maps->cacheable  = 1;
+	init_maps->bufferable = 0;
+
+	create_mapping(init_maps);
+
+	flush_cache_all();
+}
+
+/*
+ * Create the architecture specific mappings
+ */
+void __init iotable_init(struct map_desc *io_desc)
+{
+	int i;
+
+	for (i = 0; io_desc[i].last == 0; i++)
+		create_mapping(io_desc + i);
+}
+
+static inline void free_memmap(int node, unsigned long start, unsigned long end)
+{
+	unsigned long pg, pgend;
+
+	start = __phys_to_virt(start);
+	end   = __phys_to_virt(end);
+
+	pg    = PAGE_ALIGN((unsigned long)(virt_to_page(start)));
+	pgend = ((unsigned long)(virt_to_page(end))) & PAGE_MASK;
+
+	start = __virt_to_phys(pg);
+	end   = __virt_to_phys(pgend);
+
+	free_bootmem_node(NODE_DATA(node), start, end - start);
+}
+
+static inline void free_unused_memmap_node(int node, struct meminfo *mi)
+{
+	unsigned long bank_start, prev_bank_end = 0;
+	unsigned int i;
+
+	/*
+	 * [FIXME] This relies on each bank being in address order.  This
+	 * may not be the case, especially if the user has provided the
+	 * information on the command line.
+	 */
+	for (i = 0; i < mi->nr_banks; i++) {
+		if (mi->bank[i].size == 0 || mi->bank[i].node != node)
+			continue;
+
+		bank_start = mi->bank[i].start & PAGE_MASK;
+
+		/*
+		 * If we had a previous bank, and there is a space
+		 * between the current bank and the previous, free it.
+		 */
+		if (prev_bank_end && prev_bank_end != bank_start)
+			free_memmap(node, prev_bank_end, bank_start);
+
+		prev_bank_end = PAGE_ALIGN(mi->bank[i].start +
+					   mi->bank[i].size);
+	}
+}
+
+/*
+ * The mem_map array can get very big.  Free
+ * the unused area of the memory map.
+ */
+void __init create_memmap_holes(struct meminfo *mi)
+{
+	int node;
+
+	for (node = 0; node < numnodes; node++)
+		free_unused_memmap_node(node, mi);
+}
+
+/*
+ * PTE table allocation cache.
+ *
+ * This is a move away from our custom 2K page allocator.  We now use the
+ * slab cache to keep track of these objects.
+ *
+ * With this, it is questionable as to whether the PGT cache gains us
+ * anything.  We may be better off dropping the PTE stuff from our PGT
+ * cache implementation.
+ */
+#ifndef CONFIG_UCLINUX
+kmem_cache_t *pte_cache;
+
+/*
+ * The constructor gets called for each object within the cache when the
+ * cache page is created.  Note that if slab tries to misalign the blocks,
+ * we BUG() loudly.
+ */
+static void pte_cache_ctor(void *pte, kmem_cache_t *cache, unsigned long flags)
+{
+	unsigned long block = (unsigned long)pte;
+
+	if (block & 2047)
+		BUG();
+
+	memzero(pte, 2 * PTRS_PER_PTE * sizeof(pte_t));
+	cpu_cache_clean_invalidate_range(block, block +
+			PTRS_PER_PTE * sizeof(pte_t), 0);
+}
+
+
+void __init pgtable_cache_init(void)
+{
+	pte_cache = kmem_cache_create("pte-cache",
+				2 * PTRS_PER_PTE * sizeof(pte_t), 0, 0,
+				pte_cache_ctor, NULL);
+	if (!pte_cache)
+		BUG();
+}
+#endif
diff -urN linux-2.4.29/arch/armnommu/mm/proc-arm2,3.S linux-2.4.29-uc1/arch/armnommu/mm/proc-arm2,3.S
--- linux-2.4.29/arch/armnommu/mm/proc-arm2,3.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/proc-arm2,3.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,364 @@
+/*
+ *  linux/arch/arm/mm/proc-arm2,3.S
+ *
+ *  Copyright (C) 1997-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  MMU functions for ARM2,3
+ *
+ *  These are the low level assembler for performing cache
+ *  and memory functions on ARM2, ARM250 and ARM3 processors.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+
+/*
+ * MEMC workhorse code.  It's both a horse which things it's a pig.
+ */
+/*
+ * Function: cpu_memc_update_entry(pgd_t *pgd, unsigned long phys_pte, unsigned long addr)
+ * Params  : pgd	Page tables/MEMC mapping
+ *         : phys_pte	physical address, or PTE
+ *         : addr	virtual address
+ */
+ENTRY(cpu_memc_update_entry)
+		tst	r1, #PAGE_PRESENT		@ is the page present
+		orreq	r1, r1, #PAGE_OLD | PAGE_CLEAN
+		moveq	r2, #0x01f00000
+		mov	r3, r1, lsr #13			@ convert to physical page nr
+		and	r3, r3, #0x3fc
+		adr	ip, memc_phys_table_32
+		ldr	r3, [ip, r3]
+		tst	r1, #PAGE_OLD | PAGE_NOT_USER
+		biceq	r3, r3, #0x200
+		tsteq	r1, #PAGE_READONLY | PAGE_CLEAN
+		biceq	r3, r3, #0x300
+		mov	r2, r2, lsr #15			@ virtual -> nr
+		orr	r3, r3, r2, lsl #15
+		and	r2, r2, #0x300
+		orr	r3, r3, r2, lsl #2
+		and	r2, r3, #255
+		sub	r0, r0, #256 * 4
+		str	r3, [r0, r2, lsl #2]
+		strb	r3, [r3]
+		movs	pc, lr
+/*
+ * Params  : r0 = preserved
+ *         : r1 = memc table base (preserved)
+ *         : r2 = page table entry
+ *         : r3 = preserved
+ *         : r4 = unused
+ *         : r5 = memc physical address translation table
+ *         : ip = virtual address (preserved)
+ */
+update_pte:
+		mov	r4, r2, lsr #13
+		and	r4, r4, #0x3fc
+		ldr	r4, [r5, r4]			@ covert to MEMC page
+
+		tst	r2, #PAGE_OLD | PAGE_NOT_USER	@ check for MEMC read
+		biceq	r4, r4, #0x200
+		tsteq	r2, #PAGE_READONLY | PAGE_CLEAN	@ check for MEMC write
+		biceq	r4, r4, #0x300
+
+		orr	r4, r4, ip
+		and	r2, ip, #0x01800000
+		orr	r4, r4, r2, lsr #13
+
+		and	r2, r4, #255
+		str	r4, [r1, r2, lsl #2]
+		movs	pc, lr
+
+/*
+ * Params  : r0 = preserved
+ *         : r1 = memc table base (preserved)
+ *         : r2 = page table base
+ *         : r3 = preserved
+ *         : r4 = unused
+ *         : r5 = memc physical address translation table
+ *         : ip = virtual address (updated)
+ */
+update_pte_table:
+		stmfd	sp!, {r0, lr}
+		bic	r0, r2, #3
+1:		ldr	r2, [r0], #4			@ get entry
+		tst	r2, #PAGE_PRESENT		@ page present
+		blne	update_pte			@ process pte
+		add	ip, ip, #32768			@ increment virt addr
+		ldr	r2, [r0], #4			@ get entry
+		tst	r2, #PAGE_PRESENT		@ page present
+		blne	update_pte			@ process pte
+		add	ip, ip, #32768			@ increment virt addr
+		ldr	r2, [r0], #4			@ get entry
+		tst	r2, #PAGE_PRESENT		@ page present
+		blne	update_pte			@ process pte
+		add	ip, ip, #32768			@ increment virt addr
+		ldr	r2, [r0], #4			@ get entry
+		tst	r2, #PAGE_PRESENT		@ page present
+		blne	update_pte			@ process pte
+		add	ip, ip, #32768			@ increment virt addr
+		tst	ip, #32768 * 31			@ finished?
+		bne	1b
+		ldmfd	sp!, {r0, pc}^
+
+/*
+ * Function: cpu_memc_update_all(pgd_t *pgd)
+ * Params  : pgd	Page tables/MEMC mapping
+ * Notes   : this is optimised for 32k pages
+ */
+ENTRY(cpu_memc_update_all)
+		stmfd	sp!, {r4, r5, lr}
+		bl	clear_tables
+		sub	r1, r0, #256 * 4		@ start of MEMC tables
+		adr	r5, memc_phys_table_32		@ Convert to logical page number
+		mov	ip, #0				@ virtual address
+1:		ldmia	r0!, {r2, r3}
+		tst	r2, #PAGE_PRESENT
+		addeq	ip, ip, #1048576
+		blne	update_pte_table
+		mov	r2, r3
+		tst	r2, #PAGE_PRESENT
+		addeq	ip, ip, #1048576
+		blne	update_pte_table
+		teq	ip, #32 * 1048576
+		bne	1b
+		ldmfd	sp!, {r4, r5, pc}^
+
+/*
+ * Build the table to map from physical page number to memc page number
+ */
+		.type	memc_phys_table_32, #object
+memc_phys_table_32:
+		.irp	b7, 0x00, 0x80
+		.irp	b6, 0x00, 0x02
+		.irp	b5, 0x00, 0x04
+		.irp	b4, 0x00, 0x01
+
+		.irp	b3, 0x00, 0x40
+		.irp	b2, 0x00, 0x20
+		.irp	b1, 0x00, 0x10
+		.irp	b0, 0x00, 0x08
+		.long	0x03800300 + \b7 + \b6 + \b5 + \b4 + \b3 + \b2 + \b1 + \b0
+		.endr
+		.endr
+		.endr
+		.endr
+
+		.endr
+		.endr
+		.endr
+		.endr
+		.size	memc_phys_table_32, . - memc_phys_table_32
+
+/*
+ * helper for cpu_memc_update_all, this clears out all
+ * mappings, setting them close to the top of memory,
+ * and inaccessible (0x01f00000).
+ * Params  : r0 = page table pointer
+ */
+clear_tables:	ldr	r1, _arm3_set_pgd - 4
+		ldr	r2, [r1]
+		sub	r1, r0, #256 * 4		@ start of MEMC tables
+		add	r2, r1, r2, lsl #2		@ end of tables
+		mov	r3, #0x03f00000			@ Default mapping (null mapping)
+		orr	r3, r3, #0x00000f00
+		orr	r4, r3, #1
+		orr	r5, r3, #2
+		orr	ip, r3, #3
+1:		stmia	r1!, {r3, r4, r5, ip}
+		add	r3, r3, #4
+		add	r4, r4, #4
+		add	r5, r5, #4
+		add	ip, ip, #4
+		stmia	r1!, {r3, r4, r5, ip}
+		add	r3, r3, #4
+		add	r4, r4, #4
+		add	r5, r5, #4
+		add	ip, ip, #4
+		teq	r1, r2
+		bne	1b
+		mov	pc, lr
+
+/*
+ * Function: *_set_pgd(pgd_t *pgd)
+ * Params  : pgd	New page tables/MEMC mapping
+ * Purpose : update MEMC hardware with new mapping
+ */
+		.word	SYMBOL_NAME(page_nr)
+_arm3_set_pgd:	mcr	p15, 0, r1, c1, c0, 0		@ flush cache
+_arm2_set_pgd:	stmfd	sp!, {lr}
+		ldr	r1, _arm3_set_pgd - 4
+		ldr	r2, [r1]
+		sub	r0, r0, #256 * 4		@ start of MEMC tables
+		add	r1, r0, r2, lsl #2		@ end of tables
+1:		ldmia	r0!, {r2, r3, ip, lr}
+		strb	r2, [r2]
+		strb	r3, [r3]
+		strb	ip, [ip]
+		strb	lr, [lr]
+		ldmia	r0!, {r2, r3, ip, lr}
+		strb	r2, [r2]
+		strb	r3, [r3]
+		strb	ip, [ip]
+		strb	lr, [lr]
+		teq	r0, r1
+		bne	1b
+		ldmfd	sp!, {pc}^
+
+/*
+ * Function: *_proc_init (void)
+ * Purpose : Initialise the cache control registers
+ */
+_arm3_proc_init:
+		mov	r0, #0x001f0000
+		orr	r0, r0, #0x0000ff00
+		orr	r0, r0, #0x000000ff
+		mcr	p15, 0, r0, c3, c0		@ ARM3 Cacheable
+		mcr     p15, 0, r0, c4, c0		@ ARM3 Updateable
+		mov	r0, #0
+		mcr     p15, 0, r0, c5, c0		@ ARM3 Disruptive
+		mcr     p15, 0, r0, c1, c0		@ ARM3 Flush
+		mov	r0, #3
+		mcr     p15, 0, r0, c2, c0		@ ARM3 Control
+_arm2_proc_init:
+		movs	pc, lr
+
+/*
+ * Function: *_proc_fin (void)
+ * Purpose : Finalise processor (disable caches)
+ */
+_arm3_proc_fin:	mov	r0, #2
+		mcr	p15, 0, r0, c2, c0
+_arm2_proc_fin:	orrs	pc, lr, #I_BIT|F_BIT
+
+/*
+ * Function: *_xchg_1 (int new, volatile void *ptr)
+ * Params  : new	New value to store at...
+ *	   : ptr	pointer to byte-wide location
+ * Purpose : Performs an exchange operation
+ * Returns : Original byte data at 'ptr'
+ */
+_arm2_xchg_1:	mov	r2, pc
+		orr	r2, r2, #I_BIT
+		teqp	r2, #0
+		ldrb	r2, [r1]
+		strb	r0, [r1]
+		mov	r0, r2
+		movs	pc, lr
+
+_arm3_xchg_1:	swpb	r0, r0, [r1]
+		movs	pc, lr
+
+/*
+ * Function: *_xchg_4 (int new, volatile void *ptr)
+ * Params  : new	New value to store at...
+ *	   : ptr	pointer to word-wide location
+ * Purpose : Performs an exchange operation
+ * Returns : Original word data at 'ptr'
+ */
+_arm2_xchg_4:	mov	r2, pc
+		orr	r2, r2, #I_BIT
+		teqp	r2, #0
+		ldr	r2, [r1]
+		str	r0, [r1]
+		mov	r0, r2
+		movs	pc, lr
+
+_arm3_xchg_4:	swp	r0, r0, [r1]
+		movs	pc, lr
+
+_arm2_3_check_bugs:
+		bics	pc, lr, #0x04000000		@ Clear FIQ disable bit
+
+armvlsi_name:	.asciz	"ARM/VLSI"
+_arm2_name:	.asciz	"ARM 2"
+_arm250_name:	.asciz	"ARM 250"
+_arm3_name:	.asciz	"ARM 3"
+
+		.section ".text.init", #alloc, #execinstr
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+		.globl	SYMBOL_NAME(arm2_processor_functions)
+SYMBOL_NAME(arm2_processor_functions):
+		.word	_arm2_3_check_bugs
+		.word	_arm2_proc_init
+		.word	_arm2_proc_fin
+		.word	_arm2_set_pgd
+		.word	_arm2_xchg_1
+		.word	_arm2_xchg_4
+
+cpu_arm2_info:
+		.long	armvlsi_name
+		.long	_arm2_name
+
+		.globl	SYMBOL_NAME(arm250_processor_functions)
+SYMBOL_NAME(arm250_processor_functions):
+		.word	_arm2_3_check_bugs
+		.word	_arm2_proc_init
+		.word	_arm2_proc_fin
+		.word	_arm2_set_pgd
+		.word	_arm3_xchg_1
+		.word	_arm3_xchg_4
+
+cpu_arm250_info:
+		.long	armvlsi_name
+		.long	_arm250_name
+
+		.globl	SYMBOL_NAME(arm3_processor_functions)
+SYMBOL_NAME(arm3_processor_functions):
+		.word	_arm2_3_check_bugs
+		.word	_arm3_proc_init
+		.word	_arm3_proc_fin
+		.word	_arm3_set_pgd
+		.word	_arm3_xchg_1
+		.word	_arm3_xchg_4
+
+cpu_arm3_info:
+		.long	armvlsi_name
+		.long	_arm3_name
+
+arm2_arch_name:	.asciz	"armv1"
+arm3_arch_name:	.asciz	"armv2"
+arm2_elf_name:	.asciz	"v1"
+arm3_elf_name:	.asciz	"v2"
+		.align
+
+		.section ".proc.info", #alloc, #execinstr
+
+		.long	0x41560200
+		.long	0xfffffff0
+		.long	0
+		mov	pc, lr
+		.long	arm2_arch_name
+		.long	arm2_elf_name
+		.long	0
+		.long	cpu_arm2_info
+		.long	SYMBOL_NAME(arm2_processor_functions)
+
+		.long	0x41560250
+		.long	0xfffffff0
+		.long	0
+		mov	pc, lr
+		.long	arm3_arch_name
+		.long	arm3_elf_name
+		.long	0
+		.long	cpu_arm250_info
+		.long	SYMBOL_NAME(arm250_processor_functions)
+
+		.long	0x41560300
+		.long	0xfffffff0
+		.long	0
+		mov	pc, lr
+		.long	arm3_arch_name
+		.long	arm3_elf_name
+		.long	0
+		.long	cpu_arm3_info
+		.long	SYMBOL_NAME(arm3_processor_functions)
+
diff -urN linux-2.4.29/arch/armnommu/mm/proc-arm6,7.S linux-2.4.29-uc1/arch/armnommu/mm/proc-arm6,7.S
--- linux-2.4.29/arch/armnommu/mm/proc-arm6,7.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/proc-arm6,7.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,1006 @@
+/*
+ *  linux/arch/armnommu/mm/proc-arm6,7.S
+ *
+ *  Copyright (C) 1997-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  These are the low level assembler for performing cache and TLB
+ *  functions on the ARM610 & ARM710.
+ *  
+ * Addition of S3C4530 by Arcturus Networks Inc.
+ * Addition of TI TMS320DM270 by Chee Tim Loh <cheetim_loh@innomedia.com.sg>.
+ *
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+#include <asm/errno.h>
+#ifdef CONFIG_ARCH_DM270
+#include <asm/hardware.h>
+#endif
+
+/*
+ * Function: arm6_7_cache_clean_invalidate_all (void)
+ *	   : arm6_7_cache_clean_invalidate_page (unsigned long address, int size, int flags)
+ *
+ * Params  : address	Area start address
+ *	   : size	size of area
+ *	   : flags	b0 = I cache as well
+ *
+ * Purpose : Flush all cache lines
+ */
+ENTRY(cpu_arm6_cache_clean_invalidate_all)
+ENTRY(cpu_arm7_cache_clean_invalidate_all)
+ENTRY(cpu_arm6_cache_clean_invalidate_range)
+ENTRY(cpu_arm7_cache_clean_invalidate_range)
+ENTRY(cpu_arm6_icache_invalidate_range)
+ENTRY(cpu_arm7_icache_invalidate_range)
+ENTRY(cpu_arm6_icache_invalidate_page)
+ENTRY(cpu_arm7_icache_invalidate_page)
+ENTRY(cpu_arm6_dcache_clean_range)
+ENTRY(cpu_arm7_dcache_clean_range)
+ENTRY(cpu_arm6_dcache_invalidate_range)
+ENTRY(cpu_arm7_dcache_invalidate_range)
+		mov	r0, #0
+#ifdef CONFIG_CPU_WITH_CACHE 
+# ifdef CONFIG_CPU_WITH_MCR_INSTRUCTION
+		mcr	p15, 0, r0, c7, c0, 0		@ flush cache
+# else
+#  ifdef CONFIG_ARCH_DM270
+		/*
+		 * Flush instruction cache
+		 * 1. Save cache state
+		 * 2. Disable cache (write "0" to ICAENB)
+		 * 3. Clear cache (write "1" to ICACLR)
+		 * 4. Wait cache clear completion (wait until ICACLR is "0")
+		 * 5. Restore previous cache state
+		 */
+		ldr	r1, =DM270_ICACHE_BASE
+		ldrh	r2, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ldr	r0, =(DM270_ICACHE_ICAMODE_ICAENB | DM270_ICACHE_ICAMODE_REQ4W)
+		and	r2, r2, r0
+		mov	r0, #0
+		strh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ldr	r0, =(DM270_ICACHE_ICAMODE_ICACLR)
+		strh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+1:		ldrh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ands	r0, r0, #DM270_ICACHE_ICAMODE_ICACLR
+		bne	1b 
+		strh	r2, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+#  else
+#   warning		"FIXME: Flush cache without MCR Instruction"
+#  endif
+# endif
+#endif        
+ENTRY(cpu_arm6_dcache_clean_page)
+ENTRY(cpu_arm7_dcache_clean_page)
+ENTRY(cpu_arm6_dcache_clean_entry)
+ENTRY(cpu_arm7_dcache_clean_entry)
+ENTRY(cpu_arm6_flush_ram_page)
+ENTRY(cpu_arm7_flush_ram_page)
+		mov	pc, lr
+
+/*
+ * Function: arm6_7_tlb_invalidate_all (void)
+ *
+ * Purpose : flush all TLB entries in all caches
+ */
+ENTRY(cpu_arm6_tlb_invalidate_all)
+ENTRY(cpu_arm7_tlb_invalidate_all)
+		mov	r0, #0
+#ifndef NO_MM        
+		mcr	p15, 0, r0, c5, c0, 0		@ flush TLB
+#endif        
+		mov	pc, lr
+
+/*
+ * Function: arm6_7_tlb_invalidate_page (unsigned long address, int end, int flags)
+ *
+ * Params  : address	Area start address
+ *	   : end	Area end address
+ *	   : flags	b0 = I cache as well
+ *
+ * Purpose : flush a TLB entry
+ */
+ENTRY(cpu_arm6_tlb_invalidate_range)
+ENTRY(cpu_arm7_tlb_invalidate_range)
+#ifndef NO_MM        
+1:		mcr	p15, 0, r0, c6, c0, 0		@ flush TLB
+		add	r0, r0, #4096
+		cmp	r0, r1
+		blt	1b
+#endif        
+		mov	pc, lr
+
+/*
+ * Function: arm6_7_tlb_invalidate_page (unsigned long address, int flags)
+ *
+ * Params  : address	Address
+ *	   : flags	b0 = I-TLB as well
+ *
+ * Purpose : flush a TLB entry
+ */
+ENTRY(cpu_arm6_tlb_invalidate_page)
+ENTRY(cpu_arm7_tlb_invalidate_page)
+#ifndef NO_MM  
+		mcr	p15, 0, r0, c6, c0, 0		@ flush TLB
+#endif        
+		mov	pc, lr
+
+/*
+ * Function: arm6_7_data_abort ()
+ *
+ * Params  : r0 = address of aborted instruction
+ *
+ * Purpose : obtain information about current aborted instruction
+ *
+ * Returns : r0 = address of abort
+ *	   : r1 != 0 if writing
+ *	   : r3 = FSR
+ *	   : sp = pointer to registers
+ */
+
+ENTRY(cpu_arm6_data_abort)
+		ldr	r4, [r0]			@ read instruction causing problem
+		tst	r4, r4, lsr #21			@ C = bit 20
+		sbc	r1, r1, r1			@ r1 = C - 1
+		and	r2, r4, #14 << 24
+		teq	r2, #8 << 24			@ was it ldm/stm
+		bne	Ldata_simple
+
+Ldata_ldmstm:	tst	r4, #1 << 21			@ check writeback bit
+		beq	Ldata_simple
+		mov	r7, #0x11
+		orr	r7, r7, r7, lsl #8
+		and	r0, r4, r7
+		and	r2, r4, r7, lsl #1
+		add	r0, r0, r2, lsr #1
+		and	r2, r4, r7, lsl #2
+		add	r0, r0, r2, lsr #2
+		and	r2, r4, r7, lsl #3
+		add	r0, r0, r2, lsr #3
+		add	r0, r0, r0, lsr #8
+		add	r0, r0, r0, lsr #4
+		and	r7, r0, #15			@ r7 = no. of registers to transfer.
+		and	r5, r4, #15 << 16		@ Get Rn
+		ldr	r0, [sp, r5, lsr #14]		@ Get register
+		tst	r4, #1 << 23			@ U bit
+		subne	r7, r0, r7, lsl #2
+		addeq	r7, r0, r7, lsl #2		@ Do correction (signed)
+Ldata_saver7:	str	r7, [sp, r5, lsr #14]		@ Put register
+Ldata_simple:
+#ifdef	NO_MM
+		orr	r1, r2, #1			@ simulate FSR
+		mov	r0, #0				@ gotta have something...
+#else        
+		mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+		mrc	p15, 0, r3, c5, c0, 0		@ get FSR
+#endif        
+		and	r3, r3, #255
+#ifdef	NO_MM
+		mov	r0, #1				@ return fail
+#endif        
+		mov	pc, lr
+
+ENTRY(cpu_arm7_data_abort)
+		ldr	r4, [r0]			@ read instruction causing problem
+		tst	r4, r4, lsr #21			@ C = bit 20
+		sbc	r1, r1, r1			@ r1 = C - 1
+		and	r2, r4, #15 << 24
+		add	pc, pc, r2, lsr #22		@ Now branch to the relevent processing routine
+		movs	pc, lr
+
+		b	Ldata_unknown
+		b	Ldata_unknown
+		b	Ldata_unknown
+		b	Ldata_unknown
+		b	Ldata_lateldrpostconst		@ ldr	rd, [rn], #m
+		b	Ldata_lateldrpreconst		@ ldr	rd, [rn, #m]	@ RegVal
+		b	Ldata_lateldrpostreg		@ ldr	rd, [rn], rm
+		b	Ldata_lateldrprereg		@ ldr	rd, [rn, rm]
+		b	Ldata_ldmstm			@ ldm*a	rn, <rlist>
+		b	Ldata_ldmstm			@ ldm*b	rn, <rlist>
+		b	Ldata_unknown
+		b	Ldata_unknown
+		b	Ldata_simple			@ ldc	rd, [rn], #m	@ Same as ldr	rd, [rn], #m
+		b	Ldata_simple			@ ldc	rd, [rn, #m]
+		b	Ldata_unknown
+Ldata_unknown:	@ Part of jumptable
+		mov	r0, r2
+		mov	r1, r4
+		mov	r2, r3
+		bl	baddataabort
+@FIXME		b	ret_from_sys_call
+
+Ldata_lateldrpreconst:
+		tst	r4, #1 << 21			@ check writeback bit
+		beq	Ldata_simple
+Ldata_lateldrpostconst:
+		movs	r2, r4, lsl #20			@ Get offset
+		beq	Ldata_simple
+		and	r5, r4, #15 << 16		@ Get Rn
+		ldr	r0, [sp, r5, lsr #14]
+		tst	r4, #1 << 23			@ U bit
+		subne	r7, r0, r2, lsr #20
+		addeq	r7, r0, r2, lsr #20
+		b	Ldata_saver7
+
+Ldata_lateldrprereg:
+		tst	r4, #1 << 21			@ check writeback bit
+		beq	Ldata_simple
+Ldata_lateldrpostreg:
+		and	r5, r4, #15
+		ldr	r2, [sp, r5, lsl #2]		@ Get Rm
+		mov	r3, r4, lsr #7
+		ands	r3, r3, #31
+		and	r6, r4, #0x70
+		orreq	r6, r6, #8
+		add	pc, pc, r6
+		mov	r0, r0
+
+		mov	r2, r2, lsl r3			@ 0: LSL #!0
+		b	1f
+		b	1f				@ 1: LSL #0
+		mov	r0, r0
+		b	1f				@ 2: MUL?
+		mov	r0, r0
+		b	1f				@ 3: MUL?
+		mov	r0, r0
+		mov	r2, r2, lsr r3			@ 4: LSR #!0
+		b	1f
+		mov	r2, r2, lsr #32			@ 5: LSR #32
+		b	1f
+		b	1f				@ 6: MUL?
+		mov	r0, r0
+		b	1f				@ 7: MUL?
+		mov	r0, r0
+		mov	r2, r2, asr r3			@ 8: ASR #!0
+		b	1f
+		mov	r2, r2, asr #32			@ 9: ASR #32
+		b	1f
+		b	1f				@ A: MUL?
+		mov	r0, r0
+		b	1f				@ B: MUL?
+		mov	r0, r0
+		mov	r2, r2, ror r3			@ C: ROR #!0
+		b	1f
+		mov	r2, r2, rrx			@ D: RRX
+		b	1f
+		mov	r0, r0				@ E: MUL?
+		mov	r0, r0
+		mov	r0, r0				@ F: MUL?
+
+
+1:		and	r5, r4, #15 << 16		@ Get Rn
+		ldr	r0, [sp, r5, lsr #14]
+		tst	r4, #1 << 23			@ U bit
+		subne	r7, r0, r2
+		addeq	r7, r0, r2
+		b	Ldata_saver7
+
+/*
+ * Function: arm6_7_check_bugs (void)
+ *	   : arm6_7_proc_init (void)
+ *	   : arm6_7_proc_fin (void)
+ *
+ * Notes   : This processor does not require these
+ */
+ENTRY(cpu_arm6_check_bugs)
+ENTRY(cpu_arm7_check_bugs)
+		mrs	ip, cpsr
+		bic	ip, ip, #F_BIT
+		msr	cpsr, ip
+		mov	pc, lr
+
+ENTRY(cpu_arm6_proc_init)
+ENTRY(cpu_arm7_proc_init)
+		mov	pc, lr
+
+ENTRY(cpu_arm6_proc_fin)
+ENTRY(cpu_arm7_proc_fin)
+		mov	r0, #F_BIT | I_BIT | SVC_MODE
+		msr	cpsr_c, r0
+#ifndef	NO_MM
+		mov	r0, #0x31			@ ....S..DP...M
+		mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+#else
+# ifdef CONFIG_CPU_WITH_CACHE
+#  ifdef CONFIG_CPU_WITH_MCR_INSTRUCTION
+		mov	r0, #0x30			@ .......DP....
+		mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+#  else
+#   ifdef CONFIG_ARCH_DM270
+		/*
+		 * Disasble instruction cache
+		 * 1. Disable cache (write "0" to ICAENB)
+		 */
+		ldr	r1, =DM270_ICACHE_BASE
+		mov	r0, #0
+		strh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+#   else
+#    warning	"FIXME: Disable cache without MCR Instruction"
+#   endif
+#  endif
+# endif
+#endif        
+		mov	pc, lr
+
+ENTRY(cpu_arm6_do_idle)
+ENTRY(cpu_arm7_do_idle)
+		mov	r0, #-EINVAL
+		mov	pc, lr
+
+/*
+ * Function: arm6_7_set_pgd(unsigned long pgd_phys)
+ * Params  : pgd_phys	Physical address of page table
+ * Purpose : Perform a task switch, saving the old processes state, and restoring
+ *	     the new.
+ */
+ENTRY(cpu_arm6_set_pgd)
+ENTRY(cpu_arm7_set_pgd)
+		mov	r1, #0
+#ifdef CONFIG_CPU_WITH_CACHE
+# ifdef CONFIG_CPU_WITH_MCR_INSTRUCTION
+		mcr	p15, 0, r1, c7, c0, 0		@ flush cache
+# else
+#  ifdef CONFIG_ARCH_DM270
+		/*
+		 * Flush instruction cache
+		 * 1. Save cache state
+		 * 2. Disable cache (write "0" to ICAENB)
+		 * 3. Clear cache (write "1" to ICACLR)
+		 * 4. Wait cache clear completion (wait until ICACLR is "0")
+		 * 5. Restore previous cache state
+		 */
+		ldr	r1, =DM270_ICACHE_BASE
+		ldrh	r2, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ldr	r0, =(DM270_ICACHE_ICAMODE_ICAENB | DM270_ICACHE_ICAMODE_REQ4W)
+		and	r2, r2, r0
+		mov	r0, #0
+		strh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ldr	r0, =(DM270_ICACHE_ICAMODE_ICACLR)
+		strh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+1:		ldrh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ands	r0, r0, #DM270_ICACHE_ICAMODE_ICACLR
+		bne	1b 
+		strh	r2, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+#  else
+#   warning		"FIXME: Flush cache without MCR Instruction"
+#  endif
+# endif
+#endif
+#ifndef	NO_MM       
+		mcr	p15, 0, r0, c2, c0, 0		@ update page table ptr
+		mcr	p15, 0, r1, c5, c0, 0		@ flush TLBs
+#endif        
+		mov	pc, lr
+
+/*
+ * Function: arm6_set_pmd ()
+ *
+ * Params  : r0 = Address to set
+ *	   : r1 = value to set
+ *
+ * Purpose : Set a PMD and flush it out of any WB cache
+ */
+ENTRY(cpu_arm6_set_pmd)
+		and	r2, r1, #11
+		teq	r2, #1
+		teqne	r2, #9
+		teqne	r2, #10
+		orreq	r1, r1, #16			@ Updatable = 1 if Page table/Cacheable section
+		str	r1, [r0]
+		mov	pc, lr
+
+/*
+ * Function: arm7_set_pmd ()
+ *
+ * Params  : r0 = Address to set
+ *	   : r1 = value to set
+ *
+ * Purpose : Set a PMD and flush it out of any WB cache
+ */
+ENTRY(cpu_arm7_set_pmd)
+		tst	r1, #3
+		orrne	r1, r1, #16			@ Updatable bit is always set on ARM7
+		str	r1, [r0]
+		mov	pc, lr
+
+/*
+ * Function: arm6_7_set_pte(pte_t *ptep, pte_t pte)
+ * Params  : r0 = Address to set
+ *	   : r1 = value to set
+ * Purpose : Set a PTE and flush it out of any WB cache
+ */
+		.align	5
+ENTRY(cpu_arm6_set_pte)
+ENTRY(cpu_arm7_set_pte)
+		str	r1, [r0], #-1024		@ linux version
+
+		eor	r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
+		bic	r2, r1, #0xff0
+		bic	r2, r2, #3
+		orr	r2, r2, #HPTE_TYPE_SMALL
+
+		tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+		orrne	r2, r2, #HPTE_AP_READ
+
+		tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
+		orreq	r2, r2, #HPTE_AP_WRITE
+
+		tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young
+		movne	r2, #0
+
+		str	r2, [r0]			@ hardware version
+		mov	pc, lr
+
+/*
+ * Function: _arm6_7_reset
+ * Params  : r0 = address to jump to
+ * Notes   : This sets up everything for a reset
+ */
+ENTRY(cpu_arm6_reset)
+ENTRY(cpu_arm7_reset)
+		mov	r1, #0
+#ifdef CONFIG_CPU_WITH_CACHE
+# ifdef CONFIG_CPU_WITH_MCR_INSTRUCTION
+		mcr	p15, 0, r1, c7, c0, 0		@ flush cache
+		mov	r1, #0x30
+		mcr	p15, 0, r1, c1, c0, 0		@ turn off Cache etc
+# else
+#  ifdef CONFIG_ARCH_DM270
+		/*
+		 * Flush and disable instruction cache
+		 * 1. Disable cache (write "0" to ICAENB)
+		 * 2. Clear cache (write "1" to ICACLR)
+		 * 3. Wait cache clear completion (wait until ICACLR is "0")
+		 */
+		ldr	r2, =DM270_ICACHE_BASE
+		mov	r1, #0
+		strh	r1, [r2, #DM270_ICACHE_OFFSET_ICAMODE]
+		ldr	r1, =(DM270_ICACHE_ICAMODE_ICACLR)
+		strh	r1, [r2, #DM270_ICACHE_OFFSET_ICAMODE]
+1:		ldrh	r1, [r2, #DM270_ICACHE_OFFSET_ICAMODE]
+		ands	r1, r1, #DM270_ICACHE_ICAMODE_ICACLR
+		bne	1b 
+#  else
+#   warning		"FIXME: Flush and Disable cache without MCR Instruction"
+#  endif
+# endif
+#endif
+#ifndef	NO_MM        
+		mcr	p15, 0, r1, c5, c0, 0		@ flush TLB
+		mov	r1, #0x30
+		mcr	p15, 0, r1, c1, c0, 0		@ turn off MMU etc
+#endif        
+		mov	pc, r0
+
+cpu_armvlsi_name:
+		.asciz	"ARM/VLSI"
+cpu_triscenda7s_name:
+		.asciz	"Triscend-A7S"
+cpu_triscenda7v_name:
+		.asciz	"Triscend-A7V"
+cpu_arm6_name:	.asciz	"ARM 6"
+cpu_arm610_name:
+		.asciz	"ARM 610"
+cpu_arm7_name:	.asciz	"ARM 7"
+cpu_arm710_name:
+		.asciz	"ARM 710"
+cpu_arm7tdmi_name:
+		.asciz	"ARM 7 TDMI"
+cpu_at91_manu_name:
+		.asciz	"Atmel"
+cpu_at91_name:
+		.asciz	"AT91M40xxx"
+cpu_netarm_manu_name:
+    .asciz  "NetSilicon"
+cpu_netarm_name:
+    .asciz  "ARM7TDMI"
+cpu_s3c3410_manu_name:
+cpu_s3c4510b_manu_name:
+cpu_s3c4530_manu_name:
+cpu_s3c44b0x_manu_name:
+		.asciz	"Samsung"
+cpu_s3c3410_name:
+		.asciz	"S3C3410X"
+cpu_s3c4510b_name:
+		.asciz	"S3C4510B"
+cpu_s3c4530_name:
+		.asciz  "S3C4530A01"
+cpu_s3c44b0x_name:
+		.asciz  "S3C44B0X"
+cpu_dm270_manu_name:
+		.asciz	"TI"
+cpu_dm270_name:
+		.asciz	"TMS320DM270"
+                .align
+
+		.section ".text.init", #alloc, #execinstr
+
+__arm6_setup:	mov	r0, #F_BIT | I_BIT | SVC_MODE
+		msr	cpsr_c, r0
+		mov	r0, #0
+#ifdef CONFIG_CPU_WITH_CACHE
+# ifdef CONFIG_CPU_WITH_MCR_INSTRUCTION
+		mcr	p15, 0, r0, c7, c0		@ flush caches on v3
+# else
+#  ifdef CONFIG_ARCH_DM270
+		/*
+		 * Flush instruction cache
+		 * 1. Save cache state
+		 * 2. Disable cache (write "0" to ICAENB)
+		 * 3. Clear cache (write "1" to ICACLR)
+		 * 4. Wait cache clear completion (wait until ICACLR is "0")
+		 * 5. Restore previous cache state
+		 */
+		ldr	r1, =DM270_ICACHE_BASE
+		ldrh	r2, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ldr	r0, =(DM270_ICACHE_ICAMODE_ICAENB | DM270_ICACHE_ICAMODE_REQ4W)
+		and	r2, r2, r0
+		mov	r0, #0
+		strh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ldr	r0, =(DM270_ICACHE_ICAMODE_ICACLR)
+		strh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+1:		ldrh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ands	r0, r0, #DM270_ICACHE_ICAMODE_ICACLR
+		bne	1b 
+		strh	r2, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+#  else
+#   warning		"FIXME: Flush cache without MCR Instruction"
+		@ldr	r2, CACHE_CONTROL_MEM_LOCATION
+		@str	r0, [r2]
+#  endif
+# endif
+#endif
+#ifndef NO_MM
+		mcr	p15, 0, r0, c5, c0		@ flush TLBs on v3
+		mcr	p15, 0, r4, c2, c0		@ load page table pointer
+		mov	r0, #0x1f			@ Domains 0, 1 = client
+		mcr	p15, 0, r0, c3, c0		@ load domain access register
+		mov	r0, #0x3d			@ ....S..DPWC.M
+		orr	r0, r0, #0x100
+#endif
+#ifdef CONFIG_CPU_WITH_CACHE
+# ifdef CONFIG_CPU_WITH_MCR_INSTRUCTION
+		mov	r0, #0x3c			@ .......DPWC..
+# else 
+#  ifdef CONFIG_ARCH_DM270
+		/*
+		 * Turn on instruction cache
+		 * 1. Disable cache (write "0" to ICAENB)
+		 * 2. Clear cache (write "1" to ICACLR)
+		 * 3. Wait cache clear completion (wait until ICACLR is "0")
+		 * 4. Enable cache (write "1" to ICAENB)
+		 */
+		ldr	r1, =DM270_ICACHE_BASE
+		mov	r0, #0
+		strh	r0, [r1,#DM270_ICACHE_OFFSET_ICAMODE]
+		ldr	r0, =(DM270_ICACHE_ICAMODE_ICACLR)
+		strh	r0, [r1,#DM270_ICACHE_OFFSET_ICAMODE]
+1:		ldrh	r0, [r1,#DM270_ICACHE_OFFSET_ICAMODE]
+		ands	r0, r0, #DM270_ICACHE_ICAMODE_ICACLR
+		bne	1b
+		ldr	r0, =(DM270_ICACHE_ICAMODE_ICAENB | DM270_ICACHE_ICAMODE_REQ4W)
+		strh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		mov	r0, #0x0			
+#  else
+#   warning		"FIXME: Enable Cache and Others without MCR Instruction"
+#  endif
+# endif
+#else
+		@ Just in case r0 is modified by any code above			
+		mov	r0, #0x0			
+# warning		"FIXME: Setup anything if required"
+#endif
+		mov	pc, lr
+
+__arm7_setup:	mov	r0, #F_BIT | I_BIT | SVC_MODE
+		msr	cpsr_c, r0
+		mov	r0, #0
+#ifdef CONFIG_CPU_WITH_CACHE
+# ifdef CONFIG_CPU_WITH_MCR_INSTRUCTION
+		mcr	p15, 0, r0, c7, c0		@ flush caches on v3
+# else
+#  ifdef CONFIG_ARCH_DM270
+		/*
+		 * Flush instruction cache
+		 * 1. Save cache state
+		 * 2. Disable cache (write "0" to ICAENB)
+		 * 3. Clear cache (write "1" to ICACLR)
+		 * 4. Wait cache clear completion (wait until ICACLR is "0")
+		 * 5. Restore previous cache state
+		 */
+		ldr	r1, =DM270_ICACHE_BASE
+		ldrh	r2, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ldr	r0, =(DM270_ICACHE_ICAMODE_ICAENB | DM270_ICACHE_ICAMODE_REQ4W)
+		and	r2, r2, r0
+		mov	r0, #0
+		strh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ldr	r0, =(DM270_ICACHE_ICAMODE_ICACLR)
+		strh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+1:		ldrh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		ands	r0, r0, #DM270_ICACHE_ICAMODE_ICACLR
+		bne	1b 
+		strh	r2, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+#  else
+#   warning		"FIXME: Flush cache without MCR Instruction"
+		@ldr	r2, CACHE_CONTROL_MEM_LOCATION
+		@str	r0, [r2]
+#  endif
+# endif
+#endif
+#ifndef	NO_MM        
+		mcr	p15, 0, r0, c5, c0		@ flush TLBs on v3
+		mcr	p15, 0, r4, c2, c0		@ load page table pointer
+		mov	r0, #0x1f			@ Domains 0, 1 = client
+		mcr	p15, 0, r0, c3, c0		@ load domain access register
+		mov	r0, #0x7d			@ ....S.LDPWC.M
+		orr	r0, r0, #0x100
+#endif
+#ifdef CONFIG_CPU_WITH_CACHE
+# ifdef CONFIG_CPU_WITH_MCR_INSTRUCTION
+		mov	r0, #0x7c			@ ......LDPWC..
+# else 
+#  ifdef CONFIG_ARCH_DM270
+		/*
+		 * Turn on instruction cache
+		 * 1. Disable cache (write "0" to ICAENB)
+		 * 2. Clear cache (write "1" to ICACLR)
+		 * 3. Wait cache clear completion (wait until ICACLR is "0")
+		 * 4. Enable cache (write "1" to ICAENB)
+		 */
+		ldr	r1, =DM270_ICACHE_BASE
+		mov	r0, #0
+		strh	r0, [r1,#DM270_ICACHE_OFFSET_ICAMODE]
+		ldr	r0, =(DM270_ICACHE_ICAMODE_ICACLR)
+		strh	r0, [r1,#DM270_ICACHE_OFFSET_ICAMODE]
+1:		ldrh	r0, [r1,#DM270_ICACHE_OFFSET_ICAMODE]
+		ands	r0, r0, #DM270_ICACHE_ICAMODE_ICACLR
+		bne	1b
+		ldr	r0, =(DM270_ICACHE_ICAMODE_ICAENB | DM270_ICACHE_ICAMODE_REQ4W)
+		strh	r0, [r1, #DM270_ICACHE_OFFSET_ICAMODE]
+		mov	r0, #0x0			
+#  else
+#   warning		"FIXME: Enable Cache and Others without MCR Instruction"
+#  endif
+# endif
+#else
+		@ Just in case r0 is modified by any code above			
+		mov	r0, #0x0			
+# warning		"FIXME: Setup anything if required"
+#endif
+		mov	pc, lr
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+		.type	arm6_processor_functions, #object
+ENTRY(arm6_processor_functions)
+		.word	cpu_arm6_data_abort
+		.word	cpu_arm6_check_bugs
+		.word	cpu_arm6_proc_init
+		.word	cpu_arm6_proc_fin
+		.word	cpu_arm6_reset
+		.word	cpu_arm6_do_idle
+
+		/* cache */
+		.word	cpu_arm6_cache_clean_invalidate_all
+		.word	cpu_arm6_cache_clean_invalidate_range
+		.word	cpu_arm6_flush_ram_page
+
+		/* dcache */
+		.word	cpu_arm6_dcache_invalidate_range
+		.word	cpu_arm6_dcache_clean_range
+		.word	cpu_arm6_dcache_clean_page
+		.word	cpu_arm6_dcache_clean_entry
+
+		/* icache */
+		.word	cpu_arm6_icache_invalidate_range
+		.word	cpu_arm6_icache_invalidate_page
+
+		/* tlb */
+		.word	cpu_arm6_tlb_invalidate_all
+		.word	cpu_arm6_tlb_invalidate_range
+		.word	cpu_arm6_tlb_invalidate_page
+
+		/* pgtable */
+		.word	cpu_arm6_set_pgd
+		.word	cpu_arm6_set_pmd
+		.word	cpu_arm6_set_pte
+		.size	arm6_processor_functions, . - arm6_processor_functions
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+		.type	arm7_processor_functions, #object
+ENTRY(arm7_processor_functions)
+		.word	cpu_arm7_data_abort
+		.word	cpu_arm7_check_bugs
+		.word	cpu_arm7_proc_init
+		.word	cpu_arm7_proc_fin
+		.word	cpu_arm7_reset
+		.word	cpu_arm7_do_idle
+
+		/* cache */
+		.word	cpu_arm7_cache_clean_invalidate_all
+		.word	cpu_arm7_cache_clean_invalidate_range
+		.word	cpu_arm7_flush_ram_page
+
+		/* dcache */
+		.word	cpu_arm7_dcache_invalidate_range
+		.word	cpu_arm7_dcache_clean_range
+		.word	cpu_arm7_dcache_clean_page
+		.word	cpu_arm7_dcache_clean_entry
+
+		/* icache */
+		.word	cpu_arm7_icache_invalidate_range
+		.word	cpu_arm7_icache_invalidate_page
+
+		/* tlb */
+		.word	cpu_arm7_tlb_invalidate_all
+		.word	cpu_arm7_tlb_invalidate_range
+		.word	cpu_arm7_tlb_invalidate_page
+
+		/* pgtable */
+		.word	cpu_arm7_set_pgd
+		.word	cpu_arm7_set_pmd
+		.word	cpu_arm7_set_pte
+		.size	arm7_processor_functions, . - arm7_processor_functions
+
+		.type	cpu_arm6_info, #object
+cpu_arm6_info:
+		.long	cpu_armvlsi_name
+		.long	cpu_arm6_name
+		.size	cpu_arm6_info, . - cpu_arm6_info
+
+		.type	cpu_arm610_info, #object
+cpu_arm610_info:
+		.long	cpu_armvlsi_name
+		.long	cpu_arm610_name
+		.size	cpu_arm610_info, . - cpu_Arm610_info
+
+		.type	cpu_arm7_info, #object
+cpu_arm7_info:
+		.long	cpu_armvlsi_name
+		.long	cpu_arm7_name
+		.size	cpu_arm7_info, . - cpu_arm7_info
+
+		.type	cpu_arm7tdmi_info, #object
+cpu_arm7tdmi_info:
+		.long   cpu_armvlsi_name
+		.long   cpu_arm7tdmi_name
+		.size   cpu_arm7tdmi_info, . - cpu_arm7tdmi_info
+
+		.type	cpu_triscenda7_info, #object
+cpu_triscenda7_info:
+#if defined(CONFIG_ARCH_TA7S)
+		.long	cpu_triscenda7s_name
+#elif defined(CONFIG_ARCH_TA7V)
+		.long	cpu_triscenda7v_name
+#endif
+		.long	cpu_arm7tdmi_name
+		.size	cpu_triscenda7_info, . - cpu_triscenda7_info
+
+		.type	cpu_at91_info, #object
+cpu_at91_info:
+		.long	cpu_at91_manu_name
+		.long	cpu_at91_name
+		.size	cpu_at91_info, . - cpu_at91_info
+
+		.type	cpu_s3c3410_info, #object
+cpu_s3c3410_info:
+		.long	cpu_s3c3410_manu_name
+		.long	cpu_s3c3410_name
+		.size	cpu_s3c3410_info, . - cpu_s3c3410_info
+
+		.type	cpu_s3c44b0x_info, #object
+cpu_s3c44b0x_info:
+		.long	cpu_s3c44b0x_manu_name
+		.long	cpu_s3c44b0x_name
+		.size	cpu_s3c44b0x_info, . - cpu_s3c44b0x_info
+
+		.type	cpu_s3c4510b_info, #object
+cpu_s3c4510b_info:
+		.long	cpu_s3c4510b_manu_name
+		.long	cpu_s3c4510b_name
+		.size	cpu_s3c4510b_info, . - cpu_s3c4510b_info
+
+                .type   cpu_s3c4530_info, #object
+cpu_s3c4530_info:
+                .long   cpu_s3c4530_manu_name
+                .long   cpu_s3c4530_name
+                .size   cpu_s3c4530_info, . - cpu_s3c4530_info
+
+		.type	cpu_dm270_info, #object
+cpu_dm270_info:
+		.long	cpu_dm270_manu_name
+		.long	cpu_dm270_name
+		.size	cpu_dm270_info, . - cpu_dm270_info
+
+		.type	cpu_arm710_info, #object
+cpu_arm710_info:
+		.long	cpu_armvlsi_name
+		.long	cpu_arm710_name
+		.size	cpu_arm710_info, . - cpu_arm710_info
+
+    .type cpu_netarm_info, #object
+cpu_netarm_info:
+    .long cpu_netarm_manu_name
+    .long cpu_netarm_name
+    .size cpu_netarm_info, . - cpu_netarm_info
+
+		.type	cpu_arch_name, #object
+cpu_arch_name:	.asciz	"armv3"
+		.size	cpu_arch_name, . - cpu_arch_name
+
+		.type	cpu_elf_name, #object
+cpu_elf_name:	.asciz	"v3"
+		.size	cpu_elf_name, . - cpu_elf_name
+
+		.align
+		.section ".proc.info", #alloc, #execinstr
+
+		.type	__arm6_proc_info, #object
+__arm6_proc_info:
+		.long	0x41560600
+		.long	0xfffffff0
+		.long	0x00000c1e
+		b	__arm6_setup
+		.long	cpu_arch_name
+		.long	cpu_elf_name
+		.long	HWCAP_SWP | HWCAP_26BIT
+		.long	cpu_arm6_info
+		.long	arm6_processor_functions
+		.size	__arm6_proc_info, . - __arm6_proc_info
+
+		.type	__arm610_proc_info, #object
+__arm610_proc_info:
+		.long	0x41560610
+		.long	0xfffffff0
+		.long	0x00000c1e
+		b	__arm6_setup
+		.long	cpu_arch_name
+		.long	cpu_elf_name
+		.long	HWCAP_SWP | HWCAP_26BIT
+		.long	cpu_arm610_info
+		.long	arm6_processor_functions
+		.size	__arm610_proc_info, . - __arm610_proc_info
+
+		.type	__arm7_proc_info, #object
+__arm7_proc_info:
+		.long	0x41007000
+		.long	0xffffff00
+		.long	0x00000c1e
+		b	__arm7_setup
+		.long	cpu_arch_name
+		.long	cpu_elf_name
+		.long	HWCAP_SWP | HWCAP_26BIT
+		.long	cpu_arm7_info
+		.long	arm7_processor_functions
+		.size	__arm7_proc_info, . - __arm7_proc_info
+
+		.type	__arm710_proc_info, #object
+__arm710_proc_info:
+		.long	0x41007100
+		.long	0xfff8ff00
+		.long	0x00000c1e
+		b	__arm7_setup
+		.long	cpu_arch_name
+		.long	cpu_elf_name
+		.long	HWCAP_SWP | HWCAP_26BIT
+		.long	cpu_arm710_info
+		.long	arm7_processor_functions
+		.size	__arm710_proc_info, . - __arm710_proc_info
+
+		.type	__arm7tdmi_proc_info, #object
+__arm7tdmi_proc_info:
+		.long	0x41007700
+		.long	0xfff8ff00
+		.long	0x00000c1e
+		b	__arm7_setup
+		.long	cpu_arch_name
+		.long	cpu_elf_name
+		.long	HWCAP_SWP | HWCAP_26BIT
+		.long	cpu_arm7tdmi_info
+		.long	arm7_processor_functions
+		.size	__arm7tdmi_proc_info, . - __arm7tdmi_proc_info
+
+		.type	__triscenda7_proc_info, #object
+__triscenda7_proc_info:
+		.long	0x0001d2ff
+		.long	0x0001ffff
+		.long	0x00000c1e
+		b	__arm7_setup
+		.long	cpu_arch_name
+		.long	cpu_elf_name
+		.long	HWCAP_SWP | HWCAP_26BIT
+		.long	cpu_triscenda7_info
+		.long	arm7_processor_functions
+		.size	__triscenda7_proc_info, . - __triscenda7_proc_info
+
+		.type	__at91_proc_info, #object
+__at91_proc_info:
+		.long	0x14000040
+		.long	0xfff000e0
+		.long	0x00000c1e
+		b	__arm7_setup
+		.long	cpu_arch_name
+		.long	cpu_elf_name
+		.long	HWCAP_SWP | HWCAP_26BIT
+		.long	cpu_at91_info
+		.long	arm7_processor_functions
+		.size	__at91_proc_info, . - __at91_proc_info
+
+		.type	__s3c4510b_proc_info, #object
+__s3c4510b_proc_info:
+                .long   0x36365000                      @ cpu_val
+                .long   0xfffff000                      @ cpu_mask
+                .long   0x00000c1e                      @ __cpu_mmu_flags
+                b       __arm7_setup                    @ __cpu_flush
+                .long   cpu_arch_name                   @ arch_name
+                .long   cpu_elf_name                    @ elf_name
+                .long   HWCAP_SWP | HWCAP_26BIT         @ elf_hwcap
+                .long   cpu_s3c4510b_info               @ info
+                .long   arm7_processor_functions        @ info
+                .size   __s3c4510b_proc_info, . - __s3c4510b_proc_info
+
+		.type	__s3c4530_proc_info, #object
+__s3c4530_proc_info:
+		.long	0x4c000000			@ cpu_val
+		.long	0xfff000e0			@ cpu_mask
+		.long	0x00000c1e			@ __cpu_mmu_flags
+		b	__arm7_setup			@ __cpu_flush
+		.long	cpu_arch_name			@ arch_name
+		.long	cpu_elf_name			@ elf_name
+		.long	HWCAP_SWP | HWCAP_26BIT		@ elf_hwcap
+		.long	cpu_s3c4530_info		@ info
+		.long	arm7_processor_functions	@ info
+		.size	__s3c4530_proc_info, . - __s3c4530_proc_info
+
+		.type   __s3c3410_proc_info, #object
+__s3c3410_proc_info:
+		.long	0x34100000			@ cpu_val
+		.long	0xffff0000			@ cpu_mask
+		.long	0x00000c1e			@ __cpu_mmu_flags
+		b	__arm7_setup			@ __cpu_flush
+		.long	cpu_arch_name			@ arch_name
+		.long	cpu_elf_name			@ elf_name
+		.long	HWCAP_SWP | HWCAP_26BIT		@ elf_hwcap
+		.long	cpu_s3c3410_info		@ info
+		.long	arm7_processor_functions	@ info
+		.size	__s3c3410_proc_info, . - __s3c3410_proc_info
+
+		.type   __s3c44b0x_proc_info, #object
+__s3c44b0x_proc_info:
+		.long	0x44b00000			@ cpu_val
+		.long	0xffff0000			@ cpu_mask
+		.long	0x00000c1e			@ __cpu_mmu_flags
+		b	__arm7_setup			@ __cpu_flush
+		.long	cpu_arch_name			@ arch_name
+		.long	cpu_elf_name			@ elf_name
+		.long	HWCAP_SWP | HWCAP_26BIT		@ elf_hwcap
+		.long	cpu_s3c44b0x_info		@ info
+		.long	arm7_processor_functions	@ info
+		.size	__s3c44b0x_proc_info, . - __s3c44b0x_proc_info
+
+		.type   __dm270_proc_info, #object
+__dm270_proc_info:
+		.long	0xd2700000			@ cpu_val
+		.long	0xffff0000			@ cpu_mask
+		.long	0x00000c1e			@ __cpu_mmu_flags
+		b	__arm7_setup			@ __cpu_flush
+		.long	cpu_arch_name			@ arch_name
+		.long	cpu_elf_name			@ elf_name
+		.long	HWCAP_SWP | HWCAP_26BIT		@ elf_hwcap
+		.long	cpu_dm270_info			@ info
+		.long	arm7_processor_functions	@ info
+		.size	__dm270_proc_info, . - __dm270_proc_info
+
diff -urN linux-2.4.29/arch/armnommu/mm/proc-arm720.S linux-2.4.29-uc1/arch/armnommu/mm/proc-arm720.S
--- linux-2.4.29/arch/armnommu/mm/proc-arm720.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/proc-arm720.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,456 @@
+/*
+ *  linux/arch/arm/mm/proc-arm720.S: MMU functions for ARM720
+ *
+ *  Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
+ *                     Rob Scott (rscott@mtrob.fdns.net)
+ *  Copyright (C) 2000 ARM Limited, Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the ARM720T.  The ARM720T has a writethrough IDC
+ * cache, so we don't need to clean it.
+ *
+ *  Changelog:
+ *   05-09-2000 SJH	Created by moving 720 specific functions
+ *			out of 'proc-arm6,7.S' per RMK discussion
+ *   07-25-2000 SJH	Added idle function.
+ *   08-25-2000	DBS	Updated for integration of ARM Ltd version.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+#include <asm/hardware.h>
+
+/*
+ * Function: arm720_cache_clean_invalidate_all (void)
+ *	   : arm720_cache_clean_invalidate_page (unsigned long address, int size,
+ *                                    int flags)
+ *
+ * Params  : address	Area start address
+ *	   : size	size of area
+ *	   : flags	b0 = I cache as well
+ *
+ * Purpose : Flush all cache lines
+ */
+ENTRY(cpu_arm720_cache_clean_invalidate_all)
+ENTRY(cpu_arm720_cache_clean_invalidate_range)
+ENTRY(cpu_arm720_icache_invalidate_range)
+ENTRY(cpu_arm720_icache_invalidate_page)
+ENTRY(cpu_arm720_dcache_invalidate_range)
+		mov	r0, #0
+		mcr	p15, 0, r0, c7, c7, 0		@ flush cache
+		mov	pc, lr
+
+/*
+ * These just expect cache lines to be cleaned.  Since we have a writethrough
+ * cache, we never have any dirty cachelines to worry about.
+ */
+ENTRY(cpu_arm720_dcache_clean_range)
+ENTRY(cpu_arm720_dcache_clean_page)
+ENTRY(cpu_arm720_dcache_clean_entry)
+ENTRY(cpu_arm720_flush_ram_page)
+		mov	pc, lr
+
+/*
+ * Function: arm720_tlb_invalidate_all (void)
+ *
+ * Purpose : flush all TLB entries in all caches
+ */
+ENTRY(cpu_arm720_tlb_invalidate_all)
+		mov	r0, #0
+		mcr	p15, 0, r0, c8, c7, 0		@ flush TLB (v4)
+		mov	pc, lr
+
+/*
+ * Function: arm720_tlb_invalidate_page (unsigned long address, int end, int flags)
+ *
+ * Params  : address	Area start address
+ *	   : end	Area end address
+ *	   : flags	b0 = I cache as well
+ *
+ * Purpose : flush a TLB entry
+ */
+ENTRY(cpu_arm720_tlb_invalidate_range)
+1:		mcr	p15, 0, r0, c8, c7, 1		@ flush TLB (v4)
+		add	r0, r0, #4096
+		cmp	r0, r1
+		blt	1b
+		mov	pc, lr
+
+/*
+ * Function: arm720_tlb_invalidate_page (unsigned long address, int flags)
+ *
+ * Params  : address	Address
+ *	   : flags	b0 = I-TLB as well
+ *
+ * Purpose : flush a TLB entry
+ */
+ENTRY(cpu_arm720_tlb_invalidate_page)
+		mcr	p15, 0, r0, c8, c7, 1		@ flush TLB (v4)
+		mov	pc, lr
+
+/*
+ * Function: arm720_data_abort ()
+ *
+ * Params  : r0 = address of aborted instruction
+ *
+ * Purpose : obtain information about current aborted instruction
+ *
+ * Returns : r0 = address of abort
+ *	   : r1 != 0 if writing
+ *	   : r3 = FSR
+ *	   : sp = pointer to registers
+ */
+
+Ldata_ldmstm:	tst	r4, #1 << 21			@ check writeback bit
+		beq	Ldata_simple
+		mov	r7, #0x11
+		orr	r7, r7, r7, lsl #8
+		and	r0, r4, r7
+		and	r2, r4, r7, lsl #1
+		add	r0, r0, r2, lsr #1
+		and	r2, r4, r7, lsl #2
+		add	r0, r0, r2, lsr #2
+		and	r2, r4, r7, lsl #3
+		add	r0, r0, r2, lsr #3
+		add	r0, r0, r0, lsr #8
+		add	r0, r0, r0, lsr #4
+		and	r7, r0, #15			@ r7 = no. of registers to transfer.
+		and	r5, r4, #15 << 16		@ Get Rn
+		ldr	r0, [sp, r5, lsr #14]		@ Get register
+		tst	r4, #1 << 23			@ U bit
+		subne	r7, r0, r7, lsl #2
+		addeq	r7, r0, r7, lsl #2		@ Do correction (signed)
+Ldata_saver7:	str	r7, [sp, r5, lsr #14]		@ Put register
+Ldata_simple:	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+		mrc	p15, 0, r3, c5, c0, 0		@ get FSR
+		and	r3, r3, #255
+		mov	pc, lr
+
+ENTRY(cpu_arm720_data_abort)
+		ldr	r4, [r0]			@ read instruction causing problem
+		tst	r4, r4, lsr #21			@ C = bit 20
+		sbc	r1, r1, r1			@ r1 = C - 1
+		and	r2, r4, #15 << 24
+		add	pc, pc, r2, lsr #22		@ Now branch to the relevent processing routine
+		movs	pc, lr
+
+		b	Ldata_lateldrhpost		@ ldrh	rd, [rn], #m/rm
+		b	Ldata_lateldrhpre		@ ldrh	rd, [rn, #m/rm]
+		b	Ldata_unknown
+		b	Ldata_unknown
+		b	Ldata_lateldrpostconst		@ ldr	rd, [rn], #m
+		b	Ldata_lateldrpreconst		@ ldr	rd, [rn, #m] 
+		b	Ldata_lateldrpostreg		@ ldr	rd, [rn], rm
+		b	Ldata_lateldrprereg		@ ldr	rd, [rn, rm]
+		b	Ldata_ldmstm			@ ldm*a	rn, <rlist>
+		b	Ldata_ldmstm			@ ldm*b	rn, <rlist>
+		b	Ldata_unknown
+		b	Ldata_unknown
+		b	Ldata_simple			@ ldc	rd, [rn], #m	@ Same as ldr	rd, [rn], #m
+		b	Ldata_simple			@ ldc	rd, [rn, #m]
+		b	Ldata_unknown
+
+Ldata_unknown:	@ Part of jumptable
+		mov	r0, r2
+		mov	r1, r4
+		mov	r2, r3
+		bl	baddataabort
+		b	ret_from_exception
+
+Ldata_lateldrhpre:
+		tst	r4, #1 << 21			@ check writeback bit
+		beq	Ldata_simple
+Ldata_lateldrhpost:
+		and	r5, r4, #0x00f			@ get Rm / low nibble of immediate value
+		tst	r4, #1 << 22			@ if (immediate offset)
+		andne	r2, r4, #0xf00			@ { immediate high nibble
+		orrne	r2, r5, r2, lsr #4		@   combine nibbles } else
+		ldreq	r2, [sp, r5, lsl #2]		@ { load Rm value }
+		and	r5, r4, #15 << 16		@ get Rn
+		ldr	r0, [sp, r5, lsr #14]		@ load Rn value
+		tst	r4, #1 << 23			@ U bit
+		subne	r7, r0, r2
+		addeq	r7, r0, r2
+		b	Ldata_saver7
+
+Ldata_lateldrpreconst:
+		tst	r4, #1 << 21			@ check writeback bit
+		beq	Ldata_simple
+Ldata_lateldrpostconst:
+		movs	r2, r4, lsl #20			@ Get offset
+		beq	Ldata_simple
+		and	r5, r4, #15 << 16		@ Get Rn
+		ldr	r0, [sp, r5, lsr #14]
+		tst	r4, #1 << 23			@ U bit
+		subne	r7, r0, r2, lsr #20
+		addeq	r7, r0, r2, lsr #20
+		b	Ldata_saver7
+
+Ldata_lateldrprereg:
+		tst	r4, #1 << 21			@ check writeback bit
+		beq	Ldata_simple
+Ldata_lateldrpostreg:
+		and	r5, r4, #15
+		ldr	r2, [sp, r5, lsl #2]		@ Get Rm
+		mov	r3, r4, lsr #7
+		ands	r3, r3, #31
+		and	r6, r4, #0x70
+		orreq	r6, r6, #8
+		add	pc, pc, r6
+		mov	r0, r0
+
+		mov	r2, r2, lsl r3			@ 0: LSL #!0
+		b	1f
+		b	1f				@ 1: LSL #0
+		mov	r0, r0
+		b	1f				@ 2: MUL?
+		mov	r0, r0
+		b	1f				@ 3: MUL?
+		mov	r0, r0
+		mov	r2, r2, lsr r3			@ 4: LSR #!0
+		b	1f
+		mov	r2, r2, lsr #32			@ 5: LSR #32
+		b	1f
+		b	1f				@ 6: MUL?
+		mov	r0, r0
+		b	1f				@ 7: MUL?
+		mov	r0, r0
+		mov	r2, r2, asr r3			@ 8: ASR #!0
+		b	1f
+		mov	r2, r2, asr #32			@ 9: ASR #32
+		b	1f
+		b	1f				@ A: MUL?
+		mov	r0, r0
+		b	1f				@ B: MUL?
+		mov	r0, r0
+		mov	r2, r2, ror r3			@ C: ROR #!0
+		b	1f
+		mov	r2, r2, rrx			@ D: RRX
+		b	1f
+		mov	r0, r0				@ E: MUL?
+		mov	r0, r0
+		mov	r0, r0				@ F: MUL?
+
+
+1:		and	r5, r4, #15 << 16		@ Get Rn
+		ldr	r0, [sp, r5, lsr #14]
+		tst	r4, #1 << 23			@ U bit
+		subne	r7, r0, r2
+		addeq	r7, r0, r2
+		b	Ldata_saver7
+
+/*
+ * Function: arm720_check_bugs (void)
+ *	   : arm720_proc_init (void)
+ *	   : arm720_proc_fin (void)
+ *
+ * Notes   : This processor does not require these
+ */
+ENTRY(cpu_arm720_check_bugs)
+		mrs	ip, cpsr
+		bic	ip, ip, #F_BIT
+		msr	cpsr, ip
+		mov	pc, lr
+
+ENTRY(cpu_arm720_proc_init)
+		mov	pc, lr
+
+ENTRY(cpu_arm720_proc_fin)
+		stmfd	sp!, {lr}
+		mov	ip, #F_BIT | I_BIT | SVC_MODE
+		msr	cpsr_c, ip
+		mrc	p15, 0, r0, c1, c0, 0
+		bic	r0, r0, #0x1000			@ ...i............
+		bic	r0, r0, #0x000e			@ ............wca.
+		mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+		mcr	p15, 0, r1, c7, c7, 0		@ invalidate cache
+		ldmfd	sp!, {pc}
+
+/*
+ * Function: arm720_proc_do_idle(void)
+ * Params  : r0 = unused
+ * Purpose : put the processer in proper idle mode
+ */
+ENTRY(cpu_arm720_do_idle)
+		mov	pc, lr
+
+/*
+ * Function: arm720_set_pgd(unsigned long pgd_phys)
+ * Params  : pgd_phys	Physical address of page table
+ * Purpose : Perform a task switch, saving the old process' state and restoring
+ *	     the new.
+ */
+ENTRY(cpu_arm720_set_pgd)
+		mov	r1, #0
+		mcr	p15, 0, r1, c7, c7, 0		@ invalidate cache
+		mcr	p15, 0, r0, c2, c0, 0		@ update page table ptr
+		mcr	p15, 0, r1, c8, c7, 0		@ flush TLB (v4)
+		mov	pc, lr
+
+/*
+ * Function: arm720_set_pmd ()
+ *
+ * Params  : r0 = Address to set
+ *	   : r1 = value to set
+ *
+ * Purpose : Set a PMD and flush it out of any WB cache
+ */
+ENTRY(cpu_arm720_set_pmd)
+		tst	r1, #3
+		orrne	r1, r1, #16			@ Updatable bit is
+		str	r1, [r0]			@ always set on ARM720
+		mov	pc, lr
+
+/*
+ * Function: arm720_set_pte(pte_t *ptep, pte_t pte)
+ * Params  : r0 = Address to set
+ *	   : r1 = value to set
+ * Purpose : Set a PTE and flush it out of any WB cache
+ */
+		.align	5
+ENTRY(cpu_arm720_set_pte)
+		str	r1, [r0], #-1024		@ linux version
+
+		eor	r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
+		bic	r2, r1, #0xff0
+		bic	r2, r2, #3
+		orr	r2, r2, #HPTE_TYPE_SMALL
+
+		tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+		orrne	r2, r2, #HPTE_AP_READ
+
+		tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
+		orreq	r2, r2, #HPTE_AP_WRITE
+
+		tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young
+		movne	r2, #0
+
+		str	r2, [r0]			@ hardware version
+		mov	pc, lr
+
+/*
+ * Function: arm720_reset
+ * Params  : r0 = address to jump to
+ * Notes   : This sets up everything for a reset
+ */
+ENTRY(cpu_arm720_reset)
+		mov	ip, #0
+		mcr	p15, 0, ip, c7, c7, 0		@ invalidate cache
+		mcr	p15, 0, ip, c8, c7, 0		@ flush TLB (v4)
+		mrc	p15, 0, ip, c1, c0, 0		@ get ctrl register
+		bic	ip, ip, #0x000f			@ ............wcam
+		bic	ip, ip, #0x2100			@ ..v....s........
+		mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
+		mov	pc, r0
+
+	
+cpu_armvlsi_name:
+		.asciz	"ARM"
+cpu_arm720_name:
+		.asciz	"ARM720T"
+		.align
+
+		.section ".text.init", #alloc, #execinstr
+
+__arm720_setup:	mov	r0, #0
+		mcr	p15, 0, r0, c7, c7, 0		@ invalidate caches
+		mcr	p15, 0, r0, c8, c7, 0		@ flush TLB (v4)
+		mcr	p15, 0, r4, c2, c0		@ load page table pointer
+		mov	r0, #0x1f			@ Domains 0, 1 = client
+		mcr	p15, 0, r0, c3, c0		@ load domain access register
+
+		mrc	p15, 0, r0, c1, c0		@ get control register
+		bic	r0, r0, #0x0e00			@ ..V. ..RS BLDP WCAM
+		orr	r0, r0, #0x2100			@ .... .... .111 .... (old)
+		orr	r0, r0, #0x003d			@ ..1. ..01 ..11 1101 (new)
+		mov	pc, lr				@ __ret (head-armv.S)
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+		.type	arm720_processor_functions, #object
+ENTRY(arm720_processor_functions)
+		.word	cpu_arm720_data_abort
+		.word	cpu_arm720_check_bugs
+		.word	cpu_arm720_proc_init
+		.word	cpu_arm720_proc_fin
+		.word	cpu_arm720_reset
+		.word	cpu_arm720_do_idle
+
+		/* cache */
+		.word	cpu_arm720_cache_clean_invalidate_all
+		.word	cpu_arm720_cache_clean_invalidate_range
+		.word	cpu_arm720_flush_ram_page
+
+		/* dcache */
+		.word	cpu_arm720_dcache_invalidate_range
+		.word	cpu_arm720_dcache_clean_range
+		.word	cpu_arm720_dcache_clean_page
+		.word	cpu_arm720_dcache_clean_entry
+
+		/* icache */
+		.word	cpu_arm720_icache_invalidate_range
+		.word	cpu_arm720_icache_invalidate_page
+
+		/* tlb */
+		.word	cpu_arm720_tlb_invalidate_all
+		.word	cpu_arm720_tlb_invalidate_range
+		.word	cpu_arm720_tlb_invalidate_page
+
+		/* pgtable */
+		.word	cpu_arm720_set_pgd
+		.word	cpu_arm720_set_pmd
+		.word	cpu_arm720_set_pte
+		.size	arm720_processor_functions, . - arm720_processor_functions
+
+		.type	cpu_arm720_info, #object
+cpu_arm720_info:
+		.long	cpu_armvlsi_name
+		.long	cpu_arm720_name
+		.size	cpu_arm720_info, . - cpu_arm720_info
+	
+		.type	cpu_arch_name, #object
+cpu_arch_name:	.asciz	"armv4"
+		.size	cpu_arch_name, . - cpu_arch_name
+
+		.type	cpu_elf_name, #object
+cpu_elf_name:	.asciz	"v4"
+		.size	cpu_elf_name, . - cpu_elf_name
+		.align
+
+/*
+ * See /include/asm-arm for a definition of this structure.
+ */
+	
+		.section ".proc.info", #alloc, #execinstr
+
+		.type	__arm720_proc_info, #object
+__arm720_proc_info:
+		.long	0x41807200				@ cpu_val
+		.long	0xffffff00				@ cpu_mask
+		.long	0x00000c1e				@ section_mmu_flags
+		b	__arm720_setup				@ cpu_flush
+		.long	cpu_arch_name				@ arch_name
+		.long	cpu_elf_name				@ elf_name
+		.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT	@ elf_hwcap
+		.long	cpu_arm720_info				@ info
+		.long	arm720_processor_functions
+		.size	__arm720_proc_info, . - __arm720_proc_info
diff -urN linux-2.4.29/arch/armnommu/mm/proc-arm740.S linux-2.4.29-uc1/arch/armnommu/mm/proc-arm740.S
--- linux-2.4.29/arch/armnommu/mm/proc-arm740.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/proc-arm740.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,482 @@
+/*
+ *  linux/arch/arm/mm/proc-arm740.S: MMU functions for ARM740
+ *
+ *  Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
+ *                     Rob Scott (rscott@mtrob.fdns.net)
+ *  Copyright (C) 2000 ARM Limited, Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the ARM720T.  The ARM720T has a writethrough IDC
+ * cache, so we don't need to clean it.
+ *
+ *  Changelog:
+ *   05-09-2000 SJH	Created by moving 720 specific functions
+ *			out of 'proc-arm6,7.S' per RMK discussion
+ *   07-25-2000 SJH	Added idle function.
+ *   08-25-2000	DBS	Updated for integration of ARM Ltd version.
+ *   12-03-2001 FG      Forked 740 function from 720
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+#include <asm/hardware.h>
+
+/*
+ * Function: arm740_cache_clean_invalidate_all (void)
+ *	   : arm740_cache_clean_invalidate_page (unsigned long address, int size,
+ *                                    int flags)
+ *
+ * Params  : address	Area start address
+ *	   : size	size of area
+ *	   : flags	b0 = I cache as well
+ *
+ * Purpose : Flush all cache lines
+ */
+ENTRY(cpu_arm740_cache_clean_invalidate_all)
+ENTRY(cpu_arm740_cache_clean_invalidate_range)
+ENTRY(cpu_arm740_icache_invalidate_range)
+ENTRY(cpu_arm740_icache_invalidate_page)
+ENTRY(cpu_arm740_dcache_invalidate_range)
+		mov	r0, #0
+		mcr	p15, 0, r0, c7, c7, 0		@ flush cache
+		mov	pc, lr
+
+/*
+ * These just expect cache lines to be cleaned.  Since we have a writethrough
+ * cache, we never have any dirty cachelines to worry about.
+ */
+ENTRY(cpu_arm740_dcache_clean_range)
+ENTRY(cpu_arm740_dcache_clean_page)
+ENTRY(cpu_arm740_dcache_clean_entry)
+ENTRY(cpu_arm740_flush_ram_page)
+		mov	pc, lr
+
+/*
+ * Function: arm740_tlb_invalidate_all (void)
+ *
+ * Purpose : flush all TLB entries in all caches
+ */
+ENTRY(cpu_arm740_tlb_invalidate_all)
+		mov	r0, #0
+		mcr	p15, 0, r0, c8, c7, 0		@ flush TLB (v4)
+		mov	pc, lr
+
+/*
+ * Function: arm740_tlb_invalidate_page (unsigned long address, int end, int flags)
+ *
+ * Params  : address	Area start address
+ *	   : end	Area end address
+ *	   : flags	b0 = I cache as well
+ *
+ * Purpose : flush a TLB entry
+ */
+ENTRY(cpu_arm740_tlb_invalidate_range)
+1:		mcr	p15, 0, r0, c8, c7, 1		@ flush TLB (v4)
+		add	r0, r0, #4096
+		cmp	r0, r1
+		blt	1b
+		mov	pc, lr
+
+/*
+ * Function: arm740_tlb_invalidate_page (unsigned long address, int flags)
+ *
+ * Params  : address	Address
+ *	   : flags	b0 = I-TLB as well
+ *
+ * Purpose : flush a TLB entry
+ */
+ENTRY(cpu_arm740_tlb_invalidate_page)
+		mcr	p15, 0, r0, c8, c7, 1		@ flush TLB (v4)
+		mov	pc, lr
+
+/*
+ * Function: arm740_data_abort ()
+ *
+ * Params  : r0 = address of aborted instruction
+ *
+ * Purpose : obtain information about current aborted instruction
+ *
+ * Returns : r0 = address of abort
+ *	   : r1 != 0 if writing
+ *	   : r3 = FSR
+ *	   : sp = pointer to registers
+ */
+
+Ldata_ldmstm:	tst	r4, #1 << 21			@ check writeback bit
+		beq	Ldata_simple
+		mov	r7, #0x11
+		orr	r7, r7, r7, lsl #8
+		and	r0, r4, r7
+		and	r2, r4, r7, lsl #1
+		add	r0, r0, r2, lsr #1
+		and	r2, r4, r7, lsl #2
+		add	r0, r0, r2, lsr #2
+		and	r2, r4, r7, lsl #3
+		add	r0, r0, r2, lsr #3
+		add	r0, r0, r0, lsr #8
+		add	r0, r0, r0, lsr #4
+		and	r7, r0, #15			@ r7 = no. of registers to transfer.
+		and	r5, r4, #15 << 16		@ Get Rn
+		ldr	r0, [sp, r5, lsr #14]		@ Get register
+		tst	r4, #1 << 23			@ U bit
+		subne	r7, r0, r7, lsl #2
+		addeq	r7, r0, r7, lsl #2		@ Do correction (signed)
+Ldata_saver7:	str	r7, [sp, r5, lsr #14]		@ Put register
+Ldata_simple:	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+		mrc	p15, 0, r3, c5, c0, 0		@ get FSR
+		and	r3, r3, #255
+		mov	pc, lr
+
+ENTRY(cpu_arm740_data_abort)
+		ldr	r4, [r0]			@ read instruction causing problem
+		tst	r4, r4, lsr #21			@ C = bit 20
+		sbc	r1, r1, r1			@ r1 = C - 1
+		and	r2, r4, #15 << 24
+		add	pc, pc, r2, lsr #22		@ Now branch to the relevent processing routine
+		movs	pc, lr
+
+		b	Ldata_lateldrhpost		@ ldrh	rd, [rn], #m/rm
+		b	Ldata_lateldrhpre		@ ldrh	rd, [rn, #m/rm]
+		b	Ldata_unknown
+		b	Ldata_unknown
+		b	Ldata_lateldrpostconst		@ ldr	rd, [rn], #m
+		b	Ldata_lateldrpreconst		@ ldr	rd, [rn, #m] 
+		b	Ldata_lateldrpostreg		@ ldr	rd, [rn], rm
+		b	Ldata_lateldrprereg		@ ldr	rd, [rn, rm]
+		b	Ldata_ldmstm			@ ldm*a	rn, <rlist>
+		b	Ldata_ldmstm			@ ldm*b	rn, <rlist>
+		b	Ldata_unknown
+		b	Ldata_unknown
+		b	Ldata_simple			@ ldc	rd, [rn], #m	@ Same as ldr	rd, [rn], #m
+		b	Ldata_simple			@ ldc	rd, [rn, #m]
+		b	Ldata_unknown
+
+Ldata_unknown:	@ Part of jumptable
+		mov	r0, r2
+		mov	r1, r4
+		mov	r2, r3
+		bl	baddataabort
+		b	ret_from_exception
+
+Ldata_lateldrhpre:
+		tst	r4, #1 << 21			@ check writeback bit
+		beq	Ldata_simple
+Ldata_lateldrhpost:
+		and	r5, r4, #0x00f			@ get Rm / low nibble of immediate value
+		tst	r4, #1 << 22			@ if (immediate offset)
+		andne	r2, r4, #0xf00			@ { immediate high nibble
+		orrne	r2, r5, r2, lsr #4		@   combine nibbles } else
+		ldreq	r2, [sp, r5, lsl #2]		@ { load Rm value }
+		and	r5, r4, #15 << 16		@ get Rn
+		ldr	r0, [sp, r5, lsr #14]		@ load Rn value
+		tst	r4, #1 << 23			@ U bit
+		subne	r7, r0, r2
+		addeq	r7, r0, r2
+		b	Ldata_saver7
+
+Ldata_lateldrpreconst:
+		tst	r4, #1 << 21			@ check writeback bit
+		beq	Ldata_simple
+Ldata_lateldrpostconst:
+		movs	r2, r4, lsl #20			@ Get offset
+		beq	Ldata_simple
+		and	r5, r4, #15 << 16		@ Get Rn
+		ldr	r0, [sp, r5, lsr #14]
+		tst	r4, #1 << 23			@ U bit
+		subne	r7, r0, r2, lsr #20
+		addeq	r7, r0, r2, lsr #20
+		b	Ldata_saver7
+
+Ldata_lateldrprereg:
+		tst	r4, #1 << 21			@ check writeback bit
+		beq	Ldata_simple
+Ldata_lateldrpostreg:
+		and	r5, r4, #15
+		ldr	r2, [sp, r5, lsl #2]		@ Get Rm
+		mov	r3, r4, lsr #7
+		ands	r3, r3, #31
+		and	r6, r4, #0x70
+		orreq	r6, r6, #8
+		add	pc, pc, r6
+		mov	r0, r0
+
+		mov	r2, r2, lsl r3			@ 0: LSL #!0
+		b	1f
+		b	1f				@ 1: LSL #0
+		mov	r0, r0
+		b	1f				@ 2: MUL?
+		mov	r0, r0
+		b	1f				@ 3: MUL?
+		mov	r0, r0
+		mov	r2, r2, lsr r3			@ 4: LSR #!0
+		b	1f
+		mov	r2, r2, lsr #32			@ 5: LSR #32
+		b	1f
+		b	1f				@ 6: MUL?
+		mov	r0, r0
+		b	1f				@ 7: MUL?
+		mov	r0, r0
+		mov	r2, r2, asr r3			@ 8: ASR #!0
+		b	1f
+		mov	r2, r2, asr #32			@ 9: ASR #32
+		b	1f
+		b	1f				@ A: MUL?
+		mov	r0, r0
+		b	1f				@ B: MUL?
+		mov	r0, r0
+		mov	r2, r2, ror r3			@ C: ROR #!0
+		b	1f
+		mov	r2, r2, rrx			@ D: RRX
+		b	1f
+		mov	r0, r0				@ E: MUL?
+		mov	r0, r0
+		mov	r0, r0				@ F: MUL?
+
+
+1:		and	r5, r4, #15 << 16		@ Get Rn
+		ldr	r0, [sp, r5, lsr #14]
+		tst	r4, #1 << 23			@ U bit
+		subne	r7, r0, r2
+		addeq	r7, r0, r2
+		b	Ldata_saver7
+
+/*
+ * Function: arm740_check_bugs (void)
+ *	   : arm740_proc_init (void)
+ *	   : arm740_proc_fin (void)
+ *
+ * Notes   : This processor does not require these
+ */
+ENTRY(cpu_arm740_check_bugs)
+		mrs	ip, cpsr
+		bic	ip, ip, #F_BIT
+		msr	cpsr, ip
+		mov	pc, lr
+
+ENTRY(cpu_arm740_proc_init)
+		mov	pc, lr
+
+ENTRY(cpu_arm740_proc_fin)
+		stmfd	sp!, {lr}
+		mov	ip, #F_BIT | I_BIT | SVC_MODE
+		msr	cpsr_c, ip
+		mrc	p15, 0, r0, c1, c0, 0
+		bic	r0, r0, #0x1000			@ ...i............
+		bic	r0, r0, #0x000e			@ ............wca.
+		mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+		mcr	p15, 0, r1, c7, c7, 0		@ invalidate cache
+		ldmfd	sp!, {pc}
+
+/*
+ * Function: arm740_proc_do_idle(void)
+ * Params  : r0 = unused
+ * Purpose : put the processer in proper idle mode
+ */
+ENTRY(cpu_arm740_do_idle)
+		mov	pc, lr
+
+/*
+ * Function: arm740_set_pgd(unsigned long pgd_phys)
+ * Params  : pgd_phys	Physical address of page table
+ * Purpose : Perform a task switch, saving the old process' state and restoring
+ *	     the new.
+ */
+ENTRY(cpu_arm740_set_pgd)
+		mov	r1, #0
+		mcr	p15, 0, r1, c7, c7, 0		@ invalidate cache
+		mcr	p15, 0, r0, c2, c0, 0		@ update page table ptr
+		mcr	p15, 0, r1, c8, c7, 0		@ flush TLB (v4)
+		mov	pc, lr
+
+/*
+ * Function: arm740_set_pmd ()
+ *
+ * Params  : r0 = Address to set
+ *	   : r1 = value to set
+ *
+ * Purpose : Set a PMD and flush it out of any WB cache
+ */
+ENTRY(cpu_arm740_set_pmd)
+		tst	r1, #3
+		orrne	r1, r1, #16			@ Updatable bit is
+		str	r1, [r0]			@ always set on ARM720
+		mov	pc, lr
+
+/*
+ * Function: arm740_set_pte(pte_t *ptep, pte_t pte)
+ * Params  : r0 = Address to set
+ *	   : r1 = value to set
+ * Purpose : Set a PTE and flush it out of any WB cache
+ */
+		.align	5
+ENTRY(cpu_arm740_set_pte)
+		str	r1, [r0], #-1024		@ linux version
+
+		eor	r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
+		bic	r2, r1, #0xff0
+		bic	r2, r2, #3
+		orr	r2, r2, #HPTE_TYPE_SMALL
+
+		tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+		orrne	r2, r2, #HPTE_AP_READ
+
+		tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
+		orreq	r2, r2, #HPTE_AP_WRITE
+
+		tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young
+		movne	r2, #0
+
+		str	r2, [r0]			@ hardware version
+		mov	pc, lr
+
+/*
+ * Function: arm740_reset
+ * Params  : r0 = address to jump to
+ * Notes   : This sets up everything for a reset
+ */
+ENTRY(cpu_arm740_reset)
+		mov	ip, #0
+		mcr	p15, 0, ip, c7, c7, 0		@ invalidate cache
+		mcr	p15, 0, ip, c8, c7, 0		@ flush TLB (v4)
+		mrc	p15, 0, ip, c1, c0, 0		@ get ctrl register
+		bic	ip, ip, #0x000e				@ ............wcam
+		mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
+		mov	pc, r0
+
+	
+cpu_armvlsi_name:
+		.asciz	"ARM"
+cpu_arm740_name:
+		.asciz	"ARM740T"
+		.align
+
+		.section ".text.init", #alloc, #execinstr
+
+__arm740_setup:
+
+@setup memory regions
+@ 
+
+		mov	r0, #0
+		mcr	p15, 0, r0, c7, c7, 0		@ invalidate caches
+
+		mov r0, #0x0					@disable region 3-7
+		mcr p15, 0, r0, c6, c3
+		mcr p15, 0, r0, c6, c4
+		mcr p15, 0, r0, c6, c5
+		mcr p15, 0, r0, c6, c6
+		mcr p15, 0, r0, c6, c7
+	
+
+		mov r0, #0x0000003F			@ (base = 0, size = 4GB, non cacheable, no write buffer)
+		mcr p15, 0, r0, c6,	c0		@ enable region 0, default
+		mov r0, #0x00000037			@ (base = 0, size = 256MB, cacheable, write buffered)
+		mcr p15, 0, r0, c6,	c1		@enable region 1, RAM
+		mov r0, #0x20000000
+		add r0, r0, #0x37			@ (base = 512MB, size = 256MB, cacheable, write buffered)
+		mcr p15, 0, r0, c6,	c2		@enable region 2, ROM/Flash
+
+		mov r0, #0x06				
+		mcr p15, 0, r0, c2, c0		@ Region 1&2 cacheable
+		mov r0, #0x02			
+		mcr p15, 0, r0, c3, c0		@ Region 1 write buferred
+
+		mov r0, #0xff00
+		add r0, r0, #0x00ff
+		mcr p15, 0, r0, c5, c0		@ all read/write access
+
+		mrc	p15, 0, r0, c1, c0		@ get control register
+		orr r0, r0, #0x00030000		@ Split cache mode
+		orr	r0, r0, #0x0000000d		@ MPU, Cache, Write Buffer on
+	
+		mov	pc, lr				@ __ret (head-armv.S)
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+		.type	arm720_processor_functions, #object
+ENTRY(arm740_processor_functions)
+		.word	cpu_arm740_data_abort
+		.word	cpu_arm740_check_bugs
+		.word	cpu_arm740_proc_init
+		.word	cpu_arm740_proc_fin
+		.word	cpu_arm740_reset
+		.word	cpu_arm740_do_idle
+
+		/* cache */
+		.word	cpu_arm740_cache_clean_invalidate_all
+		.word	cpu_arm740_cache_clean_invalidate_range
+		.word	cpu_arm740_flush_ram_page
+
+		/* dcache */
+		.word	cpu_arm740_dcache_invalidate_range
+		.word	cpu_arm740_dcache_clean_range
+		.word	cpu_arm740_dcache_clean_page
+		.word	cpu_arm740_dcache_clean_entry
+
+		/* icache */
+		.word	cpu_arm740_icache_invalidate_range
+		.word	cpu_arm740_icache_invalidate_page
+
+		/* tlb */
+		.word	cpu_arm740_tlb_invalidate_all
+		.word	cpu_arm740_tlb_invalidate_range
+		.word	cpu_arm740_tlb_invalidate_page
+
+		/* pgtable */
+		.word	cpu_arm740_set_pgd
+		.word	cpu_arm740_set_pmd
+		.word	cpu_arm740_set_pte
+		.size	arm740_processor_functions, . - arm740_processor_functions
+
+		.type	cpu_arm740_info, #object
+cpu_arm740_info:
+		.long	cpu_armvlsi_name
+		.long	cpu_arm740_name
+		.size	cpu_arm740_info, . - cpu_arm70_info
+	
+		.type	cpu_arch_name, #object
+cpu_arch_name:	.asciz	"armv4"
+		.size	cpu_arch_name, . - cpu_arch_name
+
+		.type	cpu_elf_name, #object
+cpu_elf_name:	.asciz	"v4"
+		.size	cpu_elf_name, . - cpu_elf_name
+		.align
+
+/*
+ * See /include/asm-arm for a definition of this structure.
+ */
+	
+		.section ".proc.info", #alloc, #execinstr
+
+		.type	__arm740_proc_info, #object
+__arm740_proc_info:
+		.long	0x41807400				@ cpu_val
+		.long	0xfffffF00				@ cpu_mask
+		.long	0x00000c1e				@ section_mmu_flags
+		b	__arm740_setup				@ cpu_flush
+		.long	cpu_arch_name				@ arch_name
+		.long	cpu_elf_name				@ elf_name
+		.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT	@ elf_hwcap
+		.long	cpu_arm740_info				@ info
+		.long	arm740_processor_functions
+		.size	__arm740_proc_info, . - __arm740_proc_info
diff -urN linux-2.4.29/arch/armnommu/mm/proc-arm920.S linux-2.4.29-uc1/arch/armnommu/mm/proc-arm920.S
--- linux-2.4.29/arch/armnommu/mm/proc-arm920.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/proc-arm920.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,602 @@
+/*
+ *  linux/arch/arm/mm/arm920.S: MMU functions for ARM920
+ *
+ *  Copyright (C) 1999,2000 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the arm920.
+ */
+#include <linux/linkage.h>
+#include <linux/config.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+#include <asm/hardware.h>
+
+/*
+ * This is the maximum size of an area which will be invalidated
+ * using the single invalidate entry instructions.  Anything larger
+ * than this, and we go for the whole cache.
+ *
+ * This value should be chosen such that we choose the cheapest
+ * alternative.
+ */
+#define MAX_AREA_SIZE	16384
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define DCACHELINESIZE	32
+#define ICACHELINESIZE	32
+
+/*
+ * and the page size
+ */
+#define PAGESIZE	4096
+
+	.text
+
+/*
+ * cpu_arm920_data_abort()
+ *
+ * obtain information about current aborted instruction
+ *
+ * r0 = address of aborted instruction
+ *
+ * Returns:
+ *  r0 = address of abort
+ *  r1 != 0 if writing
+ *  r3 = FSR
+ */
+	.align	5
+ENTRY(cpu_arm920_data_abort)
+	ldr	r1, [r0]			@ read aborted instruction
+	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+	tst	r1, r1, lsr #21			@ C = bit 20
+	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
+	sbc	r1, r1, r1			@ r1 = C - 1
+	and	r3, r3, #255
+	mov	pc, lr
+
+/*
+ * cpu_arm920_check_bugs()
+ */
+ENTRY(cpu_arm920_check_bugs)
+	mrs	ip, cpsr
+	bic	ip, ip, #F_BIT
+	msr	cpsr, ip
+	mov	pc, lr
+
+/*
+ * cpu_arm920_proc_init()
+ */
+ENTRY(cpu_arm920_proc_init)
+	mov	pc, lr
+
+/*
+ * cpu_arm920_proc_fin()
+ */
+ENTRY(cpu_arm920_proc_fin)
+	stmfd	sp!, {lr}
+	mov	ip, #F_BIT | I_BIT | SVC_MODE
+	msr	cpsr_c, ip
+	bl	cpu_arm920_cache_clean_invalidate_all
+	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
+	bic	r0, r0, #0x1000			@ ...i............
+	bic	r0, r0, #0x000e			@ ............wca.
+	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+	ldmfd	sp!, {pc}
+
+/*
+ * cpu_arm920_reset(loc)
+ *
+ * Perform a soft reset of the system.  Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+	.align	5
+ENTRY(cpu_arm920_reset)
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
+	bic	ip, ip, #0x000f			@ ............wcam
+	bic	ip, ip, #0x1100			@ ...i...s........
+	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
+	mov	pc, r0
+
+/*
+ * cpu_arm920_do_idle()
+ */
+	.align	5
+ENTRY(cpu_arm920_do_idle)
+#if defined(CONFIG_CPU_ARM920_CPU_IDLE)
+	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
+#endif
+	mov	pc, lr
+
+/* ================================= CACHE ================================ */
+
+
+/*
+ * cpu_arm920_cache_clean_invalidate_all()
+ *
+ * clean and invalidate all cache lines
+ *
+ * Note:
+ *  1. we should preserve r0 at all times
+ */
+	.align	5
+ENTRY(cpu_arm920_cache_clean_invalidate_all)
+	mov	r2, #1
+cpu_arm920_cache_clean_invalidate_all_r2:
+	mov	ip, #0
+#ifdef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+/*
+ * 'Clean & Invalidate whole DCache'
+ * Re-written to use Index Ops.
+ * Uses registers r1, r3 and ip
+ */
+	mov	r1, #7 << 5			@ 8 segments
+1:	orr	r3, r1, #63 << 26		@ 64 entries
+2:	mcr	p15, 0, r3, c7, c14, 2		@ clean & invalidate D index
+	subs	r3, r3, #1 << 26
+	bcs	2b				@ entries 63 to 0
+	subs	r1, r1, #1 << 5
+	bcs	1b				@ segments 7 to 0
+#endif
+	teq	r2, #0
+	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm920_cache_clean_invalidate_range(start, end, flags)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * start: Area start address
+ * end:   Area end address
+ * flags: nonzero for I cache as well
+ */
+	.align	5
+ENTRY(cpu_arm920_cache_clean_invalidate_range)
+	bic	r0, r0, #DCACHELINESIZE - 1	@ && added by PGM
+	sub	r3, r1, r0
+	cmp	r3, #MAX_AREA_SIZE
+	bgt	cpu_arm920_cache_clean_invalidate_all_r2
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blt	1b
+	teq	r2, #0
+	movne	r0, #0
+	mcrne	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	mov	pc, lr
+
+/*
+ * cpu_arm920_flush_ram_page(page)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * page: page to clean and invalidate
+ */
+	.align	5
+ENTRY(cpu_arm920_flush_ram_page)
+	mov	r1, #PAGESIZE
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bne	1b
+	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* ================================ D-CACHE =============================== */
+
+/*
+ * cpu_arm920_dcache_invalidate_range(start, end)
+ *
+ * throw away all D-cached data in specified region without an obligation
+ * to write them back.  Note however that we must clean the D-cached entries
+ * around the boundaries if the start and/or end address are not cache
+ * aligned.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm920_dcache_invalidate_range)
+	tst	r0, #DCACHELINESIZE - 1
+	bic	r0, r0, #DCACHELINESIZE - 1
+	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
+	tst	r1, #DCACHELINESIZE - 1
+	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blt	1b
+	mov	pc, lr
+
+/*
+ * cpu_arm920_dcache_clean_range(start, end)
+ *
+ * For the specified virtual address range, ensure that all caches contain
+ * clean data, such that peripheral accesses to the physical RAM fetch
+ * correct data.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm920_dcache_clean_range)
+	bic	r0, r0, #DCACHELINESIZE - 1
+	sub	r1, r1, r0
+	cmp	r1, #MAX_AREA_SIZE
+	mov	r2, #0
+	bgt	cpu_arm920_cache_clean_invalidate_all_r2
+
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bpl	1b
+	mcr	p15, 0, r2, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm920_dcache_clean_page(page)
+ *
+ * Cleans a single page of dcache so that if we have any future aliased
+ * mappings, they will be consistent at the time that they are created.
+ *
+ * page: virtual address of page to clean from dcache
+ *
+ * Note:
+ *  1. we don't need to flush the write buffer in this case.
+ *  2. we don't invalidate the entries since when we write the page
+ *     out to disk, the entries may get reloaded into the cache.
+ */
+	.align	5
+ENTRY(cpu_arm920_dcache_clean_page)
+#ifndef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH
+	mov	r1, #PAGESIZE
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bne	1b
+#endif
+	mov	pc, lr
+
+/*
+ * cpu_arm920_dcache_clean_entry(addr)
+ *
+ * Clean the specified entry of any caches such that the MMU
+ * translation fetches will obtain correct data.
+ *
+ * addr: cache-unaligned virtual address
+ */
+	.align	5
+ENTRY(cpu_arm920_dcache_clean_entry)
+#ifndef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* ================================ I-CACHE =============================== */
+
+/*
+ * cpu_arm920_icache_invalidate_range(start, end)
+ *
+ * invalidate a range of virtual addresses from the Icache
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm920_icache_invalidate_range)
+1:	mcr	p15, 0, r0, c7, c10, 1		@ Clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+ENTRY(cpu_arm920_icache_invalidate_page)
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	mov	pc, lr
+
+
+/* ================================== TLB ================================= */
+
+/*
+ * cpu_arm920_tlb_invalidate_all()
+ *
+ * Invalidate all TLB entries
+ */
+	.align	5
+ENTRY(cpu_arm920_tlb_invalidate_all)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, lr
+
+/*
+ * cpu_arm920_tlb_invalidate_range(start, end)
+ *
+ * invalidate TLB entries covering the specified range
+ *
+ * start: range start address
+ * end:   range end address
+ */
+	.align	5
+ENTRY(cpu_arm920_tlb_invalidate_range)
+	mov	r3, #0
+	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
+1:	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
+	mcr	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
+	add	r0, r0, #PAGESIZE
+	cmp	r0, r1
+	blt	1b
+	mov	pc, lr
+
+/*
+ * cpu_arm920_tlb_invalidate_page(page, flags)
+ *
+ * invalidate the TLB entries for the specified page.
+ *
+ * page:  page to invalidate
+ * flags: non-zero if we include the I TLB
+ */
+	.align	5
+ENTRY(cpu_arm920_tlb_invalidate_page)
+	mov	r3, #0
+	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
+	teq	r1, #0
+	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
+	mcrne	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
+	mov	pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_arm920_set_pgd(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+	.align	5
+ENTRY(cpu_arm920_set_pgd)
+	mov	ip, #0
+#ifdef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH
+	/* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+@ && 'Clean & Invalidate whole DCache'
+@ && Re-written to use Index Ops.
+@ && Uses registers r1, r3 and ip
+
+	mov	r1, #7 << 5			@ 8 segments
+1:	orr	r3, r1, #63 << 26		@ 64 entries
+2:	mcr	p15, 0, r3, c7, c14, 2		@ clean & invalidate D index
+	subs	r3, r3, #1 << 26
+	bcs	2b				@ entries 63 to 0
+	subs	r1, r1, #1 << 5
+	bcs	1b				@ segments 7 to 0
+#endif
+	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, lr
+
+/*
+ * cpu_arm920_set_pmd(pmdp, pmd)
+ *
+ * Set a level 1 translation table entry, and clean it out of
+ * any caches such that the MMUs can load it correctly.
+ *
+ * pmdp: pointer to PMD entry
+ * pmd:  PMD value to store
+ */
+	.align	5
+ENTRY(cpu_arm920_set_pmd)
+#ifdef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH
+	eor	r2, r1, #0x0a			@ C & Section
+	tst	r2, #0x0b
+	biceq	r1, r1, #4			@ clear bufferable bit
+#endif
+	str	r1, [r0]
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm920_set_pte(ptep, pte)
+ *
+ * Set a PTE and flush it out
+ */
+	.align	5
+ENTRY(cpu_arm920_set_pte)
+	str	r1, [r0], #-1024		@ linux version
+
+	eor	r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
+	bic	r2, r1, #0xff0
+	bic	r2, r2, #3
+	orr	r2, r2, #HPTE_TYPE_SMALL
+
+	tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+	orrne	r2, r2, #HPTE_AP_READ
+
+	tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
+	orreq	r2, r2, #HPTE_AP_WRITE
+
+	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
+	movne	r2, #0
+
+#ifdef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH
+	eor	r3, r1, #0x0a			@ C & small page?
+	tst	r3, #0x0b
+	biceq	r2, r2, #4
+#endif
+	str	r2, [r0]			@ hardware version
+	mov	r0, r0
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+
+cpu_manu_name:
+	.asciz	"ARM/VLSI"
+ENTRY(cpu_arm920_name)
+	.ascii	"Arm920"
+#if defined(CONFIG_CPU_ARM920_CPU_IDLE)
+	.ascii	"s"
+#endif
+#if defined(CONFIG_CPU_ARM920_I_CACHE_ON)
+	.ascii	"i"
+#endif
+#if defined(CONFIG_CPU_ARM920_D_CACHE_ON)
+	.ascii	"d"
+#if defined(CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH)
+	.ascii	"(wt)"
+#else
+	.ascii	"(wb)"
+#endif
+#endif
+	.ascii	"\0"
+	.align
+
+	.section ".text.init", #alloc, #execinstr
+
+__arm920_setup:
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
+	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
+	mcr	p15, 0, r4, c2, c0		@ load page table pointer
+	mov	r0, #0x1f			@ Domains 0, 1 = client
+	mcr	p15, 0, r0, c3, c0		@ load domain access register
+	mrc	p15, 0, r0, c1, c0		@ get control register v4
+/*
+ * Clear out 'unwanted' bits (then put them in if we need them)
+ */
+	bic	r0, r0, #0x0e00			@ ....??r.........
+	bic	r0, r0, #0x0002			@ ..............a.
+	bic	r0, r0, #0x000c			@ W,D
+	bic	r0, r0, #0x1000			@ I
+/*
+ * Turn on what we want
+ */
+	orr	r0, r0, #0x0031			@ ..........DP...M
+	orr	r0, r0, #0x0100			@ .......S........
+
+#ifdef CONFIG_CPU_ARM920_D_CACHE_ON
+	orr	r0, r0, #0x0004			@ Enable D cache
+#endif
+#ifdef CONFIG_CPU_ARM920_I_CACHE_ON
+	orr	r0, r0, #0x1000                 @ I Cache on
+#endif
+	mov	pc, lr
+
+	.text
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+	.type	arm920_processor_functions, #object
+arm920_processor_functions:
+	.word	cpu_arm920_data_abort
+	.word	cpu_arm920_check_bugs
+	.word	cpu_arm920_proc_init
+	.word	cpu_arm920_proc_fin
+	.word	cpu_arm920_reset
+	.word   cpu_arm920_do_idle
+
+	/* cache */
+	.word	cpu_arm920_cache_clean_invalidate_all
+	.word	cpu_arm920_cache_clean_invalidate_range
+	.word	cpu_arm920_flush_ram_page
+
+	/* dcache */
+	.word	cpu_arm920_dcache_invalidate_range
+	.word	cpu_arm920_dcache_clean_range
+	.word	cpu_arm920_dcache_clean_page
+	.word	cpu_arm920_dcache_clean_entry
+
+	/* icache */
+	.word	cpu_arm920_icache_invalidate_range
+	.word	cpu_arm920_icache_invalidate_page
+
+	/* tlb */
+	.word	cpu_arm920_tlb_invalidate_all
+	.word	cpu_arm920_tlb_invalidate_range
+	.word	cpu_arm920_tlb_invalidate_page
+
+	/* pgtable */
+	.word	cpu_arm920_set_pgd
+	.word	cpu_arm920_set_pmd
+	.word	cpu_arm920_set_pte
+	.size	arm920_processor_functions, . - arm920_processor_functions
+
+	.type	cpu_arm920_info, #object
+cpu_arm920_info:
+	.long	cpu_manu_name
+	.long	cpu_arm920_name
+	.size	cpu_arm920_info, . - cpu_arm920_info
+
+	.type	cpu_arch_name, #object
+cpu_arch_name:
+	.asciz	"armv4"
+	.size	cpu_arch_name, . - cpu_arch_name
+
+	.type	cpu_elf_name, #object
+cpu_elf_name:
+	.asciz	"v4"
+	.size	cpu_elf_name, . - cpu_elf_name
+	.align
+
+	.section ".proc.info", #alloc, #execinstr
+
+	.type	__arm920_proc_info,#object
+__arm920_proc_info:
+	.long	0x41009200
+	.long	0xff00fff0
+	.long	0x00000c1e			@ mmuflags
+	b	__arm920_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+	.long	cpu_arm920_info
+	.long	arm920_processor_functions
+	.size	__arm920_proc_info, . - __arm920_proc_info
diff -urN linux-2.4.29/arch/armnommu/mm/proc-arm940.S linux-2.4.29-uc1/arch/armnommu/mm/proc-arm940.S
--- linux-2.4.29/arch/armnommu/mm/proc-arm940.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/proc-arm940.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,501 @@
+/*
+ *  linux/arch/arm/mm/arm940.S: PU functions for ARM940
+ *  2001 Minspeed
+ */ 
+#include <linux/linkage.h>
+#include <linux/config.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+#include <asm/hardware.h>
+
+/*
+ * This is the maximum size of an area which will be invalidated
+ * using the single invalidate entry instructions.  Anything larger
+ * than this, and we go for the whole cache.
+ *
+ * This value should be chosen such that we choose the cheapest
+ * alternative.
+ */
+#define MAX_AREA_SIZE	16384
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define DCACHELINESIZE	32
+#define ICACHELINESIZE	32
+
+/*
+ * and the page size
+ */
+#define PAGESIZE	4096
+
+	.text
+
+/*
+ * cpu_arm940_data_abort()
+ *
+ * obtain information about current aborted instruction
+ *
+ * r0 = address of aborted instruction
+ *
+ * Returns:
+ *  r0 = address of abort
+ *  r1 != 0 if writing
+ *  r3 = FSR
+ */
+	.align	5
+ENTRY(cpu_arm940_data_abort)
+	ldr	r1, [r0]			@ read aborted instruction
+	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+	tst	r1, r1, lsr #21			@ C = bit 20
+	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
+	sbc	r1, r1, r1			@ r1 = C - 1
+	and	r3, r3, #255
+	mov	pc, lr
+
+/*
+ * cpu_arm940_check_bugs()
+ */
+ENTRY(cpu_arm940_check_bugs)
+	mrs	ip, cpsr
+	bic	ip, ip, #F_BIT
+	msr	cpsr, ip
+	mov	pc, lr
+
+/*
+ * cpu_arm940_proc_init()
+ */
+ENTRY(cpu_arm940_proc_init)
+	mov	pc, lr
+
+/*
+ * cpu_arm940_proc_fin()
+ */
+ENTRY(cpu_arm940_proc_fin)
+	stmfd	sp!, {lr}
+	mov	ip, #F_BIT | I_BIT | SVC_MODE
+	msr	cpsr_c, ip
+	bl	cpu_arm940_cache_clean_invalidate_all
+	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
+	bic	r0, r0, #0x1000			@ ...i............
+	bic	r0, r0, #0x000e			@ ............wca.
+	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+	ldmfd	sp!, {pc}
+
+/*
+ * cpu_arm940_reset(loc)
+ *
+ * Perform a soft reset of the system.  Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+	.align	5
+ENTRY(cpu_arm940_reset)
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
+	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
+	bic	ip, ip, #0x000f			@ ............wcam
+	bic	ip, ip, #0x1100			@ ...i...s........
+	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
+	mov	pc, r0
+
+/*
+ * cpu_arm940_do_idle()
+ */
+	.align	5
+ENTRY(cpu_arm940_do_idle)  
+#if defined(CONFIG_CPU_ARM940_CPU_IDLE)
+	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
+#endif
+	mov	pc, lr
+
+/* ================================= CACHE ================================ */
+
+
+/*
+ * cpu_arm940_cache_clean_invalidate_all()
+ *
+ * clean and invalidate all cache lines
+ *
+ * Note:
+ *  1. we should preserve r0 at all times
+ */
+	.align	5
+ENTRY(cpu_arm940_cache_clean_invalidate_all)
+	mov	r2, #1
+cpu_arm940_cache_clean_invalidate_all_r2:
+	mov	ip, #0
+#ifdef CONFIG_CPU_ARM940_FORCE_WRITE_THROUGH
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+/*
+ * 'Clean & Invalidate whole DCache'
+ * Re-written to use Index Ops.
+ * Uses registers r1, r3 and ip
+ */
+	mov	r1, #7 << 5			@ 8 segments
+1:	orr	r3, r1, #63 << 26		@ 64 entries
+2:	mcr	p15, 0, r3, c7, c14, 2		@ clean & invalidate D index
+	subs	r3, r3, #1 << 26
+	bcs	2b				@ entries 63 to 0
+	subs	r1, r1, #1 << 5
+	bcs	1b				@ segments 7 to 0
+#endif
+	teq	r2, #0
+	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm940_cache_clean_invalidate_range(start, end, flags)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * start: Area start address
+ * end:   Area end address
+ * flags: nonzero for I cache as well
+ */
+	.align	5
+ENTRY(cpu_arm940_cache_clean_invalidate_range)
+	bic	r0, r0, #DCACHELINESIZE - 1	@ && added by PGM
+	sub	r3, r1, r0
+	cmp	r3, #MAX_AREA_SIZE
+	bgt	cpu_arm940_cache_clean_invalidate_all_r2
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blt	1b
+	teq	r2, #0
+	movne	r0, #0
+	mcrne	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	mov	pc, lr
+
+/*
+ * cpu_arm940_flush_ram_page(page)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * page: page to clean and invalidate
+ */
+	.align	5
+ENTRY(cpu_arm940_flush_ram_page)
+	mov	pc, lr
+	
+
+/* ================================ D-CACHE =============================== */
+
+/*
+ * cpu_arm940_dcache_invalidate_range(start, end)
+ *
+ * throw away all D-cached data in specified region without an obligation
+ * to write them back.  Note however that we must clean the D-cached entries
+ * around the boundaries if the start and/or end address are not cache
+ * aligned.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm940_dcache_invalidate_range)
+	tst	r0, #DCACHELINESIZE - 1
+	bic	r0, r0, #DCACHELINESIZE - 1
+	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
+	tst	r1, #DCACHELINESIZE - 1
+	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blt	1b
+	mov	pc, lr
+
+/*
+ * cpu_arm940_dcache_clean_range(start, end)
+ *
+ * For the specified virtual address range, ensure that all caches contain
+ * clean data, such that peripheral accesses to the physical RAM fetch
+ * correct data.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm940_dcache_clean_range)
+	bic	r0, r0, #DCACHELINESIZE - 1
+	sub	r1, r1, r0
+	cmp	r1, #MAX_AREA_SIZE
+	mov	r2, #0
+	bgt	cpu_arm940_cache_clean_invalidate_all_r2
+
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bpl	1b
+	mcr	p15, 0, r2, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm940_dcache_clean_page(page)
+ *
+ * Cleans a single page of dcache so that if we have any future aliased
+ * mappings, they will be consistent at the time that they are created.
+ *
+ * page: virtual address of page to clean from dcache
+ *
+ * Note:
+ *  1. we don't need to flush the write buffer in this case.
+ *  2. we don't invalidate the entries since when we write the page
+ *     out to disk, the entries may get reloaded into the cache.
+ */
+	.align	5
+ENTRY(cpu_arm940_dcache_clean_page)
+#ifndef CONFIG_CPU_ARM940_FORCE_WRITE_THROUGH
+	mov	r1, #PAGESIZE
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bne	1b
+#endif
+	mov	pc, lr
+
+/*
+ * cpu_arm940_dcache_clean_entry(addr)
+ *
+ * Clean the specified entry of any caches such that the MMU
+ * translation fetches will obtain correct data.
+ *
+ * addr: cache-unaligned virtual address
+ */
+	.align	5
+ENTRY(cpu_arm940_dcache_clean_entry)
+#ifndef CONFIG_CPU_ARM940_FORCE_WRITE_THROUGH
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* ================================ I-CACHE =============================== */
+
+/*
+ * cpu_arm940_icache_invalidate_range(start, end)
+ *
+ * invalidate a range of virtual addresses from the Icache
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm940_icache_invalidate_range)
+1:	mcr	p15, 0, r0, c7, c10, 1		@ Clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+ENTRY(cpu_arm940_icache_invalidate_page)
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	mov	pc, lr
+
+
+/* ================================== TLB ================================= */
+
+/*
+ * cpu_arm940_tlb_invalidate_all()
+ *
+ * Invalidate all TLB entries
+ */
+	.align	5
+ENTRY(cpu_arm940_tlb_invalidate_all)
+	mov	pc, lr
+	
+
+/*
+ * cpu_arm940_tlb_invalidate_range(start, end)
+ *
+ * invalidate TLB entries covering the specified range
+ *
+ * start: range start address
+ * end:   range end address
+ */
+	.align	5
+ENTRY(cpu_arm940_tlb_invalidate_range)
+	mov	pc, lr
+
+/*
+ * cpu_arm940_tlb_invalidate_page(page, flags)
+ *
+ * invalidate the TLB entries for the specified page.
+ *
+ * page:  page to invalidate
+ * flags: non-zero if we include the I TLB
+ */
+	.align	5
+ENTRY(cpu_arm940_tlb_invalidate_page)
+	mov	pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_arm940_set_pgd(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+	.align	5
+ENTRY(cpu_arm940_set_pgd)
+	mov	pc, lr
+
+/*
+ * cpu_arm940_set_pmd(pmdp, pmd)
+ *
+ * Set a level 1 translation table entry, and clean it out of
+ * any caches such that the MMUs can load it correctly.
+ *
+ * pmdp: pointer to PMD entry
+ * pmd:  PMD value to store
+ */
+	.align	5
+ENTRY(cpu_arm940_set_pmd)
+	mov	pc, lr
+
+/*
+ * cpu_arm940_set_pte(ptep, pte)
+ *
+ * Set a PTE and flush it out
+ */
+	.align	5
+ENTRY(cpu_arm940_set_pte)
+	mov	pc, lr
+
+
+cpu_manu_name:
+	.asciz	"ARM/CNXT"
+ENTRY(cpu_arm940_name)
+	.ascii	"Arm940"
+#if defined(CONFIG_CPU_ARM940_CPU_IDLE)
+	.ascii	"s"
+#endif
+#if defined(CONFIG_CPU_ARM940_I_CACHE_ON)
+	.ascii	"i"
+#endif
+#if defined(CONFIG_CPU_ARM940_D_CACHE_ON)
+	.ascii	"d"
+#if defined(CONFIG_CPU_ARM940_FORCE_WRITE_THROUGH)
+	.ascii	"(wt)"
+#else
+	.ascii	"(wb)"
+#endif
+#endif
+	.ascii	"\0"
+	.align
+
+	.section ".text.init", #alloc, #execinstr
+
+__arm940_setup:
+	MRC     p15, 0, R0, c1, c0, 0		@ get control register
+		
+/*
+ * Clear out 'unwanted' bits (then put them in if we need them)
+ */
+	bic	r0, r0, #0x0e00			@ ....??r.........
+	bic	r0, r0, #0x0002			@ ..............a.
+	bic	r0, r0, #0x000c			@ W,D
+	bic	r0, r0, #0x1000			@ I
+/*
+ * Turn on what we want
+ */
+	orr	r0, r0, #0x0001			@ Enable PU
+
+#ifdef CONFIG_CPU_ARM940_D_CACHE_ON
+	orr	r0, r0, #0x0004			@ Enable D cache
+#endif
+#ifdef CONFIG_CPU_ARM940_I_CACHE_ON
+	orr	r0, r0, #0x1000                 @ I Cache on
+#endif
+	mov	pc, lr
+
+	.text
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+	.type	arm940_processor_functions, #object
+arm940_processor_functions:
+	.word	cpu_arm940_data_abort
+	.word	cpu_arm940_check_bugs
+	.word	cpu_arm940_proc_init
+	.word	cpu_arm940_proc_fin
+	.word	cpu_arm940_reset
+	.word   cpu_arm940_do_idle
+
+	/* cache */
+	.word	cpu_arm940_cache_clean_invalidate_all
+	.word	cpu_arm940_cache_clean_invalidate_range
+	.word	cpu_arm940_flush_ram_page
+
+	/* dcache */
+	.word	cpu_arm940_dcache_invalidate_range
+	.word	cpu_arm940_dcache_clean_range
+	.word	cpu_arm940_dcache_clean_page
+	.word	cpu_arm940_dcache_clean_entry
+
+	/* icache */
+	.word	cpu_arm940_icache_invalidate_range
+	.word	cpu_arm940_icache_invalidate_page
+
+	/* tlb */
+	.word	cpu_arm940_tlb_invalidate_all
+	.word	cpu_arm940_tlb_invalidate_range
+	.word	cpu_arm940_tlb_invalidate_page
+
+	/* pgtable */
+	.word	cpu_arm940_set_pgd
+	.word	cpu_arm940_set_pmd
+	.word	cpu_arm940_set_pte
+	.size	arm940_processor_functions, . - arm940_processor_functions
+
+	.type	cpu_arm940_info, #object
+cpu_arm940_info:
+	.long	cpu_manu_name
+	.long	cpu_arm940_name
+	.size	cpu_arm940_info, . - cpu_arm940_info
+
+	.type	cpu_arch_name, #object
+cpu_arch_name:
+	.asciz	"armv4"
+	.size	cpu_arch_name, . - cpu_arch_name
+
+	.type	cpu_elf_name, #object
+cpu_elf_name:
+	.asciz	"v4"
+	.size	cpu_elf_name, . - cpu_elf_name
+	.align
+
+	.section ".proc.info", #alloc, #execinstr
+
+	.type	__arm940_proc_info,#object
+__arm940_proc_info:
+	.long	0x41009400
+	.long	0xff00fff0
+	.long	0x00000c1e			@ mmuflags
+	b	__arm940_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+	.long	cpu_arm940_info
+	.long	arm940_processor_functions
+	.size	__arm940_proc_info, . - __arm940_proc_info
+
+
+
+
diff -urN linux-2.4.29/arch/armnommu/mm/proc-arm940T.S linux-2.4.29-uc1/arch/armnommu/mm/proc-arm940T.S
--- linux-2.4.29/arch/armnommu/mm/proc-arm940T.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/proc-arm940T.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,624 @@
+/*
+ *  linux/arch/arm/mm/arm940T.S: Protection Unit (PU) functions for ARM940T
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ */
+
+#include <linux/linkage.h>
+#include <linux/config.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+#include <asm/hardware.h>
+
+/*
+ * This definitions are not used but it may answer some
+ * questions about ARM940T architecture.
+ *
+ * The size of the I or D cache:
+ * #define MAX_CACHE_SIZE	4096
+ *
+ * the cache line size of the I or D cache:
+ * #define CACHELINESIZE	16
+ *
+ * the segment size:
+ * #define SEG_SIZE		1024
+ *
+ * the number of segments:
+ * #define SEG_NUM		4
+ *
+ * the number of entries
+ * #define ENTRIES_NUM		64
+ *
+ */
+
+	.text
+
+/*
+ * cpu_arm940_data_abort()
+ *
+ * "obtain information about current aborted instruction
+ * Note: we read user space.  This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture.  Unfortunately, this does happen.  We live with it."
+ *				Doesn't work for ARM940.   OZH.
+ *  Input:
+ *  r2 = address of aborted instruction
+ *  r3 = cpsr
+ *
+ * Returns:
+ *  r0 = address of aborted instruction
+ *  r1 != 0 if writing
+ *  r3 = FSR
+ *  r4 = corrupted
+ */
+ 
+	.align	5
+ENTRY(cpu_arm940_data_abort)
+	mov	r3, #0			@ FIXME: ARM940 does not have the fault
+					@ status register. We set 0 status to
+					@ get "Unhandled fault" with SIGKILL
+					@ signal if it is not from the kernel.
+	mov	r0, r2			@ FAR = real address
+	ldr	r1, [r2]		@ read aborted instruction
+	and	r3, r3, #255
+	tst	r1, r1, lsr #21		@ C = bit 20
+	sbc	r1, r1, r1		@ r1 = C - 1
+	mov	pc, lr
+
+/*
+ * cpu_arm940_check_bugs()
+ */
+ENTRY(cpu_arm940_check_bugs)
+	mrs	ip, cpsr
+	bic	ip, ip, #F_BIT
+	msr	cpsr, ip
+	mov	pc, lr
+
+/*
+ * cpu_arm940_proc_init()
+ */
+ENTRY(cpu_arm940_proc_init)
+	mov	pc, lr
+
+/*
+ * cpu_arm940_proc_fin()
+ */
+ENTRY(cpu_arm940_proc_fin)
+	stmfd	sp!, {lr}
+	mov	ip, #F_BIT | I_BIT | SVC_MODE
+	msr	cpsr_c, ip
+	bl	cpu_arm940_cache_clean_invalidate_all
+	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
+	bic	r0, r0, #0x1000			@ ...i............
+	bic	r0, r0, #0x0004			@ .............d..
+	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+	ldmfd	sp!, {pc}
+
+/*
+ * cpu_arm940_reset(loc)
+ *
+ * Perform a soft reset of the system.  Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+	.align	5
+ENTRY(cpu_arm940_reset)
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c5, 0		@ invalidate(flush) I cache
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate(flush) D cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
+	bic	ip, ip, #0x1000			@ ...i............
+	bic	ip, ip, #0x0004			@ .............d..
+	bic	ip, ip, #0x0001			@ ...............p
+	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
+	mov	pc, r0				@ Start from r0 address
+
+/*
+ * cpu_arm940_do_idle()
+ */
+	.align	5
+ENTRY(cpu_arm940_do_idle)
+#if defined(CONFIG_CPU_ARM940_CPU_IDLE)
+	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
+#endif
+	mov	pc, lr
+
+/* ================================= CACHE ================================ */
+/*
+ * cpu_arm940_cache_clean_invalidate_all()
+ *
+ * clean and invalidate all cache lines
+ *
+ * Note:
+ *  1. we should preserve r0 at all times
+ */
+	.align	5
+ENTRY(cpu_arm940_cache_clean_invalidate_all)
+ENTRY(cpu_arm940_flush_ram_page)
+	mov	r2, #1
+
+cpu_arm940_cache_clean_invalidate_all_r2:
+
+	mrc	p15, 0, ip, c3, c0, 0
+	tst	ip, #0xff			@ is Wbuffer enabled?
+	beq	3f
+/*
+ * 'Clean & Invalidate whole DCache'
+ * Re-written to use Index Ops.
+ * Uses registers r1, r3 and ip
+ */
+	mov	r1, #3 << 4			@ 4 segments
+1:	orr	r3, r1, #63 << 26		@ 64 entries
+2:	mcr	p15, 0, r3, c7, c14, 2		@ clean & invalidate(flush) D entry
+	subs	r3, r3, #1 << 26
+	bcs	2b				@ entries 63 to 0
+	subs	r1, r1, #1 << 3
+	bcs	1b				@ segments 3 to 0
+	mov	ip, #0
+	b	4f
+3:
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate(flush) D cache
+	nop;nop;nop
+4:
+	teq	r2, #0
+	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate(flush) I cache
+	nop;nop;nop
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm940_cache_clean_invalidate_range(start, end, flags)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * start: Area start address
+ * end:   Area end address
+ * flags: nonzero for I cache as well
+ */
+		.align	5
+ENTRY(cpu_arm940_cache_clean_invalidate_range)
+	b	cpu_arm940_cache_clean_invalidate_all_r2
+	nop;nop;nop
+
+/* ================================ D-CACHE =============================== */
+
+/*
+ * cpu_arm940_dcache_invalidate_all()
+ *
+ */
+	.align	5
+ENTRY(cpu_arm940_dcache_invalidate_clean_all)
+ENTRY(cpu_arm940_dcache_invalidate_all)
+ENTRY(cpu_arm940_dcache_invalidate_range)
+	mov	r2, #0
+	b	cpu_arm940_cache_clean_invalidate_all_r2
+	nop;nop;nop
+
+/*
+ * cpu_arm940_dcache_clean_all()
+ *
+ */
+	.align	5
+ENTRY(cpu_arm940_dcache_clean_all)
+ENTRY(cpu_arm940_dcache_clean_range)
+ENTRY(cpu_arm940_dcache_clean_page)
+ENTRY(cpu_arm940_dcache_clean_entry)
+	mrc	p15, 0, r1, c3, c0, 0
+	tst	r1, #0xff			@ is Wbuffer enabled?
+	beq	3f
+	mov	r1, #3 << 4			@ 4 segments
+1:	orr	r2, r1, #63 << 26		@ 64 entries
+2:	mcr	p15, 0, r2, c7, c10, 2		@ clean D entry
+	subs	r2, r2, #1 << 26
+	bcs	2b				@ entries 63 to 0
+	subs	r1, r1, #1 << 3
+	bcs	1b				@ segments 3 to 0
+3:
+	mov	pc, lr
+
+	.align	5
+ENTRY(cpu_arm940_dcache_enable)
+	mrc	15, 0, r0, c1, c0, 0
+	orr	r0, r0, #0x4
+	mcr	15, 0, r0, c1, c0, 0
+	mov	pc, lr
+
+ENTRY(cpu_arm940_dcache_disable)
+	mrc	15, 0, r0, c1, c0, 0
+	bic	r0, r0, #0x4
+	mcr	15, 0, r0, c1, c0, 0
+	mov	pc, lr
+
+ENTRY(cpu_arm940_dcache_flush)
+	mov	r0, #0
+	mcr	15, 0, r0, c7, c6, 0
+	nop;nop;nop
+	mov	pc, lr
+
+/* ================================ I-CACHE =============================== */
+
+	.align	5
+ENTRY(cpu_arm940_icache_invalidate_all)
+ENTRY(cpu_arm940_icache_invalidate_range)
+ENTRY(cpu_arm940_icache_invalidate_page)
+
+	b	cpu_arm940_cache_clean_invalidate_all
+	nop;nop;nop
+
+/* ================================== TLB & PageTable ===================== */
+
+	.align	5
+ENTRY(cpu_arm940_tlb_invalidate_all)
+ENTRY(cpu_arm940_tlb_invalidate_range)
+ENTRY(cpu_arm940_tlb_invalidate_page)
+ENTRY(cpu_arm940_set_pgd)
+ENTRY(cpu_arm940_set_pmd)
+ENTRY(cpu_arm940_set_pte)
+
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* =============================== PU functions ===========================
+ *
+ * void arm940_uncache_region_x( unsigned int baseandsize, unsigned int flag);
+ *
+ */
+ENTRY(arm940_uncache_region_4)
+	teq	r1, #0
+	bne	1f
+	mcr	p15, 0, r1, c7, c6, 0		@ invalidate D cache
+	mcr	p15, 0, r0, c6, c4, 0		@ For data
+
+	mrc	p15, 0, r0, c2, c0, 0		@ Make uncacheble
+	bic	r0, r0, #0x10
+	mcr	p15, 0, r0, c2, c0, 0
+
+	mrc	p15, 0, r0, c3, c0, 0		@ Make unbufferable
+	bic	r0, r0, #0x10
+	mcr	p15, 0, r0, c3, c0, 0
+	mov	pc, lr
+1:
+	mov	r1, #0
+	mcr	p15, 0, r1, c7, c5, 0		@ invalidate(flush) I cache
+	mcr	p15, 0, r0, c6, c4, 1		@ For instruction
+	mrc	p15, 0, r0, c2, c0, 1		@ Make uncacheble
+	bic	r0, r0, #0x10
+	mcr	p15, 0, r0, c2, c0, 1
+	mov	pc, lr
+
+ENTRY(arm940_uncache_region_5)
+	teq	r1, #0
+	bne	1f
+	mcr	p15, 0, r1, c7, c6, 0		@ invalidate D cache
+	mcr	p15, 0, r0, c6, c5, 0		@ For data
+
+	mrc	p15, 0, r0, c2, c0, 0		@ Make uncacheble
+	bic	r0, r0, #0x20
+	mcr	p15, 0, r0, c2, c0, 0
+
+	mrc	p15, 0, r0, c3, c0, 0		@ Make unbufferable
+	bic	r0, r0, #0x20
+	mcr	p15, 0, r0, c3, c0, 0
+	mov	pc, lr
+1:
+	mov	r1, #0
+	mcr	p15, 0, r1, c7, c5, 0		@ invalidate(flush) I cache
+	mcr	p15, 0, r0, c6, c5, 1		@ For instruction
+	mrc	p15, 0, r0, c2, c0, 1		@ Make uncacheble
+	bic	r0, r0, #0x20
+	mcr	p15, 0, r0, c2, c0, 1
+	mov	pc, lr
+
+ENTRY(arm940_uncache_region_6)
+	teq	r1, #0
+	bne	1f
+	mcr	p15, 0, r1, c7, c6, 0		@ invalidate D cache
+	mcr	p15, 0, r0, c6, c6, 0		@ For data
+
+	mrc	p15, 0, r0, c2, c0, 0		@ Make uncacheble
+	bic	r0, r0, #0x40
+	mcr	p15, 0, r0, c2, c0, 0
+
+	mrc	p15, 0, r0, c3, c0, 0		@ Make unbufferable
+	bic	r0, r0, #0x40
+	mcr	p15, 0, r0, c3, c0, 0
+	mov	pc, lr
+1:
+	mov	r1, #0
+	mcr	p15, 0, r1, c7, c5, 0		@ invalidate(flush) I cache
+	mcr	p15, 0, r0, c6, c6, 1		@ For instruction
+	mrc	p15, 0, r0, c2, c0, 1		@ Make uncacheble
+	bic	r0, r0, #0x40
+	mcr	p15, 0, r0, c2, c0, 1
+	mov	pc, lr
+
+ENTRY(arm940_uncache_region_7)
+	teq	r1, #0
+	bne	1f
+	mcr	p15, 0, r1, c7, c6, 0		@ invalidate D cache
+	mcr	p15, 0, r0, c6, c7, 0		@ For data
+
+	mrc	p15, 0, r0, c2, c0, 0		@ Make uncacheble
+	bic	r0, r0, #0x80
+	mcr	p15, 0, r0, c2, c0, 0
+
+	mrc	p15, 0, r0, c3, c0, 0		@ Make unbufferable
+	bic	r0, r0, #0x80
+	mcr	p15, 0, r0, c3, c0, 0
+	mov	pc, lr
+1:	
+	mov	r1, #0
+	mcr	p15, 0, r1, c7, c5, 0		@ invalidate(flush) I cache
+	mcr	p15, 0, r0, c6, c7, 1		@ For instruction
+	mrc	p15, 0, r0, c2, c0, 1		@ Make uncacheble
+	bic	r0, r0, #0x80
+	mcr	p15, 0, r0, c2, c0, 1
+	mov	pc, lr
+
+	.global arm940_get_creg_0
+arm940_get_creg_0:
+	mrc	p15, 0, r0, c0, c0, 0
+	mov	pc, lr
+
+	.global arm940_get_creg_1
+arm940_get_creg_1:
+	mrc	p15, 0, r0, c1, c0, 0
+	mov	pc, lr
+
+	.global arm940_get_creg_2
+arm940_get_creg_2:
+	teq	r0, #0
+	mrceq	p15, 0, r0, c2, c0, 0
+	mrcne	p15, 0, r0, c2, c0, 1
+	mov	pc, lr
+
+	.global arm940_get_creg_3
+arm940_get_creg_3:
+	mrc	p15, 0, r0, c3, c0, 0
+	mov	pc, lr
+
+	.global arm940_get_creg_5
+arm940_get_creg_5:
+	teq	r0, #0
+	mrceq	p15, 0, r0, c5, c0, 0
+	mrcne	p15, 0, r0, c5, c0, 1
+	mov	pc, lr
+
+	.global arm940_get_creg_6_0
+arm940_get_creg_6_0:
+	teq	r0, #0
+	mrceq	p15, 0, r0, c6, c0, 0
+	mrcne	p15, 0, r0, c6, c0, 1
+	mov	pc, lr
+
+	.global arm940_get_creg_6_1
+arm940_get_creg_6_1:
+	teq	r0, #0
+	mrceq	p15, 0, r0, c6, c1, 0
+	mrcne	p15, 0, r0, c6, c1, 1
+	mov	pc, lr
+
+	.global arm940_get_creg_6_2
+arm940_get_creg_6_2:
+	teq	r0, #0
+	mrceq	p15, 0, r0, c6, c2, 0
+	mrcne	p15, 0, r0, c6, c2, 1
+	mov	pc, lr
+
+	.global arm940_get_creg_6_3
+arm940_get_creg_6_3:
+	teq	r0, #0
+	mrceq	p15, 0, r0, c6, c3, 0
+	mrcne	p15, 0, r0, c6, c3, 1
+	mov	pc, lr
+
+	.global arm940_get_creg_6_4
+arm940_get_creg_6_4:
+	teq	r0, #0
+	mrceq	p15, 0, r0, c6, c4, 0
+	mrcne	p15, 0, r0, c6, c4, 1
+	mov	pc, lr
+
+	.global arm940_get_creg_6_5
+arm940_get_creg_6_5:
+	teq	r0, #0
+	mrceq	p15, 0, r0, c6, c5, 0
+	mrcne	p15, 0, r0, c6, c5, 1
+	mov	pc, lr
+
+	.global arm940_get_creg_6_6
+arm940_get_creg_6_6:
+	teq	r0, #0
+	mrceq	p15, 0, r0, c6, c6, 0
+	mrcne	p15, 0, r0, c6, c6, 1
+	mov	pc, lr
+
+	.global arm940_get_creg_6_7
+arm940_get_creg_6_7:
+	teq	r0, #0
+	mrceq	p15, 0, r0, c6, c7, 0
+	mrcne	p15, 0, r0, c6, c7, 1
+	mov	pc, lr
+
+cpu_manu_name:
+	.asciz	"Samsung"
+ENTRY(cpu_arm940_name)
+	.ascii	"Arm940T"
+#if defined(CONFIG_CPU_ARM940_CPU_IDLE)
+	.ascii	"s"
+#endif
+
+#if defined(CONFIG_UCBOOTSTRAP)
+
+icache_ascii:
+	.ascii	"-"
+dcache_ascii:
+	.ascii	"-"
+wbuffer_ascii:
+	.ascii	"(wt)"
+	.ascii	"\0"
+	.align
+
+	.section ".text.init", #alloc, #execinstr
+
+__arm940_setup:
+	mov	r0, #0
+	MCR	p15, 0, r0, c7, c5, 0		@ invalidate ICache on v4
+	MCR	p15, 0, r0, c7, c6, 0		@ invalidate DCache on v4
+	MCR	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
+	MRC	p15, 0, r0, c1, c0, 0		@ get control register v4
+	
+	ldr	r1, ptr_icache_ascii
+	tst	r0, #0x1000			@ is Icache enable?
+	movne	r2, #0x69
+	moveq	r2, #0x2d
+	strneb	r2, [r1]
+	nop;nop;nop
+
+	ldr	r1, ptr_dcache_ascii
+	mov	r2, #0x64
+	tst	r0, #0x0004			@ is Dcache enable?
+	movne	r2, #0x64
+	moveq	r2, #0x2d
+	strneb	r2, [r1]
+	nop;nop;nop
+	
+	ldr	r1, ptr_wbuffer_ascii
+	mrc	p15, 0, r2, c3, c0, 0
+	tst	r2, #0xff			@ is Wbuffer enable?
+	movne	r2, #0x62
+	moveq	r2, #0x74
+	strneb	r2, [r1]
+
+	orr	r0, r0, #1			@ Enable PU
+	mov	pc, lr
+	nop;nop;nop
+
+ptr_icache_ascii:
+	.long	icache_ascii
+ptr_dcache_ascii:
+	.long	dcache_ascii
+ptr_wbuffer_ascii:
+	.long	wbuffer_ascii+2
+	
+#else	/* CONFIG_UCBOOTSTRAP */
+
+#if defined(CONFIG_CPU_ARM940_I_CACHE_ON)
+	.ascii	"i"
+#endif
+#if defined(CONFIG_CPU_ARM940_D_CACHE_ON)
+	.ascii	"d"
+#if defined(CONFIG_CPU_ARM940_WRITETHROUGH)
+	.ascii	"(wt)"
+#else
+	.ascii	"(wb)"
+#endif
+#endif
+	.ascii	"\0"
+	.align
+
+	.section ".text.init", #alloc, #execinstr
+
+__arm940_setup:
+	mov	r0, #0
+	MCR	p15, 0, r0, c7, c5, 0		@ invalidate ICache on v4
+	MCR	p15, 0, r0, c7, c6, 0		@ invalidate DCache on v4
+	MCR	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
+	MRC	p15, 0, r0, c1, c0, 0		@ get control register v4
+#if defined(CONFIG_CPU_ARM940_I_CACHE_ON)
+	orr	r0, r0, #0x1000
+#else
+	bic	r0, r0, #0x1000
+#endif
+#if defined(CONFIG_CPU_ARM940_D_CACHE_ON)
+	orr	r0, r0, #0x4
+#else
+	bic	r0, r0, #0x4
+#endif
+	orr	r0, r0, #1			@ Enable PU
+	mov	pc, lr
+	nop;nop;nop
+
+#endif	/* CONFIG_UCBOOTSTRAP */
+
+	
+	.text
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+	.type	arm940_processor_functions, #object
+arm940_processor_functions:
+	.word	cpu_arm940_data_abort
+	.word	cpu_arm940_check_bugs
+	.word	cpu_arm940_proc_init
+	.word	cpu_arm940_proc_fin
+	.word	cpu_arm940_reset
+	.word   cpu_arm940_do_idle
+
+	/* cache */
+	.word	cpu_arm940_cache_clean_invalidate_all
+	.word	cpu_arm940_cache_clean_invalidate_range
+	.word	cpu_arm940_flush_ram_page
+
+	/* dcache */
+	.word	cpu_arm940_dcache_invalidate_range
+	.word	cpu_arm940_dcache_clean_range
+	.word	cpu_arm940_dcache_clean_page
+	.word	cpu_arm940_dcache_clean_entry
+
+	/* icache */
+	.word	cpu_arm940_icache_invalidate_range
+	.word	cpu_arm940_icache_invalidate_page
+
+	/* tlb */
+	.word	cpu_arm940_tlb_invalidate_all
+	.word	cpu_arm940_tlb_invalidate_range
+	.word	cpu_arm940_tlb_invalidate_page
+
+	/* pgtable */
+	.word	cpu_arm940_set_pgd
+	.word	cpu_arm940_set_pmd
+	.word	cpu_arm940_set_pte
+	.size	arm940_processor_functions, . - arm940_processor_functions
+
+	.type	cpu_arm940_info, #object
+cpu_arm940_info:
+	.long	cpu_manu_name
+	.long	cpu_arm940_name
+	.size	cpu_arm940_info, . - cpu_arm940_info
+
+	.type	cpu_arch_name, #object
+cpu_arch_name:
+	.asciz	"armv4"
+	.size	cpu_arch_name, . - cpu_arch_name
+
+	.type	cpu_elf_name, #object
+cpu_elf_name:
+	.asciz	"v4"
+	.size	cpu_elf_name, . - cpu_elf_name
+	.align
+
+	.section ".proc.info", #alloc, #execinstr
+
+	.type	__arm940_proc_info,#object
+__arm940_proc_info:
+	.long	0x41009400
+	.long	0xff00fff0
+	.long	0x00000c1e			@ mmuflags
+	b	__arm940_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+	.long	cpu_arm940_info
+	.long	arm940_processor_functions
+	.size	__arm940_proc_info, . - __arm940_proc_info
diff -urN linux-2.4.29/arch/armnommu/mm/proc-sa110.S linux-2.4.29-uc1/arch/armnommu/mm/proc-sa110.S
--- linux-2.4.29/arch/armnommu/mm/proc-sa110.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/proc-sa110.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,774 @@
+/*
+ *  linux/arch/arm/mm/proc-sa110.S
+ *
+ *  Copyright (C) 1997-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  MMU functions for SA110
+ *
+ *  These are the low level assembler for performing cache and TLB
+ *  functions on the StrongARM-110, StrongARM-1100 and StrongARM-1110.
+ * 
+ *  Note that SA1100 and SA1110 share everything but their name and CPU ID.
+ *
+ *  12-jun-2000, Erik Mouw (J.A.K.Mouw@its.tudelft.nl):
+ *    Flush the read buffer at context switches
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+#include <asm/hardware.h>
+
+/* This is the maximum size of an area which will be flushed.  If the area
+ * is larger than this, then we flush the whole cache
+ */
+#define MAX_AREA_SIZE	32768
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define DCACHELINESIZE	32
+
+/*
+ * and the page size
+ */
+#define PAGESIZE	4096
+
+#define FLUSH_OFFSET	32768
+
+		.macro flush_110_dcache	rd, ra, re
+		add	\re, \ra, #16384		@ only necessary for 16k
+1001:		ldr	\rd, [\ra], #DCACHELINESIZE
+		teq	\re, \ra
+		bne	1001b
+		.endm
+
+		.macro flush_1100_dcache	rd, ra, re
+		add	\re, \ra, #8192			@ only necessary for 8k
+1001:		ldr	\rd, [\ra], #DCACHELINESIZE
+		teq	\re, \ra
+		bne	1001b
+#ifdef FLUSH_BASE_MINICACHE
+		add	\ra, \ra, #FLUSH_BASE_MINICACHE - FLUSH_BASE
+		add	\re, \ra, #512			@ only 512 bytes
+1002:		ldr	\rd, [\ra], #DCACHELINESIZE
+		teq	\re, \ra
+		bne	1002b
+#endif
+		.endm
+
+		.data
+Lclean_switch:	.long	0
+		.text
+
+
+/*
+ * cpu_sa110_data_abort()
+ *
+ * obtain information about current aborted instruction
+ *
+ * r0 = address of aborted instruction
+ *
+ * Returns:
+ *  r0 = address of abort
+ *  r1 != 0 if writing
+ *  r3 = FSR
+ */
+	.align	5
+ENTRY(cpu_sa110_data_abort)
+ENTRY(cpu_sa1100_data_abort)
+	ldr	r1, [r0]			@ read aborted instruction
+	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+	tst	r1, r1, lsr #21			@ C = bit 20
+	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
+	sbc	r1, r1, r1			@ r1 = C - 1
+	and	r3, r3, #255
+	mov	pc, lr
+
+/*
+ * cpu_sa110_check_bugs()
+ */
+ENTRY(cpu_sa110_check_bugs)
+ENTRY(cpu_sa1100_check_bugs)
+	mrs	ip, cpsr
+	bic	ip, ip, #F_BIT
+	msr	cpsr, ip
+	mov	pc, lr
+
+/*
+ * cpu_sa110_proc_init()
+ */
+ENTRY(cpu_sa110_proc_init)
+ENTRY(cpu_sa1100_proc_init)
+	mov	r0, #0
+	mcr	p15, 0, r0, c15, c1, 2		@ Enable clock switching
+	mov	pc, lr
+
+/*
+ * cpu_sa110_proc_fin()
+ */
+ENTRY(cpu_sa110_proc_fin)
+	stmfd	sp!, {lr}
+	mov	ip, #F_BIT | I_BIT | SVC_MODE
+	msr	cpsr_c, ip
+	bl	cpu_sa110_cache_clean_invalidate_all	@ clean caches
+1:	mov	r0, #0
+	mcr	p15, 0, r0, c15, c2, 2		@ Disable clock switching
+	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
+	bic	r0, r0, #0x1000			@ ...i............
+	bic	r0, r0, #0x000e			@ ............wca.
+	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+	ldmfd	sp!, {pc}
+
+ENTRY(cpu_sa1100_proc_fin)
+	stmfd	sp!, {lr}
+	mov	ip, #F_BIT | I_BIT | SVC_MODE
+	msr	cpsr_c, ip
+	bl	cpu_sa1100_cache_clean_invalidate_all	@ clean caches
+	b	1b
+
+/*
+ * cpu_sa110_reset(loc)
+ *
+ * Perform a soft reset of the system.  Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+	.align	5
+ENTRY(cpu_sa110_reset)
+ENTRY(cpu_sa1100_reset)
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
+	bic	ip, ip, #0x000f			@ ............wcam
+	bic	ip, ip, #0x1100			@ ...i...s........
+	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
+	mov	pc, r0
+
+/*
+ * cpu_sa110_do_idle(type)
+ *
+ * Cause the processor to idle
+ *
+ * type: call type:
+ *   0 = slow idle
+ *   1 = fast idle
+ *   2 = switch to slow processor clock
+ *   3 = switch to fast processor clock
+ */
+	.align	5
+idle:	mcr	p15, 0, r0, c15, c8, 2		@ Wait for interrupt, cache aligned
+	mov	r0, r0				@ safety
+	mov	pc, lr
+
+ENTRY(cpu_sa110_do_idle)
+	mov	ip, #0
+	cmp	r0, #4
+	addcc	pc, pc, r0, lsl #2
+	mov	pc, lr
+
+	b	idle
+	b	idle
+	b	slow_clock
+	b	fast_clock
+
+fast_clock:
+	mcr	p15, 0, ip, c15, c1, 2		@ enable clock switching
+	mov	pc, lr
+
+slow_clock:
+	mcr	p15, 0, ip, c15, c2, 2		@ disable clock switching
+	ldr	r1, =UNCACHEABLE_ADDR		@ load from uncacheable loc
+	ldr	r1, [r1, #0]			@ force switch to MCLK
+	mov	pc, lr
+
+	.align	5
+ENTRY(cpu_sa1100_do_idle)
+	mov	r0, r0				@ 4 nop padding
+	mov	r0, r0
+	mov	r0, r0
+	mov	r0, #0
+	ldr	r1, =UNCACHEABLE_ADDR		@ ptr to uncacheable address
+	mrs	r2, cpsr
+	orr	r3, r2, #192			@ disallow interrupts
+	msr	cpsr_c, r3
+	@ --- aligned to a cache line
+	mcr	p15, 0, r0, c15, c2, 2		@ disable clock switching
+	ldr	r1, [r1, #0]			@ force switch to MCLK
+	mcr	p15, 0, r0, c15, c8, 2		@ wait for interrupt
+	mov	r0, r0				@ safety
+	mcr	p15, 0, r0, c15, c1, 2		@ enable clock switching
+	msr	cpsr_c, r2			@ allow interrupts
+	mov	pc, lr
+
+/* ================================= CACHE ================================ */
+
+
+/*
+ * cpu_sa110_cache_clean_invalidate_all (void)
+ *
+ * clean and invalidate all cache lines
+ *
+ * Note:
+ *  1. we should preserve r0 at all times
+ */
+	.align	5
+ENTRY(cpu_sa110_cache_clean_invalidate_all)
+	mov	r2, #1
+cpu_sa110_cache_clean_invalidate_all_r2:
+	ldr	r3, =Lclean_switch
+	ldr	ip, =FLUSH_BASE
+	ldr	r1, [r3]
+	ands	r1, r1, #1
+	eor	r1, r1, #1
+	str	r1, [r3]
+	addne	ip, ip, #FLUSH_OFFSET
+	flush_110_dcache	r3, ip, r1
+	mov	ip, #0
+	teq	r2, #0
+	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+	.align	5
+ENTRY(cpu_sa1100_cache_clean_invalidate_all)
+	mov	r2, #1
+cpu_sa1100_cache_clean_invalidate_all_r2:
+	ldr	r3, =Lclean_switch
+	ldr	ip, =FLUSH_BASE
+	ldr	r1, [r3]
+	ands	r1, r1, #1
+	eor	r1, r1, #1
+	str	r1, [r3]
+	addne	ip, ip, #FLUSH_OFFSET
+	flush_1100_dcache	r3, ip, r1
+	mov	ip, #0
+	teq	r2, #0
+	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, r1, c9, c0, 0		@ invalidate RB
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_sa110_cache_clean_invalidate_range(start, end, flags)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * start: Area start address
+ * end:   Area end address
+ * flags: nonzero for I cache as well
+ */
+	.align	5
+ENTRY(cpu_sa110_cache_clean_invalidate_range)
+	bic	r0, r0, #DCACHELINESIZE - 1
+	sub	r3, r1, r0
+	cmp	r3, #MAX_AREA_SIZE
+	bgt	cpu_sa110_cache_clean_invalidate_all_r2
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blt	1b
+	teq	r2, #0
+	movne	r0, #0
+	mcrne	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	mov	pc, lr
+
+ENTRY(cpu_sa1100_cache_clean_invalidate_range)
+	sub	r3, r1, r0
+	cmp	r3, #MAX_AREA_SIZE
+	bgt	cpu_sa1100_cache_clean_invalidate_all_r2
+	b	1b
+
+/*
+ * cpu_sa110_flush_ram_page(page)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * page: page to clean and invalidate
+ */
+	.align	5
+ENTRY(cpu_sa110_flush_ram_page)
+ENTRY(cpu_sa1100_flush_ram_page)
+	mov	r1, #PAGESIZE
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bne	1b
+	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* ================================ D-CACHE =============================== */
+
+/*
+ * cpu_sa110_dcache_invalidate_range(start, end)
+ *
+ * throw away all D-cached data in specified region without an obligation
+ * to write them back.  Note however that we must clean the D-cached entries
+ * around the boundaries if the start and/or end address are not cache
+ * aligned.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_sa110_dcache_invalidate_range)
+ENTRY(cpu_sa1100_dcache_invalidate_range)
+	tst	r0, #DCACHELINESIZE - 1
+	bic	r0, r0, #DCACHELINESIZE - 1
+	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
+	tst	r1, #DCACHELINESIZE - 1
+	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blt	1b
+	mov	pc, lr
+
+/*
+ * cpu_sa110_dcache_clean_range(start, end)
+ *
+ * For the specified virtual address range, ensure that all caches contain
+ * clean data, such that peripheral accesses to the physical RAM fetch
+ * correct data.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_sa110_dcache_clean_range)
+	bic	r0, r0, #DCACHELINESIZE - 1
+	sub	r1, r1, r0
+	cmp	r1, #MAX_AREA_SIZE
+	mov	r2, #0
+	bgt	cpu_sa110_cache_clean_invalidate_all_r2
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bpl	1b
+	mcr	p15, 0, r2, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+ENTRY(cpu_sa1100_dcache_clean_range)
+	bic	r0, r0, #DCACHELINESIZE - 1
+	sub	r1, r1, r0
+	cmp	r1, #MAX_AREA_SIZE
+	mov	r2, #0
+	bgt	cpu_sa1100_cache_clean_invalidate_all_r2
+	b	1b
+
+/*
+ * cpu_sa110_clean_dcache_page(page)
+ *
+ * Cleans a single page of dcache so that if we have any future aliased
+ * mappings, they will be consistent at the time that they are created.
+ *
+ * Note:
+ *  1. we don't need to flush the write buffer in this case.
+ *  2. we don't invalidate the entries since when we write the page
+ *     out to disk, the entries may get reloaded into the cache.
+ */
+	.align	5
+ENTRY(cpu_sa110_dcache_clean_page)
+ENTRY(cpu_sa1100_dcache_clean_page)
+	mov	r1, #PAGESIZE
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bne	1b
+	mov	pc, lr
+
+/*
+ * cpu_sa110_dcache_clean_entry(addr)
+ *
+ * Clean the specified entry of any caches such that the MMU
+ * translation fetches will obtain correct data.
+ *
+ * addr: cache-unaligned virtual address
+ */
+	.align	5
+ENTRY(cpu_sa110_dcache_clean_entry)
+ENTRY(cpu_sa1100_dcache_clean_entry)
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* ================================ I-CACHE =============================== */
+
+/*
+ * cpu_sa110_icache_invalidate_range(start, end)
+ *
+ * invalidate a range of virtual addresses from the Icache
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_sa110_icache_invalidate_range)
+ENTRY(cpu_sa1100_icache_invalidate_range)
+1:	mcr	p15, 0, r0, c7, c10, 1		@ Clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+ENTRY(cpu_sa110_icache_invalidate_page)
+ENTRY(cpu_sa1100_icache_invalidate_page)
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	mov	pc, lr
+
+/* ================================== TLB ================================= */
+
+/*
+ * cpu_sa110_tlb_invalidate_all()
+ *
+ * Invalidate all TLB entries
+ */
+	.align	5
+ENTRY(cpu_sa110_tlb_invalidate_all)
+ENTRY(cpu_sa1100_tlb_invalidate_all)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, lr
+
+/*
+ * cpu_sa110_tlb_invalidate_range(start, end)
+ *
+ * invalidate TLB entries covering the specified range
+ *
+ * start: range start address
+ * end:   range end address
+ */
+	.align	5
+ENTRY(cpu_sa110_tlb_invalidate_range)
+ENTRY(cpu_sa1100_tlb_invalidate_range)
+	mov	r3, #0
+	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
+1:	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
+	add	r0, r0, #PAGESIZE
+	cmp	r0, r1
+	blt	1b
+	mcr	p15, 0, r3, c8, c5, 0		@ invalidate I TLB
+	mov	pc, lr
+
+/*
+ * cpu_sa110_tlb_invalidate_page(page, flags)
+ *
+ * invalidate the TLB entries for the specified page.
+ *
+ * page:  page to invalidate
+ * flags: non-zero if we include the I TLB
+ */
+	.align	5
+ENTRY(cpu_sa110_tlb_invalidate_page)
+ENTRY(cpu_sa1100_tlb_invalidate_page)
+	mov	r3, #0
+	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
+	teq	r1, #0
+	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
+	mcrne	p15, 0, r3, c8, c5, 0		@ invalidate I TLB
+	mov	pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_sa110_set_pgd(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+	.align	5
+ENTRY(cpu_sa110_set_pgd)
+	ldr	r3, =Lclean_switch
+	ldr	ip, =FLUSH_BASE
+	ldr	r2, [r3]
+	ands	r2, r2, #1
+	eor	r2, r2, #1
+	str	r2, [r3]
+	addne	ip, ip, #FLUSH_OFFSET
+	flush_110_dcache	r3, ip, r1
+	mov	r1, #0
+	mcr	p15, 0, r1, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
+	mcr	p15, 0, r1, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, lr
+
+/*
+ * cpu_sa1100_set_pgd(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+	.align	5
+ENTRY(cpu_sa1100_set_pgd)
+	ldr	r3, =Lclean_switch
+	ldr	ip, =FLUSH_BASE
+	ldr	r2, [r3]
+	ands	r2, r2, #1
+	eor	r2, r2, #1
+	str	r2, [r3]
+	addne	ip, ip, #FLUSH_OFFSET
+	flush_1100_dcache	r3, ip, r1
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c9, c0, 0		@ invalidate RB
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, lr
+
+/*
+ * cpu_sa110_set_pmd(pmdp, pmd)
+ *
+ * Set a level 1 translation table entry, and clean it out of
+ * any caches such that the MMUs can load it correctly.
+ *
+ * pmdp: pointer to PMD entry
+ * pmd:  PMD value to store
+ */
+	.align	5
+ENTRY(cpu_sa110_set_pmd)
+ENTRY(cpu_sa1100_set_pmd)
+	str	r1, [r0]
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_sa110_set_pte(ptep, pte)
+ *
+ * Set a PTE and flush it out
+ */
+	.align	5
+ENTRY(cpu_sa110_set_pte)
+ENTRY(cpu_sa1100_set_pte)
+	str	r1, [r0], #-1024		@ linux version
+
+	eor	r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
+	bic	r2, r1, #0xff0
+	bic	r2, r2, #3
+	orr	r2, r2, #HPTE_TYPE_SMALL
+
+	tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+	orrne	r2, r2, #HPTE_AP_READ
+
+	tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
+	orreq	r2, r2, #HPTE_AP_WRITE
+
+	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
+	movne	r2, #0
+
+	str	r2, [r0]			@ hardware version
+	mov	r0, r0
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+
+cpu_manu_name:
+	.asciz	"Intel"
+cpu_sa110_name:
+	.asciz	"StrongARM-110"
+cpu_sa1100_name:
+	.asciz	"StrongARM-1100"
+cpu_sa1110_name:
+	.asciz	"StrongARM-1110"
+	.align
+
+	.section ".text.init", #alloc, #execinstr
+
+__sa1100_setup:	@ Allow read-buffer operations from userland
+	mcr	p15, 0, r0, c9, c0, 5
+	mrc	p15, 0, r0, c1, c0		@ get control register v4
+	bic	r0, r0, #0x0e00			@ ..VI ZFRS BLDP WCAM
+	bic	r0, r0, #0x0002			@ .... 000. .... ..0.
+	orr	r0, r0, #0x003d
+	orr	r0, r0, #0x3100			@ ..11 ...1 ..11 11.1
+	b	__setup_common
+
+__sa110_setup:
+	mrc	p15, 0, r0, c1, c0		@ get control register v4
+	bic	r0, r0, #0x2e00			@ ..VI ZFRS BLDP WCAM
+	bic	r0, r0, #0x0002			@ ..0. 000. .... ..0.
+	orr	r0, r0, #0x003d
+	orr	r0, r0, #0x1100			@ ...1 ...1 ..11 11.1
+__setup_common:
+	mov	r10, #0
+	mcr	p15, 0, r10, c7, c7		@ invalidate I,D caches on v4
+	mcr	p15, 0, r10, c7, c10, 4		@ drain write buffer on v4
+	mcr	p15, 0, r10, c8, c7		@ invalidate I,D TLBs on v4
+	mcr	p15, 0, r4, c2, c0		@ load page table pointer
+	mov	r10, #0x1f			@ Domains 0, 1 = client
+	mcr	p15, 0, r10, c3, c0		@ load domain access register
+	mov	pc, lr
+
+	.text
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+
+	.type	sa110_processor_functions, #object
+ENTRY(sa110_processor_functions)
+	.word	cpu_sa110_data_abort
+	.word	cpu_sa110_check_bugs
+	.word	cpu_sa110_proc_init
+	.word	cpu_sa110_proc_fin
+	.word	cpu_sa110_reset
+	.word	cpu_sa110_do_idle
+
+	/* cache */
+	.word	cpu_sa110_cache_clean_invalidate_all
+	.word	cpu_sa110_cache_clean_invalidate_range
+	.word	cpu_sa110_flush_ram_page
+
+	/* dcache */
+	.word	cpu_sa110_dcache_invalidate_range
+	.word	cpu_sa110_dcache_clean_range
+	.word	cpu_sa110_dcache_clean_page
+	.word	cpu_sa110_dcache_clean_entry
+
+	/* icache */
+	.word	cpu_sa110_icache_invalidate_range
+	.word	cpu_sa110_icache_invalidate_page
+
+	/* tlb */
+	.word	cpu_sa110_tlb_invalidate_all
+	.word	cpu_sa110_tlb_invalidate_range
+	.word	cpu_sa110_tlb_invalidate_page
+
+	/* pgtable */
+	.word	cpu_sa110_set_pgd
+	.word	cpu_sa110_set_pmd
+	.word	cpu_sa110_set_pte
+	.size	sa110_processor_functions, . - sa110_processor_functions
+
+	.type	cpu_sa110_info, #object
+cpu_sa110_info:
+	.long	cpu_manu_name
+	.long	cpu_sa110_name
+	.size	cpu_sa110_info, . - cpu_sa110_info
+
+
+/*
+ * SA1100 and SA1110 share the same function calls
+ */
+	.type	sa1100_processor_functions, #object
+ENTRY(sa1100_processor_functions)
+	.word	cpu_sa1100_data_abort
+	.word	cpu_sa1100_check_bugs
+	.word	cpu_sa1100_proc_init
+	.word	cpu_sa1100_proc_fin
+	.word	cpu_sa1100_reset
+	.word	cpu_sa1100_do_idle
+
+	/* cache */
+	.word	cpu_sa1100_cache_clean_invalidate_all
+	.word	cpu_sa1100_cache_clean_invalidate_range
+	.word	cpu_sa1100_flush_ram_page
+
+	/* dcache */
+	.word	cpu_sa1100_dcache_invalidate_range
+	.word	cpu_sa1100_dcache_clean_range
+	.word	cpu_sa1100_dcache_clean_page
+	.word	cpu_sa1100_dcache_clean_entry
+
+	/* icache */
+	.word	cpu_sa1100_icache_invalidate_range
+	.word	cpu_sa1100_icache_invalidate_page
+
+	/* tlb */
+	.word	cpu_sa1100_tlb_invalidate_all
+	.word	cpu_sa1100_tlb_invalidate_range
+	.word	cpu_sa1100_tlb_invalidate_page
+
+	/* pgtable */
+	.word	cpu_sa1100_set_pgd
+	.word	cpu_sa1100_set_pmd
+	.word	cpu_sa1100_set_pte
+	.size	sa1100_processor_functions, . - sa1100_processor_functions
+
+cpu_sa1100_info:
+	.long	cpu_manu_name
+	.long	cpu_sa1100_name
+	.size	cpu_sa1100_info, . - cpu_sa1100_info
+
+cpu_sa1110_info:
+	.long	cpu_manu_name
+	.long	cpu_sa1110_name
+	.size	cpu_sa1110_info, . - cpu_sa1110_info
+
+	.type	cpu_arch_name, #object
+cpu_arch_name:
+	.asciz	"armv4"
+	.size	cpu_arch_name, . - cpu_arch_name
+
+	.type	cpu_elf_name, #object
+cpu_elf_name:
+	.asciz	"v4"
+	.size	cpu_elf_name, . - cpu_elf_name
+	.align
+
+	.section ".proc.info", #alloc, #execinstr
+
+	.type	__sa110_proc_info,#object
+__sa110_proc_info:
+	.long	0x4401a100
+	.long	0xfffffff0
+	.long	0x00000c0e
+	b	__sa110_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
+	.long	cpu_sa110_info
+	.long	sa110_processor_functions
+	.size	__sa110_proc_info, . - __sa110_proc_info
+
+	.type	__sa1100_proc_info,#object
+__sa1100_proc_info:
+	.long	0x4401a110
+	.long	0xfffffff0
+	.long	0x00000c0e
+	b	__sa1100_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
+	.long	cpu_sa1100_info
+	.long	sa1100_processor_functions
+	.size	__sa1100_proc_info, . - __sa1100_proc_info
+
+	.type	__sa1110_proc_info,#object
+__sa1110_proc_info:
+	.long	0x6901b110
+	.long	0xfffffff0
+	.long	0x00000c0e
+	b	__sa1100_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
+	.long	cpu_sa1110_info
+	.long	sa1100_processor_functions
+	.size	__sa1110_proc_info, . - __sa1110_proc_info
diff -urN linux-2.4.29/arch/armnommu/mm/proc-syms.c linux-2.4.29-uc1/arch/armnommu/mm/proc-syms.c
--- linux-2.4.29/arch/armnommu/mm/proc-syms.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/proc-syms.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,31 @@
+/*
+ *  linux/arch/arm/mm/proc-syms.c
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <asm/proc-fns.h>
+
+#ifndef MULTI_CPU
+EXPORT_SYMBOL(cpu_cache_clean_invalidate_all);
+EXPORT_SYMBOL(cpu_cache_clean_invalidate_range);
+EXPORT_SYMBOL(cpu_flush_ram_page);
+EXPORT_SYMBOL(cpu_dcache_clean_page);
+EXPORT_SYMBOL(cpu_dcache_clean_entry);
+EXPORT_SYMBOL(cpu_dcache_clean_range);
+EXPORT_SYMBOL(cpu_dcache_invalidate_range);
+EXPORT_SYMBOL(cpu_icache_invalidate_range);
+EXPORT_SYMBOL(cpu_icache_invalidate_page);
+EXPORT_SYMBOL(cpu_tlb_invalidate_all);
+EXPORT_SYMBOL(cpu_tlb_invalidate_range);
+EXPORT_SYMBOL(cpu_tlb_invalidate_page);
+EXPORT_SYMBOL(cpu_set_pgd);
+EXPORT_SYMBOL(cpu_set_pmd);
+EXPORT_SYMBOL(cpu_set_pte);
+#else
+EXPORT_SYMBOL(processor);
+#endif
diff -urN linux-2.4.29/arch/armnommu/mm/small_page.c linux-2.4.29-uc1/arch/armnommu/mm/small_page.c
--- linux-2.4.29/arch/armnommu/mm/small_page.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/mm/small_page.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,213 @@
+/*
+ *  linux/arch/arm/mm/small_page.c
+ *
+ *  Copyright (C) 1996  Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Changelog:
+ *   26/01/1996	RMK	Cleaned up various areas to make little more generic
+ *   07/02/1999	RMK	Support added for 16K and 32K page sizes
+ *			containing 8K blocks
+ */
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/smp.h>
+
+#include <asm/bitops.h>
+#include <asm/pgtable.h>
+
+#define PEDANTIC
+
+/*
+ * Requirement:
+ *  We need to be able to allocate naturally aligned memory of finer
+ *  granularity than the page size.  This is typically used for the
+ *  second level page tables on 32-bit ARMs.
+ *
+ * Theory:
+ *  We "misuse" the Linux memory management system.  We use alloc_page
+ *  to allocate a page and then mark it as reserved.  The Linux memory
+ *  management system will then ignore the "offset", "next_hash" and
+ *  "pprev_hash" entries in the mem_map for this page.
+ *
+ *  We then use a bitstring in the "offset" field to mark which segments
+ *  of the page are in use, and manipulate this as required during the
+ *  allocation and freeing of these small pages.
+ *
+ *  We also maintain a queue of pages being used for this purpose using
+ *  the "next_hash" and "pprev_hash" entries of mem_map;
+ */
+
+struct order {
+	struct page *queue;
+	unsigned int mask;		/* (1 << shift) - 1		*/
+	unsigned int shift;		/* (1 << shift) size of page	*/
+	unsigned int block_mask;	/* nr_blocks - 1		*/
+	unsigned int all_used;		/* (1 << nr_blocks) - 1		*/
+};
+
+
+static struct order orders[] = {
+#if PAGE_SIZE == 4096
+	{ NULL, 2047, 11,  1, 0x00000003 }
+#elif PAGE_SIZE == 32768
+	{ NULL, 2047, 11, 15, 0x0000ffff },
+	{ NULL, 8191, 13,  3, 0x0000000f }
+#else
+#error unsupported page size
+#endif
+};
+
+#define USED_MAP(pg)			((pg)->index)
+#define TEST_AND_CLEAR_USED(pg,off)	(test_and_clear_bit(off, &USED_MAP(pg)))
+#define SET_USED(pg,off)		(set_bit(off, &USED_MAP(pg)))
+
+static spinlock_t small_page_lock = SPIN_LOCK_UNLOCKED;
+
+static void add_page_to_queue(struct page *page, struct page **p)
+{
+#ifdef PEDANTIC
+	if (page->pprev_hash)
+		PAGE_BUG(page);
+#endif
+	page->next_hash = *p;
+	if (*p)
+		(*p)->pprev_hash = &page->next_hash;
+	*p = page;
+	page->pprev_hash = p;
+}
+
+static void remove_page_from_queue(struct page *page)
+{
+	if (page->pprev_hash) {
+		if (page->next_hash)
+			page->next_hash->pprev_hash = page->pprev_hash;
+		*page->pprev_hash = page->next_hash;
+		page->pprev_hash = NULL;
+	}
+}
+
+static unsigned long __get_small_page(int priority, struct order *order)
+{
+	unsigned long flags;
+	struct page *page;
+	int offset;
+
+	if (!order->queue)
+		goto need_new_page;
+
+	spin_lock_irqsave(&small_page_lock, flags);
+	page = order->queue;
+again:
+#ifdef PEDANTIC
+	if (USED_MAP(page) & ~order->all_used)
+		PAGE_BUG(page);
+#endif
+	offset = ffz(USED_MAP(page));
+	SET_USED(page, offset);
+	if (USED_MAP(page) == order->all_used)
+		remove_page_from_queue(page);
+	spin_unlock_irqrestore(&small_page_lock, flags);
+
+	return (unsigned long) page_address(page) + (offset << order->shift);
+
+need_new_page:
+	page = alloc_page(priority);
+
+	spin_lock_irqsave(&small_page_lock, flags);
+	if (!order->queue) {
+		if (!page)
+			goto no_page;
+		SetPageReserved(page);
+		USED_MAP(page) = 0;
+		cli();
+		add_page_to_queue(page, &order->queue);
+	} else {
+		__free_page(page);
+		cli();
+		page = order->queue;
+	}
+	goto again;
+
+no_page:
+	spin_unlock_irqrestore(&small_page_lock, flags);
+	return 0;
+}
+
+static void __free_small_page(unsigned long spage, struct order *order)
+{
+	unsigned long flags;
+	struct page *page;
+
+	page = virt_to_page(spage);
+	if (VALID_PAGE(page)) {
+
+		/*
+		 * The container-page must be marked Reserved
+		 */
+		if (!PageReserved(page) || spage & order->mask)
+			goto non_small;
+
+#ifdef PEDANTIC
+		if (USED_MAP(page) & ~order->all_used)
+			PAGE_BUG(page);
+#endif
+
+		spage = spage >> order->shift;
+		spage &= order->block_mask;
+
+		/*
+		 * the following must be atomic wrt get_page
+		 */
+		spin_lock_irqsave(&small_page_lock, flags);
+
+		if (USED_MAP(page) == order->all_used)
+			add_page_to_queue(page, &order->queue);
+
+		if (!TEST_AND_CLEAR_USED(page, spage))
+			goto already_free;
+
+		if (USED_MAP(page) == 0)
+			goto free_page;
+
+		spin_unlock_irqrestore(&small_page_lock, flags);
+	}
+	return;
+
+free_page:
+	/*
+	 * unlink the page from the small page queue and free it
+	 */
+	remove_page_from_queue(page);
+	spin_unlock_irqrestore(&small_page_lock, flags);
+	ClearPageReserved(page);
+	__free_page(page);
+	return;
+
+non_small:
+	printk("Trying to free non-small page from %p\n", __builtin_return_address(0));
+	return;
+already_free:
+	printk("Trying to free free small page from %p\n", __builtin_return_address(0));
+}
+
+unsigned long get_page_8k(int priority)
+{
+	return __get_small_page(priority, orders+1);
+}
+
+void free_page_8k(unsigned long spage)
+{
+	__free_small_page(spage, orders+1);
+}
diff -urN linux-2.4.29/arch/armnommu/nwfpe/ARM-gcc.h linux-2.4.29-uc1/arch/armnommu/nwfpe/ARM-gcc.h
--- linux-2.4.29/arch/armnommu/nwfpe/ARM-gcc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/ARM-gcc.h	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,132 @@
+
+/*
+-------------------------------------------------------------------------------
+One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined.
+-------------------------------------------------------------------------------
+*/
+#ifdef __ARMEB__
+#define BIGENDIAN
+#else
+#define LITTLEENDIAN
+#endif
+
+/*
+-------------------------------------------------------------------------------
+The macro `BITS64' can be defined to indicate that 64-bit integer types are
+supported by the compiler.
+-------------------------------------------------------------------------------
+*/
+#define BITS64
+
+/*
+-------------------------------------------------------------------------------
+Each of the following `typedef's defines the most convenient type that holds
+integers of at least as many bits as specified.  For example, `uint8' should
+be the most convenient type that can hold unsigned integers of as many as
+8 bits.  The `flag' type must be able to hold either a 0 or 1.  For most
+implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
+to the same as `int'.
+-------------------------------------------------------------------------------
+*/
+typedef char flag;
+typedef unsigned char uint8;
+typedef signed char int8;
+typedef int uint16;
+typedef int int16;
+typedef unsigned int uint32;
+typedef signed int int32;
+#ifdef BITS64
+typedef unsigned long long int bits64;
+typedef signed long long int sbits64;
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Each of the following `typedef's defines a type that holds integers
+of _exactly_ the number of bits specified.  For instance, for most
+implementation of C, `bits16' and `sbits16' should be `typedef'ed to
+`unsigned short int' and `signed short int' (or `short int'), respectively.
+-------------------------------------------------------------------------------
+*/
+typedef unsigned char bits8;
+typedef signed char sbits8;
+typedef unsigned short int bits16;
+typedef signed short int sbits16;
+typedef unsigned int bits32;
+typedef signed int sbits32;
+#ifdef BITS64
+typedef unsigned long long int uint64;
+typedef signed long long int int64;
+#endif
+
+#ifdef BITS64
+/*
+-------------------------------------------------------------------------------
+The `LIT64' macro takes as its argument a textual integer literal and if
+necessary ``marks'' the literal as having a 64-bit integer type.  For
+example, the Gnu C Compiler (`gcc') requires that 64-bit literals be
+appended with the letters `LL' standing for `long long', which is `gcc's
+name for the 64-bit integer type.  Some compilers may allow `LIT64' to be
+defined as the identity macro:  `#define LIT64( a ) a'.
+-------------------------------------------------------------------------------
+*/
+#define LIT64( a ) a##LL
+#endif
+
+/*
+-------------------------------------------------------------------------------
+The macro `INLINE' can be used before functions that should be inlined.  If
+a compiler does not support explicit inlining, this macro should be defined
+to be `static'.
+-------------------------------------------------------------------------------
+*/
+#define INLINE extern __inline__
+
+
+/* For use as a GCC soft-float library we need some special function names. */
+
+#ifdef __LIBFLOAT__
+
+/* Some 32-bit ops can be mapped straight across by just changing the name. */
+#define float32_add			__addsf3
+#define float32_sub			__subsf3
+#define float32_mul			__mulsf3
+#define float32_div			__divsf3
+#define int32_to_float32		__floatsisf
+#define float32_to_int32_round_to_zero	__fixsfsi
+#define float32_to_uint32_round_to_zero	__fixunssfsi
+
+/* These ones go through the glue code.  To avoid namespace pollution
+   we rename the internal functions too.  */
+#define float32_eq			___float32_eq
+#define float32_le			___float32_le
+#define float32_lt			___float32_lt
+
+/* All the 64-bit ops have to go through the glue, so we pull the same
+   trick.  */
+#define float64_add			___float64_add
+#define float64_sub			___float64_sub
+#define float64_mul			___float64_mul
+#define float64_div			___float64_div
+#define int32_to_float64		___int32_to_float64
+#define float64_to_int32_round_to_zero	___float64_to_int32_round_to_zero
+#define float64_to_uint32_round_to_zero	___float64_to_uint32_round_to_zero
+#define float64_to_float32		___float64_to_float32
+#define float32_to_float64		___float32_to_float64
+#define float64_eq			___float64_eq
+#define float64_le			___float64_le
+#define float64_lt			___float64_lt
+
+#if 0
+#define float64_add			__adddf3
+#define float64_sub			__subdf3
+#define float64_mul			__muldf3
+#define float64_div			__divdf3
+#define int32_to_float64		__floatsidf
+#define float64_to_int32_round_to_zero	__fixdfsi
+#define float64_to_uint32_round_to_zero	__fixunsdfsi
+#define float64_to_float32		__truncdfsf2
+#define float32_to_float64		__extendsfdf2
+#endif
+
+#endif
diff -urN linux-2.4.29/arch/armnommu/nwfpe/config.h linux-2.4.29-uc1/arch/armnommu/nwfpe/config.h
--- linux-2.4.29/arch/armnommu/nwfpe/config.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/config.h	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,31 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Rebel.com, 1998-1999
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#if 1
+#define C_SYMBOL_NAME(foo)	foo
+#else
+#define C_SYMBOL_NAME(foo)	_##foo
+#endif
+
+#endif
diff -urN linux-2.4.29/arch/armnommu/nwfpe/double_cpdo.c linux-2.4.29-uc1/arch/armnommu/nwfpe/double_cpdo.c
--- linux-2.4.29/arch/armnommu/nwfpe/double_cpdo.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/double_cpdo.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,292 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Rebel.com, 1998-1999
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "softfloat.h"
+#include "fpopcode.h"
+#include "fpa11.h"
+
+extern FPA11 *fpa11;
+
+float64 getDoubleConstant(unsigned int);
+
+float64 float64_exp(float64 Fm);
+float64 float64_ln(float64 Fm);
+float64 float64_sin(float64 rFm);
+float64 float64_cos(float64 rFm);
+float64 float64_arcsin(float64 rFm);
+float64 float64_arctan(float64 rFm);
+float64 float64_log(float64 rFm);
+float64 float64_tan(float64 rFm);
+float64 float64_arccos(float64 rFm);
+float64 float64_pow(float64 rFn,float64 rFm);
+float64 float64_pol(float64 rFn,float64 rFm);
+
+unsigned int DoubleCPDO(const unsigned int opcode)
+{
+   float64 rFm, rFn;
+   unsigned int Fd, Fm, Fn, nRc = 1;
+
+   //printk("DoubleCPDO(0x%08x)\n",opcode);
+   
+   Fm = getFm(opcode);
+   if (CONSTANT_FM(opcode))
+   {
+     rFm = getDoubleConstant(Fm);
+   }
+   else
+   {  
+     switch (fpa11->fType[Fm])
+     {
+        case typeSingle:
+          rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle);
+        break;
+
+        case typeDouble:
+          rFm = fpa11->fpreg[Fm].fDouble;
+          break;
+
+        case typeExtended:
+            // !! patb
+	    //printk("not implemented! why not?\n");
+            //!! ScottB
+            // should never get here, if extended involved
+            // then other operand should be promoted then
+            // ExtendedCPDO called.
+            break;
+
+        default: return 0;
+     }
+   }
+
+   if (!MONADIC_INSTRUCTION(opcode))
+   {
+      Fn = getFn(opcode);
+      switch (fpa11->fType[Fn])
+      {
+        case typeSingle:
+          rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle);
+        break;
+
+        case typeDouble:
+          rFn = fpa11->fpreg[Fn].fDouble;
+        break;
+        
+        default: return 0;
+      }
+   }
+
+   Fd = getFd(opcode);
+   /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */
+   switch (opcode & MASK_ARITHMETIC_OPCODE)
+   {
+      /* dyadic opcodes */
+      case ADF_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm);
+      break;
+
+      case MUF_CODE:
+      case FML_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm);
+      break;
+
+      case SUF_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm);
+      break;
+
+      case RSF_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn);
+      break;
+
+      case DVF_CODE:
+      case FDV_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm);
+      break;
+
+      case RDF_CODE:
+      case FRD_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn);
+      break;
+
+#if 0
+      case POW_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm);
+      break;
+
+      case RPW_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn);
+      break;
+#endif
+
+      case RMF_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm);
+      break;
+
+#if 0
+      case POL_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm);
+      break;
+#endif
+
+      /* monadic opcodes */
+      case MVF_CODE:
+         fpa11->fpreg[Fd].fDouble = rFm;
+      break;
+
+      case MNF_CODE:
+      {
+         unsigned int *p = (unsigned int*)&rFm;
+         p[1] ^= 0x80000000;
+         fpa11->fpreg[Fd].fDouble = rFm;
+      }
+      break;
+
+      case ABS_CODE:
+      {
+         unsigned int *p = (unsigned int*)&rFm;
+         p[1] &= 0x7fffffff;
+         fpa11->fpreg[Fd].fDouble = rFm;
+      }
+      break;
+
+      case RND_CODE:
+      case URD_CODE:
+         fpa11->fpreg[Fd].fDouble = 
+             int32_to_float64(float64_to_int32(rFm));
+      break;
+
+      case SQT_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm);
+      break;
+
+#if 0
+      case LOG_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_log(rFm);
+      break;
+
+      case LGN_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_ln(rFm);
+      break;
+
+      case EXP_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_exp(rFm);
+      break;
+
+      case SIN_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_sin(rFm);
+      break;
+
+      case COS_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_cos(rFm);
+      break;
+
+      case TAN_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_tan(rFm);
+      break;
+
+      case ASN_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm);
+      break;
+
+      case ACS_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_arccos(rFm);
+      break;
+
+      case ATN_CODE:
+         fpa11->fpreg[Fd].fDouble = float64_arctan(rFm);
+      break;
+#endif
+
+      case NRM_CODE:
+      break;
+      
+      default:
+      {
+        nRc = 0;
+      }
+   }
+
+   if (0 != nRc) fpa11->fType[Fd] = typeDouble;
+   return nRc;
+}
+
+#if 0
+float64 float64_exp(float64 rFm)
+{
+  return rFm;
+//series
+}
+
+float64 float64_ln(float64 rFm)
+{
+  return rFm;
+//series
+}
+
+float64 float64_sin(float64 rFm)
+{
+  return rFm;
+//series
+}
+
+float64 float64_cos(float64 rFm)
+{
+   return rFm;
+   //series
+}
+
+#if 0
+float64 float64_arcsin(float64 rFm)
+{
+//series
+}
+
+float64 float64_arctan(float64 rFm)
+{
+  //series
+}
+#endif
+
+float64 float64_log(float64 rFm)
+{
+  return float64_div(float64_ln(rFm),getDoubleConstant(7));
+}
+
+float64 float64_tan(float64 rFm)
+{
+  return float64_div(float64_sin(rFm),float64_cos(rFm));
+}
+
+float64 float64_arccos(float64 rFm)
+{
+return rFm;
+   //return float64_sub(halfPi,float64_arcsin(rFm));
+}
+
+float64 float64_pow(float64 rFn,float64 rFm)
+{
+  return float64_exp(float64_mul(rFm,float64_ln(rFn))); 
+}
+
+float64 float64_pol(float64 rFn,float64 rFm)
+{
+  return float64_arctan(float64_div(rFn,rFm)); 
+}
+#endif
diff -urN linux-2.4.29/arch/armnommu/nwfpe/entry26.S linux-2.4.29-uc1/arch/armnommu/nwfpe/entry26.S
--- linux-2.4.29/arch/armnommu/nwfpe/entry26.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/entry26.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,112 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Corel Computer Corporation, 1998
+    (c) Philip Blundell 1998-1999
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <asm/constants.h>
+
+/* This is the kernel's entry point into the floating point emulator.
+It is called from the kernel with code similar to this:
+
+	mov	fp, #0
+	teqp	pc, #I_BIT | MODE_SVC
+	ldr	r4, .LC2
+	ldr	pc, [r4]		@ Call FP module USR entry point
+
+The kernel expects the emulator to return via one of two possible
+points of return it passes to the emulator.  The emulator, if
+successful in its emulation, jumps to ret_from_exception and the
+kernel takes care of returning control from the trap to the user code.
+If the emulator is unable to emulate the instruction, it returns to
+fpundefinstr and the kernel halts the user program with a core dump.
+
+This routine does four things:
+
+1) It saves SP into a variable called userRegisters.  The kernel has
+created a struct pt_regs on the stack and saved the user registers
+into it.  See /usr/include/asm/proc/ptrace.h for details.  The
+emulator code uses userRegisters as the base of an array of words from
+which the contents of the registers can be extracted.
+
+2) It locates the FP emulator work area within the TSS structure and
+points `fpa11' to it.
+
+3) It calls EmulateAll to emulate a floating point instruction.
+EmulateAll returns 1 if the emulation was successful, or 0 if not.
+
+4) If an instruction has been emulated successfully, it looks ahead at
+the next instruction.  If it is a floating point instruction, it
+executes the instruction, without returning to user space.  In this
+way it repeatedly looks ahead and executes floating point instructions
+until it encounters a non floating point instruction, at which time it
+returns via _fpreturn.
+
+This is done to reduce the effect of the trap overhead on each
+floating point instructions.  GCC attempts to group floating point
+instructions to allow the emulator to spread the cost of the trap over
+several floating point instructions.  */
+
+	.globl	nwfpe_enter
+nwfpe_enter:
+	ldr	r4, =userRegisters
+	str	sp, [r4]		@ save pointer to user regs
+
+	mov	r10, sp, lsr #13	@ find workspace
+	mov	r10, r10, lsl #13
+	add	r10, r10, #TSS_FPESAVE
+
+	ldr	r4, =fpa11
+	str	r10, [r4]		@ store pointer to our state
+	mov	r4, sp			@ use r4 for local pointer
+
+	ldr	r5, [r4, #60]		@ get contents of PC
+	bic	r5, r5, #0xfc000003
+	ldr	r0, [r5, #-4]		@ get actual instruction into r0
+	bl	EmulateAll		@ emulate the instruction
+1:	cmp	r0, #0			@ was emulation successful
+	beq	fpundefinstr		@ no, return failure
+
+next:
+	ldrt	r6, [r5], #4		@ get the next instruction and
+					@ increment PC
+
+	and	r2, r6, #0x0F000000	@ test for FP insns
+	teq	r2, #0x0C000000
+	teqne	r2, #0x0D000000
+	teqne	r2, #0x0E000000
+	bne	ret_from_exception	@ return ok if not a fp insn
+
+	ldr	r9, [r4, #60]		@ get new condition codes
+	and	r9, r9, #0xfc000003
+	orr	r7, r5, r9
+	str	r7, [r4, #60]		@ update PC copy in regs
+
+	mov	r0, r6			@ save a copy
+	mov	r1, r9			@ fetch the condition codes
+	bl	checkCondition		@ check the condition
+	cmp	r0, #0			@ r0 = 0 ==> condition failed
+
+	@ if condition code failed to match, next insn
+	beq	next			@ get the next instruction;
+	    
+	mov	r0, r6			@ prepare for EmulateAll()
+	adr	lr, 1b
+	orr	lr, lr, #3
+	b	EmulateAll		@ if r0 != 0, goto EmulateAll
diff -urN linux-2.4.29/arch/armnommu/nwfpe/entry.S linux-2.4.29-uc1/arch/armnommu/nwfpe/entry.S
--- linux-2.4.29/arch/armnommu/nwfpe/entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/entry.S	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,129 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Corel Computer Corporation, 1998
+    (c) Philip Blundell 1998-1999
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* This is the kernel's entry point into the floating point emulator.
+It is called from the kernel with code similar to this:
+
+	adrsvc	al, r9, ret_from_exception	@ r9  = normal FP return
+	adrsvc	al, lr, fpundefinstr		@ lr  = undefined instr return
+
+	get_current_task r10
+	mov	r8, #1
+	strb	r8, [r10, #TSK_USED_MATH]	@ set current->used_math
+	add	r10, r10, #TSS_FPESAVE		@ r10 = workspace
+	ldr	r4, .LC2
+	ldr	pc, [r4]			@ Call FP emulator entry point
+
+The kernel expects the emulator to return via one of two possible
+points of return it passes to the emulator.  The emulator, if
+successful in its emulation, jumps to ret_from_exception (passed in
+r9) and the kernel takes care of returning control from the trap to
+the user code.  If the emulator is unable to emulate the instruction,
+it returns via _fpundefinstr (passed via lr) and the kernel halts the
+user program with a core dump.
+
+On entry to the emulator r10 points to an area of private FP workspace
+reserved in the thread structure for this process.  This is where the
+emulator saves its registers across calls.  The first word of this area
+is used as a flag to detect the first time a process uses floating point,
+so that the emulator startup cost can be avoided for tasks that don't
+want it.
+
+This routine does three things:
+
+1) It saves SP into a variable called userRegisters.  The kernel has
+created a struct pt_regs on the stack and saved the user registers
+into it.  See /usr/include/asm/proc/ptrace.h for details.  The
+emulator code uses userRegisters as the base of an array of words from
+which the contents of the registers can be extracted.
+
+2) It calls EmulateAll to emulate a floating point instruction.
+EmulateAll returns 1 if the emulation was successful, or 0 if not.
+
+3) If an instruction has been emulated successfully, it looks ahead at
+the next instruction.  If it is a floating point instruction, it
+executes the instruction, without returning to user space.  In this
+way it repeatedly looks ahead and executes floating point instructions
+until it encounters a non floating point instruction, at which time it
+returns via _fpreturn.
+
+This is done to reduce the effect of the trap overhead on each
+floating point instructions.  GCC attempts to group floating point
+instructions to allow the emulator to spread the cost of the trap over
+several floating point instructions.  */
+
+	.globl	nwfpe_enter
+nwfpe_enter:
+	/* ?? Could put userRegisters and fpa11 into fixed regs during
+	   emulation.  This would reduce load/store overhead at the expense
+	   of stealing two regs from the register allocator.  Not sure if
+	   it's worth it.  */
+	ldr r4, =userRegisters
+        str sp, [r4]			@ save pointer to user regs
+	ldr r4, =fpa11
+	str r10, [r4]			@ store pointer to our state
+        mov r4, sp			@ use r4 for local pointer
+        mov r10, lr			@ save the failure-return addresses
+
+        ldr r5, [r4, #60]	 	@ get contents of PC;
+	sub r8, r5, #4
+.Lx2:	ldrt r0, [r8], #0		@ get actual instruction into r0
+emulate:
+	bl EmulateAll			@ emulate the instruction
+   	cmp r0, #0			@ was emulation successful
+        moveq pc, r10			@ no, return failure
+
+next:
+.Lx1:	ldrt r6, [r5], #4		@ get the next instruction and
+					@ increment PC
+
+	and   r2, r6, #0x0F000000	@ test for FP insns
+        teq   r2, #0x0C000000
+        teqne r2, #0x0D000000
+        teqne r2, #0x0E000000
+        movne pc, r9			@ return ok if not a fp insn
+
+        str r5, [r4, #60]		@ update PC copy in regs
+
+        mov r0, r6			@ save a copy
+        ldr r1, [r4, #64]		@ fetch the condition codes
+   	bl  checkCondition		@ check the condition
+   	cmp r0, #0			@ r0 = 0 ==> condition failed
+
+        @ if condition code failed to match, next insn
+   	beq next			@ get the next instruction;
+   	    
+        mov r0, r6			@ prepare for EmulateAll()
+   	b emulate			@ if r0 != 0, goto EmulateAll
+
+	@ We need to be prepared for the instruction at .Lx1 or .Lx2
+	@ to fault.
+	.section .fixup,"ax"
+	.align
+.Lfix:	mov	pc, r9
+	.previous
+
+	.section __ex_table,"a"
+	.align 3
+	.long	.Lx2, .Lfix
+	.long	.Lx1, .Lfix
+	.previous
diff -urN linux-2.4.29/arch/armnommu/nwfpe/extended_cpdo.c linux-2.4.29-uc1/arch/armnommu/nwfpe/extended_cpdo.c
--- linux-2.4.29/arch/armnommu/nwfpe/extended_cpdo.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/extended_cpdo.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,275 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Rebel.com, 1998-1999
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "softfloat.h"
+#include "fpopcode.h"
+#include "fpa11.h"
+
+floatx80 getExtendedConstant(unsigned int);
+
+floatx80 floatx80_exp(floatx80 Fm);
+floatx80 floatx80_ln(floatx80 Fm);
+floatx80 floatx80_sin(floatx80 rFm);
+floatx80 floatx80_cos(floatx80 rFm);
+floatx80 floatx80_arcsin(floatx80 rFm);
+floatx80 floatx80_arctan(floatx80 rFm);
+floatx80 floatx80_log(floatx80 rFm);
+floatx80 floatx80_tan(floatx80 rFm);
+floatx80 floatx80_arccos(floatx80 rFm);
+floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm);
+floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm);
+
+unsigned int ExtendedCPDO(const unsigned int opcode)
+{
+   floatx80 rFm, rFn;
+   unsigned int Fd, Fm, Fn, nRc = 1;
+
+   //printk("ExtendedCPDO(0x%08x)\n",opcode);
+   
+   Fm = getFm(opcode);
+   if (CONSTANT_FM(opcode))
+   {
+     rFm = getExtendedConstant(Fm);
+   }
+   else
+   {  
+     switch (fpa11->fType[Fm])
+     {
+        case typeSingle:
+          rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
+        break;
+
+        case typeDouble:
+          rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
+        break;
+        
+        case typeExtended:
+          rFm = fpa11->fpreg[Fm].fExtended;
+        break;
+        
+        default: return 0;
+     }
+   }
+   
+   if (!MONADIC_INSTRUCTION(opcode))
+   {
+      Fn = getFn(opcode);
+      switch (fpa11->fType[Fn])
+      {
+        case typeSingle:
+          rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
+        break;
+
+        case typeDouble:
+          rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
+        break;
+        
+        case typeExtended:
+          rFn = fpa11->fpreg[Fn].fExtended;
+        break;
+        
+        default: return 0;
+      }
+   }
+
+   Fd = getFd(opcode);
+   switch (opcode & MASK_ARITHMETIC_OPCODE)
+   {
+      /* dyadic opcodes */
+      case ADF_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_add(rFn,rFm);
+      break;
+
+      case MUF_CODE:
+      case FML_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_mul(rFn,rFm);
+      break;
+
+      case SUF_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_sub(rFn,rFm);
+      break;
+
+      case RSF_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_sub(rFm,rFn);
+      break;
+
+      case DVF_CODE:
+      case FDV_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_div(rFn,rFm);
+      break;
+
+      case RDF_CODE:
+      case FRD_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_div(rFm,rFn);
+      break;
+
+#if 0
+      case POW_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_pow(rFn,rFm);
+      break;
+
+      case RPW_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_pow(rFm,rFn);
+      break;
+#endif
+
+      case RMF_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_rem(rFn,rFm);
+      break;
+
+#if 0
+      case POL_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_pol(rFn,rFm);
+      break;
+#endif
+
+      /* monadic opcodes */
+      case MVF_CODE:
+         fpa11->fpreg[Fd].fExtended = rFm;
+      break;
+
+      case MNF_CODE:
+         rFm.high ^= 0x8000;
+         fpa11->fpreg[Fd].fExtended = rFm;
+      break;
+
+      case ABS_CODE:
+         rFm.high &= 0x7fff;
+         fpa11->fpreg[Fd].fExtended = rFm;
+      break;
+
+      case RND_CODE:
+      case URD_CODE:
+         fpa11->fpreg[Fd].fExtended = 
+             int32_to_floatx80(floatx80_to_int32(rFm));
+      break;
+
+      case SQT_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_sqrt(rFm);
+      break;
+
+#if 0
+      case LOG_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_log(rFm);
+      break;
+
+      case LGN_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_ln(rFm);
+      break;
+
+      case EXP_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_exp(rFm);
+      break;
+
+      case SIN_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_sin(rFm);
+      break;
+
+      case COS_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_cos(rFm);
+      break;
+
+      case TAN_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_tan(rFm);
+      break;
+
+      case ASN_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_arcsin(rFm);
+      break;
+
+      case ACS_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_arccos(rFm);
+      break;
+
+      case ATN_CODE:
+         fpa11->fpreg[Fd].fExtended = floatx80_arctan(rFm);
+      break;
+#endif
+
+      case NRM_CODE:
+      break;
+      
+      default:
+      {
+        nRc = 0;
+      }
+   }
+   
+   if (0 != nRc) fpa11->fType[Fd] = typeExtended;
+   return nRc;
+}
+
+#if 0
+floatx80 floatx80_exp(floatx80 Fm)
+{
+//series
+}
+
+floatx80 floatx80_ln(floatx80 Fm)
+{
+//series
+}
+
+floatx80 floatx80_sin(floatx80 rFm)
+{
+//series
+}
+
+floatx80 floatx80_cos(floatx80 rFm)
+{
+//series
+}
+
+floatx80 floatx80_arcsin(floatx80 rFm)
+{
+//series
+}
+
+floatx80 floatx80_arctan(floatx80 rFm)
+{
+  //series
+}
+
+floatx80 floatx80_log(floatx80 rFm)
+{
+  return floatx80_div(floatx80_ln(rFm),getExtendedConstant(7));
+}
+
+floatx80 floatx80_tan(floatx80 rFm)
+{
+  return floatx80_div(floatx80_sin(rFm),floatx80_cos(rFm));
+}
+
+floatx80 floatx80_arccos(floatx80 rFm)
+{
+   //return floatx80_sub(halfPi,floatx80_arcsin(rFm));
+}
+
+floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm)
+{
+  return floatx80_exp(floatx80_mul(rFm,floatx80_ln(rFn))); 
+}
+
+floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm)
+{
+  return floatx80_arctan(floatx80_div(rFn,rFm)); 
+}
+#endif
diff -urN linux-2.4.29/arch/armnommu/nwfpe/fpa11.c linux-2.4.29-uc1/arch/armnommu/nwfpe/fpa11.c
--- linux-2.4.29/arch/armnommu/nwfpe/fpa11.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/fpa11.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,212 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Rebel.com, 1998-1999
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <asm/system.h>
+
+#include "fpa11.h"
+#include "fpopcode.h"
+
+#include "fpmodule.h"
+#include "fpmodule.inl"
+
+/* forward declarations */
+unsigned int EmulateCPDO(const unsigned int);
+unsigned int EmulateCPDT(const unsigned int);
+unsigned int EmulateCPRT(const unsigned int);
+
+/* Emulator registers */
+FPA11 *fpa11;
+
+/* Reset the FPA11 chip.  Called to initialize and reset the emulator. */
+void resetFPA11(void)
+{
+  int i;
+
+  /* initialize the register type array */
+  for (i=0;i<=7;i++)
+  {
+    fpa11->fType[i] = typeNone;
+  }
+  
+  /* FPSR: set system id to FP_EMULATOR, clear all other bits */
+  fpa11->fpsr = FP_EMULATOR;
+  
+  /* FPCR: set SB, AB and DA bits, clear all others */
+#if MAINTAIN_FPCR
+  fpa11->fpcr = MASK_RESET;
+#endif
+}
+
+void SetRoundingMode(const unsigned int opcode)
+{
+#if MAINTAIN_FPCR
+   fpa11->fpcr &= ~MASK_ROUNDING_MODE;
+#endif   
+   switch (opcode & MASK_ROUNDING_MODE)
+   {
+      default:
+      case ROUND_TO_NEAREST:
+         float_rounding_mode = float_round_nearest_even;
+#if MAINTAIN_FPCR         
+         fpa11->fpcr |= ROUND_TO_NEAREST;
+#endif         
+      break;
+      
+      case ROUND_TO_PLUS_INFINITY:
+         float_rounding_mode = float_round_up;
+#if MAINTAIN_FPCR         
+         fpa11->fpcr |= ROUND_TO_PLUS_INFINITY;
+#endif         
+      break;
+      
+      case ROUND_TO_MINUS_INFINITY:
+         float_rounding_mode = float_round_down;
+#if MAINTAIN_FPCR         
+         fpa11->fpcr |= ROUND_TO_MINUS_INFINITY;
+#endif         
+      break;
+      
+      case ROUND_TO_ZERO:
+         float_rounding_mode = float_round_to_zero;
+#if MAINTAIN_FPCR         
+         fpa11->fpcr |= ROUND_TO_ZERO;
+#endif         
+      break;
+  }
+}
+
+void SetRoundingPrecision(const unsigned int opcode)
+{
+#if MAINTAIN_FPCR
+   fpa11->fpcr &= ~MASK_ROUNDING_PRECISION;
+#endif   
+   switch (opcode & MASK_ROUNDING_PRECISION)
+   {
+      case ROUND_SINGLE:
+         floatx80_rounding_precision = 32;
+#if MAINTAIN_FPCR         
+         fpa11->fpcr |= ROUND_SINGLE;
+#endif         
+      break;
+      
+      case ROUND_DOUBLE:
+         floatx80_rounding_precision = 64;
+#if MAINTAIN_FPCR         
+         fpa11->fpcr |= ROUND_DOUBLE;
+#endif         
+      break;
+      
+      case ROUND_EXTENDED:
+         floatx80_rounding_precision = 80;
+#if MAINTAIN_FPCR         
+         fpa11->fpcr |= ROUND_EXTENDED;
+#endif         
+      break;
+      
+      default: floatx80_rounding_precision = 80;
+  }
+}
+
+/* Emulate the instruction in the opcode. */
+unsigned int EmulateAll(unsigned int opcode)
+{
+  unsigned int nRc = 0;
+  unsigned long flags;
+
+  save_flags(flags); sti();
+
+  if (fpa11->initflag == 0)		/* good place for __builtin_expect */
+  {
+    resetFPA11();
+    SetRoundingMode(ROUND_TO_NEAREST);
+    SetRoundingPrecision(ROUND_EXTENDED);
+    fpa11->initflag = 1;
+  }
+
+  if (TEST_OPCODE(opcode,MASK_CPRT))
+  {
+    /* Emulate conversion opcodes. */
+    /* Emulate register transfer opcodes. */
+    /* Emulate comparison opcodes. */
+    nRc = EmulateCPRT(opcode);
+  }
+  else if (TEST_OPCODE(opcode,MASK_CPDO))
+  {
+    /* Emulate monadic arithmetic opcodes. */
+    /* Emulate dyadic arithmetic opcodes. */
+    nRc = EmulateCPDO(opcode);
+  }
+  else if (TEST_OPCODE(opcode,MASK_CPDT))
+  {
+    /* Emulate load/store opcodes. */
+    /* Emulate load/store multiple opcodes. */
+    nRc = EmulateCPDT(opcode);
+  }
+  else
+  {
+    /* Invalid instruction detected.  Return FALSE. */
+    nRc = 0;
+  }
+
+  restore_flags(flags);
+
+  return(nRc);
+}
+
+#if 0
+unsigned int EmulateAll1(unsigned int opcode)
+{
+  switch ((opcode >> 24) & 0xf)
+  {
+     case 0xc:
+     case 0xd:
+       if ((opcode >> 20) & 0x1)
+       {
+          switch ((opcode >> 8) & 0xf)
+          {
+             case 0x1: return PerformLDF(opcode); break;
+             case 0x2: return PerformLFM(opcode); break;
+             default: return 0;
+          }
+       }
+       else
+       {
+          switch ((opcode >> 8) & 0xf)
+          {
+             case 0x1: return PerformSTF(opcode); break;
+             case 0x2: return PerformSFM(opcode); break;
+             default: return 0;
+          }
+      }
+     break;
+     
+     case 0xe: 
+       if (opcode & 0x10)
+         return EmulateCPDO(opcode);
+       else
+         return EmulateCPRT(opcode);
+     break;
+  
+     default: return 0;
+  }
+}
+#endif
+
diff -urN linux-2.4.29/arch/armnommu/nwfpe/fpa11_cpdo.c linux-2.4.29-uc1/arch/armnommu/nwfpe/fpa11_cpdo.c
--- linux-2.4.29/arch/armnommu/nwfpe/fpa11_cpdo.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/fpa11_cpdo.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,116 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Rebel.com, 1998-1999
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "fpa11.h"
+#include "fpopcode.h"
+
+unsigned int SingleCPDO(const unsigned int opcode);
+unsigned int DoubleCPDO(const unsigned int opcode);
+unsigned int ExtendedCPDO(const unsigned int opcode);
+
+unsigned int EmulateCPDO(const unsigned int opcode)
+{
+   unsigned int Fd, nType, nDest, nRc = 1;
+   
+   //printk("EmulateCPDO(0x%08x)\n",opcode);
+
+   /* Get the destination size.  If not valid let Linux perform
+      an invalid instruction trap. */
+   nDest = getDestinationSize(opcode);
+   if (typeNone == nDest) return 0;
+   
+   SetRoundingMode(opcode);
+     
+   /* Compare the size of the operands in Fn and Fm.
+      Choose the largest size and perform operations in that size,
+      in order to make use of all the precision of the operands. 
+      If Fm is a constant, we just grab a constant of a size 
+      matching the size of the operand in Fn. */
+   if (MONADIC_INSTRUCTION(opcode))
+     nType = nDest;
+   else
+     nType = fpa11->fType[getFn(opcode)];
+   
+   if (!CONSTANT_FM(opcode))
+   {
+     register unsigned int Fm = getFm(opcode);
+     if (nType < fpa11->fType[Fm])
+     {
+        nType = fpa11->fType[Fm];
+     }
+   }
+
+   switch (nType)
+   {
+      case typeSingle   : nRc = SingleCPDO(opcode);   break;
+      case typeDouble   : nRc = DoubleCPDO(opcode);   break;
+      case typeExtended : nRc = ExtendedCPDO(opcode); break;
+      default           : nRc = 0;
+   }
+
+   /* If the operation succeeded, check to see if the result in the
+      destination register is the correct size.  If not force it
+      to be. */
+   Fd = getFd(opcode);
+   nType = fpa11->fType[Fd];
+   if ((0 != nRc) && (nDest != nType))
+   {
+     switch (nDest)
+     {
+       case typeSingle:
+       {
+         if (typeDouble == nType)
+           fpa11->fpreg[Fd].fSingle = 
+              float64_to_float32(fpa11->fpreg[Fd].fDouble);
+         else
+           fpa11->fpreg[Fd].fSingle = 
+              floatx80_to_float32(fpa11->fpreg[Fd].fExtended);
+       }
+       break;
+          
+       case typeDouble:
+       {
+         if (typeSingle == nType)
+           fpa11->fpreg[Fd].fDouble = 
+              float32_to_float64(fpa11->fpreg[Fd].fSingle);
+         else
+           fpa11->fpreg[Fd].fDouble = 
+              floatx80_to_float64(fpa11->fpreg[Fd].fExtended);
+       }
+       break;
+          
+       case typeExtended:
+       {
+         if (typeSingle == nType)
+           fpa11->fpreg[Fd].fExtended = 
+              float32_to_floatx80(fpa11->fpreg[Fd].fSingle);
+         else
+           fpa11->fpreg[Fd].fExtended = 
+              float64_to_floatx80(fpa11->fpreg[Fd].fDouble);
+       }
+       break;
+     }
+     
+     fpa11->fType[Fd] = nDest;
+   }
+   
+   return nRc;
+}
diff -urN linux-2.4.29/arch/armnommu/nwfpe/fpa11_cpdt.c linux-2.4.29-uc1/arch/armnommu/nwfpe/fpa11_cpdt.c
--- linux-2.4.29/arch/armnommu/nwfpe/fpa11_cpdt.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/fpa11_cpdt.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,380 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Rebel.com, 1998-1999
+    (c) Philip Blundell, 1998
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "softfloat.h"
+#include "fpopcode.h"
+#include "fpa11.h"
+#include "fpmodule.h"
+#include "fpmodule.inl"
+
+#include <asm/uaccess.h>
+
+extern __inline__
+void loadSingle(const unsigned int Fn,const unsigned int *pMem)
+{
+   fpa11->fType[Fn] = typeSingle;
+   get_user(fpa11->fpreg[Fn].fSingle, pMem);
+}
+
+extern __inline__
+void loadDouble(const unsigned int Fn,const unsigned int *pMem)
+{
+   unsigned int *p;
+   p = (unsigned int*)&fpa11->fpreg[Fn].fDouble;
+   fpa11->fType[Fn] = typeDouble;
+#ifdef __ARMEB__
+   get_user(p[0], &pMem[0]);
+   get_user(p[1], &pMem[1]); /* sign & exponent */
+#else
+   get_user(p[0], &pMem[1]);
+   get_user(p[1], &pMem[0]); /* sign & exponent */
+#endif
+}   
+
+extern __inline__
+void loadExtended(const unsigned int Fn,const unsigned int *pMem)
+{
+   unsigned int *p;
+   p = (unsigned int*)&fpa11->fpreg[Fn].fExtended;
+   fpa11->fType[Fn] = typeExtended;
+   get_user(p[0], &pMem[0]);  /* sign & exponent */
+#ifdef __ARMEB__
+   get_user(p[1], &pMem[1]);  /* ls bits */
+   get_user(p[2], &pMem[2]);  /* ms bits */
+#else
+   get_user(p[1], &pMem[2]);  /* ls bits */
+   get_user(p[2], &pMem[1]);  /* ms bits */
+#endif
+}   
+
+extern __inline__
+void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
+{
+   register unsigned int *p;
+   unsigned long x;
+
+   p = (unsigned int*)&(fpa11->fpreg[Fn]);
+   get_user(x, &pMem[0]);
+   fpa11->fType[Fn] = (x >> 14) & 0x00000003;
+   
+   switch (fpa11->fType[Fn])
+   {
+      case typeSingle:
+      case typeDouble:
+      {
+         get_user(p[0], &pMem[2]);  /* Single */
+         get_user(p[1], &pMem[1]);  /* double msw */
+         p[2] = 0;        /* empty */
+      }
+      break; 
+   
+      case typeExtended:
+      {
+#ifdef __ARMEB__
+	 get_user(p[1], &pMem[1]);
+         get_user(p[2], &pMem[2]);  /* msw */
+#else
+	 get_user(p[1], &pMem[2]);
+         get_user(p[2], &pMem[1]);  /* msw */
+#endif
+         p[0] = (x & 0x80003fff);      
+      }
+      break;
+   }
+}
+
+extern __inline__
+void storeSingle(const unsigned int Fn,unsigned int *pMem)
+{
+   float32 val;
+   register unsigned int *p = (unsigned int*)&val;
+   
+   switch (fpa11->fType[Fn])
+   {
+      case typeDouble: 
+         val = float64_to_float32(fpa11->fpreg[Fn].fDouble);
+      break;
+
+      case typeExtended: 
+         val = floatx80_to_float32(fpa11->fpreg[Fn].fExtended);
+      break;
+
+      default: val = fpa11->fpreg[Fn].fSingle;
+   }
+  
+   put_user(p[0], pMem);
+}   
+
+extern __inline__
+void storeDouble(const unsigned int Fn,unsigned int *pMem)
+{
+   float64 val;
+   register unsigned int *p = (unsigned int*)&val;
+
+   switch (fpa11->fType[Fn])
+   {
+      case typeSingle: 
+         val = float32_to_float64(fpa11->fpreg[Fn].fSingle);
+      break;
+
+      case typeExtended:
+         val = floatx80_to_float64(fpa11->fpreg[Fn].fExtended);
+      break;
+
+      default: val = fpa11->fpreg[Fn].fDouble;
+   }
+#ifdef __ARMEB__
+   put_user(p[0], &pMem[0]);	/* msw */
+   put_user(p[1], &pMem[1]);	/* lsw */
+#else
+   put_user(p[1], &pMem[0]);	/* msw */
+   put_user(p[0], &pMem[1]);	/* lsw */
+#endif
+}   
+
+extern __inline__
+void storeExtended(const unsigned int Fn,unsigned int *pMem)
+{
+   floatx80 val;
+   register unsigned int *p = (unsigned int*)&val;
+   
+   switch (fpa11->fType[Fn])
+   {
+      case typeSingle: 
+         val = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
+      break;
+
+      case typeDouble: 
+         val = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
+      break;
+
+      default: val = fpa11->fpreg[Fn].fExtended;
+   }
+   
+   put_user(p[0], &pMem[0]); /* sign & exp */
+#ifdef __ARMEB__
+   put_user(p[1], &pMem[1]);
+   put_user(p[2], &pMem[2]); /* msw */
+#else
+   put_user(p[1], &pMem[2]);
+   put_user(p[2], &pMem[1]); /* msw */
+#endif
+}   
+
+extern __inline__
+void storeMultiple(const unsigned int Fn,unsigned int *pMem)
+{
+   register unsigned int nType, *p;
+   
+   p = (unsigned int*)&(fpa11->fpreg[Fn]);
+   nType = fpa11->fType[Fn];
+   
+   switch (nType)
+   {
+      case typeSingle:
+      case typeDouble:
+      {
+	 put_user(p[0], &pMem[2]); /* single */
+	 put_user(p[1], &pMem[1]); /* double msw */
+	 put_user(nType << 14, &pMem[0]);
+      }
+      break; 
+   
+      case typeExtended:
+      {
+#ifdef __ARMEB__
+	 put_user(p[2], &pMem[2]); /* msw */
+	 put_user(p[1], &pMem[1]);
+#else
+	 put_user(p[2], &pMem[1]); /* msw */
+	 put_user(p[1], &pMem[2]);
+#endif
+	 put_user((p[0] & 0x80003fff) | (nType << 14), &pMem[0]);
+      }
+      break;
+   }
+}
+
+unsigned int PerformLDF(const unsigned int opcode)
+{
+   unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
+     write_back = WRITE_BACK(opcode);
+
+   //printk("PerformLDF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
+
+   pBase = (unsigned int*)readRegister(getRn(opcode));
+   if (REG_PC == getRn(opcode))
+   {
+     pBase += 2;
+     write_back = 0;
+   }
+
+   pFinal = pBase;
+   if (BIT_UP_SET(opcode))
+     pFinal += getOffset(opcode);
+   else
+     pFinal -= getOffset(opcode);
+
+   if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
+
+   switch (opcode & MASK_TRANSFER_LENGTH)
+   {
+      case TRANSFER_SINGLE  : loadSingle(getFd(opcode),pAddress);   break;
+      case TRANSFER_DOUBLE  : loadDouble(getFd(opcode),pAddress);   break;
+      case TRANSFER_EXTENDED: loadExtended(getFd(opcode),pAddress); break;
+      default: nRc = 0;
+   }
+   
+   if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
+   return nRc;
+}
+
+unsigned int PerformSTF(const unsigned int opcode)
+{
+   unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
+     write_back = WRITE_BACK(opcode);
+   
+   //printk("PerformSTF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
+   SetRoundingMode(ROUND_TO_NEAREST);
+   
+   pBase = (unsigned int*)readRegister(getRn(opcode));
+   if (REG_PC == getRn(opcode))
+   {
+     pBase += 2;
+     write_back = 0;
+   }
+
+   pFinal = pBase;
+   if (BIT_UP_SET(opcode))
+     pFinal += getOffset(opcode);
+   else
+     pFinal -= getOffset(opcode);
+
+   if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
+
+   switch (opcode & MASK_TRANSFER_LENGTH)
+   {
+      case TRANSFER_SINGLE  : storeSingle(getFd(opcode),pAddress);   break;
+      case TRANSFER_DOUBLE  : storeDouble(getFd(opcode),pAddress);   break;
+      case TRANSFER_EXTENDED: storeExtended(getFd(opcode),pAddress); break;
+      default: nRc = 0;
+   }
+   
+   if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
+   return nRc;
+}
+
+unsigned int PerformLFM(const unsigned int opcode)
+{
+   unsigned int i, Fd, *pBase, *pAddress, *pFinal,
+     write_back = WRITE_BACK(opcode);
+
+   pBase = (unsigned int*)readRegister(getRn(opcode));
+   if (REG_PC == getRn(opcode))
+   {
+     pBase += 2;
+     write_back = 0;
+   }
+
+   pFinal = pBase;
+   if (BIT_UP_SET(opcode))
+     pFinal += getOffset(opcode);
+   else
+     pFinal -= getOffset(opcode);
+
+   if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
+
+   Fd = getFd(opcode);
+   for (i=getRegisterCount(opcode);i>0;i--)
+   {
+     loadMultiple(Fd,pAddress);
+     pAddress += 3; Fd++;
+     if (Fd == 8) Fd = 0;
+   }
+
+   if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
+   return 1;
+}
+
+unsigned int PerformSFM(const unsigned int opcode)
+{
+   unsigned int i, Fd, *pBase, *pAddress, *pFinal,
+     write_back = WRITE_BACK(opcode);
+   
+   pBase = (unsigned int*)readRegister(getRn(opcode));
+   if (REG_PC == getRn(opcode))
+   {
+     pBase += 2;
+     write_back = 0;
+   }
+   
+   pFinal = pBase;
+   if (BIT_UP_SET(opcode))
+     pFinal += getOffset(opcode);
+   else
+     pFinal -= getOffset(opcode);
+
+   if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
+
+   Fd = getFd(opcode);
+   for (i=getRegisterCount(opcode);i>0;i--)
+   {
+     storeMultiple(Fd,pAddress);
+     pAddress += 3; Fd++;
+     if (Fd == 8) Fd = 0;
+   }
+
+   if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
+   return 1;
+}
+
+#if 1
+unsigned int EmulateCPDT(const unsigned int opcode)
+{
+  unsigned int nRc = 0;
+
+  //printk("EmulateCPDT(0x%08x)\n",opcode);
+  
+  if (LDF_OP(opcode))
+  {
+    nRc = PerformLDF(opcode);
+  }
+  else if (LFM_OP(opcode))
+  {
+    nRc = PerformLFM(opcode);
+  }
+  else if (STF_OP(opcode))
+  {
+    nRc = PerformSTF(opcode);
+  } 
+  else if (SFM_OP(opcode))
+  {
+    nRc = PerformSFM(opcode);
+  }
+  else
+  {
+    nRc = 0;
+  }
+  
+  return nRc;
+}
+#endif
diff -urN linux-2.4.29/arch/armnommu/nwfpe/fpa11_cprt.c linux-2.4.29-uc1/arch/armnommu/nwfpe/fpa11_cprt.c
--- linux-2.4.29/arch/armnommu/nwfpe/fpa11_cprt.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/fpa11_cprt.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,286 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Rebel.com, 1998-1999
+    (c) Philip Blundell, 1999
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "milieu.h"
+#include "softfloat.h"
+#include "fpopcode.h"
+#include "fpa11.h"
+#include "fpa11.inl"
+#include "fpmodule.h"
+#include "fpmodule.inl"
+
+extern flag floatx80_is_nan(floatx80);
+extern flag float64_is_nan( float64);
+extern flag float32_is_nan( float32);
+
+void SetRoundingMode(const unsigned int opcode);
+
+unsigned int PerformFLT(const unsigned int opcode);
+unsigned int PerformFIX(const unsigned int opcode);
+
+static unsigned int
+PerformComparison(const unsigned int opcode);
+
+unsigned int EmulateCPRT(const unsigned int opcode)
+{
+  unsigned int nRc = 1;
+
+  //printk("EmulateCPRT(0x%08x)\n",opcode);
+
+  if (opcode & 0x800000)
+  {
+     /* This is some variant of a comparison (PerformComparison will
+	sort out which one).  Since most of the other CPRT
+	instructions are oddball cases of some sort or other it makes
+	sense to pull this out into a fast path.  */
+     return PerformComparison(opcode);
+  }
+
+  /* Hint to GCC that we'd like a jump table rather than a load of CMPs */
+  switch ((opcode & 0x700000) >> 20)
+  {
+    case  FLT_CODE >> 20: nRc = PerformFLT(opcode); break;
+    case  FIX_CODE >> 20: nRc = PerformFIX(opcode); break;
+    
+    case  WFS_CODE >> 20: writeFPSR(readRegister(getRd(opcode))); break;
+    case  RFS_CODE >> 20: writeRegister(getRd(opcode),readFPSR()); break;
+
+#if 0    /* We currently have no use for the FPCR, so there's no point
+	    in emulating it. */
+    case  WFC_CODE >> 20: writeFPCR(readRegister(getRd(opcode)));
+    case  RFC_CODE >> 20: writeRegister(getRd(opcode),readFPCR()); break;
+#endif
+
+    default: nRc = 0;
+  }
+  
+  return nRc;
+}
+
+unsigned int PerformFLT(const unsigned int opcode)
+{
+   unsigned int nRc = 1;
+   SetRoundingMode(opcode);
+   SetRoundingPrecision(opcode);
+   
+   switch (opcode & MASK_ROUNDING_PRECISION)
+   {
+      case ROUND_SINGLE:
+      {
+        fpa11->fType[getFn(opcode)] = typeSingle;
+        fpa11->fpreg[getFn(opcode)].fSingle =
+	   int32_to_float32(readRegister(getRd(opcode)));
+      }
+      break;
+
+      case ROUND_DOUBLE:
+      {
+        fpa11->fType[getFn(opcode)] = typeDouble;
+        fpa11->fpreg[getFn(opcode)].fDouble =
+            int32_to_float64(readRegister(getRd(opcode)));
+      }
+      break;
+        
+      case ROUND_EXTENDED:
+      {
+        fpa11->fType[getFn(opcode)] = typeExtended;
+        fpa11->fpreg[getFn(opcode)].fExtended =
+	   int32_to_floatx80(readRegister(getRd(opcode)));
+      }
+      break;
+      
+      default: nRc = 0;
+  }
+  
+  return nRc;
+}
+
+unsigned int PerformFIX(const unsigned int opcode)
+{
+   unsigned int nRc = 1;
+   unsigned int Fn = getFm(opcode);
+   
+   SetRoundingMode(opcode);
+
+   switch (fpa11->fType[Fn])
+   {
+      case typeSingle:
+      {
+         writeRegister(getRd(opcode),
+	               float32_to_int32(fpa11->fpreg[Fn].fSingle));
+      }
+      break;
+
+      case typeDouble:
+      {
+         writeRegister(getRd(opcode),
+	               float64_to_int32(fpa11->fpreg[Fn].fDouble));
+      }
+      break;
+      	               
+      case typeExtended:
+      {
+         writeRegister(getRd(opcode),
+	               floatx80_to_int32(fpa11->fpreg[Fn].fExtended));
+      }
+      break;
+      
+      default: nRc = 0;
+  }
+  
+  return nRc;
+}
+
+   
+static unsigned int __inline__
+PerformComparisonOperation(floatx80 Fn, floatx80 Fm)
+{
+   unsigned int flags = 0;
+
+   /* test for less than condition */
+   if (floatx80_lt(Fn,Fm))
+   {
+      flags |= CC_NEGATIVE;
+   }
+  
+   /* test for equal condition */
+   if (floatx80_eq(Fn,Fm))
+   {
+      flags |= CC_ZERO;
+   }
+
+   /* test for greater than or equal condition */
+   if (floatx80_lt(Fm,Fn))
+   {
+      flags |= CC_CARRY;
+   }
+   
+   writeConditionCodes(flags);
+   return 1;
+}
+
+/* This instruction sets the flags N, Z, C, V in the FPSR. */
+   
+static unsigned int PerformComparison(const unsigned int opcode)
+{
+   unsigned int Fn, Fm;
+   floatx80 rFn, rFm;
+   int e_flag = opcode & 0x400000;	/* 1 if CxFE */
+   int n_flag = opcode & 0x200000;	/* 1 if CNxx */
+   unsigned int flags = 0;
+
+   //printk("PerformComparison(0x%08x)\n",opcode);
+
+   Fn = getFn(opcode);
+   Fm = getFm(opcode);
+
+   /* Check for unordered condition and convert all operands to 80-bit
+      format.
+      ?? Might be some mileage in avoiding this conversion if possible.
+      Eg, if both operands are 32-bit, detect this and do a 32-bit
+      comparison (cheaper than an 80-bit one).  */
+   switch (fpa11->fType[Fn])
+   {
+      case typeSingle: 
+        //printk("single.\n");
+	if (float32_is_nan(fpa11->fpreg[Fn].fSingle))
+	   goto unordered;
+        rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
+      break;
+
+      case typeDouble: 
+        //printk("double.\n");
+	if (float64_is_nan(fpa11->fpreg[Fn].fDouble))
+	   goto unordered;
+        rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
+      break;
+      
+      case typeExtended: 
+        //printk("extended.\n");
+	if (floatx80_is_nan(fpa11->fpreg[Fn].fExtended))
+	   goto unordered;
+        rFn = fpa11->fpreg[Fn].fExtended;
+      break;
+      
+      default: return 0;
+   }
+
+   if (CONSTANT_FM(opcode))
+   {
+     //printk("Fm is a constant: #%d.\n",Fm);
+     rFm = getExtendedConstant(Fm);
+     if (floatx80_is_nan(rFm))
+        goto unordered;
+   }
+   else
+   {
+     //printk("Fm = r%d which contains a ",Fm);
+      switch (fpa11->fType[Fm])
+      {
+         case typeSingle: 
+           //printk("single.\n");
+	   if (float32_is_nan(fpa11->fpreg[Fm].fSingle))
+	      goto unordered;
+           rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
+         break;
+
+         case typeDouble: 
+           //printk("double.\n");
+	   if (float64_is_nan(fpa11->fpreg[Fm].fDouble))
+	      goto unordered;
+           rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
+         break;
+      
+         case typeExtended: 
+           //printk("extended.\n");
+	   if (floatx80_is_nan(fpa11->fpreg[Fm].fExtended))
+	      goto unordered;
+           rFm = fpa11->fpreg[Fm].fExtended;
+         break;
+      
+         default: return 0;
+      }
+   }
+
+   if (n_flag)
+   {
+      rFm.high ^= 0x8000;
+   }
+
+   return PerformComparisonOperation(rFn,rFm);
+
+ unordered:
+   /* ?? The FPA data sheet is pretty vague about this, in particular
+      about whether the non-E comparisons can ever raise exceptions.
+      This implementation is based on a combination of what it says in
+      the data sheet, observation of how the Acorn emulator actually
+      behaves (and how programs expect it to) and guesswork.  */
+   flags |= CC_OVERFLOW;
+   flags &= ~(CC_ZERO | CC_NEGATIVE);
+
+   if (BIT_AC & readFPSR()) flags |= CC_CARRY;
+
+   if (e_flag) float_raise(float_flag_invalid);
+
+   writeConditionCodes(flags);
+   return 1;
+}
diff -urN linux-2.4.29/arch/armnommu/nwfpe/fpa11.h linux-2.4.29-uc1/arch/armnommu/nwfpe/fpa11.h
--- linux-2.4.29/arch/armnommu/nwfpe/fpa11.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/fpa11.h	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,61 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Rebel.com, 1998-1999
+    
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __FPA11_H__
+#define __FPA11_H__
+
+/* includes */
+#include "fpsr.h"		/* FP control and status register definitions */
+#include "softfloat.h"
+
+#define		typeNone		0x00
+#define		typeSingle		0x01
+#define		typeDouble		0x02
+#define		typeExtended		0x03
+
+typedef union tagFPREG {
+   float32  fSingle;
+   float64  fDouble;
+   floatx80 fExtended;
+} FPREG;
+
+/* FPA11 device model */
+typedef struct tagFPA11 {
+  FPREG fpreg[8];		/* 8 floating point registers */
+  FPSR fpsr;			/* floating point status register */
+  FPCR fpcr;			/* floating point control register */
+  unsigned char fType[8];	/* type of floating point value held in
+				   floating point registers.  One of none
+				   single, double or extended. */
+  int initflag;			/* this is special.  The kernel guarantees
+				   to set it to 0 when a thread is launched,
+				   so we can use it to detect whether this
+				   instance of the emulator needs to be
+				   initialised. */
+} FPA11;
+
+extern void resetFPA11(void);
+extern void SetRoundingMode(const unsigned int);
+extern void SetRoundingPrecision(const unsigned int);
+
+extern FPA11 *fpa11;
+
+#endif
diff -urN linux-2.4.29/arch/armnommu/nwfpe/fpa11.inl linux-2.4.29-uc1/arch/armnommu/nwfpe/fpa11.inl
--- linux-2.4.29/arch/armnommu/nwfpe/fpa11.inl	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/fpa11.inl	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Corel Computer Corporation, 1998
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "fpa11.h"
+
+/* Read and write floating point status register */
+extern __inline__ unsigned int readFPSR(void)
+{
+  return(fpa11->fpsr);
+}
+
+extern __inline__ void writeFPSR(FPSR reg)
+{
+  /* the sysid byte in the status register is readonly */
+  fpa11->fpsr = (fpa11->fpsr & MASK_SYSID) | (reg & ~MASK_SYSID);
+}
+
+/* Read and write floating point control register */
+extern __inline__ FPCR readFPCR(void)
+{
+  /* clear SB, AB and DA bits before returning FPCR */
+  return(fpa11->fpcr & ~MASK_RFC);
+}
+
+extern __inline__ void writeFPCR(FPCR reg)
+{
+  fpa11->fpcr &= ~MASK_WFC;		/* clear SB, AB and DA bits */
+  fpa11->fpcr |= (reg & MASK_WFC);	/* write SB, AB and DA bits */
+}
diff -urN linux-2.4.29/arch/armnommu/nwfpe/fpmodule.c linux-2.4.29-uc1/arch/armnommu/nwfpe/fpmodule.c
--- linux-2.4.29/arch/armnommu/nwfpe/fpmodule.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/fpmodule.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,158 @@
+
+/*
+    NetWinder Floating Point Emulator
+    (c) Rebel.com, 1998-1999
+    (c) Philip Blundell, 1998-1999
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/config.h>
+
+/* XXX */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+/* XXX */
+
+#include "softfloat.h"
+#include "fpopcode.h"
+#include "fpmodule.h"
+#include "fpa11.h"
+#include "fpa11.inl"
+
+/* external data */
+extern FPA11 *fpa11;
+
+/* kernel symbols required for signal handling */
+typedef struct task_struct*	PTASK;
+
+#ifdef MODULE
+void fp_send_sig(unsigned long sig, PTASK p, int priv);
+#if LINUX_VERSION_CODE > 0x20115
+MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>");
+MODULE_DESCRIPTION("NWFPE floating point emulator");
+#endif
+
+#else
+#define fp_send_sig	send_sig
+#define kern_fp_enter	fp_enter
+#endif
+
+/* kernel function prototypes required */
+void fp_setup(void);
+
+/* external declarations for saved kernel symbols */
+extern void (*kern_fp_enter)(void);
+
+/* Original value of fp_enter from kernel before patched by fpe_init. */ 
+static void (*orig_fp_enter)(void);
+
+/* forward declarations */
+extern void nwfpe_enter(void);
+
+/* Address of user registers on the kernel stack. */
+unsigned int *userRegisters;
+
+int __init fpe_init(void)
+{
+  if (sizeof(FPA11) > sizeof(union fp_state))
+    printk(KERN_ERR "nwfpe: bad structure size\n");
+  else {
+    /* Display title, version and copyright information. */
+    printk(KERN_WARNING "NetWinder Floating Point Emulator V0.95 "
+	   "(c) 1998-1999 Rebel.com\n");
+
+    /* Save pointer to the old FP handler and then patch ourselves in */
+    orig_fp_enter = kern_fp_enter;
+    kern_fp_enter = nwfpe_enter;
+  }
+
+  return 0;
+}
+
+void __exit fpe_exit(void)
+{
+  /* Restore the values we saved earlier. */
+  kern_fp_enter = orig_fp_enter;
+}
+
+/*
+ScottB:  November 4, 1998
+
+Moved this function out of softfloat-specialize into fpmodule.c.
+This effectively isolates all the changes required for integrating with the
+Linux kernel into fpmodule.c.  Porting to NetBSD should only require modifying
+fpmodule.c to integrate with the NetBSD kernel (I hope!).
+
+[1/1/99: Not quite true any more unfortunately.  There is Linux-specific
+code to access data in user space in some other source files at the 
+moment (grep for get_user / put_user calls).  --philb]
+
+float_exception_flags is a global variable in SoftFloat.
+
+This function is called by the SoftFloat routines to raise a floating
+point exception.  We check the trap enable byte in the FPSR, and raise
+a SIGFPE exception if necessary.  If not the relevant bits in the 
+cumulative exceptions flag byte are set and we return.
+*/
+
+void float_raise(signed char flags)
+{
+  register unsigned int fpsr, cumulativeTraps;
+  
+#ifdef CONFIG_DEBUG_USER
+  printk(KERN_DEBUG "NWFPE: %s[%d] takes exception %08x at %p from %08x\n",
+	 current->comm, current->pid, flags,
+	 __builtin_return_address(0), userRegisters[15]);
+#endif
+
+  /* Keep SoftFloat exception flags up to date.  */
+  float_exception_flags |= flags;
+
+  /* Read fpsr and initialize the cumulativeTraps.  */
+  fpsr = readFPSR();
+  cumulativeTraps = 0;
+  
+  /* For each type of exception, the cumulative trap exception bit is only
+     set if the corresponding trap enable bit is not set.  */
+  if ((!(fpsr & BIT_IXE)) && (flags & BIT_IXC))
+     cumulativeTraps |= BIT_IXC;  
+  if ((!(fpsr & BIT_UFE)) && (flags & BIT_UFC))
+     cumulativeTraps |= BIT_UFC;  
+  if ((!(fpsr & BIT_OFE)) && (flags & BIT_OFC))
+     cumulativeTraps |= BIT_OFC;  
+  if ((!(fpsr & BIT_DZE)) && (flags & BIT_DZC))
+     cumulativeTraps |= BIT_DZC;  
+  if ((!(fpsr & BIT_IOE)) && (flags & BIT_IOC))
+     cumulativeTraps |= BIT_IOC;  
+
+  /* Set the cumulative exceptions flags.  */
+  if (cumulativeTraps)
+    writeFPSR(fpsr | cumulativeTraps);
+
+  /* Raise an exception if necessary.  */
+  if (fpsr & (flags << 16))
+    fp_send_sig(SIGFPE, current, 1);
+}
+
+module_init(fpe_init);
+module_exit(fpe_exit);
diff -urN linux-2.4.29/arch/armnommu/nwfpe/fpmodule.h linux-2.4.29-uc1/arch/armnommu/nwfpe/fpmodule.h
--- linux-2.4.29/arch/armnommu/nwfpe/fpmodule.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/fpmodule.h	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,53 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Rebel.com, 1998-1999
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __FPMODULE_H__
+#define __FPMODULE_H__
+
+#include <linux/config.h>
+
+#ifdef CONFIG_CPU_32
+#define REG_ORIG_R0	17
+#define REG_CPSR	16
+#else
+#define REG_ORIG_R0	16
+#define REG_CPSR	15
+#endif
+
+#define REG_PC		15
+#define REG_LR		14
+#define REG_SP		13
+#define REG_IP		12
+#define REG_FP		11
+#define REG_R10		10
+#define REG_R9		9
+#define REG_R9		9
+#define REG_R8		8
+#define REG_R7		7
+#define REG_R6		6
+#define REG_R5		5
+#define REG_R4		4
+#define REG_R3		3
+#define REG_R2		2
+#define REG_R1		1
+#define REG_R0		0
+
+#endif
diff -urN linux-2.4.29/arch/armnommu/nwfpe/fpmodule.inl linux-2.4.29-uc1/arch/armnommu/nwfpe/fpmodule.inl
--- linux-2.4.29/arch/armnommu/nwfpe/fpmodule.inl	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/fpmodule.inl	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,84 @@
+/*
+   NetWinder Floating Point Emulator
+   (c) Rebel.com, 1998-1999
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* Address of user registers on the kernel stack. */
+extern unsigned int *userRegisters;
+
+extern __inline__
+unsigned int readRegister(const unsigned int nReg)
+{
+  /* Note: The CPU thinks it has dealt with the current instruction.  As
+           a result the program counter has been advanced to the next
+           instruction, and points 4 bytes beyond the actual instruction
+           that caused the invalid instruction trap to occur.  We adjust
+           for this in this routine.  LDF/STF instructions with Rn = PC
+           depend on the PC being correct, as they use PC+8 in their 
+           address calculations. */
+  unsigned int val = userRegisters[nReg];
+  if (REG_PC == nReg) val -= 4;
+  return val;
+}
+
+extern __inline__
+void writeRegister(const unsigned int nReg, const unsigned int val)
+{
+  userRegisters[nReg] = val;
+}
+
+extern __inline__
+unsigned int readCPSR(void)
+{
+  return(readRegister(REG_CPSR));
+}
+
+extern __inline__
+void writeCPSR(const unsigned int val)
+{
+  writeRegister(REG_CPSR,val);
+}
+
+extern __inline__
+unsigned int readConditionCodes(void)
+{
+#ifdef __FPEM_TEST__
+   return(0);
+#else
+   return(readCPSR() & CC_MASK);
+#endif
+}
+
+extern __inline__
+void writeConditionCodes(const unsigned int val)
+{
+  unsigned int rval;
+  /*
+   * Operate directly on userRegisters since
+   * the CPSR may be the PC register itself.
+   */
+  rval = userRegisters[REG_CPSR] & ~CC_MASK;
+  userRegisters[REG_CPSR] = rval | (val & CC_MASK);
+}
+
+extern __inline__
+unsigned int readMemoryInt(unsigned int *pMem)
+{
+  return *pMem;
+}
diff -urN linux-2.4.29/arch/armnommu/nwfpe/fpopcode.c linux-2.4.29-uc1/arch/armnommu/nwfpe/fpopcode.c
--- linux-2.4.29/arch/armnommu/nwfpe/fpopcode.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/fpopcode.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,163 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Rebel.com, 1998-1999
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "softfloat.h"
+#include "fpopcode.h"
+#include "fpsr.h"
+#include "fpa11.h"
+#include "fpmodule.h"
+#include "fpmodule.inl"
+
+static floatx80 floatx80Constant[] = {
+  { 0x0000, 0x0000000000000000ULL},	/* extended 0.0 */
+  { 0x3fff, 0x8000000000000000ULL},	/* extended 1.0 */
+  { 0x4000, 0x8000000000000000ULL},	/* extended 2.0 */
+  { 0x4000, 0xc000000000000000ULL},	/* extended 3.0 */
+  { 0x4001, 0x8000000000000000ULL},	/* extended 4.0 */
+  { 0x4001, 0xa000000000000000ULL},	/* extended 5.0 */
+  { 0x3ffe, 0x8000000000000000ULL},	/* extended 0.5 */
+  { 0x4002, 0xa000000000000000ULL}	/* extended 10.0 */
+};  
+
+static float64 float64Constant[] = {
+  0x0000000000000000ULL,		/* double 0.0 */
+  0x3ff0000000000000ULL,		/* double 1.0 */
+  0x4000000000000000ULL,		/* double 2.0 */
+  0x4008000000000000ULL,		/* double 3.0 */
+  0x4010000000000000ULL,		/* double 4.0 */
+  0x4014000000000000ULL,		/* double 5.0 */
+  0x3fe0000000000000ULL,		/* double 0.5 */
+  0x4024000000000000ULL			/* double 10.0 */
+};  
+
+static float32 float32Constant[] = {
+  0x00000000,				/* single 0.0 */
+  0x3f800000,				/* single 1.0 */
+  0x40000000,				/* single 2.0 */
+  0x40400000,				/* single 3.0 */
+  0x40800000,				/* single 4.0 */
+  0x40a00000,				/* single 5.0 */
+  0x3f000000,				/* single 0.5 */
+  0x41200000				/* single 10.0 */
+};  
+
+floatx80 getExtendedConstant(const unsigned int nIndex)
+{
+   return floatx80Constant[nIndex];
+} 
+
+float64 getDoubleConstant(const unsigned int nIndex)
+{
+   return float64Constant[nIndex];
+} 
+
+float32 getSingleConstant(const unsigned int nIndex)
+{
+   return float32Constant[nIndex];
+} 
+
+unsigned int getTransferLength(const unsigned int opcode)
+{
+  unsigned int nRc;
+  
+  switch (opcode & MASK_TRANSFER_LENGTH)
+  {
+    case 0x00000000: nRc = 1; break; /* single precision */
+    case 0x00008000: nRc = 2; break; /* double precision */
+    case 0x00400000: nRc = 3; break; /* extended precision */
+    default: nRc = 0;
+  }
+  
+  return(nRc);
+}
+
+unsigned int getRegisterCount(const unsigned int opcode)
+{
+  unsigned int nRc;
+  
+  switch (opcode & MASK_REGISTER_COUNT)
+  {
+    case 0x00000000: nRc = 4; break;
+    case 0x00008000: nRc = 1; break;
+    case 0x00400000: nRc = 2; break;
+    case 0x00408000: nRc = 3; break;
+    default: nRc = 0;
+  }
+  
+  return(nRc);
+}
+
+unsigned int getRoundingPrecision(const unsigned int opcode)
+{
+  unsigned int nRc;
+  
+  switch (opcode & MASK_ROUNDING_PRECISION)
+  {
+    case 0x00000000: nRc = 1; break;
+    case 0x00000080: nRc = 2; break;
+    case 0x00080000: nRc = 3; break;
+    default: nRc = 0;
+  }
+  
+  return(nRc);
+}
+
+unsigned int getDestinationSize(const unsigned int opcode)
+{
+  unsigned int nRc;
+  
+  switch (opcode & MASK_DESTINATION_SIZE)
+  {
+    case 0x00000000: nRc = typeSingle; break;
+    case 0x00000080: nRc = typeDouble; break;
+    case 0x00080000: nRc = typeExtended; break;
+    default: nRc = typeNone;
+  }
+  
+  return(nRc);
+}
+
+/* contition code lookup table
+ index into the table is test code: EQ, NE, ... LT, GT, AL, NV
+ bit position in short is condition code: NZCV */
+unsigned short aCC[16] = {
+    0xF0F0, // EQ == Z set
+    0x0F0F, // NE
+    0xCCCC, // CS == C set
+    0x3333, // CC
+    0xFF00, // MI == N set
+    0x00FF, // PL
+    0xAAAA, // VS == V set
+    0x5555, // VC
+    0x0C0C, // HI == C set && Z clear
+    0xF3F3, // LS == C clear || Z set
+    0xAA55, // GE == (N==V)
+    0x55AA, // LT == (N!=V)
+    0x0A05, // GT == (!Z && (N==V))
+    0xF5FA, // LE == (Z || (N!=V))
+    0xFFFF, // AL always
+    0 // NV
+};
+
+unsigned int checkCondition(const unsigned int opcode, const unsigned int ccodes)
+{
+  return (aCC[opcode>>28] >> (ccodes>>28)) & 1;
+}
diff -urN linux-2.4.29/arch/armnommu/nwfpe/fpopcode.h linux-2.4.29-uc1/arch/armnommu/nwfpe/fpopcode.h
--- linux-2.4.29/arch/armnommu/nwfpe/fpopcode.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/fpopcode.h	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,376 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Rebel.com, 1998-1999
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __FPOPCODE_H__
+#define __FPOPCODE_H__
+
+/*
+ARM Floating Point Instruction Classes
+| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
+|c o n d|1 1 0 P|U|u|W|L|   Rn  |v|  Fd |0|0|0|1|  o f f s e t  | CPDT
+|c o n d|1 1 0 P|U|w|W|L|   Rn  |x|  Fd |0|0|0|1|  o f f s e t  | CPDT
+| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
+|c o n d|1 1 1 0|a|b|c|d|e|  Fn |j|  Fd |0|0|0|1|f|g|h|0|i|  Fm | CPDO
+|c o n d|1 1 1 0|a|b|c|L|e|  Fn |   Rd  |0|0|0|1|f|g|h|1|i|  Fm | CPRT
+|c o n d|1 1 1 0|a|b|c|1|e|  Fn |1|1|1|1|0|0|0|1|f|g|h|1|i|  Fm | comparisons
+| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
+
+CPDT		data transfer instructions
+		LDF, STF, LFM, SFM
+		
+CPDO		dyadic arithmetic instructions
+		ADF, MUF, SUF, RSF, DVF, RDF,
+		POW, RPW, RMF, FML, FDV, FRD, POL
+
+CPDO		monadic arithmetic instructions
+		MVF, MNF, ABS, RND, SQT, LOG, LGN, EXP,
+		SIN, COS, TAN, ASN, ACS, ATN, URD, NRM
+		
+CPRT		joint arithmetic/data transfer instructions
+		FIX (arithmetic followed by load/store)
+		FLT (load/store followed by arithmetic)
+		CMF, CNF CMFE, CNFE (comparisons)
+		WFS, RFS (write/read floating point status register)
+		WFC, RFC (write/read floating point control register)
+
+cond		condition codes
+P		pre/post index bit: 0 = postindex, 1 = preindex
+U		up/down bit: 0 = stack grows down, 1 = stack grows up
+W		write back bit: 1 = update base register (Rn)
+L		load/store bit: 0 = store, 1 = load
+Rn		base register
+Rd		destination/source register		
+Fd		floating point destination register
+Fn		floating point source register
+Fm		floating point source register or floating point constant
+
+uv		transfer length (TABLE 1)
+wx		register count (TABLE 2)
+abcd		arithmetic opcode (TABLES 3 & 4)
+ef		destination size (rounding precision) (TABLE 5)
+gh		rounding mode (TABLE 6)
+j		dyadic/monadic bit: 0 = dyadic, 1 = monadic
+i 		constant bit: 1 = constant (TABLE 6)
+*/
+
+/*
+TABLE 1
++-------------------------+---+---+---------+---------+
+|  Precision              | u | v | FPSR.EP | length  |
++-------------------------+---+---+---------+---------+
+| Single                  | 0 ü 0 |    x    | 1 words |
+| Double                  | 1 ü 1 |    x    | 2 words |
+| Extended                | 1 ü 1 |    x    | 3 words |
+| Packed decimal          | 1 ü 1 |    0    | 3 words |
+| Expanded packed decimal | 1 ü 1 |    1    | 4 words |
++-------------------------+---+---+---------+---------+
+Note: x = don't care
+*/
+
+/*
+TABLE 2
++---+---+---------------------------------+
+| w | x | Number of registers to transfer |
++---+---+---------------------------------+
+| 0 ü 1 |  1                              |
+| 1 ü 0 |  2                              |
+| 1 ü 1 |  3                              |
+| 0 ü 0 |  4                              |
++---+---+---------------------------------+
+*/
+
+/*
+TABLE 3: Dyadic Floating Point Opcodes
++---+---+---+---+----------+-----------------------+-----------------------+
+| a | b | c | d | Mnemonic | Description           | Operation             |
++---+---+---+---+----------+-----------------------+-----------------------+
+| 0 | 0 | 0 | 0 | ADF      | Add                   | Fd := Fn + Fm         |
+| 0 | 0 | 0 | 1 | MUF      | Multiply              | Fd := Fn * Fm         |
+| 0 | 0 | 1 | 0 | SUF      | Subtract              | Fd := Fn - Fm         |
+| 0 | 0 | 1 | 1 | RSF      | Reverse subtract      | Fd := Fm - Fn         |
+| 0 | 1 | 0 | 0 | DVF      | Divide                | Fd := Fn / Fm         |
+| 0 | 1 | 0 | 1 | RDF      | Reverse divide        | Fd := Fm / Fn         |
+| 0 | 1 | 1 | 0 | POW      | Power                 | Fd := Fn ^ Fm         |
+| 0 | 1 | 1 | 1 | RPW      | Reverse power         | Fd := Fm ^ Fn         |
+| 1 | 0 | 0 | 0 | RMF      | Remainder             | Fd := IEEE rem(Fn/Fm) |
+| 1 | 0 | 0 | 1 | FML      | Fast Multiply         | Fd := Fn * Fm         |
+| 1 | 0 | 1 | 0 | FDV      | Fast Divide           | Fd := Fn / Fm         |
+| 1 | 0 | 1 | 1 | FRD      | Fast reverse divide   | Fd := Fm / Fn         |
+| 1 | 1 | 0 | 0 | POL      | Polar angle (ArcTan2) | Fd := arctan2(Fn,Fm)  |
+| 1 | 1 | 0 | 1 |          | undefined instruction | trap                  |
+| 1 | 1 | 1 | 0 |          | undefined instruction | trap                  |
+| 1 | 1 | 1 | 1 |          | undefined instruction | trap                  |
++---+---+---+---+----------+-----------------------+-----------------------+
+Note: POW, RPW, POL are deprecated, and are available for backwards
+      compatibility only.
+*/
+
+/*
+TABLE 4: Monadic Floating Point Opcodes
++---+---+---+---+----------+-----------------------+-----------------------+
+| a | b | c | d | Mnemonic | Description           | Operation             |
++---+---+---+---+----------+-----------------------+-----------------------+
+| 0 | 0 | 0 | 0 | MVF      | Move                  | Fd := Fm              |
+| 0 | 0 | 0 | 1 | MNF      | Move negated          | Fd := - Fm            |
+| 0 | 0 | 1 | 0 | ABS      | Absolute value        | Fd := abs(Fm)         |
+| 0 | 0 | 1 | 1 | RND      | Round to integer      | Fd := int(Fm)         |
+| 0 | 1 | 0 | 0 | SQT      | Square root           | Fd := sqrt(Fm)        |
+| 0 | 1 | 0 | 1 | LOG      | Log base 10           | Fd := log10(Fm)       |
+| 0 | 1 | 1 | 0 | LGN      | Log base e            | Fd := ln(Fm)          |
+| 0 | 1 | 1 | 1 | EXP      | Exponent              | Fd := e ^ Fm          |
+| 1 | 0 | 0 | 0 | SIN      | Sine                  | Fd := sin(Fm)         |
+| 1 | 0 | 0 | 1 | COS      | Cosine                | Fd := cos(Fm)         |
+| 1 | 0 | 1 | 0 | TAN      | Tangent               | Fd := tan(Fm)         |
+| 1 | 0 | 1 | 1 | ASN      | Arc Sine              | Fd := arcsin(Fm)      |
+| 1 | 1 | 0 | 0 | ACS      | Arc Cosine            | Fd := arccos(Fm)      |
+| 1 | 1 | 0 | 1 | ATN      | Arc Tangent           | Fd := arctan(Fm)      |
+| 1 | 1 | 1 | 0 | URD      | Unnormalized round    | Fd := int(Fm)         |
+| 1 | 1 | 1 | 1 | NRM      | Normalize             | Fd := norm(Fm)        |
++---+---+---+---+----------+-----------------------+-----------------------+
+Note: LOG, LGN, EXP, SIN, COS, TAN, ASN, ACS, ATN are deprecated, and are
+      available for backwards compatibility only.
+*/
+
+/*
+TABLE 5
++-------------------------+---+---+
+|  Rounding Precision     | e | f |
++-------------------------+---+---+
+| IEEE Single precision   | 0 ü 0 |
+| IEEE Double precision   | 0 ü 1 |
+| IEEE Extended precision | 1 ü 0 |
+| undefined (trap)        | 1 ü 1 |
++-------------------------+---+---+
+*/
+
+/*
+TABLE 5
++---------------------------------+---+---+
+|  Rounding Mode                  | g | h |
++---------------------------------+---+---+
+| Round to nearest (default)      | 0 ü 0 |
+| Round toward plus infinity      | 0 ü 1 |
+| Round toward negative infinity  | 1 ü 0 |
+| Round toward zero               | 1 ü 1 |
++---------------------------------+---+---+
+*/
+
+/*
+===
+=== Definitions for load and store instructions
+===
+*/
+
+/* bit masks */
+#define BIT_PREINDEX	0x01000000
+#define BIT_UP		0x00800000
+#define BIT_WRITE_BACK	0x00200000
+#define BIT_LOAD	0x00100000
+
+/* masks for load/store */
+#define MASK_CPDT		0x0c000000  /* data processing opcode */
+#define MASK_OFFSET		0x000000ff
+#define MASK_TRANSFER_LENGTH	0x00408000
+#define MASK_REGISTER_COUNT	MASK_TRANSFER_LENGTH
+#define MASK_COPROCESSOR	0x00000f00
+
+/* Tests for transfer length */
+#define TRANSFER_SINGLE		0x00000000
+#define TRANSFER_DOUBLE		0x00008000
+#define TRANSFER_EXTENDED	0x00400000
+#define TRANSFER_PACKED		MASK_TRANSFER_LENGTH
+
+/* Get the coprocessor number from the opcode. */
+#define getCoprocessorNumber(opcode)	((opcode & MASK_COPROCESSOR) >> 8)
+
+/* Get the offset from the opcode. */
+#define getOffset(opcode)		(opcode & MASK_OFFSET)
+
+/* Tests for specific data transfer load/store opcodes. */
+#define TEST_OPCODE(opcode,mask)	(((opcode) & (mask)) == (mask))
+
+#define LOAD_OP(opcode)   TEST_OPCODE((opcode),MASK_CPDT | BIT_LOAD)
+#define STORE_OP(opcode)  ((opcode & (MASK_CPDT | BIT_LOAD)) == MASK_CPDT)
+
+#define LDF_OP(opcode)	(LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 1))
+#define LFM_OP(opcode)	(LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 2))
+#define STF_OP(opcode)	(STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 1))
+#define SFM_OP(opcode)	(STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 2))
+
+#define PREINDEXED(opcode)		((opcode & BIT_PREINDEX) != 0)
+#define POSTINDEXED(opcode)		((opcode & BIT_PREINDEX) == 0)
+#define BIT_UP_SET(opcode)		((opcode & BIT_UP) != 0)
+#define BIT_UP_CLEAR(opcode)		((opcode & BIT_DOWN) == 0)
+#define WRITE_BACK(opcode)		((opcode & BIT_WRITE_BACK) != 0)
+#define LOAD(opcode)			((opcode & BIT_LOAD) != 0)
+#define STORE(opcode)			((opcode & BIT_LOAD) == 0)
+
+/*
+===
+=== Definitions for arithmetic instructions
+===
+*/
+/* bit masks */
+#define BIT_MONADIC	0x00008000
+#define BIT_CONSTANT	0x00000008
+
+#define CONSTANT_FM(opcode)		((opcode & BIT_CONSTANT) != 0)
+#define MONADIC_INSTRUCTION(opcode)	((opcode & BIT_MONADIC) != 0)
+
+/* instruction identification masks */
+#define MASK_CPDO		0x0e000000  /* arithmetic opcode */
+#define MASK_ARITHMETIC_OPCODE	0x00f08000
+#define MASK_DESTINATION_SIZE	0x00080080
+
+/* dyadic arithmetic opcodes. */
+#define ADF_CODE	0x00000000
+#define MUF_CODE	0x00100000
+#define SUF_CODE	0x00200000
+#define RSF_CODE	0x00300000
+#define DVF_CODE	0x00400000
+#define RDF_CODE	0x00500000
+#define POW_CODE	0x00600000
+#define RPW_CODE	0x00700000
+#define RMF_CODE	0x00800000
+#define FML_CODE	0x00900000
+#define FDV_CODE	0x00a00000
+#define FRD_CODE	0x00b00000
+#define POL_CODE	0x00c00000
+/* 0x00d00000 is an invalid dyadic arithmetic opcode */
+/* 0x00e00000 is an invalid dyadic arithmetic opcode */
+/* 0x00f00000 is an invalid dyadic arithmetic opcode */
+
+/* monadic arithmetic opcodes. */
+#define MVF_CODE	0x00008000
+#define MNF_CODE	0x00108000
+#define ABS_CODE	0x00208000
+#define RND_CODE	0x00308000
+#define SQT_CODE	0x00408000
+#define LOG_CODE	0x00508000
+#define LGN_CODE	0x00608000
+#define EXP_CODE	0x00708000
+#define SIN_CODE	0x00808000
+#define COS_CODE	0x00908000
+#define TAN_CODE	0x00a08000
+#define ASN_CODE	0x00b08000
+#define ACS_CODE	0x00c08000
+#define ATN_CODE	0x00d08000
+#define URD_CODE	0x00e08000
+#define NRM_CODE	0x00f08000
+
+/*
+===
+=== Definitions for register transfer and comparison instructions
+===
+*/
+
+#define MASK_CPRT		0x0e000010  /* register transfer opcode */
+#define MASK_CPRT_CODE		0x00f00000
+#define FLT_CODE		0x00000000
+#define FIX_CODE		0x00100000
+#define WFS_CODE		0x00200000
+#define RFS_CODE		0x00300000
+#define WFC_CODE		0x00400000
+#define RFC_CODE		0x00500000
+#define CMF_CODE		0x00900000
+#define CNF_CODE		0x00b00000
+#define CMFE_CODE		0x00d00000
+#define CNFE_CODE		0x00f00000
+
+/*
+===
+=== Common definitions
+===
+*/
+
+/* register masks */
+#define MASK_Rd		0x0000f000
+#define MASK_Rn		0x000f0000
+#define MASK_Fd		0x00007000
+#define MASK_Fm		0x00000007
+#define MASK_Fn		0x00070000
+
+/* condition code masks */
+#define CC_MASK		0xf0000000
+#define CC_NEGATIVE	0x80000000
+#define CC_ZERO		0x40000000
+#define CC_CARRY	0x20000000
+#define CC_OVERFLOW	0x10000000
+#define CC_EQ		0x00000000
+#define CC_NE		0x10000000
+#define CC_CS		0x20000000
+#define CC_HS		CC_CS
+#define CC_CC		0x30000000
+#define CC_LO		CC_CC
+#define CC_MI		0x40000000
+#define CC_PL		0x50000000
+#define CC_VS		0x60000000
+#define CC_VC		0x70000000
+#define CC_HI		0x80000000
+#define CC_LS		0x90000000
+#define CC_GE		0xa0000000
+#define CC_LT		0xb0000000
+#define CC_GT		0xc0000000
+#define CC_LE		0xd0000000
+#define CC_AL		0xe0000000
+#define CC_NV		0xf0000000
+
+/* rounding masks/values */
+#define MASK_ROUNDING_MODE	0x00000060
+#define ROUND_TO_NEAREST	0x00000000
+#define ROUND_TO_PLUS_INFINITY	0x00000020
+#define ROUND_TO_MINUS_INFINITY	0x00000040
+#define ROUND_TO_ZERO		0x00000060
+
+#define MASK_ROUNDING_PRECISION	0x00080080
+#define ROUND_SINGLE		0x00000000
+#define ROUND_DOUBLE		0x00000080
+#define ROUND_EXTENDED		0x00080000
+
+/* Get the condition code from the opcode. */
+#define getCondition(opcode)		(opcode >> 28)
+
+/* Get the source register from the opcode. */
+#define getRn(opcode)			((opcode & MASK_Rn) >> 16)
+
+/* Get the destination floating point register from the opcode. */
+#define getFd(opcode)			((opcode & MASK_Fd) >> 12)
+
+/* Get the first source floating point register from the opcode. */
+#define getFn(opcode)		((opcode & MASK_Fn) >> 16)
+
+/* Get the second source floating point register from the opcode. */
+#define getFm(opcode)		(opcode & MASK_Fm)
+
+/* Get the destination register from the opcode. */
+#define getRd(opcode)		((opcode & MASK_Rd) >> 12)
+
+/* Get the rounding mode from the opcode. */
+#define getRoundingMode(opcode)		((opcode & MASK_ROUNDING_MODE) >> 5)
+
+float32 getSingleConstant(const unsigned int nIndex);
+float64 getDoubleConstant(const unsigned int nIndex);
+floatx80 getExtendedConstant(const unsigned int nIndex);
+
+unsigned int getRegisterCount(const unsigned int opcode);
+unsigned int getDestinationSize(const unsigned int opcode);
+
+#endif
diff -urN linux-2.4.29/arch/armnommu/nwfpe/fpsr.h linux-2.4.29-uc1/arch/armnommu/nwfpe/fpsr.h
--- linux-2.4.29/arch/armnommu/nwfpe/fpsr.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/fpsr.h	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,108 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Rebel.com, 1998-1999
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __FPSR_H__
+#define __FPSR_H__
+
+/*
+The FPSR is a 32 bit register consisting of 4 parts, each exactly
+one byte.
+
+	SYSTEM ID
+	EXCEPTION TRAP ENABLE BYTE
+	SYSTEM CONTROL BYTE
+	CUMULATIVE EXCEPTION FLAGS BYTE
+	
+The FPCR is a 32 bit register consisting of bit flags.
+*/
+
+/* SYSTEM ID
+------------
+Note: the system id byte is read only  */
+
+typedef unsigned int FPSR;  /* type for floating point status register */
+typedef unsigned int FPCR;  /* type for floating point control register */
+
+#define MASK_SYSID		0xff000000
+#define BIT_HARDWARE		0x80000000
+#define FP_EMULATOR		0x01000000	/* System ID for emulator */ 
+#define FP_ACCELERATOR		0x81000000	/* System ID for FPA11 */
+
+/* EXCEPTION TRAP ENABLE BYTE
+----------------------------- */
+
+#define MASK_TRAP_ENABLE	0x00ff0000
+#define MASK_TRAP_ENABLE_STRICT	0x001f0000
+#define BIT_IXE		0x00100000   /* inexact exception enable */
+#define BIT_UFE		0x00080000   /* underflow exception enable */
+#define BIT_OFE		0x00040000   /* overflow exception enable */
+#define BIT_DZE		0x00020000   /* divide by zero exception enable */
+#define BIT_IOE		0x00010000   /* invalid operation exception enable */
+
+/* SYSTEM CONTROL BYTE
+---------------------- */
+
+#define MASK_SYSTEM_CONTROL	0x0000ff00
+#define MASK_TRAP_STRICT	0x00001f00
+
+#define BIT_AC	0x00001000	/* use alternative C-flag definition
+				   for compares */
+#define BIT_EP	0x00000800	/* use expanded packed decimal format */
+#define BIT_SO	0x00000400	/* select synchronous operation of FPA */
+#define BIT_NE	0x00000200	/* NaN exception bit */
+#define BIT_ND	0x00000100	/* no denormalized numbers bit */
+
+/* CUMULATIVE EXCEPTION FLAGS BYTE
+---------------------------------- */
+
+#define MASK_EXCEPTION_FLAGS		0x000000ff
+#define MASK_EXCEPTION_FLAGS_STRICT	0x0000001f
+
+#define BIT_IXC		0x00000010	/* inexact exception flag */
+#define BIT_UFC		0x00000008	/* underflow exception flag */
+#define BIT_OFC		0x00000004	/* overfloat exception flag */
+#define BIT_DZC		0x00000002	/* divide by zero exception flag */
+#define BIT_IOC		0x00000001	/* invalid operation exception flag */
+
+/* Floating Point Control Register
+----------------------------------*/
+
+#define BIT_RU		0x80000000	/* rounded up bit */
+#define BIT_IE		0x10000000	/* inexact bit */
+#define BIT_MO		0x08000000	/* mantissa overflow bit */
+#define BIT_EO		0x04000000	/* exponent overflow bit */
+#define BIT_SB		0x00000800	/* store bounce */
+#define BIT_AB		0x00000400	/* arithmetic bounce */
+#define BIT_RE		0x00000200	/* rounding exception */
+#define BIT_DA		0x00000100	/* disable FPA */
+
+#define MASK_OP		0x00f08010	/* AU operation code */
+#define MASK_PR		0x00080080	/* AU precision */
+#define MASK_S1		0x00070000	/* AU source register 1 */
+#define MASK_S2		0x00000007	/* AU source register 2 */
+#define MASK_DS		0x00007000	/* AU destination register */
+#define MASK_RM		0x00000060	/* AU rounding mode */
+#define MASK_ALU	0x9cfff2ff	/* only ALU can write these bits */
+#define MASK_RESET	0x00000d00	/* bits set on reset, all others cleared */
+#define MASK_WFC	MASK_RESET
+#define MASK_RFC	~MASK_RESET
+
+#endif
diff -urN linux-2.4.29/arch/armnommu/nwfpe/Makefile linux-2.4.29-uc1/arch/armnommu/nwfpe/Makefile
--- linux-2.4.29/arch/armnommu/nwfpe/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,32 @@
+#
+# linux/arch/arm/nwfpe/Makefile
+#
+# Copyright (C) 1998, 1999 Philip Blundell
+#
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= math-emu.o
+
+obj-y			:=
+obj-m			:=
+obj-n			:=
+
+list-multi		:= nwfpe.o
+
+obj-$(CONFIG_NWFPE)	+= nwfpe.o
+
+nwfpe-objs		:= fpa11.o fpa11_cpdo.o fpa11_cpdt.o fpa11_cprt.o \
+			   fpmodule.o fpopcode.o softfloat.o \
+			   single_cpdo.o double_cpdo.o extended_cpdo.o
+
+ifeq ($(CONFIG_CPU_26),y)
+nwfpe-objs		+= entry26.o
+else
+nwfpe-objs		+= entry.o
+endif
+
+include $(TOPDIR)/Rules.make
+
+nwfpe.o: $(nwfpe-objs)
+	$(LD) -r -o $@ $(nwfpe-objs)
diff -urN linux-2.4.29/arch/armnommu/nwfpe/milieu.h linux-2.4.29-uc1/arch/armnommu/nwfpe/milieu.h
--- linux-2.4.29/arch/armnommu/nwfpe/milieu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/milieu.h	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,48 @@
+
+/*
+===============================================================================
+
+This C header file is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2.
+
+Written by John R. Hauser.  This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704.  Funding was partially provided by the
+National Science Foundation under grant MIP-9311980.  The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
+is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
+arithmetic/softfloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these three paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Include common integer types and flags.
+-------------------------------------------------------------------------------
+*/
+#include "ARM-gcc.h"
+
+/*
+-------------------------------------------------------------------------------
+Symbolic Boolean literals.
+-------------------------------------------------------------------------------
+*/
+enum {
+    FALSE = 0,
+    TRUE  = 1
+};
+
diff -urN linux-2.4.29/arch/armnommu/nwfpe/single_cpdo.c linux-2.4.29-uc1/arch/armnommu/nwfpe/single_cpdo.c
--- linux-2.4.29/arch/armnommu/nwfpe/single_cpdo.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/single_cpdo.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,257 @@
+/*
+    NetWinder Floating Point Emulator
+    (c) Rebel.com, 1998-1999
+
+    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "softfloat.h"
+#include "fpopcode.h"
+#include "fpa11.h"
+
+float32 getSingleConstant(unsigned int);
+
+float32 float32_exp(float32 Fm);
+float32 float32_ln(float32 Fm);
+float32 float32_sin(float32 rFm);
+float32 float32_cos(float32 rFm);
+float32 float32_arcsin(float32 rFm);
+float32 float32_arctan(float32 rFm);
+float32 float32_log(float32 rFm);
+float32 float32_tan(float32 rFm);
+float32 float32_arccos(float32 rFm);
+float32 float32_pow(float32 rFn,float32 rFm);
+float32 float32_pol(float32 rFn,float32 rFm);
+
+unsigned int SingleCPDO(const unsigned int opcode)
+{
+   float32 rFm, rFn;
+   unsigned int Fd, Fm, Fn, nRc = 1;
+
+   Fm = getFm(opcode);
+   if (CONSTANT_FM(opcode))
+   {
+     rFm = getSingleConstant(Fm);
+   }
+   else
+   {  
+     switch (fpa11->fType[Fm])
+     {
+        case typeSingle:
+          rFm = fpa11->fpreg[Fm].fSingle;
+        break;
+        
+        default: return 0;
+     }
+   }
+
+   if (!MONADIC_INSTRUCTION(opcode))
+   {
+      Fn = getFn(opcode);
+      switch (fpa11->fType[Fn])
+      {
+        case typeSingle:
+          rFn = fpa11->fpreg[Fn].fSingle;
+        break;
+
+        default: return 0;
+      }
+   }
+
+   Fd = getFd(opcode);
+   switch (opcode & MASK_ARITHMETIC_OPCODE)
+   {
+      /* dyadic opcodes */
+      case ADF_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_add(rFn,rFm);
+      break;
+
+      case MUF_CODE:
+      case FML_CODE:
+        fpa11->fpreg[Fd].fSingle = float32_mul(rFn,rFm);
+      break;
+
+      case SUF_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_sub(rFn,rFm);
+      break;
+
+      case RSF_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_sub(rFm,rFn);
+      break;
+
+      case DVF_CODE:
+      case FDV_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_div(rFn,rFm);
+      break;
+
+      case RDF_CODE:
+      case FRD_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_div(rFm,rFn);
+      break;
+
+#if 0
+      case POW_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_pow(rFn,rFm);
+      break;
+
+      case RPW_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_pow(rFm,rFn);
+      break;
+#endif
+
+      case RMF_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_rem(rFn,rFm);
+      break;
+
+#if 0
+      case POL_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_pol(rFn,rFm);
+      break;
+#endif
+
+      /* monadic opcodes */
+      case MVF_CODE:
+         fpa11->fpreg[Fd].fSingle = rFm;
+      break;
+
+      case MNF_CODE:
+         rFm ^= 0x80000000;
+         fpa11->fpreg[Fd].fSingle = rFm;
+      break;
+
+      case ABS_CODE:
+         rFm &= 0x7fffffff;
+         fpa11->fpreg[Fd].fSingle = rFm;
+      break;
+
+      case RND_CODE:
+      case URD_CODE:
+         fpa11->fpreg[Fd].fSingle = 
+             int32_to_float32(float32_to_int32(rFm));
+      break;
+
+      case SQT_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_sqrt(rFm);
+      break;
+
+#if 0
+      case LOG_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_log(rFm);
+      break;
+
+      case LGN_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_ln(rFm);
+      break;
+
+      case EXP_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_exp(rFm);
+      break;
+
+      case SIN_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_sin(rFm);
+      break;
+
+      case COS_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_cos(rFm);
+      break;
+
+      case TAN_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_tan(rFm);
+      break;
+
+      case ASN_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_arcsin(rFm);
+      break;
+
+      case ACS_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_arccos(rFm);
+      break;
+
+      case ATN_CODE:
+         fpa11->fpreg[Fd].fSingle = float32_arctan(rFm);
+      break;
+#endif
+
+      case NRM_CODE:
+      break;
+      
+      default:
+      {
+        nRc = 0;
+      }
+   }
+
+   if (0 != nRc) fpa11->fType[Fd] = typeSingle;
+   return nRc;
+}
+
+#if 0
+float32 float32_exp(float32 Fm)
+{
+//series
+}
+
+float32 float32_ln(float32 Fm)
+{
+//series
+}
+
+float32 float32_sin(float32 rFm)
+{
+//series
+}
+
+float32 float32_cos(float32 rFm)
+{
+//series
+}
+
+float32 float32_arcsin(float32 rFm)
+{
+//series
+}
+
+float32 float32_arctan(float32 rFm)
+{
+  //series
+}
+
+float32 float32_arccos(float32 rFm)
+{
+   //return float32_sub(halfPi,float32_arcsin(rFm));
+}
+
+float32 float32_log(float32 rFm)
+{
+  return float32_div(float32_ln(rFm),getSingleConstant(7));
+}
+
+float32 float32_tan(float32 rFm)
+{
+  return float32_div(float32_sin(rFm),float32_cos(rFm));
+}
+
+float32 float32_pow(float32 rFn,float32 rFm)
+{
+  return float32_exp(float32_mul(rFm,float32_ln(rFn))); 
+}
+
+float32 float32_pol(float32 rFn,float32 rFm)
+{
+  return float32_arctan(float32_div(rFn,rFm)); 
+}
+#endif
diff -urN linux-2.4.29/arch/armnommu/nwfpe/softfloat.c linux-2.4.29-uc1/arch/armnommu/nwfpe/softfloat.c
--- linux-2.4.29/arch/armnommu/nwfpe/softfloat.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/softfloat.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,4876 @@
+/*
+===============================================================================
+
+This C source file is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2.
+
+Written by John R. Hauser.  This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704.  Funding was partially provided by the
+National Science Foundation under grant MIP-9311980.  The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
+is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
+arithmetic/softfloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these three paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include "milieu.h"
+#include "softfloat.h"
+
+/*
+-------------------------------------------------------------------------------
+Floating-point rounding mode, extended double-precision rounding precision,
+and exception flags.
+-------------------------------------------------------------------------------
+*/
+int8 float_rounding_mode = float_round_nearest_even;
+int8 floatx80_rounding_precision = 80;
+int8 float_exception_flags;
+
+/*
+-------------------------------------------------------------------------------
+Primitive arithmetic functions, including multi-word arithmetic, and
+division and square root approximations.  (Can be specialized to target if
+desired.)
+-------------------------------------------------------------------------------
+*/
+#include "softfloat-macros"
+
+/*
+-------------------------------------------------------------------------------
+Functions and definitions to determine:  (1) whether tininess for underflow
+is detected before or after rounding by default, (2) what (if anything)
+happens when exceptions are raised, (3) how signaling NaNs are distinguished
+from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
+are propagated from function inputs to output.  These details are target-
+specific.
+-------------------------------------------------------------------------------
+*/
+#include "softfloat-specialize"
+
+/*
+-------------------------------------------------------------------------------
+Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
+and 7, and returns the properly rounded 32-bit integer corresponding to the
+input.  If `zSign' is nonzero, the input is negated before being converted
+to an integer.  Bit 63 of `absZ' must be zero.  Ordinarily, the fixed-point
+input is simply rounded to an integer, with the inexact exception raised if
+the input cannot be represented exactly as an integer.  If the fixed-point
+input is too large, however, the invalid exception is raised and the largest
+positive or negative integer is returned.
+-------------------------------------------------------------------------------
+*/
+static int32 roundAndPackInt32( flag zSign, bits64 absZ )
+{
+    int8 roundingMode;
+    flag roundNearestEven;
+    int8 roundIncrement, roundBits;
+    int32 z;
+
+    roundingMode = float_rounding_mode;
+    roundNearestEven = ( roundingMode == float_round_nearest_even );
+    roundIncrement = 0x40;
+    if ( ! roundNearestEven ) {
+        if ( roundingMode == float_round_to_zero ) {
+            roundIncrement = 0;
+        }
+        else {
+            roundIncrement = 0x7F;
+            if ( zSign ) {
+                if ( roundingMode == float_round_up ) roundIncrement = 0;
+            }
+            else {
+                if ( roundingMode == float_round_down ) roundIncrement = 0;
+            }
+        }
+    }
+    roundBits = absZ & 0x7F;
+    absZ = ( absZ + roundIncrement )>>7;
+    absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
+    z = absZ;
+    if ( zSign ) z = - z;
+    if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
+        float_exception_flags |= float_flag_invalid;
+        return zSign ? 0x80000000 : 0x7FFFFFFF;
+    }
+    if ( roundBits ) float_exception_flags |= float_flag_inexact;
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the fraction bits of the single-precision floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE bits32 extractFloat32Frac( float32 a )
+{
+
+    return a & 0x007FFFFF;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the exponent bits of the single-precision floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE int16 extractFloat32Exp( float32 a )
+{
+
+    return ( a>>23 ) & 0xFF;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the sign bit of the single-precision floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE flag extractFloat32Sign( float32 a )
+{
+
+    return a>>31;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Normalizes the subnormal single-precision floating-point value represented
+by the denormalized significand `aSig'.  The normalized exponent and
+significand are stored at the locations pointed to by `zExpPtr' and
+`zSigPtr', respectively.
+-------------------------------------------------------------------------------
+*/
+static void
+ normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr )
+{
+    int8 shiftCount;
+
+    shiftCount = countLeadingZeros32( aSig ) - 8;
+    *zSigPtr = aSig<<shiftCount;
+    *zExpPtr = 1 - shiftCount;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
+single-precision floating-point value, returning the result.  After being
+shifted into the proper positions, the three fields are simply added
+together to form the result.  This means that any integer portion of `zSig'
+will be added into the exponent.  Since a properly normalized significand
+will have an integer portion equal to 1, the `zExp' input should be 1 less
+than the desired result exponent whenever `zSig' is a complete, normalized
+significand.
+-------------------------------------------------------------------------------
+*/
+INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig )
+{
+#if 0
+   float32 f;
+   __asm__("@ packFloat32;
+   	    mov %0, %1, asl #31;
+   	    orr %0, %2, asl #23;
+   	    orr %0, %3"
+   	    : /* no outputs */
+   	    : "g" (f), "g" (zSign), "g" (zExp), "g" (zSig)
+   	    : "cc");
+   return f;
+#else
+    return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig;
+#endif 
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+and significand `zSig', and returns the proper single-precision floating-
+point value corresponding to the abstract input.  Ordinarily, the abstract
+value is simply rounded and packed into the single-precision format, with
+the inexact exception raised if the abstract input cannot be represented
+exactly.  If the abstract value is too large, however, the overflow and
+inexact exceptions are raised and an infinity or maximal finite value is
+returned.  If the abstract value is too small, the input value is rounded to
+a subnormal number, and the underflow and inexact exceptions are raised if
+the abstract input cannot be represented exactly as a subnormal single-
+precision floating-point number.
+    The input significand `zSig' has its binary point between bits 30
+and 29, which is 7 bits to the left of the usual location.  This shifted
+significand must be normalized or smaller.  If `zSig' is not normalized,
+`zExp' must be 0; in that case, the result returned is a subnormal number,
+and it must not require rounding.  In the usual case that `zSig' is
+normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
+The handling of underflow and overflow follows the IEC/IEEE Standard for
+Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
+{
+    int8 roundingMode;
+    flag roundNearestEven;
+    int8 roundIncrement, roundBits;
+    flag isTiny;
+
+    roundingMode = float_rounding_mode;
+    roundNearestEven = ( roundingMode == float_round_nearest_even );
+    roundIncrement = 0x40;
+    if ( ! roundNearestEven ) {
+        if ( roundingMode == float_round_to_zero ) {
+            roundIncrement = 0;
+        }
+        else {
+            roundIncrement = 0x7F;
+            if ( zSign ) {
+                if ( roundingMode == float_round_up ) roundIncrement = 0;
+            }
+            else {
+                if ( roundingMode == float_round_down ) roundIncrement = 0;
+            }
+        }
+    }
+    roundBits = zSig & 0x7F;
+    if ( 0xFD <= (bits16) zExp ) {
+        if (    ( 0xFD < zExp )
+             || (    ( zExp == 0xFD )
+                  && ( (sbits32) ( zSig + roundIncrement ) < 0 ) )
+           ) {
+            float_raise( float_flag_overflow | float_flag_inexact );
+            return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
+        }
+        if ( zExp < 0 ) {
+            isTiny =
+                   ( float_detect_tininess == float_tininess_before_rounding )
+                || ( zExp < -1 )
+                || ( zSig + roundIncrement < 0x80000000 );
+            shift32RightJamming( zSig, - zExp, &zSig );
+            zExp = 0;
+            roundBits = zSig & 0x7F;
+            if ( isTiny && roundBits ) float_raise( float_flag_underflow );
+        }
+    }
+    if ( roundBits ) float_exception_flags |= float_flag_inexact;
+    zSig = ( zSig + roundIncrement )>>7;
+    zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
+    if ( zSig == 0 ) zExp = 0;
+    return packFloat32( zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+and significand `zSig', and returns the proper single-precision floating-
+point value corresponding to the abstract input.  This routine is just like
+`roundAndPackFloat32' except that `zSig' does not have to be normalized in
+any way.  In all cases, `zExp' must be 1 less than the ``true'' floating-
+point exponent.
+-------------------------------------------------------------------------------
+*/
+static float32
+ normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
+{
+    int8 shiftCount;
+
+    shiftCount = countLeadingZeros32( zSig ) - 1;
+    return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the fraction bits of the double-precision floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE bits64 extractFloat64Frac( float64 a )
+{
+
+    return a & LIT64( 0x000FFFFFFFFFFFFF );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the exponent bits of the double-precision floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE int16 extractFloat64Exp( float64 a )
+{
+
+    return ( a>>52 ) & 0x7FF;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the sign bit of the double-precision floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE flag extractFloat64Sign( float64 a )
+{
+
+    return a>>63;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Normalizes the subnormal double-precision floating-point value represented
+by the denormalized significand `aSig'.  The normalized exponent and
+significand are stored at the locations pointed to by `zExpPtr' and
+`zSigPtr', respectively.
+-------------------------------------------------------------------------------
+*/
+static void
+ normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr )
+{
+    int8 shiftCount;
+
+    shiftCount = countLeadingZeros64( aSig ) - 11;
+    *zSigPtr = aSig<<shiftCount;
+    *zExpPtr = 1 - shiftCount;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
+double-precision floating-point value, returning the result.  After being
+shifted into the proper positions, the three fields are simply added
+together to form the result.  This means that any integer portion of `zSig'
+will be added into the exponent.  Since a properly normalized significand
+will have an integer portion equal to 1, the `zExp' input should be 1 less
+than the desired result exponent whenever `zSig' is a complete, normalized
+significand.
+-------------------------------------------------------------------------------
+*/
+INLINE float64 packFloat64( flag zSign, int16 zExp, bits64 zSig )
+{
+
+    return ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+and significand `zSig', and returns the proper double-precision floating-
+point value corresponding to the abstract input.  Ordinarily, the abstract
+value is simply rounded and packed into the double-precision format, with
+the inexact exception raised if the abstract input cannot be represented
+exactly.  If the abstract value is too large, however, the overflow and
+inexact exceptions are raised and an infinity or maximal finite value is
+returned.  If the abstract value is too small, the input value is rounded to
+a subnormal number, and the underflow and inexact exceptions are raised if
+the abstract input cannot be represented exactly as a subnormal double-
+precision floating-point number.
+    The input significand `zSig' has its binary point between bits 62
+and 61, which is 10 bits to the left of the usual location.  This shifted
+significand must be normalized or smaller.  If `zSig' is not normalized,
+`zExp' must be 0; in that case, the result returned is a subnormal number,
+and it must not require rounding.  In the usual case that `zSig' is
+normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
+The handling of underflow and overflow follows the IEC/IEEE Standard for
+Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
+{
+    int8 roundingMode;
+    flag roundNearestEven;
+    int16 roundIncrement, roundBits;
+    flag isTiny;
+
+    roundingMode = float_rounding_mode;
+    roundNearestEven = ( roundingMode == float_round_nearest_even );
+    roundIncrement = 0x200;
+    if ( ! roundNearestEven ) {
+        if ( roundingMode == float_round_to_zero ) {
+            roundIncrement = 0;
+        }
+        else {
+            roundIncrement = 0x3FF;
+            if ( zSign ) {
+                if ( roundingMode == float_round_up ) roundIncrement = 0;
+            }
+            else {
+                if ( roundingMode == float_round_down ) roundIncrement = 0;
+            }
+        }
+    }
+    roundBits = zSig & 0x3FF;
+    if ( 0x7FD <= (bits16) zExp ) {
+        if (    ( 0x7FD < zExp )
+             || (    ( zExp == 0x7FD )
+                  && ( (sbits64) ( zSig + roundIncrement ) < 0 ) )
+           ) {
+            //register int lr = __builtin_return_address(0);
+            //printk("roundAndPackFloat64 called from 0x%08x\n",lr);
+            float_raise( float_flag_overflow | float_flag_inexact );
+            return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 );
+        }
+        if ( zExp < 0 ) {
+            isTiny =
+                   ( float_detect_tininess == float_tininess_before_rounding )
+                || ( zExp < -1 )
+                || ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) );
+            shift64RightJamming( zSig, - zExp, &zSig );
+            zExp = 0;
+            roundBits = zSig & 0x3FF;
+            if ( isTiny && roundBits ) float_raise( float_flag_underflow );
+        }
+    }
+    if ( roundBits ) float_exception_flags |= float_flag_inexact;
+    zSig = ( zSig + roundIncrement )>>10;
+    zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
+    if ( zSig == 0 ) zExp = 0;
+    return packFloat64( zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+and significand `zSig', and returns the proper double-precision floating-
+point value corresponding to the abstract input.  This routine is just like
+`roundAndPackFloat64' except that `zSig' does not have to be normalized in
+any way.  In all cases, `zExp' must be 1 less than the ``true'' floating-
+point exponent.
+-------------------------------------------------------------------------------
+*/
+static float64
+ normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
+{
+    int8 shiftCount;
+
+    shiftCount = countLeadingZeros64( zSig ) - 1;
+    return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<<shiftCount );
+
+}
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+Returns the fraction bits of the extended double-precision floating-point
+value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE bits64 extractFloatx80Frac( floatx80 a )
+{
+
+    return a.low;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the exponent bits of the extended double-precision floating-point
+value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE int32 extractFloatx80Exp( floatx80 a )
+{
+
+    return a.high & 0x7FFF;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the sign bit of the extended double-precision floating-point value
+`a'.
+-------------------------------------------------------------------------------
+*/
+INLINE flag extractFloatx80Sign( floatx80 a )
+{
+
+    return a.high>>15;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Normalizes the subnormal extended double-precision floating-point value
+represented by the denormalized significand `aSig'.  The normalized exponent
+and significand are stored at the locations pointed to by `zExpPtr' and
+`zSigPtr', respectively.
+-------------------------------------------------------------------------------
+*/
+static void
+ normalizeFloatx80Subnormal( bits64 aSig, int32 *zExpPtr, bits64 *zSigPtr )
+{
+    int8 shiftCount;
+
+    shiftCount = countLeadingZeros64( aSig );
+    *zSigPtr = aSig<<shiftCount;
+    *zExpPtr = 1 - shiftCount;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
+extended double-precision floating-point value, returning the result.
+-------------------------------------------------------------------------------
+*/
+INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig )
+{
+    floatx80 z;
+
+    z.low = zSig;
+    z.high = ( ( (bits16) zSign )<<15 ) + zExp;
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+and extended significand formed by the concatenation of `zSig0' and `zSig1',
+and returns the proper extended double-precision floating-point value
+corresponding to the abstract input.  Ordinarily, the abstract value is
+rounded and packed into the extended double-precision format, with the
+inexact exception raised if the abstract input cannot be represented
+exactly.  If the abstract value is too large, however, the overflow and
+inexact exceptions are raised and an infinity or maximal finite value is
+returned.  If the abstract value is too small, the input value is rounded to
+a subnormal number, and the underflow and inexact exceptions are raised if
+the abstract input cannot be represented exactly as a subnormal extended
+double-precision floating-point number.
+    If `roundingPrecision' is 32 or 64, the result is rounded to the same
+number of bits as single or double precision, respectively.  Otherwise, the
+result is rounded to the full precision of the extended double-precision
+format.
+    The input significand must be normalized or smaller.  If the input
+significand is not normalized, `zExp' must be 0; in that case, the result
+returned is a subnormal number, and it must not require rounding.  The
+handling of underflow and overflow follows the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static floatx80
+ roundAndPackFloatx80(
+     int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
+ )
+{
+    int8 roundingMode;
+    flag roundNearestEven, increment, isTiny;
+    int64 roundIncrement, roundMask, roundBits;
+
+    roundingMode = float_rounding_mode;
+    roundNearestEven = ( roundingMode == float_round_nearest_even );
+    if ( roundingPrecision == 80 ) goto precision80;
+    if ( roundingPrecision == 64 ) {
+        roundIncrement = LIT64( 0x0000000000000400 );
+        roundMask = LIT64( 0x00000000000007FF );
+    }
+    else if ( roundingPrecision == 32 ) {
+        roundIncrement = LIT64( 0x0000008000000000 );
+        roundMask = LIT64( 0x000000FFFFFFFFFF );
+    }
+    else {
+        goto precision80;
+    }
+    zSig0 |= ( zSig1 != 0 );
+    if ( ! roundNearestEven ) {
+        if ( roundingMode == float_round_to_zero ) {
+            roundIncrement = 0;
+        }
+        else {
+            roundIncrement = roundMask;
+            if ( zSign ) {
+                if ( roundingMode == float_round_up ) roundIncrement = 0;
+            }
+            else {
+                if ( roundingMode == float_round_down ) roundIncrement = 0;
+            }
+        }
+    }
+    roundBits = zSig0 & roundMask;
+    if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
+        if (    ( 0x7FFE < zExp )
+             || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
+           ) {
+            goto overflow;
+        }
+        if ( zExp <= 0 ) {
+            isTiny =
+                   ( float_detect_tininess == float_tininess_before_rounding )
+                || ( zExp < 0 )
+                || ( zSig0 <= zSig0 + roundIncrement );
+            shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
+            zExp = 0;
+            roundBits = zSig0 & roundMask;
+            if ( isTiny && roundBits ) float_raise( float_flag_underflow );
+            if ( roundBits ) float_exception_flags |= float_flag_inexact;
+            zSig0 += roundIncrement;
+            if ( (sbits64) zSig0 < 0 ) zExp = 1;
+            roundIncrement = roundMask + 1;
+            if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
+                roundMask |= roundIncrement;
+            }
+            zSig0 &= ~ roundMask;
+            return packFloatx80( zSign, zExp, zSig0 );
+        }
+    }
+    if ( roundBits ) float_exception_flags |= float_flag_inexact;
+    zSig0 += roundIncrement;
+    if ( zSig0 < roundIncrement ) {
+        ++zExp;
+        zSig0 = LIT64( 0x8000000000000000 );
+    }
+    roundIncrement = roundMask + 1;
+    if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
+        roundMask |= roundIncrement;
+    }
+    zSig0 &= ~ roundMask;
+    if ( zSig0 == 0 ) zExp = 0;
+    return packFloatx80( zSign, zExp, zSig0 );
+ precision80:
+    increment = ( (sbits64) zSig1 < 0 );
+    if ( ! roundNearestEven ) {
+        if ( roundingMode == float_round_to_zero ) {
+            increment = 0;
+        }
+        else {
+            if ( zSign ) {
+                increment = ( roundingMode == float_round_down ) && zSig1;
+            }
+            else {
+                increment = ( roundingMode == float_round_up ) && zSig1;
+            }
+        }
+    }
+    if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
+        if (    ( 0x7FFE < zExp )
+             || (    ( zExp == 0x7FFE )
+                  && ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) )
+                  && increment
+                )
+           ) {
+            roundMask = 0;
+ overflow:
+            float_raise( float_flag_overflow | float_flag_inexact );
+            if (    ( roundingMode == float_round_to_zero )
+                 || ( zSign && ( roundingMode == float_round_up ) )
+                 || ( ! zSign && ( roundingMode == float_round_down ) )
+               ) {
+                return packFloatx80( zSign, 0x7FFE, ~ roundMask );
+            }
+            return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+        }
+        if ( zExp <= 0 ) {
+            isTiny =
+                   ( float_detect_tininess == float_tininess_before_rounding )
+                || ( zExp < 0 )
+                || ! increment
+                || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
+            shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
+            zExp = 0;
+            if ( isTiny && zSig1 ) float_raise( float_flag_underflow );
+            if ( zSig1 ) float_exception_flags |= float_flag_inexact;
+            if ( roundNearestEven ) {
+                increment = ( (sbits64) zSig1 < 0 );
+            }
+            else {
+                if ( zSign ) {
+                    increment = ( roundingMode == float_round_down ) && zSig1;
+                }
+                else {
+                    increment = ( roundingMode == float_round_up ) && zSig1;
+                }
+            }
+            if ( increment ) {
+                ++zSig0;
+                zSig0 &= ~ ( ( zSig1 + zSig1 == 0 ) & roundNearestEven );
+                if ( (sbits64) zSig0 < 0 ) zExp = 1;
+            }
+            return packFloatx80( zSign, zExp, zSig0 );
+        }
+    }
+    if ( zSig1 ) float_exception_flags |= float_flag_inexact;
+    if ( increment ) {
+        ++zSig0;
+        if ( zSig0 == 0 ) {
+            ++zExp;
+            zSig0 = LIT64( 0x8000000000000000 );
+        }
+        else {
+            zSig0 &= ~ ( ( zSig1 + zSig1 == 0 ) & roundNearestEven );
+        }
+    }
+    else {
+        if ( zSig0 == 0 ) zExp = 0;
+    }
+    
+    return packFloatx80( zSign, zExp, zSig0 );
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes an abstract floating-point value having sign `zSign', exponent
+`zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
+and returns the proper extended double-precision floating-point value
+corresponding to the abstract input.  This routine is just like
+`roundAndPackFloatx80' except that the input significand does not have to be
+normalized.
+-------------------------------------------------------------------------------
+*/
+static floatx80
+ normalizeRoundAndPackFloatx80(
+     int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
+ )
+{
+    int8 shiftCount;
+
+    if ( zSig0 == 0 ) {
+        zSig0 = zSig1;
+        zSig1 = 0;
+        zExp -= 64;
+    }
+    shiftCount = countLeadingZeros64( zSig0 );
+    shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
+    zExp -= shiftCount;
+    return
+        roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1 );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+/*
+-------------------------------------------------------------------------------
+Returns the least-significant 64 fraction bits of the quadruple-precision
+floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE bits64 extractFloat128Frac1( float128 a )
+{
+
+    return a.low;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the most-significant 48 fraction bits of the quadruple-precision
+floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE bits64 extractFloat128Frac0( float128 a )
+{
+
+    return a.high & LIT64( 0x0000FFFFFFFFFFFF );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the exponent bits of the quadruple-precision floating-point value
+`a'.
+-------------------------------------------------------------------------------
+*/
+INLINE int32 extractFloat128Exp( float128 a )
+{
+
+    return ( a.high>>48 ) & 0x7FFF;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the sign bit of the quadruple-precision floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE flag extractFloat128Sign( float128 a )
+{
+
+    return a.high>>63;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Normalizes the subnormal quadruple-precision floating-point value
+represented by the denormalized significand formed by the concatenation of
+`aSig0' and `aSig1'.  The normalized exponent is stored at the location
+pointed to by `zExpPtr'.  The most significant 49 bits of the normalized
+significand are stored at the location pointed to by `zSig0Ptr', and the
+least significant 64 bits of the normalized significand are stored at the
+location pointed to by `zSig1Ptr'.
+-------------------------------------------------------------------------------
+*/
+static void
+ normalizeFloat128Subnormal(
+     bits64 aSig0,
+     bits64 aSig1,
+     int32 *zExpPtr,
+     bits64 *zSig0Ptr,
+     bits64 *zSig1Ptr
+ )
+{
+    int8 shiftCount;
+
+    if ( aSig0 == 0 ) {
+        shiftCount = countLeadingZeros64( aSig1 ) - 15;
+        if ( shiftCount < 0 ) {
+            *zSig0Ptr = aSig1>>( - shiftCount );
+            *zSig1Ptr = aSig1<<( shiftCount & 63 );
+        }
+        else {
+            *zSig0Ptr = aSig1<<shiftCount;
+            *zSig1Ptr = 0;
+        }
+        *zExpPtr = - shiftCount - 63;
+    }
+    else {
+        shiftCount = countLeadingZeros64( aSig0 ) - 15;
+        shortShift128Left( aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr );
+        *zExpPtr = 1 - shiftCount;
+    }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Packs the sign `zSign', the exponent `zExp', and the significand formed
+by the concatenation of `zSig0' and `zSig1' into a quadruple-precision
+floating-point value, returning the result.  After being shifted into the
+proper positions, the three fields `zSign', `zExp', and `zSig0' are simply
+added together to form the most significant 32 bits of the result.  This
+means that any integer portion of `zSig0' will be added into the exponent.
+Since a properly normalized significand will have an integer portion equal
+to 1, the `zExp' input should be 1 less than the desired result exponent
+whenever `zSig0' and `zSig1' concatenated form a complete, normalized
+significand.
+-------------------------------------------------------------------------------
+*/
+INLINE float128
+ packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 )
+{
+    float128 z;
+
+    z.low = zSig1;
+    z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0;
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+and extended significand formed by the concatenation of `zSig0', `zSig1',
+and `zSig2', and returns the proper quadruple-precision floating-point value
+corresponding to the abstract input.  Ordinarily, the abstract value is
+simply rounded and packed into the quadruple-precision format, with the
+inexact exception raised if the abstract input cannot be represented
+exactly.  If the abstract value is too large, however, the overflow and
+inexact exceptions are raised and an infinity or maximal finite value is
+returned.  If the abstract value is too small, the input value is rounded to
+a subnormal number, and the underflow and inexact exceptions are raised if
+the abstract input cannot be represented exactly as a subnormal quadruple-
+precision floating-point number.
+    The input significand must be normalized or smaller.  If the input
+significand is not normalized, `zExp' must be 0; in that case, the result
+returned is a subnormal number, and it must not require rounding.  In the
+usual case that the input significand is normalized, `zExp' must be 1 less
+than the ``true'' floating-point exponent.  The handling of underflow and
+overflow follows the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float128
+ roundAndPackFloat128(
+     flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 )
+{
+    int8 roundingMode;
+    flag roundNearestEven, increment, isTiny;
+
+    roundingMode = float_rounding_mode;
+    roundNearestEven = ( roundingMode == float_round_nearest_even );
+    increment = ( (sbits64) zSig2 < 0 );
+    if ( ! roundNearestEven ) {
+        if ( roundingMode == float_round_to_zero ) {
+            increment = 0;
+        }
+        else {
+            if ( zSign ) {
+                increment = ( roundingMode == float_round_down ) && zSig2;
+            }
+            else {
+                increment = ( roundingMode == float_round_up ) && zSig2;
+            }
+        }
+    }
+    if ( 0x7FFD <= (bits32) zExp ) {
+        if (    ( 0x7FFD < zExp )
+             || (    ( zExp == 0x7FFD )
+                  && eq128(
+                         LIT64( 0x0001FFFFFFFFFFFF ),
+                         LIT64( 0xFFFFFFFFFFFFFFFF ),
+                         zSig0,
+                         zSig1
+                     )
+                  && increment
+                )
+           ) {
+            float_raise( float_flag_overflow | float_flag_inexact );
+            if (    ( roundingMode == float_round_to_zero )
+                 || ( zSign && ( roundingMode == float_round_up ) )
+                 || ( ! zSign && ( roundingMode == float_round_down ) )
+               ) {
+                return
+                    packFloat128(
+                        zSign,
+                        0x7FFE,
+                        LIT64( 0x0000FFFFFFFFFFFF ),
+                        LIT64( 0xFFFFFFFFFFFFFFFF )
+                    );
+            }
+            return packFloat128( zSign, 0x7FFF, 0, 0 );
+        }
+        if ( zExp < 0 ) {
+            isTiny =
+                   ( float_detect_tininess == float_tininess_before_rounding )
+                || ( zExp < -1 )
+                || ! increment
+                || lt128(
+                       zSig0,
+                       zSig1,
+                       LIT64( 0x0001FFFFFFFFFFFF ),
+                       LIT64( 0xFFFFFFFFFFFFFFFF )
+                   );
+            shift128ExtraRightJamming(
+                zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 );
+            zExp = 0;
+            if ( isTiny && zSig2 ) float_raise( float_flag_underflow );
+            if ( roundNearestEven ) {
+                increment = ( (sbits64) zSig2 < 0 );
+            }
+            else {
+                if ( zSign ) {
+                    increment = ( roundingMode == float_round_down ) && zSig2;
+                }
+                else {
+                    increment = ( roundingMode == float_round_up ) && zSig2;
+                }
+            }
+        }
+    }
+    if ( zSig2 ) float_exception_flags |= float_flag_inexact;
+    if ( increment ) {
+        add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 );
+        zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven );
+    }
+    else {
+        if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0;
+    }
+    return packFloat128( zSign, zExp, zSig0, zSig1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+and significand formed by the concatenation of `zSig0' and `zSig1', and
+returns the proper quadruple-precision floating-point value corresponding to
+the abstract input.  This routine is just like `roundAndPackFloat128' except
+that the input significand has fewer bits and does not have to be normalized
+in any way.  In all cases, `zExp' must be 1 less than the ``true'' floating-
+point exponent.
+-------------------------------------------------------------------------------
+*/
+static float128
+ normalizeRoundAndPackFloat128(
+     flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 )
+{
+    int8 shiftCount;
+    bits64 zSig2;
+
+    if ( zSig0 == 0 ) {
+        zSig0 = zSig1;
+        zSig1 = 0;
+        zExp -= 64;
+    }
+    shiftCount = countLeadingZeros64( zSig0 ) - 15;
+    if ( 0 <= shiftCount ) {
+        zSig2 = 0;
+        shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
+    }
+    else {
+        shift128ExtraRightJamming(
+            zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 );
+    }
+    zExp -= shiftCount;
+    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
+
+}
+
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the 32-bit two's complement integer `a' to
+the single-precision floating-point format.  The conversion is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 int32_to_float32( int32 a )
+{
+    flag zSign;
+
+    if ( a == 0 ) return 0;
+    if ( a == 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
+    zSign = ( a < 0 );
+    return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the 32-bit two's complement integer `a' to
+the double-precision floating-point format.  The conversion is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 int32_to_float64( int32 a )
+{
+    flag aSign;
+    uint32 absA;
+    int8 shiftCount;
+    bits64 zSig;
+
+    if ( a == 0 ) return 0;
+    aSign = ( a < 0 );
+    absA = aSign ? - a : a;
+    shiftCount = countLeadingZeros32( absA ) + 21;
+    zSig = absA;
+    return packFloat64( aSign, 0x432 - shiftCount, zSig<<shiftCount );
+
+}
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the 32-bit two's complement integer `a'
+to the extended double-precision floating-point format.  The conversion
+is performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 int32_to_floatx80( int32 a )
+{
+    flag zSign;
+    uint32 absA;
+    int8 shiftCount;
+    bits64 zSig;
+
+    if ( a == 0 ) return packFloatx80( 0, 0, 0 );
+    zSign = ( a < 0 );
+    absA = zSign ? - a : a;
+    shiftCount = countLeadingZeros32( absA ) + 32;
+    zSig = absA;
+    return packFloatx80( zSign, 0x403E - shiftCount, zSig<<shiftCount );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the 32-bit two's complement integer `a' to
+the quadruple-precision floating-point format.  The conversion is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float128 int32_to_float128( int32 a )
+{
+    flag zSign;
+    uint32 absA;
+    int8 shiftCount;
+    bits64 zSig0;
+
+    if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
+    zSign = ( a < 0 );
+    absA = zSign ? - a : a;
+    shiftCount = countLeadingZeros32( absA ) + 17;
+    zSig0 = absA;
+    return packFloat128( zSign, 0x402E - shiftCount, zSig0<<shiftCount, 0 );
+
+}
+
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the single-precision floating-point value
+`a' to the 32-bit two's complement integer format.  The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic---which means in particular that the conversion is rounded
+according to the current rounding mode.  If `a' is a NaN, the largest
+positive integer is returned.  Otherwise, if the conversion overflows, the
+largest integer with the same sign as `a' is returned.
+-------------------------------------------------------------------------------
+*/
+int32 float32_to_int32( float32 a )
+{
+    flag aSign;
+    int16 aExp, shiftCount;
+    bits32 aSig;
+    bits64 zSig;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    aSign = extractFloat32Sign( a );
+    if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
+    if ( aExp ) aSig |= 0x00800000;
+    shiftCount = 0xAF - aExp;
+    zSig = aSig;
+    zSig <<= 32;
+    if ( 0 < shiftCount ) shift64RightJamming( zSig, shiftCount, &zSig );
+    return roundAndPackInt32( aSign, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the single-precision floating-point value
+`a' to the 32-bit two's complement integer format.  The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic, except that the conversion is always rounded toward zero.  If
+`a' is a NaN, the largest positive integer is returned.  Otherwise, if the
+conversion overflows, the largest integer with the same sign as `a' is
+returned.
+-------------------------------------------------------------------------------
+*/
+int32 float32_to_int32_round_to_zero( float32 a )
+{
+    flag aSign;
+    int16 aExp, shiftCount;
+    bits32 aSig;
+    int32 z;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    aSign = extractFloat32Sign( a );
+    shiftCount = aExp - 0x9E;
+    if ( 0 <= shiftCount ) {
+        if ( a == 0xCF000000 ) return 0x80000000;
+        float_raise( float_flag_invalid );
+        if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
+        return 0x80000000;
+    }
+    else if ( aExp <= 0x7E ) {
+        if ( aExp | aSig ) float_exception_flags |= float_flag_inexact;
+        return 0;
+    }
+    aSig = ( aSig | 0x00800000 )<<8;
+    z = aSig>>( - shiftCount );
+    if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) {
+        float_exception_flags |= float_flag_inexact;
+    }
+    return aSign ? - z : z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the single-precision floating-point value
+`a' to the double-precision floating-point format.  The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float32_to_float64( float32 a )
+{
+    flag aSign;
+    int16 aExp;
+    bits32 aSig;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    aSign = extractFloat32Sign( a );
+    if ( aExp == 0xFF ) {
+        if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) );
+        return packFloat64( aSign, 0x7FF, 0 );
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return packFloat64( aSign, 0, 0 );
+        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
+        --aExp;
+    }
+    return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 );
+
+}
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the single-precision floating-point value
+`a' to the extended double-precision floating-point format.  The conversion
+is performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 float32_to_floatx80( float32 a )
+{
+    flag aSign;
+    int16 aExp;
+    bits32 aSig;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    aSign = extractFloat32Sign( a );
+    if ( aExp == 0xFF ) {
+        if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a ) );
+        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
+        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
+    }
+    aSig |= 0x00800000;
+    return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the single-precision floating-point value
+`a' to the double-precision floating-point format.  The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float128 float32_to_float128( float32 a )
+{
+    flag aSign;
+    int16 aExp;
+    bits32 aSig;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    aSign = extractFloat32Sign( a );
+    if ( aExp == 0xFF ) {
+        if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a ) );
+        return packFloat128( aSign, 0x7FFF, 0, 0 );
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
+        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
+        --aExp;
+    }
+    return packFloat128( aSign, aExp + 0x3F80, ( (bits64) aSig )<<25, 0 );
+
+}
+
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Rounds the single-precision floating-point value `a' to an integer, and
+returns the result as a single-precision floating-point value.  The
+operation is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_round_to_int( float32 a )
+{
+    flag aSign;
+    int16 aExp;
+    bits32 lastBitMask, roundBitsMask;
+    int8 roundingMode;
+    float32 z;
+
+    aExp = extractFloat32Exp( a );
+    if ( 0x96 <= aExp ) {
+        if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) {
+            return propagateFloat32NaN( a, a );
+        }
+        return a;
+    }
+    if ( aExp <= 0x7E ) {
+        if ( (bits32) ( a<<1 ) == 0 ) return a;
+        float_exception_flags |= float_flag_inexact;
+        aSign = extractFloat32Sign( a );
+        switch ( float_rounding_mode ) {
+         case float_round_nearest_even:
+            if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
+                return packFloat32( aSign, 0x7F, 0 );
+            }
+            break;
+         case float_round_down:
+            return aSign ? 0xBF800000 : 0;
+         case float_round_up:
+            return aSign ? 0x80000000 : 0x3F800000;
+        }
+        return packFloat32( aSign, 0, 0 );
+    }
+    lastBitMask = 1;
+    lastBitMask <<= 0x96 - aExp;
+    roundBitsMask = lastBitMask - 1;
+    z = a;
+    roundingMode = float_rounding_mode;
+    if ( roundingMode == float_round_nearest_even ) {
+        z += lastBitMask>>1;
+        if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
+    }
+    else if ( roundingMode != float_round_to_zero ) {
+        if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) {
+            z += roundBitsMask;
+        }
+    }
+    z &= ~ roundBitsMask;
+    if ( z != a ) float_exception_flags |= float_flag_inexact;
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of adding the absolute values of the single-precision
+floating-point values `a' and `b'.  If `zSign' is true, the sum is negated
+before being returned.  `zSign' is ignored if the result is a NaN.  The
+addition is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float32 addFloat32Sigs( float32 a, float32 b, flag zSign )
+{
+    int16 aExp, bExp, zExp;
+    bits32 aSig, bSig, zSig;
+    int16 expDiff;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    bSig = extractFloat32Frac( b );
+    bExp = extractFloat32Exp( b );
+    expDiff = aExp - bExp;
+    aSig <<= 6;
+    bSig <<= 6;
+    if ( 0 < expDiff ) {
+        if ( aExp == 0xFF ) {
+            if ( aSig ) return propagateFloat32NaN( a, b );
+            return a;
+        }
+        if ( bExp == 0 ) {
+            --expDiff;
+        }
+        else {
+            bSig |= 0x20000000;
+        }
+        shift32RightJamming( bSig, expDiff, &bSig );
+        zExp = aExp;
+    }
+    else if ( expDiff < 0 ) {
+        if ( bExp == 0xFF ) {
+            if ( bSig ) return propagateFloat32NaN( a, b );
+            return packFloat32( zSign, 0xFF, 0 );
+        }
+        if ( aExp == 0 ) {
+            ++expDiff;
+        }
+        else {
+            aSig |= 0x20000000;
+        }
+        shift32RightJamming( aSig, - expDiff, &aSig );
+        zExp = bExp;
+    }
+    else {
+        if ( aExp == 0xFF ) {
+            if ( aSig | bSig ) return propagateFloat32NaN( a, b );
+            return a;
+        }
+        if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
+        zSig = 0x40000000 + aSig + bSig;
+        zExp = aExp;
+        goto roundAndPack;
+    }
+    aSig |= 0x20000000;
+    zSig = ( aSig + bSig )<<1;
+    --zExp;
+    if ( (sbits32) zSig < 0 ) {
+        zSig = aSig + bSig;
+        ++zExp;
+    }
+ roundAndPack:
+    return roundAndPackFloat32( zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of subtracting the absolute values of the single-
+precision floating-point values `a' and `b'.  If `zSign' is true, the
+difference is negated before being returned.  `zSign' is ignored if the
+result is a NaN.  The subtraction is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
+{
+    int16 aExp, bExp, zExp;
+    bits32 aSig, bSig, zSig;
+    int16 expDiff;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    bSig = extractFloat32Frac( b );
+    bExp = extractFloat32Exp( b );
+    expDiff = aExp - bExp;
+    aSig <<= 7;
+    bSig <<= 7;
+    if ( 0 < expDiff ) goto aExpBigger;
+    if ( expDiff < 0 ) goto bExpBigger;
+    if ( aExp == 0xFF ) {
+        if ( aSig | bSig ) return propagateFloat32NaN( a, b );
+        float_raise( float_flag_invalid );
+        return float32_default_nan;
+    }
+    if ( aExp == 0 ) {
+        aExp = 1;
+        bExp = 1;
+    }
+    if ( bSig < aSig ) goto aBigger;
+    if ( aSig < bSig ) goto bBigger;
+    return packFloat32( float_rounding_mode == float_round_down, 0, 0 );
+ bExpBigger:
+    if ( bExp == 0xFF ) {
+        if ( bSig ) return propagateFloat32NaN( a, b );
+        return packFloat32( zSign ^ 1, 0xFF, 0 );
+    }
+    if ( aExp == 0 ) {
+        ++expDiff;
+    }
+    else {
+        aSig |= 0x40000000;
+    }
+    shift32RightJamming( aSig, - expDiff, &aSig );
+    bSig |= 0x40000000;
+ bBigger:
+    zSig = bSig - aSig;
+    zExp = bExp;
+    zSign ^= 1;
+    goto normalizeRoundAndPack;
+ aExpBigger:
+    if ( aExp == 0xFF ) {
+        if ( aSig ) return propagateFloat32NaN( a, b );
+        return a;
+    }
+    if ( bExp == 0 ) {
+        --expDiff;
+    }
+    else {
+        bSig |= 0x40000000;
+    }
+    shift32RightJamming( bSig, expDiff, &bSig );
+    aSig |= 0x40000000;
+ aBigger:
+    zSig = aSig - bSig;
+    zExp = aExp;
+ normalizeRoundAndPack:
+    --zExp;
+    return normalizeRoundAndPackFloat32( zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of adding the single-precision floating-point values `a'
+and `b'.  The operation is performed according to the IEC/IEEE Standard for
+Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_add( float32 a, float32 b )
+{
+    flag aSign, bSign;
+
+    aSign = extractFloat32Sign( a );
+    bSign = extractFloat32Sign( b );
+    if ( aSign == bSign ) {
+        return addFloat32Sigs( a, b, aSign );
+    }
+    else {
+        return subFloat32Sigs( a, b, aSign );
+    }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of subtracting the single-precision floating-point values
+`a' and `b'.  The operation is performed according to the IEC/IEEE Standard
+for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_sub( float32 a, float32 b )
+{
+    flag aSign, bSign;
+
+    aSign = extractFloat32Sign( a );
+    bSign = extractFloat32Sign( b );
+    if ( aSign == bSign ) {
+        return subFloat32Sigs( a, b, aSign );
+    }
+    else {
+        return addFloat32Sigs( a, b, aSign );
+    }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of multiplying the single-precision floating-point values
+`a' and `b'.  The operation is performed according to the IEC/IEEE Standard
+for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_mul( float32 a, float32 b )
+{
+    flag aSign, bSign, zSign;
+    int16 aExp, bExp, zExp;
+    bits32 aSig, bSig;
+    bits64 zSig64;
+    bits32 zSig;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    aSign = extractFloat32Sign( a );
+    bSig = extractFloat32Frac( b );
+    bExp = extractFloat32Exp( b );
+    bSign = extractFloat32Sign( b );
+    zSign = aSign ^ bSign;
+    if ( aExp == 0xFF ) {
+        if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
+            return propagateFloat32NaN( a, b );
+        }
+        if ( ( bExp | bSig ) == 0 ) {
+            float_raise( float_flag_invalid );
+            return float32_default_nan;
+        }
+        return packFloat32( zSign, 0xFF, 0 );
+    }
+    if ( bExp == 0xFF ) {
+        if ( bSig ) return propagateFloat32NaN( a, b );
+        if ( ( aExp | aSig ) == 0 ) {
+            float_raise( float_flag_invalid );
+            return float32_default_nan;
+        }
+        return packFloat32( zSign, 0xFF, 0 );
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
+        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
+    }
+    if ( bExp == 0 ) {
+        if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
+        normalizeFloat32Subnormal( bSig, &bExp, &bSig );
+    }
+    zExp = aExp + bExp - 0x7F;
+    aSig = ( aSig | 0x00800000 )<<7;
+    bSig = ( bSig | 0x00800000 )<<8;
+    shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 );
+    zSig = zSig64;
+    if ( 0 <= (sbits32) ( zSig<<1 ) ) {
+        zSig <<= 1;
+        --zExp;
+    }
+    return roundAndPackFloat32( zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of dividing the single-precision floating-point value `a'
+by the corresponding value `b'.  The operation is performed according to the
+IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_div( float32 a, float32 b )
+{
+    flag aSign, bSign, zSign;
+    int16 aExp, bExp, zExp;
+    bits32 aSig, bSig, zSig;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    aSign = extractFloat32Sign( a );
+    bSig = extractFloat32Frac( b );
+    bExp = extractFloat32Exp( b );
+    bSign = extractFloat32Sign( b );
+    zSign = aSign ^ bSign;
+    if ( aExp == 0xFF ) {
+        if ( aSig ) return propagateFloat32NaN( a, b );
+        if ( bExp == 0xFF ) {
+            if ( bSig ) return propagateFloat32NaN( a, b );
+            float_raise( float_flag_invalid );
+            return float32_default_nan;
+        }
+        return packFloat32( zSign, 0xFF, 0 );
+    }
+    if ( bExp == 0xFF ) {
+        if ( bSig ) return propagateFloat32NaN( a, b );
+        return packFloat32( zSign, 0, 0 );
+    }
+    if ( bExp == 0 ) {
+        if ( bSig == 0 ) {
+            if ( ( aExp | aSig ) == 0 ) {
+                float_raise( float_flag_invalid );
+                return float32_default_nan;
+            }
+            float_raise( float_flag_divbyzero );
+            return packFloat32( zSign, 0xFF, 0 );
+        }
+        normalizeFloat32Subnormal( bSig, &bExp, &bSig );
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
+        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
+    }
+    zExp = aExp - bExp + 0x7D;
+    aSig = ( aSig | 0x00800000 )<<7;
+    bSig = ( bSig | 0x00800000 )<<8;
+    if ( bSig <= ( aSig + aSig ) ) {
+        aSig >>= 1;
+        ++zExp;
+    }
+    zSig = ( ( (bits64) aSig )<<32 ) / bSig;
+    if ( ( zSig & 0x3F ) == 0 ) {
+        zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 );
+    }
+    return roundAndPackFloat32( zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the remainder of the single-precision floating-point value `a'
+with respect to the corresponding value `b'.  The operation is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_rem( float32 a, float32 b )
+{
+    flag aSign, bSign, zSign;
+    int16 aExp, bExp, expDiff;
+    bits32 aSig, bSig;
+    bits32 q;
+    bits64 aSig64, bSig64, q64;
+    bits32 alternateASig;
+    sbits32 sigMean;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    aSign = extractFloat32Sign( a );
+    bSig = extractFloat32Frac( b );
+    bExp = extractFloat32Exp( b );
+    bSign = extractFloat32Sign( b );
+    if ( aExp == 0xFF ) {
+        if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
+            return propagateFloat32NaN( a, b );
+        }
+        float_raise( float_flag_invalid );
+        return float32_default_nan;
+    }
+    if ( bExp == 0xFF ) {
+        if ( bSig ) return propagateFloat32NaN( a, b );
+        return a;
+    }
+    if ( bExp == 0 ) {
+        if ( bSig == 0 ) {
+            float_raise( float_flag_invalid );
+            return float32_default_nan;
+        }
+        normalizeFloat32Subnormal( bSig, &bExp, &bSig );
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return a;
+        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
+    }
+    expDiff = aExp - bExp;
+    aSig |= 0x00800000;
+    bSig |= 0x00800000;
+    if ( expDiff < 32 ) {
+        aSig <<= 8;
+        bSig <<= 8;
+        if ( expDiff < 0 ) {
+            if ( expDiff < -1 ) return a;
+            aSig >>= 1;
+        }
+        q = ( bSig <= aSig );
+        if ( q ) aSig -= bSig;
+        if ( 0 < expDiff ) {
+            q = ( ( (bits64) aSig )<<32 ) / bSig;
+            q >>= 32 - expDiff;
+            bSig >>= 2;
+            aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
+        }
+        else {
+            aSig >>= 2;
+            bSig >>= 2;
+        }
+    }
+    else {
+        if ( bSig <= aSig ) aSig -= bSig;
+        aSig64 = ( (bits64) aSig )<<40;
+        bSig64 = ( (bits64) bSig )<<40;
+        expDiff -= 64;
+        while ( 0 < expDiff ) {
+            q64 = estimateDiv128To64( aSig64, 0, bSig64 );
+            q64 = ( 2 < q64 ) ? q64 - 2 : 0;
+            aSig64 = - ( ( bSig * q64 )<<38 );
+            expDiff -= 62;
+        }
+        expDiff += 64;
+        q64 = estimateDiv128To64( aSig64, 0, bSig64 );
+        q64 = ( 2 < q64 ) ? q64 - 2 : 0;
+        q = q64>>( 64 - expDiff );
+        bSig <<= 6;
+        aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q;
+    }
+    do {
+        alternateASig = aSig;
+        ++q;
+        aSig -= bSig;
+    } while ( 0 <= (sbits32) aSig );
+    sigMean = aSig + alternateASig;
+    if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
+        aSig = alternateASig;
+    }
+    zSign = ( (sbits32) aSig < 0 );
+    if ( zSign ) aSig = - aSig;
+    return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the square root of the single-precision floating-point value `a'.
+The operation is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_sqrt( float32 a )
+{
+    flag aSign;
+    int16 aExp, zExp;
+    bits32 aSig, zSig;
+    bits64 rem, term;
+
+    aSig = extractFloat32Frac( a );
+    aExp = extractFloat32Exp( a );
+    aSign = extractFloat32Sign( a );
+    if ( aExp == 0xFF ) {
+        if ( aSig ) return propagateFloat32NaN( a, 0 );
+        if ( ! aSign ) return a;
+        float_raise( float_flag_invalid );
+        return float32_default_nan;
+    }
+    if ( aSign ) {
+        if ( ( aExp | aSig ) == 0 ) return a;
+        float_raise( float_flag_invalid );
+        return float32_default_nan;
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return 0;
+        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
+    }
+    zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;
+    aSig = ( aSig | 0x00800000 )<<8;
+    zSig = estimateSqrt32( aExp, aSig ) + 2;
+    if ( ( zSig & 0x7F ) <= 5 ) {
+        if ( zSig < 2 ) {
+            zSig = 0xFFFFFFFF;
+        }
+        else {
+            aSig >>= aExp & 1;
+            term = ( (bits64) zSig ) * zSig;
+            rem = ( ( (bits64) aSig )<<32 ) - term;
+            while ( (sbits64) rem < 0 ) {
+                --zSig;
+                rem += ( ( (bits64) zSig )<<1 ) | 1;
+            }
+            zSig |= ( rem != 0 );
+        }
+    }
+    shift32RightJamming( zSig, 1, &zSig );
+    return roundAndPackFloat32( 0, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is equal to the
+corresponding value `b', and 0 otherwise.  The comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float32_eq( float32 a, float32 b )
+{
+
+    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+       ) {
+        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid );
+        }
+        return 0;
+    }
+    return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is less than or
+equal to the corresponding value `b', and 0 otherwise.  The comparison is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float32_le( float32 a, float32 b )
+{
+    flag aSign, bSign;
+
+    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+       ) {
+        float_raise( float_flag_invalid );
+        return 0;
+    }
+    aSign = extractFloat32Sign( a );
+    bSign = extractFloat32Sign( b );
+    if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
+    return ( a == b ) || ( aSign ^ ( a < b ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is less than
+the corresponding value `b', and 0 otherwise.  The comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float32_lt( float32 a, float32 b )
+{
+    flag aSign, bSign;
+
+    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+       ) {
+        float_raise( float_flag_invalid );
+        return 0;
+    }
+    aSign = extractFloat32Sign( a );
+    bSign = extractFloat32Sign( b );
+    if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
+    return ( a != b ) && ( aSign ^ ( a < b ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is equal to the
+corresponding value `b', and 0 otherwise.  The invalid exception is raised
+if either operand is a NaN.  Otherwise, the comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float32_eq_signaling( float32 a, float32 b )
+{
+
+    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+       ) {
+        float_raise( float_flag_invalid );
+        return 0;
+    }
+    return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is less than or
+equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
+cause an exception.  Otherwise, the comparison is performed according to the
+IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float32_le_quiet( float32 a, float32 b )
+{
+    flag aSign, bSign;
+    //int16 aExp, bExp;
+
+    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+       ) {
+        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid );
+        }
+        return 0;
+    }
+    aSign = extractFloat32Sign( a );
+    bSign = extractFloat32Sign( b );
+    if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
+    return ( a == b ) || ( aSign ^ ( a < b ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is less than
+the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
+exception.  Otherwise, the comparison is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float32_lt_quiet( float32 a, float32 b )
+{
+    flag aSign, bSign;
+
+    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+       ) {
+        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid );
+        }
+        return 0;
+    }
+    aSign = extractFloat32Sign( a );
+    bSign = extractFloat32Sign( b );
+    if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
+    return ( a != b ) && ( aSign ^ ( a < b ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the double-precision floating-point value
+`a' to the 32-bit two's complement integer format.  The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic---which means in particular that the conversion is rounded
+according to the current rounding mode.  If `a' is a NaN, the largest
+positive integer is returned.  Otherwise, if the conversion overflows, the
+largest integer with the same sign as `a' is returned.
+-------------------------------------------------------------------------------
+*/
+int32 float64_to_int32( float64 a )
+{
+    flag aSign;
+    int16 aExp, shiftCount;
+    bits64 aSig;
+
+    aSig = extractFloat64Frac( a );
+    aExp = extractFloat64Exp( a );
+    aSign = extractFloat64Sign( a );
+    if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
+    if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
+    shiftCount = 0x42C - aExp;
+    if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
+    return roundAndPackInt32( aSign, aSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the double-precision floating-point value
+`a' to the 32-bit two's complement integer format.  The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic, except that the conversion is always rounded toward zero.  If
+`a' is a NaN, the largest positive integer is returned.  Otherwise, if the
+conversion overflows, the largest integer with the same sign as `a' is
+returned.
+-------------------------------------------------------------------------------
+*/
+int32 float64_to_int32_round_to_zero( float64 a )
+{
+    flag aSign;
+    int16 aExp, shiftCount;
+    bits64 aSig, savedASig;
+    int32 z;
+
+    aSig = extractFloat64Frac( a );
+    aExp = extractFloat64Exp( a );
+    aSign = extractFloat64Sign( a );
+    shiftCount = 0x433 - aExp;
+    if ( shiftCount < 21 ) {
+        if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
+        goto invalid;
+    }
+    else if ( 52 < shiftCount ) {
+        if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
+        return 0;
+    }
+    aSig |= LIT64( 0x0010000000000000 );
+    savedASig = aSig;
+    aSig >>= shiftCount;
+    z = aSig;
+    if ( aSign ) z = - z;
+    if ( ( z < 0 ) ^ aSign ) {
+ invalid:
+        float_exception_flags |= float_flag_invalid;
+        return aSign ? 0x80000000 : 0x7FFFFFFF;
+    }
+    if ( ( aSig<<shiftCount ) != savedASig ) {
+        float_exception_flags |= float_flag_inexact;
+    }
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the double-precision floating-point value
+`a' to the 32-bit two's complement unsigned integer format.  The conversion
+is performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic---which means in particular that the conversion is rounded
+according to the current rounding mode.  If `a' is a NaN, the largest
+positive integer is returned.  Otherwise, if the conversion overflows, the
+largest positive integer is returned.
+-------------------------------------------------------------------------------
+*/
+int32 float64_to_uint32( float64 a )
+{
+    flag aSign;
+    int16 aExp, shiftCount;
+    bits64 aSig;
+
+    aSig = extractFloat64Frac( a );
+    aExp = extractFloat64Exp( a );
+    aSign = 0; //extractFloat64Sign( a );
+    //if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
+    if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
+    shiftCount = 0x42C - aExp;
+    if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
+    return roundAndPackInt32( aSign, aSig );
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the double-precision floating-point value
+`a' to the 32-bit two's complement integer format.  The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic, except that the conversion is always rounded toward zero.  If
+`a' is a NaN, the largest positive integer is returned.  Otherwise, if the
+conversion overflows, the largest positive integer is returned.
+-------------------------------------------------------------------------------
+*/
+int32 float64_to_uint32_round_to_zero( float64 a )
+{
+    flag aSign;
+    int16 aExp, shiftCount;
+    bits64 aSig, savedASig;
+    int32 z;
+
+    aSig = extractFloat64Frac( a );
+    aExp = extractFloat64Exp( a );
+    aSign = extractFloat64Sign( a );
+    shiftCount = 0x433 - aExp;
+    if ( shiftCount < 21 ) {
+        if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
+        goto invalid;
+    }
+    else if ( 52 < shiftCount ) {
+        if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
+        return 0;
+    }
+    aSig |= LIT64( 0x0010000000000000 );
+    savedASig = aSig;
+    aSig >>= shiftCount;
+    z = aSig;
+    if ( aSign ) z = - z;
+    if ( ( z < 0 ) ^ aSign ) {
+ invalid:
+        float_exception_flags |= float_flag_invalid;
+        return aSign ? 0x80000000 : 0x7FFFFFFF;
+    }
+    if ( ( aSig<<shiftCount ) != savedASig ) {
+        float_exception_flags |= float_flag_inexact;
+    }
+    return z;
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the double-precision floating-point value
+`a' to the single-precision floating-point format.  The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float64_to_float32( float64 a )
+{
+    flag aSign;
+    int16 aExp;
+    bits64 aSig;
+    bits32 zSig;
+
+    aSig = extractFloat64Frac( a );
+    aExp = extractFloat64Exp( a );
+    aSign = extractFloat64Sign( a );
+    if ( aExp == 0x7FF ) {
+        if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a ) );
+        return packFloat32( aSign, 0xFF, 0 );
+    }
+    shift64RightJamming( aSig, 22, &aSig );
+    zSig = aSig;
+    if ( aExp || zSig ) {
+        zSig |= 0x40000000;
+        aExp -= 0x381;
+    }
+    return roundAndPackFloat32( aSign, aExp, zSig );
+
+}
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the double-precision floating-point value
+`a' to the extended double-precision floating-point format.  The conversion
+is performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 float64_to_floatx80( float64 a )
+{
+    flag aSign;
+    int16 aExp;
+    bits64 aSig;
+
+    aSig = extractFloat64Frac( a );
+    aExp = extractFloat64Exp( a );
+    aSign = extractFloat64Sign( a );
+    if ( aExp == 0x7FF ) {
+        if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a ) );
+        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
+        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
+    }
+    return
+        packFloatx80(
+            aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the double-precision floating-point value
+`a' to the quadruple-precision floating-point format.  The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float128 float64_to_float128( float64 a )
+{
+    flag aSign;
+    int16 aExp;
+    bits64 aSig, zSig0, zSig1;
+
+    aSig = extractFloat64Frac( a );
+    aExp = extractFloat64Exp( a );
+    aSign = extractFloat64Sign( a );
+    if ( aExp == 0x7FF ) {
+        if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a ) );
+        return packFloat128( aSign, 0x7FFF, 0, 0 );
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
+        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
+        --aExp;
+    }
+    shift128Right( aSig, 0, 4, &zSig0, &zSig1 );
+    return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 );
+
+}
+
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Rounds the double-precision floating-point value `a' to an integer, and
+returns the result as a double-precision floating-point value.  The
+operation is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float64_round_to_int( float64 a )
+{
+    flag aSign;
+    int16 aExp;
+    bits64 lastBitMask, roundBitsMask;
+    int8 roundingMode;
+    float64 z;
+
+    aExp = extractFloat64Exp( a );
+    if ( 0x433 <= aExp ) {
+        if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) {
+            return propagateFloat64NaN( a, a );
+        }
+        return a;
+    }
+    if ( aExp <= 0x3FE ) {
+        if ( (bits64) ( a<<1 ) == 0 ) return a;
+        float_exception_flags |= float_flag_inexact;
+        aSign = extractFloat64Sign( a );
+        switch ( float_rounding_mode ) {
+         case float_round_nearest_even:
+            if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) {
+                return packFloat64( aSign, 0x3FF, 0 );
+            }
+            break;
+         case float_round_down:
+            return aSign ? LIT64( 0xBFF0000000000000 ) : 0;
+         case float_round_up:
+            return
+            aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 );
+        }
+        return packFloat64( aSign, 0, 0 );
+    }
+    lastBitMask = 1;
+    lastBitMask <<= 0x433 - aExp;
+    roundBitsMask = lastBitMask - 1;
+    z = a;
+    roundingMode = float_rounding_mode;
+    if ( roundingMode == float_round_nearest_even ) {
+        z += lastBitMask>>1;
+        if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
+    }
+    else if ( roundingMode != float_round_to_zero ) {
+        if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) {
+            z += roundBitsMask;
+        }
+    }
+    z &= ~ roundBitsMask;
+    if ( z != a ) float_exception_flags |= float_flag_inexact;
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of adding the absolute values of the double-precision
+floating-point values `a' and `b'.  If `zSign' is true, the sum is negated
+before being returned.  `zSign' is ignored if the result is a NaN.  The
+addition is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float64 addFloat64Sigs( float64 a, float64 b, flag zSign )
+{
+    int16 aExp, bExp, zExp;
+    bits64 aSig, bSig, zSig;
+    int16 expDiff;
+
+    aSig = extractFloat64Frac( a );
+    aExp = extractFloat64Exp( a );
+    bSig = extractFloat64Frac( b );
+    bExp = extractFloat64Exp( b );
+    expDiff = aExp - bExp;
+    aSig <<= 9;
+    bSig <<= 9;
+    if ( 0 < expDiff ) {
+        if ( aExp == 0x7FF ) {
+            if ( aSig ) return propagateFloat64NaN( a, b );
+            return a;
+        }
+        if ( bExp == 0 ) {
+            --expDiff;
+        }
+        else {
+            bSig |= LIT64( 0x2000000000000000 );
+        }
+        shift64RightJamming( bSig, expDiff, &bSig );
+        zExp = aExp;
+    }
+    else if ( expDiff < 0 ) {
+        if ( bExp == 0x7FF ) {
+            if ( bSig ) return propagateFloat64NaN( a, b );
+            return packFloat64( zSign, 0x7FF, 0 );
+        }
+        if ( aExp == 0 ) {
+            ++expDiff;
+        }
+        else {
+            aSig |= LIT64( 0x2000000000000000 );
+        }
+        shift64RightJamming( aSig, - expDiff, &aSig );
+        zExp = bExp;
+    }
+    else {
+        if ( aExp == 0x7FF ) {
+            if ( aSig | bSig ) return propagateFloat64NaN( a, b );
+            return a;
+        }
+        if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
+        zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
+        zExp = aExp;
+        goto roundAndPack;
+    }
+    aSig |= LIT64( 0x2000000000000000 );
+    zSig = ( aSig + bSig )<<1;
+    --zExp;
+    if ( (sbits64) zSig < 0 ) {
+        zSig = aSig + bSig;
+        ++zExp;
+    }
+ roundAndPack:
+    return roundAndPackFloat64( zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of subtracting the absolute values of the double-
+precision floating-point values `a' and `b'.  If `zSign' is true, the
+difference is negated before being returned.  `zSign' is ignored if the
+result is a NaN.  The subtraction is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
+{
+    int16 aExp, bExp, zExp;
+    bits64 aSig, bSig, zSig;
+    int16 expDiff;
+
+    aSig = extractFloat64Frac( a );
+    aExp = extractFloat64Exp( a );
+    bSig = extractFloat64Frac( b );
+    bExp = extractFloat64Exp( b );
+    expDiff = aExp - bExp;
+    aSig <<= 10;
+    bSig <<= 10;
+    if ( 0 < expDiff ) goto aExpBigger;
+    if ( expDiff < 0 ) goto bExpBigger;
+    if ( aExp == 0x7FF ) {
+        if ( aSig | bSig ) return propagateFloat64NaN( a, b );
+        float_raise( float_flag_invalid );
+        return float64_default_nan;
+    }
+    if ( aExp == 0 ) {
+        aExp = 1;
+        bExp = 1;
+    }
+    if ( bSig < aSig ) goto aBigger;
+    if ( aSig < bSig ) goto bBigger;
+    return packFloat64( float_rounding_mode == float_round_down, 0, 0 );
+ bExpBigger:
+    if ( bExp == 0x7FF ) {
+        if ( bSig ) return propagateFloat64NaN( a, b );
+        return packFloat64( zSign ^ 1, 0x7FF, 0 );
+    }
+    if ( aExp == 0 ) {
+        ++expDiff;
+    }
+    else {
+        aSig |= LIT64( 0x4000000000000000 );
+    }
+    shift64RightJamming( aSig, - expDiff, &aSig );
+    bSig |= LIT64( 0x4000000000000000 );
+ bBigger:
+    zSig = bSig - aSig;
+    zExp = bExp;
+    zSign ^= 1;
+    goto normalizeRoundAndPack;
+ aExpBigger:
+    if ( aExp == 0x7FF ) {
+        if ( aSig ) return propagateFloat64NaN( a, b );
+        return a;
+    }
+    if ( bExp == 0 ) {
+        --expDiff;
+    }
+    else {
+        bSig |= LIT64( 0x4000000000000000 );
+    }
+    shift64RightJamming( bSig, expDiff, &bSig );
+    aSig |= LIT64( 0x4000000000000000 );
+ aBigger:
+    zSig = aSig - bSig;
+    zExp = aExp;
+ normalizeRoundAndPack:
+    --zExp;
+    return normalizeRoundAndPackFloat64( zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of adding the double-precision floating-point values `a'
+and `b'.  The operation is performed according to the IEC/IEEE Standard for
+Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float64_add( float64 a, float64 b )
+{
+    flag aSign, bSign;
+
+    aSign = extractFloat64Sign( a );
+    bSign = extractFloat64Sign( b );
+    if ( aSign == bSign ) {
+        return addFloat64Sigs( a, b, aSign );
+    }
+    else {
+        return subFloat64Sigs( a, b, aSign );
+    }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of subtracting the double-precision floating-point values
+`a' and `b'.  The operation is performed according to the IEC/IEEE Standard
+for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float64_sub( float64 a, float64 b )
+{
+    flag aSign, bSign;
+
+    aSign = extractFloat64Sign( a );
+    bSign = extractFloat64Sign( b );
+    if ( aSign == bSign ) {
+        return subFloat64Sigs( a, b, aSign );
+    }
+    else {
+        return addFloat64Sigs( a, b, aSign );
+    }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of multiplying the double-precision floating-point values
+`a' and `b'.  The operation is performed according to the IEC/IEEE Standard
+for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float64_mul( float64 a, float64 b )
+{
+    flag aSign, bSign, zSign;
+    int16 aExp, bExp, zExp;
+    bits64 aSig, bSig, zSig0, zSig1;
+
+    aSig = extractFloat64Frac( a );
+    aExp = extractFloat64Exp( a );
+    aSign = extractFloat64Sign( a );
+    bSig = extractFloat64Frac( b );
+    bExp = extractFloat64Exp( b );
+    bSign = extractFloat64Sign( b );
+    zSign = aSign ^ bSign;
+    if ( aExp == 0x7FF ) {
+        if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
+            return propagateFloat64NaN( a, b );
+        }
+        if ( ( bExp | bSig ) == 0 ) {
+            float_raise( float_flag_invalid );
+            return float64_default_nan;
+        }
+        return packFloat64( zSign, 0x7FF, 0 );
+    }
+    if ( bExp == 0x7FF ) {
+        if ( bSig ) return propagateFloat64NaN( a, b );
+        if ( ( aExp | aSig ) == 0 ) {
+            float_raise( float_flag_invalid );
+            return float64_default_nan;
+        }
+        return packFloat64( zSign, 0x7FF, 0 );
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
+        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
+    }
+    if ( bExp == 0 ) {
+        if ( bSig == 0 ) return packFloat64( zSign, 0, 0 );
+        normalizeFloat64Subnormal( bSig, &bExp, &bSig );
+    }
+    zExp = aExp + bExp - 0x3FF;
+    aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
+    bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
+    mul64To128( aSig, bSig, &zSig0, &zSig1 );
+    zSig0 |= ( zSig1 != 0 );
+    if ( 0 <= (sbits64) ( zSig0<<1 ) ) {
+        zSig0 <<= 1;
+        --zExp;
+    }
+    return roundAndPackFloat64( zSign, zExp, zSig0 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of dividing the double-precision floating-point value `a'
+by the corresponding value `b'.  The operation is performed according to
+the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float64_div( float64 a, float64 b )
+{
+    flag aSign, bSign, zSign;
+    int16 aExp, bExp, zExp;
+    bits64 aSig, bSig, zSig;
+    bits64 rem0, rem1;
+    bits64 term0, term1;
+
+    aSig = extractFloat64Frac( a );
+    aExp = extractFloat64Exp( a );
+    aSign = extractFloat64Sign( a );
+    bSig = extractFloat64Frac( b );
+    bExp = extractFloat64Exp( b );
+    bSign = extractFloat64Sign( b );
+    zSign = aSign ^ bSign;
+    if ( aExp == 0x7FF ) {
+        if ( aSig ) return propagateFloat64NaN( a, b );
+        if ( bExp == 0x7FF ) {
+            if ( bSig ) return propagateFloat64NaN( a, b );
+            float_raise( float_flag_invalid );
+            return float64_default_nan;
+        }
+        return packFloat64( zSign, 0x7FF, 0 );
+    }
+    if ( bExp == 0x7FF ) {
+        if ( bSig ) return propagateFloat64NaN( a, b );
+        return packFloat64( zSign, 0, 0 );
+    }
+    if ( bExp == 0 ) {
+        if ( bSig == 0 ) {
+            if ( ( aExp | aSig ) == 0 ) {
+                float_raise( float_flag_invalid );
+                return float64_default_nan;
+            }
+            float_raise( float_flag_divbyzero );
+            return packFloat64( zSign, 0x7FF, 0 );
+        }
+        normalizeFloat64Subnormal( bSig, &bExp, &bSig );
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
+        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
+    }
+    zExp = aExp - bExp + 0x3FD;
+    aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
+    bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
+    if ( bSig <= ( aSig + aSig ) ) {
+        aSig >>= 1;
+        ++zExp;
+    }
+    zSig = estimateDiv128To64( aSig, 0, bSig );
+    if ( ( zSig & 0x1FF ) <= 2 ) {
+        mul64To128( bSig, zSig, &term0, &term1 );
+        sub128( aSig, 0, term0, term1, &rem0, &rem1 );
+        while ( (sbits64) rem0 < 0 ) {
+            --zSig;
+            add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
+        }
+        zSig |= ( rem1 != 0 );
+    }
+    return roundAndPackFloat64( zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the remainder of the double-precision floating-point value `a'
+with respect to the corresponding value `b'.  The operation is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float64_rem( float64 a, float64 b )
+{
+    flag aSign, bSign, zSign;
+    int16 aExp, bExp, expDiff;
+    bits64 aSig, bSig;
+    bits64 q, alternateASig;
+    sbits64 sigMean;
+
+    aSig = extractFloat64Frac( a );
+    aExp = extractFloat64Exp( a );
+    aSign = extractFloat64Sign( a );
+    bSig = extractFloat64Frac( b );
+    bExp = extractFloat64Exp( b );
+    bSign = extractFloat64Sign( b );
+    if ( aExp == 0x7FF ) {
+        if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
+            return propagateFloat64NaN( a, b );
+        }
+        float_raise( float_flag_invalid );
+        return float64_default_nan;
+    }
+    if ( bExp == 0x7FF ) {
+        if ( bSig ) return propagateFloat64NaN( a, b );
+        return a;
+    }
+    if ( bExp == 0 ) {
+        if ( bSig == 0 ) {
+            float_raise( float_flag_invalid );
+            return float64_default_nan;
+        }
+        normalizeFloat64Subnormal( bSig, &bExp, &bSig );
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return a;
+        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
+    }
+    expDiff = aExp - bExp;
+    aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11;
+    bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
+    if ( expDiff < 0 ) {
+        if ( expDiff < -1 ) return a;
+        aSig >>= 1;
+    }
+    q = ( bSig <= aSig );
+    if ( q ) aSig -= bSig;
+    expDiff -= 64;
+    while ( 0 < expDiff ) {
+        q = estimateDiv128To64( aSig, 0, bSig );
+        q = ( 2 < q ) ? q - 2 : 0;
+        aSig = - ( ( bSig>>2 ) * q );
+        expDiff -= 62;
+    }
+    expDiff += 64;
+    if ( 0 < expDiff ) {
+        q = estimateDiv128To64( aSig, 0, bSig );
+        q = ( 2 < q ) ? q - 2 : 0;
+        q >>= 64 - expDiff;
+        bSig >>= 2;
+        aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
+    }
+    else {
+        aSig >>= 2;
+        bSig >>= 2;
+    }
+    do {
+        alternateASig = aSig;
+        ++q;
+        aSig -= bSig;
+    } while ( 0 <= (sbits64) aSig );
+    sigMean = aSig + alternateASig;
+    if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
+        aSig = alternateASig;
+    }
+    zSign = ( (sbits64) aSig < 0 );
+    if ( zSign ) aSig = - aSig;
+    return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the square root of the double-precision floating-point value `a'.
+The operation is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float64_sqrt( float64 a )
+{
+    flag aSign;
+    int16 aExp, zExp;
+    bits64 aSig, zSig;
+    bits64 rem0, rem1, term0, term1; //, shiftedRem;
+    //float64 z;
+
+    aSig = extractFloat64Frac( a );
+    aExp = extractFloat64Exp( a );
+    aSign = extractFloat64Sign( a );
+    if ( aExp == 0x7FF ) {
+        if ( aSig ) return propagateFloat64NaN( a, a );
+        if ( ! aSign ) return a;
+        float_raise( float_flag_invalid );
+        return float64_default_nan;
+    }
+    if ( aSign ) {
+        if ( ( aExp | aSig ) == 0 ) return a;
+        float_raise( float_flag_invalid );
+        return float64_default_nan;
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return 0;
+        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
+    }
+    zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
+    aSig |= LIT64( 0x0010000000000000 );
+    zSig = estimateSqrt32( aExp, aSig>>21 );
+    zSig <<= 31;
+    aSig <<= 9 - ( aExp & 1 );
+    zSig = estimateDiv128To64( aSig, 0, zSig ) + zSig + 2;
+    if ( ( zSig & 0x3FF ) <= 5 ) {
+        if ( zSig < 2 ) {
+            zSig = LIT64( 0xFFFFFFFFFFFFFFFF );
+        }
+        else {
+            aSig <<= 2;
+            mul64To128( zSig, zSig, &term0, &term1 );
+            sub128( aSig, 0, term0, term1, &rem0, &rem1 );
+            while ( (sbits64) rem0 < 0 ) {
+                --zSig;
+                shortShift128Left( 0, zSig, 1, &term0, &term1 );
+                term1 |= 1;
+                add128( rem0, rem1, term0, term1, &rem0, &rem1 );
+            }
+            zSig |= ( ( rem0 | rem1 ) != 0 );
+        }
+    }
+    shift64RightJamming( zSig, 1, &zSig );
+    return roundAndPackFloat64( 0, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the double-precision floating-point value `a' is equal to the
+corresponding value `b', and 0 otherwise.  The comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float64_eq( float64 a, float64 b )
+{
+
+    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+       ) {
+        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid );
+        }
+        return 0;
+    }
+    return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the double-precision floating-point value `a' is less than or
+equal to the corresponding value `b', and 0 otherwise.  The comparison is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float64_le( float64 a, float64 b )
+{
+    flag aSign, bSign;
+
+    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+       ) {
+        float_raise( float_flag_invalid );
+        return 0;
+    }
+    aSign = extractFloat64Sign( a );
+    bSign = extractFloat64Sign( b );
+    if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
+    return ( a == b ) || ( aSign ^ ( a < b ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the double-precision floating-point value `a' is less than
+the corresponding value `b', and 0 otherwise.  The comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float64_lt( float64 a, float64 b )
+{
+    flag aSign, bSign;
+
+    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+       ) {
+        float_raise( float_flag_invalid );
+        return 0;
+    }
+    aSign = extractFloat64Sign( a );
+    bSign = extractFloat64Sign( b );
+    if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
+    return ( a != b ) && ( aSign ^ ( a < b ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the double-precision floating-point value `a' is equal to the
+corresponding value `b', and 0 otherwise.  The invalid exception is raised
+if either operand is a NaN.  Otherwise, the comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float64_eq_signaling( float64 a, float64 b )
+{
+
+    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+       ) {
+        float_raise( float_flag_invalid );
+        return 0;
+    }
+    return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the double-precision floating-point value `a' is less than or
+equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
+cause an exception.  Otherwise, the comparison is performed according to the
+IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float64_le_quiet( float64 a, float64 b )
+{
+    flag aSign, bSign;
+    //int16 aExp, bExp;
+
+    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+       ) {
+        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid );
+        }
+        return 0;
+    }
+    aSign = extractFloat64Sign( a );
+    bSign = extractFloat64Sign( b );
+    if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
+    return ( a == b ) || ( aSign ^ ( a < b ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the double-precision floating-point value `a' is less than
+the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
+exception.  Otherwise, the comparison is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float64_lt_quiet( float64 a, float64 b )
+{
+    flag aSign, bSign;
+
+    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+       ) {
+        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid );
+        }
+        return 0;
+    }
+    aSign = extractFloat64Sign( a );
+    bSign = extractFloat64Sign( b );
+    if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
+    return ( a != b ) && ( aSign ^ ( a < b ) );
+
+}
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the extended double-precision floating-
+point value `a' to the 32-bit two's complement integer format.  The
+conversion is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic---which means in particular that the conversion
+is rounded according to the current rounding mode.  If `a' is a NaN, the
+largest positive integer is returned.  Otherwise, if the conversion
+overflows, the largest integer with the same sign as `a' is returned.
+-------------------------------------------------------------------------------
+*/
+int32 floatx80_to_int32( floatx80 a )
+{
+    flag aSign;
+    int32 aExp, shiftCount;
+    bits64 aSig;
+
+    aSig = extractFloatx80Frac( a );
+    aExp = extractFloatx80Exp( a );
+    aSign = extractFloatx80Sign( a );
+    if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
+    shiftCount = 0x4037 - aExp;
+    if ( shiftCount <= 0 ) shiftCount = 1;
+    shift64RightJamming( aSig, shiftCount, &aSig );
+    return roundAndPackInt32( aSign, aSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the extended double-precision floating-
+point value `a' to the 32-bit two's complement integer format.  The
+conversion is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic, except that the conversion is always rounded
+toward zero.  If `a' is a NaN, the largest positive integer is returned.
+Otherwise, if the conversion overflows, the largest integer with the same
+sign as `a' is returned.
+-------------------------------------------------------------------------------
+*/
+int32 floatx80_to_int32_round_to_zero( floatx80 a )
+{
+    flag aSign;
+    int32 aExp, shiftCount;
+    bits64 aSig, savedASig;
+    int32 z;
+
+    aSig = extractFloatx80Frac( a );
+    aExp = extractFloatx80Exp( a );
+    aSign = extractFloatx80Sign( a );
+    shiftCount = 0x403E - aExp;
+    if ( shiftCount < 32 ) {
+        if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
+        goto invalid;
+    }
+    else if ( 63 < shiftCount ) {
+        if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
+        return 0;
+    }
+    savedASig = aSig;
+    aSig >>= shiftCount;
+    z = aSig;
+    if ( aSign ) z = - z;
+    if ( ( z < 0 ) ^ aSign ) {
+ invalid:
+        float_exception_flags |= float_flag_invalid;
+        return aSign ? 0x80000000 : 0x7FFFFFFF;
+    }
+    if ( ( aSig<<shiftCount ) != savedASig ) {
+        float_exception_flags |= float_flag_inexact;
+    }
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the extended double-precision floating-
+point value `a' to the single-precision floating-point format.  The
+conversion is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 floatx80_to_float32( floatx80 a )
+{
+    flag aSign;
+    int32 aExp;
+    bits64 aSig;
+
+    aSig = extractFloatx80Frac( a );
+    aExp = extractFloatx80Exp( a );
+    aSign = extractFloatx80Sign( a );
+    if ( aExp == 0x7FFF ) {
+        if ( (bits64) ( aSig<<1 ) ) {
+            return commonNaNToFloat32( floatx80ToCommonNaN( a ) );
+        }
+        return packFloat32( aSign, 0xFF, 0 );
+    }
+    shift64RightJamming( aSig, 33, &aSig );
+    if ( aExp || aSig ) aExp -= 0x3F81;
+    return roundAndPackFloat32( aSign, aExp, aSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the extended double-precision floating-
+point value `a' to the double-precision floating-point format.  The
+conversion is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 floatx80_to_float64( floatx80 a )
+{
+    flag aSign;
+    int32 aExp;
+    bits64 aSig, zSig;
+
+    aSig = extractFloatx80Frac( a );
+    aExp = extractFloatx80Exp( a );
+    aSign = extractFloatx80Sign( a );
+    if ( aExp == 0x7FFF ) {
+        if ( (bits64) ( aSig<<1 ) ) {
+            return commonNaNToFloat64( floatx80ToCommonNaN( a ) );
+        }
+        return packFloat64( aSign, 0x7FF, 0 );
+    }
+    shift64RightJamming( aSig, 1, &zSig );
+    if ( aExp || aSig ) aExp -= 0x3C01;
+    return roundAndPackFloat64( aSign, aExp, zSig );
+
+}
+
+#ifdef FLOAT128
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the extended double-precision floating-
+point value `a' to the quadruple-precision floating-point format.  The
+conversion is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float128 floatx80_to_float128( floatx80 a )
+{
+    flag aSign;
+    int16 aExp;
+    bits64 aSig, zSig0, zSig1;
+
+    aSig = extractFloatx80Frac( a );
+    aExp = extractFloatx80Exp( a );
+    aSign = extractFloatx80Sign( a );
+    if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) {
+        return commonNaNToFloat128( floatx80ToCommonNaN( a ) );
+    }
+    shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 );
+    return packFloat128( aSign, aExp, zSig0, zSig1 );
+
+}
+
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Rounds the extended double-precision floating-point value `a' to an integer,
+and returns the result as an extended quadruple-precision floating-point
+value.  The operation is performed according to the IEC/IEEE Standard for
+Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_round_to_int( floatx80 a )
+{
+    flag aSign;
+    int32 aExp;
+    bits64 lastBitMask, roundBitsMask;
+    int8 roundingMode;
+    floatx80 z;
+
+    aExp = extractFloatx80Exp( a );
+    if ( 0x403E <= aExp ) {
+        if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) {
+            return propagateFloatx80NaN( a, a );
+        }
+        return a;
+    }
+    if ( aExp <= 0x3FFE ) {
+        if (    ( aExp == 0 )
+             && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
+            return a;
+        }
+        float_exception_flags |= float_flag_inexact;
+        aSign = extractFloatx80Sign( a );
+        switch ( float_rounding_mode ) {
+         case float_round_nearest_even:
+            if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 )
+               ) {
+                return
+                    packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
+            }
+            break;
+         case float_round_down:
+            return
+                  aSign ?
+                      packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) )
+                : packFloatx80( 0, 0, 0 );
+         case float_round_up:
+            return
+                  aSign ? packFloatx80( 1, 0, 0 )
+                : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) );
+        }
+        return packFloatx80( aSign, 0, 0 );
+    }
+    lastBitMask = 1;
+    lastBitMask <<= 0x403E - aExp;
+    roundBitsMask = lastBitMask - 1;
+    z = a;
+    roundingMode = float_rounding_mode;
+    if ( roundingMode == float_round_nearest_even ) {
+        z.low += lastBitMask>>1;
+        if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
+    }
+    else if ( roundingMode != float_round_to_zero ) {
+        if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) {
+            z.low += roundBitsMask;
+        }
+    }
+    z.low &= ~ roundBitsMask;
+    if ( z.low == 0 ) {
+        ++z.high;
+        z.low = LIT64( 0x8000000000000000 );
+    }
+    if ( z.low != a.low ) float_exception_flags |= float_flag_inexact;
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of adding the absolute values of the extended double-
+precision floating-point values `a' and `b'.  If `zSign' is true, the sum is
+negated before being returned.  `zSign' is ignored if the result is a NaN.
+The addition is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
+{
+    int32 aExp, bExp, zExp;
+    bits64 aSig, bSig, zSig0, zSig1;
+    int32 expDiff;
+
+    aSig = extractFloatx80Frac( a );
+    aExp = extractFloatx80Exp( a );
+    bSig = extractFloatx80Frac( b );
+    bExp = extractFloatx80Exp( b );
+    expDiff = aExp - bExp;
+    if ( 0 < expDiff ) {
+        if ( aExp == 0x7FFF ) {
+            if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
+            return a;
+        }
+        if ( bExp == 0 ) --expDiff;
+        shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
+        zExp = aExp;
+    }
+    else if ( expDiff < 0 ) {
+        if ( bExp == 0x7FFF ) {
+            if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+            return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+        }
+        if ( aExp == 0 ) ++expDiff;
+        shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
+        zExp = bExp;
+    }
+    else {
+        if ( aExp == 0x7FFF ) {
+            if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
+                return propagateFloatx80NaN( a, b );
+            }
+            return a;
+        }
+        zSig1 = 0;
+        zSig0 = aSig + bSig;
+        if ( aExp == 0 ) {
+            normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 );
+            goto roundAndPack;
+        }
+        zExp = aExp;
+        goto shiftRight1;
+    }
+    
+    zSig0 = aSig + bSig;
+
+    if ( (sbits64) zSig0 < 0 ) goto roundAndPack; 
+ shiftRight1:
+    shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 );
+    zSig0 |= LIT64( 0x8000000000000000 );
+    ++zExp;
+ roundAndPack:
+    return
+        roundAndPackFloatx80(
+            floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of subtracting the absolute values of the extended
+double-precision floating-point values `a' and `b'.  If `zSign' is true,
+the difference is negated before being returned.  `zSign' is ignored if the
+result is a NaN.  The subtraction is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
+{
+    int32 aExp, bExp, zExp;
+    bits64 aSig, bSig, zSig0, zSig1;
+    int32 expDiff;
+    floatx80 z;
+
+    aSig = extractFloatx80Frac( a );
+    aExp = extractFloatx80Exp( a );
+    bSig = extractFloatx80Frac( b );
+    bExp = extractFloatx80Exp( b );
+    expDiff = aExp - bExp;
+    if ( 0 < expDiff ) goto aExpBigger;
+    if ( expDiff < 0 ) goto bExpBigger;
+    if ( aExp == 0x7FFF ) {
+        if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
+            return propagateFloatx80NaN( a, b );
+        }
+        float_raise( float_flag_invalid );
+        z.low = floatx80_default_nan_low;
+        z.high = floatx80_default_nan_high;
+        return z;
+    }
+    if ( aExp == 0 ) {
+        aExp = 1;
+        bExp = 1;
+    }
+    zSig1 = 0;
+    if ( bSig < aSig ) goto aBigger;
+    if ( aSig < bSig ) goto bBigger;
+    return packFloatx80( float_rounding_mode == float_round_down, 0, 0 );
+ bExpBigger:
+    if ( bExp == 0x7FFF ) {
+        if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+        return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
+    }
+    if ( aExp == 0 ) ++expDiff;
+    shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
+ bBigger:
+    sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 );
+    zExp = bExp;
+    zSign ^= 1;
+    goto normalizeRoundAndPack;
+ aExpBigger:
+    if ( aExp == 0x7FFF ) {
+        if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
+        return a;
+    }
+    if ( bExp == 0 ) --expDiff;
+    shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
+ aBigger:
+    sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 );
+    zExp = aExp;
+ normalizeRoundAndPack:
+    return
+        normalizeRoundAndPackFloatx80(
+            floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of adding the extended double-precision floating-point
+values `a' and `b'.  The operation is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_add( floatx80 a, floatx80 b )
+{
+    flag aSign, bSign;
+    
+    aSign = extractFloatx80Sign( a );
+    bSign = extractFloatx80Sign( b );
+    if ( aSign == bSign ) {
+        return addFloatx80Sigs( a, b, aSign );
+    }
+    else {
+        return subFloatx80Sigs( a, b, aSign );
+    }
+    
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of subtracting the extended double-precision floating-
+point values `a' and `b'.  The operation is performed according to the
+IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_sub( floatx80 a, floatx80 b )
+{
+    flag aSign, bSign;
+
+    aSign = extractFloatx80Sign( a );
+    bSign = extractFloatx80Sign( b );
+    if ( aSign == bSign ) {
+        return subFloatx80Sigs( a, b, aSign );
+    }
+    else {
+        return addFloatx80Sigs( a, b, aSign );
+    }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of multiplying the extended double-precision floating-
+point values `a' and `b'.  The operation is performed according to the
+IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_mul( floatx80 a, floatx80 b )
+{
+    flag aSign, bSign, zSign;
+    int32 aExp, bExp, zExp;
+    bits64 aSig, bSig, zSig0, zSig1;
+    floatx80 z;
+
+    aSig = extractFloatx80Frac( a );
+    aExp = extractFloatx80Exp( a );
+    aSign = extractFloatx80Sign( a );
+    bSig = extractFloatx80Frac( b );
+    bExp = extractFloatx80Exp( b );
+    bSign = extractFloatx80Sign( b );
+    zSign = aSign ^ bSign;
+    if ( aExp == 0x7FFF ) {
+        if (    (bits64) ( aSig<<1 )
+             || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
+            return propagateFloatx80NaN( a, b );
+        }
+        if ( ( bExp | bSig ) == 0 ) goto invalid;
+        return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+    }
+    if ( bExp == 0x7FFF ) {
+        if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+        if ( ( aExp | aSig ) == 0 ) {
+ invalid:
+            float_raise( float_flag_invalid );
+            z.low = floatx80_default_nan_low;
+            z.high = floatx80_default_nan_high;
+            return z;
+        }
+        return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
+        normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
+    }
+    if ( bExp == 0 ) {
+        if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 );
+        normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
+    }
+    zExp = aExp + bExp - 0x3FFE;
+    mul64To128( aSig, bSig, &zSig0, &zSig1 );
+    if ( 0 < (sbits64) zSig0 ) {
+        shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 );
+        --zExp;
+    }
+    return
+        roundAndPackFloatx80(
+            floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of dividing the extended double-precision floating-point
+value `a' by the corresponding value `b'.  The operation is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_div( floatx80 a, floatx80 b )
+{
+    flag aSign, bSign, zSign;
+    int32 aExp, bExp, zExp;
+    bits64 aSig, bSig, zSig0, zSig1;
+    bits64 rem0, rem1, rem2, term0, term1, term2;
+    floatx80 z;
+
+    aSig = extractFloatx80Frac( a );
+    aExp = extractFloatx80Exp( a );
+    aSign = extractFloatx80Sign( a );
+    bSig = extractFloatx80Frac( b );
+    bExp = extractFloatx80Exp( b );
+    bSign = extractFloatx80Sign( b );
+    zSign = aSign ^ bSign;
+    if ( aExp == 0x7FFF ) {
+        if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
+        if ( bExp == 0x7FFF ) {
+            if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+            goto invalid;
+        }
+        return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+    }
+    if ( bExp == 0x7FFF ) {
+        if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+        return packFloatx80( zSign, 0, 0 );
+    }
+    if ( bExp == 0 ) {
+        if ( bSig == 0 ) {
+            if ( ( aExp | aSig ) == 0 ) {
+ invalid:
+                float_raise( float_flag_invalid );
+                z.low = floatx80_default_nan_low;
+                z.high = floatx80_default_nan_high;
+                return z;
+            }
+            float_raise( float_flag_divbyzero );
+            return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+        }
+        normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
+        normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
+    }
+    zExp = aExp - bExp + 0x3FFE;
+    rem1 = 0;
+    if ( bSig <= aSig ) {
+        shift128Right( aSig, 0, 1, &aSig, &rem1 );
+        ++zExp;
+    }
+    zSig0 = estimateDiv128To64( aSig, rem1, bSig );
+    mul64To128( bSig, zSig0, &term0, &term1 );
+    sub128( aSig, rem1, term0, term1, &rem0, &rem1 );
+    while ( (sbits64) rem0 < 0 ) {
+        --zSig0;
+        add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
+    }
+    zSig1 = estimateDiv128To64( rem1, 0, bSig );
+    if ( (bits64) ( zSig1<<1 ) <= 8 ) {
+        mul64To128( bSig, zSig1, &term1, &term2 );
+        sub128( rem1, 0, term1, term2, &rem1, &rem2 );
+        while ( (sbits64) rem1 < 0 ) {
+            --zSig1;
+            add128( rem1, rem2, 0, bSig, &rem1, &rem2 );
+        }
+        zSig1 |= ( ( rem1 | rem2 ) != 0 );
+    }
+    return
+        roundAndPackFloatx80(
+            floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the remainder of the extended double-precision floating-point value
+`a' with respect to the corresponding value `b'.  The operation is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_rem( floatx80 a, floatx80 b )
+{
+    flag aSign, bSign, zSign;
+    int32 aExp, bExp, expDiff;
+    bits64 aSig0, aSig1, bSig;
+    bits64 q, term0, term1, alternateASig0, alternateASig1;
+    floatx80 z;
+
+    aSig0 = extractFloatx80Frac( a );
+    aExp = extractFloatx80Exp( a );
+    aSign = extractFloatx80Sign( a );
+    bSig = extractFloatx80Frac( b );
+    bExp = extractFloatx80Exp( b );
+    bSign = extractFloatx80Sign( b );
+    if ( aExp == 0x7FFF ) {
+        if (    (bits64) ( aSig0<<1 )
+             || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
+            return propagateFloatx80NaN( a, b );
+        }
+        goto invalid;
+    }
+    if ( bExp == 0x7FFF ) {
+        if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+        return a;
+    }
+    if ( bExp == 0 ) {
+        if ( bSig == 0 ) {
+ invalid:
+            float_raise( float_flag_invalid );
+            z.low = floatx80_default_nan_low;
+            z.high = floatx80_default_nan_high;
+            return z;
+        }
+        normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
+    }
+    if ( aExp == 0 ) {
+        if ( (bits64) ( aSig0<<1 ) == 0 ) return a;
+        normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
+    }
+    bSig |= LIT64( 0x8000000000000000 );
+    zSign = aSign;
+    expDiff = aExp - bExp;
+    aSig1 = 0;
+    if ( expDiff < 0 ) {
+        if ( expDiff < -1 ) return a;
+        shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
+        expDiff = 0;
+    }
+    q = ( bSig <= aSig0 );
+    if ( q ) aSig0 -= bSig;
+    expDiff -= 64;
+    while ( 0 < expDiff ) {
+        q = estimateDiv128To64( aSig0, aSig1, bSig );
+        q = ( 2 < q ) ? q - 2 : 0;
+        mul64To128( bSig, q, &term0, &term1 );
+        sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
+        shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
+        expDiff -= 62;
+    }
+    expDiff += 64;
+    if ( 0 < expDiff ) {
+        q = estimateDiv128To64( aSig0, aSig1, bSig );
+        q = ( 2 < q ) ? q - 2 : 0;
+        q >>= 64 - expDiff;
+        mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );
+        sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
+        shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
+        while ( le128( term0, term1, aSig0, aSig1 ) ) {
+            ++q;
+            sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
+        }
+    }
+    else {
+        term1 = 0;
+        term0 = bSig;
+    }
+    sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
+    if (    lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
+         || (    eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
+              && ( q & 1 ) )
+       ) {
+        aSig0 = alternateASig0;
+        aSig1 = alternateASig1;
+        zSign = ! zSign;
+    }
+    return
+        normalizeRoundAndPackFloatx80(
+            80, zSign, bExp + expDiff, aSig0, aSig1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the square root of the extended double-precision floating-point
+value `a'.  The operation is performed according to the IEC/IEEE Standard
+for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_sqrt( floatx80 a )
+{
+    flag aSign;
+    int32 aExp, zExp;
+    bits64 aSig0, aSig1, zSig0, zSig1;
+    bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
+    bits64 shiftedRem0, shiftedRem1;
+    floatx80 z;
+
+    aSig0 = extractFloatx80Frac( a );
+    aExp = extractFloatx80Exp( a );
+    aSign = extractFloatx80Sign( a );
+    if ( aExp == 0x7FFF ) {
+        if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a );
+        if ( ! aSign ) return a;
+        goto invalid;
+    }
+    if ( aSign ) {
+        if ( ( aExp | aSig0 ) == 0 ) return a;
+ invalid:
+        float_raise( float_flag_invalid );
+        z.low = floatx80_default_nan_low;
+        z.high = floatx80_default_nan_high;
+        return z;
+    }
+    if ( aExp == 0 ) {
+        if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
+        normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
+    }
+    zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF;
+    zSig0 = estimateSqrt32( aExp, aSig0>>32 );
+    zSig0 <<= 31;
+    aSig1 = 0;
+    shift128Right( aSig0, 0, ( aExp & 1 ) + 2, &aSig0, &aSig1 );
+    zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0 ) + zSig0 + 4;
+    if ( 0 <= (sbits64) zSig0 ) zSig0 = LIT64( 0xFFFFFFFFFFFFFFFF );
+    shortShift128Left( aSig0, aSig1, 2, &aSig0, &aSig1 );
+    mul64To128( zSig0, zSig0, &term0, &term1 );
+    sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
+    while ( (sbits64) rem0 < 0 ) {
+        --zSig0;
+        shortShift128Left( 0, zSig0, 1, &term0, &term1 );
+        term1 |= 1;
+        add128( rem0, rem1, term0, term1, &rem0, &rem1 );
+    }
+    shortShift128Left( rem0, rem1, 63, &shiftedRem0, &shiftedRem1 );
+    zSig1 = estimateDiv128To64( shiftedRem0, shiftedRem1, zSig0 );
+    if ( (bits64) ( zSig1<<1 ) <= 10 ) {
+        if ( zSig1 == 0 ) zSig1 = 1;
+        mul64To128( zSig0, zSig1, &term1, &term2 );
+        shortShift128Left( term1, term2, 1, &term1, &term2 );
+        sub128( rem1, 0, term1, term2, &rem1, &rem2 );
+        mul64To128( zSig1, zSig1, &term2, &term3 );
+        sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
+        while ( (sbits64) rem1 < 0 ) {
+            --zSig1;
+            shortShift192Left( 0, zSig0, zSig1, 1, &term1, &term2, &term3 );
+            term3 |= 1;
+            add192(
+                rem1, rem2, rem3, term1, term2, term3, &rem1, &rem2, &rem3 );
+        }
+        zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
+    }
+    return
+        roundAndPackFloatx80(
+            floatx80_rounding_precision, 0, zExp, zSig0, zSig1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the extended double-precision floating-point value `a' is
+equal to the corresponding value `b', and 0 otherwise.  The comparison is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag floatx80_eq( floatx80 a, floatx80 b )
+{
+
+    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
+              && (bits64) ( extractFloatx80Frac( a )<<1 ) )
+         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
+              && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+       ) {
+        if (    floatx80_is_signaling_nan( a )
+             || floatx80_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid );
+        }
+        return 0;
+    }
+    return
+           ( a.low == b.low )
+        && (    ( a.high == b.high )
+             || (    ( a.low == 0 )
+                  && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
+           );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the extended double-precision floating-point value `a' is
+less than or equal to the corresponding value `b', and 0 otherwise.  The
+comparison is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag floatx80_le( floatx80 a, floatx80 b )
+{
+    flag aSign, bSign;
+
+    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
+              && (bits64) ( extractFloatx80Frac( a )<<1 ) )
+         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
+              && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+       ) {
+        float_raise( float_flag_invalid );
+        return 0;
+    }
+    aSign = extractFloatx80Sign( a );
+    bSign = extractFloatx80Sign( b );
+    if ( aSign != bSign ) {
+        return
+               aSign
+            || (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
+                 == 0 );
+    }
+    return
+          aSign ? le128( b.high, b.low, a.high, a.low )
+        : le128( a.high, a.low, b.high, b.low );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the extended double-precision floating-point value `a' is
+less than the corresponding value `b', and 0 otherwise.  The comparison
+is performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag floatx80_lt( floatx80 a, floatx80 b )
+{
+    flag aSign, bSign;
+
+    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
+              && (bits64) ( extractFloatx80Frac( a )<<1 ) )
+         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
+              && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+       ) {
+        float_raise( float_flag_invalid );
+        return 0;
+    }
+    aSign = extractFloatx80Sign( a );
+    bSign = extractFloatx80Sign( b );
+    if ( aSign != bSign ) {
+        return
+               aSign
+            && (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
+                 != 0 );
+    }
+    return
+          aSign ? lt128( b.high, b.low, a.high, a.low )
+        : lt128( a.high, a.low, b.high, b.low );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the extended double-precision floating-point value `a' is equal
+to the corresponding value `b', and 0 otherwise.  The invalid exception is
+raised if either operand is a NaN.  Otherwise, the comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag floatx80_eq_signaling( floatx80 a, floatx80 b )
+{
+
+    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
+              && (bits64) ( extractFloatx80Frac( a )<<1 ) )
+         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
+              && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+       ) {
+        float_raise( float_flag_invalid );
+        return 0;
+    }
+    return
+           ( a.low == b.low )
+        && (    ( a.high == b.high )
+             || (    ( a.low == 0 )
+                  && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
+           );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the extended double-precision floating-point value `a' is less
+than or equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs
+do not cause an exception.  Otherwise, the comparison is performed according
+to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag floatx80_le_quiet( floatx80 a, floatx80 b )
+{
+    flag aSign, bSign;
+
+    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
+              && (bits64) ( extractFloatx80Frac( a )<<1 ) )
+         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
+              && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+       ) {
+        if (    floatx80_is_signaling_nan( a )
+             || floatx80_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid );
+        }
+        return 0;
+    }
+    aSign = extractFloatx80Sign( a );
+    bSign = extractFloatx80Sign( b );
+    if ( aSign != bSign ) {
+        return
+               aSign
+            || (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
+                 == 0 );
+    }
+    return
+          aSign ? le128( b.high, b.low, a.high, a.low )
+        : le128( a.high, a.low, b.high, b.low );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the extended double-precision floating-point value `a' is less
+than the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause
+an exception.  Otherwise, the comparison is performed according to the
+IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag floatx80_lt_quiet( floatx80 a, floatx80 b )
+{
+    flag aSign, bSign;
+
+    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
+              && (bits64) ( extractFloatx80Frac( a )<<1 ) )
+         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
+              && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+       ) {
+        if (    floatx80_is_signaling_nan( a )
+             || floatx80_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid );
+        }
+        return 0;
+    }
+    aSign = extractFloatx80Sign( a );
+    bSign = extractFloatx80Sign( b );
+    if ( aSign != bSign ) {
+        return
+               aSign
+            && (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
+                 != 0 );
+    }
+    return
+          aSign ? lt128( b.high, b.low, a.high, a.low )
+        : lt128( a.high, a.low, b.high, b.low );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the quadruple-precision floating-point
+value `a' to the 32-bit two's complement integer format.  The conversion
+is performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic---which means in particular that the conversion is rounded
+according to the current rounding mode.  If `a' is a NaN, the largest
+positive integer is returned.  Otherwise, if the conversion overflows, the
+largest integer with the same sign as `a' is returned.
+-------------------------------------------------------------------------------
+*/
+int32 float128_to_int32( float128 a )
+{
+    flag aSign;
+    int32 aExp, shiftCount;
+    bits64 aSig0, aSig1;
+
+    aSig1 = extractFloat128Frac1( a );
+    aSig0 = extractFloat128Frac0( a );
+    aExp = extractFloat128Exp( a );
+    aSign = extractFloat128Sign( a );
+    if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0;
+    if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
+    aSig0 |= ( aSig1 != 0 );
+    shiftCount = 0x4028 - aExp;
+    if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 );
+    return roundAndPackInt32( aSign, aSig0 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the quadruple-precision floating-point
+value `a' to the 32-bit two's complement integer format.  The conversion
+is performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic, except that the conversion is always rounded toward zero.  If
+`a' is a NaN, the largest positive integer is returned.  Otherwise, if the
+conversion overflows, the largest integer with the same sign as `a' is
+returned.
+-------------------------------------------------------------------------------
+*/
+int32 float128_to_int32_round_to_zero( float128 a )
+{
+    flag aSign;
+    int32 aExp, shiftCount;
+    bits64 aSig0, aSig1, savedASig;
+    int32 z;
+
+    aSig1 = extractFloat128Frac1( a );
+    aSig0 = extractFloat128Frac0( a );
+    aExp = extractFloat128Exp( a );
+    aSign = extractFloat128Sign( a );
+    aSig0 |= ( aSig1 != 0 );
+    shiftCount = 0x402F - aExp;
+    if ( shiftCount < 17 ) {
+        if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0;
+        goto invalid;
+    }
+    else if ( 48 < shiftCount ) {
+        if ( aExp || aSig0 ) float_exception_flags |= float_flag_inexact;
+        return 0;
+    }
+    aSig0 |= LIT64( 0x0001000000000000 );
+    savedASig = aSig0;
+    aSig0 >>= shiftCount;
+    z = aSig0;
+    if ( aSign ) z = - z;
+    if ( ( z < 0 ) ^ aSign ) {
+ invalid:
+        float_exception_flags |= float_flag_invalid;
+        return aSign ? 0x80000000 : 0x7FFFFFFF;
+    }
+    if ( ( aSig0<<shiftCount ) != savedASig ) {
+        float_exception_flags |= float_flag_inexact;
+    }
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the quadruple-precision floating-point
+value `a' to the single-precision floating-point format.  The conversion
+is performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float128_to_float32( float128 a )
+{
+    flag aSign;
+    int32 aExp;
+    bits64 aSig0, aSig1;
+    bits32 zSig;
+
+    aSig1 = extractFloat128Frac1( a );
+    aSig0 = extractFloat128Frac0( a );
+    aExp = extractFloat128Exp( a );
+    aSign = extractFloat128Sign( a );
+    if ( aExp == 0x7FFF ) {
+        if ( aSig0 | aSig1 ) {
+            return commonNaNToFloat32( float128ToCommonNaN( a ) );
+        }
+        return packFloat32( aSign, 0xFF, 0 );
+    }
+    aSig0 |= ( aSig1 != 0 );
+    shift64RightJamming( aSig0, 18, &aSig0 );
+    zSig = aSig0;
+    if ( aExp || zSig ) {
+        zSig |= 0x40000000;
+        aExp -= 0x3F81;
+    }
+    return roundAndPackFloat32( aSign, aExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the quadruple-precision floating-point
+value `a' to the double-precision floating-point format.  The conversion
+is performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float128_to_float64( float128 a )
+{
+    flag aSign;
+    int32 aExp;
+    bits64 aSig0, aSig1;
+
+    aSig1 = extractFloat128Frac1( a );
+    aSig0 = extractFloat128Frac0( a );
+    aExp = extractFloat128Exp( a );
+    aSign = extractFloat128Sign( a );
+    if ( aExp == 0x7FFF ) {
+        if ( aSig0 | aSig1 ) {
+            return commonNaNToFloat64( float128ToCommonNaN( a ) );
+        }
+        return packFloat64( aSign, 0x7FF, 0 );
+    }
+    shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
+    aSig0 |= ( aSig1 != 0 );
+    if ( aExp || aSig0 ) {
+        aSig0 |= LIT64( 0x4000000000000000 );
+        aExp -= 0x3C01;
+    }
+    return roundAndPackFloat64( aSign, aExp, aSig0 );
+
+}
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the quadruple-precision floating-point
+value `a' to the extended double-precision floating-point format.  The
+conversion is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 float128_to_floatx80( float128 a )
+{
+    flag aSign;
+    int32 aExp;
+    bits64 aSig0, aSig1;
+
+    aSig1 = extractFloat128Frac1( a );
+    aSig0 = extractFloat128Frac0( a );
+    aExp = extractFloat128Exp( a );
+    aSign = extractFloat128Sign( a );
+    if ( aExp == 0x7FFF ) {
+        if ( aSig0 | aSig1 ) {
+            return commonNaNToFloatx80( float128ToCommonNaN( a ) );
+        }
+        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+    }
+    if ( aExp == 0 ) {
+        if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 );
+        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
+    }
+    else {
+        aSig0 |= LIT64( 0x0001000000000000 );
+    }
+    shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 );
+    return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 );
+
+}
+
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Rounds the quadruple-precision floating-point value `a' to an integer, and
+returns the result as a quadruple-precision floating-point value.  The
+operation is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float128 float128_round_to_int( float128 a )
+{
+    flag aSign;
+    int32 aExp;
+    bits64 lastBitMask, roundBitsMask;
+    int8 roundingMode;
+    float128 z;
+
+    aExp = extractFloat128Exp( a );
+    if ( 0x402F <= aExp ) {
+        if ( 0x406F <= aExp ) {
+            if (    ( aExp == 0x7FFF )
+                 && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) )
+               ) {
+                return propagateFloat128NaN( a, a );
+            }
+            return a;
+        }
+        lastBitMask = 1;
+        lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1;
+        roundBitsMask = lastBitMask - 1;
+        z = a;
+        roundingMode = float_rounding_mode;
+        if ( roundingMode == float_round_nearest_even ) {
+            if ( lastBitMask ) {
+                add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low );
+                if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
+            }
+            else {
+                if ( (sbits64) z.low < 0 ) {
+                    ++z.high;
+                    if ( (bits64) ( z.low<<1 ) == 0 ) z.high &= ~1;
+                }
+            }
+        }
+        else if ( roundingMode != float_round_to_zero ) {
+            if (   extractFloat128Sign( z )
+                 ^ ( roundingMode == float_round_up ) ) {
+                add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low );
+            }
+        }
+        z.low &= ~ roundBitsMask;
+    }
+    else {
+        if ( aExp <= 0x3FFE ) {
+            if ( ( ( (bits64) ( a.high<<1 ) ) | a.low ) == 0 ) return a;
+            float_exception_flags |= float_flag_inexact;
+            aSign = extractFloat128Sign( a );
+            switch ( float_rounding_mode ) {
+             case float_round_nearest_even:
+                if (    ( aExp == 0x3FFE )
+                     && (   extractFloat128Frac0( a )
+                          | extractFloat128Frac1( a ) )
+                   ) {
+                    return packFloat128( aSign, 0x3FFF, 0, 0 );
+                }
+                break;
+             case float_round_down:
+                return
+                      aSign ? packFloat128( 1, 0x3FFF, 0, 0 )
+                    : packFloat128( 0, 0, 0, 0 );
+             case float_round_up:
+                return
+                      aSign ? packFloat128( 1, 0, 0, 0 )
+                    : packFloat128( 0, 0x3FFF, 0, 0 );
+            }
+            return packFloat128( aSign, 0, 0, 0 );
+        }
+        lastBitMask = 1;
+        lastBitMask <<= 0x402F - aExp;
+        roundBitsMask = lastBitMask - 1;
+        z.low = 0;
+        z.high = a.high;
+        roundingMode = float_rounding_mode;
+        if ( roundingMode == float_round_nearest_even ) {
+            z.high += lastBitMask>>1;
+            if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) {
+                z.high &= ~ lastBitMask;
+            }
+        }
+        else if ( roundingMode != float_round_to_zero ) {
+            if (   extractFloat128Sign( z )
+                 ^ ( roundingMode == float_round_up ) ) {
+                z.high |= ( a.low != 0 );
+                z.high += roundBitsMask;
+            }
+        }
+        z.high &= ~ roundBitsMask;
+    }
+    if ( ( z.low != a.low ) || ( z.high != a.high ) ) {
+        float_exception_flags |= float_flag_inexact;
+    }
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of adding the absolute values of the quadruple-precision
+floating-point values `a' and `b'.  If `zSign' is true, the sum is negated
+before being returned.  `zSign' is ignored if the result is a NaN.  The
+addition is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float128 addFloat128Sigs( float128 a, float128 b, flag zSign )
+{
+    int32 aExp, bExp, zExp;
+    bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
+    int32 expDiff;
+
+    aSig1 = extractFloat128Frac1( a );
+    aSig0 = extractFloat128Frac0( a );
+    aExp = extractFloat128Exp( a );
+    bSig1 = extractFloat128Frac1( b );
+    bSig0 = extractFloat128Frac0( b );
+    bExp = extractFloat128Exp( b );
+    expDiff = aExp - bExp;
+    if ( 0 < expDiff ) {
+        if ( aExp == 0x7FFF ) {
+            if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b );
+            return a;
+        }
+        if ( bExp == 0 ) {
+            --expDiff;
+        }
+        else {
+            bSig0 |= LIT64( 0x0001000000000000 );
+        }
+        shift128ExtraRightJamming(
+            bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 );
+        zExp = aExp;
+    }
+    else if ( expDiff < 0 ) {
+        if ( bExp == 0x7FFF ) {
+            if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
+            return packFloat128( zSign, 0x7FFF, 0, 0 );
+        }
+        if ( aExp == 0 ) {
+            ++expDiff;
+        }
+        else {
+            aSig0 |= LIT64( 0x0001000000000000 );
+        }
+        shift128ExtraRightJamming(
+            aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 );
+        zExp = bExp;
+    }
+    else {
+        if ( aExp == 0x7FFF ) {
+            if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
+                return propagateFloat128NaN( a, b );
+            }
+            return a;
+        }
+        add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
+        if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 );
+        zSig2 = 0;
+        zSig0 |= LIT64( 0x0002000000000000 );
+        zExp = aExp;
+        goto shiftRight1;
+    }
+    aSig0 |= LIT64( 0x0001000000000000 );
+    add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
+    --zExp;
+    if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack;
+    ++zExp;
+ shiftRight1:
+    shift128ExtraRightJamming(
+        zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
+ roundAndPack:
+    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of subtracting the absolute values of the quadruple-
+precision floating-point values `a' and `b'.  If `zSign' is true, the
+difference is negated before being returned.  `zSign' is ignored if the
+result is a NaN.  The subtraction is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float128 subFloat128Sigs( float128 a, float128 b, flag zSign )
+{
+    int32 aExp, bExp, zExp;
+    bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
+    int32 expDiff;
+    float128 z;
+
+    aSig1 = extractFloat128Frac1( a );
+    aSig0 = extractFloat128Frac0( a );
+    aExp = extractFloat128Exp( a );
+    bSig1 = extractFloat128Frac1( b );
+    bSig0 = extractFloat128Frac0( b );
+    bExp = extractFloat128Exp( b );
+    expDiff = aExp - bExp;
+    shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
+    shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 );
+    if ( 0 < expDiff ) goto aExpBigger;
+    if ( expDiff < 0 ) goto bExpBigger;
+    if ( aExp == 0x7FFF ) {
+        if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
+            return propagateFloat128NaN( a, b );
+        }
+        float_raise( float_flag_invalid );
+        z.low = float128_default_nan_low;
+        z.high = float128_default_nan_high;
+        return z;
+    }
+    if ( aExp == 0 ) {
+        aExp = 1;
+        bExp = 1;
+    }
+    if ( bSig0 < aSig0 ) goto aBigger;
+    if ( aSig0 < bSig0 ) goto bBigger;
+    if ( bSig1 < aSig1 ) goto aBigger;
+    if ( aSig1 < bSig1 ) goto bBigger;
+    return packFloat128( float_rounding_mode == float_round_down, 0, 0, 0 );
+ bExpBigger:
+    if ( bExp == 0x7FFF ) {
+        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
+        return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 );
+    }
+    if ( aExp == 0 ) {
+        ++expDiff;
+    }
+    else {
+        aSig0 |= LIT64( 0x4000000000000000 );
+    }
+    shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
+    bSig0 |= LIT64( 0x4000000000000000 );
+ bBigger:
+    sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 );
+    zExp = bExp;
+    zSign ^= 1;
+    goto normalizeRoundAndPack;
+ aExpBigger:
+    if ( aExp == 0x7FFF ) {
+        if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b );
+        return a;
+    }
+    if ( bExp == 0 ) {
+        --expDiff;
+    }
+    else {
+        bSig0 |= LIT64( 0x4000000000000000 );
+    }
+    shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 );
+    aSig0 |= LIT64( 0x4000000000000000 );
+ aBigger:
+    sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
+    zExp = aExp;
+ normalizeRoundAndPack:
+    --zExp;
+    return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of adding the quadruple-precision floating-point values
+`a' and `b'.  The operation is performed according to the IEC/IEEE Standard
+for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float128 float128_add( float128 a, float128 b )
+{
+    flag aSign, bSign;
+
+    aSign = extractFloat128Sign( a );
+    bSign = extractFloat128Sign( b );
+    if ( aSign == bSign ) {
+        return addFloat128Sigs( a, b, aSign );
+    }
+    else {
+        return subFloat128Sigs( a, b, aSign );
+    }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of subtracting the quadruple-precision floating-point
+values `a' and `b'.  The operation is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float128 float128_sub( float128 a, float128 b )
+{
+    flag aSign, bSign;
+
+    aSign = extractFloat128Sign( a );
+    bSign = extractFloat128Sign( b );
+    if ( aSign == bSign ) {
+        return subFloat128Sigs( a, b, aSign );
+    }
+    else {
+        return addFloat128Sigs( a, b, aSign );
+    }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of multiplying the quadruple-precision floating-point
+values `a' and `b'.  The operation is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float128 float128_mul( float128 a, float128 b )
+{
+    flag aSign, bSign, zSign;
+    int32 aExp, bExp, zExp;
+    bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
+    float128 z;
+
+    aSig1 = extractFloat128Frac1( a );
+    aSig0 = extractFloat128Frac0( a );
+    aExp = extractFloat128Exp( a );
+    aSign = extractFloat128Sign( a );
+    bSig1 = extractFloat128Frac1( b );
+    bSig0 = extractFloat128Frac0( b );
+    bExp = extractFloat128Exp( b );
+    bSign = extractFloat128Sign( b );
+    zSign = aSign ^ bSign;
+    if ( aExp == 0x7FFF ) {
+        if (    ( aSig0 | aSig1 )
+             || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
+            return propagateFloat128NaN( a, b );
+        }
+        if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid;
+        return packFloat128( zSign, 0x7FFF, 0, 0 );
+    }
+    if ( bExp == 0x7FFF ) {
+        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
+        if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
+ invalid:
+            float_raise( float_flag_invalid );
+            z.low = float128_default_nan_low;
+            z.high = float128_default_nan_high;
+            return z;
+        }
+        return packFloat128( zSign, 0x7FFF, 0, 0 );
+    }
+    if ( aExp == 0 ) {
+        if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
+        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
+    }
+    if ( bExp == 0 ) {
+        if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
+        normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
+    }
+    zExp = aExp + bExp - 0x4000;
+    aSig0 |= LIT64( 0x0001000000000000 );
+    shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 );
+    mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 );
+    add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 );
+    zSig2 |= ( zSig3 != 0 );
+    if ( LIT64( 0x0002000000000000 ) <= zSig0 ) {
+        shift128ExtraRightJamming(
+            zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
+        ++zExp;
+    }
+    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of dividing the quadruple-precision floating-point value
+`a' by the corresponding value `b'.  The operation is performed according to
+the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float128 float128_div( float128 a, float128 b )
+{
+    flag aSign, bSign, zSign;
+    int32 aExp, bExp, zExp;
+    bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
+    bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
+    float128 z;
+
+    aSig1 = extractFloat128Frac1( a );
+    aSig0 = extractFloat128Frac0( a );
+    aExp = extractFloat128Exp( a );
+    aSign = extractFloat128Sign( a );
+    bSig1 = extractFloat128Frac1( b );
+    bSig0 = extractFloat128Frac0( b );
+    bExp = extractFloat128Exp( b );
+    bSign = extractFloat128Sign( b );
+    zSign = aSign ^ bSign;
+    if ( aExp == 0x7FFF ) {
+        if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b );
+        if ( bExp == 0x7FFF ) {
+            if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
+            goto invalid;
+        }
+        return packFloat128( zSign, 0x7FFF, 0, 0 );
+    }
+    if ( bExp == 0x7FFF ) {
+        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
+        return packFloat128( zSign, 0, 0, 0 );
+    }
+    if ( bExp == 0 ) {
+        if ( ( bSig0 | bSig1 ) == 0 ) {
+            if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
+ invalid:
+                float_raise( float_flag_invalid );
+                z.low = float128_default_nan_low;
+                z.high = float128_default_nan_high;
+                return z;
+            }
+            float_raise( float_flag_divbyzero );
+            return packFloat128( zSign, 0x7FFF, 0, 0 );
+        }
+        normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
+    }
+    if ( aExp == 0 ) {
+        if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
+        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
+    }
+    zExp = aExp - bExp + 0x3FFD;
+    shortShift128Left(
+        aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 );
+    shortShift128Left(
+        bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
+    if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) {
+        shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 );
+        ++zExp;
+    }
+    zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 );
+    mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 );
+    sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 );
+    while ( (sbits64) rem0 < 0 ) {
+        --zSig0;
+        add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 );
+    }
+    zSig1 = estimateDiv128To64( rem1, rem2, bSig0 );
+    if ( ( zSig1 & 0x3FFF ) <= 4 ) {
+        mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 );
+        sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 );
+        while ( (sbits64) rem1 < 0 ) {
+            --zSig1;
+            add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 );
+        }
+        zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
+    }
+    shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 );
+    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the remainder of the quadruple-precision floating-point value `a'
+with respect to the corresponding value `b'.  The operation is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float128 float128_rem( float128 a, float128 b )
+{
+    flag aSign, bSign, zSign;
+    int32 aExp, bExp, expDiff;
+    bits64 aSig0, aSig1, bSig0, bSig1;
+    bits64 q, term0, term1, term2, allZero, alternateASig0, alternateASig1;
+    bits64 sigMean1;
+    sbits64 sigMean0;
+    float128 z;
+
+    aSig1 = extractFloat128Frac1( a );
+    aSig0 = extractFloat128Frac0( a );
+    aExp = extractFloat128Exp( a );
+    aSign = extractFloat128Sign( a );
+    bSig1 = extractFloat128Frac1( b );
+    bSig0 = extractFloat128Frac0( b );
+    bExp = extractFloat128Exp( b );
+    bSign = extractFloat128Sign( b );
+    if ( aExp == 0x7FFF ) {
+        if (    ( aSig0 | aSig1 )
+             || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
+            return propagateFloat128NaN( a, b );
+        }
+        goto invalid;
+    }
+    if ( bExp == 0x7FFF ) {
+        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
+        return a;
+    }
+    if ( bExp == 0 ) {
+        if ( ( bSig0 | bSig1 ) == 0 ) {
+ invalid:
+            float_raise( float_flag_invalid );
+            z.low = float128_default_nan_low;
+            z.high = float128_default_nan_high;
+            return z;
+        }
+        normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
+    }
+    if ( aExp == 0 ) {
+        if ( ( aSig0 | aSig1 ) == 0 ) return a;
+        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
+    }
+    expDiff = aExp - bExp;
+    if ( expDiff < -1 ) return a;
+    shortShift128Left(
+        aSig0 | LIT64( 0x0001000000000000 ),
+        aSig1,
+        15 - ( expDiff < 0 ),
+        &aSig0,
+        &aSig1
+    );
+    shortShift128Left(
+        bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
+    q = le128( bSig0, bSig1, aSig0, aSig1 );
+    if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
+    expDiff -= 64;
+    while ( 0 < expDiff ) {
+        q = estimateDiv128To64( aSig0, aSig1, bSig0 );
+        q = ( 4 < q ) ? q - 4 : 0;
+        mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
+        shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero );
+        shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero );
+        sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 );
+        expDiff -= 61;
+    }
+    if ( -64 < expDiff ) {
+        q = estimateDiv128To64( aSig0, aSig1, bSig0 );
+        q = ( 4 < q ) ? q - 4 : 0;
+        q >>= - expDiff;
+        shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
+        expDiff += 52;
+        if ( expDiff < 0 ) {
+            shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
+        }
+        else {
+            shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 );
+        }
+        mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
+        sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 );
+    }
+    else {
+        shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 );
+        shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
+    }
+    do {
+        alternateASig0 = aSig0;
+        alternateASig1 = aSig1;
+        ++q;
+        sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
+    } while ( 0 <= (sbits64) aSig0 );
+    add128(
+        aSig0, aSig1, alternateASig0, alternateASig1, &sigMean0, &sigMean1 );
+    if (    ( sigMean0 < 0 )
+         || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {
+        aSig0 = alternateASig0;
+        aSig1 = alternateASig1;
+    }
+    zSign = ( (sbits64) aSig0 < 0 );
+    if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 );
+    return
+        normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the square root of the quadruple-precision floating-point value `a'.
+The operation is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float128 float128_sqrt( float128 a )
+{
+    flag aSign;
+    int32 aExp, zExp;
+    bits64 aSig0, aSig1, zSig0, zSig1, zSig2;
+    bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
+    bits64 shiftedRem0, shiftedRem1;
+    float128 z;
+
+    aSig1 = extractFloat128Frac1( a );
+    aSig0 = extractFloat128Frac0( a );
+    aExp = extractFloat128Exp( a );
+    aSign = extractFloat128Sign( a );
+    if ( aExp == 0x7FFF ) {
+        if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a );
+        if ( ! aSign ) return a;
+        goto invalid;
+    }
+    if ( aSign ) {
+        if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a;
+ invalid:
+        float_raise( float_flag_invalid );
+        z.low = float128_default_nan_low;
+        z.high = float128_default_nan_high;
+        return z;
+    }
+    if ( aExp == 0 ) {
+        if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 );
+        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
+    }
+    zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE;
+    aSig0 |= LIT64( 0x0001000000000000 );
+    zSig0 = estimateSqrt32( aExp, aSig0>>17 );
+    zSig0 <<= 31;
+    shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 );
+    zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0 ) + zSig0 + 4;
+    if ( 0 <= (sbits64) zSig0 ) zSig0 = LIT64( 0xFFFFFFFFFFFFFFFF );
+    shortShift128Left( aSig0, aSig1, 2, &aSig0, &aSig1 );
+    mul64To128( zSig0, zSig0, &term0, &term1 );
+    sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
+    while ( (sbits64) rem0 < 0 ) {
+        --zSig0;
+        shortShift128Left( 0, zSig0, 1, &term0, &term1 );
+        term1 |= 1;
+        add128( rem0, rem1, term0, term1, &rem0, &rem1 );
+    }
+    shortShift128Left( rem0, rem1, 63, &shiftedRem0, &shiftedRem1 );
+    zSig1 = estimateDiv128To64( shiftedRem0, shiftedRem1, zSig0 );
+    if ( ( zSig1 & 0x3FFF ) <= 5 ) {
+        if ( zSig1 == 0 ) zSig1 = 1;
+        mul64To128( zSig0, zSig1, &term1, &term2 );
+        shortShift128Left( term1, term2, 1, &term1, &term2 );
+        sub128( rem1, 0, term1, term2, &rem1, &rem2 );
+        mul64To128( zSig1, zSig1, &term2, &term3 );
+        sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
+        while ( (sbits64) rem1 < 0 ) {
+            --zSig1;
+            shortShift192Left( 0, zSig0, zSig1, 1, &term1, &term2, &term3 );
+            term3 |= 1;
+            add192(
+                rem1, rem2, rem3, term1, term2, term3, &rem1, &rem2, &rem3 );
+        }
+        zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
+    }
+    shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 );
+    return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the quadruple-precision floating-point value `a' is equal to
+the corresponding value `b', and 0 otherwise.  The comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float128_eq( float128 a, float128 b )
+{
+
+    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
+              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
+         || (    ( extractFloat128Exp( b ) == 0x7FFF )
+              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+       ) {
+        if (    float128_is_signaling_nan( a )
+             || float128_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid );
+        }
+        return 0;
+    }
+    return
+           ( a.low == b.low )
+        && (    ( a.high == b.high )
+             || (    ( a.low == 0 )
+                  && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) )
+           );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the quadruple-precision floating-point value `a' is less than
+or equal to the corresponding value `b', and 0 otherwise.  The comparison
+is performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float128_le( float128 a, float128 b )
+{
+    flag aSign, bSign;
+
+    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
+              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
+         || (    ( extractFloat128Exp( b ) == 0x7FFF )
+              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+       ) {
+        float_raise( float_flag_invalid );
+        return 0;
+    }
+    aSign = extractFloat128Sign( a );
+    bSign = extractFloat128Sign( b );
+    if ( aSign != bSign ) {
+        return
+               aSign
+            || (    ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
+                 == 0 );
+    }
+    return
+          aSign ? le128( b.high, b.low, a.high, a.low )
+        : le128( a.high, a.low, b.high, b.low );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the quadruple-precision floating-point value `a' is less than
+the corresponding value `b', and 0 otherwise.  The comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float128_lt( float128 a, float128 b )
+{
+    flag aSign, bSign;
+
+    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
+              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
+         || (    ( extractFloat128Exp( b ) == 0x7FFF )
+              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+       ) {
+        float_raise( float_flag_invalid );
+        return 0;
+    }
+    aSign = extractFloat128Sign( a );
+    bSign = extractFloat128Sign( b );
+    if ( aSign != bSign ) {
+        return
+               aSign
+            && (    ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
+                 != 0 );
+    }
+    return
+          aSign ? lt128( b.high, b.low, a.high, a.low )
+        : lt128( a.high, a.low, b.high, b.low );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the quadruple-precision floating-point value `a' is equal to
+the corresponding value `b', and 0 otherwise.  The invalid exception is
+raised if either operand is a NaN.  Otherwise, the comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float128_eq_signaling( float128 a, float128 b )
+{
+
+    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
+              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
+         || (    ( extractFloat128Exp( b ) == 0x7FFF )
+              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+       ) {
+        float_raise( float_flag_invalid );
+        return 0;
+    }
+    return
+           ( a.low == b.low )
+        && (    ( a.high == b.high )
+             || (    ( a.low == 0 )
+                  && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) )
+           );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the quadruple-precision floating-point value `a' is less than
+or equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
+cause an exception.  Otherwise, the comparison is performed according to the
+IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float128_le_quiet( float128 a, float128 b )
+{
+    flag aSign, bSign;
+
+    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
+              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
+         || (    ( extractFloat128Exp( b ) == 0x7FFF )
+              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+       ) {
+        if (    float128_is_signaling_nan( a )
+             || float128_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid );
+        }
+        return 0;
+    }
+    aSign = extractFloat128Sign( a );
+    bSign = extractFloat128Sign( b );
+    if ( aSign != bSign ) {
+        return
+               aSign
+            || (    ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
+                 == 0 );
+    }
+    return
+          aSign ? le128( b.high, b.low, a.high, a.low )
+        : le128( a.high, a.low, b.high, b.low );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the quadruple-precision floating-point value `a' is less than
+the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
+exception.  Otherwise, the comparison is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float128_lt_quiet( float128 a, float128 b )
+{
+    flag aSign, bSign;
+
+    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
+              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
+         || (    ( extractFloat128Exp( b ) == 0x7FFF )
+              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+       ) {
+        if (    float128_is_signaling_nan( a )
+             || float128_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid );
+        }
+        return 0;
+    }
+    aSign = extractFloat128Sign( a );
+    bSign = extractFloat128Sign( b );
+    if ( aSign != bSign ) {
+        return
+               aSign
+            && (    ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
+                 != 0 );
+    }
+    return
+          aSign ? lt128( b.high, b.low, a.high, a.low )
+        : lt128( a.high, a.low, b.high, b.low );
+
+}
+
+#endif
+
diff -urN linux-2.4.29/arch/armnommu/nwfpe/softfloat.h linux-2.4.29-uc1/arch/armnommu/nwfpe/softfloat.h
--- linux-2.4.29/arch/armnommu/nwfpe/softfloat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/softfloat.h	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,290 @@
+
+/*
+===============================================================================
+
+This C header file is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2.
+
+Written by John R. Hauser.  This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704.  Funding was partially provided by the
+National Science Foundation under grant MIP-9311980.  The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
+is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
+arithmetic/softfloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these three paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#ifndef __SOFTFLOAT_H__
+#define __SOFTFLOAT_H__
+
+/*
+-------------------------------------------------------------------------------
+The macro `FLOATX80' must be defined to enable the extended double-precision
+floating-point format `floatx80'.  If this macro is not defined, the
+`floatx80' type will not be defined, and none of the functions that either
+input or output the `floatx80' type will be defined.  The same applies to
+the `FLOAT128' macro and the quadruple-precision format `float128'.
+-------------------------------------------------------------------------------
+*/
+#define FLOATX80
+/* #define FLOAT128 */
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE floating-point types.
+-------------------------------------------------------------------------------
+*/
+typedef unsigned long int float32;
+typedef unsigned long long float64;
+#ifdef FLOATX80
+typedef struct {
+    unsigned short high;
+    unsigned long long low;
+} floatx80;
+#endif
+#ifdef FLOAT128
+typedef struct {
+    unsigned long long high, low;
+} float128;
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE floating-point underflow tininess-detection mode.
+-------------------------------------------------------------------------------
+*/
+extern signed char float_detect_tininess;
+enum {
+    float_tininess_after_rounding  = 0,
+    float_tininess_before_rounding = 1
+};
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE floating-point rounding mode.
+-------------------------------------------------------------------------------
+*/
+extern signed char float_rounding_mode;
+enum {
+    float_round_nearest_even = 0,
+    float_round_to_zero      = 1,
+    float_round_down         = 2,
+    float_round_up           = 3
+};
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE floating-point exception flags.
+-------------------------------------------------------------------------------
+extern signed char float_exception_flags;
+enum {
+    float_flag_inexact   =  1,
+    float_flag_underflow =  2,
+    float_flag_overflow  =  4,
+    float_flag_divbyzero =  8,
+    float_flag_invalid   = 16
+};
+
+ScottB: November 4, 1998
+Changed the enumeration to match the bit order in the FPA11.
+*/
+
+extern signed char float_exception_flags;
+enum {
+    float_flag_invalid   =  1,
+    float_flag_divbyzero =  2,
+    float_flag_overflow  =  4,
+    float_flag_underflow =  8,
+    float_flag_inexact   = 16
+};
+
+/*
+-------------------------------------------------------------------------------
+Routine to raise any or all of the software IEC/IEEE floating-point
+exception flags.
+-------------------------------------------------------------------------------
+*/
+void float_raise( signed char );
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE integer-to-floating-point conversion routines.
+-------------------------------------------------------------------------------
+*/
+float32 int32_to_float32( signed int );
+float64 int32_to_float64( signed int );
+#ifdef FLOATX80
+floatx80 int32_to_floatx80( signed int );
+#endif
+#ifdef FLOAT128
+float128 int32_to_float128( signed int );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE single-precision conversion routines.
+-------------------------------------------------------------------------------
+*/
+signed int float32_to_int32( float32 );
+signed int float32_to_int32_round_to_zero( float32 );
+float64 float32_to_float64( float32 );
+#ifdef FLOATX80
+floatx80 float32_to_floatx80( float32 );
+#endif
+#ifdef FLOAT128
+float128 float32_to_float128( float32 );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE single-precision operations.
+-------------------------------------------------------------------------------
+*/
+float32 float32_round_to_int( float32 );
+float32 float32_add( float32, float32 );
+float32 float32_sub( float32, float32 );
+float32 float32_mul( float32, float32 );
+float32 float32_div( float32, float32 );
+float32 float32_rem( float32, float32 );
+float32 float32_sqrt( float32 );
+char float32_eq( float32, float32 );
+char float32_le( float32, float32 );
+char float32_lt( float32, float32 );
+char float32_eq_signaling( float32, float32 );
+char float32_le_quiet( float32, float32 );
+char float32_lt_quiet( float32, float32 );
+char float32_is_signaling_nan( float32 );
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE double-precision conversion routines.
+-------------------------------------------------------------------------------
+*/
+signed int float64_to_int32( float64 );
+signed int float64_to_int32_round_to_zero( float64 );
+float32 float64_to_float32( float64 );
+#ifdef FLOATX80
+floatx80 float64_to_floatx80( float64 );
+#endif
+#ifdef FLOAT128
+float128 float64_to_float128( float64 );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE double-precision operations.
+-------------------------------------------------------------------------------
+*/
+float64 float64_round_to_int( float64 );
+float64 float64_add( float64, float64 );
+float64 float64_sub( float64, float64 );
+float64 float64_mul( float64, float64 );
+float64 float64_div( float64, float64 );
+float64 float64_rem( float64, float64 );
+float64 float64_sqrt( float64 );
+char float64_eq( float64, float64 );
+char float64_le( float64, float64 );
+char float64_lt( float64, float64 );
+char float64_eq_signaling( float64, float64 );
+char float64_le_quiet( float64, float64 );
+char float64_lt_quiet( float64, float64 );
+char float64_is_signaling_nan( float64 );
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE extended double-precision conversion routines.
+-------------------------------------------------------------------------------
+*/
+signed int floatx80_to_int32( floatx80 );
+signed int floatx80_to_int32_round_to_zero( floatx80 );
+float32 floatx80_to_float32( floatx80 );
+float64 floatx80_to_float64( floatx80 );
+#ifdef FLOAT128
+float128 floatx80_to_float128( floatx80 );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE extended double-precision rounding precision.  Valid
+values are 32, 64, and 80.
+-------------------------------------------------------------------------------
+*/
+extern signed char floatx80_rounding_precision;
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE extended double-precision operations.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_round_to_int( floatx80 );
+floatx80 floatx80_add( floatx80, floatx80 );
+floatx80 floatx80_sub( floatx80, floatx80 );
+floatx80 floatx80_mul( floatx80, floatx80 );
+floatx80 floatx80_div( floatx80, floatx80 );
+floatx80 floatx80_rem( floatx80, floatx80 );
+floatx80 floatx80_sqrt( floatx80 );
+char floatx80_eq( floatx80, floatx80 );
+char floatx80_le( floatx80, floatx80 );
+char floatx80_lt( floatx80, floatx80 );
+char floatx80_eq_signaling( floatx80, floatx80 );
+char floatx80_le_quiet( floatx80, floatx80 );
+char floatx80_lt_quiet( floatx80, floatx80 );
+char floatx80_is_signaling_nan( floatx80 );
+
+#endif
+
+#ifdef FLOAT128
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE quadruple-precision conversion routines.
+-------------------------------------------------------------------------------
+*/
+signed int float128_to_int32( float128 );
+signed int float128_to_int32_round_to_zero( float128 );
+float32 float128_to_float32( float128 );
+float64 float128_to_float64( float128 );
+#ifdef FLOATX80
+floatx80 float128_to_floatx80( float128 );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE quadruple-precision operations.
+-------------------------------------------------------------------------------
+*/
+float128 float128_round_to_int( float128 );
+float128 float128_add( float128, float128 );
+float128 float128_sub( float128, float128 );
+float128 float128_mul( float128, float128 );
+float128 float128_div( float128, float128 );
+float128 float128_rem( float128, float128 );
+float128 float128_sqrt( float128 );
+char float128_eq( float128, float128 );
+char float128_le( float128, float128 );
+char float128_lt( float128, float128 );
+char float128_eq_signaling( float128, float128 );
+char float128_le_quiet( float128, float128 );
+char float128_lt_quiet( float128, float128 );
+char float128_is_signaling_nan( float128 );
+
+#endif
+
+#endif
diff -urN linux-2.4.29/arch/armnommu/nwfpe/softfloat-macros linux-2.4.29-uc1/arch/armnommu/nwfpe/softfloat-macros
--- linux-2.4.29/arch/armnommu/nwfpe/softfloat-macros	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/softfloat-macros	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,740 @@
+
+/*
+===============================================================================
+
+This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2.
+
+Written by John R. Hauser.  This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704.  Funding was partially provided by the
+National Science Foundation under grant MIP-9311980.  The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
+is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
+arithmetic/softfloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these three paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Shifts `a' right by the number of bits given in `count'.  If any nonzero
+bits are shifted off, they are ``jammed'' into the least significant bit of
+the result by setting the least significant bit to 1.  The value of `count'
+can be arbitrarily large; in particular, if `count' is greater than 32, the
+result will be either 0 or 1, depending on whether `a' is zero or nonzero.
+The result is stored in the location pointed to by `zPtr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr )
+{
+    bits32 z;
+    if ( count == 0 ) {
+        z = a;
+    }
+    else if ( count < 32 ) {
+        z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 );
+    }
+    else {
+        z = ( a != 0 );
+    }
+    *zPtr = z;
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts `a' right by the number of bits given in `count'.  If any nonzero
+bits are shifted off, they are ``jammed'' into the least significant bit of
+the result by setting the least significant bit to 1.  The value of `count'
+can be arbitrarily large; in particular, if `count' is greater than 64, the
+result will be either 0 or 1, depending on whether `a' is zero or nonzero.
+The result is stored in the location pointed to by `zPtr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr )
+{
+    bits64 z;
+
+ __asm__("@shift64RightJamming -- start");   
+    if ( count == 0 ) {
+        z = a;
+    }
+    else if ( count < 64 ) {
+        z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 );
+    }
+    else {
+        z = ( a != 0 );
+    }
+ __asm__("@shift64RightJamming -- end");   
+    *zPtr = z;
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64
+_plus_ the number of bits given in `count'.  The shifted result is at most
+64 nonzero bits; this is stored at the location pointed to by `z0Ptr'.  The
+bits shifted off form a second 64-bit result as follows:  The _last_ bit
+shifted off is the most-significant bit of the extra result, and the other
+63 bits of the extra result are all zero if and only if _all_but_the_last_
+bits shifted off were all zero.  This extra result is stored in the location
+pointed to by `z1Ptr'.  The value of `count' can be arbitrarily large.
+    (This routine makes more sense if `a0' and `a1' are considered to form a
+fixed-point value with binary point between `a0' and `a1'.  This fixed-point
+value is shifted right by the number of bits given in `count', and the
+integer part of the result is returned at the location pointed to by
+`z0Ptr'.  The fractional part of the result may be slightly corrupted as
+described above, and is returned at the location pointed to by `z1Ptr'.)
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shift64ExtraRightJamming(
+     bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
+{
+    bits64 z0, z1;
+    int8 negCount = ( - count ) & 63;
+
+    if ( count == 0 ) {
+        z1 = a1;
+        z0 = a0;
+    }
+    else if ( count < 64 ) {
+        z1 = ( a0<<negCount ) | ( a1 != 0 );
+        z0 = a0>>count;
+    }
+    else {
+        if ( count == 64 ) {
+            z1 = a0 | ( a1 != 0 );
+        }
+        else {
+            z1 = ( ( a0 | a1 ) != 0 );
+        }
+        z0 = 0;
+    }
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
+number of bits given in `count'.  Any bits shifted off are lost.  The value
+of `count' can be arbitrarily large; in particular, if `count' is greater
+than 128, the result will be 0.  The result is broken into two 64-bit pieces
+which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shift128Right(
+     bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
+{
+    bits64 z0, z1;
+    int8 negCount = ( - count ) & 63;
+
+    if ( count == 0 ) {
+        z1 = a1;
+        z0 = a0;
+    }
+    else if ( count < 64 ) {
+        z1 = ( a0<<negCount ) | ( a1>>count );
+        z0 = a0>>count;
+    }
+    else {
+        z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0;
+        z0 = 0;
+    }
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
+number of bits given in `count'.  If any nonzero bits are shifted off, they
+are ``jammed'' into the least significant bit of the result by setting the
+least significant bit to 1.  The value of `count' can be arbitrarily large;
+in particular, if `count' is greater than 128, the result will be either 0
+or 1, depending on whether the concatenation of `a0' and `a1' is zero or
+nonzero.  The result is broken into two 64-bit pieces which are stored at
+the locations pointed to by `z0Ptr' and `z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shift128RightJamming(
+     bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
+{
+    bits64 z0, z1;
+    int8 negCount = ( - count ) & 63;
+
+    if ( count == 0 ) {
+        z1 = a1;
+        z0 = a0;
+    }
+    else if ( count < 64 ) {
+        z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 );
+        z0 = a0>>count;
+    }
+    else {
+        if ( count == 64 ) {
+            z1 = a0 | ( a1 != 0 );
+        }
+        else if ( count < 128 ) {
+            z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 );
+        }
+        else {
+            z1 = ( ( a0 | a1 ) != 0 );
+        }
+        z0 = 0;
+    }
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right
+by 64 _plus_ the number of bits given in `count'.  The shifted result is
+at most 128 nonzero bits; these are broken into two 64-bit pieces which are
+stored at the locations pointed to by `z0Ptr' and `z1Ptr'.  The bits shifted
+off form a third 64-bit result as follows:  The _last_ bit shifted off is
+the most-significant bit of the extra result, and the other 63 bits of the
+extra result are all zero if and only if _all_but_the_last_ bits shifted off
+were all zero.  This extra result is stored in the location pointed to by
+`z2Ptr'.  The value of `count' can be arbitrarily large.
+    (This routine makes more sense if `a0', `a1', and `a2' are considered
+to form a fixed-point value with binary point between `a1' and `a2'.  This
+fixed-point value is shifted right by the number of bits given in `count',
+and the integer part of the result is returned at the locations pointed to
+by `z0Ptr' and `z1Ptr'.  The fractional part of the result may be slightly
+corrupted as described above, and is returned at the location pointed to by
+`z2Ptr'.)
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shift128ExtraRightJamming(
+     bits64 a0,
+     bits64 a1,
+     bits64 a2,
+     int16 count,
+     bits64 *z0Ptr,
+     bits64 *z1Ptr,
+     bits64 *z2Ptr
+ )
+{
+    bits64 z0, z1, z2;
+    int8 negCount = ( - count ) & 63;
+
+    if ( count == 0 ) {
+        z2 = a2;
+        z1 = a1;
+        z0 = a0;
+    }
+    else {
+        if ( count < 64 ) {
+            z2 = a1<<negCount;
+            z1 = ( a0<<negCount ) | ( a1>>count );
+            z0 = a0>>count;
+        }
+        else {
+            if ( count == 64 ) {
+                z2 = a1;
+                z1 = a0;
+            }
+            else {
+                a2 |= a1;
+                if ( count < 128 ) {
+                    z2 = a0<<negCount;
+                    z1 = a0>>( count & 63 );
+                }
+                else {
+                    z2 = ( count == 128 ) ? a0 : ( a0 != 0 );
+                    z1 = 0;
+                }
+            }
+            z0 = 0;
+        }
+        z2 |= ( a2 != 0 );
+    }
+    *z2Ptr = z2;
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the
+number of bits given in `count'.  Any bits shifted off are lost.  The value
+of `count' must be less than 64.  The result is broken into two 64-bit
+pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shortShift128Left(
+     bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
+{
+
+    *z1Ptr = a1<<count;
+    *z0Ptr =
+        ( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 63 ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left
+by the number of bits given in `count'.  Any bits shifted off are lost.
+The value of `count' must be less than 64.  The result is broken into three
+64-bit pieces which are stored at the locations pointed to by `z0Ptr',
+`z1Ptr', and `z2Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shortShift192Left(
+     bits64 a0,
+     bits64 a1,
+     bits64 a2,
+     int16 count,
+     bits64 *z0Ptr,
+     bits64 *z1Ptr,
+     bits64 *z2Ptr
+ )
+{
+    bits64 z0, z1, z2;
+    int8 negCount;
+
+    z2 = a2<<count;
+    z1 = a1<<count;
+    z0 = a0<<count;
+    if ( 0 < count ) {
+        negCount = ( ( - count ) & 63 );
+        z1 |= a2>>negCount;
+        z0 |= a1>>negCount;
+    }
+    *z2Ptr = z2;
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit
+value formed by concatenating `b0' and `b1'.  Addition is modulo 2^128, so
+any carry out is lost.  The result is broken into two 64-bit pieces which
+are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ add128(
+     bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
+{
+    bits64 z1;
+
+    z1 = a1 + b1;
+    *z1Ptr = z1;
+    *z0Ptr = a0 + b0 + ( z1 < a1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the
+192-bit value formed by concatenating `b0', `b1', and `b2'.  Addition is
+modulo 2^192, so any carry out is lost.  The result is broken into three
+64-bit pieces which are stored at the locations pointed to by `z0Ptr',
+`z1Ptr', and `z2Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ add192(
+     bits64 a0,
+     bits64 a1,
+     bits64 a2,
+     bits64 b0,
+     bits64 b1,
+     bits64 b2,
+     bits64 *z0Ptr,
+     bits64 *z1Ptr,
+     bits64 *z2Ptr
+ )
+{
+    bits64 z0, z1, z2;
+    int8 carry0, carry1;
+
+    z2 = a2 + b2;
+    carry1 = ( z2 < a2 );
+    z1 = a1 + b1;
+    carry0 = ( z1 < a1 );
+    z0 = a0 + b0;
+    z1 += carry1;
+    z0 += ( z1 < carry1 );
+    z0 += carry0;
+    *z2Ptr = z2;
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the
+128-bit value formed by concatenating `a0' and `a1'.  Subtraction is modulo
+2^128, so any borrow out (carry out) is lost.  The result is broken into two
+64-bit pieces which are stored at the locations pointed to by `z0Ptr' and
+`z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ sub128(
+     bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
+{
+
+    *z1Ptr = a1 - b1;
+    *z0Ptr = a0 - b0 - ( a1 < b1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2'
+from the 192-bit value formed by concatenating `a0', `a1', and `a2'.
+Subtraction is modulo 2^192, so any borrow out (carry out) is lost.  The
+result is broken into three 64-bit pieces which are stored at the locations
+pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ sub192(
+     bits64 a0,
+     bits64 a1,
+     bits64 a2,
+     bits64 b0,
+     bits64 b1,
+     bits64 b2,
+     bits64 *z0Ptr,
+     bits64 *z1Ptr,
+     bits64 *z2Ptr
+ )
+{
+    bits64 z0, z1, z2;
+    int8 borrow0, borrow1;
+
+    z2 = a2 - b2;
+    borrow1 = ( a2 < b2 );
+    z1 = a1 - b1;
+    borrow0 = ( a1 < b1 );
+    z0 = a0 - b0;
+    z0 -= ( z1 < borrow1 );
+    z1 -= borrow1;
+    z0 -= borrow0;
+    *z2Ptr = z2;
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Multiplies `a' by `b' to obtain a 128-bit product.  The product is broken
+into two 64-bit pieces which are stored at the locations pointed to by
+`z0Ptr' and `z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr )
+{
+    bits32 aHigh, aLow, bHigh, bLow;
+    bits64 z0, zMiddleA, zMiddleB, z1;
+
+    aLow = a;
+    aHigh = a>>32;
+    bLow = b;
+    bHigh = b>>32;
+    z1 = ( (bits64) aLow ) * bLow;
+    zMiddleA = ( (bits64) aLow ) * bHigh;
+    zMiddleB = ( (bits64) aHigh ) * bLow;
+    z0 = ( (bits64) aHigh ) * bHigh;
+    zMiddleA += zMiddleB;
+    z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 );
+    zMiddleA <<= 32;
+    z1 += zMiddleA;
+    z0 += ( z1 < zMiddleA );
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Multiplies the 128-bit value formed by concatenating `a0' and `a1' by `b' to
+obtain a 192-bit product.  The product is broken into three 64-bit pieces
+which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
+`z2Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ mul128By64To192(
+     bits64 a0,
+     bits64 a1,
+     bits64 b,
+     bits64 *z0Ptr,
+     bits64 *z1Ptr,
+     bits64 *z2Ptr
+ )
+{
+    bits64 z0, z1, z2, more1;
+
+    mul64To128( a1, b, &z1, &z2 );
+    mul64To128( a0, b, &z0, &more1 );
+    add128( z0, more1, 0, z1, &z0, &z1 );
+    *z2Ptr = z2;
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the
+128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit
+product.  The product is broken into four 64-bit pieces which are stored at
+the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ mul128To256(
+     bits64 a0,
+     bits64 a1,
+     bits64 b0,
+     bits64 b1,
+     bits64 *z0Ptr,
+     bits64 *z1Ptr,
+     bits64 *z2Ptr,
+     bits64 *z3Ptr
+ )
+{
+    bits64 z0, z1, z2, z3;
+    bits64 more1, more2;
+
+    mul64To128( a1, b1, &z2, &z3 );
+    mul64To128( a1, b0, &z1, &more2 );
+    add128( z1, more2, 0, z2, &z1, &z2 );
+    mul64To128( a0, b0, &z0, &more1 );
+    add128( z0, more1, 0, z1, &z0, &z1 );
+    mul64To128( a0, b1, &more1, &more2 );
+    add128( more1, more2, 0, z2, &more1, &z2 );
+    add128( z0, z1, 0, more1, &z0, &z1 );
+    *z3Ptr = z3;
+    *z2Ptr = z2;
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns an approximation to the 64-bit integer quotient obtained by dividing
+`b' into the 128-bit value formed by concatenating `a0' and `a1'.  The
+divisor `b' must be at least 2^63.  If q is the exact quotient truncated
+toward zero, the approximation returned lies between q and q + 2 inclusive.
+If the exact quotient q is larger than 64 bits, the maximum positive 64-bit
+unsigned integer is returned.
+-------------------------------------------------------------------------------
+*/
+static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b )
+{
+    bits64 b0, b1;
+    bits64 rem0, rem1, term0, term1;
+    bits64 z;
+    if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF );
+    b0 = b>>32;
+    z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32;
+    mul64To128( b, z, &term0, &term1 );
+    sub128( a0, a1, term0, term1, &rem0, &rem1 );
+    while ( ( (sbits64) rem0 ) < 0 ) {
+        z -= LIT64( 0x100000000 );
+        b1 = b<<32;
+        add128( rem0, rem1, b0, b1, &rem0, &rem1 );
+    }
+    rem0 = ( rem0<<32 ) | ( rem1>>32 );
+    z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0;
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns an approximation to the square root of the 32-bit significand given
+by `a'.  Considered as an integer, `a' must be at least 2^31.  If bit 0 of
+`aExp' (the least significant bit) is 1, the integer returned approximates
+2^31*sqrt(`a'/2^31), where `a' is considered an integer.  If bit 0 of `aExp'
+is 0, the integer returned approximates 2^31*sqrt(`a'/2^30).  In either
+case, the approximation returned lies strictly within +/-2 of the exact
+value.
+-------------------------------------------------------------------------------
+*/
+static bits32 estimateSqrt32( int16 aExp, bits32 a )
+{
+    static const bits16 sqrtOddAdjustments[] = {
+        0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
+        0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
+    };
+    static const bits16 sqrtEvenAdjustments[] = {
+        0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
+        0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
+    };
+    int8 index;
+    bits32 z;
+
+    index = ( a>>27 ) & 15;
+    if ( aExp & 1 ) {
+        z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ];
+        z = ( ( a / z )<<14 ) + ( z<<15 );
+        a >>= 1;
+    }
+    else {
+        z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ];
+        z = a / z + z;
+        z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
+        if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );
+    }
+    return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the number of leading 0 bits before the most-significant 1 bit
+of `a'.  If `a' is zero, 32 is returned.
+-------------------------------------------------------------------------------
+*/
+static int8 countLeadingZeros32( bits32 a )
+{
+    static const int8 countLeadingZerosHigh[] = {
+        8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+    };
+    int8 shiftCount;
+
+    shiftCount = 0;
+    if ( a < 0x10000 ) {
+        shiftCount += 16;
+        a <<= 16;
+    }
+    if ( a < 0x1000000 ) {
+        shiftCount += 8;
+        a <<= 8;
+    }
+    shiftCount += countLeadingZerosHigh[ a>>24 ];
+    return shiftCount;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the number of leading 0 bits before the most-significant 1 bit
+of `a'.  If `a' is zero, 64 is returned.
+-------------------------------------------------------------------------------
+*/
+static int8 countLeadingZeros64( bits64 a )
+{
+    int8 shiftCount;
+
+    shiftCount = 0;
+    if ( a < ( (bits64) 1 )<<32 ) {
+        shiftCount += 32;
+    }
+    else {
+        a >>= 32;
+    }
+    shiftCount += countLeadingZeros32( a );
+    return shiftCount;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the 128-bit value formed by concatenating `a0' and `a1'
+is equal to the 128-bit value formed by concatenating `b0' and `b1'.
+Otherwise, returns 0.
+-------------------------------------------------------------------------------
+*/
+INLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
+{
+
+    return ( a0 == b0 ) && ( a1 == b1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
+than or equal to the 128-bit value formed by concatenating `b0' and `b1'.
+Otherwise, returns 0.
+-------------------------------------------------------------------------------
+*/
+INLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
+{
+
+    return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
+than the 128-bit value formed by concatenating `b0' and `b1'.  Otherwise,
+returns 0.
+-------------------------------------------------------------------------------
+*/
+INLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
+{
+
+    return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is
+not equal to the 128-bit value formed by concatenating `b0' and `b1'.
+Otherwise, returns 0.
+-------------------------------------------------------------------------------
+*/
+INLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
+{
+
+    return ( a0 != b0 ) || ( a1 != b1 );
+
+}
+
diff -urN linux-2.4.29/arch/armnommu/nwfpe/softfloat-specialize linux-2.4.29-uc1/arch/armnommu/nwfpe/softfloat-specialize
--- linux-2.4.29/arch/armnommu/nwfpe/softfloat-specialize	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/nwfpe/softfloat-specialize	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,471 @@
+
+/*
+===============================================================================
+
+This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2.
+
+Written by John R. Hauser.  This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704.  Funding was partially provided by the
+National Science Foundation under grant MIP-9311980.  The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
+is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
+arithmetic/softfloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these three paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Underflow tininess-detection mode, statically initialized to default value.
+(The declaration in `softfloat.h' must match the `int8' type here.)
+-------------------------------------------------------------------------------
+*/
+int8 float_detect_tininess = float_tininess_after_rounding;
+
+/*
+-------------------------------------------------------------------------------
+Raises the exceptions specified by `flags'.  Floating-point traps can be
+defined here if desired.  It is currently not possible for such a trap to
+substitute a result value.  If traps are not implemented, this routine
+should be simply `float_exception_flags |= flags;'.
+
+ScottB:  November 4, 1998
+Moved this function out of softfloat-specialize into fpmodule.c.
+This effectively isolates all the changes required for integrating with the
+Linux kernel into fpmodule.c.  Porting to NetBSD should only require modifying
+fpmodule.c to integrate with the NetBSD kernel (I hope!).
+-------------------------------------------------------------------------------
+void float_raise( int8 flags )
+{
+    float_exception_flags |= flags;
+}
+*/
+
+/*
+-------------------------------------------------------------------------------
+Internal canonical NaN format.
+-------------------------------------------------------------------------------
+*/
+typedef struct {
+    flag sign;
+    bits64 high, low;
+} commonNaNT;
+
+/*
+-------------------------------------------------------------------------------
+The pattern for a default generated single-precision NaN.
+-------------------------------------------------------------------------------
+*/
+#define float32_default_nan 0xFFFFFFFF
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is a NaN;
+otherwise returns 0.
+-------------------------------------------------------------------------------
+*/
+flag float32_is_nan( float32 a )
+{
+
+    return ( 0xFF000000 < (bits32) ( a<<1 ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is a signaling
+NaN; otherwise returns 0.
+-------------------------------------------------------------------------------
+*/
+flag float32_is_signaling_nan( float32 a )
+{
+
+    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the single-precision floating-point NaN
+`a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
+exception is raised.
+-------------------------------------------------------------------------------
+*/
+static commonNaNT float32ToCommonNaN( float32 a )
+{
+    commonNaNT z;
+
+    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
+    z.sign = a>>31;
+    z.low = 0;
+    z.high = ( (bits64) a )<<41;
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the canonical NaN `a' to the single-
+precision floating-point format.
+-------------------------------------------------------------------------------
+*/
+static float32 commonNaNToFloat32( commonNaNT a )
+{
+
+    return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes two single-precision floating-point values `a' and `b', one of which
+is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
+signaling NaN, the invalid exception is raised.
+-------------------------------------------------------------------------------
+*/
+static float32 propagateFloat32NaN( float32 a, float32 b )
+{
+    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
+
+    aIsNaN = float32_is_nan( a );
+    aIsSignalingNaN = float32_is_signaling_nan( a );
+    bIsNaN = float32_is_nan( b );
+    bIsSignalingNaN = float32_is_signaling_nan( b );
+    a |= 0x00400000;
+    b |= 0x00400000;
+    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
+    if ( aIsNaN ) {
+        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
+    }
+    else {
+        return b;
+    }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+The pattern for a default generated double-precision NaN.
+-------------------------------------------------------------------------------
+*/
+#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the double-precision floating-point value `a' is a NaN;
+otherwise returns 0.
+-------------------------------------------------------------------------------
+*/
+flag float64_is_nan( float64 a )
+{
+
+    return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the double-precision floating-point value `a' is a signaling
+NaN; otherwise returns 0.
+-------------------------------------------------------------------------------
+*/
+flag float64_is_signaling_nan( float64 a )
+{
+
+    return
+           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
+        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the double-precision floating-point NaN
+`a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
+exception is raised.
+-------------------------------------------------------------------------------
+*/
+static commonNaNT float64ToCommonNaN( float64 a )
+{
+    commonNaNT z;
+
+    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
+    z.sign = a>>63;
+    z.low = 0;
+    z.high = a<<12;
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the canonical NaN `a' to the double-
+precision floating-point format.
+-------------------------------------------------------------------------------
+*/
+static float64 commonNaNToFloat64( commonNaNT a )
+{
+
+    return
+          ( ( (bits64) a.sign )<<63 )
+        | LIT64( 0x7FF8000000000000 )
+        | ( a.high>>12 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes two double-precision floating-point values `a' and `b', one of which
+is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
+signaling NaN, the invalid exception is raised.
+-------------------------------------------------------------------------------
+*/
+static float64 propagateFloat64NaN( float64 a, float64 b )
+{
+    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
+
+    aIsNaN = float64_is_nan( a );
+    aIsSignalingNaN = float64_is_signaling_nan( a );
+    bIsNaN = float64_is_nan( b );
+    bIsSignalingNaN = float64_is_signaling_nan( b );
+    a |= LIT64( 0x0008000000000000 );
+    b |= LIT64( 0x0008000000000000 );
+    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
+    if ( aIsNaN ) {
+        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
+    }
+    else {
+        return b;
+    }
+
+}
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+The pattern for a default generated extended double-precision NaN.  The
+`high' and `low' values hold the most- and least-significant bits,
+respectively.
+-------------------------------------------------------------------------------
+*/
+#define floatx80_default_nan_high 0xFFFF
+#define floatx80_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the extended double-precision floating-point value `a' is a
+NaN; otherwise returns 0.
+-------------------------------------------------------------------------------
+*/
+flag floatx80_is_nan( floatx80 a )
+{
+
+    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the extended double-precision floating-point value `a' is a
+signaling NaN; otherwise returns 0.
+-------------------------------------------------------------------------------
+*/
+flag floatx80_is_signaling_nan( floatx80 a )
+{
+    //register int lr;
+    bits64 aLow;
+
+    //__asm__("mov %0, lr" : : "g" (lr));
+    //fp_printk("floatx80_is_signalling_nan() called from 0x%08x\n",lr);
+    aLow = a.low & ~ LIT64( 0x4000000000000000 );
+    return
+           ( ( a.high & 0x7FFF ) == 0x7FFF )
+        && (bits64) ( aLow<<1 )
+        && ( a.low == aLow );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the extended double-precision floating-
+point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
+invalid exception is raised.
+-------------------------------------------------------------------------------
+*/
+static commonNaNT floatx80ToCommonNaN( floatx80 a )
+{
+    commonNaNT z;
+
+    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
+    z.sign = a.high>>15;
+    z.low = 0;
+    z.high = a.low<<1;
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the canonical NaN `a' to the extended
+double-precision floating-point format.
+-------------------------------------------------------------------------------
+*/
+static floatx80 commonNaNToFloatx80( commonNaNT a )
+{
+    floatx80 z;
+
+    z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
+    z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes two extended double-precision floating-point values `a' and `b', one
+of which is a NaN, and returns the appropriate NaN result.  If either `a' or
+`b' is a signaling NaN, the invalid exception is raised.
+-------------------------------------------------------------------------------
+*/
+static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
+{
+    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
+
+    aIsNaN = floatx80_is_nan( a );
+    aIsSignalingNaN = floatx80_is_signaling_nan( a );
+    bIsNaN = floatx80_is_nan( b );
+    bIsSignalingNaN = floatx80_is_signaling_nan( b );
+    a.low |= LIT64( 0xC000000000000000 );
+    b.low |= LIT64( 0xC000000000000000 );
+    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
+    if ( aIsNaN ) {
+        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
+    }
+    else {
+        return b;
+    }
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+/*
+-------------------------------------------------------------------------------
+The pattern for a default generated quadruple-precision NaN.  The `high' and
+`low' values hold the most- and least-significant bits, respectively.
+-------------------------------------------------------------------------------
+*/
+#define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
+#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
+otherwise returns 0.
+-------------------------------------------------------------------------------
+*/
+flag float128_is_nan( float128 a )
+{
+
+    return
+           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
+        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the quadruple-precision floating-point value `a' is a
+signaling NaN; otherwise returns 0.
+-------------------------------------------------------------------------------
+*/
+flag float128_is_signaling_nan( float128 a )
+{
+
+    return
+           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
+        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the quadruple-precision floating-point NaN
+`a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
+exception is raised.
+-------------------------------------------------------------------------------
+*/
+static commonNaNT float128ToCommonNaN( float128 a )
+{
+    commonNaNT z;
+
+    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
+    z.sign = a.high>>63;
+    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the canonical NaN `a' to the quadruple-
+precision floating-point format.
+-------------------------------------------------------------------------------
+*/
+static float128 commonNaNToFloat128( commonNaNT a )
+{
+    float128 z;
+
+    shift128Right( a.high, a.low, 16, &z.high, &z.low );
+    z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
+    return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes two quadruple-precision floating-point values `a' and `b', one of
+which is a NaN, and returns the appropriate NaN result.  If either `a' or
+`b' is a signaling NaN, the invalid exception is raised.
+-------------------------------------------------------------------------------
+*/
+static float128 propagateFloat128NaN( float128 a, float128 b )
+{
+    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
+
+    aIsNaN = float128_is_nan( a );
+    aIsSignalingNaN = float128_is_signaling_nan( a );
+    bIsNaN = float128_is_nan( b );
+    bIsSignalingNaN = float128_is_signaling_nan( b );
+    a.high |= LIT64( 0x0000800000000000 );
+    b.high |= LIT64( 0x0000800000000000 );
+    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
+    if ( aIsNaN ) {
+        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
+    }
+    else {
+        return b;
+    }
+
+}
+
+#endif
+
diff -urN linux-2.4.29/arch/armnommu/tools/constants-hdr linux-2.4.29-uc1/arch/armnommu/tools/constants-hdr
--- linux-2.4.29/arch/armnommu/tools/constants-hdr	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/tools/constants-hdr	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * This file is automatically generated from arch/arm/tools/getconstants.c.
+ * Do not edit!  Only include this file in assembly (.S) files!
+ */
+
diff -urN linux-2.4.29/arch/armnommu/tools/gen-mach-types linux-2.4.29-uc1/arch/armnommu/tools/gen-mach-types
--- linux-2.4.29/arch/armnommu/tools/gen-mach-types	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/tools/gen-mach-types	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,73 @@
+#!/bin/awk
+#
+# Awk script to generate include/asm-arm/mach-types.h
+#
+BEGIN	{ nr = 0 }
+/^#/	{ next }
+/^[ 	]*$/ { next }
+
+NF == 4 {
+	  machine_is[nr] = "machine_is_"$1;
+	  config[nr] = "CONFIG_"$2;
+	  mach_type[nr] = "MACH_TYPE_"$3;
+	  num[nr] = $4; nr++
+	}
+
+NF == 3 {
+	  machine_is[nr] = "machine_is_"$1;
+	  config[nr] = "CONFIG_"$2;
+	  mach_type[nr] = "MACH_TYPE_"$3;
+	  num[nr] = ""; nr++
+	}
+
+
+END	{
+	  printf("/*\n");
+	  printf(" * This was automagically generated from %s!\n", FILENAME);
+	  printf(" * Do NOT edit\n");
+	  printf(" */\n\n");
+	  printf("#ifndef __ASM_ARM_MACH_TYPE_H\n");
+	  printf("#define __ASM_ARM_MACH_TYPE_H\n\n");
+	  printf("#include <linux/config.h>\n\n");
+	  printf("#ifndef __ASSEMBLY__\n");
+	  printf("/* The type of machine we're running on */\n");
+	  printf("extern unsigned int __machine_arch_type;\n");
+	  printf("#endif\n\n");
+
+	  printf("/* see arch/arm/kernel/arch.c for a description of these */\n");
+	  for (i = 0; i < nr; i++)
+	    if (num[i] ~ /..*/)
+	      printf("#define %-30s %d\n", mach_type[i], num[i]);
+
+	  printf("\n");
+
+	  for (i = 0; i < nr; i++)
+	    if (num[i] ~ /..*/) {
+	      printf("#ifdef %s\n", config[i]);
+	      printf("# ifdef machine_arch_type\n");
+	      printf("#  undef machine_arch_type\n");
+	      printf("#  define machine_arch_type\t__machine_arch_type\n");
+	      printf("# else\n");
+	      printf("#  define machine_arch_type\t%s\n", mach_type[i]);
+	      printf("# endif\n");
+	      printf("# define %s()\t(machine_arch_type == %s)\n", machine_is[i], mach_type[i]);
+	      printf("#else\n");
+	      printf("# define %s()\t(0)\n", machine_is[i]);
+	      printf("#endif\n\n");
+	    }
+
+	  printf("/*\n * These have not yet been registered\n */\n");
+	  for (i = 0; i < nr; i++)
+	    if (num[i] !~ /..*/)
+	      printf("/* #define %-30s <<not registered>> */\n", mach_type[i]);
+
+	  for (i = 0; i < nr; i++)
+	    if (num[i] !~ /..*/) {
+	      printf("#define %s()\t(0)\n", machine_is[i]);
+	    }
+
+	  printf("\n#ifndef machine_arch_type\n");
+	  printf("#define machine_arch_type\t__machine_arch_type\n");
+	  printf("#endif\n\n");
+	  printf("#endif\n");
+	}
diff -urN linux-2.4.29/arch/armnommu/tools/getconstants.c linux-2.4.29-uc1/arch/armnommu/tools/getconstants.c
--- linux-2.4.29/arch/armnommu/tools/getconstants.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/tools/getconstants.c	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,64 @@
+/*
+ *  linux/arch/arm/tools/getconsdata.c
+ *
+ *  Copyright (C) 1995-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+
+#ifndef __APCS_32__
+#error APCS-32 required
+#endif
+
+#define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n)
+
+#define DEFN(name,off) asm("\n#define "name" %0" :: "I" (off))
+
+void func(void)
+{
+DEFN("TSK_SIGPENDING",		OFF_TSK(sigpending));
+DEFN("TSK_ADDR_LIMIT",		OFF_TSK(addr_limit));
+DEFN("TSK_NEED_RESCHED",	OFF_TSK(need_resched));
+DEFN("TSK_PTRACE",		OFF_TSK(ptrace));
+DEFN("TSK_USED_MATH",		OFF_TSK(used_math));
+
+DEFN("TSS_SAVE",		OFF_TSK(thread.save));
+DEFN("TSS_FPESAVE",		OFF_TSK(thread.fpstate.soft.save));
+
+#ifdef CONFIG_CPU_32
+DEFN("TSS_DOMAIN",		OFF_TSK(thread.domain));
+
+DEFN("HPTE_TYPE_SMALL",		PTE_TYPE_SMALL);
+DEFN("HPTE_AP_READ",		PTE_AP_READ);
+DEFN("HPTE_AP_WRITE",		PTE_AP_WRITE);
+
+DEFN("LPTE_PRESENT",		L_PTE_PRESENT);
+DEFN("LPTE_YOUNG",		L_PTE_YOUNG);
+DEFN("LPTE_BUFFERABLE",		L_PTE_BUFFERABLE);
+DEFN("LPTE_CACHEABLE",		L_PTE_CACHEABLE);
+DEFN("LPTE_USER",		L_PTE_USER);
+DEFN("LPTE_WRITE",		L_PTE_WRITE);
+DEFN("LPTE_EXEC",		L_PTE_EXEC);
+DEFN("LPTE_DIRTY",		L_PTE_DIRTY);
+#endif
+
+#ifdef CONFIG_CPU_26
+DEFN("PAGE_PRESENT",		_PAGE_PRESENT);
+DEFN("PAGE_READONLY",		_PAGE_READONLY);
+DEFN("PAGE_NOT_USER",		_PAGE_NOT_USER);
+DEFN("PAGE_OLD",		_PAGE_OLD);
+DEFN("PAGE_CLEAN",		_PAGE_CLEAN);
+#endif
+
+DEFN("PAGE_SZ",			PAGE_SIZE);
+
+DEFN("SYS_ERROR0",		0x9f0000);
+}
diff -urN linux-2.4.29/arch/armnommu/tools/mach-types linux-2.4.29-uc1/arch/armnommu/tools/mach-types
--- linux-2.4.29/arch/armnommu/tools/mach-types	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/tools/mach-types	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,604 @@
+# Database of machine macros and numbers
+#
+# This file is linux/arch/arm/tools/mach-types
+#
+# Please do not send patches to this file; it is automatically generated!
+# To add an entry into this database, please see Documentation/arm/README,
+# or contact rmk@arm.linux.org.uk
+#
+# Last update: Tue Aug 24 06:25:28 2004
+#
+# machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
+#
+ebsa110			ARCH_EBSA110		EBSA110			0
+riscpc			ARCH_RPC		RISCPC			1
+nexuspci		ARCH_NEXUSPCI		NEXUSPCI		3
+ebsa285			ARCH_EBSA285		EBSA285			4
+netwinder		ARCH_NETWINDER		NETWINDER		5
+cats			ARCH_CATS		CATS			6
+tbox			ARCH_TBOX		TBOX			7
+co285			ARCH_CO285		CO285			8
+clps7110		ARCH_CLPS7110		CLPS7110		9
+archimedes		ARCH_ARC		ARCHIMEDES		10
+a5k			ARCH_A5K		A5K			11
+etoile			ARCH_ETOILE		ETOILE			12
+lacie_nas		ARCH_LACIE_NAS		LACIE_NAS		13
+clps7500		ARCH_CLPS7500		CLPS7500		14
+shark			ARCH_SHARK		SHARK			15
+brutus			SA1100_BRUTUS		BRUTUS			16
+personal_server		ARCH_PERSONAL_SERVER	PERSONAL_SERVER		17
+itsy			SA1100_ITSY		ITSY			18
+l7200			ARCH_L7200		L7200			19
+pleb			SA1100_PLEB		PLEB			20
+integrator		ARCH_INTEGRATOR		INTEGRATOR		21
+h3600			SA1100_H3600		H3600			22
+ixp1200			ARCH_IXP1200		IXP1200			23
+p720t			ARCH_P720T		P720T			24
+assabet			SA1100_ASSABET		ASSABET			25
+victor			SA1100_VICTOR		VICTOR			26
+lart			SA1100_LART		LART			27
+ranger			SA1100_RANGER		RANGER			28
+graphicsclient		SA1100_GRAPHICSCLIENT	GRAPHICSCLIENT		29
+xp860			SA1100_XP860		XP860			30
+cerf			SA1100_CERF		CERF			31
+nanoengine		SA1100_NANOENGINE	NANOENGINE		32
+fpic			SA1100_FPIC		FPIC			33
+extenex1		SA1100_EXTENEX1		EXTENEX1		34
+sherman			SA1100_SHERMAN		SHERMAN			35
+accelent_sa		SA1100_ACCELENT		ACCELENT_SA		36
+accelent_l7200		ARCH_L7200_ACCELENT	ACCELENT_L7200		37
+netport			SA1100_NETPORT		NETPORT			38
+pangolin		SA1100_PANGOLIN		PANGOLIN		39
+yopy			SA1100_YOPY		YOPY			40
+coolidge		SA1100_COOLIDGE		COOLIDGE		41
+huw_webpanel		SA1100_HUW_WEBPANEL	HUW_WEBPANEL		42
+spotme			ARCH_SPOTME		SPOTME			43
+freebird		ARCH_FREEBIRD		FREEBIRD		44
+ti925			ARCH_TI925		TI925			45
+riscstation		ARCH_RISCSTATION	RISCSTATION		46
+cavy			SA1100_CAVY		CAVY			47
+jornada720		SA1100_JORNADA720	JORNADA720		48
+omnimeter		SA1100_OMNIMETER	OMNIMETER		49
+edb7211			ARCH_EDB7211		EDB7211			50
+citygo			SA1100_CITYGO		CITYGO			51
+pfs168			SA1100_PFS168		PFS168			52
+spot			SA1100_SPOT		SPOT			53
+flexanet		SA1100_FLEXANET		FLEXANET		54
+webpal			ARCH_WEBPAL		WEBPAL			55
+linpda			SA1100_LINPDA		LINPDA			56
+anakin			ARCH_ANAKIN		ANAKIN			57
+mvi			SA1100_MVI		MVI			58
+jupiter			SA1100_JUPITER		JUPITER			59
+psionw			ARCH_PSIONW		PSIONW			60
+aln			SA1100_ALN		ALN			61
+epxa			ARCH_CAMELOT		CAMELOT			62
+gds2200			SA1100_GDS2200		GDS2200			63
+psion_series7		SA1100_PSION_SERIES7	PSION_SERIES7		64
+xfile			SA1100_XFILE		XFILE			65
+accelent_ep9312		ARCH_ACCELENT_EP9312	ACCELENT_EP9312		66
+ic200			ARCH_IC200		IC200			67
+creditlart		SA1100_CREDITLART	CREDITLART		68
+htm			SA1100_HTM		HTM			69
+iq80310			ARCH_IQ80310		IQ80310			70
+freebot			SA1100_FREEBOT		FREEBOT			71
+entel			ARCH_ENTEL		ENTEL			72
+enp3510			ARCH_ENP3510		ENP3510			73
+trizeps			SA1100_TRIZEPS		TRIZEPS			74
+nesa			SA1100_NESA		NESA			75
+venus			ARCH_VENUS		VENUS			76
+tardis			ARCH_TARDIS		TARDIS			77
+mercury			ARCH_MERCURY		MERCURY			78
+empeg			SA1100_EMPEG		EMPEG			79
+adi_evb			ARCH_I80200FCC		I80200FCC		80
+itt_cpb			SA1100_ITT_CPB		ITT_CPB			81
+svc			SA1100_SVC		SVC			82
+alpha2			SA1100_ALPHA2		ALPHA2			84
+alpha1			SA1100_ALPHA1		ALPHA1			85
+netarm			ARCH_NETARM		NETARM			86
+simpad			SA1100_SIMPAD		SIMPAD			87
+pda1			ARCH_PDA1		PDA1			88
+lubbock			ARCH_LUBBOCK		LUBBOCK			89
+aniko			ARCH_ANIKO		ANIKO			90
+clep7212		ARCH_CLEP7212		CLEP7212		91
+cs89712			ARCH_CS89712		CS89712			92
+weararm			SA1100_WEARARM		WEARARM			93
+possio_px		SA1100_POSSIO_PX	POSSIO_PX		94
+sidearm			SA1100_SIDEARM		SIDEARM			95
+stork			SA1100_STORK		STORK			96
+shannon			SA1100_SHANNON		SHANNON			97
+ace			ARCH_ACE		ACE			98
+ballyarm		SA1100_BALLYARM		BALLYARM		99
+simputer		SA1100_SIMPUTER		SIMPUTER		100
+nexterm			SA1100_NEXTERM		NEXTERM			101
+sa1100_elf		SA1100_SA1100_ELF	SA1100_ELF		102
+gator			SA1100_GATOR		GATOR			103
+granite			ARCH_GRANITE		GRANITE			104
+consus			SA1100_CONSUS		CONSUS			105
+aaed2000		ARCH_AAED2000		AAED2000		106
+cdb89712		ARCH_CDB89712		CDB89712		107
+graphicsmaster		SA1100_GRAPHICSMASTER	GRAPHICSMASTER		108
+adsbitsy		SA1100_ADSBITSY		ADSBITSY		109
+pxa_idp			ARCH_PXA_IDP		PXA_IDP			110
+plce			ARCH_PLCE		PLCE			111
+pt_system3		SA1100_PT_SYSTEM3	PT_SYSTEM3		112
+murphy			ARCH_MEDALB		MEDALB			113
+eagle			ARCH_EAGLE		EAGLE			114
+dsc21			ARCH_DSC21		DSC21			115
+dsc24			ARCH_DSC24		DSC24			116
+ti5472			ARCH_TI5472		TI5472			117
+autcpu12		ARCH_AUTCPU12		AUTCPU12		118
+uengine			ARCH_UENGINE		UENGINE			119
+bluestem		SA1100_BLUESTEM		BLUESTEM		120
+xingu8			ARCH_XINGU8		XINGU8			121
+bushstb			ARCH_BUSHSTB		BUSHSTB			122
+epsilon1		SA1100_EPSILON1		EPSILON1		123
+balloon			SA1100_BALLOON		BALLOON			124
+puppy			ARCH_PUPPY		PUPPY			125
+elroy			SA1100_ELROY		ELROY			126
+gms720			ARCH_GMS720		GMS720			127
+s24x			ARCH_S24X		S24X			128
+jtel_clep7312		ARCH_JTEL_CLEP7312	JTEL_CLEP7312		129
+cx821xx			ARCH_CX821XX		CX821XX			130
+edb7312			ARCH_EDB7312		EDB7312			131
+bsa1110			SA1100_BSA1110		BSA1110			132
+powerpin		ARCH_POWERPIN		POWERPIN		133
+openarm			ARCH_OPENARM		OPENARM			134
+whitechapel		SA1100_WHITECHAPEL	WHITECHAPEL		135
+h3100			SA1100_H3100		H3100			136
+h3800			SA1100_H3800		H3800			137
+blue_v1			ARCH_BLUE_V1		BLUE_V1			138
+pxa_cerf		ARCH_PXA_CERF		PXA_CERF		139
+arm7tevb		ARCH_ARM7TEVB		ARM7TEVB		140
+d7400			SA1100_D7400		D7400			141
+piranha			ARCH_PIRANHA		PIRANHA			142
+sbcamelot		SA1100_SBCAMELOT	SBCAMELOT		143
+kings			SA1100_KINGS		KINGS			144
+smdk2400		ARCH_SMDK2400		SMDK2400		145
+collie			SA1100_COLLIE		COLLIE			146
+idr			ARCH_IDR		IDR			147
+badge4			SA1100_BADGE4		BADGE4			148
+webnet			ARCH_WEBNET		WEBNET			149
+d7300			SA1100_D7300		D7300			150
+cep			SA1100_CEP		CEP			151
+fortunet		ARCH_FORTUNET		FORTUNET		152
+vc547x			ARCH_VC547X		VC547X			153
+filewalker		SA1100_FILEWALKER	FILEWALKER		154
+netgateway		SA1100_NETGATEWAY	NETGATEWAY		155
+symbol2800		SA1100_SYMBOL2800	SYMBOL2800		156
+suns			SA1100_SUNS		SUNS			157
+frodo			SA1100_FRODO		FRODO			158
+ms301			SA1100_MACH_TYTE_MS301	MACH_TYTE_MS301		159
+mx1ads			ARCH_MX1ADS		MX1ADS			160
+h7201			ARCH_H7201		H7201			161
+h7202			ARCH_H7202		H7202			162
+amico			ARCH_AMICO		AMICO			163
+iam			SA1100_IAM		IAM			164
+tt530			SA1100_TT530		TT530			165
+sam2400			ARCH_SAM2400		SAM2400			166
+jornada56x		SA1100_JORNADA56X	JORNADA56X		167
+active			SA1100_ACTIVE		ACTIVE			168
+iq80321			ARCH_IQ80321		IQ80321			169
+wid			SA1100_WID		WID			170
+sabinal			ARCH_SABINAL		SABINAL			171
+ixp425_matacumbe	ARCH_IXP425_MATACUMBE	IXP425_MATACUMBE	172
+miniprint		SA1100_MINIPRINT	MINIPRINT		173
+adm510x			ARCH_ADM510X		ADM510X			174
+svs200			SA1100_SVS200		SVS200			175
+atg_tcu			ARCH_ATG_TCU		ATG_TCU			176
+jornada820		SA1100_JORNADA820	JORNADA820		177
+s3c44b0			ARCH_S3C44B0		S3C44B0			178
+margis2			ARCH_MARGIS2		MARGIS2			179
+ks8695			ARCH_KS8695		KS8695			180
+brh			ARCH_BRH		BRH			181
+s3c2410			ARCH_S3C2410		S3C2410			182
+possio_px30		ARCH_POSSIO_PX30	POSSIO_PX30		183
+s3c2800			ARCH_S3C2800		S3C2800			184
+fleetwood		SA1100_FLEETWOOD	FLEETWOOD		185
+omaha			ARCH_OMAHA		OMAHA			186
+ta7			ARCH_TA7		TA7			187
+nova			SA1100_NOVA		NOVA			188
+hmk			ARCH_HMK		HMK			189
+karo			ARCH_KARO		KARO			190
+fester			SA1100_FESTER		FESTER			191
+gpi			ARCH_GPI		GPI			192
+smdk2410		ARCH_SMDK2410		SMDK2410		193
+i519			ARCH_I519		I519			194
+nexio			SA1100_NEXIO		NEXIO			195
+bitbox			SA1100_BITBOX		BITBOX			196
+g200			SA1100_G200		G200			197
+gill			SA1100_GILL		GILL			198
+pxa_mercury		ARCH_PXA_MERCURY	PXA_MERCURY		199
+ceiva			ARCH_CEIVA		CEIVA			200
+fret			SA1100_FRET		FRET			201
+emailphone		SA1100_EMAILPHONE	EMAILPHONE		202
+h3900			ARCH_H3900		H3900			203
+pxa1			ARCH_PXA1		PXA1			204
+koan369			SA1100_KOAN369		KOAN369			205
+cogent			ARCH_COGENT		COGENT			206
+esl_simputer		ARCH_ESL_SIMPUTER	ESL_SIMPUTER		207
+esl_simputer_clr	ARCH_ESL_SIMPUTER_CLR	ESL_SIMPUTER_CLR	208
+esl_simputer_bw		ARCH_ESL_SIMPUTER_BW	ESL_SIMPUTER_BW		209
+hhp_cradle		ARCH_HHP_CRADLE		HHP_CRADLE		210
+he500			ARCH_HE500		HE500			211
+inhandelf2		SA1100_INHANDELF2	INHANDELF2		212
+inhandftip		SA1100_INHANDFTIP	INHANDFTIP		213
+dnp1110			SA1100_DNP1110		DNP1110			214
+pnp1110			SA1100_PNP1110		PNP1110			215
+csb226			ARCH_CSB226		CSB226			216
+arnold			SA1100_ARNOLD		ARNOLD			217
+psiboard		SA1100_PSIBOARD		PSIBOARD		218
+jz8028			ARCH_JZ8028		JZ8028			219
+h5400			ARCH_H5400		H5400			220
+forte			SA1100_FORTE		FORTE			221
+acam			SA1100_ACAM		ACAM			222
+abox			SA1100_ABOX		ABOX			223
+atmel			ARCH_ATMEL		ATMEL			224
+sitsang			ARCH_SITSANG		SITSANG			225
+cpu1110lcdnet		SA1100_CPU1110LCDNET	CPU1110LCDNET		226
+mpl_vcma9		ARCH_MPL_VCMA9		MPL_VCMA9		227
+opus_a1			ARCH_OPUS_A1		OPUS_A1			228
+daytona			ARCH_DAYTONA		DAYTONA			229
+killbear		SA1100_KILLBEAR		KILLBEAR		230
+yoho			ARCH_YOHO		YOHO			231
+jasper			ARCH_JASPER		JASPER			232
+dsc25			ARCH_DSC25		DSC25			233
+omap_innovator		MACH_OMAP_INNOVATOR	OMAP_INNOVATOR		234
+ramses			ARCH_RAMSES		RAMSES			235
+s28x			ARCH_S28X		S28X			236
+mport3			ARCH_MPORT3		MPORT3			237
+pxa_eagle250		ARCH_PXA_EAGLE250	PXA_EAGLE250		238
+pdb			ARCH_PDB		PDB			239
+blue_2g			SA1100_BLUE_2G		BLUE_2G			240
+bluearch		SA1100_BLUEARCH		BLUEARCH		241
+ixdp2400		ARCH_IXDB2400		IXDB2400		242
+ixdp2800		ARCH_IXDB2800		IXDB2800		243
+explorer		SA1100_EXPLORER		EXPLORER		244
+ixdp425			ARCH_IXDP425		IXDP425			245
+chimp			ARCH_CHIMP		CHIMP			246
+stork_nest		ARCH_STORK_NEST		STORK_NEST		247
+stork_egg		ARCH_STORK_EGG		STORK_EGG		248
+wismo			SA1100_WISMO		WISMO			249
+ezlinx			ARCH_EZLINX		EZLINX			250
+at91rm9200		ARCH_AT91RM9200		AT91RM9200		251
+orion			ARCH_ORION		ORION			252
+neptune			ARCH_NEPTUNE		NEPTUNE			253
+hackkit			SA1100_HACKKIT		HACKKIT			254
+pxa_wins30		ARCH_PXA_WINS30		PXA_WINS30		255
+lavinna			SA1100_LAVINNA		LAVINNA			256
+pxa_uengine		ARCH_PXA_UENGINE	PXA_UENGINE		257
+innokom			ARCH_INNOKOM		INNOKOM			258
+bms			ARCH_BMS		BMS			259
+ixcdp1100		ARCH_IXCDP1100		IXCDP1100		260
+prpmc1100		ARCH_PRPMC1100		PRPMC1100		261
+at91rm9200dk		ARCH_AT91RM9200DK	AT91RM9200DK		262
+armstick		ARCH_ARMSTICK		ARMSTICK		263
+armonie			ARCH_ARMONIE		ARMONIE			264
+mport1			ARCH_MPORT1		MPORT1			265
+s3c5410			ARCH_S3C5410		S3C5410			266
+zcp320a			ARCH_ZCP320A		ZCP320A			267
+i_box			ARCH_I_BOX		I_BOX			268
+stlc1502		ARCH_STLC1502		STLC1502		269
+siren			ARCH_SIREN		SIREN			270
+greenlake		ARCH_GREENLAKE		GREENLAKE		271
+argus			ARCH_ARGUS		ARGUS			272
+combadge		SA1100_COMBADGE		COMBADGE		273
+rokepxa			ARCH_ROKEPXA		ROKEPXA			274
+cintegrator		ARCH_CINTEGRATOR	CINTEGRATOR		275
+guidea07		ARCH_GUIDEA07		GUIDEA07		276
+tat257			ARCH_TAT257		TAT257			277
+igp2425			ARCH_IGP2425		IGP2425			278
+bluegrama		ARCH_BLUEGRAMMA		BLUEGRAMMA		279
+ipod			ARCH_IPOD		IPOD			280
+adsbitsyx		ARCH_ADSBITSYX		ADSBITSYX		281
+trizeps2		ARCH_TRIZEPS2		TRIZEPS2		282
+viper			ARCH_VIPER		VIPER			283
+adsbitsyplus		SA1100_ADSBITSYPLUS	ADSBITSYPLUS		284
+adsagc			SA1100_ADSAGC		ADSAGC			285
+stp7312			ARCH_STP7312		STP7312			286
+nx_phnx			MACH_NX_PHNX		NX_PHNX			287
+wep_ep250		ARCH_WEP_EP250		WEP_EP250		288
+inhandelf3		ARCH_INHANDELF3		INHANDELF3		289
+adi_coyote		ARCH_ADI_COYOTE		ADI_COYOTE		290
+iyonix			ARCH_IYONIX		IYONIX			291
+damicam1		ARCH_DAMICAM_SA1110	DAMICAM_SA1110		292
+meg03			ARCH_MEG03		MEG03			293
+pxa_whitechapel		ARCH_PXA_WHITECHAPEL	PXA_WHITECHAPEL		294
+nwsc			ARCH_NWSC		NWSC			295
+nwlarm			ARCH_NWLARM		NWLARM			296
+ixp425_mguard		ARCH_IXP425_MGUARD	IXP425_MGUARD		297
+pxa_netdcu4		ARCH_PXA_NETDCU4	PXA_NETDCU4		298
+ixdp2401		ARCH_IXDP2401		IXDP2401		299
+ixdp2801		ARCH_IXDP2801		IXDP2801		300
+zodiac			ARCH_ZODIAC		ZODIAC			301
+armmodul		ARCH_ARMMODUL		ARMMODUL		302
+ketop			SA1100_KETOP		KETOP			303
+av7200			ARCH_AV7200		AV7200			304
+arch_ti925		ARCH_ARCH_TI925		ARCH_TI925		305
+acq200			ARCH_ACQ200		ACQ200			306
+pt_dafit		SA1100_PT_DAFIT		PT_DAFIT		307
+ihba			ARCH_IHBA		IHBA			308
+quinque			ARCH_QUINQUE		QUINQUE			309
+nimbraone		ARCH_NIMBRAONE		NIMBRAONE		310
+nimbra29x		ARCH_NIMBRA29X		NIMBRA29X		311
+nimbra210		ARCH_NIMBRA210		NIMBRA210		312
+hhp_d95xx		ARCH_HHP_D95XX		HHP_D95XX		313
+labarm			ARCH_LABARM		LABARM			314
+m825xx			ARCH_M825XX		M825XX			315
+m7100			SA1100_M7100		M7100			316
+nipc2			ARCH_NIPC2		NIPC2			317
+fu7202			ARCH_FU7202		FU7202			318
+adsagx			ARCH_ADSAGX		ADSAGX			319
+pxa_pooh		ARCH_PXA_POOH		PXA_POOH		320
+bandon			ARCH_BANDON		BANDON			321
+pcm7210			ARCH_PCM7210		PCM7210			322
+nms9200			ARCH_NMS9200		NMS9200			323
+logodl			ARCH_LOGODL		LOGODL			324
+m7140			SA1100_M7140		M7140			325
+korebot			ARCH_KOREBOT		KOREBOT			326
+iq31244			ARCH_IQ31244		IQ31244			327
+koan393			SA1100_KOAN393		KOAN393			328
+inhandftip3		ARCH_INHANDFTIP3	INHANDFTIP3		329
+gonzo			ARCH_GONZO		GONZO			330
+bast			ARCH_BAST		BAST			331
+scanpass		ARCH_SCANPASS		SCANPASS		332
+ep7312_pooh		ARCH_EP7312_POOH	EP7312_POOH		333
+ta7s			ARCH_TA7S		TA7S			334
+ta7v			ARCH_TA7V		TA7V			335
+icarus			SA1100_ICARUS		ICARUS			336
+h1900			ARCH_H1900		H1900			337
+gemini			SA1100_GEMINI		GEMINI			338
+axim			ARCH_AXIM		AXIM			339
+audiotron		ARCH_AUDIOTRON		AUDIOTRON		340
+h2200			ARCH_H2200		H2200			341
+loox600			ARCH_LOOX600		LOOX600			342
+niop			ARCH_NIOP		NIOP			343
+dm310			ARCH_DM310		DM310			344
+seedpxa_c2		ARCH_SEEDPXA_C2		SEEDPXA_C2		345
+ixp4xx_mguardpci	ARCH_IXP4XX_MGUARD_PCI	IXP4XX_MGUARD_PCI	346
+h1940			ARCH_H1940		H1940			347
+scorpio			ARCH_SCORPIO		SCORPIO			348
+viva			ARCH_VIVA		VIVA			349
+pxa_xcard		ARCH_PXA_XCARD		PXA_XCARD		350
+csb335			ARCH_CSB335		CSB335			351
+ixrd425			ARCH_IXRD425		IXRD425			352
+iq80315			ARCH_IQ80315		IQ80315			353
+nmp7312			ARCH_NMP7312		NMP7312			354
+cx861xx			ARCH_CX861XX		CX861XX			355
+enp2611			ARCH_ENP2611		ENP2611			356
+xda			SA1100_XDA		XDA			357
+csir_ims		ARCH_CSIR_IMS		CSIR_IMS		358
+ixp421_dnaeeth		ARCH_IXP421_DNAEETH	IXP421_DNAEETH		359
+pocketserv9200		ARCH_POCKETSERV9200	POCKETSERV9200		360
+toto			ARCH_TOTO		TOTO			361
+s3c2440			ARCH_S3C2440		S3C2440			362
+ks8695p			ARCH_KS8695P		KS8695P			363
+se4000			ARCH_SE4000		SE4000			364
+quadriceps		ARCH_QUADRICEPS		QUADRICEPS		365
+bronco			ARCH_BRONCO		BRONCO			366
+esl_wireless_tab	ARCH_ESL_WIRELESS_TABLETESL_WIRELESS_TABLET	367
+esl_sofcomp		ARCH_ESL_SOFCOMP	ESL_SOFCOMP		368
+s5c7375			ARCH_S5C7375		S5C7375			369
+spearhead		ARCH_SPEARHEAD		SPEARHEAD		370
+pantera			ARCH_PANTERA		PANTERA			371
+prayoglite		ARCH_PRAYOGLITE		PRAYOGLITE		372
+gumstik			ARCH_GUMSTIK		GUMSTIK			373
+rcube			ARCH_RCUBE		RCUBE			374
+rea_olv			ARCH_REA_OLV		REA_OLV			375
+pxa_iphone		ARCH_PXA_IPHONE		PXA_IPHONE		376
+s3c3410			ARCH_S3C3410		S3C3410			377
+espd_4510b		ARCH_ESPD_4510B		ESPD_4510B		378
+mp1x			ARCH_MP1X		MP1X			379
+at91rm9200tb		ARCH_AT91RM9200TB	AT91RM9200TB		380
+adsvgx			ARCH_ADSVGX		ADSVGX			381
+omap_h2			MACH_OMAP_H2		OMAP_H2			382
+pelee			ARCH_PELEE		PELEE			383
+e740			MACH_E740		E740			384
+iq80331			ARCH_IQ80331		IQ80331			385
+versatile_pb		ARCH_VERSATILE_PB	VERSATILE_PB		387
+kev7a400		MACH_KEV7A400		KEV7A400		388
+lpd7a400		MACH_LPD7A400		LPD7A400		389
+lpd7a404		MACH_LPD7A404		LPD7A404		390
+fujitsu_camelot		ARCH_FUJITSU_CAMELOT	FUJITSU_CAMELOT		391
+janus2m			ARCH_JANUS2M		JANUS2M			392
+embtf			MACH_EMBTF		EMBTF			393
+hpm			MACH_HPM		HPM			394
+smdk2410tk		MACH_SMDK2410TK		SMDK2410TK		395
+smdk2410aj		MACH_SMDK2410AJ		SMDK2410AJ		396
+streetracer		MACH_STREETRACER	STREETRACER		397
+eframe			MACH_EFRAME		EFRAME			398
+csb337			MACH_CSB337		CSB337			399
+pxa_lark		MACH_PXA_LARK		PXA_LARK		400
+pxa_pnp2110		MACH_PNP2110		PNP2110			401
+tcc72x			MACH_TCC72X		TCC72X			402
+altair			MACH_ALTAIR		ALTAIR			403
+kc3			MACH_KC3		KC3			404
+sinteftd		MACH_SINTEFTD		SINTEFTD		405
+mainstone		MACH_MAINSTONE		MAINSTONE		406
+aday4x			MACH_ADAY4X		ADAY4X			407
+lite300			MACH_LITE300		LITE300			408
+s5c7376			MACH_S5C7376		S5C7376			409
+mt02			MACH_MT02		MT02			410
+mport3s			MACH_MPORT3S		MPORT3S			411
+ra_alpha		MACH_RA_ALPHA		RA_ALPHA		412
+xcep			MACH_XCEP		XCEP			413
+arcom_mercury		MACH_ARCOM_MERCURY	ARCOM_MERCURY		414
+stargate		MACH_STARGATE		STARGATE		415
+armadilloj		MACH_ARMADILLOJ		ARMADILLOJ		416
+elroy_jack		MACH_ELROY_JACK		ELROY_JACK		417
+backend			MACH_BACKEND		BACKEND			418
+s5linbox		MACH_S5LINBOX		S5LINBOX		419
+nomadik			MACH_NOMADIK		NOMADIK			420
+ia_cpu_9200		MACH_IA_CPU_9200	IA_CPU_9200		421
+at91_bja1		MACH_AT91_BJA1		AT91_BJA1		422
+corgi			MACH_CORGI		CORGI			423
+poodle			MACH_POODLE		POODLE			424
+ten			MACH_TEN		TEN			425
+roverp5p		MACH_ROVERP5P		ROVERP5P		426
+sc2700			MACH_SC2700		SC2700			427
+ex_eagle		MACH_EX_EAGLE		EX_EAGLE		428
+nx_pxa12		MACH_NX_PXA12		NX_PXA12		429
+nx_pxa5			MACH_NX_PXA5		NX_PXA5			430
+blackboard2		MACH_BLACKBOARD2	BLACKBOARD2		431
+i819			MACH_I819		I819			432
+ixmb995e		MACH_IXMB995E		IXMB995E		433
+skyrider		MACH_SKYRIDER		SKYRIDER		434
+skyhawk			MACH_SKYHAWK		SKYHAWK			435
+enterprise		MACH_ENTERPRISE		ENTERPRISE		436
+dep2410			MACH_DEP2410		DEP2410			437
+armcore			MACH_ARMCORE		ARMCORE			438
+hobbit			MACH_HOBBIT		HOBBIT			439
+h7210			MACH_H7210		H7210			440
+pxa_netdcu5		MACH_PXA_NETDCU5	PXA_NETDCU5		441
+acc			MACH_ACC		ACC			442
+esl_sarva		MACH_ESL_SARVA		ESL_SARVA		443
+xm250			MACH_XM250		XM250			444
+t6tc1xb			MACH_T6TC1XB		T6TC1XB			445
+ess710			MACH_ESS710		ESS710			446
+mx3ads			MACH_MX3ADS		MX3ADS			447
+himalaya		MACH_HIMALAYA		HIMALAYA		448
+bolfenk			MACH_BOLFENK		BOLFENK			449
+at91rm9200kr		MACH_AT91RM9200KR	AT91RM9200KR		450
+edb9312			MACH_EDB9312		EDB9312			451
+omap_generic		MACH_OMAP_GENERIC	OMAP_GENERIC		452
+aximx3			MACH_AXIMX3		AXIMX3			453
+eb67xdip		MACH_EB67XDIP		EB67XDIP		454
+webtxs			MACH_WEBTXS		WEBTXS			455
+hawk			MACH_HAWK		HAWK			456
+ccat91sbc001		MACH_CCAT91SBC001	CCAT91SBC001		457
+expresso		MACH_EXPRESSO		EXPRESSO		458
+h4000			MACH_H4000		H4000			459
+dino			MACH_DINO		DINO			460
+ml675k			MACH_ML675K		ML675K			461
+edb9301			MACH_EDB9301		EDB9301			462
+edb9315			MACH_EDB9315		EDB9315			463
+reciva_tt		MACH_RECIVA_TT		RECIVA_TT		464
+cstcb01			MACH_CSTCB01		CSTCB01			465
+cstcb1			MACH_CSTCB1		CSTCB1			466
+shadwell		MACH_SHADWELL		SHADWELL		467
+goepel263		MACH_GOEPEL263		GOEPEL263		468
+acq100			MACH_ACQ100		ACQ100			469
+mx1fs2			MACH_MX1FS2		MX1FS2			470
+hiptop_g1		MACH_HIPTOP_G1		HIPTOP_G1		471
+sparky			MACH_SPARKY		SPARKY			472
+ns9750			MACH_NS9750		NS9750			473
+phoenix			MACH_PHOENIX		PHOENIX			474
+vr1000			MACH_VR1000		VR1000			475
+deisterpxa		MACH_DEISTERPXA		DEISTERPXA		476
+bcm1160			MACH_BCM1160		BCM1160			477
+pcm022			MACH_PCM022		PCM022			478
+adsgcx			MACH_ADSGCX		ADSGCX			479
+dreadnaught		MACH_DREADNAUGHT	DREADNAUGHT		480
+dm320			MACH_DM320		DM320			481
+markov			MACH_MARKOV		MARKOV			482
+cos7a400		MACH_COS7A400		COS7A400		483
+milano			MACH_MILANO		MILANO			484
+ue9328			MACH_UE9328		UE9328			485
+uex255			MACH_UEX255		UEX255			486
+ue2410			MACH_UE2410		UE2410			487
+a620			MACH_A620		A620			488
+ocelot			MACH_OCELOT		OCELOT			489
+cheetah			MACH_CHEETAH		CHEETAH			490
+omap_perseus2		MACH_OMAP_PERSEUS2	OMAP_PERSEUS2		491
+zvue			MACH_ZVUE		ZVUE			492
+roverp1			MACH_ROVERP1		ROVERP1			493
+asidial2		MACH_ASIDIAL2		ASIDIAL2		494
+s3c24a0			MACH_S3C24A0		S3C24A0			495
+e800			MACH_E800		E800			496
+e750			MACH_E750		E750			497
+s3c5500			MACH_S3C5500		S3C5500			498
+smdk5500		MACH_SMDK5500		SMDK5500		499
+signalsync		MACH_SIGNALSYNC		SIGNALSYNC		500
+nbc			MACH_NBC		NBC			501
+kodiak			MACH_KODIAK		KODIAK			502
+netbookpro		MACH_NETBOOKPRO		NETBOOKPRO		503
+hw90200			MACH_HW90200		HW90200			504
+condor			MACH_CONDOR		CONDOR			505
+cup			MACH_CUP		CUP			506
+kite			MACH_KITE		KITE			507
+scb9328			MACH_SCB9328		SCB9328			508
+omap_h3			MACH_OMAP_H3		OMAP_H3			509
+omap_h4			MACH_OMAP_H4		OMAP_H4			510
+n10			MACH_N10		N10			511
+montejade		MACH_MONTEJADE		MONTEJADE		512
+sg560			MACH_SG560		SG560			513
+dp1000			MACH_DP1000		DP1000			514
+omap_osk		MACH_OMAP_OSK		OMAP_OSK		515
+rg100v3			MACH_RG100V3		RG100V3			516
+mx2ads			MACH_MX2ADS		MX2ADS			517
+pxa_kilo		MACH_PXA_KILO		PXA_KILO		518
+ixp4xx_eagle		MACH_IXP4XX_EAGLE	IXP4XX_EAGLE		519
+tosa			MACH_TOSA		TOSA			520
+mb2520f			MACH_MB2520F		MB2520F			521
+emc1000			MACH_EMC1000		EMC1000			522
+tidsc25			MACH_TIDSC25		TIDSC25			523
+akcpmxl			MACH_AKCPMXL		AKCPMXL			524
+av3xx			MACH_AV3XX		AV3XX			525
+avila			MACH_AVILA		AVILA			526
+pxa_mpm10		MACH_PXA_MPM10		PXA_MPM10		527
+pxa_kyanite		MACH_PXA_KYANITE	PXA_KYANITE		528
+sgold			MACH_SGOLD		SGOLD			529
+oscar			MACH_OSCAR		OSCAR			530
+epxa4usb2		MACH_EPXA4USB2		EPXA4USB2		531
+xsengine		MACH_XSENGINE		XSENGINE		532
+ip600			MACH_IP600		IP600			533
+mcan2			MACH_MCAN2		MCAN2			534
+ddi_blueridge		MACH_DDI_BLUERIDGE	DDI_BLUERIDGE		535
+skyminder		MACH_SKYMINDER		SKYMINDER		536
+lpd79520		MACH_LPD79520		LPD79520		537
+edb9302			MACH_EDB9302		EDB9302			538
+hw90340			MACH_HW90340		HW90340			539
+cip_box			MACH_CIP_BOX		CIP_BOX			540
+ivpn			MACH_IVPN		IVPN			541
+rsoc2			MACH_RSOC2		RSOC2			542
+husky			MACH_HUSKY		HUSKY			543
+boxer			MACH_BOXER		BOXER			544
+shepherd		MACH_SHEPHERD		SHEPHERD		545
+aml42800aa		MACH_AML42800AA		AML42800AA		546
+ml674001		MACH_MACH_TYPE_ML674001	MACH_TYPE_ML674001	547
+lpc2294			MACH_LPC2294		LPC2294			548
+switchgrass		MACH_SWITCHGRASS	SWITCHGRASS		549
+ens_cmu			MACH_ENS_CMU		ENS_CMU			550
+mm6_sdb			MACH_MM6_SDB		MM6_SDB			551
+saturn			MACH_SATURN		SATURN			552
+argonplusevb		MACH_ARGONPLUSEVB	ARGONPLUSEVB		553
+scma11evb		MACH_SCMA11EVB		SCMA11EVB		554
+smdk2800		MACH_SMDK2800		SMDK2800		555
+mtwilson		MACH_MTWILSON		MTWILSON		556
+ziti			MACH_ZITI		ZITI			557
+grandfather		MACH_GRANDFATHER	GRANDFATHER		558
+tengine			MACH_TENGINE		TENGINE			559
+s3c2460			MACH_S3C2460		S3C2460			560
+pdm			MACH_PDM		PDM			561
+h4700			MACH_H4700		H4700			562
+h6300			MACH_H6300		H6300			563
+rz1700			MACH_RZ1700		RZ1700			564
+a716			MACH_A716		A716			565
+estk2440a		MACH_ESTK2440A		ESTK2440A		566
+atwixp425		MACH_ATWIXP425		ATWIXP425		567
+csb336			MACH_CSB336		CSB336			568
+rirm2			MACH_RIRM2		RIRM2			569
+cx23518			MACH_CX23518		CX23518			570
+cx2351x			MACH_CX2351X		CX2351X			571
+computime		MACH_COMPUTIME		COMPUTIME		572
+izarus			MACH_IZARUS		IZARUS			573
+pxa_rts			MACH_RTS		RTS			574
+se5100			MACH_SE5100		SE5100			575
+s3c2510			MACH_S3C2510		S3C2510			576
+csb437tl		MACH_CSB437TL		CSB437TL		577
+slauson			MACH_SLAUSON		SLAUSON			578
+pearlriver		MACH_PEARLRIVER		PEARLRIVER		579
+tdc_p210		MACH_TDC_P210		TDC_P210		580
+sg580			MACH_SG580		SG580			581
+wrsbcarm7		MACH_WRSBCARM7		WRSBCARM7		582
+ipd			MACH_IPD		IPD			583
+
+
+
+# The following are broken and should be removed and replaced with
+# allocated numbers ASAP
+p52                   ARCH_P52                P52                     87
+snds100                       BOARD_SNDS100           SNDS100 90
+dm270                 ARCH_DM270              DM270                   95
+evS3C4530HEI          BOARD_EVS3C4530HEI      EVS3C4530HEI            164
+S3C2500REFRGP         BOARD_S3C2500REFRGP     S3C2500REFRGP           167
+smdk2500              BOARD_SMDK2500          SMDK2500                166
diff -urN linux-2.4.29/arch/armnommu/tools/Makefile linux-2.4.29-uc1/arch/armnommu/tools/Makefile
--- linux-2.4.29/arch/armnommu/tools/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/tools/Makefile	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,36 @@
+#
+# linux/arch/armnommu/tools/Makefile
+#
+# Copyright (C) 2001 Russell King
+#
+
+all:	$(TOPDIR)/include/asm-armnommu/mach-types.h \
+	$(TOPDIR)/include/asm-armnommu/constants.h
+
+$(TOPDIR)/include/asm-armnommu/mach-types.h: mach-types gen-mach-types
+	awk -f gen-mach-types mach-types > $@
+
+# Generate the constants.h header file using the compiler.  We get
+# the compiler to spit out assembly code, and then mundge it into
+# what we want.
+
+$(TOPDIR)/include/asm-armnommu/constants.h: constants-hdr getconstants.c
+	$(CC) $(CFLAGS) -S -o - getconstants.c | \
+	 sed 's/^\(#define .* \)#\(.*\)/\1\2/;/^#define/!d' | \
+	 cat constants-hdr - > $@.tmp
+	cmp $@.tmp $@ >/dev/null 2>&1 || mv $@.tmp $@; $(RM) $@.tmp
+
+# Build our dependencies, and then generate the constants and
+# mach-types header files.  If we do it now, mkdep will pick
+# the dependencies up later on when it runs through the other
+# directories
+
+dep:
+	$(TOPDIR)/scripts/mkdep getconstants.c | sed s,getconstants.o,$(TOPDIR)/include/asm-armnommu/constants.h, > .depend
+	$(MAKE) all
+
+.PHONY:	all dep
+
+ifneq ($(wildcard .depend),)
+include .depend
+endif
diff -urN linux-2.4.29/arch/armnommu/vmlinux-armo.lds.in linux-2.4.29-uc1/arch/armnommu/vmlinux-armo.lds.in
--- linux-2.4.29/arch/armnommu/vmlinux-armo.lds.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/vmlinux-armo.lds.in	2005-06-14 02:11:21.000000000 +0100
@@ -0,0 +1,111 @@
+/* ld script to make ARM Linux kernel
+ * taken from the i386 version by Russell King
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ */
+OUTPUT_ARCH(arm)
+ENTRY(stext)
+SECTIONS
+{
+	. = TEXTADDR;
+
+	.init : {
+		_stext = .;
+		__init_begin = .;	/* Init code and data		*/
+			*(.text.init)
+		__proc_info_begin = .;
+			*(.proc.info)
+		__proc_info_end = .;
+		__arch_info_begin = .;
+			*(.arch.info)
+		__arch_info_end = .;
+		__tagtable_begin = .;
+			*(.taglist)
+		__tagtable_end = .;
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		__initcall_end = .;
+		. = ALIGN(32768);
+		__init_end = .;
+	}
+
+	.init.task : {
+		*(.init.task)
+	}
+
+	/DISCARD/ : {			/* Exit code and data		*/
+		*(.text.exit)
+		*(.data.exit)
+		*(.exitcall.exit)
+	}
+
+	.text : {
+		_text = .;		/* Text and read-only data	*/
+			*(.text)
+			*(.fixup)
+			*(.gnu.warning)
+			*(.text.lock)	/* out-of-line lock text */
+			*(.rodata)
+			*(.glue_7)
+			*(.glue_7t)
+			*(.kstrtab)
+		. = ALIGN(16);		/* Exception table		*/
+		__start___ex_table = .;
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;	/* Kernel symbol table		*/
+			*(__ksymtab)
+		__stop___ksymtab = .;
+
+		__start___kallsyms = .; /* All kernel symbols           */
+			*(__kallsyms)
+		__stop___kallsyms = .;
+
+		*(.got)			/* Global offset table		*/
+
+		_etext = .;		/* End of text section		*/
+	}
+
+	.data : {
+		/*
+		 * The cacheline aligned data
+		 */
+		. = ALIGN(32);
+		*(.data.cacheline_aligned)
+
+		/*
+		 * and the usual data section
+		 */
+		*(.data)
+		CONSTRUCTORS
+
+		_edata = .;
+	}
+
+
+	.bss : {
+		__bss_start = .;	/* BSS				*/
+		*(.bss)
+		*(COMMON)
+		_end = . ;
+	}
+
+					/* Stabs debugging sections.	*/
+	.stab 0 : { *(.stab) }
+	.stabstr 0 : { *(.stabstr) }
+	.stab.excl 0 : { *(.stab.excl) }
+	.stab.exclstr 0 : { *(.stab.exclstr) }
+	.stab.index 0 : { *(.stab.index) }
+	.stab.indexstr 0 : { *(.stab.indexstr) }
+	.comment 0 : { *(.comment) }
+	.debug_abbrev 0 : { *(.debug_abbrev) }
+	.debug_info 0 : { *(.debug_info) }
+	.debug_line 0 : { *(.debug_line) }
+	.debug_pubnames 0 : { *(.debug_pubnames) }
+	.debug_aranges 0 : { *(.debug_aranges) }
+}
diff -urN linux-2.4.29/arch/armnommu/vmlinux-armv.lds.in linux-2.4.29-uc1/arch/armnommu/vmlinux-armv.lds.in
--- linux-2.4.29/arch/armnommu/vmlinux-armv.lds.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/armnommu/vmlinux-armv.lds.in	2005-06-14 02:11:20.000000000 +0100
@@ -0,0 +1,121 @@
+/* ld script to make ARM Linux kernel
+ * taken from the i386 version by Russell King
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ */
+OUTPUT_ARCH(arm)
+ENTRY(stext)
+SECTIONS
+{
+	. = TEXTADDR;
+	.init : {			/* Init code and data		*/
+		_stext = .;
+		__init_begin = .;
+			*(.text.init)
+		__proc_info_begin = .;
+			*(.proc.info)
+		__proc_info_end = .;
+		__arch_info_begin = .;
+			*(.arch.info)
+		__arch_info_end = .;
+		__tagtable_begin = .;
+			*(.taglist)
+		__tagtable_end = .;
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		__initcall_end = .;
+		. = ALIGN(4096);
+		__init_end = .;
+	}
+
+	/DISCARD/ : {			/* Exit code and data		*/
+		*(.text.exit)
+		*(.data.exit)
+		*(.exitcall.exit)
+	}
+
+	.text : {			/* Real text segment		*/
+		_text = .;		/* Text and read-only data	*/
+			*(.text)
+			*(.fixup)
+			*(.gnu.warning)
+			*(.text.lock)	/* out-of-line lock text */
+			*(.rodata)
+			*(.rodata.str1.4)
+			*(.glue_7)
+			*(.glue_7t)
+			*(.kstrtab)
+		. = ALIGN(16);
+		__start___ex_table = .;	/* Exception table		*/
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;	/* Kernel symbol table		*/
+			*(__ksymtab)
+		__stop___ksymtab = .;
+
+		__start___kallsyms = .; /* All kernel symbols           */
+			*(__kallsyms)
+		__stop___kallsyms = .;
+
+		*(.got)			/* Global offset table		*/
+
+		_etext = .;		/* End of text section		*/
+	}
+
+	. = ALIGN(8192);
+
+	.data : {
+        	__data_start = .;
+		/*
+		 * first, the init task union, aligned
+		 * to an 8192 byte boundary.
+		 */
+		*(.init.task)
+
+		/*
+		 * then the cacheline aligned data
+		 */
+		. = ALIGN(32);
+		*(.data.cacheline_aligned)
+
+		/*
+		 * and the usual data section
+		 */
+		*(.data)
+		CONSTRUCTORS
+
+		_edata = .;
+	}
+
+	.bss : {
+		__bss_start = .;	/* BSS				*/
+		*(.bss)
+		*(COMMON)
+    . = ALIGN(0x10); 
+		_end = . ;
+    _ebss = . ;
+	}
+
+
+	. = ALIGN(8192);
+	_end_kernel = . ;
+
+					/* Stabs debugging sections.	*/
+	.stab 0 : { *(.stab) }
+	.stabstr 0 : { *(.stabstr) }
+	.stab.excl 0 : { *(.stab.excl) }
+	.stab.exclstr 0 : { *(.stab.exclstr) }
+	.stab.index 0 : { *(.stab.index) }
+	.stab.indexstr 0 : { *(.stab.indexstr) }
+	.comment 0 : { *(.comment) }
+	.debug_abbrev 0 : { *(.debug_abbrev) }
+	.debug_info 0 : { *(.debug_info) }
+	.debug_line 0 : { *(.debug_line) }
+	.debug_pubnames 0 : { *(.debug_pubnames) }
+	.debug_aranges 0 : { *(.debug_aranges) }
+}
diff -urN linux-2.4.29/arch/blackfin/Boards.mk linux-2.4.29-uc1/arch/blackfin/Boards.mk
--- linux-2.4.29/arch/blackfin/Boards.mk	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/Boards.mk	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,26 @@
+#   Changes made by Akbar Hussain & Tony Kou April 04, 2001
+
+
+# Put definitions for platforms and boards in here.
+
+ifdef CONFIG_BLACKFIN
+  ifdef CONFIG_EAGLE
+    PLATFORM := 535
+    BOARD := ADI
+  endif
+  ifdef CONFIG_HAWK
+    PLATFORM := 535
+    BOARD := ADI
+  endif
+  ifdef CONFIG_PUB
+    PLATFORM := 535
+    BOARD := ADI
+  endif
+  ifdef CONFIG_BLACKFIN_EZKIT
+    PLATFORM := 533
+    BOARD := ADI
+  endif
+endif
+
+export BOARD
+export PLATFORM
diff -urN linux-2.4.29/arch/blackfin/boot/empty.S linux-2.4.29-uc1/arch/blackfin/boot/empty.S
--- linux-2.4.29/arch/blackfin/boot/empty.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/boot/empty.S	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1 @@
+.end
diff -urN linux-2.4.29/arch/blackfin/boot/Makefile linux-2.4.29-uc1/arch/blackfin/boot/Makefile
--- linux-2.4.29/arch/blackfin/boot/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/boot/Makefile	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,12 @@
+rootfs.o: rootfs.img
+	$(CROSS_COMPILE)gcc -c empty.S -o empty.o
+	$(OBJCOPY) --add-section=.ramdisk=$< empty.o $@
+
+linux.dxe: $(TOPDIR)/linux rootfs.o
+	$(LD) $(LINKFLAGS) $(TOPDIR)/linux rootfs.o -o $@
+
+clean:
+	rm -f *.[oa]
+
+dep depend:
+	:
diff -urN linux-2.4.29/arch/blackfin/config.in linux-2.4.29-uc1/arch/blackfin/config.in
--- linux-2.4.29/arch/blackfin/config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/config.in	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,302 @@
+#############################################################################
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+#
+# based mainly on the arch/i386/config.in and bit of the 2.0, m68knommu
+# config.in
+#
+#############################################################################
+
+mainmenu_name 'uClinux/frio (w/o MMU) Kernel Configuration'
+
+define_bool CONFIG_UCLINUX y
+define_bool CONFIG_UID16 y
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n 
+define_bool CONFIG_BLACKFIN y
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Processor type and features'
+
+unset CONFIG_SERIAL_SPACE2
+
+comment 'Platform'
+
+choice 	'Board' \
+	"EZ-Kit(533)	CONFIG_BLACKFIN_EZKIT \
+	 Hawk-35(MDS)	CONFIG_HAWK \
+	 Eagle-35(MDS)	CONFIG_EAGLE \
+	 PUB(ADI)	CONFIG_PUB"	Hawk
+
+comment 'Execution Location'
+
+choice 'Kernel executes from' \
+	"RAM	CONFIG_RAMKERNEL \
+	 ROM	CONFIG_ROMKERNEL" ROM
+
+comment 'Cache Support'
+
+bool 'Enable CACHE' CONFIG_BLACKFIN_CACHE
+bool 'Enable DCACHE' CONFIG_BLACKFIN_DCACHE
+
+comment 'Kernel space test program'
+
+bool 'Enable Audio Demonstration' AC97_DEMO
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'General setup'
+
+bool 'Networking support' CONFIG_NET
+bool 'SGI Visual Workstation support' CONFIG_VISWS
+if [ "$CONFIG_VISWS" = "y" ]; then
+   define_bool CONFIG_X86_VISWS_APIC y
+   define_bool CONFIG_X86_LOCAL_APIC y
+   define_bool CONFIG_PCI y
+else
+   if [ "$CONFIG_SMP" = "y" ]; then
+      define_bool CONFIG_X86_IO_APIC y
+      define_bool CONFIG_X86_LOCAL_APIC y
+   fi
+   bool 'PCI support' CONFIG_PCI
+   if [ "$CONFIG_PCI" = "y" ]; then
+      choice '  PCI access mode' \
+	"BIOS		CONFIG_PCI_GOBIOS	\
+	 Direct		CONFIG_PCI_GODIRECT	\
+	 Any		CONFIG_PCI_GOANY"	Any
+      if [ "$CONFIG_PCI_GOBIOS" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then
+         define_bool CONFIG_PCI_BIOS y
+      fi
+      if [ "$CONFIG_PCI_GODIRECT" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then
+         define_bool CONFIG_PCI_DIRECT y
+      fi
+   fi
+fi
+
+source drivers/pci/Config.in
+
+if [ "$CONFIG_VISWS" != "y" ]; then
+   bool 'MCA support' CONFIG_MCA
+fi
+
+bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+
+if [ "$CONFIG_HOTPLUG" = "y" ] ; then
+   source drivers/pcmcia/Config.in
+else
+   define_bool CONFIG_PCMCIA n
+fi
+
+bool 'System V IPC' CONFIG_SYSVIPC
+bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   choice 'Kernel core (/proc/kcore) format' \
+	"ELF		CONFIG_KCORE_ELF	\
+	 A.OUT		CONFIG_KCORE_AOUT" ELF
+fi
+tristate 'Kernel support for flat binaries' CONFIG_BINFMT_FLAT
+if [ "$CONFIG_BINFMT_FLAT" != "n" ]; then
+   bool '    Enable ZFLAT support' CONFIG_BINFMT_ZFLAT
+fi
+tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
+tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+
+bool 'Power Management support' CONFIG_PM
+
+dep_bool '  ACPI support' CONFIG_ACPI $CONFIG_PM
+if [ "$CONFIG_ACPI" != "n" ]; then
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      bool '    ACPI interpreter (EXPERIMENTAL)' CONFIG_ACPI_INTERPRETER
+      bool '    Enter S1 for sleep (EXPERIMENTAL)' CONFIG_ACPI_S1_SLEEP
+   fi
+fi
+
+dep_tristate '  Advanced Power Management BIOS support' CONFIG_APM $CONFIG_PM
+if [ "$CONFIG_APM" != "n" ]; then
+   bool '    Ignore USER SUSPEND' CONFIG_APM_IGNORE_USER_SUSPEND
+   bool '    Enable PM at boot time' CONFIG_APM_DO_ENABLE
+   bool '    Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE
+   bool '    Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK
+   bool '    RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT
+   bool '    Allow interrupts during APM BIOS calls' CONFIG_APM_ALLOW_INTS
+   bool '    Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF
+fi
+
+endmenu
+
+#############################################################################
+
+source drivers/mtd/Config.in
+
+source drivers/parport/Config.in
+
+source drivers/pnp/Config.in
+
+source drivers/block/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   source net/Config.in
+fi
+
+source drivers/telephony/Config.in
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'ATA/IDE/MFM/RLL support'
+
+tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+
+if [ "$CONFIG_IDE" != "n" ]; then
+  source drivers/ide/Config.in
+else
+  define_bool CONFIG_BLK_DEV_HD n
+fi
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'SCSI support'
+
+tristate 'SCSI support' CONFIG_SCSI
+
+if [ "$CONFIG_SCSI" != "n" ]; then
+   source drivers/scsi/Config.in
+fi
+endmenu
+
+#############################################################################
+
+source drivers/ieee1394/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Network device support'
+
+   bool 'Network device support' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+      if [ "$CONFIG_ATM" = "y" ]; then
+         source drivers/atm/Config.in
+      fi
+   fi
+   endmenu
+fi
+
+source net/ax25/Config.in
+
+source net/irda/Config.in
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'ISDN subsystem'
+if [ "$CONFIG_NET" != "n" ]; then
+   tristate 'ISDN support' CONFIG_ISDN
+   if [ "$CONFIG_ISDN" != "n" ]; then
+      source drivers/isdn/Config.in
+   fi
+fi
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+
+bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+   source drivers/cdrom/Config.in
+fi
+endmenu
+
+#############################################################################
+
+source drivers/char/Config.in
+
+
+#source drivers/misc/Config.in
+
+source fs/Config.in
+
+if [ "$CONFIG_VT" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Console drivers'
+   bool 'VGA text console' CONFIG_VGA_CONSOLE
+   bool 'Video mode selection support' CONFIG_VIDEO_SELECT
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
+      source drivers/video/Config.in
+   fi
+   endmenu
+fi
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Sound'
+
+tristate 'Sound card support' CONFIG_SOUND
+if [ "$CONFIG_SOUND" != "n" ]; then
+   source drivers/sound/Config.in
+fi
+endmenu
+
+#############################################################################
+
+source drivers/usb/Config.in
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+bool 'Full Symbolic/Source Debugging support' CONFIG_FULLDEBUG
+#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
+bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+bool 'Include kgdb kernel debugger' CONFIG_KGDB
+
+bool 'Kernel profiling support' CONFIG_PROFILE
+if [ "$CONFIG_PROFILE" = "y" ]; then
+  int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+  bool 'Use fast second timer for profiling' CONFIG_HIGHPROFILE
+fi
+
+if [ "$CONFIG_COLDFIRE" = "y" ]; then
+	bool 'Magic SysRq Key' CONFIG_MAGIC_SYSRQ
+	bool 'Panic/Dump to FLASH' CONFIG_DUMPTOFLASH
+fi
+endmenu
+
+#############################################################################
+
+source lib/Config.in
+source crypto/Config.in
+
+#############################################################################
diff -urN linux-2.4.29/arch/blackfin/console/68328fb.c linux-2.4.29-uc1/arch/blackfin/console/68328fb.c
--- linux-2.4.29/arch/blackfin/console/68328fb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/console/68328fb.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,1127 @@
+/*
+ * linux/arch/m68knommu/console/68328fb.c -- Low level implementation of the
+ *                                           mc68328 LCD frame buffer device
+ *
+ *    Copyright (C) 1998,1999 Kenneth Albanowski <kjahds@kjahds.com>,
+ *                            The Silver Hammer Group, Ltd.
+ *
+ *
+ * This file is based on the Amiga CyberVision frame buffer device (Cyberfb.c):
+ *
+ *    Copyright (C) 1996 Martin Apel
+ *                       Geert Uytterhoeven
+ *
+ *
+ * This file is based on the Amiga frame buffer device (amifb.c):
+ *
+ *    Copyright (C) 1995 Geert Uytterhoeven
+ *
+ *
+ * History:
+ *   - 17 Feb 98: Original version by Kenneth Albanowski <kjahds@kjahds.com>
+ *
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/config.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <linux/fb.h>
+
+
+#define arraysize(x)    (sizeof(x)/sizeof(*(x)))
+
+struct mc68328_fb_par {
+   int xres;
+   int yres;
+   int bpp;
+};
+
+static struct mc68328_fb_par current_par;
+
+static int current_par_valid = 0;
+static int currcon = 0;
+
+static struct display disp[MAX_NR_CONSOLES];
+static struct fb_info fb_info;
+
+static int node;        /* node of the /dev/fb?current file */
+
+
+   /*
+    *    Switch for Chipset Independency
+    */
+
+static struct fb_hwswitch {
+
+   /* Initialisation */
+
+   int (*init)(void);
+
+   /* Display Control */
+
+   int (*encode_fix)(struct fb_fix_screeninfo *fix, struct mc68328_fb_par *par);
+   int (*decode_var)(struct fb_var_screeninfo *var, struct mc68328_fb_par *par);
+   int (*encode_var)(struct fb_var_screeninfo *var, struct mc68328_fb_par *par);
+   int (*getcolreg)(u_int regno, u_int *red, u_int *green, u_int *blue,
+                    u_int *transp);
+   int (*setcolreg)(u_int regno, u_int red, u_int green, u_int blue,
+                    u_int transp);
+   void (*blank)(int blank);
+} *fbhw;
+
+
+   /*
+    *    Frame Buffer Name
+    */
+
+static char mc68328_fb_name[16] = "mc68328";
+
+
+   /*
+    *    mc68328vision Graphics Board
+    */
+
+#define CYBER8_WIDTH 1152
+#define CYBER8_HEIGHT 886
+#define CYBER8_PIXCLOCK 12500    /* ++Geert: Just a guess */
+
+#define CYBER16_WIDTH 800
+#define CYBER16_HEIGHT 600
+#define CYBER16_PIXCLOCK 25000   /* ++Geert: Just a guess */
+
+#define PALM_WIDTH 160
+#define PALM_HEIGHT 160
+
+
+/*static int mc68328Key = 0;
+static u_char mc68328_colour_table [256][4];*/
+static unsigned long mc68328Mem;
+static unsigned long mc68328Size;
+
+static long *memstart;
+
+
+   /*
+    *    Predefined Video Mode Names
+    */
+
+static char *mc68328_fb_modenames[] = {
+
+   /*
+    *    Autodetect (Default) Video Mode
+    */
+
+   "default",
+
+   /*
+    *    Predefined Video Modes
+    */
+    
+   "Palm",            /* Palm Pilot devices, 1.0 and higher */
+   "Palm Grey",            /* Palm Pilot devices, 1.0 and higher */
+
+   /*
+    *    Dummy Video Modes
+    */
+
+   "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
+   "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
+   "dummy", "dummy", "dummy", "dummy",
+
+   /*
+    *    User Defined Video Modes
+    *
+    *    This doesn't work yet!!
+    */
+
+   "user0", "user1", "user2", "user3", "user4", "user5", "user6", "user7"
+};
+
+
+   /*
+    *    Predefined Video Mode Definitions
+    */
+
+static struct fb_var_screeninfo mc68328_fb_predefined[] = {
+
+   /*
+    *    Autodetect (Default) Video Mode
+    */
+
+   { 0, },
+
+   /*
+    *    Predefined Video Modes
+    */
+    
+   {
+      /* Palm */
+      PALM_WIDTH, PALM_HEIGHT, PALM_WIDTH, PALM_HEIGHT, 
+      0, 0, 
+      1, -1,
+      {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 0, 0},
+      0, 0, 
+      -1, -1, /* phys height, width */
+      FB_ACCEL_NONE, 
+      0, 0, 0, 0, 0, 0, 0, /* timing */
+      0, /* sync */
+      FB_VMODE_NONINTERLACED
+   },
+   {
+      /* Palm Grey */
+      PALM_WIDTH, PALM_HEIGHT, PALM_WIDTH, PALM_HEIGHT, 
+      0, 0, 
+      2, -1,
+      {0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0},
+      0, 0, 
+      -1, -1, /* phys height, width */
+      FB_ACCEL_NONE, 
+      0, 0, 0, 0, 0, 0, 0, /* timing */
+      0, /* sync */
+      FB_VMODE_NONINTERLACED
+   },
+
+   /*
+    *    Dummy Video Modes
+    */
+
+   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, },
+   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, },
+   { 0, }, { 0, },
+
+   /*
+    *    User Defined Video Modes
+    */
+
+   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }
+};
+
+
+#define NUM_TOTAL_MODES    arraysize(mc68328_fb_predefined)
+#define NUM_PREDEF_MODES   (3)
+
+
+static int mc68328fb_inverse = 0;
+static int mc68328fb_mode = 0;
+static int mc68328fbCursorMode = 0;
+
+
+   /*
+    *    Some default modes
+    */
+
+#define PALM_DEFMODE     (1)
+#define CYBER16_DEFMODE    (2)
+
+
+   /*
+    *    Interface used by the world
+    */
+
+void mc68328_video_setup(char *options, int *ints);
+
+static int mc68328_fb_get_fix(struct fb_fix_screeninfo *fix, int con);
+static int mc68328_fb_get_var(struct fb_var_screeninfo *var, int con);
+static int mc68328_fb_set_var(struct fb_var_screeninfo *var, int con);
+static int mc68328_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con);
+static int mc68328_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con);
+static int mc68328_fb_pan_display(struct fb_var_screeninfo *var, int con);
+static int mc68328_fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+                          u_long arg, int con);
+
+
+   /*
+    *    Interface to the low level console driver
+    */
+
+struct fb_info *mc68328_fb_init(long *mem_start); /* Through amiga_fb_init() */
+static int mc68328fb_switch(int con);
+static int mc68328fb_updatevar(int con);
+static void mc68328fb_blank(int blank);
+
+
+   /*
+    *    Accelerated Functions used by the low level console driver
+    */
+
+void mc68328_WaitQueue(u_short fifo);
+void mc68328_WaitBlit(void);
+void mc68328_BitBLT(u_short curx, u_short cury, u_short destx, u_short desty,
+                  u_short width, u_short height, u_short mode);
+void mc68328_RectFill(u_short x, u_short y, u_short width, u_short height,
+                    u_short mode, u_short color);
+void mc68328_MoveCursor(u_short x, u_short y);
+
+
+   /*
+    *   Hardware Specific Routines
+    */
+
+static int mc68328_init(void);
+static int mc68328_encode_fix(struct fb_fix_screeninfo *fix,
+                          struct mc68328_fb_par *par);
+static int mc68328_decode_var(struct fb_var_screeninfo *var,
+                          struct mc68328_fb_par *par);
+static int mc68328_encode_var(struct fb_var_screeninfo *var,
+                          struct mc68328_fb_par *par);
+static int mc68328_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                         u_int *transp);
+static int mc68328_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp);
+static void mc68328_blank(int blank);
+
+
+   /*
+    *    Internal routines
+    */
+
+static void mc68328_fb_get_par(struct mc68328_fb_par *par);
+static void mc68328_fb_set_par(struct mc68328_fb_par *par);
+static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
+static struct fb_cmap *get_default_colormap(int bpp);
+static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
+                          int kspc);
+static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
+                          int kspc);
+static void do_install_cmap(int con);
+static void memcpy_fs(int fsfromto, void *to, void *from, int len);
+static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto);
+static int alloc_cmap(struct fb_cmap *cmap, int len, int transp);
+static void mc68328_fb_set_disp(int con);
+static int get_video_mode(const char *name);
+
+
+/* -------------------- Hardware specific routines -------------------------- */
+
+
+   /*
+    *    Initialization
+    *
+    *    Set the default video mode for this chipset. If a video mode was
+    *    specified on the command line, it will override the default mode.
+    */
+
+static int mc68328_init(void)
+{
+	/*int i;
+	char size;
+	volatile u_long *CursorBase;
+	unsigned long board_addr;
+	struct ConfigDev *cd;*/
+
+	if (mc68328fb_mode == -1)
+		mc68328fb_mode = PALM_DEFMODE;
+
+	mc68328Mem = (*(volatile unsigned long*)0xFFFFFA00);
+	/*kernel_map (board_addr + 0x01400000, 0x00400000,*/
+	mc68328Size = 160*160/8;
+
+	return (0);
+}
+
+
+   /*
+    *    This function should fill in the `fix' structure based on the
+    *    values in the `par' structure.
+    */
+
+static int mc68328_encode_fix(struct fb_fix_screeninfo *fix,
+                          struct mc68328_fb_par *par)
+{
+   int i;
+
+   strcpy(fix->id, mc68328_fb_name);
+   fix->smem_start = mc68328Mem;
+   fix->smem_len = mc68328Size;
+
+   fix->type = FB_TYPE_PACKED_PIXELS;
+   fix->type_aux = 0;
+   if (par->bpp == 1)
+      fix->visual = FB_VISUAL_MONO01;
+   else
+      fix->visual = FB_VISUAL_DIRECTCOLOR;
+
+   fix->xpanstep = 0;
+   fix->ypanstep = 0;
+   fix->ywrapstep = 0;
+
+   for (i = 0; i < arraysize(fix->reserved); i++)
+      fix->reserved[i] = 0;
+
+   return(0);
+}
+
+
+   /*
+    *    Get the video params out of `var'. If a value doesn't fit, round
+    *    it up, if it's too big, return -EINVAL.
+    */
+
+static int mc68328_decode_var(struct fb_var_screeninfo *var,
+                          struct mc68328_fb_par *par)
+{
+   par->xres = PALM_WIDTH;
+   par->yres = PALM_HEIGHT;
+   par->bpp = 1;
+   return(0);
+}
+
+
+   /*
+    *    Fill the `var' structure based on the values in `par' and maybe
+    *    other values read out of the hardware.
+    */
+
+static int mc68328_encode_var(struct fb_var_screeninfo *var,
+                          struct mc68328_fb_par *par)
+{
+   int i;
+
+   var->xres = par->xres;
+   var->yres = par->yres;
+   var->xres_virtual = par->xres;
+   var->yres_virtual = par->yres;
+   var->xoffset = 0;
+   var->yoffset = 0;
+
+   var->bits_per_pixel = par->bpp;
+   var->grayscale = -1;
+
+   var->red.offset = 0;
+   var->red.length = par->bpp;
+   var->red.msb_right = 0;
+   var->blue = var->green = var->red;
+
+   var->transp.offset = 0;
+   var->transp.length = 0;
+   var->transp.msb_right = 0;
+
+   var->nonstd = 0;
+   var->activate = 0;
+
+   var->height = -1;
+   var->width = -1;
+   var->accel = FB_ACCEL_NONE;
+   var->vmode = FB_VMODE_NONINTERLACED;
+
+   /* Dummy values */
+
+   var->pixclock = 0;
+   var->sync = 0;
+   var->left_margin = 0;
+   var->right_margin = 0;
+   var->upper_margin = 0;
+   var->lower_margin = 0;
+   var->hsync_len = 0;
+   var->vsync_len = 0;
+
+   for (i = 0; i < arraysize(var->reserved); i++)
+      var->reserved[i] = 0;
+
+   return(0);
+}
+
+
+   /*
+    *    Set a single color register. The values supplied are already
+    *    rounded down to the hardware's capabilities (according to the
+    *    entries in the var structure). Return != 0 for invalid regno.
+    */
+
+static int mc68328_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp)
+{
+	return 1;
+#if 0
+if (regno > 255)
+  return (1);
+
+*(mc68328Regs + 0x3c8) = (char)regno;
+mc68328_colour_table [regno][0] = red & 0xff;
+mc68328_colour_table [regno][1] = green & 0xff;
+mc68328_colour_table [regno][2] = blue & 0xff;
+mc68328_colour_table [regno][3] = transp;
+
+*(mc68328Regs + 0x3c9) = (red & 0xff) >> 2;
+*(mc68328Regs + 0x3c9) = (green & 0xff) >> 2;
+*(mc68328Regs + 0x3c9) = (blue & 0xff) >> 2;
+
+return (0);
+#endif
+}
+
+
+   /*
+    *    Read a single color register and split it into
+    *    colors/transparent. Return != 0 for invalid regno.
+    */
+
+static int mc68328_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                         u_int *transp)
+{
+	return 1;
+#if 0
+if (regno >= 256)
+  return (1);
+*red    = mc68328_colour_table [regno][0];
+*green  = mc68328_colour_table [regno][1];
+*blue   = mc68328_colour_table [regno][2];
+*transp = mc68328_colour_table [regno][3];
+return (0);
+#endif
+}
+
+
+   /*
+    *    (Un)Blank the screen
+    */
+
+void mc68328_blank(int blank)
+{
+#if 0
+	if (blank)
+		(*(volatile unsigned char*)0xFFFFFA27) &= ~128;
+	else
+		(*(volatile unsigned char*)0xFFFFFA27) |= 128;
+#endif
+}
+
+
+/**************************************************************
+ * We are waiting for "fifo" FIFO-slots empty
+ */
+void mc68328_WaitQueue (u_short fifo)
+{
+}
+
+/**************************************************************
+ * We are waiting for Hardware (Graphics Engine) not busy
+ */
+void mc68328_WaitBlit (void)
+{
+}
+
+/**************************************************************
+ * BitBLT - Through the Plane
+ */
+void mc68328_BitBLT (u_short curx, u_short cury, u_short destx, u_short desty,
+                   u_short width, u_short height, u_short mode)
+{
+#if 0
+u_short blitcmd = S3_BITBLT;
+
+/* Set drawing direction */
+/* -Y, X maj, -X (default) */
+if (curx > destx)
+  blitcmd |= 0x0020;  /* Drawing direction +X */
+else
+  {
+  curx  += (width - 1);
+  destx += (width - 1);
+  }
+
+if (cury > desty)
+  blitcmd |= 0x0080;  /* Drawing direction +Y */
+else
+  {
+  cury  += (height - 1);
+  desty += (height - 1);
+  }
+
+mc68328_WaitQueue (0x8000);
+
+*((u_short volatile *)(mc68328Regs + S3_PIXEL_CNTL)) = 0xa000;
+*((u_short volatile *)(mc68328Regs + S3_FRGD_MIX)) = (0x0060 | mode);
+
+*((u_short volatile *)(mc68328Regs + S3_CUR_X)) = curx;
+*((u_short volatile *)(mc68328Regs + S3_CUR_Y)) = cury;
+
+*((u_short volatile *)(mc68328Regs + S3_DESTX_DIASTP)) = destx;
+*((u_short volatile *)(mc68328Regs + S3_DESTY_AXSTP)) = desty;
+
+*((u_short volatile *)(mc68328Regs + S3_MIN_AXIS_PCNT)) = height - 1;
+*((u_short volatile *)(mc68328Regs + S3_MAJ_AXIS_PCNT)) = width  - 1;
+
+*((u_short volatile *)(mc68328Regs + S3_CMD)) = blitcmd;
+#endif
+}
+
+/**************************************************************
+ * Rectangle Fill Solid
+ */
+void mc68328_RectFill (u_short x, u_short y, u_short width, u_short height,
+                     u_short mode, u_short color)
+{
+#if 0
+u_short blitcmd = S3_FILLEDRECT;
+
+mc68328_WaitQueue (0x8000);
+
+*((u_short volatile *)(mc68328Regs + S3_PIXEL_CNTL)) = 0xa000;
+*((u_short volatile *)(mc68328Regs + S3_FRGD_MIX)) = (0x0020 | mode);
+
+*((u_short volatile *)(mc68328Regs + S3_MULT_MISC)) = 0xe000;
+*((u_short volatile *)(mc68328Regs + S3_FRGD_COLOR)) = color;
+
+*((u_short volatile *)(mc68328Regs + S3_CUR_X)) = x;
+*((u_short volatile *)(mc68328Regs + S3_CUR_Y)) = y;
+
+*((u_short volatile *)(mc68328Regs + S3_MIN_AXIS_PCNT)) = height - 1;
+*((u_short volatile *)(mc68328Regs + S3_MAJ_AXIS_PCNT)) = width  - 1;
+
+*((u_short volatile *)(mc68328Regs + S3_CMD)) = blitcmd;
+#endif
+}
+
+
+/**************************************************************
+ * Move cursor to x, y
+ */
+void mc68328_MoveCursor (u_short x, u_short y)
+{
+	(*(volatile unsigned short*)0xFFFFFA18) = (mc68328fbCursorMode << 14) | x;
+	(*(volatile unsigned short*)0xFFFFFA1A) = y;
+#if 0
+*(mc68328Regs + S3_CRTC_ADR)  = 0x39;
+*(mc68328Regs + S3_CRTC_DATA) = 0xa0;
+
+*(mc68328Regs + S3_CRTC_ADR)  = S3_HWGC_ORGX_H;
+*(mc68328Regs + S3_CRTC_DATA) = (char)((x & 0x0700) >> 8);
+*(mc68328Regs + S3_CRTC_ADR)  = S3_HWGC_ORGX_L;
+*(mc68328Regs + S3_CRTC_DATA) = (char)(x & 0x00ff);
+
+*(mc68328Regs + S3_CRTC_ADR)  = S3_HWGC_ORGY_H;
+*(mc68328Regs + S3_CRTC_DATA) = (char)((y & 0x0700) >> 8);
+*(mc68328Regs + S3_CRTC_ADR)  = S3_HWGC_ORGY_L;
+*(mc68328Regs + S3_CRTC_DATA) = (char)(y & 0x00ff);
+#endif
+}
+
+
+/* -------------------- Interfaces to hardware functions -------------------- */
+
+
+static struct fb_hwswitch mc68328_switch = {
+   mc68328_init, mc68328_encode_fix, mc68328_decode_var, mc68328_encode_var,
+   mc68328_getcolreg, mc68328_setcolreg, mc68328_blank
+};
+
+
+/* -------------------- Generic routines ------------------------------------ */
+
+
+   /*
+    *    Fill the hardware's `par' structure.
+    */
+
+static void mc68328_fb_get_par(struct mc68328_fb_par *par)
+{
+   if (current_par_valid)
+      *par = current_par;
+   else
+      fbhw->decode_var(&mc68328_fb_predefined[mc68328fb_mode], par);
+}
+
+
+static void mc68328_fb_set_par(struct mc68328_fb_par *par)
+{
+   current_par = *par;
+   current_par_valid = 1;
+}
+
+
+static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
+{
+   int err, activate;
+   struct mc68328_fb_par par;
+
+   if ((err = fbhw->decode_var(var, &par)))
+      return(err);
+   activate = var->activate;
+   if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
+      mc68328_fb_set_par(&par);
+   fbhw->encode_var(var, &par);
+   var->activate = activate;
+   return(0);
+}
+
+
+   /*
+    *    Default Colormaps
+    */
+
+static u_short red16[] =
+   { 0xc000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0x0000,
+     0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff};
+static u_short green16[] =
+   { 0xc000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0x0000,
+     0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff};
+static u_short blue16[] =
+   { 0xc000, 0x0000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0x0000,
+     0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff};
+
+
+static struct fb_cmap default_16_colors =
+   { 0, 16, red16, green16, blue16, NULL };
+
+
+static struct fb_cmap *get_default_colormap(int bpp)
+{
+   return(&default_16_colors);
+}
+
+
+#define CNVT_TOHW(val,width)     ((((val)<<(width))+0x7fff-(val))>>16)
+#define CNVT_FROMHW(val,width)   (((width) ? ((((val)<<16)-(val)) / \
+                                              ((1<<(width))-1)) : 0))
+
+static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
+                          int kspc)
+{
+   int i, start;
+   u_short *red, *green, *blue, *transp;
+   u_int hred, hgreen, hblue, htransp;
+
+   red = cmap->red;
+   green = cmap->green;
+   blue = cmap->blue;
+   transp = cmap->transp;
+   start = cmap->start;
+   if (start < 0)
+      return(-EINVAL);
+   for (i = 0; i < cmap->len; i++) {
+      if (fbhw->getcolreg(start++, &hred, &hgreen, &hblue, &htransp))
+         return(0);
+      hred = CNVT_FROMHW(hred, var->red.length);
+      hgreen = CNVT_FROMHW(hgreen, var->green.length);
+      hblue = CNVT_FROMHW(hblue, var->blue.length);
+      htransp = CNVT_FROMHW(htransp, var->transp.length);
+      if (kspc) {
+         *red = hred;
+         *green = hgreen;
+         *blue = hblue;
+         if (transp)
+            *transp = htransp;
+      } else {
+         put_fs_word(hred, red);
+         put_fs_word(hgreen, green);
+         put_fs_word(hblue, blue);
+         if (transp)
+            put_fs_word(htransp, transp);
+      }
+      red++;
+      green++;
+      blue++;
+      if (transp)
+         transp++;
+   }
+   return(0);
+}
+
+
+static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
+                          int kspc)
+{
+   int i, start;
+   u_short *red, *green, *blue, *transp;
+   u_int hred, hgreen, hblue, htransp;
+
+   red = cmap->red;
+   green = cmap->green;
+   blue = cmap->blue;
+   transp = cmap->transp;
+   start = cmap->start;
+
+   if (start < 0)
+      return(-EINVAL);
+   for (i = 0; i < cmap->len; i++) {
+      if (kspc) {
+         hred = *red;
+         hgreen = *green;
+         hblue = *blue;
+         htransp = transp ? *transp : 0;
+      } else {
+         hred = get_fs_word(red);
+         hgreen = get_fs_word(green);
+         hblue = get_fs_word(blue);
+         htransp = transp ? get_fs_word(transp) : 0;
+      }
+      hred = CNVT_TOHW(hred, var->red.length);
+      hgreen = CNVT_TOHW(hgreen, var->green.length);
+      hblue = CNVT_TOHW(hblue, var->blue.length);
+      htransp = CNVT_TOHW(htransp, var->transp.length);
+      red++;
+      green++;
+      blue++;
+      if (transp)
+         transp++;
+      if (fbhw->setcolreg(start++, hred, hgreen, hblue, htransp))
+         return(0);
+   }
+   return(0);
+}
+
+
+static void do_install_cmap(int con)
+{
+   if (con != currcon)
+      return;
+   if (disp[con].cmap.len)
+      do_fb_set_cmap(&disp[con].cmap, &disp[con].var, 1);
+   else
+      do_fb_set_cmap(get_default_colormap(disp[con].var.bits_per_pixel),
+                                          &disp[con].var, 1);
+}
+
+
+static void memcpy_fs(int fsfromto, void *to, void *from, int len)
+{
+   switch (fsfromto) {
+      case 0:
+         memcpy(to, from, len);
+         return;
+      case 1:
+         memcpy_fromfs(to, from, len);
+         return;
+      case 2:
+         memcpy_tofs(to, from, len);
+         return;
+   }
+}
+
+
+static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
+{
+   int size;
+   int tooff = 0, fromoff = 0;
+
+   if (to->start > from->start)
+      fromoff = to->start-from->start;
+   else
+      tooff = from->start-to->start;
+   size = to->len-tooff;
+   if (size > from->len-fromoff)
+      size = from->len-fromoff;
+   if (size < 0)
+      return;
+   size *= sizeof(u_short);
+   memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size);
+   memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size);
+   memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size);
+   if (from->transp && to->transp)
+      memcpy_fs(fsfromto, to->transp+tooff, from->transp+fromoff, size);
+}
+
+
+static int alloc_cmap(struct fb_cmap *cmap, int len, int transp)
+{
+   int size = len*sizeof(u_short);
+
+   if (cmap->len != len) {
+      if (cmap->red)
+         kfree(cmap->red);
+      if (cmap->green)
+         kfree(cmap->green);
+      if (cmap->blue)
+         kfree(cmap->blue);
+      if (cmap->transp)
+         kfree(cmap->transp);
+      cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
+      cmap->len = 0;
+      if (!len)
+         return(0);
+      if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
+         return(-1);
+      if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
+         return(-1);
+      if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
+         return(-1);
+      if (transp) {
+         if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
+            return(-1);
+      } else
+         cmap->transp = NULL;
+   }
+   cmap->start = 0;
+   cmap->len = len;
+   copy_cmap(get_default_colormap(len), cmap, 0);
+   return(0);
+}
+
+
+   /*
+    *    Get the Fixed Part of the Display
+    */
+
+static int mc68328_fb_get_fix(struct fb_fix_screeninfo *fix, int con)
+{
+   struct mc68328_fb_par par;
+   int error = 0;
+
+   if (con == -1)
+      mc68328_fb_get_par(&par);
+   else
+      error = fbhw->decode_var(&disp[con].var, &par);
+   return(error ? error : fbhw->encode_fix(fix, &par));
+}
+
+
+   /*
+    *    Get the User Defined Part of the Display
+    */
+
+static int mc68328_fb_get_var(struct fb_var_screeninfo *var, int con)
+{
+   struct mc68328_fb_par par;
+   int error = 0;
+
+   if (con == -1) {
+      mc68328_fb_get_par(&par);
+      error = fbhw->encode_var(var, &par);
+   } else
+      *var = disp[con].var;
+   return(error);
+}
+
+
+static void mc68328_fb_set_disp(int con)
+{
+   struct fb_fix_screeninfo fix;
+
+   mc68328_fb_get_fix(&fix, con);
+   if (con == -1)
+      con = 0;
+   disp[con].screen_base = (u_char *)fix.smem_start;
+   disp[con].visual = fix.visual;
+   disp[con].type = fix.type;
+   disp[con].type_aux = fix.type_aux;
+   disp[con].ypanstep = fix.ypanstep;
+   disp[con].ywrapstep = fix.ywrapstep;
+   disp[con].can_soft_blank = 1;
+   disp[con].inverse = mc68328fb_inverse;
+}
+
+
+   /*
+    *    Set the User Defined Part of the Display
+    */
+
+static int mc68328_fb_set_var(struct fb_var_screeninfo *var, int con)
+{
+   int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
+
+   if ((err = do_fb_set_var(var, con == currcon)))
+      return(err);
+   if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+      oldxres = disp[con].var.xres;
+      oldyres = disp[con].var.yres;
+      oldvxres = disp[con].var.xres_virtual;
+      oldvyres = disp[con].var.yres_virtual;
+      oldbpp = disp[con].var.bits_per_pixel;
+      disp[con].var = *var;
+      if (oldxres != var->xres || oldyres != var->yres ||
+          oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
+          oldbpp != var->bits_per_pixel) {
+         mc68328_fb_set_disp(con);
+         (*fb_info.changevar)(con);
+         alloc_cmap(&disp[con].cmap, 0, 0);
+         do_install_cmap(con);
+      }
+   }
+   var->activate = 0;
+   return(0);
+}
+
+
+   /*
+    *    Get the Colormap
+    */
+
+static int mc68328_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con)
+{
+   if (con == currcon) /* current console? */
+      return(do_fb_get_cmap(cmap, &disp[con].var, kspc));
+   else if (disp[con].cmap.len) /* non default colormap? */
+      copy_cmap(&disp[con].cmap, cmap, kspc ? 0 : 2);
+   else
+      copy_cmap(get_default_colormap(disp[con].var.bits_per_pixel), cmap,
+                kspc ? 0 : 2);
+   return(0);
+}
+
+
+   /*
+    *    Set the Colormap
+    */
+
+static int mc68328_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con)
+{
+   int err;
+
+   if (!disp[con].cmap.len) {       /* no colormap allocated? */
+      if ((err = alloc_cmap(&disp[con].cmap, 1<<disp[con].var.bits_per_pixel,
+                            0)))
+         return(err);
+   }
+   if (con == currcon)              /* current console? */
+      return(do_fb_set_cmap(cmap, &disp[con].var, kspc));
+   else
+      copy_cmap(cmap, &disp[con].cmap, kspc ? 0 : 1);
+   return(0);
+}
+
+
+   /*
+    *    Pan or Wrap the Display
+    *
+    *    This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+    */
+
+static int mc68328_fb_pan_display(struct fb_var_screeninfo *var, int con)
+{
+   return(-EINVAL);
+}
+
+
+   /*
+    *    mc68328 Frame Buffer Specific ioctls
+    */
+
+static int mc68328_fb_ioctl(struct inode *inode, struct file *file,
+                          u_int cmd, u_long arg, int con)
+{
+   return(-EINVAL);
+}
+
+
+static struct fb_ops mc68328_fb_ops = {
+   mc68328_fb_get_fix, mc68328_fb_get_var, mc68328_fb_set_var, mc68328_fb_get_cmap,
+   mc68328_fb_set_cmap, mc68328_fb_pan_display, mc68328_fb_ioctl
+};
+
+
+void mc68328_video_setup(char *options, int *ints)
+{
+   char *this_opt;
+   int i;
+
+   fb_info.fontname[0] = '\0';
+
+   if (!options || !*options)
+      return;
+
+   for (this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ","))
+      if (!strcmp(this_opt, "inverse")) {
+         mc68328fb_inverse = 1;
+         for (i = 0; i < 16; i++) {
+            red16[i] = ~red16[i];
+            green16[i] = ~green16[i];
+            blue16[i] = ~blue16[i];
+         }
+      } else if (!strncmp(this_opt, "font:", 5))
+         strcpy(fb_info.fontname, this_opt+5);
+      else
+         mc68328fb_mode = get_video_mode(this_opt);
+}
+
+
+   /*
+    *    Initialization
+    */
+
+struct fb_info *mc68328_fb_init(long *mem_start)
+{
+   int err;
+   struct mc68328_fb_par par;
+
+   memstart = mem_start;
+
+   fbhw = &mc68328_switch;
+
+   err = register_framebuffer(mc68328_fb_name, &node, &mc68328_fb_ops,
+                              NUM_TOTAL_MODES, mc68328_fb_predefined);
+   if (err < 0)
+      panic("Cannot register frame buffer\n");
+
+   fbhw->init();
+   fbhw->decode_var(&mc68328_fb_predefined[mc68328fb_mode], &par);
+   fbhw->encode_var(&mc68328_fb_predefined[0], &par);
+
+   strcpy(fb_info.modename, mc68328_fb_name);
+   fb_info.disp = disp;
+   fb_info.switch_con = &mc68328fb_switch;
+   fb_info.updatevar = &mc68328fb_updatevar;
+   fb_info.blank = &mc68328fb_blank;
+
+   do_fb_set_var(&mc68328_fb_predefined[0], 1);
+   mc68328_fb_get_var(&disp[0].var, -1);
+   mc68328_fb_set_disp(-1);
+   do_install_cmap(0);
+   return(&fb_info);
+}
+
+
+static int mc68328fb_switch(int con)
+{
+   /* Do we have to save the colormap? */
+   if (disp[currcon].cmap.len)
+      do_fb_get_cmap(&disp[currcon].cmap, &disp[currcon].var, 1);
+
+   do_fb_set_var(&disp[con].var, 1);
+   currcon = con;
+   /* Install new colormap */
+   do_install_cmap(con);
+   return(0);
+}
+
+
+   /*
+    *    Update the `var' structure (called by fbcon.c)
+    *
+    *    This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'.
+    *    Since it's called by a kernel driver, no range checking is done.
+    */
+
+static int mc68328fb_updatevar(int con)
+{
+   return(0);
+}
+
+
+   /*
+    *    Blank the display.
+    */
+
+static void mc68328fb_blank(int blank)
+{
+   fbhw->blank(blank);
+}
+
+
+   /*
+    *    Get a Video Mode
+    */
+
+static int get_video_mode(const char *name)
+{
+   int i;
+
+   for (i = 1; i < NUM_PREDEF_MODES; i++)
+      if (!strcmp(name, mc68328_fb_modenames[i]))
+         return(i);
+   return(0);
+}
diff -urN linux-2.4.29/arch/blackfin/console/fbcon.c linux-2.4.29-uc1/arch/blackfin/console/fbcon.c
--- linux-2.4.29/arch/blackfin/console/fbcon.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/console/fbcon.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,3894 @@
+/*
+ * linux/arch/m68knommu/console/fbcon.c -- Low level frame buffer based console
+ *                                    driver
+ *
+ * Modifications to support 4-bit wide monochrome fonts
+ *	-- Kenneth Albanowski <kjahds@kjahds.com>
+ *
+ * Copyright (C) 1998,1999 Kenneth Albanowski <kjahds@kjahds.com>,
+ *                         The Silver Hammer Group, Ltd.
+ * 
+ * Based on:
+ *
+ * linux/arch/m68k/console/fbcon.c -- Low level frame buffer based console
+ *                                    driver
+ *
+ *    Copyright (C) 1995 Geert Uytterhoeven
+ *
+ *
+ * This file is based on the original Amiga console driver (amicon.c):
+ *
+ *    Copyright (C) 1993 Hamish Macdonald
+ *                       Greg Harp
+ *    Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
+ *
+ *          with work by William Rucklidge (wjr@cs.cornell.edu)
+ *                       Geert Uytterhoeven
+ *                       Jes Sorensen (jds@kom.auc.dk)
+ *                       Martin Apel
+ *
+ * and on the original Atari console driver (atacon.c):
+ *
+ *    Copyright (C) 1993 Bjoern Brauel
+ *                       Roman Hodek
+ *
+ *          with work by Guenther Kelleter
+ *                       Martin Schaller
+ *                       Andreas Schwab
+ *
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * To do:
+ *  - Implement 16 plane mode.
+ *  - Add support for 16/24/32 bit packed pixels
+ *  - Hardware cursor
+ */
+
+
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/config.h>
+#include <linux/kd.h>
+#include <linux/slab.h>
+
+#include <asm/irq.h>
+#ifdef CONFIG_AMIGA
+#include <asm/amigahw.h>
+#include <asm/amigaints.h>
+#endif /* CONFIG_AMIGA */
+#ifdef CONFIG_ATARI
+#include <asm/atariints.h>
+#endif
+#ifdef CONFIG_FB_CYBER
+#include "../amiga/s3blit.h"
+#endif /* CONFIG_FB_CYBER */
+#include <linux/fb.h>
+#include <asm/font.h>
+#include <asm/machdep.h>
+
+#include <asm/system.h>
+
+#include "../../../drivers/char/vt_kern.h"   /* vt_cons and vc_resize_con() */
+
+extern struct fb_info *mc68328_fb_init(long *mem_start);
+
+
+/* Import console_blanked from console.c */
+
+extern int console_blanked;
+
+
+   /*
+    *    The following symbols select what modes are supported. They should
+    *    be settable by the user ("make config") later.
+    */
+
+/* Clear all definitions */
+
+#undef CONFIG_FBCON_MONO
+#undef CONFIG_FBCON_ILBM
+#undef CONFIG_FBCON_PLANES
+#undef CONFIG_FBCON_2PLANE
+#undef CONFIG_FBCON_4PLANE
+#undef CONFIG_FBCON_8PLANE
+#undef CONFIG_FBCON_8PACKED
+#undef CONFIG_FBCON_16PACKED
+#undef CONFIG_FBCON_24PACKED
+#undef CONFIG_FBCON_32PACKED
+#undef CONFIG_FBCON_CYBER
+
+
+/* Monochrome is default */
+
+#define CONFIG_FBCON_MONO
+
+/* Amiga support */
+
+#ifdef CONFIG_AMIGA
+#ifndef CONFIG_FBCON_ILBM
+#define CONFIG_FBCON_ILBM
+#endif
+#ifndef CONFIG_FBCON_PLANES
+#define CONFIG_FBCON_PLANES
+#endif
+
+/* Cybervision Graphics Board */
+
+#ifdef CONFIG_FB_CYBER
+#ifndef CONFIG_FBCON_CYBER
+#define CONFIG_FBCON_CYBER
+#endif
+#endif /* CONFIG_FB_CYBER */
+
+#endif /* CONFIG_AMIGA */
+
+/* Atari support */
+
+#ifdef CONFIG_ATARI
+#ifndef CONFIG_FBCON_2PLANE
+#define CONFIG_FBCON_2PLANE
+#endif
+#ifndef CONFIG_FBCON_4PLANE
+#define CONFIG_FBCON_4PLANE
+#endif
+#ifndef CONFIG_FBCON_8PLANE
+#define CONFIG_FBCON_8PLANE
+#endif
+#ifndef CONFIG_FBCON_8PACKED
+#define CONFIG_FBCON_8PACKED
+#endif
+#ifndef CONFIG_FBCON_16PACKED
+#define CONFIG_FBCON_16PACKED
+#endif
+#endif /* CONFIG_ATARI */
+
+
+/* Extra definitions to make the code more readable */
+
+#if defined(CONFIG_FBCON_2PLANE) || defined(CONFIG_FBCON_4PLANE) || \
+    defined(CONFIG_FBCON_8PLANE)
+#define CONFIG_FBCON_IPLAN2
+#else
+#undef CONFIG_FBCON_IPLAN2
+#endif
+
+#if defined(CONFIG_FBCON_CYBER) || defined(CONFIG_FBCON_8PACKED) || \
+    defined(CONFIG_FBCON_16PACKED) || defined(CONFIG_FBCON_24PACKED) || \
+    defined(CONFIG_FBCON_32PACKED)
+#define CONFIG_FBCON_PACKED
+#else
+#undef CONFIG_FBCON_PACKED
+#endif
+
+
+struct fb_info *fb_info;
+struct display *disp;
+
+
+/* ++Geert: Sorry, no hardware cursor support at the moment;
+   use Atari alike software cursor */
+
+static int cursor_drawn = 0;
+
+#define CURSOR_DRAW_DELAY           (2)
+
+/* # VBL ints between cursor state changes */
+#define AMIGA_CURSOR_BLINK_RATE   (20)
+#define ATARI_CURSOR_BLINK_RATE   (42)
+
+static int vbl_cursor_cnt = 0;
+static int cursor_on = 0;
+static int cursor_blink_rate;
+
+static __inline__ int CURSOR_UNDRAWN(void)
+{
+   int cursor_was_drawn;
+   vbl_cursor_cnt = 0;
+   cursor_was_drawn = cursor_drawn;
+   cursor_drawn = 0;
+   return(cursor_was_drawn);
+}
+
+   /*
+    *    Attribute Decoding
+    */
+
+/* Color */
+#define attr_fgcol(p,conp)    \
+	(((conp)->vc_attr >> ((p)->inverse ? 4 : 0)) & 0x0f)
+#define attr_bgcol(p,conp)    \
+	(((conp)->vc_attr >> ((p)->inverse ? 0 : 4)) & 0x0f)
+#define	attr_bgcol_ec(p,conp) \
+	(((conp)->vc_video_erase_char >> ((p)->inverse ? 8 : 12)) & 0x0f)
+
+/* Monochrome */
+#define attr_bold(p,conp)     \
+	(((conp)->vc_attr & 3) == 2)
+#define attr_reverse(p,conp)  \
+	(((conp)->vc_attr & 8) ^ ((p)->inverse ? 8 : 0))
+#define attr_underline(p,conp) \
+	(((conp)->vc_attr) & 4)
+
+
+   /*
+    *    Scroll Method
+    */
+
+#define SCROLL_YWRAP          (0)
+#define SCROLL_YPAN           (1)
+#define SCROLL_YMOVE          (2)
+
+#define divides(a, b)         ((!(a) || (b)%(a)) ? 0 : 1)
+
+
+   /*
+    *    Interface used by the world
+    */
+
+static u_long fbcon_startup(u_long kmem_start, char **display_desc);
+static void fbcon_init(struct vc_data *conp);
+static int fbcon_deinit(struct vc_data *conp);
+static int fbcon_changevar(int con);
+static int fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
+                       int width);
+static int fbcon_putc(struct vc_data *conp, int c, int y, int x);
+static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int y,
+                       int x);
+static int fbcon_cursor(struct vc_data *conp, int mode);
+static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir, int count);
+static int fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+                       int height, int width);
+static int fbcon_switch(struct vc_data *conp);
+static int fbcon_blank(int blank);
+
+
+   /*
+    *    Internal routines
+    */
+
+static void fbcon_setup(int con, int setcol, int cls);
+static __inline__ void *mymemclear_small(void *s, size_t count);
+static __inline__ void *mymemclear(void *s, size_t count);
+static __inline__ void *mymemset(void *s, size_t count);
+static __inline__ void *mymemmove(void *d, void *s, size_t count);
+static __inline__ void fast_memmove(char *dst, char *src, size_t size);
+static __inline__ void memclear_4p_col(void *d, size_t h, u_long val, int bpr);
+static __inline__ void memset_even_4p(void *d, size_t count, u_long val1,
+                                      u_long val2);
+static __inline__ void memmove_4p_col(void *d, void *s, int h, int bpr);
+static __inline__ u_long expand4l(u_char c);
+static __inline__ void expand4dl(u_char c, u_long *ret1, u_long *ret2);
+static __inline__ u_long dup4l(u_char c);
+static __inline__ void memclear_8p_col(void *d, size_t h, u_long val1,
+                                       u_long val2, int bpr);
+static __inline__ void memset_even_8p(void *d, size_t count, u_long val1,
+                                      u_long val2, u_long val3, u_long val4);
+static __inline__ void memmove_8p_col(void *d, void *s, int h, int bpr);
+static __inline__ void expand8dl(u_char c, u_long *ret1, u_long *ret2);
+static __inline__ void memclear_2p_col(void *d, size_t h, u_short val, int bpr);
+static __inline__ void memset_even_2p(void *d, size_t count, u_long val);
+static __inline__ void memmove_2p_col(void *d, void *s, int h, int bpr);
+static __inline__ u_short expand2w(u_char c);
+static __inline__ u_long expand2l(u_char c);
+static __inline__ u_short dup2w(u_char c);
+static __inline__ int real_y(struct display *p, int y);
+static void fbcon_vbl_handler(int irq, struct pt_regs *fp, void *dummy);
+static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy, int dx,
+                            int height, int width, u_int y_break);
+
+
+   /*
+    *    Monochrome
+    */
+
+#ifdef CONFIG_FBCON_MONO
+static void bmove_mono(struct display *p, int sy, int sx, int dy, int dx,
+                       int height, int width);
+static void clear_mono(struct vc_data *conp, struct display *p, int sy, int sx,
+                       int height, int width);
+static void putc_mono(struct vc_data *conp, struct display *p, int c, int y,
+                      int x);
+static void putcs_mono(struct vc_data *conp, struct display *p, const char *s,
+                       int count, int y, int x);
+static void rev_char_mono(struct display *p, int x, int y);
+#endif /* CONFIG_FBCON_MONO */
+
+
+   /*
+    *    Color Interleaved Planes
+    */
+
+#ifdef CONFIG_FBCON_ILBM
+static void bmove_ilbm(struct display *p, int sy, int sx, int dy, int dx,
+                       int height, int width);
+static void clear_ilbm(struct vc_data *conp, struct display *p, int sy, int sx,
+                       int height, int width);
+static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int y,
+                      int x);
+static void putcs_ilbm(struct vc_data *conp, struct display *p, const char *s,
+                       int count, int y, int x);
+static void rev_char_ilbm(struct display *p, int x, int y);
+#endif /* CONFIG_FBCON_ILBM */
+
+
+   /*
+    *    Color Planes
+    */
+
+#ifdef CONFIG_FBCON_PLANES
+static void bmove_plan(struct display *p, int sy, int sx, int dy, int dx,
+                       int height, int width);
+static void clear_plan(struct vc_data *conp, struct display *p, int sy, int sx,
+                       int height, int width);
+static void putc_plan(struct vc_data *conp, struct display *p, int c, int y,
+                      int x);
+static void putcs_plan(struct vc_data *conp, struct display *p, const char *s,
+                       int count, int y, int x);
+static void rev_char_plan(struct display *p, int x, int y);
+#endif /* CONFIG_FBCON_PLANES */
+
+
+   /*
+    *    2 Planes (2-bytes interleave)
+    */
+
+#ifdef CONFIG_FBCON_2PLANE
+static void bmove_2_plane(struct display *p, int sy, int sx, int dy, int dx,
+                          int height, int width);
+static void clear_2_plane(struct vc_data *conp, struct display *p, int sy,
+                          int sx, int height, int width);
+static void putc_2_plane(struct vc_data *conp, struct display *p, int c, int y,
+                         int x);
+static void putcs_2_plane(struct vc_data *conp, struct display *p,
+                          const char *s, int count, int y, int x);
+static void rev_char_2_plane(struct display *display, int x, int y);
+#endif /* CONFIG_FBCON_2PLANE */
+
+
+   /*
+    *    4 Planes (2-bytes interleave)
+    */
+
+#ifdef CONFIG_FBCON_4PLANE
+static void bmove_4_plane(struct display *p, int sy, int sx, int dy, int dx,
+                          int height, int width);
+static void clear_4_plane(struct vc_data *conp, struct display *p, int sy,
+                          int sx, int height, int width);
+static void putc_4_plane(struct vc_data *conp, struct display *p, int c, int y,
+                         int x);
+static void putcs_4_plane(struct vc_data *conp, struct display *p,
+                          const char *s, int count, int y, int x);
+static void rev_char_4_plane(struct display *p, int x, int y);
+#endif /* CONFIG_FBCON_4PLANE */
+
+
+   /*
+    *    8 Planes (2-bytes interleave)
+    */
+
+#ifdef CONFIG_FBCON_8PLANE
+static void bmove_8_plane(struct display *p, int sy, int sx, int dy, int dx,
+                          int height, int width);
+static void clear_8_plane(struct vc_data *conp, struct display *p, int sy,
+                          int sx, int height, int width);
+static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int y,
+                         int x);
+static void putcs_8_plane(struct vc_data *conp, struct display *p,
+                          const char *s, int count, int y, int x);
+static void rev_char_8_plane(struct display *display, int x, int y);
+#endif /* CONFIG_FBCON_8PLANE */
+
+
+   /*
+    *    8 bpp Packed Pixels
+    */
+
+#ifdef CONFIG_FBCON_8PACKED
+static void bmove_8_packed(struct display *p, int sy, int sx, int dy, int dx,
+                           int height, int width);
+static void clear_8_packed(struct vc_data *conp, struct display *p, int sy,
+                           int sx, int height, int width);
+static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int y,
+                          int x);
+static void putcs_8_packed(struct vc_data *conp, struct display *p,
+                           const char *s, int count, int y, int x);
+static void rev_char_8_packed(struct display *p, int x, int y);
+#endif /* CONFIG_FBCON_8PACKED */
+
+
+   /*
+    *    16 bpp Packed Pixels
+    */
+
+#ifdef CONFIG_FBCON_16PACKED
+static void bmove_16_packed(struct display *p, int sy, int sx, int dy, int dx,
+                            int height, int width);
+static void clear_16_packed(struct vc_data *conp, struct display *p, int sy,
+                            int sx, int height, int width);
+static void putc_16_packed(struct vc_data *conp, struct display *p, int c,
+                           int y, int x);
+static void putcs_16_packed(struct vc_data *conp, struct display *p,
+                            const char *s, int count, int y, int x);
+static void rev_char_16_packed(struct display *p, int x, int y);
+#endif */ CONFIG_FBCON_8PACKED */
+
+
+   /*
+    *    Cybervision (accelerated)
+    */
+
+#ifdef CONFIG_FBCON_CYBER
+static void bmove_cyber(struct display *p, int sy, int sx, int dy, int dx,
+                        int height, int width);
+static void clear_cyber(struct vc_data *conp, struct display *p, int sy, int sx,
+                        int height, int width);
+static void putc_cyber(struct vc_data *conp, struct display *p, int c, int y,
+                       int x);
+static void putcs_cyber(struct vc_data *conp, struct display *p, const char *s,
+                        int count, int y, int x);
+static void rev_char_cyber(struct display *p, int x, int y);
+
+extern void Cyber_WaitQueue(u_short fifo);
+extern void Cyber_WaitBlit(void);
+extern void Cyber_BitBLT(u_short curx, u_short cury, u_short destx,
+                         u_short desty, u_short width, u_short height,
+                         u_short mode);
+extern void Cyber_RectFill(u_short x, u_short y, u_short width, u_short height,
+                           u_short mode, u_short color);
+extern void Cyber_MoveCursor(u_short x, u_short y);
+#endif /* CONFIG_FBCON_CYBER */
+
+
+   /*
+    *    `switch' for the Low Level Operations
+    */
+
+struct display_switch {
+    void (*bmove)(struct display *p, int sy, int sx, int dy, int dx, int height,
+                  int width);
+    void (*clear)(struct vc_data *conp, struct display *p, int sy, int sx,
+                  int height, int width);
+    void (*putc)(struct vc_data *conp, struct display *p, int c, int y, int x);
+    void (*putcs)(struct vc_data *conp, struct display *p, const char *s,
+                  int count, int y, int x);
+    void (*rev_char)(struct display *p, int x, int y);
+};
+
+
+#ifdef CONFIG_FBCON_MONO
+struct display_switch dispsw_mono = {
+   bmove_mono, clear_mono, putc_mono, putcs_mono, rev_char_mono
+};
+#endif /* CONFIG_FBCON_MONO */
+
+#ifdef CONFIG_FBCON_ILBM
+struct display_switch dispsw_ilbm = {
+   bmove_ilbm, clear_ilbm, putc_ilbm, putcs_ilbm, rev_char_ilbm
+};
+#endif /* CONFIG_FBCON_ILBM */
+
+#ifdef CONFIG_FBCON_PLANES
+struct display_switch dispsw_plan = {
+   bmove_plan, clear_plan, putc_plan, putcs_plan, rev_char_plan
+};
+#endif /* CONFIG_FBCON_PLANES */
+
+#ifdef CONFIG_FBCON_2PLANE
+struct display_switch dispsw_2_plane = {
+   bmove_2_plane, clear_2_plane, putc_2_plane, putcs_2_plane, rev_char_2_plane
+};
+#endif /* CONFIG_FBCON_2PLANE */
+
+#ifdef CONFIG_FBCON_4PLANE
+struct display_switch dispsw_4_plane = {
+   bmove_4_plane, clear_4_plane, putc_4_plane, putcs_4_plane, rev_char_4_plane
+};
+#endif /* CONFIG_FBCON_4PLANE */
+
+#ifdef CONFIG_FBCON_8PLANE
+struct display_switch dispsw_8_plane = {
+   bmove_8_plane, clear_8_plane, putc_8_plane, putcs_8_plane, rev_char_8_plane
+};
+#endif /* CONFIG_FBCON_8PLANE */
+
+#ifdef CONFIG_FBCON_8PACKED
+struct display_switch dispsw_8_packed = {
+   bmove_8_packed, clear_8_packed, putc_8_packed, putcs_8_packed, rev_char_8_packed
+};
+#endif /* CONFIG_FBCON_8PACKED */
+
+#ifdef CONFIG_FBCON_16PACKED
+struct display_switch dispsw_16_packed = {
+   bmove_16_packed, clear_16_packed, putc_16_packed, putcs_16_packed,
+   rev_char_16_packed
+};
+#endif /* CONFIG_FBCON_16PACKED */
+
+#ifdef CONFIG_FBCON_CYBER
+struct display_switch dispsw_cyber = {
+   bmove_cyber, clear_cyber, putc_cyber, putcs_cyber, rev_char_cyber
+};
+#endif /* CONFIG_FBCON_CYBER */
+
+
+static u_long fbcon_startup(u_long kmem_start, char **display_desc)
+{
+   int irqres = 0;
+
+   fb_info = mc68328_fb_init(&kmem_start);
+   disp = fb_info->disp;
+   *display_desc = fb_info->modename;
+   fb_info->changevar = &fbcon_changevar;
+
+#ifdef CONFIG_AMIGA
+   if (MACH_IS_AMIGA) {
+      cursor_blink_rate = AMIGA_CURSOR_BLINK_RATE;
+      irqres = add_isr(IRQ_AMIGA_VERTB, fbcon_vbl_handler, 0, NULL,
+                       "console/cursor");
+   }
+#endif /* CONFIG_AMIGA */
+#ifdef CONFIG_ATARI
+   if (MACH_IS_ATARI) {
+      cursor_blink_rate = ATARI_CURSOR_BLINK_RATE;
+      irqres = add_isr(IRQ_AUTO_4, fbcon_vbl_handler, IRQ_TYPE_PRIO, NULL,
+		       "console/cursor");
+   }
+#endif /* CONFIG_ATARI */
+
+#if defined(CONFIG_AMIGA) || defined(CONFIG_ATARI)
+   if (!irqres)
+      panic("fbcon_startup: Couldn't add vblank interrupt");
+#endif
+
+   return(kmem_start);
+}
+
+
+static void fbcon_init(struct vc_data *conp)
+{
+   int unit = conp->vc_num;
+
+   if (unit)
+      disp[unit] = disp[0];
+   disp[unit].conp = conp;
+   fbcon_setup(unit, 1, 0);
+}
+
+
+static int fbcon_deinit(struct vc_data *conp)
+{
+   disp[conp->vc_num].conp = 0;
+   return(0);
+}
+
+
+static int fbcon_changevar(int con)
+{
+   fbcon_setup(con, 1, 1);
+   return(0);
+}
+
+
+static void fbcon_setup(int con, int setcol, int cls)
+{
+   struct display *p = &disp[con];
+   struct vc_data *conp = p->conp;
+
+   p->var.xoffset = p->var.yoffset = p->yscroll = 0;  /* reset wrap/pan */
+
+   if (!fb_info->fontname[0] ||
+       !findsoftfont(fb_info->fontname, &p->fontwidth, &p->fontheight,
+                     &p->fontdata))
+	   getdefaultfont(p->var.xres, p->var.yres, NULL, &p->fontwidth,
+	                  &p->fontheight, &p->fontdata);
+
+   if (divides(p->ywrapstep, p->fontheight) && divides(p->fontheight, p->var.yres_virtual))
+      p->scrollmode = SCROLL_YWRAP;
+   else if (divides(p->ypanstep, p->fontheight) &&
+            p->var.yres_virtual >= p->var.yres+p->fontheight)
+      p->scrollmode = SCROLL_YPAN;
+   else
+      p->scrollmode = SCROLL_YMOVE;
+
+   conp->vc_cols = p->var.xres/p->fontwidth;
+   conp->vc_rows = p->var.yres/p->fontheight;
+   p->vrows = p->var.yres_virtual/p->fontheight;
+   conp->vc_can_do_color = p->var.bits_per_pixel != 1;
+
+#ifdef CONFIG_FBCON_MONO
+   if (p->var.bits_per_pixel == 1) {
+      if (p->line_length)
+         p->next_line = p->line_length;
+      else
+         p->next_line = p->var.xres_virtual/8;
+      p->next_plane = 0;
+      p->dispsw = &dispsw_mono;
+   } else
+#endif /* CONFIG_FBCON_MONO */
+#ifdef CONFIG_FBCON_IPLAN2
+   if (p->type == FB_TYPE_INTERLEAVED_PLANES && p->type_aux == 2) {
+      p->next_line = p->var.xres_virtual*p->var.bits_per_pixel>>3;
+      p->next_plane = 0;
+#ifdef CONFIG_FBCON_2PLANE
+      if (p->var.bits_per_pixel == 2)
+         p->dispsw = &dispsw_2_plane;
+      else
+#endif /* CONFIG_FBCON_2PLANE */
+#ifdef CONFIG_FBCON_4PLANE
+      if (p->var.bits_per_pixel == 4)
+         p->dispsw = &dispsw_4_plane;
+      else
+#endif /* CONFIG_FBCON_4PLANE */
+#ifdef CONFIG_FBCON_8PLANE
+      if (p->var.bits_per_pixel == 8)
+         p->dispsw = &dispsw_8_plane;
+      else
+#endif /* CONFIG_FBCON_8PLANE */
+      goto fail;
+   } else
+#endif /* CONFIG_FBCON_IPLAN2 */
+#ifdef CONFIG_FBCON_ILBM
+   if (p->type == FB_TYPE_INTERLEAVED_PLANES && p->type_aux != 2) {
+      if (p->line_length) {
+         p->next_line = p->line_length*p->var.bits_per_pixel;
+         p->next_plane = p->line_length;
+      } else {
+         p->next_line = p->type_aux;
+         p->next_plane = p->type_aux/p->var.bits_per_pixel;
+      }
+      p->dispsw = &dispsw_ilbm;
+   } else
+#endif /* CONFIG_FBCON_ILBM */
+#ifdef CONFIG_FBCON_PLANES
+   if (p->type == FB_TYPE_PLANES) {
+      if (p->line_length)
+         p->next_line = p->line_length;
+      else
+         p->next_line = p->var.xres_virtual>>3;
+      p->next_plane = p->var.yres_virtual*p->next_line;
+      p->dispsw = &dispsw_plan;
+   } else
+#endif /* CONFIG_FBCON_PLANES */
+#ifdef CONFIG_FBCON_PACKED
+   if (p->type == FB_TYPE_PACKED_PIXELS) {
+      p->next_line = p->var.xres_virtual*p->var.bits_per_pixel>>3;
+      p->next_plane = 0;
+#ifdef CONFIG_FBCON_CYBER
+      if (p->var.accel == FB_ACCEL_CYBERVISION)
+         p->dispsw = &dispsw_cyber;
+      else
+#endif /* CONFIG_FBCON_CYBER */
+#ifdef CONFIG_FBCON_8PACKED
+      if (p->var.bits_per_pixel == 8)
+         p->dispsw = &dispsw_8_packed;
+      else
+#endif /* CONFIG_FBCON_8PACKED */
+#ifdef CONFIG_FBCON_16PACKED
+      if (p->var.bits_per_pixel == 16)
+         p->dispsw = &dispsw_16_packed;
+      else
+#endif /* CONFIG_FBCON_16PACKED */
+#ifdef CONFIG_FBCON_24PACKED
+      if (p->var.bits_per_pixel == 24)
+         p->dispsw = &dispsw_24_packed;
+      else
+#endif /* CONFIG_FBCON_24PACKED */
+#ifdef CONFIG_FBCON_32PACKED
+      if (p->var.bits_per_pixel == 32)
+         p->dispsw = &dispsw_32_packed;
+      else
+#endif /* CONFIG_FBCON_32PACKED */
+      goto fail;
+   } else
+#endif /* CONFIG_FBCON_PACKED */
+   {
+fail:
+#ifdef CONFIG_FBCON_MONO
+      printk("fbcon_setup: type %d (aux %d) not supported, trying mono\n",
+             p->type, p->type_aux);
+      if (p->line_length)
+         p->next_line = p->line_length;
+      else
+         p->next_line = p->var.xres_virtual/8;
+      p->next_plane = 0;
+      p->var.bits_per_pixel = 1;
+      p->dispsw = &dispsw_mono;
+#else /* CONFIG_FBCON_MONO */
+      panic("fbcon_setup: no default driver");
+#endif /* CONFIG_FBCON_MONO */
+   }
+
+   if ((p->dispsw != &dispsw_mono) && (p->fontwidth != 8))
+      panic("fbcon_setup: No support for fontwidth != 8 on non-monochrome targets");
+
+   if ((p->dispsw == &dispsw_mono) && (p->fontwidth != 8) && (p->fontwidth != 4) )
+      panic("fbcon_setup: No support for fontwidth != 8/4 on monochrome targets");
+
+   if (setcol) {
+      p->fgcol = p->var.bits_per_pixel > 2 ? 7 : (1<<p->var.bits_per_pixel)-1;
+      p->bgcol = 0;
+   }
+
+   if (cls)
+      vc_resize_con(conp->vc_rows, conp->vc_cols, con);
+}
+
+
+/* ================================================================= */
+/*                      Utility Assembler Functions                  */
+/* ================================================================= */
+
+
+/* ====================================================================== */
+
+/* Those of a delicate disposition might like to skip the next couple of
+ * pages.
+ *
+ * These functions are drop in replacements for memmove and
+ * memset(_, 0, _). However their five instances add at least a kilobyte
+ * to the object file. You have been warned.
+ *
+ * Not a great fan of assembler for the sake of it, but I think
+ * that these routines are at least 10 times faster than their C
+ * equivalents for large blits, and that's important to the lowest level of
+ * a graphics driver. Question is whether some scheme with the blitter
+ * would be faster. I suspect not for simple text system - not much
+ * asynchrony.
+ *
+ * Code is very simple, just gruesome expansion. Basic strategy is to
+ * increase data moved/cleared at each step to 16 bytes to reduce
+ * instruction per data move overhead. movem might be faster still
+ * For more than 15 bytes, we try to align the write direction on a
+ * longword boundary to get maximum speed. This is even more gruesome.
+ * Unaligned read/write used requires 68020+ - think this is a problem?
+ *
+ * Sorry!
+ */
+
+
+/* ++roman: I've optimized Robert's original versions in some minor
+ * aspects, e.g. moveq instead of movel, let gcc choose the registers,
+ * use movem in some places...
+ * For other modes than 1 plane, lots of more such assembler functions
+ * were needed (e.g. the ones using movep or expanding color values).
+ */
+
+/* ++andreas: more optimizations:
+   subl #65536,d0 replaced by clrw d0; subql #1,d0 for dbcc
+   addal is faster than addaw
+   movep is rather expensive compared to ordinary move's
+   some functions rewritten in C for clarity, no speed loss */
+
+static __inline__ void *mymemclear_small(void *s, size_t count)
+{
+   if (!count)
+      return(0);
+
+   __asm__ __volatile__(
+         "lsrl   #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t"
+      "1: lsrl   #1,%1 ; jcc 1f ; movew %2,%0@-\n\t"
+      "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@-\n\t"
+      "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t"
+      "1: subql  #1,%1 ; jcs 3f\n\t"
+      "2: moveml %2/%3/%4/%5,%0@-\n\t"
+         "dbra %1,2b\n\t"
+      "3:"
+         : "=a" (s), "=d" (count)
+         :  "d" (0), "d" (0), "d" (0), "d" (0),
+            "0" ((char *)s+count), "1" (count)
+  );
+
+   return(0);
+}
+
+
+static __inline__ void *mymemclear(void *s, size_t count)
+{
+   if (!count)
+      return(0);
+
+   if (count < 16) {
+      __asm__ __volatile__(
+            "lsrl   #1,%1 ; jcc 1f ; clrb %0@+\n\t"
+         "1: lsrl   #1,%1 ; jcc 1f ; clrw %0@+\n\t"
+         "1: lsrl   #1,%1 ; jcc 1f ; clrl %0@+\n\t"
+         "1: lsrl   #1,%1 ; jcc 1f ; clrl %0@+ ; clrl %0@+\n\t"
+         "1:"
+            : "=a" (s), "=d" (count)
+            : "0" (s), "1" (count)
+     );
+   } else {
+      long tmp;
+      __asm__ __volatile__(
+            "movel %1,%2\n\t"
+            "lsrl   #1,%2 ; jcc 1f ; clrb %0@+ ; subqw #1,%1\n\t"
+            "lsrl   #1,%2 ; jcs 2f\n\t"  /* %0 increased=>bit 2 switched*/
+            "clrw   %0@+  ; subqw  #2,%1 ; jra 2f\n\t"
+         "1: lsrl   #1,%2 ; jcc 2f\n\t"
+            "clrw   %0@+  ; subqw  #2,%1\n\t"
+         "2: movew %1,%2; lsrl #2,%1 ; jeq 6f\n\t"
+            "lsrl   #1,%1 ; jcc 3f ; clrl %0@+\n\t"
+         "3: lsrl   #1,%1 ; jcc 4f ; clrl %0@+ ; clrl %0@+\n\t"
+         "4: subql  #1,%1 ; jcs 6f\n\t"
+         "5: clrl %0@+; clrl %0@+ ; clrl %0@+ ; clrl %0@+\n\t"
+            "dbra %1,5b   ; clrw %1; subql #1,%1; jcc 5b\n\t"
+         "6: movew %2,%1; btst #1,%1 ; jeq 7f ; clrw %0@+\n\t"
+         "7:            ; btst #0,%1 ; jeq 8f ; clrb %0@+\n\t"
+         "8:"
+            : "=a" (s), "=d" (count), "=d" (tmp)
+            : "0" (s), "1" (count)
+     );
+   }
+
+   return(0);
+}
+
+
+static __inline__ void *mymemset(void *s, size_t count)
+{
+   if (!count)
+      return(0);
+
+   __asm__ __volatile__(
+         "lsrl   #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t"
+      "1: lsrl   #1,%1 ; jcc 1f ; movew %2,%0@-\n\t"
+      "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@-\n\t"
+      "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t"
+      "1: subql  #1,%1 ; jcs 3f\n\t"
+      "2: moveml %2/%3/%4/%5,%0@-\n\t"
+         "dbra %1,2b\n\t"
+      "3:"
+         : "=a" (s), "=d" (count)
+         :  "d" (-1), "d" (-1), "d" (-1), "d" (-1),
+            "0" ((char *) s + count), "1" (count)
+  );
+
+   return(0);
+}
+
+
+static __inline__ void *mymemmove(void *d, void *s, size_t count)
+{
+   if (d < s) {
+      if (count < 16) {
+         __asm__ __volatile__(
+               "lsrl   #1,%2 ; jcc 1f ; moveb %1@+,%0@+\n\t"
+            "1: lsrl   #1,%2 ; jcc 1f ; movew %1@+,%0@+\n\t"
+            "1: lsrl   #1,%2 ; jcc 1f ; movel %1@+,%0@+\n\t"
+            "1: lsrl   #1,%2 ; jcc 1f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t"
+            "1:"
+               : "=a" (d), "=a" (s), "=d" (count)
+               : "0" (d), "1" (s), "2" (count)
+        );
+      } else {
+         long tmp;
+         __asm__ __volatile__(
+               "movel  %0,%3\n\t"
+               "lsrl   #1,%3 ; jcc 1f ; moveb %1@+,%0@+ ; subqw #1,%2\n\t"
+               "lsrl   #1,%3 ; jcs 2f\n\t"  /* %0 increased=>bit 2 switched*/
+               "movew  %1@+,%0@+  ; subqw  #2,%2 ; jra 2f\n\t"
+            "1: lsrl   #1,%3 ; jcc 2f\n\t"
+               "movew  %1@+,%0@+  ; subqw  #2,%2\n\t"
+            "2: movew  %2,%-; lsrl #2,%2 ; jeq 6f\n\t"
+               "lsrl   #1,%2 ; jcc 3f ; movel %1@+,%0@+\n\t"
+            "3: lsrl   #1,%2 ; jcc 4f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t"
+            "4: subql  #1,%2 ; jcs 6f\n\t"
+            "5: movel  %1@+,%0@+;movel %1@+,%0@+\n\t"
+               "movel  %1@+,%0@+;movel %1@+,%0@+\n\t"
+               "dbra   %2,5b ; clrw %2; subql #1,%2; jcc 5b\n\t"
+            "6: movew  %+,%2; btst #1,%2 ; jeq 7f ; movew %1@+,%0@+\n\t"
+            "7:              ; btst #0,%2 ; jeq 8f ; moveb %1@+,%0@+\n\t"
+            "8:"
+               : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
+               : "0" (d), "1" (s), "2" (count)
+        );
+      }
+   } else {
+      if (count < 16) {
+         __asm__ __volatile__(
+               "lsrl   #1,%2 ; jcc 1f ; moveb %1@-,%0@-\n\t"
+            "1: lsrl   #1,%2 ; jcc 1f ; movew %1@-,%0@-\n\t"
+            "1: lsrl   #1,%2 ; jcc 1f ; movel %1@-,%0@-\n\t"
+            "1: lsrl   #1,%2 ; jcc 1f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t"
+            "1:"
+               : "=a" (d), "=a" (s), "=d" (count)
+               : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
+        );
+      } else {
+         long tmp;
+         __asm__ __volatile__(
+               "movel %0,%3\n\t"
+               "lsrl   #1,%3 ; jcc 1f ; moveb %1@-,%0@- ; subqw #1,%2\n\t"
+               "lsrl   #1,%3 ; jcs 2f\n\t"  /* %0 increased=>bit 2 switched*/
+               "movew  %1@-,%0@-  ; subqw  #2,%2 ; jra 2f\n\t"
+            "1: lsrl   #1,%3 ; jcc 2f\n\t"
+               "movew  %1@-,%0@-  ; subqw  #2,%2\n\t"
+            "2: movew %2,%-; lsrl #2,%2 ; jeq 6f\n\t"
+               "lsrl   #1,%2 ; jcc 3f ; movel %1@-,%0@-\n\t"
+            "3: lsrl   #1,%2 ; jcc 4f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t"
+            "4: subql  #1,%2 ; jcs 6f\n\t"
+            "5: movel %1@-,%0@-;movel %1@-,%0@-\n\t"
+               "movel %1@-,%0@-;movel %1@-,%0@-\n\t"
+               "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5b\n\t"
+            "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@-,%0@-\n\t"
+            "7:              ; btst #0,%2 ; jeq 8f ; moveb %1@-,%0@-\n\t"
+            "8:"
+               : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
+               : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
+        );
+      }
+   }
+
+   return(0);
+}
+
+
+/* ++andreas: Simple and fast version of memmove, assumes size is
+   divisible by 16, suitable for moving the whole screen bitplane */
+static __inline__ void fast_memmove(char *dst, char *src, size_t size)
+{
+  if (!size)
+    return;
+  if (dst < src)
+    __asm__ __volatile__
+      ("1:"
+       "  moveml %0@+,%/d0/%/d1/%/a0/%/a1\n"
+       "  moveml %/d0/%/d1/%/a0/%/a1,%1@\n"
+       "  addql #8,%1; addql #8,%1\n"
+       "  dbra %2,1b\n"
+       "  clrw %2; subql #1,%2\n"
+       "  jcc 1b"
+       : "=a" (src), "=a" (dst), "=d" (size)
+       : "0" (src), "1" (dst), "2" (size / 16 - 1)
+       : "d0", "d1", "a0", "a1", "memory");
+  else
+    __asm__ __volatile__
+      ("1:"
+       "  subql #8,%0; subql #8,%0\n"
+       "  moveml %0@,%/d0/%/d1/%/a0/%/a1\n"
+       "  moveml %/d0/%/d1/%/a0/%/a1,%1@-\n"
+       "  dbra %2,1b\n"
+       "  clrw %2; subql #1,%2\n"
+       "  jcc 1b"
+       : "=a" (src), "=a" (dst), "=d" (size)
+       : "0" (src + size), "1" (dst + size), "2" (size / 16 - 1)
+       : "d0", "d1", "a0", "a1", "memory");
+}
+
+
+/* Sets the bytes in the visible column at d, height h, to the value
+ * val for a 4 plane screen. The the bis of the color in 'color' are
+ * moved (8 times) to the respective bytes. This means:
+ *
+ * for(h times; d += bpr)
+ *   *d     = (color & 1) ? 0xff : 0;
+ *   *(d+2) = (color & 2) ? 0xff : 0;
+ *   *(d+4) = (color & 4) ? 0xff : 0;
+ *   *(d+6) = (color & 8) ? 0xff : 0;
+ */
+
+static __inline__ void memclear_4p_col(void *d, size_t h, u_long val, int bpr)
+{
+	__asm__ __volatile__
+		("1: movepl %4,%0@(0)\n\t"
+		  "addal  %5,%0\n\t"
+		  "dbra	  %1,1b"
+		  : "=a" (d), "=d" (h)
+		  : "0" (d), "1" (h - 1), "d" (val), "r" (bpr)
+		);
+}
+
+/* Sets a 4 plane region from 'd', length 'count' bytes, to the color
+ * in val1/val2. 'd' has to be an even address and count must be divisible
+ * by 8, because only whole words and all planes are accessed. I.e.:
+ *
+ * for(count/8 times)
+ *   *d     = *(d+1) = (color & 1) ? 0xff : 0;
+ *   *(d+2) = *(d+3) = (color & 2) ? 0xff : 0;
+ *   *(d+4) = *(d+5) = (color & 4) ? 0xff : 0;
+ *   *(d+6) = *(d+7) = (color & 8) ? 0xff : 0;
+ */
+
+static __inline__ void memset_even_4p(void *d, size_t count, u_long val1,
+                                      u_long val2)
+{
+  u_long *dd = d;
+
+  count /= 8;
+  while (count--)
+    {
+      *dd++ = val1;
+      *dd++ = val2;
+    }
+}
+
+/* Copies a 4 plane column from 's', height 'h', to 'd'. */
+
+static __inline__ void memmove_4p_col (void *d, void *s, int h, int bpr)
+{
+  u_char *dd = d, *ss = s;
+
+  while (h--)
+    {
+      dd[0] = ss[0];
+      dd[2] = ss[2];
+      dd[4] = ss[4];
+      dd[6] = ss[6];
+      dd += bpr;
+      ss += bpr;
+    }
+}
+
+
+/* This expands a 4 bit color into a long for movepl (4 plane) operations. */
+
+static __inline__ u_long expand4l(u_char c)
+{
+	u_long	rv;
+
+	__asm__ __volatile__
+		("lsrb	 #1,%2\n\t"
+		  "scs	 %0\n\t"
+		  "lsll	 #8,%0\n\t"
+		  "lsrb	 #1,%2\n\t"
+		  "scs	 %0\n\t"
+		  "lsll	 #8,%0\n\t"
+		  "lsrb	 #1,%2\n\t"
+		  "scs	 %0\n\t"
+		  "lsll	 #8,%0\n\t"
+		  "lsrb	 #1,%2\n\t"
+		  "scs	 %0\n\t"
+		  : "=&d" (rv), "=d" (c)
+		  : "1" (c)
+		);
+	return(rv);
+}
+
+/* This expands a 4 bit color into two longs for two movel operations
+ * (4 planes).
+ */
+
+static __inline__ void expand4dl(u_char c, u_long *ret1, u_long *ret2)
+{
+	u_long	rv1, rv2;
+
+	__asm__ __volatile__
+		("lsrb	 #1,%3\n\t"
+		  "scs	 %0\n\t"
+		  "extw	 %0\n\t"
+		  "swap	 %0\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %0\n\t"
+		  "extw	 %0\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %1\n\t"
+		  "extw	 %1\n\t"
+		  "swap	 %1\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs   %1\n\t"
+		  "extw	 %1"
+		  : "=&d" (rv1), "=&d" (rv2), "=d" (c)
+		  : "2" (c)
+		);
+	*ret1 = rv1;
+	*ret2 = rv2;
+}
+
+
+/* This duplicates a byte 4 times into a long. */
+
+static __inline__ u_long dup4l(u_char c)
+{
+	ushort	tmp;
+	ulong	rv;
+
+	__asm__ __volatile__
+		("moveb  %2,%0\n\t"
+		  "lslw   #8,%0\n\t"
+		  "moveb  %2,%0\n\t"
+		  "movew  %0,%1\n\t"
+		  "swap   %0\n\t"
+		  "movew  %1,%0"
+		  : "=&d" (rv), "=d" (tmp)
+		  : "d" (c)
+		);
+
+	return(rv);
+}
+
+
+/* Sets the bytes in the visible column at d, height h, to the value
+ * val1,val2 for a 8 plane screen. The the bis of the color in 'color' are
+ * moved (8 times) to the respective bytes. This means:
+ *
+ * for(h times; d += bpr)
+ *   *d      = (color & 1) ? 0xff : 0;
+ *   *(d+2)  = (color & 2) ? 0xff : 0;
+ *   *(d+4)  = (color & 4) ? 0xff : 0;
+ *   *(d+6)  = (color & 8) ? 0xff : 0;
+ *   *(d+8)  = (color & 16) ? 0xff : 0;
+ *   *(d+10) = (color & 32) ? 0xff : 0;
+ *   *(d+12) = (color & 64) ? 0xff : 0;
+ *   *(d+14) = (color & 128) ? 0xff : 0;
+ */
+
+static __inline__ void memclear_8p_col(void *d, size_t h, u_long val1,
+                                       u_long val2, int bpr)
+{
+	__asm__ __volatile__
+		("1: movepl %4,%0@(0)\n\t"
+	      "movepl %5,%0@(8)\n\t"
+		  "addal  %6,%0\n\t"
+		  "dbra	  %1,1b"
+		  : "=a" (d), "=d" (h)
+		  : "0" (d), "1" (h - 1), "d" (val1), "d" (val2), "r" (bpr)
+		);
+}
+
+/* Sets a 8 plane region from 'd', length 'count' bytes, to the color
+ * val1..val4. 'd' has to be an even address and count must be divisible
+ * by 16, because only whole words and all planes are accessed. I.e.:
+ *
+ * for(count/16 times)
+ *   *d      = *(d+1)  = (color & 1) ? 0xff : 0;
+ *   *(d+2)  = *(d+3)  = (color & 2) ? 0xff : 0;
+ *   *(d+4)  = *(d+5)  = (color & 4) ? 0xff : 0;
+ *   *(d+6)  = *(d+7)  = (color & 8) ? 0xff : 0;
+ *   *(d+8)  = *(d+9)  = (color & 16) ? 0xff : 0;
+ *   *(d+10) = *(d+11) = (color & 32) ? 0xff : 0;
+ *   *(d+12) = *(d+13) = (color & 64) ? 0xff : 0;
+ *   *(d+14) = *(d+15) = (color & 128) ? 0xff : 0;
+ */
+
+static __inline__ void memset_even_8p(void *d, size_t count, u_long val1,
+                                      u_long val2, u_long val3, u_long val4)
+{
+  u_long *dd = d;
+
+  count /= 16;
+  while (count--)
+    {
+      *dd++ = val1;
+      *dd++ = val2;
+      *dd++ = val3;
+      *dd++ = val4;
+    }
+}
+
+/* Copies a 8 plane column from 's', height 'h', to 'd'. */
+
+static __inline__ void memmove_8p_col (void *d, void *s, int h, int bpr)
+{
+  u_char *dd = d, *ss = s;
+
+  while (h--)
+    {
+      dd[0] = ss[0];
+      dd[2] = ss[2];
+      dd[4] = ss[4];
+      dd[6] = ss[6];
+      dd[8] = ss[8];
+      dd[10] = ss[10];
+      dd[12] = ss[12];
+      dd[14] = ss[14];
+      dd += bpr;
+      ss += bpr;
+    }
+}
+
+
+/* This expands a 8 bit color into two longs for two movepl (8 plane)
+ * operations.
+ */
+
+static __inline__ void expand8dl(u_char c, u_long *ret1, u_long *ret2)
+{
+	u_long	rv1, rv2;
+
+	__asm__ __volatile__
+		("lsrb	 #1,%3\n\t"
+		  "scs	 %0\n\t"
+		  "lsll	 #8,%0\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %0\n\t"
+		  "lsll	 #8,%0\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %0\n\t"
+		  "lsll	 #8,%0\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %0\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %1\n\t"
+		  "lsll	 #8,%1\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %1\n\t"
+		  "lsll	 #8,%1\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %1\n\t"
+		  "lsll	 #8,%1\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %1"
+		  : "=&d" (rv1), "=&d" (rv2),"=d" (c)
+		  : "2" (c)
+		);
+
+	*ret1 = rv1;
+	*ret2 = rv2;
+}
+
+/* This expands a 8 bit color into four longs for four movel operations
+ * (8 planes).
+ */
+
+/* ++andreas: use macro to avoid taking address of return values */
+#define expand8ql(c, rv1, rv2, rv3, rv4) \
+do {	u_char tmp = c;						\
+	__asm__ __volatile__					\
+		("lsrb	 #1,%5\n\t"				\
+		  "scs	 %0\n\t"				\
+		  "extw	 %0\n\t"				\
+		  "swap	 %0\n\t"				\
+		  "lsrb	 #1,%5\n\t"				\
+		  "scs	 %0\n\t"				\
+		  "extw	 %0\n\t"				\
+		  "lsrb	 #1,%5\n\t"				\
+		  "scs	 %1\n\t"				\
+		  "extw	 %1\n\t"				\
+		  "swap	 %1\n\t"				\
+		  "lsrb	 #1,%5\n\t"				\
+		  "scs   %1\n\t"				\
+		  "extw	 %1\n\t"				\
+		  "lsrb	 #1,%5\n\t"				\
+		  "scs	 %2\n\t"				\
+		  "extw	 %2\n\t"				\
+		  "swap	 %2\n\t"				\
+		  "lsrb	 #1,%5\n\t"				\
+		  "scs	 %2\n\t"				\
+		  "extw	 %2\n\t"				\
+		  "lsrb	 #1,%5\n\t"				\
+		  "scs	 %3\n\t"				\
+		  "extw	 %3\n\t"				\
+		  "swap	 %3\n\t"				\
+		  "lsrb	 #1,%5\n\t"				\
+		  "scs   %3\n\t"				\
+		  "extw	 %3"					\
+		  : "=&d" (rv1), "=&d" (rv2), "=&d" (rv3),	\
+		    "=&d" (rv4), "=d" (tmp)			\
+		  : "4" (tmp)					\
+		);						\
+} while (0)
+
+
+/* Sets the bytes in the visible column at d, height h, to the value
+ * val for a 2 plane screen. The the bis of the color in 'color' are
+ * moved (8 times) to the respective bytes. This means:
+ *
+ * for(h times; d += bpr)
+ *   *d     = (color & 1) ? 0xff : 0;
+ *   *(d+2) = (color & 2) ? 0xff : 0;
+ */
+
+static __inline__ void memclear_2p_col(void *d, size_t h, u_short val, int bpr)
+{
+	__asm__ __volatile__
+		("1: movepw %4,%0@(0)\n\t"
+		  "addal  %5,%0\n\t"
+		  "dbra	  %1,1b"
+		  : "=a" (d), "=d" (h)
+		  : "0" (d), "1" (h - 1), "d" (val), "r" (bpr)
+		);
+}
+
+/* Sets a 2 plane region from 'd', length 'count' bytes, to the color
+ * in val1. 'd' has to be an even address and count must be divisible
+ * by 8, because only whole words and all planes are accessed. I.e.:
+ *
+ * for(count/4 times)
+ *   *d     = *(d+1) = (color & 1) ? 0xff : 0;
+ *   *(d+2) = *(d+3) = (color & 2) ? 0xff : 0;
+ */
+
+static __inline__ void memset_even_2p(void *d, size_t count, u_long val)
+{
+  u_long *dd = d;
+
+  count /= 4;
+  while (count--)
+    *dd++ = val;
+}
+
+/* Copies a 2 plane column from 's', height 'h', to 'd'. */
+
+static __inline__ void memmove_2p_col (void *d, void *s, int h, int bpr)
+{
+  u_char *dd = d, *ss = s;
+
+  while (h--)
+    {
+      dd[0] = ss[0];
+      dd[2] = ss[2];
+      dd += bpr;
+      ss += bpr;
+    }
+}
+
+
+/* This expands a 2 bit color into a short for movepw (2 plane) operations. */
+
+static __inline__ u_short expand2w(u_char c)
+{
+	u_short	rv;
+
+	__asm__ __volatile__
+		("lsrb	 #1,%2\n\t"
+		  "scs	 %0\n\t"
+		  "lsll	 #8,%0\n\t"
+		  "lsrb	 #1,%2\n\t"
+		  "scs	 %0\n\t"
+		  : "=&d" (rv), "=d" (c)
+		  : "1" (c)
+		);
+	return(rv);
+}
+
+/* This expands a 2 bit color into one long for a movel operation
+ * (2 planes).
+ */
+
+static __inline__ u_long expand2l(u_char c)
+{
+	u_long	rv;
+
+	__asm__ __volatile__
+		("lsrb	 #1,%2\n\t"
+		  "scs	 %0\n\t"
+		  "extw	 %0\n\t"
+		  "swap	 %0\n\t"
+		  "lsrb	 #1,%2\n\t"
+		  "scs	 %0\n\t"
+		  "extw	 %0\n\t"
+		  : "=&d" (rv), "=d" (c)
+		  : "1" (c)
+		);
+
+	return rv;
+}
+
+
+/* This duplicates a byte 2 times into a short. */
+
+static __inline__ u_short dup2w(u_char c)
+{
+    ushort  rv;
+
+    __asm__ __volatile__
+        ( "moveb  %1,%0\n\t"
+          "lslw   #8,%0\n\t"
+          "moveb  %1,%0\n\t"
+          : "=&d" (rv)
+          : "d" (c)
+        );
+
+    return( rv );
+}
+
+
+/* ====================================================================== */
+
+/* fbcon_XXX routines - interface used by the world
+ *
+ * This system is now divided into two levels because of complications
+ * caused by hardware scrolling. Top level functions:
+ *
+ *    fbcon_bmove(), fbcon_clear(), fbcon_putc()
+ *
+ * handles y values in range [0, scr_height-1] that correspond to real
+ * screen positions. y_wrap shift means that first line of bitmap may be
+ * anywhere on this display. These functions convert lineoffsets to
+ * bitmap offsets and deal with the wrap-around case by splitting blits.
+ *
+ *    fbcon_bmove_physical_8()   -- These functions fast implementations
+ *    fbcon_clear_physical_8()   -- of original fbcon_XXX fns.
+ *    fbcon_putc_physical_8()    -- (fontwidth != 8) may be added later
+ *
+ * WARNING:
+ *
+ * At the moment fbcon_putc() cannot blit across vertical wrap boundary
+ * Implies should only really hardware scroll in rows. Only reason for
+ * restriction is simplicity & efficiency at the moment.
+ */
+
+static __inline__ int real_y(struct display *p, int y)
+{
+   int rows = p->vrows;
+
+   y += p->yscroll;
+   return(y < rows ? y : y-rows);
+}
+
+
+static int fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
+                       int width)
+{
+   int unit = conp->vc_num;
+   struct display *p = &disp[unit];
+   u_int y_break;
+
+   if (!p->can_soft_blank && console_blanked)
+      return(0);
+
+   if ((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&
+       (sx <= p->cursor_x) && (p->cursor_x < sx+width))
+      CURSOR_UNDRAWN();
+
+   /* Split blits that cross physical y_wrap boundary */
+
+   y_break = p->vrows-p->yscroll;
+   if (sy < y_break && sy+height-1 >= y_break) {
+      u_int b = y_break-sy;
+      p->dispsw->clear(conp, p, real_y(p, sy), sx, b, width);
+      p->dispsw->clear(conp, p, real_y(p, sy+b), sx, height-b, width);
+   } else
+      p->dispsw->clear(conp, p, real_y(p, sy), sx, height, width);
+
+   return(0);
+}
+
+
+static int fbcon_putc(struct vc_data *conp, int c, int y, int x)
+{
+   int unit = conp->vc_num;
+   struct display *p = &disp[unit];
+
+   if (!p->can_soft_blank && console_blanked)
+      return(0);
+
+   if ((p->cursor_x == x) && (p->cursor_y == y))
+       CURSOR_UNDRAWN();
+
+   p->dispsw->putc(conp, p, c, real_y(p, y), x);
+
+   return(0);
+}
+
+
+static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int y,
+                       int x)
+{
+   int unit = conp->vc_num;
+   struct display *p = &disp[unit];
+
+   if (!p->can_soft_blank && console_blanked)
+      return(0);
+
+   if ((p->cursor_y == y) && (x <= p->cursor_x) && (p->cursor_x < x+count))
+      CURSOR_UNDRAWN();
+
+   p->dispsw->putcs(conp, p, s, count, real_y(p, y), x);
+
+   return(0);
+}
+
+
+static int fbcon_cursor(struct vc_data *conp, int mode)
+{
+   int unit = conp->vc_num;
+   struct display *p = &disp[unit];
+
+   if (CURSOR_UNDRAWN ())
+      p->dispsw->rev_char(p, p->cursor_x, real_y(p, p->cursor_y));
+   p->cursor_x = conp->vc_x;
+   p->cursor_y = conp->vc_y;
+
+   switch (mode) {
+      case CM_ERASE:
+         cursor_on = 0;
+         break;
+
+      case CM_MOVE:
+      case CM_DRAW:
+         vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+         cursor_on = 1;
+         break;
+   }
+
+   return(0);
+}
+
+
+static void fbcon_vbl_handler(int irq, struct pt_regs *fp, void *dummy)
+{
+   struct display *p;
+
+   if (!cursor_on)
+      return;
+
+   if (vbl_cursor_cnt && --vbl_cursor_cnt == 0) {
+      /* Here no check is possible for console changing. The console
+       * switching code should set vbl_cursor_cnt to an appropriate value.
+       */
+      p = &disp[fg_console];
+      p->dispsw->rev_char(p, p->cursor_x, real_y(p, p->cursor_y));
+      cursor_drawn ^= 1;
+      vbl_cursor_cnt = cursor_blink_rate;
+   }
+}
+
+
+static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
+{
+   int unit = conp->vc_num;
+   struct display *p = &disp[unit];
+
+   if (!p->can_soft_blank && console_blanked)
+      return(0);
+
+   fbcon_cursor(conp, CM_ERASE);
+
+   /*
+    * ++Geert: Only use ywrap/ypan if the console is in text mode
+    */
+
+   switch (dir) {
+      case SM_UP:
+         if (t == 0 && b == conp->vc_rows &&
+             vt_cons[unit]->vc_mode == KD_TEXT) {
+            if (count > conp->vc_rows)             /* Maximum realistic size */
+               count = conp->vc_rows;
+            switch (p->scrollmode) {
+               case SCROLL_YWRAP:
+                  p->yscroll += count;
+                  if (p->yscroll >= p->vrows) /* Deal with wrap */
+                     p->yscroll -= p->vrows;
+                  p->var.xoffset = 0;
+                  p->var.yoffset = p->yscroll*p->fontheight;
+                  p->var.vmode |= FB_VMODE_YWRAP;
+                  fb_info->updatevar(unit);
+                  break;
+
+               case SCROLL_YPAN:
+                  p->yscroll += count;
+                  if (p->yscroll+conp->vc_rows > p->vrows) {
+                     p->dispsw->bmove(p, p->yscroll, 0, 0, 0, b-count,
+                                      conp->vc_cols);
+                     p->yscroll = 0;
+                  }
+                  p->var.xoffset = 0;
+                  p->var.yoffset = p->yscroll*p->fontheight;
+                  p->var.vmode &= ~FB_VMODE_YWRAP;
+                  fb_info->updatevar(unit);
+                  break;
+
+               case SCROLL_YMOVE:
+                  p->dispsw->bmove(p, count, 0, 0, 0, b-count, conp->vc_cols);
+                  break;
+            }
+         } else
+            fbcon_bmove(conp, t+count, 0, t, 0, b-t-count, conp->vc_cols);
+         fbcon_clear(conp, b-count, 0, count, conp->vc_cols);
+         break;
+
+      case SM_DOWN:
+         if (t == 0 && b == conp->vc_rows &&
+             vt_cons[unit]->vc_mode == KD_TEXT) {
+            if (count > conp->vc_rows)             /* Maximum realistic size */
+               count = conp->vc_rows;
+            switch (p->scrollmode) {
+               case SCROLL_YWRAP:
+                  p->yscroll -= count;
+                  if (p->yscroll < 0)              /* Deal with wrap */
+                     p->yscroll += p->vrows;
+                  p->var.xoffset = 0;
+                  p->var.yoffset = p->yscroll*p->fontheight;
+                  p->var.vmode |= FB_VMODE_YWRAP;
+                  fb_info->updatevar(unit);
+                  break;
+
+               case SCROLL_YPAN:
+                  p->yscroll -= count;
+                  if (p->yscroll < 0) {
+                     p->yscroll = p->vrows-conp->vc_rows;
+                     p->dispsw->bmove(p, 0, 0, p->yscroll+count, 0, b-count,
+                                      conp->vc_cols);
+                  }
+                  p->var.xoffset = 0;
+                  p->var.yoffset = p->yscroll*p->fontheight;
+                  p->var.vmode &= ~FB_VMODE_YWRAP;
+                  fb_info->updatevar(unit);
+                  break;
+
+               case SCROLL_YMOVE:
+                  p->dispsw->bmove(p, 0, 0, count, 0, b-count, conp->vc_cols);
+                  break;
+            }
+         } else
+            fbcon_bmove(conp, t, 0, t+count, 0, b-t-count, conp->vc_cols);
+
+         /* Fixed bmove() should end Arno's frustration with copying?
+          * Confucius says:
+          *    Man who copies in wrong direction, end up with trashed data
+          */
+         fbcon_clear(conp, t, 0, count, conp->vc_cols);
+         break;
+
+      case SM_LEFT:
+         fbcon_bmove(conp, 0, t+count, 0, t, conp->vc_rows, b-t-count);
+         fbcon_clear(conp, 0, b-count, conp->vc_rows, count);
+         break;
+
+      case SM_RIGHT:
+         fbcon_bmove(conp, 0, t, 0, t+count, conp->vc_rows, b-t-count);
+         fbcon_clear(conp, 0, t, conp->vc_rows, count);
+         break;
+   }
+
+   return(0);
+}
+
+
+static int fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+                       int height, int width)
+{
+   int unit = conp->vc_num;
+   struct display *p = &disp[unit];
+
+   if (!p->can_soft_blank && console_blanked)
+      return(0);
+
+   if (((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&
+        (sx <= p->cursor_x) && (p->cursor_x < sx+width)) ||
+       ((dy <= p->cursor_y) && (p->cursor_y < dy+height) &&
+        (dx <= p->cursor_x) && (p->cursor_x < dx+width)))
+      fbcon_cursor(conp, CM_ERASE);
+
+   /* Split blits that cross physical y_wrap case.
+    * Pathological case involves 4 blits, better to use recursive
+    * code rather than unrolled case
+    *
+    * Recursive invocations don't need to erase the cursor over and
+    * over again, so we use fbcon_bmove_rec()
+    */
+   fbcon_bmove_rec(p, sy, sx, dy, dx, height, width, p->vrows-p->yscroll);
+
+   return(0);
+}
+
+
+static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy, int dx,
+                            int height, int width, u_int y_break)
+{
+   u_int b;
+
+   if (sy < y_break && sy+height > y_break) {
+      b = y_break-sy;
+      if (dy < sy) {       /* Avoid trashing self */
+         fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
+         fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
+      } else {
+         fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
+         fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
+      }
+      return;
+   }
+
+   if (dy < y_break && dy+height > y_break) {
+      b = y_break-dy;
+      if (dy < sy) {       /* Avoid trashing self */
+         fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
+         fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
+      } else {
+         fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
+         fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
+      }
+      return;
+   }
+   p->dispsw->bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width);
+}
+
+
+static int fbcon_switch(struct vc_data *conp)
+{
+   if (fb_info && fb_info->switch_con)
+      (*fb_info->switch_con)(conp->vc_num);
+   return(0);
+}
+
+
+static int fbcon_blank(int blank)
+{
+   struct display *p = &disp[fg_console];
+
+   fbcon_cursor(p->conp, blank ? CM_ERASE : CM_DRAW);
+
+   if (!p->can_soft_blank)
+      if (blank) {
+         if (p->visual == FB_VISUAL_MONO01)
+             mymemset(p->screen_base, p->var.xres_virtual*p->var.yres_virtual*
+                                      p->var.bits_per_pixel>>3);
+          else
+             mymemclear(p->screen_base, p->var.xres_virtual*p->var.yres_virtual*
+                                        p->var.bits_per_pixel>>3);
+         return(0);
+      } else {
+         /* Tell console.c that it has to restore the screen itself */
+         return(1);
+      }
+   (*fb_info->blank)(blank);
+   return(0);
+}
+
+
+static int fbcon_get_font(struct vc_data *conp, int *w, int *h, char *data)
+{
+	int unit = conp->vc_num;
+	struct display *p = &disp[unit];
+	int i, size, alloc;
+
+	size = (p->fontwidth+7)/8 * p->fontheight * 256;
+	alloc = (*w+7)/8 * *h * 256;
+	*w = p->fontwidth;
+	*h = p->fontheight;
+   
+	if (alloc < size)
+		/* allocation length not sufficient */
+		return( -ENAMETOOLONG );
+
+	if ((i = verify_area( VERIFY_WRITE, (void *)data, size )))
+		return i;
+
+	memcpy_tofs( data, p->fontdata, size );
+	return( 0 );
+}
+
+
+#define REFCOUNT(fd)	(((int *)(fd))[-1])
+
+static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data)
+{
+	int unit = conp->vc_num;
+	struct display *p = &disp[unit];
+	int i, size, userspace = 1, resize;
+	char *old_data = NULL, *new_data;
+
+	if (w < 0)
+		w = p->fontwidth;
+	if (h < 0)
+		h = p->fontheight;
+	
+	printk("Set_font, w=%d, h=%d, data=%s\n", w, h, data);
+	
+	if (w == 0) {
+		/* engage predefined font, name in 'data' */
+		char name[MAX_FONT_NAME+1];
+	   
+		if ((i = verify_area( VERIFY_READ, (void *)data, MAX_FONT_NAME )))
+			return i;
+		memcpy_fromfs( name, data, MAX_FONT_NAME );
+		name[sizeof(name)-1] = 0;
+		
+		if (!findsoftfont( name, &w, &h, (u_char **)&data ))
+			return( -ENOENT );
+		userspace = 0;
+	}
+	else if (w == 1) {
+		/* copy font from some other console in 'h'*/
+		struct display *op;
+
+		if (h < 0 || !vc_cons_allocated( h ))
+			return( -ENOTTY );
+		if (h == unit)
+			return( 0 ); /* nothing to do */
+		op = &disp[h];
+		if (op->fontdata == p->fontdata)
+			return( 0 ); /* already the same font... */
+
+		resize = (op->fontwidth != p->fontwidth) ||
+			     (op->fontheight != p->fontheight);
+		if (p->userfont)
+			old_data = p->fontdata;
+		p->fontdata = op->fontdata;
+		w = p->fontwidth = op->fontwidth;
+		h = p->fontheight = op->fontheight;
+		if ((p->userfont = op->userfont))
+			REFCOUNT(p->fontdata)++; /* increment usage counter */
+		goto activate;
+	}
+
+	if ((p->dispsw != &dispsw_mono) && (w != 8))
+		/* Currently only fontwidth == 8 supported */
+		return( -ENXIO );
+	if ((p->dispsw == &dispsw_mono) && (w != 8) && (w != 4))
+		return( -ENXIO );
+		
+	resize = (w != p->fontwidth) || (h != p->fontheight);
+	size = (w+7)/8 * h * 256;
+	
+	if (p->userfont)
+		old_data = p->fontdata;
+	
+	if (userspace) {
+		if ((i = verify_area( VERIFY_READ, (void *)data, size )))
+			return i;
+		if (!(new_data = kmalloc( sizeof(int)+size, GFP_USER )))
+			return( -ENOMEM );
+		new_data += sizeof(int);
+		REFCOUNT(new_data) = 1; /* usage counter */
+		memcpy_fromfs( new_data, data, size );
+		p->fontdata = new_data;
+		p->userfont = 1;
+	}
+	else {
+		p->fontdata = data;
+		p->userfont = 0;
+	}
+	p->fontwidth = w;
+	p->fontheight = h;
+
+  activate:
+	if (resize) {
+		p->var.xoffset = p->var.yoffset = p->yscroll = 0;  /* reset wrap/pan */
+		if (divides(p->ywrapstep, p->fontheight))
+			p->scrollmode = SCROLL_YWRAP;
+		else if (divides(p->ypanstep, p->fontheight) &&
+				 p->var.yres_virtual >= p->var.yres+p->fontheight)
+			p->scrollmode = SCROLL_YPAN;
+		else
+			p->scrollmode = SCROLL_YMOVE;
+
+		vc_resize_con( p->var.yres/h, p->var.xres/w, unit );
+	}
+	else if (unit == fg_console)
+		update_screen( unit );
+	
+	if (old_data) {
+		if (--REFCOUNT(old_data) == 0) {
+			kfree( old_data - sizeof(int) );
+		}
+	}
+	
+	return( 0 );
+}
+
+
+/* ====================================================================== */
+
+/*
+ *    Low Level Operations for the various display memory organizations.
+ *
+ *    Currently only the following organizations are supported here:
+ *
+ *      - Monochrome
+ *      - Color Interleaved Planes à la Amiga
+ *      - Color Normal Planes
+ *      - Color Interleaved Planes à la Atari (2, 4 and 8 planes)
+ *      - Color Packed Pixels (8 and 16 bpp)
+ *      - Cybervision Color Packed Pixels (accelerated)
+ */
+
+#ifdef CONFIG_FBCON_MONO
+
+   /*
+    *    Monochrome
+    */
+
+
+static u_char mask4[2] = {0xF0, 0x0F};
+
+static void bmove_mono(struct display *p, int sy, int sx, int dy, int dx,
+                       int height, int width)
+{
+   u_char *src, *dest;
+   u_int rows;
+
+   if (p->fontwidth == 8) {
+   if (sx == 0 && sy == 0 && width == p->next_line) {
+      src = p->screen_base;
+      dest = p->screen_base+dy*p->fontheight*width;
+      mymemmove(dest, src, height*p->fontheight*width);
+   } else if (dy <= sy) {
+      src = p->screen_base+sy*p->fontheight*p->next_line+sx;
+      dest = p->screen_base+dy*p->fontheight*p->next_line+dx;
+      for (rows = height*p->fontheight; rows--;) {
+         mymemmove(dest, src, width);
+         src += p->next_line;
+         dest += p->next_line;
+      }
+   } else {
+      src = p->screen_base+((sy+height)*p->fontheight-1)*p->next_line+sx;
+      dest = p->screen_base+((dy+height)*p->fontheight-1)*p->next_line+dx;
+      for (rows = height*p->fontheight; rows--;) {
+         mymemmove(dest, src, width);
+         src -= p->next_line;
+         dest -= p->next_line;
+      }
+   }
+   } else { /* fw == 4 */
+   if ((sx == 0) && (sy == 0) && (width == (p->next_line*2))) {
+      src = p->screen_base;
+      dest = p->screen_base+dy*p->fontheight*p->next_line;
+      mymemmove(dest, src, height*p->fontheight*p->next_line);
+   } else if ((dy <= sy) && ((width & 1) == 0) && ((sx & 1) == 0) && ((dy & 1) == 0)) {
+      src = p->screen_base+sy*p->fontheight*p->next_line+(sx>>1);
+      dest = p->screen_base+dy*p->fontheight*p->next_line+(dx>>1);
+      for (rows = height*p->fontheight; rows--;) {
+         mymemmove(dest, src, width);
+         src += p->next_line;
+         dest += p->next_line;
+      }
+   } else {
+     int x,y,ry;
+     for(x=0;x<width;x++)
+       for(y=0;y<height;y++)
+         for(ry=0;ry<p->fontheight;ry++) {
+           u_char * src = p->screen_base+((sy+y)*p->fontheight+ry)*p->next_line+((sx+x)>>1);
+           u_char * dest = p->screen_base+((dy+y)*p->fontheight+ry)*p->next_line+((dx+x)>>1);
+           int rs = (sx+x) & 1;
+           int rd = (dx+x) & 1;
+           if (rs == rd)
+           	*dest = (*dest & ~mask4[rd]) | (*src & mask4[rs]);
+           else if (rs == 0) 
+           	*dest = (*dest & ~mask4[rd]) | ((*src & mask4[rs]) >> 4);
+           else if (rs == 1) 
+           	*dest = (*dest & ~mask4[rd]) | ((*src & mask4[rs]) << 4);
+         }
+   }
+   }
+
+}
+
+
+static void clear_mono(struct vc_data *conp, struct display *p, int sy, int sx,
+                       int height, int width)
+{
+   u_char *dest;
+   u_int rows;
+
+   dest = p->screen_base+sy*p->fontheight*p->next_line+sx;
+
+   if (p->fontwidth == 8) {
+   if (sx == 0 && width == p->next_line)
+      if (attr_reverse(p,conp))
+         mymemset(dest, height*p->fontheight*width);
+      else
+         mymemclear(dest, height*p->fontheight*width);
+   else
+      for (rows = height*p->fontheight; rows--; dest += p->next_line)
+         if (attr_reverse(p,conp))
+            mymemset(dest, width);
+         else
+            mymemclear_small(dest, width);
+   } else { /* fw == 4 */
+
+     if ((sx == 0) && (width == (p->next_line*2)))
+        if (attr_reverse(p,conp))
+           mymemset(dest, height*p->fontheight*p->next_line);
+        else
+           mymemclear(dest, height*p->fontheight*p->next_line);
+     else
+     {
+     int x,y,ry;
+     for(x=sx;x<sx+width;x++)
+       for(y=sy;y<sy+height;y++)
+         for(ry=0;ry<p->fontheight;ry++)
+           *(p->screen_base+(y*p->fontheight+ry)*p->next_line+(x>>1)) &= mask4[x & 1 ^ 1];
+     }
+  }
+}
+
+
+static void putc_mono(struct vc_data *conp, struct display *p, int c, int y,
+                      int x)
+{
+   u_char *dest, *cdat;
+   u_int rows, bold, reverse, underline;
+   u_char d;
+
+   c &= 0xff;
+   
+   if (p->fontwidth == 8) {
+
+   dest = p->screen_base+y*p->fontheight*p->next_line+x;
+   cdat = p->fontdata+c*p->fontheight;
+   bold = attr_bold(p,conp);
+   reverse = attr_reverse(p,conp);
+   underline = attr_underline(p,conp);
+
+   for (rows = p->fontheight; rows--; dest += p->next_line) {
+      d = *cdat++;
+      if (underline && !rows)
+         d = 0xff;
+      else if (bold)
+         d |= d>>1;
+      if (reverse)
+         d = ~d;
+      *dest = d;
+   }
+   } else { /* fontwidth == 4 */
+   int r = x & 1;
+   dest = p->screen_base+y*p->fontheight*p->next_line+(x>>1);
+   
+   cdat = p->fontdata+c*p->fontheight;
+   bold = attr_bold(p,conp);
+   reverse = attr_reverse(p,conp);
+   underline = attr_underline(p,conp);
+
+   for (rows = p->fontheight; rows--; dest += p->next_line) {
+      d = *cdat++;
+      if (underline && !rows)
+         d = 0xff;
+      else if (bold)
+         d |= d>>1;
+      if (reverse)
+         d = ~d;
+      *dest = (*dest & ~mask4[r]) | (d & mask4[r]);
+   }
+   }
+}
+
+
+static void putcs_mono(struct vc_data *conp, struct display *p, const char *s,
+                       int count, int y, int x)
+{
+   u_char *dest, *dest0, *cdat;
+   u_int rows, bold, reverse, underline;
+   u_char c, d;
+   
+   if (p->fontwidth==8) {
+
+   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   bold = attr_bold(p,conp);
+   reverse = attr_reverse(p,conp);
+   underline = attr_underline(p,conp);
+
+   while (count--) {
+      c = *s++;
+      dest = dest0++;
+      cdat = p->fontdata+c*p->fontheight;
+      for (rows = p->fontheight; rows--; dest += p->next_line) {
+         d = *cdat++;
+         if (underline && !rows)
+            d = 0xff;
+         else if (bold)
+            d |= d>>1;
+         if (reverse)
+            d = ~d;
+         *dest = d;
+      }
+   }
+   
+   } else {	/* fontwidth == 4 */
+
+   int r = x & 1;
+   dest0 = p->screen_base+y*p->fontheight*p->next_line+(x>>1);
+   bold = attr_bold(p,conp);
+   reverse = attr_reverse(p,conp);
+   underline = attr_underline(p,conp);
+
+   while (count--) {
+      c = *s++;
+      dest = dest0;
+      cdat = p->fontdata+c*p->fontheight;
+      for (rows = p->fontheight; rows--; dest += p->next_line) {
+         d = *cdat++;
+         if (underline && !rows)
+            d = 0xff;
+         else if (bold)
+            d |= d>>1;
+         if (reverse)
+            d = ~d;
+         *dest = (*dest & ~mask4[r]) | (d & mask4[r]);
+      }
+      r ^= 1;
+      if (!r)
+        dest0++;
+   }
+   	
+   }
+}
+
+
+static void rev_char_mono(struct display *p, int x, int y)
+{
+   u_char *dest;
+   u_int rows;
+
+   if (p->fontwidth == 8) {
+     dest = p->screen_base+y*p->fontheight*p->next_line+x;
+     for (rows = p->fontheight; rows--; dest += p->next_line)
+        *dest = ~*dest;
+   } else { /* fw == 4 */
+     dest = p->screen_base+y*p->fontheight*p->next_line+(x>>1);
+     for (rows = p->fontheight; rows--; dest += p->next_line)
+        *dest ^= mask4[x&1];
+   }
+}
+
+#endif /* CONFIG_FBCON_MONO */
+
+
+/* ====================================================================== */
+
+#ifdef CONFIG_FBCON_ILBM
+
+   /*
+    *    Color Interleaved Planes
+    *
+    *    This code heavily relies on the fact that
+    *
+    *       next_line == interleave == next_plane*bits_per_pixel
+    *
+    *    But maybe it can be merged with the code for normal bitplanes without
+    *    much performance loss?
+    */
+
+static void bmove_ilbm(struct display *p, int sy, int sx, int dy, int dx,
+                       int height, int width)
+{
+   if (sx == 0 && sy == 0 && width == p->next_plane)
+      mymemmove(p->screen_base+dy*p->fontheight*p->next_line, p->screen_base,
+                height*p->fontheight*p->next_line);
+   else {
+      u_char *src, *dest;
+      u_int i;
+
+      if (dy <= sy) {
+         src = p->screen_base+sy*p->fontheight*p->next_line+sx;
+         dest = p->screen_base+dy*p->fontheight*p->next_line+dx;
+         for (i = p->var.bits_per_pixel*height*p->fontheight; i--;) {
+            mymemmove(dest, src, width);
+            src += p->next_plane;
+            dest += p->next_plane;
+         }
+      } else {
+         src = p->screen_base+(sy+height)*p->fontheight*p->next_line+sx;
+         dest = p->screen_base+(dy+height)*p->fontheight*p->next_line+dx;
+         for (i = p->var.bits_per_pixel*height*p->fontheight; i--;) {
+            src -= p->next_plane;
+            dest -= p->next_plane;
+            mymemmove(dest, src, width);
+         }
+      }
+   }
+}
+
+
+static void clear_ilbm(struct vc_data *conp, struct display *p, int sy, int sx,
+                       int height, int width)
+{
+   u_char *dest;
+   u_int i, rows;
+   int bg, bg0;
+
+   dest = p->screen_base+sy*p->fontheight*p->next_line+sx;
+
+   bg0 = attr_bgcol_ec(p,conp);
+   for (rows = height*p->fontheight; rows--;) {
+      bg = bg0;
+      for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
+         if (bg & 1)
+            mymemset(dest, width);
+         else
+            mymemclear(dest, width);
+         bg >>= 1;
+      }
+   }
+}
+
+
+static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int y,
+                      int x)
+{
+   u_char *dest, *cdat;
+   u_int rows, i;
+   u_char d;
+   int fg0, bg0, fg, bg;
+
+   c &= 0xff;
+
+   dest = p->screen_base+y*p->fontheight*p->next_line+x;
+   cdat = p->fontdata+c*p->fontheight;
+   fg0 = attr_fgcol(p,conp);
+   bg0 = attr_bgcol(p,conp);
+
+   for (rows = p->fontheight; rows--;) {
+      d = *cdat++;
+      fg = fg0;
+      bg = bg0;
+      for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
+         if (bg & 1)
+            if (fg & 1)
+               *dest = 0xff;
+            else
+               *dest = ~d;
+         else
+            if (fg & 1)
+               *dest = d;
+            else
+               *dest = 0x00;
+         bg >>= 1;
+         fg >>= 1;
+      }
+   }
+}
+
+
+/*
+ *    I split the console character loop in two parts:
+ *
+ *      - slow version: this blits one character at a time
+ *
+ *      - fast version: this blits 4 characters at a time at a longword aligned
+ *                      address, to reduce the number of expensive Chip RAM
+ *                      accesses.
+ *
+ *    Experiments on my A4000/040 revealed that this makes a console switch on a
+ *    640x400 screen with 256 colors about 3 times faster.
+ *
+ *                                                                Geert
+ */
+
+static void putcs_ilbm(struct vc_data *conp, struct display *p, const char *s,
+                       int count, int y, int x)
+{
+   u_char *dest0, *dest, *cdat1, *cdat2, *cdat3, *cdat4;
+   u_int rows, i;
+   u_char c1, c2, c3, c4;
+   u_long d;
+   int fg0, bg0, fg, bg;
+
+   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   fg0 = attr_fgcol(p,conp);
+   bg0 = attr_bgcol(p,conp);
+
+   while (count--)
+      if (x&3 || count < 3) {   /* Slow version */
+         c1 = *s++;
+         dest = dest0++;
+         x++;
+
+         cdat1 = p->fontdata+c1*p->fontheight;
+         for (rows = p->fontheight; rows--;) {
+            d = *cdat1++;
+            fg = fg0;
+            bg = bg0;
+            for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
+               if (bg & 1)
+                  if (fg & 1)
+                     *dest = 0xff;
+                  else
+                     *dest = ~d;
+               else
+                  if (fg & 1)
+                     *dest = d;
+                  else
+                     *dest = 0x00;
+               bg >>= 1;
+               fg >>= 1;
+            }
+         }
+      } else {                      /* Fast version */
+         c1 = s[0];
+         c2 = s[1];
+         c3 = s[2];
+         c4 = s[3];
+
+         dest = dest0;
+         cdat1 = p->fontdata+c1*p->fontheight;
+         cdat2 = p->fontdata+c2*p->fontheight;
+         cdat3 = p->fontdata+c3*p->fontheight;
+         cdat4 = p->fontdata+c4*p->fontheight;
+         for (rows = p->fontheight; rows--;) {
+            d = *cdat1++<<24 | *cdat2++<<16 | *cdat3++<<8 | *cdat4++;
+            fg = fg0;
+            bg = bg0;
+            for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
+               if (bg & 1)
+                  if (fg & 1)
+                     *(u_long *)dest = 0xffffffff;
+                  else
+                     *(u_long *)dest = ~d;
+               else
+                  if (fg & 1)
+                     *(u_long *)dest = d;
+                  else
+                     *(u_long *)dest = 0x00000000;
+               bg >>= 1;
+               fg >>= 1;
+            }
+         }
+         s += 4;
+         dest0 += 4;
+         x += 4;
+         count -= 3;
+      }
+}
+
+
+static void rev_char_ilbm(struct display *p, int x, int y)
+{
+   u_char *dest, *dest0;
+   u_int rows, i;
+   int mask;
+
+   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   mask = p->fgcol ^ p->bgcol;
+
+   /*
+    *    This should really obey the individual character's
+    *    background and foreground colors instead of simply
+    *    inverting.
+    */
+
+   for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
+      if (mask & 1) {
+         dest = dest0;
+         for (rows = p->fontheight; rows--; dest += p->next_line)
+            *dest = ~*dest;
+      }
+      mask >>= 1;
+   }
+}
+
+#endif /* CONFIG_FBCON_ILBM */
+
+
+/* ====================================================================== */
+
+#ifdef CONFIG_FBCON_PLANES
+
+   /*
+    *    Color Planes
+    */
+
+static void bmove_plan(struct display *p, int sy, int sx, int dy, int dx,
+                       int height, int width)
+{
+   u_char *src, *dest, *src0, *dest0;
+   u_int i, rows;
+
+   if (sx == 0 && sy == 0 && width == p->next_line) {
+      src = p->screen_base;
+      dest = p->screen_base+dy*p->fontheight*width;
+      for (i = p->var.bits_per_pixel; i--;) {
+         mymemmove(dest, src, height*p->fontheight*width);
+         src += p->next_plane;
+         dest += p->next_plane;
+      }
+   } else if (dy <= sy) {
+      src0 = p->screen_base+sy*p->fontheight*p->next_line+sx;
+      dest0 = p->screen_base+dy*p->fontheight*p->next_line+dx;
+      for (i = p->var.bits_per_pixel; i--;) {
+         src = src0;
+         dest = dest0;
+         for (rows = height*p->fontheight; rows--;) {
+            mymemmove(dest, src, width);
+            src += p->next_line;
+            dest += p->next_line;
+         }
+         src0 += p->next_plane;
+         dest0 += p->next_plane;
+      }
+   } else {
+      src0 = p->screen_base+(sy+height)*p->fontheight*p->next_line+sx;
+      dest0 = p->screen_base+(dy+height)*p->fontheight*p->next_line+dx;
+      for (i = p->var.bits_per_pixel; i--;) {
+         src = src0;
+         dest = dest0;
+         for (rows = height*p->fontheight; rows--;) {
+            src -= p->next_line;
+            dest -= p->next_line;
+            mymemmove(dest, src, width);
+         }
+         src0 += p->next_plane;
+         dest0 += p->next_plane;
+      }
+   }
+}
+
+
+static void clear_plan(struct vc_data *conp, struct display *p, int sy, int sx,
+                       int height, int width)
+{
+   u_char *dest, *dest0;
+   u_int i, rows;
+   int bg;
+
+   dest0 = p->screen_base+sy*p->fontheight*p->next_line+sx;
+
+   bg = attr_bgcol_ec(p,conp);
+   for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
+      dest = dest0;
+      for (rows = height*p->fontheight; rows--; dest += p->next_line)
+         if (bg & 1)
+            mymemset(dest, width);
+         else
+            mymemclear(dest, width);
+      bg >>= 1;
+   }
+}
+
+
+static void putc_plan(struct vc_data *conp, struct display *p, int c, int y,
+                      int x)
+{
+   u_char *dest, *dest0, *cdat, *cdat0;
+   u_int rows, i;
+   u_char d;
+   int fg, bg;
+
+   c &= 0xff;
+
+   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   cdat0 = p->fontdata+c*p->fontheight;
+   fg = attr_fgcol(p,conp);
+   bg = attr_bgcol(p,conp);
+
+   for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
+      dest = dest0;
+      cdat = cdat0;
+      for (rows = p->fontheight; rows--; dest += p->next_line) {
+         d = *cdat++;
+         if (bg & 1)
+            if (fg & 1)
+               *dest = 0xff;
+            else
+               *dest = ~d;
+         else
+            if (fg & 1)
+               *dest = d;
+            else
+               *dest = 0x00;
+      }
+      bg >>= 1;
+      fg >>= 1;
+   }
+}
+
+
+/*
+ *    I split the console character loop in two parts
+ *    (cfr. fbcon_putcs_ilbm())
+ */
+
+static void putcs_plan(struct vc_data *conp, struct display *p, const char *s,
+                       int count, int y, int x)
+{
+   u_char *dest, *dest0, *dest1;
+   u_char *cdat1, *cdat2, *cdat3, *cdat4, *cdat10, *cdat20, *cdat30, *cdat40;
+   u_int rows, i;
+   u_char c1, c2, c3, c4;
+   u_long d;
+   int fg0, bg0, fg, bg;
+
+   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   fg0 = attr_fgcol(p,conp);
+   bg0 = attr_bgcol(p,conp);
+
+   while (count--)
+      if (x&3 || count < 3) {   /* Slow version */
+         c1 = *s++;
+         dest1 = dest0++;
+         x++;
+
+         cdat10 = p->fontdata+c1*p->fontheight;
+         fg = fg0;
+         bg = bg0;
+
+         for (i = p->var.bits_per_pixel; i--; dest1 += p->next_plane) {
+            dest = dest1;
+            cdat1 = cdat10;
+            for (rows = p->fontheight; rows--; dest += p->next_line) {
+               d = *cdat1++;
+               if (bg & 1)
+                  if (fg & 1)
+                     *dest = 0xff;
+                  else
+                     *dest = ~d;
+               else
+                  if (fg & 1)
+                     *dest = d;
+                  else
+                     *dest = 0x00;
+            }
+            bg >>= 1;
+            fg >>= 1;
+         }
+      } else {                      /* Fast version */
+         c1 = s[0];
+         c2 = s[1];
+         c3 = s[2];
+         c4 = s[3];
+
+         dest1 = dest0;
+         cdat10 = p->fontdata+c1*p->fontheight;
+         cdat20 = p->fontdata+c2*p->fontheight;
+         cdat30 = p->fontdata+c3*p->fontheight;
+         cdat40 = p->fontdata+c4*p->fontheight;
+         fg = fg0;
+         bg = bg0;
+
+         for (i = p->var.bits_per_pixel; i--; dest1 += p->next_plane) {
+            dest = dest1;
+            cdat1 = cdat10;
+            cdat2 = cdat20;
+            cdat3 = cdat30;
+            cdat4 = cdat40;
+            for (rows = p->fontheight; rows--; dest += p->next_line) {
+               d = *cdat1++<<24 | *cdat2++<<16 | *cdat3++<<8 | *cdat4++;
+               if (bg & 1)
+                  if (fg & 1)
+                     *(u_long *)dest = 0xffffffff;
+                  else
+                     *(u_long *)dest = ~d;
+               else
+                  if (fg & 1)
+                     *(u_long *)dest = d;
+                  else
+                     *(u_long *)dest = 0x00000000;
+            }
+            bg >>= 1;
+            fg >>= 1;
+         }
+         s += 4;
+         dest0 += 4;
+         x += 4;
+         count -= 3;
+      }
+}
+
+
+static void rev_char_plan(struct display *p, int x, int y)
+{
+   u_char *dest, *dest0;
+   u_int rows, i;
+   int mask;
+
+   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   mask = p->fgcol ^ p->bgcol;
+
+   /*
+    *    This should really obey the individual character's
+    *    background and foreground colors instead of simply
+    *    inverting.
+    */
+
+   for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
+      if (mask & 1) {
+         dest = dest0;
+         for (rows = p->fontheight; rows--; dest += p->next_line)
+            *dest = ~*dest;
+      }
+      mask >>= 1;
+   }
+}
+
+#endif /* CONFIG_FBCON_PLANES */
+
+
+/* ====================================================================== */
+
+#ifdef CONFIG_FBCON_2PLANE
+
+   /*
+    *    2 Planes (2-bytes interleave)
+    */
+
+/* Increment/decrement 2 plane addresses */
+
+#define	INC_2P(p)	do { if (!((long)(++(p)) & 1)) (p) += 2; } while(0)
+#define	DEC_2P(p)	do { if ((long)(--(p)) & 1) (p) -= 2; } while(0)
+
+/* Convert a standard 4 bit color to our 2 bit color assignment:
+ * If at least two RGB channels are active, the low bit is turned on;
+ * The intensity bit (b3) is shifted into b1.
+ */
+
+#define	COLOR_2P(c)	(((c & 7) >= 3 && (c & 7) != 4) | (c & 8) >> 2)
+
+
+static void bmove_2_plane(struct display *p, int sy, int sx, int dy, int dx,
+                          int height, int width)
+{
+	/* bmove() has to distinguish two major cases: If both, source and
+	 * destination, start at even addresses or both are at odd
+	 * addresses, just the first odd and last even column (if present)
+	 * require special treatment (memmove_col()). The rest between
+	 * then can be copied by normal operations, because all adjacent
+	 * bytes are affected and are to be stored in the same order.
+	 *   The pathological case is when the move should go from an odd
+	 * address to an even or vice versa. Since the bytes in the plane
+	 * words must be assembled in new order, it seems wisest to make
+	 * all movements by memmove_col().
+	 */
+
+    if (sx == 0 && dx == 0 && width == p->next_line/2) {
+		/* Special (but often used) case: Moving whole lines can be
+		 * done with memmove()
+		 */
+		mymemmove(p->screen_base + dy * p->next_line * p->fontheight,
+				   p->screen_base + sy * p->next_line * p->fontheight,
+				   p->next_line * height * p->fontheight);
+    } else {
+        int rows, cols;
+        u_char *src;
+        u_char *dst;
+        int bytes = p->next_line;
+        int linesize = bytes * p->fontheight;
+		       u_int colsize  = height * p->fontheight;
+		       u_int upwards  = (dy < sy) || (dy == sy && dx < sx);
+
+		if ((sx & 1) == (dx & 1)) {
+			/* odd->odd or even->even */
+
+			if (upwards) {
+
+				src = p->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
+
+				if (sx & 1) {
+					memmove_2p_col(dst, src, colsize, bytes);
+					src += 3;
+					dst += 3;
+					--width;
+				}
+
+				if (width > 1) {
+					for(rows = colsize; rows > 0; --rows) {
+						mymemmove(dst, src, (width>>1)*4);
+						src += bytes;
+						dst += bytes;
+					}
+				}
+
+				if (width & 1) {
+					src -= colsize * bytes;
+					dst -= colsize * bytes;
+					memmove_2p_col(dst + (width>>1)*4, src + (width>>1)*4,
+									colsize, bytes);
+				}
+			}
+			else {
+
+				if (!((sx+width-1) & 1)) {
+					src = p->screen_base + sy * linesize + ((sx+width-1)>>1)*4;
+					dst = p->screen_base + dy * linesize + ((dx+width-1)>>1)*4;
+					memmove_2p_col(dst, src, colsize, bytes);
+					--width;
+				}
+
+				src = p->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
+
+				if (width > 1) {
+					src += colsize * bytes + (sx & 1)*3;
+					dst += colsize * bytes + (sx & 1)*3;
+					for(rows = colsize; rows > 0; --rows) {
+						src -= bytes;
+						dst -= bytes;
+						mymemmove(dst, src, (width>>1)*4);
+					}
+				}
+
+				if (width & 1) {
+					memmove_2p_col(dst-3, src-3, colsize, bytes);
+				}
+
+			}
+		}
+		else {
+			/* odd->even or even->odd */
+
+			if (upwards) {
+				src = p->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
+				for(cols = width; cols > 0; --cols) {
+					memmove_2p_col(dst, src, colsize, bytes);
+					INC_2P(src);
+					INC_2P(dst);
+				}
+			}
+			else {
+				sx += width-1;
+				dx += width-1;
+				src = p->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
+				for(cols = width; cols > 0; --cols) {
+					memmove_2p_col(dst, src, colsize, bytes);
+					DEC_2P(src);
+					DEC_2P(dst);
+				}
+			}
+		}
+
+
+    }
+}
+
+
+static void clear_2_plane(struct vc_data *conp, struct display *p, int sy,
+                          int sx, int height, int width)
+{
+    ulong offset;
+    u_char *start;
+    int rows;
+    int bytes = p->next_line;
+    int lines = height * p->fontheight;
+    ulong  size;
+	u_long          cval;
+	u_short			pcval;
+
+    cval = expand2l (COLOR_2P (attr_bgcol_ec(p,conp)));
+
+    if (sx == 0 && width == bytes/2) {
+
+        offset = sy * bytes * p->fontheight;
+        size   = lines * bytes;
+		memset_even_2p(p->screen_base+offset, size, cval);
+
+    } else {
+
+        offset = (sy * bytes * p->fontheight) + (sx>>1)*4 + (sx & 1);
+		start = p->screen_base + offset;
+		pcval = expand2w(COLOR_2P(attr_bgcol_ec(p,conp)));
+
+		/* Clears are split if the region starts at an odd column or
+		 * end at an even column. These extra columns are spread
+		 * across the interleaved planes. All in between can be
+		 * cleared by normal mymemclear_small(), because both bytes of
+		 * the single plane words are affected.
+		 */
+
+		if (sx & 1) {
+			memclear_2p_col(start, lines, pcval, bytes);
+			start += 3;
+			width--;
+		}
+
+		if (width & 1) {
+			memclear_2p_col(start + (width>>1)*4, lines, pcval, bytes);
+			width--;
+		}
+
+		if (width) {
+			for(rows = lines; rows-- ; start += bytes)
+				memset_even_2p(start, width*2, cval);
+		}
+    }
+}
+
+
+static void putc_2_plane(struct vc_data *conp, struct display *p, int c, int y,
+                         int x)
+{
+   u_char   *dest;
+    u_char   *cdat;
+    int rows;
+    int bytes = p->next_line;
+	ulong			  eorx, fgx, bgx, fdx;
+
+	c &= 0xff;
+
+    dest  = p->screen_base + y * p->fontheight * bytes + (x>>1)*4 + (x & 1);
+    cdat  = p->fontdata + (c * p->fontheight);
+
+	fgx   = expand2w(COLOR_2P(attr_fgcol(p,conp)));
+	bgx   = expand2w(COLOR_2P(attr_bgcol(p,conp)));
+	eorx  = fgx ^ bgx;
+
+    for(rows = p->fontheight ; rows-- ; dest += bytes) {
+		fdx = dup2w(*cdat++);
+		__asm__ __volatile__ ("movepw %1,%0@(0)" : /* no outputs */
+							   : "a" (dest), "d" ((fdx & eorx) ^ bgx));
+	}
+}
+
+
+static void putcs_2_plane(struct vc_data *conp, struct display *p,
+                          const char *s, int count, int y, int x)
+{
+	u_char   *dest, *dest0;
+    u_char   *cdat, c;
+    int rows;
+    int bytes;
+	ulong			  eorx, fgx, bgx, fdx;
+
+    bytes = p->next_line;
+    dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*4 + (x & 1);
+	fgx   = expand2w(COLOR_2P(attr_fgcol(p,conp)));
+	bgx   = expand2w(COLOR_2P(attr_bgcol(p,conp)));
+	eorx  = fgx ^ bgx;
+
+	while (count--) {
+
+		c = *s++;
+		cdat  = p->fontdata + (c * p->fontheight);
+
+		for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+			fdx = dup2w(*cdat++);
+			__asm__ __volatile__ ("movepw %1,%0@(0)" : /* no outputs */
+								   : "a" (dest), "d" ((fdx & eorx) ^ bgx));
+		}
+		INC_2P(dest0);
+	}
+}
+
+
+static void rev_char_2_plane(struct display *p, int x, int y)
+{
+   u_char *dest;
+   int j;
+   int bytes;
+
+   dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*4 + (x & 1);
+   j = p->fontheight;
+   bytes = p->next_line;
+   while (j--)
+     {
+      /* This should really obey the individual character's
+       * background and foreground colors instead of simply
+       * inverting.
+       */
+       dest[0] = ~dest[0];
+       dest[2] = ~dest[2];
+       dest += bytes;
+     }
+}
+#endif /* CONFIG_FBCON_2PLANE */
+
+
+/* ====================================================================== */
+
+#ifdef CONFIG_FBCON_4PLANE
+
+   /*
+    *    4 Planes (2-bytes interleave)
+    */
+
+/* Increment/decrement 4 plane addresses */
+
+#define	INC_4P(p)	do { if (!((long)(++(p)) & 1)) (p) += 6; } while(0)
+#define	DEC_4P(p)	do { if ((long)(--(p)) & 1) (p) -= 6; } while(0)
+
+
+static void bmove_4_plane(struct display *p, int sy, int sx, int dy, int dx,
+                          int height, int width)
+{
+	/* bmove() has to distinguish two major cases: If both, source and
+	 * destination, start at even addresses or both are at odd
+	 * addresses, just the first odd and last even column (if present)
+	 * require special treatment (memmove_col()). The rest between
+	 * then can be copied by normal operations, because all adjacent
+	 * bytes are affected and are to be stored in the same order.
+	 *   The pathological case is when the move should go from an odd
+	 * address to an even or vice versa. Since the bytes in the plane
+	 * words must be assembled in new order, it seems wisest to make
+	 * all movements by memmove_col().
+	 */
+
+    if (sx == 0 && dx == 0 && width == p->next_line/4) {
+		/* Special (but often used) case: Moving whole lines can be
+		 * done with memmove()
+		 */
+		mymemmove(p->screen_base + dy * p->next_line * p->fontheight,
+				   p->screen_base + sy * p->next_line * p->fontheight,
+				   p->next_line * height * p->fontheight);
+    } else {
+        int rows, cols;
+        u_char *src;
+        u_char *dst;
+        int bytes = p->next_line;
+        int linesize = bytes * p->fontheight;
+		       u_int colsize  = height * p->fontheight;
+		       u_int upwards  = (dy < sy) || (dy == sy && dx < sx);
+
+		if ((sx & 1) == (dx & 1)) {
+			/* odd->odd or even->even */
+
+			if (upwards) {
+
+				src = p->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
+
+				if (sx & 1) {
+					memmove_4p_col(dst, src, colsize, bytes);
+					src += 7;
+					dst += 7;
+					--width;
+				}
+
+				if (width > 1) {
+					for(rows = colsize; rows > 0; --rows) {
+						mymemmove(dst, src, (width>>1)*8);
+						src += bytes;
+						dst += bytes;
+					}
+				}
+
+				if (width & 1) {
+					src -= colsize * bytes;
+					dst -= colsize * bytes;
+					memmove_4p_col(dst + (width>>1)*8, src + (width>>1)*8,
+									colsize, bytes);
+				}
+			}
+			else {
+
+				if (!((sx+width-1) & 1)) {
+					src = p->screen_base + sy * linesize + ((sx+width-1)>>1)*8;
+					dst = p->screen_base + dy * linesize + ((dx+width-1)>>1)*8;
+					memmove_4p_col(dst, src, colsize, bytes);
+					--width;
+				}
+
+				src = p->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
+
+				if (width > 1) {
+					src += colsize * bytes + (sx & 1)*7;
+					dst += colsize * bytes + (sx & 1)*7;
+					for(rows = colsize; rows > 0; --rows) {
+						src -= bytes;
+						dst -= bytes;
+						mymemmove(dst, src, (width>>1)*8);
+					}
+				}
+
+				if (width & 1) {
+					memmove_4p_col(dst-7, src-7, colsize, bytes);
+				}
+
+			}
+		}
+		else {
+			/* odd->even or even->odd */
+
+			if (upwards) {
+				src = p->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
+				for(cols = width; cols > 0; --cols) {
+					memmove_4p_col(dst, src, colsize, bytes);
+					INC_4P(src);
+					INC_4P(dst);
+				}
+			}
+			else {
+				sx += width-1;
+				dx += width-1;
+				src = p->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
+				for(cols = width; cols > 0; --cols) {
+					memmove_4p_col(dst, src, colsize, bytes);
+					DEC_4P(src);
+					DEC_4P(dst);
+				}
+			}
+		}
+
+
+    }
+}
+
+
+static void clear_4_plane(struct vc_data *conp, struct display *p, int sy,
+                          int sx, int height, int width)
+{
+    ulong offset;
+    u_char *start;
+    int rows;
+    int bytes = p->next_line;
+    int lines = height * p->fontheight;
+    ulong  size;
+	u_long          cval1, cval2, pcval;
+
+	expand4dl(attr_bgcol_ec(p,conp), &cval1, &cval2);
+
+    if (sx == 0 && width == bytes/4) {
+
+	offset = sy * bytes * p->fontheight;
+        size   = lines * bytes;
+		memset_even_4p(p->screen_base+offset, size, cval1, cval2);
+
+    } else {
+
+        offset = (sy * bytes * p->fontheight) + (sx>>1)*8 + (sx & 1);
+		start = p->screen_base + offset;
+		pcval = expand4l(attr_bgcol_ec(p,conp));
+
+		/* Clears are split if the region starts at an odd column or
+		 * end at an even column. These extra columns are spread
+		 * across the interleaved planes. All in between can be
+		 * cleared by normal mymemclear_small(), because both bytes of
+		 * the single plane words are affected.
+		 */
+
+		if (sx & 1) {
+			memclear_4p_col(start, lines, pcval, bytes);
+			start += 7;
+			width--;
+		}
+
+		if (width & 1) {
+			memclear_4p_col(start + (width>>1)*8, lines, pcval, bytes);
+			width--;
+		}
+
+		if (width) {
+			for(rows = lines; rows-- ; start += bytes)
+				memset_even_4p(start, width*4, cval1, cval2);
+		}
+    }
+}
+
+
+static void putc_4_plane(struct vc_data *conp, struct display *p, int c, int y,
+                         int x)
+{
+	u_char   *dest;
+    u_char   *cdat;
+    int rows;
+    int bytes = p->next_line;
+	ulong			  eorx, fgx, bgx, fdx;
+
+	c &= 0xff;
+
+    dest  = p->screen_base + y * p->fontheight * bytes + (x>>1)*8 + (x & 1);
+    cdat  = p->fontdata + (c * p->fontheight);
+
+	fgx   = expand4l(attr_fgcol(p,conp));
+	bgx   = expand4l(attr_bgcol(p,conp));
+	eorx  = fgx ^ bgx;
+
+    for(rows = p->fontheight ; rows-- ; dest += bytes) {
+		fdx = dup4l(*cdat++);
+		__asm__ __volatile__ ("movepl %1,%0@(0)" : /* no outputs */
+							   : "a" (dest), "d" ((fdx & eorx) ^ bgx));
+	}
+}
+
+
+static void putcs_4_plane(struct vc_data *conp, struct display *p,
+                          const char *s, int count, int y, int x)
+{
+	u_char   *dest, *dest0;
+    u_char   *cdat, c;
+    int rows;
+    int bytes;
+	ulong			  eorx, fgx, bgx, fdx;
+
+    bytes = p->next_line;
+    dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*8 + (x & 1);
+	fgx   = expand4l(attr_fgcol(p,conp));
+	bgx   = expand4l(attr_bgcol(p,conp));
+	eorx  = fgx ^ bgx;
+
+	while (count--) {
+
+		/* I think, unrolling the loops like in the 1 plane case isn't
+		 * practicable here, because the body is much longer for 4
+		 * planes (mostly the dup4l()). I guess, unrolling this would
+		 * need more than 256 bytes and so exceed the instruction
+		 * cache :-(
+		 */
+
+		c = *s++;
+		cdat  = p->fontdata + (c * p->fontheight);
+
+		for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+			fdx = dup4l(*cdat++);
+			__asm__ __volatile__ ("movepl %1,%0@(0)" : /* no outputs */
+								   : "a" (dest), "d" ((fdx & eorx) ^ bgx));
+		}
+		INC_4P(dest0);
+	}
+}
+
+
+static void rev_char_4_plane(struct display *p, int x, int y)
+{
+   u_char *dest;
+   int j;
+   int bytes;
+
+   dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*8 + (x & 1);
+   j = p->fontheight;
+   bytes = p->next_line;
+
+   while (j--)
+     {
+      /* This should really obey the individual character's
+       * background and foreground colors instead of simply
+       * inverting.
+       */
+       dest[0] = ~dest[0];
+       dest[2] = ~dest[2];
+       dest[4] = ~dest[4];
+       dest[6] = ~dest[6];
+       dest += bytes;
+     }
+}
+#endif /* CONFIG_FBCON_4PLANE */
+
+
+/* ====================================================================== */
+
+#ifdef CONFIG_FBCON_8PLANE
+
+   /*
+    *    8 Planes (2-bytes interleave)
+    */
+
+/* In 8 plane mode, 256 colors would be possible, but only the first
+ * 16 are used by the console code (the upper 4 bits are
+ * background/unused). For that, the following functions mask off the
+ * higher 4 bits of each color.
+ */
+
+/* Increment/decrement 8 plane addresses */
+
+#define	INC_8P(p)	do { if (!((long)(++(p)) & 1)) (p) += 14; } while(0)
+#define	DEC_8P(p)	do { if ((long)(--(p)) & 1) (p) -= 14; } while(0)
+
+
+static void bmove_8_plane(struct display *p, int sy, int sx, int dy, int dx,
+                          int height, int width)
+{
+	/* bmove() has to distinguish two major cases: If both, source and
+	 * destination, start at even addresses or both are at odd
+	 * addresses, just the first odd and last even column (if present)
+	 * require special treatment (memmove_col()). The rest between
+	 * then can be copied by normal operations, because all adjacent
+	 * bytes are affected and are to be stored in the same order.
+	 *   The pathological case is when the move should go from an odd
+	 * address to an even or vice versa. Since the bytes in the plane
+	 * words must be assembled in new order, it seems wisest to make
+	 * all movements by memmove_col().
+	 */
+
+    if (sx == 0 && dx == 0 && width == p->next_line/8) {
+		/* Special (but often used) case: Moving whole lines can be
+		 * done with memmove()
+		 */
+      fast_memmove (p->screen_base + dy * p->next_line * p->fontheight,
+		    p->screen_base + sy * p->next_line * p->fontheight,
+		    p->next_line * height * p->fontheight);
+    } else {
+        int rows, cols;
+        u_char *src;
+        u_char *dst;
+        int bytes = p->next_line;
+        int linesize = bytes * p->fontheight;
+		       u_int colsize  = height * p->fontheight;
+		       u_int upwards  = (dy < sy) || (dy == sy && dx < sx);
+
+		if ((sx & 1) == (dx & 1)) {
+			/* odd->odd or even->even */
+
+			if (upwards) {
+
+				src = p->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
+
+				if (sx & 1) {
+					memmove_8p_col(dst, src, colsize, bytes);
+					src += 15;
+					dst += 15;
+					--width;
+				}
+
+				if (width > 1) {
+					for(rows = colsize; rows > 0; --rows) {
+						fast_memmove (dst, src, (width >> 1) * 16);
+						src += bytes;
+						dst += bytes;
+					}
+				}
+
+				if (width & 1) {
+					src -= colsize * bytes;
+					dst -= colsize * bytes;
+					memmove_8p_col(dst + (width>>1)*16, src + (width>>1)*16,
+									colsize, bytes);
+				}
+			}
+			else {
+
+				if (!((sx+width-1) & 1)) {
+					src = p->screen_base + sy * linesize + ((sx+width-1)>>1)*16;
+					dst = p->screen_base + dy * linesize + ((dx+width-1)>>1)*16;
+					memmove_8p_col(dst, src, colsize, bytes);
+					--width;
+				}
+
+				src = p->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
+
+				if (width > 1) {
+					src += colsize * bytes + (sx & 1)*15;
+					dst += colsize * bytes + (sx & 1)*15;
+					for(rows = colsize; rows > 0; --rows) {
+						src -= bytes;
+						dst -= bytes;
+						fast_memmove (dst, src, (width>>1)*16);
+					}
+				}
+
+				if (width & 1) {
+					memmove_8p_col(dst-15, src-15, colsize, bytes);
+				}
+
+			}
+		}
+		else {
+			/* odd->even or even->odd */
+
+			if (upwards) {
+				src = p->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
+				for(cols = width; cols > 0; --cols) {
+					memmove_8p_col(dst, src, colsize, bytes);
+					INC_8P(src);
+					INC_8P(dst);
+				}
+			}
+			else {
+				sx += width-1;
+				dx += width-1;
+				src = p->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
+				for(cols = width; cols > 0; --cols) {
+					memmove_8p_col(dst, src, colsize, bytes);
+					DEC_8P(src);
+					DEC_8P(dst);
+				}
+			}
+		}
+
+
+    }
+}
+
+
+static void clear_8_plane(struct vc_data *conp, struct display *p, int sy,
+                          int sx, int height, int width)
+{
+    ulong offset;
+    u_char *start;
+    int rows;
+    int bytes = p->next_line;
+    int lines = height * p->fontheight;
+    ulong  size;
+	u_long          cval1, cval2, cval3, cval4, pcval1, pcval2;
+
+	expand8ql(attr_bgcol_ec(p,conp), cval1, cval2, cval3, cval4);
+
+    if (sx == 0 && width == bytes/8) {
+
+        offset = sy * bytes * p->fontheight;
+        size   = lines * bytes;
+		memset_even_8p(p->screen_base+offset, size, cval1, cval2, cval3, cval4);
+
+    } else {
+
+        offset = (sy * bytes * p->fontheight) + (sx>>1)*16 + (sx & 1);
+		start = p->screen_base + offset;
+		expand8dl(attr_bgcol_ec(p,conp), &pcval1, &pcval2);
+
+		/* Clears are split if the region starts at an odd column or
+		 * end at an even column. These extra columns are spread
+		 * across the interleaved planes. All in between can be
+		 * cleared by normal mymemclear_small(), because both bytes of
+		 * the single plane words are affected.
+		 */
+
+		if (sx & 1) {
+			memclear_8p_col(start, lines, pcval1, pcval2, bytes);
+			start += 7;
+			width--;
+		}
+
+		if (width & 1) {
+			memclear_8p_col(start + (width>>1)*16, lines, pcval1,
+							 pcval2, bytes);
+			width--;
+		}
+
+		if (width) {
+			for(rows = lines; rows-- ; start += bytes)
+				memset_even_8p(start, width*8, cval1, cval2, cval3, cval4);
+		}
+    }
+}
+
+
+static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int y,
+                         int x)
+{
+	u_char   *dest;
+    u_char   *cdat;
+    int rows;
+    int bytes = p->next_line;
+	ulong			  eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
+
+	c &= 0xff;
+
+    dest  = p->screen_base + y * p->fontheight * bytes + (x>>1)*16 + (x & 1);
+    cdat  = p->fontdata + (c * p->fontheight);
+
+	expand8dl(attr_fgcol(p,conp), &fgx1, &fgx2);
+	expand8dl(attr_bgcol(p,conp), &bgx1, &bgx2);
+	eorx1  = fgx1 ^ bgx1; eorx2  = fgx2 ^ bgx2;
+
+    for(rows = p->fontheight ; rows-- ; dest += bytes) {
+		fdx = dup4l(*cdat++);
+		__asm__ __volatile__
+			("movepl %1,%0@(0)\n\t"
+			  "movepl %2,%0@(8)"
+			  : /* no outputs */
+			  : "a" (dest), "d" ((fdx & eorx1) ^ bgx1),
+			    "d" ((fdx & eorx2) ^ bgx2)
+			);
+	}
+}
+
+
+static void putcs_8_plane(struct vc_data *conp, struct display *p,
+                          const char *s, int count, int y, int x)
+{
+	u_char   *dest, *dest0;
+    u_char   *cdat, c;
+    int rows;
+    int bytes;
+	ulong			  eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
+
+    bytes = p->next_line;
+    dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*16 + (x & 1);
+
+	expand8dl(attr_fgcol(p,conp), &fgx1, &fgx2);
+	expand8dl(attr_bgcol(p,conp), &bgx1, &bgx2);
+	eorx1  = fgx1 ^ bgx1; eorx2  = fgx2 ^ bgx2;
+
+	while (count--) {
+
+		/* I think, unrolling the loops like in the 1 plane case isn't
+		 * practicable here, because the body is much longer for 4
+		 * planes (mostly the dup4l()). I guess, unrolling this would
+		 * need more than 256 bytes and so exceed the instruction
+		 * cache :-(
+		 */
+
+		c = *s++;
+		cdat  = p->fontdata + (c * p->fontheight);
+
+		for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+			fdx = dup4l(*cdat++);
+			__asm__ __volatile__
+				("movepl %1,%0@(0)\n\t"
+				  "movepl %2,%0@(8)"
+				  : /* no outputs */
+				  : "a" (dest), "d" ((fdx & eorx1) ^ bgx1),
+				  "d" ((fdx & eorx2) ^ bgx2)
+				);
+		}
+		INC_8P(dest0);
+	}
+}
+
+
+static void rev_char_8_plane(struct display *p, int x, int y)
+{
+   u_char *dest;
+   int j;
+   int bytes;
+
+   dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*16 + (x & 1);
+   j = p->fontheight;
+   bytes = p->next_line;
+
+   while (j--)
+     {
+      /* This should really obey the individual character's
+       * background and foreground colors instead of simply
+       * inverting. For 8 plane mode, only the lower 4 bits of the
+       * color are inverted, because only that color registers have
+       * been set up.
+       */
+       dest[0] = ~dest[0];
+       dest[2] = ~dest[2];
+       dest[4] = ~dest[4];
+       dest[6] = ~dest[6];
+       dest += bytes;
+     }
+}
+#endif /* CONFIG_FBCON_8PLANE */
+
+
+/* ====================================================================== */
+
+#ifdef CONFIG_FBCON_8PACKED
+
+   /*
+    *    8 bpp Packed Pixels
+    */
+
+static u_long nibbletab_8_packed[]={
+0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
+0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
+0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
+0xffff0000,0xffff00ff,0xffffff00,0xffffffff};
+
+static void bmove_8_packed(struct display *p, int sy, int sx, int dy, int dx,
+                           int height, int width)
+{
+	int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
+	u_char *src,*dst;
+
+	if (sx == 0 && dx == 0 && width * 8 == bytes) {
+		mymemmove(p->screen_base + dy * linesize,
+			  p->screen_base + sy * linesize,
+			  height * linesize);
+	}
+	else {
+		if (dy < sy || (dy == sy && dx < sx)) {
+			src = p->screen_base + sy * linesize + sx * 8;
+			dst = p->screen_base + dy * linesize + dx * 8;
+			for (rows = height * p->fontheight ; rows-- ;) {
+				mymemmove(dst, src, width * 8);
+				src += bytes;
+				dst += bytes;
+			}
+		}
+		else {
+			src = p->screen_base + (sy+height) * linesize + sx * 8
+				- bytes;
+			dst = p->screen_base + (dy+height) * linesize + dx * 8
+				- bytes;
+			for (rows = height * p->fontheight ; rows-- ;) {
+				mymemmove(dst, src, width * 8);
+				src -= bytes;
+				dst -= bytes;
+			}
+		}
+	}
+}
+
+
+static void clear_8_packed(struct vc_data *conp, struct display *p, int sy,
+                           int sx, int height, int width)
+{
+	u_char *dest0,*dest;
+	int bytes=p->next_line,lines=height * p->fontheight, rows, i;
+	u_long bgx;
+
+	dest = p->screen_base + sy * p->fontheight * bytes + sx * 8;
+
+	bgx=attr_bgcol_ec(p,conp);
+	bgx |= (bgx << 8);
+	bgx |= (bgx << 16);
+
+	if (sx == 0 && width * 8 == bytes) {
+		for (i = 0 ; i < lines * width ; i++) {
+			((u_long *)dest)[0]=bgx;
+			((u_long *)dest)[1]=bgx;
+			dest+=8;
+		}
+	} else {
+		dest0=dest;
+		for (rows = lines; rows-- ; dest0 += bytes) {
+			dest=dest0;
+			for (i = 0 ; i < width ; i++) {
+				((u_long *)dest)[0]=bgx;
+				((u_long *)dest)[1]=bgx;
+				dest+=8;
+			}
+		}
+	}
+}
+
+
+static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int y,
+                          int x)
+{
+	u_char *dest,*cdat;
+	int bytes=p->next_line,rows;
+	ulong eorx,fgx,bgx;
+
+	c &= 0xff;
+
+	dest = p->screen_base + y * p->fontheight * bytes + x * 8;
+	cdat = p->fontdata + c * p->fontheight;
+
+	fgx=attr_fgcol(p,conp);
+	bgx=attr_bgcol(p,conp);
+	fgx |= (fgx << 8);
+	fgx |= (fgx << 16);
+	bgx |= (bgx << 8);
+	bgx |= (bgx << 16);
+	eorx = fgx ^ bgx;
+
+	for (rows = p->fontheight ; rows-- ; dest += bytes) {
+		((u_long *)dest)[0]=
+			(nibbletab_8_packed[*cdat >> 4] & eorx) ^ bgx;
+		((u_long *)dest)[1]=
+			(nibbletab_8_packed[*cdat++ & 0xf] & eorx) ^ bgx;
+	}
+}
+
+
+static void putcs_8_packed(struct vc_data *conp, struct display *p,
+                           const char *s, int count, int y, int x)
+{
+	u_char *cdat, c, *dest, *dest0;
+	int rows,bytes=p->next_line;
+	u_long eorx, fgx, bgx;
+
+	dest0 = p->screen_base + y * p->fontheight * bytes + x * 8;
+	fgx=attr_fgcol(p,conp);
+	bgx=attr_bgcol(p,conp);
+	fgx |= (fgx << 8);
+	fgx |= (fgx << 16);
+	bgx |= (bgx << 8);
+	bgx |= (bgx << 16);
+	eorx = fgx ^ bgx;
+	while (count--) {
+		c = *s++;
+		cdat = p->fontdata + c * p->fontheight;
+
+		for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+			((u_long *)dest)[0]=
+			(nibbletab_8_packed[*cdat >> 4] & eorx) ^ bgx;
+			((u_long *)dest)[1]=
+			(nibbletab_8_packed[*cdat++ & 0xf] & eorx) ^ bgx;
+		}
+		dest0+=8;
+	}
+}
+
+
+static void rev_char_8_packed(struct display *p, int x, int y)
+{
+	u_char *dest;
+	int bytes=p->next_line, rows;
+
+	dest = p->screen_base + y * p->fontheight * bytes + x * 8;
+	for (rows = p->fontheight ; rows-- ; dest += bytes) {
+		((u_long *)dest)[0] ^= 0x0f0f0f0f;
+		((u_long *)dest)[1] ^= 0x0f0f0f0f;
+	}
+}
+
+#endif /* CONFIG_FBCON_8PACKED */
+
+
+/* ====================================================================== */
+
+#ifdef CONFIG_FBCON_16PACKED
+
+   /*
+    *    16 bpp Packed Pixels
+    */
+
+u_short packed16_cmap[16];
+
+static u_long tab_16_packed[]={
+0x00000000,0x0000ffff,0xffff0000,0xffffffff};
+
+static void bmove_16_packed(struct display *p, int sy, int sx, int dy, int dx,
+                            int height, int width)
+{
+	int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
+	u_char *src,*dst;
+
+	if (sx == 0 && dx == 0 && width * 16 == bytes) {
+		mymemmove(p->screen_base + dy * linesize,
+			  p->screen_base + sy * linesize,
+			  height * linesize);
+	}
+	else {
+		if (dy < sy || (dy == sy && dx < sx)) {
+			src = p->screen_base + sy * linesize + sx * 16;
+			dst = p->screen_base + dy * linesize + dx * 16;
+			for (rows = height * p->fontheight ; rows-- ;) {
+				mymemmove(dst, src, width * 16);
+				src += bytes;
+				dst += bytes;
+			}
+		}
+		else {
+			src = p->screen_base + (sy+height) * linesize + sx * 16
+				- bytes;
+			dst = p->screen_base + (dy+height) * linesize + dx * 16
+				- bytes;
+			for (rows = height * p->fontheight ; rows-- ;) {
+				mymemmove(dst, src, width * 16);
+				src -= bytes;
+				dst -= bytes;
+			}
+		}
+	}
+}
+
+
+static void clear_16_packed(struct vc_data *conp, struct display *p, int sy,
+                            int sx, int height, int width)
+{
+	u_char *dest0,*dest;
+	int bytes=p->next_line,lines=height * p->fontheight, rows, i;
+	u_long bgx;
+
+	dest = p->screen_base + sy * p->fontheight * bytes + sx * 16;
+
+	bgx = attr_bgcol_ec(p,conp);
+	bgx = packed16_cmap[bgx];
+	bgx |= (bgx << 16);
+
+	if (sx == 0 && width * 16 == bytes) {
+		for (i = 0 ; i < lines * width ; i++) {
+			((u_long *)dest)[0]=bgx;
+			((u_long *)dest)[1]=bgx;
+			((u_long *)dest)[2]=bgx;
+			((u_long *)dest)[3]=bgx;
+			dest+=16;
+		}
+	} else {
+		dest0=dest;
+		for (rows = lines; rows-- ; dest0 += bytes) {
+			dest=dest0;
+			for (i = 0 ; i < width ; i++) {
+				((u_long *)dest)[0]=bgx;
+				((u_long *)dest)[1]=bgx;
+				((u_long *)dest)[2]=bgx;
+				((u_long *)dest)[3]=bgx;
+				dest+=16;
+			}
+		}
+	}
+}
+
+
+static void putc_16_packed(struct vc_data *conp, struct display *p, int c,
+                           int y, int x)
+{
+	u_char *dest,*cdat;
+	int bytes=p->next_line,rows;
+	ulong eorx,fgx,bgx;
+
+	c &= 0xff;
+
+	dest = p->screen_base + y * p->fontheight * bytes + x * 16;
+	cdat = p->fontdata + c * p->fontheight;
+
+	fgx = attr_fgcol(p,conp);
+	fgx = packed16_cmap[fgx];
+	bgx = attr_bgcol(p,conp);
+	bgx = packed16_cmap[bgx];
+	fgx |= (fgx << 16);
+	bgx |= (bgx << 16);
+	eorx = fgx ^ bgx;
+
+	for (rows = p->fontheight ; rows-- ; dest += bytes) {
+		((u_long *)dest)[0]=
+			(tab_16_packed[*cdat >> 6] & eorx) ^ bgx;
+		((u_long *)dest)[1]=
+			(tab_16_packed[*cdat >> 4 & 0x3] & eorx) ^ bgx;
+		((u_long *)dest)[2]=
+			(tab_16_packed[*cdat >> 2 & 0x3] & eorx) ^ bgx;
+		((u_long *)dest)[3]=
+			(tab_16_packed[*cdat++ & 0x3] & eorx) ^ bgx;
+	}
+}
+
+
+/* TODO */
+static void putcs_16_packed(struct vc_data *conp, struct display *p,
+                            const char *s, int count, int y, int x)
+{
+	u_char *cdat, c, *dest, *dest0;
+	int rows,bytes=p->next_line;
+	u_long eorx, fgx, bgx;
+
+	dest0 = p->screen_base + y * p->fontheight * bytes + x * 16;
+	fgx = attr_fgcol(p,conp);
+	fgx = packed16_cmap[fgx];
+	bgx = attr_bgcol(p,conp);
+	bgx = packed16_cmap[bgx];
+	fgx |= (fgx << 16);
+	bgx |= (bgx << 16);
+	eorx = fgx ^ bgx;
+	while (count--) {
+		c = *s++;
+		cdat = p->fontdata + c * p->fontheight;
+
+		for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+			((u_long *)dest)[0]=
+				(tab_16_packed[*cdat >> 6] & eorx) ^ bgx;
+			((u_long *)dest)[1]=
+				(tab_16_packed[*cdat >> 4 & 0x3] & eorx) ^ bgx;
+			((u_long *)dest)[2]=
+				(tab_16_packed[*cdat >> 2 & 0x3] & eorx) ^ bgx;
+			((u_long *)dest)[3]=
+				(tab_16_packed[*cdat++ & 0x3] & eorx) ^ bgx;
+		}
+		dest0+=16;
+	}
+}
+
+
+static void rev_char_16_packed(struct display *p, int x, int y)
+{
+	u_char *dest;
+	int bytes=p->next_line, rows;
+
+	dest = p->screen_base + y * p->fontheight * bytes + x * 16;
+	for (rows = p->fontheight ; rows-- ; dest += bytes) {
+		((u_long *)dest)[0] ^= 0xffffffff;
+		((u_long *)dest)[1] ^= 0xffffffff;
+		((u_long *)dest)[2] ^= 0xffffffff;
+		((u_long *)dest)[3] ^= 0xffffffff;
+	}
+}
+
+#endif /* CONFIG_FBCON_16PACKED */
+
+
+/* ====================================================================== */
+
+#ifdef CONFIG_FBCON_CYBER
+
+   /*
+    *    Cybervision (accelerated)
+    */
+
+static void bmove_cyber(struct display *p, int sy, int sx, int dy, int dx,
+                        int height, int width)
+{
+	sx *= 8; dx *= 8; width *= 8;
+	Cyber_BitBLT((u_short)sx, (u_short)(sy*p->fontheight), (u_short)dx,
+                (u_short)(dy*p->fontheight), (u_short)width,
+                (u_short)(height*p->fontheight), (u_short)S3_NEW);
+}
+
+
+static void clear_cyber(struct vc_data *conp, struct display *p, int sy, int sx,
+                        int height, int width)
+{
+   u_char bg;
+        
+	sx *= 8; width *= 8;
+	bg = attr_bgcol_ec(p,conp);
+   Cyber_RectFill((u_short)sx, (u_short)(sy*p->fontheight), (u_short)width,
+                  (u_short)(height*p->fontheight), (u_short)S3_NEW,
+                  (u_short)bg); 
+}
+
+
+static void putc_cyber(struct vc_data *conp, struct display *p, int c, int y,
+                       int x)
+{
+	u_char *dest, *cdat;
+	u_long tmp;
+	u_int rows, reverse, underline; 
+	u_char d;
+   u_char fg, bg;
+
+   c &= 0xff;
+
+	dest = p->screen_base+y*p->fontheight*p->next_line+8*x;
+	cdat = p->fontdata+(c*p->fontheight);
+   fg = disp->fgcol;
+   bg = disp->bgcol;
+	reverse = conp->vc_reverse;
+	underline = conp->vc_underline;
+
+   Cyber_WaitBlit();
+	for (rows = p->fontheight; rows--; dest += p->next_line) {
+  		d = *cdat++;
+
+		if (underline && !rows)
+			d = 0xff;
+		if (reverse)
+			d = ~d;
+
+      tmp =  ((d & 0x80) ? fg : bg) << 24;
+      tmp |= ((d & 0x40) ? fg : bg) << 16;
+      tmp |= ((d & 0x20) ? fg : bg) << 8;
+      tmp |= ((d & 0x10) ? fg : bg);
+      *((u_long*) dest) = tmp;
+      tmp =  ((d & 0x8) ? fg : bg) << 24;
+      tmp |= ((d & 0x4) ? fg : bg) << 16;
+      tmp |= ((d & 0x2) ? fg : bg) << 8;
+      tmp |= ((d & 0x1) ? fg : bg);
+      *((u_long*) dest + 1) = tmp;
+	}
+}
+
+
+static void putcs_cyber(struct vc_data *conp, struct display *p, const char *s,
+                        int count, int y, int x)
+{
+	u_char *dest, *dest0, *cdat;
+   u_long tmp;
+	u_int rows, reverse, underline;
+	u_char c, d;
+   u_char fg, bg;
+
+	dest0 = p->screen_base+y*p->fontheight*p->next_line+8*x;
+   fg = disp->fgcol;
+   bg = disp->bgcol;
+	reverse = conp->vc_reverse;
+	underline = conp->vc_underline;
+
+   Cyber_WaitBlit();
+	while (count--) {
+		c = *s++;
+		dest = dest0;
+      dest0 += 8;
+		cdat = p->fontdata+(c*p->fontheight);
+		for (rows = p->fontheight; rows--; dest += p->next_line) {
+ 			d = *cdat++;
+
+			if (underline && !rows)
+				d = 0xff;
+			if (reverse)
+				d = ~d;
+
+         tmp =  ((d & 0x80) ? fg : bg) << 24;
+         tmp |= ((d & 0x40) ? fg : bg) << 16;
+         tmp |= ((d & 0x20) ? fg : bg) << 8;
+         tmp |= ((d & 0x10) ? fg : bg);
+         *((u_long*) dest) = tmp;
+         tmp =  ((d & 0x8) ? fg : bg) << 24;
+         tmp |= ((d & 0x4) ? fg : bg) << 16;
+         tmp |= ((d & 0x2) ? fg : bg) << 8;
+         tmp |= ((d & 0x1) ? fg : bg);
+         *((u_long*) dest + 1) = tmp;
+		}
+	}
+}
+
+
+static void rev_char_cyber(struct display *p, int x, int y)
+{
+	u_char *dest;
+	u_int rows;
+   u_char fg, bg;
+
+   fg = disp->fgcol;
+   bg = disp->bgcol;
+
+	dest = p->screen_base+y*p->fontheight*p->next_line+8*x;
+   Cyber_WaitBlit();
+	for (rows = p->fontheight; rows--; dest += p->next_line) {
+		*dest = (*dest == fg) ? bg : fg;
+      *(dest+1) = (*(dest + 1) == fg) ? bg : fg;
+      *(dest+2) = (*(dest + 2) == fg) ? bg : fg;
+      *(dest+3) = (*(dest + 3) == fg) ? bg : fg;
+      *(dest+4) = (*(dest + 4) == fg) ? bg : fg;
+      *(dest+5) = (*(dest + 5) == fg) ? bg : fg;
+      *(dest+6) = (*(dest + 6) == fg) ? bg : fg;
+      *(dest+7) = (*(dest + 7) == fg) ? bg : fg;
+	}
+}
+
+#endif /* CONFIG_FBCON_CYBER */
+
+
+/* ====================================================================== */
+
+   /*
+    *    The console `switch' structure for the frame buffer based console
+    */
+
+struct consw fb_con = {
+   fbcon_startup, fbcon_init, fbcon_deinit, fbcon_clear, fbcon_putc,
+   fbcon_putcs, fbcon_cursor, fbcon_scroll, fbcon_bmove, fbcon_switch,
+   fbcon_blank, fbcon_get_font, fbcon_set_font
+};
diff -urN linux-2.4.29/arch/blackfin/console/font_8x16.c linux-2.4.29-uc1/arch/blackfin/console/font_8x16.c
--- linux-2.4.29/arch/blackfin/console/font_8x16.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/console/font_8x16.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,4625 @@
+/**********************************************/
+/*                                            */
+/*       Font file generated by cpi2fnt       */
+/*                                            */
+/**********************************************/
+
+#define FONTDATAMAX 4096
+
+char fontname_8x16[] = "VGA8x16";
+
+int  fontheight_8x16 = 16;
+int  fontwidth_8x16  = 8;
+
+unsigned char fontdata_8x16[FONTDATAMAX] = {
+
+	/* 0 0x00 '^@' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 1 0x01 '^A' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x81, /* 10000001 */
+	0xa5, /* 10100101 */
+	0x81, /* 10000001 */
+	0x81, /* 10000001 */
+	0xbd, /* 10111101 */
+	0x99, /* 10011001 */
+	0x81, /* 10000001 */
+	0x81, /* 10000001 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 2 0x02 '^B' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xff, /* 11111111 */
+	0xdb, /* 11011011 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xc3, /* 11000011 */
+	0xe7, /* 11100111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 3 0x03 '^C' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 4 0x04 '^D' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 5 0x05 '^E' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0xe7, /* 11100111 */
+	0xe7, /* 11100111 */
+	0xe7, /* 11100111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 6 0x06 '^F' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 7 0x07 '^G' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 8 0x08 '^H' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xe7, /* 11100111 */
+	0xc3, /* 11000011 */
+	0xc3, /* 11000011 */
+	0xe7, /* 11100111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 9 0x09 '^I' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x42, /* 01000010 */
+	0x42, /* 01000010 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 10 0x0a '^J' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xc3, /* 11000011 */
+	0x99, /* 10011001 */
+	0xbd, /* 10111101 */
+	0xbd, /* 10111101 */
+	0x99, /* 10011001 */
+	0xc3, /* 11000011 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 11 0x0b '^K' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1e, /* 00011110 */
+	0x0e, /* 00001110 */
+	0x1a, /* 00011010 */
+	0x32, /* 00110010 */
+	0x78, /* 01111000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 12 0x0c '^L' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 13 0x0d '^M' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3f, /* 00111111 */
+	0x33, /* 00110011 */
+	0x3f, /* 00111111 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x70, /* 01110000 */
+	0xf0, /* 11110000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 14 0x0e '^N' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7f, /* 01111111 */
+	0x63, /* 01100011 */
+	0x7f, /* 01111111 */
+	0x63, /* 01100011 */
+	0x63, /* 01100011 */
+	0x63, /* 01100011 */
+	0x63, /* 01100011 */
+	0x67, /* 01100111 */
+	0xe7, /* 11100111 */
+	0xe6, /* 11100110 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 15 0x0f '^O' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xdb, /* 11011011 */
+	0x3c, /* 00111100 */
+	0xe7, /* 11100111 */
+	0x3c, /* 00111100 */
+	0xdb, /* 11011011 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 16 0x10 '^P' */
+	0x00, /* 00000000 */
+	0x80, /* 10000000 */
+	0xc0, /* 11000000 */
+	0xe0, /* 11100000 */
+	0xf0, /* 11110000 */
+	0xf8, /* 11111000 */
+	0xfe, /* 11111110 */
+	0xf8, /* 11111000 */
+	0xf0, /* 11110000 */
+	0xe0, /* 11100000 */
+	0xc0, /* 11000000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 17 0x11 '^Q' */
+	0x00, /* 00000000 */
+	0x02, /* 00000010 */
+	0x06, /* 00000110 */
+	0x0e, /* 00001110 */
+	0x1e, /* 00011110 */
+	0x3e, /* 00111110 */
+	0xfe, /* 11111110 */
+	0x3e, /* 00111110 */
+	0x1e, /* 00011110 */
+	0x0e, /* 00001110 */
+	0x06, /* 00000110 */
+	0x02, /* 00000010 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 18 0x12 '^R' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 19 0x13 '^S' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 20 0x14 '^T' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7f, /* 01111111 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0x7b, /* 01111011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 21 0x15 '^U' */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x60, /* 01100000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x0c, /* 00001100 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 22 0x16 '^V' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 23 0x17 '^W' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 24 0x18 '^X' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 25 0x19 '^Y' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 26 0x1a '^Z' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0xfe, /* 11111110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 27 0x1b '^[' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xfe, /* 11111110 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 28 0x1c '^\' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 29 0x1d '^]' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x28, /* 00101000 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x28, /* 00101000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 30 0x1e '^^' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0x7c, /* 01111100 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 31 0x1f '^_' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 32 0x20 ' ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 33 0x21 '!' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 34 0x22 '"' */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x24, /* 00100100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 35 0x23 '#' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 36 0x24 '$' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc2, /* 11000010 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x86, /* 10000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 37 0x25 '%' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc2, /* 11000010 */
+	0xc6, /* 11000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc6, /* 11000110 */
+	0x86, /* 10000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 38 0x26 '&' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 39 0x27 ''' */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 40 0x28 '(' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 41 0x29 ')' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 42 0x2a '*' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0xff, /* 11111111 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 43 0x2b '+' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 44 0x2c ',' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 45 0x2d '-' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 46 0x2e '.' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 47 0x2f '/' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x02, /* 00000010 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 48 0x30 '0' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 49 0x31 '1' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x38, /* 00111000 */
+	0x78, /* 01111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 50 0x32 '2' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 51 0x33 '3' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x3c, /* 00111100 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 52 0x34 '4' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0c, /* 00001100 */
+	0x1c, /* 00011100 */
+	0x3c, /* 00111100 */
+	0x6c, /* 01101100 */
+	0xcc, /* 11001100 */
+	0xfe, /* 11111110 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x1e, /* 00011110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 53 0x35 '5' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xfc, /* 11111100 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 54 0x36 '6' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xfc, /* 11111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 55 0x37 '7' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 56 0x38 '8' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 57 0x39 '9' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 58 0x3a ':' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 59 0x3b ';' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 60 0x3c '<' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 61 0x3d '=' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 62 0x3e '>' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 63 0x3f '?' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 64 0x40 '@' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xde, /* 11011110 */
+	0xde, /* 11011110 */
+	0xde, /* 11011110 */
+	0xdc, /* 11011100 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 65 0x41 'A' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 66 0x42 'B' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xfc, /* 11111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 67 0x43 'C' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0xc2, /* 11000010 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc2, /* 11000010 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 68 0x44 'D' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 69 0x45 'E' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x66, /* 01100110 */
+	0x62, /* 01100010 */
+	0x68, /* 01101000 */
+	0x78, /* 01111000 */
+	0x68, /* 01101000 */
+	0x60, /* 01100000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 70 0x46 'F' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x66, /* 01100110 */
+	0x62, /* 01100010 */
+	0x68, /* 01101000 */
+	0x78, /* 01111000 */
+	0x68, /* 01101000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 71 0x47 'G' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0xc2, /* 11000010 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xde, /* 11011110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x66, /* 01100110 */
+	0x3a, /* 00111010 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 72 0x48 'H' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 73 0x49 'I' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 74 0x4a 'J' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1e, /* 00011110 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 75 0x4b 'K' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xe6, /* 11100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x78, /* 01111000 */
+	0x78, /* 01111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 76 0x4c 'L' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf0, /* 11110000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 77 0x4d 'M' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xee, /* 11101110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xd6, /* 11010110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 78 0x4e 'N' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xe6, /* 11100110 */
+	0xf6, /* 11110110 */
+	0xfe, /* 11111110 */
+	0xde, /* 11011110 */
+	0xce, /* 11001110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 79 0x4f 'O' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 80 0x50 'P' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 81 0x51 'Q' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xde, /* 11011110 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0x0e, /* 00001110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 82 0x52 'R' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 83 0x53 'S' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x60, /* 01100000 */
+	0x38, /* 00111000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 84 0x54 'T' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x5a, /* 01011010 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 85 0x55 'U' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 86 0x56 'V' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 87 0x57 'W' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xfe, /* 11111110 */
+	0xee, /* 11101110 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 88 0x58 'X' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 89 0x59 'Y' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 90 0x5a 'Z' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x86, /* 10000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc2, /* 11000010 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 91 0x5b '[' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 92 0x5c '\' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x80, /* 10000000 */
+	0xc0, /* 11000000 */
+	0xe0, /* 11100000 */
+	0x70, /* 01110000 */
+	0x38, /* 00111000 */
+	0x1c, /* 00011100 */
+	0x0e, /* 00001110 */
+	0x06, /* 00000110 */
+	0x02, /* 00000010 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 93 0x5d ']' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 94 0x5e '^' */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 95 0x5f '_' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 96 0x60 '`' */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 97 0x61 'a' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 98 0x62 'b' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x78, /* 01111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 99 0x63 'c' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 100 0x64 'd' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1c, /* 00011100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x3c, /* 00111100 */
+	0x6c, /* 01101100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 101 0x65 'e' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 102 0x66 'f' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1c, /* 00011100 */
+	0x36, /* 00110110 */
+	0x32, /* 00110010 */
+	0x30, /* 00110000 */
+	0x78, /* 01111000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 103 0x67 'g' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0xcc, /* 11001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	/* 104 0x68 'h' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x6c, /* 01101100 */
+	0x76, /* 01110110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 105 0x69 'i' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 106 0x6a 'j' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x0e, /* 00001110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 107 0x6b 'k' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x78, /* 01111000 */
+	0x78, /* 01111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 108 0x6c 'l' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 109 0x6d 'm' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xec, /* 11101100 */
+	0xfe, /* 11111110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 110 0x6e 'n' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 111 0x6f 'o' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 112 0x70 'p' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+
+	/* 113 0x71 'q' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x1e, /* 00011110 */
+	0x00, /* 00000000 */
+
+	/* 114 0x72 'r' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x76, /* 01110110 */
+	0x66, /* 01100110 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 115 0x73 's' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x60, /* 01100000 */
+	0x38, /* 00111000 */
+	0x0c, /* 00001100 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 116 0x74 't' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0xfc, /* 11111100 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x36, /* 00110110 */
+	0x1c, /* 00011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 117 0x75 'u' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 118 0x76 'v' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 119 0x77 'w' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 120 0x78 'x' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x38, /* 00111000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 121 0x79 'y' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+
+	/* 122 0x7a 'z' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xcc, /* 11001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 123 0x7b '{' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0e, /* 00001110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x0e, /* 00001110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 124 0x7c '|' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 125 0x7d '}' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x70, /* 01110000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x0e, /* 00001110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 126 0x7e '~' */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 127 0x7f '' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 128 0x80 '€' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0xc2, /* 11000010 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc2, /* 11000010 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 129 0x81 '�' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 130 0x82 '‚' */
+	0x00, /* 00000000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 131 0x83 'ƒ' */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 132 0x84 '„' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 133 0x85 '…' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 134 0x86 '†' */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 135 0x87 '‡' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 136 0x88 'ˆ' */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 137 0x89 '‰' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 138 0x8a 'Š' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 139 0x8b '‹' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 140 0x8c 'Œ' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 141 0x8d '�' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 142 0x8e 'Ž' */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 143 0x8f '�' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 144 0x90 '�' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x66, /* 01100110 */
+	0x62, /* 01100010 */
+	0x68, /* 01101000 */
+	0x78, /* 01111000 */
+	0x68, /* 01101000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 145 0x91 '‘' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xec, /* 11101100 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x7e, /* 01111110 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0x6e, /* 01101110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 146 0x92 '’' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3e, /* 00111110 */
+	0x6c, /* 01101100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xfe, /* 11111110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xce, /* 11001110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 147 0x93 '“' */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 148 0x94 '”' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 149 0x95 '•' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 150 0x96 '–' */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x78, /* 01111000 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 151 0x97 '—' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 152 0x98 '˜' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	/* 153 0x99 '™' */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 154 0x9a 'š' */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 155 0x9b '›' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 156 0x9c 'œ' */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x64, /* 01100100 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xe6, /* 11100110 */
+	0xfc, /* 11111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 157 0x9d '�' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 158 0x9e 'ž' */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xf8, /* 11111000 */
+	0xc4, /* 11000100 */
+	0xcc, /* 11001100 */
+	0xde, /* 11011110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 159 0x9f 'Ÿ' */
+	0x00, /* 00000000 */
+	0x0e, /* 00001110 */
+	0x1b, /* 00011011 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 160 0xa0 ' ' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 161 0xa1 '¡' */
+	0x00, /* 00000000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 162 0xa2 '¢' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 163 0xa3 '£' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 164 0xa4 '¤' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 165 0xa5 '¥' */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xe6, /* 11100110 */
+	0xf6, /* 11110110 */
+	0xfe, /* 11111110 */
+	0xde, /* 11011110 */
+	0xce, /* 11001110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 166 0xa6 '¦' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x3e, /* 00111110 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 167 0xa7 '§' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 168 0xa8 '¨' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 169 0xa9 '©' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 170 0xaa 'ª' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 171 0xab '«' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0xe0, /* 11100000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xdc, /* 11011100 */
+	0x86, /* 10000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x3e, /* 00111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 172 0xac '¬' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0xe0, /* 11100000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x66, /* 01100110 */
+	0xce, /* 11001110 */
+	0x9a, /* 10011010 */
+	0x3f, /* 00111111 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 173 0xad '­' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 174 0xae '®' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x36, /* 00110110 */
+	0x6c, /* 01101100 */
+	0xd8, /* 11011000 */
+	0x6c, /* 01101100 */
+	0x36, /* 00110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 175 0xaf '¯' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xd8, /* 11011000 */
+	0x6c, /* 01101100 */
+	0x36, /* 00110110 */
+	0x6c, /* 01101100 */
+	0xd8, /* 11011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 176 0xb0 '°' */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+
+	/* 177 0xb1 '±' */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+
+	/* 178 0xb2 '²' */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+
+	/* 179 0xb3 '³' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 180 0xb4 '´' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 181 0xb5 'µ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 182 0xb6 '¶' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 183 0xb7 '·' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 184 0xb8 '¸' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 185 0xb9 '¹' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x06, /* 00000110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 186 0xba 'º' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 187 0xbb '»' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x06, /* 00000110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 188 0xbc '¼' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x06, /* 00000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 189 0xbd '½' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 190 0xbe '¾' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 191 0xbf '¿' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 192 0xc0 'À' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 193 0xc1 'Á' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 194 0xc2 'Â' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 195 0xc3 'Ã' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 196 0xc4 'Ä' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 197 0xc5 'Å' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 198 0xc6 'Æ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 199 0xc7 'Ç' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 200 0xc8 'È' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x30, /* 00110000 */
+	0x3f, /* 00111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 201 0xc9 'É' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3f, /* 00111111 */
+	0x30, /* 00110000 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 202 0xca 'Ê' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf7, /* 11110111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 203 0xcb 'Ë' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xf7, /* 11110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 204 0xcc 'Ì' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x30, /* 00110000 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 205 0xcd 'Í' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 206 0xce 'Î' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf7, /* 11110111 */
+	0x00, /* 00000000 */
+	0xf7, /* 11110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 207 0xcf 'Ï' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 208 0xd0 'Ð' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 209 0xd1 'Ñ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 210 0xd2 'Ò' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 211 0xd3 'Ó' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x3f, /* 00111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 212 0xd4 'Ô' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 213 0xd5 'Õ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 214 0xd6 'Ö' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3f, /* 00111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 215 0xd7 '×' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xff, /* 11111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 216 0xd8 'Ø' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 217 0xd9 'Ù' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 218 0xda 'Ú' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 219 0xdb 'Û' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 220 0xdc 'Ü' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 221 0xdd 'Ý' */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+
+	/* 222 0xde 'Þ' */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+
+	/* 223 0xdf 'ß' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 224 0xe0 'à' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xdc, /* 11011100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 225 0xe1 'á' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xd8, /* 11011000 */
+	0xcc, /* 11001100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 226 0xe2 'â' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 227 0xe3 'ã' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 228 0xe4 'ä' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 229 0xe5 'å' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 230 0xe6 'æ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+
+	/* 231 0xe7 'ç' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 232 0xe8 'è' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 233 0xe9 'é' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 234 0xea 'ê' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0xee, /* 11101110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 235 0xeb 'ë' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1e, /* 00011110 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x3e, /* 00111110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 236 0xec 'ì' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 237 0xed 'í' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x03, /* 00000011 */
+	0x06, /* 00000110 */
+	0x7e, /* 01111110 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0xf3, /* 11110011 */
+	0x7e, /* 01111110 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 238 0xee 'î' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1c, /* 00011100 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x1c, /* 00011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 239 0xef 'ï' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 240 0xf0 'ð' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 241 0xf1 'ñ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 242 0xf2 'ò' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 243 0xf3 'ó' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 244 0xf4 'ô' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0e, /* 00001110 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 245 0xf5 'õ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 246 0xf6 'ö' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 247 0xf7 '÷' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 248 0xf8 'ø' */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 249 0xf9 'ù' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 250 0xfa 'ú' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 251 0xfb 'û' */
+	0x00, /* 00000000 */
+	0x0f, /* 00001111 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0xec, /* 11101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x3c, /* 00111100 */
+	0x1c, /* 00011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 252 0xfc 'ü' */
+	0x00, /* 00000000 */
+	0x6c, /* 01101100 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 253 0xfd 'ý' */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x32, /* 00110010 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 254 0xfe 'þ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 255 0xff 'ÿ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+};
+
diff -urN linux-2.4.29/arch/blackfin/console/font_8x8.c linux-2.4.29-uc1/arch/blackfin/console/font_8x8.c
--- linux-2.4.29/arch/blackfin/console/font_8x8.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/console/font_8x8.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,2577 @@
+/**********************************************/
+/*                                            */
+/*       Font file generated by cpi2fnt       */
+/*                                            */
+/**********************************************/
+
+#define FONTDATAMAX 2048
+
+char fontname_8x8[] = "VGA8x8";
+
+int  fontheight_8x8 = 8;
+int  fontwidth_8x8  = 8;
+
+unsigned char fontdata_8x8[FONTDATAMAX] = {
+
+	/* 0 0x00 '^@' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 1 0x01 '^A' */
+	0x7e, /* 01111110 */
+	0x81, /* 10000001 */
+	0xa5, /* 10100101 */
+	0x81, /* 10000001 */
+	0xbd, /* 10111101 */
+	0x99, /* 10011001 */
+	0x81, /* 10000001 */
+	0x7e, /* 01111110 */
+
+	/* 2 0x02 '^B' */
+	0x7e, /* 01111110 */
+	0xff, /* 11111111 */
+	0xdb, /* 11011011 */
+	0xff, /* 11111111 */
+	0xc3, /* 11000011 */
+	0xe7, /* 11100111 */
+	0xff, /* 11111111 */
+	0x7e, /* 01111110 */
+
+	/* 3 0x03 '^C' */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+
+	/* 4 0x04 '^D' */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+
+	/* 5 0x05 '^E' */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xd6, /* 11010110 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+
+	/* 6 0x06 '^F' */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+
+	/* 7 0x07 '^G' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 8 0x08 '^H' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xe7, /* 11100111 */
+	0xc3, /* 11000011 */
+	0xc3, /* 11000011 */
+	0xe7, /* 11100111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 9 0x09 '^I' */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x42, /* 01000010 */
+	0x42, /* 01000010 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 10 0x0a '^J' */
+	0xff, /* 11111111 */
+	0xc3, /* 11000011 */
+	0x99, /* 10011001 */
+	0xbd, /* 10111101 */
+	0xbd, /* 10111101 */
+	0x99, /* 10011001 */
+	0xc3, /* 11000011 */
+	0xff, /* 11111111 */
+
+	/* 11 0x0b '^K' */
+	0x0f, /* 00001111 */
+	0x07, /* 00000111 */
+	0x0f, /* 00001111 */
+	0x7d, /* 01111101 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x78, /* 01111000 */
+
+	/* 12 0x0c '^L' */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+
+	/* 13 0x0d '^M' */
+	0x3f, /* 00111111 */
+	0x33, /* 00110011 */
+	0x3f, /* 00111111 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x70, /* 01110000 */
+	0xf0, /* 11110000 */
+	0xe0, /* 11100000 */
+
+	/* 14 0x0e '^N' */
+	0x7f, /* 01111111 */
+	0x63, /* 01100011 */
+	0x7f, /* 01111111 */
+	0x63, /* 01100011 */
+	0x63, /* 01100011 */
+	0x67, /* 01100111 */
+	0xe6, /* 11100110 */
+	0xc0, /* 11000000 */
+
+	/* 15 0x0f '^O' */
+	0x18, /* 00011000 */
+	0xdb, /* 11011011 */
+	0x3c, /* 00111100 */
+	0xe7, /* 11100111 */
+	0xe7, /* 11100111 */
+	0x3c, /* 00111100 */
+	0xdb, /* 11011011 */
+	0x18, /* 00011000 */
+
+	/* 16 0x10 '^P' */
+	0x80, /* 10000000 */
+	0xe0, /* 11100000 */
+	0xf8, /* 11111000 */
+	0xfe, /* 11111110 */
+	0xf8, /* 11111000 */
+	0xe0, /* 11100000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+
+	/* 17 0x11 '^Q' */
+	0x02, /* 00000010 */
+	0x0e, /* 00001110 */
+	0x3e, /* 00111110 */
+	0xfe, /* 11111110 */
+	0x3e, /* 00111110 */
+	0x0e, /* 00001110 */
+	0x02, /* 00000010 */
+	0x00, /* 00000000 */
+
+	/* 18 0x12 '^R' */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+
+	/* 19 0x13 '^S' */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+
+	/* 20 0x14 '^T' */
+	0x7f, /* 01111111 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0x7b, /* 01111011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x00, /* 00000000 */
+
+	/* 21 0x15 '^U' */
+	0x3e, /* 00111110 */
+	0x61, /* 01100001 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x86, /* 10000110 */
+	0x7c, /* 01111100 */
+
+	/* 22 0x16 '^V' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 23 0x17 '^W' */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+
+	/* 24 0x18 '^X' */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 25 0x19 '^Y' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 26 0x1a '^Z' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0xfe, /* 11111110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 27 0x1b '^[' */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xfe, /* 11111110 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 28 0x1c '^\' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 29 0x1d '^]' */
+	0x00, /* 00000000 */
+	0x24, /* 00100100 */
+	0x66, /* 01100110 */
+	0xff, /* 11111111 */
+	0x66, /* 01100110 */
+	0x24, /* 00100100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 30 0x1e '^^' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 31 0x1f '^_' */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 32 0x20 ' ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 33 0x21 '!' */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 34 0x22 '"' */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x24, /* 00100100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 35 0x23 '#' */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+
+	/* 36 0x24 '$' */
+	0x18, /* 00011000 */
+	0x3e, /* 00111110 */
+	0x60, /* 01100000 */
+	0x3c, /* 00111100 */
+	0x06, /* 00000110 */
+	0x7c, /* 01111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 37 0x25 '%' */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xcc, /* 11001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x66, /* 01100110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 38 0x26 '&' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 39 0x27 ''' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 40 0x28 '(' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+
+	/* 41 0x29 ')' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	/* 42 0x2a '*' */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0xff, /* 11111111 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 43 0x2b '+' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 44 0x2c ',' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+
+	/* 45 0x2d '-' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 46 0x2e '.' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 47 0x2f '/' */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+
+	/* 48 0x30 '0' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	/* 49 0x31 '1' */
+	0x18, /* 00011000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 50 0x32 '2' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x06, /* 00000110 */
+	0x1c, /* 00011100 */
+	0x30, /* 00110000 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 51 0x33 '3' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x06, /* 00000110 */
+	0x3c, /* 00111100 */
+	0x06, /* 00000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 52 0x34 '4' */
+	0x1c, /* 00011100 */
+	0x3c, /* 00111100 */
+	0x6c, /* 01101100 */
+	0xcc, /* 11001100 */
+	0xfe, /* 11111110 */
+	0x0c, /* 00001100 */
+	0x1e, /* 00011110 */
+	0x00, /* 00000000 */
+
+	/* 53 0x35 '5' */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xfc, /* 11111100 */
+	0x06, /* 00000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 54 0x36 '6' */
+	0x38, /* 00111000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0xfc, /* 11111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 55 0x37 '7' */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	/* 56 0x38 '8' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 57 0x39 '9' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	/* 58 0x3a ':' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 59 0x3b ';' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+
+	/* 60 0x3c '<' */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+
+	/* 61 0x3d '=' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 62 0x3e '>' */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+
+	/* 63 0x3f '?' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 64 0x40 '@' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xde, /* 11011110 */
+	0xde, /* 11011110 */
+	0xde, /* 11011110 */
+	0xc0, /* 11000000 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	/* 65 0x41 'A' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 66 0x42 'B' */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xfc, /* 11111100 */
+	0x00, /* 00000000 */
+
+	/* 67 0x43 'C' */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 68 0x44 'D' */
+	0xf8, /* 11111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+
+	/* 69 0x45 'E' */
+	0xfe, /* 11111110 */
+	0x62, /* 01100010 */
+	0x68, /* 01101000 */
+	0x78, /* 01111000 */
+	0x68, /* 01101000 */
+	0x62, /* 01100010 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 70 0x46 'F' */
+	0xfe, /* 11111110 */
+	0x62, /* 01100010 */
+	0x68, /* 01101000 */
+	0x78, /* 01111000 */
+	0x68, /* 01101000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+
+	/* 71 0x47 'G' */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xce, /* 11001110 */
+	0x66, /* 01100110 */
+	0x3a, /* 00111010 */
+	0x00, /* 00000000 */
+
+	/* 72 0x48 'H' */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 73 0x49 'I' */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 74 0x4a 'J' */
+	0x1e, /* 00011110 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	/* 75 0x4b 'K' */
+	0xe6, /* 11100110 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x78, /* 01111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+
+	/* 76 0x4c 'L' */
+	0xf0, /* 11110000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 77 0x4d 'M' */
+	0xc6, /* 11000110 */
+	0xee, /* 11101110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xd6, /* 11010110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 78 0x4e 'N' */
+	0xc6, /* 11000110 */
+	0xe6, /* 11100110 */
+	0xf6, /* 11110110 */
+	0xde, /* 11011110 */
+	0xce, /* 11001110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 79 0x4f 'O' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 80 0x50 'P' */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+
+	/* 81 0x51 'Q' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xce, /* 11001110 */
+	0x7c, /* 01111100 */
+	0x0e, /* 00001110 */
+
+	/* 82 0x52 'R' */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+
+	/* 83 0x53 'S' */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 84 0x54 'T' */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x5a, /* 01011010 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 85 0x55 'U' */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 86 0x56 'V' */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	/* 87 0x57 'W' */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+
+	/* 88 0x58 'X' */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 89 0x59 'Y' */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 90 0x5a 'Z' */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x8c, /* 10001100 */
+	0x18, /* 00011000 */
+	0x32, /* 00110010 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 91 0x5b '[' */
+	0x3c, /* 00111100 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 92 0x5c '\' */
+	0xc0, /* 11000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0x02, /* 00000010 */
+	0x00, /* 00000000 */
+
+	/* 93 0x5d ']' */
+	0x3c, /* 00111100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 94 0x5e '^' */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 95 0x5f '_' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+
+	/* 96 0x60 '`' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 97 0x61 'a' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 98 0x62 'b' */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x7c, /* 01111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+
+	/* 99 0x63 'c' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 100 0x64 'd' */
+	0x1c, /* 00011100 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 101 0x65 'e' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 102 0x66 'f' */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x60, /* 01100000 */
+	0xf8, /* 11111000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+
+	/* 103 0x67 'g' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0xf8, /* 11111000 */
+
+	/* 104 0x68 'h' */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x6c, /* 01101100 */
+	0x76, /* 01110110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+
+	/* 105 0x69 'i' */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 106 0x6a 'j' */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+
+	/* 107 0x6b 'k' */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x78, /* 01111000 */
+	0x6c, /* 01101100 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+
+	/* 108 0x6c 'l' */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 109 0x6d 'm' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xec, /* 11101100 */
+	0xfe, /* 11111110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0x00, /* 00000000 */
+
+	/* 110 0x6e 'n' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+
+	/* 111 0x6f 'o' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 112 0x70 'p' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+
+	/* 113 0x71 'q' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0x1e, /* 00011110 */
+
+	/* 114 0x72 'r' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x76, /* 01110110 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+
+	/* 115 0x73 's' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x06, /* 00000110 */
+	0xfc, /* 11111100 */
+	0x00, /* 00000000 */
+
+	/* 116 0x74 't' */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0xfc, /* 11111100 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x36, /* 00110110 */
+	0x1c, /* 00011100 */
+	0x00, /* 00000000 */
+
+	/* 117 0x75 'u' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 118 0x76 'v' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	/* 119 0x77 'w' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+
+	/* 120 0x78 'x' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 121 0x79 'y' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0xfc, /* 11111100 */
+
+	/* 122 0x7a 'z' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x4c, /* 01001100 */
+	0x18, /* 00011000 */
+	0x32, /* 00110010 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 123 0x7b '{' */
+	0x0e, /* 00001110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x0e, /* 00001110 */
+	0x00, /* 00000000 */
+
+	/* 124 0x7c '|' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 125 0x7d '}' */
+	0x70, /* 01110000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x0e, /* 00001110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	/* 126 0x7e '~' */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 127 0x7f '' */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 128 0x80 '€' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0x78, /* 01111000 */
+
+	/* 129 0x81 '�' */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 130 0x82 '‚' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 131 0x83 'ƒ' */
+	0x7c, /* 01111100 */
+	0x82, /* 10000010 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 132 0x84 '„' */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 133 0x85 '…' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 134 0x86 '†' */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 135 0x87 '‡' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x7e, /* 01111110 */
+	0x0c, /* 00001100 */
+	0x38, /* 00111000 */
+
+	/* 136 0x88 'ˆ' */
+	0x7c, /* 01111100 */
+	0x82, /* 10000010 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 137 0x89 '‰' */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 138 0x8a 'Š' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 139 0x8b '‹' */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 140 0x8c 'Œ' */
+	0x7c, /* 01111100 */
+	0x82, /* 10000010 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 141 0x8d '�' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 142 0x8e 'Ž' */
+	0xc6, /* 11000110 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 143 0x8f '�' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 144 0x90 '�' */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xf8, /* 11111000 */
+	0xc0, /* 11000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 145 0x91 '‘' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0xd8, /* 11011000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 146 0x92 '’' */
+	0x3e, /* 00111110 */
+	0x6c, /* 01101100 */
+	0xcc, /* 11001100 */
+	0xfe, /* 11111110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xce, /* 11001110 */
+	0x00, /* 00000000 */
+
+	/* 147 0x93 '“' */
+	0x7c, /* 01111100 */
+	0x82, /* 10000010 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 148 0x94 '”' */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 149 0x95 '•' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 150 0x96 '–' */
+	0x78, /* 01111000 */
+	0x84, /* 10000100 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 151 0x97 '—' */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 152 0x98 '˜' */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0xfc, /* 11111100 */
+
+	/* 153 0x99 '™' */
+	0xc6, /* 11000110 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	/* 154 0x9a 'š' */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 155 0x9b '›' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 156 0x9c 'œ' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x64, /* 01100100 */
+	0xf0, /* 11110000 */
+	0x60, /* 01100000 */
+	0x66, /* 01100110 */
+	0xfc, /* 11111100 */
+	0x00, /* 00000000 */
+
+	/* 157 0x9d '�' */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 158 0x9e 'ž' */
+	0xf8, /* 11111000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xfa, /* 11111010 */
+	0xc6, /* 11000110 */
+	0xcf, /* 11001111 */
+	0xc6, /* 11000110 */
+	0xc7, /* 11000111 */
+
+	/* 159 0x9f 'Ÿ' */
+	0x0e, /* 00001110 */
+	0x1b, /* 00011011 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	/* 160 0xa0 ' ' */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 161 0xa1 '¡' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 162 0xa2 '¢' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 163 0xa3 '£' */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 164 0xa4 '¤' */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+
+	/* 165 0xa5 '¥' */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0xe6, /* 11100110 */
+	0xf6, /* 11110110 */
+	0xde, /* 11011110 */
+	0xce, /* 11001110 */
+	0x00, /* 00000000 */
+
+	/* 166 0xa6 '¦' */
+	0x3c, /* 00111100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x3e, /* 00111110 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 167 0xa7 '§' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 168 0xa8 '¨' */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x63, /* 01100011 */
+	0x3e, /* 00111110 */
+	0x00, /* 00000000 */
+
+	/* 169 0xa9 '©' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 170 0xaa 'ª' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 171 0xab '«' */
+	0x63, /* 01100011 */
+	0xe6, /* 11100110 */
+	0x6c, /* 01101100 */
+	0x7e, /* 01111110 */
+	0x33, /* 00110011 */
+	0x66, /* 01100110 */
+	0xcc, /* 11001100 */
+	0x0f, /* 00001111 */
+
+	/* 172 0xac '¬' */
+	0x63, /* 01100011 */
+	0xe6, /* 11100110 */
+	0x6c, /* 01101100 */
+	0x7a, /* 01111010 */
+	0x36, /* 00110110 */
+	0x6a, /* 01101010 */
+	0xdf, /* 11011111 */
+	0x06, /* 00000110 */
+
+	/* 173 0xad '­' */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 174 0xae '®' */
+	0x00, /* 00000000 */
+	0x33, /* 00110011 */
+	0x66, /* 01100110 */
+	0xcc, /* 11001100 */
+	0x66, /* 01100110 */
+	0x33, /* 00110011 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 175 0xaf '¯' */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0x66, /* 01100110 */
+	0x33, /* 00110011 */
+	0x66, /* 01100110 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 176 0xb0 '°' */
+	0x22, /* 00100010 */
+	0x88, /* 10001000 */
+	0x22, /* 00100010 */
+	0x88, /* 10001000 */
+	0x22, /* 00100010 */
+	0x88, /* 10001000 */
+	0x22, /* 00100010 */
+	0x88, /* 10001000 */
+
+	/* 177 0xb1 '±' */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+
+	/* 178 0xb2 '²' */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+
+	/* 179 0xb3 '³' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 180 0xb4 '´' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 181 0xb5 'µ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 182 0xb6 '¶' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 183 0xb7 '·' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 184 0xb8 '¸' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 185 0xb9 '¹' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x06, /* 00000110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 186 0xba 'º' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 187 0xbb '»' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x06, /* 00000110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 188 0xbc '¼' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x06, /* 00000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 189 0xbd '½' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 190 0xbe '¾' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 191 0xbf '¿' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 192 0xc0 'À' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 193 0xc1 'Á' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 194 0xc2 'Â' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 195 0xc3 'Ã' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 196 0xc4 'Ä' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 197 0xc5 'Å' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 198 0xc6 'Æ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 199 0xc7 'Ç' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 200 0xc8 'È' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x30, /* 00110000 */
+	0x3f, /* 00111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 201 0xc9 'É' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3f, /* 00111111 */
+	0x30, /* 00110000 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 202 0xca 'Ê' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf7, /* 11110111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 203 0xcb 'Ë' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xf7, /* 11110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 204 0xcc 'Ì' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x30, /* 00110000 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 205 0xcd 'Í' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 206 0xce 'Î' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf7, /* 11110111 */
+	0x00, /* 00000000 */
+	0xf7, /* 11110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 207 0xcf 'Ï' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 208 0xd0 'Ð' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 209 0xd1 'Ñ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 210 0xd2 'Ò' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 211 0xd3 'Ó' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x3f, /* 00111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 212 0xd4 'Ô' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 213 0xd5 'Õ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 214 0xd6 'Ö' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3f, /* 00111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 215 0xd7 '×' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xff, /* 11111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 216 0xd8 'Ø' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 217 0xd9 'Ù' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 218 0xda 'Ú' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 219 0xdb 'Û' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 220 0xdc 'Ü' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 221 0xdd 'Ý' */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+
+	/* 222 0xde 'Þ' */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+
+	/* 223 0xdf 'ß' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 224 0xe0 'à' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0xc8, /* 11001000 */
+	0xdc, /* 11011100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 225 0xe1 'á' */
+	0x78, /* 01111000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xd8, /* 11011000 */
+	0xcc, /* 11001100 */
+	0xc6, /* 11000110 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+
+	/* 226 0xe2 'â' */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+
+	/* 227 0xe3 'ã' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+
+	/* 228 0xe4 'ä' */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 229 0xe5 'å' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	/* 230 0xe6 'æ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0xc0, /* 11000000 */
+
+	/* 231 0xe7 'ç' */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 232 0xe8 'è' */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+
+	/* 233 0xe9 'é' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	/* 234 0xea 'ê' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0xee, /* 11101110 */
+	0x00, /* 00000000 */
+
+	/* 235 0xeb 'ë' */
+	0x0e, /* 00001110 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x3e, /* 00111110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 236 0xec 'ì' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 237 0xed 'í' */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x7e, /* 01111110 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0x7e, /* 01111110 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+
+	/* 238 0xee 'î' */
+	0x1e, /* 00011110 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x7e, /* 01111110 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x1e, /* 00011110 */
+	0x00, /* 00000000 */
+
+	/* 239 0xef 'ï' */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 240 0xf0 'ð' */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 241 0xf1 'ñ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 242 0xf2 'ò' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 243 0xf3 'ó' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 244 0xf4 'ô' */
+	0x0e, /* 00001110 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 245 0xf5 'õ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+
+	/* 246 0xf6 'ö' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 247 0xf7 '÷' */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 248 0xf8 'ø' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 249 0xf9 'ù' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 250 0xfa 'ú' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 251 0xfb 'û' */
+	0x0f, /* 00001111 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0xec, /* 11101100 */
+	0x6c, /* 01101100 */
+	0x3c, /* 00111100 */
+	0x1c, /* 00011100 */
+
+	/* 252 0xfc 'ü' */
+	0x6c, /* 01101100 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 253 0xfd 'ý' */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 254 0xfe 'þ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 255 0xff 'ÿ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+};
+
diff -urN linux-2.4.29/arch/blackfin/console/fonts.c linux-2.4.29-uc1/arch/blackfin/console/fonts.c
--- linux-2.4.29/arch/blackfin/console/fonts.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/console/fonts.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,112 @@
+
+/*
+ * arch/m68k/console/fonts.c -- `Soft' font definitions
+ *
+ *    Created 1995 by Geert Uytterhoeven
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <asm/font.h>
+
+
+   /*
+    *    External Font Definitions
+    */
+
+/* VGA8x8 */
+extern char fontname_8x8[];
+extern int fontwidth_8x8, fontheight_8x8;
+extern u_char fontdata_8x8[];
+
+/* VGA8x16 */
+extern char fontname_8x16[];
+extern int fontwidth_8x16, fontheight_8x16;
+extern u_char fontdata_8x16[];
+
+/* PEARL8x8 */
+extern char fontname_pearl8x8[];
+extern int fontwidth_pearl8x8, fontheight_pearl8x8;
+extern u_char fontdata_pearl8x8[];
+
+/* MINI4x6 */
+extern char fontname_mini4x6[];
+extern int fontwidth_mini4x6, fontheight_mini4x6;
+extern u_char fontdata_mini4x6[];
+
+
+   /*
+    *    Font Descriptor Array
+    */
+
+struct softfontdesc {
+   char *name;
+   int *width;
+   int *height;
+   u_char *data;
+};
+
+#define VGA8x8_IDX	0
+#define VGA8x16_IDX	1
+#define PEARL8x8_IDX	2
+#define MINI4x6_IDX	3
+
+static struct softfontdesc softfonts[] = {
+   { fontname_8x8, &fontwidth_8x8, &fontheight_8x8, fontdata_8x8 },
+   { fontname_8x16, &fontwidth_8x16, &fontheight_8x16, fontdata_8x16 },
+   { fontname_pearl8x8, &fontwidth_pearl8x8, &fontheight_pearl8x8,
+     fontdata_pearl8x8 },
+   { fontname_mini4x6, &fontwidth_mini4x6, &fontheight_mini4x6,
+     fontdata_mini4x6 },
+};
+
+static u_long numsoftfonts = sizeof(softfonts)/sizeof(*softfonts);
+
+
+   /*
+    *    Find a font with a specific name
+    */
+
+int findsoftfont(char *name, int *width, int *height, u_char *data[])
+{
+   int i;
+
+   for (i = 0; i < numsoftfonts; i++)
+      if (!strcmp(softfonts[i].name, name)) {
+         if (width)
+            *width = *softfonts[i].width;
+         if (height)
+            *height = *softfonts[i].height;
+         if (data)
+            *data = softfonts[i].data;
+			return(1);
+      }
+	return(0);
+}
+
+
+   /*
+    *    Get the default font for a specific screen size
+    */
+
+void getdefaultfont(int xres, int yres, char *name[], int *width, int *height,
+                    u_char *data[])
+{
+    int i;
+    
+    i = MINI4x6_IDX;
+
+    if (name)
+	*name = softfonts[i].name;
+    if (width)
+	*width = *softfonts[i].width;
+    if (height)
+	*height = *softfonts[i].height;
+    if (data)
+	*data = softfonts[i].data;
+}
diff -urN linux-2.4.29/arch/blackfin/console/Makefile linux-2.4.29-uc1/arch/blackfin/console/Makefile
--- linux-2.4.29/arch/blackfin/console/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/console/Makefile	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,12 @@
+#
+# Makefile for Linux arch/frionommu/console source directory
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+L_TARGET = console.a
+obj-y = 68328fb.o fbcon.o fonts.o font_8x16.o font_8x8.o pearl_8x8.o mini_4x6.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/blackfin/console/mini_4x6.c linux-2.4.29-uc1/arch/blackfin/console/mini_4x6.c
--- linux-2.4.29/arch/blackfin/console/mini_4x6.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/console/mini_4x6.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,2149 @@
+
+/* Hand composed "Miniscule" 4x6 font, with binary data generated using Perl stub.
+ *
+ * Use 'perl -x mini_4x6.c < mini_4x6.c > new_version.c' to regenerate binary data.
+ *
+ * Created by Kenneth Albanowski. No rights reserved, released to the public domain.
+ *
+ * Version 1.0
+ *
+ */
+
+/*
+
+#!/usr/bin/perl -pn
+
+s{((0x)?[0-9a-fA-F]+)(.*\[([\*\ ]{4})\])}{
+
+	($num,$pat,$bits) = ($1,$3,$4);
+	
+	$bits =~ s/([^\s0])|(.)/ defined($1) + 0 /ge;
+	
+	$num = ord(pack("B8", $bits));
+	$num |= $num >> 4;
+	$num = sprintf("0x%.2x", $num);
+	
+	#print "$num,$pat,$bits\n";
+	
+	$num . $pat;
+}ge;
+
+__END__;
+*/
+
+#define FONTDATAMAX 1536
+
+char fontname_mini4x6[] = "MINI4x6";
+
+int  fontheight_mini4x6 = 6;
+int  fontwidth_mini4x6  = 4;
+
+/* Note: binary data consists of one byte for each row of each character top
+   to bottom, character 0 to character 255, six bytes per character. Each
+   byte contains the same four character bits in both nybbles.
+   MSBit to LSBit = left to right.
+ */
+
+unsigned char fontdata_mini4x6[FONTDATAMAX] = {
+
+	/*{*/
+	  	/*   Char 0: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 1: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 2: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 3: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 4: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 5: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 6: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 7: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 8: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 9: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 10: '' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 11: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 12: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 13: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 14: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 15: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 16: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 17: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 18: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 19: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 20: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 21: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 22: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 23: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 24: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 25: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 26: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 27: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 28: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 29: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 30: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 31: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 32: ' ' */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 33: '!' */
+	0x44,	/*=  [ *  ]       */
+	0x44,	/*=  [ *  ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 34: '"' */
+	0xaa,	/*=  [* * ]       */
+	0xaa,	/*=  [* * ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 35: '#' */
+	0xaa,	/*=  [* * ]       */
+	0xff,	/*=  [****]       */
+	0xff,	/*=  [****]       */
+	0xaa,	/*=  [* * ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 36: '$' */
+	0x44,	/*=  [ *  ]       */
+	0x66,	/*=  [ ** ]       */
+	0xee,	/*=  [*** ]       */
+	0xcc,	/*=  [**  ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 37: '%' */
+	0xaa,	/*=  [* * ]       */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x88,	/*=  [*   ]       */
+	0xaa,	/*=  [* * ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 38: '&' */
+	0xaa,	/*=  [* * ]       */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x88,	/*=  [*   ]       */
+	0xaa,	/*=  [* * ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 39: ''' */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 40: '(' */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x44,	/*=  [ *  ]       */
+	0x44,	/*=  [ *  ]       */
+	0x22,	/*=  [  * ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 41: ')' */
+	0x44,	/*=  [ *  ]       */
+	0x22,	/*=  [  * ]       */
+	0x22,	/*=  [  * ]       */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 42: '*' */
+	0x00,	/*=  [    ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 43: '+' */
+	0x00,	/*=  [    ]       */
+	0x44,	/*=  [ *  ]       */
+	0xee,	/*=  [*** ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 44: ',' */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x44,	/*=  [ *  ]       */
+	0x88,	/*=  [*   ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 45: '-' */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 46: '.' */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 47: '/' */
+	0x00,	/*=  [    ]       */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x88,	/*=  [*   ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 48: '0'   */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/
+	  	/*   Char 49: '1'   */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/
+	  	/*   Char 50: '2'   */
+	0xcc,	/*=   [**  ]        */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/
+	  	/*   Char 51: '3'   */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x22,	/*=   [  * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 52: '4'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 53: '5'   */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 54: '6'   */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 55: '7'   */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 56: '8'   */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 57: '9'   */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 58: ':'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 59: ';'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	/*}*/
+	/*{*/ 	/*   Char 60: '<'   */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 61: '='   */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 62: '>'   */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 63: '?'   */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 64: '@'   */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 65: 'A'   */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 66: 'B'   */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 67: 'C'   */
+	0x66,	/*=   [ ** ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 68: 'D'   */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 69: 'E'   */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 70: 'F'   */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 71: 'G'   */
+	0x66,	/*=   [ ** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 72: 'H'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 73: 'I'   */
+	0xee,	/*=   [*** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 74: 'J'   */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 75: 'K'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 76: 'L'   */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 77: 'M'   */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 78: 'N'   */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 79: 'O'   */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 80: 'P'   */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 81: 'Q'   */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 82: 'R'   */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 83: 'S'   */
+	0x66,	/*=   [ ** ]        */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x22,	/*=   [  * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 84: 'T'   */
+	0xee,	/*=   [*** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 85: 'U'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 86: 'V'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 87: 'W'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 88: 'X'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 89: 'Y'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 90: 'Z'   */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 91: '['   */
+	0x66,	/*=   [ ** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 92: '\'   */
+	0x00,	/*=   [    ]        */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 93: ']'   */
+	0x66,	/*=   [ ** ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 94: '^'   */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 95: '_'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	/*}*/
+	/*{*/ 	/*   Char 96: '`'   */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 97: 'a'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 98: 'b'   */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 99: 'c'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0x88,	/*=   [*   ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 100: 'd'   */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x66,	/*=   [ ** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 101: 'e'   */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 102: 'f'   */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 103: 'g'   */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 104: 'h'   */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 105: 'i'   */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 106: 'j'   */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 107: 'k'   */
+	0x00,	/*=   [    ]        */
+	0x88,	/*=   [*   ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 108: 'l'   */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 109: 'm'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 110: 'n'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 111: 'o'   */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 112: 'p'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x88,	/*=   [*   ]        */
+	/*}*/
+	/*{*/ 	/*   Char 113: 'q'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x22,	/*=   [  * ]        */
+	/*}*/
+	/*{*/ 	/*   Char 114: 'r'   */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 115: 's'   */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0xcc,	/*=   [**  ]        */
+	0x22,	/*=   [  * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 116: 't'   */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 117: 'u'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 118: 'v'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 119: 'w'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 120: 'x'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 121: 'y'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0xcc,	/*=   [**  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 122: 'z' */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xcc,	/*=   [**  ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 123: '{' */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 124: '|' */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 125: '}' */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x66,	/*=   [ ** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 126: '~' */
+	0x55,	/*=   [ * *]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 127: '' */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 128:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 129:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 130:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 131:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 132:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 133:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 134:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 135:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 136:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 137:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 138:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 139:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 140:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 141:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 142:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 143:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 144:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 145:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 146:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 147:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 148:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 149:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 150:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 151:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 152:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 153:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 154:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 155:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 156:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 157:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 158:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 159:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 160:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 161:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 162:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 163:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 164:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 165:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 166:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 167:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 168:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 169:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 170:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 171:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 172:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 173:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 174:  */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0xcc,	/*=   [**  ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 175:  */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0x66,	/*=   [ ** ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 176:  */
+	0x88,	/*=   [*   ]        */
+	0x22,	/*=   [  * ]        */
+	0x88,	/*=   [*   ]        */
+	0x22,	/*=   [  * ]        */
+	0x88,	/*=   [*   ]        */
+	0x22,	/*=   [  * ]        */
+	/*}*/
+	/*{*/ 	/*   Char 177:  */
+	0xaa,	/*=   [* * ]        */
+	0x55,	/*=   [ * *]        */
+	0xaa,	/*=   [* * ]        */
+	0x55,	/*=   [ * *]        */
+	0xaa,	/*=   [* * ]        */
+	0x55,	/*=   [ * *]        */
+	/*}*/
+	/*{*/ 	/*   Char 178:  */
+	0xdd,	/*=   [** *]        */
+	0xbb,	/*=   [* **]        */
+	0xdd,	/*=   [** *]        */
+	0xbb,	/*=   [* **]        */
+	0xdd,	/*=   [** *]        */
+	0xbb,	/*=   [* **]        */
+	/*}*/
+	/*{*/ 	/*   Char 179:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 180:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 181:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 182:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 183:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 184:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 185:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 186:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 187:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 188:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 189:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 190:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 191:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 192:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x77,	/*=   [ ***]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 193:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 194:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 195:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x77,	/*=   [ ***]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 196:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 197:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xff,	/*=   [****]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 198:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 199:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x77,	/*=   [ ***]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 200:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 201:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 202:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 203:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 204:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 205:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 206:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 207:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 208:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 209:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 210:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 211:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x77,	/*=   [ ***]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 212:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 213:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 214:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x77,	/*=   [ ***]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 215:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xff,	/*=   [****]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 216:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 217:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 218:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x77,	/*=   [ ***]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 219:  */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	/*}*/
+	/*{*/ 	/*   Char 220:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	/*}*/
+	/*{*/ 	/*   Char 221:  */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 222:  */
+	0x33,	/*=   [  **]        */
+	0x33,	/*=   [  **]        */
+	0x33,	/*=   [  **]        */
+	0x33,	/*=   [  **]        */
+	0x33,	/*=   [  **]        */
+	0x33,	/*=   [  **]        */
+	/*}*/
+	/*{*/ 	/*   Char 223:  */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 224:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 225:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 226:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 227:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 228:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 229:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 230:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 231:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 232:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 233:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 234:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 235:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 236:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 237:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 238:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 239:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 240:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 241:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 242:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 243:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 244:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 245:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 246:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 247:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 248:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 249:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 250:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 251:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 252:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 253:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 254:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 255:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+};
diff -urN linux-2.4.29/arch/blackfin/console/pearl_8x8.c linux-2.4.29-uc1/arch/blackfin/console/pearl_8x8.c
--- linux-2.4.29/arch/blackfin/console/pearl_8x8.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/console/pearl_8x8.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,2582 @@
+/**********************************************/
+/*                                            */
+/*       Font file generated by cpi2fnt       */
+/*       ------------------------------       */
+/*       Combined with the alpha-numeric      */
+/*       portion of Greg Harp's old PEARL     */
+/*       font (from earlier versions of       */
+/*       linux-m86k) by John Shifflett        */
+/*                                            */
+/**********************************************/
+
+#define FONTDATAMAX 2048
+
+char fontname_pearl8x8[] = "PEARL8x8";
+
+int  fontheight_pearl8x8 = 8;
+int  fontwidth_pearl8x8  = 8;
+
+unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
+
+   /* 0 0x00 '^@' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 1 0x01 '^A' */
+   0x7e, /* 01111110 */
+   0x81, /* 10000001 */
+   0xa5, /* 10100101 */
+   0x81, /* 10000001 */
+   0xbd, /* 10111101 */
+   0x99, /* 10011001 */
+   0x81, /* 10000001 */
+   0x7e, /* 01111110 */
+
+   /* 2 0x02 '^B' */
+   0x7e, /* 01111110 */
+   0xff, /* 11111111 */
+   0xdb, /* 11011011 */
+   0xff, /* 11111111 */
+   0xc3, /* 11000011 */
+   0xe7, /* 11100111 */
+   0xff, /* 11111111 */
+   0x7e, /* 01111110 */
+
+   /* 3 0x03 '^C' */
+   0x6c, /* 01101100 */
+   0xfe, /* 11111110 */
+   0xfe, /* 11111110 */
+   0xfe, /* 11111110 */
+   0x7c, /* 01111100 */
+   0x38, /* 00111000 */
+   0x10, /* 00010000 */
+   0x00, /* 00000000 */
+
+   /* 4 0x04 '^D' */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x7c, /* 01111100 */
+   0xfe, /* 11111110 */
+   0x7c, /* 01111100 */
+   0x38, /* 00111000 */
+   0x10, /* 00010000 */
+   0x00, /* 00000000 */
+
+   /* 5 0x05 '^E' */
+   0x38, /* 00111000 */
+   0x7c, /* 01111100 */
+   0x38, /* 00111000 */
+   0xfe, /* 11111110 */
+   0xfe, /* 11111110 */
+   0xd6, /* 11010110 */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+
+   /* 6 0x06 '^F' */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x7c, /* 01111100 */
+   0xfe, /* 11111110 */
+   0xfe, /* 11111110 */
+   0x7c, /* 01111100 */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+
+   /* 7 0x07 '^G' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 8 0x08 '^H' */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xe7, /* 11100111 */
+   0xc3, /* 11000011 */
+   0xc3, /* 11000011 */
+   0xe7, /* 11100111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+
+   /* 9 0x09 '^I' */
+   0x00, /* 00000000 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x42, /* 01000010 */
+   0x42, /* 01000010 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 10 0x0a '^J' */
+   0xff, /* 11111111 */
+   0xc3, /* 11000011 */
+   0x99, /* 10011001 */
+   0xbd, /* 10111101 */
+   0xbd, /* 10111101 */
+   0x99, /* 10011001 */
+   0xc3, /* 11000011 */
+   0xff, /* 11111111 */
+
+   /* 11 0x0b '^K' */
+   0x0f, /* 00001111 */
+   0x07, /* 00000111 */
+   0x0f, /* 00001111 */
+   0x7d, /* 01111101 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x78, /* 01111000 */
+
+   /* 12 0x0c '^L' */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+
+   /* 13 0x0d '^M' */
+   0x3f, /* 00111111 */
+   0x33, /* 00110011 */
+   0x3f, /* 00111111 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x70, /* 01110000 */
+   0xf0, /* 11110000 */
+   0xe0, /* 11100000 */
+
+   /* 14 0x0e '^N' */
+   0x7f, /* 01111111 */
+   0x63, /* 01100011 */
+   0x7f, /* 01111111 */
+   0x63, /* 01100011 */
+   0x63, /* 01100011 */
+   0x67, /* 01100111 */
+   0xe6, /* 11100110 */
+   0xc0, /* 11000000 */
+
+   /* 15 0x0f '^O' */
+   0x18, /* 00011000 */
+   0xdb, /* 11011011 */
+   0x3c, /* 00111100 */
+   0xe7, /* 11100111 */
+   0xe7, /* 11100111 */
+   0x3c, /* 00111100 */
+   0xdb, /* 11011011 */
+   0x18, /* 00011000 */
+
+   /* 16 0x10 '^P' */
+   0x80, /* 10000000 */
+   0xe0, /* 11100000 */
+   0xf8, /* 11111000 */
+   0xfe, /* 11111110 */
+   0xf8, /* 11111000 */
+   0xe0, /* 11100000 */
+   0x80, /* 10000000 */
+   0x00, /* 00000000 */
+
+   /* 17 0x11 '^Q' */
+   0x02, /* 00000010 */
+   0x0e, /* 00001110 */
+   0x3e, /* 00111110 */
+   0xfe, /* 11111110 */
+   0x3e, /* 00111110 */
+   0x0e, /* 00001110 */
+   0x02, /* 00000010 */
+   0x00, /* 00000000 */
+
+   /* 18 0x12 '^R' */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+
+   /* 19 0x13 '^S' */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+
+   /* 20 0x14 '^T' */
+   0x7f, /* 01111111 */
+   0xdb, /* 11011011 */
+   0xdb, /* 11011011 */
+   0x7b, /* 01111011 */
+   0x1b, /* 00011011 */
+   0x1b, /* 00011011 */
+   0x1b, /* 00011011 */
+   0x00, /* 00000000 */
+
+   /* 21 0x15 '^U' */
+   0x3e, /* 00111110 */
+   0x61, /* 01100001 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x86, /* 10000110 */
+   0x7c, /* 01111100 */
+
+   /* 22 0x16 '^V' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x7e, /* 01111110 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 23 0x17 '^W' */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+
+   /* 24 0x18 '^X' */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 25 0x19 '^Y' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 26 0x1a '^Z' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0xfe, /* 11111110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 27 0x1b '^[' */
+   0x00, /* 00000000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xfe, /* 11111110 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 28 0x1c '^\' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 29 0x1d '^]' */
+   0x00, /* 00000000 */
+   0x24, /* 00100100 */
+   0x66, /* 01100110 */
+   0xff, /* 11111111 */
+   0x66, /* 01100110 */
+   0x24, /* 00100100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 30 0x1e '^^' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 31 0x1f '^_' */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0x7e, /* 01111110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 32 0x20 ' ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 33 0x21 '!' */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 34 0x22 '"' */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 35 0x23 '#' */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0xfe, /* 11111110 */
+   0x6c, /* 01101100 */
+   0xfe, /* 11111110 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x00, /* 00000000 */
+
+   /* 36 0x24 '$' */
+   0x18, /* 00011000 */
+   0x3e, /* 00111110 */
+   0x60, /* 01100000 */
+   0x3c, /* 00111100 */
+   0x06, /* 00000110 */
+   0x7c, /* 01111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 37 0x25 '%' */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xcc, /* 11001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x66, /* 01100110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 38 0x26 '&' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x68, /* 01101000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 39 0x27 ''' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 40 0x28 '(' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+
+   /* 41 0x29 ')' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+
+   /* 42 0x2a '*' */
+   0x00, /* 00000000 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0xff, /* 11111111 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 43 0x2b '+' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 44 0x2c ',' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+
+   /* 45 0x2d '-' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 46 0x2e '.' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 47 0x2f '/' */
+   0x03, /* 00000011 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 48 0x30 '0' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xde, /* 11011110 */
+   0xfe, /* 11111110 */
+   0xf6, /* 11110110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 49 0x31 '1' */
+   0x18, /* 00011000 */
+   0x78, /* 01111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 50 0x32 '2' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 51 0x33 '3' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0x06, /* 00000110 */
+   0x1c, /* 00011100 */
+   0x06, /* 00000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 52 0x34 '4' */
+   0x1c, /* 00011100 */
+   0x3c, /* 00111100 */
+   0x6c, /* 01101100 */
+   0xcc, /* 11001100 */
+   0xfe, /* 11111110 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+
+   /* 53 0x35 '5' */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xfc, /* 11111100 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 54 0x36 '6' */
+   0x38, /* 00111000 */
+   0x60, /* 01100000 */
+   0xc0, /* 11000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 55 0x37 '7' */
+   0xfe, /* 11111110 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0x60, /* 01100000 */
+   0x00, /* 00000000 */
+
+   /* 56 0x38 '8' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 57 0x39 '9' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+
+   /* 58 0x3a ':' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 59 0x3b ';' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+
+   /* 60 0x3c '<' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+
+   /* 61 0x3d '=' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 62 0x3e '>' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+
+   /* 63 0x3f '?' */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 64 0x40 '@' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xde, /* 11011110 */
+   0xde, /* 11011110 */
+   0xde, /* 11011110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 65 0x41 'A' */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 66 0x42 'B' */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 67 0x43 'C' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 68 0x44 'D' */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 69 0x45 'E' */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xf8, /* 11111000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 70 0x46 'F' */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xf8, /* 11111000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 71 0x47 'G' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xce, /* 11001110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 72 0x48 'H' */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 73 0x49 'I' */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 74 0x4a 'J' */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 75 0x4b 'K' */
+   0xc6, /* 11000110 */
+   0xcc, /* 11001100 */
+   0xd8, /* 11011000 */
+   0xf0, /* 11110000 */
+   0xd8, /* 11011000 */
+   0xcc, /* 11001100 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 76 0x4c 'L' */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 77 0x4d 'M' */
+   0x82, /* 10000010 */
+   0xc6, /* 11000110 */
+   0xee, /* 11101110 */
+   0xfe, /* 11111110 */
+   0xd6, /* 11010110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 78 0x4e 'N' */
+   0xc6, /* 11000110 */
+   0xe6, /* 11100110 */
+   0xf6, /* 11110110 */
+   0xde, /* 11011110 */
+   0xce, /* 11001110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 79 0x4f 'O' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 80 0x50 'P' */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 81 0x51 'Q' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xf6, /* 11110110 */
+   0xde, /* 11011110 */
+   0x7c, /* 01111100 */
+   0x06, /* 00000110 */
+
+   /* 82 0x52 'R' */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0xd8, /* 11011000 */
+   0xcc, /* 11001100 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 83 0x53 'S' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0x60, /* 01100000 */
+   0x38, /* 00111000 */
+   0x0c, /* 00001100 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 84 0x54 'T' */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 85 0x55 'U' */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 86 0x56 'V' */
+   0xc3, /* 11000011 */
+   0xc3, /* 11000011 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 87 0x57 'W' */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xd6, /* 11010110 */
+   0xfe, /* 11111110 */
+   0xee, /* 11101110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 88 0x58 'X' */
+   0xc3, /* 11000011 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0xc3, /* 11000011 */
+   0x00, /* 00000000 */
+
+   /* 89 0x59 'Y' */
+   0xc3, /* 11000011 */
+   0xc3, /* 11000011 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 90 0x5a 'Z' */
+   0xfe, /* 11111110 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 91 0x5b '[' */
+   0x3c, /* 00111100 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 92 0x5c '\' */
+   0xc0, /* 11000000 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x06, /* 00000110 */
+   0x03, /* 00000011 */
+   0x00, /* 00000000 */
+
+   /* 93 0x5d ']' */
+   0x3c, /* 00111100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 94 0x5e '^' */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 95 0x5f '_' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+
+   /* 96 0x60 '`' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 97 0x61 'a' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0x06, /* 00000110 */
+   0x7e, /* 01111110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 98 0x62 'b' */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 99 0x63 'c' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 100 0x64 'd' */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x7e, /* 01111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 101 0x65 'e' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 102 0x66 'f' */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x60, /* 01100000 */
+   0xf0, /* 11110000 */
+   0x60, /* 01100000 */
+   0x60, /* 01100000 */
+   0x60, /* 01100000 */
+   0x00, /* 00000000 */
+
+   /* 103 0x67 'g' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x06, /* 00000110 */
+   0x7c, /* 01111100 */
+
+   /* 104 0x68 'h' */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 105 0x69 'i' */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 106 0x6a 'j' */
+   0x06, /* 00000110 */
+   0x00, /* 00000000 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+
+   /* 107 0x6b 'k' */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xcc, /* 11001100 */
+   0xd8, /* 11011000 */
+   0xf0, /* 11110000 */
+   0xd8, /* 11011000 */
+   0xcc, /* 11001100 */
+   0x00, /* 00000000 */
+
+   /* 108 0x6c 'l' */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 109 0x6d 'm' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xec, /* 11101100 */
+   0xfe, /* 11111110 */
+   0xd6, /* 11010110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 110 0x6e 'n' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 111 0x6f 'o' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 112 0x70 'p' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+
+   /* 113 0x71 'q' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+
+   /* 114 0x72 'r' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xdc, /* 11011100 */
+   0xe6, /* 11100110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 115 0x73 's' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x06, /* 00000110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 116 0x74 't' */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x7c, /* 01111100 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x36, /* 00110110 */
+   0x1c, /* 00011100 */
+   0x00, /* 00000000 */
+
+   /* 117 0x75 'u' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 118 0x76 'v' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+
+   /* 119 0x77 'w' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xd6, /* 11010110 */
+   0xfe, /* 11111110 */
+   0x6c, /* 01101100 */
+   0x00, /* 00000000 */
+
+   /* 120 0x78 'x' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 121 0x79 'y' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc3, /* 11000011 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+
+   /* 122 0x7a 'z' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x0c, /* 00001100 */
+   0x38, /* 00111000 */
+   0x60, /* 01100000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 123 0x7b '{' */
+   0x0e, /* 00001110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x70, /* 01110000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x0e, /* 00001110 */
+   0x00, /* 00000000 */
+
+   /* 124 0x7c '|' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 125 0x7d '}' */
+   0x70, /* 01110000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x0e, /* 00001110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x70, /* 01110000 */
+   0x00, /* 00000000 */
+
+   /* 126 0x7e '~' */
+   0x72, /* 01110010 */
+   0x9c, /* 10011100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 127 0x7f '' */
+   0x00, /* 00000000 */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 128 0x80 '€' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x0c, /* 00001100 */
+   0x78, /* 01111000 */
+
+   /* 129 0x81 '�' */
+   0xcc, /* 11001100 */
+   0x00, /* 00000000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 130 0x82 '‚' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 131 0x83 'ƒ' */
+   0x7c, /* 01111100 */
+   0x82, /* 10000010 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 132 0x84 '„' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 133 0x85 '…' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 134 0x86 '†' */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 135 0x87 '‡' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x7e, /* 01111110 */
+   0x0c, /* 00001100 */
+   0x38, /* 00111000 */
+
+   /* 136 0x88 'ˆ' */
+   0x7c, /* 01111100 */
+   0x82, /* 10000010 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 137 0x89 '‰' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 138 0x8a 'Š' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 139 0x8b '‹' */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 140 0x8c 'Œ' */
+   0x7c, /* 01111100 */
+   0x82, /* 10000010 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 141 0x8d '�' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 142 0x8e 'Ž' */
+   0xc6, /* 11000110 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 143 0x8f '�' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 144 0x90 '�' */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xf8, /* 11111000 */
+   0xc0, /* 11000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 145 0x91 '‘' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0xd8, /* 11011000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 146 0x92 '’' */
+   0x3e, /* 00111110 */
+   0x6c, /* 01101100 */
+   0xcc, /* 11001100 */
+   0xfe, /* 11111110 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xce, /* 11001110 */
+   0x00, /* 00000000 */
+
+   /* 147 0x93 '“' */
+   0x7c, /* 01111100 */
+   0x82, /* 10000010 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 148 0x94 '”' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 149 0x95 '•' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 150 0x96 '–' */
+   0x78, /* 01111000 */
+   0x84, /* 10000100 */
+   0x00, /* 00000000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 151 0x97 '—' */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 152 0x98 '˜' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x06, /* 00000110 */
+   0xfc, /* 11111100 */
+
+   /* 153 0x99 '™' */
+   0xc6, /* 11000110 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+
+   /* 154 0x9a 'š' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 155 0x9b '›' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 156 0x9c 'œ' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x64, /* 01100100 */
+   0xf0, /* 11110000 */
+   0x60, /* 01100000 */
+   0x66, /* 01100110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 157 0x9d '�' */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 158 0x9e 'ž' */
+   0xf8, /* 11111000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xfa, /* 11111010 */
+   0xc6, /* 11000110 */
+   0xcf, /* 11001111 */
+   0xc6, /* 11000110 */
+   0xc7, /* 11000111 */
+
+   /* 159 0x9f 'Ÿ' */
+   0x0e, /* 00001110 */
+   0x1b, /* 00011011 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0xd8, /* 11011000 */
+   0x70, /* 01110000 */
+   0x00, /* 00000000 */
+
+   /* 160 0xa0 ' ' */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 161 0xa1 '¡' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 162 0xa2 '¢' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 163 0xa3 '£' */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 164 0xa4 '¤' */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x00, /* 00000000 */
+   0xdc, /* 11011100 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+
+   /* 165 0xa5 '¥' */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x00, /* 00000000 */
+   0xe6, /* 11100110 */
+   0xf6, /* 11110110 */
+   0xde, /* 11011110 */
+   0xce, /* 11001110 */
+   0x00, /* 00000000 */
+
+   /* 166 0xa6 '¦' */
+   0x3c, /* 00111100 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x3e, /* 00111110 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 167 0xa7 '§' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 168 0xa8 '¨' */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x63, /* 01100011 */
+   0x3e, /* 00111110 */
+   0x00, /* 00000000 */
+
+   /* 169 0xa9 '©' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 170 0xaa 'ª' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 171 0xab '«' */
+   0x63, /* 01100011 */
+   0xe6, /* 11100110 */
+   0x6c, /* 01101100 */
+   0x7e, /* 01111110 */
+   0x33, /* 00110011 */
+   0x66, /* 01100110 */
+   0xcc, /* 11001100 */
+   0x0f, /* 00001111 */
+
+   /* 172 0xac '¬' */
+   0x63, /* 01100011 */
+   0xe6, /* 11100110 */
+   0x6c, /* 01101100 */
+   0x7a, /* 01111010 */
+   0x36, /* 00110110 */
+   0x6a, /* 01101010 */
+   0xdf, /* 11011111 */
+   0x06, /* 00000110 */
+
+   /* 173 0xad '­' */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 174 0xae '®' */
+   0x00, /* 00000000 */
+   0x33, /* 00110011 */
+   0x66, /* 01100110 */
+   0xcc, /* 11001100 */
+   0x66, /* 01100110 */
+   0x33, /* 00110011 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 175 0xaf '¯' */
+   0x00, /* 00000000 */
+   0xcc, /* 11001100 */
+   0x66, /* 01100110 */
+   0x33, /* 00110011 */
+   0x66, /* 01100110 */
+   0xcc, /* 11001100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 176 0xb0 '°' */
+   0x22, /* 00100010 */
+   0x88, /* 10001000 */
+   0x22, /* 00100010 */
+   0x88, /* 10001000 */
+   0x22, /* 00100010 */
+   0x88, /* 10001000 */
+   0x22, /* 00100010 */
+   0x88, /* 10001000 */
+
+   /* 177 0xb1 '±' */
+   0x55, /* 01010101 */
+   0xaa, /* 10101010 */
+   0x55, /* 01010101 */
+   0xaa, /* 10101010 */
+   0x55, /* 01010101 */
+   0xaa, /* 10101010 */
+   0x55, /* 01010101 */
+   0xaa, /* 10101010 */
+
+   /* 178 0xb2 '²' */
+   0x77, /* 01110111 */
+   0xdd, /* 11011101 */
+   0x77, /* 01110111 */
+   0xdd, /* 11011101 */
+   0x77, /* 01110111 */
+   0xdd, /* 11011101 */
+   0x77, /* 01110111 */
+   0xdd, /* 11011101 */
+
+   /* 179 0xb3 '³' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 180 0xb4 '´' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 181 0xb5 'µ' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 182 0xb6 '¶' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf6, /* 11110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 183 0xb7 '·' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 184 0xb8 '¸' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 185 0xb9 '¹' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf6, /* 11110110 */
+   0x06, /* 00000110 */
+   0xf6, /* 11110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 186 0xba 'º' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 187 0xbb '»' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x06, /* 00000110 */
+   0xf6, /* 11110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 188 0xbc '¼' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf6, /* 11110110 */
+   0x06, /* 00000110 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 189 0xbd '½' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 190 0xbe '¾' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 191 0xbf '¿' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 192 0xc0 'À' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 193 0xc1 'Á' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 194 0xc2 'Â' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 195 0xc3 'Ã' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 196 0xc4 'Ä' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 197 0xc5 'Å' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 198 0xc6 'Æ' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 199 0xc7 'Ç' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x37, /* 00110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 200 0xc8 'È' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x37, /* 00110111 */
+   0x30, /* 00110000 */
+   0x3f, /* 00111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 201 0xc9 'É' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x3f, /* 00111111 */
+   0x30, /* 00110000 */
+   0x37, /* 00110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 202 0xca 'Ê' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf7, /* 11110111 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 203 0xcb 'Ë' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0xf7, /* 11110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 204 0xcc 'Ì' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x37, /* 00110111 */
+   0x30, /* 00110000 */
+   0x37, /* 00110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 205 0xcd 'Í' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 206 0xce 'Î' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf7, /* 11110111 */
+   0x00, /* 00000000 */
+   0xf7, /* 11110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 207 0xcf 'Ï' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 208 0xd0 'Ð' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 209 0xd1 'Ñ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 210 0xd2 'Ò' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 211 0xd3 'Ó' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x3f, /* 00111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 212 0xd4 'Ô' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 213 0xd5 'Õ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 214 0xd6 'Ö' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x3f, /* 00111111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 215 0xd7 '×' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xff, /* 11111111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 216 0xd8 'Ø' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 217 0xd9 'Ù' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 218 0xda 'Ú' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 219 0xdb 'Û' */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+
+   /* 220 0xdc 'Ü' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+
+   /* 221 0xdd 'Ý' */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+
+   /* 222 0xde 'Þ' */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+
+   /* 223 0xdf 'ß' */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 224 0xe0 'à' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0xc8, /* 11001000 */
+   0xdc, /* 11011100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 225 0xe1 'á' */
+   0x78, /* 01111000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xd8, /* 11011000 */
+   0xcc, /* 11001100 */
+   0xc6, /* 11000110 */
+   0xcc, /* 11001100 */
+   0x00, /* 00000000 */
+
+   /* 226 0xe2 'â' */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 227 0xe3 'ã' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x00, /* 00000000 */
+
+   /* 228 0xe4 'ä' */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 229 0xe5 'å' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xd8, /* 11011000 */
+   0xd8, /* 11011000 */
+   0xd8, /* 11011000 */
+   0x70, /* 01110000 */
+   0x00, /* 00000000 */
+
+   /* 230 0xe6 'æ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x7c, /* 01111100 */
+   0xc0, /* 11000000 */
+
+   /* 231 0xe7 'ç' */
+   0x00, /* 00000000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 232 0xe8 'è' */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+
+   /* 233 0xe9 'é' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+
+   /* 234 0xea 'ê' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0xee, /* 11101110 */
+   0x00, /* 00000000 */
+
+   /* 235 0xeb 'ë' */
+   0x0e, /* 00001110 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x3e, /* 00111110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 236 0xec 'ì' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xdb, /* 11011011 */
+   0xdb, /* 11011011 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 237 0xed 'í' */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x7e, /* 01111110 */
+   0xdb, /* 11011011 */
+   0xdb, /* 11011011 */
+   0x7e, /* 01111110 */
+   0x60, /* 01100000 */
+   0xc0, /* 11000000 */
+
+   /* 238 0xee 'î' */
+   0x1e, /* 00011110 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0x7e, /* 01111110 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x1e, /* 00011110 */
+   0x00, /* 00000000 */
+
+   /* 239 0xef 'ï' */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 240 0xf0 'ð' */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 241 0xf1 'ñ' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 242 0xf2 'ò' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 243 0xf3 'ó' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 244 0xf4 'ô' */
+   0x0e, /* 00001110 */
+   0x1b, /* 00011011 */
+   0x1b, /* 00011011 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 245 0xf5 'õ' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xd8, /* 11011000 */
+   0xd8, /* 11011000 */
+   0x70, /* 01110000 */
+
+   /* 246 0xf6 'ö' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 247 0xf7 '÷' */
+   0x00, /* 00000000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x00, /* 00000000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 248 0xf8 'ø' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 249 0xf9 'ù' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 250 0xfa 'ú' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 251 0xfb 'û' */
+   0x0f, /* 00001111 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0xec, /* 11101100 */
+   0x6c, /* 01101100 */
+   0x3c, /* 00111100 */
+   0x1c, /* 00011100 */
+
+   /* 252 0xfc 'ü' */
+   0x6c, /* 01101100 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 253 0xfd 'ý' */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 254 0xfe 'þ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 255 0xff 'ÿ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+};
+
diff -urN linux-2.4.29/arch/blackfin/console/txtcon.c linux-2.4.29-uc1/arch/blackfin/console/txtcon.c
--- linux-2.4.29/arch/blackfin/console/txtcon.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/console/txtcon.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,127 @@
+/*
+ * linux/arch/m68k/console/txtcon.c -- Low level text mode based console driver
+ *
+ *    Copyright (C) 1995 Geert Uytterhoeven
+ *
+ *
+ * This file is currently only a skeleton, since all Amigas and Ataris have
+ * bitmapped graphics.
+ *
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+
+#include <linux/types.h>
+#include <linux/console.h>
+
+
+   /*
+    *    Interface used by the world
+    */
+
+static u_long txtcon_startup(u_long kmem_start, char **display_desc);
+static void txtcon_init(struct vc_data *conp);
+static int txtcon_deinit(struct vc_data *conp);
+static int txtcon_clear(struct vc_data *conp, int sy, int sx, int height,
+                        int width);
+static int txtcon_putc(struct vc_data *conp, int c, int y, int x);
+static int txtcon_putcs(struct vc_data *conp, const char *s, int count, int y,
+                        int x);
+static int txtcon_cursor(struct vc_data *conp, int mode);
+static int txtcon_scroll(struct vc_data *conp, int t, int b, int dir, int count);
+static int txtcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+                        int height, int width);
+static int txtcon_switch(struct vc_data *conp);
+static int txtcon_blank(int blank);
+
+
+
+static u_long txtcon_startup(u_long kmem_start, char **display_desc)
+{
+   *display_desc = "Not yet implemented";
+   return(kmem_start);
+}
+
+
+static void txtcon_init(struct vc_data *conp)
+{
+}
+
+
+static int txtcon_deinit(struct vc_data *conp)
+{
+   return(0);
+}
+
+
+/* ====================================================================== */
+
+/* txtcon_XXX routines - interface used by the world */
+
+
+static int txtcon_clear(struct vc_data *conp, int sy, int sx, int height,
+                        int width)
+{
+   return(0);
+}
+
+
+static int txtcon_putc(struct vc_data *conp, int c, int y, int x)
+{
+   return(0);
+}
+
+
+static int txtcon_putcs(struct vc_data *conp, const char *s, int count, int y,
+                        int x)
+{
+   return(0);
+}
+
+
+static int txtcon_cursor(struct vc_data *conp, int mode)
+{
+   return(0);
+}
+
+
+static int txtcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
+{
+   return(0);
+}
+
+
+static int txtcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+                        int height, int width)
+{
+   return(0);
+}
+
+
+static int txtcon_switch(struct vc_data *conp)
+{
+   return(0);
+}
+
+
+static int txtcon_blank(int blank)
+{
+   return(0);
+}
+
+
+/* ====================================================================== */
+
+   /*
+    *    The console `switch' structure for the text mode based console
+    */
+
+struct consw txt_con = {
+   txtcon_startup, txtcon_init, txtcon_deinit, txtcon_clear, txtcon_putc,
+   txtcon_putcs, txtcon_cursor, txtcon_scroll, txtcon_bmove, txtcon_switch,
+   txtcon_blank
+};
+
diff -urN linux-2.4.29/arch/blackfin/defconfig linux-2.4.29-uc1/arch/blackfin/defconfig
--- linux-2.4.29/arch/blackfin/defconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/defconfig	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,454 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_UCLINUX=y
+CONFIG_UID16=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Processor type and features
+#
+CONFIG_BLACKFIN=y
+# CONFIG_M68000 is not set
+# CONFIG_M68EN302 is not set
+# CONFIG_M68328 is not set
+# CONFIG_M68EZ328 is not set
+# CONFIG_M68332 is not set
+# CONFIG_M68360 is not set
+# CONFIG_M5204 is not set
+# CONFIG_M5206 is not set
+# CONFIG_M5206e is not set
+# CONFIG_M5307 is not set
+# CONFIG_M5407 is not set
+
+#
+# Platform
+#
+# CONFIG_COLDFIRE=y
+# CONFIG_ARNEWSH is not set
+# CONFIG_NETtel=y
+# CONFIG_eLIA is not set
+# CONFIG_DISKtel is not set
+# CONFIG_CADRE3 is not set
+# CONFIG_OLDMASK is not set
+# CONFIG_FLASH1MB=y
+# CONFIG_FLASH2MB is not set
+# CONFIG_FLASH4MB is not set
+# CONFIG_EXTRA_FLASH1MB is not set
+# CONFIG_RAM4MB=y
+# CONFIG_RAM8MB is not set
+# CONFIG_RAM16MB is not set
+# CONFIG_RAM32MB is not set
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+
+#
+# General setup
+#
+# CONFIG_NET=y
+# CONFIG_VISWS is not set
+# CONFIG_PCI is not set
+# CONFIG_MCA is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+# CONFIG_KCORE_ELF is not set
+CONFIG_KCORE_AOUT=y
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_ELF is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ACPI is not set
+# CONFIG_APM is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_BLKMEM=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK=y
+# CONFIG_RTNETLINK=y
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Network device support
+#
+# CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+# CONFIG_ULTRA is not set
+# CONFIG_ULTRA32 is not set
+# CONFIG_SMC9194=y
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_ASYNC is not set
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Character devices
+#
+# CONFIG_COLDFIRE_SERIAL=y
+# CONFIG_SERIAL is not set
+# CONFIG_MCF_MBUS is not set
+# CONFIG_LCDTXT is not set
+# CONFIG_LCDDMA is not set
+# CONFIG_DAC0800 is not set
+# CONFIG_DACI2S is not set
+# CONFIG_T6963 is not set
+# CONFIG_HIFN7901 is not set
+# CONFIG_LEDMAN=y
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_SYSV_FS_WRITE is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+# CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_FULLDEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_PROFILE is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DUMPTOFLASH is not set
diff -urN linux-2.4.29/arch/blackfin/kernel/bios32.c linux-2.4.29-uc1/arch/blackfin/kernel/bios32.c
--- linux-2.4.29/arch/blackfin/kernel/bios32.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/kernel/bios32.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,532 @@
+/*
+ * bios32.c - PCI BIOS functions for m68k systems.
+ *
+ * Written by Wout Klaren.
+ *
+ * Based on the DEC Alpha bios32.c by Dave Rusling and David Mosberger.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#if 0
+# define DBG_DEVS(args)		printk args
+#else
+# define DBG_DEVS(args)
+#endif
+
+#ifdef CONFIG_PCI
+
+/*
+ * PCI support for Linux/m68k. Currently only the Hades is supported.
+ *
+ * The support for PCI bridges in the DEC Alpha version has
+ * been removed in this version.
+ */
+
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/uaccess.h>
+
+#define KB		1024
+#define MB		(1024*KB)
+#define GB		(1024*MB)
+
+#define MAJOR_REV	0
+#define MINOR_REV	5
+
+/*
+ * Align VAL to ALIGN, which must be a power of two.
+ */
+
+#define ALIGN(val,align)	(((val) + ((align) - 1)) & ~((align) - 1))
+
+#define MAX(val1, val2) 	(((val1) > (val2)) ? val1 : val2)
+
+/*
+ * Offsets relative to the I/O and memory base addresses from where resources
+ * are allocated.
+ */
+
+#define IO_ALLOC_OFFSET		0x00004000
+#define MEM_ALLOC_OFFSET	0x04000000
+
+/*
+ * Declarations of hardware specific initialisation functions.
+ */
+
+extern struct pci_bus_info *init_hades_pci(void);
+
+/*
+ * Bus info structure of the PCI bus. A pointer to this structure is
+ * put in the sysdata member of the pci_bus structure.
+ */
+
+static struct pci_bus_info *bus_info;
+
+static int pci_modify = 1;		/* If set, layout the PCI bus ourself. */
+static int skip_vga = 0;		/* If set do not modify base addresses
+					   of vga cards.*/
+static int disable_pci_burst = 0;	/* If set do not allow PCI bursts. */
+
+static unsigned int io_base;
+static unsigned int mem_base;
+
+struct pci_fixup pcibios_fixups[] =
+{
+	{ 0 }
+};
+
+/*
+ * static void disable_dev(struct pci_dev *dev)
+ *
+ * Disable PCI device DEV so that it does not respond to I/O or memory
+ * accesses.
+ *
+ * Parameters:
+ *
+ * dev	- device to disable.
+ */
+
+static void __init disable_dev(struct pci_dev *dev)
+{
+	struct pci_bus *bus;
+	unsigned short cmd;
+
+	if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) ||
+	     (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA) ||
+	     (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga)
+		return;
+
+	bus = dev->bus;
+	pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
+
+	cmd &= (~PCI_COMMAND_IO & ~PCI_COMMAND_MEMORY & ~PCI_COMMAND_MASTER);
+	pcibios_write_config_word(bus->number, dev->devfn, PCI_COMMAND, cmd);
+}
+
+/*
+ * static void layout_dev(struct pci_dev *dev)
+ *
+ * Layout memory and I/O for a device.
+ *
+ * Parameters:
+ *
+ * device	- device to layout memory and I/O for.
+ */
+
+static void __init layout_dev(struct pci_dev *dev)
+{
+	struct pci_bus *bus;
+	unsigned short cmd;
+	unsigned int base, mask, size, reg;
+	unsigned int alignto;
+	int i;
+
+	/*
+	 * Skip video cards if requested.
+	 */
+
+	if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) ||
+	     (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA) ||
+	     (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga)
+		return;
+
+	bus = dev->bus;
+	pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
+
+	for (reg = PCI_BASE_ADDRESS_0, i = 0; reg <= PCI_BASE_ADDRESS_5; reg += 4, i++)
+	{
+		/*
+		 * Figure out how much space and of what type this
+		 * device wants.
+		 */
+
+		pcibios_write_config_dword(bus->number, dev->devfn, reg,
+					   0xffffffff);
+		pcibios_read_config_dword(bus->number, dev->devfn, reg, &base);
+
+		if (!base)
+		{
+			/* this base-address register is unused */
+			dev->resource[i].start = 0;
+			dev->resource[i].end = 0;
+			dev->resource[i].flags = 0;
+			continue;
+		}
+
+		/*
+		 * We've read the base address register back after
+		 * writing all ones and so now we must decode it.
+		 */
+
+		if (base & PCI_BASE_ADDRESS_SPACE_IO)
+		{
+			/*
+			 * I/O space base address register.
+			 */
+
+			cmd |= PCI_COMMAND_IO;
+
+			base &= PCI_BASE_ADDRESS_IO_MASK;
+			mask = (~base << 1) | 0x1;
+			size = (mask & base) & 0xffffffff;
+
+			/*
+			 * Align to multiple of size of minimum base.
+			 */
+
+			alignto = MAX(0x040, size) ;
+			base = ALIGN(io_base, alignto);
+			io_base = base + size;
+			pcibios_write_config_dword(bus->number, dev->devfn,
+						   reg, base | PCI_BASE_ADDRESS_SPACE_IO);
+
+			dev->resource[i].start = base;
+			dev->resource[i].end = dev->resource[i].start + size - 1;
+			dev->resource[i].flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
+
+			DBG_DEVS(("layout_dev: IO address: %lX\n", base));
+		}
+		else
+		{
+			unsigned int type;
+
+			/*
+			 * Memory space base address register.
+			 */
+
+			cmd |= PCI_COMMAND_MEMORY;
+			type = base & PCI_BASE_ADDRESS_MEM_TYPE_MASK;
+			base &= PCI_BASE_ADDRESS_MEM_MASK;
+			mask = (~base << 1) | 0x1;
+			size = (mask & base) & 0xffffffff;
+			switch (type)
+			{
+			case PCI_BASE_ADDRESS_MEM_TYPE_32:
+			case PCI_BASE_ADDRESS_MEM_TYPE_64:
+				break;
+
+			case PCI_BASE_ADDRESS_MEM_TYPE_1M:
+				printk("bios32 WARNING: slot %d, function %d "
+				       "requests memory below 1MB---don't "
+				       "know how to do that.\n",
+				       PCI_SLOT(dev->devfn),
+				       PCI_FUNC(dev->devfn));
+				continue;
+			}
+
+			/*
+			 * Align to multiple of size of minimum base.
+			 */
+
+			alignto = MAX(0x1000, size) ;
+			base = ALIGN(mem_base, alignto);
+			mem_base = base + size;
+			pcibios_write_config_dword(bus->number, dev->devfn,
+						   reg, base);
+
+			dev->resource[i].start = base;
+			dev->resource[i].end = dev->resource[i].start + size - 1;
+			dev->resource[i].flags = IORESOURCE_MEM;
+
+			if (type == PCI_BASE_ADDRESS_MEM_TYPE_64)
+			{
+				/*
+				 * 64-bit address, set the highest 32 bits
+				 * to zero.
+				 */
+
+				reg += 4;
+				pcibios_write_config_dword(bus->number, dev->devfn,
+							   reg, 0);
+
+				i++;
+				dev->resource[i].start = 0;
+				dev->resource[i].end = 0;
+				dev->resource[i].flags = 0;
+			}
+		}
+	}
+
+	/*
+	 * Enable device:
+	 */
+
+	if (dev->class >> 8 == PCI_CLASS_NOT_DEFINED ||
+	    dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA ||
+	    dev->class >> 8 == PCI_CLASS_DISPLAY_VGA ||
+	    dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)
+	{
+		/*
+		 * All of these (may) have I/O scattered all around
+		 * and may not use i/o-base address registers at all.
+		 * So we just have to always enable I/O to these
+		 * devices.
+		 */
+		cmd |= PCI_COMMAND_IO;
+	}
+
+	pcibios_write_config_word(bus->number, dev->devfn, PCI_COMMAND,
+				  cmd | PCI_COMMAND_MASTER);
+
+	pcibios_write_config_byte(bus->number, dev->devfn, PCI_LATENCY_TIMER,
+				  (disable_pci_burst) ? 0 : 32);
+
+	if (bus_info != NULL)
+		bus_info->conf_device(bus->number, dev->devfn);	/* Machine dependent configuration. */
+
+	DBG_DEVS(("layout_dev: bus %d  slot 0x%x  VID 0x%x  DID 0x%x  class 0x%x\n",
+		  bus->number, PCI_SLOT(dev->devfn), dev->vendor, dev->device, dev->class));
+}
+
+/*
+ * static void layout_bus(struct pci_bus *bus)
+ *
+ * Layout memory and I/O for all devices on the given bus.
+ *
+ * Parameters:
+ *
+ * bus	- bus.
+ */
+
+static void __init layout_bus(struct pci_bus *bus)
+{
+	unsigned int bio, bmem;
+	struct pci_dev *dev;
+
+	DBG_DEVS(("layout_bus: starting bus %d\n", bus->number));
+
+	if (!bus->devices && !bus->children)
+		return;
+
+	/*
+	 * Align the current bases on appropriate boundaries (4K for
+	 * IO and 1MB for memory).
+	 */
+
+	bio = io_base = ALIGN(io_base, 4*KB);
+	bmem = mem_base = ALIGN(mem_base, 1*MB);
+
+	/*
+	 * PCI devices might have been setup by a PCI BIOS emulation
+	 * running under TOS. In these cases there is a
+	 * window during which two devices may have an overlapping
+	 * address range. To avoid this causing trouble, we first
+	 * turn off the I/O and memory address decoders for all PCI
+	 * devices.  They'll be re-enabled only once all address
+	 * decoders are programmed consistently.
+	 */
+
+	DBG_DEVS(("layout_bus: disable_dev for bus %d\n", bus->number));
+
+	for (dev = bus->devices; dev; dev = dev->sibling)
+	{
+		if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) ||
+		    (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA))
+			disable_dev(dev);
+	}
+
+	/*
+	 * Allocate space to each device:
+	 */
+
+	DBG_DEVS(("layout_bus: starting bus %d devices\n", bus->number));
+
+	for (dev = bus->devices; dev; dev = dev->sibling)
+	{
+		if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) ||
+		    (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA))
+			layout_dev(dev);
+	}
+
+	DBG_DEVS(("layout_bus: bus %d finished\n", bus->number));
+}
+
+/*
+ * static void pcibios_fixup(void)
+ *
+ * Layout memory and I/O of all devices on the PCI bus if 'pci_modify' is
+ * true. This might be necessary because not every m68k machine with a PCI
+ * bus has a PCI BIOS. This function should be called right after
+ * pci_scan_bus() in pcibios_init().
+ */
+
+static void __init pcibios_fixup(void)
+{
+	if (pci_modify)
+	{
+		/*
+		 * Set base addresses for allocation of I/O and memory space.
+		 */
+
+		io_base = bus_info->io_space.start + IO_ALLOC_OFFSET;
+		mem_base = bus_info->mem_space.start + MEM_ALLOC_OFFSET;
+
+		/*
+		 * Scan the tree, allocating PCI memory and I/O space.
+		 */
+
+		layout_bus(pci_bus_b(pci_root.next));
+	}
+
+	/*
+	 * Fix interrupt assignments, etc.
+	 */
+
+	bus_info->fixup(pci_modify);
+}
+
+/*
+ * static void pcibios_claim_resources(struct pci_bus *bus)
+ *
+ * Claim all resources that are assigned to devices on the given bus.
+ *
+ * Parameters:
+ *
+ * bus	- bus.
+ */
+
+static void __init pcibios_claim_resources(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+	int i;
+
+	while (bus)
+	{
+		for (dev = bus->devices; (dev != NULL); dev = dev->sibling)
+		{
+			for (i = 0; i < PCI_NUM_RESOURCES; i++)
+			{
+				struct resource *r = &dev->resource[i];
+				struct resource *pr;
+				struct pci_bus_info *bus_info = (struct pci_bus_info *) dev->sysdata;
+
+				if ((r->start == 0) || (r->parent != NULL))
+					continue;
+#if 1
+				if (r->flags & IORESOURCE_IO)
+					pr = &bus_info->io_space;
+				else
+					pr = &bus_info->mem_space;
+#else
+				if (r->flags & IORESOURCE_IO)
+					pr = &ioport_resource;
+				else
+					pr = &iomem_resource;
+#endif
+				if (request_resource(pr, r) < 0)
+				{
+					printk(KERN_ERR "PCI: Address space collision on region %d of device %s\n", i, dev->name);
+				}
+			}
+		}
+
+		if (bus->children)
+			pcibios_claim_resources(bus->children);
+
+		bus = bus->next;
+	}
+}
+
+/*
+ * int pcibios_assign_resource(struct pci_dev *dev, int i)
+ *
+ * Assign a new address to a PCI resource.
+ *
+ * Parameters:
+ *
+ * dev	- device.
+ * i	- resource.
+ *
+ * Result: 0 if successfull.
+ */
+
+int __init pcibios_assign_resource(struct pci_dev *dev, int i)
+{
+	struct resource *r = &dev->resource[i];
+	struct resource *pr = pci_find_parent_resource(dev, r);
+	unsigned long size = r->end + 1;
+
+	if (!pr)
+		return -EINVAL;
+
+	if (r->flags & IORESOURCE_IO)
+	{
+		if (size > 0x100)
+			return -EFBIG;
+
+		if (allocate_resource(pr, r, size, bus_info->io_space.start +
+				      IO_ALLOC_OFFSET,  bus_info->io_space.end, 1024))
+			return -EBUSY;
+	}
+	else
+	{
+		if (allocate_resource(pr, r, size, bus_info->mem_space.start +
+				      MEM_ALLOC_OFFSET, bus_info->mem_space.end, size))
+			return -EBUSY;
+	}
+
+	if (i < 6)
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, r->start);
+
+	return 0;
+}
+
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+	void *sysdata;
+
+	sysdata = (bus->parent) ? bus->parent->sysdata : bus->sysdata;
+
+	for (dev = bus->devices; (dev != NULL); dev = dev->sibling)
+		dev->sysdata = sysdata;
+}
+
+void __init pcibios_init(void)
+{
+	printk("Linux/m68k PCI BIOS32 revision %x.%02x\n", MAJOR_REV, MINOR_REV);
+
+	bus_info = NULL;
+#ifdef CONFIG_HADES
+	if (MACH_IS_HADES)
+		bus_info = init_hades_pci();
+#endif
+	if (bus_info != NULL)
+	{
+		printk("PCI: Probing PCI hardware\n");
+		pci_scan_bus(0, bus_info->m68k_pci_ops, bus_info);
+		pcibios_fixup();
+		pcibios_claim_resources(pci_root);
+	}
+	else
+		printk("PCI: No PCI bus detected\n");
+}
+
+char * __init pcibios_setup(char *str)
+{
+	if (!strcmp(str, "nomodify"))
+	{
+		pci_modify = 0;
+		return NULL;
+	}
+	else if (!strcmp(str, "skipvga"))
+	{
+		skip_vga = 1;
+		return NULL;
+	}
+	else if (!strcmp(str, "noburst"))
+	{
+		disable_pci_burst = 1;
+		return NULL;
+	}
+
+	return str;
+}
+#endif /* CONFIG_PCI */
diff -urN linux-2.4.29/arch/blackfin/kernel/frio_defs.c linux-2.4.29-uc1/arch/blackfin/kernel/frio_defs.c
--- linux-2.4.29/arch/blackfin/kernel/frio_defs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/kernel/frio_defs.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,101 @@
+/*
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ */
+
+/*  Changes by AKBAR HUSSAIN Lineo  */
+
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/hardirq.h>
+
+/*  Now nisa gas don't understand : #define blur, blur	*/
+#define DEFINE(sym, val) \
+	asm volatile("\n#define " #sym " %c0" : : "i" (val))
+
+int main(void)
+{
+	/* offsets into the task struct (defined in /include/linux/sched.h) */
+	DEFINE(TASK_STATE, offsetof(struct task_struct, state));
+	DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
+	DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
+	DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
+	DEFINE(TASK_COUNTER, offsetof(struct task_struct, counter));
+	DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, sigpending));
+	DEFINE(TASK_NEEDRESCHED, offsetof(struct task_struct, need_resched));
+	DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
+	DEFINE(TASK_MM, offsetof(struct task_struct, mm));
+	DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
+
+	/* offsets into the thread struct (defined in 
+	   include/asm-frionommu/processor.h) 
+	*/
+	/* Unused - amit
+	DEFINE(CPUSTAT_SOFTIRQ_ACTIVE, offsetof(irq_cpustat_t, __softirq_active));
+	DEFINE(CPUSTAT_SOFTIRQ_MASK, offsetof(irq_cpustat_t, __softirq_mask));
+	*/
+	/* Need to fix this when more thread definitions are added - akale */
+	DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
+	DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
+	DEFINE(THREAD_SR, offsetof(struct thread_struct, seqstat));
+	DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
+	DEFINE(THREAD_PC, offsetof(struct thread_struct, pc));
+
+	/* offsets into the pt_regs */
+	DEFINE(PT_ORIG_R0, offsetof(struct pt_regs, orig_r0));
+	DEFINE(PT_R0, offsetof(struct pt_regs, r0));
+	DEFINE(PT_R1, offsetof(struct pt_regs, r1));
+	DEFINE(PT_R2, offsetof(struct pt_regs, r2));
+	DEFINE(PT_R3, offsetof(struct pt_regs, r3));
+	DEFINE(PT_R4, offsetof(struct pt_regs, r4));
+	DEFINE(PT_R5, offsetof(struct pt_regs, r5));
+	DEFINE(PT_R6, offsetof(struct pt_regs, r6));
+	DEFINE(PT_R7, offsetof(struct pt_regs, r7));
+	DEFINE(PT_P0, offsetof(struct pt_regs, p0));
+	DEFINE(PT_P1, offsetof(struct pt_regs, p1));
+	DEFINE(PT_P2, offsetof(struct pt_regs, p2));
+	DEFINE(PT_P3, offsetof(struct pt_regs, p3));
+	DEFINE(PT_P4, offsetof(struct pt_regs, p4));
+	DEFINE(PT_P5, offsetof(struct pt_regs, p5));
+
+	DEFINE(PT_A0w, offsetof(struct pt_regs, a0w));
+	DEFINE(PT_A1w, offsetof(struct pt_regs, a1w));
+	DEFINE(PT_A0x, offsetof(struct pt_regs, a0x));
+	DEFINE(PT_A1x, offsetof(struct pt_regs, a1x));
+	DEFINE(PT_RETS, offsetof(struct pt_regs, rets));
+	DEFINE(PT_RESERVED, offsetof(struct pt_regs, reserved));
+	DEFINE(PT_ASTAT, offsetof(struct pt_regs, astat));
+	DEFINE(PT_SEQSTAT, offsetof(struct pt_regs, seqstat));
+	DEFINE(PT_PC, offsetof(struct pt_regs, pc));
+	DEFINE(PT_IPEND, offsetof(struct pt_regs, ipend));
+	DEFINE(PT_USP, offsetof(struct pt_regs, usp));
+	DEFINE(PT_FP, offsetof(struct pt_regs, fp));
+	DEFINE(PT_SYSCFG, offsetof(struct pt_regs, syscfg));
+
+	/* offsets into the irq_handler struct */
+	DEFINE(IRQ_HANDLER, offsetof(struct irq_node, handler));
+	DEFINE(IRQ_DEVID, offsetof(struct irq_node, dev_id));
+	DEFINE(IRQ_NEXT, offsetof(struct irq_node, next));
+
+	/* offsets into the kernel_stat struct */
+	DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
+
+	/* signal defines */
+	DEFINE(SIGSEGV, SIGSEGV);
+	DEFINE(SEGV_MAPERR, SEGV_MAPERR);
+	DEFINE(SIGTRAP, SIGTRAP);
+
+	DEFINE(PT_PTRACED, PT_PTRACED);
+	DEFINE(PT_TRACESYS, PT_TRACESYS);
+	DEFINE(PT_DTRACE, PT_DTRACE);
+
+	return 0;
+}
diff -urN linux-2.4.29/arch/blackfin/kernel/frio_defs.head linux-2.4.29-uc1/arch/blackfin/kernel/frio_defs.head
--- linux-2.4.29/arch/blackfin/kernel/frio_defs.head	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/kernel/frio_defs.head	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * WARNING! This file is automatically generated - DO NOT EDIT!
+ */
+
+#define TS_MAGICKEY	0x5a5a5a5a
diff -urN linux-2.4.29/arch/blackfin/kernel/frio_ksyms.c linux-2.4.29-uc1/arch/blackfin/kernel/frio_ksyms.c
--- linux-2.4.29/arch/blackfin/kernel/frio_ksyms.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/kernel/frio_ksyms.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,85 @@
+/* Changes made by Akbar Hussain & Tony Kou  lineo Inc., 2001 */
+
+#include <linux/module.h>
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
+
+#include <asm/setup.h>
+#include <asm/machdep.h>
+#include <asm/pgalloc.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/semaphore.h>
+#include <asm/checksum.h>
+#include <asm/hardirq.h>
+#include <asm/softirq.h>
+
+asmlinkage long long __ashrdi3 (long long, int);
+asmlinkage long long __lshrdi3 (long long, int);
+extern char frio_debug_device[];
+
+extern void dump_thread(struct pt_regs *, struct user *);
+
+/* platform dependent support */
+
+EXPORT_SYMBOL(frio_machtype);
+EXPORT_SYMBOL(frio_cputype);
+EXPORT_SYMBOL(cache_push);
+EXPORT_SYMBOL(cache_clear);
+#ifndef CONFIG_SINGLE_MEMORY_CHUNK
+EXPORT_SYMBOL(mm_vtop);
+EXPORT_SYMBOL(mm_ptov);
+EXPORT_SYMBOL(mm_end_of_chunk);
+#endif
+EXPORT_SYMBOL(frio_realnum_memory);
+EXPORT_SYMBOL(frio_memory);
+#ifndef CONFIG_SUN3
+EXPORT_SYMBOL(mm_vtop_fallback);
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
+EXPORT_SYMBOL(kernel_set_cachemode);
+#endif
+EXPORT_SYMBOL(frio_debug_device);
+EXPORT_SYMBOL(dump_fpu);
+EXPORT_SYMBOL(dump_thread);
+EXPORT_SYMBOL(strnlen);
+EXPORT_SYMBOL(strrchr);
+EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(local_irq_count);
+EXPORT_SYMBOL(local_bh_count);
+EXPORT_SYMBOL(mach_enable_irq);
+EXPORT_SYMBOL(mach_disable_irq);
+EXPORT_SYMBOL(kernel_thread);
+#ifdef CONFIG_VME
+EXPORT_SYMBOL(vme_brdtype);
+#endif
+
+/* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial_copy);
+
+/* The following are special because they're not called
+   explicitly (the C compiler generates them).  Fortunately,
+   their interface isn't gonna change any time soon now, so
+   it's OK to leave it out of version control.  */
+EXPORT_SYMBOL_NOVERS(__ashrdi3);
+EXPORT_SYMBOL_NOVERS(__lshrdi3);
+EXPORT_SYMBOL_NOVERS(memcpy);
+EXPORT_SYMBOL_NOVERS(memset);
+EXPORT_SYMBOL_NOVERS(memcmp);
+EXPORT_SYMBOL_NOVERS(memscan);
+
+EXPORT_SYMBOL(get_wchan);
+
+#if 0
+EXPORT_SYMBOL_NOVERS(__down_failed);
+EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
+EXPORT_SYMBOL_NOVERS(__down_failed_trylock);
+EXPORT_SYMBOL_NOVERS(__up_wakeup);
+#endif
diff -urN linux-2.4.29/arch/blackfin/kernel/Makefile linux-2.4.29-uc1/arch/blackfin/kernel/Makefile
--- linux-2.4.29/arch/blackfin/kernel/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/kernel/Makefile	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,38 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+all: kernel.o
+
+O_TARGET := kernel.o
+obj-y := process.o traps.o ptrace.o \
+	  sys_frio.o time.o semaphore.o
+obj-y += setup.o frio_ksyms.o
+
+#Removed by Chang Junxiao 07 01
+#ifdef CONFIG_PCI
+#obj-y += bios32.o
+#endif
+
+obj-$(CONFIG_KGDB)      += nisa-stub.o
+
+head.o: head.S frio_defs.h
+
+entry.o: entry.S frio_defs.h
+
+frio_defs.h: frio_defs.c frio_defs.head
+	rm -f frio_defs.d
+	SUNPRO_DEPENDENCIES="frio_defs.d frio_defs.h" \
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S frio_defs.c
+	cp frio_defs.head frio_defs.h
+	grep '^#define' frio_defs.s >> frio_defs.h
+	rm frio_defs.s
+-include frio_defs.d
+
+include $(TOPDIR)/Rules.make
+
diff -urN linux-2.4.29/arch/blackfin/kernel/nisa-stub.c linux-2.4.29-uc1/arch/blackfin/kernel/nisa-stub.c
--- linux-2.4.29/arch/blackfin/kernel/nisa-stub.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/kernel/nisa-stub.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,1519 @@
+/**
+ * Generic portion for gdb stub without any architecture- or platform- specific
+ * infomation.
+ *
+ * Copyright (c) 2001 by Tony Kou of Arcturus Network Com.
+ * All right reserved. 		tonyko@arcturusnetworks.com
+ *
+ * This file is provided "as-is", and without any express
+ * or implied warranties, including, without limitation,
+ * the implied warranties of merchantability and fitness
+ * for a particular purpose.
+ */
+
+/**************************************************************************
+ *
+ *    The following gdb commands are supported:
+ *
+ * command          function                               Return value
+ *
+ *    g             return the value of the CPU registers  hex data or ENN
+ *    G             set the value of the CPU registers     OK or ENN
+ *
+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
+ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
+ *
+ *    c             Resume at current address              SNN   ( signal NN)
+ *    cAA..AA       Continue at address AA..AA             SNN
+ *
+ *    Pnnn=regs     Write register nnn with value          OK or ENN
+ *
+ *    s             Step one instruction                   SNN
+ *    sAA..AA       Step one instruction from AA..AA       SNN
+ *
+ *    k             kill
+ *
+ *    zt,addr,len   Remove hardware breakpoint or 
+ *                  hardware watchpoint
+ *                  Suupport:
+ *                    . 4 hardware breakpoint
+ *                    . 1 insn address range watchpoint
+ *                    . 2 data address watchpoint or 
+ *                      1 data address range watchpoint    OK or ENN
+ *
+ *    Zt,addr,len   Insert hardware breakpoint or 
+ *                  hardware watchpoint
+ *                  Suupport:
+ *                    . 4 hardware breakpoint
+ *                    . 1 insn address range watchpoint
+ *                    . 2 data address watchpoint or 
+ *                      1 data address range watchpoint    OK or ENN
+ *
+ *    ?             What was the last sigval ?             SNN   (signal NN)
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum.  A packet consists of
+ *
+ * $<packet info>#<checksum>.               
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer.  '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host:                  Reply:
+ * $m0,10#2a               +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/ 
+
+#include "nisa-stub.h"
+
+#define GDB_RXBUFLEN	300
+#define GDB_TXBUFLEN	300 
+
+const char nibble_to_hex_table[] = "0123456789abcdef";
+
+
+/*
+ * Converts '[0-9,a-f,A-F]'
+ * to its long integer equivalent.
+ */
+long hex_to_long ( char h )
+{
+  if( h >= 'a' && h <= 'f' )
+    return h - 'a' + 10;
+
+  if( h >= '0' && h <= '9' )
+    return h - '0';
+
+  if( h >= 'A' && h <= 'F' )
+    return h - 'A' + 10;
+
+  return 0;
+}
+
+
+/*
+ * Converts the low nibble of i
+ * to its hex character equivalent.
+ */
+char nibble_to_hex ( char i )
+{
+  return nibble_to_hex_table[i & 0xf];
+}
+
+
+/*
+ * Converts an arbitrary number of hex
+ * digits to a long integer.
+ */
+long hexbuf_to_long ( short len, const char *hexbuf )
+{
+  int retval = 0;
+
+
+  while( len-- )
+    retval = ( retval << 4 ) + hex_to_long( *hexbuf++ );
+
+  return retval;
+}
+
+
+/*
+ * Converts a long integer into a string of hex bytes.
+ *
+ * If pad is zero, then we only consume the exact number of
+ * bytes in hexbuf that we need; there will be no leading zeros.
+ *  
+ * If pad is nonzero, we consume exactly pad bytes (up to 8),
+ * of hexbuf, left-padding hexbuf with zeros if necessary,
+ * and ignoring the most significant bits of l if necessary.
+ *
+ * We return the number of bytes in hexbuf consumed.
+ */
+short long_to_hexbuf ( long l, char *hexbuf, short pad )
+{
+  short consumed = 0;
+  signed short bits;
+
+
+  if( pad )
+    bits = ( pad * sizeof( long )) - sizeof( long );
+  else
+    bits = sizeof( long ) * 8 - 4;
+
+  do {
+
+    if(( *hexbuf = nibble_to_hex( l >> bits )) != '0'
+       || pad || consumed ) {
+
+      hexbuf++;
+      consumed++;
+    }
+
+    bits -= 4;
+
+  } while( bits >= 0 );
+
+  /* always consume at least one byte, even if l was zero */
+  return consumed ? consumed : 1;
+}
+
+
+/*
+ */
+unsigned char gdb_putstr ( short len, const char *buf )
+{
+  unsigned char sum = 0;
+
+  
+  while( len-- ) {
+    sum += *buf;
+    gdb_putc( *buf++ );
+  }
+
+  return sum;
+}
+
+
+/*
+ */
+void gdb_putmsg ( char c, const char *buf, short len )
+{
+  unsigned char sum;
+
+
+  do {
+    
+    /* send the header */
+    gdb_putc( '$' );
+
+    /* send the message type, if specified */
+    if( c ) 
+      gdb_putc( c );
+
+    /* send the data */
+    sum = c + gdb_putstr( len, buf );
+
+    /* send the footer */
+    gdb_putc( '#' );
+    gdb_putc( nibble_to_hex( sum >> 4 ));
+    gdb_putc( nibble_to_hex( sum ));
+
+  } while( '+' != gdb_getc() );
+
+  return;
+}
+
+
+/*
+ */
+short gdb_getmsg ( char *rxbuf )
+{
+  char c;
+  unsigned char sum;
+  unsigned char rx_sum;
+  char *buf;
+
+  
+ get_msg:
+
+  /* wait around for start character, ignore all others */
+  while( gdb_getc() != '$' );
+
+  /* start counting bytes */
+  buf = rxbuf;
+  sum = 0;
+  
+  /* read until we see the '#' at the end of the packet */
+  do {
+    
+    *buf++ = c = gdb_getc();
+    
+    if( c != '#' ) {
+      sum += c;
+    }
+      
+    /* since the buffer is ascii,
+       may as well terminate it */
+    *buf = 0;
+    
+  } while( c != '#' );
+  
+  /* receive checksum */
+  rx_sum = hex_to_long( gdb_getc());
+  rx_sum = ( rx_sum << 4 ) + hex_to_long( gdb_getc() );
+  
+  /* if computed checksum doesn't
+     match received checksum, then reject */
+  if( sum != rx_sum ) {
+    
+    gdb_putc( '-' );
+    goto get_msg;
+  }
+  
+  else {
+    /* got the message ok */
+    gdb_putc( '+' );
+  }
+
+  return 1;
+}
+
+
+/*
+ * "last signal" message
+ * 
+ * "Sxx", where:
+ * xx is the signal number
+ */
+void gdb_last_signal ( short sigval )
+{
+  char tx_buf[2];
+  
+
+  gdb_putmsg( 'S', tx_buf,
+	      long_to_hexbuf( sigval, tx_buf, 2 ));
+
+  return;
+}
+
+
+/*
+ * "expedited response" message
+ * "Txx..........."
+ *
+ */
+void gdb_expedited ( short sigval )
+{
+  char tx_buf[sizeof( long ) * 2];
+  long val;
+  short id = 0;
+  short reglen;
+  unsigned char sum;
+
+
+  do {
+
+    /* send header */
+    gdb_putc( '$' );
+    sum = gdb_putstr( 1, "T" );
+
+    /* signal number */
+    sum += gdb_putstr( long_to_hexbuf( sigval, tx_buf, 2 ), tx_buf );
+
+    /* register values */
+    while(( reglen = gdb_peek_register_file( id, &val )) != 0 ) {
+
+      /* register id */
+      sum += gdb_putstr( long_to_hexbuf( id, tx_buf, 0 ), tx_buf );
+      sum += gdb_putstr( 1, ":" );
+
+      /* register value
+	 (gdb 4.18 requires all 32 bits in values) */
+      sum += gdb_putstr( long_to_hexbuf( val, tx_buf, reglen * 2 ), tx_buf );
+      sum += gdb_putstr( 1, ";" );
+
+      /* try the next register */
+      id++;
+    }
+
+    /* send the message footer */
+    gdb_putc( '#' );
+    gdb_putc( nibble_to_hex( sum >> 4 ));
+    gdb_putc( nibble_to_hex( sum ));
+
+  } while( '+' != gdb_getc() );
+
+  return;
+}
+
+
+/*
+ */
+void gdb_read_memory ( const char *hargs )
+{
+  char tx_buf[sizeof( long ) * 2];
+  long addr = 0;
+  long len = 0;
+  unsigned char sum;
+
+
+  /* parse address */
+  while( *hargs != ',' )
+    addr = ( addr << 4 ) + hex_to_long( *hargs++ );
+
+  /* skip ',' */
+  hargs++;
+
+  /* parse length */
+  while( *hargs != '#' )
+    len = ( len << 4 ) + hex_to_long( *hargs++ );
+
+  /* skip '#' */
+  hargs++;
+
+  /* send header */
+  gdb_putc( '$' );
+  sum = 0;
+  
+  while( len ) {
+      
+    /* read in long units where we can
+       (this is important if the address is
+       a peripheral register or other memory
+       location that only supports long accesses) */
+    while( len >= sizeof( long )
+	   && ( addr % sizeof( long ) == 0 )) {
+      
+      sum += gdb_putstr( long_to_hexbuf( *(long*)addr, tx_buf,
+					 sizeof( long ) * 2 ), tx_buf );
+      
+      addr += sizeof( long );
+      len -= sizeof( long );
+    }
+    
+    /* read in short units where we can
+       (same reasons as above) */
+    if( len >= sizeof( short )
+	&& ( addr % sizeof( short ) == 0 )) {
+      
+      sum += gdb_putstr( long_to_hexbuf( *(short*)addr, tx_buf,
+			   sizeof( short ) * 2 ), tx_buf );
+      
+      addr += sizeof( short );
+      len -= sizeof( short );
+    }
+    
+    if( len == 1
+	|| ( len && ( addr % sizeof( short ) != 0 ))) {
+      
+      /* request is totally misaligned;
+	 read a byte, and hope for the best */
+      sum += gdb_putstr( long_to_hexbuf( *(char*)addr, tx_buf,
+			   sizeof( char ) * 2 ), tx_buf );
+      
+      addr += sizeof( char );
+      len -= sizeof( char );
+    }
+  }
+
+  /* send the message footer */
+  gdb_putc( '#' );
+  gdb_putc( nibble_to_hex( sum >> 4 ));
+  gdb_putc( nibble_to_hex( sum ));
+
+  /* get response from gdb (ignore it for now) */
+  /* TODO: check gdb response in gdb_read_memory */
+  gdb_getc();
+
+  return;
+}
+
+
+/*
+ */
+void gdb_write_memory ( const char *hargs )
+{
+  long addr = 0;
+  long len = 0;
+
+  /* parse address */
+  while( *hargs != ',' )
+    addr = ( addr << 4 ) + hex_to_long( *hargs++ );
+
+  /* skip ',' */
+  hargs++;
+
+  /* parse length */
+  while( *hargs != ':' )
+    len = ( len << 4 ) + hex_to_long( *hargs++ );
+
+  /* skip ':' */
+  hargs++;
+
+  /* Check for attempt to write to ROM - parse to target specific code to handle this one  */
+  if (gdb_is_rom_addr(addr))
+  {
+	 gdb_write_rom(len, addr, hargs);
+  }
+  else
+  {
+     /* write in long units where we can
+        (this is important if the target is
+        a peripheral register or other memory
+        location that only supports long accesses) */
+     while( len >= sizeof( long )
+   	 && addr % sizeof( long ) == 0 ) {
+
+       *(long*)addr = hexbuf_to_long( sizeof( long ) * 2, hargs );
+       hargs += sizeof( long ) * 2;
+       addr += sizeof( long );
+       len -= sizeof( long );
+     }
+
+     /* write in short units where we can (same reasons as above) */
+     if( len >= sizeof( short )
+         && addr % sizeof( short ) == 0 ) {
+
+       *(short*)addr = hexbuf_to_long( sizeof( short ) * 2, hargs );
+       hargs += sizeof( short ) * 2;
+       addr += sizeof( short );
+       len -= sizeof( short );
+     }
+
+     if( (len == 1) || ( len && ((addr % sizeof( short )) != 0) ) ) {
+
+       /* request is totally misaligned;
+          write a byte, and hope for the best */
+
+       *(char*)addr = hexbuf_to_long( sizeof( char ) * 2, hargs );
+       hargs += sizeof( char ) * 2;
+       addr += sizeof( char );
+       len -= sizeof( char );
+     }
+  }
+
+  gdb_putmsg( 0, "OK", 2 );
+  return;
+}
+
+
+/*
+ */
+void gdb_console_output( short len, const char *buf )
+{
+  char tx_buf[2];
+  unsigned char sum;
+
+
+  gdb_putc( '$' );
+  sum = gdb_putstr( 1, "O" );
+
+  while( len-- ) {
+    tx_buf[0] = nibble_to_hex( *buf >> 4 );
+    tx_buf[1] = nibble_to_hex( *buf++ );
+
+    sum += gdb_putstr( 2, tx_buf );
+  }
+
+  /* send the message footer */
+  gdb_putc( '#' );
+  gdb_putc( nibble_to_hex( sum >> 4 ));
+  gdb_putc( nibble_to_hex( sum ));
+
+  /* DON'T wait for response; we don't want to get hung
+     up here and halt the application if gdb has gone away! */
+  
+  return;
+}
+
+
+/*
+ */
+void gdb_write_registers ( char *hargs )
+{
+  short id = 0;
+  long val;
+  short reglen;
+
+
+  while( *hargs != '#' ) {
+
+    /* how big is this register? */
+    reglen = gdb_peek_register_file( id, &val );
+
+    if( reglen ) {
+
+      /* extract the register's value */
+      val = hexbuf_to_long( reglen * 2, hargs );
+      hargs += sizeof( long ) * 2;
+
+      /* stuff it into the register file */
+      gdb_poke_register_file( id++, val );
+    }
+
+    else break;
+  }
+
+  gdb_putmsg( 0, "OK", 2 );
+
+  return;
+}
+
+
+/*
+ */
+void gdb_read_registers ( char *hargs )
+{
+  char tx_buf[sizeof( long ) * 2];
+  long val;
+  short id = 0;
+  short reglen;
+  unsigned char sum;
+
+
+  do {
+
+    gdb_putc( '$' );
+    sum = 0;
+
+    /* send register values */
+    while(( reglen = gdb_peek_register_file( id++, &val ) ) != 0 )
+      sum += gdb_putstr( long_to_hexbuf( val, tx_buf, reglen * 2 ), tx_buf );
+
+    /* send the message footer */
+    gdb_putc( '#' );
+    gdb_putc( nibble_to_hex( sum >> 4 ));
+    gdb_putc( nibble_to_hex( sum ));
+
+  } while( '+' != gdb_getc() );
+    
+  return;  
+}
+
+
+/*
+ */
+void gdb_write_register ( char *hargs )
+{
+  long id = 0;
+  long val = 0;
+
+
+  while( *hargs != '=' )
+    id = ( id << 4 ) + hex_to_long( *hargs++ );
+
+  hargs++;
+
+  while( *hargs != '#' )
+    val = ( val << 4 ) + hex_to_long( *hargs++ );
+
+  gdb_poke_register_file( id, val );
+
+  gdb_putmsg( 0, "OK", 2 );
+
+  return;
+}
+
+
+/*
+ * The gdb command processor.
+ */
+void gdb_monitor ( short sigval )
+{
+  char rxbuf[GDB_RXBUFLEN];
+  char *hargs=rxbuf;
+  unsigned long addr=0, type =-1, length =0;
+
+
+  while( 1 ) {
+
+    gdb_getmsg( rxbuf );
+
+    hargs = rxbuf;
+    switch( *hargs++ ) {
+      
+    case '?' : /* send last signal */
+
+      gdb_last_signal( sigval );
+      break;
+
+
+    case 'c' : /* continue (address optional) */
+
+		/* parse address, if any */
+      while( *hargs != '#' )
+	   {
+        addr = ( addr << 4 ) + hex_to_long( *hargs++ );
+	   }
+
+      gdb_continue( addr );
+      
+      /* exit back to interrupted code */
+      return;
+      
+
+    case 'g' :
+
+      gdb_read_registers( hargs );
+      break;
+
+
+    case 'G' :
+
+      gdb_write_registers( hargs );
+      break;
+
+
+    case 'H' :
+      
+      /* set thread---
+	 unimplemented, but gdb wants it */
+      gdb_putmsg( 0, "OK", 2 );
+      break;
+
+
+    case 'k' : /* kill program */
+
+      gdb_putmsg( 0, "OK", 2 );
+      gdb_kill();
+      break;
+     
+
+    case 'm' :
+      
+      gdb_read_memory( hargs );
+      break;
+
+
+    case 'M' :
+
+      gdb_write_memory( hargs );
+      break;
+
+      
+    case 'P':
+
+      gdb_write_register( hargs );
+      break;
+
+
+    case 'q' : /* query */
+
+      /* TODO: finish query command in gdb_handle_exception. */
+
+      /* for now, only respond to "unrecognized query" */
+      gdb_putmsg( 0, "''", 2 );
+
+      break;
+
+
+    case 's' : /* step (address optional) */
+
+		/* parse address, if any */
+      while( *hargs != '#' )
+	   {
+        addr = ( addr << 4 ) + hex_to_long( *hargs++ );
+	   }
+
+      gdb_step( addr );
+      
+      /* exit back to interrupted code */
+      return;
+
+    case 'Z' : /* Insert break or watch-point:  Format:  Zt,addr,length  */
+      type = hex_to_long( *hargs++ );
+      if !(type >= 0 && type <=4){
+	  gdb_putmsg(0,"E03",3);
+	  return; }
+
+      while ( *hargs++ != ',');	/* skip ',' */
+
+      /* parse addr field */
+      while ( *hargs != ',' )
+	 addr = (addr << 4) + hex_to_long( *hargs++ );
+
+      hargs++; /* skip second ',' */
+
+      while (! *hargs)
+	 length = (length << 4) + hex_to_long( *hargs++ );
+
+      gdb_insert_watch(type, addr, length);  
+      break;
+      
+    case 'z' : /* remove break or watch-point:  Format:  zt,addr,length  */
+      type = hex_to_long( *hargs++ );
+      if !(type >= 0 && type <=4){
+          gdb_putmsg(0,"E04",3);
+          return; }
+ 
+      while ( *hargs++ != ','); /* skip ',' */
+ 
+      /* parse addr field */
+      while ( *hargs != ',' )
+         addr = (addr << 4) + hex_to_long( *hargs++ );
+ 
+      hargs++; /* skip second ',' */
+ 
+      while (! *hargs)
+         length = (length << 4) + hex_to_long( *hargs++ );
+ 
+      gdb_remove_watch(type, addr, length);
+      break; 
+
+    default :
+      
+      /* received a command we don't recognize---
+	 send empty response per gdb spec */
+      gdb_putmsg( 0, "", 0 );
+    
+    }
+  }
+
+  return;
+}
+
+
+/*
+ */
+void gdb_handle_exception( long sigval )
+{
+  /* tell the host why we're here */
+  gdb_expedited( sigval );
+
+  /* ask gdb what to do next */
+  gdb_monitor( sigval );
+
+  /* return to the interrupted code */
+  gdb_return_from_exception();
+
+  return;
+}
+
+/********** Below is BlackFin DSP specific definition ***********
+
+/*
+ * Generic code to save processor context.
+ */
+#define SAVE_CONTEXT()				\
+asm("						\
+	[--sp] = (r7:7, p5:5);\n		\
+	p5.l = CPUregisters;\n			\
+	p5.h = CPUregisters;\n			\
+	[p5++] = r0;\n				\
+	[p5++] = r1;\n				\
+	[p5++] = r2;\n				\
+	[p5++] = r3;\n				\
+	[p5++] = r4;\n				\
+	[p5++] = r5;\n				\
+	[p5++] = r6;\n				\
+	[p5++] = r7;\n				\
+	[p5++] = p1;\n				\
+	[p5++] = p2;\n				\
+	[p5++] = p3;\n				\
+	[p5++] = p4;\n				\
+	r7 = [sp];	/* get original p5 */ \n\
+	[p5++] = r7;\n				\
+	r7 = sp;\n				\
+	r7 += -8;	/* get original sp */ \n\
+	[p5++] = r7;\n				\
+	[p5++] = fp;\n				\
+	r7 = usp;\n				\
+	[p5++] = r7;\n				\
+					      \n\
+	r7 = i0;\n				\
+	[p5++] = r7;\n				\
+	r7 = i1;\n				\
+	[p5++] = r7;\n				\
+	r7 = i2;\n				\
+	[p5++] = r7;\n				\
+	r7 = i3;\n				\
+	[p5++] = r7;\n				\
+					      \n\
+	r7 = m0;\n				\
+	[p5++] = r7;\n				\
+	r7 = m1;\n				\
+	[p5++] = r7;\n				\
+	r7 = m2;\n				\
+	[p5++] = r7;\n				\
+	r7 = m3;\n				\
+	[p5++] = r7;\n				\
+					      \n\
+	r7 = l0;\n				\
+	[p5++] = r7;\n				\
+	r7 = l1;\n				\
+	[p5++] = r7;\n				\
+	r7 = l2;\n				\
+	[p5++] = r7;\n				\
+	r7 = l3;\n				\
+	[p5++] = r7;\n				\
+					      \n\	
+	r7 = b0;\n				\
+	[p5++] = r7;\n				\
+	r7 = b1;\n				\
+	[p5++] = r7;\n				\
+	r7 = b2;\n				\
+	[p5++] = r7;\n				\
+	r7 = b3;\n				\
+	[p5++] = r7;\n				\
+					      \n\
+	r7 = a0x;\n				\
+	[p5++] = r7;\n				\
+	r7 = a0w;\n				\
+	[p5++] = r7;\n				\
+	r7 = a1x;\n				\
+	[p5++] = r7;\n				\
+	r7 = a1w;\n				\
+	[p5++] = r7;\n				\
+					      \n\
+	r7 = ASTAT;\n				\
+	[p5++] = r7;\n				\
+	r7 = RETS;\n				\
+	[p5++] = r7;\n				\
+	r7 = RETI;\n				\
+	[p5++] = r7;\n				\
+	r7 = RETX;\n				\
+	[p5++] = r7;	/* get breakpoint from here, former pc */\n\
+	r7 = RETN;\n				\
+	[p5++] = r7;\n				\
+	r7 = RETE;\n				\
+	[p5++] = r7;\n				\
+	r7 = LC0;\n				\
+	[p5++] = r7;\n				\
+	r7 = LC1;\n				\
+	[p5++] = r7;\n				\
+	r7 = LT0;\n				\
+	[p5++] = r7;\n				\
+	r7 = LT1;\n				\
+	[p5++] = r7;\n				\
+	r7 = LB0;\n				\
+	[p5++] = r7;\n				\
+	r7 = LB1;\n				\
+	[p5++] = r7;\n				\
+	r7 = SYSCFG;\n				\
+	[p5++] = r7;\n				\
+	r7 = SEQSTAT;\n				\
+	[p5++] = r7;\n				\
+					      \n\
+	(r7:7, p5:5) = [sp++];\n		\
+");
+/*	sp.l = localStackPtr;
+ *
+ *	sp.h = localStackPtr;	
+ * switch to local stack - not currently working so commented out! 
+ */
+
+/*
+ * Stuffs a unsigned char out the serial port.
+ */
+void gdb_putc ( char c )
+{
+	unsigned int temp, temp_uartctl;
+
+	DISABLE_ALL_INTERRUPTS(temp)
+	/* Cant allow UART interrupts while sending */
+	temp_uartctl = UART0_IER;
+	UART0_IER = 0;
+
+	/* wait for space in UART tx  */
+	while (!(UART0_LSR & UART0_LSR_THRE));
+
+	/* place unsigned char from buffer into tx  */
+	UART0_THR =  (unsigned short)c;
+
+	/*
+		Allow UART interrupts now that have finished
+	*/
+	UART0_IER = temp_uartctl | UART0_IER_ETBEI | UART0_IER_ELSI;
+
+	ENABLE_ALL_INTERRUPTS(temp)
+	return;
+}
+
+
+/*
+ * Blocks until a unsigned char is received at the serial port.
+ */
+char gdb_getc ( void )
+{
+	unsigned int temp, temp_uartctl;
+	char c;
+	unsigned short rxData;
+
+	DISABLE_ALL_INTERRUPTS(temp)
+	/* Cant allow UART interrupts while sending */
+	temp_uartctl = UART0_IER;
+	UART0_IER = 0;
+
+	/* Do initial read of uart RX register to determine if any characters have been received */
+	rxStatusData = EZ328_URX;
+
+	/* Wait for received data */
+	while ( !(rxData & (UART0_LSR | UART0_LSR_DR ))
+	{
+	   rxData = UART0_RBR;
+
+           /* Tickle H/W watchdog timer *********************/
+	EZ328_WATCHDOG = EZ328_WATCHDOG_ENABLE;
+	}
+
+	/* Assign char received to variable to return - ignore any errors during receive */
+	c = (char)rxStatusData;
+
+	/*
+		Allow UART interrupts now that have finished
+	*/
+	UART0_IER = temp_uartctl | UART0_IER_ERBFI | UART0_IER_ELSI;
+
+	ENABLE_ALL_INTERRUPTS(temp)
+	return c;
+}
+
+
+/*
+ * Retrieves a register value from gdb_register_file.
+ * Returns the size of the register, in bytes,
+ * or zero if an invalid id is specified (which *will*
+ * happen--- gdb.c uses this functionality to tell
+ * how many registers we actually have).
+ */
+short gdb_peek_register_file ( short id, long *val )
+{
+	/* all supported registers are int (4Bytes) */
+	short retval = sizeof( long );
+
+	if ( (id >= R0) && (id <= SEQSTAT) )
+	{
+		*val = CPUregisters[id];
+	}
+	else
+	{
+		retval = 0;
+	}
+
+  return retval;
+}
+
+
+/*
+ * Stuffs a register value into gdb_register_file.
+ * Returns the size of the register, in bytes,
+ * or zero if an invalid id is specified.
+ */
+short gdb_poke_register_file ( short id, long val )
+{
+	/* all our registers are longs */
+	short retval = sizeof( long );
+
+	if ( (id >= R0) && (id <= SEQSTAT) )
+	{
+		CPUregisters[id] = val;
+	}
+	else
+	{
+		retval = 0;
+	}
+
+	return retval;
+}
+
+
+/*
+ * Uses the UBC to generate an exception
+ * after we execute the next instruction.
+ *****************************************************/
+void gdb_step ( unsigned long addr )
+{
+
+	/* if we're stepping from an address,
+           adjust pc (untested!) */
+  	/* TODO: test gdb_step when PC is supplied */
+	if( addr )
+	{
+           CPUregisters[RETX] = addr;
+	}
+
+	/* set Trace bit in CPU status register */
+	CPUregisters[SYSCFG] |= STEP_BIT;
+
+	/* we're all done now */
+  	return;
+}
+
+
+/*
+ * Continue program execution at addr,
+ * or at the current pc if addr == 0.
+ */
+void gdb_continue ( unsigned long addr )
+{
+
+  if( addr )
+  {
+    CPUregisters[RETX] = addr;
+  }
+
+  /* Clear Trace bit in CPU status register - in case been tracing */
+  CPUregisters[SYSCFG] &= ~STEP_BIT;
+
+  return;
+}
+
+
+/*
+ * Kills the current application.
+ * Simulates a reset by jumping to
+ * the address taken from the reset
+ * vector at address 0.
+ */
+void gdb_kill ( void )
+{
+}
+
+/*
+ * Flag for insn & data watchpoint MMR registers: 
+ */
+static unsigned int cur_watch_points = 0;
+static unsigned int cur_watch_range = 0;
+static unsigned int cur_data_points = 0;
+
+
+typedef struct
+{	unsigned long insn_type[4];
+	unsigned long insn_addr[4];
+
+	unsigned long data_mode[2];
+	unsigned long data_addr[2];
+
+	unsigned long insn_range_addr;
+	unsigned long insn_range_len;
+
+	unsigned long data_range_type;
+	unsigned long data_range_addr;
+	unsigned long data_range_len;
+}watch_point_t;
+
+static watch_point_t cur_watch={
+	{-1,-1,-1,-1},
+	{0,  0, 0, 0},
+	{-1, -1},{0 , 0},
+	0, 0, -1, 0, 0};
+
+void gdb_remove_watch(
+	unsigned long type, 
+	unsigned long addr, 
+	unsigned long length)
+{
+     unsigned char i;
+
+     switch (type) {
+	case 1: /* remove hardware breakpoint */
+		if (length && cur_watch_range && (cur_watch.insn_range_addr == addr)
+				&& (cur_watch.insn_range_len == length)){
+		    cur_watch_range = 0;
+		    WPIACTL &= ~0x220000; 
+		 }
+
+		if (!length && cur_watch_points){
+		    i = 0;
+		    while ((cur_watch.insn_type[i] == -1) || (cur_watch.insn_addr[i] != addr) && i<4)
+			i++;
+
+		    if (i < 4){
+			cur_watch.insn_type[i] = -1;
+			cur_watch_points--;
+			DISABLE_INST_WATCHPOINT(i, addr);  
+		     }
+		 }
+		break;
+
+	case 2:  /* remove data hardware address watchpoint */
+	case 3:
+	case 4:
+		if (length && cur_data_points == 3 && data_range_type == type
+			&& data_range_addr == addr && data_range_len == length) {
+		    cur_data_points = 0;
+		    data_range_type = -1;
+
+		    WPDACTL &= ~0x0D;
+		 }
+
+		if (!length && cur_data_points && cur_data_points < 3) {
+		    i = 0;
+		    while (cur_watch.data_mode[i] == -1 || 
+				cur_watch.data_addr[i] != addr || i<2) i++;
+		    if (i < 2) {
+		    	cur_watch.data_mode[i] = -1;
+		    	cur_data_points--;
+
+		    	WPDACTL &= ~(i? 0x9 : 0x5);
+		     }
+		}
+		break;
+		
+
+	case 0: /* remove software breakpoint */
+	} /* end of switch (type)  */
+
+    return;
+}
+
+
+void gdb_insert_watch(
+	unsigned long type,
+	unsigned long addr, 
+	unsigned long length)
+{
+     unsigned char i, mode;
+
+     switch(type){
+	case 1:	/* set hardware breakpoint */
+		if (length && !cur_watch_range){
+		    cur_watch_range =1;
+		    cur_watch.insn_range_addr = addr;
+		    cur_watch.insn_range_len = length;
+
+		    /* enable instruction address range watchpoint to WPIA45 */
+		    (*((volatile unsigned long*)(WPIA_ADDR + 4*4))) = addr & (~1); 
+		    (*((volatile unsigned long*)(WPIA_ADDR + 5*4))) = (addr+length) & (~1); 
+		    (*((volatile unsigned long*)(WPIACNT_ADDR + 4*4))) = 0;
+		    WPIACTL = (WPIACTL & 0xFD81FDFC) | 0x220001;
+		 }
+
+		if (! length && (cur_watch_points < 4)){
+		     i = 0;
+		     while (cur_watch.insn_type[i] != -1 && i<4) i++;
+		     if ( i < 4){
+		     	cur_watch.insn_type[i] = 1;
+		     	cur_watch.insn_addr[i] = addr;
+		     	cur_watch_points++;
+
+		     	ENABLE_INST_WATCHPOINT(i, addr); }
+		  }
+
+		break;
+
+	case 2:	/* data hardware address watchpoint */
+	case 3:
+	case 4:
+		if (length && !cur_data_points){ /* ok to set up data addr WP */
+		    cur_data_points = 3; /* no way to set seperate data addr WP */
+		    data_range_type = type;
+		    data_range_addr = addr;
+		    data_range_len = length;
+
+		    (*((volatile unsigned long*)WPDA_ADDR)) = addr;
+		    (*((volatile unsigned long*)(WPDA_ADDR + 4))) = addr + length;
+		    WPDACNT &= 0xFFFF0000; /* only need set up WPDACNT0  */
+		    WPDACTL = (WPDACTL & 0xFFFFF020) | 0x851 | ((type-1) << 8);
+		}
+
+		if (!length && cur_data_points < 2) {
+		    i = 0;
+		    while (cur_watch.data_mode[i] != -1 && i < 2) i++;
+		    if (i < 2) {
+			cur_watch.data_mode[i] = 1;
+			cur_watch.data_addr[i] = addr;
+			cur_data_points++;
+
+		    (*((volatile unsigned long*)(WPDA_ADDR + i*4))) = addr;
+		    (*((volatile unsigned long*)(WPDACNT_ADDR + i*4))) &= 0xFFFF0000;
+		    WPDACTL = (WPDACTL & ENABLE_DATA_WP_MASK[i]) | ENABLE_DATA_WP[i] 
+				| ((type-1) << (i? 12 : 8);
+		     }
+		 }
+		break;
+		     
+	caes 0: /* software breakpoint */
+
+	}
+
+    return; 
+}   
+
+
+
+/*
+ *	EXCEPTION ISR (Single step/software breakpoint: EXCPT 15)
+ */
+asm("
+.align 2
+.global gdb_exception_isr;
+.type gdb_exception_isr, STT_FUNC;
+gdb_exception_isr:
+");
+	SAVE_CONTEXT();
+
+	//DISABLE_EMU_INTERRUPTS();  ***************
+
+asm("
+	/* Put SIGTRAP on R0 as arg of gdb_handle_exception(long sigval) */
+	R1 = SEQSTAT;
+	R1 <<= 26;
+	R1 >>= 26;	/* get the EXCAUSE field */
+	R0 = 0xf(Z);	/* EXCPT 15 happen */
+	CC = R1 == R0;
+	BRT 1f;
+
+	R0 = 0x10(Z);	/* single step */
+	CC = R1 == R0;
+	BRT 1f;
+
+	R0 = 0x28(Z);	/* Watchpoint match invoked*/
+	CC = R1 == R0;
+	BRF gdb_return_from_exception;
+1:	
+	R0 = 5(Z);
+	call	 gdb_handle_exception;	/* never returns to here! */
+
+/*
+ * Restores registers to the values specified in CPUregisters
+ */
+gdb_return_from_exception:
+	p0.l = CPUregisters;
+	p0.h = CPUregisters;
+	p0 += 200;	// point to end of CPUregisters.
+	r0 = [p0--];
+	seqstat = r0;
+	r0 = [p0--];
+	syscfg = r0;
+	r0 = [p0--];
+	lb1 = r0;
+	r0 = [p0--];
+	lb0 = r0;
+	r0 = [p0--];
+	lt1 = r0;
+	r0 = [p0--];
+	lt0 = r0;
+	r0 = [p0--];
+	lc1 = r0;
+	r0 = [p0--];
+	lc0 = r0;
+	r0 = [p0--];
+	rete = r0;
+	r0 = [p0--];
+	retn = r0;
+	r0 = [p0--];
+	retx = r0;
+	r0 = [p0--];
+	reti = r0;
+	r0 = [p0--];
+	rets = r0;
+	r0 = [p0--];
+	astat = r0;
+	
+	r0 = [p0--];
+	a1w = r0;
+	r0 = [p0--];
+	a1x = r0;
+	r0 = [p0--];
+	a0w = r0;
+	r0 = [p0--];
+	a0x = r0;
+
+	r0 = [p0--];
+	b3 = r0;
+	r0 = [p0--];
+	b2 = r0;
+	r0 = [p0--];
+	b1 = r0;
+	r0 = [p0--];
+	b0 = r0;
+
+	r0 = [p0--];
+	l3 = r0;
+	r0 = [p0--];
+	l2 = r0;
+	r0 = [p0--];
+	l1 = r0;
+	r0 = [p0--];
+	l0 = r0;
+
+	r0 = [p0--];
+	m3 = r0;
+	r0 = [p0--];
+	m2 = r0;
+	r0 = [p0--];
+	m1 = r0;
+	r0 = [p0--];
+	m0 = r0;
+
+	r0 = [p0--];
+	i3 = r0;
+	r0 = [p0--];
+	i2 = r0;
+	r0 = [p0--];
+	i1 = r0;
+	r0 = [p0--];
+	i0 = r0;
+
+	r0 = [p0--];
+	usp = r0;
+	fp = [p0--];
+	sp = [p0--];
+	p5 = [p0--];
+	p4 = [p0--];
+	p3 = [p0--];
+	p2 = [p0--];
+	p1 = [p0--];
+	r0 = [p0--];
+	[--sp] = r0;	/* temp save p0 to system stack */
+
+	r7 = [p0--];
+	r6 = [p0--];
+	r5 = [p0--];
+	r4 = [p0--];
+	r3 = [p0--];
+	r2 = [p0--];
+	r1 = [p0--];
+	r0 = [p0--];
+	p0 = [sp++];	/* restore p0 and system stack */
+
+
+	andi.l #0xFF7FFFFF,0xFFFFF304 /* IMR - enable emulator interrupts */
+ 	move.w 0xFFFFFD0E,0xFFFFFD0E	/* ICEMSR - clear status bits */
+
+	rtx;	  /* return from exception! */
+");
+
+
+void gdb_init(void)
+{
+	/* Set vector for step and EXCPT 15 interrupts */
+   SET_VECTOR(EVT_EXCEPTION_ADDR,gdb_exception_isr);
+
+
+	/* initialize watchpoint MMR: disable every watchpoints
+           and enable watch point unit, also enable WPIREN */
+   WPDACTL |= 0xFC020001;
+   WPDACTL = 0;
+   WPSTAT = 0;	/* clear WP status register */
+
+	BREAKPOINT();	/* Causes control to be passed to GDB stub */
+}
+
+int gdb_is_rom_addr(long addr)
+{
+	return (int)((addr >= 0x800000L) && (addr < 0xC00000L )); /* need more attention */
+}
+
+void gdb_write_rom(long len,long addr, const char *hargs)
+{
+  /*
+  	Test for special case of attempting to write a trap #1 op-code (0x4E41) to flash memory
+	In this case do a hardware breakpoint instead
+	Ignore all other cases - ie simply dont write anything.
+  */
+	if ( len == 2 )
+	{
+   	if (hexbuf_to_long( sizeof( short ) * 2, hargs ) == 0x4e41L)
+      	    gdb_set_hw_break(addr);
+	}
+}
+
+
+/************** Remote communication protocol *************
+ 
+   A debug packet whose contents are <data>
+   is encapsulated for transmission in the form:
+ 
+        $ <data> # CSUM1 CSUM2
+ 
+        <data> must be ASCII alphanumeric and cannot include characters
+        '$' or '#'.  If <data> starts with two characters followed by
+        ':', then the existing stubs interpret this as a sequence number.
+ 
+        CSUM1 and CSUM2 are ascii hex representation of an 8-bit
+        checksum of <data>, the most significant nibble is sent first.
+        the hex digits 0-9,a-f are used.
+ 
+   Receiver responds with:
+ 
+        +       - if CSUM is correct and ready for next packet
+        -       - if CSUM is incorrect
+ 
+   <data> is as follows:
+   All values are encoded in ascii hex digits.
+ 
+        Request         Packet
+ 
+        read registers  g
+        reply           XX....X         Each byte of register data
+                                        is described by two hex digits.
+                                        Registers are in the internal order
+                                        for GDB, and the bytes in a register
+                                        are in the same order the machine uses.
+                        or ENN          for an error.
+ 
+        write regs      GXX..XX         Each byte of register data 
+                                        is described by two hex digits.
+        reply           OK              for success
+                        ENN             for an error
+ 
+        write reg       Pn...=r...      Write register n... with value r...,
+                                        which contains two hex digits for each
+                                        byte in the register (target byte
+                                        order).
+        reply           OK              for success
+                        ENN             for an error
+        (not supported by all stubs).
+ 
+        read mem        mAA..AA,LLLL    AA..AA is address, LLLL is length.
+        reply           XX..XX          XX..XX is mem contents
+                                        Can be fewer bytes than requested
+                                        if able to read only part of the data.
+                        or ENN          NN is errno
+ 
+        write mem       MAA..AA,LLLL:XX..XX
+                                        AA..AA is address,
+                                        LLLL is number of bytes,
+                                        XX..XX is data
+        reply           OK              for success
+                        ENN             for an error (this includes the case
+                                        where only part of the data was
+                                        written).
+ 
+        write mem       XAA..AA,LLLL:XX..XX
+         (binary)                       AA..AA is address,
+                                        LLLL is number of bytes,
+                                        XX..XX is binary data
+        reply           OK              for success
+                        ENN             for an error
+ 
+        cont            cAA..AA         AA..AA is address to resume
+                                        If AA..AA is omitted,
+                                        resume at same address.
+ 
+        last signal     ?               Reply the current reason for stopping.
+                                        This is the same reply as is generated
+                                        for step or cont : SAA where AA is the
+                                        signal number.
+ 
+        There is no immediate reply to step or cont.
+        The reply comes when the machine stops.
+        It is           SAA             AA is the "signal number"
+ 
+        or...           TAAn...:r...;n:r...;n...:r...;
+                                        AA = signal number
+                                        n... = register number
+                                        r... = register contents
+        or...           WAA             The process exited, and AA is
+                                        the exit status.  This is only
+                                        applicable for certains sorts of
+                                        targets.
+        kill request    k
+ 
+        toggle debug    d               toggle debug flag (see 386 & 68k stubs)
+        reset           r               reset -- see sparc stub.
+        reserved        <other>         On other requests, the stub should
+                                        ignore the request and send an empty
+                                        response ($#<checksum>).  This way
+                                        we can extend the protocol and GDB
+                                        can tell whether the stub it is
+                                        talking to uses the old or the new.
+        search          tAA:PP,MM       Search backwards starting at address
+                                        AA for a match with pattern PP and
+                                        mask MM.  PP and MM are 4 bytes.
+                                        Not supported by all stubs. 
+ 
+        general query   qXXXX           Request info about XXXX.
+        general set     QXXXX=yyyy      Set value of XXXX to yyyy.
+        query sect offs qOffsets        Get section offsets.  Reply is
+                                        Text=xxx;Data=yyy;Bss=zzz
+        console output  Otext           Send text to stdout.  Only comes from
+                                        remote target.
+ 
+        Responses can be run-length encoded to save space.  A '*' means that
+        the next character is an ASCII encoding giving a repeat count which
+        stands for that many repititions of the character preceding the '*'.
+        The encoding is n+29, yielding a printable character where n >=3
+        (which is where rle starts to win).  Don't use an n > 126.
+ 
+        So
+        "0* " means the same as "0000".  
+**************************************************************************/  
diff -urN linux-2.4.29/arch/blackfin/kernel/nisa-stub.h linux-2.4.29-uc1/arch/blackfin/kernel/nisa-stub.h
--- linux-2.4.29/arch/blackfin/kernel/nisa-stub.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/kernel/nisa-stub.h	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,1057 @@
+/*
+  GDB stub for BlackFin DSP (in emulation mode).
+
+  Copyright (c) 2001 by Tony Kou of Arcturus Network Com.
+  All right reserved.           tonyko@arcturusnetworks.com
+ 
+  Permission to use, copy and distribute this file
+  is freely granted, as long as this copyright notice
+  is preserved.
+ 
+  This file is provided "as-is", and without any express
+  or implied warranties, including, without limitation,
+  the implied warranties of merchantability and fitness
+  for a particular purpose.
+*/ 
+
+/*
+  This implementation assumes following:
+
+	Application being debugged is always in supervisor mode. User mode is
+	currently not supported.
+
+	Assumes serial port has already been setup for appropriate baud rate.
+	Tested using rate of 115200.
+
+	Application being debugged is in ROM (eg FLASH). This is not a requirement,
+	but simply the reason why this stub was written in the first place. The
+	standard 68K stub would probably work (once serial port stuff was sorted)
+	if application is in RAM.
+
+	This stub supports only a single hardware breakpoint. If external
+	hardware is used then you would need to modify this stub anyway. This does
+	not affect the number of software breakpoints (breakpoints in RAM). GDB
+	handles this by simply reading and writing to RAM (to read op-codes and
+	replace them with breakpoint instructions).
+
+	I have tried to determine if GDB needs more than one breakpoint when single
+	steping through source code. I my limited testing I have not found the GDB
+	needs more than one breakpoint which means that the stub can be used	to
+	single step code. The limitation of one hardware breakpoint means that you
+	can only set a single breakpoint	when running the application from ROM. If
+	you attempt to set more than one breakpoint then this stub simply
+	overwrites the any previous breakpoint with the new one, such that only
+	the last breakpoint set will actually be active. Of course GDB wont know
+	this so it will still think you have multiple breakpoints set.
+
+	Have not check out how hardware breakpoints are set and used directly from
+	GDB UI. Currently only tested against software breakpoints being fudged by
+	this stub setting hardware breakpoints. I think I may need later version
+	of GDB to test this against.
+*/
+
+/* platform-specific stuff */
+void	gdb_putc ( char c );
+char	gdb_getc ( void );
+short	gdb_peek_register_file ( short id, long *val );
+short	gdb_poke_register_file ( short id, long val );
+void	gdb_step ( unsigned long addr );
+void	gdb_continue ( unsigned long addr );
+void	gdb_kill( void );
+void	gdb_return_from_exception( void );
+void	gdb_init(void);
+void	gdb_set_hw_break(unsigned long addr);
+int	gdb_is_rom_addr(long addr);
+void	gdb_write_rom(long len,long addr, const char *hargs);
+
+
+/* platform-neutral stuff */
+long	hex_to_long ( char h );
+char	nibble_to_hex ( char i );
+long	hexbuf_to_long ( short len, const char *hexbuf );
+short	long_to_hexbuf ( long l, char *hexbuf, short pad );
+void	gdb_putmsg ( char c, const char *buf, short len );
+short	gdb_getmsg ( char *rxbuf );
+void	gdb_last_signal ( short sigval );
+void	gdb_expedited ( short sigval );
+void	gdb_read_memory ( const char *hargs );
+void	gdb_write_memory ( const char *hargs );
+void	gdb_console_output( short len, const char *buf );
+void	gdb_write_registers ( char *hargs );
+void	gdb_read_registers ( char *hargs );
+void	gdb_write_register ( char *hargs );
+void	gdb_monitor ( short sigval );
+void	gdb_handle_exception( long sigval );
+unsigned char gdb_putstr ( short len, const char *buf );
+
+
+void gdb_exception_isr(void);
+
+/* Function prototype for above interrupt handler */
+void gdb_int7_isr(void);
+void gdb_aline_isr(void);
+
+#define BYTE_REF(addr)           (*((volatile unsigned char*)addr))
+#define HALFWORD_REF(addr)       (*((volatile unsigned short*)addr))
+#define WORD_REF(addr)           (*((volatile unsigned long*)addr)) 
+
+/********************************************
+
+	BlackFin - periperal register defintions
+	---------------------------------------
+*********************************************/
+
+/* Base address of system MMR registers(2MB) FFC00000 -- FFDFFFFF */
+#define	BLACKFIN_BASE	0xFFC00000
+
+/* Interrupt Registers */
+#define IMASK_ADDR                      0xffe02104 /*  register 32 bit */
+#define IMASK                           WORD(IMASK_ADDR)
+#define IPEND_ADDR                      0xffe02108 /*  register 32 bit */
+#define IPEND                           WORD(IPEND_ADDR)
+#define ILAT_ADDR                       0xffe0210c /*  register 32 bit */
+#define ILAT                            WORD(ILAT_ADDR) 
+
+/* types of interrupts *******************************/
+#define EZ328_INT_EMIQ	0x00800000
+#define EZ328_INT_SAM	0x00400000
+#define EZ328_INT_IRQ5	0x00100000
+#define EZ328_INT_IRQ6	0x00080000
+#define EZ328_INT_IRQ3	0x00040000
+#define EZ328_INT_IRQ2	0x00020000
+#define EZ328_INT_IRQ1	0x00010000
+#define EZ328_INT_INT3	0x00000800
+#define EZ328_INT_INT2	0x00000400
+#define EZ328_INT_INT1	0x00000200
+#define EZ328_INT_INT0	0x00000100
+#define EZ328_INT_PWM	0x00000080
+#define EZ328_INT_KEYB	0x00000040
+#define EZ328_INT_RTC	0x00000010
+#define EZ328_INT_WDT	0x00000008
+#define EZ328_INT_UART	0x00000004
+#define EZ328_INT_TMR	0x00000002
+#define EZ328_INT_SPI	0x00000001
+
+/********************************************
+
+	BlackFin - UART0 register defintions
+	---------------------------------------
+*********************************************/
+#define UART0_THR_ADDR                  0xffc01800  /* UART 0 Transmit holding register  16 bit */
+#define UART0_THR                       HALFWORD_REF(UART0_THR_ADDR)
+
+#define UART0_RBR_ADDR                  0xffc01800  /* UART 0 Receive buffer register  16 bit */
+#define UART0_RBR                       HALFWORD_REF(UART0_RBR_ADDR)
+
+/* Divisor Latch Register used for calculating: Baud Rate = SCLK / (16 * DL)    */
+#define UART0_DLL_ADDR                  0xffc01800  /* UART 0 Divisor latch (low byte) register  16 bit */
+#define UART0_DLL                       HALFWORD_REF(UART0_DLL_ADDR)
+#define UART0_DLH_ADDR                  0xffc01802  /* UART 0 Divisor latch (high byte) register  16 bit */#define UART0_DLH                       HALFWORD_REF(UART0_DLH_ADDR)
+
+#define UART0_IER_ADDR                  0xffc01802  /* UART 0 Interrupt enable register  16 bit */
+#define UART0_IER                       HALFWORD_REF(UART0_IER_ADDR)
+#define UART0_IER_ERBFI                 0x01    /* Enable Receive Buffer Full Interrupt(DR bit) */
+#define UART0_IER_ETBEI                 0x02    /* Enable Transmit Buffer Empty Interrupt(THRE bit) */
+#define UART0_IER_ELSI                  0x04    /* Enable RX Status Interrupt(gen if any of LSR[4:1] set) */
+#define UART0_IER_EDDSI                 0x08    /* Enable Modem Status Interrupt(gen if 
+                                                   any UARTx_MSR[3:0] set) */
+
+#define UART0_IIR_ADDR                  0xffc01804  /* UART 0 Interrupt identification register  16 bit */
+#define UART0_IIR                       HALFWORD_REF(UART0_IIR_ADDR)
+#define UART0_IIR_NOINT                 0x01    /* Bit0: cleared when no interrupt */
+#define UART0_IIR_STATUS                0x06    /* mask bit for the status: bit2-1 */
+#define UART0_IIR_LSR                   0x06    /* Receive line status */
+#define UART0_IIR_RBR                   0x04    /* Receive data ready */
+#define UART0_IIR_THR                   0x02    /* Ready to transmit  */
+#define UART0_IIR_MSR                   0x00    /* Modem status       */ 
+
+#define UART0_LCR_ADDR                  0xffc01806  /* UART 0 Line control register  16 bit */
+#define UART0_LCR                       HALFWORD_REF(UART0_LCR_ADDR)
+#define UART0_LCR_WLS5                  0       /* word length 5 bits */
+#define UART0_LCR_WLS6                  0x01    /* word length 6 bits */
+#define UART0_LCR_WLS7                  0x02    /* word length 7 bits */
+#define UART0_LCR_WLS8                  0x03    /* word length 8 bits */
+#define UART0_LCR_STB                   0x04    /* StopBit: 1: 2 stop bits for non-5-bit word length
+                                                               1/2 stop bits for 5-bit word length
+                                                            0: 1 stop bit */
+#define UART0_LCR_PEN                   0x08    /* Parity Enable 1: for enable */
+#define UART0_LCR_EPS                   0x10    /* Parity Selection: 1: for even pariety
+                                                                     0: odd parity when PEN =1 & SP =0 */
+#define UART0_LCR_SP                    0x20    /* Sticky Parity: */
+#define UART0_LCR_SB                    0x40    /* Set Break: force TX pin to 0 */
+#define UART0_LCR_DLAB                  0x80    /* Divisor Latch Access */
+
+#define UART0_LSR_ADDR                  0xffc0180a  /* UART 0 Line status register  16 bit */
+#define UART0_LSR                       HALFWORD_REF(UART0_LSR_ADDR)
+#define UART0_LSR_DR                    0x01    /* Data Ready */
+#define UART0_LSR_OE                    0x02    /* Overrun Error */
+#define UART0_LSR_PE                    0x04    /* Parity Error  */
+#define UART0_LSR_FE                    0x08    /* Frame Error   */
+#define UART0_LSR_BI                    0x10    /* Break Interrupt */
+#define UART0_LSR_THRE                  0x20    /* THR empty, REady to accept */
+#define UART0_LSR_TEMT                  0x40    /* TSR and UARTx_thr both empty */
+
+/****************************
+ *
+ *  WATCHPOINT & PATCH UNIT REGISTERS  (0XFFC07000 - 0XFFC07200)
+ *
+ ****************************/
+ 
+#define WPIACTL_ADDR                    0xffe07000 /*  register 32 bit */
+#define WPIACTL                         WORD(WPIACTL_ADDR)
+                /* TOTAL OF 6  */
+#define WPIA_ADDR                       0xffe07040 /*  register 32 bit */
+#define WPIA                            WORD(WPIA_ADDR)
+                /* TOTAL OF 6  */
+#define WPIACNT_ADDR                    0xffe07080 /*  register 32 bit */
+#define WPIACNT                         WORD(WPIACNT_ADDR)
+ 
+#define WPDACTL_ADDR                    0xffe07100 /*  register 32 bit */
+#define WPDACTL                         WORD(WPDACTL_ADDR)
+                /* TOTAL OF 2 */
+#define WPDA_ADDR                       0xffe07140 /*  register 32 bit */
+#define WPDA                            WORD(WPDA_ADDR)
+                /* TOTAL OF 2 */
+#define WPDACNT_ADDR                    0xffe07180 /*  register 32 bit */
+#define WPDACNT                         WORD(WPDACNT_ADDR)
+ 
+#define WPSTAT_ADDR                     0xffe07200 /*  register 32 bit */
+#define WPSTAT                          WORD(WPSTAT_ADDR) 
+
+
+
+
+
+/* ICEM registers */
+#define	EZ328_ICEMACR	(*(volatile unsigned long *)(EZ328BASE+0xD00))	/* ICEM address compare reg */
+#define	EZ328_ICEMAMR	(*(volatile unsigned long *)(EZ328BASE+0xD04))	/* ICEM address mask reg */
+#define	EZ328_ICEMCCR	(*(volatile unsigned short *)(EZ328BASE+0xD08))	/* ICEM control compare reg */
+#define	EZ328_ICEMCMR	(*(volatile unsigned short *)(EZ328BASE+0xD0A))	/* ICEM control mask reg */
+#define	EZ328_ICEMCR	(*(volatile unsigned short *)(EZ328BASE+0xD0C))	/* ICEM control reg */
+#define	EZ328_ICEMSR	(*(volatile unsigned short *)(EZ328BASE+0xD0E))	/* ICEM status reg */
+
+/****************************
+ *
+ *  WATCHDOG TIMER  (0XFFC01000 - 0XFFC013F) time = COUNT * SCLK
+ *
+ ****************************/
+ 
+#define WDOGCTL_ADDR                    0xffc01000  /* Watchdog control register  32 bit */
+#define WDOGCTL                         WORD_REF(WDOGCTL_ADDR)
+#define WDOGCNT_ADDR                    0xffc01004  /* Watchdog count register 32 bit */
+#define WDOGCNT                         WORD_REF(WDOGCNT_ADDR)
+#define WDOGSTAT_ADDR                   0xffc01008  /* Watchdog status register 32 bit */
+#define WDOGSTAT                        WORD_REF(WDOGSTAT_ADDR) 
+
+/* Define values for Watchdog register */
+#define WDOGCTL_EN_GP		0x04 /* watchdog invoke GP interrupt: IVG13 */
+#define WDOGCTL_ENABLE		0xF0 /* 0000-1000 and 1110-1111 of Bit: 7-4 enable it */
+#define WDOGCTL_DISABLE		0xE0 /* only 1101 of Bit: 7-4 disable WDOG */
+
+/*********************
+
+	BlackFin - vectors
+	-----------------
+**********************/
+
+/* Macro function to set a vector into the vector table */
+#define SET_VECTOR(vect,func)  	*(unsigned long*)((unsigned long)vect) = (unsigned long)func
+
+/* Invoked by: Watchdog, 
+ * Note: shared with Memory DMA interrupt.
+ */
+#define EVT_IVG13_ADDR		0xffe02034 /*  General purpose interrupt register 32 bit */
+#define EVT_IVG13		WORD(EVT_IVG13_ADDR) 
+
+/* Inviked by: UART0 RCV/XMT or UART1 RCV/XMT    */
+#define EVT_IVG10_ADDR		0xffe02028 /*  General purpose interrupt register 32 bit */
+#define EVT_IVG10		WORD(EVT_IVG10_ADDR)
+
+/* Invoked by: 
+ *    EXCAUSE = 0b010000 :  Single Step
+ *              0b010001 :  Trace Buffer Overflow  
+ *              0b101000 :  Emulation Watch Point Match
+ *              0000-1111:  EXCPT m, and "EXCPT 15" as SW breakpoint
+ */
+#define EVT_EXCEPTION_ADDR	0xffe0200c /* Identification with code in EXCAUSE register 32 bit */
+#define EVT_EXCEPTION		WORD(EVT_EXCEPTION_ADDR)
+#define STEP_BIT		0x02	/* step-bit in SYSCFG register */
+
+/**************************************
+
+	BlackFin - CPU register defintions
+	---------------------------------
+***************************************/
+
+/*
+	There are 51 registers under BlackFin DSP core, for convinience, we treat
+	extended accumulator A0x and A1x as 32-bit reg, though only 8-bit long.
+	The D0-D7,A0-A7,PS,PC registers are 4 unsigned char (32 bit)
+*/
+#define NUMREGBYTES 51*4
+typedef enum
+{
+  R0, R1, R2, R3, R4, R5, R6, R7,
+  P0, P1, P2, P3, P4, P5, SP, FP, USP,
+  I0, I1, I2, I3, M0, M1, M2, M3, 
+  L0, L1, L2, L3, B0, B1, B2, B3,
+  A0x, A0w, A1x, A1w,
+  ASTAT, RETS, RETI, RETX, RETN, RETE,
+  LC0, LC1, LT0, LT1, LB0, LB1,
+  SYSCFG, SEQSTAT
+} regname;
+
+long CPUregisters[NUMREGBYTES/4];
+
+/*************************
+
+	Local stack for stub
+	--------------------
+**************************/
+/*
+	FIXME: Currently not used as code crashes on switching to local stack
+	Reason for needing local stack - Need to consider affect of "inferior" function 
+        calls on application stack
+	When I really figure out what this really means I may look at fixing this.
+*/
+#define STACKSIZE 400
+int localStack[STACKSIZE/sizeof(int)];
+int* localStackPtr = &localStack[STACKSIZE/sizeof(int) - 1];
+
+
+/*************************
+
+	Useful Macro functions
+	----------------------
+**************************/
+
+/* Disable all possible interrupts levels (except NMI, RESET, EMU and EVSW) */
+#define DISABLE_ALL_INTERRUPTS(save)	asm("	%0 = cli;\n\t": "=d" (save));
+
+/* Enable all interrupts levels */
+#define ENABLE_ALL_INTERRUPTS(save)	asm("	sti %0;\n\t": : (d) (save));
+
+/* disable further emulator interrupts - esp level 7*/
+#define DISABLE_EMU_INTERRUPTS()	asm("	ori.l #0x00800000,0xFFFFF304");
+
+
+
+/* SW breakpoint: hope no confilict with others : opcode: 0x00AF(2 Bytes) */
+#define BREAKPOINT()	asm("	excpt 15;\n\t")
+
+
+/* Value related with setting up WP MMR  */
+static const unsigned long ENABLE_INSN_WP[4]=
+	{0x29, 0x51, 0x2801, 0x5001};
+
+static const unsigned long ENABLE_INSN_WP_MASK[4]=
+	{0xFDE7F950, 0xFDE7F8A8, 0xFDE751F8, 0xFDE6A9F8};
+
+/* Value about data address watchpoint MMR registers */
+static const unsigned long ENABLE_DATA_WP_MASK[2]=
+	{ 0xFFFFFC2A, 0xFFFFC3D6}
+
+static const unsigned long ENABLE_DATA_WP[2]=
+	{ 0x54, 0x828}
+
+
+/* enable instruction address watchpoint 1-4 */
+#define ENABLE_INST_WATCHPOINT(num, addr)					\
+	(*((volatile unsigned long*)(WPIACNT_ADDR + num * 4))) &= 0xFFFF0000;	\
+	(*((volatile unsigned long*)(WPIA_ADDR + num * 4))) = (addr & (~1));	\
+	WPIACTL = (WPIACTL & ENABLE_INSN_WP_MASK[num]) | ENABLE_INSN_WP[num];
+	
+#define DISABLE_INST_WATCHPOINT(num, addr)	\
+	WPIACTL &= ~ENABLE_INSN_WP[num]
+
+
+
+/*
+  Generic code to save processor context.
+  Assumes the stack looks like this:
+
+  ....				<--- stack pointer + 6
+  pc(32 bits)			<--- stack pointer + 2
+  sr(16 bits)			<--- stack pointer points here
+*/
+#define SAVE_CONTEXT()			asm("
+	[--sp] = (r7:7, p5:5);
+	p5.l = CPUregisters;
+	p5.h = CPUregisters;
+	[p5++] = r0;
+	[p5++] = r1;
+	[p5++] = r2;
+	[p5++] = r3;
+	[p5++] = r4;
+	[p5++] = r5;
+	[p5++] = r6;
+	[p5++] = r7;
+	[p5++] = p1;
+	[p5++] = p2;
+	[p5++] = p3;
+	[p5++] = p4;
+	r7 = [sp];	/* get original p5 */
+	[p5++] = r7;
+	r7 = sp;
+	r7 += -8;	/* get original sp */
+	[p5++] = r7;
+	[p5++] = fp;
+	r7 = usp;
+	[p5++] = r7;
+
+	r7 = i0;
+	[p5++] = r7;
+	r7 = i1;
+	[p5++] = r7;
+	r7 = i2;
+	[p5++] = r7;
+	r7 = i3;
+	[p5++] = r7;
+
+	r7 = m0;
+	[p5++] = r7;
+	r7 = m1;
+	[p5++] = r7;
+	r7 = m2;
+	[p5++] = r7;
+	r7 = m3;
+	[p5++] = r7;
+
+	r7 = l0;
+	[p5++] = r7;
+	r7 = l1;
+	[p5++] = r7;
+	r7 = l2;
+	[p5++] = r7;
+	r7 = l3;
+	[p5++] = r7;
+		
+
+	r7 = b0;
+	[p5++] = r7;
+	r7 = b1;
+	[p5++] = r7;
+	r7 = b2;
+	[p5++] = r7;
+	r7 = b3;
+	[p5++] = r7;
+
+	r7 = a0x;
+	[p5++] = r7;
+	r7 = a0w;
+	[p5++] = r7;
+	r7 = a1x;
+	[p5++] = r7;
+	r7 = a1w;
+	[p5++] = r7;
+
+	r7 = ASTAT;
+	[p5++] = r7;
+	r7 = RETS;
+	[p5++] = r7;
+	r7 = RETI;
+	[p5++] = r7;
+	r7 = RETX;
+	[p5++] = r7;	/* get breakpoint from here, former pc */
+	r7 = RETN;
+	[p5++] = r7;
+	r7 = RETE;
+	[p5++] = r7;
+	r7 = LC0;
+	[p5++] = r7;
+	r7 = LC1;
+	[p5++] = r7;
+	r7 = LT0;
+	[p5++] = r7;
+	r7 = LT1;
+	[p5++] = r7;
+	r7 = LB0;
+	[p5++] = r7;
+	r7 = LB1;
+	[p5++] = r7;
+	r7 = SYSCFG;
+	[p5++] = r7;
+	r7 = SEQSTAT;
+	[p5++] = r7;
+
+	(r7:7, p5:5) = [sp++];
+
+/*	sp.l = localStackPtr;
+	sp.h = localStackPtr;	*//* switch to local stack - not currently working so commented out! */
+");
+
+/*
+  Stuffs a unsigned char out the serial port.
+ */
+void gdb_putc ( char c )
+{
+	unsigned int temp, temp_uartctl;
+
+	DISABLE_ALL_INTERRUPTS(temp)
+	/* Cant allow UART interrupts while sending */
+	temp_uartctl = UART0_IER;
+	UART0_IER = 0;
+
+	/* wait for space in UART tx  */
+	while (!(UART0_LSR & UART0_LSR_THRE));
+
+	/* place unsigned char from buffer into tx  */
+	UART0_THR =  (unsigned short)c;
+
+	/*
+		Allow UART interrupts now that have finished
+	*/
+	UART0_IER = temp_uartctl | UART0_IER_ETBEI | UART0_IER_ELSI;
+
+	ENABLE_ALL_INTERRUPTS(temp)
+	return;
+}
+
+
+/*
+  Blocks until a unsigned char is received at the serial port.
+ */
+char gdb_getc ( void )
+{
+	unsigned int temp, temp_uartctl;
+	char c;
+	unsigned short rxData;
+
+	DISABLE_ALL_INTERRUPTS(temp)
+	/* Cant allow UART interrupts while sending */
+	temp_uartctl = UART0_IER;
+	UART0_IER = 0;
+
+	/* Do initial read of uart RX register to determine if any characters have been received */
+	rxStatusData = EZ328_URX;
+
+	/* Wait for received data */
+	while ( !(rxData & (UART0_LSR | UART0_LSR_DR ))
+	{
+	   rxData = UART0_RBR;
+
+           /* Tickle H/W watchdog timer *********************/
+	EZ328_WATCHDOG = EZ328_WATCHDOG_ENABLE;
+	}
+
+	/* Assign char received to variable to return - ignore any errors during receive */
+	c = (char)rxStatusData;
+
+	/*
+		Allow UART interrupts now that have finished
+	*/
+	UART0_IER = temp_uartctl | UART0_IER_ERBFI | UART0_IER_ELSI;
+
+	ENABLE_ALL_INTERRUPTS(temp)
+	return c;
+}
+
+
+/*
+  Retrieves a register value from gdb_register_file.
+  Returns the size of the register, in bytes,
+  or zero if an invalid id is specified (which *will*
+  happen--- gdb.c uses this functionality to tell
+  how many registers we actually have).
+ */
+short gdb_peek_register_file ( short id, long *val )
+{
+	/* all supported registers are int (4Bytes) */
+	short retval = sizeof( long );
+
+	if ( (id >= R0) && (id <= SEQSTAT) )
+	{
+		*val = CPUregisters[id];
+	}
+	else
+	{
+		retval = 0;
+	}
+
+  return retval;
+}
+
+
+/*
+  Stuffs a register value into gdb_register_file.
+  Returns the size of the register, in bytes,
+  or zero if an invalid id is specified.
+ */
+short gdb_poke_register_file ( short id, long val )
+{
+	/* all our registers are longs */
+	short retval = sizeof( long );
+
+	if ( (id >= R0) && (id <= SEQSTAT) )
+	{
+		CPUregisters[id] = val;
+	}
+	else
+	{
+		retval = 0;
+	}
+
+	return retval;
+}
+
+
+/*
+  Uses the UBC to generate an exception
+  after we execute the next instruction.
+*****************************************************/
+void gdb_step ( unsigned long addr )
+{
+
+	/* if we're stepping from an address,
+           adjust pc (untested!) */
+  	/* TODO: test gdb_step when PC is supplied */
+	if( addr )
+	{
+           CPUregisters[RETX] = addr;
+	}
+
+	/* set Trace bit in CPU status register */
+	CPUregisters[SYSCFG] |= STEP_BIT;
+
+	/* we're all done now */
+  	return;
+}
+
+
+/*
+  Continue program execution at addr,
+  or at the current pc if addr == 0.
+*/
+void gdb_continue ( unsigned long addr )
+{
+
+  if( addr )
+  {
+    CPUregisters[RETX] = addr;
+  }
+
+  /* Clear Trace bit in CPU status register - in case been tracing */
+  CPUregisters[SYSCFG] &= ~STEP_BIT;
+
+  return;
+}
+
+
+/*
+  Kills the current application.
+  Simulates a reset by jumping to
+  the address taken from the reset
+  vector at address 0.
+ */
+void gdb_kill ( void )
+{
+}
+
+/* Flag for insn & data watchpoint MMR registers:  */
+static unsigned int cur_watch_points = 0;
+static unsigned int cur_watch_range = 0;
+static unsigned int cur_data_points = 0;
+
+
+typedef struct
+{	unsigned long insn_type[4];
+	unsigned long insn_addr[4];
+
+	unsigned long data_mode[2];
+	unsigned long data_addr[2];
+
+	unsigned long insn_range_addr;
+	unsigned long insn_range_len;
+
+	unsigned long data_range_type;
+	unsigned long data_range_addr;
+	unsigned long data_range_len;
+}watch_point_t;
+
+static watch_point_t cur_watch={
+	{-1,-1,-1,-1},
+	{0,  0, 0, 0},
+	{-1, -1},{0 , 0},
+	0, 0, -1, 0, 0};
+
+void gdb_remove_watch(
+	unsigned long type, 
+	unsigned long addr, 
+	unsigned long length)
+{
+     unsigned char i;
+
+     switch (type) {
+	case 1: /* remove hardware breakpoint */
+		if (length && cur_watch_range && (cur_watch.insn_range_addr == addr)
+				&& (cur_watch.insn_range_len == length)){
+		    cur_watch_range = 0;
+		    WPIACTL &= ~0x220000; 
+		 }
+
+		if (!length && cur_watch_points){
+		    i = 0;
+		    while ((cur_watch.insn_type[i] == -1) || (cur_watch.insn_addr[i] != addr) && i<4)
+			i++;
+
+		    if (i < 4){
+			cur_watch.insn_type[i] = -1;
+			cur_watch_points--;
+			DISABLE_INST_WATCHPOINT(i, addr);  
+		     }
+		 }
+		break;
+
+	case 2:  /* remove data hardware address watchpoint */
+	case 3:
+	case 4:
+		if (length && cur_data_points == 3 && data_range_type == type
+			&& data_range_addr == addr && data_range_len == length) {
+		    cur_data_points = 0;
+		    data_range_type = -1;
+
+		    WPDACTL &= ~0x0D;
+		 }
+
+		if (!length && cur_data_points && cur_data_points < 3) {
+		    i = 0;
+		    while (cur_watch.data_mode[i] == -1 || 
+				cur_watch.data_addr[i] != addr || i<2) i++;
+		    if (i < 2) {
+		    	cur_watch.data_mode[i] = -1;
+		    	cur_data_points--;
+
+		    	WPDACTL &= ~(i? 0x9 : 0x5);
+		     }
+		}
+		break;
+		
+
+	case 0: /* remove software breakpoint */
+	} /* end of switch (type)  */
+
+    return;
+}
+
+
+void gdb_insert_watch(
+	unsigned long type,
+	unsigned long addr, 
+	unsigned long length)
+{
+     unsigned char i, mode;
+
+     switch(type){
+	case 1:	/* set hardware breakpoint */
+		if (length && !cur_watch_range){
+		    cur_watch_range =1;
+		    cur_watch.insn_range_addr = addr;
+		    cur_watch.insn_range_len = length;
+
+		    /* enable instruction address range watchpoint to WPIA45 */
+		    (*((volatile unsigned long*)(WPIA_ADDR + 4*4))) = addr & (~1); 
+		    (*((volatile unsigned long*)(WPIA_ADDR + 5*4))) = (addr+length) & (~1); 
+		    (*((volatile unsigned long*)(WPIACNT_ADDR + 4*4))) = 0;
+		    WPIACTL = (WPIACTL & 0xFD81FDFC) | 0x220001;
+		 }
+
+		if (! length && (cur_watch_points < 4)){
+		     i = 0;
+		     while (cur_watch.insn_type[i] != -1 && i<4) i++;
+		     if ( i < 4){
+		     	cur_watch.insn_type[i] = 1;
+		     	cur_watch.insn_addr[i] = addr;
+		     	cur_watch_points++;
+
+		     	ENABLE_INST_WATCHPOINT(i, addr); }
+		  }
+
+		break;
+
+	case 2:	/* data hardware address watchpoint */
+	case 3:
+	case 4:
+		if (length && !cur_data_points){ /* ok to set up data addr WP */
+		    cur_data_points = 3; /* no way to set seperate data addr WP */
+		    data_range_type = type;
+		    data_range_addr = addr;
+		    data_range_len = length;
+
+		    (*((volatile unsigned long*)WPDA_ADDR)) = addr;
+		    (*((volatile unsigned long*)(WPDA_ADDR + 4))) = addr + length;
+		    WPDACNT &= 0xFFFF0000; /* only need set up WPDACNT0  */
+		    WPDACTL = (WPDACTL & 0xFFFFF020) | 0x851 | ((type-1) << 8);
+		}
+
+		if (!length && cur_data_points < 2) {
+		    i = 0;
+		    while (cur_watch.data_mode[i] != -1 && i < 2) i++;
+		    if (i < 2) {
+			cur_watch.data_mode[i] = 1;
+			cur_watch.data_addr[i] = addr;
+			cur_data_points++;
+
+		    (*((volatile unsigned long*)(WPDA_ADDR + i*4))) = addr;
+		    (*((volatile unsigned long*)(WPDACNT_ADDR + i*4))) &= 0xFFFF0000;
+		    WPDACTL = (WPDACTL & ENABLE_DATA_WP_MASK[i]) | ENABLE_DATA_WP[i] 
+				| ((type-1) << (i? 12 : 8);
+		     }
+		 }
+		break;
+		     
+	caes 0: /* software breakpoint */
+
+	}
+
+    return; 
+}   
+
+
+
+/*
+	EXCEPTION ISR (Single step/software breakpoint: EXCPT 15)
+*/
+asm("
+.align 2
+.global gdb_exception_isr;
+.type gdb_exception_isr, STT_FUNC;
+gdb_exception_isr:
+");
+	SAVE_CONTEXT();
+
+	//DISABLE_EMU_INTERRUPTS();  ***************
+
+asm("
+	/* Put SIGTRAP on R0 as arg of gdb_handle_exception(long sigval) */
+	R1 = SEQSTAT;
+	R1 <<= 26;
+	R1 >>= 26;	/* get the EXCAUSE field */
+	R0 = 0xf(Z);	/* EXCPT 15 happen */
+	CC = R1 == R0;
+	BRT 1f;
+
+	R0 = 0x10(Z);	/* single step */
+	CC = R1 == R0;
+	BRT 1f;
+
+	R0 = 0x28(Z);	/* Watchpoint match invoked*/
+	CC = R1 == R0;
+	BRF gdb_return_from_exception;
+1:	
+	R0 = 5(Z);
+	call	 gdb_handle_exception;	/* never returns to here! */
+
+/*
+  Restores registers to the values specified in CPUregisters
+*/
+gdb_return_from_exception:
+	p0.l = CPUregisters;
+	p0.h = CPUregisters;
+	p0 += 200;	// point to end of CPUregisters.
+	r0 = [p0--];
+	seqstat = r0;
+	r0 = [p0--];
+	syscfg = r0;
+	r0 = [p0--];
+	lb1 = r0;
+	r0 = [p0--];
+	lb0 = r0;
+	r0 = [p0--];
+	lt1 = r0;
+	r0 = [p0--];
+	lt0 = r0;
+	r0 = [p0--];
+	lc1 = r0;
+	r0 = [p0--];
+	lc0 = r0;
+	r0 = [p0--];
+	rete = r0;
+	r0 = [p0--];
+	retn = r0;
+	r0 = [p0--];
+	retx = r0;
+	r0 = [p0--];
+	reti = r0;
+	r0 = [p0--];
+	rets = r0;
+	r0 = [p0--];
+	astat = r0;
+	
+	r0 = [p0--];
+	a1w = r0;
+	r0 = [p0--];
+	a1x = r0;
+	r0 = [p0--];
+	a0w = r0;
+	r0 = [p0--];
+	a0x = r0;
+
+	r0 = [p0--];
+	b3 = r0;
+	r0 = [p0--];
+	b2 = r0;
+	r0 = [p0--];
+	b1 = r0;
+	r0 = [p0--];
+	b0 = r0;
+
+	r0 = [p0--];
+	l3 = r0;
+	r0 = [p0--];
+	l2 = r0;
+	r0 = [p0--];
+	l1 = r0;
+	r0 = [p0--];
+	l0 = r0;
+
+	r0 = [p0--];
+	m3 = r0;
+	r0 = [p0--];
+	m2 = r0;
+	r0 = [p0--];
+	m1 = r0;
+	r0 = [p0--];
+	m0 = r0;
+
+	r0 = [p0--];
+	i3 = r0;
+	r0 = [p0--];
+	i2 = r0;
+	r0 = [p0--];
+	i1 = r0;
+	r0 = [p0--];
+	i0 = r0;
+
+	r0 = [p0--];
+	usp = r0;
+	fp = [p0--];
+	sp = [p0--];
+	p5 = [p0--];
+	p4 = [p0--];
+	p3 = [p0--];
+	p2 = [p0--];
+	p1 = [p0--];
+	r0 = [p0--];
+	[--sp] = r0;	/* temp save p0 to system stack */
+
+	r7 = [p0--];
+	r6 = [p0--];
+	r5 = [p0--];
+	r4 = [p0--];
+	r3 = [p0--];
+	r2 = [p0--];
+	r1 = [p0--];
+	r0 = [p0--];
+	p0 = [sp++];	/* restore p0 and system stack */
+
+
+	andi.l #0xFF7FFFFF,0xFFFFF304 /* IMR - enable emulator interrupts */
+ 	move.w 0xFFFFFD0E,0xFFFFFD0E	/* ICEMSR - clear status bits */
+
+	rtx;	  /* return from exception! */
+");
+
+
+void gdb_init(void)
+{
+	/* Set vector for step and EXCPT 15 interrupts */
+   SET_VECTOR(EVT_EXCEPTION_ADDR,gdb_exception_isr);
+
+
+	/* initialize watchpoint MMR: disable every watchpoints
+           and enable watch point unit, also enable WPIREN */
+   WPDACTL |= 0xFC020001;
+   WPDACTL = 0;
+   WPSTAT = 0;	/* clear WP status register */
+
+
+
+   SET_VECTOR(TRAP_1_VECTOR,gdb_traceTrap_isr);
+
+   /* Vectors for emulation mode */
+	SET_VECTOR(INT_LEVEL_7_VECTOR,gdb_int7_isr);
+	SET_VECTOR(A_LINE_VECTOR,gdb_aline_isr);
+
+
+	/* Enable EMUIRQ signal to cause interrupt */
+	EZ328_PGSEL &= ~0x04;
+	EZ328_PGPUEN |= 0x04;
+
+   EZ328_ICEMSR = EZ328_ICEMSR;	/* ICEMSR - clear status bits to avoid immediate interrupt */
+
+	/* enable emulator breakpoints */
+	EZ328_IMR &= ~EZ328_INT_EMIQ;
+
+	BREAKPOINT();	/* Causes control to be passed to GDB stub */
+}
+
+int gdb_is_rom_addr(long addr)
+{
+	return (int)((addr >= 0x800000L) && (addr < 0xC00000L ));
+}
+
+void gdb_write_rom(long len,long addr, const char *hargs)
+{
+  /*
+  	Test for special case of attempting to write a trap #1 op-code (0x4E41) to flash memory
+	In this case do a hardware breakpoint instead
+	Ignore all other cases - ie simply dont write anything.
+  */
+	if ( len == 2 )
+	{
+   	if (hexbuf_to_long( sizeof( short ) * 2, hargs ) == 0x4e41L)
+      	    gdb_set_hw_break(addr);
+	}
+}
+
+void gdb_set_hw_break(unsigned long addr)
+{
+	EZ328_ICEMACR = addr;
+	EZ328_ICEMAMR = 0x00000000;	/* full address matches only */
+	EZ328_ICEMCCR = 0x0003;			/* read instruction breakpoint */
+	EZ328_ICEMCMR = 0x0000;			/* Dont mask read/write and data/instruction matching */
+	EZ328_ICEMCR = 0x001F;			/* Enable int7 for Bus breakpoint, disable hardmap, Single breakpoint,
+												program break, Enable compare */
+}
+short lastICEMSR;
+
+/*
+	HW breakpoint ISR
+*/
+asm("
+   .global gdb_int7_isr
+gdb_int7_isr:
+");
+DISABLE_EMU_INTERRUPTS();
+ENABLE_ALL_INTERRUPTS();	/* A bit controversial - should interrupts be enabled after a breakpoint - remove this if not */
+SAVE_CONTEXT();
+asm("
+	move.w 0xFFFFFD0E, %d0	/* read current ICEMSR */
+   move.w %d0,lastICEMSR	/* save it  */
+	btst	 #1,%d0		/* test for a-line exception - instruction breakpoint */
+	beq	 clearStatus
+							/* remove a-line exception frame to get at real frame */
+	move.w	6(%sp),66(%a0)		/* Save SR to CPUregisters */
+	move.l	8(%sp),68(%a0)		/* Save PC to CPUregisters */
+	addi.l	#6,60(%a0)  	 /* fixup saved stack pointer to position prior to interrupt */
+
+clearStatus:
+ 	move.w 0xFFFFFD0E,0xFFFFFD0E	/* ICEMSR - clear status bits */
+	andi.w #0xFFFE,0xFFFFFD0C		/* ICEMCR - disable further breakpoint interrupts */
+
+	/* Push SIGTRAP on STACK(local) */
+	move.l #5, -(%sp)
+	jsr	 gdb_handle_exception /* never returns to here! */
+");
+
+/*
+	Simply return from a-line exception
+	Will get an a-line exception as well as int7 exception for certains types of breakpoints.
+	But get an int7 exception for all types of breakpoints, so can simply ignore all a-line exceptions.
+*/
+asm("
+	.global gdb_aline_isr
+gdb_aline_isr:
+	rte
+");
+
diff -urN linux-2.4.29/arch/blackfin/kernel/process.c linux-2.4.29-uc1/arch/blackfin/kernel/process.c
--- linux-2.4.29/arch/blackfin/kernel/process.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/kernel/process.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,331 @@
+/*
+ *  linux/arch/frionommu/kernel/process.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ *
+ *
+ *  uClinux changes Copyright (C) 2000, Lineo, davidm@lineo.com
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+/*   Changes made for FRIO by Akbar Hussain Lineo Inc., July 2001  */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/reboot.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+#include <asm/segment.h>
+
+/*
+ * Initial task structure. Make this a per-architecture thing,
+ * because different architectures tend to have different
+ * alignment requirements and potentially different initial
+ * setup.
+ */
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS;
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+union task_union init_task_union
+__attribute__((section(".data.init_task"), aligned(KTHREAD_SIZE)))
+	= { task: INIT_TASK(init_task_union.task) };
+
+asmlinkage void ret_from_fork(void);
+
+
+/*
+ * The idle loop on FRIO 
+ */
+static void default_idle(void)
+{
+	while(1) {
+		if (!current->need_resched)
+			__asm__("idle;\n\t" : : : "cc"); 
+	/* for FRIO idle_req bit of SEQSTAT is set, and also idle is supervisor
+	 * mode insn, need "SSYNC" ???  Tony */
+
+		schedule();
+	}
+}
+
+void (*frio_idle)(void) = default_idle;
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle(void)
+{
+	/* endless idle loop with no priority at all */
+	init_idle(); /* In sched.c (Generic) */
+	current->nice = 20;
+	current->counter = -100;
+	frio_idle();
+}
+
+void machine_restart(char * __unused)
+{
+	if (mach_reset)
+		mach_reset();  
+/*  Frio 1st system event is for machine setup, see setup.c */
+	for (;;);
+}
+
+void machine_halt(void)
+{
+	if (mach_halt)
+		mach_halt(); /* NULL see setup.c, ? have hardware support */
+	for (;;);
+}
+
+void machine_power_off(void)
+{
+	if (mach_power_off)
+		mach_power_off(); /* NULL see setup.c */
+	for (;;);
+}
+
+void show_regs(struct pt_regs * regs)
+{
+	printk("\n");
+	printk("PC: %08lu  Status: %04lu  SysStatus: %04lu  RETS: %08lu\n",
+	       regs->pc, regs->astat, regs->seqstat, regs->rets);
+	printk("A0.x: %08lx  A0.w: %08lx  A1.x: %08lx  A1.w: %08lx\n",
+	       regs->a0x, regs->a0w, regs->a1x, regs->a1w);
+	printk("P0: %08lx  P1: %08lx  P2: %08lx  P3: %08lx\n",
+	       regs->p0, regs->p1, regs->p2, regs->p3);
+	printk("P4: %08lx  P5: %08lx\n",
+	       regs->p4, regs->p5);
+	printk("R0: %08lx  R1: %08lx  R2: %08lx  R3: %08lx\n",
+	       regs->r0, regs->r1, regs->r2, regs->r3);
+	printk("R4: %08lx  R5: %08lx  R6: %08lx  R7: %08lx\n",
+	       regs->r4, regs->r5, regs->r6, regs->r7);
+
+	/* PS_S should be 0x0c00, to expect the 0b00 value in SEQSTAT's bit 11:10 */
+	if (!(regs->seqstat & PS_S))
+		printk("USP: %08lx\n", rdusp());
+}
+
+/*
+ * Create a kernel thread
+ */
+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	long retval;
+	long clone_arg = flags | CLONE_VM;
+	unsigned long t_hold_sp;
+
+	__asm__ __volatile__ (
+			"r1 = sp; \n\t"		/* movel	%%sp, %%d2\n\t"*/
+			"r0 = %6; \n\t"		/* movel	%5, %%d1\n\t" */
+			"r5 = %2; \n\t"		/* movel	%1, %%d0\n\t" */
+			"excpt 0; \n\t"		/* trap		#0\n\t" */
+			"%1 = sp; \n\t"		/* cmpl		%%sp, %%d2\n\t" */
+			"cc = %1 == r1; \n\t"
+			"if cc jump 1f; \n\t"		/* jeq		1f\n\t" */
+			"r0 = %4; \n\t"		/* movel	%3, %%sp@-\n\t"*/
+			"call (%5); \n\t"	/* jsr		%4@\n\t" */
+			"r5 = %3; \n\t"		/* movel	%2, %%d0\n\t" */
+			"excpt 0; \n"		/* trap		#0\n" */
+			"1:"
+		: "=d" (retval), "=d" (t_hold_sp)
+		: "i" (__NR_clone),
+		  "i" (__NR_exit),
+		  "a" (arg),
+		  "a" (fn),
+		  "a" (clone_arg)
+		: "CC", "R0", "R1", "R2", "R5");
+
+	return retval;
+}
+
+void flush_thread(void)
+{
+}
+
+/*
+ * "frio_fork()".. By the time we get here, the
+ * non-volatile registers have also been saved on the
+ * stack. We do some ugly pointer stuff here.. (see
+ * also copy_thread)
+ */
+
+asmlinkage int frio_fork(struct pt_regs *regs)  
+/* Need to change the name in /platform/.../entry.S */
+{
+#ifdef NO_MM
+	/* fork almost works,  enough to trick you into looking elsewhere :-( */
+	return(-EINVAL);
+#else
+	return do_fork(SIGCHLD, rdusp(), regs, 0);
+#endif
+}
+
+asmlinkage int frio_vfork(struct pt_regs *regs)   
+/* Need to change the name in /platform/.../entry.S */
+{
+	unsigned long newsp;
+
+	newsp = regs->r1;
+	if (!newsp)
+	   newsp = rdusp();
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0);
+}
+
+asmlinkage int frio_clone(struct pt_regs *regs) 
+/* Need to change the name in /platform/.../entry.S */
+{
+	unsigned long clone_flags;
+	unsigned long newsp;
+
+	/* syscall2 puts clone_flags in r0 and usp in r1 */
+	clone_flags = regs->r0;
+	newsp = regs->r1;
+	if (!newsp)
+	   newsp = rdusp();
+	return do_fork(clone_flags, newsp, regs, 0);
+}
+
+int copy_thread(int nr, unsigned long clone_flags,
+		unsigned long usp, unsigned long topstk,
+		struct task_struct * p, struct pt_regs * regs)
+{
+	struct pt_regs * childregs;
+	unsigned long stack_offset;
+
+	stack_offset = KTHREAD_SIZE - sizeof(struct pt_regs);
+	childregs = (struct pt_regs *) ((unsigned long) p + stack_offset);
+
+	*childregs = *regs;
+	childregs->r0 = 0;
+
+	p->thread.usp = usp;
+
+	/* eeks we should be this from copy_thread and not try to construct
+	 * ourselves. We'll get in trouble if we get a sys_clone from user
+	 * space - amit */
+
+	p->thread.ksp = (unsigned long)childregs;
+	p->thread.pc = (unsigned long)ret_from_fork;
+
+	return 0;
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs * regs, struct user * dump)
+{
+
+/* changed the size calculations - should hopefully work better. lbt */
+	dump->magic = CMAGIC;
+	dump->start_code = 0;
+	dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
+	dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
+	dump->u_dsize = ((unsigned long) (current->mm->brk +
+					  (PAGE_SIZE-1))) >> PAGE_SHIFT;
+	dump->u_dsize -= dump->u_tsize;
+	dump->u_ssize = 0;
+
+	if (dump->start_stack < TASK_SIZE)
+		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
+
+	dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump);
+	dump->regs.r0 = regs->r0;
+	dump->regs.r1 = regs->r1;
+	dump->regs.r2 = regs->r2;
+	dump->regs.r3 = regs->r3;
+	dump->regs.r4 = regs->r4;
+	dump->regs.r5 = regs->r5;
+	dump->regs.r6 = regs->r6;
+	dump->regs.r7 = regs->r7;
+	dump->regs.p0 = regs->p0;
+	dump->regs.p1 = regs->p1;
+	dump->regs.p2 = regs->p2;
+	dump->regs.p3 = regs->p3;
+	dump->regs.p4 = regs->p4;
+	dump->regs.p5 = regs->p5;
+	dump->regs.orig_r0 = regs->orig_r0;
+	dump->regs.a0w = regs->a0w;
+	dump->regs.a1w = regs->a1w;
+	dump->regs.a0x = regs->a0x;
+	dump->regs.a1x = regs->a1x;
+	dump->regs.rets = regs->rets;
+	dump->regs.astat = regs->astat;
+	dump->regs.pc = regs->pc;
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage int sys_execve(struct pt_regs regs)
+{
+	int error;
+	char * filename;
+
+	lock_kernel();
+	filename = getname((char *)regs.r0);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+	error = do_execve(filename, (char **)regs.r1, (char **)regs.r2, &regs);
+	putname(filename);
+out:
+	unlock_kernel();
+	return error;
+}
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+#define first_sched	((unsigned long) scheduling_functions_start_here)
+#define last_sched	((unsigned long) scheduling_functions_end_here)
+
+unsigned long get_wchan(struct task_struct *p)
+{
+	unsigned long fp, pc;
+	unsigned long stack_page;
+	int count = 0;
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	stack_page = (unsigned long)p;
+	fp = p->thread.usp;
+	do {
+		if (fp < stack_page+sizeof(struct task_struct) ||
+		    fp >= 8184+stack_page)
+			return 0;
+		pc = ((unsigned long *)fp)[1];
+		/* FIXME: This depends on the order of these functions. */
+		if (pc < first_sched || pc >= last_sched)
+			return pc;
+		fp = *(unsigned long *) fp;
+	} while (count++ < 16);
+	return 0;
+}
diff -urN linux-2.4.29/arch/blackfin/kernel/ptrace.c linux-2.4.29-uc1/arch/blackfin/kernel/ptrace.c
--- linux-2.4.29/arch/blackfin/kernel/ptrace.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/kernel/ptrace.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,399 @@
+/*
+ *  linux/arch/m68k/kernel/ptrace.c
+ *
+ *  Copyright (C) 1994 by Hamish Macdonald
+ *  Taken from linux/kernel/ptrace.c and modified for M680x0.
+ *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/config.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+
+/*   Changes for FRIO made by TONY & AKBAR HUSSAIN   Lineo Inc. */
+
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/* determines which bits in the ASTAT reg the user has access to. */
+/* 1 = access 0 = no access */
+//#define ASTAT_MASK 0x017f   /* FRIO ASTAT reg */
+
+/* determines which bits in the SYSCFG reg the user has access to. */
+/* 1 = access 0 = no access */
+#define SYSCFG_MASK 0x0007   /* FRIO SYSCFG reg */
+/* sets the trace bits. */
+#define TRACE_BITS 0x0001
+
+/* Find the stack offset for a register, relative to thread.esp0. */
+#define PT_REG(reg)	((long)&((struct pt_regs *)0)->reg)
+
+/* Mapping from PT_xxx to the stack offset at which the register is
+   saved.  Notice that usp has no stack-slot and needs to be treated
+   specially (see get_reg/put_reg below). */
+static int regoff[] = {
+	PT_REG(r3), PT_REG(r4), PT_REG(r2), PT_REG(r1),
+	PT_REG(p5), PT_REG(p4), PT_REG(p3), PT_REG(p2), PT_REG(p1), PT_REG(p0),
+	PT_REG(r7), PT_REG(r6), PT_REG(r5),
+	PT_REG(pc),
+	PT_REG(seqstat), PT_REG(astat), PT_REG(rets),
+	PT_REG(a1w),     PT_REG(a0w),   PT_REG(a1x), PT_REG(a0x),
+	PT_REG(orig_r0), PT_REG(r0),
+	PT_REG(usp), PT_REG(fp),
+	PT_REG(ipend),
+	PT_REG(syscfg)
+};
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+static inline long get_reg(struct task_struct *task, int regno)
+{
+	unsigned long *addr;
+	regno /= 4;
+	if (regno == PT_USP / 4)
+		addr = &task->thread.usp;
+	else if (regno < sizeof(regoff)/sizeof(regoff[0]))
+		addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
+	else
+		return 0;
+	return *addr;
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static inline int put_reg(struct task_struct *task, int regno,
+			  unsigned long data)
+{
+	unsigned long *addr;
+	regno /= 4;
+	if (regno == PT_USP / 4)
+		addr = &task->thread.usp;
+	else if (regno < sizeof(regoff)/sizeof(regoff[0]))
+		addr = (unsigned long *) (task->thread.esp0 + regoff[regno]);
+	else
+		return -1;
+	*addr = data;
+	return 0;
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching...
+ *
+ * Make sure the single step bit is not set.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+	/* XXX: Not supported yet. */
+}
+
+asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	unsigned long flags = 0;
+	int ret;
+
+	lock_kernel();
+	ret = -EPERM;
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED)
+			goto out;
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		ret = 0;
+		goto out;
+	}
+	ret = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	read_unlock(&tasklist_lock);	/* FIXME!!! */
+	if (!child)
+		goto out;
+	ret = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out;
+	if (request == PTRACE_ATTACH) {
+		if (child == current)
+			goto out;
+		if ((!child->task_dumpable ||
+		    (current->uid != child->euid) ||
+		    (current->uid != child->suid) ||
+		    (current->uid != child->uid) ||
+	 	    (current->gid != child->egid) ||
+		    (current->gid != child->sgid) ||
+	 	    (!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
+	 	    (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
+			goto out;
+		/* the same process cannot be attached many times */
+		if (child->ptrace & PT_PTRACED)
+			goto out;
+		child->ptrace |= PT_PTRACED;
+
+		write_lock_irqsave(&tasklist_lock, flags);
+		if (child->p_pptr != current) {
+			REMOVE_LINKS(child);
+			child->p_pptr = current;
+			SET_LINKS(child);
+		}
+		write_unlock_irqrestore(&tasklist_lock, flags);
+
+		send_sig(SIGSTOP, child, 1);
+		ret = 0;
+		goto out;
+	}
+	ret = -ESRCH;
+	if (!(child->ptrace & PT_PTRACED))
+		goto out;
+	if (child->state != TASK_STOPPED) {
+		if (request != PTRACE_KILL)
+			goto out;
+	}
+	if (child->p_pptr != current)
+		goto out;
+
+	switch (request) {
+	/* when I and D space are separate, these will need to be fixed. */
+		case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+		case PTRACE_PEEKDATA: {
+			unsigned long tmp;
+			int copied;
+
+			copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+			ret = -EIO;
+			if (copied != sizeof(tmp))
+				goto out;
+			ret = put_user(tmp,(unsigned long *) data);
+			goto out;
+		}
+
+	/* read the word at location addr in the USER area. */
+		case PTRACE_PEEKUSR: {
+			unsigned long tmp;
+			
+			ret = -EIO;
+			if ((addr & 3) || addr < 0 || (addr >= sizeof(struct user_regs_struct)&&(addr!=(49*4))&&(addr!=(50*4))&&(addr!=(51*4))))
+				goto out;
+			
+			tmp = 0;  /* Default return condition */
+			addr = addr >> 2; /* temporary hack. */
+			ret = -EIO;
+			if (addr < 27) {
+				tmp = get_reg(child, addr * 4);
+			} else if (addr == 49) {
+				tmp = child->mm->start_code;
+			} else if (addr == 50) {
+				tmp = child->mm->start_data;
+			} else if (addr == 51) {
+				tmp = child->mm->end_code;
+			} else
+				goto out;
+			ret = put_user(tmp,(unsigned long *) data);
+			goto out;
+		}
+
+      /* when I and D space are separate, this will have to be fixed. */
+		case PTRACE_POKETEXT: /* write the word at location addr. */
+		case PTRACE_POKEDATA:
+			ret = 0;
+			if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+				goto out;
+			ret = -EIO;
+			goto out;
+
+		case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+			ret = -EIO;
+			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user_regs_struct))
+				goto out;
+
+			if (addr == PT_SYSCFG) {
+				data &= SYSCFG_MASK;
+				data |= get_reg(child, PT_SYSCFG);
+			}
+			if (addr < 27 * 4) 
+				ret = put_reg(child, addr, data);
+			goto out;
+
+		case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+		case PTRACE_CONT: { /* restart after signal. */
+			long tmp;
+
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				goto out;
+			child->ptrace &= ~PT_TRACESYS;
+			child->exit_code = data;
+			/* make sure the single step bit is not set. */
+			tmp = get_reg(child, PT_SYSCFG) & ~(TRACE_BITS);
+			put_reg(child, PT_SYSCFG, tmp);
+			wake_up_process(child);
+			ret = 0;
+			goto out;
+		}
+
+/*
+ * make the child exit.  Best I can do is send it a sigkill. 
+ * perhaps it should be put in the status that it wants to 
+ * exit.
+ */
+		case PTRACE_KILL: {
+			long tmp;
+
+			ret = 0;
+			if (child->state == TASK_ZOMBIE) /* already dead */
+				goto out;
+			child->exit_code = SIGKILL;
+	/* make sure the single step bit is not set. */
+			tmp = get_reg(child, PT_SYSCFG) & ~(TRACE_BITS);
+			put_reg(child, PT_SYSCFG, tmp);
+			wake_up_process(child);
+			goto out;
+		}
+
+		case PTRACE_SINGLESTEP: {  /* set the trap flag. */
+			long tmp;
+
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				goto out;
+			child->ptrace &= ~PT_TRACESYS;
+			tmp = get_reg(child, PT_SYSCFG) | (TRACE_BITS);
+			put_reg(child, PT_SYSCFG, tmp);
+
+			child->exit_code = data;
+	/* give it a chance to run. */
+			wake_up_process(child);
+			ret = 0;
+			goto out;
+		}
+
+		case PTRACE_DETACH: { /* detach a process that was attached. */
+			long tmp;
+
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				goto out;
+			child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
+			child->exit_code = data;
+			write_lock_irqsave(&tasklist_lock, flags);
+			REMOVE_LINKS(child);
+			child->p_pptr = child->p_opptr;
+			SET_LINKS(child);
+			write_unlock_irqrestore(&tasklist_lock, flags);
+			/* make sure the single step bit is not set. */
+			tmp = get_reg(child, PT_SYSCFG) & ~(TRACE_BITS);
+			put_reg(child, PT_SYSCFG, tmp);
+			wake_up_process(child);
+			ret = 0;
+			goto out;
+		}
+
+		case PTRACE_GETREGS: { /* Get all gp regs from the child. */
+#if 0	/* not used for nisa at present -- STchen */
+		  	int i;
+			unsigned long tmp;
+			for (i = 0; i < 42; i++) {
+			    tmp = get_reg(child, i);
+			    
+			    if (put_user(tmp, (unsigned long *) data)) {
+				ret = -EFAULT;
+				goto out;
+			    }
+			    data += sizeof(long);
+			}
+#endif
+			ret = 0;
+			goto out;
+		}
+
+		case PTRACE_SETREGS: { /* Set all gp regs in the child. */
+#if 0
+			int i;
+			unsigned long tmp;
+			for (i = 0; i < 42; i++) {
+			    if (get_user(tmp, (unsigned long *) data)) {
+				ret = -EFAULT;
+				goto out;
+			    }
+			    if (i == PT_SYSCFG) {
+				tmp &= SYSCFG_MASK;
+				tmp |= get_reg(child, PT_SYSCFG) & ~(SYSCFG_MASK);
+			    }
+			    put_reg(child, i, tmp);
+			    data += sizeof(long);
+			}
+#endif
+			ret = 0;
+			goto out;
+		}
+
+#ifdef PTRACE_GETFPREGS
+		case PTRACE_GETFPREGS: { /* Get the child FPU state. */
+			ret = 0;
+			if (copy_to_user((void *)data, &child->thread.fp,
+					 sizeof(struct user_m68kfp_struct)))
+				ret = -EFAULT;
+			goto out;
+		}
+#endif
+
+#ifdef PTRACE_SETFPREGS
+		case PTRACE_SETFPREGS: { /* Set the child FPU state. */
+			ret = 0;
+			if (copy_from_user(&child->thread.fp, (void *)data,
+					   sizeof(struct user_m68kfp_struct)))
+				ret = -EFAULT;
+			goto out;
+		}
+#endif
+
+		default:
+			ret = -EIO;
+			goto out;
+	}
+out:
+	unlock_kernel();
+	return ret;
+}
+
+asmlinkage void syscall_trace(void)
+{
+	lock_kernel();
+	if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
+			!= (PT_PTRACED|PT_TRACESYS))
+		goto out;
+	current->exit_code = SIGTRAP;
+	current->state = TASK_STOPPED;
+	notify_parent(current, SIGCHLD);
+	schedule();
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+out:
+	unlock_kernel();
+}
diff -urN linux-2.4.29/arch/blackfin/kernel/semaphore.c linux-2.4.29-uc1/arch/blackfin/kernel/semaphore.c
--- linux-2.4.29/arch/blackfin/kernel/semaphore.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/kernel/semaphore.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,131 @@
+/*
+ * Just taken from alpha implementation.
+ * This can't work well, perhaps.
+ */
+/*
+ *  Generic semaphore code. Buyer beware. Do your own
+ * specific changes in <asm/semaphore-helper.h>
+ */
+
+#include <linux/sched.h>
+#include <asm/semaphore-helper.h>
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to sleep, while the "waking" variable is
+ * incremented when the "up()" code goes to wake up waiting
+ * processes.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * waking_non_zero() (from asm/semaphore.h) must execute
+ * atomically.
+ *
+ * When __up() is called, the count was negative before
+ * incrementing it, and we need to wake up somebody.
+ *
+ * This routine adds one to the count of processes that need to
+ * wake up and exit.  ALL waiting processes actually wake up but
+ * only the one that gets to the "waking" field first will gate
+ * through and acquire the semaphore.  The others will go back
+ * to sleep.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+void __up(struct semaphore *sem)
+{
+	wake_one_more(sem);
+	wake_up(&sem->wait);
+}
+
+/*
+ * Perform the "down" function.  Return zero for semaphore acquired,
+ * return negative for signalled out of the function.
+ *
+ * If called from __down, the return is ignored and the wait loop is
+ * not interruptible.  This means that a task waiting on a semaphore
+ * using "down()" cannot be killed until someone does an "up()" on
+ * the semaphore.
+ *
+ * If called from __down_interruptible, the return value gets checked
+ * upon return.  If the return value is negative then the task continues
+ * with the negative value in the return register (it can be tested by
+ * the caller).
+ *
+ * Either form may be used in conjunction with "up()".
+ *
+ */
+
+#define DOWN_HEAD(task_state)						\
+									\
+									\
+	current->state = (task_state);					\
+	add_wait_queue(&sem->wait, &wait);				\
+									\
+	/*								\
+	 * Ok, we're set up.  sem->count is known to be less than zero	\
+	 * so we must wait.						\
+	 *								\
+	 * We can let go the lock for purposes of waiting.		\
+	 * We re-acquire it after awaking so as to protect		\
+	 * all semaphore operations.					\
+	 *								\
+	 * If "up()" is called before we call waking_non_zero() then	\
+	 * we will catch it right away.  If it is called later then	\
+	 * we will have to go through a wakeup cycle to catch it.	\
+	 *								\
+	 * Multiple waiters contend for the semaphore lock to see	\
+	 * who gets to gate through and who has to wait some more.	\
+	 */								\
+	for (;;) {
+
+#define DOWN_TAIL(task_state)			\
+		current->state = (task_state);	\
+	}					\
+	current->state = TASK_RUNNING;		\
+	remove_wait_queue(&sem->wait, &wait);
+
+void __down(struct semaphore * sem)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	DOWN_HEAD(TASK_UNINTERRUPTIBLE)
+	if (waking_non_zero(sem))
+		break;
+	schedule();
+	DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int ret = 0;
+
+	DOWN_HEAD(TASK_INTERRUPTIBLE)
+
+	ret = waking_non_zero_interruptible(sem, current);
+	if (ret)
+	{
+		if (ret == 1)
+			/* ret != 0 only if we get interrupted -arca */
+			ret = 0;
+		break;
+	}
+	schedule();
+	DOWN_TAIL(TASK_INTERRUPTIBLE)
+	return ret;
+}
+
+int __down_trylock(struct semaphore * sem)
+{
+	return waking_non_zero_trylock(sem);
+}
+
diff -urN linux-2.4.29/arch/blackfin/kernel/setup.c linux-2.4.29-uc1/arch/blackfin/kernel/setup.c
--- linux-2.4.29/arch/blackfin/kernel/setup.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/kernel/setup.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,219 @@
+/* Changes made by Akbar Hussain April 05, 2001  for FRIO */
+
+/*
+ *  linux/arch/m68knommu/kernel/setup.c
+ *
+ *  Copyleft  ()) 2000       James D. Schettine {james@telos-systems.com}
+ *  Copyright (C) 1999,2000  Greg Ungerer (gerg@lineo.com)
+ *  Copyright (C) 1998,1999  D. Jeff Dionne <jeff@lineo.ca>
+ *  Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ *  Copyright (C) 1995       Hamish Macdonald
+ *  Copyright (C) 2000       Lineo Inc. (www.lineo.com) 
+ *  Copyright (C) 2003	     Metrowerks
+ */
+
+/*
+ * This file handles the architecture-dependent parts of system setup
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/genhd.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/major.h>
+#include <linux/bootmem.h>
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <linux/blk.h>
+#include <asm/pgtable.h>
+#endif
+
+unsigned long rom_length;
+unsigned long memory_start;
+unsigned long memory_end;
+
+struct task_struct *_current_task;
+
+char command_line[512];
+char saved_command_line[512];
+
+/* setup some dummy routines */
+static void dummy_waitbut(void)
+{
+}
+
+void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) = NULL;
+void (*mach_tick)( void ) = NULL;
+
+/* machine dependent keyboard functions */
+int (*mach_keyb_init) (void) = NULL;
+int (*mach_kbdrate) (struct kbd_repeat *) = NULL;
+void (*mach_kbd_leds) (unsigned int) = NULL;
+
+/* machine dependent irq functions */
+void (*mach_init_IRQ) (void) = NULL;
+void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
+int (*mach_request_irq) (unsigned int, void (*)(int, void *, struct pt_regs *),
+                         unsigned long, const char *, void *);
+void (*mach_free_irq) (unsigned int irq, void *dev_id) = NULL;
+void (*mach_enable_irq) (unsigned int) = NULL;
+void (*mach_disable_irq) (unsigned int) = NULL;
+int (*mach_get_irq_list) (char *) = NULL;
+void (*mach_process_int) (int irq, struct pt_regs *fp) = NULL;
+
+/* machine dependent timer functions */
+unsigned long (*mach_gettimeoffset) (void) = NULL;
+void (*mach_gettod) (int*, int*, int*, int*, int*, int*) = NULL;
+int (*mach_hwclk) (int, struct hwclk_time*) = NULL;
+int (*mach_set_clock_mmss) (unsigned long) = NULL;
+void (*mach_mksound)( unsigned int count, unsigned int ticks ) = NULL;
+void (*mach_reset)( void ) = NULL;
+void (*waitbut)(void) = dummy_waitbut;
+void (*mach_debug_init)(void) = NULL;
+void (*mach_halt)( void ) = NULL;
+void (*mach_power_off)( void ) = NULL;
+
+#define DEBUG 1
+#ifdef CONFIG_BLACKFIN
+	#define CPU "Blackfin"
+#endif
+
+#ifndef CPU
+	#define	CPU "UNKOWN"
+#endif
+
+extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
+extern int _ramstart, _ramend;
+
+void setup_arch(char **cmdline_p)
+{
+	int bootmap_size;
+
+#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)  
+	/* we need to initialize the Flashrom device here since we might
+	 * do things with flash early on in the boot
+	 */
+	flash_probe();
+#endif 
+
+	memory_start = PAGE_ALIGN(_ramstart);
+	memory_end = _ramend; /* by now the stack is part of the init task */
+
+	init_mm.start_code = (unsigned long) &_stext;
+	init_mm.end_code = (unsigned long) &_etext;
+	init_mm.end_data = (unsigned long) &_edata;
+	// init_mm.brk = (unsigned long) &_end;
+	
+	config_BSP(&command_line[0], sizeof(command_line));
+
+	printk("uClinux/" CPU "\n");
+
+#ifdef CONFIG_BLACKFIN
+#  ifdef CONFIG_BLACKFIN_EZKIT
+	printk("Blackfin BF533 support by BuyWays (www.buyways.nl)\n");
+#  else
+	printk("Blackfin support by Metrowerks (www.metrowerks.com)\n");
+#  endif
+#endif
+
+#ifdef DEBUG
+	printk("Memory map:\n  text = 0x%06x-0x%06x\n  data = 0x%06x-0x%06x\n  bss  = 0x%06x-0x%06x\n  romfs= 0x%06x-0x%06x\n  mem  = 0x%06x-0x%06x\n  stack= 0x%06x-0x%06x\n",
+		(int)&_stext,(int)&_etext,(int)&_sdata,(int)&_edata,
+		(int)&_sbss,(int)&_ebss,(int)&_ebss,(int)memory_start,
+		(int)memory_start,(int)memory_end,(int)memory_end,
+		(int)_ramend);
+#endif
+
+	init_task.mm->start_code = (unsigned long) &_stext;
+	init_task.mm->end_code = (unsigned long) &_etext;
+	init_task.mm->end_data = (unsigned long) &_edata;
+	init_task.mm->brk = (unsigned long) &_end;
+
+	ROOT_DEV = MKDEV(BLKMEM_MAJOR,0);
+
+	/* Keep a copy of command line */
+	*cmdline_p = &command_line[0];
+	memcpy(saved_command_line, command_line, sizeof(saved_command_line));
+	saved_command_line[sizeof(saved_command_line)-1] = 0;
+
+#ifdef DEBUG
+	if (strlen(*cmdline_p)) 
+		printk("Command line: '%s'\n", *cmdline_p);
+#endif
+	
+#ifdef CONFIG_VT_CONSOLE
+#ifdef CONFIG_FB
+       conswitchp = &dummy_con;
+#endif
+#endif
+
+	/*
+	 * give all the memory to the bootmap allocator,  tell it to put the
+	 * boot mem_map at the start of memory
+	 */
+	bootmap_size = init_bootmem_node(
+			NODE_DATA(0),
+			memory_start >> PAGE_SHIFT, /* map goes here */
+			PAGE_OFFSET >> PAGE_SHIFT,	/* 0 on coldfire */
+			memory_end >> PAGE_SHIFT);
+
+	/*
+	 * free the usable memory,  we have to make sure we do not free
+	 * the bootmem bitmap so we then reserve it after freeing it :-)
+	 */
+	free_bootmem(memory_start, memory_end - memory_start);
+
+	reserve_bootmem(memory_start, bootmap_size);
+	/*
+	 * get kmalloc into gear
+	 */
+	paging_init();
+}
+
+int get_cpuinfo(char * buffer)
+{
+    char *cpu, *mmu, *fpu;
+    u_long clockfreq;
+
+    cpu = CPU;
+    mmu = "none";
+    fpu = "none";
+
+#ifdef CONFIG_BLACKFIN
+    clockfreq = (loops_per_jiffy*HZ)*3;
+#else
+    clockfreq = (loops_per_jiffy*HZ)*16; 
+#endif
+
+    return(sprintf(buffer, "CPU:\t\t%s\n"
+		   "MMU:\t\t%s\n"
+		   "FPU:\t\t%s\n"
+		   "Clocking:\t%lu.%1luMHz\n"
+		   "BogoMips:\t%lu.%02lu\n"
+		   "Calibration:\t%lu loops\n",
+		   cpu, mmu, fpu,
+		   clockfreq/1000000,(clockfreq/100000)%10,
+		   (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
+		   (loops_per_jiffy*HZ)));
+
+}
+
+void arch_gettod(int *year, int *mon, int *day, int *hour,
+		 int *min, int *sec)
+{
+	if (mach_gettod)   /* depend on arch, should provide mach_gettod */
+		mach_gettod(year, mon, day, hour, min, sec);
+	else
+		*year = *mon = *day = *hour = *min = *sec = 0;
+}
diff -urN linux-2.4.29/arch/blackfin/kernel/sys_frio.c linux-2.4.29-uc1/arch/blackfin/kernel/sys_frio.c
--- linux-2.4.29/arch/blackfin/kernel/sys_frio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/kernel/sys_frio.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,669 @@
+/*
+ * linux/arch/m68k/kernel/sys_m68k.c
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/m68k
+ * platform.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/cachectl.h>
+#include <asm/traps.h>
+#include <asm/ipc.h>
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+asmlinkage int sys_pipe(unsigned long * fildes)
+{
+	int fd[2];
+	int error;
+
+	error = do_pipe(fd);
+	if (!error) {
+		if (copy_to_user(fildes, fd, 2*sizeof(int)))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+/* common code for old and new mmaps */
+static inline long do_mmap2(
+	unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	int error = -EBADF;
+	struct file * file = NULL;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (!(flags & MAP_ANONYMOUS)) {
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
+/*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
+ * handle more than 4 system call parameters, so these system calls
+ * used a memory block for parameter passing..
+ */
+
+struct mmap_arg_struct {
+	unsigned long addr;
+	unsigned long len;
+	unsigned long prot;
+	unsigned long flags;
+	unsigned long fd;
+	unsigned long offset;
+};
+
+asmlinkage int old_mmap(struct mmap_arg_struct *arg)
+{
+	struct mmap_arg_struct a;
+	int error = -EFAULT;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		goto out;
+
+	error = -EINVAL;
+	if (a.offset & ~PAGE_MASK)
+		goto out;
+
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+out:
+	return error;
+}
+
+#if 0 /* DAVIDM - do we want this */
+struct mmap_arg_struct64 {
+	__u32 addr;
+	__u32 len;
+	__u32 prot;
+	__u32 flags;
+	__u64 offset; /* 64 bits */
+	__u32 fd;
+};
+
+asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
+{
+	int error = -EFAULT;
+	struct file * file = NULL;
+	struct mmap_arg_struct64 a;
+	unsigned long pgoff;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+
+	if ((long)a.offset & ~PAGE_MASK)
+		return -EINVAL;
+
+	pgoff = a.offset >> PAGE_SHIFT;
+	if ((a.offset >> PAGE_SHIFT) != pgoff)
+		return -EINVAL;
+
+	if (!(a.flags & MAP_ANONYMOUS)) {
+		error = -EBADF;
+		file = fget(a.fd);
+		if (!file)
+			goto out;
+	}
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	down(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
+	up(&current->mm->mmap_sem);
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+#endif
+
+extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+
+struct sel_arg_struct {
+	unsigned long n;
+	fd_set *inp, *outp, *exp;
+	struct timeval *tvp;
+};
+
+asmlinkage int old_select(struct sel_arg_struct *arg)
+{
+	struct sel_arg_struct a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+	/* sys_select() does the appropriate kernel locking */
+	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
+}
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+asmlinkage int sys_ipc (uint call, int first, int second,
+			int third, void *ptr, long fifth)
+{
+//	int version, ret;
+	int version;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	if (call <= SEMCTL)
+		switch (call) {
+		case SEMOP:
+			return sys_semop (first, (struct sembuf *)ptr, second);
+		case SEMGET:
+			return sys_semget (first, second, third);
+		case SEMCTL: {
+			union semun fourth;
+			if (!ptr)
+				return -EINVAL;
+			if (get_user(fourth.__pad, (void **) ptr))
+				return -EFAULT;
+			return sys_semctl (first, second, third, fourth);
+			}
+		default:
+			return -EINVAL;
+		}
+	if (call <= MSGCTL) 
+		switch (call) {
+		case MSGSND:
+			return sys_msgsnd (first, (struct msgbuf *) ptr, 
+					  second, third);
+		case MSGRCV:
+			switch (version) {
+			case 0: {
+				struct ipc_kludge tmp;
+				if (!ptr)
+					return -EINVAL;
+				if (copy_from_user (&tmp,
+						    (struct ipc_kludge *)ptr,
+						    sizeof (tmp)))
+					return -EFAULT;
+				return sys_msgrcv (first, tmp.msgp, second,
+						   tmp.msgtyp, third);
+				}
+			default:
+				return sys_msgrcv (first,
+						   (struct msgbuf *) ptr,
+						   second, fifth, third);
+			}
+		case MSGGET:
+			return sys_msgget ((key_t) first, second);
+		case MSGCTL:
+			return sys_msgctl (first, second,
+					   (struct msqid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+#if 0 /* DAVIDM not implemented */
+	if (call <= SHMCTL) 
+		switch (call) {
+		case SHMAT:
+			switch (version) {
+			default: {
+				ulong raddr;
+				ret = sys_shmat (first, (char *) ptr,
+						 second, &raddr);
+				if (ret)
+					return ret;
+				return put_user (raddr, (ulong *) third);
+			}
+			}
+		case SHMDT: 
+			return sys_shmdt ((char *)ptr);
+		case SHMGET:
+			return sys_shmget (first, second, third);
+		case SHMCTL:
+			return sys_shmctl (first, second,
+					   (struct shmid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+#endif
+
+	return -EINVAL;
+}
+
+asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
+{
+  return -ENOSYS;
+}
+
+#if DAVIDM /* fixme,  may need something like this for the 5407 */
+/* Convert virtual address VADDR to physical address PADDR */
+#define virt_to_phys_040(vaddr)						\
+({									\
+})
+
+static inline int
+cache_flush_040 (unsigned long addr, int scope, int cache, unsigned long len)
+{
+  unsigned long paddr, i;
+
+  switch (scope)
+    {
+    case FLUSH_SCOPE_ALL:
+      switch (cache)
+	{
+	case FLUSH_CACHE_DATA:
+	  /* This nop is needed for some broken versions of the 68040.  */
+	  __asm__ __volatile__ ("nop\n\t"
+				".chip 68040\n\t"
+				"cpusha %dc\n\t"
+				".chip 68k");
+	  break;
+	case FLUSH_CACHE_INSN:
+	  __asm__ __volatile__ ("nop\n\t"
+				".chip 68040\n\t"
+				"cpusha %ic\n\t"
+				".chip 68k");
+	  break;
+	default:
+	case FLUSH_CACHE_BOTH:
+	  __asm__ __volatile__ ("nop\n\t"
+				".chip 68040\n\t"
+				"cpusha %bc\n\t"
+				".chip 68k");
+	  break;
+	}
+      break;
+
+    case FLUSH_SCOPE_LINE:
+      /* Find the physical address of the first mapped page in the
+	 address range.  */
+      if ((paddr = virt_to_phys_040(addr))) {
+        paddr += addr & ~(PAGE_MASK | 15);
+        len = (len + (addr & 15) + 15) >> 4;
+      } else {
+	unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
+
+	if (len <= tmp)
+	  return 0;
+	addr += tmp;
+	len -= tmp;
+	tmp = PAGE_SIZE;
+	for (;;)
+	  {
+	    if ((paddr = virt_to_phys_040(addr)))
+	      break;
+	    if (len <= tmp)
+	      return 0;
+	    addr += tmp;
+	    len -= tmp;
+	  }
+	len = (len + 15) >> 4;
+      }
+      i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
+      while (len--)
+	{
+	  switch (cache)
+	    {
+	    case FLUSH_CACHE_DATA:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushl %%dc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    case FLUSH_CACHE_INSN:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushl %%ic,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    default:
+	    case FLUSH_CACHE_BOTH:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushl %%bc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    }
+	  if (!--i && len)
+	    {
+	      /*
+	       * No need to page align here since it is done by
+	       * virt_to_phys_040().
+	       */
+	      addr += PAGE_SIZE;
+	      i = PAGE_SIZE / 16;
+	      /* Recompute physical address when crossing a page
+	         boundary. */
+	      for (;;)
+		{
+		  if ((paddr = virt_to_phys_040(addr)))
+		    break;
+		  if (len <= i)
+		    return 0;
+		  len -= i;
+		  addr += PAGE_SIZE;
+		}
+	    }
+	  else
+	    paddr += 16;
+	}
+      break;
+
+    default:
+    case FLUSH_SCOPE_PAGE:
+      len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
+      for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
+	{
+	  if (!(paddr = virt_to_phys_040(addr)))
+	    continue;
+	  switch (cache)
+	    {
+	    case FLUSH_CACHE_DATA:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushp %%dc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    case FLUSH_CACHE_INSN:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushp %%ic,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    default:
+	    case FLUSH_CACHE_BOTH:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushp %%bc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    }
+	}
+      break;
+    }
+  return 0;
+}
+
+#define virt_to_phys_060(vaddr)				\
+({							\
+  unsigned long paddr;					\
+  __asm__ __volatile__ (".chip 68060\n\t"		\
+			"plpar (%0)\n\t"		\
+			".chip 68k"			\
+			: "=a" (paddr)			\
+			: "0" (vaddr));			\
+  (paddr); /* XXX */					\
+})
+
+static inline int
+cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len)
+{
+  unsigned long paddr, i;
+
+  switch (scope)
+    {
+    case FLUSH_SCOPE_ALL:
+      switch (cache)
+	{
+	case FLUSH_CACHE_DATA:
+	  __asm__ __volatile__ (".chip 68060\n\t"
+				"cpusha %dc\n\t"
+				"cinva %dc\n\t"
+				".chip 68k");
+	  break;
+	case FLUSH_CACHE_INSN:
+	  __asm__ __volatile__ (".chip 68060\n\t"
+				"cpusha %ic\n\t"
+				"cinva %ic\n\t"
+				".chip 68k");
+	  break;
+	default:
+	case FLUSH_CACHE_BOTH:
+	  __asm__ __volatile__ (".chip 68060\n\t"
+				"cpusha %bc\n\t"
+				"cinva %bc\n\t"
+				".chip 68k");
+	  break;
+	}
+      break;
+
+    case FLUSH_SCOPE_LINE:
+      /* Find the physical address of the first mapped page in the
+	 address range.  */
+      len += addr & 15;
+      addr &= -16;
+      if (!(paddr = virt_to_phys_060(addr))) {
+	unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
+
+	if (len <= tmp)
+	  return 0;
+	addr += tmp;
+	len -= tmp;
+	tmp = PAGE_SIZE;
+	for (;;)
+	  {
+	    if ((paddr = virt_to_phys_060(addr)))
+	      break;
+	    if (len <= tmp)
+	      return 0;
+	    addr += tmp;
+	    len -= tmp;
+	  }
+      }
+      len = (len + 15) >> 4;
+      i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
+      while (len--)
+	{
+	  switch (cache)
+	    {
+	    case FLUSH_CACHE_DATA:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushl %%dc,(%0)\n\t"
+				    "cinvl %%dc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    case FLUSH_CACHE_INSN:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushl %%ic,(%0)\n\t"
+				    "cinvl %%ic,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    default:
+	    case FLUSH_CACHE_BOTH:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushl %%bc,(%0)\n\t"
+				    "cinvl %%bc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    }
+	  if (!--i && len)
+	    {
+
+	      /*
+	       * We just want to jump to the first cache line
+	       * in the next page.
+	       */
+	      addr += PAGE_SIZE;
+	      addr &= PAGE_MASK;
+
+	      i = PAGE_SIZE / 16;
+	      /* Recompute physical address when crossing a page
+	         boundary. */
+	      for (;;)
+	        {
+	          if ((paddr = virt_to_phys_060(addr)))
+	            break;
+	          if (len <= i)
+	            return 0;
+	          len -= i;
+	          addr += PAGE_SIZE;
+	        }
+	    }
+	  else
+	    paddr += 16;
+	}
+      break;
+
+    default:
+    case FLUSH_SCOPE_PAGE:
+      len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
+      addr &= PAGE_MASK;	/* Workaround for bug in some
+				   revisions of the 68060 */
+      for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
+	{
+	  if (!(paddr = virt_to_phys_060(addr)))
+	    continue;
+	  switch (cache)
+	    {
+	    case FLUSH_CACHE_DATA:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushp %%dc,(%0)\n\t"
+				    "cinvp %%dc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    case FLUSH_CACHE_INSN:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushp %%ic,(%0)\n\t"
+				    "cinvp %%ic,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    default:
+	    case FLUSH_CACHE_BOTH:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushp %%bc,(%0)\n\t"
+				    "cinvp %%bc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    }
+	}
+      break;
+    }
+  return 0;
+}
+#endif
+
+/* sys_cacheflush -- flush (part of) the processor cache.  */
+asmlinkage int
+sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
+{
+	int ret = -EINVAL;
+#if DAVIDM /* fixme 5407 */
+	struct vm_area_struct *vma;
+
+	lock_kernel();
+	if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL ||
+	    cache & ~FLUSH_CACHE_BOTH)
+		goto out;
+
+	if (scope == FLUSH_SCOPE_ALL) {
+		/* Only the superuser may flush the whole cache. */
+		ret = -EPERM;
+		if (!capable(CAP_SYS_ADMIN))
+			goto out;
+	} else {
+		/* Verify that the specified address region actually belongs to
+		 * this process.
+		 */
+		vma = find_vma (current->mm, addr);
+		ret = -EINVAL;
+		/* Check for overflow.  */
+		if (addr + len < addr)
+			goto out;
+		if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end)
+			goto out;
+	}
+
+	if (CPU_IS_020_OR_030) {
+		if (scope == FLUSH_SCOPE_LINE && len < 256) {
+			unsigned long cacr;
+			__asm__ ("movec %%cacr, %0" : "=r" (cacr));
+			if (cache & FLUSH_CACHE_INSN)
+				cacr |= 4;
+			if (cache & FLUSH_CACHE_DATA)
+				cacr |= 0x400;
+			len >>= 2;
+			while (len--) {
+				__asm__ __volatile__ ("movec %1, %%caar\n\t"
+						      "movec %0, %%cacr"
+						      : /* no outputs */
+						      : "r" (cacr), "r" (addr));
+				addr += 4;
+			}
+		} else {
+			/* Flush the whole cache, even if page granularity requested. */
+			unsigned long cacr;
+			__asm__ ("movec %%cacr, %0" : "=r" (cacr));
+			if (cache & FLUSH_CACHE_INSN)
+				cacr |= 8;
+			if (cache & FLUSH_CACHE_DATA)
+				cacr |= 0x800;
+			__asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr));
+		}
+		ret = 0;
+		goto out;
+	} else if (CPU_IS_040) {
+		ret = cache_flush_040 (addr, scope, cache, len);
+	} else if (CPU_IS_060) {
+		ret = cache_flush_060 (addr, scope, cache, len);
+	}
+out:
+	unlock_kernel();
+#endif
+	return ret;
+}
+
+/*
+ * Old cruft
+ */
+asmlinkage int sys_pause(void)
+{
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	return -ERESTARTNOHAND;
+}
diff -urN linux-2.4.29/arch/blackfin/kernel/time.c linux-2.4.29-uc1/arch/blackfin/kernel/time.c
--- linux-2.4.29/arch/blackfin/kernel/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/kernel/time.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,188 @@
+/*
+ *  linux/arch/frionommu/kernel/time.c
+ *
+ *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *
+ * This file contains the frio-specific time handling details.
+ * Most of the stuff is located in the machine specific files.
+ *
+ * 1997-09-10	Updated NTP code according to technical memorandum Jan '96
+ *		"A Kernel Model for Precision Timekeeping" by Dave Mills
+ */
+
+#include <linux/config.h> /* CONFIG_HEARTBEAT */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+
+#include <asm/machdep.h>
+#include <asm/io.h>
+
+#include <linux/timex.h>
+
+
+static inline int set_rtc_mmss(unsigned long nowtime)
+{
+  if (mach_set_clock_mmss)
+    return mach_set_clock_mmss (nowtime);
+  return -1;
+}
+
+static inline void do_profile (unsigned long pc)
+{
+	if (prof_buffer && current->pid) {
+		extern int _stext;
+		pc -= (unsigned long) &_stext;
+		pc >>= prof_shift;
+		if (pc < prof_len)
+			++prof_buffer[pc];
+		else
+		/*
+		 * Don't ignore out-of-bounds PC values silently,
+		 * put them into the last histogram slot, so if
+		 * present, they will show up as a sharp peak.
+		 */
+			++prof_buffer[prof_len-1];
+	}
+}
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
+{
+	/* last time the cmos clock got updated */
+	static long last_rtc_update=0;
+
+	/* may need to kick the hardware timer */
+#if 0
+	if (mach_tick)
+	  mach_tick();
+#endif
+
+	do_timer(regs);
+
+#if 0
+	if (!user_mode(regs))
+		do_profile(regs->pc);
+#endif
+
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
+	    xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
+	  if (set_rtc_mmss(xtime.tv_sec) == 0)
+	    last_rtc_update = xtime.tv_sec;
+	  else
+	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	}
+#if 0
+#ifdef CONFIG_HEARTBEAT
+	/* use power LED as a heartbeat instead -- much more useful
+	   for debugging -- based on the version for PReP by Cort */
+	/* acts like an actual heart beat -- ie thump-thump-pause... */
+	if (mach_heartbeat) {
+	    static unsigned cnt = 0, period = 0, dist = 0;
+
+	    if (cnt == 0 || cnt == dist)
+		mach_heartbeat( 1 );
+	    else if (cnt == 7 || cnt == dist+7)
+		mach_heartbeat( 0 );
+
+	    if (++cnt > period) {
+		cnt = 0;
+		/* The hyperbolic function below modifies the heartbeat period
+		 * length in dependency of the current (5min) load. It goes
+		 * through the points f(0)=126, f(1)=86, f(5)=51,
+		 * f(inf)->30. */
+		period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
+		dist = period / 4;
+	    }
+	}
+#endif /* CONFIG_HEARTBEAT */
+#endif
+}
+
+void time_init(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+
+	extern void arch_gettod(int *year, int *mon, int *day, int *hour,
+				int *min, int *sec);
+
+	arch_gettod (&year, &mon, &day, &hour, &min, &sec);
+
+	if ((year += 1900) < 1970)
+		year += 100;
+	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+	xtime.tv_usec = 0;
+
+	mach_sched_init(timer_interrupt);
+}
+
+extern rwlock_t xtime_lock;
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+#if 0 /* DAVIDM later if possible */
+	extern volatile unsigned long lost_ticks;
+	unsigned long lost;
+#endif
+	unsigned long flags = 0;
+	unsigned long usec, sec;
+
+	read_lock_irqsave(&xtime_lock, flags);
+	usec = mach_gettimeoffset ? mach_gettimeoffset() : 0;
+#if 0 /* DAVIDM later if possible */
+	lost = lost_ticks;
+	if (lost)
+		usec += lost * (1000000/HZ);
+#endif
+	sec = xtime.tv_sec;
+	usec += xtime.tv_usec;
+	read_unlock_irqrestore(&xtime_lock, flags);
+
+	while (usec >= 1000000) {
+		usec -= 1000000;
+		sec++;
+	}
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	write_lock_irq(&xtime_lock);
+	/* This is revolting. We need to set the xtime.tv_usec
+	 * correctly. However, the value in this location is
+	 * is value at the last tick.
+	 * Discover what correction gettimeofday
+	 * would have done, and then undo it!
+	 */
+	tv->tv_usec -= mach_gettimeoffset();
+
+	while (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+
+	xtime = *tv;
+	time_adjust = 0;		/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+	write_unlock_irq(&xtime_lock);
+}
diff -urN linux-2.4.29/arch/blackfin/kernel/traps.c linux-2.4.29-uc1/arch/blackfin/kernel/traps.c
--- linux-2.4.29/arch/blackfin/kernel/traps.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/kernel/traps.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,263 @@
+/*
+ *  linux/arch/frionommu/kernel/traps.c
+ *
+ *  Copyright (C) 1993, 1994 by Hamish Macdonald
+ *
+ * Adapted for BlackFin (ADI) by Ted Ma <mated@sympatico.ca>
+ * Copyright (c) 2002 Arcturus Networks Inc. (www.arcturusnetworks.com)
+ *		-BlackFin/FRIO uses S/W interrupt 15 for the system calls
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * Sets up all exception vectors
+ */
+
+/* Note: 
+ *    1. ILLEGAL USE PROTECTED RESOURCE ( EXCAUSE = 0x2E)
+ *            illegal execution supervisor mode only instruction
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/a.out.h>
+#include <linux/user.h>
+#include <linux/string.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/traps.h>
+#include <asm/pgtable.h>
+#include <asm/machdep.h>
+#include <asm/siginfo.h>
+//#include <asm/hw_irq.h>	// don't think I need this ...MaTed---
+
+/* frio nisa specific include headers */
+#include <asm/blackfin.h>
+
+/* assembler routines */
+asmlinkage void excpt_handle(void);
+asmlinkage void system_call(void);
+asmlinkage void trap(void);
+asmlinkage void inthandler(void);
+asmlinkage void nmihandler(void);
+asmlinkage void emu_handle(void);
+asmlinkage void rst_handle(void);
+asmlinkage void nmi_handler(void);
+asmlinkage void ivhw_handle(void);
+asmlinkage void ivtmr_handle(void);
+asmlinkage void ivg7_handle(void);
+
+extern int kprintf(char *, ...);
+
+/* Declare exception handler: For detail, look into gcc nisa.
+ */
+
+void excpt_handle(void)
+{ }
+
+/* Frio has 64 exceptions, and 0-15 can be user invoked	
+ * this table provide seperated handler for different exception
+ */
+e_vector vectors[64] = {
+	system_call, excpt_handle, excpt_handle, excpt_handle,
+	excpt_handle, excpt_handle, excpt_handle, excpt_handle,
+	excpt_handle, excpt_handle, excpt_handle, excpt_handle,
+	excpt_handle, excpt_handle, excpt_handle, excpt_handle,
+	trap, trap, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, trap, trap, trap, trap, trap, trap, trap,
+	trap, trap, trap, trap, trap, trap, trap, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0
+};
+
+
+enum {
+#undef REG
+#define REG(name, pos) reg_##name,
+#include <asm/regs.h>
+};
+
+#define EXITCODE  *(char volatile *)0xFF7EEEEE
+
+static void __init nisa_trap_init (void)
+{
+    asm("p0.l = 0x2000; p0.h = 0xffe0;
+	 p1.h = trap;
+	 p1.l = trap;
+	 [p0+(4*3)] = p1;     // Vector event 03 ----- Exception handler (trap) in entry.S
+	 p1.l = system_call;
+	 p1.h = system_call;
+	 [p0+(4*15)] = p1;"); // Vector event 15 ----- System call handler(system_call) in entry.S
+
+}
+
+/* Initiate the event table handler  ---- called from init/main.c start_kernel()
+ */
+void __init trap_init (void)
+{
+
+	nisa_trap_init();
+}
+
+
+
+static char *vec_names[] = {
+	"SYSTEM CALL" , "EXCPT 1" , "EXCPT 2" , "EXCPT 3",
+        "EXCPT 4" , "EXCPT 5" , "EXCPT 6" , "EXCPT 7",
+        "EXCPT 8" , "EXCPT 9" , "EXCPT 10", "EXCPT 11",
+        "EXCPT 12", "EXCPT 13", "EXCPT 14", "EXCPT 15",
+	"SINGLE STEP", "EMULATION TRACE OVERFLOW", "UNASSIGNED RESERVED 18",
+	"UNASSIGNED RESERVED 19", "UNASSIGNED RESERVED 20", "UNASSIGNED RESERVED 21",
+	"UNASSIGNED RESERVED 22", "UNASSIGNED RESERVED 23", "UNASSIGNED RESERVED 24",
+	"UNASSIGNED RESERVED 25", "UNASSIGNED RESERVED 26", "UNASSIGNED RESERVED 27",
+	"UNASSIGNED RESERVED 28", "UNASSIGNED RESERVED 29", "UNASSIGNED RESERVED 30",
+	"UNASSIGNED RESERVED 31", "UNASSIGNED RESERVED 32",
+	"UNDEFINED INSTRUCTION", "ILLEGAL INSTRUCTION", "CPLB PROTECTION VIOLATION",
+	"MISALIGNED DATA ACCESS", "UNRECOVERABLE EVENT", "CPLB MISS",
+	"MULTIPLE CPLB HITS", "EMULATION WATCHPOINT MATCH", "INSTRUCTION ACCESS VIOLATION",
+	"MISALIGNED INSTRUCTION FETCH", "INSTRUCTION CPLB PROTECTION VIOLATION",
+	"INSTRUCTION CPLB MISS", "INSTRUCTION MULTIPLE CPLB HITS",
+	"ILLEGAL USE PROTECTED RESOURCE", "UNASSIGNED RESERVED 47", "UNASSIGNED RESERVED 48",
+	"UNASSIGNED RESERVED 49", "UNASSIGNED RESERVED 50", "UNASSIGNED RESERVED 51",
+	"UNASSIGNED RESERVED 52", "UNASSIGNED RESERVED 53", "UNASSIGNED RESERVED 54",
+	"UNASSIGNED RESERVED 55", "UNASSIGNED RESERVED 56", "UNASSIGNED RESERVED 57",
+	"UNASSIGNED RESERVED 58", "UNASSIGNED RESERVED 59", "UNASSIGNED RESERVED 60",
+	"UNASSIGNED RESERVED 61", "UNASSIGNED RESERVED 62", "UNASSIGNED RESERVED 63"
+	};
+
+void die_if_kernel(char *,struct pt_regs *,int);
+asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
+                             unsigned long error_code);
+
+asmlinkage void trap_c(struct pt_regs *fp);
+
+int kstack_depth_to_print = 48;
+
+/* MODULE_RANGE is a guess of how much space is likely to be
+   vmalloced.  */
+#define MODULE_RANGE (8*1024*1024)
+
+asmlinkage void trap_c(struct pt_regs *fp)
+{
+	int sig;
+	siginfo_t info;
+
+	/* send the appropriate signal to the user program */
+	switch (fp->seqstat & 0x3f) {
+	    case VEC_STEP:
+		info.si_code = TRAP_STEP;
+		sig = SIGTRAP;
+		break;
+	    case VEC_UNDEF_I:
+		info.si_code = ILL_ILLOPC;
+		sig = SIGILL;
+		break;
+	    case VEC_OVFLOW:
+		info.si_code = TRAP_TRACEFLOW;
+		sig = SIGTRAP;
+		break;
+	    case VEC_ILGAL_I:
+		info.si_code = ILL_ILLPARAOP;
+		sig = SIGILL;
+		break;
+	    case VEC_ILL_RES:
+		info.si_code = ILL_PRVOPC;
+		sig = SIGILL;
+                break;
+
+	    case VEC_MISALI_D:
+	    case VEC_MISALI_I:
+		info.si_code = BUS_ADRALN;
+		sig = SIGBUS;
+		break;
+
+	    case VEC_UNCOV:
+		info.si_code = ILL_ILLEXCPT;
+		sig = SIGILL;
+		break;
+
+	    case VEC_WATCH:
+		info.si_code = TRAP_WATCHPT;
+		sig = SIGTRAP;
+		break;
+
+	    case VEC_ISTRU_VL:
+		info.si_code = BUS_OPFETCH;
+		sig = SIGBUS;
+                break;
+
+	    case VEC_CPLB_I_VL:
+	    case VEC_CPLB_VL:
+		info.si_code = ILL_CPLB_VI;
+		sig = SIGILL;
+                break;
+
+	    case VEC_CPLB_I_M:
+	    case VEC_CPLB_M:
+		info.si_code = IlL_CPLB_MISS;
+		sig = SIGILL;
+                break;
+
+	    case VEC_CPLB_I_MHIT:
+	    case VEC_CPLB_MHIT:
+		info.si_code = ILL_CPLB_MULHIT;
+		sig = SIGILL;
+                break;
+
+	    default:
+		info.si_code = TRAP_ILLTRAP;
+		sig = SIGTRAP;
+		break;
+	}
+	info.si_signo = sig;
+	info.si_errno = 0;
+	info.si_addr = (void *) fp->pc;
+	force_sig_info (sig, &info, current);
+}
+
+void show_trace_task(struct task_struct *tsk)
+{
+	/* XXX: we can do better, need a proper stack dump */
+	printk("STACK ksp = 0x%lx, usp = 0x%lx\n", tsk->thread.ksp, tsk->thread.usp);
+}
+
+void die_if_kernel (char *str, struct pt_regs *fp, int nr)
+{
+	if (!(fp->seqstat & PS_S))
+		return;
+
+	console_verbose();
+	printk("%s: %08x\n",str,nr);
+	printk("PC: [<%08lu>]    SEQSTAT: %04lu\n",
+	       fp->pc, fp->seqstat);
+	printk("r0: %08lx    r1: %08lx    r2: %08lx    r3: %08lx\n",
+	       fp->r0, fp->r1, fp->r2, fp->r3);
+	printk("r4: %08lx    r5: %08lx    r6: %08lx    r7: %08lx\n",
+	       fp->r4, fp->r5, fp->r6, fp->r7);
+	printk("p0: %08lx    p1: %08lx    p2: %08lx    p3: %08lx\n",
+	       fp->p0, fp->p1, fp->p2, fp->p3);
+	printk("p4: %08lx    p5: %08lx    fp: %08lx\n",
+	       fp->p4, fp->p5, fp->fp);
+	printk("aow: %08lx    a0.x: %08lx    a1w: %08lx    a1.x: %08lx\n",
+	       fp->a0w, fp->a0x, fp->a1w, fp->a1x);
+
+	printk("Process %s (pid: %d, stackpage=%08lx)\n",
+		current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
+	do_exit(SIGSEGV);
+}
+
+
+/* Typical exception handling routines	*/
+
diff -urN linux-2.4.29/arch/blackfin/lib/ashrdi3.c linux-2.4.29-uc1/arch/blackfin/lib/ashrdi3.c
--- linux-2.4.29/arch/blackfin/lib/ashrdi3.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/lib/ashrdi3.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,63 @@
+/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define BITS_PER_UNIT 8
+
+typedef 	 int SItype	__attribute__ ((mode (SI)));
+typedef unsigned int USItype	__attribute__ ((mode (SI)));
+typedef		 int DItype	__attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
+DItype
+__ashrdi3 (DItype u, word_type b)
+{
+  DIunion w;
+  word_type bm;
+  DIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ll = u;
+
+  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      /* w.s.high = 1..1 or 0..0 */
+      w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
+      w.s.low = uu.s.high >> -bm;
+    }
+  else
+    {
+      USItype carries = (USItype)uu.s.high << bm;
+      w.s.high = uu.s.high >> b;
+      w.s.low = ((USItype)uu.s.low >> b) | carries;
+    }
+
+  return w.ll;
+}
diff -urN linux-2.4.29/arch/blackfin/lib/checksum.c linux-2.4.29-uc1/arch/blackfin/lib/checksum.c
--- linux-2.4.29/arch/blackfin/lib/checksum.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/lib/checksum.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,157 @@
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		IP/TCP/UDP checksumming routines
+ *
+ * Authors:	Jorge Cwik, <jorge@laser.satlink.net>
+ *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ *		Tom May, <ftom@netcom.com>
+ *		Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
+ *		Lots of code moved from tcp.c and ip.c; see those files
+ *		for more names.
+ *
+ * 03/02/96	Jes Sorensen, Andreas Schwab, Roman Hodek:
+ *		Fixed some nasty bugs, causing some horrible crashes.
+ *		A: At some points, the sum (%0) was used as
+ *		length-counter instead of the length counter
+ *		(%1). Thanks to Roman Hodek for pointing this out.
+ *		B: GCC seems to mess up if one uses too many
+ *		data-registers to hold input values and one tries to
+ *		specify d0 and d1 as scratch registers. Letting gcc choose these
+ *      registers itself solves the problem.
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+ 
+/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most
+   of the assembly has to go. */
+
+#include <net/checksum.h>
+#include <asm/checksum.h>
+
+static inline unsigned short from32to16(unsigned long x)
+{
+	/* add up 16-bit and 16-bit for 16+c bit */
+	x = (x & 0xffff) + (x >> 16);
+	/* add up carry.. */
+	x = (x & 0xffff) + (x >> 16);
+	return x;
+}
+
+static unsigned long do_csum(const unsigned char * buff, int len)
+{
+	int odd, count;
+	unsigned long result = 0;
+
+	if (len <= 0)
+		goto out;
+	odd = 1 & (unsigned long) buff;
+	if (odd) {
+		result = *buff;
+		len--;
+		buff++;
+	}
+	count = len >> 1;		/* nr of 16-bit words.. */
+	if (count) {
+		if (2 & (unsigned long) buff) {
+			result += *(unsigned short *) buff;
+			count--;
+			len -= 2;
+			buff += 2;
+		}
+		count >>= 1;		/* nr of 32-bit words.. */
+		if (count) {
+		        unsigned long carry = 0;
+			do {
+				unsigned long w = *(unsigned long *) buff;
+				count--;
+				buff += 4;
+				result += carry;
+				result += w;
+				carry = (w > result);
+			} while (count);
+			result += carry;
+			result = (result & 0xffff) + (result >> 16);
+		}
+		if (len & 2) {
+			result += *(unsigned short *) buff;
+			buff += 2;
+		}
+	}
+	if (len & 1)
+		result += (*buff << 8);
+	result = from32to16(result);
+	if (odd)
+		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+	return result;
+}
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ */
+unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
+{
+	return ~do_csum(iph,ihl*4);
+}
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
+{
+	unsigned int result = do_csum(buff, len);
+
+	/* add in old sum, and carry.. */
+	result += sum;
+	/* 16+c bits -> 16 bits */
+	result = (result & 0xffff) + (result >> 16);
+	return result;
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+unsigned short ip_compute_csum(const unsigned char * buff, int len)
+{
+	return ~do_csum(buff,len);
+}
+
+/*
+ * copy from fs while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err)
+{
+	if (csum_err) *csum_err = 0;
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
+
+/*
+ * copy from ds while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy(const char *src, char *dst, int len, int sum)
+{
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
diff -urN linux-2.4.29/arch/blackfin/lib/divsi3.S linux-2.4.29-uc1/arch/blackfin/lib/divsi3.S
--- linux-2.4.29/arch/blackfin/lib/divsi3.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/lib/divsi3.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,129 @@
+.text
+.align 2
+.global ___divsi3;
+.type ___divsi3, STT_FUNC;
+.global __divsi3;
+.type __divsi3, STT_FUNC;
+
+___divsi3:
+__divsi3:
+	[--SP] = RETS;
+	CC = R0 < 0;
+	IF CC JUMP num_neg;
+	CC = R1 < 0;
+	IF CC JUMP den_neg;
+	CALL pos_ans;
+
+num_neg:
+	CC = R1 < 0;
+	IF CC JUMP both_neg;
+	R0 = -R0;
+	CALL ___udivsi3;
+	R0 = -R0;
+	CALL done;
+
+den_neg:
+	R1 = -R1;
+	CALL ___udivsi3;
+	R0 = -R0;
+	CALL done;
+
+both_neg:
+	R0 = -R0;
+	R1 = -R1;
+
+pos_ans:
+	CALL ___udivsi3;
+	CALL done;
+	NOP;
+done:
+	RETS = [SP++];
+	RTS;
+
+.align 2
+.global ___udivsi3;
+.type ___udivsi3, STT_FUNC;
+.global __udivsi3;
+.type __udivsi3, STT_FUNC;
+
+___udivsi3:
+__udivsi3:
+	[--SP] = RETS;
+	[--SP] = R4;
+	[--SP] = P4;
+	P4 = 32;
+	LSETUP (udiv_begin, udiv_end) LC0 = P4;
+	R3 = 0;
+
+udiv_begin:
+	CALL lshft;
+	R2 = R3;
+	R3 = R3 - R1;
+	CC = R3 < 0;
+	IF !CC JUMP one_qb;
+	R3 = R2;
+	R2 = -2;
+	R0 = R0 & R2;
+	JUMP.S udiv_end;
+
+one_qb:
+	R2 = 1;
+	R0 = R0 | R2;
+
+udiv_end:
+	NOP;
+return:
+	R1 = R3;
+	P4 = [SP++];
+	R4 = [SP++];
+	RETS = [SP++];
+	RTS;
+
+lshft:
+	R2 = R0;
+	R4 = 31;
+	R2 >>= R4;
+	R4 = 1;
+	R2 = R2 & R4;
+	R3 <<= 0x1;
+	R3 = R3 | R2;
+	R0 <<= 0x1;
+	RTS;
+
+
+.global ___umodsi3;
+.type ___umodsi3, STT_FUNC;
+.global __umodsi3;
+.type __umodsi3, STT_FUNC;
+
+___umodsi3:
+__umodsi3:
+	LINK 0x0;
+	[--SP] = (R7:6);
+	R6 = R0;
+	R7 = R1;
+	CALL ___udivsi3;
+	R7 *= R0;
+	R0 = R6 - R7;
+	( R7:6 ) = [SP++];
+	UNLINK;
+	RTS;
+
+
+.global ___modsi3;
+.type ___modsi3, STT_FUNC;
+.global __modsi3;
+.type __modsi3, STT_FUNC;
+
+___modsi3:
+__modsi3:
+	LINK 0x0;
+	[--SP] = (R7:6);
+	R6 = R0;
+	R7 = R1;
+	CALL ___divsi3;
+	R7 *= R0;
+	R0 = R6 - R7;
+	( R7:6 ) = [SP++];
+	UNLINK;
+	RTS;
diff -urN linux-2.4.29/arch/blackfin/lib/Makefile linux-2.4.29-uc1/arch/blackfin/lib/Makefile
--- linux-2.4.29/arch/blackfin/lib/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/lib/Makefile	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,11 @@
+#
+# Makefile for frio-specific library files..
+#
+
+.S.o:
+	$(CC) $(AFLAGS) -D__ASSEMBLY__ -traditional -c $< -o $@
+
+L_TARGET = lib.a
+obj-y  = ashrdi3.o checksum.o memcpy.o memset.o memcmp.o muldi3.o divsi3.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/blackfin/lib/memcmp.c linux-2.4.29-uc1/arch/blackfin/lib/memcmp.c
--- linux-2.4.29/arch/blackfin/lib/memcmp.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/lib/memcmp.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,12 @@
+#include <linux/types.h>
+
+int memcmp(const void * cs,const void * ct, size_t count) 
+{
+        const unsigned char *su1, *su2;
+        signed char res = 0;
+
+        for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+                if ((res = *su1 - *su2) != 0)
+                        break;
+        return res;
+}
diff -urN linux-2.4.29/arch/blackfin/lib/memcpy.c linux-2.4.29-uc1/arch/blackfin/lib/memcpy.c
--- linux-2.4.29/arch/blackfin/lib/memcpy.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/lib/memcpy.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,13 @@
+/* Changes made by Tony Kou    Lineo, Inc    May 2001	*/
+
+#include <linux/types.h>
+#include <linux/autoconf.h>
+
+void * memcpy(void * to, const void * from, size_t n)
+{
+  const char *c_from = from;
+  char *c_to = to;
+  while (n-- > 0)
+    *c_to++ = *c_from++;
+  return((void *) to);
+}
diff -urN linux-2.4.29/arch/blackfin/lib/memset.c linux-2.4.29-uc1/arch/blackfin/lib/memset.c
--- linux-2.4.29/arch/blackfin/lib/memset.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/lib/memset.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,52 @@
+#include <linux/types.h>
+
+void * memset(void * s, int c, size_t count)
+{
+  void *xs = s;
+  size_t temp;
+
+  if (!count)
+    return xs;
+  c &= 0xff;
+  c |= c << 8;
+  c |= c << 16;
+  if ((long) s & 1)
+    {
+      char *cs = s;
+      *cs++ = c;
+      s = cs;
+      count--;
+    }
+  if (count > 2 && (long) s & 2)
+    {
+      short *ss = s;
+      *ss++ = c;
+      s = ss;
+      count -= 2;
+    }
+  temp = count >> 2;
+  if (temp)
+    {
+      long *ls = s;
+      for (; temp; temp--)
+	*ls++ = c;
+      s = ls;
+    }
+  if (count & 2)
+    {
+      short *ss = s;
+      *ss++ = c;
+      s = ss;
+    }
+  if (count & 1)
+    {
+      char *cs = s;
+      *cs = c;
+    }
+  return xs;
+}
+
+void bzero(void *s, size_t n)
+{
+	memset(s, 0, n);
+}
diff -urN linux-2.4.29/arch/blackfin/lib/muldi3.c linux-2.4.29-uc1/arch/blackfin/lib/muldi3.c
--- linux-2.4.29/arch/blackfin/lib/muldi3.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/lib/muldi3.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,96 @@
+/* Generic function got from GNU gcc package, libgcc2.c */
+#ifndef SI_TYPE_SIZE
+#define SI_TYPE_SIZE 32
+#endif
+#define __ll_B (1L << (SI_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
+#define __ll_highpart(t) ((USItype) (t) / __ll_B)
+#define BITS_PER_UNIT 8
+	
+#if !defined (umul_ppmm)
+#define umul_ppmm(w1, w0, u, v)						\
+  do {									\
+    USItype __x0, __x1, __x2, __x3;					\
+    USItype __ul, __vl, __uh, __vh;					\
+									\
+    __ul = __ll_lowpart (u);						\
+    __uh = __ll_highpart (u);						\
+    __vl = __ll_lowpart (v);						\
+    __vh = __ll_highpart (v);						\
+									\
+    __x0 = (USItype) __ul * __vl;					\
+    __x1 = (USItype) __ul * __vh;					\
+    __x2 = (USItype) __uh * __vl;					\
+    __x3 = (USItype) __uh * __vh;					\
+									\
+    __x1 += __ll_highpart (__x0);/* this can't give carry */		\
+    __x1 += __x2;		/* but this indeed can */		\
+    if (__x1 < __x2)		/* did we get it? */			\
+      __x3 += __ll_B;		/* yes, add it in the proper pos. */	\
+									\
+    (w1) = __x3 + __ll_highpart (__x1);					\
+    (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0);		\
+  } while (0)
+#endif
+
+#if !defined (__umulsidi3)
+#define __umulsidi3(u, v) \
+  ({DIunion __w;                                                        \
+       umul_ppmm (__w.s.high, __w.s.low, u, v);                            \
+           __w.ll; })
+#endif
+
+typedef unsigned int USItype    __attribute__ ((mode (SI)));
+typedef		 int SItype     __attribute__ ((mode (SI)));
+typedef		 int DItype     __attribute__ ((mode (DI)));
+typedef		int word_type __attribute__ ((mode (__word__)));
+
+/* DIstruct for little-endian ADI BlackFin, original Frio */
+struct DIstruct {SItype low, high;};
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion; 
+
+DItype __muldi3 (DItype u, DItype v)
+{
+  DIunion w;
+  DIunion uu, vv;
+ 
+  uu.ll = u,
+  vv.ll = v;
+//  panic("kernel panic for __muldi3");
+  w.ll = __umulsidi3 (uu.s.low, vv.s.low); 
+  w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
+             + (USItype) uu.s.high * (USItype) vv.s.low);
+ 
+  return w.ll;
+} 
+DItype
+__ashldi3 (DItype u, word_type b)
+{
+  DIunion w;
+  word_type bm;
+  DIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ll = u;
+
+  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      w.s.low = 0;
+      w.s.high = (USItype)uu.s.low << -bm;
+    }
+  else
+    {
+      USItype carries = (USItype)uu.s.low >> bm;
+      w.s.low = (USItype)uu.s.low << b;
+      w.s.high = ((USItype)uu.s.high << b) | carries;
+    }
+
+  return w.ll;
+}
diff -urN linux-2.4.29/arch/blackfin/Makefile linux-2.4.29-uc1/arch/blackfin/Makefile
--- linux-2.4.29/arch/blackfin/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/Makefile	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,63 @@
+# Changes made by Akbar Hussain April 04, 2001
+# frionommu/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 1999,2001  D. Jeff Dionne <jeff@lineo.ca>,
+#	                   Rt-Control Inc. / Lineo, Inc.
+#
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uclinux.org>,
+#                          Kenneth Albanowski <kjahds@kjahds.com>,
+#
+# Based on arch/m68k/Makefile:
+# Copyright (C) 1994 by Hamish Macdonald
+#
+
+# test for cross compiling
+COMPILE_ARCH = $(shell uname -m)
+
+UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\"
+
+# Find out which board we are compiling for
+
+# For FRIO it is just PLATFORM := frio & BOARD := ADI
+
+include arch/$(ARCH)/Boards.mk
+
+# Set up the memory model.  RAM or ROM.
+ifdef CONFIG_RAMKERNEL
+MODEL = ram
+else
+MODEL = rom
+endif
+export MODEL
+
+# get the compiler, flags and targets from the platform, no need for now
+ifdef PLATFORM
+include arch/$(ARCH)/platform/$(PLATFORM)/Rules.make
+endif
+
+linux.dxe: linux
+	@$(MAKEBOOT) linux.dxe
+
+arch/$(ARCH)/boot/rootfs.o:
+	@$(MAKEBOOT) rootfs.o
+
+arch/$(ARCH)/empty.o:
+	$(CROSS_COMPILE)gcc -o arch/$(ARCH)/empty.o -c arch/$(ARCH)/empty.c
+
+bootstrap:
+	@$(MAKEBOOT) bootstrap
+
+archmrproper:
+	echo CROSS_COMPILE is set to $(CROSS_COMPILE)
+	echo C compiler is $(CC)
+
+archdep:
diff -urN linux-2.4.29/arch/blackfin/mm/fault.c linux-2.4.29-uc1/arch/blackfin/mm/fault.c
--- linux-2.4.29/arch/blackfin/mm/fault.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/mm/fault.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,60 @@
+/*
+ *  linux/arch/frionommu/mm/fault.c
+ *
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com) 
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68k/mm/fault.c
+ *  linux/arch/m68knommu/mm/fault.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ *
+ */
+
+
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+
+extern void die_if_kernel(char *, struct pt_regs *, long);
+
+/*
+ * This routine handles page faults.  It determines the problem, and
+ * then passes it off to one of the appropriate routines.
+ *
+ * error_code:
+ *	bit 0 == 0 means no page found, 1 means protection fault
+ *	bit 1 == 0 means read, 1 means write
+ *
+ * If this routine detects a bad access, it returns 1, otherwise it
+ * returns 0.
+ */
+asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
+			      unsigned long error_code)
+{
+#ifdef DEBUG
+	printk ("regs->astat=%#lx, regs->pc=%#lx, address=%#lx, %ld\n",
+		regs->astat, regs->pc, address, error_code);
+#endif
+
+/*
+ * Oops. The kernel tried to access some bad page. We'll have to
+ * terminate things with extreme prejudice.
+ */
+	if ((unsigned long) address < PAGE_SIZE) {
+		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
+	} else
+		printk(KERN_ALERT "Unable to handle kernel access");
+	printk(" at virtual address %08lx\n",address);
+	die_if_kernel("Oops", regs, error_code);
+	do_exit(SIGKILL);
+
+	return 1;
+}
+
diff -urN linux-2.4.29/arch/blackfin/mm/init.c linux-2.4.29-uc1/arch/blackfin/mm/init.c
--- linux-2.4.29/arch/blackfin/mm/init.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/mm/init.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,266 @@
+/*
+ *  linux/arch/m68knommu/mm/init.c
+ *
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *                      Kenneth Albanowski <kjahds@kjahds.com>,
+ *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com) 
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68k/mm/init.c
+ *  linux/arch/m68knommu/mm/init.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ *
+ *  DEC/2000 -- linux 2.4 support <davidm@lineo.com>
+ *
+#include <asm/shglcore.h>
+ */
+
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#ifdef CONFIG_BLK_DEV_RAM
+#include <linux/blk.h>
+#endif
+#include <linux/bootmem.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/machdep.h>
+#include <asm/virtconvert.h>
+
+#undef DEBUG
+
+static unsigned long totalram_pages = 0;
+
+extern void die_if_kernel(char *,struct pt_regs *,long);
+
+extern void free_initmem(void);
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+static unsigned long empty_bad_page_table;
+
+static unsigned long empty_bad_page;
+
+unsigned long empty_zero_page;
+
+extern unsigned long rom_length;
+
+void show_mem(void)
+{
+    unsigned long i;
+    int free = 0, total = 0, reserved = 0, nonshared = 0, shared = 0;
+
+    printk("\nMem-info:\n");
+    show_free_areas();
+#if 0 /* DAVIDM */
+    printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+#endif
+    i = ((unsigned long) high_memory) >> PAGE_SHIFT;
+    while (i-- > 0) {
+	total++;
+	if (PageReserved(mem_map+i))
+	    reserved++;
+	else if (!atomic_read(&mem_map[i].count))
+	    free++;
+	else if (atomic_read(&mem_map[i].count) == 1)
+	    nonshared++;
+	else
+	    shared += atomic_read(&mem_map[i].count)-1;
+    }
+    printk("%d pages of RAM\n",total);
+    printk("%d free pages\n",free);
+    printk("%d reserved pages\n",reserved);
+    printk("%d pages nonshared\n",nonshared);
+    printk("%d pages shared\n",shared);
+    show_buffers();
+}
+
+extern unsigned long memory_start;
+extern unsigned long memory_end;
+
+/*
+ * paging_init() continues the virtual memory environment setup which
+ * was begun by the code in arch/head.S.
+ * The parameters are pointers to where to stick the starting and ending
+ * addresses  of available kernel virtual memory.
+ */
+void paging_init(void)
+{
+	/*
+	 * make sure start_mem is page aligned,  otherwise bootmem and
+	 * page_alloc get different views og the world
+	 */
+#ifdef DEBUG
+	unsigned long start_mem = PAGE_ALIGN(memory_start);
+#endif
+	unsigned long end_mem   = memory_end & PAGE_MASK;
+
+#ifdef DEBUG
+	printk ("start_mem is %#lx\nvirtual_end is %#lx\n",
+		start_mem, end_mem);
+#endif
+
+	/*
+	 * initialize the bad page table and bad page to point
+	 * to a couple of allocated pages
+	 */
+	empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	memset((void *)empty_zero_page, 0, PAGE_SIZE);
+
+	/*
+	 * Set up SFC/DFC registers (user data space)
+	 */
+	set_fs (USER_DS);
+
+#ifdef DEBUG
+	printk ("before free_area_init\n");
+
+	printk ("free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n",
+		start_mem, end_mem);
+#endif
+
+	{
+		unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+
+		zones_size[ZONE_NORMAL]     = 0 >> PAGE_SHIFT;
+		zones_size[ZONE_DMA]  = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
+#ifdef CONFIG_HIGHMEM
+		zones_size[ZONE_HIGHMEM] = 0;
+#endif
+		free_area_init_node(0, NULL, NULL, zones_size, PAGE_OFFSET, NULL);
+	}
+}
+
+void mem_init(void)
+{
+	int codek = 0, datak = 0, initk = 0;
+	/* DAVIDM look at setup memory map generically with reserved area */
+	int datapages = 0;
+	unsigned long tmp;
+#ifdef CONFIG_UCLINUX
+	extern char _etext, _stext, _sdata, _ebss, __init_begin, __init_end;
+	extern unsigned int _ramend, _rambase;
+	unsigned long len = _ramend - _rambase;
+#else
+	extern char _etext, _romvec, __data_start;
+	unsigned long len = end_mem-(unsigned long)&__data_start;
+#endif
+	unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */
+	unsigned long end_mem   = memory_end; /* DAVIDM - this must not include kernel stack at top */
+
+#ifdef DEBUG
+	printk("Mem_init: start=%lx, end=%lx\n", start_mem, end_mem);
+#endif
+
+	end_mem &= PAGE_MASK;
+	high_memory = (void *) end_mem;
+
+	start_mem = PAGE_ALIGN(start_mem);
+	max_mapnr = num_physpages = MAP_NR(high_memory);
+	printk("Physical pages: %lx\n", num_physpages);
+
+	/* this will put all memory onto the freelists */
+	totalram_pages = free_all_bootmem();
+
+	for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
+		if (PageReserved(mem_map+MAP_NR(tmp))) {
+			datapages++;
+			continue;
+		}
+	}
+	
+#ifdef CONFIG_UCLINUX
+	codek = (&_etext - &_stext) >> 10;
+	datak = (&_ebss - &_sdata) >> 10;
+	initk = (&__init_begin - &__init_end) >> 10;
+#else
+	codek = (&_etext - &_romvec) >> 10;
+	datak = datapages << (PAGE_SHIFT-10);
+	initk = 0;
+#endif
+
+	tmp = nr_free_pages() << PAGE_SHIFT;
+	printk("Memory available: %luk/%luk RAM, %luk/%luk ROM (%dk kernel code, %dk data)\n",
+	       tmp >> 10,
+	       len >> 10,
+	       (rom_length > 0) ? ((rom_length >> 10) - codek) : 0,
+	       rom_length >> 10,
+	       codek,
+	       datak
+	       );
+}
+
+void si_meminfo(struct sysinfo *val)
+{
+    unsigned long i;
+
+    i = ((unsigned long) high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
+    val->totalram = 0;
+    val->sharedram = 0;
+    val->freeram = nr_free_pages();
+    val->bufferram = atomic_read(&buffermem_pages);
+    while (i-- > 0) {
+	if (PageReserved(mem_map+i))
+	    continue;
+	val->totalram++;
+	if (!atomic_read(&mem_map[i].count))
+	    continue;
+	val->sharedram += atomic_read(&mem_map[i].count)-1;
+    }
+#ifdef CONFIG_HIGHMEM
+	val->totalhigh = totalhigh_pages;
+	val->freehigh = nr_free_highpages();
+#else
+	val->freehigh = val->totalhigh = 0;
+#endif
+	val->mem_unit = PAGE_SIZE;
+}
+
+
+void
+free_initmem()
+{
+#ifdef CONFIG_RAMKERNEL
+	unsigned long addr;
+	extern char __init_begin, __init_end;
+/*
+ *	the following code should be cool even if these sections
+ *	are not page aligned.
+ */
+	addr = PAGE_ALIGN((unsigned long)(&__init_begin));
+	/* next to check that the page we free is not a partial page */
+	for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) {
+		ClearPageReserved(mem_map + MAP_NR(addr));
+		set_page_count(mem_map+MAP_NR(addr), 1);
+		free_page(addr);
+		totalram_pages++;
+	}
+	printk("Freeing unused kernel memory: %ldk freed\n",
+			(addr - PAGE_ALIGN((long) &__init_begin)) >> 10);
+#endif
+}
+
diff -urN linux-2.4.29/arch/blackfin/mm/kmap.c linux-2.4.29-uc1/arch/blackfin/mm/kmap.c
--- linux-2.4.29/arch/blackfin/mm/kmap.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/mm/kmap.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,58 @@
+/*
+ *  linux/arch/frionommu/mm/kmap.c
+ *
+ *  Based: linux/arch/m68knommu/mm/kmap.c
+ *
+ *  Copyright (C) 2000 Lineo, <davidm@lineo.com>
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#undef DEBUG
+
+/*
+ * Map some physical address range into the kernel address space.
+ */
+
+void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
+{
+	return (void *)physaddr;
+}
+
+/*
+ * Unmap a ioremap()ed region again
+ */
+void iounmap(void *addr)
+{
+}
+
+/*
+ * __iounmap unmaps nearly everything, so be careful
+ * it doesn't free currently pointer/page tables anymore but it
+ * wans't used anyway and might be added later.
+ */
+void __iounmap(void *addr, unsigned long size)
+{
+}
+
+/*
+ * Set new cache mode for some kernel address space.
+ * The caller must push data for that range itself, if such data may already
+ * be in the cache.
+ */
+void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
+{
+}
diff -urN linux-2.4.29/arch/blackfin/mm/Makefile linux-2.4.29-uc1/arch/blackfin/mm/Makefile
--- linux-2.4.29/arch/blackfin/mm/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/mm/Makefile	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,13 @@
+#
+# Makefile for the linux frio-specific parts of the memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET := mm.o
+obj-y	 := init.o fault.o memory.o kmap.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/blackfin/mm/memory.c linux-2.4.29-uc1/arch/blackfin/mm/memory.c
--- linux-2.4.29/arch/blackfin/mm/memory.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/mm/memory.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,1031 @@
+/*
+ *  linux/arch/frionommu/mm/memory.c
+ *
+ *  Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *
+ *  MAR/1999 -- hacked for the ColdFire (gerg@lineo.com)
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68k/mm/memory.c
+ *  linux/arch/m68knommu/mm/memory.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+#include <asm/shglcore.h>
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/virtconvert.h>
+
+#ifndef NO_MM
+
+extern pte_t *kernel_page_table (unsigned long *memavailp);
+
+/* Strings for `extern inline' functions in <asm/pgtable.h>.  If put
+   directly into these functions, they are output for every file that
+   includes pgtable.h */
+
+const char PgtabStr_bad_pmd[] = "Bad pmd in pte_alloc: %08lx\n";
+const char PgtabStr_bad_pgd[] = "Bad pgd in pmd_alloc: %08lx\n";
+const char PgtabStr_bad_pmdk[] = "Bad pmd in pte_alloc_kernel: %08lx\n";
+const char PgtabStr_bad_pgdk[] = "Bad pgd in pmd_alloc_kernel: %08lx\n";
+
+static struct ptable_desc {
+	struct ptable_desc *prev;
+	struct ptable_desc *next;
+	unsigned long	   page;
+	unsigned char	   alloced;
+} ptable_list = { &ptable_list, &ptable_list, 0, 0xff };
+
+#define PD_NONEFREE(dp) ((dp)->alloced == 0xff)
+#define PD_ALLFREE(dp) ((dp)->alloced == 0)
+#define PD_TABLEFREE(dp,i) (!((dp)->alloced & (1<<(i))))
+#define PD_MARKUSED(dp,i) ((dp)->alloced |= (1<<(i)))
+#define PD_MARKFREE(dp,i) ((dp)->alloced &= ~(1<<(i)))
+
+#define PTABLE_SIZE (PTRS_PER_PMD * sizeof(pmd_t))
+
+pmd_t *get_pointer_table (void)
+{
+	pmd_t *pmdp = NULL;
+	unsigned long flags;
+	struct ptable_desc *dp = ptable_list.next;
+	int i;
+
+	/*
+	 * For a pointer table for a user process address space, a
+	 * table is taken from a page allocated for the purpose.  Each
+	 * page can hold 8 pointer tables.  The page is remapped in
+	 * virtual address space to be noncacheable.
+	 */
+	if (PD_NONEFREE (dp)) {
+
+		if (!(dp = kmalloc (sizeof(struct ptable_desc),GFP_KERNEL))) {
+			return 0;
+		}
+
+		if (!(dp->page = __get_free_page (GFP_KERNEL))) {
+			kfree (dp);
+			return 0;
+		}
+
+		nocache_page (dp->page);
+
+		dp->alloced = 0;
+		/* put at head of list */
+		save_flags(flags);
+		cli();
+		dp->next = ptable_list.next;
+		dp->prev = ptable_list.next->prev;
+		ptable_list.next->prev = dp;
+		ptable_list.next = dp;
+		restore_flags(flags);
+	}
+
+	for (i = 0; i < 8; i++)
+		if (PD_TABLEFREE (dp, i)) {
+			PD_MARKUSED (dp, i);
+			pmdp = (pmd_t *)(dp->page + PTABLE_SIZE*i);
+			break;
+		}
+
+	if (PD_NONEFREE (dp)) {
+		/* move to end of list */
+		save_flags(flags);
+		cli();
+		dp->prev->next = dp->next;
+		dp->next->prev = dp->prev;
+
+		dp->next = ptable_list.next->prev;
+		dp->prev = ptable_list.prev;
+		ptable_list.prev->next = dp;
+		ptable_list.prev = dp;
+		restore_flags(flags);
+	}
+
+	memset (pmdp, 0, PTABLE_SIZE);
+
+	return pmdp;
+}
+
+void free_pointer_table (pmd_t *ptable)
+{
+	struct ptable_desc *dp;
+	unsigned long page = (unsigned long)ptable & PAGE_MASK;
+	int index = ((unsigned long)ptable - page)/PTABLE_SIZE;
+	unsigned long flags;
+
+	for (dp = ptable_list.next; dp->page && dp->page != page; dp = dp->next)
+		;
+
+	if (!dp->page)
+		panic ("unable to find desc for ptable %p on list!", ptable);
+
+	if (PD_TABLEFREE (dp, index))
+		panic ("table already free!");
+
+	PD_MARKFREE (dp, index);
+
+	if (PD_ALLFREE (dp)) {
+		/* all tables in page are free, free page */
+		save_flags(flags);
+		cli();
+		dp->prev->next = dp->next;
+		dp->next->prev = dp->prev;
+		restore_flags(flags);
+		cache_page (dp->page);
+		free_page (dp->page);
+		kfree (dp);
+		return;
+	} else {
+		/*
+		 * move this descriptor the the front of the list, since
+		 * it has one or more free tables.
+		 */
+		save_flags(flags);
+		cli();
+		dp->prev->next = dp->next;
+		dp->next->prev = dp->prev;
+
+		dp->next = ptable_list.next;
+		dp->prev = ptable_list.next->prev;
+		ptable_list.next->prev = dp;
+		ptable_list.next = dp;
+		restore_flags(flags);
+	}
+}
+
+/* maximum pages used for kpointer tables */
+#define KPTR_PAGES      4
+/* # of reserved slots */
+#define RESERVED_KPTR	4
+extern pmd_tablepage kernel_pmd_table; /* reserved in head.S */
+
+static struct kpointer_pages {
+        pmd_tablepage *page[KPTR_PAGES];
+        u_char alloced[KPTR_PAGES];
+} kptr_pages;
+
+void init_kpointer_table(void) {
+	short i = KPTR_PAGES-1;
+
+	/* first page is reserved in head.S */
+	kptr_pages.page[i] = &kernel_pmd_table;
+	kptr_pages.alloced[i] = ~(0xff>>RESERVED_KPTR);
+	for (i--; i>=0; i--) {
+		kptr_pages.page[i] = NULL;
+		kptr_pages.alloced[i] = 0;
+	}
+}
+
+pmd_t *get_kpointer_table (void)
+{
+	/* For pointer tables for the kernel virtual address space,
+	 * use the page that is reserved in head.S that can hold up to
+	 * 8 pointer tables. 3 of these tables are always reserved
+	 * (kernel_pg_dir, swapper_pg_dir and kernel pointer table for
+	 * the first 16 MB of RAM). In addition, the 4th pointer table
+	 * in this page is reserved. On Amiga and Atari, it is used to
+	 * map in the hardware registers. It may be used for other
+	 * purposes on other 68k machines. This leaves 4 pointer tables
+	 * available for use by the kernel. 1 of them are usually used
+	 * for the vmalloc tables. This allows mapping of 3 * 32 = 96 MB
+	 * of physical memory. But these pointer tables are also used
+	 * for other purposes, like kernel_map(), so further pages can
+	 * now be allocated.
+	 */
+	pmd_tablepage *page;
+	pmd_table *table;
+	long nr, offset = -8;
+	short i;
+
+	for (i=KPTR_PAGES-1; i>=0; i--) {
+		asm volatile("bfffo %1{%2,#8},%0"
+			: "=d" (nr)
+			: "d" ((u_char)~kptr_pages.alloced[i]), "d" (offset));
+		if (nr)
+			break;
+	}
+	if (i < 0) {
+		printk("No space for kernel pointer table!\n");
+		return NULL;
+	}
+	if (!(page = kptr_pages.page[i])) {
+		if (!(page = (pmd_tablepage *)__get_free_page(GFP_KERNEL))) {
+			printk("No space for kernel pointer table!\n");
+			return NULL;
+		}
+		nocache_page((u_long)(kptr_pages.page[i] = page));
+	}
+	asm volatile("bfset %0@{%1,#1}"
+		: /* no output */
+		: "a" (&kptr_pages.alloced[i]), "d" (nr-offset));
+	table = &(*page)[nr-offset];
+	memset(table, 0, sizeof(pmd_table));
+	return ((pmd_t *)table);
+}
+
+void free_kpointer_table (pmd_t *pmdp)
+{
+	pmd_table *table = (pmd_table *)pmdp;
+	pmd_tablepage *page = (pmd_tablepage *)((u_long)table & PAGE_MASK);
+	long nr;
+	short i;
+
+	for (i=KPTR_PAGES-1; i>=0; i--) {
+		if (kptr_pages.page[i] == page)
+			break;
+	}
+	nr = ((u_long)table - (u_long)page) / sizeof(pmd_table);
+	if (!table || i < 0 || (i == KPTR_PAGES-1 && nr < RESERVED_KPTR)) {
+		printk("Attempt to free invalid kernel pointer table: %p\n", table);
+		return;
+	}
+	asm volatile("bfclr %0@{%1,#1}"
+		: /* no output */
+		: "a" (&kptr_pages.alloced[i]), "d" (nr));
+	if (!kptr_pages.alloced[i]) {
+		kptr_pages.page[i] = 0;
+		cache_page ((u_long)page);
+		free_page ((u_long)page);
+	}
+}
+
+static unsigned long transp_transl_matches( unsigned long regval,
+					    unsigned long vaddr )
+{
+    unsigned long base, mask;
+
+    /* enabled? */
+    if (!(regval & 0x8000))
+	return( 0 );
+
+    if (CPU_IS_030) {
+	/* function code match? */
+	base = (regval >> 4) & 7;
+	mask = ~(regval & 7);
+	if ((SUPER_DATA & mask) != (base & mask))
+	    return( 0 );
+    }
+    else {
+	/* must not be user-only */
+	if ((regval & 0x6000) == 0)
+	    return( 0 );
+    }
+
+    /* address match? */
+    base = regval & 0xff000000;
+    mask = ~((regval << 8) & 0xff000000);
+    return( (vaddr & mask) == (base & mask) );
+}
+
+/*
+ * The following two routines map from a physical address to a kernel
+ * virtual address and vice versa.
+ */
+unsigned long mm_vtop (unsigned long vaddr)
+{
+	int i;
+	unsigned long voff = vaddr;
+	unsigned long offset = 0;
+
+	for (i = 0; i < boot_info.num_memory; i++)
+	{
+		if (voff < offset + boot_info.memory[i].size) {
+#ifdef DEBUGPV
+			printk ("virt_to_phys(%lx)=%lx\n", vaddr,
+				boot_info.memory[i].addr + voff - offset);
+#endif
+			return boot_info.memory[i].addr + voff - offset;
+		} else
+			offset += boot_info.memory[i].size;
+	}
+
+	/* not in one of the memory chunks; test for applying transparent
+	 * translation */
+
+	if (CPU_IS_030) {
+	    unsigned long ttreg;
+
+	    asm volatile(   "movel %1, %%a2\n\t"
+			    ".long 0xf0120a00;" /* pmove %/tt0,%a0@ */
+			  : "=g" (ttreg) : "g" (&ttreg) : "cc", "%a2" );
+	    if (transp_transl_matches( ttreg, vaddr ))
+		return vaddr;
+
+	    asm volatile(   "movel %1, %%a2\n\t"
+			    ".long 0xf0120a00" /* pmove %/tt1,%a0@ */
+			  : "=g" (ttreg) : "g" (&ttreg) : "cc", "%a2" );
+	    if (transp_transl_matches( ttreg, vaddr ))
+		return vaddr;
+	}
+	else if (CPU_IS_040_OR_060) {
+	    unsigned long ttreg;
+	    
+	    asm volatile(   ".long 0x4e7a0006\n\t" /* movec %dtt0,%d0 */
+			    "movel %%d0, %0\n"
+			  : "=g" (ttreg) );
+	    if (transp_transl_matches( ttreg, vaddr ))
+		return vaddr;
+	    asm volatile(   ".long 0x4e7a0007" /* movec %dtt1,%d0 */
+			    "movel %%d0, %0\n"
+			  : "=g" (ttreg) );
+	    if (transp_transl_matches( ttreg, vaddr ))
+		return vaddr;
+	}
+
+	/* no match, too, so get the actual physical address from the MMU. */
+
+	if (CPU_IS_060) {
+	  unsigned long fs = get_fs();
+	  unsigned long  paddr;
+
+	  set_fs (SUPER_DATA);
+
+	  /* The PLPAR instruction causes an access error if the translation
+	   * is not possible. We don't catch that here, so a bad kernel trap
+	   * will be reported in this case. */
+	  asm volatile ("movel %1,%/a0\n\t"
+			".word 0xf5c8\n\t"	/* plpar (a0) */
+			"movel %/a0,%0"
+			: "=g" (paddr)
+			: "g" (vaddr)
+			: "a0" );
+	  set_fs (fs);
+
+	  return paddr;
+
+	} else if (CPU_IS_040) {
+	  unsigned long mmusr;
+	  unsigned long fs = get_fs();
+
+	  set_fs (SUPER_DATA);
+
+	  asm volatile ("movel %1,%/a0\n\t"
+			".word 0xf568\n\t"	/* ptestr (a0) */
+			".long 0x4e7a8805\n\t"	/* movec mmusr, a0 */
+			"movel %/a0,%0"
+			: "=g" (mmusr)
+			: "g" (vaddr)
+			: "a0", "d0");
+	  set_fs (fs);
+
+	  if (mmusr & MMU_R_040)
+	    return (mmusr & PAGE_MASK) | (vaddr & (PAGE_SIZE-1));
+
+	  panic ("virt_to_phys040: bad virtual address %08lx (%lx)", vaddr, mmusr);
+	} else {
+	  volatile unsigned short temp;
+	  unsigned short mmusr;
+	  unsigned long *descaddr;
+
+	  asm volatile ("ptestr #5,%2@,#7,%0\n\t"
+			"pmove %/psr,%1@"
+			: "=a&" (descaddr)
+			: "a" (&temp), "a" (vaddr));
+	  mmusr = temp;
+
+	  if (mmusr & (MMU_I|MMU_B|MMU_L))
+	    panic ("virt_to_phys030: bad virtual address %08lx (%x)", vaddr, mmusr);
+
+	  descaddr = (unsigned long *)phys_to_virt(descaddr);
+
+	  switch (mmusr & MMU_NUM) {
+	  case 1:
+	    return (*descaddr & 0xfe000000) | (vaddr & 0x01ffffff);
+	  case 2:
+	    return (*descaddr & 0xfffc0000) | (vaddr & 0x0003ffff);
+	  case 3:
+	    return (*descaddr & PAGE_MASK) | (vaddr & (PAGE_SIZE-1));
+	  default:
+	    panic ("virt_to_phys: bad levels (%u) for virtual address %08lx", 
+		   mmusr & MMU_NUM, vaddr);
+	  }
+	}
+
+	panic ("virt_to_phys: bad virtual address %08lx", vaddr);
+}
+
+unsigned long mm_ptov (unsigned long paddr)
+{
+	int i;
+	unsigned long offset = 0;
+
+	for (i = 0; i < boot_info.num_memory; i++)
+	{
+		if (paddr >= boot_info.memory[i].addr &&
+		    paddr < (boot_info.memory[i].addr
+			     + boot_info.memory[i].size)) {
+#ifdef DEBUGPV
+			printk ("phys_to_virt(%lx)=%lx\n", paddr,
+				(paddr - boot_info.memory[i].addr) + offset);
+#endif
+			return (paddr - boot_info.memory[i].addr) + offset;
+		} else
+			offset += boot_info.memory[i].size;
+	}
+
+	/*
+	 * assume that the kernel virtual address is the same as the
+	 * physical address.
+	 *
+	 * This should be reasonable in most situations:
+	 *  1) They shouldn't be dereferencing the virtual address
+	 *     unless they are sure that it is valid from kernel space.
+	 *  2) The only usage I see so far is converting a page table
+	 *     reference to some non-FASTMEM address space when freeing
+         *     mmaped "/dev/mem" pages.  These addresses are just passed
+	 *     to "free_page", which ignores addresses that aren't in
+	 *     the memory list anyway.
+	 *
+	 */
+
+	/*
+	 * if on an amiga and address is in first 16M, move it 
+	 * to the ZTWO_ADDR range
+	 */
+	if (MACH_IS_AMIGA && paddr < 16*1024*1024)
+		return ZTWO_VADDR(paddr);
+	return paddr;
+}
+
+/* invalidate page in both caches */
+#define	clear040(paddr) __asm__ __volatile__ ("movel %0,%/a0\n\t"\
+					      "nop\n\t"\
+					      ".word 0xf4d0"\
+					      /* CINVP I/D (a0) */\
+					      : : "g" ((paddr))\
+					      : "a0")
+
+/* invalidate page in i-cache */
+#define	cleari040(paddr) __asm__ __volatile__ ("movel %0,%/a0\n\t"\
+					       /* CINVP I (a0) */\
+					       "nop\n\t"\
+					       ".word 0xf490"\
+					       : : "g" ((paddr))\
+					       : "a0")
+
+/* push page in both caches */
+#define	push040(paddr) __asm__ __volatile__ ("movel %0,%/a0\n\t"\
+					      "nop\n\t"\
+					     ".word 0xf4f0"\
+					     /* CPUSHP I/D (a0) */\
+					     : : "g" ((paddr))\
+					     : "a0")
+
+/* push and invalidate page in both caches */
+#define	pushcl040(paddr) do { push040((paddr));\
+			      if (CPU_IS_060) clear040((paddr));\
+			 } while(0)
+
+/* push page in both caches, invalidate in i-cache */
+#define	pushcli040(paddr) do { push040((paddr));\
+			       if (CPU_IS_060) cleari040((paddr));\
+			  } while(0)
+
+/* push page defined by virtual address in both caches */
+#define	pushv040(vaddr) __asm__ __volatile__ ("movel %0,%/a0\n\t"\
+					      /* ptestr (a0) */\
+					      "nop\n\t"\
+					      ".word 0xf568\n\t"\
+					      /* movec mmusr,d0 */\
+					      ".long 0x4e7a0805\n\t"\
+					      "andw #0xf000,%/d0\n\t"\
+					      "movel %/d0,%/a0\n\t"\
+					      /* CPUSHP I/D (a0) */\
+					      "nop\n\t"\
+					      ".word 0xf4f0"\
+					      : : "g" ((vaddr))\
+					      : "a0", "d0")
+
+/* push page defined by virtual address in both caches */
+#define	pushv060(vaddr) __asm__ __volatile__ ("movel %0,%/a0\n\t"\
+					      /* plpar (a0) */\
+					      ".word 0xf5c8\n\t"\
+					      /* CPUSHP I/D (a0) */\
+					      ".word 0xf4f0"\
+					      : : "g" ((vaddr))\
+					      : "a0")
+
+
+/*
+ * 040: Hit every page containing an address in the range paddr..paddr+len-1.
+ * (Low order bits of the ea of a CINVP/CPUSHP are "don't care"s).
+ * Hit every page until there is a page or less to go. Hit the next page,
+ * and the one after that if the range hits it.
+ */
+/* ++roman: A little bit more care is required here: The CINVP instruction
+ * invalidates cache entries WITHOUT WRITING DIRTY DATA BACK! So the beginning
+ * and the end of the region must be treated differently if they are not
+ * exactly at the beginning or end of a page boundary. Else, maybe too much
+ * data becomes invalidated and thus lost forever. CPUSHP does what we need:
+ * it invalidates the page after pushing dirty data to memory. (Thanks to Jes
+ * for discovering the problem!)
+ */
+/* ... but on the '060, CPUSH doesn't invalidate (for us, since we have set
+ * the DPI bit in the CACR; would it cause problems with temporarily changing
+ * this?). So we have to push first and then additionally to invalidate.
+ */
+
+/*
+ * cache_clear() semantics: Clear any cache entries for the area in question,
+ * without writing back dirty entries first. This is useful if the data will
+ * be overwritten anyway, e.g. by DMA to memory. The range is defined by a
+ * _physical_ address.
+ */
+
+void cache_clear (unsigned long paddr, int len)
+{
+    if (CPU_IS_040_OR_060) {
+	/*
+	 * cwe need special treatment for the first page, in case it
+	 * is not page-aligned.
+	 */
+	if (paddr & (PAGE_SIZE - 1)){
+	    pushcl040(paddr);
+	    if (len <= PAGE_SIZE){
+		if (((paddr + len - 1) ^ paddr) & PAGE_MASK) {
+		    pushcl040(paddr + len - 1);
+		}
+		return;
+	    }else{
+		len -=PAGE_SIZE;
+		paddr += PAGE_SIZE;
+	    }
+	}
+		
+	while (len > PAGE_SIZE) {
+#if 0
+	    pushcl040(paddr);
+#else
+	    clear040(paddr);
+#endif
+	    len -= PAGE_SIZE;
+	    paddr += PAGE_SIZE;
+	}
+	if (len > 0) {
+	    pushcl040(paddr);
+	    if (((paddr + len - 1) ^ paddr) & PAGE_MASK) {
+		/* a page boundary gets crossed at the end */
+		pushcl040(paddr + len - 1);
+	    }
+	}
+    }
+    else /* 68030 or 68020 */
+	asm volatile ("movec %/cacr,%/d0\n\t"
+		      "oriw %0,%/d0\n\t"
+		      "movec %/d0,%/cacr"
+		      : : "i" (FLUSH_I_AND_D)
+		      : "d0");
+}
+
+
+/*
+ * cache_push() semantics: Write back any dirty cache data in the given area,
+ * and invalidate the range in the instruction cache. It needs not (but may)
+ * invalidate those entries also in the data cache. The range is defined by a
+ * _physical_ address.
+ */
+
+void cache_push (unsigned long paddr, int len)
+{
+    if (CPU_IS_040_OR_060) {
+	/*
+         * on 68040 or 68060, push cache lines for pages in the range;
+	 * on the '040 this also invalidates the pushed lines, but not on
+	 * the '060!
+	 */
+	while (len > PAGE_SIZE) {
+	    pushcli040(paddr);
+	    len -= PAGE_SIZE;
+	    paddr += PAGE_SIZE;
+	    }
+	if (len > 0) {
+	    pushcli040(paddr);
+	    if (((paddr + len - 1) ^ paddr) & PAGE_MASK) {
+		/* a page boundary gets crossed at the end */
+		pushcli040(paddr + len - 1);
+		}
+	    }
+	}
+    
+    
+    /*
+     * 68030/68020 have no writeback cache. On the other hand,
+     * cache_push is actually a superset of cache_clear (the lines
+     * get written back and invalidated), so we should make sure
+     * to perform the corresponding actions. After all, this is getting
+     * called in places where we've just loaded code, or whatever, so
+     * flushing the icache is appropriate; flushing the dcache shouldn't
+     * be required.
+     */
+    else /* 68030 or 68020 */
+	asm volatile ("movec %/cacr,%/d0\n\t"
+		      "oriw %0,%/d0\n\t"
+		      "movec %/d0,%/cacr"
+		      : : "i" (FLUSH_I)
+		      : "d0");
+}
+
+
+/*
+ * cache_push_v() semantics: Write back any dirty cache data in the given
+ * area, and invalidate those entries at least in the instruction cache. This
+ * is intended to be used after data has been written that can be executed as
+ * code later. The range is defined by a _user_mode_ _virtual_ address  (or,
+ * more exactly, the space is defined by the %sfc/%dfc register.)
+ */
+
+void cache_push_v (unsigned long vaddr, int len)
+{
+    if (CPU_IS_040) {
+	/* on 68040, push cache lines for pages in the range */
+	while (len > PAGE_SIZE) {
+	    pushv040(vaddr);
+	    len -= PAGE_SIZE;
+	    vaddr += PAGE_SIZE;
+	    }
+	if (len > 0) {
+	    pushv040(vaddr);
+	    if (((vaddr + len - 1) ^ vaddr) & PAGE_MASK) {
+		/* a page boundary gets crossed at the end */
+		pushv040(vaddr + len - 1);
+		}
+	    }
+	}
+    else if (CPU_IS_060) {
+	/* on 68040, push cache lines for pages in the range */
+	while (len > PAGE_SIZE) {
+	    pushv060(vaddr);
+	    len -= PAGE_SIZE;
+	    vaddr += PAGE_SIZE;
+	}
+	if (len > 0) {
+	    pushv060(vaddr);
+	    if (((vaddr + len - 1) ^ vaddr) & PAGE_MASK) {
+		/* a page boundary gets crossed at the end */
+		pushv060(vaddr + len - 1);
+	    }
+	}
+    }
+    /* 68030/68020 have no writeback cache; still need to clear icache. */
+    else /* 68030 or 68020 */
+	asm volatile ("movec %/cacr,%/d0\n\t"
+		      "oriw %0,%/d0\n\t"
+		      "movec %/d0,%/cacr"
+		      : : "i" (FLUSH_I)
+		      : "d0");
+}
+
+#undef clear040
+#undef cleari040
+#undef push040
+#undef pushcl040
+#undef pushcli040
+#undef pushv040
+#undef pushv060
+
+unsigned long mm_phys_to_virt (unsigned long addr)
+{
+    return phys_to_virt (addr);
+}
+
+int mm_end_of_chunk (unsigned long addr, int len)
+{
+	int i;
+
+	for (i = 0; i < boot_info.num_memory; i++)
+		if (boot_info.memory[i].addr + boot_info.memory[i].size
+		    == addr + len)
+			return 1;
+	return 0;
+}
+
+/* Map some physical address range into the kernel address space. The
+ * code is copied and adapted from map_chunk().
+ */
+
+unsigned long kernel_map(unsigned long paddr, unsigned long size,
+			 int nocacheflag, unsigned long *memavailp )
+{
+#define STEP_SIZE	(256*1024)
+
+	static unsigned long vaddr = 0xe0000000; /* safe place */
+	unsigned long physaddr, retaddr;
+	pte_t *ktablep = NULL;
+	pmd_t *kpointerp;
+	pgd_t *page_dir;
+	int pindex;   /* index into pointer table */
+	int prot;
+	
+	/* Round down 'paddr' to 256 KB and adjust size */
+	physaddr = paddr & ~(STEP_SIZE-1);
+	size += paddr - physaddr;
+	retaddr = vaddr + (paddr - physaddr);
+	paddr = physaddr;
+	/* Round up the size to 256 KB. It doesn't hurt if too much is
+	 * mapped... */
+	size = (size + STEP_SIZE - 1) & ~(STEP_SIZE-1);
+
+	if (CPU_IS_040_OR_060) {
+		prot = _PAGE_PRESENT | _PAGE_GLOBAL040;
+		switch( nocacheflag ) {
+		  case KERNELMAP_FULL_CACHING:
+			prot |= _PAGE_CACHE040;
+			break;
+		  case KERNELMAP_NOCACHE_SER:
+		  default:
+			prot |= _PAGE_NOCACHE_S;
+			break;
+		  case KERNELMAP_NOCACHE_NONSER:
+			prot |= _PAGE_NOCACHE;
+			break;
+		  case KERNELMAP_NO_COPYBACK:
+			prot |= _PAGE_CACHE040W;
+			/* prot |= 0; */
+			break;
+		}
+	} else
+		prot = _PAGE_PRESENT |
+			   ((nocacheflag == KERNELMAP_FULL_CACHING ||
+				 nocacheflag == KERNELMAP_NO_COPYBACK) ? 0 : _PAGE_NOCACHE030);
+	
+	page_dir = pgd_offset_k(vaddr);
+	if (pgd_present(*page_dir)) {
+		kpointerp = (pmd_t *)pgd_page(*page_dir);
+		pindex = (vaddr >> 18) & 0x7f;
+		if (pindex != 0 && CPU_IS_040_OR_060) {
+			if (pmd_present(*kpointerp))
+				ktablep = (pte_t *)pmd_page(*kpointerp);
+			else {
+				ktablep = kernel_page_table (memavailp);
+				/* Make entries invalid */
+				memset( ktablep, 0, sizeof(long)*PTRS_PER_PTE);
+				pmd_set(kpointerp,ktablep);
+			}
+			ktablep += (pindex & 15)*64;
+		}
+	}
+	else {
+		/* we need a new pointer table */
+		kpointerp = get_kpointer_table ();
+		pgd_set(page_dir, (pmd_t *)kpointerp);
+		memset( kpointerp, 0, PTRS_PER_PMD*sizeof(pmd_t));
+		pindex = 0;
+	}
+
+	for (physaddr = paddr; physaddr < paddr + size; vaddr += STEP_SIZE) {
+
+		if (pindex > 127) {
+			/* we need a new pointer table */
+			kpointerp = get_kpointer_table ();
+			pgd_set(pgd_offset_k(vaddr), (pmd_t *)kpointerp);
+			memset( kpointerp, 0, PTRS_PER_PMD*sizeof(pmd_t));
+			pindex = 0;
+		}
+
+		if (CPU_IS_040_OR_060) {
+			int i;
+			unsigned long ktable;
+
+			/*
+			 * 68040, use page tables pointed to by the
+			 * kernel pointer table.
+			 */
+
+			if ((pindex & 15) == 0) {
+				/* Need new page table every 4M on the '040 */
+				ktablep = kernel_page_table (memavailp);
+				/* Make entries invalid */
+				memset( ktablep, 0, sizeof(long)*PTRS_PER_PTE);
+			}
+
+			ktable = virt_to_phys(ktablep);
+
+			/*
+			 * initialize section of the page table mapping
+			 * this 1M portion.
+			 */
+			for (i = 0; i < 64; i++) {
+				pte_val(*ktablep++) = physaddr | prot;
+				physaddr += PAGE_SIZE;
+			}
+
+			/*
+			 * make the kernel pointer table point to the
+			 * kernel page table.
+			 */
+
+			((unsigned long *)kpointerp)[pindex++] = ktable | _PAGE_TABLE;
+
+		} else {
+			/*
+			 * 68030, use early termination page descriptors.
+			 * Each one points to 64 pages (256K).
+			 */
+			((unsigned long *)kpointerp)[pindex++] = physaddr | prot;
+			physaddr += 64 * PAGE_SIZE;
+		}
+	}
+
+	return( retaddr );
+}
+
+
+static inline void set_cmode_pte( pmd_t *pmd, unsigned long address,
+				  unsigned long size, unsigned cmode )
+{	pte_t *pte;
+	unsigned long end;
+
+	if (pmd_none(*pmd))
+		return;
+
+	pte = pte_offset( pmd, address );
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end >= PMD_SIZE)
+		end = PMD_SIZE;
+
+	for( ; address < end; pte++ ) {
+		pte_val(*pte) = (pte_val(*pte) & ~_PAGE_NOCACHE) | cmode;
+		address += PAGE_SIZE;
+	}
+}
+
+
+static inline void set_cmode_pmd( pgd_t *dir, unsigned long address,
+				  unsigned long size, unsigned cmode )
+{
+	pmd_t *pmd;
+	unsigned long end;
+
+	if (pgd_none(*dir))
+		return;
+
+	pmd = pmd_offset( dir, address );
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+
+	if ((pmd_val(*pmd) & _DESCTYPE_MASK) == _PAGE_PRESENT) {
+		/* 68030 early termination descriptor */
+		pmd_val(*pmd) = (pmd_val(*pmd) & ~_PAGE_NOCACHE) | cmode;
+		return;
+	}
+	else {
+		/* "normal" tables */
+		for( ; address < end; pmd++ ) {
+			set_cmode_pte( pmd, address, end - address, cmode );
+			address = (address + PMD_SIZE) & PMD_MASK;
+		}
+	}
+}
+
+
+/*
+ * Set new cache mode for some kernel address space.
+ * The caller must push data for that range itself, if such data may already
+ * be in the cache.
+ */
+
+void kernel_set_cachemode( unsigned long address, unsigned long size,
+						   unsigned cmode )
+{
+	pgd_t *dir = pgd_offset_k( address );
+	unsigned long end = address + size;
+	
+	if (CPU_IS_040_OR_060) {
+		switch( cmode ) {
+		  case KERNELMAP_FULL_CACHING:
+			cmode = _PAGE_CACHE040;
+			break;
+		  case KERNELMAP_NOCACHE_SER:
+		  default:
+			cmode = _PAGE_NOCACHE_S;
+			break;
+		  case KERNELMAP_NOCACHE_NONSER:
+			cmode = _PAGE_NOCACHE;
+			break;
+		  case KERNELMAP_NO_COPYBACK:
+			cmode = _PAGE_CACHE040W;
+			break;
+		}
+	} else
+		cmode = ((cmode == KERNELMAP_FULL_CACHING ||
+				  cmode == KERNELMAP_NO_COPYBACK)    ?
+			 0 : _PAGE_NOCACHE030);
+
+	for( ; address < end; dir++ ) {
+		set_cmode_pmd( dir, address, end - address, cmode );
+		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+	}
+	flush_tlb_all();
+}
+
+#else /* !NO_MM */
+
+/*
+ * 040: Hit every page containing an address in the range paddr..paddr+len-1.
+ * (Low order bits of the ea of a CINVP/CPUSHP are "don't care"s).
+ * Hit every page until there is a page or less to go. Hit the next page,
+ * and the one after that if the range hits it.
+ */
+/* ++roman: A little bit more care is required here: The CINVP instruction
+ * invalidates cache entries WITHOUT WRITING DIRTY DATA BACK! So the beginning
+ * and the end of the region must be treated differently if they are not
+ * exactly at the beginning or end of a page boundary. Else, maybe too much
+ * data becomes invalidated and thus lost forever. CPUSHP does what we need:
+ * it invalidates the page after pushing dirty data to memory. (Thanks to Jes
+ * for discovering the problem!)
+ */
+/* ... but on the '060, CPUSH doesn't invalidate (for us, since we have set
+ * the DPI bit in the CACR; would it cause problems with temporarily changing
+ * this?). So we have to push first and then additionally to invalidate.
+ */
+
+/*
+ * cache_clear() semantics: Clear any cache entries for the area in question,
+ * without writing back dirty entries first. This is useful if the data will
+ * be overwritten anyway, e.g. by DMA to memory. The range is defined by a
+ * _physical_ address.
+ */
+
+void cache_clear (unsigned long paddr, int len)
+{
+}
+
+
+/*
+ *	Define cache invalidate functions. Anything
+ *	that has separate data and instruction caches will be a problem.
+ */
+#define	cache_invalidate_lines(a,b)
+
+
+/*
+ * cache_push() semantics: Write back any dirty cache data in the given area,
+ * and invalidate the range in the instruction cache. It needs not (but may)
+ * invalidate those entries also in the data cache. The range is defined by a
+ * _physical_ address.
+ */
+
+void cache_push (unsigned long paddr, int len)
+{
+	cache_invalidate_lines(paddr, len);
+}
+
+
+/*
+ * cache_push_v() semantics: Write back any dirty cache data in the given
+ * area, and invalidate those entries at least in the instruction cache. This
+ * is intended to be used after data has been written that can be executed as
+ * code later. The range is defined by a _user_mode_ _virtual_ address  (or,
+ * more exactly, the space is defined by the %sfc/%dfc register.)
+ */
+
+void cache_push_v (unsigned long vaddr, int len)
+{
+	cache_invalidate_lines(vaddr, len);
+}
+
+unsigned long mm_phys_to_virt (unsigned long addr)
+{
+    return phys_to_virt (addr);
+}
+
+/* Map some physical address range into the kernel address space. The
+ * code is copied and adapted from map_chunk().
+ */
+
+unsigned long kernel_map(unsigned long paddr, unsigned long size,
+			 int nocacheflag, unsigned long *memavailp )
+{
+	return paddr;
+}
+
+
+#ifdef MAGIC_ROM_PTR
+int is_in_rom(unsigned long addr) {
+	extern unsigned long    _ramstart, _ramend;
+
+	/* Anything not in operational RAM is returned as in rom! */
+	if ((addr >= _ramstart) && (addr < _ramend))
+		return(0);
+	return(1);
+}
+#endif
+
+#endif /* !NO_MM */
diff -urN linux-2.4.29/arch/blackfin/platform/533/ADI/bootlogo.h linux-2.4.29-uc1/arch/blackfin/platform/533/ADI/bootlogo.h
--- linux-2.4.29/arch/blackfin/platform/533/ADI/bootlogo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/ADI/bootlogo.h	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,270 @@
+#define bootlogo_width 160
+#define bootlogo_height 160
+static unsigned char bootlogo_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x55,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x08, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00,
+  0x00, 0xff, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0xf8, 0x80, 0x0f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x50, 0x04, 0x00, 0x00, 0x00, 0x78, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x03, 0x00, 0x00,
+  0x00, 0x78, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x40,
+  0xa8, 0x02, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x70, 0x28, 0x01, 0x00, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x20, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x70,
+  0x54, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x80, 0x01, 0x3a, 0x78, 0x80, 0x0e,
+  0x50, 0xc0, 0x03, 0x0e, 0x00, 0x20, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00,
+  0x00, 0x3e, 0xf0, 0x83, 0x1f, 0xfc, 0xe0, 0x0f, 0x78, 0xf8, 0x87, 0x1f,
+  0x00, 0x18, 0x00, 0x30, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xf8, 0xc3,
+  0x1f, 0xfc, 0xe0, 0x0f, 0x78, 0xf8, 0x87, 0x0f, 0x00, 0x20, 0x00, 0x10,
+  0x55, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xc0, 0x03, 0x9f, 0xf3, 0x80, 0x0f,
+  0x78, 0x80, 0xc7, 0x0e, 0x00, 0x18, 0x00, 0x20, 0xaa, 0x00, 0x00, 0x00,
+  0x00, 0x1e, 0xe0, 0x03, 0x9f, 0xf1, 0x80, 0x07, 0x78, 0x80, 0x67, 0x00,
+  0x00, 0x24, 0x00, 0x18, 0x55, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x01,
+  0x5e, 0xf0, 0x80, 0x07, 0x3c, 0x00, 0x2f, 0x00, 0x00, 0x14, 0x00, 0x20,
+  0xaa, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x01, 0x7f, 0xf0, 0x80, 0x07,
+  0x3c, 0x00, 0x3f, 0x00, 0x00, 0x08, 0x00, 0x18, 0x55, 0x00, 0x00, 0x00,
+  0x00, 0x0f, 0xe0, 0x00, 0x3f, 0xf0, 0xc0, 0x03, 0x1e, 0x00, 0x1f, 0x00,
+  0x00, 0x14, 0x00, 0x28, 0xaa, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xf0, 0x00,
+  0x1f, 0xf0, 0xc0, 0x03, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x04, 0x00, 0x0c,
+  0x54, 0x00, 0x00, 0x00, 0x80, 0x07, 0x78, 0x00, 0x1f, 0x78, 0xc0, 0x03,
+  0x1f, 0x00, 0x1e, 0x00, 0x00, 0x0a, 0x00, 0x12, 0xa8, 0x00, 0x00, 0x00,
+  0x80, 0x07, 0x78, 0x00, 0x1f, 0x78, 0xe0, 0x03, 0x1f, 0x00, 0x1f, 0x00,
+  0x00, 0x04, 0x00, 0x0a, 0x54, 0x00, 0x00, 0x00, 0x80, 0x07, 0x78, 0x80,
+  0x0f, 0x78, 0xe0, 0x03, 0x1f, 0x00, 0x1e, 0x00, 0x00, 0x0a, 0x00, 0x08,
+  0x50, 0x01, 0x00, 0x00, 0x84, 0x03, 0x78, 0x80, 0x07, 0x3c, 0xe0, 0xc1,
+  0x0f, 0x00, 0x1f, 0x00, 0x00, 0x04, 0x00, 0x06, 0xa8, 0x00, 0x00, 0x00,
+  0xc0, 0x03, 0x78, 0xc0, 0x07, 0x3c, 0xe0, 0xc1, 0x0f, 0x00, 0x1f, 0x00,
+  0x00, 0x0a, 0x00, 0x08, 0x50, 0x01, 0x00, 0x00, 0xc2, 0x01, 0x38, 0xc0,
+  0x07, 0x3c, 0xe0, 0x60, 0x0f, 0x80, 0x1e, 0x00, 0x00, 0x05, 0x00, 0x07,
+  0xa0, 0x00, 0x00, 0x80, 0xe0, 0x01, 0x3c, 0xc0, 0x07, 0x3c, 0xf0, 0xa0,
+  0x07, 0xc0, 0x1c, 0x00, 0x00, 0x0a, 0x80, 0x08, 0xa0, 0x02, 0x00, 0xa0,
+  0xe0, 0x21, 0x1c, 0xc0, 0x03, 0x1c, 0x71, 0x90, 0x47, 0x40, 0x3c, 0x04,
+  0x00, 0x05, 0x80, 0x06, 0xa0, 0x02, 0x00, 0x20, 0xe0, 0x31, 0x1e, 0xc3,
+  0x03, 0x1e, 0x79, 0x98, 0x47, 0x60, 0x38, 0x04, 0x00, 0x15, 0x40, 0x0a,
+  0xa0, 0x0a, 0x00, 0x1a, 0xe0, 0x19, 0x9e, 0xe1, 0x01, 0x9e, 0x78, 0xcc,
+  0xa7, 0x32, 0x78, 0x02, 0x80, 0x2a, 0x40, 0x05, 0x80, 0x2a, 0x00, 0x05,
+  0xe0, 0x0d, 0x9e, 0xe0, 0x01, 0xde, 0x78, 0xc6, 0x97, 0x1b, 0x78, 0x03,
+  0x80, 0x52, 0x30, 0x0a, 0x00, 0x95, 0xd2, 0x0a, 0xe0, 0x0f, 0xfe, 0xe0,
+  0x00, 0x7e, 0xf8, 0x87, 0x9f, 0x0f, 0xf8, 0x01, 0x00, 0xa1, 0x0e, 0x15,
+  0x80, 0x55, 0x55, 0x01, 0xe0, 0x01, 0x3c, 0xf0, 0x00, 0x3c, 0xf0, 0x80,
+  0x8f, 0x0f, 0x70, 0x00, 0x00, 0x81, 0x02, 0x14, 0x00, 0x54, 0x55, 0x00,
+  0xc0, 0x01, 0x3c, 0x00, 0x00, 0x0c, 0x60, 0x00, 0x07, 0x03, 0x70, 0x00,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x01, 0x00, 0x11, 0x09, 0x00, 0x04, 0x00, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+  0x00, 0x20, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x49, 0x32, 0x49, 0x49, 0x91,
+  0x24, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x20, 0x49, 0x0a, 0x09, 0xc9, 0x92, 0x14, 0x81, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x49,
+  0x18, 0x01, 0x49, 0x92, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x49, 0x30, 0x01, 0x49, 0x92,
+  0x14, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x08, 0x69, 0x22, 0x09, 0x49, 0xd2, 0x24, 0x24, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x51,
+  0x1a, 0x09, 0x49, 0xa2, 0x44, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x87, 0x08, 0x00, 0x00, 0x00,
+  0xf2, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0xf0, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x88, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09,
+  0x09, 0x01, 0x10, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x24, 0x80,
+  0x88, 0x86, 0x48, 0x04, 0x09, 0x08, 0x01, 0x01, 0x09, 0x01, 0x10, 0x71,
+  0x88, 0x66, 0x00, 0x00, 0x00, 0x40, 0x24, 0x80, 0x88, 0x89, 0x48, 0x84,
+  0x08, 0x08, 0x01, 0x01, 0x09, 0x01, 0x10, 0x89, 0x88, 0x99, 0x00, 0x00,
+  0x00, 0x40, 0x24, 0x80, 0x88, 0x88, 0x88, 0x82, 0xf8, 0xf0, 0xe0, 0x80,
+  0xf0, 0xf8, 0x13, 0x81, 0x88, 0x88, 0x00, 0x00, 0x00, 0x40, 0x24, 0x80,
+  0x88, 0x88, 0x08, 0x81, 0x08, 0x09, 0x01, 0x41, 0x08, 0x01, 0xf0, 0xf0,
+  0x88, 0x88, 0x00, 0x00, 0x00, 0x40, 0x24, 0x80, 0x88, 0x88, 0x88, 0x42,
+  0x08, 0x09, 0x01, 0x21, 0x08, 0x01, 0x10, 0x88, 0x88, 0x88, 0x00, 0x00,
+  0x00, 0x40, 0x46, 0x88, 0x88, 0x88, 0x4c, 0x44, 0x08, 0x09, 0x09, 0x11,
+  0x08, 0x01, 0x10, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x80, 0x85, 0x87,
+  0x88, 0x08, 0x4b, 0x24, 0xf0, 0xf0, 0xf0, 0xf8, 0xf1, 0x00, 0x10, 0x70,
+  0x89, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x3f, 0x0f, 0x00, 0x00, 0x08, 0x02, 0x04, 0x00,
+  0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0x1f, 0x00, 0x00, 0x48, 0x62, 0xc4, 0x31, 0x4a, 0x18, 0x3c, 0x03,
+  0x21, 0x45, 0x92, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x1f, 0x00, 0x00,
+  0x48, 0x92, 0x24, 0x48, 0xb6, 0x24, 0x88, 0x04, 0x21, 0x4b, 0x92, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xa8, 0xf2, 0x24, 0x48,
+  0x92, 0x3c, 0x88, 0x04, 0x21, 0x49, 0x62, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x10, 0x11, 0x24, 0x48, 0x92, 0x04, 0x88, 0x04,
+  0x21, 0x49, 0x62, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x3f, 0x00, 0x00,
+  0x10, 0x11, 0x24, 0x48, 0x92, 0x04, 0x88, 0x04, 0x21, 0x49, 0x93, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0xcf, 0x7e, 0x00, 0x00, 0x10, 0xe1, 0xc4, 0x31,
+  0x92, 0x38, 0x30, 0x03, 0x2f, 0x89, 0x92, 0x00, 0x00, 0x00, 0x80, 0xe3,
+  0x07, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc1, 0x03, 0x7e, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0xc9, 0x23, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x95,
+  0x33, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xdd, 0xfb, 0x7e, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x1d, 0xf8, 0x7e, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x40, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9b,
+  0x70, 0x7e, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x00, 0x02, 0x00, 0x47, 0x80,
+  0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x80, 0x03, 0x00, 0x7e, 0x00, 0x00,
+  0x3c, 0xa3, 0x20, 0x31, 0x52, 0x02, 0x49, 0xcc, 0x3f, 0xa3, 0x94, 0x08,
+  0x00, 0x00, 0x00, 0x27, 0x02, 0x7e, 0x00, 0x00, 0x88, 0xe4, 0x20, 0x41,
+  0xb2, 0x05, 0x49, 0x90, 0x88, 0xe4, 0x6c, 0x09, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x7e, 0x00, 0x00, 0x88, 0x24, 0xe0, 0x70, 0x92, 0x04, 0x47, 0x9c,
+  0x88, 0x24, 0x24, 0x09, 0x00, 0x00, 0x00, 0x13, 0x48, 0x7e, 0x00, 0x00,
+  0x88, 0x24, 0x20, 0x48, 0x92, 0x04, 0x41, 0x92, 0x88, 0x24, 0x24, 0x01,
+  0x00, 0x00, 0x00, 0x43, 0x00, 0xfe, 0x00, 0x00, 0x88, 0x24, 0x20, 0x48,
+  0x92, 0x04, 0x41, 0x92, 0x88, 0x24, 0x24, 0x09, 0x00, 0x00, 0x00, 0x07,
+  0x94, 0xce, 0x00, 0x00, 0x08, 0x23, 0x20, 0xb0, 0x92, 0x04, 0x41, 0x2c,
+  0x0b, 0x23, 0x24, 0x09, 0x00, 0x00, 0x00, 0x49, 0x02, 0xce, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x11, 0x08, 0xdc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+  0x01, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0xf8, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x01, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01,
+  0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xf0, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x70, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00,
+  0x00, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0xe0, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x3c, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00,
+  0x00, 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xc0, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x1f, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00,
+  0x00, 0x80, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00,
+  0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0xfe, 0x0f,
+  0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x08, 0x00,
+  0x00, 0xc0, 0x03, 0x00, 0x78, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x40, 0x10,
+  0x12, 0x10, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
+  0x84, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x20, 0x26, 0x0a, 0x10, 0x9d, 0x39,
+  0xa6, 0xb2, 0x0a, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x02, 0x00, 0xfe, 0x0f,
+  0x00, 0x00, 0x20, 0x21, 0x06, 0x28, 0x25, 0x4a, 0xa9, 0x8a, 0x09, 0x00,
+  0x00, 0xe0, 0x01, 0x22, 0x02, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x20, 0x21,
+  0x0e, 0x38, 0xa5, 0x4b, 0xa9, 0xb2, 0x09, 0x00, 0x00, 0xf0, 0x01, 0x22,
+  0x02, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x20, 0x21, 0x12, 0x44, 0xa5, 0x4a,
+  0x49, 0xa1, 0x0a, 0x00, 0x00, 0xf8, 0x01, 0x22, 0x02, 0x00, 0xfc, 0x1f,
+  0x00, 0x00, 0x20, 0x26, 0x52, 0x44, 0x9d, 0x4d, 0x46, 0x99, 0x0a, 0x00,
+  0x00, 0xfc, 0x01, 0x22, 0x02, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x40, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0xb2,
+  0x84, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x01, 0x6e, 0x78, 0x00, 0xfc, 0x1f,
+  0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xfc, 0x01, 0x02, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x02,
+  0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0xfc, 0x0f,
+  0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x20, 0x01, 0x02, 0x00, 0x00, 0x00,
+  0x00, 0x24, 0x06, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x40, 0x10,
+  0x1e, 0x20, 0x90, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
+  0x00, 0x80, 0xfc, 0x03, 0x00, 0x00, 0x20, 0x26, 0x22, 0x20, 0xf9, 0x89,
+  0x32, 0xe7, 0x08, 0x00, 0x00, 0x92, 0x38, 0x00, 0x00, 0x00, 0xfc, 0x01,
+  0x00, 0x00, 0x20, 0x21, 0x22, 0xa0, 0x92, 0x88, 0x4a, 0x29, 0x15, 0x00,
+  0x00, 0x00, 0x78, 0x00, 0x00, 0x40, 0xfa, 0x04, 0x00, 0x00, 0x20, 0x21,
+  0x22, 0xa0, 0x93, 0x88, 0x4a, 0x29, 0x1d, 0x00, 0x00, 0x11, 0xf2, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x20, 0x21, 0x22, 0xa8, 0x90, 0x88,
+  0x4a, 0x29, 0x05, 0x00, 0x48, 0x40, 0xf0, 0x01, 0x00, 0x80, 0x14, 0x04,
+  0x00, 0x00, 0x20, 0x26, 0x9e, 0x10, 0x93, 0x78, 0x32, 0x29, 0x19, 0x00,
+  0x00, 0x09, 0xe0, 0x03, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x40, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xc5, 0x03,
+  0x00, 0x40, 0x22, 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0xc0, 0x07, 0x00, 0x20, 0x08, 0x04,
+  0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x50, 0x90, 0x03, 0x00, 0xb0, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
+  0x00, 0x38, 0x22, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x48, 0x04, 0x44, 0x00, 0x00, 0x3c, 0x08, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x20, 0x00, 0x00, 0x00, 0xbf, 0x40, 0x42, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x24, 0x80, 0x48, 0x02,
+  0xc0, 0x1f, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x05, 0xf0, 0x3f, 0x09, 0x00,
+  0x00, 0x10, 0x24, 0x48, 0x10, 0x12, 0x41, 0x52, 0x24, 0x09, 0x46, 0x71,
+  0x90, 0x20, 0x02, 0xfc, 0xff, 0x1f, 0x80, 0x22, 0x00, 0x90, 0x24, 0x49,
+  0x12, 0x92, 0x40, 0xb2, 0x24, 0x09, 0xc9, 0x49, 0x04, 0x80, 0x90, 0xfc,
+  0xff, 0xbf, 0x24, 0x00, 0x00, 0x90, 0x24, 0x49, 0x12, 0x92, 0x40, 0x92,
+  0x24, 0x06, 0x49, 0x48, 0x50, 0x0a, 0x02, 0xfe, 0xff, 0x3f, 0x00, 0x05,
+  0x00, 0x50, 0xa5, 0x4a, 0x15, 0x92, 0x40, 0x92, 0x24, 0x06, 0x49, 0x48,
+  0x80, 0x40, 0x48, 0xfe, 0xff, 0x3f, 0x49, 0x00, 0x00, 0x20, 0x42, 0x84,
+  0x88, 0x1a, 0x41, 0x92, 0x34, 0x49, 0x49, 0x68, 0x00, 0x38, 0x10, 0x07,
+  0x00, 0x60, 0x80, 0x00, 0x00, 0x20, 0x42, 0x84, 0x88, 0x14, 0x4e, 0x92,
+  0x28, 0x49, 0x46, 0x50, 0x00, 0x80, 0x83, 0x01, 0x00, 0xa0, 0x6a, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+  0x00, 0x00, 0xfc, 0x00, 0x00, 0xc0, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, };
diff -urN linux-2.4.29/arch/blackfin/platform/533/ADI/bootlogo.rh linux-2.4.29-uc1/arch/blackfin/platform/533/ADI/bootlogo.rh
--- linux-2.4.29/arch/blackfin/platform/533/ADI/bootlogo.rh	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/ADI/bootlogo.rh	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,270 @@
+#define bootlogo_width 160
+#define bootlogo_height 160
+
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x80, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x02, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xaa
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x01, 0x10, 0x00, 0x00, 0x00, 0x7e, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00
+	.byte  0x00, 0xff, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x1f, 0x01, 0xf0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x0a, 0x20, 0x00, 0x00, 0x00, 0x1e, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xc0, 0x00, 0x00
+	.byte  0x00, 0x1e, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x02
+	.byte  0x15, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0e, 0x14, 0x80, 0x00, 0x00
+	.byte  0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x04, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0e
+	.byte  0x2a, 0x80, 0x00, 0x00, 0x00, 0x7c, 0x01, 0x80, 0x5c, 0x1e, 0x01, 0x70
+	.byte  0x0a, 0x03, 0xc0, 0x70, 0x00, 0x04, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00
+	.byte  0x00, 0x7c, 0x0f, 0xc1, 0xf8, 0x3f, 0x07, 0xf0, 0x1e, 0x1f, 0xe1, 0xf8
+	.byte  0x00, 0x18, 0x00, 0x0c, 0x55, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1f, 0xc3
+	.byte  0xf8, 0x3f, 0x07, 0xf0, 0x1e, 0x1f, 0xe1, 0xf0, 0x00, 0x04, 0x00, 0x08
+	.byte  0xaa, 0x00, 0x00, 0x00, 0x00, 0x78, 0x03, 0xc0, 0xf9, 0xcf, 0x01, 0xf0
+	.byte  0x1e, 0x01, 0xe3, 0x70, 0x00, 0x18, 0x00, 0x04, 0x55, 0x00, 0x00, 0x00
+	.byte  0x00, 0x78, 0x07, 0xc0, 0xf9, 0x8f, 0x01, 0xe0, 0x1e, 0x01, 0xe6, 0x00
+	.byte  0x00, 0x24, 0x00, 0x18, 0xaa, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0x80
+	.byte  0x7a, 0x0f, 0x01, 0xe0, 0x3c, 0x00, 0xf4, 0x00, 0x00, 0x28, 0x00, 0x04
+	.byte  0x55, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0x80, 0xfe, 0x0f, 0x01, 0xe0
+	.byte  0x3c, 0x00, 0xfc, 0x00, 0x00, 0x10, 0x00, 0x18, 0xaa, 0x00, 0x00, 0x00
+	.byte  0x00, 0xf0, 0x07, 0x00, 0xfc, 0x0f, 0x03, 0xc0, 0x78, 0x00, 0xf8, 0x00
+	.byte  0x00, 0x28, 0x00, 0x14, 0x55, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x0f, 0x00
+	.byte  0xf8, 0x0f, 0x03, 0xc0, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x20, 0x00, 0x30
+	.byte  0x2a, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x1e, 0x00, 0xf8, 0x1e, 0x03, 0xc0
+	.byte  0xf8, 0x00, 0x78, 0x00, 0x00, 0x50, 0x00, 0x48, 0x15, 0x00, 0x00, 0x00
+	.byte  0x01, 0xe0, 0x1e, 0x00, 0xf8, 0x1e, 0x07, 0xc0, 0xf8, 0x00, 0xf8, 0x00
+	.byte  0x00, 0x20, 0x00, 0x50, 0x2a, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x1e, 0x01
+	.byte  0xf0, 0x1e, 0x07, 0xc0, 0xf8, 0x00, 0x78, 0x00, 0x00, 0x50, 0x00, 0x10
+	.byte  0x0a, 0x80, 0x00, 0x00, 0x21, 0xc0, 0x1e, 0x01, 0xe0, 0x3c, 0x07, 0x83
+	.byte  0xf0, 0x00, 0xf8, 0x00, 0x00, 0x20, 0x00, 0x60, 0x15, 0x00, 0x00, 0x00
+	.byte  0x03, 0xc0, 0x1e, 0x03, 0xe0, 0x3c, 0x07, 0x83, 0xf0, 0x00, 0xf8, 0x00
+	.byte  0x00, 0x50, 0x00, 0x10, 0x0a, 0x80, 0x00, 0x00, 0x43, 0x80, 0x1c, 0x03
+	.byte  0xe0, 0x3c, 0x07, 0x06, 0xf0, 0x01, 0x78, 0x00, 0x00, 0xa0, 0x00, 0xe0
+	.byte  0x05, 0x00, 0x00, 0x01, 0x07, 0x80, 0x3c, 0x03, 0xe0, 0x3c, 0x0f, 0x05
+	.byte  0xe0, 0x03, 0x38, 0x00, 0x00, 0x50, 0x01, 0x10, 0x05, 0x40, 0x00, 0x05
+	.byte  0x07, 0x84, 0x38, 0x03, 0xc0, 0x38, 0x8e, 0x09, 0xe2, 0x02, 0x3c, 0x20
+	.byte  0x00, 0xa0, 0x01, 0x60, 0x05, 0x40, 0x00, 0x04, 0x07, 0x8c, 0x78, 0xc3
+	.byte  0xc0, 0x78, 0x9e, 0x19, 0xe2, 0x06, 0x1c, 0x20, 0x00, 0xa8, 0x02, 0x50
+	.byte  0x05, 0x50, 0x00, 0x58, 0x07, 0x98, 0x79, 0x87, 0x80, 0x79, 0x1e, 0x33
+	.byte  0xe5, 0x4c, 0x1e, 0x40, 0x01, 0x54, 0x02, 0xa0, 0x01, 0x54, 0x00, 0xa0
+	.byte  0x07, 0xb0, 0x79, 0x07, 0x80, 0x7b, 0x1e, 0x63, 0xe9, 0xd8, 0x1e, 0xc0
+	.byte  0x01, 0x4a, 0x0c, 0x50, 0x00, 0xa9, 0x4b, 0x50, 0x07, 0xf0, 0x7f, 0x07
+	.byte  0x00, 0x7e, 0x1f, 0xe1, 0xf9, 0xf0, 0x1f, 0x80, 0x00, 0x85, 0x70, 0xa8
+	.byte  0x01, 0xaa, 0xaa, 0x80, 0x07, 0x80, 0x3c, 0x0f, 0x00, 0x3c, 0x0f, 0x01
+	.byte  0xf1, 0xf0, 0x0e, 0x00, 0x00, 0x81, 0x40, 0x28, 0x00, 0x2a, 0xaa, 0x00
+	.byte  0x03, 0x80, 0x3c, 0x00, 0x00, 0x30, 0x06, 0x00, 0xe0, 0xc0, 0x0e, 0x00
+	.byte  0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x02, 0x80, 0x00, 0x88, 0x90, 0x00, 0x20, 0x00, 0x80, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00
+	.byte  0x00, 0x04, 0x80, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x92, 0x4c, 0x92, 0x92, 0x89
+	.byte  0x24, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x04, 0x92, 0x50, 0x90, 0x93, 0x49, 0x28, 0x81, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x92
+	.byte  0x18, 0x80, 0x92, 0x49, 0x30, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x92, 0x0c, 0x80, 0x92, 0x49
+	.byte  0x28, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x10, 0x96, 0x44, 0x90, 0x92, 0x4b, 0x24, 0x24, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x8a
+	.byte  0x58, 0x90, 0x92, 0x45, 0x22, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+	.byte  0x10, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe1, 0x10, 0x00, 0x00, 0x00
+	.byte  0x4f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x02, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, 0x90
+	.byte  0x90, 0x80, 0x08, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x24, 0x01
+	.byte  0x11, 0x61, 0x12, 0x20, 0x90, 0x10, 0x80, 0x80, 0x90, 0x80, 0x08, 0x8e
+	.byte  0x11, 0x66, 0x00, 0x00, 0x00, 0x02, 0x24, 0x01, 0x11, 0x91, 0x12, 0x21
+	.byte  0x10, 0x10, 0x80, 0x80, 0x90, 0x80, 0x08, 0x91, 0x11, 0x99, 0x00, 0x00
+	.byte  0x00, 0x02, 0x24, 0x01, 0x11, 0x11, 0x11, 0x41, 0x1f, 0x0f, 0x07, 0x01
+	.byte  0x0f, 0x1f, 0xc8, 0x81, 0x11, 0x11, 0x00, 0x00, 0x00, 0x02, 0x24, 0x01
+	.byte  0x11, 0x11, 0x10, 0x81, 0x10, 0x90, 0x80, 0x82, 0x10, 0x80, 0x0f, 0x0f
+	.byte  0x11, 0x11, 0x00, 0x00, 0x00, 0x02, 0x24, 0x01, 0x11, 0x11, 0x11, 0x42
+	.byte  0x10, 0x90, 0x80, 0x84, 0x10, 0x80, 0x08, 0x11, 0x11, 0x11, 0x00, 0x00
+	.byte  0x00, 0x02, 0x62, 0x11, 0x11, 0x11, 0x32, 0x22, 0x10, 0x90, 0x90, 0x88
+	.byte  0x10, 0x80, 0x08, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x01, 0xa1, 0xe1
+	.byte  0x11, 0x10, 0xd2, 0x24, 0x0f, 0x0f, 0x0f, 0x1f, 0x8f, 0x00, 0x08, 0x0e
+	.byte  0x91, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f
+	.byte  0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xfc, 0xf0, 0x00, 0x00, 0x10, 0x40, 0x20, 0x00
+	.byte  0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0xff, 0xf8, 0x00, 0x00, 0x12, 0x46, 0x23, 0x8c, 0x52, 0x18, 0x3c, 0xc0
+	.byte  0x84, 0xa2, 0x49, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xf8, 0x00, 0x00
+	.byte  0x12, 0x49, 0x24, 0x12, 0x6d, 0x24, 0x11, 0x20, 0x84, 0xd2, 0x49, 0x00
+	.byte  0x00, 0x00, 0x01, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x15, 0x4f, 0x24, 0x12
+	.byte  0x49, 0x3c, 0x11, 0x20, 0x84, 0x92, 0x46, 0x00, 0x00, 0x00, 0x01, 0xff
+	.byte  0xff, 0xfc, 0x00, 0x00, 0x08, 0x88, 0x24, 0x12, 0x49, 0x20, 0x11, 0x20
+	.byte  0x84, 0x92, 0x46, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xfc, 0x00, 0x00
+	.byte  0x08, 0x88, 0x24, 0x12, 0x49, 0x20, 0x11, 0x20, 0x84, 0x92, 0xc9, 0x00
+	.byte  0x00, 0x00, 0x01, 0xff, 0xf3, 0x7e, 0x00, 0x00, 0x08, 0x87, 0x23, 0x8c
+	.byte  0x49, 0x1c, 0x0c, 0xc0, 0xf4, 0x91, 0x49, 0x00, 0x00, 0x00, 0x01, 0xc7
+	.byte  0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x83, 0xc0, 0x7e, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x01, 0x93, 0xc4, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xa9
+	.byte  0xcc, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xbb, 0xdf, 0x7e, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x01, 0xb8, 0x1f, 0x7e, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00
+	.byte  0x40, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xd9
+	.byte  0x0e, 0x7e, 0x00, 0x00, 0x10, 0x00, 0x07, 0x00, 0x40, 0x00, 0xe2, 0x01
+	.byte  0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x7e, 0x00, 0x00
+	.byte  0x3c, 0xc5, 0x04, 0x8c, 0x4a, 0x40, 0x92, 0x33, 0xfc, 0xc5, 0x29, 0x10
+	.byte  0x00, 0x00, 0x00, 0xe4, 0x40, 0x7e, 0x00, 0x00, 0x11, 0x27, 0x04, 0x82
+	.byte  0x4d, 0xa0, 0x92, 0x09, 0x11, 0x27, 0x36, 0x90, 0x00, 0x00, 0x00, 0x80
+	.byte  0x00, 0x7e, 0x00, 0x00, 0x11, 0x24, 0x07, 0x0e, 0x49, 0x20, 0xe2, 0x39
+	.byte  0x11, 0x24, 0x24, 0x90, 0x00, 0x00, 0x00, 0xc8, 0x12, 0x7e, 0x00, 0x00
+	.byte  0x11, 0x24, 0x04, 0x12, 0x49, 0x20, 0x82, 0x49, 0x11, 0x24, 0x24, 0x80
+	.byte  0x00, 0x00, 0x00, 0xc2, 0x00, 0x7f, 0x00, 0x00, 0x11, 0x24, 0x04, 0x12
+	.byte  0x49, 0x20, 0x82, 0x49, 0x11, 0x24, 0x24, 0x90, 0x00, 0x00, 0x00, 0xe0
+	.byte  0x29, 0x73, 0x00, 0x00, 0x10, 0xc4, 0x04, 0x0d, 0x49, 0x20, 0x82, 0x34
+	.byte  0xd0, 0xc4, 0x24, 0x90, 0x00, 0x00, 0x00, 0x92, 0x40, 0x73, 0x80, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x88, 0x10, 0x3b, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82
+	.byte  0x80, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x1f, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x03, 0x80, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80
+	.byte  0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x0f, 0xf8, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x0e, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00
+	.byte  0x00, 0x07, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x07, 0xfe, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x3c, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00
+	.byte  0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x03, 0xff, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0xf8, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00
+	.byte  0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xe0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x7f, 0xf0
+	.byte  0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x01, 0x10, 0x00
+	.byte  0x00, 0x03, 0xc0, 0x00, 0x1e, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x02, 0x08
+	.byte  0x48, 0x08, 0xa0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00
+	.byte  0x21, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x04, 0x64, 0x50, 0x08, 0xb9, 0x9c
+	.byte  0x65, 0x4d, 0x50, 0x00, 0x00, 0x07, 0x80, 0x00, 0x40, 0x00, 0x7f, 0xf0
+	.byte  0x00, 0x00, 0x04, 0x84, 0x60, 0x14, 0xa4, 0x52, 0x95, 0x51, 0x90, 0x00
+	.byte  0x00, 0x07, 0x80, 0x44, 0x40, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x04, 0x84
+	.byte  0x70, 0x1c, 0xa5, 0xd2, 0x95, 0x4d, 0x90, 0x00, 0x00, 0x0f, 0x80, 0x44
+	.byte  0x40, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x04, 0x84, 0x48, 0x22, 0xa5, 0x52
+	.byte  0x92, 0x85, 0x50, 0x00, 0x00, 0x1f, 0x80, 0x44, 0x40, 0x00, 0x3f, 0xf8
+	.byte  0x00, 0x00, 0x04, 0x64, 0x4a, 0x22, 0xb9, 0xb2, 0x62, 0x99, 0x50, 0x00
+	.byte  0x00, 0x3f, 0x80, 0x44, 0x40, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x02, 0x08
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x4d
+	.byte  0x21, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x80, 0x76, 0x1e, 0x00, 0x3f, 0xf8
+	.byte  0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x3f, 0x80, 0x40, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x80, 0x40
+	.byte  0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x00, 0x00, 0x3f, 0xf0
+	.byte  0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x04, 0x80, 0x40, 0x00, 0x00, 0x00
+	.byte  0x00, 0x24, 0x60, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x02, 0x08
+	.byte  0x78, 0x04, 0x09, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00
+	.byte  0x00, 0x01, 0x3f, 0xc0, 0x00, 0x00, 0x04, 0x64, 0x44, 0x04, 0x9f, 0x91
+	.byte  0x4c, 0xe7, 0x10, 0x00, 0x00, 0x49, 0x1c, 0x00, 0x00, 0x00, 0x3f, 0x80
+	.byte  0x00, 0x00, 0x04, 0x84, 0x44, 0x05, 0x49, 0x11, 0x52, 0x94, 0xa8, 0x00
+	.byte  0x00, 0x00, 0x1e, 0x00, 0x00, 0x02, 0x5f, 0x20, 0x00, 0x00, 0x04, 0x84
+	.byte  0x44, 0x05, 0xc9, 0x11, 0x52, 0x94, 0xb8, 0x00, 0x00, 0x88, 0x4f, 0x00
+	.byte  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x84, 0x44, 0x15, 0x09, 0x11
+	.byte  0x52, 0x94, 0xa0, 0x00, 0x12, 0x02, 0x0f, 0x80, 0x00, 0x01, 0x28, 0x20
+	.byte  0x00, 0x00, 0x04, 0x64, 0x79, 0x08, 0xc9, 0x1e, 0x4c, 0x94, 0x98, 0x00
+	.byte  0x00, 0x90, 0x07, 0xc0, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xa3, 0xc0
+	.byte  0x00, 0x02, 0x44, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x03, 0xe0, 0x00, 0x04, 0x10, 0x20
+	.byte  0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x10, 0x0a, 0x09, 0xc0, 0x00, 0x0d, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00
+	.byte  0x00, 0x1c, 0x44, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x22, 0x00, 0x00, 0x3c, 0x10, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x04, 0x00, 0x00, 0x00, 0xfd, 0x02, 0x42, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x24, 0x01, 0x12, 0x40
+	.byte  0x03, 0xf8, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0xa0, 0x0f, 0xfc, 0x90, 0x00
+	.byte  0x00, 0x08, 0x24, 0x12, 0x08, 0x48, 0x82, 0x4a, 0x24, 0x90, 0x62, 0x8e
+	.byte  0x09, 0x04, 0x40, 0x3f, 0xff, 0xf8, 0x01, 0x44, 0x00, 0x09, 0x24, 0x92
+	.byte  0x48, 0x49, 0x02, 0x4d, 0x24, 0x90, 0x93, 0x92, 0x20, 0x01, 0x09, 0x3f
+	.byte  0xff, 0xfd, 0x24, 0x00, 0x00, 0x09, 0x24, 0x92, 0x48, 0x49, 0x02, 0x49
+	.byte  0x24, 0x60, 0x92, 0x12, 0x0a, 0x50, 0x40, 0x7f, 0xff, 0xfc, 0x00, 0xa0
+	.byte  0x00, 0x0a, 0xa5, 0x52, 0xa8, 0x49, 0x02, 0x49, 0x24, 0x60, 0x92, 0x12
+	.byte  0x01, 0x02, 0x12, 0x7f, 0xff, 0xfc, 0x92, 0x00, 0x00, 0x04, 0x42, 0x21
+	.byte  0x11, 0x58, 0x82, 0x49, 0x2c, 0x92, 0x92, 0x16, 0x00, 0x1c, 0x08, 0xe0
+	.byte  0x00, 0x06, 0x01, 0x00, 0x00, 0x04, 0x42, 0x21, 0x11, 0x28, 0x72, 0x49
+	.byte  0x14, 0x92, 0x62, 0x0a, 0x00, 0x01, 0xc1, 0x80, 0x00, 0x05, 0x56, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02
+	.byte  0x00, 0x00, 0x3f, 0x00, 0x00, 0x03, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 
diff -urN linux-2.4.29/arch/blackfin/platform/533/ADI/crt0_ram.S linux-2.4.29-uc1/arch/blackfin/platform/533/ADI/crt0_ram.S
--- linux-2.4.29/arch/blackfin/platform/533/ADI/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/ADI/crt0_ram.S	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,161 @@
+/* linux/arch/frio/kernel/head.S:  A startup file for the Blackfin 
+ *
+ * Copyright (c) 2003  Bas Vermeulen <bas@buyways.nl>,
+ *                     BuyWays B.V. (www.buyways.nl)
+ * Copyright (c) 2003  Metrowerks/Motorola
+ * Copyright (C) 1998  D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
+ *                     Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ * (c) 1995, Dionne & Associates
+ * (c) 1995, DKG Display Tech.
+ */
+
+#define ASSEMBLY
+
+#include <linux/config.h>
+
+.global _stext;
+.global __bss_start;
+
+.global start;
+.global _start;
+
+.global _rambase;
+.global __ramvec;
+.global _ramvec;
+.global _ramstart;
+.global _ramend;
+
+#define	MEM_BASE	0x00000000
+#define VBR_BASE	MEM_BASE
+#define MEM_SIZE	0x1000000
+
+/*********************************************************************/
+
+.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+.text
+	
+_start:
+start:
+_stext:
+
+	/*
+	 * It seems that the value of SP reg is unpredicable after reset.
+	 * We'd better set SP before using "reti" and "[--sp] = reti" 
+	 *
+	 * HuTao May26, 2003 3:02PM
+	 */
+	sp.h = 0xffb0;	/* 0x1000(4KB) L1 RAM as system stack */
+	sp.l = 0x1000;
+
+	// This next section keeps the processor in supervisor mode
+        // during kernel boot.  Switches to user mode at end of boot.
+	// See page 3-9 of Hardware Reference manual for documentation.
+
+	// EVT15 = _real_start
+
+	p0.l = 0x203c
+	p0.h = 0xffe0;
+	p1.l = _real_start;
+	p1.h = _real_start;
+	[p0] = p1;
+
+	// IMASK = 0x8000
+
+	p0.l = 0x2104;
+	p0.h = 0xffe0;
+	p1.l = 0x8000;
+	p1.h = 0x0;
+	[p0] = p1;
+
+	raise 15;
+	p0.l = WAIT_HERE;
+	p0.h = WAIT_HERE;
+	reti = p0;
+	rti;
+	
+WAIT_HERE:
+	jump WAIT_HERE;
+
+.global _real_start;
+_real_start:
+	[ -- sp ] = reti;
+	p0.l = 0x0200;
+	p0.h = 0xFFC0;
+	r0 = 0xD6(z);
+	w[p0] = r0;	/* watchdog off for now */
+
+	/* Code update for BSS size == 0
+	 * Zero out the bss region.
+	 */
+	p1.l = _sbss;
+	p1.h = _sbss;
+	p2.l = _ebss;
+	p2.h = _ebss;
+	lsetup (_clear_bss, _clear_bss_end ) lc1 = p2 - p1;
+	CC = p2<=p1;
+	if CC jump _clear_bss_skip;
+	r0 = 0;
+_clear_bss:
+_clear_bss_end:
+	[p1++] = r0;
+_clear_bss_skip:	/* to skip bss clear */
+
+	p1.l = _rambase;
+	p1.h = _rambase;
+	r0.l = _sdata ;
+	r0.h = _sdata ;
+	[p1] = r0;
+
+	p1.l = _ramstart;
+	p1.h = _ramstart;
+	r0.l = _end;
+	r0.h = _end;
+	[p1] = r0;
+
+	r0.l = 0x0000;
+	r0.h = 0x100;	/* MEM_SIZE = 0x01000000 */
+	p1.l = _ramend;
+	p1.h = _ramend;
+	[p1] = r0;
+
+	/*
+	 *  load the current task pointer and stack
+	 */
+	r1.l = init_task_union;
+	r1.h = init_task_union;
+	p1.l = _current_task;
+	p1.h = _current_task;
+	[p1] = r1;
+
+/* Use kernel stack instead of an l1 stack. l1 stack might overflow.
+ * For this time being this should be sufficient.
+ */
+	r2 = 0x2000(z);
+	r1 = r1 + r2;
+	sp = r1;
+
+	call	start_kernel;
+_exit:
+
+	jump.s	_exit;
+
+	.data
+env:
+	.long	0;
diff -urN linux-2.4.29/arch/blackfin/platform/533/ADI/crt0_rom.S linux-2.4.29-uc1/arch/blackfin/platform/533/ADI/crt0_rom.S
--- linux-2.4.29/arch/blackfin/platform/533/ADI/crt0_rom.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/ADI/crt0_rom.S	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,109 @@
+/* linux/arch/frionommu/platform/533/ADI/crt0_rom.S:  A startup file for the BlackFin BF533 
+ *
+ * Copyright (C) 1998  D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
+ *                     Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ * (c) 1995, Dionne & Associates
+ * (c) 1995, DKG Display Tech.
+ */
+
+#define ASSEMBLY
+
+
+#include <linux/config.h>
+
+.global _stext;
+.global __bss_start;
+
+.global start;
+.global _start;
+
+.global _rambase;
+.global __ramvec;
+.global _ramvec;
+.global _ramstart;
+.global _ramend;
+
+#define	MEM_BASE	0x00000000
+#define VBR_BASE	MEM_BASE
+#define MEM_SIZE	0x00400000
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+.text
+	
+_start:
+start:
+_stext:
+	r7 = cli;
+	sp.l = 0x0000;
+	sp.h = 0x0500;
+	usp = sp;
+
+	r0 = 0;		/* VBR_BASE */
+	p1.l = _ramvec;
+	p1.h = _ramvec;
+	[p1] = r0;
+	p1.l = _rambase;
+	p1.h = _rambase;
+	[p1] = r0;
+
+	r0.l = 0x0000;
+	r0.h = 0x0040;	/* MEM_SIZE = 0x00400000 */
+	p1.l = _ramend;
+	p1.h = _ramend;
+	[p1] = r0;
+
+#if 0
+	/*
+	 * Zero out the bss region.
+	 */
+	p1.l = _sbss;
+	p1.h = _sbss;
+	p2.l = _ebss;
+	p2.h = _ebss;
+	r0 = 0;
+_clear_bss:
+	[p1++] = r0;
+	CC = p1 == p2;
+	if !cc jump _clear_bss;
+#endif
+	/*
+	 *  load the current task pointer and stack
+	 */
+	p1.l = init_task_union;
+	p1.h = init_task_union;
+	p2.l = _current_task;
+	p2.h = _current_task;
+	[p2] = p1;
+	[p2 + 0x2000] = sp;
+
+	sti r7;
+	sp.l = 0x0000;
+	sp.h = 0x0500;
+	usp = sp;
+	call	start_kernel;
+_exit:
+
+	jump.s	_exit;
+
+	.data
+env:
+	.long	0;
diff -urN linux-2.4.29/arch/blackfin/platform/533/ADI/ram.ld linux-2.4.29-uc1/arch/blackfin/platform/533/ADI/ram.ld
--- linux-2.4.29/arch/blackfin/platform/533/ADI/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/ADI/ram.ld	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,128 @@
+OUTPUT_FORMAT("elf32-little-nisa")
+OUTPUT_ARCH(nisa)
+ENTRY(start)
+MEMORY 
+	{
+	ram		: ORIGIN = 0x1000,        LENGTH = 0x1000000
+	l2_sram		: ORIGIN = 0xF0000000, LENGTH = 0x40000
+	l1_data_a	: ORIGIN = 0xFF800000, LENGTH = 0x4000
+	l1_data_b	: ORIGIN = 0xFF900000, LENGTH = 0x4000
+	l1_code		: ORIGIN = 0xFFA00000, LENGTH = 0x4000
+	l1_scratch	: ORIGIN = 0xFFB00000, LENGTH = 0x1000
+	}
+
+SECTIONS
+{
+  . = 0x1000 ;
+  .text : {
+	  _text = .;                    /* Text and read-only data */
+	  text_start = . ;
+	  __text_start = . ;
+          *(.text)
+          *(.text.*)
+	  *($code)
+          *(.fixup)		
+          *(__ex_table)	
+	  . = ALIGN(4) ;
+	  _etext = . ;
+	  etext = . ;
+	} > ram
+  
+	
+  .data :
+	{
+	  _sdata = . ;
+	  __data_start = . ;
+
+	  . = ALIGN(0x2000) ;
+	  *(.data.init_task)
+	  . = ALIGN(0x2000) ;
+
+      *(.rodata)
+      *(.data)
+      *(.data.*)	
+      . = ALIGN(4096) ;
+      ramdisk_begin = .;
+      *(.ramdisk)
+      ramdisk_end = .;
+
+      *(.setup.init)		
+      *(.exitcall.exit)		
+	
+	  . = ALIGN(4096) ;
+	  __init_begin = .;
+	  *(.text.init)
+	  *(.data.init)
+	  . = ALIGN(16);
+	  __setup_start = .;
+	  *(.setup.init)
+	  __setup_end = .;
+	  __initcall_start = .;
+	  *(.initcall.init)
+	  . = ALIGN(4) ;
+	  __initcall_end = .;
+	  __init_end = .;
+
+	  _edata = . ;
+	  edata = . ;
+	} > ram
+
+  .bss :
+    {
+	  . = ALIGN(16) ;
+	  _sbss = . ;
+	  __bss_start = . ;
+	  __data_end = . ;
+	  *(.bss)
+	  *(COMMON)
+	  . = ALIGN(16) ;
+	  end = . ;
+	  _ebss = . ;	  
+	  _end = . ;
+    } > ram
+
+  . = 0x1000000;
+  .eram :
+    {
+	__ramend = . ;
+    } > ram
+
+
+
+
+
+
+  . = 0xF0000000 ;
+  .l2ram :
+    {
+	_l2_sram = . ;
+    } > l2_sram
+
+
+  . = 0xFF800000 ;
+  .l1data1 :
+    {
+	_l1_data_a = . ;
+    } > l1_data_a
+
+
+  . = 0xFF900000 ;
+  .l1data2 :
+    {
+	_l1_data_b = . ;
+    } > l1_data_b
+
+
+  . = 0xFFA00000 ;
+  .l1code :
+    {
+	_l1_code = . ;
+    } > l1_code
+
+  . = 0xFFB00000 ;
+  .l1scratch :
+    {
+	_l1_scratch = . ;
+    } > l1_scratch
+
+}
diff -urN linux-2.4.29/arch/blackfin/platform/533/ADI/rom.ld linux-2.4.29-uc1/arch/blackfin/platform/533/ADI/rom.ld
--- linux-2.4.29/arch/blackfin/platform/533/ADI/rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/ADI/rom.ld	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,99 @@
+OUTPUT_ARCH(nisa)
+ENTRY(_start)
+MEMORY 
+	{
+	romvec : ORIGIN = 0x10c00000, LENGTH = 0x10400
+	flash  : ORIGIN = 0x10c10400, LENGTH = 0xfec00
+	eflash : ORIGIN = 0x10d00000, LENGTH = 4
+	ramvec : ORIGIN = 0x00000000, LENGTH = 0x400
+	ram    : ORIGIN = 0x10000400, LENGTH = 0x100000-0x400
+	eram   : ORIGIN = 0x10100000, LENGTH = 4
+	}
+
+SECTIONS
+{
+  . = 0x10c00000 ;
+  .romvec : {
+	  _flashstart = . ;
+	  _romvec = . ;
+	} > romvec
+
+  . = 0x10c10400 ;
+  .text : {
+	  _text = .;                    /* Text and read-only data */
+	  text_start = . ;
+          *(.text)
+          *(.text.*)
+          *(.rodata)
+          *(.fixup)		
+          *(__ex_table)	
+	  . = ALIGN(4) ;
+	  _etext = . ;
+	  __data_rom_start = . ;
+	} > flash
+  
+  . = 0x10d00000 ;
+  .eflash :
+        {
+          _flashend = . ;
+        } > eflash
+	
+  . = 0 ;
+  .ramvec :
+	{
+	  __ramvec = . ;
+	} > ramvec
+	
+  /* . = 0x10000400 ; */
+  .data 0x10000400 :
+	{
+	  _sdata = . ;
+	  __data_start = . ;
+
+	  . = ALIGN(0x2000) ;
+	  *(.data.init_task)
+	  . = ALIGN(0x2000) ;
+
+      *(.data)
+      *(.data.*)	
+      *(.setup.init)		
+      *(.exitcall.exit)		
+	
+	  . = ALIGN(4096) ;
+	  __init_begin = .;
+	  *(.text.init)
+	  *(.data.init)
+	  . = ALIGN(16);
+	  __setup_start = .;
+	  *(.setup.init)
+	  __setup_end = .;
+	  __initcall_start = .;
+	  *(.initcall.init)
+	  . = ALIGN(4) ;
+	  __initcall_end = .;
+	  __init_end = .;
+
+	  _edata = . ;
+	  edata = . ;
+	} > ram
+
+  .bss :
+    {
+	  . = ALIGN(16) ;
+	  _sbss = . ;
+	  __bss_start = . ;
+	  __data_end = . ;
+	  *(.bss)
+	  *(COMMON)
+	  . = ALIGN(16) ;
+	  end = . ;
+	  _ebss = . ;	  
+	  _end = . ;
+    } > ram
+
+  . = 0x10100000 ;
+  .eram :
+	{
+  	  __ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/blackfin/platform/533/config.c linux-2.4.29-uc1/arch/blackfin/platform/533/config.c
--- linux-2.4.29/arch/blackfin/platform/533/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/config.c	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,126 @@
+/*
+ *  linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999 D. Jeff Dionne
+ *  Copyright (C) 2003 Metrowerks (Blackfin support)
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <asm/current.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/blackfin.h>
+
+/*
+ * By setting TSCALE such that TCOUNT counts a binary fraction
+ * of microseconds, we can read TCOUNT directly and then with
+ * a logical shift trivially calculate how many microseconds 
+ * since the last tick, allowing do_gettimeofday() to yield
+ * far better time resolution for real time benchmarking.
+ */
+
+#define CCLK_MHZ 300	/* would be nice to derive using the rtc */
+#define TSCALE_SHIFT 2	/* 0.25 microseconds */
+#define TSCALE_COUNT (CCLK_MHZ >> TSCALE_SHIFT)
+#define CLOCKS_PER_JIFFY ((1000*1000/HZ) << TSCALE_SHIFT)
+
+void config_FRIO_irq(void);
+
+void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
+{
+
+  /* power up the timer, but don't enable it just yet */
+
+  TCNTL = 1;
+
+  /* make TCOUNT a binary fraction of microseconds using
+   * the TSCALE prescaler counter.
+   */
+
+  TSCALE = TSCALE_COUNT - 1;
+  TCOUNT = TPERIOD = CLOCKS_PER_JIFFY - 1;
+
+  /* now enable the timer */
+
+  TCNTL = 7;
+
+  /* set up the timer irq */
+
+  request_irq(IRQ_CORETMR, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+  enable_irq(IRQ_CORETMR);
+}
+
+void BSP_tick(void)
+{
+#if 0
+  /* Reset Timer2 */
+  TSTAT2 &= 0;
+#endif
+}
+
+unsigned long BSP_gettimeoffset (void)
+{
+  return (CLOCKS_PER_JIFFY - TCOUNT) >> TSCALE_SHIFT;
+}
+
+void BSP_gettod (int *yearp, int *monp, int *dayp,
+		   int *hourp, int *minp, int *secp)
+{
+}
+
+int BSP_hwclk(int op, struct hwclk_time *t)
+{
+  if (!op) {
+    /* read */
+  } else {
+    /* write */
+  }
+  return 0;
+}
+
+int BSP_set_clock_mmss (unsigned long nowtime)
+{
+#if 0
+  short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+
+  tod->second1 = real_seconds / 10;
+  tod->second2 = real_seconds % 10;
+  tod->minute1 = real_minutes / 10;
+  tod->minute2 = real_minutes % 10;
+#endif
+  return 0;
+}
+
+void BSP_reset (void)
+{
+}
+
+void config_BSP(char *command, int len)
+{
+  mach_sched_init      = BSP_sched_init;
+  mach_tick            = BSP_tick;
+  mach_gettimeoffset   = BSP_gettimeoffset;
+  mach_gettod          = BSP_gettod;
+  mach_hwclk           = NULL;
+  mach_set_clock_mmss  = NULL;
+  // mach_mksound         = NULL;
+  mach_reset           = BSP_reset;
+  // mach_debug_init      = NULL;
+
+  config_FRIO_irq();
+}
diff -urN linux-2.4.29/arch/blackfin/platform/533/entry.S linux-2.4.29-uc1/arch/blackfin/platform/533/entry.S
--- linux-2.4.29/arch/blackfin/platform/533/entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/entry.S	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,686 @@
+/* -*- mode: asm -*-
+ *
+ *  linux/arch/frionommu/platform/533/entry.S
+ *
+ *  Copyright (C) 2003        Bas Vermeulen <bas@buyways.nl>,
+ *                            BuyWays B.V. (www.buyways.nl)
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ * Linux/frio support: Tony Kou & Metrowerks
+ * BlackFin BF533 fixes: Bas Vermeulen & BuyWays B.V.
+ */
+
+/*
+ * entry.S  contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all interrupts
+ * and faults that can result in a task-switch.
+ *
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ *
+ */
+
+/*
+ * Secondary stage of kernel interrupt and exception handling. Points of entry
+ * into the kernel are in interrupt.S There are jumps to this file from
+ * interrupt.S Context is already saved when control comes to this file. SP
+ * points to bottom of the context, hence the stack appears same as pt_regs.
+ * ... amit
+ */
+
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/errno.h>
+#include <asm/setup.h>
+#include <asm/traps.h>
+
+#include "frio_defs.h"
+
+.globl SYMBOL_NAME(system_call), SYMBOL_NAME(buserr), SYMBOL_NAME(trap)
+.globl SYMBOL_NAME(resume), SYMBOL_NAME(ret_from_exception)
+.globl SYMBOL_NAME(ret_from_signal)
+.globl SYMBOL_NAME(sys_call_table)
+.globl SYMBOL_NAME(sys_fork), SYMBOL_NAME(sys_clone), SYMBOL_NAME(sys_vfork)
+.globl SYMBOL_NAME(ret_from_interrupt), SYMBOL_NAME(bad_interrupt)
+.globl SYMBOL_NAME(inthandler1), SYMBOL_NAME(inthandler2),SYMBOL_NAME(inthandler3)
+.globl SYMBOL_NAME(inthandler4),SYMBOL_NAME(inthandler5),SYMBOL_NAME(inthandler6)
+.globl SYMBOL_NAME(inthandler7)
+.globl SYMBOL_NAME(kernel_to_user_mode), SYMBOL_NAME(do_delay_trace), SYMBOL_NAME(Lsignal_return)
+
+.text
+
+ENTRY(trap) /* Exception: 4th entry into system event table(supervisor mode */
+	SAVE_ALL_INT
+	
+        p2.l = 0x2108;
+        p2.h = 0xffe0;
+        r0 = [p2];              // Read current IPEND
+        [sp + PT_IPEND] = r0;   // Store IPEND
+
+	r1 = [sp + PT_SEQSTAT];	// reason code is it bit 5:0
+	r0.l = 0x3f;
+	r0.h = 0x0;
+	r1 = r1 & r0;
+	CC = r1 == 0;
+	if ! cc jump 1f;
+	raise 14;	/* invoked by TRAP #0, for sys call */
+	jump.s	SYMBOL_NAME(ret_from_exception); /* pcrel12 enough */
+1:
+	r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */
+	call	SYMBOL_NAME(trap_c);
+	jump.s	SYMBOL_NAME(ret_from_exception); /* pcrel12 enough */
+
+ENTRY(reschedule)
+	p2.l = SYMBOL_NAME(_current_task);
+	p2.h = SYMBOL_NAME(_current_task);
+	[p2 + (TASK_THREAD + THREAD_ESP0)] = sp;
+
+	[--sp] = rets;
+	call SYMBOL_NAME(schedule);
+	rets = [sp++];
+	rts;
+ENTRY(reschedule2)
+	/* save top of frame*/
+	p2.l = SYMBOL_NAME(_current_task);
+	p2.h = SYMBOL_NAME(_current_task);
+	[p2+(TASK_THREAD+THREAD_ESP0)] = sp;
+
+	p3.l = SYMBOL_NAME(ret_from_exception);
+	p3.h = SYMBOL_NAME(ret_from_exception);
+	rets = p3;
+	jump.l SYMBOL_NAME(schedule); /* unknow how far away */
+	/* Note: asmlinkage void schedule(void) */
+
+	/* After a fork we jump here directly from resume,*/
+	/* so that %r1 contains the previous task*/
+	/* Theoretically only needed on SMP, but let's watch*/
+	/* what happens in schedule_tail() in future...*/
+
+ENTRY(ret_from_fork)
+	/* Don't bother with trace yet - akale */
+	r0 = r1;
+	call SYMBOL_NAME(schedule_tail);
+	/* Note: void schedule_tail(struct task_struct *prev)	*/
+	
+	r0 = [sp + PT_IPEND];
+	cc = bittst(r0, 15);
+	if cc jump in_kernel;
+	RESTORE_ALL
+	rti; 
+in_kernel:
+	/* do a 'fake' RTI by jumping to [RETI] */
+        /* to avoid clearing supervisor mode in child */
+	RESTORE_ALL
+	p0 = reti;
+	jump (p0);
+	/* NO! jump.s SYMBOL_NAME(ret_from_exception); */
+
+badsys:
+	r7 = -ENOSYS; /* signextending enough */
+	[sp + PT_R0] = r7;	/* return value from system call */
+	rti;	
+
+do_trace:
+	r7 = -ENOSYS;
+	[sp + PT_R0] = r7;	/* needed for strace */
+	sp += -4;		/* why minus then plus again ??? Tony */
+	call SYMBOL_NAME(syscall_trace); /* void syscall_trace(void) */
+	sp += 4;
+	r5 = [sp+PT_R5];
+	r0 = -ENOSYS;
+	r7 = NR_syscalls;
+	cc = r5 < r7;
+	if ! cc jump 1f;
+	p4 = r1;
+	p5.l = SYMBOL_NAME(sys_call_table);
+	p5.h = SYMBOL_NAME(sys_call_table);
+	p5 = p5 + (p4 << 2);
+	r0 = [sp + PT_R0];	/* confirm the system call args */
+	r1 = [sp + PT_R1];
+	r2 = [sp + PT_R2];
+	jump (p5);
+1:
+	[sp + PT_R0] = r0;	/* save the return value */
+	sp += -4;		/* dummy return address  */
+	jump.l SYMBOL_NAME(syscall_trace); /* void syscall_trace(void) */
+
+ENTRY(system_call)
+	// Store IPEND
+	p2.l = 0x2108;
+	p2.h = 0xffe0;
+	r0 = [p2];
+	[sp + PT_IPEND] = r0;
+
+	// Store RETS for now
+	r0 = rets;
+	[sp + PT_RESERVED] = r0;
+	// Set the stack for the current process
+	p2.l = SYMBOL_NAME(_current_task);
+	p2.h = SYMBOL_NAME(_current_task);
+	[p2+(TASK_THREAD+THREAD_ESP0)] = sp;
+
+	// Check the System Call
+	r7 = NR_syscalls;
+	cc = r5 < r7;		// r5 = number of system call
+	if ! cc jump badsys;
+
+	// Execute the appropriate system call
+	p4 = r5;
+	p5.l = SYMBOL_NAME(sys_call_table);
+	p5.h = SYMBOL_NAME(sys_call_table);
+	p5 = p5 + (p4 << 2);
+	r0 = [sp + PT_R0];
+	r1 = [sp + PT_R1];
+	r2 = [sp + PT_R2];
+	p5 = [p5];
+	call (p5);
+	[sp + PT_R0] = r0;
+	
+	// Check whether we need to drop to user mode
+	r0 = [sp + PT_IPEND];
+	CC = r0 == 0;
+	if !CC jump exit_syscall;
+	call kernel_to_user_mode;
+	r0 = 0x0002;
+	[sp + PT_IPEND] = r0;
+exit_syscall:
+	/* Only allow interrupts when we are really the last one on
+	 * the kernel stack, otherwise stack overflow can occur during
+         * heavy interrupt load
+	 */
+	p5.l = SYMBOL_NAME(_current_task);
+	p5.h = SYMBOL_NAME(_current_task);
+	r7 = [p5];
+	p5 = r7;
+	r7 = [p5 + TASK_NEEDRESCHED];
+	cc = r7 == 0;
+	if cc jump syscall_delayed_trace;
+	call SYMBOL_NAME(reschedule);
+	jump exit_syscall;
+syscall_delayed_trace:
+	/* Check for delayed trace */
+	r0 = [sp + PT_RESERVED];
+	r7 = [p5 + TASK_FLAGS];
+	cc = BITTST(r7, PF_DTRACE_BIT);
+	BITCLR(r7, PF_DTRACE_BIT);
+	[p5 + TASK_FLAGS] = r7;
+	if !cc jump syscall_task_state;
+	call SYMBOL_NAME(do_delayed_trace);
+syscall_task_state:
+	r7 = [p5 + TASK_STATE];
+	cc = r7 == 0;
+	if cc jump syscall_sigpending;
+	call SYMBOL_NAME(reschedule);
+	jump exit_syscall;
+syscall_sigpending:
+	r7 = [p5 + TASK_SIGPENDING];
+	cc = r7 == 0;
+	if cc jump syscall_really_exit;
+	call SYMBOL_NAME(Lsignal_return);
+syscall_really_exit:
+	r0 = [sp + PT_RESERVED];
+	rets = r0;
+	rts;
+
+ENTRY(ret_from_exception)
+	r0 = [sp + PT_IPEND];
+	CC = bittst(r0, 15);	/* check if returning to kernel*/
+	if cc jump 4f;   /* if so, skip resched, signals*/   
+	cc = bittst(r0, 3);	/* check if return from exception */
+	if cc jump 1f;
+	/* reduce the nested interrupt IVG14 --> IVG 15, */
+	/* see also asm/processor.h: start_thread */
+	call kernel_to_user_mode; 
+	r0.l = 0x2;
+	r0.h = 0x0;	/* flag for return to user mode */
+	[sp + PT_IPEND] = r0;
+1:
+	/* only allow interrupts when we are really the last one on the*/
+	/* kernel stack, otherwise stack overflow can occur during*/
+	/* heavy interupt load*/
+	p5.l = SYMBOL_NAME(_current_task);
+	p5.h = SYMBOL_NAME(_current_task);
+	r7 = [p5];
+	p5 = r7;
+	r7 = [p5+TASK_NEEDRESCHED];
+	cc = r7 == 0;
+	if cc jump 2f;
+	call SYMBOL_NAME(reschedule);
+	jump SYMBOL_NAME(ret_from_exception);
+2:
+	/* check for delayed trace*/
+	r7 = [p5+TASK_FLAGS];
+	cc = bittst(r7, PF_DTRACE_BIT);
+	bitclr (r7, PF_DTRACE_BIT);
+	[p5+TASK_FLAGS] = r7;
+	if !cc jump 5f;
+	call SYMBOL_NAME(do_delayed_trace);
+5:
+	r7 = [p5+TASK_STATE];		/* state*/
+	cc = r7 == 0;
+	if cc jump 3f
+	call SYMBOL_NAME(reschedule);
+	jump SYMBOL_NAME(ret_from_exception);
+3:
+	r7 = [p5+TASK_SIGPENDING];
+	cc = r7 == 0;
+	if cc jump 4f;
+	call SYMBOL_NAME(Lsignal_return);
+4:
+	p2.l = 0x2108;
+	p2.h = 0xffe0;
+	r0 = [p2];              // Read current IPEND
+	CC = bittst(r0, 14);
+	if !cc jump 8f;
+	nop;
+8:
+	CC = bittst(r0, 3);	/* check if return from exception*/
+	if cc jump 7f;
+	
+	r7 = [sp + PT_SYSCFG];	/* handle single step - STchen */
+	cc = bittst(r7, 0);
+	if cc jump supper_single_step;
+7:
+	RESTORE_ALL           
+	rtx;
+
+supper_single_step:
+	r0.l = prev_single_step;
+	r0.l = prev_single_step;
+	p2.l = 0x200c;
+	p2.h = 0xffe0;
+	[p2] = r0;
+	r0.l = force_exception;
+	r0.h = force_exception;
+	reti = r0;
+	rti;
+	
+	/* we must force the exception for supper single step while */ 
+	/* system return to user mode from system call, otherwise single */
+	/* step will happen in kernel but not in application --STchen*/
+force_exception:
+	excpt 0x1;
+	
+	/* return from exception to prevent supper single step */
+prev_single_step:
+	r0.l = SYMBOL_NAME(trap);
+	r0.h = SYMBOL_NAME(trap);
+	p2.l = 0x200c;
+	p2.h = 0xffe0;
+	[p2] = r0;
+	RESTORE_ALL
+	rtx;
+	
+SYMBOL_NAME_LABEL(Lsignal_return)
+	r0 = 0;
+	r1 = sp;
+	[--sp] = rets;
+	call SYMBOL_NAME(do_signal);
+	rets = [sp++];
+	rts;
+
+SYMBOL_NAME_LABEL(do_delayed_trace)
+	[--sp] = rets;
+	r0 = LSIGTRAP;
+	r1 = p5;
+	r2 = 1;
+	call SYMBOL_NAME(send_sig);
+	rets = [sp++];
+	rts;
+
+ENTRY(sys_fork)
+	call	SYMBOL_NAME(frio_fork);
+	rts;
+
+ENTRY(sys_clone)
+	r0 = sp;
+	[--sp] = rets;
+	call	SYMBOL_NAME(frio_clone);
+	rets = [sp++];
+	rts;
+
+ENTRY(sys_vfork)
+	r0 = sp;
+	[--sp] = rets;
+	call	SYMBOL_NAME(frio_vfork);
+	rets = [sp++];
+	rts;
+
+ENTRY(sys_sigsuspend)
+	call	SYMBOL_NAME(do_sigsuspend);
+	rts;
+
+ENTRY(sys_rt_sigsuspend)
+	call	SYMBOL_NAME(do_rt_sigsuspend);
+	rts;
+
+ENTRY(sys_sigreturn)
+	r0 = sp;
+	[--sp] = rets;
+	call	SYMBOL_NAME(do_sigreturn);
+	rets = [sp++];
+	rts;
+
+ENTRY(sys_rt_sigreturn)
+	call	SYMBOL_NAME(do_rt_sigreturn);
+	rts;
+
+/* Force kernel return from interrupt 15 to user mode -- Steven Chen*/
+SYMBOL_NAME_LABEL(kernel_to_user_mode)
+	[--sp] = rets;
+	r0 = [sp++];
+	reti = r0;
+	rti;
+	
+SYMBOL_NAME_LABEL(resume)
+	/*
+	 * Beware - when entering resume, prev (the current task) is
+	 * in r0, next (the new task) is in r1.
+	 */
+
+	p0 = r0;
+	p1 = r1;
+
+	[--sp] = rets;
+	[--sp] = (r7:6, p5:3);
+	[--sp] = fp;
+
+	/* save seqstat */
+	r7 = seqstat;
+	[p0+(TASK_THREAD+THREAD_SR)] = r7;
+
+	/* save usp */
+	p2 = usp;
+	[p0+(TASK_THREAD+THREAD_USP)] = p2;
+
+	/* save current kernel stack pointer */
+	[p0+(TASK_THREAD+THREAD_KSP)] = sp;
+
+	/* save program counter */
+	r1.l = SYMBOL_NAME(new_old_task);
+	r1.h = SYMBOL_NAME(new_old_task);
+	[p0+(TASK_THREAD+THREAD_PC)] = r1;
+
+	/* Return previous task in %r1 */
+	r1.l = SYMBOL_NAME(_current_task);
+	r1.h = SYMBOL_NAME(_current_task);
+
+	/* switch to new task (p1 contains new task) */
+	p5 = r1;
+	[p5] = p1;
+
+	/* restore the kernel stack pointer */
+	sp = [p1+(TASK_THREAD+THREAD_KSP)];
+
+	/* restore user stack pointer */
+	p0 = [p1+(TASK_THREAD+THREAD_USP)];
+	usp = p0;
+
+	/* restore status register */
+	r7 = [p1+(TASK_THREAD+THREAD_SR)];
+	seqstat = r7;
+
+	/* restore pc */
+	p0 = [p1+(TASK_THREAD+THREAD_PC)];
+	jump (p0); 
+
+	/*
+	 * While we don't rely on compiler magic, nothing prevents us from
+	 * simple jumps.
+	 * Following code actually lands up in a new (old) task. .. akale
+	 */
+
+new_old_task:	
+	fp = [sp++];
+
+	/* You may get assembler errors if you modify following instruction.
+	 * Had to do lots of experiments to get it right. The assembler simply
+	 * doesn't accept a correct syntax - amit */
+	( R7:6, p5 : 3) = [sp++];
+
+	rets = [sp++];
+
+	/*
+	 * When we come out of resume, r0 carries "old" task, becuase we are
+	 * in "new" task.
+	 */
+
+	rts;
+
+
+.data
+ALIGN
+SYMBOL_NAME_LABEL(sys_call_table)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 0  -  old "setup()" system call*/
+	.long SYMBOL_NAME(sys_exit)
+	.long SYMBOL_NAME(sys_fork)
+	.long SYMBOL_NAME(sys_read)
+	.long SYMBOL_NAME(sys_write)
+	.long SYMBOL_NAME(sys_open)		/* 5 */
+	.long SYMBOL_NAME(sys_close)
+	.long SYMBOL_NAME(sys_waitpid)
+	.long SYMBOL_NAME(sys_creat)
+	.long SYMBOL_NAME(sys_link)
+	.long SYMBOL_NAME(sys_unlink)		/* 10 */
+	.long SYMBOL_NAME(sys_execve)
+	.long SYMBOL_NAME(sys_chdir)
+	.long SYMBOL_NAME(sys_time)
+	.long SYMBOL_NAME(sys_mknod)
+	.long SYMBOL_NAME(sys_chmod)		/* 15 */
+	.long SYMBOL_NAME(sys_chown16)
+	.long SYMBOL_NAME(sys_ni_syscall)	/*old break syscall holder*/
+	.long SYMBOL_NAME(sys_stat)
+	.long SYMBOL_NAME(sys_lseek)
+	.long SYMBOL_NAME(sys_getpid)		/* 20 */
+	.long SYMBOL_NAME(sys_mount)
+	.long SYMBOL_NAME(sys_oldumount)
+	.long SYMBOL_NAME(sys_setuid16)
+	.long SYMBOL_NAME(sys_getuid16)
+	.long SYMBOL_NAME(sys_stime)		/* 25 */
+	.long SYMBOL_NAME(sys_ptrace)
+	.long SYMBOL_NAME(sys_alarm)
+	.long SYMBOL_NAME(sys_fstat)
+	.long SYMBOL_NAME(sys_pause)
+	.long SYMBOL_NAME(sys_utime)		/* 30 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old stty syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old gtty syscall holder */
+	.long SYMBOL_NAME(sys_access)
+	.long SYMBOL_NAME(sys_nice)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 35 old ftime syscall */
+	.long SYMBOL_NAME(sys_sync)
+	.long SYMBOL_NAME(sys_kill)
+	.long SYMBOL_NAME(sys_rename)
+	.long SYMBOL_NAME(sys_mkdir)
+	.long SYMBOL_NAME(sys_rmdir)		/* 40 */
+	.long SYMBOL_NAME(sys_dup)
+	.long SYMBOL_NAME(sys_pipe)
+	.long SYMBOL_NAME(sys_times)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old prof syscall holder */
+	.long SYMBOL_NAME(sys_brk)		/* 45 */
+	.long SYMBOL_NAME(sys_setgid16)
+	.long SYMBOL_NAME(sys_getgid16)
+	.long SYMBOL_NAME(sys_signal)
+	.long SYMBOL_NAME(sys_geteuid16)
+	.long SYMBOL_NAME(sys_getegid16)	/* 50 */
+	.long SYMBOL_NAME(sys_acct)
+	.long SYMBOL_NAME(sys_umount)		/* recycled unused phys() */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old lock syscall holder */
+	.long SYMBOL_NAME(sys_ioctl)
+	.long SYMBOL_NAME(sys_fcntl)		/* 55 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old mpx syscall holder */
+	.long SYMBOL_NAME(sys_setpgid)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old ulimit syscall */
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_umask)		/* 60 */
+	.long SYMBOL_NAME(sys_chroot)
+	.long SYMBOL_NAME(sys_ustat)
+	.long SYMBOL_NAME(sys_dup2)
+	.long SYMBOL_NAME(sys_getppid)
+	.long SYMBOL_NAME(sys_getpgrp)		/* 65 */
+	.long SYMBOL_NAME(sys_setsid)
+	.long SYMBOL_NAME(sys_sigaction)
+	.long SYMBOL_NAME(sys_sgetmask)
+	.long SYMBOL_NAME(sys_ssetmask)
+	.long SYMBOL_NAME(sys_setreuid16)	/* 70 */
+	.long SYMBOL_NAME(sys_setregid16)
+	.long SYMBOL_NAME(sys_sigsuspend)
+	.long SYMBOL_NAME(sys_sigpending)
+	.long SYMBOL_NAME(sys_sethostname)
+	.long SYMBOL_NAME(sys_setrlimit)	/* 75 */
+	.long SYMBOL_NAME(sys_old_getrlimit)
+	.long SYMBOL_NAME(sys_getrusage)
+	.long SYMBOL_NAME(sys_gettimeofday)
+	.long SYMBOL_NAME(sys_settimeofday)
+	.long SYMBOL_NAME(sys_getgroups16)	/* 80 */
+	.long SYMBOL_NAME(sys_setgroups16)
+	.long SYMBOL_NAME(old_select)
+	.long SYMBOL_NAME(sys_symlink)
+	.long SYMBOL_NAME(sys_lstat)
+	.long SYMBOL_NAME(sys_readlink)		/* 85 */
+	.long SYMBOL_NAME(sys_uselib)
+	.long SYMBOL_NAME(sys_swapon)
+	.long SYMBOL_NAME(sys_reboot)
+	.long SYMBOL_NAME(old_readdir)
+	.long SYMBOL_NAME(old_mmap)		/* 90 */
+	.long SYMBOL_NAME(sys_munmap)
+	.long SYMBOL_NAME(sys_truncate)
+	.long SYMBOL_NAME(sys_ftruncate)
+	.long SYMBOL_NAME(sys_fchmod)
+	.long SYMBOL_NAME(sys_fchown16)		/* 95 */
+	.long SYMBOL_NAME(sys_getpriority)
+	.long SYMBOL_NAME(sys_setpriority)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old profil syscall */
+	.long SYMBOL_NAME(sys_statfs)
+	.long SYMBOL_NAME(sys_fstatfs)		/* 100 */
+	.long SYMBOL_NAME(sys_ioperm)
+	.long SYMBOL_NAME(sys_socketcall)
+	.long SYMBOL_NAME(sys_syslog)
+	.long SYMBOL_NAME(sys_setitimer)
+	.long SYMBOL_NAME(sys_getitimer)	/* 105 */
+	.long SYMBOL_NAME(sys_newstat)
+	.long SYMBOL_NAME(sys_newlstat)
+	.long SYMBOL_NAME(sys_newfstat)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* iopl for i386 */ /* 110 */
+	.long SYMBOL_NAME(sys_vhangup)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* obsolete idle() syscall */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* vm86old for i386 */
+	.long SYMBOL_NAME(sys_wait4)
+	.long SYMBOL_NAME(sys_swapoff)		/* 115 */
+	.long SYMBOL_NAME(sys_sysinfo)
+	.long SYMBOL_NAME(sys_ipc)
+	.long SYMBOL_NAME(sys_fsync)
+	.long SYMBOL_NAME(sys_sigreturn)
+	.long SYMBOL_NAME(sys_clone)		/* 120 */
+	.long SYMBOL_NAME(sys_setdomainname)
+	.long SYMBOL_NAME(sys_newuname)
+	.long SYMBOL_NAME(sys_cacheflush)	/* modify_ldt for i386 */
+	.long SYMBOL_NAME(sys_adjtimex)
+	.long SYMBOL_NAME(sys_mprotect)		/* 125 */
+	.long SYMBOL_NAME(sys_sigprocmask)
+	.long SYMBOL_NAME(sys_create_module)
+	.long SYMBOL_NAME(sys_init_module)
+	.long SYMBOL_NAME(sys_delete_module)
+	.long SYMBOL_NAME(sys_get_kernel_syms)	/* 130 */
+	.long SYMBOL_NAME(sys_quotactl)
+	.long SYMBOL_NAME(sys_getpgid)
+	.long SYMBOL_NAME(sys_fchdir)
+	.long SYMBOL_NAME(sys_bdflush)
+	.long SYMBOL_NAME(sys_sysfs)		/* 135 */
+	.long SYMBOL_NAME(sys_personality)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for afs_syscall */
+	.long SYMBOL_NAME(sys_setfsuid16)
+	.long SYMBOL_NAME(sys_setfsgid16)
+	.long SYMBOL_NAME(sys_llseek)		/* 140 */
+	.long SYMBOL_NAME(sys_getdents)
+	.long SYMBOL_NAME(sys_select)
+	.long SYMBOL_NAME(sys_flock)
+	.long SYMBOL_NAME(sys_msync)
+	.long SYMBOL_NAME(sys_readv)		/* 145 */
+	.long SYMBOL_NAME(sys_writev)
+	.long SYMBOL_NAME(sys_getsid)
+	.long SYMBOL_NAME(sys_fdatasync)
+	.long SYMBOL_NAME(sys_sysctl)
+	.long SYMBOL_NAME(sys_mlock)		/* 150 */
+	.long SYMBOL_NAME(sys_munlock)
+	.long SYMBOL_NAME(sys_mlockall)
+	.long SYMBOL_NAME(sys_munlockall)
+	.long SYMBOL_NAME(sys_sched_setparam)
+	.long SYMBOL_NAME(sys_sched_getparam)   /* 155 */
+	.long SYMBOL_NAME(sys_sched_setscheduler)
+	.long SYMBOL_NAME(sys_sched_getscheduler)
+	.long SYMBOL_NAME(sys_sched_yield)
+	.long SYMBOL_NAME(sys_sched_get_priority_max)
+	.long SYMBOL_NAME(sys_sched_get_priority_min)  /* 160 */
+	.long SYMBOL_NAME(sys_sched_rr_get_interval)
+	.long SYMBOL_NAME(sys_nanosleep)
+	.long SYMBOL_NAME(sys_mremap)
+	.long SYMBOL_NAME(sys_setresuid16)
+	.long SYMBOL_NAME(sys_getresuid16)	/* 165 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for vm86 */
+	.long SYMBOL_NAME(sys_query_module)
+	.long SYMBOL_NAME(sys_poll)
+	.long SYMBOL_NAME(sys_nfsservctl)
+	.long SYMBOL_NAME(sys_setresgid16)	/* 170 */
+	.long SYMBOL_NAME(sys_getresgid16)
+	.long SYMBOL_NAME(sys_prctl)
+	.long SYMBOL_NAME(sys_rt_sigreturn)
+	.long SYMBOL_NAME(sys_rt_sigaction)
+	.long SYMBOL_NAME(sys_rt_sigprocmask)	/* 175 */
+	.long SYMBOL_NAME(sys_rt_sigpending)
+	.long SYMBOL_NAME(sys_rt_sigtimedwait)
+	.long SYMBOL_NAME(sys_rt_sigqueueinfo)
+	.long SYMBOL_NAME(sys_rt_sigsuspend)
+	.long SYMBOL_NAME(sys_pread)		/* 180 */
+	.long SYMBOL_NAME(sys_pwrite)
+	.long SYMBOL_NAME(sys_lchown16);
+	.long SYMBOL_NAME(sys_getcwd)
+	.long SYMBOL_NAME(sys_capget)
+	.long SYMBOL_NAME(sys_capset)           /* 185 */
+	.long SYMBOL_NAME(sys_sigaltstack)
+	.long SYMBOL_NAME(sys_sendfile)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* streams1 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* streams2 */
+	.long SYMBOL_NAME(sys_vfork)            /* 190 */
+	.long SYMBOL_NAME(sys_getrlimit)
+	.long SYMBOL_NAME(sys_mmap2)
+	.long SYMBOL_NAME(sys_truncate64)
+	.long SYMBOL_NAME(sys_ftruncate64)
+	.long SYMBOL_NAME(sys_stat64)		/* 195 */
+	.long SYMBOL_NAME(sys_lstat64)
+	.long SYMBOL_NAME(sys_fstat64)
+	.long SYMBOL_NAME(sys_chown)
+	.long SYMBOL_NAME(sys_getuid)
+	.long SYMBOL_NAME(sys_getgid)		/* 200 */
+	.long SYMBOL_NAME(sys_geteuid)
+	.long SYMBOL_NAME(sys_getegid)
+	.long SYMBOL_NAME(sys_setreuid)
+	.long SYMBOL_NAME(sys_setregid)
+	.long SYMBOL_NAME(sys_getgroups)	/* 205 */
+	.long SYMBOL_NAME(sys_setgroups)
+	.long SYMBOL_NAME(sys_fchown)
+	.long SYMBOL_NAME(sys_setresuid)
+	.long SYMBOL_NAME(sys_getresuid)
+	.long SYMBOL_NAME(sys_setresgid)	/* 210 */
+	.long SYMBOL_NAME(sys_getresgid)
+	.long SYMBOL_NAME(sys_lchown)
+	.long SYMBOL_NAME(sys_setuid)
+	.long SYMBOL_NAME(sys_setgid)
+	.long SYMBOL_NAME(sys_setfsuid)		/* 215 */
+	.long SYMBOL_NAME(sys_setfsgid)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
+
+	/* no recognization now by nisa-gcc */
+	.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4	
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.endr
diff -urN linux-2.4.29/arch/blackfin/platform/533/fixup.pl linux-2.4.29-uc1/arch/blackfin/platform/533/fixup.pl
--- linux-2.4.29/arch/blackfin/platform/533/fixup.pl	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/fixup.pl	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,91 @@
+#!/usr/bin/perl
+
+#
+# Nasty piece of work, designed to translated linux.bin binary image
+# in to several different formats.
+# 
+# Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>,
+#                    The Silver Hammer Group, Ltd.
+#
+
+@CRC = (
+        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+        0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+        0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+        0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+        0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
+        0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
+        0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
+        0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
+        0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
+        0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
+        0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
+        0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
+        0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+        0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
+        0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
+        0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
+        0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
+        0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
+        0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
+        0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
+        0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
+        0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+        0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
+        0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
+        0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
+        0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+        0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
+        0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
+        0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
+        0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
+        0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
+        0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
+);
+
+sub CrcBlock {
+	my($data,$crc) = @_;
+	my($i);
+	printf "Crc of %d bytes\n", length($data);
+	for ($i=0;$i<length($data);$i++) {
+#		printf "crc = %d, Lookup = %d, CRC[] = %d\n", $crc,						($crc>>8) ^
+#						ord(substr($data,$i,1)),
+#$CRC[						($crc>>8) ^
+#						ord(substr($data,$i,1)) &
+#0xff];
+#
+
+		$crc = ($crc << 8) ^ $CRC[
+						((($crc>>8) & 0xff) ^
+						ord(substr($data,$i,1))) &
+						0xff
+					];
+		$crc &= 0xffff;
+	}
+	return $crc & 0xffff;
+}
+
+open(T,"<linux.bin");
+$/ = undef;
+
+$image = join('', <T>);
+close(T);
+
+$realLength = length($image);
+$image .= "\0" x (0x100000 - $realLength);
+
+$posOfCardLength = 108;
+$posOfChecksum = 112;
+#$crc = CrcBlock(substr($image, 0, $posOfChecksum), 0);
+#$crc = CrcBlock(substr($image, $posOfChecksum+2), $crc);
+
+#substr($image, $posOfCardLength, 4) = pack("N", length($image));
+#substr($image, $posOfChecksum, 2) = pack("n", $crc);
+
+open(O,">linux.trg");
+print O substr($image, 0x10000, (($realLength - 0x10000) + 0xffff) & ~0xffff);
+close(O);
+
+open(O, ">linux.rom");
+print O $image;
+close(O);
diff -urN linux-2.4.29/arch/blackfin/platform/533/interrupt.S linux-2.4.29-uc1/arch/blackfin/platform/533/interrupt.S
--- linux-2.4.29/arch/blackfin/platform/533/interrupt.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/interrupt.S	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,210 @@
+/* linux/arch/frionommu/platform/frio/interrupt.S: 
+ *	 H/W interrupts
+ *	 - assumes default interrupt configuration for the interrupts
+ * 
+ * Copyright (C) 2003  Metrowerks, Inc. <mwaddel@metrowerks.com>
+ * Copyright (C) 2002  Arcturus Networks Ltd. Ted Ma <mated@sympatico.ca>
+ * Copyright (C) 1998  D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
+ *                     Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ * (c) 1995, Dionne & Associates
+ * (c) 1995, DKG Display Tech.
+ *
+ */
+
+#define ASSEMBLY
+	 
+#include <asm/hw_irq.h>
+
+#include <linux/autoconf.h>
+
+#include <asm/entry.h>
+#include "frio_defs.h"
+
+// Global references
+.global _stext;
+.global __bss_start;
+.global frio_irq_panic;		 // go to panic in ints.c
+	 
+	 
+/*****************************************************************************/
+// Data areas
+.bss
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+
+.data
+
+	 
+.text
+.align 2 	// just in case
+/*
+ * initial interrupt handlers
+ */
+#ifndef CONFIG_KGDB	// installs own handler
+ 	 /* interrupt routine for emulation - 0 */
+	 /* Currently used only if GDB stub is not in - invalid	  */
+	 /* gdb-stub set the evt itself */
+	 /* save registers for post-mortem only */
+.global evt_emulation
+evt_emulation:
+	SAVE_CONTEXT
+
+	r0 = IRQ_EMU;
+	r1 = seqstat; 
+	call	frio_irq_panic;	// this should go to an invalid - panic
+	// - GDB stub fills this in by itself (if defined)
+	rte; 
+#endif
+
+	/* interrupt routine for nmi - 2 */
+.global evt_nmi
+evt_nmi:
+	SAVE_CONTEXT
+
+	r0 = IRQ_NMI;
+	r1 = RETN;	     // get return address (but not going back)  
+	call frio_irq_panic; // this should end up at a panic - for now 
+_evt_nmi_exit:
+	rtn; 
+			
+irq_panic:
+	r0 = IRQ_EVX;
+	
+	/* Changed by HuTao, May 21, 2003 2:44PM */
+	r1 =  sp;
+	call	frio_irq_panic;
+	/* panic doesn't return, so no restoration of context. */
+	 
+	/* interrupt routine for ivhw - 5 */
+	/* Hardware Error */
+.global evt_ivhw
+evt_ivhw:
+	SAVE_CONTEXT
+
+	r1 = seqstat;	  // reason code is it bit 18:14
+	r0 = IRQ_HWERR; 
+	call	frio_irq_panic;
+	rti; 
+
+	/* interrupt routine for core timer - 6 */	 
+.global evt_timer
+evt_timer:
+
+	SAVE_CONTEXT
+	r0 = IRQ_CORETMR;  
+	r1 = SP;
+	call	process_int; // process_int(vec, pt_regs);
+	RESTORE_CONTEXT
+	rti; 
+	nop;
+
+	 /* interrupt routine for evt7 - 7 */	 
+.global evt_evt7
+evt_evt7:
+	SAVE_CONTEXT
+
+	r0 = 7;
+	r1 = SP;
+	call	process_int; // process_int(vec, pt_regs);
+evt_evt7_exit:
+	RESTORE_CONTEXT
+	rti; 
+
+	/* interrupt routine for evt8 - 8 */
+.global evt_evt8
+evt_evt8:
+	SAVE_CONTEXT
+
+	r0 = 8;
+	r1 = SP;
+	 
+	call	process_int; // process_int(vec, pt_regs);
+evt_evt8_exit:
+	RESTORE_CONTEXT
+	rti; 
+
+	/* interrupt routine for evt9 - 9 */	 
+.global evt_evt9
+evt_evt9:
+	SAVE_CONTEXT
+
+	r0 = 9;
+	r1 = SP;
+
+	call	process_int; // process_int(vec, pt_regs);
+evt_evt9_exit:
+	RESTORE_CONTEXT
+	rti; 
+
+	/* interrupt routine for evt10	- 10 */	 
+.global evt_evt10
+evt_evt10:
+	SAVE_CONTEXT
+
+	r0 = 10;
+	r1 = SP;
+	call	process_int; // process_int(vec, pt_regs);
+evt_evt10_exit:
+	RESTORE_CONTEXT
+	rti; 
+
+	 /* interrupt routine for evt11	- 11 */	 
+.global evt_evt11
+evt_evt11:
+	 SAVE_CONTEXT
+
+	r0 = 11;
+	r1 = SP;
+	call	process_int; // process_int(vec, pt_regs);
+evt_evt11_exit:
+	RESTORE_CONTEXT
+	rti; 
+
+	/* interrupt routine for evt12	- 12 */	 
+.global evt_evt12
+evt_evt12:
+	SAVE_CONTEXT
+
+	r0 = 12;
+	r1 = SP;
+	call	process_int; // process_int(vec, pt_regs);
+evt_evt12_exit:
+	RESTORE_CONTEXT
+	rti; 
+
+	/* interrupt routine for evt13	- 13 */
+.global evt_evt13
+evt_evt13:
+	SAVE_CONTEXT
+
+	r0 = 13;
+	r1 = SP;
+	 
+	call	process_int; // process_int(vec, pt_regs);
+evt_evt13_exit:
+	RESTORE_CONTEXT
+	rti; 
+
+	/* interrupt routine for system_call - 14 */	 
+.global evt_system_call
+evt_system_call:
+	SAVE_CONTEXT
+	call system_call;
+	RESTORE_CONTEXT
+	rti;
+.global evt_soft_int1
+evt_soft_int1:
+	SAVE_CONTEXT
+
+	r0 = IRQ_SW_INT1;	// Software Interrupt 1 
+	r1 = SP;
+	call	process_int; // process_int(vec, pt_regs);
+evt_soft_int1_exit:
+	RESTORE_CONTEXT
+	rti; 
diff -urN linux-2.4.29/arch/blackfin/platform/533/ints.c linux-2.4.29-uc1/arch/blackfin/platform/533/ints.c
--- linux-2.4.29/arch/blackfin/platform/533/ints.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/ints.c	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,397 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Apr18 2003, Changed by HuTao to support interrupt cascading for Blackfin 
+ *             drivers
+ * Sep 2003, Changed to support BlackFin BF533.
+ *
+ * Copyright 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne <jeff@uclinux.org>
+ * Copyright 2000-2001 Lineo, Inc. D. Jefff Dionne <jeff@lineo.ca>
+ * Copyright 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
+ * Copyright 2003 Metrowerks/Motorola
+ * Copyright 2003 Bas Vermeulen <bas@buyways.nl>,
+ *                BuyWays B.V. (www.buyways.nl)
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/kernel_stat.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+
+#include <asm/blackfin.h>
+
+/********************************************************************
+ * NOTES:
+ * - we have separated the physical Hardware interrupt from the
+ * levels that the LINUX kernel sees (see the description in irq.h)
+ * - 
+ ********************************************************************/
+
+#define INTERNAL_IRQS (32)
+
+int irq_flags = 0;
+
+/*********************
+ * Prototypes
+ ********************/
+/* Changed by HuTao, May21, 2003 2:38PM */
+asmlinkage void frio_irq_panic( int reason, struct pt_regs * reg);
+extern void dump(struct pt_regs * regs);
+
+/* BASE LEVEL interrupt handler routines */
+//asmlinkage void evt_reset(void);
+asmlinkage void evt_nmi(void);
+asmlinkage void evt_exception(void);
+asmlinkage void trap(void);
+asmlinkage void evt_ivhw(void);
+asmlinkage void evt_timer(void);
+asmlinkage void evt_evt7(void);
+asmlinkage void evt_evt8(void);
+asmlinkage void evt_evt9(void);
+asmlinkage void evt_evt10(void);
+asmlinkage void evt_evt11(void);
+asmlinkage void evt_evt12(void);
+asmlinkage void evt_evt13(void);
+asmlinkage void evt_soft_int1(void);
+asmlinkage void evt_system_call(void);
+
+/* irq node variables for the 32 (potential) on chip sources */
+static irq_node_t *int_irq_list[INTERNAL_IRQS];
+
+static int int_irq_count[INTERNAL_IRQS];
+static short int_irq_ablecount[INTERNAL_IRQS];
+
+/* Modified by HuTao, May21, 2003 */
+/*********
+ * frio_irq_panic
+ * - calls panic with string setup
+ *********/
+asmlinkage void frio_irq_panic( int reason, struct pt_regs * regs)
+{
+	
+  	printk("\n\nException: IRQ 0x%x entered\n", reason);
+	printk("code=[0x%08x], ", regs->seqstat & 0x3f);
+	printk("stack frame=0x%04x, ",(unsigned long) regs);
+	printk("bad PC=0x%04x\n", regs->pc);
+	dump(regs);
+	panic("Unhandled IRQ or exceptions!\n");
+}
+
+static void int_badint(int irq, void *dev_id, struct pt_regs *fp)
+{
+	num_spurious += 1;
+}
+
+ 
+/*
+ * This function should be called during kernel startup to initialize
+ * the Frio IRQ handling routines.
+ */
+
+void FRIO_init_IRQ(void)
+{
+   /*  Disable all the peripheral intrs  - page 4-29 HW Ref manual */	
+   *(unsigned volatile long *)(SIC_MASK_ADDR) = SIC_MASK_ALL;
+   
+   cli();
+#ifndef CONFIG_KGDB	// nisa-stub does this if enabled
+   *(unsigned volatile long *)(EVT_EMULATION_ADDR) = 
+#endif
+// RESET is a R/O register ...MaTed---
+// *(unsigned volatile long *)(EVT_RESET_ADDR) = 
+//                            (unsigned volatile long)evt_reset;
+   *(unsigned volatile long *)(EVT_NMI_ADDR) = 
+                              (unsigned volatile long)evt_nmi;
+   *(unsigned volatile long *)(EVT_EXCEPTION_ADDR) = 
+                              (unsigned volatile long)trap;
+   *(unsigned volatile long *)(EVT_HARDWARE_ERROR_ADDR) = 
+                              (unsigned volatile long)evt_ivhw;
+   *(unsigned volatile long *)(EVT_TIMER_ADDR) = 
+                              (unsigned volatile long)evt_timer;
+   *(unsigned volatile long *)(EVT_IVG7_ADDR) = 
+                              (unsigned volatile long)evt_evt7;
+   *(unsigned volatile long *)(EVT_IVG8_ADDR) = 
+                              (unsigned volatile long)evt_evt8;
+   *(unsigned volatile long *)(EVT_IVG9_ADDR) = 
+                              (unsigned volatile long)evt_evt9;
+   *(unsigned volatile long *)(EVT_IVG10_ADDR) = 
+                              (unsigned volatile long)evt_evt10;
+   *(unsigned volatile long *)(EVT_IVG11_ADDR) = 
+                              (unsigned volatile long)evt_evt11;
+   *(unsigned volatile long *)(EVT_IVG12_ADDR) = 
+                              (unsigned volatile long)evt_evt12;
+   *(unsigned volatile long *)(EVT_IVG13_ADDR) = 
+                              (unsigned volatile long)evt_evt13;
+   *(unsigned volatile long *)(EVT_IVG14_ADDR) = 
+                              (unsigned volatile long)evt_system_call;
+   *(unsigned volatile long *)(EVT_IVG15_ADDR) = 
+                              (unsigned volatile long)evt_soft_int1;
+
+   /* Enable interrupts IVG7-15 */
+   IMASK = irq_flags |= 0xffa0;
+   ILAT=0;
+   sti();
+}
+
+void FRIO_enable_irq(unsigned int irq);
+void FRIO_disable_irq(unsigned int irq);
+
+int FRIO_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d from %s\n", 
+			      __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+	if (!int_irq_list[irq]) {
+		int_irq_list[irq] = new_irq_node();
+		int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	}
+
+	if (!(int_irq_list[irq]->flags & IRQ_FLG_STD)) {
+		if (int_irq_list[irq]->flags & IRQ_FLG_LOCK) {
+			printk("IRQ %d is already assigned.\n", irq);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("Can't replace IRQ %d\n", irq);
+			return -EBUSY;
+		}
+	}
+	int_irq_list[irq]->handler = handler;
+	int_irq_list[irq]->flags   = flags;
+	int_irq_list[irq]->dev_id  = dev_id;
+	int_irq_list[irq]->devname = devname;
+
+	return 0;
+}
+
+void FRIO_free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_list[irq]->dev_id != dev_id)
+		printk("%s: removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, int_irq_list[irq]->devname);
+	int_irq_list[irq]->handler = int_badint;
+	int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	int_irq_list[irq]->dev_id  = NULL;
+	int_irq_list[irq]->devname = NULL;
+
+	FRIO_disable_irq(irq);
+}
+
+/*
+ * Enable/disable a particular machine specific interrupt source.
+ * Note that this may affect other interrupts in case of a shared interrupt.
+ * This function should only be called for a _very_ short time to change some
+ * internal data, that may not be changed by the interrupt at the same time.
+ * int_(enable|disable)_irq calls may also be nested.
+ */
+
+void FRIO_enable_irq(unsigned int irq)
+{
+	unsigned long irq_val;
+
+	cli();
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (irq <= IRQ_CORETMR)
+	{
+		/* enable the interrupt */
+		irq_flags |= 1<<irq;
+		sti();
+		return;
+	}
+
+	if (irq == IRQ_SPORT0)
+		irq_val = 0x600;
+	else if (irq == IRQ_SPORT1)
+		irq_val = 0x1800;
+	else if (irq == IRQ_UART)
+		irq_val = 0xC000;
+	else
+		irq_val = (1<<(irq - IRQ_CORETMR));
+
+   	*(unsigned volatile long *)(SIC_MASK_ADDR) |= irq_val;
+
+	sti();
+	
+}
+
+void FRIO_disable_irq(unsigned int irq)
+{
+	unsigned long irq_val;
+
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (irq < IRQ_CORETMR)
+	{
+		cli();
+		irq_flags &= ~(1<<irq);
+		sti();
+		return;
+	}
+
+	/*
+ 	 * If it is the interrupt for peripheral,
+	 * we only disable it in SIC_IMASK register.
+	 * No need to change IMASK register of CORE,
+	 * since all of the IVG for peripherals was 
+ 	 * enabled in FRIO_init_IRQ()
+	 *
+ 	 * HuTao, Apr18 2003
+	 */
+
+	if (irq == IRQ_SPORT0)
+		irq_val = 0x600;
+	else if (irq == IRQ_SPORT1)
+		irq_val = 0x1800;
+	else if (irq == IRQ_UART)
+		irq_val = 0xC000;
+	else
+		irq_val = (1<<(irq - IRQ_CORETMR));
+
+	cli();
+
+   	*(unsigned volatile long *)(SIC_MASK_ADDR) &= ~(irq_val); 
+	
+	sti();
+
+}
+
+void  call_isr(int irq, struct pt_regs * fp)
+{
+	if(int_irq_list[irq]->handler)
+	    int_irq_list[irq]->handler(irq,int_irq_list[irq]->dev_id, fp);
+	else 
+	    printk("unregistered interrupt %d\n", irq); 
+}
+
+void FRIO_do_irq(int vec, struct pt_regs *fp)
+{
+    /*
+     * We will check the SIC_IPEND to determine if it is
+     * the peripherals' interrupt.
+     * 
+     * HuTao, Apr18 2003
+     */
+    if (vec <= IRQ_CORETMR)
+    {	
+	 call_isr(vec, fp);
+	 return;
+    }
+
+    switch (vec)
+    {
+    case IVG7:
+	    if ((SIC_ISR & 0x1) && (SIC_MASK & 0x1))
+		    call_isr(IRQ_PLL_WAKEUP, fp);
+	    if ((SIC_ISR & 0x2) && (SIC_MASK & 0x2))
+		    call_isr(IRQ_DMA_ERROR, fp);
+	    if ((SIC_ISR & 0x4) && (SIC_MASK & 0x4))
+		    call_isr(IRQ_PPI_ERROR, fp);
+	    if ((SIC_ISR & 0x8) && (SIC_MASK & 0x8))
+		    call_isr(IRQ_SPORT0_ERROR, fp);
+	    if ((SIC_ISR & 0x10) && (SIC_MASK & 0x10))
+		    call_isr(IRQ_SPORT1_ERROR, fp);
+	    if ((SIC_ISR & 0x20) && (SIC_MASK & 0x20))
+		    call_isr(IRQ_SPI_ERROR, fp);
+	    if ((SIC_ISR & 0x40) && (SIC_MASK & 0x40))
+		    call_isr(IRQ_UART_ERROR, fp);
+	    break;
+    case IVG8:
+	    if ((SIC_ISR & 0x80) && (SIC_MASK & 0x80))
+		    call_isr(IRQ_RTC, fp);
+	    if ((SIC_ISR & 0x100) && (SIC_MASK & 0x100))
+		    call_isr(IRQ_PPI, fp);
+	    break;
+    case IVG9:
+	    if ((SIC_ISR & 0x600) && (SIC_MASK & 0x600))
+		    call_isr(IRQ_SPORT0, fp);
+	    if ((SIC_ISR & 0x1800) && (SIC_MASK & 0x1800))
+		    call_isr(IRQ_SPORT1, fp);
+	    break;
+    case IVG10:
+	    if ((SIC_ISR & 0x2000) && (SIC_MASK & 0x2000))
+		    call_isr(IRQ_SPI, fp);
+	    if ((SIC_ISR & 0xC000) && (SIC_MASK & 0xC000))
+		    call_isr(IRQ_UART, fp);
+	    break;
+    case IVG11:
+	    if ((SIC_ISR & 0x10000) && (SIC_MASK & 0x10000))
+		    call_isr(IRQ_TMR0, fp);
+	    if ((SIC_ISR & 0x20000) && (SIC_MASK & 0x20000))
+		    call_isr(IRQ_TMR1, fp);
+	    if ((SIC_ISR & 0x40000) && (SIC_MASK & 0x40000))
+		    call_isr(IRQ_TMR2, fp);
+	    break;
+    case IVG12:
+	    if ((SIC_ISR & 0x80000) && (SIC_MASK & 0x80000))
+		    call_isr(IRQ_PROG_INTA, fp);
+	    if ((SIC_ISR & 0x100000) && (SIC_MASK & 0x100000))
+		    call_isr(IRQ_PROG_INTB, fp);
+	    break;
+    case IVG13:
+	    if ((SIC_ISR & 0x200000) && (SIC_MASK & 0x200000))
+		    call_isr(IRQ_MEM_DMA0, fp);
+	    if ((SIC_ISR & 0x400000) && (SIC_MASK & 0x400000))
+		    call_isr(IRQ_MEM_DMA1, fp);
+	    if ((SIC_ISR & 0x800000) && (SIC_MASK & 0x800000))
+		    call_isr(IRQ_WATCH, fp);
+	    break;
+    }
+}
+
+int FRIO_get_irq_list(char *buf)
+{
+	int i, len = 0;
+	irq_node_t *node;
+
+	len += sprintf(buf+len, "Internal Blackfin interrupts\n");
+
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		if (!(node = int_irq_list[i]))
+			continue;
+		if (!(node->handler))
+			continue;
+
+		len += sprintf(buf+len, " %2d: %10u    %s\n", i,
+		               int_irq_count[i], int_irq_list[i]->devname);
+	}
+	return len;
+}
+
+void config_FRIO_irq(void)
+{
+	mach_default_handler = NULL;
+	mach_init_IRQ        = FRIO_init_IRQ;
+	mach_request_irq     = FRIO_request_irq;
+	mach_free_irq        = FRIO_free_irq;
+	mach_enable_irq      = FRIO_enable_irq;
+	mach_disable_irq     = FRIO_disable_irq;
+	mach_get_irq_list    = FRIO_get_irq_list;
+	mach_process_int     = FRIO_do_irq;
+}
diff -urN linux-2.4.29/arch/blackfin/platform/533/Makefile linux-2.4.29-uc1/arch/blackfin/platform/533/Makefile
--- linux-2.4.29/arch/blackfin/platform/533/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/Makefile	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,30 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o traps.o ints.o interrupt.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S $(BOARD)/bootlogo.rh
+
+entry.o: entry.S frio_defs.h
+
+frio_defs.h: ../../kernel/frio_defs.c ../../kernel/frio_defs.head
+	rm -f frio_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/frio_defs.c
+	cp ../../kernel/frio_defs.head frio_defs.h
+	grep '^#define' frio_defs.s >> frio_defs.h
+	rm frio_defs.s
+-include frio_defs.d
+
+$(BOARD)/bootlogo.rh: $(BOARD)/bootlogo.h
+	perl tools/bootlogo.pl < $(BOARD)/bootlogo.h > $(BOARD)/bootlogo.rh
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/blackfin/platform/533/peng.pl linux-2.4.29-uc1/arch/blackfin/platform/533/peng.pl
--- linux-2.4.29/arch/blackfin/platform/533/peng.pl	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/peng.pl	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,10 @@
+
+$_ = join("", <>);
+
+s/(0x[0-9a-f]{2})/sprintf("0x%.2x",ord(pack("b8",unpack("B8",chr(hex($1))))))/gei;
+
+s/^ /	.byte /gm;
+s/[,};]+$//gm;
+s/^static.*//gm;
+
+print $_;
diff -urN linux-2.4.29/arch/blackfin/platform/533/Rules.make linux-2.4.29-uc1/arch/blackfin/platform/533/Rules.make
--- linux-2.4.29/arch/blackfin/platform/533/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/Rules.make	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,94 @@
+#
+# ADI/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 2002  Metrowerks, Inc. <mwaddel@metrowerks.ca> 
+# Copyright (c) 2000,2001  Lineo, Inc. <jeff@lineo.ca> 
+# Copyright (c) 1998,1999  D. Jeff Dionne <jeff@uclinux.org>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+#
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+INCGCC = $(GCC_DIR)/include
+#LIBGCC = $(GCC_DIR)/000/libgcc.a
+
+CFLAGS := -mno-underscore -fno-builtin -DNO_CACHE $(CFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -D__ELF__ -DMAGIC_ROM_PTR -DNO_FORGET -DUTS_SYSNAME='"uClinux"' -D__linux__ 
+AFLAGS := $(AFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME='"uClinux"' -Wa
+
+ifndef CONFIG_FULLDEBUG
+LINKFLAGS = -T $(TOPDIR)/arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+else
+LINKFLAGS = -S -T $(TOPDIR)/arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+endif
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+
+
+
+
+#########   Temp modification: Tonyko   ############
+#CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+
+CORE_FILES := arch/$(ARCH)/kernel/process.o arch/$(ARCH)/kernel/traps.o \
+	      arch/$(ARCH)/kernel/ptrace.o  arch/$(ARCH)/kernel/sys_frio.o \
+              arch/$(ARCH)/kernel/time.o    arch/$(ARCH)/kernel/semaphore.o \
+              arch/$(ARCH)/kernel/setup.o   arch/$(ARCH)/kernel/frio_ksyms.o \
+              arch/$(ARCH)/mm/init.o        arch/$(ARCH)/mm/fault.o \
+              arch/$(ARCH)/mm/memory.o      arch/$(ARCH)/mm/kmap.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/entry.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/config.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/signal.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/interrupt.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/traps.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/ints.o $(CORE_FILES)
+
+
+LIBS += arch/$(ARCH)/lib/lib.a
+
+ifdef CONFIG_FRAMEBUFFER
+SUBDIRS := $(SUBDIRS) arch/$(ARCH)/console
+ARCHIVES := $(ARCHIVES) arch/$(ARCH)/console/console.a
+endif
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+romfs.s19: romfs.img arch/$(ARCH)/empty.o
+	$(CROSS_COMPILE)objcopy -v -R .text -R .data -R .bss --add-section=.fs=romfs.img --adjust-section-vma=.fs=0xa0000 arch/$(ARCH)/empty.o romfs.s19
+	$(CROSS_COMPILE)objcopy -O srec romfs.s19
+
+linux.data: linux
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.romvec --remove-section=.text --remove-section=.ramvec --remove-section=.bss --remove-section=.eram linux linux.data
+
+linux.text: linux
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.ramvec --remove-section=.bss --remove-section=.data --remove-section=.eram --set-section-flags=.romvec=CONTENTS,ALLOC,LOAD,READONLY,CODE linux linux.text
+
+romfs.img:
+	echo creating a vmlinux rom image without root filesystem!
+
+linux.bin: linux.text linux.data romfs.img
+	if [ -f romfs.img ]; then\
+		cat linux.text linux.data romfs.img > linux.bin;\
+	else\
+		cat linux.text linux.data > linux.bin;\
+	fi
+
+linux.trg linux.rom: linux.bin
+	perl arch/$(ARCH)/platform/$(PLATFORM)/tools/fixup.pl
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f arch/$(ARCH)/platform/$(PLATFORM)/frio_defs.h
+	rm -f linux.text linux.data linux.bin linux.rom linux.trg
+	rm -f linux.s19 romfs.s19
+	rm -f linux.img romdisk.img
diff -urN linux-2.4.29/arch/blackfin/platform/533/signal.c linux-2.4.29-uc1/arch/blackfin/platform/533/signal.c
--- linux-2.4.29/arch/blackfin/platform/533/signal.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/signal.c	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,735 @@
+/*
+ *  linux/arch/frionommu/kernel/signal.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
+ * Atari :-) Current limitation: Only one sigstack can be active at one time.
+ * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
+ * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
+ * signal handlers!
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/highuid.h>
+#include <linux/personality.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/traps.h>
+#include <asm/ucontext.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage long sys_wait4(pid_t pid, unsigned int *stat_addr,
+			 int options, struct rusage *ru);
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
+
+struct sigframe
+{
+	char *pretcode;
+	int sig;
+	int code;
+	struct sigcontext *psc;
+	char retcode[8];
+	unsigned long extramask[_NSIG_WORDS-1];
+	struct sigcontext sc;
+};
+
+struct rt_sigframe
+{
+	char *pretcode;
+	int sig;
+	struct siginfo *pinfo;
+	void *puc;
+	char retcode[8];
+	struct siginfo info;
+	struct ucontext uc;
+};
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ *
+ * ??? input entry: r3 of pt_regs
+ */
+asmlinkage int do_sigsuspend(struct pt_regs *regs)
+{
+	old_sigset_t mask = regs->r3;	/* old_sigset_t: unsigned long */
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending(current);
+
+	regs->r0 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+do_rt_sigsuspend(struct pt_regs *regs)
+{
+	sigset_t *unewset = (sigset_t *)regs->r1;
+	size_t sigsetsize = (size_t)regs->r2;
+	/* ??? need change for the exact regs  */
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending(current);
+
+	regs->r0 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int 
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+{
+	return do_sigaltstack(uss, uoss, rdusp());
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ *
+ * Keep the return code on the stack quadword aligned!
+ * That makes the cache flush below easier.
+ */
+
+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
+{
+	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+		return -EFAULT;
+	if (from->si_code < 0)
+		return __copy_to_user(to, from, sizeof(siginfo_t));
+	else {
+		int err;
+
+		/* If you change siginfo_t structure, please be sure
+		   this code is fixed accordingly.
+		   It should never copy any pad contained in the structure
+		   to avoid security leaks, but must copy the generic
+		   3 ints plus the relevant union member.  */
+		err = __put_user(from->si_signo, &to->si_signo);
+		err |= __put_user(from->si_errno, &to->si_errno);
+		err |= __put_user((short)from->si_code, &to->si_code);
+		/* First 32bits of unions are always present.  */
+		err |= __put_user(from->si_pid, &to->si_pid);
+		switch (from->si_code >> 16) {
+		case __SI_FAULT >> 16:
+			break;
+		case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+			err |= __put_user(from->si_status, &to->si_status);
+		default:
+			err |= __put_user(from->si_uid, &to->si_uid);
+			break;
+		/* case __SI_RT: This is not generated by the kernel as of now.  */
+		}
+		return err;
+	}
+}
+
+
+static inline int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp, int *pd0)
+{
+	struct sigcontext context;
+	int err = 0;
+
+	/* get previous context */
+	if (copy_from_user(&context, usc, sizeof(context)))
+		goto badframe;
+	
+	/* restore passed registers */
+	regs->r1 = context.sc_r1;
+	regs->p0 = context.sc_p0;
+	regs->p1 = context.sc_p1;
+	regs->seqstat = context.sc_seqstat;
+	regs->pc = context.sc_pc;
+	regs->orig_r0 = -1;		/* disable syscall checks */
+	wrusp(context.sc_usp);
+
+	*pd0 = context.sc_r0;
+	return err;
+
+badframe:
+	return 1;
+}
+
+static inline int
+rt_restore_ucontext(struct pt_regs *regs, struct ucontext *uc, int *pd0)
+{
+	int temp;
+	greg_t *gregs = uc->uc_mcontext.gregs;
+	unsigned long usp;
+	int err;
+
+	err = __get_user(temp, &uc->uc_mcontext.version);
+	if (temp != MCONTEXT_VERSION)
+		goto badframe;
+	/* restore passed registers */
+	err |= __get_user(regs->r0, &gregs[0]);
+	err |= __get_user(regs->r1, &gregs[1]);
+	err |= __get_user(regs->r2, &gregs[2]);
+	err |= __get_user(regs->r3, &gregs[3]);
+	err |= __get_user(regs->r4, &gregs[4]);
+	err |= __get_user(regs->r5, &gregs[5]);
+	err |= __get_user(regs->r6, &gregs[6]);
+	err |= __get_user(regs->r7, &gregs[7]);
+	err |= __get_user(regs->p0, &gregs[8]);
+	err |= __get_user(regs->p1, &gregs[9]);
+	err |= __get_user(regs->p2, &gregs[10]);
+	err |= __get_user(regs->p3, &gregs[11]);
+	err |= __get_user(regs->p4, &gregs[12]);
+	err |= __get_user(regs->p5, &gregs[13]);
+	err |= __get_user(usp, &gregs[14]);
+	wrusp(usp);
+	err |= __get_user(regs->a0w, &gregs[15]);
+	err |= __get_user(regs->a1w, &gregs[16]);
+	err |= __get_user(regs->a0x, &gregs[17]);
+	err |= __get_user(regs->a1x, &gregs[18]);
+	err |= __get_user(regs->astat, &gregs[19]);
+	err |= __get_user(regs->rets, &gregs[20]);
+	regs->orig_r0 = -1;		/* disable syscall checks */
+
+	if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
+		goto badframe;
+
+	*pd0 = regs->r0;
+	return err;
+
+badframe:
+	return 1;
+}
+
+asmlinkage int do_sigreturn(unsigned long __unused)
+{
+	__label__ badframe;
+
+	struct pt_regs *regs = (struct pt_regs *) __unused;
+	unsigned long usp = rdusp();
+	struct sigframe *frame = (struct sigframe *)(usp);// - 4);
+	/* how is transfered ???   Tony */ 
+
+	sigset_t set;
+	int r0;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__get_user(set.sig[0], &frame->sc.sc_mask))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	current->blocked = set;
+	recalc_sigpending(current);
+
+	if (restore_sigcontext(regs, &frame->sc, frame + 1, &r0))
+		goto badframe;
+	return r0;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int do_rt_sigreturn(unsigned long __unused)
+{
+	struct pt_regs *regs = (struct pt_regs *) &__unused;
+	unsigned long usp = rdusp();
+	struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
+	/* how is transfered ???   Tony	*/
+
+	sigset_t set;
+	int d0;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	current->blocked = set;
+	recalc_sigpending(current);
+	
+	if (rt_restore_ucontext(regs, &frame->uc, &d0))
+		goto badframe;
+	return d0;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+			     unsigned long mask)
+{
+	sc->sc_mask = mask;
+	sc->sc_usp = rdusp();
+	sc->sc_r0 = regs->r0;
+	sc->sc_r1 = regs->r1;
+	sc->sc_p0 = regs->p0;
+	sc->sc_p1 = regs->p1;
+	sc->sc_seqstat = regs->seqstat;
+	sc->sc_pc = regs->pc;
+}
+
+static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
+{
+	greg_t *gregs = uc->uc_mcontext.gregs;
+	int err = 0;
+
+	err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
+	err |= __put_user(regs->r0, &gregs[0]);
+	err |= __put_user(regs->r1, &gregs[1]);
+	err |= __put_user(regs->r2, &gregs[2]);
+	err |= __put_user(regs->r3, &gregs[3]);
+	err |= __put_user(regs->r4, &gregs[4]);
+	err |= __put_user(regs->r5, &gregs[5]);
+	err |= __put_user(regs->r6, &gregs[6]);
+	err |= __put_user(regs->r7, &gregs[7]);
+	err |= __put_user(regs->p0, &gregs[8]);
+	err |= __put_user(regs->p1, &gregs[9]);
+	err |= __put_user(regs->p2, &gregs[10]);
+	err |= __put_user(regs->p3, &gregs[11]);
+	err |= __put_user(regs->p4, &gregs[12]);
+	err |= __put_user(regs->p5, &gregs[13]);
+	err |= __put_user(rdusp() , &gregs[14]);
+	err |= __put_user(regs->a0w, &gregs[15]);
+	err |= __put_user(regs->a1w, &gregs[16]);
+	err |= __put_user(regs->a0x, &gregs[17]);
+	err |= __put_user(regs->a1x, &gregs[18]);
+	err |= __put_user(regs->astat, &gregs[19]);
+	err |= __put_user(regs->rets, &gregs[20]);
+
+	return err;
+}
+
+static inline void push_cache (unsigned long vaddr)
+{
+}
+
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	unsigned long usp;
+
+	/* Default to using normal stack.  */
+	usp = rdusp();
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if (ka->sa.sa_flags & SA_ONSTACK) {
+		if (!on_sig_stack(usp))
+			usp = current->sas_ss_sp + current->sas_ss_size;
+	}
+	return (void *)((usp - frame_size) & -8UL);
+}
+
+static void setup_frame (int sig, struct k_sigaction *ka,
+			 sigset_t *set, struct pt_regs *regs)
+{
+	struct sigframe *frame;
+	struct sigcontext context;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	err |= __put_user((current->exec_domain
+			   && current->exec_domain->signal_invmap
+			   && sig < 32
+			   ? current->exec_domain->signal_invmap[sig]
+			   : sig),
+			  &frame->sig);
+
+	err |= __put_user(&frame->sc, &frame->psc);
+
+	setup_sigcontext(&context, regs, set->sig[0]);
+	err |= copy_to_user (&frame->sc, &context, sizeof(context));
+
+	/* Set up to return from userspace.  */
+	err |= __put_user(frame->retcode, &frame->pretcode);
+	/* r5 = 0x77(z); excpt 0x0; -STchen*/
+	err |= __put_user(0x85, &(frame->retcode[0]));
+	err |= __put_user(0xe1, &(frame->retcode[1]));
+	err |= __put_user(0x77, &(frame->retcode[2]));
+	err |= __put_user(0x00, &(frame->retcode[3]));
+	err |= __put_user(0xa0, &(frame->retcode[4]));
+	err |= __put_user(0x00, &(frame->retcode[5]));
+
+	if (err)
+		goto give_sigsegv;
+
+	push_cache ((unsigned long) &frame->retcode);
+
+	/* Set up registers for signal handler */
+	wrusp ((unsigned long) frame);
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+	regs->rets = (unsigned long) (frame->retcode);
+
+adjust_stack:
+
+#if NEEDED
+	/* Prepare to skip over the extra stuff in the exception frame.  */
+	if (regs->stkadj) {
+		struct pt_regs *tregs =
+			(struct pt_regs *)((ulong)regs + regs->stkadj);
+#if DEBUG
+		printk("Performing stackadjust=%04x\n", regs->stkadj);
+#endif
+		/* This must be copied with decreasing addresses to
+                   handle overlaps.  */
+		tregs->pc = regs->pc;
+		tregs->seqstat = regs->seqstat;
+	}
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+	goto adjust_stack;
+}
+
+static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
+			    sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	err |= __put_user((current->exec_domain
+			   && current->exec_domain->signal_invmap
+			   && sig < 32
+			   ? current->exec_domain->signal_invmap[sig]
+			   : sig),
+			  &frame->sig);
+	err |= __put_user(&frame->info, &frame->pinfo);
+	err |= __put_user(&frame->uc, &frame->puc);
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+			  &frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(rdusp()),
+			  &frame->uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= rt_setup_ucontext(&frame->uc, regs);
+	err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	/* Set up to return from userspace.  */
+	err |= __put_user(frame->retcode, &frame->pretcode);
+	/* moveq #,d0; notb d0; trap #0 */
+	err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
+			  (long *)(frame->retcode + 0));
+	err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
+
+	if (err)
+		goto give_sigsegv;
+
+	push_cache ((unsigned long) &frame->retcode);
+
+	/* Set up registers for signal handler */
+	wrusp ((unsigned long) frame);
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+
+adjust_stack:
+
+#if NEEDED
+	/* Prepare to skip over the extra stuff in the exception frame.  */
+	if (regs->stkadj) {
+		struct pt_regs *tregs =
+			(struct pt_regs *)((ulong)regs + regs->stkadj);
+#if DEBUG
+		printk("Performing stackadjust=%04x\n", regs->stkadj);
+#endif
+		/* This must be copied with decreasing addresses to
+                   handle overlaps.  */
+		tregs->pc = regs->pc;
+		tregs->seqstat = regs->seqstat;
+	}
+#endif /* NEEDED */
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+	goto adjust_stack;
+}
+
+static inline void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
+{
+	switch (regs->r0) {
+	case -ERESTARTNOHAND:
+		if (!has_handler)
+			goto do_restart;
+		regs->r0 = -EINTR;
+		break;
+
+	case -ERESTARTSYS:
+		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
+			regs->r0 = -EINTR;
+			break;
+		}
+	/* fallthrough */
+	case -ERESTARTNOINTR:
+	do_restart:
+		regs->r0 = regs->orig_r0;
+//		regs->pc -= 2; /* if minus 2 correct	*/
+		break;
+	}
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static void
+handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
+	      sigset_t *oldset, struct pt_regs *regs)
+{
+	/* are we from a system call? to see pt_regs->orig_r0 */
+	if (regs->orig_r0 >= 0)
+		/* If so, check system call restarting.. */
+		handle_restart(regs, ka, 1);
+
+	/* set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+	if (!(ka->sa.sa_flags & SA_NODEFER))
+		sigaddset(&current->blocked,sig);
+	recalc_sigpending(current);
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals
+ * that the kernel can handle, and then we build all the user-level signal
+ * handling stack-frames in one go after that.
+ */
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
+{
+	siginfo_t info;
+	struct k_sigaction *ka;
+
+	current->thread.esp0 = (unsigned long) regs;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	for (;;) {
+		int signr;
+
+		signr = dequeue_signal(&current->blocked, &info);
+
+		if (!signr)
+			break;
+
+		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			//regs->seqstat &= ~PS_T; /* Tony  */
+
+			/* Did we come from a system call? */
+			if (regs->orig_r0 >= 0) {
+				/* Restart the system call the same way as
+				   if the process were not traced.  */
+				struct k_sigaction *ka =
+					&current->sig->action[signr-1];
+				int has_handler =
+					(ka->sa.sa_handler != SIG_IGN &&
+					 ka->sa.sa_handler != SIG_DFL);
+				handle_restart(regs, ka, has_handler);
+			}
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code)) {
+			discard_frame:
+			    continue;
+			}
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				goto discard_frame;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD:
+			case SIGWINCH: case SIGURG:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP:
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				if (!(current->p_pptr->sig->action[SIGCHLD-1]
+				      .sa.sa_flags & SA_NOCLDSTOP))
+					notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGIOT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				sigaddset(&current->pending.signal, signr);
+				recalc_sigpending(current);
+				current->flags |= PF_SIGNALED;
+				do_exit(exit_code);
+				/* NOTREACHED */
+			}
+		}
+
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(signr, ka, &info, oldset, regs);
+		return 1;
+	}
+
+	/* Did we come from a system call? */
+	if (regs->orig_r0 >= 0)
+		/* Restart the system call - no handlers present */
+		handle_restart(regs, NULL, 0);
+
+	/* If we are about to discard some frame stuff we must copy
+	   over the remaining frame. */
+
+#if NEEDED
+	if (regs->stkadj) {
+		struct pt_regs *tregs =
+		  (struct pt_regs *) ((ulong) regs + regs->stkadj);
+
+		/* This must be copied with decreasing addresses to
+		   handle overlaps.  */
+		tregs->pc = regs->pc;
+		tregs->seqstat = regs->seqstat;
+	}
+#endif
+
+	return 0;
+}
+
+/************************ garbage of original m68k ***************/
diff -urN linux-2.4.29/arch/blackfin/platform/533/tools/bootlogo.pl linux-2.4.29-uc1/arch/blackfin/platform/533/tools/bootlogo.pl
--- linux-2.4.29/arch/blackfin/platform/533/tools/bootlogo.pl	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/tools/bootlogo.pl	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,10 @@
+
+$_ = join("", <>);
+
+s/(0x[0-9a-f]{2})/sprintf("0x%.2x",ord(pack("b8",unpack("B8",chr(hex($1))))))/gei;
+
+s/^ /	.byte /gm;
+s/[,};]+$//gm;
+s/^static.*//gm;
+
+print $_;
diff -urN linux-2.4.29/arch/blackfin/platform/533/tools/fixup.pl linux-2.4.29-uc1/arch/blackfin/platform/533/tools/fixup.pl
--- linux-2.4.29/arch/blackfin/platform/533/tools/fixup.pl	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/tools/fixup.pl	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,91 @@
+#!/usr/bin/perl
+
+#
+# Nasty piece of work, designed to translated linux.bin binary image
+# in to several different formats.
+# 
+# Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>,
+#                    The Silver Hammer Group, Ltd.
+#
+
+@CRC = (
+        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+        0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+        0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+        0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+        0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
+        0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
+        0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
+        0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
+        0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
+        0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
+        0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
+        0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
+        0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+        0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
+        0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
+        0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
+        0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
+        0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
+        0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
+        0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
+        0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
+        0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+        0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
+        0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
+        0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
+        0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+        0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
+        0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
+        0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
+        0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
+        0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
+        0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
+);
+
+sub CrcBlock {
+	my($data,$crc) = @_;
+	my($i);
+	printf "Crc of %d bytes\n", length($data);
+	for ($i=0;$i<length($data);$i++) {
+#		printf "crc = %d, Lookup = %d, CRC[] = %d\n", $crc,						($crc>>8) ^
+#						ord(substr($data,$i,1)),
+#$CRC[						($crc>>8) ^
+#						ord(substr($data,$i,1)) &
+#0xff];
+#
+
+		$crc = ($crc << 8) ^ $CRC[
+						((($crc>>8) & 0xff) ^
+						ord(substr($data,$i,1))) &
+						0xff
+					];
+		$crc &= 0xffff;
+	}
+	return $crc & 0xffff;
+}
+
+open(T,"<linux.bin");
+$/ = undef;
+
+$image = join('', <T>);
+close(T);
+
+$realLength = length($image);
+$image .= "\0" x (0x100000 - $realLength);
+
+$posOfCardLength = 108;
+$posOfChecksum = 112;
+#$crc = CrcBlock(substr($image, 0, $posOfChecksum), 0);
+#$crc = CrcBlock(substr($image, $posOfChecksum+2), $crc);
+
+#substr($image, $posOfCardLength, 4) = pack("N", length($image));
+#substr($image, $posOfChecksum, 2) = pack("n", $crc);
+
+open(O,">linux.trg");
+print O substr($image, 0x10000, (($realLength - 0x10000) + 0xffff) & ~0xffff);
+close(O);
+
+open(O, ">linux.rom");
+print O $image;
+close(O);
diff -urN linux-2.4.29/arch/blackfin/platform/533/traps.c linux-2.4.29-uc1/arch/blackfin/platform/533/traps.c
--- linux-2.4.29/arch/blackfin/platform/533/traps.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/533/traps.c	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,209 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/traps.c -- general exception handling code
+ *
+ * Cloned from Linux/m68k.
+ *
+ * No original Copyright holder listed,
+ * Probabily original (C) Roman Zippel (assigned DJD, 1999)
+ *
+ * Copyright 2003 Metrowerks - for Blackfin
+ * Copyright 2000-2001 Lineo, Inc. D. Jeff Dionne <jeff@lineo.ca>
+ * Copyright 1999-2000 D. Jeff Dionne, <jeff@uclinux.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+// This #define is to cause the variables interruptFlags and interruptEnable
+//  to be defined ...MaTed---
+#define DEF_INTERRUPT_FLAGS 1
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/errno.h>
+#include <linux/irq.h>
+
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+
+/* table for system interrupt handlers */
+static irq_handler_t irq_list[SYS_IRQS];
+
+static const char *default_names[SYS_IRQS] = {
+	"spurious int", "int1 handler", "int2 handler", "int3 handler",
+	"int4 handler", "int5 handler", "int6 handler", "int7 handler"
+};
+
+/* The number of spurious interrupts */
+volatile unsigned int num_spurious;
+
+#define NUM_IRQ_NODES 16
+static irq_node_t nodes[NUM_IRQ_NODES];
+
+/*
+ * void init_IRQ(void)
+ *
+ * Parameters:	None
+ *
+ * Returns:	Nothing
+ *
+ * This function should be called during kernel startup to initialize
+ * the IRQ handling routines.
+ */
+
+void init_IRQ(void)
+{
+	mach_init_IRQ ();
+}
+
+irq_node_t *new_irq_node(void)
+{
+	irq_node_t *node;
+	short i;
+
+	for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--)
+		if (!node->handler)
+			return node;
+
+	printk ("new_irq_node: out of nodes\n");
+	return NULL;
+}
+
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq)
+		return mach_request_irq(irq, handler, flags, devname, dev_id);
+
+	if (irq < IRQ_EMU || irq > IRQ_SW_INT2) {
+		printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+	if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
+		if (irq_list[irq].flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+	}
+	irq_list[irq].handler = handler;
+	irq_list[irq].flags   = flags;
+	irq_list[irq].dev_id  = dev_id;
+	irq_list[irq].devname = devname;
+	return 0;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq) {
+		mach_free_irq(irq, dev_id);
+		return;
+	}
+
+	if (irq < IRQ_EMU || irq > IRQ_SW_INT2) {
+		printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (irq_list[irq].dev_id != dev_id)
+		printk("%s: Removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, irq_list[irq].devname);
+
+	if (mach_default_handler)
+		irq_list[irq].handler = (*mach_default_handler)[irq];
+	else
+		irq_list[irq].handler = NULL;
+	irq_list[irq].flags   = IRQ_FLG_STD;
+	irq_list[irq].dev_id  = NULL;
+	irq_list[irq].devname = default_names[irq];
+}
+
+unsigned long probe_irq_on (void)
+{
+	return 0;
+}
+
+int probe_irq_off (unsigned long irqs)
+{
+	return 0;
+}
+
+asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
+{
+                if (mach_process_int)
+                        mach_process_int(vec, fp);
+                else
+                        panic("Can't process interrupt vector %ld\n", vec);
+                return;
+}
+
+int get_irq_list(char *buf)
+{
+        int i, len = 0;
+	
+        /* autovector interrupts */
+        if (mach_default_handler) {
+                for (i = 0; i < SYS_IRQS; i++) {
+                       len += sprintf(buf+len, "auto %2d: %10u ", i,
+		       i ? kstat.irqs[0][i] : num_spurious);
+                       len += sprintf(buf+len, "  ");
+                       len += sprintf(buf+len, "%s\n", irq_list[i].devname);
+
+		}
+        }
+        len += mach_get_irq_list(buf+len);
+        return len;
+}
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+
+void dump(struct pt_regs *fp)
+{
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk("\nCURRENT PROCESS:\n\n");
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk("USER-STACK=%08x\n\n",
+			(int) current->mm->start_stack);
+	}
+
+	printk("PC: %08lx\n", fp->pc);
+	printk("SEQSTAT: %08lx    SP: %08lx\n", (long) fp->seqstat, (long) fp);
+	printk("R0: %08lx    R1: %08lx    R2: %08lx    R3: %08lx\n",
+		fp->r0, fp->r1, fp->r2, fp->r3);
+	printk("R4: %08lx    R5: %08lx    R6: %08lx    R7: %08lx\n",
+		fp->r4, fp->r5, fp->r6, fp->r7);
+	printk("P0: %08lx    P1: %08lx    P2: %08lx    P3: %08lx\n",
+		fp->p0, fp->p1, fp->p2, fp->p3);
+	printk("P4: %08lx    P5: %08lx    FP: %08lx\n",
+		fp->p4, fp->p5, fp->fp);
+	printk("A0.w: %08lx    A0.x: %08lx    A1.w: %08lx    A1.x: %08lx\n",
+		fp->a0w, fp->a0x, fp->a1w, fp->a1x);
+
+	printk("\nUSP: %08lx   ASTAT: %08lx\n",
+		rdusp(), fp->astat);
+
+	printk("\n\n");
+}
diff -urN linux-2.4.29/arch/blackfin/platform/535/ADI/bootlogo.h linux-2.4.29-uc1/arch/blackfin/platform/535/ADI/bootlogo.h
--- linux-2.4.29/arch/blackfin/platform/535/ADI/bootlogo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/ADI/bootlogo.h	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,270 @@
+#define bootlogo_width 160
+#define bootlogo_height 160
+static unsigned char bootlogo_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x55,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x08, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00,
+  0x00, 0xff, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0xf8, 0x80, 0x0f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x50, 0x04, 0x00, 0x00, 0x00, 0x78, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x03, 0x00, 0x00,
+  0x00, 0x78, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x40,
+  0xa8, 0x02, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x70, 0x28, 0x01, 0x00, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x20, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x70,
+  0x54, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x80, 0x01, 0x3a, 0x78, 0x80, 0x0e,
+  0x50, 0xc0, 0x03, 0x0e, 0x00, 0x20, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00,
+  0x00, 0x3e, 0xf0, 0x83, 0x1f, 0xfc, 0xe0, 0x0f, 0x78, 0xf8, 0x87, 0x1f,
+  0x00, 0x18, 0x00, 0x30, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xf8, 0xc3,
+  0x1f, 0xfc, 0xe0, 0x0f, 0x78, 0xf8, 0x87, 0x0f, 0x00, 0x20, 0x00, 0x10,
+  0x55, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xc0, 0x03, 0x9f, 0xf3, 0x80, 0x0f,
+  0x78, 0x80, 0xc7, 0x0e, 0x00, 0x18, 0x00, 0x20, 0xaa, 0x00, 0x00, 0x00,
+  0x00, 0x1e, 0xe0, 0x03, 0x9f, 0xf1, 0x80, 0x07, 0x78, 0x80, 0x67, 0x00,
+  0x00, 0x24, 0x00, 0x18, 0x55, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x01,
+  0x5e, 0xf0, 0x80, 0x07, 0x3c, 0x00, 0x2f, 0x00, 0x00, 0x14, 0x00, 0x20,
+  0xaa, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x01, 0x7f, 0xf0, 0x80, 0x07,
+  0x3c, 0x00, 0x3f, 0x00, 0x00, 0x08, 0x00, 0x18, 0x55, 0x00, 0x00, 0x00,
+  0x00, 0x0f, 0xe0, 0x00, 0x3f, 0xf0, 0xc0, 0x03, 0x1e, 0x00, 0x1f, 0x00,
+  0x00, 0x14, 0x00, 0x28, 0xaa, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xf0, 0x00,
+  0x1f, 0xf0, 0xc0, 0x03, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x04, 0x00, 0x0c,
+  0x54, 0x00, 0x00, 0x00, 0x80, 0x07, 0x78, 0x00, 0x1f, 0x78, 0xc0, 0x03,
+  0x1f, 0x00, 0x1e, 0x00, 0x00, 0x0a, 0x00, 0x12, 0xa8, 0x00, 0x00, 0x00,
+  0x80, 0x07, 0x78, 0x00, 0x1f, 0x78, 0xe0, 0x03, 0x1f, 0x00, 0x1f, 0x00,
+  0x00, 0x04, 0x00, 0x0a, 0x54, 0x00, 0x00, 0x00, 0x80, 0x07, 0x78, 0x80,
+  0x0f, 0x78, 0xe0, 0x03, 0x1f, 0x00, 0x1e, 0x00, 0x00, 0x0a, 0x00, 0x08,
+  0x50, 0x01, 0x00, 0x00, 0x84, 0x03, 0x78, 0x80, 0x07, 0x3c, 0xe0, 0xc1,
+  0x0f, 0x00, 0x1f, 0x00, 0x00, 0x04, 0x00, 0x06, 0xa8, 0x00, 0x00, 0x00,
+  0xc0, 0x03, 0x78, 0xc0, 0x07, 0x3c, 0xe0, 0xc1, 0x0f, 0x00, 0x1f, 0x00,
+  0x00, 0x0a, 0x00, 0x08, 0x50, 0x01, 0x00, 0x00, 0xc2, 0x01, 0x38, 0xc0,
+  0x07, 0x3c, 0xe0, 0x60, 0x0f, 0x80, 0x1e, 0x00, 0x00, 0x05, 0x00, 0x07,
+  0xa0, 0x00, 0x00, 0x80, 0xe0, 0x01, 0x3c, 0xc0, 0x07, 0x3c, 0xf0, 0xa0,
+  0x07, 0xc0, 0x1c, 0x00, 0x00, 0x0a, 0x80, 0x08, 0xa0, 0x02, 0x00, 0xa0,
+  0xe0, 0x21, 0x1c, 0xc0, 0x03, 0x1c, 0x71, 0x90, 0x47, 0x40, 0x3c, 0x04,
+  0x00, 0x05, 0x80, 0x06, 0xa0, 0x02, 0x00, 0x20, 0xe0, 0x31, 0x1e, 0xc3,
+  0x03, 0x1e, 0x79, 0x98, 0x47, 0x60, 0x38, 0x04, 0x00, 0x15, 0x40, 0x0a,
+  0xa0, 0x0a, 0x00, 0x1a, 0xe0, 0x19, 0x9e, 0xe1, 0x01, 0x9e, 0x78, 0xcc,
+  0xa7, 0x32, 0x78, 0x02, 0x80, 0x2a, 0x40, 0x05, 0x80, 0x2a, 0x00, 0x05,
+  0xe0, 0x0d, 0x9e, 0xe0, 0x01, 0xde, 0x78, 0xc6, 0x97, 0x1b, 0x78, 0x03,
+  0x80, 0x52, 0x30, 0x0a, 0x00, 0x95, 0xd2, 0x0a, 0xe0, 0x0f, 0xfe, 0xe0,
+  0x00, 0x7e, 0xf8, 0x87, 0x9f, 0x0f, 0xf8, 0x01, 0x00, 0xa1, 0x0e, 0x15,
+  0x80, 0x55, 0x55, 0x01, 0xe0, 0x01, 0x3c, 0xf0, 0x00, 0x3c, 0xf0, 0x80,
+  0x8f, 0x0f, 0x70, 0x00, 0x00, 0x81, 0x02, 0x14, 0x00, 0x54, 0x55, 0x00,
+  0xc0, 0x01, 0x3c, 0x00, 0x00, 0x0c, 0x60, 0x00, 0x07, 0x03, 0x70, 0x00,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x01, 0x00, 0x11, 0x09, 0x00, 0x04, 0x00, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+  0x00, 0x20, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x49, 0x32, 0x49, 0x49, 0x91,
+  0x24, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x20, 0x49, 0x0a, 0x09, 0xc9, 0x92, 0x14, 0x81, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x49,
+  0x18, 0x01, 0x49, 0x92, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x49, 0x30, 0x01, 0x49, 0x92,
+  0x14, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x08, 0x69, 0x22, 0x09, 0x49, 0xd2, 0x24, 0x24, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x51,
+  0x1a, 0x09, 0x49, 0xa2, 0x44, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x87, 0x08, 0x00, 0x00, 0x00,
+  0xf2, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0xf0, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x88, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09,
+  0x09, 0x01, 0x10, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x24, 0x80,
+  0x88, 0x86, 0x48, 0x04, 0x09, 0x08, 0x01, 0x01, 0x09, 0x01, 0x10, 0x71,
+  0x88, 0x66, 0x00, 0x00, 0x00, 0x40, 0x24, 0x80, 0x88, 0x89, 0x48, 0x84,
+  0x08, 0x08, 0x01, 0x01, 0x09, 0x01, 0x10, 0x89, 0x88, 0x99, 0x00, 0x00,
+  0x00, 0x40, 0x24, 0x80, 0x88, 0x88, 0x88, 0x82, 0xf8, 0xf0, 0xe0, 0x80,
+  0xf0, 0xf8, 0x13, 0x81, 0x88, 0x88, 0x00, 0x00, 0x00, 0x40, 0x24, 0x80,
+  0x88, 0x88, 0x08, 0x81, 0x08, 0x09, 0x01, 0x41, 0x08, 0x01, 0xf0, 0xf0,
+  0x88, 0x88, 0x00, 0x00, 0x00, 0x40, 0x24, 0x80, 0x88, 0x88, 0x88, 0x42,
+  0x08, 0x09, 0x01, 0x21, 0x08, 0x01, 0x10, 0x88, 0x88, 0x88, 0x00, 0x00,
+  0x00, 0x40, 0x46, 0x88, 0x88, 0x88, 0x4c, 0x44, 0x08, 0x09, 0x09, 0x11,
+  0x08, 0x01, 0x10, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x80, 0x85, 0x87,
+  0x88, 0x08, 0x4b, 0x24, 0xf0, 0xf0, 0xf0, 0xf8, 0xf1, 0x00, 0x10, 0x70,
+  0x89, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x3f, 0x0f, 0x00, 0x00, 0x08, 0x02, 0x04, 0x00,
+  0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0x1f, 0x00, 0x00, 0x48, 0x62, 0xc4, 0x31, 0x4a, 0x18, 0x3c, 0x03,
+  0x21, 0x45, 0x92, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x1f, 0x00, 0x00,
+  0x48, 0x92, 0x24, 0x48, 0xb6, 0x24, 0x88, 0x04, 0x21, 0x4b, 0x92, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xa8, 0xf2, 0x24, 0x48,
+  0x92, 0x3c, 0x88, 0x04, 0x21, 0x49, 0x62, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x10, 0x11, 0x24, 0x48, 0x92, 0x04, 0x88, 0x04,
+  0x21, 0x49, 0x62, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x3f, 0x00, 0x00,
+  0x10, 0x11, 0x24, 0x48, 0x92, 0x04, 0x88, 0x04, 0x21, 0x49, 0x93, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0xcf, 0x7e, 0x00, 0x00, 0x10, 0xe1, 0xc4, 0x31,
+  0x92, 0x38, 0x30, 0x03, 0x2f, 0x89, 0x92, 0x00, 0x00, 0x00, 0x80, 0xe3,
+  0x07, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc1, 0x03, 0x7e, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0xc9, 0x23, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x95,
+  0x33, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xdd, 0xfb, 0x7e, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x1d, 0xf8, 0x7e, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x40, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9b,
+  0x70, 0x7e, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x00, 0x02, 0x00, 0x47, 0x80,
+  0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x80, 0x03, 0x00, 0x7e, 0x00, 0x00,
+  0x3c, 0xa3, 0x20, 0x31, 0x52, 0x02, 0x49, 0xcc, 0x3f, 0xa3, 0x94, 0x08,
+  0x00, 0x00, 0x00, 0x27, 0x02, 0x7e, 0x00, 0x00, 0x88, 0xe4, 0x20, 0x41,
+  0xb2, 0x05, 0x49, 0x90, 0x88, 0xe4, 0x6c, 0x09, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x7e, 0x00, 0x00, 0x88, 0x24, 0xe0, 0x70, 0x92, 0x04, 0x47, 0x9c,
+  0x88, 0x24, 0x24, 0x09, 0x00, 0x00, 0x00, 0x13, 0x48, 0x7e, 0x00, 0x00,
+  0x88, 0x24, 0x20, 0x48, 0x92, 0x04, 0x41, 0x92, 0x88, 0x24, 0x24, 0x01,
+  0x00, 0x00, 0x00, 0x43, 0x00, 0xfe, 0x00, 0x00, 0x88, 0x24, 0x20, 0x48,
+  0x92, 0x04, 0x41, 0x92, 0x88, 0x24, 0x24, 0x09, 0x00, 0x00, 0x00, 0x07,
+  0x94, 0xce, 0x00, 0x00, 0x08, 0x23, 0x20, 0xb0, 0x92, 0x04, 0x41, 0x2c,
+  0x0b, 0x23, 0x24, 0x09, 0x00, 0x00, 0x00, 0x49, 0x02, 0xce, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x11, 0x08, 0xdc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+  0x01, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0xf8, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x01, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01,
+  0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xf0, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x70, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00,
+  0x00, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0xe0, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x3c, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00,
+  0x00, 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xc0, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x1f, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00,
+  0x00, 0x80, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00,
+  0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0xfe, 0x0f,
+  0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x08, 0x00,
+  0x00, 0xc0, 0x03, 0x00, 0x78, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x40, 0x10,
+  0x12, 0x10, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
+  0x84, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x20, 0x26, 0x0a, 0x10, 0x9d, 0x39,
+  0xa6, 0xb2, 0x0a, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x02, 0x00, 0xfe, 0x0f,
+  0x00, 0x00, 0x20, 0x21, 0x06, 0x28, 0x25, 0x4a, 0xa9, 0x8a, 0x09, 0x00,
+  0x00, 0xe0, 0x01, 0x22, 0x02, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x20, 0x21,
+  0x0e, 0x38, 0xa5, 0x4b, 0xa9, 0xb2, 0x09, 0x00, 0x00, 0xf0, 0x01, 0x22,
+  0x02, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x20, 0x21, 0x12, 0x44, 0xa5, 0x4a,
+  0x49, 0xa1, 0x0a, 0x00, 0x00, 0xf8, 0x01, 0x22, 0x02, 0x00, 0xfc, 0x1f,
+  0x00, 0x00, 0x20, 0x26, 0x52, 0x44, 0x9d, 0x4d, 0x46, 0x99, 0x0a, 0x00,
+  0x00, 0xfc, 0x01, 0x22, 0x02, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x40, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0xb2,
+  0x84, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x01, 0x6e, 0x78, 0x00, 0xfc, 0x1f,
+  0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xfc, 0x01, 0x02, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x02,
+  0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0xfc, 0x0f,
+  0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x20, 0x01, 0x02, 0x00, 0x00, 0x00,
+  0x00, 0x24, 0x06, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x40, 0x10,
+  0x1e, 0x20, 0x90, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
+  0x00, 0x80, 0xfc, 0x03, 0x00, 0x00, 0x20, 0x26, 0x22, 0x20, 0xf9, 0x89,
+  0x32, 0xe7, 0x08, 0x00, 0x00, 0x92, 0x38, 0x00, 0x00, 0x00, 0xfc, 0x01,
+  0x00, 0x00, 0x20, 0x21, 0x22, 0xa0, 0x92, 0x88, 0x4a, 0x29, 0x15, 0x00,
+  0x00, 0x00, 0x78, 0x00, 0x00, 0x40, 0xfa, 0x04, 0x00, 0x00, 0x20, 0x21,
+  0x22, 0xa0, 0x93, 0x88, 0x4a, 0x29, 0x1d, 0x00, 0x00, 0x11, 0xf2, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x20, 0x21, 0x22, 0xa8, 0x90, 0x88,
+  0x4a, 0x29, 0x05, 0x00, 0x48, 0x40, 0xf0, 0x01, 0x00, 0x80, 0x14, 0x04,
+  0x00, 0x00, 0x20, 0x26, 0x9e, 0x10, 0x93, 0x78, 0x32, 0x29, 0x19, 0x00,
+  0x00, 0x09, 0xe0, 0x03, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x40, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xc5, 0x03,
+  0x00, 0x40, 0x22, 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0xc0, 0x07, 0x00, 0x20, 0x08, 0x04,
+  0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x50, 0x90, 0x03, 0x00, 0xb0, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
+  0x00, 0x38, 0x22, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x48, 0x04, 0x44, 0x00, 0x00, 0x3c, 0x08, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x20, 0x00, 0x00, 0x00, 0xbf, 0x40, 0x42, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x24, 0x80, 0x48, 0x02,
+  0xc0, 0x1f, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x05, 0xf0, 0x3f, 0x09, 0x00,
+  0x00, 0x10, 0x24, 0x48, 0x10, 0x12, 0x41, 0x52, 0x24, 0x09, 0x46, 0x71,
+  0x90, 0x20, 0x02, 0xfc, 0xff, 0x1f, 0x80, 0x22, 0x00, 0x90, 0x24, 0x49,
+  0x12, 0x92, 0x40, 0xb2, 0x24, 0x09, 0xc9, 0x49, 0x04, 0x80, 0x90, 0xfc,
+  0xff, 0xbf, 0x24, 0x00, 0x00, 0x90, 0x24, 0x49, 0x12, 0x92, 0x40, 0x92,
+  0x24, 0x06, 0x49, 0x48, 0x50, 0x0a, 0x02, 0xfe, 0xff, 0x3f, 0x00, 0x05,
+  0x00, 0x50, 0xa5, 0x4a, 0x15, 0x92, 0x40, 0x92, 0x24, 0x06, 0x49, 0x48,
+  0x80, 0x40, 0x48, 0xfe, 0xff, 0x3f, 0x49, 0x00, 0x00, 0x20, 0x42, 0x84,
+  0x88, 0x1a, 0x41, 0x92, 0x34, 0x49, 0x49, 0x68, 0x00, 0x38, 0x10, 0x07,
+  0x00, 0x60, 0x80, 0x00, 0x00, 0x20, 0x42, 0x84, 0x88, 0x14, 0x4e, 0x92,
+  0x28, 0x49, 0x46, 0x50, 0x00, 0x80, 0x83, 0x01, 0x00, 0xa0, 0x6a, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+  0x00, 0x00, 0xfc, 0x00, 0x00, 0xc0, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, };
diff -urN linux-2.4.29/arch/blackfin/platform/535/ADI/bootlogo.rh linux-2.4.29-uc1/arch/blackfin/platform/535/ADI/bootlogo.rh
--- linux-2.4.29/arch/blackfin/platform/535/ADI/bootlogo.rh	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/ADI/bootlogo.rh	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,270 @@
+#define bootlogo_width 160
+#define bootlogo_height 160
+
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x80, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x02, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xaa
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x01, 0x10, 0x00, 0x00, 0x00, 0x7e, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00
+	.byte  0x00, 0xff, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x1f, 0x01, 0xf0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x0a, 0x20, 0x00, 0x00, 0x00, 0x1e, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xc0, 0x00, 0x00
+	.byte  0x00, 0x1e, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x02
+	.byte  0x15, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0e, 0x14, 0x80, 0x00, 0x00
+	.byte  0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x04, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0e
+	.byte  0x2a, 0x80, 0x00, 0x00, 0x00, 0x7c, 0x01, 0x80, 0x5c, 0x1e, 0x01, 0x70
+	.byte  0x0a, 0x03, 0xc0, 0x70, 0x00, 0x04, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00
+	.byte  0x00, 0x7c, 0x0f, 0xc1, 0xf8, 0x3f, 0x07, 0xf0, 0x1e, 0x1f, 0xe1, 0xf8
+	.byte  0x00, 0x18, 0x00, 0x0c, 0x55, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1f, 0xc3
+	.byte  0xf8, 0x3f, 0x07, 0xf0, 0x1e, 0x1f, 0xe1, 0xf0, 0x00, 0x04, 0x00, 0x08
+	.byte  0xaa, 0x00, 0x00, 0x00, 0x00, 0x78, 0x03, 0xc0, 0xf9, 0xcf, 0x01, 0xf0
+	.byte  0x1e, 0x01, 0xe3, 0x70, 0x00, 0x18, 0x00, 0x04, 0x55, 0x00, 0x00, 0x00
+	.byte  0x00, 0x78, 0x07, 0xc0, 0xf9, 0x8f, 0x01, 0xe0, 0x1e, 0x01, 0xe6, 0x00
+	.byte  0x00, 0x24, 0x00, 0x18, 0xaa, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0x80
+	.byte  0x7a, 0x0f, 0x01, 0xe0, 0x3c, 0x00, 0xf4, 0x00, 0x00, 0x28, 0x00, 0x04
+	.byte  0x55, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0x80, 0xfe, 0x0f, 0x01, 0xe0
+	.byte  0x3c, 0x00, 0xfc, 0x00, 0x00, 0x10, 0x00, 0x18, 0xaa, 0x00, 0x00, 0x00
+	.byte  0x00, 0xf0, 0x07, 0x00, 0xfc, 0x0f, 0x03, 0xc0, 0x78, 0x00, 0xf8, 0x00
+	.byte  0x00, 0x28, 0x00, 0x14, 0x55, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x0f, 0x00
+	.byte  0xf8, 0x0f, 0x03, 0xc0, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x20, 0x00, 0x30
+	.byte  0x2a, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x1e, 0x00, 0xf8, 0x1e, 0x03, 0xc0
+	.byte  0xf8, 0x00, 0x78, 0x00, 0x00, 0x50, 0x00, 0x48, 0x15, 0x00, 0x00, 0x00
+	.byte  0x01, 0xe0, 0x1e, 0x00, 0xf8, 0x1e, 0x07, 0xc0, 0xf8, 0x00, 0xf8, 0x00
+	.byte  0x00, 0x20, 0x00, 0x50, 0x2a, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x1e, 0x01
+	.byte  0xf0, 0x1e, 0x07, 0xc0, 0xf8, 0x00, 0x78, 0x00, 0x00, 0x50, 0x00, 0x10
+	.byte  0x0a, 0x80, 0x00, 0x00, 0x21, 0xc0, 0x1e, 0x01, 0xe0, 0x3c, 0x07, 0x83
+	.byte  0xf0, 0x00, 0xf8, 0x00, 0x00, 0x20, 0x00, 0x60, 0x15, 0x00, 0x00, 0x00
+	.byte  0x03, 0xc0, 0x1e, 0x03, 0xe0, 0x3c, 0x07, 0x83, 0xf0, 0x00, 0xf8, 0x00
+	.byte  0x00, 0x50, 0x00, 0x10, 0x0a, 0x80, 0x00, 0x00, 0x43, 0x80, 0x1c, 0x03
+	.byte  0xe0, 0x3c, 0x07, 0x06, 0xf0, 0x01, 0x78, 0x00, 0x00, 0xa0, 0x00, 0xe0
+	.byte  0x05, 0x00, 0x00, 0x01, 0x07, 0x80, 0x3c, 0x03, 0xe0, 0x3c, 0x0f, 0x05
+	.byte  0xe0, 0x03, 0x38, 0x00, 0x00, 0x50, 0x01, 0x10, 0x05, 0x40, 0x00, 0x05
+	.byte  0x07, 0x84, 0x38, 0x03, 0xc0, 0x38, 0x8e, 0x09, 0xe2, 0x02, 0x3c, 0x20
+	.byte  0x00, 0xa0, 0x01, 0x60, 0x05, 0x40, 0x00, 0x04, 0x07, 0x8c, 0x78, 0xc3
+	.byte  0xc0, 0x78, 0x9e, 0x19, 0xe2, 0x06, 0x1c, 0x20, 0x00, 0xa8, 0x02, 0x50
+	.byte  0x05, 0x50, 0x00, 0x58, 0x07, 0x98, 0x79, 0x87, 0x80, 0x79, 0x1e, 0x33
+	.byte  0xe5, 0x4c, 0x1e, 0x40, 0x01, 0x54, 0x02, 0xa0, 0x01, 0x54, 0x00, 0xa0
+	.byte  0x07, 0xb0, 0x79, 0x07, 0x80, 0x7b, 0x1e, 0x63, 0xe9, 0xd8, 0x1e, 0xc0
+	.byte  0x01, 0x4a, 0x0c, 0x50, 0x00, 0xa9, 0x4b, 0x50, 0x07, 0xf0, 0x7f, 0x07
+	.byte  0x00, 0x7e, 0x1f, 0xe1, 0xf9, 0xf0, 0x1f, 0x80, 0x00, 0x85, 0x70, 0xa8
+	.byte  0x01, 0xaa, 0xaa, 0x80, 0x07, 0x80, 0x3c, 0x0f, 0x00, 0x3c, 0x0f, 0x01
+	.byte  0xf1, 0xf0, 0x0e, 0x00, 0x00, 0x81, 0x40, 0x28, 0x00, 0x2a, 0xaa, 0x00
+	.byte  0x03, 0x80, 0x3c, 0x00, 0x00, 0x30, 0x06, 0x00, 0xe0, 0xc0, 0x0e, 0x00
+	.byte  0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x02, 0x80, 0x00, 0x88, 0x90, 0x00, 0x20, 0x00, 0x80, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00
+	.byte  0x00, 0x04, 0x80, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x92, 0x4c, 0x92, 0x92, 0x89
+	.byte  0x24, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x04, 0x92, 0x50, 0x90, 0x93, 0x49, 0x28, 0x81, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x92
+	.byte  0x18, 0x80, 0x92, 0x49, 0x30, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x92, 0x0c, 0x80, 0x92, 0x49
+	.byte  0x28, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x10, 0x96, 0x44, 0x90, 0x92, 0x4b, 0x24, 0x24, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x8a
+	.byte  0x58, 0x90, 0x92, 0x45, 0x22, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+	.byte  0x10, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe1, 0x10, 0x00, 0x00, 0x00
+	.byte  0x4f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x02, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, 0x90
+	.byte  0x90, 0x80, 0x08, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x24, 0x01
+	.byte  0x11, 0x61, 0x12, 0x20, 0x90, 0x10, 0x80, 0x80, 0x90, 0x80, 0x08, 0x8e
+	.byte  0x11, 0x66, 0x00, 0x00, 0x00, 0x02, 0x24, 0x01, 0x11, 0x91, 0x12, 0x21
+	.byte  0x10, 0x10, 0x80, 0x80, 0x90, 0x80, 0x08, 0x91, 0x11, 0x99, 0x00, 0x00
+	.byte  0x00, 0x02, 0x24, 0x01, 0x11, 0x11, 0x11, 0x41, 0x1f, 0x0f, 0x07, 0x01
+	.byte  0x0f, 0x1f, 0xc8, 0x81, 0x11, 0x11, 0x00, 0x00, 0x00, 0x02, 0x24, 0x01
+	.byte  0x11, 0x11, 0x10, 0x81, 0x10, 0x90, 0x80, 0x82, 0x10, 0x80, 0x0f, 0x0f
+	.byte  0x11, 0x11, 0x00, 0x00, 0x00, 0x02, 0x24, 0x01, 0x11, 0x11, 0x11, 0x42
+	.byte  0x10, 0x90, 0x80, 0x84, 0x10, 0x80, 0x08, 0x11, 0x11, 0x11, 0x00, 0x00
+	.byte  0x00, 0x02, 0x62, 0x11, 0x11, 0x11, 0x32, 0x22, 0x10, 0x90, 0x90, 0x88
+	.byte  0x10, 0x80, 0x08, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x01, 0xa1, 0xe1
+	.byte  0x11, 0x10, 0xd2, 0x24, 0x0f, 0x0f, 0x0f, 0x1f, 0x8f, 0x00, 0x08, 0x0e
+	.byte  0x91, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f
+	.byte  0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xfc, 0xf0, 0x00, 0x00, 0x10, 0x40, 0x20, 0x00
+	.byte  0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0xff, 0xf8, 0x00, 0x00, 0x12, 0x46, 0x23, 0x8c, 0x52, 0x18, 0x3c, 0xc0
+	.byte  0x84, 0xa2, 0x49, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xf8, 0x00, 0x00
+	.byte  0x12, 0x49, 0x24, 0x12, 0x6d, 0x24, 0x11, 0x20, 0x84, 0xd2, 0x49, 0x00
+	.byte  0x00, 0x00, 0x01, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x15, 0x4f, 0x24, 0x12
+	.byte  0x49, 0x3c, 0x11, 0x20, 0x84, 0x92, 0x46, 0x00, 0x00, 0x00, 0x01, 0xff
+	.byte  0xff, 0xfc, 0x00, 0x00, 0x08, 0x88, 0x24, 0x12, 0x49, 0x20, 0x11, 0x20
+	.byte  0x84, 0x92, 0x46, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xfc, 0x00, 0x00
+	.byte  0x08, 0x88, 0x24, 0x12, 0x49, 0x20, 0x11, 0x20, 0x84, 0x92, 0xc9, 0x00
+	.byte  0x00, 0x00, 0x01, 0xff, 0xf3, 0x7e, 0x00, 0x00, 0x08, 0x87, 0x23, 0x8c
+	.byte  0x49, 0x1c, 0x0c, 0xc0, 0xf4, 0x91, 0x49, 0x00, 0x00, 0x00, 0x01, 0xc7
+	.byte  0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x83, 0xc0, 0x7e, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x01, 0x93, 0xc4, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xa9
+	.byte  0xcc, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xbb, 0xdf, 0x7e, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x01, 0xb8, 0x1f, 0x7e, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00
+	.byte  0x40, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xd9
+	.byte  0x0e, 0x7e, 0x00, 0x00, 0x10, 0x00, 0x07, 0x00, 0x40, 0x00, 0xe2, 0x01
+	.byte  0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x7e, 0x00, 0x00
+	.byte  0x3c, 0xc5, 0x04, 0x8c, 0x4a, 0x40, 0x92, 0x33, 0xfc, 0xc5, 0x29, 0x10
+	.byte  0x00, 0x00, 0x00, 0xe4, 0x40, 0x7e, 0x00, 0x00, 0x11, 0x27, 0x04, 0x82
+	.byte  0x4d, 0xa0, 0x92, 0x09, 0x11, 0x27, 0x36, 0x90, 0x00, 0x00, 0x00, 0x80
+	.byte  0x00, 0x7e, 0x00, 0x00, 0x11, 0x24, 0x07, 0x0e, 0x49, 0x20, 0xe2, 0x39
+	.byte  0x11, 0x24, 0x24, 0x90, 0x00, 0x00, 0x00, 0xc8, 0x12, 0x7e, 0x00, 0x00
+	.byte  0x11, 0x24, 0x04, 0x12, 0x49, 0x20, 0x82, 0x49, 0x11, 0x24, 0x24, 0x80
+	.byte  0x00, 0x00, 0x00, 0xc2, 0x00, 0x7f, 0x00, 0x00, 0x11, 0x24, 0x04, 0x12
+	.byte  0x49, 0x20, 0x82, 0x49, 0x11, 0x24, 0x24, 0x90, 0x00, 0x00, 0x00, 0xe0
+	.byte  0x29, 0x73, 0x00, 0x00, 0x10, 0xc4, 0x04, 0x0d, 0x49, 0x20, 0x82, 0x34
+	.byte  0xd0, 0xc4, 0x24, 0x90, 0x00, 0x00, 0x00, 0x92, 0x40, 0x73, 0x80, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x88, 0x10, 0x3b, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82
+	.byte  0x80, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x1f, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x03, 0x80, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80
+	.byte  0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x0f, 0xf8, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x0e, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00
+	.byte  0x00, 0x07, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x07, 0xfe, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x3c, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00
+	.byte  0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x03, 0xff, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0xf8, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00
+	.byte  0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xe0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x7f, 0xf0
+	.byte  0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x01, 0x10, 0x00
+	.byte  0x00, 0x03, 0xc0, 0x00, 0x1e, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x02, 0x08
+	.byte  0x48, 0x08, 0xa0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00
+	.byte  0x21, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x04, 0x64, 0x50, 0x08, 0xb9, 0x9c
+	.byte  0x65, 0x4d, 0x50, 0x00, 0x00, 0x07, 0x80, 0x00, 0x40, 0x00, 0x7f, 0xf0
+	.byte  0x00, 0x00, 0x04, 0x84, 0x60, 0x14, 0xa4, 0x52, 0x95, 0x51, 0x90, 0x00
+	.byte  0x00, 0x07, 0x80, 0x44, 0x40, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x04, 0x84
+	.byte  0x70, 0x1c, 0xa5, 0xd2, 0x95, 0x4d, 0x90, 0x00, 0x00, 0x0f, 0x80, 0x44
+	.byte  0x40, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x04, 0x84, 0x48, 0x22, 0xa5, 0x52
+	.byte  0x92, 0x85, 0x50, 0x00, 0x00, 0x1f, 0x80, 0x44, 0x40, 0x00, 0x3f, 0xf8
+	.byte  0x00, 0x00, 0x04, 0x64, 0x4a, 0x22, 0xb9, 0xb2, 0x62, 0x99, 0x50, 0x00
+	.byte  0x00, 0x3f, 0x80, 0x44, 0x40, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x02, 0x08
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x4d
+	.byte  0x21, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x80, 0x76, 0x1e, 0x00, 0x3f, 0xf8
+	.byte  0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x3f, 0x80, 0x40, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x80, 0x40
+	.byte  0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x00, 0x00, 0x3f, 0xf0
+	.byte  0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x04, 0x80, 0x40, 0x00, 0x00, 0x00
+	.byte  0x00, 0x24, 0x60, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x02, 0x08
+	.byte  0x78, 0x04, 0x09, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00
+	.byte  0x00, 0x01, 0x3f, 0xc0, 0x00, 0x00, 0x04, 0x64, 0x44, 0x04, 0x9f, 0x91
+	.byte  0x4c, 0xe7, 0x10, 0x00, 0x00, 0x49, 0x1c, 0x00, 0x00, 0x00, 0x3f, 0x80
+	.byte  0x00, 0x00, 0x04, 0x84, 0x44, 0x05, 0x49, 0x11, 0x52, 0x94, 0xa8, 0x00
+	.byte  0x00, 0x00, 0x1e, 0x00, 0x00, 0x02, 0x5f, 0x20, 0x00, 0x00, 0x04, 0x84
+	.byte  0x44, 0x05, 0xc9, 0x11, 0x52, 0x94, 0xb8, 0x00, 0x00, 0x88, 0x4f, 0x00
+	.byte  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x84, 0x44, 0x15, 0x09, 0x11
+	.byte  0x52, 0x94, 0xa0, 0x00, 0x12, 0x02, 0x0f, 0x80, 0x00, 0x01, 0x28, 0x20
+	.byte  0x00, 0x00, 0x04, 0x64, 0x79, 0x08, 0xc9, 0x1e, 0x4c, 0x94, 0x98, 0x00
+	.byte  0x00, 0x90, 0x07, 0xc0, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xa3, 0xc0
+	.byte  0x00, 0x02, 0x44, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x03, 0xe0, 0x00, 0x04, 0x10, 0x20
+	.byte  0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x10, 0x0a, 0x09, 0xc0, 0x00, 0x0d, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00
+	.byte  0x00, 0x1c, 0x44, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x22, 0x00, 0x00, 0x3c, 0x10, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x04, 0x00, 0x00, 0x00, 0xfd, 0x02, 0x42, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x24, 0x01, 0x12, 0x40
+	.byte  0x03, 0xf8, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0xa0, 0x0f, 0xfc, 0x90, 0x00
+	.byte  0x00, 0x08, 0x24, 0x12, 0x08, 0x48, 0x82, 0x4a, 0x24, 0x90, 0x62, 0x8e
+	.byte  0x09, 0x04, 0x40, 0x3f, 0xff, 0xf8, 0x01, 0x44, 0x00, 0x09, 0x24, 0x92
+	.byte  0x48, 0x49, 0x02, 0x4d, 0x24, 0x90, 0x93, 0x92, 0x20, 0x01, 0x09, 0x3f
+	.byte  0xff, 0xfd, 0x24, 0x00, 0x00, 0x09, 0x24, 0x92, 0x48, 0x49, 0x02, 0x49
+	.byte  0x24, 0x60, 0x92, 0x12, 0x0a, 0x50, 0x40, 0x7f, 0xff, 0xfc, 0x00, 0xa0
+	.byte  0x00, 0x0a, 0xa5, 0x52, 0xa8, 0x49, 0x02, 0x49, 0x24, 0x60, 0x92, 0x12
+	.byte  0x01, 0x02, 0x12, 0x7f, 0xff, 0xfc, 0x92, 0x00, 0x00, 0x04, 0x42, 0x21
+	.byte  0x11, 0x58, 0x82, 0x49, 0x2c, 0x92, 0x92, 0x16, 0x00, 0x1c, 0x08, 0xe0
+	.byte  0x00, 0x06, 0x01, 0x00, 0x00, 0x04, 0x42, 0x21, 0x11, 0x28, 0x72, 0x49
+	.byte  0x14, 0x92, 0x62, 0x0a, 0x00, 0x01, 0xc1, 0x80, 0x00, 0x05, 0x56, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02
+	.byte  0x00, 0x00, 0x3f, 0x00, 0x00, 0x03, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 
diff -urN linux-2.4.29/arch/blackfin/platform/535/ADI/crt0_ram.S linux-2.4.29-uc1/arch/blackfin/platform/535/ADI/crt0_ram.S
--- linux-2.4.29/arch/blackfin/platform/535/ADI/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/ADI/crt0_ram.S	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,154 @@
+/* linux/arch/frio/kernel/head.S:  A startup file for the Blackfin 
+ *
+ * Copyright (c) 2003  Metrowerks/Motorola
+ * Copyright (C) 1998  D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
+ *                     Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ * (c) 1995, Dionne & Associates
+ * (c) 1995, DKG Display Tech.
+ */
+
+#define ASSEMBLY
+
+#include <linux/config.h>
+
+.global _stext;
+.global __bss_start;
+
+.global start;
+.global _start;
+
+.global _rambase;
+.global __ramvec;
+.global _ramvec;
+.global _ramstart;
+.global _ramend;
+
+#define	MEM_BASE	0x00000000
+#define VBR_BASE	MEM_BASE
+#define MEM_SIZE	0x1000000
+
+/*********************************************************************/
+
+.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+.text
+	
+_start:
+start:
+_stext:
+
+	/*
+	 * It seems that the value of SP reg is unpredicable after reset.
+	 * We'd better set SP before using "reti" and "[--sp] = reti" 
+	 *
+	 * HuTao May26, 2003 3:02PM
+	 */
+	sp.h = 0xf000;	/* 0x1000(4KB) L1 RAM as system stack */
+	sp.l = 0x1000;
+
+	// This next section keeps the processor in supervisor mode
+        // during kernel boot.  Switches to user mode at end of boot.
+	// See page 3-9 of Hardware Reference manual for documentation.
+	p0.l = 0x203c
+	p0.h = 0xffe0;
+	p1.l = _real_start;
+	p1.h = _real_start;
+	[p0] = p1;
+
+	p0.l = 0x2104;
+	p0.h = 0xffe0;
+	p1.l = 0x8000;
+	p1.h = 0x0;
+	[p0] = p1;
+
+	raise 15;
+	p0.l = WAIT_HERE;
+	p0.h = WAIT_HERE;
+	reti = p0;
+	rti;
+	
+WAIT_HERE:
+	jump WAIT_HERE;
+
+.global _real_start;
+_real_start:
+	[ -- sp ] = reti;
+	p0.l = 0x1000;
+	p0.h = 0xFFC0;
+	r0 = 0xD6(z);
+	w[p0] = r0;	/* watchdog off for now */
+
+	/* Code update for BSS size == 0
+	 * Zero out the bss region.
+	 */
+	p1.l = _sbss;
+	p1.h = _sbss;
+	p2.l = _ebss;
+	p2.h = _ebss;
+	lsetup (_clear_bss, _clear_bss_end ) lc1 = p2 - p1;
+	CC = p2<=p1;
+	if CC jump _clear_bss_skip;
+	r0 = 0;
+_clear_bss:
+_clear_bss_end:
+	[p1++] = r0;
+_clear_bss_skip:	/* to skip bss clear */
+
+	p1.l = _rambase;
+	p1.h = _rambase;
+	r0.l = _sdata ;
+	r0.h = _sdata ;
+	[p1] = r0;
+
+	p1.l = _ramstart;
+	p1.h = _ramstart;
+	r0.l = _end;
+	r0.h = _end;
+	[p1] = r0;
+
+	r0.l = 0x0000;
+	r0.h = 0x100;	/* MEM_SIZE = 0x01000000 */
+	p1.l = _ramend;
+	p1.h = _ramend;
+	[p1] = r0;
+
+	/*
+	 *  load the current task pointer and stack
+	 */
+	r1.l = init_task_union;
+	r1.h = init_task_union;
+	p1.l = _current_task;
+	p1.h = _current_task;
+	[p1] = r1;
+
+/* Use kernel stack instead of an l1 stack. l1 stack might overflow.
+ * For this time being this should be sufficient.
+ */
+	r2 = 0x2000(z);
+	r1 = r1 + r2;
+	sp = r1;
+
+	call	start_kernel;
+_exit:
+
+	jump.s	_exit;
+
+	.data
+env:
+	.long	0;
diff -urN linux-2.4.29/arch/blackfin/platform/535/ADI/crt0_rom.S linux-2.4.29-uc1/arch/blackfin/platform/535/ADI/crt0_rom.S
--- linux-2.4.29/arch/blackfin/platform/535/ADI/crt0_rom.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/ADI/crt0_rom.S	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,109 @@
+/* linux/arch/m68knommu/kernel/head.S:  A startup file for the MC68332 
+ *
+ * Copyright (C) 1998  D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
+ *                     Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ * (c) 1995, Dionne & Associates
+ * (c) 1995, DKG Display Tech.
+ */
+
+#define ASSEMBLY
+
+
+#include <linux/config.h>
+
+.global _stext;
+.global __bss_start;
+
+.global start;
+.global _start;
+
+.global _rambase;
+.global __ramvec;
+.global _ramvec;
+.global _ramstart;
+.global _ramend;
+
+#define	MEM_BASE	0x00000000
+#define VBR_BASE	MEM_BASE
+#define MEM_SIZE	0x00400000
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+.text
+	
+_start:
+start:
+_stext:
+	r7 = cli;
+	sp.l = 0x0000;
+	sp.h = 0x0500;
+	usp = sp;
+
+	r0 = 0;		/* VBR_BASE */
+	p1.l = _ramvec;
+	p1.h = _ramvec;
+	[p1] = r0;
+	p1.l = _rambase;
+	p1.h = _rambase;
+	[p1] = r0;
+
+	r0.l = 0x0000;
+	r0.h = 0x0040;	/* MEM_SIZE = 0x00400000 */
+	p1.l = _ramend;
+	p1.h = _ramend;
+	[p1] = r0;
+
+#if 0
+	/*
+	 * Zero out the bss region.
+	 */
+	p1.l = _sbss;
+	p1.h = _sbss;
+	p2.l = _ebss;
+	p2.h = _ebss;
+	r0 = 0;
+_clear_bss:
+	[p1++] = r0;
+	CC = p1 == p2;
+	if !cc jump _clear_bss;
+#endif
+	/*
+	 *  load the current task pointer and stack
+	 */
+	p1.l = init_task_union;
+	p1.h = init_task_union;
+	p2.l = _current_task;
+	p2.h = _current_task;
+	[p2] = p1;
+	[p2 + 0x2000] = sp;
+
+	sti r7;
+	sp.l = 0x0000;
+	sp.h = 0x0500;
+	usp = sp;
+	call	start_kernel;
+_exit:
+
+	jump.s	_exit;
+
+	.data
+env:
+	.long	0;
diff -urN linux-2.4.29/arch/blackfin/platform/535/ADI/ram.ld linux-2.4.29-uc1/arch/blackfin/platform/535/ADI/ram.ld
--- linux-2.4.29/arch/blackfin/platform/535/ADI/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/ADI/ram.ld	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,128 @@
+OUTPUT_FORMAT("elf32-little-nisa")
+OUTPUT_ARCH(nisa)
+ENTRY(start)
+MEMORY 
+	{
+	ram		: ORIGIN = 0x1000,        LENGTH = 0x1000000
+	l2_sram		: ORIGIN = 0xF0000000, LENGTH = 0x40000
+	l1_data_a	: ORIGIN = 0xFF800000, LENGTH = 0x4000
+	l1_data_b	: ORIGIN = 0xFF900000, LENGTH = 0x4000
+	l1_code		: ORIGIN = 0xFFA00000, LENGTH = 0x4000
+	l1_scratch	: ORIGIN = 0xFFB00000, LENGTH = 0x1000
+	}
+
+SECTIONS
+{
+  . = 0x1000 ;
+  .text : {
+	  _text = .;                    /* Text and read-only data */
+	  text_start = . ;
+	  __text_start = . ;
+          *(.text)
+          *(.text.*)
+	  *($code)
+          *(.fixup)		
+          *(__ex_table)	
+	  . = ALIGN(4) ;
+	  _etext = . ;
+	  etext = . ;
+	} > ram
+  
+	
+  .data :
+	{
+	  _sdata = . ;
+	  __data_start = . ;
+
+	  . = ALIGN(0x2000) ;
+	  *(.data.init_task)
+	  . = ALIGN(0x2000) ;
+
+      *(.rodata)
+      *(.data)
+      *(.data.*)	
+      . = ALIGN(4096) ;
+      ramdisk_begin = .;
+      *(.ramdisk)
+      ramdisk_end = .;
+
+      *(.setup.init)		
+      *(.exitcall.exit)		
+	
+	  . = ALIGN(4096) ;
+	  __init_begin = .;
+	  *(.text.init)
+	  *(.data.init)
+	  . = ALIGN(16);
+	  __setup_start = .;
+	  *(.setup.init)
+	  __setup_end = .;
+	  __initcall_start = .;
+	  *(.initcall.init)
+	  . = ALIGN(4) ;
+	  __initcall_end = .;
+	  __init_end = .;
+
+	  _edata = . ;
+	  edata = . ;
+	} > ram
+
+  .bss :
+    {
+	  . = ALIGN(16) ;
+	  _sbss = . ;
+	  __bss_start = . ;
+	  __data_end = . ;
+	  *(.bss)
+	  *(COMMON)
+	  . = ALIGN(16) ;
+	  end = . ;
+	  _ebss = . ;	  
+	  _end = . ;
+    } > ram
+
+  . = 0x1000000;
+  .eram :
+    {
+	__ramend = . ;
+    } > ram
+
+
+
+
+
+
+  . = 0xF0000000 ;
+  .l2ram :
+    {
+	_l2_sram = . ;
+    } > l2_sram
+
+
+  . = 0xFF800000 ;
+  .l1data1 :
+    {
+	_l1_data_a = . ;
+    } > l1_data_a
+
+
+  . = 0xFF900000 ;
+  .l1data2 :
+    {
+	_l1_data_b = . ;
+    } > l1_data_b
+
+
+  . = 0xFFA00000 ;
+  .l1code :
+    {
+	_l1_code = . ;
+    } > l1_code
+
+  . = 0xFFB00000 ;
+  .l1scratch :
+    {
+	_l1_scratch = . ;
+    } > l1_scratch
+
+}
diff -urN linux-2.4.29/arch/blackfin/platform/535/ADI/rom.ld linux-2.4.29-uc1/arch/blackfin/platform/535/ADI/rom.ld
--- linux-2.4.29/arch/blackfin/platform/535/ADI/rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/ADI/rom.ld	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,99 @@
+OUTPUT_ARCH(nisa)
+ENTRY(_start)
+MEMORY 
+	{
+	romvec : ORIGIN = 0x10c00000, LENGTH = 0x10400
+	flash  : ORIGIN = 0x10c10400, LENGTH = 0xfec00
+	eflash : ORIGIN = 0x10d00000, LENGTH = 4
+	ramvec : ORIGIN = 0x00000000, LENGTH = 0x400
+	ram    : ORIGIN = 0x10000400, LENGTH = 0x100000-0x400
+	eram   : ORIGIN = 0x10100000, LENGTH = 4
+	}
+
+SECTIONS
+{
+  . = 0x10c00000 ;
+  .romvec : {
+	  _flashstart = . ;
+	  _romvec = . ;
+	} > romvec
+
+  . = 0x10c10400 ;
+  .text : {
+	  _text = .;                    /* Text and read-only data */
+	  text_start = . ;
+          *(.text)
+          *(.text.*)
+          *(.rodata)
+          *(.fixup)		
+          *(__ex_table)	
+	  . = ALIGN(4) ;
+	  _etext = . ;
+	  __data_rom_start = . ;
+	} > flash
+  
+  . = 0x10d00000 ;
+  .eflash :
+        {
+          _flashend = . ;
+        } > eflash
+	
+  . = 0 ;
+  .ramvec :
+	{
+	  __ramvec = . ;
+	} > ramvec
+	
+  /* . = 0x10000400 ; */
+  .data 0x10000400 :
+	{
+	  _sdata = . ;
+	  __data_start = . ;
+
+	  . = ALIGN(0x2000) ;
+	  *(.data.init_task)
+	  . = ALIGN(0x2000) ;
+
+      *(.data)
+      *(.data.*)	
+      *(.setup.init)		
+      *(.exitcall.exit)		
+	
+	  . = ALIGN(4096) ;
+	  __init_begin = .;
+	  *(.text.init)
+	  *(.data.init)
+	  . = ALIGN(16);
+	  __setup_start = .;
+	  *(.setup.init)
+	  __setup_end = .;
+	  __initcall_start = .;
+	  *(.initcall.init)
+	  . = ALIGN(4) ;
+	  __initcall_end = .;
+	  __init_end = .;
+
+	  _edata = . ;
+	  edata = . ;
+	} > ram
+
+  .bss :
+    {
+	  . = ALIGN(16) ;
+	  _sbss = . ;
+	  __bss_start = . ;
+	  __data_end = . ;
+	  *(.bss)
+	  *(COMMON)
+	  . = ALIGN(16) ;
+	  end = . ;
+	  _ebss = . ;	  
+	  _end = . ;
+    } > ram
+
+  . = 0x10100000 ;
+  .eram :
+	{
+  	  __ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/blackfin/platform/535/config.c linux-2.4.29-uc1/arch/blackfin/platform/535/config.c
--- linux-2.4.29/arch/blackfin/platform/535/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/config.c	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,126 @@
+/*
+ *  linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999 D. Jeff Dionne
+ *  Copyright (C) 2003 Metrowerks (Blackfin support)
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <asm/current.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/blackfin.h>
+
+/*
+ * By setting TSCALE such that TCOUNT counts a binary fraction
+ * of microseconds, we can read TCOUNT directly and then with
+ * a logical shift trivially calculate how many microseconds 
+ * since the last tick, allowing do_gettimeofday() to yield
+ * far better time resolution for real time benchmarking.
+ */
+
+#define CCLK_MHZ 300	/* would be nice to derive using the rtc */
+#define TSCALE_SHIFT 2	/* 0.25 microseconds */
+#define TSCALE_COUNT (CCLK_MHZ >> TSCALE_SHIFT)
+#define CLOCKS_PER_JIFFY ((1000*1000/HZ) << TSCALE_SHIFT)
+
+void config_FRIO_irq(void);
+
+void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
+{
+
+  /* power up the timer, but don't enable it just yet */
+
+  TCNTL = 1;
+
+  /* make TCOUNT a binary fraction of microseconds using
+   * the TSCALE prescaler counter.
+   */
+
+  TSCALE = TSCALE_COUNT - 1;
+  TCOUNT = TPERIOD = CLOCKS_PER_JIFFY - 1;
+
+  /* now enable the timer */
+
+  TCNTL = 7;
+
+  /* set up the timer irq */
+
+  request_irq(IRQ_CORETMR, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+  enable_irq(IRQ_CORETMR);
+}
+
+void BSP_tick(void)
+{
+#if 0
+  /* Reset Timer2 */
+  TSTAT2 &= 0;
+#endif
+}
+
+unsigned long BSP_gettimeoffset (void)
+{
+  return (CLOCKS_PER_JIFFY - TCOUNT) >> TSCALE_SHIFT;
+}
+
+void BSP_gettod (int *yearp, int *monp, int *dayp,
+		   int *hourp, int *minp, int *secp)
+{
+}
+
+int BSP_hwclk(int op, struct hwclk_time *t)
+{
+  if (!op) {
+    /* read */
+  } else {
+    /* write */
+  }
+  return 0;
+}
+
+int BSP_set_clock_mmss (unsigned long nowtime)
+{
+#if 0
+  short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+
+  tod->second1 = real_seconds / 10;
+  tod->second2 = real_seconds % 10;
+  tod->minute1 = real_minutes / 10;
+  tod->minute2 = real_minutes % 10;
+#endif
+  return 0;
+}
+
+void BSP_reset (void)
+{
+}
+
+void config_BSP(char *command, int len)
+{
+  mach_sched_init      = BSP_sched_init;
+  mach_tick            = BSP_tick;
+  mach_gettimeoffset   = BSP_gettimeoffset;
+  mach_gettod          = BSP_gettod;
+  mach_hwclk           = NULL;
+  mach_set_clock_mmss  = NULL;
+  // mach_mksound         = NULL;
+  mach_reset           = BSP_reset;
+  // mach_debug_init      = NULL;
+
+  config_FRIO_irq();
+}
diff -urN linux-2.4.29/arch/blackfin/platform/535/entry.S linux-2.4.29-uc1/arch/blackfin/platform/535/entry.S
--- linux-2.4.29/arch/blackfin/platform/535/entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/entry.S	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,627 @@
+/* -*- mode: asm -*-
+ *
+ *  linux/arch/frio/kernel/entry.S
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ * Linux/frio support: Tony Kou & Metrowerks
+ */
+
+/*
+ * entry.S  contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all interrupts
+ * and faults that can result in a task-switch.
+ *
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ *
+ */
+
+/*
+ * Secondary stage of kernel interrupt and exception handling. Points of entry
+ * into the kernel are in interrupt.S There are jumps to this file from
+ * interrupt.S Context is already saved when control comes to this file. SP
+ * points to bottom of the context, hence the stack appears same as pt_regs.
+ * ... amit
+ */
+
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/errno.h>
+#include <asm/setup.h>
+#include <asm/traps.h>
+
+#include "frio_defs.h"
+
+.globl SYMBOL_NAME(system_call), SYMBOL_NAME(buserr), SYMBOL_NAME(trap)
+.globl SYMBOL_NAME(resume), SYMBOL_NAME(ret_from_exception)
+.globl SYMBOL_NAME(ret_from_signal)
+.globl SYMBOL_NAME(sys_call_table)
+.globl SYMBOL_NAME(sys_fork), SYMBOL_NAME(sys_clone), SYMBOL_NAME(sys_vfork)
+.globl SYMBOL_NAME(ret_from_interrupt), SYMBOL_NAME(bad_interrupt)
+.globl SYMBOL_NAME(inthandler1), SYMBOL_NAME(inthandler2),SYMBOL_NAME(inthandler3)
+.globl SYMBOL_NAME(inthandler4),SYMBOL_NAME(inthandler5),SYMBOL_NAME(inthandler6)
+.globl SYMBOL_NAME(inthandler7)
+.globl SYMBOL_NAME(kernel_to_user_mode), SYMBOL_NAME(do_delay_trace), SYMBOL_NAME(Lsignal_return)
+
+.text
+
+ENTRY(trap) /* Exception: 4th entry into system event table(supervisor mode */
+	SAVE_ALL_INT
+	
+        p2.l = 0x2108;
+        p2.h = 0xffe0;
+        r0 = [p2];              // Read current IPEND
+        [sp + PT_IPEND] = r0;   // Store IPEND
+
+	r1 = [sp + PT_SEQSTAT];	// reason code is it bit 5:0
+	r0.l = 0x3f;
+	r0.h = 0x0;
+	r1 = r1 & r0;
+	CC = r1 == 0;
+	if ! cc jump 1f;
+	raise 14;	/* invoked by TRAP #0, for sys call */
+	jump.s	SYMBOL_NAME(ret_from_exception); /* pcrel12 enough */
+1:
+	r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */
+	call	SYMBOL_NAME(trap_c);
+	jump.s	SYMBOL_NAME(ret_from_exception); /* pcrel12 enough */
+
+ENTRY(reschedule)
+	/* save top of frame*/
+	p2.l = SYMBOL_NAME(_current_task);
+	p2.h = SYMBOL_NAME(_current_task);
+	[p2+(TASK_THREAD+THREAD_ESP0)] = sp;
+
+	p3.l = SYMBOL_NAME(ret_from_exception);
+	p3.h = SYMBOL_NAME(ret_from_exception);
+	rets = p3;
+	jump.l SYMBOL_NAME(schedule); /* unknow how far away */
+	/* Note: asmlinkage void schedule(void) */
+
+	/* After a fork we jump here directly from resume,*/
+	/* so that %r1 contains the previous task*/
+	/* Theoretically only needed on SMP, but let's watch*/
+	/* what happens in schedule_tail() in future...*/
+ENTRY(ret_from_fork)
+
+	/* Don't bother with trace yet - akale */
+	r0 = r1;
+	call SYMBOL_NAME(schedule_tail);
+	/* Note: void schedule_tail(struct task_struct *prev)	*/
+	
+	jump.s SYMBOL_NAME(ret_from_exception);
+
+badsys:
+	r7 = -ENOSYS; /* signextending enough */
+	[sp + PT_R0] = r7;	/* return value from system call */
+	rti;	
+
+do_trace:
+	r7 = -ENOSYS;
+	[sp + PT_R0] = r7;	/* needed for strace */
+	sp += -4;		/* why minus then plus again ??? Tony */
+	call SYMBOL_NAME(syscall_trace); /* void syscall_trace(void) */
+	sp += 4;
+	r5 = [sp+PT_R5];
+	r0 = -ENOSYS;
+	r7 = NR_syscalls;
+	cc = r5 < r7;
+	if ! cc jump 1f;
+	p4 = r1;
+	p5.l = SYMBOL_NAME(sys_call_table);
+	p5.h = SYMBOL_NAME(sys_call_table);
+	p5 = p5 + (p4 << 2);
+	r0 = [sp + PT_R0];	/* confirm the system call args */
+	r1 = [sp + PT_R1];
+	r2 = [sp + PT_R2];
+	jump (p5);
+1:
+	[sp + PT_R0] = r0;	/* save the return value */
+	sp += -4;		/* dummy return address  */
+	jump.l SYMBOL_NAME(syscall_trace); /* void syscall_trace(void) */
+
+ENTRY(system_call)	/* entry for excpt 0 into EVENT table */
+	/* save top of frame*/
+	SAVE_ALL_INT
+	[--sp] = reti;
+	sp += 4;
+	
+        p2.l = 0x2108;
+        p2.h = 0xffe0;
+        r0 = [p2];              // Read current IPEND
+        [sp + PT_IPEND] = r0;   // Store IPEND
+
+	p2.l = SYMBOL_NAME(_current_task);
+	p2.h = SYMBOL_NAME(_current_task);
+	[p2+(TASK_THREAD+THREAD_ESP0)] = sp;
+
+	
+#if 0 /* amit don't trace syscalls for now */
+	r7 = [p2+TASK_FLAGS];
+	cc = bittst (r7,PF_TRACESYS_BIT);
+	if cc jump do_trace;
+#endif
+
+	r7 = NR_syscalls;
+	cc = r5 < r7;	/* r5 = number of system call */
+	if ! cc jump badsys;
+
+	p4 = r5;
+	p5.l = SYMBOL_NAME(sys_call_table);
+	p5.h = SYMBOL_NAME(sys_call_table);
+	p5 = p5 + (p4<<2);
+	r0 = [sp + PT_R0];	/* confirm the system call args */
+	r1 = [sp + PT_R1];
+	r2 = [sp + PT_R2];
+	p5 = [p5];
+	call (p5);
+	
+	[sp+PT_R0] = r0;
+	jump.s SYMBOL_NAME(ret_from_exception);
+
+ENTRY(ret_from_exception)
+
+	r0 = [sp + PT_IPEND];
+	CC = bittst(r0, 15);	/* check if returning to kernel*/
+	if cc jump 4f;   /* if so, skip resched, signals*/   
+
+	cc = bittst(r0, 3);	/* check if return from exception */
+	if cc jump 1f;
+	CC = bittst(r0, 14);	/* check if return from interrupt */
+	if cc jump 1f;
+	/* reduce the nested interrupt IVG14 --> IVG 15, */
+	/* see also asm/processor.h: start_thread */
+	call kernel_to_user_mode; 
+	r0.l = 0x2;
+	r0.h = 0x0;	/* flag for return to user mode */
+	[sp + PT_IPEND] = r0;
+1:
+	/* only allow interrupts when we are really the last one on the*/
+	/* kernel stack, otherwise stack overflow can occur during*/
+	/* heavy interupt load*/
+	p5.l = SYMBOL_NAME(_current_task);
+	p5.h = SYMBOL_NAME(_current_task);
+	r7 = [p5];
+	p5 = r7;
+	r7 = [p5+TASK_NEEDRESCHED];
+	cc = r7 == 0;
+	if cc jump 2f;
+	jump.l SYMBOL_NAME(reschedule);
+2:
+	/* check for delayed trace*/
+	r7 = [p5+TASK_FLAGS];
+	cc = bittst(r7, PF_DTRACE_BIT);
+	bitclr (r7, PF_DTRACE_BIT);
+	[p5+TASK_FLAGS] = r7;
+	if !cc jump 5f;
+	call SYMBOL_NAME(do_delayed_trace);
+5:
+	r7 = [p5+TASK_STATE];		/* state*/
+	cc = r7 == 0;
+	if cc jump 3f
+	jump.l SYMBOL_NAME(reschedule);
+3:
+	r7 = [p5+TASK_SIGPENDING];
+	cc = r7 == 0;
+	if cc jump 4f;
+	call SYMBOL_NAME(Lsignal_return);
+4:
+	p2.l = 0x2108;
+	p2.h = 0xffe0;
+	r0 = [p2];              // Read current IPEND
+	CC = bittst(r0, 3);	/* check if return from exception*/
+	if cc jump 7f;
+	
+	r7 = [sp + PT_SYSCFG];	/* handle single step - STchen */
+	cc = bittst(r7, 0);
+	if cc jump supper_single_step;
+	
+	CC = bittst(r0, 14);	/* check if return from interrupt */
+	if cc jump 6f;
+	r0 = [sp + PT_IPEND];
+	CC = bittst(r0, 1);	/* return to user mode */
+	if cc jump 6f;
+7:	
+	RESTORE_ALL
+6:
+	RESTORE_ALL2
+
+supper_single_step:
+	r0.l = prev_single_step;
+	r0.l = prev_single_step;
+	p2.l = 0x200c;
+	p2.h = 0xffe0;
+	[p2] = r0;
+	r0.l = force_exception;
+	r0.h = force_exception;
+	reti = r0;
+	rti;
+	
+	/* we must force the exception for supper single step while */ 
+	/* system return to user mode from system call, otherwise single */
+	/* step will happen in kernel but not in application --STchen*/
+force_exception:
+	excpt 0x1;
+	
+	/* return from exception to prevent supper single step */
+prev_single_step:
+	r0.l = SYMBOL_NAME(trap);
+	r0.h = SYMBOL_NAME(trap);
+	p2.l = 0x200c;
+	p2.h = 0xffe0;
+	[p2] = r0;
+	RESTORE_ALL
+	
+SYMBOL_NAME_LABEL(Lsignal_return)
+	r0 = 0;
+	r1 = sp;
+	[--sp] = rets;
+	call SYMBOL_NAME(do_signal);
+	rets = [sp++];
+	rts;
+
+SYMBOL_NAME_LABEL(do_delayed_trace)
+	[--sp] = rets;
+	r0 = LSIGTRAP;
+	r1 = p5;
+	r2 = 1;
+	call SYMBOL_NAME(send_sig);
+	rets = [sp++];
+	rts;
+
+ENTRY(sys_fork)
+	call	SYMBOL_NAME(frio_fork);
+	rts;
+
+ENTRY(sys_clone)
+	r0 = sp;
+	[--sp] = rets;
+	call	SYMBOL_NAME(frio_clone);
+	rets = [sp++];
+	rts;
+
+ENTRY(sys_vfork)
+	r0 = sp;
+	[--sp] = rets;
+	call	SYMBOL_NAME(frio_vfork);
+	rets = [sp++];
+	rts;
+
+ENTRY(sys_sigsuspend)
+	call	SYMBOL_NAME(do_sigsuspend);
+	rts;
+
+ENTRY(sys_rt_sigsuspend)
+	call	SYMBOL_NAME(do_rt_sigsuspend);
+	rts;
+
+ENTRY(sys_sigreturn)
+	r0 = sp;
+	[--sp] = rets;
+	call	SYMBOL_NAME(do_sigreturn);
+	rets = [sp++];
+	rts;
+
+ENTRY(sys_rt_sigreturn)
+	call	SYMBOL_NAME(do_rt_sigreturn);
+	rts;
+
+/* Force kernel return from interrupt 15 to user mode -- Steven Chen*/
+SYMBOL_NAME_LABEL(kernel_to_user_mode)
+	[--sp] = rets;
+	reti = [sp++];
+	rti;
+	
+SYMBOL_NAME_LABEL(resume)
+	/*
+	 * Beware - when entering resume, prev (the current task) is
+	 * in r0, next (the new task) is in r1.
+	 */
+
+	p0 = r0;
+	p1 = r1;
+
+	[--sp] = rets;
+	[--sp] = (r7:6, p5:3);
+	[--sp] = fp;
+
+	/* save seqstat */
+	r7 = seqstat;
+	[p0+(TASK_THREAD+THREAD_SR)] = r7;
+
+	/* save usp */
+	p2 = usp;
+	[p0+(TASK_THREAD+THREAD_USP)] = p2;
+
+	/* save current kernel stack pointer */
+	[p0+(TASK_THREAD+THREAD_KSP)] = sp;
+
+	/* save program counter */
+	r1.l = SYMBOL_NAME(new_old_task);
+	r1.h = SYMBOL_NAME(new_old_task);
+	[p0+(TASK_THREAD+THREAD_PC)] = r1;
+
+	/* Return previous task in %r1 */
+	r1.l = SYMBOL_NAME(_current_task);
+	r1.h = SYMBOL_NAME(_current_task);
+
+	/* switch to new task (p1 contains new task) */
+	p5 = r1;
+	[p5] = p1;
+
+	/* restore the kernel stack pointer */
+	sp = [p1+(TASK_THREAD+THREAD_KSP)];
+
+	/* restore user stack pointer */
+	p0 = [p1+(TASK_THREAD+THREAD_USP)];
+	usp = p0;
+
+	/* restore status register */
+	r7 = [p1+(TASK_THREAD+THREAD_SR)];
+	seqstat = r7;
+
+	/* restore pc */
+	p0 = [p1+(TASK_THREAD+THREAD_PC)];
+	jump (p0); 
+
+	/*
+	 * While we don't rely on compiler magic, nothing prevents us from
+	 * simple jumps.
+	 * Following code actually lands up in a new (old) task. .. akale
+	 */
+
+new_old_task:	
+	fp = [sp++];
+
+	/* You may get assembler errors if you modify following instruction.
+	 * Had to do lots of experiments to get it right. The assembler simply
+	 * doesn't accept a correct syntax - amit */
+	( R7:6, p5 : 3) = [sp++];
+
+	rets = [sp++];
+
+	/*
+	 * When we come out of resume, r0 carries "old" task, becuase we are
+	 * in "new" task.
+	 */
+
+	rts;
+
+
+.data
+ALIGN
+SYMBOL_NAME_LABEL(sys_call_table)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 0  -  old "setup()" system call*/
+	.long SYMBOL_NAME(sys_exit)
+	.long SYMBOL_NAME(sys_fork)
+	.long SYMBOL_NAME(sys_read)
+	.long SYMBOL_NAME(sys_write)
+	.long SYMBOL_NAME(sys_open)		/* 5 */
+	.long SYMBOL_NAME(sys_close)
+	.long SYMBOL_NAME(sys_waitpid)
+	.long SYMBOL_NAME(sys_creat)
+	.long SYMBOL_NAME(sys_link)
+	.long SYMBOL_NAME(sys_unlink)		/* 10 */
+	.long SYMBOL_NAME(sys_execve)
+	.long SYMBOL_NAME(sys_chdir)
+	.long SYMBOL_NAME(sys_time)
+	.long SYMBOL_NAME(sys_mknod)
+	.long SYMBOL_NAME(sys_chmod)		/* 15 */
+	.long SYMBOL_NAME(sys_chown16)
+	.long SYMBOL_NAME(sys_ni_syscall)	/*old break syscall holder*/
+	.long SYMBOL_NAME(sys_stat)
+	.long SYMBOL_NAME(sys_lseek)
+	.long SYMBOL_NAME(sys_getpid)		/* 20 */
+	.long SYMBOL_NAME(sys_mount)
+	.long SYMBOL_NAME(sys_oldumount)
+	.long SYMBOL_NAME(sys_setuid16)
+	.long SYMBOL_NAME(sys_getuid16)
+	.long SYMBOL_NAME(sys_stime)		/* 25 */
+	.long SYMBOL_NAME(sys_ptrace)
+	.long SYMBOL_NAME(sys_alarm)
+	.long SYMBOL_NAME(sys_fstat)
+	.long SYMBOL_NAME(sys_pause)
+	.long SYMBOL_NAME(sys_utime)		/* 30 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old stty syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old gtty syscall holder */
+	.long SYMBOL_NAME(sys_access)
+	.long SYMBOL_NAME(sys_nice)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 35 old ftime syscall */
+	.long SYMBOL_NAME(sys_sync)
+	.long SYMBOL_NAME(sys_kill)
+	.long SYMBOL_NAME(sys_rename)
+	.long SYMBOL_NAME(sys_mkdir)
+	.long SYMBOL_NAME(sys_rmdir)		/* 40 */
+	.long SYMBOL_NAME(sys_dup)
+	.long SYMBOL_NAME(sys_pipe)
+	.long SYMBOL_NAME(sys_times)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old prof syscall holder */
+	.long SYMBOL_NAME(sys_brk)		/* 45 */
+	.long SYMBOL_NAME(sys_setgid16)
+	.long SYMBOL_NAME(sys_getgid16)
+	.long SYMBOL_NAME(sys_signal)
+	.long SYMBOL_NAME(sys_geteuid16)
+	.long SYMBOL_NAME(sys_getegid16)	/* 50 */
+	.long SYMBOL_NAME(sys_acct)
+	.long SYMBOL_NAME(sys_umount)		/* recycled unused phys() */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old lock syscall holder */
+	.long SYMBOL_NAME(sys_ioctl)
+	.long SYMBOL_NAME(sys_fcntl)		/* 55 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old mpx syscall holder */
+	.long SYMBOL_NAME(sys_setpgid)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old ulimit syscall */
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_umask)		/* 60 */
+	.long SYMBOL_NAME(sys_chroot)
+	.long SYMBOL_NAME(sys_ustat)
+	.long SYMBOL_NAME(sys_dup2)
+	.long SYMBOL_NAME(sys_getppid)
+	.long SYMBOL_NAME(sys_getpgrp)		/* 65 */
+	.long SYMBOL_NAME(sys_setsid)
+	.long SYMBOL_NAME(sys_sigaction)
+	.long SYMBOL_NAME(sys_sgetmask)
+	.long SYMBOL_NAME(sys_ssetmask)
+	.long SYMBOL_NAME(sys_setreuid16)	/* 70 */
+	.long SYMBOL_NAME(sys_setregid16)
+	.long SYMBOL_NAME(sys_sigsuspend)
+	.long SYMBOL_NAME(sys_sigpending)
+	.long SYMBOL_NAME(sys_sethostname)
+	.long SYMBOL_NAME(sys_setrlimit)	/* 75 */
+	.long SYMBOL_NAME(sys_old_getrlimit)
+	.long SYMBOL_NAME(sys_getrusage)
+	.long SYMBOL_NAME(sys_gettimeofday)
+	.long SYMBOL_NAME(sys_settimeofday)
+	.long SYMBOL_NAME(sys_getgroups16)	/* 80 */
+	.long SYMBOL_NAME(sys_setgroups16)
+	.long SYMBOL_NAME(old_select)
+	.long SYMBOL_NAME(sys_symlink)
+	.long SYMBOL_NAME(sys_lstat)
+	.long SYMBOL_NAME(sys_readlink)		/* 85 */
+	.long SYMBOL_NAME(sys_uselib)
+	.long SYMBOL_NAME(sys_swapon)
+	.long SYMBOL_NAME(sys_reboot)
+	.long SYMBOL_NAME(old_readdir)
+	.long SYMBOL_NAME(old_mmap)		/* 90 */
+	.long SYMBOL_NAME(sys_munmap)
+	.long SYMBOL_NAME(sys_truncate)
+	.long SYMBOL_NAME(sys_ftruncate)
+	.long SYMBOL_NAME(sys_fchmod)
+	.long SYMBOL_NAME(sys_fchown16)		/* 95 */
+	.long SYMBOL_NAME(sys_getpriority)
+	.long SYMBOL_NAME(sys_setpriority)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old profil syscall */
+	.long SYMBOL_NAME(sys_statfs)
+	.long SYMBOL_NAME(sys_fstatfs)		/* 100 */
+	.long SYMBOL_NAME(sys_ioperm)
+	.long SYMBOL_NAME(sys_socketcall)
+	.long SYMBOL_NAME(sys_syslog)
+	.long SYMBOL_NAME(sys_setitimer)
+	.long SYMBOL_NAME(sys_getitimer)	/* 105 */
+	.long SYMBOL_NAME(sys_newstat)
+	.long SYMBOL_NAME(sys_newlstat)
+	.long SYMBOL_NAME(sys_newfstat)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* iopl for i386 */ /* 110 */
+	.long SYMBOL_NAME(sys_vhangup)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* obsolete idle() syscall */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* vm86old for i386 */
+	.long SYMBOL_NAME(sys_wait4)
+	.long SYMBOL_NAME(sys_swapoff)		/* 115 */
+	.long SYMBOL_NAME(sys_sysinfo)
+	.long SYMBOL_NAME(sys_ipc)
+	.long SYMBOL_NAME(sys_fsync)
+	.long SYMBOL_NAME(sys_sigreturn)
+	.long SYMBOL_NAME(sys_clone)		/* 120 */
+	.long SYMBOL_NAME(sys_setdomainname)
+	.long SYMBOL_NAME(sys_newuname)
+	.long SYMBOL_NAME(sys_cacheflush)	/* modify_ldt for i386 */
+	.long SYMBOL_NAME(sys_adjtimex)
+	.long SYMBOL_NAME(sys_mprotect)		/* 125 */
+	.long SYMBOL_NAME(sys_sigprocmask)
+	.long SYMBOL_NAME(sys_create_module)
+	.long SYMBOL_NAME(sys_init_module)
+	.long SYMBOL_NAME(sys_delete_module)
+	.long SYMBOL_NAME(sys_get_kernel_syms)	/* 130 */
+	.long SYMBOL_NAME(sys_quotactl)
+	.long SYMBOL_NAME(sys_getpgid)
+	.long SYMBOL_NAME(sys_fchdir)
+	.long SYMBOL_NAME(sys_bdflush)
+	.long SYMBOL_NAME(sys_sysfs)		/* 135 */
+	.long SYMBOL_NAME(sys_personality)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for afs_syscall */
+	.long SYMBOL_NAME(sys_setfsuid16)
+	.long SYMBOL_NAME(sys_setfsgid16)
+	.long SYMBOL_NAME(sys_llseek)		/* 140 */
+	.long SYMBOL_NAME(sys_getdents)
+	.long SYMBOL_NAME(sys_select)
+	.long SYMBOL_NAME(sys_flock)
+	.long SYMBOL_NAME(sys_msync)
+	.long SYMBOL_NAME(sys_readv)		/* 145 */
+	.long SYMBOL_NAME(sys_writev)
+	.long SYMBOL_NAME(sys_getsid)
+	.long SYMBOL_NAME(sys_fdatasync)
+	.long SYMBOL_NAME(sys_sysctl)
+	.long SYMBOL_NAME(sys_mlock)		/* 150 */
+	.long SYMBOL_NAME(sys_munlock)
+	.long SYMBOL_NAME(sys_mlockall)
+	.long SYMBOL_NAME(sys_munlockall)
+	.long SYMBOL_NAME(sys_sched_setparam)
+	.long SYMBOL_NAME(sys_sched_getparam)   /* 155 */
+	.long SYMBOL_NAME(sys_sched_setscheduler)
+	.long SYMBOL_NAME(sys_sched_getscheduler)
+	.long SYMBOL_NAME(sys_sched_yield)
+	.long SYMBOL_NAME(sys_sched_get_priority_max)
+	.long SYMBOL_NAME(sys_sched_get_priority_min)  /* 160 */
+	.long SYMBOL_NAME(sys_sched_rr_get_interval)
+	.long SYMBOL_NAME(sys_nanosleep)
+	.long SYMBOL_NAME(sys_mremap)
+	.long SYMBOL_NAME(sys_setresuid16)
+	.long SYMBOL_NAME(sys_getresuid16)	/* 165 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for vm86 */
+	.long SYMBOL_NAME(sys_query_module)
+	.long SYMBOL_NAME(sys_poll)
+	.long SYMBOL_NAME(sys_nfsservctl)
+	.long SYMBOL_NAME(sys_setresgid16)	/* 170 */
+	.long SYMBOL_NAME(sys_getresgid16)
+	.long SYMBOL_NAME(sys_prctl)
+	.long SYMBOL_NAME(sys_rt_sigreturn)
+	.long SYMBOL_NAME(sys_rt_sigaction)
+	.long SYMBOL_NAME(sys_rt_sigprocmask)	/* 175 */
+	.long SYMBOL_NAME(sys_rt_sigpending)
+	.long SYMBOL_NAME(sys_rt_sigtimedwait)
+	.long SYMBOL_NAME(sys_rt_sigqueueinfo)
+	.long SYMBOL_NAME(sys_rt_sigsuspend)
+	.long SYMBOL_NAME(sys_pread)		/* 180 */
+	.long SYMBOL_NAME(sys_pwrite)
+	.long SYMBOL_NAME(sys_lchown16);
+	.long SYMBOL_NAME(sys_getcwd)
+	.long SYMBOL_NAME(sys_capget)
+	.long SYMBOL_NAME(sys_capset)           /* 185 */
+	.long SYMBOL_NAME(sys_sigaltstack)
+	.long SYMBOL_NAME(sys_sendfile)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* streams1 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* streams2 */
+	.long SYMBOL_NAME(sys_vfork)            /* 190 */
+	.long SYMBOL_NAME(sys_getrlimit)
+	.long SYMBOL_NAME(sys_mmap2)
+	.long SYMBOL_NAME(sys_truncate64)
+	.long SYMBOL_NAME(sys_ftruncate64)
+	.long SYMBOL_NAME(sys_stat64)		/* 195 */
+	.long SYMBOL_NAME(sys_lstat64)
+	.long SYMBOL_NAME(sys_fstat64)
+	.long SYMBOL_NAME(sys_chown)
+	.long SYMBOL_NAME(sys_getuid)
+	.long SYMBOL_NAME(sys_getgid)		/* 200 */
+	.long SYMBOL_NAME(sys_geteuid)
+	.long SYMBOL_NAME(sys_getegid)
+	.long SYMBOL_NAME(sys_setreuid)
+	.long SYMBOL_NAME(sys_setregid)
+	.long SYMBOL_NAME(sys_getgroups)	/* 205 */
+	.long SYMBOL_NAME(sys_setgroups)
+	.long SYMBOL_NAME(sys_fchown)
+	.long SYMBOL_NAME(sys_setresuid)
+	.long SYMBOL_NAME(sys_getresuid)
+	.long SYMBOL_NAME(sys_setresgid)	/* 210 */
+	.long SYMBOL_NAME(sys_getresgid)
+	.long SYMBOL_NAME(sys_lchown)
+	.long SYMBOL_NAME(sys_setuid)
+	.long SYMBOL_NAME(sys_setgid)
+	.long SYMBOL_NAME(sys_setfsuid)		/* 215 */
+	.long SYMBOL_NAME(sys_setfsgid)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
+
+	/* no recognization now by nisa-gcc */
+	.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4	
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.endr
diff -urN linux-2.4.29/arch/blackfin/platform/535/fixup.pl linux-2.4.29-uc1/arch/blackfin/platform/535/fixup.pl
--- linux-2.4.29/arch/blackfin/platform/535/fixup.pl	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/fixup.pl	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,91 @@
+#!/usr/bin/perl
+
+#
+# Nasty piece of work, designed to translated linux.bin binary image
+# in to several different formats.
+# 
+# Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>,
+#                    The Silver Hammer Group, Ltd.
+#
+
+@CRC = (
+        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+        0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+        0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+        0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+        0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
+        0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
+        0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
+        0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
+        0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
+        0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
+        0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
+        0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
+        0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+        0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
+        0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
+        0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
+        0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
+        0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
+        0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
+        0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
+        0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
+        0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+        0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
+        0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
+        0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
+        0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+        0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
+        0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
+        0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
+        0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
+        0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
+        0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
+);
+
+sub CrcBlock {
+	my($data,$crc) = @_;
+	my($i);
+	printf "Crc of %d bytes\n", length($data);
+	for ($i=0;$i<length($data);$i++) {
+#		printf "crc = %d, Lookup = %d, CRC[] = %d\n", $crc,						($crc>>8) ^
+#						ord(substr($data,$i,1)),
+#$CRC[						($crc>>8) ^
+#						ord(substr($data,$i,1)) &
+#0xff];
+#
+
+		$crc = ($crc << 8) ^ $CRC[
+						((($crc>>8) & 0xff) ^
+						ord(substr($data,$i,1))) &
+						0xff
+					];
+		$crc &= 0xffff;
+	}
+	return $crc & 0xffff;
+}
+
+open(T,"<linux.bin");
+$/ = undef;
+
+$image = join('', <T>);
+close(T);
+
+$realLength = length($image);
+$image .= "\0" x (0x100000 - $realLength);
+
+$posOfCardLength = 108;
+$posOfChecksum = 112;
+#$crc = CrcBlock(substr($image, 0, $posOfChecksum), 0);
+#$crc = CrcBlock(substr($image, $posOfChecksum+2), $crc);
+
+#substr($image, $posOfCardLength, 4) = pack("N", length($image));
+#substr($image, $posOfChecksum, 2) = pack("n", $crc);
+
+open(O,">linux.trg");
+print O substr($image, 0x10000, (($realLength - 0x10000) + 0xffff) & ~0xffff);
+close(O);
+
+open(O, ">linux.rom");
+print O $image;
+close(O);
diff -urN linux-2.4.29/arch/blackfin/platform/535/frio_defs.h linux-2.4.29-uc1/arch/blackfin/platform/535/frio_defs.h
--- linux-2.4.29/arch/blackfin/platform/535/frio_defs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/frio_defs.h	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,62 @@
+/*
+ * WARNING! This file is automatically generated - DO NOT EDIT!
+ */
+
+#define TS_MAGICKEY	0x5a5a5a5a
+#define TASK_STATE 0
+#define TASK_FLAGS 4
+#define TASK_PTRACE 24
+#define TASK_BLOCKED 636
+#define TASK_COUNTER 32
+#define TASK_SIGPENDING 8
+#define TASK_NEEDRESCHED 20
+#define TASK_THREAD 600
+#define TASK_MM 44
+#define TASK_ACTIVE_MM 80
+#define THREAD_KSP 0
+#define THREAD_USP 4
+#define THREAD_SR 8
+#define THREAD_ESP0 12
+#define THREAD_PC 16
+
+/**************************************/
+/* Added by HuTao, May26 2003 3:29PM */
+#define PT_IPEND 100
+#define PT_USP 92
+#define PT_FP 96
+/**************************************/
+
+#define PT_ORIG_R0 84
+#define PT_R0 88
+#define PT_R1 12
+#define PT_R2 8
+#define PT_R3 0
+#define PT_R4 4
+#define PT_R5 48
+#define PT_R6 44
+#define PT_R7 40
+#define PT_P0 36
+#define PT_P1 32
+#define PT_P2 28
+#define PT_P3 24
+#define PT_P4 20
+#define PT_P5 16
+#define PT_A0w 72
+#define PT_A1w 68
+#define PT_A0x 80
+#define PT_A1x 76
+#define PT_RETS 64
+#define PT_ASTAT 60
+#define PT_SEQSTAT 56
+#define PT_PC 52
+#define IRQ_HANDLER 0
+#define IRQ_DEVID 8
+#define IRQ_NEXT 16
+#define STAT_IRQ 5148
+#define SIGSEGV 11
+#define SEGV_MAPERR 196609
+#define SIGTRAP 5
+#define PT_PTRACED 1
+#define PT_TRACESYS 2
+#define PT_DTRACE 4
+#define PT_SYSCFG 104
diff -urN linux-2.4.29/arch/blackfin/platform/535/interrupt.S linux-2.4.29-uc1/arch/blackfin/platform/535/interrupt.S
--- linux-2.4.29/arch/blackfin/platform/535/interrupt.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/interrupt.S	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,321 @@
+/* linux/arch/frionommu/platform/frio/interrupt.S: 
+ *	 H/W interrupts
+ *	 - assumes default interrupt configuration for the interrupts
+ * 
+ * Copyright (C) 2003  Metrowerks, Inc. <mwaddel@metrowerks.com>
+ * Copyright (C) 2002  Arcturus Networks Ltd. Ted Ma <mated@sympatico.ca>
+ * Copyright (C) 1998  D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
+ *                     Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ * (c) 1995, Dionne & Associates
+ * (c) 1995, DKG Display Tech.
+ *
+ */
+
+#define ASSEMBLY
+	 
+#include <asm/hw_irq.h>
+
+#include <linux/autoconf.h>
+
+#include <asm/entry.h>
+#include "frio_defs.h"
+
+// Global references
+.global _stext;
+.global __bss_start;
+.global frio_irq_panic;		 // go to panic in ints.c
+	 
+/*
+ * Code to save processor context.
+ *  We even save the register which are preserved by a function call
+ *	 - r4, r5, r6, r7, p3, p4, p5
+ */
+#define SAVE_CONTEXT save_context
+.macro save_context
+	[--sp] = ( R7:0, P5:0 );
+	[--sp] = fp;
+	[--sp] = usp;
+
+	[--sp] = i0;
+	[--sp] = i1;
+	[--sp] = i2;
+	[--sp] = i3;
+
+	[--sp] = m0;
+	[--sp] = m1;
+	[--sp] = m2;
+	[--sp] = m3;
+
+	[--sp] = l0;
+	[--sp] = l1;
+	[--sp] = l2;
+	[--sp] = l3;
+
+	[--sp] = b0;
+	[--sp] = b1;
+	[--sp] = b2;
+	[--sp] = b3;
+	[--sp] = a0.x;
+	[--sp] = a0.w;
+	[--sp] = a1.x;
+	[--sp] = a1.w;
+
+	[--sp] = LC0;
+	[--sp] = LC1;
+	[--sp] = LT0;
+	[--sp] = LT1;
+	[--sp] = LB0;
+	[--sp] = LB1;
+
+	[--sp] = ASTAT;
+
+	[--sp] = RETS;
+	[--sp] = RETI;
+	[--sp] = RETX;	/* get breakpoint from here, former pc */
+	[--sp] = RETN;
+	[--sp] = RETE;
+	[--sp] = SYSCFG;
+	[--sp] = SEQSTAT;
+.endm
+	 
+#define RESTORE_CONTEXT restore_context
+.macro restore_context
+	 SEQSTAT = [sp++];
+	 SYSCFG = [sp++];
+	 RETE = [sp++];
+	 RETN = [sp++];
+	 RETX = [sp++];
+	 RETI = [sp++];
+	 RETS = [sp++];
+
+	 ASTAT = [sp++];
+
+	 LB1 = [sp++];
+	 LB0 = [sp++];
+	 LT1 = [sp++];
+	 LT0 = [sp++];
+	 LC1 = [sp++];
+	 LC0 = [sp++];
+
+	 a1.w = [sp++];
+	 a1.x = [sp++];
+	 a0.w = [sp++];
+	 a0.x = [sp++];
+	 b3 = [sp++];
+	 b2 = [sp++];
+	 b1 = [sp++];
+	 b0 = [sp++];
+
+	 l3 = [sp++];
+	 l2 = [sp++];
+	 l1 = [sp++];
+	 l0 = [sp++];
+
+	 m3 = [sp++];
+	 m2 = [sp++];
+	 m1 = [sp++];
+	 m0 = [sp++];
+
+	 i3 = [sp++];
+	 i2 = [sp++];
+	 i1 = [sp++];
+	 i0 = [sp++];
+
+	 usp = [sp++];
+	 fp = [sp++];
+
+	 ( R7 : 0, P5 : 0) = [ SP ++ ];
+.endm
+	 
+/*****************************************************************************/
+// Data areas
+.bss
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+
+.data
+
+	 
+.text
+.align 2 	// just in case
+/*
+ * initial interrupt handlers
+ */
+#ifndef CONFIG_KGDB	// installs own handler
+ 	 /* interrupt routine for emulation - 0 */
+	 /* Currently used only if GDB stub is not in - invalid	  */
+	 /* gdb-stub set the evt itself */
+	 /* save registers for post-mortem only */
+.global evt_emulation
+evt_emulation:
+	 SAVE_CONTEXT
+
+	 r0 = IRQ_EMU;
+	 r1 = seqstat; 
+	 call	frio_irq_panic;	// this should go to an invalid - panic
+	// - GDB stub fills this in by itself (if defined)
+	  rte; 
+#endif
+
+	/* interrupt routine for nmi - 2 */
+.global evt_nmi
+evt_nmi:
+	 SAVE_CONTEXT
+
+	r0 = IRQ_NMI;
+	r1 = RETN;	     // get return address (but not going back)  
+	call frio_irq_panic; // this should end up at a panic - for now 
+_evt_nmi_exit:
+	 rtn; 
+			
+irq_panic:
+	 r0 = IRQ_EVX;
+	
+	/* Changed by HuTao, May 21, 2003 2:44PM */
+	 r1 =  sp;
+	 call	frio_irq_panic;
+	 /* panic doesn't return, so no restoration of context. */
+	 
+	 /* interrupt routine for ivhw - 5 */
+	 /* Hardware Error */
+.global evt_ivhw
+evt_ivhw:
+	 SAVE_CONTEXT
+
+	 r1 = seqstat;	  // reason code is it bit 18:14
+	 r0 = IRQ_HWERR; 
+	 call	frio_irq_panic;
+	 rti; 
+
+	 /* interrupt routine for core timer - 6 */	 
+.global evt_timer
+evt_timer:
+
+	SAVE_CONTEXT
+	r0 = IRQ_CORETMR;  
+	call process_int;  /* call do_timer; */
+	RESTORE_CONTEXT
+	rti; 
+	nop;
+
+	 /* interrupt routine for evt7 - 7 */	 
+.global evt_evt7
+evt_evt7:
+	 SAVE_CONTEXT
+	 
+//	 r0 = IRQ_RTC;	// Real Time Clock 
+//	 r0 = IRQ_USB;	// Universal Serial Bus 
+//	 r0 = IRQ_PCI;	// Personal Computer Interface ?? 
+	 r0 = 7;
+
+
+	 call	process_int; 
+evt_evt7_exit:
+	 RESTORE_CONTEXT
+	 rti; 
+
+	 /* interrupt routine for evt8 - 8 */
+.global evt_evt8
+evt_evt8:
+	 SAVE_CONTEXT
+
+// 	 r0 = IRQ_SPORT0; // Synchronous port 0 
+// 	 r0 = IRQ_SPORT1; // Synchronous POrt 1
+	 r0 = 8;
+	 
+	 call	process_int; 
+evt_evt8_exit:
+	 RESTORE_CONTEXT
+	 rti; 
+
+	 /* interrupt routine for evt9 - 9 */	 
+.global evt_evt9
+evt_evt9:
+	 SAVE_CONTEXT
+
+// 	 r0 = IRQ_SPI0;	// Serial Peripheral Interface 0
+// 	 r0 = IRQ_SPI1;	// Serial Peripheral Interface 1
+	 r0 = 9;
+
+	 call	process_int; 
+evt_evt9_exit:
+	 RESTORE_CONTEXT
+	 rti; 
+
+	 /* interrupt routine for evt10	- 10 */	 
+.global evt_evt10
+evt_evt10:
+	 SAVE_CONTEXT
+
+// 	 r0 = IRQ_UART1; // UART 
+	 r0 = 10;
+	 
+	 call	process_int; 
+evt_evt10_exit:
+	 RESTORE_CONTEXT
+	 rti; 
+
+	 /* interrupt routine for evt11	- 11 */	 
+.global evt_evt11
+evt_evt11:
+	 SAVE_CONTEXT
+
+// 	 r0 = IRQ_TMR0;	// TImer 0
+// 	 r0 = IRQ_TMR1;	// TImer 1
+// 	 r0 = IRQ_TMR2;	// TImer 2
+	 r0 = 11;
+
+	 call	process_int; 
+evt_evt11_exit:
+	 RESTORE_CONTEXT
+	 rti; 
+
+	 /* interrupt routine for evt12	- 12 */	 
+.global evt_evt12
+evt_evt12:
+	 SAVE_CONTEXT
+
+// 	 r0 = IRQ_PROG_INTA;	// Programmable interrupts flag A
+// 	 r0 = IRQ_PROG_INTB;	// Programmable interrupts flag B
+	 r0 = 12;
+	 
+	 call	process_int; 
+evt_evt12_exit:
+	 RESTORE_CONTEXT
+	 rti; 
+
+	 /* interrupt routine for evt13	- 13 */
+.global evt_evt13
+evt_evt13:
+	 SAVE_CONTEXT
+
+// 	 r0 = IRQ_WATCH;	// Watch dog interrupt
+	 r0 = 13;
+	 
+	 call	process_int; 
+evt_evt13_exit:
+	 RESTORE_CONTEXT
+	 rti; 
+
+	 /* interrupt routine for system_call - 14 */	 
+.global evt_system_call
+evt_system_call:
+	jump.l system_call;
+
+	 /* interrupt routine for soft_int1 - 15 */	 
+.global evt_soft_int1
+evt_soft_int1:
+	 SAVE_CONTEXT
+
+	 r0 = IRQ_SW_INT1;	// Software Interrupt 1 
+	 
+	 call	process_int; 
+evt_soft_int1_exit:
+	 RESTORE_CONTEXT
+	 rti; 
diff -urN linux-2.4.29/arch/blackfin/platform/535/ints.c linux-2.4.29-uc1/arch/blackfin/platform/535/ints.c
--- linux-2.4.29/arch/blackfin/platform/535/ints.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/ints.c	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,590 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Apr18 2003, Changed by HuTao to support interrupt cascading for Blackfin 
+ *             drivers
+ *
+ * Copyright 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne <jeff@uclinux.org>
+ * Copyright 2000-2001 Lineo, Inc. D. Jefff Dionne <jeff@lineo.ca>
+ * Copyright 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
+ * Copyright 2003 Metrowerks/Motorola
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/kernel_stat.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+
+#include <asm/blackfin.h>
+
+/********************************************************************
+ * NOTES:
+ * - we have separated the physical Hardware interrupt from the
+ * levels that the LINUX kernel sees (see the description in irq.h)
+ * - 
+ ********************************************************************/
+
+#define INTERNAL_IRQS (32)
+
+int irq_flags = 0;
+
+/*********************
+ * Prototypes
+ ********************/
+/* Changed by HuTao, May21, 2003 2:38PM */
+asmlinkage void frio_irq_panic( int reason, struct pt_regs * reg);
+extern void dump(struct pt_regs * regs);
+
+/* BASE LEVEL interrupt handler routines */
+//asmlinkage void evt_reset(void);
+asmlinkage void evt_nmi(void);
+asmlinkage void evt_exception(void);
+asmlinkage void trap(void);
+asmlinkage void evt_ivhw(void);
+asmlinkage void evt_timer(void);
+asmlinkage void evt_evt7(void);
+asmlinkage void evt_evt8(void);
+asmlinkage void evt_evt9(void);
+asmlinkage void evt_evt10(void);
+asmlinkage void evt_evt11(void);
+asmlinkage void evt_evt12(void);
+asmlinkage void evt_evt13(void);
+asmlinkage void evt_soft_int1(void);
+asmlinkage void evt_system_call(void);
+
+/* irq node variables for the 32 (potential) on chip sources */
+static irq_node_t *int_irq_list[INTERNAL_IRQS];
+
+static int int_irq_count[INTERNAL_IRQS];
+static short int_irq_ablecount[INTERNAL_IRQS];
+
+/* Modified by HuTao, May21, 2003 */
+/*********
+ * frio_irq_panic
+ * - calls panic with string setup
+ *********/
+asmlinkage void frio_irq_panic( int reason, struct pt_regs * regs)
+{
+	
+  	printk("\n\nException: IRQ 0x%x entered\n", reason);
+	printk("code=[0x%08x], ", regs->seqstat & 0x3f);
+	printk("stack frame=0x%04x, ",(unsigned long) regs);
+	printk("bad PC=0x%04x\n", regs->pc);
+	dump(regs);
+	panic("Unhandled IRQ or exceptions!\n");
+}
+
+static void int_badint(int irq, void *dev_id, struct pt_regs *fp)
+{
+	num_spurious += 1;
+}
+
+ 
+/*
+ * This function should be called during kernel startup to initialize
+ * the Frio IRQ handling routines.
+ */
+
+void FRIO_init_IRQ(void)
+{
+
+#ifndef CONFIG_PCI
+	
+   /*  Disable all the peripheral intrs  - page 4-29 HW Ref manual */	
+   *(unsigned volatile long *)(SIC_MASK_ADDR) = SIC_MASK_ALL;
+
+#else /* CONFIG_PCI */
+
+   /* 
+    * Enable interrupt for PCI in SIC_IMASK.
+    *
+    * However, the PCI interrupts (INTA, INTB, INTC and INTD)
+    * will NOT be enabled until corresponding bits in PCI_ICTL reg
+    * are set in FRIO_enable_irq()
+    *
+    * HuTao, Jul14 2003
+    */
+   *(unsigned volatile long *)(SIC_MASK_ADDR) = SIC_MASK_ALL | 0x00000008;
+
+#endif /* CONFIG_PCI */
+ 
+   cli();
+#ifndef CONFIG_KGDB	// nisa-stub does this if enabled
+   *(unsigned volatile long *)(EVT_EMULATION_ADDR) = 
+#endif
+// RESET is a R/O register ...MaTed---
+// *(unsigned volatile long *)(EVT_RESET_ADDR) = 
+//                            (unsigned volatile long)evt_reset;
+   *(unsigned volatile long *)(EVT_NMI_ADDR) = 
+                              (unsigned volatile long)evt_nmi;
+   *(unsigned volatile long *)(EVT_EXCEPTION_ADDR) = 
+                              (unsigned volatile long)trap;
+   *(unsigned volatile long *)(EVT_HARDWARE_ERROR_ADDR) = 
+                              (unsigned volatile long)evt_ivhw;
+   *(unsigned volatile long *)(EVT_TIMER_ADDR) = 
+                              (unsigned volatile long)evt_timer;
+   *(unsigned volatile long *)(EVT_IVG7_ADDR) = 
+                              (unsigned volatile long)evt_evt7;
+   *(unsigned volatile long *)(EVT_IVG8_ADDR) = 
+                              (unsigned volatile long)evt_evt8;
+   *(unsigned volatile long *)(EVT_IVG9_ADDR) = 
+                              (unsigned volatile long)evt_evt9;
+   *(unsigned volatile long *)(EVT_IVG10_ADDR) = 
+                              (unsigned volatile long)evt_evt10;
+   *(unsigned volatile long *)(EVT_IVG11_ADDR) = 
+                              (unsigned volatile long)evt_evt11;
+   *(unsigned volatile long *)(EVT_IVG12_ADDR) = 
+                              (unsigned volatile long)evt_evt12;
+   *(unsigned volatile long *)(EVT_IVG13_ADDR) = 
+                              (unsigned volatile long)evt_evt13;
+   *(unsigned volatile long *)(EVT_IVG14_ADDR) = 
+                              (unsigned volatile long)evt_system_call;
+   *(unsigned volatile long *)(EVT_IVG15_ADDR) = 
+                              (unsigned volatile long)evt_soft_int1;
+
+   IMASK = irq_flags |= 0xff80;
+   ILAT=0;
+   sti();
+}
+
+void FRIO_enable_irq(unsigned int irq);
+void FRIO_disable_irq(unsigned int irq);
+
+int FRIO_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d from %s\n", 
+			      __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+	if (!int_irq_list[irq]) {
+		int_irq_list[irq] = new_irq_node();
+		int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	}
+
+	if (!(int_irq_list[irq]->flags & IRQ_FLG_STD)) {
+		if (int_irq_list[irq]->flags & IRQ_FLG_LOCK) {
+			printk("IRQ %d is already assigned.\n", irq);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("Can't replace IRQ %d\n", irq);
+			return -EBUSY;
+		}
+	}
+	int_irq_list[irq]->handler = handler;
+	int_irq_list[irq]->flags   = flags;
+	int_irq_list[irq]->dev_id  = dev_id;
+	int_irq_list[irq]->devname = devname;
+
+	return 0;
+}
+
+void FRIO_free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_list[irq]->dev_id != dev_id)
+		printk("%s: removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, int_irq_list[irq]->devname);
+	int_irq_list[irq]->handler = int_badint;
+	int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	int_irq_list[irq]->dev_id  = NULL;
+	int_irq_list[irq]->devname = NULL;
+
+	FRIO_disable_irq(irq);
+}
+
+/*
+ * Enable/disable a particular machine specific interrupt source.
+ * Note that this may affect other interrupts in case of a shared interrupt.
+ * This function should only be called for a _very_ short time to change some
+ * internal data, that may not be changed by the interrupt at the same time.
+ * int_(enable|disable)_irq calls may also be nested.
+ */
+
+void FRIO_enable_irq(unsigned int irq)
+{
+	unsigned long irq_val;
+
+	cli();
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (irq <= IRQ_CORETMR)
+	{
+		/* enable the interrupt */
+		irq_flags |= 1<<irq;
+		sti();
+		return;
+	}
+
+	/*
+ 	 * If it is the interrupt for peripheral,
+	 * we only enable it in SIC_IMASK register.
+	 * No need to change IMASK register of CORE,
+	 * since all of the IVG for peripherals was 
+ 	 * enabled in FRIO_init_IRQ()
+	 *
+ 	 * HuTao, Apr18 2003
+	 */
+	irq_val = 0;
+	switch (irq)
+	{
+	case IRQ_RTC:
+		irq_val = 0x1;
+		break;
+	case IRQ_USB:
+		irq_val = 0x4;
+		break;
+	case IRQ_UART0:
+		irq_val = 0x0c00;	/* Enable  UART0 TX and RX intrs */
+		break;
+	case IRQ_UART1:
+		irq_val = 0x3000;	/* Enable  UART1 TX and Rx intrs */
+		break;
+	case IRQ_SPORT0:
+		irq_val = 0x30;		/* Enalbe SPORT0 TX and RX intrs */
+		break;
+	case IRQ_SPORT1:
+		irq_val = 0xc0;		/* Enable SPORT1 TX and RX intrs */
+		break;
+	case IRQ_SPI0:
+		irq_val = 0x100;	
+		break;
+	case IRQ_SPI1:
+		irq_val = 0x200;
+		break;
+
+#ifdef CONFIG_PCI
+	
+	case IRQ_PCI_INTA:
+		PCI_ICTL |= 0x1;
+		break;
+
+	case IRQ_PCI_INTB:
+		PCI_ICTL |= 0x2;
+		break;
+
+	case IRQ_PCI_INTC:
+		PCI_ICTL |= 0x4;
+		break;
+
+	case IRQ_PCI_INTD:
+		PCI_ICTL |= 0x8;
+		break;
+#endif /* CONFIG_PCI */
+
+	case IRQ_TMR0:
+		irq_val = 0x4000;
+		break;
+	case IRQ_TMR1:
+		irq_val = 0x8000;
+		break;
+	case IRQ_TMR2:
+		irq_val = 0x10000;
+		break;
+	case IRQ_MEM_DMA:
+		irq_val = 0x80000;
+		break;
+	case IRQ_PROG_INTA:
+		irq_val = 0x20000;
+		break;
+	case IRQ_PROG_INTB:
+		irq_val = 0x40000;
+		break;
+	default:
+		printk("Unsupported peripheral IRQ!\n");
+		break;
+	
+	}
+
+#ifdef CONFIG_PUB
+   	*(unsigned volatile long *)(SIC_MASK_ADDR) &= (~irq_val) ;
+#else
+   	*(unsigned volatile long *)(SIC_MASK_ADDR) |= irq_val ;
+#endif 
+	sti();
+
+}
+
+void FRIO_disable_irq(unsigned int irq)
+{
+	unsigned long irq_val;
+
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (irq < IRQ_CORETMR)
+	{
+		cli();
+		irq_flags &= ~(1<<irq);
+		sti();
+		return;
+	}
+
+	/*
+ 	 * If it is the interrupt for peripheral,
+	 * we only disable it in SIC_IMASK register.
+	 * No need to change IMASK register of CORE,
+	 * since all of the IVG for peripherals was 
+ 	 * enabled in FRIO_init_IRQ()
+	 *
+ 	 * HuTao, Apr18 2003
+	 */
+	irq_val = 0;
+	switch (irq)
+	{
+	case IRQ_RTC:
+		irq_val = 0x1;
+		break;
+	case IRQ_USB:
+		irq_val = 0x4;
+		break;
+	case IRQ_UART0:
+		irq_val = 0x0c00;	/* Enable  UART0 TX and RX intrs */
+		break;
+	case IRQ_UART1:
+		irq_val = 0x3000;	/* Enable  UART1 TX and Rx intrs */
+		break;
+	case IRQ_SPORT0:
+		irq_val = 0x30;		/* Enalbe SPORT0 TX and RX intrs */
+		break;
+	case IRQ_SPORT1:
+		irq_val = 0xc0;		/* Enable SPORT1 TX and RX intrs */
+		break;
+	case IRQ_SPI0:
+		irq_val = 0x100;	
+		break;
+	case IRQ_SPI1:
+		irq_val = 0x200;
+		break;	
+
+#ifdef CONFIG_PCI
+
+	case IRQ_PCI_INTA:
+		PCI_ICTL &= ~0x1;
+		break;
+
+	case IRQ_PCI_INTB:
+		PCI_ICTL &= ~0x2;
+		break;
+
+	case IRQ_PCI_INTC:
+		PCI_ICTL &= ~0x4;
+		break;
+
+	case IRQ_PCI_INTD:
+		PCI_ICTL &= ~0x8;
+		break;
+
+#endif /* CONFIG_PCI */
+
+	case IRQ_TMR0:
+		irq_val = 0x4000;
+		break;
+	case IRQ_TMR1:
+		irq_val = 0x8000;
+		break;
+	case IRQ_TMR2:
+		irq_val = 0x10000;
+		break;
+	case IRQ_MEM_DMA:
+		irq_val = 0x80000;
+		break;
+	case IRQ_PROG_INTA:
+		irq_val = 0x20000;
+		break;
+	case IRQ_PROG_INTB:
+		irq_val = 0x40000;
+		break;
+	default:
+		printk("Unsupported peripheral IRQ!\n");
+		break;
+	}
+
+	cli();
+
+#ifdef CONFIG_PUB
+   	*(unsigned volatile long *)(SIC_MASK_ADDR) |= irq_val; 
+#else
+   	*(unsigned volatile long *)(SIC_MASK_ADDR) &= (~irq_val); 
+#endif
+	sti();
+
+}
+
+void  call_isr(int irq, struct pt_regs * fp)
+{
+	if(int_irq_list[irq]->handler)
+	    int_irq_list[irq]->handler(irq,int_irq_list[irq]->dev_id, fp);
+	else 
+	    printk("unregistered interrupt %d\n", irq); 
+}
+
+void FRIO_do_irq(int vec, struct pt_regs *fp)
+{
+    /*
+     * We will check the SIC_IPEND to determine if it is
+     * the peripherals' interrupt.
+     * 
+     * HuTao, Apr18 2003
+     */
+    if (vec <= IRQ_CORETMR)
+    {	
+	 call_isr(vec, fp);
+	 return;
+    }
+
+    switch (vec)
+    {
+	/* RTC, USB and PCI */ 
+	case 7:
+		/* TODO: handle the case all intr occur at the same time */
+
+		if ((SIC_ISR & 0x1) && (SIC_MASK & 0x1))
+			call_isr(IRQ_RTC, fp);
+		
+		if ((SIC_ISR & 0x4) && (SIC_MASK & 0x4))
+			call_isr(IRQ_USB, fp);
+
+		if ((SIC_ISR & 0x8) && (SIC_MASK & 0x8))
+		{
+		#ifndef CONFIG_PCI
+			printk("PCI intr detected, however PCI NOT configured!\n"); 
+		#else /* CONFIG_PCI */
+			unsigned long stat;
+			
+			stat = PCI_STAT;
+			PCI_STAT = 0xffffffff;
+			asm("ssync;");
+
+			if ((stat & 0x1) && (PCI_ICTL & 0x1))
+				call_isr(IRQ_PCI_INTA, fp);
+
+			if ((stat & 0x2) && (PCI_ICTL & 0x2))
+				call_isr(IRQ_PCI_INTB, fp);
+			
+			if ((stat & 0x4) && (PCI_ICTL & 0x4))
+				call_isr(IRQ_PCI_INTC, fp);
+
+			if ((stat & 0x8) && (PCI_ICTL & 0x8))
+				call_isr(IRQ_PCI_INTD, fp);
+
+		#endif /* CONFIG_PCI */
+		}
+
+		break;
+
+
+	/* SPORT0 TX/RX, SPORT1 TX/RX */
+	case 8:
+		if ((SIC_ISR & 0x30) && (SIC_MASK & 0x30))
+			call_isr(IRQ_SPORT0, fp);
+		
+		if ((SIC_ISR & 0xc0) && (SIC_MASK & 0xc0))
+			call_isr(IRQ_SPORT1, fp);	/* SPORT TX/RX */
+		break;
+
+		
+	/* SPI0 and SPI1 */	
+	case 9:
+		if ((SIC_ISR & 0x100) && (SIC_MASK & 0x100))
+			call_isr(IRQ_SPI0, fp);
+
+		if ((SIC_ISR & 0x200) && (SIC_MASK & 0x200))
+			call_isr(IRQ_SPI1, fp);
+		break;
+
+	/* UART0/1, TX/RX */
+	case 10:
+		if ((SIC_ISR & 0xc00) && (SIC_MASK & 0xc00))
+			call_isr(IRQ_UART0, fp);
+
+		if ((SIC_ISR & 0x3000) && (SIC_MASK & 0x3000))
+			call_isr(IRQ_UART1, fp);	
+		break;
+
+	/* Timer0/1/2 */	
+	case 11:
+		if ((SIC_ISR & 0x4000) && (SIC_MASK & 0x4000))
+			call_isr(IRQ_TMR0, fp);
+
+		if ((SIC_ISR & 0x8000) && (SIC_MASK & 0x8000))
+			call_isr(IRQ_TMR1, fp);
+
+		if ((SIC_ISR & 0x10000) && (SIC_MASK & 0x10000))
+			call_isr(IRQ_TMR2, fp);
+		break;	
+
+	/* PROG A and PROG B */
+	case 12:
+		if ((SIC_ISR & 0x20000) && (SIC_MASK & 0x20000))
+			call_isr(IRQ_PROG_INTA, fp);
+		
+		if ((SIC_ISR & 0x40000) && (SIC_MASK & 0x40000))
+			call_isr(IRQ_PROG_INTB, fp);
+		break;
+
+	/* Memory DMA and Watch Dog */
+	case 13:
+		if ((SIC_ISR & 0x80000) && (SIC_MASK & 0x80000))
+			call_isr(IRQ_MEM_DMA, fp);
+		
+		if ((SIC_ISR & 0x100000) && (SIC_MASK & 0x100000))
+			call_isr(IRQ_WATCH, fp);
+		break;
+	
+    }
+}
+
+int FRIO_get_irq_list(char *buf)
+{
+	int i, len = 0;
+	irq_node_t *node;
+
+	len += sprintf(buf+len, "Internal Blackfin interrupts\n");
+
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		if (!(node = int_irq_list[i]))
+			continue;
+		if (!(node->handler))
+			continue;
+
+		len += sprintf(buf+len, " %2d: %10u    %s\n", i,
+		               int_irq_count[i], int_irq_list[i]->devname);
+	}
+	return len;
+}
+
+void config_FRIO_irq(void)
+{
+	mach_default_handler = NULL;
+	mach_init_IRQ        = FRIO_init_IRQ;
+	mach_request_irq     = FRIO_request_irq;
+	mach_free_irq        = FRIO_free_irq;
+	mach_enable_irq      = FRIO_enable_irq;
+	mach_disable_irq     = FRIO_disable_irq;
+	mach_get_irq_list    = FRIO_get_irq_list;
+	mach_process_int     = FRIO_do_irq;
+}
diff -urN linux-2.4.29/arch/blackfin/platform/535/Makefile linux-2.4.29-uc1/arch/blackfin/platform/535/Makefile
--- linux-2.4.29/arch/blackfin/platform/535/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/Makefile	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,30 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o traps.o ints.o interrupt.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S $(BOARD)/bootlogo.rh
+
+entry.o: entry.S frio_defs.h
+
+frio_defs.h: ../../kernel/frio_defs.c ../../kernel/frio_defs.head
+	rm -f frio_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/frio_defs.c
+	cp ../../kernel/frio_defs.head frio_defs.h
+	grep '^#define' frio_defs.s >> frio_defs.h
+	rm frio_defs.s
+-include frio_defs.d
+
+$(BOARD)/bootlogo.rh: $(BOARD)/bootlogo.h
+	perl tools/bootlogo.pl < $(BOARD)/bootlogo.h > $(BOARD)/bootlogo.rh
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/blackfin/platform/535/peng.pl linux-2.4.29-uc1/arch/blackfin/platform/535/peng.pl
--- linux-2.4.29/arch/blackfin/platform/535/peng.pl	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/peng.pl	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,10 @@
+
+$_ = join("", <>);
+
+s/(0x[0-9a-f]{2})/sprintf("0x%.2x",ord(pack("b8",unpack("B8",chr(hex($1))))))/gei;
+
+s/^ /	.byte /gm;
+s/[,};]+$//gm;
+s/^static.*//gm;
+
+print $_;
diff -urN linux-2.4.29/arch/blackfin/platform/535/Rules.make linux-2.4.29-uc1/arch/blackfin/platform/535/Rules.make
--- linux-2.4.29/arch/blackfin/platform/535/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/Rules.make	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,94 @@
+#
+# ADI/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 2002  Metrowerks, Inc. <mwaddel@metrowerks.ca> 
+# Copyright (c) 2000,2001  Lineo, Inc. <jeff@lineo.ca> 
+# Copyright (c) 1998,1999  D. Jeff Dionne <jeff@uclinux.org>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+#
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+INCGCC = $(GCC_DIR)/include
+#LIBGCC = $(GCC_DIR)/000/libgcc.a
+
+CFLAGS := -fno-builtin -DNO_CACHE $(CFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -D__ELF__ -DMAGIC_ROM_PTR -DNO_FORGET -DUTS_SYSNAME='"uClinux"' -D__linux__ 
+AFLAGS := $(AFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME='"uClinux"' -Wa
+
+ifndef CONFIG_FULLDEBUG
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+else
+LINKFLAGS = -S -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+endif
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+
+
+
+
+#########   Temp modification: Tonyko   ############
+#CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+
+CORE_FILES := arch/$(ARCH)/kernel/process.o arch/$(ARCH)/kernel/traps.o \
+	      arch/$(ARCH)/kernel/ptrace.o  arch/$(ARCH)/kernel/sys_frio.o \
+              arch/$(ARCH)/kernel/time.o    arch/$(ARCH)/kernel/semaphore.o \
+              arch/$(ARCH)/kernel/setup.o   arch/$(ARCH)/kernel/frio_ksyms.o \
+              arch/$(ARCH)/mm/init.o        arch/$(ARCH)/mm/fault.o \
+              arch/$(ARCH)/mm/memory.o      arch/$(ARCH)/mm/kmap.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/entry.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/config.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/signal.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/interrupt.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/traps.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/ints.o $(CORE_FILES)
+
+
+LIBS += arch/$(ARCH)/lib/lib.a
+
+ifdef CONFIG_FRAMEBUFFER
+SUBDIRS := $(SUBDIRS) arch/$(ARCH)/console
+ARCHIVES := $(ARCHIVES) arch/$(ARCH)/console/console.a
+endif
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+romfs.s19: romfs.img arch/$(ARCH)/empty.o
+	$(CROSS_COMPILE)objcopy -v -R .text -R .data -R .bss --add-section=.fs=romfs.img --adjust-section-vma=.fs=0xa0000 arch/$(ARCH)/empty.o romfs.s19
+	$(CROSS_COMPILE)objcopy -O srec romfs.s19
+
+linux.data: linux
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.romvec --remove-section=.text --remove-section=.ramvec --remove-section=.bss --remove-section=.eram linux linux.data
+
+linux.text: linux
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.ramvec --remove-section=.bss --remove-section=.data --remove-section=.eram --set-section-flags=.romvec=CONTENTS,ALLOC,LOAD,READONLY,CODE linux linux.text
+
+romfs.img:
+	echo creating a vmlinux rom image without root filesystem!
+
+linux.bin: linux.text linux.data romfs.img
+	if [ -f romfs.img ]; then\
+		cat linux.text linux.data romfs.img > linux.bin;\
+	else\
+		cat linux.text linux.data > linux.bin;\
+	fi
+
+linux.trg linux.rom: linux.bin
+	perl arch/$(ARCH)/platform/$(PLATFORM)/tools/fixup.pl
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f arch/$(ARCH)/platform/$(PLATFORM)/m68k_defs.h
+	rm -f linux.text linux.data linux.bin linux.rom linux.trg
+	rm -f linux.s19 romfs.s19
+	rm -f linux.img romdisk.img
diff -urN linux-2.4.29/arch/blackfin/platform/535/signal.c linux-2.4.29-uc1/arch/blackfin/platform/535/signal.c
--- linux-2.4.29/arch/blackfin/platform/535/signal.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/signal.c	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,734 @@
+/*
+ *  linux/arch/frionommu/kernel/signal.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
+ * Atari :-) Current limitation: Only one sigstack can be active at one time.
+ * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
+ * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
+ * signal handlers!
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/highuid.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/traps.h>
+#include <asm/ucontext.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage long sys_wait4(pid_t pid, unsigned int *stat_addr,
+			 int options, struct rusage *ru);
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
+
+struct sigframe
+{
+	char *pretcode;
+	int sig;
+	int code;
+	struct sigcontext *psc;
+	char retcode[8];
+	unsigned long extramask[_NSIG_WORDS-1];
+	struct sigcontext sc;
+};
+
+struct rt_sigframe
+{
+	char *pretcode;
+	int sig;
+	struct siginfo *pinfo;
+	void *puc;
+	char retcode[8];
+	struct siginfo info;
+	struct ucontext uc;
+};
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ *
+ * ??? input entry: r3 of pt_regs
+ */
+asmlinkage int do_sigsuspend(struct pt_regs *regs)
+{
+	old_sigset_t mask = regs->r3;	/* old_sigset_t: unsigned long */
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending(current);
+
+	regs->r0 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+do_rt_sigsuspend(struct pt_regs *regs)
+{
+	sigset_t *unewset = (sigset_t *)regs->r1;
+	size_t sigsetsize = (size_t)regs->r2;
+	/* ??? need change for the exact regs  */
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending(current);
+
+	regs->r0 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int 
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+{
+	return do_sigaltstack(uss, uoss, rdusp());
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ *
+ * Keep the return code on the stack quadword aligned!
+ * That makes the cache flush below easier.
+ */
+
+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
+{
+	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+		return -EFAULT;
+	if (from->si_code < 0)
+		return __copy_to_user(to, from, sizeof(siginfo_t));
+	else {
+		int err;
+
+		/* If you change siginfo_t structure, please be sure
+		   this code is fixed accordingly.
+		   It should never copy any pad contained in the structure
+		   to avoid security leaks, but must copy the generic
+		   3 ints plus the relevant union member.  */
+		err = __put_user(from->si_signo, &to->si_signo);
+		err |= __put_user(from->si_errno, &to->si_errno);
+		err |= __put_user((short)from->si_code, &to->si_code);
+		/* First 32bits of unions are always present.  */
+		err |= __put_user(from->si_pid, &to->si_pid);
+		switch (from->si_code >> 16) {
+		case __SI_FAULT >> 16:
+			break;
+		case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+			err |= __put_user(from->si_status, &to->si_status);
+		default:
+			err |= __put_user(from->si_uid, &to->si_uid);
+			break;
+		/* case __SI_RT: This is not generated by the kernel as of now.  */
+		}
+		return err;
+	}
+}
+
+
+static inline int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp, int *pd0)
+{
+	struct sigcontext context;
+	int err = 0;
+
+	/* get previous context */
+	if (copy_from_user(&context, usc, sizeof(context)))
+		goto badframe;
+	
+	/* restore passed registers */
+	regs->r1 = context.sc_r1;
+	regs->p0 = context.sc_p0;
+	regs->p1 = context.sc_p1;
+	regs->seqstat = context.sc_seqstat;
+	regs->pc = context.sc_pc;
+	regs->orig_r0 = -1;		/* disable syscall checks */
+	wrusp(context.sc_usp);
+
+	*pd0 = context.sc_r0;
+	return err;
+
+badframe:
+	return 1;
+}
+
+static inline int
+rt_restore_ucontext(struct pt_regs *regs, struct ucontext *uc, int *pd0)
+{
+	int temp;
+	greg_t *gregs = uc->uc_mcontext.gregs;
+	unsigned long usp;
+	int err;
+
+	err = __get_user(temp, &uc->uc_mcontext.version);
+	if (temp != MCONTEXT_VERSION)
+		goto badframe;
+	/* restore passed registers */
+	err |= __get_user(regs->r0, &gregs[0]);
+	err |= __get_user(regs->r1, &gregs[1]);
+	err |= __get_user(regs->r2, &gregs[2]);
+	err |= __get_user(regs->r3, &gregs[3]);
+	err |= __get_user(regs->r4, &gregs[4]);
+	err |= __get_user(regs->r5, &gregs[5]);
+	err |= __get_user(regs->r6, &gregs[6]);
+	err |= __get_user(regs->r7, &gregs[7]);
+	err |= __get_user(regs->p0, &gregs[8]);
+	err |= __get_user(regs->p1, &gregs[9]);
+	err |= __get_user(regs->p2, &gregs[10]);
+	err |= __get_user(regs->p3, &gregs[11]);
+	err |= __get_user(regs->p4, &gregs[12]);
+	err |= __get_user(regs->p5, &gregs[13]);
+	err |= __get_user(usp, &gregs[14]);
+	wrusp(usp);
+	err |= __get_user(regs->a0w, &gregs[15]);
+	err |= __get_user(regs->a1w, &gregs[16]);
+	err |= __get_user(regs->a0x, &gregs[17]);
+	err |= __get_user(regs->a1x, &gregs[18]);
+	err |= __get_user(regs->astat, &gregs[19]);
+	err |= __get_user(regs->rets, &gregs[20]);
+	regs->orig_r0 = -1;		/* disable syscall checks */
+
+	if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
+		goto badframe;
+
+	*pd0 = regs->r0;
+	return err;
+
+badframe:
+	return 1;
+}
+
+asmlinkage int do_sigreturn(unsigned long __unused)
+{
+	__label__ badframe;
+
+	struct pt_regs *regs = (struct pt_regs *) __unused;
+	unsigned long usp = rdusp();
+	struct sigframe *frame = (struct sigframe *)(usp);// - 4);
+	/* how is transfered ???   Tony */ 
+
+	sigset_t set;
+	int r0;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__get_user(set.sig[0], &frame->sc.sc_mask))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	current->blocked = set;
+	recalc_sigpending(current);
+
+	if (restore_sigcontext(regs, &frame->sc, frame + 1, &r0))
+		goto badframe;
+	return r0;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int do_rt_sigreturn(unsigned long __unused)
+{
+	struct pt_regs *regs = (struct pt_regs *) &__unused;
+	unsigned long usp = rdusp();
+	struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
+	/* how is transfered ???   Tony	*/
+
+	sigset_t set;
+	int d0;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	current->blocked = set;
+	recalc_sigpending(current);
+	
+	if (rt_restore_ucontext(regs, &frame->uc, &d0))
+		goto badframe;
+	return d0;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+			     unsigned long mask)
+{
+	sc->sc_mask = mask;
+	sc->sc_usp = rdusp();
+	sc->sc_r0 = regs->r0;
+	sc->sc_r1 = regs->r1;
+	sc->sc_p0 = regs->p0;
+	sc->sc_p1 = regs->p1;
+	sc->sc_seqstat = regs->seqstat;
+	sc->sc_pc = regs->pc;
+}
+
+static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
+{
+	greg_t *gregs = uc->uc_mcontext.gregs;
+	int err = 0;
+
+	err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
+	err |= __put_user(regs->r0, &gregs[0]);
+	err |= __put_user(regs->r1, &gregs[1]);
+	err |= __put_user(regs->r2, &gregs[2]);
+	err |= __put_user(regs->r3, &gregs[3]);
+	err |= __put_user(regs->r4, &gregs[4]);
+	err |= __put_user(regs->r5, &gregs[5]);
+	err |= __put_user(regs->r6, &gregs[6]);
+	err |= __put_user(regs->r7, &gregs[7]);
+	err |= __put_user(regs->p0, &gregs[8]);
+	err |= __put_user(regs->p1, &gregs[9]);
+	err |= __put_user(regs->p2, &gregs[10]);
+	err |= __put_user(regs->p3, &gregs[11]);
+	err |= __put_user(regs->p4, &gregs[12]);
+	err |= __put_user(regs->p5, &gregs[13]);
+	err |= __put_user(rdusp() , &gregs[14]);
+	err |= __put_user(regs->a0w, &gregs[15]);
+	err |= __put_user(regs->a1w, &gregs[16]);
+	err |= __put_user(regs->a0x, &gregs[17]);
+	err |= __put_user(regs->a1x, &gregs[18]);
+	err |= __put_user(regs->astat, &gregs[19]);
+	err |= __put_user(regs->rets, &gregs[20]);
+
+	return err;
+}
+
+static inline void push_cache (unsigned long vaddr)
+{
+}
+
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	unsigned long usp;
+
+	/* Default to using normal stack.  */
+	usp = rdusp();
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if (ka->sa.sa_flags & SA_ONSTACK) {
+		if (!on_sig_stack(usp))
+			usp = current->sas_ss_sp + current->sas_ss_size;
+	}
+	return (void *)((usp - frame_size) & -8UL);
+}
+
+static void setup_frame (int sig, struct k_sigaction *ka,
+			 sigset_t *set, struct pt_regs *regs)
+{
+	struct sigframe *frame;
+	struct sigcontext context;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	err |= __put_user((current->exec_domain
+			   && current->exec_domain->signal_invmap
+			   && sig < 32
+			   ? current->exec_domain->signal_invmap[sig]
+			   : sig),
+			  &frame->sig);
+
+	err |= __put_user(&frame->sc, &frame->psc);
+
+	setup_sigcontext(&context, regs, set->sig[0]);
+	err |= copy_to_user (&frame->sc, &context, sizeof(context));
+
+	/* Set up to return from userspace.  */
+	err |= __put_user(frame->retcode, &frame->pretcode);
+	/* r5 = 0x77(z); excpt 0x0; -STchen*/
+	err |= __put_user(0x85, &(frame->retcode[0]));
+	err |= __put_user(0xe1, &(frame->retcode[1]));
+	err |= __put_user(0x77, &(frame->retcode[2]));
+	err |= __put_user(0x00, &(frame->retcode[3]));
+	err |= __put_user(0xa0, &(frame->retcode[4]));
+	err |= __put_user(0x00, &(frame->retcode[5]));
+
+	if (err)
+		goto give_sigsegv;
+
+	push_cache ((unsigned long) &frame->retcode);
+
+	/* Set up registers for signal handler */
+	wrusp ((unsigned long) frame);
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+	regs->rets = (unsigned long) (frame->retcode);
+
+adjust_stack:
+
+#if NEEDED
+	/* Prepare to skip over the extra stuff in the exception frame.  */
+	if (regs->stkadj) {
+		struct pt_regs *tregs =
+			(struct pt_regs *)((ulong)regs + regs->stkadj);
+#if DEBUG
+		printk("Performing stackadjust=%04x\n", regs->stkadj);
+#endif
+		/* This must be copied with decreasing addresses to
+                   handle overlaps.  */
+		tregs->pc = regs->pc;
+		tregs->seqstat = regs->seqstat;
+	}
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+	goto adjust_stack;
+}
+
+static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
+			    sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	err |= __put_user((current->exec_domain
+			   && current->exec_domain->signal_invmap
+			   && sig < 32
+			   ? current->exec_domain->signal_invmap[sig]
+			   : sig),
+			  &frame->sig);
+	err |= __put_user(&frame->info, &frame->pinfo);
+	err |= __put_user(&frame->uc, &frame->puc);
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+			  &frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(rdusp()),
+			  &frame->uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= rt_setup_ucontext(&frame->uc, regs);
+	err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	/* Set up to return from userspace.  */
+	err |= __put_user(frame->retcode, &frame->pretcode);
+	/* moveq #,d0; notb d0; trap #0 */
+	err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
+			  (long *)(frame->retcode + 0));
+	err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
+
+	if (err)
+		goto give_sigsegv;
+
+	push_cache ((unsigned long) &frame->retcode);
+
+	/* Set up registers for signal handler */
+	wrusp ((unsigned long) frame);
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+
+adjust_stack:
+
+#if NEEDED
+	/* Prepare to skip over the extra stuff in the exception frame.  */
+	if (regs->stkadj) {
+		struct pt_regs *tregs =
+			(struct pt_regs *)((ulong)regs + regs->stkadj);
+#if DEBUG
+		printk("Performing stackadjust=%04x\n", regs->stkadj);
+#endif
+		/* This must be copied with decreasing addresses to
+                   handle overlaps.  */
+		tregs->pc = regs->pc;
+		tregs->seqstat = regs->seqstat;
+	}
+#endif /* NEEDED */
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+	goto adjust_stack;
+}
+
+static inline void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
+{
+	switch (regs->r0) {
+	case -ERESTARTNOHAND:
+		if (!has_handler)
+			goto do_restart;
+		regs->r0 = -EINTR;
+		break;
+
+	case -ERESTARTSYS:
+		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
+			regs->r0 = -EINTR;
+			break;
+		}
+	/* fallthrough */
+	case -ERESTARTNOINTR:
+	do_restart:
+		regs->r0 = regs->orig_r0;
+//		regs->pc -= 2; /* if minus 2 correct	*/
+		break;
+	}
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static void
+handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
+	      sigset_t *oldset, struct pt_regs *regs)
+{
+	/* are we from a system call? to see pt_regs->orig_r0 */
+	if (regs->orig_r0 >= 0)
+		/* If so, check system call restarting.. */
+		handle_restart(regs, ka, 1);
+
+	/* set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+	if (!(ka->sa.sa_flags & SA_NODEFER))
+		sigaddset(&current->blocked,sig);
+	recalc_sigpending(current);
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals
+ * that the kernel can handle, and then we build all the user-level signal
+ * handling stack-frames in one go after that.
+ */
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
+{
+	siginfo_t info;
+	struct k_sigaction *ka;
+
+	current->thread.esp0 = (unsigned long) regs;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	for (;;) {
+		int signr;
+
+		signr = dequeue_signal(&current->blocked, &info);
+
+		if (!signr)
+			break;
+
+		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			//regs->seqstat &= ~PS_T; /* Tony  */
+
+			/* Did we come from a system call? */
+			if (regs->orig_r0 >= 0) {
+				/* Restart the system call the same way as
+				   if the process were not traced.  */
+				struct k_sigaction *ka =
+					&current->sig->action[signr-1];
+				int has_handler =
+					(ka->sa.sa_handler != SIG_IGN &&
+					 ka->sa.sa_handler != SIG_DFL);
+				handle_restart(regs, ka, has_handler);
+			}
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code)) {
+			discard_frame:
+			    continue;
+			}
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				goto discard_frame;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD:
+			case SIGWINCH: case SIGURG:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP:
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				if (!(current->p_pptr->sig->action[SIGCHLD-1]
+				      .sa.sa_flags & SA_NOCLDSTOP))
+					notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGIOT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				sigaddset(&current->pending.signal, signr);
+				recalc_sigpending(current);
+				current->flags |= PF_SIGNALED;
+				do_exit(exit_code);
+				/* NOTREACHED */
+			}
+		}
+
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(signr, ka, &info, oldset, regs);
+		return 1;
+	}
+
+	/* Did we come from a system call? */
+	if (regs->orig_r0 >= 0)
+		/* Restart the system call - no handlers present */
+		handle_restart(regs, NULL, 0);
+
+	/* If we are about to discard some frame stuff we must copy
+	   over the remaining frame. */
+
+#if NEEDED
+	if (regs->stkadj) {
+		struct pt_regs *tregs =
+		  (struct pt_regs *) ((ulong) regs + regs->stkadj);
+
+		/* This must be copied with decreasing addresses to
+		   handle overlaps.  */
+		tregs->pc = regs->pc;
+		tregs->seqstat = regs->seqstat;
+	}
+#endif
+
+	return 0;
+}
+
+/************************ garbage of original m68k ***************/
diff -urN linux-2.4.29/arch/blackfin/platform/535/tools/bootlogo.pl linux-2.4.29-uc1/arch/blackfin/platform/535/tools/bootlogo.pl
--- linux-2.4.29/arch/blackfin/platform/535/tools/bootlogo.pl	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/tools/bootlogo.pl	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,10 @@
+
+$_ = join("", <>);
+
+s/(0x[0-9a-f]{2})/sprintf("0x%.2x",ord(pack("b8",unpack("B8",chr(hex($1))))))/gei;
+
+s/^ /	.byte /gm;
+s/[,};]+$//gm;
+s/^static.*//gm;
+
+print $_;
diff -urN linux-2.4.29/arch/blackfin/platform/535/tools/fixup.pl linux-2.4.29-uc1/arch/blackfin/platform/535/tools/fixup.pl
--- linux-2.4.29/arch/blackfin/platform/535/tools/fixup.pl	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/tools/fixup.pl	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,91 @@
+#!/usr/bin/perl
+
+#
+# Nasty piece of work, designed to translated linux.bin binary image
+# in to several different formats.
+# 
+# Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>,
+#                    The Silver Hammer Group, Ltd.
+#
+
+@CRC = (
+        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+        0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+        0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+        0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+        0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
+        0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
+        0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
+        0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
+        0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
+        0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
+        0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
+        0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
+        0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+        0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
+        0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
+        0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
+        0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
+        0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
+        0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
+        0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
+        0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
+        0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+        0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
+        0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
+        0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
+        0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+        0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
+        0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
+        0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
+        0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
+        0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
+        0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
+);
+
+sub CrcBlock {
+	my($data,$crc) = @_;
+	my($i);
+	printf "Crc of %d bytes\n", length($data);
+	for ($i=0;$i<length($data);$i++) {
+#		printf "crc = %d, Lookup = %d, CRC[] = %d\n", $crc,						($crc>>8) ^
+#						ord(substr($data,$i,1)),
+#$CRC[						($crc>>8) ^
+#						ord(substr($data,$i,1)) &
+#0xff];
+#
+
+		$crc = ($crc << 8) ^ $CRC[
+						((($crc>>8) & 0xff) ^
+						ord(substr($data,$i,1))) &
+						0xff
+					];
+		$crc &= 0xffff;
+	}
+	return $crc & 0xffff;
+}
+
+open(T,"<linux.bin");
+$/ = undef;
+
+$image = join('', <T>);
+close(T);
+
+$realLength = length($image);
+$image .= "\0" x (0x100000 - $realLength);
+
+$posOfCardLength = 108;
+$posOfChecksum = 112;
+#$crc = CrcBlock(substr($image, 0, $posOfChecksum), 0);
+#$crc = CrcBlock(substr($image, $posOfChecksum+2), $crc);
+
+#substr($image, $posOfCardLength, 4) = pack("N", length($image));
+#substr($image, $posOfChecksum, 2) = pack("n", $crc);
+
+open(O,">linux.trg");
+print O substr($image, 0x10000, (($realLength - 0x10000) + 0xffff) & ~0xffff);
+close(O);
+
+open(O, ">linux.rom");
+print O $image;
+close(O);
diff -urN linux-2.4.29/arch/blackfin/platform/535/traps.c linux-2.4.29-uc1/arch/blackfin/platform/535/traps.c
--- linux-2.4.29/arch/blackfin/platform/535/traps.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/blackfin/platform/535/traps.c	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,209 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/traps.c -- general exception handling code
+ *
+ * Cloned from Linux/m68k.
+ *
+ * No original Copyright holder listed,
+ * Probabily original (C) Roman Zippel (assigned DJD, 1999)
+ *
+ * Copyright 2003 Metrowerks - for Blackfin
+ * Copyright 2000-2001 Lineo, Inc. D. Jeff Dionne <jeff@lineo.ca>
+ * Copyright 1999-2000 D. Jeff Dionne, <jeff@uclinux.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+// This #define is to cause the variables interruptFlags and interruptEnable
+//  to be defined ...MaTed---
+#define DEF_INTERRUPT_FLAGS 1
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/errno.h>
+#include <linux/irq.h>
+
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+
+/* table for system interrupt handlers */
+static irq_handler_t irq_list[SYS_IRQS];
+
+static const char *default_names[SYS_IRQS] = {
+	"spurious int", "int1 handler", "int2 handler", "int3 handler",
+	"int4 handler", "int5 handler", "int6 handler", "int7 handler"
+};
+
+/* The number of spurious interrupts */
+volatile unsigned int num_spurious;
+
+#define NUM_IRQ_NODES 16
+static irq_node_t nodes[NUM_IRQ_NODES];
+
+/*
+ * void init_IRQ(void)
+ *
+ * Parameters:	None
+ *
+ * Returns:	Nothing
+ *
+ * This function should be called during kernel startup to initialize
+ * the IRQ handling routines.
+ */
+
+void init_IRQ(void)
+{
+	mach_init_IRQ ();
+}
+
+irq_node_t *new_irq_node(void)
+{
+	irq_node_t *node;
+	short i;
+
+	for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--)
+		if (!node->handler)
+			return node;
+
+	printk ("new_irq_node: out of nodes\n");
+	return NULL;
+}
+
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq)
+		return mach_request_irq(irq, handler, flags, devname, dev_id);
+
+	if (irq < IRQ_EMU || irq > IRQ_SW_INT2) {
+		printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+	if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
+		if (irq_list[irq].flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+	}
+	irq_list[irq].handler = handler;
+	irq_list[irq].flags   = flags;
+	irq_list[irq].dev_id  = dev_id;
+	irq_list[irq].devname = devname;
+	return 0;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq) {
+		mach_free_irq(irq, dev_id);
+		return;
+	}
+
+	if (irq < IRQ_EMU || irq > IRQ_SW_INT2) {
+		printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (irq_list[irq].dev_id != dev_id)
+		printk("%s: Removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, irq_list[irq].devname);
+
+	if (mach_default_handler)
+		irq_list[irq].handler = (*mach_default_handler)[irq];
+	else
+		irq_list[irq].handler = NULL;
+	irq_list[irq].flags   = IRQ_FLG_STD;
+	irq_list[irq].dev_id  = NULL;
+	irq_list[irq].devname = default_names[irq];
+}
+
+unsigned long probe_irq_on (void)
+{
+	return 0;
+}
+
+int probe_irq_off (unsigned long irqs)
+{
+	return 0;
+}
+
+asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
+{
+                if (mach_process_int)
+                        mach_process_int(vec, fp);
+                else
+                        panic("Can't process interrupt vector %ld\n", vec);
+                return;
+}
+
+int get_irq_list(char *buf)
+{
+        int i, len = 0;
+	
+        /* autovector interrupts */
+        if (mach_default_handler) {
+                for (i = 0; i < SYS_IRQS; i++) {
+                       len += sprintf(buf+len, "auto %2d: %10u ", i,
+		       i ? kstat.irqs[0][i] : num_spurious);
+                       len += sprintf(buf+len, "  ");
+                       len += sprintf(buf+len, "%s\n", irq_list[i].devname);
+
+		}
+        }
+        len += mach_get_irq_list(buf+len);
+        return len;
+}
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+
+void dump(struct pt_regs *fp)
+{
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk("\nCURRENT PROCESS:\n\n");
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk("USER-STACK=%08x\n\n",
+			(int) current->mm->start_stack);
+	}
+
+	printk("PC: %08lx\n", fp->pc);
+	printk("SEQSTAT: %08lx    SP: %08lx\n", (long) fp->seqstat, (long) fp);
+	printk("R0: %08lx    R1: %08lx    R2: %08lx    R3: %08lx\n",
+		fp->r0, fp->r1, fp->r2, fp->r3);
+	printk("R4: %08lx    R5: %08lx    R6: %08lx    R7: %08lx\n",
+		fp->r4, fp->r5, fp->r6, fp->r7);
+	printk("P0: %08lx    P1: %08lx    P2: %08lx    P3: %08lx\n",
+		fp->p0, fp->p1, fp->p2, fp->p3);
+	printk("P4: %08lx    P5: %08lx    FP: %08lx\n",
+		fp->p4, fp->p5, fp->fp);
+	printk("A0.w: %08lx    A0.x: %08lx    A1.w: %08lx    A1.x: %08lx\n",
+		fp->a0w, fp->a0x, fp->a1w, fp->a1x);
+
+	printk("\nUSP: %08lx   ASTAT: %08lx\n",
+		rdusp(), fp->astat);
+
+	printk("\n\n");
+}
diff -urN linux-2.4.29/arch/e1nommu/Boards.mk linux-2.4.29-uc1/arch/e1nommu/Boards.mk
--- linux-2.4.29/arch/e1nommu/Boards.mk	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/Boards.mk	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,16 @@
+# Copyright (C) 2002 GDT, Yiannis Mitsos<yiannis.mitsos@gdt.gr>
+# Put definitions for platforms and boards in here.
+
+ifdef CONFIG_E132XS
+PLATFORM := E132XS
+
+ifdef CONFIG_E132XS_BOARD
+BOARD := E132XS_BOARD
+endif
+
+endif
+
+
+export BOARD
+export PLATFORM
+
diff -urN linux-2.4.29/arch/e1nommu/boot/Makefile linux-2.4.29-uc1/arch/e1nommu/boot/Makefile
--- linux-2.4.29/arch/e1nommu/boot/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/boot/Makefile	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,5 @@
+clean:
+	rm -f *.[oa]
+
+dep depend:
+	:
diff -urN linux-2.4.29/arch/e1nommu/config.in linux-2.4.29-uc1/arch/e1nommu/config.in
--- linux-2.4.29/arch/e1nommu/config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/config.in	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,355 @@
+#############################################################################
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+#
+# based mainly on the arch/i386/config.in and bit of the 2.4, m68knommu
+# config.in
+#
+#############################################################################
+
+mainmenu_name 'uClinux/Hyperstone (w/o MMU) Kernel Configuration'
+
+define_bool CONFIG_UCLINUX y
+define_bool CONFIG_UID16 y
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+
+############################################################################
+# temporary defines for new features
+# (haven't these people heard about feature-freezing within *one* release?)
+############################################################################
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+############################################################################
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+#############################################################################
+
+##mainmenu_option next_comment
+##comment 'Loadable module support'
+##bool 'Enable loadable module support' CONFIG_MODULES
+##if [ "$CONFIG_MODULES" = "y" ]; then
+##   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+##   bool '  Kernel module loader' CONFIG_KMOD
+##fi
+##endmenu
+
+define_bool CONFIG_MODULES n
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Processor type and features'
+
+define_bool CONFIG_HYPERSTONE y
+define_bool CONFIG_ARCH_HYPERSTONE y
+
+choice 'CPU' \
+	"E1-32XS	CONFIG_E132XS \
+	 E1-32XN	CONFIG_E132XN" 
+
+comment 'Platform'
+
+if [ "$CONFIG_E132XS" = "y" ]; then
+	define_bool CONFIG_E132XS_BOARD y
+fi
+
+int 'External Oscillator Frequency in MHz' CONFIG_HYPERSTONE_OSC_FREQ_MHZ 15
+
+choice 'Kernel executes from' \
+	"RAM	CONFIG_RAMKERNEL \
+	 ROM	CONFIG_ROMKERNEL" RAM
+
+bool 'Extra arguments in the command line' CONFIG_EXTRA_ARGS
+if [ "$CONFIG_EXTRA_ARGS" = "y" ]; then
+      string "Extra Arguments" CONFIG_EXTRA_ARGS_VARIABLES ""
+fi
+
+bool 'Embedded Serial Debug Console' CONFIG_EMBEDDED_SERIAL_CONSOLE
+if [ "$CONFIG_EMBEDDED_SERIAL_CONSOLE" = "y" ]; then
+	int 'Select chip select number' CONFIG_EMBEDDED_SERIAL_CONSOLE_CS 3
+fi
+
+bool 'External devices ?' CONFIG_EXTERNAL_DEVICES
+
+if [ "$CONFIG_EXTERNAL_DEVICES" = "y" ]; then
+bool 'I/O access to external devices' CONFIG_IO_ACCESS
+bool 'Enable E132XS CS89x0 Ethernet' CONFIG_HYPERSTONE_CS89X0
+if [ "$CONFIG_HYPERSTONE_CS89X0" = "y" ]; then
+	int 'Interrupt line number' CONFIG_HYPERSTONE_CS89X0_IRQ "1"
+   if [ "$CONFIG_IP_PNP" = "y" ]; then
+      string "Board IP" CONFIG_E132XS_BOARD_NET_BOARD_IP ""
+      string "Hostname" CONFIG_E132XS_BOARD_NET_HOSTNAME ""
+      string "Default Gateway" CONFIG_E132XS_BOARD_NET_DEFAULTGW ""
+      string "Netmask" CONFIG_E132XS_BOARD_NET_NETMASK ""
+   fi
+if [ "$CONFIG_IP_PNP" = "y" ]; then
+   # root on NFS enabled?
+   if [ "$CONFIG_ROOT_NFS" = "y" ]; then
+      string "NFS server:/root,options" CONFIG_E132XS_BOARD_NET_NFS_ROOT ""
+   fi
+fi
+
+fi
+fi
+
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'General setup'
+
+bool 'Networking support' CONFIG_NET
+bool 'SGI Visual Workstation support' CONFIG_VISWS
+define_bool CONFIG_VISWS n
+if [ "$CONFIG_VISWS" = "y" ]; then
+   define_bool CONFIG_X86_VISWS_APIC y
+   define_bool CONFIG_X86_LOCAL_APIC y
+   define_bool CONFIG_PCI y
+else
+   if [ "$CONFIG_SMP" = "y" ]; then
+      define_bool CONFIG_X86_IO_APIC y
+      define_bool CONFIG_X86_LOCAL_APIC y
+   fi
+   bool 'PCI support' CONFIG_PCI
+   define_bool CONFIG_PCI n
+   if [ "$CONFIG_PCI" = "y" ]; then
+      choice '  PCI access mode' \
+	"BIOS		CONFIG_PCI_GOBIOS	\
+	 Direct		CONFIG_PCI_GODIRECT	\
+	 Any		CONFIG_PCI_GOANY"	Any
+      if [ "$CONFIG_PCI_GOBIOS" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then
+         define_bool CONFIG_PCI_BIOS y
+      fi
+      if [ "$CONFIG_PCI_GODIRECT" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then
+         define_bool CONFIG_PCI_DIRECT y
+      fi
+   fi
+fi
+
+source drivers/pci/Config.in
+
+if [ "$CONFIG_VISWS" != "y" ]; then
+   bool 'MCA support' CONFIG_MCA
+fi
+
+bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+
+if [ "$CONFIG_HOTPLUG" = "y" ] ; then
+   source drivers/pcmcia/Config.in
+else
+   define_bool CONFIG_PCMCIA n
+fi
+
+bool 'System V IPC' CONFIG_SYSVIPC
+bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'Sysctl support' CONFIG_SYSCTL
+define_bool CONFIG_SYSCTL n
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   choice 'Kernel core (/proc/kcore) format' \
+	"ELF		CONFIG_KCORE_ELF	\
+	 A.OUT		CONFIG_KCORE_AOUT" ELF
+fi
+tristate 'Kernel support for flat binaries' CONFIG_BINFMT_FLAT
+tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
+tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF y
+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+
+bool 'Power Management support' CONFIG_PM
+
+dep_bool '  ACPI support' CONFIG_ACPI $CONFIG_PM
+if [ "$CONFIG_ACPI" != "n" ]; then
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      bool '    ACPI interpreter (EXPERIMENTAL)' CONFIG_ACPI_INTERPRETER
+      bool '    Enter S1 for sleep (EXPERIMENTAL)' CONFIG_ACPI_S1_SLEEP
+   fi
+fi
+
+dep_tristate '  Advanced Power Management BIOS support' CONFIG_APM $CONFIG_PM
+if [ "$CONFIG_APM" != "n" ]; then
+   bool '    Ignore USER SUSPEND' CONFIG_APM_IGNORE_USER_SUSPEND
+   bool '    Enable PM at boot time' CONFIG_APM_DO_ENABLE
+   bool '    Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE
+   bool '    Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK
+   bool '    RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT
+   bool '    Allow interrupts during APM BIOS calls' CONFIG_APM_ALLOW_INTS
+   bool '    Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF
+fi
+
+endmenu
+
+#############################################################################
+
+source drivers/mtd/Config.in
+
+source drivers/parport/Config.in
+
+source drivers/pnp/Config.in
+
+source drivers/block/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   source net/Config.in
+fi
+
+source drivers/telephony/Config.in
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'ATA/IDE/MFM/RLL support'
+
+tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+
+if [ "$CONFIG_IDE" != "n" ]; then
+  source drivers/ide/Config.in
+else
+  define_bool CONFIG_BLK_DEV_HD n
+fi
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'SCSI support'
+
+tristate 'SCSI support' CONFIG_SCSI
+
+if [ "$CONFIG_SCSI" != "n" ]; then
+   source drivers/scsi/Config.in
+fi
+endmenu
+
+#############################################################################
+
+source drivers/ieee1394/Config.in
+
+source drivers/message/i2o/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Network device support'
+
+   bool 'Network device support' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+      if [ "$CONFIG_ATM" = "y" ]; then
+         source drivers/atm/Config.in
+      fi
+   fi
+   endmenu
+fi
+
+source net/ax25/Config.in
+
+source net/irda/Config.in
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'ISDN subsystem'
+if [ "$CONFIG_NET" != "n" ]; then
+   tristate 'ISDN support' CONFIG_ISDN
+   if [ "$CONFIG_ISDN" != "n" ]; then
+      source drivers/isdn/Config.in
+   fi
+fi
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+
+ bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+define_bool CONFIG_CD_NO_IDESCSI n
+if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+   source drivers/cdrom/Config.in
+fi
+endmenu
+
+#############################################################################
+
+source drivers/char/Config.in
+
+
+#source drivers/misc/Config.in
+
+source fs/Config.in
+
+if [ "$CONFIG_VT" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Console drivers'
+   bool 'VGA text console' CONFIG_VGA_CONSOLE
+   define_bool CONFIG_VGA_CONSOLE n
+   bool 'Video mode selection support' CONFIG_VIDEO_SELECT
+   define_bool CONFIG_VIDEO_SELECT n
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
+      source drivers/video/Config.in
+   fi
+   endmenu
+fi
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Sound'
+
+tristate 'Sound card support' CONFIG_SOUND
+if [ "$CONFIG_SOUND" != "n" ]; then
+   source drivers/sound/Config.in
+fi
+endmenu
+
+#############################################################################
+
+source drivers/usb/Config.in
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+bool 'Full Symbolic/Source Debugging support' CONFIG_FULLDEBUG
+#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
+bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	bool 'Non power-of-2 kernel allocator (EXPERIMENTAL)' CONFIG_CONTIGUOUS_PAGE_ALLOC
+	dep_bool '  include /proc/mem_map' CONFIG_MEM_MAP $CONFIG_CONTIGUOUS_PAGE_ALLOC
+fi
+
+bool 'Kernel profiling support' CONFIG_PROFILE
+if [ "$CONFIG_PROFILE" = "y" ]; then
+  int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+  bool 'Use fast second timer for profiling' CONFIG_HIGHPROFILE
+fi
+
+if [ "$CONFIG_COLDFIRE" = "y" ]; then
+	bool 'Panic/Dump to FLASH' CONFIG_DUMPTOFLASH
+fi
+
+bool 'Suppress Kernel BUG Messages' CONFIG_NO_KERNEL_MSG
+
+bool 'Reduce kernel task size to 1 page' CONFIG_SMALL_TASKS
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_COLDFIRE" = "y" -a "$CONFIG_FULLDEBUG" = "n" ]; then
+    bool 'Disable BDM signals' CONFIG_BDM_DISABLE
+fi
+
+endmenu
+
+
+#############################################################################
+
+source lib/Config.in
+
+#############################################################################
diff -urN linux-2.4.29/arch/e1nommu/kernel/float_entry.S linux-2.4.29-uc1/arch/e1nommu/kernel/float_entry.S
--- linux-2.4.29/arch/e1nommu/kernel/float_entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/kernel/float_entry.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,40 @@
+/* File contains the floating point exceptions */
+
+.global _ExceptionFCVTD_Entry
+.global _ExceptionFCVT_Entry
+.global _ExceptionFCMPUD_Entry
+.global _ExceptionFCMPU_Entry
+.global _ExceptionFCMPD_Entry
+.global _ExceptionFCMP_Entry
+.global _ExceptionFDIVD_Entry
+.global _ExceptionFDIV_Entry
+.global _ExceptionFMULD_Entry
+.global _ExceptionFMUL_Entry
+.global _ExceptionFSUBD_Entry
+.global _ExceptionFSUB_Entry
+.global _ExceptionFADDD_Entry
+.global _ExceptionFADD_Entry
+
+.balign 4
+_ExceptionFCVTD_Entry:  movi PC, (long)FCVTDEntry
+_ExceptionFCVT_Entry:   movi PC, (long)FCVTEntry
+_ExceptionFCMPUD_Entry: movi PC, (long)FCMPUDEntry
+_ExceptionFCMPU_Entry:  movi PC, (long)FCMPUEntry
+_ExceptionFCMPD_Entry:  movi PC, (long)FCMPDEntry
+_ExceptionFCMP_Entry:   movi PC, (long)FCMPEntry
+_ExceptionFDIVD_Entry:  movi PC, (long)FDIVDEntry
+_ExceptionFDIV_Entry:   movi PC, (long)FDIVEntry
+_ExceptionFMULD_Entry:  movi PC, (long)FMULDEntry
+_ExceptionFMUL_Entry:   movi PC, (long)FMULEntry
+_ExceptionFSUBD_Entry:  movi PC, (long)FSUBDEntry
+_ExceptionFSUB_Entry:   movi PC, (long)FSUBEntry
+_ExceptionFADDD_Entry:  movi PC, (long)FADDDEntry
+_ExceptionFADD_Entry:   movi PC, (long)FADDEntry
+
+.global FloatErrorEntry
+.balign 4
+FloatErrorEntry:
+;	FRAME L0, L0
+;	CALL  L0, 0, _Handle_FP_Exception
+	TRAP  46
+	RET   PC, L3
diff -urN linux-2.4.29/arch/e1nommu/kernel/floating.S linux-2.4.29-uc1/arch/e1nommu/kernel/floating.S
--- linux-2.4.29/arch/e1nommu/kernel/floating.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/kernel/floating.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,2267 @@
+;----------------------------------------------------------------------------;
+; Floating point emulation support for Hyperstone E1-32X-E1-16X              ;
+; Copyright: hyperstone AG                                                   ;
+;            Am Seerhein 8                                                   ;
+;            D-7750 Konstanz, Germany                                        ;
+; Date:      October 16, 2001                                                ;
+;----------------------------------------------------------------------------;
+; Changed:   96-09-24 cb                                                     ;
+; - C flag is undefined after shl instructions                               ;
+; - not all allowed NaN values were recognized                               ;
+; - FADD, FADDD: inexact flag was not set in some cases where it should be   ;
+; - FCMP...: comparison with infinity should deliver <=>, not unordered      ;
+; - FCVT: if 0 < |num| < 2**-1042, inexact and underflow were not set        ;
+; - FMULD: x*0 did not return zero                                           ;
+; - FDIVD: wrong remainder calculation for rounding                          ;
+; - FADDD: exp.diff 54 needs still be added                                  ;
+;----------------------------------------------------------------------------;
+; uClinux comments by G.Thanos                                               ;
+; -Since we dont change stacks when excecuting an FP                         ;
+;  instruction we have operate with interrupts locked!!!                     ;
+;----------------------------------------------------------------------------;
+	    .global     FloatErrorEntry
+
+	    .global     StartOfFPRoutines
+	    .global     EndOfFPRoutines
+	    .global     FADDEntry
+	    .global     FSUBEntry
+	    .global     FMULEntry
+	    .global     FDIVEntry
+	    .global     FADDDEntry
+	    .global     FSUBDEntry
+	    .global     FMULDEntry
+	    .global     FDIVDEntry
+	    .global     FCMPEntry
+	    .global     FCMPUEntry
+	    .global     FCMPDEntry
+	    .global     FCMPUDEntry
+	    .global     FCVTEntry
+	    .global     FCVTDEntry
+	    .global     EXEntry
+	    .global     DOEntry
+;
+;       *** exception numbers ***
+;
+;       the real exception number of every operation
+;       and exception
+;       is the following sum
+;       exception number = Offset**** + ExNr*****
+;       example:
+;         error number of FADDD with inexact exception
+;         exception number = OffsetAddd + ExNrInex
+
+#define OffsetAdd         0                         ; fadd
+#define OffsetSub         4                         ; fsub
+#define OffsetMul         8                         ; fmul
+#define OffsetDiv         12                        ; fdiv
+#define OffsetAddd        17                        ; faddd
+#define OffsetSubd        21                        ; fsubd
+#define OffsetMuld        25                        ; fmuld
+#define OffsetDivd        29                        ; fdivd
+#define OffsetCmp         34                        ; fcvtd
+#define OffsetCmpd        35                        ; fcmp
+#define OffsetCvtd        36                        ; fcmpd
+#define OffsetCvt         37                        ; fcvt
+;
+;
+;
+#define ExNrInv           1                         ; additional err.number invalid
+#define ExNrInex          2                         ; .... inexact
+#define ExNrOver          3                         ; .... overflow
+#define ExNrUnder         4                         ; .... underflow
+#define ExNrZero          5                         ; .... division by zero
+;
+#define NANq              0x7FF80000                ; quiet Not a Number
+#define NANs              0x7FF80001                ; signaling Not a Number
+;
+;
+;
+;
+#define LFLAG             (1 << 15)                 ; interrupt-lock flag
+
+;============================================================================;
+
+
+StartOfFPRoutines:
+
+#ifdef NOFLOAT
+
+FADDEntry:
+FSUBEntry:
+FMULEntry:
+FDIVEntry:
+FADDDEntry:
+FSUBDEntry:
+FMULDEntry:
+FDIVDEntry:
+FCMPEntry:
+FCMPUEntry:
+FCMPDEntry:
+FCMPUDEntry:
+FCVTEntry:
+FCVTDEntry:
+EXEntry:
+DOEntry:
+
+	     FRAME  L8, L0
+	     MOVI   L7, 0             ; errorcode = not implemented
+	     SUM    PC, PC, FloatErrorEntry - $
+	     RET    PC, L3
+
+EndOfFPRoutines:
+
+#else
+
+;============================================================================;
+;
+; Register Layout:
+;
+;       L0 : ADDRESS of LD
+;       L1 : LS high
+;       L2 : LS low | TEMP
+;       L3 : PC
+;       L4 : SR
+;       L5 : LD high
+;       L6 : LD low
+;       L7 : LS.EXP | result.sign
+;       L8 : LD.EXP
+;       L9 : EXP
+;       L10: Sign, if result equal zero
+;       L11: LS (saving)
+;       L12: used as exception dummy
+;       L13: Exceptionnumber
+;
+FSUBEntry:   FRAME  L14, L0
+	     MOVI   L13, OffsetSub
+	     DBR    ADDE
+	     XORI   L1, 0x80000000     ; negate LS, LS = - LS
+FADDEntry:   FRAME  L14, L0           ; prolog
+	     MOVI   L13, OffsetAdd
+ADDE:        CMPBI  L4, LFLAG         ; ReturnSR.LockFlag set ?
+	     DBNZ   DelActExc         ; Yes: --> DelActExc
+	     MOV    L11, L1
+;	     ANDNI  SR, LFLAG         ; No : remove lock flag
+DelActExc:   ANDNI  G2, 0x00001F00     ; delete actual exceptions
+	     LDW.S  L0, L5, 0         ; load LD
+	     MOV    L8, L5            ; ld.exp = ld
+	     ADD    L5, L5            ; remove sign.ld
+	     SETC   L10               ; save sign
+	     CMPI   L5, 0xFF000000     ; if ld infinity or nan
+	     BHE    NAN_OR_INFD       ; yes, branch
+	     SET0   L6                ; set ld.low = 0
+	     CMPBI  L5, 0xFF000000     ; test ld.exp
+	     DBZ    DEN0              ; branch if denormal
+	     SHLI   L5, 8             ; remove exp.ld
+	     SHRI   L5, 1             ; else correct ld.mantisse
+	     ORI    L5, 0x80000000     ; insert hidden bit
+DEN0:        SHRI   L5, 2             ; correct position of ld
+	     ADD    L8, L8            ; remove ld.sign
+	     DBNC   POSITIV0          ; positive, then branch
+	     SHRI   L8, 24            ;  correct position of ld.exp
+	     NEG    L5, L5            ; negate ld
+POSITIV0:
+	     MOV    L7, L1            ; ls.exp = ls
+	     ADD    L1, L1            ; remove sign.ls
+	     ADD    L10, C            ; save ls.sign+ld.sign
+	     CMPI   L1, 0xFF000000     ; if ls = nan or inf
+	     BHE    NAN_OR_INFS       ; yes, branch
+	     MOV    L9, L8            ; temp = ld.exp
+	     CMPBI  L1, 0xFF000000     ; test ls.exp
+	     DBZ    DEN1              ; branch if denormal
+	     SHLI   L1, 8             ; remove exp.ls
+	     SHRI   L1, 1             ; else correct ls.exp
+	     ORI    L1, 0x80000000     ; insert hidden bit
+DEN1:        SHRI   L1, 2             ; correct position of ls
+	     ADD    L7, L7            ; remove ls.sign
+	     DBNC   POSITIV1          ; positive, then branch
+	     SHRI   L7, 24            ;  correct position of ls.exp
+	     NEG    L1, L1            ; negate ls
+POSITIV1:
+	     SUB    L9, L7            ; EXP = ld.exp - ls.exp
+	     DBLT   LS_GREATER        ; if exp < 0 then ls_greater
+	     SET0   L2                ; lsf = 0
+	     CMPI   L9, 32            ; if exp.diff > 32
+	     BGE    NO_ADD1           ; do not add
+	     DBR    REAL_ADD
+	     SARD   L1,L9             ; align ls by exp.diff
+NO_ADD1:     CMPBI  SR, 0x00006000     ; else, check rounding mode
+	     BNZ    LD_TO_HIGH        ; if rm<>0 branch
+	     CMPI   L1, 0             ; check if result inexact
+	     BZ     NoAddInex         ; branch if inexact
+	     CMPBI  SR, 0x00000100
+	     BNE    TRAP_INEX
+	     ANDNI  G2,0x00001F00
+	     ORI    G2, 1
+NoAddInex:   RET    PC, L3
+
+LS_GREATER:  MOV    L8, L7            ; EXP = ls.exp
+	     NEG    L9, L9            ; correct EXP.diff
+	     CMPI   L9, 32            ; if exp.diff > 32
+	     BGE    NO_ADD2           ;   do not add
+	     DBR    REAL_ADD          ;
+	     SARD   L5,L9             ;
+NO_ADD2:     CMPBI  SR,0x00006000      ; check rounding mode
+	     BNZ    LS_TO_HIGH        ; if rm<>00 branch
+	     MOV    L5, L5            ; check for ld != 0 (inexact)
+	     BZ     REAL_ADD          ; branch if ld == 0
+	     ORI    G2, 0x00000100     ; set inexact flag
+	     SET0   L5                ; and set ld = 0; L6 is already 0
+REAL_ADD:    ADD    L6, L2            ; ldf += lsf
+	     ADDC   L5, L1            ; ld += ls
+	     BZ     REAL_ZERO         ; if result == zero, then branch
+	     DBNN   NONEG1            ; if ld == negativ, then correct
+	     SETN   L7                ; save result.sign
+	     NEG    L5, L5            ; correct ld
+NONEG1:      TESTLZ L2, L5            ; check leading zeros
+	     SHLD   L5, L2            ; align ld by tlz
+	     SHRDI  L5,  8            ; correct ld by 8
+	     SUB    L8, L2            ; correct exp by tlz
+	     ADDI   L8, 2             ; correct ld.exp
+	     BLE    UNDERFLOW         ;
+CvtRound:    CMPI   L6, 0             ; ckeck if inexact
+	     BE     AddNotInex        ;
+	     ORI    G2, 0x00000100     ; set actual inexact.exception
+AddNotInex:
+	     CMPBI  SR, 0x00006000     ; check rounding mode '00'
+	     BNZ    NOT_NEAREST       ; if rm<>00 branch
+	     ADD    L6, L6            ; round to nearest, if ld.f >= 0.5
+             ADDI   L5, CZ            ; perform rounding
+CORRECT:     CMPBI  L5, 0xff000000     ; check for overflow during rounding
+             BZ     Round_NOV_1       ; branch if no overflow
+	     ADDI   L8, 1             ; correct exponent if overflow
+Round_NOV_1: ANDNI  L5, 0xff800000     ; clear exponent part and hidden bit
+	     CMPI   L8,255            ; check exp
+	     BNN    OVERFLOW          ; if l8>255 branch
+	     SHLI   L8, 23            ; correct ld.exp
+	     OR     L5, L8            ; ld = ld.exp | ld.man
+STORE_ADDS:  SHLI   L7, 31            ; shift sign
+	     OR     L5, L7            ; ld = ld.sign | ld.exp | ld.man
+	     CMPBI  G2, 0x00000100     ; ckeck if inexact.ex = 1
+	     BZ     INEX_ADD          ; if result exact, then branch
+	     CMPBI  SR, 0x00000100     ; check if inexact.trap=enable
+	     BNE    TRAP_INEX         ; yes, then branch
+	     ANDNI  G2, 0x00001F00     ; delete actual exceptions
+	     ORI    G2, 1             ; set accrued inexact.exception
+INEX_ADD:    STW.S  L0,L5,0
+	     RET    PC, L3            ; leave
+
+REAL_ZERO:   CMPI   L10,1             ; check result.sign
+	     BN     ZERO_POS          ; ld.sign = ls.sign = (+)
+	     BNZ    ZERO_NEG          ; ld.sign = ls.sign = (-)
+	     CMPBI  SR, 0x00006000     ; check rounding mode 00
+	     BNZ    CHECK_RM          ; if rm <> 00 branch
+ZERO_POS:    STW.S  L0,  0, 0         ; store 0
+	     RET    PC, L3            ; leave
+ZERO_NEG:    MOVI   L1, 0x80000000     ; l1=-0
+	     STW.S  L0, L1, 0         ; store -0
+	     RET    PC, L3            ; leave
+CHECK_RM:    CMPBI  SR,0x00002000      ; check rounding mode
+	     BZ     ZERO_NEG          ; if SR(13)=0 round toward -infinity
+	     STW.S  L0, 0, 0          ; store +0
+	     RET    PC, L3            ; leave
+
+NOT_NEAREST: CMPBI  SR, 0x00004000     ; check rounding mode 01, SR(14)
+	     SETNZ  L10
+	     CMPI   L6,0              ; check l6=0
+	     BZ     CORRECT           ; if ldf=0 branch
+	     CMPBI  SR, 0x00002000     ; check rm, SR(13)
+	     SETNZ  L6                ;
+	     XOR    L6, L7            ;
+	     AND    L6, L10           ;
+	     DBR    CORRECT
+	     ADD    L5, L6            ;
+LS_TO_HIGH:  MOV    L10,L1            ;
+	     MOV    L1, L5
+	     MOV    L5, L10
+LD_TO_HIGH:  ADDI   L8, 2
+	     CMPI   L5, 0             ; check sign
+	     DBNN   NONEG2            ; if ld=negative correct
+	     SETN   L7                ; store sign
+	     NEG    L5,L5             ; correct ld
+NONEG2:      TESTLZ L2, L5            ; check leading zeros
+	     SHLD   L5, L2            ; align ld by tlz
+	     SHRDI  L5,  8            ; correct ld by 8
+	     SUB    L8, L2            ; correct exp by tlz
+	     CMPI   L1,0              ; check ls.mant
+	     BZ     CORRECT           ; else leave
+	     SETN   L6                ; l6=ls.sign
+	     ORI    G2, 0x00000100     ; set inexact.exception
+	     CMPBI  SR, 0x00004000     ; check SR(14)
+	     SETNZ  L9
+	     CMPBI  SR,0x00002000      ; check SR(13)
+	     SETNZ  L10               ;
+	     XOR    L10,L7            ;
+	     AND    L10,L9           ;
+	     XOR    L6, L7            ;
+	     BNZ    SIGN_DIFF         ; if ls.sign <> ld.sign
+	     DBR    CORRECT
+	     ADD    L5, L10           ; ld.mant += l10
+
+SIGN_DIFF:   SHRI   L10, 1            ;
+	     SETNC  L10               ;
+	     SUB    L5, L10           ;
+	     CMPBI  L5, 0xff800000     ;
+	     SETZ   L10               ;
+	     SUB    L8,L10            ; correct exponent
+	     ANDNI  L5, 0xff800000     ;
+	     ORI    L5, 0x00800000     ;
+	     BR     CORRECT
+NAN_OR_INFD:
+	     BHT    NanLd             ; ld = nan
+	     ADD    L1, L1            ; ld = inf, check ls.sign
+	     SETC   L2                ; save ls.sign
+	     CMPI   L1, 0xFF000000     ; if l1=nan or inf
+	     BHE    InfLs             ; yes, branch
+	     RET    PC, L3            ; ld=inf, ls=normal -> return ld
+InfLs:       BHT    NanLs             ; branch, if ls=nan
+	     CMP    L10, L2           ; ld=ls=inf, compare ls.sign and ld.sign
+	     BNE    STORE_NAN_S       ; signaling nan, invalid op.
+	     RET    PC, L3            ; leave, inf+inf -> inf
+
+NanLd:       SHRI   L5, 2             ; if ld=NaNs
+	     BC     STORE_NAN_S       ; yes, branch, NaNs
+	     ANDNI  L1, 0x807ffffe     ; check for ls=NaNs
+	     CMPI   L1, 0x7f800001     ;
+	     BZ     STORE_NAN_S       ; yes, branch
+	     BR     STORE_NAN_Q       ; store NANq
+
+NAN_OR_INFS: BHT    NanLs             ; ls = nan, ld=normal
+	     STW.S  L0, L11, 0        ; store ls=+-infinity
+	     RET    PC, L3
+NanLs:       SHRI   L1, 2             ; if ls = NANs
+	     BC     STORE_NAN_S       ; yes, exception
+	     BR     STORE_NAN_Q       ; LD = NANq
+
+STORE_NAN_S: CMPBI  SR, 0x00001000     ; if invalid.floating trap = enable
+	     BE     NOINV_TRAP        ; no, branch
+	     ANDNI  G2, 0x00001F00     ; delete actual exception
+	     ORI    G2, 0x00001000     ; set actual.invalid.exception
+	     MOVI   L5, NANs
+	     ADDI   L13, ExNrInv      ; correct exceptionnumber
+	     MOVD   L1, L10
+	     MOV    L7, L13
+	     SUM    PC, PC, FloatErrorEntry - $
+
+NOINV_TRAP:  ANDNI  G2, 0x00001F00      ; clear actual exceptions
+	     ORI    G2, 0x00000010     ; set accrued.invalid.exception
+STORE_NAN_Q: MOVI   L5, NANq          ; LD = NANq
+	     STW.S  L0, L5, 0         ; store LD
+	     RET    PC, L3            ; leave
+;
+;
+; Register Layout:
+;
+;       L0 : ADDRESS of LD
+;       L1 : LS high
+;       L2 : TEMP
+;       L3 : PC
+;       L4 : SR
+;       L5 : LD high
+;       L6 : LD low
+;       L7 : SIGN LS
+;       L8 : EXP
+;       L9 : TEMP
+;       L10: TEMP
+;       L11: LS (saving)
+;       L12: Exception dummy
+;       L13: Exceptionnumber
+;
+;  A * B --> A.m * B.m * (A.exp + B.exp)
+;  Single Floating Point multiplication
+;
+
+FMULEntry:   FRAME  L14, L0            ; prolog
+	     MOVI   L13, OffsetMul
+	     CMPBI  L4, LFLAG          ; ReturnSR.LockFlag set ?
+	     DBNZ   FMULDelAExc        ; Yes: --> FMULDelAExc
+	     MOV    L11, L1
+	     ANDNI  SR,LFLAG           ; No : remove lock flag
+FMULDelAExc: ANDNI  G2,0x00001F00       ; delete actual exceptions
+	     LDW.S  L0, L5, 0          ; load LD
+	     ADD    L5, L5             ; remove ld.sign
+	     SETC   L7                 ; save ld.sign
+	     CMPI   L5, 0xFF000000      ; if LD == (NAN OR INF)
+	     BNC    NAN_INF_DM         ; yes, branch
+	     ADD    L1, L1             ; remove ls.sign
+	     ADD    L7, C              ; LS: Store Sign Bit
+	     CMPI   L1, 0xFF000000      ; if LS == (NAN OR INF)
+	     BNC    NAN_INF_SM         ; yes, branch
+	     MOV    L8, L5             ; EXP = LD.EXP
+	     SHLI   L5, 7              ; ld.man = ld - ld.exp
+	     SHRI   L8, 24             ; if (EXP = real EXP) == 0
+	     BNZ    HIDDEN1            ; yes, branch
+	     TESTLZ L2, L5             ;
+	     CMPI   L2, 32             ; check if l2>=32
+	     BZ     Hidden1Zero        ;
+	     SHL    L5, L2             ;
+	     SHRI   L5, 1              ;
+	     SUB    L8, L2             ; correct ld.exp
+	     ADDI   L8, 1
+	     BR     Hidden1Zero
+
+HIDDEN1:     ORI    L5, 0x80000000      ; insert hidden bit
+	     SHRI   L5, 1              ; correct ld
+Hidden1Zero:
+	     MOV    L2, L1             ; Temp = ls.exp
+	     SHLI   L1, 7              ; ld.man = ld - ld.exp
+	     SHRI   L2, 24             ; if (TEMP = real LS.EXP) == 0
+	     BNZ    HIDDEN2            ; yes, branch
+	     TESTLZ L6, L1             ;
+	     CMPI   L6, 32             ;
+	     BZ     Hidden2Zero        ;
+	     SHL    L1, L6
+	     SHRI   L1, 8
+	     SUB    L2, L6
+	     ADDI   L2, 1
+	     BR     Hidden2Zero
+
+HIDDEN2:     ORI    L1, 0x80000000      ; insert hidden bit
+	     SHRI   L1, 8              ; correct ls
+Hidden2Zero:
+	     ADD    L8, L2
+	     MULS   L5, L1             ; LD = LD * LS
+	     BZ     STORE_ZERO         ; if LD == 0 then store it
+	     TESTLZ L2, L5             ; count first zero bits
+	     ADDI   L2, -8             ; 8 must be free
+	     SHLD   L5, L2             ; align first bit
+	     SUB    L8, L2             ;
+	     ADDI   L8, -126 + 1       ; EXP += -126 + (64-2*48-8-7)
+	     BLE    UNDERFLOW          ;
+	     CMPI   L6, 0              ; check if inexact
+	     BZ     MulNotInex         ; if not inexact branch
+	     ORI    G2, 0x00000100      ; set inexact.exception
+MulNotInex:
+             BR     AddNotInex
+
+STORE_ZERO:  SHLI   L7, 31             ; right position of sign
+	     OR     L5, L7             ; ld.sign | zero
+	     STW.S  L0, L5, 0          ; store ld
+	     RET    PC, L3             ; leave
+
+NAN_INF_SM:  BZ     INF_SM             ; if LS == INF then branch
+	     SHRI   L1, 2              ; check, if ls=NANs
+	     BC     STORE_NAN_S        ;
+	     BR     STORE_NAN_Q        ;
+INF_SM:      CMPI   L5, 0              ; check if ld=0
+	     BZ     STORE_NAN_S        ; yes, exception
+	     BR     STORE_INF1         ; store +- infinity
+
+NAN_INF_DM:  BHT    NanLdM             ; ld = nan
+	     ADD    L1, L1             ; check and remove ls.sign
+	     BZ     STORE_NAN_S        ; if l1=0 invalid operation
+	     ADD    L7, C              ; store ls.sign
+	     CMPI   L1, 0xFF000000      ;
+	     BSE    STORE_INF1         ; ld=inf, branch if ls=inf or normal
+NanLsM:      SHRI   L1, 2              ; check, if ls = NANs
+	     BC     STORE_NAN_S        ; yes
+	     BR     STORE_NAN_Q        ; no
+NanLdM:      SHRI   L5, 2              ; check, if ld=NANS
+	     BC     STORE_NAN_S        ; yes
+	     ANDNI  L1, 0x807ffffe      ; check for ls=NaNs
+	     CMPI   L1, 0x7f800001      ;
+	     BZ     STORE_NAN_S        ; yes
+	     BR     STORE_NAN_Q        ; no
+;
+;
+; Register Layout:
+;
+;       L0 : ADDRESS of1 LD
+;       L1 : LS high
+;       L2 : TEMP
+;       L3 : PC
+;       L4 : SR
+;       L5 : LD high
+;       L6 : LD low
+;       L7 : SIGN LS
+;       L8 : EXP
+;       L9 : TEMP
+;       L10: TEMP
+;       L11: LS (saving)
+;       L12: Exception dummy
+;       L13: Exceptionnumber
+;
+;  A / B --> A.m / B.m * (A.exp - B.exp)
+;  Single Floating Point division
+;
+NO_HIDDEN3:  TESTLZ L2, L5             ; test leading zeros from ld
+	     SUB    L8, L2             ; correct exp by leading zeros
+	     ADDI   L8, 8              ; first 8 bits are zero
+	     SHL    L5, L2             ; correct ld
+	     SHRI   L5, 1              ; first bit must be zero
+	     BR     SKIP3
+
+NO_HIDDEN4:  TESTLZ L2, L1             ; test leadingt zeros from ls
+	     ADD    L8, L2             ; correct exp by leading zeros
+	     ADDI   L8, -8             ; first 8 bits are zero
+	     DBR    SKIP4              ; leave denorm 2
+	     SHL    L1, L2             ; correct ls
+
+F_DIV_ZERO:  ADD    L5, L5             ; check and remove ld.sign
+	     DBZ    STORE_NAN_S        ; if zero, then INF exception
+	     ADD    L7, C              ; correct true sign for result
+	     CMPI   L5, 0xFF000000      ; else if LD == NAN
+	     BHT    NanLdD             ; then branch, check NANs or NANq
+	     SHLI   L7, 31             ; correct position of sign
+	     MOVI   L5, 0x7F800000      ;
+	     OR     L5, L7             ; l5=+-infinity
+	     CMPBI  SR, 0x00000800      ; if divison_by_zero.trap = enable
+	     BZ     NO_DIV_TRAP        ; no, branch
+	     ANDNI  G2, 0x00001F00      ; else, del all actual exceptions
+	     ORI    G2, 0x00000800      ; set actual.division_by_zero.exception
+	     ADDI   L13, ExNrZero      ; correct exceptionnumber
+	     MOVD   L1, L11
+	     MOV    L7, L13
+	     SUM    PC, PC, FloatErrorEntry - $
+
+NO_DIV_TRAP: ANDNI  G2, 0x00001F00
+	     ORI    G2, 8
+	     STW.S  L0, L5, 0
+	     RET    PC, L3
+
+FDIVEntry:   FRAME  L14, L0            ; prolog
+	     MOVI   L13, OffsetDiv     ; basic exception offset, fdiv
+	     CMPBI  L4, LFLAG          ; ReturnSR.LockFlag set ?
+	     DBNZ   FDIVDelAExc        ; Yes: --> FDIVDelAExc
+	     MOV    L11, L1            ; save ls
+;	     ANDNI  SR, LFLAG          ; No : remove lock flag
+FDIVDelAExc: ANDNI  G2, 0x00001F00      ; delete actual exceptions
+	     LDW.S  L0, L5, 0          ; load LD
+	     ADD    L1, L1             ; check and remove ls.sign
+	     DBZ    F_DIV_ZERO         ; XX / 0 == undefined
+	     SETC   L7                 ; save ls.sign
+	     CMPI   L1, 0xFF000000      ; if LS == (NAN OR INF)
+	     BNC    NAN_INF_S          ; yes, branch
+	     ADD    L5, L5             ; check and remove ld.sign
+	     DBZ    STORE_ZERO         ; if ld=0 store l7 | zero
+	     ADD    L7, C              ;   LD: Store Sign Bit
+	     CMPI   L5, 0xFF000000      ; if LD == (NAN OR INF)
+	     BNC    NAN_INF_D          ; yes, branch
+	     MOV    L8, L5             ; EXP = LD.EXP
+	     SHRI   L8, 24             ; if (EXP = real EXP) == 0
+	     BZ     NO_HIDDEN3         ; yes, branch
+	     SHLI   L5, 7              ; ld.man = ld - ld.exp
+	     ORI    L5, 0x80000000      ; insert hidden bit
+	     SHRI   L5, 1              ; correct ld
+SKIP3:
+	     MOV    L2, L1             ; TEMP = LS.EXP
+	     SHRI   L2, 24             ; if (TEMP = real LS.EXP) == 0
+	     BZ     NO_HIDDEN4         ; yes, branch
+	     SUB    L8, L2             ; EXP = LD.EXP - LS.EXP
+	     SHLI   L1, 7              ; correct LS
+	     ORI    L1, 0x80000000      ; insert hidden bit
+SKIP4:
+	     SET0   L6                 ; LDf = 0
+	     DIVU   L5, L1             ; LD = LD//LDf / LS
+	     MOV    L1, L5             ; l1 = remainder
+	     MOV    L5, L6             ; LD = quotient
+	     TESTLZ L2, L5             ; count first zero bits
+	     SHL    L5, L2
+	     SET0   L6
+	     CMPI   L1, 0
+	     BZ     NoRemainder
+	     ORI    L6, 0x00000800
+NoRemainder:
+	     SHRDI  L5, 8              ; align first bit
+	     SUB    L8, L2             ; correct EXP by shiftet numbers
+	     ADDI   L8, 126 + 1        ; EXP += 126 + 8 - 7
+	     BLE    UNDERFLOW          ; if ld.exp <= 0 then branch
+	     CMPI   L6, 0              ;
+	     BZ     DivNotInex         ;
+	     ORI    G2, 0x00000100      ; set actual inexact.exception
+DivNotInex:
+	     BR     AddNotInex
+
+NAN_INF_D:   BZ     STORE_INF1         ; else store +-INF
+NanLdD:      ANDNI  L5, 0x00fffffc      ; ls=normal, check for ld=NaNs
+	     CMPBI  L5, 0xff000002      ;
+	     BZ     STORE_NAN_S        ; yes, exception
+	     BR     STORE_NAN_Q        ; no, store ld=NANq
+
+NAN_INF_S:   BZ     INF_S1             ; IF LS == INF then branch
+	     SHRI   L1, 2              ; IF LS == NANq
+	     BC     STORE_NAN_S        ; then branch, else LS == NANs
+	     ANDNI  L5, 0x807ffffe      ; check for ld=NaNs
+	     CMPI   L5, 0x7f800001      ;
+	     BZ     STORE_NAN_S        ; no, branch exception
+	     BR     STORE_NAN_Q        ; branch NANq
+
+INF_S1:      ADD    L5, L5             ; check and remove ld.sign
+	     ADD    L7, C              ; store ld.sign
+	     CMPI   L5, 0xFF000000      ; CMP LD == (NAN OR INF)
+	     BE     STORE_NAN_S        ; if LD == INF then branch
+	     BHT    NanLdD             ; ld=nan
+	     MOVI   L5, 0              ; store ld=+-0
+	     SHLI   L7, 31             ;
+	     OR     L5, L7             ;
+	     STW.S  L0, L5, 0          ;
+	     RET    PC, L3             ;
+
+STORE_INF1:  MOVI   L5, 0x7F800000      ; LD = INF
+	     SHLI   L7, 31             ; correct sign bit position
+	     OR     L5, L7             ; insert sign bit
+	     STW.S  L0, L5, 0          ; store LD
+	     RET    PC, L3             ; leave
+;
+;
+UNDERFLOW:
+	     ORI    L5, 0x00800000     ; insert removed hidden bit
+	     CMPBI  SR, 0x00000200     ; if underflow.trap = enable
+	     BNE    TRAP_UNDER        ; yes, branch
+	     ANDNI  G2, 0x00001F00     ; delete actual exceptions
+	     ORI    G2, 2             ; set accrued.underflow.exception
+	     NEG    L8, L8            ; correct exp, exp = -exp
+	     CMPI   L8, 25            ; if exp.diff > 25
+	     BLT    UNDER_1           ; yes, then branch
+	     CMPBI  SR,0x00004000      ; check rm=00,01
+	     DBNZ   UNDER_2           ; if rm <> 00,01 branch
+	     SET0   L5
+	     BR     SIGNED_ZERO
+
+UNDER_1:     MOV    L1, L7            ; store sign bit
+	     SET0   L7
+	     ADDI   L8, 1             ;
+	     SHRD   L6, L8            ; shift l6//l7
+	     SHL    L6, L8            ;
+	     SHRD   L5, L8            ; triple shift
+	     SET0   L8                ;
+
+	     SHLDI  L6, 0             ;
+	     BZ     UNDER_3
+
+	     CMPBI  SR,0x00000100      ;
+	     BNE    TRAP_INEX
+
+	     ORI    G2, 1
+	     CMPBI  SR, 0x00006000     ; ckeck if rm=00
+	     BNZ    UnderNotNear      ; if rm <> 00 branch
+	     ADD    L7, L7            ; round to nearest-even
+	     ADDC   L6, L6
+	     ADDI   L5, CZ            ; perform rounding
+CheckHid:    CMPBI  L5, 0xff000000     ; check for overflow during rounding
+             BZ     Round_NOV_2       ; branch if no overflow
+	     ADDI   L8, 1             ; correct exponent if overflow
+Round_NOV_2: ANDNI  L5, 0xff800000     ; clear exponent part and hidden bit
+UNDER_3:     DBR    CORRECT           ;
+	     MOV    L7, L1            ;
+
+UnderNotNear:
+	     CMPBI  SR,0x00004000       ; ckeck rounding mode
+	     SETNZ  L6
+	     CMPBI  SR,0x00002000       ; ckeck rounding mode
+	     SETNZ  L7
+	     XOR    L7, L1
+	     AND    L7, L6
+	     DBR    CheckHid
+	     ADD    L5, L7
+
+UNDER_2:     CMPBI  SR,0x00002000      ; check SR(13)
+	     SETNZ  L6
+	     XOR    L6,L7             ;
+	     ADD    L5,L6
+SIGNED_ZERO:
+	     SHLI   L7,31             ;
+	     OR     L5,L7             ;
+	     CMPBI  SR,0x00000100      ;
+	     BNE    TRAP_INEX
+	     STW.S  L0,L5,0
+	     ANDNI  G2,0x00001F00
+	     ORI    G2, 1
+	     RET    PC,L3
+
+TRAP_UNDER:  ANDNI  G2, 0x00001F00     ; del all actual exceptions
+	     ORI    G2, 0x00000200     ; set actual.underflow.exception
+	     ADDI   L8, 192           ; correct bias for trap-handler
+	     TESTLZ L2, L5
+	     ADDI   L2, -8
+	     SUB    L8, L2
+	     SHLD   L5, L2
+	     CMPBI  SR, 0x00006000
+	     BNZ    TrapNotNear
+	     ADD    L6, L6            ; round to nearest-even
+	     ADDI   L5, CZ            ; perform rounding
+TrapStore:   CMPBI  L5, 0xff000000     ; check for overflow during rounding
+             BZ     Round_NOV_3       ; branch if no overflow
+	     ADDI   L8, 1             ; correct exponent if overflow
+Round_NOV_3: ANDNI  L5, 0xff800000     ; clear exponent part and hidden bit
+	     SHRI   L8, 23
+	     SHRI   L7, 31
+	     OR     L5, L8
+	     OR     L5, L7
+	     ADDI   L13, ExNrUnder    ; correct errornumber
+	     MOVD   L1, L11
+	     MOV    L7, L13
+	     SUM    PC, PC, FloatErrorEntry - $
+
+TrapNotNear:
+	     CMPBI  SR, 0x00004000     ; check rounding mode 01, SR(14)
+	     SETNZ  L10
+	     CMPI   L6,0              ; check l6=0
+	     BZ     TrapStore         ; if ldf=0 branch
+	     CMPBI  SR, 0x00002000     ; check rm, SR(13)
+	     SETNZ  L6
+	     XOR    L6, L7            ;
+	     AND    L6, L10           ;
+	     DBR    TrapStore
+	     ADD    L5, L6            ;
+INEXACT:
+	     SHLI   L7, 31            ; correct position of sign
+	     CMPBI  SR, 0x00000100     ; if inexact.trap = enable
+	     DBNE   TRAP_INEX         ; yes, skip
+	     OR     L5, L7
+	     STW.S  L0, L5, 0
+	     ANDNI  G2, 0x00001F00
+	     ORI    G2, 1             ; set accrued.inexact.exception
+	     RET    PC, L3
+TRAP_INEX:   ANDNI  G2,0x00001F00      ; clear actual exceptions
+	     ORI    G2,0x00000100      ; set actual inexact.exception
+	     ADDI   L13, ExNrInex
+	     MOVD   L1, L11
+	     MOV    L7, L13
+	     SUM    PC, PC, FloatErrorEntry - $
+
+OVERFLOW:    CMPBI  SR, 0x00000400     ; if overfow.trap = enable
+	     BNE    TRAP_OVER         ; yes, branch
+	     CMPBI  SR, 0x00000100     ; if inexact.trap = enable
+	     BNE    TRAP_INEX         ; yes, branch
+	     ANDNI  G2, 0x00001F00     ;
+	     ORI    G2, 5             ; set accrued.overflow exception
+	     CMPBI  SR, 0x00006000     ; check rm=00
+	     BNZ    O_NOT_NEAR        ; if rm <> 0 branch
+	     MOVI   L5, 0x7F800000     ; round to nearest, ld=inf
+	     SHLI   L7, 31            ; extract correct sign
+	     XOR    L5, L7            ; insert correct sign into LD
+	     STW.S  L0, L5, 0         ; store LD
+	     RET    PC, L3            ; leave
+
+O_NOT_NEAR:  MOVI   L5,0x7F7FFFFF
+	     CMPBI  SR,0x00004000
+	     BZ     OVER_RM1
+	     CMPBI  SR,0x00002000
+	     SETNZ  L1
+	     XOR    L1,L7
+	     ADD    L5,L1
+OVER_RM1:    SHLI   L7,31
+	     OR     L5,L7
+	     STW.S  L0,L5,0
+	     RET    PC,L3
+
+TRAP_OVER:   ANDNI  G2, 0x00001F00     ; delete actual exception
+	     ORI    G2, 0x00000400     ; set actual.overflow.exception
+	     ORI    G2, 1
+	     ADDI   L8, -192          ; correct bias for trap-handler
+	     CMPBI  SR, 0x00006000
+	     BNZ    TrapOverNNear
+	     ADD    L6, L6            ; round to nearest-even
+	     ADDI   L5, CZ            ; perform rounding
+TrapOverSt:  CMPBI  L5, 0xff000000     ; check for overflow during rounding
+             BZ     Round_NOV_4       ; branch if no overflow
+	     ADDI   L8, 1             ; correct exponent if overflow
+Round_NOV_4: ANDNI  L5, 0xff800000     ; clear exponent part and hidden bit
+	     SHRI   L8, 23
+	     SHRI   L7, 31
+	     OR     L5, L8
+	     OR     L5, L7
+	     ADDI   L13, ExNrOver
+	     MOVD   L1, L11
+	     MOV    L7, L13
+	     SUM    PC, PC, FloatErrorEntry - $
+
+TrapOverNNear:
+	     CMPBI  SR, 0x00004000     ; check rounding mode 01, SR(14)
+	     SETNZ  L10
+	     CMPI   L6,0              ; check l6=0
+	     BZ     TrapOverSt        ; if ldf=0 branch
+	     CMPBI  SR, 0x00002000     ; check rm, SR(13)
+	     SETNZ  L6
+	     XOR    L6, L7            ;
+	     AND    L6, L10           ;
+	     DBR    TrapOverSt
+	     ADD    L5, L6            ;
+;
+; Register Layout:
+;
+;       L0 : ADDRESS of LD
+;       L1 : LS
+;       L2 : sign LS
+;       L3 : PC
+;       L4 : SR
+;       L5 : LD | Exception dummy
+;       L6 : sign LD | Exception dummy
+;       L7 : LS (saving)
+;       L8 : Exception dummy
+;       L9 : Exceptionnumber
+;       L10: Exception dummy
+;
+;  Single Floating Point compare
+;
+FCMPEntry:   FRAME  L11, L0
+	     MOVI   L9, OffsetCmp      ; basic exception number, fcmp
+	     CMPBI  L4, LFLAG          ; ReturnSR.LockFlag det ?
+	     DBNZ   FCMPDelAExc        ; YES: --> FCMPDelAExc
+	     MOV    L7, L1
+;	     ANDNI  SR, LFLAG          ; No, remove lock flag
+FCMPDelAExc: ANDNI  G2, 0x00001F00      ; delete actual exceptions
+	     LDW.S  L0, L5, 0          ; load LD
+	     ADD    L1, L1             ; check and remove ls.sign
+	     DBZ    tmp1
+	     SET0   L2                 ; sign=0 for zero input
+	     SETC   L2                 ; save ls.sign
+	     CMPI   L1, 0xFF000000      ; test INF and NAN
+	     DBHT   UNORDERED          ; branch if NaN
+tmp1:	     ANDNI  L4, 0x0F            ; clear all flags
+
+	     ADD    L5, L5             ; check and remove ld.sign
+	     DBZ    CMP_Ordered
+	     SET0   L6                 ; sign=0 for zero input
+	     SETC   L6                 ; save ld.sign
+	     CMPI   L5, 0xFF000000      ; test INF and NAN
+	     BHT    UNORDERED          ; branch if NaN
+
+CMP_Ordered: CMP    L2, L6             ; if ld.sign = ls.sign
+	     BNE    DIFF_SIGN          ; no, branch
+	     SHRI   L1, 1              ; correct ls
+	     SHRI   L5, 1              ; correct ld
+	     CMPI   L2, 1              ; if ls.sign = neg = ld.sign
+	     DBE    BOTH_NEG0          ; yes,
+	     CMP    L1, L5             ; then, compare ls, ld
+	     CMP    L5, L1             ; else, compare ld, ls
+BOTH_NEG0:   MASK   L2, SR, 0x07        ; copy flags to l2
+	     OR     L4, L2             ; insert flags in SR
+	     RET    PC, L3             ; leave fcmpu
+
+DIFF_SIGN:   BGT    LD_GT_LS           ; if ls.sign > ld.sign
+	     ORI    L4, 5              ; yes, insert flags
+LD_GT_LS:    RET    PC, L3             ; leave fcmpu
+
+UNORDERED:   ORI    G2, 0x00000010      ; set accrued.invalid.exception
+	     ORI    L4, 0x0C            ; set flags
+	     CMPBI  SR, 0x00001000      ; if invalid.floating trap = enable
+	     BE     NOUNOR_TRAP        ; no, branch
+	     ADDI   L9, ExNrInv        ; add invalid exception number
+	     ANDNI  G2, 0x00001F00      ; else, del all actual exceptions
+	     ORI    G2, 0x00001000      ; set actual.invalid.exception
+	     MOVD   L1, L7
+	     MOV    L7, L9
+	     SUM    PC, PC, FloatErrorEntry - $
+
+NOUNOR_TRAP: RET    PC, L3             ; leave
+;
+;
+; Register Layout:
+;
+;       L0 : ADDRESS of LD
+;       L1 : LS high
+;       L2 : sign LS
+;       L3 : PC
+;       L4 : SR
+;       L5 : LD high
+;       L6 : sign LD
+;
+;  Single Floating Point compare unordered
+;
+FCMPUEntry:  FRAME  L7, L0
+	     CMPBI  L4, LFLAG          ; ReturnSR-LockFlag set ?
+	     BNZ    LoadLD             ; Yes: --> LoadLD
+;	     ANDNI  SR, LFLAG          ; No : Remove LFlag
+LoadLD:      LDW.S  L0, L5, 0          ; load LD
+	     ADD    L1, L1             ; check and remove ls.sign
+	     DBZ    tmp3
+	     SET0   L2                 ; sign=0 for zero input
+	     SETC   L2                 ; save ls.sign
+	     CMPI   L1, 0xFF000000      ; test INF and NAN
+	     DBHT   UNORDERED1         ; branch if NaN
+tmp3:	     ANDNI  L4, 0x0F            ; clear all flags
+	     
+	     ADD    L5, L5             ; check and remove ld.sign
+	     DBZ    tmp4
+	     SET0   L6                 ; sign=0 for zero input
+	     SETC   L6                 ; save ld.sign
+	     CMPI   L5, 0xFF000000      ; test INF and NAN
+	     BHT    UNORDERED1         ; branch if NaN
+tmp4:	     BR     CMP_Ordered
+
+UNORDERED1:  ORI    G2, 0x00000010      ; set accrued.invalid.exception
+	     ORI    L4, 0x0C            ; set flags
+	     RET    PC, L3             ; leave
+
+; Register Layout:
+;
+;       L0 : ADDRESS of LD
+;       L1 : LS high
+;       L2 : LS low
+;       L3 : PC
+;       L4 : SR
+;       L5 : LD high
+;       L6 : LD low
+;       L7 : SIGN LS
+;       L8 : SIGN LD
+;       L9 : LS high (saving)
+;       L10: LS low (saving)
+;       L11: Exceptionnumber
+;
+;  Double Floating Point compare
+;
+
+FCMPDEntry:  FRAME  L12, L0
+	     CMPBI  L4, LFLAG          ; ReturnSR.LockFlag set ?
+	     DBNZ   GetExcNo           ; Yes: --> GetExcNo
+	     MOVD   L9, L1
+;	     ANDNI  SR, LFLAG          ; No : Remove LFLAG
+GetExcNo:    MOVI   L11, OffsetCmpd    ; basic exception number offset
+	     LDW.S  L0, L5, 4          ; load Ld
+	     LDW.S  L0, L6, 0          ; load Ldf
+	     ADD    L1, L1             ; check and remove ls.sign
+	     DBZ    tmp5
+	     SET0   L7                 ; sign=0 for zero input
+	     SETC   L7                 ; save ls.sign
+	     CMPI   L1, 0xFFE00000      ; test INF and NAN
+	     DBHT   UNORDERED2         ; branch if NaN
+tmp5:	     ANDNI  L4, 0xF
+
+	     ADD    L5, L5             ; check ld.sign
+	     DBZ    ForUnorder
+	     SET0   L0                 ; sign=0 for zero input
+	     SETC   L8                 ; save ld.sign
+	     CMPI   L5, 0xFFE00000      ; test INF and NAN
+	     BHT    UNORDERED2         ; branch if NaN
+
+ForUnorder:  CMP    L7, L8             ; if ls.sign = ld.sign
+	     BNE    DIFF_SIGN
+	     CMPI   L8, 1
+	     BE     AlNeg              ; if both numbers are negative
+
+	     CMP    L5, L1
+	     BST    SetNegC            ; if smaller then set N and C flag
+	     BE     TmpEqP             ; if equal then test Ldf and Lsf
+	     RET    PC, L3
+
+UNORDERED2:  MOVD   L7, L9             ; move ls//lsf
+	     DBR    UNORDERED
+	     MOV    L9, L11            ; move exceptionnumber
+
+TmpEqP:      CMP    L6, L2
+	     BE     AlEqual            ; if equal then set zero flag
+	     BST    SetNegC            ; if smaller then set N and C flag
+	     RET    PC, L3
+
+
+AlNeg:       CMP    L5, L1
+	     BHT    SetNegC            ; if higher then set N and C flag
+	     BE     TmpEq              ; if equal then test Ldf and Lsf
+	     RET    PC, L3
+
+TmpEq:       CMP    L6, L2
+	     BE     AlEqual            ; if Ldf equal Lsf then set zero flag
+	     BHT    SetNegC            ; if higher then set N and C flag
+	     RET    PC, L3
+
+AlEqual:     ORI    L4, 2              ; set zero flag
+	     RET    PC, L3
+
+SetNegC:     ORI    L4, 5              ; set negative and carry flag
+	     RET    PC, L3
+
+
+; Register Layout:
+;
+;       L0 : ADDRESS of LD
+;       L1 : LS high
+;       L2 : LS low
+;       L3 : PC
+;       L4 : SR
+;       L5 : LD high
+;       L6 : LD low
+;       L7 : SIGN LS
+;       L8 : SIGN LD
+;
+;  Double Floating Point compare unoredered
+;
+
+FCMPUDEntry: FRAME  L9, L0
+	     CMPBI  L4, LFLAG          ; ReturnSR.LockFlag set ?
+	     BNZ    FCMPSHL            ; Yes: --> FCMPSHL
+;	     ANDNI  SR, LFLAG          ; No : Remove LockFlag
+FCMPSHL:     LDW.S  L0, L5, 4          ; load Ld
+	     LDW.S  L0, L6, 0          ; load Ldf
+	     ADD    L1, L1             ; check and remove ls.sign
+	     DBZ    tmp7
+	     SET0   L7                 ; sign=0 for zero input
+	     SETC   L7                 ; save ls.sign
+	     CMPI   L1, 0xFFE00000      ; test INF and NAN
+	     DBHT   UNORDERED1         ; branch if NaN
+tmp7:	     ANDNI  L4, 0xF             ; clear all flags
+
+	     ADD    L5, L5             ; check and remove ld.sign
+	     DBZ    ForUnorder
+	     SET0   L8                 ; sign=0 for zero input
+	     SETC   L8                 ; save ld.sign
+	     CMPI   L5, 0xFFE00000      ; test INF and NAN
+	     BHT    UNORDERED1         ; branch if NaN
+	     BR     ForUnorder
+;
+;
+; Register Layout:
+;
+;       L0 : ADDRESS of LD
+;       L1 : LS high
+;       L2 : LS low | sign LS
+;       L3 : PC
+;       L4 : SR
+;       L5 : LD high
+;       L6 : LD low
+;       L7 : Result sign
+;       L8 : LD.EXP
+;       L9 : Rounding Mode
+;       L10: Exception dummy
+;       L11: LS high (saving)
+;       L12: LS low (saving)
+;       L13: Exceptionnumber
+;
+;  Single Floating Point FCVT
+;  Conversion Double to Single Precision
+;
+FCVTEntry:   FRAME  L14,L0             ; prolog
+	     MOVI   L13, OffsetCvt     ; basic exc.nr.offset of fcvt
+	     CMPBI  L4, LFLAG          ; ReturnSR.LockFlag set ?
+	     BNZ    SaveLS             ; Yes: --> SaveLS
+;	     ANDNI  SR, LFLAG          ; remove lock flag
+SaveLS:      MOVD   L11, L1            ; save ls//lsf
+	     MOVD   L5, L1             ; store mantissa
+	     SETN   L7                 ; store sign bit
+	     MOV    L8, L1             ; store exp
+	     ANDNI  L8, 0x80000000      ; remove sign
+	     BNZ    CvtNonZero
+	     MOV    L2, L2             ; ls.high is zero, check ls.low
+	     BZ     CvtZero            ; ls=0, store zero
+CvtNonZero:  SHRI   L8, 20             ; extract exp
+	     CMPI   L8, 0x000007FF      ; check nan or inf
+	     BZ     CVT_NANINF         ; if nan or inf branch
+	     ADDI   L8, 127-1023       ; transformed exp
+	     BLE    CVT_UNDER          ; if denormalized or zero branch
+	     CMPI   L8, 256            ; check overflow
+	     BHE    OVERFLOW           ; if overflow branch
+	     SHLDI  L5, 11             ; remove exp
+	     ORI    L5, 0x80000000      ; insert hidden bit
+	     SHRDI  L5, 8
+	     BR     CvtRound
+CvtZero:     STW.S  L0, L5, 0
+	     RET    PC, L3
+
+CVT_UNDER:   SHLDI  L5, 12             ; remove exp
+	     SHRDI  L5, 9              ; correct position
+	     BR     UNDERFLOW
+
+CVT_NANINF:  SHLDI  L5, 12             ; extract mantissa
+	     BZ     CVT_INF            ; if mantissa=0 branch
+	     CMPI   L5, 0x00001000      ; check NANq
+	     BZ     STORE_NAN_Q        ; if NANq branch
+	     BR     STORE_NAN_S        ; branch to NANs
+
+CVT_INF:     SHLI   L7, 31             ; correct position of sign
+	     OR     L5, L7             ; = MOV L5, L7
+	     ORI    L5, 0x7F800000      ; correct exp
+	     STW.S  L0, L5, 0          ; store signed inf
+	     RET    PC, L3
+;
+; Register Layout:
+;
+;       L0 : ADDRESS of LD
+;       L1 : LS high
+;       L2 : sign LS
+;       L3 : PC
+;       L4 : SR
+;       L5 : LD high
+;       L6 : LD low
+;       L7 : LS (saving)
+;       L8 : Exception dummy
+;       L9 : Exceptionnumber
+;       L10: Exception dummy
+;
+;  Single Floating Point FCVTD
+;     Conversion Single to Double Precision
+;
+FCVTDEntry:  FRAME  L11, L0            ;
+	     CMPBI  L4, LFLAG          ; ReturnSR.LockFlag set ?
+	     BNZ    GetOffset          ; Yes: --> GetOffset
+;	     ANDNI  SR, LFLAG          ; No : Remove LFLAG
+GetOffset:   MOVI   L9, OffsetCvtd     ; basic ex.nr.offset, fcvtd
+             ADD    L1, L1             ; check and remove ls.sign
+	     SETC   L2                 ; save ls.sign
+	     CMPI   L1, 0xFF000000      ; IF LS == NAN OR INF
+	     BHE    FCvtdNan           ; yes, branch
+	     MOV    L5, L1             ; LD = LS
+	     SHRI   L5, 24             ; extract real EXP
+	     DBNZ   StrNFCvtd          ; if exp > 0 then branch
+	     MOV    L6, L1             ; mov matisee to LDf
+	     BE     StoreFCvtd         ; if exp == 0 and mant == 0 then branch
+	     TESTLZ L5, L6             ; count leading zeros
+	     ADDI   L5, -7             ; seven must be free
+	     SHL    L6, L5             ; correct fraction
+	     ADDI   L5, -1             ; correct exp
+	     NEG    L5, L5             ; ready
+
+StrNFCvtd:   ADDI   L5, 1023 - 127     ; correct EXP for double
+	     SHLI   L6, 8              ; remove exp
+	     SHLDI  L5, 20             ; insert mantisse into LD
+StoreFCvtd:  SHLI   L2, 31             ; correct sign position
+	     OR     L5, L2             ; insert sign
+	     STW.S  L0, L5, 4          ; store LD
+	     STW.S  L0, L6, 0          ; store LDf
+	     RET    PC, L3             ; leave
+;
+;************************************************
+;
+;
+FCvtdNan:    BNZ    FCvtdNan1          ; branch if LS == NAN
+	     MOVI   L5, 0x7FF00000      ; store INF
+	     MOVI   L6, 0              ; LDF = 0
+	     BR     StoreFCvtd
+
+FCvtdNan1:   CMPBI  L1, 2              ; if LS == INFq
+	     DBNE   CvtNanS            ; no, store NANs
+	     ADDI   L0, 4              ; correct pointer
+	     BR     CvtNanQ
+NoCvtDTrap:  ORI    G2, 0x00000010     ; set accrued.invalid.exception
+	     ANDNI  G2, 0x00001F00
+CvtNanQ:     MOVI   L5, 0
+	     STW.S  L0, L5, -4
+	     MOVI   L5, NANq          ; LD = NANq
+	     STW.S  L0, L5, 0         ; store NANq
+	     RET    PC, L3            ; leave
+
+CvtNanS:     CMPBI  SR, 0x00001000     ; if invalid.floating trap = enable
+	     BE     NoCvtDTrap        ; no, branch
+	     ANDNI  G2, 0x00001F00     ; delete actual exception
+	     ORI    G2, 0x00001000     ; set actual.invalid.exception
+	     MOVI   L5, NANs          ; LD = NANs
+	     ADDI   L9, ExNrInv       ; correct errornumber
+	     ADDI   L0,-4
+	     MOVD   L1, L7
+	     MOV    L7, L9
+	     SUM    PC, PC, FloatErrorEntry - $
+
+;
+;**************************
+;**********************
+; Register Layout:
+;
+;       L0 : ADDRESS of LD
+;       L1 : LS [0]
+;       L2 : LS [1]
+;       L3 : LS [2] | LS.sign
+;       L4 : LS [3] | LS.exp
+;       L5 : LD [0]
+;       L6 : LD [1]
+;       L7 : LD [2] | LD.sign
+;       L8 : LD [3] | LD.exp
+;       L9 : SIGN
+;       L10: EXP
+;       L11: PC
+;       L12: SR
+;       L13: LS high (saving)
+;       L14: LS low (saving)
+;       L15: Errornumber
+;
+FSUBDEntry:
+	     FRAME  L0, L0
+	     MOVI   L15, OffsetSubd
+	     DBR    ADDDE
+	     XORI   L1, 0x80000000      ; ls = -ls
+FADDDEntry:
+	     FRAME  L0, L0            ;
+	     MOVI   L15, OffsetAddd
+ADDDE:       CMPBI  L4, LFLAG          ; ReturnSR.LockFlag set ?
+	     DBNZ   ADDDelAExc         ; Yes: --> AddDelAExc
+	     MOVD   L13, L1
+	     ANDNI  SR,LFLAG           ; No : Remove LockFlag
+ADDDelAExc:  ANDNI  G2, 0x00001F00      ; delete actual exceptions
+	     MOVD   L11, L3            ; save PC//SR
+	     LDW.S  L0, L5, 4
+	     LDW.S  L0, L6, 0          ; load LDf
+	     ADD    L2, L2             ; check and remove ls.sign
+	     ADDC   L1, L1
+	     SETC   L3                 ; save ls.sign
+	     MOV    L9,L3              ; store sign bit if result=zero
+	     ADD    L6, L6             ; check and remove ld.sign
+	     ADDC   L5, L5
+	     SETC   L7                 ; save ld.sign
+	     ADD    L9,L7              ; store sign bit if result=zero
+
+	     CMPI   L5, 0xFFE00000      ; if LD == (NAN OR INF)
+	     BNC    NanInfADD          ; yes, branch
+	     CMPI   L1, 0xFFE00000      ; if LS == (NAN OR INF)
+	     BNC    NanInfADS          ; yes, branch
+
+	     MOV    L8, L5             ; ld.exp = ld
+	     SHRI   L8, 21             ; EXP = real EXP
+	     BZ     NoHidA1            ; if ld.exp == 0 yes, branch
+	     SHRDI  L5, 1              ; correct LD.fract
+	     SHLI   L5, 11             ; ld.man = ld - ld.exp
+	     ORI    L5, 0x80000000      ; insert hidden bit
+	     SHRI   L5, 11             ; correct position of ld.man
+NoHidA1:     CMPI   L7, 0              ; if LD.sign
+	     DBE    NoNegAd1           ; no, branch
+	     MOV    L4, L1             ; Temp = ls
+	     NOT    L6, L6
+	     NOT    L5, L5
+	     ADDI   L6, 1
+	     ADDC   L5, C
+NoNegAd1:
+	     SHRI   L4, 21             ; TEMP = real LS.EXP
+	     BZ     NoHidA2            ; yes, branch
+	     SHRDI  L1, 1              ; correct LS.EXP
+	     SHLI   L1, 11             ; ls.man = ls - ls.exp
+	     ORI    L1, 0x80000000      ; insert hidden bit
+	     SHRI   L1, 11             ; correct position of ls.man
+NoHidA2:     CMPI   L3, 0              ; if LS.sign
+	     DBE    NoNegAd2           ; no, branch
+	     MOV    L10, L8            ; EXP = LD.exp
+	     NOT    L2, L2
+	     NOT    L1, L1
+	     ADDI   L2, 1
+	     ADDC   L1, C
+NoNegAd2:
+	     SUB    L10, L4            ;
+	     BLT    LsGtADD            ;
+	     DBE    SkipAd4            ;
+	     MOVD   L3, 0              ;
+	     CMPI   L10, 54            ;
+	     BLE    ADDD1              ;
+	     CMPBI  SR,0x00006000       ; chech rm=00
+	     BNZ    NoADDD1            ;
+	     MOVD   L1, L1             ; check for ls != 0 (inexact)
+	     BZ     NoAdddSt
+	     ORI    G2, 0x00000100      ;
+	     CMPBI  SR, 0x00000100      ; check if inexact trap=enable
+	     BNE    TrapInexDA1        ; yes, branch
+	     ANDNI  G2, 0x00001F00
+	     ORI    G2, 1              ;
+NoAdddSt:    RET    PC, L11
+
+ADDD1:       CMPI   L10, 32            ;
+	     BLT    SkipAd0            ;
+	     MOV    L3, L2             ;
+	     MOV    L2, L1             ;
+	     SETNM  L1                 ;
+	     ADDI   L10, -32           ;
+SkipAd0:     SHRD   L3, L10            ; L1//L2//L3//L4 << L10
+	     SHL    L3, L10            ;
+	     SHRD   L2, L10            ;
+	     SHL    L2, L10            ;
+	     SARD   L1, L10            ;
+SkipAd4:     MOV    L10, L8            ;
+	     DBR    RealADDD           ;
+	     MOVD   L7, 0              ;
+
+LsGtADD:     NEG    L10, L10           ;
+	     CMPI   L10, 54            ;
+	     DBLE   SkipAd1            ;
+	     MOVD   L7, 0              ;
+	     CMPBI  SR,0x00006000       ; check rm=00
+	     BNZ    NoADDD2            ; if rm <> 00 branch
+	     MOV    L5, L5             ; check for ld != 0 (inexact)
+	     DBZ    RealADDD1          ; no, perform addition
+	     MOVD   L5, 0              ; using ld=0
+	     ORI    G2, 0x00000100      ; set inexact flag
+	     BR     RealADDD1          ; and continue with addition
+
+SkipAd1:     CMPI   L10, 32            ;
+	     BLT    SkipAd2            ;
+	     MOV    L7, L6             ;
+	     MOV    L6, L5             ;
+	     SETNM  L5                 ;
+	     ADDI   L10, -32           ;
+SkipAd2:     SHRD   L7, L10            ; L5//L4//L3//L2 >> L10
+	     SHL    L7, L10            ;
+	     SHRD   L6, L10            ;
+	     SHL    L6, L10            ;
+	     SARD   L5, L10            ;
+RealADDD1:   MOV    L10, L4            ;
+	     MOVD   L3, 0              ;
+
+RealADDD:    ADD    L8, L4             ; Ld += Ls
+	     ADDC   L7, L3             ;
+	     ADDC   L6, L2             ;
+	     ADDC   L5, L1             ;
+	     BZ     StrADDDZ           ;
+	     DBNN   NormADDD           ;
+	     SETN   L9                 ;
+	     NOT    L8, L8             ;  twos complement of
+	     NOT    L7, L7             ;  Ld//Ldf//Ldff//Ldfff
+	     NOT    L6, L6
+	     NOT    L5, L5
+	     ADDI   L8, 1
+	     ADDC   L7, C
+	     ADDC   L6, C
+	     ADDC   L5, C
+NormADDD:    TESTLZ L4, L5             ;
+	     ADDI   L4, -11            ;
+	     BZ     FinADDD            ;
+	     DBN    ShrADDD            ;
+	     SUB    L10, L4            ;
+
+ShlADDD:     SHLD   L5, L4             ; L5//L6//L7//L8 << L4
+	     SHR    L6, L4             ;
+	     SHLD   L6, L4             ;
+	     SHR    L7, L4             ;
+	     DBR    NormADDD           ;
+	     SHLD   L7, L4             ;
+
+ShrADDD:     NEG    L4, L4             ; L5//L6//L7//L8 >> L4
+	     SHRD   L7, L4             ;
+	     SHL    L7, L4             ;
+	     SHRD   L6, L4             ;
+	     SHL    L6, L4             ;
+	     SHRD   L5, L4             ;
+
+FinADDD:     CMPI   L10, 0             ;
+	     BLE    UnderDIVDA         ; branch if underflow
+	     SHLDI  L7, 0
+	     BZ     AddNoInex
+	     ORI    G2, 0x00000100
+AddNoInex:   CMPBI  SR, 0x00006000      ; check rm=00
+	     BNZ    ARm1               ; if not 00 branch
+	     ADD    L8, L8             ; round to nearest-even
+	     ADDC   L7, L7
+	     ADDI   L6, CZ             ; perform rounding
+	     ADD    L5, C              ;
+CorrADD:     CMPBI  L5, 0x00200000      ;
+	     DBE    StrADDD            ;
+	     MOVD   L3, L11            ;
+	     ADDI   L10, 1             ;
+StrADDD:     CMPI   L10, 0x000007FF     ;
+	     BNN    OverDIVD           ;
+	     SHLI   L10, 20            ;
+	     BE     StrUnder           ;
+	     ANDNI  L5, 0xFFF00000      ;
+	     OR     L5, L10            ;
+	     SHLI   L9, 31             ;
+	     CMPBI  G2, 0x00000100      ; check if result inexact
+	     DBZ    NoInexSt           ; no, branch
+	     OR     L5, L9
+	     CMPBI  SR, 0x00000100      ; check if inexact.trap=enable
+	     BNE    TrapInexD
+	     ANDNI  G2, 0x00001F00
+	     ORI    G2, 1
+NoInexSt:
+	     STW.S  L0, L6,-4          ; store LD
+	     STW.S  L0, L5, 0          ; store LDf
+	     RET    PC, L11            ; leave
+
+StrADDDZ:    SET0   L10
+	     SHRI   L9, 1              ;
+	     BNC    SameSign           ;
+	     MOV    L9,SR              ;
+	     SHRI   L9,14              ; check SR(13)
+	     BC     AChk               ; if SR(13)=1 branch
+SameSign:    SHRDI  L9, 1              ;
+AChk:        STW.S  L0, 0,-4           ; store LDf == zero
+	     STW.S  L0, L10, 0         ; store LD  == zero
+	     RET    PC, L11
+ARm1:
+	     CMPBI  SR,0x00004000       ; check SR(14)
+	     SETNZ  L1
+	     SHRDI  L7,0               ; check l7//l8=0
+	     BZ     CorrADD            ; if zero branch
+	     CMPBI  SR, 0x00002000      ; check SR(13)
+	     SETNZ  L2
+	     XOR    L2,L9              ;
+	     AND    L2,L1              ;
+	     ADD    L6,L2              ; l6+= rounding bit
+	     DBR    CorrADD
+	     ADD    L5,C               ; l5+= carry bit
+
+NoADDD2:     MOVD   L9,L1
+	     MOVD   L1,L5
+	     MOVD   L5,L9
+	     MOV    L8,L4
+NoADDD1:     MOV    L10,L8
+	     CMPI   L5,0               ;
+	     DBNN   NoNegD1            ; if l5>0 branch
+	     SETN   L9                 ; l9=result.sign
+	     NOT    L6, L6
+	     NOT    L5, L5
+	     ADDI   L6, 1
+	     ADDC   L5, C
+NoNegD1:     SHRDI  L1,0
+	     BZ     CorrADD
+	     SETN   L2
+	     ORI    G2,0x00000100
+	     CMPBI  SR,0x00004000       ; check SR(14)
+	     SETNZ  L3
+	     CMPBI  SR,0x00002000       ; check SR(13)
+	     SETNZ  L4
+	     XOR    L4,L9              ;
+	     AND    L4,L3              ;
+	     XOR    L2,L9              ;
+	     BNZ    SignDiff           ;
+	     ADD    L6,L4              ;
+	     DBR    CorrADD
+	     ADD    L5,C               ;
+SignDiff:
+	     SHRI   L4, 1              ;
+	     SETNC  L4                 ;
+	     SUB    L6,L4              ;
+	     SUB    L5,C               ;
+	     CMPBI  L5, 0xfff00000     ;
+	     SETZ   L4                 ;
+	     SUB    L10,L4             ;
+	     ANDNI  L5, 0xfff00000     ;
+	     ORI    L5,0x00100000      ;
+	     BR     CorrADD
+
+NanInfADD:   BHT    NanADD             ; if LD == NAN then branch
+	     MOV    L6, L6             ; check ld.low
+	     BNZ    NanADD             ; branch if ld=nan
+	     CMPI   L1, 0xFFE00000     ; if LS != (NAN OR INF)
+	     BST    InfADD1            ; do not add, LD//Ldf == +- INF
+	     BHT    InfNanDS           ; IF LS == NAN, then branch
+	     MOV    L2, L2             ; check ls.low
+	     BNZ    InfNanDS           ; branch if ls=nan
+	     CMP    L3, L7             ; if LD.sign == LS.SIGN
+	     BNE    StdNanAS           ; inf-inf
+InfADD1:     RET    PC, L11
+
+NanADD:      SHRI   L5, 2              ; if LD == NANs
+	     BST    StdNanAS           ; yes, branch
+	     ANDNI  L1, 0x001ffffc      ; check for ls=NANs
+	     CMPI   L1, 0xFFE00002      ;
+	     BE     StdNanAS           ; yes, exception
+	     BR     StdNanAQ           ; no, no exception
+InfNanDS:
+	     SHRI   L1, 2              ;
+	     BHE    StdNanAQ           ; yes, branch
+	     BR     StdNanAS           ; no, exception
+
+NanInfADS:   BHT    InfNanDS           ; if LS == NAN, then branch
+	     MOV    L2, L2             ; check ls.low
+	     BNZ    InfNanDS           ; branch if ls=nan
+	     STW.S  L0, L14, -4        ; store LS (infinity)
+	     STW.S  L0, L13, 0         ; store LSf
+	     RET    PC, L11            ; leave
+
+NoInvATRAP:  ORI    G2, 0x00000010     ; set accrued.invalid.exception
+StdNanAQ:    ANDNI  G2, 0x00001F00     ; clear actual except.
+	     MOVI   L5, NANq          ; LD = NANq
+	     STW.S  L0, 0, -4         ; store Ldf
+	     STW.S  L0, L5, 0         ; store Ld=NANq
+	     RET    PC, L11           ; leave
+
+StdNanAS:    CMPBI  SR, 0x00001000     ; if invalid.floating trap = enable
+	     BE     NoInvATRAP        ; no, branch
+	     ANDNI  G2, 0x00001F00     ; delete actual exception
+	     ORI    G2, 0x00001000     ; set actual.invalid.exception
+	     MOVI   L5, NANs
+	     ADDI   L0,-4
+	     MOVD   L3, L11
+	     ADDI   L15, ExNrInv
+	     MOVD   L1, L13
+	     MOV    L7, L15
+	     SUM    PC, PC, FloatErrorEntry - $
+;
+; Register Layout:
+;
+;       L0 : ADDRESS of LD
+;       L1 : LS high
+;       L2 : LS low
+;       L3 : PC
+;       L4 : SR
+;       L5 : LD high
+;       L6 : LD low
+;       L7 : RESULT[0]
+;       L8 : RESULT[1]
+;       L9 : RESULT[2]
+;       L10: RESULT[3]
+;       L11: SIGN
+;       L12: EXP
+;       L13: LS high (saving)
+;       L14: LS low (saving)
+;       L15: Exceptionnumber
+;
+;  A * B --> A.m * B.m * (A.exp + B.exp)
+;  Single Floating Point multiplication
+;
+
+NoHidM1:     TESTLZ L9, L5             ;
+	     CMPI   L9, 32             ;
+	     BLT    NotAllZ1           ;
+	     MOV    L5, L6
+	     SET0   L6
+	     ADDI   L12, -32
+	     TESTLZ L9, L5
+	     CMPI   L9, 4
+	     BHE    NotAllZ1
+	     SHRI   L5, 4
+	     ADDI   L12, 4
+	     ADDI   L9, 4
+NotAllZ1:    ADDI   L9, -4             ;
+	     SHLD   L5, L9             ;
+	     BZ     StrDZZ             ;
+	     ADDI   L12, 6             ;
+	     DBR    HidM1              ;
+	     SUB    L12, L9            ;
+NoHidM2:     TESTLZ L9, L1             ;
+	     CMPI   L9, 32             ;
+	     BLT    NotAllZ2           ;
+	     MOV    L1, L2             ;
+	     SET0   L2
+	     ADDI   L12, -32
+	     TESTLZ L9, L1
+	     CMPI   L9, 5
+	     BHE    NotAllZ2
+	     SHRI   L1, 5
+	     ADDI   L12, 5
+	     ADDI   L9, 5
+
+NotAllZ2:    ADDI   L9, -5             ;
+	     SHLD   L1, L9             ;
+	     BZ     StrDZZ1            ;
+	     ADDI   L12, 5             ;
+	     DBR    HidM2              ;
+	     SUB    L12, L9            ;
+StrDZZ1:     MOVD   L5, L1
+StrDZZ:      SHLI   L11, 31
+	     OR     L5, L11
+	     STW.S  L0, L6, -4          ; store LDf
+	     STW.S  L0, L5, 0           ; store LD
+	     RET    PC, L3              ; leave
+
+FMULDEntry:
+	     FRAME  L0, L0            ;
+	     MOVI   L15, OffsetMuld
+	     CMPBI  L4, LFLAG          ; ReturnSR.LockFlag set ?
+	     DBNZ   LoadLDf            ; Yes: --> LoadLDf
+	     MOVD   L13, L1
+;	     ANDNI  SR, LFLAG          ; No : remove lock-flag
+LoadLDf:     LDW.S  L0, L5, 4          ;
+	     LDW.S  L0, L6, 0          ; load LDf
+	     ADD    L2, L2             ; check and remove ls.sign
+	     ADDC   L1, L1
+	     SETC   L11                ; save ls.sign
+	     ADD    L6, L6             ; check and remove ld.sign
+	     ADDC   L5, L5
+	     ADD    L11, C             ; LD: Store Sign Bit
+	     CMPI   L5, 0xFFE00000      ; if LD == (NAN OR INF)
+	     BHE    NanInfMDD          ; yes, branch
+	     CMPI   L1, 0xFFE00000      ; if LS == (NAN OR INF)
+	     BHE    NanInfMDS          ; yes, branch
+	     MOV    L12, L5            ; EXP = LD
+	     SHRI   L12, 21            ; if ld.exp == 0, EXP = real EXP
+	     BZ     NoHidM1            ; yes, branch
+	     SHLDI  L5, 5              ; correct LD.EXP
+	     SHLI   L5, 5              ; ld.man = ld - ld.exp
+	     ORI    L5, 0x80000000      ; insert hidden bit
+	     SHRI   L5, 5              ; correct ld.man position
+HidM1:
+	     MOV    L10, L1            ; TEMP = LS
+	     SHRI   L10, 21            ; if ls.exp == 0, TEMP = real LS.EXP
+	     DBZ    NoHidM2            ; yes, branch
+	     ADD    L12, L10           ; EXP = LD.EXP + LS.EXP
+	     SHLDI  L1, 4              ; correct LS.EXP
+	     SHLI   L1, 6              ; ls.man = ls - ls.exp
+	     ORI    L1, 0x80000000      ; insert hidden bit
+	     SHRI   L1, 6              ; correct ls.man position
+HidM2:
+	     ; LD//LDf * LS//LSf -> L7//L8//L9//L10
+
+	     MOV    L9, L2             ;
+	     MULU   L9, L6             ; LDf * LSf -> L9//L10
+	     MOV    L7, L1             ;
+	     MULU   L7, L6             ; LDf * LS -> L7//L8
+	     ADD    L9, L8             ; L8//L9 += L7//L8
+	     SET0   L8                 ;
+	     ADDC   L8, L7             ;
+	     MOV    L6, L2             ;
+	     MULU   L6, L5             ; LD * LSf -> L6//L7
+	     ADD    L9, L7             ; L8//L9 += L6//L7
+	     ADDC   L8, L6             ;
+	     MULU   L5, L1             ; LD * LS -> L5//L6
+	     SET0   L7                 ; L7//L8 += L5//L6
+	     ADD    L8, L6             ;
+	     ADDC   L7, L5             ;
+	     TESTLZ L6, L7             ; (only L6=11 and L6=12 are possible???)
+	     ADDI   L6, -11            ;
+	     BZ     SkipMShift         ;
+	     BN     ShiftNeg           ;
+	     SUB    L12, L6            ; L7//L8//L9//L10 >> L6
+	     SHLD   L7, L6             ;
+	     SHR    L8, L6             ;
+	     SHLD   L8, L6             ;
+	     SHR    L9, L6             ;
+	     DBR    SkipMShift
+	     SHLD   L9, L6             ;
+
+ShiftNeg:    NEG    L6, L6             ; L7//L8//L9//L10 << L6
+	     ADD    L12, L6
+	     SHRD   L9, L6
+	     SHL    L9, L6
+	     SHRD   L8, L6
+	     SHL    L8, L6
+	     SHRD   L7, L6
+SkipMShift:
+	     ADDI   L12, -1022         ;
+	     BLE    UnderMD            ;
+	     SHLDI  L9, 0              ; check if result inexact
+	     BZ     MulNoInex          ;
+	     ORI    G2, 0x00000100      ; set inexact
+MulNoInex:
+	     CMPBI  SR,0x00006000       ; check rm=00
+	     BNZ    MRm1               ; if rm<>00 branch
+	     ADD    L10, L10           ; round ro nearest-even
+	     ADDC   L9, L9
+	     ADDI   L8, CZ             ; perform rounding
+	     ADD    L7, C              ;
+CorrMUD:     CMPBI  L7, 0x00200000      ;
+	     BZ     NoMulDCor          ;
+	     ADDI   L12, 1             ;
+NoMulDCor:   CMPI   L12,0x000007FF      ;
+	     BGE    OverMD             ;
+StdMULT:
+	     SHLI   L12, 20            ;
+	     BE     UnderMZD           ;
+	     ANDNI  L7, 0xFFF00000      ;
+	     OR     L7, L12            ;
+	     SHLI   L11, 31            ;
+	     OR     L7, L11            ;
+	     STW.S  L0, L8, -4         ;
+	     STW.S  L0, L7, 0          ;
+	     CMPBI  G2, 0x00000100      ; check if result inexact
+	     BZ     StdNoInex          ; no, then branch
+	     CMPBI  SR, 0x00000100      ; check, if inexact.trap=enable
+	     BNE    TrapInexD          ;
+	     ANDNI  G2, 0x00001F00
+	     ORI    G2, 1              ; set accrued.inexact exception
+StdNoInex:   RET    PC, L3             ;
+;
+;************************************************
+;
+UnderMD:     MOVD   L5, L7             ; l7//l8  -> l5//l6
+	     MOVD   L7, L9             ; l9//l10 -> l7//l8
+	     DBR    UnderDIVD
+	     MOVD   L9, L11            ;
+OverMD:      MOVD   L5, L7
+	     DBR    OverDIVD
+	     MOVD   L9, L11            ;
+UnderMZD:    MOVD   L5, L7             ;
+	     DBR    StrUnder           ;
+	     MOVD   L9, L11            ;
+;
+;************************************************
+;
+MRm1:
+	     CMPBI  SR,0x00004000       ; check SR(14)
+	     SETNZ  L1
+	     SHRDI  L9,0               ; check l9//l10=0
+	     BZ     CorrMUD            ; branch without rounding
+	     CMPBI  SR, 0x00002000      ; check SR(13)
+	     SETNZ  L2
+	     XOR    L2,L11             ;
+	     AND    L2,L1              ;
+	     ADD    L8,L2              ; l6+= rounding bit
+	     DBR    CorrMUD
+	     ADD    L7,C               ; l5+= carry bit
+
+NanInfMDS:   BHT    NanMD1             ;
+	     MOV    L2, L2             ; check ls.low
+	     BNZ    NanMD1             ; branch if ls=nan
+	     SHLDI  L5, 0              ; ls=inf, check if ld=0
+	     BE     StdNanS            ; invalid operation in this case
+	     BR     InfMD              ; else store inf
+
+NanInfMDD:   BHT    NanMD              ; IF LD == NAN then branch
+	     MOV    L6, L6             ; check ld.low
+	     BNZ    NanMD              ; branch if ld=nan
+	     CMPI   L1, 0xFFE00000      ; if LS == (NAN OR INF ?)
+	     BHT    NanMDS             ; if ls=nan, branch
+	     BST    NanInfMDD1         ; if ls=normal, continue
+	     MOV    L2, L2             ; check ls.low
+	     BNZ    NanMDS             ; branch if ls=nan
+NanInfMDD1:  SHLDI  L1, 0              ; ld=inf, ls=inf or norm, check if ls=0
+	     BE     StdNanS            ; invalid operation in this case
+InfMD:       MOVI   L5, 0x7FF00000      ; else return inf
+	     SHLI   L11, 31            ;
+	     OR     L5, L11            ;
+	     STW.S  L0,  0,-4          ;
+	     STW.S  L0, L5, 0          ;
+	     RET    PC, L3             ;
+
+NanMDS:      SHRI   L1, 2              ; check, if ls=NANs
+	     BC     StdNanS
+	     BR     StdNanQ
+
+NanMD:       SHRI   L5, 2              ; check, if ld=NANs
+	     BC     StdNanS            ; yes, exception
+	     ANDNI  L1, 0x001ffffc      ; check if ls=NaNs
+	     CMPI   L1, 0xFFE00002      ;
+	     BZ     StdNanS            ; yes, exception
+	     BR     StdNanQ            ; no exception
+
+NanMD1:      SHRI   L5, 2              ; check, if ld=NANs
+	     BC     StdNanS            ;
+	     BR     StdNanQ            ;
+;
+; Register Layout:
+;
+;       L0 : ADDRESS of LD
+;       L1 : LS high
+;       L2 : LS low
+;       L3 : PC
+;       L4 : SR
+;       L5 : LD high
+;       L6 : LD low
+;       L7 : RESULT high
+;       L8 : RESULT low
+;       L9 : SIGN
+;       L10: EXP
+;       L11: TEMP
+;       L12: TEMP
+;       L13: LS high (saving)
+;       L14: LS low (saving)
+;       L15: Exceptionnumber
+;
+;  A / B --> A.m / B.m * (A.exp - B.exp)
+;  Single Floating Point division
+;
+DenDIVD0:                              ; shift as much as possible-1 to left
+	     TESTLZ L8, L5             ; test leading zeros
+	     CMPI   L8, 32             ; if LD == zero
+	     BLT    SMALLER1           ; no, skip
+	     SHLDI  L5, 31             ; LD//LDf << 31
+	     BZ     StrDZ              ; LD = 0, then store 0
+	     ADDI   L10, -31           ; correct exponent
+	     BR     DenDIVD0
+
+SMALLER1:    SUB    L10, L8            ; correct exponent
+	     ADDI   L10, 11            ; without the first 11 bit
+	     ADDI   L8, -1             ; shift one less as possible
+	     DBR    SkipD0             ; skip
+	     SHLD   L5, L8             ; correct LD
+;
+DenDIVD1:                              ; shift as much as possible to left
+	     TESTLZ L8, L1             ; test leading zeros LS
+	     CMPI   L8, 32             ; if LS.high == zero
+	     BLT    SMALLER2           ; no, skip
+	     SHLDI  L1, 31             ; yes, LS//LSf << 31
+	     DBR    DenDIVD1           ; once again
+	     ADDI   L10, 31            ; correct EXP
+
+SMALLER2:    ADD    L10, L8            ; correct EXP
+	     ADDI   L10, -11           ; whitout the first 11 bit
+	     DBR    SkipD1
+	     SHLD   L1, L8             ; shift as much as possible
+;
+FDIVDZero:   ADD    L6, L6             ; check and remove ld.sign
+	     ADDC   L5, L5
+	     DBZ    StdNanS            ; branch if LD and Ldf == ZERO
+	     ADD    L9, C              ; set correct sign bit
+	     CMPI   L5, 0xFFE00000      ; if, ld//ldf=nan or inf
+	     BHT    ZeroNan            ; branch if ld=nan
+	     BST    FDIVDZero1         ; if ld=normal, continue
+	     MOV    L6, L6             ; check ld.low
+	     BNZ    ZeroNan            ; branch if ld=nan
+FDIVDZero1:  MOVI   L5,0x7FF00000       ; return inf on normal/0 and inf/0
+	     MOVI   L6,0
+	     SHLI   L9,31
+	     OR     L5,L9
+	     CMPBI  SR, 0x00000800      ; if div_by_zero.trap == enable
+	     BZ     NoDIVDEX1          ; no, then branch
+	     ANDNI  G2, 0x00001F00      ; del all actual.exception
+	     ORI    G2, 0x00000800      ; set actual.div_by_zero.exception
+	     ADDI   L15, ExNrZero      ; correct exceptionnumber
+	     ADDI   L0, -4
+	     MOVD   L1, L13
+	     MOV    L7, L15
+	     SUM    PC, PC, FloatErrorEntry - $
+
+ZeroNan:     SHRI   L5, 2              ; if ld//ldf = NANs
+	     BNC    StdNanQ            ; no ld=NANq
+	     BR     StdNanS            ; yes, exception
+NoDIVDEX1:
+	     ORI    G2, 8              ; set accrued.div_by_zero.flag
+	     STW.S  L0, 0, -4          ; store INF, LDf
+	     STW.S  L0, L5, 0          ; store INF, LD
+	     RET    PC, L3             ; leave
+;
+;
+FDIVDEntry:
+	     FRAME  L0, L0             ;
+	     MOVI   L15, OffsetDivd
+	     CMPBI  L4, LFLAG          ; ReturnSR.LockFlag set ?
+	     DBNZ   FDIVLoad           ; Yes: --> FDIVLoad
+	     MOVD   L13, L1
+	     ANDNI  SR,LFLAG           ; No : Remove LFLAG
+FDIVLoad:    LDW.S  L0, L5, 4          ;
+	     LDW.S  L0, L6, 0          ; Load LD.high
+	     ADD    L2, L2             ; check and remove ls.sign
+	     ADDC   L1, L1
+	     DBZ    FDIVDZero          ; XX / 0 == undefined
+	     SETC   L9                 ; save ls.sign
+	     ADD    L6, L6             ; check and remove ld.sign
+	     ADDC   L5, L5
+	     ADD    L9, C              ; LD: Store Sign Bit
+	     CMPI   L5, 0xFFE00000      ; if LD == (NAN OR INF)
+	     BNC    NanInfDDD          ; yes, branch
+	     CMPI   L1, 0xFFE00000      ; if LS == (NAN OR INF)
+	     BNC    NanInfDDS          ; yes, branch
+	     MOV    L10, L5            ; EXP = LD.EXP
+	     SHRI   L10, 21            ; if ld.exp == 0,EXP = real EXP
+	     BZ     DenDIVD0           ; yes, branch
+	     SHLDI  L5, 10             ; ld.man = ld - ld.exp
+	     ORI    L5, 0x80000000      ; insert hidden bit
+	     SHRDI  L5, 1              ; correct position of ld
+SkipD0:
+	     MOV    L8, L1             ; TEMP = LS.EXP
+	     SHRI   L8, 21             ; if ls.exp == 0, TEMP = real LS.EXP
+	     BZ     DenDIVD1           ; yes, branch
+	     SUB    L10, L8            ; EXP = LD.EXP + LS.EXP
+	     SHLDI  L1, 10             ; correct LS
+	     ORI    L1, 0x80000000      ; insert hidden bit
+SkipD1:
+
+; Newton iteration for 64bit / 64bit
+;
+NEWTON:      DIVU   L5, L1             ;
+	     MOV    L7, L6             ;
+	     SHRI   L2, 1              ;
+	     MULU   L7, L2             ;
+	     SHRI   L5, 1              ;
+	     SUB    L7, L5             ;
+	     BNC    PosDIVD            ;   modified 1/11/96 m.schlett
+	     NOT    L8, L8
+	     NOT    L7, L7
+	     ADDI   L8, 1
+	     ADDC   L7, C
+	     DIVU   L7, L1             ;
+	     MOV    L5, L6             ;
+	     MOV    L1, L8
+	     ADD    L8, L8             ; shli l8, 1
+	     ADD    L5, C              ;
+	     MOV    L6, L8             ;
+	     DBR    SkipD3             ;
+	     SET1   L8                 ; marker for remainder calculation
+
+PosDIVD:     DIVU   L7, L1             ;
+	     MOV    L5, L6             ;
+	     MOV    L1, L8             ; save l8
+	     ADD    L8, L8             ; shli l8, 1
+	     SUB    L5, C              ;
+	     SET0   L6                 ;
+	     SUB    L6, L8             ;
+	     SUB    L5, C              ;
+	     SET1M  L8                 ; marker for remainder calculation
+SkipD3:
+	     ;ANDNI  L6, 0x00000001      ; last bit may be wrong
+	     MOV    L11, L7            ; store ls
+	     MOV    L12, L2            ; store lsf
+	     TESTLZ L2, L5             ; check how far we must shift
+	     SUB    L10, L2            ; correct EXP if important
+	     NEG    L2, L2             ; correct shift value
+	     ADDI   L2, 11             ; 11 bits must be free
+	     SET0   L7                 ; trible shift
+	     SHRD   L6, L2             ; LD//LDf//L7 >> L2
+	     SHL    L6, L2             ;
+	     SHRD   L5, L2             ;
+	     ADDI   L10, 1023
+	     CMPI   L7, 0x7FC00000      ; check if
+	     BNC    CalcMod            ; if N=0 calculate remainder
+	     CMPBI  SR, 0x00006000      ; check rm
+	     BNZ    CalcMod            ;
+	     SET0   L8                 ; no remainder
+DDNearest:
+	     CMPI   L10, 0
+	     BLE    UnderDIVDD
+	     ADD    L7, L8
+	     CMPI   L7, 0
+	     BE     DDNoInex
+	     ORI    G2, 0x00000100
+DDNoInex:    BNN    DDnoRound
+	     SET0   L8
+	     ADD    L7, L7             ; round to nearest-even
+	     ADDI   L6, CZ             ; perform rounding
+             ADD    L5, C
+
+DDnoRound:
+	     CMPBI  L5, 0x00200000      ; is there an overflow after rounding
+	     BZ     NoDIVDCor          ; no, skip
+	     ADDI   L10, 1             ; correct EXP
+
+NoDIVDCor:   CMPI   L10, 0x000007FF     ; check if overflow
+	     BNN    OverDIVD           ; if l10>=7ff branch
+	     SHLI   L10, 20            ; align EXP
+	     BE     StrUnder           ;
+StoreDIVDS:  SHLI   L9, 31             ; set correct sign
+	     ANDNI  L5, 0xFFF00000      ; remove hidden bit
+	     OR     L5, L10            ; ld = ld.man + ld.exp
+	     OR     L5, L9             ; insert correct sign
+StoreDIVD:   STW.S  L0, L6, -4         ; store LD low
+	     STW.S  L0, L5, 0          ; store LD high
+	     CMPBI  G2, 0x00000100      ; check if inexact
+	     BZ     DIVDNoInex
+	     CMPBI  SR, 0x00000100      ; check if inexact.trap=enable
+	     BNE    TrapInexD
+	     ANDNI  G2, 0x00001F00
+	     ORI    G2, 1              ; set accrued.inexact exception
+DIVDNoInex:  RET    PC, L3             ; return
+
+;            ---- calculate remainder
+CalcMod:     ;MOV    L8, L12            ;
+	     MULU   L1, L12            ; preliminary remainder (+-1) in L8
+	     CMP    L11, L1 
+	     BN     NegMod             ; store sign of remainder
+	     BNE    ForwMod            ; leave remainder as is
+	     MOV    L2, L2             ; check low word of product
+	     BZ     ZeroMod            ; set remainder zero, else negative
+NegMod:
+	     DBR    ForwMod
+	     NEG    L8, L8             ; change sign of remainder
+ZeroMod:     
+	     SET0   L8                 ; l8=CarryFlag
+ForwMod:     CMPBI  SR, 0x00006000      ; check rounding mode = 00
+	     BZ     DDNearest          ; if rm=00 branch
+DDnotNear:
+	     ADD    L7, L8             ;
+	     SHLI   L7, 0
+	     BZ     DDnNZero
+	     BNN    DDnNFor
+	     ADDI   L6, 0xFFFFFFFF      ; l6 -= 1
+	     BC     DDnNFor            ; if carry branch
+	     ADDI   L5, 0xFFFFFFFF      ; l5 -= 1
+	     CMPBI  L5, 0xfff00000
+	     SETZ   L8
+	     SUB    L10, L8
+	     SHLD   L5, L8
+	     ANDNI  L5, 0xfff00000
+DDnNFor:
+	     ORI    G2, 0x00000100
+	     SHRDI  L10,0
+	     DBLE   UnderDIVD
+	     SET0   L8
+	     CMPBI  SR,0x00004000       ; check SR(14)
+	     SETNZ  L1
+	     CMPBI  SR, 0x00002000      ; check SR(13)
+	     SETNZ  L2
+	     XOR    L2,L9              ;
+	     AND    L2,L1              ;
+	     ADD    L6,L2              ; l6+= rounding bit
+	     DBR    DDnoRound
+	     ADD    L5,C               ; l5+= carry bit
+;
+DDnNZero:    SHRDI  L10,0
+	     BLE    UnderDIVD
+	     BR     DDnoRound
+;
+;************************************************
+;
+UnderDIVDD:
+	     ADD    L7, L8
+	     DBNN   UnderDIVD
+	     SUB    L6, C
+	     SUB    L5, C
+	     CMPBI  L5, 0xfff00000
+	     SETZ   L8
+	     SUB    L10, L8
+	     SHLD   L5, L8
+	     ANDNI  L5, 0xfff00000
+	     SHR    L6, L8
+	     SHLD   L6, L8
+	     DBR    UnderDIVD
+	     SET0   L8
+UnderDIVDA:
+	     MOVD   L3, L11            ; save PC//SR correctly
+UnderDIVD:
+	     CMPBI  SR, 0x00000200      ; if underflow.trap = enable
+	     BNE    TrapUnderD         ; yes, branch
+	     ORI    G2, 2              ; set accrued.underflow.exception
+	     MOVD   L1, L9
+	     NEG    L2, L2             ; correct exp, exp = -exp
+	     CMPI   L2, 54             ; if exp.diff > 55
+	     BGE    RoundDZ            ; yes, then branch
+StrUnder:    ADDI   L2, 1              ; exp +=1 for denorm. numbers
+	     CMPI   L2, 32             ; if exp.diff < 32
+	     BLT    UnderSHD           ; then branch
+	     MOV    L9, L8
+	     MOV    L8, L7
+	     MOV    L7, L6
+	     MOV    L6, L5
+	     SET0   L5
+	     ADDI   L2,-32             ;
+UnderSHD:    SET0   L10
+	     SHRD   L8, L2             ; L5//L6//L7//L8//L9//L10 >>L2
+	     SHL    L8, L2             ;
+	     SHRD   L7, L2             ;
+	     SHL    L7, L2
+	     SHRD   L6, L2             ;
+	     SHL    L6, L2             ;
+	     SHRD   L5, L2             ;
+	     SHRDI  L9, 0
+	     BNZ    InexactD            ;
+	     SHRDI  L7, 0              ;
+	     BNE    InexactD           ;
+	     MOV    L9, L1
+	     MOVI   L10, 0             ;
+	     BR     StoreDIVDS
+
+TrapUnderD:  ANDNI  G2, 0x00001F00      ; del all actual.exception
+	     ORI    G2, 0x00000200      ; set actual.underflow.exception
+	     ADDI   L10, -1536
+	     TESTLZ L2, L5
+	     ADDI   L2, -11
+	     SUB    L10, L2
+	     CMPI   L2, 21
+	     BLT    TrUnShift
+TrCorrZero:
+	     SHLDI  L5, 21
+	     SHRI   L6, 21
+	     SHLDI  L6, 21
+	     SHRI   L7, 21
+	     SHLDI  L7, 21
+	     ADDI   L10, -21
+	     TESTLZ L2, L5
+	     CMPI   L2, 32
+	     DBGE   TrCorrZero
+	     ADDI   L2, -11
+TrUnShift:
+	     SHLD   L5, L2
+	     SHR    L6, L2
+	     SHLD   L6, L2
+	     CMPBI  SR,0x00006000
+	     BNZ    TrUnderNNear
+	     ADD    L8, L8             ; round to nearest-even
+	     ADDC   L7, L7
+	     ADDI   L6, CZ             ; perform rounding
+	     ADD    L5, C
+TrStoreUn:   CMPBI  L5, 0x00200000
+	     BZ     NoCorUnder
+	     ADDI   L10, 1
+NoCorUnder:
+	     ANDNI  L5, 0xFFF00000
+	     SHLI   L9, 31
+	     SHLI   L10, 20
+	     OR     L5, L9
+	     OR     L5, L10
+	     ADDI   L15, ExNrUnder
+	     ADDI   L0,-4
+	     MOVD   L1, L13
+	     MOV    L7, L15
+	     SUM    PC, PC, FloatErrorEntry - $
+
+TrUnderNNear:
+	     CMPBI  SR,0x00004000       ; check SR(14)
+	     SETNZ  L1
+	     SHRDI  L7, 0              ; check l7//l8=0
+	     BZ     TrStoreUn          ; branch without rounding
+	     CMPBI  SR, 0x00002000      ; check SR(13)
+	     SETNZ  L2
+	     XOR    L2, L9             ;
+	     AND    L2, L1             ;
+	     ADD    L6, L2              ; l6+= rounding bit
+	     DBR    TrStoreUn
+	     ADD    L5,C               ; l5+= carry bit
+
+RoundDZ:     SET0   L5                 ;
+	     MOV    L9, L1
+	     CMPBI  SR,0x00004000       ; check SR(14)
+	     DBZ    StrDZ              ; if SR(14)=1 branch
+	     SET0   L6
+	     CMPBI  SR,0x00002000       ; check SR(13)
+	     SETNZ  L1
+	     XOR    L1, L9
+	     ADD    L6, L1
+StrDZ:       SHLI   L9, 31
+	     OR     L5, L9
+	     STW.S  L0, L6, -4          ; store LDf
+	     STW.S  L0, L5, 0           ; store LD
+	     RET    PC, L3              ; leave
+
+InexactD:    ORI    G2, 0x00000100      ; set actual underflow.except.
+	     ORI    G2, 2              ; set accrued underflow.except.
+	     CMPBI  SR, 0x00006000      ;
+	     BNZ    InexNotNear        ;
+	     SHLDI  L9, 0              ;
+	     BZ     InexUnAdd          ;
+	     ORI    L8, 0x00000001
+InexUnAdd:   ADD    L8, L8             ; round to nearest-even
+             ADDC   L7, L7
+	     ADDI   L6, CZ             ; perform rounding
+InexForw:    ADD    L5, C              ;
+InexNoRound: MOV    L9, L1
+	     SET0   L10
+	     CMPBI  L5, 0xfff00000
+	     SETNZ  L11
+	     ADD    L10, L11
+	     ANDNI  L5, 0xfff00000
+	     DBR    StoreDIVDS
+	     SHLI   L10, 20
+InexNotNear:
+	     CMPBI  SR,0x00004000       ; check SR(14)
+	     SETNZ  L11
+	     CMPBI  SR, 0x00002000      ; check SR(13)
+	     SETNZ  L12
+	     XOR    L12,L1             ;
+	     AND    L12,L11            ;
+	     DBR    InexForw
+	     ADD    L6,L12             ; l6+= rounding bit
+TrapInexDA1:
+	     ADDI   L0,-4
+	     LDW.S  L0,L5,4
+	     LDW.S  L0,L6,0
+	     MOVD   L3, L11
+TrapInexD:   ANDNI  G2, 0x00001F00      ; clear all actual exceptions
+	     ORI    G2, 0x00000100      ; set actual inexact.exception
+	     ADDI   L15, ExNrInex
+	     ADDI   L0,-4
+	     MOVD   L1, L13
+	     MOV    L7, L15
+	     SUM    PC, PC, FloatErrorEntry - $
+
+OverDIVD:    CMPBI  SR, 0x00000400      ; if overflow.trap = enable
+	     BNE    TrapOverD          ; yes, branch
+	     CMPBI  SR, 0x00000100      ; if inexact.trap=enable
+	     BNE    TrapInexD
+	     ANDNI  G2,0x00001F00       ; clear all actual exceptions
+	     ORI    G2, 5              ; set accrued.overflow.exception
+	     CMPBI  SR, 0x00006000      ; check rm=00
+	     BNZ    ODRm1              ; if rm<>00 branch
+	     MOVI   L5, 0x7FF00000      ; LD = INF
+	     SHLI   L9, 31             ; correct sign position
+	     OR     L5, L9             ; insert sign
+	     STW.S  L0,  0,-4          ; store LDf
+	     STW.S  L0, L5, 0          ; store LD
+	     RET    PC, L3             ; leave
+
+TrapOverD:   ANDNI  G2, 0x00001F00      ; del all actual.eception
+	     ORI    G2, 0x00000400      ; set actual.overflow.exception
+	     ADDI   L10, 1536
+	     TESTLZ L2, L5
+	     ADDI   L2, -11
+	     SUB    L10, L2
+	     SHLD   L5, L2
+	     SHR    L6, L2
+	     SHLD   L6, L2
+	     CMPBI  SR,0x00006000
+	     BNZ    TrOverNNear
+	     ADD    L8, L8             ; round to nearest-even
+	     ADDC   L7, L7
+	     ADDI   L6, CZ             ; perform rounding
+	     ADD    L5, C
+TrStoreOv:   CMPBI  L5, 0x00200000
+	     BZ     NoTrapCor
+	     ADDI   L10, 1
+NoTrapCor:   ANDNI  L5, 0xFFF00000
+	     SHLI   L9, 31
+	     SHLI   L10, 20
+	     OR     L5, L9
+	     OR     L5, L10
+	     ADDI   L15, ExNrOver      ; correct errornumber
+	     ADDI   L0,-4
+	     MOVD   L1, L13
+	     MOV    L7, L15
+	     SUM    PC, PC, FloatErrorEntry - $
+
+TrOverNNear:
+	     CMPBI  SR,0x00004000       ; check SR(14)
+	     SETNZ  L1
+	     SHRDI  L7, 0              ; check l7//l8=0
+	     BZ     TrStoreOv          ; branch without rounding
+	     CMPBI  SR, 0x00002000      ; check SR(13)
+	     SETNZ  L2
+	     XOR    L2,L11             ;
+	     AND    L2,L1              ;
+	     ADD    L6,L2              ; l6+= rounding bit
+	     DBR    TrStoreOv
+	     ADD    L5,C               ; l5+= carry bit
+
+ODRm1:       MOVI   L5,0x7FEFFFFF       ;
+	     MOVI   L6,0xFFFFFFFF       ; ld//ldf=max
+	     CMPBI  SR,0x00004000       ; check SR(14)
+	     BZ     Rm1Store           ; if SR(14)=0 rm=01
+	     CMPBI  SR,0x00002000       ; check SR(13)
+	     SETNZ  L1
+	     XOR    L1,L9              ;
+	     ADD    L6,L1              ; ldf+=l1
+	     ADD    L5,C               ; ld+=carry
+Rm1Store:    SHLI   L9,31              ; correct position of sign
+	     OR     L5,L9              ; signed max or inf
+	     STW.S  L0, L6, -4         ; store ldf
+	     STW.S  L0, L5, 0          ; store ld
+	     RET    PC, L3             ; leave
+
+;
+;************************************************
+;
+NanInfDDS:   BHT    NanDDS             ;
+	     MOV    L2, L2             ; check ls.low
+	     BNZ    NanDDS             ; branch if ls=nan
+	     SHLI   L9, 31             ; correct position of sign
+	     SET0   L5                 ; normal/inf, return 0
+	     OR     L5, L9             ; ld=ld.sign|zero
+	     STW.S  L0, 0, -4          ; store ldf
+	     STW.S  L0, L5, 0          ; store ld
+	     RET    PC, L3             ; leave
+
+NanInfDDD:   BHT    NanDD              ; IF LD == NAN then branch
+	     MOV    L6, L6             ; check ld.low
+	     BNZ    NanDD              ; branch if ld=nan
+	     CMPI   L1, 0xFFE00000      ; if LS == (NAN OR INF ?)
+	     BHT    NanDDS             ; ls=nan, branch
+	     BST    NanInfDDD2         ; ls=normal, continue
+	     MOV    L2, L2             ; check ls.low
+	     BNZ    NanDDS             ; branch if ls=nan
+	     BR     StdNanS            ; ls=ld=infinity, exception
+NanInfDDD2:  MOVI   L5, 0x7FF00000      ; inf/normal, return inf
+	     SHLI   L9, 31             ;
+	     OR     L5, L9             ;
+	     STW.S  L0,  0,-4          ;
+	     STW.S  L0, L5, 0          ;
+	     RET    PC, L3             ;
+
+
+NanDDS:      SHRI   L1, 2              ; check if Ls=NANs
+	     BC     StdNanS            ;
+	     BR     StdNanQ            ;
+
+NanDD:       SHRI   L5, 2              ; if, ld=NANs
+	     BC     StdNanS            ; yes, branch exception
+	     ANDNI  L1, 0x001ffffc      ; check for ls=NaNs
+	     CMPI   L1, 0xFFE00002      ;
+	     BST    StdNanS            ; yes, branch exception
+	     BR     StdNanQ            ; store NANq
+;
+;************************************************
+;
+;
+NoInvDTrap:  ORI    G2, 0x00000010     ; set accrued.invalid.exception
+	     ANDNI  G2, 0x00001F00
+StdNanQ:     MOVI   L5, 0
+	     STW.S  L0, L5, -4
+	     MOVI   L5, NANq          ; LD = NANq
+	     STW.S  L0, L5, 0         ; store NANq
+	     RET    PC, L3            ; leave
+
+StdNanS:     CMPBI  SR, 0x00001000     ; if invalid.floating trap = enable
+	     BE     NoInvDTrap        ; no, branch
+	     ANDNI  G2, 0x00001F00     ; delete actual exception
+	     ORI    G2, 0x00001000     ; set actual.invalid.exception
+	     MOVI   L5, NANs          ; LD = NANs
+	     ADDI   L15, ExNrInv      ; correct errornumber
+	     ADDI   L0,-4
+	     MOVD   L1, L13
+	     MOV    L7, L15
+	     SUM    PC, PC, FloatErrorEntry - $
+EndOfFPRoutines:
+
+;----------------------------- EX, DO Entry ----------------------------------
+; Note: The halfword succeding the EX, DO differentiate branches to routines
+;-----------------------------------------------------------------------------
+
+EXEntry:     FRAME  L5, L0
+	     ADDI   L3, 2
+	     RET    PC, L3
+
+DOEntry:     FRAME  L5, L0
+	     ADDI   L3, 2
+	     RET    PC, L3
+#endif
+
+
+	     .END
diff -urN linux-2.4.29/arch/e1nommu/kernel/init_task.c linux-2.4.29-uc1/arch/e1nommu/kernel/init_task.c
--- linux-2.4.29/arch/e1nommu/kernel/init_task.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/kernel/init_task.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ * arch/e1nommu/kernel/init_task.c
+ *
+ *  Copyright (C) 2002-2003,    George Thanos <george.thanos@gdt.gr>
+ *                              Yannis Mitsos <yannis.mitsos@gdt.gr>
+ */
+
+
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS;
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+/*
+ * Initial task structure.
+ *
+ * We need to make sure that this is 8192-byte aligned due to the
+ * way process stacks are handled. This is done by having a special
+ * "init_task" linker map entry..
+ */
+union task_union init_task_union
+__attribute__((section(".tasks"), aligned(THREAD_SIZE))) 
+        = { task: INIT_TASK(init_task_union.task) };
+
+
diff -urN linux-2.4.29/arch/e1nommu/kernel/irq.c linux-2.4.29-uc1/arch/e1nommu/kernel/irq.c
--- linux-2.4.29/arch/e1nommu/kernel/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/kernel/irq.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,741 @@
+/*
+ * linux/arch/hyperstone-nommu/platform/E132XS/irq.c
+ *
+ * Copyright (C) 2002-2003 GDT,  Yannis Mitsos<yannis.mitsos@gdt.gr>
+ *                               George Thanos<george.thanos@gdt.gr>
+ * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
+ *
+ */
+#include <linux/config.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/pgalloc.h>
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <linux/irq.h>
+
+void Uninitialised_Entry(void);
+void SysCall_Entry(void);
+void Exception48_Entry(void);
+void Exception49_Entry(void);
+void Exception51_Entry(void);
+void Exception52_Entry(void);
+void Exception53_Entry(void);
+void Exception54_Entry(void);
+void Exception55_Entry(void);
+
+/*
+ * Controller mappings for all interrupt sources:
+ */
+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
+				{ [0 ... NR_IRQS-1] = { 0, &no_irq_type, }};
+
+/*
+ * Special irq handlers.
+ */
+
+void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+
+/*
+ * Generic no controller code
+ */
+
+static void enable_none(unsigned int irq) { }
+static unsigned int startup_none(unsigned int irq) { return 0; }
+static void disable_none(unsigned int irq) { }
+static void ack_none(unsigned int irq)
+{
+/*
+ * 'what should we do if we get a hw irq event on an illegal vector'.
+ * each architecture has to answer this themselves, it doesnt deserve
+ * a generic callback i think.
+ */
+	printk("unexpected IRQ trap at vector %02x\n", irq);
+}
+
+/* startup is the same as "enable", shutdown is same as "disable" */
+#define shutdown_none	disable_none
+#define end_none	enable_none
+
+struct hw_interrupt_type no_irq_type = {
+	"none",
+	startup_none,
+	shutdown_none,
+	enable_none,
+	disable_none,
+	ack_none,
+	end_none
+};
+
+volatile unsigned long irq_err_count, spurious_count;
+
+/*
+ * Generic, controller-independent functions:
+ */
+
+int get_irq_list(char *buf)
+{
+	struct irqaction * action;
+	char *p = buf;
+	int i;
+
+	p += sprintf(p, "           ");
+	for (i=0; i < 1 /*smp_num_cpus*/; i++)
+		p += sprintf(p, "CPU%d       ", i);
+	*p++ = '\n';
+
+	for (i = 0 ; i < NR_IRQS ; i++) {
+		int j, count, num;
+		const char *type_name = irq_desc[i].handler->typename;
+
+		action = irq_desc[i].action;
+		if (!action) 
+			continue;
+
+		count = 0;
+		num = -1;
+		for (j = 0; j < NR_IRQS; j++)
+			if (irq_desc[j].handler->typename == type_name) {
+				if (i == j)
+					num = count;
+				count++;
+			}
+
+		p += sprintf(p, "%3d: ",i);
+		p += sprintf(p, "%10u ", kstat_irqs(i));
+		if (count > 1) {
+			int prec = (num >= 100 ? 3 : num >= 10 ? 2 : 1);
+			p += sprintf(p, " %*s%d", 14 - prec, type_name, num);
+		} else
+			p += sprintf(p, " %14s", type_name);
+		p += sprintf(p, "  %s", action->name);
+
+		for (action=action->next; action; action = action->next)
+			p += sprintf(p, ", %s", action->name);
+		*p++ = '\n';
+	}
+	p += sprintf(p, "ERR: %10lu\n", irq_err_count);
+	return p - buf;
+}
+
+/*
+ * This should really return information about whether
+ * we should do bottom half handling etc. Right now we
+ * end up _always_ checking the bottom half, which is a
+ * waste of time and is not what some drivers would
+ * prefer.
+ */
+int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
+{
+	int status;
+	int cpu = smp_processor_id();
+
+	irq_enter(cpu, irq);
+
+	status = 1;	/* Force the "do bottom halves" bit */
+
+	if (!(action->flags & SA_INTERRUPT))
+		__sti();
+
+	do {
+		status |= action->flags;
+		action->handler(irq, action->dev_id, regs);
+		action = action->next;
+	} while (action);
+	if (status & SA_SAMPLE_RANDOM)
+		add_interrupt_randomness(irq);
+	__cli();
+
+	irq_exit(cpu, irq);
+
+	return status;
+}
+
+/*
+ * Generic enable/disable code: this just calls
+ * down into the PIC-specific version for the actual
+ * hardware disable after having gotten the irq
+ * controller lock. 
+ */
+
+/**
+ *	disable_irq_nosync - disable an irq without waiting
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line. Disables of an interrupt
+ *	stack. Unlike disable_irq(), this function does not ensure existing
+ *	instances of the IRQ handler have completed before returning.
+ *
+ *	This function may be called from IRQ context.
+ */
+ 
+void inline disable_irq_nosync(unsigned int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	if (!desc->depth++) {
+		desc->status |= IRQ_DISABLED;
+		desc->handler->disable(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/**
+ *	disable_irq - disable an irq and wait for completion
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line. Disables of an interrupt
+ *	stack. That is for two disables you need two enables. This
+ *	function waits for any pending IRQ handlers for this interrupt
+ *	to complete before returning. If you use this function while
+ *	holding a resource the IRQ handler may need you will deadlock.
+ *
+ *	This function may be called - with care - from IRQ context.
+ */
+ 
+void disable_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+
+	if (!local_irq_count(smp_processor_id())) {
+		do {
+			barrier();
+		} while (irq_desc[irq].status & IRQ_INPROGRESS);
+	}
+
+}
+
+/**
+ *	enable_irq - enable interrupt handling on an irq
+ *	@irq: Interrupt to enable
+ *
+ *	Re-enables the processing of interrupts on this IRQ line
+ *	providing no disable_irq calls are now in effect.
+ *
+ *	This function may be called from IRQ context.
+ */
+ 
+void enable_irq(unsigned int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	switch (desc->depth) {
+	case 1: {
+		unsigned int status = desc->status & ~IRQ_DISABLED;
+		desc->status = status;
+		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+			desc->status = status | IRQ_REPLAY;
+			hw_resend_irq(desc->handler,irq);
+		}
+		desc->handler->enable(irq);
+		/* fall-through */
+	}
+	default:
+		desc->depth--;
+		break;
+	case 0:
+		printk("enable_irq(%u) unbalanced from %p\n", irq,
+		       __builtin_return_address(0));
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/*
+ * do_IRQ handles all normal device IRQ's.
+ */
+asmlinkage void do_IRQ(struct pt_regs regs, unsigned int irq)
+{	
+	/* 
+	 * We ack quickly, we don't want the irq controller
+	 * thinking we're snobs just because some other CPU has
+	 * disabled global interrupts (we have already done the
+	 * INT_ACK cycles, it's too late to try to pretend to the
+	 * controller that we aren't taking the interrupt).
+	 *
+	 * 0 return value means that this irq is already being
+	 * handled by some other CPU. (or is disabled)
+	 */
+	int cpu = smp_processor_id();
+	irq_desc_t *desc;
+	struct irqaction * action;
+	unsigned int status;
+
+	kstat.irqs[cpu][irq]++;
+	desc = irq_desc + irq;
+	spin_lock(&desc->lock);
+	desc->handler->ack(irq);
+	/*
+	   REPLAY is when Linux resends an IRQ that was dropped earlier
+	   WAITING is used by probe to mark irqs that are being tested
+	   */
+	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
+	status |= IRQ_PENDING; /* we _want_ to handle it */
+
+	/*
+	 * If the IRQ is disabled for whatever reason, we cannot
+	 * use the action we have.
+	 */
+	action = NULL;
+	if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		action = desc->action;
+		status &= ~IRQ_PENDING; /* we commit to handling */
+		status |= IRQ_INPROGRESS; /* we are handling it */
+	}
+	desc->status = status;
+
+	/*
+	 * If there is no IRQ handler or it was disabled, exit early.
+	   Since we set PENDING, if another processor is handling
+	   a different instance of this same irq, the other processor
+	   will take care of it.
+	 */
+	if (!action)
+		goto out;
+
+	/*
+	 * Edge triggered interrupts need to remember
+	 * pending events.
+	 * This applies to any hw interrupts that allow a second
+	 * instance of the same irq to arrive while we are in do_IRQ
+	 * or in the handler. But the code here only handles the _second_
+	 * instance of the irq, not the third or fourth. So it is mostly
+	 * useful for irq hardware that does not mask cleanly in an
+	 * SMP environment.
+	 */
+	for (;;) {
+		spin_unlock(&desc->lock);
+		handle_IRQ_event(irq, &regs, action);
+		spin_lock(&desc->lock);
+
+		if (!(desc->status & IRQ_PENDING))
+			break;
+		desc->status &= ~IRQ_PENDING;
+	}
+	desc->status &= ~IRQ_INPROGRESS;
+out:
+	/*
+	 * The ->end() handler has to deal with interrupts which got
+	 * disabled while the handler was running.
+	 */
+	desc->handler->end(irq);
+	spin_unlock(&desc->lock);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+	//return 1;
+}
+
+/**
+ *	request_irq - allocate an interrupt line
+ *	@irq: Interrupt line to allocate
+ *	@handler: Function to be called when the IRQ occurs
+ *	@irqflags: Interrupt type flags
+ *	@devname: An ascii name for the claiming device
+ *	@dev_id: A cookie passed back to the handler function
+ *
+ *	This call allocates interrupt resources and enables the
+ *	interrupt line and IRQ handling. From the point this
+ *	call is made your handler function may be invoked. Since
+ *	your handler function must clear any interrupt the board 
+ *	raises, you must take care both to initialise your hardware
+ *	and to set up the interrupt handler in the right order.
+ *
+ *	Dev_id must be globally unique. Normally the address of the
+ *	device data structure is used as the cookie. Since the handler
+ *	receives this value it makes sense to use it.
+ *
+ *	If your interrupt is shared you must pass a non NULL dev_id
+ *	as this is required when freeing the interrupt.
+ *
+ *	Flags:
+ *
+ *	SA_SHIRQ		Interrupt is shared
+ *
+ *	SA_INTERRUPT		Disable local interrupts while processing
+ *
+ *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
+ *
+ */
+
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
+{
+	int retval;
+	struct irqaction * action;
+
+#ifdef DEBUG
+	printk("request_irq was called with irq: <%d>,handler: <0x%8x>, irqflags: <0x%8x>, devname: 
+			<%s>, dev_id <0x%8x>\n",irq, handler, irqflags, devname, dev_id);
+#endif
+	/*
+	 * Sanity-check: shared interrupts should REALLY pass in
+	 * a real dev-ID, otherwise we'll have trouble later trying
+	 * to figure out which interrupt is which (messes up the
+	 * interrupt freeing logic etc).
+	 */
+	if (irqflags & SA_SHIRQ) {
+		if (!dev_id)
+			printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]);
+	}
+	
+	if (irq >= NR_IRQS)
+		return -EINVAL;
+	if (!handler)
+		return -EINVAL;
+
+	action = (struct irqaction *)
+			kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = 0;
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_irq(irq, action);
+	if (retval)
+		kfree(action);
+	return retval;
+}
+
+/**
+ *	free_irq - free an interrupt
+ *	@irq: Interrupt line to free
+ *	@dev_id: Device identity to free
+ *
+ *	Remove an interrupt handler. The handler is removed and if the
+ *	interrupt line is no longer in use by any driver it is disabled.
+ *	On a shared IRQ the caller must ensure the interrupt is disabled
+ *	on the card it drives before calling this function. The function
+ *	does not return until any executing interrupts for this IRQ
+ *	have completed.
+ *
+ *	This function may be called from interrupt context. 
+ *
+ *	Bugs: Attempting to free an irq in a handler for the same irq hangs
+ *	      the machine.
+ */
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	irq_desc_t *desc;
+	struct irqaction **p;
+	unsigned long flags;
+
+#ifdef DEBUG
+	printk("Inside free_irq with irq: <%d> and dev_id: <0x%8x>\n",irq, dev_id);
+#endif 
+
+	if (irq >= NR_IRQS)
+		return;
+
+	desc = irq_desc + irq;
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
+	for (;;) {
+		struct irqaction * action = *p;
+		if (action) {
+			struct irqaction **pp = p;
+			p = &action->next;
+			if (action->dev_id != dev_id)
+				continue;
+
+			/* Found it - now remove it from the list of entries */
+			*pp = action->next;
+			if (!desc->action) {
+				desc->status |= IRQ_DISABLED;
+				desc->handler->shutdown(irq);
+			}
+			spin_unlock_irqrestore(&desc->lock,flags);
+			kfree(action);
+			return;
+		}
+		printk("Trying to free free IRQ%d\n",irq);
+		spin_unlock_irqrestore(&desc->lock,flags);
+		return;
+	}
+}
+
+/*
+ * IRQ autodetection code..
+ *
+ * This depends on the fact that any interrupt that
+ * comes in on to an unassigned handler will get stuck
+ * with "IRQ_WAITING" cleared and the interrupt
+ * disabled.
+ */
+
+static DECLARE_MUTEX(probe_sem);
+
+/**
+ *	probe_irq_on	- begin an interrupt autodetect
+ *
+ *	Commence probing for an interrupt. The interrupts are scanned
+ *	and a mask of potential interrupt lines is returned.
+ *
+ */
+
+unsigned long probe_irq_on(void)
+{
+	unsigned int i;
+	irq_desc_t *desc;
+	unsigned long val;
+	unsigned long delay;
+
+	down(&probe_sem);
+	/* 
+	 * something may have generated an irq long ago and we want to
+	 * flush such a longstanding irq before considering it as spurious. 
+	 */
+	for (i = NR_IRQS-1; i > 0; i--)  {
+		desc = irq_desc + i;
+
+		spin_lock_irq(&desc->lock);
+		if (!irq_desc[i].action) 
+			irq_desc[i].handler->startup(i);
+		spin_unlock_irq(&desc->lock);
+	}
+
+	/* Wait for longstanding interrupts to trigger. */
+	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
+		/* about 20ms delay */ synchronize_irq();
+
+	/*
+	 * enable any unassigned irqs
+	 * (we must startup again here because if a longstanding irq
+	 * happened in the previous stage, it may have masked itself)
+	 */
+	for (i = NR_IRQS-1; i > 0; i--) {
+		desc = irq_desc + i;
+
+		spin_lock_irq(&desc->lock);
+		if (!desc->action) {
+			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
+			if (desc->handler->startup(i))
+				desc->status |= IRQ_PENDING;
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	/*
+	 * Wait for spurious interrupts to trigger
+	 */
+	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
+		/* about 100ms delay */ synchronize_irq();
+
+	/*
+	 * Now filter out any obviously spurious interrupts
+	 */
+	val = 0;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			/* It triggered already - consider it spurious. */
+			if (!(status & IRQ_WAITING)) {
+				desc->status = status & ~IRQ_AUTODETECT;
+				desc->handler->shutdown(i);
+			} else
+				if (i < 32)
+					val |= 1 << i;
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	return val;
+}
+
+/**
+ *	probe_irq_off	- end an interrupt autodetect
+ *	@val: mask of potential interrupts (unused)
+ *
+ *	Scans the unused interrupt lines and returns the line which
+ *	appears to have triggered the interrupt. If no interrupt was
+ *	found then zero is returned. If more than one interrupt is
+ *	found then minus the first candidate is returned to indicate
+ *	their is doubt.
+ *
+ *	The interrupt probe logic state is returned to its previous
+ *	value.
+ *
+ *	BUGS: When used in a module (which arguably shouldnt happen)
+ *	nothing prevents two IRQ probe callers from overlapping. The
+ *	results of this are non-optimal.
+ */
+
+int probe_irq_off(unsigned long irq)
+{
+	int i, irq_found, nr_irqs;
+
+	nr_irqs = 0;
+	irq_found = 0;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			if (!(status & IRQ_WAITING)) {
+				if (!nr_irqs)
+					irq_found = i;
+				nr_irqs++;
+			}
+			desc->status = status & ~IRQ_AUTODETECT;
+			desc->handler->shutdown(i);
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+	up(&probe_sem);
+
+	if (nr_irqs > 1)
+		irq_found = -irq_found;
+	return irq_found;
+
+}
+
+int setup_irq(unsigned int irq, struct irqaction * new)
+{
+	int shared = 0;
+	struct irqaction *old, **p;
+	unsigned long flags;
+	irq_desc_t *desc = irq_desc + irq;
+
+	/*
+	 * Some drivers like serial.c use request_irq() heavily,
+	 * so we have to be careful not to interfere with a
+	 * running system.
+	 */
+	if (new->flags & SA_SAMPLE_RANDOM) {
+		/*
+		 * This function might sleep, we want to call it first,
+		 * outside of the atomic block.
+		 * Yes, this might clear the entropy pool if the wrong
+		 * driver is attempted to be loaded, without actually
+		 * installing a new handler, but is this really a problem,
+		 * only the sysadmin is able to do this.
+		 */
+		rand_initialize_irq(irq);
+	}
+
+	/*
+	 * The following block of code has to be executed atomically
+	 */
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
+	if ((old = *p) != NULL) {
+		/* Can't share interrupts unless both agree to */
+		if (!(old->flags & new->flags & SA_SHIRQ)) {
+			spin_unlock_irqrestore(&desc->lock,flags);
+			return -EBUSY;
+		}
+
+		/* add new interrupt at end of irq queue */
+		do {
+			p = &old->next;
+			old = *p;
+		} while (old);
+		shared = 1;
+	}
+
+	*p = new;
+
+	if (!shared) {
+		desc->depth = 0;
+		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
+		desc->handler->startup(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock,flags);
+	return 0;
+}
+
+static void irq_nop (unsigned irq) { }
+static unsigned irq_zero (unsigned irq) { return 0; }
+
+static struct hw_interrupt_type e132xs_irq_type = {
+	"IRQ",
+	irq_zero,		/* startup */
+	irq_nop,		/* shutdown */
+	irq_nop,		/* enable */
+	irq_nop,		/* disable */
+	irq_nop,		/* ack */
+	irq_nop,		/* end */
+};
+
+void MEM0_set_exception(int num, void *handler);
+
+/* Initialise IRQ entries */
+void __init init_IRQ(void)
+{
+	unsigned long i;
+	/* First set trap entries to trap entry table. */
+	for(i=0; i<46; i++) {
+		/* 16. Exception allocated for breakpoint support */
+		if(i==16)
+			continue;
+		MEM0_set_exception( i , Uninitialised_Entry );
+	}
+	
+	/* System Call entry */
+	MEM0_set_exception( 47, SysCall_Entry );
+
+	/* Interrupts */
+	MEM0_set_exception( 48, Exception48_Entry );
+	MEM0_set_exception( 49, Exception49_Entry );
+	/* 50. Entry is allocated by UART for GDB support */
+	MEM0_set_exception( 51, Exception51_Entry );
+	MEM0_set_exception( 52, Exception52_Entry );
+	MEM0_set_exception( 53, Exception53_Entry );
+	MEM0_set_exception( 54, Exception54_Entry );
+	MEM0_set_exception( 55, Exception55_Entry );
+	MEM0_set_exception( 56, Uninitialised_Entry );
+
+	/* Regular exceptions are located at trap.c */
+
+	/* Then initialise the  s/w
+ 	 */
+
+	for(i=0; i<NR_IRQS; i++){
+		irq_desc[i].status  = IRQ_DISABLED;
+		irq_desc[i].action  = NULL;
+		irq_desc[i].depth   = 1;
+		irq_desc[i].handler = &e132xs_irq_type;
+	}
+
+}
+
+void Uninitialised_Exception_Entry(void)
+{
+	printk("WARNING:***Exception Entry Not Initialised***\n");
+	BUG();
+}
diff -urN linux-2.4.29/arch/e1nommu/kernel/Makefile linux-2.4.29-uc1/arch/e1nommu/kernel/Makefile
--- linux-2.4.29/arch/e1nommu/kernel/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/kernel/Makefile	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,18 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+all: kernel.o
+
+O_TARGET := kernel.o
+
+obj-y := process.o semaphore.o setup.o init_task.o time.o traps.o signal.o ptrace.o irq.o sys_e1.o float_entry.o floating.o
+#obj-y += signal.o
+# ksyms.o - not needed because we don't support modules right now.
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/e1nommu/kernel/process.c linux-2.4.29-uc1/arch/e1nommu/kernel/process.c
--- linux-2.4.29/arch/e1nommu/kernel/process.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/kernel/process.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,1055 @@
+/*
+ *  linux/arch/e1nommu/kernel/process.c
+ *
+ *  Copyright (C) 2002-2003,	George Thanos <george.thanos@gdt.gr>
+ *  							Yannis Mitsos <yannis.mitsos@gdt.gr>
+ *
+ *  This file handles the architecture-dependent parts of 
+ *  process handling..
+ *
+ *	The process handling scheme is the following. Each process has a kernel register stack
+ *	and a kernel aggregate stack. In user mode each process has its own user
+ *	register stack and user aggregate stack. In general each process has 4 stacks,
+ *	2 in user mode and 2 in kernel mode.
+ *	When we run in user mode and an interrupt takes place we need two registers to
+ *	indicate the kernel register stack pointer and the kernel aggregate stack pointer,
+ *	since we need to change stacks. These registers are G11 and G9 respectively.
+ *	G11 indicates the lower bound of the kernel register stack(grows to higher addresses)
+ *	and G9 the upper bound of the kernel aggregate stack(grows to lower addresses).
+ *
+ *	For more details on the implementation see the comments and inline documentation of each
+ *	function.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/reboot.h>
+#include <linux/mman.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/unistd.h>
+#include <asm/stack.h>
+
+#define _STH asm volatile("ori   SR, 0x20");
+#define _CLH asm volatile("andni SR, 0x20");
+
+void Flush_Register_Context(void);
+void ret_from_vfork(void);
+
+/* This function performs the actual task switching */
+long in_switch_to=0;
+void __switch_to(struct task_struct * prev, struct task_struct * next)
+{
+#if 0 
+	in_switch_to++;
+	printk("switch_to : %d\n", in_switch_to);
+	printk("prev id : %d, next id: %d\n"
+	       "prev task: 0x%08x, next task: 0x%08x\n",
+	       prev->pid, next->pid, prev, next ); 
+#endif
+	/* Lock! An interrupt here could be a disaster. */
+	cli();
+	Flush_Register_Context();
+
+	/* Perform register saving. PC should not be saved */
+	asm volatile(
+    	"mov 	%0, SR\n\t"
+	"mov    %1, G2\n\t"
+	"mov    %2, G3\n\t"
+	"mov    %3, G4\n\t"
+	"mov    %4, G5\n\t"
+	"mov    %5, G6\n\t"
+	"mov    %6, G7\n\t"
+	:"=l"(prev->thread.SR),
+	 "=l"(prev->thread.G2),
+	 "=l"(prev->thread.G3),
+	 "=l"(prev->thread.G4),
+	 "=l"(prev->thread.G5),
+	 "=l"(prev->thread.G6),
+	 "=l"(prev->thread.G7)
+	 :/*no input*/
+	 :"cc","memory","%L0","%L1","%L2","%L3","%L4");
+
+	asm volatile(
+	"mov    %0, G8\n\t"
+	"mov    %1, G9\n\t"
+	"mov    %2, G11\n\t"
+	"mov    %3, G12\n\t"
+	"mov    %4, G13\n\t"
+	"mov    %5, G14\n\t"
+	"mov    %6, G15\n\t"
+	"setadr L4\n\t" // Don't save L0 - saved PC
+    "mov 	%7, L4\n\t"
+	"ori	SR, 0x20\n\t"
+	"mov    %8, UB\n\t" /* Upper Stack Bound - G19*/
+	:"=l"(prev->thread.G8),
+	 "=l"(prev->thread.G9),
+	 "=l"(prev->thread.G11),
+	 "=l"(prev->thread.G12),
+	 "=l"(prev->thread.G13),
+	 "=l"(prev->thread.G14),
+	 "=l"(prev->thread.G15),
+	 "=l"(prev->thread.SP),
+	 "=l"(prev->thread.UB)
+	 :/*no input*/
+	 :"cc","memory","%L2");
+
+	prev->thread.SP += 16;
+	current = next;
+
+	/* Perform restorings */
+	asm volatile(
+	"movi   L0, _after_return_instruction\n\t"
+	"ori    L0, 0x1\n\t" /* S flag */
+	"mov 	L1, %0\n\t"
+	"mov    G2, %1\n\t"
+	"mov    G3, %2\n\t"
+	"mov    G4, %3\n\t"
+	"mov    G5, %4\n\t"
+	"mov    G6, %5\n\t"
+	"mov    G7, %6\n\t"
+	"mov    G8, %7\n\t"
+	"mov    G9, %8\n\t"
+	:/* no output*/
+	:"l"(next->thread.SR),
+	 "l"(next->thread.G2),
+	 "l"(next->thread.G3),
+	 "l"(next->thread.G4),
+	 "l"(next->thread.G5),
+	 "l"(next->thread.G6),
+	 "l"(next->thread.G7),
+	 "l"(next->thread.G8),
+	 "l"(next->thread.G9)
+	:"cc","memory","%L0","%L1");
+
+	asm volatile(
+	"mov    G11,%0\n\t"
+	"mov    G12,%1\n\t"
+	"mov    G13,%2\n\t"
+	"mov    G14,%3\n\t"
+	"mov    G15,%4\n\t"
+	"fetch  4\n\t"
+	"ori	SR, 0x20\n\t" /* Set H flag */
+	"mov    SP, %5\n\t"   /* SP - G18 */
+	"ori	SR, 0x20\n\t" /* Set H flag */
+	"mov    UB, %6\n\t"   /* UB - G19 */
+	"ret    PC, L0\n\t"   /* Validate new Local Register Stack */
+	"_after_return_instruction:\n\t"
+	:/* no output*/
+	:"l"(next->thread.G11),
+	 "l"(next->thread.G12),
+	 "l"(next->thread.G13),
+	 "l"(prev->thread.G14),
+	 "l"(next->thread.G15),
+	 "l"(next->thread.SP),
+	 "l"(next->thread.UB)
+	:"cc","%L0","%L1","memory");
+
+	sti();
+	/* gcc saves L2 to Aggregate stack. Since we have saved
+	 * L2 explicitely and we need to use our saved value
+	 * we have to return before gcc does so!
+	 */
+	asm volatile(	"addi   G3, 8\n\t"
+			"ret PC, L2\n\t");
+}
+
+/* This is the architecture dependent initialization function
+ * when vforking/cloning a new process */
+#define DEBUG_copy_thread 0 
+int copy_thread(int nr, unsigned long clone_flags, unsigned long  child_ustack,	
+		unsigned long unused, struct task_struct *p, struct pt_regs *regs)
+{
+#define	   FL         	regs->FL
+#define	   L         	regs->L
+#define    ret_PC     	L[FL+0]
+#define    ret_SR     	L[FL+1]
+#define    ret_SP     	L[FL+2]
+#define    RETURN_MODE  (ret_PC & 0x1)? 1:0
+#define    KERNEL_MODE  1
+#define    USER_MODE    0
+#define    ALLOC_KAGGREGATE_STACK              alloc_task_struct()
+#define    ALLOC_KREGISTER_STACK               alloc_task_struct()
+
+/* ReturnSR :
+ * Given the <_SP_> value  we produce a SR that will enable
+ * a function to return with a Frame Pointer of <_FP_> registers
+ * higher in the register stack than <_SP_> and a Frame Length 
+ * of <_FL_>. (FLAGS : S=1, I=0, L=0)
+ * Be careful!! We don't check if FL=16 to set it 0.
+ * When FL=16 set _FL_ to 0.
+ */
+#define ReturnSR(_FP_, _FL_, _SP_)				\
+({												\
+	 	volatile unsigned long RetSR = 0; 		\
+		RetSR = ((_SP_) + ( (long)(_FP_)<<2 ) ) & 0x1FC; /*0x1FC - b0000 0001 1111 1100*/ \
+		RetSR = RetSR << 23;/*25-2*/			\
+		RetSR |= (_FL_)<<21;					\
+		RetSR |= 0x00040000; /* S=1, I=0, L=0 */\
+		RetSR;									\
+})
+
+	char *G3, *G4, *G5, *G9, *G11;
+	unsigned long *Flowers;
+	long AggregateStackSize, RegisterStackSize, mode = RETURN_MODE;
+#if DEBUG_copy_thread
+	printk("copy_thread...\n");
+	printk("&p : 0x%08x\n", (int)p );
+#endif
+	
+	/* G11 is the register stack pointer
+	 * Register Stack grows to higher addresses - G11 points to the bottom of the stack*/
+	p->thread.G11 = (unsigned long)ALLOC_KREGISTER_STACK;
+	/* G9 is the aggregate stack pointer
+	 * Aggregate Stack grows to lower addresses - G9 points to the top of the stack*/
+	p->thread.G9  = (unsigned long)p + THREAD_SIZE;
+
+	asm volatile(
+	"mov %0, G11\n\t"
+	"mov %1, G9\n\t"
+	"mov %2, G3\n\t"
+	"mov %3, G4\n\t"
+	"mov %4, G5\n\t"
+	:"=l"(G11),
+	 "=l"(G9),
+	 "=l"(G3),
+	 "=l"(G4),
+	 "=l"(G5)
+	:/* no input */);
+#if _DEBUG_copy_thread
+	printk( "G11: 0x%08x, G9: 0x%08x,\n"
+		"G3: 0x%08x,  G4: 0x%08x, G5: 0x%08x\n",
+		G11, G9, G3, G4, G5 );
+#endif
+	
+
+	/* We differentiate initialization of kernel register stack,
+	 * depending whether we came from user or kernel mode */
+	/* The child process returns in the following order:
+	 * 1. Validates Kernel Register Stack within __switch_to().
+	 * 2. Returns from switch_to() to ret_from_vfork() (skips schedule() )
+	 */
+	if( mode == KERNEL_MODE ) {
+		/* Actions: 
+		 * a.Copy Kernel Aggregate Stack of parent to child (G3 -> G9)
+		 * b.Copy Kernel Register Stack.
+		 * c.Add the Flowers (We call "Flowers" the extra information that we
+		 * add to the child's kernel register stack in order to return)*/
+
+		/* Copy Kernel Aggregate Stack */
+		AggregateStackSize = (long)(G9 - G3);
+		if(AggregateStackSize & 0x3) BUG();/* Check for word allignment */
+		/* Aggregate Stack. We cannot copy the full stack size. 
+	 	 * We would overwrite child's process descriptor */
+		 memcpy( (char*)(p->thread.G9 - AggregateStackSize), G3, AggregateStackSize );
+
+		/* Copy Kernel Register Stack. */
+		RegisterStackSize = ret_SP - (int)G11;
+		if(RegisterStackSize & 0x3 ) BUG();/* Check for word allignment */
+		memcpy( (char*)p->thread.G11, G11, RegisterStackSize );
+
+		/* Initialise Globals (Globals is the information needed in order to
+		 * perform task switching within <__switch_to()>) */
+		p->thread.SP =  (unsigned long)(p->thread.G11 + RegisterStackSize + 10*4);
+		p->thread.UB =  (unsigned long)(p->thread.G11 + THREAD_SIZE);
+		/* This is the SR that is used to change-validate the register stack
+		 * within __switch_to()*/
+		p->thread.SR = ReturnSR(-4, 15, p->thread.SP); /* __switch_to FL=15 */
+
+		/*Put to G2 the value of the current FER*/
+		_STH;
+		p->thread.G2 = 0;
+		p->thread.G3 =  p->thread.G9 - (G9 - G3);
+		p->thread.G4 =  p->thread.G9 - (G9 - G4);
+		p->thread.G5 =  p->thread.G9 - (G9 - G5);
+		p->thread.G6 =  0;
+		p->thread.G7 =  0;
+		p->thread.G8 =  0;
+	/*	p->thread.G9   Initialised to top  
+		p->thread.G10  Used by GDB 
+		p->thread.G11  Initialised to top */
+		p->thread.G12 = 0;
+		p->thread.G13 = 0;
+		p->thread.G14 = 0;
+		p->thread.G15 = 0;
+		
+		/*Flowers!!! - We arbitrarily call Flowers the additional information
+		 * that we put at the top of the register stack in order to return*/
+		Flowers    =  (unsigned long*)(p->thread.G11 + RegisterStackSize );
+		Flowers[-1] = 0; /* Return value should be 0 when the child returns */
+		Flowers[0] =  L[FL + 0]; 
+		Flowers[1] =  ReturnSR(-16, 6, p->thread.SP); /* Return to <clone> */
+		Flowers[2] =  L[FL + 2];
+		Flowers[3] =  L[FL + 3];
+		Flowers[4] =  L[FL + 4];
+		Flowers[5] =  L[FL + 5];
+	/* 	Flowers[6] - next parameter of switch_to
+		Flowers[7] - prev parameter of switch_to	*/
+		Flowers[8] = (unsigned long)&ret_from_vfork;  Flowers[8] |= 0x1;
+		Flowers[9] = ReturnSR(-10, 6, p->thread.SP); /* Return to <ret_from_vfork>*/
+	} 
+	else /* USER_MODE */
+	{
+		unsigned long *TopOfchildAggStack, *TopOfparentAggStack;
+		/* Actions: 
+		 * a.Copy only the necessary Kernel Aggregate Stack to return.
+		 * b.Don't Copy Kernel Register Stack. Just set SP to a reasonable value.
+		 * c.Initialize Globals */
+
+	    /* We need 4 registers inside <__switch_to> and another 3
+		 * in <ret_from_vfork> totally 7. Thus 10 registers is ample space.
+		 * Stack will altered since we come from user mode, so we just want 
+		 * the appropriate info in order to return from user to kernel mode.
+		 */
+
+		/* Initialise Globals (Globals is the information needed in order to
+		 * perform task switching within <__switch_to()>) */
+		p->thread.SP =  (unsigned long)(p->thread.G11 + 10*4);
+		p->thread.UB =  (unsigned long)(p->thread.G11 + THREAD_SIZE);
+		p->thread.SR =  ReturnSR(-4, 15, p->thread.SP); /* __switch_to FL=15 */
+
+		/*Put to G2 the value of the current FER*/
+		_STH;
+		p->thread.G2 =  0;
+		p->thread.G3 =  p->thread.G9 - 13 * 4;
+		p->thread.G4 =  p->thread.G9 -  4 * 4;
+		p->thread.G5 =  p->thread.G9 - (G9 - G5);
+		p->thread.G6 =  0;
+		p->thread.G7 =  0;
+		p->thread.G8 =  0;
+	/*	p->thread.G9   Initialised to top  
+		p->thread.G10  Used by GDB 
+		p->thread.G11  Initialised to top */
+		p->thread.G12 = 0;
+		p->thread.G13 = 0;
+		p->thread.G14 = 0;
+		p->thread.G15 = 0;
+
+		/* Return value should be 0 when the child returns.
+		 * This is done in ret_from_vfork in entry.S */
+		TopOfchildAggStack  = (unsigned long*)(p->thread.G9);
+		TopOfparentAggStack  = (unsigned long*)G9;
+		/* Since we need to return to user mode we need the
+		 * info located in the kernel aggregate stack of parent
+		 * We copy info from parent to child kernel aggregate stack.*/
+		TopOfchildAggStack[-1]  = TopOfparentAggStack[-1]; 
+		TopOfchildAggStack[-2]  = TopOfparentAggStack[-2]; 
+		TopOfchildAggStack[-3]  = TopOfparentAggStack[-3]; 
+		TopOfchildAggStack[-4]  = TopOfparentAggStack[-4]; 
+		TopOfchildAggStack[-5]  = TopOfparentAggStack[-5]; 
+		TopOfchildAggStack[-6]  = TopOfparentAggStack[-6]; 
+		TopOfchildAggStack[-7]  = TopOfparentAggStack[-7]; 
+		TopOfchildAggStack[-8]  = TopOfparentAggStack[-8]; 
+		TopOfchildAggStack[-9]  = TopOfparentAggStack[-9]; 
+		TopOfchildAggStack[-10] = TopOfparentAggStack[-10]; 
+		TopOfchildAggStack[-11] = TopOfparentAggStack[-11]; 
+
+		/* <Flowers> is again the info that we add to the kernel 
+		 * register stack of the child in order to gracefully return. */
+		Flowers = (unsigned long*)p->thread.G11;
+		Flowers[0] = 0;
+		Flowers[1] = 0;
+		Flowers[2] = 0;
+		Flowers[3] = 0;
+		Flowers[4] = 0;
+		Flowers[5] = 0;
+	/* 	Flowers[6] - next parameter of switch_to
+		Flowers[7] - prev parameter of switch_to	*/
+		Flowers[8] = (unsigned long)&ret_from_vfork; Flowers[8] |= 0x1;
+		Flowers[9] = ReturnSR(-10, 6, p->thread.SP); /* Return to <ret_from_vfork> with FL=6*/
+
+		/* When calling vfork in user mode parent may not be able to return
+		 * because the child has corrupted the stack. In order to return safely
+		 * we need to copy the parent's return information, and restore it just
+		 * before parent returns. */
+		current->thread.vfork_ret_info.ret_from_vfork = 1;
+		get_user(current->thread.vfork_ret_info.ReturnPC, &L[1]);
+		get_user(current->thread.vfork_ret_info.ReturnSR, &L[2]);
+		/*
+		printk("L[1] : 0x%x, L[2] : 0x%x\n", (int)L[1], (int)L[2]);
+		printk("current : 0x%x, current->ret_from_vfork : 0x%x\n", 
+				current, 
+				&current->thread.vfork_ret_info.ret_from_vfork ); */
+	}
+
+#if DEBUG_copy_thread 
+	printk( "p->pid : %d\n", p->pid );
+	printk( "p->thread.G11: 0x%08x, p->thread.G9: 0x%08x,\n"
+		"p->thread.G3: 0x%08x,  p->thread.G4: 0x%08x,\np->thread.G5: 0x%08x\n",
+		p->thread.G11, p->thread.G9, p->thread.G3, p->thread.G4, p->thread.G5 );
+#endif
+		return 0;
+
+#undef    ReturnSR
+#undef    FL
+#undef	  L
+#undef    ret_PC
+#undef    ret_SR
+#undef    ret_SP
+#undef    RETURN_MODE
+#undef    KERNEL_MODE
+#undef    USER_MODE 
+#undef    ALLOC_KAGGREGATE_STACK
+#undef    ALLOC_KREGISTER_STACK
+}
+
+/*
+ * Create a kernel thread
+ */
+#define DEBUG_kernel_thread 0
+extern asmlinkage long sys_exit(int);
+long arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+{
+	unsigned long _pid;
+	flags |= CLONE_VM;
+
+	_pid = clone(flags);
+#if DEBUG_kernel_thread
+	printk("Kernel_thread: _pid:%d\n",_pid);
+#endif
+	if(!_pid){
+#if DEBUG_kernel_thread
+		printk("Child thread %d is ready to run...\n"
+		       "fn:0x%08x, arg:0x%08x\n",current->pid, fn, (long)arg);
+#endif
+		fn(arg);
+		sys_exit(1);
+	}
+	return _pid;
+}
+
+asmlinkage int sys_fork(struct pt_regs regs)
+{
+	return(-EINVAL);
+}
+
+#define DBG_sys_vfork 0
+asmlinkage int sys_vfork(struct pt_regs regs)
+{
+	int retval;
+#if DBG_sys_vfork
+	printk("Entered vfork, pid : %d\n", current->pid);	
+#endif
+	retval =  do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, &regs, 0);
+#if DBG_sys_vfork
+	printk("Exiting vfork, pid : %d\n", current->pid);	
+#endif
+	return retval;
+}
+
+asmlinkage int sys_clone(struct pt_regs regs)
+{
+#define L	regs.L
+#define FL	regs.FL
+	unsigned long clone_flags = L[ FL-2];
+	return do_fork( clone_flags, 0, &regs, 0);
+#undef  L
+#undef  FL
+}
+
+/*
+ * The idle loop on hyperstone..
+ */
+static void default_idle(void)
+{
+#ifdef DEBUG
+	printk("default_idle...\n");
+#endif
+		while(1) {
+		if (!current->need_resched){
+		asm volatile("
+PowerDown:
+			ANDNI    SR, 0x8000              
+            STW.IOA  0,  0, 0x0B800000
+            BR       (long)PDLoopX2         
+PDLoopX2:   NOP
+            NOP
+            NOP
+            NOP
+            NOP"
+		: /* no outputs */
+		: 
+		);
+
+		}
+		schedule();
+	}
+}
+
+void (*idle)(void) = default_idle;
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle(void)
+{
+	/* endless idle loop with no priority at all */
+	init_idle();
+	current->nice = 20;
+	current->counter = -100;
+	idle();
+}
+
+void machine_restart(char * __unused)
+{
+	if (mach_reset)
+		mach_reset();
+	for (;;);
+}
+
+void machine_halt(void)
+{
+	if (mach_halt)
+		mach_halt();
+	for (;;);
+}
+
+void machine_power_off(void)
+{
+	if (mach_power_off)
+		mach_power_off();
+	for (;;);
+}
+
+/* In order to execute a new application we have to
+ * modify the kernel aggregate stack pointers. Pointers
+ * should show in the following memory area:
+ * FROM : (TOP_OF_STACK-44) -- TO : (TOP_OF_STACK-16)
+ * TOP_OF_STACK - 4 = Kernel Register stack pointer G3
+ * TOP_OF_STACK - 8 = Kernel Register stack pointer G4
+ * TOP_OF_STACK - 12= Kernel Register stack pointer G5
+ * TOP_OF_STACK - 16= Index to the top of the next Aggregate Stack Frame
+ * Function should be executed just before returning from
+ * sys_execve system call, when no other job has to be done in terms of
+ * process execution.
+ */
+void Switch_AggregateStackValues(void)
+{
+	unsigned long G3, G4, G5, G9;
+	asm volatile(	"mov %0, G9\n\t"
+			:"=l"(G9)
+	     		:/*no input*/
+	     		:"%G9");
+	G3 = G9 - 44; 
+	G4 = G9 - 16;
+	G5 = G9 - 0x1000;
+	asm volatile(	"mov G3, %0\n\t"
+			"mov G4, %1\n\t"
+			"mov G5, %2\n\t"
+			:/*no output*/
+			:"l"(G3), "l"(G4), "l"(G5)
+			:"%G3", "%G4", "%G5" );
+}
+
+/*
+ *  sys_execve() executes a new program.
+ */
+#if 0
+#define DBG_sys_execve
+#endif
+asmlinkage int sys_execve(struct pt_regs regs)
+{
+#define L		regs.L
+#define FL		regs.FL
+#define ARG1		L [ FL-3 ]
+#define ARG2		L [ FL-4 ]
+#define ARG3		L [ FL-5 ]
+#define ReturnPC	L [ FL ]
+	/* ReturnPC is the PC value of the interrupted task
+	 * (Next instruction to be executed)
+	 */ 
+#ifdef DBG_sys_execve
+		char **argv = ((char **)ARG2);
+		char **envp = ((char **)ARG3);
+		char *name  = ((char *) ARG1);
+#else
+#define name		((char *)ARG1)
+#define argv		((char **)ARG2)
+#define envp		((char **)ARG3)
+#endif
+        int error;
+		char *filename;
+
+#ifdef DBG_sys_execve
+		int i, argc = 0, envc = 0;
+		printk("name:<%s>, argv:[0x%x],  envp:[0x%x]\n", name, argv, envp );
+		if(argv)
+			for(i=0; argv[i] != (char*)0; i++)
+				argc++;
+		printk("argc : %d\n", argc);
+#endif
+
+        lock_kernel();
+        filename = getname(name);
+#ifdef DBG_sys_execve
+		printk("filename:<%s>\n", filename );
+#endif
+        error = PTR_ERR(filename);
+        if (IS_ERR(filename))
+				goto out;
+        error = do_execve(name, argv, envp, &regs);
+
+	   /* We are not aware if we came from user or kernel mode.
+	 	* Since execve needs user mode, we have to explicitely
+	 	* verify that.
+	 	*/ 
+		ReturnPC &= 0xffFFffFE;
+        putname(filename);
+out:
+        unlock_kernel();
+        return error;
+#undef name
+#undef argv
+#undef envp
+	
+#undef ReturnPC
+#undef L
+#undef FL
+#undef ARG1
+#undef ARG2
+#undef ARG3
+}
+
+#define DEBUG_start_thread 0 
+void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long usp)
+{
+	unsigned long *G9;
+	struct {
+		unsigned long FP;
+		unsigned long FL;
+	} SR;
+	unsigned long first_arg;
+#define TOP_OF_KERNEL_AGGREGATE_STACK  G9
+#define uG3				*(TOP_OF_KERNEL_AGGREGATE_STACK - 1)
+#define uG4				*(TOP_OF_KERNEL_AGGREGATE_STACK - 2)
+#define uG5				*(TOP_OF_KERNEL_AGGREGATE_STACK - 3)
+#define SavedG4				*(TOP_OF_KERNEL_AGGREGATE_STACK - 4)
+#define L0				*(TOP_OF_KERNEL_AGGREGATE_STACK - 5)
+#define L1				*(TOP_OF_KERNEL_AGGREGATE_STACK - 6)
+#define L2				*(TOP_OF_KERNEL_AGGREGATE_STACK - 7)
+#define L3				*(TOP_OF_KERNEL_AGGREGATE_STACK - 8)
+#define L4				*(TOP_OF_KERNEL_AGGREGATE_STACK - 9)
+#define L5				*(TOP_OF_KERNEL_AGGREGATE_STACK - 10)
+#define UB				*(TOP_OF_KERNEL_AGGREGATE_STACK - 11)
+#define uSavedPC			L0
+#define uSavedSR			L1
+#define uSavedSP			L2
+#define uSavedUB			UB
+	asm volatile("mov %0, G9\n\t"
+		     :"=l"(TOP_OF_KERNEL_AGGREGATE_STACK)
+		     :/*no input*/
+		     :"%G9");
+/* We split the user stack into two different entities of approximately 0x1000
+ * bytes each. The upper entity in memory is the User Aggregate Stack, while the
+ * lower entity in memory is the User Register Stack.
+ */
+	/* User Register Stack */
+	uSavedSP =  ((current->mm->end_brk + 3) & ~3);	
+	uSavedUB =  ((current->mm->end_brk + 3) & ~3) + USER_REGISTER_STACK_SIZE;
+	/* We keep STACK_OFFSET stack space, just in case we run out of stack
+	 * This will enable us to handle the exception*/
+	uSavedUB -= STACK_OFFSET;
+
+	/* User Aggregate Stack */
+	uG3 = usp;
+	uG4 = usp;
+	/* We assign a slight space between the two stacks */
+	uG5 = uSavedUB + STACK_OFFSET + 0x10;
+	/* We keep STACK_OFFSET stack space, just in case we run out of stack
+	 * This will enable us to handle the exception*/
+	uG5 += STACK_OFFSET;
+
+	/* Saved SR value */
+	/* Trap enable : Invalid Operation, Div by zero, Overflow
+	 * Trap disable: Underflow, Inexact.
+	 * Rounding Mode : Round to nearest.
+	 */
+	uSavedSR = 0x1C00; 
+	/* FL = 2 arbitrarily */
+/*1.FL*/SR.FL = 2; SR.FL <<= 21; uSavedSR |= SR.FL;
+/*2.FP*/SR.FP = uSavedSP; SR.FP &= 0x000001fc; 
+	SR.FP <<= 23; uSavedSR |= SR.FP;
+
+	/* User PC */
+	uSavedPC = pc;
+    /* Pass Arguments */
+	/* argc is located where <usp> points to. 
+	 * argv is located 4 bytes higher from argc.
+	 * envp is located (sizeof(char*) * (argc+1)) bytes
+	 * higher than argv. (See _uClibc_start in uClibc for 
+	 * more details)
+	 */
+	first_arg = usp;
+	/* Set the value of <first_arg> in the base of the User Register Stack. */
+	*(unsigned long *)uSavedSP = first_arg;
+	/* We assign the uSavedSP a little bit higher so as to be able to fill
+	 * the Register Stack with the value of <first_arg>.
+	 */
+	uSavedSP += 16; 
+#if DEBUG_start_thread 
+	/* This is just for debugging. It should not compiled in */
+	printk("DEBUG start_thread...\n");
+	printk("G3: [0x%x], G4: [0x%x], G5: [0x%x]\n", uG3, uG4, uG5 );
+	printk("uPC: [0x%x], uSR: [0x%x], uSavedSP: [0x%x], uSavedUB: [0x%x]\n",
+		uSavedPC, uSavedSR, uSavedSP, uSavedUB );
+	printk("&uPC: [0x%x], &uSR: [0x%x], &uSavedSP: [0x%x], &uSavedUB: [0x%x]\n",
+		&uSavedPC, &uSavedSR, &uSavedSP, &uSavedUB );
+	printk("Remember G5 -= STACK_OFFSET, UB += STACK_OFFSET\n");
+	{	unsigned long G11;
+		asm volatile("mov %0, G11\n\t"
+		     :"=l"(G11)
+		     :/*no input*/
+		     :"%G11");
+		printk("G9: [0x%x], G11: [0x%x]\n", (long)G9, (long)G11 );
+	}
+#endif
+
+#undef uSavedUB
+#undef uSavedSP
+#undef uSR
+#undef uPC
+#undef SavedG4
+#undef L0
+#undef L1
+#undef L2
+#undef L3
+#undef L4
+#undef L5
+#undef UB
+#undef uG3
+#undef uG4
+#undef uG5
+#undef TOP_OF_KERNEL_AGGREGATE_STACK
+}
+
+/*
+ * Free current thread data structures etc..
+ */
+void exit_thread(void)
+{
+	/* We de-allocate the kernel register stack 
+	 * we allocated in copy_thread..*/
+	/* free_task_struct(current->thread.G11); */
+}
+
+void flush_thread(void)
+{
+	/* Nothing to be done for the time being */
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+
+inline unsigned long thread_saved_pc(struct thread_struct *t) { return 0; }
+
+unsigned long get_wchan(struct task_struct *p)
+{
+		return 0; /* Empty for the time being */
+}
+
+/* If we are in kernel aggregate stack; function 
+ * returns 1, else returns 0.
+ */
+//#define DBG_AreWeInKernelAggrStack
+long AreWeInKernelAggrStack(void)
+{
+	unsigned long G3, G9;
+	asm volatile("mov %0, G3\n\t"
+				 "mov %1, G9\n\t"
+				 :"=l"(G3),
+				  "=l"(G9)
+				 :/*no input*/);
+	if( G9 > G3 && (G9 - 0x1000) < G3) {
+#ifdef DBG_AreWeInKernelAggrStack
+			printk("AreWeInKernelAggrStack returns 1\n");
+#endif
+			return 1;
+	}
+	else {
+			current->thread.stack_use.excp_in_km_while_using_user_aggr_stack = 1;
+#ifdef DBG_AreWeInKernelAggrStack
+			printk("AreWeInKernelAggrStack returns 0\n");
+#endif
+			return 0;
+	}
+}
+
+/* If we are in kernel register stack; function 
+ * returns 1, else returns 0.
+ */
+//#define DBG_AreWeInKernelRegisterStack
+long AreWeInKernelRegisterStack(void)
+{
+	unsigned long SP, G11; 
+	asm volatile("ori SR, 0x20\n\t"
+				 "mov %0, SP\n\t"
+				 "mov %1, G11\n\t"
+				 :"=l"(SP),
+				  "=l"(G11)
+				 :/*no input*/ );
+
+	if( G11 <= SP  &&  G11 + 0x1000 > SP ) {
+#ifdef DBG_AreWeInKernelRegisterStack
+			printk("AreWeInKernelRegisterStack returns 1\n");
+#endif
+			return 1;
+	}
+	else {
+			current->thread.stack_use.excp_in_km_while_using_user_reg_stack = 1;
+#ifdef DBG_AreWeInKernelRegisterStack
+			printk("AreWeInKernelRegisterStack returns 0\n");
+#endif
+			return 0;
+	}
+}
+
+/* If we need to change register stack; function
+ * returns 1, else returns 0
+ */
+//#define DBG_ShouldWeChangeRegisterStack
+long ShouldWeChangeBackRegisterStack(void)
+{
+	if( current->thread.stack_use.excp_in_km_while_using_user_reg_stack == 1 ) {
+		current->thread.stack_use.excp_in_km_while_using_user_reg_stack = 0;
+#ifdef DBG_ShouldWeChangeRegisterStack
+		printk("ShouldWeChangeRegisterStack returns 1\n");
+#endif
+		return 1;
+	} else {
+#ifdef DBG_ShouldWeChangeRegisterStack
+		printk("ShouldWeChangeRegisterStack returns 0\n");
+#endif
+		return 0;
+	}
+}
+
+/* If we need to change aggregate stack; function
+ * returns 1, else returns 0.
+ */
+//#define DBG_ShouldWeChangeAggregateStack
+long ShouldWeChangeBackAggregateStack(void)
+{
+	if( current->thread.stack_use.excp_in_km_while_using_user_aggr_stack == 1 ) {
+		current->thread.stack_use.excp_in_km_while_using_user_aggr_stack = 0;
+#ifdef DBG_ShouldWeChangeAggregateStack
+		printk("ShouldWeChangeAggregateStack returns 1\n");
+#endif
+		return 1;
+	} else {
+#ifdef DBG_ShouldWeChangeAggregateStack
+		printk("ShouldWeChangeAggregateStack returns 0\n");
+#endif
+		return 0;
+	}
+}
+
+long ShortOfUserRegisterStack(void)
+{
+#define UserSP	G9[-7]
+#define UserUB	G9[-11]
+		unsigned long *G9;
+
+		/* G9 is the Aggregate Stack Pointer */
+		asm volatile("mov %0, G9"
+					:"=l"(G9)
+					:/* no input */);
+
+		if( UserUB - UserSP < STACK_OFFSET )
+				return 1;
+		else
+				return 0;
+#undef  UserSP
+#undef  UserUB
+}
+
+long ShortOfUserAggregateStack(void)
+{
+#define UserG3  G9[-1]
+#define UserG5  G9[-3]
+		unsigned long *G9;
+
+		/* G9 is the Aggregate Stack Pointer */
+		asm volatile("mov %0, G9"
+					:"=l"(G9)
+					:/* no input */);
+
+		if( UserG3 - UserG5 < STACK_OFFSET )
+				return 1;
+		else
+				return 0;
+#undef UserG3
+#undef UserG5
+}	
+
+/* Code Related to stack growning 
+ * Non-valid for uClinux */
+#if 0
+#define DBG_expand_user_reg_stack
+void expand_user_reg_stack(void)
+{
+#define UserSP	G9[-7]
+#define UserUB	G9[-11]
+
+		unsigned long NewStackSize = 2 * current->thread.ursi.size;
+		unsigned long *NewLowerBound = (unsigned long*)0;
+		unsigned long *G9;
+		unsigned long prevSP;
+
+		/* G9 is the Aggregate Stack Pointer */
+		asm volatile("mov %0, G9"
+					:"=l"(G9)
+					:/* no input */);
+
+		/* Allocate the new Register Stack */
+		NewLowerBound =  (unsigned long*) do_mmap( 0, 0, NewStackSize,
+								 PROT_READ | PROT_EXEC | PROT_WRITE, 0, 0 );
+
+		/*Zero new stack */
+		memset( (char*)NewLowerBound, 0, NewStackSize);
+		/* Copy old stack to the new one */
+		memcpy( NewLowerBound, current->thread.ursi.LowerBound, current->thread.ursi.size ); 
+
+#ifdef DBG_expand_user_reg_stack
+		printk("Entered expand_user_reg_stack...\n");
+		printk("Previous stack size : 0x%x, New stack size : 0x%x\n", current->thread.ursi.size, NewStackSize );
+		printk("Previous LowerBound : 0x%x, New LowerBound : 0x%x\n", current->thread.ursi.LowerBound, NewLowerBound ); 
+#endif
+
+		/* Set SP, UB values. The actual return values are located in
+		 * the Kernel Aggregate Stack. */
+		/* Put their values in the Kernel Aggregate Stack */
+#ifdef DBG_expand_user_reg_stack
+		printk("Previous UserSP : 0x%x, Previous UserUB : 0x%x\n", UserSP, UserUB );
+		printk("stack size : 0x%x\n", UserSP - current->thread.ursi.LowerBound );
+#endif
+		prevSP = UserSP;
+	 	UserSP = prevSP - current->thread.ursi.LowerBound + (unsigned long)NewLowerBound; 	
+		UserUB = (unsigned long)NewLowerBound + NewStackSize - STACK_OFFSET;
+
+#ifdef DBG_expand_user_reg_stack
+		printk("New UserSP : 0x%x, New UserUB : 0x%x\n", UserSP, UserUB );
+		printk("G9 : 0x%x, &UserSP : 0x%x, &UserUB : 0x%x\n", G9, &UserSP, &UserUB );
+#endif
+
+		/* Memory unmap the already mapped stack */
+		if( current->thread.uasi.size > 0x1000 )
+		do_munmap( current->mm, current->thread.ursi.LowerBound, current->thread.ursi.size );
+
+		/* Update the values of the register_stack_info struct */
+		current->thread.ursi.LowerBound = NewLowerBound;
+		current->thread.ursi.size = NewStackSize;
+#ifdef DBG_expand_user_reg_stack
+		printk("Exiting expand_user_reg_stack\n");
+#endif
+
+#undef UserSP
+#undef UserUB
+}
+
+#define DBG_expand_user_aggr_stack
+void expand_user_aggr_stack(void)
+{
+		unsigned long NewStackSize = 2 * current->thread.uasi.size;
+		unsigned long *NewLowerBound = (unsigned long*)0;
+		unsigned long *G9;
+		unsigned long G3, G4, G5;
+		unsigned long prevG3, prevG4, prevG5;
+
+#define UserG3  G9[-1]
+#define UserG4  G9[-2]
+#define UserG5  G9[-3]
+	
+		/* G9 is the Aggregate Stack Pointer */
+		asm volatile("mov %0, G9"
+					:"=l"(G9)
+					:/* no input */);
+
+		/* Allocate the new Register Stack */
+		NewLowerBound =  (unsigned long*) do_mmap( 0, 0, NewStackSize,
+								 PROT_READ | PROT_EXEC | PROT_WRITE, 0, 0 );
+
+		/*Zero new stack */
+		memset( (char*)NewLowerBound, 0, NewStackSize);
+		/* Copy old stack to the new one */
+		memcpy( (char*)((unsigned long)NewLowerBound + (NewStackSize/2)), 
+				current->thread.uasi.LowerBound, 
+				current->thread.uasi.size ); 
+
+#ifdef DBG_expand_user_aggr_stack
+		printk("Entered expand_user_aggr_stack\n");
+		printk("Previous stack size : 0x%x, New stack size : 0x%x\n", current->thread.uasi.size, NewStackSize );
+		printk("Previous LowerBound : 0x%x, New LowerBound : 0x%x\n", current->thread.uasi.LowerBound, NewLowerBound ); 
+#endif
+
+		/* Set new G3, G4, G5 values. The actual return values are located in
+		 * the Kernel Aggregate Stack. */
+		prevG3 = UserG3;
+		UserG3 = prevG3 - current->thread.uasi.LowerBound + (unsigned long)NewLowerBound + (NewStackSize/2);
+		prevG4 = UserG4;
+		UserG4 = prevG4 - current->thread.uasi.LowerBound + (unsigned long)NewLowerBound + (NewStackSize/2);
+		prevG5 = UserG5;
+		UserG5 = (unsigned long)NewLowerBound + STACK_OFFSET;
+
+#ifdef DBG_expand_user_aggr_stack
+		printk("prevG3 : 0x%x, newG3 : 0x%x\n", prevG3, UserG3 );
+		printk("prevG4 : 0x%x, newG4 : 0x%x\n", prevG4, UserG4 );
+		printk("prevG5 : 0x%x, newG5 : 0x%x\n", prevG5, UserG5 );
+#endif
+
+		/* Memory unmap the already mapped stack */
+		if( current->thread.uasi.size > 0x1000 )
+		do_munmap( current->mm, current->thread.ursi.LowerBound, current->thread.ursi.size );
+
+		/* Update the values of the register_stack_info struct */
+		current->thread.ursi.LowerBound = NewLowerBound;
+		current->thread.ursi.size = NewStackSize;
+#ifdef DBG_expand_user_aggr_stack
+		printk("Exiting expand_user_aggr_stack\n");
+#endif
+
+#undef UserG3
+#undef UserG4
+#undef UserG5
+}
+
+long changeSPvalue(unsigned long newUB, unsigned long oldUB, unsigned long oldSP )
+{
+		unsigned long newSP = newUB - (oldUB - oldSP) - (current->thread.ursi.size/2);
+		printk("oldSP : 0x%x, newSP : 0x%x\n", oldSP, newSP );
+		return newSP;
+}
+
+/* Printing SP, UB in supervisor mode */
+void print_SP_UB(void)
+{
+	unsigned long SP, UB;
+	printk("Entered print_SP_UB\n");
+	asm volatile("ori SR, 0x20\n\t"
+				 "mov %0, SP\n\t"
+				 "ori SR, 0x20\n\t"
+				 "mov %1, UB\n\t"
+				 :"=l"(SP),
+				  "=l"(UB)
+				 :/*no input*/);
+	printk("SP : 0x%x, UB, : 0x%x\n", (int)SP, (int)UB);
+}
+#endif
diff -urN linux-2.4.29/arch/e1nommu/kernel/ptrace.c linux-2.4.29-uc1/arch/e1nommu/kernel/ptrace.c
--- linux-2.4.29/arch/e1nommu/kernel/ptrace.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/kernel/ptrace.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,14 @@
+/*
+ * arch/e1nommu/kernel/ptrace.c
+ *
+ *  Copyright (C) 2002-2003,    George Thanos <george.thanos@gdt.gr>
+ *                              Yannis Mitsos <yannis.mitsos@gdt.gr>
+ */
+
+#include <linux/sched.h>
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ * Make sure the single step bit is not set.
+ */
+void ptrace_disable(struct task_struct *child) { }
diff -urN linux-2.4.29/arch/e1nommu/kernel/semaphore.c linux-2.4.29-uc1/arch/e1nommu/kernel/semaphore.c
--- linux-2.4.29/arch/e1nommu/kernel/semaphore.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/kernel/semaphore.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,159 @@
+/*
+ *  linux/arch/e1nommu/kernel/semaphore.c
+ *
+ *  Copyright (C) 2002-2003 	George Thanos <george.thanos@gdt.gr>
+ *    			 	Yannis Mitsos <yannis.mitsos@gdt.gr>
+ *
+ *  Derived from <linux/arch/s390/kernel/semaphore.c>
+ *  Copyright (C) 1999, Linus Torvalds
+ *
+ */
+#include <linux/sched.h>
+
+#include <asm/semaphore.h>
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to acquire the semaphore, while the "sleeping"
+ * variable is a count of such acquires.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * "sleeping" and the contention routine ordering is
+ * protected by the semaphore spinlock.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+
+/*
+ * Logic:
+ *  - only on a boundary condition do we need to care. When we go
+ *    from a negative count to a non-negative, we wake people up.
+ *  - when we go from a non-negative count to a negative do we
+ *    (a) synchronize with the "sleeper" count and (b) make sure
+ *    that we're on the wakeup list before we synchronize so that
+ *    we cannot lose wakeup events.
+ */
+
+void __up(struct semaphore *sem)
+{
+	wake_up(&sem->wait);
+}
+
+static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED;
+
+void __down(struct semaphore * sem)
+{
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+	tsk->state = TASK_UNINTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	spin_lock_irq(&semaphore_lock);
+	sem->sleepers++;
+	for (;;) {
+		int sleepers = sem->sleepers;
+
+		/*
+		 * Add "everybody else" into it. They aren't
+		 * playing, because we own the spinlock.
+		 */
+		if (!atomic_add_negative(sleepers - 1, &sem->count)) {
+			sem->sleepers = 0;
+			break;
+		}
+		sem->sleepers = 1;	/* us - see -1 above */
+		spin_unlock_irq(&semaphore_lock);
+
+		schedule();
+		tsk->state = TASK_UNINTERRUPTIBLE;
+		spin_lock_irq(&semaphore_lock);
+	}
+	spin_unlock_irq(&semaphore_lock);
+	remove_wait_queue(&sem->wait, &wait);
+	tsk->state = TASK_RUNNING;
+	wake_up(&sem->wait);
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+	int retval = 0;
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+	tsk->state = TASK_INTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	spin_lock_irq(&semaphore_lock);
+	sem->sleepers ++;
+	for (;;) {
+		int sleepers = sem->sleepers;
+
+		/*
+		 * With signals pending, this turns into
+		 * the trylock failure case - we won't be
+		 * sleeping, and we* can't get the lock as
+		 * it has contention. Just correct the count
+		 * and exit.
+		 */
+		if (signal_pending(current)) {
+			retval = -EINTR;
+			sem->sleepers = 0;
+			atomic_add(sleepers, &sem->count);
+			break;
+		}
+
+		/*
+		 * Add "everybody else" into it. They aren't
+		 * playing, because we own the spinlock. The
+		 * "-1" is because we're still hoping to get
+		 * the lock.
+		 */
+		if (!atomic_add_negative(sleepers - 1, &sem->count)) {
+			sem->sleepers = 0;
+			break;
+		}
+		sem->sleepers = 1;	/* us - see -1 above */
+		spin_unlock_irq(&semaphore_lock);
+
+		schedule();
+		tsk->state = TASK_INTERRUPTIBLE;
+		spin_lock_irq(&semaphore_lock);
+	}
+	spin_unlock_irq(&semaphore_lock);
+	tsk->state = TASK_RUNNING;
+	remove_wait_queue(&sem->wait, &wait);
+	wake_up(&sem->wait);
+	return retval;
+}
+
+/*
+ * Trylock failed - make sure we correct for
+ * having decremented the count.
+ */
+int __down_trylock(struct semaphore * sem)
+{
+        unsigned long flags;
+	int sleepers;
+
+	spin_lock_irqsave(&semaphore_lock, flags);
+	sleepers = sem->sleepers + 1;
+	sem->sleepers = 0;
+
+	/*
+	 * Add "everybody else" and us into it. They aren't
+	 * playing, because we own the spinlock.
+	 */
+	if (!atomic_add_negative(sleepers, &sem->count))
+		wake_up(&sem->wait);
+
+	spin_unlock_irqrestore(&semaphore_lock, flags);
+	return 1;
+}
diff -urN linux-2.4.29/arch/e1nommu/kernel/setup.c linux-2.4.29-uc1/arch/e1nommu/kernel/setup.c
--- linux-2.4.29/arch/e1nommu/kernel/setup.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/kernel/setup.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,306 @@
+/*
+ * linux/arch/e1nommu/kernel/setup.c
+ *
+ * Copyright (C) 2002-2003  George Thanos <george.thanos@gdt.gr>
+ * 			    Yannis Mitsos <yannis.mitsos@gdt.gr>
+ *
+ * derived from:
+ *  linux/arch/m68knommu/kernel/setup.c
+ *
+ *  Copyleft  ()) 2000       James D. Schettine {james@telos-systems.com}
+ *  Copyright (C) 1999,2000  Greg Ungerer (gerg@uClinux.org)
+ *  Copyright (C) 1998-2003  D. Jeff Dionne <jeff@uClinux.org>
+ *  Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ *  Copyright (C) 1995       Hamish Macdonald
+ *  Copyright (C) 2000       Lineo Inc. (www.lineo.com) 
+ */
+
+/*
+ * This file handles the architecture-dependent parts of system setup
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/genhd.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/major.h>
+#include <linux/bootmem.h>
+#include <linux/seq_file.h>
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <linux/blk.h>
+#include <asm/pgtable.h>
+#endif
+
+unsigned long rom_length;
+unsigned long memory_start;
+unsigned long memory_end;
+
+struct task_struct *_current_task;
+
+//char command_line[512]="root=/dev/ram0 init=/linuxrc rw";
+//char command_line[512]="console=ttyS0,115200 devfs=dreg,digmod,dall root=/dev/rd/0 init=/linuxrc";
+//char command_line[512]="ip=147.102.7.253::147.102.7.200:255.255.255.0:aceos:eth0:off root=/dev/nfs nfsroot=147.102.19.18:/hyperstone-root1 console=ttyS0,115200";
+//char command_line[512]="console=ttyS0,115200 devfs=dreg,digmod,dall ip=:::::: root=/dev/nfs nfsroot=147.102.19.18:/hyperstone-root";
+//char command_line[512]="console=ttyS0,115200 devfs=dreg,digmod,dall";
+char command_line[512];
+
+char saved_command_line[512];
+
+void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) = NULL;
+void (*mach_tick)( void ) = NULL;
+/* machine dependent keyboard functions */
+int (*mach_keyb_init) (void) = NULL;
+#ifdef __NF_NOT_DEF
+int (*mach_kbdrate) (struct kbd_repeat *) = NULL;
+#endif
+void (*mach_kbd_leds) (unsigned int) = NULL;
+/* machine dependent irq functions */
+void (*mach_init_IRQ) (void) = NULL;
+void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
+int (*mach_request_irq) (unsigned int, void (*)(int, void *, struct pt_regs *),
+                         unsigned long, const char *, void *);
+void (*mach_free_irq) (unsigned int irq, void *dev_id) = NULL;
+void (*mach_enable_irq) (unsigned int) = NULL;
+void (*mach_disable_irq) (unsigned int) = NULL;
+int (*mach_get_irq_list) (char *) = NULL;
+void (*mach_process_int) (int irq, struct pt_regs *fp) = NULL;
+void (*mach_trap_init) (void);
+/* machine dependent timer functions */
+unsigned long (*mach_gettimeoffset) (void) = NULL;
+void (*mach_gettod) (int*, int*, int*, int*, int*, int*) = NULL;
+void (*mach_reset)( void ) = NULL;
+int (*mach_set_clock_mmss) (unsigned long) = NULL;
+void (*mach_debug_init)(void) = NULL;
+void (*mach_halt)( void ) = NULL;
+void (*mach_power_off)( void ) = NULL;
+
+//#define DEBUG	1
+
+#ifdef CONFIG_E132XS
+	#define CPU "Hyperstone E1-32XS"
+#endif
+
+#ifdef CONFIG_BLK_DEV_BLKMEM
+#define CAT_ROMARRAY
+#endif
+
+extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
+extern int _ramstart, _ramend;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+extern int _sinitrd, _einitrd;
+#endif
+
+extern unsigned long fExt_Osc;
+extern int _sbss, __ramend;
+
+void setup_arch(char **cmdline_p)
+{
+	int bootmap_size;
+
+#undef ZERO_MEM
+#ifdef ZERO_MEM
+	int start_mem = (int)&_ebss;
+	int end_mem = (int)&__ramend;
+	memset((char*)&_ebss, 0, end_mem - start_mem);
+	printk("ZERO MEM : 0x%x -> 0x%x\n", start_mem, end_mem );
+#endif
+
+#ifdef CAT_ROMARRAY
+#if 0
+	extern int __data_rom_start;
+	extern int __data_start;
+	int *romarray = (int *)((int) &__data_rom_start +
+				      (int)&_edata - (int)&__data_start);
+
+#endif
+	int	 *romarray = (int *)(&_ebss);
+#endif
+
+#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
+    /* we need to initialize the Flashrom device here since we might
+	 * do things with flash early on in the boot
+	 */
+	flash_probe();
+#endif
+
+	memory_start = PAGE_ALIGN(_ramstart);
+	memory_end = _ramend; /* by now the stack is part of the init task */
+
+	init_mm.start_code = (unsigned long) &_stext;
+	init_mm.end_code = (unsigned long) &_etext;
+	init_mm.end_data = (unsigned long) &_edata;
+#if 0 /* DAVIDM - don't set brk just incase someone decides to use it */
+	init_mm.brk = (unsigned long) &_end;
+#else
+	init_mm.brk = (unsigned long) 0;
+#endif
+
+	config_BSP(&command_line[0], sizeof(command_line));
+
+	printk("\x0F\r\n\nuClinux/" CPU "\n");
+	printk("Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
+
+#ifdef DEBUG
+	printk("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x "
+		"BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext,
+		(int) &_sdata, (int) &_edata,
+		(int) &_sbss, (int) &_ebss);
+	printk("KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x "
+		"STACK=0x%06x-0x%06x\n",
+#ifdef CAT_ROMARRAY
+	       (int) romarray, ((int) romarray) + romarray[2],
+#else
+	       (int) &_ebss, (int) memory_start,
+#endif
+		(int) memory_start, (int) memory_end,
+		(int) memory_end, (int) _ramend);
+#endif
+
+#ifdef CONFIG_BLK_DEV_BLKMEM
+    ROOT_DEV = MKDEV(BLKMEM_MAJOR,0);
+#endif
+
+	/* Keep a copy of command line */
+	*cmdline_p = &command_line[0];
+	memcpy(saved_command_line, command_line, sizeof(saved_command_line));
+	saved_command_line[sizeof(saved_command_line)-1] = 0;
+
+#ifdef DEBUG
+	if (strlen(*cmdline_p)) 
+		printk("Command line: '%s'\n", *cmdline_p);
+#endif
+	/*rom_length = (unsigned long)&_flashend - (unsigned long)&_romvec;*/
+	
+#ifdef CONFIG_VT_CONSOLE
+#ifdef CONFIG_FB
+       conswitchp = &dummy_con;
+#endif
+#endif
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	initrd_start = (unsigned long)&_sinitrd;
+	initrd_end = (unsigned long)&_einitrd;
+	printk("initrd starts at 0x%X, ends at 0x%X\n", initrd_start, initrd_end);
+	if (initrd_end > memory_end) {
+		printk("initrd extends beyond end of memory (0x%X), disabling\n", memory_end);
+		initrd_start = 0;
+	}
+#endif
+
+	/*
+	 * give all the memory to the bootmap allocator,  tell it to put the
+	 * boot mem_map at the start of memory
+	 */
+	bootmap_size = init_bootmem_node(
+			NODE_DATA(0),
+			memory_start >> PAGE_SHIFT, /* map goes here */
+			PAGE_OFFSET >> PAGE_SHIFT,	/* 0 on coldfire */
+			memory_end >> PAGE_SHIFT);
+	/*
+	 * free the usable memory,  we have to make sure we do not free
+	 * the bootmem bitmap so we then reserve it after freeing it :-)
+	 */
+	free_bootmem(memory_start, memory_end - memory_start);
+	reserve_bootmem(memory_start, bootmap_size);
+
+	/*
+	 * get kmalloc into gear
+	 */
+	paging_init();
+#ifdef DEBUG
+	printk("Done setup_arch\n");
+#endif
+
+}
+
+int get_cpuinfo(char * buffer)
+{
+    char *cpu, *mmu, *fpu;
+    u_long clockfreq;
+
+    cpu = CPU;
+    mmu = "none";
+    fpu = "none";
+
+/*    clockfreq = (loops_per_jiffy*HZ)*16; */
+    clockfreq = fExt_Osc * 1000;
+
+    return(sprintf(buffer, "CPU:\t\t%s\n"
+		   "MMU:\t\t%s\n"
+		   "FPU:\t\t%s\n"
+		   "Clocking:\t%lu.%1luMHz\n"
+		   "BogoMips:\t%lu.%02lu\n"
+		   "Calibration:\t%lu loops\n",
+		   cpu, mmu, fpu,
+		   clockfreq/1000000,(clockfreq/100000)%10,
+		   (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
+		   (loops_per_jiffy*HZ)));
+}
+
+/*
+ *	Get CPU information for use by the procfs.
+ */
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+    char *cpu, *mmu, *fpu;
+    u_long clockfreq;
+	signed short mult_factor[8]={3, 2, 1, 0, -1, 0, 0, 0};
+	unsigned long tmp;
+
+    cpu = CPU;
+    mmu = "none";
+    fpu = "none";
+
+	tmp =  fExt_Osc << mult_factor[((system_sh_regs->TPRValue >> 26) & 0x7)];
+    clockfreq = tmp * 1000000;
+
+    seq_printf(m, "CPU:\t\t%s\n"
+		   "MMU:\t\t%s\n"
+		   "FPU:\t\t%s\n"
+		   "Clocking:\t%lu.%1luMHz\n"
+		   "BogoMips:\t%lu.%02lu\n"
+		   "Calibration:\t%lu loops\n",
+		   cpu, mmu, fpu,
+		   clockfreq/1000000,(clockfreq/100000)%10,
+		   (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
+		   (loops_per_jiffy*HZ));
+    return 0;
+}
+
+/* whatever... copied from m68knommu */
+static void *c_start(struct seq_file *m, loff_t *pos)
+{ return (*pos < NR_CPUS) ? ((void *)0x12345678) : NULL; }
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{ ++*pos; return c_start(m, pos); }
+static void c_stop(struct seq_file *m, void *v)
+{ ; }
+
+struct seq_operations cpuinfo_op = {
+	start:	c_start,
+	next:	c_next,
+	stop:	c_stop,
+	show:	show_cpuinfo,
+};
+
+void arch_gettod(int *year, int *mon, int *day, int *hour,
+		 int *min, int *sec)
+{
+	if (mach_gettod)
+		mach_gettod(year, mon, day, hour, min, sec);
+	else
+		*year = *mon = *day = *hour = *min = *sec = 0;
+}
diff -urN linux-2.4.29/arch/e1nommu/kernel/signal.c linux-2.4.29-uc1/arch/e1nommu/kernel/signal.c
--- linux-2.4.29/arch/e1nommu/kernel/signal.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/kernel/signal.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,740 @@
+/*
+ * linux/arch/e1nommu/kernel/signal.c
+ *
+ * Copyright (C) 2002-2003     George Thanos <george.thanos@gdt.gr>
+ *                             Yannis Mitsos <yannis.mitsos@gdt.gr>
+ * Original Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+/*****************************************************************
+ * signal handlers should be executed in User Mode. When a signal
+ * has arrived that a handler have been set for it, kernel 
+ * should return to the handler instead of the main process. 
+ * When the handler terminates the kernel will continue the
+ * execution of the main process from the point it was
+ * interrupted before the signal handler started to execute.
+ *
+ * Before starting executing the handler the return information 
+ * located in the kernel mode aggregate stack should be copied
+ * to the user mode aggregate stack. After that, kernel mode
+ * aggregate stack should be altered, so that program will 
+ * execute the handler. When the handler terminates the sigreturn()
+ * system call is invoked in order to restore the return
+ * information located in the kernel mode stack for the main/
+ * interrupted process. Return info is described by the <kaggrframe
+ * struct>.
+ ******************************************************************/
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/personality.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+#define DEBUG_SIG 0
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+void _sigreturn(void)
+{
+		sigreturn();
+}
+
+struct kaggrframe {
+	unsigned long UB; /* Lower Address  in kernel aggregate stack */
+	unsigned long L5;
+	unsigned long L4;
+	unsigned long L3;
+	unsigned long L2;
+	unsigned long L1;
+	unsigned long L0;
+	unsigned long dummy;
+	unsigned long G5;
+	unsigned long G4;
+	unsigned long G3; /* Upper Address  in kernel aggregate stack */
+};
+
+struct aggr_stack_frame {
+	struct kaggrframe kaggrframe;
+	char sigreturn_code[12]; /* located in lower addresses */
+	sigset_t oldset;
+};
+
+struct reg_stack_kernel_frame {
+	unsigned long ReturnPC; /* L0 */
+	unsigned long ReturnSR; /* L1 */
+	unsigned long ReturnSP; /* L2 */
+};
+/* We need a space of 3 registers for the 
+ * handler register stack.
+ */
+struct reg_stack_handler_frame {
+	unsigned long signum;   /* L0 */
+	unsigned long ReturnPC; /* L1 */
+	unsigned long ReturnSR; /* L2 */
+};
+
+/* We need a space of 4 registers for the register stack 
+ * of the sigreturn system call invocation.
+ */
+struct reg_stack_sigreturn_frame {
+	unsigned long L0;
+	unsigned long L1;
+	unsigned long L2;
+	unsigned long L3;
+};
+
+struct reg_stack_frame {
+	struct reg_stack_sigreturn_frame reg_sigreturn;
+	struct reg_stack_handler_frame   reg_handler;
+	struct reg_stack_kernel_frame    reg_kframe;
+};
+
+
+/**********************************************************************
+ * How do we setup the frame?
+ * OK, we need to maintain: 
+ * 1. Information located in the kernel aggregate in order to return nicely.
+ * 2. The set of currently blocked signals.
+ * 3. We need to copy the _sigreturn() code into the stack. After executing
+ *    the handler, we should run sigreturn in order to call sys_sigreturn().
+ * All the aformentioned info will be copied in the user aggregate stack.
+ * 		|---------------| <-- old user G3
+ * 		|blocked signals|
+ * 		|---------------|
+ * 		|				|
+ * 		|   sigreturn   |
+ * 		|	code		|
+ * 		|---------------|
+ * 		|				|
+ * 		|				|
+ * 		|   kaggrframe	|
+ * 		|				|
+ * 		|				|
+ * 		|---------------| <-- new user G3, G4
+ *
+ * In the user register stack we only maintain the information in order to
+ * return: 
+ * 		a. From kernel mode to the signal handler. 
+ * 		b. From the signal handler to the sigreturn code
+ * 		   located in the user aggregate stack.
+ *
+ * 		|---------------|    ^  <-- new user SP
+ * 		|  Return SP	|    |
+ * 		|---------------|    |
+ * 		|  Return SR	|  kernel mode
+ * 		|---------------|    |
+ * 		|  Return PC	|    |
+ * 		|---------------|    v	^
+ * 		|  Return SR    |   	| 
+ * 		|---------------|		|
+ * 		|  Return PC    |	 handler
+ * 		|---------------|		|
+ * 		|   signum      |		|
+ * 		|---------------|	^	v
+ * 		|     L3        |	|
+ * 		|---------------|	|
+ * 		|     L2        |	|
+ * 		|---------------|	sigreturn frame
+ * 		|     L1        |	|
+ * 		|---------------|	|
+ * 		|     L0        |	|
+ * 		|---------------|	v   <-- old user SP
+ * 
+ **********************************************************************/
+
+//#define DBG_setup_frame
+static void setup_frame(int sig, struct k_sigaction *ka,
+				            sigset_t *blockedset /*, struct pt_regs * regs*/)
+{
+	unsigned long *G9;
+	unsigned long newG3;
+	struct {
+		unsigned long FP;
+		unsigned long FL;
+	} SR;
+	struct aggr_stack_frame *user_aggr_frame_ptr;
+	struct reg_stack_frame  *user_reg_frame_ptr, reg_frame;
+
+	/* G9 defines the upper bound of the kernel aggregate stack  */
+	asm volatile ("mov %0, G9\n\t"
+					:"=l"(G9):/* no input*/:"%G9");
+
+#define TOP_OF_KERNEL_AGGREGATE_STACK  G9
+#define _G3              *(TOP_OF_KERNEL_AGGREGATE_STACK - 1)
+#define _G4              *(TOP_OF_KERNEL_AGGREGATE_STACK - 2)
+#define _G5              *(TOP_OF_KERNEL_AGGREGATE_STACK - 3)
+#define _dummy			 *(TOP_OF_KERNEL_AGGREGATE_STACK - 4)
+#define _L0              *(TOP_OF_KERNEL_AGGREGATE_STACK - 5)
+#define _L1              *(TOP_OF_KERNEL_AGGREGATE_STACK - 6)
+#define _L2              *(TOP_OF_KERNEL_AGGREGATE_STACK - 7)
+#define _L3              *(TOP_OF_KERNEL_AGGREGATE_STACK - 8)
+#define _L4              *(TOP_OF_KERNEL_AGGREGATE_STACK - 9)
+#define _L5              *(TOP_OF_KERNEL_AGGREGATE_STACK - 10)
+#define _UB              *(TOP_OF_KERNEL_AGGREGATE_STACK - 11)
+
+	/***************************************************
+	 * Start constructing the aggregate stack
+	 * 1. Decrease the user aggregate SP by 
+	 *    sizeof(struct aggr_stack_frame).
+	 * 2. Copy kernel aggregate return info 
+	 *    to <user_aggr_frame_ptr->kaggrframe>.
+	 * 3. Copy sigreturn code to 
+	 *    <user_aggr_frame_ptr->sigreturn_code>.
+	 * 4. Copy *blockedset to <user_aggr_frame_ptr->oldset>
+	 ***************************************************/
+
+#ifdef DBG_setup_frame
+	printk("Entered setup_frame\n");
+	printk("Values located in the kernel aggregate stack\n");
+	printk("G3 : 0x%x, G4 : 0x%x, G5 : 0x%x\n", _G3, _G4, _G5 );
+	printk("L0 : 0x%x, L1 : 0x%x, L2 : 0x%x\n", _L0, _L1, _L2 );
+	printk("L3 : 0x%x, L4 : 0x%x, L5 : 0x%x, UB : 0x%x\n",  _L3, _L4, _L5, _UB ); 
+#endif
+
+	/* _G3 is the lower index of the aggregate stack. _G3 is
+	 * decreased by sizeof(struct aggr_stack_frame) */
+	newG3 = _G3 - sizeof(struct aggr_stack_frame);
+	user_aggr_frame_ptr = (struct aggr_stack_frame*)newG3;
+
+	/* fill aggregate stack with the frame info */
+	put_user(_G3, &user_aggr_frame_ptr->kaggrframe.G3);
+	put_user(_G4, &user_aggr_frame_ptr->kaggrframe.G4);
+	put_user(_G5, &user_aggr_frame_ptr->kaggrframe.G5);
+	put_user(_dummy, &user_aggr_frame_ptr->kaggrframe.dummy);
+	put_user(_L0, &user_aggr_frame_ptr->kaggrframe.L0 );
+	put_user(_L1, &user_aggr_frame_ptr->kaggrframe.L1 );
+	put_user(_L2, &user_aggr_frame_ptr->kaggrframe.L2 );
+	put_user(_L3, &user_aggr_frame_ptr->kaggrframe.L3 );
+	put_user(_L4, &user_aggr_frame_ptr->kaggrframe.L4 );
+	put_user(_L5, &user_aggr_frame_ptr->kaggrframe.L5 );
+	put_user(_UB, &user_aggr_frame_ptr->kaggrframe.UB );
+
+	/* Copy sigreturn code to the user aggregate stack.
+	 * 12 is the sizeof _sigreturn function (from objdump...)*/
+	copy_to_user((char*)user_aggr_frame_ptr->sigreturn_code, (char*)_sigreturn, 12 );
+	put_user(blockedset->sig[0], &user_aggr_frame_ptr->oldset.sig[0]);
+	put_user(blockedset->sig[1], &user_aggr_frame_ptr->oldset.sig[1]);
+
+	/* _G3 and _G4 are indexing right after user_aggregate_ptr
+	 * Be carefull not to exceed the aggregate stack of the signal
+	 * handler. You will corrupt user_aggr_frame_ptr values. */
+	_G3 = newG3;
+	_G4 = newG3;
+
+#ifdef DBG_setup_frame
+	printk("User Aggregate Stack values of the signal handler\n");
+	printk("newG3 : 0x%x, newG4 : 0x%x\n", _G3, _G4 );
+#endif
+
+	/***************************************************
+	 * Start constructing the register stack
+	 ***************************************************/
+	user_reg_frame_ptr = (struct reg_stack_frame *)_L2;
+
+#define ReturnSP  reg_frame.reg_kframe.ReturnSP
+#define ReturnSR  reg_frame.reg_kframe.ReturnSR
+#define ReturnPC  reg_frame.reg_kframe.ReturnPC
+	ReturnSP = _L2 + sizeof(struct reg_stack_handler_frame) 
+				   + sizeof(struct reg_stack_sigreturn_frame);	
+	ReturnPC = (unsigned long)ka->sa.sa_handler;
+
+	ReturnSR = _L1 & 0x7F00;
+    /* FL = 6 arbitrarily 
+	 * FP = SP - 2*4. When entering signal handler a 
+	 * frame Lx, L1 will reduce SP by 4 bytes!!!*/
+/*1.FL*/SR.FL = 6; SR.FL <<= 21; ReturnSR |= SR.FL;
+/*2.FP*/SR.FP = (ReturnSP - 2*4); SR.FP &= 0x000001fc;
+	SR.FP <<= 23; ReturnSR |= SR.FP;
+
+	/* Place the return info in the kernel
+	 * aggregate stack. */
+	_L0 = ReturnPC;
+	_L1 = ReturnSR;
+	_L2 = ReturnSP;
+#undef ReturnSP
+#undef ReturnSR
+#undef ReturnPC
+
+#define _signum_    reg_frame.reg_handler.signum
+#define _ReturnPC_  reg_frame.reg_handler.ReturnPC
+#define _ReturnSR_  reg_frame.reg_handler.ReturnSR
+
+	_signum_ = sig;
+	put_user( _signum_, &user_reg_frame_ptr->reg_handler.signum );
+	_ReturnPC_ = (unsigned long)user_aggr_frame_ptr->sigreturn_code;
+	put_user( _ReturnPC_, &user_reg_frame_ptr->reg_handler.ReturnPC );
+
+    /* FL = 4 */
+	_ReturnSR_ = 0;
+/*1.FL*/SR.FL = 4; SR.FL <<= 21; _ReturnSR_ |= SR.FL;
+/*2.FP*/SR.FP = ( reg_frame.reg_kframe.ReturnSP - 7*4); SR.FP &= 0x000001fc;
+	SR.FP <<= 23; _ReturnSR_ |= SR.FP;
+	put_user( _ReturnSR_, &user_reg_frame_ptr->reg_handler.ReturnSR );
+
+#undef signum
+#undef ReturnPC
+#undef ReturnSR
+
+#undef _L0
+#undef _L1
+#undef _L2
+#undef _L3
+#undef _L4
+#undef _L5
+#undef _UB
+#undef _G3
+#undef _G4
+#undef _G5
+#undef _dummy
+#undef TOP_OF_KERNEL_AGGREGATE_STACK
+}
+
+static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set)
+{
+}
+
+/*
+ * OK, we're invoking a handler
+ */	
+//#define DBG_handle_signal
+static void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+	      siginfo_t *info, sigset_t *oldset, struct pt_regs regs)
+{
+#define L    regs.L
+#define FL   regs.FL
+#define SYSCALL_RETURN_VALUE	L[FL-1]
+#define SYSCALL_RETURN_PC		L[FL]
+
+#ifdef  DBG_handle_signal
+	printk("f.blocked->sig[0] : 0x%x, blocked->sig[1] : 0x%x\n",
+		  (int)current->blocked.sig[0], (int)current->blocked.sig[1] );
+	printk("L[FL+3] : 0x%x(%d)\n", (int)L[FL+3], (int)L[FL+3] );
+#endif
+	/* We have to check for system call restarting both here and
+	 * at the end of do_signal.
+	 * 1. If a handler is specified do_signal returns immidiately
+	 *    according to POSIX. The check code at the end of do_signal
+	 *    won't run.
+	 * 2. If a handler is not present and action is "ignore" code at
+	 *    the end of do_signal will run.
+	 *
+	 * -> L[FL+3] will contain the value 14 if we came from a 
+	 * system-call
+	 */
+
+	/* Do we come from a system call? */
+	if ( L[FL+3] == 14 ) {
+		/* If so, check system call restarting.. */
+		switch ( SYSCALL_RETURN_VALUE ) {
+			/* Handler is specified here... */
+			case -ERESTARTNOHAND:
+				SYSCALL_RETURN_VALUE = -EINTR;
+				break;
+			case -ERESTARTSYS:
+				if (!(ka->sa.sa_flags & SA_RESTART)) {
+					SYSCALL_RETURN_VALUE = -EINTR;
+					break;
+				}
+			/* fallthrough */
+			case -ERESTARTNOINTR:
+				SYSCALL_RETURN_PC -= 2;
+		}
+	}
+#undef SYSCALL_RETURN_VALUE
+#undef SYSCALL_RETURN_PC
+#undef L
+#undef FL
+
+	/* Set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset);
+	else
+		setup_frame(sig, ka, oldset);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sigmask_lock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending(current);
+		spin_unlock_irq(&current->sigmask_lock);
+	}
+}
+
+//#define DBG_sys_sigreturn
+asmlinkage int sys_sigreturn(void)
+{
+	unsigned long *G9;
+	struct aggr_stack_frame *user_aggr_frame_ptr;
+	asm volatile ("mov %0, G9"
+					:"=l"(G9):/* no input*/);
+#define TOP_OF_KERNEL_AGGREGATE_STACK  G9
+#define _G3              *(TOP_OF_KERNEL_AGGREGATE_STACK - 1)
+#define _G4              *(TOP_OF_KERNEL_AGGREGATE_STACK - 2)
+#define _G5              *(TOP_OF_KERNEL_AGGREGATE_STACK - 3)
+#define _dummy			 *(TOP_OF_KERNEL_AGGREGATE_STACK - 4)
+#define _L0              *(TOP_OF_KERNEL_AGGREGATE_STACK - 5)
+#define _L1              *(TOP_OF_KERNEL_AGGREGATE_STACK - 6)
+#define _L2              *(TOP_OF_KERNEL_AGGREGATE_STACK - 7)
+#define _L3              *(TOP_OF_KERNEL_AGGREGATE_STACK - 8)
+#define _L4              *(TOP_OF_KERNEL_AGGREGATE_STACK - 9)
+#define _L5              *(TOP_OF_KERNEL_AGGREGATE_STACK - 10)
+#define _UB              *(TOP_OF_KERNEL_AGGREGATE_STACK - 11)
+
+	user_aggr_frame_ptr = (struct aggr_stack_frame*)_G3;
+	get_user( _G3, &user_aggr_frame_ptr->kaggrframe.G3 );
+	get_user( _G4, &user_aggr_frame_ptr->kaggrframe.G4 );
+	get_user( _G5, &user_aggr_frame_ptr->kaggrframe.G5 );
+	get_user( _dummy, &user_aggr_frame_ptr->kaggrframe.dummy );
+	get_user( _L0, &user_aggr_frame_ptr->kaggrframe.L0 );
+	get_user( _L1, &user_aggr_frame_ptr->kaggrframe.L1 );
+	get_user( _L2, &user_aggr_frame_ptr->kaggrframe.L2 );
+	get_user( _L3, &user_aggr_frame_ptr->kaggrframe.L3 );
+	get_user( _L4, &user_aggr_frame_ptr->kaggrframe.L4 );
+	get_user( _L5, &user_aggr_frame_ptr->kaggrframe.L5 );
+	get_user( _UB, &user_aggr_frame_ptr->kaggrframe.UB );
+
+#ifdef DBG_sys_sigreturn
+	printk("Entered sys_sigreturn\n");
+	printk("aggr_frame : 0x%x\n", (int)aggr_frame );
+	printk("G3 : 0x%x, G4 : 0x%x, G5 : 0x%x\n", _G3, _G4, _G5 );
+	printk("L0 : 0x%x, L1 : 0x%x, L2 : 0x%x\n", _L0, _L1, _L2 );
+	printk("L3 : 0x%x, L4 : 0x%x, L5 : 0x%x, UB : 0x%x\n", _L3, _L4, _L5, _UB );
+#endif
+	{
+		sigset_t oldset;
+		/* Get block signal values */
+		get_user( oldset.sig[0], &user_aggr_frame_ptr->oldset.sig[0] );
+		get_user( oldset.sig[1], &user_aggr_frame_ptr->oldset.sig[1] );
+
+		sigdelsetmask(&oldset, ~_BLOCKABLE);
+		spin_lock_irq(&current->sigmask_lock);
+		current->blocked = oldset;
+		recalc_sigpending(current);
+		spin_unlock_irq(&current->sigmask_lock);
+	}
+
+#ifdef DBG_sys_sigreturn
+	printk("after. blocked->sig[0] : 0x%x, blocked->sig[1] : 0x%x\n",
+		(int)current->blocked.sig[0], (int)current->blocked.sig[1] );
+#endif
+
+#undef _L0
+#undef _L1
+#undef _L2
+#undef _L3
+#undef _L4
+#undef _L5
+#undef _UB
+#undef _G3
+#undef _G4
+#undef _G5
+#undef _dummy
+#undef _TOP_OF_KERNEL_AGGREGATE_STACK
+	return 0;
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals that
+ * the kernel can handle, and then we build all the user-level signal handling
+ * stack-frames in one go after that.
+ */
+//#define DBG_do_signal
+int do_signal(struct pt_regs regs)
+{
+	siginfo_t info;
+	struct k_sigaction *ka;
+	sigset_t *oldset;
+
+	/*
+	 * We want the common case to go fast, which
+	 * is why we may in certain cases get here from
+	 * kernel mode. Just return without doing anything
+	 * if so.
+	 */
+	if (!user_mode(&regs))
+		return 1;
+
+	oldset = &current->blocked;
+
+	for (;;) {
+		unsigned long signr;
+
+		spin_lock_irq(&current->sigmask_lock);
+		signr = dequeue_signal(&current->blocked, &info);
+		spin_unlock_irq(&current->sigmask_lock);
+
+		if (!signr)
+			break;
+
+		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			/* Let the debugger run.  */
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code))
+				continue;
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				continue;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) {
+#ifdef DBG_do_signal
+			printk("Signal IGNORED\n");
+#endif
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+#ifdef DBG_do_signal
+			printk("Signal DEFAULT, signum : %d\n", (int)signr);
+#endif
+
+			/* Init gets no signals it doesn't want.  */
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD: case SIGWINCH:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP:
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+					notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGABRT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, &regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				sig_exit(signr, exit_code, &info);
+				/* NOTREACHED */
+			} /* end of switch */
+		} /* end of if SIG_DFL */
+
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(signr, ka, &info, oldset, regs);
+		return 1;
+	}
+
+#define L    regs.L
+#define FL   regs.FL
+#define SYSCALL_RETURN_VALUE	L[FL-1]
+#define SYSCALL_RETURN_PC		L[FL]
+
+#ifdef DBG_do_signal
+	printk("L[FL+3] : 0x%x(%d)\n", (int)L[FL+3], (int)L[FL+3] );
+#endif
+	/* Ok, in our case we don not have negative values for the
+	 * interrupts and the exceptions, rather for the sys-calls
+	 * the L[FL+3] will contain the value 14 if we came from a 
+	 * system-call
+	 */
+
+	/* Do we come from a system call? */
+	if ( L[FL+3] == 14 ) {
+		/* If so, check system call restarting.. */
+		switch ( SYSCALL_RETURN_VALUE ) {
+			/* No handler is specified here... */
+			case -ERESTARTNOHAND:
+				SYSCALL_RETURN_PC -= 2;
+				break;
+			case -ERESTARTSYS:
+				if (!(ka->sa.sa_flags & SA_RESTART)) {
+					SYSCALL_RETURN_VALUE = -EINTR;
+					break;
+				}
+			/* fallthrough */
+			case -ERESTARTNOINTR:
+				SYSCALL_RETURN_PC -= 2;
+		}
+	}
+#undef SYSCALL_RETURN_VALUE
+#undef SYSCALL_RETURN_PC
+#undef L
+#undef FL
+
+	return 0;
+}
+
+/* sys_rt_sigaction is defined in <kernel/signal.c> */
+
+asmlinkage int
+sys_sigaction(int sig, const struct sigaction *act,
+						     struct sigaction *oact)
+{
+    struct k_sigaction new_ka, old_ka;
+    int ret;
+
+    if (act) {
+        if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+            get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+            get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+            return -EFAULT;
+        get_user(new_ka.sa.sa_flags, &act->sa_flags);
+        get_user(new_ka.sa.sa_mask.sig[0], &act->sa_mask.sig[0]);
+        get_user(new_ka.sa.sa_mask.sig[1], &act->sa_mask.sig[1]);
+    }
+
+    ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+    if (!ret && oact) {
+        if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+            put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+            put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+            return -EFAULT;
+        put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+        put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask.sig[0]);
+        put_user(old_ka.sa.sa_mask.sig[1], &oact->sa_mask.sig[1]);
+    }
+
+    return ret;
+}
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ *
+ * sys_sigsuspend built having in ming the following library implementation
+ * from uClibc. sys_sigsuspend is not currently used sys_rt_sigsuspend is
+ * used instead.
+ *
+ *	_syscall3(int, __sigsuspend, int, a, unsigned long int, b, unsigned long int, c);
+ * int sigsuspend (const sigset_t *set)
+ * {
+ *	return __sigsuspend(0, 0, set->__val[0]);
+ * }
+ */
+asmlinkage long 
+sys_sigsuspend(struct pt_regs regs)
+{
+#define L	regs.L
+#define FL  regs.FL
+#define SYSCALL_RETURN_VALUE	L[FL-1]
+/* We don't care about the first 2 args*/
+#define _3rd_ARG  				L[FL-5]
+
+    sigset_t saveset;
+	old_sigset_t mask = _3rd_ARG;
+
+    mask &= _BLOCKABLE;
+    spin_lock_irq(&current->sigmask_lock);
+    saveset = current->blocked;
+    siginitset(&current->blocked, mask);
+    recalc_sigpending(current);
+    spin_unlock_irq(&current->sigmask_lock);
+
+    SYSCALL_RETURN_VALUE = -EINTR;
+    while (1) {
+        current->state = TASK_INTERRUPTIBLE;
+        schedule();
+    	spin_lock_irq(&current->sigmask_lock);
+    	current->blocked = saveset;
+    	spin_unlock_irq(&current->sigmask_lock);
+        if ( do_signal(regs) )
+            return -EINTR;
+    }
+#undef _3rd_ARG
+#undef SYSCALL_RETURN_VALUE
+#undef L
+#undef FL
+}
+
+asmlinkage long
+sys_rt_sigsuspend(struct pt_regs regs)
+{
+#define L	regs.L
+#define FL  regs.FL
+#define SYSCALL_RETURN_VALUE	L[FL-1]
+#define _1st_ARG  				L[FL-3]
+#define _2nd_ARG  				L[FL-4]
+    sigset_t saveset, newset;
+	sigset_t *unewset = (sigset_t *)_1st_ARG;
+	size_t sigsetsize = (size_t)_2nd_ARG;
+
+    if (sigsetsize != sizeof(sigset_t))
+        return -EINVAL;
+
+    if (copy_from_user(&newset, unewset, sizeof(sigset_t)))
+        return -EFAULT;
+
+    sigdelsetmask(&newset, ~_BLOCKABLE);
+    spin_lock_irq(&current->sigmask_lock);
+    saveset = current->blocked;
+    current->blocked = newset;
+    recalc_sigpending(current);
+    spin_unlock_irq(&current->sigmask_lock);
+
+    SYSCALL_RETURN_VALUE = -EINTR;
+    while (1) {
+        current->state = TASK_INTERRUPTIBLE;
+        schedule();
+    	spin_lock_irq(&current->sigmask_lock);
+    	current->blocked = saveset;
+    	spin_unlock_irq(&current->sigmask_lock);
+        if (do_signal(regs))
+            return -EINTR;
+    }
+#undef _1st_ARG
+#undef _2nd_ARG
+#undef SYSCALL_RETURN_VALUE
+#undef FL
+#undef L
+}
+
+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) { return 0;}
diff -urN linux-2.4.29/arch/e1nommu/kernel/sys_e1.c linux-2.4.29-uc1/arch/e1nommu/kernel/sys_e1.c
--- linux-2.4.29/arch/e1nommu/kernel/sys_e1.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/kernel/sys_e1.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,350 @@
+/*  Copyright (C) 2002-2003,    George Thanos <george.thanos@gdt.gr>
+ *				Yannis Mitsos <yannis.mitsos@gdt.gr>
+ *
+ * linux/arch/e1nommu/kernel/sys_hyperstone.c
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/ipc.h>
+#include <asm/syscalls.h>
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+asmlinkage int sys_pipe(unsigned long * fildes)
+{
+	int fd[2];
+	int error;
+
+	error = do_pipe(fd);
+	if (!error) {
+		if (copy_to_user(fildes, fd, 2*sizeof(int)))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+/* common code for old and new mmaps */
+static inline long do_mmap2(
+	unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	int error = -EBADF;
+	struct file * file = NULL;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (!(flags & MAP_ANONYMOUS)) {
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
+/*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
+ * handle more than 4 system call parameters, so these system calls
+ * used a memory block for parameter passing..
+ */
+//#define DBG_old_mmap
+asmlinkage int sys_old_mmap(struct mmap_arg_struct *arg)
+{
+	struct mmap_arg_struct a;
+	int error = -EFAULT;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		goto out;
+#ifdef DBG_old_mmap
+	printk("old_mmap..\n"
+		   "addr  : 0x%x, len : 0x%x, prot : 0x%x\n"
+		   "flags : 0x%x, fd  : 0x%x, offset : 0x%x\n",
+			a.addr, a.len, a.prot, a.flags, a.fd, a.offset );
+#endif
+
+	error = -EINVAL;
+	if (a.offset & ~PAGE_MASK)
+		goto out;
+
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+#ifdef DBG_old_mmap
+	printk("old_mmap do_mmap2 ret_val : %d\n", error);
+#endif
+out:
+	return error;
+}
+
+#if 0 /* DAVIDM - do we want this */
+struct mmap_arg_struct64 {
+	__u32 addr;
+	__u32 len;
+	__u32 prot;
+	__u32 flags;
+	__u64 offset; /* 64 bits */
+	__u32 fd;
+};
+
+asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
+{
+	int error = -EFAULT;
+	struct file * file = NULL;
+	struct mmap_arg_struct64 a;
+	unsigned long pgoff;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+
+	if ((long)a.offset & ~PAGE_MASK)
+		return -EINVAL;
+
+	pgoff = a.offset >> PAGE_SHIFT;
+	if ((a.offset >> PAGE_SHIFT) != pgoff)
+		return -EINVAL;
+
+	if (!(a.flags & MAP_ANONYMOUS)) {
+		error = -EBADF;
+		file = fget(a.fd);
+		if (!file)
+			goto out;
+	}
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+#endif
+
+asmlinkage long sys_old_select(struct sel_arg_struct *arg)
+{
+	struct sel_arg_struct a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+	/* sys_select() does the appropriate kernel locking */
+	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
+}
+
+/* Originally derived from MIPS. Added exclusive access
+ * to system_utsname through uts_sem. */
+asmlinkage long sys_olduname(struct old_utsname * name)
+{
+	int error;
+
+	if (!name)
+		return -EFAULT;
+	if (!access_ok(VERIFY_WRITE,name,sizeof(struct old_utsname)))
+		return -EFAULT;
+
+	down_read(&uts_sem);
+	
+	error = __copy_to_user(&name->sysname,&system_utsname.sysname,__NEW_UTS_LEN);
+	error -= __put_user(0,name->sysname+__NEW_UTS_LEN);
+	error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__NEW_UTS_LEN);
+	error -= __put_user(0,name->nodename+__NEW_UTS_LEN);
+	error -= __copy_to_user(&name->release,&system_utsname.release,__NEW_UTS_LEN);
+	error -= __put_user(0,name->release+__NEW_UTS_LEN);
+	error -= __copy_to_user(&name->version,&system_utsname.version,__NEW_UTS_LEN);
+	error -= __put_user(0,name->version+__NEW_UTS_LEN);
+	error -= __copy_to_user(&name->machine,&system_utsname.machine,__NEW_UTS_LEN);
+	error = __put_user(0,name->machine+__NEW_UTS_LEN);
+	error =	error ? -EFAULT : 0;
+
+	up_read(&uts_sem);
+
+	return error;
+}
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+asmlinkage long sys_ipc (uint call, int first, int second,
+			int third, void *ptr, long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	if (call <= SEMCTL)
+		switch (call) {
+		case SEMOP:
+			return sys_semop (first, (struct sembuf *)ptr, second);
+		case SEMGET:
+			return sys_semget (first, second, third);
+		case SEMCTL: {
+			union semun fourth;
+			if (!ptr)
+				return -EINVAL;
+			if (get_user(fourth.__pad, (void **) ptr))
+				return -EFAULT;
+			return sys_semctl (first, second, third, fourth);
+			}
+		default:
+			return -EINVAL;
+		}
+	if (call <= MSGCTL) 
+		switch (call) {
+		case MSGSND:
+			return sys_msgsnd (first, (struct msgbuf *) ptr, 
+					  second, third);
+		case MSGRCV:
+			switch (version) {
+			case 0: {
+				struct ipc_kludge tmp;
+				if (!ptr)
+					return -EINVAL;
+				if (copy_from_user (&tmp,
+						    (struct ipc_kludge *)ptr,
+						    sizeof (tmp)))
+					return -EFAULT;
+				return sys_msgrcv (first, tmp.msgp, second,
+						   tmp.msgtyp, third);
+				}
+			default:
+				return sys_msgrcv (first,
+						   (struct msgbuf *) ptr,
+						   second, fifth, third);
+			}
+		case MSGGET:
+			return sys_msgget ((key_t) first, second);
+		case MSGCTL:
+			return sys_msgctl (first, second,
+					   (struct msqid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+	if (call <= SHMCTL) 
+		switch (call) {
+		case SHMAT:
+			switch (version) {
+			default: {
+				ulong raddr;
+				ret = sys_shmat (first, (char *) ptr,
+						 second, &raddr);
+				if (ret)
+					return ret;
+				return put_user (raddr, (ulong *) third);
+			}
+			}
+		case SHMDT: 
+			return sys_shmdt ((char *)ptr);
+		case SHMGET:
+			return sys_shmget (first, second, third);
+		case SHMCTL:
+			return sys_shmctl (first, second,
+					   (struct shmid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+
+	return -EINVAL;
+}
+
+asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
+{
+  return -ENOSYS;
+}
+
+/*
+ * Old cruft
+ */
+asmlinkage int sys_pause(void)
+{
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	return -ERESTARTNOHAND;
+}
+
+/* The following system call is added for the hyperstone
+ * architecture in order Non-local exits to be feasible in the library.
+ */
+//#define DBG_sys_e1newSP
+asmlinkage long sys_e1newSP( unsigned long SavedSP)
+{	
+	unsigned long *G9, tmpSR, tmpSP;
+	struct {
+		unsigned long FP;
+		unsigned long FL;
+	} SR;
+
+#ifdef DBG_sys_e1newSP
+	printk("Entered sys_e1newSP\n");
+	printk("SavedSP : 0x%x\n", (int)SavedSP );
+#endif
+	asm volatile("mov %0, G9"
+		     :"=l"(G9)
+		     :/*no input*/ );
+
+#define ReturnSP	G9[-7] 
+#define ReturnSR	G9[-6] 
+#define UserFL		G9[-10]
+	/* We assign a frame length of 15 reg for longjmp
+	 * It is big big enough...*/
+#define longjmpFL	15
+
+	/* Construct ReturnSP */
+	tmpSR  = ReturnSR;
+	/* We want to maintain the FP info in the SR */
+	tmpSR &= 0x00007f00;
+/*1.FL*/SR.FL = longjmpFL; SR.FL <<= 21; tmpSR |= SR.FL;
+/*2.FP*/SR.FP = SavedSP; SR.FP &= 0x000001fc;
+        SR.FP <<= 23; tmpSR |= SR.FP;
+	ReturnSR = tmpSR;
+
+	/* Construct ReturnSR */
+	tmpSP = SavedSP;
+	tmpSP += longjmpFL<<2;
+	ReturnSP = tmpSP;
+#ifdef DBG_sys_e1newSP
+	printk("ReturnSR : 0x%x, ReturnSP : 0x%x\n", (int)ReturnSR, (int)ReturnSP );
+#endif
+
+	return 0;
+
+#undef  longjmpFL
+#undef  UserFL
+#undef  ReturnSP
+#undef  ReturnSP
+}
+
diff -urN linux-2.4.29/arch/e1nommu/kernel/time.c linux-2.4.29-uc1/arch/e1nommu/kernel/time.c
--- linux-2.4.29/arch/e1nommu/kernel/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/kernel/time.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,196 @@
+/*
+ *  linux/arch/e1nommu/kernel/time.c
+ *
+ *  Copyright (C) 2002-2003,    George Thanos <george.thanos@gdt.gr>
+ *				Yannis Mitsos <yannis.mitsos@gdt.gr>
+ *
+ *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ * 
+ *  This file contains the e1-specific time handling details.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+
+#include <asm/machdep.h>
+#include <asm/io.h>
+
+#include <linux/timex.h>
+
+
+static inline int set_rtc_mmss(unsigned long nowtime)
+{
+  if (mach_set_clock_mmss)
+    return mach_set_clock_mmss (nowtime);
+  return -1;
+}
+
+static inline void do_profile (unsigned long pc)
+{
+#ifdef CONFIG_PROFILE /* FIXME */
+	if (prof_buffer && current->pid) {
+		extern int _stext;
+		pc -= (unsigned long) &_stext;
+		pc >>= prof_shift;
+		if (pc < prof_len)
+			++prof_buffer[pc];
+		else
+		/*
+		 * Don't ignore out-of-bounds PC values silently,
+		 * put them into the last histogram slot, so if
+		 * present, they will show up as a sharp peak.
+		 */
+			++prof_buffer[prof_len-1];
+	}
+#endif
+}
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+#define DEBUG_TIMER 0 
+#if DEBUG_TIMER
+unsigned long in_timer_interrupt =0;
+#endif
+void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
+{
+	/* last time the cmos clock got updated */
+	static long last_rtc_update=0;
+
+#if DEBUG_TIMER
+	in_timer_interrupt++;
+
+	if( !(in_timer_interrupt % 500) ) {
+		printk("timer_interrupt: %d\n", in_timer_interrupt);
+#if 0
+#define  L   regs->L
+#define  FL  regs->FL
+	{ int i;
+	  printk("Interrupted Task:");
+	  for( i=0 ; i<FL; i++) {
+		  printk("L[%d] : 0x%08x,%s",i,L[i], (i%3)?" ":"\n");
+	  }
+	  printk("\nSaved PC: 0x%08x\n",L[FL] );
+	  printk("Exception Entry: %d\n",L[FL+3] );
+	}
+
+#undef   FL
+#undef   L
+#endif
+	}
+#endif
+	
+	/* may need to kick the hardware timer */
+	/* We have already called BSP tick
+	if (mach_tick)
+	  mach_tick();
+	*/
+
+	do_timer(regs);
+
+#ifdef CONFIG_PROFILE /* FIXME */
+	if (!user_mode(regs))
+		do_profile(regs->pc);
+#endif
+
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
+	    xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
+	  if (set_rtc_mmss(xtime.tv_sec) == 0)
+	    last_rtc_update = xtime.tv_sec;
+	  else
+	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	}
+}
+
+void time_init(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+
+	extern void arch_gettod(int *year, int *mon, int *day, int *hour,
+				int *min, int *sec);
+
+	/* FIX by dqg : Set to zero for platforms that don't have tod */
+	/* without this time is undefined and can overflow time_t, causing  */
+	/* very stange errors */
+	year = 1980;
+	mon = day = 1;
+	hour = min = sec = 0;
+	arch_gettod (&year, &mon, &day, &hour, &min, &sec);
+
+	if ((year += 1900) < 1970)
+		year += 100;
+	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+	xtime.tv_usec = 0;
+
+	mach_sched_init(timer_interrupt);
+}
+
+extern rwlock_t xtime_lock;
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+/* FIXME
+	extern volatile unsigned long wall_jiffies;
+*/
+	unsigned long flags;
+	unsigned long usec, sec, lost;
+
+	read_lock_irqsave(&xtime_lock, flags);
+	usec = mach_gettimeoffset ? mach_gettimeoffset() : 0;
+/* FIXME
+	lost = jiffies - wall_jiffies;
+	if (lost)
+		usec += lost * (1000000/HZ);
+*/
+	sec = xtime.tv_sec;
+	usec += xtime.tv_usec;
+	read_unlock_irqrestore(&xtime_lock, flags);
+
+	while (usec >= 1000000) {
+		usec -= 1000000;
+		sec++;
+	}
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	write_lock_irq(&xtime_lock);
+	/* This is revolting. We need to set the xtime.tv_usec
+	 * correctly. However, the value in this location is
+	 * is value at the last tick.
+	 * Discover what correction gettimeofday
+	 * would have done, and then undo it!
+	 */
+	if (mach_gettimeoffset)
+		tv->tv_usec -= mach_gettimeoffset();
+
+	while (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+
+	xtime = *tv;
+	time_adjust = 0;		/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+	write_unlock_irq(&xtime_lock);
+}
diff -urN linux-2.4.29/arch/e1nommu/kernel/traps.c linux-2.4.29-uc1/arch/e1nommu/kernel/traps.c
--- linux-2.4.29/arch/e1nommu/kernel/traps.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/kernel/traps.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,104 @@
+/*
+ *  linux/arch/hyperstone-nommu/kernel/traps.c
+ *
+ *  Copyright (C) 2002-2003,    George Thanos <george.thanos@gdt.gr>
+ *                              Yannis Mitsos <yannis.mitsos@gdt.gr>
+ */
+#include <asm/ptrace.h>
+#include <asm/signal.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+
+void die_if_kernel (char *str, struct pt_regs *regs, int nr)
+{
+	if(user_mode(regs))
+		return;
+
+	do_exit(SIGSEGV);
+}
+
+/* FP exception number entries */
+#define FCVTD   1
+#define FCVT    2
+#define FCMPUD  3
+#define FCMPU   4
+#define FCMPD   5
+#define FCMP    6
+#define FDIVD   7
+#define FDIV    8
+#define FMULD   9
+#define FMUL    10
+#define FSUBD   11
+#define FSUB    12
+#define FADDD   13
+#define FADD    14
+
+void Exception58_Entry(void);
+void Exception59_Entry(void);
+void Exception60_Entry(void);
+void Exception63_Entry(void);
+void ExceptionFP_Entry(void);
+
+void ExceptionFCVTD_Entry(void);
+void ExceptionFCVT_Entry(void);
+void ExceptionFCMPUD_Entry(void);
+void ExceptionFCMPU_Entry(void);
+void ExceptionFCMPD_Entry(void);
+void ExceptionFCMP_Entry(void);
+void ExceptionFDIVD_Entry(void);
+void ExceptionFDIV_Entry(void);
+void ExceptionFMULD_Entry(void);
+void ExceptionFMUL_Entry(void);
+void ExceptionFSUBD_Entry(void);
+void ExceptionFSUB_Entry(void);
+void ExceptionFADDD_Entry(void);
+void ExceptionFADD_Entry(void);
+
+/* Set an entry in the Trap Entry Table.
+ * Entries are mapped in the beggining of
+ * memory area MEM0.
+ */
+void MEM0_set_exception(int num, void *handler)
+{
+	unsigned long *exception_ptr = (unsigned long *)((long)0x000000FC - 4*num);
+	*exception_ptr = *((unsigned long*)handler);
+}
+
+void MEM0_set_fp_exception(int num, void *handler)
+{
+	unsigned long *exception_ptr = (unsigned long *)((long)0x0000011C + 0x10*num);
+	*exception_ptr = *((unsigned long*)handler);
+}
+
+void trap_init(void) 
+{ 
+        /*Regular Exceptions*/
+        /* 57. Trace exception is allocated by GDB */
+        MEM0_set_exception( 58, Exception58_Entry );
+        MEM0_set_exception( 59, Exception59_Entry );
+        MEM0_set_exception( 60, Exception60_Entry );
+
+	/* Set the FP exception */
+        MEM0_set_exception( 46, ExceptionFP_Entry );
+
+	/* Floating Point Exceptions */
+
+	MEM0_set_fp_exception( FCVTD , ExceptionFCVTD_Entry );
+	MEM0_set_fp_exception( FCVT  , ExceptionFCVT_Entry );
+	MEM0_set_fp_exception( FCMPUD, ExceptionFCMPUD_Entry );
+	MEM0_set_fp_exception( FCMPU,  ExceptionFCMPU_Entry );
+	MEM0_set_fp_exception( FCMPD,  ExceptionFCMPD_Entry );
+	MEM0_set_fp_exception( FCMP,   ExceptionFCMP_Entry );
+	MEM0_set_fp_exception( FDIVD,  ExceptionFDIVD_Entry );
+	MEM0_set_fp_exception( FDIV,   ExceptionFDIV_Entry );
+	MEM0_set_fp_exception( FMULD,  ExceptionFMULD_Entry );
+	MEM0_set_fp_exception( FMUL,   ExceptionFMUL_Entry );
+	MEM0_set_fp_exception( FSUBD,  ExceptionFSUBD_Entry );
+	MEM0_set_fp_exception( FSUB,   ExceptionFSUB_Entry );
+	MEM0_set_fp_exception( FADDD,  ExceptionFADDD_Entry );
+	MEM0_set_fp_exception( FADD,   ExceptionFADD_Entry );
+}
+
+void show_trace_task(struct task_struct *tsk) { }
+
diff -urN linux-2.4.29/arch/e1nommu/lib/checksum.c linux-2.4.29-uc1/arch/e1nommu/lib/checksum.c
--- linux-2.4.29/arch/e1nommu/lib/checksum.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/lib/checksum.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,156 @@
+/*  Yannis Mitsos <yannis.mitsos@gdt.gr> :
+ *  Derived from the m68k-nommu implementation. 
+ *
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		IP/TCP/UDP checksumming routines
+ *
+ * Authors:	Jorge Cwik, <jorge@laser.satlink.net>
+ *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ *		Tom May, <ftom@netcom.com>
+ *		Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
+ *		Lots of code moved from tcp.c and ip.c; see those files
+ *		for more names.
+ *
+ * 03/02/96	Jes Sorensen, Andreas Schwab, Roman Hodek:
+ *		Fixed some nasty bugs, causing some horrible crashes.
+ *		A: At some points, the sum (%0) was used as
+ *		length-counter instead of the length counter
+ *		(%1). Thanks to Roman Hodek for pointing this out.
+ *		B: GCC seems to mess up if one uses too many
+ *		data-registers to hold input values and one tries to
+ *		specify d0 and d1 as scratch registers. Letting gcc choose these
+ *      registers itself solves the problem.
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+
+#include <net/checksum.h>
+#include <asm/checksum.h>
+
+static inline unsigned short from32to16(unsigned long x)
+{
+	/* add up 16-bit and 16-bit for 16+c bit */
+	x = (x & 0xffff) + (x >> 16);
+	/* add up carry.. */
+	x = (x & 0xffff) + (x >> 16);
+	return x;
+}
+
+static unsigned long do_csum(const unsigned char * buff, int len)
+{
+	int odd, count;
+	unsigned long result = 0;
+
+	if (len <= 0)
+		goto out;
+	odd = 1 & (unsigned long) buff;
+	if (odd) {
+		result = *buff;
+		len--;
+		buff++;
+	}
+	count = len >> 1;		/* nr of 16-bit words.. */
+	if (count) {
+		if (2 & (unsigned long) buff) {
+			result += *(unsigned short *) buff;
+			count--;
+			len -= 2;
+			buff += 2;
+		}
+		count >>= 1;		/* nr of 32-bit words.. */
+		if (count) {
+		        unsigned long carry = 0;
+			do {
+				unsigned long w = *(unsigned long *) buff;
+				count--;
+				buff += 4;
+				result += carry;
+				result += w;
+				carry = (w > result);
+			} while (count);
+			result += carry;
+			result = (result & 0xffff) + (result >> 16);
+		}
+		if (len & 2) {
+			result += *(unsigned short *) buff;
+			buff += 2;
+		}
+	}
+	if (len & 1)
+		result += (*buff << 8);
+	result = from32to16(result);
+	if (odd)
+		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+	return result;
+}
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ */
+unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
+{
+	return ~do_csum(iph,ihl*4);
+}
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
+{
+	unsigned int result = do_csum(buff, len);
+
+	/* add in old sum, and carry.. */
+	result += sum;
+	if (sum > result)
+		result += 1;
+	return result;
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+unsigned short ip_compute_csum(const unsigned char * buff, int len)
+{
+	return ~do_csum(buff,len);
+}
+
+/*
+ * copy from fs while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy_from_user(const char *src, char *dst, int len, unsigned int sum, int *csum_err)
+{
+	if (csum_err) *csum_err = 0;
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
+
+/*
+ * copy from ds while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy(const char *src, char *dst, int len, unsigned int sum)
+{
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
diff -urN linux-2.4.29/arch/e1nommu/lib/delay.c linux-2.4.29-uc1/arch/e1nommu/lib/delay.c
--- linux-2.4.29/arch/e1nommu/lib/delay.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/lib/delay.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,60 @@
+/*
+ *  arch/e1nommu/lib/delay.c
+ *
+ *  Copyrights: (C) 2002 GDT,  George Thanos<george.thanos@gdt.gr>
+ *  			       Yannis Mitsos<yannis.mitsos@gdt.gr>
+ *
+ *  Derived from the S390 version
+ *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+
+void __delay(unsigned long loops)
+{
+		int tmp=1;
+        /*
+         * To end the bloody studid and useless discussion about the
+         * BogoMips number I took the liberty to define the __delay
+         * function in a way that that resulting BogoMips number will
+         * yield the megahertz number of the cpu. The important function
+         * is udelay and that is done using the tod clock. -- martin.
+         */
+	asm volatile("p0:
+					dbne p0 
+					sub %1, %0"
+					:  /* no outputs */
+					: "l" (tmp), "l" (loops) );
+}
+
+extern unsigned long f;
+
+/*
+ * Waits for 'usecs' microseconds
+ * FIXME I consoder that the Prescelar is set to 10MHz.
+ */
+void __udelay(unsigned long usecs)
+{
+	long start_cc, end_cc;
+
+	if (usecs == 0)
+		return;
+		
+	asm volatile ("
+					ORI SR, 0x20
+					MOV %0, TR" 
+					: "=l" (start_cc)
+					: /* no inputs */);
+
+	do {
+		asm volatile ("
+						ORI SR, 0x20
+						MOV %0, TR" 
+						: "=l" (end_cc)
+						: /* no inputs */);
+	} while (((end_cc - start_cc)) < (usecs*10));
+}
+
diff -urN linux-2.4.29/arch/e1nommu/lib/Makefile linux-2.4.29-uc1/arch/e1nommu/lib/Makefile
--- linux-2.4.29/arch/e1nommu/lib/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/lib/Makefile	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,11 @@
+#
+# arch/e1nommu/lib/Makefile
+#
+
+.S.o:
+	$(CC) $(AFLAGS) -D__ASSEMBLY__ -c -o $@ $<
+
+L_TARGET := lib.a
+obj-y    := memchr.o memcmp.o memcpy.o memset.o strcmp.o strcpy.o checksum.o delay.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/e1nommu/lib/memchr.S linux-2.4.29-uc1/arch/e1nommu/lib/memchr.S
--- linux-2.4.29/arch/e1nommu/lib/memchr.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/lib/memchr.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ * Derived from the Hyperstone's library source code.
+ * Modefied src in order to apply the -mgnu-param compiler option.
+ * Copyright (C) 2002-2003 GDT, Yannis Mitsos <yannis.mitsos@gdt.gr>
+ * 				George Thanos <george.thanos@gdt.gr>
+ */
+	    .text
+	    .align   2
+	    .global  _memchr
+
+;ENTRY(_memchr)
+_memchr:
+	frame L6, L3
+	andni L1, 0xFFFFFF00
+	cmpi L0, 0
+	be L_10
+	ldbu.n L2, L5, 1
+L_12:
+	cmp  L5, L1
+	be L_15
+	addi L0, -1
+	dbne L_12
+	ldbu.n L2, L5, 1
+L_10:
+	movi L2, 0
+	ret PC, L3
+L_15:
+	addi L2, -1
+	ret PC, L3
+	.end
diff -urN linux-2.4.29/arch/e1nommu/lib/memcmp.S linux-2.4.29-uc1/arch/e1nommu/lib/memcmp.S
--- linux-2.4.29/arch/e1nommu/lib/memcmp.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/lib/memcmp.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,54 @@
+/*
+ * Derived from the Hyperstone's library source code.
+ * Modefied src in order to apply the -mgnu-param compiler option.
+ * Copyright (C) 2002-2003 GDT, Yannis Mitsos <yannis.mitsos@gdt.gr>
+ *                              George Thanos <george.thanos@gdt.gr>
+ */
+	    .text
+	    .align   2
+	    .global  _memcmp
+
+;ENTRY (_memcmp)
+_memcmp:
+	    FRAME    L9, L3                 # get incoming parameters
+	    CMPBI    L2,3                   # check word alignment
+	    BNZ      byte_compare
+	    CMPBI    L1,3                   # check word alignment
+	    BNZ      byte_compare
+
+double_compare:
+	    ADDI     L0, -8
+	    BLT      is_equal
+	    LDD.P    L1, L5
+	    LDD.P    L2, L7
+	    SUB      L5, L7
+	    DBNZ     corr_8
+	    SUB      L6, L8
+	    BZ       double_compare
+	    ADDI     L0, 4
+	    ADDI     L2, -4
+	    ADDI     L1, -4
+	    BR       byte_compare
+
+corr_8:     ADDI     L0, 8
+	    ADDI     L2, -8
+	    ADDI     L1, -8
+byte_compare:
+	    ADDI     L0, -1
+	    BLT      equal
+	    LDBU.N   L2, L5, 1              # Load and compare bytes
+	    LDBU.N   L1, L6, 1
+	    SUB      L5, L6
+	    BZ       byte_compare
+	    MOV      L2, L5
+	    RET      PC, L3
+
+is_equal:   CMPI     L0, -8
+	    DBNE     byte_compare
+	    ADDI     L0, 8
+equal:
+	    MOVI     L2, 0
+	    RET      PC, L3
+
+	    .END
+
diff -urN linux-2.4.29/arch/e1nommu/lib/memcpy.S linux-2.4.29-uc1/arch/e1nommu/lib/memcpy.S
--- linux-2.4.29/arch/e1nommu/lib/memcpy.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/lib/memcpy.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,79 @@
+/*
+ * Derived from the Hyperstone's library source code.
+ * Modefied src in order to apply the -mgnu-param compiler option.
+ * Copyright (C) 2002-2003 GDT, Yannis Mitsos <yannis.mitsos@gdt.gr>
+ *                              George Thanos <george.thanos@gdt.gr>
+ */
+	    .text
+	    .align   2
+	    .global  _memcpy
+;ENTRY(_memcpy)
+_memcpy:
+	    FRAME    L8, L3
+	    MOV      L7, L2                 # Save for return
+
+#*****************************
+# Perform byte copy if both
+# not on a word alignment
+#*****************************
+	    CMPBI    L2, 3                  # check word alignment
+            BNZ      mem_except
+	    CMPBI    L1, 3                  # check word alignment
+            BNZ      mem_except
+
+#*****************************
+# Copy Double,Word,Halfword,
+# then byte
+#*****************************
+DBL_LOOP:
+	    CMPI     L0, 8                  # Copy Doubles
+            BLT      DO_WORD
+            LDD.P    L1, L5
+            ADDI     L0, -8
+            DBR      DBL_LOOP
+            STD.P    L2, L5
+
+DO_WORD:
+	   CMPI      L0, 4                  # Copy leftover word
+           BLT       DO_HALF
+	   LDW.P     L1, L5
+           ADDI      L0, -4
+	   DBZ       DONE                   # Done if L0 is 0
+           STW.P     L2, L5
+
+DO_HALF:
+	   CMPI      L0, 2                  # Copy leftover byte
+           BLT       DO_BYTE
+           LDHU.N    L1, L5, 2
+           ADDI      L0, -2
+	   DBZ       DONE                   # Done if L0 is 0
+           STHU.N    L2, L5, 2
+
+DO_BYTE:
+	   CMPI      L0, 1                  # Copy leftover byte
+           BLT       DONE
+           LDBU.D    L1, L5, 0
+           STBU.D    L2, L5, 0
+
+DONE:                                       # Copy done
+	   MOV       L2, L7                 # Return pointer
+           RET       PC, L3
+
+#****************************
+# Byte memcpy
+#****************************
+mem_except:
+           DBR       L_5
+           MOVI      L6,0
+L_3:
+	   LDBS.D    L1, L5, 0              # Transfer the byte
+           ADDI      L6, 1
+           STBS.D    L2, L5, 0
+           ADDI      L2, 1
+           ADDI      L1, 1
+L_5:                                        # Loop test
+           CMP       L6, L0
+	   BST       L_3
+	   MOV       L2, L7                 # Return pointer
+	   RET       PC, L3
+	   .END
diff -urN linux-2.4.29/arch/e1nommu/lib/memset.S linux-2.4.29-uc1/arch/e1nommu/lib/memset.S
--- linux-2.4.29/arch/e1nommu/lib/memset.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/lib/memset.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+ * Derived from the Hyperstone's library source code.
+ * Modefied src in order to apply the -mgnu-param compiler option.
+ * Copyright (C) 2002-2003 GDT, Yannis Mitsos <yannis.mitsos@gdt.gr>
+ *                              George Thanos <george.thanos@gdt.gr>
+ */
+	    .text
+	    .align   2
+		.global _memset
+
+;ENTRY(_memset)
+_memset:    FRAME    L9, L3
+	    MASK     L5, L1, 0xFF
+	    MOV      L8, L2
+	    CMPI     L0, 0                  # if n = 0 then return
+            BE       retour
+
+loop0:      CMPBI    L8, 0x3
+	    BZ       word_bound
+	    ADDI     L0, -1
+	    DBNZ     loop0
+	    STBU.N   L8, L5, 1
+retour:     RET      PC, L3
+
+word_bound:
+	    CMPI     L0, 8
+	    DBLT     loop2
+	    MOV      L7, L5
+	    SHLI     L7, 8
+            OR       L5, L7
+            MOV      L7, L5
+            SHLI     L7, 16
+            OR       L5, L7
+            MOV      L6, L5
+loop1:      ADDI     L0, -8
+            CMPI     L0, 8
+            DBGE     loop1
+	    STD.P    L8, L5
+            CMPI     L0, 0
+            DBNZ     loop2
+	    ANDNI    L5, ~ 0xFF
+	    RET      PC, L3
+
+loop2:      ADDI     L0, -1
+	    DBNZ     loop2
+	    STBU.N   L8, L5, 1
+	    RET      PC, L3
diff -urN linux-2.4.29/arch/e1nommu/lib/strcmp.S linux-2.4.29-uc1/arch/e1nommu/lib/strcmp.S
--- linux-2.4.29/arch/e1nommu/lib/strcmp.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/lib/strcmp.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,76 @@
+/*
+ * Derived from the Hyperstone's library source code.
+ * Modefied src in order to apply the -mgnu-param compiler option.
+ * Copyright (C) 2002-2003 GDT, Yannis Mitsos <yannis.mitsos@gdt.gr>
+ *                              George Thanos <george.thanos@gdt.gr>
+ */
+            .text
+	    .align   2
+	    .global  _strcmp
+;ENTRY(_strcmp)
+_strcmp:
+	    FRAME    L8,L2
+	    CMPBI    L1, 3        # check for word alignment
+	    BNZ      str_except
+	    CMPBI    L0, 3        # check for word alignment
+	    BNZ      str_except
+
+start:
+	    LDD.P    L1, L4       # post inc mode
+	    LDD.P    L0, L6       # post inc mode
+            CMPBI    L4, ANYBZ
+            BE       correct1
+            CMP      L4, L6
+            BNE      correct1
+            CMP      L5, L7
+            BNE      correct
+            CMPBI    L5, ANYBZ
+            BE       correct
+            CMPBI    L6, ANYBZ
+            BE       correct1
+            CMPBI    L7, ANYBZ
+            BNE      start
+
+correct:    MASK     L4, L5, 0xff000000
+	    MASK     L6, L7, 0xff000000
+            CMP      L4, L6
+            BNE      Exit
+            SHLI     L5, 8
+            CMPI     L4, 0
+            DBNE     correct
+            SHLI     L7, 8
+            MOV      L1, L4
+            RET      PC, L2
+
+Exit:       SUB      L4, L6       # Subtract chars
+            SARI     L4, 24
+            MOV      L1, L4
+            RET      PC, L2
+
+correct1:   MASK     L5, L4, 0xff000000
+	    MASK     L7, L6, 0xff000000
+            CMP      L5, L7
+            BNE      Exit1
+            SHLI     L4, 8
+            CMPI     L5, 0
+            DBNE     correct1
+            SHLI     L6, 8
+            MOV      L1, L5
+            RET      PC, L2
+Exit1:      SUB      L5, L7       # Subtract chars
+            SARI     L5, 24
+            MOV      L1, L5
+            RET      PC, L2
+
+testzero:   CMPI     L4, 0
+            BE       L_5
+str_except:
+	    LDBU.N   L1, L4, 1    # Load *s1, compare bytes
+	    LDBU.N   L0, L5, 1    # Load *s2, compare bytes
+            CMP      L4, L5
+	    BE       testzero
+	    SUB      L4, L5       # Subtract chars
+L_5:        MOV      L1, L4
+	    RET      PC, L2
+	    .END
+
diff -urN linux-2.4.29/arch/e1nommu/lib/strcpy.S linux-2.4.29-uc1/arch/e1nommu/lib/strcpy.S
--- linux-2.4.29/arch/e1nommu/lib/strcpy.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/lib/strcpy.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,94 @@
+/*
+ * Derived from the Hyperstone's library source code.
+ * Modefied src in order to apply the -mgnu-param compiler option.
+ * Copyright (C) 2002-2003 GDT, Yannis Mitsos <yannis.mitsos@gdt.gr>
+ *                              George Thanos <george.thanos@gdt.gr>
+ */
+	    .text
+	    .align   2
+	    .global  _strcpy
+;ENTRY(_strcpy)
+_strcpy:
+	FRAME	L9,L2
+
+#*********************************
+# Perform byte copy if both not
+# aligned on a word
+#*********************************
+	CMPBI	L1,3		# check word alignment
+	BNZ	str_except
+	CMPBI	L0,3		# check word alignment
+	BNZ	str_except
+
+
+	MOV	L4,L0		# load s2 into L4
+	MOV	L0,L1		# load s1 into L0
+	BR	start
+
+loop:
+	BE	label_3	
+	STD.P	L0,L7		# post inc
+	
+start:
+	LDD.P	L4,L5		# post inc
+	LDD.P	L4,L7		# post inc
+	CMPBI	L5,ANYBZ	# test for null
+	BE	label_1		
+	CMPBI	L6,ANYBZ	# test for null
+	BE	label_2		
+	STD.P	L0,L5		# post inc
+	CMPBI	L7,ANYBZ	# test for null
+	DBNE	loop		
+	CMPBI	L8,ANYBZ	# test for null
+	DBR	label_4
+	MOV 	L8,L7		# move to L8
+
+label_1:			# move L5 to L8
+	DBR	label_4
+	MOV	L8,L5
+
+label_2:			# store L5, move L6
+	STW.P	L0,L5		# post inc
+	DBR	label_4
+	MOV	L8,L6
+
+label_3:			# store L7
+	FETCH	16
+	STW.P	L0,L7		# post inc
+
+label_4:			# locate null
+	CMPBI	L8,0xFF000000	# 1st byte
+	BZ	ret_1
+	CMPBI	L8,0xFF0000	# 2nd byte
+	BZ	ret_2
+	CMPBI	L8,0xFF00	# 3rd byte
+	BNZ	ret_3
+
+	SHRI	L8,16		# store 2-bytes
+	STHU.N	L0,L8,2		# half word, next address
+
+ret_1:
+	STBU.D	L0,0,0		# store null
+	RET	PC,L2
+
+ret_2:
+	SHRI	L8,16		# store 2 bytes, includes null
+	STHU.D	L0,L8,0
+	RET	PC,L2
+
+ret_3:  
+	STW.R	L0,L8		# store entire word, includes nullstr1_except:
+	RET	PC,L2
+
+#******************************
+# Byte strcpy
+#******************************
+str_except:
+	MOV	L5,L1		# Save the pointer
+L_4:
+	LDBU.N	L0,L4,1		# Copy a byte, exit if NULL
+	STBU.N	L5,L4,1
+	CMPI	L4,0
+	BNE	L_4
+	RET	PC,L2
+	.END
diff -urN linux-2.4.29/arch/e1nommu/Makefile linux-2.4.29-uc1/arch/e1nommu/Makefile
--- linux-2.4.29/arch/e1nommu/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/Makefile	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,49 @@
+#
+# e1nommu/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 1998-2003  D. Jeff Dionne <jeff@uClinux.org>,
+# Copyright (C) 1998,1999  Kenneth Albanowski <kjahds@kjahds.com>,
+#
+# Based on arch/m68knommu/Makefile:
+# Copyright (C) 1994 by Hamish Macdonald
+#
+
+# test for cross compiling
+COMPILE_ARCH = $(shell uname -m)
+
+UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\"
+
+# Find out which board we are compiling for
+include arch/$(ARCH)/Boards.mk
+
+# Set up the memory model.  RAM or ROM.
+ifdef CONFIG_RAMKERNEL
+MODEL = ram
+else
+MODEL = rom
+endif
+export MODEL
+
+# get the compiler, flags and targets from the platform
+ifdef PLATFORM
+include arch/$(ARCH)/platform/$(PLATFORM)/Rules.make
+endif
+
+arch/$(ARCH)/empty.o:
+	$(CROSS_COMPILE)gcc -o arch/$(ARCH)/empty.o -c arch/$(ARCH)/empty.c
+
+bootstrap:
+	@$(MAKEBOOT) bootstrap
+
+archmrproper:
+
+archdep:
diff -urN linux-2.4.29/arch/e1nommu/mm/fault.c linux-2.4.29-uc1/arch/e1nommu/mm/fault.c
--- linux-2.4.29/arch/e1nommu/mm/fault.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/mm/fault.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,63 @@
+/*
+ *  linux/arch/e1nommu/mm/fault.c
+ *
+ *  Derived from <linux/arch/m68knommu/mm/fault.c>
+ *  Copyright (C) 2002-2003 GDT, Yannis Mitsos <yannis.mitsos@gdt.gr>
+ *  			     	 George Thanos <george.thanos@gdt.gr>
+ *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com) 
+ *  Copyright (C) 1998-2003  D. Jeff Dionne <jeff@uClinux.org>,
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68k/mm/fault.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ */
+
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+
+extern void die_if_kernel(char *, struct pt_regs *, long);
+
+/*
+ * This routine handles page faults.  It determines the problem, and
+ * then passes it off to one of the appropriate routines.
+ *
+ * error_code:
+ *	bit 0 == 0 means no page found, 1 means protection fault
+ *	bit 1 == 0 means read, 1 means write
+ *
+ * If this routine detects a bad access, it returns 1, otherwise it
+ * returns 0.
+ */
+asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
+			      unsigned long error_code)
+{
+#ifdef DEBUG
+		/* FIXME */
+/*	printk ("regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n",
+		regs->sr, regs->pc, address, error_code);
+		*/
+		printk("BUG in  mm/fault.c\n");
+#endif
+
+/*
+ * Oops. The kernel tried to access some bad page. We'll have to
+ * terminate things with extreme prejudice.
+ */
+	if ((unsigned long) address < PAGE_SIZE) {
+		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
+	} else
+		printk(KERN_ALERT "Unable to handle kernel access");
+	printk(" at virtual address %08lx\n",address);
+	die_if_kernel("Oops", regs, error_code);
+	do_exit(SIGKILL);
+
+	return 1;
+}
+
diff -urN linux-2.4.29/arch/e1nommu/mm/init.c linux-2.4.29-uc1/arch/e1nommu/mm/init.c
--- linux-2.4.29/arch/e1nommu/mm/init.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/mm/init.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,268 @@
+/*
+ *  Derived from <linux/arch/m68knommu/mm/init.c>
+ *  Copyright (C) 2002-2003 GDT, Yannis Mitsos <yannis.mitsos@gdt.gr>
+ *                           	 George Thanos <george.thanos@gdt.gr>
+ *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com) 
+ *  Copyright (C) 1998-2003 D. Jeff Dionne <jeff@uClinux.org>,
+ *  Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>,
+ */
+
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#ifdef CONFIG_BLK_DEV_RAM
+#include <linux/blk.h>
+#endif
+#include <linux/bootmem.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/machdep.h>
+/* #include <asm/shglcore.h> */
+#include <asm/virtconvert.h>
+
+#undef DEBUG
+
+static unsigned long totalram_pages = 0;
+
+extern void die_if_kernel(char *,struct pt_regs *,long);
+
+extern void free_initmem(void);
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+static unsigned long empty_bad_page_table;
+
+static unsigned long empty_bad_page;
+
+unsigned long empty_zero_page;
+
+extern unsigned long rom_length;
+
+void show_mem(void)
+{
+    unsigned long i;
+    int free = 0, total = 0, reserved = 0, shared = 0;
+    int cached = 0;
+
+    printk("\nMem-info:\n");
+    show_free_areas();
+#if 0
+    printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+#endif
+    i = max_mapnr;
+    while (i-- > 0) {
+	total++;
+	if (PageReserved(mem_map+i))
+	    reserved++;
+	else if (PageSwapCache(mem_map+i))
+	    cached++;
+	else if (!page_count(mem_map+i))
+	    free++;
+	else
+	    shared += page_count(mem_map+i) - 1;
+    }
+    printk("%d pages of RAM\n",total);
+    printk("%d free pages\n",free);
+    printk("%d reserved pages\n",reserved);
+    printk("%d pages shared\n",shared);
+    printk("%d pages swap cached\n",cached);
+#if 0
+    printk("%ld pages in page table cache\n",pgtable_cache_size);
+#endif
+    show_buffers();
+}
+
+extern unsigned long memory_start;
+extern unsigned long memory_end;
+
+/*
+ * paging_init() continues the virtual memory environment setup which
+ * was begun by the code in arch/head.S.
+ * The parameters are pointers to where to stick the starting and ending
+ * addresses  of available kernel virtual memory.
+ */
+void paging_init(void)
+{
+	/*
+	 * make sure start_mem is page aligned,  otherwise bootmem and
+	 * page_alloc get different views og the world
+	 */
+#ifdef DEBUG
+	unsigned long start_mem = PAGE_ALIGN(memory_start);
+#endif
+	unsigned long end_mem   = memory_end & PAGE_MASK;
+
+#ifdef DEBUG
+	printk ("start_mem is %#lx\nvirtual_end is %#lx\n",
+		start_mem, end_mem);
+#endif
+
+	/*
+	 * initialize the bad page table and bad page to point
+	 * to a couple of allocated pages
+	 */
+	empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	memset((void *)empty_zero_page, 0, PAGE_SIZE);
+
+	/*
+	 * Set up SFC/DFC registers (user data space)
+	 */
+	set_fs (USER_DS);
+
+#ifdef DEBUG
+	printk ("before free_area_init\n");
+
+	printk ("free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n",
+		start_mem, end_mem);
+#endif
+
+	{
+		unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+
+		zones_size[ZONE_DMA]     = 0 >> PAGE_SHIFT;
+		zones_size[ZONE_NORMAL]  = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
+#ifdef CONFIG_HIGHMEM
+		zones_size[ZONE_HIGHMEM] = 0;
+#endif
+		free_area_init_node(0, NULL, NULL, zones_size, PAGE_OFFSET, NULL);
+	}
+}
+
+void mem_init(void)
+{
+	int codek = 0, datak = 0, initk = 0;
+	/* DAVIDM look at setup memory map generically with reserved area */
+	unsigned long tmp;
+#ifdef CONFIG_UCLINUX
+	extern char _etext, _stext, _sdata, _ebss, __init_begin, __init_end;
+	extern unsigned int _ramend, _rambase;
+	unsigned long len = _ramend - _rambase;
+#else
+	extern char _etext, _romvec, __data_start;
+	unsigned long len = end_mem-(unsigned long)&__data_start;
+	int datapages = 0;
+#endif
+	unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */
+	unsigned long end_mem   = memory_end; /* DAVIDM - this must not include kernel stack at top */
+
+#ifdef DEBUG
+	printk("Mem_init: start=%lx, end=%lx\n", start_mem, end_mem);
+#endif
+
+	end_mem &= PAGE_MASK;
+	high_memory = (void *) end_mem;
+
+	start_mem = PAGE_ALIGN(start_mem);
+	max_mapnr = num_physpages = MAP_NR(high_memory);
+
+	/* this will put all memory onto the freelists */
+	totalram_pages = free_all_bootmem();
+
+#ifdef CONFIG_UCLINUX
+	codek = (&_etext - &_stext) >> 10;
+	datak = (&_ebss - &_sdata) >> 10;
+	initk = (&__init_begin - &__init_end) >> 10;
+#else
+	for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
+		if (PageReserved(mem_map+MAP_NR(tmp))) {
+			datapages++;
+			continue;
+		}
+	}
+	
+	codek = (&_etext - &_romvec) >> 10;
+	datak = datapages << (PAGE_SHIFT-10);
+	initk = 0;
+#endif
+
+	tmp = nr_free_pages() << PAGE_SHIFT;
+	printk("Memory available: %luk/%luk RAM, %luk/%luk ROM (%dk kernel code, %dk data)\n",
+	       tmp >> 10,
+	       len >> 10,
+	       (rom_length > 0) ? ((rom_length >> 10) - codek) : 0,
+	       rom_length >> 10,
+	       codek,
+	       datak
+	       );
+}
+
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	int pages = 0;
+	for (; start < end; start += PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(start));
+		set_page_count(virt_to_page(start), 1);
+		free_page(start);
+		totalram_pages++;
+		pages++;
+	}
+	printk ("Freeing initrd memory: %dk freed\n", pages);
+}
+#endif
+
+
+void si_meminfo(struct sysinfo *val)
+{
+    unsigned long i;
+
+    i = max_mapnr;
+    val->totalram = totalram_pages;
+    val->sharedram = 0;
+    val->freeram = nr_free_pages();
+    val->bufferram = atomic_read(&buffermem_pages);
+    val->totalhigh = 0;
+    val->freehigh = 0;
+    val->mem_unit = PAGE_SIZE;
+    return;
+}
+
+
+void
+free_initmem()
+{
+#ifdef CONFIG_RAMKERNEL
+	unsigned long addr;
+	extern char __init_begin, __init_end;
+/*
+ *	the following code should be cool even if these sections
+ *	are not page aligned.
+ */
+	addr = PAGE_ALIGN((unsigned long)(&__init_begin));
+	/* next to check that the page we free is not a partial page */
+	for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(addr));
+		set_page_count(virt_to_page(addr), 1);
+		free_page(addr);
+		totalram_pages++;
+	}
+	printk("Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n",
+			(addr - PAGE_ALIGN((long) &__init_begin)) >> 10,
+			PAGE_ALIGN((unsigned long)(&__init_begin)),
+			addr - PAGE_SIZE);
+#endif
+}
+
diff -urN linux-2.4.29/arch/e1nommu/mm/kmap.c linux-2.4.29-uc1/arch/e1nommu/mm/kmap.c
--- linux-2.4.29/arch/e1nommu/mm/kmap.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/mm/kmap.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,60 @@
+/*
+ * linux/arch/e1nommu/mm/kmap.c
+ *
+ * Derived from <linux/arch/m68knommu/mm/kmap.c>
+ * Copyright (C) 2002-2003 GDT, Yannis Mitsos <yannis.mitsos@gdt.gr>
+ *                          	George Thanos <george.thanos@gdt.gr>
+ *
+ * Copyright (C) 2000 Lineo, <davidm@lineo.com>
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#undef DEBUG
+
+/*
+ * Map some physical address range into the kernel address space.
+ */
+
+void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
+{
+	return (void *)physaddr;
+}
+
+/*
+ * Unmap a ioremap()ed region again
+ */
+void iounmap(void *addr)
+{
+}
+
+/*
+ * __iounmap unmaps nearly everything, so be careful
+ * it doesn't free currently pointer/page tables anymore but it
+ * wans't used anyway and might be added later.
+ */
+void __iounmap(void *addr, unsigned long size)
+{
+}
+
+/*
+ * Set new cache mode for some kernel address space.
+ * The caller must push data for that range itself, if such data may already
+ * be in the cache.
+ */
+void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
+{
+}
diff -urN linux-2.4.29/arch/e1nommu/mm/Makefile linux-2.4.29-uc1/arch/e1nommu/mm/Makefile
--- linux-2.4.29/arch/e1nommu/mm/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/mm/Makefile	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,13 @@
+#
+# Makefile for the linux Hyperstone-specific parts of the memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET := mm.o
+obj-y    := init.o fault.o kmap.o memory.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/e1nommu/mm/memory.c linux-2.4.29-uc1/arch/e1nommu/mm/memory.c
--- linux-2.4.29/arch/e1nommu/mm/memory.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/mm/memory.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,161 @@
+/*
+ *  linux/arch/e1nommu/mm/memory.c
+ *
+ *  Derived from <linux/arch/m68knommu/mm/memory.c>
+ *  Copyright (C) 2002-2003 GDT, Yannis Mitsos <yannis.mitsos@gdt.gr>
+ *                           	 George Thanos <george.thanos@gdt.gr>
+ *  Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+/* #include <asm/traps.h>    */
+/* #include <asm/shglcore.h> */
+#include <asm/virtconvert.h>
+
+#ifndef NO_MM
+
+#error "!NO_MM NOT PORTED"
+/* check m68knommu/mm/memory.c */
+
+#else /* !NO_MM */
+
+/*
+ * 040: Hit every page containing an address in the range paddr..paddr+len-1.
+ * (Low order bits of the ea of a CINVP/CPUSHP are "don't care"s).
+ * Hit every page until there is a page or less to go. Hit the next page,
+ * and the one after that if the range hits it.
+ */
+/* ++roman: A little bit more care is required here: The CINVP instruction
+ * invalidates cache entries WITHOUT WRITING DIRTY DATA BACK! So the beginning
+ * and the end of the region must be treated differently if they are not
+ * exactly at the beginning or end of a page boundary. Else, maybe too much
+ * data becomes invalidated and thus lost forever. CPUSHP does what we need:
+ * it invalidates the page after pushing dirty data to memory. (Thanks to Jes
+ * for discovering the problem!)
+ */
+/* ... but on the '060, CPUSH doesn't invalidate (for us, since we have set
+ * the DPI bit in the CACR; would it cause problems with temporarily changing
+ * this?). So we have to push first and then additionally to invalidate.
+ */
+
+/*
+ * cache_clear() semantics: Clear any cache entries for the area in question,
+ * without writing back dirty entries first. This is useful if the data will
+ * be overwritten anyway, e.g. by DMA to memory. The range is defined by a
+ * _physical_ address.
+ */
+
+void cache_clear (unsigned long paddr, int len)
+{
+}
+
+/*
+ *	Define cache invalidate functions. The ColdFire 5407 is really
+ *	the only processor that needs to do some work here. Anything
+ *	that has separate data and instruction caches will be a problem.
+ */
+#ifdef CONFIG_E132XS
+
+static __inline__ void cache_invalidate_lines(unsigned long paddr, int len)
+{
+		printk("Inside cache_invalidate_lines \n");
+		idle();
+		/* FIXME
+	unsigned long	sset, eset;
+
+	sset = (paddr & 0x00000ff0);
+	eset = ((paddr + len) & 0x0000ff0) + 0x10;
+
+	__asm__ __volatile__ (
+		"nop\n\t"
+		"clrl	%%d0\n\t"
+		"1:\n\t"
+		"movel	%0,%%a0\n\t"
+		"addl	%%d0,%%a0\n\t"
+		"2:\n\t"
+		".word	0xf4e8\n\t"
+		"addl	#0x10,%%a0\n\t"
+		"cmpl	%1,%%a0\n\t"
+		"blt	2b\n\t"
+		"addql	#1,%%d0\n\t"
+		"cmpil	#4,%%d0\n\t"
+		"bne	1b"
+		: : "a" (sset), "a" (eset) : "d0", "a0" );
+		*/
+}
+
+#else
+#define	cache_invalidate_lines(a,b)
+#endif /*  CONFIG_E132XS */
+
+
+/*
+ * cache_push() semantics: Write back any dirty cache data in the given area,
+ * and invalidate the range in the instruction cache. It needs not (but may)
+ * invalidate those entries also in the data cache. The range is defined by a
+ * _physical_ address.
+ */
+
+void cache_push (unsigned long paddr, int len)
+{
+	cache_invalidate_lines(paddr, len);
+}
+
+
+/*
+ * cache_push_v() semantics: Write back any dirty cache data in the given
+ * area, and invalidate those entries at least in the instruction cache. This
+ * is intended to be used after data has been written that can be executed as
+ * code later. The range is defined by a _user_mode_ _virtual_ address  (or,
+ * more exactly, the space is defined by the %sfc/%dfc register.)
+ */
+
+void cache_push_v (unsigned long vaddr, int len)
+{
+	cache_invalidate_lines(vaddr, len);
+}
+
+/* Map some physical address range into the kernel address space. The
+ * code is copied and adapted from map_chunk().
+ */
+
+unsigned long kernel_map(unsigned long paddr, unsigned long size,
+			 int nocacheflag, unsigned long *memavailp )
+{
+	return paddr;
+}
+
+
+#ifdef MAGIC_ROM_PTR
+
+
+int is_in_rom(unsigned long addr)
+{
+
+extern int _ramstart, _ramend;
+
+#ifdef CONFIG_E132XS
+	if ((addr < _ramstart) && (addr >= _ramend))
+		return(1);
+#else
+#error "check is_in_rom()"
+#endif
+
+
+	return(0); /* default case, not in ROM */
+}
+
+#endif /* MAGIC_ROM_PTR */
+
+#endif /* NO_MM */
diff -urN linux-2.4.29/arch/e1nommu/platform/E132XS/config.c linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/config.c
--- linux-2.4.29/arch/e1nommu/platform/E132XS/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/config.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,241 @@
+/*
+ * linux/arch/e1nommu/platform/E132XS/config.c
+ *
+ * Copyright (C) 2002-2003 GDT,  Yannis Mitsos<yannis.mitsos@gdt.gr>
+ *                               George Thanos<george.thanos@gdt.gr>
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/sched.h> /* for request_irq FIXME. Later we should change according to m68knommu implementation*/
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+
+extern void st16550_serial_init(void);
+extern void st16550_serial_set(unsigned long baud);
+
+unsigned long fExt_Osc = CONFIG_HYPERSTONE_OSC_FREQ_MHZ; 	/* default assumption */
+
+/* Since the FCR register is write only currently we do not
+ * have any mean to know what was the initial value. Later we shall 
+ * consider applying the same methodology  as the HyRTK using a segment
+ * where all the write only registers are stored. Until then we initialize
+ * the FCR in our own way.
+ */
+
+/* The TPR register is configured in such way that the internal clock is 
+ * XTAL1 * 8 and the Timer prescaler is set to 0xA, so the precision of 
+ * the interanl timer is 10MHz. 
+ */
+extern void timer_interrupt(int irq, void *dummy, struct pt_regs * regs);
+
+static struct irqaction irq8  = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
+
+void BSP_sched_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile long TPR_value, TCR_value;
+	signed int ClockDivider[5] = {3, 2, 1, 0, -1};
+	int return_value;
+	TPR_value = 0x000a0000;
+	
+	TCR_value = (CONFIG_HYPERSTONE_OSC_FREQ_MHZ << ClockDivider[(0x7 & (TPR_value >> 26))]);  
+	TCR_value = TCR_value / ((0xff &(TPR_value >> 16))+2);
+	TCR_value = (TCR_value * 1000000 ) / 100;   
+	
+#ifdef DEBUG
+	printk("BSP_sched_init: Frequency of external Oscillator = %lu MHz, computed TCR value %lu ticks\n", fExt_Osc ,TCR_value);
+#endif
+
+  /* setup irq handler before enabling the timer 
+   * We cannot use the request_irq since the kmalloc
+   * is not functioning at this time. So, we set the timer interrupt
+   * by allocating an irqaction in our own */
+	
+	return_value = setup_irq(IRQ_TIMER ,&irq8);
+	if (return_value){
+		printk("Request for the Timer's IRQ failed!\n");
+		mach_halt();
+	}
+
+	update_sh_reg(TPR_reg, TPR_value);
+
+	asm volatile (" 
+				FETCH   4	
+				ORI		SR, 0x20
+				MOVI	TR, 0x0
+				ORI		SR, 0x20
+				MOV		TCR, %1"
+				: /* no outputs */
+				: "l" (TPR_value), "l" (TCR_value)
+				); 
+
+	update_sh_reg_bit(FCR_reg, 23, 0); /* Enable the timer's interrupt */
+}
+
+
+void BSP_tick(void)
+{
+  /* FIXME Reset Timer by adding a constant value to the TCR. Should we change
+   * it later to calculete the value according to the FCR ? */
+		
+	static unsigned long TCR_reload;
+
+	asm volatile(
+			"FETCH 4\n\t"
+			"ORI SR, 0x20\n\t"
+			"MOV %0, TR\n\t"
+			"ADDI %0, 0x186A0\n\t"    // 10ms
+//			"ADDI %0, 0xF4240\n\t"    // 100ms
+//			"ADDI %0, 0x989680\n\t"  // 1 sec
+//			"ADDI %0, 0x1312D00\n\t"  // 2 sec
+//			"ADDI %0, 0x0BEBC200\n\t" // 20 sec
+//			"ADDI %0, 0x1fffffff\n\t" // 20 sec
+			"ORI SR, 0x20\n\t"
+			"MOV TCR, %0\n\t"
+			: "=l" (TCR_reload) 
+			: "0" (TCR_reload) 
+			);	
+	
+}
+
+unsigned long BSP_gettimeoffset (void)
+{
+  return 0;
+}
+
+void BSP_gettod (int *yearp, int *monp, int *dayp,
+		   int *hourp, int *minp, int *secp)
+{
+	*yearp = *monp = *dayp = *hourp = *minp = *secp = 0;
+}
+
+int BSP_set_clock_mmss (unsigned long nowtime)
+{
+  return 0;
+}
+
+void BSP_reset (void)
+{
+	cli();
+/* FIXME */
+	mach_halt();
+
+}
+
+/* The following function copies the values of the Write-only registers
+ * from the location addressed via the G10. We should change it later
+ * if we would like to boot directly from flash without the help of the 
+ * ROM stub. (Yannis-FIXME) 
+ */
+
+shadow_regs_t system_regs;
+shadow_regs_t *system_sh_regs; 
+
+static void	BSP_copy_regs(void)
+{
+volatile unsigned long *base_addr;
+unsigned char i;
+	
+	system_sh_regs = &system_regs;
+
+	asm volatile("mov %0, G10"
+					:"=l" (base_addr)
+					:);
+	for(i=0; i < 9; i++)
+		memcpy((unsigned long *) system_sh_regs+i,(unsigned long *) base_addr+i, sizeof(*base_addr));
+}
+
+unsigned int io_periph[NR_CS];
+
+void BSP_init_periphs(void)
+{
+	int i;
+
+	for(i=0; i<NR_CS; i++){
+		io_periph[i]= (SLOW_IO_ACCESS | i << 22);
+	}
+#ifdef CONFIG_HYPERSTONE_CS89X0
+	io_periph[4] = (io_periph[4] | 1 << IOWait);
+	/* In the Evaluation Board the Interrupt line for the Ethernet is active low. 
+	 * So, we modify accordingly the FCR register */
+	update_sh_reg(FCR_reg, 0x66ffFFFF);
+#endif
+
+#ifdef CONFIG_SERIAL_CONSOLE
+	update_sh_reg_bit(FCR_reg, 25, 0);
+	update_sh_reg_bit(FCR_reg, 29, 0);
+#endif
+}
+
+#ifdef CONFIG_EMBEDDED_SERIAL_CONSOLE 
+extern void st16550_serial_init(void);
+extern void st16550_setup_console(void);
+extern void st16550_serial_set(unsigned long baud);
+#endif
+
+void config_BSP(char *command, int len)
+{
+
+	memset(command, 0, len);
+
+#ifdef CONFIG_HYPERSTONE_CS89X0
+	strcat(command, "ip=" 
+#ifdef CONFIG_IP_PNP_DHCP || CONFIG_IP_PNP_BOOTP
+	":"
+#else
+	CONFIG_E132XS_BOARD_NET_BOARD_IP ":"
+#endif 
+	":" CONFIG_E132XS_BOARD_NET_DEFAULTGW ":" 
+    CONFIG_E132XS_BOARD_NET_NETMASK ":" CONFIG_E132XS_BOARD_NET_HOSTNAME ":eth0:"
+#ifdef CONFIG_IP_PNP_DHCP || CONFIG_IP_PNP_BOOTP
+	"bootp ");
+#else
+	"off ");
+#endif 
+#endif
+
+#ifdef CONFIG_ROOT_NFS
+	strcat(command, "root=/dev/nfs rw nfsroot=" CONFIG_E132XS_BOARD_NET_NFS_ROOT " ");
+#endif
+
+#ifdef CONFIG_EXTRA_ARGS
+	strcat(command, CONFIG_EXTRA_ARGS_VARIABLES);
+#endif
+
+	printk("\nE1-32XS evaluation board support (C) 2002 George Thanos and Yannis Mitsos.\n");
+
+	BSP_copy_regs();
+
+#ifdef CONFIG_EXTERNAL_DEVICES
+	BSP_init_periphs();
+#endif
+
+#ifdef CONFIG_EMBEDDED_SERIAL_CONSOLE
+	st16550_serial_init();
+	st16550_serial_set(115200);
+	st16550_setup_console();
+#endif
+
+  mach_sched_init      = BSP_sched_init;
+  mach_tick            = BSP_tick; 
+  mach_gettimeoffset   = BSP_gettimeoffset;
+  mach_gettod          = BSP_gettod;
+//  mach_hwclk           = NULL;
+  mach_set_clock_mmss  = NULL;
+  mach_reset           = BSP_reset;
+  mach_trap_init       = NULL;
+ // mach_debug_init      = NULL;
+ 
+}
diff -urN linux-2.4.29/arch/e1nommu/platform/E132XS/E132XS_BOARD/crt0_ram_noromfs.S linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/E132XS_BOARD/crt0_ram_noromfs.S
--- linux-2.4.29/arch/e1nommu/platform/E132XS/E132XS_BOARD/crt0_ram_noromfs.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/E132XS_BOARD/crt0_ram_noromfs.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,119 @@
+/*
+ * Initially derived from Hyperstone's E1 processor initialization
+ * and modified accordingly.
+ *
+ * Copyright (C) 2002-2003 GDT, George Thanos <george.thanos@gdt.gr>
+ * 			        Yannis Mitsos <yannis.mitsos@gdt.gr>
+ * Copyright (C) March 2002 Hyperstone AG
+ */
+
+.macro  _STH
+        ori   SR, 0x20
+.endm
+
+.global	__rambase
+.global	__ramstart
+.global	__ramend
+	.data
+	.balign	4
+__rambase:
+		  .long	 0
+__ramstart:
+		  .long  0
+__ramend:
+		  .long  0
+	.balign	16 
+
+.global __init_reg_stack
+
+	.global	Priority	; Task-Priority
+	.global	_Stack1Size	; Size of hardware stack
+	.global	_Stack2Size	; Size of aggregate stack
+	.global	_Stack1Base	; Base of hardware stack
+	.global	_Stack2Base	; Base of aggregate stack
+	.global	_Mem0HeapBase	; Base of Heap in Mem0
+	.global	_Mem1HeapBase	; Base of Heap in Mem1
+
+//	.global	_main
+	.global	Main
+
+	.text
+BasePtrs:
+	.weak	G6Base,G7Base,G8Base,G9Base,G10Base,G11Base,G12Base,G13Base
+	.long	G6Base,G7Base,G8Base,G9Base,G10Base,G11Base,G12Base,G13Base
+BasePtrsEnd:
+
+;============================================================================;
+; Startup-Code                                                               ;
+;============================================================================;
+	.text
+Main:
+//StartUp:
+_main:
+_start:
+	frame	L8, L0
+	mov L1, SR
+	movi	L2, __bss_start	; clear the .bss segment
+0:	cmpi	L2, __bss_end
+	bhe	0f
+	dbr	0b
+	stw.p	L2, 0
+0:	sum     L2, PC, BasePtrs-$	; Load BasePtrs G6-G13
+
+	ldd.p   L2, G6			; Zero G6-G13
+	ldd.p   L2, G8
+	ldw.p   L2, G11
+	ldd.p   L2, G12
+
+_linux_kernel_startup_initialization:
+	# load _rambase, _ramstart, _ramend
+	movi	L1, __rambase
+	movi	L2, __sdata
+	stw.n	L1, L2, 4
+	movi	L2, __end
+	stw.n	L1, L2, 4
+	movi	L2, ___ramend
+	stw.n	L1, L2, 4
+	# load _current_task
+	movi	L1, __current_task
+	movi	L2, _init_task_union
+	stw.r	L1, L2
+
+
+# Aggregate Stack for Init Task
+	movi    G9, _init_task_union
+	sum	G9, G9, 0x2000
+	mov 	G3, G9
+	mov     G4, G9
+	sum	G5, G9, -0x2000		; 2 * PAGE_SIZE
+
+# Register Stack for Init Task
+	movi	G11, __Init_Register_Stack_
+	_STH
+	movi	SP, __Init_Register_Stack_        # SP
+	movi    L2, __Init_Register_Stack_
+	addi    L2, 0x2000
+	_STH
+	mov	UB, L2				  # UB
+	mov	L1, SR
+	andni	L1, 0xffe00000 # Clear FP, FL
+	ori	L1, 0x00400000 # Set FL=2
+	movi	L2, __Init_Register_Stack_        # SP
+	andni	L2, 0xfffffe03 # Get FP (bits 2..8) from SP
+	shli	L2, 23         # Shift left by 23 to match SRs FP
+	or	L1, L2         # Get the new FP to saved SR
+	movi	L0, __init_reg_stack
+	ori     L0, 0x1
+	ret	PC, L0
+
+__init_reg_stack:
+	call	L2, 0, _start_kernel
+
+	.section _GOT_
+	.long   _start+4		; OnCreate
+	.long   _start+8		; OnError
+	.long   BasePtrs	; G6
+	.long   BasePtrs+4	; G7
+	.long   BasePtrs+8	; G8
+	
+	.END
diff -urN linux-2.4.29/arch/e1nommu/platform/E132XS/E132XS_BOARD/crt0_ram.S linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/E132XS_BOARD/crt0_ram.S
--- linux-2.4.29/arch/e1nommu/platform/E132XS/E132XS_BOARD/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/E132XS_BOARD/crt0_ram.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,180 @@
+/*
+ * Initially derived from Hyperstone's E1 processor initialization
+ * and modified accordingly.
+ *
+ * Copyright (C) 2002-2003 GDT, George Thanos <george.thanos@gdt.gr>
+ * 			        Yannis Mitsos <yannis.mitsos@gdt.gr>
+ * Copyright (C) March 2002 Hyperstone AG
+ */
+
+.macro  _STH
+        ori   SR, 0x20
+.endm
+
+.global	__rambase
+.global	__ramstart
+.global	__ramend
+
+.global	__romfs_size
+
+.data
+.balign	4
+__rambase:
+	.long	 0
+__ramstart:
+	.long  0	
+__ramend:
+	.long  0
+__romfs_size:
+	.long	0
+
+.balign	16 
+
+.global __init_reg_stack
+
+	.global	Priority	; Task-Priority
+	.global	_Stack1Size	; Size of hardware stack
+	.global	_Stack2Size	; Size of aggregate stack
+	.global	_Stack1Base	; Base of hardware stack
+	.global	_Stack2Base	; Base of aggregate stack
+	.global	_Mem0HeapBase	; Base of Heap in Mem0
+	.global	_Mem1HeapBase	; Base of Heap in Mem1
+
+	.global	Main
+
+	.text
+BasePtrs:
+	.weak	G6Base,G7Base,G8Base,G9Base,G10Base,G11Base,G12Base,G13Base
+	.long	G6Base,G7Base,G8Base,G9Base,G10Base,G11Base,G12Base,G13Base
+BasePtrsEnd:
+
+;============================================================================;
+; Startup-Code                                                               ;
+;============================================================================;
+	.text
+Main:
+_main:
+_start:
+	frame	L8, L0
+	mov 	L1, SR
+
+	/*
+	* Move ROM filesystem above bss :-)
+	* The ROMFS when created is appended 
+	* at the beginning of the bss segment
+	* This is happening since the bss is 
+	* a NON-LOAD segment and the objcopy
+	* places the .romfs segment at the first 
+	* empty slot after the data :-(
+	*/
+	movi	L2, __bss_start ; Get the start of the .bss
+	movi	L3, __bss_end	; Get the end of the .bss
+
+	/* Check if we have ROMFS at the end of the bss section */
+	ldw.d	L2, L4, 0x0		; Get the ROMFS size
+	cmpi	L4, 0x2d726f6d
+	bnz _no_romfs
+	ldw.d	L2, L4, 0x4		; Get the ROMFS size
+	cmpi	L4, 0x3166732d
+	bnz _no_romfs
+
+	/* it seems that we have a valid ROMFS at the bss */
+	ldw.d	L2, L4, 0x8		; Get the ROMFS size
+	addi	L4, 0x4			; We are going to copy dwords so we
+							; have to round accordingly
+	andni	L4, 0x00000003
+	
+	stw.a	0, L4, __romfs_size
+
+	add		L3, L4			; Find the end where ROMFS should reside
+	add		L2, L4			; Find the end where ROMFS resides !	
+
+	stw.a	0, L3, __ramstart ; Set start of ram
+
+_copy_romfs:
+	cmpi	L4, 0x0
+	bn		_clear_bss
+	ldw.n	L2, L5, -4
+	addi	L4, -4
+	dbr		_copy_romfs
+	stw.n	L3, L5, -4
+	br		_clear_bss
+
+_no_romfs:
+	movi 	L4, 0
+	stw.a	0, L4, __romfs_size
+	stw.a	0, L3, __ramstart 
+
+_clear_bss:
+	movi	L2, __bss_start	; clear the .bss segment
+0:	cmpi	L2, __bss_end
+	bhe	0f
+	dbr	0b
+	stw.p	L2, 0
+0:	sum     L2, PC, BasePtrs-$	; Load BasePtrs G6-G13
+
+	ldd.p   L2, G6			; Zero G6-G13
+	ldd.p   L2, G8
+	ldw.p   L2, G11
+	ldd.p   L2, G12
+
+_linux_kernel_startup_initialization:
+	# load _rambase, _ramstart, _ramend
+	stw.a	0, L3, __rambase ; The base address of the SDRAM
+	movi	L1, __ramend
+	movi	L2, ___ramend
+	stw.r	L1, L2
+
+#if 0
+	movi	L1, __rambase
+	movi	L2, __sdata
+	stw.n	L1, L2, 4
+	movi	L2, __end
+	stw.n	L1, L2, 4
+	movi	L2, ___ramend
+	stw.n	L1, L2, 4
+#endif
+
+	# load _current_task
+	movi	L1, __current_task
+	movi	L2, _init_task_union
+	stw.r	L1, L2
+
+
+# Aggregate Stack for Init Task
+	movi    G9, _init_task_union
+	sum	G9, G9, 0x2000
+	mov 	G3, G9
+	mov     G4, G9
+	sum	G5, G9, -0x2000		; 2 * PAGE_SIZE
+
+# Register Stack for Init Task
+	movi	G11, __Init_Register_Stack_
+	_STH
+	movi	SP, __Init_Register_Stack_        # SP
+	movi    L2, __Init_Register_Stack_
+	addi    L2, 0x2000
+	_STH
+	mov	UB, L2				  # UB
+	mov	L1, SR
+	andni	L1, 0xffe00000 # Clear FP, FL
+	ori	L1, 0x00400000 # Set FL=2
+	movi	L2, __Init_Register_Stack_        # SP
+	andni	L2, 0xfffffe03 # Get FP (bits 2..8) from SP
+	shli	L2, 23         # Shift left by 23 to match SRs FP
+	or	L1, L2         # Get the new FP to saved SR
+	movi	L0, __init_reg_stack
+	ori     L0, 0x1
+	ret	PC, L0
+
+__init_reg_stack:
+	call	L2, 0, _start_kernel
+
+	.section _GOT_
+	.long   _start+4		; OnCreate
+	.long   _start+8		; OnError
+	.long   BasePtrs	; G6
+	.long   BasePtrs+4	; G7
+	.long   BasePtrs+8	; G8
+	
+	.END
diff -urN linux-2.4.29/arch/e1nommu/platform/E132XS/E132XS_BOARD/ram.ld linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/E132XS_BOARD/ram.ld
--- linux-2.4.29/arch/e1nommu/platform/E132XS/E132XS_BOARD/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/E132XS_BOARD/ram.ld	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,183 @@
+OUTPUT_FORMAT("coff-e1-big")
+MEMORY
+	{
+        romvec   : ORIGIN = 0x2000000,  LENGTH = 0x0000400
+        flash    : ORIGIN = 0xE0000000, LENGTH = 0x20000 
+        eflash   : ORIGIN = 0x2200000,  LENGTH = 0x20000
+        ram      : ORIGIN = 0x00000000, LENGTH = 0x1000000
+        eram16MB : ORIGIN = 0x01000000, LENGTH = 0
+        sram     : ORIGIN = 0x40000000, LENGTH = 0x40000
+		iram     : ORIGIN = 0xC0000000, LENGTH = 0x4000
+	}
+/* No Idea what are all these below !!! NEEDED */
+ENTRY(Main)
+MEM0start   = 0x00000000;
+MEM0size    = 0x40000000;
+MEM1start   = 0x40000000;
+MEM1size    = 0x40000000;
+MEM2start   = 0x80000000;
+MEM2size    = 0x40000000;
+IRAMstart   = 0xC0000000;
+IRAMsize    = 0x20000000;
+MEM3start   = 0xE0000000;
+MEM3size    = 0x20000000;
+Stack1Reserve = 560;
+_Stack1Size = DEFINED(_Stack1Size)? _Stack1Size : 1*1024;
+_Stack2Size = DEFINED(_Stack2Size)? _Stack2Size : 16*1024;
+_Stack1Base = DEFINED(_Stack1Base)? _Stack1Base : __bss_end;
+_Stack2Base = DEFINED(_Stack2Base)? _Stack2Base : __bss_end + _Stack1Size + Stack1Reserve;
+_Mem0HeapBase = DEFINED(_Mem0HeapBase)? _Mem0HeapBase : _Stack2Base + _Stack2Size;
+_Mem1HeapBase = DEFINED(_Mem1HeapBase)? _Mem1HeapBase : 0;
+Priority    = DEFINED(Priority)   ? Priority    : 31;
+TextBase    = DEFINED(TextBase)   ? TextBase    : 0x8000;
+
+SECTIONS
+{
+/*
+	{
+	_flashstart = . ;
+	_romvec = . ;
+	__rom_start = . ;
+	} > romvec
+.rom :
+        {
+        _start = . ;   
+        } > flash
+.eflash :
+	{
+	_flashend = . ; 
+	} > eflash
+.realvec :     
+	{
+	__ramvec = . ;
+	__ram_start = . ;
+        } > ramvec
+*/
+  .G6 (DEFINED(G6Base) ? G6Base : 0x9000) : {
+    *(.G6)
+  }
+  .G7 (DEFINED(G7Base) ? G7Base : 0x40001000) : {
+    *(.G7)
+  }
+  .G8 (DEFINED(G8Base) ? G8Base : 0xC0000000) : {
+    *(.G8)
+  }
+  .G9 (DEFINED(G9Base) ? G9Base : 0) : {
+    *(.G9)
+  }
+  .G10 (DEFINED(G10Base) ? G10Base : 0) : {
+    *(.G10)
+  }
+  .G11 (DEFINED(G11Base) ? G11Base : 0) : {
+    *(.G11)
+  }
+  .G12 (DEFINED(G12Base) ? G12Base : 0) : {
+    *(.G12)
+  }
+  .G13 (DEFINED(G13Base) ? G13Base : 0) : {
+    *(.G13)
+  }
+
+.text TextBase :         /* Text section */
+	{
+    __stext = . ;
+	text_start = . ;
+       	*(.text)
+		*(.text.*)
+		*(.rodata)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	___start___ex_table = .;
+		*(__ex_table)
+	___stop___ex_table = .;
+
+        ___start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	___stop___ksymtab = .;
+
+	__etext = . ;
+	___data_rom_start = ALIGN ( 4 ) ;
+    G6Size = SIZEOF(.G6);
+    G7Size = SIZEOF(.G7);
+    G8Size = SIZEOF(.G8);
+    G9Size = SIZEOF(.G9);
+    G10Size = SIZEOF(.G10);
+    G11Size = SIZEOF(.G11);
+    G12Size = SIZEOF(.G12);
+    G13Size = SIZEOF(.G13);
+
+        } > ram
+.data :
+	{ 
+	__sdata = . ;
+	__data_start = . ;
+
+        . = ALIGN(0x2000) ;
+/*        *(.data.init_task) */
+        *(.task_data)
+        . = ALIGN(0x2000) ;
+
+        . = ALIGN(0x2000) ;
+/*        *(.data.task_init) */
+        *(.tasks)
+        . = ALIGN(0x2000) ;
+
+        *(.data)
+        *(.data.*)
+        *(.setup.init)
+/*        *(.exitcal.exit) */
+        *(.exit.*) /* It should be .exitcall.exit */ 
+
+        . = ALIGN(4096) ;
+        ___init_begin = .;
+        *(.text.init)
+        *(.data.init)
+        . = ALIGN(16);
+        ___setup_start = .;
+        *(.setup.init)
+        *(.setup.*)
+        ___setup_end = .;
+        ___initcall_start = .;
+        *(.init.*) /* It should be .initcall.init */ 
+/*        *(.initcall.init) */
+        . = ALIGN(4) ;
+        ___initcall_end = .;
+        ___init_end = .;
+		*(.initrd);
+    	. = ALIGN(4096);
+	__edata = . ;
+	edata = ALIGN( 0x10 ) ;
+        } > ram
+.bss :
+        {
+	__sbss = ALIGN( 0x10 ) ;
+	__bss_start = ALIGN( 0x10 ) ;
+	___data_end = ALIGN( 0x10 ) ;
+	*(.bss)
+	*(COMMON)
+	__ebss = . ;
+	__bss_end = . ;
+	end = ALIGN( 0x10 ) ;
+	__end = ALIGN( 0x10 ) ;
+	} > ram
+
+.eram16MB :    
+	{
+	___ramend = . - 0x7000;
+	} > eram16MB
+
+  .stab  0 (NOLOAD) :
+  {
+    [ .stab ]
+  }
+  .stabstr  0 (NOLOAD) :
+  {
+    [ .stabstr ]
+  }
+
+  _GOT_  0 (NOLOAD) :
+  {
+    [ _GOT_ ]
+  }
+}
diff -urN linux-2.4.29/arch/e1nommu/platform/E132XS/entry.S linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/entry.S
--- linux-2.4.29/arch/e1nommu/platform/E132XS/entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/entry.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,712 @@
+/*
+ *  arch/e1nommu/platform/E132XS/entry.S
+ *
+ *  Copyright (C) 2002 GDT,  George Thanos<george.thanos@gdt.gr>
+ *                           Yannis Mitsos<yannis.mitsos@gdt.gr>
+ *
+ *  Each process has its own Kernel Register Stack and its own Kernel 
+ *  Aggregate Stack. In user mode each process also has a User Register 
+ *  Stack and a User Aggregate Stack. In general a process affords four(4)
+ *  stacks.
+ *  When running in User Mode and a interrupt, exception or system
+ *  call takes place, we have to switch from User Register Stack to 
+ *  Kernel Register Stack and from User Aggregate Stack to Kernel
+ *  Aggregate Stack. None of these two stack switchings are supported by h/w
+ *  thus we have to do them explicitely in s/w.
+ */
+
+#include <linux/sys.h>
+#include <asm/errno.h>
+#include <asm/stack.h>
+
+/* Clear interrupts */
+.macro  _CLI
+	ori   SR, 0x8000
+.endm
+/* Set interrupts */
+.macro  _STI
+	andni SR, 0x8000
+.endm
+/* Set H flag */
+.macro  _STH
+	ori   SR, 0x20
+.endm
+
+/* These are the h/w interrupt entries 
+ * Processor should reference these entries
+ * in the h/w trap entry table.
+ */
+.global _Common_Int_Handler
+.global _Common_Exception_Handler
+.global _Common_SysCall_Handler
+.global _ret_from_vfork
+
+_Uninitialised:
+	frame L2, L0
+	call  L2, PC, _Uninitialised_Exception_Entry
+	ret PC, L0
+
+_INT1:
+	frame L6, L0
+	movi  L3, 0               # L3 register contains the IRQ number
+	movi  PC, (long)__Exception_Common_Entry
+
+_INT2:
+	frame L6, L0
+	movi  L3, 1               # L3 register contains the IRQ number
+	movi  PC, (long)__Exception_Common_Entry
+
+_INT3:
+	frame L6, L0
+	movi  L3, 2               # L3 register coontains the IRQ number
+	movi  PC, (long)__Exception_Common_Entry
+
+_INT4:
+	frame L6, L0
+	movi  L3, 3               # L3 register contains the IRQ number
+	movi  PC, (long)__Exception_Common_Entry
+
+_IO1:
+	frame L6, L0
+	movi  L3, 4               # L3 register contains the IRQ number
+	movi  PC, (long)__Exception_Common_Entry
+
+_IO2:
+	frame L6, L0
+	movi  L3, 5               # L3 register contains the IRQ number
+	movi  PC, (long)__Exception_Common_Entry
+
+_IO3:
+	frame L6, L0
+	movi  L3, 6               # L3 register contains the IRQ number
+	movi  PC, (long)__Exception_Common_Entry
+
+_Timer:
+	frame L6, L0
+	movi  L3, 7
+	call  L6, 0, _BSP_tick
+	movi  PC, (long)__Exception_Common_Entry
+
+_SysCall:
+	frame L6, L0
+	movi  L3, 8 
+	movi  PC, (long)__Exception_Common_Entry
+
+_Exception57:
+	frame L6, L0
+	movi  L3, 9 
+	movi  PC, (long)__Exception_Common_Entry
+
+_Exception58:
+	frame L6, L0
+	movi  L3, 10
+	movi  PC, (long)__Exception_Common_Entry
+
+_Exception59:
+	frame L6, L0
+	movi  L3, 11
+	movi  PC, (long)__Exception_Common_Entry
+
+#define EXTEND_STACKS 1
+_Exception60:
+#if EXTEND_STACKS
+	_STH
+	mov L2, UB
+	addi L2, STACK_OFFSET /* We allocate a space of 16 registers  or 64 bytes */
+	_STH
+	mov UB, L2
+	addi G5, -STACK_OFFSET
+#endif
+	frame L6, L0
+	movi  L3, 12
+	movi  PC, (long)__Exception_Common_Entry
+
+_Exception63:
+	frame L6, L0
+	movi  L3, 13
+	movi  PC, (long)__Exception_Common_Entry
+
+_ExceptionFP:
+	frame L6, L0
+	movi  L3, 14
+	movi  PC, (long)__Exception_Common_Entry
+
+/*****************************************************************
+ * This is the starting point for every exception, interrupt,
+ * system call. We have assigned a frame of 6 regsiters.
+ * They are used as following : 
+ * L0 : interrupted tasks PC
+ * L1 : interrupted tasks SR
+ * L2 : Info setadr instr provides for the current frame.
+ *		Can be viewed as the current SP.
+ * L3 : IRQ Number, Exception Number, System-Call.
+ * L4 : The address that L0 register is mapped to, for the
+ *		interrupted frame. Can be viewed as the SP of the
+ * 		interrupted frame.
+ * L5 : The FL of the interrupt frame.
+ *****************************************************************/
+
+__Exception_Common_Entry:
+# Get the address and frame length of interrupted frame 
+# L4 Address of register L0 memory map
+# L5 Frame Length
+	mov    L5, L1
+	sari   L5, 21
+	andni  L5, 0xfffffff0	# L5: interrupted tasks FL.
+	cmpi   L5, 0			# Check if L4 EQ 0 (L4 = 16)
+	bnz    __Estimate_FP
+	movi   L5, 16
+__Estimate_FP:
+	setadr L4 				# Get memory position of current L0 register
+	shli   L5, 2			# Registers in memory are word alligned  (FL<<2)
+	sub    L4, L5			# Subtract prev FL to get L0 mem position of interrupted task
+	sari   L5, 2			# Restore FL (FL>>2)
+	setadr L2				# L2 contains the saved SP
+
+# Push all local registers to memory
+	call   L6, 0, _Flush_Register_Context
+
+/* Check if we come from an interrupt/system call,
+ * or an exception.
+ */
+	cmpi   L3, 8
+	ble    __Did_int_syscall_happened_in_usermode
+	br     __Did_exception_happened_in_usermode
+
+/* Check if we were in kernel mode or in user mode,
+ * when interrupt-system call  happened.
+ * If we were in user mode then switch stacks, else
+ * proceed by calling the common interrupt handling routine.
+ */
+__Did_int_syscall_happened_in_usermode:
+	cmpbi L0, 0x1
+	bz __SwitchTo_KernelStacks
+	br __Branch_To_Handler
+
+/* Check if we were in kernel mode or in user mode,
+ * when exception happened.
+ * - If we were in user mode then switch stacks
+ * - If we were in kernel mode then:
+ * 	 1. Check if we used the kernel aggregate stack.
+ *      If not move from user to kernel aggregate stack.
+ * 	 2. Check if we used the kernel register stack.
+ *      If not move from user to kernel register stack.
+ * - Branch to the appropriate exception handler.
+ */
+__Did_exception_happened_in_usermode:
+	cmpbi L0, 0x1
+	bz __SwitchTo_KernelStacks
+__CheckIfInKernelAggrStack:
+	call  L6, 0, _AreWeInKernelAggrStack
+	cmpbi L5, 0x1
+	bz  __SwitchTo_KernelAggregateStack
+__CheckIfInKernelRegisterStack:
+	call  L6, 0, _AreWeInKernelRegisterStack
+	cmpbi L5, 0x1
+	bz  __SwitchTo_KernelRegisterStack
+	br __Branch_To_Handler
+
+__Branch_To_Handler:
+	cmpi L3, 7
+	ble  __Int_Handler
+	cmpi L3, 8
+	ble  __SysCall_Handler
+	cmpi L3, 14
+	ble  __Exception_Handler
+/* We should never get here! */
+	_STI
+/* We should never get here! */
+	_STI
+	_STH
+	movi FCR, 0x77ffffB9
+	trap 16 # Just to be sure!
+
+__Int_Handler:
+	call L6, 0, _do_IRQ
+	cmpbi   L0,	0x1
+#- if interrupt happened in user mode
+	bz  _ret_from_intr
+#- else...
+	br  __Return_Final
+
+/* Entry point for the system-calls.
+ * We have already saved the register context
+ * L4 points to the address of the saved stack,
+ * while L5 specifies the number of the saved registers
+ */
+__SysCall_Handler:
+#if 1	/* in case we need to debug the Syscalls we may have to make this 0 */
+/* Check for the number of the system call */
+	frame	L8, L0 	# We need 2 more registers
+	mov 	L6, L5	# L5 contains the Frame Length
+	addi	L6, -2	# system-call entry is at L[FL-2]	
+	shli	L6, 2	# All entries are word aligned *2
+	add		L6, L4	# Add the entry to the base L (regs->L)
+	ldw.r	L6, L7	# L7 contains the system-call number saved in L[FL-2]
+	cmpi	L7, NR_syscalls
+	bgt		_bad_sys	#invalid syscall number
+/* Set the default return value */
+	addi	L6, +4	# RETURN_VALUE is located in L[FL-1]		
+	movi	L7, -ENOSYS
+	stw.r	L6, L7	# The value is saved in the L[FL-1]
+	addi	L6, -4	
+	ldw.r	L6, L7	#  L7 contains the system-call number
+/* load syscall table address. */
+	movi	L6, _SysCall_Table # Get the base address of the SysCall table
+	shli	L7, 2	# Multiply x4 the syscall number, since the table 4 byte aligned
+	add		L6, L7  # Add the offset to the SysCall table
+	ldw.r	L6, L7	# Now L7 points to the address of the syscall to be executed
+	cmpi	L7, 0	# Just to be sure that we are not having a NULL pointer
+	bz		_bad_sys
+/* Call the system call */
+	_STI
+	call	L6, L7, 0
+/****************************************************************
+ * The following code is equivelant to :            		*
+ * if(current->thread.vfork_ret_info.ret_from_vfork) {		*
+ * 	L[1] = current->thread.vfork_ret_info.ReturnPC;		*
+ *	L[2] = current->thread.vfork_ret_info.ReturnSR;		*
+ *	current->thread.vfork_ret_info.ret_from_vfork = 0;	*
+ *	}							*
+ ****************************************************************/
+	ldw.a 	0 , L7, __current_task
+	ldw.d	L7, L8, 0x2b4 
+	cmpi	L8, 0 
+	be      __ret_normal
+	ldw.a 	0 , L7, __current_task
+	ldw.d	L7, L8, 0x2b8 /* ReturnPC */ 
+	stw.d	L4, L8, 4
+	ldw.a 	0 , L7, __current_task
+	ldw.d	L7, L8, 0x2bc /* ReturnPC */ 
+	stw.d	L4, L8, 8 
+	ldw.a 	0 , L7, __current_task
+	movi    L8, 0
+	stw.d   L7, L8, 0x2b4
+__ret_normal: 
+/****************************************************/
+#else
+	call L6, 0, _Common_SysCall_Handler
+#endif
+	cmpbi	L0,	0x1
+#- if system call happened in user mode
+	bz  _ret_from_sys_call
+#- else...
+	br  __Return_Final
+
+_bad_sys:
+	addi	L6, +4	# RETURN_VALUE is located in L[FL-1]
+	movi	L7, -ENOSYS
+	cmpbi	L0,	0x1
+#- if system call happened in user mode
+	bz  _ret_from_sys_call
+#- else...
+	br  __Return_Final
+
+__Exception_Handler:
+	call   L6, 0, _Common_Exception_Handler
+	cmpbi  L0, 0x1
+#- if exception happened in user mode
+	bz  _ret_from_exception
+#- else...
+	br  _ret_from_exception_happened_in_kernel_mode
+
+
+_ret_from_intr:
+_ret_from_sys_call:
+_ret_from_exception:
+	ldw.a 	0 , L2, __current_task # If not nested, check <current->need_resched>
+	ldw.d	L2, L3, 20
+	cmpi	L3, 1 
+	bz		_reschedule
+	ldw.d	L2, L3, 8 # sigpending is the 3rd element in the task_struct 
+	cmpi	L3, 0
+	bnz		_signal_return
+	br		__SwitchBack_ToUserStacks
+
+_reschedule:
+	call	L6, 0, _schedule
+	br		_ret_from_sys_call
+
+_signal_return:
+	_STI
+	call	L6, 0, _do_signal
+	br		__SwitchBack_ToUserStacks
+
+/* When child returns from vfork the value L[FL-1] should
+ * be set to zero. L[FL-1] is the return value of vfork to
+ * the child's register stack.
+ */
+_ret_from_vfork:
+	cmpbi	L0,	0x1
+	bnz __Return_Final  # Exit without switching the stacks
+	_CLI
+	ldw.d G4, L0, -20   # Interrupted Tasks FP
+	ldw.d G4, L1, -24   # Interrupted Tasks FL
+	shli  L1, 2			# multiply L1 by 4
+	add   L0, L1 		# L0 contains the address L[FL]
+	movi  L1, 0
+	stw.d L0, L1, -4	# L[FL-1] = 0 - Return value of the child should be zero
+	br	__SwitchBack_ToUserStacks
+
+_ret_from_exception_happened_in_kernel_mode:
+/* Check for signals immediately since the process may be
+ * terminated by the exception handler. Don't touch the scheduler.
+ * Check if we changed register or aggregate stack before calling
+ * the exception handler. If this is the case then, switch stacks
+ * as it was before.
+ */
+	call    L6, 0, _ShouldWeChangeBackRegisterStack
+	cmpbi   L5, 0x1
+	bnz __SwitchBackTo_UserRegisterStack
+_CheckIfWeNeedToChangeAggregateStack:
+	call    L6, 0, _ShouldWeChangeBackAggregateStack
+	cmpbi   L5, 0x1
+	bnz __SwitchBackTo_UserAggregateStack
+	br __Return_Final
+
+/*
+ * This is the final point of return for interrupts
+ * system calls and exceptions.
+ */
+__Return_Final:
+	ret PC, L0
+
+/**************************************************************
+ * Switching Stacks code from User to Kernel Mode
+ *
+ * This is the code path for switching register and aggregate
+ * stacks when we come from User Mode either in an Interrupt,
+ * System Call or Exception.
+ **************************************************************/
+__SwitchTo_KernelStacks:
+# Switch from User Aggregate Stack to Kernel Aggregate Stack
+	stw.d G9,G3,-4
+	stw.d G9,G4,-8
+	stw.d G9,G5,-12
+	sum   G3,G9,-12
+	sum   G4,G9,-12
+	sum   G5,G9,-0x1000 # KSTACK_SIZE
+
+# Switch from User Register Stack to Kernel Register Stack
+# Move Aggregate SP downwards
+	addi  G3, -4
+	stw.n G3, G4, -28
+	sum   G4, G3,  28
+	chk   G5, G3
+# Push FP, FL, IRQ etc. number to Aggregate Stack
+	stw.d G4, L0, -4	# Saved PC
+	stw.d G4, L1, -8	# Saved SR
+	stw.d G4, L2, -12	# Saved SP
+	stw.d G4, L3, -16	# Saved IRQ number
+	stw.d G4, L4, -20	# Saved FP
+	stw.d G4, L5, -24	# Saved FL
+	_STH
+	mov   L0, UB		# Get UB
+	stw.d G4, L0, -28	# Saved UB
+# Validate Interrupt Register Stack
+# Prepare saved PC value
+	movi  L0, __Load_Param1		# Saved PC
+	ori   L0, 0x1 	    		# Supervisor Mode
+# Prepare saved SR value
+	mov   L1, SR
+	andni L1, 0xffF80000	# Clear FP, FL, ILC
+	ori   L1, 0x00c00000	# Set FL=6
+	mov   L2, G11			# SP
+	andni L2, 0xfffffe03	# Get FP (bits 2..8) from SP
+	shli  L2, 23			# Shift left by 23 to match SRs FP
+	or    L1, L2			# Get the new FP to saved SR
+
+# Set SP, UB
+	mov   L2, G11			# G11 is the interrupt register SP
+	_STH
+	mov   SP, L2			# Set SP
+
+	mov   L2, G11			# G11 is the interrupt register SP
+	addi  L2, 0x1000		# Get UB value
+	_STH
+	mov   UB, L2			# Set UB
+# Return
+	ret   PC, L0			# Validate Register Stack
+
+# Load parameters for Ints/SysCalls from Aggregate Stack 
+__Load_Param1:
+	ldw.d G4, L0, -4    # Be aware of prev User/Supervisor Mode
+	ldw.d G4, L3, -16   # IRQ Number
+	ldw.d G4, L4, -20   # Interrupted Tasks FP
+	ldw.d G4, L5, -24   # Interrupted Tasks FL
+# Finally branch to the appropriate handler
+	br __Branch_To_Handler
+#end of __SwitchTo_KernelStacks
+
+/******************************************************************
+ * __SwitchTo_KernelAggregateStack
+ * Only switch from User Aggregate Stack to Kernel Aggr Stack
+ * Code only Used in exceptions. When, exception happens in kernel
+ * mode, but still user mode stacks are used, we have to
+ * switch to kernel stacks before proceeding.
+ *
+ * __SwitchTo_KernelRegisterStack has same functionality but for
+ * the register stack.
+ ******************************************************************/
+__SwitchTo_KernelAggregateStack:
+	stw.d G9,G3,-4
+	stw.d G9,G4,-8
+	stw.d G9,G5,-12
+	sum   G3,G9,-12
+	sum   G4,G9,-12
+	sum   G5,G9,-0x1000 # KSTACK_SIZE
+# Proceed to check if RegisterStack
+	br __CheckIfInKernelRegisterStack
+#end of __SwitchTo_KernelAggregateStack
+
+/******************************************************************
+ * Switch from User Register Stack to Kernel Register Stack 
+ ******************************************************************/
+__SwitchTo_KernelRegisterStack:
+# Move Aggregate SP downwards
+	addi  G3, -4
+	stw.n G3, G4, -28
+	sum   G4, G3,  28
+	chk   G5, G3
+# Push FP, FL, IRQ etc. number to Aggregate Stack
+	stw.d G4, L0, -4	# Saved PC
+	stw.d G4, L1, -8	# Saved SR
+	stw.d G4, L2, -12	# Saved SP
+	stw.d G4, L3, -16	# Saved IRQ number
+	stw.d G4, L4, -20	# Saved FP
+	stw.d G4, L5, -24	# Saved FL
+	_STH
+	mov   L0, UB		# Get UB
+	stw.d G4, L0, -28	# Saved UB
+# Validate Interrupt Register Stack
+# Prepare saved PC value
+	movi  L0, __Load_Param2		# Saved PC
+	ori   L0, 0x1 	    		# Supervisor Mode
+# Prepare saved SR value
+	mov   L1, SR
+	andni L1, 0xffF80000	# Clear FP, FL, ILC
+	ori   L1, 0x00c00000	# Set FL=6
+	mov   L2, G11			# SP
+	andni L2, 0xfffffe03	# Get FP (bits 2..8) from SP
+	shli  L2, 23			# Shift left by 23 to match SRs FP
+	or    L1, L2			# Get the new FP to saved SR
+
+# Set SP, UB
+	mov   L2, G11			# G11 is the interrupt register SP
+	_STH
+	mov   SP, L2			# Set SP
+
+	mov   L2, G11			# G11 is the interrupt register SP
+	addi  L2, 0x1000		# Get UB value
+	_STH
+	mov   UB, L2			# Set UB
+# Return
+	ret   PC, L0			# Validate Register Stack
+
+# Load parameters for Ints/SysCalls from Aggregate Stack 
+__Load_Param2:
+	ldw.d G4, L0, -4    # Be aware of prev User/Supervisor Mode
+	ldw.d G4, L1, -8
+	ldw.d G4, L2, -12
+	ldw.d G4, L3, -16   # IRQ Number
+	ldw.d G4, L4, -20   # Interrupted Tasks FP
+	ldw.d G4, L5, -24   # Interrupted Tasks FL
+	br __Branch_To_Handler
+#end of __SwitchTo_KernelRegisterStack
+
+/******************************************************************
+ * Switching stacks code from kernel to user stack.
+ *
+ * This is the main code for switching from user register and
+ * aggregate stacks to kernel stacks. First switching register stack
+ * and then aggregate stack.
+ ******************************************************************/
+__SwitchBack_ToUserStacks:
+	_CLI
+# Restore Info from Aggregate Stack
+	movi  L0, __PushValuesTo_UserRegisterStack1
+	ori   L0, 0x1			# S flag/Return in Supervisor mode
+	mov   L1, SR			# Get current SR
+	andni L1, 0xffF80000	# Delete FP, FL
+	ori   L1, 0x00c00000	# Set FL=6
+
+	ldw.d G4, L2, -12		# Get Saved SP
+	andni L2, 0xffFFfe03	# Get the SR.FP field from SP
+	shli  L2, 23
+	or    L1, L2			# Set new FP
+
+	ldw.d G4, L2, -12		# Get Saved SP
+	_STH	
+	mov   SP, L2			# Set SP
+
+	ldw.d G4, L2, -28		# UB 
+	_STH	
+	mov   UB, L2			# Set UB
+#Return  NOW!!!
+	ret PC, L0
+
+.balign 4
+__PushValuesTo_UserRegisterStack1:
+	ldw.d G4, L0, -4
+	ldw.d G4, L1, -8
+
+# Switch from Kernel Aggregate Stack to User Aggregate Stack
+	ldw.d G9,G3, -4
+	ldw.d G9,G4, -8
+	ldw.d G9,G5, -12
+	br __Return_Final
+#end of __SwitchBack_ToUserStacks
+
+/************************************************************ 
+ * Switch from Kernel Register Stack to User Register Stack.
+ *
+ * This is only used when an exception happens in kernel mode,
+ * but we still used the user stacks.
+ * We have to identify this mismatch and change from user
+ * to kernel stack both for the register and aggregate stack.
+ *
+ * When returning from exception we have to return to the exact
+ * stack point that the exception took place, thus we have to
+ * change stacks again from kernel to user stack.
+ *
+ * __SwitchBackTo_UserAggregateStack has the same functionality
+ * but for the aggregate stack.
+ ************************************************************/
+__SwitchBackTo_UserRegisterStack:
+	_CLI
+# Restore Info from Aggregate Stack
+	movi  L0, __PushValuesTo_UserRegisterStack2
+	ori   L0, 0x1			# S flag/Return in Supervisor mode
+	mov   L1, SR			# Get current SR
+	andni L1, 0xffF80000	# Delete FP, FL
+	ori   L1, 0x00c00000	# Set FL=6
+
+	ldw.d G4, L2, -12		# Get Saved SP
+	andni L2, 0xffFFfe03	# Get the SR.FP field from SP
+	shli  L2, 23
+	or    L1, L2			# Set new FP
+
+	ldw.d G4, L2, -12		# Get Saved SP
+	_STH	
+	mov   SP, L2			# Set SP
+
+	ldw.d G4, L2, -28		# UB 
+	_STH	
+	mov   UB, L2			# Set UB
+#Return  NOW!!!
+	ret PC, L0
+
+.balign 4
+__PushValuesTo_UserRegisterStack2:
+	ldw.d G4, L0, -4
+	ldw.d G4, L1, -8
+	br _CheckIfWeNeedToChangeAggregateStack
+#end of __SwitchBackTo_UserRegisterStack
+
+/***************************************************************
+ * Switch from Kernel Aggregate Stack to User Aggregate Stack.
+ ***************************************************************/
+__SwitchBackTo_UserAggregateStack:
+	ldw.d G9,G3, -4
+	ldw.d G9,G4, -8
+	ldw.d G9,G5, -12
+	br __Return_Final
+#end of __SwitchBackTo_UserAggregateStack
+
+/**********************************************************
+ * Flush/push the local register context to memory.
+ * When returning the local registers, have exactly 
+ * the same context as just before calling this function.
+ **********************************************************/
+.global  _Flush_Register_Context
+_Flush_Register_Context:
+	frame  L6, L0
+# Saved SP is located in L2 and equals current FP.
+	setadr L2
+
+# Move local register contents to Aggregate Stack
+# Start Prologue
+	addi  G3, -4
+	stw.n G3, G4, -12
+	sum   G4, G3,  12
+	chk   G5, G3
+# End Prologue
+	stw.d G4, L0, -12   # Return PC
+	stw.d G4, L1, -8    # Return SR
+	stw.d G4, L2, -4    # SP
+
+# Flush Register Stack to memory 
+	frame L14, L0
+	call  L14, PC, 0
+	frame L14, L0
+	call  L14, PC, 0
+	frame L14, L0
+	call  L14, PC, 0
+	frame L14, L0
+
+# Restore Register Context From Aggregate Stack
+	ldw.d G4, L0, -12
+	ldw.d G4, L1, -8
+	ldw.d G4, L2, -4
+
+	_STH
+	mov   SP, L2   # Set SP
+# Start Epilogue
+	mov   G3, G4
+	ldw.n G3, G4, 4
+	ret   PC, L0	
+# End Epilogue
+
+
+.global _Uninitialised_Entry
+.global _Exception63_Entry
+.global _Exception60_Entry
+.global _Exception59_Entry
+.global _Exception58_Entry
+.global _Exception57_Entry
+.global _Exception55_Entry
+.global _Exception54_Entry
+.global _Exception53_Entry
+.global _Exception52_Entry
+.global _Exception51_Entry
+.global _Exception50_Entry
+.global _Exception49_Entry
+.global _Exception48_Entry
+.global _SysCall_Entry
+.global _ExceptionFP_Entry
+
+.balign 4
+_Uninitialised_Entry: 		MOVI PC, (long)_Uninitialised 
+.balign 4
+_Exception63_Entry: 		MOVI PC, (long)_Exception63
+/* 62 Reserved */
+/* 61 Reserved */
+.balign 4
+_Exception60_Entry: 		MOVI PC, (long)_Exception60
+.balign 4
+_Exception59_Entry: 		MOVI PC, (long)_Exception59
+.balign 4
+_Exception58_Entry: 		MOVI PC, (long)_Exception58
+.balign 4
+_Exception57_Entry: 		MOVI PC, (long)_Exception57
+/* 56 Reserved */
+.balign 4
+_Exception55_Entry:  		MOVI PC, (long)_Timer
+.balign 4
+_Exception54_Entry:  		MOVI PC, (long)_IO3
+.balign 4
+_Exception53_Entry:			MOVI PC, (long)_INT1
+.balign 4
+_Exception52_Entry: 		MOVI PC, (long)_INT2
+.balign 4
+_Exception51_Entry: 		MOVI PC, (long)_INT3
+.balign 4
+_Exception50_Entry: 		MOVI PC, (long)_INT4
+.balign 4
+_Exception49_Entry:  		MOVI PC, (long)_IO1
+.balign 4
+_Exception48_Entry:  		MOVI PC, (long)_IO2
+.balign 4
+_SysCall_Entry:     		MOVI PC, (long)_SysCall
+.balign 4
+_ExceptionFP_Entry:		MOVI PC, (long)_ExceptionFP
diff -urN linux-2.4.29/arch/e1nommu/platform/E132XS/initstack.S linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/initstack.S
--- linux-2.4.29/arch/e1nommu/platform/E132XS/initstack.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/initstack.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,14 @@
+/*
+ *  arch/e1nommu/platform/E132XS/initstack.S
+ *
+ *  Copyright (C) 2002 GDT,  George Thanos<george.thanos@gdt.gr>
+ *                           Yannis Mitsos<yannis.mitsos@gdt.gr>
+ */
+.global __Init_Register_Stack_
+
+.section .tasks
+
+.align 13 
+__Init_Register_Stack_:
+.space   0x2000
+
diff -urN linux-2.4.29/arch/e1nommu/platform/E132XS/Makefile linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/Makefile
--- linux-2.4.29/arch/e1nommu/platform/E132XS/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/Makefile	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,43 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+#.S.o:
+#	$(CC) -E -D__ASSEMBLY__ $(AFLAGS) -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o platform.o
+
+#E132XS_OBJS := #
+
+#e132xs = $(E132XS_OBJS) 
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).s
+
+O_TARGET := platform.o
+obj-y := config.o entry.o initstack.o syscalls.o syscall_entry.o traps.o
+
+ifeq ($(CONFIG_EMBEDDED_SERIAL_CONSOLE),y)
+obj-y += st16550.o
+endif
+
+ifeq ($(CONFIG_BLK_DEV_INITRD),y)
+my_initrd.o: my_initrd.s
+obj-y += my_initrd.o
+endif
+
+
+# entry.o: entry.S m68k_defs.h
+# 
+# m68k_defs.h: ../../kernel/m68k_defs.c ../../kernel/m68k_defs.head
+# 	rm -f m68k_defs.d
+# 	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/m68k_defs.c
+# 	cp ../../kernel/m68k_defs.head m68k_defs.h
+# 	grep '^#define' m68k_defs.s >> m68k_defs.h
+# 	rm m68k_defs.s
+# -include m68k_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/e1nommu/platform/E132XS/my_initrd.S linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/my_initrd.S
--- linux-2.4.29/arch/e1nommu/platform/E132XS/my_initrd.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/my_initrd.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,13 @@
+/*
+ *  arch/e1nommu/platform/E132XS/my_initrd.S
+ *
+ *  Copyright (C) 2002 GDT,  George Thanos<george.thanos@gdt.gr>
+ *                           Yannis Mitsos<yannis.mitsos@gdt.gr>
+ */
+.section .initrd
+.global __sinitrd
+.global __einitrd
+
+__sinitrd:
+.include "initrdgz.img"
+__einitrd:
diff -urN linux-2.4.29/arch/e1nommu/platform/E132XS/Rules.make linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/Rules.make
--- linux-2.4.29/arch/e1nommu/platform/E132XS/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/Rules.make	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,48 @@
+#
+# E132XS/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1999 by Greg Ungerer (gerg@lineo.com)
+# Copyright (C) 2000 Lineo Inc.
+# Copyright (C) 2002 Yiannis Mitsos <yannis.mitsos@gdt.gr>
+
+# CROSS_COMPILE = $(GCC_EXEC_PREFIX)
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/libgcc.a
+
+# INCGCC = $(TOOLS)/gcc-include
+# LIBGCC = $(TOOLS)/gcc-lib/libgcc.a
+
+CFLAGS := -fno-builtin -nostdinc $(CFLAGS) -I$(INCGCC) -pipe  \
+	-DNO_MM -DNO_FPU -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME=\"uClinux\" \
+	-D__linux__ -mgnu-param #-DDEBUG
+
+##AFLAGS := $(CFLAGS)
+AFLAGS :=  --gstabs
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS) 
+
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+archclean:
+	@$(MAKEBOOT) clean
+
diff -urN linux-2.4.29/arch/e1nommu/platform/E132XS/st16550.c linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/st16550.c
--- linux-2.4.29/arch/e1nommu/platform/E132XS/st16550.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/st16550.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,201 @@
+/*
+ * linux/arch/e1nommu/platform/E132XS/st16550.c
+ *
+ * Driver for the second serial Debug_UART of the E1-32XS Evaluation board 
+ * This driver is used for debugging purposes, in the future it should be 
+ * replaced with the Serial driver provided by the standard linux kernel
+ * /drivers/char/serial.c !!!!
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Original Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Original Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
+ * Copyright (C) 2002 by Yannis Mitsos <yannis.mitsos@gdt.gr>
+ */
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/serial_reg.h>
+
+#include <asm/delay.h>
+#include <asm/st16550_serial.h>
+#include <asm/io.h>
+
+//static unsigned long Debug_UART = ((CONFIG_SERIAL_CONSOLE_CS + 4) << 22);
+
+static __inline__ void st16550_cons_put_char(char ch, unsigned long ioaddr)
+{
+	char lsr;
+
+	do {
+#ifndef CONFIG_IO_ACCESS 
+		lsr = inb(ioaddr | (UART_LSR << IORegAddress));
+#else
+		lsr = inb(ioaddr + UART_LSR);
+#endif
+	} while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
+	outb(ch, (ioaddr | (UART_TX << IORegAddress)));
+}
+
+static __inline__ char st16550_cons_get_char(unsigned long ioaddr)
+{
+		int i;
+	while ((inb(ioaddr + UART_LSR) & UART_LSR_DR) == 0)
+//		udelay(1);
+		for(i=0; i<=10000;i++);
+	return inb(ioaddr + UART_RX);
+}
+
+void st16550_console_write(struct console *co, const char *s, unsigned count)
+{
+	char lsr, ier;
+	unsigned i;
+	
+#ifndef CONFIG_IO_ACCESS 
+	ier = inb(Debug_UART | (UART_IER << IORegAddress));
+	outb(0x00, (Debug_UART | (UART_IER << IORegAddress)));
+#else
+	ier = inb(Debug_UART + UART_IER);
+	outb(0x00, Debug_UART + UART_IER);
+#endif
+	for (i=0; i < count; i++, s++) {
+
+		if(*s == '\n')
+			st16550_cons_put_char('\r', Debug_UART);
+		st16550_cons_put_char(*s, Debug_UART);
+	}
+
+	do {
+#ifndef CONFIG_IO_ACCESS
+		lsr = inb(Debug_UART | (UART_LSR << IORegAddress));
+#else
+		lsr = inb(Debug_UART + UART_LSR);
+#endif	
+   	} while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
+
+#ifndef CONFIG_IO_ACCESS
+	outb(ier, (Debug_UART | (UART_IER << IORegAddress)));
+#else
+	outb(ier, Debug_UART + UART_IER);
+#endif
+}
+
+char getDebugChar(void)
+{
+	return st16550_cons_get_char(Debug_UART);
+}
+
+void putDebugChar(char kgdb_char)
+{
+	st16550_cons_put_char(kgdb_char, Debug_UART);
+}
+
+
+static kdev_t 
+st16550_console_dev(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+
+
+static struct console st16550_console = {
+    name:	 	"ttyS",
+    write:	 	st16550_console_write,
+	read: 	 	NULL,
+    device:	 	st16550_console_dev,
+	unblank: 	NULL,
+    setup:	 	NULL,
+    flags:		CON_PRINTBUFFER,
+    index:		-1,
+	cflag:		0
+//	console:	NULL
+};
+
+
+void __init st16550_setup_console(void)
+{
+	register_console(&st16550_console);
+}
+
+
+void st16550_serial_init(void)
+{
+	/*
+	 * Configure active Debug_UART, (CHANNELOFFSET already set.)
+	 *
+	 * Set 8 bits, 1 stop bit, no parity.
+	 *
+	 * LCR<7>       0       divisor latch access bit
+	 * LCR<6>       0       break control (1=send break)
+	 * LCR<5>       0       stick parity (0=space, 1=mark)
+	 * LCR<4>       0       parity even (0=odd, 1=even)
+	 * LCR<3>       0       parity enable (1=enabled)
+	 * LCR<2>       0       # stop bits (0=1, 1=1.5)
+	 * LCR<1:0>     11      bits per character(00=5, 01=6, 10=7, 11=8)
+	 */
+
+#ifndef CONFIG_IO_ACCESS
+	outb(0x3, (Debug_UART | (UART_LCR << IORegAddress)));
+
+	outb(FIFO_ENABLE, (Debug_UART | (UART_FCR << IORegAddress)));	/* Enable the FIFO */
+
+	outb(INT_ENABLE, (Debug_UART | (UART_IER << IORegAddress)));	/* Enable appropriate interrupts */
+#else
+	outb(0x3, Debug_UART + UART_LCR);
+
+	outb(FIFO_ENABLE, Debug_UART + UART_FCR);	/* Enable the FIFO */
+
+	outb(INT_ENABLE, Debug_UART + UART_IER);	/* Enable appropriate interrupts */
+#endif
+}
+
+
+void st16550_serial_set(unsigned long baud)
+{
+	unsigned char sav_lcr;
+	int value;
+	unsigned char DLM_value, DLL_value;
+
+	/*
+	 * Enable access to the divisor latches by setting DLAB in LCR.
+	 *
+	 */
+#ifndef CONFIG_IO_ACCESS
+	sav_lcr = inb(Debug_UART | (UART_LCR << IORegAddress));
+#else
+	sav_lcr = inb(Debug_UART + UART_LCR);
+#endif
+
+	/*
+	 * Set baud rate 
+	 */
+    value = (int)((int)(XTAL >> 4) / baud); /* Yannis: FIXME check if the devision works */ 	
+	DLL_value = (value & 0xff);
+	DLM_value = ((value & 0xff00)>>8);
+	
+#ifndef CONFIG_IO_ACCESS
+	outb(0x83, (Debug_UART | (UART_LCR << IORegAddress)));
+	outb(DLM_value, (Debug_UART | (UART_DLM << IORegAddress)));	
+	outb(DLL_value, (Debug_UART | (UART_DLL << IORegAddress)));
+	outb(0x03, (Debug_UART | (UART_LCR << IORegAddress)));
+
+	/*
+	 * Restore line control register
+	 */
+	outb(sav_lcr, (Debug_UART | (UART_LCR << IORegAddress)));
+#else
+	outb(0x83, Debug_UART + UART_LCR);
+	outb(DLM_value, Debug_UART + UART_DLM);	
+	outb(DLL_value, Debug_UART + UART_DLL);
+	outb(0x03, Debug_UART + UART_LCR);
+
+	/*
+	 * Restore line control register
+	 */
+	outb(sav_lcr, Debug_UART + UART_LCR);
+#endif
+}
diff -urN linux-2.4.29/arch/e1nommu/platform/E132XS/syscall_entry.S linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/syscall_entry.S
--- linux-2.4.29/arch/e1nommu/platform/E132XS/syscall_entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/syscall_entry.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,242 @@
+/*
+ *  arch/e1nommu/platform/E132XS/syscall_entry.S
+ *
+ *  Copyright (C) 2002 GDT,  George Thanos<george.thanos@gdt.gr>
+ *                           Yannis Mitsos<yiannis.mitsos@gdt.gr>
+ */
+#include <linux/linkage.h>
+
+.data
+.balign 4
+.global _SysCall_Table
+_SysCall_Table:
+.long 0
+.long SYMBOL_NAME(_e132xs_exit) /*1*/
+.long SYMBOL_NAME(_e132xs_fork)
+.long SYMBOL_NAME(_e132xs_read)
+.long SYMBOL_NAME(_e132xs_write)
+.long SYMBOL_NAME(_e132xs_open) /*5*/
+.long SYMBOL_NAME(_e132xs_close)
+.long SYMBOL_NAME(_e132xs_waitpid)
+.long SYMBOL_NAME(_e132xs_creat)
+.long SYMBOL_NAME(_e132xs_link)
+.long SYMBOL_NAME(_e132xs_unlink) /*10*/
+.long SYMBOL_NAME(_e132xs_execve)
+.long SYMBOL_NAME(_e132xs_chdir)
+.long SYMBOL_NAME(_e132xs_time)
+.long SYMBOL_NAME(_e132xs_mknod)
+.long SYMBOL_NAME(_e132xs_chmod) /*15*/
+.long SYMBOL_NAME(_e132xs_chown)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_break is not used */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_oldstat is not used */
+.long SYMBOL_NAME(_e132xs_lseek)
+.long SYMBOL_NAME(_e132xs_getpid) /*20*/
+.long SYMBOL_NAME(_e132xs_mount)
+.long SYMBOL_NAME(_e132xs_umount)
+.long SYMBOL_NAME(_e132xs_setuid)
+.long SYMBOL_NAME(_e132xs_getuid)
+.long SYMBOL_NAME(_e132xs_stime)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_ptrace FIXME */
+.long SYMBOL_NAME(_e132xs_alarm)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_oldfstat is not used */
+.long SYMBOL_NAME(_e132xs_pause)
+.long SYMBOL_NAME(_e132xs_utime) /*30*/
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_stty is not used */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_gtty is not used */
+.long SYMBOL_NAME(_e132xs_access)
+.long SYMBOL_NAME(_e132xs_nice)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_ftime is not used */
+.long SYMBOL_NAME(_e132xs_sync)
+.long SYMBOL_NAME(_e132xs_kill)
+.long SYMBOL_NAME(_e132xs_rename)
+.long SYMBOL_NAME(_e132xs_mkdir)
+.long SYMBOL_NAME(_e132xs_rmdir) /*40*/
+.long SYMBOL_NAME(_e132xs_dup)
+.long SYMBOL_NAME(_e132xs_pipe)
+.long SYMBOL_NAME(_e132xs_times)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_prof is not used */
+.long SYMBOL_NAME(_e132xs_brk)
+.long SYMBOL_NAME(_e132xs_setgid)
+.long SYMBOL_NAME(_e132xs_getgid)
+.long SYMBOL_NAME(_e132xs_signal)
+.long SYMBOL_NAME(_e132xs_geteuid)
+.long SYMBOL_NAME(_e132xs_getegid) /*50*/
+.long SYMBOL_NAME(_e132xs_acct)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_umount2 is not used */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_lock is not used */
+.long SYMBOL_NAME(_e132xs_ioctl)
+.long SYMBOL_NAME(_e132xs_fcntl)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_mpx is not used */
+.long SYMBOL_NAME(_e132xs_setpgid)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_ulimit is not used */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_oldolduname is not used */
+.long SYMBOL_NAME(_e132xs_umask) /*60*/
+.long SYMBOL_NAME(_e132xs_chroot)
+.long SYMBOL_NAME(_e132xs_ustat)
+.long SYMBOL_NAME(_e132xs_dup2)
+.long SYMBOL_NAME(_e132xs_getppid)
+.long SYMBOL_NAME(_e132xs_getpgrp)
+.long SYMBOL_NAME(_e132xs_setsid)
+.long SYMBOL_NAME(_e132xs_sigaction) 
+.long SYMBOL_NAME(_e132xs_sgetmask)
+.long SYMBOL_NAME(_e132xs_ssetmask)
+.long SYMBOL_NAME(_e132xs_setreuid) /*70*/
+.long SYMBOL_NAME(_e132xs_setregid)
+.long SYMBOL_NAME(_e132xs_sigsuspend)
+.long SYMBOL_NAME(_e132xs_sigpending)
+.long SYMBOL_NAME(_e132xs_sethostname)
+.long SYMBOL_NAME(_e132xs_setrlimit)
+.long SYMBOL_NAME(_e132xs_old_getrlimit)
+.long SYMBOL_NAME(_e132xs_getrusage)
+.long SYMBOL_NAME(_e132xs_gettimeofday)
+.long SYMBOL_NAME(_e132xs_settimeofday)
+.long SYMBOL_NAME(_e132xs_getgroups) /*80*/
+.long SYMBOL_NAME(_e132xs_setgroups)
+.long SYMBOL_NAME(_e132xs_old_select)
+.long SYMBOL_NAME(_e132xs_symlink)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_oldstat is not used */
+.long SYMBOL_NAME(_e132xs_readlink)
+.long SYMBOL_NAME(_e132xs_uselib)
+.long SYMBOL_NAME(_e132xs_swapon)
+.long SYMBOL_NAME(_e132xs_reboot)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_readdir is not used */
+.long SYMBOL_NAME(_e132xs_old_mmap) /*90*/
+.long SYMBOL_NAME(_e132xs_munmap)
+.long SYMBOL_NAME(_e132xs_truncate)
+.long SYMBOL_NAME(_e132xs_ftruncate)
+.long SYMBOL_NAME(_e132xs_fchmod)
+.long SYMBOL_NAME(_e132xs_fchown)
+.long SYMBOL_NAME(_e132xs_getpriority)
+.long SYMBOL_NAME(_e132xs_setpriority)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_profil is not used*/
+.long SYMBOL_NAME(_e132xs_statfs)
+.long SYMBOL_NAME(_e132xs_fstatfs) /*100*/
+.long SYMBOL_NAME(_e132xs_ioperm)
+.long SYMBOL_NAME(_e132xs_socketcall)
+.long SYMBOL_NAME(_e132xs_syslog)
+.long SYMBOL_NAME(_e132xs_setitimer)
+.long SYMBOL_NAME(_e132xs_getitimer)
+.long SYMBOL_NAME(_e132xs_newstat)
+.long SYMBOL_NAME(_e132xs_newlstat)
+.long SYMBOL_NAME(_e132xs_newfstat)
+.long SYMBOL_NAME(_e132xs_olduname)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_iopl is not used*/ /*110*/
+.long SYMBOL_NAME(_e132xs_vhangup)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_idle is not used*/
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_vm86 is not used*/
+.long SYMBOL_NAME(_e132xs_wait4)
+.long SYMBOL_NAME(_e132xs_swapoff)
+.long SYMBOL_NAME(_e132xs_sysinfo)
+.long SYMBOL_NAME(_e132xs_ipc)
+.long SYMBOL_NAME(_e132xs_fsync)
+.long SYMBOL_NAME(_e132xs_sigreturn)
+.long SYMBOL_NAME(_e132xs_clone)  /*120*/
+.long SYMBOL_NAME(_e132xs_setdomainname)
+.long SYMBOL_NAME(_e132xs_newuname)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_cacheflush FIXME */
+.long SYMBOL_NAME(_e132xs_adjtimex)
+.long SYMBOL_NAME(_e132xs_mprotect)
+.long SYMBOL_NAME(_e132xs_sigprocmask)
+.long SYMBOL_NAME(_e132xs_create_module)
+.long SYMBOL_NAME(_e132xs_init_module)
+.long SYMBOL_NAME(_e132xs_delete_module)
+.long SYMBOL_NAME(_e132xs_get_kernel_syms) /* 130 */
+.long SYMBOL_NAME(_e132xs_quotactl)
+.long SYMBOL_NAME(_e132xs_getpgid)
+.long SYMBOL_NAME(_e132xs_fchdir)
+.long SYMBOL_NAME(_e132xs_bdflush)
+.long SYMBOL_NAME(_e132xs_sysfs)
+.long SYMBOL_NAME(_e132xs_personality)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* afs_syscall not implemented*/
+.long SYMBOL_NAME(_e132xs_setfsuid)
+.long SYMBOL_NAME(_e132xs_setfsgid)
+.long SYMBOL_NAME(_e132xs_llseek) /* 140 */
+.long SYMBOL_NAME(_e132xs_getdents)
+.long SYMBOL_NAME(_e132xs_select)
+.long SYMBOL_NAME(_e132xs_flock)
+.long SYMBOL_NAME(_e132xs_msync)
+.long SYMBOL_NAME(_e132xs_readv)
+.long SYMBOL_NAME(_e132xs_writev)
+.long SYMBOL_NAME(_e132xs_getsid)
+.long SYMBOL_NAME(_e132xs_fdatasync)
+.long SYMBOL_NAME(_e132xs_sysctl)
+.long SYMBOL_NAME(_e132xs_mlock) /* 150 */
+.long SYMBOL_NAME(_e132xs_munlock)
+.long SYMBOL_NAME(_e132xs_mlockall)
+.long SYMBOL_NAME(_e132xs_munlockall)
+.long SYMBOL_NAME(_e132xs_sched_setparam)
+.long SYMBOL_NAME(_e132xs_sched_getparam)
+.long SYMBOL_NAME(_e132xs_sched_setscheduler)
+.long SYMBOL_NAME(_e132xs_sched_getscheduler)
+.long SYMBOL_NAME(_e132xs_sched_yield)
+.long SYMBOL_NAME(_e132xs_sched_get_priority_max)
+.long SYMBOL_NAME(_e132xs_sched_get_priority_min) /* 160 */
+.long SYMBOL_NAME(_e132xs_sched_rr_get_interval)
+.long SYMBOL_NAME(_e132xs_nanosleep)
+.long SYMBOL_NAME(_e132xs_mremap)
+.long SYMBOL_NAME(_e132xs_setresuid)
+.long SYMBOL_NAME(_e132xs_getresuid)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /*Entry is empty - No system call corresponds*/ /*166*/
+.long SYMBOL_NAME(_e132xs_query_module)
+.long SYMBOL_NAME(_e132xs_poll)
+.long SYMBOL_NAME(_e132xs_nfsservctl)
+.long SYMBOL_NAME(_e132xs_setresgid) /* 170 */
+.long SYMBOL_NAME(_e132xs_getresgid)
+.long SYMBOL_NAME(_e132xs_prctl)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_rt_sigreturn FIXME */
+.long SYMBOL_NAME(_e132xs_rt_sigaction)
+.long SYMBOL_NAME(_e132xs_rt_sigprocmask)
+.long SYMBOL_NAME(_e132xs_rt_sigpending)
+.long SYMBOL_NAME(_e132xs_rt_sigtimedwait)
+.long SYMBOL_NAME(_e132xs_rt_sigqueueinfo)
+.long SYMBOL_NAME(_e132xs_rt_sigsuspend)
+.long SYMBOL_NAME(_e132xs_pread) /* 180 */
+.long SYMBOL_NAME(_e132xs_pwrite)
+.long SYMBOL_NAME(_e132xs_lchown)
+.long SYMBOL_NAME(_e132xs_getcwd)
+.long SYMBOL_NAME(_e132xs_capget)
+.long SYMBOL_NAME(_e132xs_capset)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* sys_sigaltstack FIXME */
+.long SYMBOL_NAME(_e132xs_sendfile)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* getpmsg is not used */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* putpmsg is not used */
+.long SYMBOL_NAME(_e132xs_vfork) /* 190 */
+.long SYMBOL_NAME(_e132xs_getrlimit) /* FIXME */
+.long SYMBOL_NAME(_e132xs_mmap2) /* mmap2 contains 6 arguments */
+.long SYMBOL_NAME(_e132xs_truncate64)
+.long SYMBOL_NAME(_e132xs_ftruncate64)
+.long SYMBOL_NAME(_e132xs_stat64)
+.long SYMBOL_NAME(_e132xs_lstat64)
+.long SYMBOL_NAME(_e132xs_fstat64)
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* chown32 is not used  */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* getuid32 is not used  */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* getgid32 is not used  */ /* 200 */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* geteuid32 is not used  */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* getegid32 is not used  */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* setreuid32 is not used  */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* setregid32 is not used  */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* getgroups32 is not used  */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* setgroups32 is not used  */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* fchown32 is not used  */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* setresuid32 is not used  */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* getresuid32 is not used  */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* setresgid32 is not used  */ /* 210 */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* getresgid32 is not used  */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* lchown32 is not used  */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* setuid32 is not used  */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* setgid32 is not used  */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* setfsuid32 is not used  */ /* 215 */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* setfsgid32 is not used  */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* number 217 is not used */
+.long SYMBOL_NAME(_e132xs_ni_syscall) /* number 218 is not used */
+.long SYMBOL_NAME(_e132xs_pivot_root)
+.long SYMBOL_NAME(_e132xs_getdents64) /* 220 */
+.long SYMBOL_NAME(_e132xs_gettid)
+.long SYMBOL_NAME(_e132xs_tkill)
+.long SYMBOL_NAME(_e132xs_kprintf)
+.long SYMBOL_NAME(_e132xs_e1newSP) /*Hyperstone E1 specific*/
+.long 0
+.long 0
+.long 0
+.long 0
+.long 0
diff -urN linux-2.4.29/arch/e1nommu/platform/E132XS/syscalls.c linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/syscalls.c
--- linux-2.4.29/arch/e1nommu/platform/E132XS/syscalls.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/syscalls.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,334 @@
+/*
+ *  arch/e1nommu/platform/E132XS/syscalls.c
+ *
+ *  Copyrights: (C) 2002 GDT,  George Thanos<george.thanos@gdt.gr>
+ *                             Yannis Mitsos<yannis.mitsos@gdt.gr>
+ */
+#include  <linux/sys.h>
+#include  <asm/syscalls.h>
+
+#define L              regs.L
+#define FL             regs.FL
+#define RETURN_VALUE   L [ FL-1 ]
+#define SYSCALL_ENTRY  L [ FL-2 ]
+#define ARG1	       L [ FL-3 ]
+#define ARG2	       L [ FL-4 ]
+#define ARG3	       L [ FL-5 ]
+#define ARG4	       L [ FL-6 ]
+#define ARG5	       L [ FL-7 ]
+#define ARG6	       L [ FL-8 ]
+
+#define SYSCALL_ARG_0( name )	 			\
+void e132xs_##name(struct pt_regs regs ) 		\
+{ 				  			\
+	RETURN_VALUE = sys_##name( );			\
+}
+
+#define SYSCALL_ARG_1( name, type1 ) 			\
+void e132xs_##name(struct pt_regs regs ) 		\
+{ 				  			\
+	RETURN_VALUE = sys_##name( (type1)ARG1 );	\
+}
+
+#define SYSCALL_ARG_2( name, type1, type2)  			\
+void e132xs_##name(struct pt_regs regs )			\
+{ 				  				\
+	RETURN_VALUE = sys_##name( (type1)ARG1, (type2)ARG2 );	\
+}
+
+#define SYSCALL_ARG_3( name, type1, type2, type3 ) 				\
+	void e132xs_##name(struct pt_regs regs ) 				\
+{ 				  						\
+	RETURN_VALUE = sys_##name( (type1)ARG1, (type2)ARG2, (type3)ARG3 );	\
+}
+
+#define SYSCALL_ARG_4( name, type1, type2, type3, type4) 				\
+void e132xs_##name(struct pt_regs regs ) 							\
+{ 				  								\
+	RETURN_VALUE = sys_##name( (type1)ARG1, (type2)ARG2, (type3)ARG3, (type4)ARG4 );	\
+}
+
+#define SYSCALL_ARG_5( name, type1, type2, type3, type4, type5 ) 					\
+void e132xs_##name(struct pt_regs regs ) 								\
+{ 				  									\
+	RETURN_VALUE = sys_##name( (type1)ARG1, (type2)ARG2, (type3)ARG3, (type4)ARG4, (type5)ARG5 );	\
+}
+
+#define SYSCALL_ARG_6( name, type1, type2, type3, type4, type5, type6 ) 					\
+void e132xs_##name(struct pt_regs regs ) 									\
+{ 				  										\
+	RETURN_VALUE = sys_##name( (type1)ARG1, (type2)ARG2, (type3)ARG3, (type4)ARG4, (type5)ARG5, (type6)ARG6 );\
+}
+
+#define SYSCALL_REGS( name )	 			\
+void e132xs_##name(struct pt_regs regs ) 		\
+{ 				  			\
+	RETURN_VALUE = sys_##name( regs );		\
+}
+
+SYSCALL_ARG_0(ni_syscall) /*System Call Not Implemented - ERROR */
+SYSCALL_ARG_1(exit, int ) /* 1 */ 
+SYSCALL_REGS(fork)
+SYSCALL_ARG_3(read, unsigned int, char *, size_t)
+SYSCALL_ARG_3(write, unsigned int, const char *, size_t)
+SYSCALL_ARG_3(open, const char *, int, int) /*5*/
+SYSCALL_ARG_1(close, unsigned int)
+SYSCALL_ARG_3(waitpid, pid_t, unsigned int *, int)
+SYSCALL_ARG_2(creat, const char *, int)
+SYSCALL_ARG_2(link, const char *, const char *)
+SYSCALL_ARG_1(unlink, const char *) /*10*/
+#if 0
+SYSCALL_REGS(execve)
+#else
+/* In order to modify the Kernel Aggregate SP
+ * before we return to the execution of the new process
+ * we adopted this ugly scheme.
+ */
+void Switch_AggregateStackValues(void);
+void e132xs_execve(struct pt_regs regs )
+{
+	RETURN_VALUE = sys_execve( regs );
+	Switch_AggregateStackValues();
+}
+#endif
+SYSCALL_ARG_1(chdir, const char *)
+SYSCALL_ARG_1(time, int *)
+SYSCALL_ARG_3(mknod, const char *, int, dev_t)
+SYSCALL_ARG_2(chmod, const char *, mode_t) /*15*/
+SYSCALL_ARG_3(chown, const char *, uid_t, gid_t)
+/* sys_break is not used */
+/* sys_oldstat is not used */
+SYSCALL_ARG_3(lseek,unsigned int,off_t,unsigned int)
+SYSCALL_ARG_0(getpid) /*20*/
+SYSCALL_ARG_5(mount,char *, char *, char *, unsigned long, void *)
+SYSCALL_ARG_2(umount,char *, int)
+SYSCALL_ARG_1(setuid,uid_t)
+SYSCALL_ARG_0(getuid)
+SYSCALL_ARG_1(stime, int *) /*25*/
+/*SYSCALL_ARG_4(ptrace,long,long,long,long) not available FIXME */
+SYSCALL_ARG_1(alarm, unsigned int)
+/* sys_oldfstat is not used */
+SYSCALL_ARG_0(pause)
+SYSCALL_ARG_2(utime,char *, struct utimbuf *) /*30*/
+/* sys_stty is not used */
+/* sys_gtty is not used */
+SYSCALL_ARG_2(access,const char *, int)
+SYSCALL_ARG_1(nice,int)
+/* sys_ftime is not used */ /*35*/
+SYSCALL_ARG_0(sync)
+SYSCALL_ARG_2(kill,int, int)
+SYSCALL_ARG_2(rename,const char *, const char *)
+SYSCALL_ARG_2(mkdir,const char *, int)
+SYSCALL_ARG_1(rmdir,const char *) /*40*/
+SYSCALL_ARG_1(dup,int)
+SYSCALL_ARG_1(pipe, unsigned long *)
+SYSCALL_ARG_1(times,struct tms *)
+/* sys_prof is not used */
+SYSCALL_ARG_1(brk,long)  /*45*/
+SYSCALL_ARG_1(setgid,gid_t)
+SYSCALL_ARG_0(getgid)
+SYSCALL_ARG_2(signal,int, __sighandler_t)
+SYSCALL_ARG_0(geteuid)
+SYSCALL_ARG_0(getegid) /*50*/
+SYSCALL_ARG_1(acct, const char *)
+/* sys_umount2 is not used */
+/* sys_lock is not used */
+SYSCALL_ARG_3(ioctl,unsigned int, unsigned int, unsigned long)
+SYSCALL_ARG_3(fcntl,unsigned int, unsigned int, unsigned long) /*55*/
+/* sys_mpx is not used */
+SYSCALL_ARG_2(setpgid,pid_t, pid_t)
+/* sys_ulimit is not used */
+/* sys_oldolduname is not used */
+SYSCALL_ARG_1(umask,int) /*60*/
+SYSCALL_ARG_1(chroot,const char *)
+SYSCALL_ARG_2(ustat,dev_t, struct ustat *)
+SYSCALL_ARG_2(dup2, int, int)
+SYSCALL_ARG_0(getppid)
+SYSCALL_ARG_0(getpgrp) /*65*/
+SYSCALL_ARG_0(setsid)
+SYSCALL_ARG_3(sigaction,int, const struct sigaction *, struct sigaction *)
+SYSCALL_ARG_0(sgetmask)
+SYSCALL_ARG_1(ssetmask,int)
+SYSCALL_ARG_2(setreuid, uid_t, uid_t) /*70*/
+SYSCALL_ARG_2(setregid, uid_t, uid_t)
+SYSCALL_REGS(sigsuspend)
+SYSCALL_ARG_1(sigpending,old_sigset_t *)
+SYSCALL_ARG_2(sethostname, char *, int)
+SYSCALL_ARG_2(setrlimit,unsigned int, struct rlimit *)  /*75*/
+SYSCALL_ARG_2(old_getrlimit, unsigned int, struct rlimit *)
+SYSCALL_ARG_2(getrusage, int, struct rusage *)
+SYSCALL_ARG_2(gettimeofday, struct timeval *, struct timezone *)
+SYSCALL_ARG_2(settimeofday, struct timeval *, struct timezone *)
+SYSCALL_ARG_2(getgroups, int, gid_t *) /*80*/
+SYSCALL_ARG_2(setgroups, int, gid_t *)
+SYSCALL_ARG_1(old_select, struct sel_arg_struct *)
+SYSCALL_ARG_2(symlink,const char *, const char *)
+/* sys_oldstat is not used */
+SYSCALL_ARG_3(readlink, const char *, char *, int)
+SYSCALL_ARG_1(uselib, const char *)
+SYSCALL_ARG_2(swapon, const char *, int)
+SYSCALL_ARG_4(reboot, int, int, unsigned int, void *)
+/* sys_readdir is not used */
+SYSCALL_ARG_1(old_mmap, struct mmap_arg_struct *) /*90*/
+SYSCALL_ARG_2(munmap, unsigned long, size_t)
+SYSCALL_ARG_2(truncate, const char *, unsigned long)
+SYSCALL_ARG_2(ftruncate, unsigned int, unsigned long)
+SYSCALL_ARG_2(fchmod, unsigned int, mode_t)
+SYSCALL_ARG_3(fchown, unsigned int, uid_t, gid_t)
+SYSCALL_ARG_2(getpriority, int, int)
+SYSCALL_ARG_3(setpriority, int, int, int)
+/* sys_profil is not used*/
+SYSCALL_ARG_2(statfs, char *, struct statfs *)
+SYSCALL_ARG_2(fstatfs, unsigned int, struct statfs *) /*100*/
+SYSCALL_ARG_3(ioperm, unsigned long, unsigned long, int)
+SYSCALL_ARG_2(socketcall, int, unsigned long *)
+SYSCALL_ARG_3(syslog,int, char *, int)
+SYSCALL_ARG_3(setitimer, int, struct itimerval *, struct itimerval *)
+SYSCALL_ARG_2(getitimer, int, struct itimerval *)
+SYSCALL_ARG_2(newstat, char *, struct __old_kernel_stat *)
+SYSCALL_ARG_2(newlstat, char *, struct __old_kernel_stat *)
+SYSCALL_ARG_2(newfstat, unsigned int, struct __old_kernel_stat *)
+SYSCALL_ARG_1(olduname, struct old_utsname *)
+/* sys_iopl is not used*/ /*110*/
+SYSCALL_ARG_0(vhangup)
+/* sys_idle is not used*/
+/* sys_vm86 is not used*/
+SYSCALL_ARG_4(wait4, pid_t, unsigned int *, int, struct rusage *)
+SYSCALL_ARG_1(swapoff, const char *)
+SYSCALL_ARG_1(sysinfo, struct sysinfo *)
+SYSCALL_ARG_6(ipc, uint, int, int, int, void *, long)
+SYSCALL_ARG_1(fsync, unsigned int)
+SYSCALL_ARG_0(sigreturn)
+SYSCALL_REGS(clone) /*120*/
+SYSCALL_ARG_2(setdomainname,char *,int)
+SYSCALL_ARG_1(newuname, struct new_utsname *)
+/*SYSCALL_ARG_4(cacheflush, unsigned long, int, int, unsigned long) not available FIXME */
+SYSCALL_ARG_1(adjtimex, struct timex *)
+SYSCALL_ARG_3(mprotect, unsigned long, size_t, unsigned long)
+SYSCALL_ARG_3(sigprocmask, int, old_sigset_t *, old_sigset_t *)
+SYSCALL_ARG_2(create_module, const char *, size_t)
+SYSCALL_ARG_2(init_module, const char *, struct module *)
+SYSCALL_ARG_1(delete_module, const char *)
+SYSCALL_ARG_1(get_kernel_syms, struct kernel_sym *) /*130*/
+SYSCALL_ARG_4(quotactl, int, const char *, int, caddr_t)
+SYSCALL_ARG_1(getpgid, pid_t)
+SYSCALL_ARG_1(fchdir, unsigned int)
+SYSCALL_ARG_2(bdflush, int, long)
+SYSCALL_ARG_3(sysfs, int, unsigned long, unsigned long) /*135*/
+SYSCALL_ARG_1(personality, unsigned long)
+/* sys_afs_syscall not implemented*/
+SYSCALL_ARG_1(setfsuid, uid_t)
+SYSCALL_ARG_1(setfsgid, gid_t)
+SYSCALL_ARG_5(llseek, unsigned int , unsigned long , unsigned long, loff_t, unsigned int)
+SYSCALL_ARG_3(getdents, unsigned int, void *, unsigned int)
+SYSCALL_ARG_5(select,int, fd_set *, fd_set *, fd_set *, struct timeval *)
+SYSCALL_ARG_2(flock, unsigned int, unsigned int)
+SYSCALL_ARG_3(msync, unsigned long, size_t, int)
+SYSCALL_ARG_3(readv, unsigned long, const struct iovec *, unsigned long)
+SYSCALL_ARG_3(writev,unsigned long, const struct iovec *, unsigned long)
+SYSCALL_ARG_1(getsid, pid_t)
+SYSCALL_ARG_1(fdatasync, unsigned int)
+SYSCALL_ARG_1(sysctl, struct __sysctl_args *)
+SYSCALL_ARG_2(mlock, unsigned long, size_t) /*150*/
+SYSCALL_ARG_2(munlock, unsigned long, size_t)
+SYSCALL_ARG_1(mlockall,int )
+SYSCALL_ARG_0(munlockall)
+SYSCALL_ARG_2(sched_setparam, pid_t, struct sched_param *)
+SYSCALL_ARG_2(sched_getparam, pid_t, struct sched_param *)
+SYSCALL_ARG_3(sched_setscheduler, pid_t, int, struct sched_param *)
+SYSCALL_ARG_1(sched_getscheduler, pid_t)
+SYSCALL_ARG_0(sched_yield)
+SYSCALL_ARG_1(sched_get_priority_max, int)
+SYSCALL_ARG_1(sched_get_priority_min, int) /*160*/
+SYSCALL_ARG_2(sched_rr_get_interval, pid_t, struct timespec *)
+SYSCALL_ARG_2(nanosleep, struct timespec *, struct timespec *)
+SYSCALL_ARG_5(mremap, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)
+SYSCALL_ARG_3(setresuid, uid_t, uid_t, uid_t)
+SYSCALL_ARG_3(getresuid, uid_t *, uid_t *, uid_t *) /*165*/
+/*166 is missing*/
+SYSCALL_ARG_5(query_module, const char *, int, char *, size_t, size_t *)
+SYSCALL_ARG_3(poll, struct pollfd *, unsigned int, long)
+SYSCALL_ARG_3(nfsservctl, int, void *, void *)
+SYSCALL_ARG_3(setresgid, gid_t, gid_t, gid_t) /*170*/
+SYSCALL_ARG_3(getresgid, gid_t *, gid_t *, gid_t *)
+SYSCALL_ARG_5(prctl, int, unsigned long, unsigned long, unsigned long, unsigned long)
+/*SYSCALL_ARG_1(rt_sigreturn, ) * FIXME */
+SYSCALL_ARG_4(rt_sigaction, int, const struct sigaction *, struct sigaction *, size_t)
+SYSCALL_ARG_4(rt_sigprocmask, int, sigset_t *, sigset_t *, size_t)
+SYSCALL_ARG_2(rt_sigpending, sigset_t *, size_t)
+SYSCALL_ARG_4(rt_sigtimedwait, const sigset_t *, siginfo_t *, const struct timespec *, size_t)
+SYSCALL_ARG_3(rt_sigqueueinfo, int, int, siginfo_t *)
+SYSCALL_REGS(rt_sigsuspend)
+SYSCALL_ARG_4(pread, unsigned int, char *, size_t, loff_t) /*180*/
+SYSCALL_ARG_4(pwrite, unsigned int, const char *, size_t, loff_t)
+SYSCALL_ARG_3(lchown, const char *, uid_t,gid_t)
+SYSCALL_ARG_2(getcwd, char *, unsigned long)
+SYSCALL_ARG_2(capget, cap_user_header_t, cap_user_data_t)
+SYSCALL_ARG_2(capset, cap_user_header_t, const cap_user_data_t)
+/*SYSCALL_ARG_2(sigaltstack ) * FIXME */
+SYSCALL_ARG_4(sendfile, int, int, off_t *, size_t)
+/* getpmsg is not used */
+/* putpmsg is not used */
+SYSCALL_REGS(vfork) /*190*/
+SYSCALL_ARG_2(getrlimit, unsigned int, struct rlimit *) /* FIXME */
+SYSCALL_ARG_6(mmap2, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long )
+SYSCALL_ARG_2(truncate64, const char *, loff_t)
+SYSCALL_ARG_2(ftruncate64, unsigned int, loff_t)
+SYSCALL_ARG_3(stat64, char *, struct stat64 *, long)
+SYSCALL_ARG_3(lstat64, char *, struct stat64 *, long)
+SYSCALL_ARG_3(fstat64, unsigned long, struct stat64 *, long)
+/* chown32 is not used  */
+/* getuid32 is not used  */
+/* getgid32 is not used  */ /*200*/
+/* geteuid32 is not used  */
+/* getegid32 is not used  */
+/* setreuid32 is not used  */
+/* setregid32 is not used  */
+/* getgroups32 is not used  */
+/* setgroups32 is not used  */
+/* fchown32 is not used  */
+/* setresuid32 is not used  */
+/* getresuid32 is not used  */
+/* setresgid32 is not used  */ /*210*/
+/* getresgid32 is not used  */
+/* lchown32 is not used  */
+/* setuid32 is not used  */
+/* setgid32 is not used  */
+/* setfsuid32 is not used  */ /*215*/
+/* setfsgid32 is not used  */
+/* Number 217 is not used */
+/* Number 218 is not used */
+SYSCALL_ARG_2(pivot_root, const char *, const char *)
+SYSCALL_ARG_3(getdents64, unsigned int, void *, unsigned int) /* 220 */
+SYSCALL_ARG_0(gettid)
+SYSCALL_ARG_2(tkill, int, int)
+SYSCALL_ARG_2(kprintf, char *, int)
+SYSCALL_ARG_1(e1newSP, unsigned long)
+
+typedef struct {
+	void (*handler)(struct pt_regs);
+} syscall_entry_t;
+
+extern syscall_entry_t  SysCall_Table[];
+
+#define SYSCALLS_DEBUG  0 
+void Common_SysCall_Handler(struct pt_regs regs)
+{
+	unsigned long entry = SYSCALL_ENTRY;
+	RETURN_VALUE = -ENOSYS;
+
+#if SYSCALLS_DEBUG
+	printk("SYSCALLS_DEBUG: entry : %d  <-> L : 0x%x, FL : %d\n", entry, L, FL );
+#endif
+
+	if( entry > NR_syscalls || !SysCall_Table[entry].handler )
+			return;
+	sti();
+	SysCall_Table[entry].handler(regs);
+
+	if(current->thread.vfork_ret_info.ret_from_vfork) {
+		L[1] = current->thread.vfork_ret_info.ReturnPC;
+		L[2] = current->thread.vfork_ret_info.ReturnSR;
+		current->thread.vfork_ret_info.ret_from_vfork = 0;
+	}
+}
diff -urN linux-2.4.29/arch/e1nommu/platform/E132XS/traps.c linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/traps.c
--- linux-2.4.29/arch/e1nommu/platform/E132XS/traps.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/e1nommu/platform/E132XS/traps.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,226 @@
+/*
+ * arch/e1nommu/platform/E132XS/traps.c
+ * 
+ * Copyright (C) 2002 GDT,  George Thanos<george.thanos@gdt.gr>
+ *                          Yannis Mitsos<yannis.mitsos@gdt.gr>
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+
+#include <asm/current.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <asm/delay.h>
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+#include <asm/processor.h>
+#include <asm/unistd.h>
+#include <asm/stack.h>
+
+long ShortOfUserRegisterStack(void);
+long ShortOfUserAggregateStack(void);
+
+void Common_Exception_Handler(struct pt_regs regs, int exception_num)
+{
+		unsigned long *G9, G3, G4;
+		asm volatile("mov %0, G9\n\t"
+					 "mov %1, G3\n\t"
+					 "mov %2, G4\n\t"
+					 :"=l"(G9),
+					  "=l"(G3),
+					  "=l"(G4)
+					 :/*no input*/);
+
+        /* printk("WARNING:***Common_Exception_Handler***\n");
+	 */
+
+#define L    regs.L
+#define FL   regs.FL
+
+	/* Some register values may not be pushed appropriately
+	 * to memory, thus use of <exception_num> is more appropriate.
+	 * switch( L[FL+3] ) {
+	 */
+	switch( exception_num ) {
+	case 9: 
+		printk("Exception 57...\n");
+		while(1)
+		{
+			/* Parity Error */
+			toggle_green_led(0);
+		}
+		break;	
+	case 10: 
+		printk("Exception 58...\n");
+		while(1)
+		{
+			/* Parity Error */
+			toggle_red_led(0);
+		}
+		break;	
+	case 11:
+		printk("Exception 59...\n");
+		while(1)
+		{
+			/*Extended Overflow */
+			toggle_green_led(500000);
+		}
+		break;	
+	case 12: 
+#define UserUB  G9[-11]
+#define UserG5  G9[-3]
+
+		if( ShortOfUserRegisterStack() ) {
+				if  ( user_mode( (struct pt_regs*)&regs ) ) { 
+					/* Exception happened in User Mode */
+					printk("Short of User Mode Register Stack. U!\n");
+					printk("FATAL ERROR - Killing process : %d ......\n", current->pid );
+					//send_sig( SIGKILL, current, 1);
+					kill( current->pid, SIGKILL );
+				} else if ( current->thread.stack_use.excp_in_km_while_using_user_reg_stack ) {
+					/* Exception happened in Kernel Mode but while still using the User Register stack */
+					printk("Short of User Mode Register Stack. K!\n");
+					printk("FATAL ERROR - Killing process : %d ......\n", current->pid );
+					do_exit(SIGKILL);
+				} else {
+					/* Exception happened in Kernel Mode */
+					printk( "Short of Kernel Mode Register Stack!\n"
+							"KERNEL BUG!\n");
+					goto _kernel_bug;
+				}
+				break;
+		}
+		else if( ShortOfUserAggregateStack() ) {
+				if  ( user_mode( (struct pt_regs*)&regs ) ) {
+					/* Exception happened in User Mode */
+					printk("Short of User Mode Aggregate Stack. U!\n");
+					printk("FATAL ERROR - Killing process : %d ......\n", current->pid );
+					kill( current->pid, SIGKILL );
+				} else if( current->thread.stack_use.excp_in_km_while_using_user_aggr_stack ) {
+					/* Exception happened in Kernel Mode but while still using the User Aggregate stack */
+					printk("Short of User Mode Aggregate Stack. K!\n");
+					printk("FATAL ERROR - Killing process : %d ......\n", current->pid );
+					do_exit(SIGKILL);
+				} else {
+					/* Exception happened in Kernel Mode */
+					printk( "Short of Kernel Mode Aggregate Stack!\n"
+							"KERNEL BUG!\n");
+					goto _kernel_bug;
+				}
+				break;
+		}
+
+		if  ( user_mode( (struct pt_regs*)&regs ) ) {
+
+			/* restore UB & G5 to their prev values */
+			UserG5 += STACK_OFFSET; 
+			UserUB -= STACK_OFFSET; 
+
+			printk("Pointer or Priviledge Error Happened in User Mode\n");
+			printk("Killing process : %d ......\n", current->pid );
+			printk("PC : 0x%08x\n", (int)L[FL+0] ); 
+			printk("SR : 0x%08x\n", (int)L[FL+1] );
+			printk("SP : 0x%08x\n", (int)L[FL+4] );
+			printk("FL : 0x%08x\n", (int)L[FL+5] );
+			printk("current->pid : %d\n", current->pid );
+
+			kill( current->pid, SIGKILL );
+			break;
+		}
+		else
+			printk("Pointer or Priviledge Error Happened in Kernel Mode\n"
+				   "KERNEL BUG\n" );
+_kernel_bug:
+	{
+		/* Kernel Mode... */
+		unsigned long UB, G5;
+		asm volatile("ori SR, 0x20\n\t"
+					 "mov %0, UB\n\t"
+					 "mov %1, G5\n\t"
+					 :"=l"(UB),
+					  "=l"(G5)
+					 :/* no input */ );
+		G5 += STACK_OFFSET; 
+		UB -= STACK_OFFSET; 
+		asm volatile("ori SR, 0x20\n\t"
+					 "mov UB, %0\n\t"
+					 "mov G5, %1\n\t"
+					 :/* no output */
+					 :"l"(UB),
+					  "l"(G5) );
+		printk("PC : 0x%08x\n", (int)L[FL+0] ); 
+		printk("SR : 0x%08x\n", (int)L[FL+1] );
+		printk("SP : 0x%08x\n", (int)L[FL+4] );
+		printk("FL : 0x%08x\n", (int)L[FL+5] );
+		printk("current->pid : %d\n", current->pid );
+
+		cli();
+		toggle_red_led(500000);
+#undef UserUB
+#undef UserG5
+	}
+		break;
+	case 13 :
+		if  ( user_mode( (struct pt_regs*)&regs ) ) {
+			printk( "An instruction of all ones happened in user mode.\n"
+			"Killing process...\n");
+			kill( current->pid, SIGKILL );
+		} else {
+			printk("An instruction of all ones happened in kernel mode\n");
+			BUG();
+		}
+		break;
+	case 14 :
+		/* printk("Floating Exception took place...\nSending SIGFPE signal\n");
+		 */
+		kill( current->pid, SIGFPE );
+		/* the actual exception bits are cleared on the
+		 * next FP instruction. We don't have to clear them.
+		 */
+		break;
+	default:
+		printk("Exception handler: Something else happened...\n");
+		while(1);
+		break;
+	}
+#undef L
+#undef FL
+}
+
+int sys_kprintf(const char *msg, int len)
+{
+		char *str;
+		int flags;
+
+		save_flags(flags); cli();
+
+		if( len == 0 ) {
+				return 1;
+		}
+
+		str = (char *)kmalloc( len, GFP_ATOMIC );	
+		copy_from_user( str, msg, len );
+		printk("%s\n", str);
+		kfree(str);
+
+		restore_flags(flags);
+		return 100;
+}
+
+void _toggle_red_led(int arg)
+{
+	toggle_red_led(arg);
+}
+
+void _toggle_green_led(int arg)
+{
+	toggle_green_led(arg);
+}
+
+void _toggle_red_and_green_led(int arg)
+{
+	toggle_red_and_green_led(arg);
+}
diff -urN linux-2.4.29/arch/frv/boot/install.sh linux-2.4.29-uc1/arch/frv/boot/install.sh
--- linux-2.4.29/arch/frv/boot/install.sh	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/boot/install.sh	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,61 @@
+#!/bin/sh
+#
+# arch/arm/boot/install.sh
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+# Adapted from code in arch/i386/boot/install.sh by Russell King
+#
+# "make install" script for arm architecture
+#
+# Arguments:
+#   $1 - kernel version
+#   $2 - kernel image file
+#   $3 - kernel map file
+#   $4 - default install path (blank if root directory)
+#
+
+# User may have a custom install script
+
+if [ -x /sbin/installkernel ]; then
+  exec /sbin/installkernel "$@"
+fi
+
+if [ "$2" = "zImage" ]; then
+# Compressed install
+  echo "Installing compressed kernel"
+  if [ -f $4/vmlinuz-$1 ]; then
+    mv $4/vmlinuz-$1 $4/vmlinuz.old
+  fi
+
+  if [ -f $4/System.map-$1 ]; then
+    mv $4/System.map-$1 $4/System.old
+  fi
+
+  cat $2 > $4/vmlinuz-$1
+  cp $3 $4/System.map-$1
+else
+# Normal install
+  echo "Installing normal kernel"
+  if [ -f $4/vmlinux-$1 ]; then
+    mv $4/vmlinux-$1 $4/vmlinux.old
+  fi
+
+  if [ -f $4/System.map ]; then
+    mv $4/System.map $4/System.old
+  fi
+
+  cat $2 > $4/vmlinux-$1
+  cp $3 $4/System.map
+fi
+
+if [ -x /sbin/loadmap ]; then
+  /sbin/loadmap --rdev /dev/ima
+else
+  echo "You have to install it yourself"
+fi
diff -urN linux-2.4.29/arch/frv/boot/Makefile linux-2.4.29-uc1/arch/frv/boot/Makefile
--- linux-2.4.29/arch/frv/boot/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/boot/Makefile	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,66 @@
+#
+# arch/arm/boot/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995-2000 Russell King
+#
+
+SYSTEM	=$(TOPDIR)/$(LINUX)
+
+ZTEXTADDR	 = 0x02080000
+PARAMS_PHYS	 = 0x0207c000
+INITRD_PHYS	 = 0x02180000
+INITRD_VIRT	 = 0x02180000
+
+#
+# If you don't define ZRELADDR above,
+# then it defaults to ZTEXTADDR
+#
+ifeq ($(ZRELADDR),)
+ZRELADDR	= $(ZTEXTADDR)
+endif
+
+export	SYSTEM ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS INITRD_VIRT PARAMS_PHYS
+
+Image:	$(CONFIGURE) $(SYSTEM)
+	$(OBJCOPY) -O binary -R .note -R .comment -g -S $(SYSTEM) $@
+
+bzImage: zImage
+
+zImage:	$(CONFIGURE) compressed/$(LINUX)
+	$(OBJCOPY) -O binary -R .note -R .comment -S compressed/$(LINUX) $@
+
+bootpImage: bootp/bootp
+	$(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@
+
+compressed/$(LINUX): $(TOPDIR)/$(LINUX) dep
+	@$(MAKE) -C compressed $(LINUX)
+
+bootp/bootp: zImage initrd
+	@$(MAKE) -C bootp bootp
+
+initrd:
+	@test "$(INITRD_VIRT)" != "" || (echo This architecture does not support INITRD; exit -1)
+	@test "$(INITRD)" != "" || (echo You must specify INITRD; exit -1)
+
+#
+# installation
+#
+install: $(CONFIGURE) Image
+	sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
+
+zinstall: $(CONFIGURE) zImage
+	sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
+
+#
+# miscellany
+#
+mrproper clean:
+	$(RM) Image zImage bootpImage
+#	@$(MAKE) -C compressed clean
+#	@$(MAKE) -C bootp clean
+
+dep:
diff -urN linux-2.4.29/arch/frv/config.in linux-2.4.29-uc1/arch/frv/config.in
--- linux-2.4.29/arch/frv/config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/config.in	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,331 @@
+############################################################################# -*- sh -*-
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+#
+# based mainly on the arch/m68knommu/config.in
+#
+#############################################################################
+
+mainmenu_name 'Fujitsu FR-V Kernel Configuration'
+
+define_bool CONFIG_FUJITSU y
+define_bool CONFIG_FRV y
+define_bool CONFIG_UID16 y
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_DM9000_ARCH_CONFIG y
+define_bool CONFIG_NO_MMU_LARGE_ALLOCS y
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'MMU support options'
+
+choice 'Kernel Type' \
+	"Linux		CONFIG_MMU_LINUX \
+	 uCLinux	CONFIG_UCLINUX \
+	" CONFIG_MMU_LINUX
+
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Processor type and features'
+
+choice 'CPU' \
+	"FR40x/45x/55x	CONFIG_FR40x \
+	 FR55x		CONFIG_FR55x " FR40x
+
+comment 'Platform'
+
+choice 'System' \
+	"MB93091-VDK	CONFIG_MB93091_VDK \
+	 MB93093-PDK	CONFIG_MB93093_PDK \
+	" MB93091-VDK
+
+if [ "$CONFIG_MB93091_VDK" = "y" ]; then
+	choice 'Motherboard' \
+		"MB93090-MB00	CONFIG_MB93090_MB00 \
+		 None		CONFIG_MB93091_NO_MB \
+		" MB93090-MB00 
+fi
+
+choice 'Kernel executes from' \
+	"RAM	CONFIG_RAMKERNEL \
+	 ROM	CONFIG_ROMKERNEL \
+	 HIMEM  CONFIG_HIMEMKERNEL" ROM
+
+if [ "$CONFIG_MMU_LINUX" = "y" ]; then
+	choice 'High Memory Support' \
+		"off    CONFIG_NOHIGHMEM \
+		on     CONFIG_HIGHMEM \
+		" on
+
+	if [ "$CONFIG_HIGHMEM" = "y" ]; then
+		bool 'HIGHMEM I/O support' CONFIG_HIGHIO
+	fi
+fi
+
+bool 'Disable DCache' CONFIG_DCACHE_DISABLE
+
+if [ "$CONFIG_DCACHE_DISABLE" = "n" ]; then
+	choice 'Default cache-write mode' \
+	         "Write-Through  CONFIG_FRV_DEFL_CACHE_WTHRU \
+                  Write-Back     CONFIG_FRV_DEFL_CACHE_WBACK" Write-Through
+
+	bool 'Disable cache write allocate' CONFIG_FRV_DEFL_CACHE_NWA
+fi
+
+bool 'Out-of-line the atomic operations' CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'General setup'
+
+bool 'Networking support' CONFIG_NET
+
+if [ "$CONFIG_MB93091_VDK" = "y" ]; then
+	bool 'PCI support' CONFIG_PCI
+fi
+
+if [ "$CONFIG_UCLINUX" = "y" ]; then
+	bool 'Reserve memory uncached for (PCI) DMA' CONFIG_RESERVE_DMA_CONSISTENT
+fi
+
+define_bool CONFIG_SMP n
+
+source drivers/pci/Config.in
+
+bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+
+if [ "$CONFIG_HOTPLUG" = "y" ] ; then
+   source drivers/pcmcia/Config.in
+else
+   define_bool CONFIG_PCMCIA n
+fi
+
+bool 'System V IPC' CONFIG_SYSVIPC
+bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   choice 'Kernel core (/proc/kcore) format' \
+	"ELF		CONFIG_KCORE_ELF	\
+	 A.OUT		CONFIG_KCORE_AOUT" ELF
+fi
+tristate 'Kernel support for flat binaries' CONFIG_BINFMT_FLAT
+if [ "$CONFIG_BINFMT_FLAT" != "n" ]; then
+   bool '    Enable ZFLAT support' CONFIG_BINFMT_ZFLAT
+   bool '    Enable shared FLAT support' CONFIG_BINFMT_SHARED_FLAT
+fi
+tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
+tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+tristate 'Kernel support for ELF-FDPIC binaries' CONFIG_BINFMT_ELF_FDPIC
+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+
+if [ "$CONFIG_UCLINUX" = "y" ]; then
+    bool 'Kernel image protection' CONFIG_PROTECT_KERNEL
+fi
+
+bool 'Power Management support' CONFIG_PM
+
+endmenu
+
+#############################################################################
+
+source drivers/mtd/Config.in
+
+source drivers/fujitsu/Config.in
+
+source drivers/frv_acpi/Config.in
+
+source drivers/block/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   source net/Config.in
+fi
+
+source drivers/telephony/Config.in
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'ATA/IDE/MFM/RLL support'
+
+tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+
+if [ "$CONFIG_IDE" != "n" ]; then
+  source drivers/ide/Config.in
+else
+  define_bool CONFIG_BLK_DEV_IDE_MODES n
+  define_bool CONFIG_BLK_DEV_HD n
+fi
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'SCSI support'
+
+tristate 'SCSI support' CONFIG_SCSI
+
+if [ "$CONFIG_SCSI" != "n" ]; then
+   source drivers/scsi/Config.in
+fi
+endmenu
+
+#############################################################################
+
+source drivers/ieee1394/Config.in
+
+source drivers/message/i2o/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Network device support'
+
+   bool 'Network device support' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+      if [ "$CONFIG_ATM" = "y" ]; then
+         source drivers/atm/Config.in
+      fi
+   fi
+   endmenu
+fi
+
+source net/ax25/Config.in
+
+source net/irda/Config.in
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'ISDN subsystem'
+if [ "$CONFIG_NET" != "n" ]; then
+   tristate 'ISDN support' CONFIG_ISDN
+   if [ "$CONFIG_ISDN" != "n" ]; then
+      source drivers/isdn/Config.in
+   fi
+fi
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+
+bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+   source drivers/cdrom/Config.in
+fi
+endmenu
+
+#############################################################################
+
+source drivers/char/Config.in
+
+
+#source drivers/misc/Config.in
+
+source fs/Config.in
+
+if [ "$CONFIG_VT" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Console drivers'
+   bool 'VGA text console' CONFIG_VGA_CONSOLE
+   bool 'Video mode selection support' CONFIG_VIDEO_SELECT
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
+      source drivers/video/Config.in
+   fi
+   endmenu
+fi
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Sound'
+
+tristate 'Sound card support' CONFIG_SOUND
+if [ "$CONFIG_SOUND" != "n" ]; then
+   source drivers/sound/Config.in
+fi
+endmenu
+
+#############################################################################
+
+source drivers/usb/Config.in
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+bool 'Full Symbolic/Source Debugging support' CONFIG_FULLDEBUG
+bool 'Garbage-collect sections' CONFIG_GC_SECTIONS
+#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
+bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	bool 'Non power-of-2 kernel allocator (EXPERIMENTAL)' CONFIG_CONTIGUOUS_PAGE_ALLOC
+	dep_bool '  include /proc/mem_map' CONFIG_MEM_MAP $CONFIG_CONTIGUOUS_PAGE_ALLOC
+fi
+
+bool 'Kernel profiling support' CONFIG_PROFILE
+if [ "$CONFIG_PROFILE" = "y" ]; then
+  int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+  bool 'Use fast second timer for profiling' CONFIG_HIGHPROFILE
+fi
+
+bool 'Suppress Kernel BUG Messages' CONFIG_NO_KERNEL_MSG
+bool '  Debug memory allocations' CONFIG_DEBUG_SLAB
+
+bool 'Reduce kernel task size to 1 page' CONFIG_SMALL_TASKS
+
+bool 'Compiled-in Kernel Boot Parameter' CONFIG_BOOTPARAM
+if [ "$CONFIG_BOOTPARAM" = "y" ]; then
+  string 'Kernel Boot Parameter' CONFIG_BOOTPARAM_STRING ""
+fi
+
+bool '  In-kernel GDB stub' CONFIG_GDBSTUB
+if [ "$CONFIG_GDBSTUB" != "n" ]; then
+    if [ "$CONFIG_MB93093_PDK" = "y" ]; then
+	define_bool CONFIG_GDBSTUB_UART0 y
+    else
+	define_bool CONFIG_GDBSTUB_UART1 y
+    fi
+    bool '    Immediate activation' CONFIG_GDBSTUB_IMMEDIATE
+    bool '    Console through GDB stub' CONFIG_GDBSTUB_CONSOLE
+fi
+
+endmenu
+
+
+#############################################################################
+
+source crypto/Config.in
+source lib/Config.in
+
+#############################################################################
diff -urN linux-2.4.29/arch/frv/kernel/break.S linux-2.4.29-uc1/arch/frv/kernel/break.S
--- linux-2.4.29/arch/frv/kernel/break.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/break.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,711 @@
+/* break.S: Break interrupt handling (kept separate from entry.S)
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/ptrace.h>
+#include <asm/spr-regs.h>
+
+#include <asm/errno.h>
+
+#
+# the break handler has its own stack
+#
+	.section	.bss.stack
+	.globl		__break_user_context
+	.balign		8192
+__break_stack:
+	.space		(8192 - (USER_CONTEXT_SIZE + REG__DEBUG_XTRA)) & ~7
+__break_stack_tos:
+	.space		REG__DEBUG_XTRA
+__break_user_context:
+	.space		USER_CONTEXT_SIZE
+
+#
+# miscellaneous variables
+#
+	.section	.bss
+#ifndef CONFIG_UCLINUX
+	.globl		__break_tlb_miss_real_return_info
+__break_tlb_miss_real_return_info:
+	.balign		8
+	.space		2*4			/* saved PCSR, PSR for TLB-miss handler fixup */
+#endif
+
+__break_trace_through_exceptions:
+	.space		4
+
+#define CS2_ECS1	0xe1200000
+#define CS2_USERLED	0x4
+
+.macro LEDS val,reg
+#	sethi.p		%hi(CS2_ECS1+CS2_USERLED),gr30
+#	setlo		%lo(CS2_ECS1+CS2_USERLED),gr30
+#	setlos		#~\val,\reg
+#	st		\reg,@(gr30,gr0)
+#	membar
+.endm
+
+###############################################################################
+#
+# entry point for Break Exceptions/Interrupts
+#
+###############################################################################
+	.text
+	.balign		4
+	.globl		__entry_break
+__entry_break:
+#ifndef CONFIG_UCLINUX
+	movgs		gr31,scr3
+#endif
+	LEDS		0x1001,gr31
+
+	sethi.p		%hi(__break_user_context),gr31
+	setlo		%lo(__break_user_context),gr31
+
+	stdi		gr2,@(gr31,#REG_GR(2))
+	movsg		ccr,gr3
+	sti		gr3,@(gr31,#REG_CCR)
+
+	# catch the return from a TLB-miss handler that had single-step disabled
+	# traps will be enabled, so we have to do this now
+#ifndef CONFIG_UCLINUX
+	movsg		bpcsr,gr3
+	sethi.p		%hi(__break_tlb_miss_return_breaks_here),gr2
+	setlo		%lo(__break_tlb_miss_return_breaks_here),gr2
+	subcc		gr2,gr3,gr0,icc0
+	beq		icc0,#2,__break_return_singlestep_tlbmiss
+#endif
+
+	# determine whether we have stepped through into an exception
+	# - we need to take special action to suspend h/w single stepping if we've done
+	#   that, so that the gdbstub doesn't get bogged down endlessly stepping through
+	#   external interrupt handling
+	movsg		bpsr,gr3
+	andicc		gr3,#BPSR_BET,gr0,icc0
+	bne		icc0,#2,__break_maybe_userspace	/* jump if PSR.ET was 1 */
+
+	LEDS		0x1003,gr2
+
+	movsg		brr,gr3
+	andicc		gr3,#BRR_ST,gr0,icc0
+	andicc.p	gr3,#BRR_SB,gr0,icc1
+	bne		icc0,#2,__break_step		/* jump if single-step caused break */
+	beq		icc1,#2,__break_continue	/* jump if BREAK didn't cause break */
+
+	LEDS		0x1007,gr2
+
+	# handle special breaks
+	movsg		bpcsr,gr3
+
+	sethi.p		%hi(__entry_return_singlestep_breaks_here),gr2
+	setlo		%lo(__entry_return_singlestep_breaks_here),gr2
+	subcc		gr2,gr3,gr0,icc0
+	beq		icc0,#2,__break_return_singlestep
+
+	bra		__break_continue
+
+
+###############################################################################
+#
+# handle BREAK instruction in kernel-mode exception epilogue
+#
+###############################################################################
+__break_return_singlestep:
+	LEDS		0x100f,gr2
+
+	# special break insn requests single-stepping to be turned back on
+	#		HERE		RETT
+	# PSR.ET	0		0
+	# PSR.PS	old PSR.S	?
+	# PSR.S		1		1
+	# BPSR.ET	0		1 (can't have caused orig excep otherwise)
+	# BPSR.BS	1		old PSR.S
+	movsg		dcr,gr2
+	sethi.p		%hi(DCR_SE),gr3
+	setlo		%lo(DCR_SE),gr3
+	or		gr2,gr3,gr2
+	movgs		gr2,dcr
+
+	movsg		psr,gr2
+	andi		gr2,#PSR_PS,gr2
+	slli		gr2,#11,gr2			/* PSR.PS -> BPSR.BS */
+	ori		gr2,#BPSR_BET,gr2		/* 1 -> BPSR.BET */
+	movgs		gr2,bpsr
+
+	# return to the invoker of the original kernel exception
+	movsg		pcsr,gr2
+	movgs		gr2,bpcsr
+
+	LEDS		0x101f,gr2
+
+	ldi		@(gr31,#REG_CCR),gr3
+	movgs		gr3,ccr
+	lddi.p		@(gr31,#REG_GR(2)),gr2
+	xor		gr31,gr31,gr31
+	movgs		gr0,brr
+#ifndef CONFIG_UCLINUX
+	movsg		scr3,gr31
+#endif
+	rett		#1
+
+###############################################################################
+#
+# handle BREAK instruction in TLB-miss handler return path
+#
+###############################################################################
+#ifndef CONFIG_UCLINUX
+__break_return_singlestep_tlbmiss:
+	LEDS		0x1100,gr2
+	
+	sethi.p		%hi(__break_tlb_miss_real_return_info),gr3
+	setlo		%lo(__break_tlb_miss_real_return_info),gr3
+	lddi		@(gr3,#0),gr2
+	movgs		gr2,pcsr
+	movgs		gr3,psr
+
+	bra		__break_return_singlestep
+#endif
+
+
+###############################################################################
+#
+# handle single stepping into an exception prologue from kernel mode
+# - we try and catch it whilst it is still in the main vector table
+# - if we catch it there, we have to jump to the fixup handler
+#   - there is a fixup table that has a pointer for every 16b slot in the trap
+#     table
+#
+###############################################################################
+__break_step:
+	LEDS		0x2003,gr2
+
+	# external interrupts seem to escape from the trap table before single
+	# step catches up with them
+	movsg		bpcsr,gr2
+	sethi.p		%hi(__entry_kernel_external_interrupt),gr3
+	setlo		%lo(__entry_kernel_external_interrupt),gr3
+	subcc		gr2,gr3,gr0,icc0
+	beq		icc0,#2,__break_step_kernel_external_interrupt
+	sethi.p		%hi(__entry_uspace_external_interrupt),gr3
+	setlo		%lo(__entry_uspace_external_interrupt),gr3
+	subcc		gr2,gr3,gr0,icc0
+	beq		icc0,#2,__break_step_uspace_external_interrupt
+
+	LEDS		0x2007,gr2
+
+	# the two main vector tables are adjacent on one 8Kb slab
+	movsg		bpcsr,gr2
+	setlos		#0xffffe000,gr3
+	and		gr2,gr3,gr2
+	sethi.p		%hi(__trap_tables),gr3
+	setlo		%lo(__trap_tables),gr3
+	subcc		gr2,gr3,gr0,icc0
+	bne		icc0,#2,__break_continue
+
+	LEDS		0x200f,gr2
+
+	# skip workaround if so requested by GDB
+	sethi.p		%hi(__break_trace_through_exceptions),gr3
+	setlo		%lo(__break_trace_through_exceptions),gr3
+	ld		@(gr3,gr0),gr3
+	subcc		gr3,gr0,gr0,icc0
+	bne		icc0,#0,__break_continue
+
+	LEDS		0x201f,gr2
+
+	# access the fixup table - there's a 1:1 mapping between the slots in the trap tables and
+	# the slots in the trap fixup tables allowing us to simply divide the offset into the
+	# former by 4 to access the latter
+	sethi.p		%hi(__trap_tables),gr3
+	setlo		%lo(__trap_tables),gr3
+	movsg		bpcsr,gr2
+	sub		gr2,gr3,gr2
+	srli.p		gr2,#2,gr2
+
+	sethi		%hi(__trap_fixup_tables),gr3
+	setlo.p		%lo(__trap_fixup_tables),gr3
+	andi		gr2,#~3,gr2
+	ld		@(gr2,gr3),gr2
+	jmpil		@(gr2,#0)
+
+# step through an internal exception from kernel mode
+	.globl		__break_step_kernel_softprog_interrupt
+__break_step_kernel_softprog_interrupt:
+	sethi.p		%hi(__entry_kernel_softprog_interrupt_reentry),gr3
+	setlo		%lo(__entry_kernel_softprog_interrupt_reentry),gr3
+	bra		__break_return_as_kernel_prologue
+
+# step through an external interrupt from kernel mode
+	.globl		__break_step_kernel_external_interrupt
+__break_step_kernel_external_interrupt:
+	sethi.p		%hi(__entry_kernel_external_interrupt_reentry),gr3
+	setlo		%lo(__entry_kernel_external_interrupt_reentry),gr3
+
+__break_return_as_kernel_prologue:
+	LEDS		0x203f,gr2
+
+	movgs		gr3,bpcsr
+
+	# do the bit we had to skip
+#ifndef CONFIG_UCLINUX
+	movsg		ear0,gr2		/* EAR0 can get clobbered by gdb-stub (ICI/ICEI) */
+	movgs		gr2,scr2
+#endif
+
+	or.p		sp,gr0,gr2		/* set up the stack pointer */
+	subi		sp,#REG__END,sp
+	sti.p		gr2,@(sp,#REG_SP)
+
+	setlos		#REG__STATUS_STEP,gr2
+	sti		gr2,@(sp,#REG__STATUS)		/* record single step status */
+
+	# cancel single-stepping mode
+	movsg		dcr,gr2
+	sethi.p		%hi(~DCR_SE),gr3
+	setlo		%lo(~DCR_SE),gr3
+	and		gr2,gr3,gr2
+	movgs		gr2,dcr
+
+	LEDS		0x207f,gr2
+
+	ldi		@(gr31,#REG_CCR),gr3
+	movgs		gr3,ccr
+	lddi.p		@(gr31,#REG_GR(2)),gr2
+	xor		gr31,gr31,gr31
+	movgs		gr0,brr
+#ifndef CONFIG_UCLINUX
+	movsg		scr3,gr31
+#endif
+	rett		#1
+
+# step through an internal exception from uspace mode
+	.globl		__break_step_uspace_softprog_interrupt
+__break_step_uspace_softprog_interrupt:
+	sethi.p		%hi(__entry_uspace_softprog_interrupt_reentry),gr3
+	setlo		%lo(__entry_uspace_softprog_interrupt_reentry),gr3
+	bra		__break_return_as_uspace_prologue
+
+# step through an external interrupt from kernel mode
+	.globl		__break_step_uspace_external_interrupt
+__break_step_uspace_external_interrupt:
+	sethi.p		%hi(__entry_uspace_external_interrupt_reentry),gr3
+	setlo		%lo(__entry_uspace_external_interrupt_reentry),gr3
+
+__break_return_as_uspace_prologue:
+	LEDS		0x20ff,gr2
+
+	movgs		gr3,bpcsr
+
+	# do the bit we had to skip
+	sethi.p		%hi(__kernel_frame0_ptr),gr28
+	setlo		%lo(__kernel_frame0_ptr),gr28
+	ldi.p		@(gr28,#0),gr28
+
+	setlos		#REG__STATUS_STEP,gr2
+	sti		gr2,@(gr28,#REG__STATUS)	/* record single step status */
+
+	# cancel single-stepping mode
+	movsg		dcr,gr2
+	sethi.p		%hi(~DCR_SE),gr3
+	setlo		%lo(~DCR_SE),gr3
+	and		gr2,gr3,gr2
+	movgs		gr2,dcr
+
+	LEDS		0x20fe,gr2
+
+	ldi		@(gr31,#REG_CCR),gr3
+	movgs		gr3,ccr
+	lddi.p		@(gr31,#REG_GR(2)),gr2
+	xor		gr31,gr31,gr31
+	movgs		gr0,brr
+#ifndef CONFIG_UCLINUX
+	movsg		scr3,gr31
+#endif
+	rett		#1
+
+#ifndef CONFIG_UCLINUX
+# step through an ITLB-miss handler from user mode
+	.globl		__break_user_insn_tlb_miss
+__break_user_insn_tlb_miss:
+	# we'll want to try the trap stub again
+	sethi.p		%hi(__trap_user_insn_tlb_miss),gr2
+	setlo		%lo(__trap_user_insn_tlb_miss),gr2
+	movgs		gr2,bpcsr
+
+__break_tlb_miss_common:
+	LEDS		0x2101,gr2
+	
+	# cancel single-stepping mode
+	movsg		dcr,gr2
+	sethi.p		%hi(~DCR_SE),gr3
+	setlo		%lo(~DCR_SE),gr3
+	and		gr2,gr3,gr2
+	movgs		gr2,dcr
+
+	# we'll swap the real return address for one with a BREAK insn so that we can re-enable
+	# single stepping on return
+	movsg		pcsr,gr2
+	sethi.p		%hi(__break_tlb_miss_real_return_info),gr3
+	setlo		%lo(__break_tlb_miss_real_return_info),gr3
+	sti		gr2,@(gr3,#0)
+
+	sethi.p		%hi(__break_tlb_miss_return_break),gr2
+	setlo		%lo(__break_tlb_miss_return_break),gr2
+	movgs		gr2,pcsr
+
+	# we also have to fudge PSR because the return BREAK is in kernel space and we want
+	# to get a BREAK fault not an access violation should the return be to userspace
+	movsg		psr,gr2
+	sti.p		gr2,@(gr3,#4)
+	ori		gr2,#PSR_PS,gr2
+	movgs		gr2,psr
+
+	LEDS		0x2102,gr2
+	
+	ldi		@(gr31,#REG_CCR),gr3
+	movgs		gr3,ccr
+	lddi		@(gr31,#REG_GR(2)),gr2
+	movsg		scr3,gr31
+	movgs		gr0,brr
+	rett		#1
+
+# step through a DTLB-miss handler from user mode
+	.globl		__break_user_data_tlb_miss
+__break_user_data_tlb_miss:
+	# we'll want to try the trap stub again
+	sethi.p		%hi(__trap_user_data_tlb_miss),gr2
+	setlo		%lo(__trap_user_data_tlb_miss),gr2
+	movgs		gr2,bpcsr
+	bra		__break_tlb_miss_common
+
+# step through an ITLB-miss handler from kernel mode
+	.globl		__break_kernel_insn_tlb_miss
+__break_kernel_insn_tlb_miss:
+	# we'll want to try the trap stub again
+	sethi.p		%hi(__trap_kernel_insn_tlb_miss),gr2
+	setlo		%lo(__trap_kernel_insn_tlb_miss),gr2
+	movgs		gr2,bpcsr
+	bra		__break_tlb_miss_common
+
+# step through a DTLB-miss handler from kernel mode
+	.globl		__break_kernel_data_tlb_miss
+__break_kernel_data_tlb_miss:
+	# we'll want to try the trap stub again
+	sethi.p		%hi(__trap_kernel_data_tlb_miss),gr2
+	setlo		%lo(__trap_kernel_data_tlb_miss),gr2
+	movgs		gr2,bpcsr
+	bra		__break_tlb_miss_common
+#endif
+
+###############################################################################
+#
+# handle debug events originating with userspace
+#
+###############################################################################
+__break_maybe_userspace:
+	LEDS		0x3003,gr2
+
+	setlos		#BPSR_BS,gr2
+	andcc		gr3,gr2,gr0,icc0
+	bne		icc0,#0,__break_continue	/* skip if PSR.S was 1 */
+
+	movsg		brr,gr2
+	andicc		gr2,#BRR_ST|BRR_SB,gr0,icc0
+	beq		icc0,#0,__break_continue	/* jump if not BREAK or single-step */
+
+	LEDS		0x3007,gr2
+
+	# do the first part of the exception prologue here
+	sethi.p		%hi(__kernel_frame0_ptr),gr28
+	setlo		%lo(__kernel_frame0_ptr),gr28
+	ldi		@(gr28,#0),gr28
+	andi		gr28,#~7,gr28
+
+	# set up the kernel stack pointer
+	sti		sp  ,@(gr28,#REG_SP)
+	ori		gr28,0,sp
+	sti		gr0 ,@(gr28,#REG_GR(28))
+
+	stdi		gr20,@(gr28,#REG_GR(20))
+	stdi		gr22,@(gr28,#REG_GR(22))
+
+	movsg		tbr,gr20
+	movsg		bpcsr,gr21
+	movsg		psr,gr22
+
+	# determine the exception type and cancel single-stepping mode
+	or		gr0,gr0,gr23
+
+	movsg		dcr,gr2
+	sethi.p		%hi(DCR_SE),gr3
+	setlo		%lo(DCR_SE),gr3
+	andcc		gr2,gr3,gr0,icc0
+	beq		icc0,#0,__break_no_user_sstep	/* must have been a BREAK insn */
+
+	not		gr3,gr3
+	and		gr2,gr3,gr2
+	movgs		gr2,dcr
+	ori		gr23,#REG__STATUS_STEP,gr23
+
+__break_no_user_sstep:
+	LEDS		0x300f,gr2
+
+	movsg		brr,gr2
+	andi		gr2,#BRR_ST|BRR_SB,gr2
+	slli		gr2,#1,gr2
+	or		gr23,gr2,gr23
+	sti.p		gr23,@(gr28,#REG__STATUS)	/* record single step status */
+
+	# adjust the value acquired from TBR - this indicates the exception
+	setlos		#~TBR_TT,gr2
+	and.p		gr20,gr2,gr20
+	setlos		#TBR_TT_BREAK,gr2
+	or.p		gr20,gr2,gr20
+
+	# fudge PSR.PS and BPSR.BS to return to kernel mode through the trap
+	# table as trap 126
+	andi		gr22,#~PSR_PS,gr22		/* PSR.PS should be 0 */
+	movgs		gr22,psr
+
+	setlos		#BPSR_BS,gr2			/* BPSR.BS should be 1 and BPSR.BET 0 */
+	movgs		gr2,bpsr
+
+	# return through remainder of the exception prologue
+	sethi.p		%hi(__entry_common),gr3
+	setlo		%lo(__entry_common),gr3
+	movgs		gr3,bpcsr
+
+	LEDS		0x301f,gr2
+
+	ldi		@(gr31,#REG_CCR),gr3
+	movgs		gr3,ccr
+	lddi.p		@(gr31,#REG_GR(2)),gr2
+	xor		gr31,gr31,gr31
+	movgs		gr0,brr
+#ifndef CONFIG_UCLINUX
+	movsg		scr3,gr31
+#endif
+	rett		#1
+
+###############################################################################
+#
+# resume normal debug-mode entry
+#
+###############################################################################
+__break_continue:
+	LEDS		0x4003,gr2
+
+	# set up the kernel stack pointer
+	sti		sp,@(gr31,#REG_SP)
+
+	sethi.p		%hi(__break_stack_tos),sp
+	setlo		%lo(__break_stack_tos),sp
+
+	# finish building the exception frame
+	stdi		gr4 ,@(gr31,#REG_GR(4))
+	stdi		gr6 ,@(gr31,#REG_GR(6))
+	stdi		gr8 ,@(gr31,#REG_GR(8))
+	stdi		gr10,@(gr31,#REG_GR(10))
+	stdi		gr12,@(gr31,#REG_GR(12))
+	stdi		gr14,@(gr31,#REG_GR(14))
+	stdi		gr16,@(gr31,#REG_GR(16))
+	stdi		gr18,@(gr31,#REG_GR(18))
+	stdi		gr20,@(gr31,#REG_GR(20))
+	stdi		gr22,@(gr31,#REG_GR(22))
+	stdi		gr24,@(gr31,#REG_GR(24))
+	stdi		gr26,@(gr31,#REG_GR(26))
+	sti		gr0 ,@(gr31,#REG_GR(28))		 /* NULL frame pointer */
+	sti		gr29,@(gr31,#REG_GR(29))
+	sti		gr30,@(gr31,#REG_GR(30))
+	sti		gr8 ,@(gr31,#REG_ORIG_GR8)
+
+#ifndef CONFIG_UCLINUX
+	movsg		scr3,gr19
+	sti		gr19,@(gr31,#REG_GR(31))
+#endif
+
+	movsg		bpsr ,gr19
+	movsg		tbr  ,gr20
+	movsg		bpcsr,gr21
+	movsg		psr  ,gr22
+	movsg		isr  ,gr23
+	movsg		cccr ,gr25
+	movsg		lr   ,gr26
+	movsg		lcr  ,gr27
+
+	andi.p		gr22,#~(PSR_S|PSR_ET),gr5	/* rebuild PSR */
+	andi		gr19,#PSR_ET,gr4
+	or.p		gr4,gr5,gr5
+	srli		gr19,#10,gr4
+	andi		gr4,#PSR_S,gr4
+	or.p		gr4,gr5,gr5
+
+	setlos		#-1,gr6
+	sti		gr20,@(gr31,#REG_TBR)
+	sti		gr21,@(gr31,#REG_PC)
+	sti		gr5 ,@(gr31,#REG_PSR)
+	sti		gr23,@(gr31,#REG_ISR)
+	sti		gr25,@(gr31,#REG_CCCR)
+	stdi		gr26,@(gr31,#REG_LR)
+	sti		gr6 ,@(gr31,#REG_SYSCALLNO)
+
+	# store CPU-specific regs
+	movsg		iacc0h,gr4
+	movsg		iacc0l,gr5
+	stdi		gr4,@(gr31,#REG_IACC0)
+
+	movsg		gner0,gr4
+	movsg		gner1,gr5
+	stdi		gr4,@(gr31,#REG_GNER0)
+
+	# build the debug register frame
+	movsg		brr,gr4
+	movgs		gr0,brr
+	movsg		nmar,gr5
+	movsg		dcr,gr6
+
+	stdi		gr4 ,@(gr31,#REG_BRR)
+	sti		gr19,@(gr31,#REG_BPSR)
+	sti.p		gr6 ,@(gr31,#REG_DCR)
+
+	# trap exceptions during break handling and disable h/w breakpoints/watchpoints
+	sethi		%hi(DCR_EBE),gr5
+	setlo.p		%lo(DCR_EBE),gr5
+	sethi		%hi(__entry_breaktrap_table),gr4
+	setlo		%lo(__entry_breaktrap_table),gr4
+	movgs		gr5,dcr
+	movgs		gr4,tbr
+
+	# set up kernel global registers
+	sethi.p		%hi(__kernel_current_task),gr5
+	setlo		%lo(__kernel_current_task),gr5
+	ld.p		@(gr5,gr0),gr29
+
+	sethi		%hi(_gp),gr16
+	setlo.p		%lo(_gp),gr16
+
+	# make sure we (the kernel) get div-zero and misalignment exceptions
+	setlos		#ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
+	movgs		gr5,isr
+
+	# enter the GDB stub
+	LEDS		0x4007,gr2
+
+	or.p		gr0,gr0,fp
+	call		SYMBOL_NAME(debug_stub)
+
+	LEDS		0x403f,gr2
+
+	# return from break
+	lddi		@(gr31,#REG_IACC0),gr4
+	movgs		gr4,iacc0h
+	movgs		gr5,iacc0l
+
+	lddi		@(gr31,#REG_GNER0),gr4
+	movgs		gr4,gner0
+	movgs		gr5,gner1
+
+	lddi		@(gr31,#REG_LR)  ,gr26
+	lddi		@(gr31,#REG_CCR) ,gr24
+	lddi		@(gr31,#REG_PSR) ,gr22
+	ldi		@(gr31,#REG_PC)  ,gr21
+	ldi		@(gr31,#REG_TBR) ,gr20
+	ldi.p		@(gr31,#REG_DCR) ,gr6
+
+	andi		gr22,#PSR_S,gr19		/* rebuild BPSR */
+	andi.p		gr22,#PSR_ET,gr5
+	slli		gr19,#10,gr19
+	or		gr5,gr19,gr19
+
+	movgs		gr6 ,dcr
+	movgs		gr19,bpsr
+	movgs		gr20,tbr
+	movgs		gr21,bpcsr
+	movgs		gr23,isr
+	movgs		gr24,ccr
+	movgs		gr25,cccr
+	movgs		gr26,lr
+	movgs		gr27,lcr
+
+	LEDS		0x407f,gr2
+
+#ifndef CONFIG_UCLINUX
+	ldi		@(gr31,#REG_GR(31)),gr2
+	movgs		gr2,scr3
+#endif
+
+	ldi		@(gr31,#REG_GR(30)),gr30
+	ldi		@(gr31,#REG_GR(29)),gr29
+	lddi		@(gr31,#REG_GR(26)),gr26
+	lddi		@(gr31,#REG_GR(24)),gr24
+	lddi		@(gr31,#REG_GR(22)),gr22
+	lddi		@(gr31,#REG_GR(20)),gr20
+	lddi		@(gr31,#REG_GR(18)),gr18
+	lddi		@(gr31,#REG_GR(16)),gr16
+	lddi		@(gr31,#REG_GR(14)),gr14
+	lddi		@(gr31,#REG_GR(12)),gr12
+	lddi		@(gr31,#REG_GR(10)),gr10
+	lddi		@(gr31,#REG_GR(8)) ,gr8
+	lddi		@(gr31,#REG_GR(6)) ,gr6
+	lddi		@(gr31,#REG_GR(4)) ,gr4
+	lddi		@(gr31,#REG_GR(2)) ,gr2
+	ldi.p		@(gr31,#REG_SP)    ,sp
+
+	xor		gr31,gr31,gr31
+	movgs		gr0,brr
+#ifndef CONFIG_UCLINUX
+	movsg		scr3,gr31
+#endif
+	rett		#1
+
+###################################################################################################
+#
+# GDB stub "system calls"
+#
+###################################################################################################
+
+#ifdef CONFIG_GDBSTUB
+	# void gdbstub_console_write(struct console *con, const char *p, unsigned n)
+	.globl		gdbstub_console_write
+gdbstub_console_write:
+	break
+	bralr
+#endif
+
+	# GDB stub BUG() trap
+	.globl		__debug_bug_trap
+__debug_bug_trap:
+	break
+	bralr
+
+	# transfer kernel exeception to GDB for handling
+	.globl		__break_hijack_kernel_event
+__break_hijack_kernel_event:
+	break
+	.globl		__break_hijack_kernel_event_breaks_here
+__break_hijack_kernel_event_breaks_here:
+	nop
+
+#ifndef CONFIG_UCLINUX
+	# handle a return from TLB-miss that requires single-step reactivation
+	.globl		__break_tlb_miss_return_break
+__break_tlb_miss_return_break:
+	break
+__break_tlb_miss_return_breaks_here:
+	nop
+#endif
+
+	# guard the first .text label in the next file from confusion
+	nop
diff -urN linux-2.4.29/arch/frv/kernel/cmode.S linux-2.4.29-uc1/arch/frv/kernel/cmode.S
--- linux-2.4.29/arch/frv/kernel/cmode.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/cmode.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,191 @@
+/* entry.S: FR-V entry
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Woodhouse (dwmw2@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/ptrace.h>
+#include <asm/errno.h>
+#include <asm/cache.h>
+#include <asm/spr-regs.h>
+	
+#define __addr_MASK	0xfeff9820	/* interrupt controller mask */
+
+#define __addr_SDRAMC	0xfe000400	/* SDRAM controller regs */
+#define SDRAMC_DSTS	0x28		/* SDRAM status */
+#define SDRAMC_DSTS_SSI	0x00000001	/* indicates that the SDRAM is in self-refresh mode */
+#define SDRAMC_DRCN	0x30		/* SDRAM refresh control */
+#define SDRAMC_DRCN_SR	0x00000001	/* transition SDRAM into self-refresh mode */
+#define __addr_CLKC	0xfeff9a00
+#define CLKC_SWCMODE	0x00000008
+#define __addr_LEDS	0xe1200004	
+        .file		"cmode.S"
+
+.macro li v r
+	sethi.p		%hi(\v),\r
+	setlo		%lo(\v),\r
+.endm
+
+	.text
+	.balign		4
+
+	
+###############################################################################
+#
+# Change CMODE
+# - void frv_change_cmode(int cmode)
+#
+###############################################################################
+	.globl		frv_change_cmode
+        .type		frv_change_cmode,@function
+
+.macro	LEDS v
+#ifdef DEBUG_CMODE
+	setlos	#~\v,gr10
+	sti	gr10,@(gr11,#0)
+	membar
+#endif
+.endm
+		
+frv_change_cmode:	
+	movsg		lr,gr9
+#ifdef DEBUG_CMODE
+	li		__addr_LEDS,gr11
+#endif
+	dcef		@(gr0,gr0),#1
+
+	# Shift argument left by 24 bits to fit in SWCMODE register later.
+	slli		gr8,#24,gr8
+
+	# (1) Set '0' in the PSR.ET bit, and prohibit interrupts. 
+	movsg		psr,gr14
+	andi		gr14,#~PSR_ET,gr3
+	movgs		gr3,psr
+
+#if 0 // Fujitsu recommend to skip this and will update docs.
+	# (2) Set '0' to all bits of the MASK register of the interrupt 
+	#     controller, and mask interrupts. 
+	li		__addr_MASK,gr12
+	ldi		@(gr12,#0),gr13
+	li		0xffff0000,gr4
+	sti		gr4,@(gr12,#0)
+#endif
+	
+	# (3) Stop the transfer function of DMAC. Stop all the bus masters 
+	#     to access SDRAM and the internal resources.
+
+	# (already done by caller)
+	
+	# (4) Preload a series of following instructions to the instruction
+	#     cache. 
+	li		#__cmode_icache_lock_start,gr3
+	li		#__cmode_icache_lock_end,gr4
+
+1:	icpl		gr3,gr0,#1
+	addi		gr3,#L1_CACHE_BYTES,gr3
+	cmp		gr4,gr3,icc0
+	bhi		icc0,#0,1b
+
+	# Set up addresses in regs for later steps.
+	setlos		SDRAMC_DRCN_SR,gr3
+	li		__addr_SDRAMC,gr4
+	li		__addr_CLKC,gr5
+	ldi		@(gr5,#0),gr6
+	li		#0x80000000,gr7
+	or		gr6,gr7,gr6
+	
+	bra		__cmode_icache_lock_start
+
+	.balign	L1_CACHE_BYTES
+__cmode_icache_lock_start:		
+
+	# (5) Flush the content of all caches by the DCEF instruction. 
+	dcef		@(gr0,gr0),#1
+
+	# (6) Execute loading the dummy for SDRAM.
+	ldi		@(gr9,#0),gr0
+
+	# (7) Set '1' to the DRCN.SR bit, and change SDRAM to the 
+	#     self-refresh mode. Execute the dummy load to all memory
+	#     devices set to cacheable on the external bus side in parallel
+	#     with this.
+	sti		gr3,@(gr4,#SDRAMC_DRCN)
+
+	# (8) Execute memory barrier instruction (MEMBAR).
+	membar
+	
+	# (9) Read the DSTS register repeatedly until '1' stands in the 
+	#     DSTS.SSI field.
+1:	ldi		@(gr4,#SDRAMC_DSTS),gr3
+	andicc		gr3,#SDRAMC_DSTS_SSI,gr3,icc0
+	beq		icc0,#0,1b
+
+	# (10) Execute memory barrier instruction (MEMBAR).
+	membar
+	
+#if 1
+	# (11) Set the value of CMODE that you want to change to 
+	#      SWCMODE.SWCM[3:0].
+	sti		gr8,@(gr5,#CLKC_SWCMODE)
+
+	# (12) Set '1' to the CLKC.SWEN bit. In that case, do not change 
+	#      fields other than SWEN of the CLKC register.
+	sti		gr6,@(gr5,#0)
+#endif
+	# (13) Execute the instruction just after the memory barrier 
+	# instruction that executes the self-loop 256 times. (Meanwhile,
+	# the CMODE switch is done.) 
+	membar
+	setlos		#256,gr7
+2:	subicc		gr7,#1,gr7,icc0
+	bne		icc0,#2,2b
+
+	LEDS	0x36	
+
+	# (14) Release the self-refresh of SDRAM.
+	sti		gr0,@(gr4,#SDRAMC_DRCN)
+
+	# Wait for it...
+3:	ldi		@(gr4,#SDRAMC_DSTS),gr3
+	andicc		gr3,#SDRAMC_DSTS_SSI,gr3,icc0
+	bne		icc0,#2,3b
+
+#if 0
+	li		0x0100000,gr10
+4:	subicc		gr10,#1,gr10,icc0
+
+	bne		icc0,#0,4b
+#endif
+
+__cmode_icache_lock_end:		
+
+	li		#__cmode_icache_lock_start,gr3
+	li		#__cmode_icache_lock_end,gr4
+
+4:	icul		gr3
+	addi		gr3,#L1_CACHE_BYTES,gr3
+	cmp		gr4,gr3,icc0
+	bhi		icc0,#0,4b
+
+#if 0 // Fujitsu recommend to skip this and will update docs.
+	# (15) Release the interrupt mask setting of the MASK register of 
+	# the interrupt controller if necessary.
+	sti		gr13,@(gr12,#0)
+#endif	
+	# (16) Set  1' in the PSR.ET bit, and permit interrupt.
+	movgs		gr14,psr
+
+	bralr
+	
+	.size		frv_change_cmode, .-frv_change_cmode
diff -urN linux-2.4.29/arch/frv/kernel/console.c linux-2.4.29-uc1/arch/frv/kernel/console.c
--- linux-2.4.29/arch/frv/kernel/console.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/console.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,2670 @@
+
+/*
+ *  linux/drivers/char/console.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+/*
+ *	console.c
+ *
+ * This module exports the console io functions:
+ *
+ *     'void do_keyboard_interrupt(void)'
+ *
+ *     'int vc_allocate(unsigned int console)'
+ *     'int vc_cons_allocated(unsigned int console)'
+ *     'int vc_resize(unsigned long lines, unsigned long cols)'
+ *     'int vc_resize_con(unsigned long lines, unsigned long cols,
+ *			  unsigned int currcons)'
+ *     'void vc_disallocate(unsigned int currcons)'
+ *
+ *     'unsigned long con_init(unsigned long)'
+ *     'int con_open(struct tty_struct *tty, struct file * filp)'
+ *     'void con_write(struct tty_struct * tty)'
+ *     'void console_print(const char * b)'
+ *     'void update_screen(int new_console)'
+ *
+ *     'void do_blank_screen(int)'
+ *     'void do_unblank_screen(void)'
+ *     'void poke_blanked_console(void)'
+ *
+ *     'unsigned short *screen_pos(int currcons, int w_offset, int viewed)'
+ *     'void complement_pos(int currcons, int offset)'
+ *     'void invert_screen(int currcons, int offset, int count, int shift)'
+ *
+ *     'void scrollback(int lines)'
+ *     'void scrollfront(int lines)'
+ *
+ *     'int con_get_font(char *)' 
+ *     'int con_set_font(char *)'
+ * 
+ *     'void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)'
+ *     'int mouse_reporting(void)'
+ *
+ *     'unsigned long get_video_num_lines(unsigned int console)'
+ *     'unsigned long get_video_num_columns(unsigned int console)'
+ *     'unsigned long get_video_size_row(unsigned int console)'
+ *
+ * Hopefully this will be a rather complete VT102 implementation.
+ *
+ * Beeping thanks to John T Kohl.
+ *
+ * Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics
+ *   Chars, and VT100 enhancements by Peter MacDonald.
+ *
+ * Copy and paste function by Andrew Haylett,
+ *   some enhancements by Alessandro Rubini.
+ *
+ * User definable mapping table and font loading by Eugene G. Crosser,
+ * <crosser@pccross.msk.su>
+ *
+ * Code to check for different video-cards mostly by Galen Hunt,
+ * <g-hunt@ee.utah.edu>
+ *
+ * Rudimentary ISO 10646/Unicode/UTF-8 character set support by
+ * Markus Kuhn, <mskuhn@immd4.informatik.uni-erlangen.de>.
+ *
+ * Dynamic allocation of consoles, aeb@cwi.nl, May 1994
+ * Resizing of consoles, aeb, 940926
+ *
+ * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
+ * <poe@daimi.aau.dk>
+ *
+ * 680x0 LINUX support by Arno Griffioen (arno@usn.nl)
+ *
+ * 9-Apr-94:  Arno Griffioen: fixed scrolling and delete-char bug.
+ *            Scrolling code moved to amicon.c
+ *
+ * 18-Apr-94: David Carter [carter@cs.bris.ac.uk]. 680x0 LINUX modified 
+ *            Integrated support for new low level driver `amicon_ocs.c'
+ *
+ */
+
+#define BLANK 0x0020
+#define CAN_LOAD_EGA_FONTS    /* undefine if the user must not do this */
+
+/* A bitmap for codes <32. A bit of 1 indicates that the code
+ * corresponding to that bit number invokes some special action
+ * (such as cursor movement) and should not be displayed as a
+ * glyph unless the disp_ctrl mode is explicitly enabled.
+ */
+#define CTRL_ACTION 0x0d00ff81
+#define CTRL_ALWAYS 0x0800f501	/* Cannot be overridden by disp_ctrl */
+
+/*
+ * Here is the default bell parameters: 750HZ, 1/8th of a second
+ */
+#define DEFAULT_BELL_PITCH	750
+#define DEFAULT_BELL_DURATION	(HZ/8)
+
+/*
+ *  NOTE!!! We sometimes disable and enable interrupts for a short while
+ * (to put a word in video IO), but this will work even for keyboard
+ * interrupts. We know interrupts aren't enabled when getting a keyboard
+ * interrupt, as we use trap-gates. Hopefully all is well.
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/console.h>
+#include <linux/kd.h>
+#include <linux/malloc.h>
+#include <linux/major.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include "../../../drivers/char/kbd_kern.h"
+#include "../../../drivers/char/vt_kern.h"
+#include "../../../drivers/char/consolemap.h"
+#include "../../../drivers/char/selection.h"
+
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+struct tty_driver console_driver;
+static int console_refcount;
+static struct tty_struct *console_table[MAX_NR_CONSOLES];
+static struct termios *console_termios[MAX_NR_CONSOLES];
+static struct termios *console_termios_locked[MAX_NR_CONSOLES];
+
+static void vc_init(unsigned int console, int do_clear);
+
+static void update_attr(int currcons);
+static void gotoxy(int currcons, int new_x, int new_y);
+static void save_cur(int currcons);
+static void blank_screen(void);
+static void unblank_screen(void);
+extern void change_console(unsigned int);
+static inline void set_cursor(int currcons);
+static void reset_terminal(int currcons, int do_clear);
+extern void reset_vc(unsigned int new_console);
+extern void vt_init(void);
+extern void register_console(void (*proc)(const char *));
+extern void vesa_blank(void);
+extern void vesa_unblank(void);
+extern void compute_shiftstate(void);
+void poke_blanked_console(void);
+void do_blank_screen(int);
+
+unsigned long	video_num_lines;
+unsigned long	video_num_columns;
+unsigned long	video_size_row;
+
+static int printable = 0;			/* Is console ready for printing? */
+unsigned long video_font_height;	/* Height of current screen font */
+unsigned long video_scan_lines;		/* Number of scan lines on screen */
+unsigned long default_font_height;      /* Height of default screen font */
+int	      video_mode_512ch = 0;	/* 512-character mode */
+static unsigned short console_charmask = 0x0ff;
+
+static unsigned short *vc_scrbuf[MAX_NR_CONSOLES];
+
+/* used by kbd_bh - set by keyboard_interrupt */
+       int do_poke_blanked_console = 0;
+       int console_blanked = 0;
+static int blankinterval = 10*60*HZ;
+static int vesa_off_interval = 0;
+static int vesa_blank_mode = 0; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
+
+static struct vc {
+	struct vc_data *d;
+
+	/* might add  scrmem, vt_struct, kbd  at some time,
+	   to have everything in one place - the disadvantage
+	   would be that vc_cons etc can no longer be static */
+} vc_cons [MAX_NR_CONSOLES];
+struct consw *conswitchp;
+
+#define cols            (vc_cons[currcons].d->vc_cols)
+#define rows            (vc_cons[currcons].d->vc_rows)
+#define size_row        (vc_cons[currcons].d->vc_size_row)
+#define screenbuf_size	(vc_cons[currcons].d->vc_screenbuf_size)
+#define cons_num	(vc_cons[currcons].d->vc_num)
+#define origin		(vc_cons[currcons].d->vc_origin)
+#define scr_end		(vc_cons[currcons].d->vc_scr_end)
+#define pos		(vc_cons[currcons].d->vc_pos)
+#define top		(vc_cons[currcons].d->vc_top)
+#define bottom		(vc_cons[currcons].d->vc_bottom)
+#define x		(vc_cons[currcons].d->vc_x)
+#define y		(vc_cons[currcons].d->vc_y)
+#define vc_state	(vc_cons[currcons].d->vc_state)
+#define npar		(vc_cons[currcons].d->vc_npar)
+#define par		(vc_cons[currcons].d->vc_par)
+#define ques		(vc_cons[currcons].d->vc_ques)
+#define attr		(vc_cons[currcons].d->vc_attr)
+#define saved_x		(vc_cons[currcons].d->vc_saved_x)
+#define saved_y		(vc_cons[currcons].d->vc_saved_y)
+#define translate	(vc_cons[currcons].d->vc_translate)
+#define G0_charset	(vc_cons[currcons].d->vc_G0_charset)
+#define G1_charset	(vc_cons[currcons].d->vc_G1_charset)
+#define saved_G0	(vc_cons[currcons].d->vc_saved_G0)
+#define saved_G1	(vc_cons[currcons].d->vc_saved_G1)
+#define utf		(vc_cons[currcons].d->vc_utf)
+#define utf_count	(vc_cons[currcons].d->vc_utf_count)
+#define utf_char	(vc_cons[currcons].d->vc_utf_char)
+#define video_mem_start	(vc_cons[currcons].d->vc_video_mem_start)
+#define video_mem_end	(vc_cons[currcons].d->vc_video_mem_end)
+#define video_erase_char (vc_cons[currcons].d->vc_video_erase_char)	
+#define disp_ctrl	(vc_cons[currcons].d->vc_disp_ctrl)
+#define toggle_meta	(vc_cons[currcons].d->vc_toggle_meta)
+#define decscnm		(vc_cons[currcons].d->vc_decscnm)
+#define decom		(vc_cons[currcons].d->vc_decom)
+#define decawm		(vc_cons[currcons].d->vc_decawm)
+#define deccm		(vc_cons[currcons].d->vc_deccm)
+#define decim		(vc_cons[currcons].d->vc_decim)
+#define deccolm	 	(vc_cons[currcons].d->vc_deccolm)
+#define need_wrap	(vc_cons[currcons].d->vc_need_wrap)
+#define has_scrolled	(vc_cons[currcons].d->vc_has_scrolled)
+#define kmalloced	(vc_cons[currcons].d->vc_kmalloced)
+#define report_mouse	(vc_cons[currcons].d->vc_report_mouse)
+#define can_do_color	(vc_cons[currcons].d->vc_can_do_color)
+#define color		(vc_cons[currcons].d->vc_color)
+#define s_color		(vc_cons[currcons].d->vc_s_color)
+#define def_color	(vc_cons[currcons].d->vc_def_color)
+#define	foreground	(color & 0x0f)
+#define background	(color & 0xf0)
+#define charset		(vc_cons[currcons].d->vc_charset)
+#define s_charset	(vc_cons[currcons].d->vc_s_charset)
+#define	intensity	(vc_cons[currcons].d->vc_intensity)
+#define	underline	(vc_cons[currcons].d->vc_underline)
+#define	blink		(vc_cons[currcons].d->vc_blink)
+#define	reverse		(vc_cons[currcons].d->vc_reverse)
+#define	s_intensity	(vc_cons[currcons].d->vc_s_intensity)
+#define	s_underline	(vc_cons[currcons].d->vc_s_underline)
+#define	s_blink		(vc_cons[currcons].d->vc_s_blink)
+#define	s_reverse	(vc_cons[currcons].d->vc_s_reverse)
+#define	ulcolor		(vc_cons[currcons].d->vc_ulcolor)
+#define	halfcolor	(vc_cons[currcons].d->vc_halfcolor)
+#define tab_stop	(vc_cons[currcons].d->vc_tab_stop)
+#define bell_pitch	(vc_cons[currcons].d->vc_bell_pitch)
+#define bell_duration	(vc_cons[currcons].d->vc_bell_duration)
+#define sw		(vc_cons[currcons].d->vc_sw)
+
+#define vcmode		(vt_cons[currcons]->vc_mode)
+#if 0 /* XXX */
+#define	vtmode		(vt_cons[currcons]->vt_mode)
+#define	vtpid		(vt_cons[currcons]->vt_pid)
+#define	vtnewvt		(vt_cons[currcons]->vt_newvt)
+#endif
+
+#define structsize	(sizeof(struct vc_data) + sizeof(struct vt_struct))
+
+int vc_cons_allocated(unsigned int i)
+{
+	return (i < MAX_NR_CONSOLES && vc_cons[i].d);
+}
+
+int vc_allocate(unsigned int currcons)		/* return 0 on success */
+{
+	if (currcons >= MAX_NR_CONSOLES)
+	  return -ENODEV;
+	if (!vc_cons[currcons].d) {
+	    long p, q;
+
+	    /* prevent users from taking too much memory */
+	    if (currcons >= MAX_NR_USER_CONSOLES && !suser())
+	      return -EPERM;
+
+	    /* due to the granularity of kmalloc, we waste some memory here */
+	    /* the alloc is done in two steps, to optimize the common situation
+	       of a 25x80 console (structsize=216, screenbuf_size=4000) */
+	    p = (long) kmalloc(structsize, GFP_KERNEL);
+	    if (!p)
+		return -ENOMEM;
+	    vc_cons[currcons].d = (struct vc_data *) p;
+	    vt_cons[currcons] = (struct vt_struct *)(p+sizeof(struct vc_data));
+
+	    /* ++Geert: sw->con_init determines console size */
+	    sw = conswitchp;
+	    cons_num = currcons;
+	    sw->con_init (vc_cons[currcons].d);
+	    size_row = cols<<1;
+	    screenbuf_size = rows*size_row;
+
+	    q = (long) kmalloc(screenbuf_size, GFP_KERNEL);
+	    if (!q) {
+		kfree_s((char *) p, structsize);
+		vc_cons[currcons].d = NULL;
+		return -ENOMEM;
+	    }
+	    vc_scrbuf[currcons] = (unsigned short *) q;
+	    kmalloced = 1;
+	    vc_init (currcons, 1);
+	}
+	return 0;
+}
+
+/*
+ * Change # of rows and columns (0 means the size of fg_console)
+ * [this is to be used together with some user program
+ * like resize that changes the hardware videomode]
+ */
+int vc_resize(unsigned long lines, unsigned long columns)
+{
+	unsigned long cc, ll, ss, sr;
+	unsigned long occ, oll, oss, osr;
+	unsigned short *p;
+	unsigned int currcons = fg_console, i;
+	unsigned short *newscreens[MAX_NR_CONSOLES];
+	long ol, nl, rlth, rrem;
+
+	cc = (columns ? columns : cols);
+	ll = (lines ? lines : rows);
+	sr = cc << 1;
+	ss = sr * ll;
+
+	/*
+	 * Some earlier version had all consoles of potentially
+	 * different sizes, but that was really messy.
+	 * So now we only change if there is room for all consoles
+	 * of the same size.
+	 */
+	for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
+	    if (!vc_cons_allocated(currcons))
+	      newscreens[currcons] = 0;
+	    else {
+		p = (unsigned short *) kmalloc(ss, GFP_USER);
+		if (!p) {
+		    for (i = 0; i< currcons; i++)
+		      if (newscreens[i])
+			kfree_s(newscreens[i], ss);
+		    return -ENOMEM;
+		}
+		newscreens[currcons] = p;
+	    }
+	}
+
+#if 0 /* XXX */
+	get_scrmem(fg_console);
+#endif
+
+	for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
+	    if (!vc_cons_allocated(currcons))
+	      continue;
+
+	    oll = rows;
+	    occ = cols;
+	    osr = size_row;
+	    oss = screenbuf_size;
+
+	    rows = ll;
+	    cols = cc;
+	    size_row = sr;
+	    screenbuf_size = ss;
+
+	    rlth = MIN(osr, sr);
+	    rrem = sr - rlth;
+	    ol = origin;
+	    nl = (long) newscreens[currcons];
+	    if (ll < oll)
+	      ol += (oll - ll) * osr;
+
+	    update_attr(currcons);
+	    while (ol < scr_end) {
+		/* ++Geert: TODO: Because the attributes have different meanings
+                   on monochrome and color, they should really be converted if
+                   can_do_color changes... */
+		memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
+		if (rrem)
+		  memsetw((void *)(nl + rlth), video_erase_char, rrem);
+		ol += osr;
+		nl += sr;
+	    }
+
+	    if (kmalloced)
+	      kfree_s(vc_scrbuf[currcons], oss);
+	    vc_scrbuf[currcons] = newscreens[currcons];
+	    kmalloced = 1;
+	    screenbuf_size = ss;
+
+	    origin = (long) video_mem_start = vc_scrbuf[currcons];
+	    scr_end = video_mem_end = ((long) video_mem_start) + ss;
+
+	    if (scr_end > nl)
+	      memsetw((void *) nl, video_erase_char, scr_end - nl);
+
+	    /* do part of a reset_terminal() */
+	    top = 0;
+	    bottom = rows;
+	    gotoxy(currcons, x, y);
+	    save_cur(currcons);
+	}
+
+#if 0 /* XXX */
+	set_scrmem(fg_console, 0);
+	set_origin(fg_console);
+#endif /* XXX */
+	update_screen(fg_console);
+	set_cursor(fg_console);
+
+	return 0;
+}
+
+/*
+ * ++Geert: Change # of rows and columns for one specific console.
+ * Of course it's not messy to have all consoles of potentially different sizes,
+ * except on PCish hardware :-)
+ *
+ * This is called by the low level console driver (arch/m68k/console/fbcon.c or
+ * arch/m68k/console/txtcon.c)
+ */
+void vc_resize_con(unsigned long lines, unsigned long columns,
+		   unsigned int currcons)
+{
+	unsigned long cc, ll, ss, sr;
+	unsigned long occ, oll, oss, osr;
+	unsigned short *newscreen;
+	long ol, nl, rlth, rrem;
+	struct winsize ws;
+
+	if (!columns || !lines || currcons >= MAX_NR_CONSOLES)
+	    return;
+
+	cc = columns;
+	ll = lines;
+	sr = cc << 1;
+	ss = sr * ll;
+
+	if (!vc_cons_allocated(currcons))
+	    newscreen = 0;
+	else if (!(newscreen = (unsigned short *) kmalloc(ss, GFP_USER)))
+	    return;
+
+	if (vc_cons_allocated(currcons)) {
+	    oll = rows;
+	    occ = cols;
+	    osr = size_row;
+	    oss = screenbuf_size;
+
+	    rows = ll;
+	    cols = cc;
+	    size_row = sr;
+	    screenbuf_size = ss;
+
+	    rlth = MIN(osr, sr);
+	    rrem = sr - rlth;
+	    ol = origin;
+	    nl = (long) newscreen;
+	    if (ll < oll)
+	      ol += (oll - ll) * osr;
+
+	    update_attr(currcons);
+	    while (ol < scr_end) {
+		/* ++Geert: TODO: Because the attributes have different meanings
+                   on monochrome and color, they should really be converted if
+                   can_do_color changes... */
+		memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
+		if (rrem)
+		  memsetw((void *)(nl + rlth), video_erase_char, rrem);
+		ol += osr;
+		nl += sr;
+	    }
+
+	    if (kmalloced)
+	      kfree_s(vc_scrbuf[currcons], oss);
+	    vc_scrbuf[currcons] = newscreen;
+	    kmalloced = 1;
+	    screenbuf_size = ss;
+
+	    origin = (long) video_mem_start = vc_scrbuf[currcons];
+	    scr_end = video_mem_end = ((long)video_mem_start) + ss;
+
+	    if (scr_end > nl)
+	      memsetw((void *) nl, video_erase_char, scr_end - nl);
+
+	    /* do part of a reset_terminal() */
+	    top = 0;
+	    bottom = rows;
+	    gotoxy(currcons, x, y);
+	    save_cur(currcons);
+
+	    ws.ws_row = rows;
+	    ws.ws_col = cols;
+	    if (memcmp(&ws, &console_table[currcons]->winsize, sizeof (struct winsize)) &&
+	        console_table[currcons]->pgrp > 0)
+		kill_pg(console_table[currcons]->pgrp, SIGWINCH, 1);
+	    console_table[currcons]->winsize = ws;
+	}
+
+   if (currcons == fg_console && vt_cons[fg_console]->vc_mode == KD_TEXT)
+      update_screen(fg_console);
+}
+
+void vc_disallocate(unsigned int currcons)
+{
+	if (vc_cons_allocated(currcons)) {
+	    if (kmalloced)
+	      kfree_s(vc_scrbuf[currcons], screenbuf_size);
+	    if (currcons >= MIN_NR_CONSOLES)
+	      kfree_s(vc_cons[currcons].d, structsize);
+	    vc_cons[currcons].d = 0;
+	}
+}
+
+
+#define set_kbd(x) set_vc_kbd_mode(kbd_table+currcons,x)
+#define clr_kbd(x) clr_vc_kbd_mode(kbd_table+currcons,x)
+#define is_kbd(x) vc_kbd_mode(kbd_table+currcons,x)
+
+#define decarm		VC_REPEAT
+#define decckm		VC_CKMODE
+#define kbdapplic	VC_APPLIC
+#define lnm		VC_CRLF
+
+/*
+ * this is what the terminal answers to a ESC-Z or csi0c query.
+ */
+#define VT100ID "\033[?1;2c"
+#define VT102ID "\033[?6c"
+
+static unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
+				       8,12,10,14, 9,13,11,15 };
+
+/*
+ * gotoxy() must verify all boundaries, because the arguments
+ * might also be negative. If the given position is out of
+ * bounds, the cursor is placed at the nearest margin.
+ */
+static void gotoxy(int currcons, int new_x, int new_y)
+{
+	int min_y, max_y;
+
+	if (new_x < 0)
+		x = 0;
+	else
+		if (new_x >= cols)
+			x = cols - 1;
+		else
+			x = new_x;
+ 	if (decom) {
+		min_y = top;
+		max_y = bottom;
+	} else {
+		min_y = 0;
+		max_y = rows;
+	}
+	if (new_y < min_y)
+		y = min_y;
+	else if (new_y >= max_y)
+		y = max_y - 1;
+	else
+		y = new_y;
+	pos = video_mem_start + y * cols + x;
+	need_wrap = 0;
+}
+
+/* for absolute user moves, when decom is set */
+static void gotoxay(int currcons, int new_x, int new_y)
+{
+	gotoxy(currcons, new_x, decom ? (top+new_y) : new_y);
+}
+
+static void hide_cursor(int currcons)
+{
+	sw->con_cursor(vc_cons[currcons].d,CM_ERASE);
+	return;
+}
+
+static void set_cursor(int currcons)
+{
+	if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
+		return;
+	if (deccm)
+		sw->con_cursor(vc_cons[currcons].d,CM_DRAW);
+	else
+		hide_cursor(currcons);
+	return;
+}
+
+void no_scroll(char *str, int *ints)
+{
+  /*
+   * no_scroll currently does nothing on the m68k.
+   */
+}
+
+/*
+ * Arno:
+ * Why do we need these? The keyboard code doesn't seem to do anything
+ * with them either...
+ */
+void scrollfront(int l)
+{
+	return;
+}
+
+void scrollback(int l)
+{
+	return;
+}
+
+static void scrup(int currcons, unsigned int t, unsigned int b,
+		  int nr)
+{
+	unsigned short *p;
+	int i;
+
+	if (b > rows || t >= b)
+		return;
+
+	memmove (video_mem_start + t * cols,
+		 video_mem_start + (t + nr) * cols,
+		 (b - t - nr) * cols * 2);
+
+	p = video_mem_start + (b - nr) * cols;
+	for (i = nr * cols; i > 0; i--)
+	  *p++ = video_erase_char;
+
+	if (currcons != fg_console)
+	  return;
+/*
+ * Arno:
+ * Scrolling has now been moved to amicon.c where it should have
+ * been all along.
+ */
+	sw->con_scroll(vc_cons[currcons].d, t, b, SM_UP, nr);
+
+	return;
+	
+}
+
+static void scrdown(int currcons, unsigned int t, unsigned int b,
+		    int nr)
+{
+	unsigned short *p;
+	int i;
+
+	if (b > rows || t >= b)
+		return;
+
+	memmove (video_mem_start + (t + nr) * cols,
+		 video_mem_start + t * cols,
+		 (b - t - nr) * cols * 2);
+
+	p = video_mem_start + t * cols;
+	for (i = nr * cols; i > 0; i--)
+	  *p++ = video_erase_char;
+
+	if (currcons != fg_console)
+	  return;
+/*
+ * Arno:
+ * Scrolling has now been moved to amicon.c where it should have
+ * been all along.
+ */
+	sw->con_scroll(vc_cons[currcons].d, t, b, SM_DOWN, nr);
+
+	return;
+}
+
+static void lf(int currcons)
+{
+    	/* don't scroll if above bottom of scrolling region, or
+	 * if below scrolling region
+	 */
+    	if (y+1 == bottom)
+		scrup(currcons,top,bottom, 1);
+	else if (y < rows-1) {
+	    	y++;
+		pos += cols;
+	}
+	need_wrap = 0;
+}
+
+static void ri(int currcons)
+{
+    	/* don't scroll if below top of scrolling region, or
+	 * if above scrolling region
+	 */
+	if (y == top)
+		scrdown(currcons,top,bottom, 1);
+	else if (y > 0) {
+		y--;
+		pos -= cols;
+	}
+	need_wrap = 0;
+}
+
+static inline void cr(int currcons)
+{
+	pos -= x;
+	need_wrap = x = 0;
+}
+
+static inline void bs(int currcons)
+{
+	if (x) {
+		pos--;
+		x--;
+		need_wrap = 0;
+	}
+}
+
+static inline void del(int currcons)
+{
+	/* ignored */
+}
+
+static void csi_J(int currcons, int vpar)
+{
+	unsigned long count;
+	unsigned short *start;
+
+	switch (vpar) {
+		case 0:	/* erase from cursor to end of display */
+			count = (video_mem_start
+				 + cols * rows
+				 - pos);
+			start = pos;
+			if (currcons != fg_console)
+			  break;
+			/* 680x0 do in two stages */
+			sw->con_clear(vc_cons[currcons].d,y,x,1,cols-x);
+			sw->con_clear(vc_cons[currcons].d,y+1,0,rows-y-1, cols);
+			break;
+		case 1:	/* erase from start to cursor */
+			count = pos - video_mem_start + 1;
+			start = video_mem_start;
+			if (currcons != fg_console)
+			  break;
+			/* 680x0 do in two stages */
+			sw->con_clear(vc_cons[currcons].d,0,0,y, cols);
+			sw->con_clear(vc_cons[currcons].d,y,0,1,x + 1);
+			break;
+		case 2: /* erase whole display */
+			count = cols * rows;
+			start = video_mem_start;
+			if (currcons != fg_console)
+			  break;
+			sw->con_clear(vc_cons[currcons].d,0,0,rows, cols);
+			break;
+		default:
+			return;
+	}
+	while (count-- > 0)
+	  *start++ = video_erase_char;
+	need_wrap = 0;
+}
+
+static void csi_K(int currcons, int vpar)
+{
+	unsigned long count;
+	unsigned short *start;
+
+	switch (vpar) {
+		case 0:	/* erase from cursor to end of line */
+			count = cols - x;
+			start = pos;
+			if (currcons != fg_console)
+			  break;
+			sw->con_clear(vc_cons[currcons].d,y,x,1,cols-x);
+			break;
+		case 1:	/* erase from start of line to cursor */
+			start = pos - x;
+			count = x + 1;
+			if (currcons != fg_console)
+			  break;
+			sw->con_clear(vc_cons[currcons].d,y,0,1,x + 1);
+			break;
+		case 2: /* erase whole line */
+			start = pos - x;
+			count = cols;
+			if (currcons != fg_console)
+			  break;
+			sw->con_clear(vc_cons[currcons].d,y,0,1,cols);
+			break;
+		default:
+			return;
+	}
+	while (count-- > 0)
+	  *start++ = video_erase_char;
+	need_wrap = 0;
+}
+
+static void csi_X(int currcons, int vpar) /* erase the following vpar positions */
+{					  /* not vt100? */
+	unsigned long count;
+	unsigned short * start;
+
+	if (!vpar)
+		vpar++;
+
+	start=pos;
+	count=(vpar > cols-x) ? (cols-x) : vpar;
+
+	if (currcons == fg_console)
+		sw->con_clear(vc_cons[currcons].d,y,x,1,count);
+
+	while (count-- > 0)
+		*start++ = video_erase_char;
+	need_wrap = 0;
+}
+
+/*
+ * Arno: 
+ * On 680x0 attributes are currently not used. This piece of code
+ * seems hardware independent, but uses the EGA/VGA way of representing
+ * attributes. 
+ * TODO: modify for 680x0 and add attribute processing to putc code.
+ *
+ * ++roman: I completely changed the attribute format for monochrome
+ * mode (!can_do_color). The formerly used MDA (monochrome display
+ * adapter) format didn't allow the combination of certain effects.
+ * Now the attribute is just a bit vector:
+ *  Bit 0..1: intensity (0..2)
+ *  Bit 2   : underline
+ *  Bit 3   : reverse
+ *  Bit 7   : blink
+ */
+static void update_attr(int currcons)
+{
+	if (!can_do_color) {
+		/* Special treatment for monochrome */
+		attr = intensity |
+			(underline ? 4 : 0) |
+			((reverse ^ decscnm) ? 8 : 0) |
+			(blink ? 0x80 : 0);
+		video_erase_char = ' ' | ((reverse ^ decscnm) ? 0x800 : 0);
+		return;
+	}
+
+	attr = color;
+	if (underline)
+		attr = (attr & 0xf0) | ulcolor;
+	else if (intensity == 0)
+		attr = (attr & 0xf0) | halfcolor;
+	if (reverse ^ decscnm)
+		attr = reverse_video_char(attr);
+	if (blink)
+		attr ^= 0x80;
+	if (intensity == 2)
+		attr ^= 0x08;
+	if (decscnm)
+		video_erase_char = (reverse_video_char(color) << 8) | ' ';
+	else
+		video_erase_char = (color << 8) | ' ';
+}
+
+static void default_attr(int currcons)
+{
+	intensity = 1;
+	underline = 0;
+	reverse = 0;
+	blink = 0;
+	color = def_color;
+}
+
+static void csi_m(int currcons)
+{
+	int i;
+
+	for (i=0;i<=npar;i++)
+		switch (par[i]) {
+			case 0:	/* all attributes off */
+				default_attr(currcons);
+				break;
+			case 1:
+				intensity = 2;
+				break;
+			case 2:
+				intensity = 0;
+				break;
+			case 4:
+				underline = 1;
+				break;
+			case 5:
+				blink = 1;
+				break;
+			case 7:
+				reverse = 1;
+				break;
+			case 10: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Select primary font, don't display
+				  * control chars if defined, don't set
+				  * bit 8 on output.
+				  */
+				translate = set_translate(charset == 0
+						? G0_charset
+						: G1_charset);
+				disp_ctrl = 0;
+				toggle_meta = 0;
+				break;
+			case 11: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Select first alternate font, let's
+				  * chars < 32 be displayed as ROM chars.
+				  */
+				translate = set_translate(IBMPC_MAP);
+				disp_ctrl = 1;
+				toggle_meta = 0;
+				break;
+			case 12: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Select second alternate font, toggle
+				  * high bit before displaying as ROM char.
+				  */
+				translate = set_translate(IBMPC_MAP);
+				disp_ctrl = 1;
+				toggle_meta = 1;
+				break;
+			case 21:
+			case 22:
+				intensity = 1;
+				break;
+			case 24:
+				underline = 0;
+				break;
+			case 25:
+				blink = 0;
+				break;
+			case 27:
+				reverse = 0;
+				break;
+			case 38: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Enables underscore, white foreground
+				  * with white underscore (Linux - use
+				  * default foreground).
+				  */
+				color = (def_color & 0x0f) | background;
+				underline = 1;
+				break;
+			case 39: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Disable underline option.
+				  * Reset colour to default? It did this
+				  * before...
+				  */
+				color = (def_color & 0x0f) | background;
+				underline = 0;
+				break;
+			case 49:
+				color = (def_color & 0xf0) | foreground;
+				break;
+			default:
+				if (par[i] >= 30 && par[i] <= 37)
+					color = color_table[par[i]-30]
+						| background; 
+				else if (par[i] >= 40 && par[i] <= 47)
+					color = (color_table[par[i]-40]<<4)
+						| foreground;
+				break;
+		}
+	update_attr(currcons);
+}
+
+static void respond_string(const char * p, struct tty_struct * tty)
+{
+	while (*p) {
+		tty_insert_flip_char(tty, *p, 0);
+		p++;
+	}
+	tty_schedule_flip(tty);
+}
+
+static void cursor_report(int currcons, struct tty_struct * tty)
+{
+	char buf[40];
+
+	sprintf(buf, "\033[%ld;%ldR", y + (decom ? top+1 : 1), x+1);
+	respond_string(buf, tty);
+}
+
+static inline void status_report(struct tty_struct * tty)
+{
+	respond_string("\033[0n", tty);	/* Terminal ok */
+}
+
+static inline void respond_ID(struct tty_struct * tty)
+{
+	respond_string(VT102ID, tty);
+}
+
+void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)
+{
+	char buf[8];
+
+	sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
+		(char)('!' + mry));
+	respond_string(buf, tty);
+}
+
+/* invoked via ioctl(TIOCLINUX) */
+int mouse_reporting(void)
+{
+	int currcons = fg_console;
+
+	return report_mouse;
+}
+
+static inline unsigned short *screenpos(int currcons, int offset, int viewed)
+{
+	unsigned short *p = (unsigned short *)(origin + offset);
+#if 0
+	if (viewed && currcons == fg_console)
+		p -= (__real_origin - __origin);
+#endif
+	return p;
+}
+
+/* Note: inverting the screen twice should revert to the original state */
+void invert_screen(int currcons, int offset, int count, int viewed)
+{
+	unsigned short *p;
+	unsigned short xx, yy, oldattr;
+
+	count /= 2;
+	p = screenpos(currcons, offset, viewed);
+	xx = (offset >> 1) % cols;
+	yy = (offset >> 1) / cols;
+	oldattr = attr;
+	if (can_do_color)
+		while (count--) {
+			unsigned short old = scr_readw(p);
+			unsigned short new = reverse_video_short(old);
+			scr_writew(new, p);
+			p++;
+			if (currcons != fg_console)
+				continue;
+			attr = new >> 8;
+			sw->con_putc(vc_cons[currcons].d, new & 0xff, yy, xx);
+			if (++xx == cols)
+				xx = 0, ++yy;
+		}
+	else
+		while (count--) {
+			unsigned short old = scr_readw(p);
+			unsigned short new = old ^ 0x800;
+			scr_writew(new, p);
+			p++;
+			if (currcons != fg_console)
+				continue;
+			attr = new >> 8;
+			sw->con_putc(vc_cons[currcons].d, new & 0xff, yy, xx);
+			if (++xx == cols)
+				xx = 0, ++yy;
+		}
+	attr = oldattr;
+}
+
+/* used by selection: complement pointer position */
+void complement_pos(int currcons, int offset)
+{
+	static unsigned short *p = NULL;
+	static unsigned short old = 0;
+	static unsigned short oldx = 0, oldy = 0;
+	unsigned short new, oldattr;
+
+	oldattr = attr;
+	if (p) {
+		scr_writew(old, p);
+		if (currcons == fg_console) {
+			attr = old >> 8;
+			sw->con_putc(vc_cons[currcons].d, old & 0xff, oldy, oldx);
+			attr = oldattr;
+		}
+	}
+	if (offset == -1)
+		p = NULL;
+	else {
+		p = screenpos(currcons, offset, 1);
+		old = scr_readw(p);
+		oldx = (offset >> 1) % cols;
+		oldy = (offset >> 1) / cols;
+		if (can_do_color)
+			new = old ^ 0x7700;
+		else
+			new = old ^ 0x800;
+		scr_writew(new, p);
+		if (currcons == fg_console) {
+			attr = new >> 8;
+			sw->con_putc(vc_cons[currcons].d, new & 0xff, oldy, oldx);
+			attr = oldattr;
+		}
+	}
+}
+
+/* used by selection */
+unsigned short screen_word(int currcons, int offset, int viewed)
+{
+	return scr_readw(screenpos(currcons, offset, viewed));
+}
+
+/* used by selection - convert a screen word to a glyph number */
+int scrw2glyph(unsigned short scr_word)
+{
+	return ( video_mode_512ch )
+		? ((scr_word & 0x0800) >> 3) + (scr_word & 0x00ff)
+		: scr_word & 0x00ff;
+}
+
+/* used by vcs - note the word offset */
+unsigned short *screen_pos(int currcons, int w_offset, int viewed)
+{
+	return screenpos(currcons, 2 * w_offset, viewed);
+}
+
+void getconsxy(int currcons, char *p)
+{
+	p[0] = x;
+	p[1] = y;
+}
+
+void putconsxy(int currcons, char *p)
+{
+	gotoxy(currcons, p[0], p[1]);
+	set_cursor(currcons);
+}
+
+static void set_mode(int currcons, int on_off)
+{
+	int i;
+
+	for (i=0; i<=npar; i++)
+		if (ques) switch(par[i]) {	/* DEC private modes set/reset */
+			case 1:			/* Cursor keys send ^[Ox/^[[x */
+				if (on_off)
+					set_kbd(decckm);
+				else
+					clr_kbd(decckm); 
+				break;
+			case 3:	/* 80/132 mode switch unimplemented */
+				deccolm = on_off;
+#if 0
+				(void) vc_resize(rows, deccolm ? 132 : 80);
+				/* this alone does not suffice; some user mode
+				   utility has to change the hardware regs */
+#endif
+				break;
+			case 5:			/* Inverted screen on/off */
+				if (decscnm != on_off) {
+					decscnm = on_off;
+					invert_screen(currcons, 0, screenbuf_size, 0);
+					update_attr(currcons);
+				}
+				break;
+			case 6:			/* Origin relative/absolute */
+				decom = on_off;
+				gotoxay(currcons,0,0);
+				break;
+			case 7:			/* Autowrap on/off */
+				decawm = on_off;
+				break;
+			case 8:			/* Autorepeat on/off */
+				if (on_off)
+					set_kbd(decarm);
+				else
+					clr_kbd(decarm);
+				break;
+			case 9:
+				report_mouse = on_off ? 1 : 0;
+				break;
+			case 25:		/* Cursor on/off */
+				deccm = on_off;
+				set_cursor(currcons);
+				break;
+			case 1000:
+				report_mouse = on_off ? 2 : 0;
+				break;
+		} else switch(par[i]) {		/* ANSI modes set/reset */
+			case 3:			/* Monitor (display ctrls) */
+				disp_ctrl = on_off;
+				break;
+			case 4:			/* Insert Mode on/off */
+				decim = on_off;
+				break;
+			case 20:		/* Lf, Enter == CrLf/Lf */
+				if (on_off)
+					set_kbd(lnm);
+				else
+					clr_kbd(lnm);
+				break;
+		}
+}
+
+static void setterm_command(int currcons)
+{
+	switch(par[0]) {
+		case 1:	/* set color for underline mode */
+			if (can_do_color && par[1] < 16) {
+				ulcolor = color_table[par[1]];
+				if (underline)
+					update_attr(currcons);
+			}
+			break;
+		case 2:	/* set color for half intensity mode */
+			if (can_do_color && par[1] < 16) {
+				halfcolor = color_table[par[1]];
+				if (intensity == 0)
+					update_attr(currcons);
+			}
+			break;
+		case 8:	/* store colors as defaults */
+			def_color = attr;
+			default_attr(currcons);
+			update_attr(currcons);
+			break;
+		case 9:	/* set blanking interval */
+			blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
+			poke_blanked_console();
+			break;
+		case 10: /* set bell frequency in Hz */
+			if (npar >= 1)
+				bell_pitch = par[1];
+			else
+				bell_pitch = DEFAULT_BELL_PITCH;
+			break;
+		case 11: /* set bell duration in msec */
+			if (npar >= 1)
+				bell_duration = (par[1] < 2000) ?
+					par[1]*HZ/1000 : 0;
+			else
+				bell_duration = DEFAULT_BELL_DURATION;
+			break;
+		case 12: /* bring specified console to the front */
+			if (par[1] >= 1 && vc_cons_allocated(par[1]-1))
+				update_screen(par[1]-1);
+			break;
+		case 13: /* unblank the screen */
+			unblank_screen();
+			break;
+		case 14: /* set vesa powerdown interval */
+			vesa_off_interval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
+			break;
+	}
+}
+
+static void insert_char(int currcons)
+{
+	int i;
+	unsigned short *p = pos;
+
+	for (i = cols - x - 2; i >= 0; i--)
+	  p[i + 1] = p[i];
+	*pos = video_erase_char;
+	need_wrap = 0;
+
+	if (currcons != fg_console)
+	  return;
+
+	/* Arno:
+	 * Move the remainder of the line (-1 character) one spot to the right
+	 */
+	sw->con_bmove(vc_cons[currcons].d,y,x,y,x+1,1,(cols-x-1));
+	/*
+	 * Print the erase char on the current position
+	 */
+	sw->con_putc(vc_cons[currcons].d,(video_erase_char & 0x00ff),y,x);
+}
+
+static void csi_at(int currcons, unsigned int nr)
+{
+	int i;
+	unsigned short *p;
+
+	if (nr > cols - x)
+		nr = cols - x;
+	else if (!nr)
+		nr = 1;
+
+	p = pos + cols - x - nr;
+	while (--p >= pos)
+	  p[nr] = *p;
+	for (i = 0; i < nr; i++)
+	  *++p = video_erase_char;
+	need_wrap = 0;
+
+	if (currcons != fg_console)
+	  return;
+
+	sw->con_bmove (vc_cons[currcons].d, y, x, y, x + nr,
+		       1, cols - x - nr);
+	while (nr--)
+	  sw->con_putc (vc_cons[currcons].d, video_erase_char & 0x00ff,
+			y, x + nr);
+}
+
+static void csi_L(int currcons, unsigned int nr)
+{
+	if (nr > rows)
+		nr = rows;
+	else if (!nr)
+		nr = 1;
+	scrdown (currcons, y, bottom, nr);
+	need_wrap = 0;
+}
+
+static void csi_P(int currcons, unsigned int nr)
+{
+	int i;
+	unsigned short *p, *end;
+
+	if (nr > cols - x)
+		nr = cols - x;
+	else if (!nr)
+		nr = 1;
+
+	p = pos;
+	end = pos + cols - x - nr;
+	while (p < end)
+	  *p = p[nr], p++;
+	for (i = 0; i < nr; i++)
+	  *p++ = video_erase_char;
+	need_wrap = 0;
+
+	if (currcons != fg_console)
+	  return;
+
+	sw->con_bmove (vc_cons[currcons].d, y, x + nr, y, x,
+		       1, cols - x - nr);
+
+	while (nr--)
+	  sw->con_putc (vc_cons[currcons].d, video_erase_char & 0x00ff,
+			y, cols - 1 - nr);
+}
+
+static void csi_M(int currcons, unsigned int nr)
+{
+	if (nr > rows)
+		nr = rows;
+	else if (!nr)
+		nr=1;
+	scrup (currcons, y, bottom, nr);
+	need_wrap = 0;
+}
+
+static void save_cur(int currcons)
+{
+	saved_x		= x;
+	saved_y		= y;
+	s_intensity	= intensity;
+	s_underline	= underline;
+	s_blink		= blink;
+	s_reverse	= reverse;
+	s_charset	= charset;
+	s_color		= color;
+	saved_G0	= G0_charset;
+	saved_G1	= G1_charset;
+}
+
+static void restore_cur(int currcons)
+{
+	gotoxy(currcons,saved_x,saved_y);
+	intensity	= s_intensity;
+	underline	= s_underline;
+	blink		= s_blink;
+	reverse		= s_reverse;
+	charset		= s_charset;
+	color		= s_color;
+	G0_charset	= saved_G0;
+	G1_charset	= saved_G1;
+	translate	= set_translate(charset ? G1_charset : G0_charset);
+	update_attr(currcons);
+	need_wrap = 0;
+}
+
+enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey, 
+	EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
+	ESpalette };
+
+static void reset_terminal(int currcons, int do_clear)
+{
+	top		= 0;
+	bottom		= rows;
+	vc_state	= ESnormal;
+	ques		= 0;
+	translate	= set_translate(LAT1_MAP);
+	G0_charset	= LAT1_MAP;
+	G1_charset	= GRAF_MAP;
+	charset		= 0;
+	need_wrap	= 0;
+	report_mouse	= 0;
+	utf             = 0;
+	utf_count       = 0;
+
+	disp_ctrl	= 0;
+	toggle_meta	= 0;
+
+	decscnm		= 0;
+	decom		= 0;
+	decawm		= 1;
+	deccm		= 1;
+	decim		= 0;
+
+	set_kbd(decarm);
+	clr_kbd(decckm);
+	clr_kbd(kbdapplic);
+	clr_kbd(lnm);
+	kbd_table[currcons].lockstate = 0;
+	kbd_table[currcons].slockstate = 0;
+	kbd_table[currcons].ledmode = LED_SHOW_FLAGS;
+	kbd_table[currcons].ledflagstate = kbd_table[currcons].default_ledflagstate;
+	set_leds();
+
+	default_attr(currcons);
+	update_attr(currcons);
+
+	tab_stop[0]	= 0x01010100;
+	tab_stop[1]	=
+	tab_stop[2]	=
+	tab_stop[3]	=
+	tab_stop[4]	= 0x01010101;
+
+	bell_pitch = DEFAULT_BELL_PITCH;
+	bell_duration = DEFAULT_BELL_DURATION;
+
+	gotoxy(currcons,0,0);
+	save_cur(currcons);
+	if (do_clear)
+	    csi_J(currcons,2);
+}
+
+/*
+ * Turn the Scroll-Lock LED on when the tty is stopped
+ */
+static void con_stop(struct tty_struct *tty)
+{
+	int console_num;
+	if (!tty)
+		return;
+	console_num = MINOR(tty->device) - (tty->driver.minor_start);
+	if (!vc_cons_allocated(console_num))
+		return;
+	set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
+	set_leds();
+}
+
+/*
+ * Turn the Scroll-Lock LED off when the console is started
+ */
+static void con_start(struct tty_struct *tty)
+{
+	int console_num;
+	if (!tty)
+		return;
+	console_num = MINOR(tty->device) - (tty->driver.minor_start);
+	if (!vc_cons_allocated(console_num))
+		return;
+	clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
+	set_leds();
+}
+
+static int con_write(struct tty_struct * tty, int from_user,
+		     const unsigned char *buf, int count)
+{
+	int c, tc, ok, n = 0;
+	unsigned int currcons;
+	struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
+
+	currcons = vt->vc_num;
+	if (!vc_cons_allocated(currcons)) {
+		/* could this happen? */
+		static int error = 0;
+		if (!error) {
+			error = 1;
+			printk("con_write: tty %d not allocated\n", currcons+1);
+		}
+		return 0;
+	}
+
+	/* undraw cursor first */
+	if (currcons == fg_console)
+		hide_cursor(currcons);
+	
+	/* clear the selection */
+	if (currcons == sel_cons)
+		clear_selection();
+
+        disable_bh(CONSOLE_BH);
+	while (count) {
+		enable_bh(CONSOLE_BH);
+		c = from_user ? get_user(buf) : *buf;
+		buf++; n++; count--;
+		disable_bh(CONSOLE_BH);
+
+		if (utf) {
+		    /* Combine UTF-8 into Unicode */
+		    /* Incomplete characters silently ignored */
+		    if(c > 0x7f) {   
+			if (utf_count > 0 && (c & 0xc0) == 0x80) {
+				utf_char = (utf_char << 6) | (c & 0x3f);
+				utf_count--;
+				if (utf_count == 0)
+				    tc = c = utf_char;
+				else continue;
+			} else {
+				if ((c & 0xe0) == 0xc0) {
+				    utf_count = 1;
+				    utf_char = (c & 0x1f);
+				} else if ((c & 0xf0) == 0xe0) {
+				    utf_count = 2;
+				    utf_char = (c & 0x0f);
+				} else if ((c & 0xf8) == 0xf0) {
+				    utf_count = 3;
+				    utf_char = (c & 0x07);
+				} else if ((c & 0xfc) == 0xf8) {
+				    utf_count = 4;
+				    utf_char = (c & 0x03);
+				} else if ((c & 0xfe) == 0xfc) {
+				    utf_count = 5;
+				    utf_char = (c & 0x01);
+				} else
+				    utf_count = 0;
+				continue;
+			}
+		    } else {
+			tc = c;
+			utf_count = 0;
+		    }
+		} else {	/* no utf */
+		    tc = translate[toggle_meta ? (c|0x80) : c];
+		}
+
+                /* If the original code was a control character we
+                 * only allow a glyph to be displayed if the code is
+                 * not normally used (such as for cursor movement) or
+                 * if the disp_ctrl mode has been explicitly enabled.
+                 * Certain characters (as given by the CTRL_ALWAYS
+                 * bitmap) are always displayed as control characters,
+                 * as the console would be pretty useless without
+                 * them; to display an arbitrary font position use the
+                 * direct-to-font zone in UTF-8 mode.
+                 */
+                ok = tc && (c >= 32 ||
+                            (!utf && !(((disp_ctrl ? CTRL_ALWAYS
+                                         : CTRL_ACTION) >> c) & 1)))
+                        && (c != 127 || disp_ctrl);
+
+		if (vc_state == ESnormal && ok) {
+			/* Now try to find out how to display it */
+			tc = conv_uni_to_pc(tc);
+			if ( tc == -4 ) {
+                                /* If we got -4 (not found) then see if we have
+                                   defined a replacement character (U+FFFD) */
+                                tc = conv_uni_to_pc(0xfffd);
+                        } else if ( tc == -3 ) {
+                                /* Bad hash table -- hope for the best */
+                                tc = c;
+                        }
+			if (tc & ~console_charmask)
+				continue; /* Conversion failed */
+
+			if (need_wrap) {
+				cr(currcons);
+				lf(currcons);
+			}
+			
+#if 1 /* XXX */
+                        /* DPC: 1994-04-12
+                         *   Speed up overstrike mode, using new putcs.
+                         *
+                         * P.S. I hate 8 spaces per tab! Use Emacs!
+			 */
+			
+			/* Only use this for the foreground console,
+                           where we really draw the chars */
+
+                        if (count > 2 &&
+			    !decim && !utf && currcons == fg_console) { 
+				static char putcs_buf[256];
+				char   *p     = putcs_buf;
+				int putcs_count  = 1;
+				ushort nextx  = x + 1;
+
+				*p++ = tc;
+				*pos++ = tc | (attr << 8);
+				
+				if (nextx == cols) {
+					sw->con_putc(vc_cons[currcons].d,
+						     *putcs_buf, y, x);
+					pos--;
+					need_wrap = decawm;
+					continue;
+				}
+				
+				/* TAB TAB TAB - Arghh!!!! */
+				
+				while (count)
+				{
+					enable_bh(CONSOLE_BH);
+					c = from_user ? get_user(buf) : *buf;
+					disable_bh(CONSOLE_BH);
+					tc = translate[toggle_meta ? (c|0x80) : c];
+					if (!tc ||
+					    !(c >= 32
+					      || !(((disp_ctrl ? CTRL_ALWAYS
+						   : CTRL_ACTION) >> c) & 1)))
+					  break;
+					tc = conv_uni_to_pc(tc);
+					if (tc == -4)
+					  tc = conv_uni_to_pc(0xfffd);
+					else if (tc == -3)
+					  tc = c;
+
+					buf++; n++; count--;
+					if (tc & ~console_charmask)
+					  continue; /* Conversion failed */
+
+					*p++ = tc;
+					*pos++ = tc | (attr << 8);
+					++putcs_count;
+					++nextx;
+					if (nextx == cols || 
+					    putcs_count == sizeof (putcs_buf))
+						break;
+				}
+				
+				sw->con_putcs(vc_cons[currcons].d,
+					      putcs_buf, putcs_count, y, x);
+				if (nextx == cols) {
+					pos--;
+					x         = cols-1;
+					need_wrap = decawm;
+				} else
+					x += putcs_count;
+				continue;
+                        }
+			
+                        /* DPC: End of putcs support */
+#endif
+			
+			if (decim)
+				insert_char(currcons);
+			*pos = (attr << 8) + tc;
+			if (currcons == fg_console)
+				sw->con_putc(vc_cons[currcons].d,tc,y,x);
+			if (x == cols - 1)
+				need_wrap = decawm;
+			else {
+				pos++;
+				x++;
+			}
+			continue;
+		}
+
+		/*
+		 *  Control characters can be used in the _middle_
+		 *  of an escape sequence.
+		 */
+		switch (c) {
+		    case 7:
+			if (bell_duration)
+			    kd_mksound(bell_pitch, bell_duration);
+			continue;
+		    case 8:
+			bs(currcons);
+			continue;
+		    case 9:
+			pos -= x;
+			while (x < cols - 1) {
+				x++;
+				if (tab_stop[x >> 5] & (1 << (x & 31)))
+					break;
+			}
+			pos += x;
+			continue;
+		    case 10: case 11: case 12:
+			lf(currcons);
+			if (!is_kbd(lnm))
+				continue;
+		    case 13:
+			cr(currcons);
+			continue;
+  			case 14:
+			charset = 1;
+			translate = set_translate(G1_charset);
+			disp_ctrl = 1;
+			continue;
+		    case 15:
+			charset = 0;
+			translate = set_translate(G0_charset);
+			disp_ctrl = 0;
+			continue;
+		    case 24: case 26:
+			vc_state = ESnormal;
+			continue;
+		    case 27:
+			vc_state = ESesc;
+			continue;
+		    case 127:
+			del(currcons);
+			continue;
+		    case 128+27:
+			vc_state = ESsquare;
+			continue;
+		}
+		switch(vc_state) {
+		    case ESesc:
+			vc_state = ESnormal;
+			switch (c) {
+			    case '[':
+				vc_state = ESsquare;
+				continue;
+			    case ']':
+				vc_state = ESnonstd;
+				continue;
+			    case '%':
+				vc_state = ESpercent;
+				continue;
+			    case 'E':
+				cr(currcons);
+				lf(currcons);
+				continue;
+			    case 'M':
+				ri(currcons);
+				continue;
+			    case 'D':
+				lf(currcons);
+				continue;
+			    case 'H':
+				tab_stop[x >> 5] |= (1 << (x & 31));
+				continue;
+			    case 'Z':
+				respond_ID(tty);
+				continue;
+			    case '7':
+				save_cur(currcons);
+				continue;
+			    case '8':
+				restore_cur(currcons);
+				continue;
+			    case '(':
+				vc_state = ESsetG0;
+				continue;
+			    case ')':
+				vc_state = ESsetG1;
+				continue;
+			    case '#':
+				vc_state = EShash;
+				continue;
+			    case 'c':
+				reset_terminal(currcons,1);
+				continue;
+			    case '>':  /* Numeric keypad */
+				clr_kbd(kbdapplic);
+				continue;
+			    case '=':  /* Appl. keypad */
+				set_kbd(kbdapplic);
+				continue;
+			}	
+			continue;
+		    case ESnonstd:
+			if (c=='P') {   /* palette escape sequence */
+			    for (npar=0; npar<NPAR; npar++)
+				par[npar] = 0 ;
+			    npar = 0 ;
+			    vc_state = ESpalette;
+			    continue;
+			} else if (c=='R') {   /* reset palette */
+#if 0
+			    reset_palette (currcons);
+#endif
+			    vc_state = ESnormal;
+			} else
+			    vc_state = ESnormal;
+			continue;
+		case ESpalette:
+			if ( (c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) {
+			    par[npar++] = (c>'9' ? (c&0xDF)-'A'+10 : c-'0') ;
+			    if (npar==7) {
+#if 0
+				int i = par[0]*3, j = 1;
+				palette[i] = 16*par[j++];
+				palette[i++] += par[j++];
+				palette[i] = 16*par[j++];
+				palette[i++] += par[j++];
+				palette[i] = 16*par[j++];
+				palette[i] += par[j];
+				set_palette() ;
+#endif
+				vc_state = ESnormal;
+			    }
+			} else
+			    vc_state = ESnormal;
+			continue;
+		    case ESsquare:
+			for(npar = 0 ; npar < NPAR ; npar++)
+				par[npar] = 0;
+			npar = 0;
+			vc_state = ESgetpars;
+			if (c == '[') { /* Function key */
+				vc_state=ESfunckey;
+				continue;
+			}
+			ques = (c=='?');
+			if (ques)
+				continue;
+		    case ESgetpars:
+			if (c==';' && npar<NPAR-1) {
+				npar++;
+				continue;
+			} else if (c>='0' && c<='9') {
+				par[npar] *= 10;
+				par[npar] += c-'0';
+				continue;
+			} else vc_state=ESgotpars;
+		    case ESgotpars:
+			vc_state = ESnormal;
+			switch(c) {
+			    case 'h':
+				set_mode(currcons,1);
+				continue;
+			    case 'l':
+				set_mode(currcons,0);
+				continue;
+			    case 'n':
+				if (!ques)
+					if (par[0] == 5)
+						status_report(tty);
+					else if (par[0] == 6)
+						cursor_report(currcons,tty);
+				continue;
+			}
+			if (ques) {
+				ques = 0;
+				continue;
+			}
+			switch(c) {
+			    case 'G': case '`':
+				if (par[0]) par[0]--;
+				gotoxy(currcons,par[0],y);
+				continue;
+			    case 'A':
+				if (!par[0]) par[0]++;
+				gotoxy(currcons,x,y-par[0]);
+				continue;
+			    case 'B': case 'e':
+				if (!par[0]) par[0]++;
+				gotoxy(currcons,x,y+par[0]);
+				continue;
+			    case 'C': case 'a':
+				if (!par[0]) par[0]++;
+				gotoxy(currcons,x+par[0],y);
+				continue;
+			    case 'D':
+				if (!par[0]) par[0]++;
+				gotoxy(currcons,x-par[0],y);
+				continue;
+			    case 'E':
+				if (!par[0]) par[0]++;
+				gotoxy(currcons,0,y+par[0]);
+				continue;
+			    case 'F':
+				if (!par[0]) par[0]++;
+				gotoxy(currcons,0,y-par[0]);
+				continue;
+			    case 'd':
+				if (par[0]) par[0]--;
+				gotoxay(currcons,x,par[0]);
+				continue;
+			    case 'H': case 'f':
+				if (par[0]) par[0]--;
+				if (par[1]) par[1]--;
+				gotoxay(currcons,par[1],par[0]);
+				continue;
+			    case 'J':
+				csi_J(currcons,par[0]);
+				continue;
+			    case 'K':
+				csi_K(currcons,par[0]);
+				continue;
+			    case 'L':
+				csi_L(currcons,par[0]);
+				continue;
+			    case 'M':
+				csi_M(currcons,par[0]);
+				continue;
+			    case 'P':
+				csi_P(currcons,par[0]);
+				continue;
+			    case 'c':
+				if (!par[0])
+					respond_ID(tty);
+				continue;
+			    case 'g':
+				if (!par[0])
+					tab_stop[x >> 5] &= ~(1 << (x & 31));
+				else if (par[0] == 3) {
+					tab_stop[0] =
+						tab_stop[1] =
+							tab_stop[2] =
+								tab_stop[3] =
+									tab_stop[4] = 0;
+				}
+				continue;
+			    case 'm':
+				csi_m(currcons);
+				continue;
+			    case 'q': /* DECLL - but only 3 leds */
+				/* map 0,1,2,3 to 0,1,2,4 */
+				if (par[0] < 4)
+					setledstate(kbd_table + currcons,
+						    (par[0] < 3) ? par[0] : 4);
+				continue;
+			    case 'r':
+				if (!par[0])
+					par[0]++;
+				if (!par[1])
+					par[1] = rows;
+				/* Minimum allowed region is 2 lines */
+				if (par[0] < par[1] &&
+				    par[1] <= rows) {
+					top=par[0]-1;
+					bottom=par[1];
+					gotoxay(currcons,0,0);
+				}
+				continue;
+			    case 's':
+				save_cur(currcons);
+				continue;
+			    case 'u':
+				restore_cur(currcons);
+				continue;
+			    case 'X':
+				csi_X(currcons, par[0]);
+				continue;
+			    case '@':
+				csi_at(currcons,par[0]);
+				continue;
+			    case ']': /* setterm functions */
+				setterm_command(currcons);
+				continue;
+			}
+			continue;
+		    case ESpercent:
+			vc_state = ESnormal;
+			switch (c) {
+			    case '@':  /* defined in ISO 2022 */
+				utf = 0;
+				continue;
+			    case 'G':  /* prelim official escape code */
+			    case '8':  /* retained for compatibility */
+				utf = 1;
+				continue;
+			}
+			continue;
+		    case ESfunckey:
+			vc_state = ESnormal;
+			continue;
+		    case EShash:
+			vc_state = ESnormal;
+			if (c == '8') {
+				/* DEC screen alignment test. kludge :-) */
+				video_erase_char =
+					(video_erase_char & 0xff00) | 'E';
+				/* Arno:
+				 * Doesn't work, because csi_J(c,2)
+				 * calls con_clear and doesn't print
+				 * the erase char..
+				 */
+				csi_J(currcons, 2);
+				video_erase_char =
+					(video_erase_char & 0xff00) | ' ';
+			}
+			continue;
+		    case ESsetG0:
+			if (c == '0')
+				G0_charset = GRAF_MAP;
+			else if (c == 'B')
+				G0_charset = LAT1_MAP;
+			else if (c == 'U')
+				G0_charset = IBMPC_MAP;
+			else if (c == 'K')
+				G0_charset = USER_MAP;
+			if (charset == 0)
+				translate = set_translate(G0_charset);
+			vc_state = ESnormal;
+			continue;
+		    case ESsetG1:
+			if (c == '0')
+				G1_charset = GRAF_MAP;
+			else if (c == 'B')
+				G1_charset = LAT1_MAP;
+			else if (c == 'U')
+				G1_charset = IBMPC_MAP;
+			else if (c == 'K')
+				G1_charset = USER_MAP;
+			if (charset == 1)
+				translate = set_translate(G1_charset);
+			vc_state = ESnormal;
+			continue;
+		    default:
+			vc_state = ESnormal;
+		}
+	}
+	if (vcmode != KD_GRAPHICS)
+		set_cursor(currcons);
+	enable_bh(CONSOLE_BH);
+	return n;
+}
+
+static int con_write_room(struct tty_struct *tty)
+{
+	if (tty->stopped)
+		return 0;
+	return 4096;		/* No limit, really; we're not buffering */
+}
+
+static int con_chars_in_buffer(struct tty_struct *tty)
+{
+	return 0;		/* we're not buffering */
+}
+
+void poke_blanked_console(void)
+{
+	timer_active &= ~(1<<BLANK_TIMER);
+	if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
+		return;
+	if (console_blanked) {
+		timer_table[BLANK_TIMER].fn = unblank_screen;
+		timer_table[BLANK_TIMER].expires = 0;
+		timer_active |= 1<<BLANK_TIMER;
+	} else if (blankinterval) {
+		timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
+		timer_active |= 1<<BLANK_TIMER;
+	}
+}
+
+/* DPC: New version of console_print using putcs */
+
+void console_print(const char * b)
+{
+   int currcons = fg_console;
+   unsigned char c;
+   const char *start = b;
+   ushort count      = 0;
+   ushort myx        = x;
+   static int printing = 0;
+
+   if (!printable || printing)
+	   return;	 /* console not yet initialized */
+   printing = 1;
+
+   if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
+	   currcons = kmsg_redirect - 1;
+
+   if (!vc_cons_allocated(currcons)) {
+	   /* impossible */
+	   printk("console_print: tty %d not allocated ??\n", currcons+1);
+	   printing = 0;
+	   return;
+   }
+
+   /* undraw cursor first */
+   hide_cursor(currcons);
+
+   /* Contrived structure to try to emulate original need_wrap behaviour
+    * Problems caused when we have need_wrap set on '\n' character */
+   
+   while ((c = *(b++)) != 0) {
+       if (c == 10 || c == 13 || c == 8 || need_wrap) {
+           if ((count = b - start - 1) > 0) {
+               sw->con_putcs(vc_cons[currcons].d, start, count ,
+                             y, x);
+               x += count;
+	       if (need_wrap)
+		 x--;
+           }
+
+	   if (c == 8) {	/* backspace */
+	       bs(currcons);
+	       start = b;
+	       myx = x;
+	       continue;
+	   }
+           if (c != 13)
+               lf(currcons);
+           cr(currcons);
+
+           if (c == 10 || c == 13) {
+               start = b; myx = x; continue;
+           }
+
+           start = b-1; myx = x;
+       }
+
+       *pos = c | (attr << 8);
+       if (myx == cols - 1) {
+           need_wrap = 1;
+           continue;
+       }
+       pos++;
+       myx++;
+   }
+
+   if ((count = b - start -1) > 0) {
+       sw->con_putcs(vc_cons[currcons].d, start, count ,
+                     y, x);
+       x += count;
+       if (x == cols)
+	 {
+	   x--;
+           need_wrap = 1;
+	 }
+   }
+   
+   set_cursor(currcons);
+   poke_blanked_console();
+   printing = 0;
+}
+
+/* You didn't see this... */
+void console_printn(const char * b, int n)
+{
+   int i;
+   char buf[2];
+   
+   
+   buf[1] = '\0';
+   for(i=0;i<n;i++) {
+     buf[0] = *b++;
+     console_print(buf);
+   }
+}
+
+/*
+ * con_throttle and con_unthrottle are only used for
+ * paste_selection(), which has to stuff in a large number of
+ * characters...
+ */
+static void con_throttle(struct tty_struct *tty)
+{
+}
+
+static void con_unthrottle(struct tty_struct *tty)
+{
+	struct vt_struct *vt = (struct vt_struct *) tty->driver_data;
+
+	wake_up_interruptible(&vt->paste_wait);
+}
+
+static void vc_init(unsigned int currcons, int do_clear)
+{
+	long base = (long) vc_scrbuf[currcons];
+
+	pos = (unsigned short *)(origin = (ulong)video_mem_start = base);
+	scr_end = base + screenbuf_size;
+	video_mem_end = base + screenbuf_size;
+	reset_vc(currcons);
+	def_color       = 0x07;   /* white */
+	ulcolor		= 0x0f;   /* bold white */
+	halfcolor       = 0x08;   /* grey */
+	vt_cons[currcons]->paste_wait = 0;
+	reset_terminal(currcons, do_clear);
+}
+
+/*
+ * This is the console switching bottom half handler.
+ *
+ * Doing console switching in a bottom half handler allows
+ * us to do the switches asynchronously (needed when we want
+ * to switch due to a keyboard interrupt), while still giving
+ * us the option to easily disable it to avoid races when we
+ * need to write to the console.
+ */
+static void console_bh(void)
+{
+	if (want_console >= 0) {
+		if (want_console != fg_console) {
+			change_console(want_console);
+			/* we only changed when the console had already
+			   been allocated - a new console is not created
+			   in an interrupt routine */
+		}
+		want_console = -1;
+	}
+	if (do_poke_blanked_console) { /* do not unblank for a LED change */
+		do_poke_blanked_console = 0;
+		poke_blanked_console();
+	}
+}
+
+/*
+ *  unsigned long con_init(unsigned long);
+ *
+ * This routine initializes console interrupts, and does nothing
+ * else. If you want the screen to clear, call tty_write with
+ * the appropriate escape-sequence.
+ *
+ * Reads the information preserved by setup.s to determine the current display
+ * type and sets everything accordingly.
+ */
+unsigned long con_init(unsigned long kmem_start)
+{
+
+#ifdef CONFIG_FRAMEBUFFER
+
+#if 0 /* Disable console unless some buttons are pressed */
+	{
+		int i;
+		for(i=0;i<200000;i++) {
+			__asm__("nop");
+			if ((*(volatile unsigned char*)0xFFFFF419) & (8|1))
+				break;
+		}
+		
+		if (!((*(volatile unsigned char*)0xFFFFF419) & (8|1)))
+			return;
+		}
+	}
+#endif	
+	char *display_desc = "????";
+	unsigned int currcons = 0;
+	extern int serial_debug;
+
+
+	
+	memset(&console_driver, 0, sizeof(struct tty_driver));
+	console_driver.magic = TTY_DRIVER_MAGIC;
+	console_driver.name = "tty";
+	console_driver.name_base = 1;
+	console_driver.major = TTY_MAJOR;
+#ifdef CONFIG_PILOT_CONSOLE
+	console_driver.minor_start = 1;
+#else
+	console_driver.minor_start = 2;
+#endif
+	console_driver.num = MAX_NR_CONSOLES;
+	console_driver.type = TTY_DRIVER_TYPE_CONSOLE;
+	console_driver.init_termios = tty_std_termios;
+	console_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
+	console_driver.refcount = &console_refcount;
+	console_driver.table = console_table;
+	console_driver.termios = console_termios;
+	console_driver.termios_locked = console_termios_locked;
+
+	console_driver.open = con_open;
+	console_driver.write = con_write;
+	console_driver.write_room = con_write_room;
+	console_driver.chars_in_buffer = con_chars_in_buffer;
+	console_driver.ioctl = vt_ioctl;
+	console_driver.stop = con_stop;
+	console_driver.start = con_start;
+	console_driver.throttle = con_throttle;
+	console_driver.unthrottle = con_unthrottle;
+	
+	if (tty_register_driver(&console_driver))
+		panic("Couldn't register console driver\n");
+
+	kmem_start = conswitchp->con_startup (kmem_start, &display_desc);
+	/*conswitchp->con_set_font (&display_desc, 0, 0, "MINI4x6");*/
+	
+	timer_table[BLANK_TIMER].fn = blank_screen;
+	timer_table[BLANK_TIMER].expires = 0;
+	if (blankinterval) {
+		timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
+		timer_active |= 1<<BLANK_TIMER;
+	}
+
+	/* Due to kmalloc roundup allocating statically is more efficient -
+	   so provide MIN_NR_CONSOLES for people with very little memory */
+	for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
+		vc_cons[currcons].d = (struct vc_data *) kmem_start;
+		kmem_start += sizeof(struct vc_data);
+		vt_cons[currcons] = (struct vt_struct *) kmem_start;
+		kmem_start += sizeof(struct vt_struct);
+
+		/* ++Geert: sw->con_init determines console size */
+		sw = conswitchp;
+		cons_num = currcons;
+		sw->con_init (vc_cons[currcons].d);
+		size_row = cols<<1;
+		screenbuf_size = rows*size_row;
+
+		vc_scrbuf[currcons] = (unsigned short *) kmem_start;
+		kmem_start += screenbuf_size;
+		kmalloced = 0;
+		vc_init(currcons, currcons);
+	}
+
+	currcons = fg_console = 0;
+
+#ifdef CONFIG_PILOT_CONSOLE
+
+	gotoxy(currcons,0,rows-1);
+
+	csi_J(currcons, 0);
+	printable = 1;
+	/*update_screen(fg_console);*/
+	sw->con_cursor(vc_cons[currcons].d, CM_DRAW);
+	printable = 1;
+
+	/* If "serdebug" cmd line option was present, don't register for printk */
+	if (!serial_debug)
+		register_console(console_print);
+
+	printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n",
+		can_do_color ? "colour":"mono",
+		display_desc,
+		cols,rows,
+		MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s", MAX_NR_CONSOLES);
+#else
+	gotoxy(currcons,0, 0);
+	printable = 1;
+	sw->con_cursor(vc_cons[currcons].d, CM_DRAW);
+	printable = 1;
+
+	printk("Console driver (without boot console): %s %s %ldx%ld, %d virtual console%s (max %d)\n",
+		can_do_color ? "colour":"mono",
+		display_desc,
+		cols,rows,
+		MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s", MAX_NR_CONSOLES);
+#endif
+	init_bh(CONSOLE_BH, console_bh);
+#endif
+	return kmem_start;
+}
+
+void vesa_powerdown_screen(void)
+{
+	int currcons = fg_console;
+
+	timer_active &= ~(1<<BLANK_TIMER);
+	timer_table[BLANK_TIMER].fn = unblank_screen;
+
+	/* Power down if currently suspended (1 or 2),
+	 * suspend if currently blanked (0),
+	 * else do nothing (i.e. already powered down (3)).
+	 * Called only if powerdown features are allowed.
+	 */
+	switch (vesa_blank_mode) {
+	case 0:
+		sw->con_blank(2);
+		break;
+	case 1:
+	case 2:
+		sw->con_blank(4);
+		break;
+	}
+}
+
+void do_blank_screen(int nopowersave)
+{
+#if 0
+	int currcons;
+
+	if (console_blanked)
+		return;
+
+	if (!vc_cons_allocated(fg_console)) {
+		/* impossible */
+		printk("blank_screen: tty %d not allocated ??\n", fg_console+1);
+		return;
+	}
+
+	/* don't blank graphics */
+	if (vt_cons[fg_console]->vc_mode == KD_TEXT) {
+		if (vesa_off_interval && !nopowersave) {
+			timer_table[BLANK_TIMER].fn = vesa_powerdown_screen;
+			timer_table[BLANK_TIMER].expires = jiffies + vesa_off_interval;
+			timer_active |= (1<<BLANK_TIMER);
+		} else {
+			timer_active &= ~(1<<BLANK_TIMER);
+			timer_table[BLANK_TIMER].fn = unblank_screen;
+		}
+
+		/* try not to lose information by blanking,
+		   and not to waste memory */
+		currcons = fg_console;
+		has_scrolled = 0;
+		sw->con_blank(1);
+		if (!nopowersave)
+			sw->con_blank(vesa_blank_mode + 1);
+	}
+	else
+		hide_cursor(fg_console);
+ 	console_blanked = fg_console + 1;
+#endif
+}
+
+void do_unblank_screen(void)
+{
+#if 0
+	int currcons;
+
+	if (!console_blanked)
+		return;
+	if (!vc_cons_allocated(fg_console)) {
+		/* impossible */
+		printk("unblank_screen: tty %d not allocated ??\n", fg_console+1);
+		return;
+	}
+	timer_table[BLANK_TIMER].fn = blank_screen;
+	if (blankinterval) {
+		timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
+		timer_active |= 1<<BLANK_TIMER;
+	}
+
+	currcons = fg_console;
+  	console_blanked = 0;
+	if (sw->con_blank (0))
+		/* Low-level driver cannot restore -> do it ourselves */
+	  	update_screen( fg_console );
+	set_cursor (fg_console);
+#endif
+}
+
+void update_screen(int new_console)
+{
+	int currcons = fg_console;
+	int xx, yy, startx, attr_save;
+	char buf[256], *bufp;
+	unsigned short *p;
+	static int lock = 0;
+
+	if (/* new_console == fg_console || */ lock)
+		return;
+	if (!vc_cons_allocated(new_console)) {
+		/* strange ... */
+		printk("update_screen: tty %d not allocated ??\n", new_console+1);
+		return;
+	}
+	lock = 1;
+
+	clear_selection();
+
+	currcons = fg_console = new_console;
+	sw->con_cursor (vc_cons[currcons].d, CM_ERASE);
+	sw->con_switch (vc_cons[new_console].d);
+	/* Update the screen contents */
+	p = video_mem_start;
+	attr_save = attr;
+	for (yy = 0; yy < rows; yy++)
+	  {
+	    bufp = buf;
+	    for (startx = xx = 0; xx < cols; xx++)
+	      {
+		if (attr != ((*p >> 8) & 0xff))
+		  {
+		    if (bufp > buf)
+		      sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
+				     yy, startx);
+		    startx = xx;
+		    bufp = buf;
+		    attr = (*p >> 8) & 0xff;
+		  }
+		*bufp++ = *p++;
+		if (bufp == buf + sizeof (buf))
+		  {
+		    sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
+				   yy, startx);
+		    startx = xx + 1;
+		    bufp = buf;
+		  }
+	      }
+	    if (bufp > buf)
+	      sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
+			     yy, startx);
+	  }
+	set_cursor (currcons);
+	attr = attr_save;
+	set_leds();
+	compute_shiftstate();
+	lock = 0;
+}
+
+/*
+ * If a blank_screen is due to a timer, then a power save is allowed.
+ * If it is related to console_switching, then avoid vesa_blank().
+ */
+static void blank_screen(void)
+{
+	do_blank_screen(0);
+}
+
+static void unblank_screen(void)
+{
+	do_unblank_screen();
+}
+
+/*
+ * Allocate the console screen memory.
+ */
+int con_open(struct tty_struct *tty, struct file * filp)
+{
+	unsigned int currcons;
+	int i;
+
+	currcons = MINOR(tty->device) - tty->driver.minor_start;
+	
+	i = vc_allocate(currcons);
+	if (i)
+		return i;
+
+	vt_cons[currcons]->vc_num = currcons;
+	tty->driver_data = vt_cons[currcons];
+	
+	if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
+		tty->winsize.ws_row = rows;
+		tty->winsize.ws_col = cols;
+ 	}
+
+	return 0;
+}
+
+/*
+ * PIO_FONT support.
+ *
+ * Currently we only support 8 pixels wide fonts, at a maximum height
+ * of 32 pixels. Userspace fontdata is stored with 32 bytes reserved
+ * for each character which is kinda wasty, but this is done in order
+ * to maintain compatibility with the EGA/VGA fonts. It is upto the
+ * actual low-level console-driver convert data into its favorite
+ * format (maybe we should add a `fontoffset' field to the `display'
+ * structure so we wont have to convert the fontdata all the time.
+ * /Jes
+ */
+
+#define cmapsz 8192
+
+static int set_get_font(char * arg, int set, int ch512)
+{
+#ifdef CAN_LOAD_EGA_FONTS
+	int i, unit, size;
+	char *charmap;
+
+	if (arg){
+		i = verify_area(set ? VERIFY_READ : VERIFY_WRITE,
+				(void *)arg, ch512 ? 2*cmapsz : cmapsz);
+		if (i)
+			return i;
+	}else
+		return -EINVAL;
+
+
+	size = ch512 ? 2*cmapsz : cmapsz;
+
+	charmap = (char *)kmalloc(size, GFP_USER);
+
+	if (set){
+		memcpy_fromfs(charmap, arg, size);
+
+		for (unit = 32; unit > 0; unit--)
+			for (i = 0; i < (ch512 ? 512 : 256); i++)
+				if (charmap[32*i+unit-1])
+					goto nonzero;
+	nonzero:
+		i = conswitchp->con_set_font(vc_cons[fg_console].d, 8,
+					     unit, charmap);
+	}else{
+		memset(charmap, 0, size);
+		i = conswitchp->con_get_font(vc_cons[fg_console].d,
+					     &unit, &unit, charmap);
+		memcpy_tofs(arg, charmap, size);
+	}
+	kfree(charmap);
+
+	return i;
+#else
+	return -EINVAL;
+#endif
+}
+
+/*
+ * Load palette into the EGA/VGA DAC registers. arg points to a colour
+ * map, 3 bytes per colour, 16 colours, range from 0 to 255.
+ */
+
+int con_set_cmap (unsigned char *arg)
+{
+	return -EINVAL;
+}
+
+int con_get_cmap (unsigned char *arg)
+{
+	return -EINVAL;
+}
+
+void reset_palette(int currcons)
+{
+}
+
+void set_palette(void)
+{
+}
+
+/*
+ * Load font into the EGA/VGA character generator. arg points to a 8192
+ * byte map, 32 bytes per character. Only first H of them are used for
+ * 8xH fonts (0 < H <= 32).
+ */
+
+int con_set_font (char *arg, int ch512)
+{
+	int i;
+
+	i = set_get_font (arg,1,ch512);
+  	if ( !i ) {
+		hashtable_contents_valid = 0;
+      		video_mode_512ch = ch512;
+      		console_charmask = ch512 ? 0x1ff : 0x0ff;
+	}
+	return i;
+}
+
+int con_get_font (char *arg)
+{
+	return set_get_font (arg,0,video_mode_512ch);
+}
+
+/*
+ * Adjust the screen to fit a font of a certain height
+ *
+ * Returns < 0 for error, 0 if nothing changed, and the number
+ * of lines on the adjusted console if changed.
+ */
+int con_adjust_height(unsigned long fontheight)
+{
+	return -EINVAL;
+}
+
+void set_vesa_blanking(int arg)
+{
+	char *argp = (char *)arg + 1;
+	unsigned int mode = get_fs_byte(argp);
+	vesa_blank_mode = (mode < 4) ? mode : 0;
+}
+
+unsigned long get_video_num_lines(unsigned int currcons)
+{
+	return(rows);
+}
+
+unsigned long get_video_num_columns(unsigned int currcons)
+{
+	return(cols);
+}
+
+unsigned long get_video_size_row(unsigned int currcons)
+{
+	return(size_row);
+}
+
+/*
+ * Report the current status of the vc. This is exported to modules (ARub)
+ */
+
+int con_get_info(int *mode, int *shift, int *col, int *row,
+			struct tty_struct **tty)
+{
+	extern int shift_state;
+	extern struct tty_driver console_driver;
+	struct tty_struct **console_table=console_driver.table;
+
+	if (mode) *mode = vt_cons[fg_console]->vc_mode;
+	if (shift) *shift = shift_state;
+	if (col) *col = video_num_columns;
+	if (row) *row = video_num_lines;
+	if (tty) *tty = console_table[fg_console];
+	return fg_console;
+}
diff -urN linux-2.4.29/arch/frv/kernel/debug-stub.c linux-2.4.29-uc1/arch/frv/kernel/debug-stub.c
--- linux-2.4.29/arch/frv/kernel/debug-stub.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/debug-stub.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,236 @@
+/* debug-stub.c: debug-mode stub
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/serial_reg.h>
+
+#include <asm/system.h>
+#include <asm/serial-regs.h>
+#include <asm/timer-regs.h>
+#include <asm/irc-regs.h>
+#include <asm/gdb-stub.h>
+#include "gdb-io.h"
+
+/* CPU board CON5 */
+#define __UART0(X) (*(volatile uint8_t *)(UART0_BASE + (UART_##X)))
+
+#define LSR_WAIT_FOR0(STATE)			\
+do {						\
+} while (!(__UART0(LSR) & UART_LSR_##STATE))
+
+#define FLOWCTL_QUERY0(LINE)	({ __UART0(MSR) & UART_MSR_##LINE; })
+#define FLOWCTL_CLEAR0(LINE)	do { __UART0(MCR) &= ~UART_MCR_##LINE; } while (0)
+#define FLOWCTL_SET0(LINE)	do { __UART0(MCR) |= UART_MCR_##LINE; } while (0)
+
+#define FLOWCTL_WAIT_FOR0(LINE)			\
+do {						\
+	gdbstub_do_rx();			\
+} while(!FLOWCTL_QUERY(LINE))
+
+static void __init debug_stub_init(void);
+
+extern asmlinkage void __break_hijack_kernel_event(void);
+extern asmlinkage void __break_hijack_kernel_event_breaks_here(void);
+
+/*****************************************************************************/
+/*
+ * debug mode handler stub
+ * - we come here with the CPU in debug mode and with exceptions disabled
+ * - handle debugging services for userspace
+ */
+asmlinkage void debug_stub(void)
+{
+	int type = 0;
+
+	static u8 inited = 0;
+	if (!inited) {
+		debug_stub_init();
+		type = -1;
+		inited = 1;
+	}
+
+	/* disable single stepping */
+	__debug_regs->dcr &= ~DCR_SE;
+
+	/* kernel mode can propose an exception be handled in debug mode by jumping to a special
+	 * location */
+	if (__debug_frame->pc == (unsigned long) __break_hijack_kernel_event_breaks_here) {
+		/* replace the debug frame with the kernel frame and discard
+		 * the top kernel context */
+		*__debug_frame = *__frame;
+		__frame = __debug_frame->next_frame;
+		__debug_regs->brr = (__debug_frame->tbr & TBR_TT) << 12;
+		__debug_regs->brr |= BRR_EB;
+	}
+
+	if (__debug_frame->pc == (unsigned long) __debug_bug_trap + 4) {
+		__debug_frame->pc = __debug_frame->lr;
+		type = SIGABRT;
+	}
+
+#ifdef CONFIG_GDBSTUB
+	gdbstub(type);
+#endif
+
+} /* end debug_stub() */
+
+/*****************************************************************************/
+/*
+ * debug stub initialisation
+ */
+static void __init debug_stub_init(void)
+{
+	__set_IRR(6, 0xff000000);	/* map ERRs to NMI */
+	__set_IITMR(1, 0x20000000);	/* ERR0/1, UART0/1 IRQ detect levels */
+
+	asm volatile("	movgs	gr0,ibar0	\n"
+		     "	movgs	gr0,ibar1	\n"
+		     "	movgs	gr0,ibar2	\n"
+		     "	movgs	gr0,ibar3	\n"
+		     "	movgs	gr0,dbar0	\n"
+		     "	movgs	gr0,dbmr00	\n"
+		     "	movgs	gr0,dbmr01	\n"
+		     "	movgs	gr0,dbdr00	\n"
+		     "	movgs	gr0,dbdr01	\n"
+		     "	movgs	gr0,dbar1	\n"
+		     "	movgs	gr0,dbmr10	\n"
+		     "	movgs	gr0,dbmr11	\n"
+		     "	movgs	gr0,dbdr10	\n"
+		     "	movgs	gr0,dbdr11	\n"
+		     );
+
+	/* deal with debugging stub initialisation and initial pause */
+	if (__debug_frame->pc == (unsigned long) __debug_stub_init_break)
+		__debug_frame->pc = (unsigned long) start_kernel;
+
+#ifdef CONFIG_GDBSTUB
+	gdbstub_init();
+#endif
+
+	__clr_MASK_all();
+	__clr_MASK(15);
+	__clr_RC(15);
+
+} /* end debug_stub_init() */
+
+/*****************************************************************************/
+/*
+ * kernel "exit" trap for gdb stub
+ */
+void debug_stub_exit(int status)
+{
+
+#ifdef CONFIG_GDBSTUB
+	gdbstub_exit(status);
+#endif
+
+} /* end debug_stub_exit() */
+
+/*****************************************************************************/
+/*
+ * send string to serial port
+ */
+void debug_to_serial(const char *p, int n)
+{
+	char ch;
+
+	for (; n > 0; n--) {
+		ch = *p++;
+		FLOWCTL_SET0(DTR);
+		LSR_WAIT_FOR0(THRE);
+		// FLOWCTL_WAIT_FOR(CTS);
+
+		if (ch == 0x0a) {
+			__UART0(TX) = 0x0d;
+			mb();
+			LSR_WAIT_FOR0(THRE);
+			// FLOWCTL_WAIT_FOR(CTS);
+		}
+		__UART0(TX) = ch;
+		mb();
+
+		FLOWCTL_CLEAR0(DTR);
+	}
+
+} /* end debug_to_serial() */
+
+/*****************************************************************************/
+/*
+ * send string to serial port
+ */
+void debug_to_serial2(const char *fmt, ...)
+{
+	va_list va;
+	char buf[64];
+	int n;
+
+	va_start(va, fmt);
+	n = vsprintf(buf, fmt, va);
+	va_end(va);
+
+	debug_to_serial(buf, n);
+
+} /* end debug_to_serial2() */
+
+/*****************************************************************************/
+/*
+ * set up the ttyS0 serial port baud rate timers
+ */
+void __init console_set_baud(unsigned baud)
+{
+	unsigned value, high, low;
+	u8 lcr;
+
+	/* work out the divisor to give us the nearest higher baud rate */
+	value = __serial_clock_speed_HZ / 16 / baud;
+
+	/* determine the baud rate range */
+	high = __serial_clock_speed_HZ / 16 / value;
+	low = __serial_clock_speed_HZ / 16 / (value + 1);
+
+	/* pick the nearest bound */
+	if (low + (high - low) / 2 > baud)
+		value++;
+
+	lcr = __UART0(LCR);
+	__UART0(LCR) |= UART_LCR_DLAB;
+	mb();
+	__UART0(DLL) = value & 0xff;
+	__UART0(DLM) = (value >> 8) & 0xff;
+	mb();
+	__UART0(LCR) = lcr;
+	mb();
+
+} /* end console_set_baud() */
+
+/*****************************************************************************/
+/*
+ * 
+ */
+int __init console_get_baud(void)
+{
+	unsigned value;
+	u8 lcr;
+
+	lcr = __UART0(LCR);
+	__UART0(LCR) |= UART_LCR_DLAB;
+	mb();
+	value =  __UART0(DLM) << 8;
+	value |= __UART0(DLL);
+	__UART0(LCR) = lcr;
+	mb();
+
+	return value;
+} /* end console_get_baud() */
diff -urN linux-2.4.29/arch/frv/kernel/dma.c linux-2.4.29-uc1/arch/frv/kernel/dma.c
--- linux-2.4.29/arch/frv/kernel/dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/dma.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,567 @@
+/* dma.c: DMA controller management on FR401 and the like
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <asm/dma.h>
+#include <asm/gpio-regs.h>
+#include <asm/irc-regs.h>
+#include <asm/cpu-irqs.h>
+
+struct frv_dma_channel {
+	uint8_t			flags;
+#define FRV_DMA_FLAGS_AVAILABLE 0x00
+#define FRV_DMA_FLAGS_RESERVED	0x01
+#define FRV_DMA_FLAGS_INUSE	0x02
+#define FRV_DMA_FLAGS_PAUSED	0x04
+#define FRV_DMA_FLAGS_DREQ	0x08		/* setting of SIR bit */
+#define FRV_DMA_FLAGS_DACK	0x10		/* setting of SOR bit */
+#define FRV_DMA_FLAGS_DONE	0x20		/* setting of SOR bit */
+#define FRV_DMA_IOBITS		0x38		/* mask for SIR & SOR sttngs */
+	uint8_t			cap;		/* capabilities available */
+	int			irq;		/* completion IRQ */
+	uint32_t		sirdreqbit;		
+	uint32_t		sordackbit;		
+	uint32_t		sordonebit;		
+	uint32_t		gpdrdreqbit;		
+	uint32_t		gpdrdackbit;		
+	uint32_t		gpdrdonebit;		
+	int			cnflct_msk;	/* possible channel conflict */
+	int			cnflct_chn;	/* possible channel conflict */
+	int			cnflct_chnmsk;	/* possible channel conflict */
+	const unsigned long	ioaddr;		/* DMA controller regs addr */
+	const char		*devname;
+	dma_irq_handler_t	handler;
+	void			*data;
+};
+
+
+#define __get_DMAC(IO,X)	({ *(volatile unsigned long *)((IO) + DMAC_##X##x); })
+
+#define __set_DMAC(IO,X,V)					\
+do {								\
+	*(volatile unsigned long *)((IO) + DMAC_##X##x) = (V);	\
+	mb();							\
+} while(0)
+
+#define ___set_DMAC(IO,X,V)					\
+do {								\
+	*(volatile unsigned long *)((IO) + DMAC_##X##x) = (V);	\
+} while(0)
+
+
+static struct frv_dma_channel frv_dma_channels[FRV_DMA_NCHANS] = {
+	[0] = {
+		.cap		= FRV_DMA_CAP_DREQ | FRV_DMA_CAP_DACK | FRV_DMA_CAP_DONE,
+		.irq		= IRQ_CPU_DMA0,
+		.sirdreqbit	= SIR_DREQ0_INPUT,
+		.sordackbit	= SOR_DACK0_OUTPUT,
+		.sordonebit	= SOR_DONE0_OUTPUT,
+		.gpdrdreqbit	= GPDR_DREQ0_BIT,
+		.gpdrdackbit	= GPDR_DACK0_BIT,
+		.gpdrdonebit	= GPDR_DONE0_BIT,
+		.cnflct_msk	= FRV_DMA_FLAGS_DONE,
+		.cnflct_chn	= 4,
+		.cnflct_chnmsk	= FRV_DMA_FLAGS_DREQ,
+		.ioaddr		= 0xfe000900,
+	},
+	[1] = {
+		.cap		= FRV_DMA_CAP_DREQ | FRV_DMA_CAP_DACK | FRV_DMA_CAP_DONE,
+		.irq		= IRQ_CPU_DMA1,
+		.sirdreqbit	= SIR_DREQ1_INPUT,
+		.sordackbit	= SOR_DACK1_OUTPUT,
+		.sordonebit	= SOR_DONE1_OUTPUT,
+		.gpdrdreqbit	= GPDR_DREQ1_BIT,
+		.gpdrdackbit	= GPDR_DACK1_BIT,
+		.gpdrdonebit	= GPDR_DONE1_BIT,
+		.cnflct_msk	= FRV_DMA_FLAGS_DONE,
+		.cnflct_chn	= 5,
+		.cnflct_chnmsk	= FRV_DMA_FLAGS_DREQ,
+		.ioaddr		= 0xfe000980,
+	},
+	[2] = {
+		.cap		= FRV_DMA_CAP_DREQ | FRV_DMA_CAP_DACK,
+		.irq		= IRQ_CPU_DMA2,
+		.sirdreqbit	= SIR_DREQ2_INPUT,
+		.sordackbit	= SOR_DACK2_OUTPUT,
+		.gpdrdreqbit	= GPDR_DREQ2_BIT,
+		.gpdrdackbit	= GPDR_DACK2_BIT,
+		.cnflct_msk	= FRV_DMA_FLAGS_DACK,
+		.cnflct_chn	= 6,
+		.cnflct_chnmsk	= FRV_DMA_FLAGS_DREQ,
+		.ioaddr		= 0xfe000a00,
+	},
+	[3] = {
+		.cap		= FRV_DMA_CAP_DREQ | FRV_DMA_CAP_DACK,
+		.irq		= IRQ_CPU_DMA3,
+		.sirdreqbit	= SIR_DREQ3_INPUT,
+		.sordackbit	= SOR_DACK3_OUTPUT,
+		.gpdrdreqbit	= GPDR_DREQ3_BIT,
+		.gpdrdackbit	= GPDR_DACK3_BIT,
+		.cnflct_msk	= FRV_DMA_FLAGS_DACK,
+		.cnflct_chn	= 7,
+		.cnflct_chnmsk	= FRV_DMA_FLAGS_DREQ,
+		.ioaddr		= 0xfe000a80,
+	},
+	[4] = {
+		.cap		= FRV_DMA_CAP_DREQ,
+		.irq		= IRQ_CPU_DMA4,
+		.sirdreqbit	= SIR_DREQ4_INPUT,
+		.gpdrdreqbit	= GPDR_DREQ4_BIT,
+		.cnflct_msk	= FRV_DMA_FLAGS_DREQ,
+		.cnflct_chn	= 0,
+		.cnflct_chnmsk	= FRV_DMA_FLAGS_DONE,
+		.ioaddr		= 0xfe001000,
+	},
+	[5] = {
+		.cap		= FRV_DMA_CAP_DREQ,
+		.irq		= IRQ_CPU_DMA5,
+		.sirdreqbit	= SIR_DREQ5_INPUT,
+		.gpdrdreqbit	= GPDR_DREQ5_BIT,
+		.cnflct_msk	= FRV_DMA_FLAGS_DREQ,
+		.cnflct_chn	= 1,
+		.cnflct_chnmsk	= FRV_DMA_FLAGS_DONE,
+		.ioaddr		= 0xfe001080,
+	},
+	[6] = {
+		.cap		= FRV_DMA_CAP_DREQ,
+		.irq		= IRQ_CPU_DMA6,
+		.sirdreqbit	= SIR_DREQ6_INPUT,
+		.gpdrdreqbit	= GPDR_DREQ6_BIT,
+		.cnflct_msk	= FRV_DMA_FLAGS_DREQ,
+		.cnflct_chn	= 2,
+		.cnflct_chnmsk	= FRV_DMA_FLAGS_DACK,
+		.ioaddr		= 0xfe001100,
+	},
+	[7] = {
+		.cap		= FRV_DMA_CAP_DREQ,
+		.irq		= IRQ_CPU_DMA7,
+		.sirdreqbit	= SIR_DREQ7_INPUT,
+		.gpdrdreqbit	= GPDR_DREQ7_BIT,
+		.cnflct_msk	= FRV_DMA_FLAGS_DREQ,
+		.cnflct_chn	= 3,
+		.cnflct_chnmsk	= FRV_DMA_FLAGS_DACK,
+		.ioaddr		= 0xfe001180,
+	},
+};
+
+static rwlock_t frv_dma_channels_lock = RW_LOCK_UNLOCKED;
+
+unsigned long frv_dma_inprogress;
+
+#define frv_clear_dma_inprogress(channel) \
+	atomic_clear_mask(1 << (channel), &frv_dma_inprogress);
+
+#define frv_set_dma_inprogress(channel) \
+	atomic_set_mask(1 << (channel), &frv_dma_inprogress);
+
+/*****************************************************************************/
+/*
+ * DMA irq handler - determine channel involved, grab status and call real handler
+ */
+static void dma_irq_handler(int irq, void *_channel, struct pt_regs *regs)
+{
+	struct frv_dma_channel *channel = _channel;
+
+	frv_clear_dma_inprogress(channel - frv_dma_channels);
+	channel->handler(channel - frv_dma_channels,
+			 __get_DMAC(channel->ioaddr, CSTR),
+			 channel->data,
+			 regs);
+} /* end dma_irq_handler() */
+
+
+
+/*****************************************************************************/
+/*
+ * Determine which DMA controllers are present on this CPU
+ */
+void __init frv_dma_init(void)
+{
+	unsigned long psr = __get_PSR();
+	int i;
+	int num_dma;
+	uint32_t val;
+
+	/* First, determine how many DMA channels are available */
+	switch (PSR_IMPLE(psr)) {
+
+	case PSR_IMPLE_FR405:
+	case PSR_IMPLE_FR451:
+	case PSR_IMPLE_FR501:
+	case PSR_IMPLE_FR551:
+		num_dma = FRV_DMA_8CHANS;
+		break;
+
+	case PSR_IMPLE_FR401:
+	default:
+		num_dma = FRV_DMA_4CHANS;
+		break;
+	}
+
+	/* Now mark all of the non-existent channels as reserved */
+	for(i = num_dma; i < FRV_DMA_NCHANS; i++) {
+		frv_dma_channels[i].flags = FRV_DMA_FLAGS_RESERVED;
+	}
+
+	/* Set SIR/SOR bits to an initial state so that H/W conflicts */
+	/* are not created as we allocate DMA channels */
+	val = __get_SIR();
+	val &= ~SIR_DREQ_BITS;
+	__set_SIR(val);
+
+	val = __get_SOR();
+	val &= ~(SOR_DONE_BITS | SOR_DACK_BITS);
+	__set_SOR(val);
+}
+
+/*****************************************************************************/
+/*
+ * allocate a DMA controller channel and the IRQ associated with it
+ */
+int frv_dma_open(const char *devname,
+		 unsigned long dmamask,
+		 int dmacap,
+		 dma_irq_handler_t handler,
+		 unsigned long irq_flags,
+		 void *data)
+{
+	struct frv_dma_channel *channel;
+	int dma, ret;
+	uint32_t val, gpdr;
+	uint8_t flags = 0;
+	int other;
+
+	if(dmacap & FRV_DMA_CAP_DREQ)
+		flags |= FRV_DMA_FLAGS_DREQ;
+	if(dmacap & FRV_DMA_CAP_DACK)
+		flags |= FRV_DMA_FLAGS_DACK;
+	if(dmacap & FRV_DMA_CAP_DONE)
+		flags |= FRV_DMA_FLAGS_DONE;
+
+	write_lock(&frv_dma_channels_lock);
+
+	ret = -ENOSPC;
+
+	for (dma = FRV_DMA_NCHANS - 1; dma >= 0; dma--) {
+		channel = &frv_dma_channels[dma];
+
+		if (!test_bit(dma, &dmamask))
+			continue;
+
+		if ((channel->cap & dmacap) != dmacap)
+			continue;
+
+		if (frv_dma_channels[dma].flags)
+			continue;
+
+		/* check for possible conflict in settings of SIR/SOR */
+		/* registers.  A GPIO pin can not be used for input and */
+		/* output simultaneously */
+		if(flags & frv_dma_channels[dma].cnflct_msk) {
+			other = frv_dma_channels[dma].cnflct_chn;
+			if((frv_dma_channels[dma].cnflct_chnmsk &
+			    frv_dma_channels[other].flags) == 0)
+				/* no conflict */
+				goto found;
+		} else {
+			goto found;
+		}
+	}
+
+	goto out;
+
+ found:
+	ret = request_irq(channel->irq, dma_irq_handler, irq_flags, devname, channel);
+	if (ret < 0)
+		goto out;
+
+	/* okay, we've allocated all the resources */
+	channel = &frv_dma_channels[dma];
+
+	channel->flags		|= (FRV_DMA_FLAGS_INUSE | flags);
+	channel->devname	= devname;
+	channel->handler	= handler;
+	channel->data		= data;
+
+	/* Now make sure we are set up for DMA and not GPIO */
+	/* SIR bit must be set for DMA to work */
+	val = __get_SIR();
+	gpdr = __get_GPDR();
+	if(dmacap & FRV_DMA_CAP_DREQ) {
+		val |= channel->sirdreqbit;
+		gpdr &= ~channel->gpdrdreqbit;
+	}
+	else
+		val &= ~channel->sirdreqbit;
+	__set_SIR(val);
+
+	/* SOR bits depend on what the caller requests */
+	val = __get_SOR();
+	if(dmacap & FRV_DMA_CAP_DACK) {
+		val |= channel->sordackbit;
+		gpdr |= channel->gpdrdackbit;
+	}
+	else
+		val &= ~channel->sordackbit;
+	if(dmacap & FRV_DMA_CAP_DONE) {
+		val |= channel->sordonebit;
+		gpdr |= channel->gpdrdonebit;
+	}
+	else
+		val &= ~channel->sordonebit;
+	__set_SOR(val);
+	__set_GPDR(gpdr);
+	
+	ret = dma;
+ out:
+	write_unlock(&frv_dma_channels_lock);
+	return ret;
+} /* end frv_dma_open() */
+
+/*****************************************************************************/
+/*
+ * close a DMA channel and its associated interrupt
+ */
+void frv_dma_close(int dma)
+{
+	struct frv_dma_channel *channel = &frv_dma_channels[dma];
+	unsigned long flags;
+	uint32_t val;
+
+	write_lock_irqsave(&frv_dma_channels_lock, flags);
+
+	free_irq(channel->irq, channel);
+	frv_dma_stop(dma);
+	
+	channel->flags = FRV_DMA_FLAGS_AVAILABLE;
+
+	/* reset SIR, SOR, and GPDR so they don't cause future conflicts */
+	val = __get_SIR();
+	val &= ~channel->sirdreqbit;
+	__set_SIR(val);
+	
+	val = __get_SOR();
+	val &= ~(channel->sordackbit | channel->sordonebit);
+	__set_SOR(val);
+
+	val = __get_GPDR();
+	val &= ~(channel->gpdrdreqbit | channel->gpdrdackbit |
+		 channel->gpdrdonebit);
+	__set_GPDR(val);
+	
+	write_unlock_irqrestore(&frv_dma_channels_lock, flags);
+} /* end frv_dma_close() */
+
+/*****************************************************************************/
+/*
+ * set static configuration on a DMA channel
+ */
+void frv_dma_config(int dma, unsigned long ccfr, unsigned long cctr, unsigned long apr)
+{
+	unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
+
+	___set_DMAC(ioaddr, CCFR, ccfr);
+	___set_DMAC(ioaddr, CCTR, cctr);
+	___set_DMAC(ioaddr, APR,  apr);
+	mb();
+
+} /* end frv_dma_config() */
+
+/*****************************************************************************/
+/*
+ * start a DMA channel
+ */
+void frv_dma_start(int dma,
+		   unsigned long sba, unsigned long dba,
+		   unsigned long pix, unsigned long six, unsigned long bcl)
+{
+	unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
+
+	___set_DMAC(ioaddr, SBA,  sba);
+	___set_DMAC(ioaddr, DBA,  dba);
+	___set_DMAC(ioaddr, PIX,  pix);
+	___set_DMAC(ioaddr, SIX,  six);
+	___set_DMAC(ioaddr, BCL,  bcl);
+	___set_DMAC(ioaddr, CSTR, 0);
+	mb();
+
+	__set_DMAC(ioaddr, CCTR, __get_DMAC(ioaddr, CCTR) | DMAC_CCTRx_ACT);
+	frv_set_dma_inprogress(dma);
+
+} /* end frv_dma_start() */
+
+/*****************************************************************************/
+/*
+ * restart a DMA channel that's been stopped in circular addressing mode by comparison-end
+ */
+void frv_dma_restart_circular(int dma, unsigned long six)
+{
+	unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
+
+	___set_DMAC(ioaddr, SIX,  six);
+	___set_DMAC(ioaddr, CSTR, __get_DMAC(ioaddr, CSTR) & ~DMAC_CSTRx_CE);
+	mb();
+
+	__set_DMAC(ioaddr, CCTR, __get_DMAC(ioaddr, CCTR) | DMAC_CCTRx_ACT);
+	frv_set_dma_inprogress(dma);
+
+} /* end frv_dma_restart_circular() */
+
+/*****************************************************************************/
+/*
+ * stop a DMA channel
+ */
+void frv_dma_stop(int dma)
+{
+	unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
+	uint32_t cctr;
+
+	___set_DMAC(ioaddr, CSTR, 0);
+	cctr = __get_DMAC(ioaddr, CCTR);
+	cctr &= ~(DMAC_CCTRx_IE | DMAC_CCTRx_ACT);
+	cctr |= DMAC_CCTRx_FC; 	/* fifo clear */
+	__set_DMAC(ioaddr, CCTR, cctr);
+	__set_DMAC(ioaddr, BCL,  0);
+	frv_clear_dma_inprogress(dma);
+} /* end frv_dma_stop() */
+
+/*****************************************************************************/
+/*
+ * test interrupt status of DMA channel
+ */
+int is_frv_dma_interrupting(int dma)
+{
+	unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
+
+	return __get_DMAC(ioaddr, CSTR) & (1 << 23);
+
+} /* end is_frv_dma_interrupting() */
+
+/*****************************************************************************/
+/*
+ * dump data about a DMA channel
+ */
+void frv_dma_dump(int dma)
+{
+	unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
+	unsigned long cstr, pix, six, bcl;
+
+	cstr = __get_DMAC(ioaddr, CSTR);
+	pix  = __get_DMAC(ioaddr, PIX);
+	six  = __get_DMAC(ioaddr, SIX);
+	bcl  = __get_DMAC(ioaddr, BCL);
+
+	printk("DMA[%d] cstr=%lx pix=%lx six=%lx bcl=%lx\n", dma, cstr, pix, six, bcl);
+
+} /* end frv_dma_dump() */
+
+/*****************************************************************************/
+/*
+ * pause all DMA controllers
+ * - called by clock mangling routines
+ * - caller must be holding interrupts disabled
+ */
+void frv_dma_pause_all(void)
+{
+	struct frv_dma_channel *channel;
+	unsigned long ioaddr;;
+	unsigned long cstr, cctr;
+	int dma;
+
+	write_lock(&frv_dma_channels_lock);
+
+	for (dma = FRV_DMA_NCHANS - 1; dma >= 0; dma--) {
+		channel = &frv_dma_channels[dma];
+
+		if (!(channel->flags & FRV_DMA_FLAGS_INUSE))
+			continue;
+
+		ioaddr = channel->ioaddr;
+		cctr = __get_DMAC(ioaddr, CCTR);
+		if (cctr & DMAC_CCTRx_ACT) {
+			cctr &= ~DMAC_CCTRx_ACT;
+			__set_DMAC(ioaddr, CCTR, cctr);
+
+			do {
+				cstr = __get_DMAC(ioaddr, CSTR);
+			} while (cstr & DMAC_CSTRx_BUSY);
+
+			if (cstr & DMAC_CSTRx_FED)
+				channel->flags |= FRV_DMA_FLAGS_PAUSED;
+			frv_clear_dma_inprogress(dma);
+		}
+	}
+
+} /* end frv_dma_pause_all() */
+
+/*****************************************************************************/
+/*
+ * resume paused DMA controllers
+ * - called by clock mangling routines
+ * - caller must be holding interrupts disabled
+ */
+void frv_dma_resume_all(void)
+{
+	struct frv_dma_channel *channel;
+	unsigned long ioaddr;
+	unsigned long cstr, cctr;
+	int dma;
+
+	for (dma = FRV_DMA_NCHANS - 1; dma >= 0; dma--) {
+		channel = &frv_dma_channels[dma];
+
+		if (!(channel->flags & FRV_DMA_FLAGS_PAUSED))
+			continue;
+
+		ioaddr = channel->ioaddr;
+		cstr = __get_DMAC(ioaddr, CSTR);
+		cstr &= ~(DMAC_CSTRx_FED | DMAC_CSTRx_INT);
+		__set_DMAC(ioaddr, CSTR, cstr);
+
+		cctr = __get_DMAC(ioaddr, CCTR);
+		cctr |= DMAC_CCTRx_ACT;
+		__set_DMAC(ioaddr, CCTR, cctr);
+
+		channel->flags &= ~FRV_DMA_FLAGS_PAUSED;
+		frv_set_dma_inprogress(dma);
+	}
+
+	write_unlock(&frv_dma_channels_lock);
+} /* end frv_dma_resume_all() */
+
+/*****************************************************************************/
+/*
+ * dma status clear
+ */
+void frv_dma_status_clear(int dma)
+{
+	unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
+	uint32_t cctr;
+	___set_DMAC(ioaddr, CSTR, 0);
+
+	cctr = __get_DMAC(ioaddr, CCTR);
+} /* end frv_dma_status_clear() */
+
+EXPORT_SYMBOL(frv_dma_stop);
+EXPORT_SYMBOL(frv_dma_start);
+EXPORT_SYMBOL(frv_dma_close);
+EXPORT_SYMBOL(frv_dma_config);
+EXPORT_SYMBOL(frv_dma_dump);
+EXPORT_SYMBOL(frv_dma_status_clear);
+EXPORT_SYMBOL(frv_dma_open);
+EXPORT_SYMBOL(frv_dma_restart_circular);
+EXPORT_SYMBOL(is_frv_dma_interrupting);
+EXPORT_SYMBOL(frv_dma_pause_all);
+EXPORT_SYMBOL(frv_dma_resume_all);
diff -urN linux-2.4.29/arch/frv/kernel/entry.S linux-2.4.29-uc1/arch/frv/kernel/entry.S
--- linux-2.4.29/arch/frv/kernel/entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/entry.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,1275 @@
+/* entry.S: FR-V entry
+ *
+ * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ *
+ * Entry to the kernel is "interesting":
+ *  (1) There are no stack pointers, not even for the kernel
+ *  (2) General Registers should not be clobbered
+ *  (3) There are no kernel-only data registers
+ *  (4) Since all addressing modes are wrt to a General Register, no global
+ *      variables can be reached
+ *
+ * We deal with this by declaring that we shall kill GR28 on entering the
+ * kernel from userspace
+ *
+ * However, since break interrupts can interrupt the CPU even when PSR.ET==0,
+ * they can't rely on GR28 to be anything useful, and so need to clobber a
+ * separate register (GR31). Break interrupts are managed in break.S
+ *
+ * GR29 _is_ saved, and holds the current task pointer globally
+ *
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/ptrace.h>
+#include <asm/errno.h>
+#include <asm/cache.h>
+#include <asm/spr-regs.h>
+
+sigpending	=	0x00000008
+need_resched	=	0x00000014
+tsk_ptrace	=	0x00000018
+
+#define PT_TRACESYS	0x00000002
+
+        .file		"entry.S"
+	.text
+	.balign		4
+
+.macro LEDS val
+#	sethi.p		%hi(0xe1200004),gr30
+#	setlo		%lo(0xe1200004),gr30
+#	setlos		#~\val,gr31
+#	st		gr31,@(gr30,gr0)
+#	membar
+.endm
+
+###############################################################################
+#
+# entry point for External interrupts received whilst executing userspace code
+#
+###############################################################################
+	.globl		__entry_uspace_external_interrupt
+__entry_uspace_external_interrupt:
+	LEDS		0x6200
+	sethi.p		%hi(__kernel_frame0_ptr),gr28
+	setlo		%lo(__kernel_frame0_ptr),gr28
+	ldi		@(gr28,#0),gr28
+
+	# handle h/w single-step through exceptions
+	sti		gr0,@(gr28,#REG__STATUS)
+
+	.globl		__entry_uspace_external_interrupt_reentry
+__entry_uspace_external_interrupt_reentry:
+	LEDS		0x6201
+
+	setlos		#REG__END,gr30
+	dcpl		gr28,gr30,#0
+
+	# finish building the exception frame
+	sti		sp,  @(gr28,#REG_SP)
+	stdi		gr2, @(gr28,#REG_GR(2))
+	stdi		gr4, @(gr28,#REG_GR(4))
+	stdi		gr6, @(gr28,#REG_GR(6))
+	stdi		gr8, @(gr28,#REG_GR(8))
+	stdi		gr10,@(gr28,#REG_GR(10))
+	stdi		gr12,@(gr28,#REG_GR(12))
+	stdi		gr14,@(gr28,#REG_GR(14))
+	stdi		gr16,@(gr28,#REG_GR(16))
+	stdi		gr18,@(gr28,#REG_GR(18))
+	stdi		gr20,@(gr28,#REG_GR(20))
+	stdi		gr22,@(gr28,#REG_GR(22))
+	stdi		gr24,@(gr28,#REG_GR(24))
+	stdi		gr26,@(gr28,#REG_GR(26))
+	sti		gr0, @(gr28,#REG_GR(28))
+	sti		gr29,@(gr28,#REG_GR(29))
+	stdi.p		gr30,@(gr28,#REG_GR(30))
+
+	# set up the kernel stack pointer
+	ori		gr28,0,sp
+
+	movsg		tbr ,gr20
+	movsg		psr ,gr22
+	movsg		pcsr,gr21
+	movsg		isr ,gr23
+	movsg		ccr ,gr24
+	movsg		cccr,gr25
+	movsg		lr  ,gr26
+	movsg		lcr ,gr27
+
+	setlos.p	#-1,gr4
+	andi		gr22,#PSR_PS,gr5		/* try to rebuild original PSR value */
+	andi.p		gr22,#~(PSR_PS|PSR_S),gr6
+	slli		gr5,#1,gr5
+	or		gr6,gr5,gr5
+	andi		gr5,#~PSR_ET,gr5
+
+	sti		gr20,@(gr28,#REG_TBR)
+	sti		gr21,@(gr28,#REG_PC)
+	sti		gr5 ,@(gr28,#REG_PSR)
+	sti		gr23,@(gr28,#REG_ISR)
+	stdi		gr24,@(gr28,#REG_CCR)
+	stdi		gr26,@(gr28,#REG_LR)
+	sti		gr4 ,@(gr28,#REG_SYSCALLNO)
+
+	movsg		iacc0h,gr4
+	movsg		iacc0l,gr5
+	stdi		gr4,@(gr28,#REG_IACC0)
+
+	movsg		gner0,gr4
+	movsg		gner1,gr5
+	stdi		gr4,@(gr28,#REG_GNER0)
+
+	# set up kernel global registers
+	sethi.p		%hi(__kernel_current_task),gr5
+	setlo		%lo(__kernel_current_task),gr5
+	sethi.p		%hi(_gp),gr16
+	setlo		%lo(_gp),gr16
+	ldi.p		@(gr5,#0),gr29
+
+	# make sure we (the kernel) get div-zero and misalignment exceptions
+	setlos		#ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
+	movgs		gr5,isr
+
+	# switch to the kernel trap table
+	sethi.p		%hi(__entry_kerneltrap_table),gr6
+	setlo		%lo(__entry_kerneltrap_table),gr6
+	movgs		gr6,tbr
+
+	# set the return address
+	sethi.p		%hi(__entry_return_from_exception),gr4
+	setlo		%lo(__entry_return_from_exception),gr4
+	movgs		gr4,lr
+
+	# raise the minimum interrupt priority to 15 (NMI only) and enable exceptions
+	movsg		psr,gr4
+
+	ori		gr4,#PSR_PIL,gr4
+	movgs		gr4,psr
+	ori		gr4,#PSR_PIL|PSR_ET,gr4
+	movgs		gr4,psr
+
+	LEDS		0x6202
+	bra		do_IRQ
+
+
+###############################################################################
+#
+# entry point for External interrupts received whilst executing kernel code
+# - on arriving here, the following registers should already be set up:
+#	GR16	- kernel GP-REL pointer
+#	GR29	- current task struct pointer
+#	TBR	- kernel trap vector table
+#	ISR	- kernel's preferred integer controls
+#
+###############################################################################
+	.globl		__entry_kernel_external_interrupt
+__entry_kernel_external_interrupt:
+	LEDS		0x6210
+
+	# set up the stack pointer
+	or.p		sp,gr0,gr30
+	subi		sp,#REG__END,sp
+	sti		gr30,@(sp,#REG_SP)
+
+	# handle h/w single-step through exceptions
+	sti		gr0,@(sp,#REG__STATUS)
+
+	.globl		__entry_kernel_external_interrupt_reentry
+__entry_kernel_external_interrupt_reentry:
+	LEDS		0x6211
+
+	# set up the exception frame
+	setlos		#REG__END,gr30
+	dcpl		sp,gr30,#0
+
+	sti.p		gr28,@(sp,#REG_GR(28))
+	ori		sp,0,gr28
+
+	# finish building the exception frame
+	stdi		gr2,@(gr28,#REG_GR(2))
+	stdi		gr4,@(gr28,#REG_GR(4))
+	stdi		gr6,@(gr28,#REG_GR(6))
+	stdi		gr8,@(gr28,#REG_GR(8))
+	stdi		gr10,@(gr28,#REG_GR(10))
+	stdi		gr12,@(gr28,#REG_GR(12))
+	stdi		gr14,@(gr28,#REG_GR(14))
+	stdi		gr16,@(gr28,#REG_GR(16))
+	stdi		gr18,@(gr28,#REG_GR(18))
+	stdi		gr20,@(gr28,#REG_GR(20))
+	stdi		gr22,@(gr28,#REG_GR(22))
+	stdi		gr24,@(gr28,#REG_GR(24))
+	stdi		gr26,@(gr28,#REG_GR(26))
+	sti		gr29,@(gr28,#REG_GR(29))
+	stdi		gr30,@(gr28,#REG_GR(30))
+
+	movsg		tbr ,gr20
+	movsg		psr ,gr22
+	movsg		pcsr,gr21
+	movsg		isr ,gr23
+	movsg		ccr ,gr24
+	movsg		cccr,gr25
+	movsg		lr  ,gr26
+	movsg		lcr ,gr27
+
+	setlos.p	#-1,gr4
+	andi		gr22,#PSR_PS,gr5		/* try to rebuild original PSR value */
+	andi.p		gr22,#~(PSR_PS|PSR_S),gr6
+	slli		gr5,#1,gr5
+	or		gr6,gr5,gr5
+	andi.p		gr5,#~PSR_ET,gr5
+
+	# set CCCR.CC3 to Undefined to abort atomic-modify completion inside the kernel
+	# - for an explanation of how it works, see: Documentation/fujitsu/frv/atomic-ops.txt
+	andi		gr25,#~0xc0,gr25
+
+	sti		gr20,@(gr28,#REG_TBR)
+	sti		gr21,@(gr28,#REG_PC)
+	sti		gr5 ,@(gr28,#REG_PSR)
+	sti		gr23,@(gr28,#REG_ISR)
+	stdi		gr24,@(gr28,#REG_CCR)
+	stdi		gr26,@(gr28,#REG_LR)
+	sti		gr4 ,@(gr28,#REG_SYSCALLNO)
+
+	movsg		iacc0h,gr4
+	movsg		iacc0l,gr5
+	stdi		gr4,@(gr28,#REG_IACC0)
+
+	movsg		gner0,gr4
+	movsg		gner1,gr5
+	stdi		gr4,@(gr28,#REG_GNER0)
+
+	# set the return address
+	sethi.p		%hi(__entry_return_from_exception),gr4
+	setlo		%lo(__entry_return_from_exception),gr4
+	movgs		gr4,lr
+
+	# clear power-saving mode flags
+	movsg		hsr0,gr4
+	andi		gr4,#~HSR0_PDM,gr4
+	movgs		gr4,hsr0
+
+	# raise the minimum interrupt priority to 15 (NMI only) and enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_PIL,gr4
+	movgs		gr4,psr
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+
+	LEDS		0x6212
+	bra		do_IRQ
+
+
+###############################################################################
+#
+# entry point for Software and Progam interrupts generated whilst executing userspace code
+#
+###############################################################################
+	.globl		__entry_uspace_softprog_interrupt
+	.globl		__entry_uspace_handle_mmu_fault
+__entry_uspace_softprog_interrupt:
+	LEDS		0x6000
+#ifndef CONFIG_UCLINUX
+	movsg		ear0,gr28
+__entry_uspace_handle_mmu_fault:
+	movgs		gr28,scr2
+#endif
+	sethi.p		%hi(__kernel_frame0_ptr),gr28
+	setlo		%lo(__kernel_frame0_ptr),gr28
+	ldi		@(gr28,#0),gr28
+
+	# handle h/w single-step through exceptions
+	sti		gr0,@(gr28,#REG__STATUS)
+
+	.globl		__entry_uspace_softprog_interrupt_reentry
+__entry_uspace_softprog_interrupt_reentry:
+	LEDS		0x6001
+
+	setlos		#REG__END,gr30
+	dcpl		gr28,gr30,#0
+
+	# set up the kernel stack pointer
+	sti.p		sp,@(gr28,#REG_SP)
+	ori		gr28,0,sp
+	sti		gr0,@(gr28,#REG_GR(28))
+
+	stdi		gr20,@(gr28,#REG_GR(20))
+	stdi		gr22,@(gr28,#REG_GR(22))
+
+	movsg		tbr,gr20
+	movsg		pcsr,gr21
+	movsg		psr,gr22
+	bra		__entry_common
+
+	# single-stepping was disabled on entry to a TLB handler that then faulted
+#ifndef CONFIG_UCLINUX
+	.globl		__entry_uspace_handle_mmu_fault_sstep
+__entry_uspace_handle_mmu_fault_sstep:
+	movgs		gr28,scr2
+	sethi.p		%hi(__kernel_frame0_ptr),gr28
+	setlo		%lo(__kernel_frame0_ptr),gr28
+	ldi		@(gr28,#0),gr28
+
+	# flag single-step re-enablement
+	sti		gr0,@(gr28,#REG__STATUS)
+	bra		__entry_uspace_softprog_interrupt_reentry
+#endif
+
+
+###############################################################################
+#
+# entry point for Software and Progam interrupts generated whilst executing kernel code
+#
+###############################################################################
+	.globl		__entry_kernel_softprog_interrupt
+__entry_kernel_softprog_interrupt:
+	LEDS		0x6004
+
+#ifndef CONFIG_UCLINUX
+	movsg		ear0,gr30
+	movgs		gr30,scr2
+#endif
+
+	.globl		__entry_kernel_handle_mmu_fault
+__entry_kernel_handle_mmu_fault:
+	# set up the stack pointer
+	subi		sp,#REG__END,sp
+	sti		sp,@(sp,#REG_SP)
+	sti		sp,@(sp,#REG_SP-4)
+	andi		sp,#~7,sp
+
+	# handle h/w single-step through exceptions
+	sti		gr0,@(sp,#REG__STATUS)
+
+	.globl		__entry_kernel_softprog_interrupt_reentry
+__entry_kernel_softprog_interrupt_reentry:
+	LEDS		0x6005
+
+	setlos		#REG__END,gr30
+	dcpl		sp,gr30,#0
+
+	# set up the exception frame
+	sti.p		gr28,@(sp,#REG_GR(28))
+	ori		sp,0,gr28
+
+	stdi		gr20,@(gr28,#REG_GR(20))
+	stdi		gr22,@(gr28,#REG_GR(22))
+
+	ldi		@(sp,#REG_SP),gr22		/* reconstruct the old SP */
+	addi		gr22,#REG__END,gr22
+	sti		gr22,@(sp,#REG_SP)
+
+	# set CCCR.CC3 to Undefined to abort atomic-modify completion inside the kernel
+	# - for an explanation of how it works, see: Documentation/fujitsu/frv/atomic-ops.txt
+	movsg		cccr,gr20
+	andi		gr20,#~0xc0,gr20
+	movgs		gr20,cccr
+
+	movsg		tbr,gr20
+	movsg		pcsr,gr21
+	movsg		psr,gr22
+
+	bra		__entry_common
+
+	# single-stepping was disabled on entry to a TLB handler that then faulted
+#ifndef CONFIG_UCLINUX
+	.globl		__entry_kernel_handle_mmu_fault_sstep
+__entry_kernel_handle_mmu_fault_sstep:
+	# set up the stack pointer
+	subi		sp,#REG__END,sp
+	sti		sp,@(sp,#REG_SP)
+	sti		sp,@(sp,#REG_SP-4)
+	andi		sp,#~7,sp
+
+	# flag single-step re-enablement
+	sethi		#REG__STATUS_STEP,gr30
+	sti		gr30,@(sp,#REG__STATUS)
+	bra		__entry_kernel_softprog_interrupt_reentry
+#endif
+
+
+###############################################################################
+#
+# the rest of the kernel entry point code
+# - on arriving here, the following registers should be set up:
+#	GR1	- kernel stack pointer
+#	GR7	- syscall number (trap 0 only)
+#	GR8-13	- syscall args (trap 0 only)
+#	GR20	- saved TBR
+#	GR21	- saved PC
+#	GR22	- saved PSR
+#	GR28	- exception frame on stack
+#	SCR2	- saved EAR0 where applicable (clobbered by ICI & ICEF insns on FR451)
+#	PSR	- PSR.S 1, PSR.ET 0
+#
+###############################################################################
+	.globl		__entry_common
+__entry_common:
+	LEDS		0x6008
+
+	# finish building the exception frame
+	stdi		gr2,@(gr28,#REG_GR(2))
+	stdi		gr4,@(gr28,#REG_GR(4))
+	stdi		gr6,@(gr28,#REG_GR(6))
+	stdi		gr8,@(gr28,#REG_GR(8))
+	stdi		gr10,@(gr28,#REG_GR(10))
+	stdi		gr12,@(gr28,#REG_GR(12))
+	stdi		gr14,@(gr28,#REG_GR(14))
+	stdi		gr16,@(gr28,#REG_GR(16))
+	stdi		gr18,@(gr28,#REG_GR(18))
+	stdi		gr24,@(gr28,#REG_GR(24))
+	stdi		gr26,@(gr28,#REG_GR(26))
+	sti		gr29,@(gr28,#REG_GR(29))
+	stdi		gr30,@(gr28,#REG_GR(30))
+
+	movsg		isr ,gr23
+	movsg		ccr ,gr24
+	movsg		cccr,gr25
+	movsg		lr  ,gr26
+	movsg		lcr ,gr27
+
+	setlos.p	#-1,gr4
+	andi		gr22,#PSR_PS,gr5		/* try to rebuild original PSR value */
+	andi.p		gr22,#~(PSR_PS|PSR_S),gr6
+	slli		gr5,#1,gr5
+	or		gr6,gr5,gr5
+	andi		gr5,#~PSR_ET,gr5
+
+	sti		gr20,@(gr28,#REG_TBR)
+	sti		gr21,@(gr28,#REG_PC)
+	sti		gr5 ,@(gr28,#REG_PSR)
+	sti		gr23,@(gr28,#REG_ISR)
+	stdi		gr24,@(gr28,#REG_CCR)
+	stdi		gr26,@(gr28,#REG_LR)
+	sti		gr4 ,@(gr28,#REG_SYSCALLNO)
+
+	movsg		iacc0h,gr4
+	movsg		iacc0l,gr5
+	stdi		gr4,@(gr28,#REG_IACC0)
+
+	movsg		gner0,gr4
+	movsg		gner1,gr5
+	stdi		gr4,@(gr28,#REG_GNER0)
+
+	# set up kernel global registers
+	sethi.p		%hi(__kernel_current_task),gr5
+	setlo		%lo(__kernel_current_task),gr5
+	sethi.p		%hi(_gp),gr16
+	setlo		%lo(_gp),gr16
+	ldi		@(gr5,#0),gr29
+
+	# switch to the kernel trap table
+	sethi.p		%hi(__entry_kerneltrap_table),gr6
+	setlo		%lo(__entry_kerneltrap_table),gr6
+	movgs		gr6,tbr
+
+	# make sure we (the kernel) get div-zero and misalignment exceptions
+	setlos		#ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
+	movgs		gr5,isr
+
+	# clear power-saving mode flags
+	movsg		hsr0,gr4
+	andi		gr4,#~HSR0_PDM,gr4
+	movgs		gr4,hsr0
+
+	# multiplex again using old TBR as a guide
+	setlos.p	#TBR_TT,gr3
+	sethi		%hi(__entry_vector_table),gr6
+	and.p		gr20,gr3,gr5
+	setlo		%lo(__entry_vector_table),gr6
+	srli.p		gr5,#2,gr5
+	sethi		%hi(__entry_return_from_exception),gr4
+	ld.p		@(gr5,gr6),gr5
+	setlo		%lo(__entry_return_from_exception),gr4
+	movgs		gr4,lr
+
+	LEDS		0x6009
+	jmpl		@(gr5,gr0)
+
+
+###############################################################################
+#
+# handle instruction MMU fault
+#
+###############################################################################
+#ifndef CONFIG_UCLINUX
+	.globl		__entry_insn_mmu_fault
+__entry_insn_mmu_fault:
+	LEDS		0x6010
+	setlos		#0,gr8
+	movsg		esr0,gr9
+	movsg		scr2,gr10
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+
+	sethi.p		%hi(do_page_fault),gr5
+	setlo		%lo(do_page_fault),gr5
+	jmpl		@(gr5,gr0)	; call do_page_fault(0,esr0,ear0)
+#endif
+
+###############################################################################
+#
+# handle instruction access error
+#
+###############################################################################
+	.globl		__entry_insn_access_error
+__entry_insn_access_error:
+	LEDS		0x6011
+	sethi.p		%hi(insn_access_error),gr5
+	setlo		%lo(insn_access_error),gr5
+	movsg		esfr1,gr8
+	movsg		epcr0,gr9
+	movsg		esr0,gr10
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	jmpl		@(gr5,gr0)	; call insn_access_error(esfr1,epcr0,esr0)
+
+###############################################################################
+#
+# handle various instructions of dubious legality
+#
+###############################################################################
+	.globl		__entry_unsupported_trap
+	.globl		__entry_illegal_instruction
+	.globl		__entry_privileged_instruction
+	.globl		__entry_debug_exception
+__entry_unsupported_trap:
+	subi		gr21,#4,gr21
+	sti		gr21,@(gr28,#REG_PC)
+__entry_illegal_instruction:
+__entry_privileged_instruction:
+__entry_debug_exception:
+	LEDS		0x6012
+	sethi.p		%hi(illegal_instruction),gr5
+	setlo		%lo(illegal_instruction),gr5
+	movsg		esfr1,gr8
+	movsg		epcr0,gr9
+	movsg		esr0,gr10
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	jmpl		@(gr5,gr0)	; call ill_insn(esfr1,epcr0,esr0)
+
+###############################################################################
+#
+# handle media exception
+#
+###############################################################################
+	.globl		__entry_media_exception
+__entry_media_exception:
+	LEDS		0x6013
+	sethi.p		%hi(media_exception),gr5
+	setlo		%lo(media_exception),gr5
+	movsg		msr0,gr8
+	movsg		msr1,gr9
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	jmpl		@(gr5,gr0)	; call media_excep(msr0,msr1)
+
+###############################################################################
+#
+# handle data MMU fault
+# handle data DAT fault (write-protect exception)
+#
+###############################################################################
+#ifndef CONFIG_UCLINUX
+	.globl		__entry_data_mmu_fault
+__entry_data_mmu_fault:
+	.globl		__entry_data_dat_fault
+__entry_data_dat_fault:
+	LEDS		0x6014
+	setlos		#1,gr8
+	movsg		esr0,gr9
+	movsg		scr2,gr10	; saved EAR0
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+
+	sethi.p		%hi(do_page_fault),gr5
+	setlo		%lo(do_page_fault),gr5
+	jmpl		@(gr5,gr0)	; call do_page_fault(1,esr0,ear0)
+#endif
+
+###############################################################################
+#
+# handle data and instruction access exceptions
+#
+###############################################################################
+	.globl		__entry_insn_access_exception
+	.globl		__entry_data_access_exception
+__entry_insn_access_exception:
+__entry_data_access_exception:
+	LEDS		0x6016
+	sethi.p		%hi(memory_access_exception),gr5
+	setlo		%lo(memory_access_exception),gr5
+	movsg		esr0,gr8
+	movsg		scr2,gr9	; saved EAR0
+	movsg		epcr0,gr10
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	jmpl		@(gr5,gr0)	; call memory_access_error(esr0,ear0,epcr0)
+
+###############################################################################
+#
+# handle data access error
+#
+###############################################################################
+	.globl		__entry_data_access_error
+__entry_data_access_error:
+	LEDS		0x6016
+	sethi.p		%hi(data_access_error),gr5
+	setlo		%lo(data_access_error),gr5
+	movsg		esfr1,gr8
+	movsg		esr15,gr9
+	movsg		ear15,gr10
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	jmpl		@(gr5,gr0)	; call data_access_error(esfr1,esr15,ear15)
+
+###############################################################################
+#
+# handle data store error
+#
+###############################################################################
+	.globl		__entry_data_store_error
+__entry_data_store_error:
+	LEDS		0x6017
+	sethi.p		%hi(data_store_error),gr5
+	setlo		%lo(data_store_error),gr5
+	movsg		esfr1,gr8
+	movsg		esr14,gr9
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	jmpl		@(gr5,gr0)	; call data_store_error(esfr1,esr14)
+
+###############################################################################
+#
+# handle division exception
+#
+###############################################################################
+	.globl		__entry_division_exception
+__entry_division_exception:
+	LEDS		0x6018
+	sethi.p		%hi(division_exception),gr5
+	setlo		%lo(division_exception),gr5
+	movsg		esfr1,gr8
+	movsg		esr0,gr9
+	movsg		isr,gr10
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	jmpl		@(gr5,gr0)	; call div_excep(esfr1,esr0,isr)
+
+###############################################################################
+#
+# handle compound exception
+#
+###############################################################################
+	.globl		__entry_compound_exception
+__entry_compound_exception:
+	LEDS		0x6019
+	sethi.p		%hi(compound_exception),gr5
+	setlo		%lo(compound_exception),gr5
+	movsg		esfr1,gr8
+	movsg		esr0,gr9
+	movsg		esr14,gr10
+	movsg		esr15,gr11
+	movsg		msr0,gr12
+	movsg		msr1,gr13
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	jmpl		@(gr5,gr0)	; call comp_excep(esfr1,esr0,esr14,esr15,msr0,msr1)
+
+###############################################################################
+#
+# handle interrupts and NMIs
+#
+###############################################################################
+	.globl		__entry_do_IRQ
+__entry_do_IRQ:
+	LEDS		0x6020
+
+	# we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	bra		do_IRQ
+
+	.globl		__entry_do_NMI
+__entry_do_NMI:
+	LEDS		0x6021
+
+	# we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	bra		do_NMI
+
+###############################################################################
+#
+# the return path for a newly forked child process
+# - __switch_to() saved the old current pointer in GR8 for us
+#
+###############################################################################
+	.globl		ret_from_fork
+ret_from_fork:
+	LEDS		0x6100
+	call		SYMBOL_NAME(schedule_tail)
+
+	# rebuild saved psr
+	ldi		@(gr28,#REG_PSR),gr22
+	srli		gr22,#1,gr5
+	andi.p		gr22,#~PSR_PS,gr22
+	andi		gr5,#PSR_PS,gr5
+	or		gr5,gr22,gr22
+	ori		gr22,#PSR_S,gr22
+
+	# fork & co. return 0 to child
+	setlos.p	#0,gr8
+	bra		__syscall_exit
+
+###################################################################################################
+#
+# Return to user mode is not as complex as all this looks,
+# but we want the default path for a system call return to
+# go as quickly as possible which is why some of this is
+# less clear than it otherwise should be.
+#
+###################################################################################################
+	.globl		system_call
+system_call:
+	LEDS		0x6101
+	movsg		psr,gr4			; enable exceptions
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+
+	sti		gr7,@(gr28,#REG_SYSCALLNO)
+	sti		gr8,@(gr28,#REG_ORIG_GR8)
+
+	ldi		@(gr29,#tsk_ptrace),gr4
+	andicc		gr4,#PT_TRACESYS,gr0,icc0
+	bne		icc0,#0,__syscall_trace
+//	bra		__syscall_trace
+
+__syscall_call:
+	subicc		gr7,#NR_syscalls,gr0,icc0
+	bnc		icc0,#0,__syscall_badsys
+
+	slli.p		gr7,#2,gr7
+	sethi		%hi(sys_call_table),gr5
+	setlo		%lo(sys_call_table),gr5
+	ld		@(gr5,gr7),gr4
+	calll		@(gr4,gr0)
+
+	# rebuild saved psr - execve will change it for init/main.c
+	ldi		@(gr28,#REG_PSR),gr22
+	srli		gr22,#1,gr5
+	andi.p		gr22,#~PSR_PS,gr22
+	andi		gr5,#PSR_PS,gr5
+	or		gr5,gr22,gr22
+	ori		gr22,#PSR_S,gr22
+
+__syscall_exit:
+	LEDS		0x6102
+	sti		gr8,@(gr28,#REG_GR(8))	; save return value
+	ldi		@(gr29,#tsk_ptrace),gr4
+	andicc		gr4,#PT_TRACESYS,gr0,icc0
+	bne		icc0,#0,__syscall_trace_exit
+//	bra		__syscall_trace_exit
+
+###############################################################################
+#
+# return to interrupted process
+#
+###############################################################################
+__entry_return_from_exception:
+	LEDS		0x6103
+
+	# don't resched or process signals if returning to kernel space
+	andicc		gr22,#PSR_PS,gr0,icc0
+	bne		icc0,#0,__entry_return_direct
+
+	# need_resched and signals must be tested atomically
+	movsg		psr,gr4
+	ori		gr4,#PSR_PIL_15,gr4
+	movgs		gr4,psr
+
+	ldi		@(gr29,#need_resched),gr4
+	ldi.p		@(gr29,#sigpending),gr5
+	andcc		gr4,gr4,gr0,icc0
+	andcc.p		gr5,gr5,gr0,icc1
+
+	bne		icc0,#0,__entry_reschedule
+	bne		icc1,#0,__entry_process_signal
+
+__entry_return_direct:
+	LEDS		0x6104
+
+	andi		gr22,#~PSR_ET,gr22
+	movgs		gr22,psr
+
+	ldi		@(gr28,#REG_ISR),gr23
+	lddi		@(gr28,#REG_CCR),gr24
+	lddi		@(gr28,#REG_LR) ,gr26
+	ldi		@(gr28,#REG_PC) ,gr21
+	ldi		@(gr28,#REG_TBR),gr20
+
+	movgs		gr20,tbr
+	movgs		gr21,pcsr
+	movgs		gr23,isr
+	movgs		gr24,ccr
+	movgs		gr25,cccr
+	movgs		gr26,lr
+	movgs		gr27,lcr
+
+	lddi		@(gr28,#REG_GNER0),gr4
+	movgs		gr4,gner0
+	movgs		gr5,gner1
+
+	lddi		@(gr28,#REG_IACC0),gr4
+	movgs		gr4,iacc0h
+	movgs		gr5,iacc0l
+
+	lddi		@(gr28,#REG_GR(4)) ,gr4
+	lddi		@(gr28,#REG_GR(6)) ,gr6
+	lddi		@(gr28,#REG_GR(8)) ,gr8
+	lddi		@(gr28,#REG_GR(10)),gr10
+	lddi		@(gr28,#REG_GR(12)),gr12
+	lddi		@(gr28,#REG_GR(14)),gr14
+	lddi		@(gr28,#REG_GR(16)),gr16
+	lddi		@(gr28,#REG_GR(18)),gr18
+	lddi		@(gr28,#REG_GR(20)),gr20
+	lddi		@(gr28,#REG_GR(22)),gr22
+	lddi		@(gr28,#REG_GR(24)),gr24
+	lddi		@(gr28,#REG_GR(26)),gr26
+	ldi		@(gr28,#REG_GR(29)),gr29
+	lddi		@(gr28,#REG_GR(30)),gr30
+
+	# check to see if a debugging return is required
+	LEDS		0x67f0
+	movsg		ccr,gr2
+	ldi		@(gr28,#REG__STATUS),gr3
+	andicc		gr3,#REG__STATUS_STEP,gr0,icc0
+	bne		icc0,#0,__entry_return_singlestep
+	movgs		gr2,ccr
+
+	ldi		@(gr28,#REG_SP)    ,sp
+	lddi		@(gr28,#REG_GR(2)) ,gr2
+	ldi		@(gr28,#REG_GR(28)),gr28
+
+	LEDS		0x67fe
+
+#if 0
+	# store the current frame in the workram on the FR451
+	movgs		gr28,scr2
+	sethi.p		%hi(0xfe800000),gr28
+	setlo		%lo(0xfe800000),gr28
+
+	stdi		gr2,@(gr28,#REG_GR(2))
+	stdi		gr4,@(gr28,#REG_GR(4))
+	stdi		gr6,@(gr28,#REG_GR(6))
+	stdi		gr8,@(gr28,#REG_GR(8))
+	stdi		gr10,@(gr28,#REG_GR(10))
+	stdi		gr12,@(gr28,#REG_GR(12))
+	stdi		gr14,@(gr28,#REG_GR(14))
+	stdi		gr16,@(gr28,#REG_GR(16))
+	stdi		gr18,@(gr28,#REG_GR(18))
+	stdi		gr24,@(gr28,#REG_GR(24))
+	stdi		gr26,@(gr28,#REG_GR(26))
+	sti		gr29,@(gr28,#REG_GR(29))
+	stdi		gr30,@(gr28,#REG_GR(30))
+
+	movsg		tbr ,gr30
+	sti		gr30,@(gr28,#REG_TBR)
+	movsg		pcsr,gr30
+	sti		gr30,@(gr28,#REG_PC)
+	movsg		psr ,gr30
+	sti		gr30,@(gr28,#REG_PSR)
+	movsg		isr ,gr30
+	sti		gr30,@(gr28,#REG_ISR)
+	movsg		ccr ,gr30
+	movsg		cccr,gr31
+	stdi		gr30,@(gr28,#REG_CCR)
+	movsg		lr  ,gr30
+	movsg		lcr ,gr31
+	stdi		gr30,@(gr28,#REG_LR)
+	sti		gr0 ,@(gr28,#REG_SYSCALLNO)
+	movsg		scr2,gr28
+#endif
+
+	rett		#0
+
+__entry_return_singlestep:
+	movgs		gr2,ccr
+	lddi		@(gr28,#REG_GR(2)) ,gr2
+	ldi		@(gr28,#REG_SP)    ,sp
+	ldi		@(gr28,#REG_GR(28)),gr28
+	LEDS		0x67ff
+	break
+	.globl		__entry_return_singlestep_breaks_here
+__entry_return_singlestep_breaks_here:
+	nop
+
+__entry_reschedule:
+	LEDS		0x6700
+	call		SYMBOL_NAME(schedule)
+	bra		__entry_return_from_exception
+
+__entry_process_signal:
+	LEDS		0x6701
+
+	# we can get here from an interrupt handler
+	movsg		psr,gr4
+	andi		gr4,#~PSR_PIL_15,gr4
+	movgs		gr4,psr
+
+	ori.p		gr28,#0,gr8
+	xor		gr9,gr9,gr9
+	call		SYMBOL_NAME(do_signal)
+	bra		__entry_return_direct
+
+__syscall_badsys:
+	setlos.p	#-ENOSYS,gr4
+	bra		__syscall_exit
+
+__syscall_trace:
+	setlos.p	#0,gr8
+	call		SYMBOL_NAME(syscall_trace)
+
+	ldi		@(gr28,#REG_SYSCALLNO),gr7
+	lddi		@(gr28,#REG_GR(8)) ,gr8
+	lddi		@(gr28,#REG_GR(10)),gr10
+	lddi.p		@(gr28,#REG_GR(12)),gr12
+	bra		__syscall_call
+
+__syscall_trace_exit:
+	setlos.p	#1,gr8
+	call		SYMBOL_NAME(syscall_trace)
+	bra		__entry_return_from_exception
+
+###############################################################################
+#
+# syscall vector table
+#
+###############################################################################
+	.section .rodata
+ALIGN
+	.globl		sys_call_table
+SYMBOL_NAME_LABEL(sys_call_table)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 0  -  old "setup()" system call*/
+	.long SYMBOL_NAME(sys_exit)
+	.long SYMBOL_NAME(sys_fork)
+	.long SYMBOL_NAME(sys_read)
+	.long SYMBOL_NAME(sys_write)
+	.long SYMBOL_NAME(sys_open)		/* 5 */
+	.long SYMBOL_NAME(sys_close)
+	.long SYMBOL_NAME(sys_waitpid)
+	.long SYMBOL_NAME(sys_creat)
+	.long SYMBOL_NAME(sys_link)
+	.long SYMBOL_NAME(sys_unlink)		/* 10 */
+	.long SYMBOL_NAME(sys_execve)
+	.long SYMBOL_NAME(sys_chdir)
+	.long SYMBOL_NAME(sys_time)
+	.long SYMBOL_NAME(sys_mknod)
+	.long SYMBOL_NAME(sys_chmod)		/* 15 */
+	.long SYMBOL_NAME(sys_lchown16)
+	.long SYMBOL_NAME(sys_ni_syscall)			/* old break syscall holder */
+	.long SYMBOL_NAME(sys_stat)
+	.long SYMBOL_NAME(sys_lseek)
+	.long SYMBOL_NAME(sys_getpid)		/* 20 */
+	.long SYMBOL_NAME(sys_mount)
+	.long SYMBOL_NAME(sys_oldumount)
+	.long SYMBOL_NAME(sys_setuid16)
+	.long SYMBOL_NAME(sys_getuid16)
+	.long SYMBOL_NAME(sys_stime)		/* 25 */
+	.long SYMBOL_NAME(sys_ptrace)
+	.long SYMBOL_NAME(sys_alarm)
+	.long SYMBOL_NAME(sys_fstat)
+	.long SYMBOL_NAME(sys_ni_syscall)			/* pause */
+	.long SYMBOL_NAME(sys_utime)		/* 30 */
+	.long SYMBOL_NAME(sys_ni_syscall)			/* old stty syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)			/* old gtty syscall holder */
+	.long SYMBOL_NAME(sys_access)
+	.long SYMBOL_NAME(sys_nice)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 35 */	/* old ftime syscall holder */
+	.long SYMBOL_NAME(sys_sync)
+	.long SYMBOL_NAME(sys_kill)
+	.long SYMBOL_NAME(sys_rename)
+	.long SYMBOL_NAME(sys_mkdir)
+	.long SYMBOL_NAME(sys_rmdir)		/* 40 */
+	.long SYMBOL_NAME(sys_dup)
+	.long SYMBOL_NAME(sys_pipe)
+	.long SYMBOL_NAME(sys_times)
+	.long SYMBOL_NAME(sys_ni_syscall)			/* old prof syscall holder */
+	.long SYMBOL_NAME(sys_brk)		/* 45 */
+	.long SYMBOL_NAME(sys_setgid16)
+	.long SYMBOL_NAME(sys_getgid16)
+	.long SYMBOL_NAME(sys_signal)
+	.long SYMBOL_NAME(sys_geteuid16)
+	.long SYMBOL_NAME(sys_getegid16)	/* 50 */
+	.long SYMBOL_NAME(sys_acct)
+	.long SYMBOL_NAME(sys_umount)				/* recycled never used phys() */
+	.long SYMBOL_NAME(sys_ni_syscall)			/* old lock syscall holder */
+	.long SYMBOL_NAME(sys_ioctl)
+	.long SYMBOL_NAME(sys_fcntl)		/* 55 */
+	.long SYMBOL_NAME(sys_ni_syscall)			/* old mpx syscall holder */
+	.long SYMBOL_NAME(sys_setpgid)
+	.long SYMBOL_NAME(sys_ni_syscall)			/* old ulimit syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)			/* old old uname syscall */
+	.long SYMBOL_NAME(sys_umask)		/* 60 */
+	.long SYMBOL_NAME(sys_chroot)
+	.long SYMBOL_NAME(sys_ustat)
+	.long SYMBOL_NAME(sys_dup2)
+	.long SYMBOL_NAME(sys_getppid)
+	.long SYMBOL_NAME(sys_getpgrp)		/* 65 */
+	.long SYMBOL_NAME(sys_setsid)
+	.long SYMBOL_NAME(sys_sigaction)
+	.long SYMBOL_NAME(sys_sgetmask)
+	.long SYMBOL_NAME(sys_ssetmask)
+	.long SYMBOL_NAME(sys_setreuid16)	/* 70 */
+	.long SYMBOL_NAME(sys_setregid16)
+	.long SYMBOL_NAME(sys_sigsuspend)
+	.long SYMBOL_NAME(sys_sigpending)
+	.long SYMBOL_NAME(sys_sethostname)
+	.long SYMBOL_NAME(sys_setrlimit)	/* 75 */
+	.long SYMBOL_NAME(sys_old_getrlimit)
+	.long SYMBOL_NAME(sys_getrusage)
+	.long SYMBOL_NAME(sys_gettimeofday)
+	.long SYMBOL_NAME(sys_settimeofday)
+	.long SYMBOL_NAME(sys_getgroups16)	/* 80 */
+	.long SYMBOL_NAME(sys_setgroups16)
+	.long SYMBOL_NAME(sys_ni_syscall)			/* old_select slot */
+	.long SYMBOL_NAME(sys_symlink)
+	.long SYMBOL_NAME(sys_lstat)
+	.long SYMBOL_NAME(sys_readlink)		/* 85 */
+	.long SYMBOL_NAME(sys_uselib)
+	.long SYMBOL_NAME(sys_swapon)
+	.long SYMBOL_NAME(sys_reboot)
+	.long SYMBOL_NAME(old_readdir)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 90 */	/* old_mmap slot */
+	.long SYMBOL_NAME(sys_munmap)
+	.long SYMBOL_NAME(sys_truncate)
+	.long SYMBOL_NAME(sys_ftruncate)
+	.long SYMBOL_NAME(sys_fchmod)
+	.long SYMBOL_NAME(sys_fchown16)		/* 95 */
+	.long SYMBOL_NAME(sys_getpriority)
+	.long SYMBOL_NAME(sys_setpriority)
+	.long SYMBOL_NAME(sys_ni_syscall)			/* old profil syscall holder */
+	.long SYMBOL_NAME(sys_statfs)
+	.long SYMBOL_NAME(sys_fstatfs)		/* 100 */
+	.long SYMBOL_NAME(sys_ni_syscall)			/* ioperm for i386 */
+	.long SYMBOL_NAME(sys_socketcall)
+	.long SYMBOL_NAME(sys_syslog)
+	.long SYMBOL_NAME(sys_setitimer)
+	.long SYMBOL_NAME(sys_getitimer)	/* 105 */
+	.long SYMBOL_NAME(sys_newstat)
+	.long SYMBOL_NAME(sys_newlstat)
+	.long SYMBOL_NAME(sys_newfstat)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* obsolete olduname() syscall */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* iopl for i386 */ /* 110 */
+	.long SYMBOL_NAME(sys_vhangup)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* obsolete idle() syscall */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* vm86old for i386 */
+	.long SYMBOL_NAME(sys_wait4)
+	.long SYMBOL_NAME(sys_swapoff)		/* 115 */
+	.long SYMBOL_NAME(sys_sysinfo)
+	.long SYMBOL_NAME(sys_ipc)
+	.long SYMBOL_NAME(sys_fsync)
+	.long SYMBOL_NAME(sys_sigreturn)
+	.long SYMBOL_NAME(sys_clone)		/* 120 */
+	.long SYMBOL_NAME(sys_setdomainname)
+	.long SYMBOL_NAME(sys_newuname)
+	.long SYMBOL_NAME(sys_cacheflush)	/* modify_ldt for i386 */
+	.long SYMBOL_NAME(sys_adjtimex)
+	.long SYMBOL_NAME(sys_mprotect)		/* 125 */
+	.long SYMBOL_NAME(sys_sigprocmask)
+	.long SYMBOL_NAME(sys_create_module)
+	.long SYMBOL_NAME(sys_init_module)
+	.long SYMBOL_NAME(sys_delete_module)
+	.long SYMBOL_NAME(sys_get_kernel_syms)	/* 130 */
+	.long SYMBOL_NAME(sys_quotactl)
+	.long SYMBOL_NAME(sys_getpgid)
+	.long SYMBOL_NAME(sys_fchdir)
+	.long SYMBOL_NAME(sys_bdflush)
+	.long SYMBOL_NAME(sys_sysfs)		/* 135 */
+	.long SYMBOL_NAME(sys_personality)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for afs_syscall */
+	.long SYMBOL_NAME(sys_setfsuid16)
+	.long SYMBOL_NAME(sys_setfsgid16)
+	.long SYMBOL_NAME(sys_llseek)		/* 140 */
+	.long SYMBOL_NAME(sys_getdents)
+	.long SYMBOL_NAME(sys_select)
+	.long SYMBOL_NAME(sys_flock)
+	.long SYMBOL_NAME(sys_msync)
+	.long SYMBOL_NAME(sys_readv)		/* 145 */
+	.long SYMBOL_NAME(sys_writev)
+	.long SYMBOL_NAME(sys_getsid)
+	.long SYMBOL_NAME(sys_fdatasync)
+	.long SYMBOL_NAME(sys_sysctl)
+	.long SYMBOL_NAME(sys_mlock)		/* 150 */
+	.long SYMBOL_NAME(sys_munlock)
+	.long SYMBOL_NAME(sys_mlockall)
+	.long SYMBOL_NAME(sys_munlockall)
+	.long SYMBOL_NAME(sys_sched_setparam)
+	.long SYMBOL_NAME(sys_sched_getparam)   /* 155 */
+	.long SYMBOL_NAME(sys_sched_setscheduler)
+	.long SYMBOL_NAME(sys_sched_getscheduler)
+	.long SYMBOL_NAME(sys_sched_yield)
+	.long SYMBOL_NAME(sys_sched_get_priority_max)
+	.long SYMBOL_NAME(sys_sched_get_priority_min)  /* 160 */
+	.long SYMBOL_NAME(sys_sched_rr_get_interval)
+	.long SYMBOL_NAME(sys_nanosleep)
+	.long SYMBOL_NAME(sys_mremap)
+	.long SYMBOL_NAME(sys_setresuid16)
+	.long SYMBOL_NAME(sys_getresuid16)	/* 165 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for vm86 */
+	.long SYMBOL_NAME(sys_query_module)
+	.long SYMBOL_NAME(sys_poll)
+	.long SYMBOL_NAME(sys_nfsservctl)
+	.long SYMBOL_NAME(sys_setresgid16)	/* 170 */
+	.long SYMBOL_NAME(sys_getresgid16)
+	.long SYMBOL_NAME(sys_prctl)
+	.long SYMBOL_NAME(sys_rt_sigreturn)
+	.long SYMBOL_NAME(sys_rt_sigaction)
+	.long SYMBOL_NAME(sys_rt_sigprocmask)	/* 175 */
+	.long SYMBOL_NAME(sys_rt_sigpending)
+	.long SYMBOL_NAME(sys_rt_sigtimedwait)
+	.long SYMBOL_NAME(sys_rt_sigqueueinfo)
+	.long SYMBOL_NAME(sys_rt_sigsuspend)
+	.long SYMBOL_NAME(sys_pread)		/* 180 */
+	.long SYMBOL_NAME(sys_pwrite)
+	.long SYMBOL_NAME(sys_chown16)
+	.long SYMBOL_NAME(sys_getcwd)
+	.long SYMBOL_NAME(sys_capget)
+	.long SYMBOL_NAME(sys_capset)           /* 185 */
+	.long SYMBOL_NAME(sys_sigaltstack)
+	.long SYMBOL_NAME(sys_sendfile)
+	.long SYMBOL_NAME(sys_ni_syscall)		/* streams1 */
+	.long SYMBOL_NAME(sys_ni_syscall)		/* streams2 */
+	.long SYMBOL_NAME(sys_vfork)            /* 190 */
+	.long SYMBOL_NAME(sys_getrlimit)
+	.long SYMBOL_NAME(sys_mmap2)
+	.long SYMBOL_NAME(sys_truncate64)
+	.long SYMBOL_NAME(sys_ftruncate64)
+	.long SYMBOL_NAME(sys_stat64)		/* 195 */
+	.long SYMBOL_NAME(sys_lstat64)
+	.long SYMBOL_NAME(sys_fstat64)
+	.long SYMBOL_NAME(sys_lchown)
+	.long SYMBOL_NAME(sys_getuid)
+	.long SYMBOL_NAME(sys_getgid)		/* 200 */
+	.long SYMBOL_NAME(sys_geteuid)
+	.long SYMBOL_NAME(sys_getegid)
+	.long SYMBOL_NAME(sys_setreuid)
+	.long SYMBOL_NAME(sys_setregid)
+	.long SYMBOL_NAME(sys_getgroups)	/* 205 */
+	.long SYMBOL_NAME(sys_setgroups)
+	.long SYMBOL_NAME(sys_fchown)
+	.long SYMBOL_NAME(sys_setresuid)
+	.long SYMBOL_NAME(sys_getresuid)
+	.long SYMBOL_NAME(sys_setresgid)	/* 210 */
+	.long SYMBOL_NAME(sys_getresgid)
+	.long SYMBOL_NAME(sys_chown)
+	.long SYMBOL_NAME(sys_setuid)
+	.long SYMBOL_NAME(sys_setgid)
+	.long SYMBOL_NAME(sys_setfsuid)		/* 215 */
+	.long SYMBOL_NAME(sys_setfsgid)
+	.long SYMBOL_NAME(sys_pivot_root)
+	.long SYMBOL_NAME(sys_mincore)
+	.long SYMBOL_NAME(sys_madvise)
+	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
+	.long SYMBOL_NAME(sys_fcntl64)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for TUX */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* Reserved for Security */
+	.long SYMBOL_NAME(sys_gettid)
+	.long SYMBOL_NAME(sys_readahead)	/* 225 */
+	.long SYMBOL_NAME(sys_setxattr)
+	.long SYMBOL_NAME(sys_lsetxattr)
+	.long SYMBOL_NAME(sys_fsetxattr)
+	.long SYMBOL_NAME(sys_getxattr)
+	.long SYMBOL_NAME(sys_lgetxattr)	/* 230 */
+	.long SYMBOL_NAME(sys_fgetxattr)
+	.long SYMBOL_NAME(sys_listxattr)
+	.long SYMBOL_NAME(sys_llistxattr)
+	.long SYMBOL_NAME(sys_flistxattr)
+	.long SYMBOL_NAME(sys_removexattr)	/* 235 */
+	.long SYMBOL_NAME(sys_lremovexattr)
+	.long SYMBOL_NAME(sys_fremovexattr)
+ 	.long SYMBOL_NAME(sys_tkill)
+	.long SYMBOL_NAME(sys_sendfile64)
+#ifndef CONFIG_UCLINUX
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 240 */	/* futex */
+	.long SYMBOL_NAME(sys_ni_syscall)			/* sched_setaffinity */
+	.long SYMBOL_NAME(sys_ni_syscall)			/* sched_getaffinity */
+#else
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 240 reserved for futex */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for sched_setaffinity */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for sched_getaffinity */
+#endif
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_set_thread_area */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_get_thread_area */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 245 sys_io_setup */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_io_destroy */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_io_getevents */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_io_submit */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_io_cancel */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 250 sys_alloc_hugepages */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_free_hugepages */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_exit_group */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_lookup_dcookie */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_epoll_create */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_epoll_ctl 255 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_epoll_wait */
+ 	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_remap_file_pages */
+ 	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_set_tid_address */
+
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_timer_create */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_timer_settime */		/* 260 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_timer_gettime */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_timer_getoverrun */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_timer_delete */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_clock_settime */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_clock_gettime */		/* 265 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_clock_getres */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_clock_nanosleep */
+
+	.rept NR_syscalls-(.-sys_call_table)/4
+		.long SYMBOL_NAME(sys_ni_syscall)
+	.endr
diff -urN linux-2.4.29/arch/frv/kernel/entry-table.S linux-2.4.29-uc1/arch/frv/kernel/entry-table.S
--- linux-2.4.29/arch/frv/kernel/entry-table.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/entry-table.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,277 @@
+/* entry-table.S: main trap vector tables and exception jump table
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/spr-regs.h>
+
+###############################################################################
+#
+# declare the main trap and vector tables
+#
+# - the first instruction in each slot is a branch to the appropriate
+#   kernel-mode handler routine
+#
+# - the second instruction in each slot is a branch to the debug-mode hardware
+#   single-step bypass handler - this is called from break.S to deal with the
+#   CPU stepping in to exception handlers (particular where external interrupts
+#   are concerned)
+#
+# - the linker script places the user mode and kernel mode trap tables on to
+#   the same 8Kb page, so that break.S can be more efficient when performing
+#   single-step bypass management
+#
+###############################################################################
+
+	# trap table for entry from debug mode
+	.section	.trap.break,"ax"
+	.balign		256*16
+	.globl		__entry_breaktrap_table
+__entry_breaktrap_table:
+
+	# trap table for entry from user mode
+	.section	.trap.user,"ax"
+	.balign		256*16
+	.globl		__entry_usertrap_table
+__entry_usertrap_table:
+
+	# trap table for entry from kernel mode
+	.section	.trap.kernel,"ax"
+	.balign		256*16
+	.globl		__entry_kerneltrap_table
+__entry_kerneltrap_table:
+
+	# exception handler jump table
+	.section	.trap.vector,"ax"
+	.balign		256*4
+	.globl		__entry_vector_table
+__entry_vector_table:
+
+	# trap fixup table for single-stepping in user mode
+	.section	.trap.fixup.user,"a"
+	.balign		256*4
+	.globl		__break_usertrap_fixup_table
+__break_usertrap_fixup_table:
+
+	# trap fixup table for single-stepping in user mode
+	.section	.trap.fixup.kernel,"a"
+	.balign		256*4
+	.globl		__break_kerneltrap_fixup_table
+__break_kerneltrap_fixup_table:
+
+	# handler declaration for a sofware or program interrupt
+.macro VECTOR_SOFTPROG tbr_tt, vec
+	.section .trap.user
+	.org		\tbr_tt
+	bra		__entry_uspace_softprog_interrupt
+	.section .trap.fixup.user
+	.org		\tbr_tt >> 2
+	.long		__break_step_uspace_softprog_interrupt
+	.section .trap.kernel
+	.org		\tbr_tt
+	bra		__entry_kernel_softprog_interrupt
+	.section .trap.fixup.kernel
+	.org		\tbr_tt >> 2
+	.long		__break_step_kernel_softprog_interrupt
+	.section .trap.vector
+	.org		\tbr_tt >> 2
+	.long		\vec
+.endm
+
+	# handler declaration for a maskable external interrupt
+.macro VECTOR_IRQ tbr_tt, vec
+	.section .trap.user
+	.org		\tbr_tt
+	bra		__entry_uspace_external_interrupt
+	.section .trap.fixup.user
+	.org		\tbr_tt >> 2
+	.long		__break_step_uspace_external_interrupt
+	.section .trap.kernel
+	.org		\tbr_tt
+	bra		__entry_kernel_external_interrupt
+	.section .trap.fixup.kernel
+	.org		\tbr_tt >> 2
+	.long		__break_step_kernel_external_interrupt
+	.section .trap.vector
+	.org		\tbr_tt >> 2
+	.long		\vec
+.endm
+
+	# handler declaration for an NMI external interrupt
+.macro VECTOR_NMI tbr_tt, vec
+	.section .trap.user
+	.org		\tbr_tt
+	break
+	break
+	break
+	break
+	.section .trap.kernel
+	.org		\tbr_tt
+	break
+	break
+	break
+	break
+	.section .trap.vector
+	.org		\tbr_tt >> 2
+	.long		\vec
+.endm
+
+	# handler declaration for an MMU only sofware or program interrupt
+.macro VECTOR_SP_MMU tbr_tt, vec
+#ifndef CONFIG_UCLINUX
+	VECTOR_SOFTPROG	\tbr_tt, \vec
+#else
+	VECTOR_NMI	\tbr_tt, 0
+#endif
+.endm
+
+
+###############################################################################
+#
+# specification of the vectors
+# - note: each macro inserts code into multiple sections
+#
+###############################################################################
+	VECTOR_SP_MMU	TBR_TT_INSTR_MMU_MISS,	__entry_insn_mmu_miss
+	VECTOR_SOFTPROG	TBR_TT_INSTR_ACC_ERROR,	__entry_insn_access_error
+	VECTOR_SOFTPROG	TBR_TT_INSTR_ACC_EXCEP,	__entry_insn_access_exception
+	VECTOR_SOFTPROG	TBR_TT_PRIV_INSTR,	__entry_privileged_instruction
+	VECTOR_SOFTPROG	TBR_TT_ILLEGAL_INSTR,	__entry_illegal_instruction
+	VECTOR_SOFTPROG	TBR_TT_FP_EXCEPTION,	__entry_media_exception
+	VECTOR_SOFTPROG	TBR_TT_MP_EXCEPTION,	__entry_media_exception
+	VECTOR_SOFTPROG	TBR_TT_DATA_ACC_ERROR,	__entry_data_access_error
+	VECTOR_SP_MMU	TBR_TT_DATA_MMU_MISS,	__entry_data_mmu_miss
+	VECTOR_SOFTPROG	TBR_TT_DATA_ACC_EXCEP,	__entry_data_access_exception
+	VECTOR_SOFTPROG	TBR_TT_DATA_STR_ERROR,	__entry_data_store_error
+	VECTOR_SOFTPROG	TBR_TT_DIVISION_EXCEP,	__entry_division_exception
+
+#ifndef CONFIG_UCLINUX
+	.section .trap.user
+	.org		TBR_TT_INSTR_TLB_MISS
+	.globl		__trap_user_insn_tlb_miss
+__trap_user_insn_tlb_miss:
+	movsg		ear0,gr28			/* faulting address */
+	movsg		scr0,gr31			/* get mapped PTD coverage start address */
+	xor.p		gr28,gr31,gr31			/* compare addresses */
+	bra		__entry_user_insn_tlb_miss
+
+	.org		TBR_TT_DATA_TLB_MISS
+	.globl		__trap_user_data_tlb_miss
+__trap_user_data_tlb_miss:
+	movsg		ear0,gr28			/* faulting address */
+	movsg		scr1,gr31			/* get mapped PTD coverage start address */
+	xor.p		gr28,gr31,gr31			/* compare addresses */
+	bra		__entry_user_data_tlb_miss
+
+	.section .trap.kernel
+	.org		TBR_TT_INSTR_TLB_MISS
+	.globl		__trap_kernel_insn_tlb_miss
+__trap_kernel_insn_tlb_miss:
+	movsg		ear0,gr29			/* faulting address */
+	movsg		scr0,gr31			/* get mapped PTD coverage start address */
+	xor.p		gr29,gr31,gr31			/* compare addresses */
+	bra		__entry_kernel_insn_tlb_miss
+
+	.org		TBR_TT_DATA_TLB_MISS
+	.globl		__trap_kernel_data_tlb_miss
+__trap_kernel_data_tlb_miss:
+	movsg		ear0,gr29			/* faulting address */
+	movsg		scr1,gr31			/* get mapped PTD coverage start address */
+	xor.p		gr29,gr31,gr31			/* compare addresses */
+	bra		__entry_kernel_data_tlb_miss
+
+	.section .trap.fixup.user
+	.org		TBR_TT_INSTR_TLB_MISS >> 2
+	.globl		__trap_fixup_user_insn_tlb_miss
+__trap_fixup_user_insn_tlb_miss:
+	.long		__break_user_insn_tlb_miss
+	.org		TBR_TT_DATA_TLB_MISS >> 2
+	.globl		__trap_fixup_user_data_tlb_miss
+__trap_fixup_user_data_tlb_miss:
+	.long		__break_user_data_tlb_miss
+
+	.section .trap.fixup.kernel
+	.org		TBR_TT_INSTR_TLB_MISS >> 2
+	.globl		__trap_fixup_kernel_insn_tlb_miss
+__trap_fixup_kernel_insn_tlb_miss:
+	.long		__break_kernel_insn_tlb_miss
+	.org		TBR_TT_DATA_TLB_MISS >> 2
+	.globl		__trap_fixup_kernel_data_tlb_miss
+__trap_fixup_kernel_data_tlb_miss:
+	.long		__break_kernel_data_tlb_miss
+	
+	.section .trap.vector
+	.org		TBR_TT_INSTR_TLB_MISS >> 2
+	.long		__entry_insn_mmu_fault
+	.org		TBR_TT_DATA_TLB_MISS >> 2
+	.long		__entry_data_mmu_fault
+#endif
+
+	VECTOR_SP_MMU	TBR_TT_DATA_DAT_EXCEP,	__entry_data_dat_fault
+	VECTOR_NMI	TBR_TT_DECREMENT_TIMER,	__entry_do_NMI
+	VECTOR_SOFTPROG	TBR_TT_COMPOUND_EXCEP,	__entry_compound_exception
+	VECTOR_IRQ	TBR_TT_INTERRUPT_1,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_2,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_3,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_4,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_5,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_6,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_7,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_8,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_9,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_10,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_11,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_12,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_13,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_14,	__entry_do_IRQ
+	VECTOR_NMI	TBR_TT_INTERRUPT_15,	__entry_do_NMI
+
+	# miscellaneous user mode entry points
+	.section	.trap.user
+	.org		TBR_TT_TRAP0
+	.rept		127
+	bra		__entry_uspace_softprog_interrupt
+	bra		__break_step_uspace_softprog_interrupt
+	.long		0,0
+	.endr
+	.org		TBR_TT_BREAK
+	bra		__entry_break
+	.long		0,0,0
+
+	# miscellaneous kernel mode entry points
+	.section	.trap.kernel
+	.org		TBR_TT_TRAP0
+	.rept		127
+	bra		__entry_kernel_softprog_interrupt
+	bra		__break_step_kernel_softprog_interrupt
+	.long		0,0
+	.endr
+	.org		TBR_TT_BREAK
+	bra		__entry_break
+	.long		0,0,0
+
+	# miscellaneous debug mode entry points
+	.section	.trap.break
+	.org		TBR_TT_BREAK
+	movsg		bpcsr,gr30
+	jmpl		@(gr30,gr0)
+
+	# miscellaneous vectors
+	.section	.trap.vector
+	.org		TBR_TT_TRAP0 >> 2
+	.long		system_call
+	.rept		126
+	.long		__entry_unsupported_trap
+	.endr
+	.org		TBR_TT_BREAK >> 2
+	.long		__entry_debug_exception
diff -urN linux-2.4.29/arch/frv/kernel/frv_ksyms.c linux-2.4.29-uc1/arch/frv/kernel/frv_ksyms.c
--- linux-2.4.29/arch/frv/kernel/frv_ksyms.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/frv_ksyms.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,126 @@
+#include <linux/module.h>
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
+
+#include <asm/setup.h>
+#include <asm/pgalloc.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/semaphore.h>
+#include <asm/checksum.h>
+#include <asm/hardirq.h>
+#include <asm/softirq.h>
+#include <asm/current.h>
+
+extern void dump_thread(struct pt_regs *, struct user *);
+extern long __memcpy_user(void *dst, const void *src, size_t count);
+
+/* platform dependent support */
+
+#ifdef CONFIG_UCLINUX
+// We need to export these symbols so that modules work under uClinux.
+EXPORT_SYMBOL(memory_start);
+EXPORT_SYMBOL(memory_end);
+#endif
+
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
+
+EXPORT_SYMBOL(dump_thread);
+EXPORT_SYMBOL(strnlen);
+EXPORT_SYMBOL(strrchr);
+EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strcat);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strcmp);
+EXPORT_SYMBOL(strncmp);
+EXPORT_SYMBOL(strncpy);
+
+EXPORT_SYMBOL(ip_fast_csum);
+
+#if 0
+EXPORT_SYMBOL(local_irq_count);
+EXPORT_SYMBOL(local_bh_count);
+#endif
+EXPORT_SYMBOL(kernel_thread);
+
+EXPORT_SYMBOL(enable_irq);
+EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(__res_bus_clock_speed_HZ);
+EXPORT_SYMBOL(__page_offset);
+EXPORT_SYMBOL(__memcpy_user);
+EXPORT_SYMBOL(flush_dcache_page);
+
+EXPORT_SYMBOL_NOVERS(__debug_bug_trap);
+
+/* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial_copy);
+
+/* The following are special because they're not called
+   explicitly (the C compiler generates them).  Fortunately,
+   their interface isn't gonna change any time soon now, so
+   it's OK to leave it out of version control.  */
+EXPORT_SYMBOL_NOVERS(memcpy);
+EXPORT_SYMBOL_NOVERS(memset);
+EXPORT_SYMBOL_NOVERS(memcmp);
+EXPORT_SYMBOL_NOVERS(memscan);
+EXPORT_SYMBOL_NOVERS(memmove);
+EXPORT_SYMBOL_NOVERS(strtok);
+
+EXPORT_SYMBOL(get_wchan);
+
+#ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+EXPORT_SYMBOL_NOVERS(atomic_test_and_ANDNOT_mask);
+EXPORT_SYMBOL_NOVERS(atomic_test_and_OR_mask);
+EXPORT_SYMBOL_NOVERS(atomic_test_and_XOR_mask);
+EXPORT_SYMBOL_NOVERS(atomic_add_return);
+EXPORT_SYMBOL_NOVERS(atomic_sub_return);
+EXPORT_SYMBOL_NOVERS(__xchg_8);
+EXPORT_SYMBOL_NOVERS(__xchg_16);
+EXPORT_SYMBOL_NOVERS(__xchg_32);
+EXPORT_SYMBOL_NOVERS(__cmpxchg_8);
+EXPORT_SYMBOL_NOVERS(__cmpxchg_16);
+EXPORT_SYMBOL_NOVERS(__cmpxchg_32);
+#endif
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler...  (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __gcc_bcmp(void);
+extern void __ashldi3(void);
+extern void __ashrdi3(void);
+extern void __cmpdi2(void);
+extern void __divdi3(void);
+extern void __lshrdi3(void);
+extern void __moddi3(void);
+extern void __muldi3(void);
+extern void __negdi2(void);
+extern void __ucmpdi2(void);
+extern void __udivdi3(void);
+extern void __udivmoddi4(void);
+extern void __umoddi3(void);
+
+        /* gcc lib functions */
+//EXPORT_SYMBOL_NOVERS(__gcc_bcmp);
+EXPORT_SYMBOL_NOVERS(__ashldi3);
+EXPORT_SYMBOL_NOVERS(__ashrdi3);
+//EXPORT_SYMBOL_NOVERS(__cmpdi2);
+//EXPORT_SYMBOL_NOVERS(__divdi3);
+EXPORT_SYMBOL_NOVERS(__lshrdi3);
+//EXPORT_SYMBOL_NOVERS(__moddi3);
+EXPORT_SYMBOL_NOVERS(__muldi3);
+EXPORT_SYMBOL_NOVERS(__negdi2);
+//EXPORT_SYMBOL_NOVERS(__ucmpdi2);
+//EXPORT_SYMBOL_NOVERS(__udivdi3);
+//EXPORT_SYMBOL_NOVERS(__udivmoddi4);
+//EXPORT_SYMBOL_NOVERS(__umoddi3);
diff -urN linux-2.4.29/arch/frv/kernel/gdb-io.c linux-2.4.29-uc1/arch/frv/kernel/gdb-io.c
--- linux-2.4.29/arch/frv/kernel/gdb-io.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/gdb-io.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,216 @@
+/* gdb-io.c: FR403 GDB stub I/O
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/serial_reg.h>
+
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/irc-regs.h>
+#include <asm/timer-regs.h>
+#include <asm/gdb-stub.h>
+#include "gdb-io.h"
+
+#ifdef CONFIG_GDBSTUB_UART0
+#define __UART(X) (*(volatile uint8_t *)(UART0_BASE + (UART_##X)))
+#define __UART_IRR_NMI 0xff0f0000
+#else /* CONFIG_GDBSTUB_UART1 */
+#define __UART(X) (*(volatile uint8_t *)(UART1_BASE + (UART_##X)))
+#define __UART_IRR_NMI 0xfff00000
+#endif
+
+#define LSR_WAIT_FOR(STATE)			\
+do {						\
+	gdbstub_do_rx();			\
+} while (!(__UART(LSR) & UART_LSR_##STATE))
+
+#define FLOWCTL_QUERY(LINE)	({ __UART(MSR) & UART_MSR_##LINE; })
+#define FLOWCTL_CLEAR(LINE)	do { __UART(MCR) &= ~UART_MCR_##LINE; mb(); } while (0)
+#define FLOWCTL_SET(LINE)	do { __UART(MCR) |= UART_MCR_##LINE;  mb(); } while (0)
+
+#define FLOWCTL_WAIT_FOR(LINE)			\
+do {						\
+	gdbstub_do_rx();			\
+} while(!FLOWCTL_QUERY(LINE))
+
+/*****************************************************************************/
+/*
+ * initialise the GDB stub
+ * - called with PSR.ET==0, so can't incur external interrupts
+ */
+void gdbstub_io_init(void)
+{
+	/* set up the serial port */
+	__UART(LCR) = UART_LCR_WLEN8; /* 1N8 */
+	__UART(FCR) =
+		UART_FCR_ENABLE_FIFO |
+		UART_FCR_CLEAR_RCVR |
+		UART_FCR_CLEAR_XMIT |
+		UART_FCR_TRIGGER_1;
+
+	FLOWCTL_CLEAR(DTR);
+	FLOWCTL_SET(RTS);
+
+//	gdbstub_set_baud(115200);
+
+	/* we want to get serial receive interrupts */
+	__UART(IER) = UART_IER_RDI | UART_IER_RLSI;
+	mb();
+
+	__set_IRR(6, __UART_IRR_NMI);	/* map ERRs and UARTx to NMI */
+
+} /* end gdbstub_io_init() */
+
+/*****************************************************************************/
+/*
+ * set up the GDB stub serial port baud rate timers
+ */
+void gdbstub_set_baud(unsigned baud)
+{
+	unsigned value, high, low;
+	u8 lcr;
+
+	/* work out the divisor to give us the nearest higher baud rate */
+	value = __serial_clock_speed_HZ / 16 / baud;
+
+	/* determine the baud rate range */
+	high = __serial_clock_speed_HZ / 16 / value;
+	low = __serial_clock_speed_HZ / 16 / (value + 1);
+
+	/* pick the nearest bound */
+	if (low + (high - low) / 2 > baud)
+		value++;
+
+	lcr = __UART(LCR);
+	__UART(LCR) |= UART_LCR_DLAB;
+	mb();
+	__UART(DLL) = value & 0xff;
+	__UART(DLM) = (value >> 8) & 0xff;
+	mb();
+	__UART(LCR) = lcr;
+	mb();
+
+} /* end gdbstub_set_baud() */
+
+/*****************************************************************************/
+/*
+ * receive characters into the receive FIFO
+ */
+void gdbstub_do_rx(void)
+{
+	unsigned ix, nix;
+
+	ix = gdbstub_rx_inp;
+
+	while (__UART(LSR) & UART_LSR_DR) {
+		nix = (ix + 2) & 0xfff;
+		if (nix == gdbstub_rx_outp)
+			break;
+
+		gdbstub_rx_buffer[ix++] = __UART(LSR);
+		gdbstub_rx_buffer[ix++] = __UART(RX);
+		ix = nix;
+	}
+
+	gdbstub_rx_inp = ix;
+
+	__clr_RC(15);
+	__clr_IRL();
+
+} /* end gdbstub_do_rx() */
+
+/*****************************************************************************/
+/*
+ * wait for a character to come from the debugger
+ */
+int gdbstub_rx_char(unsigned char *_ch, int nonblock)
+{
+	unsigned ix;
+	u8 ch, st;
+
+	*_ch = 0xff;
+
+	if (gdbstub_rx_unget) {
+		*_ch = gdbstub_rx_unget;
+		gdbstub_rx_unget = 0;
+		return 0;
+	}
+
+ try_again:
+	gdbstub_do_rx();
+
+	/* pull chars out of the buffer */
+	ix = gdbstub_rx_outp;
+	if (ix == gdbstub_rx_inp) {
+		if (nonblock)
+			return -EAGAIN;
+		//watchdog_alert_counter = 0;
+		goto try_again;
+	}
+
+	st = gdbstub_rx_buffer[ix++];
+	ch = gdbstub_rx_buffer[ix++];
+	gdbstub_rx_outp = ix & 0x00000fff;
+
+	if (st & UART_LSR_BI) {
+		gdbstub_proto("### GDB Rx Break Detected ###\n");
+		return -EINTR;
+	}
+	else if (st & (UART_LSR_FE|UART_LSR_OE|UART_LSR_PE)) {
+		gdbstub_proto("### GDB Rx Error (st=%02x) ###\n",st);
+		return -EIO;
+	}
+	else {
+		gdbstub_proto("### GDB Rx %02x (st=%02x) ###\n",ch,st);
+		*_ch = ch & 0x7f;
+		return 0;
+	}
+
+} /* end gdbstub_rx_char() */
+
+/*****************************************************************************/
+/*
+ * send a character to the debugger
+ */
+void gdbstub_tx_char(unsigned char ch)
+{
+	FLOWCTL_SET(DTR);
+	LSR_WAIT_FOR(THRE);
+//	FLOWCTL_WAIT_FOR(CTS);
+
+	if (ch == 0x0a) {
+		__UART(TX) = 0x0d;
+		mb();
+		LSR_WAIT_FOR(THRE);
+//		FLOWCTL_WAIT_FOR(CTS);
+	}
+	__UART(TX) = ch;
+	mb();
+
+	FLOWCTL_CLEAR(DTR);
+} /* end gdbstub_tx_char() */
+
+/*****************************************************************************/
+/*
+ * send a character to the debugger
+ */
+void gdbstub_tx_flush(void)
+{
+	LSR_WAIT_FOR(TEMT);
+	LSR_WAIT_FOR(THRE);
+	FLOWCTL_CLEAR(DTR);
+} /* end gdbstub_tx_flush() */
diff -urN linux-2.4.29/arch/frv/kernel/gdb-io.h linux-2.4.29-uc1/arch/frv/kernel/gdb-io.h
--- linux-2.4.29/arch/frv/kernel/gdb-io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/gdb-io.h	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,55 @@
+/* gdb-io.h: FR403 GDB I/O port defs
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _GDB_IO_H
+#define _GDB_IO_H
+
+#include <asm/serial-regs.h>
+
+#undef UART_RX
+#undef UART_TX
+#undef UART_DLL
+#undef UART_DLM
+#undef UART_IER
+#undef UART_IIR
+#undef UART_FCR
+#undef UART_LCR
+#undef UART_MCR
+#undef UART_LSR
+#undef UART_MSR
+#undef UART_SCR
+
+#define UART_RX		0*8	/* In:  Receive buffer (DLAB=0) */
+#define UART_TX		0*8	/* Out: Transmit buffer (DLAB=0) */
+#define UART_DLL	0*8	/* Out: Divisor Latch Low (DLAB=1) */
+#define UART_DLM	1*8	/* Out: Divisor Latch High (DLAB=1) */
+#define UART_IER	1*8	/* Out: Interrupt Enable Register */
+#define UART_IIR	2*8	/* In:  Interrupt ID Register */
+#define UART_FCR	2*8	/* Out: FIFO Control Register */
+#define UART_LCR	3*8	/* Out: Line Control Register */
+#define UART_MCR	4*8	/* Out: Modem Control Register */
+#define UART_LSR	5*8	/* In:  Line Status Register */
+#define UART_MSR	6*8	/* In:  Modem Status Register */
+#define UART_SCR	7*8	/* I/O: Scratch Register */
+
+#define UART_LCR_DLAB	0x80	/* Divisor latch access bit */
+#define UART_LCR_SBC	0x40	/* Set break control */
+#define UART_LCR_SPAR	0x20	/* Stick parity (?) */
+#define UART_LCR_EPAR	0x10	/* Even parity select */
+#define UART_LCR_PARITY	0x08	/* Parity Enable */
+#define UART_LCR_STOP	0x04	/* Stop bits: 0=1 stop bit, 1= 2 stop bits */
+#define UART_LCR_WLEN5  0x00	/* Wordlength: 5 bits */
+#define UART_LCR_WLEN6  0x01	/* Wordlength: 6 bits */
+#define UART_LCR_WLEN7  0x02	/* Wordlength: 7 bits */
+#define UART_LCR_WLEN8  0x03	/* Wordlength: 8 bits */
+
+
+#endif /* _GDB_IO_H */
diff -urN linux-2.4.29/arch/frv/kernel/gdb-stub.c linux-2.4.29-uc1/arch/frv/kernel/gdb-stub.c
--- linux-2.4.29/arch/frv/kernel/gdb-stub.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/gdb-stub.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,2065 @@
+/* gdb-stub.c: FRV GDB stub
+ *
+ * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from Linux/MIPS version, Copyright (C) 1995 Andreas Busse
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
+ *  To enable debugger support, two things need to happen.  One, a
+ *  call to set_debug_traps() is necessary in order to allow any breakpoints
+ *  or error conditions to be properly intercepted and reported to gdb.
+ *  Two, a breakpoint needs to be generated to begin communication.  This
+ *  is most easily accomplished by a call to breakpoint().  Breakpoint()
+ *  simulates a breakpoint by executing a BREAK instruction.
+ *
+ *
+ *    The following gdb commands are supported:
+ *
+ * command          function                               Return value
+ *
+ *    g             return the value of the CPU registers  hex data or ENN
+ *    G             set the value of the CPU registers     OK or ENN
+ *
+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
+ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
+ *
+ *    c             Resume at current address              SNN   ( signal NN)
+ *    cAA..AA       Continue at address AA..AA             SNN
+ *
+ *    s             Step one instruction                   SNN
+ *    sAA..AA       Step one instruction from AA..AA       SNN
+ *
+ *    k             kill
+ *
+ *    ?             What was the last sigval ?             SNN   (signal NN)
+ *
+ *    bBB..BB	    Set baud rate to BB..BB		   OK or BNN, then sets
+ *							   baud rate
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum.  A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer.  '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host:                  Reply:
+ * $m0,10#2a               +$00010203040506070809101112131415#42
+ *
+ *
+ *  ==============
+ *  MORE EXAMPLES:
+ *  ==============
+ *
+ *  For reference -- the following are the steps that one
+ *  company took (RidgeRun Inc) to get remote gdb debugging
+ *  going. In this scenario the host machine was a PC and the
+ *  target platform was a Galileo EVB64120A MIPS evaluation
+ *  board.
+ *
+ *  Step 1:
+ *  First download gdb-5.0.tar.gz from the internet.
+ *  and then build/install the package.
+ *
+ *  Example:
+ *    $ tar zxf gdb-5.0.tar.gz
+ *    $ cd gdb-5.0
+ *    $ ./configure --target=frv-elf-gdb
+ *    $ make
+ *    $ frv-elf-gdb
+ *
+ *  Step 2:
+ *  Configure linux for remote debugging and build it.
+ *
+ *  Example:
+ *    $ cd ~/linux
+ *    $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging>
+ *    $ make dep; make vmlinux
+ *
+ *  Step 3:
+ *  Download the kernel to the remote target and start
+ *  the kernel running. It will promptly halt and wait
+ *  for the host gdb session to connect. It does this
+ *  since the "Kernel Hacking" option has defined
+ *  CONFIG_REMOTE_DEBUG which in turn enables your calls
+ *  to:
+ *     set_debug_traps();
+ *     breakpoint();
+ *
+ *  Step 4:
+ *  Start the gdb session on the host.
+ *
+ *  Example:
+ *    $ frv-elf-gdb vmlinux
+ *    (gdb) set remotebaud 115200
+ *    (gdb) target remote /dev/ttyS1
+ *    ...at this point you are connected to
+ *       the remote target and can use gdb
+ *       in the normal fasion. Setting
+ *       breakpoints, single stepping,
+ *       printing variables, etc.
+ *
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/nmi.h>
+
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/gdb-stub.h>
+
+#define LEDS(x) do { /* *(u32*)0xe1200004 = ~(x); mb(); */ } while(0)
+
+#undef GDBSTUB_DEBUG_PROTOCOL
+
+extern void debug_to_serial(const char *p, int n);
+extern void gdbstub_console_write(struct console *co, const char *p, unsigned n);
+
+extern volatile uint32_t __break_error_detect[3]; /* ESFR1, ESR15, EAR15 */
+extern struct user_context __break_user_context;
+
+struct __debug_amr {
+	unsigned long L, P;
+} __attribute__((aligned(8)));
+
+struct __debug_mmu {
+	struct {
+		unsigned long	hsr0, pcsr, esr0, ear0, epcr0;
+#ifndef CONFIG_UCLINUX
+		unsigned long	tplr, tppr, tpxr, cxnr;
+#endif
+	} regs;
+
+	struct __debug_amr	iamr[16];
+	struct __debug_amr	damr[16];
+
+#ifndef CONFIG_UCLINUX
+	struct __debug_amr	tlb[64*2];
+#endif
+};
+
+static struct __debug_mmu __debug_mmu;
+
+/*
+ * BUFMAX defines the maximum number of characters in inbound/outbound buffers
+ * at least NUMREGBYTES*2 are needed for register packets
+ */
+#define BUFMAX 2048
+
+#define BREAK_INSN	0x801000c0	/* use "break" as bkpt */
+
+static const char gdbstub_banner[] = "Linux/FR-V GDB Stub (c) RedHat 2003\n";
+
+volatile u8	gdbstub_rx_buffer[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
+volatile u32	gdbstub_rx_inp = 0;
+volatile u32	gdbstub_rx_outp = 0;
+volatile u8	gdbstub_rx_overflow = 0;
+u8		gdbstub_rx_unget = 0;
+
+/* set with GDB whilst running to permit step through exceptions */
+extern volatile u32 __attribute__((section(".bss"))) gdbstub_trace_through_exceptions;
+
+static char	input_buffer[BUFMAX];
+static char	output_buffer[BUFMAX];
+
+static const char hexchars[] = "0123456789abcdef";
+
+static const char *regnames[] = {
+	"PSR ", "ISR ", "CCR ", "CCCR",
+	"LR  ", "LCR ", "PC  ", "_stt",
+	"sys ", "GR8*", "GNE0", "GNE1",
+	"IACH", "IACL",
+	"TBR ", "SP  ", "FP  ", "GR3 ",
+	"GR4 ", "GR5 ", "GR6 ", "GR7 ",
+	"GR8 ", "GR9 ", "GR10", "GR11",
+	"GR12", "GR13", "GR14", "GR15",
+	"GR16", "GR17", "GR18", "GR19",
+	"GR20", "GR21", "GR22", "GR23",
+	"GR24", "GR25", "GR26", "GR27",
+	"EFRM", "CURR", "GR30", "BFRM"
+};
+
+struct gdbstub_bkpt {
+	unsigned long	addr;		/* address of breakpoint */
+	unsigned	len;		/* size of breakpoint */
+	uint32_t	originsns[7];	/* original instructions */
+};
+
+static struct gdbstub_bkpt gdbstub_bkpts[256];
+
+/*
+ * local prototypes
+ */
+
+static void gdbstub_recv_packet(char *buffer);
+static int gdbstub_send_packet(char *buffer);
+static int gdbstub_compute_signal(unsigned long tbr);
+static int hex(unsigned char ch);
+static int hexToInt(char **ptr, unsigned long *intValue);
+static unsigned char *mem2hex(const void *mem, char *buf, int count, int may_fault);
+static char *hex2mem(const char *buf, void *_mem, int count);
+
+/*
+ * Convert ch from a hex digit to an int
+ */
+static int hex(unsigned char ch)
+{
+	if (ch >= 'a' && ch <= 'f')
+		return ch-'a'+10;
+	if (ch >= '0' && ch <= '9')
+		return ch-'0';
+	if (ch >= 'A' && ch <= 'F')
+		return ch-'A'+10;
+	return -1;
+}
+
+void gdbstub_printk(const char *fmt, ...)
+{
+	static char buf[1024];
+	va_list args;
+	int len;
+
+	/* Emit the output into the temporary buffer */
+	va_start(args, fmt);
+	len = vsnprintf(buf, sizeof(buf), fmt, args);
+	va_end(args);
+	debug_to_serial(buf, len);
+}
+
+static inline char *gdbstub_strcpy(char *dst, const char *src)
+{
+	int loop = 0;
+	while ((dst[loop] = src[loop]))
+	       loop++;
+	return dst;
+}
+
+static void gdbstub_purge_cache(void)
+{
+	asm volatile("	dcef	@(gr0,gr0),#1	\n"
+		     "	icei	@(gr0,gr0),#1	\n"
+		     "	membar			\n"
+		     "	bar			\n"
+		     );
+}
+
+/*****************************************************************************/
+/*
+ * scan for the sequence $<data>#<checksum>
+ */
+static void gdbstub_recv_packet(char *buffer)
+{
+	unsigned char checksum;
+	unsigned char xmitcsum;
+	unsigned char ch;
+	int count, i, ret, error;
+
+	for (;;) {
+		/* wait around for the start character, ignore all other characters */
+		do {
+			gdbstub_rx_char(&ch, 0);
+		} while (ch != '$');
+
+		checksum = 0;
+		xmitcsum = -1;
+		count = 0;
+		error = 0;
+
+		/* now, read until a # or end of buffer is found */
+		while (count < BUFMAX) {
+			ret = gdbstub_rx_char(&ch, 0);
+			if (ret < 0)
+				error = ret;
+
+			if (ch == '#')
+				break;
+			checksum += ch;
+			buffer[count] = ch;
+			count++;
+		}
+
+		if (error == -EIO) {
+			gdbstub_proto("### GDB Rx Error - Skipping packet ###\n");
+			gdbstub_proto("### GDB Tx NAK\n");
+			gdbstub_tx_char('-');
+			continue;
+		}
+
+		if (count >= BUFMAX || error)
+			continue;
+
+		buffer[count] = 0;
+
+		/* read the checksum */
+		ret = gdbstub_rx_char(&ch, 0);
+		if (ret < 0)
+			error = ret;
+		xmitcsum = hex(ch) << 4;
+
+		ret = gdbstub_rx_char(&ch, 0);
+		if (ret < 0)
+			error = ret;
+		xmitcsum |= hex(ch);
+
+		if (error) {
+			if (error == -EIO)
+				gdbstub_proto("### GDB Rx Error - Skipping packet\n");
+			gdbstub_proto("### GDB Tx NAK\n");
+			gdbstub_tx_char('-');
+			continue;
+		}
+
+		/* check the checksum */
+		if (checksum != xmitcsum) {
+			gdbstub_proto("### GDB Tx NAK\n");
+			gdbstub_tx_char('-');	/* failed checksum */
+			continue;
+		}
+
+		gdbstub_proto("### GDB Rx '$%s#%02x' ###\n", buffer, checksum);
+		gdbstub_proto("### GDB Tx ACK\n");
+		gdbstub_tx_char('+'); /* successful transfer */
+
+		/* if a sequence char is present, reply the sequence ID */
+		if (buffer[2] == ':') {
+			gdbstub_tx_char(buffer[0]);
+			gdbstub_tx_char(buffer[1]);
+
+			/* remove sequence chars from buffer */
+			count = 0;
+			while (buffer[count]) count++;
+			for (i=3; i <= count; i++)
+				buffer[i - 3] = buffer[i];
+		}
+
+		break;
+	}
+} /* end gdbstub_recv_packet() */
+
+/*****************************************************************************/
+/*
+ * send the packet in buffer.
+ * - return 0 if successfully ACK'd
+ * - return 1 if abandoned due to new incoming packet
+ */
+static int gdbstub_send_packet(char *buffer)
+{
+	unsigned char checksum;
+	int count;
+	unsigned char ch;
+
+	/* $<packet info>#<checksum> */
+	gdbstub_proto("### GDB Tx '%s' ###\n", buffer);
+
+	do {
+		gdbstub_tx_char('$');
+		checksum = 0;
+		count = 0;
+
+		while ((ch = buffer[count]) != 0) {
+			gdbstub_tx_char(ch);
+			checksum += ch;
+			count += 1;
+		}
+
+		gdbstub_tx_char('#');
+		gdbstub_tx_char(hexchars[checksum >> 4]);
+		gdbstub_tx_char(hexchars[checksum & 0xf]);
+
+	} while (gdbstub_rx_char(&ch,0),
+#ifdef GDBSTUB_DEBUG_PROTOCOL
+		 ch=='-' && (gdbstub_proto("### GDB Rx NAK\n"),0),
+		 ch!='-' && ch!='+' && (gdbstub_proto("### GDB Rx ??? %02x\n",ch),0),
+#endif
+		 ch!='+' && ch!='$');
+
+	if (ch=='+') {
+		gdbstub_proto("### GDB Rx ACK\n");
+		return 0;
+	}
+
+	gdbstub_proto("### GDB Tx Abandoned\n");
+	gdbstub_rx_unget = ch;
+	return 1;
+} /* end gdbstub_send_packet() */
+
+/*
+ * While we find nice hex chars, build an int.
+ * Return number of chars processed.
+ */
+static int hexToInt(char **ptr, unsigned long *_value)
+{
+	int count = 0, ch;
+
+	*_value = 0;
+	while (**ptr) {
+		ch = hex(**ptr);
+		if (ch < 0)
+			break;
+
+		*_value = (*_value << 4) | ((uint8_t) ch & 0xf);
+		count++;
+
+		(*ptr)++;
+	}
+
+	return count;
+}
+
+/*****************************************************************************/
+/*
+ * probe an address to see whether it maps to anything
+ */
+static inline int gdbstub_addr_probe(const void *vaddr)
+{
+#ifndef CONFIG_UCLINUX
+	unsigned long paddr;
+
+	asm("lrad %1,%0,#1,#0,#0" : "=r"(paddr) : "r"(vaddr));
+	if (!(paddr & xAMPRx_V))
+		return 0;
+#endif
+
+	return 1;
+} /* end gdbstub_addr_probe() */
+
+#ifndef CONFIG_UCLINUX
+static unsigned long __saved_dampr, __saved_damlr;
+
+static inline unsigned long gdbstub_virt_to_pte(unsigned long vaddr)
+{
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+	unsigned long val, dampr5;
+
+	pgd = (pgd_t *)__get_DAMLR(3) + pgd_index(vaddr);
+	pmd = pmd_offset(pgd, vaddr);
+
+	if (pmd_bad(*pmd) || !pmd_present(*pmd))
+		return 0;
+
+	/* make sure dampr5 maps to the correct pmd */
+	dampr5 = __get_DAMPR(5);
+	val = pmd_val(*pmd);
+	__set_DAMPR(5, val | xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V);
+
+	/* now its safe to access pmd */
+	pte = (pte_t *)__get_DAMLR(5) + __pte_index(vaddr);
+	if (pte_present(*pte))
+		val = pte_val(*pte);
+	else
+		val = 0;
+
+	/* restore original dampr5 */
+	__set_DAMPR(5, dampr5);
+
+	return val;
+}
+#endif
+
+static inline int gdbstub_addr_map(const void *vaddr)
+{
+#ifndef CONFIG_UCLINUX
+	unsigned long pte;
+
+	__saved_dampr = __get_DAMPR(2);
+	__saved_damlr = __get_DAMLR(2);
+#endif
+	if (gdbstub_addr_probe(vaddr))
+		return 1;
+#ifndef CONFIG_UCLINUX
+	pte = gdbstub_virt_to_pte((unsigned long)vaddr);
+	if (pte) {
+		__set_DAMPR(2, pte);
+		__set_DAMLR(2, (unsigned long)vaddr & PAGE_MASK);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+static inline void gdbstub_addr_unmap(void)
+{
+#ifndef CONFIG_UCLINUX
+	__set_DAMPR(2, __saved_dampr);
+	__set_DAMLR(2, __saved_damlr);
+#endif
+}
+
+/*
+ * access potentially dodgy memory through a potentially dodgy pointer
+ */
+static inline int gdbstub_read_dword(const void *addr, uint32_t *_res)
+{
+	unsigned long brr;
+	uint32_t res;
+
+	if (!gdbstub_addr_map(addr))
+		return 0;
+
+	asm volatile("	movgs	gr0,brr	\n"
+		     "	ld%I2	%M2,%0	\n"
+		     "	movsg	brr,%1	\n"
+		     : "=r"(res), "=r"(brr)
+		     : "m"(*(uint32_t *) addr));
+	*_res = res;
+	gdbstub_addr_unmap();
+	return likely(!brr);
+}
+
+static inline int gdbstub_write_dword(void *addr, uint32_t val)
+{
+	unsigned long brr;
+
+	if (!gdbstub_addr_map(addr))
+		return 0;
+
+	asm volatile("	movgs	gr0,brr	\n"
+		     "	st%I2	%1,%M2	\n"
+		     "	movsg	brr,%0	\n"
+		     : "=r"(brr)
+		     : "r"(val), "m"(*(uint32_t *) addr));
+	gdbstub_addr_unmap();
+	return likely(!brr);
+}
+
+static inline int gdbstub_read_word(const void *addr, uint16_t *_res)
+{
+	unsigned long brr;
+	uint16_t res;
+
+	if (!gdbstub_addr_map(addr))
+		return 0;
+
+	asm volatile("	movgs	gr0,brr	\n"
+		     "	lduh%I2	%M2,%0	\n"
+		     "	movsg	brr,%1	\n"
+		     : "=r"(res), "=r"(brr)
+		     : "m"(*(uint16_t *) addr));
+	*_res = res;
+	gdbstub_addr_unmap();
+	return likely(!brr);
+}
+
+static inline int gdbstub_write_word(void *addr, uint16_t val)
+{
+	unsigned long brr;
+
+	if (!gdbstub_addr_map(addr))
+		return 0;
+
+	asm volatile("	movgs	gr0,brr	\n"
+		     "	sth%I2	%1,%M2	\n"
+		     "	movsg	brr,%0	\n"
+		     : "=r"(brr)
+		     : "r"(val), "m"(*(uint16_t *) addr));
+	gdbstub_addr_unmap();
+	return likely(!brr);
+}
+
+static inline int gdbstub_read_byte(const void *addr, uint8_t *_res)
+{
+	unsigned long brr;
+	uint8_t res;
+
+	if (!gdbstub_addr_map(addr))
+		return 0;
+
+	asm volatile("	movgs	gr0,brr	\n"
+		     "	ldub%I2	%M2,%0	\n"
+		     "	movsg	brr,%1	\n"
+		     : "=r"(res), "=r"(brr)
+		     : "m"(*(uint8_t *) addr));
+	*_res = res;
+	gdbstub_addr_unmap();
+	return likely(!brr);
+}
+
+static inline int gdbstub_write_byte(void *addr, uint8_t val)
+{
+	unsigned long brr;
+
+	if (!gdbstub_addr_map(addr))
+		return 0;
+
+	asm volatile("	movgs	gr0,brr	\n"
+		     "	stb%I2	%1,%M2	\n"
+		     "	movsg	brr,%0	\n"
+		     : "=r"(brr)
+		     : "r"(val), "m"(*(uint8_t *) addr));
+	gdbstub_addr_unmap();
+	return likely(!brr);
+}
+
+static void __gdbstub_console_write(struct console *co, const char *p, unsigned n)
+{
+	char outbuf[26];
+	int qty;
+
+	outbuf[0] = 'O';
+
+	while (n > 0) {
+		qty = 1;
+
+		while (n > 0 && qty < 20) {
+			mem2hex(p, outbuf + qty, 2, 0);
+			qty += 2;
+			if (*p == 0x0a) {
+				outbuf[qty++] = '0';
+				outbuf[qty++] = 'd';
+			}
+			p++;
+			n--;
+		}
+
+		outbuf[qty] = 0;
+		gdbstub_send_packet(outbuf);
+	}
+}
+
+#if 0
+void debug_to_serial(const char *p, int n)
+{
+	gdbstub_console_write(NULL,p,n);
+}
+#endif
+
+#ifdef CONFIG_GDBSTUB_CONSOLE
+
+static kdev_t gdbstub_console_dev(struct console *con)
+{
+	return MKDEV(1,3); /* /dev/null */
+}
+
+static struct console gdbstub_console = {
+	.name	= "gdb",
+	.write	= gdbstub_console_write,	/* in break.S */
+	.device	= gdbstub_console_dev,
+	.flags	= CON_PRINTBUFFER,
+	.index	= -1,
+};
+
+#endif
+
+/*****************************************************************************/
+/*
+ * Convert the memory pointed to by mem into hex, placing result in buf.
+ * - if successful, return a pointer to the last char put in buf (NUL)
+ * - in case of mem fault, return NULL
+ * may_fault is non-zero if we are reading from arbitrary memory, but is currently
+ * not used.
+ */
+static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fault)
+{
+	const uint8_t *mem = _mem;
+	uint8_t ch[4] __attribute__((aligned(4)));
+
+	if ((uint32_t)mem&1 && count>=1) {
+		if (!gdbstub_read_byte(mem,ch))
+			return NULL;
+		*buf++ = hexchars[ch[0] >> 4];
+		*buf++ = hexchars[ch[0] & 0xf];
+		mem++;
+		count--;
+	}
+
+	if ((uint32_t)mem&3 && count>=2) {
+		if (!gdbstub_read_word(mem,(uint16_t *)ch))
+			return NULL;
+		*buf++ = hexchars[ch[0] >> 4];
+		*buf++ = hexchars[ch[0] & 0xf];
+		*buf++ = hexchars[ch[1] >> 4];
+		*buf++ = hexchars[ch[1] & 0xf];
+		mem += 2;
+		count -= 2;
+	}
+
+	while (count>=4) {
+		if (!gdbstub_read_dword(mem,(uint32_t *)ch))
+			return NULL;
+		*buf++ = hexchars[ch[0] >> 4];
+		*buf++ = hexchars[ch[0] & 0xf];
+		*buf++ = hexchars[ch[1] >> 4];
+		*buf++ = hexchars[ch[1] & 0xf];
+		*buf++ = hexchars[ch[2] >> 4];
+		*buf++ = hexchars[ch[2] & 0xf];
+		*buf++ = hexchars[ch[3] >> 4];
+		*buf++ = hexchars[ch[3] & 0xf];
+		mem += 4;
+		count -= 4;
+	}
+
+	if (count>=2) {
+		if (!gdbstub_read_word(mem,(uint16_t *)ch))
+			return NULL;
+		*buf++ = hexchars[ch[0] >> 4];
+		*buf++ = hexchars[ch[0] & 0xf];
+		*buf++ = hexchars[ch[1] >> 4];
+		*buf++ = hexchars[ch[1] & 0xf];
+		mem += 2;
+		count -= 2;
+	}
+
+	if (count>=1) {
+		if (!gdbstub_read_byte(mem,ch))
+			return NULL;
+		*buf++ = hexchars[ch[0] >> 4];
+		*buf++ = hexchars[ch[0] & 0xf];
+	}
+
+	*buf = 0;
+
+	return buf;
+} /* end mem2hex() */
+
+/*****************************************************************************/
+/*
+ * convert the hex array pointed to by buf into binary to be placed in mem
+ * return a pointer to the character AFTER the last byte of buffer consumed
+ */
+static char *hex2mem(const char *buf, void *_mem, int count)
+{
+	uint8_t *mem = _mem;
+	union {
+		uint32_t l;
+		uint16_t w;
+		uint8_t  b[4];
+	} ch;
+
+	if ((u32)mem&1 && count>=1) {
+		ch.b[0]  = hex(*buf++) << 4;
+		ch.b[0] |= hex(*buf++);
+		if (!gdbstub_write_byte(mem,ch.b[0]))
+			return NULL;
+		mem++;
+		count--;
+	}
+
+	if ((u32)mem&3 && count>=2) {
+		ch.b[0]  = hex(*buf++) << 4;
+		ch.b[0] |= hex(*buf++);
+		ch.b[1]  = hex(*buf++) << 4;
+		ch.b[1] |= hex(*buf++);
+		if (!gdbstub_write_word(mem,ch.w))
+			return NULL;
+		mem += 2;
+		count -= 2;
+	}
+
+	while (count>=4) {
+		ch.b[0]  = hex(*buf++) << 4;
+		ch.b[0] |= hex(*buf++);
+		ch.b[1]  = hex(*buf++) << 4;
+		ch.b[1] |= hex(*buf++);
+		ch.b[2]  = hex(*buf++) << 4;
+		ch.b[2] |= hex(*buf++);
+		ch.b[3]  = hex(*buf++) << 4;
+		ch.b[3] |= hex(*buf++);
+		if (!gdbstub_write_dword(mem,ch.l))
+			return NULL;
+		mem += 4;
+		count -= 4;
+	}
+
+	if (count>=2) {
+		ch.b[0]  = hex(*buf++) << 4;
+		ch.b[0] |= hex(*buf++);
+		ch.b[1]  = hex(*buf++) << 4;
+		ch.b[1] |= hex(*buf++);
+		if (!gdbstub_write_word(mem,ch.w))
+			return NULL;
+		mem += 2;
+		count -= 2;
+	}
+
+	if (count>=1) {
+		ch.b[0]  = hex(*buf++) << 4;
+		ch.b[0] |= hex(*buf++);
+		if (!gdbstub_write_byte(mem,ch.b[0]))
+			return NULL;
+	}
+
+	return (char *) buf;
+} /* end hex2mem() */
+
+/*****************************************************************************/
+/*
+ * This table contains the mapping between FRV TBR.TT exception codes,
+ * and signals, which are primarily what GDB understands.  It also
+ * indicates which hardware traps we need to commandeer when
+ * initializing the stub.
+ */
+static const struct brr_to_sig_map {
+	unsigned long	brr_mask;	/* BRR bitmask */
+	unsigned long	tbr_tt;		/* TBR.TT code (in BRR.EBTT) */
+	unsigned int	signo;		/* Signal that we map this into */
+} brr_to_sig_map[] = {
+	{ BRR_EB,	TBR_TT_INSTR_ACC_ERROR,	SIGSEGV		},
+	{ BRR_EB,	TBR_TT_ILLEGAL_INSTR,	SIGILL		},
+	{ BRR_EB,	TBR_TT_PRIV_INSTR,	SIGILL		},
+	{ BRR_EB,	TBR_TT_MP_EXCEPTION,	SIGFPE		},
+	{ BRR_EB,	TBR_TT_DATA_ACC_ERROR,	SIGSEGV		},
+	{ BRR_EB,	TBR_TT_DATA_STR_ERROR,	SIGSEGV		},
+	{ BRR_EB,	TBR_TT_DIVISION_EXCEP,	SIGFPE		},
+	{ BRR_EB,	TBR_TT_COMPOUND_EXCEP,	SIGSEGV		},
+	{ BRR_EB,	TBR_TT_INTERRUPT_13,	SIGALRM		},	/* watchdog */
+	{ BRR_EB,	TBR_TT_INTERRUPT_14,	SIGINT		},	/* GDB serial */
+	{ BRR_EB,	TBR_TT_INTERRUPT_15,	SIGQUIT		},	/* NMI */
+	{ BRR_CB,	0,			SIGUSR1		},
+	{ BRR_TB,	0,			SIGUSR2		},
+	{ BRR_DBNEx,	0,			SIGTRAP		},
+	{ BRR_DBx,	0,			SIGTRAP		},	/* h/w watchpoint */
+	{ BRR_IBx,	0,			SIGTRAP		},	/* h/w breakpoint */
+	{ BRR_CBB,	0,			SIGTRAP		},
+	{ BRR_SB,	0,			SIGTRAP		},
+	{ BRR_ST,	0,			SIGTRAP		},	/* single step */
+	{ 0,		0,			SIGHUP		}	/* default */
+};
+
+/*****************************************************************************/
+/*
+ * convert the FRV BRR register contents into a UNIX signal number
+ */
+static inline int gdbstub_compute_signal(unsigned long brr)
+{
+	const struct brr_to_sig_map *map;
+	unsigned long tbr = (brr & BRR_EBTT) >> 12;
+
+	for (map = brr_to_sig_map; map->brr_mask; map++)
+		if (map->brr_mask & brr)
+			if (!map->tbr_tt || map->tbr_tt == tbr)
+				break;
+
+	return map->signo;
+} /* end gdbstub_compute_signal() */
+
+/*****************************************************************************/
+/*
+ * set a software breakpoint or a hardware breakpoint or watchpoint
+ */
+static int gdbstub_set_breakpoint(unsigned long type, unsigned long addr, unsigned long len)
+{
+	unsigned long tmp;
+	int bkpt, loop, xloop;
+
+	union {
+		struct {
+			unsigned long mask0, mask1;
+		};
+		uint8_t bytes[8];
+	} dbmr;
+
+	//gdbstub_printk("setbkpt(%ld,%08lx,%ld)\n", type, addr, len);
+
+	switch (type) {
+		/* set software breakpoint */
+	case 0:
+		if (addr & 3 || len > 7*4)
+			return -EINVAL;
+
+		for (bkpt = 255; bkpt >= 0; bkpt--)
+			if (!gdbstub_bkpts[bkpt].addr)
+				break;
+		if (bkpt < 0)
+			return -ENOSPC;
+
+		for (loop = 0; loop < len/4; loop++)
+			if (!gdbstub_read_dword(&((uint32_t *) addr)[loop],
+						&gdbstub_bkpts[bkpt].originsns[loop]))
+				return -EFAULT;
+
+		for (loop = 0; loop < len/4; loop++)
+			if (!gdbstub_write_dword(&((uint32_t *) addr)[loop],
+						 BREAK_INSN)
+			    ) {
+				/* need to undo the changes if possible */
+				for (xloop = 0; xloop < loop; xloop++)
+					gdbstub_write_dword(&((uint32_t *) addr)[xloop],
+							    gdbstub_bkpts[bkpt].originsns[xloop]);
+				return -EFAULT;
+			}
+
+		gdbstub_bkpts[bkpt].addr = addr;
+		gdbstub_bkpts[bkpt].len = len;
+
+#if 0
+		gdbstub_printk("Set BKPT[%02x]: %08lx #%d {%04x, %04x} -> { %04x, %04x }\n",
+			       bkpt,
+			       gdbstub_bkpts[bkpt].addr,
+			       gdbstub_bkpts[bkpt].len,
+			       gdbstub_bkpts[bkpt].originsns[0],
+			       gdbstub_bkpts[bkpt].originsns[1],
+			       ((uint32_t *) addr)[0],
+			       ((uint32_t *) addr)[1]
+			       );
+#endif
+		return 0;
+
+		/* set hardware breakpoint */
+	case 1:
+		if (addr & 3 || len != 4)
+			return -EINVAL;
+
+		if (!(__debug_regs->dcr & DCR_IBE0)) {
+			//gdbstub_printk("set h/w break 0: %08lx\n", addr);
+			__debug_regs->dcr |= DCR_IBE0;
+			asm volatile("movgs %0,ibar0" : : "r"(addr));
+			return 0;
+		}
+
+		if (!(__debug_regs->dcr & DCR_IBE1)) {
+			//gdbstub_printk("set h/w break 1: %08lx\n", addr);
+			__debug_regs->dcr |= DCR_IBE1;
+			asm volatile("movgs %0,ibar1" : : "r"(addr));
+			return 0;
+		}
+
+		if (!(__debug_regs->dcr & DCR_IBE2)) {
+			//gdbstub_printk("set h/w break 2: %08lx\n", addr);
+			__debug_regs->dcr |= DCR_IBE2;
+			asm volatile("movgs %0,ibar2" : : "r"(addr));
+			return 0;
+		}
+
+		if (!(__debug_regs->dcr & DCR_IBE3)) {
+			//gdbstub_printk("set h/w break 3: %08lx\n", addr);
+			__debug_regs->dcr |= DCR_IBE3;
+			asm volatile("movgs %0,ibar3" : : "r"(addr));
+			return 0;
+		}
+
+		return -ENOSPC;
+
+		/* set data read/write/access watchpoint */
+	case 2:
+	case 3:
+	case 4:
+		if ((addr & ~7) != ((addr + len - 1) & ~7))
+			return -EINVAL;
+
+		tmp = addr & 7;
+
+		memset(dbmr.bytes, 0xff, sizeof(dbmr.bytes));
+		for (loop = 0; loop < len; loop++)
+			dbmr.bytes[tmp + loop] = 0;
+
+		addr &= ~7;
+
+		if (!(__debug_regs->dcr & (DCR_DRBE0|DCR_DWBE0))) {
+			//gdbstub_printk("set h/w watchpoint 0 type %ld: %08lx\n", type, addr);
+			tmp = type==2 ? DCR_DWBE0 : type==3 ? DCR_DRBE0 : DCR_DRBE0|DCR_DWBE0;
+			__debug_regs->dcr |= tmp;
+			asm volatile("	movgs	%0,dbar0	\n"
+				     "	movgs	%1,dbmr00	\n"
+				     "	movgs	%2,dbmr01	\n"
+				     "	movgs	gr0,dbdr00	\n"
+				     "	movgs	gr0,dbdr01	\n"
+				     : : "r"(addr), "r"(dbmr.mask0), "r"(dbmr.mask1));
+			return 0;
+		}
+
+		if (!(__debug_regs->dcr & (DCR_DRBE1|DCR_DWBE1))) {
+			//gdbstub_printk("set h/w watchpoint 1 type %ld: %08lx\n", type, addr);
+			tmp = type==2 ? DCR_DWBE1 : type==3 ? DCR_DRBE1 : DCR_DRBE1|DCR_DWBE1;
+			__debug_regs->dcr |= tmp;
+			asm volatile("	movgs	%0,dbar1	\n"
+				     "	movgs	%1,dbmr10	\n"
+				     "	movgs	%2,dbmr11	\n"
+				     "	movgs	gr0,dbdr10	\n"
+				     "	movgs	gr0,dbdr11	\n"
+				     : : "r"(addr), "r"(dbmr.mask0), "r"(dbmr.mask1));
+			return 0;
+		}
+
+		return -ENOSPC;
+
+	default:
+		return -EINVAL;
+	}
+
+} /* end gdbstub_set_breakpoint() */
+
+/*****************************************************************************/
+/*
+ * clear a breakpoint or watchpoint
+ */
+int gdbstub_clear_breakpoint(unsigned long type, unsigned long addr, unsigned long len)
+{
+	unsigned long tmp;
+	int bkpt, loop;
+
+	union {
+		struct {
+			unsigned long mask0, mask1;
+		};
+		uint8_t bytes[8];
+	} dbmr;
+
+	//gdbstub_printk("clearbkpt(%ld,%08lx,%ld)\n", type, addr, len);
+
+	switch (type) {
+		/* clear software breakpoint */
+	case 0:
+		for (bkpt = 255; bkpt >= 0; bkpt--)
+			if (gdbstub_bkpts[bkpt].addr == addr && gdbstub_bkpts[bkpt].len == len)
+				break;
+		if (bkpt < 0)
+			return -ENOENT;
+
+		gdbstub_bkpts[bkpt].addr = 0;
+
+		for (loop = 0; loop < len/4; loop++)
+			if (!gdbstub_write_dword(&((uint32_t *) addr)[loop],
+						 gdbstub_bkpts[bkpt].originsns[loop]))
+				return -EFAULT;
+		return 0;
+
+		/* clear hardware breakpoint */
+	case 1:
+		if (addr & 3 || len != 4)
+			return -EINVAL;
+
+#define __get_ibar(X) ({ unsigned long x; asm volatile("movsg ibar"#X",%0" : "=r"(x)); x; })
+
+		if (__debug_regs->dcr & DCR_IBE0 && __get_ibar(0) == addr) {
+			//gdbstub_printk("clear h/w break 0: %08lx\n", addr);
+			__debug_regs->dcr &= ~DCR_IBE0;
+			asm volatile("movgs gr0,ibar0");
+			return 0;
+		}
+
+		if (__debug_regs->dcr & DCR_IBE1 && __get_ibar(1) == addr) {
+			//gdbstub_printk("clear h/w break 1: %08lx\n", addr);
+			__debug_regs->dcr &= ~DCR_IBE1;
+			asm volatile("movgs gr0,ibar1");
+			return 0;
+		}
+
+		if (__debug_regs->dcr & DCR_IBE2 && __get_ibar(2) == addr) {
+			//gdbstub_printk("clear h/w break 2: %08lx\n", addr);
+			__debug_regs->dcr &= ~DCR_IBE2;
+			asm volatile("movgs gr0,ibar2");
+			return 0;
+		}
+
+		if (__debug_regs->dcr & DCR_IBE3 && __get_ibar(3) == addr) {
+			//gdbstub_printk("clear h/w break 3: %08lx\n", addr);
+			__debug_regs->dcr &= ~DCR_IBE3;
+			asm volatile("movgs gr0,ibar3");
+			return 0;
+		}
+
+		return -EINVAL;
+
+		/* clear data read/write/access watchpoint */
+	case 2:
+	case 3:
+	case 4:
+		if ((addr & ~7) != ((addr + len - 1) & ~7))
+			return -EINVAL;
+
+		tmp = addr & 7;
+
+		memset(dbmr.bytes, 0xff, sizeof(dbmr.bytes));
+		for (loop = 0; loop < len; loop++)
+			dbmr.bytes[tmp + loop] = 0;
+
+		addr &= ~7;
+
+#define __get_dbar(X) ({ unsigned long x; asm volatile("movsg dbar"#X",%0" : "=r"(x)); x; })
+#define __get_dbmr0(X) ({ unsigned long x; asm volatile("movsg dbmr"#X"0,%0" : "=r"(x)); x; })
+#define __get_dbmr1(X) ({ unsigned long x; asm volatile("movsg dbmr"#X"1,%0" : "=r"(x)); x; })
+
+		/* consider DBAR 0 */
+		tmp = type==2 ? DCR_DWBE0 : type==3 ? DCR_DRBE0 : DCR_DRBE0|DCR_DWBE0;
+
+		if ((__debug_regs->dcr & (DCR_DRBE0|DCR_DWBE0)) != tmp ||
+		    __get_dbar(0) != addr ||
+		    __get_dbmr0(0) != dbmr.mask0 ||
+		    __get_dbmr1(0) != dbmr.mask1)
+			goto skip_dbar0;
+
+		//gdbstub_printk("clear h/w watchpoint 0 type %ld: %08lx\n", type, addr);
+		__debug_regs->dcr &= ~(DCR_DRBE0|DCR_DWBE0);
+		asm volatile("	movgs	gr0,dbar0	\n"
+			     "	movgs	gr0,dbmr00	\n"
+			     "	movgs	gr0,dbmr01	\n"
+			     "	movgs	gr0,dbdr00	\n"
+			     "	movgs	gr0,dbdr01	\n");
+		return 0;
+
+	skip_dbar0:
+		/* consider DBAR 0 */
+		tmp = type==2 ? DCR_DWBE1 : type==3 ? DCR_DRBE1 : DCR_DRBE1|DCR_DWBE1;
+
+		if ((__debug_regs->dcr & (DCR_DRBE1|DCR_DWBE1)) != tmp ||
+		    __get_dbar(1) != addr ||
+		    __get_dbmr0(1) != dbmr.mask0 ||
+		    __get_dbmr1(1) != dbmr.mask1)
+			goto skip_dbar1;
+
+		//gdbstub_printk("clear h/w watchpoint 1 type %ld: %08lx\n", type, addr);
+		__debug_regs->dcr &= ~(DCR_DRBE1|DCR_DWBE1);
+		asm volatile("	movgs	gr0,dbar1	\n"
+			     "	movgs	gr0,dbmr10	\n"
+			     "	movgs	gr0,dbmr11	\n"
+			     "	movgs	gr0,dbdr10	\n"
+			     "	movgs	gr0,dbdr11	\n");
+		return 0;
+
+	skip_dbar1:
+		return -ENOSPC;
+
+	default:
+		return -EINVAL;
+	}
+} /* end gdbstub_clear_breakpoint() */
+
+/*****************************************************************************/
+/*
+ * check a for an internal software breakpoint, and wind the PC back if necessary
+ */
+static void gdbstub_check_breakpoint(void)
+{
+	unsigned long addr = __debug_frame->pc - 4;
+	int bkpt;
+
+	for (bkpt = 255; bkpt >= 0; bkpt--)
+		if (gdbstub_bkpts[bkpt].addr == addr)
+			break;
+	if (bkpt >= 0)
+		__debug_frame->pc = addr;
+
+	//gdbstub_printk("alter pc [%d] %08lx\n", bkpt, __debug_frame->pc);
+
+} /* end gdbstub_check_breakpoint() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+static void __attribute__((unused)) gdbstub_show_regs(void)
+{
+	uint32_t *reg;
+	int loop;
+
+	gdbstub_printk("\n");
+
+	gdbstub_printk("Frame: @%p [%s]\n",
+		       __debug_frame,
+		       __debug_frame->psr & PSR_S ? "kernel" : "user");
+
+	reg = (uint32_t *) __debug_frame;
+	for (loop = 0; loop < REG__END; loop++) {
+		printk("%s %08x", regnames[loop + 0], reg[loop + 0]);
+
+		if (loop == REG__END - 1 || loop % 5 == 4)
+			printk("\n");
+		else
+			printk(" | ");
+	}
+
+	gdbstub_printk("Process %s (pid: %d)\n", current->comm, current->pid);
+} /* end gdbstub_show_regs() */
+
+/*****************************************************************************/
+/*
+ * dump debugging regs
+ */
+static void __attribute__((unused)) gdbstub_dump_debugregs(void)
+{
+	unsigned long x;
+
+	x = __debug_regs->dcr;
+	gdbstub_printk("DCR    %08lx  ", x);
+
+	x = __debug_regs->brr;
+	gdbstub_printk("BRR %08lx\n", x);
+
+	gdbstub_printk("IBAR0  %08lx  ", __get_ibar(0));
+	gdbstub_printk("IBAR1  %08lx  ", __get_ibar(1));
+	gdbstub_printk("IBAR2  %08lx  ", __get_ibar(2));
+	gdbstub_printk("IBAR3  %08lx\n", __get_ibar(3));
+
+	gdbstub_printk("DBAR0  %08lx  ", __get_dbar(0));
+	gdbstub_printk("DBMR00 %08lx  ", __get_dbmr0(0));
+	gdbstub_printk("DBMR01 %08lx\n", __get_dbmr1(0));
+
+	gdbstub_printk("DBAR1  %08lx  ", __get_dbar(1));
+	gdbstub_printk("DBMR10 %08lx  ", __get_dbmr0(1));
+	gdbstub_printk("DBMR11 %08lx\n", __get_dbmr1(1));
+
+	gdbstub_printk("\n");
+} /* end gdbstub_dump_debugregs() */
+
+/*****************************************************************************/
+/*
+ * dump the MMU state into a structure so that it can be accessed with GDB
+ */
+void gdbstub_get_mmu_state(void)
+{
+	asm volatile("movsg hsr0,%0" : "=r"(__debug_mmu.regs.hsr0));
+	asm volatile("movsg pcsr,%0" : "=r"(__debug_mmu.regs.pcsr));
+	asm volatile("movsg esr0,%0" : "=r"(__debug_mmu.regs.esr0));
+	asm volatile("movsg ear0,%0" : "=r"(__debug_mmu.regs.ear0));
+	asm volatile("movsg epcr0,%0" : "=r"(__debug_mmu.regs.epcr0));
+
+	/* read the protection / SAT registers */
+	__debug_mmu.iamr[0].L  = __get_IAMLR(0);
+	__debug_mmu.iamr[0].P  = __get_IAMPR(0);
+	__debug_mmu.iamr[1].L  = __get_IAMLR(1);
+	__debug_mmu.iamr[1].P  = __get_IAMPR(1);
+	__debug_mmu.iamr[2].L  = __get_IAMLR(2);
+	__debug_mmu.iamr[2].P  = __get_IAMPR(2);
+	__debug_mmu.iamr[3].L  = __get_IAMLR(3);
+	__debug_mmu.iamr[3].P  = __get_IAMPR(3);
+	__debug_mmu.iamr[4].L  = __get_IAMLR(4);
+	__debug_mmu.iamr[4].P  = __get_IAMPR(4);
+	__debug_mmu.iamr[5].L  = __get_IAMLR(5);
+	__debug_mmu.iamr[5].P  = __get_IAMPR(5);
+	__debug_mmu.iamr[6].L  = __get_IAMLR(6);
+	__debug_mmu.iamr[6].P  = __get_IAMPR(6);
+	__debug_mmu.iamr[7].L  = __get_IAMLR(7);
+	__debug_mmu.iamr[7].P  = __get_IAMPR(7);
+	__debug_mmu.iamr[8].L  = __get_IAMLR(8);
+	__debug_mmu.iamr[8].P  = __get_IAMPR(8);
+	__debug_mmu.iamr[9].L  = __get_IAMLR(9);
+	__debug_mmu.iamr[9].P  = __get_IAMPR(9);
+	__debug_mmu.iamr[10].L = __get_IAMLR(10);
+	__debug_mmu.iamr[10].P = __get_IAMPR(10);
+	__debug_mmu.iamr[11].L = __get_IAMLR(11);
+	__debug_mmu.iamr[11].P = __get_IAMPR(11);
+	__debug_mmu.iamr[12].L = __get_IAMLR(12);
+	__debug_mmu.iamr[12].P = __get_IAMPR(12);
+	__debug_mmu.iamr[13].L = __get_IAMLR(13);
+	__debug_mmu.iamr[13].P = __get_IAMPR(13);
+	__debug_mmu.iamr[14].L = __get_IAMLR(14);
+	__debug_mmu.iamr[14].P = __get_IAMPR(14);
+	__debug_mmu.iamr[15].L = __get_IAMLR(15);
+	__debug_mmu.iamr[15].P = __get_IAMPR(15);
+
+	__debug_mmu.damr[0].L  = __get_DAMLR(0);
+	__debug_mmu.damr[0].P  = __get_DAMPR(0);
+	__debug_mmu.damr[1].L  = __get_DAMLR(1);
+	__debug_mmu.damr[1].P  = __get_DAMPR(1);
+	__debug_mmu.damr[2].L  = __get_DAMLR(2);
+	__debug_mmu.damr[2].P  = __get_DAMPR(2);
+	__debug_mmu.damr[3].L  = __get_DAMLR(3);
+	__debug_mmu.damr[3].P  = __get_DAMPR(3);
+	__debug_mmu.damr[4].L  = __get_DAMLR(4);
+	__debug_mmu.damr[4].P  = __get_DAMPR(4);
+	__debug_mmu.damr[5].L  = __get_DAMLR(5);
+	__debug_mmu.damr[5].P  = __get_DAMPR(5);
+	__debug_mmu.damr[6].L  = __get_DAMLR(6);
+	__debug_mmu.damr[6].P  = __get_DAMPR(6);
+	__debug_mmu.damr[7].L  = __get_DAMLR(7);
+	__debug_mmu.damr[7].P  = __get_DAMPR(7);
+	__debug_mmu.damr[8].L  = __get_DAMLR(8);
+	__debug_mmu.damr[8].P  = __get_DAMPR(8);
+	__debug_mmu.damr[9].L  = __get_DAMLR(9);
+	__debug_mmu.damr[9].P  = __get_DAMPR(9);
+	__debug_mmu.damr[10].L = __get_DAMLR(10);
+	__debug_mmu.damr[10].P = __get_DAMPR(10);
+	__debug_mmu.damr[11].L = __get_DAMLR(11);
+	__debug_mmu.damr[11].P = __get_DAMPR(11);
+	__debug_mmu.damr[12].L = __get_DAMLR(12);
+	__debug_mmu.damr[12].P = __get_DAMPR(12);
+	__debug_mmu.damr[13].L = __get_DAMLR(13);
+	__debug_mmu.damr[13].P = __get_DAMPR(13);
+	__debug_mmu.damr[14].L = __get_DAMLR(14);
+	__debug_mmu.damr[14].P = __get_DAMPR(14);
+	__debug_mmu.damr[15].L = __get_DAMLR(15);
+	__debug_mmu.damr[15].P = __get_DAMPR(15);
+
+#ifndef CONFIG_UCLINUX
+	/* read the DAT entries from the TLB */
+	struct __debug_amr *p;
+	int loop;
+
+	asm volatile("movsg tplr,%0" : "=r"(__debug_mmu.regs.tplr));
+	asm volatile("movsg tppr,%0" : "=r"(__debug_mmu.regs.tppr));
+	asm volatile("movsg tpxr,%0" : "=r"(__debug_mmu.regs.tpxr));
+	asm volatile("movsg cxnr,%0" : "=r"(__debug_mmu.regs.cxnr));
+
+	p = __debug_mmu.tlb;
+
+	/* way 0 */
+	asm volatile("movgs %0,tpxr" :: "r"(0 << TPXR_WAY_SHIFT));
+	for (loop = 0; loop < 64; loop++) {
+		asm volatile("tlbpr %0,gr0,#1,#0" :: "r"(loop << PAGE_SHIFT));
+		asm volatile("movsg tplr,%0" : "=r"(p->L));
+		asm volatile("movsg tppr,%0" : "=r"(p->P));
+		p++;
+	}
+
+	/* way 1 */
+	asm volatile("movgs %0,tpxr" :: "r"(1 << TPXR_WAY_SHIFT));
+	for (loop = 0; loop < 64; loop++) {
+		asm volatile("tlbpr %0,gr0,#1,#0" :: "r"(loop << PAGE_SHIFT));
+		asm volatile("movsg tplr,%0" : "=r"(p->L));
+		asm volatile("movsg tppr,%0" : "=r"(p->P));
+		p++;
+	}
+
+	asm volatile("movgs %0,tplr" :: "r"(__debug_mmu.regs.tplr));
+	asm volatile("movgs %0,tppr" :: "r"(__debug_mmu.regs.tppr));
+	asm volatile("movgs %0,tpxr" :: "r"(__debug_mmu.regs.tpxr));
+#endif
+
+} /* end gdbstub_get_mmu_state() */
+
+/*****************************************************************************/
+/*
+ * handle event interception and GDB remote protocol processing
+ * - on entry:
+ *	PSR.ET==0, PSR.S==1 and the CPU is in debug mode
+ *	__debug_frame points to the saved registers
+ *	__frame points to the kernel mode exception frame, if it was in kernel
+ *      mode when the break happened
+ */
+void gdbstub(int type)
+{
+	unsigned long addr, length, loop, dbar, temp, temp2;
+	char *ptr;
+	int sigval = type, flush_cache = 0;
+	uint32_t zero;
+
+	LEDS(0x5000);
+
+	if (sigval < 0) {
+#ifndef CONFIG_GDBSTUB_IMMEDIATE
+		/* return immediately if GDB immediate activation option not set */
+		return;
+#else
+		sigval = SIGINT;
+#endif
+	}
+
+	save_user_regs(&__break_user_context);
+
+#if 0
+	gdbstub_printk("--> gdbstub() %08x %p %08x %08x\n",
+		       __debug_frame->pc,
+		       __debug_frame,
+		       __debug_regs->brr,
+		       __debug_regs->bpsr);
+//	gdbstub_show_regs();
+#endif
+
+	LEDS(0x5001);
+
+	/* if we were interrupted by input on the serial gdbstub serial port,
+	 * restore the context prior to the interrupt so that we return to that
+	 * directly
+	 */
+	temp = (unsigned long) __entry_kerneltrap_table;
+	temp += TBR_TT_INTERRUPT_15;
+	temp2 = (unsigned long) __entry_usertrap_table;
+	temp2 += TBR_TT_INTERRUPT_15;
+
+	if ((__debug_frame->pc & ~15) == temp ||
+	    (__debug_frame->pc & ~15) == temp2
+	    ) {
+		asm volatile("movsg pcsr,%0" : "=r"(__debug_frame->pc));
+		__debug_frame->psr |= PSR_ET;
+		__debug_frame->psr &= ~PSR_S;
+		if (__debug_frame->psr & PSR_PS)
+			__debug_frame->psr |= PSR_S;
+		__debug_regs->brr = (__debug_frame->tbr & TBR_TT) << 12;
+		__debug_regs->brr |= BRR_EB;
+		sigval = SIGINT;
+	}
+
+	LEDS(0x5002);
+
+	/* after a BREAK insn, the PC lands on the far side of it */
+	if (__debug_regs->brr & BRR_SB)
+		gdbstub_check_breakpoint();
+
+	LEDS(0x5003);
+
+	/* handle attempts to write console data via GDB "O" commands */
+	if (__debug_frame->pc == (unsigned long) gdbstub_console_write + 4) {
+		__gdbstub_console_write((struct console *) __debug_frame->gr8,
+					(const char *) __debug_frame->gr9,
+					(unsigned) __debug_frame->gr10);
+		goto done;
+	}
+
+	if (gdbstub_rx_unget) {
+		sigval = SIGINT;
+		goto packet_waiting;
+	}
+
+	if (!sigval)
+		sigval = gdbstub_compute_signal(__debug_regs->brr);
+
+	LEDS(0x5004);
+
+	/* send a message to the debugger's user saying what happened if it may
+	 * not be clear cut (we can't map exceptions onto signals properly)
+	 */
+	if (sigval != SIGINT && sigval != SIGTRAP && sigval != SIGILL) {
+		static const char title[] = "Break ";
+		static const char crlf[] = "\r\n";
+		unsigned long brr = __debug_regs->brr;
+		char hx;
+
+		ptr = output_buffer;
+		*ptr++ = 'O';
+		ptr = mem2hex(title, ptr, sizeof(title) - 1,0);
+
+		hx = hexchars[(brr & 0xf0000000) >> 28];
+		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];
+		hx = hexchars[(brr & 0x0f000000) >> 24];
+		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];
+		hx = hexchars[(brr & 0x00f00000) >> 20];
+		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];
+		hx = hexchars[(brr & 0x000f0000) >> 16];
+		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];
+		hx = hexchars[(brr & 0x0000f000) >> 12];
+		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];
+		hx = hexchars[(brr & 0x00000f00) >> 8];
+		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];
+		hx = hexchars[(brr & 0x000000f0) >> 4];
+		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];
+		hx = hexchars[(brr & 0x0000000f)];
+		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];
+
+		ptr = mem2hex(crlf, ptr, sizeof(crlf) - 1, 0);
+		*ptr = 0;
+		gdbstub_send_packet(output_buffer);	/* send it off... */
+	}
+
+	LEDS(0x5005);
+
+	/* tell the debugger that an exception has occurred */
+	ptr = output_buffer;
+
+	/* Send trap type (converted to signal) */
+	*ptr++ = 'T';
+	*ptr++ = hexchars[sigval >> 4];
+	*ptr++ = hexchars[sigval & 0xf];
+
+	/* Send Error PC */
+	*ptr++ = hexchars[GDB_REG_PC >> 4];
+	*ptr++ = hexchars[GDB_REG_PC & 0xf];
+	*ptr++ = ':';
+	ptr = mem2hex(&__debug_frame->pc, ptr, 4, 0);
+	*ptr++ = ';';
+
+	/*
+	 * Send frame pointer
+	 */
+	*ptr++ = hexchars[GDB_REG_FP >> 4];
+	*ptr++ = hexchars[GDB_REG_FP & 0xf];
+	*ptr++ = ':';
+	ptr = mem2hex(&__debug_frame->fp, ptr, 4, 0);
+	*ptr++ = ';';
+
+	/*
+	 * Send stack pointer
+	 */
+	*ptr++ = hexchars[GDB_REG_SP >> 4];
+	*ptr++ = hexchars[GDB_REG_SP & 0xf];
+	*ptr++ = ':';
+	ptr = mem2hex(&__debug_frame->sp, ptr, 4, 0);
+	*ptr++ = ';';
+
+	*ptr++ = 0;
+	gdbstub_send_packet(output_buffer);	/* send it off... */
+
+	LEDS(0x5006);
+
+ packet_waiting:
+	gdbstub_get_mmu_state();
+
+	/* wait for input from remote GDB */
+	while (1) {
+		output_buffer[0] = 0;
+
+		LEDS(0x5007);
+		gdbstub_recv_packet(input_buffer);
+		LEDS(0x5600 | input_buffer[0]);
+
+		switch (input_buffer[0]) {
+			/* request repeat of last signal number */
+		case '?':
+			output_buffer[0] = 'S';
+			output_buffer[1] = hexchars[sigval >> 4];
+			output_buffer[2] = hexchars[sigval & 0xf];
+			output_buffer[3] = 0;
+			break;
+
+		case 'd':
+			/* toggle debug flag */
+			break;
+
+			/* return the value of the CPU registers
+			 * - GR0,  GR1,  GR2,  GR3,  GR4,  GR5,  GR6,  GR7,
+			 * - GR8,  GR9,  GR10, GR11, GR12, GR13, GR14, GR15,
+			 * - GR16, GR17, GR18, GR19, GR20, GR21, GR22, GR23,
+			 * - GR24, GR25, GR26, GR27, GR28, GR29, GR30, GR31,
+			 * - GR32, GR33, GR34, GR35, GR36, GR37, GR38, GR39,
+			 * - GR40, GR41, GR42, GR43, GR44, GR45, GR46, GR47,
+			 * - GR48, GR49, GR50, GR51, GR52, GR53, GR54, GR55,
+			 * - GR56, GR57, GR58, GR59, GR60, GR61, GR62, GR63,
+			 * - FP0,  FP1,  FP2,  FP3,  FP4,  FP5,  FP6,  FP7,
+			 * - FP8,  FP9,  FP10, FP11, FP12, FP13, FP14, FP15,
+			 * - FP16, FP17, FP18, FP19, FP20, FP21, FP22, FP23,
+			 * - FP24, FP25, FP26, FP27, FP28, FP29, FP30, FP31,
+			 * - FP32, FP33, FP34, FP35, FP36, FP37, FP38, FP39,
+			 * - FP40, FP41, FP42, FP43, FP44, FP45, FP46, FP47,
+			 * - FP48, FP49, FP50, FP51, FP52, FP53, FP54, FP55,
+			 * - FP56, FP57, FP58, FP59, FP60, FP61, FP62, FP63,
+			 * - PC, PSR, CCR, CCCR,
+			 * - _X132, _X133, _X134
+			 * - TBR, BRR, DBAR0, DBAR1, DBAR2, DBAR3,
+			 * - _X141, _X142, _X143, _X144,
+			 * - LR, LCR
+			 */
+		case 'g':
+			zero = 0;
+			ptr = output_buffer;
+
+			/* deal with GR0, GR1-GR27, GR28-GR31, GR32-GR63 */
+			ptr = mem2hex(&zero, ptr, 4, 0);
+
+			for (loop = 1; loop <= 27; loop++)
+				ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(loop),
+					      ptr, 4, 0);
+			temp = (unsigned long) __frame;
+			ptr = mem2hex(&temp, ptr, 4, 0);
+			ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(29), ptr, 4, 0);
+			ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(30), ptr, 4, 0);
+#ifndef CONFIG_UCLINUX
+			ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(31), ptr, 4, 0);
+#else
+			temp = (unsigned long) __debug_frame;
+			ptr = mem2hex(&temp, ptr, 4, 0);
+#endif
+
+			for (loop = 32; loop <= 63; loop++)
+				ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(loop),
+					      ptr, 4, 0);
+
+			/* deal with FR0-FR63 */
+			for (loop = 0; loop <= 63; loop++)
+				ptr = mem2hex((unsigned long *)&__break_user_context +
+					      __FPMEDIA_FR(loop),
+					      ptr, 4, 0);
+
+			/* deal with special registers */
+			ptr = mem2hex(&__debug_frame->pc,    ptr, 4, 0);
+			ptr = mem2hex(&__debug_frame->psr,   ptr, 4, 0);
+			ptr = mem2hex(&__debug_frame->ccr,   ptr, 4, 0);
+			ptr = mem2hex(&__debug_frame->cccr,  ptr, 4, 0);
+			ptr = mem2hex(&zero, ptr, 4, 0);
+			ptr = mem2hex(&zero, ptr, 4, 0);
+			ptr = mem2hex(&zero, ptr, 4, 0);
+			ptr = mem2hex(&__debug_frame->tbr,   ptr, 4, 0);
+			ptr = mem2hex(&__debug_regs->brr ,   ptr, 4, 0);
+
+			asm volatile("movsg dbar0,%0" : "=r"(dbar));
+			ptr = mem2hex(&dbar, ptr, 4, 0);
+			asm volatile("movsg dbar1,%0" : "=r"(dbar));
+			ptr = mem2hex(&dbar, ptr, 4, 0);
+			asm volatile("movsg dbar2,%0" : "=r"(dbar));
+			ptr = mem2hex(&dbar, ptr, 4, 0);
+			asm volatile("movsg dbar3,%0" : "=r"(dbar));
+			ptr = mem2hex(&dbar, ptr, 4, 0);
+
+			asm volatile("movsg scr0,%0" : "=r"(dbar));
+			ptr = mem2hex(&dbar, ptr, 4, 0);
+			asm volatile("movsg scr1,%0" : "=r"(dbar));
+			ptr = mem2hex(&dbar, ptr, 4, 0);
+			asm volatile("movsg scr2,%0" : "=r"(dbar));
+			ptr = mem2hex(&dbar, ptr, 4, 0);
+			asm volatile("movsg scr3,%0" : "=r"(dbar));
+			ptr = mem2hex(&dbar, ptr, 4, 0);
+
+			ptr = mem2hex(&__debug_frame->lr, ptr, 4, 0);
+			ptr = mem2hex(&__debug_frame->lcr, ptr, 4, 0);
+
+			ptr = mem2hex(&__debug_frame->iacc0, ptr, 8, 0);
+
+			ptr = mem2hex(&__break_user_context.f.fsr[0], ptr, 4, 0);
+
+			for (loop = 0; loop <= 7; loop++)
+				ptr = mem2hex(&__break_user_context.f.acc[loop], ptr, 4, 0);
+
+			ptr = mem2hex(&__break_user_context.f.accg, ptr, 8, 0);
+
+			for (loop = 0; loop <= 1; loop++)
+				ptr = mem2hex(&__break_user_context.f.msr[loop], ptr, 4, 0);
+
+			ptr = mem2hex(&__debug_frame->gner0, ptr, 4, 0);
+			ptr = mem2hex(&__debug_frame->gner1, ptr, 4, 0);
+
+			ptr = mem2hex(&__break_user_context.f.fner[0], ptr, 4, 0);
+			ptr = mem2hex(&__break_user_context.f.fner[1], ptr, 4, 0);
+
+			break;
+
+			/* set the values of the CPU registers */
+		case 'G':
+			ptr = &input_buffer[1];
+
+			/* deal with GR0, GR1-GR27, GR28-GR31, GR32-GR63 */
+			ptr = hex2mem(ptr, &temp, 4);
+
+			for (loop = 1; loop <= 27; loop++)
+				ptr = hex2mem(ptr, (unsigned long *)__debug_frame + REG_GR(loop),
+					      4);
+
+			ptr = hex2mem(ptr, &temp, 4);
+			__frame = (struct pt_regs *) temp;
+			ptr = hex2mem(ptr, &__debug_frame->gr29, 4);
+			ptr = hex2mem(ptr, &__debug_frame->gr30, 4);
+#ifndef CONFIG_UCLINUX
+			ptr = hex2mem(ptr, &__debug_frame->gr31, 4);
+#else
+			ptr = hex2mem(ptr, &temp, 4);
+#endif
+
+			for (loop = 32; loop <= 63; loop++)
+				ptr = hex2mem(ptr, (unsigned long *)__debug_frame + REG_GR(loop),
+					      4);
+
+			/* deal with FR0-FR63 */
+			for (loop = 0; loop <= 63; loop++)
+				ptr = mem2hex((unsigned long *)&__break_user_context +
+					      __FPMEDIA_FR(loop),
+					      ptr, 4, 0);
+
+			/* deal with special registers */
+			ptr = hex2mem(ptr, &__debug_frame->pc,  4);
+			ptr = hex2mem(ptr, &__debug_frame->psr, 4);
+			ptr = hex2mem(ptr, &__debug_frame->ccr, 4);
+			ptr = hex2mem(ptr, &__debug_frame->cccr,4);
+
+			for (loop = 132; loop <= 140; loop++)
+				ptr = hex2mem(ptr, &temp, 4);
+
+			ptr = hex2mem(ptr, &temp, 4);
+			asm volatile("movgs %0,scr0" :: "r"(temp));
+			ptr = hex2mem(ptr, &temp, 4);
+			asm volatile("movgs %0,scr1" :: "r"(temp));
+			ptr = hex2mem(ptr, &temp, 4);
+			asm volatile("movgs %0,scr2" :: "r"(temp));
+			ptr = hex2mem(ptr, &temp, 4);
+			asm volatile("movgs %0,scr3" :: "r"(temp));
+
+			ptr = hex2mem(ptr, &__debug_frame->lr,  4);
+			ptr = hex2mem(ptr, &__debug_frame->lcr, 4);
+
+			ptr = hex2mem(ptr, &__debug_frame->iacc0, 8);
+
+			ptr = hex2mem(ptr, &__break_user_context.f.fsr[0], 4);
+
+			for (loop = 0; loop <= 7; loop++)
+				ptr = hex2mem(ptr, &__break_user_context.f.acc[loop], 4);
+
+			ptr = hex2mem(ptr, &__break_user_context.f.accg, 8);
+
+			for (loop = 0; loop <= 1; loop++)
+				ptr = hex2mem(ptr, &__break_user_context.f.msr[loop], 4);
+
+			ptr = hex2mem(ptr, &__debug_frame->gner0, 4);
+			ptr = hex2mem(ptr, &__debug_frame->gner1, 4);
+
+			ptr = hex2mem(ptr, &__break_user_context.f.fner[0], 4);
+			ptr = hex2mem(ptr, &__break_user_context.f.fner[1], 4);
+
+			gdbstub_strcpy(output_buffer,"OK");
+			break;
+
+			/* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
+		case 'm':
+			ptr = &input_buffer[1];
+
+			if (hexToInt(&ptr, &addr) &&
+			    *ptr++ == ',' &&
+			    hexToInt(&ptr, &length)
+			    ) {
+				if (mem2hex((char *)addr, output_buffer, length, 1))
+					break;
+				gdbstub_strcpy (output_buffer, "E03");
+			}
+			else {
+				gdbstub_strcpy(output_buffer,"E01");
+			}
+			break;
+
+			/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+		case 'M':
+			ptr = &input_buffer[1];
+
+			if (hexToInt(&ptr, &addr) &&
+			    *ptr++ == ',' &&
+			    hexToInt(&ptr, &length) &&
+			    *ptr++ == ':'
+			    ) {
+				if (hex2mem(ptr, (char *)addr, length)) {
+					gdbstub_strcpy(output_buffer, "OK");
+				}
+				else {
+					gdbstub_strcpy(output_buffer, "E03");
+				}
+			}
+			else
+				gdbstub_strcpy(output_buffer, "E02");
+
+			flush_cache = 1;
+			break;
+
+			/* PNN,=RRRRRRRR: Write value R to reg N return OK */
+		case 'P':
+			ptr = &input_buffer[1];
+
+			if (!hexToInt(&ptr, &addr) ||
+			    *ptr++ != '=' ||
+			    !hexToInt(&ptr, &temp)
+			    ) {
+				gdbstub_strcpy(output_buffer, "E01");
+				break;
+			}
+
+			temp2 = 1;
+			switch (addr) {
+			case GDB_REG_GR(0):
+				break;
+			case GDB_REG_GR(1) ... GDB_REG_GR(63):
+				__break_user_context.i.gr[addr - GDB_REG_GR(0)] = temp;
+				break;
+			case GDB_REG_FR(0) ... GDB_REG_FR(63):
+				__break_user_context.f.fr[addr - GDB_REG_FR(0)] = temp;
+				break;
+			case GDB_REG_PC:
+				__break_user_context.i.pc = temp;
+				break;
+			case GDB_REG_PSR:
+				__break_user_context.i.psr = temp;
+				break;
+			case GDB_REG_CCR:
+				__break_user_context.i.ccr = temp;
+				break;
+			case GDB_REG_CCCR:
+				__break_user_context.i.cccr = temp;
+				break;
+			case GDB_REG_BRR:
+				__debug_regs->brr = temp;
+				break;
+			case GDB_REG_LR:
+				__break_user_context.i.lr = temp;
+				break;
+			case GDB_REG_LCR:
+				__break_user_context.i.lcr = temp;
+				break;
+			case GDB_REG_FSR0:
+				__break_user_context.f.fsr[0] = temp;
+				break;
+			case GDB_REG_ACC(0) ... GDB_REG_ACC(7):
+				__break_user_context.f.acc[addr - GDB_REG_ACC(0)] = temp;
+				break;
+			case GDB_REG_ACCG(0):
+				*(uint32_t *) &__break_user_context.f.accg[0] = temp;
+				break;
+			case GDB_REG_ACCG(4):
+				*(uint32_t *) &__break_user_context.f.accg[4] = temp;
+				break;
+			case GDB_REG_MSR(0) ... GDB_REG_MSR(1):
+				__break_user_context.f.msr[addr - GDB_REG_MSR(0)] = temp;
+				break;
+			case GDB_REG_GNER(0) ... GDB_REG_GNER(1):
+				__break_user_context.i.gner[addr - GDB_REG_GNER(0)] = temp;
+				break;
+			case GDB_REG_FNER(0) ... GDB_REG_FNER(1):
+				__break_user_context.f.fner[addr - GDB_REG_FNER(0)] = temp;
+				break;
+			default:
+				temp2 = 0;
+				break;
+			}
+
+			if (temp2) {
+				gdbstub_strcpy(output_buffer, "OK");
+			}
+			else {
+				gdbstub_strcpy(output_buffer, "E02");
+			}
+			break;
+
+			/* cAA..AA    Continue at address AA..AA(optional) */
+		case 'c':
+			/* try to read optional parameter, pc unchanged if no parm */
+			ptr = &input_buffer[1];
+			if (hexToInt(&ptr, &addr))
+				__debug_frame->pc = addr;
+			goto done;
+
+			/* kill the program */
+		case 'k' :
+			goto done;	/* just continue */
+
+
+			/* reset the whole machine (FIXME: system dependent) */
+		case 'r':
+			break;
+
+
+			/* step to next instruction */
+		case 's':
+			__debug_regs->dcr |= DCR_SE;
+			goto done;
+
+			/* set baud rate (bBB) */
+		case 'b':
+			ptr = &input_buffer[1];
+			if (!hexToInt(&ptr, &temp)) {
+				gdbstub_strcpy(output_buffer,"B01");
+				break;
+			}
+
+			if (temp) {
+				/* ack before changing speed */
+				gdbstub_send_packet("OK");
+				gdbstub_set_baud(temp);
+			}
+			break;
+
+			/* set breakpoint */
+		case 'Z':
+			ptr = &input_buffer[1];
+
+			if (!hexToInt(&ptr,&temp) || *ptr++ != ',' ||
+			    !hexToInt(&ptr,&addr) || *ptr++ != ',' ||
+			    !hexToInt(&ptr,&length)
+			    ) {
+				gdbstub_strcpy(output_buffer,"E01");
+				break;
+			}
+
+			if (temp >= 5) {
+				gdbstub_strcpy(output_buffer,"E03");
+				break;
+			}
+
+			if (gdbstub_set_breakpoint(temp, addr, length) < 0) {
+				gdbstub_strcpy(output_buffer,"E03");
+				break;
+			}
+
+			if (temp == 0)
+				flush_cache = 1; /* soft bkpt by modified memory */
+
+			gdbstub_strcpy(output_buffer,"OK");
+			break;
+
+			/* clear breakpoint */
+		case 'z':
+			ptr = &input_buffer[1];
+
+			if (!hexToInt(&ptr,&temp) || *ptr++ != ',' ||
+			    !hexToInt(&ptr,&addr) || *ptr++ != ',' ||
+			    !hexToInt(&ptr,&length)
+			    ) {
+				gdbstub_strcpy(output_buffer,"E01");
+				break;
+			}
+
+			if (temp >= 5) {
+				gdbstub_strcpy(output_buffer,"E03");
+				break;
+			}
+
+			if (gdbstub_clear_breakpoint(temp, addr, length) < 0) {
+				gdbstub_strcpy(output_buffer,"E03");
+				break;
+			}
+
+			if (temp == 0)
+				flush_cache = 1; /* soft bkpt by modified memory */
+
+			gdbstub_strcpy(output_buffer,"OK");
+			break;
+
+		default:
+			gdbstub_proto("### GDB Unsupported Cmd '%s'\n",input_buffer);
+			break;
+		}
+
+		/* reply to the request */
+		LEDS(0x5009);
+		gdbstub_send_packet(output_buffer);
+	}
+
+ done:
+	restore_user_regs(&__break_user_context);
+
+	//gdbstub_dump_debugregs();
+	//gdbstub_printk("<-- gdbstub() %08x\n", __debug_frame->pc);
+
+	/* need to flush the instruction cache before resuming, as we may have
+	 * deposited a breakpoint, and the icache probably has no way of
+	 * knowing that a data ref to some location may have changed something
+	 * that is in the instruction cache.  NB: We flush both caches, just to
+	 * be sure...
+	 */
+
+	/* note: flushing the icache will clobber EAR0 on the FR451 */
+	if (flush_cache)
+		gdbstub_purge_cache();
+
+	LEDS(0x5666);
+
+} /* end gdbstub() */
+
+/*****************************************************************************/
+/*
+ * initialise the GDB stub
+ */
+void __init gdbstub_init(void)
+{
+#ifdef CONFIG_GDBSTUB_IMMEDIATE
+	unsigned char ch;
+	int ret;
+#endif
+
+	gdbstub_printk("%s", gdbstub_banner);
+
+	gdbstub_io_init();
+
+	/* try to talk to GDB (or anyone insane enough to want to type GDB protocol by hand) */
+	gdbstub_proto("### GDB Tx ACK\n");
+	gdbstub_tx_char('+'); /* 'hello world' */
+
+#ifdef CONFIG_GDBSTUB_IMMEDIATE
+	gdbstub_printk("GDB Stub waiting for packet\n");
+
+	/*
+	 * In case GDB is started before us, ack any packets
+	 * (presumably "$?#xx") sitting there.
+	 */
+	do { gdbstub_rx_char(&ch, 0); } while (ch != '$');
+	do { gdbstub_rx_char(&ch, 0); } while (ch != '#');
+	do { ret = gdbstub_rx_char(&ch, 0); } while (ret != 0); /* eat first csum byte */
+	do { ret = gdbstub_rx_char(&ch, 0); } while (ret != 0); /* eat second csum byte */
+
+	gdbstub_proto("### GDB Tx NAK\n");
+	gdbstub_tx_char('-'); /* nak it */
+
+#else
+	gdbstub_printk("GDB Stub set\n");
+#endif
+
+#if 0
+	/* send banner */
+	ptr = output_buffer;
+	*ptr++ = 'O';
+	ptr = mem2hex(gdbstub_banner, ptr, sizeof(gdbstub_banner) - 1, 0);
+	gdbstub_send_packet(output_buffer);
+#endif
+#if defined(CONFIG_GDBSTUB_CONSOLE) && defined(CONFIG_GDBSTUB_IMMEDIATE)
+	register_console(&gdbstub_console);
+#endif
+
+} /* end gdbstub_init() */
+
+/*****************************************************************************/
+/*
+ * register the console at a more appropriate time
+ */
+#if defined (CONFIG_GDBSTUB_CONSOLE) && !defined(CONFIG_GDBSTUB_IMMEDIATE)
+static int __init gdbstub_postinit(void)
+{
+	printk("registering console\n");
+	register_console(&gdbstub_console);
+	return 0;
+} /* end gdbstub_postinit() */
+
+__initcall(gdbstub_postinit);
+#endif
+
+/*****************************************************************************/
+/*
+ * send an exit message to GDB
+ */
+void gdbstub_exit(int status)
+{
+	unsigned char checksum;
+	int count;
+	unsigned char ch;
+
+	sprintf(output_buffer,"W%02x",status&0xff);
+
+	gdbstub_tx_char('$');
+	checksum = 0;
+	count = 0;
+
+	while ((ch = output_buffer[count]) != 0) {
+		gdbstub_tx_char(ch);
+		checksum += ch;
+		count += 1;
+	}
+
+	gdbstub_tx_char('#');
+	gdbstub_tx_char(hexchars[checksum >> 4]);
+	gdbstub_tx_char(hexchars[checksum & 0xf]);
+
+	/* make sure the output is flushed, or else RedBoot might clobber it */
+	gdbstub_tx_char('-');
+	gdbstub_tx_flush();
+
+} /* end gdbstub_exit() */
+
+/*****************************************************************************/
+/*
+ * GDB wants to call malloc() and free() to allocate memory for calling kernel
+ * functions directly from its command line
+ */
+static void *malloc(size_t size) __attribute__((unused));
+static void *malloc(size_t size)
+{
+	return kmalloc(size, GFP_ATOMIC);
+}
+
+static void free(void *p) __attribute__((unused));
+static void free(void *p)
+{
+	kfree(p);
+}
+
+static uint32_t ___get_HSR0(void) __attribute__((unused));
+static uint32_t ___get_HSR0(void)
+{
+	return __get_HSR(0);
+}
+
+static uint32_t ___set_HSR0(uint32_t x) __attribute__((unused));
+static uint32_t ___set_HSR0(uint32_t x)
+{
+	__set_HSR(0, x);
+	return __get_HSR(0);
+}
diff -urN linux-2.4.29/arch/frv/kernel/head.inc linux-2.4.29-uc1/arch/frv/kernel/head.inc
--- linux-2.4.29/arch/frv/kernel/head.inc	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/head.inc	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,50 @@
+/* head.inc: head common definitions -*- asm -*-
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+
+#if defined(CONFIG_MB93090_MB00)
+#define LED_ADDR (0x21200000+4)
+
+.macro LEDS val
+	sethi.p		%hi(0xFFC00030),gr3
+	setlo		%lo(0xFFC00030),gr3
+	lduh		@(gr3,gr0),gr3
+	andicc		gr3,#0x100,gr0,icc0
+	bne		icc0,0,999f
+	
+	setlos		#~\val,gr3
+	st		gr3,@(gr30,gr0)
+	membar
+	dcf		@(gr30,gr0)
+    999:
+.endm
+
+#elif defined(CONFIG_MB93093_PDK)
+#define LED_ADDR (0x20000023)
+
+.macro LEDS val
+	setlos		#\val,gr3
+	stb		gr3,@(gr30,gr0)
+	membar
+.endm
+
+#else
+#define LED_ADDR 0
+
+.macro LEDS val
+.endm
+#endif	
+
+#ifndef CONFIG_UCLINUX
+__sdram_base = 0x00000000		/* base address to which SDRAM relocated */
+#else
+__sdram_base = 0xc0000000		/* base address to which SDRAM relocated */
+#endif
diff -urN linux-2.4.29/arch/frv/kernel/head-mmu-fr451.S linux-2.4.29-uc1/arch/frv/kernel/head-mmu-fr451.S
--- linux-2.4.29/arch/frv/kernel/head-mmu-fr451.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/head-mmu-fr451.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,375 @@
+/* head-mmu-fr451.S: FR451 mmu-linux specific bits of initialisation
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/mem-layout.h>
+#include <asm/spr-regs.h>
+#include <asm/mb86943a.h>
+#include "head.inc"
+
+
+#define __400_DBR0	0xfe000e00
+#define __400_DBR1	0xfe000e08
+#define __400_DBR2	0xfe000e10
+#define __400_DBR3	0xfe000e18
+#define __400_DAM0	0xfe000f00
+#define __400_DAM1	0xfe000f08
+#define __400_DAM2	0xfe000f10
+#define __400_DAM3	0xfe000f18
+#define __400_LGCR	0xfe000010
+#define __400_LCR	0xfe000100
+#define __400_LSBR	0xfe000c00
+
+	.section	.text.init,"ax"
+	.balign		4
+
+###############################################################################
+#
+# describe the position and layout of the SDRAM controller registers
+#
+#	ENTRY:			EXIT:
+# GR5	-			cacheline size
+# GR11	-			displacement of 2nd SDRAM addr reg from GR14
+# GR12	-			displacement of 3rd SDRAM addr reg from GR14
+# GR13	-			displacement of 4th SDRAM addr reg from GR14
+# GR14	-			address of 1st SDRAM addr reg
+# GR15	-			amount to shift address by to match SDRAM addr reg
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+# CC0	-			T if DBR0 is present
+# CC1	-			T if DBR1 is present
+# CC2	-			T if DBR2 is present
+# CC3	-			T if DBR3 is present
+#
+###############################################################################
+	.globl		__head_fr451_describe_sdram
+__head_fr451_describe_sdram:
+	sethi.p		%hi(__400_DBR0),gr14
+	setlo		%lo(__400_DBR0),gr14
+	setlos.p	#__400_DBR1-__400_DBR0,gr11
+	setlos		#__400_DBR2-__400_DBR0,gr12
+	setlos.p	#__400_DBR3-__400_DBR0,gr13
+	setlos		#32,gr5			; cacheline size
+	setlos.p	#0,gr15			; amount to shift addr reg by
+	setlos		#0x00ff,gr4
+	movgs		gr4,cccr		; extant DARS/DAMK regs
+	bralr
+
+###############################################################################
+#
+# rearrange the bus controller registers
+#
+#	ENTRY:			EXIT:
+# GR26	&__head_reference	[saved]
+# GR30	LED address		revised LED address
+#
+###############################################################################
+	.globl		__head_fr451_set_busctl
+__head_fr451_set_busctl:
+	sethi.p		%hi(__400_LGCR),gr4
+	setlo		%lo(__400_LGCR),gr4
+	sethi.p		%hi(__400_LSBR),gr10
+	setlo		%lo(__400_LSBR),gr10
+	sethi.p		%hi(__400_LCR),gr11
+	setlo		%lo(__400_LCR),gr11
+
+	# set the bus controller
+	ldi		@(gr4,#0),gr5
+	ori		gr5,#0xff,gr5		; make sure all chip-selects are enabled
+	sti		gr5,@(gr4,#0)
+
+	sethi.p		%hi(__region_CS1),gr4
+	setlo		%lo(__region_CS1),gr4
+	sethi.p		%hi(__region_CS1_M),gr5
+	setlo		%lo(__region_CS1_M),gr5
+	sethi.p		%hi(__region_CS1_C),gr6
+	setlo		%lo(__region_CS1_C),gr6
+	sti		gr4,@(gr10,#1*0x08)
+	sti		gr5,@(gr10,#1*0x08+0x100)
+	sti		gr6,@(gr11,#1*0x08)
+	sethi.p		%hi(__region_CS2),gr4
+	setlo		%lo(__region_CS2),gr4
+	sethi.p		%hi(__region_CS2_M),gr5
+	setlo		%lo(__region_CS2_M),gr5
+	sethi.p		%hi(__region_CS2_C),gr6
+	setlo		%lo(__region_CS2_C),gr6
+	sti		gr4,@(gr10,#2*0x08)
+	sti		gr5,@(gr10,#2*0x08+0x100)
+	sti		gr6,@(gr11,#2*0x08)
+	sethi.p		%hi(__region_CS3),gr4
+	setlo		%lo(__region_CS3),gr4
+	sethi.p		%hi(__region_CS3_M),gr5
+	setlo		%lo(__region_CS3_M),gr5
+	sethi.p		%hi(__region_CS3_C),gr6
+	setlo		%lo(__region_CS3_C),gr6
+	sti		gr4,@(gr10,#3*0x08)
+	sti		gr5,@(gr10,#3*0x08+0x100)
+	sti		gr6,@(gr11,#3*0x08)
+	sethi.p		%hi(__region_CS4),gr4
+	setlo		%lo(__region_CS4),gr4
+	sethi.p		%hi(__region_CS4_M),gr5
+	setlo		%lo(__region_CS4_M),gr5
+	sethi.p		%hi(__region_CS4_C),gr6
+	setlo		%lo(__region_CS4_C),gr6
+	sti		gr4,@(gr10,#4*0x08)
+	sti		gr5,@(gr10,#4*0x08+0x100)
+	sti		gr6,@(gr11,#4*0x08)
+	sethi.p		%hi(__region_CS5),gr4
+	setlo		%lo(__region_CS5),gr4
+	sethi.p		%hi(__region_CS5_M),gr5
+	setlo		%lo(__region_CS5_M),gr5
+	sethi.p		%hi(__region_CS5_C),gr6
+	setlo		%lo(__region_CS5_C),gr6
+	sti		gr4,@(gr10,#5*0x08)
+	sti		gr5,@(gr10,#5*0x08+0x100)
+	sti		gr6,@(gr11,#5*0x08)
+	sethi.p		%hi(__region_CS6),gr4
+	setlo		%lo(__region_CS6),gr4
+	sethi.p		%hi(__region_CS6_M),gr5
+	setlo		%lo(__region_CS6_M),gr5
+	sethi.p		%hi(__region_CS6_C),gr6
+	setlo		%lo(__region_CS6_C),gr6
+	sti		gr4,@(gr10,#6*0x08)
+	sti		gr5,@(gr10,#6*0x08+0x100)
+	sti		gr6,@(gr11,#6*0x08)
+	sethi.p		%hi(__region_CS7),gr4
+	setlo		%lo(__region_CS7),gr4
+	sethi.p		%hi(__region_CS7_M),gr5
+	setlo		%lo(__region_CS7_M),gr5
+	sethi.p		%hi(__region_CS7_C),gr6
+	setlo		%lo(__region_CS7_C),gr6
+	sti		gr4,@(gr10,#7*0x08)
+	sti		gr5,@(gr10,#7*0x08+0x100)
+	sti		gr6,@(gr11,#7*0x08)
+	membar
+	bar
+
+	# adjust LED bank address
+#ifdef CONFIG_MB93091_VDK
+	sethi.p		%hi(__region_CS2 + 0x01200004),gr30
+	setlo		%lo(__region_CS2 + 0x01200004),gr30
+#endif
+	bralr
+
+###############################################################################
+#
+# determine the total SDRAM size
+#
+#	ENTRY:			EXIT:
+# GR25	-			SDRAM size
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+#
+###############################################################################
+	.globl		__head_fr451_survey_sdram
+__head_fr451_survey_sdram:
+	sethi.p		%hi(__400_DAM0),gr11
+	setlo		%lo(__400_DAM0),gr11
+	sethi.p		%hi(__400_DBR0),gr12
+	setlo		%lo(__400_DBR0),gr12
+
+	sethi.p		%hi(0xfe000000),gr17		; unused SDRAM DBR value
+	setlo		%lo(0xfe000000),gr17
+	setlos		#0,gr25
+
+	ldi		@(gr12,#0x00),gr4		; DAR0
+	subcc		gr4,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS0
+	ldi		@(gr11,#0x00),gr6		; DAM0: bits 31:20 match addr 31:20
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS0:
+
+	ldi		@(gr12,#0x08),gr4		; DAR1
+	subcc		gr4,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS1
+	ldi		@(gr11,#0x08),gr6		; DAM1: bits 31:20 match addr 31:20
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS1:
+
+	ldi		@(gr12,#0x10),gr4		; DAR2
+	subcc		gr4,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS2
+	ldi		@(gr11,#0x10),gr6		; DAM2: bits 31:20 match addr 31:20
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS2:
+
+	ldi		@(gr12,#0x18),gr4		; DAR3
+	subcc		gr4,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS3
+	ldi		@(gr11,#0x18),gr6		; DAM3: bits 31:20 match addr 31:20
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS3:
+	bralr
+
+###############################################################################
+#
+# set the protection map with the I/DAMPR registers
+#
+#	ENTRY:			EXIT:
+# GR25	SDRAM size		[saved]
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+#
+#
+# Using this map:
+#	REGISTERS	ADDRESS RANGE		VIEW
+#	===============	======================	===============================
+#	IAMPR0/DAMPR0	0xC0000000-0xCFFFFFFF	Cached kernel RAM Window
+#	DAMPR11		0xE0000000-0xFFFFFFFF	Uncached I/O
+#
+###############################################################################
+	.globl		__head_fr451_set_protection
+__head_fr451_set_protection:
+	movsg		lr,gr27
+
+	# set the I/O region protection registers for FR451 in MMU mode
+#define PGPROT_IO	xAMPRx_L|xAMPRx_M|xAMPRx_S_KERNEL|xAMPRx_C|xAMPRx_V
+
+	sethi.p		%hi(__region_IO),gr5
+	setlo		%lo(__region_IO),gr5
+	setlos		#PGPROT_IO|xAMPRx_SS_512Mb,gr4
+	or		gr4,gr5,gr4
+	movgs		gr5,damlr11			; General I/O tile
+	movgs		gr4,dampr11
+
+	# need to open a window onto at least part of the RAM for the kernel's use
+	sethi.p		%hi(__sdram_base),gr8
+	setlo		%lo(__sdram_base),gr8		; physical address
+	sethi.p		%hi(__page_offset),gr9
+	setlo		%lo(__page_offset),gr9		; virtual address
+
+	setlos		#xAMPRx_L|xAMPRx_M|xAMPRx_SS_256Mb|xAMPRx_S_KERNEL|xAMPRx_V,gr11
+	or		gr8,gr11,gr8
+
+	movgs		gr9,iamlr0			; mapped from real address 0
+	movgs		gr8,iampr0			; cached kernel memory at 0xC0000000
+	movgs		gr9,damlr0
+	movgs		gr8,dampr0
+
+	# set a temporary mapping for the kernel running at address 0 until we've turned on the MMU
+	sethi.p		%hi(__sdram_base),gr9
+	setlo		%lo(__sdram_base),gr9		; virtual address
+
+	and.p		gr4,gr11,gr4
+	and		gr5,gr11,gr5
+	or.p		gr4,gr11,gr4
+	or		gr5,gr11,gr5
+
+	movgs		gr9,iamlr1			; mapped from real address 0
+	movgs		gr8,iampr1			; cached kernel memory at 0x00000000
+	movgs		gr9,damlr1
+	movgs		gr8,dampr1
+
+	# we use DAMR2-10 for kmap_atomic(), cache flush and TLB management
+	# since the DAMLR regs are not going to change, we can set them now
+	# also set up IAMLR2 to the same as DAMLR5
+	sethi.p		%hi(KMAP_ATOMIC_PRIMARY_FRAME),gr4
+	setlo		%lo(KMAP_ATOMIC_PRIMARY_FRAME),gr4
+	sethi.p		%hi(PAGE_SIZE),gr5
+	setlo		%lo(PAGE_SIZE),gr5
+	
+	movgs		gr4,damlr2
+	movgs		gr4,iamlr2
+	add		gr4,gr5,gr4
+	movgs		gr4,damlr3
+	add		gr4,gr5,gr4
+	movgs		gr4,damlr4
+	add		gr4,gr5,gr4
+	movgs		gr4,damlr5
+	add		gr4,gr5,gr4
+	movgs		gr4,damlr6
+	add		gr4,gr5,gr4
+	movgs		gr4,damlr7
+	add		gr4,gr5,gr4
+	movgs		gr4,damlr8
+	add		gr4,gr5,gr4
+	movgs		gr4,damlr9
+	add		gr4,gr5,gr4
+	movgs		gr4,damlr10
+
+	movgs		gr0,dampr2
+	movgs		gr0,dampr4
+	movgs		gr0,dampr5
+	movgs		gr0,dampr6
+	movgs		gr0,dampr7
+	movgs		gr0,dampr8
+	movgs		gr0,dampr9
+	movgs		gr0,dampr10
+
+	movgs		gr0,iamlr3
+	movgs		gr0,iamlr4
+	movgs		gr0,iamlr5
+	movgs		gr0,iamlr6
+	movgs		gr0,iamlr7
+
+	movgs		gr0,iampr2
+	movgs		gr0,iampr3
+	movgs		gr0,iampr4
+	movgs		gr0,iampr5
+	movgs		gr0,iampr6
+	movgs		gr0,iampr7
+
+	# start in TLB context 0 with the swapper's page tables
+	movgs		gr0,cxnr
+
+	sethi.p		%hi(swapper_pg_dir),gr4
+	setlo		%lo(swapper_pg_dir),gr4
+	sethi.p		%hi(__page_offset),gr5
+	setlo		%lo(__page_offset),gr5
+	sub		gr4,gr5,gr4
+	movgs		gr4,ttbr
+	setlos		#xAMPRx_L|xAMPRx_M|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr5
+	or		gr4,gr5,gr4
+	movgs		gr4,dampr3
+
+	# the FR451 also has an extra trap base register
+	movsg		tbr,gr4
+	movgs		gr4,btbr
+
+	LEDS		0x3300
+	jmpl		@(gr27,gr0)
+
+###############################################################################
+#
+# finish setting up the protection registers
+#
+###############################################################################
+	.globl		__head_fr451_finalise_protection
+__head_fr451_finalise_protection:
+	# turn on the timers as appropriate
+	movgs		gr0,timerh
+	movgs		gr0,timerl
+	movgs		gr0,timerd
+	movsg		hsr0,gr4
+	sethi.p		%hi(HSR0_ETMI),gr5
+	setlo		%lo(HSR0_ETMI),gr5
+	or		gr4,gr5,gr4
+	movgs		gr4,hsr0
+	
+	# clear the TLB entry cache
+	movgs		gr0,iamlr1
+	movgs		gr0,iampr1
+	movgs		gr0,damlr1
+	movgs		gr0,dampr1
+
+	# clear the PGE cache
+	sethi.p		%hi(__flush_tlb_all),gr4
+	setlo		%lo(__flush_tlb_all),gr4
+	jmpl		@(gr4,gr0)
diff -urN linux-2.4.29/arch/frv/kernel/head.S linux-2.4.29-uc1/arch/frv/kernel/head.S
--- linux-2.4.29/arch/frv/kernel/head.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/head.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,636 @@
+/* head.S: kernel entry point for FR-V kernel
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/spr-regs.h>
+#include <asm/mb86943a.h>
+#include <asm/cache.h>
+#include "head.inc"
+
+###############################################################################
+#
+# void _boot(unsigned long magic, char *command_line) __attribute__((noreturn))
+#
+# - if magic is 0xdead1eaf, then command_line is assumed to point to the kernel
+#   command line string
+#
+###############################################################################
+	.section	.text.head,"ax"
+	.balign		4
+
+	.globl		_boot, __head_reference
+        .type		_boot,@function
+_boot:
+__head_reference:
+	sethi.p		%hi(LED_ADDR),gr30
+	setlo		%lo(LED_ADDR),gr30
+
+	LEDS		0x0000
+
+	# calculate reference address for PC-relative stuff
+	call		0f
+0:	movsg		lr,gr26
+	addi		gr26,#__head_reference-0b,gr26
+
+	# invalidate and disable both of the caches and turn off the memory access checking
+	dcef		@(gr0,gr0),1
+	bar
+
+	sethi.p		%hi(~(HSR0_ICE|HSR0_DCE|HSR0_CBM|HSR0_EIMMU|HSR0_EDMMU)),gr4
+	setlo		%lo(~(HSR0_ICE|HSR0_DCE|HSR0_CBM|HSR0_EIMMU|HSR0_EDMMU)),gr4
+	movsg		hsr0,gr5
+	and		gr4,gr5,gr5
+	movgs		gr5,hsr0
+	movsg		hsr0,gr5
+
+	LEDS		0x0001
+
+	icei		@(gr0,gr0),1
+	dcei		@(gr0,gr0),1
+	bar
+
+	# turn the instruction cache back on
+	sethi.p		%hi(HSR0_ICE),gr4
+	setlo		%lo(HSR0_ICE),gr4
+	movsg		hsr0,gr5
+	or		gr4,gr5,gr5
+	movgs		gr5,hsr0
+	movsg		hsr0,gr5
+
+	bar
+
+	LEDS		0x0002
+
+	# retrieve the parameters (including command line) before we overwrite them
+	sethi.p		%hi(0xdead1eaf),gr7
+	setlo		%lo(0xdead1eaf),gr7
+	subcc		gr7,gr8,gr0,icc0
+	bne		icc0,#0,__head_no_parameters
+
+	sethi.p		%hi(saved_command_line-1),gr6
+	setlo		%lo(saved_command_line-1),gr6
+	sethi.p		%hi(__head_reference),gr4
+	setlo		%lo(__head_reference),gr4
+	sub		gr6,gr4,gr6
+	add.p		gr6,gr26,gr6
+	subi		gr9,#1,gr9
+	setlos.p	#511,gr4
+	setlos		#1,gr5
+
+__head_copy_cmdline:
+	ldubu.p		@(gr9,gr5),gr16
+	subicc		gr4,#1,gr4,icc0
+	stbu.p		gr16,@(gr6,gr5)
+	subicc		gr16,#0,gr0,icc1
+	bls		icc0,#0,__head_end_cmdline
+	bne		icc1,#1,__head_copy_cmdline
+__head_end_cmdline:
+	stbu		gr0,@(gr6,gr5)
+__head_no_parameters:
+
+###############################################################################
+#
+# we need to relocate the SDRAM to 0x00000000 (linux) or 0xC0000000 (uClinux)
+# - note that we're going to have to run entirely out of the icache whilst
+#   fiddling with the SDRAM controller registers
+#
+###############################################################################
+#ifndef CONFIG_UCLINUX
+	call		__head_fr451_describe_sdram
+
+#else
+	movsg		psr,gr5
+	srli		gr5,#28,gr5
+	subicc		gr5,#3,gr0,icc0
+	beq		icc0,#0,__head_fr551_sdram
+
+	call		__head_fr401_describe_sdram
+	bra		__head_do_sdram
+
+__head_fr551_sdram:
+	call		__head_fr555_describe_sdram
+	LEDS		0x000d
+
+__head_do_sdram:
+#endif
+
+	# preload the registers with invalid values in case any DBR/DARS are marked not present
+	sethi.p		%hi(0xfe000000),gr17		; unused SDRAM DBR value
+	setlo		%lo(0xfe000000),gr17
+	or.p		gr17,gr0,gr20
+	or		gr17,gr0,gr21
+	or.p		gr17,gr0,gr22
+	or		gr17,gr0,gr23
+	
+	# consult the SDRAM controller CS address registers
+	cld		@(gr14,gr0 ),gr20,	cc0,#1	; DBR0 / DARS0
+	cld		@(gr14,gr11),gr21,	cc1,#1	; DBR1 / DARS1
+	cld		@(gr14,gr12),gr22,	cc2,#1	; DBR2 / DARS2
+	cld.p		@(gr14,gr13),gr23,	cc3,#1	; DBR3 / DARS3
+
+	sll		gr20,gr15,gr20			; shift values up for FR551
+	sll		gr21,gr15,gr21
+	sll		gr22,gr15,gr22
+	sll		gr23,gr15,gr23
+
+	LEDS		0x0003
+
+	# assume the lowest valid CS line to be the SDRAM base and get its address
+	subcc		gr20,gr17,gr0,icc0
+	subcc.p		gr21,gr17,gr0,icc1
+	subcc		gr22,gr17,gr0,icc2
+	subcc.p		gr23,gr17,gr0,icc3
+	ckne		icc0,cc4			; T if DBR0 != 0xfe000000
+	ckne		icc1,cc5
+	ckne		icc2,cc6
+	ckne		icc3,cc7
+	cor		gr23,gr0,gr24,		cc7,#1	; GR24 = SDRAM base
+	cor		gr22,gr0,gr24,		cc6,#1
+	cor		gr21,gr0,gr24,		cc5,#1
+	cor		gr20,gr0,gr24,		cc4,#1
+
+	# calculate the displacement required to get the SDRAM into the right place in memory
+	sethi.p		%hi(__sdram_base),gr16
+	setlo		%lo(__sdram_base),gr16
+	sub		gr16,gr24,gr16			; delta = __sdram_base - DBRx
+
+	# calculate the new values to go in the controller regs
+	cadd.p		gr20,gr16,gr20,		cc4,#1	; DCS#0 (new) = DCS#0 (old) + delta
+	cadd		gr21,gr16,gr21,		cc5,#1
+	cadd.p		gr22,gr16,gr22,		cc6,#1
+	cadd		gr23,gr16,gr23,		cc7,#1
+
+	srl		gr20,gr15,gr20			; shift values down for FR551
+	srl		gr21,gr15,gr21
+	srl		gr22,gr15,gr22
+	srl		gr23,gr15,gr23
+
+	# work out the address at which the reg updater resides and lock it into icache
+	# also work out the address the updater will jump to when finished
+	sethi.p		%hi(__head_move_sdram-__head_reference),gr18
+	setlo		%lo(__head_move_sdram-__head_reference),gr18
+	sethi.p		%hi(__head_sdram_moved-__head_reference),gr19
+	setlo		%lo(__head_sdram_moved-__head_reference),gr19
+	add.p		gr18,gr26,gr18
+	add		gr19,gr26,gr19
+	add.p		gr19,gr16,gr19			; moved = addr + (__sdram_base - DBRx)
+	add		gr18,gr5,gr4			; two cachelines probably required
+
+	icpl		gr18,gr0,#1			; load and lock the cachelines
+	icpl		gr4,gr0,#1
+	LEDS		0x0004
+	membar
+	bar
+	jmpl		@(gr18,gr0)
+
+	.balign		L1_CACHE_BYTES
+__head_move_sdram:
+	cst		gr20,@(gr14,gr0 ),	cc4,#1
+	cst		gr21,@(gr14,gr11),	cc5,#1
+	cst		gr22,@(gr14,gr12),	cc6,#1
+	cst		gr23,@(gr14,gr13),	cc7,#1
+	cld		@(gr14,gr0 ),gr20,	cc4,#1
+	cld		@(gr14,gr11),gr21,	cc5,#1
+	cld		@(gr14,gr12),gr22,	cc4,#1
+	cld		@(gr14,gr13),gr23,	cc7,#1
+	bar
+	membar
+	jmpl		@(gr19,gr0)
+
+	.balign		L1_CACHE_BYTES
+__head_sdram_moved:
+	icul		gr18
+	add		gr18,gr5,gr4
+	icul		gr4
+	icei		@(gr0,gr0),1
+	dcei		@(gr0,gr0),1
+
+	LEDS		0x0005
+
+	# recalculate reference address
+	call		0f
+0:	movsg		lr,gr26
+	addi		gr26,#__head_reference-0b,gr26
+
+
+###############################################################################
+#
+# move the kernel image down to the bottom of the SDRAM
+#
+###############################################################################
+	sethi.p		%hi(__kernel_image_size_no_bss+15),gr4
+	setlo		%lo(__kernel_image_size_no_bss+15),gr4
+	srli.p		gr4,#4,gr4			; count
+	or		gr26,gr26,gr16			; source
+
+	sethi.p		%hi(__sdram_base),gr17		; destination
+	setlo		%lo(__sdram_base),gr17
+
+	setlos		#8,gr5
+	sub.p		gr16,gr5,gr16			; adjust src for LDDU
+	sub		gr17,gr5,gr17			; adjust dst for LDDU
+
+	sethi.p		%hi(__head_move_kernel-__head_reference),gr18
+	setlo		%lo(__head_move_kernel-__head_reference),gr18
+	sethi.p		%hi(__head_kernel_moved-__head_reference+__sdram_base),gr19
+	setlo		%lo(__head_kernel_moved-__head_reference+__sdram_base),gr19
+	add		gr18,gr26,gr18
+	icpl		gr18,gr0,#1
+	jmpl		@(gr18,gr0)
+
+	.balign		32
+__head_move_kernel:
+	lddu		@(gr16,gr5),gr10
+	lddu		@(gr16,gr5),gr12
+	stdu.p		gr10,@(gr17,gr5)
+	subicc		gr4,#1,gr4,icc0
+	stdu.p		gr12,@(gr17,gr5)
+	bhi		icc0,#0,__head_move_kernel
+	jmpl		@(gr19,gr0)
+
+	.balign		32
+__head_kernel_moved:
+	icul		gr18
+	icei		@(gr0,gr0),1
+	dcei		@(gr0,gr0),1
+
+	LEDS		0x0006
+
+	# recalculate reference address
+	call		0f
+0:	movsg		lr,gr26
+	addi		gr26,#__head_reference-0b,gr26
+
+
+###############################################################################
+#
+# rearrange the iomem map and set the protection registers
+#
+###############################################################################
+
+#ifndef CONFIG_UCLINUX
+	LEDS		0x3301
+	call		__head_fr451_set_busctl
+	LEDS		0x3303
+	call		__head_fr451_survey_sdram
+	LEDS		0x3305
+	call		__head_fr451_set_protection
+
+#else
+	movsg		psr,gr5
+	srli		gr5,#PSR_IMPLE_SHIFT,gr5
+	subicc		gr5,#PSR_IMPLE_FR551,gr0,icc0
+	beq		icc0,#0,__head_fr555_memmap
+	subicc		gr5,#PSR_IMPLE_FR451,gr0,icc0
+	beq		icc0,#0,__head_fr451_memmap
+
+	LEDS		0x3101
+	call		__head_fr401_set_busctl
+	LEDS		0x3103
+	call		__head_fr401_survey_sdram
+	LEDS		0x3105
+	call		__head_fr401_set_protection
+	bra		__head_done_memmap
+
+__head_fr451_memmap:
+	LEDS		0x3301
+	call		__head_fr401_set_busctl
+	LEDS		0x3303
+	call		__head_fr401_survey_sdram
+	LEDS		0x3305
+	call		__head_fr451_set_protection
+	bra		__head_done_memmap
+
+__head_fr555_memmap:
+	LEDS		0x3501
+	call		__head_fr555_set_busctl
+	LEDS		0x3503
+	call		__head_fr555_survey_sdram
+	LEDS		0x3505
+	call		__head_fr555_set_protection
+
+__head_done_memmap:
+#endif
+	LEDS		0x0007
+
+###############################################################################
+#
+# turn the data cache and MMU on
+# - for the FR451 this'll mean that the window through which the kernel is
+#   viewed will change
+#
+###############################################################################
+
+#ifndef CONFIG_UCLINUX
+#define MMUMODE		HSR0_EIMMU|HSR0_EDMMU|HSR0_EXMMU|HSR0_EDAT|HSR0_XEDAT
+#else
+#define MMUMODE		HSR0_EIMMU|HSR0_EDMMU
+#endif
+
+	movsg		hsr0,gr5
+#if defined(CONFIG_DCACHE_DISABLE)
+	sethi.p		%hi(MMUMODE),gr4
+	setlo		%lo(MMUMODE),gr4
+#else	
+#if defined(CONFIG_FRV_DEFL_CACHE_WTHRU)
+	sethi.p		%hi(HSR0_DCE|HSR0_CBM_WRITE_THRU|MMUMODE),gr4
+	setlo		%lo(HSR0_DCE|HSR0_CBM_WRITE_THRU|MMUMODE),gr4
+#elif defined(CONFIG_FRV_DEFL_CACHE_WBACK)
+	sethi.p		%hi(HSR0_DCE|HSR0_CBM_COPY_BACK|MMUMODE),gr4
+	setlo		%lo(HSR0_DCE|HSR0_CBM_COPY_BACK|MMUMODE),gr4
+#else
+#error Indeterminate default cache configuration
+#endif
+#if defined(CONFIG_FRV_DEFL_CACHE_NWA)
+	movsg		psr,gr6
+	srli		gr6,#24,gr6
+	cmpi		gr6,#0x50,icc0 // FR451
+	beq		icc0,#0,0f
+	cmpi		gr6,#0x40,icc0 // FR405
+	bne		icc0,#0,1f
+    0:
+	# turn off write-allocate
+	sethi.p		%hi(HSR0_NWA),gr6
+	setlo		%lo(HSR0_NWA),gr6
+	or		gr4,gr6,gr4
+    1:
+#endif
+#endif  /* CONFIG_DCACHE_DISABLE */
+
+	or		gr4,gr5,gr5
+	movgs		gr5,hsr0
+	bar
+	LEDS		0x0008
+
+	sethi.p		%hi(__head_mmu_enabled),gr19
+	setlo		%lo(__head_mmu_enabled),gr19
+	jmpl		@(gr19,gr0)
+
+__head_mmu_enabled:
+	icei		@(gr0,gr0),#1
+	dcei		@(gr0,gr0),#1
+
+	LEDS		0x0009
+
+#ifndef CONFIG_UCLINUX
+	call		__head_fr451_finalise_protection
+#endif
+
+	LEDS		0x000a
+
+###############################################################################
+#
+# set up the runtime environment
+#
+###############################################################################
+
+	# clear the BSS area
+	sethi.p		%hi(__bss_start),gr4
+	setlo		%lo(__bss_start),gr4
+	sethi.p		%hi(_end),gr5
+	setlo		%lo(_end),gr5
+	or.p		gr0,gr0,gr18
+	or		gr0,gr0,gr19
+
+0:
+	stdi		gr18,@(gr4,#0)
+	stdi		gr18,@(gr4,#8)
+	stdi		gr18,@(gr4,#16)
+	stdi.p		gr18,@(gr4,#24)
+	addi		gr4,#24,gr4
+	subcc		gr5,gr4,gr0,icc0
+	bhi		icc0,#2,0b
+
+	LEDS		0x000b
+
+	# save the SDRAM details
+	sethi.p		%hi(__sdram_old_base),gr4
+	setlo		%lo(__sdram_old_base),gr4
+	st		gr24,@(gr4,gr0)
+
+	sethi.p		%hi(__sdram_base),gr5
+	setlo		%lo(__sdram_base),gr5
+	sethi.p		%hi(memory_start),gr4
+	setlo		%lo(memory_start),gr4
+	st		gr5,@(gr4,gr0)
+
+	add		gr25,gr5,gr25
+	sethi.p		%hi(memory_end),gr4
+	setlo		%lo(memory_end),gr4
+	st		gr25,@(gr4,gr0)
+
+	# point the TBR at the kernel trap table
+	sethi.p		%hi(__entry_kerneltrap_table),gr4
+	setlo		%lo(__entry_kerneltrap_table),gr4
+	movgs		gr4,tbr
+
+	# set up the exception frame for init
+	sethi.p		%hi(__kernel_frame0_ptr),gr28
+	setlo		%lo(__kernel_frame0_ptr),gr28
+	sethi.p		%hi(_gp),gr16
+	setlo		%lo(_gp),gr16
+	sethi.p		%hi(__entry_usertrap_table),gr4
+	setlo		%lo(__entry_usertrap_table),gr4
+
+	lddi.p		@(gr28,#0),gr28		; load __frame & current
+	
+	or		gr0,gr0,fp
+	or		gr28,gr0,sp
+
+	sti.p		gr4,@(gr28,REG_TBR)
+	setlos		#ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
+	movgs		gr5,isr
+
+	# turn on and off various CPU services
+	movsg		psr,gr22
+	sethi.p		%hi(#PSR_EM|PSR_EF|PSR_CM|PSR_NEM),gr4
+	setlo		%lo(#PSR_EM|PSR_EF|PSR_CM|PSR_NEM),gr4
+	or		gr22,gr4,gr22
+	movgs		gr22,psr
+	
+	andi		gr22,#~(PSR_PIL|PSR_PS|PSR_S),gr22
+	ori		gr22,#PSR_ET,gr22
+	sti		gr22,@(gr28,REG_PSR)
+	
+
+###############################################################################
+#
+# set up the registers and jump into the kernel
+#
+###############################################################################
+
+	LEDS		0x000c
+
+	# initialise the processor and the peripherals
+	#call		SYMBOL_NAME(processor_init)
+	#call		SYMBOL_NAME(unit_init)
+	#LEDS		0x0aff
+
+	sethi.p		#0xe5e5,gr3
+	setlo		#0xe5e5,gr3
+	or.p		gr3,gr0,gr4
+	or		gr3,gr0,gr5
+	or.p		gr3,gr0,gr6
+	or		gr3,gr0,gr7
+	or.p		gr3,gr0,gr8
+	or		gr3,gr0,gr9
+	or.p		gr3,gr0,gr10
+	or		gr3,gr0,gr11
+	or.p		gr3,gr0,gr12
+	or		gr3,gr0,gr13
+	or.p		gr3,gr0,gr14
+	or		gr3,gr0,gr15
+	or.p		gr3,gr0,gr17
+	or		gr3,gr0,gr18
+	or.p		gr3,gr0,gr19
+	or		gr3,gr0,gr20
+	or.p		gr3,gr0,gr21
+	or		gr3,gr0,gr23
+	or.p		gr3,gr0,gr24
+	or		gr3,gr0,gr25
+	or.p		gr3,gr0,gr26
+	or		gr3,gr0,gr27
+#	or.p		gr3,gr0,gr30
+	or		gr3,gr0,gr31
+	movgs		gr0,lr
+	movgs		gr0,lcr
+	movgs		gr0,ccr
+	movgs		gr0,cccr
+
+#ifndef CONFIG_UCLINUX
+	movgs		gr3,scr2
+	movgs		gr3,scr3
+#endif
+
+	LEDS		0x0fff
+
+	# invoke the debugging stub if present
+	# - arch/frv/kernel/debug-stub.c will shift control directly to init/main.c
+	#   (it will not return here)
+	break
+	.globl		__debug_stub_init_break
+__debug_stub_init_break:
+
+	# however, if you need to use an ICE, and don't care about using any userspace
+	# debugging tools (such as the ptrace syscall), you can just step over the break
+	# above and get to the kernel this way
+	# look at arch/frv/kernel/debug-stub.c: debug_stub_init() to see what you've missed
+	call		start_kernel
+	
+	.globl		__head_end
+__head_end:
+	.size		_boot, .-_boot
+
+	# provide a point for GDB to place a break
+	.section	.text.start,"ax"
+	.globl		_start
+	.balign		4
+_start:
+	call		_boot
+
+	.previous
+###############################################################################
+#
+# split a tile off of the region defined by GR8-GR9
+#
+#	ENTRY:			EXIT:
+# GR4	-			IAMPR value representing tile
+# GR5	-			DAMPR value representing tile
+# GR6	-			IAMLR value representing tile
+# GR7	-			DAMLR value representing tile
+# GR8	region base pointer	[saved]
+# GR9	region top pointer	updated to exclude new tile
+# GR11	xAMLR mask		[saved]
+# GR25	SDRAM size		[saved]
+# GR30	LED address		[saved]
+#
+# - GR8 and GR9 should be rounded up/down to the nearest megabyte before calling
+#
+###############################################################################
+	.globl		__head_split_region
+	.type		__head_split_region,@function
+__head_split_region:
+	subcc.p		gr9,gr8,gr4,icc0
+	setlos		#31,gr5
+	scan.p		gr4,gr0,gr6
+	beq		icc0,#0,__head_region_empty
+	sub.p		gr5,gr6,gr6			; bit number of highest set bit (1MB=>20)
+	setlos		#1,gr4
+	sll.p		gr4,gr6,gr4			; size of region (1 << bitno)
+	subi		gr6,#17,gr6			; 1MB => 0x03
+	slli.p		gr6,#4,gr6			; 1MB => 0x30
+	sub		gr9,gr4,gr9			; move uncovered top down
+
+	or		gr9,gr6,gr4
+	ori		gr4,#xAMPRx_S_USER|xAMPRx_C_CACHED|xAMPRx_V,gr4
+	or.p		gr4,gr0,gr5
+
+	and		gr4,gr11,gr6
+	and.p		gr5,gr11,gr7
+	bralr
+
+__head_region_empty:
+	or.p		gr0,gr0,gr4
+	or		gr0,gr0,gr5
+	or.p		gr0,gr0,gr6
+	or		gr0,gr0,gr7
+	bralr
+	.size		__head_split_region, .-__head_split_region
+
+###############################################################################
+#
+# write the 32-bit hex number in GR8 to ttyS0
+#
+###############################################################################
+#if 0
+	.globl		__head_write_to_ttyS0
+	.type		__head_write_to_ttyS0,@function
+__head_write_to_ttyS0:
+	sethi.p		%hi(0xfeff9c00),gr31
+	setlo		%lo(0xfeff9c00),gr31
+	setlos		#8,gr20
+
+0:	ldubi		@(gr31,#5*8),gr21
+	andi		gr21,#0x60,gr21
+	subicc		gr21,#0x60,gr21,icc0
+	bne		icc0,#0,0b
+
+1:	srli		gr8,#28,gr21
+	slli		gr8,#4,gr8
+
+	addi		gr21,#'0',gr21
+	subicc		gr21,#'9',gr0,icc0
+	bls		icc0,#2,2f
+	addi		gr21,#'A'-'0'-10,gr21
+2:
+	stbi		gr21,@(gr31,#0*8)
+	subicc		gr20,#1,gr20,icc0
+	bhi		icc0,#2,1b
+
+	setlos		#'\r',gr21
+	stbi		gr21,@(gr31,#0*8)
+
+	setlos		#'\n',gr21
+	stbi		gr21,@(gr31,#0*8)
+
+3:	ldubi		@(gr31,#5*8),gr21
+	andi		gr21,#0x60,gr21
+	subicc		gr21,#0x60,gr21,icc0
+	bne		icc0,#0,3b
+	bralr
+
+	.size		__head_write_to_ttyS0, .-__head_write_to_ttyS0
+#endif
diff -urN linux-2.4.29/arch/frv/kernel/head-uc-fr401.S linux-2.4.29-uc1/arch/frv/kernel/head-uc-fr401.S
--- linux-2.4.29/arch/frv/kernel/head-uc-fr401.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/head-uc-fr401.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,312 @@
+/* head-uc-fr401.S: FR401/3/5 uc-linux specific bits of initialisation
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/spr-regs.h>
+#include <asm/mb86943a.h>
+#include "head.inc"
+
+
+#define __400_DBR0	0xfe000e00
+#define __400_DBR1	0xfe000e08
+#define __400_DBR2	0xfe000e10	/* not on FR401 */
+#define __400_DBR3	0xfe000e18	/* not on FR401 */
+#define __400_DAM0	0xfe000f00
+#define __400_DAM1	0xfe000f08
+#define __400_DAM2	0xfe000f10	/* not on FR401 */
+#define __400_DAM3	0xfe000f18	/* not on FR401 */
+#define __400_LGCR	0xfe000010
+#define __400_LCR	0xfe000100
+#define __400_LSBR	0xfe000c00
+
+	.section	.text.init,"ax"
+	.balign		4
+
+###############################################################################
+#
+# describe the position and layout of the SDRAM controller registers
+#
+#	ENTRY:			EXIT:
+# GR5	-			cacheline size
+# GR11	-			displacement of 2nd SDRAM addr reg from GR14
+# GR12	-			displacement of 3rd SDRAM addr reg from GR14
+# GR13	-			displacement of 4th SDRAM addr reg from GR14
+# GR14	-			address of 1st SDRAM addr reg
+# GR15	-			amount to shift address by to match SDRAM addr reg
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+# CC0	-			T if DBR0 is present
+# CC1	-			T if DBR1 is present
+# CC2	-			T if DBR2 is present (not FR401/FR401A)
+# CC3	-			T if DBR3 is present (not FR401/FR401A)
+#
+###############################################################################
+	.globl		__head_fr401_describe_sdram
+__head_fr401_describe_sdram:
+	sethi.p		%hi(__400_DBR0),gr14
+	setlo		%lo(__400_DBR0),gr14
+	setlos.p	#__400_DBR1-__400_DBR0,gr11
+	setlos		#__400_DBR2-__400_DBR0,gr12
+	setlos.p	#__400_DBR3-__400_DBR0,gr13
+	setlos		#32,gr5			; cacheline size
+	setlos.p	#0,gr15			; amount to shift addr reg by
+
+	# specify which DBR regs are present
+	setlos		#0x00ff,gr4
+	movgs		gr4,cccr
+	movsg		psr,gr3			; check for FR401/FR401A
+	srli		gr3,#25,gr3
+	subicc		gr3,#0x20>>1,gr0,icc0
+	bnelr		icc0,#1
+	setlos		#0x000f,gr4
+	movgs		gr4,cccr
+	bralr
+
+###############################################################################
+#
+# rearrange the bus controller registers
+#
+#	ENTRY:			EXIT:
+# GR26	&__head_reference	[saved]
+# GR30	LED address		revised LED address
+#
+###############################################################################
+	.globl		__head_fr401_set_busctl
+__head_fr401_set_busctl:
+	sethi.p		%hi(__400_LGCR),gr4
+	setlo		%lo(__400_LGCR),gr4
+	sethi.p		%hi(__400_LSBR),gr10
+	setlo		%lo(__400_LSBR),gr10
+	sethi.p		%hi(__400_LCR),gr11
+	setlo		%lo(__400_LCR),gr11
+
+	# set the bus controller
+	ldi		@(gr4,#0),gr5
+	ori		gr5,#0xff,gr5		; make sure all chip-selects are enabled
+	sti		gr5,@(gr4,#0)
+
+	sethi.p		%hi(__region_CS1),gr4
+	setlo		%lo(__region_CS1),gr4
+	sethi.p		%hi(__region_CS1_M),gr5
+	setlo		%lo(__region_CS1_M),gr5
+	sethi.p		%hi(__region_CS1_C),gr6
+	setlo		%lo(__region_CS1_C),gr6
+	sti		gr4,@(gr10,#1*0x08)
+	sti		gr5,@(gr10,#1*0x08+0x100)
+	sti		gr6,@(gr11,#1*0x08)
+	sethi.p		%hi(__region_CS2),gr4
+	setlo		%lo(__region_CS2),gr4
+	sethi.p		%hi(__region_CS2_M),gr5
+	setlo		%lo(__region_CS2_M),gr5
+	sethi.p		%hi(__region_CS2_C),gr6
+	setlo		%lo(__region_CS2_C),gr6
+	sti		gr4,@(gr10,#2*0x08)
+	sti		gr5,@(gr10,#2*0x08+0x100)
+	sti		gr6,@(gr11,#2*0x08)
+	sethi.p		%hi(__region_CS3),gr4
+	setlo		%lo(__region_CS3),gr4
+	sethi.p		%hi(__region_CS3_M),gr5
+	setlo		%lo(__region_CS3_M),gr5
+	sethi.p		%hi(__region_CS3_C),gr6
+	setlo		%lo(__region_CS3_C),gr6
+	sti		gr4,@(gr10,#3*0x08)
+	sti		gr5,@(gr10,#3*0x08+0x100)
+	sti		gr6,@(gr11,#3*0x08)
+	sethi.p		%hi(__region_CS4),gr4
+	setlo		%lo(__region_CS4),gr4
+	sethi.p		%hi(__region_CS4_M),gr5
+	setlo		%lo(__region_CS4_M),gr5
+	sethi.p		%hi(__region_CS4_C),gr6
+	setlo		%lo(__region_CS4_C),gr6
+	sti		gr4,@(gr10,#4*0x08)
+	sti		gr5,@(gr10,#4*0x08+0x100)
+	sti		gr6,@(gr11,#4*0x08)
+	sethi.p		%hi(__region_CS5),gr4
+	setlo		%lo(__region_CS5),gr4
+	sethi.p		%hi(__region_CS5_M),gr5
+	setlo		%lo(__region_CS5_M),gr5
+	sethi.p		%hi(__region_CS5_C),gr6
+	setlo		%lo(__region_CS5_C),gr6
+	sti		gr4,@(gr10,#5*0x08)
+	sti		gr5,@(gr10,#5*0x08+0x100)
+	sti		gr6,@(gr11,#5*0x08)
+	sethi.p		%hi(__region_CS6),gr4
+	setlo		%lo(__region_CS6),gr4
+	sethi.p		%hi(__region_CS6_M),gr5
+	setlo		%lo(__region_CS6_M),gr5
+	sethi.p		%hi(__region_CS6_C),gr6
+	setlo		%lo(__region_CS6_C),gr6
+	sti		gr4,@(gr10,#6*0x08)
+	sti		gr5,@(gr10,#6*0x08+0x100)
+	sti		gr6,@(gr11,#6*0x08)
+	sethi.p		%hi(__region_CS7),gr4
+	setlo		%lo(__region_CS7),gr4
+	sethi.p		%hi(__region_CS7_M),gr5
+	setlo		%lo(__region_CS7_M),gr5
+	sethi.p		%hi(__region_CS7_C),gr6
+	setlo		%lo(__region_CS7_C),gr6
+	sti		gr4,@(gr10,#7*0x08)
+	sti		gr5,@(gr10,#7*0x08+0x100)
+	sti		gr6,@(gr11,#7*0x08)
+	membar
+	bar
+
+	# adjust LED bank address
+	sethi.p		%hi(LED_ADDR - 0x20000000 +__region_CS2),gr30
+	setlo		%lo(LED_ADDR - 0x20000000 +__region_CS2),gr30
+	bralr
+
+###############################################################################
+#
+# determine the total SDRAM size
+#
+#	ENTRY:			EXIT:
+# GR25	-			SDRAM size
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+#
+###############################################################################
+	.globl		__head_fr401_survey_sdram
+__head_fr401_survey_sdram:
+	sethi.p		%hi(__400_DAM0),gr11
+	setlo		%lo(__400_DAM0),gr11
+	sethi.p		%hi(__400_DBR0),gr12
+	setlo		%lo(__400_DBR0),gr12
+
+	sethi.p		%hi(0xfe000000),gr17		; unused SDRAM DBR value
+	setlo		%lo(0xfe000000),gr17
+	setlos		#0,gr25
+
+	ldi		@(gr12,#0x00),gr4		; DAR0
+	subcc		gr4,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS0
+	ldi		@(gr11,#0x00),gr6		; DAM0: bits 31:20 match addr 31:20
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS0:
+
+	ldi		@(gr12,#0x08),gr4		; DAR1
+	subcc		gr4,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS1
+	ldi		@(gr11,#0x08),gr6		; DAM1: bits 31:20 match addr 31:20
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS1:
+
+	# FR401/FR401A does not have DCS2/3
+	movsg		psr,gr3
+	srli		gr3,#25,gr3
+	subicc		gr3,#0x20>>1,gr0,icc0
+	beq		icc0,#0,__head_no_DCS3
+
+	ldi		@(gr12,#0x10),gr4		; DAR2
+	subcc		gr4,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS2
+	ldi		@(gr11,#0x10),gr6		; DAM2: bits 31:20 match addr 31:20
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS2:
+
+	ldi		@(gr12,#0x18),gr4		; DAR3
+	subcc		gr4,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS3
+	ldi		@(gr11,#0x18),gr6		; DAM3: bits 31:20 match addr 31:20
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS3:
+	bralr
+
+###############################################################################
+#
+# set the protection map with the I/DAMPR registers
+#
+#	ENTRY:			EXIT:
+# GR25	SDRAM size		[saved]
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+#
+###############################################################################
+	.globl		__head_fr401_set_protection
+__head_fr401_set_protection:
+	movsg		lr,gr27
+
+	# set the I/O region protection registers for FR401/3/5
+	sethi.p		%hi(__region_IO),gr5
+	setlo		%lo(__region_IO),gr5
+	ori		gr5,#xAMPRx_SS_512Mb|xAMPRx_S_KERNEL|xAMPRx_C|xAMPRx_V,gr5
+	movgs		gr0,iampr7
+	movgs		gr5,dampr7			; General I/O tile
+
+	# need to tile the remaining IAMPR/DAMPR registers to cover as much of the RAM as possible
+	# - start with the highest numbered registers
+	sethi.p		%hi(__kernel_image_end),gr8
+	setlo		%lo(__kernel_image_end),gr8
+	sethi.p		%hi(32768),gr4			; allow for a maximal allocator bitmap
+	setlo		%lo(32768),gr4
+	add		gr8,gr4,gr8
+	sethi.p		%hi(1024*2048-1),gr4		; round up to nearest 2MiB
+	setlo		%lo(1024*2048-1),gr4
+	add.p		gr8,gr4,gr8
+	not		gr4,gr4
+	and		gr8,gr4,gr8
+
+	sethi.p		%hi(__page_offset),gr9
+	setlo		%lo(__page_offset),gr9
+	add		gr9,gr25,gr9
+
+	# GR8 = base of uncovered RAM
+	# GR9 = top of uncovered RAM
+
+#ifdef CONFIG_MB93093_PDK
+	sethi.p		%hi(__region_CS2),gr4
+	setlo		%lo(__region_CS2),gr4
+	ori		gr4,#xAMPRx_SS_1Mb|xAMPRx_S_KERNEL|xAMPRx_C|xAMPRx_V,gr4
+	movgs		gr4,dampr6
+	movgs		gr0,iampr6	
+#else
+	call		__head_split_region
+	movgs		gr4,iampr6
+	movgs		gr5,dampr6
+#endif
+	call		__head_split_region
+	movgs		gr4,iampr5
+	movgs		gr5,dampr5
+	call		__head_split_region
+	movgs		gr4,iampr4
+	movgs		gr5,dampr4
+	call		__head_split_region
+	movgs		gr4,iampr3
+	movgs		gr5,dampr3
+	call		__head_split_region
+	movgs		gr4,iampr2
+	movgs		gr5,dampr2
+	call		__head_split_region
+	movgs		gr4,iampr1
+	movgs		gr5,dampr1
+
+	# cover kernel core image with kernel-only segment
+	sethi.p		%hi(__page_offset),gr8
+	setlo		%lo(__page_offset),gr8
+	call		__head_split_region
+
+#ifdef CONFIG_PROTECT_KERNEL
+	ori.p		gr4,#xAMPRx_S_KERNEL,gr4
+	ori		gr5,#xAMPRx_S_KERNEL,gr5
+#endif
+
+	movgs		gr4,iampr0
+	movgs		gr5,dampr0
+	jmpl		@(gr27,gr0)
diff -urN linux-2.4.29/arch/frv/kernel/head-uc-fr451.S linux-2.4.29-uc1/arch/frv/kernel/head-uc-fr451.S
--- linux-2.4.29/arch/frv/kernel/head-uc-fr451.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/head-uc-fr451.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,175 @@
+/* head-uc-fr451.S: FR451 uc-linux specific bits of initialisation
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/spr-regs.h>
+#include <asm/mb86943a.h>
+#include "head.inc"
+
+
+#define __400_DBR0	0xfe000e00
+#define __400_DBR1	0xfe000e08
+#define __400_DBR2	0xfe000e10
+#define __400_DBR3	0xfe000e18
+#define __400_DAM0	0xfe000f00
+#define __400_DAM1	0xfe000f08
+#define __400_DAM2	0xfe000f10
+#define __400_DAM3	0xfe000f18
+#define __400_LGCR	0xfe000010
+#define __400_LCR	0xfe000100
+#define __400_LSBR	0xfe000c00
+
+	.section	.text.init,"ax"
+	.balign		4
+
+###############################################################################
+#
+# set the protection map with the I/DAMPR registers
+#
+#	ENTRY:			EXIT:
+# GR25	SDRAM size		[saved]
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+#
+###############################################################################
+	.globl		__head_fr451_set_protection
+__head_fr451_set_protection:
+	movsg		lr,gr27
+
+	movgs		gr0,dampr10
+	movgs		gr0,damlr10
+	movgs		gr0,dampr9
+	movgs		gr0,damlr9
+	movgs		gr0,dampr8
+	movgs		gr0,damlr8
+
+	# set the I/O region protection registers for FR401/3/5
+	sethi.p		%hi(__region_IO),gr5
+	setlo		%lo(__region_IO),gr5
+	sethi.p		%hi(0x1fffffff),gr7
+	setlo		%lo(0x1fffffff),gr7
+	ori		gr5,#xAMPRx_SS_512Mb|xAMPRx_S_KERNEL|xAMPRx_C|xAMPRx_V,gr5
+	movgs		gr5,dampr11			; General I/O tile
+	movgs		gr7,damlr11
+
+	# need to tile the remaining IAMPR/DAMPR registers to cover as much of the RAM as possible
+	# - start with the highest numbered registers
+	sethi.p		%hi(__kernel_image_end),gr8
+	setlo		%lo(__kernel_image_end),gr8
+	sethi.p		%hi(32768),gr4			; allow for a maximal allocator bitmap
+	setlo		%lo(32768),gr4
+	add		gr8,gr4,gr8
+	sethi.p		%hi(1024*2048-1),gr4		; round up to nearest 2MiB
+	setlo		%lo(1024*2048-1),gr4
+	add.p		gr8,gr4,gr8
+	not		gr4,gr4
+	and		gr8,gr4,gr8
+
+	sethi.p		%hi(__page_offset),gr9
+	setlo		%lo(__page_offset),gr9
+	add		gr9,gr25,gr9
+
+	sethi.p		%hi(0xffffc000),gr11
+	setlo		%lo(0xffffc000),gr11
+
+	# GR8 = base of uncovered RAM
+	# GR9 = top of uncovered RAM
+	# GR11 = xAMLR mask
+	LEDS		0x3317
+	call		__head_split_region
+	movgs		gr4,iampr7
+	movgs		gr6,iamlr7
+	movgs		gr5,dampr7
+	movgs		gr7,damlr7
+
+	LEDS		0x3316
+	call		__head_split_region
+	movgs		gr4,iampr6
+	movgs		gr6,iamlr6
+	movgs		gr5,dampr6
+	movgs		gr7,damlr6
+
+	LEDS		0x3315
+	call		__head_split_region
+	movgs		gr4,iampr5
+	movgs		gr6,iamlr5
+	movgs		gr5,dampr5
+	movgs		gr7,damlr5
+
+	LEDS		0x3314
+	call		__head_split_region
+	movgs		gr4,iampr4
+	movgs		gr6,iamlr4
+	movgs		gr5,dampr4
+	movgs		gr7,damlr4
+
+	LEDS		0x3313
+	call		__head_split_region
+	movgs		gr4,iampr3
+	movgs		gr6,iamlr3
+	movgs		gr5,dampr3
+	movgs		gr7,damlr3
+
+	LEDS		0x3312
+	call		__head_split_region
+	movgs		gr4,iampr2
+	movgs		gr6,iamlr2
+	movgs		gr5,dampr2
+	movgs		gr7,damlr2
+
+	LEDS		0x3311
+	call		__head_split_region
+	movgs		gr4,iampr1
+	movgs		gr6,iamlr1
+	movgs		gr5,dampr1
+	movgs		gr7,damlr1
+
+	# cover kernel core image with kernel-only segment
+	LEDS		0x3310
+	sethi.p		%hi(__page_offset),gr8
+	setlo		%lo(__page_offset),gr8
+	call		__head_split_region
+
+#ifdef CONFIG_PROTECT_KERNEL
+	ori.p		gr4,#xAMPRx_S_KERNEL,gr4
+	ori		gr5,#xAMPRx_S_KERNEL,gr5
+#endif
+
+	movgs		gr4,iampr0
+	movgs		gr6,iamlr0
+	movgs		gr5,dampr0
+	movgs		gr7,damlr0
+
+	# start in TLB context 0 with no page tables
+	movgs		gr0,cxnr
+	movgs		gr0,ttbr
+
+	# the FR451 also has an extra trap base register
+	movsg		tbr,gr4
+	movgs		gr4,btbr
+	
+	# turn on the timers as appropriate
+	movgs		gr0,timerh
+	movgs		gr0,timerl
+	movgs		gr0,timerd
+	movsg		hsr0,gr4
+	sethi.p		%hi(HSR0_ETMI),gr5
+	setlo		%lo(HSR0_ETMI),gr5
+	or		gr4,gr5,gr4
+	movgs		gr4,hsr0
+	
+	LEDS		0x3300
+	jmpl		@(gr27,gr0)
diff -urN linux-2.4.29/arch/frv/kernel/head-uc-fr555.S linux-2.4.29-uc1/arch/frv/kernel/head-uc-fr555.S
--- linux-2.4.29/arch/frv/kernel/head-uc-fr555.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/head-uc-fr555.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,348 @@
+/* head-uc-fr555.S: FR555 uc-linux specific bits of initialisation
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/spr-regs.h>
+#include <asm/mb86943a.h>
+#include "head.inc"
+
+
+#define __551_DARS0	0xfeff0100
+#define __551_DARS1	0xfeff0104
+#define __551_DARS2	0xfeff0108
+#define __551_DARS3	0xfeff010c
+#define __551_DAMK0	0xfeff0110
+#define __551_DAMK1	0xfeff0114
+#define __551_DAMK2	0xfeff0118
+#define __551_DAMK3	0xfeff011c
+#define __551_LCR	0xfeff1100
+#define __551_LSBR	0xfeff1c00
+
+	.section	.text.init,"ax"
+	.balign		4
+
+###############################################################################
+#
+# describe the position and layout of the SDRAM controller registers
+#
+#	ENTRY:			EXIT:
+# GR5	-			cacheline size
+# GR11	-			displacement of 2nd SDRAM addr reg from GR14
+# GR12	-			displacement of 3rd SDRAM addr reg from GR14
+# GR13	-			displacement of 4th SDRAM addr reg from GR14
+# GR14	-			address of 1st SDRAM addr reg
+# GR15	-			amount to shift address by to match SDRAM addr reg
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+# CC0	-			T if DARS0 is present
+# CC1	-			T if DARS1 is present
+# CC2	-			T if DARS2 is present
+# CC3	-			T if DARS3 is present
+#
+###############################################################################
+	.globl		__head_fr555_describe_sdram
+__head_fr555_describe_sdram:
+	sethi.p		%hi(__551_DARS0),gr14
+	setlo		%lo(__551_DARS0),gr14
+	setlos.p	#__551_DARS1-__551_DARS0,gr11
+	setlos		#__551_DARS2-__551_DARS0,gr12
+	setlos.p	#__551_DARS3-__551_DARS0,gr13
+	setlos		#64,gr5			; cacheline size
+	setlos		#20,gr15		; amount to shift addr by
+	setlos		#0x00ff,gr4
+	movgs		gr4,cccr		; extant DARS/DAMK regs
+	bralr
+
+###############################################################################
+#
+# rearrange the bus controller registers
+#
+#	ENTRY:			EXIT:
+# GR26	&__head_reference	[saved]
+# GR30	LED address		revised LED address
+#
+###############################################################################
+	.globl		__head_fr555_set_busctl
+__head_fr555_set_busctl:
+	LEDS		0x100f
+	sethi.p		%hi(__551_LSBR),gr10
+	setlo		%lo(__551_LSBR),gr10
+	sethi.p		%hi(__551_LCR),gr11
+	setlo		%lo(__551_LCR),gr11
+
+	# set the bus controller
+	sethi.p		%hi(__region_CS1),gr4
+	setlo		%lo(__region_CS1),gr4
+	sethi.p		%hi(__region_CS1_M),gr5
+	setlo		%lo(__region_CS1_M),gr5
+	sethi.p		%hi(__region_CS1_C),gr6
+	setlo		%lo(__region_CS1_C),gr6
+	sti		gr4,@(gr10,#1*0x08)
+	sti		gr5,@(gr10,#1*0x08+0x100)
+	sti		gr6,@(gr11,#1*0x08)
+	sethi.p		%hi(__region_CS2),gr4
+	setlo		%lo(__region_CS2),gr4
+	sethi.p		%hi(__region_CS2_M),gr5
+	setlo		%lo(__region_CS2_M),gr5
+	sethi.p		%hi(__region_CS2_C),gr6
+	setlo		%lo(__region_CS2_C),gr6
+	sti		gr4,@(gr10,#2*0x08)
+	sti		gr5,@(gr10,#2*0x08+0x100)
+	sti		gr6,@(gr11,#2*0x08)
+	sethi.p		%hi(__region_CS3),gr4
+	setlo		%lo(__region_CS3),gr4
+	sethi.p		%hi(__region_CS3_M),gr5
+	setlo		%lo(__region_CS3_M),gr5
+	sethi.p		%hi(__region_CS3_C),gr6
+	setlo		%lo(__region_CS3_C),gr6
+	sti		gr4,@(gr10,#3*0x08)
+	sti		gr5,@(gr10,#3*0x08+0x100)
+	sti		gr6,@(gr11,#3*0x08)
+	sethi.p		%hi(__region_CS4),gr4
+	setlo		%lo(__region_CS4),gr4
+	sethi.p		%hi(__region_CS4_M),gr5
+	setlo		%lo(__region_CS4_M),gr5
+	sethi.p		%hi(__region_CS4_C),gr6
+	setlo		%lo(__region_CS4_C),gr6
+	sti		gr4,@(gr10,#4*0x08)
+	sti		gr5,@(gr10,#4*0x08+0x100)
+	sti		gr6,@(gr11,#4*0x08)
+	sethi.p		%hi(__region_CS5),gr4
+	setlo		%lo(__region_CS5),gr4
+	sethi.p		%hi(__region_CS5_M),gr5
+	setlo		%lo(__region_CS5_M),gr5
+	sethi.p		%hi(__region_CS5_C),gr6
+	setlo		%lo(__region_CS5_C),gr6
+	sti		gr4,@(gr10,#5*0x08)
+	sti		gr5,@(gr10,#5*0x08+0x100)
+	sti		gr6,@(gr11,#5*0x08)
+	sethi.p		%hi(__region_CS6),gr4
+	setlo		%lo(__region_CS6),gr4
+	sethi.p		%hi(__region_CS6_M),gr5
+	setlo		%lo(__region_CS6_M),gr5
+	sethi.p		%hi(__region_CS6_C),gr6
+	setlo		%lo(__region_CS6_C),gr6
+	sti		gr4,@(gr10,#6*0x08)
+	sti		gr5,@(gr10,#6*0x08+0x100)
+	sti		gr6,@(gr11,#6*0x08)
+	sethi.p		%hi(__region_CS7),gr4
+	setlo		%lo(__region_CS7),gr4
+	sethi.p		%hi(__region_CS7_M),gr5
+	setlo		%lo(__region_CS7_M),gr5
+	sethi.p		%hi(__region_CS7_C),gr6
+	setlo		%lo(__region_CS7_C),gr6
+	sti		gr4,@(gr10,#7*0x08)
+	sti		gr5,@(gr10,#7*0x08+0x100)
+	sti		gr6,@(gr11,#7*0x08)
+	membar
+	bar
+
+	# adjust LED bank address
+#ifdef CONFIG_MB93091_VDK
+	sethi.p		%hi(LED_ADDR - 0x20000000 +__region_CS2),gr30
+	setlo		%lo(LED_ADDR - 0x20000000 +__region_CS2),gr30
+#endif
+	bralr
+
+###############################################################################
+#
+# determine the total SDRAM size
+#
+#	ENTRY:			EXIT:
+# GR25	-			SDRAM size
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+#
+###############################################################################
+	.globl		__head_fr555_survey_sdram
+__head_fr555_survey_sdram:
+	sethi.p		%hi(__551_DAMK0),gr11
+	setlo		%lo(__551_DAMK0),gr11
+	sethi.p		%hi(__551_DARS0),gr12
+	setlo		%lo(__551_DARS0),gr12
+
+	sethi.p		%hi(0xfff),gr17			; unused SDRAM AMK value
+	setlo		%lo(0xfff),gr17
+	setlos		#0,gr25
+
+	ldi		@(gr11,#0x00),gr6		; DAMK0: bits 11:0 match addr 11:0
+	subcc		gr6,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS0
+	ldi		@(gr12,#0x00),gr4		; DARS0
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS0:
+
+	ldi		@(gr11,#0x04),gr6		; DAMK1: bits 11:0 match addr 11:0
+	subcc		gr6,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS1
+	ldi		@(gr12,#0x04),gr4		; DARS1
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS1:
+
+	ldi		@(gr11,#0x8),gr6		; DAMK2: bits 11:0 match addr 11:0
+	subcc		gr6,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS2
+	ldi		@(gr12,#0x8),gr4		; DARS2
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS2:
+
+	ldi		@(gr11,#0xc),gr6		; DAMK3: bits 11:0 match addr 11:0
+	subcc		gr6,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS3
+	ldi		@(gr12,#0xc),gr4		; DARS3
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS3:
+	
+	slli		gr25,#20,gr25			; shift [11:0] -> [31:20]
+	bralr
+
+###############################################################################
+#
+# set the protection map with the I/DAMPR registers
+#
+#	ENTRY:			EXIT:
+# GR25	SDRAM size		saved
+# GR30	LED address		saved
+#
+###############################################################################
+	.globl		__head_fr555_set_protection
+__head_fr555_set_protection:
+	movsg		lr,gr27
+
+	sethi.p		%hi(0xfff00000),gr11
+	setlo		%lo(0xfff00000),gr11
+		
+	# set the I/O region protection registers for FR555
+	sethi.p		%hi(__region_IO),gr7
+	setlo		%lo(__region_IO),gr7
+	ori		gr7,#xAMPRx_SS_512Mb|xAMPRx_S_KERNEL|xAMPRx_C|xAMPRx_V,gr5
+	movgs		gr0,iampr15
+	movgs		gr0,iamlr15
+	movgs		gr5,dampr15
+	movgs		gr7,damlr15
+
+	# need to tile the remaining IAMPR/DAMPR registers to cover as much of the RAM as possible
+	# - start with the highest numbered registers
+	sethi.p		%hi(__kernel_image_end),gr8
+	setlo		%lo(__kernel_image_end),gr8
+	sethi.p		%hi(32768),gr4			; allow for a maximal allocator bitmap
+	setlo		%lo(32768),gr4
+	add		gr8,gr4,gr8
+	sethi.p		%hi(1024*2048-1),gr4		; round up to nearest 2MiB
+	setlo		%lo(1024*2048-1),gr4
+	add.p		gr8,gr4,gr8
+	not		gr4,gr4
+	and		gr8,gr4,gr8
+
+	sethi.p		%hi(__page_offset),gr9
+	setlo		%lo(__page_offset),gr9
+	add		gr9,gr25,gr9
+
+	# GR8 = base of uncovered RAM
+	# GR9 = top of uncovered RAM
+	# GR11 - mask for DAMLR/IAMLR regs
+	#
+	call		__head_split_region
+	movgs		gr4,iampr14
+	movgs		gr6,iamlr14
+	movgs		gr5,dampr14
+	movgs		gr7,damlr14
+	call		__head_split_region
+	movgs		gr4,iampr13
+	movgs		gr6,iamlr13
+	movgs		gr5,dampr13
+	movgs		gr7,damlr13
+	call		__head_split_region
+	movgs		gr4,iampr12
+	movgs		gr6,iamlr12
+	movgs		gr5,dampr12
+	movgs		gr7,damlr12
+	call		__head_split_region
+	movgs		gr4,iampr11
+	movgs		gr6,iamlr11
+	movgs		gr5,dampr11
+	movgs		gr7,damlr11
+	call		__head_split_region
+	movgs		gr4,iampr10
+	movgs		gr6,iamlr10
+	movgs		gr5,dampr10
+	movgs		gr7,damlr10
+	call		__head_split_region
+	movgs		gr4,iampr9
+	movgs		gr6,iamlr9
+	movgs		gr5,dampr9
+	movgs		gr7,damlr9
+	call		__head_split_region
+	movgs		gr4,iampr8
+	movgs		gr6,iamlr8
+	movgs		gr5,dampr8
+	movgs		gr7,damlr8
+
+	call		__head_split_region
+	movgs		gr4,iampr7
+	movgs		gr6,iamlr7
+	movgs		gr5,dampr7
+	movgs		gr7,damlr7
+	call		__head_split_region
+	movgs		gr4,iampr6
+	movgs		gr6,iamlr6
+	movgs		gr5,dampr6
+	movgs		gr7,damlr6
+	call		__head_split_region
+	movgs		gr4,iampr5
+	movgs		gr6,iamlr5
+	movgs		gr5,dampr5
+	movgs		gr7,damlr5
+	call		__head_split_region
+	movgs		gr4,iampr4
+	movgs		gr6,iamlr4
+	movgs		gr5,dampr4
+	movgs		gr7,damlr4
+	call		__head_split_region
+	movgs		gr4,iampr3
+	movgs		gr6,iamlr3
+	movgs		gr5,dampr3
+	movgs		gr7,damlr3
+	call		__head_split_region
+	movgs		gr4,iampr2
+	movgs		gr6,iamlr2
+	movgs		gr5,dampr2
+	movgs		gr7,damlr2
+	call		__head_split_region
+	movgs		gr4,iampr1
+	movgs		gr6,iamlr1
+	movgs		gr5,dampr1
+	movgs		gr7,damlr1
+
+	# cover kernel core image with kernel-only segment
+	sethi.p		%hi(__page_offset),gr8
+	setlo		%lo(__page_offset),gr8
+	call		__head_split_region
+
+#ifdef CONFIG_PROTECT_KERNEL
+	ori.p		gr4,#xAMPRx_S_KERNEL,gr4
+	ori		gr5,#xAMPRx_S_KERNEL,gr5
+#endif
+
+	movgs		gr4,iampr0
+	movgs		gr6,iamlr0
+	movgs		gr5,dampr0
+	movgs		gr7,damlr0
+	jmpl		@(gr27,gr0)
diff -urN linux-2.4.29/arch/frv/kernel/irq.c linux-2.4.29-uc1/arch/frv/kernel/irq.c
--- linux-2.4.29/arch/frv/kernel/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/irq.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,1014 @@
+/* irq.c: FRV IRQ handling
+ *
+ * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
+ * (mostly architecture independent, will move to kernel/irq.c in 2.5.)
+ *
+ * IRQs are in fact implemented a bit like signal handlers for the kernel.
+ * Naturally it's not a 1:1 relation, but there are similarities.
+ */
+
+#include <linux/config.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/irq.h>
+#include <linux/proc_fs.h>
+
+#include <asm/atomic.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/irc-regs.h>
+#include <asm/irq-routing.h>
+#include <asm/gdb-stub.h>
+
+extern void __init fpga_init(void);
+extern void __init route_mb93493_irqs(void);
+
+static void register_irq_proc (unsigned int irq);
+
+/*
+ * Special irq handlers.
+ */
+
+void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+
+atomic_t irq_err_count;
+
+/*
+ * Generic, controller-independent functions:
+ */
+int get_irq_list(char *buf)
+{
+	struct irq_group *group;
+	struct irqaction *action;
+	char *p = buf;
+	int level, grp, ix, j;
+
+	p += sprintf(p, "           ");
+	for (j = 0; j < smp_num_cpus; j++)
+		p += sprintf(p, "CPU%d       ", j);
+	*p++ = '\n';
+
+	for (grp = 0; grp < NR_IRQ_GROUPS; grp++) {
+		group = irq_groups[grp];
+		if (!group)
+			continue;
+
+		for (ix = 0; ix < NR_IRQ_ACTIONS_PER_GROUP ; ix++) {
+			action = group->actions[ix];
+			if (!action)
+				continue;
+
+			level = group->sources[ix]->level - frv_irq_levels;
+
+			p += sprintf(p, "%3d: ", (grp << NR_IRQ_LOG2_ACTIONS_PER_GROUP) + ix);
+#ifndef CONFIG_SMP
+			p += sprintf(p, "%10u ", kstat_irqs(level));
+#else
+			for (j = 0; j < smp_num_cpus; j++)
+				p += sprintf(p, "%10u ", kstat.irqs[cpu_logical_map(j)][level]);
+#endif
+			p += sprintf(p, " %12s@%x", group->sources[ix]->muxname, level);
+
+			p += sprintf(p, "  %s", action->name);
+			for (action = action->next; action; action = action->next)
+				p += sprintf(p, ", %s", action->name);
+			*p++ = '\n';
+		}
+	}
+
+#if CONFIG_SMP
+	p += sprintf(p, "LOC: ");
+	for (j = 0; j < smp_num_cpus; j++)
+		p += sprintf(p, "%10u ", apic_timer_irqs[cpu_logical_map(j)]);
+	p += sprintf(p, "\n");
+#endif
+
+	p += sprintf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+	return p - buf;
+}
+
+
+/*
+ * Global interrupt locks for SMP. Allow interrupts to come in on any
+ * CPU, yet make cli/sti act globally to protect critical regions..
+ */
+
+#ifdef CONFIG_SMP
+unsigned char global_irq_holder = NO_PROC_ID;
+unsigned volatile long global_irq_lock; /* pendantic: long for set_bit --RR */
+
+extern void show_stack(unsigned long* esp);
+
+static void show(char * str)
+{
+	int i;
+	int cpu = smp_processor_id();
+
+	printk("\n%s, CPU %d:\n", str, cpu);
+	printk("irq:  %d [",irqs_running());
+	for(i=0;i < smp_num_cpus;i++)
+		printk(" %d",local_irq_count(i));
+	printk(" ]\nbh:   %d [",spin_is_locked(&global_bh_lock) ? 1 : 0);
+	for(i=0;i < smp_num_cpus;i++)
+		printk(" %d",local_bh_count(i));
+
+	printk(" ]\nStack dumps:");
+	for(i = 0; i < smp_num_cpus; i++) {
+		unsigned long esp;
+		if (i == cpu)
+			continue;
+		printk("\nCPU %d:",i);
+		esp = init_tss[i].esp0;
+		if (!esp) {
+			/* tss->esp0 is set to NULL in cpu_init(),
+			 * it's initialized when the cpu returns to user
+			 * space. -- manfreds
+			 */
+			printk(" <unknown> ");
+			continue;
+		}
+		esp &= ~(THREAD_SIZE-1);
+		esp += sizeof(struct task_struct);
+		show_stack((void*)esp);
+ 	}
+	printk("\nCPU %d:",cpu);
+	show_stack(NULL);
+	printk("\n");
+}
+
+#define MAXCOUNT 100000000
+
+/*
+ * I had a lockup scenario where a tight loop doing
+ * spin_unlock()/spin_lock() on CPU#1 was racing with
+ * spin_lock() on CPU#0. CPU#0 should have noticed spin_unlock(), but
+ * apparently the spin_unlock() information did not make it
+ * through to CPU#0 ... nasty, is this by design, do we have to limit
+ * 'memory update oscillation frequency' artificially like here?
+ *
+ * Such 'high frequency update' races can be avoided by careful design, but
+ * some of our major constructs like spinlocks use similar techniques,
+ * it would be nice to clarify this issue. Set this define to 0 if you
+ * want to check whether your system freezes.  I suspect the delay done
+ * by SYNC_OTHER_CORES() is in correlation with 'snooping latency', but
+ * i thought that such things are guaranteed by design, since we use
+ * the 'LOCK' prefix.
+ */
+#define SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND 0
+
+#if SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND
+# define SYNC_OTHER_CORES(x) udelay(x+1)
+#else
+/*
+ * We have to allow irqs to arrive between __sti and __cli
+ */
+# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
+#endif
+
+static inline void wait_on_irq(int cpu)
+{
+	int count = MAXCOUNT;
+
+	for (;;) {
+
+		/*
+		 * Wait until all interrupts are gone. Wait
+		 * for bottom half handlers unless we're
+		 * already executing in one..
+		 */
+		if (!irqs_running())
+			if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock))
+				break;
+
+		/* Duh, we have to loop. Release the lock to avoid deadlocks */
+		clear_bit(0,&global_irq_lock);
+
+		for (;;) {
+			if (!--count) {
+				show("wait_on_irq");
+				count = ~0;
+			}
+			preempt_disable();
+			__sti();
+			SYNC_OTHER_CORES(cpu);
+			__cli();
+			preempt_enable();
+			if (irqs_running())
+				continue;
+			if (global_irq_lock)
+				continue;
+			if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock))
+				continue;
+			if (!test_and_set_bit(0,&global_irq_lock))
+				break;
+		}
+	}
+}
+
+/*
+ * This is called when we want to synchronize with
+ * interrupts. We may for example tell a device to
+ * stop sending interrupts: but to make sure there
+ * are no interrupts that are executing on another
+ * CPU we need to call this function.
+ */
+void synchronize_irq(void)
+{
+	if (irqs_running()) {
+		/* Stupid approach */
+		cli();
+		sti();
+	}
+}
+
+static inline void get_irqlock(int cpu)
+{
+	if (test_and_set_bit(0,&global_irq_lock)) {
+		/* do we already hold the lock? */
+		if ((unsigned char) cpu == global_irq_holder)
+			return;
+		/* Uhhuh.. Somebody else got it. Wait.. */
+		do {
+			do {
+			} while (test_bit(0,&global_irq_lock));
+		} while (test_and_set_bit(0,&global_irq_lock));
+	}
+	/*
+	 * We also to make sure that nobody else is running
+	 * in an interrupt context.
+	 */
+	wait_on_irq(cpu);
+
+	/*
+	 * Ok, finally..
+	 */
+	global_irq_holder = cpu;
+}
+
+#define EFLAGS_IF_SHIFT 9
+
+/*
+ * A global "cli()" while in an interrupt context
+ * turns into just a local cli(). Interrupts
+ * should use spinlocks for the (very unlikely)
+ * case that they ever want to protect against
+ * each other.
+ *
+ * If we already have local interrupts disabled,
+ * this will not turn a local disable into a
+ * global one (problems with spinlocks: this makes
+ * save_flags+cli+sti usable inside a spinlock).
+ */
+void __global_cli(void)
+{
+	unsigned int flags;
+
+	__save_flags(flags);
+	if (flags & (1 << EFLAGS_IF_SHIFT)) {
+		int cpu;
+		__cli();
+		cpu = smp_processor_id();
+		if (!local_irq_count(cpu))
+			get_irqlock(cpu);
+	}
+}
+
+void __global_sti(void)
+{
+	int cpu;
+
+	preempt_disble();
+	cpu = smp_processor_id();
+	if (!local_irq_count(cpu))
+		release_irqlock(cpu);
+	__sti();
+	preempt_enable();
+}
+
+/*
+ * SMP flags value to restore to:
+ * 0 - global cli
+ * 1 - global sti
+ * 2 - local cli
+ * 3 - local sti
+ */
+unsigned long __global_save_flags(void)
+{
+	int retval;
+	int local_enabled;
+	unsigned long flags;
+	int cpu;
+
+	__save_flags(flags);
+	local_enabled = (flags >> EFLAGS_IF_SHIFT) & 1;
+	/* default to local */
+	retval = 2 + local_enabled;
+
+	preempt_disable();
+	cpu = smp_processor_id();
+	/* check for global flags if we're not in an interrupt */
+	if (!local_irq_count(cpu)) {
+		if (local_enabled)
+			retval = 1;
+		if (global_irq_holder == cpu)
+			retval = 0;
+	}
+	preempt_enable();
+	return retval;
+}
+
+void __global_restore_flags(unsigned long flags)
+{
+	switch (flags) {
+	case 0:
+		__global_cli();
+		break;
+	case 1:
+		__global_sti();
+		break;
+	case 2:
+		__cli();
+		break;
+	case 3:
+		__sti();
+		break;
+	default:
+		printk("global_restore_flags: %08lx (%08lx)\n",
+			flags, (&flags)[-1]);
+	}
+}
+#endif
+
+/*
+ * Generic enable/disable code: this just calls
+ * down into the PIC-specific version for the actual
+ * hardware disable after having gotten the irq
+ * controller lock.
+ */
+
+/**
+ *	disable_irq_nosync - disable an irq without waiting
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line.  Disables and Enables are
+ *	nested.
+ *	Unlike disable_irq(), this function does not ensure existing
+ *	instances of the IRQ handler have completed before returning.
+ *
+ *	This function may be called from IRQ context.
+ */
+
+void disable_irq_nosync(unsigned int irq)
+{
+	struct irq_source *source;
+	struct irq_group *group;
+	struct irq_level *level;
+	unsigned long flags;
+	int idx = irq & (NR_IRQ_ACTIONS_PER_GROUP - 1);
+
+	group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
+	if (!group)
+		BUG();
+
+	source = group->sources[idx];
+	if (!source)
+		BUG();
+
+	level = source->level;
+
+	spin_lock_irqsave(&level->lock, flags);
+
+	if (group->control) {
+		if (!group->disable_cnt[idx]++)
+			group->control(group, idx, 0);
+	} else if (!level->disable_count++)
+		__set_MASK(level - frv_irq_levels);
+
+	spin_unlock_irqrestore(&level->lock, flags);
+}
+
+/**
+ *	disable_irq - disable an irq and wait for completion
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line.  Enables and Disables are
+ *	nested.
+ *	This function waits for any pending IRQ handlers for this interrupt
+ *	to complete before returning. If you use this function while
+ *	holding a resource the IRQ handler may need you will deadlock.
+ *
+ *	This function may be called - with care - from IRQ context.
+ */
+
+void disable_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+
+#ifdef CONFIG_SMP
+	if (!local_irq_count(smp_processor_id())) {
+		do {
+			barrier();
+		} while (irq_desc[irq].status & IRQ_INPROGRESS);
+	}
+#endif
+}
+
+/**
+ *	enable_irq - enable handling of an irq
+ *	@irq: Interrupt to enable
+ *
+ *	Undoes the effect of one call to disable_irq().  If this
+ *	matches the last disable, processing of interrupts on this
+ *	IRQ line is re-enabled.
+ *
+ *	This function may be called from IRQ context.
+ */
+
+void enable_irq(unsigned int irq)
+{
+	struct irq_source *source;
+	struct irq_group *group;
+	struct irq_level *level;
+	unsigned long flags;
+	int idx = irq & (NR_IRQ_ACTIONS_PER_GROUP - 1);
+	int count;
+
+	group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
+	if (!group)
+		BUG();
+
+	source = group->sources[idx];
+	if (!source)
+		BUG();
+
+	level = source->level;
+
+	spin_lock_irqsave(&level->lock, flags);
+	
+	if (group->control)
+		count = group->disable_cnt[idx];
+	else
+		count = level->disable_count;
+
+	switch (count) {
+	case 1:
+		if (group->control) {
+			if (group->actions[idx])
+				group->control(group, idx, 1);
+		} else {
+			if (level->usage)
+				__clr_MASK(level - frv_irq_levels);
+		}
+			/* fall-through */
+	default:
+		count--;
+		break;
+
+	case 0:
+		printk("enable_irq(%u) unbalanced from %p\n", irq, __builtin_return_address(0));
+	}
+
+	if (group->control)
+		group->disable_cnt[idx] = count;
+	else
+		level->disable_count = count;
+
+	spin_unlock_irqrestore(&level->lock, flags);
+}
+
+/*****************************************************************************/
+/*
+ * handles all normal device IRQ's
+ * - we use the IRQ level as the IRQ number
+ * - registers are referred to by the __frame variable (GR28)
+ */
+asmlinkage void do_IRQ(void)
+{
+	struct irq_source *source;
+	int level, cpu;
+
+	level = (__frame->tbr >> 4) & 0xf;
+	cpu = smp_processor_id();
+
+	if ((unsigned long) __frame - (unsigned long) (current + 1) < 512)
+		BUG();
+
+	__set_MASK(level);
+	__clr_RC(level);
+	__clr_IRL();
+
+	kstat.irqs[cpu][level]++;
+
+	irq_enter(cpu, level);
+
+	for (source = frv_irq_levels[level].sources; source; source = source->next)
+		source->doirq(source);
+
+	irq_exit(cpu, irq);
+
+	__clr_MASK(level);
+
+	/* only process softirqs if we didn't interrupt another interrupt handler */
+	if ((__frame->psr & PSR_PIL) == PSR_PIL_0)
+		if (softirq_pending(cpu))
+			do_softirq();
+
+} /* end do_IRQ() */
+
+/*****************************************************************************/
+/**
+ *	request_irq - allocate an interrupt line
+ *	@irq: Interrupt line to allocate
+ *	@handler: Function to be called when the IRQ occurs
+ *	@irqflags: Interrupt type flags
+ *	@devname: An ascii name for the claiming device
+ *	@dev_id: A cookie passed back to the handler function
+ *
+ *	This call allocates interrupt resources and enables the
+ *	interrupt line and IRQ handling. From the point this
+ *	call is made your handler function may be invoked. Since
+ *	your handler function must clear any interrupt the board
+ *	raises, you must take care both to initialise your hardware
+ *	and to set up the interrupt handler in the right order.
+ *
+ *	Dev_id must be globally unique. Normally the address of the
+ *	device data structure is used as the cookie. Since the handler
+ *	receives this value it makes sense to use it.
+ *
+ *	If your interrupt is shared you must pass a non NULL dev_id
+ *	as this is required when freeing the interrupt.
+ *
+ *	Flags:
+ *
+ *	SA_SHIRQ		Interrupt is shared
+ *
+ *	SA_INTERRUPT		Disable local interrupts while processing
+ *
+ *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
+ *
+ */
+
+int request_irq(unsigned int irq,
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags,
+		const char * devname,
+		void *dev_id)
+{
+	int retval;
+	struct irqaction *action;
+
+#if 1
+	/*
+	 * Sanity-check: shared interrupts should REALLY pass in
+	 * a real dev-ID, otherwise we'll have trouble later trying
+	 * to figure out which interrupt is which (messes up the
+	 * interrupt freeing logic etc).
+	 */
+	if (irqflags & SA_SHIRQ) {
+		if (!dev_id)
+			printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n",
+			       devname, (&irq)[-1]);
+	}
+#endif
+
+	if ((irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP) >= NR_IRQ_GROUPS)
+		return -EINVAL;
+	if (!handler)
+		return -EINVAL;
+
+	action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = 0;
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_irq(irq, action);
+	if (retval)
+		kfree(action);
+	return retval;
+}
+
+/**
+ *	free_irq - free an interrupt
+ *	@irq: Interrupt line to free
+ *	@dev_id: Device identity to free
+ *
+ *	Remove an interrupt handler. The handler is removed and if the
+ *	interrupt line is no longer in use by any driver it is disabled.
+ *	On a shared IRQ the caller must ensure the interrupt is disabled
+ *	on the card it drives before calling this function. The function
+ *	does not return until any executing interrupts for this IRQ
+ *	have completed.
+ *
+ *	This function may be called from interrupt context.
+ *
+ *	Bugs: Attempting to free an irq in a handler for the same irq hangs
+ *	      the machine.
+ */
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	struct irq_source *source;
+	struct irq_group *group;
+	struct irq_level *level;
+	struct irqaction **p, **pp;
+	unsigned long flags;
+
+	if ((irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP) >= NR_IRQ_GROUPS)
+		return;
+
+	group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
+	if (!group)
+		BUG();
+
+	source = group->sources[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
+	if (!source)
+		BUG();
+
+	level = source->level;
+	p = &group->actions[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
+
+	spin_lock_irqsave(&level->lock, flags);
+
+	for (pp = p; *pp; pp = &(*pp)->next) {
+		struct irqaction *action = *pp;
+
+		if (action->dev_id != dev_id)
+			continue;
+
+		/* found it - remove from the list of entries */
+		*pp = action->next;
+
+		level->usage--;
+
+		if (p == pp && group->control)
+			group->control(group, irq & (NR_IRQ_ACTIONS_PER_GROUP - 1), 0);
+
+		if (level->usage == 0)
+			__set_MASK(level - frv_irq_levels);
+
+		spin_unlock_irqrestore(&desc->lock,flags);
+
+#ifdef CONFIG_SMP
+		/* Wait to make sure it's not being used on another CPU */
+		while (desc->status & IRQ_INPROGRESS)
+			barrier();
+#endif
+		kfree(action);
+		return;
+	}
+}
+
+/*
+ * IRQ autodetection code..
+ *
+ * This depends on the fact that any interrupt that comes in on to an
+ * unassigned IRQ will cause GxICR_DETECT to be set
+ */
+
+static DECLARE_MUTEX(probe_sem);
+
+/**
+ *	probe_irq_on	- begin an interrupt autodetect
+ *
+ *	Commence probing for an interrupt. The interrupts are scanned
+ *	and a mask of potential interrupt lines is returned.
+ *
+ */
+
+unsigned long probe_irq_on(void)
+{
+	down(&probe_sem);
+	return 0;
+}
+
+/*
+ * Return a mask of triggered interrupts (this
+ * can handle only legacy ISA interrupts).
+ */
+
+/**
+ *	probe_irq_mask - scan a bitmap of interrupt lines
+ *	@val:	mask of interrupts to consider
+ *
+ *	Scan the ISA bus interrupt lines and return a bitmap of
+ *	active interrupts. The interrupt probe logic state is then
+ *	returned to its previous value.
+ *
+ *	Note: we need to scan all the irq's even though we will
+ *	only return ISA irq numbers - just so that we reset them
+ *	all to a known state.
+ */
+unsigned int probe_irq_mask(unsigned long xmask)
+{
+	up(&probe_sem);
+	return 0;
+}
+
+/*
+ * Return the one interrupt that triggered (this can
+ * handle any interrupt source).
+ */
+
+/**
+ *	probe_irq_off	- end an interrupt autodetect
+ *	@xmask: mask of potential interrupts (unused)
+ *
+ *	Scans the unused interrupt lines and returns the line which
+ *	appears to have triggered the interrupt. If no interrupt was
+ *	found then zero is returned. If more than one interrupt is
+ *	found then minus the first candidate is returned to indicate
+ *	their is doubt.
+ *
+ *	The interrupt probe logic state is returned to its previous
+ *	value.
+ *
+ *	BUGS: When used in a module (which arguably shouldnt happen)
+ *	nothing prevents two IRQ probe callers from overlapping. The
+ *	results of this are non-optimal.
+ */
+
+int probe_irq_off(unsigned long xmask)
+{
+	up(&probe_sem);
+	return -1;
+}
+
+/* this was setup_x86_irq but it seems pretty generic */
+int setup_irq(unsigned int irq, struct irqaction *new)
+{
+	struct irq_source *source;
+	struct irq_group *group;
+	struct irq_level *level;
+	struct irqaction **p, **pp;
+	unsigned long flags;
+
+	group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
+	if (!group)
+		BUG();
+
+	source = group->sources[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
+	if (!source)
+		BUG();
+
+	level = source->level;
+
+	p = &group->actions[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
+
+	/*
+	 * Some drivers like serial.c use request_irq() heavily,
+	 * so we have to be careful not to interfere with a
+	 * running system.
+	 */
+	if (new->flags & SA_SAMPLE_RANDOM) {
+		/*
+		 * This function might sleep, we want to call it first,
+		 * outside of the atomic block.
+		 * Yes, this might clear the entropy pool if the wrong
+		 * driver is attempted to be loaded, without actually
+		 * installing a new handler, but is this really a problem,
+		 * only the sysadmin is able to do this.
+		 */
+		rand_initialize_irq(irq);
+	}
+
+	/* must juggle the interrupt processing stuff with interrupts disabled */
+	spin_lock_irqsave(&level->lock, flags);
+
+	/* can't share interrupts unless all parties agree to */
+	if (level->usage != 0 && !(level->flags & new->flags & SA_SHIRQ)) {
+		spin_unlock_irqrestore(&desc->lock,flags);
+		return -EBUSY;
+	}
+
+	/* add new interrupt at end of irq queue */
+	pp = p;
+	while (*pp)
+		pp = &(*pp)->next;
+
+	*pp = new;
+
+	level->usage++;
+	level->flags = new->flags;
+
+	/* turn the interrupts on */
+	if (level->usage == 1)
+		__clr_MASK(level - frv_irq_levels);
+
+	if (p == pp && group->control)
+		group->control(group, irq & (NR_IRQ_ACTIONS_PER_GROUP - 1), 1);
+
+	spin_unlock_irqrestore(&level->lock, flags);
+	register_irq_proc(irq);
+	return 0;
+}
+
+static struct proc_dir_entry * root_irq_dir;
+static struct proc_dir_entry * irq_dir [NR_IRQS];
+
+#define HEX_DIGITS 8
+
+static unsigned int parse_hex_value (const char *buffer,
+				     unsigned long count, unsigned long *ret)
+{
+	unsigned char hexnum [HEX_DIGITS];
+	unsigned long value;
+	int i;
+
+	if (!count)
+		return -EINVAL;
+	if (count > HEX_DIGITS)
+		count = HEX_DIGITS;
+	if (copy_from_user(hexnum, buffer, count))
+		return -EFAULT;
+
+	/*
+	 * Parse the first 8 characters as a hex string, any non-hex char
+	 * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+	 */
+	value = 0;
+
+	for (i = 0; i < count; i++) {
+		unsigned int c = hexnum[i];
+
+		switch (c) {
+			case '0' ... '9': c -= '0'; break;
+			case 'a' ... 'f': c -= 'a'-10; break;
+			case 'A' ... 'F': c -= 'A'-10; break;
+		default:
+			goto out;
+		}
+		value = (value << 4) | c;
+	}
+out:
+	*ret = value;
+	return 0;
+}
+
+#if CONFIG_SMP
+
+static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
+
+static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
+static int irq_affinity_read_proc (char *page, char **start, off_t off,
+			int count, int *eof, void *data)
+{
+	if (count < HEX_DIGITS+1)
+		return -EINVAL;
+	return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
+}
+
+static int irq_affinity_write_proc (struct file *file, const char *buffer,
+					unsigned long count, void *data)
+{
+	int irq = (long) data, full_count = count, err;
+	unsigned long new_value;
+
+	if (!irq_desc[irq].handler->set_affinity)
+		return -EIO;
+
+	err = parse_hex_value(buffer, count, &new_value);
+
+	/*
+	 * Do not allow disabling IRQs completely - it's a too easy
+	 * way to make the system unusable accidentally :-) At least
+	 * one online CPU still has to be targeted.
+	 */
+	if (!(new_value & cpu_online_map))
+		return -EINVAL;
+
+	irq_affinity[irq] = new_value;
+	irq_desc[irq].handler->set_affinity(irq, new_value);
+
+	return full_count;
+}
+
+#endif
+
+static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
+			int count, int *eof, void *data)
+{
+	unsigned long *mask = (unsigned long *) data;
+	if (count < HEX_DIGITS+1)
+		return -EINVAL;
+	return sprintf (page, "%08lx\n", *mask);
+}
+
+static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
+					unsigned long count, void *data)
+{
+	unsigned long *mask = (unsigned long *) data, full_count = count, err;
+	unsigned long new_value;
+
+	show_state();
+	err = parse_hex_value(buffer, count, &new_value);
+	if (err)
+		return err;
+
+	*mask = new_value;
+	return full_count;
+}
+
+#define MAX_NAMELEN 10
+
+static void register_irq_proc (unsigned int irq)
+{
+	char name [MAX_NAMELEN];
+
+	if (!root_irq_dir || irq_dir[irq])
+		return;
+
+	memset(name, 0, MAX_NAMELEN);
+	sprintf(name, "%d", irq);
+
+	/* create /proc/irq/1234 */
+	irq_dir[irq] = proc_mkdir(name, root_irq_dir);
+
+#if CONFIG_SMP
+	{
+		struct proc_dir_entry *entry;
+
+		/* create /proc/irq/1234/smp_affinity */
+		entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
+
+		if (entry) {
+			entry->nlink = 1;
+			entry->data = (void *)(long)irq;
+			entry->read_proc = irq_affinity_read_proc;
+			entry->write_proc = irq_affinity_write_proc;
+		}
+
+		smp_affinity_entry[irq] = entry;
+	}
+#endif
+}
+
+unsigned long prof_cpu_mask = -1;
+
+void init_irq_proc (void)
+{
+	struct proc_dir_entry *entry;
+	int i;
+
+	/* create /proc/irq */
+	root_irq_dir = proc_mkdir("irq", 0);
+
+	/* create /proc/irq/prof_cpu_mask */
+	entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
+	if (!entry)
+	    return;
+
+	entry->nlink = 1;
+	entry->data = (void *)&prof_cpu_mask;
+	entry->read_proc = prof_cpu_mask_read_proc;
+	entry->write_proc = prof_cpu_mask_write_proc;
+
+	/*
+	 * Create entries for all existing IRQs.
+	 */
+	for (i = 0; i < NR_IRQS; i++)
+		register_irq_proc(i);
+}
+
+/*****************************************************************************/
+/*
+ * initialise the interrupt system
+ */
+void __init init_IRQ(void)
+{
+	route_cpu_irqs();
+	fpga_init();
+#ifdef CONFIG_FUJITSU_MB93493
+	route_mb93493_irqs();
+#endif
+} /* end init_IRQ() */
diff -urN linux-2.4.29/arch/frv/kernel/irq-mb93091.c linux-2.4.29-uc1/arch/frv/kernel/irq-mb93091.c
--- linux-2.4.29/arch/frv/kernel/irq-mb93091.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/irq-mb93091.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,116 @@
+/* irq-mb93091.c: MB93091 FPGA interrupt handling
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/irc-regs.h>
+#include <asm/irq-routing.h>
+
+#define __reg16(ADDR) (*(volatile unsigned short *)(ADDR))
+
+#define __get_IMR()	({ __reg16(0xffc00004); })
+#define __set_IMR(M)	do { __reg16(0xffc00004) = (M); wmb(); } while(0)
+#define __get_IFR()	({ __reg16(0xffc0000c); })
+#define __clr_IFR(M)	do { __reg16(0xffc0000c) = ~(M); wmb(); } while(0)
+
+static void frv_fpga_doirq(struct irq_source *source);
+static void frv_fpga_control(struct irq_group *group, int irq, int on);
+
+/*****************************************************************************/
+/*
+ * FPGA IRQ multiplexor
+ */
+static struct irq_source frv_fpga[4] = {
+#define __FPGA(X, M)					\
+	[X] = {						\
+		.muxname	= "fpga."#X,		\
+		.irqmask	= M,			\
+		.doirq		= frv_fpga_doirq,	\
+	}
+
+	__FPGA(0, 0x0028),
+	__FPGA(1, 0x0050),
+	__FPGA(2, 0x1c00),
+	__FPGA(3, 0x6386),
+};
+
+static struct irq_group frv_fpga_irqs = {
+	.first_irq	= IRQ_BASE_FPGA,
+	.control	= frv_fpga_control,
+	.sources = {
+		[ 1] = &frv_fpga[3],
+		[ 2] = &frv_fpga[3],
+		[ 3] = &frv_fpga[0],
+		[ 4] = &frv_fpga[1],
+		[ 5] = &frv_fpga[0],
+		[ 6] = &frv_fpga[1],
+		[ 7] = &frv_fpga[3],
+		[ 8] = &frv_fpga[3],
+		[ 9] = &frv_fpga[3],
+		[10] = &frv_fpga[2],
+		[11] = &frv_fpga[2],
+		[12] = &frv_fpga[2],
+		[13] = &frv_fpga[3],
+		[14] = &frv_fpga[3],
+	},
+};
+
+
+static void frv_fpga_control(struct irq_group *group, int index, int on)
+{
+	uint16_t imr = __get_IMR();
+
+	if (on)
+		imr &= ~(1 << index);
+	else
+		imr |= 1 << index;
+
+	__set_IMR(imr);
+}
+
+static void frv_fpga_doirq(struct irq_source *source)
+{
+	uint16_t mask, imr;
+
+	imr = __get_IMR();
+	mask = source->irqmask & ~imr & __get_IFR();
+	if (mask) {
+		__set_IMR(imr | mask);
+		__clr_IFR(mask);
+		distribute_irqs(&frv_fpga_irqs, mask);
+		__set_IMR(imr);
+	}
+}
+
+void __init fpga_init(void)
+{
+	__set_IMR(0x7ffe);
+	__clr_IFR(0x0000);
+
+	frv_irq_route_external(&frv_fpga[0], IRQ_CPU_EXTERNAL0);
+	frv_irq_route_external(&frv_fpga[1], IRQ_CPU_EXTERNAL1);
+	frv_irq_route_external(&frv_fpga[2], IRQ_CPU_EXTERNAL2);
+	frv_irq_route_external(&frv_fpga[3], IRQ_CPU_EXTERNAL3);
+	frv_irq_set_group(&frv_fpga_irqs);
+}
diff -urN linux-2.4.29/arch/frv/kernel/irq-mb93093.c linux-2.4.29-uc1/arch/frv/kernel/irq-mb93093.c
--- linux-2.4.29/arch/frv/kernel/irq-mb93093.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/irq-mb93093.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,99 @@
+/* irq-mb93093.c: MB93093 FPGA interrupt handling
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/irc-regs.h>
+#include <asm/irq-routing.h>
+
+#define __reg16(ADDR) (*(volatile unsigned short *)(__region_CS2 + (ADDR)))
+
+#define __get_IMR()	({ __reg16(0x0a); })
+#define __set_IMR(M)	do { __reg16(0x0a) = (M);		wmb(); } while(0)
+#define __get_IFR()	({ __reg16(0x02); })
+#define __clr_IFR(M)	do { __reg16(0x02) = ~(M);		wmb(); } while(0)
+
+static void frv_fpga_doirq(struct irq_source *source);
+static void frv_fpga_control(struct irq_group *group, int irq, int on);
+
+/*****************************************************************************/
+/*
+ * FPGA IRQ multiplexor
+ */
+static struct irq_source frv_fpga[4] = {
+#define __FPGA(X, M)					\
+	[X] = {						\
+		.muxname	= "fpga."#X,		\
+		.irqmask	= M,			\
+		.doirq		= frv_fpga_doirq,	\
+	}
+
+	__FPGA(0, 0x0700),
+};
+
+static struct irq_group frv_fpga_irqs = {
+	.first_irq	= IRQ_BASE_FPGA,
+	.control	= frv_fpga_control,
+	.sources = {
+		[ 8] = &frv_fpga[0],
+		[ 9] = &frv_fpga[0],
+		[10] = &frv_fpga[0],
+	},
+};
+
+
+static void frv_fpga_control(struct irq_group *group, int index, int on)
+{
+	uint16_t imr = __get_IMR();
+
+	if (on)
+		imr &= ~(1 << index);
+	else
+		imr |= 1 << index;
+
+	__set_IMR(imr);
+}
+
+static void frv_fpga_doirq(struct irq_source *source)
+{
+	uint16_t mask, imr;
+
+	imr = __get_IMR();
+	mask = source->irqmask & ~imr & __get_IFR();
+	if (mask) {
+		__set_IMR(imr | mask);
+		__clr_IFR(mask);
+		distribute_irqs(&frv_fpga_irqs, mask);
+		__set_IMR(imr);
+	}
+}
+
+void __init fpga_init(void)
+{
+	__set_IMR(0x0700);
+	__clr_IFR(0x0000);
+
+	frv_irq_route_external(&frv_fpga[0], IRQ_CPU_EXTERNAL2);
+	frv_irq_set_group(&frv_fpga_irqs);
+}
diff -urN linux-2.4.29/arch/frv/kernel/irq-mb93493.c linux-2.4.29-uc1/arch/frv/kernel/irq-mb93493.c
--- linux-2.4.29/arch/frv/kernel/irq-mb93493.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/irq-mb93493.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,108 @@
+/* irq-mb93493.c: MB93493 companion chip interrupt handler
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/irc-regs.h>
+#include <asm/irq-routing.h>
+#include <asm/mb93493-irqs.h>
+
+static void frv_mb93493_doirq(struct irq_source *source);
+
+/*****************************************************************************/
+/*
+ * MB93493 companion chip IRQ multiplexor
+ */
+static struct irq_source frv_mb93493[2] = {
+	[0] = {
+		.muxname		= "mb93493.0",
+		.muxdata		= __region_CS3 + 0x3d0,
+		.doirq			= frv_mb93493_doirq,
+		.irqmask		= 0x0000,
+	},
+	[1] = {
+		.muxname		= "mb93493.1",
+		.muxdata		= __region_CS3 + 0x3d4,
+		.doirq			= frv_mb93493_doirq,
+		.irqmask		= 0x0000,
+	},
+};
+
+static void frv_mb93493_control(struct irq_group *group, int index, int on)
+{
+	struct irq_source *source;
+	uint32_t iqsr;
+
+	if ((frv_mb93493[0].irqmask & (1 << index)))
+		source = &frv_mb93493[0];
+	else
+		source = &frv_mb93493[1];
+
+	iqsr = readl(source->muxdata);
+	if (on)
+		iqsr |= 1 << (index + 16);
+	else
+		iqsr &= ~(1 << (index + 16));
+
+	writel(iqsr, source->muxdata);
+}
+
+static struct irq_group frv_mb93493_irqs = {
+	.first_irq	= IRQ_BASE_MB93493,
+	.control	= frv_mb93493_control,
+};
+
+static void frv_mb93493_doirq(struct irq_source *source)
+{
+	uint32_t mask = readl(source->muxdata);
+	mask = mask & (mask >> 16) & 0xffff;
+
+	if (mask)
+		distribute_irqs(&frv_mb93493_irqs, mask);
+}
+
+static void __init mb93493_irq_route(int irq, int source)
+{
+	frv_mb93493[source].irqmask |= 1 << (irq - IRQ_BASE_MB93493);
+	frv_mb93493_irqs.sources[irq - IRQ_BASE_MB93493] = &frv_mb93493[source];
+}
+
+void __init route_mb93493_irqs(void)
+{
+	frv_irq_route_external(&frv_mb93493[0], IRQ_CPU_MB93493_0);
+	frv_irq_route_external(&frv_mb93493[1], IRQ_CPU_MB93493_1);
+
+	frv_irq_set_group(&frv_mb93493_irqs);
+
+	mb93493_irq_route(IRQ_MB93493_VDC,		IRQ_MB93493_VDC_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_VCC,		IRQ_MB93493_VCC_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_AUDIO_IN,		IRQ_MB93493_AUDIO_IN_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_I2C_0,		IRQ_MB93493_I2C_0_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_I2C_1,		IRQ_MB93493_I2C_1_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_USB,		IRQ_MB93493_USB_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_LOCAL_BUS,	IRQ_MB93493_LOCAL_BUS_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_PCMCIA,		IRQ_MB93493_PCMCIA_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_GPIO,		IRQ_MB93493_GPIO_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_AUDIO_OUT,	IRQ_MB93493_AUDIO_OUT_ROUTE);
+}
diff -urN linux-2.4.29/arch/frv/kernel/irq-routing.c linux-2.4.29-uc1/arch/frv/kernel/irq-routing.c
--- linux-2.4.29/arch/frv/kernel/irq-routing.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/irq-routing.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,291 @@
+/* irq-routing.c: IRQ routing
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/sched.h>
+#include <linux/random.h>
+#include <linux/init.h>
+#include <linux/serial_reg.h>
+#include <asm/io.h>
+#include <asm/irq-routing.h>
+#include <asm/irc-regs.h>
+#include <asm/serial-regs.h>
+#include <asm/dma.h>
+
+struct irq_level frv_irq_levels[16] = {
+	[0 ... 15] = {
+		.lock	= SPIN_LOCK_UNLOCKED,
+	}
+};
+
+struct irq_group *irq_groups[NR_IRQ_GROUPS];
+
+extern struct irq_group frv_cpu_irqs;
+
+void __init frv_irq_route(struct irq_source *source, int irqlevel)
+{
+	source->level = &frv_irq_levels[irqlevel];
+	source->next = frv_irq_levels[irqlevel].sources;
+	frv_irq_levels[irqlevel].sources = source;
+}
+
+void __init frv_irq_route_external(struct irq_source *source, int irq)
+{
+	int irqlevel = 0;
+
+	switch (irq) {
+	case IRQ_CPU_EXTERNAL0:	irqlevel = IRQ_XIRQ0_LEVEL; break;
+	case IRQ_CPU_EXTERNAL1:	irqlevel = IRQ_XIRQ1_LEVEL; break;
+	case IRQ_CPU_EXTERNAL2:	irqlevel = IRQ_XIRQ2_LEVEL; break;
+	case IRQ_CPU_EXTERNAL3:	irqlevel = IRQ_XIRQ3_LEVEL; break;
+	case IRQ_CPU_EXTERNAL4:	irqlevel = IRQ_XIRQ4_LEVEL; break;
+	case IRQ_CPU_EXTERNAL5:	irqlevel = IRQ_XIRQ5_LEVEL; break;
+	case IRQ_CPU_EXTERNAL6:	irqlevel = IRQ_XIRQ6_LEVEL; break;
+	case IRQ_CPU_EXTERNAL7:	irqlevel = IRQ_XIRQ7_LEVEL; break;
+	default: BUG();
+	}
+
+	source->level = &frv_irq_levels[irqlevel];
+	source->next = frv_irq_levels[irqlevel].sources;
+	frv_irq_levels[irqlevel].sources = source;
+}
+
+void __init frv_irq_set_group(struct irq_group *group)
+{
+	irq_groups[group->first_irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP] = group; 
+}
+
+void distribute_irqs(struct irq_group *group, unsigned long irqmask)
+{
+	struct irqaction *action;
+	int irq;
+
+	while (irqmask) {
+		asm("scan %1,gr0,%0" : "=r"(irq) : "r"(irqmask));
+		if (irq < 0 || irq > 31)
+			asm volatile("break");
+		irq = 31 - irq;
+
+		irqmask &= ~(1 << irq);
+		action = group->actions[irq];
+
+		irq += group->first_irq;
+
+		if (action) {
+			int status = 0;
+
+			if (!(action->flags & SA_INTERRUPT))
+				sti();
+
+			do {
+				status |= action->flags;
+				action->handler(irq, action->dev_id, __frame);
+				action = action->next;
+			} while (action);
+
+			if (status & SA_SAMPLE_RANDOM)
+				add_interrupt_randomness(irq);
+			cli();
+		}
+	}
+}
+
+/*****************************************************************************/
+/*
+ * CPU UART interrupts
+ */
+static void frv_cpuuart_doirq(struct irq_source *source)
+{
+	uint8_t iir = readb((void *) source->muxdata + UART_IIR * 8);
+	if ((iir & 0x0f) != UART_IIR_NO_INT)
+		distribute_irqs(&frv_cpu_irqs, source->irqmask);
+}
+
+struct irq_source frv_cpuuart[2] = {
+#define __CPUUART(X, A)					\
+	[X] = {						\
+		.muxname	= "uart",		\
+		.muxdata	= A,			\
+		.irqmask	= 1 << IRQ_CPU_UART##X,	\
+		.doirq		= frv_cpuuart_doirq,	\
+	}
+
+	__CPUUART(0, UART0_BASE),
+	__CPUUART(1, UART1_BASE),
+};
+
+/*****************************************************************************/
+/*
+ * CPU DMA interrupts
+ */
+static void frv_cpudma_doirq(struct irq_source *source)
+{
+	uint32_t cstr = readl((void *) source->muxdata + DMAC_CSTRx);
+	if (cstr & DMAC_CSTRx_INT)
+		distribute_irqs(&frv_cpu_irqs, source->irqmask);
+}
+
+struct irq_source frv_cpudma[8] = {
+#define __CPUDMA(X, A)					\
+	[X] = {						\
+		.muxname	= "dma",		\
+		.muxdata	= A,			\
+		.irqmask	= 1 << IRQ_CPU_DMA##X,	\
+		.doirq		= frv_cpudma_doirq,	\
+	}
+
+	__CPUDMA(0, 0xfe000900),
+	__CPUDMA(1, 0xfe000980),
+	__CPUDMA(2, 0xfe000a00),
+	__CPUDMA(3, 0xfe000a80),
+	__CPUDMA(4, 0xfe001000),
+	__CPUDMA(5, 0xfe001080),
+	__CPUDMA(6, 0xfe001100),
+	__CPUDMA(7, 0xfe001180),
+};
+
+/*****************************************************************************/
+/*
+ * CPU timer interrupts - can't tell whether they've generated an interrupt or not
+ */
+static void frv_cputimer_doirq(struct irq_source *source)
+{
+	distribute_irqs(&frv_cpu_irqs, source->irqmask);
+}
+
+struct irq_source frv_cputimer[3] = {
+#define __CPUTIMER(X)						\
+	[X] = {							\
+		.muxname	= "timer",			\
+		.muxdata	= 0,				\
+		.irqmask	= 1 << IRQ_CPU_TIMER##X,	\
+		.doirq		= frv_cputimer_doirq,		\
+	}
+
+	__CPUTIMER(0),
+	__CPUTIMER(1),
+	__CPUTIMER(2),
+};
+
+/*****************************************************************************/
+/*
+ * external CPU interrupts - can't tell directly whether they've generated an interrupt or not
+ */
+static void frv_cpuexternal_doirq(struct irq_source *source)
+{
+	distribute_irqs(&frv_cpu_irqs, source->irqmask);
+}
+
+struct irq_source frv_cpuexternal[8] = {
+#define __CPUEXTERNAL(X)					\
+	[X] = {							\
+		.muxname	= "ext",			\
+		.muxdata	= 0,				\
+		.irqmask	= 1 << IRQ_CPU_EXTERNAL##X,	\
+		.doirq		= frv_cpuexternal_doirq,	\
+	}
+
+	__CPUEXTERNAL(0),
+	__CPUEXTERNAL(1),
+	__CPUEXTERNAL(2),
+	__CPUEXTERNAL(3),
+	__CPUEXTERNAL(4),
+	__CPUEXTERNAL(5),
+	__CPUEXTERNAL(6),
+	__CPUEXTERNAL(7),
+};
+
+#define set_IRR(N,A,B,C,D) __set_IRR(N, (A << 28) | (B << 24) | (C << 20) | (D << 16))
+
+struct irq_group frv_cpu_irqs = {
+	.sources = {
+		[IRQ_CPU_UART0]		= &frv_cpuuart[0],
+		[IRQ_CPU_UART1]		= &frv_cpuuart[1],
+		[IRQ_CPU_TIMER0]	= &frv_cputimer[0],
+		[IRQ_CPU_TIMER1]	= &frv_cputimer[1],
+		[IRQ_CPU_TIMER2]	= &frv_cputimer[2],
+		[IRQ_CPU_DMA0]		= &frv_cpudma[0],
+		[IRQ_CPU_DMA1]		= &frv_cpudma[1],
+		[IRQ_CPU_DMA2]		= &frv_cpudma[2],
+		[IRQ_CPU_DMA3]		= &frv_cpudma[3],
+		[IRQ_CPU_DMA4]		= &frv_cpudma[4],
+		[IRQ_CPU_DMA5]		= &frv_cpudma[5],
+		[IRQ_CPU_DMA6]		= &frv_cpudma[6],
+		[IRQ_CPU_DMA7]		= &frv_cpudma[7],
+		[IRQ_CPU_EXTERNAL0]	= &frv_cpuexternal[0],
+		[IRQ_CPU_EXTERNAL1]	= &frv_cpuexternal[1],
+		[IRQ_CPU_EXTERNAL2]	= &frv_cpuexternal[2],
+		[IRQ_CPU_EXTERNAL3]	= &frv_cpuexternal[3],
+		[IRQ_CPU_EXTERNAL4]	= &frv_cpuexternal[4],
+		[IRQ_CPU_EXTERNAL5]	= &frv_cpuexternal[5],
+		[IRQ_CPU_EXTERNAL6]	= &frv_cpuexternal[6],
+		[IRQ_CPU_EXTERNAL7]	= &frv_cpuexternal[7],
+	},
+};
+
+/*****************************************************************************/
+/*
+ * route the CPU's interrupt sources
+ */
+void __init route_cpu_irqs(void)
+{
+	frv_irq_set_group(&frv_cpu_irqs);
+
+	__set_IITMR(0, 0x003f0000);	/* DMA0-3, TIMER0-2 IRQ detect levels */
+	__set_IITMR(1, 0x20000000);	/* ERR0-1, UART0-1, DMA4-7 IRQ detect levels */
+
+	/* route UART and error interrupts */
+	frv_irq_route(&frv_cpuuart[0],	IRQ_UART0_LEVEL);
+	frv_irq_route(&frv_cpuuart[1],	IRQ_UART1_LEVEL);
+
+	set_IRR(6, IRQ_GDBSTUB_LEVEL, IRQ_GDBSTUB_LEVEL, IRQ_UART1_LEVEL, IRQ_UART0_LEVEL);
+
+	/* route DMA channel interrupts */
+	frv_irq_route(&frv_cpudma[0],	IRQ_DMA0_LEVEL);
+	frv_irq_route(&frv_cpudma[1],	IRQ_DMA1_LEVEL);
+	frv_irq_route(&frv_cpudma[2],	IRQ_DMA2_LEVEL);
+	frv_irq_route(&frv_cpudma[3],	IRQ_DMA3_LEVEL);
+	frv_irq_route(&frv_cpudma[4],	IRQ_DMA4_LEVEL);
+	frv_irq_route(&frv_cpudma[5],	IRQ_DMA5_LEVEL);
+	frv_irq_route(&frv_cpudma[6],	IRQ_DMA6_LEVEL);
+	frv_irq_route(&frv_cpudma[7],	IRQ_DMA7_LEVEL);
+
+	set_IRR(4, IRQ_DMA3_LEVEL, IRQ_DMA2_LEVEL, IRQ_DMA1_LEVEL, IRQ_DMA0_LEVEL);
+	set_IRR(7, IRQ_DMA7_LEVEL, IRQ_DMA6_LEVEL, IRQ_DMA5_LEVEL, IRQ_DMA4_LEVEL);
+
+	/* route timer interrupts */
+	frv_irq_route(&frv_cputimer[0],	IRQ_TIMER0_LEVEL);
+	frv_irq_route(&frv_cputimer[1],	IRQ_TIMER1_LEVEL);
+	frv_irq_route(&frv_cputimer[2],	IRQ_TIMER2_LEVEL);
+
+	set_IRR(5, 0, IRQ_TIMER2_LEVEL, IRQ_TIMER1_LEVEL, IRQ_TIMER0_LEVEL);
+
+	/* route external interrupts */
+	frv_irq_route(&frv_cpuexternal[0], IRQ_XIRQ0_LEVEL);
+	frv_irq_route(&frv_cpuexternal[1], IRQ_XIRQ1_LEVEL);
+	frv_irq_route(&frv_cpuexternal[2], IRQ_XIRQ2_LEVEL);
+	frv_irq_route(&frv_cpuexternal[3], IRQ_XIRQ3_LEVEL);
+	frv_irq_route(&frv_cpuexternal[4], IRQ_XIRQ4_LEVEL);
+	frv_irq_route(&frv_cpuexternal[5], IRQ_XIRQ5_LEVEL);
+	frv_irq_route(&frv_cpuexternal[6], IRQ_XIRQ6_LEVEL);
+	frv_irq_route(&frv_cpuexternal[7], IRQ_XIRQ7_LEVEL);
+
+	set_IRR(2, IRQ_XIRQ7_LEVEL, IRQ_XIRQ6_LEVEL, IRQ_XIRQ5_LEVEL, IRQ_XIRQ4_LEVEL);
+	set_IRR(3, IRQ_XIRQ3_LEVEL, IRQ_XIRQ2_LEVEL, IRQ_XIRQ1_LEVEL, IRQ_XIRQ0_LEVEL);
+
+#if defined(CONFIG_MB93091_VDK)
+	__set_TM1(0x55550000);		/* XIRQ7-0 all active low */
+#elif defined(CONFIG_MB93093_PDK)
+	__set_TM1(0x15550000);		/* XIRQ7 active high, 6-0 all active low */
+#else
+#error dont know external IRQ trigger levels for this setup
+#endif
+
+} /* end route_cpu_irqs() */
diff -urN linux-2.4.29/arch/frv/kernel/kernel_thread.S linux-2.4.29-uc1/arch/frv/kernel/kernel_thread.S
--- linux-2.4.29/arch/frv/kernel/kernel_thread.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/kernel_thread.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,70 @@
+/* kernel_thread.S: kernel thread creation
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/linkage.h>
+#include <asm/unistd.h>
+
+#define CLONE_VM	0x00000100	/* set if VM shared between processes */
+#define	KERN_ERR	"<3>"
+
+	.section .rodata
+kernel_thread_emsg:
+	.asciz	KERN_ERR "failed to create kernel thread: error=%d\n"
+
+	.text
+	.balign		4
+
+/*
+ * Create a kernel thread
+ *
+ * int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+ */
+	.globl		arch_kernel_thread
+arch_kernel_thread:
+	or.p		gr8,gr0,gr4
+	or		gr9,gr0,gr5
+	
+	# start by forking the current process, but with shared VM
+	setlos.p	#__NR_clone,gr7		; syscall number
+	ori		gr10,#CLONE_VM,gr8	; first syscall arg	[clone_flags]
+	sethi.p		#0xe4e4,gr9		; second syscall arg	[newsp]
+	setlo		#0xe4e4,gr9
+	tira		gr0,#0
+	setlos.p	#4095,gr7
+	andcc		gr8,gr8,gr0,icc0
+	addcc.p		gr8,gr7,gr0,icc1
+	bnelr		icc0,#2
+	bc		icc1,#0,kernel_thread_error
+
+	# now invoke the work function
+	or		gr5,gr0,gr8
+	calll		@(gr4,gr0)
+
+	# and finally exit the thread
+	setlos		#__NR_exit,gr7		; syscall number
+	tira		gr0,#0
+
+kernel_thread_error:
+	subi		sp,#8,sp
+	movsg		lr,gr4
+	sti		gr8,@(sp,#0)
+	sti.p		gr4,@(sp,#4)
+
+	or		gr8,gr0,gr9
+	sethi.p		%hi(kernel_thread_emsg),gr8
+	setlo		%lo(kernel_thread_emsg),gr8
+
+	call		SYMBOL_NAME(printk)
+
+	ldi		@(sp,#4),gr4
+	ldi		@(sp,#0),gr8
+	subi		sp,#8,sp
+	jmpl		@(gr4,gr0)
diff -urN linux-2.4.29/arch/frv/kernel/local.h linux-2.4.29-uc1/arch/frv/kernel/local.h
--- linux-2.4.29/arch/frv/kernel/local.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/local.h	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,56 @@
+/* local.h: local definitions
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _FRV_LOCAL_H
+#define _FRV_LOCAL_H
+
+#include <asm/vmlinux.h>
+
+#ifndef __ASSEMBLY__
+
+/* dma.c */
+extern unsigned long frv_dma_inprogress;
+
+extern void frv_dma_pause_all(void);
+extern void frv_dma_resume_all(void);
+
+/* sleep.S */
+extern asmlinkage void frv_cpu_suspend(unsigned long);
+extern asmlinkage void frv_cpu_core_sleep(void);
+
+/* setup.c */
+extern unsigned long __nongprelbss pdm_suspend_mode;
+extern void determine_clocks(int verbose);
+extern int __nongprelbss clock_p0_current;
+extern int __nongprelbss clock_cm_current;
+extern int __nongprelbss clock_cmode_current;
+
+#ifdef CONFIG_PM
+extern int __nongprelbss clock_cmodes_permitted;
+extern unsigned long __nongprelbss clock_bits_settable;
+#define CLOCK_BIT_CM		0x0000000f
+#define CLOCK_BIT_CM_H		0x00000001	/* CLKC.CM can be set to 0 */
+#define CLOCK_BIT_CM_M		0x00000002	/* CLKC.CM can be set to 1 */
+#define CLOCK_BIT_CM_L		0x00000004	/* CLKC.CM can be set to 2 */
+#define CLOCK_BIT_P0		0x00000010	/* CLKC.P0 can be changed */
+#define CLOCK_BIT_CMODE		0x00000020	/* CLKC.CMODE can be changed */
+
+extern void (*__power_switch_wake_setup)(void);
+extern int  (*__power_switch_wake_check)(void);
+extern void (*__power_switch_wake_cleanup)(void);
+#endif
+
+/* time.c */
+extern void time_divisor_init(void);
+
+
+#endif /* __ASSEMBLY__ */
+#endif /* _FRV_LOCAL_H */
diff -urN linux-2.4.29/arch/frv/kernel/Makefile linux-2.4.29-uc1/arch/frv/kernel/Makefile
--- linux-2.4.29/arch/frv/kernel/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/Makefile	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,37 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+all: head.o entry-table.o kernel.o
+
+export-objs := frv_ksyms.o semaphore.o dma.o
+
+O_TARGET := kernel.o
+
+obj-y := entry.o break.o switch_to.o kernel_thread.o \
+	 process.o traps.o ptrace.o signal.o nmi.o dma.o \
+	 sys_frv.o time.o semaphore.o setup.o frv_ksyms.o \
+	 debug-stub.o irq.o irq-routing.o sleep.o uaccess.o
+
+obj-$(CONFIG_MMU_LINUX)		+= head-mmu-fr451.o
+obj-$(CONFIG_UCLINUX)		+= head-uc-fr401.o head-uc-fr451.o head-uc-fr555.o
+
+obj-$(CONFIG_GDBSTUB)		+= gdb-stub.o gdb-io.o
+
+obj-$(CONFIG_MB93091_VDK)	+= irq-mb93091.o
+obj-$(CONFIG_MB93093_PDK)	+= irq-mb93093.o
+obj-$(CONFIG_FUJITSU_MB93493)	+= irq-mb93493.o
+obj-$(CONFIG_PM)		+= pm.o cmode.o
+obj-$(CONFIG_SYSCTL)		+= sysctl.o
+
+ifeq ($(CONFIG_MB93093_PDK),y)
+obj-$(CONFIG_PM)		+= pm-mb93093.o
+endif
+
+include $(TOPDIR)/Rules.make
+
diff -urN linux-2.4.29/arch/frv/kernel/nmi.c linux-2.4.29-uc1/arch/frv/kernel/nmi.c
--- linux-2.4.29/arch/frv/kernel/nmi.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/nmi.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,42 @@
+/* nmi.c: FRV NMI handler (level 15 external interrupt)
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/irq.h>
+#include <linux/proc_fs.h>
+
+#include <asm/atomic.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/pgalloc.h>
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/gdb-stub.h>
+
+/*****************************************************************************/
+/*
+ * deal with the NMI
+ */
+asmlinkage void do_NMI(void)
+{
+} /* end do_IRQ() */
diff -urN linux-2.4.29/arch/frv/kernel/pm.c linux-2.4.29-uc1/arch/frv/kernel/pm.c
--- linux-2.4.29/arch/frv/kernel/pm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/pm.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,430 @@
+/*
+ * FR-V Power Management Routines
+ *
+ * Copyright (c) 2004 Red Hat, Inc.
+ *
+ * Based on SA1100 version:
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/sysctl.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+
+#include <asm/mb86943a.h>
+
+#include "local.h"
+
+extern void frv_change_cmode(int);
+
+/*
+ * Debug macros
+ */
+#define DEBUG
+
+int pm_do_suspend(void)
+{
+	cli();
+
+	__set_LEDS(0xb1);
+
+	/* go zzz */
+	frv_cpu_suspend(pdm_suspend_mode);
+
+	__set_LEDS(0xb2);
+
+	sti();
+
+	return 0;
+}
+
+static unsigned long __irq_mask;
+/*
+ * Setup interrupt masks, etc to enable wakeup by power switch
+ */
+static void __default_power_switch_setup(void)
+{
+	/* default is to mask all interrupt sources. */
+	__irq_mask = *(unsigned long *)0xfeff9820;
+	*(unsigned long *)0xfeff9820 = 0xfffe0000;
+}
+
+/*
+ * Cleanup interrupt masks, etc after wakeup by power switch
+ */
+static void __default_power_switch_cleanup(void)
+{
+	*(unsigned long *)0xfeff9820 = __irq_mask;
+}
+
+/*
+ * Return non-zero if wakeup irq was caused by power switch
+ */
+static int __default_power_switch_check(void)
+{
+	return 1;
+}
+
+void (*__power_switch_wake_setup)(void) = __default_power_switch_setup;
+int  (*__power_switch_wake_check)(void) = __default_power_switch_check;
+void (*__power_switch_wake_cleanup)(void) = __default_power_switch_cleanup;
+
+int pm_do_bus_sleep(void)
+{
+	cli();
+
+	/*
+         * Here is where we need some platform-dependent setup
+	 * of the interrupt state so that appropriate wakeup
+	 * sources are allowed and all others are masked.
+	 */
+	__power_switch_wake_setup();
+
+	__set_LEDS(0xa1);
+
+	/* go zzz
+	 *
+	 * This is in a loop in case power switch shares an irq with other
+	 * devices. The wake_check() tells us if we need to finish waking
+	 * or go back to sleep.
+	 */
+	do {
+		frv_cpu_suspend(HSR0_PDM_BUS_SLEEP);
+	} while (__power_switch_wake_check && !__power_switch_wake_check());
+
+	__set_LEDS(0xa2);
+
+	/*
+         * Here is where we need some platform-dependent restore
+	 * of the interrupt state prior to being called.
+	 */
+	__power_switch_wake_cleanup();
+
+	sti();
+
+	return 0;
+}
+
+unsigned long sleep_phys_sp(void *sp)
+{
+	return virt_to_phys(sp);
+}
+
+#ifdef CONFIG_SYSCTL
+/*
+ * Use a temporary sysctl number. Horrid, but will be cleaned up in 2.6
+ * when all the PM interfaces exist nicely.
+ */
+#define CTL_PM 9899
+#define CTL_PM_SUSPEND 1
+#define CTL_PM_CMODE 2
+#define CTL_PM_P0 4
+#define CTL_PM_CM 5
+
+static int user_atoi(char *ubuf, int len)
+{
+	char buf[16];
+	unsigned long ret;
+
+	if (len > 15)
+		return -EINVAL;
+
+	if (copy_from_user(buf, ubuf, len))
+		return -EFAULT;
+
+	buf[len] = 0;
+	ret = simple_strtoul(buf, NULL, 0);
+	if (ret > INT_MAX)
+		return -ERANGE;
+	return ret;
+}
+
+/*
+ * Send us to sleep.
+ */
+static int sysctl_pm_do_suspend(ctl_table *ctl, int write, struct file *filp,
+				void *buffer, size_t *lenp)
+{
+	int retval, mode;
+
+	if (*lenp <= 0)
+		return -EIO;
+
+	mode = user_atoi(buffer, *lenp);
+	if ((mode != 1) && (mode != 5))
+		return -EINVAL;
+
+	retval = pm_send_all(PM_SUSPEND, (void *)3);
+
+	if (retval == 0) {
+		if (mode == 5)
+		    retval = pm_do_bus_sleep();
+		else
+		    retval = pm_do_suspend();
+		pm_send_all(PM_RESUME, (void *)0);
+	}
+
+	return retval;
+}
+
+ 
+static int try_set_cmode(int new_cmode)
+{
+	if (new_cmode > 15)
+		return -EINVAL;
+	if (!(clock_cmodes_permitted & (1<<new_cmode)))
+		return -EINVAL;
+
+	/* Tell all the drivers we're suspending... */
+	pm_send_all(PM_SUSPEND, (void *)3);
+
+	/* Now change cmode */
+	cli();
+	frv_dma_pause_all();
+
+	frv_change_cmode(new_cmode);
+
+	determine_clocks(0);
+	time_divisor_init();
+
+#ifdef DEBUG
+	determine_clocks(1);
+#endif
+	frv_dma_resume_all();
+	sti();
+
+	/* Tell all the drivers we're resuming... */
+	pm_send_all(PM_RESUME, (void *)0);
+	return 0;
+}
+
+
+static int cmode_procctl(ctl_table *ctl, int write, struct file *filp,
+			 void *buffer, size_t *lenp)
+{
+	int new_cmode;
+
+	if (!write)
+		return proc_dointvec(ctl, write, filp, buffer, lenp);
+
+	new_cmode = user_atoi(buffer, *lenp);
+
+	return try_set_cmode(new_cmode)?:*lenp;
+}
+
+static int cmode_sysctl(ctl_table *table, int *name, int nlen,
+			void *oldval, size_t *oldlenp,
+			void *newval, size_t newlen, void **context)
+{
+	if (oldval && oldlenp) {
+		size_t oldlen;
+
+		if (get_user(oldlen, oldlenp))
+			return -EFAULT;
+
+		if (oldlen != sizeof(int))
+			return -EINVAL;
+
+		if (put_user(clock_cmode_current, (unsigned int *)oldval) ||
+		    put_user(sizeof(int), oldlenp))
+			return -EFAULT;
+	}
+	if (newval && newlen) {
+		int new_cmode;
+
+		if (newlen != sizeof(int))
+			return -EINVAL;
+
+		if (get_user(new_cmode, (int *)newval))
+			return -EFAULT;
+
+		return try_set_cmode(new_cmode)?:1;
+	}
+	return 1;
+}
+
+static int try_set_p0(int new_p0)
+{
+	unsigned long flags, clkc;
+
+	if (new_p0 < 0 || new_p0 > 1)
+		return -EINVAL;
+
+	local_irq_save(flags);
+	__set_PSR(flags & ~PSR_ET);
+
+	frv_dma_pause_all();
+
+	clkc = __get_CLKC();
+	if (new_p0)
+		clkc |= CLKC_P0;
+	else
+		clkc &= ~CLKC_P0;
+	__set_CLKC(clkc);
+
+	determine_clocks(0);
+	time_divisor_init();
+
+#ifdef DEBUG
+	determine_clocks(1);
+#endif
+	frv_dma_resume_all();
+	local_irq_restore(flags);
+	return 0;
+}
+
+static int try_set_cm(int new_cm)
+{
+	unsigned long flags, clkc;
+
+	if (new_cm < 0 || new_cm > 1)
+		return -EINVAL;
+
+	local_irq_save(flags);
+	__set_PSR(flags & ~PSR_ET);
+
+	frv_dma_pause_all();
+
+	clkc = __get_CLKC();
+	clkc &= ~CLKC_CM;
+	clkc |= new_cm;
+	__set_CLKC(clkc);
+
+	determine_clocks(0);
+	time_divisor_init();
+
+#if 1 //def DEBUG
+	determine_clocks(1);
+#endif
+
+	frv_dma_resume_all();
+	local_irq_restore(flags);
+	return 0;
+}
+
+static int p0_procctl(ctl_table *ctl, int write, struct file *filp,
+		      void *buffer, size_t *lenp)
+{
+	int new_p0;
+
+	if (!write)
+		return proc_dointvec(ctl, write, filp, buffer, lenp);
+
+	new_p0 = user_atoi(buffer, *lenp);
+
+	return try_set_p0(new_p0)?:*lenp;
+}
+
+static int p0_sysctl(ctl_table *table, int *name, int nlen,
+		     void *oldval, size_t *oldlenp,
+		     void *newval, size_t newlen, void **context)
+{
+	if (oldval && oldlenp) {
+		size_t oldlen;
+
+		if (get_user(oldlen, oldlenp))
+			return -EFAULT;
+
+		if (oldlen != sizeof(int))
+			return -EINVAL;
+
+		if (put_user(clock_p0_current, (unsigned int *)oldval) ||
+		    put_user(sizeof(int), oldlenp))
+			return -EFAULT;
+	}
+	if (newval && newlen) {
+		int new_p0;
+
+		if (newlen != sizeof(int))
+			return -EINVAL;
+
+		if (get_user(new_p0, (int *)newval))
+			return -EFAULT;
+
+		return try_set_p0(new_p0)?:1;
+	}
+	return 1;
+}
+
+static int cm_procctl(ctl_table *ctl, int write, struct file *filp,
+		      void *buffer, size_t *lenp)
+{
+	int new_cm;
+
+	if (!write)
+		return proc_dointvec(ctl, write, filp, buffer, lenp);
+
+	new_cm = user_atoi(buffer, *lenp);
+
+	return try_set_cm(new_cm)?:*lenp;
+}
+
+static int cm_sysctl(ctl_table *table, int *name, int nlen,
+		     void *oldval, size_t *oldlenp,
+		     void *newval, size_t newlen, void **context)
+{
+	if (oldval && oldlenp) {
+		size_t oldlen;
+
+		if (get_user(oldlen, oldlenp))
+			return -EFAULT;
+
+		if (oldlen != sizeof(int))
+			return -EINVAL;
+
+		if (put_user(clock_cm_current, (unsigned int *)oldval) ||
+		    put_user(sizeof(int), oldlenp))
+			return -EFAULT;
+	}
+	if (newval && newlen) {
+		int new_cm;
+
+		if (newlen != sizeof(int))
+			return -EINVAL;
+
+		if (get_user(new_cm, (int *)newval))
+			return -EFAULT;
+
+		return try_set_cm(new_cm)?:1;
+	}
+	return 1;
+}
+
+
+static struct ctl_table pm_table[] =
+{
+	{CTL_PM_SUSPEND, "suspend", NULL, 0, 0200, NULL, &sysctl_pm_do_suspend},
+	{CTL_PM_CMODE, "cmode", &clock_cmode_current, sizeof(int), 0644, NULL, &cmode_procctl, &cmode_sysctl, NULL},
+	{CTL_PM_P0, "p0", &clock_p0_current, sizeof(int), 0644, NULL, &p0_procctl, &p0_sysctl, NULL},
+	{CTL_PM_CM, "cm", &clock_cm_current, sizeof(int), 0644, NULL, &cm_procctl, &cm_sysctl, NULL},
+	{0}
+};
+
+static struct ctl_table pm_dir_table[] =
+{
+	{CTL_PM, "pm", NULL, 0, 0555, pm_table},
+	{0}
+};
+
+/*
+ * Initialize power interface
+ */
+static int __init pm_init(void)
+{
+	register_sysctl_table(pm_dir_table, 1);
+	return 0;
+}
+
+__initcall(pm_init);
+
+#endif
diff -urN linux-2.4.29/arch/frv/kernel/pm-mb93093.c linux-2.4.29-uc1/arch/frv/kernel/pm-mb93093.c
--- linux-2.4.29/arch/frv/kernel/pm-mb93093.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/pm-mb93093.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,66 @@
+/*
+ * FR-V MB93093 Power Management Routines
+ *
+ * Copyright (c) 2004 Red Hat, Inc.
+ *
+ * Written by: msalter@redhat.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/sysctl.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+
+#include <asm/mb86943a.h>
+
+#include "local.h"
+
+static unsigned long imask;
+/*
+ * Setup interrupt masks, etc to enable wakeup by power switch
+ */
+static void mb93093_power_switch_setup(void)
+{
+	/* mask all but FPGA interrupt sources. */
+	imask = *(volatile unsigned long *)0xfeff9820;
+	*(volatile unsigned long *)0xfeff9820 = ~(1 << (IRQ_XIRQ2_LEVEL + 16)) & 0xfffe0000;
+}
+
+/*
+ * Cleanup interrupt masks, etc after wakeup by power switch
+ */
+static void mb93093_power_switch_cleanup(void)
+{
+	*(volatile unsigned long *)0xfeff9820 = imask;
+}
+
+/*
+ * Return non-zero if wakeup irq was caused by power switch
+ */
+static int mb93093_power_switch_check(void)
+{
+	return 1;
+}
+
+/*
+ * Initialize power interface
+ */
+static int __init mb93093_pm_init(void)
+{
+	__power_switch_wake_setup = mb93093_power_switch_setup;
+	__power_switch_wake_check = mb93093_power_switch_check;
+	__power_switch_wake_cleanup = mb93093_power_switch_cleanup;
+	return 0;
+}
+
+__initcall(mb93093_pm_init);
+
diff -urN linux-2.4.29/arch/frv/kernel/process.c linux-2.4.29-uc1/arch/frv/kernel/process.c
--- linux-2.4.29/arch/frv/kernel/process.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/process.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,435 @@
+/*
+ *  linux/arch/m68k/kernel/process.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ *
+ *  68060 fixes by Jesper Skov
+ *
+ *  uClinux changes Copyright (C) 2000-2002, David McCullough <davidm@snapgear.com>
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/elf.h>
+#include <linux/reboot.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+#include <asm/gdb-stub.h>
+#include <asm/mb-regs.h>
+
+#include "local.h"
+
+/*
+ * Initial task structure. Make this a per-architecture thing,
+ * because different architectures tend to have different
+ * alignment requirements and potentially different initial
+ * setup.
+ */
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS;
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+union task_union init_task_union
+__attribute__((section(".data.init_task"), aligned(THREAD_SIZE))) = {
+	.task	= INIT_TASK(init_task_union.task),
+};
+
+asmlinkage void ret_from_fork(void);
+
+/*
+ * The idle loop
+ */
+static void __attribute__((unused)) default_idle(void)
+{
+	while (1) {
+		schedule();
+#ifndef NO_MM
+		check_pgt_cache();
+#endif
+	}
+}
+
+#include <asm/pgalloc.h>
+
+struct task_struct *alloc_task_struct(void)
+{
+	struct task_struct *p = kmalloc(THREAD_SIZE, GFP_KERNEL);
+	if (p)
+		atomic_set((atomic_t *) (p + 1), 1);
+	return p;
+}
+
+void free_task_struct(struct task_struct *p)
+{
+	if (atomic_dec_and_test((atomic_t *) (p + 1)))
+		kfree(p);
+}
+
+void get_task_struct(struct task_struct *p)
+{
+	atomic_inc((atomic_t *) (p + 1));
+}
+
+static void core_sleep_idle(void)
+{
+	while (1) {
+	  	if (frv_dma_inprogress) {
+		  	/* If we put the core to sleep, DMA will be suspended */
+		  	schedule();
+#ifndef NO_MM
+			check_pgt_cache();
+#endif
+		} else {
+		  	cli();
+			if (need_resched()) {
+			  	sti();
+			} else {
+#ifdef LED_DEBUG_SLEEP
+				/* Show that we're sleeping... */
+				__set_LEDS(0x55aa);
+#endif
+				frv_cpu_core_sleep();
+#ifdef LED_DEBUG_SLEEP
+				/* ... and that we woke up */
+				__set_LEDS(0);
+#endif
+				mb();
+			}
+
+			schedule();
+
+#ifndef NO_MM
+			check_pgt_cache();
+#endif
+		}
+	}
+}
+
+
+
+void (*idle)(void) = core_sleep_idle;
+//void (*idle)(void) = default_idle;
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle(void)
+{
+	/* endless idle loop with no priority at all */
+	idle();
+}
+
+void machine_restart(char * __unused)
+{
+	unsigned long reset_addr;
+#ifdef CONFIG_GDBSTUB
+	gdbstub_exit(0);
+#endif
+
+	if (PSR_IMPLE(__get_PSR()) == PSR_IMPLE_FR551)
+		reset_addr = 0xfefff500;
+	else
+		reset_addr = 0xfeff0500;
+	
+	/* Software reset. */
+	asm volatile("      dcef @(gr0,gr0),1 ! membar !"
+		     "      sti     %1,@(%0,0) !"
+		     "      nop ! nop ! nop ! nop ! nop ! "
+		     "      nop ! nop ! nop ! nop ! nop ! "
+		     "      nop ! nop ! nop ! nop ! nop ! "
+		     "      nop ! nop ! nop ! nop ! nop ! "
+		     : : "r" (reset_addr), "r" (1) );
+
+	for (;;)
+		;
+}
+
+void machine_halt(void)
+{
+#ifdef CONFIG_GDBSTUB
+	gdbstub_exit(0);
+#endif
+
+	for (;;);
+}
+
+void machine_power_off(void)
+{
+#ifdef CONFIG_GDBSTUB
+	gdbstub_exit(0);
+#endif
+
+	for (;;);
+}
+
+void flush_thread(void)
+{
+#if 0 //ndef NO_FPU
+	unsigned long zero = 0;
+#endif
+	set_fs(USER_DS);
+}
+
+inline unsigned long user_stack(const struct pt_regs *regs)
+{
+	while (regs->next_frame)
+		regs = regs->next_frame;
+	return user_mode(regs) ? regs->sp : 0;
+}
+
+asmlinkage int sys_fork(void)
+{
+#ifdef NO_MM
+	/* fork almost works, enough to trick you into looking elsewhere:-( */
+	return -EINVAL;
+#else
+	return do_fork(SIGCHLD, user_stack(__frame), __frame, 0);
+#endif
+}
+
+asmlinkage int sys_vfork(void)
+{
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, user_stack(__frame), __frame, 0);
+}
+
+/*****************************************************************************/
+/*
+ * clone a process
+ * - child_tls (in GR12) is accessed directly by copy_thread()
+ */
+asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
+			 int __user *parent_tidp, int __user *child_tidp,
+			 void __user *child_tls)
+{
+#if 0 //def CONFIG_UCLINUX
+	/* uClinux can't or doesn't support all of the CLONE_* options */
+	if (clone_flags & (CLONE_SYSVSEM | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID |
+			   CLONE_DETACHED | CLONE_UNTRACED | CLONE_CHILD_SETTID | CLONE_STOPPED))
+		return -EINVAL;
+#endif
+
+	if (!newsp)
+		newsp = user_stack(__frame);
+
+	return do_fork(clone_flags, newsp, __frame, 0);
+}
+
+/*****************************************************************************/
+/*
+ * set up the kernel stack and exception frames for a new process
+ */
+int copy_thread(int nr, unsigned long clone_flags,
+		unsigned long usp, unsigned long topstk,
+		struct task_struct *p, struct pt_regs *regs)
+{
+	struct pt_regs *childregs0, *childregs, *regs0;
+
+	regs0 = __kernel_frame0_ptr;
+	childregs0 = (struct pt_regs *) ((unsigned long) p + THREAD_SIZE - USER_CONTEXT_SIZE);
+	childregs = childregs0;
+
+	/* set up the userspace frame (the only place that the USP is stored) */
+	*childregs0 = *regs0;
+
+	childregs0->gr8		= 0;
+	childregs0->sp		= usp;
+	childregs0->next_frame	= NULL;
+
+#if 0
+	if (clone_flags & CLONE_SETTLS)
+		/* access sys_clone()'s child_tls argument directly */
+		childregs0->gr29 = regs->gr12;
+#endif
+
+	/* set up the return kernel frame if called from kernel_thread() */
+	if (regs != regs0) {
+		childregs--;
+		*childregs = *regs;
+		childregs->sp = (unsigned long) childregs0;
+		childregs->next_frame = childregs0;
+		childregs->gr29 = (unsigned long) p;
+	}
+
+	p->thread.frame	 = childregs;
+	p->thread.curr	 = p;
+	p->thread.sp	 = (unsigned long) childregs;
+	p->thread.fp	 = 0;
+	p->thread.lr	 = 0;
+	p->thread.pc	 = (unsigned long) ret_from_fork;
+	p->thread.frame0 = childregs0;
+
+	save_user_regs(p->thread.user);
+
+	return 0;
+} /* end copy_thread() */
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs *regs, struct user *dump)
+{
+	/* changed the size calculations - should hopefully work better. lbt */
+	dump->magic = CMAGIC;
+	dump->start_code = 0;
+	dump->start_stack = user_stack(regs) & ~(PAGE_SIZE - 1);
+	dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
+	dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
+	dump->u_dsize -= dump->u_tsize;
+	dump->u_ssize = 0;
+
+	if (dump->start_stack < TASK_SIZE)
+		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
+
+	dump->regs = *(struct user_context *) regs;
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage int sys_execve(char *name, char **argv, char **envp)
+{
+	int error;
+	char * filename;
+
+	lock_kernel();
+	filename = getname(name);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+	error = do_execve(filename, argv, envp, __frame);
+	putname(filename);
+ out:
+	unlock_kernel();
+	return error;
+}
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+#define first_sched	((unsigned long) scheduling_functions_start_here)
+#define last_sched	((unsigned long) scheduling_functions_end_here)
+
+unsigned long get_wchan(struct task_struct *p)
+{
+	struct pt_regs *regs0;
+	unsigned long fp, pc;
+	unsigned long stack_limit;
+	int count = 0;
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	stack_limit = (unsigned long) (p + 1);
+	fp = p->thread.fp;
+	regs0 = p->thread.frame0;
+
+	do {
+		if (fp < stack_limit || fp >= (unsigned long) regs0 || fp & 3)
+			return 0;
+
+		pc = ((unsigned long *) fp)[2];
+
+		/* FIXME: This depends on the order of these functions. */
+		if (pc < first_sched || pc >= last_sched)
+			return pc;
+
+		fp = *(unsigned long *) fp;
+	} while (count++ < 16);
+
+	return 0;
+}
+
+int elf_check_arch(const struct elf32_hdr *hdr)
+{
+	unsigned long hsr0 = __get_HSR(0);
+	unsigned long psr = __get_PSR();
+
+	if (hdr->e_machine != EM_FRV)
+		return 0;
+
+	switch (hdr->e_flags & EF_FRV_GPR_MASK) {
+	case EF_FRV_GPR64:
+		if ((hsr0 & HSR0_GRN) == HSR0_GRN_32)
+			return 0;
+	case EF_FRV_GPR32:
+	case 0:
+		break;
+	default:
+		return 0;
+	}
+
+	switch (hdr->e_flags & EF_FRV_FPR_MASK) {
+	case EF_FRV_FPR64:
+		if ((hsr0 & HSR0_FRN) == HSR0_FRN_32)
+			return 0;
+	case EF_FRV_FPR32:
+	case EF_FRV_FPR_NONE:
+	case 0:
+		break;
+	default:
+		return 0;
+	}
+
+	if ((hdr->e_flags & EF_FRV_MULADD) == EF_FRV_MULADD)
+		if (PSR_IMPLE(psr) != PSR_IMPLE_FR405 &&
+		    PSR_IMPLE(psr) != PSR_IMPLE_FR451)
+			return 0;
+
+	switch (hdr->e_flags & EF_FRV_CPU_MASK) {
+	case EF_FRV_CPU_GENERIC:
+		break;
+	case EF_FRV_CPU_FR300:
+	case EF_FRV_CPU_SIMPLE:
+	case EF_FRV_CPU_TOMCAT:
+	default:
+		return 0;
+	case EF_FRV_CPU_FR400:
+		if (PSR_IMPLE(psr) != PSR_IMPLE_FR401 &&
+		    PSR_IMPLE(psr) != PSR_IMPLE_FR405 &&
+		    PSR_IMPLE(psr) != PSR_IMPLE_FR451 &&
+		    PSR_IMPLE(psr) != PSR_IMPLE_FR551)
+			return 0;
+		break;
+	case EF_FRV_CPU_FR405:
+		if (PSR_IMPLE(psr) != PSR_IMPLE_FR405 &&
+		    PSR_IMPLE(psr) != PSR_IMPLE_FR451)
+			return 0;
+		break;
+	case EF_FRV_CPU_FR450:
+		if (PSR_IMPLE(psr) != PSR_IMPLE_FR451)
+			return 0;
+		break;
+	case EF_FRV_CPU_FR500:
+		if (PSR_IMPLE(psr) != PSR_IMPLE_FR501)
+			return 0;
+		break;
+	case EF_FRV_CPU_FR550:
+		if (PSR_IMPLE(psr) != PSR_IMPLE_FR551)
+			return 0;
+		break;
+	}
+
+	return 1;
+}
diff -urN linux-2.4.29/arch/frv/kernel/ptrace.c linux-2.4.29-uc1/arch/frv/kernel/ptrace.c
--- linux-2.4.29/arch/frv/kernel/ptrace.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/ptrace.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,421 @@
+/*
+ *  linux/arch/m68k/kernel/ptrace.c
+ *
+ *  Copyright (C) 1994 by Hamish Macdonald
+ *  Taken from linux/kernel/ptrace.c and modified for M680x0.
+ *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/config.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/unistd.h>
+
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/* determines which bits in the SR the user has access to. */
+/* 1 = access 0 = no access */
+#define SR_MASK 0x001f
+
+/* sets the trace bits. */
+#define TRACE_BITS 0x8000
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+static inline long get_reg(struct task_struct *task, int regno)
+{
+	struct user_context *user = task->thread.user;
+
+	if (regno < 0 || regno >= PT__END)
+		return 0;
+
+	return ((unsigned long *) user)[regno];
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static inline int put_reg(struct task_struct *task, int regno,
+			  unsigned long data)
+{
+	struct user_context *user = task->thread.user;
+
+	if (regno < 0 || regno >= PT__END)
+		return -EIO;
+
+	switch (regno) {
+	case PT_GR(0):
+		return 0;
+	case PT_PSR:
+	case PT__STATUS:
+		return -EIO;
+	default:
+		((unsigned long *) user)[regno] = data;
+		return 0;
+	}
+}
+
+/*
+ * check that an address falls within the bounds of the target process's memory mappings
+ */
+static inline int is_user_addr_valid(struct task_struct *child,
+				     unsigned long start, unsigned long len)
+{
+#ifndef CONFIG_UCLINUX
+	if (start >= PAGE_OFFSET || len > PAGE_OFFSET - start)
+		return -EIO;
+	return 0;
+#else
+	struct vm_list_struct *vml;
+
+	for (vml = child->mm->vmlist; vml; vml = vml->next)
+		if (start >= vml->vma->vm_start && start + len <= vml->vma->vm_end)
+			return 0;
+
+	return -EIO;
+#endif
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Control h/w single stepping
+ */
+void ptrace_disable(struct task_struct *child)
+{
+	child->thread.frame0->__status &= ~REG__STATUS_STEP;
+}
+
+void ptrace_enable(struct task_struct *child)
+{
+	child->thread.frame0->__status |= REG__STATUS_STEP;
+}
+
+asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	unsigned long tmp;
+	int ret;
+
+	lock_kernel();
+	ret = -EPERM;
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED)
+			goto out;
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		ret = 0;
+		goto out;
+	}
+	ret = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		goto out;
+
+	ret = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out_tsk;
+
+	if (request == PTRACE_ATTACH) {
+		ret = ptrace_attach(child);
+		goto out_tsk;
+	}
+
+	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+	if (ret < 0)
+		goto out_tsk;
+
+	switch (request) {
+		/* when I and D space are separate, these will need to be fixed. */
+	case PTRACE_PEEKTEXT: /* read word at location addr. */
+	case PTRACE_PEEKDATA: {
+		int copied;
+
+		ret = -EIO;
+		if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0)
+			break;
+
+		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+		if (copied != sizeof(tmp))
+			break;
+
+		ret = put_user(tmp,(unsigned long *) data);
+		break;
+	}
+
+		/* read the word at location addr in the USER area. */
+	case PTRACE_PEEKUSR: {
+		tmp = 0;
+		ret = -EIO;
+		if ((addr & 3) || addr < 0)
+			break;
+
+		ret = 0;
+		switch (addr >> 2) {
+		case 0 ... PT__END - 1:
+			tmp = get_reg(child, addr >> 2);
+			break;
+
+		case PT__END + 0:
+			tmp = child->mm->end_code - child->mm->start_code;
+			break;
+
+		case PT__END + 1:
+			tmp = child->mm->end_data - child->mm->start_data;
+			break;
+
+		case PT__END + 2:
+			tmp = child->mm->start_stack - child->mm->start_brk;
+			break;
+
+		case PT__END + 3:
+			tmp = child->mm->start_code;
+			break;
+
+		case PT__END + 4:
+			tmp = child->mm->start_stack;
+			break;
+
+		default:
+			ret = -EIO;
+			break;
+		}
+
+		if (ret == 0)
+			ret = put_user(tmp, (unsigned long *) data);
+		break;
+	}
+
+		/* when I and D space are separate, this will have to be fixed. */
+	case PTRACE_POKETEXT: /* write the word at location addr. */
+	case PTRACE_POKEDATA:
+		ret = -EIO;
+		if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0)
+			break;
+		if (access_process_vm(child, addr, &data, sizeof(data), 1) != sizeof(data))
+			break;
+		ret = 0;
+		break;
+
+	case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+		ret = -EIO;
+		if ((addr & 3) || addr < 0)
+			break;
+
+		ret = 0;
+		switch (addr >> 2) {
+		case 0 ... PT__END-1:
+			ret = put_reg(child, addr >> 2, data);
+			break;
+
+		default:
+			ret = -EIO;
+			break;
+		}
+		break;
+
+	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+	case PTRACE_CONT: /* restart after signal. */
+		ret = -EIO;
+		if ((unsigned long) data > _NSIG)
+			break;
+		if (request == PTRACE_SYSCALL)
+			child->ptrace |= PT_TRACESYS;
+		else
+			child->ptrace &= ~PT_TRACESYS;
+		child->exit_code = data;
+		ptrace_disable(child);
+		wake_up_process(child);
+		ret = 0;
+		break;
+
+		/* make the child exit.  Best I can do is send it a sigkill.
+		 * perhaps it should be put in the status that it wants to
+		 * exit.
+		 */
+	case PTRACE_KILL:
+		ret = 0;
+		if (child->state == TASK_ZOMBIE) /* already dead */
+			break;
+		child->exit_code = SIGKILL;
+		ptrace_disable(child);
+		wake_up_process(child);
+		break;
+
+	case PTRACE_SINGLESTEP:  /* set the trap flag. */
+		ret = -EIO;
+		if ((unsigned long) data > _NSIG)
+			break;
+		child->ptrace &= ~PT_TRACESYS;
+		ptrace_enable(child);
+		child->exit_code = data;
+		wake_up_process(child);
+		ret = 0;
+		break;
+
+	case PTRACE_DETACH:	/* detach a process that was attached. */
+		ret = ptrace_detach(child, data);
+		break;
+
+	case PTRACE_GETREGS: { /* Get all integer regs from the child. */
+		int i;
+		for (i = 0; i < PT__GPEND; i++) {
+			tmp = get_reg(child, i);
+			if (put_user(tmp, (unsigned long *) data)) {
+				ret = -EFAULT;
+				break;
+			}
+			data += sizeof(long);
+		}
+		ret = 0;
+		break;
+	}
+
+	case PTRACE_SETREGS: { /* Set all integer regs in the child. */
+		int i;
+		for (i = 0; i < PT__GPEND; i++) {
+			if (get_user(tmp, (unsigned long *) data)) {
+				ret = -EFAULT;
+				break;
+			}
+			put_reg(child, i, tmp);
+			data += sizeof(long);
+		}
+		ret = 0;
+		break;
+	}
+
+	case PTRACE_GETFPREGS: { /* Get the child FP/Media state. */
+		ret = 0;
+		if (copy_to_user((void *) data,
+				 &child->thread.user->f,
+				 sizeof(child->thread.user->f)))
+			ret = -EFAULT;
+		break;
+	}
+
+	case PTRACE_SETFPREGS: { /* Set the child FP/Media state. */
+		ret = 0;
+		if (copy_from_user(&child->thread.user->f,
+				   (void *) data,
+				   sizeof(child->thread.user->f)))
+			ret = -EFAULT;
+		break;
+	}
+
+	case PTRACE_GETFDPIC:
+		tmp = 0;
+		switch (addr) {
+		case PTRACE_GETFDPIC_EXEC:
+			tmp = child->mm->exec_fdpic_loadmap;
+			break;
+		case PTRACE_GETFDPIC_INTERP:
+			tmp = child->mm->interp_fdpic_loadmap;
+			break;
+		default:
+			break;
+		}
+
+		ret = 0;
+		if (put_user(tmp, (unsigned long *) data)) {
+			ret = -EFAULT;
+			break;
+		}
+		break;
+
+	default:
+		ret = -EIO;
+		break;
+	}
+out_tsk:
+	free_task_struct(child);
+out:
+	unlock_kernel();
+	return ret;
+}
+
+asmlinkage void syscall_trace(int leaving)
+{
+#if 0
+	if (!current->mm)
+		return;
+
+	if (__frame->gr7 == __NR_close)
+		return;
+
+#if 0
+	if (__frame->gr7 != __NR_mmap2 &&
+	    __frame->gr7 != __NR_vfork &&
+	    __frame->gr7 != __NR_execve &&
+	    __frame->gr7 != __NR_exit)
+		return;
+#endif
+
+	if (!leaving) {
+		printk(KERN_CRIT "[%d] syscall_%lu(%lx,%lx,%lx,%lx,%lx,%lx)\n",
+		       current->pid,
+		       __frame->gr7,
+		       __frame->gr8,
+		       __frame->gr9,
+		       __frame->gr10,
+		       __frame->gr11,
+		       __frame->gr12,
+		       __frame->gr13);
+	}
+	else {
+		if ((int)__frame->gr8 > -4096 && (int)__frame->gr8 < 4096)
+			printk(KERN_CRIT "[%d] sys() = %ld\n", current->pid, __frame->gr8);
+		else
+			printk(KERN_CRIT "[%d] sys() = %lx\n", current->pid, __frame->gr8);
+	}
+	return;
+#endif
+
+	/* we need to indicate entry or exit to strace */
+	if (leaving)
+		__frame->__status |= REG__STATUS_SYSC_EXIT;
+	else
+		__frame->__status |= REG__STATUS_SYSC_ENTRY;
+
+	if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
+			!= (PT_PTRACED|PT_TRACESYS))
+		return;
+	current->exit_code = SIGTRAP;
+	current->state = TASK_STOPPED;
+	notify_parent(current, SIGCHLD);
+	schedule();
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+}
diff -urN linux-2.4.29/arch/frv/kernel/semaphore.c linux-2.4.29-uc1/arch/frv/kernel/semaphore.c
--- linux-2.4.29/arch/frv/kernel/semaphore.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/semaphore.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,157 @@
+/* semaphore.c: FR-V semaphores
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from lib/rwsem-spinlock.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <asm/semaphore.h>
+
+struct sem_waiter {
+	struct list_head	list;
+	struct task_struct	*task;
+};
+
+#if SEM_DEBUG
+void semtrace(struct semaphore *sem, const char *str)
+{
+	if (sem->debug)
+		printk("[%d] %s({%d,%d})\n",
+		       current->pid,
+		       str,
+		       sem->counter,
+		       list_empty(&sem->wait_list) ? 0 : 1);
+}
+#else
+#define semtrace(SEM,STR) do { } while(0)
+#endif
+
+/*
+ * wait for a token to be granted from a semaphore
+ * - entered with lock held and interrupts disabled
+ */
+void __down(struct semaphore *sem, unsigned long flags)
+{
+	struct task_struct *tsk = current;
+	struct sem_waiter waiter;
+
+	semtrace(sem, "Entering __down");
+
+	/* set up my own style of waitqueue */
+	waiter.task = tsk;
+	get_task_struct(tsk);
+
+	list_add_tail(&waiter.list, &sem->wait_list);
+
+	/* we don't need to touch the semaphore struct anymore */
+	spin_unlock_irqrestore(&sem->wait_lock, flags);
+
+	/* wait to be given the semaphore */
+	set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+
+	for (;;) {
+		if (list_empty(&waiter.list))
+			break;
+		schedule();
+		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+	}
+
+	tsk->state = TASK_RUNNING;
+	semtrace(sem, "Leaving __down");
+}
+
+EXPORT_SYMBOL(__down);
+
+/*
+ * interruptibly wait for a token to be granted from a semaphore
+ * - entered with lock held and interrupts disabled
+ */
+int __down_interruptible(struct semaphore *sem, unsigned long flags)
+{
+	struct task_struct *tsk = current;
+	struct sem_waiter waiter;
+	int ret;
+
+	semtrace(sem,"Entering __down_interruptible");
+
+	/* set up my own style of waitqueue */
+	waiter.task = tsk;
+	get_task_struct(tsk);
+
+	list_add_tail(&waiter.list, &sem->wait_list);
+
+	/* we don't need to touch the semaphore struct anymore */
+	set_task_state(tsk, TASK_INTERRUPTIBLE);
+
+	spin_unlock_irqrestore(&sem->wait_lock, flags);
+
+	/* wait to be given the semaphore */
+	ret = 0;
+	for (;;) {
+		if (list_empty(&waiter.list))
+			break;
+		if (unlikely(signal_pending(current)))
+			goto interrupted;
+		schedule();
+		set_task_state(tsk, TASK_INTERRUPTIBLE);
+	}
+
+ out:
+	tsk->state = TASK_RUNNING;
+	semtrace(sem, "Leaving __down_interruptible");
+	return ret;
+
+ interrupted:
+	spin_lock_irqsave(&sem->wait_lock, flags);
+
+	if (!list_empty(&waiter.list)) {
+		list_del(&waiter.list);
+		ret = -EINTR;
+	}
+
+	spin_unlock_irqrestore(&sem->wait_lock, flags);
+	if (ret == -EINTR)
+		free_task_struct(current);
+	goto out;
+}
+
+EXPORT_SYMBOL(__down_interruptible);
+
+/*
+ * release a single token back to a semaphore
+ * - entered with lock held and interrupts disabled
+ */
+void __up(struct semaphore *sem)
+{
+	struct task_struct *tsk;
+	struct sem_waiter *waiter;
+
+	semtrace(sem,"Entering __up");
+
+	/* grant the token to the process at the front of the queue */
+	waiter = list_entry(sem->wait_list.next, struct sem_waiter, list);
+
+	/* We must be careful not to touch 'waiter' after we set ->task = NULL.
+	 * It is an allocated on the waiter's stack and may become invalid at
+	 * any time after that point (due to a wakeup from another source).
+	 */
+	list_del_init(&waiter->list);
+	tsk = waiter->task;
+	mb();
+	waiter->task = NULL;
+	wake_up_process(tsk);
+	free_task_struct(tsk);
+
+	semtrace(sem,"Leaving __up");
+}
+
+EXPORT_SYMBOL(__up);
diff -urN linux-2.4.29/arch/frv/kernel/setup.c linux-2.4.29-uc1/arch/frv/kernel/setup.c
--- linux-2.4.29/arch/frv/kernel/setup.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/setup.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,1161 @@
+/*
+ *  linux/arch/frvnommu/kernel/setup.c
+ *
+ *  Copyleft  ()) 2000       James D. Schettine {james@telos-systems.com}
+ *  Copyright (C) 1999-2003  Greg Ungerer (gerg@snapgear.com)
+ *  Copyright (C) 1998,1999  D. Jeff Dionne <jeff@lineo.ca>
+ *  Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ *  Copyright (C) 1995       Hamish Macdonald
+ *  Copyright (C) 2000       Lineo Inc. (www.lineo.com)
+ *  Copyright (C) 2001 	     Lineo, Inc. <www.lineo.com>
+ *  Copyright (C) 2003 	     David Howells <dhowells@redhat.com>, Red Hat, Inc.
+ */
+
+/*
+ * This file handles the architecture-dependent parts of system setup
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/genhd.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/major.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/seq_file.h>
+#include <linux/serial_reg.h>
+#include <linux/serial.h>
+
+#include <asm/setup.h>
+#include <asm/serial.h>
+#include <asm/irq.h>
+#include <asm/vmlinux.h>
+#include <asm/pgalloc.h>
+#include <asm/busctl-regs.h>
+#include <asm/serial-regs.h>
+#include <asm/timer-regs.h>
+#include <asm/irc-regs.h>
+#include <asm/spr-regs.h>
+#include <asm/mb-regs.h>
+#include <asm/mb93493-regs.h>
+#include <asm/gdb-stub.h>
+#include <asm/irq-routing.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <linux/blk.h>
+#include <asm/pgtable.h>
+#endif
+
+#include "local.h"
+
+#ifdef CONFIG_MB93090_MB00
+static void __init mb93090_display(void);
+#endif
+#ifndef CONFIG_UCLINUX
+static void __init setup_linux_memory(void);
+#else
+static void __init setup_uclinux_memory(void);
+#endif
+
+#ifdef CONFIG_CONSOLE
+extern struct consw *conswitchp;
+#ifdef CONFIG_FRAMEBUFFER
+extern struct consw fb_con;
+#endif
+#endif
+
+#ifdef CONFIG_MB93090_MB00
+static char __initdata mb93090_banner[] = "FJ/RH FR-V Linux";
+static char __initdata mb93090_version[] = UTS_RELEASE;
+
+int __nongprelbss mb93090_mb00_detected;
+#endif
+
+const char __frv_unknown_system[] = "unknown";
+const char __frv_mb93091_cb10[] = "mb93091-cb10";
+const char __frv_mb93091_cb11[] = "mb93091-cb11";
+const char __frv_mb93091_cb30[] = "mb93091-cb30";
+const char __frv_mb93091_cb41[] = "mb93091-cb41";
+const char __frv_mb93091_cb60[] = "mb93091-cb60";
+const char __frv_mb93091_cb70[] = "mb93091-cb70";
+const char __frv_mb93091_cb451[] = "mb93091-cb451";
+const char __frv_mb93090_mb00[] = "mb93090-mb00";
+
+const char __frv_mb93493[] = "mb93493";
+
+const char __frv_mb93093[] = "mb93093";
+
+static const char *__nongprelbss cpu_series;
+static const char *__nongprelbss cpu_core;
+static const char *__nongprelbss cpu_silicon;
+static const char *__nongprelbss cpu_mmu;
+static const char *__nongprelbss cpu_system;
+static const char *__nongprelbss cpu_board1;
+static const char *__nongprelbss cpu_board2;
+
+static unsigned long __nongprelbss cpu_psr_all;
+static unsigned long __nongprelbss cpu_hsr0_all;
+
+unsigned long __nongprelbss pdm_suspend_mode;
+
+unsigned long __nongprelbss rom_length;
+unsigned long __nongprelbss memory_start;
+unsigned long __nongprelbss memory_end;
+
+unsigned long __nongprelbss dma_consistent_mem_start;
+unsigned long __nongprelbss dma_consistent_mem_end;
+
+unsigned long __initdata __sdram_old_base;
+
+struct cpuinfo_frv __nongprelbss boot_cpu_data;
+
+char command_line[512];
+char saved_command_line[512] = "console=ttyS0,115200 root=/dev/mtdblock3 ro";
+
+#ifdef CONFIG_PM
+#define __pminit
+#define __pminitdata
+#else
+#define __pminit __init
+#define __pminitdata __initdata
+#endif
+
+struct clock_cmode {
+	uint8_t	xbus, sdram, corebus, core, dsu;
+};
+
+#define _frac(N,D) ((N)<<4 | (D))
+#define _x0_16	_frac(1,6)
+#define _x0_25	_frac(1,4)
+#define _x0_33	_frac(1,3)
+#define _x0_375	_frac(3,8)
+#define _x0_5	_frac(1,2)
+#define _x0_66	_frac(2,3)
+#define _x0_75	_frac(3,4)
+#define _x1	_frac(1,1)
+#define _x1_5	_frac(3,2)
+#define _x2	_frac(2,1)
+#define _x3	_frac(3,1)
+#define _x4	_frac(4,1)
+#define _x4_5	_frac(9,2)
+#define _x6	_frac(6,1)
+#define _x8	_frac(8,1)
+#define _x9	_frac(9,1)
+
+int __nongprelbss clock_p0_current;
+int __nongprelbss clock_cm_current;
+int __nongprelbss clock_cmode_current;
+#ifdef CONFIG_PM
+int __nongprelbss clock_cmodes_permitted;
+unsigned long __nongprelbss clock_bits_settable;
+#endif
+
+static struct clock_cmode __pminitdata undef_clock_cmode = { _x1, _x1, _x1, _x1, _x1 };
+
+static struct clock_cmode __pminitdata clock_cmodes_fr401_fr403[16] = {
+	[4]	= {	_x1,	_x1,	_x2,	_x2,	_x0_25	},
+	[5]	= { 	_x1,	_x2,	_x4,	_x4,	_x0_5	},
+	[8]	= { 	_x1,	_x1,	_x1,	_x2,	_x0_25	},
+	[9]	= { 	_x1,	_x2,	_x2,	_x4,	_x0_5	},
+	[11]	= { 	_x1,	_x4,	_x4,	_x8,	_x1	},
+	[12]	= { 	_x1,	_x1,	_x2,	_x4,	_x0_5	},
+	[13]	= { 	_x1,	_x2,	_x4,	_x8,	_x1	},
+};
+
+static struct clock_cmode __pminitdata clock_cmodes_fr405[16] = {
+	[0]	= {	_x1,	_x1,	_x1,	_x1,	_x0_5	},
+	[1]	= {	_x1,	_x1,	_x1,	_x3,	_x0_25	},
+	[2]	= {	_x1,	_x1,	_x2,	_x6,	_x0_5	},
+	[3]	= {	_x1,	_x2,	_x2,	_x6,	_x0_5	},
+	[4]	= {	_x1,	_x1,	_x2,	_x2,	_x0_16	},
+	[8]	= { 	_x1,	_x1,	_x1,	_x2,	_x0_16	},
+	[9]	= { 	_x1,	_x2,	_x2,	_x4,	_x0_33	},
+	[12]	= { 	_x1,	_x1,	_x2,	_x4,	_x0_33	},
+	[14]	= { 	_x1,	_x3,	_x3,	_x9,	_x0_75	},
+	[15]	= { 	_x1,	_x1_5,	_x1_5,	_x4_5,	_x0_375	},
+
+#define CLOCK_CMODES_PERMITTED_FR405 0xd31f
+};
+
+static struct clock_cmode __pminitdata clock_cmodes_fr555[16] = {
+	[0]	= {	_x1,	_x2,	_x2,	_x4,	_x0_33	},
+	[1]	= {	_x1,	_x3,	_x3,	_x6,	_x0_5	},
+	[2]	= {	_x1,	_x2,	_x4,	_x8,	_x0_66	},
+	[3]	= {	_x1,	_x1_5,	_x3,	_x6,	_x0_5	},
+	[4]	= {	_x1,	_x3,	_x3,	_x9,	_x0_75	},
+	[5]	= {	_x1,	_x2,	_x2,	_x6,	_x0_5	},
+	[6]	= {	_x1,	_x1_5,	_x1_5,	_x4_5,	_x0_375	},
+};
+
+static const struct clock_cmode __pminitdata *clock_cmodes;
+static int __pminitdata clock_doubled;
+
+static struct serial_struct __frv_uart0 = {
+	.baud_base		= 0,
+	.io_type		= SERIAL_IO_MEMHI,
+	.iomem_base		= (u8 *) UART0_BASE,
+	.iomem_reg_shift	= 3,
+	.irq			= IRQ_CPU_UART0,
+	.flags			= STD_COM_FLAGS,
+};
+
+static struct serial_struct __frv_uart1 = {
+	.baud_base		= 0,
+	.io_type		= SERIAL_IO_MEMHI,
+	.iomem_base		= (u8 *) UART1_BASE,
+	.iomem_reg_shift	= 3,
+	.irq			= IRQ_CPU_UART1,
+	.flags			= STD_COM_FLAGS,
+};
+
+#if 0
+static void __init printk_xampr(unsigned long ampr, unsigned long amlr, char i_d, int n)
+{
+	unsigned long phys, virt, cxn, size;
+
+#ifndef CONFIG_UCLINUX
+	virt = amlr & 0xffffc000;
+	cxn = amlr & 0x3fff;
+#else
+	virt = ampr & 0xffffc000;
+	cxn = 0;
+#endif
+	phys = ampr & xAMPRx_PPFN;
+	size = 1 << (((ampr & xAMPRx_SS) >> 4) + 17);
+
+	printk("%cAMPR%d: va %08lx-%08lx [pa %08lx] %c%c%c%c [cxn:%04lx]\n",
+	       i_d, n,
+	       virt, virt + size - 1,
+	       phys,
+	       ampr & xAMPRx_S  ? 'S' : '-',
+	       ampr & xAMPRx_C  ? 'C' : '-',
+	       ampr & DAMPRx_WP ? 'W' : '-',
+	       ampr & xAMPRx_V  ? 'V' : '-',
+	       cxn
+	       );
+}
+#endif
+
+/*****************************************************************************/
+/*
+ * dump the memory map
+ */
+static void __init dump_memory_map(void)
+{
+
+#if 0
+	/* dump the protection map */
+	printk_xampr(__get_IAMPR(0),  __get_IAMLR(0),  'I', 0);
+	printk_xampr(__get_IAMPR(1),  __get_IAMLR(1),  'I', 1);
+	printk_xampr(__get_IAMPR(2),  __get_IAMLR(2),  'I', 2);
+	printk_xampr(__get_IAMPR(3),  __get_IAMLR(3),  'I', 3);
+	printk_xampr(__get_IAMPR(4),  __get_IAMLR(4),  'I', 4);
+	printk_xampr(__get_IAMPR(5),  __get_IAMLR(5),  'I', 5);
+	printk_xampr(__get_IAMPR(6),  __get_IAMLR(6),  'I', 6);
+	printk_xampr(__get_IAMPR(7),  __get_IAMLR(7),  'I', 7);
+	printk_xampr(__get_IAMPR(8),  __get_IAMLR(8),  'I', 8);
+	printk_xampr(__get_IAMPR(9),  __get_IAMLR(9),  'i', 9);
+	printk_xampr(__get_IAMPR(10), __get_IAMLR(10), 'I', 10);
+	printk_xampr(__get_IAMPR(11), __get_IAMLR(11), 'I', 11);
+	printk_xampr(__get_IAMPR(12), __get_IAMLR(12), 'I', 12);
+	printk_xampr(__get_IAMPR(13), __get_IAMLR(13), 'I', 13);
+	printk_xampr(__get_IAMPR(14), __get_IAMLR(14), 'I', 14);
+	printk_xampr(__get_IAMPR(15), __get_IAMLR(15), 'I', 15);
+
+	printk_xampr(__get_DAMPR(0),  __get_DAMLR(0),  'D', 0);
+	printk_xampr(__get_DAMPR(1),  __get_DAMLR(1),  'D', 1);
+	printk_xampr(__get_DAMPR(2),  __get_DAMLR(2),  'D', 2);
+	printk_xampr(__get_DAMPR(3),  __get_DAMLR(3),  'D', 3);
+	printk_xampr(__get_DAMPR(4),  __get_DAMLR(4),  'D', 4);
+	printk_xampr(__get_DAMPR(5),  __get_DAMLR(5),  'D', 5);
+	printk_xampr(__get_DAMPR(6),  __get_DAMLR(6),  'D', 6);
+	printk_xampr(__get_DAMPR(7),  __get_DAMLR(7),  'D', 7);
+	printk_xampr(__get_DAMPR(8),  __get_DAMLR(8),  'D', 8);
+	printk_xampr(__get_DAMPR(9),  __get_DAMLR(9),  'D', 9);
+	printk_xampr(__get_DAMPR(10), __get_DAMLR(10), 'D', 10);
+	printk_xampr(__get_DAMPR(11), __get_DAMLR(11), 'D', 11);
+	printk_xampr(__get_DAMPR(12), __get_DAMLR(12), 'D', 12);
+	printk_xampr(__get_DAMPR(13), __get_DAMLR(13), 'D', 13);
+	printk_xampr(__get_DAMPR(14), __get_DAMLR(14), 'D', 14);
+	printk_xampr(__get_DAMPR(15), __get_DAMLR(15), 'D', 15);
+#endif
+
+#if 0
+	/* dump the bus controller registers */
+	printk("LGCR: %08lx\n", __get_LGCR());
+	printk("Master: %08lx-%08lx CR=%08lx\n",
+	       __get_LEMBR(), __get_LEMBR() + __get_LEMAM(),
+	       __get_LMAICR());
+
+	int loop;
+	for (loop = 1; loop <= 7; loop++) {
+		unsigned long lcr = __get_LCR(loop), lsbr = __get_LSBR(loop);
+		printk("CS#%d: %08lx-%08lx %c%c%c%c%c%c%c%c%c\n",
+		       loop,
+		       lsbr, lsbr + __get_LSAM(loop),
+		       lcr & 0x80000000 ? 'r' : '-',
+		       lcr & 0x40000000 ? 'w' : '-',
+		       lcr & 0x08000000 ? 'b' : '-',
+		       lcr & 0x04000000 ? 'B' : '-',
+		       lcr & 0x02000000 ? 'C' : '-',
+		       lcr & 0x01000000 ? 'D' : '-',
+		       lcr & 0x00800000 ? 'W' : '-',
+		       lcr & 0x00400000 ? 'R' : '-',
+		       (lcr & 0x00030000) == 0x00000000 ? '4' :
+		       (lcr & 0x00030000) == 0x00010000 ? '2' :
+		       (lcr & 0x00030000) == 0x00020000 ? '1' :
+		       '-'
+		       );
+	}
+#endif
+
+#if 0
+	printk("\n");
+#endif
+} /* end dump_memory_map() */
+
+/*****************************************************************************/
+/*
+ * attempt to detect a VDK motherboard and DAV daughter board on an MB93091 system
+ */
+#ifdef CONFIG_MB93091_VDK
+static void __init detect_mb93091(void)
+{
+#ifdef CONFIG_MB93090_MB00
+	/* Detect CB70 without motherboard */
+	if (!(cpu_system == __frv_mb93091_cb70 && ((*(unsigned short *)0xffc00030) & 0x100))) {
+		cpu_board1 = __frv_mb93090_mb00;
+		mb93090_mb00_detected = 1;
+	}
+#endif
+
+#ifdef CONFIG_FUJITSU_MB93493
+	cpu_board2 = __frv_mb93493;
+#endif
+
+} /* end detect_mb93091() */
+#endif
+
+/*****************************************************************************/
+/*
+ * determine the CPU type and set appropriate parameters
+ *
+ * Family     Series      CPU Core    Silicon    Imple  Vers
+ * ----------------------------------------------------------
+ * FR-V --+-> FR400 --+-> FR401 --+-> MB93401     02     00 [1]
+ *        |           |           |
+ *        |           |           +-> MB93401/A   02     01
+ *        |           |           |
+ *        |           |           +-> MB93403     02     02
+ *        |           |
+ *        |           +-> FR405 ----> MB93405     04     00
+ *        |
+ *        +-> FR450 ----> FR451 ----> MB93451     05     00
+ *        |
+ *        +-> FR500 ----> FR501 --+-> MB93501     01     01 [2]
+ *        |                       |
+ *        |                       +-> MB93501/A   01     02
+ *        |
+ *        +-> FR550 --+-> FR551 ----> MB93555     03     01
+ *
+ *  [1] The MB93401 is an obsolete CPU replaced by the MB93401A
+ *  [2] The MB93501 is an obsolete CPU replaced by the MB93501A
+ *
+ * Imple is PSR(Processor Status Register)[31:28].
+ * Vers is PSR(Processor Status Register)[27:24].
+ *
+ * A "Silicon" consists of CPU core and some on-chip peripherals.
+ */
+static void __init determine_cpu(void)
+{
+	unsigned long hsr0 = __get_HSR(0);
+	unsigned long psr = __get_PSR();
+
+	/* work out what selectable services the CPU supports */
+	__set_PSR(psr | PSR_EM | PSR_EF | PSR_CM | PSR_NEM);
+	cpu_psr_all = __get_PSR();
+	__set_PSR(psr);
+
+	__set_HSR(0, hsr0 | HSR0_GRLE | HSR0_GRHE | HSR0_FRLE | HSR0_FRHE);
+	cpu_hsr0_all = __get_HSR(0);
+	__set_HSR(0, hsr0);
+
+	/* derive other service specs from the CPU type */
+	cpu_series		= "unknown";
+	cpu_core		= "unknown";
+	cpu_silicon		= "unknown";
+	cpu_mmu			= "Prot";
+	cpu_system		= __frv_unknown_system;
+	clock_cmodes		= NULL;
+	clock_doubled		= 0;
+#ifdef CONFIG_PM
+	clock_bits_settable	= CLOCK_BIT_CM_H | CLOCK_BIT_CM_M | CLOCK_BIT_P0;
+#endif
+
+	switch (PSR_IMPLE(psr)) {
+	case PSR_IMPLE_FR401:
+		cpu_series	= "fr400";
+		cpu_core	= "fr401";
+		pdm_suspend_mode = HSR0_PDM_PLL_RUN;
+
+		switch (PSR_VERSION(psr)) {
+		case PSR_VERSION_FR401_MB93401:
+			cpu_silicon	= "mb93401";
+			cpu_system	= __frv_mb93091_cb10;
+			clock_cmodes	= clock_cmodes_fr401_fr403;
+			clock_doubled	= 1;
+			break;
+		case PSR_VERSION_FR401_MB93401A:
+			cpu_silicon	= "mb93401/A";
+			cpu_system	= __frv_mb93091_cb11;
+			clock_cmodes	= clock_cmodes_fr401_fr403;
+			break;
+		case PSR_VERSION_FR401_MB93403:
+			cpu_silicon	= "mb93403";
+#ifndef CONFIG_MB93093_PDK
+			cpu_system	= __frv_mb93091_cb30;
+#else
+			cpu_system	= __frv_mb93093;
+#endif
+			clock_cmodes	= clock_cmodes_fr401_fr403;
+			break;
+		default:
+			break;
+		}
+		break;
+
+	case PSR_IMPLE_FR405:
+		cpu_series	= "fr400";
+		cpu_core	= "fr405";
+		pdm_suspend_mode = HSR0_PDM_PLL_STOP;
+
+		switch (PSR_VERSION(psr)) {
+		case PSR_VERSION_FR405_MB93405:
+			cpu_silicon	= "mb93405";
+			cpu_system	= __frv_mb93091_cb60;
+			clock_cmodes	= clock_cmodes_fr405;
+#ifdef CONFIG_PM
+			clock_bits_settable |= CLOCK_BIT_CMODE;
+			clock_cmodes_permitted = CLOCK_CMODES_PERMITTED_FR405;
+#endif
+
+			/* the FPGA on the CB70 has extra registers
+			 * - it has 0x0046 in the VDK_ID FPGA register at 0x1a0, which is
+			 *   how we tell the difference between it and a CB60
+			 */
+			if (*(volatile unsigned short *) 0xffc001a0 == 0x0046)
+				cpu_system = __frv_mb93091_cb70;
+			break;
+		default:
+			break;
+		}
+		break;
+
+	case PSR_IMPLE_FR451:
+		cpu_series	= "fr450";
+		cpu_core	= "fr451";
+		pdm_suspend_mode = HSR0_PDM_PLL_STOP;
+#ifdef CONFIG_PM
+		clock_bits_settable |= CLOCK_BIT_CMODE;
+		clock_cmodes_permitted = CLOCK_CMODES_PERMITTED_FR405;
+#endif
+		switch (PSR_VERSION(psr)) {
+		case PSR_VERSION_FR451_MB93451:
+			cpu_silicon	= "mb93451";
+			cpu_mmu		= "Prot, SAT, xSAT, DAT";
+			cpu_system	= __frv_mb93091_cb451;
+			clock_cmodes	= clock_cmodes_fr405;
+			break;
+		default:
+			break;
+		}
+		break;
+
+	case PSR_IMPLE_FR501:
+		cpu_series	= "fr500";
+		cpu_core	= "fr501";
+		pdm_suspend_mode = HSR0_PDM_PLL_STOP;
+
+		switch (PSR_VERSION(psr)) {
+		case PSR_VERSION_FR501_MB93501:  cpu_silicon = "mb93501";   break;
+		case PSR_VERSION_FR501_MB93501A: cpu_silicon = "mb93501/A"; break;
+		default:
+			break;
+		}
+		break;
+
+	case PSR_IMPLE_FR551:
+		cpu_series	= "fr550";
+		cpu_core	= "fr551";
+		pdm_suspend_mode = HSR0_PDM_PLL_RUN;
+
+		switch (PSR_VERSION(psr)) {
+		case PSR_VERSION_FR551_MB93555:
+			cpu_silicon	= "mb93555";
+			cpu_mmu		= "Prot, SAT";
+			cpu_system	= __frv_mb93091_cb41;
+			clock_cmodes	= clock_cmodes_fr555;
+			clock_doubled	= 1;
+			break;
+		default:
+			break;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	printk("- Series:%s CPU:%s Silicon:%s\n",
+	       cpu_series, cpu_core, cpu_silicon);
+
+#ifdef CONFIG_MB93091_VDK
+	detect_mb93091();
+#endif
+
+#if defined(CONFIG_MB93093_PDK) && defined(CONFIG_FUJITSU_MB93493)
+	cpu_board2 = __frv_mb93493;
+#endif
+
+} /* end determine_cpu() */
+
+/*****************************************************************************/
+/*
+ * calculate the bus clock speed
+ */
+void __pminit determine_clocks(int verbose)
+{
+	const struct clock_cmode *mode, *tmode;
+	unsigned long clkc, psr, quot;
+
+	clkc = __get_CLKC();
+	psr = __get_PSR();
+
+#ifdef CONFIG_PM
+	clock_p0_current = !!(clkc & CLKC_P0);
+	clock_cm_current = clkc & CLKC_CM;
+	clock_cmode_current = (clkc & CLKC_CMODE) >> CLKC_CMODE_s;
+#endif
+
+	if (verbose)
+		printk("psr=%08lx hsr0=%08lx clkc=%08lx\n", psr, __get_HSR(0), clkc);
+
+	/* the CB70 has some alternative ways of setting the clock speed through switches accessed
+	 * through the FPGA.  */
+	if (cpu_system == __frv_mb93091_cb70) {
+		unsigned short clkswr = *(volatile unsigned short *) 0xffc00104UL & 0x1fffUL;
+
+		if (clkswr & 0x1000)
+			__clkin_clock_speed_HZ = 60000000UL;
+		else
+			__clkin_clock_speed_HZ =
+				((clkswr >> 8) & 0xf) * 10000000 +
+				((clkswr >> 4) & 0xf) * 1000000 +
+				((clkswr     ) & 0xf) * 100000;
+	}
+	/* the FR451 is currently fixed at 24MHz */
+	else if (cpu_system == __frv_mb93091_cb451) {
+		//__clkin_clock_speed_HZ = 24000000UL; // CB451-FPGA
+		unsigned short clkswr = *(volatile unsigned short *) 0xffc00104UL & 0x1fffUL;
+
+		if (clkswr & 0x1000)
+			__clkin_clock_speed_HZ = 60000000UL;
+		else
+			__clkin_clock_speed_HZ =
+				((clkswr >> 8) & 0xf) * 10000000 +
+				((clkswr >> 4) & 0xf) * 1000000 +
+				((clkswr     ) & 0xf) * 100000;
+	}
+	/* otherwise determine the clockspeed from VDK or other registers */
+	else {
+		__clkin_clock_speed_HZ = __get_CLKIN();
+	}
+
+	/* look up the appropriate clock relationships table entry */
+	mode = &undef_clock_cmode;
+	if (clock_cmodes) {
+		tmode = &clock_cmodes[(clkc & CLKC_CMODE) >> CLKC_CMODE_s];
+		if (tmode->xbus)
+			mode = tmode;
+	}
+
+#define CLOCK(SRC,RATIO) ((SRC) * (((RATIO) >> 4) & 0x0f) / ((RATIO) & 0x0f))
+
+	if (clock_doubled)
+		__clkin_clock_speed_HZ <<= 1;
+
+	__ext_bus_clock_speed_HZ	= CLOCK(__clkin_clock_speed_HZ, mode->xbus);
+	__sdram_clock_speed_HZ		= CLOCK(__clkin_clock_speed_HZ, mode->sdram);
+	__dsu_clock_speed_HZ		= CLOCK(__clkin_clock_speed_HZ, mode->dsu);
+
+	switch (clkc & CLKC_CM) {
+	case 0: /* High */
+		__core_bus_clock_speed_HZ	= CLOCK(__clkin_clock_speed_HZ, mode->corebus);
+		__core_clock_speed_HZ		= CLOCK(__clkin_clock_speed_HZ, mode->core);
+		break;
+	case 1: /* Medium */
+		__core_bus_clock_speed_HZ	= CLOCK(__clkin_clock_speed_HZ, mode->sdram);
+		__core_clock_speed_HZ		= CLOCK(__clkin_clock_speed_HZ, mode->sdram);
+		break;
+	case 2: /* Low; not supported */
+	case 3: /* UNDEF */
+		printk("Unsupported CLKC CM %ld\n", clkc & CLKC_CM);
+		panic("Bye");
+	}
+
+	__res_bus_clock_speed_HZ = __ext_bus_clock_speed_HZ;
+	if (clkc & CLKC_P0)
+		__res_bus_clock_speed_HZ >>= 1;
+
+	if (verbose) {
+		printk("CLKIN: %lu.%3.3luMHz\n",
+		       __clkin_clock_speed_HZ / 1000000,
+		       (__clkin_clock_speed_HZ / 1000) % 1000);
+
+		printk("CLKS:"
+		       " ext=%luMHz res=%luMHz sdram=%luMHz cbus=%luMHz core=%luMHz dsu=%luMHz\n",
+		       __ext_bus_clock_speed_HZ / 1000000,
+		       __res_bus_clock_speed_HZ / 1000000,
+		       __sdram_clock_speed_HZ / 1000000,
+		       __core_bus_clock_speed_HZ / 1000000,
+		       __core_clock_speed_HZ / 1000000,
+		       __dsu_clock_speed_HZ / 1000000
+		       );
+	}
+
+	/* calculate the number of __delay() loop iterations per sec (2 insn loop) */
+	__delay_loops_MHz = __core_clock_speed_HZ / (1000000 * 2);
+
+	/* set the serial prescaler */
+	__serial_clock_speed_HZ = __res_bus_clock_speed_HZ;
+	quot = 1;
+	while (__serial_clock_speed_HZ / quot / 16 / 65536 > 3000)
+		quot += 1;
+
+	/* double the divisor if P0 is clear, so that if/when P0 is set, it's still achievable
+	 * - we have to be careful - dividing too much can mean we can't get 115200 baud
+	 */
+	if (__serial_clock_speed_HZ > 32000000 && !(clkc & CLKC_P0))
+		quot <<= 1;
+
+	__serial_clock_speed_HZ /= quot;
+	__frv_uart0.baud_base = __serial_clock_speed_HZ / 16;
+	__frv_uart1.baud_base = __serial_clock_speed_HZ / 16;
+
+	if (verbose)
+		printk("      uart=%luMHz\n",
+		       __serial_clock_speed_HZ / 1000000 * quot);
+
+	while (!(__get_UART0_LSR() & UART_LSR_TEMT))
+		continue;
+
+	while (!(__get_UART1_LSR() & UART_LSR_TEMT))
+		continue;
+
+	__set_UCPVR(quot);
+	__set_UCPSR(0);
+} /* end determine_clocks() */
+
+/*****************************************************************************/
+/*
+ * reserve some DMA consistent memory
+ */
+#ifdef CONFIG_RESERVE_DMA_CONSISTENT
+static void __init reserve_dma_consistent(void)
+{
+	unsigned long ampr;
+
+	/* find the first non-kernel memory tile and steal it */
+#define __steal_AMPR(r)						\
+	if (__get_DAMPR(r) & xAMPRx_V) {			\
+		ampr = __get_DAMPR(r);				\
+		__set_DAMPR(r, ampr | xAMPRx_S | xAMPRx_C);	\
+		__set_IAMPR(r, 0);				\
+		goto found;					\
+	}
+
+	__steal_AMPR(1);
+	__steal_AMPR(2);
+	__steal_AMPR(3);
+	__steal_AMPR(4);
+	__steal_AMPR(5);
+	__steal_AMPR(6);
+
+	if (PSR_IMPLE(__get_PSR()) == PSR_IMPLE_FR551) {
+		__steal_AMPR(7);
+		__steal_AMPR(8);
+		__steal_AMPR(9);
+		__steal_AMPR(10);
+		__steal_AMPR(11);
+		__steal_AMPR(12);
+		__steal_AMPR(13);
+		__steal_AMPR(14);
+	}
+
+	/* unable to grant any DMA consistent memory */
+	printk("No DMA consistent memory reserved\n");
+	return;
+
+ found:
+	dma_consistent_mem_start = ampr & xAMPRx_PPFN;
+	ampr &= xAMPRx_SS;
+	ampr >>= 4;
+	ampr = 1 << (ampr - 3 + 20);
+	dma_consistent_mem_end = dma_consistent_mem_start + ampr;
+
+	printk("DMA consistent memory reserved %lx-%lx\n",
+	       dma_consistent_mem_start, dma_consistent_mem_end);
+
+} /* end reserve_dma_consistent() */
+#endif
+
+/*****************************************************************************/
+/*
+ * calibrate the delay loop
+ */
+void __init calibrate_delay(void)
+{
+	loops_per_jiffy = __delay_loops_MHz * (1000000 / HZ);
+
+	printk("Calibrating delay loop... %lu.%02lu BogoMIPS\n",
+	       loops_per_jiffy / (500000 / HZ),
+	       (loops_per_jiffy / (5000 / HZ)) % 100);
+
+} /* end calibrate_delay() */
+
+/*****************************************************************************/
+/*
+ * look through the command line for some things we need to know immediately
+ */
+static void __init parse_cmdline_early(char *cmdline)
+{
+	if (!cmdline)
+		return;
+
+	while (*cmdline) {
+		if (*cmdline == ' ')
+			cmdline++;
+
+		/* "mem=XXX[kKmM]" sets SDRAM size to <mem>, overriding the value we worked
+		 * out from the SDRAM controller mask register
+		 */
+		if (!memcmp(cmdline, "mem=", 4)) {
+			unsigned long long mem_size;
+
+			mem_size = memparse(cmdline + 4, &cmdline);
+			memory_end = memory_start + mem_size;
+		}
+
+		while (*cmdline && *cmdline != ' ')
+			cmdline++;
+	}
+
+} /* end parse_cmdline_early() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+void __init setup_arch(char **cmdline_p)
+{
+#ifndef CONFIG_UCLINUX
+	printk("Linux FR-V port done by Red Hat Inc <dhowells@redhat.com>\n");
+#else
+	printk("uClinux FR-V port done by Red Hat Inc <dhowells@redhat.com>\n");
+#endif
+
+	determine_cpu();
+	determine_clocks(1);
+
+	/* For printk-directly-beats-on-serial-hardware hack */
+	console_set_baud(115200);
+#ifdef CONFIG_GDBSTUB
+	gdbstub_set_baud(115200);
+#endif
+
+#ifdef CONFIG_RESERVE_DMA_CONSISTENT
+	reserve_dma_consistent();
+#endif
+	dump_memory_map();
+
+#ifdef CONFIG_MB93090_MB00
+	if (mb93090_mb00_detected)
+		mb93090_display();
+#endif
+	/* register those serial ports that are available */
+#ifndef CONFIG_GDBSTUB_UART0
+	__reg(UART0_BASE + UART_IER * 8) = 0;
+	register_serial(&__frv_uart0);
+#endif
+#ifndef CONFIG_GDBSTUB_UART1
+	__reg(UART1_BASE + UART_IER * 8) = 0;
+	register_serial(&__frv_uart1);
+#endif
+
+#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
+	/* we need to initialize the Flashrom device here since we might
+	 * do things with flash early on in the boot
+	 */
+	flash_probe();
+#endif
+
+	/* deal with the command line - RedBoot may have passed one to the kernel */
+	memcpy(command_line, saved_command_line, sizeof(command_line));
+	*cmdline_p = &command_line[0];
+	parse_cmdline_early(command_line);
+
+	/* set up the memory description
+	 * - by now the stack is part of the init task */
+	printk("Memory %08lx-%08lx\n", memory_start, memory_end);
+
+	if (memory_start == memory_end) BUG();
+
+	init_mm.start_code = (unsigned long) &_stext;
+	init_mm.end_code = (unsigned long) &_etext;
+	init_mm.end_data = (unsigned long) &_edata;
+#if 0 /* DAVIDM - don't set brk just incase someone decides to use it */
+	init_mm.brk = (unsigned long) &_end;
+#else
+	init_mm.brk = (unsigned long) 0;
+#endif
+
+#ifdef DEBUG
+	printk("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x BSS=0x%06x-0x%06x\n",
+	       (int) &_stext, (int) &_etext,
+	       (int) &_sdata, (int) &_edata,
+	       (int) &_sbss, (int) &_ebss);
+#endif
+
+#ifdef CONFIG_VT
+#if defined(CONFIG_VGA_CONSOLE)
+        conswitchp = &vga_con;
+#elif defined(CONFIG_DUMMY_CONSOLE)
+        conswitchp = &dummy_con;
+#endif
+#endif
+
+#ifdef CONFIG_BLK_DEV_BLKMEM
+	ROOT_DEV = MKDEV(BLKMEM_MAJOR,0);
+#endif
+	/*rom_length = (unsigned long)&_flashend - (unsigned long)&_romvec;*/
+
+#ifndef CONFIG_UCLINUX
+	setup_linux_memory();
+#else
+	setup_uclinux_memory();
+#endif
+
+	/* get kmalloc into gear */
+	paging_init();
+
+	/* init DMA */
+	frv_dma_init();
+#ifdef DEBUG
+	printk("Done setup_arch\n");
+#endif
+
+} /* end setup_arch() */
+
+/*****************************************************************************/
+/*
+ * set up the memory map for normal MMU linux
+ */
+#ifndef CONFIG_UCLINUX
+static void __init setup_linux_memory(void)
+{
+	unsigned long bootmap_size, low_top_pfn, kstart, kend, high_mem;
+
+	kstart	= (unsigned long) &__kernel_image_start - PAGE_OFFSET;
+	kend	= (unsigned long) &__kernel_image_end - PAGE_OFFSET;
+
+	kstart = kstart & PAGE_MASK;
+	kend = (kend + PAGE_SIZE - 1) & PAGE_MASK;
+
+	/* give all the memory to the bootmap allocator,  tell it to put the
+	 * boot mem_map immediately following the kernel image
+	 */
+	bootmap_size = init_bootmem_node(NODE_DATA(0),
+					 kend >> PAGE_SHIFT,		/* map addr */
+					 memory_start >> PAGE_SHIFT,	/* start of RAM */
+					 memory_end >> PAGE_SHIFT	/* end of RAM */
+					 );
+
+	/* pass the memory that the kernel can immediately use over to the bootmem allocator */
+	max_mapnr = num_physpages = (memory_end - memory_start) >> PAGE_SHIFT;
+	low_top_pfn = (KERNEL_LOWMEM_END - KERNEL_LOWMEM_START) >> PAGE_SHIFT;
+	high_mem = 0;
+
+	if (num_physpages > low_top_pfn) {
+#ifdef CONFIG_HIGHMEM
+		high_mem = num_physpages - low_top_pfn;
+#else
+		max_mapnr = num_physpages = low_top_pfn;
+#endif
+	}
+	else {
+		low_top_pfn = num_physpages;
+	}
+
+	num_mappedpages = low_top_pfn;
+
+	printk(KERN_NOTICE "%ldMB LOWMEM available.\n", low_top_pfn >> (20 - PAGE_SHIFT));
+
+	free_bootmem(memory_start, low_top_pfn << PAGE_SHIFT);
+
+#ifdef CONFIG_HIGHMEM
+	if (high_mem)
+		printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", high_mem >> (20 - PAGE_SHIFT));
+#endif
+
+	/* take back the memory occupied by the kernel image and the bootmem alloc map */
+	reserve_bootmem(kstart, kend - kstart + bootmap_size);
+
+	/* reserve the memory occupied by the initial ramdisk */
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (LOADER_TYPE && INITRD_START) {
+		if (INITRD_START + INITRD_SIZE <= (low_top_pfn << PAGE_SHIFT)) {
+			reserve_bootmem(INITRD_START, INITRD_SIZE);
+			initrd_start = INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
+			initrd_end = initrd_start + INITRD_SIZE;
+		}
+		else {
+			printk(KERN_ERR
+			       "initrd extends beyond end of memory (0x%08lx > 0x%08lx)\n"
+			       "disabling initrd\n",
+			       INITRD_START + INITRD_SIZE,
+			       low_top_pfn << PAGE_SHIFT);
+			initrd_start = 0;
+		}
+	}
+#endif
+
+} /* end setup_linux_memory() */
+#endif
+
+/*****************************************************************************/
+/*
+ * set up the memory map for uClinux
+ */
+#ifdef CONFIG_UCLINUX
+static void __init setup_uclinux_memory(void)
+{
+#ifdef CONFIG_PROTECT_KERNEL
+	unsigned long dampr;
+#endif
+	int bootmap_size;
+
+	/* give all the memory to the bootmap allocator,  tell it to put the
+	 * boot mem_map immediately following the kernel image
+	 */
+	bootmap_size =
+		init_bootmem_node(NODE_DATA(0),
+				  (unsigned long) &__kernel_image_end >> PAGE_SHIFT, /* map addr */
+				  memory_start >> PAGE_SHIFT,	/* start of RAM */
+				  memory_end >> PAGE_SHIFT	/* end of RAM */
+				  );
+
+	/* free the usable memory,  we have to make sure we do not free
+	 * the bootmem bitmap so we then reserve it after freeing it :-)
+	 */
+	free_bootmem(memory_start, memory_end - memory_start);
+
+	high_memory = (void *) (memory_end & PAGE_MASK);
+	max_mapnr = num_physpages = num_mappedpages = MAP_NR(high_memory);
+
+#ifndef CONFIG_PROTECT_KERNEL
+	reserve_bootmem((unsigned long) &__kernel_image_end, bootmap_size);
+	reserve_bootmem((unsigned long) &__kernel_image_start,
+			(unsigned long) &__kernel_image_end -
+			(unsigned long) &__kernel_image_start);
+
+#else
+	dampr = __get_DAMPR(0);
+	dampr &= xAMPRx_SS;
+	dampr = (dampr >> 4) + 17;
+	dampr = 1 << dampr;
+
+	reserve_bootmem(__get_DAMPR(0) & xAMPRx_PPFN, dampr);
+#endif
+
+#ifdef CONFIG_RESERVE_DMA_CONSISTENT
+	if (dma_consistent_mem_start)
+		reserve_bootmem(dma_consistent_mem_start,
+				dma_consistent_mem_end - dma_consistent_mem_start);
+#endif
+
+} /* end setup_uclinux_memory() */
+#endif
+
+/*****************************************************************************/
+/*
+ * get CPU information for use by procfs
+ */
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+	const char *gr, *fr, *fm, *fp, *cm, *nem, *ble, *sep;
+
+	gr  = cpu_hsr0_all & HSR0_GRHE	? "gr0-63"	: "gr0-31";
+	fr  = cpu_hsr0_all & HSR0_FRHE	? "fr0-63"	: "fr0-31";
+	fm  = cpu_psr_all  & PSR_EM	? ", Media"	: "";
+	fp  = cpu_psr_all  & PSR_EF	? ", FPU"	: "";
+	cm  = cpu_psr_all  & PSR_CM	? ", CCCR"	: "";
+	nem = cpu_psr_all  & PSR_NEM	? ", NE"	: "";
+	ble = cpu_psr_all  & PSR_BE	? "BE"		: "LE";
+
+	seq_printf(m,
+		   "CPU-Series:\t%s\n"
+		   "CPU-Core:\t%s, %s, %s%s%s\n"
+		   "CPU:\t\t%s\n"
+		   "MMU:\t\t%s\n"
+		   "FP-Media:\t%s%s%s\n"
+		   "System:\t\t%s",
+		   cpu_series,
+		   cpu_core, gr, ble, cm, nem,
+		   cpu_silicon,
+		   cpu_mmu,
+		   fr, fm, fp,
+		   cpu_system);
+
+	if (cpu_board1)
+		seq_printf(m, ", %s", cpu_board1);
+
+	if (cpu_board2)
+		seq_printf(m, ", %s", cpu_board2);
+
+	seq_printf(m, "\n");
+
+#ifdef CONFIG_PM
+	seq_printf(m, "PM-Controls:");
+	sep = "\t";
+
+	if (clock_bits_settable & CLOCK_BIT_CMODE) {
+		seq_printf(m, "%scmode=0x%04hx", sep, clock_cmodes_permitted);
+		sep = ", ";
+	}
+
+	if (clock_bits_settable & CLOCK_BIT_CM) {
+		seq_printf(m, "%scm=0x%lx", sep, clock_bits_settable & CLOCK_BIT_CM);
+		sep = ", ";
+	}
+
+	if (clock_bits_settable & CLOCK_BIT_P0) {
+		seq_printf(m, "%sp0=0x3", sep);
+		sep = ", ";
+	}
+
+	seq_printf(m, "%ssuspend=0x22\n", sep);
+#endif
+
+	seq_printf(m,
+		   "PM-Status:\tcmode=%d, cm=%d, p0=%d\n",
+		   clock_cmode_current, clock_cm_current, clock_p0_current);
+
+#define print_clk(TAG, VAR) \
+	seq_printf(m, "Clock-" TAG ":\t%lu.%2.2lu MHz\n", VAR / 1000000, (VAR / 10000) % 100)
+
+	print_clk("In",    __clkin_clock_speed_HZ);
+	print_clk("Core",  __core_clock_speed_HZ);
+	print_clk("SDRAM", __sdram_clock_speed_HZ);
+	print_clk("CBus",  __core_bus_clock_speed_HZ);
+	print_clk("Res",   __res_bus_clock_speed_HZ);
+	print_clk("Ext",   __ext_bus_clock_speed_HZ);
+	print_clk("DSU",   __dsu_clock_speed_HZ);
+
+	seq_printf(m,
+		   "BogoMips:\t%lu.%02lu\n",
+		   (loops_per_jiffy * HZ) / 500000, ((loops_per_jiffy * HZ) / 5000) % 100);
+
+	return 0;
+} /* end show_cpuinfo() */
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	return *pos < NR_CPUS ? (void *) 0x12345678 : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+	.start	= c_start,
+	.next	= c_next,
+	.stop	= c_stop,
+	.show	= show_cpuinfo,
+};
+
+void arch_gettod(int *year, int *mon, int *day, int *hour,
+		 int *min, int *sec)
+{
+	*year = *mon = *day = *hour = *min = *sec = 0;
+}
+
+/*****************************************************************************/
+/*
+ *
+ */
+#ifdef CONFIG_MB93090_MB00
+static void __init mb93090_sendlcdcmd(uint32_t cmd)
+{
+	unsigned long base = __addr_LCD();
+	int loop;
+
+	/* request reading of the busy flag */
+	__set_LCD(base, LCD_CMD_READ_BUSY);
+	__set_LCD(base, LCD_CMD_READ_BUSY & ~LCD_E);
+
+	/* wait for the busy flag to become clear */
+	for (loop = 10000; loop > 0; loop--)
+		if (!(__get_LCD(base) & 0x80))
+			break;
+
+	/* send the command */
+	__set_LCD(base, cmd);
+	__set_LCD(base, cmd & ~LCD_E);
+
+} /* end mb93090_sendlcdcmd() */
+
+/*****************************************************************************/
+/*
+ * write to the MB93090 LEDs and LCD
+ */
+static void __init mb93090_display(void)
+{
+	const char *p;
+
+	__set_LEDS(0);
+
+	/* set up the LCD */
+	mb93090_sendlcdcmd(LCD_CMD_CLEAR);
+	mb93090_sendlcdcmd(LCD_CMD_FUNCSET(1,1,0));
+	mb93090_sendlcdcmd(LCD_CMD_ON(0,0));
+	mb93090_sendlcdcmd(LCD_CMD_HOME);
+
+	mb93090_sendlcdcmd(LCD_CMD_SET_DD_ADDR(0));
+	for (p = mb93090_banner; *p; p++)
+		mb93090_sendlcdcmd(LCD_DATA_WRITE(*p));
+
+	mb93090_sendlcdcmd(LCD_CMD_SET_DD_ADDR(64));
+	for (p = mb93090_version; *p; p++)
+		mb93090_sendlcdcmd(LCD_DATA_WRITE(*p));
+
+} /* end mb93090_display() */
+
+#endif // CONFIG_MB93090_MB00
diff -urN linux-2.4.29/arch/frv/kernel/signal.c linux-2.4.29-uc1/arch/frv/kernel/signal.c
--- linux-2.4.29/arch/frv/kernel/signal.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/signal.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,686 @@
+/*
+ *  linux/arch/frvnommu/kernel/signal.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
+ *  2000-06-20  Pentium III FXSR, SSE support by Gareth Hughes
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/tty.h>
+#include <linux/personality.h>
+#include <asm/ucontext.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+
+#define DEBUG_SIG 0
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+struct fdpic_func_descriptor {
+	unsigned long	text;
+	unsigned long	GOT;
+};
+
+asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
+
+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
+{
+	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+		return -EFAULT;
+	if (from->si_code < 0)
+		return __copy_to_user(to, from, sizeof(siginfo_t));
+	else {
+		int err;
+
+		/* If you change siginfo_t structure, please be sure
+		   this code is fixed accordingly.
+		   It should never copy any pad contained in the structure
+		   to avoid security leaks, but must copy the generic
+		   3 ints plus the relevant union member.  */
+		err = __put_user(from->si_signo, &to->si_signo);
+		err |= __put_user(from->si_errno, &to->si_errno);
+		err |= __put_user((short)from->si_code, &to->si_code);
+		/* First 32bits of unions are always present.  */
+		err |= __put_user(from->si_pid, &to->si_pid);
+		switch (from->si_code >> 16) {
+		case __SI_FAULT >> 16:
+			break;
+		case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+			err |= __put_user(from->si_status, &to->si_status);
+		default:
+			err |= __put_user(from->si_uid, &to->si_uid);
+			break;
+		/* case __SI_RT: This is not generated by the kernel as of now.  */
+		}
+		return err;
+	}
+}
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int
+sys_sigsuspend(int history0, int history1, old_sigset_t mask)
+{
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	__frame->gr8 = -EINTR;
+	while (1) {
+		schedule();
+		if (do_signal(__frame, &saveset))
+			/* return the signal number as the return value of this function
+			 * - this is an utterly evil hack. syscalls should not invoke do_signal()
+			 *   as entry.S sets regs->gr8 to the return value of the system call
+			 * - we can't just use sigpending() as we'd have to discard SIG_IGN signals
+			 *   and call waitpid() if SIGCHLD needed discarding
+			 * - this only works on the i386 because it passes arguments to the signal
+			 *   handler on the stack, and the return value in EAX is effectively
+			 *   discarded
+			 */
+			return __frame->gr8;
+	}
+}
+
+asmlinkage int
+sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
+{
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	__frame->gr8 = -EINTR;
+	while (1) {
+		schedule();
+		if (do_signal(__frame, &saveset))
+			/* return the signal number as the return value of this function
+			 * - this is an utterly evil hack. syscalls should not invoke do_signal()
+			 *   as entry.S sets regs->gr8 to the return value of the system call
+			 * - we can't just use sigpending() as we'd have to discard SIG_IGN signals
+			 *   and call waitpid() if SIGCHLD needed discarding
+			 * - this only works on the i386 because it passes arguments to the signal
+			 *   handler on the stack, and the return value in EAX is effectively
+			 *   discarded
+			 */
+			return __frame->gr8;
+	}
+}
+
+asmlinkage int
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+{
+	return do_sigaltstack(uss, uoss, __frame->sp);
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+
+struct sigframe
+{
+	void (*pretcode)(void);
+	int sig;
+	struct sigcontext sc;
+	unsigned long extramask[_NSIG_WORDS-1];
+	uint32_t retcode[2];
+};
+
+struct rt_sigframe
+{
+	void (*pretcode)(void);
+	int sig;
+	struct siginfo *pinfo;
+	void *puc;
+	struct siginfo info;
+	struct ucontext uc;
+	uint32_t retcode[2];
+};
+
+static
+int restore_sigcontext(struct sigcontext *sc, int *_gr8)
+{
+	struct user_context *user = current->thread.user;
+	unsigned long tbr, psr;
+
+	tbr = user->i.tbr;
+	psr = user->i.psr;
+	if (copy_from_user(user, &sc->sc_context, sizeof(sc->sc_context)))
+		goto badframe;
+	user->i.tbr = tbr;
+	user->i.psr = psr;
+
+	restore_user_regs(user);
+
+	user->i.syscallno = -1;		/* disable syscall checks */
+
+	*_gr8 = user->i.gr[8];
+	return 0;
+
+badframe:
+	return 1;
+}
+
+asmlinkage int sys_sigreturn(void)
+{
+	struct sigframe *frame = (struct sigframe *) __frame->sp;
+	sigset_t set;
+	int gr8;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__get_user(set.sig[0], &frame->sc.sc_oldmask))
+		goto badframe;
+
+	if (_NSIG_WORDS > 1 &&
+	    __copy_from_user(&set.sig[1], &frame->extramask, sizeof(frame->extramask)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigcontext(&frame->sc, &gr8))
+		goto badframe;
+	return gr8;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int sys_rt_sigreturn(void)
+{
+	struct rt_sigframe *frame = (struct rt_sigframe *) __frame->sp;
+	sigset_t set;
+	stack_t st;
+	int gr8;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigcontext(&frame->uc.uc_mcontext, &gr8))
+		goto badframe;
+
+	if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
+		goto badframe;
+
+	/* It is more difficult to avoid calling this function than to
+	 * call it and ignore errors.  */
+	do_sigaltstack(&st, NULL, __frame->sp);
+
+	return gr8;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+/*
+ * Set up a signal frame
+ */
+static
+int setup_sigcontext(struct sigcontext *sc, unsigned long mask)
+{
+	save_user_regs(current->thread.user);
+
+	if (copy_to_user(&sc->sc_context, current->thread.user, sizeof(sc->sc_context)) != 0)
+		goto badframe;
+
+	/* non-iBCS2 extensions.. */
+	if (__put_user(mask, &sc->sc_oldmask) < 0)
+		goto badframe;
+
+	return 0;
+
+ badframe:
+	return 1;
+}
+
+/*****************************************************************************/
+/*
+ * Determine which stack to use..
+ */
+static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
+{
+	unsigned long sp;
+
+	/* Default to using normal stack */
+	sp = regs->sp;
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if (ka->sa.sa_flags & SA_ONSTACK) {
+		if (! on_sig_stack(sp))
+			sp = current->sas_ss_sp + current->sas_ss_size;
+	}
+
+	return (void *) ((sp - frame_size) & ~7UL);
+} /* end get_sigframe() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs)
+{
+	struct sigframe *frame;
+	int rsig;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	rsig = sig;
+	if (sig < 32 && current->exec_domain && current->exec_domain->signal_invmap)
+		rsig = current->exec_domain->signal_invmap[sig];
+
+	if (__put_user(rsig, &frame->sig) < 0)
+		goto give_sigsegv;
+
+	if (setup_sigcontext(&frame->sc, set->sig[0]))
+		goto give_sigsegv;
+
+	if (_NSIG_WORDS > 1) {
+		if (__copy_to_user(frame->extramask, &set->sig[1],
+				   sizeof(frame->extramask)))
+			goto give_sigsegv;
+	}
+
+	/* Set up to return from userspace.  If provided, use a stub
+	 * already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		if (__put_user(ka->sa.sa_restorer, &frame->pretcode) < 0)
+			goto give_sigsegv;
+	}
+	else {
+		/* Set up the following code on the stack:
+		 *	setlos	#__NR_sigreturn,gr7
+		 *	tira	gr0,0
+		 */
+		if (__put_user((void (*)(void))frame->retcode, &frame->pretcode) ||
+		    __put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) ||
+		    __put_user(0xc0700000, &frame->retcode[1]))
+			goto give_sigsegv;
+
+		flush_icache_range((unsigned long) frame->retcode,
+				   (unsigned long) (frame->retcode + 2));
+	}
+
+	/* set up registers for signal handler */
+	regs->sp   = (unsigned long) frame;
+	regs->lr   = (unsigned long) &frame->retcode;
+	regs->gr8  = sig;
+
+	if (get_personality & FDPIC_FUNCPTRS) {
+		struct fdpic_func_descriptor *funcptr =
+			(struct fdpic_func_descriptor *) ka->sa.sa_handler;
+		__get_user(regs->pc, &funcptr->text);
+		__get_user(regs->gr15, &funcptr->GOT);
+	} else {
+		regs->pc   = (unsigned long) ka->sa.sa_handler;
+		regs->gr15 = 0;
+	}
+
+	set_fs(USER_DS);
+
+#if DEBUG_SIG
+	printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
+		sig, current->comm, current->pid, frame, regs->pc, frame->pretcode);
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+
+	force_sig(SIGSEGV, current);
+} /* end setup_frame() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+			   sigset_t *set, struct pt_regs * regs)
+{
+	struct rt_sigframe *frame;
+	int rsig;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	rsig = sig;
+	if (sig < 32 && current->exec_domain && current->exec_domain->signal_invmap)
+		rsig = current->exec_domain->signal_invmap[sig];
+
+	if (__put_user(rsig,		&frame->sig) ||
+	    __put_user(&frame->info,	&frame->pinfo) ||
+	    __put_user(&frame->uc,	&frame->puc))
+		goto give_sigsegv;
+
+	if (copy_siginfo_to_user(&frame->info, info))
+		goto give_sigsegv;
+
+	/* Create the ucontext.  */
+	if (__put_user(0, &frame->uc.uc_flags) ||
+	    __put_user(0, &frame->uc.uc_link) ||
+	    __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) ||
+	    __put_user(sas_ss_flags(regs->sp), &frame->uc.uc_stack.ss_flags) ||
+	    __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size))
+		goto give_sigsegv;
+
+	if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0]))
+		goto give_sigsegv;
+
+	if (__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
+		goto give_sigsegv;
+
+	/* Set up to return from userspace.  If provided, use a stub
+	 * already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		if (__put_user(ka->sa.sa_restorer, &frame->pretcode))
+			goto give_sigsegv;
+	}
+	else {
+		/* Set up the following code on the stack:
+		 *	setlos	#__NR_sigreturn,gr7
+		 *	tira	gr0,0
+		 */
+		if (__put_user((void (*)(void))frame->retcode, &frame->pretcode) ||
+		    __put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) ||
+		    __put_user(0xc0700000, &frame->retcode[1]))
+			goto give_sigsegv;
+
+		flush_icache_range((unsigned long) frame->retcode,
+				   (unsigned long) (frame->retcode + 2));
+	}
+
+	/* Set up registers for signal handler */
+	regs->sp  = (unsigned long) frame;
+	regs->lr   = (unsigned long) &frame->retcode;
+	regs->gr8 = sig;
+	regs->gr9 = (unsigned long) &frame->info;
+
+	if (get_personality & FDPIC_FUNCPTRS) {
+		struct fdpic_func_descriptor *funcptr =
+			(struct fdpic_func_descriptor *) ka->sa.sa_handler;
+		__get_user(regs->pc, &funcptr->text);
+		__get_user(regs->gr15, &funcptr->GOT);
+	} else {
+		regs->pc   = (unsigned long) ka->sa.sa_handler;
+		regs->gr15 = 0;
+	}
+
+	set_fs(USER_DS);
+
+#if DEBUG_SIG
+	printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
+		sig, current->comm, current->pid, frame, regs->pc, frame->pretcode);
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+
+} /* end setup_rt_frame() */
+
+/*****************************************************************************/
+/*
+ * OK, we're invoking a handler
+ */
+static void handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
+			  sigset_t *oldset, struct pt_regs * regs)
+{
+	/* Are we from a system call? */
+	if (in_syscall(regs)) {
+		/* If so, check system call restarting.. */
+		switch (regs->gr8) {
+			case -ERESTARTNOHAND:
+				regs->gr8 = -EINTR;
+				break;
+
+			case -ERESTARTSYS:
+				if (!(ka->sa.sa_flags & SA_RESTART)) {
+					regs->gr8 = -EINTR;
+					break;
+				}
+			/* fallthrough */
+			case -ERESTARTNOINTR:
+				regs->gr8 = regs->orig_gr8;
+				regs->pc -= 4;
+		}
+	}
+
+	/* Set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sigmask_lock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending(current);
+		spin_unlock_irq(&current->sigmask_lock);
+	}
+} /* end handle_signal() */
+
+int print_fatal_signals;
+
+/*****************************************************************************/
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ */
+int do_signal(struct pt_regs *regs, sigset_t *oldset)
+{
+	struct k_sigaction *ka;
+	siginfo_t info;
+
+	/*
+	 * We want the common case to go fast, which
+	 * is why we may in certain cases get here from
+	 * kernel mode. Just return without doing anything
+	 * if so.
+	 */
+	if (!user_mode(regs))
+		return 1;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	for (;;) {
+		unsigned long signr;
+
+		spin_lock_irq(&current->sigmask_lock);
+		signr = dequeue_signal(&current->blocked, &info);
+		spin_unlock_irq(&current->sigmask_lock);
+
+		if (!signr)
+			break;
+
+		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			/* Let the debugger run.  */
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code))
+				continue;
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				continue;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+
+			/* Init gets no signals it doesn't want.  */
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP: {
+				struct signal_struct *sig;
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				sig = current->p_pptr->sig;
+				if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+					notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+			}
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGABRT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				sig_exit(signr, exit_code, &info);
+				/* NOTREACHED */
+			}
+		}
+
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(signr, ka, &info, oldset, regs);
+		return 1;
+	}
+
+	/* Did we come from a system call? */
+	if (regs->syscallno >= 0) {
+		/* Restart the system call - no handlers present */
+		if (regs->gr8 == -ERESTARTNOHAND ||
+		    regs->gr8 == -ERESTARTSYS ||
+		    regs->gr8 == -ERESTARTNOINTR) {
+			regs->gr8 = regs->orig_gr8;
+			regs->pc -= 4;
+		}
+	}
+	return 0;
+} /* end do_signal() */
diff -urN linux-2.4.29/arch/frv/kernel/sleep.S linux-2.4.29-uc1/arch/frv/kernel/sleep.S
--- linux-2.4.29/arch/frv/kernel/sleep.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/sleep.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,375 @@
+/* entry.S: FR-V entry
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Woodhouse (dwmw2@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include <asm/errno.h>
+#include <asm/cache.h>
+#include <asm/spr-regs.h>
+
+#define __addr_MASK	0xfeff9820	/* interrupt controller mask */
+
+#define __addr_FR55X_DRCN	0xfeff0218      /* Address of DRCN register */
+#define FR55X_DSTS_OFFSET	-4		/* Offset from DRCN to DSTS */
+#define FR55X_SDRAMC_DSTS_SSI	0x00000002	/* indicates that the SDRAM is in self-refresh mode */
+
+#define __addr_FR4XX_DRCN	0xfe000430      /* Address of DRCN register */
+#define FR4XX_DSTS_OFFSET	-8		/* Offset from DRCN to DSTS */
+#define FR4XX_SDRAMC_DSTS_SSI	0x00000001	/* indicates that the SDRAM is in self-refresh mode */
+
+
+        .file		"sleep.S"
+
+	.section	.bss
+	.balign		8
+	.globl		__sleep_save_area
+__sleep_save_area:
+	.space		16
+
+
+	.text
+	.balign		4
+
+.macro li v r
+	sethi.p		%hi(\v),\r
+	setlo		%lo(\v),\r
+.endm
+
+#ifdef CONFIG_PM
+###############################################################################
+#
+# CPU suspension routine
+# - void frv_cpu_suspend(unsigned long pdm_mode)
+#
+###############################################################################
+	.globl		frv_cpu_suspend
+        .type		frv_cpu_suspend,@function
+frv_cpu_suspend:
+
+	#----------------------------------------------------
+	# save hsr0, psr, isr, and lr for resume code
+	#----------------------------------------------------
+	li		__sleep_save_area,gr11
+
+	movsg		hsr0,gr4
+	movsg		psr,gr5
+	movsg		isr,gr6
+	movsg		lr,gr7
+	stdi		gr4,@(gr11,#0)
+	stdi		gr6,@(gr11,#8)
+
+	# store the return address from sleep in GR14, and its complement in GR13 as a check
+	li		__ramboot_resume,gr14
+#ifndef CONFIG_UCLINUX
+	# Resume via RAMBOOT# will turn MMU off, so bootloader needs a physical address.
+	sethi.p		%hi(__page_offset),gr13
+	setlo		%lo(__page_offset),gr13
+	sub		gr14,gr13,gr14
+#endif
+	not		gr14,gr13
+
+	#----------------------------------------------------
+	# preload and lock into icache that code which may have to run
+	# when dram is in self-refresh state.
+	#----------------------------------------------------
+	movsg		hsr0, gr3
+	li		HSR0_ICE,gr4
+	or		gr3,gr4,gr3
+	movgs		gr3,hsr0
+	or		gr3,gr8,gr7	// add the sleep bits for later
+	
+	li		#__icache_lock_start,gr3
+	li		#__icache_lock_end,gr4
+1:	icpl		gr3,gr0,#1
+	addi		gr3,#L1_CACHE_BYTES,gr3
+	cmp		gr4,gr3,icc0
+	bhi		icc0,#0,1b
+
+	# disable exceptions
+	movsg		psr,gr8
+	andi.p		gr8,#~PSR_PIL,gr8
+	andi		gr8,~PSR_ET,gr8
+	movgs		gr8,psr
+	ori		gr8,#PSR_ET,gr8
+
+	srli		gr8,#28,gr4
+	subicc		gr4,#3,gr0,icc0
+	beq		icc0,#0,1f
+	# FR4xx
+	li		__addr_FR4XX_DRCN,gr4
+	li		FR4XX_SDRAMC_DSTS_SSI,gr5
+	li		FR4XX_DSTS_OFFSET,gr6
+	bra		__icache_lock_start
+1:	
+	# FR5xx
+	li		__addr_FR55X_DRCN,gr4
+	li		FR55X_SDRAMC_DSTS_SSI,gr5
+	li		FR55X_DSTS_OFFSET,gr6
+	bra		__icache_lock_start
+
+	.size		frv_cpu_suspend, .-frv_cpu_suspend
+
+#
+# the final part of the sleep sequence...
+# - we want it to be be cacheline aligned so we can lock it into the icache easily
+#  On entry:	gr7 holds desired hsr0 sleep value
+#               gr8 holds desired psr sleep value
+#
+	.balign		L1_CACHE_BYTES
+        .type		__icache_lock_start,@function
+__icache_lock_start:
+
+	#----------------------------------------------------
+	# put SDRAM in self-refresh mode
+	#----------------------------------------------------
+	
+	# Flush all data in the cache using the DCEF instruction.
+	dcef		@(gr0,gr0),#1
+
+	# Stop DMAC transfer
+
+	# Execute dummy load from SDRAM
+	ldi		@(gr11,#0),gr11
+
+	# put the SDRAM into self-refresh mode
+	ld              @(gr4,gr0),gr11
+	ori		gr11,#1,gr11
+	st		gr11,@(gr4,gr0)
+	membar
+
+	# wait for SDRAM to reach self-refresh mode
+1:	ld		@(gr4,gr6),gr11
+	andcc		gr11,gr5,gr11,icc0
+	beq		icc0,#0,1b
+
+	#  Set the GPIO register so that the IRQ[3:0] pins become valid, as required.
+	#  Set the clock mode (CLKC register) as required.
+	#     - At this time, also set the CLKC register P0 bit.
+	
+	# Set the HSR0 register PDM field.
+	movgs		gr7,hsr0
+
+	# Execute NOP 32 times.
+	.rept		32
+	nop
+	.endr
+
+#if 0 // Fujitsu recommend to skip this and will update docs.
+	#      Release the interrupt mask setting of the MASK register of the 
+	#      interrupt controller if necessary.
+	sti		gr10,@(gr9,#0)
+	membar
+#endif
+		
+	# Set the PSR register ET bit to 1 to enable interrupts.
+	movgs		gr8,psr
+
+	###################################################
+	# this is only reached if waking up via interrupt
+	###################################################
+
+	# Execute NOP 32 times.
+	.rept		32
+	nop
+	.endr
+
+	#----------------------------------------------------
+	# wake SDRAM from self-refresh mode
+	#----------------------------------------------------
+	ld              @(gr4,gr0),gr11
+	andi		gr11,#~1,gr11
+	st		gr11,@(gr4,gr0)
+	membar
+2:	
+	ld		@(gr4,gr6),gr11	// Wait for it to come back...
+	andcc		gr11,gr5,gr0,icc0
+	bne		icc0,0,2b
+	
+	# wait for the SDRAM to stabilise
+	li		0x0100000,gr3
+3:	subicc		gr3,#1,gr3,icc0
+	bne		icc0,#0,3b
+
+	# now that DRAM is back, this is the end of the code which gets
+	# locked in icache.
+__icache_lock_end:
+	.size		__icache_lock_start, .-__icache_lock_start
+
+	# Fall-through to the RAMBOOT# wakeup path
+	
+###############################################################################
+#
+#  resume from suspend re-entry point reached via RAMBOOT# and bootloader
+#
+###############################################################################
+__ramboot_resume:
+	
+	#----------------------------------------------------
+	# restore hsr0, psr, isr, and leave saved lr in gr7
+	#----------------------------------------------------
+	li		__sleep_save_area,gr11
+#ifndef CONFIG_UCLINUX
+	movsg		hsr0,gr4
+	sethi.p		%hi(HSR0_EXMMU),gr3
+	setlo		%lo(HSR0_EXMMU),gr3
+	andcc		gr3,gr4,gr0,icc0
+	bne		icc0,#0,2f
+	
+	# need to use physical address
+	sethi.p		%hi(__page_offset),gr3
+	setlo		%lo(__page_offset),gr3
+	sub		gr11,gr3,gr11
+	
+	# flush all tlb entries
+	setlos		#64,gr4
+	setlos.p	#PAGE_SIZE,gr5
+	setlos		#0,gr6
+1:
+	tlbpr		gr6,gr0,#6,#0
+	subicc.p	gr4,#1,gr4,icc0
+	add		gr6,gr5,gr6
+	bne		icc0,#2,1b
+
+	# need a temporary mapping for the current physical address we are
+	# using between time MMU is enabled and jump to virtual address is
+	# made.
+	sethi.p		%hi(0x00000000),gr4
+	setlo		%lo(0x00000000),gr4		; physical address
+	setlos		#xAMPRx_L|xAMPRx_M|xAMPRx_SS_256Mb|xAMPRx_S_KERNEL|xAMPRx_V,gr5
+	or		gr4,gr5,gr5
+
+	movsg		cxnr,gr13
+	or		gr4,gr13,gr4	
+
+	movgs		gr4,iamlr1			; mapped from real address 0
+	movgs		gr5,iampr1			; cached kernel memory at 0x00000000
+2:
+#endif
+
+	lddi		@(gr11,#0),gr4 ; hsr0, psr 
+	lddi		@(gr11,#8),gr6 ; isr, lr
+	movgs		gr4,hsr0
+	bar
+	
+#ifndef CONFIG_UCLINUX
+	sethi.p		%hi(1f),gr11
+	setlo		%lo(1f),gr11
+	jmpl		@(gr11,gr0)
+1:
+	movgs		gr0,iampr1 	; get rid of temporary mapping
+#endif
+	movgs		gr5,psr
+	movgs		gr6,isr
+	
+	#----------------------------------------------------
+	# unlock the icache which was locked before going to sleep
+	#----------------------------------------------------
+	li		__icache_lock_start,gr3
+	li		__icache_lock_end,gr4
+1:	icul		gr3
+	addi		gr3,#L1_CACHE_BYTES,gr3
+	cmp		gr4,gr3,icc0
+	bhi		icc0,#0,1b
+
+	#----------------------------------------------------
+	# back to business as usual
+	#----------------------------------------------------
+	jmpl		@(gr7,gr0)		;
+
+#endif /* CONFIG_PM */
+
+###############################################################################
+#
+# CPU core sleep mode routine
+#
+###############################################################################
+	.globl		frv_cpu_core_sleep
+        .type		frv_cpu_core_sleep,@function
+frv_cpu_core_sleep:
+
+	# Preload into icache.
+	li		#__core_sleep_icache_lock_start,gr3
+	li		#__core_sleep_icache_lock_end,gr4
+
+1:	icpl		gr3,gr0,#1
+	addi		gr3,#L1_CACHE_BYTES,gr3
+	cmp		gr4,gr3,icc0
+	bhi		icc0,#0,1b
+
+	bra	__core_sleep_icache_lock_start
+
+	.balign L1_CACHE_BYTES
+__core_sleep_icache_lock_start:
+	
+	# (1) Set the PSR register ET bit to 0 to disable interrupts.
+	movsg		psr,gr8
+	andi.p		gr8,#~(PSR_PIL),gr8
+	andi		gr8,#~(PSR_ET),gr4
+	movgs		gr4,psr
+
+#if 0 // Fujitsu recommend to skip this and will update docs.
+	# (2) Set '1' to all bits in the MASK register of the interrupt 
+	#     controller and mask interrupts.
+	sethi.p		%hi(__addr_MASK),gr9
+	setlo		%lo(__addr_MASK),gr9
+	sethi.p		%hi(0xffff0000),gr4
+	setlo		%lo(0xffff0000),gr4
+	ldi		@(gr9,#0),gr10
+	sti		gr4,@(gr9,#0)
+#endif
+	# (3) Flush all data in the cache using the DCEF instruction.
+	dcef		@(gr0,gr0),#1
+
+	# (4) Execute the memory barrier instruction
+	membar
+
+	# (5) Set the GPIO register so that the IRQ[3:0] pins become valid, as required.
+	# (6) Set the clock mode (CLKC register) as required.
+	#     - At this time, also set the CLKC register P0 bit.
+	# (7) Set the HSR0 register PDM field to  001 .
+	movsg		hsr0,gr4
+	ori		gr4,HSR0_PDM_CORE_SLEEP,gr4
+	movgs		gr4,hsr0
+
+	# (8) Execute NOP 32 times.
+	.rept		32
+	nop
+	.endr
+
+#if 0 // Fujitsu recommend to skip this and will update docs.
+	# (9) Release the interrupt mask setting of the MASK register of the 
+	#     interrupt controller if necessary.
+	sti		gr10,@(gr9,#0)
+	membar
+#endif
+		
+	# (10) Set the PSR register ET bit to 1 to enable interrupts.
+	movgs		gr8,psr
+
+__core_sleep_icache_lock_end:
+
+	# Unlock from icache
+	li	__core_sleep_icache_lock_start,gr3
+	li	__core_sleep_icache_lock_end,gr4
+1:	icul		gr3
+	addi		gr3,#L1_CACHE_BYTES,gr3
+	cmp		gr4,gr3,icc0
+	bhi		icc0,#0,1b
+
+	bralr
+		
+	.size		frv_cpu_core_sleep, .-frv_cpu_core_sleep
diff -urN linux-2.4.29/arch/frv/kernel/switch_to.S linux-2.4.29-uc1/arch/frv/kernel/switch_to.S
--- linux-2.4.29/arch/frv/kernel/switch_to.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/switch_to.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,484 @@
+###############################################################################
+#
+# switch_to.S: context switch operation
+#
+# Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+# Written by David Howells (dhowells@redhat.com)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+###############################################################################
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/processor.h>
+#include <asm/registers.h>
+#include <asm/spr-regs.h>
+
+.macro LEDS val
+	setlos		#~\val,gr27
+	st		gr27,@(gr30,gr0)
+	membar
+	dcf		@(gr30,gr0)
+.endm
+
+	.section	.sdata
+	.balign		8
+
+	# address of frame 0 (userspace) on current kernel stack
+	.globl		__kernel_frame0_ptr
+__kernel_frame0_ptr:
+	.long		init_task_union + 8192 - USER_CONTEXT_SIZE
+
+	# address of current task
+	.globl		__kernel_current_task
+__kernel_current_task:
+	.long		init_task_union
+
+	.section	.text
+	.balign		4
+
+###############################################################################
+#
+# struct task_struct *__switch_to(struct thread_struct *prev_thread,
+#				  struct thread_struct *next_thread,
+#				  struct task_struct *prev)
+#
+###############################################################################
+	.globl		__switch_to
+__switch_to:
+	# save outgoing process's context
+	sethi.p		%hi(__switch_back),gr13
+	setlo		%lo(__switch_back),gr13
+	movsg		lr,gr12
+
+	stdi		gr28,@(gr8,#__THREAD_FRAME)
+	sti		sp  ,@(gr8,#__THREAD_SP)
+	sti		fp  ,@(gr8,#__THREAD_FP)
+	stdi		gr12,@(gr8,#__THREAD_LR)
+	stdi		gr16,@(gr8,#__THREAD_GR(16))
+	stdi		gr18,@(gr8,#__THREAD_GR(18))
+	stdi		gr20,@(gr8,#__THREAD_GR(20))
+	stdi		gr22,@(gr8,#__THREAD_GR(22))
+	stdi		gr24,@(gr8,#__THREAD_GR(24))
+	stdi.p		gr26,@(gr8,#__THREAD_GR(26))
+
+	or		gr8,gr8,gr22
+	ldi.p		@(gr8,#__THREAD_USER),gr8
+	call		save_user_regs
+	or		gr22,gr22,gr8
+
+	# retrieve the new context
+	sethi.p		%hi(__kernel_frame0_ptr),gr6
+	setlo		%lo(__kernel_frame0_ptr),gr6
+	movsg		psr,gr4
+
+	lddi.p		@(gr9,#__THREAD_FRAME),gr10
+	or		gr10,gr10,gr27		; save prev for the return value
+
+	lddi		@(gr9,#__THREAD_SP),gr12
+	lddi		@(gr9,#__THREAD_LR),gr14
+	ldi.p		@(gr9,#__THREAD_FRAME0),gr7
+
+	# actually switch kernel contexts with ordinary exceptions disabled
+	andi		gr4,#~PSR_ET,gr5
+	movgs		gr5,psr
+
+	or.p		gr10,gr0,gr28		; set __frame
+	or		gr11,gr0,gr29		; set __current
+	or.p		gr12,gr0,sp
+	or		gr13,gr0,fp
+
+	sti		gr7,@(gr6,#0)		; set __kernel_frame0_ptr
+	sti		gr29,@(gr6,#4)		; set __kernel_current_task
+
+	movgs		gr14,lr
+	bar
+
+	# jump to __switch_back or ret_from_fork as appropriate
+	# - move prev to GR8
+	movgs		gr4,psr
+	jmpl.p		@(gr15,gr0)
+	or		gr27,gr27,gr8
+
+###############################################################################
+#
+# restore incoming process's context
+# - on entry:
+#   - SP, FP, LR, GR28 and GR29 will have been set up appropriately
+#   - GR8 will point to the outgoing task_struct
+#   - GR9 will point to the incoming thread_struct
+#
+###############################################################################
+__switch_back:
+	lddi		@(gr9,#__THREAD_GR(16)),gr16
+	lddi		@(gr9,#__THREAD_GR(18)),gr18
+	lddi		@(gr9,#__THREAD_GR(20)),gr20
+	lddi		@(gr9,#__THREAD_GR(22)),gr22
+	lddi		@(gr9,#__THREAD_GR(24)),gr24
+	lddi		@(gr9,#__THREAD_GR(26)),gr26
+
+	# fall through into restore_user_regs()
+	ldi.p		@(gr9,#__THREAD_USER),gr8
+	or		gr8,gr8,gr9
+
+###############################################################################
+#
+# restore extra general regs and FP/Media regs
+# - void *restore_user_regs(const struct user_context *target, void *retval)
+# - on entry:
+#   - GR8 will point to the user context to swap in
+#   - GR9 will contain the value to be returned in GR8 (prev task on context switch)
+#
+###############################################################################
+	.globl		restore_user_regs
+restore_user_regs:
+	movsg		hsr0,gr6
+	ori		gr6,#HSR0_GRHE|HSR0_FRLE|HSR0_FRHE,gr6
+	movgs		gr6,hsr0
+	movsg		hsr0,gr6
+
+	movsg		psr,gr7
+	ori		gr7,#PSR_EF|PSR_EM,gr7
+	movgs		gr7,psr
+	movsg		psr,gr7
+	srli		gr7,#24,gr7
+	bar
+
+	lddi		@(gr8,#__FPMEDIA_MSR(0)),gr4
+
+	movgs		gr4,msr0
+	movgs		gr5,msr1
+
+	lddfi		@(gr8,#__FPMEDIA_ACC(0)),fr16
+	lddfi		@(gr8,#__FPMEDIA_ACC(2)),fr18
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(0)),fr20
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(1)),fr21
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(2)),fr22
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(3)),fr23
+
+	mwtacc		fr16,acc0
+	mwtacc		fr17,acc1
+	mwtacc		fr18,acc2
+	mwtacc		fr19,acc3
+	mwtaccg		fr20,accg0
+	mwtaccg		fr21,accg1
+	mwtaccg		fr22,accg2
+	mwtaccg		fr23,accg3
+
+	# some CPUs have extra ACCx and ACCGx regs and maybe FSRx regs
+	subicc.p	gr7,#0x50,gr0,icc0
+	subicc		gr7,#0x31,gr0,icc1
+	beq		icc0,#0,__restore_acc_fr451
+	beq		icc1,#0,__restore_acc_fr555
+__restore_acc_cont:
+
+	# some CPU's have GR32-GR63
+	setlos		#HSR0_FRHE,gr4
+	andcc		gr6,gr4,gr0,icc0
+	beq		icc0,#1,__restore_skip_gr32_gr63
+
+	lddi		@(gr8,#__INT_GR(32)),gr32
+	lddi		@(gr8,#__INT_GR(34)),gr34
+	lddi		@(gr8,#__INT_GR(36)),gr36
+	lddi		@(gr8,#__INT_GR(38)),gr38
+	lddi		@(gr8,#__INT_GR(40)),gr40
+	lddi		@(gr8,#__INT_GR(42)),gr42
+	lddi		@(gr8,#__INT_GR(44)),gr44
+	lddi		@(gr8,#__INT_GR(46)),gr46
+	lddi		@(gr8,#__INT_GR(48)),gr48
+	lddi		@(gr8,#__INT_GR(50)),gr50
+	lddi		@(gr8,#__INT_GR(52)),gr52
+	lddi		@(gr8,#__INT_GR(54)),gr54
+	lddi		@(gr8,#__INT_GR(56)),gr56
+	lddi		@(gr8,#__INT_GR(58)),gr58
+	lddi		@(gr8,#__INT_GR(60)),gr60
+	lddi		@(gr8,#__INT_GR(62)),gr62
+__restore_skip_gr32_gr63:
+
+	# all CPU's have FR0-FR31
+	lddfi		@(gr8,#__FPMEDIA_FR( 0)),fr0
+	lddfi		@(gr8,#__FPMEDIA_FR( 2)),fr2
+	lddfi		@(gr8,#__FPMEDIA_FR( 4)),fr4
+	lddfi		@(gr8,#__FPMEDIA_FR( 6)),fr6
+	lddfi		@(gr8,#__FPMEDIA_FR( 8)),fr8
+	lddfi		@(gr8,#__FPMEDIA_FR(10)),fr10
+	lddfi		@(gr8,#__FPMEDIA_FR(12)),fr12
+	lddfi		@(gr8,#__FPMEDIA_FR(14)),fr14
+	lddfi		@(gr8,#__FPMEDIA_FR(16)),fr16
+	lddfi		@(gr8,#__FPMEDIA_FR(18)),fr18
+	lddfi		@(gr8,#__FPMEDIA_FR(20)),fr20
+	lddfi		@(gr8,#__FPMEDIA_FR(22)),fr22
+	lddfi		@(gr8,#__FPMEDIA_FR(24)),fr24
+	lddfi		@(gr8,#__FPMEDIA_FR(26)),fr26
+	lddfi		@(gr8,#__FPMEDIA_FR(28)),fr28
+	lddfi.p		@(gr8,#__FPMEDIA_FR(30)),fr30
+
+	# some CPU's have FR32-FR63
+	setlos		#HSR0_FRHE,gr4
+	andcc		gr6,gr4,gr0,icc0
+	beq		icc0,#1,__restore_skip_fr32_fr63
+
+	lddfi		@(gr8,#__FPMEDIA_FR(32)),fr32
+	lddfi		@(gr8,#__FPMEDIA_FR(34)),fr34
+	lddfi		@(gr8,#__FPMEDIA_FR(36)),fr36
+	lddfi		@(gr8,#__FPMEDIA_FR(38)),fr38
+	lddfi		@(gr8,#__FPMEDIA_FR(40)),fr40
+	lddfi		@(gr8,#__FPMEDIA_FR(42)),fr42
+	lddfi		@(gr8,#__FPMEDIA_FR(44)),fr44
+	lddfi		@(gr8,#__FPMEDIA_FR(46)),fr46
+	lddfi		@(gr8,#__FPMEDIA_FR(48)),fr48
+	lddfi		@(gr8,#__FPMEDIA_FR(50)),fr50
+	lddfi		@(gr8,#__FPMEDIA_FR(52)),fr52
+	lddfi		@(gr8,#__FPMEDIA_FR(54)),fr54
+	lddfi		@(gr8,#__FPMEDIA_FR(56)),fr56
+	lddfi		@(gr8,#__FPMEDIA_FR(58)),fr58
+	lddfi		@(gr8,#__FPMEDIA_FR(60)),fr60
+	lddfi		@(gr8,#__FPMEDIA_FR(62)),fr62
+__restore_skip_fr32_fr63:
+
+	lddi		@(gr8,#__FPMEDIA_FNER(0)),gr4
+	movsg		fner0,gr4
+	movsg		fner1,gr5
+	or.p		gr9,gr9,gr8
+	bralr
+
+	# the FR451 also has ACC8-11/ACCG8-11 regs (but not 4-7...)
+__restore_acc_fr451:
+	lddfi		@(gr8,#__FPMEDIA_ACC(4)),fr16
+	lddfi		@(gr8,#__FPMEDIA_ACC(6)),fr18
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(4)),fr20
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(5)),fr21
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(6)),fr22
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(7)),fr23
+
+	mwtacc		fr16,acc8
+	mwtacc		fr17,acc9
+	mwtacc		fr18,acc10
+	mwtacc		fr19,acc11
+	mwtaccg		fr20,accg8
+	mwtaccg		fr21,accg9
+	mwtaccg		fr22,accg10
+	mwtaccg		fr23,accg11
+	bra		__restore_acc_cont
+
+	# the FR555 also has ACC4-7/ACCG4-7 regs and an FSR0 reg
+__restore_acc_fr555:
+	lddfi		@(gr8,#__FPMEDIA_ACC(4)),fr16
+	lddfi		@(gr8,#__FPMEDIA_ACC(6)),fr18
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(4)),fr20
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(5)),fr21
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(6)),fr22
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(7)),fr23
+
+	mnop.p
+	mwtacc		fr16,acc4
+	mnop.p
+	mwtacc		fr17,acc5
+	mnop.p
+	mwtacc		fr18,acc6
+	mnop.p
+	mwtacc		fr19,acc7
+	mnop.p
+	mwtaccg		fr20,accg4
+	mnop.p
+	mwtaccg		fr21,accg5
+	mnop.p
+	mwtaccg		fr22,accg6
+	mnop.p
+	mwtaccg		fr23,accg7
+
+	ldi		@(gr8,#__FPMEDIA_FSR(0)),gr4
+	movgs		gr4,fsr0
+
+	bra		__restore_acc_cont
+
+
+###############################################################################
+#
+# save extra general regs and FP/Media regs
+# - void save_user_regs(struct user_context *target)
+#
+###############################################################################
+	.globl		save_user_regs
+save_user_regs:
+	movsg		hsr0,gr6
+	ori		gr6,#HSR0_GRHE|HSR0_FRLE|HSR0_FRHE,gr6
+	movgs		gr6,hsr0
+	movsg		hsr0,gr6
+
+	movsg		psr,gr7
+	ori		gr7,#PSR_EF|PSR_EM,gr7
+	movgs		gr7,psr
+	movsg		psr,gr7
+	srli		gr7,#24,gr7
+	bar
+
+	movsg		fner0,gr4
+	movsg		fner1,gr5
+	stdi.p		gr4,@(gr8,#__FPMEDIA_FNER(0))
+
+	# some CPU's have GR32-GR63
+	setlos		#HSR0_GRHE,gr4
+	andcc		gr6,gr4,gr0,icc0
+	beq		icc0,#1,__save_skip_gr32_gr63
+
+	stdi		gr32,@(gr8,#__INT_GR(32))
+	stdi		gr34,@(gr8,#__INT_GR(34))
+	stdi		gr36,@(gr8,#__INT_GR(36))
+	stdi		gr38,@(gr8,#__INT_GR(38))
+	stdi		gr40,@(gr8,#__INT_GR(40))
+	stdi		gr42,@(gr8,#__INT_GR(42))
+	stdi		gr44,@(gr8,#__INT_GR(44))
+	stdi		gr46,@(gr8,#__INT_GR(46))
+	stdi		gr48,@(gr8,#__INT_GR(48))
+	stdi		gr50,@(gr8,#__INT_GR(50))
+	stdi		gr52,@(gr8,#__INT_GR(52))
+	stdi		gr54,@(gr8,#__INT_GR(54))
+	stdi		gr56,@(gr8,#__INT_GR(56))
+	stdi		gr58,@(gr8,#__INT_GR(58))
+	stdi		gr60,@(gr8,#__INT_GR(60))
+	stdi		gr62,@(gr8,#__INT_GR(62))
+__save_skip_gr32_gr63:
+
+	# all CPU's have FR0-FR31
+	stdfi		fr0 ,@(gr8,#__FPMEDIA_FR( 0))
+	stdfi		fr2 ,@(gr8,#__FPMEDIA_FR( 2))
+	stdfi		fr4 ,@(gr8,#__FPMEDIA_FR( 4))
+	stdfi		fr6 ,@(gr8,#__FPMEDIA_FR( 6))
+	stdfi		fr8 ,@(gr8,#__FPMEDIA_FR( 8))
+	stdfi		fr10,@(gr8,#__FPMEDIA_FR(10))
+	stdfi		fr12,@(gr8,#__FPMEDIA_FR(12))
+	stdfi		fr14,@(gr8,#__FPMEDIA_FR(14))
+	stdfi		fr16,@(gr8,#__FPMEDIA_FR(16))
+	stdfi		fr18,@(gr8,#__FPMEDIA_FR(18))
+	stdfi		fr20,@(gr8,#__FPMEDIA_FR(20))
+	stdfi		fr22,@(gr8,#__FPMEDIA_FR(22))
+	stdfi		fr24,@(gr8,#__FPMEDIA_FR(24))
+	stdfi		fr26,@(gr8,#__FPMEDIA_FR(26))
+	stdfi		fr28,@(gr8,#__FPMEDIA_FR(28))
+	stdfi.p		fr30,@(gr8,#__FPMEDIA_FR(30))
+
+	# some CPU's have FR32-FR63
+	setlos		#HSR0_FRHE,gr4
+	andcc		gr6,gr4,gr0,icc0
+	beq		icc0,#1,__save_skip_fr32_fr63
+
+	stdfi		fr32,@(gr8,#__FPMEDIA_FR(32))
+	stdfi		fr34,@(gr8,#__FPMEDIA_FR(34))
+	stdfi		fr36,@(gr8,#__FPMEDIA_FR(36))
+	stdfi		fr38,@(gr8,#__FPMEDIA_FR(38))
+	stdfi		fr40,@(gr8,#__FPMEDIA_FR(40))
+	stdfi		fr42,@(gr8,#__FPMEDIA_FR(42))
+	stdfi		fr44,@(gr8,#__FPMEDIA_FR(44))
+	stdfi		fr46,@(gr8,#__FPMEDIA_FR(46))
+	stdfi		fr48,@(gr8,#__FPMEDIA_FR(48))
+	stdfi		fr50,@(gr8,#__FPMEDIA_FR(50))
+	stdfi		fr52,@(gr8,#__FPMEDIA_FR(52))
+	stdfi		fr54,@(gr8,#__FPMEDIA_FR(54))
+	stdfi		fr56,@(gr8,#__FPMEDIA_FR(56))
+	stdfi		fr58,@(gr8,#__FPMEDIA_FR(58))
+	stdfi		fr60,@(gr8,#__FPMEDIA_FR(60))
+	stdfi		fr62,@(gr8,#__FPMEDIA_FR(62))
+__save_skip_fr32_fr63:
+
+	mrdacc		acc0 ,fr4
+	mrdacc		acc1 ,fr5
+
+	stdfi.p		fr4 ,@(gr8,#__FPMEDIA_ACC(0))
+
+	mrdacc		acc2 ,fr6
+	mrdacc		acc3 ,fr7
+
+	stdfi.p		fr6 ,@(gr8,#__FPMEDIA_ACC(2))
+
+	mrdaccg		accg0,fr4
+	stbfi.p		fr4 ,@(gr8,#__FPMEDIA_ACCG(0))
+
+	mrdaccg		accg1,fr5
+	stbfi.p		fr5 ,@(gr8,#__FPMEDIA_ACCG(1))
+
+	mrdaccg		accg2,fr6
+	stbfi.p		fr6 ,@(gr8,#__FPMEDIA_ACCG(2))
+
+	mrdaccg		accg3,fr7
+	stbfi		fr7 ,@(gr8,#__FPMEDIA_ACCG(3))
+
+	movsg		msr0 ,gr4
+	movsg		msr1 ,gr5
+
+	stdi		gr4 ,@(gr8,#__FPMEDIA_MSR(0))
+
+	# some CPUs have extra ACCx and ACCGx regs and maybe FSRx regs
+	subicc.p	gr7,#0x50,gr0,icc0
+	subicc		gr7,#0x31,gr0,icc1
+	beq		icc0,#0,__save_acc_fr451
+	beq		icc1,#0,__save_acc_fr555
+__save_acc_cont:
+
+	lddfi		@(gr8,#__FPMEDIA_FR(4)),fr4
+	lddfi.p		@(gr8,#__FPMEDIA_FR(6)),fr6
+	bralr
+
+	# the FR451 also has ACC8-11/ACCG8-11 regs (but not 4-7...)
+__save_acc_fr451:
+	mrdacc		acc8 ,fr4
+	mrdacc		acc9 ,fr5
+
+	stdfi.p		fr4 ,@(gr8,#__FPMEDIA_ACC(4))
+
+	mrdacc		acc10,fr6
+	mrdacc		acc11,fr7
+
+	stdfi.p		fr6 ,@(gr8,#__FPMEDIA_ACC(6))
+
+	mrdaccg		accg8,fr4
+	stbfi.p		fr4 ,@(gr8,#__FPMEDIA_ACCG(4))
+
+	mrdaccg		accg9,fr5
+	stbfi.p		fr5 ,@(gr8,#__FPMEDIA_ACCG(5))
+
+	mrdaccg		accg10,fr6
+	stbfi.p		fr6 ,@(gr8,#__FPMEDIA_ACCG(6))
+
+	mrdaccg		accg11,fr7
+	stbfi		fr7 ,@(gr8,#__FPMEDIA_ACCG(7))
+	bra		__save_acc_cont
+
+	# the FR555 also has ACC4-7/ACCG4-7 regs and an FSR0 reg
+__save_acc_fr555:
+	mnop.p
+	mrdacc		acc4 ,fr4
+	mnop.p
+	mrdacc		acc5 ,fr5
+
+	stdfi		fr4 ,@(gr8,#__FPMEDIA_ACC(4))
+
+	mnop.p
+	mrdacc		acc6 ,fr6
+	mnop.p
+	mrdacc		acc7 ,fr7
+
+	stdfi		fr6 ,@(gr8,#__FPMEDIA_ACC(6))
+
+	mnop.p
+	mrdaccg		accg4,fr4
+	stbfi		fr4 ,@(gr8,#__FPMEDIA_ACCG(4))
+
+	mnop.p
+	mrdaccg		accg5,fr5
+	stbfi		fr5 ,@(gr8,#__FPMEDIA_ACCG(5))
+
+	mnop.p
+	mrdaccg		accg6,fr6
+	stbfi		fr6 ,@(gr8,#__FPMEDIA_ACCG(6))
+
+	mnop.p
+	mrdaccg		accg7,fr7
+	stbfi		fr7 ,@(gr8,#__FPMEDIA_ACCG(7))
+
+	movsg		fsr0 ,gr4
+	sti		gr4 ,@(gr8,#__FPMEDIA_FSR(0))
+	bra		__save_acc_cont
diff -urN linux-2.4.29/arch/frv/kernel/sysctl.c linux-2.4.29-uc1/arch/frv/kernel/sysctl.c
--- linux-2.4.29/arch/frv/kernel/sysctl.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/sysctl.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,206 @@
+/* sysctl.c: implementation of /proc/sys files relating to FRV specifically
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+
+static const char frv_cache_wback[] = "wback";
+static const char frv_cache_wthru[] = "wthru";
+
+static void frv_change_dcache_mode(unsigned long newmode)
+{
+	unsigned long flags, hsr0;
+
+	local_irq_save(flags);
+
+	hsr0 = __get_HSR(0);
+	hsr0 &= ~HSR0_DCE;
+	__set_HSR(0, hsr0);
+
+	asm volatile("	dcef	@(gr0,gr0),#1	\n"
+		     "	membar			\n"
+		     : : : "memory"
+		     );
+
+	hsr0 = (hsr0 & ~HSR0_CBM) | newmode;
+	__set_HSR(0, hsr0);
+	hsr0 |= HSR0_DCE;
+	__set_HSR(0, hsr0);
+
+	local_irq_restore(flags);
+
+	//printk("HSR0 now %08lx\n", hsr0);
+}
+
+/*****************************************************************************/
+/*
+ * handle requests to dynamically switch the write caching mode delivered by /proc
+ */
+static int procctl_frv_cachemode(ctl_table *table, int write, struct file *filp,
+				 void *buffer, size_t *lenp)
+{
+	unsigned long hsr0;
+	char buff[8];
+	int len;
+
+	len = *lenp;
+
+	if (write) {
+		/* potential state change */
+		if (len <= 1 || len > sizeof(buff) - 1)
+			return -EINVAL;
+
+		if (copy_from_user(buff, buffer, len) != 0)
+			return -EFAULT;
+
+		if (buff[len - 1] == '\n')
+			buff[len - 1] = '\0';
+		else
+			buff[len] = '\0';
+
+		if (strcmp(buff, frv_cache_wback) == 0) {
+			/* switch dcache into write-back mode */
+			frv_change_dcache_mode(HSR0_CBM_COPY_BACK);
+			return 0;
+		}
+
+		if (strcmp(buff, frv_cache_wthru) == 0) {
+			/* switch dcache into write-through mode */
+			frv_change_dcache_mode(HSR0_CBM_WRITE_THRU);
+			return 0;
+		}
+
+		return -EINVAL;
+	}
+
+	/* read the state */
+	if (filp->f_pos > 0) {
+		*lenp = 0;
+		return 0;
+	}
+
+	hsr0 = __get_HSR(0);
+	switch (hsr0 & HSR0_CBM) {
+	case HSR0_CBM_WRITE_THRU:
+		memcpy(buff, frv_cache_wthru, sizeof(frv_cache_wthru) - 1);
+		buff[sizeof(frv_cache_wthru) - 1] = '\n';
+		len = sizeof(frv_cache_wthru);
+		break;
+	default:
+		memcpy(buff, frv_cache_wback, sizeof(frv_cache_wback) - 1);
+		buff[sizeof(frv_cache_wback) - 1] = '\n';
+		len = sizeof(frv_cache_wback);
+		break;
+	}
+
+	if (len > *lenp)
+		len = *lenp;
+
+	if (copy_to_user(buffer, buff, len) != 0)
+		return -EFAULT;
+
+	*lenp = len;
+	filp->f_pos = len;
+	return 0;
+
+} /* end procctl_frv_cachemode() */
+
+/*****************************************************************************/
+/*
+ * permit the mm_struct the nominated process is using have its MMU context ID pinned
+ */
+#ifndef NO_MM
+static int procctl_frv_pin_cxnr(ctl_table *table, int write, struct file *filp,
+				void *buffer, size_t *lenp)
+{
+	pid_t pid;
+	char buff[16], *p;
+	int len;
+
+	len = *lenp;
+
+	if (write) {
+		/* potential state change */
+		if (len <= 1 || len > sizeof(buff) - 1)
+			return -EINVAL;
+
+		if (copy_from_user(buff, buffer, len) != 0)
+			return -EFAULT;
+
+		if (buff[len - 1] == '\n')
+			buff[len - 1] = '\0';
+		else
+			buff[len] = '\0';
+
+		pid = simple_strtoul(buff, &p, 10);
+		if (*p)
+			return -EINVAL;
+
+		return cxn_pin_by_pid(pid);
+	}
+
+	/* read the currently pinned CXN */
+	if (filp->f_pos > 0) {
+		*lenp = 0;
+		return 0;
+	}
+
+	len = snprintf(buff, sizeof(buff), "%d\n", cxn_pinned);
+	if (len > *lenp)
+		len = *lenp;
+
+	if (copy_to_user(buffer, buff, len) != 0)
+		return -EFAULT;
+
+	*lenp = len;
+	filp->f_pos = len;
+	return 0;
+
+} /* end procctl_frv_pin_cxnr() */
+#endif
+
+/*
+ * FR-V specific sysctls
+ */
+static struct ctl_table frv_table[] =
+{
+	{ 1, "cache-mode",	NULL, 0, 0644, NULL, &procctl_frv_cachemode },
+#ifndef NO_MM
+	{ 2, "pin-cxnr",	NULL, 0, 0644, NULL, &procctl_frv_pin_cxnr },
+#endif
+	{ 0 }
+};
+
+/*
+ * Use a temporary sysctl number. Horrid, but will be cleaned up in 2.6
+ * when all the PM interfaces exist nicely.
+ */
+#define CTL_FRV 9898
+static struct ctl_table frv_dir_table[] =
+{
+	{CTL_FRV, "frv", NULL, 0, 0555, frv_table},
+	{0}
+};
+
+/*
+ * Initialize power interface
+ */
+static int __init frv_sysctl_init(void)
+{
+	register_sysctl_table(frv_dir_table, 1);
+	return 0;
+}
+
+__initcall(frv_sysctl_init);
diff -urN linux-2.4.29/arch/frv/kernel/sys_frv.c linux-2.4.29-uc1/arch/frv/kernel/sys_frv.c
--- linux-2.4.29/arch/frv/kernel/sys_frv.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/sys_frv.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,224 @@
+/*
+ * linux/arch/frvnommu/kernel/sys_frv.c
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/FRV
+ * platform.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/ipc.h>
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+asmlinkage long sys_pipe(unsigned long * fildes)
+{
+	int fd[2];
+	int error;
+
+	error = do_pipe(fd);
+	if (!error) {
+		if (copy_to_user(fildes, fd, 2*sizeof(int)))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+			  unsigned long prot, unsigned long flags,
+			  unsigned long fd, unsigned long pgoff)
+{
+	int error = -EBADF;
+	struct file * file = NULL;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (!(flags & MAP_ANONYMOUS)) {
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+
+	/* As with sparc32, make sure the shift for mmap2 is constant
+	   (12), no matter what PAGE_SIZE we have.... */
+
+	/* But unlike sparc32, don't just silently break if we're
+	   trying to map something we can't */
+	if (pgoff & ((1<<(PAGE_SHIFT-12))-1))
+		return -EINVAL;
+
+	pgoff >>= (PAGE_SHIFT - 12);
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+
+#if 0 /* DAVIDM - do we want this */
+struct mmap_arg_struct64 {
+	__u32 addr;
+	__u32 len;
+	__u32 prot;
+	__u32 flags;
+	__u64 offset; /* 64 bits */
+	__u32 fd;
+};
+
+asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
+{
+	int error = -EFAULT;
+	struct file * file = NULL;
+	struct mmap_arg_struct64 a;
+	unsigned long pgoff;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+
+	if ((long)a.offset & ~PAGE_MASK)
+		return -EINVAL;
+
+	pgoff = a.offset >> PAGE_SHIFT;
+	if ((a.offset >> PAGE_SHIFT) != pgoff)
+		return -EINVAL;
+
+	if (!(a.flags & MAP_ANONYMOUS)) {
+		error = -EBADF;
+		file = fget(a.fd);
+		if (!file)
+			goto out;
+	}
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+#endif
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+asmlinkage long sys_ipc(unsigned long call,
+			unsigned long first,
+			unsigned long second,
+			unsigned long third,
+			void *ptr,
+			unsigned long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	if (call <= SEMCTL)
+		switch (call) {
+		case SEMOP:
+			return sys_semop (first, (struct sembuf *)ptr, second);
+		case SEMGET:
+			return sys_semget (first, second, third);
+		case SEMCTL: {
+			union semun fourth;
+			if (!ptr)
+				return -EINVAL;
+			if (get_user(fourth.__pad, (void **) ptr))
+				return -EFAULT;
+			return sys_semctl (first, second, third, fourth);
+			}
+		default:
+			return -EINVAL;
+		}
+	if (call <= MSGCTL) 
+		switch (call) {
+		case MSGSND:
+			return sys_msgsnd (first, (struct msgbuf *) ptr, 
+					  second, third);
+		case MSGRCV:
+			switch (version) {
+			case 0: {
+				struct ipc_kludge tmp;
+				if (!ptr)
+					return -EINVAL;
+				if (copy_from_user (&tmp,
+						    (struct ipc_kludge *)ptr,
+						    sizeof (tmp)))
+					return -EFAULT;
+				return sys_msgrcv (first, tmp.msgp, second,
+						   tmp.msgtyp, third);
+				}
+			default:
+				return sys_msgrcv (first,
+						   (struct msgbuf *) ptr,
+						   second, fifth, third);
+			}
+		case MSGGET:
+			return sys_msgget ((key_t) first, second);
+		case MSGCTL:
+			return sys_msgctl (first, second,
+					   (struct msqid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+	if (call <= SHMCTL) 
+		switch (call) {
+		case SHMAT:
+			switch (version) {
+			default: {
+				ulong raddr;
+				ret = sys_shmat (first, (char *) ptr,
+						 second, &raddr);
+				if (ret)
+					return ret;
+				return put_user (raddr, (ulong *) third);
+			}
+			}
+		case SHMDT: 
+			return sys_shmdt ((char *)ptr);
+		case SHMGET:
+			return sys_shmget (first, second, third);
+		case SHMCTL:
+			return sys_shmctl (first, second,
+					   (struct shmid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+
+	return -EINVAL;
+}
+
+/* sys_cacheflush -- flush (part of) the processor cache.  */
+asmlinkage
+long sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
+{
+	return -EINVAL;
+}
+
+asmlinkage long sys_getpagesize(void)
+{
+	return PAGE_SIZE;
+}
diff -urN linux-2.4.29/arch/frv/kernel/time.c linux-2.4.29-uc1/arch/frv/kernel/time.c
--- linux-2.4.29/arch/frv/kernel/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/time.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,262 @@
+/*
+ *  linux/arch/m68k/kernel/time.c
+ *
+ *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *
+ * This file contains the m68k-specific time handling details.
+ * Most of the stuff is located in the machine specific files.
+ *
+ * 1997-09-10	Updated NTP code according to technical memorandum Jan '96
+ *		"A Kernel Model for Precision Timekeeping" by Dave Mills
+ */
+
+/* 2002-8-13 George Anzinger  Modified for High res timers: 
+ *                            Copyright (C) 2002 MontaVista Software
+ */
+#define _INCLUDED_FROM_TIME_C
+#include <linux/config.h> /* CONFIG_HEARTBEAT */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/timer-regs.h>
+#include <asm/mb-regs.h>
+#include <asm/irc-regs.h>
+#include <asm/mb86943a.h>
+#include <asm/irq-routing.h>
+
+#include <linux/timex.h>
+
+unsigned long __nongprelbss __clkin_clock_speed_HZ;
+unsigned long __nongprelbss __ext_bus_clock_speed_HZ;
+unsigned long __nongprelbss __res_bus_clock_speed_HZ;
+unsigned long __nongprelbss __sdram_clock_speed_HZ;
+unsigned long __nongprelbss __core_bus_clock_speed_HZ;
+unsigned long __nongprelbss __core_clock_speed_HZ;
+unsigned long __nongprelbss __dsu_clock_speed_HZ;
+unsigned long __nongprelbss __serial_clock_speed_HZ;
+unsigned long __delay_loops_MHz;
+
+unsigned int   __arch_latch;
+unsigned long  __arch_timer_clock_hz;
+
+static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs);
+
+static struct irqaction timer_irq  = {
+	timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL
+};
+
+static inline int set_rtc_mmss(unsigned long nowtime)
+{
+	return -1;
+}
+
+static inline void do_profile (unsigned long pc)
+{
+	if (prof_buffer && current->pid) {
+		pc -= (unsigned long) &_stext;
+		pc >>= prof_shift;
+		if (pc < prof_len)
+			++prof_buffer[pc];
+		else
+		/*
+		 * Don't ignore out-of-bounds PC values silently,
+		 * put them into the last histogram slot, so if
+		 * present, they will show up as a sharp peak.
+		 */
+			++prof_buffer[prof_len-1];
+	}
+}
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
+{
+	/* last time the cmos clock got updated */
+	static long last_rtc_update = 0;
+
+	/* may need to kick the hardware timer */
+	do_timer(regs);
+
+	if (!user_mode(regs))
+		do_profile(regs->pc);
+
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
+	    xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
+		if (set_rtc_mmss(xtime.tv_sec) == 0)
+			last_rtc_update = xtime.tv_sec;
+		else
+			last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	}
+
+#ifdef CONFIG_HEARTBEAT
+	static unsigned short n;
+	n++;
+	__set_LEDS(n);
+#endif /* CONFIG_HEARTBEAT */
+}
+
+void time_divisor_init(void)
+{
+	unsigned short pre, prediv;
+
+	/* set the scheduling timer going */
+	pre = 1;
+	prediv = 4;
+
+	__arch_timer_clock_hz = __res_bus_clock_speed_HZ / pre / (1 << prediv);
+	__arch_latch = __arch_timer_clock_hz / HZ;
+
+	__set_TPRV(pre);
+	__set_TxCKSL_DATA(0, prediv);
+	__set_TCTR(TCTR_SC_CTR0 | TCTR_RL_RW_LH8 | TCTR_MODE_2);
+	__set_TCSR_DATA(0, __arch_latch & 0xff);
+	__set_TCSR_DATA(0, __arch_latch >> 8);
+}
+
+void time_init(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+
+	extern void arch_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec);
+
+	/* FIX by dqg : Set to zero for platforms that don't have tod */
+	/* without this time is undefined and can overflow time_t, causing  */
+	/* very stange errors */
+	year = 1980;
+	mon = day = 1;
+	hour = min = sec = 0;
+	arch_gettod (&year, &mon, &day, &hour, &min, &sec);
+
+	if ((year += 1900) < 1970)
+		year += 100;
+	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+	xtime.tv_usec = 0;
+
+	time_divisor_init();
+	/* install scheduling interrupt handler */
+	setup_irq(IRQ_CPU_TIMER0, &timer_irq);
+}
+
+extern rwlock_t xtime_lock;
+extern u64 __attribute__((section(".sdata"))) jiffies_64;
+
+static unsigned long do_gettimeoffset(void)
+{
+	int count;
+	static int first_time = 1;
+	static int count_p;
+	static unsigned long jiffies_p = 0;
+
+	if (first_time) {
+	    first_time = 0;
+	    count_p = __arch_latch;    /* for the first call after boot */
+	}
+
+	/*
+	 * cache volatile jiffies temporarily; we have IRQs turned off. 
+	 */
+	unsigned long jiffies_t;
+
+	/* timer count may underflow right here */
+	__set_TCTR(TCTR_SC_CTR0 | TCTR_RL_LATCH);  /* latch the count ASAP */
+
+	count = __get_TCSR_DATA(0);	/* read the latched count */
+
+ 	jiffies_t = jiffies;
+
+	count |= __get_TCSR_DATA(0) << 8;
+	
+	/*
+	 * avoiding timer inconsistencies (they are rare, but they happen)...
+	 */
+
+	if( jiffies_t == jiffies_p ) {
+		if( count > count_p ) {
+			/* the nutcase */
+
+			if (__get_IRL() == IRQ_TIMER0_LEVEL) {
+				/*
+				 * We cannot detect lost timer interrupts ... 
+				 * well, that's why we call them lost, don't we? :)
+				 * [hmm, on the Pentium and Alpha we can ... sort of]
+				 */
+				count -= __arch_latch;
+			} else {
+				printk("do_gettimeoffset(): hardware timer problem?\n");
+			}
+		}
+	} else
+		jiffies_p = jiffies_t;
+
+	count_p = count;
+
+	count = ((__arch_latch-1) - count) * tick;
+	count = (count + __arch_latch/2) / __arch_latch;
+
+	return count;
+}
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+	extern volatile unsigned long wall_jiffies;
+	unsigned long flags;
+	unsigned long usec, sec, lost;
+
+	read_lock_irqsave(&xtime_lock, flags);
+	usec = do_gettimeoffset();
+	lost = jiffies - wall_jiffies;
+	if (lost)
+		usec += lost * (1000000/HZ);
+	sec = xtime.tv_sec;
+	usec += xtime.tv_usec;
+	read_unlock_irqrestore(&xtime_lock, flags);
+
+	while (usec >= 1000000) {
+		usec -= 1000000;
+		sec++;
+	}
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	write_lock_irq(&xtime_lock);
+	/* This is revolting. We need to set the xtime.tv_usec
+	 * correctly. However, the value in this location is
+	 * is value at the last tick.
+	 * Discover what correction gettimeofday
+	 * would have done, and then undo it!
+	 */
+	while (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+
+	xtime = *tv;
+	time_adjust = 0;		/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+	write_unlock_irq(&xtime_lock);
+}
diff -urN linux-2.4.29/arch/frv/kernel/traps.c linux-2.4.29-uc1/arch/frv/kernel/traps.c
--- linux-2.4.29/arch/frv/kernel/traps.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/traps.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,434 @@
+/* traps.c: high-level exception handler for FR-V
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/a.out.h>
+#include <linux/user.h>
+#include <linux/string.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/fpu.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/siginfo.h>
+#include <asm/unaligned.h>
+
+void show_backtrace(struct pt_regs *, unsigned long);
+
+extern asmlinkage void __break_hijack_kernel_event(void);
+
+/*****************************************************************************/
+/*
+ * instruction access error
+ */
+asmlinkage void insn_access_error(unsigned long esfr1, unsigned long epcr0, unsigned long esr0)
+{
+	siginfo_t info;
+
+	die_if_kernel("-- Insn Access Error --\n"
+		      "EPCR0 : %08lx\n"
+		      "ESR0  : %08lx\n",
+		      epcr0, esr0);
+
+	info.si_signo	= SIGSEGV;
+	info.si_code	= SEGV_ACCERR;
+	info.si_errno	= 0;
+	info.si_addr	= (void *) ((epcr0 & EPCR0_V) ? (epcr0 & EPCR0_PC) : __frame->pc);
+
+	force_sig_info(info.si_signo, &info, current);
+} /* end insn_access_error() */
+
+/*****************************************************************************/
+/*
+ * handler for:
+ * - illegal instruction
+ * - privileged instruction
+ * - unsupported trap
+ * - debug exceptions
+ */
+asmlinkage void illegal_instruction(unsigned long esfr1, unsigned long epcr0, unsigned long esr0)
+{
+	siginfo_t info;
+
+	die_if_kernel("-- Illegal Instruction --\n"
+		      "EPCR0 : %08lx\n"
+		      "ESR0  : %08lx\n"
+		      "ESFR1 : %08lx\n",
+		      epcr0, esr0, esfr1);
+
+	info.si_errno	= 0;
+	info.si_addr	= (void *) ((epcr0 & EPCR0_PC) ? (epcr0 & EPCR0_PC) : __frame->pc);
+
+	switch (__frame->tbr & TBR_TT) {
+	case TBR_TT_ILLEGAL_INSTR:
+		info.si_signo	= SIGILL;
+		info.si_code	= ILL_ILLOPC;
+		break;
+	case TBR_TT_PRIV_INSTR:
+		info.si_signo	= SIGILL;
+		info.si_code	= ILL_PRVOPC;
+		break;
+	case TBR_TT_TRAP2 ... TBR_TT_TRAP126:
+		info.si_signo	= SIGILL;
+		info.si_code	= ILL_ILLTRP;
+		break;
+	/* GDB uses "tira gr0, #1" as a breakpoint instruction.  */
+	case TBR_TT_TRAP1:
+	case TBR_TT_BREAK:
+		info.si_signo	= SIGTRAP;
+		info.si_code	=
+			(__frame->__status & REG__STATUS_STEPPED) ? TRAP_TRACE : TRAP_BRKPT;
+		break;
+	}
+
+	force_sig_info(info.si_signo, &info, current);
+} /* end illegal_instruction() */
+
+/*****************************************************************************/
+/*
+ * 
+ */
+asmlinkage void media_exception(unsigned long msr0, unsigned long msr1)
+{
+	siginfo_t info;
+
+	die_if_kernel("-- Media Exception --\n"
+		      "MSR0 : %08lx\n"
+		      "MSR1 : %08lx\n",
+		      msr0, msr1);
+
+	info.si_signo	= SIGFPE;
+	info.si_code	= FPE_MDAOVF;
+	info.si_errno	= 0;
+	info.si_addr	= (void *) __frame->pc;
+
+	force_sig_info(info.si_signo, &info, current);
+} /* end media_exception() */
+
+/*****************************************************************************/
+/*
+ * instruction or data access exception
+ */
+asmlinkage void memory_access_exception(unsigned long esr0,
+					unsigned long ear0,
+					unsigned long epcr0)
+{
+	siginfo_t info;
+
+#ifndef CONFIG_UCLINUX
+	unsigned long fixup;
+
+	if ((esr0 & ESRx_EC) == ESRx_EC_DATA_ACCESS)
+		if (handle_misalignment(esr0, ear0, epcr0) == 0)
+			return;
+
+	if ((fixup = search_exception_table(__frame->pc)) != 0) {
+		__frame->pc = fixup;
+		return;
+	}
+#endif
+
+	die_if_kernel("-- Memory Access Exception --\n"
+		      "ESR0  : %08lx\n"
+		      "EAR0  : %08lx\n"
+		      "EPCR0 : %08lx\n",
+		      esr0, ear0, epcr0);
+
+	info.si_signo	= SIGSEGV;
+	info.si_code	= SEGV_ACCERR;
+	info.si_errno	= 0;
+	info.si_addr	= NULL;
+
+	if ((esr0 & (ESRx_VALID | ESR0_EAV)) == (ESRx_VALID | ESR0_EAV))
+		info.si_addr = (void *) ear0;
+
+	force_sig_info(info.si_signo, &info, current);
+
+} /* end memory_access_exception() */
+
+/*****************************************************************************/
+/*
+ * data access error
+ * - double-word data load from CPU control area (0xFExxxxxx)
+ * - read performed on inactive or self-refreshing SDRAM
+ * - error notification from slave device
+ * - misaligned address
+ * - access to out of bounds memory region
+ * - user mode accessing privileged memory region
+ * - write to R/O memory region
+ */
+asmlinkage void data_access_error(unsigned long esfr1, unsigned long esr15, unsigned long ear15)
+{
+	siginfo_t info;
+
+	die_if_kernel("-- Data Access Error --\n"
+		      "ESR15 : %08lx\n"
+		      "EAR15 : %08lx\n",
+		      esr15, ear15);
+
+	info.si_signo	= SIGSEGV;
+	info.si_code	= SEGV_ACCERR;
+	info.si_errno	= 0;
+	info.si_addr	= (void *)
+		(((esr15 & (ESRx_VALID|ESR15_EAV)) == (ESRx_VALID|ESR15_EAV)) ? ear15 : 0);
+
+	force_sig_info(info.si_signo, &info, current);
+} /* end data_access_error() */
+
+/*****************************************************************************/
+/*
+ * data store error - should only happen if accessing inactive or self-refreshing SDRAM
+ */
+asmlinkage void data_store_error(unsigned long esfr1, unsigned long esr15)
+{
+	die_if_kernel("-- Data Store Error --\n"
+		      "ESR15 : %08lx\n",
+		      esr15);
+	BUG();
+} /* end data_store_error() */
+
+/*****************************************************************************/
+/*
+ * 
+ */
+asmlinkage void division_exception(unsigned long esfr1, unsigned long esr0, unsigned long isr)
+{
+	siginfo_t info;
+
+	die_if_kernel("-- Division Exception --\n"
+		      "ESR0 : %08lx\n"
+		      "ISR  : %08lx\n",
+		      esr0, isr);
+
+	info.si_signo	= SIGFPE;
+	info.si_code	= FPE_INTDIV;
+	info.si_errno	= 0;
+	info.si_addr	= (void *) __frame->pc;
+
+	force_sig_info(info.si_signo, &info, current);
+} /* end division_exception() */
+
+/*****************************************************************************/
+/*
+ * 
+ */
+asmlinkage void compound_exception(unsigned long esfr1,
+				   unsigned long esr0, unsigned long esr14, unsigned long esr15,
+				   unsigned long msr0, unsigned long msr1)
+{
+	die_if_kernel("-- Compound Exception --\n"
+		      "ESR0  : %08lx\n"
+		      "ESR15 : %08lx\n"
+		      "ESR15 : %08lx\n"
+		      "MSR0  : %08lx\n"
+		      "MSR1  : %08lx\n",
+		      esr0, esr14, esr15, msr0, msr1);
+	BUG();
+} /* end compound_exception() */
+
+/*****************************************************************************/
+/*
+ * The architecture-independent backtrace generator
+ */
+void dump_stack(void)
+{
+	show_stack(0);
+}
+
+void show_stack(struct pt_regs *regs)
+{
+	if (!regs)
+		regs = __frame;
+}
+
+void show_trace_task(struct task_struct *tsk)
+{
+	printk("CONTEXT: stack=0x%lx frame=0x%p LR=0x%lx RET=0x%lx\n",
+	       tsk->thread.sp, tsk->thread.frame, tsk->thread.lr, tsk->thread.sched_lr);
+}
+
+static const char *regnames[] = {
+	"PSR ", "ISR ", "CCR ", "CCCR",
+	"LR  ", "LCR ", "PC  ", "_stt",
+	"sys ", "GR8*", "GNE0", "GNE1",
+	"IACH", "IACL",
+	"TBR ", "SP  ", "FP  ", "GR3 ",
+	"GR4 ", "GR5 ", "GR6 ", "GR7 ",
+	"GR8 ", "GR9 ", "GR10", "GR11",
+	"GR12", "GR13", "GR14", "GR15",
+	"GR16", "GR17", "GR18", "GR19",
+	"GR20", "GR21", "GR22", "GR23",
+	"GR24", "GR25", "GR26", "GR27",
+	"EFRM", "CURR", "GR30", "BFRM"
+};
+
+void show_regs(struct pt_regs *regs)
+{
+	uint32_t *reg;
+	int loop;
+
+	printk("\n");
+
+	printk("Frame: @%08x [%s]\n",
+	       (uint32_t) regs,
+	       regs->psr & PSR_S ? "kernel" : "user");
+
+	reg = (uint32_t *) regs;
+	for (loop = 0; loop < REG__END; loop++) {
+		printk("%s %08x", regnames[loop + 0], reg[loop + 0]);
+
+		if (loop == REG__END - 1 || loop % 5 == 4)
+			printk("\n");
+		else
+			printk(" | ");
+	}
+
+	printk("Process %s (pid: %d)\n", current->comm, current->pid);
+}
+
+void die_if_kernel(const char *str, ...)
+{
+	char buffer[256];
+	va_list va;
+
+	if (user_mode(__frame))
+		return;
+
+	va_start(va, str);
+	vsprintf(buffer, str, va);
+	va_end(va);
+
+	console_verbose();
+	printk("\n===================================\n");
+	printk("%s\n", buffer);
+	show_backtrace(__frame, 0);
+
+	__break_hijack_kernel_event();
+	do_exit(SIGSEGV);
+}
+
+/*****************************************************************************/
+/*
+ * dump the contents of an exception frame
+ */
+static void show_backtrace_regs(struct pt_regs *frame)
+{
+	uint32_t *reg;
+	int loop;
+
+	/* print the registers for this frame */
+	printk("<-- %s Frame: @%p -->\n",
+	       frame->psr & PSR_S ? "Kernel Mode" : "User Mode",
+	       frame);
+
+	reg = (uint32_t *) frame;
+	for (loop = 0; loop < REG__END; loop++) {
+		printk("%s %08x", regnames[loop + 0], reg[loop + 0]);
+
+		if (loop == REG__END - 1 || loop % 5 == 4)
+			printk("\n");
+		else
+			printk(" | ");
+	}
+
+	printk("--------\n");
+} /* end show_backtrace_regs() */
+
+/*****************************************************************************/
+/*
+ * generate a backtrace of the kernel stack
+ */
+void show_backtrace(struct pt_regs *frame, unsigned long sp)
+{
+	struct pt_regs *frame0;
+	unsigned long tos = 0, stop = 0, base;
+	int format;
+
+	base = ((((unsigned long) frame) + 8191) & ~8191) - sizeof(struct user_context);
+	frame0 = (struct pt_regs *) base;
+
+	if (sp) {
+		tos = sp;
+		stop = (unsigned long) frame;
+	}
+
+	printk("\nProcess %s (pid: %d)\n\n", current->comm, current->pid);
+
+	for (;;) {
+		/* dump stack segment between frames */
+		//printk("%08lx -> %08lx\n", tos, stop);
+		format = 0;
+		while (tos < stop) {
+			if (format == 0)
+				printk(" %04lx :", tos & 0xffff);
+
+			printk(" %08lx", *(unsigned long *) tos);
+
+			tos += 4;
+			format++;
+			if (format == 8) {
+				printk("\n");
+				format = 0;
+			}
+		}
+
+		if (format > 0)
+			printk("\n");
+
+		/* dump frame 0 outside of the loop */
+		if (frame == frame0)
+			break;
+
+		tos = frame->sp;
+		if (((unsigned long) frame) + sizeof(*frame) != tos) {
+			printk("-- TOS %08lx does not follow frame %p --\n",
+			       tos, frame);
+			break;
+		}
+
+		show_backtrace_regs(frame);
+
+		/* dump the stack between this frame and the next */
+		stop = (unsigned long) frame->next_frame;
+		if (stop != base &&
+		    (stop < tos ||
+		     stop > base ||
+		     (stop < base && stop + sizeof(*frame) > base) ||
+		     stop & 3)) {
+			printk("-- next_frame %08lx is invalid (range %08lx-%08lx) --\n",
+			       stop, tos, base);
+			break;
+		}
+
+		/* move to next frame */
+		frame = frame->next_frame;
+	}
+
+	/* we can always dump frame 0, even if the rest of the stack is corrupt */
+	show_backtrace_regs(frame0);
+
+} /* end show_backtrace() */
+
+/*****************************************************************************/
+/*
+ * initialise traps 
+ */
+void __init trap_init (void)
+{
+} /* end trap_init() */
diff -urN linux-2.4.29/arch/frv/kernel/uaccess.c linux-2.4.29-uc1/arch/frv/kernel/uaccess.c
--- linux-2.4.29/arch/frv/kernel/uaccess.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/kernel/uaccess.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,95 @@
+/* uaccess.c: userspace access functions
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/mm.h>
+#include <asm/uaccess.h>
+
+/*****************************************************************************/
+/*
+ * copy a null terminated string from userspace
+ */
+long strncpy_from_user(char *dst, const char *src, long count)
+{
+	unsigned long max;
+	char *p, ch;
+	long err = -EFAULT;
+
+	if (count < 0)
+		BUG();
+
+	p = dst;
+
+#ifdef NO_MM
+	if ((unsigned long) src < memory_start)
+		goto error;
+#endif
+
+	if ((unsigned long) src >= get_addr_limit())
+		goto error;
+
+	max = get_addr_limit() - (unsigned long) src;
+	if ((unsigned long) count > max) {
+		memset(dst + max, 0, count - max);
+		count = max;
+	}
+	
+	err = 0;
+	for (; count > 0; count--, p++, src++) {
+		__get_user_asm(err, ch, src, "ub", "=r");
+		if (err < 0)
+			goto error;
+		if (!ch)
+			break;
+		*p = ch;
+	}
+
+	err = p - dst; /* return length excluding NUL */
+
+ error:
+	if (count > 0)
+		memset(p, 0, count); /* clear remainder of buffer [security] */
+
+	return err;
+} /* end strncpy_from_user() */
+
+/*****************************************************************************/
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 on exception, a value greater than N if too long
+ */
+long strnlen_user(const char *src, long count)
+{
+	const char *p;
+	long err = 0;
+	char ch;
+
+	if (count < 0)
+		BUG();
+
+#ifdef NO_MM
+	if ((unsigned long) src < memory_start)
+		return 0;
+#endif
+
+	if ((unsigned long) src >= get_addr_limit())
+		return 0;
+
+	for (p = src; count > 0; count--, p++) {
+		__get_user_asm(err, ch, p, "ub", "=r");
+		if (err < 0)
+			return 0;
+		if (!ch)
+			break;
+	}
+
+	return p - src + 1; /* return length including NUL */
+} /* end strnlen_user() */
diff -urN linux-2.4.29/arch/frv/lib/__ashldi3.S linux-2.4.29-uc1/arch/frv/lib/__ashldi3.S
--- linux-2.4.29/arch/frv/lib/__ashldi3.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/lib/__ashldi3.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,41 @@
+/* __ashldi3.S:	64-bit arithmetic shift left
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+        .file		"__ashldi3.S"
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# unsigned long long __ashldi3(unsigned long long value [GR8:GR9], unsigned by [GR10])
+#
+###############################################################################
+        .globl		__ashldi3
+        .type		__ashldi3,@function
+__ashldi3:
+	andicc.p	gr10,#63,gr10,icc0
+	setlos		#32,gr5
+	andicc.p	gr10,#32,gr0,icc1
+	beqlr		icc0,#0
+	ckeq		icc1,cc4			; cc4 is true if 0<N<32
+
+	# deal with a shift in the range 1<=N<=31
+	csll.p		gr8,gr10,gr8	,cc4,#1		; MSW <<= N
+	csub		gr5,gr10,gr5	,cc4,#1		; M = 32 - N
+	csrl.p		gr9,gr5,gr4	,cc4,#1
+	csll		gr9,gr10,gr9	,cc4,#1		; LSW <<= N
+	cor.p		gr4,gr8,gr8	,cc4,#1		; MSW |= LSW >> M
+
+	# deal with a shift in the range 32<=N<=63
+	csll		gr9,gr10,gr8	,cc4,#0		; MSW = LSW << (N & 31 [implicit AND])
+	cor.p		gr0,gr0,gr9	,cc4,#0		; LSW = 0
+	bralr
+	.size		__ashldi3, .-__ashldi3
diff -urN linux-2.4.29/arch/frv/lib/__ashrdi3.S linux-2.4.29-uc1/arch/frv/lib/__ashrdi3.S
--- linux-2.4.29/arch/frv/lib/__ashrdi3.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/lib/__ashrdi3.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,42 @@
+/* __ashrdi3.S:	64-bit arithmetic shift right
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+        .file		"__ashrdi3.S"
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# signed long long __ashrdi3(signed long long value [GR8:GR9], unsigned by [GR10])
+#
+###############################################################################
+        .globl		__ashrdi3
+        .type		__ashrdi3,@function
+__ashrdi3:
+	andicc.p	gr10,#63,gr10,icc0
+	setlos		#32,gr5
+	andicc.p	gr10,#32,gr0,icc1
+	beqlr		icc0,#0
+	setlos.p	#31,gr6
+	ckeq		icc1,cc4			; cc4 is true if 0<N<32
+
+	# deal with a shift in the range 1<=N<=31
+	csrl.p		gr9,gr10,gr9	,cc4,#1		; LSW >>= N
+	csub		gr5,gr10,gr5	,cc4,#1		; M = 32 - N
+	csll.p		gr8,gr5,gr4	,cc4,#1
+	csra		gr8,gr10,gr8	,cc4,#1		; MSW >>= N
+	cor.p		gr4,gr9,gr9	,cc4,#1		; LSW |= MSW << M
+
+	# deal with a shift in the range 32<=N<=63
+	csra		gr8,gr10,gr9	,cc4,#0		; LSW = MSW >> (N & 31 [implicit AND])
+	csra.p		gr8,gr6,gr8	,cc4,#0		; MSW >>= 31
+	bralr
+	.size		__ashrdi3, .-__ashrdi3
diff -urN linux-2.4.29/arch/frv/lib/atomic-ops.S linux-2.4.29-uc1/arch/frv/lib/atomic-ops.S
--- linux-2.4.29/arch/frv/lib/atomic-ops.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/lib/atomic-ops.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,265 @@
+/* atomic-ops.S: kernel atomic operations
+ *
+ * For an explanation of how atomic ops work in this arch, see:
+ *   Documentation/fujitsu/frv/atomic-ops.txt
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/spr-regs.h>
+
+	.text
+	.balign 4
+
+###############################################################################
+#
+# unsigned long atomic_test_and_ANDNOT_mask(unsigned long mask, volatile unsigned long *v);
+#
+###############################################################################
+	.globl		atomic_test_and_ANDNOT_mask
+        .type		atomic_test_and_ANDNOT_mask,@function
+atomic_test_and_ANDNOT_mask:
+	not.p		gr8,gr10
+0:
+	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
+	ckeq		icc3,cc7
+	ld.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
+	orcr		cc7,cc7,cc3			/* set CC3 to true */
+	and		gr8,gr10,gr11
+	cst.p		gr11,@(gr9,gr0)		,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
+	beq		icc3,#0,0b
+	bralr
+
+	.size		atomic_test_and_ANDNOT_mask, .-atomic_test_and_ANDNOT_mask
+
+###############################################################################
+#
+# unsigned long atomic_test_and_OR_mask(unsigned long mask, volatile unsigned long *v);
+#
+###############################################################################
+	.globl		atomic_test_and_OR_mask
+        .type		atomic_test_and_OR_mask,@function
+atomic_test_and_OR_mask:
+	or.p		gr8,gr8,gr10
+0:
+	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
+	ckeq		icc3,cc7
+	ld.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
+	orcr		cc7,cc7,cc3			/* set CC3 to true */
+	or		gr8,gr10,gr11
+	cst.p		gr11,@(gr9,gr0)		,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
+	beq		icc3,#0,0b
+	bralr
+
+	.size		atomic_test_and_OR_mask, .-atomic_test_and_OR_mask
+
+###############################################################################
+#
+# unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsigned long *v);
+#
+###############################################################################
+	.globl		atomic_test_and_XOR_mask
+        .type		atomic_test_and_XOR_mask,@function
+atomic_test_and_XOR_mask:
+	or.p		gr8,gr8,gr10
+0:
+	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
+	ckeq		icc3,cc7
+	ld.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
+	orcr		cc7,cc7,cc3			/* set CC3 to true */
+	xor		gr8,gr10,gr11
+	cst.p		gr11,@(gr9,gr0)		,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
+	beq		icc3,#0,0b
+	bralr
+
+	.size		atomic_test_and_XOR_mask, .-atomic_test_and_XOR_mask
+
+###############################################################################
+#
+# int atomic_add_return(int i, atomic_t *v)
+#
+###############################################################################
+	.globl		atomic_add_return
+        .type		atomic_add_return,@function
+atomic_add_return:
+	or.p		gr8,gr8,gr10
+0:
+	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
+	ckeq		icc3,cc7
+	ld.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
+	orcr		cc7,cc7,cc3			/* set CC3 to true */
+	add		gr8,gr10,gr8
+	cst.p		gr8,@(gr9,gr0)		,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
+	beq		icc3,#0,0b
+	bralr
+
+	.size		atomic_add_return, .-atomic_add_return
+
+###############################################################################
+#
+# int atomic_sub_return(int i, atomic_t *v)
+#
+###############################################################################
+	.globl		atomic_sub_return
+        .type		atomic_sub_return,@function
+atomic_sub_return:
+	or.p		gr8,gr8,gr10
+0:
+	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
+	ckeq		icc3,cc7
+	ld.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
+	orcr		cc7,cc7,cc3			/* set CC3 to true */
+	sub		gr8,gr10,gr8
+	cst.p		gr8,@(gr9,gr0)		,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
+	beq		icc3,#0,0b
+	bralr
+
+	.size		atomic_sub_return, .-atomic_sub_return
+
+###############################################################################
+#
+# uint8_t __xchg_8(uint8_t i, uint8_t *v)
+#
+###############################################################################
+	.globl		__xchg_8
+        .type		__xchg_8,@function
+__xchg_8:
+	or.p		gr8,gr8,gr10
+0:
+	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
+	ckeq		icc3,cc7
+	ldub.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
+	orcr		cc7,cc7,cc3			/* set CC3 to true */
+	cstb.p		gr10,@(gr9,gr0)		,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
+	beq		icc3,#0,0b
+	bralr
+
+	.size		__xchg_8, .-__xchg_8
+
+###############################################################################
+#
+# uint16_t __xchg_16(uint16_t i, uint16_t *v)
+#
+###############################################################################
+	.globl		__xchg_16
+        .type		__xchg_16,@function
+__xchg_16:
+	or.p		gr8,gr8,gr10
+0:
+	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
+	ckeq		icc3,cc7
+	lduh.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
+	orcr		cc7,cc7,cc3			/* set CC3 to true */
+	csth.p		gr10,@(gr9,gr0)		,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
+	beq		icc3,#0,0b
+	bralr
+
+	.size		__xchg_16, .-__xchg_16
+
+###############################################################################
+#
+# uint32_t __xchg_32(uint32_t i, uint32_t *v)
+#
+###############################################################################
+	.globl		__xchg_32
+        .type		__xchg_32,@function
+__xchg_32:
+	or.p		gr8,gr8,gr10
+0:
+	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
+	ckeq		icc3,cc7
+	ld.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
+	orcr		cc7,cc7,cc3			/* set CC3 to true */
+	cst.p		gr10,@(gr9,gr0)		,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
+	beq		icc3,#0,0b
+	bralr
+
+	.size		__xchg_32, .-__xchg_32
+
+###############################################################################
+#
+# uint8_t __cmpxchg_8(uint8_t *v, uint8_t test, uint8_t new)
+#
+###############################################################################
+	.globl		__cmpxchg_8
+        .type		__cmpxchg_8,@function
+__cmpxchg_8:
+	or.p		gr8,gr8,gr11
+0:
+	orcc		gr0,gr0,gr0,icc3
+	ckeq		icc3,cc7
+	ldub.p		@(gr11,gr0),gr8
+	orcr		cc7,cc7,cc3
+	sub		gr8,gr9,gr7
+	sllicc		gr7,#24,gr0,icc0
+	bne		icc0,#0,1f
+	cstb.p		gr10,@(gr11,gr0)	,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1
+	beq		icc3,#0,0b
+1:
+	bralr
+
+	.size		__cmpxchg_8, .-__cmpxchg_8
+
+###############################################################################
+#
+# uint16_t __cmpxchg_16(uint16_t *v, uint16_t test, uint16_t new)
+#
+###############################################################################
+	.globl		__cmpxchg_16
+        .type		__cmpxchg_16,@function
+__cmpxchg_16:
+	or.p		gr8,gr8,gr11
+0:
+	orcc		gr0,gr0,gr0,icc3
+	ckeq		icc3,cc7
+	lduh.p		@(gr11,gr0),gr8
+	orcr		cc7,cc7,cc3
+	sub		gr8,gr9,gr7
+	sllicc		gr7,#16,gr0,icc0
+	bne		icc0,#0,1f
+	csth.p		gr10,@(gr11,gr0)	,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1
+	beq		icc3,#0,0b
+1:
+	bralr
+
+	.size		__cmpxchg_16, .-__cmpxchg_16
+
+###############################################################################
+#
+# uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new)
+#
+###############################################################################
+	.globl		__cmpxchg_32
+        .type		__cmpxchg_32,@function
+__cmpxchg_32:
+	or.p		gr8,gr8,gr11
+0:
+	orcc		gr0,gr0,gr0,icc3
+	ckeq		icc3,cc7
+	ld.p		@(gr11,gr0),gr8
+	orcr		cc7,cc7,cc3
+	subcc		gr8,gr9,gr7,icc0
+	bne		icc0,#0,1f
+	cst.p		gr10,@(gr11,gr0)	,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1
+	beq		icc3,#0,0b
+1:
+	bralr
+
+	.size		__cmpxchg_32, .-__cmpxchg_32
diff -urN linux-2.4.29/arch/frv/lib/cache.S linux-2.4.29-uc1/arch/frv/lib/cache.S
--- linux-2.4.29/arch/frv/lib/cache.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/lib/cache.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,99 @@
+/* cache.S: cache managment routines
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/spr-regs.h>
+#include <asm/cache.h>
+
+        .file		"cache.S"
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# Write back a range of dcache
+# - void frv_dcache_writeback(unsigned long start [GR8], unsigned long size [GR9])
+#
+###############################################################################
+        .globl		frv_dcache_writeback
+        .type		frv_dcache_writeback,@function
+frv_dcache_writeback:	
+	andi		gr8,~(L1_CACHE_BYTES-1),gr8
+
+2:	dcf		@(gr8,gr0)
+	addi		gr8,#L1_CACHE_BYTES,gr8
+	cmp		gr9,gr8,icc0
+	bhi		icc0,#2,2b
+
+	membar
+	bralr
+	.size		frv_dcache_writeback, .-frv_dcache_writeback
+
+##############################################################################
+#
+# Invalidate a range of dcache and icache
+# - void frv_cache_invalidate(unsigned long start [GR8], unsigned long end [GR9]);
+#
+###############################################################################
+        .globl		frv_cache_invalidate
+        .type		frv_cache_invalidate,@function
+frv_cache_invalidate:
+	andi		gr8,~(L1_CACHE_BYTES-1),gr8
+
+2:	dci		@(gr8,gr0)
+	ici		@(gr8,gr0)
+	addi		gr8,#L1_CACHE_BYTES,gr8
+	cmp		gr9,gr8,icc0
+	bhi		icc0,#2,2b
+
+	membar
+	bralr
+	.size		frv_cache_invalidate, .-frv_cache_invalidate
+
+##############################################################################
+#
+# Invalidate a range of icache
+# - void frv_icache_invalidate(unsigned long start [GR8], unsigned long end [GR9]);
+#
+###############################################################################
+        .globl		frv_icache_invalidate
+        .type		frv_icache_invalidate,@function
+frv_icache_invalidate:
+	andi		gr8,~(L1_CACHE_BYTES-1),gr8
+
+2:	ici		@(gr8,gr0)
+	addi		gr8,#L1_CACHE_BYTES,gr8
+	cmp		gr9,gr8,icc0
+	bhi		icc0,#2,2b
+
+	membar
+	bralr
+	.size		frv_icache_invalidate, .-frv_icache_invalidate
+
+###############################################################################
+#
+# Write back and invalidate a range of dcache and icache
+# - void frv_cache_wback_inv(unsigned long start [GR8], unsigned long end [GR9])
+#
+###############################################################################
+        .globl		frv_cache_wback_inv
+        .type		frv_cache_wback_inv,@function
+frv_cache_wback_inv:	
+	andi		gr8,~(L1_CACHE_BYTES-1),gr8
+
+2:	dcf		@(gr8,gr0)
+	ici		@(gr8,gr0)
+	addi		gr8,#L1_CACHE_BYTES,gr8
+	cmp		gr9,gr8,icc0
+	bhi		icc0,#2,2b
+
+	membar
+	bralr
+	.size		frv_cache_wback_inv, .-frv_cache_wback_inv
diff -urN linux-2.4.29/arch/frv/lib/checksum.c linux-2.4.29-uc1/arch/frv/lib/checksum.c
--- linux-2.4.29/arch/frv/lib/checksum.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/lib/checksum.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,148 @@
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		IP/TCP/UDP checksumming routines
+ *
+ * Authors:	Jorge Cwik, <jorge@laser.satlink.net>
+ *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ *		Tom May, <ftom@netcom.com>
+ *		Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
+ *		Lots of code moved from tcp.c and ip.c; see those files
+ *		for more names.
+ *
+ * 03/02/96	Jes Sorensen, Andreas Schwab, Roman Hodek:
+ *		Fixed some nasty bugs, causing some horrible crashes.
+ *		A: At some points, the sum (%0) was used as
+ *		length-counter instead of the length counter
+ *		(%1). Thanks to Roman Hodek for pointing this out.
+ *		B: GCC seems to mess up if one uses too many
+ *		data-registers to hold input values and one tries to
+ *		specify d0 and d1 as scratch registers. Letting gcc choose these
+ *      registers itself solves the problem.
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+ 
+/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most
+   of the assembly has to go. */
+
+#include <net/checksum.h>
+#include <asm/checksum.h>
+
+static inline unsigned short from32to16(unsigned long x)
+{
+	/* add up 16-bit and 16-bit for 16+c bit */
+	x = (x & 0xffff) + (x >> 16);
+	/* add up carry.. */
+	x = (x & 0xffff) + (x >> 16);
+	return x;
+}
+
+static unsigned long do_csum(const unsigned char * buff, int len)
+{
+	int odd, count;
+	unsigned long result = 0;
+
+	if (len <= 0)
+		goto out;
+	odd = 1 & (unsigned long) buff;
+	if (odd) {
+		result = *buff;
+		len--;
+		buff++;
+	}
+	count = len >> 1;		/* nr of 16-bit words.. */
+	if (count) {
+		if (2 & (unsigned long) buff) {
+			result += *(unsigned short *) buff;
+			count--;
+			len -= 2;
+			buff += 2;
+		}
+		count >>= 1;		/* nr of 32-bit words.. */
+		if (count) {
+		        unsigned long carry = 0;
+			do {
+				unsigned long w = *(unsigned long *) buff;
+				count--;
+				buff += 4;
+				result += carry;
+				result += w;
+				carry = (w > result);
+			} while (count);
+			result += carry;
+			result = (result & 0xffff) + (result >> 16);
+		}
+		if (len & 2) {
+			result += *(unsigned short *) buff;
+			buff += 2;
+		}
+	}
+	if (len & 1)
+		result += (*buff << 8);
+	result = from32to16(result);
+	if (odd)
+		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+	return result;
+}
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
+{
+	unsigned int result = do_csum(buff, len);
+
+	/* add in old sum, and carry.. */
+	result += sum;
+	if (sum > result)
+		result += 1;
+	return result;
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+unsigned short ip_compute_csum(const unsigned char * buff, int len)
+{
+	return ~do_csum(buff,len);
+}
+
+/*
+ * copy from fs while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err)
+{
+	if (csum_err) *csum_err = 0;
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
+
+/*
+ * copy from ds while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy(const char *src, char *dst, int len, int sum)
+{
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
diff -urN linux-2.4.29/arch/frv/lib/__div.c linux-2.4.29-uc1/arch/frv/lib/__div.c
--- linux-2.4.29/arch/frv/lib/__div.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/lib/__div.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,317 @@
+/* More subroutines needed by GCC output code on some machines.  */
+/* Compile this one with gcc.  */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001, 2002, 2003  Free Software Foundation, Inc.
+
+This file is based on selective parts of libgcc2.c
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GCC 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 GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+struct DWstruct {int high, low;};
+
+typedef union
+{
+  struct DWstruct s;
+  long long ll;
+} DWunion;
+
+
+#define add_ssaaaa(sh, sl, ah, al, bh, bl)				\
+  __asm__ ("addcc %3,%5,%1,icc3\n\taddx %2,%4,%0,icc3"			\
+	   : "=d" (sh), "=d" (sl)					\
+	   : "d" (ah), "d" (al), "d" (bh), "d" (bl)			\
+	   : "icc3");
+
+#define sub_ddmmss(sh, sl, ah, al, bh, bl)				\
+  __asm__ ("subcc %3,%5,%1,icc3\n\tsubx %2,%4,%0,icc3"			\
+	   : "=d" (sh), "=d" (sl)					\
+	   : "d" (ah), "d" (al), "d" (bh), "d" (bl)			\
+	   : "icc3");
+
+#define umul_ppmm(ph, pl, m0, m1) \
+  ({union {								\
+      unsigned long long __ll;						\
+      struct {unsigned int __h, __l; } __i;				\
+    } __xx;								\
+  __xx.__ll = __umulsidi3(m0, m1);					\
+  (ph) = __xx.__i.__h; (pl) = __xx.__i.__l;})
+
+#define __umulsidi3(u, v) (((unsigned long long)(unsigned int)(u)) * ((unsigned long long)(unsigned int)(v)))
+
+
+#define __ll_B ((unsigned) 1 << 16)
+#define __ll_lowpart(t) ((unsigned) (t) & 0xffff)
+#define __ll_highpart(t) ((unsigned) (t) >> 16)
+
+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
+  do {									\
+    unsigned __d1, __d0, __q1, __q0;					\
+    unsigned __r1, __r0, __m;						\
+    __d1 = __ll_highpart (d);						\
+    __d0 = __ll_lowpart (d);						\
+									\
+    __r1 = (n1) % __d1;							\
+    __q1 = (n1) / __d1;							\
+    __m = (unsigned) __q1 * __d0;						\
+    __r1 = __r1 * __ll_B | __ll_highpart (n0);				\
+    if (__r1 < __m)							\
+      {									\
+	__q1--, __r1 += (d);						\
+	if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
+	  if (__r1 < __m)						\
+	    __q1--, __r1 += (d);					\
+      }									\
+    __r1 -= __m;							\
+									\
+    __r0 = __r1 % __d1;							\
+    __q0 = __r1 / __d1;							\
+    __m = (unsigned) __q0 * __d0;						\
+    __r0 = __r0 * __ll_B | __ll_lowpart (n0);				\
+    if (__r0 < __m)							\
+      {									\
+	__q0--, __r0 += (d);						\
+	if (__r0 >= (d))						\
+	  if (__r0 < __m)						\
+	    __q0--, __r0 += (d);					\
+      }									\
+    __r0 -= __m;							\
+									\
+    (q) = (unsigned) __q1 * __ll_B | __q0;				\
+    (r) = __r0;								\
+  } while (0)
+
+
+#define count_leading_zeros(count, x) \
+  do {                                                                  \
+  __asm__ ("scani %1,1,%0"                                              \
+           : "=r" ((unsigned)(count))                                   \
+           : "r" ((unsigned)(x)));					\
+  } while (0)
+
+static inline __attribute__ ((__always_inline__))
+unsigned long long
+__udivmoddi4 (unsigned long long n, unsigned long long d, unsigned long long *rp)
+{
+  const DWunion nn = {.ll = n};
+  const DWunion dd = {.ll = d};
+  DWunion rr;
+  unsigned d0, d1, n0, n1, n2;
+  unsigned q0, q1;
+  unsigned b, bm;
+
+  d0 = dd.s.low;
+  d1 = dd.s.high;
+  n0 = nn.s.low;
+  n1 = nn.s.high;
+
+  if (d1 == 0)
+    {
+      if (d0 > n1)
+	{
+	  /* 0q = nn / 0D */
+
+	  count_leading_zeros (bm, d0);
+
+	  if (bm != 0)
+	    {
+	      /* Normalize, i.e. make the most significant bit of the
+		 denominator set.  */
+
+	      d0 = d0 << bm;
+	      n1 = (n1 << bm) | (n0 >> (32 - bm));
+	      n0 = n0 << bm;
+	    }
+
+	  __udiv_qrnnd_c (q0, n0, n1, n0, d0);
+	  q1 = 0;
+
+	  /* Remainder in n0 >> bm.  */
+	}
+      else
+	{
+	  /* qq = NN / 0d */
+
+	  if (d0 == 0)
+	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
+
+	  count_leading_zeros (bm, d0);
+
+	  if (bm == 0)
+	    {
+	      /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+		 conclude (the most significant bit of n1 is set) /\ (the
+		 leading quotient digit q1 = 1).
+
+		 This special case is necessary, not an optimization.
+		 (Shifts counts of W_TYPE_SIZE are undefined.)  */
+
+	      n1 -= d0;
+	      q1 = 1;
+	    }
+	  else
+	    {
+	      /* Normalize.  */
+
+	      b = 32 - bm;
+
+	      d0 = d0 << bm;
+	      n2 = n1 >> b;
+	      n1 = (n1 << bm) | (n0 >> b);
+	      n0 = n0 << bm;
+
+	      __udiv_qrnnd_c (q1, n1, n2, n1, d0);
+	    }
+
+	  /* n1 != d0...  */
+
+	  __udiv_qrnnd_c (q0, n0, n1, n0, d0);
+
+	  /* Remainder in n0 >> bm.  */
+	}
+
+      if (rp != 0)
+	{
+	  rr.s.low = n0 >> bm;
+	  rr.s.high = 0;
+	  *rp = rr.ll;
+	}
+    }
+  else
+    {
+      if (d1 > n1)
+	{
+	  /* 00 = nn / DD */
+
+	  q0 = 0;
+	  q1 = 0;
+
+	  /* Remainder in n1n0.  */
+	  if (rp != 0)
+	    {
+	      rr.s.low = n0;
+	      rr.s.high = n1;
+	      *rp = rr.ll;
+	    }
+	}
+      else
+	{
+	  /* 0q = NN / dd */
+
+	  count_leading_zeros (bm, d1);
+	  if (bm == 0)
+	    {
+	      /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+		 conclude (the most significant bit of n1 is set) /\ (the
+		 quotient digit q0 = 0 or 1).
+
+		 This special case is necessary, not an optimization.  */
+
+	      /* The condition on the next line takes advantage of that
+		 n1 >= d1 (true due to program flow).  */
+	      if (n1 > d1 || n0 >= d0)
+		{
+		  q0 = 1;
+		  sub_ddmmss (n1, n0, n1, n0, d1, d0);
+		}
+	      else
+		q0 = 0;
+
+	      q1 = 0;
+
+	      if (rp != 0)
+		{
+		  rr.s.low = n0;
+		  rr.s.high = n1;
+		  *rp = rr.ll;
+		}
+	    }
+	  else
+	    {
+	      unsigned m1, m0;
+	      /* Normalize.  */
+
+	      b = 32 - bm;
+
+	      d1 = (d1 << bm) | (d0 >> b);
+	      d0 = d0 << bm;
+	      n2 = n1 >> b;
+	      n1 = (n1 << bm) | (n0 >> b);
+	      n0 = n0 << bm;
+
+	      __udiv_qrnnd_c (q0, n1, n2, n1, d1);
+	      umul_ppmm (m1, m0, q0, d0);
+
+	      if (m1 > n1 || (m1 == n1 && m0 > n0))
+		{
+		  q0--;
+		  sub_ddmmss (m1, m0, m1, m0, d1, d0);
+		}
+
+	      q1 = 0;
+
+	      /* Remainder in (n1n0 - m1m0) >> bm.  */
+	      if (rp != 0)
+		{
+		  sub_ddmmss (n1, n0, n1, n0, m1, m0);
+		  rr.s.low = (n1 << b) | (n0 >> bm);
+		  rr.s.high = n1 >> bm;
+		  *rp = rr.ll;
+		}
+	    }
+	}
+    }
+
+  const DWunion ww = {{.low = q0, .high = q1}};
+  return ww.ll;
+}
+
+
+unsigned long long
+__udivdi3 (unsigned long long n, unsigned long long d)
+{
+  return __udivmoddi4 (n, d, (unsigned long long *) 0);
+}
+
+long long
+__divll (long long u, long long v)
+{
+  int c = 0;
+  DWunion uu = {.ll = u};
+  DWunion vv = {.ll = v};
+  long long w;
+
+  if (uu.s.high < 0)
+    c = ~c,
+    uu.ll = -uu.ll;
+  if (vv.s.high < 0)
+    c = ~c,
+    vv.ll = -vv.ll;
+
+  w = __udivmoddi4 (uu.ll, vv.ll, (unsigned long long *) 0);
+  if (c)
+    w = -w;
+
+  return w;
+}
diff -urN linux-2.4.29/arch/frv/lib/insl_ns.S linux-2.4.29-uc1/arch/frv/lib/insl_ns.S
--- linux-2.4.29/arch/frv/lib/insl_ns.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/lib/insl_ns.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,53 @@
+/* insl_ns.S: input array of 4b words from device port without byte swapping
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+
+        .file		"insl_ns.S"
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# void __insl_ns(unsigned int port, void *buf, int n)
+#
+###############################################################################
+        .globl		__insl_ns
+        .type		__insl_ns,@function
+__insl_ns:
+	andicc.p	gr9,#3,gr0,icc0
+	setlos		#4,gr4
+	bne		icc0,#0,__insl_ns_misaligned
+	subi		gr9,#4,gr9
+0:
+	ldi.p		@(gr8,#0),gr5
+	subicc		gr10,#1,gr10,icc0
+	stu.p		gr5,@(gr9,gr4)
+	bhi		icc0,#2,0b
+	bralr
+
+__insl_ns_misaligned:
+	subi.p		gr9,#1,gr9
+	setlos		#1,gr4
+0:
+	ldi		@(gr8,#0),gr5
+
+	srli		gr5,#24,gr6
+	stbu.p		gr6,@(gr9,gr4)
+	srli		gr5,#16,gr6
+	stbu.p		gr6,@(gr9,gr4)
+	srli		gr5,#8,gr6
+	stbu.p		gr6,@(gr9,gr4)
+	subicc		gr10,#1,gr10,icc0
+	stbu.p		gr5,@(gr9,gr4)
+	bhi		icc0,#2,0b
+	bralr
+
+	.size		__insl_ns, .-__insl_ns
diff -urN linux-2.4.29/arch/frv/lib/insl_sw.S linux-2.4.29-uc1/arch/frv/lib/insl_sw.S
--- linux-2.4.29/arch/frv/lib/insl_sw.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/lib/insl_sw.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,41 @@
+/* insl_sw.S: input array of 4b words from device port with byte swapping
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+
+        .file		"insl_sw.S"
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# void __insl_sw(unsigned int port, void *buf, int n)
+#
+###############################################################################
+        .globl		__insl_sw
+        .type		__insl_sw,@function
+__insl_sw:
+	subi.p		gr9,#1,gr9
+	setlos		#1,gr4
+0:
+	ldi.p		@(gr8,#0),gr5		; get 0xAABBCCDD
+	subicc		gr10,#1,gr10,icc0
+
+	stbu.p		gr5,@(gr9,gr4)		; write 0xDD
+	srli		gr5,#8,gr5
+	stbu.p		gr5,@(gr9,gr4)		; write 0xCC
+	srli		gr5,#8,gr5
+	stbu.p		gr5,@(gr9,gr4)		; write 0xBB
+	srli		gr5,#8,gr5
+	stbu.p		gr5,@(gr9,gr4)		; write 0xAA
+	bhi		icc0,#2,0b
+	bralr
+
+	.size		__insl_sw, .-__insl_sw
diff -urN linux-2.4.29/arch/frv/lib/__lshrdi3.S linux-2.4.29-uc1/arch/frv/lib/__lshrdi3.S
--- linux-2.4.29/arch/frv/lib/__lshrdi3.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/lib/__lshrdi3.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,41 @@
+/* __lshrdi3.S:	64-bit logical shift right
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+        .file		"__lshrdi3.S"
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# unsigned long long __lshrdi3(unsigned long long value [GR8:GR9], unsigned by [GR10])
+#
+###############################################################################
+        .globl		__lshrdi3
+        .type		__lshrdi3,@function
+__lshrdi3:
+	andicc.p	gr10,#63,gr10,icc0
+	setlos		#32,gr5
+	andicc.p	gr10,#32,gr0,icc1
+	beqlr		icc0,#0
+	ckeq		icc1,cc4			; cc4 is true if 0<N<32
+
+	# deal with a shift in the range 1<=N<=31
+	csrl.p		gr9,gr10,gr9	,cc4,#1		; LSW >>= N
+	csub		gr5,gr10,gr5	,cc4,#1		; M = 32 - N
+	csll.p		gr8,gr5,gr4	,cc4,#1
+	csrl		gr8,gr10,gr8	,cc4,#1		; MSW >>= N
+	cor.p		gr4,gr9,gr9	,cc4,#1		; LSW |= MSW << M
+
+	# deal with a shift in the range 32<=N<=63
+	csrl		gr8,gr10,gr9	,cc4,#0		; LSW = MSW >> (N & 31 [implicit AND])
+	cor.p		gr0,gr0,gr8	,cc4,#0		; MSW = 0
+	bralr
+	.size		__lshrdi3, .-__lshrdi3
diff -urN linux-2.4.29/arch/frv/lib/Makefile linux-2.4.29-uc1/arch/frv/lib/Makefile
--- linux-2.4.29/arch/frv/lib/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/lib/Makefile	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,9 @@
+#
+# Makefile for FRV-specific library files..
+#
+
+L_TARGET = lib.a
+obj-y  = __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o checksum.o memcpy.o memset.o \
+	outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o atomic-ops.o __div.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/frv/lib/memcpy.S linux-2.4.29-uc1/arch/frv/lib/memcpy.S
--- linux-2.4.29/arch/frv/lib/memcpy.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/lib/memcpy.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,154 @@
+/* memcpy.S: optimised assembly memcpy
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+
+        .file		"memcpy.S"
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# void *memcpy(void *to, const char *from, size_t count)
+#
+# - NOTE: must not use any stack. exception detection performs function return
+#         to caller's fixup routine, aborting the remainder of the copy
+#
+###############################################################################
+        .globl		memcpy,__memcpy_end
+        .type		memcpy,@function
+memcpy:
+	or.p		gr8,gr9,gr4
+	orcc		gr10,gr0,gr0,icc3
+	or.p		gr10,gr4,gr4
+	beqlr		icc3,#0
+
+	# optimise based on best common alignment for to, from & count
+	andicc.p	gr4,#0x1f,gr0,icc0
+	setlos		#8,gr11
+	andicc.p	gr4,#0x0f,gr0,icc1
+	beq		icc0,#0,memcpy_32
+	andicc.p	gr4,#0x07,gr0,icc0
+	beq		icc1,#0,memcpy_16
+	andicc.p	gr4,#0x03,gr0,icc1
+	beq		icc0,#0,memcpy_8
+	andicc.p	gr4,#0x01,gr0,icc0
+	beq		icc1,#0,memcpy_4
+	setlos.p	#1,gr11
+	beq		icc0,#0,memcpy_2
+
+	# do byte by byte copy
+	sub.p		gr8,gr11,gr3
+	sub		gr9,gr11,gr9
+0:	ldubu.p		@(gr9,gr11),gr4
+	subicc		gr10,#1,gr10,icc0
+	stbu.p		gr4,@(gr3,gr11)
+	bne		icc0,#2,0b
+	bralr
+
+	# do halfword by halfword copy
+memcpy_2:
+	setlos		#2,gr11
+	sub.p		gr8,gr11,gr3
+	sub		gr9,gr11,gr9
+0:	lduhu.p		@(gr9,gr11),gr4
+	subicc		gr10,#2,gr10,icc0
+	sthu.p		gr4,@(gr3,gr11)
+	bne		icc0,#2,0b
+	bralr
+
+	# do word by word copy
+memcpy_4:
+	setlos		#4,gr11
+	sub.p		gr8,gr11,gr3
+	sub		gr9,gr11,gr9
+0:	ldu.p		@(gr9,gr11),gr4
+	subicc		gr10,#4,gr10,icc0
+	stu.p		gr4,@(gr3,gr11)
+	bne		icc0,#2,0b
+	bralr
+
+	# do double-word by double-word copy
+memcpy_8:
+	sub.p		gr8,gr11,gr3
+	sub		gr9,gr11,gr9
+0:	lddu.p		@(gr9,gr11),gr4
+	subicc		gr10,#8,gr10,icc0
+	stdu.p		gr4,@(gr3,gr11)
+	bne		icc0,#2,0b
+	bralr
+
+	# do quad-word by quad-word copy
+memcpy_16:
+	sub.p		gr8,gr11,gr3
+	sub		gr9,gr11,gr9
+0:	lddu		@(gr9,gr11),gr4
+	lddu.p		@(gr9,gr11),gr6
+	subicc		gr10,#16,gr10,icc0
+	stdu		gr4,@(gr3,gr11)
+	stdu.p		gr6,@(gr3,gr11)
+	bne		icc0,#2,0b
+	bralr
+
+	# do eight-word by eight-word copy
+memcpy_32:
+	sub.p		gr8,gr11,gr3
+	sub		gr9,gr11,gr9
+0:	lddu		@(gr9,gr11),gr4
+	lddu		@(gr9,gr11),gr6
+	lddu		@(gr9,gr11),gr12
+	lddu.p		@(gr9,gr11),gr14
+	subicc		gr10,#32,gr10,icc0
+	stdu		gr4,@(gr3,gr11)
+	stdu		gr6,@(gr3,gr11)
+	stdu		gr12,@(gr3,gr11)
+	stdu.p		gr14,@(gr3,gr11)
+	bne		icc0,#2,0b
+	bralr
+__memcpy_end:
+
+	.size		memcpy, __memcpy_end-memcpy
+
+###############################################################################
+#
+# copy to/from userspace
+# - return the number of bytes that could not be copied (0 on complete success)
+#
+# long __memcpy_user(void *dst, const void *src, size_t count)
+#
+###############################################################################
+        .globl		__memcpy_user, __memcpy_user_error_lr, __memcpy_user_error_handler
+        .type		__memcpy_user,@function
+__memcpy_user:
+	movsg		lr,gr7
+	subi.p		sp,#8,sp
+	add		gr8,gr10,gr6		; calculate expected end address
+	stdi		gr6,@(sp,#0)
+
+	# abuse memcpy to do the dirty work
+	call		memcpy
+__memcpy_user_error_lr:
+	ldi.p		@(sp,#4),gr7
+	setlos		#0,gr8
+	jmpl.p		@(gr7,gr0)
+	addi		sp,#8,sp
+
+	# deal any exception generated by memcpy
+	# GR8 - memcpy's current dest address
+	# GR11 - memset's step value (index register for store insns)
+__memcpy_user_error_handler:
+	lddi.p		@(sp,#0),gr4		; load GR4 with dst+count, GR5 with ret addr
+	add		gr11,gr3,gr7
+	sub.p		gr4,gr7,gr8
+
+	addi		sp,#8,sp
+	jmpl		@(gr5,gr0)
+
+	.size		__memcpy_user, .-__memcpy_user
diff -urN linux-2.4.29/arch/frv/lib/memset.S linux-2.4.29-uc1/arch/frv/lib/memset.S
--- linux-2.4.29/arch/frv/lib/memset.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/lib/memset.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,183 @@
+/* memset.S: optimised assembly memset
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+
+        .file		"memset.S"
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# void *memset(void *p, char ch, size_t count)
+#
+# - NOTE: must not use any stack. exception detection performs function return
+#         to caller's fixup routine, aborting the remainder of the set
+#         GR4, GR7, GR8, and GR11 must be managed
+#
+###############################################################################
+        .globl		memset,__memset_end
+        .type		memset,@function
+memset:
+	orcc.p		gr10,gr0,gr5,icc3		; GR5 = count
+	andi		gr9,#0xff,gr9
+	or.p		gr8,gr0,gr4			; GR4 = address
+	beqlr		icc3,#0
+
+	# conditionally write a byte to 2b-align the address
+	setlos.p	#1,gr6
+	andicc		gr4,#1,gr0,icc0
+	ckne		icc0,cc7
+	cstb.p		gr9,@(gr4,gr0)		,cc7,#1
+	csubcc		gr5,gr6,gr5		,cc7,#1	; also set ICC3
+	cadd.p		gr4,gr6,gr4		,cc7,#1
+	beqlr		icc3,#0
+
+	# conditionally write a word to 4b-align the address
+	andicc.p	gr4,#2,gr0,icc0
+	subicc		gr5,#2,gr0,icc1
+	setlos.p	#2,gr6
+	ckne		icc0,cc7
+	slli.p		gr9,#8,gr12			; need to double up the pattern
+	cknc		icc1,cc5
+	or.p		gr9,gr12,gr12
+	andcr		cc7,cc5,cc7
+
+	csth.p		gr12,@(gr4,gr0)		,cc7,#1
+	csubcc		gr5,gr6,gr5		,cc7,#1	; also set ICC3
+	cadd.p		gr4,gr6,gr4		,cc7,#1
+	beqlr		icc3,#0
+
+	# conditionally write a dword to 8b-align the address
+	andicc.p	gr4,#4,gr0,icc0
+	subicc		gr5,#4,gr0,icc1
+	setlos.p	#4,gr6
+	ckne		icc0,cc7
+	slli.p		gr12,#16,gr13			; need to quadruple-up the pattern
+	cknc		icc1,cc5
+	or.p		gr13,gr12,gr12
+	andcr		cc7,cc5,cc7
+
+	cst.p		gr12,@(gr4,gr0)		,cc7,#1
+	csubcc		gr5,gr6,gr5		,cc7,#1	; also set ICC3
+	cadd.p		gr4,gr6,gr4		,cc7,#1
+	beqlr		icc3,#0
+
+	or.p		gr12,gr12,gr13			; need to octuple-up the pattern
+
+	# the address is now 8b-aligned - loop around writing 64b chunks
+	setlos		#8,gr7
+	subi.p		gr4,#8,gr4			; store with update index does weird stuff
+	setlos		#64,gr6
+
+	subicc		gr5,#64,gr0,icc0
+0:	cknc		icc0,cc7
+	cstdu		gr12,@(gr4,gr7)		,cc7,#1
+	cstdu		gr12,@(gr4,gr7)		,cc7,#1
+	cstdu		gr12,@(gr4,gr7)		,cc7,#1
+	cstdu		gr12,@(gr4,gr7)		,cc7,#1
+	cstdu		gr12,@(gr4,gr7)		,cc7,#1
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	csubcc		gr5,gr6,gr5		,cc7,#1	; also set ICC3
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	subicc		gr5,#64,gr0,icc0
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	beqlr		icc3,#0
+	bnc		icc0,#2,0b
+
+	# now do 32-byte remnant
+	subicc.p	gr5,#32,gr0,icc0
+	setlos		#32,gr6
+	cknc		icc0,cc7
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	csubcc		gr5,gr6,gr5		,cc7,#1	; also set ICC3
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	setlos		#16,gr6
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	subicc		gr5,#16,gr0,icc0
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	beqlr		icc3,#0
+
+	# now do 16-byte remnant
+	cknc		icc0,cc7
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	csubcc		gr5,gr6,gr5		,cc7,#1	; also set ICC3
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	beqlr		icc3,#0
+
+	# now do 8-byte remnant
+	subicc		gr5,#8,gr0,icc1
+	cknc		icc1,cc7
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	csubcc		gr5,gr7,gr5		,cc7,#1	; also set ICC3
+	setlos.p	#4,gr7
+	beqlr		icc3,#0
+
+	# now do 4-byte remnant
+	subicc		gr5,#4,gr0,icc0
+	addi.p		gr4,#4,gr4
+	cknc		icc0,cc7
+	cstu.p		gr12,@(gr4,gr7)		,cc7,#1
+	csubcc		gr5,gr7,gr5		,cc7,#1	; also set ICC3
+	subicc.p	gr5,#2,gr0,icc1
+	beqlr		icc3,#0
+
+	# now do 2-byte remnant
+	setlos		#2,gr7
+	addi.p		gr4,#2,gr4
+	cknc		icc1,cc7
+	csthu.p		gr12,@(gr4,gr7)		,cc7,#1
+	csubcc		gr5,gr7,gr5		,cc7,#1	; also set ICC3
+	subicc.p	gr5,#1,gr0,icc0
+	beqlr		icc3,#0
+
+	# now do 1-byte remnant
+	setlos		#0,gr7
+	addi.p		gr4,#2,gr4
+	cknc		icc0,cc7
+	cstb.p		gr12,@(gr4,gr0)		,cc7,#1
+	bralr
+__memset_end:
+
+	.size		memset, __memset_end-memset
+
+###############################################################################
+#
+# clear memory in userspace
+# - return the number of bytes that could not be cleared (0 on complete success)
+#
+# long __memset_user(void *p, size_t count)
+#
+###############################################################################
+        .globl		__memset_user, __memset_user_error_lr, __memset_user_error_handler
+        .type		__memset_user,@function
+__memset_user:
+	movsg		lr,gr11
+
+	# abuse memset to do the dirty work
+	or.p		gr9,gr9,gr10
+	setlos		#0,gr9
+	call		memset
+__memset_user_error_lr:
+	jmpl.p		@(gr11,gr0)
+	setlos		#0,gr8
+
+	# deal any exception generated by memset
+	# GR4  - memset's address tracking pointer
+	# GR7  - memset's step value (index register for store insns)
+	# GR8  - memset's original start address
+	# GR10 - memset's original count
+__memset_user_error_handler:
+	add.p		gr4,gr7,gr4
+	add		gr8,gr10,gr8
+	jmpl.p		@(gr11,gr0)
+	sub		gr8,gr4,gr8		; we return the amount left uncleared
+
+	.size		__memset_user, .-__memset_user
diff -urN linux-2.4.29/arch/frv/lib/__muldi3.S linux-2.4.29-uc1/arch/frv/lib/__muldi3.S
--- linux-2.4.29/arch/frv/lib/__muldi3.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/lib/__muldi3.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,33 @@
+/* __muldi3.S:	64-bit multiply
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+        .file		"__muldi3.S"
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# unsigned long long __muldi3(unsigned long long x [GR8:GR9],
+#                             unsigned long long y [GR10:GR11])
+#
+###############################################################################
+        .globl		__muldi3, __mulll, __umulll
+        .type		__muldi3,@function
+__muldi3:
+__mulll:
+__umulll:
+	umul		gr8,gr11,gr4		; GR4:GR5 = x.MSW * y.LSW
+	umul		gr9,gr10,gr6		; GR6:GR7 = x.LSW * y.MSW
+	umul.p		gr9,gr11,gr8		; GR8:GR9 = x.LSW * y.LSW
+	add		gr5,gr7,gr5
+	add.p		gr8,gr5,gr8		; GR8 += GR5 + GR7
+	bralr
+	.size		__muldi3, .-__muldi3
diff -urN linux-2.4.29/arch/frv/lib/__negdi2.S linux-2.4.29-uc1/arch/frv/lib/__negdi2.S
--- linux-2.4.29/arch/frv/lib/__negdi2.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/lib/__negdi2.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,29 @@
+/* __negdi2.S: 64-bit negate
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+
+        .file		"__negdi2.S"
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# unsigned long long __negdi2(unsigned long long value [GR8:GR9])
+#
+###############################################################################
+        .globl		__negdi2
+        .type		__negdi2,@function
+__negdi2:
+	subcc		gr0,gr9,gr9,icc0
+	subx		gr0,gr8,gr8,icc0
+	bralr
+	.size		__negdi2, .-__negdi2
+
diff -urN linux-2.4.29/arch/frv/lib/outsl_ns.S linux-2.4.29-uc1/arch/frv/lib/outsl_ns.S
--- linux-2.4.29/arch/frv/lib/outsl_ns.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/lib/outsl_ns.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,60 @@
+/* outsl_ns.S: output array of 4b words to device without byte swapping
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+
+        .file		"outsl_ns.S"
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# void __outsl_ns(unsigned int port, const void *buf, int n)
+#
+###############################################################################
+        .globl		__outsl_ns
+        .type		__outsl_ns,@function
+__outsl_ns:
+	andicc.p	gr9,#3,gr0,icc0
+	setlos		#4,gr4
+	bne		icc0,#0,__outsl_ns_misaligned
+	subi		gr9,#4,gr9
+0:
+	ldu.p		@(gr9,gr4),gr5
+	subicc		gr10,#1,gr10,icc0
+	sti.p		gr5,@(gr8,#0)
+	bhi		icc0,#2,0b
+
+	membar
+	bralr
+
+__outsl_ns_misaligned:
+	subi.p		gr9,#1,gr9
+	setlos		#1,gr4
+0:
+	ldubu		@(gr9,gr4),gr5
+	ldubu.p		@(gr9,gr4),gr6
+	slli		gr5,#8,gr5
+	ldubu.p		@(gr9,gr4),gr7
+	or		gr5,gr6,gr5
+	ldubu.p		@(gr9,gr4),gr6
+	slli		gr5,#16,gr5
+	slli.p		gr7,#8,gr7
+	or		gr5,gr6,gr5
+	subicc.p	gr10,#1,gr10,icc0
+	or		gr5,gr7,gr5
+
+	sti.p		gr5,@(gr8,#0)
+	bhi		icc0,#2,0b
+
+	membar
+	bralr
+
+	.size		__outsl_ns, .-__outsl_ns
diff -urN linux-2.4.29/arch/frv/lib/outsl_sw.S linux-2.4.29-uc1/arch/frv/lib/outsl_sw.S
--- linux-2.4.29/arch/frv/lib/outsl_sw.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/lib/outsl_sw.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,46 @@
+/* outsl_ns.S: output array of 4b words to device with byte swapping
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+
+        .file		"outsl_sw.S"
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# void __outsl_sw(unsigned int port, const void *buf, int n)
+#
+###############################################################################
+        .globl		__outsl_sw
+        .type		__outsl_sw,@function
+__outsl_sw:
+	subi.p		gr9,#1,gr9
+	setlos		#1,gr4
+0:
+	ldubu		@(gr9,gr4),gr5
+	ldubu		@(gr9,gr4),gr6
+	slli		gr6,#8,gr6
+	ldubu.p		@(gr9,gr4),gr7
+	or		gr5,gr6,gr5
+	ldubu.p		@(gr9,gr4),gr6
+	slli		gr7,#16,gr7
+	slli.p		gr6,#24,gr6
+	or		gr5,gr7,gr5
+	subicc.p	gr10,#1,gr10,icc0
+	or		gr5,gr6,gr5
+
+	sti.p		gr5,@(gr8,#0)
+	bhi		icc0,#2,0b
+
+	membar
+	bralr
+
+	.size		__outsl_sw, .-__outsl_sw
diff -urN linux-2.4.29/arch/frv/Makefile linux-2.4.29-uc1/arch/frv/Makefile
--- linux-2.4.29/arch/frv/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/Makefile	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,138 @@
+#
+# frv/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 2003, 2004 Red Hat Inc.
+# - Written by David Howells <dhowells@redhat.com>
+# - Derived from arch/m68knommu/Makefile,
+#	Copyright (c) 1999,2001  D. Jeff Dionne <jeff@lineo.ca>,
+#	Rt-Control Inc. / Lineo, Inc.
+#
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uclinux.org>,
+#                          Kenneth Albanowski <kjahds@kjahds.com>,
+#
+# Based on arch/m68k/Makefile:
+# Copyright (C) 1994 by Hamish Macdonald
+#
+
+ARCHDIR = arch/$(ARCH)
+
+CCSPECS	:= $(shell $(CC) -v 2>&1 | grep "^Reading specs from " | head -1 | cut -c20-)
+CCDIR	:= $(strip $(patsubst %/specs,%,$(CCSPECS)))
+CPUCLASS := fr400
+
+# test for cross compiling
+COMPILE_ARCH = $(shell uname -m)
+
+#
+# If you want the kernel build to build modules outside of the tree
+# then define this and pass it to the main linux makefile
+#
+ifdef EXTRA_MODULE_DIRS
+SUBDIRS += $(EXTRA_MODULE_DIRS)
+endif
+
+UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\"
+
+ARCHMODFLAGS	+= -G0 -mlong-calls
+CFLAGS		+= -G4
+LINKFLAGS	:= -X -T $(ARCHDIR)/vmlinux.ldi -Map linkmap.txt
+
+ifdef CONFIG_GC_SECTIONS
+CFLAGS		+= -ffunction-sections -fdata-sections
+LINKFLAGS	+= --gc-sections
+endif
+
+ifndef CONFIG_UCLINUX
+CFLAGS		+= -mcpu=fr450
+AFLAGS		+= -mcpu=fr450
+ASFLAGS		+= -mcpu=fr450
+else
+ifdef CONFIG_FR55x
+CFLAGS		+= -mcpu=fr550 -DNO_MM
+AFLAGS		+= -mcpu=fr550 -DNO_MM
+ASFLAGS		+= -mcpu=fr550 -DNO_MM
+else
+CFLAGS		+= -mcpu=fr400 -DNO_MM
+AFLAGS		+= -mcpu=fr400 -DNO_MM
+ASFLAGS		+= -mcpu=fr400 -DNO_MM
+endif
+endif
+
+ifndef CROSS_COMPILE
+ifndef CONFIG_UCLINUX
+CROSS_COMPILE = frv-linux-gnu-
+else
+ifdef CONFIG_FR55x
+CROSS_COMPILE = frv550-uclinux-
+else
+CROSS_COMPILE = frv400-uclinux-
+endif
+endif
+endif
+
+# pretend the kernel is going to run on an FR400 with no media-fp unit
+# - reserve CC3 for use with atomic ops
+# - all the extra registers are dealt with only at context switch time
+CFLAGS		+= -mno-fdpic -mgpr-32 -msoft-float -mno-media -ffixed-fcc3 -ffixed-cc3
+AFLAGS		+= -mno-fdpic
+ASFLAGS		+= -mno-fdpic
+
+# Set up the memory model.  RAM or ROM.
+ifdef CONFIG_RAMKERNEL
+MODEL = ram
+endif
+ifdef CONFIG_ROMKERNEL
+MODEL = rom
+endif
+ifdef CONFIG_HIMEMKERNEL
+MODEL = himem
+endif
+export MODEL
+
+
+HEAD := $(ARCHDIR)/kernel/head.o
+
+SUBDIRS += $(ARCHDIR)/kernel $(ARCHDIR)/mm $(ARCHDIR)/lib
+
+CORE_FILES := \
+	$(ARCHDIR)/kernel/entry-table.o \
+	$(ARCHDIR)/kernel/kernel.o \
+	$(ARCHDIR)/mm/mm.o $(CORE_FILES)
+
+ifdef CONFIG_MB93090_MB00
+SUBDIRS		+= $(ARCHDIR)/mb93090-mb00
+CORE_FILES	+= $(ARCHDIR)/mb93090-mb00/motherboard.o
+endif
+
+LIBS += $(ARCHDIR)/lib/lib.a 
+
+
+vmlinux: $(ARCHDIR)/vmlinux.ldi
+linux: $(ARCHDIR)/vmlinux.ldi
+
+$(ARCHDIR)/vmlinux.ldi: $(ARCHDIR)/vmlinux.lds
+	cpp -P -nostdinc -I include -D__ASSEMBLY__ -E -o $@ $<
+
+bootstrap:
+	@$(MAKEBOOT) bootstrap
+
+archmrproper:
+	@$(MAKE) -C $(ARCHDIR)/boot mrproper
+
+archclean: FORCE
+	@$(MAKE) -C $(ARCHDIR)/boot clean
+
+archdep: scripts/mkdep symlinks
+	@$(MAKE) -C $(ARCHDIR)/boot dep
+
+
+.PHONY: FORCE
diff -urN linux-2.4.29/arch/frv/mb93090-mb00/Makefile linux-2.4.29-uc1/arch/frv/mb93090-mb00/Makefile
--- linux-2.4.29/arch/frv/mb93090-mb00/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mb93090-mb00/Makefile	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,17 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+O_TARGET := motherboard.o
+
+obj-$(CONFIG_PCI) := pci-frv.o pci-dma.o pci-irq.o pci-vdk.o
+
+export-objs :=
+
+include $(TOPDIR)/Rules.make
+
diff -urN linux-2.4.29/arch/frv/mb93090-mb00/pci-dma.c linux-2.4.29-uc1/arch/frv/mb93090-mb00/pci-dma.c
--- linux-2.4.29/arch/frv/mb93090-mb00/pci-dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mb93090-mb00/pci-dma.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,192 @@
+/*
+ * Dynamic DMA mapping support.
+ *
+ * On i386 there is no hardware dynamic DMA address translation,
+ * so consistent alloc/free are merely page allocation/freeing.
+ * The rest of the dynamic DMA mapping interface is implemented
+ * in asm/pci.h.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/highmem.h>
+#include <asm/io.h>
+
+#ifndef CONFIG_UCLINUX
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
+{
+	void *ret;
+	int gfp = GFP_ATOMIC;
+
+	if (hwdev == NULL || hwdev->dma_mask < 0xffffffff)
+		gfp |= GFP_DMA;
+
+	ret = consistent_alloc(gfp, size, dma_handle);
+
+	if (ret != NULL)
+		memset(ret, 0, size);
+
+	return ret;
+}
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+{
+	consistent_free(vaddr);
+}
+
+dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+                BUG();
+
+	frv_cache_wback_inv((unsigned long) ptr, (unsigned long) ptr + size);
+
+	return virt_to_bus(ptr);
+}
+
+int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
+{
+	unsigned long dampr2;
+	void *vaddr;
+	int i;
+
+	if (direction == PCI_DMA_NONE)
+                BUG();
+
+	dampr2 = __get_DAMPR(2);
+
+	for (i = 0; i < nents; i++) {
+		vaddr = kmap_atomic(sg[i].page, __KM_CACHE);
+
+		frv_dcache_writeback((unsigned long) vaddr,
+				     (unsigned long) vaddr + PAGE_SIZE);
+
+	}
+
+	kunmap_atomic(vaddr, __KM_CACHE);
+	if (dampr2) {
+		__set_DAMPR(2, dampr2);
+		__set_IAMPR(2, dampr2);
+	}
+
+	return nents;
+}
+
+
+#else /* !CONFIG_UCLINUX */
+
+#if 1
+#define PCI_SRAM_START	dma_consistent_mem_start
+#define PCI_SRAM_END	dma_consistent_mem_end
+#else // Use video RAM on Matrox
+#define PCI_SRAM_START	0xe8900000
+#define PCI_SRAM_END	0xe8a00000
+#endif
+
+struct pci_alloc_record {
+	struct list_head list;
+	unsigned long ofs;
+	unsigned long len;
+};
+
+static spinlock_t pci_alloc_lock = SPIN_LOCK_UNLOCKED;
+static LIST_HEAD(pci_alloc_list);
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+			   dma_addr_t *dma_handle)
+{
+	struct list_head *this = &pci_alloc_list;
+	struct pci_alloc_record *new;
+	unsigned long flags;
+	unsigned long start = PCI_SRAM_START;
+	unsigned long end;
+
+	if (!PCI_SRAM_START) {
+		printk("%s called without any DMA area reserved!\n", __func__);
+		return NULL;
+	}
+	new = kmalloc(sizeof (*new), GFP_ATOMIC);
+	if (!new)
+		return NULL;
+
+	/* Round up to a reasonable alignment */
+	new->len = (size + 31) & ~31;
+
+	spin_lock_irqsave(&pci_alloc_lock, flags);
+	
+	list_for_each (this, &pci_alloc_list) {
+		struct pci_alloc_record *this_r = list_entry(this, struct pci_alloc_record, list);
+		end = this_r->ofs;
+
+		if (end - start >= size)
+			goto gotone;
+
+		start = this_r->ofs + this_r->len;
+	}
+	/* Reached end of list. */
+	end = PCI_SRAM_END;
+	this = &pci_alloc_list;
+
+	if (end - start >= size) {
+	gotone:
+		new->ofs = start;
+		list_add_tail(&new->list, this);
+		spin_unlock_irqrestore(&pci_alloc_lock, flags);
+
+		*dma_handle = start;
+		return (void *)start;
+	}
+
+	kfree(new);
+	spin_unlock_irqrestore(&pci_alloc_lock, flags);
+	return NULL;
+}
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+	struct pci_alloc_record *rec;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pci_alloc_lock, flags);
+
+	list_for_each_entry(rec, &pci_alloc_list, list) {
+		if (rec->ofs == dma_handle) {
+			list_del(&rec->list);
+			kfree(rec);
+			spin_unlock_irqrestore(&pci_alloc_lock, flags);
+			return;
+		}
+	}
+	spin_unlock_irqrestore(&pci_alloc_lock, flags);
+	BUG();
+}
+
+dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+                BUG();
+
+	frv_cache_wback_inv((unsigned long) ptr, (unsigned long) ptr + size);
+
+	return virt_to_bus(ptr);
+}
+
+int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
+{
+	int i;
+
+	for (i = 0; i < nents; i++)
+		frv_cache_wback_inv(sg_dma_address(&sg[i]),
+				    sg_dma_address(&sg[i]) + sg_dma_len(&sg[i]));
+
+	if (direction == PCI_DMA_NONE)
+                BUG();
+
+	return nents;
+}
+
+#endif /* !CONFIG_UCLINUX */
diff -urN linux-2.4.29/arch/frv/mb93090-mb00/pci-frv.c linux-2.4.29-uc1/arch/frv/mb93090-mb00/pci-frv.c
--- linux-2.4.29/arch/frv/mb93090-mb00/pci-frv.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mb93090-mb00/pci-frv.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,357 @@
+/*
+ *	Low-Level PCI Access for FRV machines
+ *
+ * Copyright 1993, 1994 Drew Eckhardt
+ *      Visionary Computing
+ *      (Unix and Linux consulting and custom programming)
+ *      Drew@Colorado.EDU
+ *      +1 (303) 786-7975
+ *
+ * Drew's work was sponsored by:
+ *	iX Multiuser Multitasking Magazine
+ *	Hannover, Germany
+ *	hm@ix.de
+ *
+ * Copyright 1997--2000 Martin Mares <mj@ucw.cz>
+ *
+ * For more information, please consult the following manuals (look at
+ * http://www.pcisig.com/ for how to get them):
+ *
+ * PCI BIOS Specification
+ * PCI Local Bus Specification
+ * PCI to PCI Bridge Specification
+ * PCI System Design Guide
+ *
+ *
+ * CHANGELOG :
+ * Jun 17, 1994 : Modified to accommodate the broken pre-PCI BIOS SPECIFICATION
+ *	Revision 2.0 present on <thys@dennis.ee.up.ac.za>'s ASUS mainboard.
+ *
+ * Jan 5,  1995 : Modified to probe PCI hardware at boot time by Frederic
+ *     Potter, potter@cao-vlsi.ibp.fr
+ *
+ * Jan 10, 1995 : Modified to store the information about configured pci
+ *      devices into a list, which can be accessed via /proc/pci by
+ *      Curtis Varner, cvarner@cs.ucr.edu
+ *
+ * Jan 12, 1995 : CPU-PCI bridge optimization support by Frederic Potter.
+ *	Alpha version. Intel & UMC chipset support only.
+ *
+ * Apr 16, 1995 : Source merge with the DEC Alpha PCI support. Most of the code
+ *	moved to drivers/pci/pci.c.
+ *
+ * Dec 7, 1996  : Added support for direct configuration access of boards
+ *      with Intel compatible access schemes (tsbogend@alpha.franken.de)
+ *
+ * Feb 3, 1997  : Set internal functions to static, save/restore flags
+ *	avoid dead locks reading broken PCI BIOS, werner@suse.de 
+ *
+ * Apr 26, 1997 : Fixed case when there is BIOS32, but not PCI BIOS
+ *	(mj@atrey.karlin.mff.cuni.cz)
+ *
+ * May 7,  1997 : Added some missing cli()'s. [mj]
+ * 
+ * Jun 20, 1997 : Corrected problems in "conf1" type accesses.
+ *      (paubert@iram.es)
+ *
+ * Aug 2,  1997 : Split to PCI BIOS handling and direct PCI access parts
+ *	and cleaned it up...     Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *
+ * Feb 6,  1998 : No longer using BIOS to find devices and device classes. [mj]
+ *
+ * May 1,  1998 : Support for peer host bridges. [mj]
+ *
+ * Jun 19, 1998 : Changed to use spinlocks, so that PCI configuration space
+ *	can be accessed from interrupts even on SMP systems. [mj]
+ *
+ * August  1998 : Better support for peer host bridges and more paranoid
+ *	checks for direct hardware access. Ugh, this file starts to look as
+ *	a large gallery of common hardware bug workarounds (watch the comments)
+ *	-- the PCI specs themselves are sane, but most implementors should be
+ *	hit hard with \hammer scaled \magstep5. [mj]
+ *
+ * Jan 23, 1999 : More improvements to peer host bridge logic. i450NX fixup. [mj]
+ *
+ * Feb 8,  1999 : Added UM8886BF I/O address fixup. [mj]
+ *
+ * August  1999 : New resource management and configuration access stuff. [mj]
+ *
+ * Sep 19, 1999 : Use PCI IRQ routing tables for detection of peer host bridges.
+ *		  Based on ideas by Chris Frantz and David Hinds. [mj]
+ *
+ * Sep 28, 1999 : Handle unreported/unassigned IRQs. Thanks to Shuu Yamaguchi
+ *		  for a lot of patience during testing. [mj]
+ *
+ * Oct  8, 1999 : Split to pci-i386.c, pci-pc.c and pci-visws.c. [mj]
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+
+#include "pci-frv.h"
+
+void
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			struct resource *res, int resource)
+{
+	u32 new, check;
+	int reg;
+
+	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+	if (resource < 6) {
+		reg = PCI_BASE_ADDRESS_0 + 4*resource;
+	} else if (resource == PCI_ROM_RESOURCE) {
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+		new |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else {
+		/* Somebody might have asked allocation of a non-standard resource */
+		return;
+	}
+	
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
+		printk(KERN_ERR "PCI: Error while updating region "
+		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+		       new, check);
+	}
+}
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ *
+ * Why? Because some silly external IO cards only decode
+ * the low 10 bits of the IO address. The 0x00-0xff region
+ * is reserved for motherboard devices that decode all 16
+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+ * but we want to try to avoid allocating at 0x2900-0x2bff
+ * which might have be mirrored at 0x0100-0x03ff..
+ */
+void
+pcibios_align_resource(void *data, struct resource *res,
+		       unsigned long size, unsigned long align)
+{
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		if (start & 0x300) {
+			start = (start + 0x3ff) & ~0x3ff;
+			res->start = start;
+		}
+	}
+}
+
+
+/*
+ *  Handle resources of PCI devices.  If the world were perfect, we could
+ *  just allocate all the resource regions and do nothing more.  It isn't.
+ *  On the other hand, we cannot just re-allocate all devices, as it would
+ *  require us to know lots of host bridge internals.  So we attempt to
+ *  keep as much of the original configuration as possible, but tweak it
+ *  when it's found to be wrong.
+ *
+ *  Known BIOS problems we have to work around:
+ *	- I/O or memory regions not configured
+ *	- regions configured, but not enabled in the command register
+ *	- bogus I/O addresses above 64K used
+ *	- expansion ROMs left enabled (this may sound harmless, but given
+ *	  the fact the PCI specs explicitly allow address decoders to be
+ *	  shared between expansion ROMs and other resource regions, it's
+ *	  at least dangerous)
+ *
+ *  Our solution:
+ *	(1) Allocate resources for all buses behind PCI-to-PCI bridges.
+ *	    This gives us fixed barriers on where we can allocate.
+ *	(2) Allocate resources for all enabled devices.  If there is
+ *	    a collision, just mark the resource as unallocated. Also
+ *	    disable expansion ROMs during this step.
+ *	(3) Try to allocate resources for disabled devices.  If the
+ *	    resources were assigned correctly, everything goes well,
+ *	    if they weren't, they won't disturb allocation of other
+ *	    resources.
+ *	(4) Assign new addresses to resources which were either
+ *	    not configured at all or misconfigured.  If explicitly
+ *	    requested by the user, configure expansion ROM address
+ *	    as well.
+ */
+
+static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
+{
+	struct list_head *ln;
+	struct pci_bus *bus;
+	struct pci_dev *dev;
+	int idx;
+	struct resource *r, *pr;
+
+	/* Depth-First Search on bus tree */
+	for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
+		bus = pci_bus_b(ln);
+		if ((dev = bus->self)) {
+			for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
+				r = &dev->resource[idx];
+				if (!r->start)
+					continue;
+				pr = pci_find_parent_resource(dev, r);
+				if (!pr || request_resource(pr, r) < 0)
+					printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, dev->slot_name);
+			}
+		}
+		pcibios_allocate_bus_resources(&bus->children);
+	}
+}
+
+static void __init pcibios_allocate_resources(int pass)
+{
+	struct pci_dev *dev;
+	int idx, disabled;
+	u16 command;
+	struct resource *r, *pr;
+
+	pci_for_each_dev(dev) {
+		pci_read_config_word(dev, PCI_COMMAND, &command);
+		for(idx = 0; idx < 6; idx++) {
+			r = &dev->resource[idx];
+			if (r->parent)		/* Already allocated */
+				continue;
+			if (!r->start)		/* Address not assigned at all */
+				continue;
+			if (r->flags & IORESOURCE_IO)
+				disabled = !(command & PCI_COMMAND_IO);
+			else
+				disabled = !(command & PCI_COMMAND_MEMORY);
+			if (pass == disabled) {
+				DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
+				    r->start, r->end, r->flags, disabled, pass);
+				pr = pci_find_parent_resource(dev, r);
+				if (!pr || request_resource(pr, r) < 0) {
+					printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, dev->slot_name);
+					/* We'll assign a new address later */
+					r->end -= r->start;
+					r->start = 0;
+				}
+			}
+		}
+		if (!pass) {
+			r = &dev->resource[PCI_ROM_RESOURCE];
+			if (r->flags & PCI_ROM_ADDRESS_ENABLE) {
+				/* Turn the ROM off, leave the resource region, but keep it unregistered. */
+				u32 reg;
+				DBG("PCI: Switching off ROM of %s\n", dev->slot_name);
+				r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
+				pci_read_config_dword(dev, dev->rom_base_reg, &reg);
+				pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE);
+			}
+		}
+	}
+}
+
+static void __init pcibios_assign_resources(void)
+{
+	struct pci_dev *dev;
+	int idx;
+	struct resource *r;
+
+	pci_for_each_dev(dev) {
+		int class = dev->class >> 8;
+
+		/* Don't touch classless devices and host bridges */
+		if (!class || class == PCI_CLASS_BRIDGE_HOST)
+			continue;
+
+		for(idx=0; idx<6; idx++) {
+			r = &dev->resource[idx];
+
+			/*
+			 *  Don't touch IDE controllers and I/O ports of video cards!
+			 */
+			if ((class == PCI_CLASS_STORAGE_IDE && idx < 4) ||
+			    (class == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO)))
+				continue;
+
+			/*
+			 *  We shall assign a new address to this resource, either because
+			 *  the BIOS forgot to do so or because we have decided the old
+			 *  address was unusable for some reason.
+			 */
+			if (!r->start && r->end)
+				pci_assign_resource(dev, idx);
+		}
+
+		if (pci_probe & PCI_ASSIGN_ROMS) {
+			r = &dev->resource[PCI_ROM_RESOURCE];
+			r->end -= r->start;
+			r->start = 0;
+			if (r->end)
+				pci_assign_resource(dev, PCI_ROM_RESOURCE);
+		}
+	}
+}
+
+void __init pcibios_resource_survey(void)
+{
+	DBG("PCI: Allocating resources\n");
+	pcibios_allocate_bus_resources(&pci_root_buses);
+	pcibios_allocate_resources(0);
+	pcibios_allocate_resources(1);
+	pcibios_assign_resources();
+}
+
+int pcibios_enable_resources(struct pci_dev *dev, int mask)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for(idx=0; idx<6; idx++) {
+		/* Only set up the requested stuff */
+		if (!(mask & (1<<idx)))
+			continue;
+			
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (dev->resource[PCI_ROM_RESOURCE].start)
+		cmd |= PCI_COMMAND_MEMORY;
+	if (cmd != old_cmd) {
+		printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+/*
+ *  If we set up a device for bus mastering, we need to check the latency
+ *  timer as certain crappy BIOSes forget to set it properly.
+ */
+unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+	u8 lat;
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+	if (lat < 16)
+		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+	else if (lat > pcibios_max_latency)
+		lat = pcibios_max_latency;
+	else
+		return;
+	printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
diff -urN linux-2.4.29/arch/frv/mb93090-mb00/pci-frv.h linux-2.4.29-uc1/arch/frv/mb93090-mb00/pci-frv.h
--- linux-2.4.29/arch/frv/mb93090-mb00/pci-frv.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mb93090-mb00/pci-frv.h	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+ *	Low-Level PCI Access for FRV machines.
+ *
+ *	(c) 1999 Martin Mares <mj@ucw.cz>
+ */
+
+#include <asm/vmlinux.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+#define PCI_PROBE_BIOS		0x0001
+#define PCI_PROBE_CONF1		0x0002
+#define PCI_PROBE_CONF2		0x0004
+#define PCI_NO_SORT		0x0100
+#define PCI_BIOS_SORT		0x0200
+#define PCI_NO_CHECKS		0x0400
+#define PCI_ASSIGN_ROMS		0x1000
+#define PCI_BIOS_IRQ_SCAN	0x2000
+#define PCI_ASSIGN_ALL_BUSSES	0x4000
+
+extern unsigned int __nongpreldata pci_probe;
+
+/* pci-i386.c */
+
+extern unsigned int pcibios_max_latency;
+
+void pcibios_resource_survey(void);
+int pcibios_enable_resources(struct pci_dev *, int);
+
+/* pci-pc.c */
+
+extern int __nongpreldata pcibios_last_bus;
+extern struct pci_bus *__nongpreldata pci_root_bus;
+extern struct pci_ops *__nongpreldata pci_root_ops;
+
+/* pci-irq.c */
+extern unsigned int pcibios_irq_mask;
+
+void pcibios_irq_init(void);
+void pcibios_fixup_irqs(void);
+void pcibios_enable_irq(struct pci_dev *dev);
diff -urN linux-2.4.29/arch/frv/mb93090-mb00/pci-irq.c linux-2.4.29-uc1/arch/frv/mb93090-mb00/pci-irq.c
--- linux-2.4.29/arch/frv/mb93090-mb00/pci-irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mb93090-mb00/pci-irq.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,68 @@
+/* pci-irq.c: PCI IRQ routing on the FRV motherboard
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * derived from: arch/i386/kernel/pci-irq.c: (c) 1999--2000 Martin Mares <mj@suse.cz>
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/irq-routing.h>
+
+#include "pci-frv.h"
+
+/*
+ *	DEVICE	DEVNO	INT#A	INT#B	INT#C	INT#D
+ *	=======	=======	=======	=======	=======	=======
+ *	MB86943	0	fpga.10	-	-	-
+ *	RTL8029	16	fpga.12	-	-	-
+ *	SLOT 1	19	fpga.6	fpga.5	fpga.4	fpga.3
+ *	SLOT 2	18	fpga.5	fpga.4	fpga.3	fpga.6
+ *	SLOT 3	17	fpga.4	fpga.3	fpga.6	fpga.5
+ *
+ */
+
+static const uint8_t __initdata pci_bus0_irq_routing[32][4] = {
+	[0 ] {	IRQ_FPGA_MB86943_PCI_INTA },
+	[16] {	IRQ_FPGA_RTL8029_INTA },
+	[17] {	IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD, IRQ_FPGA_PCI_INTA, IRQ_FPGA_PCI_INTB },
+	[18] {	IRQ_FPGA_PCI_INTB, IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD, IRQ_FPGA_PCI_INTA },
+	[19] {	IRQ_FPGA_PCI_INTA, IRQ_FPGA_PCI_INTB, IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD },
+};
+
+void __init pcibios_irq_init(void)
+{
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+	struct pci_dev *dev;
+	uint8_t line, pin;
+
+	pci_for_each_dev(dev) {
+		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+		if (pin) {
+			dev->irq = pci_bus0_irq_routing[PCI_SLOT(dev->devfn)][pin - 1];
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+		}
+		pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
+	}
+}
+
+void __init pcibios_penalize_isa_irq(int irq)
+{
+}
+
+void pcibios_enable_irq(struct pci_dev *dev)
+{
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+}
diff -urN linux-2.4.29/arch/frv/mb93090-mb00/pci-vdk.c linux-2.4.29-uc1/arch/frv/mb93090-mb00/pci-vdk.c
--- linux-2.4.29/arch/frv/mb93090-mb00/pci-vdk.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mb93090-mb00/pci-vdk.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,480 @@
+/* pci-vdk.c: MB93090-MB00 (VDK) PCI support
+ *
+ * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/mb-regs.h>
+#include <asm/mb86943a.h>
+#include "pci-frv.h"
+
+unsigned int __nongpreldata pci_probe = 1;
+
+int  __nongpreldata pcibios_last_bus = -1;
+struct pci_bus *__nongpreldata pci_root_bus;
+struct pci_ops *__nongpreldata pci_root_ops;
+
+/*
+ * Functions for accessing PCI configuration space
+ */
+
+#define CONFIG_CMD(dev, where) \
+	(0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3))
+
+#define __set_PciCfgAddr(A) writel((A), (volatile void *) __region_CS1 + 0x80)
+
+#define __get_PciCfgDataB(A) readb((volatile void *) __region_CS1 + 0x88 + ((A) & 3))
+#define __get_PciCfgDataW(A) readw((volatile void *) __region_CS1 + 0x88 + ((A) & 2))
+#define __get_PciCfgDataL(A) readl((volatile void *) __region_CS1 + 0x88)
+
+#define __set_PciCfgDataB(A,V) \
+	writeb((V), (volatile void *) __region_CS1 + 0x88 + (3 - ((A) & 3)))
+#define __set_PciCfgDataW(A,V) \
+	writew((V), (volatile void *) __region_CS1 + 0x88 + (2 - ((A) & 2)))
+#define __set_PciCfgDataL(A,V) \
+	writel((V), (volatile void *) __region_CS1 + 0x88)
+
+#define __get_PciBridgeDataB(A) readb((volatile void *) __region_CS1 + 0x800 + (A))
+#define __get_PciBridgeDataW(A) readw((volatile void *) __region_CS1 + 0x800 + (A))
+#define __get_PciBridgeDataL(A) readl((volatile void *) __region_CS1 + 0x800 + (A))
+
+#define __set_PciBridgeDataB(A,V) writeb((V), (volatile void *) __region_CS1 + 0x800 + (A))
+#define __set_PciBridgeDataW(A,V) writew((V), (volatile void *) __region_CS1 + 0x800 + (A))
+#define __set_PciBridgeDataL(A,V) writel((V), (volatile void *) __region_CS1 + 0x800 + (A))
+
+static inline int __query(const struct pci_dev *dev)
+{
+//	return dev->bus->number==0 && (dev->devfn==PCI_DEVFN(0,0));
+//	return dev->bus->number==1;
+//	return dev->bus->number==0 &&
+//		(dev->devfn==PCI_DEVFN(2,0) || dev->devfn==PCI_DEVFN(3,0));
+	return 0;
+}
+
+static int pci_frv_read_transmogrify_value(struct pci_dev *dev, int where, u32 *value)
+{
+	uint32_t rawval;
+
+	if (dev->bus->number == 0 && dev->devfn == PCI_DEVFN(0, 0)) {
+		rawval = __get_PciBridgeDataL(where);
+	}
+	else {
+		__set_PciCfgAddr(CONFIG_CMD(dev, where));
+		rawval = __get_PciCfgDataL(where);
+	}
+
+	*value = rawval;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_frv_write_transmogrify_value(struct pci_dev *dev, int where, u32 value)
+{
+	uint32_t rawval;
+
+	rawval = value;
+
+	if (dev->bus->number == 0 && dev->devfn == PCI_DEVFN(0, 0)) {
+		__set_PciBridgeDataL(where, rawval);
+	}
+	else {
+		__set_PciCfgAddr(CONFIG_CMD(dev, where));
+		__set_PciCfgDataL(where, rawval);
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************/
+/*
+ * 
+ */
+static int pci_frv_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	u32 _value;
+	int ret;
+
+	ret = pci_frv_read_transmogrify_value(dev, where & ~3, &_value);
+
+	*value = _value >> ((where & 3) * 8);
+	return ret;
+}
+
+static int pci_frv_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	u32 _value;
+	int ret;
+
+	ret = pci_frv_read_transmogrify_value(dev, where & ~3, &_value);
+
+	*value = _value >> ((where & 2) * 8);
+	return ret;
+}
+
+static int pci_frv_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	int ret;
+
+	ret = pci_frv_read_transmogrify_value(dev, where & ~3, value);
+	return ret;
+}
+
+static int pci_frv_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	if (dev->bus->number == 0 && dev->devfn == PCI_DEVFN(0, 0)) {
+		__set_PciBridgeDataB(where, value);
+	}
+	else {
+		__set_PciCfgAddr(CONFIG_CMD(dev, where));
+		__set_PciCfgDataB(where, value);
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_frv_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	if (dev->bus->number == 0 && dev->devfn == PCI_DEVFN(0, 0)) {
+		__set_PciBridgeDataW(where, value);
+	}
+	else {
+		__set_PciCfgAddr(CONFIG_CMD(dev, where));
+		__set_PciCfgDataW(where, value);
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_frv_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	return pci_frv_write_transmogrify_value(dev, where & ~3, value);
+}
+
+static struct pci_ops pci_direct_frv = {
+	pci_frv_read_config_byte,
+	pci_frv_read_config_word,
+	pci_frv_read_config_dword,
+	pci_frv_write_config_byte,
+	pci_frv_write_config_word,
+	pci_frv_write_config_dword
+};
+
+/*
+ * Before we decide to use direct hardware access mechanisms, we try to do some
+ * trivial checks to ensure it at least _seems_ to be working -- we just test
+ * whether bus 00 contains a host bridge (this is similar to checking
+ * techniques used in XFree86, but ours should be more reliable since we
+ * attempt to make use of direct access hints provided by the PCI BIOS).
+ *
+ * This should be close to trivial, but it isn't, because there are buggy
+ * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
+ */
+static int __init pci_sanity_check(struct pci_ops *o)
+{
+	struct pci_bus bus;		/* Fake bus and device */
+	struct pci_dev dev;
+	u32 id;
+
+	bus.number	= 0;
+	dev.bus		= &bus;
+	dev.devfn	= 0;
+	dev.hdr_type	= 1;
+	strcpy(dev.slot_name,"00:00.0");
+
+	if (o->read_dword(&dev, PCI_VENDOR_ID, &id) == PCIBIOS_SUCCESSFUL) {
+		printk("PCI: VDK Bridge device:vendor: %08x\n", id);
+		if (id == 0x200e10cf)
+			return 1;
+	}
+
+	printk("PCI: VDK Bridge: Sanity check failed\n");
+	return 0;
+}
+
+static struct pci_ops * __init pci_check_direct(void)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	/* check if access works */
+	if (pci_sanity_check(&pci_direct_frv)) {
+		__restore_flags(flags);
+		printk("PCI: Using configuration frv\n");
+//		request_mem_region(0xBE040000, 256, "FRV bridge");
+//		request_mem_region(0xBFFFFFF4, 12, "PCI frv");
+		return &pci_direct_frv;
+	}
+
+	local_irq_restore(flags);
+	return NULL;
+}
+
+/*
+ * Several buggy motherboards address only 16 devices and mirror
+ * them to next 16 IDs. We try to detect this `feature' on all
+ * primary buses (those containing host bridges as they are
+ * expected to be unique) and remove the ghost devices.
+ */
+
+static void __init pcibios_fixup_ghosts(struct pci_bus *b)
+{
+	struct list_head *ln, *mn;
+	struct pci_dev *d, *e;
+	int mirror = PCI_DEVFN(16,0);
+	int seen_host_bridge = 0;
+	int i;
+
+	for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
+		d = pci_dev_b(ln);
+		if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST)
+			seen_host_bridge++;
+		for (mn=ln->next; mn != &b->devices; mn=mn->next) {
+			e = pci_dev_b(mn);
+			if (e->devfn != d->devfn + mirror ||
+			    e->vendor != d->vendor ||
+			    e->device != d->device ||
+			    e->class != d->class)
+				continue;
+			for(i=0; i<PCI_NUM_RESOURCES; i++)
+				if (e->resource[i].start != d->resource[i].start ||
+				    e->resource[i].end != d->resource[i].end ||
+				    e->resource[i].flags != d->resource[i].flags)
+					continue;
+			break;
+		}
+		if (mn == &b->devices)
+			return;
+	}
+	if (!seen_host_bridge)
+		return;
+	printk("PCI: Ignoring ghost devices on bus %02x\n", b->number);
+
+	ln = &b->devices;
+	while (ln->next != &b->devices) {
+		d = pci_dev_b(ln->next);
+		if (d->devfn >= mirror) {
+			list_del(&d->global_list);
+			list_del(&d->bus_list);
+			kfree(d);
+		} else
+			ln = ln->next;
+	}
+}
+
+/*
+ * Discover remaining PCI buses in case there are peer host bridges.
+ * We use the number of last PCI bus provided by the PCI BIOS.
+ */
+static void __init pcibios_fixup_peer_bridges(void)
+{
+	struct pci_bus bus;
+	struct pci_dev dev;
+	int n;
+	u16 l;
+
+	if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff)
+		return;
+	printk("PCI: Peer bridge fixup\n");
+	for (n=0; n <= pcibios_last_bus; n++) {
+		if (pci_bus_exists(&pci_root_buses, n))
+			continue;
+		bus.number = n;
+		bus.ops = pci_root_ops;
+		dev.bus = &bus;
+		for(dev.devfn=0; dev.devfn<256; dev.devfn += 8)
+			if (!pci_read_config_word(&dev, PCI_VENDOR_ID, &l) &&
+			    l != 0x0000 && l != 0xffff) {
+				printk("Found device at %02x:%02x [%04x]\n", n, dev.devfn, l);
+				printk("PCI: Discovered peer bus %02x\n", n);
+				pci_scan_bus(n, pci_root_ops, NULL);
+				break;
+			}
+	}
+}
+
+/*
+ * Exceptions for specific devices. Usually work-arounds for fatal design flaws.
+ */
+
+static void __init pci_fixup_umc_ide(struct pci_dev *d)
+{
+	/*
+	 * UM8886BF IDE controller sets region type bits incorrectly,
+	 * therefore they look like memory despite of them being I/O.
+	 */
+	int i;
+
+	printk("PCI: Fixing base address flags for device %s\n", d->slot_name);
+	for(i=0; i<4; i++)
+		d->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
+}
+
+static void __init pci_fixup_ide_bases(struct pci_dev *d)
+{
+	int i;
+
+	/*
+	 * PCI IDE controllers use non-standard I/O port decoding, respect it.
+	 */
+	if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
+		return;
+	printk("PCI: IDE base address fixup for %s\n", d->slot_name);
+	for(i=0; i<4; i++) {
+		struct resource *r = &d->resource[i];
+		if ((r->start & ~0x80) == 0x374) {
+			r->start |= 2;
+			r->end = r->start;
+		}
+	}
+}
+
+static void __init pci_fixup_ide_trash(struct pci_dev *d)
+{
+	int i;
+
+	/*
+	 * There exist PCI IDE controllers which have utter garbage
+	 * in first four base registers. Ignore that.
+	 */
+	printk("PCI: IDE base address trash cleared for %s\n", d->slot_name);
+	for(i=0; i<4; i++)
+		d->resource[i].start = d->resource[i].end = d->resource[i].flags = 0;
+}
+
+struct pci_fixup pcibios_fixups[] = {
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_UMC,	PCI_DEVICE_ID_UMC_UM8886BF,	pci_fixup_umc_ide },
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_5513,		pci_fixup_ide_trash },
+	{ PCI_FIXUP_HEADER,	PCI_ANY_ID,		PCI_ANY_ID,			pci_fixup_ide_bases },
+	{ 0 }
+};
+
+/*
+ *  Called after each bus is probed, but before its children
+ *  are examined.
+ */
+
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+#if 0
+	printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number);
+#endif
+	pcibios_fixup_ghosts(bus);
+	pci_read_bridge_bases(bus);
+
+	if (bus->number == 0) {
+		struct list_head *ln;
+		struct pci_dev *dev;
+		for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
+			dev = pci_dev_b(ln);
+			if (dev->devfn == 0) {
+				dev->resource[0].start = 0;
+				dev->resource[0].end = 0;
+			}
+		}
+	}
+}
+
+/*
+ * Initialization. Try all known PCI access methods. Note that we support
+ * using both PCI BIOS and direct access: in such cases, we use I/O ports
+ * to access config space, but we still keep BIOS order of cards to be
+ * compatible with 2.0.X. This should go away some day.
+ */
+
+void __init pcibios_init(void)
+{
+	struct pci_ops *dir = NULL;
+
+	if (!mb93090_mb00_detected)
+		return;
+
+	__reg_MB86943_sl_ctl |= MB86943_SL_CTL_DRCT_MASTER_SWAP | MB86943_SL_CTL_DRCT_SLAVE_SWAP;
+
+	__reg_MB86943_ecs_base(1)	= ((__region_CS2 + 0x01000000) >> 9) | 0x08000000;
+	__reg_MB86943_ecs_base(2)	= ((__region_CS2 + 0x00000000) >> 9) | 0x08000000;
+
+	*(volatile uint32_t *) (__region_CS1 + 0x848) = 0xe0000000;
+	*(volatile uint32_t *) (__region_CS1 + 0x8b8) = 0x00000000;
+
+	__reg_MB86943_sl_pci_io_base	= (__region_CS2 + 0x04000000) >> 9;
+	__reg_MB86943_sl_pci_mem_base	= (__region_CS2 + 0x08000000) >> 9;
+	__reg_MB86943_pci_sl_io_base	= __region_CS2 + 0x04000000;
+	__reg_MB86943_pci_sl_mem_base	= __region_CS2 + 0x08000000;
+	mb();
+
+	*(volatile unsigned long *)(__region_CS2+0x01300014) == 1;
+
+	ioport_resource.start	= (__reg_MB86943_sl_pci_io_base << 9) & 0xfffffc00;
+	ioport_resource.end	= (__reg_MB86943_sl_pci_io_range << 9) | 0x3ff;
+	ioport_resource.end	+= ioport_resource.start;
+
+	printk("PCI IO window:  %08lx-%08lx\n", ioport_resource.start, ioport_resource.end);
+
+	iomem_resource.start	= (__reg_MB86943_sl_pci_mem_base << 9) & 0xfffffc00;
+
+	/* Reserve somewhere to write to flush posted writes. */
+	iomem_resource.start += 0x400;
+
+	iomem_resource.end	= (__reg_MB86943_sl_pci_mem_range << 9) | 0x3ff;
+	iomem_resource.end	+= iomem_resource.start;
+
+	printk("PCI MEM window: %08lx-%08lx\n", iomem_resource.start, iomem_resource.end);
+	printk("PCI DMA memory: %08lx-%08lx\n", dma_consistent_mem_start, dma_consistent_mem_end);
+
+	if (!pci_probe)
+		return;
+
+	dir = pci_check_direct();
+	if (dir)
+		pci_root_ops = dir;
+	else {
+		printk("PCI: No PCI bus detected\n");
+		return;
+	}
+
+	printk("PCI: Probing PCI hardware\n");
+	pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);
+
+	pcibios_irq_init();
+	pcibios_fixup_peer_bridges();
+	pcibios_fixup_irqs();
+	pcibios_resource_survey();
+}
+
+char * __init pcibios_setup(char *str)
+{
+	if (!strcmp(str, "off")) {
+		pci_probe = 0;
+		return NULL;
+	} else if (!strncmp(str, "lastbus=", 8)) {
+		pcibios_last_bus = simple_strtol(str+8, NULL, 0);
+		return NULL;
+	}
+	return str;
+}
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+	int err;
+
+	if ((err = pcibios_enable_resources(dev, mask)) < 0)
+		return err;
+	pcibios_enable_irq(dev);
+	return 0;
+}
+
diff -urN linux-2.4.29/arch/frv/mm/cache-page.c linux-2.4.29-uc1/arch/frv/mm/cache-page.c
--- linux-2.4.29/arch/frv/mm/cache-page.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mm/cache-page.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,46 @@
+/* cache-page.c: whole-page cache wrangling functions for MMU linux
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <asm/pgalloc.h>
+
+/*****************************************************************************/
+/*
+ * DCF takes a virtual address and the page may not currently have one
+ * - temporarily hijack a kmap_atomic() slot and attach the page to it
+ */
+void flush_dcache_page(struct page *page)
+{
+	void *vaddr = kmap_atomic(page, __KM_CACHE);
+
+	frv_dcache_writeback((unsigned long) vaddr, (unsigned long) vaddr + PAGE_SIZE);
+
+	kunmap_atomic(vaddr, __KM_CACHE);
+
+} /* end flush_dcache_page() */
+
+/*****************************************************************************/
+/*
+ * ICI takes a virtual address and the page may not currently have one
+ * - so we temporarily attach the page to a bit of virtual space so that is can be flushed
+ */
+void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+			     unsigned long start, unsigned long len)
+{
+	void *vaddr = kmap_atomic(page, __KM_CACHE);
+
+	start = (start & ~PAGE_MASK) | (unsigned long) vaddr;
+	frv_cache_wback_inv(start, start + len);
+
+	kunmap_atomic(vaddr, __KM_CACHE);
+
+} /* end flush_icache_user_range() */
diff -urN linux-2.4.29/arch/frv/mm/dma-alloc.c linux-2.4.29-uc1/arch/frv/mm/dma-alloc.c
--- linux-2.4.29/arch/frv/mm/dma-alloc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mm/dma-alloc.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,184 @@
+/* dma-alloc.c: consistent DMA memory allocation
+ *
+ * Derived from arch/ppc/mm/cachemap.c
+ *
+ *  PowerPC version derived from arch/arm/mm/consistent.c
+ *    Copyright (C) 2001 Dan Malek (dmalek@jlc.net)
+ *
+ *  linux/arch/arm/mm/consistent.c
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * Consistent memory allocators.  Used for DMA devices that want to
+ * share uncached memory with the processor core.  The function return
+ * is the virtual address and 'dma_handle' is the physical address.
+ * Mostly stolen from the ARM port, with some changes for PowerPC.
+ *						-- Dan
+ * Modified for 36-bit support.  -Matt
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+
+static int map_page(unsigned long va, unsigned long pa, pgprot_t prot)
+{
+	pmd_t *pd;
+	pte_t *pg;
+	int err = -ENOMEM;
+
+	spin_lock(&init_mm.page_table_lock);
+
+	/* Use upper 10 bits of VA to index the first level map */
+	pd = pmd_offset(pgd_offset_k(va), va);
+
+	/* Use middle 10 bits of VA to index the second-level map */
+	pg = pte_alloc(&init_mm, pd, va);
+	if (pg != 0) {
+		err = 0;
+		set_pte(pg, mk_pte_phys(pa & PAGE_MASK, prot));
+	}
+
+	spin_unlock(&init_mm.page_table_lock);
+	return err;
+}
+
+/*
+ * This function will allocate the requested contiguous pages and
+ * map them into the kernel's vmalloc() space.  This is done so we
+ * get unique mapping for these pages, outside of the kernel's 1:1
+ * virtual:physical mapping.  This is necessary so we can cover large
+ * portions of the kernel with single large page TLB entries, and
+ * still get unique uncached pages for consistent DMA.
+ */
+void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
+{
+	struct vm_struct *area;
+	unsigned long page, va, pa;
+	void *ret;
+	int order, err, i;
+
+	if (in_interrupt())
+		BUG();
+
+	/* only allocate page size areas */
+	size = PAGE_ALIGN(size);
+	order = get_order(size);
+
+	page = __get_free_pages(gfp, order);
+	if (!page) {
+		BUG();
+		return NULL;
+	}
+
+	/* allocate some common virtual space to map the new pages */
+	area = get_vm_area(size, VM_ALLOC);
+	if (area == 0) {
+		free_pages(page, order);
+		return NULL;
+	}
+	va = VMALLOC_VMADDR(area->addr);
+	ret = (void *) va;
+
+	/* this gives us the real physical address of the first page */
+	*dma_handle = pa = virt_to_bus((void *) page);
+
+	/* set refcount=1 on all pages in an order>0 allocation so that vfree() will actually free
+	 * all pages that were allocated.
+	 */
+	if (order > 0) {
+		struct page *rpage = virt_to_page(page);
+
+		for (i = 1; i < (1 << order); i++)
+			set_page_count(rpage + i, 1);
+	}
+
+	err = 0;
+	for (i = 0; i < size && err == 0; i += PAGE_SIZE)
+		err = map_page(va + i, pa + i, PAGE_KERNEL_NOCACHE);
+
+	if (err) {
+		vfree((void *) va);
+		return NULL;
+	}
+
+	/* we need to ensure that there are no cachelines in use, or worse dirty in this area
+	 * - can't do until after virtual address mappings are created
+	 */
+	frv_cache_invalidate(va, va + size);
+
+	return ret;
+}
+
+/*
+ * free page(s) as defined by the above mapping.
+ */
+void consistent_free(void *vaddr)
+{
+	if (in_interrupt())
+		BUG();
+	vfree(vaddr);
+}
+
+/*
+ * make an area consistent.
+ */
+void consistent_sync(void *vaddr, size_t size, int direction)
+{
+	unsigned long start = (unsigned long) vaddr;
+	unsigned long end   = start + size;
+
+	switch (direction) {
+	case PCI_DMA_NONE:
+		BUG();
+	case PCI_DMA_FROMDEVICE:	/* invalidate only */
+		frv_cache_invalidate(start, end);
+		break;
+	case PCI_DMA_TODEVICE:		/* writeback only */
+		frv_dcache_writeback(start, end);
+		break;
+	case PCI_DMA_BIDIRECTIONAL:	/* writeback and invalidate */
+		frv_dcache_writeback(start, end);
+		break;
+	}
+}
+
+/*
+ * consistent_sync_page make a page are consistent. identical
+ * to consistent_sync, but takes a struct page instead of a virtual address
+ */
+
+void consistent_sync_page(struct page *page, unsigned long offset,
+			  size_t size, int direction)
+{
+	void *start;
+
+	start = page_address(page) + offset;
+	consistent_sync(start, size, direction);
+}
diff -urN linux-2.4.29/arch/frv/mm/elf-fdpic.c linux-2.4.29-uc1/arch/frv/mm/elf-fdpic.c
--- linux-2.4.29/arch/frv/mm/elf-fdpic.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mm/elf-fdpic.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,123 @@
+/* elf-fdpic.c: ELF FDPIC memory layout management
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/elf-fdpic.h>
+
+/*****************************************************************************/
+/*
+ * lay out the userspace VM according to our grand design
+ */
+#ifndef NO_MM
+void elf_fdpic_arch_lay_out_mm(struct elf_fdpic_params *exec_params,
+			       struct elf_fdpic_params *interp_params,
+			       unsigned long *start_stack,
+			       unsigned long *start_brk)
+{
+	*start_stack = 0x02200000UL;
+
+	/* if the only executable is a shared object, assume that it is an interpreter rather than
+	 * a true executable, and map it such that "ld.so --list" comes out right
+	 */
+	if (!(interp_params->flags & ELF_FDPIC_FLAG_PRESENT) &&
+	    exec_params->hdr.e_type != ET_EXEC
+	    ) {
+		exec_params->load_addr = PAGE_SIZE;
+
+		*start_brk = 0x80000000UL;
+	}
+	else {
+		exec_params->load_addr = 0x02200000UL;
+
+		if ((exec_params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) ==
+		    ELF_FDPIC_FLAG_INDEPENDENT
+		    ) {
+			exec_params->flags &= ~ELF_FDPIC_FLAG_ARRANGEMENT;
+			exec_params->flags |= ELF_FDPIC_FLAG_CONSTDISP;
+		}
+	}
+
+} /* end elf_fdpic_arch_lay_out_mm() */
+#endif
+
+/*****************************************************************************/
+/*
+ * place non-fixed mmaps firstly in the bottom part of memory, working up, and then in the top part
+ * of memory, working down
+ */
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len,
+				     unsigned long pgoff, unsigned long flags)
+{
+	struct vm_area_struct *vma;
+	unsigned long limit;
+
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+
+	/* only honour a hint if we're not going to clobber something doing so */
+	if (addr) {
+		addr = PAGE_ALIGN(addr);
+		vma = find_vma(current->mm, addr);
+		if (TASK_SIZE - len >= addr &&
+		    (!vma || addr + len <= vma->vm_start))
+			goto success;
+	}
+
+	/* search between the bottom of user VM and the stack grow area */
+	addr = PAGE_SIZE;
+	limit = (current->mm->start_stack - 0x00200000);
+	if (addr + len <= limit) {
+		limit -= len;
+
+		if (addr <= limit) {
+			vma = find_vma(current->mm, PAGE_SIZE);
+			for (; vma; vma = vma->vm_next) {
+				if (addr > limit)
+					break;
+				if (addr + len <= vma->vm_start)
+					goto success;
+				addr = vma->vm_end;
+			}
+		}
+	}
+
+	/* search from just above the WorkRAM area to the top of memory */
+	addr = PAGE_ALIGN(0x80000000);
+	limit = TASK_SIZE - len;
+	if (addr <= limit) {
+		vma = find_vma(current->mm, addr);
+		for (; vma; vma = vma->vm_next) {
+			if (addr > limit)
+				break;
+			if (addr + len <= vma->vm_start)
+				goto success;
+			addr = vma->vm_end;
+		}
+
+		if (!vma && addr <= limit)
+			goto success;
+	}
+
+#if 0
+	printk("[area] l=%lx (ENOMEM) f='%s'\n",
+	       len, filp ? filp->f_dentry->d_name.name : "");
+#endif
+	return -ENOMEM;
+
+ success:
+#if 0
+	printk("[area] l=%lx ad=%lx f='%s'\n",
+	       len, addr, filp ? filp->f_dentry->d_name.name : "");
+#endif
+	return addr;
+} /* end arch_get_unmapped_area() */
diff -urN linux-2.4.29/arch/frv/mm/extable.c linux-2.4.29-uc1/arch/frv/mm/extable.c
--- linux-2.4.29/arch/frv/mm/extable.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mm/extable.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,91 @@
+/*
+ * linux/arch/frv/mm/extable.c
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+
+extern const struct exception_table_entry __attribute__((aligned(8))) __start___ex_table[];
+extern const struct exception_table_entry __attribute__((aligned(8))) __stop___ex_table[];
+extern const void __memset_end, __memset_user_error_lr, __memset_user_error_handler;
+extern const void __memcpy_end, __memcpy_user_error_lr, __memcpy_user_error_handler;
+extern spinlock_t modlist_lock;
+
+/*****************************************************************************/
+/*
+ *
+ */
+static inline unsigned long search_one_table(const struct exception_table_entry *first,
+					     const struct exception_table_entry *last,
+					     unsigned long value)
+{
+        while (first <= last) {
+		const struct exception_table_entry __attribute__((aligned(8))) *mid;
+		long diff;
+
+		mid = (last - first) / 2 + first;
+		diff = mid->insn - value;
+                if (diff == 0)
+                        return mid->fixup;
+                else if (diff < 0)
+                        first = mid + 1;
+                else
+                        last = mid - 1;
+        }
+        return 0;
+} /* end search_one_table() */
+
+/*****************************************************************************/
+/*
+ * see if there's a fixup handler available to deal with a kernel fault
+ */
+unsigned long search_exception_table(unsigned long pc)
+{
+	unsigned long ret = 0;
+
+	/* determine if the fault lay during a memcpy_user or a memset_user */
+	if (__frame->lr == (unsigned long) &__memset_user_error_lr &&
+	    (unsigned long) &memset <= pc && pc < (unsigned long) &__memset_end
+	    ) {
+		/* the fault occurred in a protected memset
+		 * - we search for the return address (in LR) instead of the program counter
+		 * - it was probably during a clear_user()
+		 */
+		return (unsigned long) &__memset_user_error_handler;
+	}
+	else if (__frame->lr == (unsigned long) &__memcpy_user_error_lr &&
+		 (unsigned long) &memcpy <= pc && pc < (unsigned long) &__memcpy_end
+		 ) {
+		/* the fault occurred in a protected memset
+		 * - we search for the return address (in LR) instead of the program counter
+		 * - it was probably during a copy_to/from_user()
+		 */
+		return (unsigned long) &__memcpy_user_error_handler;
+	}
+
+#ifndef CONFIG_MODULES
+	/* there is only the kernel to search.  */
+	ret = search_one_table(__start___ex_table, __stop___ex_table - 1, pc);
+	return ret;
+
+#else
+	/* the kernel is the last "module" -- no need to treat it special */
+	unsigned long flags;
+	struct module *mp;
+
+	spin_lock_irqsave(&modlist_lock, flags);
+
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (mp->ex_table_start == NULL || !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
+			continue;
+		ret = search_one_table(mp->ex_table_start, mp->ex_table_end - 1, pc);
+		if (ret)
+			break;
+	}
+
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
+#endif
+} /* end search_exception_table() */
diff -urN linux-2.4.29/arch/frv/mm/fault.c linux-2.4.29-uc1/arch/frv/mm/fault.c
--- linux-2.4.29/arch/frv/mm/fault.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mm/fault.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,312 @@
+/*
+ *  linux/arch/frv/mm/fault.c
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * - Written by David Howells (dhowells@redhat.com)
+ * - Derived from arch/m68knommu/mm/fault.c
+ *   - Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *   - Copyright (C) 2000  Lineo, Inc.  (www.lineo.com)
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68k/mm/fault.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ */
+
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/hardirq.h>
+#include <asm/uaccess.h>
+
+/*****************************************************************************/
+/*
+ * This routine handles page faults.  It determines the problem, and
+ * then passes it off to one of the appropriate routines.
+ */
+asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear0)
+{
+	struct mm_struct *mm;
+	struct vm_area_struct * vma;
+	unsigned long _pme, lrai, lrad, fixup;
+	int write;
+	siginfo_t info;
+	pgd_t *pge;
+	pte_t *pte;
+
+#if 0
+	const char *atxc[16] = {
+		[0x0] = "mmu-miss", [0x8] = "multi-dat", [0x9] = "multi-sat",
+		[0xa] = "tlb-miss", [0xc] = "privilege", [0xd] = "write-prot",
+	};
+
+	printk("do_page_fault(%d,%lx [%s],%lx)\n",
+	       datammu, esr0, atxc[esr0 >> 20 & 0xf], ear0);
+#endif
+
+	mm = current->mm;
+
+	/*
+	 * We fault-in kernel-space virtual memory on-demand. The
+	 * 'reference' page table is init_mm.pgd.
+	 *
+	 * NOTE! We MUST NOT take any locks for this case. We may
+	 * be in an interrupt or a critical region, and should
+	 * only copy the information from the master page table,
+	 * nothing more.
+	 *
+	 * This verifies that the fault happens in kernel space
+	 * and that the fault was a page not present (invalid) error
+	 */
+	if (!user_mode(__frame) && (esr0 & ESR0_ATXC) == ESR0_ATXC_AMRTLB_MISS) {
+		if (ear0 >= VMALLOC_START && ear0 < VMALLOC_END)
+			goto kernel_pte_fault;
+		if (ear0 >= PKMAP_BASE && ear0 < PKMAP_END)
+			goto kernel_pte_fault;
+	}
+
+	info.si_code = SEGV_MAPERR;
+
+	/*
+	 * If we're in an interrupt or have no user
+	 * context, we must not take the fault..
+	 */
+	if (in_interrupt() || !mm)
+		goto no_context;
+
+	down_read(&mm->mmap_sem);
+
+	vma = find_vma(mm, ear0);
+	if (!vma)
+		goto bad_area;
+	if (vma->vm_start <= ear0)
+		goto good_area;
+	if (!(vma->vm_flags & VM_GROWSDOWN))
+		goto bad_area;
+
+	if (user_mode(__frame)) {
+		/*
+		 * accessing the stack below %esp is always a bug.
+		 * The "+ 32" is there due to some instructions (like
+		 * pusha) doing post-decrement on the stack and that
+		 * doesn't show up until later..
+		 */
+		if ((ear0 & PAGE_MASK) + 2 * PAGE_SIZE < __frame->sp) {
+#if 0
+			printk("[%d] ### Access below stack @%lx (sp=%lx)\n",
+			       current->pid, ear0, __frame->sp);
+			show_registers(__frame);
+			printk("[%d] ### Code: [%08lx] %02x %02x %02x %02x %02x %02x %02x %02x\n",
+			       current->pid,
+			       __frame->pc,
+			       ((u8*)__frame->pc)[0],
+			       ((u8*)__frame->pc)[1],
+			       ((u8*)__frame->pc)[2],
+			       ((u8*)__frame->pc)[3],
+			       ((u8*)__frame->pc)[4],
+			       ((u8*)__frame->pc)[5],
+			       ((u8*)__frame->pc)[6],
+			       ((u8*)__frame->pc)[7]
+			       );
+#endif
+			goto bad_area;
+		}
+	}
+	if (expand_stack(vma, ear0))
+		goto bad_area;
+
+/*
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it..
+ */
+ good_area:
+	info.si_code = SEGV_ACCERR;
+	write = 0;
+	switch (esr0 & ESR0_ATXC) {
+	default:
+		/* handle write to write protected page */
+	case ESR0_ATXC_WP_EXCEP:
+#ifdef TEST_VERIFY_AREA
+		if (!(user_mode(__frame)))
+			printk("WP fault at %08lx\n", __frame->pc);
+#endif
+		if (!(vma->vm_flags & VM_WRITE))
+			goto bad_area;
+		write = 1;
+		break;
+
+		 /* handle read from protected page */
+	case ESR0_ATXC_PRIV_EXCEP:
+		goto bad_area;
+
+		 /* handle read, write or exec on absent page
+		  * - can't support write without permitting read
+		  * - don't support execute without permitting read and vice-versa
+		  */
+	case ESR0_ATXC_AMRTLB_MISS:
+		if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
+			goto bad_area;
+		break;
+	}
+
+	/*
+	 * If for any reason at all we couldn't handle the fault,
+	 * make sure we exit gracefully rather than endlessly redo
+	 * the fault.
+	 */
+	switch (handle_mm_fault(mm, vma, ear0, write)) {
+	case 1:
+		current->min_flt++;
+		break;
+	case 2:
+		current->maj_flt++;
+		break;
+	case 0:
+		goto do_sigbus;
+	default:
+		goto out_of_memory;
+	}
+
+	up_read(&mm->mmap_sem);
+	return;
+
+/*
+ * Something tried to access memory that isn't in our memory map..
+ * Fix it, but check if it's kernel or user first..
+ */
+ bad_area:
+	up_read(&mm->mmap_sem);
+
+	/* User mode accesses just cause a SIGSEGV */
+	if (user_mode(__frame)) {
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		/* info.si_code has been set above */
+		info.si_addr = (void *) ear0;
+		force_sig_info(SIGSEGV, &info, current);
+		return;
+	}
+
+ no_context:
+	/* are we prepared to handle this kernel fault? */
+	if ((fixup = search_exception_table(__frame->pc)) != 0) {
+		__frame->pc = fixup;
+		return;
+	}
+
+/*
+ * Oops. The kernel tried to access some bad page. We'll have to
+ * terminate things with extreme prejudice.
+ */
+
+	bust_spinlocks(1);
+
+	if (ear0 < PAGE_SIZE)
+		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
+	else
+		printk(KERN_ALERT "Unable to handle kernel paging request");
+	printk(" at virtual addr %08lx\n", ear0);
+	printk("  PC  : %08lx\n", __frame->pc);
+	printk("  EXC : esr0=%08lx ear0=%08lx\n", esr0, ear0);
+
+	asm("lrai %1,%0,#1,#0,#0" : "=&r"(lrai) : "r"(ear0));
+	asm("lrad %1,%0,#1,#0,#0" : "=&r"(lrad) : "r"(ear0));
+
+	printk(KERN_ALERT "  LRAI: %08lx\n", lrai);
+	printk(KERN_ALERT "  LRAD: %08lx\n", lrad);
+
+	pge = mm->pgd + pgd_index(ear0);
+	_pme = pge->pge[0].ste[0];
+
+	printk(KERN_ALERT "  PGE : %8p { PME %08lx }\n", pge, _pme);
+
+	if (_pme & xAMPRx_V) {
+		unsigned long dampr, damlr, val;
+
+		asm volatile("movsg dampr2,%0 ! movgs %2,dampr2 ! movsg damlr2,%1"
+			     : "=&r"(dampr), "=r"(damlr)
+			     : "r" (_pme | xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V)
+			     );
+
+		pte = (pte_t *) damlr + __pte_index(ear0);
+		val = pte_val(*pte);
+
+		asm volatile("movgs %0,dampr2" :: "r" (dampr));
+
+		printk(KERN_ALERT "  PTE : %8p { %08lx }\n", pte, val);
+	}
+
+	die_if_kernel("Oops\n");
+	do_exit(SIGKILL);
+
+/*
+ * We ran out of memory, or some other thing happened to us that made
+ * us unable to handle the page fault gracefully.
+ */
+ out_of_memory:
+	up_read(&mm->mmap_sem);
+	printk("VM: killing process %s\n", current->comm);
+	if (user_mode(__frame))
+		do_exit(SIGKILL);
+	goto no_context;
+
+ do_sigbus:
+	up_read(&mm->mmap_sem);
+
+	/*
+	 * Send a sigbus, regardless of whether we were in kernel
+	 * or user mode.
+	 */
+	info.si_signo = SIGBUS;
+	info.si_errno = 0;
+	info.si_code = BUS_ADRERR;
+	info.si_addr = (void *) ear0;
+	force_sig_info(SIGBUS, &info, current);
+
+	/* Kernel mode? Handle exceptions or die */
+	if (!user_mode(__frame))
+		goto no_context;
+	return;
+
+/*
+ * The fault was caused by a kernel PTE (such as installed by vmalloc or kmap)
+ */
+ kernel_pte_fault:
+	{
+		/*
+		 * Synchronize this task's top level page-table
+		 * with the 'reference' page table.
+		 *
+		 * Do _not_ use "tsk" here. We might be inside
+		 * an interrupt in the middle of a task switch..
+		 */
+		int offset = __pgd_offset(ear0);
+		pgd_t *pgd, *pgd_k;
+		pmd_t *pmd, *pmd_k;
+		pte_t *pte_k;
+
+		pgd = (pgd_t *) __get_TTBR();
+		pgd = offset + (pgd_t *) __va(pgd);
+		pgd_k = init_mm.pgd + offset;
+
+		if (!pgd_present(*pgd_k))
+			goto no_context;
+		set_pgd(pgd, *pgd_k);
+
+		pmd = pmd_offset(pgd, ear0);
+		pmd_k = pmd_offset(pgd_k, ear0);
+		if (!pmd_present(*pmd_k))
+			goto no_context;
+		set_pmd(pmd, *pmd_k);
+
+		pte_k = pte_offset(pmd_k, ear0);
+		if (!pte_present(*pte_k))
+			goto no_context;
+		return;
+	}
+} /* end do_page_fault() */
diff -urN linux-2.4.29/arch/frv/mm/init.c linux-2.4.29-uc1/arch/frv/mm/init.c
--- linux-2.4.29/arch/frv/mm/init.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mm/init.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,259 @@
+/* init.c: memory initialisation for FRV
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Derived from:
+ *  - linux/arch/m68knommu/mm/init.c
+ *    - Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>, Kenneth Albanowski <kjahds@kjahds.com>,
+ *    - Copyright (C) 2000  Lineo, Inc.  (www.lineo.com) 
+ *  - linux/arch/m68k/mm/init.c
+ *    - Copyright (C) 1995  Hamish Macdonald
+ */
+
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/virtconvert.h>
+#include <asm/vmlinux.h>
+
+#undef DEBUG
+
+static unsigned long __nongprelbss totalram_pages;
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+static unsigned long empty_bad_page_table;
+static unsigned long empty_bad_page;
+unsigned long empty_zero_page;
+
+/*****************************************************************************/
+/*
+ * 
+ */
+void show_mem(void)
+{
+	unsigned long i;
+	int free = 0, total = 0, reserved = 0, shared = 0;
+
+	printk("\nMem-info:\n");
+	show_free_areas();
+	i = max_mapnr;
+	while (i-- > 0) {
+		struct page *page = &mem_map[i];
+
+		total++;
+		if (PageReserved(page))
+			reserved++;
+		else if (!page_count(page))
+			free++;
+		else
+			shared += page_count(page) - 1;
+	}
+
+	printk("%d pages of RAM\n",total);
+	printk("%d free pages\n",free);
+	printk("%d reserved pages\n",reserved);
+	printk("%d pages shared\n",shared);
+	show_buffers();
+} /* end show_mem() */
+
+/*****************************************************************************/
+/*
+ * paging_init() continues the virtual memory environment setup which
+ * was begun by the code in arch/head.S.
+ * The parameters are pointers to where to stick the starting and ending
+ * addresses  of available kernel virtual memory.
+ */
+void paging_init(void)
+{
+	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+
+	/* allocate some pages for kernel housekeeping tasks */
+	empty_bad_page_table	= (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
+	empty_bad_page		= (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
+	empty_zero_page		= (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
+
+	memset((void *) empty_zero_page, 0, PAGE_SIZE);
+
+#if CONFIG_HIGHMEM
+	if (num_physpages - num_mappedpages) {
+		pgd_t *pge;
+		pmd_t *pme;
+
+		pkmap_page_table = alloc_bootmem_pages(PAGE_SIZE);
+
+		memset(pkmap_page_table, 0, PAGE_SIZE);
+
+		pge = swapper_pg_dir + __pgd_offset(PKMAP_BASE);
+		pme = pmd_offset(pge, PKMAP_BASE);
+		__set_pmd(pme, virt_to_phys(pkmap_page_table) | _PAGE_TABLE);
+	}
+#endif
+
+	/* distribute the allocatable pages across the various zones and pass them to the allocator
+	 */
+	zones_size[ZONE_DMA]     = num_mappedpages;
+	zones_size[ZONE_NORMAL]  = 0 >> PAGE_SHIFT;
+#ifdef CONFIG_HIGHMEM
+	zones_size[ZONE_HIGHMEM] = num_physpages - num_mappedpages;
+#endif
+
+	free_area_init_node(0, NULL, NULL, zones_size, __pa(PAGE_OFFSET), NULL);
+
+#ifndef CONFIG_UCLINUX
+	/* high memory (if present) starts after the last mapped page
+	 * - this is used by kmap()
+	 */
+	extern struct page *highmem_start_page;
+	highmem_start_page = mem_map + num_mappedpages;
+
+	/* initialise init's MMU context */
+	init_new_context(&init_task, &init_mm);
+#endif
+
+} /* end paging_init() */
+
+/*****************************************************************************/
+/*
+ * 
+ */
+void mem_init(void)
+{
+	unsigned long npages = (memory_end - memory_start) >> PAGE_SHIFT;
+	unsigned long tmp;
+#ifndef CONFIG_UCLINUX
+	unsigned long loop, pfn;
+	int datapages = 0;
+#endif
+	int codek = 0, datak = 0;
+
+	/* this will put all memory onto the freelists */
+	totalram_pages = free_all_bootmem();
+
+#ifndef CONFIG_UCLINUX
+	for (loop = 0 ; loop < npages ; loop++)
+		if (PageReserved(&mem_map[loop]))
+			datapages++;
+
+#ifdef CONFIG_HIGHMEM
+	for (pfn = num_physpages - 1; pfn >= num_mappedpages; pfn--) {
+		struct page *page = &mem_map[pfn];
+
+		ClearPageReserved(page);
+		set_bit(PG_highmem, &page->flags);
+		atomic_set(&page->count, 1);
+		__free_page(page);
+		totalram_pages++;
+	}
+#endif
+	
+	codek = ((unsigned long) &_etext - (unsigned long) &_stext) >> 10;
+	datak = datapages << (PAGE_SHIFT - 10);
+
+#else
+	codek = (_etext - _stext) >> 10;
+	datak = 0; //(_ebss - _sdata) >> 10;
+#endif
+
+	tmp = nr_free_pages() << PAGE_SHIFT;
+	printk("Memory available: %luKiB/%luKiB RAM, %luKiB/%luKiB ROM (%dKiB kernel code, %dKiB data)\n",
+	       tmp >> 10,
+	       npages << (PAGE_SHIFT - 10),
+	       (rom_length > 0) ? ((rom_length >> 10) - codek) : 0,
+	       rom_length >> 10,
+	       codek,
+	       datak
+	       );
+} /* end mem_init() */
+
+/*****************************************************************************/
+/*
+ * free the memory that was only required for initialisation
+ */
+void free_initmem(void)
+{
+#if defined(CONFIG_RAMKERNEL) && !defined(CONFIG_PROTECT_KERNEL)
+	unsigned long start, end, addr;
+
+	start = PAGE_ALIGN((unsigned long) &__init_begin);	/* round up */
+	end   = ((unsigned long) &__init_end) & PAGE_MASK;	/* round down */
+
+	/* next to check that the page we free is not a partial page */
+	for (addr = start; addr < end; addr += PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(addr));
+		set_page_count(virt_to_page(addr), 1);
+		free_page(addr);
+		totalram_pages++;
+	}
+
+	printk("Freeing unused kernel memory: %ldKiB freed (0x%lx - 0x%lx)\n",
+	       (end - start) >> 10, start, end);
+#endif
+} /* end free_initmem() */
+
+/*****************************************************************************/
+/*
+ * free the initial ramdisk memory
+ */
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	int pages = 0;
+	for (; start < end; start += PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(start));
+		set_page_count(virt_to_page(start), 1);
+		free_page(start);
+		totalram_pages++;
+		pages++;
+	}
+	printk("Freeing initrd memory: %dKiB freed\n", (pages * PAGE_SIZE) >> 10);
+} /* end free_initrd_mem() */
+#endif
+
+/*****************************************************************************/
+/*
+ * enquire about memory statistics
+ */
+void si_meminfo(struct sysinfo *val)
+{
+	val->totalram	= totalram_pages;
+	val->sharedram	= 0;
+	val->freeram	= nr_free_pages();
+	val->bufferram	= atomic_read(&buffermem_pages);
+	val->totalhigh	= num_physpages - num_mappedpages;
+	val->freehigh	= nr_free_highpages();
+	val->mem_unit	= PAGE_SIZE;
+
+} /* end si_meminfo() */
+
diff -urN linux-2.4.29/arch/frv/mm/kmap.c linux-2.4.29-uc1/arch/frv/mm/kmap.c
--- linux-2.4.29/arch/frv/mm/kmap.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mm/kmap.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,56 @@
+/*
+ *  linux/arch/m68knommu/mm/kmap.c
+ *
+ *  Copyright (C) 2000 Lineo, <davidm@lineo.com>
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#undef DEBUG
+
+/*****************************************************************************/
+/*
+ * Map some physical address range into the kernel address space.
+ */
+
+void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
+{
+	return (void *)physaddr;
+}
+
+/*
+ * Unmap a ioremap()ed region again
+ */
+void iounmap(void *addr)
+{
+}
+
+/*
+ * __iounmap unmaps nearly everything, so be careful
+ * it doesn't free currently pointer/page tables anymore but it
+ * wans't used anyway and might be added later.
+ */
+void __iounmap(void *addr, unsigned long size)
+{
+}
+
+/*
+ * Set new cache mode for some kernel address space.
+ * The caller must push data for that range itself, if such data may already
+ * be in the cache.
+ */
+void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
+{
+}
diff -urN linux-2.4.29/arch/frv/mm/Makefile linux-2.4.29-uc1/arch/frv/mm/Makefile
--- linux-2.4.29/arch/frv/mm/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mm/Makefile	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,17 @@
+#
+# Makefile for the linux m68k-specific parts of the memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET := mm.o
+obj-y	 := init.o kmap.o
+
+obj-$(CONFIG_MMU_LINUX) += \
+	pgalloc.o fault.o extable.o cache-page.o tlb-flush.o tlb-miss.o \
+	mmu-context.o dma-alloc.o unaligned.o elf-fdpic.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/frv/mm/mmu-context.c linux-2.4.29-uc1/arch/frv/mm/mmu-context.c
--- linux-2.4.29/arch/frv/mm/mmu-context.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mm/mmu-context.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,205 @@
+/* mmu-context.c: MMU context allocation and management
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#define NR_CXN	4096
+
+static unsigned long cxn_bitmap[NR_CXN / (sizeof(unsigned long) * 8)];
+static LIST_HEAD(cxn_owners_lru);
+static spinlock_t cxn_owners_lock = SPIN_LOCK_UNLOCKED;
+
+int __nongpreldata cxn_pinned = -1;
+
+
+/*****************************************************************************/
+/*
+ * initialise a new context
+ */
+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	memset(&mm->context, 0, sizeof(mm->context));
+	INIT_LIST_HEAD(&mm->context.id_link);
+	mm->context.itlb_cached_pge = 0xffffffffUL;
+	mm->context.dtlb_cached_pge = 0xffffffffUL;
+
+	return 0;
+} /* end init_new_context() */
+
+/*****************************************************************************/
+/*
+ * make sure a kernel MMU context has a CPU context number
+ * - call with cxn_owners_lock held
+ */
+static unsigned get_cxn(mm_context_t *ctx)
+{
+	struct list_head *_p;
+	mm_context_t *p;
+	unsigned cxn;
+
+	if (!list_empty(&ctx->id_link)) {
+		list_move_tail(&ctx->id_link, &cxn_owners_lru);
+	}
+	else {
+		/* find the first unallocated context number
+		 * - 0 is reserved for the kernel
+		 */
+		cxn = find_next_zero_bit(&cxn_bitmap, NR_CXN, 1);
+		if (cxn < NR_CXN) {
+			set_bit(cxn, &cxn_bitmap);
+		}
+		else {
+			/* none remaining - need to steal someone else's cxn */
+			p = NULL;
+			list_for_each(_p, &cxn_owners_lru) {
+				p = list_entry(_p, mm_context_t, id_link);
+				if (!p->id_busy && p->id != cxn_pinned)
+					break;
+			}
+
+			BUG_ON(_p == &cxn_owners_lru);
+
+			cxn = p->id;
+			p->id = 0;
+			list_del_init(&p->id_link);
+			__flush_tlb_mm(cxn);
+		}
+
+		ctx->id = cxn;
+		list_add_tail(&ctx->id_link, &cxn_owners_lru);
+	}
+
+	return ctx->id;
+} /* end get_cxn() */
+
+/*****************************************************************************/
+/*
+ * restore the current TLB miss handler mapped page tables into the MMU context and set up a
+ * mapping for the page directory
+ */
+void change_mm_context(mm_context_t *old, mm_context_t *ctx, pgd_t *_pgd)
+{
+	unsigned long pgd = virt_to_phys(_pgd);
+
+	/* save the state of the outgoing MMU context */
+	old->id_busy = 0;
+
+	asm volatile("movsg scr0,%0"   : "=r"(old->itlb_cached_pge));
+	asm volatile("movsg dampr4,%0" : "=r"(old->itlb_ptd_mapping));
+	asm volatile("movsg scr1,%0"   : "=r"(old->dtlb_cached_pge));
+	asm volatile("movsg dampr5,%0" : "=r"(old->dtlb_ptd_mapping));
+
+	/* select an MMU context number */
+	spin_lock(&cxn_owners_lock);
+	get_cxn(ctx);
+	ctx->id_busy = 1;
+	spin_unlock(&cxn_owners_lock);
+
+	asm volatile("movgs %0,cxnr"   : : "r"(ctx->id));
+
+	/* restore the state of the incoming MMU context */
+	asm volatile("movgs %0,scr0"   : : "r"(ctx->itlb_cached_pge));
+	asm volatile("movgs %0,dampr4" : : "r"(ctx->itlb_ptd_mapping));
+	asm volatile("movgs %0,scr1"   : : "r"(ctx->dtlb_cached_pge));
+	asm volatile("movgs %0,dampr5" : : "r"(ctx->dtlb_ptd_mapping));
+
+	/* map the PGD into uncached virtual memory */
+	asm volatile("movgs %0,ttbr"   : : "r"(pgd));
+	asm volatile("movgs %0,dampr3"
+		     :: "r"(pgd | xAMPRx_L | xAMPRx_M | xAMPRx_SS_16Kb |
+			    xAMPRx_S | xAMPRx_C | xAMPRx_V));
+
+} /* end change_mm_context() */
+
+/*****************************************************************************/
+/*
+ * finished with an MMU context number
+ */
+void destroy_context(struct mm_struct *mm)
+{
+	mm_context_t *ctx = &mm->context;
+
+	spin_lock(&cxn_owners_lock);
+
+	if (!list_empty(&ctx->id_link)) {
+		if (ctx->id == cxn_pinned)
+			cxn_pinned = -1;
+
+		list_del_init(&ctx->id_link);
+		clear_bit(ctx->id, &cxn_bitmap);
+		__flush_tlb_mm(ctx->id);
+		ctx->id = 0;
+	}
+
+	spin_unlock(&cxn_owners_lock);
+} /* end destroy_context() */
+
+/*****************************************************************************/
+/*
+ * display the MMU context currently a process is currently using
+ */
+#ifdef CONFIG_PROC_FS
+char *proc_pid_status_frv_cxnr(struct mm_struct *mm, char *buffer)
+{
+	spin_lock(&cxn_owners_lock);
+	buffer += sprintf(buffer, "CXNR: %u\n", mm->context.id);
+	spin_unlock(&cxn_owners_lock);
+
+	return buffer;
+} /* end proc_pid_status_frv_cxnr() */
+#endif
+
+/*****************************************************************************/
+/*
+ * (un)pin a process's mm_struct's MMU context ID
+ */
+int cxn_pin_by_pid(pid_t pid)
+{
+	struct task_struct *tsk;
+	struct mm_struct *mm = NULL;
+	int ret;
+
+	/* unpin if pid is zero */
+	if (pid == 0) {
+		cxn_pinned = -1;
+		return 0;
+	}
+
+	ret = -ESRCH;
+
+	/* get a handle on the mm_struct */
+	read_lock(&tasklist_lock);
+	tsk = find_task_by_pid(pid);
+	if (tsk) {
+		ret = -EINVAL;
+
+		task_lock(tsk);
+		if (tsk->mm) {
+			mm = tsk->mm;
+			atomic_inc(&mm->mm_users);
+			ret = 0;
+		}
+		task_unlock(tsk);
+	}
+	read_unlock(&tasklist_lock);
+
+	if (ret < 0)
+		return ret;
+
+	/* make sure it has a CXN and pin it */
+	spin_lock(&cxn_owners_lock);
+	cxn_pinned = get_cxn(&mm->context);
+	spin_unlock(&cxn_owners_lock);
+
+	mmput(mm);
+	return 0;
+} /* end cxn_pin_by_pid() */
diff -urN linux-2.4.29/arch/frv/mm/pgalloc.c linux-2.4.29-uc1/arch/frv/mm/pgalloc.c
--- linux-2.4.29/arch/frv/mm/pgalloc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mm/pgalloc.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,95 @@
+/* pgalloc.c: page directory & page table allocation
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <asm/pgalloc.h>
+
+pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((aligned(PAGE_SIZE)));
+
+pgd_t *get_pgd_slow(void)
+{
+	struct page *page;
+	pgd_t *pgd;
+
+	page = alloc_pages(GFP_KERNEL, 0);
+	if (!page)
+		return 0;
+
+	pgd = (pgd_t *) page_address(page);
+	clear_page(pgd);
+
+	memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
+	memcpy(pgd + USER_PTRS_PER_PGD,
+	       swapper_pg_dir + USER_PTRS_PER_PGD,
+	       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+
+	flush_dcache_page(page);
+	return pgd;
+}
+
+pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+	struct page *page;
+	pte_t *pte;
+
+	page = alloc_pages(GFP_KERNEL, 0);
+	if (!page)
+		return 0;
+
+	pte = (pte_t *) page_address(page);
+	clear_page(pte);
+	flush_dcache_page(page);
+	return pte;
+}
+
+int do_check_pgt_cache(int low, int high)
+{
+	int freed = 0;
+
+	if (pgtable_cache_size > high) {
+		do {
+			if (pgd_quicklist) {
+				free_pgd_slow(get_pgd_fast());
+				freed++;
+			}
+			if (pmd_quicklist) {
+				pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
+				freed++;
+			}
+			if (pte_quicklist) {
+				pte_free_slow(pte_alloc_one_fast(NULL, 0));
+				freed++;
+			}
+		} while(pgtable_cache_size > low);
+	}
+
+	return freed;
+}
+
+void __set_pmd(pmd_t *pmdptr, unsigned long __pmd)
+{
+	unsigned long *__ste_p = pmdptr->ste;
+	int loop;
+
+	if (!__pmd) {
+		memset(__ste_p, 0, PME_SIZE);
+	}
+	else {
+		for (loop = PME_SIZE; loop > 0; loop -= 4) {
+			*__ste_p++ = __pmd;
+			__pmd += __frv_PT_SIZE;
+		}
+	}
+
+	frv_dcache_writeback((unsigned long) pmdptr, (unsigned long) (pmdptr + 1));
+}
diff -urN linux-2.4.29/arch/frv/mm/tlb-flush.S linux-2.4.29-uc1/arch/frv/mm/tlb-flush.S
--- linux-2.4.29/arch/frv/mm/tlb-flush.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mm/tlb-flush.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,185 @@
+/* tlb-flush.S: TLB flushing routines
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include <asm/spr-regs.h>
+
+.macro DEBUG ch
+#	sethi.p		%hi(0xfeff9c00),gr4
+#	setlo		%lo(0xfeff9c00),gr4
+#	setlos		#\ch,gr5
+#	stbi		gr5,@(gr4,#0)
+#	membar
+.endm
+
+	.section	.rodata
+
+	# sizes corresponding to TPXR.LMAX
+	.balign		1
+__tlb_lmax_sizes:
+	.byte		0, 64, 0, 0
+	.byte		0, 0, 0, 0
+	.byte		0, 0, 0, 0
+	.byte		0, 0, 0, 0
+
+	.section	.text
+	.balign		4
+
+###############################################################################
+#
+# flush everything
+# - void __flush_tlb_all(void)
+#
+###############################################################################
+	.globl		__flush_tlb_all
+	.type		__flush_tlb_all,@function
+__flush_tlb_all:
+	DEBUG		'A'
+
+	# kill cached PGE value
+	setlos		#0xffffffff,gr4
+	movgs		gr4,scr0
+	movgs		gr4,scr1
+
+	# kill AMPR-cached TLB values
+	movgs		gr0,iamlr1
+	movgs		gr0,iampr1
+	movgs		gr0,damlr1
+	movgs		gr0,dampr1
+
+	# find out how many lines there are
+	movsg		tpxr,gr5
+	sethi.p		%hi(__tlb_lmax_sizes),gr4
+	srli		gr5,#TPXR_LMAX_SHIFT,gr5
+	setlo.p		%lo(__tlb_lmax_sizes),gr4
+	andi		gr5,#TPXR_LMAX_SMASK,gr5
+	ldub		@(gr4,gr5),gr4
+
+	# now, we assume that the TLB line step is page size in size
+	setlos.p	#PAGE_SIZE,gr5
+	setlos		#0,gr6
+1:
+	tlbpr		gr6,gr0,#6,#0
+	subicc.p	gr4,#1,gr4,icc0
+	add		gr6,gr5,gr6
+	bne		icc0,#2,1b
+
+	DEBUG		'B'
+	bralr
+
+	.size		__flush_tlb_all, .-__flush_tlb_all
+
+###############################################################################
+#
+# flush everything to do with one context
+# - void __flush_tlb_mm(unsigned long contextid [GR8])
+#
+###############################################################################
+	.globl		__flush_tlb_mm
+	.type		__flush_tlb_mm,@function
+__flush_tlb_mm:
+	DEBUG		'M'
+
+	# kill cached PGE value
+	setlos		#0xffffffff,gr4
+	movgs		gr4,scr0
+	movgs		gr4,scr1
+
+	# specify the context we want to flush
+	movgs		gr8,tplr
+
+	# find out how many lines there are
+	movsg		tpxr,gr5
+	sethi.p		%hi(__tlb_lmax_sizes),gr4
+	srli		gr5,#TPXR_LMAX_SHIFT,gr5
+	setlo.p		%lo(__tlb_lmax_sizes),gr4
+	andi		gr5,#TPXR_LMAX_SMASK,gr5
+	ldub		@(gr4,gr5),gr4
+
+	# now, we assume that the TLB line step is page size in size
+	setlos.p	#PAGE_SIZE,gr5
+	setlos		#0,gr6
+0:
+	tlbpr		gr6,gr0,#5,#0
+	subicc.p	gr4,#1,gr4,icc0
+	add		gr6,gr5,gr6
+	bne		icc0,#2,0b
+
+	DEBUG		'N'
+	bralr
+
+	.size		__flush_tlb_mm, .-__flush_tlb_mm
+
+###############################################################################
+#
+# flush a range of addresses from the TLB
+# - void __flush_tlb_page(unsigned long contextid [GR8],
+#			  unsigned long start [GR9])
+#
+###############################################################################
+	.globl		__flush_tlb_page
+	.type		__flush_tlb_page,@function
+__flush_tlb_page:
+	# kill cached PGE value
+	setlos		#0xffffffff,gr4
+	movgs		gr4,scr0
+	movgs		gr4,scr1
+
+	# specify the context we want to flush
+	movgs		gr8,tplr
+
+	# zap the matching TLB line and AMR values
+	setlos		#~(PAGE_SIZE-1),gr5
+	and		gr9,gr5,gr9
+	tlbpr		gr9,gr0,#5,#0
+
+	bralr
+
+	.size		__flush_tlb_page, .-__flush_tlb_page
+
+###############################################################################
+#
+# flush a range of addresses from the TLB
+# - void __flush_tlb_range(unsigned long contextid [GR8],
+#			   unsigned long start [GR9],
+#			   unsigned long end [GR10])
+#
+###############################################################################
+	.globl		__flush_tlb_range
+	.type		__flush_tlb_range,@function
+__flush_tlb_range:
+	# kill cached PGE value
+	setlos		#0xffffffff,gr4
+	movgs		gr4,scr0
+	movgs		gr4,scr1
+
+	# specify the context we want to flush
+	movgs		gr8,tplr
+
+	# round the start down to beginning of TLB line and end up to beginning of next TLB line
+	setlos.p	#~(PAGE_SIZE-1),gr5
+	setlos		#PAGE_SIZE,gr6
+	subi.p		gr10,#1,gr10
+	and		gr9,gr5,gr9
+	and		gr10,gr5,gr10
+2:
+	tlbpr		gr9,gr0,#5,#0
+	subcc.p		gr9,gr10,gr0,icc0
+	add		gr9,gr6,gr9
+	bne		icc0,#0,2b		; most likely a 1-page flush
+
+	bralr
+
+	.size		__flush_tlb_range, .-__flush_tlb_range
diff -urN linux-2.4.29/arch/frv/mm/tlb-miss.S linux-2.4.29-uc1/arch/frv/mm/tlb-miss.S
--- linux-2.4.29/arch/frv/mm/tlb-miss.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mm/tlb-miss.S	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,591 @@
+/* tlb-miss.S: TLB miss handlers
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/highmem.h>
+#include <asm/spr-regs.h>
+
+	.section	.text
+	.balign		4
+
+	.globl		__entry_insn_mmu_miss
+__entry_insn_mmu_miss:
+	break
+	nop
+
+	.globl		__entry_insn_mmu_exception
+__entry_insn_mmu_exception:
+	break
+	nop
+
+	.globl		__entry_data_mmu_miss
+__entry_data_mmu_miss:
+	break
+	nop
+
+	.globl		__entry_data_mmu_exception
+__entry_data_mmu_exception:
+	break
+	nop
+
+###############################################################################
+#
+# handle a lookup failure of one sort or another in a kernel TLB handler
+# On entry:
+#   GR29 - faulting address
+#   SCR2 - saved CCR
+#
+###############################################################################
+	.type		__tlb_kernel_fault,@function
+__tlb_kernel_fault:
+	# see if we're supposed to re-enable single-step mode upon return
+	sethi.p		%hi(__break_tlb_miss_return_break),gr30
+	setlo		%lo(__break_tlb_miss_return_break),gr30
+	movsg		pcsr,gr31
+
+	subcc		gr31,gr30,gr0,icc0
+	beq		icc0,#0,__tlb_kernel_fault_sstep
+
+	movsg		scr2,gr30
+	movgs		gr30,ccr
+	movgs		gr29,scr2			/* save EAR0 value */
+	sethi.p		%hi(__kernel_current_task),gr29
+	setlo		%lo(__kernel_current_task),gr29
+	ldi.p		@(gr29,#0),gr29			/* restore GR29 */
+
+	bra		__entry_kernel_handle_mmu_fault
+
+	# we've got to re-enable single-stepping
+__tlb_kernel_fault_sstep:
+	sethi.p		%hi(__break_tlb_miss_real_return_info),gr30
+	setlo		%lo(__break_tlb_miss_real_return_info),gr30
+	lddi		@(gr30,0),gr30
+	movgs		gr30,pcsr
+	movgs		gr31,psr
+
+	movsg		scr2,gr30
+	movgs		gr30,ccr
+	movgs		gr29,scr2			/* save EAR0 value */
+	sethi.p		%hi(__kernel_current_task),gr29
+	setlo		%lo(__kernel_current_task),gr29
+	ldi.p		@(gr29,#0),gr29			/* restore GR29 */
+	bra		__entry_kernel_handle_mmu_fault_sstep
+	
+	.size		__tlb_kernel_fault, .-__tlb_kernel_fault
+
+###############################################################################
+#
+# handle a lookup failure of one sort or another in a user TLB handler
+# On entry:
+#   GR28 - faulting address
+#   SCR2 - saved CCR
+#
+###############################################################################
+	.type		__tlb_user_fault,@function
+__tlb_user_fault:
+	# see if we're supposed to re-enable single-step mode upon return
+	sethi.p		%hi(__break_tlb_miss_return_break),gr30
+	setlo		%lo(__break_tlb_miss_return_break),gr30
+	movsg		pcsr,gr31
+	subcc		gr31,gr30,gr0,icc0
+	beq		icc0,#0,__tlb_user_fault_sstep
+
+	movsg		scr2,gr30
+	movgs		gr30,ccr
+	bra		__entry_uspace_handle_mmu_fault
+
+	# we've got to re-enable single-stepping
+__tlb_user_fault_sstep:
+	sethi.p		%hi(__break_tlb_miss_real_return_info),gr30
+	setlo		%lo(__break_tlb_miss_real_return_info),gr30
+	lddi		@(gr30,0),gr30
+	movgs		gr30,pcsr
+	movgs		gr31,psr
+	movsg		scr2,gr30
+	movgs		gr30,ccr
+	bra		__entry_uspace_handle_mmu_fault_sstep
+
+	.size		__tlb_user_fault, .-__tlb_user_fault
+
+###############################################################################
+#
+# Kernel instruction TLB miss handler
+# On entry:
+#   GR1   - kernel stack pointer
+#   GR28  - saved exception frame pointer
+#   GR29  - faulting address
+#   GR31  - EAR0 ^ SCR0
+#   SCR0  - base of virtual range covered by cached PGE from last ITLB miss (or 0xffffffff)
+#   DAMR3 - mapped page directory
+#   DAMR4 - mapped page table as matched by SCR0
+#
+###############################################################################
+	.globl		__entry_kernel_insn_tlb_miss
+	.type		__entry_kernel_insn_tlb_miss,@function
+__entry_kernel_insn_tlb_miss:
+	movsg		ccr,gr30			/* save CCR */
+	movgs		gr30,scr2
+
+	# see if the cached page table mapping is appropriate
+	srlicc.p	gr31,#26,gr0,icc0
+	setlos		0x3ffc,gr30
+	srli.p		gr29,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bne		icc0,#0,__itlb_k_PTD_miss
+
+__itlb_k_PTD_mapped:
+	# access the PTD with EAR0[25:14]
+	# - DAMLR4 points to the virtual address of the appropriate page table
+	# - the PTD holds 4096 PTEs
+	# - the PTD must be accessed uncached
+	# - the PTE must be marked accessed if it was valid
+	#
+	and		gr31,gr30,gr31
+	movsg		damlr4,gr30
+	add		gr30,gr31,gr31
+	ldi		@(gr31,#0),gr30			/* fetch the PTE */
+	andicc		gr30,#_PAGE_PRESENT,gr0,icc0
+	ori.p		gr30,#_PAGE_ACCESSED,gr30
+	beq		icc0,#0,__tlb_kernel_fault	/* jump if PTE invalid */
+	sti.p		gr30,@(gr31,#0)			/* update the PTE */
+	andi		gr30,#~_PAGE_ACCESSED,gr30
+
+	# we're using IAMR1 as an extra TLB entry
+	# - punt the entry here (if valid) to the real TLB and then replace with the new PTE
+	# - need to check DAMR1 lest we cause an multiple-DAT-hit exception
+	# - IAMPR1 has no WP bit, and we mustn't lose WP information
+	movsg		iampr1,gr31
+	andicc		gr31,#xAMPRx_V,gr0,icc0
+	setlos.p	0xfffff000,gr31
+	beq		icc0,#0,__itlb_k_nopunt		/* punt not required */
+
+	movsg		iamlr1,gr31
+	movgs		gr31,tplr			/* set TPLR.CXN */
+	tlbpr		gr31,gr0,#4,#0			/* delete matches from TLB, IAMR1, DAMR1 */
+
+	movsg		dampr1,gr31
+	ori		gr31,#xAMPRx_V,gr31		/* entry was invalidated by tlbpr #4 */
+	movgs		gr31,tppr
+	movsg		iamlr1,gr31			/* set TPLR.CXN */
+	movgs		gr31,tplr
+	tlbpr		gr31,gr0,#2,#0			/* save to the TLB */
+	movsg		tpxr,gr31			/* check the TLB write error flag */
+	andicc.p	gr31,#TPXR_E,gr0,icc0
+	setlos		#0xfffff000,gr31
+	bne		icc0,#0,__tlb_kernel_fault
+
+__itlb_k_nopunt:
+
+	# assemble the new TLB entry
+	and		gr29,gr31,gr29
+	movsg		cxnr,gr31
+	or		gr29,gr31,gr29
+	movgs		gr29,iamlr1			/* xAMLR = address | context number */
+	movgs		gr30,iampr1
+	movgs		gr29,damlr1
+	movgs		gr30,dampr1
+
+	# return, restoring registers
+	movsg		scr2,gr30
+	movgs		gr30,ccr
+	sethi.p		%hi(__kernel_current_task),gr29
+	setlo		%lo(__kernel_current_task),gr29
+	ldi		@(gr29,#0),gr29
+	rett		#0
+	beq		icc0,#3,0			/* prevent icache prefetch */
+
+	# the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more
+	# appropriate page table and map that instead
+	#   - access the PGD with EAR0[31:26]
+	#   - DAMLR3 points to the virtual address of the page directory
+	#   - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables
+__itlb_k_PTD_miss:
+	srli		gr29,#26,gr31			/* calculate PGE offset */
+	slli		gr31,#8,gr31			/* and clear bottom bits */
+
+	movsg		damlr3,gr30
+	ld		@(gr31,gr30),gr30		/* access the PGE */
+
+	andicc.p	gr30,#_PAGE_PRESENT,gr0,icc0
+	andicc		gr30,#xAMPRx_SS,gr0,icc1
+
+	# map this PTD instead and record coverage address
+	ori.p		gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30
+	beq		icc0,#0,__tlb_kernel_fault	/* jump if PGE not present */
+	slli.p		gr31,#18,gr31
+	bne		icc1,#0,__itlb_k_bigpage
+	movgs		gr30,dampr4
+	movgs		gr31,scr0
+
+	# we can now resume normal service
+	setlos		0x3ffc,gr30
+	srli.p		gr29,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bra		__itlb_k_PTD_mapped
+
+__itlb_k_bigpage:
+	break
+	nop
+
+	.size		__entry_kernel_insn_tlb_miss, .-__entry_kernel_insn_tlb_miss
+
+###############################################################################
+#
+# Kernel data TLB miss handler
+# On entry:
+#   GR1   - kernel stack pointer
+#   GR28  - saved exception frame pointer
+#   GR29  - faulting address
+#   GR31  - EAR0 ^ SCR1
+#   SCR1  - base of virtual range covered by cached PGE from last DTLB miss (or 0xffffffff)
+#   DAMR3 - mapped page directory
+#   DAMR5 - mapped page table as matched by SCR1
+#
+###############################################################################
+	.globl		__entry_kernel_data_tlb_miss
+	.type		__entry_kernel_data_tlb_miss,@function
+__entry_kernel_data_tlb_miss:
+	movsg		ccr,gr30			/* save CCR */
+	movgs		gr30,scr2
+
+	# see if the cached page table mapping is appropriate
+	srlicc.p	gr31,#26,gr0,icc0
+	setlos		0x3ffc,gr30
+	srli.p		gr29,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bne		icc0,#0,__dtlb_k_PTD_miss
+
+__dtlb_k_PTD_mapped:
+	# access the PTD with EAR0[25:14]
+	# - DAMLR5 points to the virtual address of the appropriate page table
+	# - the PTD holds 4096 PTEs
+	# - the PTD must be accessed uncached
+	# - the PTE must be marked accessed if it was valid
+	#
+	and		gr31,gr30,gr31
+	movsg		damlr5,gr30
+	add		gr30,gr31,gr31
+	ldi		@(gr31,#0),gr30			/* fetch the PTE */
+	andicc		gr30,#_PAGE_PRESENT,gr0,icc0
+	ori.p		gr30,#_PAGE_ACCESSED,gr30
+	beq		icc0,#0,__tlb_kernel_fault	/* jump if PTE invalid */
+	sti.p		gr30,@(gr31,#0)			/* update the PTE */
+	andi		gr30,#~_PAGE_ACCESSED,gr30
+
+	# we're using DAMR1 as an extra TLB entry
+	# - punt the entry here (if valid) to the real TLB and then replace with the new PTE
+	# - need to check IAMR1 lest we cause an multiple-DAT-hit exception
+	movsg		dampr1,gr31
+	andicc		gr31,#xAMPRx_V,gr0,icc0
+	setlos.p	0xfffff000,gr31
+	beq		icc0,#0,__dtlb_k_nopunt		/* punt not required */
+
+	movsg		damlr1,gr31
+	movgs		gr31,tplr			/* set TPLR.CXN */
+	tlbpr		gr31,gr0,#4,#0			/* delete matches from TLB, IAMR1, DAMR1 */
+
+	movsg		dampr1,gr31
+	ori		gr31,#xAMPRx_V,gr31		/* entry was invalidated by tlbpr #4 */
+	movgs		gr31,tppr
+	movsg		damlr1,gr31			/* set TPLR.CXN */
+	movgs		gr31,tplr
+	tlbpr		gr31,gr0,#2,#0			/* save to the TLB */
+	movsg		tpxr,gr31			/* check the TLB write error flag */
+	andicc.p	gr31,#TPXR_E,gr0,icc0
+	setlos		#0xfffff000,gr31
+	bne		icc0,#0,__tlb_kernel_fault
+
+__dtlb_k_nopunt:
+
+	# assemble the new TLB entry
+	and		gr29,gr31,gr29
+	movsg		cxnr,gr31
+	or		gr29,gr31,gr29
+	movgs		gr29,iamlr1			/* xAMLR = address | context number */
+	movgs		gr30,iampr1
+	movgs		gr29,damlr1
+	movgs		gr30,dampr1
+
+	# return, restoring registers
+	movsg		scr2,gr30
+	movgs		gr30,ccr
+	sethi.p		%hi(__kernel_current_task),gr29
+	setlo		%lo(__kernel_current_task),gr29
+	ldi		@(gr29,#0),gr29
+	rett		#0
+	beq		icc0,#3,0			/* prevent icache prefetch */
+
+	# the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more
+	# appropriate page table and map that instead
+	#   - access the PGD with EAR0[31:26]
+	#   - DAMLR3 points to the virtual address of the page directory
+	#   - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables
+__dtlb_k_PTD_miss:
+	srli		gr29,#26,gr31			/* calculate PGE offset */
+	slli		gr31,#8,gr31			/* and clear bottom bits */
+
+	movsg		damlr3,gr30
+	ld		@(gr31,gr30),gr30		/* access the PGE */
+
+	andicc.p	gr30,#_PAGE_PRESENT,gr0,icc0
+	andicc		gr30,#xAMPRx_SS,gr0,icc1
+
+	# map this PTD instead and record coverage address
+	ori.p		gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30
+	beq		icc0,#0,__tlb_kernel_fault	/* jump if PGE not present */
+	slli.p		gr31,#18,gr31
+	bne		icc1,#0,__dtlb_k_bigpage
+	movgs		gr30,dampr5
+	movgs		gr31,scr1
+
+	# we can now resume normal service
+	setlos		0x3ffc,gr30
+	srli.p		gr29,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bra		__dtlb_k_PTD_mapped
+
+__dtlb_k_bigpage:
+	break
+	nop
+
+	.size		__entry_kernel_data_tlb_miss, .-__entry_kernel_data_tlb_miss
+
+###############################################################################
+#
+# Userspace instruction TLB miss handler (with PGE prediction)
+# On entry:
+#   GR28  - faulting address
+#   GR31  - EAR0 ^ SCR0
+#   SCR0  - base of virtual range covered by cached PGE from last ITLB miss (or 0xffffffff)
+#   DAMR3 - mapped page directory
+#   DAMR4 - mapped page table as matched by SCR0
+#
+###############################################################################
+	.globl		__entry_user_insn_tlb_miss
+	.type		__entry_user_insn_tlb_miss,@function
+__entry_user_insn_tlb_miss:
+	movsg		ccr,gr30			/* save CCR */
+	movgs		gr30,scr2
+
+	# see if the cached page table mapping is appropriate
+	srlicc.p	gr31,#26,gr0,icc0
+	setlos		0x3ffc,gr30
+	srli.p		gr28,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bne		icc0,#0,__itlb_u_PTD_miss
+
+__itlb_u_PTD_mapped:
+	# access the PTD with EAR0[25:14]
+	# - DAMLR4 points to the virtual address of the appropriate page table
+	# - the PTD holds 4096 PTEs
+	# - the PTD must be accessed uncached
+	# - the PTE must be marked accessed if it was valid
+	#
+	and		gr31,gr30,gr31
+	movsg		damlr4,gr30
+	add		gr30,gr31,gr31
+	ldi		@(gr31,#0),gr30			/* fetch the PTE */
+	andicc		gr30,#_PAGE_PRESENT,gr0,icc0
+	ori.p		gr30,#_PAGE_ACCESSED,gr30
+	beq		icc0,#0,__tlb_user_fault	/* jump if PTE invalid */
+	sti.p		gr30,@(gr31,#0)			/* update the PTE */
+	andi		gr30,#~_PAGE_ACCESSED,gr30
+
+	# we're using IAMR1/DAMR1 as an extra TLB entry
+	# - punt the entry here (if valid) to the real TLB and then replace with the new PTE
+	movsg		dampr1,gr31
+	andicc		gr31,#xAMPRx_V,gr0,icc0
+	setlos.p	0xfffff000,gr31
+	beq		icc0,#0,__itlb_u_nopunt		/* punt not required */
+
+	movsg		dampr1,gr31
+	movgs		gr31,tppr
+	movsg		damlr1,gr31			/* set TPLR.CXN */
+	movgs		gr31,tplr
+	tlbpr		gr31,gr0,#2,#0			/* save to the TLB */
+	movsg		tpxr,gr31			/* check the TLB write error flag */
+	andicc.p	gr31,#TPXR_E,gr0,icc0
+	setlos		#0xfffff000,gr31
+	bne		icc0,#0,__tlb_user_fault
+
+__itlb_u_nopunt:
+
+	# assemble the new TLB entry
+	and		gr28,gr31,gr28
+	movsg		cxnr,gr31
+	or		gr28,gr31,gr28
+	movgs		gr28,iamlr1			/* xAMLR = address | context number */
+	movgs		gr30,iampr1
+	movgs		gr28,damlr1
+	movgs		gr30,dampr1
+	
+	# return, restoring registers
+	movsg		scr2,gr30
+	movgs		gr30,ccr
+	rett		#0
+	beq		icc0,#3,0			/* prevent icache prefetch */
+
+	# the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more
+	# appropriate page table and map that instead
+	#   - access the PGD with EAR0[31:26]
+	#   - DAMLR3 points to the virtual address of the page directory
+	#   - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables
+__itlb_u_PTD_miss:
+	srli		gr28,#26,gr31			/* calculate PGE offset */
+	slli		gr31,#8,gr31			/* and clear bottom bits */
+
+	movsg		damlr3,gr30
+	ld		@(gr31,gr30),gr30		/* access the PGE */
+
+	andicc.p	gr30,#_PAGE_PRESENT,gr0,icc0
+	andicc		gr30,#xAMPRx_SS,gr0,icc1
+
+	# map this PTD instead and record coverage address
+	ori.p		gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30
+	beq		icc0,#0,__tlb_user_fault	/* jump if PGE not present */
+	slli.p		gr31,#18,gr31
+	bne		icc1,#0,__itlb_u_bigpage
+	movgs		gr30,dampr4
+	movgs		gr31,scr0
+
+	# we can now resume normal service
+	setlos		0x3ffc,gr30
+	srli.p		gr28,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bra		__itlb_u_PTD_mapped
+
+__itlb_u_bigpage:
+	break
+	nop
+
+	.size		__entry_user_insn_tlb_miss, .-__entry_user_insn_tlb_miss
+
+###############################################################################
+#
+# Userspace data TLB miss handler
+# On entry:
+#   GR28  - faulting address
+#   GR31  - EAR0 ^ SCR1
+#   SCR1  - base of virtual range covered by cached PGE from last DTLB miss (or 0xffffffff)
+#   DAMR3 - mapped page directory
+#   DAMR5 - mapped page table as matched by SCR1
+#
+###############################################################################
+	.globl		__entry_user_data_tlb_miss
+	.type		__entry_user_data_tlb_miss,@function
+__entry_user_data_tlb_miss:
+	movsg		ccr,gr30			/* save CCR */
+	movgs		gr30,scr2
+
+	# see if the cached page table mapping is appropriate
+	srlicc.p	gr31,#26,gr0,icc0
+	setlos		0x3ffc,gr30
+	srli.p		gr28,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bne		icc0,#0,__dtlb_u_PTD_miss
+
+__dtlb_u_PTD_mapped:
+	# access the PTD with EAR0[25:14]
+	# - DAMLR5 points to the virtual address of the appropriate page table
+	# - the PTD holds 4096 PTEs
+	# - the PTD must be accessed uncached
+	# - the PTE must be marked accessed if it was valid
+	#
+	and		gr31,gr30,gr31
+	movsg		damlr5,gr30
+
+__dtlb_u_using_iPTD:
+	add		gr30,gr31,gr31
+	ldi		@(gr31,#0),gr30			/* fetch the PTE */
+	andicc		gr30,#_PAGE_PRESENT,gr0,icc0
+	ori.p		gr30,#_PAGE_ACCESSED,gr30
+	beq		icc0,#0,__tlb_user_fault	/* jump if PTE invalid */
+	sti.p		gr30,@(gr31,#0)			/* update the PTE */
+	andi		gr30,#~_PAGE_ACCESSED,gr30
+
+	# we're using DAMR1 as an extra TLB entry
+	# - punt the entry here (if valid) to the real TLB and then replace with the new PTE
+	movsg		dampr1,gr31
+	andicc		gr31,#xAMPRx_V,gr0,icc0
+	setlos.p	0xfffff000,gr31
+	beq		icc0,#0,__dtlb_u_nopunt		/* punt not required */
+
+	movsg		dampr1,gr31
+	movgs		gr31,tppr
+	movsg		damlr1,gr31			/* set TPLR.CXN */
+	movgs		gr31,tplr
+	tlbpr		gr31,gr0,#2,#0			/* save to the TLB */
+	movsg		tpxr,gr31			/* check the TLB write error flag */
+	andicc.p	gr31,#TPXR_E,gr0,icc0
+	setlos		#0xfffff000,gr31
+	bne		icc0,#0,__tlb_user_fault
+
+__dtlb_u_nopunt:
+
+	# assemble the new TLB entry
+	and		gr28,gr31,gr28
+	movsg		cxnr,gr31
+	or		gr28,gr31,gr28
+	movgs		gr28,iamlr1			/* xAMLR = address | context number */
+	movgs		gr30,iampr1
+	movgs		gr28,damlr1
+	movgs		gr30,dampr1
+
+	# return, restoring registers
+	movsg		scr2,gr30
+	movgs		gr30,ccr
+	rett		#0
+	beq		icc0,#3,0			/* prevent icache prefetch */
+
+	# the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more
+	# appropriate page table and map that instead
+	#   - first of all, check the insn PGE cache - we may well get a hit there
+	#   - access the PGD with EAR0[31:26]
+	#   - DAMLR3 points to the virtual address of the page directory
+	#   - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables
+__dtlb_u_PTD_miss:
+	movsg		scr0,gr31			/* consult the insn-PGE-cache key */
+	xor		gr28,gr31,gr31
+	srlicc		gr31,#26,gr0,icc0
+	srli		gr28,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bne		icc0,#0,__dtlb_u_iPGE_miss
+
+	# what we're looking for is covered by the insn-PGE-cache
+	setlos		0x3ffc,gr30
+	and		gr31,gr30,gr31
+	movsg		damlr4,gr30
+	bra		__dtlb_u_using_iPTD
+
+__dtlb_u_iPGE_miss:	
+	srli		gr28,#26,gr31			/* calculate PGE offset */
+	slli		gr31,#8,gr31			/* and clear bottom bits */
+
+	movsg		damlr3,gr30
+	ld		@(gr31,gr30),gr30		/* access the PGE */
+
+	andicc.p	gr30,#_PAGE_PRESENT,gr0,icc0
+	andicc		gr30,#xAMPRx_SS,gr0,icc1
+
+	# map this PTD instead and record coverage address
+	ori.p		gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30
+	beq		icc0,#0,__tlb_user_fault	/* jump if PGE not present */
+	slli.p		gr31,#18,gr31
+	bne		icc1,#0,__dtlb_u_bigpage
+	movgs		gr30,dampr5
+	movgs		gr31,scr1
+
+	# we can now resume normal service
+	setlos		0x3ffc,gr30
+	srli.p		gr28,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bra		__dtlb_u_PTD_mapped
+
+__dtlb_u_bigpage:
+	break
+	nop
+
+	.size		__entry_user_data_tlb_miss, .-__entry_user_data_tlb_miss
diff -urN linux-2.4.29/arch/frv/mm/unaligned.c linux-2.4.29-uc1/arch/frv/mm/unaligned.c
--- linux-2.4.29/arch/frv/mm/unaligned.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/mm/unaligned.c	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,218 @@
+/* unaligned.c: unalignment fixup handler for CPUs on which it is supported (FR451 only)
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/user.h>
+#include <linux/string.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#if 0
+#define kdebug(fmt, ...) printk("FDPIC "fmt"\n" ,##__VA_ARGS__ )
+#else
+#define kdebug(fmt, ...) do {} while(0)
+#endif
+
+#define _MA_SIGNED	0x01
+#define _MA_HALF	0x02
+#define _MA_WORD	0x04
+#define _MA_DWORD	0x08
+#define _MA_SZ_MASK	0x0e
+#define _MA_LOAD	0x10
+#define _MA_STORE	0x20
+#define _MA_UPDATE	0x40
+#define _MA_IMM		0x80
+
+#define _MA_LDxU	_MA_LOAD | _MA_UPDATE
+#define _MA_LDxI	_MA_LOAD | _MA_IMM
+#define _MA_STxU	_MA_STORE | _MA_UPDATE
+#define _MA_STxI	_MA_STORE | _MA_IMM
+
+static const uint8_t tbl_LDGRk_reg[0x40] = {
+	[0x02] = _MA_LOAD | _MA_HALF | _MA_SIGNED,	/* LDSH  @(GRi,GRj),GRk */
+	[0x03] = _MA_LOAD | _MA_HALF,			/* LDUH  @(GRi,GRj),GRk */
+	[0x04] = _MA_LOAD | _MA_WORD,			/* LD	 @(GRi,GRj),GRk */
+	[0x05] = _MA_LOAD | _MA_DWORD,			/* LDD	 @(GRi,GRj),GRk */
+	[0x12] = _MA_LDxU | _MA_HALF | _MA_SIGNED,	/* LDSHU @(GRi,GRj),GRk */
+	[0x13] = _MA_LDxU | _MA_HALF,			/* LDUHU @(GRi,GRj),GRk */
+	[0x14] = _MA_LDxU | _MA_WORD,			/* LDU	 @(GRi,GRj),GRk */
+	[0x15] = _MA_LDxU | _MA_DWORD,			/* LDDU	 @(GRi,GRj),GRk */
+};
+
+static const uint8_t tbl_STGRk_reg[0x40] = {
+	[0x01] = _MA_STORE | _MA_HALF,			/* STH   @(GRi,GRj),GRk */
+	[0x02] = _MA_STORE | _MA_WORD,			/* ST	 @(GRi,GRj),GRk */
+	[0x03] = _MA_STORE | _MA_DWORD,			/* STD	 @(GRi,GRj),GRk */
+	[0x11] = _MA_STxU  | _MA_HALF,			/* STHU  @(GRi,GRj),GRk */
+	[0x12] = _MA_STxU  | _MA_WORD,			/* STU	 @(GRi,GRj),GRk */
+	[0x13] = _MA_STxU  | _MA_DWORD,			/* STDU	 @(GRi,GRj),GRk */
+};
+
+static const uint8_t tbl_LDSTGRk_imm[0x80] = {
+	[0x31] = _MA_LDxI | _MA_HALF | _MA_SIGNED,	/* LDSHI @(GRi,d12),GRk */
+	[0x32] = _MA_LDxI | _MA_WORD,			/* LDI   @(GRi,d12),GRk */
+	[0x33] = _MA_LDxI | _MA_DWORD,			/* LDDI  @(GRi,d12),GRk */
+	[0x36] = _MA_LDxI | _MA_HALF,			/* LDUHI @(GRi,d12),GRk */
+	[0x51] = _MA_STxI | _MA_HALF,			/* STHI  @(GRi,d12),GRk */
+	[0x52] = _MA_STxI | _MA_WORD,			/* STI   @(GRi,d12),GRk */
+	[0x53] = _MA_STxI | _MA_DWORD,			/* STDI  @(GRi,d12),GRk */
+};
+
+
+/*****************************************************************************/
+/*
+ * see if we can handle the exception by fixing up a misaligned memory access
+ */
+int handle_misalignment(unsigned long esr0, unsigned long ear0, unsigned long epcr0)
+{
+	unsigned long insn, addr, *greg;
+	int GRi, GRj, GRk, D12, op;
+
+	union {
+		uint64_t _64;
+		uint32_t _32[2];
+		uint16_t _16;
+		uint8_t _8[8];
+	} x;
+
+	if (!(esr0 & ESR0_EAV) || !(epcr0 & EPCR0_V) || !(ear0 & 7))
+		return -EAGAIN;
+
+	epcr0 &= EPCR0_PC;
+
+	if (__frame->pc != epcr0) {
+		kdebug("MISALIGN: Execution not halted on excepting instruction\n");
+		BUG();
+	}
+
+	if (__get_user(insn, (unsigned long *) epcr0) < 0)
+		return -EFAULT;
+
+	/* determine the instruction type first */
+	switch ((insn >> 18) & 0x7f) {
+	case 0x2:
+		/* LDx @(GRi,GRj),GRk */
+		op = tbl_LDGRk_reg[(insn >> 6) & 0x3f];
+		break;
+
+	case 0x3:
+		/* STx GRk,@(GRi,GRj) */
+		op = tbl_STGRk_reg[(insn >> 6) & 0x3f];
+		break;
+
+	default:
+		op = tbl_LDSTGRk_imm[(insn >> 18) & 0x7f];
+		break;
+	}
+
+	if (!op)
+		return -EAGAIN;
+
+	kdebug("MISALIGN: pc=%08lx insn=%08lx ad=%08lx op=%02x\n", epcr0, insn, ear0, op);
+
+	memset(&x, 0xba, 8);
+
+	/* validate the instruction parameters */
+	greg = (unsigned long *) &__frame->tbr;
+
+	GRi = (insn >> 12) & 0x3f;
+	GRk = (insn >> 25) & 0x3f;
+
+	if (GRi > 31 || GRk > 31)
+		return -ENOENT;
+
+	if (op & _MA_DWORD && GRk & 1)
+		return -EINVAL;
+
+	if (op & _MA_IMM) {
+		D12 = insn & 0xfff;
+		asm ("slli %0,#20,%0 ! srai %0,#20,%0" : "=r"(D12) : "0"(D12)); /* sign extend */
+		addr = (GRi ? greg[GRi] : 0) + D12;
+	}
+	else {
+		GRj = (insn >>  0) & 0x3f;
+		if (GRj > 31)
+			return -ENOENT;
+		addr = (GRi ? greg[GRi] : 0) + (GRj ? greg[GRj] : 0);
+	}
+
+	if (addr != ear0) {
+		kdebug("MISALIGN: Calculated addr (%08lx) does not match EAR0 (%08lx)\n",
+		       addr, ear0);
+		return -EFAULT;
+	}
+
+	/* check the address is okay */
+	if (user_mode(__frame) && ___range_ok(ear0, 8) < 0)
+		return -EFAULT;
+
+	/* perform the memory op */
+	if (op & _MA_STORE) {
+		/* perform a store */
+		x._32[0] = 0;
+		if (GRk != 0) {
+			if (op & _MA_HALF) {
+				x._16 = greg[GRk];
+			}
+			else {
+				x._32[0] = greg[GRk];
+			}
+		}
+		if (op & _MA_DWORD)
+			x._32[1] = greg[GRk + 1];
+
+		kdebug("MISALIGN: Store GR%d { %08x:%08x } -> %08lx (%dB)\n",
+		       GRk, x._32[1], x._32[0], addr, op & _MA_SZ_MASK);
+
+		if (__memcpy_user((void *) addr, &x, op & _MA_SZ_MASK) != 0)
+			return -EFAULT;
+	}
+	else {
+		/* perform a load */
+		if (__memcpy_user(&x, (void *) addr, op & _MA_SZ_MASK) != 0)
+			return -EFAULT;
+
+		if (op & _MA_HALF) {
+			if (op & _MA_SIGNED)
+				asm ("slli %0,#16,%0 ! srai %0,#16,%0"
+				     : "=r"(x._32[0]) : "0"(x._16));
+			else
+				asm ("sethi #0,%0"
+				     : "=r"(x._32[0]) : "0"(x._16));
+		}
+
+		kdebug("MISALIGN: Load %08lx (%dB) -> GR%d, { %08x:%08x }\n",
+		       addr, op & _MA_SZ_MASK, GRk, x._32[1], x._32[0]);
+
+		if (GRk != 0)
+			greg[GRk] = x._32[0];
+		if (op & _MA_DWORD)
+			greg[GRk + 1] = x._32[1];
+	}
+
+	/* update the base pointer if required */
+	if (op & _MA_UPDATE)
+		greg[GRi] = addr;
+
+	/* well... we've done that insn */
+	__frame->pc = __frame->pc + 4;
+
+	return 0;
+} /* end handle_misalignment() */
diff -urN linux-2.4.29/arch/frv/vmlinux.lds linux-2.4.29-uc1/arch/frv/vmlinux.lds
--- linux-2.4.29/arch/frv/vmlinux.lds	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/frv/vmlinux.lds	2005-06-14 02:11:12.000000000 +0100
@@ -0,0 +1,155 @@
+/* ld script to make FRV Linux kernel -*- c -*-
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
+ */
+OUTPUT_FORMAT("elf32-frv", "elf32-frv", "elf32-frv")
+OUTPUT_ARCH(frv)
+ENTRY(_start)
+
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+
+__page_offset = 0xc0000000;		/* start of area covered by struct pages */
+__kernel_image_start = __page_offset;	/* address at which kernel image resides */
+
+SECTIONS
+{
+  . = __kernel_image_start;
+
+  /* discardable initialisation code and data */
+  . = ALIGN(PAGE_SIZE);			/* Init code and data */
+  __init_begin = .;
+
+  .text.init : {
+	*(.text.head)
+#ifndef CONFIG_FULLDEBUG
+	*(.text.init)
+	*(.text.exit)
+#endif
+  }
+  .data.init : { *(.data.init) }
+
+  . = ALIGN(8);
+  __setup_start = .;
+  .setup.init : { KEEP(*(.setup.init)) }
+  __setup_end = .;
+
+  __initcall_start = .;
+  .initcall.init : { KEEP(*(.initcall.init)) }
+  __initcall_end = .;
+
+  . = ALIGN(THREAD_SIZE);
+  __init_end = .;
+
+  /* put sections together that have massive alignment issues */
+  . = ALIGN(THREAD_SIZE);
+  .data.init_task : {
+	  /* init task record & stack */
+	  *(.data.init_task)
+  }
+
+  .trap : {
+	/* trap table management - read entry-table.S before modifying */
+	. = ALIGN(8192);
+	__trap_tables = .;
+	*(.trap.user)	
+	*(.trap.kernel)	
+	. = ALIGN(4096);
+	*(.trap.break)	
+  }
+
+  . = ALIGN(4096);
+  .data.page_aligned : { *(.data.idt) }
+
+  . = ALIGN(L1_CACHE_BYTES);
+  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+  /* Text and read-only data */
+  . = ALIGN(4);
+  _text = .;
+  _stext = .;
+  .text : {
+	*(.text.start .text .text.*)
+	*(.fixup)
+	*(.gnu.warning)
+	*(.exitcall.exit)
+	} = 0x9090
+
+  _etext = .;			/* End of text section */
+
+  .rodata : {
+	*(.rodata) *(.rodata.*)
+	*(.trap.vector)
+
+	/* this clause must not be modified - the ordering and adjacency are imperative */
+	__trap_fixup_tables = .;
+	*(.trap.fixup.user .trap.fixup.kernel)
+
+	}
+  .kstrtab : { *(.kstrtab) }
+
+  . = ALIGN(8);		/* Exception table */
+  __start___ex_table = .;
+  __ex_table : { KEEP(*(__ex_table)) }
+  __stop___ex_table = .;
+
+  __start___ksymtab = .;	/* Kernel symbol table */
+  __ksymtab : { *(__ksymtab) }
+  __stop___ksymtab = .;
+
+  _sdata = .;
+  .data : {			/* Data */
+	*(.data .data.*)
+	*(.data.exit)
+	CONSTRUCTORS
+	}
+
+  _edata = .;			/* End of data section */
+
+  /* Sections to be discarded */
+/* /DISCARD/ : {
+	*(.data.exit)
+	*(.exitcall.exit)
+	}
+*/
+
+  /* GP section */
+  . = ALIGN(L1_CACHE_BYTES);
+  _gp = . + 2048;
+  PROVIDE (gp = _gp);
+
+  .sdata : { *(.sdata .sdata.*) }
+
+  /* BSS */
+  . = ALIGN(L1_CACHE_BYTES);
+  __bss_start = .;
+
+  .sbss		: { *(.sbss .sbss.*) }
+  .bss		: { *(.bss .bss.*) }
+  .bss.stack	: { *(.bss) }
+  _ebss = .;
+  _end = . ;
+  . = ALIGN(PAGE_SIZE);
+  __kernel_image_end = .;
+
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+
+  .debug_line		0 : { *(.debug_line) }
+  .debug_info		0 : { *(.debug_info) }
+  .debug_abbrev		0 : { *(.debug_abbrev) }
+  .debug_aranges	0 : { *(.debug_aranges) }
+  .debug_frame		0 : { *(.debug_frame) }
+  .debug_pubnames	0 : { *(.debug_pubnames) }
+  .debug_str		0 : { *(.debug_str) }
+  .debug_ranges		0 : { *(.debug_ranges) }
+
+  .comment 0 : { *(.comment) }
+}
+
+__kernel_image_size_no_bss = __bss_start - __kernel_image_start;
diff -urN linux-2.4.29/arch/h8300/Boards.mk linux-2.4.29-uc1/arch/h8300/Boards.mk
--- linux-2.4.29/arch/h8300/Boards.mk	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/Boards.mk	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,29 @@
+# Put definitions for platforms and boards in here.
+
+ifdef CONFIG_BOARD_GENERIC
+ifdef CONFIG_CPU_H8300H
+PLATFORM := h8300h
+endif
+ifdef CONFIG_CPU_H8S
+PLATFORM := h8s
+endif
+BOARD := generic
+endif
+
+ifdef CONFIG_BOARD_AKI3068NET
+PLATFORM := h8300h
+BOARD := aki3068net
+endif
+
+ifdef CONFIG_BOARD_H8MAX
+PLATFORM := h8300h
+BOARD := h8max
+endif
+
+ifdef CONFIG_BOARD_EDOSK2674
+PLATFORM := h8s
+BOARD := edosk2674
+endif
+
+export PLATFORM
+export BOARD
diff -urN linux-2.4.29/arch/h8300/config.in linux-2.4.29-uc1/arch/h8300/config.in
--- linux-2.4.29/arch/h8300/config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/config.in	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,236 @@
+#############################################################################
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+#
+# based mainly on the arch/i386/config.in and bit of the 2.0, h8300
+# config.in
+#
+#############################################################################
+
+mainmenu_name 'uClinux/h8300 (w/o MMU) Kernel Configuration'
+
+define_bool CONFIG_UCLINUX y
+define_bool CONFIG_UID16 y
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Target Selection'
+define_bool CONFIG_CPU_H8300H n
+define_bool CONFIG_CPU_H8S n
+
+source arch/h8300/target_config.in
+endmenu
+
+if [ "$CONFIG_BOARD_GENERIC" = "y" ]; then
+
+mainmenu_option next_comment
+comment 'Platform dependant setup'
+
+  choice 'CPU' \
+	  "H8/3002			CONFIG_H83002 \
+  	   H8/3006,3007,gdb_simulator	CONFIG_H83007 \
+	   H8/3044,3045,3046,3047,3048,3052	CONFIG_H83048 \
+           H8/3065,3066,3067,3068,3069	CONFIG_H83068 \
+           H8S/2670,2673,2674,2675,2676,2678	CONFIG_H8S2678" 
+
+  int 'Clock Frequency' CONFIG_CLK_FREQ 250000
+
+choice 'Kernel executes from' \
+	"RAM	CONFIG_RAMKERNEL \
+	 ROM	CONFIG_ROMKERNEL" ROM
+
+endmenu
+fi
+
+if [ "$CONFIG_H83002" = "y" -o "$CONFIG_H83007" = "y" -o \
+     "$CONFIG_H83048" = "y" -o "$CONFIG_H83068" = "y" ]; then
+  define_bool CONFIG_CPU_H8S n
+  define_bool CONFIG_CPU_H8300H y
+fi
+
+if [ "$CONFIG_H8S2678" = "y" ]; then
+  define_bool CONFIG_CPU_H8300H n
+  define_bool CONFIG_CPU_H8S y
+fi
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'General setup'
+
+bool 'Networking support' CONFIG_NET
+bool 'System V IPC' CONFIG_SYSVIPC
+bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   choice 'Kernel core (/proc/kcore) format' \
+	"ELF		CONFIG_KCORE_ELF	\
+	 A.OUT		CONFIG_KCORE_AOUT" ELF
+fi
+tristate 'Kernel support for flat binaries' CONFIG_BINFMT_FLAT
+if [ "$CONFIG_BINFMT_FLAT" != "n" ]; then
+   bool '    Enable ZFLAT support' CONFIG_BINFMT_ZFLAT
+   bool '    Enable shared FLAT support' CONFIG_BINFMT_SHARED_FLAT
+fi
+tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
+tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+bool 'Set Default Kernel Command Line' CONFIG_DEFAULT_CMDLINE
+if [ "$CONFIG_DEFAULT_CMDLINE" = "y" ]; then
+  string 'Kernel command line' CONFIG_KERNEL_COMMAND ""
+fi
+bool 'BLKDEV Reserved Memory' CONFIG_BLKDEV_RESERVE n
+if [ "$CONFIG_BLKDEV_RESERVE" = "y" ]; then
+   hex 'Reserved Address' CONFIG_BLKDEV_RESERVE_ADDRESS 0
+fi
+endmenu
+
+#############################################################################
+
+source drivers/mtd/Config.in
+
+source drivers/parport/Config.in
+
+source drivers/pnp/Config.in
+
+source drivers/block/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   source net/Config.in
+fi
+
+source drivers/telephony/Config.in
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'ATA/IDE/MFM/RLL support'
+
+tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+
+if [ "$CONFIG_IDE" != "n" ]; then
+  source drivers/ide/Config.in
+  if [ "$CONFIG_BOARD_GENERIC" = "n" ]; then
+    source arch/h8300/ide_config.in
+  fi
+else
+  define_bool CONFIG_BLK_DEV_HD n
+fi
+endmenu
+
+#############################################################################
+
+if [ "$CONFIG_NET" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Network device support'
+
+   bool 'Network device support' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+      if [ "$CONFIG_ATM" = "y" ]; then
+         source drivers/atm/Config.in
+      fi
+   fi
+   endmenu
+fi
+
+#############################################################################
+
+source drivers/char/Config.in
+
+
+#source drivers/misc/Config.in
+
+source fs/Config.in
+
+if [ "$CONFIG_VT" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Console drivers'
+   bool 'VGA text console' CONFIG_VGA_CONSOLE
+   bool 'Video mode selection support' CONFIG_VIDEO_SELECT
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
+      source drivers/video/Config.in
+   fi
+   endmenu
+fi
+
+#############################################################################
+
+source drivers/usb/Config.in
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+bool 'Full Symbolic/Source Debugging support' CONFIG_FULLDEBUG
+#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
+bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	bool 'Non power-of-2 kernel allocator (EXPERIMENTAL)' CONFIG_CONTIGUOUS_PAGE_ALLOC
+	dep_bool '  include /proc/mem_map' CONFIG_MEM_MAP $CONFIG_CONTIGUOUS_PAGE_ALLOC
+fi
+
+bool 'Kernel profiling support' CONFIG_PROFILE
+if [ "$CONFIG_PROFILE" = "y" ]; then
+  int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+  bool 'Use fast second timer for profiling' CONFIG_HIGHPROFILE
+fi
+
+bool 'Suppress Kernel BUG Messages' CONFIG_NO_KERNEL_MSG
+
+bool 'Reduce kernel task size to 1 page' CONFIG_SMALL_TASKS
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_COLDFIRE" = "y" ]; then
+    bool 'Disable BDM signals' CONFIG_BDM_DISABLE
+fi
+
+if [ "$CONFIG_H83007" = "y" -o "$CONFIG_H8S2678" = "y" ]; then
+  bool 'Executing from GDB Simurator' CONFIG_GDB_EXEC 
+  dep_bool 'Message Output for GDB MagicPrint' CONFIG_GDB_MAGICPRINT $CONFIG_GDB_EXEC
+else
+  define_bool CONFIG_GDB_EXEC n
+  define_bool CONFIG_GDB_MAGICPRINT n
+fi
+
+bool 'SystemCall trace print' CONFIG_SYSCALL_PRINT
+
+if [ "$CONFIG_GDB_EXEC" = "n" ]; then
+    bool 'Use gdb stub' CONFIG_GDB_DEBUG
+fi
+
+dep_bool 'Use gdb protocol print' CONFIG_SH_STANDARD_BIOS $CONFIG_GDB_DEBUG
+
+
+endmenu
+
+
+#############################################################################
+
+source crypto/Config.in
+source lib/Config.in
+
+#############################################################################
diff -urN linux-2.4.29/arch/h8300/defconfig linux-2.4.29-uc1/arch/h8300/defconfig
--- linux-2.4.29/arch/h8300/defconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/defconfig	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,257 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_UCLINUX=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Target Selection
+#
+CONFIG_BOARD_GENERIC=y
+# CONFIG_BOARD_AKI3068NET is not set
+# CONFIG_BOARD_H8MAX is not set
+
+#
+# Platform dependant setup
+#
+# CONFIG_H83002 is not set
+CONFIG_H83007=y
+# CONFIG_H83048 is not set
+# CONFIG_H83068 is not set
+CONFIG_CLK_FREQ=16000
+# CONFIG_RAMKERNEL is not set
+CONFIG_ROMKERNEL=y
+CONFIG_CPU_H8300H=y
+
+#
+# General setup
+#
+# CONFIG_NET is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_ELF is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_DEFAULT_CMDLINE=y
+CONFIG_KERNEL_COMMAND="console=ttySC0,38400n81"
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_RAMDISK_DATA is not set
+CONFIG_BLK_DEV_BLKMEM=y
+CONFIG_NOFLASH=y
+# CONFIG_AMDFLASH is not set
+# CONFIG_INTELFLASH is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Character devices
+#
+CONFIG_SH_SCI=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_LEDMAN is not set
+# CONFIG_DS1302 is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_EXT2_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_FULLDEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_CONTIGUOUS_PAGE_ALLOC is not set
+# CONFIG_MEM_MAP is not set
+# CONFIG_PROFILE is not set
+CONFIG_NO_KERNEL_MSG=y
+# CONFIG_SMALL_TASKS is not set
+# CONFIG_GDB_EXEC is not set
+# CONFIG_GDB_MAGICPRINT is not set
diff -urN linux-2.4.29/arch/h8300/ide_config.in linux-2.4.29-uc1/arch/h8300/ide_config.in
--- linux-2.4.29/arch/h8300/ide_config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/ide_config.in	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,7 @@
+# uClinux H8/300 Target Board Selection Menu (IDE)
+
+if [ "$CONFIG_BOARD_AKI3068NET" = "y" ]; then
+  hex 'IDE regitser base address' CONFIG_H8300_IDE_BASE 0x600000
+  hex 'IDE regitser alternate address' CONFIG_H8300_IDE_ALT 0x600020
+  int 'IDE IRQ no' CONFIG_H8300_IDE_IRQNO 4
+fi
diff -urN linux-2.4.29/arch/h8300/kernel/gpio.c linux-2.4.29-uc1/arch/h8300/kernel/gpio.c
--- linux-2.4.29/arch/h8300/kernel/gpio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/kernel/gpio.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,175 @@
+/*
+ *  linux/arch/h8300/kernel/gpio.c
+ *
+ *  Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ */
+
+/*
+ * Internal I/O Port Management
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/proc_fs.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+
+#define _(addr) (volatile unsigned char *)(addr)
+#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
+#include <asm/regs306x.h>
+static volatile unsigned char *ddrs[] = {
+	_(P1DDR),_(P2DDR),_(P3DDR),_(P4DDR),_(P5DDR),_(P6DDR),
+	NULL,    _(P8DDR),_(P9DDR),_(PADDR),_(PBDDR),
+};
+#define MAX_PORT 11
+#endif
+
+#if defined(CONFIG_H83002) || defined(CONFIG_H8048)
+/* Fix me!! */
+#include <asm/regs306x.h>
+static volatile unsigned char *ddrs[] = {
+	_(P1DDR),_(P2DDR),_(P3DDR),_(P4DDR),_(P5DDR),_(P6DDR),
+	NULL,    _(P8DDR),_(P9DDR),_(PADDR),_(PBDDR),
+};
+#define MAX_PORT 11
+#endif
+
+#if defined(CONFIG_H8S2678)
+#include <asm/regs267x.h>
+static volatile unsigned char *ddrs[] = {
+	_(P1DDR),_(P2DDR),_(P3DDR),NULL    ,_(P5DDR),_(P6DDR),
+	_(P7DDR),_(P8DDR),NULL,    _(PADDR),_(PBDDR),_(PCDDR),
+	_(PDDDR),_(PEDDR),_(PFDDR),_(PGDDR),_(PHDDR),
+	_(PADDR),_(PBDDR),_(PCDDR),_(PDDDR),_(PEDDR),_(PFDDR),
+	_(PGDDR),_(PHDDR)
+};
+#define MAX_PORT 17
+#endif
+#undef _
+
+#if !defined(P1DDR)
+#error Unsuppoted CPU Selection
+#endif
+
+static struct {
+	unsigned char used;
+	unsigned char ddr;
+} gpio_regs[MAX_PORT];
+
+extern char *_platform_gpio_table(int length);
+
+int h8300_reserved_gpio(int port, unsigned int bits)
+{
+	unsigned char *used;
+
+	if (port < 0 || port >= MAX_PORT)
+		return -1;
+	used = &(gpio_regs[port].used);
+	if ((*used & bits) != 0)
+		return 0;
+	*used |= bits;
+	return 1;
+}
+
+int h8300_free_gpio(int port, unsigned int bits)
+{
+	unsigned char *used;
+
+	if (port < 0 || port >= MAX_PORT)
+		return -1;
+	used = &(gpio_regs[port].used);
+	if ((*used & bits) != bits)
+		return 0;
+	*used &= (~bits);
+	return 1;
+}
+
+int h8300_set_gpio_dir(int port_bit,int dir)
+{
+	int port = (port_bit >> 8) & 0xff;
+	int bit  = port_bit & 0xff;
+
+	if (ddrs[port] == NULL)
+		return 0;
+	if (gpio_regs[port].used & bit) {
+		if (dir)
+			gpio_regs[port].ddr |= bit;
+		else
+			gpio_regs[port].ddr &= ~bit;
+		*ddrs[port] = gpio_regs[port].ddr;
+		return 1;
+	} else
+		return 0;
+}
+
+int h8300_get_gpio_dir(int port_bit)
+{
+	int port = (port_bit >> 8) & 0xff;
+	int bit  = port_bit & 0xff;
+
+	if (ddrs[port] == NULL)
+		return 0;
+	if (gpio_regs[port].used & bit) {
+		return (gpio_regs[port].ddr & bit) != 0;
+	} else
+		return -1;
+}
+
+#if defined(CONFIG_PROC_FS)
+static char *port_status(int portno)
+{
+	static char result[10];
+	const static char io[2]={'I','O'};
+	char *rp;
+	int c;
+	unsigned char used,ddr;
+	
+	used = gpio_regs[portno].used;
+	ddr  = gpio_regs[portno].ddr;
+	result[8]='\0';
+	rp = result + 7;
+	for (c = 8; c > 0; c--,rp--,used >>= 1, ddr >>= 1)
+		if (used & 0x01)
+			*rp = io[ ddr & 0x01];
+		else	
+			*rp = '-';
+	return result;
+}
+
+static int gpio_proc_read(char *buf, char **start, off_t offset, 
+                          int len, int *eof, void *data)
+{
+	int c,outlen;
+	const static char port_name[]="123456789ABCDEFGH";
+	outlen = 0;
+	for (c = 0; c < MAX_PORT; c++) {
+		if (ddrs[c] == NULL)
+			continue ;
+		len = sprintf(buf,"P%c: %s\n",port_name[c],port_status(c));
+		buf += len;
+		outlen += len;
+	}
+	return outlen;
+}
+
+static __init int register_proc(void)
+{
+	struct proc_dir_entry *proc_gpio;
+
+	proc_gpio = create_proc_entry("gpio", S_IRUGO, NULL);
+	if (proc_gpio) 
+		proc_gpio->read_proc = gpio_proc_read;
+	return proc_gpio != NULL;
+}
+
+__initcall(register_proc);
+#endif
+
+void __init h8300_gpio_init(void)
+{
+	memcpy(gpio_regs,_platform_gpio_table(sizeof(gpio_regs)),sizeof(gpio_regs));
+}
+
diff -urN linux-2.4.29/arch/h8300/kernel/h8300_ksyms.c linux-2.4.29-uc1/arch/h8300/kernel/h8300_ksyms.c
--- linux-2.4.29/arch/h8300/kernel/h8300_ksyms.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/kernel/h8300_ksyms.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,119 @@
+#include <linux/module.h>
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
+
+#include <asm/setup.h>
+#include <asm/pgalloc.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/semaphore.h>
+#include <asm/checksum.h>
+#include <asm/hardirq.h>
+#include <asm/softirq.h>
+#include <asm/current.h>
+#include <asm/gpio.h>
+
+//asmlinkage long long __ashrdi3 (long long, int);
+//asmlinkage long long __lshrdi3 (long long, int);
+extern char h8300_debug_device[];
+
+extern void dump_thread(struct pt_regs *, struct user *);
+
+/* platform dependent support */
+
+EXPORT_SYMBOL(dump_thread);
+EXPORT_SYMBOL(strnlen);
+EXPORT_SYMBOL(strrchr);
+EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strcat);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strcmp);
+EXPORT_SYMBOL(strncmp);
+
+EXPORT_SYMBOL(ip_fast_csum);
+
+EXPORT_SYMBOL(kernel_thread);
+
+EXPORT_SYMBOL(__up);
+EXPORT_SYMBOL(__down);
+
+/* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial_copy);
+
+/* The following are special because they're not called
+   explicitly (the C compiler generates them).  Fortunately,
+   their interface isn't gonna change any time soon now, so
+   it's OK to leave it out of version control.  */
+//EXPORT_SYMBOL_NOVERS(__ashrdi3);
+//EXPORT_SYMBOL_NOVERS(__lshrdi3);
+EXPORT_SYMBOL_NOVERS(memcpy);
+EXPORT_SYMBOL_NOVERS(memset);
+EXPORT_SYMBOL_NOVERS(memcmp);
+EXPORT_SYMBOL_NOVERS(memscan);
+EXPORT_SYMBOL_NOVERS(memmove);
+
+EXPORT_SYMBOL(get_wchan);
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler...  (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __gcc_bcmp(void);
+extern void __ashldi3(void);
+extern void __ashrdi3(void);
+extern void __cmpdi2(void);
+extern void __divdi3(void);
+extern void __divsi3(void);
+extern void __lshrdi3(void);
+extern void __moddi3(void);
+extern void __modsi3(void);
+extern void __muldi3(void);
+extern void __mulsi3(void);
+extern void __negdi2(void);
+extern void __ucmpdi2(void);
+extern void __udivdi3(void);
+extern void __udivmoddi4(void);
+extern void __udivsi3(void);
+extern void __umoddi3(void);
+extern void __umodsi3(void);
+
+        /* gcc lib functions */
+EXPORT_SYMBOL_NOVERS(__gcc_bcmp);
+EXPORT_SYMBOL_NOVERS(__ashldi3);
+EXPORT_SYMBOL_NOVERS(__ashrdi3);
+EXPORT_SYMBOL_NOVERS(__cmpdi2);
+EXPORT_SYMBOL_NOVERS(__divdi3);
+EXPORT_SYMBOL_NOVERS(__divsi3);
+EXPORT_SYMBOL_NOVERS(__lshrdi3);
+EXPORT_SYMBOL_NOVERS(__moddi3);
+EXPORT_SYMBOL_NOVERS(__modsi3);
+EXPORT_SYMBOL_NOVERS(__muldi3);
+EXPORT_SYMBOL_NOVERS(__mulsi3);
+EXPORT_SYMBOL_NOVERS(__negdi2);
+EXPORT_SYMBOL_NOVERS(__ucmpdi2);
+EXPORT_SYMBOL_NOVERS(__udivdi3);
+EXPORT_SYMBOL_NOVERS(__udivmoddi4);
+EXPORT_SYMBOL_NOVERS(__udivsi3);
+EXPORT_SYMBOL_NOVERS(__umoddi3);
+EXPORT_SYMBOL_NOVERS(__umodsi3);
+
+EXPORT_SYMBOL_NOVERS(_current_task);
+
+#ifdef MAGIC_ROM_PTR
+EXPORT_SYMBOL_NOVERS(is_in_rom);
+#endif
+
+EXPORT_SYMBOL_NOVERS(h8300_reserved_gpio);
+EXPORT_SYMBOL_NOVERS(h8300_free_gpio);
+EXPORT_SYMBOL_NOVERS(h8300_set_gpio_dir);
+EXPORT_SYMBOL_NOVERS(h8300_get_gpio_dir);
+
diff -urN linux-2.4.29/arch/h8300/kernel/ints.c linux-2.4.29-uc1/arch/h8300/kernel/ints.c
--- linux-2.4.29/arch/h8300/kernel/ints.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/kernel/ints.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,245 @@
+/*
+ * linux/arch/h8300/kernel/ints.c
+ * Interrupt handling common routines.
+ *
+ * Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ * Based on linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne <jeff@uClinux.org>
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/bootmem.h>
+#include <linux/random.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/gpio.h>
+#include <asm/hardirq.h>
+
+/* table for system interrupt handlers */
+static irq_handler_t *irq_list[NR_IRQS];
+static int use_kmalloc;
+
+extern unsigned long *interrupt_redirect_table;
+extern const int h8300_saved_vectors[];
+extern const unsigned long h8300_trap_table[];
+
+#define CPU_VECTOR ((unsigned long *)0x000000)
+#define ADDR_MASK (0xffffff)
+
+int h8300_enable_irq_pin(unsigned int irq);
+void h8300_disable_irq_pin(unsigned int irq);
+
+static inline unsigned long *get_vector_address(void)
+{
+	unsigned long *rom_vector = CPU_VECTOR;
+	unsigned long base,tmp;
+	int vec_no;
+
+	base = rom_vector[EXT_IRQ0] & ADDR_MASK;
+	
+	/* check romvector format */
+	for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ0+EXT_IRQS; vec_no++) {
+		if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK))
+			return NULL;
+	}
+
+	/* ramvector base address */
+	base -= EXT_IRQ0*4;
+
+	/* writerble check */
+	tmp = ~(*(volatile unsigned long *)base);
+	(*(volatile unsigned long *)base) = tmp;
+	if ((*(volatile unsigned long *)base) != tmp)
+		return NULL;
+	return (unsigned long *)base;
+}
+
+void __init init_IRQ(void)
+{
+#if defined(CONFIG_RAMKERNEL)
+	int i;
+	unsigned long *ramvec,*ramvec_p;
+	const unsigned long *trap_entry;
+	const int *saved_vector;
+
+	ramvec = get_vector_address();
+	if (ramvec == NULL)
+		panic("interrupt vector serup failed.");
+	else
+		printk("virtual vector at 0x%08lx\n",(unsigned long)ramvec);
+
+	/* create redirect table */
+	ramvec_p = ramvec;
+	trap_entry = h8300_trap_table;
+	saved_vector = h8300_saved_vectors;
+	for ( i = 0; i < NR_TRAPS; i++) {
+		if (i == *saved_vector) {
+			ramvec_p++;
+			saved_vector++;
+		} else {
+			if (*trap_entry)
+				*ramvec_p++ = VECTOR(*trap_entry++);
+			else {
+				ramvec_p++;
+				trap_entry++;
+			}
+		}
+	}
+	for ( ; i < NR_IRQS; i++)
+		if (i == *saved_vector) {
+			ramvec_p++;
+			saved_vector++;
+		} else
+			*ramvec_p++ = REDIRECT(interrupt_entry);
+	interrupt_redirect_table = ramvec;
+#ifdef DUMP_VECTOR
+	ramvec_p = ramvec;
+	for (i = 0; i < NR_IRQS; i++) {
+		if ((i % 8) == 0)
+			printk("\n%p: ",ramvec_p);
+		printk("%p ",*ramvec_p);
+		ramvec_p++;
+	}
+	printk("\n");
+#endif
+#endif
+}
+
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+                unsigned long flags, const char *devname, void *dev_id)
+{
+	irq_handler_t *irq_handle;
+	if (irq < 0 || irq >= NR_IRQS) {
+		printk("Incorrect IRQ %d from %s\n", irq, devname);
+		return -EINVAL;
+	}
+	if (irq_list[irq] || (h8300_enable_irq_pin(irq) == -EBUSY))
+		return -EBUSY;  /* already used */
+	if(use_kmalloc)
+		irq_handle = (irq_handler_t *)kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
+	else {
+		irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t));
+		irq_handle = ((irq_handler_t *)
+			      ((unsigned long) irq_handle | 0x80000000UL));
+	}
+
+	if (irq_handle == NULL)
+		return -ENOMEM;
+
+	irq_handle->handler = handler;
+	irq_handle->flags   = flags;
+	irq_handle->count   = 0;
+	irq_handle->dev_id  = dev_id;
+	irq_handle->devname = devname;
+	irq_list[irq] = irq_handle;
+
+	if (irq_handle->flags & SA_SAMPLE_RANDOM)
+		rand_initialize_irq(irq);
+
+	/* enable interrupt */
+	/* compatible i386  */
+	enable_irq(irq);
+	return 0;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq >= NR_IRQS) {
+		return;
+	}
+	if (!irq_list[irq] || irq_list[irq]->dev_id != dev_id)
+		printk("Removing probably wrong IRQ %d from %s\n",
+		       irq, irq_list[irq]->devname);
+	/* disable interrupt & release IRQ pin */
+	h8300_disable_irq_pin(irq);
+	if (((unsigned long)irq_list[irq] & 0x80000000UL) == 0) {
+		kfree(irq_list[irq]);
+		irq_list[irq] = NULL;
+	}
+}
+
+void enable_irq(unsigned int irq)
+{
+	if (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS))
+		IER_REGS |= 1 << (irq - EXT_IRQ0);
+}
+
+void disable_irq(unsigned int irq)
+{
+	if (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS))
+		IER_REGS &= ~(1 << (irq - EXT_IRQ0));
+}
+
+/*
+ * Do we need these probe functions on the m68k?
+ */
+unsigned long probe_irq_on (void)
+{
+	return 0;
+}
+
+int probe_irq_off (unsigned long irqs)
+{
+	return 0;
+}
+
+asmlinkage void process_int(int irq, struct pt_regs *fp)
+{
+	irq_enter(0,0);
+	/* ISR clear       */
+	/* compatible i386 */
+	h8300_clear_isr(irq);
+	if (irq < NR_IRQS) {
+		if (irq_list[irq]) {
+			irq_list[irq]->handler(irq, irq_list[irq]->dev_id, fp);
+			irq_list[irq]->count++;
+			if (irq_list[irq]->flags & SA_SAMPLE_RANDOM)
+				add_interrupt_randomness(irq);
+		}
+	} else {
+		BUG();
+	}
+	irq_exit(0,0);
+}
+
+int get_irq_list(char *buf)
+{
+	int i, len = 0;
+
+	for (i = 0; i < NR_IRQS; i++) {
+		if (irq_list[i]) {
+			len += sprintf(buf+len, "irq %2d: %10u ", i,
+			               irq_list[i]->count);
+			len += sprintf(buf+len, "%s\n", irq_list[i]->devname);
+		}
+	}
+	return len;
+}
+
+void init_irq_proc(void)
+{
+}
+
+static int __init enable_kmalloc(void)
+{
+	use_kmalloc = 1;
+	return 0;
+}
+__initcall(enable_kmalloc);
diff -urN linux-2.4.29/arch/h8300/kernel/Makefile linux-2.4.29-uc1/arch/h8300/kernel/Makefile
--- linux-2.4.29/arch/h8300/kernel/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/kernel/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,20 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+all: kernel.o
+
+O_TARGET := kernel.o
+obj-y := process.o traps.o ptrace.o ints.o \
+	 sys_h8300.o time.o semaphore.o signal.o \
+         setup.o h8300_ksyms.o gpio.o syscalls.o
+
+export-objs := h8300_ksyms.o
+
+include $(TOPDIR)/Rules.make
+
diff -urN linux-2.4.29/arch/h8300/kernel/process.c linux-2.4.29-uc1/arch/h8300/kernel/process.c
--- linux-2.4.29/arch/h8300/kernel/process.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/kernel/process.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,314 @@
+/*
+ *  linux/arch/h8300/kernel/process.c
+ *
+ * Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68knommu/kernel/process.c
+ *
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@uClinux.org>,
+ *                      Kenneth Albanowski <kjahds@kjahds.com>,
+ *                      The Silver Hammer Group, Ltd.
+ *
+ *  linux/arch/m68k/kernel/process.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ *
+ *  68060 fixes by Jesper Skov
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/reboot.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+
+/*
+ * Initial task structure. Make this a per-architecture thing,
+ * because different architectures tend to have different
+ * alignment requirements and potentially different initial
+ * setup.
+ */
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS;
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+union task_union init_task_union
+__attribute__((section(".data.init_task"), aligned(KTHREAD_SIZE)))
+	= { task: INIT_TASK(init_task_union.task) };
+
+asmlinkage void ret_from_exception(void);
+
+/*
+ * The idle loop on an H8/300..
+ */
+#if !defined(CONFIG_GDB_EXEC)
+static void default_idle(void)
+{
+	while(1) {
+		if (!current->need_resched) {
+			sti();
+			__asm__("sleep");
+			cli();
+		}
+		schedule();
+	}
+}
+
+void (*idle)(void) = default_idle;
+#else
+static void gdb_idle(void)
+{
+	while(1) {
+		if (current->need_resched)
+			schedule();
+	}
+}
+
+void (*idle)(void) = gdb_idle;
+#endif
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle(void)
+{
+	/* endless idle loop with no priority at all */
+	init_idle();
+	current->nice = 20;
+	current->counter = -100;
+	idle();
+}
+
+void machine_restart(char * __unused)
+{
+	cli();
+	__asm__("jmp @@0"); 
+}
+
+void machine_halt(void)
+{
+	cli();
+	__asm__("sleep");
+	for (;;);
+}
+
+void machine_power_off(void)
+{
+	cli();
+	__asm__("sleep");
+	for (;;);
+}
+
+void show_regs(struct pt_regs * regs)
+{
+	printk("\n");
+	printk("PC: %08lx  Status: %02x\n",
+	       regs->pc, regs->ccr);
+	printk("ORIG_ER0: %08lx ER0: %08lx ER1: %08lx\n",
+	       regs->orig_er0, regs->er0, regs->er1);
+	printk("ER2: %08lx ER3: %08lx ER4: %08lx ER5: %08lx\n",
+	       regs->er2, regs->er3, regs->er4, regs->er5);
+	if (!(regs->ccr & 0x10))
+		printk("USP: %08lx\n", rdusp());
+}
+
+/*
+ * Create a kernel thread
+ */
+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	long retval;
+	long clone_arg;
+	mm_segment_t fs;
+
+	fs = get_fs();
+	set_fs (KERNEL_DS);
+	clone_arg = flags | CLONE_VM;
+	__asm__("mov.l sp,er3\n\t"
+		"sub.l er2,er2\n\t"
+		"mov.l %2,er1\n\t"
+		"mov.l %1,er0\n\t"
+		"trapa #0\n\t"
+		"cmp.l sp,er3\n\t"
+		"beq 1f\n\t"
+		"mov.l %4,er0\n\t"
+		"mov.l %3,er1\n\t"
+		"jsr @er1\n\t"
+		"mov.l %5,er0\n\t"
+		"trapa #0\n"
+		"1:\n\t"
+		"mov.l er0,%0"
+		:"=r"(retval)
+		:"i"(__NR_clone),"g"(clone_arg),"r"(fn),"r"(arg),"i"(__NR_exit)
+		:"er0","er1","er2","er3");
+	set_fs (fs);
+	return retval;
+}
+
+void flush_thread(void)
+{
+}
+
+/*
+ * "h8300_fork()".. By the time we get here, the
+ * non-volatile registers have also been saved on the
+ * stack. We do some ugly pointer stuff here.. (see
+ * also copy_thread)
+ */
+
+asmlinkage int h8300_fork(struct pt_regs *regs)
+{
+	return -EINVAL;
+}
+
+asmlinkage int h8300_vfork(struct pt_regs *regs)
+{
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0);
+}
+
+asmlinkage int h8300_clone(struct pt_regs *regs)
+{
+	unsigned long clone_flags;
+	unsigned long newsp;
+
+	/* syscall2 puts clone_flags in er1 and usp in er2 */
+	clone_flags = regs->er1;
+	newsp = regs->er2;
+	if (!newsp)
+		newsp  = rdusp();
+	return do_fork(clone_flags, newsp, regs, 0);
+}
+
+int copy_thread(int nr, unsigned long clone_flags,
+                unsigned long usp, unsigned long topstk,
+		 struct task_struct * p, struct pt_regs * regs)
+{
+	struct pt_regs * childregs;
+	struct switch_stack * childstack, *stack;
+	unsigned long stack_offset, *retp;
+
+	stack_offset = KTHREAD_SIZE - sizeof(struct pt_regs);
+	childregs = (struct pt_regs *) ((unsigned long)p + stack_offset);
+
+	*childregs = *regs;
+
+	retp = ((unsigned long *) regs);
+	stack = ((struct switch_stack *) retp) - 1;
+
+	childstack = ((struct switch_stack *) childregs) - 1;
+	*childstack = *stack;
+	childregs->er0 = 0;
+	childstack->retpc = (unsigned long) ret_from_exception;
+
+	p->thread.usp = usp;
+	p->thread.ksp = (unsigned long)childstack;
+
+	return 0;
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs * regs, struct user * dump)
+{
+	struct switch_stack *sw;
+
+/* changed the size calculations - should hopefully work better. lbt */
+	dump->magic = CMAGIC;
+	dump->start_code = 0;
+	dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
+	dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
+	dump->u_dsize = ((unsigned long) (current->mm->brk +
+					  (PAGE_SIZE-1))) >> PAGE_SHIFT;
+	dump->u_dsize -= dump->u_tsize;
+	dump->u_ssize = 0;
+
+	dump->u_ar0 = (struct user_regs_struct *)(((int)(&dump->regs)) -((int)(dump)));
+	sw = ((struct switch_stack *)regs) - 1;
+	dump->regs.er0 = regs->er0;
+	dump->regs.er1 = regs->er1;
+	dump->regs.er2 = regs->er2;
+	dump->regs.er3 = regs->er3;
+	dump->regs.er4 = regs->er4;
+	dump->regs.er5 = regs->er5;
+	dump->regs.er6 = sw->er6;
+	dump->regs.orig_er0 = regs->orig_er0;
+	dump->regs.ccr = regs->ccr;
+	dump->regs.pc  = regs->pc;
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage int sys_execve(char *name, char **argv, char **envp, int dummy, ...)
+{
+	int error;
+	char * filename;
+	struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy);
+
+	lock_kernel();
+	filename = getname(name);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+	error = do_execve(filename, argv, envp, regs);
+	putname(filename);
+out:
+	unlock_kernel();
+	return error;
+}
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+#define first_sched	((unsigned long) scheduling_functions_start_here)
+#define last_sched	((unsigned long) scheduling_functions_end_here)
+
+unsigned long get_wchan(struct task_struct *p)
+{
+	unsigned long fp, pc;
+	unsigned long stack_page;
+	int count = 0;
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	stack_page = (unsigned long)p;
+	fp = ((struct switch_stack *)p->thread.ksp)->er6;
+	do {
+		if (fp < stack_page+sizeof(struct task_struct) ||
+		    fp >= 8184+stack_page)
+			return 0;
+		pc = ((unsigned long *)fp)[1];
+		/* FIXME: This depends on the order of these functions. */
+		if (pc < first_sched || pc >= last_sched)
+			return pc;
+		fp = *(unsigned long *) fp;
+	} while (count++ < 16);
+	return 0;
+}
diff -urN linux-2.4.29/arch/h8300/kernel/ptrace.c linux-2.4.29-uc1/arch/h8300/kernel/ptrace.c
--- linux-2.4.29/arch/h8300/kernel/ptrace.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/kernel/ptrace.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,287 @@
+/*
+ *  linux/arch/h8300/kernel/ptrace.c
+ *
+ *  Yoshinori Sato <qzb04471@nifty.ne.jp>
+ *
+ *  Based on:
+ *  linux/arch/m68k/kernel/ptrace.c
+ *
+ *  Copyright (C) 1994 by Hamish Macdonald
+ *  Taken from linux/kernel/ptrace.c and modified for M680x0.
+ *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/config.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/signal.h>
+
+/* cpu depend functions */
+extern long h8300_get_reg(struct task_struct *task, int regno);
+extern int  h8300_put_reg(struct task_struct *task, int regno, unsigned long data);
+extern void h8300_disable_trace(struct task_struct *child);
+extern void h8300_enable_trace(struct task_struct *child);
+
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+inline
+static int read_long(struct task_struct * tsk, unsigned long addr,
+	unsigned long * result)
+{
+	*result = *(unsigned long *)addr;
+	return 0;
+}
+
+void ptrace_disable(struct task_struct *child)
+{
+	h8300_disable_trace(child);
+}
+
+asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	int ret;
+
+	lock_kernel();
+	ret = -EPERM;
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED)
+			goto out;
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		ret = 0;
+		goto out;
+	}
+	ret = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		goto out;
+
+	ret = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out_tsk;
+
+	if (request == PTRACE_ATTACH) {
+		ret = ptrace_attach(child);
+		goto out_tsk;
+	}
+	ret = -ESRCH;
+	if (!(child->ptrace & PT_PTRACED))
+		goto out_tsk;
+	if (child->state != TASK_STOPPED) {
+		if (request != PTRACE_KILL)
+			goto out_tsk;
+	}
+	if (child->p_pptr != current)
+		goto out_tsk;
+
+	switch (request) {
+		case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+		case PTRACE_PEEKDATA: {
+			unsigned long tmp;
+
+			ret = -EIO;
+			if (access_process_vm(child, addr, &tmp, sizeof(tmp), 0) != sizeof(tmp))
+				break;
+			ret = verify_area(VERIFY_WRITE, (void *) data, sizeof(long));
+			if (!ret)
+				put_user(tmp, (unsigned long *) data);
+			break ;
+		}
+
+	/* read the word at location addr in the USER area. */
+		case PTRACE_PEEKUSR: {
+			unsigned long tmp;
+			
+			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
+				ret = -EIO;
+			
+			ret = verify_area(VERIFY_WRITE, (void *) data,
+					  sizeof(long));
+			if (ret)
+				break ;
+			tmp = 0;  /* Default return condition */
+			addr = addr >> 2; /* temporary hack. */
+			if (addr < H8300_REGS_NO)
+				tmp = h8300_get_reg(child, addr);
+			else {
+				switch(addr) {
+				case 49:
+					tmp = child->mm->start_code;
+					break ;
+				case 50:
+					tmp = child->mm->start_data;
+					break ;
+				case 51:
+					tmp = child->mm->end_code;
+					break ;
+				case 52:
+					tmp = child->mm->end_data;
+					break ;
+				default:
+					ret = -EIO;
+				}
+			}
+			if (!ret)
+				put_user(tmp,(unsigned long *) data);
+			break ;
+		}
+
+      /* when I and D space are separate, this will have to be fixed. */
+		case PTRACE_POKETEXT: /* write the word at location addr. */
+		case PTRACE_POKEDATA:
+			ret = 0;
+			if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+				break;
+			ret = -EIO;
+			break;
+
+		case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) {
+				ret = -EIO;
+				break ;
+			}
+			addr = addr >> 2; /* temporary hack. */
+			    
+			if (addr == PT_ORIG_ER0) {
+				ret = -EIO;
+				break ;
+			}
+			if (addr < H8300_REGS_NO) {
+				ret = h8300_put_reg(child, addr, data);
+				break ;
+			}
+			ret = -EIO;
+			break ;
+		case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+		case PTRACE_CONT: { /* restart after signal. */
+			ret = -EIO;
+			if ((unsigned long) data >= _NSIG)
+				break ;
+			if (request == PTRACE_SYSCALL)
+				child->flags |= PT_TRACESYS;
+			else
+				child->flags &= ~PT_TRACESYS;
+			child->exit_code = data;
+			wake_up_process(child);
+			/* make sure the single step bit is not set. */
+			h8300_disable_trace(child);
+			ret = 0;
+		}
+
+/*
+ * make the child exit.  Best I can do is send it a sigkill. 
+ * perhaps it should be put in the status that it wants to 
+ * exit.
+ */
+		case PTRACE_KILL: {
+
+			ret = 0;
+			if (child->state == TASK_ZOMBIE) /* already dead */
+				break;
+			child->exit_code = SIGKILL;
+			h8300_disable_trace(child);
+			wake_up_process(child);
+			break;
+		}
+
+		case PTRACE_SINGLESTEP: {  /* set the trap flag. */
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				break;
+			child->ptrace &= ~PT_TRACESYS;
+			child->exit_code = data;
+			h8300_enable_trace(child);
+			wake_up_process(child);
+			ret = 0;
+			break;
+		}
+
+		case PTRACE_DETACH:	/* detach a process that was attached. */
+			ret = ptrace_detach(child, data);
+			break;
+
+		case PTRACE_GETREGS: { /* Get all gp regs from the child. */
+		  	int i;
+			unsigned long tmp;
+			for (i = 0; i < H8300_REGS_NO; i++) {
+			    tmp = h8300_get_reg(child, i);
+			    if (put_user(tmp, (unsigned long *) data)) {
+				ret = -EFAULT;
+				break;
+			    }
+			    data += sizeof(long);
+			}
+			ret = 0;
+			break;
+		}
+
+		case PTRACE_SETREGS: { /* Set all gp regs in the child. */
+			int i;
+			unsigned long tmp;
+			for (i = 0; i < H8300_REGS_NO; i++) {
+			    if (get_user(tmp, (unsigned long *) data)) {
+				ret = -EFAULT;
+				break;
+			    }
+			    h8300_put_reg(child, i, tmp);
+			    data += sizeof(long);
+			}
+			ret = 0;
+			break;
+		}
+
+		default:
+			ret = -EIO;
+			break;
+	}
+out_tsk:
+	free_task_struct(child);
+out:
+	unlock_kernel();
+	return ret;
+}
+
+asmlinkage void syscall_trace(void)
+{
+	if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
+			!= (PT_PTRACED|PT_TRACESYS))
+		return;
+	current->exit_code = SIGTRAP;
+	current->state = TASK_STOPPED;
+	notify_parent(current, SIGCHLD);
+	schedule();
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+}
diff -urN linux-2.4.29/arch/h8300/kernel/semaphore.c linux-2.4.29-uc1/arch/h8300/kernel/semaphore.c
--- linux-2.4.29/arch/h8300/kernel/semaphore.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/kernel/semaphore.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,132 @@
+/*
+ *  Generic semaphore code. Buyer beware. Do your own
+ * specific changes in <asm/semaphore-helper.h>
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <asm/semaphore-helper.h>
+
+#ifndef CONFIG_RMW_INSNS
+spinlock_t semaphore_wake_lock;
+#endif
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to sleep, while the "waking" variable is
+ * incremented when the "up()" code goes to wake up waiting
+ * processes.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * waking_non_zero() (from asm/semaphore.h) must execute
+ * atomically.
+ *
+ * When __up() is called, the count was negative before
+ * incrementing it, and we need to wake up somebody.
+ *
+ * This routine adds one to the count of processes that need to
+ * wake up and exit.  ALL waiting processes actually wake up but
+ * only the one that gets to the "waking" field first will gate
+ * through and acquire the semaphore.  The others will go back
+ * to sleep.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+void __up(struct semaphore *sem)
+{
+	wake_one_more(sem);
+	wake_up(&sem->wait);
+}
+
+/*
+ * Perform the "down" function.  Return zero for semaphore acquired,
+ * return negative for signalled out of the function.
+ *
+ * If called from __down, the return is ignored and the wait loop is
+ * not interruptible.  This means that a task waiting on a semaphore
+ * using "down()" cannot be killed until someone does an "up()" on
+ * the semaphore.
+ *
+ * If called from __down_interruptible, the return value gets checked
+ * upon return.  If the return value is negative then the task continues
+ * with the negative value in the return register (it can be tested by
+ * the caller).
+ *
+ * Either form may be used in conjunction with "up()".
+ *
+ */
+
+
+#define DOWN_HEAD(task_state)						\
+									\
+									\
+	current->state = (task_state);					\
+	add_wait_queue(&sem->wait, &wait);				\
+									\
+	/*								\
+	 * Ok, we're set up.  sem->count is known to be less than zero	\
+	 * so we must wait.						\
+	 *								\
+	 * We can let go the lock for purposes of waiting.		\
+	 * We re-acquire it after awaking so as to protect		\
+	 * all semaphore operations.					\
+	 *								\
+	 * If "up()" is called before we call waking_non_zero() then	\
+	 * we will catch it right away.  If it is called later then	\
+	 * we will have to go through a wakeup cycle to catch it.	\
+	 *								\
+	 * Multiple waiters contend for the semaphore lock to see	\
+	 * who gets to gate through and who has to wait some more.	\
+	 */								\
+	for (;;) {
+
+#define DOWN_TAIL(task_state)			\
+		current->state = (task_state);	\
+	}					\
+	current->state = TASK_RUNNING;		\
+	remove_wait_queue(&sem->wait, &wait);
+
+void __down(struct semaphore * sem)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	DOWN_HEAD(TASK_UNINTERRUPTIBLE)
+	if (waking_non_zero(sem))
+		break;
+	schedule();
+	DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int ret = 0;
+
+	DOWN_HEAD(TASK_INTERRUPTIBLE)
+
+	ret = waking_non_zero_interruptible(sem, current);
+	if (ret)
+	{
+		if (ret == 1)
+			/* ret != 0 only if we get interrupted -arca */
+			ret = 0;
+		break;
+	}
+	schedule();
+	DOWN_TAIL(TASK_INTERRUPTIBLE)
+	return ret;
+}
+
+int __down_trylock(struct semaphore * sem)
+{
+	return waking_non_zero_trylock(sem);
+}
diff -urN linux-2.4.29/arch/h8300/kernel/setup.c linux-2.4.29-uc1/arch/h8300/kernel/setup.c
--- linux-2.4.29/arch/h8300/kernel/setup.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/kernel/setup.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,269 @@
+/*
+ *  linux/arch/h8300/kernel/setup.c
+ *
+ *  Copyleft  ()) 2000       James D. Schettine {james@telos-systems.com}
+ *  Copyright (C) 1999,2000  Greg Ungerer (gerg@snapgear.com)
+ *  Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uClinux.org>
+ *  Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ *  Copyright (C) 1995       Hamish Macdonald
+ *  Copyright (C) 2000       Lineo Inc. (www.lineo.com) 
+ *  Copyright (C) 2001 	     Lineo, Inc. <www.lineo.com>
+ *
+ *  H8/300H porting Yoshinori Sato <ysato@users.sourceforge.jp>
+ */
+
+/*
+ * This file handles the architecture-dependent parts of system setup
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/genhd.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/major.h>
+#include <linux/bootmem.h>
+#include <linux/seq_file.h>
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <linux/blk.h>
+#include <asm/pgtable.h>
+#endif
+
+#if defined(CONFIG_CPU_H8300H)
+#define CPU "H8/300H"
+#include <asm/regs306x.h>
+#endif
+#if defined(CONFIG_CPU_H8S)
+#define CPU "H8S"
+#include <asm/regs267x.h>
+#endif
+
+#define STUBSIZE 0xc000;
+
+unsigned long rom_length;
+unsigned long memory_start;
+unsigned long memory_end;
+
+struct task_struct *_current_task;
+
+char command_line[512];
+char saved_command_line[512];
+
+extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end, _erom;
+extern int _ramstart, _ramend;
+extern char _target_name[];
+extern int h8300_gpio_init(void);
+
+#if defined(CONFIG_BLK_DEV_INITRD)
+extern unsigned long initrd_start,initrd_end;
+#endif
+
+#if defined(CONFIG_GDB_EXEC) && defined(CONFIG_GDB_MAGICPRINT)
+/* printk with gdb service */
+static void gdb_console_output(struct console *c, char *msg, unsigned len)
+{
+	for (; len > 0; len--) {
+		asm("mov.w %0,r2\n\t"
+                    "jsr @0xc4"::"r"(*msg++):"er2");
+	}
+}
+
+static kdev_t gdb_console_device(struct console *c)
+{
+    	/* TODO: this is totally bogus */
+	/* return MKDEV(SCI_MAJOR, SCI_MINOR_START + c->index); */
+	return 0;
+}
+
+/*
+ *	Setup initial baud/bits/parity. We do two things here:
+ *	- construct a cflag setting for the first rs_open()
+ *	- initialize the serial port
+ *	Return non-zero if we didn't find a serial port.
+ */
+static int __init gdb_console_setup(struct console *co, char *options)
+{
+	return 0;
+}
+
+static struct console gdb_console = {
+	name:		"gdb",
+	write:		gdb_console_output,
+	device:		gdb_console_device,
+	setup:		gdb_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+#endif
+
+void __init setup_arch(char **cmdline_p)
+{
+	int bootmap_size;
+	unsigned int blkdev_length = 0;
+
+	memory_start = (unsigned long) &_ramstart;
+#if defined(CONFIG_ROMKERNEL)
+	rom_length = (unsigned long) &_erom;
+#endif
+
+#if defined(CONFIG_BLK_DEV_BLKMEM)
+	/* allow for ROMFS on the end of the kernel */
+	if (memcmp((void *)memory_start, "-rom1fs-", 8) == 0) {
+		blkdev_length = be32_to_cpu(((unsigned long *) (memory_start))[2]);
+#if defined(CONFIG_BLK_DEV_INITRD)
+		initrd_end = memory_start += blkdev_length
+#else
+		memory_start += blkdev_length;
+#endif
+	}
+#endif
+
+	memory_start = PAGE_ALIGN(memory_start);
+	memory_end = (unsigned long) &_ramend; /* by now the stack is part of the init task */
+#if defined(CONFIG_GDB_DEBUG)
+	memory_end -= STUBSIZE;
+#endif
+#if defined(CONFIG_BLKDEV_RESERVE)
+	/* get BLKDEV length */
+	blkdev_length = be32_to_cpu(((unsigned long *) (CONFIG_BLKDEV_RESERVE_ADDRESS))[2]);
+	/* BLKDEV before userarea */
+	if (memory_start < CONFIG_BLKDEV_RESERVE_ADDRESS + blkdev_length)
+		memory_start = CONFIG_BLKDEV_RESERVE_ADDRESS + blkdev_length;
+	/* BLKDEV after userarea */
+	if (memory_end > CONFIG_BLKDEV_RESERVE_ADDRESS)
+		memory_end = CONFIG_BLKDEV_RESERVE_ADDRESS;
+#endif
+
+	init_mm.start_code = (unsigned long) &_stext;
+	init_mm.end_code = (unsigned long) &_etext;
+	init_mm.end_data = (unsigned long) &_edata;
+	init_mm.brk = (unsigned long) 0; 
+
+#if defined(CONFIG_GDB_EXEC) && defined(CONFIG_GDB_MAGICPRINT)
+	register_console(&gdb_console);
+#endif
+
+	printk("\r\nuClinux " CPU "\n");
+	printk("Target Hardware: %s\n", _target_name);
+	printk("H8/300 series support by Yoshinori Sato <ysato@users.sourceforge.jp>\n");
+
+	printk("Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
+
+
+#ifdef DEBUG
+	printk("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x "
+		"BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext,
+		(int) &_sdata, (int) &_edata,
+		(int) &_sbss, (int) &_ebss);
+	printk("KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x "
+		"STACK=0x%06x-0x%06x\n",
+	       (int) &_ebss, (int) memory_start,
+		(int) memory_start, (int) memory_end,
+		(int) memory_end, (int) &_ramend);
+#endif
+
+#ifdef CONFIG_BLK_DEV_BLKMEM
+	ROOT_DEV = MKDEV(BLKMEM_MAJOR,0);
+#endif
+
+#ifdef CONFIG_DEFAULT_CMDLINE
+	/* set from default command line */
+	if (*command_line == '\0')
+		strcpy(command_line,CONFIG_KERNEL_COMMAND);
+#endif
+	/* Keep a copy of command line */
+	*cmdline_p = &command_line[0];
+	memcpy(saved_command_line, command_line, sizeof(saved_command_line));
+	saved_command_line[sizeof(saved_command_line)-1] = 0;
+
+#ifdef DEBUG
+	if (strlen(*cmdline_p)) 
+		printk("Command line: '%s'\n", *cmdline_p);
+#endif
+
+	/*
+	 * give all the memory to the bootmap allocator,  tell it to put the
+	 * boot mem_map at the start of memory
+	 */
+	bootmap_size = init_bootmem_node(
+			NODE_DATA(0),
+			memory_start >> PAGE_SHIFT, /* map goes here */
+			PAGE_OFFSET >> PAGE_SHIFT,	/* 0 on coldfire */
+			memory_end >> PAGE_SHIFT);
+	/*
+	 * free the usable memory,  we have to make sure we do not free
+	 * the bootmem bitmap so we then reserve it after freeing it :-)
+	 */
+	free_bootmem(memory_start, memory_end - memory_start);
+	reserve_bootmem(memory_start, bootmap_size);
+	/*
+	 * get kmalloc into gear
+	 */
+	paging_init();
+	/*
+ 	 * initalize gpio management
+	 */
+	h8300_gpio_init();
+#ifdef DEBUG
+	printk("Done setup_arch\n");
+#endif
+}
+
+/*
+ *	Get CPU information for use by the procfs.
+ */
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+    char *cpu;
+    int mode;
+    u_long clockfreq;
+
+    cpu = CPU;
+    mode = *(volatile unsigned char *)MDCR & 0x07;
+
+    clockfreq = CONFIG_CLK_FREQ;
+
+    seq_printf(m,  "CPU:\t\t%s (mode:%d)\n"
+		   "Clock:\t\t%lu.%1luMHz\n"
+		   "BogoMips:\t%lu.%02lu\n"
+		   "Calibration:\t%lu loops\n",
+	           cpu,mode,
+		   clockfreq/1000,clockfreq%1000,
+		   (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
+		   (loops_per_jiffy*HZ));
+
+    return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+	start:	c_start,
+	next:	c_next,
+	stop:	c_stop,
+	show:	show_cpuinfo,
+};
diff -urN linux-2.4.29/arch/h8300/kernel/signal.c linux-2.4.29-uc1/arch/h8300/kernel/signal.c
--- linux-2.4.29/arch/h8300/kernel/signal.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/kernel/signal.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,690 @@
+/*
+ *  linux/arch/h8300/kernel/signal.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * uClinux H8/300 support by Yoshinori Sato
+ *                and David McCullough <davidm@snapgear.com>
+ *
+ * Based on
+ * Linux/m68k by Hamish Macdonald
+ */
+
+/*
+ * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
+ * Atari :-) Current limitation: Only one sigstack can be active at one time.
+ * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
+ * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
+ * signal handlers!
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/highuid.h>
+#include <linux/personality.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/ucontext.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage long sys_wait4(pid_t pid, unsigned int * stat_addr, int options,
+			struct rusage * ru);
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int do_sigsuspend(struct pt_regs *regs)
+{
+	old_sigset_t mask = regs->er3;
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->er0 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+do_rt_sigsuspend(struct pt_regs *regs)
+{
+	sigset_t *unewset = (sigset_t *)regs->er1;
+	size_t sigsetsize = (size_t)regs->er2;
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->er0 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int 
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+{
+	return do_sigaltstack(uss, uoss, rdusp());
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ *
+ * Keep the return code on the stack quadword aligned!
+ * That makes the cache flush below easier.
+ */
+
+struct sigframe
+{
+	unsigned long dummy_signo;
+	unsigned long dummy_vector;
+#if defined(CONFIG_CPU_H8S)
+	unsigned short exr;
+#endif
+	unsigned long dummy_handler;
+	char *pretcode;
+	struct sigcontext *psc;
+	char retcode[6];
+	unsigned long extramask[_NSIG_WORDS-1];
+	struct sigcontext sc;
+} __attribute__((aligned(2),packed));
+
+struct rt_sigframe
+{
+	unsigned long dummy_signo;
+	unsigned long dummy_vector;
+#if defined(CONFIG_CPU_H8S)
+	unsigned short exr;
+#endif
+	unsigned long dummy_handler;
+	char *pretcode;
+	struct siginfo *pinfo;
+	void *puc;
+	char retcode[6];
+	struct siginfo info;
+	struct ucontext uc;
+} __attribute__((aligned(2),packed));
+
+
+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
+{
+	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+		return -EFAULT;
+	if (from->si_code < 0)
+		return __copy_to_user(to, from, sizeof(siginfo_t));
+	else {
+		int err;
+
+		/* If you change siginfo_t structure, please be sure
+		   this code is fixed accordingly.
+		   It should never copy any pad contained in the structure
+		   to avoid security leaks, but must copy the generic
+		   3 ints plus the relevant union member.  */
+		err = __put_user(from->si_signo, &to->si_signo);
+		err |= __put_user(from->si_errno, &to->si_errno);
+		err |= __put_user((short)from->si_code, &to->si_code);
+		/* First 32bits of unions are always present.  */
+		err |= __put_user(from->si_pid, &to->si_pid);
+		switch (from->si_code >> 16) {
+		case __SI_FAULT >> 16:
+			break;
+		case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+			err |= __put_user(from->si_status, &to->si_status);
+		default:
+			err |= __put_user(from->si_uid, &to->si_uid);
+			break;
+		/* case __SI_RT: This is not generated by the kernel as of now.  */
+		}
+		return err;
+	}
+}
+
+static inline int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp,
+		   int *pd0)
+{
+	struct sigcontext context;
+	int err = 0;
+
+	/* get previous context */
+	if (copy_from_user(&context, usc, sizeof(context)))
+		goto badframe;
+	
+	/* restore passed registers */
+	regs->er1 = context.sc_er1;
+	regs->er2 = context.sc_er2;
+	regs->er3 = context.sc_er3;
+	regs->er5 = context.sc_er5;
+	regs->ccr = (regs->ccr & 0x10)|(context.sc_ccr & 0xef);
+	regs->pc = context.sc_pc;
+	regs->orig_er0 = -1;		/* disable syscall checks */
+	wrusp(context.sc_usp);
+
+	*pd0 = context.sc_er0;
+	return err;
+
+badframe:
+	return 1;
+}
+
+static inline int
+rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
+		    struct ucontext *uc, int *pd0)
+{
+	int temp;
+	greg_t *gregs = uc->uc_mcontext.gregs;
+	unsigned long usp;
+	int err;
+
+	err = __get_user(temp, &uc->uc_mcontext.version);
+	if (temp != MCONTEXT_VERSION)
+		goto badframe;
+	/* restore passed registers */
+	err |= __get_user(regs->er0, &gregs[0]);
+	err |= __get_user(regs->er1, &gregs[1]);
+	err |= __get_user(regs->er2, &gregs[2]);
+	err |= __get_user(regs->er3, &gregs[3]);
+	err |= __get_user(regs->er4, &gregs[4]);
+	err |= __get_user(regs->er5, &gregs[5]);
+	err |= __get_user(sw->er6, &gregs[6]);
+	err |= __get_user(usp, &gregs[7]);
+	wrusp(usp);
+	err |= __get_user(regs->pc, &gregs[8]);
+	err |= __get_user(temp, &gregs[9]);
+	regs->ccr = (regs->ccr & 0x10) | (temp & 0xef);
+	regs->orig_er0 = -1;		/* disable syscall checks */
+
+	if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
+		goto badframe;
+
+	*pd0 = regs->er0;
+	return err;
+
+badframe:
+	return 1;
+}
+
+asmlinkage int do_sigreturn(unsigned long __unused,...)
+{
+	struct switch_stack *sw = (struct switch_stack *) &__unused;
+	struct pt_regs *regs = (struct pt_regs *) (sw + 1);
+	unsigned long usp = rdusp();
+	struct sigframe *frame = (struct sigframe *)(usp - 4);
+	sigset_t set;
+	int er0;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
+	    (_NSIG_WORDS > 1 &&
+	     __copy_from_user(&set.sig[1], &frame->extramask,
+			      sizeof(frame->extramask))))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+	
+	if (restore_sigcontext(regs, &frame->sc, frame + 1, &er0))
+		goto badframe;
+	return er0;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int do_rt_sigreturn(unsigned long __unused,...)
+{
+	struct switch_stack *sw = (struct switch_stack *) &__unused;
+	struct pt_regs *regs = (struct pt_regs *) (sw + 1);
+	unsigned long usp = rdusp();
+	struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
+	sigset_t set;
+	int er0;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+	
+	if (rt_restore_ucontext(regs, sw, &frame->uc, &er0))
+		goto badframe;
+	return er0;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+			     unsigned long mask)
+{
+	sc->sc_mask = mask;
+	sc->sc_usp = rdusp();
+	sc->sc_er0 = regs->er0;
+	sc->sc_er1 = regs->er1;
+	sc->sc_er2 = regs->er2;
+	sc->sc_er3 = regs->er3;
+	sc->sc_er5 = regs->er5;
+	sc->sc_ccr = regs->ccr;
+	sc->sc_pc = regs->pc;
+}
+
+static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
+{
+	struct switch_stack *sw = (struct switch_stack *)regs - 1;
+	greg_t *gregs = uc->uc_mcontext.gregs;
+	int err = 0;
+
+	err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
+	err |= __put_user(regs->er0, &gregs[0]);
+	err |= __put_user(regs->er1, &gregs[1]);
+	err |= __put_user(regs->er2, &gregs[2]);
+	err |= __put_user(regs->er3, &gregs[3]);
+	err |= __put_user(regs->er4, &gregs[4]);
+	err |= __put_user(regs->er5, &gregs[5]);
+	err |= __put_user(sw->er6, &gregs[6]);
+	err |= __put_user(rdusp(), &gregs[7]);
+	err |= __put_user(regs->pc, &gregs[8]);
+	err |= __put_user(regs->ccr, &gregs[9]);
+	return err;
+}
+
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	unsigned long usp;
+
+	/* Default to using normal stack.  */
+	usp = rdusp();
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if (ka->sa.sa_flags & SA_ONSTACK) {
+		if (!on_sig_stack(usp))
+			usp = current->sas_ss_sp + current->sas_ss_size;
+	}
+	return (void *)((usp - frame_size) & -8UL);
+}
+
+static void setup_frame (int sig, struct k_sigaction *ka,
+			 sigset_t *set, struct pt_regs *regs)
+{
+	struct sigframe *frame;
+	struct sigcontext context;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (_NSIG_WORDS > 1)
+		err |= copy_to_user(frame->extramask, &set->sig[1],
+				    sizeof(frame->extramask));
+
+	setup_sigcontext(&context, regs, set->sig[0]);
+	err |= copy_to_user (&frame->sc, &context, sizeof(context));
+
+	/* Set up to return from userspace.  */
+	err |= __put_user(frame->retcode, &frame->pretcode);
+
+	/* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */
+	err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
+			(long *)(frame->retcode + 0));
+	err |= __put_user(0x5700, (short *)(frame->retcode + 4));
+
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up registers for signal handler */
+	wrusp ((unsigned long) frame);
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+
+	regs->er0 = (current->exec_domain
+		     && current->exec_domain->signal_invmap
+		     && sig < 32
+		     ? current->exec_domain->signal_invmap[sig]
+		     : sig);
+	regs->er1 = (unsigned long)frame->psc; /* secret second arg to signal handlers */
+	regs->er5 = (unsigned long)current->mm->start_data;   /* GOT base */
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
+			    sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	err |= __put_user(&frame->info, &frame->pinfo);
+	err |= __put_user(&frame->uc, &frame->puc);
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+			  &frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(rdusp()),
+			  &frame->uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= rt_setup_ucontext(&frame->uc, regs);
+	err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	/* Set up to return from userspace.  */
+	err |= __put_user(frame->retcode, &frame->pretcode);
+
+	/* moveq #,d0; notb d0; movea.l #,a5; trap #0 */
+	/* sub.l er0,er0; mov.b #__NR_rt_sigreturn,r0l; trapa #0 */
+	err != __put_user(0x1a80f800 + (__NR_rt_sigreturn & 0xff),
+			(long *)(frame->retcode + 0));
+	err |= __put_user(0x5700, (short *)(frame->retcode + 4));
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up registers for signal handler */
+	wrusp ((unsigned long) frame);
+	frame->dummy_handler = 0;
+
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+	regs->er0 = (current->exec_domain
+		     && current->exec_domain->signal_invmap
+		     && sig < 32
+		     ? current->exec_domain->signal_invmap[sig]
+		     : sig);
+	regs->er1 = (unsigned long)frame->pinfo;  /* second arg to sigaction and friends */
+	regs->er2 = (unsigned long)frame->puc;    /* third arg to sigaction and friends */
+	regs->er5 = (unsigned long)current->mm->start_data;   /* GOT base */
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static inline void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
+{
+	switch (regs->er0) {
+	case -ERESTARTNOHAND:
+		if (!has_handler)
+			goto do_restart;
+		regs->er0 = -EINTR;
+		break;
+
+	case -ERESTARTSYS:
+		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
+			regs->er0 = -EINTR;
+			break;
+		}
+	/* fallthrough */
+	case -ERESTARTNOINTR:
+	do_restart:
+		regs->er0 = regs->orig_er0;
+		regs->pc -= 2;
+		break;
+	}
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static void
+handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
+	      sigset_t *oldset, struct pt_regs *regs)
+{
+	/* are we from a system call? */
+	if (regs->orig_er0 >= 0)
+		/* If so, check system call restarting.. */
+		handle_restart(regs, ka, 1);
+
+	/* set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sigmask_lock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending(current);
+		spin_lock_irq(&current->sigmask_lock);
+	}
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals
+ * that the kernel can handle, and then we build all the user-level signal
+ * handling stack-frames in one go after that.
+ */
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
+{
+	siginfo_t info;
+	struct k_sigaction *ka;
+
+	current->thread.esp0 = (unsigned long) regs;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	for (;;) {
+		int signr;
+
+		spin_lock_irq(&current->sigmask_lock);
+		signr = dequeue_signal(&current->blocked, &info);
+		spin_unlock_irq(&current->sigmask_lock);
+
+		if (!signr)
+			break;
+
+		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+
+			/* DAVIDM do we need to clear trace bit in CCR */
+
+			/* Did we come from a system call? */
+			if (regs->orig_er0 >= 0) {
+				/* Restart the system call the same way as
+				   if the process were not traced.  */
+				struct k_sigaction *ka =
+					&current->sig->action[signr-1];
+				int has_handler =
+					(ka->sa.sa_handler != SIG_IGN &&
+					 ka->sa.sa_handler != SIG_DFL);
+				handle_restart(regs, ka, has_handler);
+			}
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code)) {
+			discard_frame:
+			    continue;
+			}
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				goto discard_frame;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD:
+			case SIGWINCH: case SIGURG:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP: {
+				struct signal_struct *sig;
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+                                sig = current->p_pptr->sig;
+                                if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags 
+& SA_NOCLDSTOP))
+                                        notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+			}
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGIOT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				sig_exit(signr, exit_code, &info);
+				/* NOTREACHED */
+			}
+		}
+
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(signr, ka, &info, oldset, regs);
+		return 1;
+	}
+
+	/* Did we come from a system call? */
+	if (regs->orig_er0 >= 0)
+		/* Restart the system call - no handlers present */
+		handle_restart(regs, NULL, 0);
+
+	return 0;
+}
diff -urN linux-2.4.29/arch/h8300/kernel/syscalls.S linux-2.4.29-uc1/arch/h8300/kernel/syscalls.S
--- linux-2.4.29/arch/h8300/kernel/syscalls.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/kernel/syscalls.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,310 @@
+/* Systemcall Entry Table */
+#include <linux/config.h>
+#include <linux/sys.h>
+#include <asm/linkage.h>
+
+.globl SYMBOL_NAME(sys_call_table)
+
+#if defined(CONFIG_CPU_H8300H)
+	.h8300h
+#endif
+#if defined(CONFIG_CPU_H8S)
+	.h8300s
+#endif
+	.section .text
+	.align	2
+SYMBOL_NAME_LABEL(sys_call_table)	
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 0  -  old "setup()" system call*/
+	.long SYMBOL_NAME(sys_exit)
+	.long SYMBOL_NAME(sys_fork)
+	.long SYMBOL_NAME(sys_read)
+	.long SYMBOL_NAME(sys_write)
+	.long SYMBOL_NAME(sys_open)		/* 5 */
+	.long SYMBOL_NAME(sys_close)
+	.long SYMBOL_NAME(sys_waitpid)
+	.long SYMBOL_NAME(sys_creat)
+	.long SYMBOL_NAME(sys_link)
+	.long SYMBOL_NAME(sys_unlink)		/* 10 */
+	.long SYMBOL_NAME(sys_execve)
+	.long SYMBOL_NAME(sys_chdir)
+	.long SYMBOL_NAME(sys_time)
+	.long SYMBOL_NAME(sys_mknod)
+	.long SYMBOL_NAME(sys_chmod)		/* 15 */
+	.long SYMBOL_NAME(sys_chown16)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old break syscall holder */
+	.long SYMBOL_NAME(sys_stat)
+	.long SYMBOL_NAME(sys_lseek)
+	.long SYMBOL_NAME(sys_getpid)		/* 20 */
+	.long SYMBOL_NAME(sys_mount)
+	.long SYMBOL_NAME(sys_oldumount)
+	.long SYMBOL_NAME(sys_setuid16)
+	.long SYMBOL_NAME(sys_getuid16)
+	.long SYMBOL_NAME(sys_stime)		/* 25 */
+	.long SYMBOL_NAME(sys_ptrace)
+	.long SYMBOL_NAME(sys_alarm)
+	.long SYMBOL_NAME(sys_fstat)
+	.long SYMBOL_NAME(sys_pause)
+	.long SYMBOL_NAME(sys_utime)		/* 30 */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old stty syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old gtty syscall holder */
+	.long SYMBOL_NAME(sys_access)
+	.long SYMBOL_NAME(sys_nice)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 35 */		/* old ftime syscall holder */
+	.long SYMBOL_NAME(sys_sync)
+	.long SYMBOL_NAME(sys_kill)
+	.long SYMBOL_NAME(sys_rename)
+	.long SYMBOL_NAME(sys_mkdir)
+	.long SYMBOL_NAME(sys_rmdir)		/* 40 */
+	.long SYMBOL_NAME(sys_dup)
+	.long SYMBOL_NAME(sys_pipe)
+	.long SYMBOL_NAME(sys_times)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old prof syscall holder */
+	.long SYMBOL_NAME(sys_brk)		/* 45 */
+	.long SYMBOL_NAME(sys_setgid16)
+	.long SYMBOL_NAME(sys_getgid16)
+	.long SYMBOL_NAME(sys_signal)
+	.long SYMBOL_NAME(sys_geteuid16)
+	.long SYMBOL_NAME(sys_getegid16)	/* 50 */
+	.long SYMBOL_NAME(sys_acct)
+	.long SYMBOL_NAME(sys_umount)					/* recycled never used phys() */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old lock syscall holder */
+	.long SYMBOL_NAME(sys_ioctl)
+	.long SYMBOL_NAME(sys_fcntl)		/* 55 */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old mpx syscall holder */
+	.long SYMBOL_NAME(sys_setpgid)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old ulimit syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_umask)		/* 60 */
+	.long SYMBOL_NAME(sys_chroot)
+	.long SYMBOL_NAME(sys_ustat)
+	.long SYMBOL_NAME(sys_dup2)
+	.long SYMBOL_NAME(sys_getppid)
+	.long SYMBOL_NAME(sys_getpgrp)		/* 65 */
+	.long SYMBOL_NAME(sys_setsid)
+	.long SYMBOL_NAME(sys_sigaction)
+	.long SYMBOL_NAME(sys_sgetmask)
+	.long SYMBOL_NAME(sys_ssetmask)
+	.long SYMBOL_NAME(sys_setreuid16)	/* 70 */
+	.long SYMBOL_NAME(sys_setregid16)
+	.long SYMBOL_NAME(sys_sigsuspend)
+	.long SYMBOL_NAME(sys_sigpending)
+	.long SYMBOL_NAME(sys_sethostname)
+	.long SYMBOL_NAME(sys_setrlimit)	/* 75 */
+	.long SYMBOL_NAME(sys_old_getrlimit)
+	.long SYMBOL_NAME(sys_getrusage)
+	.long SYMBOL_NAME(sys_gettimeofday)
+	.long SYMBOL_NAME(sys_settimeofday)
+	.long SYMBOL_NAME(sys_getgroups16)	/* 80 */
+	.long SYMBOL_NAME(sys_setgroups16)
+	.long SYMBOL_NAME(old_select)
+	.long SYMBOL_NAME(sys_symlink)
+	.long SYMBOL_NAME(sys_lstat)
+	.long SYMBOL_NAME(sys_readlink)		/* 85 */
+	.long SYMBOL_NAME(sys_uselib)
+	.long SYMBOL_NAME(sys_swapon)
+	.long SYMBOL_NAME(sys_reboot)
+	.long SYMBOL_NAME(old_readdir)
+	.long SYMBOL_NAME(old_mmap)		/* 90 */
+	.long SYMBOL_NAME(sys_munmap)
+	.long SYMBOL_NAME(sys_truncate)
+	.long SYMBOL_NAME(sys_ftruncate)
+	.long SYMBOL_NAME(sys_fchmod)
+	.long SYMBOL_NAME(sys_fchown16)		/* 95 */
+	.long SYMBOL_NAME(sys_getpriority)
+	.long SYMBOL_NAME(sys_setpriority)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old profil syscall holder */
+	.long SYMBOL_NAME(sys_statfs)
+	.long SYMBOL_NAME(sys_fstatfs)		/* 100 */
+	.long SYMBOL_NAME(sys_ioperm)
+	.long SYMBOL_NAME(sys_socketcall)
+	.long SYMBOL_NAME(sys_syslog)
+	.long SYMBOL_NAME(sys_setitimer)
+	.long SYMBOL_NAME(sys_getitimer)	/* 105 */
+	.long SYMBOL_NAME(sys_newstat)
+	.long SYMBOL_NAME(sys_newlstat)
+	.long SYMBOL_NAME(sys_newfstat)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* iopl for i386 */ /* 110 */
+	.long SYMBOL_NAME(sys_vhangup)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* obsolete idle() syscall */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* vm86old for i386 */
+	.long SYMBOL_NAME(sys_wait4)
+	.long SYMBOL_NAME(sys_swapoff)		/* 115 */
+	.long SYMBOL_NAME(sys_sysinfo)
+	.long SYMBOL_NAME(sys_ipc)
+	.long SYMBOL_NAME(sys_fsync)
+	.long SYMBOL_NAME(sys_sigreturn)
+	.long SYMBOL_NAME(sys_clone)		/* 120 */
+	.long SYMBOL_NAME(sys_setdomainname)
+	.long SYMBOL_NAME(sys_newuname)
+	.long SYMBOL_NAME(sys_cacheflush)	/* modify_ldt for i386 */
+	.long SYMBOL_NAME(sys_adjtimex)
+	.long SYMBOL_NAME(sys_mprotect)		/* 125 */
+	.long SYMBOL_NAME(sys_sigprocmask)
+	.long SYMBOL_NAME(sys_create_module)
+	.long SYMBOL_NAME(sys_init_module)
+	.long SYMBOL_NAME(sys_delete_module)
+	.long SYMBOL_NAME(sys_get_kernel_syms)	/* 130 */
+	.long SYMBOL_NAME(sys_quotactl)
+	.long SYMBOL_NAME(sys_getpgid)
+	.long SYMBOL_NAME(sys_fchdir)
+	.long SYMBOL_NAME(sys_bdflush)
+	.long SYMBOL_NAME(sys_sysfs)		/* 135 */
+	.long SYMBOL_NAME(sys_personality)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for afs_syscall */
+	.long SYMBOL_NAME(sys_setfsuid16)
+	.long SYMBOL_NAME(sys_setfsgid16)
+	.long SYMBOL_NAME(sys_llseek)		/* 140 */
+	.long SYMBOL_NAME(sys_getdents)
+	.long SYMBOL_NAME(sys_select)
+	.long SYMBOL_NAME(sys_flock)
+	.long SYMBOL_NAME(sys_msync)
+	.long SYMBOL_NAME(sys_readv)		/* 145 */
+	.long SYMBOL_NAME(sys_writev)
+	.long SYMBOL_NAME(sys_getsid)
+	.long SYMBOL_NAME(sys_fdatasync)
+	.long SYMBOL_NAME(sys_sysctl)
+	.long SYMBOL_NAME(sys_mlock)		/* 150 */
+	.long SYMBOL_NAME(sys_munlock)
+	.long SYMBOL_NAME(sys_mlockall)
+	.long SYMBOL_NAME(sys_munlockall)
+	.long SYMBOL_NAME(sys_sched_setparam)
+	.long SYMBOL_NAME(sys_sched_getparam)   /* 155 */
+	.long SYMBOL_NAME(sys_sched_setscheduler)
+	.long SYMBOL_NAME(sys_sched_getscheduler)
+	.long SYMBOL_NAME(sys_sched_yield)
+	.long SYMBOL_NAME(sys_sched_get_priority_max)
+	.long SYMBOL_NAME(sys_sched_get_priority_min)  /* 160 */
+	.long SYMBOL_NAME(sys_sched_rr_get_interval)
+	.long SYMBOL_NAME(sys_nanosleep)
+	.long SYMBOL_NAME(sys_mremap)
+	.long SYMBOL_NAME(sys_setresuid16)
+	.long SYMBOL_NAME(sys_getresuid16)	/* 165 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for vm86 */
+	.long SYMBOL_NAME(sys_query_module)
+	.long SYMBOL_NAME(sys_poll)
+	.long SYMBOL_NAME(sys_nfsservctl)
+	.long SYMBOL_NAME(sys_setresgid16)	/* 170 */
+	.long SYMBOL_NAME(sys_getresgid16)
+	.long SYMBOL_NAME(sys_prctl)
+	.long SYMBOL_NAME(sys_rt_sigreturn)
+	.long SYMBOL_NAME(sys_rt_sigaction)
+	.long SYMBOL_NAME(sys_rt_sigprocmask)	/* 175 */
+	.long SYMBOL_NAME(sys_rt_sigpending)
+	.long SYMBOL_NAME(sys_rt_sigtimedwait)
+	.long SYMBOL_NAME(sys_rt_sigqueueinfo)
+	.long SYMBOL_NAME(sys_rt_sigsuspend)
+	.long SYMBOL_NAME(sys_pread)		/* 180 */
+	.long SYMBOL_NAME(sys_pwrite)
+	.long SYMBOL_NAME(sys_lchown16);
+	.long SYMBOL_NAME(sys_getcwd)
+	.long SYMBOL_NAME(sys_capget)
+	.long SYMBOL_NAME(sys_capset)           /* 185 */
+	.long SYMBOL_NAME(sys_sigaltstack)
+	.long SYMBOL_NAME(sys_sendfile)
+	.long SYMBOL_NAME(sys_ni_syscall)		/* streams1 */
+	.long SYMBOL_NAME(sys_ni_syscall)		/* streams2 */
+	.long SYMBOL_NAME(sys_vfork)            /* 190 */
+	.long SYMBOL_NAME(sys_getrlimit)
+	.long SYMBOL_NAME(sys_mmap2)
+	.long SYMBOL_NAME(sys_truncate64)
+	.long SYMBOL_NAME(sys_ftruncate64)
+	.long SYMBOL_NAME(sys_stat64)		/* 195 */
+	.long SYMBOL_NAME(sys_lstat64)
+	.long SYMBOL_NAME(sys_fstat64)
+	.long SYMBOL_NAME(sys_chown)
+	.long SYMBOL_NAME(sys_getuid)
+	.long SYMBOL_NAME(sys_getgid)		/* 200 */
+	.long SYMBOL_NAME(sys_geteuid)
+	.long SYMBOL_NAME(sys_getegid)
+	.long SYMBOL_NAME(sys_setreuid)
+	.long SYMBOL_NAME(sys_setregid)
+	.long SYMBOL_NAME(sys_getgroups)	/* 205 */
+	.long SYMBOL_NAME(sys_setgroups)
+	.long SYMBOL_NAME(sys_fchown)
+	.long SYMBOL_NAME(sys_setresuid)
+	.long SYMBOL_NAME(sys_getresuid)
+	.long SYMBOL_NAME(sys_setresgid)	/* 210 */
+	.long SYMBOL_NAME(sys_getresgid)
+	.long SYMBOL_NAME(sys_lchown)
+	.long SYMBOL_NAME(sys_setuid)
+	.long SYMBOL_NAME(sys_setgid)
+	.long SYMBOL_NAME(sys_setfsuid)		/* 215 */
+	.long SYMBOL_NAME(sys_setfsgid)
+	.long SYMBOL_NAME(sys_pivot_root)
+	.long SYMBOL_NAME(sys_mincore)
+	.long SYMBOL_NAME(sys_madvise)
+	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
+	.long SYMBOL_NAME(sys_gettid)
+	.long SYMBOL_NAME(sys_tkill)
+	.long SYMBOL_NAME(sys_fcntl64)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for TUX */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* Reserved for Security */
+	.long SYMBOL_NAME(sys_gettid)
+	.long SYMBOL_NAME(sys_readahead)	/* 225 */
+	.long SYMBOL_NAME(sys_setxattr)
+	.long SYMBOL_NAME(sys_lsetxattr)
+	.long SYMBOL_NAME(sys_fsetxattr)
+	.long SYMBOL_NAME(sys_getxattr)
+	.long SYMBOL_NAME(sys_lgetxattr)	/* 230 */
+	.long SYMBOL_NAME(sys_fgetxattr)
+	.long SYMBOL_NAME(sys_listxattr)
+	.long SYMBOL_NAME(sys_llistxattr)
+	.long SYMBOL_NAME(sys_flistxattr)
+	.long SYMBOL_NAME(sys_removexattr)	/* 235 */
+	.long SYMBOL_NAME(sys_lremovexattr)
+	.long SYMBOL_NAME(sys_fremovexattr)
+ 	.long SYMBOL_NAME(sys_tkill)
+	.long SYMBOL_NAME(sys_sendfile64)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 240 reserved for futex */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for sched_setaffinity */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for sched_getaffinity */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_set_thread_area */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_get_thread_area */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 245 sys_io_setup */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_io_destroy */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_io_getevents */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_io_submit */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_io_cancel */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 250 sys_alloc_hugepages */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_free_hugepages */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_exit_group */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_lookup_dcookie */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_epoll_create */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_epoll_ctl 255 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_epoll_wait */
+ 	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_remap_file_pages */
+ 	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_set_tid_address */
+
+	.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
+		.long SYMBOL_NAME(sys_ni_syscall)
+	.endr
+
+SYMBOL_NAME_LABEL(sys_clone)
+	mov.l	#SYMBOL_NAME(h8300_clone),er0
+	jmp	@SYMBOL_NAME(syscall_trampoline)
+	
+SYMBOL_NAME_LABEL(sys_sigsuspend)
+	mov.l	#SYMBOL_NAME(do_sigsuspend),er0
+	jmp	@SYMBOL_NAME(syscall_trampoline)
+
+SYMBOL_NAME_LABEL(sys_rt_sigsuspend)
+	mov.l	#SYMBOL_NAME(do_rt_sigsuspend),er0
+	jmp	@SYMBOL_NAME(syscall_trampoline)
+
+SYMBOL_NAME_LABEL(sys_sigreturn)
+	mov.l	#SYMBOL_NAME(do_sigreturn),er0
+	jmp	@SYMBOL_NAME(syscall_trampoline)
+
+SYMBOL_NAME_LABEL(sys_rt_sigreturn)
+	mov.l	#SYMBOL_NAME(do_rt_sigreturn),er0
+	jmp	@SYMBOL_NAME(syscall_trampoline)
+
+SYMBOL_NAME_LABEL(sys_fork)
+	mov.l	#SYMBOL_NAME(h8300_fork),er0
+	jmp	@SYMBOL_NAME(syscall_trampoline)
+
+SYMBOL_NAME_LABEL(sys_vfork)
+	mov.l	#SYMBOL_NAME(h8300_vfork),er0
+	jmp	@SYMBOL_NAME(syscall_trampoline)
+
diff -urN linux-2.4.29/arch/h8300/kernel/sys_h8300.c linux-2.4.29-uc1/arch/h8300/kernel/sys_h8300.c
--- linux-2.4.29/arch/h8300/kernel/sys_h8300.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/kernel/sys_h8300.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,303 @@
+/*
+ * linux/arch/h8300/kernel/sys_h8300.c
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the H8/300
+ * platform.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/cachectl.h>
+#include <asm/ipc.h>
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+asmlinkage int sys_pipe(unsigned long * fildes)
+{
+	int fd[2];
+	int error;
+
+	error = do_pipe(fd);
+	if (!error) {
+		if (copy_to_user(fildes, fd, 2*sizeof(int)))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+/* common code for old and new mmaps */
+static inline long do_mmap2(
+	unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	int error = -EBADF;
+	struct file * file = NULL;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (!(flags & MAP_ANONYMOUS)) {
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
+/*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
+ * handle more than 4 system call parameters, so these system calls
+ * used a memory block for parameter passing..
+ */
+
+struct mmap_arg_struct {
+	unsigned long addr;
+	unsigned long len;
+	unsigned long prot;
+	unsigned long flags;
+	unsigned long fd;
+	unsigned long offset;
+};
+
+asmlinkage int old_mmap(struct mmap_arg_struct *arg)
+{
+	struct mmap_arg_struct a;
+	int error = -EFAULT;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		goto out;
+
+	error = -EINVAL;
+	if (a.offset & ~PAGE_MASK)
+		goto out;
+
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+out:
+	return error;
+}
+
+#if 0 /* DAVIDM - do we want this */
+struct mmap_arg_struct64 {
+	__u32 addr;
+	__u32 len;
+	__u32 prot;
+	__u32 flags;
+	__u64 offset; /* 64 bits */
+	__u32 fd;
+};
+
+asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
+{
+	int error = -EFAULT;
+	struct file * file = NULL;
+	struct mmap_arg_struct64 a;
+	unsigned long pgoff;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+
+	if ((long)a.offset & ~PAGE_MASK)
+		return -EINVAL;
+
+	pgoff = a.offset >> PAGE_SHIFT;
+	if ((a.offset >> PAGE_SHIFT) != pgoff)
+		return -EINVAL;
+
+	if (!(a.flags & MAP_ANONYMOUS)) {
+		error = -EBADF;
+		file = fget(a.fd);
+		if (!file)
+			goto out;
+	}
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+#endif
+
+extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+
+struct sel_arg_struct {
+	unsigned long n;
+	fd_set *inp, *outp, *exp;
+	struct timeval *tvp;
+};
+
+asmlinkage int old_select(struct sel_arg_struct *arg)
+{
+	struct sel_arg_struct a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+	/* sys_select() does the appropriate kernel locking */
+	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
+}
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+asmlinkage int sys_ipc (uint call, int first, int second,
+			int third, void *ptr, long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	if (call <= SEMCTL)
+		switch (call) {
+		case SEMOP:
+			return sys_semop (first, (struct sembuf *)ptr, second);
+		case SEMGET:
+			return sys_semget (first, second, third);
+		case SEMCTL: {
+			union semun fourth;
+			if (!ptr)
+				return -EINVAL;
+			if (get_user(fourth.__pad, (void **) ptr))
+				return -EFAULT;
+			return sys_semctl (first, second, third, fourth);
+			}
+		default:
+			return -EINVAL;
+		}
+	if (call <= MSGCTL) 
+		switch (call) {
+		case MSGSND:
+			return sys_msgsnd (first, (struct msgbuf *) ptr, 
+					  second, third);
+		case MSGRCV:
+			switch (version) {
+			case 0: {
+				struct ipc_kludge tmp;
+				if (!ptr)
+					return -EINVAL;
+				if (copy_from_user (&tmp,
+						    (struct ipc_kludge *)ptr,
+						    sizeof (tmp)))
+					return -EFAULT;
+				return sys_msgrcv (first, tmp.msgp, second,
+						   tmp.msgtyp, third);
+				}
+			default:
+				return sys_msgrcv (first,
+						   (struct msgbuf *) ptr,
+						   second, fifth, third);
+			}
+		case MSGGET:
+			return sys_msgget ((key_t) first, second);
+		case MSGCTL:
+			return sys_msgctl (first, second,
+					   (struct msqid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+	if (call <= SHMCTL) 
+		switch (call) {
+		case SHMAT:
+			switch (version) {
+			default: {
+				ulong raddr;
+				ret = sys_shmat (first, (char *) ptr,
+						 second, &raddr);
+				if (ret)
+					return ret;
+				return put_user (raddr, (ulong *) third);
+			}
+			}
+		case SHMDT: 
+			return sys_shmdt ((char *)ptr);
+		case SHMGET:
+			return sys_shmget (first, second, third);
+		case SHMCTL:
+			return sys_shmctl (first, second,
+					   (struct shmid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+
+	return -EINVAL;
+}
+
+asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
+{
+  return -ENOSYS;
+}
+
+/* sys_cacheflush -- no support.  */
+asmlinkage int
+sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
+{
+	return -EINVAL;
+}
+
+asmlinkage int sys_getpagesize(void)
+{
+	return PAGE_SIZE;
+}
+
+/*
+ * Old cruft
+ */
+asmlinkage int sys_pause(void)
+{
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	return -ERESTARTNOHAND;
+}
+
+#if defined(CONFIG_SYSCALL_PRINT)
+asmlinkage void syscall_print(void *dummy,...)
+{
+	struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy);
+#if defined(__H8300H__)
+	unsigned long *usp=rdusp()+8;
+#endif
+#if defined(__H8300S__)
+	unsigned long *usp=rdusp()+10;
+#endif
+	printk("call %06x:%d 1:%08x,2:%08x,3:%08x,ret:%08x\n",
+               ((*usp) & 0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0);
+}
+#endif
diff -urN linux-2.4.29/arch/h8300/kernel/time.c linux-2.4.29-uc1/arch/h8300/kernel/time.c
--- linux-2.4.29/arch/h8300/kernel/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/kernel/time.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,161 @@
+/*
+ *  linux/arch/h8300/kernel/time.c
+ *
+ *  Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ *  Copied/hacked from:
+ *
+ *  linux/arch/m68k/kernel/time.c
+ *
+ *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *
+ * This file contains the m68k-specific time handling details.
+ * Most of the stuff is located in the machine specific files.
+ *
+ * 1997-09-10	Updated NTP code according to technical memorandum Jan '96
+ *		"A Kernel Model for Precision Timekeeping" by Dave Mills
+ */
+
+#include <linux/config.h> /* CONFIG_HEARTBEAT */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/target_time.h>
+
+#include <linux/timex.h>
+
+#if defined(CONFIG_PROFILE)
+static inline void do_profile (unsigned long pc)
+{
+	if (prof_buffer && current->pid) {
+		extern int _stext;
+		pc -= (unsigned long) &_stext;
+		pc >>= prof_shift;
+		if (pc < prof_len)
+			++prof_buffer[pc];
+		else
+		/*
+		 * Don't ignore out-of-bounds PC values silently,
+		 * put them into the last histogram slot, so if
+		 * present, they will show up as a sharp peak.
+		 */
+			++prof_buffer[prof_len-1];
+	}
+}
+#endif
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
+{
+#if defined(CONFIG_SYNC_RTC)
+	/* last time the cmos clock got updated */
+	static long last_rtc_update=0;
+#endif
+
+	/* may need to kick the hardware timer */
+	platform_timer_eoi();
+
+	do_timer(regs);
+
+#if defined(CONFIG_PROFILE)
+	if (!user_mode(regs))
+		do_profile(regs->pc);
+#endif
+
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+#if defined(CONFIG_SYNC_RTC)
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
+	    xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
+	  if (platform_set_rtc(xtime.tv_sec) == 0)
+	    last_rtc_update = xtime.tv_sec;
+	  else
+	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	}
+#endif
+}
+
+void time_init(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+
+	/* FIX by dqg : Set to zero for platforms that don't have tod */
+	/* without this time is undefined and can overflow time_t, causing  */
+	/* very stange errors */
+	year = 1980;
+	mon = day = 1;
+	hour = min = sec = 0;
+	platform_gettod (&year, &mon, &day, &hour, &min, &sec);
+
+	if ((year += 1900) < 1970)
+		year += 100;
+	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+	xtime.tv_usec = 0;
+
+	platform_timer_setup(timer_interrupt);
+}
+
+extern rwlock_t xtime_lock;
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+	extern volatile unsigned long wall_jiffies;
+	unsigned long flags;
+	unsigned long usec, sec, lost;
+
+	read_lock_irqsave(&xtime_lock, flags);
+	usec = platform_get_usec();
+	lost = jiffies - wall_jiffies;
+	if (lost)
+		usec += lost * (1000000/HZ);
+	sec = xtime.tv_sec;
+	usec += xtime.tv_usec;
+	read_unlock_irqrestore(&xtime_lock, flags);
+
+	while (usec >= 1000000) {
+		usec -= 1000000;
+		sec++;
+	}
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	write_lock_irq(&xtime_lock);
+	/* This is revolting. We need to set the xtime.tv_usec
+	 * correctly. However, the value in this location is
+	 * is value at the last tick.
+	 * Discover what correction gettimeofday
+	 * would have done, and then undo it!
+	 */
+
+	while (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+
+	xtime = *tv;
+	time_adjust = 0;		/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+	write_unlock_irq(&xtime_lock);
+}
diff -urN linux-2.4.29/arch/h8300/kernel/traps.c linux-2.4.29-uc1/arch/h8300/kernel/traps.c
--- linux-2.4.29/arch/h8300/kernel/traps.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/kernel/traps.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,123 @@
+/*
+ * linux/arch/h8300/boot/traps.c -- general exception handling code
+ * H8/300 support Yoshinori Sato <ysato@users.sourceforge.jp>
+ * 
+ * Cloned from Linux/m68k.
+ *
+ * No original Copyright holder listed,
+ * Probabily original (C) Roman Zippel (assigned DJD, 1999)
+ *
+ * Copyright 1999-2000 D. Jeff Dionne, <jeff@uClinux.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/gpio.h>
+
+/*
+ * this must be called very early as the kernel might
+ * use some instruction that are emulated on the 060
+ */
+
+void __init base_trap_init(void)
+{
+}
+
+void __init trap_init (void)
+{
+}
+
+asmlinkage void set_esp0 (unsigned long ssp)
+{
+  current->thread.esp0 = ssp;
+}
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+
+static void dump(struct pt_regs *fp)
+{
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk("\nCURRENT PROCESS:\n\n");
+#if 0
+{
+	extern int	swt_lastjiffies, swt_reference;
+	printk("WATCHDOG: jiffies=%d lastjiffies=%d [%d] reference=%d\n",
+		jiffies, swt_lastjiffies, (swt_lastjiffies - jiffies),
+		swt_reference);
+}
+#endif
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
+			(int) current->mm->start_stack,
+			(int) (PAGE_SIZE+current));
+	}
+
+	printk("PC: %08lx\n", (long)fp->pc);
+	printk("CCR: %02x   SP: %08lx\n", fp->ccr, (unsigned long) fp);
+	printk("ER0: %08lx  ER1: %08lx   ER2: %08lx   ER3: %08lx\n",
+		fp->er0, fp->er1, fp->er2, fp->er3);
+	printk("\nCODE:");
+	tp = ((unsigned char *) fp->pc) - 0x20;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+	if (STACK_MAGIC != *(unsigned long *)((unsigned long)current+PAGE_SIZE))
+                printk("(Possibly corrupted stack page\?\?)\n");
+
+	printk("\n\n");
+}
+
+void show_trace_task(struct task_struct *tsk)
+{
+	/* DAVIDM: we can do better, need a proper stack dump */
+	printk("STACK ksp=0x%lx, usp=0x%lx\n", tsk->thread.ksp, tsk->thread.usp);
+}
+
+void die_if_kernel (char *str, struct pt_regs *fp, int nr)
+{
+	extern int console_loglevel;
+
+	if (!(fp->ccr & PS_S))
+		return;
+
+	console_loglevel = 15;
+	dump(fp);
+
+	do_exit(SIGSEGV);
+}
diff -urN linux-2.4.29/arch/h8300/lib/ashrdi3.c linux-2.4.29-uc1/arch/h8300/lib/ashrdi3.c
--- linux-2.4.29/arch/h8300/lib/ashrdi3.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/lib/ashrdi3.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,63 @@
+/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define BITS_PER_UNIT 8
+
+typedef 	 int SItype	__attribute__ ((mode (SI)));
+typedef unsigned int USItype	__attribute__ ((mode (SI)));
+typedef		 int DItype	__attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
+DItype
+__ashrdi3 (DItype u, word_type b)
+{
+  DIunion w;
+  word_type bm;
+  DIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ll = u;
+
+  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      /* w.s.high = 1..1 or 0..0 */
+      w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
+      w.s.low = uu.s.high >> -bm;
+    }
+  else
+    {
+      USItype carries = (USItype)uu.s.high << bm;
+      w.s.high = uu.s.high >> b;
+      w.s.low = ((USItype)uu.s.low >> b) | carries;
+    }
+
+  return w.ll;
+}
diff -urN linux-2.4.29/arch/h8300/lib/checksum.c linux-2.4.29-uc1/arch/h8300/lib/checksum.c
--- linux-2.4.29/arch/h8300/lib/checksum.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/lib/checksum.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,156 @@
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		IP/TCP/UDP checksumming routines
+ *
+ * Authors:	Jorge Cwik, <jorge@laser.satlink.net>
+ *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ *		Tom May, <ftom@netcom.com>
+ *		Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
+ *		Lots of code moved from tcp.c and ip.c; see those files
+ *		for more names.
+ *
+ * 03/02/96	Jes Sorensen, Andreas Schwab, Roman Hodek:
+ *		Fixed some nasty bugs, causing some horrible crashes.
+ *		A: At some points, the sum (%0) was used as
+ *		length-counter instead of the length counter
+ *		(%1). Thanks to Roman Hodek for pointing this out.
+ *		B: GCC seems to mess up if one uses too many
+ *		data-registers to hold input values and one tries to
+ *		specify d0 and d1 as scratch registers. Letting gcc choose these
+ *      registers itself solves the problem.
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+ 
+/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most
+   of the assembly has to go. */
+
+#include <net/checksum.h>
+
+static inline unsigned short from32to16(unsigned long x)
+{
+	/* add up 16-bit and 16-bit for 16+c bit */
+	x = (x & 0xffff) + (x >> 16);
+	/* add up carry.. */
+	x = (x & 0xffff) + (x >> 16);
+	return x;
+}
+
+static unsigned long do_csum(const unsigned char * buff, int len)
+{
+	int odd, count;
+	unsigned long result = 0;
+
+	if (len <= 0)
+		goto out;
+	odd = 1 & (unsigned long) buff;
+	if (odd) {
+		result = *buff;
+		len--;
+		buff++;
+	}
+	count = len >> 1;		/* nr of 16-bit words.. */
+	if (count) {
+		if (2 & (unsigned long) buff) {
+			result += *(unsigned short *) buff;
+			count--;
+			len -= 2;
+			buff += 2;
+		}
+		count >>= 1;		/* nr of 32-bit words.. */
+		if (count) {
+		        unsigned long carry = 0;
+			do {
+				unsigned long w = *(unsigned long *) buff;
+				count--;
+				buff += 4;
+				result += carry;
+				result += w;
+				carry = (w > result);
+			} while (count);
+			result += carry;
+			result = (result & 0xffff) + (result >> 16);
+		}
+		if (len & 2) {
+			result += *(unsigned short *) buff;
+			buff += 2;
+		}
+	}
+	if (len & 1)
+		result += (*buff << 8);
+	result = from32to16(result);
+	if (odd)
+		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+	return result;
+}
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ */
+unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
+{
+	return ~do_csum(iph,ihl*4);
+}
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
+{
+	unsigned int result = do_csum(buff, len);
+
+	/* add in old sum, and carry.. */
+	result += sum;
+	/* 16+c bits -> 16 bits */
+	result = (result & 0xffff) + (result >> 16);
+	return result;
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+unsigned short ip_compute_csum(const unsigned char * buff, int len)
+{
+	return ~do_csum(buff,len);
+}
+
+/*
+ * copy from fs while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err)
+{
+	if (csum_err) *csum_err = 0;
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
+
+/*
+ * copy from ds while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy(const char *src, char *dst, int len, int sum)
+{
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
diff -urN linux-2.4.29/arch/h8300/lib/Makefile linux-2.4.29-uc1/arch/h8300/lib/Makefile
--- linux-2.4.29/arch/h8300/lib/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/lib/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,11 @@
+#
+# Makefile for H8/300-specific library files..
+#
+
+.S.o:
+	$(CC) $(AFLAGS) -D__ASSEMBLY__ -c $< -o $@
+
+L_TARGET = lib.a
+obj-y  = ashrdi3.o checksum.o memcpy.o memset.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/h8300/lib/memcpy.S linux-2.4.29-uc1/arch/h8300/lib/memcpy.S
--- linux-2.4.29/arch/h8300/lib/memcpy.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/lib/memcpy.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,91 @@
+;;; memcpy.S
+
+#include <asm/linkage.h>
+#include <linux/config.h>
+	
+#if defined(__H8300H__) 
+	.h8300h
+#include <asm/regs306x.h>
+#endif
+#if defined(__H8300S__) 
+	.h8300s
+#endif
+
+#define DMAC_THRESHOLD 16
+	
+	.text
+.global SYMBOL_NAME(memcpy)
+
+;;; void *memcpy(void *to, void *from, size_t n)
+SYMBOL_NAME_LABEL(memcpy)
+	mov.l	er2,er2
+	bne	1f
+	rts	
+1:
+#if defined(__H8300H__) && defined(CONFIG_H8300_DMAMEMCPY)
+	cmp.l	#DMAC_THRESHOLD,er2
+	bcs	10f
+	;; use DMAC transfer
+	mov.l	#0x1016,er3	; byte burst
+	bld	#0,r0l
+	bxor	#0,r1l
+	bcs	3f		; non word alignment to byte transfer
+
+	bld	#0,r0l
+	bor	#0,r1l
+	bcc	1f		; even alignment
+
+	mov.b	@er1,r3l	; odd 1byte transfer
+	mov.b	r3l,@er0	; r3l sets it again later
+	adds	#1,er0
+	adds	#1,er1
+	subs	#1,er2
+		
+1:		
+	btst	#0,r2l		; odd size?
+	beq	2f
+	inc.w	#1,e3		; yes
+2:	
+	mov.b	#0x56,r3l	; use word transfer
+	shlr.l	er2		; byte count / 2
+3:
+	;; setup DMAC
+	mov.l	er1,@MAR0AR:16
+	mov.l	er0,@MAR0BR:16
+	mov.w	r2,@ETCR0AH:16
+	mov.b	r3h,@DTCR0B:8
+	mov.b	r3l,@DTCR0A:8
+4:
+	;; enable DMAC
+	bset	#7,@DTCR0B:8
+	bset	#7,@DTCR0A:8
+	dec.w	#1,e2
+	bpl	4b
+	mov.w	e3,e3		; rest check
+	beq	5f		; no
+
+	mov.l	@MAR0AR:16,er1
+	mov.l	@MAR0BR:16,er0
+	mov.b	@er1,r3l	; copy rest
+	mov.b	r3l,@er0
+5:
+	rts
+#endif
+10:	
+	;; cpu memcpy
+	mov.l	er4,er3		; save regs and param set
+	mov.l	er2,er4
+	mov.l	er5,er2
+	mov.l	er1,er5
+	mov.l	er6,er1
+	mov.l	er0,er6
+11:
+	eepmov.w		; block transfer
+	mov.w	r4,r4
+	bne	11b
+	dec.w	#1,e4
+	bpl	11b
+	mov.l	er1,er6		; restore regs
+	mov.l	er2,er5
+	mov.l	er3,er4
+	rts
diff -urN linux-2.4.29/arch/h8300/lib/memset.S linux-2.4.29-uc1/arch/h8300/lib/memset.S
--- linux-2.4.29/arch/h8300/lib/memset.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/lib/memset.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,61 @@
+/* memset.S */
+
+#include <asm/linkage.h>
+
+#if defined(__H8300H__) 
+	.h8300h
+#endif
+#if defined(__H8300S__) 
+	.h8300s
+#endif
+	.text
+
+.global	SYMBOL_NAME(memset)
+
+;;void *memset(*ptr, int c, size_t count)
+;; ptr = er0
+;; c   = er1(r1l)
+;; count = er2
+SYMBOL_NAME_LABEL(memset)
+	btst	#0,r0l
+	beq	2f
+
+	;; odd address
+1:
+	mov.b	r1l,@er0
+	adds	#1,er0
+	dec.l	#1,er2
+	beq	6f
+
+	;; even address
+2:
+	mov.l	er2,er3
+	cmp.l	#4,er2
+	blo	4f
+	;; count>=4 -> count/4
+#if defined(__H8300H__)
+	shlr.l	er2
+	shlr.l	er2
+#endif
+#if defined(__H8300S__)
+	shlr.l	#2,er2
+#endif
+	;; byte -> long
+	mov.b	r1l,r1h
+	mov.w	r1,e1
+3:
+	mov.l	er1,@er0
+	adds	#4,er0
+	dec.l	#1,er2
+	bne	3b
+4:
+	;; count % 4
+	and.b	#3,r3l
+	beq	6f
+5:
+	mov.b	r1l,@er0
+	adds	#1,er0
+	dec.b	r3l
+	bne	5b
+6:
+	rts
diff -urN linux-2.4.29/arch/h8300/Makefile linux-2.4.29-uc1/arch/h8300/Makefile
--- linux-2.4.29/arch/h8300/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,61 @@
+#
+# h8300/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 2002 Yoshinori Sato <ysato@users.sourceforge.jp>
+#
+# Based on arch/m68knommu/Makefile
+# Copyright (c) 1999,2001  D. Jeff Dionne <jeff@uClinux.org>,
+#	                   Rt-Control Inc. / Lineo, Inc.
+#
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uclinux.org>,
+#                          Kenneth Albanowski <kjahds@kjahds.com>,
+#
+# Based on arch/m68k/Makefile:
+# Copyright (C) 1994 by Hamish Macdonald
+#
+
+# test for cross compiling
+COMPILE_ARCH = $(shell uname -m)
+
+#
+# If you want the kernel build to build modules outside of the tree
+# then define this and pass it to the main linux makefile
+#
+ifdef EXTRA_MODULE_DIRS
+SUBDIRS += $(EXTRA_MODULE_DIRS)
+endif
+
+UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\"
+
+# Find out which board we are compiling for
+include arch/$(ARCH)/Boards.mk
+
+# Set up the memory model.  RAM or ROM.
+ifdef CONFIG_RAMKERNEL
+MODEL = ram
+endif
+ifdef CONFIG_ROMKERNEL
+MODEL = rom
+endif
+export MODEL
+
+# get the compiler, flags and targets from the platform
+ifdef PLATFORM
+include arch/$(ARCH)/platform/$(PLATFORM)/Rules.make
+endif
+
+bootstrap:
+	@$(MAKEBOOT) bootstrap
+
+archmrproper:
+
+archdep:
diff -urN linux-2.4.29/arch/h8300/mm/fault.c linux-2.4.29-uc1/arch/h8300/mm/fault.c
--- linux-2.4.29/arch/h8300/mm/fault.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/mm/fault.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,58 @@
+/*
+ *  linux/arch/h8300/mm/fault.c
+ *
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@uClinux.org>,
+ *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com) 
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68knommu/mm/fault.c
+ *  linux/arch/m68k/mm/fault.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ */
+
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+
+extern void die_if_kernel(char *, struct pt_regs *, long);
+
+/*
+ * This routine handles page faults.  It determines the problem, and
+ * then passes it off to one of the appropriate routines.
+ *
+ * error_code:
+ *	bit 0 == 0 means no page found, 1 means protection fault
+ *	bit 1 == 0 means read, 1 means write
+ *
+ * If this routine detects a bad access, it returns 1, otherwise it
+ * returns 0.
+ */
+asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
+			      unsigned long error_code)
+{
+#ifdef DEBUG
+	printk ("regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n",
+		regs->sr, regs->pc, address, error_code);
+#endif
+
+/*
+ * Oops. The kernel tried to access some bad page. We'll have to
+ * terminate things with extreme prejudice.
+ */
+	if ((unsigned long) address < PAGE_SIZE) {
+		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
+	} else
+		printk(KERN_ALERT "Unable to handle kernel access");
+	printk(" at virtual address %08lx\n",address);
+	die_if_kernel("Oops", regs, error_code);
+	do_exit(SIGKILL);
+
+	return 1;
+}
+
diff -urN linux-2.4.29/arch/h8300/mm/init.c linux-2.4.29-uc1/arch/h8300/mm/init.c
--- linux-2.4.29/arch/h8300/mm/init.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/mm/init.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,256 @@
+/*
+ *  linux/arch/h8300/mm/init.c
+ *
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@uClinux.org>,
+ *                      Kenneth Albanowski <kjahds@kjahds.com>,
+ *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com) 
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68knommu/mm/init.c
+ *  linux/arch/m68k/mm/init.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ *
+ *  JAN/1999 -- hacked to support ColdFire (gerg@snapgear.com)
+ *  DEC/2000 -- linux 2.4 support <davidm@lineo.com>
+ */
+
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#ifdef CONFIG_BLK_DEV_RAM
+#include <linux/blk.h>
+#endif
+#include <linux/bootmem.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/virtconvert.h>
+
+#undef DEBUG
+
+static unsigned long totalram_pages = 0;
+
+extern void die_if_kernel(char *,struct pt_regs *,long);
+
+extern void free_initmem(void);
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+static unsigned long empty_bad_page_table;
+
+static unsigned long empty_bad_page;
+
+unsigned long empty_zero_page;
+
+extern unsigned long rom_length;
+
+void show_mem(void)
+{
+    unsigned long i;
+    int free = 0, total = 0, reserved = 0, shared = 0;
+    int cached = 0;
+
+    printk("\nMem-info:\n");
+    show_free_areas();
+#if 0
+    printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+#endif
+    i = max_mapnr;
+    while (i-- > 0) {
+	total++;
+	if (PageReserved(mem_map+i))
+	    reserved++;
+	else if (PageSwapCache(mem_map+i))
+	    cached++;
+	else if (!page_count(mem_map+i))
+	    free++;
+	else
+	    shared += page_count(mem_map+i) - 1;
+    }
+    printk("%d pages of RAM\n",total);
+    printk("%d free pages\n",free);
+    printk("%d reserved pages\n",reserved);
+    printk("%d pages shared\n",shared);
+    printk("%d pages swap cached\n",cached);
+#if 0
+    printk("%ld pages in page table cache\n",pgtable_cache_size);
+#endif
+    show_buffers();
+}
+
+extern unsigned long memory_start;
+extern unsigned long memory_end;
+
+/*
+ * paging_init() continues the virtual memory environment setup which
+ * was begun by the code in arch/head.S.
+ * The parameters are pointers to where to stick the starting and ending
+ * addresses  of available kernel virtual memory.
+ */
+void paging_init(void)
+{
+	/*
+	 * make sure start_mem is page aligned,  otherwise bootmem and
+	 * page_alloc get different views og the world
+	 */
+#ifdef DEBUG
+	unsigned long start_mem = PAGE_ALIGN(memory_start);
+#endif
+	unsigned long end_mem   = memory_end & PAGE_MASK;
+
+#ifdef DEBUG
+	printk ("start_mem is %#lx\nvirtual_end is %#lx\n",
+		start_mem, end_mem);
+#endif
+
+	/*
+	 * initialize the bad page table and bad page to point
+	 * to a couple of allocated pages
+	 */
+	empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	memset((void *)empty_zero_page, 0, PAGE_SIZE);
+
+	/*
+	 * Set up SFC/DFC registers (user data space)
+	 */
+	set_fs (USER_DS);
+
+#ifdef DEBUG
+	printk ("before free_area_init\n");
+
+	printk ("free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n",
+		start_mem, end_mem);
+#endif
+
+	{
+		unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+
+		zones_size[ZONE_DMA]     = 0 >> PAGE_SHIFT;
+		zones_size[ZONE_NORMAL]  = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
+#ifdef CONFIG_HIGHMEM
+		zones_size[ZONE_HIGHMEM] = 0;
+#endif
+		free_area_init_node(0, NULL, NULL, zones_size, PAGE_OFFSET, NULL);
+	}
+}
+
+void mem_init(void)
+{
+	int codek = 0, datak = 0, initk = 0;
+	/* DAVIDM look at setup memory map generically with reserved area */
+	unsigned long tmp;
+	extern char _etext, _stext, _sdata, _ebss, __init_begin, __init_end;
+	extern unsigned char _ramend, _ramstart;
+	unsigned long len = &_ramend - &_ramstart;
+	unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */
+	unsigned long end_mem   = memory_end; /* DAVIDM - this must not include kernel stack at top */
+
+#ifdef DEBUG
+	printk("Mem_init: start=%lx, end=%lx\n", start_mem, end_mem);
+#endif
+
+	end_mem &= PAGE_MASK;
+	high_memory = (void *) end_mem;
+
+	start_mem = PAGE_ALIGN(start_mem);
+	max_mapnr = num_physpages = MAP_NR(high_memory);
+
+	/* this will put all memory onto the freelists */
+	totalram_pages = free_all_bootmem();
+
+	codek = (&_etext - &_stext) >> 10;
+	datak = (&_ebss - &_sdata) >> 10;
+	initk = (&__init_begin - &__init_end) >> 10;
+
+	tmp = nr_free_pages() << PAGE_SHIFT;
+	printk("Memory available: %luk/%luk RAM, %luk/%luk ROM (%dk kernel code, %dk data)\n",
+	       tmp >> 10,
+	       len >> 10,
+	       (rom_length > 0) ? ((rom_length >> 10) - codek) : 0,
+	       rom_length >> 10,
+	       codek,
+	       datak
+	       );
+}
+
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	int pages = 0;
+	for (; start < end; start += PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(start));
+		set_page_count(virt_to_page(start), 1);
+		free_page(start);
+		totalram_pages++;
+		pages++;
+	}
+	printk ("Freeing initrd memory: %dk freed\n", pages);
+}
+#endif
+
+
+void si_meminfo(struct sysinfo *val)
+{
+    unsigned long i;
+
+    i = max_mapnr;
+    val->totalram = totalram_pages;
+    val->sharedram = 0;
+    val->freeram = nr_free_pages();
+    val->bufferram = atomic_read(&buffermem_pages);
+    val->totalhigh = 0;
+    val->freehigh = 0;
+    val->mem_unit = PAGE_SIZE;
+    return;
+}
+
+
+void
+free_initmem()
+{
+#ifdef CONFIG_RAMKERNEL
+	unsigned long addr;
+	extern char __init_begin, __init_end;
+/*
+ *	the following code should be cool even if these sections
+ *	are not page aligned.
+ */
+	addr = PAGE_ALIGN((unsigned long)(&__init_begin));
+	/* next to check that the page we free is not a partial page */
+	for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(addr));
+		set_page_count(virt_to_page(addr), 1);
+		free_page(addr);
+		totalram_pages++;
+	}
+	printk("Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n",
+			(addr - PAGE_ALIGN((long) &__init_begin)) >> 10,
+			PAGE_ALIGN((unsigned)(&__init_begin)),
+			(unsigned)(addr - PAGE_SIZE));
+#endif
+}
+
diff -urN linux-2.4.29/arch/h8300/mm/kmap.c linux-2.4.29-uc1/arch/h8300/mm/kmap.c
--- linux-2.4.29/arch/h8300/mm/kmap.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/mm/kmap.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,56 @@
+/*
+ *  linux/arch/m68knommu/mm/kmap.c
+ *
+ *  Copyright (C) 2000 Lineo, <davidm@lineo.com>
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#undef DEBUG
+
+/*
+ * Map some physical address range into the kernel address space.
+ */
+
+void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
+{
+	return (void *)physaddr;
+}
+
+/*
+ * Unmap a ioremap()ed region again
+ */
+void iounmap(void *addr)
+{
+}
+
+/*
+ * __iounmap unmaps nearly everything, so be careful
+ * it doesn't free currently pointer/page tables anymore but it
+ * wans't used anyway and might be added later.
+ */
+void __iounmap(void *addr, unsigned long size)
+{
+}
+
+/*
+ * Set new cache mode for some kernel address space.
+ * The caller must push data for that range itself, if such data may already
+ * be in the cache.
+ */
+void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
+{
+}
diff -urN linux-2.4.29/arch/h8300/mm/Makefile linux-2.4.29-uc1/arch/h8300/mm/Makefile
--- linux-2.4.29/arch/h8300/mm/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/mm/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,13 @@
+#
+# Makefile for the linux m68k-specific parts of the memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET := mm.o
+obj-y	 := init.o fault.o memory.o kmap.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/h8300/mm/memory.c linux-2.4.29-uc1/arch/h8300/mm/memory.c
--- linux-2.4.29/arch/h8300/mm/memory.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/mm/memory.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,978 @@
+/*
+ *  linux/arch/h8300/mm/memory.c
+ *
+ *  Copyright (C) 2002  Yoshinori Sato <ysato@users.sourceforge.jp>,
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68knommu/mm/memory.c
+ *
+ *  Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *
+ *  MAR/1999 -- hacked for the ColdFire (gerg@snapgear.com)
+ *
+ *  linux/arch/m68k/mm/memory.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/virtconvert.h>
+
+#ifndef NO_MM
+
+extern pte_t *kernel_page_table (unsigned long *memavailp);
+
+/* Strings for `extern inline' functions in <asm/pgtable.h>.  If put
+   directly into these functions, they are output for every file that
+   includes pgtable.h */
+
+const char PgtabStr_bad_pmd[] = "Bad pmd in pte_alloc: %08lx\n";
+const char PgtabStr_bad_pgd[] = "Bad pgd in pmd_alloc: %08lx\n";
+const char PgtabStr_bad_pmdk[] = "Bad pmd in pte_alloc_kernel: %08lx\n";
+const char PgtabStr_bad_pgdk[] = "Bad pgd in pmd_alloc_kernel: %08lx\n";
+
+static struct ptable_desc {
+	struct ptable_desc *prev;
+	struct ptable_desc *next;
+	unsigned long	   page;
+	unsigned char	   alloced;
+} ptable_list = { &ptable_list, &ptable_list, 0, 0xff };
+
+#define PD_NONEFREE(dp) ((dp)->alloced == 0xff)
+#define PD_ALLFREE(dp) ((dp)->alloced == 0)
+#define PD_TABLEFREE(dp,i) (!((dp)->alloced & (1<<(i))))
+#define PD_MARKUSED(dp,i) ((dp)->alloced |= (1<<(i)))
+#define PD_MARKFREE(dp,i) ((dp)->alloced &= ~(1<<(i)))
+
+#define PTABLE_SIZE (PTRS_PER_PMD * sizeof(pmd_t))
+
+pmd_t *get_pointer_table (void)
+{
+	pmd_t *pmdp = NULL;
+	unsigned long flags;
+	struct ptable_desc *dp = ptable_list.next;
+	int i;
+
+	/*
+	 * For a pointer table for a user process address space, a
+	 * table is taken from a page allocated for the purpose.  Each
+	 * page can hold 8 pointer tables.  The page is remapped in
+	 * virtual address space to be noncacheable.
+	 */
+	if (PD_NONEFREE (dp)) {
+
+		if (!(dp = kmalloc (sizeof(struct ptable_desc),GFP_KERNEL))) {
+			return 0;
+		}
+
+		if (!(dp->page = __get_free_page (GFP_KERNEL))) {
+			kfree (dp);
+			return 0;
+		}
+
+		nocache_page (dp->page);
+
+		dp->alloced = 0;
+		/* put at head of list */
+		save_flags(flags);
+		cli();
+		dp->next = ptable_list.next;
+		dp->prev = ptable_list.next->prev;
+		ptable_list.next->prev = dp;
+		ptable_list.next = dp;
+		restore_flags(flags);
+	}
+
+	for (i = 0; i < 8; i++)
+		if (PD_TABLEFREE (dp, i)) {
+			PD_MARKUSED (dp, i);
+			pmdp = (pmd_t *)(dp->page + PTABLE_SIZE*i);
+			break;
+		}
+
+	if (PD_NONEFREE (dp)) {
+		/* move to end of list */
+		save_flags(flags);
+		cli();
+		dp->prev->next = dp->next;
+		dp->next->prev = dp->prev;
+
+		dp->next = ptable_list.next->prev;
+		dp->prev = ptable_list.prev;
+		ptable_list.prev->next = dp;
+		ptable_list.prev = dp;
+		restore_flags(flags);
+	}
+
+	memset (pmdp, 0, PTABLE_SIZE);
+
+	return pmdp;
+}
+
+void free_pointer_table (pmd_t *ptable)
+{
+	struct ptable_desc *dp;
+	unsigned long page = (unsigned long)ptable & PAGE_MASK;
+	int index = ((unsigned long)ptable - page)/PTABLE_SIZE;
+	unsigned long flags;
+
+	for (dp = ptable_list.next; dp->page && dp->page != page; dp = dp->next)
+		;
+
+	if (!dp->page)
+		panic ("unable to find desc for ptable %p on list!", ptable);
+
+	if (PD_TABLEFREE (dp, index))
+		panic ("table already free!");
+
+	PD_MARKFREE (dp, index);
+
+	if (PD_ALLFREE (dp)) {
+		/* all tables in page are free, free page */
+		save_flags(flags);
+		cli();
+		dp->prev->next = dp->next;
+		dp->next->prev = dp->prev;
+		restore_flags(flags);
+		cache_page (dp->page);
+		free_page (dp->page);
+		kfree (dp);
+		return;
+	} else {
+		/*
+		 * move this descriptor the the front of the list, since
+		 * it has one or more free tables.
+		 */
+		save_flags(flags);
+		cli();
+		dp->prev->next = dp->next;
+		dp->next->prev = dp->prev;
+
+		dp->next = ptable_list.next;
+		dp->prev = ptable_list.next->prev;
+		ptable_list.next->prev = dp;
+		ptable_list.next = dp;
+		restore_flags(flags);
+	}
+}
+
+/* maximum pages used for kpointer tables */
+#define KPTR_PAGES      4
+/* # of reserved slots */
+#define RESERVED_KPTR	4
+extern pmd_tablepage kernel_pmd_table; /* reserved in head.S */
+
+static struct kpointer_pages {
+        pmd_tablepage *page[KPTR_PAGES];
+        u_char alloced[KPTR_PAGES];
+} kptr_pages;
+
+void init_kpointer_table(void) {
+	short i = KPTR_PAGES-1;
+
+	/* first page is reserved in head.S */
+	kptr_pages.page[i] = &kernel_pmd_table;
+	kptr_pages.alloced[i] = ~(0xff>>RESERVED_KPTR);
+	for (i--; i>=0; i--) {
+		kptr_pages.page[i] = NULL;
+		kptr_pages.alloced[i] = 0;
+	}
+}
+
+pmd_t *get_kpointer_table (void)
+{
+	/* For pointer tables for the kernel virtual address space,
+	 * use the page that is reserved in head.S that can hold up to
+	 * 8 pointer tables. 3 of these tables are always reserved
+	 * (kernel_pg_dir, swapper_pg_dir and kernel pointer table for
+	 * the first 16 MB of RAM). In addition, the 4th pointer table
+	 * in this page is reserved. On Amiga and Atari, it is used to
+	 * map in the hardware registers. It may be used for other
+	 * purposes on other 68k machines. This leaves 4 pointer tables
+	 * available for use by the kernel. 1 of them are usually used
+	 * for the vmalloc tables. This allows mapping of 3 * 32 = 96 MB
+	 * of physical memory. But these pointer tables are also used
+	 * for other purposes, like kernel_map(), so further pages can
+	 * now be allocated.
+	 */
+	pmd_tablepage *page;
+	pmd_table *table;
+	long nr, offset = -8;
+	short i;
+
+	for (i=KPTR_PAGES-1; i>=0; i--) {
+		asm volatile("bfffo %1{%2,#8},%0"
+			: "=d" (nr)
+			: "d" ((u_char)~kptr_pages.alloced[i]), "d" (offset));
+		if (nr)
+			break;
+	}
+	if (i < 0) {
+		printk("No space for kernel pointer table!\n");
+		return NULL;
+	}
+	if (!(page = kptr_pages.page[i])) {
+		if (!(page = (pmd_tablepage *)__get_free_page(GFP_KERNEL))) {
+			printk("No space for kernel pointer table!\n");
+			return NULL;
+		}
+		nocache_page((u_long)(kptr_pages.page[i] = page));
+	}
+	asm volatile("bfset %0@{%1,#1}"
+		: /* no output */
+		: "a" (&kptr_pages.alloced[i]), "d" (nr-offset));
+	table = &(*page)[nr-offset];
+	memset(table, 0, sizeof(pmd_table));
+	return ((pmd_t *)table);
+}
+
+void free_kpointer_table (pmd_t *pmdp)
+{
+	pmd_table *table = (pmd_table *)pmdp;
+	pmd_tablepage *page = (pmd_tablepage *)((u_long)table & PAGE_MASK);
+	long nr;
+	short i;
+
+	for (i=KPTR_PAGES-1; i>=0; i--) {
+		if (kptr_pages.page[i] == page)
+			break;
+	}
+	nr = ((u_long)table - (u_long)page) / sizeof(pmd_table);
+	if (!table || i < 0 || (i == KPTR_PAGES-1 && nr < RESERVED_KPTR)) {
+		printk("Attempt to free invalid kernel pointer table: %p\n", table);
+		return;
+	}
+	asm volatile("bfclr %0@{%1,#1}"
+		: /* no output */
+		: "a" (&kptr_pages.alloced[i]), "d" (nr));
+	if (!kptr_pages.alloced[i]) {
+		kptr_pages.page[i] = 0;
+		cache_page ((u_long)page);
+		free_page ((u_long)page);
+	}
+}
+
+static unsigned long transp_transl_matches( unsigned long regval,
+					    unsigned long vaddr )
+{
+    unsigned long base, mask;
+
+    /* enabled? */
+    if (!(regval & 0x8000))
+	return( 0 );
+
+    if (CPU_IS_030) {
+	/* function code match? */
+	base = (regval >> 4) & 7;
+	mask = ~(regval & 7);
+	if ((SUPER_DATA & mask) != (base & mask))
+	    return( 0 );
+    }
+    else {
+	/* must not be user-only */
+	if ((regval & 0x6000) == 0)
+	    return( 0 );
+    }
+
+    /* address match? */
+    base = regval & 0xff000000;
+    mask = ~((regval << 8) & 0xff000000);
+    return( (vaddr & mask) == (base & mask) );
+}
+
+/*
+ * The following two routines map from a physical address to a kernel
+ * virtual address and vice versa.
+ */
+unsigned long mm_vtop (unsigned long vaddr)
+{
+	int i;
+	unsigned long voff = vaddr;
+	unsigned long offset = 0;
+
+	for (i = 0; i < boot_info.num_memory; i++)
+	{
+		if (voff < offset + boot_info.memory[i].size) {
+#ifdef DEBUGPV
+			printk ("virt_to_phys(%lx)=%lx\n", vaddr,
+				boot_info.memory[i].addr + voff - offset);
+#endif
+			return boot_info.memory[i].addr + voff - offset;
+		} else
+			offset += boot_info.memory[i].size;
+	}
+
+	/* not in one of the memory chunks; test for applying transparent
+	 * translation */
+
+	if (CPU_IS_030) {
+	    unsigned long ttreg;
+
+	    asm volatile(   "movel %1, %%a2\n\t"
+			    ".long 0xf0120a00;" /* pmove %/tt0,%a0@ */
+			  : "=g" (ttreg) : "g" (&ttreg) : "cc", "%a2" );
+	    if (transp_transl_matches( ttreg, vaddr ))
+		return vaddr;
+
+	    asm volatile(   "movel %1, %%a2\n\t"
+			    ".long 0xf0120a00" /* pmove %/tt1,%a0@ */
+			  : "=g" (ttreg) : "g" (&ttreg) : "cc", "%a2" );
+	    if (transp_transl_matches( ttreg, vaddr ))
+		return vaddr;
+	}
+	else if (CPU_IS_040_OR_060) {
+	    unsigned long ttreg;
+	    
+	    asm volatile(   ".long 0x4e7a0006\n\t" /* movec %dtt0,%d0 */
+			    "movel %%d0, %0\n"
+			  : "=g" (ttreg) );
+	    if (transp_transl_matches( ttreg, vaddr ))
+		return vaddr;
+	    asm volatile(   ".long 0x4e7a0007" /* movec %dtt1,%d0 */
+			    "movel %%d0, %0\n"
+			  : "=g" (ttreg) );
+	    if (transp_transl_matches( ttreg, vaddr ))
+		return vaddr;
+	}
+
+	/* no match, too, so get the actual physical address from the MMU. */
+
+	if (CPU_IS_060) {
+	  unsigned long fs = get_fs();
+	  unsigned long  paddr;
+
+	  set_fs (SUPER_DATA);
+
+	  /* The PLPAR instruction causes an access error if the translation
+	   * is not possible. We don't catch that here, so a bad kernel trap
+	   * will be reported in this case. */
+	  asm volatile ("movel %1,%/a0\n\t"
+			".word 0xf5c8\n\t"	/* plpar (a0) */
+			"movel %/a0,%0"
+			: "=g" (paddr)
+			: "g" (vaddr)
+			: "a0" );
+	  set_fs (fs);
+
+	  return paddr;
+
+	} else if (CPU_IS_040) {
+	  unsigned long mmusr;
+	  unsigned long fs = get_fs();
+
+	  set_fs (SUPER_DATA);
+
+	  asm volatile ("movel %1,%/a0\n\t"
+			".word 0xf568\n\t"	/* ptestr (a0) */
+			".long 0x4e7a8805\n\t"	/* movec mmusr, a0 */
+			"movel %/a0,%0"
+			: "=g" (mmusr)
+			: "g" (vaddr)
+			: "a0", "d0");
+	  set_fs (fs);
+
+	  if (mmusr & MMU_R_040)
+	    return (mmusr & PAGE_MASK) | (vaddr & (PAGE_SIZE-1));
+
+	  panic ("virt_to_phys040: bad virtual address %08lx (%lx)", vaddr, mmusr);
+	} else {
+	  volatile unsigned short temp;
+	  unsigned short mmusr;
+	  unsigned long *descaddr;
+
+	  asm volatile ("ptestr #5,%2@,#7,%0\n\t"
+			"pmove %/psr,%1@"
+			: "=a&" (descaddr)
+			: "a" (&temp), "a" (vaddr));
+	  mmusr = temp;
+
+	  if (mmusr & (MMU_I|MMU_B|MMU_L))
+	    panic ("virt_to_phys030: bad virtual address %08lx (%x)", vaddr, mmusr);
+
+	  descaddr = (unsigned long *)phys_to_virt(descaddr);
+
+	  switch (mmusr & MMU_NUM) {
+	  case 1:
+	    return (*descaddr & 0xfe000000) | (vaddr & 0x01ffffff);
+	  case 2:
+	    return (*descaddr & 0xfffc0000) | (vaddr & 0x0003ffff);
+	  case 3:
+	    return (*descaddr & PAGE_MASK) | (vaddr & (PAGE_SIZE-1));
+	  default:
+	    panic ("virt_to_phys: bad levels (%u) for virtual address %08lx", 
+		   mmusr & MMU_NUM, vaddr);
+	  }
+	}
+
+	panic ("virt_to_phys: bad virtual address %08lx", vaddr);
+}
+
+unsigned long mm_ptov (unsigned long paddr)
+{
+	int i;
+	unsigned long offset = 0;
+
+	for (i = 0; i < boot_info.num_memory; i++)
+	{
+		if (paddr >= boot_info.memory[i].addr &&
+		    paddr < (boot_info.memory[i].addr
+			     + boot_info.memory[i].size)) {
+#ifdef DEBUGPV
+			printk ("phys_to_virt(%lx)=%lx\n", paddr,
+				(paddr - boot_info.memory[i].addr) + offset);
+#endif
+			return (paddr - boot_info.memory[i].addr) + offset;
+		} else
+			offset += boot_info.memory[i].size;
+	}
+
+	/*
+	 * assume that the kernel virtual address is the same as the
+	 * physical address.
+	 *
+	 * This should be reasonable in most situations:
+	 *  1) They shouldn't be dereferencing the virtual address
+	 *     unless they are sure that it is valid from kernel space.
+	 *  2) The only usage I see so far is converting a page table
+	 *     reference to some non-FASTMEM address space when freeing
+         *     mmaped "/dev/mem" pages.  These addresses are just passed
+	 *     to "free_page", which ignores addresses that aren't in
+	 *     the memory list anyway.
+	 *
+	 */
+
+	/*
+	 * if on an amiga and address is in first 16M, move it 
+	 * to the ZTWO_ADDR range
+	 */
+	if (MACH_IS_AMIGA && paddr < 16*1024*1024)
+		return ZTWO_VADDR(paddr);
+	return paddr;
+}
+
+/* invalidate page in both caches */
+#define	clear040(paddr) __asm__ __volatile__ ("movel %0,%/a0\n\t"\
+					      "nop\n\t"\
+					      ".word 0xf4d0"\
+					      /* CINVP I/D (a0) */\
+					      : : "g" ((paddr))\
+					      : "a0")
+
+/* invalidate page in i-cache */
+#define	cleari040(paddr) __asm__ __volatile__ ("movel %0,%/a0\n\t"\
+					       /* CINVP I (a0) */\
+					       "nop\n\t"\
+					       ".word 0xf490"\
+					       : : "g" ((paddr))\
+					       : "a0")
+
+/* push page in both caches */
+#define	push040(paddr) __asm__ __volatile__ ("movel %0,%/a0\n\t"\
+					      "nop\n\t"\
+					     ".word 0xf4f0"\
+					     /* CPUSHP I/D (a0) */\
+					     : : "g" ((paddr))\
+					     : "a0")
+
+/* push and invalidate page in both caches */
+#define	pushcl040(paddr) do { push040((paddr));\
+			      if (CPU_IS_060) clear040((paddr));\
+			 } while(0)
+
+/* push page in both caches, invalidate in i-cache */
+#define	pushcli040(paddr) do { push040((paddr));\
+			       if (CPU_IS_060) cleari040((paddr));\
+			  } while(0)
+
+/* push page defined by virtual address in both caches */
+#define	pushv040(vaddr) __asm__ __volatile__ ("movel %0,%/a0\n\t"\
+					      /* ptestr (a0) */\
+					      "nop\n\t"\
+					      ".word 0xf568\n\t"\
+					      /* movec mmusr,d0 */\
+					      ".long 0x4e7a0805\n\t"\
+					      "andw #0xf000,%/d0\n\t"\
+					      "movel %/d0,%/a0\n\t"\
+					      /* CPUSHP I/D (a0) */\
+					      "nop\n\t"\
+					      ".word 0xf4f0"\
+					      : : "g" ((vaddr))\
+					      : "a0", "d0")
+
+/* push page defined by virtual address in both caches */
+#define	pushv060(vaddr) __asm__ __volatile__ ("movel %0,%/a0\n\t"\
+					      /* plpar (a0) */\
+					      ".word 0xf5c8\n\t"\
+					      /* CPUSHP I/D (a0) */\
+					      ".word 0xf4f0"\
+					      : : "g" ((vaddr))\
+					      : "a0")
+
+
+/*
+ * 040: Hit every page containing an address in the range paddr..paddr+len-1.
+ * (Low order bits of the ea of a CINVP/CPUSHP are "don't care"s).
+ * Hit every page until there is a page or less to go. Hit the next page,
+ * and the one after that if the range hits it.
+ */
+/* ++roman: A little bit more care is required here: The CINVP instruction
+ * invalidates cache entries WITHOUT WRITING DIRTY DATA BACK! So the beginning
+ * and the end of the region must be treated differently if they are not
+ * exactly at the beginning or end of a page boundary. Else, maybe too much
+ * data becomes invalidated and thus lost forever. CPUSHP does what we need:
+ * it invalidates the page after pushing dirty data to memory. (Thanks to Jes
+ * for discovering the problem!)
+ */
+/* ... but on the '060, CPUSH doesn't invalidate (for us, since we have set
+ * the DPI bit in the CACR; would it cause problems with temporarily changing
+ * this?). So we have to push first and then additionally to invalidate.
+ */
+
+/*
+ * cache_clear() semantics: Clear any cache entries for the area in question,
+ * without writing back dirty entries first. This is useful if the data will
+ * be overwritten anyway, e.g. by DMA to memory. The range is defined by a
+ * _physical_ address.
+ */
+
+void cache_clear (unsigned long paddr, int len)
+{
+    if (CPU_IS_040_OR_060) {
+	/*
+	 * cwe need special treatment for the first page, in case it
+	 * is not page-aligned.
+	 */
+	if (paddr & (PAGE_SIZE - 1)){
+	    pushcl040(paddr);
+	    if (len <= PAGE_SIZE){
+		if (((paddr + len - 1) ^ paddr) & PAGE_MASK) {
+		    pushcl040(paddr + len - 1);
+		}
+		return;
+	    }else{
+		len -=PAGE_SIZE;
+		paddr += PAGE_SIZE;
+	    }
+	}
+		
+	while (len > PAGE_SIZE) {
+#if 0
+	    pushcl040(paddr);
+#else
+	    clear040(paddr);
+#endif
+	    len -= PAGE_SIZE;
+	    paddr += PAGE_SIZE;
+	}
+	if (len > 0) {
+	    pushcl040(paddr);
+	    if (((paddr + len - 1) ^ paddr) & PAGE_MASK) {
+		/* a page boundary gets crossed at the end */
+		pushcl040(paddr + len - 1);
+	    }
+	}
+    }
+    else /* 68030 or 68020 */
+	asm volatile ("movec %/cacr,%/d0\n\t"
+		      "oriw %0,%/d0\n\t"
+		      "movec %/d0,%/cacr"
+		      : : "i" (FLUSH_I_AND_D)
+		      : "d0");
+}
+
+
+/*
+ * cache_push() semantics: Write back any dirty cache data in the given area,
+ * and invalidate the range in the instruction cache. It needs not (but may)
+ * invalidate those entries also in the data cache. The range is defined by a
+ * _physical_ address.
+ */
+
+void cache_push (unsigned long paddr, int len)
+{
+    if (CPU_IS_040_OR_060) {
+	/*
+         * on 68040 or 68060, push cache lines for pages in the range;
+	 * on the '040 this also invalidates the pushed lines, but not on
+	 * the '060!
+	 */
+	while (len > PAGE_SIZE) {
+	    pushcli040(paddr);
+	    len -= PAGE_SIZE;
+	    paddr += PAGE_SIZE;
+	    }
+	if (len > 0) {
+	    pushcli040(paddr);
+	    if (((paddr + len - 1) ^ paddr) & PAGE_MASK) {
+		/* a page boundary gets crossed at the end */
+		pushcli040(paddr + len - 1);
+		}
+	    }
+	}
+    
+    
+    /*
+     * 68030/68020 have no writeback cache. On the other hand,
+     * cache_push is actually a superset of cache_clear (the lines
+     * get written back and invalidated), so we should make sure
+     * to perform the corresponding actions. After all, this is getting
+     * called in places where we've just loaded code, or whatever, so
+     * flushing the icache is appropriate; flushing the dcache shouldn't
+     * be required.
+     */
+    else /* 68030 or 68020 */
+	asm volatile ("movec %/cacr,%/d0\n\t"
+		      "oriw %0,%/d0\n\t"
+		      "movec %/d0,%/cacr"
+		      : : "i" (FLUSH_I)
+		      : "d0");
+}
+
+
+/*
+ * cache_push_v() semantics: Write back any dirty cache data in the given
+ * area, and invalidate those entries at least in the instruction cache. This
+ * is intended to be used after data has been written that can be executed as
+ * code later. The range is defined by a _user_mode_ _virtual_ address  (or,
+ * more exactly, the space is defined by the %sfc/%dfc register.)
+ */
+
+void cache_push_v (unsigned long vaddr, int len)
+{
+    if (CPU_IS_040) {
+	/* on 68040, push cache lines for pages in the range */
+	while (len > PAGE_SIZE) {
+	    pushv040(vaddr);
+	    len -= PAGE_SIZE;
+	    vaddr += PAGE_SIZE;
+	    }
+	if (len > 0) {
+	    pushv040(vaddr);
+	    if (((vaddr + len - 1) ^ vaddr) & PAGE_MASK) {
+		/* a page boundary gets crossed at the end */
+		pushv040(vaddr + len - 1);
+		}
+	    }
+	}
+    else if (CPU_IS_060) {
+	/* on 68040, push cache lines for pages in the range */
+	while (len > PAGE_SIZE) {
+	    pushv060(vaddr);
+	    len -= PAGE_SIZE;
+	    vaddr += PAGE_SIZE;
+	}
+	if (len > 0) {
+	    pushv060(vaddr);
+	    if (((vaddr + len - 1) ^ vaddr) & PAGE_MASK) {
+		/* a page boundary gets crossed at the end */
+		pushv060(vaddr + len - 1);
+	    }
+	}
+    }
+    /* 68030/68020 have no writeback cache; still need to clear icache. */
+    else /* 68030 or 68020 */
+	asm volatile ("movec %/cacr,%/d0\n\t"
+		      "oriw %0,%/d0\n\t"
+		      "movec %/d0,%/cacr"
+		      : : "i" (FLUSH_I)
+		      : "d0");
+}
+
+#undef clear040
+#undef cleari040
+#undef push040
+#undef pushcl040
+#undef pushcli040
+#undef pushv040
+#undef pushv060
+
+int mm_end_of_chunk (unsigned long addr, int len)
+{
+	int i;
+
+	for (i = 0; i < boot_info.num_memory; i++)
+		if (boot_info.memory[i].addr + boot_info.memory[i].size
+		    == addr + len)
+			return 1;
+	return 0;
+}
+
+/* Map some physical address range into the kernel address space. The
+ * code is copied and adapted from map_chunk().
+ */
+
+unsigned long kernel_map(unsigned long paddr, unsigned long size,
+			 int nocacheflag, unsigned long *memavailp )
+{
+#define STEP_SIZE	(256*1024)
+
+	static unsigned long vaddr = 0xe0000000; /* safe place */
+	unsigned long physaddr, retaddr;
+	pte_t *ktablep = NULL;
+	pmd_t *kpointerp;
+	pgd_t *page_dir;
+	int pindex;   /* index into pointer table */
+	int prot;
+	
+	/* Round down 'paddr' to 256 KB and adjust size */
+	physaddr = paddr & ~(STEP_SIZE-1);
+	size += paddr - physaddr;
+	retaddr = vaddr + (paddr - physaddr);
+	paddr = physaddr;
+	/* Round up the size to 256 KB. It doesn't hurt if too much is
+	 * mapped... */
+	size = (size + STEP_SIZE - 1) & ~(STEP_SIZE-1);
+
+	if (CPU_IS_040_OR_060) {
+		prot = _PAGE_PRESENT | _PAGE_GLOBAL040;
+		switch( nocacheflag ) {
+		  case KERNELMAP_FULL_CACHING:
+			prot |= _PAGE_CACHE040;
+			break;
+		  case KERNELMAP_NOCACHE_SER:
+		  default:
+			prot |= _PAGE_NOCACHE_S;
+			break;
+		  case KERNELMAP_NOCACHE_NONSER:
+			prot |= _PAGE_NOCACHE;
+			break;
+		  case KERNELMAP_NO_COPYBACK:
+			prot |= _PAGE_CACHE040W;
+			/* prot |= 0; */
+			break;
+		}
+	} else
+		prot = _PAGE_PRESENT |
+			   ((nocacheflag == KERNELMAP_FULL_CACHING ||
+				 nocacheflag == KERNELMAP_NO_COPYBACK) ? 0 : _PAGE_NOCACHE030);
+	
+	page_dir = pgd_offset_k(vaddr);
+	if (pgd_present(*page_dir)) {
+		kpointerp = (pmd_t *)pgd_page(*page_dir);
+		pindex = (vaddr >> 18) & 0x7f;
+		if (pindex != 0 && CPU_IS_040_OR_060) {
+			if (pmd_present(*kpointerp))
+				ktablep = (pte_t *)pmd_page(*kpointerp);
+			else {
+				ktablep = kernel_page_table (memavailp);
+				/* Make entries invalid */
+				memset( ktablep, 0, sizeof(long)*PTRS_PER_PTE);
+				pmd_set(kpointerp,ktablep);
+			}
+			ktablep += (pindex & 15)*64;
+		}
+	}
+	else {
+		/* we need a new pointer table */
+		kpointerp = get_kpointer_table ();
+		pgd_set(page_dir, (pmd_t *)kpointerp);
+		memset( kpointerp, 0, PTRS_PER_PMD*sizeof(pmd_t));
+		pindex = 0;
+	}
+
+	for (physaddr = paddr; physaddr < paddr + size; vaddr += STEP_SIZE) {
+
+		if (pindex > 127) {
+			/* we need a new pointer table */
+			kpointerp = get_kpointer_table ();
+			pgd_set(pgd_offset_k(vaddr), (pmd_t *)kpointerp);
+			memset( kpointerp, 0, PTRS_PER_PMD*sizeof(pmd_t));
+			pindex = 0;
+		}
+
+		if (CPU_IS_040_OR_060) {
+			int i;
+			unsigned long ktable;
+
+			/*
+			 * 68040, use page tables pointed to by the
+			 * kernel pointer table.
+			 */
+
+			if ((pindex & 15) == 0) {
+				/* Need new page table every 4M on the '040 */
+				ktablep = kernel_page_table (memavailp);
+				/* Make entries invalid */
+				memset( ktablep, 0, sizeof(long)*PTRS_PER_PTE);
+			}
+
+			ktable = virt_to_phys(ktablep);
+
+			/*
+			 * initialize section of the page table mapping
+			 * this 1M portion.
+			 */
+			for (i = 0; i < 64; i++) {
+				pte_val(*ktablep++) = physaddr | prot;
+				physaddr += PAGE_SIZE;
+			}
+
+			/*
+			 * make the kernel pointer table point to the
+			 * kernel page table.
+			 */
+
+			((unsigned long *)kpointerp)[pindex++] = ktable | _PAGE_TABLE;
+
+		} else {
+			/*
+			 * 68030, use early termination page descriptors.
+			 * Each one points to 64 pages (256K).
+			 */
+			((unsigned long *)kpointerp)[pindex++] = physaddr | prot;
+			physaddr += 64 * PAGE_SIZE;
+		}
+	}
+
+	return( retaddr );
+}
+
+
+static inline void set_cmode_pte( pmd_t *pmd, unsigned long address,
+				  unsigned long size, unsigned cmode )
+{	pte_t *pte;
+	unsigned long end;
+
+	if (pmd_none(*pmd))
+		return;
+
+	pte = pte_offset( pmd, address );
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end >= PMD_SIZE)
+		end = PMD_SIZE;
+
+	for( ; address < end; pte++ ) {
+		pte_val(*pte) = (pte_val(*pte) & ~_PAGE_NOCACHE) | cmode;
+		address += PAGE_SIZE;
+	}
+}
+
+
+static inline void set_cmode_pmd( pgd_t *dir, unsigned long address,
+				  unsigned long size, unsigned cmode )
+{
+	pmd_t *pmd;
+	unsigned long end;
+
+	if (pgd_none(*dir))
+		return;
+
+	pmd = pmd_offset( dir, address );
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+
+	if ((pmd_val(*pmd) & _DESCTYPE_MASK) == _PAGE_PRESENT) {
+		/* 68030 early termination descriptor */
+		pmd_val(*pmd) = (pmd_val(*pmd) & ~_PAGE_NOCACHE) | cmode;
+		return;
+	}
+	else {
+		/* "normal" tables */
+		for( ; address < end; pmd++ ) {
+			set_cmode_pte( pmd, address, end - address, cmode );
+			address = (address + PMD_SIZE) & PMD_MASK;
+		}
+	}
+}
+
+
+/*
+ * Set new cache mode for some kernel address space.
+ * The caller must push data for that range itself, if such data may already
+ * be in the cache.
+ */
+
+void kernel_set_cachemode( unsigned long address, unsigned long size,
+						   unsigned cmode )
+{
+	pgd_t *dir = pgd_offset_k( address );
+	unsigned long end = address + size;
+	
+	if (CPU_IS_040_OR_060) {
+		switch( cmode ) {
+		  case KERNELMAP_FULL_CACHING:
+			cmode = _PAGE_CACHE040;
+			break;
+		  case KERNELMAP_NOCACHE_SER:
+		  default:
+			cmode = _PAGE_NOCACHE_S;
+			break;
+		  case KERNELMAP_NOCACHE_NONSER:
+			cmode = _PAGE_NOCACHE;
+			break;
+		  case KERNELMAP_NO_COPYBACK:
+			cmode = _PAGE_CACHE040W;
+			break;
+		}
+	} else
+		cmode = ((cmode == KERNELMAP_FULL_CACHING ||
+				  cmode == KERNELMAP_NO_COPYBACK)    ?
+			 0 : _PAGE_NOCACHE030);
+
+	for( ; address < end; dir++ ) {
+		set_cmode_pmd( dir, address, end - address, cmode );
+		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+	}
+	flush_tlb_all();
+}
+
+#else /* !NO_MM */
+
+void cache_clear (unsigned long paddr, int len)
+{
+}
+
+
+void cache_push (unsigned long paddr, int len)
+{
+}
+
+
+void cache_push_v (unsigned long vaddr, int len)
+{
+}
+
+/* Map some physical address range into the kernel address space. The
+ * code is copied and adapted from map_chunk().
+ */
+
+unsigned long kernel_map(unsigned long paddr, unsigned long size,
+			 int nocacheflag, unsigned long *memavailp )
+{
+	return paddr;
+}
+
+
+#ifdef MAGIC_ROM_PTR
+
+int is_in_rom(unsigned long addr)
+{
+
+	extern unsigned long    _ramstart, _ramend;
+	
+	/* Anything not in operational RAM is returned as in rom! */
+	if (addr < _ramstart || addr >= _ramend)
+		return 1;
+	else
+		return 0;
+}
+
+#endif /* MAGIC_ROM_PTR */
+
+#endif /* NO_MM */
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S linux-2.4.29-uc1/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S
--- linux-2.4.29/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,113 @@
+/*
+ *  linux/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S
+ *
+ *  Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ *  Platform depend startup for uClinux-2.4.x
+ *  Target Archtecture:	AE-3068 (aka. aki3068net)
+ *  Memory Layout     :	RAM
+ */
+
+#define ASSEMBLY
+
+#include <linux/config.h>
+#include <asm/linkage.h>
+	
+#if !defined(CONFIG_BLKDEV_RESERVE)
+#if defined(CONFIG_GDB_DEBUG)
+#define RAMEND (__ramend - 0xc000)
+#else
+#define RAMEND __ramend
+#endif
+#else
+#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
+#endif
+	
+	.global SYMBOL_NAME(_start)
+	.global SYMBOL_NAME(command_line)
+	.global SYMBOL_NAME(_platform_gpio_table)
+	.global SYMBOL_NAME(_target_name)
+	
+	.h8300h
+
+	.section .text
+	.file	"crt0_ram.S"
+
+	/* CPU Reset entry */
+SYMBOL_NAME_LABEL(_start)
+	mov.l	#RAMEND,sp
+	ldc	#0x80,ccr
+
+	/* Peripheral Setup */
+	
+#if defined(CONFIG_BLK_DEV_BLKMEM)
+	/* move romfs image */
+	jsr	@__move_romfs	
+#endif
+	
+	/* .bss clear */
+	mov.l	#__sbss,er5
+	mov.l	er5,er6
+	mov.l	#__ebss,er4
+	sub.l	er5,er4
+	shlr	er4
+	shlr	er4
+	sub.l	er0,er0
+1:	
+	mov.l	er0,@er5
+	adds	#4,er5
+	dec.l	#1,er4
+	bne	1b
+
+	/* copy kernel commandline */
+	mov.l	#COMMAND_START,er5
+	mov.l	#SYMBOL_NAME(command_line),er6
+	mov.w	#512,r4
+	eepmov.w
+
+	/* uClinux kernel start */
+	ldc	#0x90,ccr	/* running kernel */
+	mov.l	#SYMBOL_NAME(init_task_union),sp
+	mov.l	sp,@SYMBOL_NAME(_current_task)
+	add.l	#0x2000,sp
+	jsr	@_start_kernel
+_exit:
+
+	jmp	_exit
+
+	rts
+
+	/* I/O port assign information */
+__platform_gpio_table:	
+	mov.l	#gpio_table,er0
+	rts
+
+gpio_table:
+	;; P1DDR
+	.byte	0xff,0xff
+	;; P2DDR
+	.byte	0xff,0xff
+	;; P3DDR
+	.byte	0xff,0x00
+	;; P4DDR
+	.byte	0x00,0x00
+	;; P5DDR
+	.byte	0x01,0x01
+	;; P6DDR
+	.byte	0x00,0x00
+	;; dummy
+	.byte	0x00,0x00
+	;; P8DDR
+	.byte	0x0c,0x0c
+	;; P9DDR
+	.byte	0x00,0x00
+	;; PADDR
+	.byte	0x00,0x00
+	;; PBDDR
+	.byte	0x30,0x30
+
+__target_name:	
+	.asciz	"AE-3068"
+	
+	.section .bootvec,"ax"
+	jmp	@SYMBOL_NAME(_start)
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/aki3068net/Makefile linux-2.4.29-uc1/arch/h8300/platform/h8300h/aki3068net/Makefile
--- linux-2.4.29/arch/h8300/platform/h8300h/aki3068net/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/aki3068net/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,18 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+all: $(BOARD).o
+O_TARGET := $(BOARD).o
+obj-y := timer.o
+
+timer.o: timer.c
+
+clean:
+	rm -f *.[oa]
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/aki3068net/ram.ld linux-2.4.29-uc1/arch/h8300/platform/h8300h/aki3068net/ram.ld
--- linux-2.4.29/arch/h8300/platform/h8300h/aki3068net/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/aki3068net/ram.ld	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,82 @@
+/* AE-3068 (aka. aki3068net) RAM */
+
+OUTPUT_ARCH(h8300h)
+ENTRY("__start")
+
+MEMORY 
+	{
+	ram    : ORIGIN = 0x400000, LENGTH = 0x600000-0x400000
+	eram   : ORIGIN = 0x600000, LENGTH = 0
+	}
+
+SECTIONS
+{
+	.bootvec :
+	{
+	*(.bootvec)
+	} > ram
+        .text :
+	{
+	__stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(0x4) ;
+		*(.rodata*)
+	. = ALIGN(16);          /* Exception table              */
+	___start___ex_table = .;
+		*(__ex_table)
+	___stop___ex_table = .;
+
+        ___start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	___stop___ksymtab = .;
+
+	. = ALIGN(0x4) ;
+	__etext = . ;
+        } > ram
+	.data : 
+	{
+	__sdata = . ;
+	___data_start = . ;
+		*(.data)
+		*(.data.exit)	
+		*(.exitcall.exit)
+
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	. = ALIGN(0x2000) ;
+        ___init_begin = .;
+        *(.text.init)
+        *(.data.init)
+        . = ALIGN(16);
+        ___setup_start = .;
+        *(.setup.init)
+        ___setup_end = .;
+        ___initcall_start = .;
+        *(.initcall.init)
+        . = ALIGN(4) ;
+        ___initcall_end = .;
+        ___init_end = .;
+	__edata = . ;
+	. = ALIGN(0x4) ;
+	} > ram
+	.bss :
+	{
+	__sbss = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	__ebss = . ;
+	__end = . ;
+	__ramstart = .;
+	} > ram
+        .dummy2 :
+        {
+        COMMAND_START = . - 0x200 ;
+	__ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/aki3068net/timer.c linux-2.4.29-uc1/arch/h8300/platform/h8300h/aki3068net/timer.c
--- linux-2.4.29/arch/h8300/platform/h8300h/aki3068net/timer.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/aki3068net/timer.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ *  linux/arch/h8300/platform/h8300h/aki3068net/timer.c
+ *
+ *  Yoshinori Sato <ysato@users.sourcefoge.jp>
+ *
+ *  Platform depend Timer Handler
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/timex.h>
+
+#define CMFA 6
+
+int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *))
+{
+	outb(CONFIG_CLK_FREQ*10/8192,TCORA2);
+	outb(0x00,_8TCSR2);
+	request_irq(40,timer_int,0,"timer",0);
+	outb(0x40|0x08|0x03,_8TCR2);
+	return 0;
+}
+
+void platform_timer_eoi(void)
+{
+	*(unsigned char *)_8TCSR2 &= ~(1 << CMFA);
+}
+
+void platform_gettod(int *year, int *mon, int *day, int *hour,
+		 int *min, int *sec)
+{
+	*year = *mon = *day = *hour = *min = *sec = 0;
+}
+
+#define CNT_PER_USEC (1000000 / (CONFIG_CLK_FREQ * 1000 / 8192))
+unsigned long platform_get_usec(void)
+{
+	return inb(_8TCNT2) * CNT_PER_USEC;
+}
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/entry.S linux-2.4.29-uc1/arch/h8300/platform/h8300h/entry.S
--- linux-2.4.29/arch/h8300/platform/h8300h/entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/entry.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,448 @@
+/* -*- mode: asm -*-
+ *
+ *  linux/arch/h8300/platform/h8300h/entry.S
+ *
+ *  Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ *	fairly heavy changes to fix syscall args and signal processing
+ *	by David McCullough <davidm@snapgear.com>
+ */
+
+/*
+ *  entry.S
+ *  include exception/interrupt gateway
+ *          system call entry
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/linkage.h>
+	
+#define PT_PTRACED	0x00000001
+#define PT_TRACESYS	0x00000002
+#define PT_DTRACE	0x00000004	/* delayed trace (used on m68k, i386) */
+#define PT_TRACESYSGOOD	0x00000008
+#define PT_PTRACE_CAP	0x00000010	/* ptracer can follow suid-exec */
+
+ENOSYS = 38
+
+LSIGTRAP = 5
+
+TASK_THREAD = 616
+THREAD_KSP = 0
+THREAD_USP = 4
+THREAD_CCR = (8+2)
+	
+SOFTIRQ_PENDING = 0
+			
+/*
+ * these are offsets into the task-struct
+ */
+state      =  0
+flags      =  4
+sigpending =  8
+need_resched	= 20
+ptrace     = 24
+counter    = 32
+
+/* the following macro is used when enabling interrupts */
+
+LER4	=	0
+LER5	=	4
+LER3	=	8
+LER2	=	12
+LER1	=	16
+LORIG	=	20
+LCCR	=	24
+LER0	=	26
+LVEC	=	30
+LRET	=	34
+
+	.h8300h
+
+/* CPU context save/restore macros. */
+	
+	.macro	SAVE_ALL
+	mov.l	er0,@-sp
+
+	stc	ccr,r0l				/* check kernel mode */
+	orc	#0x10,ccr
+	btst	#4,r0l
+	bne	5f
+
+	mov.l	sp,@SYMBOL_NAME(sw_usp)		/* user mode */
+	mov.l	@sp,er0
+	mov.l	@SYMBOL_NAME(sw_ksp),sp
+	sub.l	#(LRET-LORIG),sp		/* allocate LORIG - LRET */ 
+	mov.l	er0,@-sp
+	mov.l	er1,@-sp
+	mov.l   @SYMBOL_NAME(sw_usp),er0
+	mov.l   @(8:16,er0),er1                 /* copy the RET addr */
+	mov.l   er1,@(LRET-LER1:16,sp)
+
+	mov.w	e1,r1				/* e1 highbyte = ccr */
+	and	#0xef,r1h			/* mask mode? flag */
+	sub.w	r0,r0
+	mov.b	r1h,r0l
+	mov.w	r0,@(LCCR-LER1:16,sp)		/* copy ccr */
+	mov.l	@(LORIG-LER1:16,sp),er0
+	mov.l	er0,@(LER0-LER1:16,sp)		/* copy ER0 */
+	bra	6f
+5:
+	mov.l	@sp,er0				/* kernel mode */
+	subs	#2,sp
+	mov.l	er0,@-sp
+	mov.l	er1,@-sp
+	mov.w	@(LRET-LER1:16,sp),r1
+	mov.b	r1h,r1l
+	mov.b	#0,r1h
+	mov.w	r1,@(LCCR-LER1:16,sp)
+6:
+	mov.l	er2,@-sp
+	mov.l	er3,@-sp
+	mov.l	er5,@-sp			/* syscall arg #5 */
+	mov.l	er4,@-sp			/* syscall arg #4 */
+	.endm
+
+	.macro	RESTORE_ALL
+	mov.w	@(LCCR:16,sp),r0		/* check kernel mode */
+	btst	#4,r0l
+	bne	7f
+
+	mov.l	@SYMBOL_NAME(sw_usp),er0
+	mov.l	@(LER0:16,sp),er1		/* restore ER0 */
+	mov.l	er1,@er0
+	mov.w	@(LCCR:16,sp),r1		/* restore the RET addr */
+	mov.b	r1l,r1h
+	mov.b	@(LRET+1:16,sp),r1l
+	mov.w	r1,e1
+	mov.w	@(LRET+2:16,sp),r1
+	mov.l	er1,@(8:16,er0)
+
+	mov.l	@sp+,er4
+	mov.l	@sp+,er5
+	mov.l	@sp+,er3
+	mov.l	@sp+,er2
+	mov.l	@sp+,er1
+	add.l	#(LRET-LER1),sp			/* remove LORIG - LRET */ 
+	mov.l	sp,@SYMBOL_NAME(sw_ksp)
+	mov.l	er0,sp
+	bra	8f
+7:
+	mov.l	@sp+,er4
+	mov.l	@sp+,er5
+	mov.l	@sp+,er3
+	mov.l	@sp+,er2
+	mov.l	@sp+,er1
+	adds	#4,sp
+	adds	#2,sp
+8:
+	mov.l	@sp+,er0
+	adds	#4,sp				/* remove the sw created LVEC */
+	rte
+	.endm
+	
+#define SWITCH_STACK_SIZE (1*4+4)		/* includes return address */
+
+	.macro	SAVE_SWITCH_STACK
+	mov.l	er6,@-sp
+	.endm
+
+	.macro	RESTORE_SWITCH_STACK
+	mov.l	@sp+,er6
+	.endm
+
+.globl SYMBOL_NAME(system_call)
+.globl SYMBOL_NAME(ret_from_exception)
+.globl SYMBOL_NAME(ret_from_signal)
+.globl SYMBOL_NAME(ret_from_interrupt)
+.globl SYMBOL_NAME(interrupt_redirect_table)
+.globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
+.globl SYMBOL_NAME(resume)
+.globl SYMBOL_NAME(syscall_trampoline)
+.globl SYMBOL_NAME(interrupt_entry)
+.globl SYMBOL_NAME(trace_break)
+	
+INTERRUPTS = 64		
+#if defined(CONFIG_ROMKERNEL)
+	.section .int_redirect,"ax"
+SYMBOL_NAME_LABEL(interrupt_redirect_table)
+	.rept	7
+	.long	0
+	.endr
+	jsr	@SYMBOL_NAME(interrupt_entry)	/* NMI */
+	jmp	@SYMBOL_NAME(system_call)	/* TRAPA #0 (System call) */
+	.long	0
+	.long	0
+	jmp	@SYMBOL_NAME(trace_break)	/* TRAPA #3 (breakpoint) */
+	.rept	INTERRUPTS-12
+	jsr	@SYMBOL_NAME(interrupt_entry)
+	.endr
+#endif
+#if defined(CONFIG_RAMKERNEL)
+.globl SYMBOL_NAME(interrupt_redirect_table)
+	.section .bss
+SYMBOL_NAME_LABEL(interrupt_redirect_table)
+	.space	4
+#endif
+
+	.section .text
+	.align	2
+SYMBOL_NAME_LABEL(interrupt_entry)
+	SAVE_ALL
+	mov.w	@(LCCR,sp),r0
+	btst	#4,r0l
+	bne	1f
+	mov.l	@SYMBOL_NAME(sw_usp),er0
+	mov.l	@(4:16,er0),er0
+	bra	2f
+1:
+	mov.l	@(LVEC:16,sp),er0
+2:
+#if defined(CONFIG_ROMKERNEL)
+	sub.l	#SYMBOL_NAME(interrupt_redirect_table),er0
+#endif
+#if defined(CONFIG_RAMKERNEL)
+	mov.l	@SYMBOL_NAME(interrupt_redirect_table),er1
+	sub.l	er1,er0
+#endif
+	shlr.l	er0
+	shlr.l	er0
+	dec.l	#1,er0
+	mov.l	sp,er1
+	jsr	@SYMBOL_NAME(process_int)
+	mov.l	@SYMBOL_NAME(irq_stat)+SOFTIRQ_PENDING,er0
+	beq	1f
+	jsr	@SYMBOL_NAME(do_softirq)
+1:
+	sub.l	er0,er0
+	dec.l	#1,er0
+	mov.l	er0,@(LORIG:16,sp)
+	jmp	@SYMBOL_NAME(ret_from_exception)
+
+SYMBOL_NAME_LABEL(system_call)
+	subs	#4,sp				/* dummy LVEC */
+	SAVE_ALL
+	mov.w	@(LCCR:16,sp),r1
+	bset	#4,r1l
+	ldc	r1l,ccr
+	mov.l	er0,er3
+	mov.l	#-ENOSYS,er0
+	mov.l	er0,@(LER0:16,sp)
+
+	/* save top of frame */
+	mov.l	sp,er0
+	mov.l	er3,@-sp
+	jsr	@SYMBOL_NAME(set_esp0)
+	mov.l	@sp+,er3
+	cmp.l	#NR_syscalls,er3
+	bcc	SYMBOL_NAME(ret_from_exception):16
+	shll.l	er3
+	shll.l	er3
+	mov.l	#SYMBOL_NAME(sys_call_table),er0
+	add.l	er3,er0
+	mov.l	@er0,er0
+	mov.l	er0,er3
+	beq	SYMBOL_NAME(ret_from_exception):16	
+	mov.l	@SYMBOL_NAME(_current_task),er2
+	mov.b	@((flags+3-(PT_TRACESYS >> 3)):16,er2),r2l
+	btst	#(PT_TRACESYS & 7),r2l
+	bne	1f
+	mov.l	@(LER1:16,sp),er0
+	mov.l	@(LER2:16,sp),er1
+	mov.l	@(LER3:16,sp),er2
+	jsr	@er3
+	mov.l	er0,@(LER0,sp)			/* save the return value */
+#if defined(CONFIG_SYSCALL_PRINT)
+	jsr	@SYMBOL_NAME(syscall_print)
+#endif
+	jmp	@SYMBOL_NAME(ret_from_exception)
+1:
+	subs	#4, sp				/* dummy return PC */
+	SAVE_SWITCH_STACK
+	mov.l	er3,er5				/* save syscall entry */
+	jsr	SYMBOL_NAME(syscall_trace)
+	mov.l	er5,er3
+	RESTORE_SWITCH_STACK
+	adds	#4, sp				/* dummy return PC */
+	mov.l	@(LER1:16,sp),er0
+	mov.l	@(LER2:16,sp),er1
+	mov.l	@(LER3:16,sp),er2
+	jsr	@er3
+	mov.l	er0,@(LER0:16,sp)		/* save the return value */
+	subs	#4, sp				/* dummy return PC */
+	SAVE_SWITCH_STACK
+	jsr	SYMBOL_NAME(syscall_trace)
+
+SYMBOL_NAME_LABEL(ret_from_signal)
+	RESTORE_SWITCH_STACK
+	adds	#4, sp				/* dummy return PC */
+
+SYMBOL_NAME_LABEL(ret_from_exception)
+	mov.b	@(LCCR+1:16,sp),r0l
+	btst	#4,r0l				/* check if returning to kernel */
+	bne	3f:16				/* if so, skip resched, signals */
+	mov.l	@SYMBOL_NAME(_current_task),er0
+	mov.l	@(need_resched:16,er0),er1
+	bne	SYMBOL_NAME(reschedule):16
+	mov.b	@((flags+(PT_DTRACE >> 3)):16,er0),r1l
+	mov.b	r1l,r1h
+	bclr	#(PT_DTRACE & 7),r1h
+	mov.b	r1h,@((flags+3-(PT_DTRACE >> 3)):16,er0)
+	btst	#(PT_DTRACE & 7),r1l		/* check for delayed trace */
+	beq	1f
+	sub.l	er2,er2
+	inc.l	#1,er2
+	mov.l	er0,er1
+	sub.l	er0,er0
+	mov.b	#LSIGTRAP,r0l
+	jsr	@SYMBOL_NAME(send_sig)		/* send_sig(LSIGTRAP,_current_task,1) */
+	mov.l	@SYMBOL_NAME(_current_task),er0
+1:
+	mov.l	@(state:16,er0),er1		/* state */
+	bne	SYMBOL_NAME(reschedule):16
+	mov.l	@(counter:16,er0),er1		/* counter */
+	beq	SYMBOL_NAME(reschedule):16
+	mov.l	@(sigpending:16,er0),er1
+	bne	Lsignal_return:16
+3:
+	RESTORE_ALL				/* Does RTE */
+
+Lsignal_return:
+	subs	#4, sp				/* dummy return PC */
+	SAVE_SWITCH_STACK
+	mov.l	sp,er1
+	add	#SWITCH_STACK_SIZE,er1
+	sub.l	er0,er0
+	jsr	@SYMBOL_NAME(do_signal)
+	RESTORE_SWITCH_STACK
+	adds	#4, sp				/* dummy return PC */
+	RESTORE_ALL
+
+SYMBOL_NAME_LABEL(reschedule)
+	/* save top of frame */
+	mov.l	sp,er0
+	jsr	@SYMBOL_NAME(set_esp0)
+
+	mov.l	#SYMBOL_NAME(ret_from_exception),er0
+	mov.l	er0,@-sp
+	jmp	@SYMBOL_NAME(schedule)
+
+SYMBOL_NAME_LABEL(resume)
+	/*
+	 *	er0 = prev
+	 *	er1 = next
+	 *	return last in er2
+	 */
+
+	/* save sr */
+	sub.w	r3,r3
+	stc	ccr,r3l
+	mov.w	r3,@((TASK_THREAD+THREAD_CCR):16,er0)
+	SAVE_SWITCH_STACK
+
+	/* disable interrupts */
+	orc	#0x80,ccr
+	mov.l	@SYMBOL_NAME(sw_usp),er3
+	mov.l	er3,@((TASK_THREAD+THREAD_USP):16,er0)
+	mov.l	sp,@((TASK_THREAD+THREAD_KSP):16,er0)
+	
+	/* get pointer to tss struct (er1 contains new task) */
+	mov.l   @SYMBOL_NAME(_current_task), er2
+	mov.l	er1,@SYMBOL_NAME(_current_task)
+
+	/* Skip address space switching if they are the same. */
+	/* FIXME: what did we hack out of here, this does nothing! */
+
+	mov.l	@((TASK_THREAD+THREAD_USP):16,er1),er0
+	mov.l	er0,@SYMBOL_NAME(sw_usp)
+	mov.l	@((TASK_THREAD+THREAD_KSP):16,er1),sp
+	RESTORE_SWITCH_STACK
+			
+	/* restore status register */
+	mov.w	@((TASK_THREAD+THREAD_CCR):16,er1),r3
+
+	ldc	r3l,ccr
+	rts
+
+SYMBOL_NAME_LABEL(trace_break)
+	subs	#4,sp			/* dummy LVEC */
+	SAVE_ALL
+	sub.l	er1,er1
+	dec.l	#1,er1
+	mov.l	er1,@(LORIG,sp)	
+	mov.l	sp,er0
+	jsr	@SYMBOL_NAME(set_esp0)
+	mov.l	@SYMBOL_NAME(sw_usp),er0
+	mov.l	@er0,er1
+	subs	#2,er1
+	mov.l	er1,@er0	
+	and.w	#0xff,e1
+	mov.l	er1,er0
+	jsr	@SYMBOL_NAME(trace_trap)
+	jmp	@SYMBOL_NAME(ret_from_exception)	
+
+SYMBOL_NAME_LABEL(syscall_trampoline)
+	SAVE_SWITCH_STACK
+	mov.l	er0,er6
+	mov.l	sp,er0
+	add.l	#SWITCH_STACK_SIZE,er0
+	jsr	@er6
+	RESTORE_SWITCH_STACK
+	rts
+
+#if defined(CONFIG_BLK_DEV_BLKMEM)
+/*
+	romfs move to __ebss
+	(used crt0)
+*/
+.globl	__move_romfs
+_romfs_sig_len = 8
+
+__move_romfs:	
+	mov.l	#__sbss,er0
+	mov.l	#_romfs_sig,er1
+	mov.b	#_romfs_sig_len,r3l
+1:					/* check romfs image */
+	mov.b	@er0+,r2l
+	mov.b	@er1+,r2h
+	cmp.b	r2l,r2h
+	bne	2f
+	dec.b	r3l
+	bne	1b
+
+	/* find romfs image */
+	mov.l	@__sbss+8,er0		/* romfs length(be) */
+	mov.l	#__sbss,er1
+	add.l	er0,er1			/* romfs image end */
+	mov.l	#__ebss,er2
+	add.l	er0,er2			/* distination address */
+#if defined(CONFIG_INTELFLASH)
+	add.l	#512,er2
+#endif
+	adds	#2,er0
+	adds	#1,er0
+	shlr	er0
+	shlr	er0			/* transfer length */
+1:
+	mov.l	@er1,er3		/* copy image */
+	mov.l	er3,@er2
+	subs	#4,er1
+	subs	#4,er2
+	dec.l	#1,er0
+	bpl	1b
+2:
+	rts
+
+	.section	.rodata
+_romfs_sig:	
+	.ascii	"-rom1fs-"
+#endif
+
+	.section	.bss
+SYMBOL_NAME_LABEL(sw_ksp)
+	.space	4	
+SYMBOL_NAME_LABEL(sw_usp)
+	.space	4	
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/generic/crt0_rom.S linux-2.4.29-uc1/arch/h8300/platform/h8300h/generic/crt0_rom.S
--- linux-2.4.29/arch/h8300/platform/h8300h/generic/crt0_rom.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/generic/crt0_rom.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,128 @@
+/*
+ *  linux/arch/h8300/platform/h8300h/generic/crt0_rom.S
+ *
+ *  Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ *  Platform depend startup for uClinux-2.4.x
+ *  Target Archtecture:	generic
+ *  Memory Layout     :	ROM
+ */
+
+#define ASSEMBLY
+
+#include <linux/config.h>
+#include <asm/linkage.h>
+	
+#if !defined(CONFIG_BLKDEV_RESERVE)
+#if defined(CONFIG_GDB_DEBUG)
+#define RAMEND (__ramend - 0xc000)
+#else
+#define RAMEND __ramend
+#endif
+#else
+#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
+#endif
+	
+	.global SYMBOL_NAME(_start)
+	.global SYMBOL_NAME(_command_line)
+	.global SYMBOL_NAME(_platform_gpio_table)
+	.global SYMBOL_NAME(_target_name)
+	
+	.h8300h
+	.section .text
+	.file	"crt0_rom.S"
+
+	/* CPU Reset entry */
+SYMBOL_NAME_LABEL(_start)
+	mov.l	#RAMEND,sp
+	ldc	#0x80,ccr
+
+	/* Peripheral Setup */
+	
+	/* .bss clear */
+	mov.l	#__sbss,er5
+	mov.l	er5,er6
+	inc.l	#1,er6
+	mov.l	#__ebss,er4
+	sub.l	er5,er4
+	sub.w	r0,r0
+	mov.b	r0l,@er5
+1:	
+	eepmov.w
+	dec.w	#1,e4
+	bpl	1b
+
+	/* copy .data */
+#if !defined(CONFIG_GDB_EXEC)
+	mov.l	#__begin_data,er5
+	mov.l	#__sdata,er6
+	mov.l	#__edata,er4
+	sub.l	er6,er4		
+1:	
+	eepmov.w	
+	dec.w	#1,e4
+	bpl	1b	
+#endif
+
+	/* copy kernel commandline */
+	mov.l	#COMMAND_START,er5
+	mov.l	#SYMBOL_NAME(_command_line),er6
+	mov.w	#512,r4
+	eepmov.w
+
+	/* uClinux kernel start */
+	ldc	#0x90,ccr	/* running kernel */
+	mov.l	#SYMBOL_NAME(init_task_union),sp
+	mov.l	sp,@SYMBOL_NAME(_current_task)
+	add.l	#0x2000,sp
+	jsr	@_start_kernel
+_exit:
+
+	jmp	_exit
+
+	rts
+
+	/* I/O port assign information */
+__platform_gpio_table:	
+	mov.l	#gpio_table,er0
+	rts
+
+gpio_table:
+	;; P1DDR
+	.byte	0x00,0x00
+	;; P2DDR
+	.byte	0x00,0x00
+	;; P3DDR
+	.byte	0x00,0x00
+	;; P4DDR
+	.byte	0x00,0x00
+	;; P5DDR
+	.byte	0x00,0x00
+	;; P6DDR
+	.byte	0x00,0x00
+	;; dummy
+	.byte	0x00,0x00
+	;; P8DDR
+	.byte	0x00,0x00
+	;; P9DDR
+	.byte	0x00,0x00
+	;; PADDR
+	.byte	0x00,0x00
+	;; PBDDR
+	.byte	0x00,0x00
+
+__target_name:	
+	.asciz	"generic"
+	
+	.section .bss
+__command_line:	
+	.space	512
+
+	/* interrupt vector */
+	.section .vectors,"ax"
+	.long	__start
+vector	=	1
+	.rept	64-1
+	.long	_interrupt_redirect_table+vector*4
+vector	=	vector + 1
+	.endr
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/generic/Makefile linux-2.4.29-uc1/arch/h8300/platform/h8300h/generic/Makefile
--- linux-2.4.29/arch/h8300/platform/h8300h/generic/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/generic/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,18 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+all: $(BOARD).o
+O_TARGET := $(BOARD).o
+obj-y := timer.o
+
+timer.o: timer.c
+
+clean:
+	rm -f *.[oa]
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/generic/ram.ld linux-2.4.29-uc1/arch/h8300/platform/h8300h/generic/ram.ld
--- linux-2.4.29/arch/h8300/platform/h8300h/generic/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/generic/ram.ld	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,70 @@
+/* AKI3068NET RAM */
+
+OUTPUT_ARCH(h8300h)
+ENTRY("__start")
+
+MEMORY 
+	{
+	ram    : ORIGIN = 0x400000, LENGTH = 0xA0000
+/*	rdisk  : ORIGIN = 0x4A0000, LENGTH = 0x70000 */
+/*	uram   : ORIGIN = 0x510000, LENGTH = 0xF0000 */
+	uram   : ORIGIN = 0x4A0000, LENGTH = 0x160000
+	eram   : ORIGIN = 0x600000, LENGTH = 0
+	}
+
+SECTIONS
+{
+	.bootvec :
+	{
+	*(.bootvec)
+	} > ram
+        .text :
+	{
+	__stext = . ;
+        *(.text)
+	__etext = . ;
+        } > ram
+	.rodata :
+	{
+	___data_rom_start = ALIGN ( 4 ) ;
+	} > ram
+	.erom :
+	{
+	__erom = . ;
+	} > ram
+	.data : 
+	{
+	__ramstart = . ;
+	__sdata = . ;
+	___data_start = . ;
+        *(.data)
+	__edata = . ;
+	edata = ALIGN( 0x10 ) ;
+	___data_end = ALIGN( 0x10 ) ;
+	} > ram
+        .bss :
+        {
+	__sbss = . ;
+	___bss_start = . ;
+	*(.bss)
+	*(COMMON)
+	__ebss = . ;
+	___bss_end = . ;
+	} > ram
+/*
+	.rootimg :
+	{
+	__rootimage = . ;
+	} > rdisk
+*/
+	.dummy1 :
+	{
+	end = ALIGN( 0x10 ) ;
+	__end = ALIGN( 0x10 ) ;
+	} > uram
+        .dummy2 :
+        {
+        _COMMAND_START = . - 0x200 ;
+	__ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/generic/rom.ld linux-2.4.29-uc1/arch/h8300/platform/h8300h/generic/rom.ld
--- linux-2.4.29/arch/h8300/platform/h8300h/generic/rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/generic/rom.ld	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,101 @@
+OUTPUT_ARCH(h8300h)
+ENTRY("__start")
+
+/*INPUT(rootimage.o)*/
+
+MEMORY 
+	{
+	vector : ORIGIN = 0x000000, LENGTH = 0x001000
+	rom    : ORIGIN = 0x000100, LENGTH = 0x200000-0x001000
+	erom   : ORIGIN = 0x200000, LENGTH = 1
+	ram    : ORIGIN = 0x200000, LENGTH = 0x100000
+	eram   : ORIGIN = 0x2fa000, LENGTH = 1
+	}
+
+SECTIONS
+{
+	.vectors :
+	{
+	__vector = . ;
+		*(.vectors*)
+	} > vector
+        .text :
+	{
+		*(.int_redirect)
+	__stext = . ;
+        	*(.text)
+	. = ALIGN(0x4) ;
+		*(.text.*)
+	. = ALIGN(0x4) ;
+		*(.exitcall.exit)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(0x4) ;
+		*(.rodata*)
+	. = ALIGN(16);          /* Exception table              */
+	___start___ex_table = .;
+		*(__ex_table)
+	___stop___ex_table = .;
+
+        ___start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	___stop___ksymtab = .;
+
+	. = ALIGN(0x4) ;
+	__etext = . ;
+	} > rom
+	.data : AT( ADDR(.text)+SIZEOF(.text))
+	{
+	__sdata = . ;
+	___data_start = . ;
+
+	. = ALIGN(0x4) ;
+		*(.data)
+	. = ALIGN(0x4) ;
+		*(.data.*)	
+
+	. = ALIGN(0x4) ;
+	___setup_start = .;
+		*(.setup.init)
+	. = ALIGN(0x4) ;
+	___setup_end = .;
+
+	. = ALIGN(0x4) ;
+	___initcall_start = .;
+		*(.initcall.init)
+	. = ALIGN(0x4) ;
+	___initcall_end = .;
+
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	. = ALIGN(0x2000) ;
+	__edata = . ;
+	} > ram
+	__begin_data = LOADADDR(.data) ;
+	.blkimg : AT( LOADADDR(.data) + SIZEOF(.data))
+	{
+	__blkimg = . ;
+		*(.rootimg*)
+	} > rom
+	.erom :
+	{
+	__erom = . ;
+	} > erom
+        .bss :
+        {
+	. = ALIGN(0x4) ;
+	__sbss = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	__ebss = . ;
+	__end = . ;
+	__ramstart = .;
+	} > ram
+        .dummy :
+        {
+        COMMAND_START = . - 0x200 ;
+	__ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/generic/Rules.make linux-2.4.29-uc1/arch/h8300/platform/h8300h/generic/Rules.make
--- linux-2.4.29/arch/h8300/platform/h8300h/generic/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/generic/Rules.make	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,92 @@
+#
+# 68EZ328/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uClinux.org>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+#
+
+CROSS_COMPILE = m68k-coff-
+
+LIBGCC = `$(CC) -v 2>&1 | grep specs | sed -e "s/Reading specs from //" | sed -e s/specs/m68000\\\/libgcc.a/`
+
+CFLAGS := $(CFLAGS) -pipe -DNO_MM -DNO_FPU -m68000 -D__COFF__ -DMAGIC_ROM_PTR -DNO_FORGET -DUTS_SYSNAME='"uClinux"'
+AFLAGS := $(AFLAGS) -pipe -DNO_MM -DNO_FPU -m68000 -D__COFF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME='"uClinux"'  -Wa,--bitwise-or
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+INIT_B := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/init_$(MODEL).b
+STOB   := arch/$(ARCH)/platform/$(PLATFORM)/tools/stob
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+ARCHIVES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+            arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(ARCHIVES)
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+ifdef CONFIG_FRAMEBUFFER
+SUBDIRS := $(SUBDIRS) arch/$(ARCH)/console
+ARCHIVES := $(ARCHIVES) arch/$(ARCH)/console/console.a
+endif
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+romfs.s19: romfs.img arch/$(ARCH)/empty.o
+	$(CROSS_COMPILE)objcopy -v -R .text -R .data -R .bss --add-section=.fs=romfs.img --adjust-section-vma=.fs=$(ROMFS_LOAD_ADDR) arch/$(ARCH)/empty.o romfs.s19
+	$(CROSS_COMPILE)objcopy -O srec romfs.s19
+
+romfs.b: romfs.s19
+	$(STOB) romfs.s19 > romfs.b
+
+linux.data: linux
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.romvec --remove-section=.text --remove-section=.ramvec --remove-section=.bss --remove-section=.eram linux linux.data
+
+linux.text: linux
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.ramvec --remove-section=.bss --remove-section=.data --remove-section=.eram --set-section-flags=.romvec=CONTENTS,ALLOC,LOAD,READONLY,CODE linux linux.text
+
+romfs.img:
+	echo creating a vmlinux rom image without root filesystem!
+
+linux.bin: linux.text linux.data romfs.img
+	if [ -f romfs.img ]; then\
+		cat linux.text linux.data romfs.img > linux.bin;\
+	else\
+		cat linux.text linux.data > linux.bin;\
+	fi
+
+flash.s19: linux.bin arch/$(ARCH)/empty.o
+	$(CROSS_COMPILE)objcopy -v -R .text -R .data -R .bss --add-section=.fs=linux.bin --adjust-section-vma=.fs=$(FLASH_LOAD_ADDR) arch/$(ARCH)/empty.o flash.s19
+	$(CROSS_COMPILE)objcopy -O srec flash.s19
+
+flash.b: flash.s19
+	$(STOB) flash.s19 > flash.b
+
+linux.trg linux.rom: linux.bin
+	perl arch/$(ARCH)/platform/$(PLATFORM)/tools/fixup.pl
+
+linux.s19: linux
+	$(CROSS_COMPILE)objcopy -O srec --adjust-section-vma=.data=0x`$(CROSS_COMPILE)nm linux | awk '/__data_rom_start/ {printf $$1}'` linux linux.s19
+
+	$(CROSS_COMPILE)objcopy -O srec linux.s19
+	
+linux.b: linux.s19
+	if [ -f $(INIT_B) ]; then\
+		cp $(INIT_B) linux.b;\
+	fi
+	$(STOB) linux.s19 >> linux.b
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f linux.text linux.data linux.bin linux.rom linux.trg
+	rm -f linux.s19 romfs.s19 flash.s19
+	rm -f linux.img romdisk.img
+	rm -f linux.b romfs.b flash.b
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/generic/timer.c linux-2.4.29-uc1/arch/h8300/platform/h8300h/generic/timer.c
--- linux-2.4.29/arch/h8300/platform/h8300h/generic/timer.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/generic/timer.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,97 @@
+/*
+ *  linux/arch/h8300/platform/h8300h/generic/timer.c
+ *
+ *  Yoshinori Sato <qzb04471@nifty.ne.jp>
+ *
+ *  Platform depend Timer Handler
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/timex.h>
+
+#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
+#include <asm/regs306x.h>
+
+#define CMFA 6
+
+int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *))
+{
+	outb(CONFIG_CLK_FREQ*10/8192,TCORA2);
+	outb(0x00,_8TCSR2);
+	request_irq(40,timer_int,0,"timer",0);
+	outb(0x40|0x08|0x03,_8TCR2);
+	return 0;
+}
+
+void platform_timer_eoi(void)
+{
+	*(unsigned char *)_8TCSR2 &= ~(1 << CMFA);
+}
+
+#define CNT_PER_USEC (1000000 / (CONFIG_CLK_FREQ * 1000 / 8192))
+unsigned long platform_get_usec(void)
+{
+	return inb(_8TCNT2) * CNT_PER_USEC;
+}
+
+#endif
+
+#if defined(H8_3002) || defined(CONFIG_H83048)
+#define TSTR 0x00ffff60
+#define TSNC 0x00ffff61
+#define TMDR 0x00ffff62
+#define TFCR 0x00ffff63
+#define TOER 0x00ffff90
+#define TOCR 0x00ffff91
+#define TCR  0x00ffff64
+#define TIOR 0x00ffff65
+#define TIER 0x00ffff66
+#define TSR  0x00ffff67
+#define TCNT 0x00ffff68
+#define GRA  0x00ffff6a
+#define GRB  0x00ffff6c
+
+int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *))
+{
+	*(unsigned short *)GRA=CONFIG_CLK_FREQ*10/8;
+	*(unsigned short *)TCNT=0;
+	outb(0x23,TCR);
+	outb(0x00,TIOR);
+	request_irq_boot(26,timer_int,0,"timer",0);
+	outb(inb(TIER) | 0x01,TIER);
+	outb(inb(TSNC) & ~0x01,TSNC);
+	outb(inb(TMDR) & ~0x01,TMDR);
+	outb(inb(TSTR) | 0x01,TSTR);
+	return 0;
+}
+
+void platform_timer_eoi(void)
+{
+	outb(inb(TSR) & ~0x01,TSR);
+}
+
+#define CNT_PER_USEC (1000000 / (CONFIG_CLK_FREQ * 1000 / 8))
+unsigned long platform_get_usec(void)
+{
+	return *(unsigned short *)TCNT * CNT_PER_USEC;
+}
+
+#endif
+
+void platform_gettod(int *year, int *mon, int *day, int *hour,
+		 int *min, int *sec)
+{
+	*year = *mon = *day = *hour = *min = *sec = 0;
+}
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/h8max/crt0_ram.S linux-2.4.29-uc1/arch/h8300/platform/h8300h/h8max/crt0_ram.S
--- linux-2.4.29/arch/h8300/platform/h8300h/h8max/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/h8max/crt0_ram.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,112 @@
+/*
+ *  linux/arch/h8300/platform/h8300h/h8max/crt0_ram.S
+ *
+ *  Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ *  Platform depend startup for uClinux-2.4.x
+ *  Target Archtecture:	H8MAX
+ *  Memory Layout     :	RAM
+ */
+
+#define ASSEMBLY
+
+#include <linux/config.h>
+#include <asm/linkage.h>
+
+#if !defined(CONFIG_BLKDEV_RESERVE)
+#if defined(CONFIG_GDB_DEBUG)
+#define RAMEND (__ramend - 0xc000)
+#else
+#define RAMEND __ramend
+#endif
+#else
+#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
+#endif
+	
+	.global SYMBOL_NAME(_start)
+	.global SYMBOL_NAME(command_line)
+	.global SYMBOL_NAME(_platform_gpio_table)
+	.global SYMBOL_NAME(_target_name)
+	
+	.h8300h
+
+	.section .text
+	.file	"crt0_ram.S"
+
+	/* CPU Reset entry */
+SYMBOL_NAME_LABEL(_start)
+	mov.l	#RAMEND,sp
+	ldc	#0x80,ccr
+
+	/* Peripheral Setup */
+
+#if defined(CONFIG_BLK_DEV_BLKMEM)
+	/* move romfs image */
+	jsr	@__move_romfs	
+#endif
+	
+	/* .bss clear */
+	mov.l	#__sbss,er5
+	mov.l	#__ebss,er4
+	sub.l	er5,er4
+	shlr	er4
+	shlr	er4
+	sub.l	er0,er0
+1:	
+	mov.l	er0,@er5
+	adds	#4,er5
+	dec.l	#1,er4
+	bne	1b
+
+	/* copy kernel commandline */
+	mov.l	#COMMAND_START,er5
+	mov.l	#SYMBOL_NAME(command_line),er6
+	mov.w	#512,r4
+	eepmov.w
+
+	/* uClinux kernel start */
+	ldc	#0x90,ccr	/* running kernel */
+	mov.l	#SYMBOL_NAME(init_task_union),sp
+	mov.l	sp,@SYMBOL_NAME(_current_task)
+	add.l	#0x2000,sp
+	jsr	@_start_kernel
+_exit:
+
+	jmp	_exit
+
+	rts
+
+	/* I/O port assign information */
+__platform_gpio_table:	
+	mov.l	#gpio_table,er0
+	rts
+
+gpio_table:
+	;; P1DDR
+	.byte	0xff,0xff
+	;; P2DDR
+	.byte	0xff,0xff
+	;; P3DDR
+	.byte	0xff,0xff
+	;; P4DDR
+	.byte	0xff,0xff
+	;; P5DDR
+	.byte	0x00,0x00
+	;; P6DDR
+	.byte	0xf6,0xf6
+	;; dummy
+	.byte	0x00,0x00
+	;; P8DDR
+	.byte	0xee,0xee
+	;; P9DDR
+	.byte	0x00,0x00
+	;; PADDR
+	.byte	0x00,0x00
+	;; PBDDR
+	.byte	0x00,0x00
+
+__target_name:	
+	.asciz	"H8MAX"
+	
+	.section .bootvec,"ax"
+	jmp	@SYMBOL_NAME(_start)
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/h8max/Makefile linux-2.4.29-uc1/arch/h8300/platform/h8300h/h8max/Makefile
--- linux-2.4.29/arch/h8300/platform/h8300h/h8max/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/h8max/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,18 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+all: $(BOARD).o
+O_TARGET := $(BOARD).o
+obj-y := timer.o
+
+timer.o: timer.c
+
+clean:
+	rm -f *.[oa]
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/h8max/ram.ld linux-2.4.29-uc1/arch/h8300/platform/h8300h/h8max/ram.ld
--- linux-2.4.29/arch/h8300/platform/h8300h/h8max/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/h8max/ram.ld	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,81 @@
+/* H8MAX RAM */
+
+OUTPUT_ARCH(h8300h)
+ENTRY("__start")
+
+MEMORY 
+	{
+	ram    : ORIGIN = 0x400000, LENGTH = 0x600000-0x400000
+	eram   : ORIGIN = 0x600000, LENGTH = 0
+	}
+
+SECTIONS
+{
+	.bootvec :
+	{
+	*(.bootvec)
+	} > ram
+        .text :
+	{
+	__stext = . ;
+        	*(.text)
+        	*(.text.exit)
+        	*(.text.lock)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(0x4) ;
+		*(.rodata*)
+	. = ALIGN(16);          /* Exception table              */
+	___start___ex_table = .;
+		*(__ex_table)
+	___stop___ex_table = .;
+
+        ___start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	___stop___ksymtab = .;
+
+	. = ALIGN(0x4) ;
+	__etext = . ;
+        } > ram
+	.data : 
+	{
+	__sdata = . ;
+	___data_start = . ;
+		*(.data)
+		*(.data.exit)
+		*(.exitcall.exit)
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	. = ALIGN(0x2000) ;
+        ___init_begin = .;
+	        *(.text.init)
+        	*(.data.init)
+        . = ALIGN(16);
+        ___setup_start = .;
+	        *(.setup.init)
+        ___setup_end = .;
+        ___initcall_start = .;
+        	*(.initcall.init)
+        . = ALIGN(4) ;
+        ___initcall_end = .;
+        ___init_end = .;
+	__edata = . ;
+	} > ram
+	.bss :
+	{
+	. = ALIGN(0x4) ;
+	__sbss = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	__ebss = . ;
+	__end = . ;
+	__ramstart = .;
+	} > ram
+        .dummy2 :
+        {
+        COMMAND_START = . - 0x200 ;
+	__ramend = .;
+	} > eram
+}
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/h8max/timer.c linux-2.4.29-uc1/arch/h8300/platform/h8300h/h8max/timer.c
--- linux-2.4.29/arch/h8300/platform/h8300h/h8max/timer.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/h8max/timer.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ *  linux/arch/h8300/platform/h8300h/h8max/timer.c
+ *
+ *  Yoshinori Sato <ysato@users.sourcefoge.jp>
+ *
+ *  Platform depend Timer Handler
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/timex.h>
+
+#define CMFA 6
+
+int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *))
+{
+	outb(CONFIG_CLK_FREQ*10/8192,TCORA2);
+	outb(0x00,_8TCSR2);
+	request_irq(40,timer_int,0,"timer",0);
+	outb(0x40|0x08|0x03,_8TCR2);
+	return 0;
+}
+
+void platform_timer_eoi(void)
+{
+	*(unsigned char *)_8TCSR2 &= ~(1 << CMFA);
+}
+
+void platform_gettod(int *year, int *mon, int *day, int *hour,
+		 int *min, int *sec)
+{
+	*year = *mon = *day = *hour = *min = *sec = 0;
+}
+
+#define CNT_PER_USEC (1000000 / (CONFIG_CLK_FREQ * 1000 / 8192))
+unsigned long platform_get_usec(void)
+{
+	return inb(_8TCNT2) * CNT_PER_USEC;
+}
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/ints_h8300h.c linux-2.4.29-uc1/arch/h8300/platform/h8300h/ints_h8300h.c
--- linux-2.4.29/arch/h8300/platform/h8300h/ints_h8300h.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/ints_h8300h.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ * linux/arch/h8300/platform/h8300h/ints_h8300h.c
+ * Interrupt handling CPU variants
+ *
+ * Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+
+#include <asm/ptrace.h>
+#include <asm/traps.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/regs306x.h>
+
+/* saved vector list */
+const int __initdata h8300_saved_vectors[]={
+#if defined(CONFIG_GDB_DEBUG)
+	TRAP3_VEC,
+#endif
+	-1
+};
+
+/* trap entry table */
+const unsigned long __initdata h8300_trap_table[NR_TRAPS]={
+	0,0,0,0,0,0,0,0,
+	(unsigned long)system_call,  /* TRAPA #0 */
+	0,0,
+	(unsigned long)trace_break,  /* TRAPA #3 */
+};
+
+int h8300_enable_irq_pin(unsigned int irq)
+{
+	int bitmask;
+	if (irq < EXT_IRQ0 || irq > EXT_IRQ5)
+		return 0;
+
+	/* initialize IRQ pin */
+	bitmask = 1 << (irq - EXT_IRQ0);
+	switch(irq) {
+	case EXT_IRQ0:
+	case EXT_IRQ1:
+	case EXT_IRQ2:
+	case EXT_IRQ3:
+		if (H8300_GPIO_RESERVE(H8300_GPIO_P8, bitmask) == 0)
+			return -EBUSY;
+		H8300_GPIO_DDR(H8300_GPIO_P8, bitmask, H8300_GPIO_INPUT);
+		break;
+	case EXT_IRQ4:
+	case EXT_IRQ5:
+		if (H8300_GPIO_RESERVE(H8300_GPIO_P9, bitmask) == 0)
+			return -EBUSY;
+		H8300_GPIO_DDR(H8300_GPIO_P9, bitmask, H8300_GPIO_INPUT);
+		break;
+	}
+
+	return 0;
+}
+
+void h8300_disable_irq_pin(unsigned int irq)
+{
+	int bitmask;
+	if (irq < EXT_IRQ0 || irq > EXT_IRQ5)
+		return;
+
+	/* disable interrupt & release IRQ pin */
+	bitmask = 1 << (irq - EXT_IRQ0);
+	switch(irq) {
+	case EXT_IRQ0:
+	case EXT_IRQ1:
+	case EXT_IRQ2:
+	case EXT_IRQ3:
+		*(volatile unsigned char *)IER &= ~bitmask;
+		H8300_GPIO_FREE(H8300_GPIO_P8, bitmask);
+		break ;
+	case EXT_IRQ4:
+	case EXT_IRQ5:
+		*(volatile unsigned char *)IER &= ~bitmask;
+		H8300_GPIO_FREE(H8300_GPIO_P9, bitmask);
+		break;
+	}
+}
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/Makefile linux-2.4.29-uc1/arch/h8300/platform/h8300h/Makefile
--- linux-2.4.29/arch/h8300/platform/h8300h/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,22 @@
+#
+# Makefile for the linux kernel.
+#
+# Reuse any files we can from the H8/300H
+#
+
+#VPATH := $(VPATH):$(BOARD)
+
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: platform.o $(BOARD)/crt0_$(MODEL).o
+O_TARGET := platform.o
+obj-y := entry.o ints_h8300h.o ptrace_h8300h.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/ptrace_h8300h.c linux-2.4.29-uc1/arch/h8300/platform/h8300h/ptrace_h8300h.c
--- linux-2.4.29/arch/h8300/platform/h8300h/ptrace_h8300h.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/ptrace_h8300h.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,282 @@
+/*
+ *  linux/arch/h8300/platform/h8300h/ptrace_h8300h.c
+ *    ptrace cpu depend helper functions
+ *
+ *  Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+#define CCR_MASK 0x6f    /* mode/imask not set */
+#define BREAKINST 0x5730 /* trapa #3 */
+
+/* Mapping from PT_xxx to the stack offset at which the register is
+   saved.  Notice that usp has no stack-slot and needs to be treated
+   specially (see get_reg/put_reg below). */
+static const int h8300_register_offset[] = {
+	PT_REG(er1), PT_REG(er2), PT_REG(er3), PT_REG(er4),
+	PT_REG(er5), SW_REG(er6), PT_REG(er0), PT_REG(orig_er0),
+	PT_REG(ccr), PT_REG(pc)
+};
+
+/* read register */
+long h8300_get_reg(struct task_struct *task, int regno)
+{
+	switch (regno) {
+	case PT_USP:
+		return task->thread.usp + sizeof(long)*2;
+	case PT_CCR:
+	    return *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]);
+	default:
+	    return *(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]);
+	}
+}
+
+/* write register */
+int h8300_put_reg(struct task_struct *task, int regno, unsigned long data)
+{
+	unsigned short oldccr;
+	switch (regno) {
+	case PT_USP:
+		task->thread.usp = data - sizeof(long)*2;
+	case PT_CCR:
+		oldccr = *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]);
+		oldccr &= ~CCR_MASK;
+		data &= CCR_MASK;
+		data |= oldccr;
+		*(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]) = data;
+		break;
+	default:
+		*(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]) = data;
+		break;
+	}
+	return 0;
+}
+
+/* disable singlestep */
+void h8300_disable_trace(struct task_struct *child)
+{
+	if((long)child->thread.breakinfo.addr != -1L) {
+		*child->thread.breakinfo.addr = child->thread.breakinfo.inst;
+		child->thread.breakinfo.addr = (unsigned short *)-1L;
+	}
+}
+
+/* calculate next pc */
+enum jump_type {none,    /* normal instruction */
+		jabs,    /* absolute address jump */
+		ind,     /* indirect address jump */
+		ret,     /* return to subrutine */
+		reg,     /* register indexed jump */
+		relb,    /* pc relative jump (byte offset) */
+		relw,    /* pc relative jump (word offset) */
+               };
+
+/* opcode decode table define
+   ptn: opcode pattern
+   msk: opcode bitmask
+   len: instruction length (<0 next table index)
+   jmp: jump operation mode */
+struct optable {
+	unsigned char bitpattern;
+	unsigned char bitmask;
+	signed char length;
+	signed char type;
+} __attribute__((aligned(1),packed));
+
+#define OPTABLE(ptn,msk,len,jmp)   \
+        {                          \
+		.bitpattern = ptn, \
+		.bitmask    = msk, \
+		.length	    = len, \
+		.type       = jmp, \
+	}
+
+const static struct optable optable_0[] = {
+	OPTABLE(0x00,0xff, 1,none), /* 0x00 */
+	OPTABLE(0x01,0xff,-1,none), /* 0x01 */
+	OPTABLE(0x02,0xfe, 1,none), /* 0x02-0x03 */
+	OPTABLE(0x04,0xee, 1,none), /* 0x04-0x05/0x14-0x15 */
+	OPTABLE(0x06,0xfe, 1,none), /* 0x06-0x07 */
+	OPTABLE(0x08,0xea, 1,none), /* 0x08-0x09/0x0c-0x0d/0x18-0x19/0x1c-0x1d */
+	OPTABLE(0x0a,0xee, 1,none), /* 0x0a-0x0b/0x1a-0x1b */
+	OPTABLE(0x0e,0xee, 1,none), /* 0x0e-0x0f/0x1e-0x1f */
+	OPTABLE(0x10,0xfc, 1,none), /* 0x10-0x13 */
+	OPTABLE(0x16,0xfe, 1,none), /* 0x16-0x17 */
+	OPTABLE(0x20,0xe0, 1,none), /* 0x20-0x3f */
+	OPTABLE(0x40,0xf0, 1,relb), /* 0x40-0x4f */
+	OPTABLE(0x50,0xfc, 1,none), /* 0x50-0x53 */
+	OPTABLE(0x54,0xfd, 1,ret ), /* 0x54/0x56 */
+	OPTABLE(0x55,0xff, 1,relb), /* 0x55 */
+	OPTABLE(0x57,0xff, 1,none), /* 0x57 */
+	OPTABLE(0x58,0xfb, 2,relw), /* 0x58/0x5c */
+	OPTABLE(0x59,0xfb, 1,reg ), /* 0x59/0x5b */
+	OPTABLE(0x5a,0xfb, 2,jabs), /* 0x5a/0x5e */
+	OPTABLE(0x5b,0xfb, 2,ind ), /* 0x5b/0x5f */
+	OPTABLE(0x60,0xe8, 1,none), /* 0x60-0x67/0x70-0x77 */
+	OPTABLE(0x68,0xfa, 1,none), /* 0x68-0x69/0x6c-0x6d */
+	OPTABLE(0x6a,0xfe,-2,none), /* 0x6a-0x6b */
+	OPTABLE(0x6e,0xfe, 2,none), /* 0x6e-0x6f */
+	OPTABLE(0x78,0xff, 4,none), /* 0x78 */
+	OPTABLE(0x79,0xff, 2,none), /* 0x79 */
+	OPTABLE(0x7a,0xff, 3,none), /* 0x7a */
+	OPTABLE(0x7b,0xff, 2,none), /* 0x7b */
+	OPTABLE(0x7c,0xfc, 2,none), /* 0x7c-0x7f */
+	OPTABLE(0x80,0x80, 1,none), /* 0x80-0xff */
+};
+
+const static struct optable optable_1[] = {
+	OPTABLE(0x00,0xff,-3,none), /* 0x0100 */
+	OPTABLE(0x40,0xf0,-3,none), /* 0x0140-0x14f */
+	OPTABLE(0x80,0xf0, 1,none), /* 0x0180-0x018f */
+	OPTABLE(0xc0,0xc0, 2,none), /* 0x01c0-0x01ff */
+};
+
+const static struct optable optable_2[] = {
+	OPTABLE(0x00,0x20, 2,none), /* 0x6a0?/0x6a8?/0x6b0?/0x6b8? */
+	OPTABLE(0x20,0x20, 3,none), /* 0x6a2?/0x6aa?/0x6b2?/0x6ba? */
+};
+
+const static struct optable optable_3[] = {
+	OPTABLE(0x69,0xfb, 2,none), /* 0x010069/0x01006d/014069/0x01406d */
+	OPTABLE(0x6b,0xff,-4,none), /* 0x01006b/0x01406b */
+	OPTABLE(0x6f,0xff, 3,none), /* 0x01006f/0x01406f */
+	OPTABLE(0x78,0xff, 5,none), /* 0x010078/0x014078 */
+};
+
+const static struct optable optable_4[] = {
+	OPTABLE(0x00,0x78, 3,none), /* 0x0100690?/0x01006d0?/0140690/0x01406d0?/0x0100698?/0x01006d8?/0140698?/0x01406d8? */
+	OPTABLE(0x20,0x78, 4,none), /* 0x0100692?/0x01006d2?/0140692/0x01406d2?/0x010069a?/0x01006da?/014069a?/0x01406da? */
+};
+
+const static struct optables_list {
+	const struct optable *ptr;
+	int size;
+} optables[] = {
+#define OPTABLES(no)                                                   \
+        {                                                              \
+		.ptr  = optable_##no,                                  \
+		.size = sizeof(optable_##no) / sizeof(struct optable), \
+	}
+	OPTABLES(0),
+	OPTABLES(1),
+	OPTABLES(2),
+	OPTABLES(3),
+	OPTABLES(4),
+
+};
+
+const unsigned char condmask[] = {
+	0x00,0x40,0x01,0x04,0x02,0x08,0x10,0x20
+};
+
+static int isbranch(struct task_struct *task,int reson)
+{
+	unsigned char cond = h8300_get_reg(task, PT_CCR);
+	/* encode complex conditions */
+	/* B4: N^V
+	   B5: Z|(N^V)
+	   B6: C|Z */
+	__asm__("bld #3,%w0\n\t"
+		"bxor #1,%w0\n\t"
+		"bst #4,%w0\n\t"
+		"bor #2,%w0\n\t"
+		"bst #5,%w0\n\t"
+		"bld #2,%w0\n\t"
+		"bor #0,%w0\n\t"
+		"bst #6,%w0\n\t"
+		:"=&r"(cond)::"cc");
+	cond &= condmask[reson >> 1];
+	if (!(reson & 1))
+		return cond == 0;
+	else
+		return cond != 0;
+}
+
+static unsigned short *getnextpc(struct task_struct *child, unsigned short *pc)
+{
+	const struct optable *op;
+	unsigned char *fetch_p;
+	unsigned char inst;
+	unsigned long addr;
+	unsigned long *sp;
+	int op_len,regno;
+	op = optables[0].ptr;
+	op_len = optables[0].size;
+	fetch_p = (unsigned char *)pc;
+	inst = *fetch_p++;
+	do {
+		if ((inst & op->bitmask) == op->bitpattern) {
+			if (op->length < 0) {
+				op = optables[-op->length].ptr;
+				op_len = optables[-op->length].size + 1;
+				inst = *fetch_p++;
+			} else {
+				switch (op->type) {
+				case none:
+					return pc + op->length;
+				case jabs:
+					addr = *(unsigned long *)pc;
+					return (unsigned short *)(addr & 0x00ffffff);
+				case ind:
+					addr = *pc & 0xff;
+					return (unsigned short *)(*(unsigned long *)addr);
+				case ret:
+					sp = (unsigned long *)h8300_get_reg(child, PT_USP);
+					/* user stack frames
+					   |   er0  | temporary saved
+					   +--------+
+					   |   exp  | exception stack frames
+					   +--------+
+					   | ret pc | userspace return address
+					*/ 
+					return (unsigned short *)(*(sp+2) & 0x00ffffff);
+				case reg:
+					regno = (*pc >> 4) & 0x07;
+					if (regno == 0)
+						addr = h8300_get_reg(child, PT_ER0);
+					else
+						addr = h8300_get_reg(child, regno-1+PT_ER1);
+					return (unsigned short *)addr;
+				case relb:
+					if ((inst = 0x55) || isbranch(child,inst & 0x0f))
+						(unsigned char *)pc += (signed char)(*fetch_p);
+					return pc+1; /* skip myself */
+				case relw:
+					if ((inst = 0x5c) || isbranch(child,(*fetch_p & 0xf0) >> 4))
+						(unsigned char *)pc += (signed short)(*(pc+1));
+					return pc+2; /* skip myself */
+				}
+			}
+		} else
+			op++;
+	} while(--op_len > 0);
+	return NULL;
+}
+
+/* Set breakpoint(s) to simulate a single step from the current PC.  */
+
+void h8300_enable_trace(struct task_struct *child)
+{
+	unsigned short *nextpc;
+	nextpc = getnextpc(child,(unsigned short *)h8300_get_reg(child, PT_PC));
+	child->thread.breakinfo.addr = nextpc;
+	child->thread.breakinfo.inst = *nextpc;
+	*nextpc = BREAKINST;
+}
+
+asmlinkage void trace_trap(unsigned long bp)
+{
+	if ((unsigned long)current->thread.breakinfo.addr == bp) {
+		h8300_disable_trace(current);
+		force_sig(SIGTRAP,current);
+	} else
+	        force_sig(SIGILL,current);
+}
+
diff -urN linux-2.4.29/arch/h8300/platform/h8300h/Rules.make linux-2.4.29-uc1/arch/h8300/platform/h8300h/Rules.make
--- linux-2.4.29/arch/h8300/platform/h8300h/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8300h/Rules.make	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,58 @@
+#
+# h8300h/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 2001		Lineo, Inc, <www.lineo.com>
+# Copyright (c) 2000,2001	D. Jeff Dionne <jeff@uClinux.org>
+# Copyright (c) 1998,1999	D. Jeff Dionne <jeff@uclinux.org>
+# Copyright (C) 1998		Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 		Hamish Macdonald
+#
+# 68VZ328 Fixes By		Evan Stawnyczy <e@lineo.ca>
+# H8/300H Modify By             Yoshinori Sato <ysato@users.sourceforge.jp>
+
+CROSS_COMPILE = h8300-linux-elf-
+
+LIBGCC = $(shell $(CC) --print-libgcc-file-name -mh -mint32)
+
+CFLAGS :=  -fno-builtin -DNO_CACHE $(CFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -mh -mint32 \
+           -D__ELF__  -DNO_FORGET -DUTS_SYSNAME=\"uClinux\" -D__linux__ -DTARGET=$(BOARD)
+ifndef CONFIG_FULLDEBUG
+CFLAGS += -Os 
+endif
+ifdef CONFIG_BINFMT_SHARED_FLAT
+CFLAGS += -DMAGIC_ROM_PTR
+endif
+AFLAGS := $(AFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -mh -D__ELF__ -DUTS_SYSNAME=\"uClinux\"
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+LDFLAGS := $(LDFLAGS) -mh8300helf 
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) \
+  	   arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD) \
+           $(SUBDIRS)
+
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/platform.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(BOARD).o \
+	      $(CORE_FILES)
+
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+linux.bin: linux
+	$(OBJCOPY) -O binary linux linux.bin
+	
+linux.srec: linux
+	$(OBJCOPY) -O srec linux linux.srec
+
+archclean:
+	rm -f linux{.bin,.srec,}
diff -urN linux-2.4.29/arch/h8300/platform/h8s/edosk2674/crt0_ram.S linux-2.4.29-uc1/arch/h8300/platform/h8s/edosk2674/crt0_ram.S
--- linux-2.4.29/arch/h8300/platform/h8s/edosk2674/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/edosk2674/crt0_ram.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,131 @@
+/*
+ *  linux/arch/h8300/platform/h8s/edosk2674/crt0_ram.S
+ *
+ *  Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ *  Platform depend startup for uClinux-2.4.x
+ *  Target Archtecture:	EDOSK-2674R
+ *  Memory Layout     :	RAM
+ */
+
+#define ASSEMBLY
+
+#include <linux/config.h>
+#include <asm/linkage.h>
+#include <asm/regs267x.h>
+			
+#if !defined(CONFIG_BLKDEV_RESERVE)
+#if defined(CONFIG_GDB_DEBUG)
+#define RAMEND (__ramend - 0xc000)
+#else
+#define RAMEND __ramend
+#endif
+#else
+#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
+#endif
+	
+	.global SYMBOL_NAME(_start)
+	.global SYMBOL_NAME(_command_line)
+	.global SYMBOL_NAME(_platform_gpio_table)
+	.global SYMBOL_NAME(_target_name)
+	
+	.h8300s
+
+	.section .text
+	.file	"crt0_ram.S"
+
+	/* CPU Reset entry */
+SYMBOL_NAME_LABEL(_start)
+	mov.l	#RAMEND,sp
+	ldc	#0x00,exr
+
+	/* Peripheral Setup */
+	bclr	#4,@INTCR:8	/* interrupt mode 2 */
+	bset	#5,@INTCR:8
+	bclr	#0,@IER+1:16
+	bset	#1,@ISCRL+1:16	/* IRQ0 Positive Edge */
+	bclr	#0,@ISCRL+1:16
+
+#if defined(CONFIG_BLK_DEV_BLKMEM)
+	/* move romfs image */
+	jsr	@__move_romfs	
+#endif
+	
+	/* .bss clear */
+	mov.l	#__sbss,er5
+	mov.l	er5,er6
+	mov.l	#__ebss,er4
+	sub.l	er5,er4
+	shlr	#2,er4
+	sub.l	er0,er0
+1:	
+	mov.l	er0,@er5
+	adds	#4,er5
+	dec.l	#1,er4
+	bne	1b
+
+	/* copy kernel commandline */
+	mov.l	#COMMAND_START,er5
+	mov.l	#SYMBOL_NAME(command_line),er6
+	mov.w	#512,r4
+	eepmov.w
+
+	/* uClinux kernel start */
+	ldc	#0x90,ccr	/* running kernel */
+	mov.l	#SYMBOL_NAME(init_task_union),sp
+	mov.l	sp,@SYMBOL_NAME(_current_task)
+	add.l	#0x2000,sp
+	jsr	@_start_kernel
+_exit:
+
+	jmp	_exit
+
+	rts
+
+	/* I/O port assign information */
+__platform_gpio_table:	
+	mov.l	#gpio_table,er0
+	rts
+
+gpio_table:
+	;; P1DDR
+	;;      used,ddr
+	.byte	0x00,0x00
+	;; P2DDR
+	.byte	0x00,0x00
+	;; P3DDR
+	.byte	0x3f,0x3a
+	;; dummy
+	.byte	0x00,0x00
+	;; P5DDR
+	.byte	0x00,0x00
+	;; P6DDR
+	.byte	0x00,0x00
+	;; P7DDR
+	.byte	0x00,0x00
+	;; P8DDR
+	.byte	0x00,0x00
+	;; dummy
+	.byte	0x00,0x00
+	;; PADDR
+	.byte	0xff,0xff
+	;; PBDDR
+	.byte	0xff,0x00
+	;; PCDDR
+	.byte	0xff,0x00
+	;; PDDDR
+	.byte	0xff,0x00
+	;; PEDDR
+	.byte	0xff,0x00
+	;; PFDDR
+	.byte	0xff,0xff
+	;; PGDDR
+	.byte	0x0f,0x0f
+	;; PHDDR
+	.byte	0x0f,0x0f
+
+__target_name:	
+	.asciz	"EDOSK-2674"
+	
+	.section .bootvec,"ax"
+	jmp	@SYMBOL_NAME(_start)
diff -urN linux-2.4.29/arch/h8300/platform/h8s/edosk2674/crt0_rom.S linux-2.4.29-uc1/arch/h8300/platform/h8s/edosk2674/crt0_rom.S
--- linux-2.4.29/arch/h8300/platform/h8s/edosk2674/crt0_rom.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/edosk2674/crt0_rom.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,197 @@
+/*
+ *  linux/arch/h8300/platform/h8s/edosk2674/crt0_rom.S
+ *
+ *  Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ *  Platform depend startup for uClinux-2.4.x
+ *  Target Archtecture:	EDOSK-2674R
+ *  Memory Layout     :	ROM
+ */
+
+#define ASSEMBLY
+
+#include <linux/config.h>
+#include <asm/linkage.h>
+#include <asm/regs267x.h>
+		
+#if !defined(CONFIG_BLKDEV_RESERVE)
+#if defined(CONFIG_GDB_DEBUG)
+#define RAMEND (_ramend - 0xc000)
+#else
+#define RAMEND _ramend
+#endif
+#else
+#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
+#endif
+	
+	.global SYMBOL_NAME(_start)
+	.global SYMBOL_NAME(_command_line)
+	.global SYMBOL_NAME(_platform_gpio_table)
+	.global SYMBOL_NAME(_target_name)
+	
+	.h8300s
+	.section .text
+	.file	"crt0_rom.S"
+
+	/* CPU Reset entry */
+SYMBOL_NAME_LABEL(_start)
+	mov.l	#RAMEND,sp
+	ldc	#0x80,ccr
+	ldc	#0,exr
+	
+	/* Peripheral Setup */
+;BSC/GPIO setup
+	mov.l	#init_regs,er0
+	mov.w	#0xffff,e2
+1:
+	mov.w	@er0+,r2
+	beq	2f
+	mov.w	@er0+,r1
+	mov.b	r1l,@er2
+	bra	1b
+
+2:
+;SDRAM setup
+#define SDRAM_SMR 0x400040
+
+	mov.b	#0,r0l
+	mov.b	r0l,@DRACCR:16
+	mov.w	#0x188,r0
+	mov.w	r0,@REFCR:16
+	mov.w	#0x85b4,r0
+	mov.w	r0,@DRAMCR:16
+	mov.b	#0,r1l
+	mov.b	r1l,@SDRAM_SMR
+	mov.w	#0x84b4,r0
+	mov.w	r0,@DRAMCR:16
+;special thanks to Arizona Cooperative Power
+	
+	/* copy .data */
+	mov.l	#__begin_data,er5
+	mov.l	#__sdata,er6
+	mov.l	#__edata,er4
+	sub.l	er6,er4
+	shlr.l	#2,er4
+1:	
+	mov.l	@er5+,er0
+	mov.l	er0,@er6
+	adds	#4,er6
+	dec.l	#1,er4
+	bne	1b	
+
+	/* .bss clear */
+	mov.l	#__sbss,er5
+	mov.l	#__ebss,er4
+	sub.l	er5,er4
+	shlr.l	#2,er4		
+	sub.l	er0,er0
+1:
+	mov.l	er0,@er5
+	adds	#4,er5
+	dec.l	#1,er4
+	bne	1b
+
+	/* copy kernel commandline */
+	mov.l	#COMMAND_START,er5
+	mov.l	#SYMBOL_NAME(_command_line),er6
+	mov.w	#512,r4
+	eepmov.w
+
+	/* uClinux kernel start */
+	ldc	#0x90,ccr	/* running kernel */
+	mov.l	#SYMBOL_NAME(init_task_union),sp
+	mov.l	sp,@SYMBOL_NAME(_current_task)
+	add.l	#0x2000,sp
+	jsr	@_start_kernel
+_exit:
+
+	jmp	_exit
+
+	rts
+
+	/* I/O port assign information */
+__platform_gpio_table:	
+	mov.l	#gpio_table,er0
+	rts
+
+#define INIT_REGS_DATA(REGS,DATA) \
+	.word	((REGS) & 0xffff),DATA
+
+init_regs:
+INIT_REGS_DATA(ASTCR,0xff)
+INIT_REGS_DATA(RDNCR,0x00)
+INIT_REGS_DATA(ABWCR,0x80)
+INIT_REGS_DATA(WTCRAH,0x27)
+INIT_REGS_DATA(WTCRAL,0x77)
+INIT_REGS_DATA(WTCRBH,0x71)
+INIT_REGS_DATA(WTCRBL,0x22)
+INIT_REGS_DATA(CSACRH,0x80)
+INIT_REGS_DATA(CSACRL,0x80)
+INIT_REGS_DATA(BROMCRH,0xa0)
+INIT_REGS_DATA(BROMCRL,0xa0)
+INIT_REGS_DATA(P3DDR,0x3a)
+INIT_REGS_DATA(P3ODR,0x06)
+INIT_REGS_DATA(PADDR,0xff)
+INIT_REGS_DATA(PFDDR,0xfe)
+INIT_REGS_DATA(PGDDR,0x0f)
+INIT_REGS_DATA(PHDDR,0x0f)
+INIT_REGS_DATA(PFCR0,0xff)
+INIT_REGS_DATA(PFCR2,0x0d)
+INIT_REGS_DATA(ITSR, 0x00)
+INIT_REGS_DATA(ITSR+1,0x3f)
+INIT_REGS_DATA(INTCR,0x20)
+		
+	.word	0
+
+gpio_table:
+	;; P1DDR
+	.byte	0x00,0x00
+	;; P2DDR
+	.byte	0x00,0x00
+	;; P3DDR
+	.byte	0x00,0x00
+	;; dummy
+	.byte	0x00,0x00
+	;; P5DDR
+	.byte	0x00,0x00
+	;; P6DDR
+	.byte	0x00,0x00
+	;; P7DDR
+	.byte	0x00,0x00
+	;; P8DDR
+	.byte	0x00,0x00
+	;; dummy
+	.byte	0x00,0x00
+	;; PADDR
+	.byte	0x00,0x00
+	;; PBDDR
+	.byte	0x00,0x00
+	;; PCDDR
+	.byte	0x00,0x00
+	;; PDDDR
+	.byte	0x00,0x00
+	;; PEDDR
+	.byte	0x00,0x00
+	;; PFDDR
+	.byte	0x00,0x00
+	;; PGDDR
+	.byte	0x00,0x00
+	;; PHDDR
+	.byte	0x00,0x00
+
+__target_name:	
+	.asciz	"EDOSK-2674"
+	
+	.section .bss
+__command_line:	
+	.space	512
+
+	/* interrupt vector */
+	.section .vectors,"ax"
+	.long	__start
+	.long	__start
+vector	=	2
+	.rept	126-1
+	.long	_interrupt_redirect_table+vector*4
+vector	=	vector + 1
+	.endr
diff -urN linux-2.4.29/arch/h8300/platform/h8s/edosk2674/Makefile linux-2.4.29-uc1/arch/h8300/platform/h8s/edosk2674/Makefile
--- linux-2.4.29/arch/h8300/platform/h8s/edosk2674/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/edosk2674/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,18 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+all: $(BOARD).o
+O_TARGET := $(BOARD).o
+obj-y := timer.o
+
+timer.o: timer.c
+
+clean:
+	rm -f *.[oa]
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/h8300/platform/h8s/edosk2674/ram.ld linux-2.4.29-uc1/arch/h8300/platform/h8s/edosk2674/ram.ld
--- linux-2.4.29/arch/h8300/platform/h8s/edosk2674/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/edosk2674/ram.ld	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,80 @@
+/* EDOSK-2674R RAM */
+
+OUTPUT_ARCH(h8300s)
+ENTRY("__start")
+
+MEMORY 
+	{
+	ram    : ORIGIN = 0x400000, LENGTH = 0xc00000-0x400000
+	eram   : ORIGIN = 0xc00000, LENGTH = 0
+	}
+
+SECTIONS
+{
+	.bootvec :
+	{
+	*(.bootvec)
+	} > ram
+        .text :
+	{
+	__stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(0x4) ;
+		*(.rodata*)
+	. = ALIGN(16);          /* Exception table              */
+	___start___ex_table = .;
+		*(__ex_table)
+	___stop___ex_table = .;
+
+        ___start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	___stop___ksymtab = .;
+
+	. = ALIGN(0x4) ;
+	__etext = . ;
+        } > ram
+	.data : 
+	{
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	__sdata = . ;
+	___data_start = . ;
+		*(.data)
+		*(.data.exit)	
+		*(.exitcall.exit)
+        ___init_begin = .;
+	        *(.text.init)
+        	*(.data.init)
+        . = ALIGN(16);
+        ___setup_start = .;
+	        *(.setup.init)
+        ___setup_end = .;
+        ___initcall_start = .;
+        	*(.initcall.init)
+        . = ALIGN(4) ;
+        ___initcall_end = .;
+        ___init_end = .;
+	__edata = . ;
+	} > ram
+	.bss :
+	{
+	. = ALIGN(0x4) ;
+	__sbss = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	__ebss = . ;
+	__end = . ;
+	__ramstart = .;
+	} > ram
+        .dummy2 :
+        {
+        COMMAND_START = . - 0x200 ;
+	__ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/h8300/platform/h8s/edosk2674/rom.ld linux-2.4.29-uc1/arch/h8300/platform/h8s/edosk2674/rom.ld
--- linux-2.4.29/arch/h8300/platform/h8s/edosk2674/rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/edosk2674/rom.ld	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,94 @@
+OUTPUT_ARCH(h8300s)
+ENTRY("__start")
+
+MEMORY 
+	{
+	vector : ORIGIN = 0x000000, LENGTH = 0x000200
+	rom    : ORIGIN = 0x000200, LENGTH = 0x100000-0x000200
+	erom   : ORIGIN = 0x100000, LENGTH = 0
+	ram    : ORIGIN = 0x400000, LENGTH = 0x800000
+	eram   : ORIGIN = 0xc00000, LENGTH = 0
+	}
+
+SECTIONS
+{
+	.vectors :
+	{
+	__vector = . ;
+		*(.vectors*)
+	} > vector
+        .text :
+	{
+		*(.int_redirect)
+	__stext = . ;
+        	*(.text)
+	. = ALIGN(0x4) ;
+		*(.text.*)
+	. = ALIGN(0x4) ;
+		*(.exitcall.exit)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(0x4) ;
+		*(.rodata*)
+	. = ALIGN(16);          /* Exception table              */
+	___start___ex_table = .;
+		*(__ex_table)
+	___stop___ex_table = .;
+
+        ___start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	___stop___ksymtab = .;
+
+	. = ALIGN(0x4) ;
+	__etext = . ;
+	} > rom
+	.data : AT( ADDR(.text)+SIZEOF(.text))
+	{
+	__sdata = . ;
+	___data_start = . ;
+
+	. = ALIGN(0x4) ;
+		*(.data)
+	. = ALIGN(0x4) ;
+		*(.data.*)	
+
+	. = ALIGN(0x4) ;
+	___setup_start = .;
+		*(.setup.init)
+	. = ALIGN(0x4) ;
+	___setup_end = .;
+
+	. = ALIGN(0x4) ;
+	___initcall_start = .;
+		*(.initcall.init)
+	. = ALIGN(0x4) ;
+	___initcall_end = .;
+
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	. = ALIGN(0x2000) ;
+	__edata = . ;
+	} > ram
+	__begin_data = LOADADDR(.data) ;
+	.erom :
+	{
+	__erom = . ;
+	} > erom
+        .bss :
+        {
+	. = ALIGN(0x4) ;
+	__sbss = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	__ebss = . ;
+	__end = . ;
+	__ramstart = .;
+	} > ram
+        .dummy :
+        {
+        COMMAND_START = . - 0x200 ;
+	__ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/h8300/platform/h8s/edosk2674/timer.c linux-2.4.29-uc1/arch/h8300/platform/h8s/edosk2674/timer.c
--- linux-2.4.29/arch/h8300/platform/h8s/edosk2674/timer.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/edosk2674/timer.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,55 @@
+/*
+ *  linux/arch/h8300/platform/h8s/generic/timer.c
+ *
+ *  Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ *  Platform depend Timer Handler
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/regs267x.h>
+
+#include <linux/timex.h>
+
+#define CMFA 6
+
+int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *))
+{
+	unsigned char mstpcrl;
+	mstpcrl = inb(MSTPCRL);
+	mstpcrl &= ~0x01;
+	outb(mstpcrl,MSTPCRL);
+	outb(CONFIG_CLK_FREQ*10/8192,_8TCORA1);
+	outb(0x00,_8TCSR1);
+	request_irq(76,timer_int,0,"timer",0);
+	outb(0x40|0x08|0x03,_8TCR1);
+	return 0;
+}
+
+void platform_timer_eoi(void)
+{
+        *(unsigned char *)_8TCSR1 &= ~(1 << CMFA);
+}
+
+void platform_gettod(int *year, int *mon, int *day, int *hour,
+		 int *min, int *sec)
+{
+	*year = *mon = *day = *hour = *min = *sec = 0;
+}
+
+#define CNT_PER_USEC (1000000 / (CONFIG_CLK_FREQ * 1000 / 8192))
+unsigned long platform_get_usec(void)
+{
+	return inb(_8TCNT1) * CNT_PER_USEC;
+}
diff -urN linux-2.4.29/arch/h8300/platform/h8s/entry.S linux-2.4.29-uc1/arch/h8300/platform/h8s/entry.S
--- linux-2.4.29/arch/h8300/platform/h8s/entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/entry.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,445 @@
+/* -*- mode: asm -*-
+ *
+ *  linux/arch/h8300/platform/h8s/entry.S
+ *
+ *  Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ *	fairly heavy changes to fix syscall args and signal processing
+ *	by David McCullough <davidm@snapgear.com>
+ */
+
+/*
+ *  entry.S
+ *  include exception/interrupt gateway
+ *          system call entry
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/linkage.h>
+	
+#define PT_PTRACED	0x00000001
+#define PT_TRACESYS	0x00000002
+#define PT_DTRACE	0x00000004	/* delayed trace (used on m68k, i386) */
+#define PT_TRACESYSGOOD	0x00000008
+#define PT_PTRACE_CAP	0x00000010	/* ptracer can follow suid-exec */
+
+ENOSYS = 38
+
+LSIGTRAP = 5
+
+TASK_THREAD = 616
+THREAD_KSP = 0
+THREAD_USP = 4
+THREAD_CCR = (8+2)
+	
+SOFTIRQ_PENDING = 0
+		
+/*
+ * these are offsets into the task-struct
+ */
+state      =  0
+flags      =  4
+sigpending =  8
+need_resched	= 20
+ptrace     = 24
+counter    = 32
+
+/* the following macro is used when enabling interrupts */
+
+LER4	=	0
+LER5	=	4
+LER3	=	8
+LER2	=	12
+LER1	=	16
+LORIG	=	20
+LCCR	=	24
+LER0	=	26
+LVEC	=	30
+LEXR	=	34
+LRET	=	36
+
+	.h8300s
+
+/* CPU context save/restore macros. */
+	
+	.macro	SAVE_ALL
+	mov.l	er0,@-sp
+
+	stc	ccr,r0l				/* check kernel mode */
+	orc	#0x10,ccr
+	btst	#4,r0l
+	bne	5f
+
+	mov.l	sp,@SYMBOL_NAME(sw_usp)		/* user mode */
+	mov.l	@sp,er0
+	mov.l	@SYMBOL_NAME(sw_ksp),sp
+	sub.l	#(LRET-LORIG),sp		/* allocate LORIG - LRET */ 
+	stm.l	er0-er3,@-sp
+	mov.l	@SYMBOL_NAME(sw_usp),er0
+	mov.l	@(10:16,er0),er1		/* copy the RET addr */
+	mov.l	er1,@(LRET-LER3:16,sp)
+	mov.w	@(8:16,er0),r1
+	mov.w	r1,@(LEXR-LER3:16,sp)		/* copy EXR */
+
+	mov.w	e1,r1				/* e1 highbyte = ccr */
+	and	#0xef,r1h			/* mask mode? flag */
+	sub.w	r0,r0
+	mov.b	r1h,r0l
+	mov.w	r0,@(LCCR-LER3:16,sp)		/* copy ccr */
+	mov.l	@(LORIG-LER3:16,sp),er0
+	mov.l	er0,@(LER0-LER3:16,sp)		/* copy ER0 */
+	bra	6f
+5:
+	mov.l	@sp,er0				/* kernel mode */
+	subs	#2,sp
+	stm.l	er0-er3,@-sp
+	mov.w	@(LRET-LER3:16,sp),r1
+	mov.b	r1h,r1l
+	mov.b	#0,r1h
+	mov.w	r1,@(LCCR-LER3:16,sp)
+6:	
+	mov.l	er5,@-sp			/* syscall arg #5 */
+	mov.l	er4,@-sp			/* syscall arg #4 */
+	.endm
+
+	.macro	RESTORE_ALL
+	mov.w	@(LCCR:16,sp),r0		/* check kernel mode */
+	btst	#4,r0l
+	bne	7f
+
+	mov.l	@SYMBOL_NAME(sw_usp),er0
+	mov.l	@(LER0:16,sp),er1		/* restore ER0 */
+	mov.l	er1,@er0
+	mov.w	@(LEXR:16,sp),r1		/* restore EXR */
+	mov.b	r1l,r1h
+	mov.w	r1,@(8:16,er0)
+	mov.w	@(LCCR:16,sp),r1		/* restore the RET addr */
+	mov.b	r1l,r1h
+	mov.b	@(LRET+1:16,sp),r1l
+	mov.w	r1,e1
+	mov.w	@(LRET+2:16,sp),r1
+	mov.l	er1,@(10:16,er0)
+
+	mov.l	@sp+,er4
+	mov.l	@sp+,er5
+	ldm.l	@sp+,er2-er3
+	mov.l	@sp+,er1
+	add.l	#(LRET-LER1),sp			/* remove LORIG - LRET */ 
+	mov.l	sp,@SYMBOL_NAME(sw_ksp)
+	mov.l	er0,sp
+	bra	8f
+7:
+	mov.l	@sp+,er4
+	mov.l	@sp+,er5
+	ldm.l	@sp+,er2-er3
+	mov.l	@sp+,er1
+	adds	#4,sp
+	adds	#2,sp
+8:
+	mov.l	@sp+,er0
+	adds	#4,sp				/* remove the sw created LVEC */
+	rte
+	.endm
+	
+#define SWITCH_STACK_SIZE (1*4+4)		/* includes return address */
+
+	.macro	SAVE_SWITCH_STACK
+	mov.l	er6,@-sp
+	.endm
+
+	.macro	RESTORE_SWITCH_STACK
+	mov.l	@sp+,er6
+	.endm
+
+.globl SYMBOL_NAME(system_call)
+.globl SYMBOL_NAME(ret_from_exception)
+.globl SYMBOL_NAME(ret_from_signal)
+.globl SYMBOL_NAME(ret_from_interrupt)
+.globl SYMBOL_NAME(interrupt_redirect_table)
+.globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
+.globl SYMBOL_NAME(resume)
+.globl SYMBOL_NAME(syscall_trampoline)
+.globl SYMBOL_NAME(trace_break)
+.globl SYMBOL_NAME(interrupt_entry)
+		
+INTERRUPTS = 128
+#if defined(CONFIG_ROMKERNEL)
+	.section .int_redirect,"ax"
+SYMBOL_NAME_LABEL(interrupt_redirect_table)
+	.rept	7
+	.long	0
+	.endr
+	jsr	@SYMBOL_NAME(interrupt_entry)	/* NMI */
+	jmp	@SYMBOL_NAME(system_call)	/* TRAPA #0 (System call) */
+	.long	0
+	.long	0
+	jmp	@SYMBOL_NAME(trace_break)	/* TRAPA #3 (breakpoint) */
+	.rept	INTERRUPTS-12
+	jsr	@SYMBOL_NAME(interrupt_entry)
+	.endr
+#endif
+#if defined(CONFIG_RAMKERNEL)
+.globl SYMBOL_NAME(interrupt_redirect_table)
+	.section .bss
+SYMBOL_NAME_LABEL(interrupt_redirect_table)
+	.space	4
+#endif
+	
+	.section .text
+	.align	2
+SYMBOL_NAME_LABEL(interrupt_entry)
+	SAVE_ALL
+	mov.w	@(LCCR,sp),r0
+	btst	#4,r0l
+	bne	1f
+	mov.l	@SYMBOL_NAME(sw_usp),er0
+	mov.l	@(4:16,er0),er0
+	bra	2f
+1:
+	mov.l	@(LVEC:16,sp),er0
+2:
+#if defined(CONFIG_ROMKERNEL)
+	sub.l	#SYMBOL_NAME(interrupt_redirect_table),er0
+#endif
+#if defined(CONFIG_RAMKERNEL)
+	mov.l	@SYMBOL_NAME(interrupt_redirect_table),er1
+	sub.l	er1,er0
+#endif
+	shlr.l	#2,er0
+	dec.l	#1,er0
+	mov.l	sp,er1
+	jsr	@SYMBOL_NAME(process_int)
+	mov.l	@SYMBOL_NAME(irq_stat)+SOFTIRQ_PENDING,er0
+	beq	1f
+	jsr	@SYMBOL_NAME(do_softirq)
+1:
+	sub.l	er0,er0
+	dec.l	#1,er0
+	mov.l	er0,@(LORIG:16,sp)
+	jmp	@SYMBOL_NAME(ret_from_exception)
+
+SYMBOL_NAME_LABEL(system_call)
+	subs	#4,sp				/* dummy LVEC */
+	SAVE_ALL
+	mov.w	@(LCCR:16,sp),r1
+	bset	#4,r1l
+	ldc	r1l,ccr
+	mov.l	er0,er3
+	mov.l	#-ENOSYS,er0
+	mov.l	er0,@(LER0:16,sp)
+
+	/* save top of frame */
+	mov.l	sp,er0
+	mov.l	er3,@-sp
+	jsr	@SYMBOL_NAME(set_esp0)
+	mov.l	@sp+,er3
+	cmp.l	#NR_syscalls,er3
+	bcc	SYMBOL_NAME(ret_from_exception):16
+	shll.l	#2,er3
+	mov.l	#SYMBOL_NAME(sys_call_table),er0
+	add.l	er3,er0
+	mov.l	@er0,er0
+	mov.l	er0,er3
+	beq	SYMBOL_NAME(ret_from_exception):16	
+	mov.l	@SYMBOL_NAME(_current_task),er2
+	mov.b	@((flags+3-(PT_TRACESYS >> 3)):16,er2),r2l
+	btst	#(PT_TRACESYS & 7),r2l
+	bne	1f
+	mov.l	@(LER1:16,sp),er0
+	mov.l	@(LER2:16,sp),er1
+	mov.l	@(LER3:16,sp),er2
+	jsr	@er3
+	mov.l	er0,@(LER0,sp)			/* save the return value */
+#if defined(CONFIG_SYSCALL_PRINT)
+	jsr	@SYMBOL_NAME(syscall_print)
+#endif
+	jmp	@SYMBOL_NAME(ret_from_exception)
+1:
+	subs	#4, sp				/* dummy return PC */
+	SAVE_SWITCH_STACK
+	mov.l	er3,er5				/* save syscall entry */
+	jsr	SYMBOL_NAME(syscall_trace)
+	mov.l	er5,er3
+	RESTORE_SWITCH_STACK
+	adds	#4, sp				/* dummy return PC */
+	mov.l	@(LER1:16,sp),er0
+	mov.l	@(LER2:16,sp),er1
+	mov.l	@(LER3:16,sp),er2
+	jsr	@er3
+	mov.l	er0,@(LER0:16,sp)		/* save the return value */
+	subs	#4, sp				/* dummy return PC */
+	SAVE_SWITCH_STACK
+	jsr	SYMBOL_NAME(syscall_trace)
+
+SYMBOL_NAME_LABEL(ret_from_signal)
+	RESTORE_SWITCH_STACK
+	adds	#4, sp				/* dummy return PC */
+
+SYMBOL_NAME_LABEL(ret_from_exception)
+	mov.b	@(LCCR+1:16,sp),r0l
+	btst	#4,r0l				/* check if returning to kernel */
+	bne	3f:16				/* if so, skip resched, signals */
+	mov.l	@SYMBOL_NAME(_current_task),er0
+	mov.l	@(need_resched:16,er0),er1
+	bne	SYMBOL_NAME(reschedule):16
+	mov.b	@((flags+(PT_DTRACE >> 3)):16,er0),r1l
+	mov.b	r1l,r1h
+	bclr	#(PT_DTRACE & 7),r1h
+	mov.b	r1h,@((flags+3-(PT_DTRACE >> 3)):16,er0)
+	btst	#(PT_DTRACE & 7),r1l		/* check for delayed trace */
+	beq	1f
+	sub.l	er2,er2
+	inc.l	#1,er2
+	mov.l	er0,er1
+	sub.l	er0,er0
+	mov.b	#LSIGTRAP,r0l
+	jsr	@SYMBOL_NAME(send_sig)		/* send_sig(LSIGTRAP,_current_task,1) */
+	mov.l	@SYMBOL_NAME(_current_task),er0
+1:
+	mov.l	@(state:16,er0),er1		/* state */
+	bne	SYMBOL_NAME(reschedule):16
+	mov.l	@(counter:16,er0),er1		/* counter */
+	beq	SYMBOL_NAME(reschedule):16
+	mov.l	@(sigpending:16,er0),er1
+	bne	Lsignal_return:16
+3:
+	RESTORE_ALL				/* Does RTE */
+
+Lsignal_return:
+	subs	#4, sp				/* dummy return PC */
+	SAVE_SWITCH_STACK
+	mov.l	sp,er1
+	add	#SWITCH_STACK_SIZE,er1
+	sub.l	er0,er0
+	jsr	@SYMBOL_NAME(do_signal)
+	RESTORE_SWITCH_STACK
+	adds	#4, sp				/* dummy return PC */
+	RESTORE_ALL
+
+SYMBOL_NAME_LABEL(reschedule)
+	/* save top of frame */
+	mov.l	sp,er0
+	jsr	@SYMBOL_NAME(set_esp0)
+
+	mov.l	#SYMBOL_NAME(ret_from_exception),er0
+	mov.l	er0,@-sp
+	jmp	@SYMBOL_NAME(schedule)
+
+SYMBOL_NAME_LABEL(resume)
+	/*
+	 *	er0 = prev
+	 *	er1 = next
+	 *	return last in er2
+	 */
+
+	/* save sr */
+	sub.w	r3,r3
+	stc	ccr,r3l
+	stc	exr,r3h
+	mov.w	r3,@((TASK_THREAD+THREAD_CCR):16,er0)
+	SAVE_SWITCH_STACK
+
+	/* disable interrupts */
+	orc	#0x80,ccr
+	mov.l	@SYMBOL_NAME(sw_usp),er3
+	mov.l	er3,@((TASK_THREAD+THREAD_USP):16,er0)
+	mov.l	sp,@((TASK_THREAD+THREAD_KSP):16,er0)
+	
+	/* get pointer to tss struct (er1 contains new task) */
+	mov.l   @SYMBOL_NAME(_current_task), er2
+	mov.l	er1,@SYMBOL_NAME(_current_task)
+
+	/* Skip address space switching if they are the same. */
+	/* FIXME: what did we hack out of here, this does nothing! */
+
+	mov.l	@((TASK_THREAD+THREAD_USP):16,er1),er0
+	mov.l	er0,@SYMBOL_NAME(sw_usp)
+	mov.l	@((TASK_THREAD+THREAD_KSP):16,er1),sp
+	RESTORE_SWITCH_STACK
+			
+	/* restore status register */
+	mov.w	@((TASK_THREAD+THREAD_CCR):16,er1),r3
+
+	ldc	r3l,ccr
+	ldc	r3h,exr
+	
+	rts
+
+SYMBOL_NAME_LABEL(trace_break)
+	subs	#4,sp			/* dummy LVEC */
+	SAVE_ALL
+	sub.l	er1,er1
+	dec.l	#1,er1
+	mov.l	er1,@(LORIG,sp)	
+	mov.l	sp,er0
+	jsr	@SYMBOL_NAME(set_esp0)
+	mov.l	@SYMBOL_NAME(sw_usp),er0
+	mov.l	@er0,er1
+	subs	#2,er1
+	mov.l	er1,@er0	
+	and.w	#0xff,e1
+	mov.l	er1,er0
+	jsr	@SYMBOL_NAME(trace_trap)
+	jmp	@SYMBOL_NAME(ret_from_exception)	
+
+SYMBOL_NAME_LABEL(syscall_trampoline)
+	SAVE_SWITCH_STACK
+	mov.l	er0,er6
+	mov.l	sp,er0
+	add.l	#SWITCH_STACK_SIZE,er0
+	jsr	@er6
+	RESTORE_SWITCH_STACK
+	rts
+
+#if defined(CONFIG_BLK_DEV_BLKMEM)
+/*
+	romfs move to __ebss
+	(used crt0)
+*/
+.globl	__move_romfs
+_romfs_sig_len = 8
+
+__move_romfs:	
+	mov.l	#__sbss,er0
+	mov.l	#_romfs_sig,er1
+	mov.b	#_romfs_sig_len,r3l
+1:					/* check romfs image */
+	mov.b	@er0+,r2l
+	mov.b	@er1+,r2h
+	cmp.b	r2l,r2h
+	bne	2f
+	dec.b	r3l
+	bne	1b
+
+	/* find romfs image */
+	mov.l	@__sbss+8,er0		/* romfs length(be) */
+	mov.l	#__sbss,er1
+	add.l	er0,er1			/* romfs image end */
+	mov.l	#__ebss,er2
+	add.l	er0,er2			/* distination address */
+	adds	#2,er0
+	adds	#1,er0
+	shlr	#2,er0			/* transfer length */
+1:
+	mov.l	@er1,er3		/* copy image */
+	mov.l	er3,@er2
+	subs	#4,er1
+	subs	#4,er2
+	dec.l	#1,er0
+	bpl	1b
+2:
+	rts
+
+	.section	.rodata
+_romfs_sig:	
+	.ascii	"-rom1fs-"
+#endif
+
+	.section	.bss
+SYMBOL_NAME_LABEL(sw_ksp)
+	.space	4	
+SYMBOL_NAME_LABEL(sw_usp)
+	.space	4	
diff -urN linux-2.4.29/arch/h8300/platform/h8s/generic/crt0_ram.S linux-2.4.29-uc1/arch/h8300/platform/h8s/generic/crt0_ram.S
--- linux-2.4.29/arch/h8300/platform/h8s/generic/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/generic/crt0_ram.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,128 @@
+/*
+ *  linux/arch/h8300/platform/h8s/edosk2674/crt0_ram.S
+ *
+ *  Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ *  Platform depend startup for uClinux-2.4.x
+ *  Target Archtecture:	generic
+ *  Memory Layout     :	RAM
+ */
+
+#define ASSEMBLY
+
+#include <linux/config.h>
+#include <asm/linkage.h>
+#include <asm/regs267x.h>
+			
+#if !defined(CONFIG_BLKDEV_RESERVE)
+#if defined(CONFIG_GDB_DEBUG)
+#define RAMEND (__ramend - 0xc000)
+#else
+#define RAMEND __ramend
+#endif
+#else
+#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
+#endif
+	
+	.global SYMBOL_NAME(_start)
+	.global SYMBOL_NAME(_command_line)
+	.global SYMBOL_NAME(_platform_gpio_table)
+	.global SYMBOL_NAME(_target_name)
+	
+	.h8300s
+
+	.section .text
+	.file	"crt0_ram.S"
+
+	/* CPU Reset entry */
+SYMBOL_NAME_LABEL(_start)
+	mov.l	#RAMEND,sp
+	ldc	#0x80,ccr
+
+	/* Peripheral Setup */
+	bclr	#4,@INTCR:8	/* interrupt mode 2 */
+	bset	#5,@INTCR:8
+
+#if defined(CONFIG_BLK_DEV_BLKMEM)
+	/* move romfs image */
+	jsr	@__move_romfs	
+#endif
+	
+	/* .bss clear */
+	mov.l	#__sbss,er5
+	mov.l	er5,er6
+	mov.l	#__ebss,er4
+	sub.l	er5,er4
+	shlr	#2,er4
+	sub.l	er0,er0
+1:	
+	mov.l	er0,@er5
+	adds	#4,er5
+	dec.l	#1,er4
+	bne	1b
+
+	/* copy kernel commandline */
+	mov.l	#COMMAND_START,er5
+	mov.l	#SYMBOL_NAME(command_line),er6
+	mov.w	#512,r4
+	eepmov.w
+
+	/* uClinux kernel start */
+	ldc	#0x90,ccr	/* running kernel */
+	mov.l	#SYMBOL_NAME(init_task_union),sp
+	mov.l	sp,@SYMBOL_NAME(_current_task)
+	add.l	#0x2000,sp
+	jsr	@_start_kernel
+_exit:
+
+	jmp	_exit
+
+	rts
+
+	/* I/O port assign information */
+__platform_gpio_table:	
+	mov.l	#gpio_table,er0
+	rts
+
+gpio_table:
+	;; P1DDR
+	;;      used,ddr
+	.byte	0x00,0x00
+	;; P2DDR
+	.byte	0x00,0x00
+	;; P3DDR
+	.byte	0x00,0x00
+	;; dummy
+	.byte	0x00,0x00
+	;; P5DDR
+	.byte	0x00,0x00
+	;; P6DDR
+	.byte	0x00,0x00
+	;; P7DDR
+	.byte	0x00,0x00
+	;; P8DDR
+	.byte	0x00,0x00
+	;; dummy
+	.byte	0x00,0x00
+	;; PADDR
+	.byte	0x00,0x00
+	;; PBDDR
+	.byte	0x00,0x00
+	;; PCDDR
+	.byte	0x00,0x00
+	;; PDDDR
+	.byte	0x00,0x00
+	;; PEDDR
+	.byte	0x00,0x00
+	;; PFDDR
+	.byte	0x00,0x00
+	;; PGDDR
+	.byte	0x00,0x00
+	;; PHDDR
+	.byte	0x00,0x00
+
+__target_name:	
+	.asciz	"generic"
+	
+	.section .bootvec,"ax"
+	jmp	@SYMBOL_NAME(_start)
diff -urN linux-2.4.29/arch/h8300/platform/h8s/generic/crt0_rom.S linux-2.4.29-uc1/arch/h8300/platform/h8s/generic/crt0_rom.S
--- linux-2.4.29/arch/h8300/platform/h8s/generic/crt0_rom.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/generic/crt0_rom.S	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,144 @@
+/*
+ *  linux/arch/h8300/platform/h8s/generic/crt0_rom.S
+ *
+ *  Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ *  Platform depend startup for uClinux-2.4.x
+ *  Target Archtecture:	generic
+ *  Memory Layout     :	ROM
+ */
+
+#define ASSEMBLY
+
+#include <linux/config.h>
+#include <asm/linkage.h>
+	
+#if !defined(CONFIG_BLKDEV_RESERVE)
+#if defined(CONFIG_GDB_DEBUG)
+#define RAMEND (__ramend - 0xc000)
+#else
+#define RAMEND __ramend
+#endif
+#else
+#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
+#endif
+	
+	.global SYMBOL_NAME(_start)
+	.global SYMBOL_NAME(_command_line)
+	.global SYMBOL_NAME(_platform_gpio_table)
+	.global SYMBOL_NAME(_target_name)
+	
+	.h8300s
+	.section .text
+	.file	"crt0_rom.S"
+
+#define INTCR 0xffff31
+	
+	/* CPU Reset entry */
+SYMBOL_NAME_LABEL(_start)
+	mov.l	#RAMEND,sp
+	ldc	#0x80,ccr
+	ldc	#0,exr
+	bclr	#4,@INTCR:8
+	bset	#5,@INTCR:8	/* Interrupt mode 2 */
+	
+	/* Peripheral Setup */
+	
+	/* .bss clear */
+	mov.l	#__sbss,er5
+	mov.l	er5,er6
+	inc.l	#1,er6
+	mov.l	#__ebss,er4
+	sub.l	er5,er4
+	sub.w	r0,r0
+	mov.b	r0l,@er5
+1:	
+	eepmov.w
+	dec.w	#1,e4
+	bpl	1b
+
+	/* copy .data */
+#if !defined(CONFIG_GDB_EXEC)
+	mov.l	#__begin_data,er5
+	mov.l	#__sdata,er6
+	mov.l	#__edata,er4
+	sub.l	er6,er4		
+1:	
+	eepmov.w	
+	dec.w	#1,e4
+	bpl	1b	
+#endif
+
+	/* copy kernel commandline */
+	mov.l	#COMMAND_START,er5
+	mov.l	#SYMBOL_NAME(_command_line),er6
+	mov.w	#512,r4
+	eepmov.w
+
+	/* uClinux kernel start */
+	ldc	#0x90,ccr	/* running kernel */
+	mov.l	#SYMBOL_NAME(init_task_union),sp
+	mov.l	sp,@SYMBOL_NAME(_current_task)
+	add.l	#0x2000,sp
+	jsr	@_start_kernel
+_exit:
+
+	jmp	_exit
+
+	rts
+
+	/* I/O port assign information */
+__platform_gpio_table:	
+	mov.l	#gpio_table,er0
+	rts
+
+gpio_table:
+	;; P1DDR
+	.byte	0x00,0x00
+	;; P2DDR
+	.byte	0x00,0x00
+	;; P3DDR
+	.byte	0x00,0x00
+	;; P4DDR
+	.byte	0x00,0x00
+	;; P5DDR
+	.byte	0x00,0x00
+	;; P6DDR
+	.byte	0x00,0x00
+	;; dummy
+	.byte	0x00,0x00
+	;; P8DDR
+	.byte	0x00,0x00
+	;; PADDR
+	.byte	0x00,0x00
+	;; PBDDR
+	.byte	0x00,0x00
+	;; PCDDR
+	.byte	0x00,0x00
+	;; PDDDR
+	.byte	0x00,0x00
+	;; PEDDR
+	.byte	0x00,0x00
+	;; PFDDR
+	.byte	0x00,0x00
+	;; PGDDR
+	.byte	0x00,0x00
+	;; PHDDR
+	.byte	0x00,0x00
+
+__target_name:	
+	.asciz	"generic"
+	
+	.section .bss
+__command_line:	
+	.space	512
+
+	/* interrupt vector */
+	.section .vectors,"ax"
+	.long	__start
+	.long	__start
+vector	=	2
+	.rept	128-2
+	.long	_interrupt_redirect_table+vector*4
+vector	=	vector + 1
+	.endr
diff -urN linux-2.4.29/arch/h8300/platform/h8s/generic/Makefile linux-2.4.29-uc1/arch/h8300/platform/h8s/generic/Makefile
--- linux-2.4.29/arch/h8300/platform/h8s/generic/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/generic/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,18 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+all: $(BOARD).o
+O_TARGET := $(BOARD).o
+obj-y := timer.o
+
+timer.o: timer.c
+
+clean:
+	rm -f *.[oa]
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/h8300/platform/h8s/generic/ram.ld linux-2.4.29-uc1/arch/h8300/platform/h8s/generic/ram.ld
--- linux-2.4.29/arch/h8300/platform/h8s/generic/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/generic/ram.ld	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,85 @@
+OUTPUT_ARCH(h8300s)
+ENTRY("__start")
+
+MEMORY 
+	{
+	ram    : ORIGIN = 0x400000, LENGTH = 0x800000
+	eram   : ORIGIN = 0x600000, LENGTH = 0
+	}
+
+SECTIONS
+{
+	.bootvec :
+	{
+	*(.bootvec)
+	} > ram
+        .text :
+	{
+		*(.int_redirect)
+	__stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+	. = ALIGN(0x4) ;
+		*(.exitcall.exit)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(0x4) ;
+		*(.rodata*)
+	. = ALIGN(16);          /* Exception table              */
+	___start___ex_table = .;
+		*(__ex_table)
+	___stop___ex_table = .;
+
+        ___start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	___stop___ksymtab = .;
+
+	. = ALIGN(0x4) ;
+	__etext = . ;
+	} > ram
+	.data :
+	{
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	__sdata = . ;
+	___data_start = . ;
+
+	. = ALIGN(0x4) ;
+		*(.data)
+	. = ALIGN(0x4) ;
+        ___init_begin = .;
+	        *(.text.init)
+	        *(.data.init)
+        . = ALIGN(16);
+	___setup_start = .;
+		*(.setup.init)
+	. = ALIGN(0x4) ;
+	___setup_end = .;
+	. = ALIGN(0x4) ;
+	___initcall_start = .;
+		*(.initcall.init)
+	. = ALIGN(0x4) ;
+	___initcall_end = .;
+        ___init_end = .;
+	__edata = . ;
+	} > ram
+	__begin_data = LOADADDR(.data) ;
+        .bss :
+        {
+	. = ALIGN(0x4) ;
+	__sbss = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	__ebss = . ;
+	__end = . ;
+	__ramstart = .;
+	} > ram
+        .dummy :
+        {
+        COMMAND_START = . - 0x200 ;
+	__ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/h8300/platform/h8s/generic/rom.ld linux-2.4.29-uc1/arch/h8300/platform/h8s/generic/rom.ld
--- linux-2.4.29/arch/h8300/platform/h8s/generic/rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/generic/rom.ld	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,100 @@
+OUTPUT_ARCH(h8300s)
+ENTRY("__start")
+
+INPUT(rootimage.o)
+
+MEMORY 
+	{
+	vector : ORIGIN = 0x000000, LENGTH = 0x000200
+	rom    : ORIGIN = 0x000200, LENGTH = 0x200000-0x000200
+	erom   : ORIGIN = 0x200000, LENGTH = 0
+	ram    : ORIGIN = 0x200000, LENGTH = 0x100000
+	eram   : ORIGIN = 0x2fa000, LENGTH = 0
+	}
+
+SECTIONS
+{
+	.vectors :
+	{
+	__vector = . ;
+		*(.vectors*)
+	} > vector
+        .text :
+	{
+		*(.int_redirect)
+	__stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+	. = ALIGN(0x4) ;
+		*(.exitcall.exit)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(0x4) ;
+		*(.rodata*)
+	. = ALIGN(16);          /* Exception table              */
+	___start___ex_table = .;
+		*(__ex_table)
+	___stop___ex_table = .;
+
+        ___start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	___stop___ksymtab = .;
+
+	. = ALIGN(0x4) ;
+	__etext = . ;
+	} > rom
+	.data : AT( ADDR(.text)+SIZEOF(.text))
+	{
+	__sdata = . ;
+	___data_start = . ;
+
+	. = ALIGN(0x4) ;
+		*(.data)
+	. = ALIGN(0x4) ;
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+        ___init_begin = .;
+	        *(.text.init)
+	        *(.data.init)
+        . = ALIGN(16);
+	___setup_start = .;
+		*(.setup.init)
+	. = ALIGN(0x4) ;
+	___setup_end = .;
+	. = ALIGN(0x4) ;
+	___initcall_start = .;
+		*(.initcall.init)
+	. = ALIGN(0x4) ;
+	___initcall_end = .;
+        ___init_end = .;
+	__edata = . ;
+	} > ram
+	__begin_data = LOADADDR(.data) ;
+	.blkimg : AT( LOADADDR(.data) + SIZEOF(.data))
+	{
+	__blkimg = . ;
+		*(.rootimg*)
+	} > rom
+	.erom :
+	{
+	__erom = . ;
+	} > erom
+        .bss :
+        {
+	. = ALIGN(0x4) ;
+	__sbss = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	__ebss = . ;
+	__end = . ;
+	__ramstart = .;
+	} > ram
+        .dummy :
+        {
+        COMMAND_START = . - 0x200 ;
+	__ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/h8300/platform/h8s/generic/timer.c linux-2.4.29-uc1/arch/h8300/platform/h8s/generic/timer.c
--- linux-2.4.29/arch/h8300/platform/h8s/generic/timer.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/generic/timer.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ *  linux/arch/h8300/platform/h8s/generic/timer.c
+ *
+ *  Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ *  Platform depend Timer Handler
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/timex.h>
+
+#define CMFA 6
+
+int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *))
+{
+	outb(CONFIG_CLK_FREQ*10/8192,_8TCORA1);
+	outb(0x00,_8TCSR1);
+	request_irq(76,timer_int,0,"timer",0);
+	outb(0x40|0x08|0x03,_8TCR1);
+	return 0;
+}
+
+void platform_timer_eoi(void)
+{
+        *(unsigned char *)_8TCSR1 &= ~(1 << CMFA);
+}
+
+void platform_gettod(int *year, int *mon, int *day, int *hour,
+		 int *min, int *sec)
+{
+	*year = *mon = *day = *hour = *min = *sec = 0;
+}
+
+#define CNT_PER_USEC (1000000 / (CONFIG_CLK_FREQ * 1000 / 8192))
+unsigned long platform_get_usec(void)
+{
+	return inb(_8TCNT1) * CNT_PER_USEC;
+}
diff -urN linux-2.4.29/arch/h8300/platform/h8s/ints_h8s.c linux-2.4.29-uc1/arch/h8300/platform/h8s/ints_h8s.c
--- linux-2.4.29/arch/h8300/platform/h8s/ints_h8s.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/ints_h8s.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,102 @@
+/*
+ * linux/arch/h8300/platform/h8s/ints_h8s.c
+ * Interrupt handling CPU variants
+ *
+ * Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+
+#include <asm/ptrace.h>
+#include <asm/traps.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/regs267x.h>
+
+/* saved vector list */
+const int __initdata h8300_saved_vectors[]={
+#if defined(CONFIG_GDB_DEBUG)
+	TRACE_VEC,
+	TRAP3_VEC,
+#endif
+	-1
+};
+
+/* trap entry table */
+const unsigned long __initdata h8300_trap_table[NR_TRAPS]={
+	0,0,0,0,0,
+	(unsigned long)trace_break,  /* TRACE */
+	0,0,
+	(unsigned long)system_call,  /* TRAPA #0 */
+	0,0,0,0,0,0,0
+};
+
+/* IRQ pin assignment */
+struct irq_pins {
+	unsigned char port_no;
+	unsigned char bit_no;
+};
+/* ISTR = 0 */
+const static struct irq_pins irq_assign_table0[16]={
+        {H8300_GPIO_P5,H8300_GPIO_B0},{H8300_GPIO_P5,H8300_GPIO_B1},
+	{H8300_GPIO_P5,H8300_GPIO_B2},{H8300_GPIO_P5,H8300_GPIO_B3},
+	{H8300_GPIO_P5,H8300_GPIO_B4},{H8300_GPIO_P5,H8300_GPIO_B5},
+	{H8300_GPIO_P5,H8300_GPIO_B6},{H8300_GPIO_P5,H8300_GPIO_B7},
+	{H8300_GPIO_P6,H8300_GPIO_B0},{H8300_GPIO_P6,H8300_GPIO_B1},
+	{H8300_GPIO_P6,H8300_GPIO_B2},{H8300_GPIO_P6,H8300_GPIO_B3},
+	{H8300_GPIO_P6,H8300_GPIO_B4},{H8300_GPIO_P6,H8300_GPIO_B5},
+	{H8300_GPIO_PF,H8300_GPIO_B1},{H8300_GPIO_PF,H8300_GPIO_B2},
+};
+/* ISTR = 1 */
+const static struct irq_pins irq_assign_table1[16]={
+	{H8300_GPIO_P8,H8300_GPIO_B0},{H8300_GPIO_P8,H8300_GPIO_B1},
+	{H8300_GPIO_P8,H8300_GPIO_B2},{H8300_GPIO_P8,H8300_GPIO_B3},
+	{H8300_GPIO_P8,H8300_GPIO_B4},{H8300_GPIO_P8,H8300_GPIO_B5},
+	{H8300_GPIO_PH,H8300_GPIO_B2},{H8300_GPIO_PH,H8300_GPIO_B3},
+	{H8300_GPIO_P2,H8300_GPIO_B0},{H8300_GPIO_P2,H8300_GPIO_B1},
+	{H8300_GPIO_P2,H8300_GPIO_B2},{H8300_GPIO_P2,H8300_GPIO_B3},
+	{H8300_GPIO_P2,H8300_GPIO_B4},{H8300_GPIO_P2,H8300_GPIO_B5},
+	{H8300_GPIO_P2,H8300_GPIO_B6},{H8300_GPIO_P2,H8300_GPIO_B7},
+};
+
+int h8300_enable_irq_pin(unsigned int irq)
+{
+	if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) {
+		unsigned short ptn = 1 << (irq - EXT_IRQ0);
+		unsigned int port_no,bit_no;
+		if (*(volatile unsigned short *)ITSR & ptn) {
+			port_no = irq_assign_table1[irq - EXT_IRQ0].port_no;
+			bit_no = irq_assign_table1[irq - EXT_IRQ0].bit_no;
+		} else {
+			port_no = irq_assign_table0[irq - EXT_IRQ0].port_no;
+			bit_no = irq_assign_table0[irq - EXT_IRQ0].bit_no;
+		}
+		if (H8300_GPIO_RESERVE(port_no, bit_no) == 0)
+			return -EBUSY;                   /* pin already use */
+		H8300_GPIO_DDR(port_no, bit_no, H8300_GPIO_INPUT);
+		*(volatile unsigned short *)ISR &= ~ptn; /* ISR clear */
+	}		
+	return 0;
+}
+
+void h8300_disable_irq_pin(unsigned int irq)
+{
+	if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) {
+		/* disable interrupt & release IRQ pin */
+		unsigned short port_no,bit_no;
+		*(volatile unsigned short *)ISR &= ~(1 << (irq - EXT_IRQ0));
+		*(volatile unsigned short *)IER &= ~(1 << (irq - EXT_IRQ0));
+		if (*(volatile unsigned short *)ITSR & (1 << (irq - EXT_IRQ0))) {
+			port_no = irq_assign_table1[irq - EXT_IRQ0].port_no;
+			bit_no = irq_assign_table1[irq - EXT_IRQ0].bit_no;
+		} else {
+			port_no = irq_assign_table0[irq - EXT_IRQ0].port_no;
+			bit_no = irq_assign_table0[irq - EXT_IRQ0].bit_no;
+		}
+		H8300_GPIO_FREE(port_no, bit_no);
+	}
+}
diff -urN linux-2.4.29/arch/h8300/platform/h8s/Makefile linux-2.4.29-uc1/arch/h8300/platform/h8s/Makefile
--- linux-2.4.29/arch/h8300/platform/h8s/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,22 @@
+#
+# Makefile for the linux kernel.
+#
+# Reuse any files we can from the H8/300H
+#
+
+#VPATH := $(VPATH):$(BOARD)
+
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: platform.o $(BOARD)/crt0_$(MODEL).o
+O_TARGET := platform.o
+obj-y := entry.o ints_h8s.o ptrace_h8s.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/h8300/platform/h8s/ptrace_h8s.c linux-2.4.29-uc1/arch/h8300/platform/h8s/ptrace_h8s.c
--- linux-2.4.29/arch/h8300/platform/h8s/ptrace_h8s.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/ptrace_h8s.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,84 @@
+/*
+ *  linux/arch/h8300/platform/h8s/ptrace_h8s.c
+ *    ptrace cpu depend helper functions
+ *
+ *  Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+#define CCR_MASK  0x6f
+#define EXR_TRACE 0x80
+
+/* Mapping from PT_xxx to the stack offset at which the register is
+   saved.  Notice that usp has no stack-slot and needs to be treated
+   specially (see get_reg/put_reg below). */
+static const int h8300_register_offset[] = {
+	PT_REG(er1), PT_REG(er2), PT_REG(er3), PT_REG(er4),
+	PT_REG(er5), SW_REG(er6), PT_REG(er0), PT_REG(orig_er0),
+	PT_REG(ccr), PT_REG(pc),  0,           PT_REG(exr)
+};
+
+/* read register */
+long h8300_get_reg(struct task_struct *task, int regno)
+{
+	switch (regno) {
+	case PT_USP:
+		return task->thread.usp + sizeof(long)*2 + 2;
+	case PT_CCR:
+	case PT_EXR:
+		return *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]);
+	default:
+		printk("get_reg %d=%08x\n",regno,*(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]));
+		return *(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]);
+	}
+}
+
+/* write register */
+int h8300_put_reg(struct task_struct *task, int regno, unsigned long data)
+{
+	unsigned short oldccr;
+	switch (regno) {
+	case PT_USP:
+		task->thread.usp = data - sizeof(long)*2 - 2;
+	case PT_CCR:
+		oldccr = *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]);
+		oldccr &= ~CCR_MASK;
+		data &= CCR_MASK;
+		data |= oldccr;
+		*(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]) = data;
+		break;
+	case PT_EXR:
+		/* exr modify not support */
+		return -EIO;
+	default:
+		*(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]) = data;
+		break;
+	}
+	return 0;
+}
+
+/* disable singlestep */
+void h8300_disable_trace(struct task_struct *child)
+{
+	*(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) &= ~EXR_TRACE;
+}
+
+/* enable singlestep */
+void h8300_enable_trace(struct task_struct *child)
+{
+	*(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) |= EXR_TRACE;
+}
+
+asmlinkage void trace_trap(unsigned long bp)
+{
+	(void)bp;
+	force_sig(SIGTRAP,current);
+}
+
diff -urN linux-2.4.29/arch/h8300/platform/h8s/Rules.make linux-2.4.29-uc1/arch/h8300/platform/h8s/Rules.make
--- linux-2.4.29/arch/h8300/platform/h8s/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/platform/h8s/Rules.make	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,59 @@
+#
+# h8s/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 2001		Lineo, Inc, <www.lineo.com>
+# Copyright (c) 2000,2001	D. Jeff Dionne <jeff@uClinux.org>
+# Copyright (c) 1998,1999	D. Jeff Dionne <jeff@uclinux.org>
+# Copyright (C) 1998		Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 		Hamish Macdonald
+#
+# 68VZ328 Fixes By		Evan Stawnyczy <e@lineo.ca>
+# H8S Modify By                 Yoshinori Sato <ysato@users.sourceforge.jp>
+
+CROSS_COMPILE = h8300-linux-elf-
+
+LIBGCC := $(shell $(CC) -print-libgcc-file-name -ms -mint32)
+
+CFLAGS := -fno-builtin -DNO_CACHE $(CFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -ms -mint32 \
+          -D__ELF__ -DNO_FORGET -DUTS_SYSNAME=\"uClinux\" -D__linux__ -DTARGET=$(BOARD)
+ifndef CONFIG_FULLDEBUG
+# Because inline function is not expand, add "-finline-limit-n"
+CFLAGS += -Os -finline-limit-50000
+endif
+ifdef CONFIG_BINFMT_SHARED_FLAT
+CFLAGS += -DMAGIC_ROM_PTR
+endif
+AFLAGS := $(AFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -ms -D__ELF__ -DUTS_SYSNAME=\"uClinux\"
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld -relax
+LDFLAGS := $(LDFLAGS) -mh8300self
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) \
+  	   arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD) \
+           $(SUBDIRS)
+
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/platform.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(BOARD).o \
+	      $(CORE_FILES)
+
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+linux.bin: linux
+	$(OBJCOPY) -O binary linux linux.bin
+	
+linux.srec: linux
+	$(OBJCOPY) -O srec linux linux.srec
+	
+archclean:
+	rm -f linux{.bin,.srec,}
diff -urN linux-2.4.29/arch/h8300/README linux-2.4.29-uc1/arch/h8300/README
--- linux-2.4.29/arch/h8300/README	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/README	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,35 @@
+uClinux-2.4 for H8/300 README
+Yoshinori Sato <ysato@users.sourceforge.jp>
+
+* Supported CPU
+H8/300H
+H8S is planning.
+
+* Supported Target
+1.simulator of GDB
+  require patches.
+
+2.AE 3068/AE 3069
+  more information 
+  MICROTRONIQUE <http://www.microtronique.com/>
+  Akizuki Denshi Tsusho Ltd. <http://www.akizuki.ne.jp> (Japanese Only)
+
+3.H8MAX 
+  Under development
+  see http://www.strawbelly-linux.com (Japanese Only)
+
+* Toolchain Version
+gcc-3.1 or higher and patch
+see arch/h8300/tools_patch/README
+binutils-2.12 or higher
+gdb-5.2 or higher
+The environment that can compile a h8300-elf binary is necessary.
+
+* Userland Develop enviroment
+Tempolary used h8300-hms(h8300-coff) Toolchain.
+I prepare toolchain corresponding to h8300-elf.
+
+* A few words of thanks
+Porting to H8/300H is support of Information-technology Promotion Agency, Japan.
+I thank support.
+and All developer/user.
diff -urN linux-2.4.29/arch/h8300/target_config.in linux-2.4.29-uc1/arch/h8300/target_config.in
--- linux-2.4.29/arch/h8300/target_config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/target_config.in	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,43 @@
+# uClinux H8/300 Target Board Selection Menu
+
+define_bool CONFIG_H83068 n
+define_bool CONFIG_H8S2768 n
+
+choice 'Target Board' \
+	"generic	                     CONFIG_BOARD_GENERIC \
+	 Akizuki_H8/3068_Network_Board       CONFIG_BOARD_AKI3068NET \
+	 H8MAX                               CONFIG_BOARD_H8MAX \
+	 HMSE_EDOSK-2674R                    CONFIG_BOARD_EDOSK2674" generic
+
+if [ "$CONFIG_BOARD_AKI3068NET" = "y" ]; then
+  define_bool CONFIG_H83068 y
+  define_int  CONFIG_CLK_FREQ 20000
+  define_bool CONFIG_RAMKERNEL y
+  define_hex  CONFIG_NE_BASE 0x200000
+  define_int  CONFIG_NE_IRQ  5
+  define_bool CONFIG_H8300_DMAMEMCPY n
+  define_bool CONFIG_BOARD_H8MAX n
+  define_bool CONFIG_BOARD_EDOSK2674 n
+fi
+
+if [ "$CONFIG_BOARD_H8MAX" = "y" ]; then
+  define_bool CONFIG_H83068 y
+  define_int  CONFIG_CLK_FREQ 25000
+  define_bool CONFIG_RAMKERNEL y
+  define_hex  CONFIG_NE_BASE 0x800600
+  define_int  CONFIG_NE_IRQ  4
+  define_bool CONFIG_H8300_DMAMEMCPY y
+  define_bool CONFIG_BOARD_AKI3068NET n
+  define_bool CONFIG_BOARD_EDOSK2674 n
+fi
+
+if [ "$CONFIG_BOARD_EDOSK2674" = "y" ]; then
+  define_bool CONFIG_H8S2678 y
+  define_int  CONFIG_CLK_FREQ 33000
+  choice 'Kernel executes from' \
+	"RAM	CONFIG_RAMKERNEL \
+	 ROM	CONFIG_ROMKERNEL" ROM
+  define_bool CONFIG_BOARD_AKI3068NET n
+  define_bool CONFIG_BOARD_H8MAX n
+fi
+
diff -urN linux-2.4.29/arch/h8300/tools_patch/gcc.diff linux-2.4.29-uc1/arch/h8300/tools_patch/gcc.diff
--- linux-2.4.29/arch/h8300/tools_patch/gcc.diff	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/tools_patch/gcc.diff	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,278 @@
+diff -Nru gcc-3.1.1/gcc/config/float-h8300.h gcc-3.1.1.dblfix/gcc/config/float-h8300.h
+--- gcc-3.1.1/gcc/config/float-h8300.h	Thu Jan  1 09:00:00 1970
++++ gcc-3.1.1.dblfix/gcc/config/float-h8300.h	Mon Sep 23 00:40:52 2002
+@@ -0,0 +1,128 @@
++/* float.h for target h8300-elf with optional IEEE 32 bit double format: based float-sh.h */
++#ifndef _FLOAT_H_
++#define _FLOAT_H_
++#include "config/h8300/h8300.h"
++
++/* Produced by enquire version 4.3, CWI, Amsterdam */
++
++   /* Radix of exponent representation */
++#undef FLT_RADIX
++#define FLT_RADIX 2
++   /* Number of base-FLT_RADIX digits in the significand of a float */
++#undef FLT_MANT_DIG
++#define FLT_MANT_DIG 24
++   /* Number of decimal digits of precision in a float */
++#undef FLT_DIG
++#define FLT_DIG 6
++   /* Addition rounds to 0: zero, 1: nearest, 2: +inf, 3: -inf, -1: unknown */
++#undef FLT_ROUNDS
++#define FLT_ROUNDS 1
++   /* Difference between 1.0 and the minimum float greater than 1.0 */
++#undef FLT_EPSILON
++#define FLT_EPSILON 1.19209290e-07F
++   /* Minimum int x such that FLT_RADIX**(x-1) is a normalised float */
++#undef FLT_MIN_EXP
++#define FLT_MIN_EXP (-125)
++   /* Minimum normalised float */
++#undef FLT_MIN
++#define FLT_MIN 1.17549435e-38F
++   /* Minimum int x such that 10**x is a normalised float */
++#undef FLT_MIN_10_EXP
++#define FLT_MIN_10_EXP (-37)
++   /* Maximum int x such that FLT_RADIX**(x-1) is a representable float */
++#undef FLT_MAX_EXP
++#define FLT_MAX_EXP 128
++   /* Maximum float */
++#undef FLT_MAX
++#define FLT_MAX 3.40282347e+38F
++   /* Maximum int x such that 10**x is a representable float */
++#undef FLT_MAX_10_EXP
++#define FLT_MAX_10_EXP 38
++
++   /* Number of base-FLT_RADIX digits in the significand of a double */
++#undef DBL_MANT_DIG
++#define DBL_MANT_DIG (DOUBLE_TYPE_SIZE == 64?53:24)
++   /* Number of decimal digits of precision in a double */
++#undef DBL_DIG
++#define DBL_DIG (DOUBLE_TYPE_SIZE == 64?15:6)
++   /* Difference between 1.0 and the minimum double greater than 1.0 */
++#undef DBL_EPSILON
++#define DBL_EPSILON (DOUBLE_TYPE_SIZE == 64?2.2204460492503131e-16:1.19209290e-07F)
++   /* Minimum int x such that FLT_RADIX**(x-1) is a normalised double */
++#undef DBL_MIN_EXP
++#define DBL_MIN_EXP (DOUBLE_TYPE_SIZE == 64?(-1021):(-125))
++   /* Minimum normalised double */
++#undef DBL_MIN
++#define DBL_MIN (DOUBLE_TYPE_SIZE == 64?2.2250738585072014e-308:1.17549435e-38F)
++   /* Minimum int x such that 10**x is a normalised double */
++#undef DBL_MIN_10_EXP
++#define DBL_MIN_10_EXP (DOUBLE_TYPE_SIZE == 64?(-307):(-37))
++   /* Maximum int x such that FLT_RADIX**(x-1) is a representable double */
++#undef DBL_MAX_EXP
++#define DBL_MAX_EXP (DOUBLE_TYPE_SIZE == 64?1024:128)
++   /* Maximum double */
++#undef DBL_MAX
++#define DBL_MAX (DOUBLE_TYPE_SIZE == 64?1.7976931348623157e+308:3.40282347e+38F)
++   /* Maximum int x such that 10**x is a representable double */
++#undef DBL_MAX_10_EXP
++#define DBL_MAX_10_EXP (DOUBLE_TYPE_SIZE == 64?308:38)
++
++/* Because -m3e and -m4-single-only have 32-bit doubles, we append L
++   to the doubles below, so that they're not truncated.  */
++
++   /* Number of base-FLT_RADIX digits in the significand of a long double */
++#undef LDBL_MANT_DIG
++#define LDBL_MANT_DIG (DOUBLE_TYPE_SIZE == 64?53:24)
++   /* Number of decimal digits of precision in a long double */
++#undef LDBL_DIG
++#define LDBL_DIG (DOUBLE_TYPE_SIZE == 64?15:6)
++   /* Difference between 1.0 and the minimum long double greater than 1.0 */
++#undef LDBL_EPSILON
++#define LDBL_EPSILON (DOUBLE_TYPE_SIZE == 64?2.2204460492503131e-16L:1.19209290e-07F)
++   /* Minimum int x such that FLT_RADIX**(x-1) is a normalised long double */
++#undef LDBL_MIN_EXP
++#define LDBL_MIN_EXP (DOUBLE_TYPE_SIZE == 64?(-1021):(-125))
++   /* Minimum normalised long double */
++#undef LDBL_MIN
++#define LDBL_MIN (DOUBLE_TYPE_SIZE == 64?2.2250738585072014e-308L:1.17549435e-38F)
++   /* Minimum int x such that 10**x is a normalised long double */
++#undef LDBL_MIN_10_EXP
++#define LDBL_MIN_10_EXP (DOUBLE_TYPE_SIZE == 64?(-307):(-37))
++   /* Maximum int x such that FLT_RADIX**(x-1) is a representable long double */
++#undef LDBL_MAX_EXP
++#define LDBL_MAX_EXP (DOUBLE_TYPE_SIZE == 64?1024:128)
++   /* Maximum long double */
++#undef LDBL_MAX
++#define LDBL_MAX (DOUBLE_TYPE_SIZE == 64?1.7976931348623157e+308L:3.40282347e+38F)
++   /* Maximum int x such that 10**x is a representable long double */
++#undef LDBL_MAX_10_EXP
++#define LDBL_MAX_10_EXP (DOUBLE_TYPE_SIZE == 64?308:38)
++
++#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
++   /* The floating-point expression evaluation method.
++        -1  indeterminate
++         0  evaluate all operations and constants just to the range and
++            precision of the type
++         1  evaluate operations and constants of type float and double
++            to the range and precision of the double type, evaluate
++            long double operations and constants to the range and
++            precision of the long double type
++         2  evaluate all operations and constants to the range and
++            precision of the long double type
++   */
++# undef FLT_EVAL_METHOD
++# define FLT_EVAL_METHOD	0
++
++   /* Number of decimal digits to enable rounding to the given number of
++      decimal digits without loss of precision.
++         if FLT_RADIX == 10^n:  #mantissa * log10 (FLT_RADIX)
++         else                :  ceil (1 + #mantissa * log10 (FLT_RADIX))
++      where #mantissa is the number of bits in the mantissa of the widest
++      supported floating-point type.
++   */
++# undef DECIMAL_DIG
++# define DECIMAL_DIG	17
++
++#endif	/* C99 */
++
++#endif /*  _FLOAT_H_ */
+diff -Nru gcc-3.1.1/gcc/config/h8300/extfloatlib.c gcc-3.1.1.dblfix/gcc/config/h8300/extfloatlib.c
+--- gcc-3.1.1/gcc/config/h8300/extfloatlib.c	Thu Jan  1 09:00:00 1970
++++ gcc-3.1.1.dblfix/gcc/config/h8300/extfloatlib.c	Sun Sep 22 23:06:11 2002
+@@ -0,0 +1,11 @@
++/* from /gcc/config/m68k/fpgnulib.c */
++
++/* convert float to int */
++long
++__fixdfsi (double a1);
++int
++__fixsfsi (float a1)
++{
++  double foo = a1;
++  return __fixdfsi (foo);
++}
+diff -Nru gcc-3.1.1/gcc/config/h8300/h8300.h gcc-3.1.1.dblfix/gcc/config/h8300/h8300.h
+--- gcc-3.1.1/gcc/config/h8300/h8300.h	Wed May 22 08:44:58 2002
++++ gcc-3.1.1.dblfix/gcc/config/h8300/h8300.h	Sun Sep 22 23:06:11 2002
+@@ -38,9 +38,12 @@
+ extern const char * const *h8_reg_names;
+ 
+ /* Names to predefine in the preprocessor for this target machine.  */
+-
++/*
+ #define CPP_PREDEFINES \
+ "-D__LONG_MAX__=2147483647L -D__LONG_LONG_MAX__=2147483647L"
++*/
++#define CPP_PREDEFINES \
++"-D__LONG_MAX__=2147483647L"
+ 
+ #define CPP_SPEC \
+   "%{!mh:%{!ms:-D__H8300__}} %{mh:-D__H8300H__} %{ms:-D__H8300S__} \
+@@ -51,6 +54,7 @@
+    %{mh:-Acpu=h8300h -Amachine=h8300h} \
+    %{ms:-Acpu=h8300s -Amachine=h8300s} \
+    %{!mint32:-D__INT_MAX__=32767} %{mint32:-D__INT_MAX__=2147483647} \
++   %{!mint32:-D__LONG_LONG_MAX__=2147483647L} %{mint32:-D__LONG_LONG_MAX__=9223372036854775807LL} \
+    %(subtarget_cpp_spec)"
+ 
+ #define SUBTARGET_CPP_SPEC ""
+@@ -220,9 +224,9 @@
+ #define SHORT_TYPE_SIZE	16
+ #define INT_TYPE_SIZE		(TARGET_INT32 ? 32 : 16)
+ #define LONG_TYPE_SIZE		32
+-#define LONG_LONG_TYPE_SIZE	32
++#define LONG_LONG_TYPE_SIZE	(TARGET_INT32 ? 64 : 32)
+ #define FLOAT_TYPE_SIZE	32
+-#define DOUBLE_TYPE_SIZE	32
++#define DOUBLE_TYPE_SIZE	(TARGET_INT32 ? 64 : 32)
+ #define LONG_DOUBLE_TYPE_SIZE	DOUBLE_TYPE_SIZE
+ 
+ #define MAX_FIXED_MODE_SIZE	32
+@@ -1337,4 +1341,20 @@
+ 
+ #define MOVE_RATIO 3
+ 
++#ifdef IN_LIBGCC2
++#undef LONG_LONG_TYPE_SIZE
++#undef DOUBLE_TYPE_SIZE
++#undef LONG_DOUBLE_TYPE_SIZE
++#if __INT_MAX__ == 32767
++#define DI SI
++#define DF SF
++#define LONG_LONG_TYPE_SIZE 32
++#define DOUBLE_TYPE_SIZE 32
++#else
++#define LONG_LONG_TYPE_SIZE 64
++#define DOUBLE_TYPE_SIZE 64
++#endif
++#define LONG_DOUBLE_TYPE_SIZE	DOUBLE_TYPE_SIZE
++#endif
++
+ #endif /* ! GCC_H8300_H */
+diff -Nru gcc-3.1.1/gcc/config/h8300/t-h8300 gcc-3.1.1.dblfix/gcc/config/h8300/t-h8300
+--- gcc-3.1.1/gcc/config/h8300/t-h8300	Fri Aug 31 02:51:04 2001
++++ gcc-3.1.1.dblfix/gcc/config/h8300/t-h8300	Sun Sep 22 23:06:11 2002
+@@ -5,25 +5,7 @@
+ LIB1ASMFUNCS = _cmpsi2 _ucmpsi2 _divhi3 _divsi3 _mulhi3 _mulsi3 \
+   _floatdisf _fixsfdi _fixunssfdi _fixunssfsi_asm
+ 
+-LIB2FUNCS_EXTRA = $(srcdir)/config/h8300/fixunssfsi.c
+-
+-# We do not have DF or DI types, so fake out the libgcc2 compilation.
+-TARGET_LIBGCC2_CFLAGS = -DDF=SF -DDI=SI
+-
+-# We want fine grained libraries, so use the new code to build the
+-# floating point emulation libraries.
+-FPBIT = fp-bit.c
+-
+-fp-bit.c: $(srcdir)/config/fp-bit.c
+-	echo '#define FLOAT' > fp-bit.c
+-	echo '#define FLOAT_ONLY' >> fp-bit.c
+-	echo '#define SMALL_MACHINE' >> fp-bit.c
+-	echo '#ifdef __H8300__' >> fp-bit.c
+-	echo '#define CMPtype HItype' >> fp-bit.c
+-	echo '#else' >> fp-bit.c
+-	echo '#define CMPtype SItype' >> fp-bit.c
+-	echo '#endif' >> fp-bit.c
+-	cat $(srcdir)/config/fp-bit.c >> fp-bit.c
++LIB2FUNCS_EXTRA = $(srcdir)/config/h8300/fixunssfsi.c $(srcdir)/floatlib.c $(srcdir)/config/h8300/extfloatlib.c
+ 
+ MULTILIB_OPTIONS = mh/ms mint32
+ MULTILIB_DIRNAMES = h8300h h8300s int32
+diff -Nru gcc-3.1.1/gcc/config.gcc gcc-3.1.1.dblfix/gcc/config.gcc
+--- gcc-3.1.1/gcc/config.gcc	Sat Jun  8 08:35:31 2002
++++ gcc-3.1.1.dblfix/gcc/config.gcc	Sun Sep 22 23:23:29 2002
+@@ -852,7 +852,7 @@
+ h8300-*-elf*)
+ 	tmake_file="h8300/t-h8300 h8300/t-elf"
+ 	tm_file="h8300/h8300.h h8300/elf.h"
+-	float_format=i32
++	float_format=h8300
+ 	;;
+ h8300-*-*)
+ 	float_format=i32
+diff -Nru gcc-3.1.1/gcc/cp/decl.c gcc-3.1.1.dblfix/gcc/cp/decl.c
+--- gcc-3.1.1/gcc/cp/decl.c	Wed Jul 10 08:46:07 2002
++++ gcc-3.1.1.dblfix/gcc/cp/decl.c	Sun Sep 22 23:06:11 2002
+@@ -3500,7 +3500,7 @@
+      except for any that we copy here from the old type.  */
+   DECL_ATTRIBUTES (newdecl)
+     = (*targetm.merge_decl_attributes) (olddecl, newdecl);
+-  decl_attributes (&newdecl, DECL_ATTRIBUTES (newdecl), 0);
++  /*decl_attributes (&newdecl, DECL_ATTRIBUTES (newdecl), 0);*/
+ 
+   if (TREE_CODE (newdecl) == TEMPLATE_DECL)
+     {
+diff -Nru gcc-3.1.1/gcc/floatlib.c gcc-3.1.1.dblfix/gcc/floatlib.c
+--- gcc-3.1.1/gcc/floatlib.c	Thu Oct 11 12:15:38 2001
++++ gcc-3.1.1.dblfix/gcc/floatlib.c	Sun Sep 22 23:06:11 2002
+@@ -430,13 +430,13 @@
+ float
+ __floatsisf (long a1)
+ {
+-    (float)__floatsidf(a1);
++    return (float)__floatsidf(a1);
+ }
+ 
+ float
+ __floatdisf (long long a1)
+ {
+-    (float)__floatdidf(a1);
++    return (float)__floatdidf(a1);
+ }
+ 
+ /* negate a float */
diff -urN linux-2.4.29/arch/h8300/tools_patch/gdd.diff linux-2.4.29-uc1/arch/h8300/tools_patch/gdd.diff
--- linux-2.4.29/arch/h8300/tools_patch/gdd.diff	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/tools_patch/gdd.diff	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,687 @@
+diff -Nru gdb-5.2.1/gdb/config/h8300/tm-h8300.h gdb-5.2.1.h8sim/gdb/config/h8300/tm-h8300.h
+--- gdb-5.2.1/gdb/config/h8300/tm-h8300.h	Tue Jan 29 13:42:36 2002
++++ gdb-5.2.1.h8sim/gdb/config/h8300/tm-h8300.h	Wed Sep 11 23:50:22 2002
+@@ -89,7 +89,7 @@
+ #define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+ 
+ /*#define BREAKPOINT {0x7A, 0xFF} */
+-#define BREAKPOINT {0x01, 0x80}	/* Sleep */
++#define BREAKPOINT {0x01, 0x81}	/* bkpt(?) */
+ #define REMOTE_BREAKPOINT { 0x57, 0x30}		/* trapa #3 */
+ /* If your kernel resets the pc after the trap happens you may need to
+    define this before including this file.    */
+diff -Nru gdb-5.2.1/include/opcode/h8300.h gdb-5.2.1.h8sim/include/opcode/h8300.h
+--- gdb-5.2.1/include/opcode/h8300.h	Mon Jan 21 23:03:26 2002
++++ gdb-5.2.1.h8sim/include/opcode/h8300.h	Wed Sep 11 23:50:22 2002
+@@ -304,7 +304,8 @@
+ #define O_LDM 85
+ #define O_STM 86
+ #define O_STMAC 87
+-#define O_LAST 88
++#define O_BKPT 88
++#define O_LAST 89
+ #define SB 0
+ #define SW 1
+ #define SL 2
+@@ -375,6 +376,8 @@
+   EBITOP(O(O_BTST,SB), IMM3|B30,"btst",0x6,0x3,0x7,0xC,0x7,0xE,0x0),
+   BITOP(O(O_BXOR,SB), IMM3|B30,"bxor",0x7,0x5,0x7,0xC,0x7,0xE,0x0),
+ 
++  SOP(O(O_BKPT,SN),2,"bkpt"),{{E,0,0}},{{ 0x0,0x1,0x8,0x1,E,0,0,0,0}} EOP,
++
+   TWOOP(O(O_CMP,SB), "cmp.b",0xA,0x1,0xC),
+   WTWOP(O(O_CMP,SW), "cmp.w",0x1,0xD),
+ 
+diff -Nru gdb-5.2.1/sim/h8300/Makefile.in gdb-5.2.1.h8sim/sim/h8300/Makefile.in
+--- gdb-5.2.1/sim/h8300/Makefile.in	Fri Apr 16 10:35:02 1999
++++ gdb-5.2.1.h8sim/sim/h8300/Makefile.in	Wed Sep 11 23:50:22 2002
+@@ -18,7 +18,7 @@
+ 
+ ## COMMON_PRE_CONFIG_FRAG
+ 
+-SIM_OBJS = compile.o sim-load.o
++SIM_OBJS = compile.o sim-load.o io.o
+ 
+ ## COMMON_POST_CONFIG_FRAG
+ 
+diff -Nru gdb-5.2.1/sim/h8300/compile.c gdb-5.2.1.h8sim/sim/h8300/compile.c
+--- gdb-5.2.1/sim/h8300/compile.c	Fri May 17 22:24:13 2002
++++ gdb-5.2.1.h8sim/sim/h8300/compile.c	Fri Oct 18 12:56:11 2002
+@@ -81,7 +81,7 @@
+ #define HIGH_BYTE(x) (((x) >> 8) & 0xff)
+ #define P(X,Y) ((X << 8) | Y)
+ 
+-#define BUILDSR()   cpu.ccr = (N << 3) | (Z << 2) | (V << 1) | C;
++#define BUILDSR()   cpu.ccr = (cpu.ccr & 0xf0) | (N << 3) | (Z << 2) | (V<<1) | C;
+ 
+ #define GETSR()		    \
+   c = (cpu.ccr >> 0) & 1;\
+@@ -319,6 +319,10 @@
+ 
+ 		  bit = thisnib;
+ 		}
++                else if (looking_for & (L_2 | IMM))
++		{
++		  plen = 1;
++                }  
+ 	      else if (looking_for == E)
+ 		{
+ 		  dst->op = q;
+@@ -443,7 +447,7 @@
+ 		  return;
+ 		}
+ 	      else
+-		printf ("Don't understand %x \n", looking_for);
++		printf ("Don't understand %x:%x \n", addr, looking_for);
+ 	    }
+ 
+ 	  len++;
+@@ -485,6 +489,8 @@
+   cpu.cache_idx[pc] = idx;
+ }
+ 
++extern int iosimulation(cpu_state_type *cpu,int cycles);
++extern void init_ioregs(cpu_state_type *cpu);
+ 
+ static unsigned char *breg[18];
+ static unsigned short *wreg[18];
+@@ -515,18 +521,33 @@
+   (x < memory_size ? (cpu.memory[x]) : (cpu.eightbit[x & 0xff]))
+ 
+ #define SET_MEMORY_L(x,y)  \
++if (x >= 0x100) \
+ {  register unsigned char *_p; register int __y = y; \
+    _p = (x < memory_size ? cpu.memory+x : cpu.eightbit + (x & 0xff)); \
+    _p[0] = (__y)>>24; _p[1] = (__y)>>16; \
+-   _p[2] = (__y)>>8; _p[3] = (__y)>>0;}
++   _p[2] = (__y)>>8; _p[3] = (__y)>>0;} \
++else \
++{ cpu.state = SIM_STATE_STOPPED; \
++  cpu.exception = SIGSEGV; \
++}
+ 
+ #define SET_MEMORY_W(x,y) \
++if (x >= 0x100) \
+ {  register unsigned char *_p; register int __y = y; \
+    _p = (x < memory_size ? cpu.memory+x : cpu.eightbit + (x & 0xff)); \
+-   _p[0] = (__y)>>8; _p[1] =(__y);}
++   _p[0] = (__y)>>8; _p[1] =(__y);} \
++else \
++{ cpu.state = SIM_STATE_STOPPED; \
++  cpu.exception = SIGSEGV; \
++}
+ 
+ #define SET_MEMORY_B(x,y) \
+-  (x < memory_size ? (cpu.memory[(x)] = y) : (cpu.eightbit[x & 0xff] = y))
++if (x >= 0x100) { \
++  (x < memory_size ? (cpu.memory[(x)] = y) : (cpu.eightbit[x & 0xff] = y)); \
++} else \
++{ cpu.state = SIM_STATE_STOPPED; \
++  cpu.exception = SIGSEGV; \
++}
+ 
+ int
+ fetch (arg, n)
+@@ -918,12 +939,13 @@
+   return 1;
+ }
+ 
++
+ void
+ sim_resume (sd, step, siggnal)
+      SIM_DESC sd;
+ {
+   static int init1;
+-  int cycles = 0;
++  static int cycles = 0;
+   int insts = 0;
+   int tick_start = get_now ();
+   void (*prev) ();
+@@ -936,6 +958,7 @@
+   int pc;
+   int c, nz, v, n;
+   int oldmask;
++  int vector;
+   init_pointers ();
+ 
+   prev = signal (SIGINT, control_c);
+@@ -994,6 +1017,15 @@
+ 
+ #endif
+ 
++      if ((vector=iosimulation(&cpu,cycles)) && !(cpu.ccr & 0x80)) 
++	{
++	  BUILDSR();
++          cpu.regs[7]-=4;
++          SET_MEMORY_L(cpu.regs[7],(cpu.ccr<<24)|pc);
++          pc=GET_MEMORY_L(vector*(h8300hmode?4:2));
++          cpu.ccr|=0x80;
++          goto top;
++        }
+       if (code->opcode)
+        {
+         cycles += code->cycles;
+@@ -1066,12 +1098,21 @@
+ 
+ 	case O (O_MOV_TO_MEM, SB):
+ 	  res = GET_B_REG (code->src.reg);
++	  if ( (code->dst.type == X (OP_DEC, SB)) &&
++	       (code->src.reg == code->dst.reg))
++	    res -= 1;
+ 	  goto log8;
+ 	case O (O_MOV_TO_MEM, SW):
+ 	  res = GET_W_REG (code->src.reg);
++	  if ( (code->dst.type == X (OP_DEC, SW)) &&
++	       (code->src.reg == code->dst.reg))
++	    res -= 2;
+ 	  goto log16;
+ 	case O (O_MOV_TO_MEM, SL):
+ 	  res = GET_L_REG (code->src.reg);
++	  if ( (code->dst.type == X (OP_DEC, SL)) &&
++	       (code->src.reg == code->dst.reg))
++	    res -= 4;
+ 	  goto log32;
+ 
+ 
+@@ -1355,6 +1396,7 @@
+ 	  cpu.state = SIM_STATE_STOPPED;
+ 	  cpu.exception = SIGILL;
+ 	  goto end;
++#if 0
+ 	case O (O_SLEEP, SN):
+ 	  /* FIXME: Doesn't this break for breakpoints when r0
+ 	     contains just the right (er, wrong) value?  */
+@@ -1368,6 +1410,29 @@
+ 	  else
+ 	    cpu.exception = SIGTRAP;
+ 	  goto end;
++#endif
++#define SIM_WIFEXITED(v) (((v) & 0xff) == 0)
++#define SIM_WIFSIGNALED(v) (((v) & 0x7f) > 0 && (((v) & 0x7f) < 0x7f))
++  	case O (O_SLEEP, SN):
++          if (cpu.ccr & 0x80)
++  	    {
++  	      cpu.state = SIM_STATE_STOPPED;
++              cpu.exception = SIGTRAP;
++            } else 
++	    while (cpu.state = SIM_STATE_RUNNING) {
++              if ((vector=iosimulation(&cpu,cycles)) && !(cpu.ccr & 0x80)) 
++	        {
++		  usleep(100);
++	          BUILDSR();
++                  cpu.regs[7]-=4;
++                  SET_MEMORY_L(cpu.regs[7],(cpu.ccr<<24)|pc+2);
++                  pc=GET_MEMORY_L(vector*(h8300hmode?4:2));
++                  cpu.ccr|=0x80;
++                  goto top;
++                }
++	      cycles++;
++ 	    }
++  	  goto end;
+ 	case O (O_BPT, SN):
+ 	  cpu.state = SIM_STATE_STOPPED;
+ 	  cpu.exception = SIGTRAP;
+@@ -1528,7 +1593,143 @@
+ 	      }
+ 	  }
+ 	  goto next;
+-
++	case O (O_LDC, SB):
++	  {
++	    switch(GET_MEMORY_B(pc)) {
++	    case 0x03:
++	      cpu.ccr = GET_B_REG(code->src.reg);
++	      break;
++	    case 0x07:
++	      cpu.ccr = code->src.literal;
++	      break;
++	    case 0x01:
++	      {
++		switch(GET_MEMORY_B(pc+2)) {
++		case 0x69:
++		  cpu.ccr = GET_MEMORY_W(GET_L_REG(code->dst.reg));
++		  break;
++		case 0x6f:
++		case 0x78:
++		  code->src.type=X(OP_DISP,SW);
++		  cpu.ccr = fetch (&code->src);
++		  break;
++		case 0x6d:
++		  code->src.type=X(OP_INC,SW);
++		  cpu.ccr = fetch (&code->src);
++		break;
++		case 0x6b:
++		  cpu.ccr = GET_MEMORY_W(code->src.literal);
++		  break;
++		}
++	      }
++	    }
++	    GETSR();
++	  }
++	  goto next;
++	case O (O_STC, SB):
++	  {
++	    BUILDSR();
++	    switch(GET_MEMORY_B(pc)) {
++	    case 0x02:
++	      SET_B_REG(code->dst.reg,cpu.ccr);
++	      break;
++	    case 0x01:
++	      switch(GET_MEMORY_B(pc+2)) {
++	      case 0x69:
++		SET_MEMORY_W(GET_L_REG(code->dst.reg),cpu.ccr);
++		break;
++	      case 0x6f:
++	      case 0x78:
++		code->dst.type=X(OP_DISP,SW);
++		store (&code->dst,cpu.ccr);
++		break;
++	      case 0x6d:
++		code->dst.type=X(OP_DEC,SW);
++		store (&code->dst,cpu.ccr);
++		break;
++	      case 0x6b:
++		SET_MEMORY_W(code->dst.literal,cpu.ccr);
++		break;
++	      }
++	    }	  
++	  }
++	  goto next;
++	case O (O_EEPMOV, SB):
++	  {
++            int cnt=GET_B_REG(4);
++	    if(cnt==0) cnt=0x100; 
++	    while(cnt!=0) {
++	      SET_MEMORY_B(cpu.regs[6],GET_MEMORY_B(cpu.regs[5]));
++	      cpu.regs[5]++;
++	      cpu.regs[6]++;
++	      --cnt;
++	    }
++	    SET_B_REG(4,cnt);
++	  }
++	  goto next;
++	case O (O_EEPMOV, SW):
++	  {
++            int cnt=GET_W_REG(4);
++	    if(cnt==0) cnt=0x10000; 
++	    while(cnt!=0) {
++	      SET_MEMORY_B(cpu.regs[6],GET_MEMORY_B(cpu.regs[5]));
++	      cpu.regs[5]++;
++	      cpu.regs[6]++;
++	      --cnt;
++	    }
++	    SET_W_REG(4,cnt);
++	  }
++	  goto next;
++	case O (O_RTE, SN):
++	  {
++            unsigned int frame;
++            frame  = GET_MEMORY_L (cpu.regs[7]);
++            cpu.ccr=frame>>24;
++            GETSR();
++            pc=frame & 0xffffff;
++	    cpu.regs[7]+=4;
++	  };
++          goto end;
++	case O (O_TRAPA, SB):
++	  {
++	    int v;
++	    v=GET_MEMORY_W(pc)>>4;
++            v&=3;
++ 	    BUILDSR();
++            cpu.regs[7]-=4;
++            SET_MEMORY_L(cpu.regs[7],(cpu.ccr<<24)|code->next_pc);
++            pc=GET_MEMORY_L(v*(h8300hmode?4:2)+0x08*(h8300hmode?4:2));
++            cpu.ccr|=0x80;
++          };
++          goto end;
++	case O (O_BKPT, SN):
++	  /* The format of r0 is defined by devo/include/wait.h.  */
++#if 0 /* FIXME: Ugh.  A breakpoint is the sleep insn.  */
++	  if (WIFEXITED (cpu.regs[0]))
++	    {
++	      cpu.state = SIM_STATE_EXITED;
++	      cpu.exception = WEXITSTATUS (cpu.regs[0]);
++	    }
++	  else if (WIFSTOPPED (cpu.regs[0]))
++	    {
++	      cpu.state = SIM_STATE_STOPPED;
++	      cpu.exception = WSTOPSIG (cpu.regs[0]);
++	    }
++	  else
++	    {
++	      cpu.state = SIM_STATE_SIGNALLED;
++	      cpu.exception = WTERMSIG (cpu.regs[0]);
++	    }
++#else
++	  /* FIXME: Doesn't this break for breakpoints when r0
++	     contains just the right (er, wrong) value?  */
++          cpu.state = SIM_STATE_STOPPED;
++	  if (! SIM_WIFEXITED (cpu.regs[0]) && SIM_WIFSIGNALED (cpu.regs[0]))
++	    cpu.exception = SIGILL;
++          else
++            cpu.exception = SIGTRAP;
++#endif
++	  goto end;
+ 	default:
+ 	  cpu.state = SIM_STATE_STOPPED;
+ 	  cpu.exception = SIGILL;
+@@ -2016,10 +2217,14 @@
+      char **argv;
+ {
+   /* FIXME: Much of the code in sim_load can be moved here.  */
++  char *ptyname;
+ 
+   sim_kind = kind;
+   myname = argv[0];
+   sim_callback = ptr;
++  if((ptyname=openpty())!=NULL) 
++    (*sim_callback->printf_filtered) (sim_callback,
++	  			      "SCI0 = %s\n",ptyname);
+   /* Fudge our descriptor.  */
+   return (SIM_DESC) 1;
+ }
+@@ -2030,6 +2235,7 @@
+      int quitting;
+ {
+   /* Nothing to do.  */
++  closepty();
+ }
+ 
+ /* Called by gdb to load a program into memory.  */
+@@ -2100,6 +2306,7 @@
+     abort ();
+   cpu.mask = memory_size - 1;
+ 
++  init_ioregs(&cpu);
+   if (sim_load_file (sd, myname, sim_callback, prog, prog_bfd,
+ 		     sim_kind == SIM_OPEN_DEBUG,
+ 		     0, sim_write)
+diff -Nru gdb-5.2.1/sim/h8300/inst.h gdb-5.2.1.h8sim/sim/h8300/inst.h
+--- gdb-5.2.1/sim/h8300/inst.h	Fri Apr 16 10:35:02 1999
++++ gdb-5.2.1.h8sim/sim/h8300/inst.h	Wed Sep 11 23:50:22 2002
+@@ -15,7 +15,7 @@
+    can only happen when simulating H8/300H programs).  We make no attempt
+    to catch overlapping addresses, wrapped addresses, etc etc.  */
+ #define H8300_MSIZE (1<<16)
+-#define H8300H_MSIZE (1<<18)
++#define H8300H_MSIZE (1<<24)
+ 
+ #define CSIZE 1000
+ 
+diff -Nru gdb-5.2.1/sim/h8300/io.c gdb-5.2.1.h8sim/sim/h8300/io.c
+--- gdb-5.2.1/sim/h8300/io.c	Thu Jan  1 09:00:00 1970
++++ gdb-5.2.1.h8sim/sim/h8300/io.c	Mon Sep 16 12:01:28 2002
+@@ -0,0 +1,272 @@
++/*
++ H8 simulator Internal Peripheral Support
++*/
++
++#include <unistd.h>
++#include <termios.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <sys/time.h>
++
++#include "inst.h"
++
++#define SMR (cpu->memory[0xffffb0])
++#define BRR (cpu->memory[0xffffb1])
++#define SCR (cpu->memory[0xffffb2])
++#define TDR (cpu->memory[0xffffb3])
++#define SSR (cpu->memory[0xffffb4])
++#define RDR (cpu->memory[0xffffb5])
++
++#define TCR 0
++#define TCSR 2
++#define TCORA 4
++#define TCORB 6
++#define TCNT 8
++
++static int scifd=-1;
++static struct termios old_attr;
++static unsigned char ssr=0;
++static unsigned char tcsr[4]={0x00,0x00,0x00,0x00};
++static int prescale[3]={8,64,8192};
++const int base[4]={0xffff80,0xffff81,0xffff90,0xffff91};
++const int prescale_div[3]={8,64,8192};
++static unsigned int prev_cycle=0;
++
++static void
++timer8(cpu_state_type *cpu,int cycles)
++{
++  int tm,cnt,cyc,pcnt;
++  cyc=(unsigned int)cycles-prev_cycle;
++  prev_cycle=cycles;
++  for (pcnt = 0; pcnt < 3; pcnt++) {
++    prescale[pcnt] -= cyc;
++    if (prescale[pcnt]<=0) 
++    {
++      for(tm=0;tm<4;tm++) {
++	tcsr[tm] &= (cpu->memory[base[tm]+TCSR] & 0xe0);
++        if ((cpu->memory[base[tm]+TCR]&0x07) == (pcnt+1))
++          {
++            cnt=++cpu->memory[base[tm]+TCNT];
++            if (cnt>=0x100)
++              {
++                tcsr[tm]|=0x20;
++                cnt=0;
++              }
++            cpu->memory[base[tm]+TCNT]=cnt;
++          }
++	if (cpu->memory[base[tm]+TCNT] >= cpu->memory[base[tm]+TCORA])
++	  {
++	    tcsr[tm]|=0x40;
++	    if ((cpu->memory[base[tm]+TCR]&0x18) == 0x08)
++	      cpu->memory[base[tm]+TCNT] = 0;
++	  }
++	if (cpu->memory[base[tm]+TCNT] >= cpu->memory[base[tm]+TCORB])
++	  {
++	    tcsr[tm]|=0x80;
++	    if ((cpu->memory[base[tm]+TCR]&0x18) == 0x10)
++	      cpu->memory[base[tm]+TCNT] = 0;
++	  }
++	cpu->memory[base[tm]+TCSR] &= 0x1f;
++	cpu->memory[base[tm]+TCSR] |= (tcsr[tm] & 0xe0);
++      }
++      prescale[pcnt]+=prescale_div[pcnt];
++    }
++  }
++}
++
++static unsigned int complete_time(cpu_state_type *cpu,int cycles)
++{
++	int length;
++	int div[]={1,4,16,64};
++	length=(SMR & 0x40)?7:8;
++	length+=(SMR & 0x20)?1:0;
++	length+=(SMR & 0x08)?1:0;
++	length+=2;
++	return length*32*div[SMR & 0x03]*BRR+cycles;
++}
++
++static void send_data(int txd)
++{
++	char dt;
++	dt=txd;
++	write(scifd,&dt,1);
++	fsync(scifd);
++}
++
++static int rcv_data(int *rxd)
++{
++	char rd;
++	if(read(scifd,&rd,1)>0) {
++		*rxd=rd;
++		return 1;
++	} else
++		return 0;
++}
++
++static int sci(cpu_state_type *cpu,int cycles)
++{
++	static int tx_end_time=0;
++	static int rx_end_time=0;
++	static int data=-1;
++	ssr &= SSR;
++	if((SCR & 0x20) && !(ssr & 0x80)) {
++		send_data(TDR);
++		ssr |= 0x80;
++		tx_end_time=complete_time(cpu,cycles);
++	}
++	if ((data == -1) && !rcv_data(&data))
++		data = -1;
++	if((data != -1) && (SCR & 0x10) && ((rx_end_time==0) || (rx_end_time-cycles)<0)) {
++		if(ssr & 0x40) {
++			ssr |= 0x20;
++		} else {
++			RDR=data;
++			ssr |= 0x40;
++			data=-1;
++		}
++		rx_end_time=complete_time(cpu,cycles);
++	}
++	if((tx_end_time>0) && (tx_end_time-cycles)<0) {
++		if(ssr & 0x80) {
++			ssr |= 0x04;
++		}
++	}
++	SSR = ssr;
++}
++
++static int 
++intcont(cpu_state_type *cpu)
++{
++  struct INT_LIST {
++    int vector;
++    int isr_adr;
++    unsigned char isr_mask;
++    int ier_adr;
++    unsigned char ier_mask;
++  } int_table[]= {
++    {36,0xffff82,0x40,0xffff80,0x40},
++    {37,0xffff82,0x80,0xffff80,0x80},
++    {38,0xffff83,0x40,0xffff81,0x40},
++    {38,0xffff83,0x80,0xffff81,0x40},
++    {39,0xffff82,0x20,0xffff80,0x20},
++    {39,0xffff83,0x20,0xffff81,0x20},
++    {40,0xffff92,0x40,0xffff90,0x40},
++    {41,0xffff92,0x80,0xffff90,0x80},
++    {42,0xffff93,0x40,0xffff91,0x40},
++    {42,0xffff93,0x80,0xffff91,0x40},
++    {43,0xffff92,0x20,0xffff90,0x20},
++    {43,0xffff93,0x20,0xffff91,0x20},
++    {52,0xffffb4,0x38,0xffffb2,0x40},
++    {53,0xffffb4,0x40,0xffffb2,0x40},
++    {54,0xffffb4,0x80,0xffffb2,0x80},
++    {55,0xffffb4,0x04,0xffffb2,0x04}
++  };
++  int irqno;
++  for (irqno=0;irqno<sizeof(int_table)/sizeof(struct INT_LIST);irqno++)
++    {
++      if(cpu->memory[int_table[irqno].ier_adr]&int_table[irqno].ier_mask)
++        if(cpu->memory[int_table[irqno].isr_adr]&int_table[irqno].isr_mask)
++          return int_table[irqno].vector;
++    }
++  return 0;
++}
++
++int 
++iosimulation(cpu_state_type *cpu,int cycles)
++{
++  timer8(cpu,cycles);
++  sci(cpu,cycles);
++  return intcont(cpu);
++}
++
++void init_ioregs(cpu_state_type *cpu)
++{
++  struct INITTABLE {
++    int addr;
++    short data;
++  } reg_ini[] = {
++    0xffff80,0x00,
++    0xffff81,0x00,
++    0xffff82,0x00,
++    0xffff83,0x00,
++    0xffff84,0xff,
++    0xffff85,0xff,
++    0xffff86,0xff,
++    0xffff87,0xff,
++    0xffff88,0x00,
++    0xffff89,0x00,
++    0xffff90,0x00,
++    0xffff91,0x00,
++    0xffff92,0x00,
++    0xffff93,0x00,
++    0xffff94,0xff,
++    0xffff95,0xff,
++    0xffff96,0xff,
++    0xffff97,0xff,
++    0xffff98,0x00,
++    0xffff99,0x00,
++    0xffffb0,0x00,
++    0xffffb1,0xff,
++    0xffffb2,0x00,
++    0xffffb3,0xff,
++    0xffffb4,0x84,
++    0xffffb8,0x00,
++    0xffffb9,0xff,
++    0xffffba,0x00,
++    0xffffbb,0xff,
++    0xffffbc,0x84,
++    0xffffc0,0x00,
++    0xffffc1,0xff,
++    0xffffc2,0x00,
++    0xffffc3,0xff,
++    0xffffc4,0x84,
++  };
++  int c;
++  for(c=0;c<sizeof(reg_ini)/sizeof(struct INITTABLE);c++)
++    cpu->memory[reg_ini[c].addr]=reg_ini[c].data;
++  ssr = 0x84;
++}
++
++char *openpty(void)
++{
++	const char nm[]="0123456789ABCDEF";
++	static char ptyname[16];
++	int c1,c2,fd;
++	struct termios attr;
++	fd = open("/dev/ptmx",O_RDWR|O_NONBLOCK);
++	if(fd >= 0) {
++		grantpt(fd);
++		unlockpt(fd);
++		strncpy(ptyname,ptsname(fd),sizeof(ptyname)-1);
++		ptyname[sizeof(ptyname)-1]='\0';
++	} else {
++		for(c1='a';c1<='z';c1++)
++			for(c2=0;c2<sizeof(nm)-1;c2++) {
++				sprintf(ptyname,"/dev/pty%c%c",c1,nm[c2]);
++				fd=open(ptyname,O_RDWR|O_NONBLOCK);
++				if(fd != -1)
++					break ;
++			}
++		ptyname[5]='t';
++	}
++	if (fd >= 0) {
++		scifd=fd;
++		tcgetattr(scifd,&attr);
++		memcpy(&old_attr,&attr,sizeof(struct termios));
++		attr.c_lflag&=~ICANON;
++		attr.c_cc[VMIN]=0;
++		attr.c_cc[VTIME]=0;
++		tcsetattr(scifd,TCSAFLUSH,&attr);
++		return ptyname;
++	} else
++		return NULL;
++}
++
++void closepty(void)
++{
++	struct termios attr;
++	if(scifd!=-1) {
++		tcsetattr(scifd,TCSAFLUSH,&old_attr);
++		close(scifd);
++	}
++}
diff -urN linux-2.4.29/arch/h8300/tools_patch/README linux-2.4.29-uc1/arch/h8300/tools_patch/README
--- linux-2.4.29/arch/h8300/tools_patch/README	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/h8300/tools_patch/README	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,23 @@
+gcc.diff
+Please compile it after applying a patch in gcc.
+It is gcc-3.1.1 only.
+
+Procedure
+$ tar xzf gcc-3.1.1.tar.gz
+$ cd gcc-3.1.1
+$ patch -p1 < gcc.diff
+$ configure --target=h8300-elf --disable-nls -enable-languages='c,c++'
+$ make
+$ make install
+
+gdb.diff
+It is necessary when I execute it on GDB sim.
+It is gdb-5.2.1 only.
+
+Procedure
+$ tar xzf gdb-5.2.1.tar.gz
+$ cd gdb-5.2.1
+$ patch -p1 < gdb.diff
+$ configure --target=h8300-elf
+$ make
+$ make install
diff -urN linux-2.4.29/arch/i386/config.in linux-2.4.29-uc1/arch/i386/config.in
--- linux-2.4.29/arch/i386/config.in	2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.29-uc1/arch/i386/config.in	2005-06-14 02:11:22.000000000 +0100
@@ -481,6 +481,16 @@
    bool '  Compile the kernel with frame pointers' CONFIG_FRAME_POINTER
 fi
 
+bool 'Timepeg instrumentation' CONFIG_TIMEPEG
+if [ "$CONFIG_TIMEPEG" != "n" ]; then
+   bool '  Interrupt latency instrumentation' CONFIG_INTLAT
+   bool '  System call timing' CONFIG_SYSCALLTIMER
+fi
+bool 'Specify Command Line' CONFIG_COMMAND_LINE
+if [ "$CONFIG_COMMAND_LINE" != "n" ]; then
+  string 'Command Line' CONFIG_COMMAND_LINE_VALUE ""
+fi
+
 int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
 
 endmenu
diff -urN linux-2.4.29/arch/i386/kernel/entry.S linux-2.4.29-uc1/arch/i386/kernel/entry.S
--- linux-2.4.29/arch/i386/kernel/entry.S	2003-06-13 15:51:29.000000000 +0100
+++ linux-2.4.29-uc1/arch/i386/kernel/entry.S	2005-06-14 02:11:22.000000000 +0100
@@ -207,8 +207,16 @@
 	jne tracesys
 	cmpl $(NR_syscalls),%eax
 	jae badsys
+#ifdef CONFIG_SYSCALLTIMER
+	pushl %eax
+	call SYMBOL_NAME(timepeg_syscall_start)
+	popl %eax
+#endif
 	call *SYMBOL_NAME(sys_call_table)(,%eax,4)
 	movl %eax,EAX(%esp)		# save the return value
+#ifdef CONFIG_SYSCALLTIMER
+	call SYMBOL_NAME(timepeg_syscall_stop)
+#endif
 ENTRY(ret_from_sys_call)
 	cli				# need_resched and signals atomic test
 	cmpl $0,need_resched(%ebx)
diff -urN linux-2.4.29/arch/i386/kernel/intlat.c linux-2.4.29-uc1/arch/i386/kernel/intlat.c
--- linux-2.4.29/arch/i386/kernel/intlat.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/i386/kernel/intlat.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,185 @@
+/*
+ * Interrupt latency instrumentation
+ *
+ * Andrew Morton <andrewm@uow.edu.au>
+ * http://www.uow.edu.au/~andrewm/linux/
+ */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_INTLAT
+
+#ifndef CONFIG_TIMEPEG
+#error INTLAT requires CONFIG_TIMEPEG
+#endif
+
+#include <linux/module.h>
+#include <asm/system.h>
+#include <asm/timepeg.h>
+
+#define read_flags(x)	\
+	__asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */ :"memory")
+
+#define INT_ON			0x0200
+#define INT_OFF			0x0000
+#define INTS_ON(flags)		((flags) & INT_ON)
+#define INTS_OFF(flags)		(!((flags) & INT_ON))
+
+/*
+ * We're about to set the interrupt flags.
+ * If we're going from enabled -> disabled, do a TPH_MODE_START.
+ * If we're going from disabled -> enabled, do a TPH_MODE_STOP.
+ */
+static void
+about_to_set(struct timepeg_slot *_tps, unsigned long _flags_now, unsigned long _new_flags)
+{
+	if (INTS_ON(_flags_now) && !INTS_ON(_new_flags))
+	{	/* enabled -> disabled */
+		timepeg_hit(_tps, TPH_MODE_START);
+	}
+	else if (!INTS_ON(_flags_now) && INTS_ON(_new_flags))
+	{	/* disabled -> enabled */
+		timepeg_hit(_tps, TPH_MODE_STOP);
+	}
+}
+
+/*
+ * Entering an ISR, we assume that interrupts were on,  so
+ * make it look like they're now turned off.
+ */
+
+void
+intlat_enter_isr(struct timepeg_slot *_tps)
+{
+	timepeg_hit(_tps, TPH_MODE_START);
+}
+
+/*
+ * Exitting from the ISR.  If interrupts have been reenabled within the
+ * ISR we do nothing.  If they haven't, make it look like the ISR exit
+ * is an enabling of interrupts.
+ */
+void
+intlat_exit_isr(struct timepeg_slot *_tps)
+{
+	unsigned long flags_now;
+
+	read_flags(flags_now);
+
+	if (INTS_OFF(flags_now))
+	{
+		timepeg_hit(_tps, TPH_MODE_STOP);
+	}
+}
+
+/*
+ * We must always call about_to_set with interrupts off; otherwise there
+ * are nasty windows
+ */
+void
+intlat_restore_flags(struct timepeg_slot *_tps, unsigned long _flags)
+{
+	unsigned long flags_now;
+
+	read_flags(flags_now);
+
+	if (INTS_ON(_flags))
+	{	/* Enabling */
+		about_to_set(_tps, flags_now, _flags);
+		__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (_flags):"memory");
+	}
+	else
+	{	/* Disabling */
+		__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (_flags):"memory");
+		about_to_set(_tps, flags_now, _flags);
+	}
+}
+
+void
+intlat_cli(struct timepeg_slot *_tps)
+{
+	unsigned long flags_now;
+
+	read_flags(flags_now);
+
+	__asm__ __volatile__("cli": : :"memory");
+	about_to_set(_tps, flags_now, INT_OFF);
+}
+
+void
+intlat_sti(struct timepeg_slot *_tps)
+{
+	unsigned long flags_now;
+
+	read_flags(flags_now);
+
+	about_to_set(_tps, flags_now, INT_ON);
+	__asm__ __volatile__("sti": : :"memory");
+}
+
+unsigned long
+intlat_local_irq_save(struct timepeg_slot *_tps)
+{
+	unsigned long x;
+	unsigned long flags_now;
+
+	read_flags(flags_now);
+
+	__asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory");
+	about_to_set(_tps, flags_now, INT_OFF);
+	return x;
+}
+
+void
+intlat_local_irq_restore(struct timepeg_slot *_tps, unsigned long _flags)
+{
+	unsigned long flags_now;
+
+	read_flags(flags_now);
+
+	if (INTS_ON(_flags))
+	{	/* Enabling */
+		about_to_set(_tps, flags_now, _flags);
+		__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (_flags):"memory");
+	}
+	else
+	{	/* Disabling */
+		__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (_flags):"memory");
+		about_to_set(_tps, flags_now, _flags);
+	}
+}
+
+void
+intlat_local_irq_disable(struct timepeg_slot *_tps)
+{
+	unsigned long flags_now;
+
+	read_flags(flags_now);
+
+	__asm__ __volatile__("cli": : :"memory");
+	about_to_set(_tps, flags_now, INT_OFF);
+}
+
+void
+intlat_local_irq_enable(struct timepeg_slot *_tps)
+{
+	unsigned long flags_now;
+
+	read_flags(flags_now);
+
+	about_to_set(_tps, flags_now, INT_ON);
+	__asm__ __volatile__("sti": : :"memory");
+}
+
+#ifdef CONFIG_MODULES
+EXPORT_SYMBOL(intlat_restore_flags);
+EXPORT_SYMBOL(intlat_local_irq_enable);
+EXPORT_SYMBOL(intlat_cli);
+EXPORT_SYMBOL(intlat_sti);
+EXPORT_SYMBOL(intlat_local_irq_save);
+EXPORT_SYMBOL(intlat_local_irq_restore);
+EXPORT_SYMBOL(intlat_local_irq_disable);
+#endif	/* CONFIG_MODULES */
+
+#endif	/* CONFIG_INTLAT */
+
diff -urN linux-2.4.29/arch/i386/kernel/irq.c linux-2.4.29-uc1/arch/i386/kernel/irq.c
--- linux-2.4.29/arch/i386/kernel/irq.c	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-uc1/arch/i386/kernel/irq.c	2005-06-14 02:11:22.000000000 +0100
@@ -45,7 +45,9 @@
 #include <asm/desc.h>
 #include <asm/irq.h>
 
-
+#ifdef CONFIG_INTLAT
+#include <asm/timepeg.h>
+#endif
 
 /*
  * Linux has a controller-independent x86 interrupt architecture.
@@ -593,6 +595,16 @@
 	}
 #endif
 
+#ifdef CONFIG_INTLAT
+	/*
+	 * Use the interrupt entry to _simulate_ the disabling of interrupts
+	 */
+	{
+		TIMEPEG_DEFINE(in, "do_IRQ.in");
+		intlat_enter_isr(&in);
+	}
+#endif
+
 	kstat.irqs[cpu][irq]++;
 	spin_lock(&desc->lock);
 	desc->handler->ack(irq);
@@ -654,6 +666,17 @@
 
 	if (softirq_pending(cpu))
 		do_softirq();
+
+#ifdef CONFIG_INTLAT
+	/*
+	 * Use the interrupt exit to _simulate_ the enabling of interrupts
+	 */
+	{
+		TIMEPEG_DEFINE(out, "do_IRQ.out");
+		intlat_exit_isr(&out);
+	}
+#endif
+
 	return 1;
 }
 
diff -urN linux-2.4.29/arch/i386/kernel/Makefile linux-2.4.29-uc1/arch/i386/kernel/Makefile
--- linux-2.4.29/arch/i386/kernel/Makefile	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-uc1/arch/i386/kernel/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -15,6 +15,7 @@
 O_TARGET := kernel.o
 
 export-objs     := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o setup.o
+export-objs     += timepeg.o intlat.o
 
 obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
@@ -30,6 +31,9 @@
 endif
 endif
 
+obj-$(CONFIG_TIMEPEG)	+= timepeg.o
+obj-$(CONFIG_INTLAT)	+= intlat.o
+
 obj-$(CONFIG_MCA)		+= mca.o
 obj-$(CONFIG_MTRR)		+= mtrr.o
 obj-$(CONFIG_X86_MSR)		+= msr.o
diff -urN linux-2.4.29/arch/i386/kernel/setup.c linux-2.4.29-uc1/arch/i386/kernel/setup.c
--- linux-2.4.29/arch/i386/kernel/setup.c	2004-08-08 00:26:04.000000000 +0100
+++ linux-2.4.29-uc1/arch/i386/kernel/setup.c	2005-06-14 02:11:22.000000000 +0100
@@ -218,6 +218,15 @@
 #define COMMAND_LINE ((char *) (PARAM+2048))
 #define COMMAND_LINE_SIZE 256
 
+#if defined(CONFIG_COMMAND_LINE)
+#undef COMMAND_LINE
+#define COMMAND_LINE	CONFIG_COMMAND_LINE_VALUE
+#elif defined(CONFIG_MTD_NETtel)
+/* Complete bastard hack for NETtel/x86 command line */
+#undef COMMAND_LINE
+#define COMMAND_LINE	((char *) 0x000e2000)
+#endif
+
 #define RAMDISK_IMAGE_START_MASK  	0x07FF
 #define RAMDISK_PROMPT_FLAG		0x8000
 #define RAMDISK_LOAD_FLAG		0x4000	
@@ -367,6 +376,9 @@
 static struct resource code_resource = { "Kernel code", 0x100000, 0 };
 static struct resource data_resource = { "Kernel data", 0, 0 };
 static struct resource vram_resource = { "Video RAM area", 0xa0000, 0xbffff, IORESOURCE_BUSY };
+#ifdef CONFIG_MTD_SNAPGEODE
+static struct resource geode_resource = { "Unknown Geode Conflict", 0x10400000, 0x3fffffff, IORESOURCE_BUSY };
+#endif
 
 /* System ROM resources */
 #define MAXROMS 6
@@ -904,6 +916,18 @@
 	}
 	*to = '\0';
 	*cmdline_p = command_line;
+
+#ifdef CONFIG_MTD_NETtel
+	/* Check for empty boot arguments in FLASH */
+	if (*((unsigned char *) &saved_command_line[0]) == 0xff) {
+		command_line[0] = 0;
+		saved_command_line[0] = 0;
+	}
+#endif
+#ifdef CONFIG_SNAPDOG
+	snapdog_service(NULL);
+#endif
+
 	if (userdef) {
 		printk(KERN_INFO "user-defined physical RAM map:\n");
 		print_memory_map("user");
@@ -1163,6 +1187,9 @@
 		}
 	}
 	request_resource(&iomem_resource, &vram_resource);
+#ifdef CONFIG_MTD_SNAPGEODE
+	request_resource(&iomem_resource, &geode_resource);
+#endif
 
 	/* request I/O space for devices used on all i[345]86 PCs */
 	for (i = 0; i < STANDARD_IO_RESOURCES; i++)
diff -urN linux-2.4.29/arch/i386/kernel/signal.c linux-2.4.29-uc1/arch/i386/kernel/signal.c
--- linux-2.4.29/arch/i386/kernel/signal.c	2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.29-uc1/arch/i386/kernel/signal.c	2005-06-14 02:11:22.000000000 +0100
@@ -680,6 +680,11 @@
 			case SIGQUIT: case SIGILL: case SIGTRAP:
 			case SIGABRT: case SIGFPE: case SIGSEGV:
 			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+#if defined (CONFIG_MTD_NETtel)
+				printk("%s is core dumping at 0x%x\n", 
+						current->comm, regs->eip);
+				show_regs(regs);
+#endif
 				if (do_coredump(signr, regs))
 					exit_code |= 0x80;
 				/* FALLTHRU */
diff -urN linux-2.4.29/arch/i386/kernel/timepeg.c linux-2.4.29-uc1/arch/i386/kernel/timepeg.c
--- linux-2.4.29/arch/i386/kernel/timepeg.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/i386/kernel/timepeg.c	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,952 @@
+/*
+ * Implementation of timepeg execution instrumentation.  See:
+ *
+ * Documentation/timepeg.txt
+ * http://www.uow.edu.au/~andrewm/linux/
+ *
+ * Andrew Morton <andrewm@uow.edu.au>
+ *
+ * Some code and ideas taken from the net profiling code
+ * which was contributed by <insert name here>
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+
+#ifdef CONFIG_TIMEPEG
+#include <asm/timepeg.h>
+
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/string.h>
+
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <asm/system.h>
+#include <asm/delay.h>
+
+#ifndef CONFIG_PROC_FS
+#error Timepegs require the /proc filesystem. Please enable CONFIG_PROC_FS.
+#endif
+
+#ifndef CONFIG_X86_TSC
+#include <asm/io.h>
+#include <linux/timer.h>
+#endif
+
+#define DEBUGGING 0
+
+/************************
+ * Storage declarations *
+ ************************/
+
+#ifndef CONFIG_X86_TSC
+volatile unsigned char	*timepeg_mmcrp;	/* mem mapped configuration registers */
+#endif
+
+/* Global singly linked list of timepegs */
+static struct timepeg_slot *g_timepeg_slots;
+
+/* Lock for the above */
+static spinlock_t g_timepeg_slots_l = SPIN_LOCK_UNLOCKED;
+
+/*
+ * Per-CPU array of most-previously-visited timepegs
+ */
+static struct timepeg_slot *g_prev_slots[NR_CPUS];
+
+/*
+ * Flag: timepeg system is usable
+ */
+int timepegs_are_running;
+
+/*
+ * Per-CPU array for recursion protection
+ */
+int timepeg_no_recur[NR_CPUS];
+
+/*
+ * Estimate of the time overhead which timepegs cause
+ */
+timepeg_t timepeg_calib;
+
+/*
+ * Records when each CPU entered timepeg_hit().  This used to be
+ * a local in timepeg_hit(), but that screws up across calls
+ * to schedule().
+ */
+timepeg_t entered_tp[NR_CPUS];
+
+/*
+ * Global /proc locking strategy:
+ *
+ * When a process is reading the /proc file we want all the users of the
+ * timepeg_slot list to simply skip over their instrumentation (leave it alone).
+ * But timepeg_read_proc() cannot proceed with using the data structure until
+ * all other users have finished.
+ *
+ * So:
+ *
+ *
+ *	timepeg_read_proc()
+ *	{
+ *		if (start_of_read())
+ *		{
+ *			reader_wants_it = 1;
+ *			while (usage_count > 0)
+ *				;
+ *			<I have it>
+ *		}
+ *		use the data
+ *		if (end_of_read)
+ *		{
+ *			reader_wants_it = 0;
+ *		}
+ *	}
+ *
+ *	timepeg_hit()
+ *	{
+ *		if (reader_wants_it == 0)
+ *		{
+ *			inc(usage_count);
+ *			if (reader_wants_it == 0)
+ *				do stuff
+ *			dec(usage_count)
+ *		}
+ *	}
+ *
+ * There's locking on reader_wants_it
+ *
+ * There may be a more clever way of doing it...
+ */
+
+/* 
+ * A (locked) flag which we use to prevent all the data structures
+ * from being touched by timepeg_hit() while timepeg_read_proc() is
+ * being used (someone is reading the /proc file).
+ */
+
+static struct
+{
+	spinlock_t lock;
+	int flag;
+	atomic_t usage_count;
+} reader_wants_it = {
+	SPIN_LOCK_UNLOCKED,
+	0,
+	ATOMIC_INIT(0),
+};
+
+static void run_test_cases(void);
+
+/*
+ * Construct a timepeg.
+ *
+ * Nothing much to do at this time - just link it in to the
+ * global list.
+ *
+ * Local interrupts are disabled and *_ntps is locked
+ */
+
+static void
+timepeg_construct(struct timepeg_slot * const _ntps)
+{
+	int i;
+
+	/* We need to lock down the list head.  (pedant) */
+	spin_lock(&g_timepeg_slots_l);
+
+	/* All this simply initialises the per-cpu per-arc min_tp/max_tp value */
+	for (i = 0; i < NR_CPUS; i++)
+	{
+		int j;
+		struct timepeg_slot_percpu *ntpsp = &(_ntps->percpu[i]);
+
+		for (	j = 0;
+			j < sizeof(ntpsp->preds) / sizeof(ntpsp->preds[0]);
+			j++)
+		{
+			struct timepeg_arc *ntpa = &(ntpsp->preds[j]);
+			ntpa->max_tp = 0;
+			ntpa->min_tp = ~0ULL;
+		}
+	}
+
+	/*
+	 * Slash through the current timepegs to see if bozo-the-coder
+	 * has given two timepegs the same name
+	 */
+	if (_ntps->line == 0)	/* file-n-line timepegs can be duplicated */
+	{
+		struct timepeg_slot *tps;
+
+		for (tps = g_timepeg_slots; tps; tps = tps->next)
+		{
+			if ((tps->line == _ntps->line) && !strcmp(tps->name, _ntps->name))
+			{
+				printk(	"timepeg: detected duplicate timepeg '%s:%d'\n",
+					_ntps->name, _ntps->line);
+				_ntps->mode_bits |= TIMEPEG_MODE_DEAD;
+				break;
+			}
+		}
+	}
+
+	/*
+	 * If this is a directed timepeg, it has a non-zero directee_name.
+	 * We do a linear search of the timepeg list looking for the
+	 * directed predecessor.  If it's not there we complain
+	 * and mark the timepeg as dead. We also do not add it to the list
+	 * of timpegs.
+	 * The linear search is OK - once the list is built it remains
+	 * in place until a reboot.  The first timepeg run is a throw-away
+	 * anyway.
+	 * We ignore the timepeg_slot.line here - assume that directed timepegs
+	 * do not point at file-and-line timepegs.
+	 */
+	if (!(_ntps->mode_bits & TIMEPEG_MODE_DEAD) && _ntps->directee_name)
+	{
+		struct timepeg_slot *tps = g_timepeg_slots;
+		while (tps)
+		{
+			if (!strcmp(tps->name, _ntps->directee_name))
+				break;
+			tps = tps->next;
+		}
+
+		if (tps == 0)
+		{
+			printk(	"timepeg: timepeg '%s' is directed to timepeg '%s', "
+				"which couldn't be located\n",
+				_ntps->name,
+				_ntps->directee_name);
+			_ntps->mode_bits |= TIMEPEG_MODE_DEAD;
+		}
+		else
+		{
+			_ntps->directed_pred = tps;
+		}
+	}
+
+	if (!(_ntps->mode_bits & TIMEPEG_MODE_DEAD))
+	{
+		_ntps->next = g_timepeg_slots;
+		g_timepeg_slots = _ntps;
+	}
+
+	spin_unlock(&g_timepeg_slots_l);
+}
+
+/*
+ * Somebody has executed TIMEPEG().
+ * Called from timepeg_hit().
+ *
+ * Local interrupts are disabled
+ */
+
+timepeg_t *
+timepeg_do_hit(	struct timepeg_slot * const _ntps,
+		timepeg_t * const _now_tp,
+		const int _mode)
+{
+	struct timepeg_slot * prev_tp;		/* Most-recently-visited */
+	const int cpu = smp_processor_id();	/* I _so_ prefer C++ */
+	struct timepeg_slot_percpu *cpu_slot;
+	timepeg_t *retval = (timepeg_t *)0;
+
+	spin_lock(&reader_wants_it.lock);
+	if (reader_wants_it.flag != 0)
+	{	/* It's being read.  Skip it */
+		spin_unlock(&reader_wants_it.lock);
+		goto bye;
+	}
+	atomic_inc(&reader_wants_it.usage_count);
+	spin_unlock(&reader_wants_it.lock);
+
+	/*
+	 * We need to lock this timepeg from other CPUs.  We know that
+	 * local interrupts are disabled so all we need do is spin on the lock.
+	 */
+	spin_lock(&_ntps->lock);
+
+	if ((_ntps->mode_bits & TIMEPEG_MODE_INITIALISED) == 0)
+	{	/* First time this timepeg has been used */
+		timepeg_construct(_ntps);
+		if (_ntps->mode_bits & TIMEPEG_MODE_INITIALISED)
+			printk("HOLY COW!  REENTERED\n");
+		_ntps->mode_bits |= TIMEPEG_MODE_INITIALISED;
+	}
+
+	if (_ntps->mode_bits & TIMEPEG_MODE_DEAD)
+	{	/*
+		 * oops.  This is a directed timepeg and we were
+		 * unable to locate its directed predecessor, or it
+		 * was previously determined to be a dupe.
+		 * Give up.
+		 */
+		spin_unlock(&_ntps->lock);
+
+		atomic_dec(&reader_wants_it.usage_count);
+		goto bye;
+	}
+
+	/* Locate the per-cpu info in this timepeg */
+	cpu_slot = &(_ntps->percpu[cpu]);
+
+	/*
+	 * Find the other end of the arc.  If it's a directed timepeg
+	 * then we know.  Otherwise find the most-recently-hit timepeg
+	 * for this CPU
+	 */
+	if (_ntps->directed_pred)
+	{	/* Directed */
+		prev_tp = _ntps->directed_pred;
+	}
+	else
+	{	/* Most-recently-seen for this CPU */
+		prev_tp = g_prev_slots[cpu];
+	}
+
+	if (prev_tp == 0)
+	{	/* Waah.  This is the first time this CPU has
+		 * hit a timepeg.
+		 */
+		/* NOTHING */
+	}
+	else if (_mode & TPH_MODE_STOP)
+	{
+		/*
+		 * OK, time to actually do something.
+		 * We update this timepeg's info for this CPU.
+		 */
+		struct timepeg_arc *ntpa = 0;
+		timepeg_t elapsed_tp;
+		int i;
+
+		/*
+		 * First, see if we already have some stats for this arc.
+		 * Linear search...
+		 */
+		ntpa = &cpu_slot->preds[0];
+		for (i = 0; i < TIMEPEG_NR_PREDS; i++, ntpa++)
+		{
+			if (ntpa->timepeg == 0)
+			{
+				/*
+				 * End of the list.  This must be
+				 * the first time we've seen this arc
+				 */
+				ntpa->timepeg = prev_tp;
+				break;
+			}
+			if (ntpa->timepeg == prev_tp)
+			{	/* We've used this arc before */
+				break;
+			}
+		}
+
+		if (i == TIMEPEG_NR_PREDS)
+		{
+			/* oops.  We've run out of space in the preds table */
+			if ((_ntps->mode_bits & TIMEPEG_MODE_FULL) == 0)
+			{
+				int j;
+				struct timepeg_arc *ntpa2;
+
+				printk(	"timepeg_do_hit(): out of predecessor slots for %s:%d\n",
+					_ntps->name, _ntps->line);
+				_ntps->mode_bits |= TIMEPEG_MODE_FULL;
+
+				ntpa2 = &cpu_slot->preds[0];
+				printk("Contents:\n");
+				for (j = 0; j < TIMEPEG_NR_PREDS; j++, ntpa2++)
+				{
+					printk(	"  %s:%d\n",
+						ntpa2->timepeg->name,
+						ntpa2->timepeg->line);
+				}
+			}
+			ntpa = 0;
+		}
+
+		/* Accumulate arc time */
+		elapsed_tp = *_now_tp - prev_tp->percpu[cpu].departure_tp - timepeg_calib;
+#ifndef CONFIG_X86_TSC
+		/* Due to the SC520 timer being two parts that cascade together,
+		 * it is possible for a negative delta to appear this is caused
+		 * by the millisecond counter being updated by the microsecond counter
+		 * at about the time we read it.  The problem is that the cascade
+		 * doesn't occur naturally between microseconds of 999 and 000, it just
+		 * happens around then.  Luckily, the error is always 1 microsecond so
+		 * it is correctable once detected.
+		 */
+		if (*_now_tp < prev_tp->percpu[cpu].departure_tp)
+			elapsed_tp += 1000;
+#endif
+
+		if (ntpa)
+		{
+			ntpa->acc_tp += elapsed_tp;
+
+			/* Bump arc usage count */
+			ntpa->nr_times++;
+
+			/* Calculate fastest time */
+			if (elapsed_tp < ntpa->min_tp)
+			{	/* elapsed < min_tp */
+				ntpa->min_tp = elapsed_tp;
+			}
+
+			/* Calculate slowest time */
+			if (elapsed_tp > ntpa->max_tp)
+			{	/* elapsed > max_tp */
+				ntpa->max_tp = elapsed_tp;
+			}
+		}
+	}
+
+	if (_mode & TPH_MODE_START)
+	{
+		/*
+		 * Note the fact that this CPU's next arc starts on this timepeg
+		 */
+		g_prev_slots[cpu] = _ntps;
+
+		/*
+		 * The outgoing inline code writes the current time into this CPU's
+		 * slot in this timepeg
+		 */
+		retval = &cpu_slot->departure_tp;
+	}
+
+	spin_unlock(&_ntps->lock);
+
+	atomic_dec(&reader_wants_it.usage_count);
+bye:
+	return retval;
+}
+
+/*
+ * Reinitialise all accumulation data
+ * Is this racy?
+ */
+
+static void
+zap_all_timepegs(void)
+{
+	struct timepeg_slot *slotp = g_timepeg_slots;
+	int i;
+
+	for ( ; slotp; slotp = slotp->next)
+	{
+		int cpu;
+
+		for (cpu = 0; cpu < NR_CPUS; cpu++)
+		{
+			int pred;
+			struct timepeg_slot_percpu *pcpu;
+
+			pcpu = &(slotp->percpu[cpu]);
+
+			/* Leave departure_tp alone */
+
+			for (pred = 0; pred < TIMEPEG_NR_PREDS; pred++)
+			{
+				struct timepeg_arc *arc = &(pcpu->preds[pred]);
+				arc->timepeg = 0;
+				arc->acc_tp = 0;
+				arc->min_tp = ~0ULL;
+				arc->max_tp = 0;
+				arc->nr_times = 0;
+			}
+		}
+	}
+
+	for (i = 0; i < sizeof(g_prev_slots)/sizeof(g_prev_slots[0]); i++)
+		g_prev_slots[i] = 0;
+}
+
+/*
+ * Dump to userland.  Return the number of chars we've generated.
+ * Gack.  What a crufty interface.
+ *
+ *
+ * Output format:
+ *
+ *	n_cpus						Integer
+ *	for_all_timepegs
+ *	{
+ *		timepeg_name
+ *		for_all_cpus
+ *		{
+ *			"cpu%d"				Literal
+ *			number_of_preds			Integer
+ *			for_all_preds
+ *			{
+ *				pred_name nt_times acc_tp min_tp max_tp
+ *			}
+ *		}
+ *	}
+ *
+ */
+
+/*
+ * Calculate the time taken for timepeg accounting.  This will be
+ * subtracted from all future accounting.  It's a bast-case.  Caches
+ * are hot.
+ */
+
+static void calibrate_timepegs(void)
+{
+	timepeg_t in, out;
+	int i;
+	unsigned long flags;
+return;
+	local_irq_save(flags);
+	for (i = 0; i < 2; i++)
+	{
+		timepeg_stamp(&in);
+		DTIMEPEG("__dummy__", "__dummy__");
+		timepeg_stamp(&out);
+	}
+	timepeg_calib = out - in;
+	local_irq_restore(flags);
+}
+
+/*
+ * The read function gets called once, even after it has returned *eof=1.  That
+ * screws up royally.  Kludge it here.
+ */
+
+static int g_read_completed = 0;
+
+static int
+timepeg_read_proc(
+	char *page_buffer,
+	char **my_first_byte,
+	off_t virtual_start,
+	int length,
+	int *eof,
+	void *data)
+{
+	int my_buffer_offset = 0, my_virtual_offset = 0;
+	char * const my_base = page_buffer;
+	struct timepeg_slot *ntps;
+	int cpu, retval = 0;
+
+	/*
+	 * Turn the timepeg system on now.
+	 */
+	if (timepegs_are_running == 0) {
+		timepegs_are_running = 1;
+		calibrate_timepegs();
+		return 0;
+	}
+
+	if (g_timepeg_slots == 0)
+	{
+		run_test_cases();
+		return 0;
+	}
+
+	if (virtual_start == 0)
+	{	/* Just been opened */
+		reader_wants_it.flag = 1;
+		while (atomic_read(&reader_wants_it.usage_count) != 0)
+			;
+		g_read_completed = 0;
+	}
+	else if (g_read_completed)
+	{
+		return 0;
+	}
+
+	my_buffer_offset += sprintf(my_base + my_buffer_offset, "%d\n", NR_CPUS);
+
+	for (ntps = g_timepeg_slots; ntps; ntps = ntps->next)
+	{
+		my_buffer_offset += sprintf(	my_base + my_buffer_offset,
+						" \"%s:%d\"\n",
+						ntps->name,
+						ntps->line);
+
+		for (cpu = 0; cpu < NR_CPUS; cpu++)
+		{
+			struct timepeg_slot_percpu *per_cpu;
+			int j, n = 0;
+
+			per_cpu = &(ntps->percpu[cpu]);
+			my_buffer_offset += sprintf(my_base + my_buffer_offset, "  cpu%04d\n", cpu);
+			for (j = 0; j < TIMEPEG_NR_PREDS; j++)
+			{
+				struct timepeg_arc *ntpa;
+				ntpa = &(per_cpu->preds[j]);
+				if (ntpa->timepeg)
+					n++;
+				else
+					break;
+			}
+			my_buffer_offset += sprintf(my_base + my_buffer_offset, "  %d\n", n);
+				
+			for (j = 0; j < TIMEPEG_NR_PREDS; j++)
+			{
+				struct timepeg_arc *ntpa;
+				ntpa = &(per_cpu->preds[j]);
+				if (ntpa->timepeg)
+				{
+					my_buffer_offset += sprintf(
+						my_base + my_buffer_offset,
+						"   \"%s:%d\" %lu %lu:%lu %lu:%lu %lu:%lu\n",
+						ntpa->timepeg->name,
+						ntpa->timepeg->line,
+						ntpa->nr_times,
+						(unsigned long)(ntpa->acc_tp >> 32),
+						(unsigned long)ntpa->acc_tp,
+						(unsigned long)(ntpa->min_tp >> 32),
+						(unsigned long)ntpa->min_tp,
+						(unsigned long)(ntpa->max_tp >> 32),
+						(unsigned long)ntpa->max_tp);
+				}
+			}
+		}
+
+		my_virtual_offset += my_buffer_offset;
+		if (my_virtual_offset <= virtual_start)
+		{
+			my_buffer_offset = 0;	/* Keep writing until we get into caller's window */
+		}
+		else
+		{	/* We provided some stuff */
+			retval = my_virtual_offset - virtual_start;
+			*my_first_byte = page_buffer + (my_buffer_offset - retval);
+			goto done;
+		}
+	}
+
+	/*
+	 * We've finished the read
+	 */
+	*eof = 1;
+	*my_first_byte = page_buffer;
+	g_read_completed = 1;
+	zap_all_timepegs();
+	reader_wants_it.flag = 0;
+
+	/*
+	 * OK, the read has finished and everything is unlocked.
+	 * We take this as our cue to run the test cases.
+	 */
+	run_test_cases();
+
+done:
+	if (my_buffer_offset > PAGE_SIZE)
+	{
+		printk("timepeg: Holy cow! I've just trashed your machine.\n");
+	}
+	return retval;
+}
+
+#ifndef CONFIG_X86_TSC
+void
+timepeg_stamp(timepeg_t *pstamp)
+{
+	unsigned long mm;
+	int milli, micro, m;
+	static int old_milli;
+	static unsigned long secs;
+
+	/* Load micro and milli second counts together */
+	mm = *(volatile unsigned long *)(timepeg_mmcrp + 0xc60);
+	micro = mm >> 16;
+	milli = mm & 0xffff;
+	
+	/* The milli second component is zeroed on read so we've
+	 * got some correcting to do.
+	 */
+	m = milli + old_milli;
+	while (m > 1000) {
+		m -= 1000;
+		secs++;
+	}
+	old_milli = m;
+
+	
+	/* Now bash everything together and return it.
+	 * This could be coded more efficiently using some clever
+	 * type casts.
+	 */
+	if (pstamp)
+		*pstamp = (((timepeg_t)secs) * 1000 + m) * 1000 + micro;
+}
+
+/* We must ensure that the timer_stamp code is polled irregularily.
+ * Strictly, we must poll the timer ever 65.5 seconds or it will overflow
+ * the milli second component.  We'll poll every 20 seconds to be very
+ * conservative.
+ */
+static void timepeg_timer(unsigned long arg) {
+	static struct timer_list timer;
+	
+	timepeg_stamp(NULL);
+
+	timer.expires = jiffies + HZ * 20;
+	timer.function = timepeg_timer;
+	timer.data = 0;
+	add_timer(&timer);
+}
+
+#endif
+
+int __init
+timepeg_init(void)
+{
+	printk("Kernel timepegs enabled. See http://www.uow.edu.au/~andrewm/linux/\n");
+#ifdef CONFIG_PROC_FS
+	create_proc_read_entry("timepeg", 0, 0, timepeg_read_proc, 0);
+#endif
+#ifndef CONFIG_X86_TSC
+	/* We're doing this for an AMD SC520 at the moment, map the config registers */
+	timepeg_mmcrp = (volatile unsigned char *) ioremap(0xfffef000, 4096);
+	
+	/* Use a 33.000 MHz crystal */
+	*(volatile unsigned char *)(timepeg_mmcrp + 0xc64) = 0x01;
+	
+	/* Begin our ping timer */
+	timepeg_timer(0);
+#endif
+	return 0;
+}
+
+__initcall(timepeg_init);
+
+EXPORT_SYMBOL(timepeg_do_hit);
+EXPORT_SYMBOL(timepeg_no_recur);
+EXPORT_SYMBOL(timepegs_are_running);
+EXPORT_SYMBOL(entered_tp);
+
+#if DEBUGGING
+
+static void
+tp_delay(const int n)
+{
+	udelay(n);
+}
+
+/*
+ * Basic regression test cases
+ *
+ * Note that the timing measurements here are only meaningful on the
+ * second run through.  This is because on the first pass more
+ * work has to be done to initialise the timepegs.  This
+ * includes work generated by the compiler (static variables with
+ * function scope) plus all the fluff in timepeg_construct
+ */
+
+static void
+test1(void)
+{
+	/*
+	 * Try a directed timepeg, referring to a timepeg which
+	 * doesn't exist yet.  We should get a printk message
+	 * and the 'misdirected' timepeg is forgotten about.
+	 */
+	DTIMEPEG("misdirected", "forward");
+	tp_delay(20);
+
+	/*
+	 * Try a non-existent timepeg.  Same result as above
+	 */
+	TIMEPEG("dangling_reference");
+	tp_delay(30);
+
+	/*
+	 * Satisfy the forward reference
+	 */
+	TIMEPEG("forward");
+	tp_delay(40);
+
+	/*
+	 * Duplicate timepeg.  The second should be complained about
+	 * and ignored
+	 */
+	TIMEPEG("duplicate");
+	TIMEPEG("duplicate");
+	DTIMEPEG("duplicate", "dangling_reference");
+	tp_delay(50);
+
+	/*
+	 * I wonder what this does?
+	 */
+	TIMEPEG("circular");
+	DTIMEPEG("circular", "circular");
+
+	/*
+	 * And this?
+	 */
+	DTIMEPEG("self", "self");
+
+	/*
+	 * Measure the inter-timepeg delay.  This
+	 * _should_ be zero, but there are a few
+	 * instructions which are not accounted for.
+	 */
+	TIMEPEG("fast_chain_1");
+	TIMEPEG("fast_chain_2");
+	TIMEPEG("fast_chain_3");
+	tp_delay(60);
+
+	/*
+	 * Now use a directed timepeg to work out how long a timepeg
+	 * _really_ takes.  This works because directed timepegs
+	 * do not take into account the time spent in intervening
+	 * timepegs.
+	 */
+	TIMEPEG("measure_1");
+	TIMEPEG("dummy1");
+	TIMEPEG("dummy2");
+	TIMEPEG("dummy3");
+	DTIMEPEG("measure_2", "measure_1");
+	tp_delay(70);
+
+	/*
+	 * Do the above again, but with one less timepeg.  The difference
+	 * is the timepeg overhead (modulo cache effects).
+	 */
+	TIMEPEG("measure_3");
+	TIMEPEG("dummy4");
+	TIMEPEG("dummy5");
+	DTIMEPEG("measure_4", "measure_3");
+	tp_delay(80);
+}
+
+
+/*
+ * Test complex call graphs
+ */
+
+static void
+test2_final(void)
+{
+	TIMEPEG("test2_final");
+	tp_delay(5);
+}
+
+static void
+test2_0(void)
+{
+	TIMEPEG("test2_0");
+	test2_final();
+}
+
+static void
+test2_1(void)
+{
+	TIMEPEG("test2_1");
+	test2_final();
+}
+
+static void
+test2_2(void)
+{
+	TIMEPEG("test2_2");
+	test2_final();
+}
+
+static void
+test2_3(void)
+{
+	TIMEPEG("test2_3");
+	test2_final();
+}
+
+static void
+test2(void)
+{
+	int i;
+
+	TIMEPEG("complex_start");
+
+	for (i = 0; i < 20; i++)
+	{
+		tp_delay(5);
+		switch (i % 4)
+		{
+		case 0:
+			test2_0();
+			break;
+		case 1:
+			test2_1();
+			break;
+		case 2:
+			test2_2();
+			break;
+		case 3:
+			test2_3();
+			break;
+		}
+	}
+	TIMEPEG("complex_end");
+	DTIMEPEG("dcomplex_end", "complex_start");
+}
+
+/*
+ * Overflow a timpeg's predecessor table
+ */
+
+static void test3(void)
+{
+	int i;
+	for (i = 0; i < 17; i++)
+	{
+		switch (i)
+		{
+		case  0:	TIMEPEG_MODE("test3 00", TPH_MODE_START); break;
+		case  1:	TIMEPEG_MODE("test3 01", TPH_MODE_START); break;
+		case  2:	TIMEPEG_MODE("test3 02", TPH_MODE_START); break;
+		case  3:	TIMEPEG_MODE("test3 03", TPH_MODE_START); break;
+		case  4:	TIMEPEG_MODE("test3 04", TPH_MODE_START); break;
+		case  5:	TIMEPEG_MODE("test3 05", TPH_MODE_START); break;
+		case  6:	TIMEPEG_MODE("test3 06", TPH_MODE_START); break;
+		case  7:	TIMEPEG_MODE("test3 07", TPH_MODE_START); break;
+		case  8:	TIMEPEG_MODE("test3 08", TPH_MODE_START); break;
+		case  9:	TIMEPEG_MODE("test3 09", TPH_MODE_START); break;
+		case 10:	TIMEPEG_MODE("test3 10", TPH_MODE_START); break;
+		case 11:	TIMEPEG_MODE("test3 11", TPH_MODE_START); break;
+		case 12:	TIMEPEG_MODE("test3 12", TPH_MODE_START); break;
+		case 13:	TIMEPEG_MODE("test3 13", TPH_MODE_START); break;
+		case 14:	TIMEPEG_MODE("test3 14", TPH_MODE_START); break;
+		case 15:	TIMEPEG_MODE("test3 15", TPH_MODE_START); break;
+		case 16:	TIMEPEG_MODE("test3 16", TPH_MODE_START); break;
+		}
+		tp_delay(10);
+		TIMEPEG_MODE("test3 sucker", TPH_MODE_STOP);
+	}
+}
+
+/*
+ * Wrap all the other tests
+ */
+
+static void
+run_test_cases(void)
+{
+	printk("timepeg: running test cases\n");
+	TIMEPEG("run_test_cases_start");
+	tp_delay(10);
+	test1();
+	TIMEPEG("run_test_cases_end");
+	DTIMEPEG("run_test_cases_end_d", "run_test_cases_start");
+	test2();
+	test3();
+}
+
+#else	/* DEBUGGING*/
+
+static void
+run_test_cases(void)
+{}
+
+#endif
+
+#endif	/* CONFIG_TIMEPEG */
+
diff -urN linux-2.4.29/arch/i386/kernel/traps.c linux-2.4.29-uc1/arch/i386/kernel/traps.c
--- linux-2.4.29/arch/i386/kernel/traps.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.29-uc1/arch/i386/kernel/traps.c	2005-06-14 02:11:22.000000000 +0100
@@ -1004,3 +1004,105 @@
 	cobalt_init();
 #endif
 }
+
+#ifdef CONFIG_SYSCALLTIMER
+/*
+ * Stuff to instrument system calls
+ */
+
+#include <asm/timepeg.h>
+#include <linux/sys.h>
+
+static struct timepeg_slot syscall_start_tps[NR_syscalls];
+static struct timepeg_slot syscall_stop_tps[NR_syscalls];
+static struct timepeg_slot schedule_switchout_tps[NR_syscalls];
+static struct timepeg_slot schedule_switchin_tps[NR_syscalls];
+
+static char syscall_start_ids[NR_syscalls][16];
+static char syscall_stop_ids[NR_syscalls][16];
+static char schedule_switchout_ids[NR_syscalls][16];
+static char schedule_switchin_ids[NR_syscalls][16];
+static int done_init;
+static int prev_syscall_no[NR_CPUS];
+
+static void init_syscall_tps(void)
+{
+	int i;
+	for (i = 0; i < NR_syscalls; i++) {
+		sprintf(syscall_start_ids[i], "start_%04d", i);
+		sprintf(syscall_stop_ids[i], "stop_%04d", i);
+		sprintf(schedule_switchout_ids[i], "switchout_%04d", i);
+		sprintf(schedule_switchin_ids[i], "switchin_%04d", i);
+
+		syscall_start_tps[i].name = syscall_start_ids[i];
+		syscall_stop_tps[i].name = syscall_stop_ids[i];
+		schedule_switchout_tps[i].name = schedule_switchout_ids[i];
+		schedule_switchin_tps[i].name = schedule_switchin_ids[i];
+#if 0
+		/*
+		 * Make them directed timepegs so we don't get tangled with
+		 * the copy_*_user() timepegs.
+		 */
+		syscall_stop_tps[i].directee_name = syscall_start_ids[i];
+#endif
+		
+		spin_lock_init(&syscall_start_tps[i].lock);
+		spin_lock_init(&syscall_stop_tps[i].lock);
+		spin_lock_init(&schedule_switchout_tps[i].lock);
+		spin_lock_init(&schedule_switchin_tps[i].lock);
+	}
+	done_init = 1;
+}
+
+asmlinkage void timepeg_syscall_start(unsigned int syscall_no)
+{
+	if (done_init == 0)
+		init_syscall_tps();
+	timepeg_hit(&syscall_start_tps[syscall_no], TPH_MODE_START);
+	current->curr_syscall = syscall_no;
+}
+
+asmlinkage void timepeg_syscall_stop(void)
+{
+	timepeg_hit(&syscall_stop_tps[current->curr_syscall], TPH_MODE_STOP);
+	current->curr_syscall = 0;
+}
+
+/*
+ * We're called when the scheduler is about to switch to another process
+ */
+
+void timepeg_schedule_switchout(void)
+{
+	if (done_init == 0)
+		init_syscall_tps();
+	if (current->curr_syscall)
+		timepeg_hit(&schedule_switchout_tps[current->curr_syscall], TPH_MODE_STOP);
+}
+
+void timepeg_schedule_switchin(void)
+{
+	if (done_init == 0)
+		init_syscall_tps();
+	if (current->curr_syscall)
+		timepeg_hit(&schedule_switchin_tps[current->curr_syscall], TPH_MODE_START);
+}
+
+/*
+ * Fault handlers look like system call 255
+ */
+
+void timepeg_start_page_fault(void)
+{
+	if (done_init == 0)
+		init_syscall_tps();
+	timepeg_hit(&syscall_start_tps[NR_syscalls - 1], TPH_MODE_START);
+	current->curr_syscall = NR_syscalls - 1;
+}
+
+void timepeg_stop_page_fault(void)
+{
+	timepeg_hit(&syscall_stop_tps[current->curr_syscall], TPH_MODE_STOP);
+	current->curr_syscall = 0;
+}
+#endif
diff -urN linux-2.4.29/arch/i386/Makefile linux-2.4.29-uc1/arch/i386/Makefile
--- linux-2.4.29/arch/i386/Makefile	2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.29-uc1/arch/i386/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -110,6 +110,14 @@
 DRIVERS += arch/i386/math-emu/math.o
 endif
 
+#
+# If you want the kernel build to build modules outside of the tree
+# then define this and pass it to the main linux makefile
+#
+ifdef EXTRA_MODULE_DIRS
+SUBDIRS += $(EXTRA_MODULE_DIRS)
+endif
+
 arch/i386/kernel: dummy
 	$(MAKE) linuxsubdirs SUBDIRS=arch/i386/kernel
 
diff -urN linux-2.4.29/arch/i386/vmlinux.lds linux-2.4.29-uc1/arch/i386/vmlinux.lds
--- linux-2.4.29/arch/i386/vmlinux.lds	2002-02-25 19:37:53.000000000 +0000
+++ linux-2.4.29-uc1/arch/i386/vmlinux.lds	2005-06-14 02:11:22.000000000 +0100
@@ -40,7 +40,7 @@
 
   . = ALIGN(4096);		/* Init code and data */
   __init_begin = .;
-  .text.init : { *(.text.init) }
+  .text.init : { *(.text.init) *(.text.exit) }
   .data.init : { *(.data.init) }
   . = ALIGN(16);
   __setup_start = .;
@@ -66,7 +66,6 @@
 
   /* Sections to be discarded */
   /DISCARD/ : {
-	*(.text.exit)
 	*(.data.exit)
 	*(.exitcall.exit)
 	}
diff -urN linux-2.4.29/arch/m68knommu/Boards.mk linux-2.4.29-uc1/arch/m68knommu/Boards.mk
--- linux-2.4.29/arch/m68knommu/Boards.mk	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/Boards.mk	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,231 @@
+# Put definitions for platforms and boards in here.
+
+ifdef CONFIG_M68328
+PLATFORM := 68328
+ifdef CONFIG_PILOT
+BOARD := pilot
+endif
+endif
+
+ifdef CONFIG_M68EZ328
+PLATFORM := 68EZ328
+ifdef CONFIG_PILOT
+BOARD := PalmV
+endif
+ifdef CONFIG_UCSIMM
+BOARD := ucsimm
+endif
+ifdef CONFIG_CWEZ328
+BOARD := cwez328
+endif
+ifdef CONFIG_ALMA_ANS
+BOARD := alma_ans
+endif
+ifdef CONFIG_M68EZ328ADS
+BOARD := ads
+endif
+endif
+
+#(es)
+ifdef CONFIG_M68VZ328
+PLATFORM := 68VZ328
+ifdef CONFIG_UCDIMM
+BOARD := ucdimm
+endif
+ifdef CONFIG_CWVZ328
+BOARD := cwvz328
+endif
+ifdef CONFIG_DRAGEN2
+BOARD := de2
+endif
+ifdef CONFIG_DRAGONIXVZ
+BOARD := dragonixvz
+endif
+ifdef CONFIG_CLIE
+BOARD := clie
+endif
+endif
+#(/es)
+
+ifdef CONFIG_M68332
+PLATFORM := 68332
+endif
+
+ifdef CONFIG_M68EN302
+PLATFORM := 68EN302
+endif
+
+ifdef CONFIG_M68360
+PLATFORM := 68360
+BOARD :=uCquicc
+endif
+
+ifdef CONFIG_M5204
+PLATFORM := 5204
+BOARD := SBC5204
+endif
+
+ifdef CONFIG_M5206
+PLATFORM := 5206
+BOARD := ARNEWSH
+endif
+
+ifdef CONFIG_M5206e
+PLATFORM := 5206e
+ifdef CONFIG_MOTOROLA
+BOARD := MOTOROLA
+endif
+ifdef CONFIG_ELITE
+BOARD := eLITE
+endif
+ifdef CONFIG_NETtel
+BOARD := NETtel
+endif
+ifdef CONFIG_TELOS
+BOARD := toolvox
+endif
+ifdef CONFIG_CFV240
+BOARD := CFV240
+endif
+endif
+
+ifdef CONFIG_M5235
+PLATFORM := 5235
+ifdef CONFIG_M5235EVB
+BOARD := M5235EVB
+endif
+endif
+
+ifdef CONFIG_M5249
+PLATFORM := 5249
+ifdef CONFIG_MOTOROLA
+BOARD := MOTOROLA
+endif
+ifdef CONFIG_NETBURNER
+BOARD := NETBURNER
+endif
+endif
+
+ifdef CONFIG_M527x
+PLATFORM := 527x
+ifdef CONFIG_M5271EVB
+BOARD := M5271EVB
+endif
+ifdef CONFIG_M5275EVB
+BOARD := M5275EVB
+endif
+endif
+
+ifdef CONFIG_M5272
+PLATFORM := 5272
+ifdef CONFIG_MOTOROLA
+BOARD := MOTOROLA
+endif
+ifdef CONFIG_NETtel
+BOARD := NETtel
+endif
+ifdef CONFIG_SE1100
+BOARD := SE1100
+endif
+ifdef CONFIG_GILBARCONAP
+BOARD := NAP
+endif
+ifdef CONFIG_COBRA5272
+BOARD := senTec
+endif
+ifdef CONFIG_BOARD_UC5272
+BOARD := uC5272
+endif
+ifdef CONFIG_BOARD_MOD5272
+BOARD := MOD5272
+endif
+ifdef CONFIG_CANCam
+BOARD := CANCam
+endif
+ifdef CONFIG_SCALES
+BOARD := SCALES
+endif
+ifdef CONFIG_SIGNAL_MCP751
+BOARD := MCP751
+endif
+ifdef CONFIG_SNEHA
+BOARD := SNEHA
+endif
+endif
+
+ifdef CONFIG_M5280
+PLATFORM := 5280
+ifdef CONFIG_SSV
+BOARD := SSV
+endif
+endif
+
+ifdef CONFIG_M5282
+PLATFORM := 5282
+ifdef CONFIG_MOTOROLA
+BOARD := MOTOROLA
+endif
+ifdef CONFIG_SSV
+BOARD := SSV
+endif
+ifdef CONFIG_NETBURNER
+BOARD := NETBURNER
+endif
+ifdef CONFIG_FUTURENETBURNER
+BOARD := FutureNetBurnerBadge
+endif
+ifdef CONFIG_AVNET
+BOARD := AVNET
+endif
+ifdef CONFIG_COBRA5282
+BOARD := senTec
+endif
+endif
+
+ifdef CONFIG_M5307
+PLATFORM := 5307
+ifdef CONFIG_ARNEWSH
+BOARD := ARNEWSH
+endif
+ifdef CONFIG_NETtel
+BOARD := NETtel
+endif
+ifdef CONFIG_eLIA
+BOARD := eLIA
+endif
+ifdef CONFIG_DISKtel
+BOARD := DISKtel
+endif
+ifdef CONFIG_SECUREEDGEMP3
+BOARD := MP3
+endif
+ifdef CONFIG_MOTOROLA
+BOARD := MOTOROLA
+endif
+ifdef CONFIG_CLEOPATRA
+BOARD := CLEOPATRA
+endif
+endif
+
+ifdef CONFIG_M5407
+PLATFORM := 5407
+ifdef CONFIG_MOTOROLA
+BOARD := MOTOROLA
+endif
+ifdef CONFIG_CLEOPATRA
+BOARD := CLEOPATRA
+endif
+ifdef CONFIG_SED_SIOSIII
+BOARD := sed_sios
+endif
+endif
+
+ifdef CONFIG_M547x
+PLATFORM := 547x
+ifdef CONFIG_M5475EVB
+BOARD := M5475EVB
+endif
+endif
+
+export BOARD
+export PLATFORM
diff -urN linux-2.4.29/arch/m68knommu/boot/Makefile linux-2.4.29-uc1/arch/m68knommu/boot/Makefile
--- linux-2.4.29/arch/m68knommu/boot/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/boot/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,5 @@
+clean:
+	rm -f *.[oa]
+
+dep depend:
+	:
diff -urN linux-2.4.29/arch/m68knommu/config.in linux-2.4.29-uc1/arch/m68knommu/config.in
--- linux-2.4.29/arch/m68knommu/config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/config.in	2005-06-14 02:21:28.000000000 +0100
@@ -0,0 +1,631 @@
+#############################################################################
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+#
+# based mainly on the arch/i386/config.in and bit of the 2.0, m68knommu
+# config.in
+#
+#############################################################################
+
+mainmenu_name 'uClinux/68k (w/o MMU) Kernel Configuration'
+
+define_bool CONFIG_UCLINUX y
+define_bool CONFIG_UID16 y
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Processor type and features'
+
+choice 'CPU' \
+	"MC68000	CONFIG_M68000 \
+	 MC68EN302	CONFIG_M68EN302 \
+	 MC68328	CONFIG_M68328 \
+         MC68EZ328	CONFIG_M68EZ328 \
+	 MC68VZ328	CONFIG_M68VZ328 \
+	 MC68332	CONFIG_M68332 \
+	 MC68360	CONFIG_M68360 \
+	 MCF5204	CONFIG_M5204 \
+	 MCF5206	CONFIG_M5206 \
+         MCF5206e	CONFIG_M5206e \
+	 MCF5235	CONFIG_M5235 \
+	 MCF5249	CONFIG_M5249 \
+	 MCF5270/1	CONFIG_M5271 \
+	 MCF5272	CONFIG_M5272 \
+	 MCF5274/5	CONFIG_M5275 \
+	 MCF5280	CONFIG_M5280 \
+	 MCF5282	CONFIG_M5282 \
+         MCF5307	CONFIG_M5307 \
+	 MCF5407	CONFIG_M5407 \
+	 MCF547x	CONFIG_M547x" M68EZ328
+
+if [ "$CONFIG_M5271" = "y" -o "$CONFIG_M5275" = "y" ]; then
+	define_bool CONFIG_M527x y
+fi
+
+if [ "$CONFIG_M5204" = "y" -o \
+     "$CONFIG_M5206" = "y" -o \
+     "$CONFIG_M5206e" = "y" -o \
+     "$CONFIG_M5235" = "y" -o \
+     "$CONFIG_M5249" = "y" -o \
+     "$CONFIG_M527x" = "y" -o \
+     "$CONFIG_M5272" = "y" -o \
+     "$CONFIG_M5280" = "y" -o \
+     "$CONFIG_M5282" = "y" -o \
+     "$CONFIG_M5307" = "y" -o \
+     "$CONFIG_M5407" = "y" -o \
+     "$CONFIG_M547x" = "y" ]; then
+	define_bool CONFIG_COLDFIRE y
+fi
+
+if [ "$CONFIG_M68360" = "y" ]; then
+	define_bool CONFIG_360QUICC y
+fi
+
+choice 'CPU CLOCK Frequency' \
+	" AUTO	CONFIG_CLOCK_AUTO \
+	 11MHz	CONFIG_CLOCK_11MHz \
+	 16MHz	CONFIG_CLOCK_16MHz \
+	 20MHz	CONFIG_CLOCK_20MHz \
+	 24MHz	CONFIG_CLOCK_24MHz \
+	 25MHz	CONFIG_CLOCK_25MHz \
+	 29.5MHz CONFIG_CLOCK_29_5MHz \
+	 33MHz	CONFIG_CLOCK_33MHz \
+	 40MHz	CONFIG_CLOCK_40MHz \
+	 45MHz	CONFIG_CLOCK_45MHz \
+	 48MHz	CONFIG_CLOCK_48MHz \
+	 50MHz	CONFIG_CLOCK_50MHz \
+	 54MHz	CONFIG_CLOCK_54MHz \
+	 60MHz	CONFIG_CLOCK_60MHz \
+	 64MHz	CONFIG_CLOCK_64MHz \
+	 66MHz	CONFIG_CLOCK_66MHz \
+	 70MHz	CONFIG_CLOCK_70MHz \
+	 100MHz	CONFIG_CLOCK_100MHz \
+	 140MHz	CONFIG_CLOCK_140MHz \
+	 150MHz	CONFIG_CLOCK_150MHz \
+	 166MHz	CONFIG_CLOCK_166MHz" AUTO
+
+if [ "$CONFIG_M5307" = "y" ]; then
+	bool 'Old mask 5307 (1H55J) silicon' CONFIG_OLDMASK
+fi
+
+comment 'Platform'
+
+if [ "$CONFIG_M68328" = "y" -o \
+     "$CONFIG_M68EZ328" = "y" -o \
+     "$CONFIG_M68VZ328" = "y" ]; then
+	bool 'Simulate vectorized exceptions (debugging user apps on 68000)' CONFIG_PSEUDO_EXCEPTION_VECTOR
+fi
+
+if [ "$CONFIG_M68328" = "y" ]; then
+	bool 'Pilot 1000/5000, PalmPilot Personal/Pro, or PalmIII support' CONFIG_PILOT3
+	if [ "$CONFIG_PILOT3" = "y" ]; then
+		bool '  (X)Copilot support' CONFIG_XCOPILOT_BUGS
+		bool '  Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF
+		bool '  Display memory usage on Pilot screen' CONFIG_PILOT_MEMORY_DISPLAY
+		bool '  Pilot console' CONFIG_PILOT_CONSOLE
+	fi
+fi
+
+if [ "$CONFIG_M68EZ328" = "y" ]; then
+	bool 'Motorola M68EZ328ADS board support' CONFIG_M68EZ328ADS
+	bool 'ALMA Electronics board support' CONFIG_ALMA_ANS
+	bool 'uCsimm module support' CONFIG_UCSIMM
+	if [ "CONFIG_UCSIMM" = "y" ]; then
+		define_bool CONFIG_UCBOOTSTRAP y
+		bool '  Use uCbootstrap system calls' CONFIG_UCBOOTSTRAP
+	fi
+	bool 'Cwlinux cwez328 support' CONFIG_CWEZ328
+	bool 'PalmV support' CONFIG_PILOT5
+	bool 'Use RTC as system timer' CONFIG_M68EZ328_USE_RTC
+fi
+
+if [ "$CONFIG_M68VZ328" = "y" ]; then
+	bool 'uCdimm module support' CONFIG_UCDIMM
+	if [ "$CONFIG_UCDIMM" = "y" ]; then
+		define_bool CONFIG_UCBOOTSTRAP y
+		bool '  Use uCbootstrap system calls' CONFIG_UCBOOTSTRAP
+		bool '  RAM Kernel loads itself from ROM' CONFIG_RELOCATE
+	fi
+	bool 'DragonEngine II board support' CONFIG_DRAGEN2
+	bool 'Dragonix VZ' CONFIG_DRAGONIXVZ
+	bool 'Cwlinux cwvz328 support' CONFIG_CWVZ328
+	if [ "$CONFIG_CWVZ328" = "y" ]; then
+	bool '  2 waitstates for flash' CONFIG_FLASH2WS
+	fi
+	bool 'Clie' CONFIG_CLIE
+fi
+
+if [ "$CONFIG_UCSIMM" = "y" -o "$CONFIG_UCDIMM" = "y" -o "$CONFIG_DRAGEN2" = "y" ]; then
+	bool '  Allow user to access IO directly' CONFIG_DIRECT_IO_ACCESS
+fi
+
+if [ "$CONFIG_UCSIMM" = "y" -o "$CONFIG_UCDIMM" = "y" -o "$CONFIG_DRAGEN2" = "y" -o "$CONFIG_DRAGONIXVZ" = "y" ]; then
+	bool '  Initialize LCD' CONFIG_INIT_LCD
+fi
+
+if [ "$CONFIG_UCSIMM" = "y" -o "$CONFIG_UCDIMM" = "y" -o "$CONFIG_DRAGEN2" = "y" ]; then
+	int '  Memory reservation (MB)' CONFIG_MEMORY_RESERVE 0
+fi
+
+if [ "$CONFIG_UCDIMM" = "y" -o "$CONFIG_DRAGONIXVZ" = "y" ]; then
+	bool '  Use 128HZ RTC scheduler instead of 100HZ timer1' CONFIG_DRAGONBALL_USE_RTC
+fi
+
+if [ "$CONFIG_DRAGONIXVZ" = "y" ]; then
+	bool 'Enable JTAG-FPGA programmer' CONFIG_DRAGONIXVZ_JTAGFPGA
+	if [ "$CONFIG_DRAGONIXVZ_JTAGFPGA" = "y" ]; then
+	choice 'FPGA type' \
+		"EP1K30	CONFIG_FPGA1K30 \
+		EP1K50	CONFIG_FPGA1K50" EP1K30
+	fi
+	bool '2 waitstates for flash' CONFIG_FLASH2WS
+fi
+
+if [ "$CONFIG_M68EN302" = "y" ]; then
+	bool 'Aplio Pro' CONFIG_APLIO_PRO
+	bool 'Aplio Entrecote' CONFIG_APLIO_ENTRECOTE
+fi
+
+if [ "$CONFIG_M68332" = "y" ]; then
+	bool 'SHGLCore support' CONFIG_SHGLCORE
+	if [ "$CONFIG_SHGLCORE" = "y" ]; then
+		bool '  2Meg SHGLCore' CONFIG_SHGLCORE_2MEG
+	fi
+fi
+
+if [ "$CONFIG_M68360" = "y" ]; then
+	bool 'Arcturus uCquicc board support' CONFIG_UCQUICC
+	if [ "$CONFIG_UCQUICC" = "y" ]; then
+		define_bool CONFIG_UCBOOTSTRAP y
+		bool '  Use uCbootstrap system calls' CONFIG_UCBOOTSTRAP
+	fi
+fi
+
+if [ "$CONFIG_M5206" = "y" ]; then
+	bool 'Arnewsh 5206 board support' CONFIG_ARN5206
+fi
+
+if [ "$CONFIG_M5206e" = "y" ]; then
+	bool 'Motorola M5206eC3 board support' CONFIG_M5206eC3
+	bool 'Motorola eLITE-5206e board support' CONFIG_ELITE
+	if [ "$CONFIG_ELITE" = "y" ]; then
+		bool '  SRAM only eLITE-5206e support' CONFIG_SMALL
+	fi
+	bool 'Telos Omnia ToolVox board support' CONFIG_TELOS
+        bool 'Netburner CFV2-40 board support' CONFIG_CFV240
+fi
+
+if [ "$CONFIG_M5235" = "y" ]; then
+	bool 'Motorola M523xEVB board support' CONFIG_M5235EVB
+fi
+
+if [ "$CONFIG_M5249" = "y" ]; then
+	bool 'Motorola M5249C3 board support' CONFIG_M5249C3
+fi
+
+if [ "$CONFIG_M5271" = "y" ]; then
+	bool 'Motorola M5271EVB board support' CONFIG_M5271EVB
+fi
+
+if [ "$CONFIG_M5275" = "y" ]; then
+	bool 'Motorola M5275EVB board support' CONFIG_M5275EVB
+fi
+
+if [ "$CONFIG_M5272" = "y" ]; then
+	bool 'Motorola M5272C3 board support' CONFIG_M5272C3
+	bool 'SecureEdge SE1100 board support' CONFIG_SE1100
+	bool 'Sneha Technologies CPU 16 Bits board support' CONFIG_CPU16B
+	
+	bool 'Netburner MOD5272 board support' CONFIG_BOARD_MOD5272
+	bool 'Arcturus Networks uC5272 dimm board support' CONFIG_BOARD_UC5272
+	if [ "$CONFIG_BOARD_UC5272" = "y" ]; then
+		bool '  Use uCbootstrap system calls' CONFIG_UCBOOTSTRAP
+		bool '  Support for Cramfs ' CONFIG_UC5272_CRAMFS
+		if ["$CONFIG_UC5272_CRAMFS" = "y" ]; then
+			define_bool CONFIG_CRAMFS y
+		fi
+		bool '  ROMFS image not RAM resident' CONFIG_ROMFS_FROM_ROM
+	fi
+	bool 'senTec COBRA5272 board support' CONFIG_COBRA5272
+	if [ "$CONFIG_COBRA5272" = "y" ]; then
+		bool '   Include framebuffer support on COBRA5272' CONFIG_FB_COBRA5272
+	fi
+	if [ "$CONFIG_M5272C3" = "y" ]; then
+		bool 'Support for PPCboot environment variables' CONFIG_PPCBOOT
+	fi
+	bool 'Feith CANCam board support' CONFIG_CANCam
+	bool 'Feith Scales board support' CONFIG_SCALES
+	bool 'Signal MCP751 board support' CONFIG_SIGNAL_MCP751
+fi
+
+if [ "$CONFIG_M5280" = "y" ]; then
+	bool 'SSV DNP5280 board support' CONFIG_DNP5280
+fi
+
+if [ "$CONFIG_M5282" = "y" ]; then
+	bool 'Motorola M5282C3 board support' CONFIG_M5282C3
+ 	bool 'Netburner MOD5282 board support' CONFIG_NETBURNER
+	bool 'Future/Netburner 5282 Badge board support' CONFIG_FUTURENETBURNER
+ 	bool 'Avnet M5282 board support' CONFIG_AVNET5282
+	bool 'Arcturus Networks uC5282 dimm board support' CONFIG_BOARD_UC5282
+	if [ "$CONFIG_BOARD_UC5282" = "y" ]; then
+		define_bool CONFIG_ARCTURUS y
+		bool '  Use uCbootstrap system calls' CONFIG_UCBOOTSTRAP
+		bool '  Support for Cramfs ' CONFIG_UC5272_CRAMFS
+		if ["$CONFIG_UC5282_CRAMFS" = "y" ]; then
+			define_bool CONFIG_CRAMFS y
+		fi
+		bool '  ROMFS image not RAM resident' CONFIG_ROMFS_FROM_ROM
+	fi
+   bool 'senTec COBRA5282 board support' CONFIG_COBRA5282
+fi
+
+if [ "$CONFIG_M5307" = "y" ]; then
+	bool 'Arnewsh 5307 board support' CONFIG_ARN5307
+	bool 'Motorola M5307C3 board support' CONFIG_M5307C3
+	bool 'eLIA board support' CONFIG_eLIA
+	bool 'DISKtel board support' CONFIG_DISKtel
+	bool 'SecureEdge MP3 board support' CONFIG_SECUREEDGEMP3
+fi
+
+if [ "$CONFIG_M5407" = "y" ]; then
+	bool 'Motorola M5407C3 board support' CONFIG_M5407C3
+	bool 'SED SIOS III board support' CONFIG_SED_SIOSIII
+fi
+
+if [ "$CONFIG_M5307" = "y" -o \
+     "$CONFIG_M5407" = "y" ]; then
+	bool 'Feith CLEOPATRA board support' CONFIG_CLEOPATRA
+fi
+if [ "$CONFIG_AVNET5282" = "y" ]; then
+	define_bool CONFIG_AVNET y
+fi
+
+if [ "$CONFIG_M5206e" = "y" -o \
+     "$CONFIG_M5272" = "y" -o \
+     "$CONFIG_M5307" = "y" ]; then
+	bool 'SecureEdge/NETtel board support' CONFIG_NETtel
+	bool 'SnapGear router board support' CONFIG_SNAPGEAR
+	bool '  ROMFS image not RAM resident' CONFIG_ROMFS_FROM_ROM
+fi
+
+if [ "$CONFIG_M547x" = "y" ]; then
+	bool 'Motorola M5475EVB board support' CONFIG_M5475EVB
+fi
+
+if [ "$CONFIG_PILOT3" = "y" -o \
+     "$CONFIG_PILOT5" = "y" ]; then
+	define_bool CONFIG_PILOT y
+fi
+if [ "$CONFIG_APLIO_PRO" = "y" -o "$CONFIG_APLIO_ENTRECOTE" = "y" ]; then
+	define_bool CONFIG_APLIO y
+fi
+if [ "$CONFIG_ARN5206" = "y" -o \
+     "$CONFIG_ARN5307" = "y" ]; then
+	define_bool CONFIG_ARNEWSH y
+fi
+if [ "$CONFIG_M5206eC3" = "y" -o \
+     "$CONFIG_M5235EVB" = "y" -o \
+     "$CONFIG_M5249C3" = "y" -o \
+     "$CONFIG_M5271EVB" = "y" -o \
+     "$CONFIG_M5272C3" = "y" -o \
+     "$CONFIG_M5275EVB" = "y" -o \
+     "$CONFIG_M5282C3" = "y" -o \
+     "$CONFIG_M5307C3" = "y" -o \
+     "$CONFIG_M5407C3" = "y" -o \
+     "$CONFIG_M5475EVB" = "y" ]; then
+	define_bool CONFIG_MOTOROLA y
+fi
+
+if [ "$CONFIG_CPU16B" = "y" ]; then
+	define_bool CONFIG_SNEHA y
+fi
+
+if [ "$CONFIG_CLEOPATRA" = "y" -o \
+     "$CONFIG_CANCam" = "y" -o \
+     "$CONFIG_SCALES" = "y" ]; then
+	define_bool CONFIG_HW_FEITH y
+fi
+
+if [ "$CONFIG_DNP5282" = "y" ]; then
+	define_bool CONFIG_SSV y
+fi
+
+if [ "$CONFIG_DNP5280" = "y" ]; then
+   define_bool CONFIG_SSV y
+fi
+ 
+choice 'RAM size' \
+	"AUTO	CONFIG_RAMAUTO \
+	  4MB	CONFIG_RAM4MB \
+	  8MB	CONFIG_RAM8MB \
+	 16MB	CONFIG_RAM16MB \
+	 32MB	CONFIG_RAM32MB \
+	 64MB	CONFIG_RAM64MB" AUTO
+choice 'RAM bit width' \
+	" AUTO	CONFIG_AUTOBIT \
+	  8bit	CONFIG_RAM8BIT \
+	 16bit	CONFIG_RAM16BIT \
+	 32bit	CONFIG_RAM32bit" AUTO
+
+choice 'Kernel executes from' \
+	"RAM	CONFIG_RAMKERNEL \
+	 ROM	CONFIG_ROMKERNEL \
+	 HIMEM  CONFIG_HIMEMKERNEL" ROM
+
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'General setup'
+
+bool 'Networking support' CONFIG_NET
+
+bool 'PCI support' CONFIG_PCI
+if [ "$CONFIG_PCI" = "y" ]; then
+   choice '  PCI access mode' \
+	"BIOS		CONFIG_PCI_GOBIOS	\
+	 Direct		CONFIG_PCI_GODIRECT	\
+	 Any		CONFIG_PCI_GOANY"	Any
+   if [ "$CONFIG_PCI_GOBIOS" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then
+      define_bool CONFIG_PCI_BIOS y
+   fi
+   if [ "$CONFIG_PCI_GODIRECT" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then
+      define_bool CONFIG_PCI_DIRECT y
+   fi
+fi
+
+source drivers/pci/Config.in
+
+bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+
+if [ "$CONFIG_HOTPLUG" = "y" ] ; then
+   source drivers/pcmcia/Config.in
+else
+   define_bool CONFIG_PCMCIA n
+fi
+
+bool 'System V IPC' CONFIG_SYSVIPC
+bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   choice 'Kernel core (/proc/kcore) format' \
+	"ELF		CONFIG_KCORE_ELF	\
+	 A.OUT		CONFIG_KCORE_AOUT" ELF
+fi
+tristate 'Kernel support for flat binaries' CONFIG_BINFMT_FLAT
+if [ "$CONFIG_BINFMT_FLAT" != "n" ]; then
+   bool '    Enable ZFLAT support' CONFIG_BINFMT_ZFLAT
+   bool '    Enable shared FLAT support' CONFIG_BINFMT_SHARED_FLAT
+fi
+tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
+tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+
+bool 'Power Management support' CONFIG_PM
+
+dep_bool '  ACPI support' CONFIG_ACPI $CONFIG_PM
+if [ "$CONFIG_ACPI" != "n" ]; then
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      bool '    ACPI interpreter (EXPERIMENTAL)' CONFIG_ACPI_INTERPRETER
+      bool '    Enter S1 for sleep (EXPERIMENTAL)' CONFIG_ACPI_S1_SLEEP
+   fi
+fi
+
+if [ "$CONFIG_UCSIMM" = "y" -o "$CONFIG_UCDIMM" = "y" ]; then
+   dep_bool '  Doze sleep mode only (clocks running)' CONFIG_PM_DOZE_ONLY $CONFIG_PM
+   dep_bool '  Wake up on power button (IRQ3)' CONFIG_PM_POWER_BUTTON_IRQ3 $CONFIG_PM
+   dep_bool '  Support user level pm_helper (/sbin/pm_helper)' CONFIG_PM_HELPER $CONFIG_PM
+fi
+
+dep_tristate '  Advanced Power Management BIOS support' CONFIG_APM $CONFIG_PM
+if [ "$CONFIG_APM" != "n" ]; then
+   bool '    Ignore USER SUSPEND' CONFIG_APM_IGNORE_USER_SUSPEND
+   bool '    Enable PM at boot time' CONFIG_APM_DO_ENABLE
+   bool '    Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE
+   bool '    Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK
+   bool '    RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT
+   bool '    Allow interrupts during APM BIOS calls' CONFIG_APM_ALLOW_INTS
+   bool '    Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF
+fi
+
+endmenu
+
+#############################################################################
+
+source drivers/mtd/Config.in
+
+source drivers/parport/Config.in
+
+source drivers/pnp/Config.in
+
+source drivers/block/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   source net/Config.in
+fi
+
+source drivers/telephony/Config.in
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'ATA/IDE/MFM/RLL support'
+
+tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+
+if [ "$CONFIG_IDE" != "n" ]; then
+  source drivers/ide/Config.in
+else
+  define_bool CONFIG_BLK_DEV_HD n
+fi
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'SCSI support'
+
+tristate 'SCSI support' CONFIG_SCSI
+
+if [ "$CONFIG_SCSI" != "n" ]; then
+   source drivers/scsi/Config.in
+fi
+endmenu
+
+#############################################################################
+
+source drivers/ieee1394/Config.in
+
+source drivers/message/i2o/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Network device support'
+
+   bool 'Network device support' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+      if [ "$CONFIG_ATM" = "y" ]; then
+         source drivers/atm/Config.in
+      fi
+   fi
+   endmenu
+fi
+
+source net/ax25/Config.in
+
+source net/irda/Config.in
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'ISDN subsystem'
+if [ "$CONFIG_NET" != "n" ]; then
+   tristate 'ISDN support' CONFIG_ISDN
+   if [ "$CONFIG_ISDN" != "n" ]; then
+      source drivers/isdn/Config.in
+   fi
+fi
+endmenu
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+
+bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+   source drivers/cdrom/Config.in
+fi
+endmenu
+
+#############################################################################
+
+source drivers/char/Config.in
+
+#source drivers/misc/Config.in
+
+source fs/Config.in
+
+if [ "$CONFIG_VT" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Console drivers'
+   bool 'VGA text console' CONFIG_VGA_CONSOLE
+   bool 'Video mode selection support' CONFIG_VIDEO_SELECT
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
+      source drivers/video/Config.in
+   fi
+   endmenu
+fi
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Sound'
+
+tristate 'Sound card support' CONFIG_SOUND
+if [ "$CONFIG_SOUND" != "n" ]; then
+   source drivers/sound/Config.in
+fi
+endmenu
+
+#############################################################################
+
+source drivers/usb/Config.in
+
+#############################################################################
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+bool 'Full Symbolic/Source Debugging support' CONFIG_FULLDEBUG
+#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
+bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	bool 'Non power-of-2 kernel allocator (EXPERIMENTAL)' CONFIG_CONTIGUOUS_PAGE_ALLOC
+	dep_bool '  include /proc/mem_map' CONFIG_MEM_MAP $CONFIG_CONTIGUOUS_PAGE_ALLOC
+fi
+
+if [ "$CONFIG_HW_FEITH" = "y" ]; then
+  if [ "$CONFIG_CONTIGUOUS_PAGE_ALLOC" != "y" ]; then
+    bool 'Allow allocating large blocks (> 1MB) of memory' CONFIG_NO_MMU_LARGE_ALLOCS
+  fi
+fi
+
+bool 'Kernel profiling support' CONFIG_PROFILE
+if [ "$CONFIG_PROFILE" = "y" ]; then
+  int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+  bool 'Use fast second timer for profiling' CONFIG_HIGHPROFILE
+fi
+
+if [ "$CONFIG_COLDFIRE" = "y" ]; then
+	bool 'Panic/Dump to FLASH' CONFIG_DUMPTOFLASH
+fi
+
+bool 'Suppress Kernel BUG Messages' CONFIG_NO_KERNEL_MSG
+
+bool 'Reduce kernel task size to 1 page' CONFIG_SMALL_TASKS
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_COLDFIRE" = "y" -a "$CONFIG_FULLDEBUG" = "n" ]; then
+    bool 'Disable BDM signals' CONFIG_BDM_DISABLE
+fi
+
+bool 'Compiled-in Kernel Boot Parameter' CONFIG_BOOTPARAM
+if [ "$CONFIG_BOOTPARAM" = "y" ]; then
+  string 'Kernel Boot Parameter' CONFIG_BOOTPARAM_STRING ""
+fi
+
+endmenu
+
+
+#############################################################################
+
+source crypto/Config.in
+source lib/Config.in
+
+#############################################################################
diff -urN linux-2.4.29/arch/m68knommu/console/68328fb.c linux-2.4.29-uc1/arch/m68knommu/console/68328fb.c
--- linux-2.4.29/arch/m68knommu/console/68328fb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/console/68328fb.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,1127 @@
+/*
+ * linux/arch/m68knommu/console/68328fb.c -- Low level implementation of the
+ *                                           mc68328 LCD frame buffer device
+ *
+ *    Copyright (C) 1998,1999 Kenneth Albanowski <kjahds@kjahds.com>,
+ *                            The Silver Hammer Group, Ltd.
+ *
+ *
+ * This file is based on the Amiga CyberVision frame buffer device (Cyberfb.c):
+ *
+ *    Copyright (C) 1996 Martin Apel
+ *                       Geert Uytterhoeven
+ *
+ *
+ * This file is based on the Amiga frame buffer device (amifb.c):
+ *
+ *    Copyright (C) 1995 Geert Uytterhoeven
+ *
+ *
+ * History:
+ *   - 17 Feb 98: Original version by Kenneth Albanowski <kjahds@kjahds.com>
+ *
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/config.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <linux/fb.h>
+
+
+#define arraysize(x)    (sizeof(x)/sizeof(*(x)))
+
+struct mc68328_fb_par {
+   int xres;
+   int yres;
+   int bpp;
+};
+
+static struct mc68328_fb_par current_par;
+
+static int current_par_valid = 0;
+static int currcon = 0;
+
+static struct display disp[MAX_NR_CONSOLES];
+static struct fb_info fb_info;
+
+static int node;        /* node of the /dev/fb?current file */
+
+
+   /*
+    *    Switch for Chipset Independency
+    */
+
+static struct fb_hwswitch {
+
+   /* Initialisation */
+
+   int (*init)(void);
+
+   /* Display Control */
+
+   int (*encode_fix)(struct fb_fix_screeninfo *fix, struct mc68328_fb_par *par);
+   int (*decode_var)(struct fb_var_screeninfo *var, struct mc68328_fb_par *par);
+   int (*encode_var)(struct fb_var_screeninfo *var, struct mc68328_fb_par *par);
+   int (*getcolreg)(u_int regno, u_int *red, u_int *green, u_int *blue,
+                    u_int *transp);
+   int (*setcolreg)(u_int regno, u_int red, u_int green, u_int blue,
+                    u_int transp);
+   void (*blank)(int blank);
+} *fbhw;
+
+
+   /*
+    *    Frame Buffer Name
+    */
+
+static char mc68328_fb_name[16] = "mc68328";
+
+
+   /*
+    *    mc68328vision Graphics Board
+    */
+
+#define CYBER8_WIDTH 1152
+#define CYBER8_HEIGHT 886
+#define CYBER8_PIXCLOCK 12500    /* ++Geert: Just a guess */
+
+#define CYBER16_WIDTH 800
+#define CYBER16_HEIGHT 600
+#define CYBER16_PIXCLOCK 25000   /* ++Geert: Just a guess */
+
+#define PALM_WIDTH 160
+#define PALM_HEIGHT 160
+
+
+/*static int mc68328Key = 0;
+static u_char mc68328_colour_table [256][4];*/
+static unsigned long mc68328Mem;
+static unsigned long mc68328Size;
+
+static long *memstart;
+
+
+   /*
+    *    Predefined Video Mode Names
+    */
+
+static char *mc68328_fb_modenames[] = {
+
+   /*
+    *    Autodetect (Default) Video Mode
+    */
+
+   "default",
+
+   /*
+    *    Predefined Video Modes
+    */
+    
+   "Palm",            /* Palm Pilot devices, 1.0 and higher */
+   "Palm Grey",            /* Palm Pilot devices, 1.0 and higher */
+
+   /*
+    *    Dummy Video Modes
+    */
+
+   "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
+   "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
+   "dummy", "dummy", "dummy", "dummy",
+
+   /*
+    *    User Defined Video Modes
+    *
+    *    This doesn't work yet!!
+    */
+
+   "user0", "user1", "user2", "user3", "user4", "user5", "user6", "user7"
+};
+
+
+   /*
+    *    Predefined Video Mode Definitions
+    */
+
+static struct fb_var_screeninfo mc68328_fb_predefined[] = {
+
+   /*
+    *    Autodetect (Default) Video Mode
+    */
+
+   { 0, },
+
+   /*
+    *    Predefined Video Modes
+    */
+    
+   {
+      /* Palm */
+      PALM_WIDTH, PALM_HEIGHT, PALM_WIDTH, PALM_HEIGHT, 
+      0, 0, 
+      1, -1,
+      {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 0, 0},
+      0, 0, 
+      -1, -1, /* phys height, width */
+      FB_ACCEL_NONE, 
+      0, 0, 0, 0, 0, 0, 0, /* timing */
+      0, /* sync */
+      FB_VMODE_NONINTERLACED
+   },
+   {
+      /* Palm Grey */
+      PALM_WIDTH, PALM_HEIGHT, PALM_WIDTH, PALM_HEIGHT, 
+      0, 0, 
+      2, -1,
+      {0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0},
+      0, 0, 
+      -1, -1, /* phys height, width */
+      FB_ACCEL_NONE, 
+      0, 0, 0, 0, 0, 0, 0, /* timing */
+      0, /* sync */
+      FB_VMODE_NONINTERLACED
+   },
+
+   /*
+    *    Dummy Video Modes
+    */
+
+   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, },
+   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, },
+   { 0, }, { 0, },
+
+   /*
+    *    User Defined Video Modes
+    */
+
+   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }
+};
+
+
+#define NUM_TOTAL_MODES    arraysize(mc68328_fb_predefined)
+#define NUM_PREDEF_MODES   (3)
+
+
+static int mc68328fb_inverse = 0;
+static int mc68328fb_mode = 0;
+static int mc68328fbCursorMode = 0;
+
+
+   /*
+    *    Some default modes
+    */
+
+#define PALM_DEFMODE     (1)
+#define CYBER16_DEFMODE    (2)
+
+
+   /*
+    *    Interface used by the world
+    */
+
+void mc68328_video_setup(char *options, int *ints);
+
+static int mc68328_fb_get_fix(struct fb_fix_screeninfo *fix, int con);
+static int mc68328_fb_get_var(struct fb_var_screeninfo *var, int con);
+static int mc68328_fb_set_var(struct fb_var_screeninfo *var, int con);
+static int mc68328_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con);
+static int mc68328_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con);
+static int mc68328_fb_pan_display(struct fb_var_screeninfo *var, int con);
+static int mc68328_fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+                          u_long arg, int con);
+
+
+   /*
+    *    Interface to the low level console driver
+    */
+
+struct fb_info *mc68328_fb_init(long *mem_start); /* Through amiga_fb_init() */
+static int mc68328fb_switch(int con);
+static int mc68328fb_updatevar(int con);
+static void mc68328fb_blank(int blank);
+
+
+   /*
+    *    Accelerated Functions used by the low level console driver
+    */
+
+void mc68328_WaitQueue(u_short fifo);
+void mc68328_WaitBlit(void);
+void mc68328_BitBLT(u_short curx, u_short cury, u_short destx, u_short desty,
+                  u_short width, u_short height, u_short mode);
+void mc68328_RectFill(u_short x, u_short y, u_short width, u_short height,
+                    u_short mode, u_short color);
+void mc68328_MoveCursor(u_short x, u_short y);
+
+
+   /*
+    *   Hardware Specific Routines
+    */
+
+static int mc68328_init(void);
+static int mc68328_encode_fix(struct fb_fix_screeninfo *fix,
+                          struct mc68328_fb_par *par);
+static int mc68328_decode_var(struct fb_var_screeninfo *var,
+                          struct mc68328_fb_par *par);
+static int mc68328_encode_var(struct fb_var_screeninfo *var,
+                          struct mc68328_fb_par *par);
+static int mc68328_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                         u_int *transp);
+static int mc68328_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp);
+static void mc68328_blank(int blank);
+
+
+   /*
+    *    Internal routines
+    */
+
+static void mc68328_fb_get_par(struct mc68328_fb_par *par);
+static void mc68328_fb_set_par(struct mc68328_fb_par *par);
+static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
+static struct fb_cmap *get_default_colormap(int bpp);
+static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
+                          int kspc);
+static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
+                          int kspc);
+static void do_install_cmap(int con);
+static void memcpy_fs(int fsfromto, void *to, void *from, int len);
+static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto);
+static int alloc_cmap(struct fb_cmap *cmap, int len, int transp);
+static void mc68328_fb_set_disp(int con);
+static int get_video_mode(const char *name);
+
+
+/* -------------------- Hardware specific routines -------------------------- */
+
+
+   /*
+    *    Initialization
+    *
+    *    Set the default video mode for this chipset. If a video mode was
+    *    specified on the command line, it will override the default mode.
+    */
+
+static int mc68328_init(void)
+{
+	/*int i;
+	char size;
+	volatile u_long *CursorBase;
+	unsigned long board_addr;
+	struct ConfigDev *cd;*/
+
+	if (mc68328fb_mode == -1)
+		mc68328fb_mode = PALM_DEFMODE;
+
+	mc68328Mem = (*(volatile unsigned long*)0xFFFFFA00);
+	/*kernel_map (board_addr + 0x01400000, 0x00400000,*/
+	mc68328Size = 160*160/8;
+
+	return (0);
+}
+
+
+   /*
+    *    This function should fill in the `fix' structure based on the
+    *    values in the `par' structure.
+    */
+
+static int mc68328_encode_fix(struct fb_fix_screeninfo *fix,
+                          struct mc68328_fb_par *par)
+{
+   int i;
+
+   strcpy(fix->id, mc68328_fb_name);
+   fix->smem_start = mc68328Mem;
+   fix->smem_len = mc68328Size;
+
+   fix->type = FB_TYPE_PACKED_PIXELS;
+   fix->type_aux = 0;
+   if (par->bpp == 1)
+      fix->visual = FB_VISUAL_MONO01;
+   else
+      fix->visual = FB_VISUAL_DIRECTCOLOR;
+
+   fix->xpanstep = 0;
+   fix->ypanstep = 0;
+   fix->ywrapstep = 0;
+
+   for (i = 0; i < arraysize(fix->reserved); i++)
+      fix->reserved[i] = 0;
+
+   return(0);
+}
+
+
+   /*
+    *    Get the video params out of `var'. If a value doesn't fit, round
+    *    it up, if it's too big, return -EINVAL.
+    */
+
+static int mc68328_decode_var(struct fb_var_screeninfo *var,
+                          struct mc68328_fb_par *par)
+{
+   par->xres = PALM_WIDTH;
+   par->yres = PALM_HEIGHT;
+   par->bpp = 1;
+   return(0);
+}
+
+
+   /*
+    *    Fill the `var' structure based on the values in `par' and maybe
+    *    other values read out of the hardware.
+    */
+
+static int mc68328_encode_var(struct fb_var_screeninfo *var,
+                          struct mc68328_fb_par *par)
+{
+   int i;
+
+   var->xres = par->xres;
+   var->yres = par->yres;
+   var->xres_virtual = par->xres;
+   var->yres_virtual = par->yres;
+   var->xoffset = 0;
+   var->yoffset = 0;
+
+   var->bits_per_pixel = par->bpp;
+   var->grayscale = -1;
+
+   var->red.offset = 0;
+   var->red.length = par->bpp;
+   var->red.msb_right = 0;
+   var->blue = var->green = var->red;
+
+   var->transp.offset = 0;
+   var->transp.length = 0;
+   var->transp.msb_right = 0;
+
+   var->nonstd = 0;
+   var->activate = 0;
+
+   var->height = -1;
+   var->width = -1;
+   var->accel = FB_ACCEL_NONE;
+   var->vmode = FB_VMODE_NONINTERLACED;
+
+   /* Dummy values */
+
+   var->pixclock = 0;
+   var->sync = 0;
+   var->left_margin = 0;
+   var->right_margin = 0;
+   var->upper_margin = 0;
+   var->lower_margin = 0;
+   var->hsync_len = 0;
+   var->vsync_len = 0;
+
+   for (i = 0; i < arraysize(var->reserved); i++)
+      var->reserved[i] = 0;
+
+   return(0);
+}
+
+
+   /*
+    *    Set a single color register. The values supplied are already
+    *    rounded down to the hardware's capabilities (according to the
+    *    entries in the var structure). Return != 0 for invalid regno.
+    */
+
+static int mc68328_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp)
+{
+	return 1;
+#if 0
+if (regno > 255)
+  return (1);
+
+*(mc68328Regs + 0x3c8) = (char)regno;
+mc68328_colour_table [regno][0] = red & 0xff;
+mc68328_colour_table [regno][1] = green & 0xff;
+mc68328_colour_table [regno][2] = blue & 0xff;
+mc68328_colour_table [regno][3] = transp;
+
+*(mc68328Regs + 0x3c9) = (red & 0xff) >> 2;
+*(mc68328Regs + 0x3c9) = (green & 0xff) >> 2;
+*(mc68328Regs + 0x3c9) = (blue & 0xff) >> 2;
+
+return (0);
+#endif
+}
+
+
+   /*
+    *    Read a single color register and split it into
+    *    colors/transparent. Return != 0 for invalid regno.
+    */
+
+static int mc68328_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                         u_int *transp)
+{
+	return 1;
+#if 0
+if (regno >= 256)
+  return (1);
+*red    = mc68328_colour_table [regno][0];
+*green  = mc68328_colour_table [regno][1];
+*blue   = mc68328_colour_table [regno][2];
+*transp = mc68328_colour_table [regno][3];
+return (0);
+#endif
+}
+
+
+   /*
+    *    (Un)Blank the screen
+    */
+
+void mc68328_blank(int blank)
+{
+#if 0
+	if (blank)
+		(*(volatile unsigned char*)0xFFFFFA27) &= ~128;
+	else
+		(*(volatile unsigned char*)0xFFFFFA27) |= 128;
+#endif
+}
+
+
+/**************************************************************
+ * We are waiting for "fifo" FIFO-slots empty
+ */
+void mc68328_WaitQueue (u_short fifo)
+{
+}
+
+/**************************************************************
+ * We are waiting for Hardware (Graphics Engine) not busy
+ */
+void mc68328_WaitBlit (void)
+{
+}
+
+/**************************************************************
+ * BitBLT - Through the Plane
+ */
+void mc68328_BitBLT (u_short curx, u_short cury, u_short destx, u_short desty,
+                   u_short width, u_short height, u_short mode)
+{
+#if 0
+u_short blitcmd = S3_BITBLT;
+
+/* Set drawing direction */
+/* -Y, X maj, -X (default) */
+if (curx > destx)
+  blitcmd |= 0x0020;  /* Drawing direction +X */
+else
+  {
+  curx  += (width - 1);
+  destx += (width - 1);
+  }
+
+if (cury > desty)
+  blitcmd |= 0x0080;  /* Drawing direction +Y */
+else
+  {
+  cury  += (height - 1);
+  desty += (height - 1);
+  }
+
+mc68328_WaitQueue (0x8000);
+
+*((u_short volatile *)(mc68328Regs + S3_PIXEL_CNTL)) = 0xa000;
+*((u_short volatile *)(mc68328Regs + S3_FRGD_MIX)) = (0x0060 | mode);
+
+*((u_short volatile *)(mc68328Regs + S3_CUR_X)) = curx;
+*((u_short volatile *)(mc68328Regs + S3_CUR_Y)) = cury;
+
+*((u_short volatile *)(mc68328Regs + S3_DESTX_DIASTP)) = destx;
+*((u_short volatile *)(mc68328Regs + S3_DESTY_AXSTP)) = desty;
+
+*((u_short volatile *)(mc68328Regs + S3_MIN_AXIS_PCNT)) = height - 1;
+*((u_short volatile *)(mc68328Regs + S3_MAJ_AXIS_PCNT)) = width  - 1;
+
+*((u_short volatile *)(mc68328Regs + S3_CMD)) = blitcmd;
+#endif
+}
+
+/**************************************************************
+ * Rectangle Fill Solid
+ */
+void mc68328_RectFill (u_short x, u_short y, u_short width, u_short height,
+                     u_short mode, u_short color)
+{
+#if 0
+u_short blitcmd = S3_FILLEDRECT;
+
+mc68328_WaitQueue (0x8000);
+
+*((u_short volatile *)(mc68328Regs + S3_PIXEL_CNTL)) = 0xa000;
+*((u_short volatile *)(mc68328Regs + S3_FRGD_MIX)) = (0x0020 | mode);
+
+*((u_short volatile *)(mc68328Regs + S3_MULT_MISC)) = 0xe000;
+*((u_short volatile *)(mc68328Regs + S3_FRGD_COLOR)) = color;
+
+*((u_short volatile *)(mc68328Regs + S3_CUR_X)) = x;
+*((u_short volatile *)(mc68328Regs + S3_CUR_Y)) = y;
+
+*((u_short volatile *)(mc68328Regs + S3_MIN_AXIS_PCNT)) = height - 1;
+*((u_short volatile *)(mc68328Regs + S3_MAJ_AXIS_PCNT)) = width  - 1;
+
+*((u_short volatile *)(mc68328Regs + S3_CMD)) = blitcmd;
+#endif
+}
+
+
+/**************************************************************
+ * Move cursor to x, y
+ */
+void mc68328_MoveCursor (u_short x, u_short y)
+{
+	(*(volatile unsigned short*)0xFFFFFA18) = (mc68328fbCursorMode << 14) | x;
+	(*(volatile unsigned short*)0xFFFFFA1A) = y;
+#if 0
+*(mc68328Regs + S3_CRTC_ADR)  = 0x39;
+*(mc68328Regs + S3_CRTC_DATA) = 0xa0;
+
+*(mc68328Regs + S3_CRTC_ADR)  = S3_HWGC_ORGX_H;
+*(mc68328Regs + S3_CRTC_DATA) = (char)((x & 0x0700) >> 8);
+*(mc68328Regs + S3_CRTC_ADR)  = S3_HWGC_ORGX_L;
+*(mc68328Regs + S3_CRTC_DATA) = (char)(x & 0x00ff);
+
+*(mc68328Regs + S3_CRTC_ADR)  = S3_HWGC_ORGY_H;
+*(mc68328Regs + S3_CRTC_DATA) = (char)((y & 0x0700) >> 8);
+*(mc68328Regs + S3_CRTC_ADR)  = S3_HWGC_ORGY_L;
+*(mc68328Regs + S3_CRTC_DATA) = (char)(y & 0x00ff);
+#endif
+}
+
+
+/* -------------------- Interfaces to hardware functions -------------------- */
+
+
+static struct fb_hwswitch mc68328_switch = {
+   mc68328_init, mc68328_encode_fix, mc68328_decode_var, mc68328_encode_var,
+   mc68328_getcolreg, mc68328_setcolreg, mc68328_blank
+};
+
+
+/* -------------------- Generic routines ------------------------------------ */
+
+
+   /*
+    *    Fill the hardware's `par' structure.
+    */
+
+static void mc68328_fb_get_par(struct mc68328_fb_par *par)
+{
+   if (current_par_valid)
+      *par = current_par;
+   else
+      fbhw->decode_var(&mc68328_fb_predefined[mc68328fb_mode], par);
+}
+
+
+static void mc68328_fb_set_par(struct mc68328_fb_par *par)
+{
+   current_par = *par;
+   current_par_valid = 1;
+}
+
+
+static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
+{
+   int err, activate;
+   struct mc68328_fb_par par;
+
+   if ((err = fbhw->decode_var(var, &par)))
+      return(err);
+   activate = var->activate;
+   if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
+      mc68328_fb_set_par(&par);
+   fbhw->encode_var(var, &par);
+   var->activate = activate;
+   return(0);
+}
+
+
+   /*
+    *    Default Colormaps
+    */
+
+static u_short red16[] =
+   { 0xc000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0x0000,
+     0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff};
+static u_short green16[] =
+   { 0xc000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0x0000,
+     0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff};
+static u_short blue16[] =
+   { 0xc000, 0x0000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0x0000,
+     0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff};
+
+
+static struct fb_cmap default_16_colors =
+   { 0, 16, red16, green16, blue16, NULL };
+
+
+static struct fb_cmap *get_default_colormap(int bpp)
+{
+   return(&default_16_colors);
+}
+
+
+#define CNVT_TOHW(val,width)     ((((val)<<(width))+0x7fff-(val))>>16)
+#define CNVT_FROMHW(val,width)   (((width) ? ((((val)<<16)-(val)) / \
+                                              ((1<<(width))-1)) : 0))
+
+static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
+                          int kspc)
+{
+   int i, start;
+   u_short *red, *green, *blue, *transp;
+   u_int hred, hgreen, hblue, htransp;
+
+   red = cmap->red;
+   green = cmap->green;
+   blue = cmap->blue;
+   transp = cmap->transp;
+   start = cmap->start;
+   if (start < 0)
+      return(-EINVAL);
+   for (i = 0; i < cmap->len; i++) {
+      if (fbhw->getcolreg(start++, &hred, &hgreen, &hblue, &htransp))
+         return(0);
+      hred = CNVT_FROMHW(hred, var->red.length);
+      hgreen = CNVT_FROMHW(hgreen, var->green.length);
+      hblue = CNVT_FROMHW(hblue, var->blue.length);
+      htransp = CNVT_FROMHW(htransp, var->transp.length);
+      if (kspc) {
+         *red = hred;
+         *green = hgreen;
+         *blue = hblue;
+         if (transp)
+            *transp = htransp;
+      } else {
+         put_fs_word(hred, red);
+         put_fs_word(hgreen, green);
+         put_fs_word(hblue, blue);
+         if (transp)
+            put_fs_word(htransp, transp);
+      }
+      red++;
+      green++;
+      blue++;
+      if (transp)
+         transp++;
+   }
+   return(0);
+}
+
+
+static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
+                          int kspc)
+{
+   int i, start;
+   u_short *red, *green, *blue, *transp;
+   u_int hred, hgreen, hblue, htransp;
+
+   red = cmap->red;
+   green = cmap->green;
+   blue = cmap->blue;
+   transp = cmap->transp;
+   start = cmap->start;
+
+   if (start < 0)
+      return(-EINVAL);
+   for (i = 0; i < cmap->len; i++) {
+      if (kspc) {
+         hred = *red;
+         hgreen = *green;
+         hblue = *blue;
+         htransp = transp ? *transp : 0;
+      } else {
+         hred = get_fs_word(red);
+         hgreen = get_fs_word(green);
+         hblue = get_fs_word(blue);
+         htransp = transp ? get_fs_word(transp) : 0;
+      }
+      hred = CNVT_TOHW(hred, var->red.length);
+      hgreen = CNVT_TOHW(hgreen, var->green.length);
+      hblue = CNVT_TOHW(hblue, var->blue.length);
+      htransp = CNVT_TOHW(htransp, var->transp.length);
+      red++;
+      green++;
+      blue++;
+      if (transp)
+         transp++;
+      if (fbhw->setcolreg(start++, hred, hgreen, hblue, htransp))
+         return(0);
+   }
+   return(0);
+}
+
+
+static void do_install_cmap(int con)
+{
+   if (con != currcon)
+      return;
+   if (disp[con].cmap.len)
+      do_fb_set_cmap(&disp[con].cmap, &disp[con].var, 1);
+   else
+      do_fb_set_cmap(get_default_colormap(disp[con].var.bits_per_pixel),
+                                          &disp[con].var, 1);
+}
+
+
+static void memcpy_fs(int fsfromto, void *to, void *from, int len)
+{
+   switch (fsfromto) {
+      case 0:
+         memcpy(to, from, len);
+         return;
+      case 1:
+         memcpy_fromfs(to, from, len);
+         return;
+      case 2:
+         memcpy_tofs(to, from, len);
+         return;
+   }
+}
+
+
+static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
+{
+   int size;
+   int tooff = 0, fromoff = 0;
+
+   if (to->start > from->start)
+      fromoff = to->start-from->start;
+   else
+      tooff = from->start-to->start;
+   size = to->len-tooff;
+   if (size > from->len-fromoff)
+      size = from->len-fromoff;
+   if (size < 0)
+      return;
+   size *= sizeof(u_short);
+   memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size);
+   memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size);
+   memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size);
+   if (from->transp && to->transp)
+      memcpy_fs(fsfromto, to->transp+tooff, from->transp+fromoff, size);
+}
+
+
+static int alloc_cmap(struct fb_cmap *cmap, int len, int transp)
+{
+   int size = len*sizeof(u_short);
+
+   if (cmap->len != len) {
+      if (cmap->red)
+         kfree(cmap->red);
+      if (cmap->green)
+         kfree(cmap->green);
+      if (cmap->blue)
+         kfree(cmap->blue);
+      if (cmap->transp)
+         kfree(cmap->transp);
+      cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
+      cmap->len = 0;
+      if (!len)
+         return(0);
+      if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
+         return(-1);
+      if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
+         return(-1);
+      if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
+         return(-1);
+      if (transp) {
+         if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
+            return(-1);
+      } else
+         cmap->transp = NULL;
+   }
+   cmap->start = 0;
+   cmap->len = len;
+   copy_cmap(get_default_colormap(len), cmap, 0);
+   return(0);
+}
+
+
+   /*
+    *    Get the Fixed Part of the Display
+    */
+
+static int mc68328_fb_get_fix(struct fb_fix_screeninfo *fix, int con)
+{
+   struct mc68328_fb_par par;
+   int error = 0;
+
+   if (con == -1)
+      mc68328_fb_get_par(&par);
+   else
+      error = fbhw->decode_var(&disp[con].var, &par);
+   return(error ? error : fbhw->encode_fix(fix, &par));
+}
+
+
+   /*
+    *    Get the User Defined Part of the Display
+    */
+
+static int mc68328_fb_get_var(struct fb_var_screeninfo *var, int con)
+{
+   struct mc68328_fb_par par;
+   int error = 0;
+
+   if (con == -1) {
+      mc68328_fb_get_par(&par);
+      error = fbhw->encode_var(var, &par);
+   } else
+      *var = disp[con].var;
+   return(error);
+}
+
+
+static void mc68328_fb_set_disp(int con)
+{
+   struct fb_fix_screeninfo fix;
+
+   mc68328_fb_get_fix(&fix, con);
+   if (con == -1)
+      con = 0;
+   disp[con].screen_base = (u_char *)fix.smem_start;
+   disp[con].visual = fix.visual;
+   disp[con].type = fix.type;
+   disp[con].type_aux = fix.type_aux;
+   disp[con].ypanstep = fix.ypanstep;
+   disp[con].ywrapstep = fix.ywrapstep;
+   disp[con].can_soft_blank = 1;
+   disp[con].inverse = mc68328fb_inverse;
+}
+
+
+   /*
+    *    Set the User Defined Part of the Display
+    */
+
+static int mc68328_fb_set_var(struct fb_var_screeninfo *var, int con)
+{
+   int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
+
+   if ((err = do_fb_set_var(var, con == currcon)))
+      return(err);
+   if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+      oldxres = disp[con].var.xres;
+      oldyres = disp[con].var.yres;
+      oldvxres = disp[con].var.xres_virtual;
+      oldvyres = disp[con].var.yres_virtual;
+      oldbpp = disp[con].var.bits_per_pixel;
+      disp[con].var = *var;
+      if (oldxres != var->xres || oldyres != var->yres ||
+          oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
+          oldbpp != var->bits_per_pixel) {
+         mc68328_fb_set_disp(con);
+         (*fb_info.changevar)(con);
+         alloc_cmap(&disp[con].cmap, 0, 0);
+         do_install_cmap(con);
+      }
+   }
+   var->activate = 0;
+   return(0);
+}
+
+
+   /*
+    *    Get the Colormap
+    */
+
+static int mc68328_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con)
+{
+   if (con == currcon) /* current console? */
+      return(do_fb_get_cmap(cmap, &disp[con].var, kspc));
+   else if (disp[con].cmap.len) /* non default colormap? */
+      copy_cmap(&disp[con].cmap, cmap, kspc ? 0 : 2);
+   else
+      copy_cmap(get_default_colormap(disp[con].var.bits_per_pixel), cmap,
+                kspc ? 0 : 2);
+   return(0);
+}
+
+
+   /*
+    *    Set the Colormap
+    */
+
+static int mc68328_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con)
+{
+   int err;
+
+   if (!disp[con].cmap.len) {       /* no colormap allocated? */
+      if ((err = alloc_cmap(&disp[con].cmap, 1<<disp[con].var.bits_per_pixel,
+                            0)))
+         return(err);
+   }
+   if (con == currcon)              /* current console? */
+      return(do_fb_set_cmap(cmap, &disp[con].var, kspc));
+   else
+      copy_cmap(cmap, &disp[con].cmap, kspc ? 0 : 1);
+   return(0);
+}
+
+
+   /*
+    *    Pan or Wrap the Display
+    *
+    *    This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+    */
+
+static int mc68328_fb_pan_display(struct fb_var_screeninfo *var, int con)
+{
+   return(-EINVAL);
+}
+
+
+   /*
+    *    mc68328 Frame Buffer Specific ioctls
+    */
+
+static int mc68328_fb_ioctl(struct inode *inode, struct file *file,
+                          u_int cmd, u_long arg, int con)
+{
+   return(-EINVAL);
+}
+
+
+static struct fb_ops mc68328_fb_ops = {
+   mc68328_fb_get_fix, mc68328_fb_get_var, mc68328_fb_set_var, mc68328_fb_get_cmap,
+   mc68328_fb_set_cmap, mc68328_fb_pan_display, mc68328_fb_ioctl
+};
+
+
+void mc68328_video_setup(char *options, int *ints)
+{
+   char *this_opt;
+   int i;
+
+   fb_info.fontname[0] = '\0';
+
+   if (!options || !*options)
+      return;
+
+   for (this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ","))
+      if (!strcmp(this_opt, "inverse")) {
+         mc68328fb_inverse = 1;
+         for (i = 0; i < 16; i++) {
+            red16[i] = ~red16[i];
+            green16[i] = ~green16[i];
+            blue16[i] = ~blue16[i];
+         }
+      } else if (!strncmp(this_opt, "font:", 5))
+         strcpy(fb_info.fontname, this_opt+5);
+      else
+         mc68328fb_mode = get_video_mode(this_opt);
+}
+
+
+   /*
+    *    Initialization
+    */
+
+struct fb_info *mc68328_fb_init(long *mem_start)
+{
+   int err;
+   struct mc68328_fb_par par;
+
+   memstart = mem_start;
+
+   fbhw = &mc68328_switch;
+
+   err = register_framebuffer(mc68328_fb_name, &node, &mc68328_fb_ops,
+                              NUM_TOTAL_MODES, mc68328_fb_predefined);
+   if (err < 0)
+      panic("Cannot register frame buffer\n");
+
+   fbhw->init();
+   fbhw->decode_var(&mc68328_fb_predefined[mc68328fb_mode], &par);
+   fbhw->encode_var(&mc68328_fb_predefined[0], &par);
+
+   strcpy(fb_info.modename, mc68328_fb_name);
+   fb_info.disp = disp;
+   fb_info.switch_con = &mc68328fb_switch;
+   fb_info.updatevar = &mc68328fb_updatevar;
+   fb_info.blank = &mc68328fb_blank;
+
+   do_fb_set_var(&mc68328_fb_predefined[0], 1);
+   mc68328_fb_get_var(&disp[0].var, -1);
+   mc68328_fb_set_disp(-1);
+   do_install_cmap(0);
+   return(&fb_info);
+}
+
+
+static int mc68328fb_switch(int con)
+{
+   /* Do we have to save the colormap? */
+   if (disp[currcon].cmap.len)
+      do_fb_get_cmap(&disp[currcon].cmap, &disp[currcon].var, 1);
+
+   do_fb_set_var(&disp[con].var, 1);
+   currcon = con;
+   /* Install new colormap */
+   do_install_cmap(con);
+   return(0);
+}
+
+
+   /*
+    *    Update the `var' structure (called by fbcon.c)
+    *
+    *    This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'.
+    *    Since it's called by a kernel driver, no range checking is done.
+    */
+
+static int mc68328fb_updatevar(int con)
+{
+   return(0);
+}
+
+
+   /*
+    *    Blank the display.
+    */
+
+static void mc68328fb_blank(int blank)
+{
+   fbhw->blank(blank);
+}
+
+
+   /*
+    *    Get a Video Mode
+    */
+
+static int get_video_mode(const char *name)
+{
+   int i;
+
+   for (i = 1; i < NUM_PREDEF_MODES; i++)
+      if (!strcmp(name, mc68328_fb_modenames[i]))
+         return(i);
+   return(0);
+}
diff -urN linux-2.4.29/arch/m68knommu/console/fbcon.c linux-2.4.29-uc1/arch/m68knommu/console/fbcon.c
--- linux-2.4.29/arch/m68knommu/console/fbcon.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/console/fbcon.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,3894 @@
+/*
+ * linux/arch/m68knommu/console/fbcon.c -- Low level frame buffer based console
+ *                                    driver
+ *
+ * Modifications to support 4-bit wide monochrome fonts
+ *	-- Kenneth Albanowski <kjahds@kjahds.com>
+ *
+ * Copyright (C) 1998,1999 Kenneth Albanowski <kjahds@kjahds.com>,
+ *                         The Silver Hammer Group, Ltd.
+ * 
+ * Based on:
+ *
+ * linux/arch/m68k/console/fbcon.c -- Low level frame buffer based console
+ *                                    driver
+ *
+ *    Copyright (C) 1995 Geert Uytterhoeven
+ *
+ *
+ * This file is based on the original Amiga console driver (amicon.c):
+ *
+ *    Copyright (C) 1993 Hamish Macdonald
+ *                       Greg Harp
+ *    Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
+ *
+ *          with work by William Rucklidge (wjr@cs.cornell.edu)
+ *                       Geert Uytterhoeven
+ *                       Jes Sorensen (jds@kom.auc.dk)
+ *                       Martin Apel
+ *
+ * and on the original Atari console driver (atacon.c):
+ *
+ *    Copyright (C) 1993 Bjoern Brauel
+ *                       Roman Hodek
+ *
+ *          with work by Guenther Kelleter
+ *                       Martin Schaller
+ *                       Andreas Schwab
+ *
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * To do:
+ *  - Implement 16 plane mode.
+ *  - Add support for 16/24/32 bit packed pixels
+ *  - Hardware cursor
+ */
+
+
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/config.h>
+#include <linux/kd.h>
+#include <linux/malloc.h>
+
+#include <asm/irq.h>
+#ifdef CONFIG_AMIGA
+#include <asm/amigahw.h>
+#include <asm/amigaints.h>
+#endif /* CONFIG_AMIGA */
+#ifdef CONFIG_ATARI
+#include <asm/atariints.h>
+#endif
+#ifdef CONFIG_FB_CYBER
+#include "../amiga/s3blit.h"
+#endif /* CONFIG_FB_CYBER */
+#include <linux/fb.h>
+#include <asm/font.h>
+#include <asm/machdep.h>
+
+#include <asm/system.h>
+
+#include "../../../drivers/char/vt_kern.h"   /* vt_cons and vc_resize_con() */
+
+extern struct fb_info *mc68328_fb_init(long *mem_start);
+
+
+/* Import console_blanked from console.c */
+
+extern int console_blanked;
+
+
+   /*
+    *    The following symbols select what modes are supported. They should
+    *    be settable by the user ("make config") later.
+    */
+
+/* Clear all definitions */
+
+#undef CONFIG_FBCON_MONO
+#undef CONFIG_FBCON_ILBM
+#undef CONFIG_FBCON_PLANES
+#undef CONFIG_FBCON_2PLANE
+#undef CONFIG_FBCON_4PLANE
+#undef CONFIG_FBCON_8PLANE
+#undef CONFIG_FBCON_8PACKED
+#undef CONFIG_FBCON_16PACKED
+#undef CONFIG_FBCON_24PACKED
+#undef CONFIG_FBCON_32PACKED
+#undef CONFIG_FBCON_CYBER
+
+
+/* Monochrome is default */
+
+#define CONFIG_FBCON_MONO
+
+/* Amiga support */
+
+#ifdef CONFIG_AMIGA
+#ifndef CONFIG_FBCON_ILBM
+#define CONFIG_FBCON_ILBM
+#endif
+#ifndef CONFIG_FBCON_PLANES
+#define CONFIG_FBCON_PLANES
+#endif
+
+/* Cybervision Graphics Board */
+
+#ifdef CONFIG_FB_CYBER
+#ifndef CONFIG_FBCON_CYBER
+#define CONFIG_FBCON_CYBER
+#endif
+#endif /* CONFIG_FB_CYBER */
+
+#endif /* CONFIG_AMIGA */
+
+/* Atari support */
+
+#ifdef CONFIG_ATARI
+#ifndef CONFIG_FBCON_2PLANE
+#define CONFIG_FBCON_2PLANE
+#endif
+#ifndef CONFIG_FBCON_4PLANE
+#define CONFIG_FBCON_4PLANE
+#endif
+#ifndef CONFIG_FBCON_8PLANE
+#define CONFIG_FBCON_8PLANE
+#endif
+#ifndef CONFIG_FBCON_8PACKED
+#define CONFIG_FBCON_8PACKED
+#endif
+#ifndef CONFIG_FBCON_16PACKED
+#define CONFIG_FBCON_16PACKED
+#endif
+#endif /* CONFIG_ATARI */
+
+
+/* Extra definitions to make the code more readable */
+
+#if defined(CONFIG_FBCON_2PLANE) || defined(CONFIG_FBCON_4PLANE) || \
+    defined(CONFIG_FBCON_8PLANE)
+#define CONFIG_FBCON_IPLAN2
+#else
+#undef CONFIG_FBCON_IPLAN2
+#endif
+
+#if defined(CONFIG_FBCON_CYBER) || defined(CONFIG_FBCON_8PACKED) || \
+    defined(CONFIG_FBCON_16PACKED) || defined(CONFIG_FBCON_24PACKED) || \
+    defined(CONFIG_FBCON_32PACKED)
+#define CONFIG_FBCON_PACKED
+#else
+#undef CONFIG_FBCON_PACKED
+#endif
+
+
+struct fb_info *fb_info;
+struct display *disp;
+
+
+/* ++Geert: Sorry, no hardware cursor support at the moment;
+   use Atari alike software cursor */
+
+static int cursor_drawn = 0;
+
+#define CURSOR_DRAW_DELAY           (2)
+
+/* # VBL ints between cursor state changes */
+#define AMIGA_CURSOR_BLINK_RATE   (20)
+#define ATARI_CURSOR_BLINK_RATE   (42)
+
+static int vbl_cursor_cnt = 0;
+static int cursor_on = 0;
+static int cursor_blink_rate;
+
+static __inline__ int CURSOR_UNDRAWN(void)
+{
+   int cursor_was_drawn;
+   vbl_cursor_cnt = 0;
+   cursor_was_drawn = cursor_drawn;
+   cursor_drawn = 0;
+   return(cursor_was_drawn);
+}
+
+   /*
+    *    Attribute Decoding
+    */
+
+/* Color */
+#define attr_fgcol(p,conp)    \
+	(((conp)->vc_attr >> ((p)->inverse ? 4 : 0)) & 0x0f)
+#define attr_bgcol(p,conp)    \
+	(((conp)->vc_attr >> ((p)->inverse ? 0 : 4)) & 0x0f)
+#define	attr_bgcol_ec(p,conp) \
+	(((conp)->vc_video_erase_char >> ((p)->inverse ? 8 : 12)) & 0x0f)
+
+/* Monochrome */
+#define attr_bold(p,conp)     \
+	(((conp)->vc_attr & 3) == 2)
+#define attr_reverse(p,conp)  \
+	(((conp)->vc_attr & 8) ^ ((p)->inverse ? 8 : 0))
+#define attr_underline(p,conp) \
+	(((conp)->vc_attr) & 4)
+
+
+   /*
+    *    Scroll Method
+    */
+
+#define SCROLL_YWRAP          (0)
+#define SCROLL_YPAN           (1)
+#define SCROLL_YMOVE          (2)
+
+#define divides(a, b)         ((!(a) || (b)%(a)) ? 0 : 1)
+
+
+   /*
+    *    Interface used by the world
+    */
+
+static u_long fbcon_startup(u_long kmem_start, char **display_desc);
+static void fbcon_init(struct vc_data *conp);
+static int fbcon_deinit(struct vc_data *conp);
+static int fbcon_changevar(int con);
+static int fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
+                       int width);
+static int fbcon_putc(struct vc_data *conp, int c, int y, int x);
+static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int y,
+                       int x);
+static int fbcon_cursor(struct vc_data *conp, int mode);
+static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir, int count);
+static int fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+                       int height, int width);
+static int fbcon_switch(struct vc_data *conp);
+static int fbcon_blank(int blank);
+
+
+   /*
+    *    Internal routines
+    */
+
+static void fbcon_setup(int con, int setcol, int cls);
+static __inline__ void *mymemclear_small(void *s, size_t count);
+static __inline__ void *mymemclear(void *s, size_t count);
+static __inline__ void *mymemset(void *s, size_t count);
+static __inline__ void *mymemmove(void *d, void *s, size_t count);
+static __inline__ void fast_memmove(char *dst, char *src, size_t size);
+static __inline__ void memclear_4p_col(void *d, size_t h, u_long val, int bpr);
+static __inline__ void memset_even_4p(void *d, size_t count, u_long val1,
+                                      u_long val2);
+static __inline__ void memmove_4p_col(void *d, void *s, int h, int bpr);
+static __inline__ u_long expand4l(u_char c);
+static __inline__ void expand4dl(u_char c, u_long *ret1, u_long *ret2);
+static __inline__ u_long dup4l(u_char c);
+static __inline__ void memclear_8p_col(void *d, size_t h, u_long val1,
+                                       u_long val2, int bpr);
+static __inline__ void memset_even_8p(void *d, size_t count, u_long val1,
+                                      u_long val2, u_long val3, u_long val4);
+static __inline__ void memmove_8p_col(void *d, void *s, int h, int bpr);
+static __inline__ void expand8dl(u_char c, u_long *ret1, u_long *ret2);
+static __inline__ void memclear_2p_col(void *d, size_t h, u_short val, int bpr);
+static __inline__ void memset_even_2p(void *d, size_t count, u_long val);
+static __inline__ void memmove_2p_col(void *d, void *s, int h, int bpr);
+static __inline__ u_short expand2w(u_char c);
+static __inline__ u_long expand2l(u_char c);
+static __inline__ u_short dup2w(u_char c);
+static __inline__ int real_y(struct display *p, int y);
+static void fbcon_vbl_handler(int irq, struct pt_regs *fp, void *dummy);
+static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy, int dx,
+                            int height, int width, u_int y_break);
+
+
+   /*
+    *    Monochrome
+    */
+
+#ifdef CONFIG_FBCON_MONO
+static void bmove_mono(struct display *p, int sy, int sx, int dy, int dx,
+                       int height, int width);
+static void clear_mono(struct vc_data *conp, struct display *p, int sy, int sx,
+                       int height, int width);
+static void putc_mono(struct vc_data *conp, struct display *p, int c, int y,
+                      int x);
+static void putcs_mono(struct vc_data *conp, struct display *p, const char *s,
+                       int count, int y, int x);
+static void rev_char_mono(struct display *p, int x, int y);
+#endif /* CONFIG_FBCON_MONO */
+
+
+   /*
+    *    Color Interleaved Planes
+    */
+
+#ifdef CONFIG_FBCON_ILBM
+static void bmove_ilbm(struct display *p, int sy, int sx, int dy, int dx,
+                       int height, int width);
+static void clear_ilbm(struct vc_data *conp, struct display *p, int sy, int sx,
+                       int height, int width);
+static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int y,
+                      int x);
+static void putcs_ilbm(struct vc_data *conp, struct display *p, const char *s,
+                       int count, int y, int x);
+static void rev_char_ilbm(struct display *p, int x, int y);
+#endif /* CONFIG_FBCON_ILBM */
+
+
+   /*
+    *    Color Planes
+    */
+
+#ifdef CONFIG_FBCON_PLANES
+static void bmove_plan(struct display *p, int sy, int sx, int dy, int dx,
+                       int height, int width);
+static void clear_plan(struct vc_data *conp, struct display *p, int sy, int sx,
+                       int height, int width);
+static void putc_plan(struct vc_data *conp, struct display *p, int c, int y,
+                      int x);
+static void putcs_plan(struct vc_data *conp, struct display *p, const char *s,
+                       int count, int y, int x);
+static void rev_char_plan(struct display *p, int x, int y);
+#endif /* CONFIG_FBCON_PLANES */
+
+
+   /*
+    *    2 Planes (2-bytes interleave)
+    */
+
+#ifdef CONFIG_FBCON_2PLANE
+static void bmove_2_plane(struct display *p, int sy, int sx, int dy, int dx,
+                          int height, int width);
+static void clear_2_plane(struct vc_data *conp, struct display *p, int sy,
+                          int sx, int height, int width);
+static void putc_2_plane(struct vc_data *conp, struct display *p, int c, int y,
+                         int x);
+static void putcs_2_plane(struct vc_data *conp, struct display *p,
+                          const char *s, int count, int y, int x);
+static void rev_char_2_plane(struct display *display, int x, int y);
+#endif /* CONFIG_FBCON_2PLANE */
+
+
+   /*
+    *    4 Planes (2-bytes interleave)
+    */
+
+#ifdef CONFIG_FBCON_4PLANE
+static void bmove_4_plane(struct display *p, int sy, int sx, int dy, int dx,
+                          int height, int width);
+static void clear_4_plane(struct vc_data *conp, struct display *p, int sy,
+                          int sx, int height, int width);
+static void putc_4_plane(struct vc_data *conp, struct display *p, int c, int y,
+                         int x);
+static void putcs_4_plane(struct vc_data *conp, struct display *p,
+                          const char *s, int count, int y, int x);
+static void rev_char_4_plane(struct display *p, int x, int y);
+#endif /* CONFIG_FBCON_4PLANE */
+
+
+   /*
+    *    8 Planes (2-bytes interleave)
+    */
+
+#ifdef CONFIG_FBCON_8PLANE
+static void bmove_8_plane(struct display *p, int sy, int sx, int dy, int dx,
+                          int height, int width);
+static void clear_8_plane(struct vc_data *conp, struct display *p, int sy,
+                          int sx, int height, int width);
+static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int y,
+                         int x);
+static void putcs_8_plane(struct vc_data *conp, struct display *p,
+                          const char *s, int count, int y, int x);
+static void rev_char_8_plane(struct display *display, int x, int y);
+#endif /* CONFIG_FBCON_8PLANE */
+
+
+   /*
+    *    8 bpp Packed Pixels
+    */
+
+#ifdef CONFIG_FBCON_8PACKED
+static void bmove_8_packed(struct display *p, int sy, int sx, int dy, int dx,
+                           int height, int width);
+static void clear_8_packed(struct vc_data *conp, struct display *p, int sy,
+                           int sx, int height, int width);
+static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int y,
+                          int x);
+static void putcs_8_packed(struct vc_data *conp, struct display *p,
+                           const char *s, int count, int y, int x);
+static void rev_char_8_packed(struct display *p, int x, int y);
+#endif /* CONFIG_FBCON_8PACKED */
+
+
+   /*
+    *    16 bpp Packed Pixels
+    */
+
+#ifdef CONFIG_FBCON_16PACKED
+static void bmove_16_packed(struct display *p, int sy, int sx, int dy, int dx,
+                            int height, int width);
+static void clear_16_packed(struct vc_data *conp, struct display *p, int sy,
+                            int sx, int height, int width);
+static void putc_16_packed(struct vc_data *conp, struct display *p, int c,
+                           int y, int x);
+static void putcs_16_packed(struct vc_data *conp, struct display *p,
+                            const char *s, int count, int y, int x);
+static void rev_char_16_packed(struct display *p, int x, int y);
+#endif */ CONFIG_FBCON_8PACKED */
+
+
+   /*
+    *    Cybervision (accelerated)
+    */
+
+#ifdef CONFIG_FBCON_CYBER
+static void bmove_cyber(struct display *p, int sy, int sx, int dy, int dx,
+                        int height, int width);
+static void clear_cyber(struct vc_data *conp, struct display *p, int sy, int sx,
+                        int height, int width);
+static void putc_cyber(struct vc_data *conp, struct display *p, int c, int y,
+                       int x);
+static void putcs_cyber(struct vc_data *conp, struct display *p, const char *s,
+                        int count, int y, int x);
+static void rev_char_cyber(struct display *p, int x, int y);
+
+extern void Cyber_WaitQueue(u_short fifo);
+extern void Cyber_WaitBlit(void);
+extern void Cyber_BitBLT(u_short curx, u_short cury, u_short destx,
+                         u_short desty, u_short width, u_short height,
+                         u_short mode);
+extern void Cyber_RectFill(u_short x, u_short y, u_short width, u_short height,
+                           u_short mode, u_short color);
+extern void Cyber_MoveCursor(u_short x, u_short y);
+#endif /* CONFIG_FBCON_CYBER */
+
+
+   /*
+    *    `switch' for the Low Level Operations
+    */
+
+struct display_switch {
+    void (*bmove)(struct display *p, int sy, int sx, int dy, int dx, int height,
+                  int width);
+    void (*clear)(struct vc_data *conp, struct display *p, int sy, int sx,
+                  int height, int width);
+    void (*putc)(struct vc_data *conp, struct display *p, int c, int y, int x);
+    void (*putcs)(struct vc_data *conp, struct display *p, const char *s,
+                  int count, int y, int x);
+    void (*rev_char)(struct display *p, int x, int y);
+};
+
+
+#ifdef CONFIG_FBCON_MONO
+struct display_switch dispsw_mono = {
+   bmove_mono, clear_mono, putc_mono, putcs_mono, rev_char_mono
+};
+#endif /* CONFIG_FBCON_MONO */
+
+#ifdef CONFIG_FBCON_ILBM
+struct display_switch dispsw_ilbm = {
+   bmove_ilbm, clear_ilbm, putc_ilbm, putcs_ilbm, rev_char_ilbm
+};
+#endif /* CONFIG_FBCON_ILBM */
+
+#ifdef CONFIG_FBCON_PLANES
+struct display_switch dispsw_plan = {
+   bmove_plan, clear_plan, putc_plan, putcs_plan, rev_char_plan
+};
+#endif /* CONFIG_FBCON_PLANES */
+
+#ifdef CONFIG_FBCON_2PLANE
+struct display_switch dispsw_2_plane = {
+   bmove_2_plane, clear_2_plane, putc_2_plane, putcs_2_plane, rev_char_2_plane
+};
+#endif /* CONFIG_FBCON_2PLANE */
+
+#ifdef CONFIG_FBCON_4PLANE
+struct display_switch dispsw_4_plane = {
+   bmove_4_plane, clear_4_plane, putc_4_plane, putcs_4_plane, rev_char_4_plane
+};
+#endif /* CONFIG_FBCON_4PLANE */
+
+#ifdef CONFIG_FBCON_8PLANE
+struct display_switch dispsw_8_plane = {
+   bmove_8_plane, clear_8_plane, putc_8_plane, putcs_8_plane, rev_char_8_plane
+};
+#endif /* CONFIG_FBCON_8PLANE */
+
+#ifdef CONFIG_FBCON_8PACKED
+struct display_switch dispsw_8_packed = {
+   bmove_8_packed, clear_8_packed, putc_8_packed, putcs_8_packed, rev_char_8_packed
+};
+#endif /* CONFIG_FBCON_8PACKED */
+
+#ifdef CONFIG_FBCON_16PACKED
+struct display_switch dispsw_16_packed = {
+   bmove_16_packed, clear_16_packed, putc_16_packed, putcs_16_packed,
+   rev_char_16_packed
+};
+#endif /* CONFIG_FBCON_16PACKED */
+
+#ifdef CONFIG_FBCON_CYBER
+struct display_switch dispsw_cyber = {
+   bmove_cyber, clear_cyber, putc_cyber, putcs_cyber, rev_char_cyber
+};
+#endif /* CONFIG_FBCON_CYBER */
+
+
+static u_long fbcon_startup(u_long kmem_start, char **display_desc)
+{
+   int irqres = 0;
+
+   fb_info = mc68328_fb_init(&kmem_start);
+   disp = fb_info->disp;
+   *display_desc = fb_info->modename;
+   fb_info->changevar = &fbcon_changevar;
+
+#ifdef CONFIG_AMIGA
+   if (MACH_IS_AMIGA) {
+      cursor_blink_rate = AMIGA_CURSOR_BLINK_RATE;
+      irqres = add_isr(IRQ_AMIGA_VERTB, fbcon_vbl_handler, 0, NULL,
+                       "console/cursor");
+   }
+#endif /* CONFIG_AMIGA */
+#ifdef CONFIG_ATARI
+   if (MACH_IS_ATARI) {
+      cursor_blink_rate = ATARI_CURSOR_BLINK_RATE;
+      irqres = add_isr(IRQ_AUTO_4, fbcon_vbl_handler, IRQ_TYPE_PRIO, NULL,
+		       "console/cursor");
+   }
+#endif /* CONFIG_ATARI */
+
+#if defined(CONFIG_AMIGA) || defined(CONFIG_ATARI)
+   if (!irqres)
+      panic("fbcon_startup: Couldn't add vblank interrupt");
+#endif
+
+   return(kmem_start);
+}
+
+
+static void fbcon_init(struct vc_data *conp)
+{
+   int unit = conp->vc_num;
+
+   if (unit)
+      disp[unit] = disp[0];
+   disp[unit].conp = conp;
+   fbcon_setup(unit, 1, 0);
+}
+
+
+static int fbcon_deinit(struct vc_data *conp)
+{
+   disp[conp->vc_num].conp = 0;
+   return(0);
+}
+
+
+static int fbcon_changevar(int con)
+{
+   fbcon_setup(con, 1, 1);
+   return(0);
+}
+
+
+static void fbcon_setup(int con, int setcol, int cls)
+{
+   struct display *p = &disp[con];
+   struct vc_data *conp = p->conp;
+
+   p->var.xoffset = p->var.yoffset = p->yscroll = 0;  /* reset wrap/pan */
+
+   if (!fb_info->fontname[0] ||
+       !findsoftfont(fb_info->fontname, &p->fontwidth, &p->fontheight,
+                     &p->fontdata))
+	   getdefaultfont(p->var.xres, p->var.yres, NULL, &p->fontwidth,
+	                  &p->fontheight, &p->fontdata);
+
+   if (divides(p->ywrapstep, p->fontheight) && divides(p->fontheight, p->var.yres_virtual))
+      p->scrollmode = SCROLL_YWRAP;
+   else if (divides(p->ypanstep, p->fontheight) &&
+            p->var.yres_virtual >= p->var.yres+p->fontheight)
+      p->scrollmode = SCROLL_YPAN;
+   else
+      p->scrollmode = SCROLL_YMOVE;
+
+   conp->vc_cols = p->var.xres/p->fontwidth;
+   conp->vc_rows = p->var.yres/p->fontheight;
+   p->vrows = p->var.yres_virtual/p->fontheight;
+   conp->vc_can_do_color = p->var.bits_per_pixel != 1;
+
+#ifdef CONFIG_FBCON_MONO
+   if (p->var.bits_per_pixel == 1) {
+      if (p->line_length)
+         p->next_line = p->line_length;
+      else
+         p->next_line = p->var.xres_virtual/8;
+      p->next_plane = 0;
+      p->dispsw = &dispsw_mono;
+   } else
+#endif /* CONFIG_FBCON_MONO */
+#ifdef CONFIG_FBCON_IPLAN2
+   if (p->type == FB_TYPE_INTERLEAVED_PLANES && p->type_aux == 2) {
+      p->next_line = p->var.xres_virtual*p->var.bits_per_pixel>>3;
+      p->next_plane = 0;
+#ifdef CONFIG_FBCON_2PLANE
+      if (p->var.bits_per_pixel == 2)
+         p->dispsw = &dispsw_2_plane;
+      else
+#endif /* CONFIG_FBCON_2PLANE */
+#ifdef CONFIG_FBCON_4PLANE
+      if (p->var.bits_per_pixel == 4)
+         p->dispsw = &dispsw_4_plane;
+      else
+#endif /* CONFIG_FBCON_4PLANE */
+#ifdef CONFIG_FBCON_8PLANE
+      if (p->var.bits_per_pixel == 8)
+         p->dispsw = &dispsw_8_plane;
+      else
+#endif /* CONFIG_FBCON_8PLANE */
+      goto fail;
+   } else
+#endif /* CONFIG_FBCON_IPLAN2 */
+#ifdef CONFIG_FBCON_ILBM
+   if (p->type == FB_TYPE_INTERLEAVED_PLANES && p->type_aux != 2) {
+      if (p->line_length) {
+         p->next_line = p->line_length*p->var.bits_per_pixel;
+         p->next_plane = p->line_length;
+      } else {
+         p->next_line = p->type_aux;
+         p->next_plane = p->type_aux/p->var.bits_per_pixel;
+      }
+      p->dispsw = &dispsw_ilbm;
+   } else
+#endif /* CONFIG_FBCON_ILBM */
+#ifdef CONFIG_FBCON_PLANES
+   if (p->type == FB_TYPE_PLANES) {
+      if (p->line_length)
+         p->next_line = p->line_length;
+      else
+         p->next_line = p->var.xres_virtual>>3;
+      p->next_plane = p->var.yres_virtual*p->next_line;
+      p->dispsw = &dispsw_plan;
+   } else
+#endif /* CONFIG_FBCON_PLANES */
+#ifdef CONFIG_FBCON_PACKED
+   if (p->type == FB_TYPE_PACKED_PIXELS) {
+      p->next_line = p->var.xres_virtual*p->var.bits_per_pixel>>3;
+      p->next_plane = 0;
+#ifdef CONFIG_FBCON_CYBER
+      if (p->var.accel == FB_ACCEL_CYBERVISION)
+         p->dispsw = &dispsw_cyber;
+      else
+#endif /* CONFIG_FBCON_CYBER */
+#ifdef CONFIG_FBCON_8PACKED
+      if (p->var.bits_per_pixel == 8)
+         p->dispsw = &dispsw_8_packed;
+      else
+#endif /* CONFIG_FBCON_8PACKED */
+#ifdef CONFIG_FBCON_16PACKED
+      if (p->var.bits_per_pixel == 16)
+         p->dispsw = &dispsw_16_packed;
+      else
+#endif /* CONFIG_FBCON_16PACKED */
+#ifdef CONFIG_FBCON_24PACKED
+      if (p->var.bits_per_pixel == 24)
+         p->dispsw = &dispsw_24_packed;
+      else
+#endif /* CONFIG_FBCON_24PACKED */
+#ifdef CONFIG_FBCON_32PACKED
+      if (p->var.bits_per_pixel == 32)
+         p->dispsw = &dispsw_32_packed;
+      else
+#endif /* CONFIG_FBCON_32PACKED */
+      goto fail;
+   } else
+#endif /* CONFIG_FBCON_PACKED */
+   {
+fail:
+#ifdef CONFIG_FBCON_MONO
+      printk("fbcon_setup: type %d (aux %d) not supported, trying mono\n",
+             p->type, p->type_aux);
+      if (p->line_length)
+         p->next_line = p->line_length;
+      else
+         p->next_line = p->var.xres_virtual/8;
+      p->next_plane = 0;
+      p->var.bits_per_pixel = 1;
+      p->dispsw = &dispsw_mono;
+#else /* CONFIG_FBCON_MONO */
+      panic("fbcon_setup: no default driver");
+#endif /* CONFIG_FBCON_MONO */
+   }
+
+   if ((p->dispsw != &dispsw_mono) && (p->fontwidth != 8))
+      panic("fbcon_setup: No support for fontwidth != 8 on non-monochrome targets");
+
+   if ((p->dispsw == &dispsw_mono) && (p->fontwidth != 8) && (p->fontwidth != 4) )
+      panic("fbcon_setup: No support for fontwidth != 8/4 on monochrome targets");
+
+   if (setcol) {
+      p->fgcol = p->var.bits_per_pixel > 2 ? 7 : (1<<p->var.bits_per_pixel)-1;
+      p->bgcol = 0;
+   }
+
+   if (cls)
+      vc_resize_con(conp->vc_rows, conp->vc_cols, con);
+}
+
+
+/* ================================================================= */
+/*                      Utility Assembler Functions                  */
+/* ================================================================= */
+
+
+/* ====================================================================== */
+
+/* Those of a delicate disposition might like to skip the next couple of
+ * pages.
+ *
+ * These functions are drop in replacements for memmove and
+ * memset(_, 0, _). However their five instances add at least a kilobyte
+ * to the object file. You have been warned.
+ *
+ * Not a great fan of assembler for the sake of it, but I think
+ * that these routines are at least 10 times faster than their C
+ * equivalents for large blits, and that's important to the lowest level of
+ * a graphics driver. Question is whether some scheme with the blitter
+ * would be faster. I suspect not for simple text system - not much
+ * asynchrony.
+ *
+ * Code is very simple, just gruesome expansion. Basic strategy is to
+ * increase data moved/cleared at each step to 16 bytes to reduce
+ * instruction per data move overhead. movem might be faster still
+ * For more than 15 bytes, we try to align the write direction on a
+ * longword boundary to get maximum speed. This is even more gruesome.
+ * Unaligned read/write used requires 68020+ - think this is a problem?
+ *
+ * Sorry!
+ */
+
+
+/* ++roman: I've optimized Robert's original versions in some minor
+ * aspects, e.g. moveq instead of movel, let gcc choose the registers,
+ * use movem in some places...
+ * For other modes than 1 plane, lots of more such assembler functions
+ * were needed (e.g. the ones using movep or expanding color values).
+ */
+
+/* ++andreas: more optimizations:
+   subl #65536,d0 replaced by clrw d0; subql #1,d0 for dbcc
+   addal is faster than addaw
+   movep is rather expensive compared to ordinary move's
+   some functions rewritten in C for clarity, no speed loss */
+
+static __inline__ void *mymemclear_small(void *s, size_t count)
+{
+   if (!count)
+      return(0);
+
+   __asm__ __volatile__(
+         "lsrl   #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t"
+      "1: lsrl   #1,%1 ; jcc 1f ; movew %2,%0@-\n\t"
+      "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@-\n\t"
+      "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t"
+      "1: subql  #1,%1 ; jcs 3f\n\t"
+      "2: moveml %2/%3/%4/%5,%0@-\n\t"
+         "dbra %1,2b\n\t"
+      "3:"
+         : "=a" (s), "=d" (count)
+         :  "d" (0), "d" (0), "d" (0), "d" (0),
+            "0" ((char *)s+count), "1" (count)
+  );
+
+   return(0);
+}
+
+
+static __inline__ void *mymemclear(void *s, size_t count)
+{
+   if (!count)
+      return(0);
+
+   if (count < 16) {
+      __asm__ __volatile__(
+            "lsrl   #1,%1 ; jcc 1f ; clrb %0@+\n\t"
+         "1: lsrl   #1,%1 ; jcc 1f ; clrw %0@+\n\t"
+         "1: lsrl   #1,%1 ; jcc 1f ; clrl %0@+\n\t"
+         "1: lsrl   #1,%1 ; jcc 1f ; clrl %0@+ ; clrl %0@+\n\t"
+         "1:"
+            : "=a" (s), "=d" (count)
+            : "0" (s), "1" (count)
+     );
+   } else {
+      long tmp;
+      __asm__ __volatile__(
+            "movel %1,%2\n\t"
+            "lsrl   #1,%2 ; jcc 1f ; clrb %0@+ ; subqw #1,%1\n\t"
+            "lsrl   #1,%2 ; jcs 2f\n\t"  /* %0 increased=>bit 2 switched*/
+            "clrw   %0@+  ; subqw  #2,%1 ; jra 2f\n\t"
+         "1: lsrl   #1,%2 ; jcc 2f\n\t"
+            "clrw   %0@+  ; subqw  #2,%1\n\t"
+         "2: movew %1,%2; lsrl #2,%1 ; jeq 6f\n\t"
+            "lsrl   #1,%1 ; jcc 3f ; clrl %0@+\n\t"
+         "3: lsrl   #1,%1 ; jcc 4f ; clrl %0@+ ; clrl %0@+\n\t"
+         "4: subql  #1,%1 ; jcs 6f\n\t"
+         "5: clrl %0@+; clrl %0@+ ; clrl %0@+ ; clrl %0@+\n\t"
+            "dbra %1,5b   ; clrw %1; subql #1,%1; jcc 5b\n\t"
+         "6: movew %2,%1; btst #1,%1 ; jeq 7f ; clrw %0@+\n\t"
+         "7:            ; btst #0,%1 ; jeq 8f ; clrb %0@+\n\t"
+         "8:"
+            : "=a" (s), "=d" (count), "=d" (tmp)
+            : "0" (s), "1" (count)
+     );
+   }
+
+   return(0);
+}
+
+
+static __inline__ void *mymemset(void *s, size_t count)
+{
+   if (!count)
+      return(0);
+
+   __asm__ __volatile__(
+         "lsrl   #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t"
+      "1: lsrl   #1,%1 ; jcc 1f ; movew %2,%0@-\n\t"
+      "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@-\n\t"
+      "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t"
+      "1: subql  #1,%1 ; jcs 3f\n\t"
+      "2: moveml %2/%3/%4/%5,%0@-\n\t"
+         "dbra %1,2b\n\t"
+      "3:"
+         : "=a" (s), "=d" (count)
+         :  "d" (-1), "d" (-1), "d" (-1), "d" (-1),
+            "0" ((char *) s + count), "1" (count)
+  );
+
+   return(0);
+}
+
+
+static __inline__ void *mymemmove(void *d, void *s, size_t count)
+{
+   if (d < s) {
+      if (count < 16) {
+         __asm__ __volatile__(
+               "lsrl   #1,%2 ; jcc 1f ; moveb %1@+,%0@+\n\t"
+            "1: lsrl   #1,%2 ; jcc 1f ; movew %1@+,%0@+\n\t"
+            "1: lsrl   #1,%2 ; jcc 1f ; movel %1@+,%0@+\n\t"
+            "1: lsrl   #1,%2 ; jcc 1f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t"
+            "1:"
+               : "=a" (d), "=a" (s), "=d" (count)
+               : "0" (d), "1" (s), "2" (count)
+        );
+      } else {
+         long tmp;
+         __asm__ __volatile__(
+               "movel  %0,%3\n\t"
+               "lsrl   #1,%3 ; jcc 1f ; moveb %1@+,%0@+ ; subqw #1,%2\n\t"
+               "lsrl   #1,%3 ; jcs 2f\n\t"  /* %0 increased=>bit 2 switched*/
+               "movew  %1@+,%0@+  ; subqw  #2,%2 ; jra 2f\n\t"
+            "1: lsrl   #1,%3 ; jcc 2f\n\t"
+               "movew  %1@+,%0@+  ; subqw  #2,%2\n\t"
+            "2: movew  %2,%-; lsrl #2,%2 ; jeq 6f\n\t"
+               "lsrl   #1,%2 ; jcc 3f ; movel %1@+,%0@+\n\t"
+            "3: lsrl   #1,%2 ; jcc 4f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t"
+            "4: subql  #1,%2 ; jcs 6f\n\t"
+            "5: movel  %1@+,%0@+;movel %1@+,%0@+\n\t"
+               "movel  %1@+,%0@+;movel %1@+,%0@+\n\t"
+               "dbra   %2,5b ; clrw %2; subql #1,%2; jcc 5b\n\t"
+            "6: movew  %+,%2; btst #1,%2 ; jeq 7f ; movew %1@+,%0@+\n\t"
+            "7:              ; btst #0,%2 ; jeq 8f ; moveb %1@+,%0@+\n\t"
+            "8:"
+               : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
+               : "0" (d), "1" (s), "2" (count)
+        );
+      }
+   } else {
+      if (count < 16) {
+         __asm__ __volatile__(
+               "lsrl   #1,%2 ; jcc 1f ; moveb %1@-,%0@-\n\t"
+            "1: lsrl   #1,%2 ; jcc 1f ; movew %1@-,%0@-\n\t"
+            "1: lsrl   #1,%2 ; jcc 1f ; movel %1@-,%0@-\n\t"
+            "1: lsrl   #1,%2 ; jcc 1f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t"
+            "1:"
+               : "=a" (d), "=a" (s), "=d" (count)
+               : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
+        );
+      } else {
+         long tmp;
+         __asm__ __volatile__(
+               "movel %0,%3\n\t"
+               "lsrl   #1,%3 ; jcc 1f ; moveb %1@-,%0@- ; subqw #1,%2\n\t"
+               "lsrl   #1,%3 ; jcs 2f\n\t"  /* %0 increased=>bit 2 switched*/
+               "movew  %1@-,%0@-  ; subqw  #2,%2 ; jra 2f\n\t"
+            "1: lsrl   #1,%3 ; jcc 2f\n\t"
+               "movew  %1@-,%0@-  ; subqw  #2,%2\n\t"
+            "2: movew %2,%-; lsrl #2,%2 ; jeq 6f\n\t"
+               "lsrl   #1,%2 ; jcc 3f ; movel %1@-,%0@-\n\t"
+            "3: lsrl   #1,%2 ; jcc 4f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t"
+            "4: subql  #1,%2 ; jcs 6f\n\t"
+            "5: movel %1@-,%0@-;movel %1@-,%0@-\n\t"
+               "movel %1@-,%0@-;movel %1@-,%0@-\n\t"
+               "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5b\n\t"
+            "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@-,%0@-\n\t"
+            "7:              ; btst #0,%2 ; jeq 8f ; moveb %1@-,%0@-\n\t"
+            "8:"
+               : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
+               : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
+        );
+      }
+   }
+
+   return(0);
+}
+
+
+/* ++andreas: Simple and fast version of memmove, assumes size is
+   divisible by 16, suitable for moving the whole screen bitplane */
+static __inline__ void fast_memmove(char *dst, char *src, size_t size)
+{
+  if (!size)
+    return;
+  if (dst < src)
+    __asm__ __volatile__
+      ("1:"
+       "  moveml %0@+,%/d0/%/d1/%/a0/%/a1\n"
+       "  moveml %/d0/%/d1/%/a0/%/a1,%1@\n"
+       "  addql #8,%1; addql #8,%1\n"
+       "  dbra %2,1b\n"
+       "  clrw %2; subql #1,%2\n"
+       "  jcc 1b"
+       : "=a" (src), "=a" (dst), "=d" (size)
+       : "0" (src), "1" (dst), "2" (size / 16 - 1)
+       : "d0", "d1", "a0", "a1", "memory");
+  else
+    __asm__ __volatile__
+      ("1:"
+       "  subql #8,%0; subql #8,%0\n"
+       "  moveml %0@,%/d0/%/d1/%/a0/%/a1\n"
+       "  moveml %/d0/%/d1/%/a0/%/a1,%1@-\n"
+       "  dbra %2,1b\n"
+       "  clrw %2; subql #1,%2\n"
+       "  jcc 1b"
+       : "=a" (src), "=a" (dst), "=d" (size)
+       : "0" (src + size), "1" (dst + size), "2" (size / 16 - 1)
+       : "d0", "d1", "a0", "a1", "memory");
+}
+
+
+/* Sets the bytes in the visible column at d, height h, to the value
+ * val for a 4 plane screen. The the bis of the color in 'color' are
+ * moved (8 times) to the respective bytes. This means:
+ *
+ * for(h times; d += bpr)
+ *   *d     = (color & 1) ? 0xff : 0;
+ *   *(d+2) = (color & 2) ? 0xff : 0;
+ *   *(d+4) = (color & 4) ? 0xff : 0;
+ *   *(d+6) = (color & 8) ? 0xff : 0;
+ */
+
+static __inline__ void memclear_4p_col(void *d, size_t h, u_long val, int bpr)
+{
+	__asm__ __volatile__
+		("1: movepl %4,%0@(0)\n\t"
+		  "addal  %5,%0\n\t"
+		  "dbra	  %1,1b"
+		  : "=a" (d), "=d" (h)
+		  : "0" (d), "1" (h - 1), "d" (val), "r" (bpr)
+		);
+}
+
+/* Sets a 4 plane region from 'd', length 'count' bytes, to the color
+ * in val1/val2. 'd' has to be an even address and count must be divisible
+ * by 8, because only whole words and all planes are accessed. I.e.:
+ *
+ * for(count/8 times)
+ *   *d     = *(d+1) = (color & 1) ? 0xff : 0;
+ *   *(d+2) = *(d+3) = (color & 2) ? 0xff : 0;
+ *   *(d+4) = *(d+5) = (color & 4) ? 0xff : 0;
+ *   *(d+6) = *(d+7) = (color & 8) ? 0xff : 0;
+ */
+
+static __inline__ void memset_even_4p(void *d, size_t count, u_long val1,
+                                      u_long val2)
+{
+  u_long *dd = d;
+
+  count /= 8;
+  while (count--)
+    {
+      *dd++ = val1;
+      *dd++ = val2;
+    }
+}
+
+/* Copies a 4 plane column from 's', height 'h', to 'd'. */
+
+static __inline__ void memmove_4p_col (void *d, void *s, int h, int bpr)
+{
+  u_char *dd = d, *ss = s;
+
+  while (h--)
+    {
+      dd[0] = ss[0];
+      dd[2] = ss[2];
+      dd[4] = ss[4];
+      dd[6] = ss[6];
+      dd += bpr;
+      ss += bpr;
+    }
+}
+
+
+/* This expands a 4 bit color into a long for movepl (4 plane) operations. */
+
+static __inline__ u_long expand4l(u_char c)
+{
+	u_long	rv;
+
+	__asm__ __volatile__
+		("lsrb	 #1,%2\n\t"
+		  "scs	 %0\n\t"
+		  "lsll	 #8,%0\n\t"
+		  "lsrb	 #1,%2\n\t"
+		  "scs	 %0\n\t"
+		  "lsll	 #8,%0\n\t"
+		  "lsrb	 #1,%2\n\t"
+		  "scs	 %0\n\t"
+		  "lsll	 #8,%0\n\t"
+		  "lsrb	 #1,%2\n\t"
+		  "scs	 %0\n\t"
+		  : "=&d" (rv), "=d" (c)
+		  : "1" (c)
+		);
+	return(rv);
+}
+
+/* This expands a 4 bit color into two longs for two movel operations
+ * (4 planes).
+ */
+
+static __inline__ void expand4dl(u_char c, u_long *ret1, u_long *ret2)
+{
+	u_long	rv1, rv2;
+
+	__asm__ __volatile__
+		("lsrb	 #1,%3\n\t"
+		  "scs	 %0\n\t"
+		  "extw	 %0\n\t"
+		  "swap	 %0\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %0\n\t"
+		  "extw	 %0\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %1\n\t"
+		  "extw	 %1\n\t"
+		  "swap	 %1\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs   %1\n\t"
+		  "extw	 %1"
+		  : "=&d" (rv1), "=&d" (rv2), "=d" (c)
+		  : "2" (c)
+		);
+	*ret1 = rv1;
+	*ret2 = rv2;
+}
+
+
+/* This duplicates a byte 4 times into a long. */
+
+static __inline__ u_long dup4l(u_char c)
+{
+	ushort	tmp;
+	ulong	rv;
+
+	__asm__ __volatile__
+		("moveb  %2,%0\n\t"
+		  "lslw   #8,%0\n\t"
+		  "moveb  %2,%0\n\t"
+		  "movew  %0,%1\n\t"
+		  "swap   %0\n\t"
+		  "movew  %1,%0"
+		  : "=&d" (rv), "=d" (tmp)
+		  : "d" (c)
+		);
+
+	return(rv);
+}
+
+
+/* Sets the bytes in the visible column at d, height h, to the value
+ * val1,val2 for a 8 plane screen. The the bis of the color in 'color' are
+ * moved (8 times) to the respective bytes. This means:
+ *
+ * for(h times; d += bpr)
+ *   *d      = (color & 1) ? 0xff : 0;
+ *   *(d+2)  = (color & 2) ? 0xff : 0;
+ *   *(d+4)  = (color & 4) ? 0xff : 0;
+ *   *(d+6)  = (color & 8) ? 0xff : 0;
+ *   *(d+8)  = (color & 16) ? 0xff : 0;
+ *   *(d+10) = (color & 32) ? 0xff : 0;
+ *   *(d+12) = (color & 64) ? 0xff : 0;
+ *   *(d+14) = (color & 128) ? 0xff : 0;
+ */
+
+static __inline__ void memclear_8p_col(void *d, size_t h, u_long val1,
+                                       u_long val2, int bpr)
+{
+	__asm__ __volatile__
+		("1: movepl %4,%0@(0)\n\t"
+	      "movepl %5,%0@(8)\n\t"
+		  "addal  %6,%0\n\t"
+		  "dbra	  %1,1b"
+		  : "=a" (d), "=d" (h)
+		  : "0" (d), "1" (h - 1), "d" (val1), "d" (val2), "r" (bpr)
+		);
+}
+
+/* Sets a 8 plane region from 'd', length 'count' bytes, to the color
+ * val1..val4. 'd' has to be an even address and count must be divisible
+ * by 16, because only whole words and all planes are accessed. I.e.:
+ *
+ * for(count/16 times)
+ *   *d      = *(d+1)  = (color & 1) ? 0xff : 0;
+ *   *(d+2)  = *(d+3)  = (color & 2) ? 0xff : 0;
+ *   *(d+4)  = *(d+5)  = (color & 4) ? 0xff : 0;
+ *   *(d+6)  = *(d+7)  = (color & 8) ? 0xff : 0;
+ *   *(d+8)  = *(d+9)  = (color & 16) ? 0xff : 0;
+ *   *(d+10) = *(d+11) = (color & 32) ? 0xff : 0;
+ *   *(d+12) = *(d+13) = (color & 64) ? 0xff : 0;
+ *   *(d+14) = *(d+15) = (color & 128) ? 0xff : 0;
+ */
+
+static __inline__ void memset_even_8p(void *d, size_t count, u_long val1,
+                                      u_long val2, u_long val3, u_long val4)
+{
+  u_long *dd = d;
+
+  count /= 16;
+  while (count--)
+    {
+      *dd++ = val1;
+      *dd++ = val2;
+      *dd++ = val3;
+      *dd++ = val4;
+    }
+}
+
+/* Copies a 8 plane column from 's', height 'h', to 'd'. */
+
+static __inline__ void memmove_8p_col (void *d, void *s, int h, int bpr)
+{
+  u_char *dd = d, *ss = s;
+
+  while (h--)
+    {
+      dd[0] = ss[0];
+      dd[2] = ss[2];
+      dd[4] = ss[4];
+      dd[6] = ss[6];
+      dd[8] = ss[8];
+      dd[10] = ss[10];
+      dd[12] = ss[12];
+      dd[14] = ss[14];
+      dd += bpr;
+      ss += bpr;
+    }
+}
+
+
+/* This expands a 8 bit color into two longs for two movepl (8 plane)
+ * operations.
+ */
+
+static __inline__ void expand8dl(u_char c, u_long *ret1, u_long *ret2)
+{
+	u_long	rv1, rv2;
+
+	__asm__ __volatile__
+		("lsrb	 #1,%3\n\t"
+		  "scs	 %0\n\t"
+		  "lsll	 #8,%0\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %0\n\t"
+		  "lsll	 #8,%0\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %0\n\t"
+		  "lsll	 #8,%0\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %0\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %1\n\t"
+		  "lsll	 #8,%1\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %1\n\t"
+		  "lsll	 #8,%1\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %1\n\t"
+		  "lsll	 #8,%1\n\t"
+		  "lsrb	 #1,%3\n\t"
+		  "scs	 %1"
+		  : "=&d" (rv1), "=&d" (rv2),"=d" (c)
+		  : "2" (c)
+		);
+
+	*ret1 = rv1;
+	*ret2 = rv2;
+}
+
+/* This expands a 8 bit color into four longs for four movel operations
+ * (8 planes).
+ */
+
+/* ++andreas: use macro to avoid taking address of return values */
+#define expand8ql(c, rv1, rv2, rv3, rv4) \
+do {	u_char tmp = c;						\
+	__asm__ __volatile__					\
+		("lsrb	 #1,%5\n\t"				\
+		  "scs	 %0\n\t"				\
+		  "extw	 %0\n\t"				\
+		  "swap	 %0\n\t"				\
+		  "lsrb	 #1,%5\n\t"				\
+		  "scs	 %0\n\t"				\
+		  "extw	 %0\n\t"				\
+		  "lsrb	 #1,%5\n\t"				\
+		  "scs	 %1\n\t"				\
+		  "extw	 %1\n\t"				\
+		  "swap	 %1\n\t"				\
+		  "lsrb	 #1,%5\n\t"				\
+		  "scs   %1\n\t"				\
+		  "extw	 %1\n\t"				\
+		  "lsrb	 #1,%5\n\t"				\
+		  "scs	 %2\n\t"				\
+		  "extw	 %2\n\t"				\
+		  "swap	 %2\n\t"				\
+		  "lsrb	 #1,%5\n\t"				\
+		  "scs	 %2\n\t"				\
+		  "extw	 %2\n\t"				\
+		  "lsrb	 #1,%5\n\t"				\
+		  "scs	 %3\n\t"				\
+		  "extw	 %3\n\t"				\
+		  "swap	 %3\n\t"				\
+		  "lsrb	 #1,%5\n\t"				\
+		  "scs   %3\n\t"				\
+		  "extw	 %3"					\
+		  : "=&d" (rv1), "=&d" (rv2), "=&d" (rv3),	\
+		    "=&d" (rv4), "=d" (tmp)			\
+		  : "4" (tmp)					\
+		);						\
+} while (0)
+
+
+/* Sets the bytes in the visible column at d, height h, to the value
+ * val for a 2 plane screen. The the bis of the color in 'color' are
+ * moved (8 times) to the respective bytes. This means:
+ *
+ * for(h times; d += bpr)
+ *   *d     = (color & 1) ? 0xff : 0;
+ *   *(d+2) = (color & 2) ? 0xff : 0;
+ */
+
+static __inline__ void memclear_2p_col(void *d, size_t h, u_short val, int bpr)
+{
+	__asm__ __volatile__
+		("1: movepw %4,%0@(0)\n\t"
+		  "addal  %5,%0\n\t"
+		  "dbra	  %1,1b"
+		  : "=a" (d), "=d" (h)
+		  : "0" (d), "1" (h - 1), "d" (val), "r" (bpr)
+		);
+}
+
+/* Sets a 2 plane region from 'd', length 'count' bytes, to the color
+ * in val1. 'd' has to be an even address and count must be divisible
+ * by 8, because only whole words and all planes are accessed. I.e.:
+ *
+ * for(count/4 times)
+ *   *d     = *(d+1) = (color & 1) ? 0xff : 0;
+ *   *(d+2) = *(d+3) = (color & 2) ? 0xff : 0;
+ */
+
+static __inline__ void memset_even_2p(void *d, size_t count, u_long val)
+{
+  u_long *dd = d;
+
+  count /= 4;
+  while (count--)
+    *dd++ = val;
+}
+
+/* Copies a 2 plane column from 's', height 'h', to 'd'. */
+
+static __inline__ void memmove_2p_col (void *d, void *s, int h, int bpr)
+{
+  u_char *dd = d, *ss = s;
+
+  while (h--)
+    {
+      dd[0] = ss[0];
+      dd[2] = ss[2];
+      dd += bpr;
+      ss += bpr;
+    }
+}
+
+
+/* This expands a 2 bit color into a short for movepw (2 plane) operations. */
+
+static __inline__ u_short expand2w(u_char c)
+{
+	u_short	rv;
+
+	__asm__ __volatile__
+		("lsrb	 #1,%2\n\t"
+		  "scs	 %0\n\t"
+		  "lsll	 #8,%0\n\t"
+		  "lsrb	 #1,%2\n\t"
+		  "scs	 %0\n\t"
+		  : "=&d" (rv), "=d" (c)
+		  : "1" (c)
+		);
+	return(rv);
+}
+
+/* This expands a 2 bit color into one long for a movel operation
+ * (2 planes).
+ */
+
+static __inline__ u_long expand2l(u_char c)
+{
+	u_long	rv;
+
+	__asm__ __volatile__
+		("lsrb	 #1,%2\n\t"
+		  "scs	 %0\n\t"
+		  "extw	 %0\n\t"
+		  "swap	 %0\n\t"
+		  "lsrb	 #1,%2\n\t"
+		  "scs	 %0\n\t"
+		  "extw	 %0\n\t"
+		  : "=&d" (rv), "=d" (c)
+		  : "1" (c)
+		);
+
+	return rv;
+}
+
+
+/* This duplicates a byte 2 times into a short. */
+
+static __inline__ u_short dup2w(u_char c)
+{
+    ushort  rv;
+
+    __asm__ __volatile__
+        ( "moveb  %1,%0\n\t"
+          "lslw   #8,%0\n\t"
+          "moveb  %1,%0\n\t"
+          : "=&d" (rv)
+          : "d" (c)
+        );
+
+    return( rv );
+}
+
+
+/* ====================================================================== */
+
+/* fbcon_XXX routines - interface used by the world
+ *
+ * This system is now divided into two levels because of complications
+ * caused by hardware scrolling. Top level functions:
+ *
+ *    fbcon_bmove(), fbcon_clear(), fbcon_putc()
+ *
+ * handles y values in range [0, scr_height-1] that correspond to real
+ * screen positions. y_wrap shift means that first line of bitmap may be
+ * anywhere on this display. These functions convert lineoffsets to
+ * bitmap offsets and deal with the wrap-around case by splitting blits.
+ *
+ *    fbcon_bmove_physical_8()   -- These functions fast implementations
+ *    fbcon_clear_physical_8()   -- of original fbcon_XXX fns.
+ *    fbcon_putc_physical_8()    -- (fontwidth != 8) may be added later
+ *
+ * WARNING:
+ *
+ * At the moment fbcon_putc() cannot blit across vertical wrap boundary
+ * Implies should only really hardware scroll in rows. Only reason for
+ * restriction is simplicity & efficiency at the moment.
+ */
+
+static __inline__ int real_y(struct display *p, int y)
+{
+   int rows = p->vrows;
+
+   y += p->yscroll;
+   return(y < rows ? y : y-rows);
+}
+
+
+static int fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
+                       int width)
+{
+   int unit = conp->vc_num;
+   struct display *p = &disp[unit];
+   u_int y_break;
+
+   if (!p->can_soft_blank && console_blanked)
+      return(0);
+
+   if ((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&
+       (sx <= p->cursor_x) && (p->cursor_x < sx+width))
+      CURSOR_UNDRAWN();
+
+   /* Split blits that cross physical y_wrap boundary */
+
+   y_break = p->vrows-p->yscroll;
+   if (sy < y_break && sy+height-1 >= y_break) {
+      u_int b = y_break-sy;
+      p->dispsw->clear(conp, p, real_y(p, sy), sx, b, width);
+      p->dispsw->clear(conp, p, real_y(p, sy+b), sx, height-b, width);
+   } else
+      p->dispsw->clear(conp, p, real_y(p, sy), sx, height, width);
+
+   return(0);
+}
+
+
+static int fbcon_putc(struct vc_data *conp, int c, int y, int x)
+{
+   int unit = conp->vc_num;
+   struct display *p = &disp[unit];
+
+   if (!p->can_soft_blank && console_blanked)
+      return(0);
+
+   if ((p->cursor_x == x) && (p->cursor_y == y))
+       CURSOR_UNDRAWN();
+
+   p->dispsw->putc(conp, p, c, real_y(p, y), x);
+
+   return(0);
+}
+
+
+static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int y,
+                       int x)
+{
+   int unit = conp->vc_num;
+   struct display *p = &disp[unit];
+
+   if (!p->can_soft_blank && console_blanked)
+      return(0);
+
+   if ((p->cursor_y == y) && (x <= p->cursor_x) && (p->cursor_x < x+count))
+      CURSOR_UNDRAWN();
+
+   p->dispsw->putcs(conp, p, s, count, real_y(p, y), x);
+
+   return(0);
+}
+
+
+static int fbcon_cursor(struct vc_data *conp, int mode)
+{
+   int unit = conp->vc_num;
+   struct display *p = &disp[unit];
+
+   if (CURSOR_UNDRAWN ())
+      p->dispsw->rev_char(p, p->cursor_x, real_y(p, p->cursor_y));
+   p->cursor_x = conp->vc_x;
+   p->cursor_y = conp->vc_y;
+
+   switch (mode) {
+      case CM_ERASE:
+         cursor_on = 0;
+         break;
+
+      case CM_MOVE:
+      case CM_DRAW:
+         vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+         cursor_on = 1;
+         break;
+   }
+
+   return(0);
+}
+
+
+static void fbcon_vbl_handler(int irq, struct pt_regs *fp, void *dummy)
+{
+   struct display *p;
+
+   if (!cursor_on)
+      return;
+
+   if (vbl_cursor_cnt && --vbl_cursor_cnt == 0) {
+      /* Here no check is possible for console changing. The console
+       * switching code should set vbl_cursor_cnt to an appropriate value.
+       */
+      p = &disp[fg_console];
+      p->dispsw->rev_char(p, p->cursor_x, real_y(p, p->cursor_y));
+      cursor_drawn ^= 1;
+      vbl_cursor_cnt = cursor_blink_rate;
+   }
+}
+
+
+static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
+{
+   int unit = conp->vc_num;
+   struct display *p = &disp[unit];
+
+   if (!p->can_soft_blank && console_blanked)
+      return(0);
+
+   fbcon_cursor(conp, CM_ERASE);
+
+   /*
+    * ++Geert: Only use ywrap/ypan if the console is in text mode
+    */
+
+   switch (dir) {
+      case SM_UP:
+         if (t == 0 && b == conp->vc_rows &&
+             vt_cons[unit]->vc_mode == KD_TEXT) {
+            if (count > conp->vc_rows)             /* Maximum realistic size */
+               count = conp->vc_rows;
+            switch (p->scrollmode) {
+               case SCROLL_YWRAP:
+                  p->yscroll += count;
+                  if (p->yscroll >= p->vrows) /* Deal with wrap */
+                     p->yscroll -= p->vrows;
+                  p->var.xoffset = 0;
+                  p->var.yoffset = p->yscroll*p->fontheight;
+                  p->var.vmode |= FB_VMODE_YWRAP;
+                  fb_info->updatevar(unit);
+                  break;
+
+               case SCROLL_YPAN:
+                  p->yscroll += count;
+                  if (p->yscroll+conp->vc_rows > p->vrows) {
+                     p->dispsw->bmove(p, p->yscroll, 0, 0, 0, b-count,
+                                      conp->vc_cols);
+                     p->yscroll = 0;
+                  }
+                  p->var.xoffset = 0;
+                  p->var.yoffset = p->yscroll*p->fontheight;
+                  p->var.vmode &= ~FB_VMODE_YWRAP;
+                  fb_info->updatevar(unit);
+                  break;
+
+               case SCROLL_YMOVE:
+                  p->dispsw->bmove(p, count, 0, 0, 0, b-count, conp->vc_cols);
+                  break;
+            }
+         } else
+            fbcon_bmove(conp, t+count, 0, t, 0, b-t-count, conp->vc_cols);
+         fbcon_clear(conp, b-count, 0, count, conp->vc_cols);
+         break;
+
+      case SM_DOWN:
+         if (t == 0 && b == conp->vc_rows &&
+             vt_cons[unit]->vc_mode == KD_TEXT) {
+            if (count > conp->vc_rows)             /* Maximum realistic size */
+               count = conp->vc_rows;
+            switch (p->scrollmode) {
+               case SCROLL_YWRAP:
+                  p->yscroll -= count;
+                  if (p->yscroll < 0)              /* Deal with wrap */
+                     p->yscroll += p->vrows;
+                  p->var.xoffset = 0;
+                  p->var.yoffset = p->yscroll*p->fontheight;
+                  p->var.vmode |= FB_VMODE_YWRAP;
+                  fb_info->updatevar(unit);
+                  break;
+
+               case SCROLL_YPAN:
+                  p->yscroll -= count;
+                  if (p->yscroll < 0) {
+                     p->yscroll = p->vrows-conp->vc_rows;
+                     p->dispsw->bmove(p, 0, 0, p->yscroll+count, 0, b-count,
+                                      conp->vc_cols);
+                  }
+                  p->var.xoffset = 0;
+                  p->var.yoffset = p->yscroll*p->fontheight;
+                  p->var.vmode &= ~FB_VMODE_YWRAP;
+                  fb_info->updatevar(unit);
+                  break;
+
+               case SCROLL_YMOVE:
+                  p->dispsw->bmove(p, 0, 0, count, 0, b-count, conp->vc_cols);
+                  break;
+            }
+         } else
+            fbcon_bmove(conp, t, 0, t+count, 0, b-t-count, conp->vc_cols);
+
+         /* Fixed bmove() should end Arno's frustration with copying?
+          * Confucius says:
+          *    Man who copies in wrong direction, end up with trashed data
+          */
+         fbcon_clear(conp, t, 0, count, conp->vc_cols);
+         break;
+
+      case SM_LEFT:
+         fbcon_bmove(conp, 0, t+count, 0, t, conp->vc_rows, b-t-count);
+         fbcon_clear(conp, 0, b-count, conp->vc_rows, count);
+         break;
+
+      case SM_RIGHT:
+         fbcon_bmove(conp, 0, t, 0, t+count, conp->vc_rows, b-t-count);
+         fbcon_clear(conp, 0, t, conp->vc_rows, count);
+         break;
+   }
+
+   return(0);
+}
+
+
+static int fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+                       int height, int width)
+{
+   int unit = conp->vc_num;
+   struct display *p = &disp[unit];
+
+   if (!p->can_soft_blank && console_blanked)
+      return(0);
+
+   if (((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&
+        (sx <= p->cursor_x) && (p->cursor_x < sx+width)) ||
+       ((dy <= p->cursor_y) && (p->cursor_y < dy+height) &&
+        (dx <= p->cursor_x) && (p->cursor_x < dx+width)))
+      fbcon_cursor(conp, CM_ERASE);
+
+   /* Split blits that cross physical y_wrap case.
+    * Pathological case involves 4 blits, better to use recursive
+    * code rather than unrolled case
+    *
+    * Recursive invocations don't need to erase the cursor over and
+    * over again, so we use fbcon_bmove_rec()
+    */
+   fbcon_bmove_rec(p, sy, sx, dy, dx, height, width, p->vrows-p->yscroll);
+
+   return(0);
+}
+
+
+static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy, int dx,
+                            int height, int width, u_int y_break)
+{
+   u_int b;
+
+   if (sy < y_break && sy+height > y_break) {
+      b = y_break-sy;
+      if (dy < sy) {       /* Avoid trashing self */
+         fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
+         fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
+      } else {
+         fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
+         fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
+      }
+      return;
+   }
+
+   if (dy < y_break && dy+height > y_break) {
+      b = y_break-dy;
+      if (dy < sy) {       /* Avoid trashing self */
+         fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
+         fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
+      } else {
+         fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
+         fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
+      }
+      return;
+   }
+   p->dispsw->bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width);
+}
+
+
+static int fbcon_switch(struct vc_data *conp)
+{
+   if (fb_info && fb_info->switch_con)
+      (*fb_info->switch_con)(conp->vc_num);
+   return(0);
+}
+
+
+static int fbcon_blank(int blank)
+{
+   struct display *p = &disp[fg_console];
+
+   fbcon_cursor(p->conp, blank ? CM_ERASE : CM_DRAW);
+
+   if (!p->can_soft_blank)
+      if (blank) {
+         if (p->visual == FB_VISUAL_MONO01)
+             mymemset(p->screen_base, p->var.xres_virtual*p->var.yres_virtual*
+                                      p->var.bits_per_pixel>>3);
+          else
+             mymemclear(p->screen_base, p->var.xres_virtual*p->var.yres_virtual*
+                                        p->var.bits_per_pixel>>3);
+         return(0);
+      } else {
+         /* Tell console.c that it has to restore the screen itself */
+         return(1);
+      }
+   (*fb_info->blank)(blank);
+   return(0);
+}
+
+
+static int fbcon_get_font(struct vc_data *conp, int *w, int *h, char *data)
+{
+	int unit = conp->vc_num;
+	struct display *p = &disp[unit];
+	int i, size, alloc;
+
+	size = (p->fontwidth+7)/8 * p->fontheight * 256;
+	alloc = (*w+7)/8 * *h * 256;
+	*w = p->fontwidth;
+	*h = p->fontheight;
+   
+	if (alloc < size)
+		/* allocation length not sufficient */
+		return( -ENAMETOOLONG );
+
+	if ((i = verify_area( VERIFY_WRITE, (void *)data, size )))
+		return i;
+
+	memcpy_tofs( data, p->fontdata, size );
+	return( 0 );
+}
+
+
+#define REFCOUNT(fd)	(((int *)(fd))[-1])
+
+static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data)
+{
+	int unit = conp->vc_num;
+	struct display *p = &disp[unit];
+	int i, size, userspace = 1, resize;
+	char *old_data = NULL, *new_data;
+
+	if (w < 0)
+		w = p->fontwidth;
+	if (h < 0)
+		h = p->fontheight;
+	
+	printk("Set_font, w=%d, h=%d, data=%s\n", w, h, data);
+	
+	if (w == 0) {
+		/* engage predefined font, name in 'data' */
+		char name[MAX_FONT_NAME+1];
+	   
+		if ((i = verify_area( VERIFY_READ, (void *)data, MAX_FONT_NAME )))
+			return i;
+		memcpy_fromfs( name, data, MAX_FONT_NAME );
+		name[sizeof(name)-1] = 0;
+		
+		if (!findsoftfont( name, &w, &h, (u_char **)&data ))
+			return( -ENOENT );
+		userspace = 0;
+	}
+	else if (w == 1) {
+		/* copy font from some other console in 'h'*/
+		struct display *op;
+
+		if (h < 0 || !vc_cons_allocated( h ))
+			return( -ENOTTY );
+		if (h == unit)
+			return( 0 ); /* nothing to do */
+		op = &disp[h];
+		if (op->fontdata == p->fontdata)
+			return( 0 ); /* already the same font... */
+
+		resize = (op->fontwidth != p->fontwidth) ||
+			     (op->fontheight != p->fontheight);
+		if (p->userfont)
+			old_data = p->fontdata;
+		p->fontdata = op->fontdata;
+		w = p->fontwidth = op->fontwidth;
+		h = p->fontheight = op->fontheight;
+		if ((p->userfont = op->userfont))
+			REFCOUNT(p->fontdata)++; /* increment usage counter */
+		goto activate;
+	}
+
+	if ((p->dispsw != &dispsw_mono) && (w != 8))
+		/* Currently only fontwidth == 8 supported */
+		return( -ENXIO );
+	if ((p->dispsw == &dispsw_mono) && (w != 8) && (w != 4))
+		return( -ENXIO );
+		
+	resize = (w != p->fontwidth) || (h != p->fontheight);
+	size = (w+7)/8 * h * 256;
+	
+	if (p->userfont)
+		old_data = p->fontdata;
+	
+	if (userspace) {
+		if ((i = verify_area( VERIFY_READ, (void *)data, size )))
+			return i;
+		if (!(new_data = kmalloc( sizeof(int)+size, GFP_USER )))
+			return( -ENOMEM );
+		new_data += sizeof(int);
+		REFCOUNT(new_data) = 1; /* usage counter */
+		memcpy_fromfs( new_data, data, size );
+		p->fontdata = new_data;
+		p->userfont = 1;
+	}
+	else {
+		p->fontdata = data;
+		p->userfont = 0;
+	}
+	p->fontwidth = w;
+	p->fontheight = h;
+
+  activate:
+	if (resize) {
+		p->var.xoffset = p->var.yoffset = p->yscroll = 0;  /* reset wrap/pan */
+		if (divides(p->ywrapstep, p->fontheight))
+			p->scrollmode = SCROLL_YWRAP;
+		else if (divides(p->ypanstep, p->fontheight) &&
+				 p->var.yres_virtual >= p->var.yres+p->fontheight)
+			p->scrollmode = SCROLL_YPAN;
+		else
+			p->scrollmode = SCROLL_YMOVE;
+
+		vc_resize_con( p->var.yres/h, p->var.xres/w, unit );
+	}
+	else if (unit == fg_console)
+		update_screen( unit );
+	
+	if (old_data) {
+		if (--REFCOUNT(old_data) == 0) {
+			kfree( old_data - sizeof(int) );
+		}
+	}
+	
+	return( 0 );
+}
+
+
+/* ====================================================================== */
+
+/*
+ *    Low Level Operations for the various display memory organizations.
+ *
+ *    Currently only the following organizations are supported here:
+ *
+ *      - Monochrome
+ *      - Color Interleaved Planes à la Amiga
+ *      - Color Normal Planes
+ *      - Color Interleaved Planes à la Atari (2, 4 and 8 planes)
+ *      - Color Packed Pixels (8 and 16 bpp)
+ *      - Cybervision Color Packed Pixels (accelerated)
+ */
+
+#ifdef CONFIG_FBCON_MONO
+
+   /*
+    *    Monochrome
+    */
+
+
+static u_char mask4[2] = {0xF0, 0x0F};
+
+static void bmove_mono(struct display *p, int sy, int sx, int dy, int dx,
+                       int height, int width)
+{
+   u_char *src, *dest;
+   u_int rows;
+
+   if (p->fontwidth == 8) {
+   if (sx == 0 && sy == 0 && width == p->next_line) {
+      src = p->screen_base;
+      dest = p->screen_base+dy*p->fontheight*width;
+      mymemmove(dest, src, height*p->fontheight*width);
+   } else if (dy <= sy) {
+      src = p->screen_base+sy*p->fontheight*p->next_line+sx;
+      dest = p->screen_base+dy*p->fontheight*p->next_line+dx;
+      for (rows = height*p->fontheight; rows--;) {
+         mymemmove(dest, src, width);
+         src += p->next_line;
+         dest += p->next_line;
+      }
+   } else {
+      src = p->screen_base+((sy+height)*p->fontheight-1)*p->next_line+sx;
+      dest = p->screen_base+((dy+height)*p->fontheight-1)*p->next_line+dx;
+      for (rows = height*p->fontheight; rows--;) {
+         mymemmove(dest, src, width);
+         src -= p->next_line;
+         dest -= p->next_line;
+      }
+   }
+   } else { /* fw == 4 */
+   if ((sx == 0) && (sy == 0) && (width == (p->next_line*2))) {
+      src = p->screen_base;
+      dest = p->screen_base+dy*p->fontheight*p->next_line;
+      mymemmove(dest, src, height*p->fontheight*p->next_line);
+   } else if ((dy <= sy) && ((width & 1) == 0) && ((sx & 1) == 0) && ((dy & 1) == 0)) {
+      src = p->screen_base+sy*p->fontheight*p->next_line+(sx>>1);
+      dest = p->screen_base+dy*p->fontheight*p->next_line+(dx>>1);
+      for (rows = height*p->fontheight; rows--;) {
+         mymemmove(dest, src, width);
+         src += p->next_line;
+         dest += p->next_line;
+      }
+   } else {
+     int x,y,ry;
+     for(x=0;x<width;x++)
+       for(y=0;y<height;y++)
+         for(ry=0;ry<p->fontheight;ry++) {
+           u_char * src = p->screen_base+((sy+y)*p->fontheight+ry)*p->next_line+((sx+x)>>1);
+           u_char * dest = p->screen_base+((dy+y)*p->fontheight+ry)*p->next_line+((dx+x)>>1);
+           int rs = (sx+x) & 1;
+           int rd = (dx+x) & 1;
+           if (rs == rd)
+           	*dest = (*dest & ~mask4[rd]) | (*src & mask4[rs]);
+           else if (rs == 0) 
+           	*dest = (*dest & ~mask4[rd]) | ((*src & mask4[rs]) >> 4);
+           else if (rs == 1) 
+           	*dest = (*dest & ~mask4[rd]) | ((*src & mask4[rs]) << 4);
+         }
+   }
+   }
+
+}
+
+
+static void clear_mono(struct vc_data *conp, struct display *p, int sy, int sx,
+                       int height, int width)
+{
+   u_char *dest;
+   u_int rows;
+
+   dest = p->screen_base+sy*p->fontheight*p->next_line+sx;
+
+   if (p->fontwidth == 8) {
+   if (sx == 0 && width == p->next_line)
+      if (attr_reverse(p,conp))
+         mymemset(dest, height*p->fontheight*width);
+      else
+         mymemclear(dest, height*p->fontheight*width);
+   else
+      for (rows = height*p->fontheight; rows--; dest += p->next_line)
+         if (attr_reverse(p,conp))
+            mymemset(dest, width);
+         else
+            mymemclear_small(dest, width);
+   } else { /* fw == 4 */
+
+     if ((sx == 0) && (width == (p->next_line*2)))
+        if (attr_reverse(p,conp))
+           mymemset(dest, height*p->fontheight*p->next_line);
+        else
+           mymemclear(dest, height*p->fontheight*p->next_line);
+     else
+     {
+     int x,y,ry;
+     for(x=sx;x<sx+width;x++)
+       for(y=sy;y<sy+height;y++)
+         for(ry=0;ry<p->fontheight;ry++)
+           *(p->screen_base+(y*p->fontheight+ry)*p->next_line+(x>>1)) &= mask4[x & 1 ^ 1];
+     }
+  }
+}
+
+
+static void putc_mono(struct vc_data *conp, struct display *p, int c, int y,
+                      int x)
+{
+   u_char *dest, *cdat;
+   u_int rows, bold, reverse, underline;
+   u_char d;
+
+   c &= 0xff;
+   
+   if (p->fontwidth == 8) {
+
+   dest = p->screen_base+y*p->fontheight*p->next_line+x;
+   cdat = p->fontdata+c*p->fontheight;
+   bold = attr_bold(p,conp);
+   reverse = attr_reverse(p,conp);
+   underline = attr_underline(p,conp);
+
+   for (rows = p->fontheight; rows--; dest += p->next_line) {
+      d = *cdat++;
+      if (underline && !rows)
+         d = 0xff;
+      else if (bold)
+         d |= d>>1;
+      if (reverse)
+         d = ~d;
+      *dest = d;
+   }
+   } else { /* fontwidth == 4 */
+   int r = x & 1;
+   dest = p->screen_base+y*p->fontheight*p->next_line+(x>>1);
+   
+   cdat = p->fontdata+c*p->fontheight;
+   bold = attr_bold(p,conp);
+   reverse = attr_reverse(p,conp);
+   underline = attr_underline(p,conp);
+
+   for (rows = p->fontheight; rows--; dest += p->next_line) {
+      d = *cdat++;
+      if (underline && !rows)
+         d = 0xff;
+      else if (bold)
+         d |= d>>1;
+      if (reverse)
+         d = ~d;
+      *dest = (*dest & ~mask4[r]) | (d & mask4[r]);
+   }
+   }
+}
+
+
+static void putcs_mono(struct vc_data *conp, struct display *p, const char *s,
+                       int count, int y, int x)
+{
+   u_char *dest, *dest0, *cdat;
+   u_int rows, bold, reverse, underline;
+   u_char c, d;
+   
+   if (p->fontwidth==8) {
+
+   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   bold = attr_bold(p,conp);
+   reverse = attr_reverse(p,conp);
+   underline = attr_underline(p,conp);
+
+   while (count--) {
+      c = *s++;
+      dest = dest0++;
+      cdat = p->fontdata+c*p->fontheight;
+      for (rows = p->fontheight; rows--; dest += p->next_line) {
+         d = *cdat++;
+         if (underline && !rows)
+            d = 0xff;
+         else if (bold)
+            d |= d>>1;
+         if (reverse)
+            d = ~d;
+         *dest = d;
+      }
+   }
+   
+   } else {	/* fontwidth == 4 */
+
+   int r = x & 1;
+   dest0 = p->screen_base+y*p->fontheight*p->next_line+(x>>1);
+   bold = attr_bold(p,conp);
+   reverse = attr_reverse(p,conp);
+   underline = attr_underline(p,conp);
+
+   while (count--) {
+      c = *s++;
+      dest = dest0;
+      cdat = p->fontdata+c*p->fontheight;
+      for (rows = p->fontheight; rows--; dest += p->next_line) {
+         d = *cdat++;
+         if (underline && !rows)
+            d = 0xff;
+         else if (bold)
+            d |= d>>1;
+         if (reverse)
+            d = ~d;
+         *dest = (*dest & ~mask4[r]) | (d & mask4[r]);
+      }
+      r ^= 1;
+      if (!r)
+        dest0++;
+   }
+   	
+   }
+}
+
+
+static void rev_char_mono(struct display *p, int x, int y)
+{
+   u_char *dest;
+   u_int rows;
+
+   if (p->fontwidth == 8) {
+     dest = p->screen_base+y*p->fontheight*p->next_line+x;
+     for (rows = p->fontheight; rows--; dest += p->next_line)
+        *dest = ~*dest;
+   } else { /* fw == 4 */
+     dest = p->screen_base+y*p->fontheight*p->next_line+(x>>1);
+     for (rows = p->fontheight; rows--; dest += p->next_line)
+        *dest ^= mask4[x&1];
+   }
+}
+
+#endif /* CONFIG_FBCON_MONO */
+
+
+/* ====================================================================== */
+
+#ifdef CONFIG_FBCON_ILBM
+
+   /*
+    *    Color Interleaved Planes
+    *
+    *    This code heavily relies on the fact that
+    *
+    *       next_line == interleave == next_plane*bits_per_pixel
+    *
+    *    But maybe it can be merged with the code for normal bitplanes without
+    *    much performance loss?
+    */
+
+static void bmove_ilbm(struct display *p, int sy, int sx, int dy, int dx,
+                       int height, int width)
+{
+   if (sx == 0 && sy == 0 && width == p->next_plane)
+      mymemmove(p->screen_base+dy*p->fontheight*p->next_line, p->screen_base,
+                height*p->fontheight*p->next_line);
+   else {
+      u_char *src, *dest;
+      u_int i;
+
+      if (dy <= sy) {
+         src = p->screen_base+sy*p->fontheight*p->next_line+sx;
+         dest = p->screen_base+dy*p->fontheight*p->next_line+dx;
+         for (i = p->var.bits_per_pixel*height*p->fontheight; i--;) {
+            mymemmove(dest, src, width);
+            src += p->next_plane;
+            dest += p->next_plane;
+         }
+      } else {
+         src = p->screen_base+(sy+height)*p->fontheight*p->next_line+sx;
+         dest = p->screen_base+(dy+height)*p->fontheight*p->next_line+dx;
+         for (i = p->var.bits_per_pixel*height*p->fontheight; i--;) {
+            src -= p->next_plane;
+            dest -= p->next_plane;
+            mymemmove(dest, src, width);
+         }
+      }
+   }
+}
+
+
+static void clear_ilbm(struct vc_data *conp, struct display *p, int sy, int sx,
+                       int height, int width)
+{
+   u_char *dest;
+   u_int i, rows;
+   int bg, bg0;
+
+   dest = p->screen_base+sy*p->fontheight*p->next_line+sx;
+
+   bg0 = attr_bgcol_ec(p,conp);
+   for (rows = height*p->fontheight; rows--;) {
+      bg = bg0;
+      for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
+         if (bg & 1)
+            mymemset(dest, width);
+         else
+            mymemclear(dest, width);
+         bg >>= 1;
+      }
+   }
+}
+
+
+static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int y,
+                      int x)
+{
+   u_char *dest, *cdat;
+   u_int rows, i;
+   u_char d;
+   int fg0, bg0, fg, bg;
+
+   c &= 0xff;
+
+   dest = p->screen_base+y*p->fontheight*p->next_line+x;
+   cdat = p->fontdata+c*p->fontheight;
+   fg0 = attr_fgcol(p,conp);
+   bg0 = attr_bgcol(p,conp);
+
+   for (rows = p->fontheight; rows--;) {
+      d = *cdat++;
+      fg = fg0;
+      bg = bg0;
+      for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
+         if (bg & 1)
+            if (fg & 1)
+               *dest = 0xff;
+            else
+               *dest = ~d;
+         else
+            if (fg & 1)
+               *dest = d;
+            else
+               *dest = 0x00;
+         bg >>= 1;
+         fg >>= 1;
+      }
+   }
+}
+
+
+/*
+ *    I split the console character loop in two parts:
+ *
+ *      - slow version: this blits one character at a time
+ *
+ *      - fast version: this blits 4 characters at a time at a longword aligned
+ *                      address, to reduce the number of expensive Chip RAM
+ *                      accesses.
+ *
+ *    Experiments on my A4000/040 revealed that this makes a console switch on a
+ *    640x400 screen with 256 colors about 3 times faster.
+ *
+ *                                                                Geert
+ */
+
+static void putcs_ilbm(struct vc_data *conp, struct display *p, const char *s,
+                       int count, int y, int x)
+{
+   u_char *dest0, *dest, *cdat1, *cdat2, *cdat3, *cdat4;
+   u_int rows, i;
+   u_char c1, c2, c3, c4;
+   u_long d;
+   int fg0, bg0, fg, bg;
+
+   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   fg0 = attr_fgcol(p,conp);
+   bg0 = attr_bgcol(p,conp);
+
+   while (count--)
+      if (x&3 || count < 3) {   /* Slow version */
+         c1 = *s++;
+         dest = dest0++;
+         x++;
+
+         cdat1 = p->fontdata+c1*p->fontheight;
+         for (rows = p->fontheight; rows--;) {
+            d = *cdat1++;
+            fg = fg0;
+            bg = bg0;
+            for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
+               if (bg & 1)
+                  if (fg & 1)
+                     *dest = 0xff;
+                  else
+                     *dest = ~d;
+               else
+                  if (fg & 1)
+                     *dest = d;
+                  else
+                     *dest = 0x00;
+               bg >>= 1;
+               fg >>= 1;
+            }
+         }
+      } else {                      /* Fast version */
+         c1 = s[0];
+         c2 = s[1];
+         c3 = s[2];
+         c4 = s[3];
+
+         dest = dest0;
+         cdat1 = p->fontdata+c1*p->fontheight;
+         cdat2 = p->fontdata+c2*p->fontheight;
+         cdat3 = p->fontdata+c3*p->fontheight;
+         cdat4 = p->fontdata+c4*p->fontheight;
+         for (rows = p->fontheight; rows--;) {
+            d = *cdat1++<<24 | *cdat2++<<16 | *cdat3++<<8 | *cdat4++;
+            fg = fg0;
+            bg = bg0;
+            for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
+               if (bg & 1)
+                  if (fg & 1)
+                     *(u_long *)dest = 0xffffffff;
+                  else
+                     *(u_long *)dest = ~d;
+               else
+                  if (fg & 1)
+                     *(u_long *)dest = d;
+                  else
+                     *(u_long *)dest = 0x00000000;
+               bg >>= 1;
+               fg >>= 1;
+            }
+         }
+         s += 4;
+         dest0 += 4;
+         x += 4;
+         count -= 3;
+      }
+}
+
+
+static void rev_char_ilbm(struct display *p, int x, int y)
+{
+   u_char *dest, *dest0;
+   u_int rows, i;
+   int mask;
+
+   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   mask = p->fgcol ^ p->bgcol;
+
+   /*
+    *    This should really obey the individual character's
+    *    background and foreground colors instead of simply
+    *    inverting.
+    */
+
+   for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
+      if (mask & 1) {
+         dest = dest0;
+         for (rows = p->fontheight; rows--; dest += p->next_line)
+            *dest = ~*dest;
+      }
+      mask >>= 1;
+   }
+}
+
+#endif /* CONFIG_FBCON_ILBM */
+
+
+/* ====================================================================== */
+
+#ifdef CONFIG_FBCON_PLANES
+
+   /*
+    *    Color Planes
+    */
+
+static void bmove_plan(struct display *p, int sy, int sx, int dy, int dx,
+                       int height, int width)
+{
+   u_char *src, *dest, *src0, *dest0;
+   u_int i, rows;
+
+   if (sx == 0 && sy == 0 && width == p->next_line) {
+      src = p->screen_base;
+      dest = p->screen_base+dy*p->fontheight*width;
+      for (i = p->var.bits_per_pixel; i--;) {
+         mymemmove(dest, src, height*p->fontheight*width);
+         src += p->next_plane;
+         dest += p->next_plane;
+      }
+   } else if (dy <= sy) {
+      src0 = p->screen_base+sy*p->fontheight*p->next_line+sx;
+      dest0 = p->screen_base+dy*p->fontheight*p->next_line+dx;
+      for (i = p->var.bits_per_pixel; i--;) {
+         src = src0;
+         dest = dest0;
+         for (rows = height*p->fontheight; rows--;) {
+            mymemmove(dest, src, width);
+            src += p->next_line;
+            dest += p->next_line;
+         }
+         src0 += p->next_plane;
+         dest0 += p->next_plane;
+      }
+   } else {
+      src0 = p->screen_base+(sy+height)*p->fontheight*p->next_line+sx;
+      dest0 = p->screen_base+(dy+height)*p->fontheight*p->next_line+dx;
+      for (i = p->var.bits_per_pixel; i--;) {
+         src = src0;
+         dest = dest0;
+         for (rows = height*p->fontheight; rows--;) {
+            src -= p->next_line;
+            dest -= p->next_line;
+            mymemmove(dest, src, width);
+         }
+         src0 += p->next_plane;
+         dest0 += p->next_plane;
+      }
+   }
+}
+
+
+static void clear_plan(struct vc_data *conp, struct display *p, int sy, int sx,
+                       int height, int width)
+{
+   u_char *dest, *dest0;
+   u_int i, rows;
+   int bg;
+
+   dest0 = p->screen_base+sy*p->fontheight*p->next_line+sx;
+
+   bg = attr_bgcol_ec(p,conp);
+   for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
+      dest = dest0;
+      for (rows = height*p->fontheight; rows--; dest += p->next_line)
+         if (bg & 1)
+            mymemset(dest, width);
+         else
+            mymemclear(dest, width);
+      bg >>= 1;
+   }
+}
+
+
+static void putc_plan(struct vc_data *conp, struct display *p, int c, int y,
+                      int x)
+{
+   u_char *dest, *dest0, *cdat, *cdat0;
+   u_int rows, i;
+   u_char d;
+   int fg, bg;
+
+   c &= 0xff;
+
+   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   cdat0 = p->fontdata+c*p->fontheight;
+   fg = attr_fgcol(p,conp);
+   bg = attr_bgcol(p,conp);
+
+   for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
+      dest = dest0;
+      cdat = cdat0;
+      for (rows = p->fontheight; rows--; dest += p->next_line) {
+         d = *cdat++;
+         if (bg & 1)
+            if (fg & 1)
+               *dest = 0xff;
+            else
+               *dest = ~d;
+         else
+            if (fg & 1)
+               *dest = d;
+            else
+               *dest = 0x00;
+      }
+      bg >>= 1;
+      fg >>= 1;
+   }
+}
+
+
+/*
+ *    I split the console character loop in two parts
+ *    (cfr. fbcon_putcs_ilbm())
+ */
+
+static void putcs_plan(struct vc_data *conp, struct display *p, const char *s,
+                       int count, int y, int x)
+{
+   u_char *dest, *dest0, *dest1;
+   u_char *cdat1, *cdat2, *cdat3, *cdat4, *cdat10, *cdat20, *cdat30, *cdat40;
+   u_int rows, i;
+   u_char c1, c2, c3, c4;
+   u_long d;
+   int fg0, bg0, fg, bg;
+
+   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   fg0 = attr_fgcol(p,conp);
+   bg0 = attr_bgcol(p,conp);
+
+   while (count--)
+      if (x&3 || count < 3) {   /* Slow version */
+         c1 = *s++;
+         dest1 = dest0++;
+         x++;
+
+         cdat10 = p->fontdata+c1*p->fontheight;
+         fg = fg0;
+         bg = bg0;
+
+         for (i = p->var.bits_per_pixel; i--; dest1 += p->next_plane) {
+            dest = dest1;
+            cdat1 = cdat10;
+            for (rows = p->fontheight; rows--; dest += p->next_line) {
+               d = *cdat1++;
+               if (bg & 1)
+                  if (fg & 1)
+                     *dest = 0xff;
+                  else
+                     *dest = ~d;
+               else
+                  if (fg & 1)
+                     *dest = d;
+                  else
+                     *dest = 0x00;
+            }
+            bg >>= 1;
+            fg >>= 1;
+         }
+      } else {                      /* Fast version */
+         c1 = s[0];
+         c2 = s[1];
+         c3 = s[2];
+         c4 = s[3];
+
+         dest1 = dest0;
+         cdat10 = p->fontdata+c1*p->fontheight;
+         cdat20 = p->fontdata+c2*p->fontheight;
+         cdat30 = p->fontdata+c3*p->fontheight;
+         cdat40 = p->fontdata+c4*p->fontheight;
+         fg = fg0;
+         bg = bg0;
+
+         for (i = p->var.bits_per_pixel; i--; dest1 += p->next_plane) {
+            dest = dest1;
+            cdat1 = cdat10;
+            cdat2 = cdat20;
+            cdat3 = cdat30;
+            cdat4 = cdat40;
+            for (rows = p->fontheight; rows--; dest += p->next_line) {
+               d = *cdat1++<<24 | *cdat2++<<16 | *cdat3++<<8 | *cdat4++;
+               if (bg & 1)
+                  if (fg & 1)
+                     *(u_long *)dest = 0xffffffff;
+                  else
+                     *(u_long *)dest = ~d;
+               else
+                  if (fg & 1)
+                     *(u_long *)dest = d;
+                  else
+                     *(u_long *)dest = 0x00000000;
+            }
+            bg >>= 1;
+            fg >>= 1;
+         }
+         s += 4;
+         dest0 += 4;
+         x += 4;
+         count -= 3;
+      }
+}
+
+
+static void rev_char_plan(struct display *p, int x, int y)
+{
+   u_char *dest, *dest0;
+   u_int rows, i;
+   int mask;
+
+   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   mask = p->fgcol ^ p->bgcol;
+
+   /*
+    *    This should really obey the individual character's
+    *    background and foreground colors instead of simply
+    *    inverting.
+    */
+
+   for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
+      if (mask & 1) {
+         dest = dest0;
+         for (rows = p->fontheight; rows--; dest += p->next_line)
+            *dest = ~*dest;
+      }
+      mask >>= 1;
+   }
+}
+
+#endif /* CONFIG_FBCON_PLANES */
+
+
+/* ====================================================================== */
+
+#ifdef CONFIG_FBCON_2PLANE
+
+   /*
+    *    2 Planes (2-bytes interleave)
+    */
+
+/* Increment/decrement 2 plane addresses */
+
+#define	INC_2P(p)	do { if (!((long)(++(p)) & 1)) (p) += 2; } while(0)
+#define	DEC_2P(p)	do { if ((long)(--(p)) & 1) (p) -= 2; } while(0)
+
+/* Convert a standard 4 bit color to our 2 bit color assignment:
+ * If at least two RGB channels are active, the low bit is turned on;
+ * The intensity bit (b3) is shifted into b1.
+ */
+
+#define	COLOR_2P(c)	(((c & 7) >= 3 && (c & 7) != 4) | (c & 8) >> 2)
+
+
+static void bmove_2_plane(struct display *p, int sy, int sx, int dy, int dx,
+                          int height, int width)
+{
+	/* bmove() has to distinguish two major cases: If both, source and
+	 * destination, start at even addresses or both are at odd
+	 * addresses, just the first odd and last even column (if present)
+	 * require special treatment (memmove_col()). The rest between
+	 * then can be copied by normal operations, because all adjacent
+	 * bytes are affected and are to be stored in the same order.
+	 *   The pathological case is when the move should go from an odd
+	 * address to an even or vice versa. Since the bytes in the plane
+	 * words must be assembled in new order, it seems wisest to make
+	 * all movements by memmove_col().
+	 */
+
+    if (sx == 0 && dx == 0 && width == p->next_line/2) {
+		/* Special (but often used) case: Moving whole lines can be
+		 * done with memmove()
+		 */
+		mymemmove(p->screen_base + dy * p->next_line * p->fontheight,
+				   p->screen_base + sy * p->next_line * p->fontheight,
+				   p->next_line * height * p->fontheight);
+    } else {
+        int rows, cols;
+        u_char *src;
+        u_char *dst;
+        int bytes = p->next_line;
+        int linesize = bytes * p->fontheight;
+		       u_int colsize  = height * p->fontheight;
+		       u_int upwards  = (dy < sy) || (dy == sy && dx < sx);
+
+		if ((sx & 1) == (dx & 1)) {
+			/* odd->odd or even->even */
+
+			if (upwards) {
+
+				src = p->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
+
+				if (sx & 1) {
+					memmove_2p_col(dst, src, colsize, bytes);
+					src += 3;
+					dst += 3;
+					--width;
+				}
+
+				if (width > 1) {
+					for(rows = colsize; rows > 0; --rows) {
+						mymemmove(dst, src, (width>>1)*4);
+						src += bytes;
+						dst += bytes;
+					}
+				}
+
+				if (width & 1) {
+					src -= colsize * bytes;
+					dst -= colsize * bytes;
+					memmove_2p_col(dst + (width>>1)*4, src + (width>>1)*4,
+									colsize, bytes);
+				}
+			}
+			else {
+
+				if (!((sx+width-1) & 1)) {
+					src = p->screen_base + sy * linesize + ((sx+width-1)>>1)*4;
+					dst = p->screen_base + dy * linesize + ((dx+width-1)>>1)*4;
+					memmove_2p_col(dst, src, colsize, bytes);
+					--width;
+				}
+
+				src = p->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
+
+				if (width > 1) {
+					src += colsize * bytes + (sx & 1)*3;
+					dst += colsize * bytes + (sx & 1)*3;
+					for(rows = colsize; rows > 0; --rows) {
+						src -= bytes;
+						dst -= bytes;
+						mymemmove(dst, src, (width>>1)*4);
+					}
+				}
+
+				if (width & 1) {
+					memmove_2p_col(dst-3, src-3, colsize, bytes);
+				}
+
+			}
+		}
+		else {
+			/* odd->even or even->odd */
+
+			if (upwards) {
+				src = p->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
+				for(cols = width; cols > 0; --cols) {
+					memmove_2p_col(dst, src, colsize, bytes);
+					INC_2P(src);
+					INC_2P(dst);
+				}
+			}
+			else {
+				sx += width-1;
+				dx += width-1;
+				src = p->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
+				for(cols = width; cols > 0; --cols) {
+					memmove_2p_col(dst, src, colsize, bytes);
+					DEC_2P(src);
+					DEC_2P(dst);
+				}
+			}
+		}
+
+
+    }
+}
+
+
+static void clear_2_plane(struct vc_data *conp, struct display *p, int sy,
+                          int sx, int height, int width)
+{
+    ulong offset;
+    u_char *start;
+    int rows;
+    int bytes = p->next_line;
+    int lines = height * p->fontheight;
+    ulong  size;
+	u_long          cval;
+	u_short			pcval;
+
+    cval = expand2l (COLOR_2P (attr_bgcol_ec(p,conp)));
+
+    if (sx == 0 && width == bytes/2) {
+
+        offset = sy * bytes * p->fontheight;
+        size   = lines * bytes;
+		memset_even_2p(p->screen_base+offset, size, cval);
+
+    } else {
+
+        offset = (sy * bytes * p->fontheight) + (sx>>1)*4 + (sx & 1);
+		start = p->screen_base + offset;
+		pcval = expand2w(COLOR_2P(attr_bgcol_ec(p,conp)));
+
+		/* Clears are split if the region starts at an odd column or
+		 * end at an even column. These extra columns are spread
+		 * across the interleaved planes. All in between can be
+		 * cleared by normal mymemclear_small(), because both bytes of
+		 * the single plane words are affected.
+		 */
+
+		if (sx & 1) {
+			memclear_2p_col(start, lines, pcval, bytes);
+			start += 3;
+			width--;
+		}
+
+		if (width & 1) {
+			memclear_2p_col(start + (width>>1)*4, lines, pcval, bytes);
+			width--;
+		}
+
+		if (width) {
+			for(rows = lines; rows-- ; start += bytes)
+				memset_even_2p(start, width*2, cval);
+		}
+    }
+}
+
+
+static void putc_2_plane(struct vc_data *conp, struct display *p, int c, int y,
+                         int x)
+{
+   u_char   *dest;
+    u_char   *cdat;
+    int rows;
+    int bytes = p->next_line;
+	ulong			  eorx, fgx, bgx, fdx;
+
+	c &= 0xff;
+
+    dest  = p->screen_base + y * p->fontheight * bytes + (x>>1)*4 + (x & 1);
+    cdat  = p->fontdata + (c * p->fontheight);
+
+	fgx   = expand2w(COLOR_2P(attr_fgcol(p,conp)));
+	bgx   = expand2w(COLOR_2P(attr_bgcol(p,conp)));
+	eorx  = fgx ^ bgx;
+
+    for(rows = p->fontheight ; rows-- ; dest += bytes) {
+		fdx = dup2w(*cdat++);
+		__asm__ __volatile__ ("movepw %1,%0@(0)" : /* no outputs */
+							   : "a" (dest), "d" ((fdx & eorx) ^ bgx));
+	}
+}
+
+
+static void putcs_2_plane(struct vc_data *conp, struct display *p,
+                          const char *s, int count, int y, int x)
+{
+	u_char   *dest, *dest0;
+    u_char   *cdat, c;
+    int rows;
+    int bytes;
+	ulong			  eorx, fgx, bgx, fdx;
+
+    bytes = p->next_line;
+    dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*4 + (x & 1);
+	fgx   = expand2w(COLOR_2P(attr_fgcol(p,conp)));
+	bgx   = expand2w(COLOR_2P(attr_bgcol(p,conp)));
+	eorx  = fgx ^ bgx;
+
+	while (count--) {
+
+		c = *s++;
+		cdat  = p->fontdata + (c * p->fontheight);
+
+		for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+			fdx = dup2w(*cdat++);
+			__asm__ __volatile__ ("movepw %1,%0@(0)" : /* no outputs */
+								   : "a" (dest), "d" ((fdx & eorx) ^ bgx));
+		}
+		INC_2P(dest0);
+	}
+}
+
+
+static void rev_char_2_plane(struct display *p, int x, int y)
+{
+   u_char *dest;
+   int j;
+   int bytes;
+
+   dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*4 + (x & 1);
+   j = p->fontheight;
+   bytes = p->next_line;
+   while (j--)
+     {
+      /* This should really obey the individual character's
+       * background and foreground colors instead of simply
+       * inverting.
+       */
+       dest[0] = ~dest[0];
+       dest[2] = ~dest[2];
+       dest += bytes;
+     }
+}
+#endif /* CONFIG_FBCON_2PLANE */
+
+
+/* ====================================================================== */
+
+#ifdef CONFIG_FBCON_4PLANE
+
+   /*
+    *    4 Planes (2-bytes interleave)
+    */
+
+/* Increment/decrement 4 plane addresses */
+
+#define	INC_4P(p)	do { if (!((long)(++(p)) & 1)) (p) += 6; } while(0)
+#define	DEC_4P(p)	do { if ((long)(--(p)) & 1) (p) -= 6; } while(0)
+
+
+static void bmove_4_plane(struct display *p, int sy, int sx, int dy, int dx,
+                          int height, int width)
+{
+	/* bmove() has to distinguish two major cases: If both, source and
+	 * destination, start at even addresses or both are at odd
+	 * addresses, just the first odd and last even column (if present)
+	 * require special treatment (memmove_col()). The rest between
+	 * then can be copied by normal operations, because all adjacent
+	 * bytes are affected and are to be stored in the same order.
+	 *   The pathological case is when the move should go from an odd
+	 * address to an even or vice versa. Since the bytes in the plane
+	 * words must be assembled in new order, it seems wisest to make
+	 * all movements by memmove_col().
+	 */
+
+    if (sx == 0 && dx == 0 && width == p->next_line/4) {
+		/* Special (but often used) case: Moving whole lines can be
+		 * done with memmove()
+		 */
+		mymemmove(p->screen_base + dy * p->next_line * p->fontheight,
+				   p->screen_base + sy * p->next_line * p->fontheight,
+				   p->next_line * height * p->fontheight);
+    } else {
+        int rows, cols;
+        u_char *src;
+        u_char *dst;
+        int bytes = p->next_line;
+        int linesize = bytes * p->fontheight;
+		       u_int colsize  = height * p->fontheight;
+		       u_int upwards  = (dy < sy) || (dy == sy && dx < sx);
+
+		if ((sx & 1) == (dx & 1)) {
+			/* odd->odd or even->even */
+
+			if (upwards) {
+
+				src = p->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
+
+				if (sx & 1) {
+					memmove_4p_col(dst, src, colsize, bytes);
+					src += 7;
+					dst += 7;
+					--width;
+				}
+
+				if (width > 1) {
+					for(rows = colsize; rows > 0; --rows) {
+						mymemmove(dst, src, (width>>1)*8);
+						src += bytes;
+						dst += bytes;
+					}
+				}
+
+				if (width & 1) {
+					src -= colsize * bytes;
+					dst -= colsize * bytes;
+					memmove_4p_col(dst + (width>>1)*8, src + (width>>1)*8,
+									colsize, bytes);
+				}
+			}
+			else {
+
+				if (!((sx+width-1) & 1)) {
+					src = p->screen_base + sy * linesize + ((sx+width-1)>>1)*8;
+					dst = p->screen_base + dy * linesize + ((dx+width-1)>>1)*8;
+					memmove_4p_col(dst, src, colsize, bytes);
+					--width;
+				}
+
+				src = p->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
+
+				if (width > 1) {
+					src += colsize * bytes + (sx & 1)*7;
+					dst += colsize * bytes + (sx & 1)*7;
+					for(rows = colsize; rows > 0; --rows) {
+						src -= bytes;
+						dst -= bytes;
+						mymemmove(dst, src, (width>>1)*8);
+					}
+				}
+
+				if (width & 1) {
+					memmove_4p_col(dst-7, src-7, colsize, bytes);
+				}
+
+			}
+		}
+		else {
+			/* odd->even or even->odd */
+
+			if (upwards) {
+				src = p->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
+				for(cols = width; cols > 0; --cols) {
+					memmove_4p_col(dst, src, colsize, bytes);
+					INC_4P(src);
+					INC_4P(dst);
+				}
+			}
+			else {
+				sx += width-1;
+				dx += width-1;
+				src = p->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
+				for(cols = width; cols > 0; --cols) {
+					memmove_4p_col(dst, src, colsize, bytes);
+					DEC_4P(src);
+					DEC_4P(dst);
+				}
+			}
+		}
+
+
+    }
+}
+
+
+static void clear_4_plane(struct vc_data *conp, struct display *p, int sy,
+                          int sx, int height, int width)
+{
+    ulong offset;
+    u_char *start;
+    int rows;
+    int bytes = p->next_line;
+    int lines = height * p->fontheight;
+    ulong  size;
+	u_long          cval1, cval2, pcval;
+
+	expand4dl(attr_bgcol_ec(p,conp), &cval1, &cval2);
+
+    if (sx == 0 && width == bytes/4) {
+
+	offset = sy * bytes * p->fontheight;
+        size   = lines * bytes;
+		memset_even_4p(p->screen_base+offset, size, cval1, cval2);
+
+    } else {
+
+        offset = (sy * bytes * p->fontheight) + (sx>>1)*8 + (sx & 1);
+		start = p->screen_base + offset;
+		pcval = expand4l(attr_bgcol_ec(p,conp));
+
+		/* Clears are split if the region starts at an odd column or
+		 * end at an even column. These extra columns are spread
+		 * across the interleaved planes. All in between can be
+		 * cleared by normal mymemclear_small(), because both bytes of
+		 * the single plane words are affected.
+		 */
+
+		if (sx & 1) {
+			memclear_4p_col(start, lines, pcval, bytes);
+			start += 7;
+			width--;
+		}
+
+		if (width & 1) {
+			memclear_4p_col(start + (width>>1)*8, lines, pcval, bytes);
+			width--;
+		}
+
+		if (width) {
+			for(rows = lines; rows-- ; start += bytes)
+				memset_even_4p(start, width*4, cval1, cval2);
+		}
+    }
+}
+
+
+static void putc_4_plane(struct vc_data *conp, struct display *p, int c, int y,
+                         int x)
+{
+	u_char   *dest;
+    u_char   *cdat;
+    int rows;
+    int bytes = p->next_line;
+	ulong			  eorx, fgx, bgx, fdx;
+
+	c &= 0xff;
+
+    dest  = p->screen_base + y * p->fontheight * bytes + (x>>1)*8 + (x & 1);
+    cdat  = p->fontdata + (c * p->fontheight);
+
+	fgx   = expand4l(attr_fgcol(p,conp));
+	bgx   = expand4l(attr_bgcol(p,conp));
+	eorx  = fgx ^ bgx;
+
+    for(rows = p->fontheight ; rows-- ; dest += bytes) {
+		fdx = dup4l(*cdat++);
+		__asm__ __volatile__ ("movepl %1,%0@(0)" : /* no outputs */
+							   : "a" (dest), "d" ((fdx & eorx) ^ bgx));
+	}
+}
+
+
+static void putcs_4_plane(struct vc_data *conp, struct display *p,
+                          const char *s, int count, int y, int x)
+{
+	u_char   *dest, *dest0;
+    u_char   *cdat, c;
+    int rows;
+    int bytes;
+	ulong			  eorx, fgx, bgx, fdx;
+
+    bytes = p->next_line;
+    dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*8 + (x & 1);
+	fgx   = expand4l(attr_fgcol(p,conp));
+	bgx   = expand4l(attr_bgcol(p,conp));
+	eorx  = fgx ^ bgx;
+
+	while (count--) {
+
+		/* I think, unrolling the loops like in the 1 plane case isn't
+		 * practicable here, because the body is much longer for 4
+		 * planes (mostly the dup4l()). I guess, unrolling this would
+		 * need more than 256 bytes and so exceed the instruction
+		 * cache :-(
+		 */
+
+		c = *s++;
+		cdat  = p->fontdata + (c * p->fontheight);
+
+		for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+			fdx = dup4l(*cdat++);
+			__asm__ __volatile__ ("movepl %1,%0@(0)" : /* no outputs */
+								   : "a" (dest), "d" ((fdx & eorx) ^ bgx));
+		}
+		INC_4P(dest0);
+	}
+}
+
+
+static void rev_char_4_plane(struct display *p, int x, int y)
+{
+   u_char *dest;
+   int j;
+   int bytes;
+
+   dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*8 + (x & 1);
+   j = p->fontheight;
+   bytes = p->next_line;
+
+   while (j--)
+     {
+      /* This should really obey the individual character's
+       * background and foreground colors instead of simply
+       * inverting.
+       */
+       dest[0] = ~dest[0];
+       dest[2] = ~dest[2];
+       dest[4] = ~dest[4];
+       dest[6] = ~dest[6];
+       dest += bytes;
+     }
+}
+#endif /* CONFIG_FBCON_4PLANE */
+
+
+/* ====================================================================== */
+
+#ifdef CONFIG_FBCON_8PLANE
+
+   /*
+    *    8 Planes (2-bytes interleave)
+    */
+
+/* In 8 plane mode, 256 colors would be possible, but only the first
+ * 16 are used by the console code (the upper 4 bits are
+ * background/unused). For that, the following functions mask off the
+ * higher 4 bits of each color.
+ */
+
+/* Increment/decrement 8 plane addresses */
+
+#define	INC_8P(p)	do { if (!((long)(++(p)) & 1)) (p) += 14; } while(0)
+#define	DEC_8P(p)	do { if ((long)(--(p)) & 1) (p) -= 14; } while(0)
+
+
+static void bmove_8_plane(struct display *p, int sy, int sx, int dy, int dx,
+                          int height, int width)
+{
+	/* bmove() has to distinguish two major cases: If both, source and
+	 * destination, start at even addresses or both are at odd
+	 * addresses, just the first odd and last even column (if present)
+	 * require special treatment (memmove_col()). The rest between
+	 * then can be copied by normal operations, because all adjacent
+	 * bytes are affected and are to be stored in the same order.
+	 *   The pathological case is when the move should go from an odd
+	 * address to an even or vice versa. Since the bytes in the plane
+	 * words must be assembled in new order, it seems wisest to make
+	 * all movements by memmove_col().
+	 */
+
+    if (sx == 0 && dx == 0 && width == p->next_line/8) {
+		/* Special (but often used) case: Moving whole lines can be
+		 * done with memmove()
+		 */
+      fast_memmove (p->screen_base + dy * p->next_line * p->fontheight,
+		    p->screen_base + sy * p->next_line * p->fontheight,
+		    p->next_line * height * p->fontheight);
+    } else {
+        int rows, cols;
+        u_char *src;
+        u_char *dst;
+        int bytes = p->next_line;
+        int linesize = bytes * p->fontheight;
+		       u_int colsize  = height * p->fontheight;
+		       u_int upwards  = (dy < sy) || (dy == sy && dx < sx);
+
+		if ((sx & 1) == (dx & 1)) {
+			/* odd->odd or even->even */
+
+			if (upwards) {
+
+				src = p->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
+
+				if (sx & 1) {
+					memmove_8p_col(dst, src, colsize, bytes);
+					src += 15;
+					dst += 15;
+					--width;
+				}
+
+				if (width > 1) {
+					for(rows = colsize; rows > 0; --rows) {
+						fast_memmove (dst, src, (width >> 1) * 16);
+						src += bytes;
+						dst += bytes;
+					}
+				}
+
+				if (width & 1) {
+					src -= colsize * bytes;
+					dst -= colsize * bytes;
+					memmove_8p_col(dst + (width>>1)*16, src + (width>>1)*16,
+									colsize, bytes);
+				}
+			}
+			else {
+
+				if (!((sx+width-1) & 1)) {
+					src = p->screen_base + sy * linesize + ((sx+width-1)>>1)*16;
+					dst = p->screen_base + dy * linesize + ((dx+width-1)>>1)*16;
+					memmove_8p_col(dst, src, colsize, bytes);
+					--width;
+				}
+
+				src = p->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
+
+				if (width > 1) {
+					src += colsize * bytes + (sx & 1)*15;
+					dst += colsize * bytes + (sx & 1)*15;
+					for(rows = colsize; rows > 0; --rows) {
+						src -= bytes;
+						dst -= bytes;
+						fast_memmove (dst, src, (width>>1)*16);
+					}
+				}
+
+				if (width & 1) {
+					memmove_8p_col(dst-15, src-15, colsize, bytes);
+				}
+
+			}
+		}
+		else {
+			/* odd->even or even->odd */
+
+			if (upwards) {
+				src = p->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
+				for(cols = width; cols > 0; --cols) {
+					memmove_8p_col(dst, src, colsize, bytes);
+					INC_8P(src);
+					INC_8P(dst);
+				}
+			}
+			else {
+				sx += width-1;
+				dx += width-1;
+				src = p->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
+				dst = p->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
+				for(cols = width; cols > 0; --cols) {
+					memmove_8p_col(dst, src, colsize, bytes);
+					DEC_8P(src);
+					DEC_8P(dst);
+				}
+			}
+		}
+
+
+    }
+}
+
+
+static void clear_8_plane(struct vc_data *conp, struct display *p, int sy,
+                          int sx, int height, int width)
+{
+    ulong offset;
+    u_char *start;
+    int rows;
+    int bytes = p->next_line;
+    int lines = height * p->fontheight;
+    ulong  size;
+	u_long          cval1, cval2, cval3, cval4, pcval1, pcval2;
+
+	expand8ql(attr_bgcol_ec(p,conp), cval1, cval2, cval3, cval4);
+
+    if (sx == 0 && width == bytes/8) {
+
+        offset = sy * bytes * p->fontheight;
+        size   = lines * bytes;
+		memset_even_8p(p->screen_base+offset, size, cval1, cval2, cval3, cval4);
+
+    } else {
+
+        offset = (sy * bytes * p->fontheight) + (sx>>1)*16 + (sx & 1);
+		start = p->screen_base + offset;
+		expand8dl(attr_bgcol_ec(p,conp), &pcval1, &pcval2);
+
+		/* Clears are split if the region starts at an odd column or
+		 * end at an even column. These extra columns are spread
+		 * across the interleaved planes. All in between can be
+		 * cleared by normal mymemclear_small(), because both bytes of
+		 * the single plane words are affected.
+		 */
+
+		if (sx & 1) {
+			memclear_8p_col(start, lines, pcval1, pcval2, bytes);
+			start += 7;
+			width--;
+		}
+
+		if (width & 1) {
+			memclear_8p_col(start + (width>>1)*16, lines, pcval1,
+							 pcval2, bytes);
+			width--;
+		}
+
+		if (width) {
+			for(rows = lines; rows-- ; start += bytes)
+				memset_even_8p(start, width*8, cval1, cval2, cval3, cval4);
+		}
+    }
+}
+
+
+static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int y,
+                         int x)
+{
+	u_char   *dest;
+    u_char   *cdat;
+    int rows;
+    int bytes = p->next_line;
+	ulong			  eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
+
+	c &= 0xff;
+
+    dest  = p->screen_base + y * p->fontheight * bytes + (x>>1)*16 + (x & 1);
+    cdat  = p->fontdata + (c * p->fontheight);
+
+	expand8dl(attr_fgcol(p,conp), &fgx1, &fgx2);
+	expand8dl(attr_bgcol(p,conp), &bgx1, &bgx2);
+	eorx1  = fgx1 ^ bgx1; eorx2  = fgx2 ^ bgx2;
+
+    for(rows = p->fontheight ; rows-- ; dest += bytes) {
+		fdx = dup4l(*cdat++);
+		__asm__ __volatile__
+			("movepl %1,%0@(0)\n\t"
+			  "movepl %2,%0@(8)"
+			  : /* no outputs */
+			  : "a" (dest), "d" ((fdx & eorx1) ^ bgx1),
+			    "d" ((fdx & eorx2) ^ bgx2)
+			);
+	}
+}
+
+
+static void putcs_8_plane(struct vc_data *conp, struct display *p,
+                          const char *s, int count, int y, int x)
+{
+	u_char   *dest, *dest0;
+    u_char   *cdat, c;
+    int rows;
+    int bytes;
+	ulong			  eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
+
+    bytes = p->next_line;
+    dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*16 + (x & 1);
+
+	expand8dl(attr_fgcol(p,conp), &fgx1, &fgx2);
+	expand8dl(attr_bgcol(p,conp), &bgx1, &bgx2);
+	eorx1  = fgx1 ^ bgx1; eorx2  = fgx2 ^ bgx2;
+
+	while (count--) {
+
+		/* I think, unrolling the loops like in the 1 plane case isn't
+		 * practicable here, because the body is much longer for 4
+		 * planes (mostly the dup4l()). I guess, unrolling this would
+		 * need more than 256 bytes and so exceed the instruction
+		 * cache :-(
+		 */
+
+		c = *s++;
+		cdat  = p->fontdata + (c * p->fontheight);
+
+		for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+			fdx = dup4l(*cdat++);
+			__asm__ __volatile__
+				("movepl %1,%0@(0)\n\t"
+				  "movepl %2,%0@(8)"
+				  : /* no outputs */
+				  : "a" (dest), "d" ((fdx & eorx1) ^ bgx1),
+				  "d" ((fdx & eorx2) ^ bgx2)
+				);
+		}
+		INC_8P(dest0);
+	}
+}
+
+
+static void rev_char_8_plane(struct display *p, int x, int y)
+{
+   u_char *dest;
+   int j;
+   int bytes;
+
+   dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*16 + (x & 1);
+   j = p->fontheight;
+   bytes = p->next_line;
+
+   while (j--)
+     {
+      /* This should really obey the individual character's
+       * background and foreground colors instead of simply
+       * inverting. For 8 plane mode, only the lower 4 bits of the
+       * color are inverted, because only that color registers have
+       * been set up.
+       */
+       dest[0] = ~dest[0];
+       dest[2] = ~dest[2];
+       dest[4] = ~dest[4];
+       dest[6] = ~dest[6];
+       dest += bytes;
+     }
+}
+#endif /* CONFIG_FBCON_8PLANE */
+
+
+/* ====================================================================== */
+
+#ifdef CONFIG_FBCON_8PACKED
+
+   /*
+    *    8 bpp Packed Pixels
+    */
+
+static u_long nibbletab_8_packed[]={
+0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
+0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
+0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
+0xffff0000,0xffff00ff,0xffffff00,0xffffffff};
+
+static void bmove_8_packed(struct display *p, int sy, int sx, int dy, int dx,
+                           int height, int width)
+{
+	int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
+	u_char *src,*dst;
+
+	if (sx == 0 && dx == 0 && width * 8 == bytes) {
+		mymemmove(p->screen_base + dy * linesize,
+			  p->screen_base + sy * linesize,
+			  height * linesize);
+	}
+	else {
+		if (dy < sy || (dy == sy && dx < sx)) {
+			src = p->screen_base + sy * linesize + sx * 8;
+			dst = p->screen_base + dy * linesize + dx * 8;
+			for (rows = height * p->fontheight ; rows-- ;) {
+				mymemmove(dst, src, width * 8);
+				src += bytes;
+				dst += bytes;
+			}
+		}
+		else {
+			src = p->screen_base + (sy+height) * linesize + sx * 8
+				- bytes;
+			dst = p->screen_base + (dy+height) * linesize + dx * 8
+				- bytes;
+			for (rows = height * p->fontheight ; rows-- ;) {
+				mymemmove(dst, src, width * 8);
+				src -= bytes;
+				dst -= bytes;
+			}
+		}
+	}
+}
+
+
+static void clear_8_packed(struct vc_data *conp, struct display *p, int sy,
+                           int sx, int height, int width)
+{
+	u_char *dest0,*dest;
+	int bytes=p->next_line,lines=height * p->fontheight, rows, i;
+	u_long bgx;
+
+	dest = p->screen_base + sy * p->fontheight * bytes + sx * 8;
+
+	bgx=attr_bgcol_ec(p,conp);
+	bgx |= (bgx << 8);
+	bgx |= (bgx << 16);
+
+	if (sx == 0 && width * 8 == bytes) {
+		for (i = 0 ; i < lines * width ; i++) {
+			((u_long *)dest)[0]=bgx;
+			((u_long *)dest)[1]=bgx;
+			dest+=8;
+		}
+	} else {
+		dest0=dest;
+		for (rows = lines; rows-- ; dest0 += bytes) {
+			dest=dest0;
+			for (i = 0 ; i < width ; i++) {
+				((u_long *)dest)[0]=bgx;
+				((u_long *)dest)[1]=bgx;
+				dest+=8;
+			}
+		}
+	}
+}
+
+
+static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int y,
+                          int x)
+{
+	u_char *dest,*cdat;
+	int bytes=p->next_line,rows;
+	ulong eorx,fgx,bgx;
+
+	c &= 0xff;
+
+	dest = p->screen_base + y * p->fontheight * bytes + x * 8;
+	cdat = p->fontdata + c * p->fontheight;
+
+	fgx=attr_fgcol(p,conp);
+	bgx=attr_bgcol(p,conp);
+	fgx |= (fgx << 8);
+	fgx |= (fgx << 16);
+	bgx |= (bgx << 8);
+	bgx |= (bgx << 16);
+	eorx = fgx ^ bgx;
+
+	for (rows = p->fontheight ; rows-- ; dest += bytes) {
+		((u_long *)dest)[0]=
+			(nibbletab_8_packed[*cdat >> 4] & eorx) ^ bgx;
+		((u_long *)dest)[1]=
+			(nibbletab_8_packed[*cdat++ & 0xf] & eorx) ^ bgx;
+	}
+}
+
+
+static void putcs_8_packed(struct vc_data *conp, struct display *p,
+                           const char *s, int count, int y, int x)
+{
+	u_char *cdat, c, *dest, *dest0;
+	int rows,bytes=p->next_line;
+	u_long eorx, fgx, bgx;
+
+	dest0 = p->screen_base + y * p->fontheight * bytes + x * 8;
+	fgx=attr_fgcol(p,conp);
+	bgx=attr_bgcol(p,conp);
+	fgx |= (fgx << 8);
+	fgx |= (fgx << 16);
+	bgx |= (bgx << 8);
+	bgx |= (bgx << 16);
+	eorx = fgx ^ bgx;
+	while (count--) {
+		c = *s++;
+		cdat = p->fontdata + c * p->fontheight;
+
+		for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+			((u_long *)dest)[0]=
+			(nibbletab_8_packed[*cdat >> 4] & eorx) ^ bgx;
+			((u_long *)dest)[1]=
+			(nibbletab_8_packed[*cdat++ & 0xf] & eorx) ^ bgx;
+		}
+		dest0+=8;
+	}
+}
+
+
+static void rev_char_8_packed(struct display *p, int x, int y)
+{
+	u_char *dest;
+	int bytes=p->next_line, rows;
+
+	dest = p->screen_base + y * p->fontheight * bytes + x * 8;
+	for (rows = p->fontheight ; rows-- ; dest += bytes) {
+		((u_long *)dest)[0] ^= 0x0f0f0f0f;
+		((u_long *)dest)[1] ^= 0x0f0f0f0f;
+	}
+}
+
+#endif /* CONFIG_FBCON_8PACKED */
+
+
+/* ====================================================================== */
+
+#ifdef CONFIG_FBCON_16PACKED
+
+   /*
+    *    16 bpp Packed Pixels
+    */
+
+u_short packed16_cmap[16];
+
+static u_long tab_16_packed[]={
+0x00000000,0x0000ffff,0xffff0000,0xffffffff};
+
+static void bmove_16_packed(struct display *p, int sy, int sx, int dy, int dx,
+                            int height, int width)
+{
+	int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
+	u_char *src,*dst;
+
+	if (sx == 0 && dx == 0 && width * 16 == bytes) {
+		mymemmove(p->screen_base + dy * linesize,
+			  p->screen_base + sy * linesize,
+			  height * linesize);
+	}
+	else {
+		if (dy < sy || (dy == sy && dx < sx)) {
+			src = p->screen_base + sy * linesize + sx * 16;
+			dst = p->screen_base + dy * linesize + dx * 16;
+			for (rows = height * p->fontheight ; rows-- ;) {
+				mymemmove(dst, src, width * 16);
+				src += bytes;
+				dst += bytes;
+			}
+		}
+		else {
+			src = p->screen_base + (sy+height) * linesize + sx * 16
+				- bytes;
+			dst = p->screen_base + (dy+height) * linesize + dx * 16
+				- bytes;
+			for (rows = height * p->fontheight ; rows-- ;) {
+				mymemmove(dst, src, width * 16);
+				src -= bytes;
+				dst -= bytes;
+			}
+		}
+	}
+}
+
+
+static void clear_16_packed(struct vc_data *conp, struct display *p, int sy,
+                            int sx, int height, int width)
+{
+	u_char *dest0,*dest;
+	int bytes=p->next_line,lines=height * p->fontheight, rows, i;
+	u_long bgx;
+
+	dest = p->screen_base + sy * p->fontheight * bytes + sx * 16;
+
+	bgx = attr_bgcol_ec(p,conp);
+	bgx = packed16_cmap[bgx];
+	bgx |= (bgx << 16);
+
+	if (sx == 0 && width * 16 == bytes) {
+		for (i = 0 ; i < lines * width ; i++) {
+			((u_long *)dest)[0]=bgx;
+			((u_long *)dest)[1]=bgx;
+			((u_long *)dest)[2]=bgx;
+			((u_long *)dest)[3]=bgx;
+			dest+=16;
+		}
+	} else {
+		dest0=dest;
+		for (rows = lines; rows-- ; dest0 += bytes) {
+			dest=dest0;
+			for (i = 0 ; i < width ; i++) {
+				((u_long *)dest)[0]=bgx;
+				((u_long *)dest)[1]=bgx;
+				((u_long *)dest)[2]=bgx;
+				((u_long *)dest)[3]=bgx;
+				dest+=16;
+			}
+		}
+	}
+}
+
+
+static void putc_16_packed(struct vc_data *conp, struct display *p, int c,
+                           int y, int x)
+{
+	u_char *dest,*cdat;
+	int bytes=p->next_line,rows;
+	ulong eorx,fgx,bgx;
+
+	c &= 0xff;
+
+	dest = p->screen_base + y * p->fontheight * bytes + x * 16;
+	cdat = p->fontdata + c * p->fontheight;
+
+	fgx = attr_fgcol(p,conp);
+	fgx = packed16_cmap[fgx];
+	bgx = attr_bgcol(p,conp);
+	bgx = packed16_cmap[bgx];
+	fgx |= (fgx << 16);
+	bgx |= (bgx << 16);
+	eorx = fgx ^ bgx;
+
+	for (rows = p->fontheight ; rows-- ; dest += bytes) {
+		((u_long *)dest)[0]=
+			(tab_16_packed[*cdat >> 6] & eorx) ^ bgx;
+		((u_long *)dest)[1]=
+			(tab_16_packed[*cdat >> 4 & 0x3] & eorx) ^ bgx;
+		((u_long *)dest)[2]=
+			(tab_16_packed[*cdat >> 2 & 0x3] & eorx) ^ bgx;
+		((u_long *)dest)[3]=
+			(tab_16_packed[*cdat++ & 0x3] & eorx) ^ bgx;
+	}
+}
+
+
+/* TODO */
+static void putcs_16_packed(struct vc_data *conp, struct display *p,
+                            const char *s, int count, int y, int x)
+{
+	u_char *cdat, c, *dest, *dest0;
+	int rows,bytes=p->next_line;
+	u_long eorx, fgx, bgx;
+
+	dest0 = p->screen_base + y * p->fontheight * bytes + x * 16;
+	fgx = attr_fgcol(p,conp);
+	fgx = packed16_cmap[fgx];
+	bgx = attr_bgcol(p,conp);
+	bgx = packed16_cmap[bgx];
+	fgx |= (fgx << 16);
+	bgx |= (bgx << 16);
+	eorx = fgx ^ bgx;
+	while (count--) {
+		c = *s++;
+		cdat = p->fontdata + c * p->fontheight;
+
+		for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+			((u_long *)dest)[0]=
+				(tab_16_packed[*cdat >> 6] & eorx) ^ bgx;
+			((u_long *)dest)[1]=
+				(tab_16_packed[*cdat >> 4 & 0x3] & eorx) ^ bgx;
+			((u_long *)dest)[2]=
+				(tab_16_packed[*cdat >> 2 & 0x3] & eorx) ^ bgx;
+			((u_long *)dest)[3]=
+				(tab_16_packed[*cdat++ & 0x3] & eorx) ^ bgx;
+		}
+		dest0+=16;
+	}
+}
+
+
+static void rev_char_16_packed(struct display *p, int x, int y)
+{
+	u_char *dest;
+	int bytes=p->next_line, rows;
+
+	dest = p->screen_base + y * p->fontheight * bytes + x * 16;
+	for (rows = p->fontheight ; rows-- ; dest += bytes) {
+		((u_long *)dest)[0] ^= 0xffffffff;
+		((u_long *)dest)[1] ^= 0xffffffff;
+		((u_long *)dest)[2] ^= 0xffffffff;
+		((u_long *)dest)[3] ^= 0xffffffff;
+	}
+}
+
+#endif /* CONFIG_FBCON_16PACKED */
+
+
+/* ====================================================================== */
+
+#ifdef CONFIG_FBCON_CYBER
+
+   /*
+    *    Cybervision (accelerated)
+    */
+
+static void bmove_cyber(struct display *p, int sy, int sx, int dy, int dx,
+                        int height, int width)
+{
+	sx *= 8; dx *= 8; width *= 8;
+	Cyber_BitBLT((u_short)sx, (u_short)(sy*p->fontheight), (u_short)dx,
+                (u_short)(dy*p->fontheight), (u_short)width,
+                (u_short)(height*p->fontheight), (u_short)S3_NEW);
+}
+
+
+static void clear_cyber(struct vc_data *conp, struct display *p, int sy, int sx,
+                        int height, int width)
+{
+   u_char bg;
+        
+	sx *= 8; width *= 8;
+	bg = attr_bgcol_ec(p,conp);
+   Cyber_RectFill((u_short)sx, (u_short)(sy*p->fontheight), (u_short)width,
+                  (u_short)(height*p->fontheight), (u_short)S3_NEW,
+                  (u_short)bg); 
+}
+
+
+static void putc_cyber(struct vc_data *conp, struct display *p, int c, int y,
+                       int x)
+{
+	u_char *dest, *cdat;
+	u_long tmp;
+	u_int rows, reverse, underline; 
+	u_char d;
+   u_char fg, bg;
+
+   c &= 0xff;
+
+	dest = p->screen_base+y*p->fontheight*p->next_line+8*x;
+	cdat = p->fontdata+(c*p->fontheight);
+   fg = disp->fgcol;
+   bg = disp->bgcol;
+	reverse = conp->vc_reverse;
+	underline = conp->vc_underline;
+
+   Cyber_WaitBlit();
+	for (rows = p->fontheight; rows--; dest += p->next_line) {
+  		d = *cdat++;
+
+		if (underline && !rows)
+			d = 0xff;
+		if (reverse)
+			d = ~d;
+
+      tmp =  ((d & 0x80) ? fg : bg) << 24;
+      tmp |= ((d & 0x40) ? fg : bg) << 16;
+      tmp |= ((d & 0x20) ? fg : bg) << 8;
+      tmp |= ((d & 0x10) ? fg : bg);
+      *((u_long*) dest) = tmp;
+      tmp =  ((d & 0x8) ? fg : bg) << 24;
+      tmp |= ((d & 0x4) ? fg : bg) << 16;
+      tmp |= ((d & 0x2) ? fg : bg) << 8;
+      tmp |= ((d & 0x1) ? fg : bg);
+      *((u_long*) dest + 1) = tmp;
+	}
+}
+
+
+static void putcs_cyber(struct vc_data *conp, struct display *p, const char *s,
+                        int count, int y, int x)
+{
+	u_char *dest, *dest0, *cdat;
+   u_long tmp;
+	u_int rows, reverse, underline;
+	u_char c, d;
+   u_char fg, bg;
+
+	dest0 = p->screen_base+y*p->fontheight*p->next_line+8*x;
+   fg = disp->fgcol;
+   bg = disp->bgcol;
+	reverse = conp->vc_reverse;
+	underline = conp->vc_underline;
+
+   Cyber_WaitBlit();
+	while (count--) {
+		c = *s++;
+		dest = dest0;
+      dest0 += 8;
+		cdat = p->fontdata+(c*p->fontheight);
+		for (rows = p->fontheight; rows--; dest += p->next_line) {
+ 			d = *cdat++;
+
+			if (underline && !rows)
+				d = 0xff;
+			if (reverse)
+				d = ~d;
+
+         tmp =  ((d & 0x80) ? fg : bg) << 24;
+         tmp |= ((d & 0x40) ? fg : bg) << 16;
+         tmp |= ((d & 0x20) ? fg : bg) << 8;
+         tmp |= ((d & 0x10) ? fg : bg);
+         *((u_long*) dest) = tmp;
+         tmp =  ((d & 0x8) ? fg : bg) << 24;
+         tmp |= ((d & 0x4) ? fg : bg) << 16;
+         tmp |= ((d & 0x2) ? fg : bg) << 8;
+         tmp |= ((d & 0x1) ? fg : bg);
+         *((u_long*) dest + 1) = tmp;
+		}
+	}
+}
+
+
+static void rev_char_cyber(struct display *p, int x, int y)
+{
+	u_char *dest;
+	u_int rows;
+   u_char fg, bg;
+
+   fg = disp->fgcol;
+   bg = disp->bgcol;
+
+	dest = p->screen_base+y*p->fontheight*p->next_line+8*x;
+   Cyber_WaitBlit();
+	for (rows = p->fontheight; rows--; dest += p->next_line) {
+		*dest = (*dest == fg) ? bg : fg;
+      *(dest+1) = (*(dest + 1) == fg) ? bg : fg;
+      *(dest+2) = (*(dest + 2) == fg) ? bg : fg;
+      *(dest+3) = (*(dest + 3) == fg) ? bg : fg;
+      *(dest+4) = (*(dest + 4) == fg) ? bg : fg;
+      *(dest+5) = (*(dest + 5) == fg) ? bg : fg;
+      *(dest+6) = (*(dest + 6) == fg) ? bg : fg;
+      *(dest+7) = (*(dest + 7) == fg) ? bg : fg;
+	}
+}
+
+#endif /* CONFIG_FBCON_CYBER */
+
+
+/* ====================================================================== */
+
+   /*
+    *    The console `switch' structure for the frame buffer based console
+    */
+
+struct consw fb_con = {
+   fbcon_startup, fbcon_init, fbcon_deinit, fbcon_clear, fbcon_putc,
+   fbcon_putcs, fbcon_cursor, fbcon_scroll, fbcon_bmove, fbcon_switch,
+   fbcon_blank, fbcon_get_font, fbcon_set_font
+};
diff -urN linux-2.4.29/arch/m68knommu/console/font_8x16.c linux-2.4.29-uc1/arch/m68knommu/console/font_8x16.c
--- linux-2.4.29/arch/m68knommu/console/font_8x16.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/console/font_8x16.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,4625 @@
+/**********************************************/
+/*                                            */
+/*       Font file generated by cpi2fnt       */
+/*                                            */
+/**********************************************/
+
+#define FONTDATAMAX 4096
+
+char fontname_8x16[] = "VGA8x16";
+
+int  fontheight_8x16 = 16;
+int  fontwidth_8x16  = 8;
+
+unsigned char fontdata_8x16[FONTDATAMAX] = {
+
+	/* 0 0x00 '^@' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 1 0x01 '^A' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x81, /* 10000001 */
+	0xa5, /* 10100101 */
+	0x81, /* 10000001 */
+	0x81, /* 10000001 */
+	0xbd, /* 10111101 */
+	0x99, /* 10011001 */
+	0x81, /* 10000001 */
+	0x81, /* 10000001 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 2 0x02 '^B' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xff, /* 11111111 */
+	0xdb, /* 11011011 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xc3, /* 11000011 */
+	0xe7, /* 11100111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 3 0x03 '^C' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 4 0x04 '^D' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 5 0x05 '^E' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0xe7, /* 11100111 */
+	0xe7, /* 11100111 */
+	0xe7, /* 11100111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 6 0x06 '^F' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 7 0x07 '^G' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 8 0x08 '^H' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xe7, /* 11100111 */
+	0xc3, /* 11000011 */
+	0xc3, /* 11000011 */
+	0xe7, /* 11100111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 9 0x09 '^I' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x42, /* 01000010 */
+	0x42, /* 01000010 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 10 0x0a '^J' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xc3, /* 11000011 */
+	0x99, /* 10011001 */
+	0xbd, /* 10111101 */
+	0xbd, /* 10111101 */
+	0x99, /* 10011001 */
+	0xc3, /* 11000011 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 11 0x0b '^K' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1e, /* 00011110 */
+	0x0e, /* 00001110 */
+	0x1a, /* 00011010 */
+	0x32, /* 00110010 */
+	0x78, /* 01111000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 12 0x0c '^L' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 13 0x0d '^M' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3f, /* 00111111 */
+	0x33, /* 00110011 */
+	0x3f, /* 00111111 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x70, /* 01110000 */
+	0xf0, /* 11110000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 14 0x0e '^N' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7f, /* 01111111 */
+	0x63, /* 01100011 */
+	0x7f, /* 01111111 */
+	0x63, /* 01100011 */
+	0x63, /* 01100011 */
+	0x63, /* 01100011 */
+	0x63, /* 01100011 */
+	0x67, /* 01100111 */
+	0xe7, /* 11100111 */
+	0xe6, /* 11100110 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 15 0x0f '^O' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xdb, /* 11011011 */
+	0x3c, /* 00111100 */
+	0xe7, /* 11100111 */
+	0x3c, /* 00111100 */
+	0xdb, /* 11011011 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 16 0x10 '^P' */
+	0x00, /* 00000000 */
+	0x80, /* 10000000 */
+	0xc0, /* 11000000 */
+	0xe0, /* 11100000 */
+	0xf0, /* 11110000 */
+	0xf8, /* 11111000 */
+	0xfe, /* 11111110 */
+	0xf8, /* 11111000 */
+	0xf0, /* 11110000 */
+	0xe0, /* 11100000 */
+	0xc0, /* 11000000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 17 0x11 '^Q' */
+	0x00, /* 00000000 */
+	0x02, /* 00000010 */
+	0x06, /* 00000110 */
+	0x0e, /* 00001110 */
+	0x1e, /* 00011110 */
+	0x3e, /* 00111110 */
+	0xfe, /* 11111110 */
+	0x3e, /* 00111110 */
+	0x1e, /* 00011110 */
+	0x0e, /* 00001110 */
+	0x06, /* 00000110 */
+	0x02, /* 00000010 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 18 0x12 '^R' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 19 0x13 '^S' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 20 0x14 '^T' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7f, /* 01111111 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0x7b, /* 01111011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 21 0x15 '^U' */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x60, /* 01100000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x0c, /* 00001100 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 22 0x16 '^V' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 23 0x17 '^W' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 24 0x18 '^X' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 25 0x19 '^Y' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 26 0x1a '^Z' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0xfe, /* 11111110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 27 0x1b '^[' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xfe, /* 11111110 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 28 0x1c '^\' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 29 0x1d '^]' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x28, /* 00101000 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x28, /* 00101000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 30 0x1e '^^' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0x7c, /* 01111100 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 31 0x1f '^_' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 32 0x20 ' ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 33 0x21 '!' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 34 0x22 '"' */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x24, /* 00100100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 35 0x23 '#' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 36 0x24 '$' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc2, /* 11000010 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x86, /* 10000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 37 0x25 '%' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc2, /* 11000010 */
+	0xc6, /* 11000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc6, /* 11000110 */
+	0x86, /* 10000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 38 0x26 '&' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 39 0x27 ''' */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 40 0x28 '(' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 41 0x29 ')' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 42 0x2a '*' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0xff, /* 11111111 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 43 0x2b '+' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 44 0x2c ',' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 45 0x2d '-' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 46 0x2e '.' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 47 0x2f '/' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x02, /* 00000010 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 48 0x30 '0' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 49 0x31 '1' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x38, /* 00111000 */
+	0x78, /* 01111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 50 0x32 '2' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 51 0x33 '3' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x3c, /* 00111100 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 52 0x34 '4' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0c, /* 00001100 */
+	0x1c, /* 00011100 */
+	0x3c, /* 00111100 */
+	0x6c, /* 01101100 */
+	0xcc, /* 11001100 */
+	0xfe, /* 11111110 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x1e, /* 00011110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 53 0x35 '5' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xfc, /* 11111100 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 54 0x36 '6' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xfc, /* 11111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 55 0x37 '7' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 56 0x38 '8' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 57 0x39 '9' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 58 0x3a ':' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 59 0x3b ';' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 60 0x3c '<' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 61 0x3d '=' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 62 0x3e '>' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 63 0x3f '?' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 64 0x40 '@' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xde, /* 11011110 */
+	0xde, /* 11011110 */
+	0xde, /* 11011110 */
+	0xdc, /* 11011100 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 65 0x41 'A' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 66 0x42 'B' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xfc, /* 11111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 67 0x43 'C' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0xc2, /* 11000010 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc2, /* 11000010 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 68 0x44 'D' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 69 0x45 'E' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x66, /* 01100110 */
+	0x62, /* 01100010 */
+	0x68, /* 01101000 */
+	0x78, /* 01111000 */
+	0x68, /* 01101000 */
+	0x60, /* 01100000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 70 0x46 'F' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x66, /* 01100110 */
+	0x62, /* 01100010 */
+	0x68, /* 01101000 */
+	0x78, /* 01111000 */
+	0x68, /* 01101000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 71 0x47 'G' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0xc2, /* 11000010 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xde, /* 11011110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x66, /* 01100110 */
+	0x3a, /* 00111010 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 72 0x48 'H' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 73 0x49 'I' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 74 0x4a 'J' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1e, /* 00011110 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 75 0x4b 'K' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xe6, /* 11100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x78, /* 01111000 */
+	0x78, /* 01111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 76 0x4c 'L' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf0, /* 11110000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 77 0x4d 'M' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xee, /* 11101110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xd6, /* 11010110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 78 0x4e 'N' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xe6, /* 11100110 */
+	0xf6, /* 11110110 */
+	0xfe, /* 11111110 */
+	0xde, /* 11011110 */
+	0xce, /* 11001110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 79 0x4f 'O' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 80 0x50 'P' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 81 0x51 'Q' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xde, /* 11011110 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0x0e, /* 00001110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 82 0x52 'R' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 83 0x53 'S' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x60, /* 01100000 */
+	0x38, /* 00111000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 84 0x54 'T' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x5a, /* 01011010 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 85 0x55 'U' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 86 0x56 'V' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 87 0x57 'W' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xfe, /* 11111110 */
+	0xee, /* 11101110 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 88 0x58 'X' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 89 0x59 'Y' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 90 0x5a 'Z' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x86, /* 10000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc2, /* 11000010 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 91 0x5b '[' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 92 0x5c '\' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x80, /* 10000000 */
+	0xc0, /* 11000000 */
+	0xe0, /* 11100000 */
+	0x70, /* 01110000 */
+	0x38, /* 00111000 */
+	0x1c, /* 00011100 */
+	0x0e, /* 00001110 */
+	0x06, /* 00000110 */
+	0x02, /* 00000010 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 93 0x5d ']' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 94 0x5e '^' */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 95 0x5f '_' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 96 0x60 '`' */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 97 0x61 'a' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 98 0x62 'b' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x78, /* 01111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 99 0x63 'c' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 100 0x64 'd' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1c, /* 00011100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x3c, /* 00111100 */
+	0x6c, /* 01101100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 101 0x65 'e' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 102 0x66 'f' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1c, /* 00011100 */
+	0x36, /* 00110110 */
+	0x32, /* 00110010 */
+	0x30, /* 00110000 */
+	0x78, /* 01111000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 103 0x67 'g' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0xcc, /* 11001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	/* 104 0x68 'h' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x6c, /* 01101100 */
+	0x76, /* 01110110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 105 0x69 'i' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 106 0x6a 'j' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x0e, /* 00001110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 107 0x6b 'k' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x78, /* 01111000 */
+	0x78, /* 01111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 108 0x6c 'l' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 109 0x6d 'm' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xec, /* 11101100 */
+	0xfe, /* 11111110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 110 0x6e 'n' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 111 0x6f 'o' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 112 0x70 'p' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+
+	/* 113 0x71 'q' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x1e, /* 00011110 */
+	0x00, /* 00000000 */
+
+	/* 114 0x72 'r' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x76, /* 01110110 */
+	0x66, /* 01100110 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 115 0x73 's' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x60, /* 01100000 */
+	0x38, /* 00111000 */
+	0x0c, /* 00001100 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 116 0x74 't' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0xfc, /* 11111100 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x36, /* 00110110 */
+	0x1c, /* 00011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 117 0x75 'u' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 118 0x76 'v' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 119 0x77 'w' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 120 0x78 'x' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x38, /* 00111000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 121 0x79 'y' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+
+	/* 122 0x7a 'z' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xcc, /* 11001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 123 0x7b '{' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0e, /* 00001110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x0e, /* 00001110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 124 0x7c '|' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 125 0x7d '}' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x70, /* 01110000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x0e, /* 00001110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 126 0x7e '~' */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 127 0x7f '' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 128 0x80 '€' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0xc2, /* 11000010 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc2, /* 11000010 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 129 0x81 '�' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 130 0x82 '‚' */
+	0x00, /* 00000000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 131 0x83 'ƒ' */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 132 0x84 '„' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 133 0x85 '…' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 134 0x86 '†' */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 135 0x87 '‡' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 136 0x88 'ˆ' */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 137 0x89 '‰' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 138 0x8a 'Š' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 139 0x8b '‹' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 140 0x8c 'Œ' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 141 0x8d '�' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 142 0x8e 'Ž' */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 143 0x8f '�' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 144 0x90 '�' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x66, /* 01100110 */
+	0x62, /* 01100010 */
+	0x68, /* 01101000 */
+	0x78, /* 01111000 */
+	0x68, /* 01101000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 145 0x91 '‘' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xec, /* 11101100 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x7e, /* 01111110 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0x6e, /* 01101110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 146 0x92 '’' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3e, /* 00111110 */
+	0x6c, /* 01101100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xfe, /* 11111110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xce, /* 11001110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 147 0x93 '“' */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 148 0x94 '”' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 149 0x95 '•' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 150 0x96 '–' */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x78, /* 01111000 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 151 0x97 '—' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 152 0x98 '˜' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	/* 153 0x99 '™' */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 154 0x9a 'š' */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 155 0x9b '›' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 156 0x9c 'œ' */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x64, /* 01100100 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xe6, /* 11100110 */
+	0xfc, /* 11111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 157 0x9d '�' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 158 0x9e 'ž' */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xf8, /* 11111000 */
+	0xc4, /* 11000100 */
+	0xcc, /* 11001100 */
+	0xde, /* 11011110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 159 0x9f 'Ÿ' */
+	0x00, /* 00000000 */
+	0x0e, /* 00001110 */
+	0x1b, /* 00011011 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 160 0xa0 ' ' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 161 0xa1 '¡' */
+	0x00, /* 00000000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 162 0xa2 '¢' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 163 0xa3 '£' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 164 0xa4 '¤' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 165 0xa5 '¥' */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xe6, /* 11100110 */
+	0xf6, /* 11110110 */
+	0xfe, /* 11111110 */
+	0xde, /* 11011110 */
+	0xce, /* 11001110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 166 0xa6 '¦' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x3e, /* 00111110 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 167 0xa7 '§' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 168 0xa8 '¨' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 169 0xa9 '©' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 170 0xaa 'ª' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 171 0xab '«' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0xe0, /* 11100000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xdc, /* 11011100 */
+	0x86, /* 10000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x3e, /* 00111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 172 0xac '¬' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0xe0, /* 11100000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x66, /* 01100110 */
+	0xce, /* 11001110 */
+	0x9a, /* 10011010 */
+	0x3f, /* 00111111 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 173 0xad '­' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 174 0xae '®' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x36, /* 00110110 */
+	0x6c, /* 01101100 */
+	0xd8, /* 11011000 */
+	0x6c, /* 01101100 */
+	0x36, /* 00110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 175 0xaf '¯' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xd8, /* 11011000 */
+	0x6c, /* 01101100 */
+	0x36, /* 00110110 */
+	0x6c, /* 01101100 */
+	0xd8, /* 11011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 176 0xb0 '°' */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+
+	/* 177 0xb1 '±' */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+
+	/* 178 0xb2 '²' */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+
+	/* 179 0xb3 '³' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 180 0xb4 '´' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 181 0xb5 'µ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 182 0xb6 '¶' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 183 0xb7 '·' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 184 0xb8 '¸' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 185 0xb9 '¹' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x06, /* 00000110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 186 0xba 'º' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 187 0xbb '»' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x06, /* 00000110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 188 0xbc '¼' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x06, /* 00000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 189 0xbd '½' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 190 0xbe '¾' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 191 0xbf '¿' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 192 0xc0 'À' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 193 0xc1 'Á' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 194 0xc2 'Â' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 195 0xc3 'Ã' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 196 0xc4 'Ä' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 197 0xc5 'Å' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 198 0xc6 'Æ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 199 0xc7 'Ç' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 200 0xc8 'È' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x30, /* 00110000 */
+	0x3f, /* 00111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 201 0xc9 'É' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3f, /* 00111111 */
+	0x30, /* 00110000 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 202 0xca 'Ê' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf7, /* 11110111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 203 0xcb 'Ë' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xf7, /* 11110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 204 0xcc 'Ì' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x30, /* 00110000 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 205 0xcd 'Í' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 206 0xce 'Î' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf7, /* 11110111 */
+	0x00, /* 00000000 */
+	0xf7, /* 11110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 207 0xcf 'Ï' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 208 0xd0 'Ð' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 209 0xd1 'Ñ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 210 0xd2 'Ò' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 211 0xd3 'Ó' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x3f, /* 00111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 212 0xd4 'Ô' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 213 0xd5 'Õ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 214 0xd6 'Ö' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3f, /* 00111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 215 0xd7 '×' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xff, /* 11111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 216 0xd8 'Ø' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 217 0xd9 'Ù' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 218 0xda 'Ú' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 219 0xdb 'Û' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 220 0xdc 'Ü' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 221 0xdd 'Ý' */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+
+	/* 222 0xde 'Þ' */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+
+	/* 223 0xdf 'ß' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 224 0xe0 'à' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xdc, /* 11011100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 225 0xe1 'á' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xd8, /* 11011000 */
+	0xcc, /* 11001100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 226 0xe2 'â' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 227 0xe3 'ã' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 228 0xe4 'ä' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 229 0xe5 'å' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 230 0xe6 'æ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+
+	/* 231 0xe7 'ç' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 232 0xe8 'è' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 233 0xe9 'é' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 234 0xea 'ê' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0xee, /* 11101110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 235 0xeb 'ë' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1e, /* 00011110 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x3e, /* 00111110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 236 0xec 'ì' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 237 0xed 'í' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x03, /* 00000011 */
+	0x06, /* 00000110 */
+	0x7e, /* 01111110 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0xf3, /* 11110011 */
+	0x7e, /* 01111110 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 238 0xee 'î' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1c, /* 00011100 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x1c, /* 00011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 239 0xef 'ï' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 240 0xf0 'ð' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 241 0xf1 'ñ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 242 0xf2 'ò' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 243 0xf3 'ó' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 244 0xf4 'ô' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0e, /* 00001110 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 245 0xf5 'õ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 246 0xf6 'ö' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 247 0xf7 '÷' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 248 0xf8 'ø' */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 249 0xf9 'ù' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 250 0xfa 'ú' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 251 0xfb 'û' */
+	0x00, /* 00000000 */
+	0x0f, /* 00001111 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0xec, /* 11101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x3c, /* 00111100 */
+	0x1c, /* 00011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 252 0xfc 'ü' */
+	0x00, /* 00000000 */
+	0x6c, /* 01101100 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 253 0xfd 'ý' */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x32, /* 00110010 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 254 0xfe 'þ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 255 0xff 'ÿ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+};
+
diff -urN linux-2.4.29/arch/m68knommu/console/font_8x8.c linux-2.4.29-uc1/arch/m68knommu/console/font_8x8.c
--- linux-2.4.29/arch/m68knommu/console/font_8x8.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/console/font_8x8.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,2577 @@
+/**********************************************/
+/*                                            */
+/*       Font file generated by cpi2fnt       */
+/*                                            */
+/**********************************************/
+
+#define FONTDATAMAX 2048
+
+char fontname_8x8[] = "VGA8x8";
+
+int  fontheight_8x8 = 8;
+int  fontwidth_8x8  = 8;
+
+unsigned char fontdata_8x8[FONTDATAMAX] = {
+
+	/* 0 0x00 '^@' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 1 0x01 '^A' */
+	0x7e, /* 01111110 */
+	0x81, /* 10000001 */
+	0xa5, /* 10100101 */
+	0x81, /* 10000001 */
+	0xbd, /* 10111101 */
+	0x99, /* 10011001 */
+	0x81, /* 10000001 */
+	0x7e, /* 01111110 */
+
+	/* 2 0x02 '^B' */
+	0x7e, /* 01111110 */
+	0xff, /* 11111111 */
+	0xdb, /* 11011011 */
+	0xff, /* 11111111 */
+	0xc3, /* 11000011 */
+	0xe7, /* 11100111 */
+	0xff, /* 11111111 */
+	0x7e, /* 01111110 */
+
+	/* 3 0x03 '^C' */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+
+	/* 4 0x04 '^D' */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+
+	/* 5 0x05 '^E' */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xd6, /* 11010110 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+
+	/* 6 0x06 '^F' */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+
+	/* 7 0x07 '^G' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 8 0x08 '^H' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xe7, /* 11100111 */
+	0xc3, /* 11000011 */
+	0xc3, /* 11000011 */
+	0xe7, /* 11100111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 9 0x09 '^I' */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x42, /* 01000010 */
+	0x42, /* 01000010 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 10 0x0a '^J' */
+	0xff, /* 11111111 */
+	0xc3, /* 11000011 */
+	0x99, /* 10011001 */
+	0xbd, /* 10111101 */
+	0xbd, /* 10111101 */
+	0x99, /* 10011001 */
+	0xc3, /* 11000011 */
+	0xff, /* 11111111 */
+
+	/* 11 0x0b '^K' */
+	0x0f, /* 00001111 */
+	0x07, /* 00000111 */
+	0x0f, /* 00001111 */
+	0x7d, /* 01111101 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x78, /* 01111000 */
+
+	/* 12 0x0c '^L' */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+
+	/* 13 0x0d '^M' */
+	0x3f, /* 00111111 */
+	0x33, /* 00110011 */
+	0x3f, /* 00111111 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x70, /* 01110000 */
+	0xf0, /* 11110000 */
+	0xe0, /* 11100000 */
+
+	/* 14 0x0e '^N' */
+	0x7f, /* 01111111 */
+	0x63, /* 01100011 */
+	0x7f, /* 01111111 */
+	0x63, /* 01100011 */
+	0x63, /* 01100011 */
+	0x67, /* 01100111 */
+	0xe6, /* 11100110 */
+	0xc0, /* 11000000 */
+
+	/* 15 0x0f '^O' */
+	0x18, /* 00011000 */
+	0xdb, /* 11011011 */
+	0x3c, /* 00111100 */
+	0xe7, /* 11100111 */
+	0xe7, /* 11100111 */
+	0x3c, /* 00111100 */
+	0xdb, /* 11011011 */
+	0x18, /* 00011000 */
+
+	/* 16 0x10 '^P' */
+	0x80, /* 10000000 */
+	0xe0, /* 11100000 */
+	0xf8, /* 11111000 */
+	0xfe, /* 11111110 */
+	0xf8, /* 11111000 */
+	0xe0, /* 11100000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+
+	/* 17 0x11 '^Q' */
+	0x02, /* 00000010 */
+	0x0e, /* 00001110 */
+	0x3e, /* 00111110 */
+	0xfe, /* 11111110 */
+	0x3e, /* 00111110 */
+	0x0e, /* 00001110 */
+	0x02, /* 00000010 */
+	0x00, /* 00000000 */
+
+	/* 18 0x12 '^R' */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+
+	/* 19 0x13 '^S' */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+
+	/* 20 0x14 '^T' */
+	0x7f, /* 01111111 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0x7b, /* 01111011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x00, /* 00000000 */
+
+	/* 21 0x15 '^U' */
+	0x3e, /* 00111110 */
+	0x61, /* 01100001 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x86, /* 10000110 */
+	0x7c, /* 01111100 */
+
+	/* 22 0x16 '^V' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 23 0x17 '^W' */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+
+	/* 24 0x18 '^X' */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 25 0x19 '^Y' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 26 0x1a '^Z' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0xfe, /* 11111110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 27 0x1b '^[' */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xfe, /* 11111110 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 28 0x1c '^\' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 29 0x1d '^]' */
+	0x00, /* 00000000 */
+	0x24, /* 00100100 */
+	0x66, /* 01100110 */
+	0xff, /* 11111111 */
+	0x66, /* 01100110 */
+	0x24, /* 00100100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 30 0x1e '^^' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 31 0x1f '^_' */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 32 0x20 ' ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 33 0x21 '!' */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 34 0x22 '"' */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x24, /* 00100100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 35 0x23 '#' */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+
+	/* 36 0x24 '$' */
+	0x18, /* 00011000 */
+	0x3e, /* 00111110 */
+	0x60, /* 01100000 */
+	0x3c, /* 00111100 */
+	0x06, /* 00000110 */
+	0x7c, /* 01111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 37 0x25 '%' */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xcc, /* 11001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x66, /* 01100110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 38 0x26 '&' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 39 0x27 ''' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 40 0x28 '(' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+
+	/* 41 0x29 ')' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	/* 42 0x2a '*' */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0xff, /* 11111111 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 43 0x2b '+' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 44 0x2c ',' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+
+	/* 45 0x2d '-' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 46 0x2e '.' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 47 0x2f '/' */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+
+	/* 48 0x30 '0' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	/* 49 0x31 '1' */
+	0x18, /* 00011000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 50 0x32 '2' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x06, /* 00000110 */
+	0x1c, /* 00011100 */
+	0x30, /* 00110000 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 51 0x33 '3' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x06, /* 00000110 */
+	0x3c, /* 00111100 */
+	0x06, /* 00000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 52 0x34 '4' */
+	0x1c, /* 00011100 */
+	0x3c, /* 00111100 */
+	0x6c, /* 01101100 */
+	0xcc, /* 11001100 */
+	0xfe, /* 11111110 */
+	0x0c, /* 00001100 */
+	0x1e, /* 00011110 */
+	0x00, /* 00000000 */
+
+	/* 53 0x35 '5' */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xfc, /* 11111100 */
+	0x06, /* 00000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 54 0x36 '6' */
+	0x38, /* 00111000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0xfc, /* 11111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 55 0x37 '7' */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	/* 56 0x38 '8' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 57 0x39 '9' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	/* 58 0x3a ':' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 59 0x3b ';' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+
+	/* 60 0x3c '<' */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+
+	/* 61 0x3d '=' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 62 0x3e '>' */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+
+	/* 63 0x3f '?' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 64 0x40 '@' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xde, /* 11011110 */
+	0xde, /* 11011110 */
+	0xde, /* 11011110 */
+	0xc0, /* 11000000 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	/* 65 0x41 'A' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 66 0x42 'B' */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xfc, /* 11111100 */
+	0x00, /* 00000000 */
+
+	/* 67 0x43 'C' */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 68 0x44 'D' */
+	0xf8, /* 11111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+
+	/* 69 0x45 'E' */
+	0xfe, /* 11111110 */
+	0x62, /* 01100010 */
+	0x68, /* 01101000 */
+	0x78, /* 01111000 */
+	0x68, /* 01101000 */
+	0x62, /* 01100010 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 70 0x46 'F' */
+	0xfe, /* 11111110 */
+	0x62, /* 01100010 */
+	0x68, /* 01101000 */
+	0x78, /* 01111000 */
+	0x68, /* 01101000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+
+	/* 71 0x47 'G' */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xce, /* 11001110 */
+	0x66, /* 01100110 */
+	0x3a, /* 00111010 */
+	0x00, /* 00000000 */
+
+	/* 72 0x48 'H' */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 73 0x49 'I' */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 74 0x4a 'J' */
+	0x1e, /* 00011110 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	/* 75 0x4b 'K' */
+	0xe6, /* 11100110 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x78, /* 01111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+
+	/* 76 0x4c 'L' */
+	0xf0, /* 11110000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 77 0x4d 'M' */
+	0xc6, /* 11000110 */
+	0xee, /* 11101110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xd6, /* 11010110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 78 0x4e 'N' */
+	0xc6, /* 11000110 */
+	0xe6, /* 11100110 */
+	0xf6, /* 11110110 */
+	0xde, /* 11011110 */
+	0xce, /* 11001110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 79 0x4f 'O' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 80 0x50 'P' */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+
+	/* 81 0x51 'Q' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xce, /* 11001110 */
+	0x7c, /* 01111100 */
+	0x0e, /* 00001110 */
+
+	/* 82 0x52 'R' */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+
+	/* 83 0x53 'S' */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 84 0x54 'T' */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x5a, /* 01011010 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 85 0x55 'U' */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 86 0x56 'V' */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	/* 87 0x57 'W' */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+
+	/* 88 0x58 'X' */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 89 0x59 'Y' */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 90 0x5a 'Z' */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x8c, /* 10001100 */
+	0x18, /* 00011000 */
+	0x32, /* 00110010 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 91 0x5b '[' */
+	0x3c, /* 00111100 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 92 0x5c '\' */
+	0xc0, /* 11000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0x02, /* 00000010 */
+	0x00, /* 00000000 */
+
+	/* 93 0x5d ']' */
+	0x3c, /* 00111100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 94 0x5e '^' */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 95 0x5f '_' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+
+	/* 96 0x60 '`' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 97 0x61 'a' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 98 0x62 'b' */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x7c, /* 01111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+
+	/* 99 0x63 'c' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 100 0x64 'd' */
+	0x1c, /* 00011100 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 101 0x65 'e' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 102 0x66 'f' */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x60, /* 01100000 */
+	0xf8, /* 11111000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+
+	/* 103 0x67 'g' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0xf8, /* 11111000 */
+
+	/* 104 0x68 'h' */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x6c, /* 01101100 */
+	0x76, /* 01110110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+
+	/* 105 0x69 'i' */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 106 0x6a 'j' */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+
+	/* 107 0x6b 'k' */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x78, /* 01111000 */
+	0x6c, /* 01101100 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+
+	/* 108 0x6c 'l' */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 109 0x6d 'm' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xec, /* 11101100 */
+	0xfe, /* 11111110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0x00, /* 00000000 */
+
+	/* 110 0x6e 'n' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+
+	/* 111 0x6f 'o' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 112 0x70 'p' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+
+	/* 113 0x71 'q' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0x1e, /* 00011110 */
+
+	/* 114 0x72 'r' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x76, /* 01110110 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+
+	/* 115 0x73 's' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x06, /* 00000110 */
+	0xfc, /* 11111100 */
+	0x00, /* 00000000 */
+
+	/* 116 0x74 't' */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0xfc, /* 11111100 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x36, /* 00110110 */
+	0x1c, /* 00011100 */
+	0x00, /* 00000000 */
+
+	/* 117 0x75 'u' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 118 0x76 'v' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	/* 119 0x77 'w' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+
+	/* 120 0x78 'x' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 121 0x79 'y' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0xfc, /* 11111100 */
+
+	/* 122 0x7a 'z' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x4c, /* 01001100 */
+	0x18, /* 00011000 */
+	0x32, /* 00110010 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 123 0x7b '{' */
+	0x0e, /* 00001110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x0e, /* 00001110 */
+	0x00, /* 00000000 */
+
+	/* 124 0x7c '|' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 125 0x7d '}' */
+	0x70, /* 01110000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x0e, /* 00001110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	/* 126 0x7e '~' */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 127 0x7f '' */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 128 0x80 '€' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0x78, /* 01111000 */
+
+	/* 129 0x81 '�' */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 130 0x82 '‚' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 131 0x83 'ƒ' */
+	0x7c, /* 01111100 */
+	0x82, /* 10000010 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 132 0x84 '„' */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 133 0x85 '…' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 134 0x86 '†' */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 135 0x87 '‡' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x7e, /* 01111110 */
+	0x0c, /* 00001100 */
+	0x38, /* 00111000 */
+
+	/* 136 0x88 'ˆ' */
+	0x7c, /* 01111100 */
+	0x82, /* 10000010 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 137 0x89 '‰' */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 138 0x8a 'Š' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 139 0x8b '‹' */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 140 0x8c 'Œ' */
+	0x7c, /* 01111100 */
+	0x82, /* 10000010 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 141 0x8d '�' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 142 0x8e 'Ž' */
+	0xc6, /* 11000110 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 143 0x8f '�' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 144 0x90 '�' */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xf8, /* 11111000 */
+	0xc0, /* 11000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 145 0x91 '‘' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0xd8, /* 11011000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 146 0x92 '’' */
+	0x3e, /* 00111110 */
+	0x6c, /* 01101100 */
+	0xcc, /* 11001100 */
+	0xfe, /* 11111110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xce, /* 11001110 */
+	0x00, /* 00000000 */
+
+	/* 147 0x93 '“' */
+	0x7c, /* 01111100 */
+	0x82, /* 10000010 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 148 0x94 '”' */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 149 0x95 '•' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 150 0x96 '–' */
+	0x78, /* 01111000 */
+	0x84, /* 10000100 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 151 0x97 '—' */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 152 0x98 '˜' */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0xfc, /* 11111100 */
+
+	/* 153 0x99 '™' */
+	0xc6, /* 11000110 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	/* 154 0x9a 'š' */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 155 0x9b '›' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 156 0x9c 'œ' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x64, /* 01100100 */
+	0xf0, /* 11110000 */
+	0x60, /* 01100000 */
+	0x66, /* 01100110 */
+	0xfc, /* 11111100 */
+	0x00, /* 00000000 */
+
+	/* 157 0x9d '�' */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 158 0x9e 'ž' */
+	0xf8, /* 11111000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xfa, /* 11111010 */
+	0xc6, /* 11000110 */
+	0xcf, /* 11001111 */
+	0xc6, /* 11000110 */
+	0xc7, /* 11000111 */
+
+	/* 159 0x9f 'Ÿ' */
+	0x0e, /* 00001110 */
+	0x1b, /* 00011011 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	/* 160 0xa0 ' ' */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 161 0xa1 '¡' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 162 0xa2 '¢' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 163 0xa3 '£' */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 164 0xa4 '¤' */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+
+	/* 165 0xa5 '¥' */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0xe6, /* 11100110 */
+	0xf6, /* 11110110 */
+	0xde, /* 11011110 */
+	0xce, /* 11001110 */
+	0x00, /* 00000000 */
+
+	/* 166 0xa6 '¦' */
+	0x3c, /* 00111100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x3e, /* 00111110 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 167 0xa7 '§' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 168 0xa8 '¨' */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x63, /* 01100011 */
+	0x3e, /* 00111110 */
+	0x00, /* 00000000 */
+
+	/* 169 0xa9 '©' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 170 0xaa 'ª' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 171 0xab '«' */
+	0x63, /* 01100011 */
+	0xe6, /* 11100110 */
+	0x6c, /* 01101100 */
+	0x7e, /* 01111110 */
+	0x33, /* 00110011 */
+	0x66, /* 01100110 */
+	0xcc, /* 11001100 */
+	0x0f, /* 00001111 */
+
+	/* 172 0xac '¬' */
+	0x63, /* 01100011 */
+	0xe6, /* 11100110 */
+	0x6c, /* 01101100 */
+	0x7a, /* 01111010 */
+	0x36, /* 00110110 */
+	0x6a, /* 01101010 */
+	0xdf, /* 11011111 */
+	0x06, /* 00000110 */
+
+	/* 173 0xad '­' */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 174 0xae '®' */
+	0x00, /* 00000000 */
+	0x33, /* 00110011 */
+	0x66, /* 01100110 */
+	0xcc, /* 11001100 */
+	0x66, /* 01100110 */
+	0x33, /* 00110011 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 175 0xaf '¯' */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0x66, /* 01100110 */
+	0x33, /* 00110011 */
+	0x66, /* 01100110 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 176 0xb0 '°' */
+	0x22, /* 00100010 */
+	0x88, /* 10001000 */
+	0x22, /* 00100010 */
+	0x88, /* 10001000 */
+	0x22, /* 00100010 */
+	0x88, /* 10001000 */
+	0x22, /* 00100010 */
+	0x88, /* 10001000 */
+
+	/* 177 0xb1 '±' */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+
+	/* 178 0xb2 '²' */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+
+	/* 179 0xb3 '³' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 180 0xb4 '´' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 181 0xb5 'µ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 182 0xb6 '¶' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 183 0xb7 '·' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 184 0xb8 '¸' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 185 0xb9 '¹' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x06, /* 00000110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 186 0xba 'º' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 187 0xbb '»' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x06, /* 00000110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 188 0xbc '¼' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x06, /* 00000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 189 0xbd '½' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 190 0xbe '¾' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 191 0xbf '¿' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 192 0xc0 'À' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 193 0xc1 'Á' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 194 0xc2 'Â' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 195 0xc3 'Ã' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 196 0xc4 'Ä' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 197 0xc5 'Å' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 198 0xc6 'Æ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 199 0xc7 'Ç' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 200 0xc8 'È' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x30, /* 00110000 */
+	0x3f, /* 00111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 201 0xc9 'É' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3f, /* 00111111 */
+	0x30, /* 00110000 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 202 0xca 'Ê' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf7, /* 11110111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 203 0xcb 'Ë' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xf7, /* 11110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 204 0xcc 'Ì' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x30, /* 00110000 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 205 0xcd 'Í' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 206 0xce 'Î' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf7, /* 11110111 */
+	0x00, /* 00000000 */
+	0xf7, /* 11110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 207 0xcf 'Ï' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 208 0xd0 'Ð' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 209 0xd1 'Ñ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 210 0xd2 'Ò' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 211 0xd3 'Ó' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x3f, /* 00111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 212 0xd4 'Ô' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 213 0xd5 'Õ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 214 0xd6 'Ö' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3f, /* 00111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 215 0xd7 '×' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xff, /* 11111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 216 0xd8 'Ø' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 217 0xd9 'Ù' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 218 0xda 'Ú' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 219 0xdb 'Û' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 220 0xdc 'Ü' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 221 0xdd 'Ý' */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+
+	/* 222 0xde 'Þ' */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+
+	/* 223 0xdf 'ß' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 224 0xe0 'à' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0xc8, /* 11001000 */
+	0xdc, /* 11011100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 225 0xe1 'á' */
+	0x78, /* 01111000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xd8, /* 11011000 */
+	0xcc, /* 11001100 */
+	0xc6, /* 11000110 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+
+	/* 226 0xe2 'â' */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+
+	/* 227 0xe3 'ã' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+
+	/* 228 0xe4 'ä' */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 229 0xe5 'å' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	/* 230 0xe6 'æ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0xc0, /* 11000000 */
+
+	/* 231 0xe7 'ç' */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 232 0xe8 'è' */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+
+	/* 233 0xe9 'é' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	/* 234 0xea 'ê' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0xee, /* 11101110 */
+	0x00, /* 00000000 */
+
+	/* 235 0xeb 'ë' */
+	0x0e, /* 00001110 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x3e, /* 00111110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 236 0xec 'ì' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 237 0xed 'í' */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x7e, /* 01111110 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0x7e, /* 01111110 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+
+	/* 238 0xee 'î' */
+	0x1e, /* 00011110 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x7e, /* 01111110 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x1e, /* 00011110 */
+	0x00, /* 00000000 */
+
+	/* 239 0xef 'ï' */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 240 0xf0 'ð' */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 241 0xf1 'ñ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 242 0xf2 'ò' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 243 0xf3 'ó' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 244 0xf4 'ô' */
+	0x0e, /* 00001110 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 245 0xf5 'õ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+
+	/* 246 0xf6 'ö' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 247 0xf7 '÷' */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 248 0xf8 'ø' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 249 0xf9 'ù' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 250 0xfa 'ú' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 251 0xfb 'û' */
+	0x0f, /* 00001111 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0xec, /* 11101100 */
+	0x6c, /* 01101100 */
+	0x3c, /* 00111100 */
+	0x1c, /* 00011100 */
+
+	/* 252 0xfc 'ü' */
+	0x6c, /* 01101100 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 253 0xfd 'ý' */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 254 0xfe 'þ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 255 0xff 'ÿ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+};
+
diff -urN linux-2.4.29/arch/m68knommu/console/fonts.c linux-2.4.29-uc1/arch/m68knommu/console/fonts.c
--- linux-2.4.29/arch/m68knommu/console/fonts.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/console/fonts.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,112 @@
+
+/*
+ * arch/m68k/console/fonts.c -- `Soft' font definitions
+ *
+ *    Created 1995 by Geert Uytterhoeven
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <asm/font.h>
+
+
+   /*
+    *    External Font Definitions
+    */
+
+/* VGA8x8 */
+extern char fontname_8x8[];
+extern int fontwidth_8x8, fontheight_8x8;
+extern u_char fontdata_8x8[];
+
+/* VGA8x16 */
+extern char fontname_8x16[];
+extern int fontwidth_8x16, fontheight_8x16;
+extern u_char fontdata_8x16[];
+
+/* PEARL8x8 */
+extern char fontname_pearl8x8[];
+extern int fontwidth_pearl8x8, fontheight_pearl8x8;
+extern u_char fontdata_pearl8x8[];
+
+/* MINI4x6 */
+extern char fontname_mini4x6[];
+extern int fontwidth_mini4x6, fontheight_mini4x6;
+extern u_char fontdata_mini4x6[];
+
+
+   /*
+    *    Font Descriptor Array
+    */
+
+struct softfontdesc {
+   char *name;
+   int *width;
+   int *height;
+   u_char *data;
+};
+
+#define VGA8x8_IDX	0
+#define VGA8x16_IDX	1
+#define PEARL8x8_IDX	2
+#define MINI4x6_IDX	3
+
+static struct softfontdesc softfonts[] = {
+   { fontname_8x8, &fontwidth_8x8, &fontheight_8x8, fontdata_8x8 },
+   { fontname_8x16, &fontwidth_8x16, &fontheight_8x16, fontdata_8x16 },
+   { fontname_pearl8x8, &fontwidth_pearl8x8, &fontheight_pearl8x8,
+     fontdata_pearl8x8 },
+   { fontname_mini4x6, &fontwidth_mini4x6, &fontheight_mini4x6,
+     fontdata_mini4x6 },
+};
+
+static u_long numsoftfonts = sizeof(softfonts)/sizeof(*softfonts);
+
+
+   /*
+    *    Find a font with a specific name
+    */
+
+int findsoftfont(char *name, int *width, int *height, u_char *data[])
+{
+   int i;
+
+   for (i = 0; i < numsoftfonts; i++)
+      if (!strcmp(softfonts[i].name, name)) {
+         if (width)
+            *width = *softfonts[i].width;
+         if (height)
+            *height = *softfonts[i].height;
+         if (data)
+            *data = softfonts[i].data;
+			return(1);
+      }
+	return(0);
+}
+
+
+   /*
+    *    Get the default font for a specific screen size
+    */
+
+void getdefaultfont(int xres, int yres, char *name[], int *width, int *height,
+                    u_char *data[])
+{
+    int i;
+    
+    i = MINI4x6_IDX;
+
+    if (name)
+	*name = softfonts[i].name;
+    if (width)
+	*width = *softfonts[i].width;
+    if (height)
+	*height = *softfonts[i].height;
+    if (data)
+	*data = softfonts[i].data;
+}
diff -urN linux-2.4.29/arch/m68knommu/console/Makefile linux-2.4.29-uc1/arch/m68knommu/console/Makefile
--- linux-2.4.29/arch/m68knommu/console/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/console/Makefile	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,12 @@
+#
+# Makefile for Linux arch/m68k/console source directory
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+L_TARGET = console.a
+obj-y = 68328fb.o fbcon.o fonts.o font_8x16.o font_8x8.o pearl_8x8.o mini_4x6.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/console/mini_4x6.c linux-2.4.29-uc1/arch/m68knommu/console/mini_4x6.c
--- linux-2.4.29/arch/m68knommu/console/mini_4x6.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/console/mini_4x6.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,2149 @@
+
+/* Hand composed "Miniscule" 4x6 font, with binary data generated using Perl stub.
+ *
+ * Use 'perl -x mini_4x6.c < mini_4x6.c > new_version.c' to regenerate binary data.
+ *
+ * Created by Kenneth Albanowski. No rights reserved, released to the public domain.
+ *
+ * Version 1.0
+ *
+ */
+
+/*
+
+#!/usr/bin/perl -pn
+
+s{((0x)?[0-9a-fA-F]+)(.*\[([\*\ ]{4})\])}{
+
+	($num,$pat,$bits) = ($1,$3,$4);
+	
+	$bits =~ s/([^\s0])|(.)/ defined($1) + 0 /ge;
+	
+	$num = ord(pack("B8", $bits));
+	$num |= $num >> 4;
+	$num = sprintf("0x%.2x", $num);
+	
+	#print "$num,$pat,$bits\n";
+	
+	$num . $pat;
+}ge;
+
+__END__;
+*/
+
+#define FONTDATAMAX 1536
+
+char fontname_mini4x6[] = "MINI4x6";
+
+int  fontheight_mini4x6 = 6;
+int  fontwidth_mini4x6  = 4;
+
+/* Note: binary data consists of one byte for each row of each character top
+   to bottom, character 0 to character 255, six bytes per character. Each
+   byte contains the same four character bits in both nybbles.
+   MSBit to LSBit = left to right.
+ */
+
+unsigned char fontdata_mini4x6[FONTDATAMAX] = {
+
+	/*{*/
+	  	/*   Char 0: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 1: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 2: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 3: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 4: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 5: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 6: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 7: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 8: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 9: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 10: '' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 11: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 12: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 13: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 14: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 15: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 16: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 17: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 18: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 19: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 20: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 21: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 22: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 23: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 24: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 25: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 26: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 27: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 28: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 29: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 30: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 31: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 32: ' ' */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 33: '!' */
+	0x44,	/*=  [ *  ]       */
+	0x44,	/*=  [ *  ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 34: '"' */
+	0xaa,	/*=  [* * ]       */
+	0xaa,	/*=  [* * ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 35: '#' */
+	0xaa,	/*=  [* * ]       */
+	0xff,	/*=  [****]       */
+	0xff,	/*=  [****]       */
+	0xaa,	/*=  [* * ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 36: '$' */
+	0x44,	/*=  [ *  ]       */
+	0x66,	/*=  [ ** ]       */
+	0xee,	/*=  [*** ]       */
+	0xcc,	/*=  [**  ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 37: '%' */
+	0xaa,	/*=  [* * ]       */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x88,	/*=  [*   ]       */
+	0xaa,	/*=  [* * ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 38: '&' */
+	0xaa,	/*=  [* * ]       */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x88,	/*=  [*   ]       */
+	0xaa,	/*=  [* * ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 39: ''' */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 40: '(' */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x44,	/*=  [ *  ]       */
+	0x44,	/*=  [ *  ]       */
+	0x22,	/*=  [  * ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 41: ')' */
+	0x44,	/*=  [ *  ]       */
+	0x22,	/*=  [  * ]       */
+	0x22,	/*=  [  * ]       */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 42: '*' */
+	0x00,	/*=  [    ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 43: '+' */
+	0x00,	/*=  [    ]       */
+	0x44,	/*=  [ *  ]       */
+	0xee,	/*=  [*** ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 44: ',' */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x44,	/*=  [ *  ]       */
+	0x88,	/*=  [*   ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 45: '-' */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 46: '.' */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 47: '/' */
+	0x00,	/*=  [    ]       */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x88,	/*=  [*   ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 48: '0'   */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/
+	  	/*   Char 49: '1'   */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/
+	  	/*   Char 50: '2'   */
+	0xcc,	/*=   [**  ]        */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/
+	  	/*   Char 51: '3'   */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x22,	/*=   [  * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 52: '4'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 53: '5'   */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 54: '6'   */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 55: '7'   */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 56: '8'   */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 57: '9'   */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 58: ':'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 59: ';'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	/*}*/
+	/*{*/ 	/*   Char 60: '<'   */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 61: '='   */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 62: '>'   */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 63: '?'   */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 64: '@'   */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 65: 'A'   */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 66: 'B'   */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 67: 'C'   */
+	0x66,	/*=   [ ** ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 68: 'D'   */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 69: 'E'   */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 70: 'F'   */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 71: 'G'   */
+	0x66,	/*=   [ ** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 72: 'H'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 73: 'I'   */
+	0xee,	/*=   [*** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 74: 'J'   */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 75: 'K'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 76: 'L'   */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 77: 'M'   */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 78: 'N'   */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 79: 'O'   */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 80: 'P'   */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 81: 'Q'   */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 82: 'R'   */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 83: 'S'   */
+	0x66,	/*=   [ ** ]        */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x22,	/*=   [  * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 84: 'T'   */
+	0xee,	/*=   [*** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 85: 'U'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 86: 'V'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 87: 'W'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 88: 'X'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 89: 'Y'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 90: 'Z'   */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 91: '['   */
+	0x66,	/*=   [ ** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 92: '\'   */
+	0x00,	/*=   [    ]        */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 93: ']'   */
+	0x66,	/*=   [ ** ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 94: '^'   */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 95: '_'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	/*}*/
+	/*{*/ 	/*   Char 96: '`'   */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 97: 'a'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 98: 'b'   */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 99: 'c'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0x88,	/*=   [*   ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 100: 'd'   */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x66,	/*=   [ ** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 101: 'e'   */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 102: 'f'   */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 103: 'g'   */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 104: 'h'   */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 105: 'i'   */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 106: 'j'   */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 107: 'k'   */
+	0x00,	/*=   [    ]        */
+	0x88,	/*=   [*   ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 108: 'l'   */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 109: 'm'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 110: 'n'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 111: 'o'   */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 112: 'p'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x88,	/*=   [*   ]        */
+	/*}*/
+	/*{*/ 	/*   Char 113: 'q'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x22,	/*=   [  * ]        */
+	/*}*/
+	/*{*/ 	/*   Char 114: 'r'   */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 115: 's'   */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0xcc,	/*=   [**  ]        */
+	0x22,	/*=   [  * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 116: 't'   */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 117: 'u'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 118: 'v'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 119: 'w'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 120: 'x'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 121: 'y'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0xcc,	/*=   [**  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 122: 'z' */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xcc,	/*=   [**  ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 123: '{' */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 124: '|' */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 125: '}' */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x66,	/*=   [ ** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 126: '~' */
+	0x55,	/*=   [ * *]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 127: '' */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 128:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 129:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 130:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 131:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 132:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 133:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 134:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 135:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 136:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 137:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 138:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 139:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 140:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 141:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 142:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 143:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 144:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 145:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 146:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 147:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 148:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 149:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 150:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 151:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 152:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 153:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 154:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 155:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 156:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 157:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 158:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 159:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 160:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 161:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 162:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 163:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 164:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 165:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 166:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 167:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 168:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 169:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 170:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 171:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 172:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 173:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 174:  */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0xcc,	/*=   [**  ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 175:  */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0x66,	/*=   [ ** ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 176:  */
+	0x88,	/*=   [*   ]        */
+	0x22,	/*=   [  * ]        */
+	0x88,	/*=   [*   ]        */
+	0x22,	/*=   [  * ]        */
+	0x88,	/*=   [*   ]        */
+	0x22,	/*=   [  * ]        */
+	/*}*/
+	/*{*/ 	/*   Char 177:  */
+	0xaa,	/*=   [* * ]        */
+	0x55,	/*=   [ * *]        */
+	0xaa,	/*=   [* * ]        */
+	0x55,	/*=   [ * *]        */
+	0xaa,	/*=   [* * ]        */
+	0x55,	/*=   [ * *]        */
+	/*}*/
+	/*{*/ 	/*   Char 178:  */
+	0xdd,	/*=   [** *]        */
+	0xbb,	/*=   [* **]        */
+	0xdd,	/*=   [** *]        */
+	0xbb,	/*=   [* **]        */
+	0xdd,	/*=   [** *]        */
+	0xbb,	/*=   [* **]        */
+	/*}*/
+	/*{*/ 	/*   Char 179:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 180:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 181:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 182:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 183:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 184:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 185:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 186:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 187:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 188:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 189:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 190:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 191:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 192:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x77,	/*=   [ ***]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 193:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 194:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 195:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x77,	/*=   [ ***]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 196:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 197:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xff,	/*=   [****]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 198:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 199:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x77,	/*=   [ ***]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 200:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 201:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 202:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 203:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 204:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 205:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 206:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 207:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 208:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 209:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 210:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 211:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x77,	/*=   [ ***]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 212:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 213:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 214:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x77,	/*=   [ ***]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 215:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xff,	/*=   [****]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 216:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 217:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 218:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x77,	/*=   [ ***]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 219:  */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	/*}*/
+	/*{*/ 	/*   Char 220:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	/*}*/
+	/*{*/ 	/*   Char 221:  */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 222:  */
+	0x33,	/*=   [  **]        */
+	0x33,	/*=   [  **]        */
+	0x33,	/*=   [  **]        */
+	0x33,	/*=   [  **]        */
+	0x33,	/*=   [  **]        */
+	0x33,	/*=   [  **]        */
+	/*}*/
+	/*{*/ 	/*   Char 223:  */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 224:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 225:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 226:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 227:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 228:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 229:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 230:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 231:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 232:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 233:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 234:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 235:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 236:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 237:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 238:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 239:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 240:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 241:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 242:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 243:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 244:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 245:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 246:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 247:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 248:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 249:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 250:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 251:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 252:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 253:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 254:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 255:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+};
diff -urN linux-2.4.29/arch/m68knommu/console/pearl_8x8.c linux-2.4.29-uc1/arch/m68knommu/console/pearl_8x8.c
--- linux-2.4.29/arch/m68knommu/console/pearl_8x8.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/console/pearl_8x8.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,2582 @@
+/**********************************************/
+/*                                            */
+/*       Font file generated by cpi2fnt       */
+/*       ------------------------------       */
+/*       Combined with the alpha-numeric      */
+/*       portion of Greg Harp's old PEARL     */
+/*       font (from earlier versions of       */
+/*       linux-m86k) by John Shifflett        */
+/*                                            */
+/**********************************************/
+
+#define FONTDATAMAX 2048
+
+char fontname_pearl8x8[] = "PEARL8x8";
+
+int  fontheight_pearl8x8 = 8;
+int  fontwidth_pearl8x8  = 8;
+
+unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
+
+   /* 0 0x00 '^@' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 1 0x01 '^A' */
+   0x7e, /* 01111110 */
+   0x81, /* 10000001 */
+   0xa5, /* 10100101 */
+   0x81, /* 10000001 */
+   0xbd, /* 10111101 */
+   0x99, /* 10011001 */
+   0x81, /* 10000001 */
+   0x7e, /* 01111110 */
+
+   /* 2 0x02 '^B' */
+   0x7e, /* 01111110 */
+   0xff, /* 11111111 */
+   0xdb, /* 11011011 */
+   0xff, /* 11111111 */
+   0xc3, /* 11000011 */
+   0xe7, /* 11100111 */
+   0xff, /* 11111111 */
+   0x7e, /* 01111110 */
+
+   /* 3 0x03 '^C' */
+   0x6c, /* 01101100 */
+   0xfe, /* 11111110 */
+   0xfe, /* 11111110 */
+   0xfe, /* 11111110 */
+   0x7c, /* 01111100 */
+   0x38, /* 00111000 */
+   0x10, /* 00010000 */
+   0x00, /* 00000000 */
+
+   /* 4 0x04 '^D' */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x7c, /* 01111100 */
+   0xfe, /* 11111110 */
+   0x7c, /* 01111100 */
+   0x38, /* 00111000 */
+   0x10, /* 00010000 */
+   0x00, /* 00000000 */
+
+   /* 5 0x05 '^E' */
+   0x38, /* 00111000 */
+   0x7c, /* 01111100 */
+   0x38, /* 00111000 */
+   0xfe, /* 11111110 */
+   0xfe, /* 11111110 */
+   0xd6, /* 11010110 */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+
+   /* 6 0x06 '^F' */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x7c, /* 01111100 */
+   0xfe, /* 11111110 */
+   0xfe, /* 11111110 */
+   0x7c, /* 01111100 */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+
+   /* 7 0x07 '^G' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 8 0x08 '^H' */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xe7, /* 11100111 */
+   0xc3, /* 11000011 */
+   0xc3, /* 11000011 */
+   0xe7, /* 11100111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+
+   /* 9 0x09 '^I' */
+   0x00, /* 00000000 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x42, /* 01000010 */
+   0x42, /* 01000010 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 10 0x0a '^J' */
+   0xff, /* 11111111 */
+   0xc3, /* 11000011 */
+   0x99, /* 10011001 */
+   0xbd, /* 10111101 */
+   0xbd, /* 10111101 */
+   0x99, /* 10011001 */
+   0xc3, /* 11000011 */
+   0xff, /* 11111111 */
+
+   /* 11 0x0b '^K' */
+   0x0f, /* 00001111 */
+   0x07, /* 00000111 */
+   0x0f, /* 00001111 */
+   0x7d, /* 01111101 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x78, /* 01111000 */
+
+   /* 12 0x0c '^L' */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+
+   /* 13 0x0d '^M' */
+   0x3f, /* 00111111 */
+   0x33, /* 00110011 */
+   0x3f, /* 00111111 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x70, /* 01110000 */
+   0xf0, /* 11110000 */
+   0xe0, /* 11100000 */
+
+   /* 14 0x0e '^N' */
+   0x7f, /* 01111111 */
+   0x63, /* 01100011 */
+   0x7f, /* 01111111 */
+   0x63, /* 01100011 */
+   0x63, /* 01100011 */
+   0x67, /* 01100111 */
+   0xe6, /* 11100110 */
+   0xc0, /* 11000000 */
+
+   /* 15 0x0f '^O' */
+   0x18, /* 00011000 */
+   0xdb, /* 11011011 */
+   0x3c, /* 00111100 */
+   0xe7, /* 11100111 */
+   0xe7, /* 11100111 */
+   0x3c, /* 00111100 */
+   0xdb, /* 11011011 */
+   0x18, /* 00011000 */
+
+   /* 16 0x10 '^P' */
+   0x80, /* 10000000 */
+   0xe0, /* 11100000 */
+   0xf8, /* 11111000 */
+   0xfe, /* 11111110 */
+   0xf8, /* 11111000 */
+   0xe0, /* 11100000 */
+   0x80, /* 10000000 */
+   0x00, /* 00000000 */
+
+   /* 17 0x11 '^Q' */
+   0x02, /* 00000010 */
+   0x0e, /* 00001110 */
+   0x3e, /* 00111110 */
+   0xfe, /* 11111110 */
+   0x3e, /* 00111110 */
+   0x0e, /* 00001110 */
+   0x02, /* 00000010 */
+   0x00, /* 00000000 */
+
+   /* 18 0x12 '^R' */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+
+   /* 19 0x13 '^S' */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+
+   /* 20 0x14 '^T' */
+   0x7f, /* 01111111 */
+   0xdb, /* 11011011 */
+   0xdb, /* 11011011 */
+   0x7b, /* 01111011 */
+   0x1b, /* 00011011 */
+   0x1b, /* 00011011 */
+   0x1b, /* 00011011 */
+   0x00, /* 00000000 */
+
+   /* 21 0x15 '^U' */
+   0x3e, /* 00111110 */
+   0x61, /* 01100001 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x86, /* 10000110 */
+   0x7c, /* 01111100 */
+
+   /* 22 0x16 '^V' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x7e, /* 01111110 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 23 0x17 '^W' */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+
+   /* 24 0x18 '^X' */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 25 0x19 '^Y' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 26 0x1a '^Z' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0xfe, /* 11111110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 27 0x1b '^[' */
+   0x00, /* 00000000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xfe, /* 11111110 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 28 0x1c '^\' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 29 0x1d '^]' */
+   0x00, /* 00000000 */
+   0x24, /* 00100100 */
+   0x66, /* 01100110 */
+   0xff, /* 11111111 */
+   0x66, /* 01100110 */
+   0x24, /* 00100100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 30 0x1e '^^' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 31 0x1f '^_' */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0x7e, /* 01111110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 32 0x20 ' ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 33 0x21 '!' */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 34 0x22 '"' */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 35 0x23 '#' */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0xfe, /* 11111110 */
+   0x6c, /* 01101100 */
+   0xfe, /* 11111110 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x00, /* 00000000 */
+
+   /* 36 0x24 '$' */
+   0x18, /* 00011000 */
+   0x3e, /* 00111110 */
+   0x60, /* 01100000 */
+   0x3c, /* 00111100 */
+   0x06, /* 00000110 */
+   0x7c, /* 01111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 37 0x25 '%' */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xcc, /* 11001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x66, /* 01100110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 38 0x26 '&' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x68, /* 01101000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 39 0x27 ''' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 40 0x28 '(' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+
+   /* 41 0x29 ')' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+
+   /* 42 0x2a '*' */
+   0x00, /* 00000000 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0xff, /* 11111111 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 43 0x2b '+' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 44 0x2c ',' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+
+   /* 45 0x2d '-' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 46 0x2e '.' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 47 0x2f '/' */
+   0x03, /* 00000011 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 48 0x30 '0' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xde, /* 11011110 */
+   0xfe, /* 11111110 */
+   0xf6, /* 11110110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 49 0x31 '1' */
+   0x18, /* 00011000 */
+   0x78, /* 01111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 50 0x32 '2' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 51 0x33 '3' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0x06, /* 00000110 */
+   0x1c, /* 00011100 */
+   0x06, /* 00000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 52 0x34 '4' */
+   0x1c, /* 00011100 */
+   0x3c, /* 00111100 */
+   0x6c, /* 01101100 */
+   0xcc, /* 11001100 */
+   0xfe, /* 11111110 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+
+   /* 53 0x35 '5' */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xfc, /* 11111100 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 54 0x36 '6' */
+   0x38, /* 00111000 */
+   0x60, /* 01100000 */
+   0xc0, /* 11000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 55 0x37 '7' */
+   0xfe, /* 11111110 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0x60, /* 01100000 */
+   0x00, /* 00000000 */
+
+   /* 56 0x38 '8' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 57 0x39 '9' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+
+   /* 58 0x3a ':' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 59 0x3b ';' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+
+   /* 60 0x3c '<' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+
+   /* 61 0x3d '=' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 62 0x3e '>' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+
+   /* 63 0x3f '?' */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 64 0x40 '@' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xde, /* 11011110 */
+   0xde, /* 11011110 */
+   0xde, /* 11011110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 65 0x41 'A' */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 66 0x42 'B' */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 67 0x43 'C' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 68 0x44 'D' */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 69 0x45 'E' */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xf8, /* 11111000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 70 0x46 'F' */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xf8, /* 11111000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 71 0x47 'G' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xce, /* 11001110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 72 0x48 'H' */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 73 0x49 'I' */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 74 0x4a 'J' */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 75 0x4b 'K' */
+   0xc6, /* 11000110 */
+   0xcc, /* 11001100 */
+   0xd8, /* 11011000 */
+   0xf0, /* 11110000 */
+   0xd8, /* 11011000 */
+   0xcc, /* 11001100 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 76 0x4c 'L' */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 77 0x4d 'M' */
+   0x82, /* 10000010 */
+   0xc6, /* 11000110 */
+   0xee, /* 11101110 */
+   0xfe, /* 11111110 */
+   0xd6, /* 11010110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 78 0x4e 'N' */
+   0xc6, /* 11000110 */
+   0xe6, /* 11100110 */
+   0xf6, /* 11110110 */
+   0xde, /* 11011110 */
+   0xce, /* 11001110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 79 0x4f 'O' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 80 0x50 'P' */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 81 0x51 'Q' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xf6, /* 11110110 */
+   0xde, /* 11011110 */
+   0x7c, /* 01111100 */
+   0x06, /* 00000110 */
+
+   /* 82 0x52 'R' */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0xd8, /* 11011000 */
+   0xcc, /* 11001100 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 83 0x53 'S' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0x60, /* 01100000 */
+   0x38, /* 00111000 */
+   0x0c, /* 00001100 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 84 0x54 'T' */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 85 0x55 'U' */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 86 0x56 'V' */
+   0xc3, /* 11000011 */
+   0xc3, /* 11000011 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 87 0x57 'W' */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xd6, /* 11010110 */
+   0xfe, /* 11111110 */
+   0xee, /* 11101110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 88 0x58 'X' */
+   0xc3, /* 11000011 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0xc3, /* 11000011 */
+   0x00, /* 00000000 */
+
+   /* 89 0x59 'Y' */
+   0xc3, /* 11000011 */
+   0xc3, /* 11000011 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 90 0x5a 'Z' */
+   0xfe, /* 11111110 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 91 0x5b '[' */
+   0x3c, /* 00111100 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 92 0x5c '\' */
+   0xc0, /* 11000000 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x06, /* 00000110 */
+   0x03, /* 00000011 */
+   0x00, /* 00000000 */
+
+   /* 93 0x5d ']' */
+   0x3c, /* 00111100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 94 0x5e '^' */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 95 0x5f '_' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+
+   /* 96 0x60 '`' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 97 0x61 'a' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0x06, /* 00000110 */
+   0x7e, /* 01111110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 98 0x62 'b' */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 99 0x63 'c' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 100 0x64 'd' */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x7e, /* 01111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 101 0x65 'e' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 102 0x66 'f' */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x60, /* 01100000 */
+   0xf0, /* 11110000 */
+   0x60, /* 01100000 */
+   0x60, /* 01100000 */
+   0x60, /* 01100000 */
+   0x00, /* 00000000 */
+
+   /* 103 0x67 'g' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x06, /* 00000110 */
+   0x7c, /* 01111100 */
+
+   /* 104 0x68 'h' */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 105 0x69 'i' */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 106 0x6a 'j' */
+   0x06, /* 00000110 */
+   0x00, /* 00000000 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+
+   /* 107 0x6b 'k' */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xcc, /* 11001100 */
+   0xd8, /* 11011000 */
+   0xf0, /* 11110000 */
+   0xd8, /* 11011000 */
+   0xcc, /* 11001100 */
+   0x00, /* 00000000 */
+
+   /* 108 0x6c 'l' */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 109 0x6d 'm' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xec, /* 11101100 */
+   0xfe, /* 11111110 */
+   0xd6, /* 11010110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 110 0x6e 'n' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 111 0x6f 'o' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 112 0x70 'p' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+
+   /* 113 0x71 'q' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+
+   /* 114 0x72 'r' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xdc, /* 11011100 */
+   0xe6, /* 11100110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 115 0x73 's' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x06, /* 00000110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 116 0x74 't' */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x7c, /* 01111100 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x36, /* 00110110 */
+   0x1c, /* 00011100 */
+   0x00, /* 00000000 */
+
+   /* 117 0x75 'u' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 118 0x76 'v' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+
+   /* 119 0x77 'w' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xd6, /* 11010110 */
+   0xfe, /* 11111110 */
+   0x6c, /* 01101100 */
+   0x00, /* 00000000 */
+
+   /* 120 0x78 'x' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 121 0x79 'y' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc3, /* 11000011 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+
+   /* 122 0x7a 'z' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x0c, /* 00001100 */
+   0x38, /* 00111000 */
+   0x60, /* 01100000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 123 0x7b '{' */
+   0x0e, /* 00001110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x70, /* 01110000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x0e, /* 00001110 */
+   0x00, /* 00000000 */
+
+   /* 124 0x7c '|' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 125 0x7d '}' */
+   0x70, /* 01110000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x0e, /* 00001110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x70, /* 01110000 */
+   0x00, /* 00000000 */
+
+   /* 126 0x7e '~' */
+   0x72, /* 01110010 */
+   0x9c, /* 10011100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 127 0x7f '' */
+   0x00, /* 00000000 */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 128 0x80 '€' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x0c, /* 00001100 */
+   0x78, /* 01111000 */
+
+   /* 129 0x81 '�' */
+   0xcc, /* 11001100 */
+   0x00, /* 00000000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 130 0x82 '‚' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 131 0x83 'ƒ' */
+   0x7c, /* 01111100 */
+   0x82, /* 10000010 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 132 0x84 '„' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 133 0x85 '…' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 134 0x86 '†' */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 135 0x87 '‡' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x7e, /* 01111110 */
+   0x0c, /* 00001100 */
+   0x38, /* 00111000 */
+
+   /* 136 0x88 'ˆ' */
+   0x7c, /* 01111100 */
+   0x82, /* 10000010 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 137 0x89 '‰' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 138 0x8a 'Š' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 139 0x8b '‹' */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 140 0x8c 'Œ' */
+   0x7c, /* 01111100 */
+   0x82, /* 10000010 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 141 0x8d '�' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 142 0x8e 'Ž' */
+   0xc6, /* 11000110 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 143 0x8f '�' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 144 0x90 '�' */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xf8, /* 11111000 */
+   0xc0, /* 11000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 145 0x91 '‘' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0xd8, /* 11011000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 146 0x92 '’' */
+   0x3e, /* 00111110 */
+   0x6c, /* 01101100 */
+   0xcc, /* 11001100 */
+   0xfe, /* 11111110 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xce, /* 11001110 */
+   0x00, /* 00000000 */
+
+   /* 147 0x93 '“' */
+   0x7c, /* 01111100 */
+   0x82, /* 10000010 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 148 0x94 '”' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 149 0x95 '•' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 150 0x96 '–' */
+   0x78, /* 01111000 */
+   0x84, /* 10000100 */
+   0x00, /* 00000000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 151 0x97 '—' */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 152 0x98 '˜' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x06, /* 00000110 */
+   0xfc, /* 11111100 */
+
+   /* 153 0x99 '™' */
+   0xc6, /* 11000110 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+
+   /* 154 0x9a 'š' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 155 0x9b '›' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 156 0x9c 'œ' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x64, /* 01100100 */
+   0xf0, /* 11110000 */
+   0x60, /* 01100000 */
+   0x66, /* 01100110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 157 0x9d '�' */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 158 0x9e 'ž' */
+   0xf8, /* 11111000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xfa, /* 11111010 */
+   0xc6, /* 11000110 */
+   0xcf, /* 11001111 */
+   0xc6, /* 11000110 */
+   0xc7, /* 11000111 */
+
+   /* 159 0x9f 'Ÿ' */
+   0x0e, /* 00001110 */
+   0x1b, /* 00011011 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0xd8, /* 11011000 */
+   0x70, /* 01110000 */
+   0x00, /* 00000000 */
+
+   /* 160 0xa0 ' ' */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 161 0xa1 '¡' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 162 0xa2 '¢' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 163 0xa3 '£' */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 164 0xa4 '¤' */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x00, /* 00000000 */
+   0xdc, /* 11011100 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+
+   /* 165 0xa5 '¥' */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x00, /* 00000000 */
+   0xe6, /* 11100110 */
+   0xf6, /* 11110110 */
+   0xde, /* 11011110 */
+   0xce, /* 11001110 */
+   0x00, /* 00000000 */
+
+   /* 166 0xa6 '¦' */
+   0x3c, /* 00111100 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x3e, /* 00111110 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 167 0xa7 '§' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 168 0xa8 '¨' */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x63, /* 01100011 */
+   0x3e, /* 00111110 */
+   0x00, /* 00000000 */
+
+   /* 169 0xa9 '©' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 170 0xaa 'ª' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 171 0xab '«' */
+   0x63, /* 01100011 */
+   0xe6, /* 11100110 */
+   0x6c, /* 01101100 */
+   0x7e, /* 01111110 */
+   0x33, /* 00110011 */
+   0x66, /* 01100110 */
+   0xcc, /* 11001100 */
+   0x0f, /* 00001111 */
+
+   /* 172 0xac '¬' */
+   0x63, /* 01100011 */
+   0xe6, /* 11100110 */
+   0x6c, /* 01101100 */
+   0x7a, /* 01111010 */
+   0x36, /* 00110110 */
+   0x6a, /* 01101010 */
+   0xdf, /* 11011111 */
+   0x06, /* 00000110 */
+
+   /* 173 0xad '­' */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 174 0xae '®' */
+   0x00, /* 00000000 */
+   0x33, /* 00110011 */
+   0x66, /* 01100110 */
+   0xcc, /* 11001100 */
+   0x66, /* 01100110 */
+   0x33, /* 00110011 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 175 0xaf '¯' */
+   0x00, /* 00000000 */
+   0xcc, /* 11001100 */
+   0x66, /* 01100110 */
+   0x33, /* 00110011 */
+   0x66, /* 01100110 */
+   0xcc, /* 11001100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 176 0xb0 '°' */
+   0x22, /* 00100010 */
+   0x88, /* 10001000 */
+   0x22, /* 00100010 */
+   0x88, /* 10001000 */
+   0x22, /* 00100010 */
+   0x88, /* 10001000 */
+   0x22, /* 00100010 */
+   0x88, /* 10001000 */
+
+   /* 177 0xb1 '±' */
+   0x55, /* 01010101 */
+   0xaa, /* 10101010 */
+   0x55, /* 01010101 */
+   0xaa, /* 10101010 */
+   0x55, /* 01010101 */
+   0xaa, /* 10101010 */
+   0x55, /* 01010101 */
+   0xaa, /* 10101010 */
+
+   /* 178 0xb2 '²' */
+   0x77, /* 01110111 */
+   0xdd, /* 11011101 */
+   0x77, /* 01110111 */
+   0xdd, /* 11011101 */
+   0x77, /* 01110111 */
+   0xdd, /* 11011101 */
+   0x77, /* 01110111 */
+   0xdd, /* 11011101 */
+
+   /* 179 0xb3 '³' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 180 0xb4 '´' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 181 0xb5 'µ' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 182 0xb6 '¶' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf6, /* 11110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 183 0xb7 '·' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 184 0xb8 '¸' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 185 0xb9 '¹' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf6, /* 11110110 */
+   0x06, /* 00000110 */
+   0xf6, /* 11110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 186 0xba 'º' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 187 0xbb '»' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x06, /* 00000110 */
+   0xf6, /* 11110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 188 0xbc '¼' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf6, /* 11110110 */
+   0x06, /* 00000110 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 189 0xbd '½' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 190 0xbe '¾' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 191 0xbf '¿' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 192 0xc0 'À' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 193 0xc1 'Á' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 194 0xc2 'Â' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 195 0xc3 'Ã' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 196 0xc4 'Ä' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 197 0xc5 'Å' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 198 0xc6 'Æ' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 199 0xc7 'Ç' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x37, /* 00110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 200 0xc8 'È' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x37, /* 00110111 */
+   0x30, /* 00110000 */
+   0x3f, /* 00111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 201 0xc9 'É' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x3f, /* 00111111 */
+   0x30, /* 00110000 */
+   0x37, /* 00110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 202 0xca 'Ê' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf7, /* 11110111 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 203 0xcb 'Ë' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0xf7, /* 11110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 204 0xcc 'Ì' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x37, /* 00110111 */
+   0x30, /* 00110000 */
+   0x37, /* 00110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 205 0xcd 'Í' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 206 0xce 'Î' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf7, /* 11110111 */
+   0x00, /* 00000000 */
+   0xf7, /* 11110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 207 0xcf 'Ï' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 208 0xd0 'Ð' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 209 0xd1 'Ñ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 210 0xd2 'Ò' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 211 0xd3 'Ó' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x3f, /* 00111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 212 0xd4 'Ô' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 213 0xd5 'Õ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 214 0xd6 'Ö' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x3f, /* 00111111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 215 0xd7 '×' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xff, /* 11111111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 216 0xd8 'Ø' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 217 0xd9 'Ù' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 218 0xda 'Ú' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 219 0xdb 'Û' */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+
+   /* 220 0xdc 'Ü' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+
+   /* 221 0xdd 'Ý' */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+
+   /* 222 0xde 'Þ' */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+
+   /* 223 0xdf 'ß' */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 224 0xe0 'à' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0xc8, /* 11001000 */
+   0xdc, /* 11011100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 225 0xe1 'á' */
+   0x78, /* 01111000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xd8, /* 11011000 */
+   0xcc, /* 11001100 */
+   0xc6, /* 11000110 */
+   0xcc, /* 11001100 */
+   0x00, /* 00000000 */
+
+   /* 226 0xe2 'â' */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 227 0xe3 'ã' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x00, /* 00000000 */
+
+   /* 228 0xe4 'ä' */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 229 0xe5 'å' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xd8, /* 11011000 */
+   0xd8, /* 11011000 */
+   0xd8, /* 11011000 */
+   0x70, /* 01110000 */
+   0x00, /* 00000000 */
+
+   /* 230 0xe6 'æ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x7c, /* 01111100 */
+   0xc0, /* 11000000 */
+
+   /* 231 0xe7 'ç' */
+   0x00, /* 00000000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 232 0xe8 'è' */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+
+   /* 233 0xe9 'é' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+
+   /* 234 0xea 'ê' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0xee, /* 11101110 */
+   0x00, /* 00000000 */
+
+   /* 235 0xeb 'ë' */
+   0x0e, /* 00001110 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x3e, /* 00111110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 236 0xec 'ì' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xdb, /* 11011011 */
+   0xdb, /* 11011011 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 237 0xed 'í' */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x7e, /* 01111110 */
+   0xdb, /* 11011011 */
+   0xdb, /* 11011011 */
+   0x7e, /* 01111110 */
+   0x60, /* 01100000 */
+   0xc0, /* 11000000 */
+
+   /* 238 0xee 'î' */
+   0x1e, /* 00011110 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0x7e, /* 01111110 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x1e, /* 00011110 */
+   0x00, /* 00000000 */
+
+   /* 239 0xef 'ï' */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 240 0xf0 'ð' */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 241 0xf1 'ñ' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 242 0xf2 'ò' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 243 0xf3 'ó' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 244 0xf4 'ô' */
+   0x0e, /* 00001110 */
+   0x1b, /* 00011011 */
+   0x1b, /* 00011011 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 245 0xf5 'õ' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xd8, /* 11011000 */
+   0xd8, /* 11011000 */
+   0x70, /* 01110000 */
+
+   /* 246 0xf6 'ö' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 247 0xf7 '÷' */
+   0x00, /* 00000000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x00, /* 00000000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 248 0xf8 'ø' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 249 0xf9 'ù' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 250 0xfa 'ú' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 251 0xfb 'û' */
+   0x0f, /* 00001111 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0xec, /* 11101100 */
+   0x6c, /* 01101100 */
+   0x3c, /* 00111100 */
+   0x1c, /* 00011100 */
+
+   /* 252 0xfc 'ü' */
+   0x6c, /* 01101100 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 253 0xfd 'ý' */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 254 0xfe 'þ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 255 0xff 'ÿ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+};
+
diff -urN linux-2.4.29/arch/m68knommu/console/txtcon.c linux-2.4.29-uc1/arch/m68knommu/console/txtcon.c
--- linux-2.4.29/arch/m68knommu/console/txtcon.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/console/txtcon.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,127 @@
+/*
+ * linux/arch/m68k/console/txtcon.c -- Low level text mode based console driver
+ *
+ *    Copyright (C) 1995 Geert Uytterhoeven
+ *
+ *
+ * This file is currently only a skeleton, since all Amigas and Ataris have
+ * bitmapped graphics.
+ *
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+
+#include <linux/types.h>
+#include <linux/console.h>
+
+
+   /*
+    *    Interface used by the world
+    */
+
+static u_long txtcon_startup(u_long kmem_start, char **display_desc);
+static void txtcon_init(struct vc_data *conp);
+static int txtcon_deinit(struct vc_data *conp);
+static int txtcon_clear(struct vc_data *conp, int sy, int sx, int height,
+                        int width);
+static int txtcon_putc(struct vc_data *conp, int c, int y, int x);
+static int txtcon_putcs(struct vc_data *conp, const char *s, int count, int y,
+                        int x);
+static int txtcon_cursor(struct vc_data *conp, int mode);
+static int txtcon_scroll(struct vc_data *conp, int t, int b, int dir, int count);
+static int txtcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+                        int height, int width);
+static int txtcon_switch(struct vc_data *conp);
+static int txtcon_blank(int blank);
+
+
+
+static u_long txtcon_startup(u_long kmem_start, char **display_desc)
+{
+   *display_desc = "Not yet implemented";
+   return(kmem_start);
+}
+
+
+static void txtcon_init(struct vc_data *conp)
+{
+}
+
+
+static int txtcon_deinit(struct vc_data *conp)
+{
+   return(0);
+}
+
+
+/* ====================================================================== */
+
+/* txtcon_XXX routines - interface used by the world */
+
+
+static int txtcon_clear(struct vc_data *conp, int sy, int sx, int height,
+                        int width)
+{
+   return(0);
+}
+
+
+static int txtcon_putc(struct vc_data *conp, int c, int y, int x)
+{
+   return(0);
+}
+
+
+static int txtcon_putcs(struct vc_data *conp, const char *s, int count, int y,
+                        int x)
+{
+   return(0);
+}
+
+
+static int txtcon_cursor(struct vc_data *conp, int mode)
+{
+   return(0);
+}
+
+
+static int txtcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
+{
+   return(0);
+}
+
+
+static int txtcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+                        int height, int width)
+{
+   return(0);
+}
+
+
+static int txtcon_switch(struct vc_data *conp)
+{
+   return(0);
+}
+
+
+static int txtcon_blank(int blank)
+{
+   return(0);
+}
+
+
+/* ====================================================================== */
+
+   /*
+    *    The console `switch' structure for the text mode based console
+    */
+
+struct consw txt_con = {
+   txtcon_startup, txtcon_init, txtcon_deinit, txtcon_clear, txtcon_putc,
+   txtcon_putcs, txtcon_cursor, txtcon_scroll, txtcon_bmove, txtcon_switch,
+   txtcon_blank
+};
+
diff -urN linux-2.4.29/arch/m68knommu/defconfig linux-2.4.29-uc1/arch/m68knommu/defconfig
--- linux-2.4.29/arch/m68knommu/defconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/defconfig	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,455 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_UCLINUX=y
+CONFIG_UID16=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Processor type and features
+#
+# CONFIG_M68000 is not set
+# CONFIG_M68EN302 is not set
+# CONFIG_M68328 is not set
+# CONFIG_M68EZ328 is not set
+# CONFIG_M68332 is not set
+# CONFIG_M68360 is not set
+# CONFIG_M5204 is not set
+# CONFIG_M5206 is not set
+# CONFIG_M5206e is not set
+CONFIG_M5307=y
+# CONFIG_M5407 is not set
+
+#
+# Platform
+#
+CONFIG_COLDFIRE=y
+# CONFIG_ARNEWSH is not set
+CONFIG_NETtel=y
+# CONFIG_eLIA is not set
+# CONFIG_DISKtel is not set
+# CONFIG_CADRE3 is not set
+# CONFIG_OLDMASK is not set
+CONFIG_FLASH1MB=y
+# CONFIG_FLASH2MB is not set
+# CONFIG_FLASH4MB is not set
+# CONFIG_EXTRA_FLASH1MB is not set
+CONFIG_RAM4MB=y
+# CONFIG_RAM8MB is not set
+# CONFIG_RAM16MB is not set
+# CONFIG_RAM32MB is not set
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+# CONFIG_HIMEMKERNEL is not set
+
+#
+# General setup
+#
+CONFIG_NET=y
+# CONFIG_VISWS is not set
+# CONFIG_PCI is not set
+# CONFIG_MCA is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+# CONFIG_KCORE_ELF is not set
+CONFIG_KCORE_AOUT=y
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_ELF is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ACPI is not set
+# CONFIG_APM is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_BLKMEM=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+# CONFIG_ULTRA is not set
+# CONFIG_ULTRA32 is not set
+CONFIG_SMC9194=y
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_ASYNC is not set
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Character devices
+#
+CONFIG_COLDFIRE_SERIAL=y
+# CONFIG_SERIAL is not set
+# CONFIG_MCF_MBUS is not set
+# CONFIG_LCDTXT is not set
+# CONFIG_LCDDMA is not set
+# CONFIG_DAC0800 is not set
+# CONFIG_DACI2S is not set
+# CONFIG_T6963 is not set
+# CONFIG_HIFN7901 is not set
+CONFIG_LEDMAN=y
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_SYSV_FS_WRITE is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FULLDEBUG=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_PROFILE is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DUMPTOFLASH is not set
+CONFIG_NO_KERNEL_MSG=y
diff -urN linux-2.4.29/arch/m68knommu/kernel/bios32.c linux-2.4.29-uc1/arch/m68knommu/kernel/bios32.c
--- linux-2.4.29/arch/m68knommu/kernel/bios32.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/kernel/bios32.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,532 @@
+/*
+ * bios32.c - PCI BIOS functions for m68k systems.
+ *
+ * Written by Wout Klaren.
+ *
+ * Based on the DEC Alpha bios32.c by Dave Rusling and David Mosberger.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#if 0
+# define DBG_DEVS(args)		printk args
+#else
+# define DBG_DEVS(args)
+#endif
+
+#ifdef CONFIG_PCI
+
+/*
+ * PCI support for Linux/m68k. Currently only the Hades is supported.
+ *
+ * The support for PCI bridges in the DEC Alpha version has
+ * been removed in this version.
+ */
+
+#include <linux/pci.h>
+#include <linux/malloc.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/uaccess.h>
+
+#define KB		1024
+#define MB		(1024*KB)
+#define GB		(1024*MB)
+
+#define MAJOR_REV	0
+#define MINOR_REV	5
+
+/*
+ * Align VAL to ALIGN, which must be a power of two.
+ */
+
+#define ALIGN(val,align)	(((val) + ((align) - 1)) & ~((align) - 1))
+
+#define MAX(val1, val2) 	(((val1) > (val2)) ? val1 : val2)
+
+/*
+ * Offsets relative to the I/O and memory base addresses from where resources
+ * are allocated.
+ */
+
+#define IO_ALLOC_OFFSET		0x00004000
+#define MEM_ALLOC_OFFSET	0x04000000
+
+/*
+ * Declarations of hardware specific initialisation functions.
+ */
+
+extern struct pci_bus_info *init_hades_pci(void);
+
+/*
+ * Bus info structure of the PCI bus. A pointer to this structure is
+ * put in the sysdata member of the pci_bus structure.
+ */
+
+static struct pci_bus_info *bus_info;
+
+static int pci_modify = 1;		/* If set, layout the PCI bus ourself. */
+static int skip_vga = 0;		/* If set do not modify base addresses
+					   of vga cards.*/
+static int disable_pci_burst = 0;	/* If set do not allow PCI bursts. */
+
+static unsigned int io_base;
+static unsigned int mem_base;
+
+struct pci_fixup pcibios_fixups[] =
+{
+	{ 0 }
+};
+
+/*
+ * static void disable_dev(struct pci_dev *dev)
+ *
+ * Disable PCI device DEV so that it does not respond to I/O or memory
+ * accesses.
+ *
+ * Parameters:
+ *
+ * dev	- device to disable.
+ */
+
+static void __init disable_dev(struct pci_dev *dev)
+{
+	struct pci_bus *bus;
+	unsigned short cmd;
+
+	if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) ||
+	     (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA) ||
+	     (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga)
+		return;
+
+	bus = dev->bus;
+	pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
+
+	cmd &= (~PCI_COMMAND_IO & ~PCI_COMMAND_MEMORY & ~PCI_COMMAND_MASTER);
+	pcibios_write_config_word(bus->number, dev->devfn, PCI_COMMAND, cmd);
+}
+
+/*
+ * static void layout_dev(struct pci_dev *dev)
+ *
+ * Layout memory and I/O for a device.
+ *
+ * Parameters:
+ *
+ * device	- device to layout memory and I/O for.
+ */
+
+static void __init layout_dev(struct pci_dev *dev)
+{
+	struct pci_bus *bus;
+	unsigned short cmd;
+	unsigned int base, mask, size, reg;
+	unsigned int alignto;
+	int i;
+
+	/*
+	 * Skip video cards if requested.
+	 */
+
+	if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) ||
+	     (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA) ||
+	     (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga)
+		return;
+
+	bus = dev->bus;
+	pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
+
+	for (reg = PCI_BASE_ADDRESS_0, i = 0; reg <= PCI_BASE_ADDRESS_5; reg += 4, i++)
+	{
+		/*
+		 * Figure out how much space and of what type this
+		 * device wants.
+		 */
+
+		pcibios_write_config_dword(bus->number, dev->devfn, reg,
+					   0xffffffff);
+		pcibios_read_config_dword(bus->number, dev->devfn, reg, &base);
+
+		if (!base)
+		{
+			/* this base-address register is unused */
+			dev->resource[i].start = 0;
+			dev->resource[i].end = 0;
+			dev->resource[i].flags = 0;
+			continue;
+		}
+
+		/*
+		 * We've read the base address register back after
+		 * writing all ones and so now we must decode it.
+		 */
+
+		if (base & PCI_BASE_ADDRESS_SPACE_IO)
+		{
+			/*
+			 * I/O space base address register.
+			 */
+
+			cmd |= PCI_COMMAND_IO;
+
+			base &= PCI_BASE_ADDRESS_IO_MASK;
+			mask = (~base << 1) | 0x1;
+			size = (mask & base) & 0xffffffff;
+
+			/*
+			 * Align to multiple of size of minimum base.
+			 */
+
+			alignto = MAX(0x040, size) ;
+			base = ALIGN(io_base, alignto);
+			io_base = base + size;
+			pcibios_write_config_dword(bus->number, dev->devfn,
+						   reg, base | PCI_BASE_ADDRESS_SPACE_IO);
+
+			dev->resource[i].start = base;
+			dev->resource[i].end = dev->resource[i].start + size - 1;
+			dev->resource[i].flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
+
+			DBG_DEVS(("layout_dev: IO address: %lX\n", base));
+		}
+		else
+		{
+			unsigned int type;
+
+			/*
+			 * Memory space base address register.
+			 */
+
+			cmd |= PCI_COMMAND_MEMORY;
+			type = base & PCI_BASE_ADDRESS_MEM_TYPE_MASK;
+			base &= PCI_BASE_ADDRESS_MEM_MASK;
+			mask = (~base << 1) | 0x1;
+			size = (mask & base) & 0xffffffff;
+			switch (type)
+			{
+			case PCI_BASE_ADDRESS_MEM_TYPE_32:
+			case PCI_BASE_ADDRESS_MEM_TYPE_64:
+				break;
+
+			case PCI_BASE_ADDRESS_MEM_TYPE_1M:
+				printk("bios32 WARNING: slot %d, function %d "
+				       "requests memory below 1MB---don't "
+				       "know how to do that.\n",
+				       PCI_SLOT(dev->devfn),
+				       PCI_FUNC(dev->devfn));
+				continue;
+			}
+
+			/*
+			 * Align to multiple of size of minimum base.
+			 */
+
+			alignto = MAX(0x1000, size) ;
+			base = ALIGN(mem_base, alignto);
+			mem_base = base + size;
+			pcibios_write_config_dword(bus->number, dev->devfn,
+						   reg, base);
+
+			dev->resource[i].start = base;
+			dev->resource[i].end = dev->resource[i].start + size - 1;
+			dev->resource[i].flags = IORESOURCE_MEM;
+
+			if (type == PCI_BASE_ADDRESS_MEM_TYPE_64)
+			{
+				/*
+				 * 64-bit address, set the highest 32 bits
+				 * to zero.
+				 */
+
+				reg += 4;
+				pcibios_write_config_dword(bus->number, dev->devfn,
+							   reg, 0);
+
+				i++;
+				dev->resource[i].start = 0;
+				dev->resource[i].end = 0;
+				dev->resource[i].flags = 0;
+			}
+		}
+	}
+
+	/*
+	 * Enable device:
+	 */
+
+	if (dev->class >> 8 == PCI_CLASS_NOT_DEFINED ||
+	    dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA ||
+	    dev->class >> 8 == PCI_CLASS_DISPLAY_VGA ||
+	    dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)
+	{
+		/*
+		 * All of these (may) have I/O scattered all around
+		 * and may not use i/o-base address registers at all.
+		 * So we just have to always enable I/O to these
+		 * devices.
+		 */
+		cmd |= PCI_COMMAND_IO;
+	}
+
+	pcibios_write_config_word(bus->number, dev->devfn, PCI_COMMAND,
+				  cmd | PCI_COMMAND_MASTER);
+
+	pcibios_write_config_byte(bus->number, dev->devfn, PCI_LATENCY_TIMER,
+				  (disable_pci_burst) ? 0 : 32);
+
+	if (bus_info != NULL)
+		bus_info->conf_device(bus->number, dev->devfn);	/* Machine dependent configuration. */
+
+	DBG_DEVS(("layout_dev: bus %d  slot 0x%x  VID 0x%x  DID 0x%x  class 0x%x\n",
+		  bus->number, PCI_SLOT(dev->devfn), dev->vendor, dev->device, dev->class));
+}
+
+/*
+ * static void layout_bus(struct pci_bus *bus)
+ *
+ * Layout memory and I/O for all devices on the given bus.
+ *
+ * Parameters:
+ *
+ * bus	- bus.
+ */
+
+static void __init layout_bus(struct pci_bus *bus)
+{
+	unsigned int bio, bmem;
+	struct pci_dev *dev;
+
+	DBG_DEVS(("layout_bus: starting bus %d\n", bus->number));
+
+	if (!bus->devices && !bus->children)
+		return;
+
+	/*
+	 * Align the current bases on appropriate boundaries (4K for
+	 * IO and 1MB for memory).
+	 */
+
+	bio = io_base = ALIGN(io_base, 4*KB);
+	bmem = mem_base = ALIGN(mem_base, 1*MB);
+
+	/*
+	 * PCI devices might have been setup by a PCI BIOS emulation
+	 * running under TOS. In these cases there is a
+	 * window during which two devices may have an overlapping
+	 * address range. To avoid this causing trouble, we first
+	 * turn off the I/O and memory address decoders for all PCI
+	 * devices.  They'll be re-enabled only once all address
+	 * decoders are programmed consistently.
+	 */
+
+	DBG_DEVS(("layout_bus: disable_dev for bus %d\n", bus->number));
+
+	for (dev = bus->devices; dev; dev = dev->sibling)
+	{
+		if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) ||
+		    (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA))
+			disable_dev(dev);
+	}
+
+	/*
+	 * Allocate space to each device:
+	 */
+
+	DBG_DEVS(("layout_bus: starting bus %d devices\n", bus->number));
+
+	for (dev = bus->devices; dev; dev = dev->sibling)
+	{
+		if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) ||
+		    (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA))
+			layout_dev(dev);
+	}
+
+	DBG_DEVS(("layout_bus: bus %d finished\n", bus->number));
+}
+
+/*
+ * static void pcibios_fixup(void)
+ *
+ * Layout memory and I/O of all devices on the PCI bus if 'pci_modify' is
+ * true. This might be necessary because not every m68k machine with a PCI
+ * bus has a PCI BIOS. This function should be called right after
+ * pci_scan_bus() in pcibios_init().
+ */
+
+static void __init pcibios_fixup(void)
+{
+	if (pci_modify)
+	{
+		/*
+		 * Set base addresses for allocation of I/O and memory space.
+		 */
+
+		io_base = bus_info->io_space.start + IO_ALLOC_OFFSET;
+		mem_base = bus_info->mem_space.start + MEM_ALLOC_OFFSET;
+
+		/*
+		 * Scan the tree, allocating PCI memory and I/O space.
+		 */
+
+		layout_bus(pci_bus_b(pci_root.next));
+	}
+
+	/*
+	 * Fix interrupt assignments, etc.
+	 */
+
+	bus_info->fixup(pci_modify);
+}
+
+/*
+ * static void pcibios_claim_resources(struct pci_bus *bus)
+ *
+ * Claim all resources that are assigned to devices on the given bus.
+ *
+ * Parameters:
+ *
+ * bus	- bus.
+ */
+
+static void __init pcibios_claim_resources(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+	int i;
+
+	while (bus)
+	{
+		for (dev = bus->devices; (dev != NULL); dev = dev->sibling)
+		{
+			for (i = 0; i < PCI_NUM_RESOURCES; i++)
+			{
+				struct resource *r = &dev->resource[i];
+				struct resource *pr;
+				struct pci_bus_info *bus_info = (struct pci_bus_info *) dev->sysdata;
+
+				if ((r->start == 0) || (r->parent != NULL))
+					continue;
+#if 1
+				if (r->flags & IORESOURCE_IO)
+					pr = &bus_info->io_space;
+				else
+					pr = &bus_info->mem_space;
+#else
+				if (r->flags & IORESOURCE_IO)
+					pr = &ioport_resource;
+				else
+					pr = &iomem_resource;
+#endif
+				if (request_resource(pr, r) < 0)
+				{
+					printk(KERN_ERR "PCI: Address space collision on region %d of device %s\n", i, dev->name);
+				}
+			}
+		}
+
+		if (bus->children)
+			pcibios_claim_resources(bus->children);
+
+		bus = bus->next;
+	}
+}
+
+/*
+ * int pcibios_assign_resource(struct pci_dev *dev, int i)
+ *
+ * Assign a new address to a PCI resource.
+ *
+ * Parameters:
+ *
+ * dev	- device.
+ * i	- resource.
+ *
+ * Result: 0 if successfull.
+ */
+
+int __init pcibios_assign_resource(struct pci_dev *dev, int i)
+{
+	struct resource *r = &dev->resource[i];
+	struct resource *pr = pci_find_parent_resource(dev, r);
+	unsigned long size = r->end + 1;
+
+	if (!pr)
+		return -EINVAL;
+
+	if (r->flags & IORESOURCE_IO)
+	{
+		if (size > 0x100)
+			return -EFBIG;
+
+		if (allocate_resource(pr, r, size, bus_info->io_space.start +
+				      IO_ALLOC_OFFSET,  bus_info->io_space.end, 1024))
+			return -EBUSY;
+	}
+	else
+	{
+		if (allocate_resource(pr, r, size, bus_info->mem_space.start +
+				      MEM_ALLOC_OFFSET, bus_info->mem_space.end, size))
+			return -EBUSY;
+	}
+
+	if (i < 6)
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, r->start);
+
+	return 0;
+}
+
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+	void *sysdata;
+
+	sysdata = (bus->parent) ? bus->parent->sysdata : bus->sysdata;
+
+	for (dev = bus->devices; (dev != NULL); dev = dev->sibling)
+		dev->sysdata = sysdata;
+}
+
+void __init pcibios_init(void)
+{
+	printk("Linux/m68k PCI BIOS32 revision %x.%02x\n", MAJOR_REV, MINOR_REV);
+
+	bus_info = NULL;
+#ifdef CONFIG_HADES
+	if (MACH_IS_HADES)
+		bus_info = init_hades_pci();
+#endif
+	if (bus_info != NULL)
+	{
+		printk("PCI: Probing PCI hardware\n");
+		pci_scan_bus(0, bus_info->m68k_pci_ops, bus_info);
+		pcibios_fixup();
+		pcibios_claim_resources(pci_root);
+	}
+	else
+		printk("PCI: No PCI bus detected\n");
+}
+
+char * __init pcibios_setup(char *str)
+{
+	if (!strcmp(str, "nomodify"))
+	{
+		pci_modify = 0;
+		return NULL;
+	}
+	else if (!strcmp(str, "skipvga"))
+	{
+		skip_vga = 1;
+		return NULL;
+	}
+	else if (!strcmp(str, "noburst"))
+	{
+		disable_pci_burst = 1;
+		return NULL;
+	}
+
+	return str;
+}
+#endif /* CONFIG_PCI */
diff -urN linux-2.4.29/arch/m68knommu/kernel/console.c linux-2.4.29-uc1/arch/m68knommu/kernel/console.c
--- linux-2.4.29/arch/m68knommu/kernel/console.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/kernel/console.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,2670 @@
+
+/*
+ *  linux/drivers/char/console.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+/*
+ *	console.c
+ *
+ * This module exports the console io functions:
+ *
+ *     'void do_keyboard_interrupt(void)'
+ *
+ *     'int vc_allocate(unsigned int console)'
+ *     'int vc_cons_allocated(unsigned int console)'
+ *     'int vc_resize(unsigned long lines, unsigned long cols)'
+ *     'int vc_resize_con(unsigned long lines, unsigned long cols,
+ *			  unsigned int currcons)'
+ *     'void vc_disallocate(unsigned int currcons)'
+ *
+ *     'unsigned long con_init(unsigned long)'
+ *     'int con_open(struct tty_struct *tty, struct file * filp)'
+ *     'void con_write(struct tty_struct * tty)'
+ *     'void console_print(const char * b)'
+ *     'void update_screen(int new_console)'
+ *
+ *     'void do_blank_screen(int)'
+ *     'void do_unblank_screen(void)'
+ *     'void poke_blanked_console(void)'
+ *
+ *     'unsigned short *screen_pos(int currcons, int w_offset, int viewed)'
+ *     'void complement_pos(int currcons, int offset)'
+ *     'void invert_screen(int currcons, int offset, int count, int shift)'
+ *
+ *     'void scrollback(int lines)'
+ *     'void scrollfront(int lines)'
+ *
+ *     'int con_get_font(char *)' 
+ *     'int con_set_font(char *)'
+ * 
+ *     'void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)'
+ *     'int mouse_reporting(void)'
+ *
+ *     'unsigned long get_video_num_lines(unsigned int console)'
+ *     'unsigned long get_video_num_columns(unsigned int console)'
+ *     'unsigned long get_video_size_row(unsigned int console)'
+ *
+ * Hopefully this will be a rather complete VT102 implementation.
+ *
+ * Beeping thanks to John T Kohl.
+ *
+ * Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics
+ *   Chars, and VT100 enhancements by Peter MacDonald.
+ *
+ * Copy and paste function by Andrew Haylett,
+ *   some enhancements by Alessandro Rubini.
+ *
+ * User definable mapping table and font loading by Eugene G. Crosser,
+ * <crosser@pccross.msk.su>
+ *
+ * Code to check for different video-cards mostly by Galen Hunt,
+ * <g-hunt@ee.utah.edu>
+ *
+ * Rudimentary ISO 10646/Unicode/UTF-8 character set support by
+ * Markus Kuhn, <mskuhn@immd4.informatik.uni-erlangen.de>.
+ *
+ * Dynamic allocation of consoles, aeb@cwi.nl, May 1994
+ * Resizing of consoles, aeb, 940926
+ *
+ * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
+ * <poe@daimi.aau.dk>
+ *
+ * 680x0 LINUX support by Arno Griffioen (arno@usn.nl)
+ *
+ * 9-Apr-94:  Arno Griffioen: fixed scrolling and delete-char bug.
+ *            Scrolling code moved to amicon.c
+ *
+ * 18-Apr-94: David Carter [carter@cs.bris.ac.uk]. 680x0 LINUX modified 
+ *            Integrated support for new low level driver `amicon_ocs.c'
+ *
+ */
+
+#define BLANK 0x0020
+#define CAN_LOAD_EGA_FONTS    /* undefine if the user must not do this */
+
+/* A bitmap for codes <32. A bit of 1 indicates that the code
+ * corresponding to that bit number invokes some special action
+ * (such as cursor movement) and should not be displayed as a
+ * glyph unless the disp_ctrl mode is explicitly enabled.
+ */
+#define CTRL_ACTION 0x0d00ff81
+#define CTRL_ALWAYS 0x0800f501	/* Cannot be overridden by disp_ctrl */
+
+/*
+ * Here is the default bell parameters: 750HZ, 1/8th of a second
+ */
+#define DEFAULT_BELL_PITCH	750
+#define DEFAULT_BELL_DURATION	(HZ/8)
+
+/*
+ *  NOTE!!! We sometimes disable and enable interrupts for a short while
+ * (to put a word in video IO), but this will work even for keyboard
+ * interrupts. We know interrupts aren't enabled when getting a keyboard
+ * interrupt, as we use trap-gates. Hopefully all is well.
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/console.h>
+#include <linux/kd.h>
+#include <linux/malloc.h>
+#include <linux/major.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include "../../../drivers/char/kbd_kern.h"
+#include "../../../drivers/char/vt_kern.h"
+#include "../../../drivers/char/consolemap.h"
+#include "../../../drivers/char/selection.h"
+
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+struct tty_driver console_driver;
+static int console_refcount;
+static struct tty_struct *console_table[MAX_NR_CONSOLES];
+static struct termios *console_termios[MAX_NR_CONSOLES];
+static struct termios *console_termios_locked[MAX_NR_CONSOLES];
+
+static void vc_init(unsigned int console, int do_clear);
+
+static void update_attr(int currcons);
+static void gotoxy(int currcons, int new_x, int new_y);
+static void save_cur(int currcons);
+static void blank_screen(void);
+static void unblank_screen(void);
+extern void change_console(unsigned int);
+static inline void set_cursor(int currcons);
+static void reset_terminal(int currcons, int do_clear);
+extern void reset_vc(unsigned int new_console);
+extern void vt_init(void);
+extern void register_console(void (*proc)(const char *));
+extern void vesa_blank(void);
+extern void vesa_unblank(void);
+extern void compute_shiftstate(void);
+void poke_blanked_console(void);
+void do_blank_screen(int);
+
+unsigned long	video_num_lines;
+unsigned long	video_num_columns;
+unsigned long	video_size_row;
+
+static int printable = 0;			/* Is console ready for printing? */
+unsigned long video_font_height;	/* Height of current screen font */
+unsigned long video_scan_lines;		/* Number of scan lines on screen */
+unsigned long default_font_height;      /* Height of default screen font */
+int	      video_mode_512ch = 0;	/* 512-character mode */
+static unsigned short console_charmask = 0x0ff;
+
+static unsigned short *vc_scrbuf[MAX_NR_CONSOLES];
+
+/* used by kbd_bh - set by keyboard_interrupt */
+       int do_poke_blanked_console = 0;
+       int console_blanked = 0;
+static int blankinterval = 10*60*HZ;
+static int vesa_off_interval = 0;
+static int vesa_blank_mode = 0; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
+
+static struct vc {
+	struct vc_data *d;
+
+	/* might add  scrmem, vt_struct, kbd  at some time,
+	   to have everything in one place - the disadvantage
+	   would be that vc_cons etc can no longer be static */
+} vc_cons [MAX_NR_CONSOLES];
+struct consw *conswitchp;
+
+#define cols            (vc_cons[currcons].d->vc_cols)
+#define rows            (vc_cons[currcons].d->vc_rows)
+#define size_row        (vc_cons[currcons].d->vc_size_row)
+#define screenbuf_size	(vc_cons[currcons].d->vc_screenbuf_size)
+#define cons_num	(vc_cons[currcons].d->vc_num)
+#define origin		(vc_cons[currcons].d->vc_origin)
+#define scr_end		(vc_cons[currcons].d->vc_scr_end)
+#define pos		(vc_cons[currcons].d->vc_pos)
+#define top		(vc_cons[currcons].d->vc_top)
+#define bottom		(vc_cons[currcons].d->vc_bottom)
+#define x		(vc_cons[currcons].d->vc_x)
+#define y		(vc_cons[currcons].d->vc_y)
+#define vc_state	(vc_cons[currcons].d->vc_state)
+#define npar		(vc_cons[currcons].d->vc_npar)
+#define par		(vc_cons[currcons].d->vc_par)
+#define ques		(vc_cons[currcons].d->vc_ques)
+#define attr		(vc_cons[currcons].d->vc_attr)
+#define saved_x		(vc_cons[currcons].d->vc_saved_x)
+#define saved_y		(vc_cons[currcons].d->vc_saved_y)
+#define translate	(vc_cons[currcons].d->vc_translate)
+#define G0_charset	(vc_cons[currcons].d->vc_G0_charset)
+#define G1_charset	(vc_cons[currcons].d->vc_G1_charset)
+#define saved_G0	(vc_cons[currcons].d->vc_saved_G0)
+#define saved_G1	(vc_cons[currcons].d->vc_saved_G1)
+#define utf		(vc_cons[currcons].d->vc_utf)
+#define utf_count	(vc_cons[currcons].d->vc_utf_count)
+#define utf_char	(vc_cons[currcons].d->vc_utf_char)
+#define video_mem_start	(vc_cons[currcons].d->vc_video_mem_start)
+#define video_mem_end	(vc_cons[currcons].d->vc_video_mem_end)
+#define video_erase_char (vc_cons[currcons].d->vc_video_erase_char)	
+#define disp_ctrl	(vc_cons[currcons].d->vc_disp_ctrl)
+#define toggle_meta	(vc_cons[currcons].d->vc_toggle_meta)
+#define decscnm		(vc_cons[currcons].d->vc_decscnm)
+#define decom		(vc_cons[currcons].d->vc_decom)
+#define decawm		(vc_cons[currcons].d->vc_decawm)
+#define deccm		(vc_cons[currcons].d->vc_deccm)
+#define decim		(vc_cons[currcons].d->vc_decim)
+#define deccolm	 	(vc_cons[currcons].d->vc_deccolm)
+#define need_wrap	(vc_cons[currcons].d->vc_need_wrap)
+#define has_scrolled	(vc_cons[currcons].d->vc_has_scrolled)
+#define kmalloced	(vc_cons[currcons].d->vc_kmalloced)
+#define report_mouse	(vc_cons[currcons].d->vc_report_mouse)
+#define can_do_color	(vc_cons[currcons].d->vc_can_do_color)
+#define color		(vc_cons[currcons].d->vc_color)
+#define s_color		(vc_cons[currcons].d->vc_s_color)
+#define def_color	(vc_cons[currcons].d->vc_def_color)
+#define	foreground	(color & 0x0f)
+#define background	(color & 0xf0)
+#define charset		(vc_cons[currcons].d->vc_charset)
+#define s_charset	(vc_cons[currcons].d->vc_s_charset)
+#define	intensity	(vc_cons[currcons].d->vc_intensity)
+#define	underline	(vc_cons[currcons].d->vc_underline)
+#define	blink		(vc_cons[currcons].d->vc_blink)
+#define	reverse		(vc_cons[currcons].d->vc_reverse)
+#define	s_intensity	(vc_cons[currcons].d->vc_s_intensity)
+#define	s_underline	(vc_cons[currcons].d->vc_s_underline)
+#define	s_blink		(vc_cons[currcons].d->vc_s_blink)
+#define	s_reverse	(vc_cons[currcons].d->vc_s_reverse)
+#define	ulcolor		(vc_cons[currcons].d->vc_ulcolor)
+#define	halfcolor	(vc_cons[currcons].d->vc_halfcolor)
+#define tab_stop	(vc_cons[currcons].d->vc_tab_stop)
+#define bell_pitch	(vc_cons[currcons].d->vc_bell_pitch)
+#define bell_duration	(vc_cons[currcons].d->vc_bell_duration)
+#define sw		(vc_cons[currcons].d->vc_sw)
+
+#define vcmode		(vt_cons[currcons]->vc_mode)
+#if 0 /* XXX */
+#define	vtmode		(vt_cons[currcons]->vt_mode)
+#define	vtpid		(vt_cons[currcons]->vt_pid)
+#define	vtnewvt		(vt_cons[currcons]->vt_newvt)
+#endif
+
+#define structsize	(sizeof(struct vc_data) + sizeof(struct vt_struct))
+
+int vc_cons_allocated(unsigned int i)
+{
+	return (i < MAX_NR_CONSOLES && vc_cons[i].d);
+}
+
+int vc_allocate(unsigned int currcons)		/* return 0 on success */
+{
+	if (currcons >= MAX_NR_CONSOLES)
+	  return -ENODEV;
+	if (!vc_cons[currcons].d) {
+	    long p, q;
+
+	    /* prevent users from taking too much memory */
+	    if (currcons >= MAX_NR_USER_CONSOLES && !suser())
+	      return -EPERM;
+
+	    /* due to the granularity of kmalloc, we waste some memory here */
+	    /* the alloc is done in two steps, to optimize the common situation
+	       of a 25x80 console (structsize=216, screenbuf_size=4000) */
+	    p = (long) kmalloc(structsize, GFP_KERNEL);
+	    if (!p)
+		return -ENOMEM;
+	    vc_cons[currcons].d = (struct vc_data *) p;
+	    vt_cons[currcons] = (struct vt_struct *)(p+sizeof(struct vc_data));
+
+	    /* ++Geert: sw->con_init determines console size */
+	    sw = conswitchp;
+	    cons_num = currcons;
+	    sw->con_init (vc_cons[currcons].d);
+	    size_row = cols<<1;
+	    screenbuf_size = rows*size_row;
+
+	    q = (long) kmalloc(screenbuf_size, GFP_KERNEL);
+	    if (!q) {
+		kfree_s((char *) p, structsize);
+		vc_cons[currcons].d = NULL;
+		return -ENOMEM;
+	    }
+	    vc_scrbuf[currcons] = (unsigned short *) q;
+	    kmalloced = 1;
+	    vc_init (currcons, 1);
+	}
+	return 0;
+}
+
+/*
+ * Change # of rows and columns (0 means the size of fg_console)
+ * [this is to be used together with some user program
+ * like resize that changes the hardware videomode]
+ */
+int vc_resize(unsigned long lines, unsigned long columns)
+{
+	unsigned long cc, ll, ss, sr;
+	unsigned long occ, oll, oss, osr;
+	unsigned short *p;
+	unsigned int currcons = fg_console, i;
+	unsigned short *newscreens[MAX_NR_CONSOLES];
+	long ol, nl, rlth, rrem;
+
+	cc = (columns ? columns : cols);
+	ll = (lines ? lines : rows);
+	sr = cc << 1;
+	ss = sr * ll;
+
+	/*
+	 * Some earlier version had all consoles of potentially
+	 * different sizes, but that was really messy.
+	 * So now we only change if there is room for all consoles
+	 * of the same size.
+	 */
+	for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
+	    if (!vc_cons_allocated(currcons))
+	      newscreens[currcons] = 0;
+	    else {
+		p = (unsigned short *) kmalloc(ss, GFP_USER);
+		if (!p) {
+		    for (i = 0; i< currcons; i++)
+		      if (newscreens[i])
+			kfree_s(newscreens[i], ss);
+		    return -ENOMEM;
+		}
+		newscreens[currcons] = p;
+	    }
+	}
+
+#if 0 /* XXX */
+	get_scrmem(fg_console);
+#endif
+
+	for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
+	    if (!vc_cons_allocated(currcons))
+	      continue;
+
+	    oll = rows;
+	    occ = cols;
+	    osr = size_row;
+	    oss = screenbuf_size;
+
+	    rows = ll;
+	    cols = cc;
+	    size_row = sr;
+	    screenbuf_size = ss;
+
+	    rlth = MIN(osr, sr);
+	    rrem = sr - rlth;
+	    ol = origin;
+	    nl = (long) newscreens[currcons];
+	    if (ll < oll)
+	      ol += (oll - ll) * osr;
+
+	    update_attr(currcons);
+	    while (ol < scr_end) {
+		/* ++Geert: TODO: Because the attributes have different meanings
+                   on monochrome and color, they should really be converted if
+                   can_do_color changes... */
+		memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
+		if (rrem)
+		  memsetw((void *)(nl + rlth), video_erase_char, rrem);
+		ol += osr;
+		nl += sr;
+	    }
+
+	    if (kmalloced)
+	      kfree_s(vc_scrbuf[currcons], oss);
+	    vc_scrbuf[currcons] = newscreens[currcons];
+	    kmalloced = 1;
+	    screenbuf_size = ss;
+
+	    origin = (long) video_mem_start = vc_scrbuf[currcons];
+	    scr_end = video_mem_end = ((long) video_mem_start) + ss;
+
+	    if (scr_end > nl)
+	      memsetw((void *) nl, video_erase_char, scr_end - nl);
+
+	    /* do part of a reset_terminal() */
+	    top = 0;
+	    bottom = rows;
+	    gotoxy(currcons, x, y);
+	    save_cur(currcons);
+	}
+
+#if 0 /* XXX */
+	set_scrmem(fg_console, 0);
+	set_origin(fg_console);
+#endif /* XXX */
+	update_screen(fg_console);
+	set_cursor(fg_console);
+
+	return 0;
+}
+
+/*
+ * ++Geert: Change # of rows and columns for one specific console.
+ * Of course it's not messy to have all consoles of potentially different sizes,
+ * except on PCish hardware :-)
+ *
+ * This is called by the low level console driver (arch/m68k/console/fbcon.c or
+ * arch/m68k/console/txtcon.c)
+ */
+void vc_resize_con(unsigned long lines, unsigned long columns,
+		   unsigned int currcons)
+{
+	unsigned long cc, ll, ss, sr;
+	unsigned long occ, oll, oss, osr;
+	unsigned short *newscreen;
+	long ol, nl, rlth, rrem;
+	struct winsize ws;
+
+	if (!columns || !lines || currcons >= MAX_NR_CONSOLES)
+	    return;
+
+	cc = columns;
+	ll = lines;
+	sr = cc << 1;
+	ss = sr * ll;
+
+	if (!vc_cons_allocated(currcons))
+	    newscreen = 0;
+	else if (!(newscreen = (unsigned short *) kmalloc(ss, GFP_USER)))
+	    return;
+
+	if (vc_cons_allocated(currcons)) {
+	    oll = rows;
+	    occ = cols;
+	    osr = size_row;
+	    oss = screenbuf_size;
+
+	    rows = ll;
+	    cols = cc;
+	    size_row = sr;
+	    screenbuf_size = ss;
+
+	    rlth = MIN(osr, sr);
+	    rrem = sr - rlth;
+	    ol = origin;
+	    nl = (long) newscreen;
+	    if (ll < oll)
+	      ol += (oll - ll) * osr;
+
+	    update_attr(currcons);
+	    while (ol < scr_end) {
+		/* ++Geert: TODO: Because the attributes have different meanings
+                   on monochrome and color, they should really be converted if
+                   can_do_color changes... */
+		memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
+		if (rrem)
+		  memsetw((void *)(nl + rlth), video_erase_char, rrem);
+		ol += osr;
+		nl += sr;
+	    }
+
+	    if (kmalloced)
+	      kfree_s(vc_scrbuf[currcons], oss);
+	    vc_scrbuf[currcons] = newscreen;
+	    kmalloced = 1;
+	    screenbuf_size = ss;
+
+	    origin = (long) video_mem_start = vc_scrbuf[currcons];
+	    scr_end = video_mem_end = ((long)video_mem_start) + ss;
+
+	    if (scr_end > nl)
+	      memsetw((void *) nl, video_erase_char, scr_end - nl);
+
+	    /* do part of a reset_terminal() */
+	    top = 0;
+	    bottom = rows;
+	    gotoxy(currcons, x, y);
+	    save_cur(currcons);
+
+	    ws.ws_row = rows;
+	    ws.ws_col = cols;
+	    if (memcmp(&ws, &console_table[currcons]->winsize, sizeof (struct winsize)) &&
+	        console_table[currcons]->pgrp > 0)
+		kill_pg(console_table[currcons]->pgrp, SIGWINCH, 1);
+	    console_table[currcons]->winsize = ws;
+	}
+
+   if (currcons == fg_console && vt_cons[fg_console]->vc_mode == KD_TEXT)
+      update_screen(fg_console);
+}
+
+void vc_disallocate(unsigned int currcons)
+{
+	if (vc_cons_allocated(currcons)) {
+	    if (kmalloced)
+	      kfree_s(vc_scrbuf[currcons], screenbuf_size);
+	    if (currcons >= MIN_NR_CONSOLES)
+	      kfree_s(vc_cons[currcons].d, structsize);
+	    vc_cons[currcons].d = 0;
+	}
+}
+
+
+#define set_kbd(x) set_vc_kbd_mode(kbd_table+currcons,x)
+#define clr_kbd(x) clr_vc_kbd_mode(kbd_table+currcons,x)
+#define is_kbd(x) vc_kbd_mode(kbd_table+currcons,x)
+
+#define decarm		VC_REPEAT
+#define decckm		VC_CKMODE
+#define kbdapplic	VC_APPLIC
+#define lnm		VC_CRLF
+
+/*
+ * this is what the terminal answers to a ESC-Z or csi0c query.
+ */
+#define VT100ID "\033[?1;2c"
+#define VT102ID "\033[?6c"
+
+static unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
+				       8,12,10,14, 9,13,11,15 };
+
+/*
+ * gotoxy() must verify all boundaries, because the arguments
+ * might also be negative. If the given position is out of
+ * bounds, the cursor is placed at the nearest margin.
+ */
+static void gotoxy(int currcons, int new_x, int new_y)
+{
+	int min_y, max_y;
+
+	if (new_x < 0)
+		x = 0;
+	else
+		if (new_x >= cols)
+			x = cols - 1;
+		else
+			x = new_x;
+ 	if (decom) {
+		min_y = top;
+		max_y = bottom;
+	} else {
+		min_y = 0;
+		max_y = rows;
+	}
+	if (new_y < min_y)
+		y = min_y;
+	else if (new_y >= max_y)
+		y = max_y - 1;
+	else
+		y = new_y;
+	pos = video_mem_start + y * cols + x;
+	need_wrap = 0;
+}
+
+/* for absolute user moves, when decom is set */
+static void gotoxay(int currcons, int new_x, int new_y)
+{
+	gotoxy(currcons, new_x, decom ? (top+new_y) : new_y);
+}
+
+static void hide_cursor(int currcons)
+{
+	sw->con_cursor(vc_cons[currcons].d,CM_ERASE);
+	return;
+}
+
+static void set_cursor(int currcons)
+{
+	if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
+		return;
+	if (deccm)
+		sw->con_cursor(vc_cons[currcons].d,CM_DRAW);
+	else
+		hide_cursor(currcons);
+	return;
+}
+
+void no_scroll(char *str, int *ints)
+{
+  /*
+   * no_scroll currently does nothing on the m68k.
+   */
+}
+
+/*
+ * Arno:
+ * Why do we need these? The keyboard code doesn't seem to do anything
+ * with them either...
+ */
+void scrollfront(int l)
+{
+	return;
+}
+
+void scrollback(int l)
+{
+	return;
+}
+
+static void scrup(int currcons, unsigned int t, unsigned int b,
+		  int nr)
+{
+	unsigned short *p;
+	int i;
+
+	if (b > rows || t >= b)
+		return;
+
+	memmove (video_mem_start + t * cols,
+		 video_mem_start + (t + nr) * cols,
+		 (b - t - nr) * cols * 2);
+
+	p = video_mem_start + (b - nr) * cols;
+	for (i = nr * cols; i > 0; i--)
+	  *p++ = video_erase_char;
+
+	if (currcons != fg_console)
+	  return;
+/*
+ * Arno:
+ * Scrolling has now been moved to amicon.c where it should have
+ * been all along.
+ */
+	sw->con_scroll(vc_cons[currcons].d, t, b, SM_UP, nr);
+
+	return;
+	
+}
+
+static void scrdown(int currcons, unsigned int t, unsigned int b,
+		    int nr)
+{
+	unsigned short *p;
+	int i;
+
+	if (b > rows || t >= b)
+		return;
+
+	memmove (video_mem_start + (t + nr) * cols,
+		 video_mem_start + t * cols,
+		 (b - t - nr) * cols * 2);
+
+	p = video_mem_start + t * cols;
+	for (i = nr * cols; i > 0; i--)
+	  *p++ = video_erase_char;
+
+	if (currcons != fg_console)
+	  return;
+/*
+ * Arno:
+ * Scrolling has now been moved to amicon.c where it should have
+ * been all along.
+ */
+	sw->con_scroll(vc_cons[currcons].d, t, b, SM_DOWN, nr);
+
+	return;
+}
+
+static void lf(int currcons)
+{
+    	/* don't scroll if above bottom of scrolling region, or
+	 * if below scrolling region
+	 */
+    	if (y+1 == bottom)
+		scrup(currcons,top,bottom, 1);
+	else if (y < rows-1) {
+	    	y++;
+		pos += cols;
+	}
+	need_wrap = 0;
+}
+
+static void ri(int currcons)
+{
+    	/* don't scroll if below top of scrolling region, or
+	 * if above scrolling region
+	 */
+	if (y == top)
+		scrdown(currcons,top,bottom, 1);
+	else if (y > 0) {
+		y--;
+		pos -= cols;
+	}
+	need_wrap = 0;
+}
+
+static inline void cr(int currcons)
+{
+	pos -= x;
+	need_wrap = x = 0;
+}
+
+static inline void bs(int currcons)
+{
+	if (x) {
+		pos--;
+		x--;
+		need_wrap = 0;
+	}
+}
+
+static inline void del(int currcons)
+{
+	/* ignored */
+}
+
+static void csi_J(int currcons, int vpar)
+{
+	unsigned long count;
+	unsigned short *start;
+
+	switch (vpar) {
+		case 0:	/* erase from cursor to end of display */
+			count = (video_mem_start
+				 + cols * rows
+				 - pos);
+			start = pos;
+			if (currcons != fg_console)
+			  break;
+			/* 680x0 do in two stages */
+			sw->con_clear(vc_cons[currcons].d,y,x,1,cols-x);
+			sw->con_clear(vc_cons[currcons].d,y+1,0,rows-y-1, cols);
+			break;
+		case 1:	/* erase from start to cursor */
+			count = pos - video_mem_start + 1;
+			start = video_mem_start;
+			if (currcons != fg_console)
+			  break;
+			/* 680x0 do in two stages */
+			sw->con_clear(vc_cons[currcons].d,0,0,y, cols);
+			sw->con_clear(vc_cons[currcons].d,y,0,1,x + 1);
+			break;
+		case 2: /* erase whole display */
+			count = cols * rows;
+			start = video_mem_start;
+			if (currcons != fg_console)
+			  break;
+			sw->con_clear(vc_cons[currcons].d,0,0,rows, cols);
+			break;
+		default:
+			return;
+	}
+	while (count-- > 0)
+	  *start++ = video_erase_char;
+	need_wrap = 0;
+}
+
+static void csi_K(int currcons, int vpar)
+{
+	unsigned long count;
+	unsigned short *start;
+
+	switch (vpar) {
+		case 0:	/* erase from cursor to end of line */
+			count = cols - x;
+			start = pos;
+			if (currcons != fg_console)
+			  break;
+			sw->con_clear(vc_cons[currcons].d,y,x,1,cols-x);
+			break;
+		case 1:	/* erase from start of line to cursor */
+			start = pos - x;
+			count = x + 1;
+			if (currcons != fg_console)
+			  break;
+			sw->con_clear(vc_cons[currcons].d,y,0,1,x + 1);
+			break;
+		case 2: /* erase whole line */
+			start = pos - x;
+			count = cols;
+			if (currcons != fg_console)
+			  break;
+			sw->con_clear(vc_cons[currcons].d,y,0,1,cols);
+			break;
+		default:
+			return;
+	}
+	while (count-- > 0)
+	  *start++ = video_erase_char;
+	need_wrap = 0;
+}
+
+static void csi_X(int currcons, int vpar) /* erase the following vpar positions */
+{					  /* not vt100? */
+	unsigned long count;
+	unsigned short * start;
+
+	if (!vpar)
+		vpar++;
+
+	start=pos;
+	count=(vpar > cols-x) ? (cols-x) : vpar;
+
+	if (currcons == fg_console)
+		sw->con_clear(vc_cons[currcons].d,y,x,1,count);
+
+	while (count-- > 0)
+		*start++ = video_erase_char;
+	need_wrap = 0;
+}
+
+/*
+ * Arno: 
+ * On 680x0 attributes are currently not used. This piece of code
+ * seems hardware independent, but uses the EGA/VGA way of representing
+ * attributes. 
+ * TODO: modify for 680x0 and add attribute processing to putc code.
+ *
+ * ++roman: I completely changed the attribute format for monochrome
+ * mode (!can_do_color). The formerly used MDA (monochrome display
+ * adapter) format didn't allow the combination of certain effects.
+ * Now the attribute is just a bit vector:
+ *  Bit 0..1: intensity (0..2)
+ *  Bit 2   : underline
+ *  Bit 3   : reverse
+ *  Bit 7   : blink
+ */
+static void update_attr(int currcons)
+{
+	if (!can_do_color) {
+		/* Special treatment for monochrome */
+		attr = intensity |
+			(underline ? 4 : 0) |
+			((reverse ^ decscnm) ? 8 : 0) |
+			(blink ? 0x80 : 0);
+		video_erase_char = ' ' | ((reverse ^ decscnm) ? 0x800 : 0);
+		return;
+	}
+
+	attr = color;
+	if (underline)
+		attr = (attr & 0xf0) | ulcolor;
+	else if (intensity == 0)
+		attr = (attr & 0xf0) | halfcolor;
+	if (reverse ^ decscnm)
+		attr = reverse_video_char(attr);
+	if (blink)
+		attr ^= 0x80;
+	if (intensity == 2)
+		attr ^= 0x08;
+	if (decscnm)
+		video_erase_char = (reverse_video_char(color) << 8) | ' ';
+	else
+		video_erase_char = (color << 8) | ' ';
+}
+
+static void default_attr(int currcons)
+{
+	intensity = 1;
+	underline = 0;
+	reverse = 0;
+	blink = 0;
+	color = def_color;
+}
+
+static void csi_m(int currcons)
+{
+	int i;
+
+	for (i=0;i<=npar;i++)
+		switch (par[i]) {
+			case 0:	/* all attributes off */
+				default_attr(currcons);
+				break;
+			case 1:
+				intensity = 2;
+				break;
+			case 2:
+				intensity = 0;
+				break;
+			case 4:
+				underline = 1;
+				break;
+			case 5:
+				blink = 1;
+				break;
+			case 7:
+				reverse = 1;
+				break;
+			case 10: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Select primary font, don't display
+				  * control chars if defined, don't set
+				  * bit 8 on output.
+				  */
+				translate = set_translate(charset == 0
+						? G0_charset
+						: G1_charset);
+				disp_ctrl = 0;
+				toggle_meta = 0;
+				break;
+			case 11: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Select first alternate font, let's
+				  * chars < 32 be displayed as ROM chars.
+				  */
+				translate = set_translate(IBMPC_MAP);
+				disp_ctrl = 1;
+				toggle_meta = 0;
+				break;
+			case 12: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Select second alternate font, toggle
+				  * high bit before displaying as ROM char.
+				  */
+				translate = set_translate(IBMPC_MAP);
+				disp_ctrl = 1;
+				toggle_meta = 1;
+				break;
+			case 21:
+			case 22:
+				intensity = 1;
+				break;
+			case 24:
+				underline = 0;
+				break;
+			case 25:
+				blink = 0;
+				break;
+			case 27:
+				reverse = 0;
+				break;
+			case 38: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Enables underscore, white foreground
+				  * with white underscore (Linux - use
+				  * default foreground).
+				  */
+				color = (def_color & 0x0f) | background;
+				underline = 1;
+				break;
+			case 39: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Disable underline option.
+				  * Reset colour to default? It did this
+				  * before...
+				  */
+				color = (def_color & 0x0f) | background;
+				underline = 0;
+				break;
+			case 49:
+				color = (def_color & 0xf0) | foreground;
+				break;
+			default:
+				if (par[i] >= 30 && par[i] <= 37)
+					color = color_table[par[i]-30]
+						| background; 
+				else if (par[i] >= 40 && par[i] <= 47)
+					color = (color_table[par[i]-40]<<4)
+						| foreground;
+				break;
+		}
+	update_attr(currcons);
+}
+
+static void respond_string(const char * p, struct tty_struct * tty)
+{
+	while (*p) {
+		tty_insert_flip_char(tty, *p, 0);
+		p++;
+	}
+	tty_schedule_flip(tty);
+}
+
+static void cursor_report(int currcons, struct tty_struct * tty)
+{
+	char buf[40];
+
+	sprintf(buf, "\033[%ld;%ldR", y + (decom ? top+1 : 1), x+1);
+	respond_string(buf, tty);
+}
+
+static inline void status_report(struct tty_struct * tty)
+{
+	respond_string("\033[0n", tty);	/* Terminal ok */
+}
+
+static inline void respond_ID(struct tty_struct * tty)
+{
+	respond_string(VT102ID, tty);
+}
+
+void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)
+{
+	char buf[8];
+
+	sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
+		(char)('!' + mry));
+	respond_string(buf, tty);
+}
+
+/* invoked via ioctl(TIOCLINUX) */
+int mouse_reporting(void)
+{
+	int currcons = fg_console;
+
+	return report_mouse;
+}
+
+static inline unsigned short *screenpos(int currcons, int offset, int viewed)
+{
+	unsigned short *p = (unsigned short *)(origin + offset);
+#if 0
+	if (viewed && currcons == fg_console)
+		p -= (__real_origin - __origin);
+#endif
+	return p;
+}
+
+/* Note: inverting the screen twice should revert to the original state */
+void invert_screen(int currcons, int offset, int count, int viewed)
+{
+	unsigned short *p;
+	unsigned short xx, yy, oldattr;
+
+	count /= 2;
+	p = screenpos(currcons, offset, viewed);
+	xx = (offset >> 1) % cols;
+	yy = (offset >> 1) / cols;
+	oldattr = attr;
+	if (can_do_color)
+		while (count--) {
+			unsigned short old = scr_readw(p);
+			unsigned short new = reverse_video_short(old);
+			scr_writew(new, p);
+			p++;
+			if (currcons != fg_console)
+				continue;
+			attr = new >> 8;
+			sw->con_putc(vc_cons[currcons].d, new & 0xff, yy, xx);
+			if (++xx == cols)
+				xx = 0, ++yy;
+		}
+	else
+		while (count--) {
+			unsigned short old = scr_readw(p);
+			unsigned short new = old ^ 0x800;
+			scr_writew(new, p);
+			p++;
+			if (currcons != fg_console)
+				continue;
+			attr = new >> 8;
+			sw->con_putc(vc_cons[currcons].d, new & 0xff, yy, xx);
+			if (++xx == cols)
+				xx = 0, ++yy;
+		}
+	attr = oldattr;
+}
+
+/* used by selection: complement pointer position */
+void complement_pos(int currcons, int offset)
+{
+	static unsigned short *p = NULL;
+	static unsigned short old = 0;
+	static unsigned short oldx = 0, oldy = 0;
+	unsigned short new, oldattr;
+
+	oldattr = attr;
+	if (p) {
+		scr_writew(old, p);
+		if (currcons == fg_console) {
+			attr = old >> 8;
+			sw->con_putc(vc_cons[currcons].d, old & 0xff, oldy, oldx);
+			attr = oldattr;
+		}
+	}
+	if (offset == -1)
+		p = NULL;
+	else {
+		p = screenpos(currcons, offset, 1);
+		old = scr_readw(p);
+		oldx = (offset >> 1) % cols;
+		oldy = (offset >> 1) / cols;
+		if (can_do_color)
+			new = old ^ 0x7700;
+		else
+			new = old ^ 0x800;
+		scr_writew(new, p);
+		if (currcons == fg_console) {
+			attr = new >> 8;
+			sw->con_putc(vc_cons[currcons].d, new & 0xff, oldy, oldx);
+			attr = oldattr;
+		}
+	}
+}
+
+/* used by selection */
+unsigned short screen_word(int currcons, int offset, int viewed)
+{
+	return scr_readw(screenpos(currcons, offset, viewed));
+}
+
+/* used by selection - convert a screen word to a glyph number */
+int scrw2glyph(unsigned short scr_word)
+{
+	return ( video_mode_512ch )
+		? ((scr_word & 0x0800) >> 3) + (scr_word & 0x00ff)
+		: scr_word & 0x00ff;
+}
+
+/* used by vcs - note the word offset */
+unsigned short *screen_pos(int currcons, int w_offset, int viewed)
+{
+	return screenpos(currcons, 2 * w_offset, viewed);
+}
+
+void getconsxy(int currcons, char *p)
+{
+	p[0] = x;
+	p[1] = y;
+}
+
+void putconsxy(int currcons, char *p)
+{
+	gotoxy(currcons, p[0], p[1]);
+	set_cursor(currcons);
+}
+
+static void set_mode(int currcons, int on_off)
+{
+	int i;
+
+	for (i=0; i<=npar; i++)
+		if (ques) switch(par[i]) {	/* DEC private modes set/reset */
+			case 1:			/* Cursor keys send ^[Ox/^[[x */
+				if (on_off)
+					set_kbd(decckm);
+				else
+					clr_kbd(decckm); 
+				break;
+			case 3:	/* 80/132 mode switch unimplemented */
+				deccolm = on_off;
+#if 0
+				(void) vc_resize(rows, deccolm ? 132 : 80);
+				/* this alone does not suffice; some user mode
+				   utility has to change the hardware regs */
+#endif
+				break;
+			case 5:			/* Inverted screen on/off */
+				if (decscnm != on_off) {
+					decscnm = on_off;
+					invert_screen(currcons, 0, screenbuf_size, 0);
+					update_attr(currcons);
+				}
+				break;
+			case 6:			/* Origin relative/absolute */
+				decom = on_off;
+				gotoxay(currcons,0,0);
+				break;
+			case 7:			/* Autowrap on/off */
+				decawm = on_off;
+				break;
+			case 8:			/* Autorepeat on/off */
+				if (on_off)
+					set_kbd(decarm);
+				else
+					clr_kbd(decarm);
+				break;
+			case 9:
+				report_mouse = on_off ? 1 : 0;
+				break;
+			case 25:		/* Cursor on/off */
+				deccm = on_off;
+				set_cursor(currcons);
+				break;
+			case 1000:
+				report_mouse = on_off ? 2 : 0;
+				break;
+		} else switch(par[i]) {		/* ANSI modes set/reset */
+			case 3:			/* Monitor (display ctrls) */
+				disp_ctrl = on_off;
+				break;
+			case 4:			/* Insert Mode on/off */
+				decim = on_off;
+				break;
+			case 20:		/* Lf, Enter == CrLf/Lf */
+				if (on_off)
+					set_kbd(lnm);
+				else
+					clr_kbd(lnm);
+				break;
+		}
+}
+
+static void setterm_command(int currcons)
+{
+	switch(par[0]) {
+		case 1:	/* set color for underline mode */
+			if (can_do_color && par[1] < 16) {
+				ulcolor = color_table[par[1]];
+				if (underline)
+					update_attr(currcons);
+			}
+			break;
+		case 2:	/* set color for half intensity mode */
+			if (can_do_color && par[1] < 16) {
+				halfcolor = color_table[par[1]];
+				if (intensity == 0)
+					update_attr(currcons);
+			}
+			break;
+		case 8:	/* store colors as defaults */
+			def_color = attr;
+			default_attr(currcons);
+			update_attr(currcons);
+			break;
+		case 9:	/* set blanking interval */
+			blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
+			poke_blanked_console();
+			break;
+		case 10: /* set bell frequency in Hz */
+			if (npar >= 1)
+				bell_pitch = par[1];
+			else
+				bell_pitch = DEFAULT_BELL_PITCH;
+			break;
+		case 11: /* set bell duration in msec */
+			if (npar >= 1)
+				bell_duration = (par[1] < 2000) ?
+					par[1]*HZ/1000 : 0;
+			else
+				bell_duration = DEFAULT_BELL_DURATION;
+			break;
+		case 12: /* bring specified console to the front */
+			if (par[1] >= 1 && vc_cons_allocated(par[1]-1))
+				update_screen(par[1]-1);
+			break;
+		case 13: /* unblank the screen */
+			unblank_screen();
+			break;
+		case 14: /* set vesa powerdown interval */
+			vesa_off_interval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
+			break;
+	}
+}
+
+static void insert_char(int currcons)
+{
+	int i;
+	unsigned short *p = pos;
+
+	for (i = cols - x - 2; i >= 0; i--)
+	  p[i + 1] = p[i];
+	*pos = video_erase_char;
+	need_wrap = 0;
+
+	if (currcons != fg_console)
+	  return;
+
+	/* Arno:
+	 * Move the remainder of the line (-1 character) one spot to the right
+	 */
+	sw->con_bmove(vc_cons[currcons].d,y,x,y,x+1,1,(cols-x-1));
+	/*
+	 * Print the erase char on the current position
+	 */
+	sw->con_putc(vc_cons[currcons].d,(video_erase_char & 0x00ff),y,x);
+}
+
+static void csi_at(int currcons, unsigned int nr)
+{
+	int i;
+	unsigned short *p;
+
+	if (nr > cols - x)
+		nr = cols - x;
+	else if (!nr)
+		nr = 1;
+
+	p = pos + cols - x - nr;
+	while (--p >= pos)
+	  p[nr] = *p;
+	for (i = 0; i < nr; i++)
+	  *++p = video_erase_char;
+	need_wrap = 0;
+
+	if (currcons != fg_console)
+	  return;
+
+	sw->con_bmove (vc_cons[currcons].d, y, x, y, x + nr,
+		       1, cols - x - nr);
+	while (nr--)
+	  sw->con_putc (vc_cons[currcons].d, video_erase_char & 0x00ff,
+			y, x + nr);
+}
+
+static void csi_L(int currcons, unsigned int nr)
+{
+	if (nr > rows)
+		nr = rows;
+	else if (!nr)
+		nr = 1;
+	scrdown (currcons, y, bottom, nr);
+	need_wrap = 0;
+}
+
+static void csi_P(int currcons, unsigned int nr)
+{
+	int i;
+	unsigned short *p, *end;
+
+	if (nr > cols - x)
+		nr = cols - x;
+	else if (!nr)
+		nr = 1;
+
+	p = pos;
+	end = pos + cols - x - nr;
+	while (p < end)
+	  *p = p[nr], p++;
+	for (i = 0; i < nr; i++)
+	  *p++ = video_erase_char;
+	need_wrap = 0;
+
+	if (currcons != fg_console)
+	  return;
+
+	sw->con_bmove (vc_cons[currcons].d, y, x + nr, y, x,
+		       1, cols - x - nr);
+
+	while (nr--)
+	  sw->con_putc (vc_cons[currcons].d, video_erase_char & 0x00ff,
+			y, cols - 1 - nr);
+}
+
+static void csi_M(int currcons, unsigned int nr)
+{
+	if (nr > rows)
+		nr = rows;
+	else if (!nr)
+		nr=1;
+	scrup (currcons, y, bottom, nr);
+	need_wrap = 0;
+}
+
+static void save_cur(int currcons)
+{
+	saved_x		= x;
+	saved_y		= y;
+	s_intensity	= intensity;
+	s_underline	= underline;
+	s_blink		= blink;
+	s_reverse	= reverse;
+	s_charset	= charset;
+	s_color		= color;
+	saved_G0	= G0_charset;
+	saved_G1	= G1_charset;
+}
+
+static void restore_cur(int currcons)
+{
+	gotoxy(currcons,saved_x,saved_y);
+	intensity	= s_intensity;
+	underline	= s_underline;
+	blink		= s_blink;
+	reverse		= s_reverse;
+	charset		= s_charset;
+	color		= s_color;
+	G0_charset	= saved_G0;
+	G1_charset	= saved_G1;
+	translate	= set_translate(charset ? G1_charset : G0_charset);
+	update_attr(currcons);
+	need_wrap = 0;
+}
+
+enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey, 
+	EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
+	ESpalette };
+
+static void reset_terminal(int currcons, int do_clear)
+{
+	top		= 0;
+	bottom		= rows;
+	vc_state	= ESnormal;
+	ques		= 0;
+	translate	= set_translate(LAT1_MAP);
+	G0_charset	= LAT1_MAP;
+	G1_charset	= GRAF_MAP;
+	charset		= 0;
+	need_wrap	= 0;
+	report_mouse	= 0;
+	utf             = 0;
+	utf_count       = 0;
+
+	disp_ctrl	= 0;
+	toggle_meta	= 0;
+
+	decscnm		= 0;
+	decom		= 0;
+	decawm		= 1;
+	deccm		= 1;
+	decim		= 0;
+
+	set_kbd(decarm);
+	clr_kbd(decckm);
+	clr_kbd(kbdapplic);
+	clr_kbd(lnm);
+	kbd_table[currcons].lockstate = 0;
+	kbd_table[currcons].slockstate = 0;
+	kbd_table[currcons].ledmode = LED_SHOW_FLAGS;
+	kbd_table[currcons].ledflagstate = kbd_table[currcons].default_ledflagstate;
+	set_leds();
+
+	default_attr(currcons);
+	update_attr(currcons);
+
+	tab_stop[0]	= 0x01010100;
+	tab_stop[1]	=
+	tab_stop[2]	=
+	tab_stop[3]	=
+	tab_stop[4]	= 0x01010101;
+
+	bell_pitch = DEFAULT_BELL_PITCH;
+	bell_duration = DEFAULT_BELL_DURATION;
+
+	gotoxy(currcons,0,0);
+	save_cur(currcons);
+	if (do_clear)
+	    csi_J(currcons,2);
+}
+
+/*
+ * Turn the Scroll-Lock LED on when the tty is stopped
+ */
+static void con_stop(struct tty_struct *tty)
+{
+	int console_num;
+	if (!tty)
+		return;
+	console_num = MINOR(tty->device) - (tty->driver.minor_start);
+	if (!vc_cons_allocated(console_num))
+		return;
+	set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
+	set_leds();
+}
+
+/*
+ * Turn the Scroll-Lock LED off when the console is started
+ */
+static void con_start(struct tty_struct *tty)
+{
+	int console_num;
+	if (!tty)
+		return;
+	console_num = MINOR(tty->device) - (tty->driver.minor_start);
+	if (!vc_cons_allocated(console_num))
+		return;
+	clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
+	set_leds();
+}
+
+static int con_write(struct tty_struct * tty, int from_user,
+		     const unsigned char *buf, int count)
+{
+	int c, tc, ok, n = 0;
+	unsigned int currcons;
+	struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
+
+	currcons = vt->vc_num;
+	if (!vc_cons_allocated(currcons)) {
+		/* could this happen? */
+		static int error = 0;
+		if (!error) {
+			error = 1;
+			printk("con_write: tty %d not allocated\n", currcons+1);
+		}
+		return 0;
+	}
+
+	/* undraw cursor first */
+	if (currcons == fg_console)
+		hide_cursor(currcons);
+	
+	/* clear the selection */
+	if (currcons == sel_cons)
+		clear_selection();
+
+        disable_bh(CONSOLE_BH);
+	while (count) {
+		enable_bh(CONSOLE_BH);
+		c = from_user ? get_user(buf) : *buf;
+		buf++; n++; count--;
+		disable_bh(CONSOLE_BH);
+
+		if (utf) {
+		    /* Combine UTF-8 into Unicode */
+		    /* Incomplete characters silently ignored */
+		    if(c > 0x7f) {   
+			if (utf_count > 0 && (c & 0xc0) == 0x80) {
+				utf_char = (utf_char << 6) | (c & 0x3f);
+				utf_count--;
+				if (utf_count == 0)
+				    tc = c = utf_char;
+				else continue;
+			} else {
+				if ((c & 0xe0) == 0xc0) {
+				    utf_count = 1;
+				    utf_char = (c & 0x1f);
+				} else if ((c & 0xf0) == 0xe0) {
+				    utf_count = 2;
+				    utf_char = (c & 0x0f);
+				} else if ((c & 0xf8) == 0xf0) {
+				    utf_count = 3;
+				    utf_char = (c & 0x07);
+				} else if ((c & 0xfc) == 0xf8) {
+				    utf_count = 4;
+				    utf_char = (c & 0x03);
+				} else if ((c & 0xfe) == 0xfc) {
+				    utf_count = 5;
+				    utf_char = (c & 0x01);
+				} else
+				    utf_count = 0;
+				continue;
+			}
+		    } else {
+			tc = c;
+			utf_count = 0;
+		    }
+		} else {	/* no utf */
+		    tc = translate[toggle_meta ? (c|0x80) : c];
+		}
+
+                /* If the original code was a control character we
+                 * only allow a glyph to be displayed if the code is
+                 * not normally used (such as for cursor movement) or
+                 * if the disp_ctrl mode has been explicitly enabled.
+                 * Certain characters (as given by the CTRL_ALWAYS
+                 * bitmap) are always displayed as control characters,
+                 * as the console would be pretty useless without
+                 * them; to display an arbitrary font position use the
+                 * direct-to-font zone in UTF-8 mode.
+                 */
+                ok = tc && (c >= 32 ||
+                            (!utf && !(((disp_ctrl ? CTRL_ALWAYS
+                                         : CTRL_ACTION) >> c) & 1)))
+                        && (c != 127 || disp_ctrl);
+
+		if (vc_state == ESnormal && ok) {
+			/* Now try to find out how to display it */
+			tc = conv_uni_to_pc(tc);
+			if ( tc == -4 ) {
+                                /* If we got -4 (not found) then see if we have
+                                   defined a replacement character (U+FFFD) */
+                                tc = conv_uni_to_pc(0xfffd);
+                        } else if ( tc == -3 ) {
+                                /* Bad hash table -- hope for the best */
+                                tc = c;
+                        }
+			if (tc & ~console_charmask)
+				continue; /* Conversion failed */
+
+			if (need_wrap) {
+				cr(currcons);
+				lf(currcons);
+			}
+			
+#if 1 /* XXX */
+                        /* DPC: 1994-04-12
+                         *   Speed up overstrike mode, using new putcs.
+                         *
+                         * P.S. I hate 8 spaces per tab! Use Emacs!
+			 */
+			
+			/* Only use this for the foreground console,
+                           where we really draw the chars */
+
+                        if (count > 2 &&
+			    !decim && !utf && currcons == fg_console) { 
+				static char putcs_buf[256];
+				char   *p     = putcs_buf;
+				int putcs_count  = 1;
+				ushort nextx  = x + 1;
+
+				*p++ = tc;
+				*pos++ = tc | (attr << 8);
+				
+				if (nextx == cols) {
+					sw->con_putc(vc_cons[currcons].d,
+						     *putcs_buf, y, x);
+					pos--;
+					need_wrap = decawm;
+					continue;
+				}
+				
+				/* TAB TAB TAB - Arghh!!!! */
+				
+				while (count)
+				{
+					enable_bh(CONSOLE_BH);
+					c = from_user ? get_user(buf) : *buf;
+					disable_bh(CONSOLE_BH);
+					tc = translate[toggle_meta ? (c|0x80) : c];
+					if (!tc ||
+					    !(c >= 32
+					      || !(((disp_ctrl ? CTRL_ALWAYS
+						   : CTRL_ACTION) >> c) & 1)))
+					  break;
+					tc = conv_uni_to_pc(tc);
+					if (tc == -4)
+					  tc = conv_uni_to_pc(0xfffd);
+					else if (tc == -3)
+					  tc = c;
+
+					buf++; n++; count--;
+					if (tc & ~console_charmask)
+					  continue; /* Conversion failed */
+
+					*p++ = tc;
+					*pos++ = tc | (attr << 8);
+					++putcs_count;
+					++nextx;
+					if (nextx == cols || 
+					    putcs_count == sizeof (putcs_buf))
+						break;
+				}
+				
+				sw->con_putcs(vc_cons[currcons].d,
+					      putcs_buf, putcs_count, y, x);
+				if (nextx == cols) {
+					pos--;
+					x         = cols-1;
+					need_wrap = decawm;
+				} else
+					x += putcs_count;
+				continue;
+                        }
+			
+                        /* DPC: End of putcs support */
+#endif
+			
+			if (decim)
+				insert_char(currcons);
+			*pos = (attr << 8) + tc;
+			if (currcons == fg_console)
+				sw->con_putc(vc_cons[currcons].d,tc,y,x);
+			if (x == cols - 1)
+				need_wrap = decawm;
+			else {
+				pos++;
+				x++;
+			}
+			continue;
+		}
+
+		/*
+		 *  Control characters can be used in the _middle_
+		 *  of an escape sequence.
+		 */
+		switch (c) {
+		    case 7:
+			if (bell_duration)
+			    kd_mksound(bell_pitch, bell_duration);
+			continue;
+		    case 8:
+			bs(currcons);
+			continue;
+		    case 9:
+			pos -= x;
+			while (x < cols - 1) {
+				x++;
+				if (tab_stop[x >> 5] & (1 << (x & 31)))
+					break;
+			}
+			pos += x;
+			continue;
+		    case 10: case 11: case 12:
+			lf(currcons);
+			if (!is_kbd(lnm))
+				continue;
+		    case 13:
+			cr(currcons);
+			continue;
+  			case 14:
+			charset = 1;
+			translate = set_translate(G1_charset);
+			disp_ctrl = 1;
+			continue;
+		    case 15:
+			charset = 0;
+			translate = set_translate(G0_charset);
+			disp_ctrl = 0;
+			continue;
+		    case 24: case 26:
+			vc_state = ESnormal;
+			continue;
+		    case 27:
+			vc_state = ESesc;
+			continue;
+		    case 127:
+			del(currcons);
+			continue;
+		    case 128+27:
+			vc_state = ESsquare;
+			continue;
+		}
+		switch(vc_state) {
+		    case ESesc:
+			vc_state = ESnormal;
+			switch (c) {
+			    case '[':
+				vc_state = ESsquare;
+				continue;
+			    case ']':
+				vc_state = ESnonstd;
+				continue;
+			    case '%':
+				vc_state = ESpercent;
+				continue;
+			    case 'E':
+				cr(currcons);
+				lf(currcons);
+				continue;
+			    case 'M':
+				ri(currcons);
+				continue;
+			    case 'D':
+				lf(currcons);
+				continue;
+			    case 'H':
+				tab_stop[x >> 5] |= (1 << (x & 31));
+				continue;
+			    case 'Z':
+				respond_ID(tty);
+				continue;
+			    case '7':
+				save_cur(currcons);
+				continue;
+			    case '8':
+				restore_cur(currcons);
+				continue;
+			    case '(':
+				vc_state = ESsetG0;
+				continue;
+			    case ')':
+				vc_state = ESsetG1;
+				continue;
+			    case '#':
+				vc_state = EShash;
+				continue;
+			    case 'c':
+				reset_terminal(currcons,1);
+				continue;
+			    case '>':  /* Numeric keypad */
+				clr_kbd(kbdapplic);
+				continue;
+			    case '=':  /* Appl. keypad */
+				set_kbd(kbdapplic);
+				continue;
+			}	
+			continue;
+		    case ESnonstd:
+			if (c=='P') {   /* palette escape sequence */
+			    for (npar=0; npar<NPAR; npar++)
+				par[npar] = 0 ;
+			    npar = 0 ;
+			    vc_state = ESpalette;
+			    continue;
+			} else if (c=='R') {   /* reset palette */
+#if 0
+			    reset_palette (currcons);
+#endif
+			    vc_state = ESnormal;
+			} else
+			    vc_state = ESnormal;
+			continue;
+		case ESpalette:
+			if ( (c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) {
+			    par[npar++] = (c>'9' ? (c&0xDF)-'A'+10 : c-'0') ;
+			    if (npar==7) {
+#if 0
+				int i = par[0]*3, j = 1;
+				palette[i] = 16*par[j++];
+				palette[i++] += par[j++];
+				palette[i] = 16*par[j++];
+				palette[i++] += par[j++];
+				palette[i] = 16*par[j++];
+				palette[i] += par[j];
+				set_palette() ;
+#endif
+				vc_state = ESnormal;
+			    }
+			} else
+			    vc_state = ESnormal;
+			continue;
+		    case ESsquare:
+			for(npar = 0 ; npar < NPAR ; npar++)
+				par[npar] = 0;
+			npar = 0;
+			vc_state = ESgetpars;
+			if (c == '[') { /* Function key */
+				vc_state=ESfunckey;
+				continue;
+			}
+			ques = (c=='?');
+			if (ques)
+				continue;
+		    case ESgetpars:
+			if (c==';' && npar<NPAR-1) {
+				npar++;
+				continue;
+			} else if (c>='0' && c<='9') {
+				par[npar] *= 10;
+				par[npar] += c-'0';
+				continue;
+			} else vc_state=ESgotpars;
+		    case ESgotpars:
+			vc_state = ESnormal;
+			switch(c) {
+			    case 'h':
+				set_mode(currcons,1);
+				continue;
+			    case 'l':
+				set_mode(currcons,0);
+				continue;
+			    case 'n':
+				if (!ques)
+					if (par[0] == 5)
+						status_report(tty);
+					else if (par[0] == 6)
+						cursor_report(currcons,tty);
+				continue;
+			}
+			if (ques) {
+				ques = 0;
+				continue;
+			}
+			switch(c) {
+			    case 'G': case '`':
+				if (par[0]) par[0]--;
+				gotoxy(currcons,par[0],y);
+				continue;
+			    case 'A':
+				if (!par[0]) par[0]++;
+				gotoxy(currcons,x,y-par[0]);
+				continue;
+			    case 'B': case 'e':
+				if (!par[0]) par[0]++;
+				gotoxy(currcons,x,y+par[0]);
+				continue;
+			    case 'C': case 'a':
+				if (!par[0]) par[0]++;
+				gotoxy(currcons,x+par[0],y);
+				continue;
+			    case 'D':
+				if (!par[0]) par[0]++;
+				gotoxy(currcons,x-par[0],y);
+				continue;
+			    case 'E':
+				if (!par[0]) par[0]++;
+				gotoxy(currcons,0,y+par[0]);
+				continue;
+			    case 'F':
+				if (!par[0]) par[0]++;
+				gotoxy(currcons,0,y-par[0]);
+				continue;
+			    case 'd':
+				if (par[0]) par[0]--;
+				gotoxay(currcons,x,par[0]);
+				continue;
+			    case 'H': case 'f':
+				if (par[0]) par[0]--;
+				if (par[1]) par[1]--;
+				gotoxay(currcons,par[1],par[0]);
+				continue;
+			    case 'J':
+				csi_J(currcons,par[0]);
+				continue;
+			    case 'K':
+				csi_K(currcons,par[0]);
+				continue;
+			    case 'L':
+				csi_L(currcons,par[0]);
+				continue;
+			    case 'M':
+				csi_M(currcons,par[0]);
+				continue;
+			    case 'P':
+				csi_P(currcons,par[0]);
+				continue;
+			    case 'c':
+				if (!par[0])
+					respond_ID(tty);
+				continue;
+			    case 'g':
+				if (!par[0])
+					tab_stop[x >> 5] &= ~(1 << (x & 31));
+				else if (par[0] == 3) {
+					tab_stop[0] =
+						tab_stop[1] =
+							tab_stop[2] =
+								tab_stop[3] =
+									tab_stop[4] = 0;
+				}
+				continue;
+			    case 'm':
+				csi_m(currcons);
+				continue;
+			    case 'q': /* DECLL - but only 3 leds */
+				/* map 0,1,2,3 to 0,1,2,4 */
+				if (par[0] < 4)
+					setledstate(kbd_table + currcons,
+						    (par[0] < 3) ? par[0] : 4);
+				continue;
+			    case 'r':
+				if (!par[0])
+					par[0]++;
+				if (!par[1])
+					par[1] = rows;
+				/* Minimum allowed region is 2 lines */
+				if (par[0] < par[1] &&
+				    par[1] <= rows) {
+					top=par[0]-1;
+					bottom=par[1];
+					gotoxay(currcons,0,0);
+				}
+				continue;
+			    case 's':
+				save_cur(currcons);
+				continue;
+			    case 'u':
+				restore_cur(currcons);
+				continue;
+			    case 'X':
+				csi_X(currcons, par[0]);
+				continue;
+			    case '@':
+				csi_at(currcons,par[0]);
+				continue;
+			    case ']': /* setterm functions */
+				setterm_command(currcons);
+				continue;
+			}
+			continue;
+		    case ESpercent:
+			vc_state = ESnormal;
+			switch (c) {
+			    case '@':  /* defined in ISO 2022 */
+				utf = 0;
+				continue;
+			    case 'G':  /* prelim official escape code */
+			    case '8':  /* retained for compatibility */
+				utf = 1;
+				continue;
+			}
+			continue;
+		    case ESfunckey:
+			vc_state = ESnormal;
+			continue;
+		    case EShash:
+			vc_state = ESnormal;
+			if (c == '8') {
+				/* DEC screen alignment test. kludge :-) */
+				video_erase_char =
+					(video_erase_char & 0xff00) | 'E';
+				/* Arno:
+				 * Doesn't work, because csi_J(c,2)
+				 * calls con_clear and doesn't print
+				 * the erase char..
+				 */
+				csi_J(currcons, 2);
+				video_erase_char =
+					(video_erase_char & 0xff00) | ' ';
+			}
+			continue;
+		    case ESsetG0:
+			if (c == '0')
+				G0_charset = GRAF_MAP;
+			else if (c == 'B')
+				G0_charset = LAT1_MAP;
+			else if (c == 'U')
+				G0_charset = IBMPC_MAP;
+			else if (c == 'K')
+				G0_charset = USER_MAP;
+			if (charset == 0)
+				translate = set_translate(G0_charset);
+			vc_state = ESnormal;
+			continue;
+		    case ESsetG1:
+			if (c == '0')
+				G1_charset = GRAF_MAP;
+			else if (c == 'B')
+				G1_charset = LAT1_MAP;
+			else if (c == 'U')
+				G1_charset = IBMPC_MAP;
+			else if (c == 'K')
+				G1_charset = USER_MAP;
+			if (charset == 1)
+				translate = set_translate(G1_charset);
+			vc_state = ESnormal;
+			continue;
+		    default:
+			vc_state = ESnormal;
+		}
+	}
+	if (vcmode != KD_GRAPHICS)
+		set_cursor(currcons);
+	enable_bh(CONSOLE_BH);
+	return n;
+}
+
+static int con_write_room(struct tty_struct *tty)
+{
+	if (tty->stopped)
+		return 0;
+	return 4096;		/* No limit, really; we're not buffering */
+}
+
+static int con_chars_in_buffer(struct tty_struct *tty)
+{
+	return 0;		/* we're not buffering */
+}
+
+void poke_blanked_console(void)
+{
+	timer_active &= ~(1<<BLANK_TIMER);
+	if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
+		return;
+	if (console_blanked) {
+		timer_table[BLANK_TIMER].fn = unblank_screen;
+		timer_table[BLANK_TIMER].expires = 0;
+		timer_active |= 1<<BLANK_TIMER;
+	} else if (blankinterval) {
+		timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
+		timer_active |= 1<<BLANK_TIMER;
+	}
+}
+
+/* DPC: New version of console_print using putcs */
+
+void console_print(const char * b)
+{
+   int currcons = fg_console;
+   unsigned char c;
+   const char *start = b;
+   ushort count      = 0;
+   ushort myx        = x;
+   static int printing = 0;
+
+   if (!printable || printing)
+	   return;	 /* console not yet initialized */
+   printing = 1;
+
+   if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
+	   currcons = kmsg_redirect - 1;
+
+   if (!vc_cons_allocated(currcons)) {
+	   /* impossible */
+	   printk("console_print: tty %d not allocated ??\n", currcons+1);
+	   printing = 0;
+	   return;
+   }
+
+   /* undraw cursor first */
+   hide_cursor(currcons);
+
+   /* Contrived structure to try to emulate original need_wrap behaviour
+    * Problems caused when we have need_wrap set on '\n' character */
+   
+   while ((c = *(b++)) != 0) {
+       if (c == 10 || c == 13 || c == 8 || need_wrap) {
+           if ((count = b - start - 1) > 0) {
+               sw->con_putcs(vc_cons[currcons].d, start, count ,
+                             y, x);
+               x += count;
+	       if (need_wrap)
+		 x--;
+           }
+
+	   if (c == 8) {	/* backspace */
+	       bs(currcons);
+	       start = b;
+	       myx = x;
+	       continue;
+	   }
+           if (c != 13)
+               lf(currcons);
+           cr(currcons);
+
+           if (c == 10 || c == 13) {
+               start = b; myx = x; continue;
+           }
+
+           start = b-1; myx = x;
+       }
+
+       *pos = c | (attr << 8);
+       if (myx == cols - 1) {
+           need_wrap = 1;
+           continue;
+       }
+       pos++;
+       myx++;
+   }
+
+   if ((count = b - start -1) > 0) {
+       sw->con_putcs(vc_cons[currcons].d, start, count ,
+                     y, x);
+       x += count;
+       if (x == cols)
+	 {
+	   x--;
+           need_wrap = 1;
+	 }
+   }
+   
+   set_cursor(currcons);
+   poke_blanked_console();
+   printing = 0;
+}
+
+/* You didn't see this... */
+void console_printn(const char * b, int n)
+{
+   int i;
+   char buf[2];
+   
+   
+   buf[1] = '\0';
+   for(i=0;i<n;i++) {
+     buf[0] = *b++;
+     console_print(buf);
+   }
+}
+
+/*
+ * con_throttle and con_unthrottle are only used for
+ * paste_selection(), which has to stuff in a large number of
+ * characters...
+ */
+static void con_throttle(struct tty_struct *tty)
+{
+}
+
+static void con_unthrottle(struct tty_struct *tty)
+{
+	struct vt_struct *vt = (struct vt_struct *) tty->driver_data;
+
+	wake_up_interruptible(&vt->paste_wait);
+}
+
+static void vc_init(unsigned int currcons, int do_clear)
+{
+	long base = (long) vc_scrbuf[currcons];
+
+	pos = (unsigned short *)(origin = (ulong)video_mem_start = base);
+	scr_end = base + screenbuf_size;
+	video_mem_end = base + screenbuf_size;
+	reset_vc(currcons);
+	def_color       = 0x07;   /* white */
+	ulcolor		= 0x0f;   /* bold white */
+	halfcolor       = 0x08;   /* grey */
+	vt_cons[currcons]->paste_wait = 0;
+	reset_terminal(currcons, do_clear);
+}
+
+/*
+ * This is the console switching bottom half handler.
+ *
+ * Doing console switching in a bottom half handler allows
+ * us to do the switches asynchronously (needed when we want
+ * to switch due to a keyboard interrupt), while still giving
+ * us the option to easily disable it to avoid races when we
+ * need to write to the console.
+ */
+static void console_bh(void)
+{
+	if (want_console >= 0) {
+		if (want_console != fg_console) {
+			change_console(want_console);
+			/* we only changed when the console had already
+			   been allocated - a new console is not created
+			   in an interrupt routine */
+		}
+		want_console = -1;
+	}
+	if (do_poke_blanked_console) { /* do not unblank for a LED change */
+		do_poke_blanked_console = 0;
+		poke_blanked_console();
+	}
+}
+
+/*
+ *  unsigned long con_init(unsigned long);
+ *
+ * This routine initializes console interrupts, and does nothing
+ * else. If you want the screen to clear, call tty_write with
+ * the appropriate escape-sequence.
+ *
+ * Reads the information preserved by setup.s to determine the current display
+ * type and sets everything accordingly.
+ */
+unsigned long con_init(unsigned long kmem_start)
+{
+
+#ifdef CONFIG_FRAMEBUFFER
+
+#if 0 /* Disable console unless some buttons are pressed */
+	{
+		int i;
+		for(i=0;i<200000;i++) {
+			__asm__("nop");
+			if ((*(volatile unsigned char*)0xFFFFF419) & (8|1))
+				break;
+		}
+		
+		if (!((*(volatile unsigned char*)0xFFFFF419) & (8|1)))
+			return;
+		}
+	}
+#endif	
+	char *display_desc = "????";
+	unsigned int currcons = 0;
+	extern int serial_debug;
+
+
+	
+	memset(&console_driver, 0, sizeof(struct tty_driver));
+	console_driver.magic = TTY_DRIVER_MAGIC;
+	console_driver.name = "tty";
+	console_driver.name_base = 1;
+	console_driver.major = TTY_MAJOR;
+#ifdef CONFIG_PILOT_CONSOLE
+	console_driver.minor_start = 1;
+#else
+	console_driver.minor_start = 2;
+#endif
+	console_driver.num = MAX_NR_CONSOLES;
+	console_driver.type = TTY_DRIVER_TYPE_CONSOLE;
+	console_driver.init_termios = tty_std_termios;
+	console_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
+	console_driver.refcount = &console_refcount;
+	console_driver.table = console_table;
+	console_driver.termios = console_termios;
+	console_driver.termios_locked = console_termios_locked;
+
+	console_driver.open = con_open;
+	console_driver.write = con_write;
+	console_driver.write_room = con_write_room;
+	console_driver.chars_in_buffer = con_chars_in_buffer;
+	console_driver.ioctl = vt_ioctl;
+	console_driver.stop = con_stop;
+	console_driver.start = con_start;
+	console_driver.throttle = con_throttle;
+	console_driver.unthrottle = con_unthrottle;
+	
+	if (tty_register_driver(&console_driver))
+		panic("Couldn't register console driver\n");
+
+	kmem_start = conswitchp->con_startup (kmem_start, &display_desc);
+	/*conswitchp->con_set_font (&display_desc, 0, 0, "MINI4x6");*/
+	
+	timer_table[BLANK_TIMER].fn = blank_screen;
+	timer_table[BLANK_TIMER].expires = 0;
+	if (blankinterval) {
+		timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
+		timer_active |= 1<<BLANK_TIMER;
+	}
+
+	/* Due to kmalloc roundup allocating statically is more efficient -
+	   so provide MIN_NR_CONSOLES for people with very little memory */
+	for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
+		vc_cons[currcons].d = (struct vc_data *) kmem_start;
+		kmem_start += sizeof(struct vc_data);
+		vt_cons[currcons] = (struct vt_struct *) kmem_start;
+		kmem_start += sizeof(struct vt_struct);
+
+		/* ++Geert: sw->con_init determines console size */
+		sw = conswitchp;
+		cons_num = currcons;
+		sw->con_init (vc_cons[currcons].d);
+		size_row = cols<<1;
+		screenbuf_size = rows*size_row;
+
+		vc_scrbuf[currcons] = (unsigned short *) kmem_start;
+		kmem_start += screenbuf_size;
+		kmalloced = 0;
+		vc_init(currcons, currcons);
+	}
+
+	currcons = fg_console = 0;
+
+#ifdef CONFIG_PILOT_CONSOLE
+
+	gotoxy(currcons,0,rows-1);
+
+	csi_J(currcons, 0);
+	printable = 1;
+	/*update_screen(fg_console);*/
+	sw->con_cursor(vc_cons[currcons].d, CM_DRAW);
+	printable = 1;
+
+	/* If "serdebug" cmd line option was present, don't register for printk */
+	if (!serial_debug)
+		register_console(console_print);
+
+	printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n",
+		can_do_color ? "colour":"mono",
+		display_desc,
+		cols,rows,
+		MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s", MAX_NR_CONSOLES);
+#else
+	gotoxy(currcons,0, 0);
+	printable = 1;
+	sw->con_cursor(vc_cons[currcons].d, CM_DRAW);
+	printable = 1;
+
+	printk("Console driver (without boot console): %s %s %ldx%ld, %d virtual console%s (max %d)\n",
+		can_do_color ? "colour":"mono",
+		display_desc,
+		cols,rows,
+		MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s", MAX_NR_CONSOLES);
+#endif
+	init_bh(CONSOLE_BH, console_bh);
+#endif
+	return kmem_start;
+}
+
+void vesa_powerdown_screen(void)
+{
+	int currcons = fg_console;
+
+	timer_active &= ~(1<<BLANK_TIMER);
+	timer_table[BLANK_TIMER].fn = unblank_screen;
+
+	/* Power down if currently suspended (1 or 2),
+	 * suspend if currently blanked (0),
+	 * else do nothing (i.e. already powered down (3)).
+	 * Called only if powerdown features are allowed.
+	 */
+	switch (vesa_blank_mode) {
+	case 0:
+		sw->con_blank(2);
+		break;
+	case 1:
+	case 2:
+		sw->con_blank(4);
+		break;
+	}
+}
+
+void do_blank_screen(int nopowersave)
+{
+#if 0
+	int currcons;
+
+	if (console_blanked)
+		return;
+
+	if (!vc_cons_allocated(fg_console)) {
+		/* impossible */
+		printk("blank_screen: tty %d not allocated ??\n", fg_console+1);
+		return;
+	}
+
+	/* don't blank graphics */
+	if (vt_cons[fg_console]->vc_mode == KD_TEXT) {
+		if (vesa_off_interval && !nopowersave) {
+			timer_table[BLANK_TIMER].fn = vesa_powerdown_screen;
+			timer_table[BLANK_TIMER].expires = jiffies + vesa_off_interval;
+			timer_active |= (1<<BLANK_TIMER);
+		} else {
+			timer_active &= ~(1<<BLANK_TIMER);
+			timer_table[BLANK_TIMER].fn = unblank_screen;
+		}
+
+		/* try not to lose information by blanking,
+		   and not to waste memory */
+		currcons = fg_console;
+		has_scrolled = 0;
+		sw->con_blank(1);
+		if (!nopowersave)
+			sw->con_blank(vesa_blank_mode + 1);
+	}
+	else
+		hide_cursor(fg_console);
+ 	console_blanked = fg_console + 1;
+#endif
+}
+
+void do_unblank_screen(void)
+{
+#if 0
+	int currcons;
+
+	if (!console_blanked)
+		return;
+	if (!vc_cons_allocated(fg_console)) {
+		/* impossible */
+		printk("unblank_screen: tty %d not allocated ??\n", fg_console+1);
+		return;
+	}
+	timer_table[BLANK_TIMER].fn = blank_screen;
+	if (blankinterval) {
+		timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
+		timer_active |= 1<<BLANK_TIMER;
+	}
+
+	currcons = fg_console;
+  	console_blanked = 0;
+	if (sw->con_blank (0))
+		/* Low-level driver cannot restore -> do it ourselves */
+	  	update_screen( fg_console );
+	set_cursor (fg_console);
+#endif
+}
+
+void update_screen(int new_console)
+{
+	int currcons = fg_console;
+	int xx, yy, startx, attr_save;
+	char buf[256], *bufp;
+	unsigned short *p;
+	static int lock = 0;
+
+	if (/* new_console == fg_console || */ lock)
+		return;
+	if (!vc_cons_allocated(new_console)) {
+		/* strange ... */
+		printk("update_screen: tty %d not allocated ??\n", new_console+1);
+		return;
+	}
+	lock = 1;
+
+	clear_selection();
+
+	currcons = fg_console = new_console;
+	sw->con_cursor (vc_cons[currcons].d, CM_ERASE);
+	sw->con_switch (vc_cons[new_console].d);
+	/* Update the screen contents */
+	p = video_mem_start;
+	attr_save = attr;
+	for (yy = 0; yy < rows; yy++)
+	  {
+	    bufp = buf;
+	    for (startx = xx = 0; xx < cols; xx++)
+	      {
+		if (attr != ((*p >> 8) & 0xff))
+		  {
+		    if (bufp > buf)
+		      sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
+				     yy, startx);
+		    startx = xx;
+		    bufp = buf;
+		    attr = (*p >> 8) & 0xff;
+		  }
+		*bufp++ = *p++;
+		if (bufp == buf + sizeof (buf))
+		  {
+		    sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
+				   yy, startx);
+		    startx = xx + 1;
+		    bufp = buf;
+		  }
+	      }
+	    if (bufp > buf)
+	      sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
+			     yy, startx);
+	  }
+	set_cursor (currcons);
+	attr = attr_save;
+	set_leds();
+	compute_shiftstate();
+	lock = 0;
+}
+
+/*
+ * If a blank_screen is due to a timer, then a power save is allowed.
+ * If it is related to console_switching, then avoid vesa_blank().
+ */
+static void blank_screen(void)
+{
+	do_blank_screen(0);
+}
+
+static void unblank_screen(void)
+{
+	do_unblank_screen();
+}
+
+/*
+ * Allocate the console screen memory.
+ */
+int con_open(struct tty_struct *tty, struct file * filp)
+{
+	unsigned int currcons;
+	int i;
+
+	currcons = MINOR(tty->device) - tty->driver.minor_start;
+	
+	i = vc_allocate(currcons);
+	if (i)
+		return i;
+
+	vt_cons[currcons]->vc_num = currcons;
+	tty->driver_data = vt_cons[currcons];
+	
+	if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
+		tty->winsize.ws_row = rows;
+		tty->winsize.ws_col = cols;
+ 	}
+
+	return 0;
+}
+
+/*
+ * PIO_FONT support.
+ *
+ * Currently we only support 8 pixels wide fonts, at a maximum height
+ * of 32 pixels. Userspace fontdata is stored with 32 bytes reserved
+ * for each character which is kinda wasty, but this is done in order
+ * to maintain compatibility with the EGA/VGA fonts. It is upto the
+ * actual low-level console-driver convert data into its favorite
+ * format (maybe we should add a `fontoffset' field to the `display'
+ * structure so we wont have to convert the fontdata all the time.
+ * /Jes
+ */
+
+#define cmapsz 8192
+
+static int set_get_font(char * arg, int set, int ch512)
+{
+#ifdef CAN_LOAD_EGA_FONTS
+	int i, unit, size;
+	char *charmap;
+
+	if (arg){
+		i = verify_area(set ? VERIFY_READ : VERIFY_WRITE,
+				(void *)arg, ch512 ? 2*cmapsz : cmapsz);
+		if (i)
+			return i;
+	}else
+		return -EINVAL;
+
+
+	size = ch512 ? 2*cmapsz : cmapsz;
+
+	charmap = (char *)kmalloc(size, GFP_USER);
+
+	if (set){
+		memcpy_fromfs(charmap, arg, size);
+
+		for (unit = 32; unit > 0; unit--)
+			for (i = 0; i < (ch512 ? 512 : 256); i++)
+				if (charmap[32*i+unit-1])
+					goto nonzero;
+	nonzero:
+		i = conswitchp->con_set_font(vc_cons[fg_console].d, 8,
+					     unit, charmap);
+	}else{
+		memset(charmap, 0, size);
+		i = conswitchp->con_get_font(vc_cons[fg_console].d,
+					     &unit, &unit, charmap);
+		memcpy_tofs(arg, charmap, size);
+	}
+	kfree(charmap);
+
+	return i;
+#else
+	return -EINVAL;
+#endif
+}
+
+/*
+ * Load palette into the EGA/VGA DAC registers. arg points to a colour
+ * map, 3 bytes per colour, 16 colours, range from 0 to 255.
+ */
+
+int con_set_cmap (unsigned char *arg)
+{
+	return -EINVAL;
+}
+
+int con_get_cmap (unsigned char *arg)
+{
+	return -EINVAL;
+}
+
+void reset_palette(int currcons)
+{
+}
+
+void set_palette(void)
+{
+}
+
+/*
+ * Load font into the EGA/VGA character generator. arg points to a 8192
+ * byte map, 32 bytes per character. Only first H of them are used for
+ * 8xH fonts (0 < H <= 32).
+ */
+
+int con_set_font (char *arg, int ch512)
+{
+	int i;
+
+	i = set_get_font (arg,1,ch512);
+  	if ( !i ) {
+		hashtable_contents_valid = 0;
+      		video_mode_512ch = ch512;
+      		console_charmask = ch512 ? 0x1ff : 0x0ff;
+	}
+	return i;
+}
+
+int con_get_font (char *arg)
+{
+	return set_get_font (arg,0,video_mode_512ch);
+}
+
+/*
+ * Adjust the screen to fit a font of a certain height
+ *
+ * Returns < 0 for error, 0 if nothing changed, and the number
+ * of lines on the adjusted console if changed.
+ */
+int con_adjust_height(unsigned long fontheight)
+{
+	return -EINVAL;
+}
+
+void set_vesa_blanking(int arg)
+{
+	char *argp = (char *)arg + 1;
+	unsigned int mode = get_fs_byte(argp);
+	vesa_blank_mode = (mode < 4) ? mode : 0;
+}
+
+unsigned long get_video_num_lines(unsigned int currcons)
+{
+	return(rows);
+}
+
+unsigned long get_video_num_columns(unsigned int currcons)
+{
+	return(cols);
+}
+
+unsigned long get_video_size_row(unsigned int currcons)
+{
+	return(size_row);
+}
+
+/*
+ * Report the current status of the vc. This is exported to modules (ARub)
+ */
+
+int con_get_info(int *mode, int *shift, int *col, int *row,
+			struct tty_struct **tty)
+{
+	extern int shift_state;
+	extern struct tty_driver console_driver;
+	struct tty_struct **console_table=console_driver.table;
+
+	if (mode) *mode = vt_cons[fg_console]->vc_mode;
+	if (shift) *shift = shift_state;
+	if (col) *col = video_num_columns;
+	if (row) *row = video_num_lines;
+	if (tty) *tty = console_table[fg_console];
+	return fg_console;
+}
diff -urN linux-2.4.29/arch/m68knommu/kernel/m68k_defs.c linux-2.4.29-uc1/arch/m68knommu/kernel/m68k_defs.c
--- linux-2.4.29/arch/m68knommu/kernel/m68k_defs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/kernel/m68k_defs.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,122 @@
+/*
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ */
+
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/hardirq.h>
+#if DAVIDM
+#include <asm/amigahw.h>
+#include <video/font.h>
+#endif
+
+#define DEFINE(sym, val) \
+	asm volatile("\n#define " #sym " %c0" : : "i" (val))
+
+int main(void)
+{
+	/* offsets into the task struct */
+	DEFINE(TASK_STATE, offsetof(struct task_struct, state));
+	DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
+	DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
+	DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
+	DEFINE(TASK_COUNTER, offsetof(struct task_struct, counter));
+	DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, sigpending));
+	DEFINE(TASK_NEEDRESCHED, offsetof(struct task_struct, need_resched));
+	DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
+	DEFINE(TASK_MM, offsetof(struct task_struct, mm));
+	DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
+
+	/* offsets into the thread struct */
+	DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
+	DEFINE(CPUSTAT_LOCAL_IRQ_COUNT, offsetof(irq_cpustat_t, __local_irq_count));
+
+	/* offsets into the thread struct */
+	DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
+	DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
+	DEFINE(THREAD_SR, offsetof(struct thread_struct, sr));
+	DEFINE(THREAD_FS, offsetof(struct thread_struct, fs));
+	DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp));
+	DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
+	DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp));
+	DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
+	DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
+
+	/* offsets into the pt_regs */
+	DEFINE(PT_D0, offsetof(struct pt_regs, d0));
+	DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0));
+	DEFINE(PT_D1, offsetof(struct pt_regs, d1));
+	DEFINE(PT_D2, offsetof(struct pt_regs, d2));
+	DEFINE(PT_D3, offsetof(struct pt_regs, d3));
+	DEFINE(PT_D4, offsetof(struct pt_regs, d4));
+	DEFINE(PT_D5, offsetof(struct pt_regs, d5));
+	DEFINE(PT_A0, offsetof(struct pt_regs, a0));
+	DEFINE(PT_A1, offsetof(struct pt_regs, a1));
+	DEFINE(PT_A2, offsetof(struct pt_regs, a2));
+	DEFINE(PT_PC, offsetof(struct pt_regs, pc));
+	DEFINE(PT_SR, offsetof(struct pt_regs, sr));
+	/* bitfields are a bit difficult */
+	DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) + 4);
+
+#ifndef CONFIG_COLDFIRE
+	/* offsets into the irq_handler struct */
+	DEFINE(IRQ_HANDLER, offsetof(struct irq_node, handler));
+	DEFINE(IRQ_DEVID, offsetof(struct irq_node, dev_id));
+	DEFINE(IRQ_NEXT, offsetof(struct irq_node, next));
+#endif
+
+	/* offsets into the kernel_stat struct */
+	DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
+
+#if DAVIDM
+	/* offsets into the bi_record struct */
+	DEFINE(BIR_TAG, offsetof(struct bi_record, tag));
+	DEFINE(BIR_SIZE, offsetof(struct bi_record, size));
+	DEFINE(BIR_DATA, offsetof(struct bi_record, data));
+
+	/* offsets into fbcon_font_desc (video/font.h) */
+	DEFINE(FBCON_FONT_DESC_IDX, offsetof(struct fbcon_font_desc, idx));
+	DEFINE(FBCON_FONT_DESC_NAME, offsetof(struct fbcon_font_desc, name));
+	DEFINE(FBCON_FONT_DESC_WIDTH, offsetof(struct fbcon_font_desc, width));
+	DEFINE(FBCON_FONT_DESC_HEIGHT, offsetof(struct fbcon_font_desc, height));
+	DEFINE(FBCON_FONT_DESC_DATA, offsetof(struct fbcon_font_desc, data));
+	DEFINE(FBCON_FONT_DESC_PREF, offsetof(struct fbcon_font_desc, pref));
+#endif
+
+	/* signal defines */
+	DEFINE(SIGSEGV, SIGSEGV);
+	DEFINE(SEGV_MAPERR, SEGV_MAPERR);
+	DEFINE(SIGTRAP, SIGTRAP);
+	DEFINE(TRAP_TRACE, TRAP_TRACE);
+
+	DEFINE(PT_PTRACED, PT_PTRACED);
+	DEFINE(PT_TRACESYS, PT_TRACESYS);
+	DEFINE(PT_DTRACE, PT_DTRACE);
+
+#if DAVIDM
+	/* offsets into the custom struct */
+	DEFINE(CUSTOMBASE, &custom);
+	DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar));
+	DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr));
+	DEFINE(C_INTENA, offsetof(struct CUSTOM, intena));
+	DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq));
+	DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr));
+	DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat));
+	DEFINE(C_SERPER, offsetof(struct CUSTOM, serper));
+	DEFINE(CIAABASE, &ciaa);
+	DEFINE(CIABBASE, &ciab);
+	DEFINE(C_PRA, offsetof(struct CIA, pra));
+	DEFINE(ZTWOBASE, zTwoBase);
+#endif
+
+	return 0;
+}
diff -urN linux-2.4.29/arch/m68knommu/kernel/m68k_defs.head linux-2.4.29-uc1/arch/m68knommu/kernel/m68k_defs.head
--- linux-2.4.29/arch/m68knommu/kernel/m68k_defs.head	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/kernel/m68k_defs.head	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * WARNING! This file is automatically generated - DO NOT EDIT!
+ */
+
+#define TS_MAGICKEY	0x5a5a5a5a
diff -urN linux-2.4.29/arch/m68knommu/kernel/m68k_ksyms.c linux-2.4.29-uc1/arch/m68knommu/kernel/m68k_ksyms.c
--- linux-2.4.29/arch/m68knommu/kernel/m68k_ksyms.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/kernel/m68k_ksyms.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,170 @@
+#include <linux/module.h>
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
+
+#include <asm/setup.h>
+#include <asm/machdep.h>
+#include <asm/pgalloc.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/semaphore.h>
+#include <asm/checksum.h>
+#include <asm/hardirq.h>
+#include <asm/softirq.h>
+#include <asm/current.h>
+#include <asm/delay.h>
+
+//asmlinkage long long __ashrdi3 (long long, int);
+//asmlinkage long long __lshrdi3 (long long, int);
+extern char m68k_debug_device[];
+
+extern void dump_thread(struct pt_regs *, struct user *);
+extern int dump_fpu(elf_fpregset_t *);
+
+/* platform dependent support */
+
+#if 0
+EXPORT_SYMBOL(m68k_machtype);
+EXPORT_SYMBOL(m68k_cputype);
+EXPORT_SYMBOL(m68k_is040or060);
+EXPORT_SYMBOL(cache_push);
+EXPORT_SYMBOL(cache_clear);
+#ifndef CONFIG_SINGLE_MEMORY_CHUNK
+EXPORT_SYMBOL(mm_vtop);
+EXPORT_SYMBOL(mm_ptov);
+EXPORT_SYMBOL(mm_end_of_chunk);
+#endif
+EXPORT_SYMBOL(m68k_realnum_memory);
+EXPORT_SYMBOL(m68k_memory);
+#endif
+#ifndef CONFIG_SUN3
+#if 0
+EXPORT_SYMBOL(mm_vtop_fallback);
+#endif
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
+#if 0
+EXPORT_SYMBOL(kernel_set_cachemode);
+#endif
+#endif
+#if 0
+EXPORT_SYMBOL(m68k_debug_device);
+#endif
+EXPORT_SYMBOL(dump_fpu);
+EXPORT_SYMBOL(dump_thread);
+EXPORT_SYMBOL(strnlen);
+EXPORT_SYMBOL(strrchr);
+EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strcat);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strcmp);
+EXPORT_SYMBOL(strncmp);
+
+EXPORT_SYMBOL(ip_fast_csum);
+
+#if 0
+EXPORT_SYMBOL(local_irq_count);
+EXPORT_SYMBOL(local_bh_count);
+#endif
+EXPORT_SYMBOL(mach_enable_irq);
+EXPORT_SYMBOL(mach_disable_irq);
+EXPORT_SYMBOL(kernel_thread);
+#ifdef CONFIG_VME
+EXPORT_SYMBOL(vme_brdtype);
+#endif
+
+/* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial_copy);
+
+/* Delay loops */
+EXPORT_SYMBOL(udelay);
+
+/* The following are special because they're not called
+   explicitly (the C compiler generates them).  Fortunately,
+   their interface isn't gonna change any time soon now, so
+   it's OK to leave it out of version control.  */
+//EXPORT_SYMBOL_NOVERS(__ashrdi3);
+//EXPORT_SYMBOL_NOVERS(__lshrdi3);
+EXPORT_SYMBOL_NOVERS(memcpy);
+EXPORT_SYMBOL_NOVERS(memset);
+EXPORT_SYMBOL_NOVERS(memcmp);
+EXPORT_SYMBOL_NOVERS(memscan);
+EXPORT_SYMBOL_NOVERS(memmove);
+
+EXPORT_SYMBOL_NOVERS(__down_failed);
+EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
+EXPORT_SYMBOL_NOVERS(__down_failed_trylock);
+EXPORT_SYMBOL_NOVERS(__up_wakeup);
+
+EXPORT_SYMBOL(get_wchan);
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler...  (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __gcc_bcmp(void);
+extern void __ashldi3(void);
+extern void __ashrdi3(void);
+extern void __cmpdi2(void);
+extern void __divdi3(void);
+extern void __divsi3(void);
+extern void __lshrdi3(void);
+extern void __moddi3(void);
+extern void __modsi3(void);
+extern void __muldi3(void);
+extern void __mulsi3(void);
+extern void __negdi2(void);
+extern void __ucmpdi2(void);
+extern void __udivdi3(void);
+extern void __udivmoddi4(void);
+extern void __udivsi3(void);
+extern void __umoddi3(void);
+extern void __umodsi3(void);
+
+        /* gcc lib functions */
+EXPORT_SYMBOL_NOVERS(__gcc_bcmp);
+EXPORT_SYMBOL_NOVERS(__ashldi3);
+EXPORT_SYMBOL_NOVERS(__ashrdi3);
+EXPORT_SYMBOL_NOVERS(__cmpdi2);
+EXPORT_SYMBOL_NOVERS(__divdi3);
+EXPORT_SYMBOL_NOVERS(__divsi3);
+EXPORT_SYMBOL_NOVERS(__lshrdi3);
+EXPORT_SYMBOL_NOVERS(__moddi3);
+EXPORT_SYMBOL_NOVERS(__modsi3);
+EXPORT_SYMBOL_NOVERS(__muldi3);
+EXPORT_SYMBOL_NOVERS(__mulsi3);
+EXPORT_SYMBOL_NOVERS(__negdi2);
+EXPORT_SYMBOL_NOVERS(__ucmpdi2);
+EXPORT_SYMBOL_NOVERS(__udivdi3);
+EXPORT_SYMBOL_NOVERS(__udivmoddi4);
+EXPORT_SYMBOL_NOVERS(__udivsi3);
+EXPORT_SYMBOL_NOVERS(__umoddi3);
+EXPORT_SYMBOL_NOVERS(__umodsi3);
+
+EXPORT_SYMBOL_NOVERS(_current_task);
+
+EXPORT_SYMBOL_NOVERS(is_in_rom);
+
+#ifdef CONFIG_COLDFIRE
+extern unsigned int *dma_device_address;
+extern unsigned long dma_base_addr, _ramend, _ramstart;
+EXPORT_SYMBOL_NOVERS(dma_base_addr);
+EXPORT_SYMBOL_NOVERS(dma_device_address);
+EXPORT_SYMBOL_NOVERS(_ramend);
+EXPORT_SYMBOL_NOVERS(_ramstart);
+
+extern asmlinkage void trap(void);
+extern void	*_ramvec;
+EXPORT_SYMBOL_NOVERS(trap);
+EXPORT_SYMBOL_NOVERS(_ramvec);
+
+#endif
diff -urN linux-2.4.29/arch/m68knommu/kernel/Makefile linux-2.4.29-uc1/arch/m68knommu/kernel/Makefile
--- linux-2.4.29/arch/m68knommu/kernel/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/kernel/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,41 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+all: kernel.o
+
+O_TARGET := kernel.o
+obj-y := process.o traps.o ptrace.o \
+	  sys_m68k.o time.o semaphore.o
+obj-y += setup.o m68k_ksyms.o
+
+export-objs := m68k_ksyms.o
+
+ifdef CONFIG_PCI
+ifndef CONFIG_COLDFIRE
+obj-y += bios32.o
+endif
+endif
+
+head.o: head.S m68k_defs.h
+
+entry.o: entry.S m68k_defs.h
+
+sun3-head.o: sun3-head.S m68k_defs.h
+
+m68k_defs.h: m68k_defs.c m68k_defs.head
+	rm -f m68k_defs.d
+	SUNPRO_DEPENDENCIES="m68k_defs.d m68k_defs.h" \
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S m68k_defs.c
+	cp m68k_defs.head m68k_defs.h
+	grep '^#define' m68k_defs.s >> m68k_defs.h
+	rm m68k_defs.s
+-include m68k_defs.d
+
+include $(TOPDIR)/Rules.make
+
diff -urN linux-2.4.29/arch/m68knommu/kernel/process.c linux-2.4.29-uc1/arch/m68knommu/kernel/process.c
--- linux-2.4.29/arch/m68knommu/kernel/process.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/kernel/process.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,393 @@
+/*
+ *  linux/arch/m68k/kernel/process.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ *
+ *  68060 fixes by Jesper Skov
+ *
+ *  uClinux changes Copyright (C) 2000-2002, David McCullough <davidm@snapgear.com>
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/reboot.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+
+/*
+ * Initial task structure. Make this a per-architecture thing,
+ * because different architectures tend to have different
+ * alignment requirements and potentially different initial
+ * setup.
+ */
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS;
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+union task_union init_task_union
+__attribute__((section(".data.init_task"), aligned(KTHREAD_SIZE)))
+	= { task: INIT_TASK(init_task_union.task) };
+
+asmlinkage void ret_from_fork(void);
+
+
+/*
+ * The idle loop on an m68k..
+ */
+static void default_idle(void)
+{
+	while(1) {
+		if (!current->need_resched)
+#if defined(MACH_ATARI_ONLY) && !defined(CONFIG_HADES)
+			/* block out HSYNC on the atari (falcon) */
+			__asm__("stop #0x2200" : : : "cc");
+#else
+			__asm__("stop #0x2000" : : : "cc");
+#endif
+		schedule();
+#ifndef NO_MM
+		check_pgt_cache();
+#endif
+	}
+}
+
+void (*idle)(void) = default_idle;
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle(void)
+{
+	/* endless idle loop with no priority at all */
+	init_idle();
+	current->nice = 20;
+	current->counter = -100;
+	idle();
+}
+
+void machine_restart(char * __unused)
+{
+	if (mach_reset)
+		mach_reset();
+	for (;;);
+}
+
+void machine_halt(void)
+{
+	if (mach_halt)
+		mach_halt();
+	for (;;);
+}
+
+void machine_power_off(void)
+{
+	if (mach_power_off)
+		mach_power_off();
+	for (;;);
+}
+
+void show_regs(struct pt_regs * regs)
+{
+	printk("\n");
+	printk("Format %02x  Vector: %04x  PC: %08lx  Status: %04x    %s\n",
+	       regs->format, regs->vector, regs->pc, regs->sr, print_tainted());
+	printk("ORIG_D0: %08lx  D0: %08lx  A2: %08lx  A1: %08lx\n",
+	       regs->orig_d0, regs->d0, regs->a2, regs->a1);
+	printk("A0: %08lx  D5: %08lx  D4: %08lx\n",
+	       regs->a0, regs->d5, regs->d4);
+	printk("D3: %08lx  D2: %08lx  D1: %08lx\n",
+	       regs->d3, regs->d2, regs->d1);
+	if (!(regs->sr & PS_S))
+		printk("USP: %08lx\n", rdusp());
+}
+
+/*
+ * Create a kernel thread
+ */
+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	long retval;
+	long clone_arg = flags | CLONE_VM;
+	mm_segment_t fs;
+
+	fs = get_fs();
+	set_fs (KERNEL_DS);
+
+	__asm__ __volatile__ (
+			"movel	%%sp, %%d2\n\t"
+			"movel	%5, %%d1\n\t"
+			"movel	%1, %%d0\n\t"
+			"trap	#0\n\t"
+			"cmpl	%%sp, %%d2\n\t"
+			"jeq	1f\n\t"
+			"movel	%3, %%sp@-\n\t"
+			"jsr	%4@\n\t"
+			"movel	%2, %%d0\n\t"
+			"trap	#0\n"
+			"1:"
+		: "=d" (retval)
+		: "i" (__NR_clone),
+		  "i" (__NR_exit),
+		  "a" (arg),
+		  "a" (fn),
+		  "a" (clone_arg)
+		: "cc", "%d0", "%d1", "%d2");
+
+	set_fs (fs);
+	return retval;
+}
+
+void flush_thread(void)
+{
+#ifndef NO_FPU
+	unsigned long zero = 0;
+#endif
+	set_fs(USER_DS);
+	current->thread.fs = __USER_DS;
+#ifndef NO_FPU
+	if (!FPU_IS_EMU)
+		asm volatile (".chip 68k/68881\n\t"
+			      "frestore %0@\n\t"
+			      ".chip 68k" : : "a" (&zero));
+#endif
+}
+
+/*
+ * "m68k_fork()".. By the time we get here, the
+ * non-volatile registers have also been saved on the
+ * stack. We do some ugly pointer stuff here.. (see
+ * also copy_thread)
+ */
+
+asmlinkage int m68k_fork(struct pt_regs *regs)
+{
+#ifdef NO_MM
+	/* fork almost works,  enough to trick you into looking elsewhere :-( */
+	return(-EINVAL);
+#else
+	return do_fork(SIGCHLD, rdusp(), regs, 0);
+#endif
+}
+
+asmlinkage int m68k_vfork(struct pt_regs *regs)
+{
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0);
+}
+
+asmlinkage int m68k_clone(struct pt_regs *regs)
+{
+	unsigned long clone_flags;
+	unsigned long newsp;
+
+	/* syscall2 puts clone_flags in d1 and usp in d2 */
+	clone_flags = regs->d1;
+	newsp = regs->d2;
+	if (!newsp)
+		newsp = rdusp();
+	return do_fork(clone_flags, newsp, regs, 0);
+}
+
+int copy_thread(int nr, unsigned long clone_flags,
+		unsigned long usp, unsigned long topstk,
+		struct task_struct * p, struct pt_regs * regs)
+{
+	struct pt_regs * childregs;
+	struct switch_stack * childstack, *stack;
+	unsigned long stack_offset, *retp;
+
+	stack_offset = KTHREAD_SIZE - sizeof(struct pt_regs);
+	childregs = (struct pt_regs *) ((unsigned long) p + stack_offset);
+
+	*childregs = *regs;
+	childregs->d0 = 0;
+
+	retp = ((unsigned long *) regs);
+	stack = ((struct switch_stack *) retp) - 1;
+
+	childstack = ((struct switch_stack *) childregs) - 1;
+	*childstack = *stack;
+	childstack->retpc = (unsigned long)ret_from_fork;
+
+	p->thread.usp = usp;
+	p->thread.ksp = (unsigned long)childstack;
+	/*
+	 * Must save the current SFC/DFC value, NOT the value when
+	 * the parent was last descheduled - RGH  10-08-96
+	 */
+	p->thread.fs = get_fs().seg;
+
+#ifndef NO_FPU
+	if (!FPU_IS_EMU) {
+		/* Copy the current fpu state */
+		asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory");
+
+		if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2])
+		  asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"
+				"fmoveml %/fpiar/%/fpcr/%/fpsr,%1"
+				: : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0])
+				: "memory");
+		/* Restore the state in case the fpu was busy */
+		asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));
+	}
+#endif
+
+	return 0;
+}
+
+/* Fill in the fpu structure for a core dump.  */
+
+int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
+{
+#ifndef NO_FPU
+	char fpustate[216];
+
+	if (FPU_IS_EMU) {
+		int i;
+
+		memcpy(fpu->fpcntl, current->thread.fpcntl, 12);
+		memcpy(fpu->fpregs, current->thread.fp, 96);
+		/* Convert internal fpu reg representation
+		 * into long double format
+		 */
+		for (i = 0; i < 24; i += 3)
+			fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) |
+			                 ((fpu->fpregs[i] & 0x0000ffff) << 16);
+		return 1;
+	}
+
+	/* First dump the fpu context to avoid protocol violation.  */
+	asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");
+	if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2])
+		return 0;
+
+	asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"
+		:: "m" (fpu->fpcntl[0])
+		: "memory");
+	asm volatile ("fmovemx %/fp0-%/fp7,%0"
+		:: "m" (fpu->fpregs[0])
+		: "memory");
+#endif
+	return 1;
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs * regs, struct user * dump)
+{
+	struct switch_stack *sw;
+
+/* changed the size calculations - should hopefully work better. lbt */
+	dump->magic = CMAGIC;
+	dump->start_code = 0;
+	dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
+	dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
+	dump->u_dsize = ((unsigned long) (current->mm->brk +
+					  (PAGE_SIZE-1))) >> PAGE_SHIFT;
+	dump->u_dsize -= dump->u_tsize;
+	dump->u_ssize = 0;
+
+	if (dump->start_stack < TASK_SIZE)
+		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
+
+	dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump);
+	sw = ((struct switch_stack *)regs) - 1;
+	dump->regs.d1 = regs->d1;
+	dump->regs.d2 = regs->d2;
+	dump->regs.d3 = regs->d3;
+	dump->regs.d4 = regs->d4;
+	dump->regs.d5 = regs->d5;
+	dump->regs.d6 = sw->d6;
+	dump->regs.d7 = sw->d7;
+	dump->regs.a0 = regs->a0;
+	dump->regs.a1 = regs->a1;
+	dump->regs.a2 = regs->a2;
+	dump->regs.a3 = sw->a3;
+	dump->regs.a4 = sw->a4;
+	dump->regs.a5 = sw->a5;
+	dump->regs.a6 = sw->a6;
+	dump->regs.d0 = regs->d0;
+	dump->regs.orig_d0 = regs->orig_d0;
+	dump->regs.stkadj = regs->stkadj;
+	dump->regs.sr = regs->sr;
+	dump->regs.pc = regs->pc;
+	dump->regs.fmtvec = (regs->format << 12) | regs->vector;
+	/* dump floating point stuff */
+	dump->u_fpvalid = dump_fpu (regs, &dump->m68kfp);
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage int sys_execve(char *name, char **argv, char **envp)
+{
+	int error;
+	char * filename;
+	struct pt_regs *regs = (struct pt_regs *) &name;
+
+	lock_kernel();
+	filename = getname(name);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+	error = do_execve(filename, argv, envp, regs);
+	putname(filename);
+out:
+	unlock_kernel();
+	return error;
+}
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+#define first_sched	((unsigned long) scheduling_functions_start_here)
+#define last_sched	((unsigned long) scheduling_functions_end_here)
+
+unsigned long get_wchan(struct task_struct *p)
+{
+	unsigned long fp, pc;
+	unsigned long stack_page;
+	int count = 0;
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	stack_page = (unsigned long)p;
+	fp = ((struct switch_stack *)p->thread.ksp)->a6;
+	do {
+		if (fp < stack_page+sizeof(struct task_struct) ||
+		    fp >= 8184+stack_page)
+			return 0;
+		pc = ((unsigned long *)fp)[1];
+		/* FIXME: This depends on the order of these functions. */
+		if (pc < first_sched || pc >= last_sched)
+			return pc;
+		fp = *(unsigned long *) fp;
+	} while (count++ < 16);
+	return 0;
+}
diff -urN linux-2.4.29/arch/m68knommu/kernel/ptrace.c linux-2.4.29-uc1/arch/m68knommu/kernel/ptrace.c
--- linux-2.4.29/arch/m68knommu/kernel/ptrace.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/kernel/ptrace.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,390 @@
+/*
+ *  linux/arch/m68k/kernel/ptrace.c
+ *
+ *  Copyright (C) 1994 by Hamish Macdonald
+ *  Taken from linux/kernel/ptrace.c and modified for M680x0.
+ *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/config.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/* determines which bits in the SR the user has access to. */
+/* 1 = access 0 = no access */
+#define SR_MASK 0x001f
+
+/* sets the trace bits. */
+#define TRACE_BITS 0x8000
+
+/* Find the stack offset for a register, relative to thread.esp0. */
+#define PT_REG(reg)	((long)&((struct pt_regs *)0)->reg)
+#define SW_REG(reg)	((long)&((struct switch_stack *)0)->reg \
+			 - sizeof(struct switch_stack))
+/* Mapping from PT_xxx to the stack offset at which the register is
+   saved.  Notice that usp has no stack-slot and needs to be treated
+   specially (see get_reg/put_reg below). */
+static int regoff[] = {
+	PT_REG(d1), PT_REG(d2), PT_REG(d3), PT_REG(d4),
+	PT_REG(d5), SW_REG(d6), SW_REG(d7), PT_REG(a0),
+	PT_REG(a1), PT_REG(a2), SW_REG(a3), SW_REG(a4),
+	SW_REG(a5), SW_REG(a6), PT_REG(d0), -1,
+	PT_REG(orig_d0), PT_REG(sr), PT_REG(pc),
+};
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+static inline long get_reg(struct task_struct *task, int regno)
+{
+	unsigned long *addr;
+
+	if (regno == PT_USP)
+		addr = &task->thread.usp;
+	else if (regno < sizeof(regoff)/sizeof(regoff[0]))
+		addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
+	else
+		return 0;
+	return *addr;
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static inline int put_reg(struct task_struct *task, int regno,
+			  unsigned long data)
+{
+	unsigned long *addr;
+
+	if (regno == PT_USP)
+		addr = &task->thread.usp;
+	else if (regno < sizeof(regoff)/sizeof(regoff[0]))
+		addr = (unsigned long *) (task->thread.esp0 + regoff[regno]);
+	else
+		return -1;
+	*addr = data;
+	return 0;
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure the single step bit is not set.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+	unsigned long tmp;
+	/* make sure the single step bit is not set. */
+	tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+	put_reg(child, PT_SR, tmp);
+}
+
+asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	int ret;
+
+	lock_kernel();
+	ret = -EPERM;
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED)
+			goto out;
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		ret = 0;
+		goto out;
+	}
+	ret = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		goto out;
+
+	ret = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out_tsk;
+
+	if (request == PTRACE_ATTACH) {
+		ret = ptrace_attach(child);
+		goto out_tsk;
+	}
+	ret = -ESRCH;
+	if (!(child->ptrace & PT_PTRACED))
+		goto out_tsk;
+	if (child->state != TASK_STOPPED) {
+		if (request != PTRACE_KILL)
+			goto out_tsk;
+	}
+	if (child->p_pptr != current)
+		goto out_tsk;
+
+	switch (request) {
+	/* when I and D space are separate, these will need to be fixed. */
+		case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+		case PTRACE_PEEKDATA: {
+			unsigned long tmp;
+			int copied;
+
+			copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+			ret = -EIO;
+			if (copied != sizeof(tmp))
+				break;
+			ret = put_user(tmp,(unsigned long *) data);
+			break;
+		}
+
+	/* read the word at location addr in the USER area. */
+		case PTRACE_PEEKUSR: {
+			unsigned long tmp;
+			
+			ret = -EIO;
+			if ((addr & 3) || addr < 0 ||
+			    addr > sizeof(struct user) - 3)
+				break;
+			
+			tmp = 0;  /* Default return condition */
+			addr = addr >> 2; /* temporary hack. */
+			ret = -EIO;
+			if (addr < 19) {
+				tmp = get_reg(child, addr);
+				if (addr == PT_SR)
+					tmp >>= 16;
+			} else if (addr >= 21 && addr < 49) {
+				tmp = child->thread.fp[addr - 21];
+#ifdef CONFIG_M68KFPU_EMU
+				/* Convert internal fpu reg representation
+				 * into long double format
+				 */
+				if (FPU_IS_EMU && (addr < 45) && !(addr % 3))
+					tmp = ((tmp & 0xffff0000) << 15) |
+					      ((tmp & 0x0000ffff) << 16);
+#endif
+			} else if (addr == 49) {
+				tmp = child->mm->start_code;
+			} else if (addr == 50) {
+				tmp = child->mm->start_data;
+			} else if (addr == 51) {
+				tmp = child->mm->end_code;
+			} else
+				break;
+			ret = put_user(tmp,(unsigned long *) data);
+			break;
+		}
+
+      /* when I and D space are separate, this will have to be fixed. */
+		case PTRACE_POKETEXT: /* write the word at location addr. */
+		case PTRACE_POKEDATA:
+			ret = 0;
+			if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+				break;
+			ret = -EIO;
+			break;
+
+		case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+			ret = -EIO;
+			if ((addr & 3) || addr < 0 ||
+			    addr > sizeof(struct user) - 3)
+				break;
+
+			addr = addr >> 2; /* temporary hack. */
+			    
+			if (addr == PT_SR) {
+				data &= SR_MASK;
+				data <<= 16;
+				data |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
+			}
+			if (addr < 19) {
+				if (put_reg(child, addr, data))
+					break;
+				ret = 0;
+				break;
+			}
+			if (addr >= 21 && addr < 48)
+			{
+#ifdef CONFIG_M68KFPU_EMU
+				/* Convert long double format
+				 * into internal fpu reg representation
+				 */
+				if (FPU_IS_EMU && (addr < 45) && !(addr % 3)) {
+					data = (unsigned long)data << 15;
+					data = (data & 0xffff0000) |
+					       ((data & 0x0000ffff) >> 1);
+				}
+#endif
+				child->thread.fp[addr - 21] = data;
+				ret = 0;
+			}
+			break;
+
+		case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+		case PTRACE_CONT: { /* restart after signal. */
+			long tmp;
+
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				break;
+			if (request == PTRACE_SYSCALL)
+				child->ptrace |= PT_TRACESYS;
+			else
+				child->ptrace &= ~PT_TRACESYS;
+			child->exit_code = data;
+			/* make sure the single step bit is not set. */
+			tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+			put_reg(child, PT_SR, tmp);
+			wake_up_process(child);
+			ret = 0;
+			break;
+		}
+
+/*
+ * make the child exit.  Best I can do is send it a sigkill. 
+ * perhaps it should be put in the status that it wants to 
+ * exit.
+ */
+		case PTRACE_KILL: {
+			long tmp;
+
+			ret = 0;
+			if (child->state == TASK_ZOMBIE) /* already dead */
+				break;
+			child->exit_code = SIGKILL;
+	/* make sure the single step bit is not set. */
+			tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+			put_reg(child, PT_SR, tmp);
+			wake_up_process(child);
+			break;
+		}
+
+		case PTRACE_SINGLESTEP: {  /* set the trap flag. */
+			long tmp;
+
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				break;
+			child->ptrace &= ~PT_TRACESYS;
+			tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
+			put_reg(child, PT_SR, tmp);
+
+			child->exit_code = data;
+	/* give it a chance to run. */
+			wake_up_process(child);
+			ret = 0;
+			break;
+		}
+
+		case PTRACE_DETACH:	/* detach a process that was attached. */
+			ret = ptrace_detach(child, data);
+			break;
+
+		case PTRACE_GETREGS: { /* Get all gp regs from the child. */
+		  	int i;
+			unsigned long tmp;
+			for (i = 0; i < 19; i++) {
+			    tmp = get_reg(child, i);
+			    if (i == PT_SR)
+				tmp >>= 16;
+			    if (put_user(tmp, (unsigned long *) data)) {
+				ret = -EFAULT;
+				break;
+			    }
+			    data += sizeof(long);
+			}
+			ret = 0;
+			break;
+		}
+
+		case PTRACE_SETREGS: { /* Set all gp regs in the child. */
+			int i;
+			unsigned long tmp;
+			for (i = 0; i < 19; i++) {
+			    if (get_user(tmp, (unsigned long *) data)) {
+				ret = -EFAULT;
+				break;
+			    }
+			    if (i == PT_SR) {
+				tmp &= SR_MASK;
+				tmp <<= 16;
+				tmp |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
+			    }
+			    put_reg(child, i, tmp);
+			    data += sizeof(long);
+			}
+			ret = 0;
+			break;
+		}
+
+#ifdef PTRACE_GETFPREGS
+		case PTRACE_GETFPREGS: { /* Get the child FPU state. */
+			ret = 0;
+			if (copy_to_user((void *)data, &child->thread.fp,
+					 sizeof(struct user_m68kfp_struct)))
+				ret = -EFAULT;
+			break;
+		}
+#endif
+
+#ifdef PTRACE_SETFPREGS
+		case PTRACE_SETFPREGS: { /* Set the child FPU state. */
+			ret = 0;
+			if (copy_from_user(&child->thread.fp, (void *)data,
+					   sizeof(struct user_m68kfp_struct)))
+				ret = -EFAULT;
+			break;
+		}
+#endif
+
+		default:
+			ret = -EIO;
+			break;
+	}
+out_tsk:
+	free_task_struct(child);
+out:
+	unlock_kernel();
+	return ret;
+}
+
+asmlinkage void syscall_trace(void)
+{
+	if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
+			!= (PT_PTRACED|PT_TRACESYS))
+		return;
+	current->exit_code = SIGTRAP;
+	current->state = TASK_STOPPED;
+	notify_parent(current, SIGCHLD);
+	schedule();
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+}
diff -urN linux-2.4.29/arch/m68knommu/kernel/semaphore.c linux-2.4.29-uc1/arch/m68knommu/kernel/semaphore.c
--- linux-2.4.29/arch/m68knommu/kernel/semaphore.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/kernel/semaphore.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,132 @@
+/*
+ *  Generic semaphore code. Buyer beware. Do your own
+ * specific changes in <asm/semaphore-helper.h>
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <asm/semaphore-helper.h>
+
+#ifndef CONFIG_RMW_INSNS
+spinlock_t semaphore_wake_lock;
+#endif
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to sleep, while the "waking" variable is
+ * incremented when the "up()" code goes to wake up waiting
+ * processes.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * waking_non_zero() (from asm/semaphore.h) must execute
+ * atomically.
+ *
+ * When __up() is called, the count was negative before
+ * incrementing it, and we need to wake up somebody.
+ *
+ * This routine adds one to the count of processes that need to
+ * wake up and exit.  ALL waiting processes actually wake up but
+ * only the one that gets to the "waking" field first will gate
+ * through and acquire the semaphore.  The others will go back
+ * to sleep.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+void __up(struct semaphore *sem)
+{
+	wake_one_more(sem);
+	wake_up(&sem->wait);
+}
+
+/*
+ * Perform the "down" function.  Return zero for semaphore acquired,
+ * return negative for signalled out of the function.
+ *
+ * If called from __down, the return is ignored and the wait loop is
+ * not interruptible.  This means that a task waiting on a semaphore
+ * using "down()" cannot be killed until someone does an "up()" on
+ * the semaphore.
+ *
+ * If called from __down_interruptible, the return value gets checked
+ * upon return.  If the return value is negative then the task continues
+ * with the negative value in the return register (it can be tested by
+ * the caller).
+ *
+ * Either form may be used in conjunction with "up()".
+ *
+ */
+
+
+#define DOWN_HEAD(task_state)						\
+									\
+									\
+	current->state = (task_state);					\
+	add_wait_queue(&sem->wait, &wait);				\
+									\
+	/*								\
+	 * Ok, we're set up.  sem->count is known to be less than zero	\
+	 * so we must wait.						\
+	 *								\
+	 * We can let go the lock for purposes of waiting.		\
+	 * We re-acquire it after awaking so as to protect		\
+	 * all semaphore operations.					\
+	 *								\
+	 * If "up()" is called before we call waking_non_zero() then	\
+	 * we will catch it right away.  If it is called later then	\
+	 * we will have to go through a wakeup cycle to catch it.	\
+	 *								\
+	 * Multiple waiters contend for the semaphore lock to see	\
+	 * who gets to gate through and who has to wait some more.	\
+	 */								\
+	for (;;) {
+
+#define DOWN_TAIL(task_state)			\
+		current->state = (task_state);	\
+	}					\
+	current->state = TASK_RUNNING;		\
+	remove_wait_queue(&sem->wait, &wait);
+
+void __down(struct semaphore * sem)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	DOWN_HEAD(TASK_UNINTERRUPTIBLE)
+	if (waking_non_zero(sem))
+		break;
+	schedule();
+	DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int ret = 0;
+
+	DOWN_HEAD(TASK_INTERRUPTIBLE)
+
+	ret = waking_non_zero_interruptible(sem, current);
+	if (ret)
+	{
+		if (ret == 1)
+			/* ret != 0 only if we get interrupted -arca */
+			ret = 0;
+		break;
+	}
+	schedule();
+	DOWN_TAIL(TASK_INTERRUPTIBLE)
+	return ret;
+}
+
+int __down_trylock(struct semaphore * sem)
+{
+	return waking_non_zero_trylock(sem);
+}
diff -urN linux-2.4.29/arch/m68knommu/kernel/setup.c linux-2.4.29-uc1/arch/m68knommu/kernel/setup.c
--- linux-2.4.29/arch/m68knommu/kernel/setup.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/kernel/setup.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,450 @@
+/*
+ *  linux/arch/m68knommu/kernel/setup.c
+ *
+ *  Copyleft  ()) 2000       James D. Schettine {james@telos-systems.com}
+ *  Copyright (C) 1999-2004  Greg Ungerer (gerg@snapgear.com)
+ *  Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uClinux.org>
+ *  Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ *  Copyright (C) 1995       Hamish Macdonald
+ *  Copyright (C) 2000       Lineo Inc. (www.lineo.com) 
+ *  Copyright (C) 2001 	     Lineo, Inc. <www.lineo.com>
+ *
+ */
+
+/*
+ * This file handles the architecture-dependent parts of system setup
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/genhd.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/major.h>
+#include <linux/bootmem.h>
+#include <linux/seq_file.h>
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <linux/blk.h>
+#include <asm/pgtable.h>
+#endif
+
+#if defined (CONFIG_M68360)
+#include<asm/m68360.h>  //Get the definition of QUICC type
+extern void m360_cpm_reset(void);
+extern QUICC *pquicc;
+extern struct console sercons;
+
+// Mask to select if the PLL prescaler is enabled.
+#define MCU_PREEN   ((unsigned short)(0x0001 << 13))
+
+#if defined(CONFIG_UCQUICC)
+#define OSCILLATOR  (unsigned long int)33000000
+#endif
+
+unsigned long int system_clock;
+#endif
+
+#if defined(CONFIG_M68VZ328)
+#include <asm/MC68VZ328.h>
+#endif
+  
+unsigned long rom_length;
+unsigned long memory_start;
+unsigned long memory_end;
+
+struct task_struct *_current_task;
+
+char command_line[512];
+char saved_command_line[512];
+
+/* setup some dummy routines */
+static void dummy_waitbut(void)
+{
+}
+
+void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) = NULL;
+void (*mach_tick)( void ) = NULL;
+/* machine dependent keyboard functions */
+int (*mach_keyb_init) (void) = NULL;
+int (*mach_kbdrate) (struct kbd_repeat *) = NULL;
+void (*mach_kbd_leds) (unsigned int) = NULL;
+/* machine dependent irq functions */
+void (*mach_init_IRQ) (void) = NULL;
+void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
+int (*mach_request_irq) (unsigned int, void (*)(int, void *, struct pt_regs *),
+                         unsigned long, const char *, void *);
+void (*mach_free_irq) (unsigned int irq, void *dev_id) = NULL;
+void (*mach_enable_irq) (unsigned int) = NULL;
+void (*mach_disable_irq) (unsigned int) = NULL;
+int (*mach_get_irq_list) (char *) = NULL;
+void (*mach_process_int) (int irq, struct pt_regs *fp) = NULL;
+void (*mach_trap_init) (void);
+/* machine dependent timer functions */
+unsigned long (*mach_gettimeoffset) (void) = NULL;
+void (*mach_gettod) (int*, int*, int*, int*, int*, int*) = NULL;
+int (*mach_hwclk) (int, struct hwclk_time*) = NULL;
+int (*mach_set_clock_mmss) (unsigned long) = NULL;
+void (*mach_mksound)( unsigned int count, unsigned int ticks ) = NULL;
+void (*mach_reset)( void ) = NULL;
+void (*waitbut)(void) = dummy_waitbut;
+void (*mach_debug_init)(void) = NULL;
+void (*mach_halt)( void ) = NULL;
+void (*mach_power_off)( void ) = NULL;
+
+
+#ifdef CONFIG_M68000
+	#define CPU "MC68000"
+#endif
+#ifdef CONFIG_M68328
+	#define CPU "MC68328"
+#endif
+#ifdef CONFIG_M68EZ328
+	#define CPU "MC68EZ328"
+#endif
+#ifdef CONFIG_M68VZ328
+	#define CPU "MC68VZ328"
+#endif
+#ifdef CONFIG_M68332
+	#define CPU "MC68332"
+#endif
+#ifdef CONFIG_M68360
+	#define CPU "MC68360"
+#endif
+#if defined(CONFIG_M5206)
+	#define	CPU "COLDFIRE(m5206)"
+#endif
+#if defined(CONFIG_M5206e)
+	#define	CPU "COLDFIRE(m5206e)"
+#endif
+#if defined(CONFIG_M5235)
+	#define CPU "COLDFIRE(m5235)"
+#endif
+#if defined(CONFIG_M5249)
+	#define CPU "COLDFIRE(m5249)"
+#endif
+#if defined(CONFIG_M5271)
+	#define CPU "COLDFIRE(m5270/5271)"
+#endif
+#if defined(CONFIG_M5275)
+	#define CPU "COLDFIRE(m5274/5275)"
+#endif
+#if defined(CONFIG_M5272)
+	#define CPU "COLDFIRE(m5272)"
+#endif
+#if defined(CONFIG_M5280)
+	#define CPU "COLDFIRE(m5280)"
+#endif
+#if defined(CONFIG_M5282)
+	#define CPU "COLDFIRE(m5282)"
+#endif
+#if defined(CONFIG_M5307)
+	#define	CPU "COLDFIRE(m5307)"
+#endif
+#if defined(CONFIG_M5407)
+	#define	CPU "COLDFIRE(m5407)"
+#endif
+#if defined(CONFIG_M547x)
+	#define	CPU "COLDFIRE(m547x)"
+#endif
+#ifndef CPU
+	#define	CPU "UNKOWN"
+#endif
+
+/* (es) */
+/* note: why is this defined here?  the must be a better place to put this */
+#if defined( CONFIG_TELOS) || defined( CONFIG_UCDIMM ) || defined( CONFIG_UCSIMM ) || defined(CONFIG_DRAGEN2) || (defined( CONFIG_PILOT ) && defined( CONFIG_M68328 ))
+#define CAT_ROMARRAY
+#endif
+/* (/es) */
+
+extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
+extern unsigned int _ramstart, _ramend;
+
+void setup_arch(char **cmdline_p)
+{
+	int bootmap_size;
+
+#if defined(CAT_ROMARRAY) && defined(DEBUG)
+	extern int __data_rom_start;
+	extern int __data_start;
+	int *romarray = (int *)((int) &__data_rom_start +
+			      (int)&_edata - (int)&__data_start);
+#endif
+
+#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
+	/* we need to initialize the Flashrom device here since we might
+	 * do things with flash early on in the boot
+	 */
+	flash_probe();
+#endif
+
+	memory_start = PAGE_ALIGN(_ramstart);
+	memory_end = _ramend; /* by now the stack is part of the init task */
+
+	init_mm.start_code = (unsigned long) &_stext;
+	init_mm.end_code = (unsigned long) &_etext;
+	init_mm.end_data = (unsigned long) &_edata;
+#if 0 /* DAVIDM - don't set brk just incase someone decides to use it */
+	init_mm.brk = (unsigned long) &_end;
+#else
+	init_mm.brk = (unsigned long) 0; 
+#endif
+
+
+#if defined (CONFIG_M68360)
+    m360_cpm_reset();
+
+   /* Calculate the real system clock value. */
+   {
+       unsigned int local_pllcr = (unsigned int)(pquicc->sim_pllcr);
+       if( local_pllcr & MCU_PREEN ) // If the prescaler is dividing by 128
+       {
+           int mf = (int)(pquicc->sim_pllcr & 0x0fff);
+           system_clock = (OSCILLATOR / 128) * (mf + 1);
+       }
+       else
+       {
+           int mf = (int)(pquicc->sim_pllcr & 0x0fff);
+           system_clock = (OSCILLATOR) * (mf + 1);
+       }
+   }
+
+   /* Setup SMC 2 as a serial console */
+   serial_console_setup(&sercons, NULL);
+   console_360_init(0, 0);
+#endif
+
+	config_BSP(&command_line[0], sizeof(command_line));
+
+	printk("\r\nuClinux/" CPU "\n");
+
+#ifdef CONFIG_UCDIMM
+	printk("uCdimm by Arcturus Networks, Inc. <www.arcturusnetworks.com>\n");
+#endif
+#ifdef CONFIG_COLDFIRE
+	printk("COLDFIRE port done by Greg Ungerer, gerg@snapgear.com\n");
+#ifdef CONFIG_M5307
+	printk("Modified for M5307 by Dave Miller, dmiller@intellistor.com\n");
+#endif
+#ifdef CONFIG_ELITE
+	printk("Modified for M5206eLITE by Rob Scott, rscott@mtrob.fdns.net\n");
+#endif  
+#ifdef CONFIG_TELOS
+	printk("Modified for Omnia ToolVox by James D. Schettine, james@telos-systems.com\n");
+#endif
+#if defined(CONFIG_M5307) || defined(CONFIG_M5407)
+	{
+		/*
+		 * Read the reset status register and print a message regarding
+		 * the source of the reset. This may provide usefull information
+		 * in debugging a system (especially one with a watchdog timer).
+		 * I know the 5407 has a reset status register and the 5307 is
+		 * very similar to the 5407. I am assuming the 5307's RSR is
+		 * the same as the 5407's RSR. If other coldfire's have the
+		 * same RSR, feel free to add them to the list.
+		 */
+		volatile unsigned char  *mbar =
+			(volatile unsigned char *) MCF_MBAR;
+		if((*(mbar + MCFSIM_RSR)) & MCFSIM_RSR_HRST)
+			printk("Coldfire was last reset by a hard reset.\n");
+		else if((*(mbar + MCFSIM_RSR)) & MCFSIM_RSR_SWTR)
+			printk("Coldfire was last reset by a software watchdog reset.\n");
+		else
+			printk("Coldfire was last reset for unknown reason.\n");
+		*(mbar + MCFSIM_RSR) = 0;
+	}
+#endif
+#endif
+	printk("Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
+
+#if defined( CONFIG_PILOT ) && defined( CONFIG_M68328 )
+	printk("TRG SuperPilot FLASH card support <info@trgnet.com>\n");
+#endif
+
+#if defined( CONFIG_PILOT ) && defined( CONFIG_M68EZ328 )
+	printk("PalmV support by <jeff@uClinux.org>\n");
+#endif
+
+#ifdef CONFIG_M68EZ328ADS
+	printk("M68EZ328ADS board support (C) 1999 Vladimir Gurevich <vgurevic@cisco.com>\n");
+#endif
+
+#ifdef CONFIG_ALMA_ANS
+	printk("Alma Electronics board support (C) 1999 Vladimir Gurevich <vgurevic@cisco.com>\n");
+#endif
+#if defined (CONFIG_M68360)
+    printk("QUICC port done by SED Systems <hamilton@sedsystems.ca>,\n");
+    printk("based on 2.0.38 port by <mleslie@ArcturusNetworks.com>.\n");
+#endif
+#ifdef CONFIG_DRAGEN2
+	printk("DragonEngine II board support by Georges Menie\n");
+#endif
+
+#ifdef CONFIG_CWEZ328
+	printk("cwez328 board support by 2002 Andrew Ip <aip@cwlinux.com> and Inky Lung <ilung@cwlinux.com>\n");
+#endif
+
+#ifdef CONFIG_CWVZ328
+	printk("cwvz328 board support by 2002 Andrew Ip <aip@cwlinux.com> and Inky Lung <ilung@cwlinux.com>\n");
+#endif
+
+#ifdef CONFIG_M5235
+	printk("MCF5235 support (C) 2004 Syntech Systems, Inc. Jate Sujjavanich, Rob Falkenhayn\n");
+#endif
+
+#ifdef DEBUG
+	printk("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x "
+		"BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext,
+		(int) &_sdata, (int) &_edata,
+		(int) &_sbss, (int) &_ebss);
+	printk("KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x "
+		"STACK=0x%06x-0x%06x\n",
+#ifdef CAT_ROMARRAY
+	       (int) romarray, ((int) romarray) + romarray[2],
+#else
+	       (int) &_ebss, (int) memory_start,
+#endif
+		(int) memory_start, (int) memory_end,
+		(int) memory_end, (int) _ramend);
+#endif
+
+#ifdef CONFIG_BLK_DEV_BLKMEM
+	ROOT_DEV = MKDEV(BLKMEM_MAJOR,0);
+#endif
+
+	/* Keep a copy of command line */
+	*cmdline_p = &command_line[0];
+	memcpy(saved_command_line, command_line, sizeof(saved_command_line));
+	saved_command_line[sizeof(saved_command_line)-1] = 0;
+
+#ifdef DEBUG
+	if (strlen(*cmdline_p)) 
+		printk("Command line: '%s'\n", *cmdline_p);
+#endif
+	/*rom_length = (unsigned long)&_flashend - (unsigned long)&_romvec;*/
+	
+#ifdef CONFIG_VT_CONSOLE
+#ifdef CONFIG_FB
+       conswitchp = &dummy_con;
+#endif
+#endif
+
+	/*
+	 * give all the memory to the bootmap allocator,  tell it to put the
+	 * boot mem_map at the start of memory
+	 */
+	bootmap_size = init_bootmem_node(
+			NODE_DATA(0),
+			memory_start >> PAGE_SHIFT, /* map goes here */
+			PAGE_OFFSET >> PAGE_SHIFT,	/* 0 on coldfire */
+			memory_end >> PAGE_SHIFT);
+	/*
+	 * free the usable memory,  we have to make sure we do not free
+	 * the bootmem bitmap so we then reserve it after freeing it :-)
+	 */
+	free_bootmem(memory_start, memory_end - memory_start);
+	reserve_bootmem(memory_start, bootmap_size);
+	/*
+	 * get kmalloc into gear
+	 */
+	paging_init();
+#ifdef DEBUG
+	printk("Done setup_arch\n");
+#endif
+
+}
+
+/*
+ *	Get CPU information for use by the procfs.
+ */
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+    char *cpu, *mmu, *fpu;
+    u_long clockfreq;
+
+    cpu = CPU;
+    mmu = "none";
+    fpu = "none";
+
+#if defined(CONFIG_COLDFIRE)
+    clockfreq = (loops_per_jiffy*HZ)*3;
+#elif defined(CONFIG_DRAGONIXVZ)
+    clockfreq = (loops_per_jiffy*HZ)*29;
+#elif defined(CONFIG_UCDIMM)
+    {
+      unsigned short p, q;
+      unsigned short prot;
+      unsigned short sysclk_sel, presc1, presc2;
+
+      p    = PLLFSR & PLLFSR_PC_MASK;
+      q    = (PLLFSR & PLLFSR_QC_MASK) >> PLLFSR_QC_SHIFT;
+      prot = (PLLFSR & PLLFSR_PROT)? 1 : 0;
+
+      presc1 = (PLLCR & PLLCR_PRESC1) ? 1 : 0;
+      presc2 = (PLLCR & PLLCR_PRESC2) ? 1 : 0;
+      sysclk_sel = (PLLCR & PLLCR_SYSCLK_SEL_MASK) >> PLLCR_SYSCLK_SEL_SHIFT;
+
+      clockfreq = 2*(14*(p+1) + q+1) * 32768;
+      clockfreq = (clockfreq >> presc1) >> presc2;
+    }
+#else
+    clockfreq = (loops_per_jiffy*HZ)*16;
+#endif
+
+    seq_printf(m, "CPU:\t\t%s\n"
+		   "MMU:\t\t%s\n"
+		   "FPU:\t\t%s\n"
+		   "Clocking:\t%lu.%1luMHz\n"
+		   "BogoMips:\t%lu.%02lu\n"
+		   "Calibration:\t%lu loops\n",
+		   cpu, mmu, fpu,
+		   clockfreq/1000000,(clockfreq/100000)%10,
+		   (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
+		   (loops_per_jiffy*HZ));
+
+	return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+	start:	c_start,
+	next:	c_next,
+	stop:	c_stop,
+	show:	show_cpuinfo,
+};
+
+void arch_gettod(int *year, int *mon, int *day, int *hour,
+		 int *min, int *sec)
+{
+	*year = *mon = *day = *hour = *min = *sec = 0;
+	if (mach_gettod)
+		mach_gettod(year, mon, day, hour, min, sec);
+}
+
+
diff -urN linux-2.4.29/arch/m68knommu/kernel/sys_m68k.c linux-2.4.29-uc1/arch/m68knommu/kernel/sys_m68k.c
--- linux-2.4.29/arch/m68knommu/kernel/sys_m68k.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/kernel/sys_m68k.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,681 @@
+/*
+ * linux/arch/m68k/kernel/sys_m68k.c
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/m68k
+ * platform.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/cachectl.h>
+#include <asm/traps.h>
+#include <asm/ipc.h>
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+asmlinkage int sys_pipe(unsigned long * fildes)
+{
+	int fd[2];
+	int error;
+
+	error = do_pipe(fd);
+	if (!error) {
+		if (copy_to_user(fildes, fd, 2*sizeof(int)))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+/* common code for old and new mmaps */
+static inline long do_mmap2(
+	unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	int error = -EBADF;
+	struct file * file = NULL;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (!(flags & MAP_ANONYMOUS)) {
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
+/*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
+ * handle more than 4 system call parameters, so these system calls
+ * used a memory block for parameter passing..
+ */
+
+struct mmap_arg_struct {
+	unsigned long addr;
+	unsigned long len;
+	unsigned long prot;
+	unsigned long flags;
+	unsigned long fd;
+	unsigned long offset;
+};
+
+asmlinkage int old_mmap(struct mmap_arg_struct *arg)
+{
+	struct mmap_arg_struct a;
+	int error = -EFAULT;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		goto out;
+
+	error = -EINVAL;
+	if (a.offset & ~PAGE_MASK)
+		goto out;
+
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+out:
+	return error;
+}
+
+#if 0 /* DAVIDM - do we want this */
+struct mmap_arg_struct64 {
+	__u32 addr;
+	__u32 len;
+	__u32 prot;
+	__u32 flags;
+	__u64 offset; /* 64 bits */
+	__u32 fd;
+};
+
+asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
+{
+	int error = -EFAULT;
+	struct file * file = NULL;
+	struct mmap_arg_struct64 a;
+	unsigned long pgoff;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+
+	if ((long)a.offset & ~PAGE_MASK)
+		return -EINVAL;
+
+	pgoff = a.offset >> PAGE_SHIFT;
+	if ((a.offset >> PAGE_SHIFT) != pgoff)
+		return -EINVAL;
+
+	if (!(a.flags & MAP_ANONYMOUS)) {
+		error = -EBADF;
+		file = fget(a.fd);
+		if (!file)
+			goto out;
+	}
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+#endif
+
+extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+
+struct sel_arg_struct {
+	unsigned long n;
+	fd_set *inp, *outp, *exp;
+	struct timeval *tvp;
+};
+
+asmlinkage int old_select(struct sel_arg_struct *arg)
+{
+	struct sel_arg_struct a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+	/* sys_select() does the appropriate kernel locking */
+	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
+}
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+asmlinkage int sys_ipc (uint call, int first, int second,
+			int third, void *ptr, long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	if (call <= SEMCTL)
+		switch (call) {
+		case SEMOP:
+			return sys_semop (first, (struct sembuf *)ptr, second);
+		case SEMGET:
+			return sys_semget (first, second, third);
+		case SEMCTL: {
+			union semun fourth;
+			if (!ptr)
+				return -EINVAL;
+			if (get_user(fourth.__pad, (void **) ptr))
+				return -EFAULT;
+			return sys_semctl (first, second, third, fourth);
+			}
+		default:
+			return -EINVAL;
+		}
+	if (call <= MSGCTL) 
+		switch (call) {
+		case MSGSND:
+			return sys_msgsnd (first, (struct msgbuf *) ptr, 
+					  second, third);
+		case MSGRCV:
+			switch (version) {
+			case 0: {
+				struct ipc_kludge tmp;
+				if (!ptr)
+					return -EINVAL;
+				if (copy_from_user (&tmp,
+						    (struct ipc_kludge *)ptr,
+						    sizeof (tmp)))
+					return -EFAULT;
+				return sys_msgrcv (first, tmp.msgp, second,
+						   tmp.msgtyp, third);
+				}
+			default:
+				return sys_msgrcv (first,
+						   (struct msgbuf *) ptr,
+						   second, fifth, third);
+			}
+		case MSGGET:
+			return sys_msgget ((key_t) first, second);
+		case MSGCTL:
+			return sys_msgctl (first, second,
+					   (struct msqid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+	if (call <= SHMCTL) 
+		switch (call) {
+		case SHMAT:
+			switch (version) {
+			default: {
+				ulong raddr;
+				ret = sys_shmat (first, (char *) ptr,
+						 second, &raddr);
+				if (ret)
+					return ret;
+				return put_user (raddr, (ulong *) third);
+			}
+			}
+		case SHMDT: 
+			return sys_shmdt ((char *)ptr);
+		case SHMGET:
+			return sys_shmget (first, second, third);
+		case SHMCTL:
+			return sys_shmctl (first, second,
+					   (struct shmid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+
+	return -EINVAL;
+}
+
+asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
+{
+  return -ENOSYS;
+}
+
+#if DAVIDM /* fixme,  may need something like this for the 5407 */
+/* Convert virtual address VADDR to physical address PADDR */
+#define virt_to_phys_040(vaddr)						\
+({									\
+  unsigned long _mmusr, _paddr;						\
+									\
+  __asm__ __volatile__ (".chip 68040\n\t"				\
+			"ptestr (%1)\n\t"				\
+			"movec %%mmusr,%0\n\t"				\
+			".chip 68k"					\
+			: "=r" (_mmusr)					\
+			: "a" (vaddr));					\
+  _paddr = (_mmusr & MMU_R_040) ? (_mmusr & PAGE_MASK) : 0;		\
+  _paddr;								\
+})
+
+static inline int
+cache_flush_040 (unsigned long addr, int scope, int cache, unsigned long len)
+{
+  unsigned long paddr, i;
+
+  switch (scope)
+    {
+    case FLUSH_SCOPE_ALL:
+      switch (cache)
+	{
+	case FLUSH_CACHE_DATA:
+	  /* This nop is needed for some broken versions of the 68040.  */
+	  __asm__ __volatile__ ("nop\n\t"
+				".chip 68040\n\t"
+				"cpusha %dc\n\t"
+				".chip 68k");
+	  break;
+	case FLUSH_CACHE_INSN:
+	  __asm__ __volatile__ ("nop\n\t"
+				".chip 68040\n\t"
+				"cpusha %ic\n\t"
+				".chip 68k");
+	  break;
+	default:
+	case FLUSH_CACHE_BOTH:
+	  __asm__ __volatile__ ("nop\n\t"
+				".chip 68040\n\t"
+				"cpusha %bc\n\t"
+				".chip 68k");
+	  break;
+	}
+      break;
+
+    case FLUSH_SCOPE_LINE:
+      /* Find the physical address of the first mapped page in the
+	 address range.  */
+      if ((paddr = virt_to_phys_040(addr))) {
+        paddr += addr & ~(PAGE_MASK | 15);
+        len = (len + (addr & 15) + 15) >> 4;
+      } else {
+	unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
+
+	if (len <= tmp)
+	  return 0;
+	addr += tmp;
+	len -= tmp;
+	tmp = PAGE_SIZE;
+	for (;;)
+	  {
+	    if ((paddr = virt_to_phys_040(addr)))
+	      break;
+	    if (len <= tmp)
+	      return 0;
+	    addr += tmp;
+	    len -= tmp;
+	  }
+	len = (len + 15) >> 4;
+      }
+      i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
+      while (len--)
+	{
+	  switch (cache)
+	    {
+	    case FLUSH_CACHE_DATA:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushl %%dc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    case FLUSH_CACHE_INSN:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushl %%ic,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    default:
+	    case FLUSH_CACHE_BOTH:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushl %%bc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    }
+	  if (!--i && len)
+	    {
+	      /*
+	       * No need to page align here since it is done by
+	       * virt_to_phys_040().
+	       */
+	      addr += PAGE_SIZE;
+	      i = PAGE_SIZE / 16;
+	      /* Recompute physical address when crossing a page
+	         boundary. */
+	      for (;;)
+		{
+		  if ((paddr = virt_to_phys_040(addr)))
+		    break;
+		  if (len <= i)
+		    return 0;
+		  len -= i;
+		  addr += PAGE_SIZE;
+		}
+	    }
+	  else
+	    paddr += 16;
+	}
+      break;
+
+    default:
+    case FLUSH_SCOPE_PAGE:
+      len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
+      for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
+	{
+	  if (!(paddr = virt_to_phys_040(addr)))
+	    continue;
+	  switch (cache)
+	    {
+	    case FLUSH_CACHE_DATA:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushp %%dc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    case FLUSH_CACHE_INSN:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushp %%ic,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    default:
+	    case FLUSH_CACHE_BOTH:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushp %%bc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    }
+	}
+      break;
+    }
+  return 0;
+}
+
+#define virt_to_phys_060(vaddr)				\
+({							\
+  unsigned long paddr;					\
+  __asm__ __volatile__ (".chip 68060\n\t"		\
+			"plpar (%0)\n\t"		\
+			".chip 68k"			\
+			: "=a" (paddr)			\
+			: "0" (vaddr));			\
+  (paddr); /* XXX */					\
+})
+
+static inline int
+cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len)
+{
+  unsigned long paddr, i;
+
+  switch (scope)
+    {
+    case FLUSH_SCOPE_ALL:
+      switch (cache)
+	{
+	case FLUSH_CACHE_DATA:
+	  __asm__ __volatile__ (".chip 68060\n\t"
+				"cpusha %dc\n\t"
+				"cinva %dc\n\t"
+				".chip 68k");
+	  break;
+	case FLUSH_CACHE_INSN:
+	  __asm__ __volatile__ (".chip 68060\n\t"
+				"cpusha %ic\n\t"
+				"cinva %ic\n\t"
+				".chip 68k");
+	  break;
+	default:
+	case FLUSH_CACHE_BOTH:
+	  __asm__ __volatile__ (".chip 68060\n\t"
+				"cpusha %bc\n\t"
+				"cinva %bc\n\t"
+				".chip 68k");
+	  break;
+	}
+      break;
+
+    case FLUSH_SCOPE_LINE:
+      /* Find the physical address of the first mapped page in the
+	 address range.  */
+      len += addr & 15;
+      addr &= -16;
+      if (!(paddr = virt_to_phys_060(addr))) {
+	unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
+
+	if (len <= tmp)
+	  return 0;
+	addr += tmp;
+	len -= tmp;
+	tmp = PAGE_SIZE;
+	for (;;)
+	  {
+	    if ((paddr = virt_to_phys_060(addr)))
+	      break;
+	    if (len <= tmp)
+	      return 0;
+	    addr += tmp;
+	    len -= tmp;
+	  }
+      }
+      len = (len + 15) >> 4;
+      i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
+      while (len--)
+	{
+	  switch (cache)
+	    {
+	    case FLUSH_CACHE_DATA:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushl %%dc,(%0)\n\t"
+				    "cinvl %%dc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    case FLUSH_CACHE_INSN:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushl %%ic,(%0)\n\t"
+				    "cinvl %%ic,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    default:
+	    case FLUSH_CACHE_BOTH:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushl %%bc,(%0)\n\t"
+				    "cinvl %%bc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    }
+	  if (!--i && len)
+	    {
+
+	      /*
+	       * We just want to jump to the first cache line
+	       * in the next page.
+	       */
+	      addr += PAGE_SIZE;
+	      addr &= PAGE_MASK;
+
+	      i = PAGE_SIZE / 16;
+	      /* Recompute physical address when crossing a page
+	         boundary. */
+	      for (;;)
+	        {
+	          if ((paddr = virt_to_phys_060(addr)))
+	            break;
+	          if (len <= i)
+	            return 0;
+	          len -= i;
+	          addr += PAGE_SIZE;
+	        }
+	    }
+	  else
+	    paddr += 16;
+	}
+      break;
+
+    default:
+    case FLUSH_SCOPE_PAGE:
+      len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
+      addr &= PAGE_MASK;	/* Workaround for bug in some
+				   revisions of the 68060 */
+      for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
+	{
+	  if (!(paddr = virt_to_phys_060(addr)))
+	    continue;
+	  switch (cache)
+	    {
+	    case FLUSH_CACHE_DATA:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushp %%dc,(%0)\n\t"
+				    "cinvp %%dc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    case FLUSH_CACHE_INSN:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushp %%ic,(%0)\n\t"
+				    "cinvp %%ic,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    default:
+	    case FLUSH_CACHE_BOTH:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushp %%bc,(%0)\n\t"
+				    "cinvp %%bc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    }
+	}
+      break;
+    }
+  return 0;
+}
+#endif
+
+/* sys_cacheflush -- flush (part of) the processor cache.  */
+asmlinkage int
+sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
+{
+	int ret = -EINVAL;
+#if DAVIDM /* fixme 5407 */
+	struct vm_area_struct *vma;
+
+	lock_kernel();
+	if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL ||
+	    cache & ~FLUSH_CACHE_BOTH)
+		goto out;
+
+	if (scope == FLUSH_SCOPE_ALL) {
+		/* Only the superuser may flush the whole cache. */
+		ret = -EPERM;
+		if (!capable(CAP_SYS_ADMIN))
+			goto out;
+	} else {
+		/* Verify that the specified address region actually belongs to
+		 * this process.
+		 */
+		vma = find_vma (current->mm, addr);
+		ret = -EINVAL;
+		/* Check for overflow.  */
+		if (addr + len < addr)
+			goto out;
+		if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end)
+			goto out;
+	}
+
+	if (CPU_IS_020_OR_030) {
+		if (scope == FLUSH_SCOPE_LINE && len < 256) {
+			unsigned long cacr;
+			__asm__ ("movec %%cacr, %0" : "=r" (cacr));
+			if (cache & FLUSH_CACHE_INSN)
+				cacr |= 4;
+			if (cache & FLUSH_CACHE_DATA)
+				cacr |= 0x400;
+			len >>= 2;
+			while (len--) {
+				__asm__ __volatile__ ("movec %1, %%caar\n\t"
+						      "movec %0, %%cacr"
+						      : /* no outputs */
+						      : "r" (cacr), "r" (addr));
+				addr += 4;
+			}
+		} else {
+			/* Flush the whole cache, even if page granularity requested. */
+			unsigned long cacr;
+			__asm__ ("movec %%cacr, %0" : "=r" (cacr));
+			if (cache & FLUSH_CACHE_INSN)
+				cacr |= 8;
+			if (cache & FLUSH_CACHE_DATA)
+				cacr |= 0x800;
+			__asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr));
+		}
+		ret = 0;
+		goto out;
+	} else if (CPU_IS_040) {
+		ret = cache_flush_040 (addr, scope, cache, len);
+	} else if (CPU_IS_060) {
+		ret = cache_flush_060 (addr, scope, cache, len);
+	}
+out:
+	unlock_kernel();
+#endif
+	return ret;
+}
+
+asmlinkage int sys_getpagesize(void)
+{
+	return PAGE_SIZE;
+}
+
+/*
+ * Old cruft
+ */
+asmlinkage int sys_pause(void)
+{
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	return -ERESTARTNOHAND;
+}
diff -urN linux-2.4.29/arch/m68knommu/kernel/time.c linux-2.4.29-uc1/arch/m68knommu/kernel/time.c
--- linux-2.4.29/arch/m68knommu/kernel/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/kernel/time.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,184 @@
+/*
+ *  linux/arch/m68k/kernel/time.c
+ *
+ *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *
+ * This file contains the m68k-specific time handling details.
+ * Most of the stuff is located in the machine specific files.
+ *
+ * 1997-09-10	Updated NTP code according to technical memorandum Jan '96
+ *		"A Kernel Model for Precision Timekeeping" by Dave Mills
+ */
+
+#include <linux/config.h> /* CONFIG_HEARTBEAT */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+
+#include <asm/machdep.h>
+#include <asm/io.h>
+
+#include <linux/timex.h>
+
+
+static inline int set_rtc_mmss(unsigned long nowtime)
+{
+  if (mach_set_clock_mmss)
+    return mach_set_clock_mmss (nowtime);
+  return -1;
+}
+
+static inline void do_profile (unsigned long pc)
+{
+	if (prof_buffer && current->pid) {
+		extern int _stext;
+		pc -= (unsigned long) &_stext;
+		pc >>= prof_shift;
+		if (pc < prof_len)
+			++prof_buffer[pc];
+		else
+		/*
+		 * Don't ignore out-of-bounds PC values silently,
+		 * put them into the last histogram slot, so if
+		 * present, they will show up as a sharp peak.
+		 */
+			++prof_buffer[prof_len-1];
+	}
+}
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
+{
+	/* last time the cmos clock got updated */
+	static long last_rtc_update=0;
+
+	/* may need to kick the hardware timer */
+	if (mach_tick)
+	  mach_tick();
+
+	do_timer(regs);
+
+	if (!user_mode(regs))
+		do_profile(regs->pc);
+
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
+	    xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
+	  if (set_rtc_mmss(xtime.tv_sec) == 0)
+	    last_rtc_update = xtime.tv_sec;
+	  else
+	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	}
+#ifdef CONFIG_HEARTBEAT
+	/* use power LED as a heartbeat instead -- much more useful
+	   for debugging -- based on the version for PReP by Cort */
+	/* acts like an actual heart beat -- ie thump-thump-pause... */
+	if (mach_heartbeat) {
+	    static unsigned cnt = 0, period = 0, dist = 0;
+
+	    if (cnt == 0 || cnt == dist)
+		mach_heartbeat( 1 );
+	    else if (cnt == 7 || cnt == dist+7)
+		mach_heartbeat( 0 );
+
+	    if (++cnt > period) {
+		cnt = 0;
+		/* The hyperbolic function below modifies the heartbeat period
+		 * length in dependency of the current (5min) load. It goes
+		 * through the points f(0)=126, f(1)=86, f(5)=51,
+		 * f(inf)->30. */
+		period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
+		dist = period / 4;
+	    }
+	}
+#endif /* CONFIG_HEARTBEAT */
+}
+
+void time_init(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+
+	extern void arch_gettod(int *year, int *mon, int *day, int *hour,
+				int *min, int *sec);
+
+	/* FIX by dqg : Set to zero for platforms that don't have tod */
+	/* without this time is undefined and can overflow time_t, causing  */
+	/* very stange errors */
+	year = 1980;
+	mon = day = 1;
+	hour = min = sec = 0;
+	arch_gettod (&year, &mon, &day, &hour, &min, &sec);
+
+	if ((year += 1900) < 1970)
+		year += 100;
+	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+	xtime.tv_usec = 0;
+
+	mach_sched_init(timer_interrupt);
+}
+
+extern rwlock_t xtime_lock;
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+	extern volatile unsigned long wall_jiffies;
+	unsigned long flags;
+	unsigned long usec, sec, lost;
+
+	read_lock_irqsave(&xtime_lock, flags);
+	usec = mach_gettimeoffset ? mach_gettimeoffset() : 0;
+	lost = jiffies - wall_jiffies;
+	if (lost)
+		usec += lost * (1000000/HZ);
+	sec = xtime.tv_sec;
+	usec += xtime.tv_usec;
+	read_unlock_irqrestore(&xtime_lock, flags);
+
+	while (usec >= 1000000) {
+		usec -= 1000000;
+		sec++;
+	}
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	write_lock_irq(&xtime_lock);
+	/* This is revolting. We need to set the xtime.tv_usec
+	 * correctly. However, the value in this location is
+	 * is value at the last tick.
+	 * Discover what correction gettimeofday
+	 * would have done, and then undo it!
+	 */
+	if (mach_gettimeoffset)
+		tv->tv_usec -= mach_gettimeoffset();
+
+	while (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+
+	xtime = *tv;
+	time_adjust = 0;		/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+	write_unlock_irq(&xtime_lock);
+}
diff -urN linux-2.4.29/arch/m68knommu/kernel/traps.c linux-2.4.29-uc1/arch/m68knommu/kernel/traps.c
--- linux-2.4.29/arch/m68knommu/kernel/traps.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/kernel/traps.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,1105 @@
+/*
+ *  linux/arch/m68k/kernel/traps.c
+ *
+ *  Copyright (C) 1993, 1994 by Hamish Macdonald
+ *
+ *  68040 fixes by Michael Rausch
+ *  68040 fixes by Martin Apel
+ *  68060 fixes by Roman Hodek
+ *  68060 fixes by Jesper Skov
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * Sets up all exception vectors
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/a.out.h>
+#include <linux/user.h>
+#include <linux/string.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/fpu.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/traps.h>
+#include <asm/pgtable.h>
+#include <asm/machdep.h>
+#include <asm/siginfo.h>
+
+/* assembler routines */
+asmlinkage void system_call(void);
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void inthandler(void);
+asmlinkage void nmihandler(void);
+#ifdef CONFIG_M68KFPU_EMU
+asmlinkage void fpu_emu(void);
+#endif
+
+e_vector vectors[256] = {
+	0, 0, buserr, trap, trap, trap, trap, trap,
+	trap, trap, trap, trap, trap, trap, trap, trap,
+	trap, trap, trap, trap, trap, trap, trap, trap,
+#ifdef CONFIG_COLDFIRE
+	inthandler, inthandler, inthandler, inthandler,
+	inthandler, inthandler, inthandler, inthandler,
+#else
+	trap, trap, trap, trap, trap, trap, trap, trap,
+#endif     
+	/* TRAP #0-15 */
+	system_call, trap, trap, trap, trap, trap, trap, trap,
+	trap, trap, trap, trap, trap, trap, trap, trap,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+};
+
+/* nmi handler for the Amiga */
+asm(".text\n"
+    __ALIGN_STR "\n"
+    SYMBOL_NAME_STR(nmihandler) ": rte");
+
+/*
+ * this must be called very early as the kernel might
+ * use some instruction that are emulated on the 060
+ */
+void __init base_trap_init(void)
+{
+#ifdef CONFIG_COLDFIRE
+	/* setup the exception vector table */
+	__asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors));
+#endif
+#if DAVIDM
+	if (CPU_IS_060) {
+		/* set up ISP entry points */
+		asmlinkage void unimp_vec(void) asm ("_060_isp_unimp");
+
+		vectors[VEC_UNIMPII] = unimp_vec;
+	}
+#endif
+}
+
+void __init trap_init (void)
+{
+	if (mach_trap_init)
+		mach_trap_init();
+
+#if 0 /* DAVIDM let the mach layer deal with all of this */
+	int i;
+
+	for (i = 48; i < 64; i++)
+		if (!vectors[i])
+			vectors[i] = trap;
+
+	for (i = 64; i < 256; i++)
+		vectors[i] = inthandler;
+
+#ifdef CONFIG_M68KFPU_EMU
+	if (FPU_IS_EMU)
+		vectors[VEC_LINE11] = fpu_emu;
+#endif
+
+	if (CPU_IS_040 && !FPU_IS_EMU) {
+		/* set up FPSP entry points */
+		asmlinkage void dz_vec(void) asm ("dz");
+		asmlinkage void inex_vec(void) asm ("inex");
+		asmlinkage void ovfl_vec(void) asm ("ovfl");
+		asmlinkage void unfl_vec(void) asm ("unfl");
+		asmlinkage void snan_vec(void) asm ("snan");
+		asmlinkage void operr_vec(void) asm ("operr");
+		asmlinkage void bsun_vec(void) asm ("bsun");
+		asmlinkage void fline_vec(void) asm ("fline");
+		asmlinkage void unsupp_vec(void) asm ("unsupp");
+
+		vectors[VEC_FPDIVZ] = dz_vec;
+		vectors[VEC_FPIR] = inex_vec;
+		vectors[VEC_FPOVER] = ovfl_vec;
+		vectors[VEC_FPUNDER] = unfl_vec;
+		vectors[VEC_FPNAN] = snan_vec;
+		vectors[VEC_FPOE] = operr_vec;
+		vectors[VEC_FPBRUC] = bsun_vec;
+		vectors[VEC_LINE11] = fline_vec;
+		vectors[VEC_FPUNSUP] = unsupp_vec;
+	}
+
+	if (CPU_IS_060 && !FPU_IS_EMU) {
+		/* set up IFPSP entry points */
+		asmlinkage void snan_vec(void) asm ("_060_fpsp_snan");
+		asmlinkage void operr_vec(void) asm ("_060_fpsp_operr");
+		asmlinkage void ovfl_vec(void) asm ("_060_fpsp_ovfl");
+		asmlinkage void unfl_vec(void) asm ("_060_fpsp_unfl");
+		asmlinkage void dz_vec(void) asm ("_060_fpsp_dz");
+		asmlinkage void inex_vec(void) asm ("_060_fpsp_inex");
+		asmlinkage void fline_vec(void) asm ("_060_fpsp_fline");
+		asmlinkage void unsupp_vec(void) asm ("_060_fpsp_unsupp");
+		asmlinkage void effadd_vec(void) asm ("_060_fpsp_effadd");
+
+		vectors[VEC_FPNAN] = snan_vec;
+		vectors[VEC_FPOE] = operr_vec;
+		vectors[VEC_FPOVER] = ovfl_vec;
+		vectors[VEC_FPUNDER] = unfl_vec;
+		vectors[VEC_FPDIVZ] = dz_vec;
+		vectors[VEC_FPIR] = inex_vec;
+		vectors[VEC_LINE11] = fline_vec;
+		vectors[VEC_FPUNSUP] = unsupp_vec;
+		vectors[VEC_UNIMPEA] = effadd_vec;
+	}
+
+        /* if running on an amiga, make the NMI interrupt do nothing */
+	if (MACH_IS_AMIGA) {
+		vectors[VEC_INT7] = nmihandler;
+	}
+#endif
+}
+
+
+
+static char *vec_names[] = {
+	"RESET SP", "RESET PC", "BUS ERROR", "ADDRESS ERROR",
+	"ILLEGAL INSTRUCTION", "ZERO DIVIDE", "CHK", "TRAPcc",
+	"PRIVILEGE VIOLATION", "TRACE", "LINE 1010", "LINE 1111",
+	"UNASSIGNED RESERVED 12", "COPROCESSOR PROTOCOL VIOLATION",
+	"FORMAT ERROR", "UNINITIALIZED INTERRUPT",
+	"UNASSIGNED RESERVED 16", "UNASSIGNED RESERVED 17",
+	"UNASSIGNED RESERVED 18", "UNASSIGNED RESERVED 19",
+	"UNASSIGNED RESERVED 20", "UNASSIGNED RESERVED 21",
+	"UNASSIGNED RESERVED 22", "UNASSIGNED RESERVED 23",
+	"SPURIOUS INTERRUPT", "LEVEL 1 INT", "LEVEL 2 INT", "LEVEL 3 INT",
+	"LEVEL 4 INT", "LEVEL 5 INT", "LEVEL 6 INT", "LEVEL 7 INT",
+	"SYSCALL", "TRAP #1", "TRAP #2", "TRAP #3",
+	"TRAP #4", "TRAP #5", "TRAP #6", "TRAP #7",
+	"TRAP #8", "TRAP #9", "TRAP #10", "TRAP #11",
+	"TRAP #12", "TRAP #13", "TRAP #14", "TRAP #15",
+	"FPCP BSUN", "FPCP INEXACT", "FPCP DIV BY 0", "FPCP UNDERFLOW",
+	"FPCP OPERAND ERROR", "FPCP OVERFLOW", "FPCP SNAN",
+	"FPCP UNSUPPORTED OPERATION",
+	"MMU CONFIGURATION ERROR"
+	};
+
+#ifndef NO_MMU
+#ifndef CONFIG_SUN3
+static char *space_names[] = {
+	"Space 0", "User Data", "User Program", "Space 3",
+	"Space 4", "Super Data", "Super Program", "CPU"
+	};
+#else
+static char *space_names[] = {
+	"Space 0", "User Data", "User Program", "Control",
+	"Space 4", "Super Data", "Super Program", "CPU"
+	};
+#endif
+#endif /* ! NO_MMU */
+
+void die_if_kernel(char *,struct pt_regs *,int);
+asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
+                             unsigned long error_code);
+
+asmlinkage void trap_c(struct frame *fp);
+
+#if defined (CONFIG_M68060)
+static inline void access_error060 (struct frame *fp)
+{
+	unsigned long fslw = fp->un.fmt4.pc; /* is really FSLW for access error */
+
+#ifdef DEBUG
+	printk("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr);
+#endif
+
+	if (fslw & MMU060_BPE) {
+		/* branch prediction error -> clear branch cache */
+		__asm__ __volatile__ ("movec %/cacr,%/d0\n\t"
+				      "orl   #0x00400000,%/d0\n\t"
+				      "movec %/d0,%/cacr"
+				      : : : "d0" );
+		/* return if there's no other error */
+		if ((!(fslw & MMU060_ERR_BITS)) && !(fslw & MMU060_SEE))
+			return;
+	}
+
+	if (fslw & (MMU060_DESC_ERR | MMU060_WP | MMU060_SP)) {
+		unsigned long errorcode;
+		unsigned long addr = fp->un.fmt4.effaddr;
+		errorcode = ((fslw & MMU060_WP) ? 1 : 0) |
+					((fslw & MMU060_W)  ? 2 : 0);
+#ifdef DEBUG
+		printk("errorcode = %d\n", errorcode );
+#endif
+		if (fslw & MMU060_MA)
+			addr = PAGE_ALIGN(addr);
+		do_page_fault(&fp->ptregs, addr, errorcode);
+	} else if (fslw & (MMU060_SEE)){
+		/* Software Emulation Error. Probably an instruction
+		 * using an unsupported addressing mode
+		 */
+		send_sig (SIGSEGV, current, 1);
+	} else {
+		printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr);
+		printk( "68060 access error, fslw=%lx\n", fslw );
+		trap_c( fp );
+	}
+}
+#endif /* CONFIG_M68060 */
+
+#if defined (CONFIG_M68040)
+static inline unsigned long probe040 (int iswrite, int fc, unsigned long addr)
+{
+	unsigned long mmusr;
+	mm_segment_t fs = get_fs();
+
+	set_fs (MAKE_MM_SEG(fc));
+
+	if (iswrite)
+		/* write */
+		asm volatile (".chip 68040\n\t"
+			      "ptestw (%1)\n\t"
+			      "movec %%mmusr,%0\n\t"
+			      ".chip 68k"
+			      : "=r" (mmusr)
+			      : "a" (addr));
+	else
+		asm volatile (".chip 68040\n\t"
+			      "ptestr (%1)\n\t"
+			      "movec %%mmusr,%0\n\t"
+			      ".chip 68k"
+			      : "=r" (mmusr)
+			      : "a" (addr));
+
+	set_fs (fs);
+
+	return mmusr;
+}
+
+static inline void do_040writeback (unsigned short ssw,
+			     unsigned short wbs,
+			     unsigned long wba,
+			     unsigned long wbd,
+			     struct frame *fp)
+{
+	mm_segment_t fs = get_fs ();
+	unsigned long mmusr;
+	unsigned long errorcode;
+
+	/*
+	 * No special handling for the second writeback anymore.
+	 * It misinterpreted the misaligned status sometimes.
+	 * This way an extra page-fault may be caused (Martin Apel).
+	 */
+
+	mmusr = probe040 (1, wbs & WBTM_040,  wba);
+	errorcode = (mmusr & MMU_R_040) ? 3 : 2;
+	if (do_page_fault (&fp->ptregs, wba, errorcode))
+	  /* just return if we can't perform the writeback */
+	  return;
+
+	set_fs (MAKE_MM_SEG(wbs & WBTM_040));
+	switch (wbs & WBSIZ_040) {
+	    case BA_SIZE_BYTE:
+		put_user (wbd & 0xff, (char *)wba);
+		break;
+	    case BA_SIZE_WORD:
+		put_user (wbd & 0xffff, (short *)wba);
+		break;
+	    case BA_SIZE_LONG:
+		put_user (wbd, (int *)wba);
+		break;
+	}
+	set_fs (fs);
+}
+
+static inline void access_error040 (struct frame *fp)
+{
+	unsigned short ssw = fp->un.fmt7.ssw;
+	unsigned long mmusr;
+
+#ifdef DEBUG
+	printk("ssw=%#x, fa=%#lx\n", ssw, fp->un.fmt7.faddr);
+        printk("wb1s=%#x, wb2s=%#x, wb3s=%#x\n", fp->un.fmt7.wb1s,  
+		fp->un.fmt7.wb2s, fp->un.fmt7.wb3s);
+	printk ("wb2a=%lx, wb3a=%lx, wb2d=%lx, wb3d=%lx\n", 
+		fp->un.fmt7.wb2a, fp->un.fmt7.wb3a,
+		fp->un.fmt7.wb2d, fp->un.fmt7.wb3d);
+#endif
+
+
+	if (ssw & ATC_040) {
+		unsigned long addr = fp->un.fmt7.faddr;
+		unsigned long errorcode;
+
+		/*
+		 * The MMU status has to be determined AFTER the address
+		 * has been corrected if there was a misaligned access (MA).
+		 */
+		if (ssw & MA_040)
+			addr = PAGE_ALIGN (addr);
+
+		/* MMU error, get the MMUSR info for this access */
+		mmusr = probe040 (!(ssw & RW_040), ssw & TM_040, addr);
+#ifdef DEBUG
+		printk("mmusr = %lx\n", mmusr);
+#endif
+		errorcode = ((mmusr & MMU_R_040) ? 1 : 0) |
+			((ssw & RW_040) ? 0 : 2);
+#ifdef CONFIG_FTRACE
+		{
+			unsigned long flags;
+
+			save_flags(flags);
+			cli();
+			do_ftrace(0xfa000000 | errorcode);
+			do_ftrace(mmusr);
+			restore_flags(flags);
+		}
+#endif
+		do_page_fault (&fp->ptregs, addr, errorcode);
+	} else {
+		printk ("68040 access error, ssw=%x\n", ssw);
+		trap_c (fp);
+	}
+
+#if 0
+	if (fp->un.fmt7.wb1s & WBV_040)
+		printk("access_error040: cannot handle 1st writeback. oops.\n");
+#endif
+
+/*
+ *  We may have to do a couple of writebacks here.
+ *
+ *  MR: we can speed up the thing a little bit and let do_040writeback()
+ *  not produce another page fault as wb2 corresponds to the address that
+ *  caused the fault. on write faults no second fault is generated, but
+ *  on read faults for security reasons (although per definitionem impossible)
+ */
+
+	if (fp->un.fmt7.wb2s & WBV_040 && (fp->un.fmt7.wb2s &
+					   WBTT_040) != BA_TT_MOVE16)
+		do_040writeback (ssw,
+				 fp->un.fmt7.wb2s, fp->un.fmt7.wb2a,
+				 fp->un.fmt7.wb2d, fp);
+
+	if (fp->un.fmt7.wb3s & WBV_040)
+		do_040writeback (ssw, fp->un.fmt7.wb3s,
+				 fp->un.fmt7.wb3a, fp->un.fmt7.wb3d,
+				 fp);
+}
+#endif /* CONFIG_M68040 */
+
+#if defined(CONFIG_SUN3)
+#include <asm/sun3mmu.h>
+
+extern int mmu_emu_handle_fault (unsigned long, int, int);
+
+/* sun3 version of bus_error030 */
+
+extern inline void bus_error030 (struct frame *fp)
+{
+	unsigned char buserr_type = sun3_get_buserr ();
+	unsigned long addr, errorcode;
+	unsigned short ssw = fp->un.fmtb.ssw;
+
+#if DEBUG
+	if (ssw & (FC | FB))
+		printk ("Instruction fault at %#010lx\n",
+			ssw & FC ?
+			fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
+			:
+			fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
+	if (ssw & DF) 
+		printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
+			ssw & RW ? "read" : "write",
+			fp->un.fmtb.daddr,
+			space_names[ssw & DFC], fp->ptregs.pc);
+#endif
+
+	/*
+	 * Check if this page should be demand-mapped. This needs to go before
+	 * the testing for a bad kernel-space access (demand-mapping applies
+	 * to kernel accesses too).
+	 */
+	
+	if ((ssw & DF)
+	    && (buserr_type & (SUN3_BUSERR_PROTERR | SUN3_BUSERR_INVALID))) {
+		if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 0))
+			return;
+	}
+
+	/* Check for kernel-space pagefault (BAD). */
+	if (fp->ptregs.sr & PS_S) {
+		/* kernel fault must be a data fault to user space */
+		if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) {
+		     // try checking the kernel mappings before surrender
+		     if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 1))
+			  return;
+			/* instruction fault or kernel data fault! */
+			if (ssw & (FC | FB))
+				printk ("Instruction fault at %#010lx\n",
+					fp->ptregs.pc);
+			if (ssw & DF) {
+				printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
+					ssw & RW ? "read" : "write",
+					fp->un.fmtb.daddr,
+					space_names[ssw & DFC], fp->ptregs.pc);
+			}
+			printk ("BAD KERNEL BUSERR\n");
+
+			die_if_kernel("Oops", &fp->ptregs,0);
+			force_sig(SIGKILL, current);
+			return;
+		}
+	} else {
+		/* user fault */
+		if (!(ssw & (FC | FB)) && !(ssw & DF))
+			/* not an instruction fault or data fault! BAD */
+			panic ("USER BUSERR w/o instruction or data fault");
+	}
+
+
+	/* First handle the data fault, if any.  */
+	if (ssw & DF) {
+		addr = fp->un.fmtb.daddr;
+
+// errorcode bit 0:	0 -> no page		1 -> protection fault
+// errorcode bit 1:	0 -> read fault		1 -> write fault
+
+// (buserr_type & SUN3_BUSERR_PROTERR)	-> protection fault
+// (buserr_type & SUN3_BUSERR_INVALID)	-> invalid page fault
+
+		if (buserr_type & SUN3_BUSERR_PROTERR)
+			errorcode = 0x01;
+		else if (buserr_type & SUN3_BUSERR_INVALID)
+			errorcode = 0x00;
+		else {
+			printk ("*** unexpected busfault type=%#04x\n", buserr_type);
+			printk ("invalid %s access at %#lx from pc %#lx\n",
+				!(ssw & RW) ? "write" : "read", addr,
+				fp->ptregs.pc);
+			die_if_kernel ("Oops", &fp->ptregs, buserr_type);
+			force_sig (SIGSEGV, current);
+			return;
+		}
+
+//todo: wtf is RM bit? --m
+		if (!(ssw & RW) || ssw & RM)
+			errorcode |= 0x02;
+
+		/* Handle page fault. */
+		do_page_fault (&fp->ptregs, addr, errorcode);
+
+		/* Retry the data fault now. */
+		return;
+	}
+
+	/* Now handle the instruction fault. */
+
+	/* Get the fault address. */
+	if (fp->ptregs.format == 0xA)
+		addr = fp->ptregs.pc + 4;
+	else
+		addr = fp->un.fmtb.baddr;
+	if (ssw & FC)
+		addr -= 2;
+
+	if (buserr_type & SUN3_BUSERR_INVALID) {
+		if (!mmu_emu_handle_fault (fp->un.fmtb.daddr, 1, 0))
+			do_page_fault (&fp->ptregs, addr, 0);
+       } else {
+#ifdef DEBUG
+		printk ("protection fault on insn access (segv).\n");
+#endif
+		force_sig (SIGSEGV, current);
+       }	
+}
+#else
+#if defined(CPU_M68020_OR_M68030)
+static inline void bus_error030 (struct frame *fp)
+{
+	volatile unsigned short temp;
+	unsigned short mmusr;
+	unsigned long addr, errorcode;
+	unsigned short ssw = fp->un.fmtb.ssw;
+	int user_space_fault = 1;
+#if DEBUG
+	unsigned long desc;
+#endif
+
+#if DEBUG
+	printk ("pid = %x  ", current->pid);
+	printk ("SSW=%#06x  ", ssw);
+
+	if (ssw & (FC | FB))
+		printk ("Instruction fault at %#010lx\n",
+			ssw & FC ?
+			fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
+			:
+			fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
+	if (ssw & DF)
+		printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
+			ssw & RW ? "read" : "write",
+			fp->un.fmtb.daddr,
+			space_names[ssw & DFC], fp->ptregs.pc);
+#endif
+
+	if (fp->ptregs.sr & PS_S) {
+		/* kernel fault must be a data fault to user space */
+		if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) {
+			/* instruction fault or kernel data fault! */
+			if (ssw & (FC | FB))
+				printk ("Instruction fault at %#010lx\n",
+					fp->ptregs.pc);
+			if (ssw & DF) {
+				printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
+					ssw & RW ? "read" : "write",
+					fp->un.fmtb.daddr,
+					space_names[ssw & DFC], fp->ptregs.pc);
+			}
+			printk ("BAD KERNEL BUSERR\n");
+			die_if_kernel("Oops",&fp->ptregs,0);
+			force_sig(SIGKILL, current);
+			return;
+		}
+	} else {
+		/* user fault */
+		if (!(ssw & (FC | FB)) && !(ssw & DF))
+			/* not an instruction fault or data fault! BAD */
+			panic ("USER BUSERR w/o instruction or data fault");
+		user_space_fault = 1;
+#if DEBUG
+		printk("User space bus-error\n");
+#endif
+	}
+
+	/* ++andreas: If a data fault and an instruction fault happen
+	   at the same time map in both pages.  */
+
+	/* First handle the data fault, if any.  */
+	if (ssw & DF)
+	  {
+	    addr = fp->un.fmtb.daddr;
+
+	    mmusr = MMU_I;
+	    if (user_space_fault) {
+#if DEBUG
+		    asm volatile ("ptestr #1,%2@,#7,%0\n\t"
+				  "pmove %/psr,%1@"
+				  : "=a&" (desc)
+				  : "a" (&temp), "a" (addr));
+#else
+		    asm volatile ("ptestr #1,%1@,#7\n\t"
+				  "pmove %/psr,%0@"
+				  : : "a" (&temp), "a" (addr));
+#endif
+		    mmusr = temp;
+	    }
+      
+#if DEBUG
+	    printk ("mmusr is %#x for addr %#lx in task %p\n",
+		    mmusr, addr, current);
+	    printk ("descriptor address is %#lx, contents %#lx\n",
+		    mm_ptov(desc), *(unsigned long *)mm_ptov(desc));
+#endif
+
+	    errorcode = (mmusr & MMU_I) ? 0 : 1;
+	    if (!(ssw & RW) || (ssw & RM))
+		    errorcode |= 2;
+
+	    if (mmusr & (MMU_I | MMU_WP)) {
+		/* Don't try to do anything further if an exception was
+		   handled. */
+		if (do_page_fault (&fp->ptregs, addr, errorcode) < 0)
+			return;
+	    } else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
+		    printk ("invalid %s access at %#lx from pc %#lx\n",
+			    !(ssw & RW) ? "write" : "read", addr,
+			    fp->ptregs.pc);
+		    die_if_kernel("Oops",&fp->ptregs,mmusr);
+		    force_sig(SIGSEGV, current);
+		    return;
+	    } else {
+#if 0
+		    static volatile long tlong;
+#endif
+
+		    printk ("weird %s access at %#lx from pc %#lx (ssw is %#x)\n",
+			    !(ssw & RW) ? "write" : "read", addr,
+			    fp->ptregs.pc, ssw);
+		    asm volatile ("ptestr #1,%1@,#0\n\t"
+				  "pmove %/psr,%0@"
+				  : /* no outputs */
+				  : "a" (&temp), "a" (addr));
+		    mmusr = temp;
+
+		    printk ("level 0 mmusr is %#x\n", mmusr);
+#if 0
+		    asm volatile ("pmove %/tt0,%0@"
+				  : /* no outputs */
+				  : "a" (&tlong));
+		    printk ("tt0 is %#lx, ", tlong);
+		    asm volatile ("pmove %/tt1,%0@"
+				  : /* no outputs */
+				  : "a" (&tlong));
+		    printk ("tt1 is %#lx\n", tlong);
+#endif
+#if DEBUG
+		    printk("Unknown SIGSEGV - 1\n");
+#endif
+		    die_if_kernel("Oops",&fp->ptregs,mmusr);
+		    force_sig(SIGSEGV, current);
+		    return;
+	    }
+
+	    /* setup an ATC entry for the access about to be retried */
+	    if (!(ssw & RW))
+		    asm volatile ("ploadw %1,%0@" : /* no outputs */
+				  : "a" (addr), "d" (ssw));
+	    else
+		    asm volatile ("ploadr %1,%0@" : /* no outputs */
+				  : "a" (addr), "d" (ssw));
+	  }
+
+	/* Now handle the instruction fault. */
+
+	if (!(ssw & (FC|FB)))
+		return;
+
+	/* get the fault address */
+	if (fp->ptregs.format == 10)
+		addr = fp->ptregs.pc + 4;
+	else
+		addr = fp->un.fmtb.baddr;
+	if (ssw & FC)
+		addr -= 2;
+
+	if ((ssw & DF) && ((addr ^ fp->un.fmtb.daddr) & PAGE_MASK) == 0)
+		/* Insn fault on same page as data fault.  But we
+		   should still create the ATC entry.  */
+		goto create_atc_entry;
+
+	mmusr = MMU_I;
+	if (user_space_fault) {
+#if DEBUG
+		asm volatile ("ptestr #1,%2@,#7,%0\n\t"
+			      "pmove %/psr,%1@"
+			      : "=a&" (desc)
+			      : "a" (&temp), "a" (addr));
+#else
+		asm volatile ("ptestr #1,%1@,#7\n\t"
+			      "pmove %/psr,%0@"
+			      : : "a" (&temp), "a" (addr));
+#endif
+		mmusr = temp;
+	}
+      
+#ifdef DEBUG
+	printk ("mmusr is %#x for addr %#lx in task %p\n",
+		mmusr, addr, current);
+	printk ("descriptor address is %#lx, contents %#lx\n",
+		mm_ptov(desc), *(unsigned long *)mm_ptov(desc));
+#endif
+
+	if (mmusr & MMU_I)
+		do_page_fault (&fp->ptregs, addr, 0);
+	else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
+		printk ("invalid insn access at %#lx from pc %#lx\n",
+			addr, fp->ptregs.pc);
+#if DEBUG
+		printk("Unknown SIGSEGV - 2\n");
+#endif
+		die_if_kernel("Oops",&fp->ptregs,mmusr);
+		force_sig(SIGSEGV, current);
+		return;
+	}
+
+create_atc_entry:
+	/* setup an ATC entry for the access about to be retried */
+	asm volatile ("ploadr #2,%0@" : /* no outputs */
+		      : "a" (addr));
+}
+#endif /* CPU_M68020_OR_M68030 */
+#endif /* !CONFIG_SUN3 */
+
+asmlinkage void buserr_c(struct frame *fp)
+{
+	/* Only set esp0 if coming from user mode */
+	if (user_mode(&fp->ptregs))
+		current->thread.esp0 = (unsigned long) fp;
+
+#if DEBUG
+	printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format);
+#endif
+
+	switch (fp->ptregs.format) {
+#if defined (CONFIG_M68060)
+	case 4:				/* 68060 access error */
+	  access_error060 (fp);
+	  break;
+#endif
+#if defined (CONFIG_M68040)
+	case 0x7:			/* 68040 access error */
+	  access_error040 (fp);
+	  break;
+#endif
+#if defined (CPU_M68020_OR_M68030)
+	case 0xa:
+	case 0xb:
+	  bus_error030 (fp);
+	  break;
+#endif
+	default:
+	  die_if_kernel("bad frame format",&fp->ptregs,0);
+#if DEBUG
+	  printk("Unknown SIGSEGV - 4\n");
+#endif
+	  force_sig(SIGSEGV, current);
+	}
+}
+
+
+int kstack_depth_to_print = 48;
+
+/* MODULE_RANGE is a guess of how much space is likely to be
+   vmalloced.  */
+#define MODULE_RANGE (8*1024*1024)
+
+static void show_stack(struct frame *fp)
+{
+	unsigned long *stack, *endstack, addr;
+#if DAVIDM
+	unsigned long module_start, module_end;
+#endif
+	extern char _start, _etext;
+	int i;
+
+	if (fp == NULL)
+		fp = (struct frame *) &fp;
+
+	addr = (unsigned long)&fp->un;
+	printk("Frame format=%X ", fp->ptregs.format);
+	switch (fp->ptregs.format) {
+	case 0x2:
+	    printk("instr addr=%08lx\n", fp->un.fmt2.iaddr);
+	    addr += sizeof(fp->un.fmt2);
+	    break;
+	case 0x3:
+	    printk("eff addr=%08lx\n", fp->un.fmt3.effaddr);
+	    addr += sizeof(fp->un.fmt3);
+	    break;
+	case 0x4:
+#if DAVIDM /* fixme */
+	    printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n"
+		    : "eff addr=%08lx pc=%08lx\n"),
+		   fp->un.fmt4.effaddr, fp->un.fmt4.pc);
+#endif
+	    addr += sizeof(fp->un.fmt4);
+	    break;
+	case 0x7:
+	    printk("eff addr=%08lx ssw=%04x faddr=%08lx\n",
+		   fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr);
+	    printk("wb 1 stat/addr/data: %04x %08lx %08lx\n",
+		   fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0);
+	    printk("wb 2 stat/addr/data: %04x %08lx %08lx\n",
+		   fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d);
+	    printk("wb 3 stat/addr/data: %04x %08lx %08lx\n",
+		   fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d);
+	    printk("push data: %08lx %08lx %08lx %08lx\n",
+		   fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2,
+		   fp->un.fmt7.pd3);
+	    addr += sizeof(fp->un.fmt7);
+	    break;
+	case 0x9:
+	    printk("instr addr=%08lx\n", fp->un.fmt9.iaddr);
+	    addr += sizeof(fp->un.fmt9);
+	    break;
+	case 0xa:
+	    printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
+		   fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb,
+		   fp->un.fmta.daddr, fp->un.fmta.dobuf);
+	    addr += sizeof(fp->un.fmta);
+	    break;
+	case 0xb:
+	    printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
+		   fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb,
+		   fp->un.fmtb.daddr, fp->un.fmtb.dobuf);
+	    printk("baddr=%08lx dibuf=%08lx ver=%x\n",
+		   fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver);
+	    addr += sizeof(fp->un.fmtb);
+	    break;
+	default:
+	    printk("\n");
+	}
+
+	stack = (unsigned long *)addr;
+	endstack = (unsigned long *)PAGE_ALIGN(addr);
+
+	printk("Stack from %08lx:", (unsigned long)stack);
+	for (i = 0; i < kstack_depth_to_print; i++) {
+		if (stack + 1 > endstack)
+			break;
+		if (i % 8 == 0)
+			printk("\n       ");
+		printk(" %08lx", *stack++);
+	}
+
+	printk ("\nCall Trace:");
+	stack = (unsigned long *) addr;
+	i = 0;
+#if 0 /* DAVIDM */
+	module_start = VMALLOC_START;
+	module_end = module_start + MODULE_RANGE;
+#endif
+	while (stack + 1 <= endstack) {
+		addr = *stack++;
+		/*
+		 * If the address is either in the text segment of the
+		 * kernel, or in the region which contains vmalloc'ed
+		 * memory, it *may* be the address of a calling
+		 * routine; if so, print it so that someone tracing
+		 * down the cause of the crash will be able to figure
+		 * out the call path that was taken.
+		 */
+		if (((addr >= (unsigned long) &_start) &&
+		     (addr <= (unsigned long) &_etext))
+#if 0 /* DAVIDM */
+			 || ((addr >= module_start) && (addr <= module_end))
+#endif
+			) {
+			if (i % 4 == 0)
+				printk("\n       ");
+			printk(" [<%08lx>]", addr);
+			i++;
+		}
+	}
+	printk("\nCode: ");
+	for (i = 0; i < 10; i++)
+		printk("%04x ", 0xffff & ((short *) fp->ptregs.pc)[i]);
+	printk ("\n");
+}
+
+/*
+ * The architecture-independent backtrace generator
+ */
+void dump_stack(void)
+{
+	show_stack(0);
+}
+
+void bad_super_trap (struct frame *fp)
+{
+	console_verbose();
+	if (fp->ptregs.vector < 4*sizeof(vec_names)/sizeof(vec_names[0]))
+		printk ("*** %s ***   FORMAT=%X\n",
+			vec_names[(fp->ptregs.vector) >> 2],
+			fp->ptregs.format);
+	else
+		printk ("*** Exception %d ***   FORMAT=%X\n",
+			(fp->ptregs.vector) >> 2, 
+			fp->ptregs.format);
+#if 0 /* DAVIDM */
+	if (fp->ptregs.vector >> 2 == VEC_ADDRERR && CPU_IS_020_OR_030) {
+		unsigned short ssw = fp->un.fmtb.ssw;
+
+		printk ("SSW=%#06x  ", ssw);
+
+		if (ssw & RC)
+			printk ("Pipe stage C instruction fault at %#010lx\n",
+				(fp->ptregs.format) == 0xA ?
+				fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2);
+		if (ssw & RB)
+			printk ("Pipe stage B instruction fault at %#010lx\n",
+				(fp->ptregs.format) == 0xA ?
+				fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
+		if (ssw & DF)
+			printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
+				ssw & RW ? "read" : "write",
+				fp->un.fmtb.daddr, space_names[ssw & DFC],
+				fp->ptregs.pc);
+	}
+#endif
+	printk ("Current process id is %d\n", current->pid);
+	die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
+}
+
+asmlinkage void trap_c(struct frame *fp)
+{
+	int sig;
+	siginfo_t info;
+
+	if (fp->ptregs.sr & PS_S) {
+		if ((fp->ptregs.vector >> 2) == VEC_TRACE) {
+			/* traced a trapping instruction */
+			current->ptrace |= PT_DTRACE;
+		} else
+			bad_super_trap(fp);
+		return;
+	}
+
+	/* send the appropriate signal to the user program */
+	switch ((fp->ptregs.vector) >> 2) {
+	    case VEC_ADDRERR:
+		info.si_code = BUS_ADRALN;
+		sig = SIGBUS;
+		break;
+	    case VEC_ILLEGAL:
+	    case VEC_LINE10:
+	    case VEC_LINE11:
+		info.si_code = ILL_ILLOPC;
+		sig = SIGILL;
+		break;
+	    case VEC_PRIV:
+		info.si_code = ILL_PRVOPC;
+		sig = SIGILL;
+		break;
+	    case VEC_COPROC:
+		info.si_code = ILL_COPROC;
+		sig = SIGILL;
+		break;
+	    case VEC_TRAP1: /* gdbserver breakpoint */
+		fp->ptregs.pc -= 2;
+		info.si_code = TRAP_TRACE;
+		sig = SIGTRAP;
+		break;
+	    case VEC_TRAP2:
+	    case VEC_TRAP3:
+	    case VEC_TRAP4:
+	    case VEC_TRAP5:
+	    case VEC_TRAP6:
+	    case VEC_TRAP7:
+	    case VEC_TRAP8:
+	    case VEC_TRAP9:
+	    case VEC_TRAP10:
+	    case VEC_TRAP11:
+	    case VEC_TRAP12:
+	    case VEC_TRAP13:
+	    case VEC_TRAP14:
+		info.si_code = ILL_ILLTRP;
+		sig = SIGILL;
+		break;
+	    case VEC_FPBRUC:
+	    case VEC_FPOE:
+	    case VEC_FPNAN:
+		info.si_code = FPE_FLTINV;
+		sig = SIGFPE;
+		break;
+	    case VEC_FPIR:
+		info.si_code = FPE_FLTRES;
+		sig = SIGFPE;
+		break;
+	    case VEC_FPDIVZ:
+		info.si_code = FPE_FLTDIV;
+		sig = SIGFPE;
+		break;
+	    case VEC_FPUNDER:
+		info.si_code = FPE_FLTUND;
+		sig = SIGFPE;
+		break;
+	    case VEC_FPOVER:
+		info.si_code = FPE_FLTOVF;
+		sig = SIGFPE;
+		break;
+	    case VEC_ZERODIV:
+		info.si_code = FPE_INTDIV;
+		sig = SIGFPE;
+		break;
+	    case VEC_CHK:
+	    case VEC_TRAP:
+		info.si_code = FPE_INTOVF;
+		sig = SIGFPE;
+		break;
+	    case VEC_TRACE:		/* ptrace single step */
+		info.si_code = TRAP_TRACE;
+		sig = SIGTRAP;
+		break;
+	    case VEC_TRAP15:		/* breakpoint */
+		info.si_code = TRAP_BRKPT;
+		sig = SIGTRAP;
+		break;
+	    default:
+		info.si_code = ILL_ILLOPC;
+		sig = SIGILL;
+		break;
+	}
+	info.si_signo = sig;
+	info.si_errno = 0;
+	switch (fp->ptregs.format) {
+	    default:
+		info.si_addr = (void *) fp->ptregs.pc;
+		break;
+	    case 2:
+		info.si_addr = (void *) fp->un.fmt2.iaddr;
+		break;
+	    case 7:
+		info.si_addr = (void *) fp->un.fmt7.effaddr;
+		break;
+	    case 9:
+		info.si_addr = (void *) fp->un.fmt9.iaddr;
+		break;
+	    case 10:
+		info.si_addr = (void *) fp->un.fmta.daddr;
+		break;
+	    case 11:
+		info.si_addr = (void *) fp->un.fmtb.daddr;
+		break;
+	}
+	force_sig_info (sig, &info, current);
+}
+
+asmlinkage void set_esp0 (unsigned long ssp)
+{
+	current->thread.esp0 = ssp;
+}
+
+void show_trace_task(struct task_struct *tsk)
+{
+	/* DAVIDM: we can do better, need a proper stack dump */
+	printk("STACK ksp=0x%lx, usp=0x%lx\n", tsk->thread.ksp, tsk->thread.usp);
+}
+
+void die_if_kernel (char *str, struct pt_regs *fp, int nr)
+{
+	if (!(fp->sr & PS_S))
+		return;
+
+	console_verbose();
+	printk("%s: %08x\n",str,nr);
+	printk("PC: [<%08lx>]\nSR: %04x  SP: %p  a2: %08lx\n",
+	       fp->pc, fp->sr, fp, fp->a2);
+	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+	       fp->d0, fp->d1, fp->d2, fp->d3);
+	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+	       fp->d4, fp->d5, fp->a0, fp->a1);
+
+	printk("Process %s (pid: %d, stackpage=%08lx)\n",
+		current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
+	show_stack((struct frame *)fp);
+	do_exit(SIGSEGV);
+}
+
+/*
+ * This function is called if an error occur while accessing
+ * user-space from the fpsp040 code.
+ */
+asmlinkage void fpsp040_die(void)
+{
+	do_exit(SIGSEGV);
+}
+
+#ifdef CONFIG_M68KFPU_EMU
+asmlinkage void fpemu_signal(int signal, int code, void *addr)
+{
+	siginfo_t info;
+
+	info.si_signo = signal;
+	info.si_errno = 0;
+	info.si_code = code;
+	info.si_addr = addr;
+	force_sig_info(signal, &info, current);
+}
+#endif
diff -urN linux-2.4.29/arch/m68knommu/lib/ashrdi3.c linux-2.4.29-uc1/arch/m68knommu/lib/ashrdi3.c
--- linux-2.4.29/arch/m68knommu/lib/ashrdi3.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/lib/ashrdi3.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,63 @@
+/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define BITS_PER_UNIT 8
+
+typedef 	 int SItype	__attribute__ ((mode (SI)));
+typedef unsigned int USItype	__attribute__ ((mode (SI)));
+typedef		 int DItype	__attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
+DItype
+__ashrdi3 (DItype u, word_type b)
+{
+  DIunion w;
+  word_type bm;
+  DIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ll = u;
+
+  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      /* w.s.high = 1..1 or 0..0 */
+      w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
+      w.s.low = uu.s.high >> -bm;
+    }
+  else
+    {
+      USItype carries = (USItype)uu.s.high << bm;
+      w.s.high = uu.s.high >> b;
+      w.s.low = ((USItype)uu.s.low >> b) | carries;
+    }
+
+  return w.ll;
+}
diff -urN linux-2.4.29/arch/m68knommu/lib/checksum.c linux-2.4.29-uc1/arch/m68knommu/lib/checksum.c
--- linux-2.4.29/arch/m68knommu/lib/checksum.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/lib/checksum.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,157 @@
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		IP/TCP/UDP checksumming routines
+ *
+ * Authors:	Jorge Cwik, <jorge@laser.satlink.net>
+ *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ *		Tom May, <ftom@netcom.com>
+ *		Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
+ *		Lots of code moved from tcp.c and ip.c; see those files
+ *		for more names.
+ *
+ * 03/02/96	Jes Sorensen, Andreas Schwab, Roman Hodek:
+ *		Fixed some nasty bugs, causing some horrible crashes.
+ *		A: At some points, the sum (%0) was used as
+ *		length-counter instead of the length counter
+ *		(%1). Thanks to Roman Hodek for pointing this out.
+ *		B: GCC seems to mess up if one uses too many
+ *		data-registers to hold input values and one tries to
+ *		specify d0 and d1 as scratch registers. Letting gcc choose these
+ *      registers itself solves the problem.
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+ 
+/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most
+   of the assembly has to go. */
+
+#include <net/checksum.h>
+#include <asm/checksum.h>
+
+static inline unsigned short from32to16(unsigned long x)
+{
+	/* add up 16-bit and 16-bit for 16+c bit */
+	x = (x & 0xffff) + (x >> 16);
+	/* add up carry.. */
+	x = (x & 0xffff) + (x >> 16);
+	return x;
+}
+
+static unsigned long do_csum(const unsigned char * buff, int len)
+{
+	int odd, count;
+	unsigned long result = 0;
+
+	if (len <= 0)
+		goto out;
+	odd = 1 & (unsigned long) buff;
+	if (odd) {
+		result = *buff;
+		len--;
+		buff++;
+	}
+	count = len >> 1;		/* nr of 16-bit words.. */
+	if (count) {
+		if (2 & (unsigned long) buff) {
+			result += *(unsigned short *) buff;
+			count--;
+			len -= 2;
+			buff += 2;
+		}
+		count >>= 1;		/* nr of 32-bit words.. */
+		if (count) {
+		        unsigned long carry = 0;
+			do {
+				unsigned long w = *(unsigned long *) buff;
+				count--;
+				buff += 4;
+				result += carry;
+				result += w;
+				carry = (w > result);
+			} while (count);
+			result += carry;
+			result = (result & 0xffff) + (result >> 16);
+		}
+		if (len & 2) {
+			result += *(unsigned short *) buff;
+			buff += 2;
+		}
+	}
+	if (len & 1)
+		result += (*buff << 8);
+	result = from32to16(result);
+	if (odd)
+		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+	return result;
+}
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ */
+unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
+{
+	return ~do_csum(iph,ihl*4);
+}
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
+{
+	unsigned int result = do_csum(buff, len);
+
+	/* add in old sum, and carry.. */
+	result += sum;
+	if (sum > result)
+		result += 1;
+	return result;
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+unsigned short ip_compute_csum(const unsigned char * buff, int len)
+{
+	return ~do_csum(buff,len);
+}
+
+/*
+ * copy from fs while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err)
+{
+	if (csum_err) *csum_err = 0;
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
+
+/*
+ * copy from ds while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy(const char *src, char *dst, int len, int sum)
+{
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
diff -urN linux-2.4.29/arch/m68knommu/lib/delay.c linux-2.4.29-uc1/arch/m68knommu/lib/delay.c
--- linux-2.4.29/arch/m68knommu/lib/delay.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/lib/delay.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,18 @@
+/*
+ *	arch/m68knommu/lib/delay.c
+ *
+ *	(C) Copyright 2004, Greg Ungerer <gerg@snapgear.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <asm/param.h>
+#include <asm/delay.h>
+
+void udelay(unsigned long usecs)
+{
+	_udelay(usecs);
+}
+
diff -urN linux-2.4.29/arch/m68knommu/lib/Makefile linux-2.4.29-uc1/arch/m68knommu/lib/Makefile
--- linux-2.4.29/arch/m68knommu/lib/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/lib/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,11 @@
+#
+# Makefile for m68k-specific library files..
+#
+
+.S.o:
+	$(CC) $(AFLAGS) -D__ASSEMBLY__ -traditional -c $< -o $@
+
+L_TARGET = lib.a
+obj-y  = ashrdi3.o checksum.o semaphore.o memcpy.o memset.o delay.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/lib/memcpy.c linux-2.4.29-uc1/arch/m68knommu/lib/memcpy.c
--- linux-2.4.29/arch/m68knommu/lib/memcpy.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/lib/memcpy.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,63 @@
+
+#include <linux/types.h>
+#include <linux/autoconf.h>
+
+void * memcpy(void * to, const void * from, size_t n)
+{
+#ifdef CONFIG_COLDFIRE
+  void *xto = to;
+  size_t temp;
+
+  if (!n)
+    return xto;
+  if ((long) to & 1)
+    {
+      char *cto = to;
+      const char *cfrom = from;
+      *cto++ = *cfrom++;
+      to = cto;
+      from = cfrom;
+      n--;
+    }
+  if (n > 2 && (long) to & 2)
+    {
+      short *sto = to;
+      const short *sfrom = from;
+      *sto++ = *sfrom++;
+      to = sto;
+      from = sfrom;
+      n -= 2;
+    }
+  temp = n >> 2;
+  if (temp)
+    {
+      long *lto = to;
+      const long *lfrom = from;
+      for (; temp; temp--)
+	*lto++ = *lfrom++;
+      to = lto;
+      from = lfrom;
+    }
+  if (n & 2)
+    {
+      short *sto = to;
+      const short *sfrom = from;
+      *sto++ = *sfrom++;
+      to = sto;
+      from = sfrom;
+    }
+  if (n & 1)
+    {
+      char *cto = to;
+      const char *cfrom = from;
+      *cto = *cfrom;
+    }
+  return xto;
+#else
+  const char *c_from = from;
+  char *c_to = to;
+  while (n-- > 0)
+    *c_to++ = *c_from++;
+  return((void *) to);
+#endif
+}
diff -urN linux-2.4.29/arch/m68knommu/lib/memset.c linux-2.4.29-uc1/arch/m68knommu/lib/memset.c
--- linux-2.4.29/arch/m68knommu/lib/memset.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/lib/memset.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,47 @@
+#include <linux/types.h>
+
+void * memset(void * s, int c, size_t count)
+{
+  void *xs = s;
+  size_t temp;
+
+  if (!count)
+    return xs;
+  c &= 0xff;
+  c |= c << 8;
+  c |= c << 16;
+  if ((long) s & 1)
+    {
+      char *cs = s;
+      *cs++ = c;
+      s = cs;
+      count--;
+    }
+  if (count > 2 && (long) s & 2)
+    {
+      short *ss = s;
+      *ss++ = c;
+      s = ss;
+      count -= 2;
+    }
+  temp = count >> 2;
+  if (temp)
+    {
+      long *ls = s;
+      for (; temp; temp--)
+	*ls++ = c;
+      s = ls;
+    }
+  if (count & 2)
+    {
+      short *ss = s;
+      *ss++ = c;
+      s = ss;
+    }
+  if (count & 1)
+    {
+      char *cs = s;
+      *cs = c;
+    }
+  return xs;
+}
diff -urN linux-2.4.29/arch/m68knommu/lib/semaphore.S linux-2.4.29-uc1/arch/m68knommu/lib/semaphore.S
--- linux-2.4.29/arch/m68knommu/lib/semaphore.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/lib/semaphore.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,67 @@
+/*
+ *  linux/arch/m68k/lib/semaphore.S
+ *
+ *  Copyright (C) 1996  Linus Torvalds
+ *
+ *  m68k version by Andreas Schwab
+ *
+ *  MAR/1999 -- modified to support ColdFire (gerg@snapgear.com)
+ */
+
+#include <linux/linkage.h>
+#include <linux/config.h>
+#include <asm/semaphore.h>
+
+/*
+ * "down_failed" is called with the eventual return address
+ * in %a0, and the address of the semaphore in %a1. We need
+ * to increment the number of waiters on the semaphore,
+ * call "__down()", and then eventually return to try again.
+ */
+ENTRY(__down_failed)
+#ifdef CONFIG_COLDFIRE
+	subl #12,%sp
+	moveml %a0/%d0/%d1,(%sp)
+#else
+	moveml %a0/%d0/%d1,-(%sp)
+#endif
+	movel %a1,-(%sp)
+	jbsr SYMBOL_NAME(__down)
+	movel (%sp)+,%a1
+	movel (%sp)+,%d0
+	movel (%sp)+,%d1
+	rts
+
+ENTRY(__down_failed_interruptible)
+	movel %a0,-(%sp)
+	movel %d1,-(%sp)
+	movel %a1,-(%sp)
+	jbsr SYMBOL_NAME(__down_interruptible)
+	movel (%sp)+,%a1
+	movel (%sp)+,%d1
+	rts
+
+ENTRY(__up_wakeup)
+#ifdef CONFIG_COLDFIRE
+	subl #12,%sp
+	moveml %a0/%d0/%d1,(%sp)
+#else
+	moveml %a0/%d0/%d1,-(%sp)
+#endif
+	movel %a1,-(%sp)
+	jbsr SYMBOL_NAME(__up)
+	movel (%sp)+,%a1
+	movel (%sp)+,%d0
+	movel (%sp)+,%d1
+	rts
+
+ENTRY(__down_failed_trylock)
+	movel %a0,-(%sp)
+	movel %d1,-(%sp)
+	movel %a1,-(%sp)
+	jbsr SYMBOL_NAME(__down_trylock)
+	movel (%sp)+,%a1
+	movel (%sp)+,%d1
+	movel (%sp)+,%a0
+	rts
+
diff -urN linux-2.4.29/arch/m68knommu/Makefile linux-2.4.29-uc1/arch/m68knommu/Makefile
--- linux-2.4.29/arch/m68knommu/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,64 @@
+#
+# m68knommu/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 1999,2001  D. Jeff Dionne <jeff@uClinux.org>,
+#	                   Rt-Control Inc. / Lineo, Inc.
+#
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uclinux.org>,
+#                          Kenneth Albanowski <kjahds@kjahds.com>,
+#
+# Based on arch/m68k/Makefile:
+# Copyright (C) 1994 by Hamish Macdonald
+#
+
+# test for cross compiling
+COMPILE_ARCH = $(shell uname -m)
+
+#
+# If you want the kernel build to build modules outside of the tree
+# then define this and pass it to the main linux makefile
+#
+ifdef EXTRA_MODULE_DIRS
+SUBDIRS += $(EXTRA_MODULE_DIRS)
+endif
+
+UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\"
+
+# Find out which board we are compiling for
+include arch/$(ARCH)/Boards.mk
+
+# Set up the memory model.  RAM or ROM.
+ifdef CONFIG_RAMKERNEL
+MODEL = ram
+endif
+ifdef CONFIG_ROMKERNEL
+MODEL = rom
+endif
+ifdef CONFIG_HIMEMKERNEL
+MODEL = himem
+endif
+export MODEL
+
+# get the compiler, flags and targets from the platform
+ifdef PLATFORM
+include arch/$(ARCH)/platform/$(PLATFORM)/Rules.make
+endif
+
+arch/$(ARCH)/empty.o:
+	$(CROSS_COMPILE)gcc -o arch/$(ARCH)/empty.o -c arch/$(ARCH)/empty.c
+
+bootstrap:
+	@$(MAKEBOOT) bootstrap
+
+archmrproper:
+
+archdep:
diff -urN linux-2.4.29/arch/m68knommu/mm/fault.c linux-2.4.29-uc1/arch/m68knommu/mm/fault.c
--- linux-2.4.29/arch/m68knommu/mm/fault.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/mm/fault.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,57 @@
+/*
+ *  linux/arch/m68knommu/mm/fault.c
+ *
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@uClinux.org>,
+ *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com) 
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68k/mm/fault.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ */
+
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+
+extern void die_if_kernel(char *, struct pt_regs *, long);
+
+/*
+ * This routine handles page faults.  It determines the problem, and
+ * then passes it off to one of the appropriate routines.
+ *
+ * error_code:
+ *	bit 0 == 0 means no page found, 1 means protection fault
+ *	bit 1 == 0 means read, 1 means write
+ *
+ * If this routine detects a bad access, it returns 1, otherwise it
+ * returns 0.
+ */
+asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
+			      unsigned long error_code)
+{
+#ifdef DEBUG
+	printk ("regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n",
+		regs->sr, regs->pc, address, error_code);
+#endif
+
+/*
+ * Oops. The kernel tried to access some bad page. We'll have to
+ * terminate things with extreme prejudice.
+ */
+	if ((unsigned long) address < PAGE_SIZE) {
+		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
+	} else
+		printk(KERN_ALERT "Unable to handle kernel access");
+	printk(" at virtual address %08lx\n",address);
+	die_if_kernel("Oops", regs, error_code);
+	do_exit(SIGKILL);
+
+	return 1;
+}
+
diff -urN linux-2.4.29/arch/m68knommu/mm/init.c linux-2.4.29-uc1/arch/m68knommu/mm/init.c
--- linux-2.4.29/arch/m68knommu/mm/init.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/mm/init.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,276 @@
+/*
+ *  linux/arch/m68knommu/mm/init.c
+ *
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@uClinux.org>,
+ *                      Kenneth Albanowski <kjahds@kjahds.com>,
+ *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com) 
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68k/mm/init.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ *
+ *  JAN/1999 -- hacked to support ColdFire (gerg@snapgear.com)
+ *  DEC/2000 -- linux 2.4 support <davidm@lineo.com>
+ */
+
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#ifdef CONFIG_BLK_DEV_RAM
+#include <linux/blk.h>
+#endif
+#include <linux/bootmem.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/machdep.h>
+#include <asm/shglcore.h>
+#include <asm/virtconvert.h>
+
+#undef DEBUG
+
+static unsigned long totalram_pages = 0;
+
+extern void die_if_kernel(char *,struct pt_regs *,long);
+
+extern void free_initmem(void);
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+static unsigned long empty_bad_page_table;
+
+static unsigned long empty_bad_page;
+
+unsigned long empty_zero_page;
+
+extern unsigned long rom_length;
+
+void show_mem(void)
+{
+    unsigned long i;
+    int free = 0, total = 0, reserved = 0, shared = 0;
+
+    printk("\nMem-info:\n");
+    show_free_areas();
+    i = max_mapnr;
+    while (i-- > 0) {
+	total++;
+	if (PageReserved(mem_map+i))
+	    reserved++;
+	else if (!page_count(mem_map+i))
+	    free++;
+	else
+	    shared += page_count(mem_map+i) - 1;
+    }
+    printk("%d pages of RAM\n",total);
+    printk("%d free pages\n",free);
+    printk("%d reserved pages\n",reserved);
+    printk("%d pages shared\n",shared);
+    show_buffers();
+}
+
+extern unsigned long memory_start;
+extern unsigned long memory_end;
+
+/*
+ * paging_init() continues the virtual memory environment setup which
+ * was begun by the code in arch/head.S.
+ * The parameters are pointers to where to stick the starting and ending
+ * addresses  of available kernel virtual memory.
+ */
+void paging_init(void)
+{
+	/*
+	 * make sure start_mem is page aligned,  otherwise bootmem and
+	 * page_alloc get different views og the world
+	 */
+#ifdef DEBUG
+	unsigned long start_mem = PAGE_ALIGN(memory_start);
+#endif
+	unsigned long end_mem   = memory_end & PAGE_MASK;
+
+#ifdef DEBUG
+	printk ("start_mem is %#lx\nvirtual_end is %#lx\n",
+		start_mem, end_mem);
+#endif
+
+	/*
+	 * initialize the bad page table and bad page to point
+	 * to a couple of allocated pages
+	 */
+	empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	memset((void *)empty_zero_page, 0, PAGE_SIZE);
+
+	/*
+	 * Set up SFC/DFC registers (user data space)
+	 */
+	set_fs (USER_DS);
+
+#ifdef DEBUG
+	printk ("before free_area_init\n");
+
+	printk ("free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n",
+		start_mem, end_mem);
+#endif
+
+	{
+		unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+
+		zones_size[ZONE_DMA]     = 0 >> PAGE_SHIFT;
+		zones_size[ZONE_NORMAL]  = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
+#ifdef CONFIG_HIGHMEM
+		zones_size[ZONE_HIGHMEM] = 0;
+#endif
+		free_area_init_node(0, NULL, NULL, zones_size, PAGE_OFFSET, NULL);
+	}
+}
+
+void mem_init(void)
+{
+	int codek = 0, datak = 0, initk = 0;
+	/* DAVIDM look at setup memory map generically with reserved area */
+	unsigned long tmp;
+#ifdef CONFIG_UCLINUX
+	extern char _etext, _stext, _sdata, _ebss, __init_begin, __init_end;
+	extern unsigned int _ramend, _rambase;
+	unsigned long len = _ramend - _rambase;
+#else
+	extern char _etext, _romvec, __data_start;
+	unsigned long len = end_mem-(unsigned long)&__data_start;
+	int datapages = 0;
+#endif
+	unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */
+	unsigned long end_mem   = memory_end; /* DAVIDM - this must not include kernel stack at top */
+
+	/* Bloody watchdog... */
+#ifdef CONFIG_SHGLCORE
+       (*((volatile unsigned char*)0xFFFA21)) = 128 | 64/* | 32 | 16*/;
+       (*((volatile unsigned short*)0xFFFA24)) &= ~512;
+       (*((volatile unsigned char*)0xFFFA27)) = 0x55;
+       (*((volatile unsigned char*)0xFFFA27)) = 0xAA;
+       
+       /*printk("Initiated watchdog, SYPCR = %x\n", *(volatile char*)0xFFFA21);*/
+#endif	                
+
+#ifdef DEBUG
+	printk("Mem_init: start=%lx, end=%lx\n", start_mem, end_mem);
+#endif
+
+	end_mem &= PAGE_MASK;
+	high_memory = (void *) end_mem;
+
+	start_mem = PAGE_ALIGN(start_mem);
+	max_mapnr = num_physpages = MAP_NR(high_memory);
+
+	/* this will put all memory onto the freelists */
+	totalram_pages = free_all_bootmem();
+
+#ifdef CONFIG_UCLINUX
+	codek = (&_etext - &_stext) >> 10;
+	datak = (&_ebss - &_sdata) >> 10;
+	initk = (&__init_begin - &__init_end) >> 10;
+#else
+	for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
+		if (PageReserved(mem_map+MAP_NR(tmp))) {
+			datapages++;
+			continue;
+		}
+	}
+	
+	codek = (&_etext - &_romvec) >> 10;
+	datak = datapages << (PAGE_SHIFT-10);
+	initk = 0;
+#endif
+
+	tmp = nr_free_pages() << PAGE_SHIFT;
+	printk("Memory available: %luk/%luk RAM, %luk/%luk ROM (%dk kernel code, %dk data)\n",
+	       tmp >> 10,
+	       len >> 10,
+	       (rom_length > 0) ? ((rom_length >> 10) - codek) : 0,
+	       rom_length >> 10,
+	       codek,
+	       datak
+	       );
+}
+
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	int pages = 0;
+	for (; start < end; start += PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(start));
+		set_page_count(virt_to_page(start), 1);
+		free_page(start);
+		totalram_pages++;
+		pages++;
+	}
+	printk("Freeing initrd memory: %dk freed\n", (pages * PAGE_SIZE) >> 10);
+}
+#endif
+
+
+void si_meminfo(struct sysinfo *val)
+{
+    unsigned long i;
+
+    i = max_mapnr;
+    val->totalram = totalram_pages;
+    val->sharedram = 0;
+    val->freeram = nr_free_pages();
+    val->bufferram = atomic_read(&buffermem_pages);
+    val->totalhigh = 0;
+    val->freehigh = 0;
+    val->mem_unit = PAGE_SIZE;
+    return;
+}
+
+
+void
+free_initmem()
+{
+#if defined(CONFIG_RAMKERNEL) && !(defined(CONFIG_UCDIMM) || defined(CONFIG_CLIE))
+	unsigned long addr;
+	extern char __init_begin, __init_end;
+/*
+ *	the following code should be cool even if these sections
+ *	are not page aligned.
+ */
+	addr = PAGE_ALIGN((unsigned long)(&__init_begin));
+	/* next to check that the page we free is not a partial page */
+	for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(addr));
+		set_page_count(virt_to_page(addr), 1);
+		free_page(addr);
+		totalram_pages++;
+	}
+	printk("Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n",
+			(addr - PAGE_ALIGN((long) &__init_begin)) >> 10,
+			PAGE_ALIGN((unsigned long)(&__init_begin)),
+			addr - PAGE_SIZE);
+#endif
+}
+
diff -urN linux-2.4.29/arch/m68knommu/mm/kmap.c linux-2.4.29-uc1/arch/m68knommu/mm/kmap.c
--- linux-2.4.29/arch/m68knommu/mm/kmap.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/mm/kmap.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,55 @@
+/*
+ *  linux/arch/m68knommu/mm/kmap.c
+ *
+ *  Copyright (C) 2000 Lineo, <davidm@lineo.com>
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#undef DEBUG
+
+/*
+ * Map some physical address range into the kernel address space.
+ */
+
+void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
+{
+	return (void *)physaddr;
+}
+
+/*
+ * Unmap a ioremap()ed region again
+ */
+void iounmap(void *addr)
+{
+}
+
+/*
+ * __iounmap unmaps nearly everything, so be careful
+ * it doesn't free currently pointer/page tables anymore but it
+ * wans't used anyway and might be added later.
+ */
+void __iounmap(void *addr, unsigned long size)
+{
+}
+
+/*
+ * Set new cache mode for some kernel address space.
+ * The caller must push data for that range itself, if such data may already
+ * be in the cache.
+ */
+void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
+{
+}
diff -urN linux-2.4.29/arch/m68knommu/mm/Makefile linux-2.4.29-uc1/arch/m68knommu/mm/Makefile
--- linux-2.4.29/arch/m68knommu/mm/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/mm/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,13 @@
+#
+# Makefile for the linux m68k-specific parts of the memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET := mm.o
+obj-y	 := init.o fault.o memory.o kmap.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/mm/memory.c linux-2.4.29-uc1/arch/m68knommu/mm/memory.c
--- linux-2.4.29/arch/m68knommu/mm/memory.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/mm/memory.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,1089 @@
+/*
+ *  linux/arch/m68knommu/mm/memory.c
+ *
+ *  Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *
+ *  MAR/1999 -- hacked for the ColdFire (gerg@snapgear.com)
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68k/mm/memory.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/shglcore.h>
+#include <asm/virtconvert.h>
+
+#ifndef NO_MM
+
+extern pte_t *kernel_page_table (unsigned long *memavailp);
+
+/* Strings for `extern inline' functions in <asm/pgtable.h>.  If put
+   directly into these functions, they are output for every file that
+   includes pgtable.h */
+
+const char PgtabStr_bad_pmd[] = "Bad pmd in pte_alloc: %08lx\n";
+const char PgtabStr_bad_pgd[] = "Bad pgd in pmd_alloc: %08lx\n";
+const char PgtabStr_bad_pmdk[] = "Bad pmd in pte_alloc_kernel: %08lx\n";
+const char PgtabStr_bad_pgdk[] = "Bad pgd in pmd_alloc_kernel: %08lx\n";
+
+static struct ptable_desc {
+	struct ptable_desc *prev;
+	struct ptable_desc *next;
+	unsigned long	   page;
+	unsigned char	   alloced;
+} ptable_list = { &ptable_list, &ptable_list, 0, 0xff };
+
+#define PD_NONEFREE(dp) ((dp)->alloced == 0xff)
+#define PD_ALLFREE(dp) ((dp)->alloced == 0)
+#define PD_TABLEFREE(dp,i) (!((dp)->alloced & (1<<(i))))
+#define PD_MARKUSED(dp,i) ((dp)->alloced |= (1<<(i)))
+#define PD_MARKFREE(dp,i) ((dp)->alloced &= ~(1<<(i)))
+
+#define PTABLE_SIZE (PTRS_PER_PMD * sizeof(pmd_t))
+
+pmd_t *get_pointer_table (void)
+{
+	pmd_t *pmdp = NULL;
+	unsigned long flags;
+	struct ptable_desc *dp = ptable_list.next;
+	int i;
+
+	/*
+	 * For a pointer table for a user process address space, a
+	 * table is taken from a page allocated for the purpose.  Each
+	 * page can hold 8 pointer tables.  The page is remapped in
+	 * virtual address space to be noncacheable.
+	 */
+	if (PD_NONEFREE (dp)) {
+
+		if (!(dp = kmalloc (sizeof(struct ptable_desc),GFP_KERNEL))) {
+			return 0;
+		}
+
+		if (!(dp->page = __get_free_page (GFP_KERNEL))) {
+			kfree (dp);
+			return 0;
+		}
+
+		nocache_page (dp->page);
+
+		dp->alloced = 0;
+		/* put at head of list */
+		save_flags(flags);
+		cli();
+		dp->next = ptable_list.next;
+		dp->prev = ptable_list.next->prev;
+		ptable_list.next->prev = dp;
+		ptable_list.next = dp;
+		restore_flags(flags);
+	}
+
+	for (i = 0; i < 8; i++)
+		if (PD_TABLEFREE (dp, i)) {
+			PD_MARKUSED (dp, i);
+			pmdp = (pmd_t *)(dp->page + PTABLE_SIZE*i);
+			break;
+		}
+
+	if (PD_NONEFREE (dp)) {
+		/* move to end of list */
+		save_flags(flags);
+		cli();
+		dp->prev->next = dp->next;
+		dp->next->prev = dp->prev;
+
+		dp->next = ptable_list.next->prev;
+		dp->prev = ptable_list.prev;
+		ptable_list.prev->next = dp;
+		ptable_list.prev = dp;
+		restore_flags(flags);
+	}
+
+	memset (pmdp, 0, PTABLE_SIZE);
+
+	return pmdp;
+}
+
+void free_pointer_table (pmd_t *ptable)
+{
+	struct ptable_desc *dp;
+	unsigned long page = (unsigned long)ptable & PAGE_MASK;
+	int index = ((unsigned long)ptable - page)/PTABLE_SIZE;
+	unsigned long flags;
+
+	for (dp = ptable_list.next; dp->page && dp->page != page; dp = dp->next)
+		;
+
+	if (!dp->page)
+		panic ("unable to find desc for ptable %p on list!", ptable);
+
+	if (PD_TABLEFREE (dp, index))
+		panic ("table already free!");
+
+	PD_MARKFREE (dp, index);
+
+	if (PD_ALLFREE (dp)) {
+		/* all tables in page are free, free page */
+		save_flags(flags);
+		cli();
+		dp->prev->next = dp->next;
+		dp->next->prev = dp->prev;
+		restore_flags(flags);
+		cache_page (dp->page);
+		free_page (dp->page);
+		kfree (dp);
+		return;
+	} else {
+		/*
+		 * move this descriptor the the front of the list, since
+		 * it has one or more free tables.
+		 */
+		save_flags(flags);
+		cli();
+		dp->prev->next = dp->next;
+		dp->next->prev = dp->prev;
+
+		dp->next = ptable_list.next;
+		dp->prev = ptable_list.next->prev;
+		ptable_list.next->prev = dp;
+		ptable_list.next = dp;
+		restore_flags(flags);
+	}
+}
+
+/* maximum pages used for kpointer tables */
+#define KPTR_PAGES      4
+/* # of reserved slots */
+#define RESERVED_KPTR	4
+extern pmd_tablepage kernel_pmd_table; /* reserved in head.S */
+
+static struct kpointer_pages {
+        pmd_tablepage *page[KPTR_PAGES];
+        u_char alloced[KPTR_PAGES];
+} kptr_pages;
+
+void init_kpointer_table(void) {
+	short i = KPTR_PAGES-1;
+
+	/* first page is reserved in head.S */
+	kptr_pages.page[i] = &kernel_pmd_table;
+	kptr_pages.alloced[i] = ~(0xff>>RESERVED_KPTR);
+	for (i--; i>=0; i--) {
+		kptr_pages.page[i] = NULL;
+		kptr_pages.alloced[i] = 0;
+	}
+}
+
+pmd_t *get_kpointer_table (void)
+{
+	/* For pointer tables for the kernel virtual address space,
+	 * use the page that is reserved in head.S that can hold up to
+	 * 8 pointer tables. 3 of these tables are always reserved
+	 * (kernel_pg_dir, swapper_pg_dir and kernel pointer table for
+	 * the first 16 MB of RAM). In addition, the 4th pointer table
+	 * in this page is reserved. On Amiga and Atari, it is used to
+	 * map in the hardware registers. It may be used for other
+	 * purposes on other 68k machines. This leaves 4 pointer tables
+	 * available for use by the kernel. 1 of them are usually used
+	 * for the vmalloc tables. This allows mapping of 3 * 32 = 96 MB
+	 * of physical memory. But these pointer tables are also used
+	 * for other purposes, like kernel_map(), so further pages can
+	 * now be allocated.
+	 */
+	pmd_tablepage *page;
+	pmd_table *table;
+	long nr, offset = -8;
+	short i;
+
+	for (i=KPTR_PAGES-1; i>=0; i--) {
+		asm volatile("bfffo %1{%2,#8},%0"
+			: "=d" (nr)
+			: "d" ((u_char)~kptr_pages.alloced[i]), "d" (offset));
+		if (nr)
+			break;
+	}
+	if (i < 0) {
+		printk("No space for kernel pointer table!\n");
+		return NULL;
+	}
+	if (!(page = kptr_pages.page[i])) {
+		if (!(page = (pmd_tablepage *)__get_free_page(GFP_KERNEL))) {
+			printk("No space for kernel pointer table!\n");
+			return NULL;
+		}
+		nocache_page((u_long)(kptr_pages.page[i] = page));
+	}
+	asm volatile("bfset %0@{%1,#1}"
+		: /* no output */
+		: "a" (&kptr_pages.alloced[i]), "d" (nr-offset));
+	table = &(*page)[nr-offset];
+	memset(table, 0, sizeof(pmd_table));
+	return ((pmd_t *)table);
+}
+
+void free_kpointer_table (pmd_t *pmdp)
+{
+	pmd_table *table = (pmd_table *)pmdp;
+	pmd_tablepage *page = (pmd_tablepage *)((u_long)table & PAGE_MASK);
+	long nr;
+	short i;
+
+	for (i=KPTR_PAGES-1; i>=0; i--) {
+		if (kptr_pages.page[i] == page)
+			break;
+	}
+	nr = ((u_long)table - (u_long)page) / sizeof(pmd_table);
+	if (!table || i < 0 || (i == KPTR_PAGES-1 && nr < RESERVED_KPTR)) {
+		printk("Attempt to free invalid kernel pointer table: %p\n", table);
+		return;
+	}
+	asm volatile("bfclr %0@{%1,#1}"
+		: /* no output */
+		: "a" (&kptr_pages.alloced[i]), "d" (nr));
+	if (!kptr_pages.alloced[i]) {
+		kptr_pages.page[i] = 0;
+		cache_page ((u_long)page);
+		free_page ((u_long)page);
+	}
+}
+
+static unsigned long transp_transl_matches( unsigned long regval,
+					    unsigned long vaddr )
+{
+    unsigned long base, mask;
+
+    /* enabled? */
+    if (!(regval & 0x8000))
+	return( 0 );
+
+    if (CPU_IS_030) {
+	/* function code match? */
+	base = (regval >> 4) & 7;
+	mask = ~(regval & 7);
+	if ((SUPER_DATA & mask) != (base & mask))
+	    return( 0 );
+    }
+    else {
+	/* must not be user-only */
+	if ((regval & 0x6000) == 0)
+	    return( 0 );
+    }
+
+    /* address match? */
+    base = regval & 0xff000000;
+    mask = ~((regval << 8) & 0xff000000);
+    return( (vaddr & mask) == (base & mask) );
+}
+
+/*
+ * The following two routines map from a physical address to a kernel
+ * virtual address and vice versa.
+ */
+unsigned long mm_vtop (unsigned long vaddr)
+{
+	int i;
+	unsigned long voff = vaddr;
+	unsigned long offset = 0;
+
+	for (i = 0; i < boot_info.num_memory; i++)
+	{
+		if (voff < offset + boot_info.memory[i].size) {
+#ifdef DEBUGPV
+			printk ("virt_to_phys(%lx)=%lx\n", vaddr,
+				boot_info.memory[i].addr + voff - offset);
+#endif
+			return boot_info.memory[i].addr + voff - offset;
+		} else
+			offset += boot_info.memory[i].size;
+	}
+
+	/* not in one of the memory chunks; test for applying transparent
+	 * translation */
+
+	if (CPU_IS_030) {
+	    unsigned long ttreg;
+
+	    asm volatile(   "movel %1, %%a2\n\t"
+			    ".long 0xf0120a00;" /* pmove %/tt0,%a0@ */
+			  : "=g" (ttreg) : "g" (&ttreg) : "cc", "%a2" );
+	    if (transp_transl_matches( ttreg, vaddr ))
+		return vaddr;
+
+	    asm volatile(   "movel %1, %%a2\n\t"
+			    ".long 0xf0120a00" /* pmove %/tt1,%a0@ */
+			  : "=g" (ttreg) : "g" (&ttreg) : "cc", "%a2" );
+	    if (transp_transl_matches( ttreg, vaddr ))
+		return vaddr;
+	}
+	else if (CPU_IS_040_OR_060) {
+	    unsigned long ttreg;
+	    
+	    asm volatile(   ".long 0x4e7a0006\n\t" /* movec %dtt0,%d0 */
+			    "movel %%d0, %0\n"
+			  : "=g" (ttreg) );
+	    if (transp_transl_matches( ttreg, vaddr ))
+		return vaddr;
+	    asm volatile(   ".long 0x4e7a0007" /* movec %dtt1,%d0 */
+			    "movel %%d0, %0\n"
+			  : "=g" (ttreg) );
+	    if (transp_transl_matches( ttreg, vaddr ))
+		return vaddr;
+	}
+
+	/* no match, too, so get the actual physical address from the MMU. */
+
+	if (CPU_IS_060) {
+	  unsigned long fs = get_fs();
+	  unsigned long  paddr;
+
+	  set_fs (SUPER_DATA);
+
+	  /* The PLPAR instruction causes an access error if the translation
+	   * is not possible. We don't catch that here, so a bad kernel trap
+	   * will be reported in this case. */
+	  asm volatile ("movel %1,%/a0\n\t"
+			".word 0xf5c8\n\t"	/* plpar (a0) */
+			"movel %/a0,%0"
+			: "=g" (paddr)
+			: "g" (vaddr)
+			: "a0" );
+	  set_fs (fs);
+
+	  return paddr;
+
+	} else if (CPU_IS_040) {
+	  unsigned long mmusr;
+	  unsigned long fs = get_fs();
+
+	  set_fs (SUPER_DATA);
+
+	  asm volatile ("movel %1,%/a0\n\t"
+			".word 0xf568\n\t"	/* ptestr (a0) */
+			".long 0x4e7a8805\n\t"	/* movec mmusr, a0 */
+			"movel %/a0,%0"
+			: "=g" (mmusr)
+			: "g" (vaddr)
+			: "a0", "d0");
+	  set_fs (fs);
+
+	  if (mmusr & MMU_R_040)
+	    return (mmusr & PAGE_MASK) | (vaddr & (PAGE_SIZE-1));
+
+	  panic ("virt_to_phys040: bad virtual address %08lx (%lx)", vaddr, mmusr);
+	} else {
+	  volatile unsigned short temp;
+	  unsigned short mmusr;
+	  unsigned long *descaddr;
+
+	  asm volatile ("ptestr #5,%2@,#7,%0\n\t"
+			"pmove %/psr,%1@"
+			: "=a&" (descaddr)
+			: "a" (&temp), "a" (vaddr));
+	  mmusr = temp;
+
+	  if (mmusr & (MMU_I|MMU_B|MMU_L))
+	    panic ("virt_to_phys030: bad virtual address %08lx (%x)", vaddr, mmusr);
+
+	  descaddr = (unsigned long *)phys_to_virt(descaddr);
+
+	  switch (mmusr & MMU_NUM) {
+	  case 1:
+	    return (*descaddr & 0xfe000000) | (vaddr & 0x01ffffff);
+	  case 2:
+	    return (*descaddr & 0xfffc0000) | (vaddr & 0x0003ffff);
+	  case 3:
+	    return (*descaddr & PAGE_MASK) | (vaddr & (PAGE_SIZE-1));
+	  default:
+	    panic ("virt_to_phys: bad levels (%u) for virtual address %08lx", 
+		   mmusr & MMU_NUM, vaddr);
+	  }
+	}
+
+	panic ("virt_to_phys: bad virtual address %08lx", vaddr);
+}
+
+unsigned long mm_ptov (unsigned long paddr)
+{
+	int i;
+	unsigned long offset = 0;
+
+	for (i = 0; i < boot_info.num_memory; i++)
+	{
+		if (paddr >= boot_info.memory[i].addr &&
+		    paddr < (boot_info.memory[i].addr
+			     + boot_info.memory[i].size)) {
+#ifdef DEBUGPV
+			printk ("phys_to_virt(%lx)=%lx\n", paddr,
+				(paddr - boot_info.memory[i].addr) + offset);
+#endif
+			return (paddr - boot_info.memory[i].addr) + offset;
+		} else
+			offset += boot_info.memory[i].size;
+	}
+
+	/*
+	 * assume that the kernel virtual address is the same as the
+	 * physical address.
+	 *
+	 * This should be reasonable in most situations:
+	 *  1) They shouldn't be dereferencing the virtual address
+	 *     unless they are sure that it is valid from kernel space.
+	 *  2) The only usage I see so far is converting a page table
+	 *     reference to some non-FASTMEM address space when freeing
+         *     mmaped "/dev/mem" pages.  These addresses are just passed
+	 *     to "free_page", which ignores addresses that aren't in
+	 *     the memory list anyway.
+	 *
+	 */
+
+	/*
+	 * if on an amiga and address is in first 16M, move it 
+	 * to the ZTWO_ADDR range
+	 */
+	if (MACH_IS_AMIGA && paddr < 16*1024*1024)
+		return ZTWO_VADDR(paddr);
+	return paddr;
+}
+
+/* invalidate page in both caches */
+#define	clear040(paddr) __asm__ __volatile__ ("movel %0,%/a0\n\t"\
+					      "nop\n\t"\
+					      ".word 0xf4d0"\
+					      /* CINVP I/D (a0) */\
+					      : : "g" ((paddr))\
+					      : "a0")
+
+/* invalidate page in i-cache */
+#define	cleari040(paddr) __asm__ __volatile__ ("movel %0,%/a0\n\t"\
+					       /* CINVP I (a0) */\
+					       "nop\n\t"\
+					       ".word 0xf490"\
+					       : : "g" ((paddr))\
+					       : "a0")
+
+/* push page in both caches */
+#define	push040(paddr) __asm__ __volatile__ ("movel %0,%/a0\n\t"\
+					      "nop\n\t"\
+					     ".word 0xf4f0"\
+					     /* CPUSHP I/D (a0) */\
+					     : : "g" ((paddr))\
+					     : "a0")
+
+/* push and invalidate page in both caches */
+#define	pushcl040(paddr) do { push040((paddr));\
+			      if (CPU_IS_060) clear040((paddr));\
+			 } while(0)
+
+/* push page in both caches, invalidate in i-cache */
+#define	pushcli040(paddr) do { push040((paddr));\
+			       if (CPU_IS_060) cleari040((paddr));\
+			  } while(0)
+
+/* push page defined by virtual address in both caches */
+#define	pushv040(vaddr) __asm__ __volatile__ ("movel %0,%/a0\n\t"\
+					      /* ptestr (a0) */\
+					      "nop\n\t"\
+					      ".word 0xf568\n\t"\
+					      /* movec mmusr,d0 */\
+					      ".long 0x4e7a0805\n\t"\
+					      "andw #0xf000,%/d0\n\t"\
+					      "movel %/d0,%/a0\n\t"\
+					      /* CPUSHP I/D (a0) */\
+					      "nop\n\t"\
+					      ".word 0xf4f0"\
+					      : : "g" ((vaddr))\
+					      : "a0", "d0")
+
+/* push page defined by virtual address in both caches */
+#define	pushv060(vaddr) __asm__ __volatile__ ("movel %0,%/a0\n\t"\
+					      /* plpar (a0) */\
+					      ".word 0xf5c8\n\t"\
+					      /* CPUSHP I/D (a0) */\
+					      ".word 0xf4f0"\
+					      : : "g" ((vaddr))\
+					      : "a0")
+
+
+/*
+ * 040: Hit every page containing an address in the range paddr..paddr+len-1.
+ * (Low order bits of the ea of a CINVP/CPUSHP are "don't care"s).
+ * Hit every page until there is a page or less to go. Hit the next page,
+ * and the one after that if the range hits it.
+ */
+/* ++roman: A little bit more care is required here: The CINVP instruction
+ * invalidates cache entries WITHOUT WRITING DIRTY DATA BACK! So the beginning
+ * and the end of the region must be treated differently if they are not
+ * exactly at the beginning or end of a page boundary. Else, maybe too much
+ * data becomes invalidated and thus lost forever. CPUSHP does what we need:
+ * it invalidates the page after pushing dirty data to memory. (Thanks to Jes
+ * for discovering the problem!)
+ */
+/* ... but on the '060, CPUSH doesn't invalidate (for us, since we have set
+ * the DPI bit in the CACR; would it cause problems with temporarily changing
+ * this?). So we have to push first and then additionally to invalidate.
+ */
+
+/*
+ * cache_clear() semantics: Clear any cache entries for the area in question,
+ * without writing back dirty entries first. This is useful if the data will
+ * be overwritten anyway, e.g. by DMA to memory. The range is defined by a
+ * _physical_ address.
+ */
+
+void cache_clear (unsigned long paddr, int len)
+{
+    if (CPU_IS_040_OR_060) {
+	/*
+	 * cwe need special treatment for the first page, in case it
+	 * is not page-aligned.
+	 */
+	if (paddr & (PAGE_SIZE - 1)){
+	    pushcl040(paddr);
+	    if (len <= PAGE_SIZE){
+		if (((paddr + len - 1) ^ paddr) & PAGE_MASK) {
+		    pushcl040(paddr + len - 1);
+		}
+		return;
+	    }else{
+		len -=PAGE_SIZE;
+		paddr += PAGE_SIZE;
+	    }
+	}
+		
+	while (len > PAGE_SIZE) {
+#if 0
+	    pushcl040(paddr);
+#else
+	    clear040(paddr);
+#endif
+	    len -= PAGE_SIZE;
+	    paddr += PAGE_SIZE;
+	}
+	if (len > 0) {
+	    pushcl040(paddr);
+	    if (((paddr + len - 1) ^ paddr) & PAGE_MASK) {
+		/* a page boundary gets crossed at the end */
+		pushcl040(paddr + len - 1);
+	    }
+	}
+    }
+    else /* 68030 or 68020 */
+	asm volatile ("movec %/cacr,%/d0\n\t"
+		      "oriw %0,%/d0\n\t"
+		      "movec %/d0,%/cacr"
+		      : : "i" (FLUSH_I_AND_D)
+		      : "d0");
+}
+
+
+/*
+ * cache_push() semantics: Write back any dirty cache data in the given area,
+ * and invalidate the range in the instruction cache. It needs not (but may)
+ * invalidate those entries also in the data cache. The range is defined by a
+ * _physical_ address.
+ */
+
+void cache_push (unsigned long paddr, int len)
+{
+    if (CPU_IS_040_OR_060) {
+	/*
+         * on 68040 or 68060, push cache lines for pages in the range;
+	 * on the '040 this also invalidates the pushed lines, but not on
+	 * the '060!
+	 */
+	while (len > PAGE_SIZE) {
+	    pushcli040(paddr);
+	    len -= PAGE_SIZE;
+	    paddr += PAGE_SIZE;
+	    }
+	if (len > 0) {
+	    pushcli040(paddr);
+	    if (((paddr + len - 1) ^ paddr) & PAGE_MASK) {
+		/* a page boundary gets crossed at the end */
+		pushcli040(paddr + len - 1);
+		}
+	    }
+	}
+    
+    
+    /*
+     * 68030/68020 have no writeback cache. On the other hand,
+     * cache_push is actually a superset of cache_clear (the lines
+     * get written back and invalidated), so we should make sure
+     * to perform the corresponding actions. After all, this is getting
+     * called in places where we've just loaded code, or whatever, so
+     * flushing the icache is appropriate; flushing the dcache shouldn't
+     * be required.
+     */
+    else /* 68030 or 68020 */
+	asm volatile ("movec %/cacr,%/d0\n\t"
+		      "oriw %0,%/d0\n\t"
+		      "movec %/d0,%/cacr"
+		      : : "i" (FLUSH_I)
+		      : "d0");
+}
+
+
+/*
+ * cache_push_v() semantics: Write back any dirty cache data in the given
+ * area, and invalidate those entries at least in the instruction cache. This
+ * is intended to be used after data has been written that can be executed as
+ * code later. The range is defined by a _user_mode_ _virtual_ address  (or,
+ * more exactly, the space is defined by the %sfc/%dfc register.)
+ */
+
+void cache_push_v (unsigned long vaddr, int len)
+{
+    if (CPU_IS_040) {
+	/* on 68040, push cache lines for pages in the range */
+	while (len > PAGE_SIZE) {
+	    pushv040(vaddr);
+	    len -= PAGE_SIZE;
+	    vaddr += PAGE_SIZE;
+	    }
+	if (len > 0) {
+	    pushv040(vaddr);
+	    if (((vaddr + len - 1) ^ vaddr) & PAGE_MASK) {
+		/* a page boundary gets crossed at the end */
+		pushv040(vaddr + len - 1);
+		}
+	    }
+	}
+    else if (CPU_IS_060) {
+	/* on 68040, push cache lines for pages in the range */
+	while (len > PAGE_SIZE) {
+	    pushv060(vaddr);
+	    len -= PAGE_SIZE;
+	    vaddr += PAGE_SIZE;
+	}
+	if (len > 0) {
+	    pushv060(vaddr);
+	    if (((vaddr + len - 1) ^ vaddr) & PAGE_MASK) {
+		/* a page boundary gets crossed at the end */
+		pushv060(vaddr + len - 1);
+	    }
+	}
+    }
+    /* 68030/68020 have no writeback cache; still need to clear icache. */
+    else /* 68030 or 68020 */
+	asm volatile ("movec %/cacr,%/d0\n\t"
+		      "oriw %0,%/d0\n\t"
+		      "movec %/d0,%/cacr"
+		      : : "i" (FLUSH_I)
+		      : "d0");
+}
+
+#undef clear040
+#undef cleari040
+#undef push040
+#undef pushcl040
+#undef pushcli040
+#undef pushv040
+#undef pushv060
+
+int mm_end_of_chunk (unsigned long addr, int len)
+{
+	int i;
+
+	for (i = 0; i < boot_info.num_memory; i++)
+		if (boot_info.memory[i].addr + boot_info.memory[i].size
+		    == addr + len)
+			return 1;
+	return 0;
+}
+
+/* Map some physical address range into the kernel address space. The
+ * code is copied and adapted from map_chunk().
+ */
+
+unsigned long kernel_map(unsigned long paddr, unsigned long size,
+			 int nocacheflag, unsigned long *memavailp )
+{
+#define STEP_SIZE	(256*1024)
+
+	static unsigned long vaddr = 0xe0000000; /* safe place */
+	unsigned long physaddr, retaddr;
+	pte_t *ktablep = NULL;
+	pmd_t *kpointerp;
+	pgd_t *page_dir;
+	int pindex;   /* index into pointer table */
+	int prot;
+	
+	/* Round down 'paddr' to 256 KB and adjust size */
+	physaddr = paddr & ~(STEP_SIZE-1);
+	size += paddr - physaddr;
+	retaddr = vaddr + (paddr - physaddr);
+	paddr = physaddr;
+	/* Round up the size to 256 KB. It doesn't hurt if too much is
+	 * mapped... */
+	size = (size + STEP_SIZE - 1) & ~(STEP_SIZE-1);
+
+	if (CPU_IS_040_OR_060) {
+		prot = _PAGE_PRESENT | _PAGE_GLOBAL040;
+		switch( nocacheflag ) {
+		  case KERNELMAP_FULL_CACHING:
+			prot |= _PAGE_CACHE040;
+			break;
+		  case KERNELMAP_NOCACHE_SER:
+		  default:
+			prot |= _PAGE_NOCACHE_S;
+			break;
+		  case KERNELMAP_NOCACHE_NONSER:
+			prot |= _PAGE_NOCACHE;
+			break;
+		  case KERNELMAP_NO_COPYBACK:
+			prot |= _PAGE_CACHE040W;
+			/* prot |= 0; */
+			break;
+		}
+	} else
+		prot = _PAGE_PRESENT |
+			   ((nocacheflag == KERNELMAP_FULL_CACHING ||
+				 nocacheflag == KERNELMAP_NO_COPYBACK) ? 0 : _PAGE_NOCACHE030);
+	
+	page_dir = pgd_offset_k(vaddr);
+	if (pgd_present(*page_dir)) {
+		kpointerp = (pmd_t *)pgd_page(*page_dir);
+		pindex = (vaddr >> 18) & 0x7f;
+		if (pindex != 0 && CPU_IS_040_OR_060) {
+			if (pmd_present(*kpointerp))
+				ktablep = (pte_t *)pmd_page(*kpointerp);
+			else {
+				ktablep = kernel_page_table (memavailp);
+				/* Make entries invalid */
+				memset( ktablep, 0, sizeof(long)*PTRS_PER_PTE);
+				pmd_set(kpointerp,ktablep);
+			}
+			ktablep += (pindex & 15)*64;
+		}
+	}
+	else {
+		/* we need a new pointer table */
+		kpointerp = get_kpointer_table ();
+		pgd_set(page_dir, (pmd_t *)kpointerp);
+		memset( kpointerp, 0, PTRS_PER_PMD*sizeof(pmd_t));
+		pindex = 0;
+	}
+
+	for (physaddr = paddr; physaddr < paddr + size; vaddr += STEP_SIZE) {
+
+		if (pindex > 127) {
+			/* we need a new pointer table */
+			kpointerp = get_kpointer_table ();
+			pgd_set(pgd_offset_k(vaddr), (pmd_t *)kpointerp);
+			memset( kpointerp, 0, PTRS_PER_PMD*sizeof(pmd_t));
+			pindex = 0;
+		}
+
+		if (CPU_IS_040_OR_060) {
+			int i;
+			unsigned long ktable;
+
+			/*
+			 * 68040, use page tables pointed to by the
+			 * kernel pointer table.
+			 */
+
+			if ((pindex & 15) == 0) {
+				/* Need new page table every 4M on the '040 */
+				ktablep = kernel_page_table (memavailp);
+				/* Make entries invalid */
+				memset( ktablep, 0, sizeof(long)*PTRS_PER_PTE);
+			}
+
+			ktable = virt_to_phys(ktablep);
+
+			/*
+			 * initialize section of the page table mapping
+			 * this 1M portion.
+			 */
+			for (i = 0; i < 64; i++) {
+				pte_val(*ktablep++) = physaddr | prot;
+				physaddr += PAGE_SIZE;
+			}
+
+			/*
+			 * make the kernel pointer table point to the
+			 * kernel page table.
+			 */
+
+			((unsigned long *)kpointerp)[pindex++] = ktable | _PAGE_TABLE;
+
+		} else {
+			/*
+			 * 68030, use early termination page descriptors.
+			 * Each one points to 64 pages (256K).
+			 */
+			((unsigned long *)kpointerp)[pindex++] = physaddr | prot;
+			physaddr += 64 * PAGE_SIZE;
+		}
+	}
+
+	return( retaddr );
+}
+
+
+static inline void set_cmode_pte( pmd_t *pmd, unsigned long address,
+				  unsigned long size, unsigned cmode )
+{	pte_t *pte;
+	unsigned long end;
+
+	if (pmd_none(*pmd))
+		return;
+
+	pte = pte_offset( pmd, address );
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end >= PMD_SIZE)
+		end = PMD_SIZE;
+
+	for( ; address < end; pte++ ) {
+		pte_val(*pte) = (pte_val(*pte) & ~_PAGE_NOCACHE) | cmode;
+		address += PAGE_SIZE;
+	}
+}
+
+
+static inline void set_cmode_pmd( pgd_t *dir, unsigned long address,
+				  unsigned long size, unsigned cmode )
+{
+	pmd_t *pmd;
+	unsigned long end;
+
+	if (pgd_none(*dir))
+		return;
+
+	pmd = pmd_offset( dir, address );
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+
+	if ((pmd_val(*pmd) & _DESCTYPE_MASK) == _PAGE_PRESENT) {
+		/* 68030 early termination descriptor */
+		pmd_val(*pmd) = (pmd_val(*pmd) & ~_PAGE_NOCACHE) | cmode;
+		return;
+	}
+	else {
+		/* "normal" tables */
+		for( ; address < end; pmd++ ) {
+			set_cmode_pte( pmd, address, end - address, cmode );
+			address = (address + PMD_SIZE) & PMD_MASK;
+		}
+	}
+}
+
+
+/*
+ * Set new cache mode for some kernel address space.
+ * The caller must push data for that range itself, if such data may already
+ * be in the cache.
+ */
+
+void kernel_set_cachemode( unsigned long address, unsigned long size,
+						   unsigned cmode )
+{
+	pgd_t *dir = pgd_offset_k( address );
+	unsigned long end = address + size;
+	
+	if (CPU_IS_040_OR_060) {
+		switch( cmode ) {
+		  case KERNELMAP_FULL_CACHING:
+			cmode = _PAGE_CACHE040;
+			break;
+		  case KERNELMAP_NOCACHE_SER:
+		  default:
+			cmode = _PAGE_NOCACHE_S;
+			break;
+		  case KERNELMAP_NOCACHE_NONSER:
+			cmode = _PAGE_NOCACHE;
+			break;
+		  case KERNELMAP_NO_COPYBACK:
+			cmode = _PAGE_CACHE040W;
+			break;
+		}
+	} else
+		cmode = ((cmode == KERNELMAP_FULL_CACHING ||
+				  cmode == KERNELMAP_NO_COPYBACK)    ?
+			 0 : _PAGE_NOCACHE030);
+
+	for( ; address < end; dir++ ) {
+		set_cmode_pmd( dir, address, end - address, cmode );
+		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+	}
+	flush_tlb_all();
+}
+
+#else /* !NO_MM */
+
+/*
+ * 040: Hit every page containing an address in the range paddr..paddr+len-1.
+ * (Low order bits of the ea of a CINVP/CPUSHP are "don't care"s).
+ * Hit every page until there is a page or less to go. Hit the next page,
+ * and the one after that if the range hits it.
+ */
+/* ++roman: A little bit more care is required here: The CINVP instruction
+ * invalidates cache entries WITHOUT WRITING DIRTY DATA BACK! So the beginning
+ * and the end of the region must be treated differently if they are not
+ * exactly at the beginning or end of a page boundary. Else, maybe too much
+ * data becomes invalidated and thus lost forever. CPUSHP does what we need:
+ * it invalidates the page after pushing dirty data to memory. (Thanks to Jes
+ * for discovering the problem!)
+ */
+/* ... but on the '060, CPUSH doesn't invalidate (for us, since we have set
+ * the DPI bit in the CACR; would it cause problems with temporarily changing
+ * this?). So we have to push first and then additionally to invalidate.
+ */
+
+/*
+ * cache_clear() semantics: Clear any cache entries for the area in question,
+ * without writing back dirty entries first. This is useful if the data will
+ * be overwritten anyway, e.g. by DMA to memory. The range is defined by a
+ * _physical_ address.
+ */
+
+void cache_clear (unsigned long paddr, int len)
+{
+}
+
+
+/*
+ *	Define cache invalidate functions. The ColdFire 5407 is really
+ *	the only processor that needs to do some work here. Anything
+ *	that has separate data and instruction caches will be a problem.
+ */
+#ifdef CONFIG_M5407
+
+static __inline__ void cache_invalidate_lines(unsigned long paddr, int len)
+{
+	unsigned long	sset, eset;
+
+	sset = (paddr & 0x00000ff0);
+	eset = ((paddr + len) & 0x0000ff0) + 0x10;
+
+	__asm__ __volatile__ (
+		"nop\n\t"
+		"clrl	%%d0\n\t"
+		"1:\n\t"
+		"movel	%0,%%a0\n\t"
+		"addl	%%d0,%%a0\n\t"
+		"2:\n\t"
+		".word	0xf4e8\n\t"
+		"addl	#0x10,%%a0\n\t"
+		"cmpl	%1,%%a0\n\t"
+		"blt	2b\n\t"
+		"addql	#1,%%d0\n\t"
+		"cmpil	#4,%%d0\n\t"
+		"bne	1b"
+		: : "a" (sset), "a" (eset) : "d0", "a0" );
+}
+
+#else
+#define	cache_invalidate_lines(a,b)
+#endif
+
+
+/*
+ * cache_push() semantics: Write back any dirty cache data in the given area,
+ * and invalidate the range in the instruction cache. It needs not (but may)
+ * invalidate those entries also in the data cache. The range is defined by a
+ * _physical_ address.
+ */
+
+void cache_push (unsigned long paddr, int len)
+{
+	cache_invalidate_lines(paddr, len);
+}
+
+
+/*
+ * cache_push_v() semantics: Write back any dirty cache data in the given
+ * area, and invalidate those entries at least in the instruction cache. This
+ * is intended to be used after data has been written that can be executed as
+ * code later. The range is defined by a _user_mode_ _virtual_ address  (or,
+ * more exactly, the space is defined by the %sfc/%dfc register.)
+ */
+
+void cache_push_v (unsigned long vaddr, int len)
+{
+	cache_invalidate_lines(vaddr, len);
+}
+
+/* Map some physical address range into the kernel address space. The
+ * code is copied and adapted from map_chunk().
+ */
+
+unsigned long kernel_map(unsigned long paddr, unsigned long size,
+			 int nocacheflag, unsigned long *memavailp )
+{
+	return paddr;
+}
+
+
+int is_in_rom(unsigned long addr)
+{
+
+#ifdef CONFIG_COLDFIRE
+	{
+		extern unsigned long    _ramstart, _ramend;
+
+		/* Anything not in operational RAM is returned as in rom! */
+		if (addr < _ramstart || addr >= _ramend)
+			return(1);
+	}
+#endif
+
+#if defined(CONFIG_PILOT) || defined(CONFIG_UCSIMM)
+	if (addr >= 0x10c00000)
+		return 1;
+#endif
+
+#ifdef CONFIG_M68EZ328ADS
+	if ( 0x00200000 <= addr && addr < 0x00400000)
+		return 1;
+#endif
+
+#ifdef CONFIG_M68332
+	extern char _etext;
+	
+ #ifdef SHGLCORE_ROM_BANK_0_ADDR
+	if ((addr >= SHGLCORE_ROM_BANK_0_ADDR) &&
+			(addr < (SHGLCORE_ROM_BANK_0_ADDR+SHGLCORE_ROM_BANK_0_LENGTH)))
+		return 1;
+ #endif
+ #ifdef SHGLCORE_ROM_BANK_1_ADDR
+	else if ((addr >= SHGLCORE_ROM_BANK_1_ADDR) &&
+			(addr < (SHGLCORE_ROM_BANK_1_ADDR+SHGLCORE_ROM_BANK_1_LENGTH)))
+		return 1;
+ #endif
+ #ifdef SHGLCORE_FLASH_BANK_0_ADDR
+	else if ((addr >= SHGLCORE_FLASH_BANK_0_ADDR) &&
+			(addr < (SHGLCORE_FLASH_BANK_0_ADDR+SHGLCORE_FLASH_BANK_0_LENGTH)))
+		return 1;
+ #endif
+ #ifdef SHGLCORE_FLASH_BANK_1_ADDR
+	else if ((addr >= SHGLCORE_FLASH_BANK_1_ADDR) &&
+			(addr < (SHGLCORE_FLASH_BANK_1_ADDR+SHGLCORE_FLASH_BANK_1_LENGTH)))
+		return 1;
+ #endif
+#endif
+
+	return(0); /* default case, not in ROM */
+}
+
+#endif /* NO_MM */
diff -urN linux-2.4.29/arch/m68knommu/platform/5206/ARNEWSH/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5206/ARNEWSH/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5206/ARNEWSH/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5206/ARNEWSH/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,254 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5206 ColdFire Arnewsh board.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Arnewsh m5206 ColdFire eval board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*
+ *	The following define the limits within which to search for
+ *	available RAM.
+ */
+#define	MEM_MIN		0x00100000	/* Search from 1Mb */
+#define	MEM_MAX		0x02000000	/* Max DRAM 32Mb! */
+#define	MEM_LUMP	0x00010000	/* 64 Kb chunks */
+
+#define MEM_TMPSTACK	0x00010000	/* At 64k - for exceptions */
+
+/*
+ *	Chip Select setup.
+ */
+#define	CS0_ADDR	0x0000f000	/* CS0 connected to Flash ROM */
+#define	CS0_MASK	0xf0000000	/*   is 1Mbyte */
+#define	CS0_CTRL	0x00000000	/*   read-only */
+#define	CS1_ADDR	0x00000000	/* CS1 not connected */
+#define	CS1_MASK	0x00000000
+#define	CS1_CTRL	0x00000000
+#define	CS2_ADDR	0x00003000	/* CS2 connected to SRAM */
+#define	CS2_MASK	0x0000f000	/*   is 1Mbyte */
+#define	CS2_CTRL	0x00001903	/*   read-write */
+#define	CS3_ADDR	0x00004000	/* CS3 connected to LED, par port */
+#define	CS3_MASK	0x0000f000	/*   is 1Mbyte */
+#define	CS3_CTRL	0x00000083	/*   read-write */
+#define	CS4_ADDR	0x00000000	/* CS4 not connected */
+#define	CS4_MASK	0x00000000
+#define	CS4_CTRL	0x00000123
+#define	CS5_ADDR	0x00000000	/* CS5 not connected */
+#define	CS5_MASK	0x00000000
+#define	CS5_CTRL	0x00000000
+#define	CS6_ADDR	0x00000000	/* CS6 not connected */
+#define	CS6_MASK	0x00000000
+#define	CS6_CTRL	0x00000000
+#define	CS7_ADDR	0x00000000	/* CS7 not connected */
+#define	CS7_MASK	0x00000000
+#define	CS7_CTRL	0x00000000
+#define	DMC_CTRL	0x00000000	/* default memory control */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 *
+	 *	On the Arnewsh 5206 board we can probe for the amount
+	 *	of DRAM present...
+	 */
+	move.l	#MEM_MIN, %a0			/* Start at bottom */
+	move.l	#MEM_MAX, %a1			/* Set stop point */
+	lea.l	MEM_TMPSTACK, %sp		/* Set up tmp stack ptr */
+
+	move.l	#VBR_BASE+8, %a2		/* Address of bus trap */
+	lea.l	_ram_buserr, %a3		/* Get RAM trap address */
+	move.l	%a3, (%a2)			/* Set trap to local ptr */
+
+_find_ram:
+	move.l	(%a0), %d0			/* Attempt read */
+	add.l	#MEM_LUMP, %a0			/* Try next bank */
+	cmp.l	%a1, %a0			/* Check more? */
+	bne	_find_ram
+
+	/*
+	 *	BUS error trap handler - used for RAM probing.
+	 */
+_ram_buserr:
+	bra	_found_ram
+
+_found_ram:					/* Vectored here on bus err */
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5206/ARNEWSH/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5206/ARNEWSH/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5206/ARNEWSH/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5206/ARNEWSH/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,65 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x10000, LENGTH = 0xf0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+			*(.rodata.str1.1)
+		. = ALIGN(0x4) ;
+			*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+			*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+			*(.text.init)
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		. = ALIGN(4) ;
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5206/config.c linux-2.4.29-uc1/arch/m68knommu/platform/5206/config.c
--- linux-2.4.29/arch/m68knommu/platform/5206/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5206/config.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,257 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/5206/config.c
+ *
+ *	Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ * 	Copyright (C) 2000-2001, Lineo Inc. (www.lineo.com) 
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcftimer.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int   dma_base_addr[MAX_DMA_CHANNELS] = {
+        MCF_MBAR + MCFDMA_BASE0,
+        MCF_MBAR + MCFDMA_BASE1,
+};
+
+unsigned int dma_device_address[MAX_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned char	*icrp;
+
+	/* Set up TIMER 1 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_CLK / 16) / HZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_TIMER1ICR);
+
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI3;
+	request_irq(29, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_TIMER1);
+}
+
+/***************************************************************************/
+
+unsigned long coldfire_timer_offset(void)
+{
+	volatile unsigned short *timerp;
+	unsigned long		trr, tcn, offset;
+
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE1);
+	tcn = timerp[MCFTIMER_TCN];
+	trr = timerp[MCFTIMER_TRR];
+
+	/*
+	 * If we are still in the first half of the upcount and a
+	 * timer interupt is pending, then add on a ticks worth of time.
+	 */
+	offset = ((tcn * (1000000 / HZ)) / trr);
+	if (((offset * 2) < (1000000 / HZ)) && (mcf_getipr() & MCFSIM_IMR_TIMER1))
+		offset += 1000000 / HZ;
+	return offset;	
+}
+
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	volatile unsigned char  *mbar;
+	unsigned char		icr;
+
+	if ((vec >= 25) && (vec <= 31)) {
+		vec -= 25;
+		mbar = (volatile unsigned char *) MCF_MBAR;
+		icr = MCFSIM_ICR_AUTOVEC | (vec << 3);
+		*(mbar + MCFSIM_ICR1 + vec) = icr;
+		vec = 0x1 << (vec + 1);
+		mcf_setimr(mcf_getimr() & ~vec);
+	}
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void coldfire_trap_init(void)
+{
+	int i;
+
+#ifndef ENABLE_dBUG
+	mcf_setimr(MCFSIM_IMR_MASKALL);
+#endif
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+	for (i = 33; (i <= 63); i++)
+		_ramvec[i] = trap;
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+}
+/***************************************************************************/
+
+void coldfire_reset(void)
+{
+	HARD_RESET_NOW();
+}
+
+/***************************************************************************/
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+
+void dump(struct pt_regs *fp)
+{
+	extern unsigned int sw_usp, sw_ksp;
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk("\nCURRENT PROCESS:\n\n");
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
+			(int) current->mm->start_stack,
+			(int) (((unsigned long) current) + 2 * PAGE_SIZE));
+	}
+
+	printk("PC: %08lx\n", fp->pc);
+	printk("SR: %08lx    SP: %08lx\n", (long) fp->sr, (long) fp);
+	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+		fp->d0, fp->d1, fp->d2, fp->d3);
+	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+		fp->d4, fp->d5, fp->a0, fp->a1);
+	printk("\nUSP: %08x   KSP: %08x   TRAPFRAME: %08x\n",
+		sw_usp, sw_ksp, (unsigned int) fp);
+
+	printk("\nCODE:");
+	tp = ((unsigned char *) fp->pc) - 0x20;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+#if 1
+	printk("\nUSER STACK:");
+	tp = (unsigned char *) sw_usp;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n\n");
+#endif
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+#ifdef CONFIG_BOOTPARAM
+	strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+	commandp[size-1] = 0;
+#else
+	memset(commandp, 0, size);
+#endif
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+	mach_reset = coldfire_reset;
+	mach_gettimeoffset = coldfire_timer_offset;
+}
+
+/***************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5206/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/5206/Makefile
--- linux-2.4.29/arch/m68knommu/platform/5206/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5206/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,50 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+#
+# re-use any 5307/coldfire files that we can.  Perhaps we should create
+# a coldfire directory for shared files ?
+#
+
+VPATH := $(VPATH):../5307
+
+ifdef CONFIG_FULLDEBUG
+	AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+#
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# AFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o ints.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
+
+entry.o: entry.S m68k_defs.h
+
+m68k_defs.h: ../../kernel/m68k_defs.c ../../kernel/m68k_defs.head
+	rm -f m68k_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/m68k_defs.c
+	cp ../../kernel/m68k_defs.head m68k_defs.h
+	grep '^#define' m68k_defs.s >> m68k_defs.h
+	rm m68k_defs.s
+-include m68k_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/platform/5206/Rules.make linux-2.4.29-uc1/arch/m68knommu/platform/5206/Rules.make
--- linux-2.4.29/arch/m68knommu/platform/5206/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5206/Rules.make	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,40 @@
+#
+# 5407/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1999,2001  Greg Ungerer (gerg@snapgear.com)
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uClinux.org>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+# Copyright (C) 2000  Lineo Inc. (www.lineo.com)
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/m5200/libgcc.a
+
+CFLAGS := -fno-builtin -nostdinc $(CFLAGS) -I$(INCGCC) -pipe -DNO_MM -DNO_FPU -m5200 -Wa,-S -Wa,-m5200 -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME=\"uClinux\" -D__linux__
+AFLAGS := $(CFLAGS)
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+            arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f arch/$(ARCH)/platform/$(PLATFORM)/m68k_defs.h
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5206e/config.c linux-2.4.29-uc1/arch/m68knommu/platform/5206e/config.c
--- linux-2.4.29/arch/m68knommu/platform/5206e/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5206e/config.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,347 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/5206e/config.c
+ *
+ *	Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/ledman.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcftimer.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+#include <asm/mcfwdebug.h>
+
+#ifdef CONFIG_NETtel
+#include <asm/irq.h>
+#include <asm/delay.h>
+#endif
+
+/***************************************************************************/
+
+#ifdef CONFIG_NETtel
+void	reset_setupbutton(void);
+#endif
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int   dma_base_addr[MAX_DMA_CHANNELS] = {
+        MCF_MBAR + MCFDMA_BASE0,
+        MCF_MBAR + MCFDMA_BASE1,
+};
+
+unsigned int dma_device_address[MAX_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned char	*icrp;
+
+	/* Set up TIMER 1 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_CLK / 16) / HZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_TIMER1ICR);
+
+#ifdef CONFIG_NETtel
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3;
+	request_irq(30, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+	reset_setupbutton();
+#else
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI3;
+	request_irq(29, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+#endif
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_TIMER1);
+}
+
+/***************************************************************************/
+
+unsigned long coldfire_timer_offset(void)
+{
+	volatile unsigned short *timerp;
+	unsigned long		trr, tcn, offset;
+
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE1);
+	tcn = timerp[MCFTIMER_TCN];
+	trr = timerp[MCFTIMER_TRR];
+
+	/*
+	 * If we are still in the first half of the upcount and a
+	 * timer interupt is pending, then add on a ticks worth of time.
+	 */
+	offset = ((tcn * (1000000 / HZ)) / trr);
+	if (((offset * 2) < (1000000 / HZ)) && (mcf_getipr() & MCFSIM_IMR_TIMER1))
+		offset += 1000000 / HZ;
+	return offset;	
+}
+
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	volatile unsigned char  *mbar;
+	unsigned char		icr;
+
+	if ((vec >= 25) && (vec <= 31)) {
+		vec -= 25;
+		mbar = (volatile unsigned char *) MCF_MBAR;
+		icr = MCFSIM_ICR_AUTOVEC | (vec << 3);
+		*(mbar + MCFSIM_ICR1 + vec) = icr;
+		vec = 0x1 << (vec + 1);
+		mcf_setimr(mcf_getimr() & ~vec);
+	}
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void coldfire_trap_init(void)
+{
+	int i;
+#ifdef MCF_MEMORY_PROTECT
+	extern unsigned long _end;
+	extern unsigned long memory_end;
+#endif
+
+#ifndef ENABLE_dBUG
+	mcf_setimr(MCFSIM_IMR_MASKALL);
+#endif
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+	for (i = 33; (i <= 63); i++)
+		_ramvec[i] = trap;
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+}
+
+/***************************************************************************/
+
+void coldfire_reset(void)
+{
+	HARD_RESET_NOW();
+}
+
+/***************************************************************************/
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+
+void dump(struct pt_regs *fp)
+{
+	extern unsigned int sw_usp, sw_ksp;
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk("\nCURRENT PROCESS:\n\n");
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
+			(int) current->mm->start_stack,
+			(int) (((unsigned long) current) + 2 * PAGE_SIZE));
+	}
+
+	printk("PC: %08lx\n", fp->pc);
+	printk("SR: %08lx    SP: %08lx\n", (long) fp->sr, (long) fp);
+	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+		fp->d0, fp->d1, fp->d2, fp->d3);
+	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+		fp->d4, fp->d5, fp->a0, fp->a1);
+	printk("\nUSP: %08x   KSP: %08x   TRAPFRAME: %08x\n",
+		sw_usp, sw_ksp, (unsigned int) fp);
+
+	printk("\nCODE:");
+	tp = ((unsigned char *) fp->pc) - 0x20;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+#if 1
+	printk("\nUSER STACK:");
+	tp = (unsigned char *) sw_usp;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n\n");
+#endif
+}
+
+/***************************************************************************/
+
+#ifdef CONFIG_NETtel
+
+/*
+ *	Routines to support the NETtel software reset button.
+ */
+void reset_button(int irq, void *dev_id, struct pt_regs *regs)
+{
+	static int	inbutton = 0;
+
+	/*
+	 *	IRQ7 is not maskable by the CPU core. It is possible
+	 *	that switch bounce may get us back here before we have
+	 *	really serviced the interrupt.
+	 */
+	if (inbutton)
+		return;
+	inbutton = 1;
+
+	/* Disable interrupt at SIM - best we can do... */
+	mcf_setimr(mcf_getimr() | MCFSIM_IMR_EINT7);
+
+#ifdef CONFIG_LEDMAN
+	ledman_signalreset();
+#endif
+
+	/* Don't leave here 'till button is no longer pushed! */
+	for (;;) {
+		if ((mcf_getipr() & MCFSIM_IMR_EINT7) == 0)
+			break;
+	}
+
+#ifndef CONFIG_LEDMAN
+	HARD_RESET_NOW();
+	/* Should never get here... */
+#endif
+
+	inbutton = 0;
+	/* Interrupt service done, enable it again */
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT7);
+}
+
+/***************************************************************************/
+
+void reset_setupbutton(void)
+{
+	mcf_autovector(31);
+	request_irq(31, reset_button, (SA_INTERRUPT | IRQ_FLG_FAST),
+		"Reset Button", NULL);
+}
+
+#endif /* CONFIG_NETtel */
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+#ifdef CONFIG_BOOTPARAM
+	strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+	commandp[size-1] = 0;
+#elif defined(CONFIG_NETtel)
+	/* Copy command line from FLASH to local buffer... */
+	memcpy(commandp, (char *) 0xf0004000, size);
+	commandp[size-1] = 0;
+#else
+	memset(commandp, 0, size);
+#endif
+
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+	mach_reset = coldfire_reset;
+	mach_gettimeoffset = coldfire_timer_offset;
+
+#ifdef CONFIG_BDM_DISABLE
+        /*
+         * Disable the BDM clocking.  This also turns off most of the rest of
+         * the BDM device.  This is good for EMC reasons. This option is not
+         * incompatible with the memory protection option.
+         */
+        wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
+#endif
+}
+
+/***************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5206e/eLITE/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5206e/eLITE/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5206e/eLITE/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5206e/eLITE/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,387 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5206e ColdFire based eLITE boards.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ *	Copyright (C) 1999 Rob Scott (rscott@mtrob.fdns.net)
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	M5206eLITE ColdFire eval board, chip select and memory setup.
+ */
+
+#ifdef CONFIG_SMALL
+#define	MEM_BASE	0x30000000      /* Base memory for M5206eLITE */
+#define	MEM_RESERVED	0x00020000      /* Don't use memory reserved by dBUG */
+#define	MEM_SIZE	0x00100000      /* 1 MB of SRAM on M5206eLITE */
+#else
+#define	MEM_BASE	0x00000000      /* Base memory for M5206eLITE */
+#define	MEM_RESERVED	0x00010000      /* Skip first MEM_LUMP for colilo */
+#define	MEM_SIZE	0x02000000      /* Max DRAM 32Mb */
+#endif
+#define	MEM_MIN		MEM_BASE+MEM_RESERVED
+/* Define end of probeable memory space */
+#define	MEM_MAX		MEM_BASE+MEM_SIZE
+#define	MEM_BUILTIN	0x20000000      /* Put built in SRAM at dBUG loc */
+#define	MEM_TMPSTACK	MEM_BUILTIN+0x800 /* Use built in SRAM for tmp stack */
+#define	MEM_LUMP	0x00010000	/* 64 Kb chunks */
+#define	VBR_BASE	MEM_BUILTIN     /* Use built in SRAM for vectors */
+
+#define	CS0_ADDR	0x0000ffe0	/* CS0 connected to Flash ROM */
+#define	CS0_MASK	0x000f0000	/*   is 1Mbyte */
+#define	CS0_CTRL	0x00001da3	/*   read-write (for flash) */
+#define	CS1_ADDR	0x00000000	/* CS1 not connected */
+#define	CS1_MASK	0x00000000
+#define	CS1_CTRL	0x00000000
+#define	CS2_ADDR	0x00003000	/* CS2 connected to SRAM */
+#define	CS2_MASK	0x000f0000	/*   is 1Mbyte */
+#define	CS2_CTRL	0x00001903	/*   read-write */
+#define	CS3_ADDR	0x00004000	/* CS3 connected to LED, par port */
+#define	CS3_MASK	0x000f0000	/*   is 1Mbyte */
+#define	CS3_CTRL	0x00000183	/*   read-write */
+#define	CS4_ADDR	0x00000000	/* CS4 not connected */
+#define	CS4_MASK	0x00000000
+#define	CS4_CTRL	0x00000000
+#define	CS5_ADDR	0x00000000	/* CS5 not connected */
+#define	CS5_MASK	0x00000000
+#define	CS5_CTRL	0x00000000
+#define	CS6_ADDR	0x00000000	/* CS6 not connected */
+#define	CS6_MASK	0x00000000
+#define	CS6_CTRL	0x00000000
+#define	CS7_ADDR	0x00000000	/* CS7 not connected */
+#define	CS7_MASK	0x00000000
+#define	CS7_CTRL	0x00000000
+#define	DMC_CTRL	0x00000000	/* default memory control */
+
+#define	DCRR		0x00000034	/* Refresh period  */
+/* DCTR definition:
+     <15>: DAEM, 1 = Drive Multiplexed Address During External Master DRAM xfer
+     <14>: EDO,  1 = EDO, 0 = Normal
+     <12>: RCD,  1 = 2 clk RAS-to-CAS, 0 = 1.0 clk RAS-to-CAS
+  <10:09>: RSH,  10 = 3.5 clk RAS low, 01 = 2.5 clk, 00 = 1.5 clk
+  <06:05>: RP,   10 = 3.5 clk RAS Precharge, 01 = 2.5 clk, 00 = 1.5 clk
+     <03>: CAS,  1 = 2.5 clk CAS assertion, 0 = 1.5 clk
+     <01>: CP,   1 = 1.5 CAS clk precharge, 0 = .5 clk
+     <00>: CSR,  1 = 2.0 clk CAS before RAS setup, 0 = 1.0 clk
+*/
+#define	DCTR		0x0000144B	/* Slow DRAM */
+#define	DCAR0		0x00000000	/* DRAM0 address, 0 base addr */
+#define	DCMR0		0x003e0000	/* DRAM0 mask, 4Mb DRAM */
+#define	DCCR0		0x00000007	/* DRAM0 control, R/W, burst pg mde */
+#define	DCAR1		0x00000000	/* DRAM1 address, 0 base addr */
+#define	DCMR1		0x00000000	/* DRAM1 mask, no DRAM */
+#define	DCCR1		0x00000000	/* DRAM1 control, off */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	move.l	#MCF_MBAR+1, %a0		/* Set I/O base addr */
+	movec	%a0, %MBAR			/* Note: bit 0 is Validate */
+	move.l	#MEM_BUILTIN+1,%a0		/* Set SRAM base addr */
+	movec	%a0, %RAMBAR0			/* Note: bit 0 is Validate */
+
+	move.l	#MCF_MBAR, %a0			/* Get I/O base addr */
+
+	/* ----------------------- CS1 ----------------------- */
+	move.w	#CS1_ADDR, %d0			/* CS1 address */
+	move.w	%d0, MCFSIM_CSAR1(%a0)		/* CS1 address */
+	move.l	#CS1_MASK, %d0			/* CS1 mask */
+	move.l	%d0, MCFSIM_CSMR1(%a0)		/* CS1 mask */
+	move.w	#CS1_CTRL, %d0			/* CS1 control */
+	move.w	%d0, MCFSIM_CSCR1(%a0)		/* CS1 control */
+
+	/* ----------------------- CS2 ----------------------- */
+	move.w	#CS2_ADDR, %d0			/* CS2 address */
+	move.w	%d0, MCFSIM_CSAR2(%a0)		/* CS2 address */
+	move.l	#CS2_MASK, %d0			/* CS2 mask */
+	move.l	%d0, MCFSIM_CSMR2(%a0)		/* CS2 mask */
+	move.w	#CS2_CTRL, %d0			/* CS2 control */
+	move.w	%d0, MCFSIM_CSCR2(%a0)		/* CS2 control */
+
+	/* ----------------------- CS3 ----------------------- */
+	move.w	#CS3_ADDR, %d0			/* CS3 address */
+	move.w	%d0, MCFSIM_CSAR3(%a0)		/* CS3 address */
+	move.l	#CS3_MASK, %d0			/* CS3 mask */
+	move.l	%d0, MCFSIM_CSMR3(%a0)		/* CS3 mask */
+	move.w	#CS3_CTRL, %d0			/* CS3 control */
+	move.w	%d0, MCFSIM_CSCR3(%a0)		/* CS3 control */
+
+	/* ----------------------- CS4 ----------------------- */
+	move.w	#CS4_ADDR, %d0			/* CS4 address */
+	move.w	%d0, MCFSIM_CSAR4(%a0)		/* CS4 address */
+	move.l	#CS4_MASK, %d0			/* CS4 mask */
+	move.l	%d0, MCFSIM_CSMR4(%a0)		/* CS4 mask */
+	move.w	#CS4_CTRL, %d0			/* CS4 control */
+	move.w	%d0, MCFSIM_CSCR4(%a0)		/* CS4 control */
+
+	/* ----------------------- CS5 ----------------------- */
+	move.w	#CS5_ADDR, %d0			/* CS5 address */
+	move.w	%d0, MCFSIM_CSAR5(%a0)		/* CS5 address */
+	move.l	#CS5_MASK, %d0			/* CS5 mask */
+	move.l	%d0, MCFSIM_CSMR5(%a0)		/* CS5 mask */
+	move.w	#CS5_CTRL, %d0			/* CS5 control */
+	move.w	%d0, MCFSIM_CSCR5(%a0)		/* CS5 control */
+
+	/* ----------------------- CS6 ----------------------- */
+	move.w	#CS6_ADDR, %d0			/* CS6 address */
+	move.w	%d0, MCFSIM_CSAR6(%a0)		/* CS6 address */
+	move.l	#CS6_MASK, %d0			/* CS6 mask */
+	move.l	%d0, MCFSIM_CSMR6(%a0)		/* CS6 mask */
+	move.w	#CS6_CTRL, %d0			/* CS6 control */
+	move.w	%d0, MCFSIM_CSCR6(%a0)		/* CS6 control */
+
+	/* ----------------------- CS7 ----------------------- */
+	move.w	#CS7_ADDR, %d0			/* CS7 address */
+	move.w	%d0, MCFSIM_CSAR7(%a0)		/* CS7 address */
+	move.l	#CS7_MASK, %d0			/* CS7 mask */
+	move.l	%d0, MCFSIM_CSMR7(%a0)		/* CS7 mask */
+	move.w	#CS7_CTRL, %d0			/* CS7 control */
+	move.w	%d0, MCFSIM_CSCR7(%a0)		/* CS7 control */
+
+	/* --------------------- Default --------------------- */
+	move.w	#DMC_CTRL, %d0			/* Default control */
+	move.w	%d0, MCFSIM_DMCR(%a0)		/* Default control */
+
+	/* ----------------------- DRAM ------------------------ */
+	move.w	#DCRR, %d0			/* Refresh period */
+	move.w	%d0, MCFSIM_DCRR(%a0)		/* Refresh period */
+	move.w	#DCTR, %d0			/* Timing address */
+	move.w	%d0, MCFSIM_DCTR(%a0)		/* Timing address */
+	move.w	#DCAR0, %d0			/* DRAM0 base address */
+	move.w	%d0, MCFSIM_DCAR0(%a0)		/* DRAM0 base address */
+	move.l	#DCMR0, %d0			/* DRAM0 mask */
+	move.l	%d0, MCFSIM_DCMR0(%a0)		/* DRAM0 mask */
+	move.b	#DCCR0, %d0			/* DRAM0 control */
+	move.b	%d0, MCFSIM_DCCR0(%a0)		/* DRAM0 control */
+	move.w	#DCAR1, %d0			/* DRAM1 base address */
+	move.w	%d0, MCFSIM_DCAR1(%a0)		/* DRAM1 base address */
+	move.l	#DCMR1, %d0			/* DRAM1 mask */
+	move.l	%d0, MCFSIM_DCMR1(%a0)		/* DRAM1 mask */
+	move.b	#DCCR1, %d0			/* DRAM1 control */
+	move.b	%d0, MCFSIM_DCCR1(%a0)		/* DRAM1 control */
+
+	/*
+	 * ChipSelect 0 - ROM cs
+	 *
+	 * ChipSelect 0 is the global chip select coming out of system reset.
+	 * CS0 is asserted for every access until CSMR0 is written.  Therefore,
+	 * the entire ChipSelect must be properly set prior to asserting
+	 * CSCR0_V.
+	 */
+	move.w	#CS0_ADDR, %d0			/* CS0 address */
+	move.w	%d0, MCFSIM_CSAR0(%a0)		/* CS0 address */
+	move.l	#CS0_MASK, %d0			/* CS0 mask */
+	move.l	%d0, MCFSIM_CSMR0(%a0)		/* CS0 mask */
+	move.w	#CS0_CTRL, %d0			/* CS0 control */
+	move.w	%d0, MCFSIM_CSCR0(%a0)		/* CS0 control */
+
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack
+	 *	Done differently for different eval boards and cpus.
+	 */
+
+#if defined(CONFIG_SMALL)
+	/*
+	 *	Set to SRAM size when configuring a minimal system
+	 */
+	move.l	#MEM_MAX, %a0
+
+#else
+	/*
+	 *	On the Arnewsh 5206 board and the Motorola m5206eLITE board
+	 *	we can probe for the amount of DRAM present...
+	 */
+	move.l	#MEM_MIN, %a0			/* Start at bottom */
+	move.l	#MEM_MAX, %a1			/* Set stop point */
+	lea.l	MEM_TMPSTACK, %sp		/* Set up tmp stack ptr */
+
+	move.l	#VBR_BASE+8, %a2		/* Address of bus trap */
+	lea.l	_ram_buserr, %a3		/* Get RAM trap address */
+	move.l	%a3, (%a2)			/* Set trap to local ptr */
+
+_find_ram:
+	move.l	(%a0), %d0			/* Attempt read */
+	add.l	#MEM_LUMP, %a0			/* Try next bank */
+	cmp.l	%a1, %a0			/* Check more? */
+	bne	_find_ram
+
+	/*
+	 *	BUS error trap handler - used for RAM probing.
+	 */
+_ram_buserr:
+	bra	_found_ram
+
+_found_ram:					/* Vectored here on bus err */
+#endif
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *      Load the current task pointer and stack.
+	 */
+	lea     init_task_union, %a0
+	movel   %a0, _current_task
+	lea     0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5206e/eLITE/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5206e/eLITE/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5206e/eLITE/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5206e/eLITE/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,65 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x30020000, LENGTH = 0xe0000
+}
+
+SECTIONS {
+
+	.text 0x30020000 : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+		*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4) ;
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5206e/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/5206e/Makefile
--- linux-2.4.29/arch/m68knommu/platform/5206e/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5206e/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,50 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+#
+# re-use any 5307/coldfire files that we can.  Perhaps we should create
+# a coldfire directory for shared files ?
+#
+
+VPATH := $(VPATH):../5307
+
+ifdef CONFIG_FULLDEBUG
+	AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+#
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# AFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o ints.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
+
+entry.o: entry.S m68k_defs.h
+
+m68k_defs.h: ../../kernel/m68k_defs.c ../../kernel/m68k_defs.head
+	rm -f m68k_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/m68k_defs.c
+	cp ../../kernel/m68k_defs.head m68k_defs.h
+	grep '^#define' m68k_defs.s >> m68k_defs.h
+	rm m68k_defs.s
+-include m68k_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/platform/5206e/MOTOROLA/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5206e/MOTOROLA/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5206e/MOTOROLA/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5206e/MOTOROLA/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,219 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5206e ColdFire based MOTOROLA boards.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	M5206eC3 ColdFire eval board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+  	/*
+	 *	SDRAM size for the Cadre III board (m5206e).
+  	 */
+#if defined(CONFIG_RAMAUTO)
+	movea.l	#0x00000000,%a0
+	move.l	MCF_MBAR+MCFSIM_DCMR0, %d0
+	and.l	#0x00fe0000, %d0
+	beq	noaddr1
+	add.l	#0x00020000, %d0
+	move.l	%d0, %a0
+noaddr1:
+	move.l	MCF_MBAR+MCFSIM_DCMR1, %d0
+	and.l	#0x00fe0000, %d0
+	beq	noaddr2
+	add.l	#0x00020000, %d0
+	add.l	%d0, %a0
+noaddr2:
+
+#else
+
+#if defined(CONFIG_RAM32MB)
+#define MEM_SIZE	0x02000000	/* Memory size 32Mb */
+#elif defined(CONFIG_RAM16MB)
+#define MEM_SIZE	0x01000000	/* Memory size 16Mb */
+#elif defined(CONFIG_RAM8MB)
+#define MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#else
+#define MEM_SIZE	0x00400000	/* Memory size 4Mb */
+#endif
+  	move.l	#MEM_SIZE, %a0
+#endif
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5206e/MOTOROLA/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5206e/MOTOROLA/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5206e/MOTOROLA/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5206e/MOTOROLA/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,65 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0x007E0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+			*(.rodata.str1.1)
+		. = ALIGN(0x4) ;
+			*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+			*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+			*(.text.init)
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		. = ALIGN(4) ;
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5206e/Rules.make linux-2.4.29-uc1/arch/m68knommu/platform/5206e/Rules.make
--- linux-2.4.29/arch/m68knommu/platform/5206e/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5206e/Rules.make	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,47 @@
+#
+# arch/m68knommu/platform/5206e/Rules.make
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1999,2001  Greg Ungerer (gerg@snapgear.com)
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uClinux.org>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+# Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+#
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/m5200/libgcc.a
+
+CFLAGS := -fno-builtin -nostdinc $(CFLAGS) -I$(INCGCC) -pipe -DNO_MM -DNO_FPU -m5200 -Wa,-S -Wa,-m5200 -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME='"uClinux"' -D__linux__
+AFLAGS := $(CFLAGS)
+
+ifdef CONFIG_MEMORY_PROTECT
+	CFLAGS += -DMCF_MEMORY_PROTECT
+endif
+ifdef CONFIG_SMALL
+	KSIZE = small_
+endif
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(KSIZE)$(MODEL).ld
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+            arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+archclean:
+	@$(MAKEBOOT) clean
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5235/config.c linux-2.4.29-uc1/arch/m68knommu/platform/5235/config.c
--- linux-2.4.29/arch/m68knommu/platform/5235/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5235/config.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,255 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/5235/config.c
+ *
+ *	Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
+ *	Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <linux/ledman.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcfpit.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+#include <asm/delay.h>
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int   dma_base_addr[MAX_DMA_CHANNELS] = {
+        MCF_MBAR + MCFDMA_BASE0,
+};
+
+unsigned int dma_device_address[MAX_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile struct mcfpit	*tp;
+
+	/* Reset the ColdFire timer */
+	tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
+	tp->pcsr |= MCFPIT_PCSR_PIF;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile unsigned char	*icrp;
+	volatile unsigned long	*imrp;
+	volatile struct mcfpit	*tp;
+
+	request_irq(64+36, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+	/* changed 55 to 36 to point to PIT0 vector */
+	icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
+		MCFINTC_ICR0 + MCFINT_PIT1);
+	*icrp = 0x2b; /* PIT1 with level 5, priority 3 */
+
+	imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
+	*imrp &= ~(1 << (36 - 32));
+
+	/* Set up PIT timer 1 as poll clock */
+	tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
+	tp->pcsr = MCFPIT_PCSR_DISABLE;
+
+	tp->pmr = ((MCF_CLK / 2) / 64) / HZ;
+	tp->pcsr = MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | MCFPIT_PCSR_OVW |
+		MCFPIT_PCSR_RLD | MCFPIT_PCSR_CLK64;
+}
+
+/***************************************************************************/
+
+unsigned long coldfire_timer_offset(void)
+{
+	volatile struct mcfpit *tp;
+	volatile unsigned long *ipr;
+	unsigned long pmr, pcntr, offset;
+
+	tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
+	ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IPRH);
+
+	pmr = tp->pmr;
+	pcntr = tp->pcntr;
+
+	/*
+	 * If we are still in the first half of the upcount and a
+	 * timer interupt is pending, then add on a ticks worth of time.
+	 */
+	offset = ((pmr - pcntr) * (1000000 / HZ)) / pmr;
+	if (((offset * 2) < (1000000 / HZ)) && (*ipr & (1 << (55 - 32))))
+		offset += 1000000 / HZ;
+	return offset;	
+}
+
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	/* Everything is auto-vectored on the 5282 */
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void coldfire_trap_init(void)
+{
+	int i;
+
+	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
+	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+	for (i = 33; (i <= 63); i++)
+		_ramvec[i] = trap;
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+}
+
+/***************************************************************************/
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+
+void dump(struct pt_regs *fp)
+{
+	extern unsigned int sw_usp, sw_ksp;
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk("\nCURRENT PROCESS:\n\n");
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
+			(int) current->mm->start_stack,
+			(int) ((unsigned long) current) + KTHREAD_SIZE);
+	}
+
+	printk("PC: %08lx\n", fp->pc);
+	printk("SR: %08lx    SP: %08lx\n", (long) fp->sr, (long) fp);
+	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+		fp->d0, fp->d1, fp->d2, fp->d3);
+	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+		fp->d4, fp->d5, fp->a0, fp->a1);
+	printk("\nUSP: %08x   KSP: %08x   TRAPFRAME: %08x\n",
+		sw_usp, sw_ksp, (unsigned int) fp);
+
+	printk("\nCODE:");
+	tp = ((unsigned char *) fp->pc) - 0x20;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+	printk("\n");
+
+	printk("\nUSER STACK:");
+	tp = (unsigned char *) (sw_usp - 0x10);
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n\n");
+}
+
+/***************************************************************************/
+
+void coldfire_reset(void)
+{
+	HARD_RESET_NOW();
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+#ifdef CONFIG_BOOTPARAM
+	strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+	commandp[size-1] = 0;
+#else
+	memset(commandp, 0, size);
+#endif
+
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+	mach_reset = coldfire_reset;
+	mach_gettimeoffset = coldfire_timer_offset;
+}
+
+/***************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5235/M5235EVB/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5235/M5235EVB/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5235/M5235EVB/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5235/M5235EVB/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,205 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5235 ColdFire based MOTOROLA boards.
+ *
+ *	(C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com).
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Motorola M5235EVB ColdFire eval board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#if defined(CONFIG_RAM4MB)
+#define	MEM_SIZE	0x00400000	/* Memory size 4Mb */
+#elif defined(CONFIG_RAM16MB)
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+#else
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+	/*
+	 *	Set memory size.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+#if 1
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01400000, %d0
+	movec	%d0, %CACR			/* Invalidate cache */
+	nop
+
+	move.l	#0x0000c000, %d0		/* Set SDRAM cached only */
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR1
+
+	move.l	#0x80400100, %d0		/* Configure cache */
+	movec	%d0, %CACR			/* Enable cache */
+	nop
+#endif
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+#if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+#else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+#endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5235/M5235EVB/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5235/M5235EVB/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5235/M5235EVB/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5235/M5235EVB/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,69 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0xfe0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+        	*(.rodata.str1.1)
+        	*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5235/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/5235/Makefile
--- linux-2.4.29/arch/m68knommu/platform/5235/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5235/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,50 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+#
+# re-use any 5307/coldfire files that we can.  Perhaps we should create
+# a coldfire directory for shared files ?
+#
+
+VPATH := $(VPATH):../5307
+
+ifdef CONFIG_FULLDEBUG
+	AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+#
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# AFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o ints.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
+
+entry.o: entry.S m68k_defs.h
+
+m68k_defs.h: ../../kernel/m68k_defs.c ../../kernel/m68k_defs.head
+	rm -f m68k_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/m68k_defs.c
+	cp ../../kernel/m68k_defs.head m68k_defs.h
+	grep '^#define' m68k_defs.s >> m68k_defs.h
+	rm m68k_defs.s
+-include m68k_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/platform/5235/Rules.make linux-2.4.29-uc1/arch/m68knommu/platform/5235/Rules.make
--- linux-2.4.29/arch/m68knommu/platform/5235/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5235/Rules.make	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,46 @@
+#
+# 5235/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1999-2003  Greg Ungerer (gerg@snapgear.com)
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uClinux.org>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+# Copyright (C) 2000  Lineo Inc. (www.lineo.com)
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+# Even though we're building for a 5282, we specify 5307 as our processor type.
+# The 5307 instruction set is the same as the 5282 (divide unit & MAC) plus
+# the 5282 instruction timings are closer to the 5307 than the other 5200
+# series processors (specifically the multiply and divide instructions which
+# are all this option really alters).
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/m5307/libgcc.a
+
+CFLAGS := -fno-builtin -nostdinc $(CFLAGS) -I$(INCGCC) -pipe -DNO_MM -DNO_FPU -m5307 -Wa,-S -Wa,-m5307 -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME=\"uClinux\" -D__linux__ -O1
+AFLAGS := $(CFLAGS)
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+            arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f arch/$(ARCH)/platform/$(PLATFORM)/m68k_defs.h
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5249/config.c linux-2.4.29-uc1/arch/m68knommu/platform/5249/config.c
--- linux-2.4.29/arch/m68knommu/platform/5249/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5249/config.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,330 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/5249/config.c
+ *
+ *	Copyright (C) 2002, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcftimer.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+#include <asm/delay.h>
+
+/***************************************************************************/
+
+void	coldfire_profile_init(void);
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int   dma_base_addr[MAX_DMA_CHANNELS] = {
+        MCF_MBAR + MCFDMA_BASE0,
+        MCF_MBAR + MCFDMA_BASE1,
+        MCF_MBAR + MCFDMA_BASE2,
+        MCF_MBAR + MCFDMA_BASE3,
+};
+
+unsigned int dma_device_address[MAX_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned char	*icrp;
+
+	/* Set up TIMER 1 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_BUSCLK / 16) / HZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_TIMER1ICR);
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI3;
+	request_irq(29, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+
+#ifdef CONFIG_HIGHPROFILE
+	coldfire_profile_init();
+#endif
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_TIMER1);
+}
+
+/***************************************************************************/
+
+unsigned long coldfire_timer_offset(void)
+{
+	volatile unsigned short *timerp;
+	unsigned long		trr, tcn, offset;
+
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE1);
+	tcn = timerp[MCFTIMER_TCN];
+	trr = timerp[MCFTIMER_TRR];
+
+	/*
+	 * If we are still in the first half of the upcount and a
+	 * timer interupt is pending, then add on a ticks worth of time.
+	 */
+	offset = ((tcn * (1000000 / HZ)) / trr);
+	if (((offset * 2) < (1000000 / HZ)) && (mcf_getipr() & MCFSIM_IMR_TIMER1))
+		offset += 1000000 / HZ;
+	return offset;	
+}
+
+/***************************************************************************/
+#ifdef CONFIG_HIGHPROFILE
+/***************************************************************************/
+
+#define	PROFILEHZ	1013
+
+/*
+ *	Use the other timer to provide high accuracy profiling info.
+ */
+
+void coldfire_profile_tick(int irq, void *dummy, struct pt_regs *regs)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer2 */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE2);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+
+        if (!user_mode(regs)) {
+                if (prof_buffer && current->pid) {
+                        extern int _stext;
+                        unsigned long ip = instruction_pointer(regs);
+                        ip -= (unsigned long) &_stext;
+                        ip >>= prof_shift;
+                        if (ip < prof_len)
+                                prof_buffer[ip]++;
+                }
+        }
+}
+
+void coldfire_profile_init(void)
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned char	*icrp;
+
+	printk("PROFILE: lodging timer2=%d as profile timer\n", PROFILEHZ);
+
+	/* Set up TIMER 2 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE2);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_BUSCLK / 16) / PROFILEHZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_TIMER2ICR);
+
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3;
+	request_irq(31, coldfire_profile_tick, (SA_INTERRUPT | IRQ_FLG_FAST),
+		"Profile Timer", NULL);
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_TIMER2);
+}
+
+/***************************************************************************/
+#endif	/* CONFIG_HIGHPROFILE */
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	volatile unsigned char  *mbar;
+
+	if ((vec >= 25) && (vec <= 31)) {
+		mbar = (volatile unsigned char *) MCF_MBAR;
+		vec = 0x1 << (vec - 24);
+		*(mbar + MCFSIM_AVR) |= vec;
+		mcf_setimr(mcf_getimr() & ~vec);
+	}
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void __init coldfire_trap_init(void)
+{
+	int i;
+
+#ifndef ENABLE_dBUG
+	mcf_setimr(MCFSIM_IMR_MASKALL);
+#endif
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+	for (i = 33; (i <= 63); i++)
+		_ramvec[i] = trap;
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+}
+
+/***************************************************************************/
+
+void coldfire_reset(void)
+{
+	HARD_RESET_NOW();
+}
+
+/***************************************************************************/
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+
+void dump(struct pt_regs *fp)
+{
+	extern unsigned int sw_usp, sw_ksp;
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk("\nCURRENT PROCESS:\n\n");
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
+			(int) current->mm->start_stack,
+			(int) (((unsigned long) current) + 2 * PAGE_SIZE));
+	}
+
+	printk("PC: %08lx\n", fp->pc);
+	printk("SR: %08lx    SP: %08lx\n", (long) fp->sr, (long) fp);
+	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+		fp->d0, fp->d1, fp->d2, fp->d3);
+	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+		fp->d4, fp->d5, fp->a0, fp->a1);
+	printk("\nUSP: %08x   KSP: %08x   TRAPFRAME: %08x\n",
+		sw_usp, sw_ksp, (unsigned int) fp);
+
+	printk("\nCODE:");
+	tp = ((unsigned char *) fp->pc) - 0x20;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nUSER STACK:");
+	tp = (unsigned char *) (sw_usp - 0x10);
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n\n");
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+#ifdef CONFIG_BOOTPARAM
+	strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+	commandp[size-1] = 0;
+#else
+	memset(commandp, 0, size);
+#endif
+
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+	mach_reset = coldfire_reset;
+	mach_gettimeoffset = coldfire_timer_offset;
+}
+
+/***************************************************************************/
+#ifdef TRAP_DBG_INTERRUPT
+
+asmlinkage void dbginterrupt_c(struct frame *fp)
+{
+	extern void dump(struct pt_regs *fp);
+	printk("%s(%d): BUS ERROR TRAP\n", __FILE__, __LINE__);
+        dump((struct pt_regs *) fp);
+	asm("halt");
+}
+
+#endif
+/***************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5249/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/5249/Makefile
--- linux-2.4.29/arch/m68knommu/platform/5249/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5249/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,50 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+#
+# re-use any 5307/coldfire files that we can.  Perhaps we should create
+# a coldfire directory for shared files ?
+#
+
+VPATH := $(VPATH):../5307
+
+ifdef CONFIG_FULLDEBUG
+	AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+#
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# AFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o ints.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
+
+entry.o: entry.S m68k_defs.h
+
+m68k_defs.h: ../../kernel/m68k_defs.c ../../kernel/m68k_defs.head
+	rm -f m68k_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/m68k_defs.c
+	cp ../../kernel/m68k_defs.head m68k_defs.h
+	grep '^#define' m68k_defs.s >> m68k_defs.h
+	rm m68k_defs.s
+-include m68k_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/platform/5249/MOTOROLA/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5249/MOTOROLA/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5249/MOTOROLA/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5249/MOTOROLA/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,278 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for Motorola M5249C3 eval board.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Motorola M5249C3 ColdFire eval board, chip select and memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	MEM_SIZE	0x00800000	/* Memory size 8MB */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 *	Set RAMBAR0 and RAMBAR1, just incase they are not set.
+	 */
+	move.l	#0x20000001, %a1
+	movec	%a1, #0XC05			/* Map RAMBAR1 region */
+	move.l	#0x20010001, %a0
+	movec	%a0, %RAMBAR0			/* Map RAMBAR region */
+
+	/*
+	 *	Set MBAR1 and MBAR2, just incase they are not set.
+	 */
+	move.l  #0x10000001, %a0
+	movec   %a0, %MBAR			/* Map MBAR region */
+	subq.l  #1, %a0				/* Get MBAR address in a0 */
+
+	move.l  #0x80000001, %a1
+	movec   %a1, #0xc0e			/* Map MBAR2 region */
+	subq.l  #1, %a1				/* Get MBAR2 address in a1 */
+
+	/*
+	 *      Move secondary interrupts to base at 128.
+	 */
+	move.b  #0x80, %d0
+	move.b  %d0, 0x16b(%a1)			/* Interrupt base register */
+
+#if 1
+	/*
+	 *      Work around broken CSMR0/DRAM vector problem.
+	 */
+	move.l  #0x001F0021, %d0		/* Disable C/I bit */
+	move.l  %d0, 0x84(%a0)			/* Set CSMR0 */
+#endif
+
+	/*
+	 *	Disable the PLL firstly. (Who knows what state it is
+	 *	in here!).
+	 */
+	move.l  0x180(%a1), %d0			/* Get current PLL value */
+	and.l   #0xfffffffe, %d0		/* PLL bypass first */
+	move.l  %d0, 0x180(%a1)			/* Set PLL register */
+	nop
+
+#if CONFIG_CLOCK_140MHz
+	/*
+	 *	Set initial clock frequency. This assumes M5249C3 board
+	 *	is fitted with 11.2896MHz crystal. It will program the
+	 *	PLL for 140MHz. Lets go fast :-)
+	 */
+	move.l  #0x125a40f0, %d0		/* Set for 140MHz */
+	move.l  %d0, 0x180(%a1)			/* Set PLL register */
+	or.l    #0x1, %d0
+	move.l  %d0, 0x180(%a1)			/* Set PLL register */
+#endif
+
+	/*
+	 *	Setup CS1 for ethernet controller.
+	 *	(Setup as per M5249C3 doco).
+	 */
+	move.l  #0xe0000000, %d0		/* CS1 mapped at 0xe0000000 */
+	move.l  %d0, 0x8c(%a0)
+	move.l  #0x001f0021, %d0		/* CS1 size of 1Mb */
+	move.l  %d0, 0x90(%a0)
+	move.w  #0x0080, %d0			/* CS1 = 16bit port, AA */
+	move.w  %d0, 0x96(%a0)
+
+	/*
+	 *	Setup CS2 for IDE interface.
+	 */
+	move.l	#0x50000000, %d0		/* CS2 mapped at 0x50000000 */
+	move.l	%d0, 0x98(%a0)
+	move.l	#0x001f0001, %d0		/* CS2 size of 1MB */
+	move.l	%d0, 0x9c(%a0)
+	move.w	#0x0080, %d0			/* CS2 = 16bit, TA */
+	move.w	%d0, 0xa2(%a0)
+
+	move.l	#0x00107020, %d0		/* IDEconfig1 */
+	move.l	%d0, 0x18c(%a1)
+	move.l	#0x000c0400, %d0		/* IDEconfig2 */
+	move.l	%d0, 0x190(%a1)
+
+	move.l	#0x00080000, %d0		/* GPIO19, IDE reset bit */
+	or.l	%d0, 0xc(%a1)			/* Function GPIO19 */
+	or.l	%d0, 0x8(%a1)			/* Enable GPIO19 as output */
+        or.l	%d0, 0x4(%a1)			/* De-assert IDE reset */
+
+	/*
+	 *	Setup VBR as per eval board (really dBUG does this).
+	 *	These settings must match it.
+	 */
+	move.l	#VBR_BASE, %a0			/* Note VBR can't be read */
+	movec   %a0, %VBR
+	move.l	%a0, _ramvec			/* Set up vector addr */
+	move.l	%a0, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Set the memory size, and then set a temporary stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l  #0x01000000, %d0		/* Invalidate whole cache */
+	movec   %d0, %CACR
+	nop
+
+	move.l  #0x0000c000, %d0		/* Set SDRAM cached only */
+	movec   %d0, %ACR0
+	move.l  #0x00000000, %d0		/* No other regions cached */
+	movec   %d0, %ACR1
+
+	move.l  #0xa0000200, %d0		/* Enable cache... */
+	movec   %d0, %CACR
+	nop
+
+#ifdef CONFIG_ROMFS_FS
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5249/MOTOROLA/crt0_rom.S linux-2.4.29-uc1/arch/m68knommu/platform/5249/MOTOROLA/crt0_rom.S
--- linux-2.4.29/arch/m68knommu/platform/5249/MOTOROLA/crt0_rom.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5249/MOTOROLA/crt0_rom.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,334 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_rom.S -- startup code for Motorola M5249C3 eval board.
+ *
+ *	(C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com).
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Motorola M5249C3 ColdFire eval board, chip select and memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	MEM_SIZE	0x00800000	/* Memory size 8MB */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Size of RAM is determined then an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+_vectors:
+
+.long	0x00000000, _start
+.long	_fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+.long	_fault, _fault, _fault, _fault, _fault, _fault, _fault, _fault
+
+/*****************************************************************************/
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 *	Set RAMBAR0 and RAMBAR1, just incase they are not set.
+	 */
+	move.l	#0x20000001, %a1
+	movec	%a1, #0XC05			/* Map RAMBAR1 region */
+	move.l	#0x20010001, %a0
+	movec	%a0, %RAMBAR0			/* Map RAMBAR region */
+
+	/*
+	 *	Set MBAR1 and MBAR2, just incase they are not set.
+	 */
+	move.l  #0x10000001, %a0
+	movec   %a0, %MBAR			/* Map MBAR region */
+	subq.l  #1, %a0				/* Get MBAR address in a0 */
+
+	move.l  #0x80000001, %a1
+	movec   %a1, #0xc0e			/* Map MBAR2 region */
+	subq.l  #1, %a1				/* Get MBAR2 address in a1 */
+
+
+	/*
+	 *	Flash chip select setup.
+	 */
+	move.l	#0xfff00000, %d0	/* Flash on CS0 */
+	move.l	%d0, MCFSIM_CSAR0(%a0)
+	move.l	#0x001f0021, %d0
+	move.l	%d0, MCFSIM_CSMR0(%a0)
+	move.w	#0x1180, %d0
+	move.w	%d0, MCFSIM_CSCR0(%a0)
+
+
+	/*
+	 *	SDRAM initialization. Magic sequence!
+	 */
+	/* STEP 1 */
+	move.w	#0x800a, %d0		/* Sync, 6 RTIM, 30h Refresh */
+	move.w	%d0, MCFSIM_DCR(%a0)	/* DCR setup */
+
+	/* STEP 2 */
+	move.l	#0x00002224, %d0
+	move.l	%d0, MCFSIM_DACR0(%a0)	/* DACR0 setup */
+
+	/* STEP 3 */
+	move.l	#0x007c0001, %d0
+	move.l	%d0, MCFSIM_DMR0(%a0)	/* DCMR0 setup */
+
+	/* STEP 4 */
+	move.l	#0x0000222c, %d0
+	move.l	%d0, MCFSIM_DACR0(%a0)	/* DACR0 setup PRECHARGE-ALL */
+
+	/* STEP 5 */
+	move.l	0x00000800, %d0		/* Read from SDRAM... */
+
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/* STEP 6 */
+	move.l	#0x0000a224, %d0
+	move.l	%d0, MCFSIM_DACR0(%a0)	/* DACR0 setup REFRESH ENABLE */
+
+	move.l	#0x20000800, %a2
+	move.l	#0x000fffff, %d0	/* Big delay */
+delay2:
+	move.l	%d0, (%a2)
+	sub.l	#1, %d0
+	bne	delay2
+
+
+	/* STEP 7 */
+	move.l	#0x0000a264, %d0
+	move.l	%d0, MCFSIM_DACR0(%a0)	/* DACR0 setup MODE CMD */
+
+	/* STEP 8 */
+	clr.l	%d0
+	move.l	%d0, 0x00000800		/* Write to set MODE */
+
+
+	/*
+	 *      Move secondary interrupts to base at 128.
+	 */
+	move.b  #0x80, %d0
+	move.b  %d0, 0x16b(%a1)			/* Interrupt base register */
+
+#if 1
+	/*
+	 *      Work around broken CSMR0/DRAM vector problem.
+	 */
+	move.l  #0x001F0021, %d0		/* Disable C/I bit */
+	move.l  %d0, 0x84(%a0)			/* Set CSMR0 */
+#endif
+
+	/*
+	 *	Disable the PLL firstly. (Who knows what state it is
+	 *	in here!).
+	 */
+	move.l  0x180(%a1), %d0			/* Get current PLL value */
+	and.l   #0xfffffffe, %d0		/* PLL bypass first */
+	move.l  %d0, 0x180(%a1)			/* Set PLL register */
+	nop
+
+#if CONFIG_CLOCK_140MHz
+	/*
+	 *	Set initial clock frequency. This assumes M5249C3 board
+	 *	is fitted with 11.2896MHz crystal. It will program the
+	 *	PLL for 140MHz. Lets go fast :-)
+	 */
+	move.l  #0x125a40f0, %d0		/* Set for 140MHz */
+	move.l  %d0, 0x180(%a1)			/* Set PLL register */
+	or.l    #0x1, %d0
+	move.l  %d0, 0x180(%a1)			/* Set PLL register */
+#endif
+
+	/*
+	 *	Setup CS1 for ethernet controller.
+	 *	(Setup as per M5249C3 doco).
+	 */
+	move.l  #0xe0000000, %d0		/* CS1 mapped at 0xe0000000 */
+	move.l  %d0, 0x8c(%a0)
+	move.l  #0x001f0021, %d0		/* CS1 size of 1Mb */
+	move.l  %d0, 0x90(%a0)
+	move.w  #0x0080, %d0			/* CS1 = 16bit port, AA */
+	move.w  %d0, 0x96(%a0)
+
+	/*
+	 *	Setup CS2 for IDE interface.
+	 */
+	move.l	#0x50000000, %d0		/* CS2 mapped at 0x50000000 */
+	move.l	%d0, 0x98(%a0)
+	move.l	#0x001f0001, %d0		/* CS2 size of 1MB */
+	move.l	%d0, 0x9c(%a0)
+	move.w	#0x0080, %d0			/* CS2 = 16bit, TA */
+	move.w	%d0, 0xa2(%a0)
+
+	move.l	#0x00107020, %d0		/* IDEconfig1 */
+	move.l	%d0, 0x18c(%a1)
+	move.l	#0x000c0400, %d0		/* IDEconfig2 */
+	move.l	%d0, 0x190(%a1)
+
+	move.l	#0x00080000, %d0		/* GPIO19, IDE reset bit */
+	or.l	%d0, 0xc(%a1)			/* Function GPIO19 */
+	or.l	%d0, 0x8(%a1)			/* Enable GPIO19 as output */
+        or.l	%d0, 0x4(%a1)			/* De-assert IDE reset */
+
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l  #0x01000000, %d0		/* Invalidate whole cache */
+	movec   %d0, %CACR
+	nop
+
+	move.l  #0x0000c000, %d0		/* Set SDRAM cached only */
+	movec   %d0, %ACR0
+	move.l  #0xfff0c000, %d0		/* No other regions cached */
+	movec   %d0, %ACR1
+
+	move.l  #0xa0000200, %d0		/* Enable cache... */
+	movec   %d0, %CACR
+	nop
+
+
+	/*
+	 *	Copy initialized data region to RAM.
+	 */
+	lea.l	_sdata, %a0			/* Get start of data */
+	lea.l	__init_end, %a1			/* Get end of data+init */
+	lea.l	_etext, %a2			/* Get end of text */
+_data_copy:
+	move.l	(%a2)+, %d0			/* Get next word */
+	move.l	%d0, (%a0)+			/* Copy to RAM */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_data_copy
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+
+	/*
+	 *	Setup VBR as per eval board.
+	 */
+	move.l	#VBR_BASE, %a0			/* Note VBR can't be read */
+	movec   %a0, %VBR
+	move.l	%a0, _ramvec			/* Set up vector addr */
+	move.l	%a0, _rambase			/* Set up base RAM addr */
+
+	lea.l	_end, %a0			/* Get end of kernel mem */
+	move.l	%a0, _ramstart
+
+	/*
+	 *	Set the memory size, and then set a temporary stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_fault:
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5249/MOTOROLA/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5249/MOTOROLA/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5249/MOTOROLA/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5249/MOTOROLA/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,65 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0x003E0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+		*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4) ;
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5249/MOTOROLA/rom.ld linux-2.4.29-uc1/arch/m68knommu/platform/5249/MOTOROLA/rom.ld
--- linux-2.4.29/arch/m68knommu/platform/5249/MOTOROLA/rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5249/MOTOROLA/rom.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,66 @@
+
+MEMORY {
+	flash  : ORIGIN = 0xfff00000, LENGTH = 0x00100000
+	ram    : ORIGIN = 0x00000400, LENGTH = 0x003FFC00
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > flash
+
+	.data : AT (ADDR(.text) + SIZEOF(.text)) {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+		*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : AT (ADDR(.text) + SIZEOF(.text) + SIZEOF(.data)) {
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4) ;
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss : AT (ADDR(.text) + SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.init)) {
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5249/Rules.make linux-2.4.29-uc1/arch/m68knommu/platform/5249/Rules.make
--- linux-2.4.29/arch/m68knommu/platform/5249/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5249/Rules.make	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,40 @@
+#
+# 5249/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1999-2002  Greg Ungerer (gerg@snapgear.com)
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uClinux.org>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+# Copyright (C) 2000  Lineo Inc. (www.lineo.com)
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/m5200/libgcc.a
+
+CFLAGS := -fno-builtin -nostdinc $(CFLAGS) -I$(INCGCC) -pipe -DNO_MM -DNO_FPU -m5200 -Wa,-S -Wa,-m5200 -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME=\"uClinux\" -D__linux__
+AFLAGS := $(CFLAGS)
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+            arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f arch/$(ARCH)/platform/$(PLATFORM)/m68k_defs.h
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/CANCam/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5272/CANCam/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5272/CANCam/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/CANCam/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,221 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for Feith CANCan board.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ * 	(C) Copyright 2000 Lineo Inc. (www.lineo.com) 
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	SNapGear NETtel board memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+#define MEM_SIZE  0x04000000      /* Memory size 64Mb */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Set size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+	nop
+
+
+#ifdef CONFIG_ROMFS_FROM_ROM
+	/*
+	 *	Check for an in RAM romfs.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	mov.l	(%a0), %d0
+	cmp.l	#0x2d726f6d, %d0		/* Check for "-rom" */
+	bne	use_xip_romfs
+	add.l	#4, %a0
+	mov.l	(%a0), %d0
+	cmp.l	#0x3166732d, %d0		/* Check for "1fs-" */
+	bne	use_xip_romfs
+#endif
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+#ifdef CONFIG_ROMFS_FROM_ROM
+	bra	done_romfs
+use_xip_romfs:
+	lea.l	_ebss, %a1			/* Set up destination  */
+	mov.l	#0, (%a1)			/* No old RAM version */
+	move.l	%a1, _ramstart			/* Set start of ram */
+done_romfs:
+#endif
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+#ifndef CONFIG_SMALL_TASKS
+	lea	0x2000(%a0), %sp
+#else
+	lea	0x1000(%a0), %sp
+#endif
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/CANCam/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5272/CANCam/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5272/CANCam/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/CANCam/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,69 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x400, LENGTH = 0x4000000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/config.c linux-2.4.29-uc1/arch/m68knommu/platform/5272/config.c
--- linux-2.4.29/arch/m68knommu/platform/5272/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/config.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,502 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/5272/config.c
+ *
+ *	Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
+ *	Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
+ *	Copyright (C) 2002,      Arcturus Networks Inc. (www.ArcturusNetworks.com)
+ *
+ *      Support for Arcturus Networks' uC5272 dimm by
+ *        Michael Leslie <mleslie@arcturusnetworks.com>
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <linux/ledman.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcftimer.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+#include <asm/delay.h>
+
+/***************************************************************************/
+
+#if defined (CONFIG_UCBOOTSTRAP)
+#include <asm/uCbootstrap.h>
+
+int    ConTTY = 0;
+static int errno;
+_bsc0(char *, getserialnum)
+_bsc1(unsigned char *, gethwaddr, int, a)
+_bsc1(char *, getbenv, char *, a)
+#endif
+
+#if defined (CONFIG_BOARD_UC5272)
+unsigned char cs8900a_hwaddr[6];
+unsigned char fec_hwaddr[6];
+unsigned char *sn;
+#endif
+
+/***************************************************************************/
+
+void	reset_setupbutton(void);
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int   dma_base_addr[MAX_DMA_CHANNELS] = {
+	MCF_MBAR + MCFDMA_BASE0,
+};
+
+unsigned int dma_device_address[MAX_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE4);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned long	*icrp;
+
+	/* Set up TIMER 4 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE4);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_CLK / 16) / HZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = 0x0000000d; /* TMR4 with priority 5 */
+	request_irq(72, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+
+#if defined(CONFIG_RESETSWITCH) && !defined(CONFIG_BOARD_UC5272)
+	/* This is not really the right place to do this... */
+	reset_setupbutton();
+#endif
+}
+
+/***************************************************************************/
+
+unsigned long coldfire_timer_offset(void)
+{
+	volatile unsigned short *timerp;
+	volatile unsigned long  *icrp;
+	unsigned long		trr, tcn, offset;
+
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE4);
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+
+	tcn = timerp[MCFTIMER_TCN];
+	trr = timerp[MCFTIMER_TRR];
+
+	/*
+	 * If we are still in the first half of the upcount and a
+	 * timer interupt is pending, then add on a ticks worth of time.
+	 */
+	offset = ((tcn * (1000000 / HZ)) / trr);
+	if ((offset < (1000000 / HZ / 2)) && ((*icrp & 0x00000008) != 0))
+		offset += 1000000 / HZ;
+	return offset;	
+}
+
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	/* Everything is auto-vectored on the 5272 */
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void coldfire_trap_init(void)
+{
+	int i;
+
+#ifndef ENABLE_dBUG
+	volatile unsigned long	*icrp;
+
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	icrp[0] = 0x88888888;
+	icrp[1] = 0x88888888;
+	icrp[2] = 0x88888888;
+	icrp[3] = 0x88888888;
+#endif
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+
+#if !defined(CONFIG_UCBOOTSTRAP)
+        for (i = 33; (i <= 63); i++)
+                _ramvec[i] = trap;
+#else /* defined(CONFIG_UCBOOTSTRAP) */
+        _ramvec[33] = trap;
+        /* skip trap #2; this is used as the uCbootloader callback */
+        for (i = 35; (i <= 63); i++)
+                _ramvec[i] = trap;
+#endif
+
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+}
+
+/***************************************************************************/
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+
+void dump(struct pt_regs *fp)
+{
+	extern unsigned int sw_usp, sw_ksp;
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk("\nCURRENT PROCESS:\n\n");
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
+			(int) current->mm->start_stack,
+			(int) ((unsigned long) current) + KTHREAD_SIZE);
+	}
+
+	printk("PC: %08lx\n", fp->pc);
+	printk("SR: %08lx    SP: %08lx\n", (long) fp->sr, (long) fp);
+	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+		fp->d0, fp->d1, fp->d2, fp->d3);
+	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+		fp->d4, fp->d5, fp->a0, fp->a1);
+	printk("\nUSP: %08x   KSP: %08x   TRAPFRAME: %08x\n",
+		sw_usp, sw_ksp, (unsigned int) fp);
+
+	printk("\nCODE:");
+	tp = ((unsigned char *) fp->pc) - 0x20;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+	printk("\n");
+
+	printk("\nUSER STACK:");
+	tp = (unsigned char *) (sw_usp - 0x10);
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n\n");
+}
+
+/***************************************************************************/
+
+void coldfire_reset(void)
+{
+	HARD_RESET_NOW();
+}
+
+/***************************************************************************/
+
+#ifdef CONFIG_PPCBOOT
+
+#define PPCBOOT_ENV_START 0xffe04000
+#define PPCBOOT_ENV_END   0xffe06000
+
+char *ppcboot_getenv(char* v)
+{
+	char* p = (char*)PPCBOOT_ENV_START+4;
+	while (1) {
+		char* e = p;
+		while ((*p != '=') && (*p != 0) && (p < (char*)PPCBOOT_ENV_END)) p++;
+			if (*p == '=') {
+				if (strncmp(v,e,p-e) == 0)
+					return p+1;
+				else
+					while ((*p++ != 0) && (p < (char*)PPCBOOT_ENV_END))
+						;
+			} else {
+				return 0;
+			}
+	};
+};
+
+#endif
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+	unsigned char *p;
+
+#if defined(CONFIG_BOARD_MOD5272)
+	volatile unsigned char	*pivrp;
+
+	/* Set base of device vectors to be 64 */
+	pivrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_PIVR);
+	*pivrp = 0x40;
+#endif
+
+#ifdef CONFIG_BOOTPARAM
+	strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+	commandp[size-1] = 0;
+#elif defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
+      defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \
+      defined(CONFIG_GILBARCONAP) || defined(CONFIG_SE1100) || \
+	 defined(CONFIG_SCALES)
+	/* Copy command line from FLASH to local buffer... */
+	memcpy(commandp, (char *) 0xf0004000, size);
+	commandp[size-1] = 0;
+#elif defined(CONFIG_MTD_KeyTechnology)
+	/* Copy command line from FLASH to local buffer... */
+	memcpy(commandp, (char *) 0xffe06000, size);
+	commandp[size-1] = 0;
+#elif defined(CONFIG_CANCam)
+	/* Copy command line from FLASH to local buffer... */
+	memcpy(commandp, (char *) 0xf0010000, size);
+	commandp[size-1] = 0;
+#elif defined(CONFIG_PPCBOOT)
+	do {
+		char *bootargs = ppcboot_getenv("bootargs");
+		if (bootargs)
+			strncpy(commandp, bootargs, size);
+	} while(0);
+#elif defined (CONFIG_BOARD_UC5272)
+	/* printk("\nColdfire uC5272 uCdimm support (c) 2002 Arcturus Networks Inc.\n"); */
+#if defined(CONFIG_UC5272_PHY_INT)
+	{
+		/** ver 1.3 uCdimm and above have PHY interrupt on INT6 **/
+		/* set GPIO to be INT6 instead - b30-31 => 01 */
+		volatile unsigned int	*temp_ptr;
+
+		/* Reset the ColdFire timer */
+		temp_ptr = (volatile unsigned int *) (MCF_MBAR + MCFSIM_PACNT);
+		*temp_ptr &= 0x3fffffff;
+		*temp_ptr |= 0x40000000;
+	}
+#endif /* CONFIG_UC5272_PHY_INT */
+ 
+#if defined(CONFIG_UCBOOTSTRAP)
+	printk("uC5272 serial string [%s]\n", getserialnum());
+
+	p = gethwaddr(0);
+	memcpy (fec_hwaddr, p, 6);
+	if (p == NULL) {
+		memcpy (fec_hwaddr, "\0x00\0xde\0xad\0xbe\0xef\0x27", 6);
+		p = fec_hwaddr;
+		printk ("Warning: HWADDR0 not set in uCbootloader. Using default.\n");
+	}
+	printk("uCbootstrap eth addr 0 %02x:%02x:%02x:%02x:%02x:%02x\n",
+		p[0], p[1], p[2], p[3], p[4], p[5]);
+
+	p = gethwaddr(1);
+	memcpy (cs8900a_hwaddr, p, 6);
+	if (p == NULL) {
+		memcpy (cs8900a_hwaddr, "\0x00\0xde\0xad\0xbe\0xef\0x28", 6);
+		p = cs8900a_hwaddr;
+		printk ("Warning: HWADDR1 not set in uCbootloader. Using default.\n");
+	}
+	printk("uCbootstrap eth addr 1 %02x:%02x:%02x:%02x:%02x:%02x\n",
+		p[0], p[1], p[2], p[3], p[4], p[5]);
+
+	p = getbenv("CONSOLE");
+	if (p != NULL)
+		sprintf(commandp, " console=%s", p);
+
+	p = getbenv("APPEND");
+	if (p != NULL)
+		strcat(commandp, p);
+#else
+	memset(commandp, 0, size);
+	sprintf (commandp, "ip=dhcp console=ttyS0");
+#endif
+#else
+	memset(commandp, 0, size);
+#endif
+
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+	mach_reset = coldfire_reset;
+	mach_gettimeoffset = coldfire_timer_offset;
+
+#ifdef CONFIG_DS1302
+{
+	extern int ds1302_set_clock_mmss(unsigned long);
+	extern void ds1302_gettod(int *, int *, int *, int *, int *, int *);
+	mach_set_clock_mmss = ds1302_set_clock_mmss;
+	mach_gettod = ds1302_gettod;
+}
+#endif
+}
+
+/***************************************************************************/
+#ifdef CONFIG_RESETSWITCH
+/***************************************************************************/
+
+/*
+ *	Routines to support the NETtel software reset button.
+ */
+void reset_button(int irq, void *dev_id, struct pt_regs *regs)
+{
+	volatile unsigned long	*icrp, *isrp;
+	static int		inbutton = 0;
+
+	/*
+	 *	IRQ7 is not maskable by the CPU core. It is possible
+	 *	that switch bounce mey get us back here before we have
+	 *	really serviced the interrupt.
+	 */
+	if (inbutton)
+		return;
+	inbutton = 1;
+
+	/* Disable interrupt at SIM - best we can do... */
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x07777777) | 0x80000000;
+
+#ifdef CONFIG_LEDMAN
+	ledman_signalreset();
+#endif
+
+	/* Don't leave here 'till button is no longer pushed! */
+	isrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ISR);
+	for (;;) {
+		if (*isrp & 0x80000000)
+			break;
+	}
+
+#ifndef CONFIG_LEDMAN
+	HARD_RESET_NOW();
+	/* Should never get here... */
+#endif
+
+	inbutton = 0;
+	/* Interrupt service done, acknowledge it */
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x07777777) | 0xf0000000;
+}
+
+/***************************************************************************/
+
+void reset_setupbutton(void)
+{
+	volatile unsigned long	*icrp;
+
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x07777777) | 0xf0000000;
+	request_irq(65, reset_button, (SA_INTERRUPT | IRQ_FLG_FAST),
+		"Reset Button", NULL);
+}
+
+/***************************************************************************/
+#endif /* CONFIG_RESETSWITCH */
+/***************************************************************************/
+#if defined(CONFIG_UCBOOTSTRAP)
+/***************************************************************************/
+
+unsigned char *get_MAC_address(char *devname)
+{
+	char *devnum  = devname + (strlen(devname)-1);
+	char *varname = "HWADDR0";
+	char *varnum  = varname + (strlen(varname)-1);
+	static unsigned char tmphwaddr[6] = {0, 0, 0, 0, 0, 0};
+	char *ret;
+	int i;
+
+	strcpy ( varnum, devnum );
+
+	ret = getbenv(varname);
+
+	memset(tmphwaddr, 0, 6);
+	if (ret && strlen(ret) == 17) {
+		for (i=0; i<6; i++) {
+			ret[(i+1) * 3] = 0;
+			tmphwaddr[i] = simple_strtoul(ret + i*3, 0, 16);
+		}
+	}
+	return(tmphwaddr);
+}
+
+/***************************************************************************/
+#endif /* CONFIG_UCBOOTSTRAP */
+/***************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/5272/Makefile
--- linux-2.4.29/arch/m68knommu/platform/5272/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,50 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+#
+# re-use any 5307/coldfire files that we can.  Perhaps we should create
+# a coldfire directory for shared files ?
+#
+
+VPATH := $(VPATH):../5307
+
+ifdef CONFIG_FULLDEBUG
+	AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+#
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# AFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o ints.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
+
+entry.o: entry.S m68k_defs.h
+
+m68k_defs.h: ../../kernel/m68k_defs.c ../../kernel/m68k_defs.head
+	rm -f m68k_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/m68k_defs.c
+	cp ../../kernel/m68k_defs.head m68k_defs.h
+	grep '^#define' m68k_defs.s >> m68k_defs.h
+	rm m68k_defs.s
+-include m68k_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/MCP751/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5272/MCP751/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5272/MCP751/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/MCP751/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,201 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5272 ColdFire based MOTOROLA boards.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ *	(C) Copyright 2000, Lineo (www.lineo.com).
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Motorola M5272C3 ColdFire eval board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec	%a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+#if defined(CONFIG_RAMAUTO)
+	move.l	MCF_MBAR+0x7c, %d0		/* Get SDRAM address mask */
+	andi.l	#0xfffff000, %d0		/* Mask out chip select options */
+	neg.l	%d0				/* Get size */
+#else
+#if defined(CONFIG_RAM16MB)
+#define	MEM_SIZE	0x01000000		/* Memory size 16Mb */
+#elif defined(CONFIG_RAM8MB)
+#define	MEM_SIZE	0x00800000		/* Memory size 8Mb */
+#else
+#define	MEM_SIZE	0x00400000		/* Memory size 4Mb */
+#endif
+	move.l	#MEM_SIZE, %d0
+#endif
+
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/MCP751/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5272/MCP751/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5272/MCP751/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/MCP751/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,68 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x400, LENGTH = 0x7FFC00
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+        	*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/MOD5272/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5272/MOD5272/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5272/MOD5272/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/MOD5272/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,162 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for Netburner MOD5272 ColdFire board.
+ *
+ *	(C) Copyright 2003, Phil Wilshire <philwil@sydcs.com>
+ *	(C) Copyright 2002, Michael Leslie <mleslie@arcturusnetworks.com>
+ *	(C) Copyright 2000, Lineo (www.lineo.com).
+ *	(C) Copyright 1999, Greg Ungerer (gerg@snapgear.com).
+ *
+ * 	2003/04/22 Modified for use with and without Cramfs Phil Wilshire
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/* Chip select and memory setup. */
+
+#define	MEM_BASE	0x02000000	/* Memory base at address 0x02000000 */
+#define	MEM_SIZE	(MEM_BASE + 0x00800000)	/* Memory size 8Mb */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+
+	
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+	
+	/* jsr	disablecache */
+	 jsr	enablecache 
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+#endif
+
+#ifdef  CONFIG_UC5272_CRAMFS
+/* Tell setup.c where the heap starts:	 */
+	lea.l	_end_romfs, %a0			/* Get end of romfs */
+	move.l	%a0,%d0
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+	move.l	%d0, _ramstart			/* Set start of heap */
+
+#endif
+	
+/* Clear .bss: */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/* Load the current task pointer and stack */
+	lea		init_task_union, %a0
+	movel		%a0, _current_task
+	lea		0x2000(%a0), %sp
+
+	/* Enable cache: */
+	/* jsr	enablecache */
+
+	/* Assember start up done, start code proper: */
+	/* pea	0       */
+	/* pea	env     */
+	/* pea	%sp@(4) */
+	/* pea	0       */
+	jsr	start_kernel
+
+	
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
+
+/* Disable the cpu cache: (clobbers %d0) */
+disablecache:
+	move.l	#0x00000000, %d0
+	move.c	%d0,%CACR
+	move.c	%d0, %ACR0
+	move.c	%d0, %ACR1
+	rts
+
+/* Enable the cpu cache: (clobbers %d0) */
+enablecache:
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+	rts
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/MOD5272/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5272/MOD5272/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5272/MOD5272/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/MOD5272/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,73 @@
+MEMORY {
+	bvec   : ORIGIN = 0x02020000, LENGTH = 0x00000400
+	ram    : ORIGIN = 0x02020400, LENGTH = 0x007dfc00
+}
+
+SECTIONS {
+
+        /* the bvec section used to trigger the bootloader */
+	.romvec :
+	{
+		_romvec = . ;
+	} > bvec
+
+	.text : {
+		_stext = . ;
+        *(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+        *(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/MOTOROLA/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5272/MOTOROLA/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5272/MOTOROLA/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/MOTOROLA/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,201 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5272 ColdFire based MOTOROLA boards.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ *	(C) Copyright 2000, Lineo (www.lineo.com).
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Motorola M5272C3 ColdFire eval board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec	%a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+#if defined(CONFIG_RAMAUTO)
+	move.l	MCF_MBAR+0x7c, %d0		/* Get SDRAM address mask */
+	andi.l	#0xfffff000, %d0		/* Mask out chip select options */
+	neg.l	%d0				/* Get size */
+#else
+#if defined(CONFIG_RAM16MB)
+#define	MEM_SIZE	0x01000000		/* Memory size 16Mb */
+#elif defined(CONFIG_RAM8MB)
+#define	MEM_SIZE	0x00800000		/* Memory size 8Mb */
+#else
+#define	MEM_SIZE	0x00400000		/* Memory size 4Mb */
+#endif
+	move.l	#MEM_SIZE, %d0
+#endif
+
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/MOTOROLA/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5272/MOTOROLA/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5272/MOTOROLA/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/MOTOROLA/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,69 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0x3e0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+        	*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/NETtel/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5272/NETtel/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5272/NETtel/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/NETtel/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,242 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5307 ColdFire based NETtel.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ * 	(C) Copyright 2000 Lineo Inc. (www.lineo.com) 
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+#include "asm/nettel.h"
+
+/*****************************************************************************/
+
+/*
+ *	SNapGear NETtel board memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#if defined(CONFIG_RAM16MB)
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+#elif defined(CONFIG_RAM8MB)
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#else
+#define	MEM_SIZE	0x00400000	/* Memory size 4Mb */
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+/*
+ *	The NETtel platform has some funky LEDs!
+ */
+.global ppdata
+ppdata:
+.short	0x0000
+
+.global ledbank
+ledbank:
+.byte	0xff
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Set size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+	nop
+
+
+#ifdef CONFIG_ROMFS_FROM_ROM
+	/*
+	 *	Check for an in RAM romfs.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	mov.l	(%a0), %d0
+	cmp.l	#0x2d726f6d, %d0		/* Check for "-rom" */
+	bne	use_xip_romfs
+	add.l	#4, %a0
+	mov.l	(%a0), %d0
+	cmp.l	#0x3166732d, %d0		/* Check for "1fs-" */
+	bne	use_xip_romfs
+#endif
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+#ifdef CONFIG_ROMFS_FROM_ROM
+	bra	done_romfs
+use_xip_romfs:
+	lea.l	_ebss, %a1			/* Set up destination  */
+	mov.l	#0, (%a1)			/* No old RAM version */
+	move.l	%a1, _ramstart			/* Set start of ram */
+done_romfs:
+#endif
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+#ifndef CONFIG_SMALL_TASKS
+	lea	0x2000(%a0), %sp
+#else
+	lea	0x1000(%a0), %sp
+#endif
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/NETtel/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5272/NETtel/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5272/NETtel/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/NETtel/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,69 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x400, LENGTH = 0x400000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        *(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/Rules.make linux-2.4.29-uc1/arch/m68knommu/platform/5272/Rules.make
--- linux-2.4.29/arch/m68knommu/platform/5272/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/Rules.make	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,46 @@
+#
+# 5272/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1999,2001  Greg Ungerer (gerg@snapgear.com)
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uClinux.org>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+# Copyright (C) 2000  Lineo Inc. (www.lineo.com)
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+# Even though we're building for a 5272, we specify 5307 as our processor type.
+# The 5307 instruction set is the same as the 5272 (divide unit & MAC) plus
+# the 5272 instruction timings are closer to the 5307 than the other 5200
+# series processors (specifically the multiply and divide instructions which
+# are all this option really alters).
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/m5307/libgcc.a
+
+CFLAGS := -fno-builtin -nostdinc $(CFLAGS) -I$(INCGCC) -pipe -DNO_MM -DNO_FPU -m5307 -Wa,-S -Wa,-m5307 -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME=\"uClinux\" -D__linux__ -O1
+AFLAGS := $(CFLAGS)
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+            arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f arch/$(ARCH)/platform/$(PLATFORM)/m68k_defs.h
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/SCALES/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5272/SCALES/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5272/SCALES/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/SCALES/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,221 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for Feith SCALES board.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ * 	(C) Copyright 2000 Lineo Inc. (www.lineo.com) 
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	SNapGear NETtel board memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+#define MEM_SIZE  0x02000000      /* Memory size 32Mb */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Set size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+	nop
+
+
+#ifdef CONFIG_ROMFS_FROM_ROM
+	/*
+	 *	Check for an in RAM romfs.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	mov.l	(%a0), %d0
+	cmp.l	#0x2d726f6d, %d0		/* Check for "-rom" */
+	bne	use_xip_romfs
+	add.l	#4, %a0
+	mov.l	(%a0), %d0
+	cmp.l	#0x3166732d, %d0		/* Check for "1fs-" */
+	bne	use_xip_romfs
+#endif
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+#ifdef CONFIG_ROMFS_FROM_ROM
+	bra	done_romfs
+use_xip_romfs:
+	lea.l	_ebss, %a1			/* Set up destination  */
+	mov.l	#0, (%a1)			/* No old RAM version */
+	move.l	%a1, _ramstart			/* Set start of ram */
+done_romfs:
+#endif
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+#ifndef CONFIG_SMALL_TASKS
+	lea	0x2000(%a0), %sp
+#else
+	lea	0x1000(%a0), %sp
+#endif
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/SCALES/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5272/SCALES/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5272/SCALES/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/SCALES/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,69 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x400, LENGTH = 0x2000000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/SE1100/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5272/SE1100/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5272/SE1100/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/SE1100/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,194 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5272 based SecureEdge SE1100 boards.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ * 	Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+#include "asm/nettel.h"
+
+/*****************************************************************************/
+
+/*
+ *	SecureEdge SE1100 board memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#if defined(CONFIG_RAM16MB)
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+#elif defined(CONFIG_RAM8MB)
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#else
+#define	MEM_SIZE	0x00400000	/* Memory size 4Mb */
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+/*
+ *	Platform has some funky LEDs!
+ */
+/*.global ppdata
+ppdata:
+.short	0x0000 */
+
+.global ledbank
+ledbank:
+.byte	0xff
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+	nop
+
+#ifdef CONFIG_ROMFS_FROM_ROM
+	/*
+	 *	Check for an in RAM romfs.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	mov.l	(%a0), %d0
+	cmp.l	#0x2d726f6d, %d0		/* check for "-rom" */
+	bne	use_xip_romfs
+	add.l	#4, %a0
+	mov.l	(%a0), %d0
+	cmp.l	#0x3166732d, %d0		/* check for "1fs-" */
+	bne	use_xip_romfs
+#endif
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#ifdef CONFIG_ROMFS_FROM_ROM
+	bra	done_romfs
+use_xip_romfs:
+	lea.l	_ebss, %a1			/* Set up destination  */
+	mov.l	#0, (%a1)			/* Make sure we don't use an */
+						/* old RAM version */
+	move.l	%a1, _ramstart			/* Set start of ram */
+done_romfs:
+#endif
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+#ifndef CONFIG_SMALL_TASKS
+	lea	0x2000(%a0), %sp
+#else
+	lea	0x1000(%a0), %sp
+#endif
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/SE1100/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5272/SE1100/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5272/SE1100/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/SE1100/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,69 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x400, LENGTH = 0x400000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        *(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/senTec/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5272/senTec/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5272/senTec/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/senTec/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,205 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for COBRA5272 board.
+ *
+ *	(C) Copyright 2000, Lineo (www.lineo.com).
+ *	(C) Copyright 1999, Greg Ungerer (gerg@snapgear.com).
+ *
+ *    1999/02/24 Modified for the 5307 processor David W. Miller
+ *    2002/03/20 Modified for senTec COBRA5272 board (H. Degenhardt)
+ *    2002/07/22 We now check the CONFIG_RAM??MB vars, and set up the
+ *               ram size accordingly.
+ *               (H. Degenhardt)
+ *    2003/03/20 We now support the EPSON S1D13706 LCD controller.
+ *               It gets initialized if CONFIG_FB_COBRA5272 is set
+ *               (hede)
+ *    2003/04/08 We now support the EPSON S1D13806 LCD controller, too.
+ *               It gets initialized if CONFIG_FB_COBRA5272 is set
+ *               (hede)
+ * 
+ * 
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	COBRA5272 board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#if defined(CONFIG_RAM32MB)
+#define MEM_SIZE        0x02000000      /* Memory size 32Mb */
+#elif defined(CONFIG_RAM16MB)
+#define MEM_SIZE        0x01000000      /* Memory size 16Mb */
+#elif defined(CONFIG_RAM8MB)
+#define MEM_SIZE        0x00800000      /* Memory size 8Mb */
+#else
+#define MEM_SIZE        0x00400000      /* Memory size 4Mb */
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Set to 4 meg for the Cadre III board (m5206e).
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+   
+#if 1
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+#endif
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/*
+	 * load the current task pointer and stack
+	 */
+	lea		init_task_union, %a0
+	movel		%a0, _current_task
+	lea		0x2000(%a0), %sp
+
+   /*
+    * hede 20030320:
+    * 
+    * We inititialize the controler if CONFIG_FB_COBRA5272
+    * is set!
+    * init for the lcd controller
+    * ATTENTION!
+    * This has to be after the initialization of
+    * bss!
+    * 
+    * 
+    */
+
+#if defined(CONFIG_FB_COBRA5272)
+#if defined(CONFIG_FB_S1D13706)
+   /* set up CS1: */
+   move.l   #0x40000201, %d0
+   move.l   %d0, (MCF_MBAR + MCFSIM_CSBR1)
+   move.l   #0xfff0007c, %d0
+   move.l   %d0, (MCF_MBAR + MCFSIM_CSOR1)
+   /* enable /TA at PB5: */
+   move.l   #0x55554555, %d0
+   move.l   %d0, (MCF_MBAR + MCFSIM_PBCNT)
+#elif defined(CONFIG_FB_S1D13806) /* set up for S1D13806 */
+   /* set up CS1: */
+   move.l   #0x40000201, %d0
+   move.l   %d0, (MCF_MBAR + MCFSIM_CSBR1)
+   move.l   #0xff00007c, %d0
+   move.l   %d0, (MCF_MBAR + MCFSIM_CSOR1)
+   /* enable /TA at PB5: */
+   move.l   #0x55554555, %d0
+   move.l   %d0, (MCF_MBAR + MCFSIM_PBCNT)
+#endif /* end if defined(CONFIG_FB_S1D13706) */
+#endif /* end #if defined(CONFIG_FB_COBRA5272) */
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/senTec/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5272/senTec/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5272/senTec/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/senTec/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,69 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0x3e0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/SNEHA/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5272/SNEHA/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5272/SNEHA/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/SNEHA/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,201 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5272 ColdFire based MOTOROLA boards.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ *	(C) Copyright 2000, Lineo (www.lineo.com).
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Motorola M5272C3 ColdFire eval board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec	%a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+#if defined(CONFIG_RAMAUTO)
+	move.l	MCF_MBAR+0x7c, %d0		/* Get SDRAM address mask */
+	andi.l	#0xfffff000, %d0		/* Mask out chip select options */
+	neg.l	%d0				/* Get size */
+#else
+#if defined(CONFIG_RAM16MB)
+#define	MEM_SIZE	0x01000000		/* Memory size 16Mb */
+#elif defined(CONFIG_RAM8MB)
+#define	MEM_SIZE	0x00800000		/* Memory size 8Mb */
+#else
+#define	MEM_SIZE	0x00400000		/* Memory size 4Mb */
+#endif
+	move.l	#MEM_SIZE, %d0
+#endif
+
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/SNEHA/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5272/SNEHA/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5272/SNEHA/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/SNEHA/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,68 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0x3e0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+        	*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/uC5272/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5272/uC5272/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5272/uC5272/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/uC5272/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,173 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for Arcturus uCdimm uC5272 ColdFire board.
+ *
+ *	(C) Copyright 2003, Phil Wilshire <philwil@sydcs.com>
+ *	(C) Copyright 2002, Michael Leslie <mleslie@arcturusnetworks.com>
+ *	(C) Copyright 2000, Lineo (www.lineo.com).
+ *	(C) Copyright 1999, Greg Ungerer (gerg@snapgear.com).
+ *
+ * 	2003/04/22 Modified for use with and without Cramfs Phil Wilshire
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/* Chip select and memory setup for Arcturus Networks' uC5272 dimm. */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+
+	
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+/* Set to 8 meg for the uC5272 dimm: */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+	
+	/* jsr	disablecache */
+	 jsr	enablecache 
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+#endif
+
+/* set leds on test */	
+_setup_port_c:	
+/* set up port c */
+	move.l #0x10000094, %a0                 /* ddr */
+	move.b #0xff,(%a0)
+	move.l #0x10000096, %a0                 /* data */
+	move.b #0x12,(%a0)
+	/*jmp _exit */                              /* thassall */
+	
+
+#ifdef  CONFIG_UC5272_CRAMFS
+/* Tell setup.c where the heap starts:	 */
+	lea.l	_end_romfs, %a0			/* Get end of romfs */
+	move.l	%a0,%d0
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+	move.l	%d0, _ramstart			/* Set start of heap */
+
+#endif
+	
+/* Clear .bss: */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/* Load the current task pointer and stack */
+	lea		init_task_union, %a0
+	movel		%a0, _current_task
+	lea		0x2000(%a0), %sp
+
+	/* Enable cache: */
+	/* jsr	enablecache */
+
+	/* Assember start up done, start code proper: */
+	/* pea	0       */
+	/* pea	env     */
+	/* pea	%sp@(4) */
+	/* pea	0       */
+	jsr	start_kernel
+
+	
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
+
+/* Disable the cpu cache: (clobbers %d0) */
+disablecache:
+	move.l	#0x00000000, %d0
+	move.c	%d0,%CACR
+	move.c	%d0, %ACR0
+	move.c	%d0, %ACR1
+	rts
+
+/* Enable the cpu cache: (clobbers %d0) */
+enablecache:
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+	rts
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/uC5272/crt0_rom.S linux-2.4.29-uc1/arch/m68knommu/platform/5272/uC5272/crt0_rom.S
--- linux-2.4.29/arch/m68knommu/platform/5272/uC5272/crt0_rom.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/uC5272/crt0_rom.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,137 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for Arcturus uCdimm uC5272 ColdFire board. 
+ *
+ *	(C) Copyright 2000, Lineo (www.lineo.com).
+ *	(C) Copyright 1999, Greg Ungerer (gerg@snapgear.com).
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Motorola M5272C3 ColdFire eval board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	MEM_SIZE	0x003ff000	/* Memory size 4Mb */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+
+#if 1
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* Invalidate cache cmd */
+	movec	%d0, %CACR			/* Invalidate cache */
+	move.l	#0x80000100, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+#endif
+	
+	/*
+	 *      Copy data segment from ROM to RAM
+	 */
+	lea	__data_rom_start, %a0
+	lea	_sdata, %a1
+	lea	_edata, %a2
+_copy_data:
+	movel	%a0@+, %a1@+
+	cmpal	%a1, %a2
+	bhi	_copy_data
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+        movel   #VBR_BASE, %d0    
+        movel   %d0, _rambase
+	       
+        movel   #_ebss, %d0
+        movel   %d0, _ramstart
+	
+        movel   #MEM_SIZE, %d0
+        movel   %d0, _ramend
+	
+        movel   #VBR_BASE, %d0
+        movel   %d0, _ramvec
+
+	/*
+	 * load the current task pointer and stack
+	 */
+	lea		init_task_union, %a0
+	movel		%a0, _current_task
+	lea		0x2000(%a0), %sp
+	
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/uC5272/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5272/uC5272/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5272/uC5272/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/uC5272/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,99 @@
+
+INCLUDE arch/m68knommu/platform/5272/uC5272/romfs.ld
+
+MEMORY {
+	bvec   : ORIGIN = 0x00020000, LENGTH = 0x00000400
+	ram    : ORIGIN = 0x00020400, LENGTH = 0x007e0000
+	flash  : ORIGIN = 0x10c00000, LENGTH = 0x00400000
+	eram   : ORIGIN = 0x00800000, LENGTH = 0     
+}
+
+SECTIONS {
+
+        /* the bvec section used to trigger the bootloader */
+	.romvec :
+	{
+		_romvec = . ;
+	} > bvec
+
+	.text : {
+		_stext = . ;
+        *(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+
+        .eram :
+        {
+        __ramend = . ;
+        /*_ramend = . ; this will break the application */
+        } > eram
+
+        .fs :   {
+                _romfs = ABSOLUTE (.);
+                                     /* see the makefile on how this is used */
+                . = . + romfs_size;  /* romfs_size must be calcuated */
+                _end_romfs = ABSOLUTE (.); /* this seems to be important !! */
+        } > ram
+
+	.flash : {
+		_flashstart = ABSOLUTE (.);
+		. = . + 131072;
+		_image_start = ABSOLUTE (.);
+	
+	} > flash
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/uC5272/romfs.default.ld linux-2.4.29-uc1/arch/m68knommu/platform/5272/uC5272/romfs.default.ld
--- linux-2.4.29/arch/m68knommu/platform/5272/uC5272/romfs.default.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/uC5272/romfs.default.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1 @@
+romfs_size =       6;
diff -urN linux-2.4.29/arch/m68knommu/platform/5272/uC5272/romfs.ld linux-2.4.29-uc1/arch/m68knommu/platform/5272/uC5272/romfs.ld
--- linux-2.4.29/arch/m68knommu/platform/5272/uC5272/romfs.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5272/uC5272/romfs.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1 @@
+romfs_size =       6;
diff -urN linux-2.4.29/arch/m68knommu/platform/527x/config.c linux-2.4.29-uc1/arch/m68knommu/platform/527x/config.c
--- linux-2.4.29/arch/m68knommu/platform/527x/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/527x/config.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,255 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/527x/config.c
+ *
+ *	Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com)
+ *	Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <linux/ledman.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcfpit.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+#include <asm/delay.h>
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int   dma_base_addr[MAX_DMA_CHANNELS] = {
+        MCF_MBAR + MCFDMA_BASE0,
+};
+
+unsigned int dma_device_address[MAX_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile struct mcfpit	*tp;
+
+	/* Reset the ColdFire timer */
+	tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
+	tp->pcsr |= MCFPIT_PCSR_PIF;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile unsigned char	*icrp;
+	volatile unsigned long	*imrp;
+	volatile struct mcfpit	*tp;
+
+	request_irq(64+36, handler, SA_INTERRUPT, "ColdFire Timer", tp);
+
+	icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
+		MCFINTC_ICR0 + MCFINT_PIT1);
+	*icrp = 0x2b; /* PIT1 with level 5, priority 3 */
+
+	imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
+	*imrp &= ~(1 << (36 - 32));
+
+	/* Set up PIT timer 1 as poll clock */
+	tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
+	tp->pcsr = MCFPIT_PCSR_DISABLE;
+
+	tp->pmr = ((MCF_CLK / 2) / 64) / HZ;
+	tp->pcsr = MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | MCFPIT_PCSR_OVW |
+		MCFPIT_PCSR_RLD | MCFPIT_PCSR_CLK64;
+}
+
+/***************************************************************************/
+
+unsigned long coldfire_timer_offset(void)
+{
+	volatile struct mcfpit *tp;
+	volatile unsigned long *ipr;
+	unsigned long pmr, pcntr, offset;
+
+	tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
+	ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IPRH);
+
+	pmr = *(&tp->pmr);
+	pcntr = *(&tp->pcntr);
+
+	/*
+	 * If we are still in the first half of the upcount and a
+	 * timer interupt is pending, then add on a ticks worth of time.
+	 */
+	offset = ((pmr - pcntr) * (1000000 / HZ)) / pmr;
+	if (((offset * 2) < (1000000 / HZ)) && (*ipr & (1 << (36 - 32))))
+		offset += 1000000 / HZ;
+	return offset;	
+}
+
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	/* Everything is auto-vectored on the 5282 */
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void coldfire_trap_init(void)
+{
+	int i;
+
+	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
+	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+	for (i = 33; (i <= 63); i++)
+		_ramvec[i] = trap;
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+}
+
+/***************************************************************************/
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+
+void dump(struct pt_regs *fp)
+{
+	extern unsigned int sw_usp, sw_ksp;
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk("\nCURRENT PROCESS:\n\n");
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
+			(int) current->mm->start_stack,
+			(int) ((unsigned long) current) + KTHREAD_SIZE);
+	}
+
+	printk("PC: %08lx\n", fp->pc);
+	printk("SR: %08lx    SP: %08lx\n", (long) fp->sr, (long) fp);
+	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+		fp->d0, fp->d1, fp->d2, fp->d3);
+	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+		fp->d4, fp->d5, fp->a0, fp->a1);
+	printk("\nUSP: %08x   KSP: %08x   TRAPFRAME: %08x\n",
+		sw_usp, sw_ksp, (unsigned int) fp);
+
+	printk("\nCODE:");
+	tp = ((unsigned char *) fp->pc) - 0x20;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+	printk("\n");
+
+	printk("\nUSER STACK:");
+	tp = (unsigned char *) (sw_usp - 0x10);
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n\n");
+}
+
+/***************************************************************************/
+
+void coldfire_reset(void)
+{
+	HARD_RESET_NOW();
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+#ifdef CONFIG_BOOTPARAM
+	strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+	commandp[size-1] = 0;
+#else
+	memset(commandp, 0, size);
+#endif
+
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+	mach_reset = coldfire_reset;
+	mach_gettimeoffset = coldfire_timer_offset;
+}
+
+/***************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/527x/M5271EVB/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/527x/M5271EVB/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/527x/M5271EVB/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/527x/M5271EVB/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,205 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF527x ColdFire based MOTOROLA boards.
+ *
+ *	(C) Copyright 1999-2004, Greg Ungerer (gerg@snapgear.com).
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Motorola M5271EVB ColdFire eval board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#if defined(CONFIG_RAM4MB)
+#define	MEM_SIZE	0x00400000	/* Memory size 4Mb */
+#elif defined(CONFIG_RAM8MB)
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#else
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+	/*
+	 *	Set memory size.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+#if 1
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01400000, %d0
+	movec	%d0, %CACR			/* Invalidate cache */
+	nop
+
+	move.l	#0x0000c000, %d0		/* Set SDRAM cached only */
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR1
+
+	move.l	#0x80400100, %d0		/* Configure cache */
+	movec	%d0, %CACR			/* Enable cache */
+	nop
+#endif
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/527x/M5271EVB/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/527x/M5271EVB/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/527x/M5271EVB/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/527x/M5271EVB/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,69 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0x3e0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/527x/M5275EVB/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/527x/M5275EVB/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/527x/M5275EVB/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/527x/M5275EVB/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,205 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF527x ColdFire based MOTOROLA boards.
+ *
+ *	(C) Copyright 1999-2004, Greg Ungerer (gerg@snapgear.com).
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Motorola M5275EVB ColdFire eval board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#if defined(CONFIG_RAM4MB)
+#define	MEM_SIZE	0x00400000	/* Memory size 4Mb */
+#elif defined(CONFIG_RAM8MB)
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#else
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+	/*
+	 *	Set memory size.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+#if 1
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01400000, %d0
+	movec	%d0, %CACR			/* Invalidate cache */
+	nop
+
+	move.l	#0x0000c000, %d0		/* Set SDRAM cached only */
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR1
+
+	move.l	#0x80400100, %d0		/* Configure cache */
+	movec	%d0, %CACR			/* Enable cache */
+	nop
+#endif
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/527x/M5275EVB/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/527x/M5275EVB/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/527x/M5275EVB/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/527x/M5275EVB/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,69 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0x3e0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/527x/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/527x/Makefile
--- linux-2.4.29/arch/m68knommu/platform/527x/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/527x/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,50 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+#
+# re-use any 5307/coldfire files that we can.  Perhaps we should create
+# a coldfire directory for shared files ?
+#
+
+VPATH := $(VPATH):../5307
+
+ifdef CONFIG_FULLDEBUG
+	AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+#
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# AFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o ints.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
+
+entry.o: entry.S m68k_defs.h
+
+m68k_defs.h: ../../kernel/m68k_defs.c ../../kernel/m68k_defs.head
+	rm -f m68k_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/m68k_defs.c
+	cp ../../kernel/m68k_defs.head m68k_defs.h
+	grep '^#define' m68k_defs.s >> m68k_defs.h
+	rm m68k_defs.s
+-include m68k_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/platform/527x/Rules.make linux-2.4.29-uc1/arch/m68knommu/platform/527x/Rules.make
--- linux-2.4.29/arch/m68knommu/platform/527x/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/527x/Rules.make	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,46 @@
+#
+# 5282/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1999-2003  Greg Ungerer (gerg@snapgear.com)
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uClinux.org>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+# Copyright (C) 2000  Lineo Inc. (www.lineo.com)
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+# Even though we're building for a 5282, we specify 5307 as our processor type.
+# The 5307 instruction set is the same as the 5282 (divide unit & MAC) plus
+# the 5282 instruction timings are closer to the 5307 than the other 5200
+# series processors (specifically the multiply and divide instructions which
+# are all this option really alters).
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/m5307/libgcc.a
+
+CFLAGS := -fno-builtin -nostdinc $(CFLAGS) -I$(INCGCC) -pipe -DNO_MM -DNO_FPU -m5307 -Wa,-S -Wa,-m5307 -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME=\"uClinux\" -D__linux__ -O1
+AFLAGS := $(CFLAGS)
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+            arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f arch/$(ARCH)/platform/$(PLATFORM)/m68k_defs.h
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5280/config.c linux-2.4.29-uc1/arch/m68knommu/platform/5280/config.c
--- linux-2.4.29/arch/m68knommu/platform/5280/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5280/config.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,283 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/5280/config.c
+ *
+ * Copied from linux/arch/m68knommu/platform/5282/config.c
+ * that is
+ *	Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
+ *	Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
+ */
+
+/*
+ * CHANGES
+ * 20030916 hede (heiko.degenhardt@sentec-elektronik.de)
+ * 	-	I changed the timer stuff according to MCF5282UM.pdf,
+ * 		rev. 1, 4/2003, chapter 19 "Programmable Interrupt Timer
+ * 		Modules".
+ * 	-	I tried to let the timer period be 10ms, and to calculate
+ * 		the offset in coldfire_timer_offset for an downcounting
+ * 		timer.
+ * 	FIXME: Could somebody verify my changes?
+ * 
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <linux/ledman.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcfpit.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+#include <asm/delay.h>
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int   dma_base_addr[MAX_DMA_CHANNELS] = {
+        MCF_MBAR + MCFDMA_BASE0,
+};
+
+unsigned int dma_device_address[MAX_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile struct mcfpit	*tp;
+
+	/* Reset the ColdFire timer */
+	tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
+	tp->pcsr |= MCFPIT_PCSR_PIF;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile unsigned char	*icrp;
+	volatile unsigned long	*imrp;
+	volatile struct mcfpit	*tp;
+
+	request_irq(64+55, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+
+	icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
+		MCFINTC_ICR0 + MCFINT_PIT1);
+	*icrp = 0x2b; /* PIT1 with level 5, priority 3 */
+
+	imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
+	*imrp &= ~(1 << (55 - 32));
+
+	/* Set up PIT timer 1 as poll clock */
+	tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
+	tp->pcsr = MCFPIT_PCSR_DISABLE;
+
+	/*
+	 * ATTENTION!
+	 * We try to get a timeout period of 10ms.
+	 * If we set up PMR to have 4999, and on impulse will be
+	 * 2us, the timer period would be 5000 * 2us = 10ms.
+	 * 
+	 * According to mcfpit.h MCFPTI_PCSR_CLK64 is 0x0600, giving
+	 * 0x0110 in PRE[3:0]. That means "System Clock Divisor" is
+	 * 128 (see p. 19-4), including the "Divide by 2" in figure 19-1.
+	 */
+	tp->pmr = (((MCF_CLK / 128) / HZ) -1);
+	tp->pcsr = MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | MCFPIT_PCSR_OVW |
+		MCFPIT_PCSR_RLD | MCFPIT_PCSR_CLK64;
+}
+
+/***************************************************************************/
+
+unsigned long coldfire_timer_offset(void)
+{
+	volatile struct mcfpit *tp;
+	volatile unsigned long *ipr;
+	unsigned long pmr, pcntr, offset;
+
+	tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
+	ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IPRH);
+
+	pmr = tp->pmr;
+	pcntr = tp->pcntr;
+
+	/*
+	 * If we are still in the first half of the downcount and a
+	 * timer interupt is pending, then add on a ticks worth of time.
+	 *
+	 * HINT: 100000 / HZ is 10000, that means 10000 us = 10 ms!
+	 *
+	 */
+	offset = ((pmr - pcntr) * (1000000 / HZ)) / (pmr + 1);
+	if (((offset * 2) < (1000000 / HZ)) && (*ipr & (1 << (55 - 32))))
+		offset += 1000000 / HZ;
+	return offset;	
+}
+
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	/* Everything is auto-vectored on the 5282 */
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void coldfire_trap_init(void)
+{
+	int i;
+
+	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
+	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+	for (i = 33; (i <= 63); i++)
+		_ramvec[i] = trap;
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+}
+
+/***************************************************************************/
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+
+void dump(struct pt_regs *fp)
+{
+	extern unsigned int sw_usp, sw_ksp;
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk("\nCURRENT PROCESS:\n\n");
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
+			(int) current->mm->start_stack,
+			(int) ((unsigned long) current) + KTHREAD_SIZE);
+	}
+
+	printk("PC: %08lx\n", fp->pc);
+	printk("SR: %08lx    SP: %08lx\n", (long) fp->sr, (long) fp);
+	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+		fp->d0, fp->d1, fp->d2, fp->d3);
+	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+		fp->d4, fp->d5, fp->a0, fp->a1);
+	printk("\nUSP: %08x   KSP: %08x   TRAPFRAME: %08x\n",
+		sw_usp, sw_ksp, (unsigned int) fp);
+
+	printk("\nCODE:");
+	tp = ((unsigned char *) fp->pc) - 0x20;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+	printk("\n");
+
+	printk("\nUSER STACK:");
+	tp = (unsigned char *) (sw_usp - 0x10);
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n\n");
+}
+
+/***************************************************************************/
+
+void coldfire_reset(void)
+{
+	HARD_RESET_NOW();
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+#ifdef CONFIG_BOOTPARAM
+	strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+	commandp[size-1] = 0;
+#else
+	memset(commandp, 0, size);
+#endif
+
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+	mach_reset = coldfire_reset;
+	mach_gettimeoffset = coldfire_timer_offset;
+}
+
+/***************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5280/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/5280/Makefile
--- linux-2.4.29/arch/m68knommu/platform/5280/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5280/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,50 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+#
+# re-use any 5307/coldfire files that we can.  Perhaps we should create
+# a coldfire directory for shared files ?
+#
+
+VPATH := $(VPATH):../5307
+
+ifdef CONFIG_FULLDEBUG
+	AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+#
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# AFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o ints.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
+
+entry.o: entry.S m68k_defs.h
+
+m68k_defs.h: ../../kernel/m68k_defs.c ../../kernel/m68k_defs.head
+	rm -f m68k_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/m68k_defs.c
+	cp ../../kernel/m68k_defs.head m68k_defs.h
+	grep '^#define' m68k_defs.s >> m68k_defs.h
+	rm m68k_defs.s
+-include m68k_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/platform/5280/Rules.make linux-2.4.29-uc1/arch/m68knommu/platform/5280/Rules.make
--- linux-2.4.29/arch/m68knommu/platform/5280/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5280/Rules.make	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,46 @@
+#
+# 5280/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1999-2003  Greg Ungerer (gerg@snapgear.com)
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@lineo.ca>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+# Copyright (C) 2000  Lineo Inc. (www.lineo.com)
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+# Even though we're building for a 5282, we specify 5307 as our processor type.
+# The 5307 instruction set is the same as the 5282 (divide unit & MAC) plus
+# the 5282 instruction timings are closer to the 5307 than the other 5200
+# series processors (specifically the multiply and divide instructions which
+# are all this option really alters).
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/m5307/libgcc.a
+
+CFLAGS := -fno-builtin -nostdinc $(CFLAGS) -I$(INCGCC) -pipe -DNO_MM -DNO_FPU -m5307 -Wa,-S -Wa,-m5307 -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME=\"uClinux\" -D__linux__ -O1
+AFLAGS := $(CFLAGS)
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+            arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f arch/$(ARCH)/platform/$(PLATFORM)/m68k_defs.h
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5280/SSV/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5280/SSV/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5280/SSV/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5280/SSV/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,204 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5280 ColdFire based DNP5280 boards.
+ *
+ *	(C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com).
+ *
+ *	2003/09/02 Modified for SSV DNP5280 board (H. Degenhardt)
+ *	           Send feedback for the DNP5280 to 
+ *	           M. Hasewinkel <support@ist1.de>
+ *
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	SSV DNP5280 ColdFire eval board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+	/*
+	 *	Set memory size.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+#if 0
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0
+	movec	%d0, %CACR			/* Invalidate cache */
+	nop
+
+	move.l	#0x0000c000, %d0		/* Set SDRAM cached only */
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR1
+
+	move.l	#0x00000000, %d0		/* Setup cache mask */
+	movec	%d0, %CACR			/* Enable cache */
+	nop
+#endif
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5280/SSV/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5280/SSV/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5280/SSV/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5280/SSV/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,69 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x10000, LENGTH = 0x3e0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5282/AVNET/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5282/AVNET/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5282/AVNET/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5282/AVNET/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,224 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5282 ColdFire based MOTOROLA boards.
+ *
+ *	(C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com).
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Motorola M5282C3 ColdFire eval board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#if defined(CONFIG_RAM4MB)
+#define	MEM_SIZE	0x00400000	/* Memory size 4Mb */
+#elif defined(CONFIG_RAM16MB)
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+#else
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+	/*
+	 *	Set memory size.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+#if 0
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0
+	movec	%d0, %CACR			/* Invalidate cache */
+	nop
+
+	move.l	#0x0000c000, %d0		/* Set SDRAM cached only */
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR1
+
+	move.l	#0x80400100, %d0		/* Instruction cache bits */
+	movec	%d0, %CACR			/* Enable cache */
+	nop
+#endif
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+#endif
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
+
+//	// ================================================================
+//	// LED test code
+//
+//	//GPTASYSCR1  @ 0x401a0006        // GPTA Control reg 1
+//	//GPTBSYSCR1  @ 0x401b0006
+//	//GPTADR      @ 0x401a001d        // GPTA Data Reg
+//	//GPTBDR      @ 0x401b001d
+//	//GPTADDR     @ 0x401a001e        // GPTA Data Direction
+//	//GPTBDDR     @ 0x401b001e
+//	//PORT_TC     @ 0x4010000f
+//	//PORT_TD     @ 0x40100010
+//	//DDR_TC      @ 0x40100023
+//	//DDR_TD      @ 0x40100024
+//	//DR_TC       @ 0x40100037
+//	//DR_TD       @ 0x40100038
+//
+//	// LED (GPIO) initialization sequence:
+//	moveq  #0x00, d0
+//	move.b d0, 0x401a0006 // Write GPTASYSCR1 := 0x00
+//	moveq  #0x00, d0
+//	move.b d0, 0x401b0006 // Write GPTBSYSCR1 := 0x00
+//
+//	moveq  #0x00, d0
+//	move.b d0, 0x401a001e // Write GPTADDR    := 0x00
+//	moveq  #0x0f, d0
+//	move.b d0, 0x401b001e // Write GPTBDDR    := 0x0f
+//
+//	moveq  #0x05, d0
+//	move.b d0, 0x40100023 // Write DDR_TC     := 0x05
+//	moveq  #0x05, d0
+//	move.b d0, 0x40100024 // Write DDR_TD     := 0x05
+//
+//	// ----------------------------------------------------------------
+//	// Set some LED bits:
+//	move.b   0x401b001d,d0   // Read GPTBDR
+//	ori.l    #0xe,d0         // Set bits
+//	andi.l   #0xfffffffe,d0  // Clear bits
+//	move.b   d0,0x401b001d   // Write GPTBDR
+//	// ----------------------------------------------------------------
+//
diff -urN linux-2.4.29/arch/m68knommu/platform/5282/AVNET/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5282/AVNET/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5282/AVNET/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5282/AVNET/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,69 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x10000, LENGTH = 0x3e0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5282/config.c linux-2.4.29-uc1/arch/m68knommu/platform/5282/config.c
--- linux-2.4.29/arch/m68knommu/platform/5282/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5282/config.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,255 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/5282/config.c
+ *
+ *	Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
+ *	Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <linux/ledman.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcfpit.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+#include <asm/delay.h>
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int   dma_base_addr[MAX_DMA_CHANNELS] = {
+        MCF_MBAR + MCFDMA_BASE0,
+};
+
+unsigned int dma_device_address[MAX_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile struct mcfpit	*tp;
+
+	/* Reset the ColdFire timer */
+	tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
+	tp->pcsr |= MCFPIT_PCSR_PIF;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile unsigned char	*icrp;
+	volatile unsigned long	*imrp;
+	volatile struct mcfpit	*tp;
+
+	request_irq(64+55, handler, SA_INTERRUPT, "ColdFire Timer", NULL);
+
+	icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
+		MCFINTC_ICR0 + MCFINT_PIT1);
+	*icrp = 0x2b; /* PIT1 with level 5, priority 3 */
+
+	imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
+	*imrp &= ~(1 << (55 - 32));
+
+	/* Set up PIT timer 1 as poll clock */
+	tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
+	tp->pcsr = MCFPIT_PCSR_DISABLE;
+
+	tp->pmr = ((MCF_CLK / 2) / 64) / HZ;
+	tp->pcsr = MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | MCFPIT_PCSR_OVW |
+		MCFPIT_PCSR_RLD | MCFPIT_PCSR_CLK64;
+}
+
+/***************************************************************************/
+
+unsigned long coldfire_timer_offset(void)
+{
+	volatile struct mcfpit *tp;
+	volatile unsigned long *ipr;
+	unsigned long pmr, pcntr, offset;
+
+	tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
+	ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IPRH);
+
+	pmr = *(&tp->pmr);
+	pcntr = *(&tp->pcntr);
+
+	/*
+	 * If we are still in the first half of the upcount and a
+	 * timer interupt is pending, then add on a ticks worth of time.
+	 */
+	offset = ((pmr - pcntr) * (1000000 / HZ)) / pmr;
+	if (((offset * 2) < (1000000 / HZ)) && (*ipr & (1 << (55 - 32))))
+		offset += 1000000 / HZ;
+	return offset;	
+}
+
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	/* Everything is auto-vectored on the 5282 */
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void coldfire_trap_init(void)
+{
+	int i;
+
+	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
+	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+	for (i = 33; (i <= 63); i++)
+		_ramvec[i] = trap;
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+}
+
+/***************************************************************************/
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+
+void dump(struct pt_regs *fp)
+{
+	extern unsigned int sw_usp, sw_ksp;
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk("\nCURRENT PROCESS:\n\n");
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
+			(int) current->mm->start_stack,
+			(int) ((unsigned long) current) + KTHREAD_SIZE);
+	}
+
+	printk("PC: %08lx\n", fp->pc);
+	printk("SR: %08lx    SP: %08lx\n", (long) fp->sr, (long) fp);
+	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+		fp->d0, fp->d1, fp->d2, fp->d3);
+	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+		fp->d4, fp->d5, fp->a0, fp->a1);
+	printk("\nUSP: %08x   KSP: %08x   TRAPFRAME: %08x\n",
+		sw_usp, sw_ksp, (unsigned int) fp);
+
+	printk("\nCODE:");
+	tp = ((unsigned char *) fp->pc) - 0x20;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+	printk("\n");
+
+	printk("\nUSER STACK:");
+	tp = (unsigned char *) (sw_usp - 0x10);
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n\n");
+}
+
+/***************************************************************************/
+
+void coldfire_reset(void)
+{
+	HARD_RESET_NOW();
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+#ifdef CONFIG_BOOTPARAM
+	strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+	commandp[size-1] = 0;
+#else
+	memset(commandp, 0, size);
+#endif
+
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+	mach_reset = coldfire_reset;
+	mach_gettimeoffset = coldfire_timer_offset;
+}
+
+/***************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5282/FutureNetBurnerBadge/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5282/FutureNetBurnerBadge/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5282/FutureNetBurnerBadge/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5282/FutureNetBurnerBadge/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,207 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5282 ColdFire based 
+ *                    Future/Netburner "Badge" board.
+ *
+ *	(C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com).
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	M5282C3 ColdFire "Badge" board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x002000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+
+/* added jens heilig 2003-10-11: define MEM_END so that it
+ * works even if MEM_BASE ist NOT zero ...
+*/
+#define MEM_END MEM_BASE + MEM_SIZE - 1
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+	/*
+	 *	Set memory size.
+	 */
+	move.l	#MEM_END, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+#if 0
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0
+	movec	%d0, %CACR			/* Invalidate cache */
+	nop
+
+        move.l   #0x80000200,%d0
+        movec    %d0,%CACR
+
+        move.l   #0x02008000,%d0
+        movec    %d0,%ACR0
+
+        move.l   #0x02000000,%d0
+        movec    %d0,%ACR1
+
+	nop
+#endif
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5282/FutureNetBurnerBadge/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5282/FutureNetBurnerBadge/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5282/FutureNetBurnerBadge/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5282/FutureNetBurnerBadge/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,69 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x2010000, LENGTH = 0x3e0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5282/m68k_defs.h linux-2.4.29-uc1/arch/m68knommu/platform/5282/m68k_defs.h
--- linux-2.4.29/arch/m68knommu/platform/5282/m68k_defs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5282/m68k_defs.h	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+ * WARNING! This file is automatically generated - DO NOT EDIT!
+ */
+
+#define TS_MAGICKEY	0x5a5a5a5a
+#define TASK_STATE 0
+#define TASK_FLAGS 4
+#define TASK_PTRACE 24
+#define TASK_BLOCKED 766
+#define TASK_COUNTER 32
+#define TASK_SIGPENDING 8
+#define TASK_NEEDRESCHED 20
+#define TASK_THREAD 612
+#define TASK_MM 44
+#define TASK_ACTIVE_MM 80
+#define CPUSTAT_SOFTIRQ_PENDING 0
+#define CPUSTAT_LOCAL_IRQ_COUNT 4
+#define THREAD_KSP 0
+#define THREAD_USP 4
+#define THREAD_SR 8
+#define THREAD_FS 10
+#define THREAD_CRP 12
+#define THREAD_ESP0 20
+#define THREAD_FPREG 24
+#define THREAD_FPCNTL 120
+#define THREAD_FPSTATE 132
+#define PT_D0 32
+#define PT_ORIG_D0 36
+#define PT_D1 0
+#define PT_D2 4
+#define PT_D3 8
+#define PT_D4 12
+#define PT_D5 16
+#define PT_A0 20
+#define PT_A1 24
+#define PT_A2 28
+#define PT_PC 48
+#define PT_SR 46
+#define PT_VECTOR 52
+#define STAT_IRQ 5148
+#define SIGSEGV 11
+#define SEGV_MAPERR 196609
+#define SIGTRAP 5
+#define TRAP_TRACE 196610
+#define PT_PTRACED 1
+#define PT_TRACESYS 2
+#define PT_DTRACE 4
diff -urN linux-2.4.29/arch/m68knommu/platform/5282/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/5282/Makefile
--- linux-2.4.29/arch/m68knommu/platform/5282/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5282/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,50 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+#
+# re-use any 5307/coldfire files that we can.  Perhaps we should create
+# a coldfire directory for shared files ?
+#
+
+VPATH := $(VPATH):../5307
+
+ifdef CONFIG_FULLDEBUG
+	AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+#
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# AFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o ints.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
+
+entry.o: entry.S m68k_defs.h
+
+m68k_defs.h: ../../kernel/m68k_defs.c ../../kernel/m68k_defs.head
+	rm -f m68k_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/m68k_defs.c
+	cp ../../kernel/m68k_defs.head m68k_defs.h
+	grep '^#define' m68k_defs.s >> m68k_defs.h
+	rm m68k_defs.s
+-include m68k_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/platform/5282/MOTOROLA/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5282/MOTOROLA/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5282/MOTOROLA/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5282/MOTOROLA/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,204 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5282 ColdFire based MOTOROLA boards.
+ *
+ *	(C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com).
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Motorola M5282C3 ColdFire eval board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#if defined(CONFIG_RAM4MB)
+#define	MEM_SIZE	0x00400000	/* Memory size 4Mb */
+#elif defined(CONFIG_RAM16MB)
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+#else
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+	/*
+	 *	Set memory size.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Enable CPU internal cache (beware, early silicon 5282
+	 *	had a broken cache, you can't enable it on those parts).
+	 */
+	move.l	#0x01000000, %d0
+	movec	%d0, %CACR			/* Invalidate cache */
+	nop
+
+	move.l	#0x0000c000, %d0		/* Set SDRAM cached only */
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR1
+
+	move.l	#0x80400100, %d0		/* Instruction cache bits */
+	movec	%d0, %CACR			/* Enable cache */
+	nop
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5282/MOTOROLA/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5282/MOTOROLA/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5282/MOTOROLA/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5282/MOTOROLA/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,69 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x10000, LENGTH = 0x3e0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5282/NETBURNER/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5282/NETBURNER/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5282/NETBURNER/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5282/NETBURNER/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,192 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5282 ColdFire based Netburner 
+ *                    MOD5282 board.
+ *
+ *	(C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com).
+ *    
+ *      ported to Netburner MOD5282 -- Kevin Glavin (kg@telco21.com) Oct 2003
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Netburner MOD5282 board, chip select and memory setup.
+ */
+
+	
+#define	MEM_BASE	0x20000000 	/* Memory base is not address 0 */
+                                        /* it starts at 0x20000000, leaving 
+                                         * the first page empty to catch null  
+                                         * pointers
+                                         */ 
+
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#define	MEM_SIZE	0x027FFFFC	/* Memory size 8Mb  
+                                           - mod5282 only supports 8Mb */
+	
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+	/*
+	 *	Set memory size.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5282/NETBURNER/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5282/NETBURNER/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5282/NETBURNER/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5282/NETBURNER/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,70 @@
+/*    netburner mod5282 changes kg@telco21.com Oct 2003 */ 
+/*    memory starts at 0x02000000 ofor 0x7FFFFF bytes   */ 
+MEMORY {
+	ram    : ORIGIN = 0x02000000, LENGTH = 0x7FFFFF
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5282/Rules.make linux-2.4.29-uc1/arch/m68knommu/platform/5282/Rules.make
--- linux-2.4.29/arch/m68knommu/platform/5282/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5282/Rules.make	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,46 @@
+#
+# 5282/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1999-2003  Greg Ungerer (gerg@snapgear.com)
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uClinux.org>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+# Copyright (C) 2000  Lineo Inc. (www.lineo.com)
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+# Even though we're building for a 5282, we specify 5307 as our processor type.
+# The 5307 instruction set is the same as the 5282 (divide unit & MAC) plus
+# the 5282 instruction timings are closer to the 5307 than the other 5200
+# series processors (specifically the multiply and divide instructions which
+# are all this option really alters).
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/m5307/libgcc.a
+
+CFLAGS := -fno-builtin -nostdinc $(CFLAGS) -I$(INCGCC) -pipe -DNO_MM -DNO_FPU -m5307 -Wa,-S -Wa,-m5307 -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME=\"uClinux\" -D__linux__ -O1
+AFLAGS := $(CFLAGS)
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+            arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f arch/$(ARCH)/platform/$(PLATFORM)/m68k_defs.h
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5282/senTec/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5282/senTec/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5282/senTec/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5282/senTec/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,218 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for COBRA5282 ColdFire based senTec boards.
+ *
+ *	(C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com).
+ *
+ *    2004/03/01 Modified for senTec COBRA5282 board (W. Elsner)
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	COBRA5282 board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+
+#if defined(CONFIG_RAM32MB)
+#define MEM_SIZE        0x02000000      /* Memory size 32Mb */
+#elif defined(CONFIG_RAM16MB)
+#define MEM_SIZE        0x01000000      /* Memory size 16Mb */
+#elif defined(CONFIG_RAM8MB)
+#define MEM_SIZE        0x00800000      /* Memory size 8Mb */
+#else
+#define MEM_SIZE        0x00400000      /* Memory size 4Mb */
+#endif
+
+#define IPSBAR 0x40000000
+#define GPACR0 0x30
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+	/*
+	 *	Set memory size.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+#if 0
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0
+	movec	%d0, %CACR			/* Invalidate cache */
+	nop
+
+	move.l	#0x0000c000, %d0		/* Set SDRAM cached only */
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR1
+
+	move.l	#0x80400100, %d0		/* Instruction cache bits */
+	movec	%d0, %CACR			/* Enable cache */
+	nop
+#endif
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+   /*
+    * User mode port access
+    */
+   move.l   #0x0000000c, %d0
+   move.b   %d0, (IPSBAR+GPACR0)
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assembler start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5282/senTec/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5282/senTec/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5282/senTec/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5282/senTec/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,68 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x10000, LENGTH = 0x3e0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+		*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5282/SSV/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5282/SSV/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5282/SSV/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5282/SSV/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,204 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5282 ColdFire based DNP5282 boards.
+ *
+ *	(C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com).
+ *
+ *	2003/09/02 Modified for SSV DNP5282 board (H. Degenhardt)
+ *	           Send feedback for the DNP5282 to 
+ *	           M. Hasewinkel <support@ist1.de>
+ *
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	SSV DNP5282 ColdFire eval board, chip select and memory setup.
+ */
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+	/*
+	 *	Set memory size.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+#if 0
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0
+	movec	%d0, %CACR			/* Invalidate cache */
+	nop
+
+	move.l	#0x0000c000, %d0		/* Set SDRAM cached only */
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR1
+
+	move.l	#0x80400100, %d0		/* Instruction cache bits */
+	movec	%d0, %CACR			/* Enable cache */
+	nop
+#endif
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5282/SSV/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5282/SSV/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5282/SSV/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5282/SSV/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,69 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x10000, LENGTH = 0x3e0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		*(.modinfo)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sdata = . ;
+		__data_start = . ;
+        *(.data)
+		*(.data.exit)
+		. = ALIGN(8192) ;
+        *(.data.init_task)
+		. = ALIGN(8192) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/ARNEWSH/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5307/ARNEWSH/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5307/ARNEWSH/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/ARNEWSH/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,210 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5307 ColdFire Arnewsh board.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ * 	Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+#include "asm/nettel.h"
+
+/*****************************************************************************/
+
+/*
+ *	SnapGear NETtel board memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/* make region ROM cachable (turn off for flash programming?) */
+	/* 0xff000000 - 0xffffffff */
+#ifdef DEBUGGER_COMPATIBLE_CACHE
+	move.l	#(0xff<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WTHRU+ACR_WPROTECT, %d0
+#else
+	move.l	#(0xff<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WBACK+ACR_WPROTECT, %d0
+#endif
+	movec	%d0, %ACR0
+
+	/* make region RAM cachable *
+	/* 0x00000000 - 0x00ffffffff */
+#ifdef DEBUGGER_COMPATIBLE_CACHE
+	move.l	#(0x00<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WTHRU,%d0
+#else
+	move.l	#(0x00<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WBACK,%d0
+#endif
+	movec	%d0, %ACR1
+
+	/*
+	 *	Make the default cache mode precise.
+	 */
+	move.l	#CACR_EC+CACR_ESB+CACR_DCM_OFF_PRE, %d0	/* enable cache */
+	movec	%d0, %CACR
+	nop
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/ARNEWSH/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5307/ARNEWSH/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5307/ARNEWSH/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/ARNEWSH/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,65 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0x007E0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+			*(.rodata.str1.1)
+		. = ALIGN(0x4) ;
+			*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+			*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+			*(.text.init)
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		. = ALIGN(4) ;
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/bios32.c linux-2.4.29-uc1/arch/m68knommu/platform/5307/bios32.c
--- linux-2.4.29/arch/m68knommu/platform/5307/bios32.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/bios32.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,1172 @@
+/*****************************************************************************/
+
+/*
+ *	bios32.c -- PCI access code for embedded CO-MEM Lite PCI controller.
+ *
+ *	(C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com).
+ *	(C) Copyright 2000, Lineo (www.lineo.com)
+ */
+
+/*****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/irq.h>
+#include <asm/anchor.h>
+
+#ifdef CONFIG_eLIA
+#include <asm/elia.h>
+#endif
+
+/*****************************************************************************/
+#ifdef CONFIG_PCI
+/*****************************************************************************/
+
+/*
+ *	Debug configuration defines. DEBUGRES sets debugging output for
+ *	the resource allocation phase. DEBUGPCI traces on pcibios_ function
+ *	calls, and DEBUGIO traces all accesses to devices on the PCI bus.
+ */
+/*#define	DEBUGRES	1*/
+/*#define	DEBUGPCI	1*/
+/*#define	DEBUGIO		1*/
+
+/*****************************************************************************/
+
+/*
+ *	PCI markers for bus present and active slots.
+ */
+int		pci_bus_is_present = 0;
+unsigned long	pci_slotmask = 0;
+
+/*
+ *	We may or may not need to swap the bytes of PCI bus tranfers.
+ *	The endianess is re-roder automatically by the CO-MEM, but it
+ *	will get the wrong byte order for a pure data stream.
+ */
+#define	pci_byteswap	0
+
+
+/*
+ *	Resource tracking. The CO-MEM part creates a virtual address
+ *	space that all the PCI devices live in - it is not in any way
+ *	directly mapped into the ColdFire address space. So we can
+ *	really assign any resources we like to devices, as long as
+ *	they do not clash with other PCI devices.
+ */
+unsigned int	pci_iobase = PCIBIOS_MIN_IO;	/* Arbitary start address */
+unsigned int	pci_membase = PCIBIOS_MIN_MEM;	/* Arbitary start address */
+
+#define	PCI_MINIO	0x100			/* 256 byte minimum I/O */
+#define	PCI_MINMEM	0x00010000		/* 64k minimum chunk */
+
+/*
+ *	The CO-MEM's shared memory segment is visible inside the PCI
+ *	memory address space. We need to keep track of the address that
+ *	this is mapped at, to setup the bus masters pointers.
+ */
+unsigned int	pci_shmemaddr;
+
+/*****************************************************************************/
+
+void 		pci_interrupt(int irq, void *id, struct pt_regs *fp);
+
+/*****************************************************************************/
+
+/*
+ *	Some platforms have custom ways of reseting the PCI bus.
+ */
+
+void pci_resetbus(void)
+{
+#ifdef CONFIG_eLIA
+	int	i;
+
+#ifdef DEBUGPCI
+	printk("pci_resetbus()\n");
+#endif
+
+	*((volatile unsigned short *) (MCF_MBAR+MCFSIM_PADDR)) |= eLIA_PCIRESET;
+	for (i = 0; (i < 1000); i++) {
+		*((volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT)) = 
+			(ppdata | eLIA_PCIRESET);
+	}
+
+
+	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT)) = ppdata;
+#endif
+}
+
+/*****************************************************************************/
+
+int pcibios_assignres(int slot)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*ip;
+	unsigned int		idsel, addr, val, align, i;
+	int			bar;
+
+#ifdef DEBUGPCI
+	printk("pcibios_assignres(slot=%x)\n", slot);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	idsel = COMEM_DA_ADDR(0x1 << (slot + 16));
+
+	/* Try to assign resource to each BAR */
+	for (bar = 0; (bar < 6); bar++) {
+		addr = COMEM_PCIBUS + PCI_BASE_ADDRESS_0 + (bar * 4);
+		rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGRD | idsel;
+		val = rp[LREG(addr)];
+#ifdef DEBUGRES
+		printk("-----------------------------------"
+			"-------------------------------------\n");
+		printk("BAR[%d]: read=%08x ", bar, val);
+#endif
+
+		rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGWR | idsel;
+		rp[LREG(addr)] = 0xffffffff;
+
+		rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGRD | idsel;
+		val = rp[LREG(addr)];
+#ifdef DEBUGRES
+		printk("write=%08x ", val);
+#endif
+		if (val == 0) {
+#ifdef DEBUGRES
+			printk("\n");
+#endif
+			continue;
+		}
+
+		/* Determine space required by BAR */
+		/* FIXME: this should go backwords from 0x80000000... */
+		for (i = 0; (i < 32); i++) {
+			if ((0x1 << i) & (val & 0xfffffffc))
+				break;
+		}
+
+#ifdef DEBUGRES
+		printk("size=%08x(%d)\n", (0x1 << i), i);
+#endif
+		i = 0x1 << i;
+
+		/* Assign a resource */
+		if (val & PCI_BASE_ADDRESS_SPACE_IO) {
+			if (i < PCI_MINIO)
+				i = PCI_MINIO;
+#ifdef DEBUGRES
+			printk("BAR[%d]: IO size=%08x iobase=%08x\n",
+				bar, i, pci_iobase);
+#endif
+			if (i > 0xffff) {
+				/* Invalid size?? */
+				val = 0 | PCI_BASE_ADDRESS_SPACE_IO;
+#ifdef DEBUGRES
+				printk("BAR[%d]: too big for IO??\n", bar);
+#endif
+			} else {
+				/* Check for un-alignment */
+				if ((align = pci_iobase % i))
+					pci_iobase += (i - align);
+				val = pci_iobase | PCI_BASE_ADDRESS_SPACE_IO;
+				pci_iobase += i;
+			}
+		} else {
+			if (i < PCI_MINMEM)
+				i = PCI_MINMEM;
+#ifdef DEBUGRES
+			printk("BAR[%d]: MEMORY size=%08x membase=%08x\n",
+				bar, i, pci_membase);
+#endif
+			/* Check for un-alignment */
+			if ((align = pci_membase % i))
+				pci_membase += (i - align);
+			val = pci_membase | PCI_BASE_ADDRESS_SPACE_MEMORY;
+			pci_membase += i;
+		}
+
+		/* Write resource back into BAR register */
+		rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGWR | idsel;
+		rp[LREG(addr)] = val;
+#ifdef DEBUGRES
+		printk("BAR[%d]: assigned bar=%08x\n", bar, val);
+#endif
+	}
+
+#ifdef DEBUGRES
+	printk("-----------------------------------"
+			"-------------------------------------\n");
+#endif
+
+	/* Assign IRQ if one is wanted... */
+	ip = (volatile unsigned char *) (COMEM_BASE + COMEM_PCIBUS);
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGRD | idsel;
+
+	addr = (PCI_INTERRUPT_PIN & 0xfc) + (~PCI_INTERRUPT_PIN & 0x03);
+	if (ip[addr]) {
+		rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGWR | idsel;
+		addr = (PCI_INTERRUPT_LINE & 0xfc)+(~PCI_INTERRUPT_LINE & 0x03);
+		ip[addr] = 25;
+#ifdef DEBUGRES
+		printk("IRQ LINE=25\n");
+#endif
+	}
+
+	return(0);
+}
+
+/*****************************************************************************/
+
+int pcibios_enable(int slot)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*wp;
+	unsigned int		idsel, addr;
+	unsigned short		cmd;
+
+#ifdef DEBUGPCI
+	printk("pcibios_enbale(slot=%x)\n", slot);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	wp = (volatile unsigned short *) COMEM_BASE;
+	idsel = COMEM_DA_ADDR(0x1 << (slot + 16));
+
+	/* Get current command settings */
+	addr = COMEM_PCIBUS + PCI_COMMAND;
+	addr = (addr & ~0x3) + (~addr & 0x02);
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGRD | idsel;
+	cmd = wp[WREG(addr)];
+	/*val = ((val & 0xff) << 8) | ((val >> 8) & 0xff);*/
+
+	/* Enable I/O and memory accesses to this device */
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGWR | idsel;
+	cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+	wp[WREG(addr)] = cmd;
+
+	return(0);
+}
+
+/*****************************************************************************/
+
+void pcibios_init(void)
+{
+	volatile unsigned long	*rp;
+	unsigned long		sel, id;
+	int			slot;
+
+#ifdef DEBUGPCI
+	printk("pcibios_init()\n");
+#endif
+
+	pci_resetbus();
+
+	/*
+	 *	Do some sort of basic check to see if the CO-MEM part
+	 *	is present... This works ok, but I think we really need
+	 *	something better...
+	 */
+	rp = (volatile unsigned long *) COMEM_BASE;
+	if ((rp[LREG(COMEM_LBUSCFG)] & 0xff) != 0x50) {
+		printk("PCI: no PCI bus present\n");
+		return;
+	}
+
+#ifdef COMEM_BRIDGEDEV
+	/*
+	 *	Setup the PCI bridge device first. It needs resources too,
+	 *	so that bus masters can get to its shared memory.
+	 */
+	slot = COMEM_BRIDGEDEV;
+	sel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << (slot + 16));
+	rp[LREG(COMEM_DAHBASE)] = sel;
+	rp[LREG(COMEM_PCIBUS)] = 0; /* Clear bus */
+	id = rp[LREG(COMEM_PCIBUS)];
+	if ((id == 0) || ((id & 0xffff0000) == (sel & 0xffff0000))) {
+		printk("PCI: no PCI bus bridge present\n");
+		return;
+	}
+
+	printk("PCI: bridge device at slot=%d id=%08x\n", slot, (int) id);
+	pci_slotmask |= 0x1 << slot;
+	pci_shmemaddr = pci_membase;
+	pcibios_assignres(slot);
+	pcibios_enable(slot);
+#endif
+
+	pci_bus_is_present = 1;
+
+	/*
+	 *	Do a quick scan of the PCI bus and see what is here.
+	 */
+	for (slot = COMEM_MINDEV; (slot <= COMEM_MAXDEV); slot++) {
+		sel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << (slot + 16));
+		rp[LREG(COMEM_DAHBASE)] = sel;
+		rp[LREG(COMEM_PCIBUS)] = 0; /* Clear bus */
+		id = rp[LREG(COMEM_PCIBUS)];
+		if ((id != 0) && ((id & 0xffff0000) != (sel & 0xffff0000))) {
+			printk("PCI: slot=%d id=%08x\n", slot, (int) id);
+			pci_slotmask |= 0x1 << slot;
+			pcibios_assignres(slot);
+			pcibios_enable(slot);
+		}
+	}
+
+	/* Get PCI irq for local vectoring */
+	if (request_irq(COMEM_IRQ, pci_interrupt, 0, "PCI bridge", NULL)) {
+		printk("PCI: failed to acquire interrupt %d\n", COMEM_IRQ);
+	} else {
+		mcf_autovector(COMEM_IRQ);
+	}
+}
+
+/*****************************************************************************/
+
+unsigned long pcibios_fixup(unsigned long mem_start, unsigned long mem_end)
+{
+	return(mem_start);
+}
+
+/*****************************************************************************/
+
+int pcibios_present(void)
+{
+	return(pci_bus_is_present);
+}
+
+/*****************************************************************************/
+
+int pcibios_read_config_dword(unsigned char bus, unsigned char dev,
+	unsigned char offset, unsigned int *val)
+{
+	volatile unsigned long	*rp;
+	unsigned long		idsel, fnsel;
+
+#ifdef DEBUGPCI
+	printk("pcibios_read_config_dword(bus=%x,dev=%x,offset=%x,val=%x)\n",
+		 bus, dev, offset, val);
+#endif
+
+	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0)) {
+		*val = 0xffffffff;
+		return(PCIBIOS_SUCCESSFUL);
+	}
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
+	fnsel = (dev & 0x7) << 8;
+
+	rp[LREG(COMEM_DAHBASE)] = idsel;
+	*val = rp[LREG(COMEM_PCIBUS + (offset & 0xfc) + fnsel)];
+
+#if 1
+	/* If we get back what we wrote, then nothing there */
+	/* This is pretty dodgy, but, hey, what else do we do?? */
+	if (!offset && (*val == ((idsel & 0xfffff000) | (offset & 0x00000fff))))
+		*val = 0xffffffff;
+#endif
+
+	return(PCIBIOS_SUCCESSFUL);
+}
+
+/*****************************************************************************/
+
+int pcibios_read_config_word(unsigned char bus, unsigned char dev,
+	unsigned char offset, unsigned short *val)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*bp;
+	unsigned long		idsel, fnsel;
+	unsigned char		swapoffset;
+
+#ifdef DEBUGPCI
+	printk("pcibios_read_config_word(bus=%x,dev=%x,offset=%x)\n",
+		bus, dev, offset);
+#endif
+
+	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0)) {
+		*val = 0xffff;
+		return(PCIBIOS_SUCCESSFUL);
+	}
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	bp = (volatile unsigned short *) COMEM_BASE;
+	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
+	fnsel = (dev & 0x7) << 8;
+	swapoffset = (offset & 0xfc) + (~offset & 0x02);
+
+	rp[LREG(COMEM_DAHBASE)] = idsel;
+	*val = bp[WREG(COMEM_PCIBUS + swapoffset + fnsel)];
+
+	return(PCIBIOS_SUCCESSFUL);
+}
+
+/*****************************************************************************/
+
+int pcibios_read_config_byte(unsigned char bus, unsigned char dev,
+	unsigned char offset, unsigned char *val)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*bp;
+	unsigned long		idsel, fnsel;
+	unsigned char		swapoffset;
+
+#ifdef DEBUGPCI
+	printk("pcibios_read_config_byte(bus=%x,dev=%x,offset=%x)\n",
+		bus, dev, offset);
+#endif
+
+	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0)) {
+		*val = 0xff;
+		return(PCIBIOS_SUCCESSFUL);
+	}
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	bp = (volatile unsigned char *) COMEM_BASE;
+	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
+	fnsel = (dev & 0x7) << 8;
+	swapoffset = (offset & 0xfc) + (~offset & 0x03);
+
+	rp[LREG(COMEM_DAHBASE)] = idsel;
+	*val = bp[(COMEM_PCIBUS + swapoffset + fnsel)];
+
+	return(PCIBIOS_SUCCESSFUL);
+}
+
+/*****************************************************************************/
+
+int pcibios_write_config_dword(unsigned char bus, unsigned char dev,
+	unsigned char offset, unsigned int val)
+{
+	volatile unsigned long	*rp;
+	unsigned long		idsel, fnsel;
+
+#ifdef DEBUGPCI
+	printk("pcibios_write_config_dword(bus=%x,dev=%x,offset=%x,val=%x)\n",
+		 bus, dev, offset, val);
+#endif
+
+	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0))
+		return(PCIBIOS_SUCCESSFUL);
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
+	fnsel = (dev & 0x7) << 8;
+
+	rp[LREG(COMEM_DAHBASE)] = idsel;
+	rp[LREG(COMEM_PCIBUS + (offset & 0xfc) + fnsel)] = val;
+	return(PCIBIOS_SUCCESSFUL);
+}
+
+/*****************************************************************************/
+
+int pcibios_write_config_word(unsigned char bus, unsigned char dev,
+	unsigned char offset, unsigned short val)
+{
+
+	volatile unsigned long	*rp;
+	volatile unsigned short	*bp;
+	unsigned long		idsel, fnsel;
+	unsigned char		swapoffset;
+
+#ifdef DEBUGPCI
+	printk("pcibios_write_config_word(bus=%x,dev=%x,offset=%x,val=%x)\n",
+		 bus, dev, offset, val);
+#endif
+
+	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0))
+		return(PCIBIOS_SUCCESSFUL);
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	bp = (volatile unsigned short *) COMEM_BASE;
+	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
+	fnsel = (dev & 0x7) << 8;
+	swapoffset = (offset & 0xfc) + (~offset & 0x02);
+
+	rp[LREG(COMEM_DAHBASE)] = idsel;
+	bp[WREG(COMEM_PCIBUS + swapoffset + fnsel)] = val;
+	return(PCIBIOS_SUCCESSFUL);
+}
+
+/*****************************************************************************/
+
+int pcibios_write_config_byte(unsigned char bus, unsigned char dev,
+	unsigned char offset, unsigned char val)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*bp;
+	unsigned long		idsel, fnsel;
+	unsigned char		swapoffset;
+
+#ifdef DEBUGPCI
+	printk("pcibios_write_config_byte(bus=%x,dev=%x,offset=%x,val=%x)\n",
+		 bus, dev, offset, val);
+#endif
+
+	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0))
+		return(PCIBIOS_SUCCESSFUL);
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	bp = (volatile unsigned char *) COMEM_BASE;
+	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
+	fnsel = (dev & 0x7) << 8;
+	swapoffset = (offset & 0xfc) + (~offset & 0x03);
+
+	rp[LREG(COMEM_DAHBASE)] = idsel;
+	bp[(COMEM_PCIBUS + swapoffset + fnsel)] = val;
+	return(PCIBIOS_SUCCESSFUL);
+}
+
+/*****************************************************************************/
+
+int pcibios_find_device(unsigned short vendor, unsigned short devid,
+	unsigned short index, unsigned char *bus, unsigned char *dev)
+{
+	unsigned int	vendev, val;
+	unsigned char	devnr;
+
+#ifdef DEBUGPCI
+	printk("pcibios_find_device(vendor=%04x,devid=%04x,index=%d)\n",
+		vendor, devid, index);
+#endif
+
+	if (vendor == 0xffff)
+		return(PCIBIOS_BAD_VENDOR_ID);
+
+	vendev = (devid << 16) | vendor;
+	for (devnr = 0; (devnr < 32); devnr++) {
+		pcibios_read_config_dword(0, devnr, PCI_VENDOR_ID, &val);
+		if (vendev == val) {
+			if (index-- == 0) {
+				*bus = 0;
+				*dev = devnr;
+				return(PCIBIOS_SUCCESSFUL);
+			}
+		}
+	}
+
+	return(PCIBIOS_DEVICE_NOT_FOUND);
+}
+
+/*****************************************************************************/
+
+int pcibios_find_class(unsigned int class, unsigned short index,
+	unsigned char *bus, unsigned char *dev)
+{
+	unsigned int	val;
+	unsigned char	devnr;
+
+#ifdef DEBUGPCI
+	printk("pcibios_find_class(class=%04x,index=%d)\n", class, index);
+#endif
+
+	/* FIXME: this ignores multi-function devices... */
+	for (devnr = 0; (devnr < 128); devnr += 8) {
+		pcibios_read_config_dword(0, devnr, PCI_CLASS_REVISION, &val);
+		if ((val >> 8) == class) {
+			if (index-- == 0) {
+				*bus = 0;
+				*dev = devnr;
+				return(PCIBIOS_SUCCESSFUL);
+			}
+		}
+	}
+
+	return(PCIBIOS_DEVICE_NOT_FOUND);
+}
+
+/*****************************************************************************/
+
+/*
+ *	Local routines to interrcept the standard I/O and vector handling
+ *	code. Don't include this 'till now - initialization code above needs
+ *	access to the real code too.
+ */
+#include <asm/mcfpci.h>
+
+/*****************************************************************************/
+
+void pci_outb(unsigned char val, unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*bp;
+
+#ifdef DEBUGIO
+	printk("pci_outb(val=%02x,addr=%x)\n", val, addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	bp = (volatile unsigned char *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(addr);
+	addr = (addr & ~0x3) + (~addr & 0x03);
+	bp[(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))] = val;
+}
+
+/*****************************************************************************/
+
+void pci_outw(unsigned short val, unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*sp;
+
+#ifdef DEBUGIO
+	printk("pci_outw(val=%04x,addr=%x)", val, addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	sp = (volatile unsigned short *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(addr);
+	addr = (addr & ~0x3) + (~addr & 0x02);
+	if (pci_byteswap)
+		val = ((val & 0xff) << 8) | ((val >> 8) & 0xff);
+	sp[WREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))] = val;
+}
+
+/*****************************************************************************/
+
+void pci_outl(unsigned int val, unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned int	*lp;
+
+#ifdef DEBUGIO
+	printk("pci_outl(val=%08x,addr=%x)\n", val, addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	lp = (volatile unsigned int *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(addr);
+
+	if (pci_byteswap)
+		val = (val << 24) | ((val & 0x0000ff00) << 8) |
+			((val & 0x00ff0000) >> 8) | (val >> 24);
+
+	lp[LREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))] = val;
+}
+
+/*****************************************************************************/
+
+unsigned long	pci_blmask[] = {
+	0x000000e0,
+	0x000000d0,
+	0x000000b0,
+	0x00000070
+};
+
+unsigned char pci_inb(unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*bp;
+	unsigned long		r;
+	unsigned char		val;
+
+#ifdef DEBUGIO
+	printk("pci_inb(addr=%x)", addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	bp = (volatile unsigned char *) COMEM_BASE;
+
+	r = COMEM_DA_IORD | COMEM_DA_ADDR(addr) | pci_blmask[(addr & 0x3)];
+	rp[LREG(COMEM_DAHBASE)] = r;
+
+	addr = (addr & ~0x3) + (~addr & 0x3);
+	val = bp[(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))];
+	return(val);
+}
+
+/*****************************************************************************/
+
+unsigned long	pci_bwmask[] = {
+	0x000000c0,
+	0x000000c0,
+	0x00000030,
+	0x00000030
+};
+
+unsigned short pci_inw(unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*sp;
+	unsigned long		r;
+	unsigned short		val;
+
+#ifdef DEBUGIO
+	printk("pci_inw(addr=%x)", addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	r = COMEM_DA_IORD | COMEM_DA_ADDR(addr) | pci_bwmask[(addr & 0x3)];
+	rp[LREG(COMEM_DAHBASE)] = r;
+
+	sp = (volatile unsigned short *) COMEM_BASE;
+	addr = (addr & ~0x3) + (~addr & 0x02);
+	val = sp[WREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))];
+	if (pci_byteswap)
+		val = ((val & 0xff) << 8) | ((val >> 8) & 0xff);
+#ifdef DEBUGIO
+	printk("=%04x\n", val);
+#endif
+	return(val);
+}
+
+/*****************************************************************************/
+
+unsigned int pci_inl(unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned int	*lp;
+	unsigned int		val;
+
+#ifdef DEBUGIO
+	printk("pci_inl(addr=%x)", addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	lp = (volatile unsigned int *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(addr);
+	val = lp[LREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))];
+
+	if (pci_byteswap)
+		val = (val << 24) | ((val & 0x0000ff00) << 8) |
+			((val & 0x00ff0000) >> 8) | (val >> 24);
+
+#ifdef DEBUGIO
+	printk("=%08x\n", val);
+#endif
+	return(val);
+}
+
+/*****************************************************************************/
+
+void pci_outsb(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*bp;
+	unsigned char		*dp = (unsigned char *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk("pci_outsb(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(a);
+
+	a = (a & ~0x3) + (~a & 0x03);
+	bp = (volatile unsigned char *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--)
+		*bp = *dp++;
+}
+
+/*****************************************************************************/
+
+void pci_outsw(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*wp;
+	unsigned short		w, *dp = (unsigned short *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk("pci_outsw(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(a);
+
+	a = (a & ~0x3) + (~a & 0x2);
+	wp = (volatile unsigned short *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--) {
+		w = *dp++;
+		if (pci_byteswap)
+			w = ((w & 0xff) << 8) | ((w >> 8) & 0xff);
+		*wp = w;
+	}
+}
+
+/*****************************************************************************/
+
+void pci_outsl(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned long	*lp;
+	unsigned long		l, *dp = (unsigned long *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk("pci_outsl(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(a);
+
+	lp = (volatile unsigned long *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--) {
+		l = *dp++;
+		if (pci_byteswap)
+			l = (l << 24) | ((l & 0x0000ff00) << 8) |
+				((l & 0x00ff0000) >> 8) | (l >> 24);
+		*lp = l;
+	}
+}
+
+/*****************************************************************************/
+
+void pci_insb(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*bp;
+	unsigned char		*dp = (unsigned char *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk("pci_insb(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(a);
+
+	a = (a & ~0x3) + (~a & 0x03);
+	bp = (volatile unsigned char *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--)
+		*dp++ = *bp;
+}
+
+/*****************************************************************************/
+
+void pci_insw(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*wp;
+	unsigned short		w, *dp = (unsigned short *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk("pci_insw(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(a);
+
+	a = (a & ~0x3) + (~a & 0x2);
+	wp = (volatile unsigned short *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--) {
+		w = *wp;
+		if (pci_byteswap)
+			w = ((w & 0xff) << 8) | ((w >> 8) & 0xff);
+		*dp++ = w;
+	}
+}
+
+/*****************************************************************************/
+
+void pci_insl(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned long	*lp;
+	unsigned long		l, *dp = (unsigned long *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk("pci_insl(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(a);
+
+	lp = (volatile unsigned long *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--) {
+		l = *lp;
+		if (pci_byteswap)
+			l = (l << 24) | ((l & 0x0000ff00) << 8) |
+				((l & 0x00ff0000) >> 8) | (l >> 24);
+		*dp++ = l;
+	}
+}
+
+/*****************************************************************************/
+
+struct pci_localirqlist {
+	void		(*handler)(int, void *, struct pt_regs *);
+	const char	*device;
+	void		*dev_id;
+};
+
+struct pci_localirqlist	pci_irqlist[COMEM_MAXPCI];
+
+/*****************************************************************************/
+
+int pci_request_irq(unsigned int irq,
+	void (*handler)(int, void *, struct pt_regs *),
+	unsigned long flags, const char *device, void *dev_id)
+{
+	int	i;
+
+#ifdef DEBUGIO
+	printk("pci_request_irq(irq=%d,handler=%x,flags=%x,device=%s,"
+		"dev_id=%x)\n", irq, (int) handler, (int) flags, device,
+		(int) dev_id);
+#endif
+
+	/* Check if this interrupt handler is already lodged */
+	for (i = 0; (i < COMEM_MAXPCI); i++) {
+		if (pci_irqlist[i].handler == handler)
+			return(0);
+	}
+
+	/* Find a free spot to put this handler */
+	for (i = 0; (i < COMEM_MAXPCI); i++) {
+		if (pci_irqlist[i].handler == 0) {
+			pci_irqlist[i].handler = handler;
+			pci_irqlist[i].device = device;
+			pci_irqlist[i].dev_id = dev_id;
+			return(0);
+		}
+	}
+
+	/* Couldn't fit?? */
+	return(1);
+}
+
+/*****************************************************************************/
+
+void pci_free_irq(unsigned int irq, void *dev_id)
+{
+	int	i;
+
+#ifdef DEBUGIO
+	printk("pci_free_irq(irq=%d,dev_id=%x)\n", irq, (int) dev_id);
+#endif
+
+	if (dev_id == (void *) NULL)
+		return;
+
+	/* Check if this interrupt handler is lodged */
+	for (i = 0; (i < COMEM_MAXPCI); i++) {
+		if (pci_irqlist[i].dev_id == dev_id) {
+			pci_irqlist[i].handler = NULL;
+			pci_irqlist[i].device = NULL;
+			pci_irqlist[i].dev_id = NULL;
+			break;
+		}
+	}
+}
+
+/*****************************************************************************/
+
+void pci_interrupt(int irq, void *id, struct pt_regs *fp)
+{
+	int	i;
+
+#ifdef DEBUGIO
+	printk("pci_interrupt(irq=%d,id=%x,fp=%x)\n", irq, (int) id, (int) fp);
+#endif
+
+	for (i = 0; (i < COMEM_MAXPCI); i++) {
+		if (pci_irqlist[i].handler)
+			(*pci_irqlist[i].handler)(irq,pci_irqlist[i].dev_id,fp);
+	}
+}
+
+/*****************************************************************************/
+
+/*
+ *	The shared memory region is broken up into contiguous 512 byte
+ *	regions for easy allocation... This is not an optimal solution
+ *	but it makes allocation and freeing regions really easy.
+ */
+
+#define	PCI_MEMSLOTSIZE		512
+#define	PCI_MEMSLOTS		(COMEM_SHMEMSIZE / PCI_MEMSLOTSIZE)
+
+char	pci_shmemmap[PCI_MEMSLOTS];
+
+
+void *pci_bmalloc(int size)
+{
+	int	i, j, nrslots;
+
+#ifdef DEBUGIO
+	printk("pci_bmalloc(size=%d)\n", size);
+#endif
+
+	if (size <= 0)
+		return((void *) NULL);
+
+	nrslots = (size - 1) / PCI_MEMSLOTSIZE;
+
+	for (i = 0; (i < (PCI_MEMSLOTS-nrslots)); i++) {
+		if (pci_shmemmap[i] == 0) {
+			for (j = i+1; (j < (i+nrslots)); j++) {
+				if (pci_shmemmap[j])
+					goto restart;
+			}
+
+			for (j = i; (j <= i+nrslots); j++)
+				pci_shmemmap[j] = 1;
+			break;
+		}
+restart:
+	}
+
+	return((void *) (COMEM_BASE + COMEM_SHMEM + (i * PCI_MEMSLOTSIZE)));
+}
+
+/*****************************************************************************/
+
+void pci_bmfree(void *mp, int size)
+{
+	int	i, j, nrslots;
+
+#ifdef DEBUGIO
+	printk("pci_bmfree(mp=%x,size=%d)\n", (int) mp, size);
+#endif
+
+	nrslots = size / PCI_MEMSLOTSIZE;
+	i = (((unsigned long) mp) - (COMEM_BASE + COMEM_SHMEM)) /
+		PCI_MEMSLOTSIZE;
+
+	for (j = i; (j < (i+nrslots)); j++)
+		pci_shmemmap[j] = 0;
+}
+
+/*****************************************************************************/
+
+unsigned long pci_virt_to_bus(volatile void *address)
+{
+	unsigned long	l;
+
+#ifdef DEBUGIO
+	printk("pci_virt_to_bus(address=%x)", (int) address);
+#endif
+
+	l = ((unsigned long) address) - COMEM_BASE;
+#ifdef DEBUGIO
+	printk("=%x\n", (int) (l+pci_shmemaddr));
+#endif
+	return(l + pci_shmemaddr);
+}
+
+/*****************************************************************************/
+
+void *pci_bus_to_virt(unsigned long address)
+{
+	unsigned long	l;
+
+#ifdef DEBUGIO
+	printk("pci_bus_to_virt(address=%x)", (int) address);
+#endif
+
+	l = address - pci_shmemaddr;
+#ifdef DEBUGIO
+	printk("=%x\n", (int) (address + COMEM_BASE));
+#endif
+	return((void *) (address + COMEM_BASE));
+}
+
+/*****************************************************************************/
+
+void pci_bmcpyto(void *dst, void *src, int len)
+{
+	unsigned long	*dp, *sp, val;
+	unsigned char	*dcp, *scp;
+	int		i, j;
+
+#ifdef DEBUGIO
+	printk("pci_bmcpyto(dst=%x,src=%x,len=%d)\n", (int)dst, (int)src, len);
+#endif
+
+	dp = (unsigned long *) dst;
+	sp = (unsigned long *) src;
+	i = len >> 2;
+
+#if 0
+	printk("DATA:");
+	scp = (unsigned char *) sp;
+	for (i = 0; (i < len); i++) {
+		if ((i % 16) == 0) printk("\n%04x: ", i);
+		printk("%02x ", *scp++);
+	}
+	printk("\n");
+#endif
+
+	for (j = 0; (i >= 0); i--, j++) {
+		val = *sp++;
+		val = (val << 24) | ((val & 0x0000ff00) << 8) |
+			((val & 0x00ff0000) >> 8) | (val >> 24);
+		*dp++ = val;
+	}
+
+	if (len & 0x3) {
+		dcp = (unsigned char *) dp;
+		scp = ((unsigned char *) sp) + 3;
+		for (i = 0; (i < (len & 0x3)); i++)
+			*dcp++ = *scp--;
+	}
+}
+
+/*****************************************************************************/
+
+void pci_bmcpyfrom(void *dst, void *src, int len)
+{
+	unsigned long	*dp, *sp, val;
+	unsigned char	*dcp, *scp;
+	int		i;
+
+#ifdef DEBUGIO
+	printk("pci_bmcpyfrom(dst=%x,src=%x,len=%d)\n",(int)dst,(int)src,len);
+#endif
+
+	dp = (unsigned long *) dst;
+	sp = (unsigned long *) src;
+	i = len >> 2;
+
+	for (; (i >= 0); i--) {
+		val = *sp++;
+		val = (val << 24) | ((val & 0x0000ff00) << 8) |
+			((val & 0x00ff0000) >> 8) | (val >> 24);
+		*dp++ = val;
+	}
+
+	if (len & 0x3) {
+		dcp = ((unsigned char *) dp) + 3;
+		scp = (unsigned char *) sp;
+		for (i = 0; (i < (len & 0x3)); i++)
+			*dcp++ = *scp--;
+	}
+
+#if 0
+	printk("DATA:");
+	dcp = (unsigned char *) dst;
+	for (i = 0; (i < len); i++) {
+		if ((i % 16) == 0) printk("\n%04x: ", i);
+		printk("%02x ", *dcp++);
+	}
+	printk("\n");
+#endif
+}
+
+/*****************************************************************************/
+#endif	/* CONFIG_PCI */
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/CLEOPATRA/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5307/CLEOPATRA/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5307/CLEOPATRA/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/CLEOPATRA/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,214 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for Feith CLEOPATRA board.
+ *
+ *	(C) Copyright 2001, Roman Wagner.
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Feith CLEOPATRA board, chip select and memory setup.
+*/
+
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#if defined(CONFIG_RAM16MB)
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+#else
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+/*
+ * The current version of the 5307 processor
+ * SWT does not work. Probing invalid addresses
+ * will hang the system.
+ *
+ * For now, set the memory size to 8 meg
+ */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* invalidate whole cache */
+	movec	%d0,%CACR
+	nop
+#ifdef DEBUGGER_COMPATIBLE_CACHE
+	move.l	#0x0000c000, %d0		/* Set SDRAM cached only */
+#else
+	move.l	#0x0000c020, %d0		/* Set SDRAM cached only (copyback) */
+#endif
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR1
+
+	/* Enable cache */
+	move.l	#0xa0000200, %d0
+	movec	%d0,%CACR
+	nop
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 * load the current task pointer and stack
+	 */
+	lea		init_task_union,%a0
+	movel	%a0, _current_task
+	lea		0x2000(%a0),%sp
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/CLEOPATRA/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5307/CLEOPATRA/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5307/CLEOPATRA/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/CLEOPATRA/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,65 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x400, LENGTH = 0x1000000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+			*(.rodata.str1.1)
+		. = ALIGN(0x4) ;
+			*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+			*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+			*(.text.init)
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = . ;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/config.c linux-2.4.29-uc1/arch/m68knommu/platform/5307/config.c
--- linux-2.4.29/arch/m68knommu/platform/5307/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/config.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,440 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/5307/config.c
+ *
+ *	Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *	Copyright (C) 2000, Lineo (www.lineo.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <linux/ledman.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcftimer.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+#include <asm/delay.h>
+
+#if defined(CONFIG_eLIA)
+#include <asm/elia.h>
+#endif
+
+#include <asm/mcfwdebug.h>
+
+/***************************************************************************/
+
+void	reset_setupbutton(void);
+void	coldfire_profile_init(void);
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int   dma_base_addr[MAX_DMA_CHANNELS] = {
+        MCF_MBAR + MCFDMA_BASE0,
+        MCF_MBAR + MCFDMA_BASE1,
+        MCF_MBAR + MCFDMA_BASE2,
+        MCF_MBAR + MCFDMA_BASE3,
+};
+
+unsigned int dma_device_address[MAX_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned char	*icrp;
+
+	/* Set up TIMER 1 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_CLK / 16) / HZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_TIMER1ICR);
+
+#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
+    defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \
+    defined(CONFIG_CLEOPATRA) 
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3;
+	request_irq(30, handler, SA_INTERRUPT, "ColdFire Timer", timerp);
+#else
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI3;
+	request_irq(29, handler, SA_INTERRUPT, "ColdFire Timer", timerp);
+#endif
+
+#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
+    defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3)
+	/* This is not really the right place to do this... */
+	reset_setupbutton();
+#endif
+#ifdef CONFIG_HIGHPROFILE
+	coldfire_profile_init();
+#endif
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_TIMER1);
+}
+
+/***************************************************************************/
+
+unsigned long coldfire_timer_offset(void)
+{
+	volatile unsigned short *timerp;
+	unsigned long		trr, tcn, offset;
+
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE1);
+	tcn = timerp[MCFTIMER_TCN];
+	trr = timerp[MCFTIMER_TRR];
+
+	/*
+	 * If we are still in the first half of the upcount and a
+	 * timer interupt is pending, then add on a ticks worth of time.
+	 */
+	offset = ((tcn * (1000000 / HZ)) / trr);
+	if (((offset * 2) < (1000000 / HZ)) && (mcf_getipr() & MCFSIM_IMR_TIMER1))
+		offset += 1000000 / HZ;
+	return offset;	
+}
+
+/***************************************************************************/
+#ifdef CONFIG_HIGHPROFILE
+/***************************************************************************/
+
+#define	PROFILEHZ	1013
+
+/*
+ *	Use the other timer to provide high accuracy profiling info.
+ */
+
+void coldfire_profile_tick(int irq, void *dummy, struct pt_regs *regs)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer2 */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE2);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+
+        if (!user_mode(regs)) {
+                if (prof_buffer && current->pid) {
+                        extern int _stext;
+                        unsigned long ip = instruction_pointer(regs);
+                        ip -= (unsigned long) &_stext;
+                        ip >>= prof_shift;
+                        if (ip < prof_len)
+                                prof_buffer[ip]++;
+                }
+        }
+}
+
+void coldfire_profile_init(void)
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned char	*icrp;
+
+	printk("PROFILE: lodging timer2=%d as profile timer\n", PROFILEHZ);
+
+	/* Set up TIMER 2 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE2);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_CLK / 16) / PROFILEHZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_TIMER2ICR);
+
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3;
+	request_irq(31, coldfire_profile_tick, (SA_INTERRUPT | IRQ_FLG_FAST),
+		"Profile Timer", timerp);
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_TIMER2);
+}
+
+/***************************************************************************/
+#endif	/* CONFIG_HIGHPROFILE */
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	volatile unsigned char  *mbar;
+
+	if ((vec >= 25) && (vec <= 31)) {
+		mbar = (volatile unsigned char *) MCF_MBAR;
+		vec = 0x1 << (vec - 24);
+		*(mbar + MCFSIM_AVR) |= vec;
+		mcf_setimr(mcf_getimr() & ~vec);
+	}
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+#ifdef TRAP_DBG_INTERRUPT
+asmlinkage void dbginterrupt(void);
+#endif
+
+void __init coldfire_trap_init(void)
+{
+	int i;
+
+#ifndef ENABLE_dBUG
+	mcf_setimr(MCFSIM_IMR_MASKALL);
+#endif
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+	for (i = 33; (i <= 63); i++)
+		_ramvec[i] = trap;
+#endif
+#ifdef TRAP_DBG_INTERRUPT
+	_ramvec[12] = dbginterrupt;
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+
+#ifdef CONFIG_BDM_DISABLE
+	/* Disable the BDM clocking.  This also turns off most of the rest of
+	 * the BDM device.  This is good for EMC reasons.  This option is not
+	 * incompatible with the memory protection option.
+	 */
+	wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
+#endif
+}
+
+/***************************************************************************/
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+
+void dump(struct pt_regs *fp)
+{
+	extern unsigned int sw_usp, sw_ksp;
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+#ifdef CONFIG_DUMPTOFLASH
+	extern unsigned long	sys_getlog(char **bp);
+	extern void		sys_resetlog(void);
+	extern void		flash_erasedump(void);
+	extern void		flash_writedump(char *buf, int len);
+	flash_erasedump();
+	sys_resetlog();
+#endif
+
+	printk("\nCURRENT PROCESS:\n\n");
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+
+#if defined(CONFIG_WATCHDOG) && defined(CONFIG_OLDMASK)
+{
+	extern int	swt_inwatchdog;
+	if (swt_inwatchdog) {
+		extern int	swt_lastjiffies, swt_reference;
+		printk("WATCHDOG: ref=%d diff=%d jiffies=%d lastjiffies=%d\n\n",
+			swt_reference, ((int) (jiffies - swt_lastjiffies)),
+			((int) jiffies), swt_lastjiffies);
+	}
+}
+#endif
+
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
+			(int) current->mm->start_stack,
+			(int) (((unsigned long) current) + 2 * PAGE_SIZE));
+	}
+
+	printk("PC: %08lx\n", fp->pc);
+	printk("SR: %08lx    SP: %08lx\n", (long) fp->sr, (long) fp);
+	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+		fp->d0, fp->d1, fp->d2, fp->d3);
+	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+		fp->d4, fp->d5, fp->a0, fp->a1);
+	printk("\nUSP: %08x   KSP: %08x   TRAPFRAME: %08x\n",
+		sw_usp, sw_ksp, (unsigned int) fp);
+
+	printk("\nCODE:");
+	tp = ((unsigned char *) fp->pc) - 0x20;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nUSER STACK:");
+	tp = (unsigned char *) (sw_usp - 0x10);
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n\n");
+
+#ifdef CONFIG_DUMPTOFLASH
+	i = sys_getlog((char **) &tp);
+	flash_writedump(tp, i);
+#endif
+}
+
+/***************************************************************************/
+
+#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
+    defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3)
+static struct timer_list    resetbutton_timerlist;
+
+/*
+ *	Routines to support the NETtel software reset button.
+ */
+static void resetbutton_poll(unsigned long arg)
+{
+    static int inbutton = 0;
+    if ((mcf_getipr() & MCFSIM_IMR_EINT7) != 0) {
+        if (!inbutton) {
+            inbutton = 1;
+#ifdef CONFIG_LEDMAN
+            ledman_signalreset();
+#else 
+			HARD_RESET_NOW();
+			/* Should never get here... */
+#endif
+        }
+    } else
+        inbutton = 0;
+
+	resetbutton_timerlist.expires = jiffies + 5;
+    add_timer(&resetbutton_timerlist);
+}
+
+/***************************************************************************/
+
+void reset_setupbutton(void)
+{
+	resetbutton_timerlist.expires = jiffies + 5;
+    resetbutton_timerlist.function = resetbutton_poll;
+    resetbutton_timerlist.data = 0;
+    add_timer(&resetbutton_timerlist);
+}
+
+#endif /* CONFIG_NETtel || CONFIG_eLIA || CONFIG_DISKtel || CONFIG_SECUREEDGEMP3 */
+
+/***************************************************************************/
+
+void coldfire_reset(void)
+{
+	HARD_RESET_NOW();
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+#ifdef CONFIG_BOOTPARAM
+	strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+	commandp[size-1] = 0;
+#elif defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
+    defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \
+	 defined(CONFIG_HW_CLEOPATRA)
+	/* Copy command line from FLASH to local buffer... */
+	memcpy(commandp, (char *) 0xf0004000, size);
+	commandp[size-1] = 0;
+#else
+	memset(commandp, 0, size);
+#endif /* CONFIG_NETtel || CONFIG_eLIA || CONFIG_DISKtel || CONFIG_SECUREEDGEMP3 */
+
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+	mach_reset = coldfire_reset;
+	mach_gettimeoffset = coldfire_timer_offset;
+}
+
+/***************************************************************************/
+#ifdef TRAP_DBG_INTERRUPT
+
+asmlinkage void dbginterrupt_c(struct frame *fp)
+{
+	extern void dump(struct pt_regs *fp);
+	printk("%s(%d): BUS ERROR TRAP\n", __FILE__, __LINE__);
+	dump((struct pt_regs *) fp);
+	asm("halt");
+}
+
+#endif
+/***************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/eLIA/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5307/eLIA/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5307/eLIA/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/eLIA/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,224 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5307 ColdFire based eLIA.
+ *
+ *	(C) Copyright 1999-2003, Greg Ungerer.
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+#include "asm/elia.h"
+
+/*****************************************************************************/
+
+/*
+ *	Moreton Bay eLIA board memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+/*
+ *	The eLIA platform has some funky LEDs!
+ */
+.global ppdata
+ppdata:
+.short	0x0000
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 *	Disable watchdog timer.
+	 */
+	move.l	#MCF_MBAR, %a0			/* Get MBAR address */
+	clr.l	%d0				/* Disable SWT */
+	move.b	%d0, MCFSIM_SYPCR(%a0)
+	move.b	#0x55, %d0			/* Clear SWT as well */
+	move.b	%d0, MCFSIM_SWSR(%a0)
+	move.b	#0xaa, %d0
+	move.b	%d0, MCFSIM_SWSR(%a0)
+	move.l	#0xffffffff, %d0		/* Mask out all interrupts */
+	move.l	%d0, MCFSIM_IMR(%a0)
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* invalidate whole cache */
+	movec	%d0,%CACR
+	nop
+#ifdef DEBUGGER_COMPATIBLE_CACHE
+	move.l	#0x0000c000, %d0		/* Set SDRAM cached only */
+#else
+	move.l	#0x0000c020, %d0		/* Set SDRAM cached only (copyback) */
+#endif
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR1
+
+	/* Enable cache */
+	move.l	#0xa0000200, %d0
+	movec	%d0,%CACR
+	nop
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/eLIA/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5307/eLIA/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5307/eLIA/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/eLIA/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,65 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x400, LENGTH = 0x400000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+			*(.rodata.str1.1)
+		. = ALIGN(0x4) ;
+			*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+			*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+			*(.text.init)
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		. = ALIGN(4) ;
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/entry.S linux-2.4.29-uc1/arch/m68knommu/platform/5307/entry.S
--- linux-2.4.29/arch/m68knommu/platform/5307/entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/entry.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,836 @@
+/* -*- mode: asm -*-
+ *
+ *  linux/arch/m68knommu/platform/5307/entry.S
+ *
+ *  Copyright (C) 1999  Greg Ungerer (gerg@snapgear.com)
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@uClinux.org>,
+ *                      Kenneth Albanowski <kjahds@kjahds.com>,
+ *  Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *  Copyright (C) 2003  Philippe De Muyter <phdm@macqel.be>
+ *
+ * Based on:
+ *
+ *  linux/arch/m68k/kernel/entry.S
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ * Linux/m68k support by Hamish Macdonald
+ *
+ * 68060 fixes by Jesper Skov
+ * ColdFire support by Greg Ungerer (gerg@snapgear.com)
+ * 5307 fixes by David W. Miller
+ * linux 2.4 support David McCullough <davidm@snapgear.com>
+ * 5307 fix by Philippe De Muyter
+ */
+
+/*
+ * entry.S  contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all interrupts
+ * and faults that can result in a task-switch.
+ *
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ *
+ * Stack layout in 'ret_from_exception':
+ *
+ *	This allows access to the syscall arguments in registers d1-d5
+ *
+ *	 0(sp) - d1
+ *	 4(sp) - d2
+ *	 8(sp) - d3
+ *	 C(sp) - d4
+ *	10(sp) - d5
+ *	14(sp) - a0
+ *	18(sp) - a1
+ *	1C(sp) - a2
+ *	20(sp) - d0
+ *	24(sp) - orig_d0
+ *	28(sp) - stack adjustment
+ *	2C(sp) - format & vector      }
+ *	2E(sp) - sr                   } different to m68k
+ *	30(sp) - pc                   }
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+
+#include "m68k_defs.h"
+
+LENOSYS = 38
+
+/* the following macro is used when enabling interrupts */
+#define ALLOWINT 0xf8ff
+#define	MAX_NOINT_IPL	0
+
+
+LD0			= 0x20
+LORIG_D0	= 0x24
+LFORMATVEC	= 0x2c
+LSR			= 0x2e
+LPC			= 0x30
+
+/*
+ * This defines the normal kernel pt-regs layout.
+ *
+ * regs are a2-a6 and d6-d7 preserved by C code
+ * the kernel doesn't mess with usp unless it needs to
+ *
+ *	This is made a little more tricky on the ColdFire. There is no
+ *	separate kernel and user stack pointers. Need to artificially
+ *	construct a usp in software... When doing this we need to disable
+ *	interrupts, otherwise bad things could happen.
+ */
+#define SAVE_ALL						\
+	move	#0x2700,%sr;		/* disable intrs */	\
+	btst	#5,%sp@(2);		/* from user? */	\
+	bnes	6f;			/* no, skip */		\
+	movel	%sp,sw_usp;		/* save user sp */	\
+	addql	#8,sw_usp;		/* remove exception */	\
+	movel	sw_ksp,%sp;		/* kernel sp */		\
+	subql	#8,%sp;			/* room for exception */\
+	clrl	%sp@-;			/* stk_adj */		\
+	movel	%d0,%sp@-;		/* orig d0 */		\
+	movel	%d0,%sp@-;		/* d0 */		\
+	subl	#32,%sp;		/* space for 8 regs */	\
+	moveml	%d1-%d5/%a0-%a2,%sp@;				\
+	movel	sw_usp,%a0;		/* get usp */		\
+	moveml	%a0@(-8),%d1-%d2;	/* get exception */	\
+	moveml	%d1-%d2,%sp@(LFORMATVEC); /* copy exception */	\
+	bra	7f;						\
+	6:							\
+	clrl	%sp@-;			/* stk_adj */		\
+	movel	%d0,%sp@-;		/* orig d0 */		\
+	movel	%d0,%sp@-;		/* d0 */		\
+	subl	#32,%sp;		/* space for 7 regs */	\
+	moveml	%d1-%d5/%a0-%a2,%sp@;				\
+	7:
+
+#define RESTORE_ALL						\
+	btst	#5,%sp@(LSR);		/* going user? */	\
+	bnes	8f;			/* no, skip */		\
+	move	#0x2700,%sr;		/* disable intrs */	\
+	movel	sw_usp,%a0;		/* get usp */		\
+	moveml	%sp@(LFORMATVEC),%d1-%d2; /* copy exception */	\
+	moveml	%d1-%d2,%a0@(-8);				\
+	moveml	%sp@,%d1-%d5/%a0-%a2;				\
+	addl	#32,%sp;		/* space for 8 regs */	\
+	movel	%sp@+,%d0;					\
+	addql	#4,%sp;			/* orig d0 */		\
+	addl	%sp@+,%sp;		/* stk adj */		\
+	addql	#8,%sp;			/* remove exception */	\
+	movel	%sp,sw_ksp;		/* save ksp */		\
+	subql	#8,sw_usp;		/* set exception */	\
+	movel	sw_usp,%sp;		/* restore usp */	\
+	rte;							\
+	8:							\
+	moveml	%sp@,%d1-%d5/%a0-%a2;				\
+	addl	#32,%sp;		/* space for 8 regs */	\
+	movel	%sp@+,%d0;					\
+	addql	#4,%sp;			/* orig d0 */		\
+	addl	%sp@+,%sp;		/* stk adj */		\
+	rte
+
+/*
+ *	Quick exception save, use current stack only.
+ */
+#define SAVE_LOCAL						\
+	move	#0x2700,%sr;		/* disable intrs */	\
+	clrl	%sp@-;			/* stk_adj */		\
+	movel	%d0,%sp@-;		/* orig d0 */		\
+	movel	%d0,%sp@-;		/* d0 */		\
+	subl	#32,%sp;		/* space for 8 regs */	\
+	moveml	%d1-%d5/%a0-%a2,%sp@;
+
+#define RESTORE_LOCAL						\
+	moveml	%sp@,%d1-%d5/%a0-%a2;				\
+	addl	#32,%sp;		/* space for 8 regs */	\
+	movel	%sp@+,%d0;					\
+	addql	#4,%sp;			/* orig d0 */		\
+	addl	%sp@+,%sp;		/* stk adj */		\
+	rte
+
+
+#define SWITCH_STACK_SIZE (6*4+4)	/* includes return address */
+
+#define SAVE_SWITCH_STACK		\
+	subl    #24,%sp; /* 6 regs */	\
+	moveml	%a3-%a6/%d6-%d7,%sp@
+
+#define RESTORE_SWITCH_STACK		\
+	moveml	%sp@,%a3-%a6/%d6-%d7;	\
+	addl	#24,%sp /* 6 regs */
+
+/*
+ *	Software copy of the user and kernel stack pointers... Ugh...
+ *	Need these to get around ColdFire not having separate kernel
+ *	and user stack pointers.
+ */
+.globl SYMBOL_NAME(sw_usp)
+.globl SYMBOL_NAME(sw_ksp)
+
+.data
+
+sw_ksp:
+.long	0
+
+sw_usp:
+.long	0
+
+.text
+
+
+.globl SYMBOL_NAME(buserr)
+.globl SYMBOL_NAME(trap)
+.globl SYMBOL_NAME(system_call)
+.globl SYMBOL_NAME(resume), SYMBOL_NAME(ret_from_exception)
+.globl SYMBOL_NAME(ret_from_signal)
+.globl SYMBOL_NAME(sys_call_table)
+.globl SYMBOL_NAME(sys_fork), SYMBOL_NAME(sys_clone), SYMBOL_NAME(sys_vfork)
+.globl SYMBOL_NAME(ret_from_interrupt)
+.globl SYMBOL_NAME(inthandler)
+.globl SYMBOL_NAME(fasthandler)
+
+#ifdef TRAP_DBG_INTERRUPT
+.globl SYMBOL_NAME(dbginterrupt)
+#endif
+
+.text
+
+ENTRY(buserr)
+	SAVE_ALL
+	moveq	#-1,%d0
+	movel	%d0,%sp@(LORIG_D0)	| a -1 in the ORIG_D0 field
+								| signifies that the stack frame
+								| is NOT for syscall
+
+	movel	%sp,%sp@- 			| stack frame pointer argument
+	jsr	SYMBOL_NAME(buserr_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+
+#ifdef TRAP_DBG_INTERRUPT
+ENTRY(dbginterrupt)
+	SAVE_ALL
+	moveq	#-1,%d0
+	movel	%d0,%sp@(LORIG_D0)	| a -1 in the ORIG_D0 field
+								| signifies that the stack frame
+								| is NOT for syscall
+
+	movel	%sp,%sp@- 			| stack frame pointer argument
+	jsr	SYMBOL_NAME(dbginterrupt_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+#endif
+
+
+ENTRY(reschedule)
+	| save top of frame
+	pea	%sp@
+	jbsr	SYMBOL_NAME(set_esp0)
+	addql	#4,%sp
+
+	pea	SYMBOL_NAME(ret_from_exception)
+	jmp	SYMBOL_NAME(schedule)
+
+	| After a fork we jump here directly from resume,
+	| so that %d1 contains the previous task
+	| Theoretically only needed on SMP, but lets watch
+	| what happens in schedule_tail() in future...
+ENTRY(ret_from_fork)
+	movel	%d1,%sp@-
+	jsr	SYMBOL_NAME(schedule_tail)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(system_call)
+	SAVE_ALL
+	move	#0x2000,%sr;		| enable intrs again
+
+	movel	#-LENOSYS,%d2
+	movel	%d2,LD0(%sp)		| default return value in d0
+					| original D0 is in orig_d0
+	movel	%d0,%d2
+
+	| save top of frame
+	pea	%sp@
+	jbsr	SYMBOL_NAME(set_esp0)
+	addql	#4,%sp
+
+	cmpl	#NR_syscalls,%d2
+	jcc	SYMBOL_NAME(ret_from_exception)
+	lea	SYMBOL_NAME(sys_call_table),%a0
+	lsll	#2,%d2		| movel	%a0@(%d2:l:4),%d3
+	movel	%a0@(%d2),%d3
+	jeq	SYMBOL_NAME(ret_from_exception)
+	lsrl	#2,%d2
+	movel	SYMBOL_NAME(_current_task),%a0
+	btst	#1,%a0@(TASK_PTRACE+3)	| PT_TRACESYS
+	bnes	1f
+	movel	%d3,%a0
+	jbsr	%a0@
+	movel	%d0,%sp@(LD0)		| save the return value
+	jra	SYMBOL_NAME(ret_from_exception)
+1:
+	subql	#4,%sp
+	SAVE_SWITCH_STACK
+	jbsr	SYMBOL_NAME(syscall_trace)
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+	movel	%d3,%a0
+	jbsr	%a0@
+	movel	%d0,%sp@(LD0)		| save the return value
+	subql	#4,%sp			| dummy return address
+	SAVE_SWITCH_STACK
+	jbsr	SYMBOL_NAME(syscall_trace)
+
+SYMBOL_NAME_LABEL(ret_from_signal)
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+
+SYMBOL_NAME_LABEL(ret_from_exception)
+	btst	#5,%sp@(LSR)		| check if returning to kernel
+	bnes	2f			| if so, skip resched, signals
+	| tstl	SYMBOL_NAME(need_resched)
+	| jne	SYMBOL_NAME(reschedule)
+	movel	SYMBOL_NAME(_current_task),%a0
+	tstl	%a0@(TASK_NEEDRESCHED)
+	jne	SYMBOL_NAME(reschedule)
+
+#if 0 /* as per m68k */
+	cmpl	#SYMBOL_NAME(task),%a0	| task[0] cannot have signals
+	jeq	2f
+#endif
+
+	bclr	#2,%a0@(TASK_PTRACE+3)	| check for delayed trace
+	jeq	1f
+	bclr	#7,%sp@(LSR)		| clear trace bit in SR
+	pea	1			| send SIGTRAP
+	movel	%a0,%sp@-
+	pea	5
+	jbsr	SYMBOL_NAME(send_sig)
+	addql	#8,%sp
+	addql	#4,%sp
+	movel	SYMBOL_NAME(_current_task),%a0
+
+1:
+	tstl	%a0@(TASK_STATE)	| state
+	jne	SYMBOL_NAME(reschedule)
+	tstl	%a0@(TASK_COUNTER)	| counter
+	jeq	SYMBOL_NAME(reschedule)
+
+	tstl	%a0@(TASK_SIGPENDING)
+	jne	Lsignal_return
+2:	RESTORE_ALL			| Does RTE
+
+Lsignal_return:
+	subql	#4,%sp			| dummy return address
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	clrl	%sp@-
+	jsr	SYMBOL_NAME(do_signal)
+	addql	#8,%sp
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+
+	btst    #5,%sp@(LSR);	/* going user? */   
+	bnes    not_user;	/* no, skip */      
+	move    #0x2700,%sr;	/* disable intrs */ 
+	movel   sw_usp,%a0;	/* get usp */       
+	moveml  %sp@(LFORMATVEC),%d1-%d2; /* copy exception */  
+	moveml  %d1-%d2,%a0@(-8);               
+	moveml  %sp@,%d1-%d5/%a0-%a2;               
+	addl    #32,%sp;        /* space for 8 regs */  
+	movel   %sp@+,%d0;                  
+	addql   #4,%sp;         /* orig d0 */       
+	addl    %sp@+,%sp;      /* stk adj */       
+	addql   #8,%sp;         /* remove exception */  
+	movel   %sp,sw_ksp;     /* save ksp */      
+	movel   sw_usp,%sp;     /* restore usp */   
+	subql   #8,%sp;         /* set exception */ 
+	rte;                            
+not_user:                          
+	moveml  %sp@,%d1-%d5/%a0-%a2;               
+	addl    #32,%sp;        /* space for 8 regs */  
+	movel   %sp@+,%d0;                  
+	addql   #4,%sp;         /* orig d0 */       
+	addl    %sp@+,%sp;      /* stk adj */       
+	rte
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ *	Common ColdFire trap handler. Most traps come through here first.
+ */
+ENTRY(trap)
+	SAVE_ALL
+	moveq	#-1,%d0
+	movel	%d0,%sp@(LORIG_D0)	| a -1 in the ORIG_D0 field
+					| signifies that the stack frame
+					| is NOT for syscall
+	movel	%sp,%sp@- 		| stack frame pointer argument
+	jsr	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+/*
+ *	This is the generic interrupt handler (for all hardware interrupt
+ *	sources). It figures out the vector number and calls the appropriate
+ *	interrupt service routine directly.
+ */
+SYMBOL_NAME_LABEL(inthandler)
+	SAVE_ALL
+	moveq	#-1,%d0
+	movel	%d0,%sp@(LORIG_D0)	| a -1 in the ORIG_D0 field
+					| signifies that the stack frame
+					| is NOT for syscall
+	addql	#1,SYMBOL_NAME(local_irq_count)
+					| put exception # in d0
+	movew   %sp@(LFORMATVEC),%d0
+	andl	#0x03fc,%d0		| mask out vector only
+
+	movel	SYMBOL_NAME(mach_kstat_irqs),%a0
+					| get addr of kstat struct
+	addql	#1,%a0@(%d0)		| incr irq intr count
+
+	lsrl	#2,%d0			| calculate real vector #
+
+	movel   %sp,%sp@-               | push regs arg onto stack
+	movel   %d0,%sp@-               | push vector # on stack
+
+	jbsr    SYMBOL_NAME(process_int)
+	addl	#8,%sp			| pop parameters off stack
+
+	bra	ret_from_interrupt	| this was fallthrough
+
+
+/*
+ *	This is the fast interrupt handler (for certain hardware interrupt
+ *	sources). Unlike the normal interrupt handler it just uses the
+ *	current stack (doesn't care if it is user or kernel). It also
+ *	doesn't bother doing the bottom half handlers.
+ */
+SYMBOL_NAME_LABEL(fasthandler)
+	SAVE_LOCAL
+
+	movew   %sp@(LFORMATVEC),%d0
+	andl	#0x03fc,%d0		| mask out vector only
+
+	movel	SYMBOL_NAME(mach_kstat_irqs),%a0
+					| get addr of kstat struct
+	addql	#1,%a0@(%d0)		| incr irq intr count
+
+	movel	%sp,%sp@-		| push regs arg onto stack
+	clrl	%d1
+	movel	%d1,%sp@- 		| push devid arg
+	lsrl	#2,%d0			| calculate real vector #
+	movel	%d0,%sp@- 		| push vector # on stack
+
+	lsll	#4,%d0			| adjust for array offset
+	lea	SYMBOL_NAME(irq_list),%a0
+	movel	%a0@(%d0),%a0		| get function to call
+	jbsr	%a0@			| call vector handler
+	addl	#12,%sp			| pop parameters off stack
+
+	RESTORE_LOCAL
+
+/*--------------------------------------------------------------------------*/
+
+SYMBOL_NAME_LABEL(ret_from_interrupt)
+	subql	#1,SYMBOL_NAME(local_irq_count)
+	jeq	2f
+1:
+	RESTORE_ALL
+2:
+	moveb	%sp@(LSR),%d0
+	andl	#(~ALLOWINT>>8)&0xff, %d0
+	jne 1b
+
+	/* check if we need to do software interrupts */
+
+	movel	SYMBOL_NAME(irq_stat)+CPUSTAT_SOFTIRQ_PENDING,%d0
+	jeq	SYMBOL_NAME(ret_from_exception)
+
+	pea	SYMBOL_NAME(ret_from_exception)
+	jmp	SYMBOL_NAME(do_softirq)
+
+/* Handler for uninitialized and spurious interrupts */
+
+SYMBOL_NAME_LABEL(bad_interrupt)
+	addql	#1,SYMBOL_NAME(num_spurious)
+	rte
+
+ENTRY(sys_fork)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(m68k_fork)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_vfork)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(m68k_vfork)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_clone)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(m68k_clone)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(do_sigsuspend)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(do_rt_sigsuspend)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_sigreturn)
+	SAVE_SWITCH_STACK
+	jbsr	SYMBOL_NAME(do_sigreturn)
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigreturn)
+	SAVE_SWITCH_STACK
+	jbsr	SYMBOL_NAME(do_rt_sigreturn)
+	RESTORE_SWITCH_STACK
+	rts
+
+SYMBOL_NAME_LABEL(resume)
+	/*
+	 * Beware - when entering resume, prev (the current task) is
+	 * in a0, next (the new task) is in a1,so don't change these
+	 * registers until their contents are no longer needed.
+	 */
+
+	/* save sr */
+	movew	%sr,%d0
+	movew	%d0,%a0@(TASK_THREAD+THREAD_SR)
+
+	/* disable interrupts */
+	oril	#0x700,%d0
+	move	%d0,%sr
+
+#ifndef NO_MM
+	/* save fs (sfc,%dfc) (may be pointing to kernel memory) */
+	movec	%sfc,%d0
+	movew	%d0,%a0@(TASK_THREAD+THREAD_FS)
+#endif
+
+#ifndef CONFIG_COLDFIRE
+	/* save usp */
+	/* it is better to use a movel here instead of a movew 8*) */
+	movec	%usp,%d0
+	movel	%d0,%a0@(TASK_THREAD+THREAD_USP)
+#else
+	movel	sw_usp,%d0 /* usp */
+	movel	%d0,%a0@(TASK_THREAD+THREAD_USP) /* DAVIDM was a2 */
+#endif
+
+	/* save non-scratch registers on stack */
+	SAVE_SWITCH_STACK
+
+	/* save current kernel stack pointer */
+	movel	%sp,%a0@(TASK_THREAD+THREAD_KSP)
+
+	/* Return previous task in %d1 */
+	// movel	%curptr,%d1
+	movel	SYMBOL_NAME(_current_task), %d1
+
+	/* switch to new task (a1 contains new task) */
+	// movel	%a1,%curptr
+	movel	%a1,SYMBOL_NAME(_current_task)
+
+	/* restore the kernel stack pointer */
+	movel	%a1@(TASK_THREAD+THREAD_KSP),%sp
+
+	/* restore non-scratch registers */
+	RESTORE_SWITCH_STACK
+
+#ifndef CONFIG_COLDFIRE
+	/* restore user stack pointer */
+	movel	%a1@(TASK_THREAD+THREAD_USP),%a0
+	movel	%a0,%usp
+#else
+	/* restore user stack pointer */
+	movel	%a1@(TASK_THREAD+THREAD_USP),%a0
+	movel	%a0, sw_usp
+#endif
+
+#ifndef CONFIG_COLDFIRE
+	/* restore fs (sfc,%dfc) */
+	movew	%a1@(TASK_THREAD+THREAD_FS),%a0
+	movec	%a0,%sfc
+	movec	%a0,%dfc
+#endif
+
+	/* restore status register */
+	movew	%a1@(TASK_THREAD+THREAD_SR),%d0
+	movew	%d0, %sr
+
+	rts
+
+.text | DAVIDM was .data,  moved to .text
+ALIGN
+SYMBOL_NAME_LABEL(sys_call_table)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 0  -  old "setup()" system call*/
+	.long SYMBOL_NAME(sys_exit)
+	.long SYMBOL_NAME(sys_fork)
+	.long SYMBOL_NAME(sys_read)
+	.long SYMBOL_NAME(sys_write)
+	.long SYMBOL_NAME(sys_open)			/* 5 */
+	.long SYMBOL_NAME(sys_close)
+	.long SYMBOL_NAME(sys_waitpid)
+	.long SYMBOL_NAME(sys_creat)
+	.long SYMBOL_NAME(sys_link)
+	.long SYMBOL_NAME(sys_unlink)		/* 10 */
+	.long SYMBOL_NAME(sys_execve)
+	.long SYMBOL_NAME(sys_chdir)
+	.long SYMBOL_NAME(sys_time)
+	.long SYMBOL_NAME(sys_mknod)
+	.long SYMBOL_NAME(sys_chmod)		/* 15 */
+	.long SYMBOL_NAME(sys_chown16)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old break syscall holder */
+	.long SYMBOL_NAME(sys_stat)
+	.long SYMBOL_NAME(sys_lseek)
+	.long SYMBOL_NAME(sys_getpid)		/* 20 */
+	.long SYMBOL_NAME(sys_mount)
+	.long SYMBOL_NAME(sys_oldumount)
+	.long SYMBOL_NAME(sys_setuid16)
+	.long SYMBOL_NAME(sys_getuid16)
+	.long SYMBOL_NAME(sys_stime)		/* 25 */
+	.long SYMBOL_NAME(sys_ptrace)
+	.long SYMBOL_NAME(sys_alarm)
+	.long SYMBOL_NAME(sys_fstat)
+	.long SYMBOL_NAME(sys_pause)
+	.long SYMBOL_NAME(sys_utime)		/* 30 */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old stty syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old gtty syscall holder */
+	.long SYMBOL_NAME(sys_access)
+	.long SYMBOL_NAME(sys_nice)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 35 */	/* old ftime syscall holder */
+	.long SYMBOL_NAME(sys_sync)
+	.long SYMBOL_NAME(sys_kill)
+	.long SYMBOL_NAME(sys_rename)
+	.long SYMBOL_NAME(sys_mkdir)
+	.long SYMBOL_NAME(sys_rmdir)		/* 40 */
+	.long SYMBOL_NAME(sys_dup)
+	.long SYMBOL_NAME(sys_pipe)
+	.long SYMBOL_NAME(sys_times)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old prof syscall holder */
+	.long SYMBOL_NAME(sys_brk)			/* 45 */
+	.long SYMBOL_NAME(sys_setgid16)
+	.long SYMBOL_NAME(sys_getgid16)
+	.long SYMBOL_NAME(sys_signal)
+	.long SYMBOL_NAME(sys_geteuid16)
+	.long SYMBOL_NAME(sys_getegid16)	/* 50 */
+	.long SYMBOL_NAME(sys_acct)
+	.long SYMBOL_NAME(sys_umount)					/* recycled never used phys() */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old lock syscall holder */
+	.long SYMBOL_NAME(sys_ioctl)
+	.long SYMBOL_NAME(sys_fcntl)		/* 55 */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old mpx syscall holder */
+	.long SYMBOL_NAME(sys_setpgid)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old ulimit syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_umask)		/* 60 */
+	.long SYMBOL_NAME(sys_chroot)
+	.long SYMBOL_NAME(sys_ustat)
+	.long SYMBOL_NAME(sys_dup2)
+	.long SYMBOL_NAME(sys_getppid)
+	.long SYMBOL_NAME(sys_getpgrp)		/* 65 */
+	.long SYMBOL_NAME(sys_setsid)
+	.long SYMBOL_NAME(sys_sigaction)
+	.long SYMBOL_NAME(sys_sgetmask)
+	.long SYMBOL_NAME(sys_ssetmask)
+	.long SYMBOL_NAME(sys_setreuid16)	/* 70 */
+	.long SYMBOL_NAME(sys_setregid16)
+	.long SYMBOL_NAME(sys_sigsuspend)
+	.long SYMBOL_NAME(sys_sigpending)
+	.long SYMBOL_NAME(sys_sethostname)
+	.long SYMBOL_NAME(sys_setrlimit)	/* 75 */
+	.long SYMBOL_NAME(sys_old_getrlimit)
+	.long SYMBOL_NAME(sys_getrusage)
+	.long SYMBOL_NAME(sys_gettimeofday)
+	.long SYMBOL_NAME(sys_settimeofday)
+	.long SYMBOL_NAME(sys_getgroups16)	/* 80 */
+	.long SYMBOL_NAME(sys_setgroups16)
+	.long SYMBOL_NAME(old_select)
+	.long SYMBOL_NAME(sys_symlink)
+	.long SYMBOL_NAME(sys_lstat)
+	.long SYMBOL_NAME(sys_readlink)		/* 85 */
+	.long SYMBOL_NAME(sys_uselib)
+	.long SYMBOL_NAME(sys_swapon)
+	.long SYMBOL_NAME(sys_reboot)
+	.long SYMBOL_NAME(old_readdir)
+	.long SYMBOL_NAME(old_mmap)			/* 90 */
+	.long SYMBOL_NAME(sys_munmap)
+	.long SYMBOL_NAME(sys_truncate)
+	.long SYMBOL_NAME(sys_ftruncate)
+	.long SYMBOL_NAME(sys_fchmod)
+	.long SYMBOL_NAME(sys_fchown16)		/* 95 */
+	.long SYMBOL_NAME(sys_getpriority)
+	.long SYMBOL_NAME(sys_setpriority)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old profil syscall holder */
+	.long SYMBOL_NAME(sys_statfs)
+	.long SYMBOL_NAME(sys_fstatfs)		/* 100 */
+	.long SYMBOL_NAME(sys_ioperm)
+	.long SYMBOL_NAME(sys_socketcall)
+	.long SYMBOL_NAME(sys_syslog)
+	.long SYMBOL_NAME(sys_setitimer)
+	.long SYMBOL_NAME(sys_getitimer)	/* 105 */
+	.long SYMBOL_NAME(sys_newstat)
+	.long SYMBOL_NAME(sys_newlstat)
+	.long SYMBOL_NAME(sys_newfstat)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* iopl for i386 */ /* 110 */
+	.long SYMBOL_NAME(sys_vhangup)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* obsolete idle() syscall */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* vm86old for i386 */
+	.long SYMBOL_NAME(sys_wait4)
+	.long SYMBOL_NAME(sys_swapoff)		/* 115 */
+	.long SYMBOL_NAME(sys_sysinfo)
+	.long SYMBOL_NAME(sys_ipc)
+	.long SYMBOL_NAME(sys_fsync)
+	.long SYMBOL_NAME(sys_sigreturn)
+	.long SYMBOL_NAME(sys_clone)		/* 120 */
+	.long SYMBOL_NAME(sys_setdomainname)
+	.long SYMBOL_NAME(sys_newuname)
+	.long SYMBOL_NAME(sys_cacheflush)	/* modify_ldt for i386 */
+	.long SYMBOL_NAME(sys_adjtimex)
+	.long SYMBOL_NAME(sys_mprotect)		/* 125 */
+	.long SYMBOL_NAME(sys_sigprocmask)
+	.long SYMBOL_NAME(sys_create_module)
+	.long SYMBOL_NAME(sys_init_module)
+	.long SYMBOL_NAME(sys_delete_module)
+	.long SYMBOL_NAME(sys_get_kernel_syms)	/* 130 */
+	.long SYMBOL_NAME(sys_quotactl)
+	.long SYMBOL_NAME(sys_getpgid)
+	.long SYMBOL_NAME(sys_fchdir)
+	.long SYMBOL_NAME(sys_bdflush)
+	.long SYMBOL_NAME(sys_sysfs)		/* 135 */
+	.long SYMBOL_NAME(sys_personality)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for afs_syscall */
+	.long SYMBOL_NAME(sys_setfsuid16)
+	.long SYMBOL_NAME(sys_setfsgid16)
+	.long SYMBOL_NAME(sys_llseek)		/* 140 */
+	.long SYMBOL_NAME(sys_getdents)
+	.long SYMBOL_NAME(sys_select)
+	.long SYMBOL_NAME(sys_flock)
+	.long SYMBOL_NAME(sys_msync)
+	.long SYMBOL_NAME(sys_readv)		/* 145 */
+	.long SYMBOL_NAME(sys_writev)
+	.long SYMBOL_NAME(sys_getsid)
+	.long SYMBOL_NAME(sys_fdatasync)
+	.long SYMBOL_NAME(sys_sysctl)
+	.long SYMBOL_NAME(sys_mlock)		/* 150 */
+	.long SYMBOL_NAME(sys_munlock)
+	.long SYMBOL_NAME(sys_mlockall)
+	.long SYMBOL_NAME(sys_munlockall)
+	.long SYMBOL_NAME(sys_sched_setparam)
+	.long SYMBOL_NAME(sys_sched_getparam)   /* 155 */
+	.long SYMBOL_NAME(sys_sched_setscheduler)
+	.long SYMBOL_NAME(sys_sched_getscheduler)
+	.long SYMBOL_NAME(sys_sched_yield)
+	.long SYMBOL_NAME(sys_sched_get_priority_max)
+	.long SYMBOL_NAME(sys_sched_get_priority_min)  /* 160 */
+	.long SYMBOL_NAME(sys_sched_rr_get_interval)
+	.long SYMBOL_NAME(sys_nanosleep)
+	.long SYMBOL_NAME(sys_mremap)
+	.long SYMBOL_NAME(sys_setresuid16)
+	.long SYMBOL_NAME(sys_getresuid16)	/* 165 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for vm86 */
+	.long SYMBOL_NAME(sys_query_module)
+	.long SYMBOL_NAME(sys_poll)
+	.long SYMBOL_NAME(sys_nfsservctl)
+	.long SYMBOL_NAME(sys_setresgid16)	/* 170 */
+	.long SYMBOL_NAME(sys_getresgid16)
+	.long SYMBOL_NAME(sys_prctl)
+	.long SYMBOL_NAME(sys_rt_sigreturn)
+	.long SYMBOL_NAME(sys_rt_sigaction)
+	.long SYMBOL_NAME(sys_rt_sigprocmask)	/* 175 */
+	.long SYMBOL_NAME(sys_rt_sigpending)
+	.long SYMBOL_NAME(sys_rt_sigtimedwait)
+	.long SYMBOL_NAME(sys_rt_sigqueueinfo)
+	.long SYMBOL_NAME(sys_rt_sigsuspend)
+	.long SYMBOL_NAME(sys_pread)		/* 180 */
+	.long SYMBOL_NAME(sys_pwrite)
+	.long SYMBOL_NAME(sys_lchown16);
+	.long SYMBOL_NAME(sys_getcwd)
+	.long SYMBOL_NAME(sys_capget)
+	.long SYMBOL_NAME(sys_capset)           /* 185 */
+	.long SYMBOL_NAME(sys_sigaltstack)
+	.long SYMBOL_NAME(sys_sendfile)
+	.long SYMBOL_NAME(sys_ni_syscall)		/* streams1 */
+	.long SYMBOL_NAME(sys_ni_syscall)		/* streams2 */
+	.long SYMBOL_NAME(sys_vfork)            /* 190 */
+	.long SYMBOL_NAME(sys_getrlimit)
+	.long SYMBOL_NAME(sys_mmap2)
+	.long SYMBOL_NAME(sys_truncate64)
+	.long SYMBOL_NAME(sys_ftruncate64)
+	.long SYMBOL_NAME(sys_stat64)		/* 195 */
+	.long SYMBOL_NAME(sys_lstat64)
+	.long SYMBOL_NAME(sys_fstat64)
+	.long SYMBOL_NAME(sys_chown)
+	.long SYMBOL_NAME(sys_getuid)
+	.long SYMBOL_NAME(sys_getgid)		/* 200 */
+	.long SYMBOL_NAME(sys_geteuid)
+	.long SYMBOL_NAME(sys_getegid)
+	.long SYMBOL_NAME(sys_setreuid)
+	.long SYMBOL_NAME(sys_setregid)
+	.long SYMBOL_NAME(sys_getgroups)	/* 205 */
+	.long SYMBOL_NAME(sys_setgroups)
+	.long SYMBOL_NAME(sys_fchown)
+	.long SYMBOL_NAME(sys_setresuid)
+	.long SYMBOL_NAME(sys_getresuid)
+	.long SYMBOL_NAME(sys_setresgid)	/* 210 */
+	.long SYMBOL_NAME(sys_getresgid)
+	.long SYMBOL_NAME(sys_lchown)
+	.long SYMBOL_NAME(sys_setuid)
+	.long SYMBOL_NAME(sys_setgid)
+	.long SYMBOL_NAME(sys_setfsuid)		/* 215 */
+	.long SYMBOL_NAME(sys_setfsgid)
+	.long SYMBOL_NAME(sys_pivot_root)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
+	.long SYMBOL_NAME(sys_gettid)
+	.long SYMBOL_NAME(sys_tkill)
+	.long SYMBOL_NAME(sys_setxattr)
+	.long SYMBOL_NAME(sys_lsetxattr)
+	.long SYMBOL_NAME(sys_fsetxattr)	/* 225 */
+	.long SYMBOL_NAME(sys_getxattr)
+	.long SYMBOL_NAME(sys_lgetxattr)
+	.long SYMBOL_NAME(sys_fgetxattr)
+	.long SYMBOL_NAME(sys_listxattr)
+	.long SYMBOL_NAME(sys_llistxattr)	/* 230 */
+	.long SYMBOL_NAME(sys_flistxattr)
+	.long SYMBOL_NAME(sys_removexattr)
+	.long SYMBOL_NAME(sys_lremovexattr)
+	.long SYMBOL_NAME(sys_fremovexattr)
+
+	.space (NR_syscalls-222)*4
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/ints.c linux-2.4.29-uc1/arch/m68knommu/platform/5307/ints.c
--- linux-2.4.29/arch/m68knommu/platform/5307/ints.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/ints.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,430 @@
+/*
+ * linux/arch/m68knommu/platform/5307/ints.c -- General interrupt handling code
+ *
+ * Copyright (C) 1999  Greg Ungerer (gerg@snapgear.com)
+ * Copyright (C) 1998  D. Jeff Dionne <jeff@ArcturusNetworks.com>
+ *                     Kenneth Albanowski <kjahds@kjahds.com>,
+ * Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *
+ * Based on:
+ *
+ * linux/arch/m68k/kernel/ints.c -- Linux/m68k general interrupt handling code
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/errno.h>
+#include <linux/config.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+
+#define KGH 0
+/*
+ *	This table stores the address info for each vector handler used as
+ *      fast interrupt handlers.
+ */
+irq_handler_t irq_list[SYS_IRQS];
+#if (SYS_IRQS != NR_IRQS)
+#error "SYS IRQS != NR IRQS"
+#endif
+/*
+ *  If interrupts are not flaged with the IRQ_FLG_FAST, use this to store a
+ *  linked list of possible handlers. The linked list allows sharing of
+ *  interrupts.
+ */
+struct irq_node *std_vec_list[SYS_IRQS];
+/*
+ *  I cannot use kmalloc to allocate/deallocate memory as it is not ready when
+ *  interrupts are first requested. I need my on allocator/deallocator of
+ *  irq nodes. This is a list of irq nodes that can be used.
+ */
+enum { POOL_SIZE = NR_IRQS};
+static struct irq_node  pool[POOL_SIZE];
+static struct irq_node *get_irq_node(void);
+
+unsigned int *mach_kstat_irqs;
+
+/* The number of spurious interrupts */
+volatile unsigned int num_spurious;
+
+unsigned int local_bh_count[NR_CPUS];
+unsigned int local_irq_count[NR_CPUS];
+
+static void default_irq_handler(int irq, void *ptr, struct pt_regs *regs)
+{
+#if 1
+	printk("%s(%d): default irq handler vec=%d [0x%x]\n",
+		__FILE__, __LINE__, irq, irq);
+#endif
+}
+
+
+#if defined( CONFIG_BOARD_UC5272 )
+ 
+asm (
+	"\t.global _start, __ramend\n\t"
+	".section .romvec\n"
+"e_vectors:\n\t"
+	".long _ramend-4, _start, buserr, trap, trap, trap, trap, trap\n\t"
+	".long trap, trap, trap, trap, trap, trap, trap, trap\n\t"
+	".long trap, trap, trap, trap, trap, trap, trap, trap\n\t"
+	".long inthandler, inthandler, inthandler, inthandler\n\t"
+	".long inthandler, inthandler, inthandler, inthandler\n\t"
+	/* TRAP #0-15 */
+	".long system_call, trap, trap, trap, trap, trap, trap, trap\n\t"
+	".long trap, trap, trap, trap, trap, trap, trap, trap\n\t"
+	".long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n\t"
+	".text\n"
+"ignore: rte\n"
+);
+#endif /* CONFIG_BOARD_UC5272 */
+
+
+
+/*
+ * void init_IRQ(void)
+ *
+ * Parameters:	None
+ *
+ * Returns:	Nothing
+ *
+ * This function should be called during kernel startup to initialize
+ * the IRQ handling routines.
+ */
+
+void init_IRQ(void)
+{
+	int i;
+	
+
+	for (i = 0; i < SYS_IRQS; i++) {
+		if (mach_default_handler)
+			irq_list[i].handler = (*mach_default_handler)[i];
+		else
+			irq_list[i].handler = default_irq_handler;
+		irq_list[i].flags   = IRQ_FLG_STD;
+		irq_list[i].dev_id  = NULL;
+		irq_list[i].devname = NULL;
+		std_vec_list[i] = NULL;
+	}
+
+	if (mach_init_IRQ)
+		mach_init_IRQ ();
+	mach_kstat_irqs = &kstat.irqs[0][0];
+	memset(pool, 0, sizeof(pool));
+}
+
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                unsigned long flags, const char *devname, void *dev_id)
+{
+	struct irq_node *action = NULL;
+	struct irq_node *cur = std_vec_list[irq];
+
+	if(dev_id == NULL)
+		printk("Bad boy: %s (at 0x%p) called %s without a dev_id!\n",
+				devname, handler, __FUNCTION__);
+#if DAVIDM
+	if ((irq & IRQ_MACHSPEC) && mach_request_irq) {
+		return mach_request_irq(IRQ_IDX(irq), handler, flags,
+			devname, dev_id);
+	}
+#endif
+
+	if (irq < 0 || irq >= NR_IRQS) {
+		printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__,
+			irq, devname);
+		return -ENXIO;
+	}
+#if KGH
+	if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
+		if (irq_list[irq].flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+	}
+#endif
+	if(flags & (IRQ_FLG_LOCK | IRQ_FLG_REPLACE))
+	{
+		printk("%s: Coldfire does not support the IRQ_FLG_LOCK or "
+				"IRQ_FLG_REPLACE flags.\n",
+				__FUNCTION__);
+		printk("%s: At least one of these flags was requested for "
+				"%s.\n", __FUNCTION__, devname);
+		flags &= (~(IRQ_FLG_LOCK | IRQ_FLG_REPLACE));
+	}
+
+	/* Check if the interrupt is busy */
+	if(irq_list[irq].devname)
+		return(-EBUSY);
+
+	/* If it is a fast intterrupt, these cannot be chained */
+	if (flags & IRQ_FLG_FAST) {
+		extern asmlinkage void fasthandler(void);
+		extern void set_evector(int vecnum, void (*handler)(void));
+		/* A standard interrupt uses this interrupt already */
+		if(std_vec_list[irq])
+			return(-EBUSY);
+		set_evector(irq, fasthandler);
+		irq_list[irq].handler = handler;
+		irq_list[irq].flags   = flags;
+		irq_list[irq].dev_id  = dev_id;
+		irq_list[irq].devname = devname;
+		return 0;
+	}
+
+	if(cur)
+	{
+		/* This checking stuff was taken from i386 interrupt setup */
+		/* Can't share interrupts unless both agree to */
+		if(!(cur->flags & flags & SA_SHIRQ))
+			return(-EBUSY);
+
+		/* Can't share interrupts unless both are same type */
+		if((cur->flags ^ flags) & SA_INTERRUPT)
+			return(-EBUSY);
+	}
+	action = get_irq_node();
+
+	if(!action)
+		return(-ENOMEM);
+
+	action->handler = handler;
+	action->flags = flags;
+	action->dev_id = dev_id;
+	action->devname = devname;
+	action->next = NULL;
+	if(std_vec_list[irq])
+	{
+		struct irq_node *p = std_vec_list[irq];
+		while(p->next)
+			p = p->next;
+		p->next = action;
+	}
+	else
+	{
+		std_vec_list[irq] = action;
+	}
+	return 0;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	struct irq_node *p = std_vec_list[irq];
+#if DAVIDM
+	if (irq & IRQ_MACHSPEC) {
+		mach_free_irq(IRQ_IDX(irq), dev_id);
+		return;
+	}
+#endif
+
+	if (irq < 0 || irq >= NR_IRQS) {
+		printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	/* It was a fast interrupt */
+	if(irq_list[irq].devname)
+	{
+		if (irq_list[irq].dev_id != dev_id)
+			printk("%s: Removing probably wrong IRQ %d from %s\n",
+					__FUNCTION__, irq,
+					irq_list[irq].devname);
+
+		if (irq_list[irq].flags & IRQ_FLG_FAST) {
+			extern asmlinkage void inthandler(void);
+			extern void set_evector(int vecnum, void (*handler)(void));
+			set_evector(irq, inthandler);
+			if (mach_default_handler)
+				irq_list[irq].handler =
+					(*mach_default_handler)[irq];
+			else
+				irq_list[irq].handler = default_irq_handler;
+			irq_list[irq].flags   = IRQ_FLG_STD;
+			irq_list[irq].dev_id  = NULL;
+			irq_list[irq].devname = NULL;
+			return;
+		}
+	}
+
+	while(p && (p->dev_id != dev_id))
+		p = p->next;
+	if(!p)
+	{
+		printk("%s: Tried to remove wrong IRQ %d.\n",
+				__FUNCTION__, irq);
+		return;
+	}
+	if(p == std_vec_list[irq])
+	{
+		std_vec_list[irq] = p->next;
+	}
+	else
+	{
+		struct irq_node *q = std_vec_list[irq];
+		while(q->next != p)
+			q = q->next;
+		q->next = p->next;
+	}
+	/* Release the irq node for get irq node */
+	memset(p, 0, sizeof(struct irq_node));
+	return;
+}
+
+#if 0
+int sys_request_irq(unsigned int irq, 
+                    void (*handler)(int, void *, struct pt_regs *), 
+                    unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq < IRQ1 || irq > IRQ7) {
+		printk("%s: Incorrect IRQ %d from %s\n",
+		       __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+#if 0
+	if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
+		if (irq_list[irq].flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+		if (!(flags & IRQ_FLG_REPLACE)) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+	}
+#endif
+
+	irq_list[irq].handler = handler;
+	irq_list[irq].flags   = flags;
+	irq_list[irq].dev_id  = dev_id;
+	irq_list[irq].devname = devname;
+	return 0;
+}
+
+void sys_free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq < IRQ1 || irq > IRQ7) {
+		printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (irq_list[irq].dev_id != dev_id)
+		printk("%s: Removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, irq_list[irq].devname);
+
+	irq_list[irq].handler = (*mach_default_handler)[irq];
+	irq_list[irq].flags   = 0;
+	irq_list[irq].dev_id  = NULL;
+	// irq_list[irq].devname = default_names[irq];
+}
+#endif
+
+/*
+ * Do we need these probe functions on the m68k?
+ *
+ *  ... may be usefull with ISA devices
+ */
+unsigned long probe_irq_on (void)
+{
+	return 0;
+}
+
+int probe_irq_off (unsigned long irqs)
+{
+	return 0;
+}
+
+asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
+{
+	if(std_vec_list[vec])
+	{
+		struct irq_node *p = std_vec_list[vec];
+
+		while(p)
+		{
+			p->handler(vec, p->dev_id, fp);
+			p = p->next;
+		}
+	}
+	else
+	{
+		++num_spurious;
+		printk("Spurious interrupt %d\n", num_spurious);
+	}
+}
+
+
+int get_irq_list(char *buf)
+{
+	int i, len = 0;
+
+	for (i = 0; i < NR_IRQS; ++i)
+	{
+		if(irq_list[i].devname)
+		{
+			len += sprintf(buf+len, "%3d: %10u F ", i,
+					i ? kstat.irqs[0][i] : num_spurious);
+			len += sprintf(buf+len, "%s\n", irq_list[i].devname);
+		}
+		if(std_vec_list[i])
+		{
+			struct irq_node *p = std_vec_list[i];
+			len += sprintf(buf+len, "%3d: %10u   ", i,
+					i ? kstat.irqs[0][i] : num_spurious);
+			len += sprintf(buf+len, "%s", p->devname);
+			p = p->next;
+			while(p)
+			{
+				len+=sprintf(buf+len, ",%s", p->devname);
+				p = p->next;
+			}
+			len += sprintf(buf+len, "\n");
+		}
+	}
+	return len;
+}
+
+struct irq_node *get_irq_node(void)
+{
+	size_t i;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	for(i = 0; i < POOL_SIZE; ++i)
+	{
+		if(pool[i].devname == NULL)
+		{
+			pool[i].devname = (void *)0xffffffff;
+			restore_flags(flags);
+			return(&pool[i]);
+		}
+	}
+	restore_flags(flags);
+	printk("%s(%s:%d): No more irq nodes, I suggest you increase POOL_SIZE",
+			__FUNCTION__, __FILE__, __LINE__);
+	return(NULL);
+}
+
+void init_irq_proc(void);
+void init_irq_proc(void)
+{
+	/* Insert /proc/irq driver here */
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/5307/Makefile
--- linux-2.4.29/arch/m68knommu/platform/5307/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,43 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+ifdef CONFIG_FULLDEBUG
+	AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+#
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# AFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o ints.o bios32.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
+
+entry.o: entry.S m68k_defs.h
+
+m68k_defs.h: ../../kernel/m68k_defs.c ../../kernel/m68k_defs.head
+	rm -f m68k_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/m68k_defs.c
+	cp ../../kernel/m68k_defs.head m68k_defs.h
+	grep '^#define' m68k_defs.s >> m68k_defs.h
+	rm m68k_defs.s
+-include m68k_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/MOTOROLA/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5307/MOTOROLA/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5307/MOTOROLA/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/MOTOROLA/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,214 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5307C3 MOTOROLA ColdFire board.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ * 	Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+#include "asm/nettel.h"
+
+/*****************************************************************************/
+
+/*
+ *	Generic board memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Make region ROM cachable (turn off for flash programming?)
+	 */
+	/* 0xff000000 - 0xffffffff */
+#ifdef DEBUGGER_COMPATIBLE_CACHE
+	move.l	#(0xff<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WTHRU+ACR_WPROTECT, %d0
+#else
+	move.l	#(0xff<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WBACK+ACR_WPROTECT, %d0
+#endif
+	movec  %d0, %ACR0
+
+	/*
+	 *	Make region RAM cachable.
+	 *
+	/* 0x00000000 - 0x00ffffffff */
+#ifdef DEBUGGER_COMPATIBLE_CACHE
+	move.l	#(0x00<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WTHRU,%d0
+#else
+	move.l	#(0x00<<ACR_BASE_POS)+(0<<ACR_MASK_POS)+ACR_ENABLE+ACR_ANY+ACR_CM_WBACK,%d0
+#endif
+	movec  %d0, %ACR1
+
+	/*
+	 *	Make the default cache mode precise.
+	 */
+	move.l	#CACR_EC+CACR_ESB+CACR_DCM_OFF_PRE, %d0 /* enable cache */
+	movec	%d0, %CACR
+	nop
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union ,%a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/MOTOROLA/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5307/MOTOROLA/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5307/MOTOROLA/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/MOTOROLA/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,65 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0x007E0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+			*(.rodata.str1.1)
+		. = ALIGN(0x4) ;
+			*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+			*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+			*(.text.init)
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		. = ALIGN(4) ;
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/MP3/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5307/MP3/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5307/MP3/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/MP3/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,173 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5307 ColdFire based MP3.
+ *
+ *	(C) Copyright 1999-2001, Greg Ungerer.
+ * 	Copyright (C) 2000-2001  Lineo Inc. (www.lineo.com) 
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+#include "asm/nettel.h"
+
+/*****************************************************************************/
+
+/*
+ *	Lineo NETtel board memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#if defined(CONFIG_RAM16MB)
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+#else
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 *	Disable watchdog timer.
+	 */
+	move.l	#MCF_MBAR, %a0			/* Get MBAR address */
+	clr.l	%d0				/* Disable SWT */
+	move.b	%d0, MCFSIM_SYPCR(%a0)
+	move.b	#0x55, %d0			/* Clear SWT as well */
+	move.b	%d0, MCFSIM_SWSR(%a0)
+	move.b	#0xaa, %d0
+	move.b	%d0, MCFSIM_SWSR(%a0)
+	move.l	#0xffffffff, %d0		/* Mask out all interrupts */
+	move.l	%d0, MCFSIM_IMR(%a0)
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* invalidate whole cache */
+	movec	%d0,%CACR
+	nop
+
+	/* MUST be write-through for DMA to work... */
+	/* This also makes this debugger safe */
+	move.l	#0x0000c000, %d0		/* Set SDRAM cached only */
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR1
+
+	/* Enable cache */
+	move.l	#0xa0000200, %d0
+	movec	%d0,%CACR
+	nop
+
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+	move.l	8(%a0), %d0			/* Get size of ROMFS */
+	addq.l	#8, %d0				/* Allow for rounding */
+	and.l	#0xfffffffc, %d0		/* Whole words */
+
+	add.l	%d0, %a0			/* Copy from end */
+	add.l	%d0, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+	/*
+	 * load the current task pointer and stack
+	 */
+	lea		init_task_union,%a0
+	movel	%a0, _current_task
+	lea		0x2000(%a0),%sp
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/MP3/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5307/MP3/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5307/MP3/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/MP3/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,65 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x400, LENGTH = 0x1000000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+			*(.rodata.str1.1)
+		. = ALIGN(0x4) ;
+			*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+			*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+			*(.text.init)
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = . ;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/NETtel/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5307/NETtel/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5307/NETtel/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/NETtel/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,245 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for MCF5307 ColdFire based NETtel.
+ *
+ *	(C) Copyright 1999, Greg Ungerer.
+ * 	Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+#include "asm/nettel.h"
+
+/*****************************************************************************/
+
+/*
+ *	Lineo NETtel board memory setup.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#if defined(CONFIG_RAM16MB)
+#define	MEM_SIZE	0x01000000	/* Memory size 16Mb */
+#elif defined(CONFIG_RAM8MB)
+#define	MEM_SIZE	0x00800000	/* Memory size 8Mb */
+#else
+#define	MEM_SIZE	0x00400000	/* Memory size 4Mb */
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+/*
+ *	The NETtel platform has some funky LEDs!
+ */
+.global ppdata
+ppdata:
+.short	0x0000
+
+.global ledbank
+ledbank:
+.byte	0xff
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 *	Set LEDs to known startup state.
+	 */
+	move.l	#NETtel_LEDADDR, %a5		/* Addr of LED bank */
+	move.b	#0xff, (%a5)			/* Turn them all off */
+
+
+	/*
+	 *	Disable watchdog timer.
+	 */
+	move.l	#MCF_MBAR, %a0			/* Get MBAR address */
+	clr.l	%d0				/* Disable SWT */
+	move.b	%d0, MCFSIM_SYPCR(%a0)
+	move.b	#0x55, %d0			/* Clear SWT as well */
+	move.b	%d0, MCFSIM_SWSR(%a0)
+	move.b	#0xaa, %d0
+	move.b	%d0, MCFSIM_SWSR(%a0)
+	move.l	#0xffffffff, %d0		/* Mask out all interrupts */
+	move.l	%d0, MCFSIM_IMR(%a0)
+
+	/*
+	 * Setup VBR here, otherwise buserror remap will not work.
+	 * if dBug was active before (on my SBC with dBug 1.1 of Dec 16 1996)
+	 *
+	 * bkr@cut.de 19990306
+	 *
+	 * Note: this is because dBUG points VBR to ROM, making vectors read
+	 * only, so the bus trap can't be changed. (RS)
+	 */
+	move.l	#VBR_BASE, %a7			/* Note VBR can't be read */
+	movec   %a7, %VBR
+	move.l	%a7, _ramvec			/* Set up vector addr */
+	move.l	%a7, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01000000, %d0		/* invalidate whole cache */
+	movec	%d0,%CACR
+	nop
+#ifdef DEBUGGER_COMPATIBLE_CACHE
+	move.l	#0x0000c000, %d0		/* Set SDRAM cached only */
+#else
+	move.l	#0x0000c020, %d0		/* Set SDRAM cached only (copyback) */
+#endif
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR1
+
+	/* Enable cache */
+	move.l	#0xa0000200, %d0
+	movec	%d0,%CACR
+	nop
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/NETtel/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5307/NETtel/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5307/NETtel/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/NETtel/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,65 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x400, LENGTH = 0x400000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+			*(.rodata.str1.1)
+		. = ALIGN(0x4) ;
+			*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+			*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+			*(.text.init)
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		. = ALIGN(4) ;
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/Rules.make linux-2.4.29-uc1/arch/m68knommu/platform/5307/Rules.make
--- linux-2.4.29/arch/m68knommu/platform/5307/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/Rules.make	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,40 @@
+#
+# 5307/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1999 by Greg Ungerer (gerg@snapgear.com)
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uClinux.org>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+# Copyright (C) 2000  Lineo Inc. (www.lineo.com)
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/m5307/libgcc.a
+
+CFLAGS := -fno-builtin -nostdinc $(CFLAGS) -I$(INCGCC) -pipe -DNO_MM -DNO_FPU -m5307 -Wa,-S -Wa,-m5307 -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME=\"uClinux\" -D__linux__
+AFLAGS := $(CFLAGS)
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+            arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f arch/$(ARCH)/platform/$(PLATFORM)/m68k_defs.h
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5307/signal.c linux-2.4.29-uc1/arch/m68knommu/platform/5307/signal.c
--- linux-2.4.29/arch/m68knommu/platform/5307/signal.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5307/signal.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,1276 @@
+/*
+ *  linux/arch/m68k/kernel/signal.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * Linux/m68k support by Hamish Macdonald
+ *
+ * 68060 fixes by Jesper Skov
+ *
+ * 1997-12-01  Modified for POSIX.1b signals by Andreas Schwab
+ *
+ * mathemu support by Roman Zippel
+ *  (Note: fpstate in the signal context is completly ignored for the emulator
+ *         and the internal floating point format is put on stack)
+ */
+
+/*
+ * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
+ * Atari :-) Current limitation: Only one sigstack can be active at one time.
+ * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
+ * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
+ * signal handlers!
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/highuid.h>
+#include <linux/personality.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/traps.h>
+#include <asm/ucontext.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage long sys_wait4(pid_t pid, unsigned int * stat_addr, int options,
+			struct rusage * ru);
+
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
+
+#ifndef CONFIG_COLDFIRE
+const int frame_extra_sizes[16] = {
+  0,
+  -1, /* sizeof(((struct frame *)0)->un.fmt1), */
+  sizeof(((struct frame *)0)->un.fmt2),
+  sizeof(((struct frame *)0)->un.fmt3),
+  sizeof(((struct frame *)0)->un.fmt4),
+  -1, /* sizeof(((struct frame *)0)->un.fmt5), */
+  -1, /* sizeof(((struct frame *)0)->un.fmt6), */
+  sizeof(((struct frame *)0)->un.fmt7),
+  -1, /* sizeof(((struct frame *)0)->un.fmt8), */
+  sizeof(((struct frame *)0)->un.fmt9),
+  sizeof(((struct frame *)0)->un.fmta),
+  sizeof(((struct frame *)0)->un.fmtb),
+  -1, /* sizeof(((struct frame *)0)->un.fmtc), */
+  -1, /* sizeof(((struct frame *)0)->un.fmtd), */
+  -1, /* sizeof(((struct frame *)0)->un.fmte), */
+  -1, /* sizeof(((struct frame *)0)->un.fmtf), */
+};
+#endif
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int do_sigsuspend(struct pt_regs *regs)
+{
+	old_sigset_t mask = regs->d3;
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->d0 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+do_rt_sigsuspend(struct pt_regs *regs)
+{
+	sigset_t *unewset = (sigset_t *)regs->d1;
+	size_t sigsetsize = (size_t)regs->d2;
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->d0 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int 
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+{
+	return do_sigaltstack(uss, uoss, rdusp());
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ *
+ * Keep the return code on the stack quadword aligned!
+ * That makes the cache flush below easier.
+ */
+
+struct sigframe
+{
+	char *pretcode;
+	int sig;
+	int code;
+	struct sigcontext *psc;
+	char retcode[12];
+	unsigned long extramask[_NSIG_WORDS-1];
+	struct sigcontext sc;
+};
+
+struct rt_sigframe
+{
+	char *pretcode;
+	int sig;
+	struct siginfo *pinfo;
+	void *puc;
+#ifndef CONFIG_COLDFIRE
+	char retcode[12];
+#else
+	char retcode[16];		/* extended since notb doesn't exist on ColdFire */
+#endif
+	struct siginfo info;
+	struct ucontext uc;
+};
+
+
+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
+{
+	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+		return -EFAULT;
+	if (from->si_code < 0)
+		return __copy_to_user(to, from, sizeof(siginfo_t));
+	else {
+		int err;
+
+		/* If you change siginfo_t structure, please be sure
+		   this code is fixed accordingly.
+		   It should never copy any pad contained in the structure
+		   to avoid security leaks, but must copy the generic
+		   3 ints plus the relevant union member.  */
+		err = __put_user(from->si_signo, &to->si_signo);
+		err |= __put_user(from->si_errno, &to->si_errno);
+		err |= __put_user((short)from->si_code, &to->si_code);
+		/* First 32bits of unions are always present.  */
+		err |= __put_user(from->si_pid, &to->si_pid);
+		switch (from->si_code >> 16) {
+		case __SI_FAULT >> 16:
+			break;
+		case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+			err |= __put_user(from->si_status, &to->si_status);
+		default:
+			err |= __put_user(from->si_uid, &to->si_uid);
+			break;
+		/* case __SI_RT: This is not generated by the kernel as of now.  */
+		}
+		return err;
+	}
+}
+
+#ifndef NO_FPU
+
+static unsigned char fpu_version = 0;	/* version number of fpu, set by setup_frame */
+
+static inline int restore_fpu_state(struct sigcontext *sc)
+{
+	int err = 1;
+
+	if (FPU_IS_EMU) {
+	    /* restore registers */
+	    memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
+	    memcpy(current->thread.fp, sc->sc_fpregs, 24);
+	    return 0;
+	}
+
+	if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
+	    /* Verify the frame format.  */
+	    if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version))
+		goto out;
+	    if (CPU_IS_020_OR_030) {
+		if (m68k_fputype & FPU_68881 &&
+		    !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4))
+		    goto out;
+		if (m68k_fputype & FPU_68882 &&
+		    !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4))
+		    goto out;
+	    } else if (CPU_IS_040) {
+		if (!(sc->sc_fpstate[1] == 0x00 ||
+                      sc->sc_fpstate[1] == 0x28 ||
+                      sc->sc_fpstate[1] == 0x60))
+		    goto out;
+	    } else if (CPU_IS_060) {
+		if (!(sc->sc_fpstate[3] == 0x00 ||
+                      sc->sc_fpstate[3] == 0x60 ||
+		      sc->sc_fpstate[3] == 0xe0))
+		    goto out;
+	    } else
+		goto out;
+
+	    __asm__ volatile (".chip 68k/68881\n\t"
+			      "fmovemx %0,%/fp0-%/fp1\n\t"
+			      "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t"
+			      ".chip 68k"
+			      : /* no outputs */
+			      : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl));
+	}
+	__asm__ volatile (".chip 68k/68881\n\t"
+			  "frestore %0\n\t"
+			  ".chip 68k" : : "m" (*sc->sc_fpstate));
+	err = 0;
+
+out:
+	return err;
+}
+
+#define FPCONTEXT_SIZE	216
+#define uc_fpstate	uc_filler[0]
+#define uc_formatvec	uc_filler[FPCONTEXT_SIZE/4]
+#define uc_extra	uc_filler[FPCONTEXT_SIZE/4+1]
+
+static inline int rt_restore_fpu_state(struct ucontext *uc)
+{
+	unsigned char fpstate[FPCONTEXT_SIZE];
+	int context_size = CPU_IS_060 ? 8 : 0;
+	fpregset_t fpregs;
+	int err = 1;
+
+	if (FPU_IS_EMU) {
+		/* restore fpu control register */
+		if (__copy_from_user(current->thread.fpcntl,
+				&uc->uc_mcontext.fpregs.f_pcr, 12))
+			goto out;
+		/* restore all other fpu register */
+		if (__copy_from_user(current->thread.fp,
+				uc->uc_mcontext.fpregs.f_fpregs, 96))
+			goto out;
+		return 0;
+	}
+
+	if (__get_user(*(long *)fpstate, (long *)&uc->uc_fpstate))
+		goto out;
+	if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
+		if (!CPU_IS_060)
+			context_size = fpstate[1];
+		/* Verify the frame format.  */
+		if (!CPU_IS_060 && (fpstate[0] != fpu_version))
+			goto out;
+		if (CPU_IS_020_OR_030) {
+			if (m68k_fputype & FPU_68881 &&
+			    !(context_size == 0x18 || context_size == 0xb4))
+				goto out;
+			if (m68k_fputype & FPU_68882 &&
+			    !(context_size == 0x38 || context_size == 0xd4))
+				goto out;
+		} else if (CPU_IS_040) {
+			if (!(context_size == 0x00 ||
+			      context_size == 0x28 ||
+			      context_size == 0x60))
+				goto out;
+		} else if (CPU_IS_060) {
+			if (!(fpstate[3] == 0x00 ||
+			      fpstate[3] == 0x60 ||
+			      fpstate[3] == 0xe0))
+				goto out;
+		} else
+			goto out;
+		if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
+				     sizeof(fpregs)))
+			goto out;
+		__asm__ volatile (".chip 68k/68881\n\t"
+				  "fmovemx %0,%/fp0-%/fp7\n\t"
+				  "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t"
+				  ".chip 68k"
+				  : /* no outputs */
+				  : "m" (*fpregs.f_fpregs),
+				    "m" (fpregs.f_pcr));
+	}
+	if (context_size &&
+	    __copy_from_user(fpstate + 4, (long *)&uc->uc_fpstate + 1,
+			     context_size))
+		goto out;
+	__asm__ volatile (".chip 68k/68881\n\t"
+			  "frestore %0\n\t"
+			  ".chip 68k" : : "m" (*fpstate));
+	err = 0;
+
+out:
+	return err;
+}
+
+#endif
+
+static inline int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp,
+		   int *pd0)
+{
+#ifndef CONFIG_COLDFIRE
+	int fsize;
+#endif
+	int formatvec;
+	struct sigcontext context;
+	int err = 0;
+
+	/* get previous context */
+	if (copy_from_user(&context, usc, sizeof(context)))
+		goto badframe;
+	
+	/* restore passed registers */
+	regs->d1 = context.sc_d1;
+	regs->a0 = context.sc_a0;
+	regs->a1 = context.sc_a1;
+	regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
+	regs->pc = context.sc_pc;
+	regs->orig_d0 = -1;		/* disable syscall checks */
+	wrusp(context.sc_usp);
+	formatvec = context.sc_formatvec;
+	regs->format = formatvec >> 12;
+	regs->vector = formatvec & 0xfff;
+
+#ifndef NO_FPU
+	err = restore_fpu_state(&context);
+#endif
+
+#ifndef CONFIG_COLDFIRE /* has no extra crap */
+	fsize = frame_extra_sizes[regs->format];
+	if (fsize < 0) {
+		/*
+		 * user process trying to return with weird frame format
+		 */
+#if DEBUG
+		printk("user process returning with weird frame format\n");
+#endif
+		goto badframe;
+	}
+
+	/* OK.	Make room on the supervisor stack for the extra junk,
+	 * if necessary.
+	 */
+
+	if (fsize) {
+		struct switch_stack *sw = (struct switch_stack *)regs - 1;
+		regs->d0 = context.sc_d0;
+#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
+		__asm__ __volatile__
+			("   movel %0,%/a0\n\t"
+			 "   subl %1,%/a0\n\t"     /* make room on stack */
+			 "   movel %/a0,%/sp\n\t"  /* set stack pointer */
+			 /* move switch_stack and pt_regs */
+			 "1: movel %0@+,%/a0@+\n\t"
+			 "   dbra %2,1b\n\t"
+			 "   lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
+			 "   lsrl  #2,%1\n\t"
+			 "   subql #1,%1\n\t"
+			 "2: movesl %4@+,%2\n\t"
+			 "3: movel %2,%/a0@+\n\t"
+			 "   dbra %1,2b\n\t"
+			 "   bral " SYMBOL_NAME_STR(ret_from_signal) "\n"
+			 "4:\n"
+			 ".section __ex_table,\"a\"\n"
+			 "   .align 4\n"
+			 "   .long 2b,4b\n"
+			 "   .long 3b,4b\n"
+			 ".previous"
+			 : /* no outputs, it doesn't ever return */
+			 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
+			   "n" (frame_offset), "a" (fp)
+			 : "a0");
+#undef frame_offset
+		/*
+		 * If we ever get here an exception occurred while
+		 * building the above stack-frame.
+		 */
+		goto badframe;
+	}
+#endif /* CONFIG_COLDFIRE */
+
+	*pd0 = context.sc_d0;
+	return err;
+
+badframe:
+	return 1;
+}
+
+static inline int
+rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
+		    struct ucontext *uc, int *pd0)
+{
+#ifndef CONFIG_COLDFIRE
+	int fsize;
+#endif
+	int temp;
+	greg_t *gregs = uc->uc_mcontext.gregs;
+	unsigned long usp;
+	int err;
+
+	err = __get_user(temp, &uc->uc_mcontext.version);
+	if (temp != MCONTEXT_VERSION)
+		goto badframe;
+	/* restore passed registers */
+	err |= __get_user(regs->d0, &gregs[0]);
+	err |= __get_user(regs->d1, &gregs[1]);
+	err |= __get_user(regs->d2, &gregs[2]);
+	err |= __get_user(regs->d3, &gregs[3]);
+	err |= __get_user(regs->d4, &gregs[4]);
+	err |= __get_user(regs->d5, &gregs[5]);
+	err |= __get_user(sw->d6, &gregs[6]);
+	err |= __get_user(sw->d7, &gregs[7]);
+	err |= __get_user(regs->a0, &gregs[8]);
+	err |= __get_user(regs->a1, &gregs[9]);
+	err |= __get_user(regs->a2, &gregs[10]);
+	err |= __get_user(sw->a3, &gregs[11]);
+	err |= __get_user(sw->a4, &gregs[12]);
+	err |= __get_user(sw->a5, &gregs[13]);
+	err |= __get_user(sw->a6, &gregs[14]);
+	err |= __get_user(usp, &gregs[15]);
+	wrusp(usp);
+	err |= __get_user(regs->pc, &gregs[16]);
+	err |= __get_user(temp, &gregs[17]);
+	regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
+	regs->orig_d0 = -1;		/* disable syscall checks */
+#ifdef CONFIG_COLDFIRE
+	err |= __get_user(temp, &uc->uc_formatvec);
+#endif
+	regs->format = temp >> 12;
+	regs->vector = temp & 0xfff;
+
+#if DAVIDM /* NO_FPU */
+	err |= rt_restore_fpu_state(uc);
+#endif
+
+	if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
+		goto badframe;
+
+#ifndef CONFIG_COLDFIRE
+	fsize = frame_extra_sizes[regs->format];
+	if (fsize < 0) {
+		/*
+		 * user process trying to return with weird frame format
+		 */
+#if DEBUG
+		printk("user process returning with weird frame format\n");
+#endif
+		goto badframe;
+	}
+
+	/* OK.	Make room on the supervisor stack for the extra junk,
+	 * if necessary.
+	 */
+
+	if (fsize) {
+#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
+		__asm__ __volatile__
+			("   movel %0,%/a0\n\t"
+			 "   subl %1,%/a0\n\t"     /* make room on stack */
+			 "   movel %/a0,%/sp\n\t"  /* set stack pointer */
+			 /* move switch_stack and pt_regs */
+			 "1: movel %0@+,%/a0@+\n\t"
+			 "   dbra %2,1b\n\t"
+			 "   lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
+			 "   lsrl  #2,%1\n\t"
+			 "   subql #1,%1\n\t"
+			 "2: movesl %4@+,%2\n\t"
+			 "3: movel %2,%/a0@+\n\t"
+			 "   dbra %1,2b\n\t"
+			 "   bral " SYMBOL_NAME_STR(ret_from_signal) "\n"
+			 "4:\n"
+			 ".section __ex_table,\"a\"\n"
+			 "   .align 4\n"
+			 "   .long 2b,4b\n"
+			 "   .long 3b,4b\n"
+			 ".previous"
+			 : /* no outputs, it doesn't ever return */
+			 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
+			   "n" (frame_offset), "a" (&uc->uc_extra)
+			 : "a0");
+#undef frame_offset
+		/*
+		 * If we ever get here an exception occurred while
+		 * building the above stack-frame.
+		 */
+		goto badframe;
+	}
+#endif /* CONFIG_COLDFIRE */
+
+	*pd0 = regs->d0;
+	return err;
+
+badframe:
+	return 1;
+}
+
+asmlinkage int do_sigreturn(unsigned long __unused)
+{
+	struct switch_stack *sw = (struct switch_stack *) &__unused;
+	struct pt_regs *regs = (struct pt_regs *) (sw + 1);
+	unsigned long usp = rdusp();
+	struct sigframe *frame = (struct sigframe *)(usp - 4);
+	sigset_t set;
+	int d0;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
+	    (_NSIG_WORDS > 1 &&
+	     __copy_from_user(&set.sig[1], &frame->extramask,
+			      sizeof(frame->extramask))))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+	
+	if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0))
+		goto badframe;
+	return d0;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int do_rt_sigreturn(unsigned long __unused)
+{
+	struct switch_stack *sw = (struct switch_stack *) &__unused;
+	struct pt_regs *regs = (struct pt_regs *) (sw + 1);
+	unsigned long usp = rdusp();
+	struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
+	sigset_t set;
+	int d0;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+	
+	if (rt_restore_ucontext(regs, sw, &frame->uc, &d0))
+		goto badframe;
+	return d0;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+#ifndef NO_FPU
+/*
+ * Set up a signal frame.
+ */
+
+static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
+{
+	if (FPU_IS_EMU) {
+		/* save registers */
+		memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);
+		memcpy(sc->sc_fpregs, current->thread.fp, 24);
+		return;
+	}
+
+	__asm__ volatile (".chip 68k/68881\n\t"
+			  "fsave %0\n\t"
+			  ".chip 68k"
+			  : : "m" (*sc->sc_fpstate) : "memory");
+
+	if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
+		fpu_version = sc->sc_fpstate[0];
+		if (CPU_IS_020_OR_030 &&
+		    regs->vector >= (VEC_FPBRUC * 4) &&
+		    regs->vector <= (VEC_FPNAN * 4)) {
+			/* Clear pending exception in 68882 idle frame */
+			if (*(unsigned short *) sc->sc_fpstate == 0x1f38)
+				sc->sc_fpstate[0x38] |= 1 << 3;
+		}
+		__asm__ volatile (".chip 68k/68881\n\t"
+				  "fmovemx %/fp0-%/fp1,%0\n\t"
+				  "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t"
+				  ".chip 68k"
+				  : /* no outputs */
+				  : "m" (*sc->sc_fpregs),
+				    "m" (*sc->sc_fpcntl)
+				  : "memory");
+	}
+}
+
+static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs)
+{
+	unsigned char fpstate[FPCONTEXT_SIZE];
+	int context_size = CPU_IS_060 ? 8 : 0;
+	int err = 0;
+
+	if (FPU_IS_EMU) {
+		/* save fpu control register */
+		err |= copy_to_user(&uc->uc_mcontext.fpregs.f_pcr,
+				current->thread.fpcntl, 12);
+		/* save all other fpu register */
+		err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
+				current->thread.fp, 96);
+		return err;
+	}
+
+	__asm__ volatile (".chip 68k/68881\n\t"
+			  "fsave %0\n\t"
+			  ".chip 68k"
+			  : : "m" (*fpstate) : "memory");
+
+	err |= __put_user(*(long *)fpstate, (long *)&uc->uc_fpstate);
+	if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
+		fpregset_t fpregs;
+		if (!CPU_IS_060)
+			context_size = fpstate[1];
+		fpu_version = fpstate[0];
+		if (CPU_IS_020_OR_030 &&
+		    regs->vector >= (VEC_FPBRUC * 4) &&
+		    regs->vector <= (VEC_FPNAN * 4)) {
+			/* Clear pending exception in 68882 idle frame */
+			if (*(unsigned short *) fpstate == 0x1f38)
+				fpstate[0x38] |= 1 << 3;
+		}
+		__asm__ volatile (".chip 68k/68881\n\t"
+				  "fmovemx %/fp0-%/fp7,%0\n\t"
+				  "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t"
+				  ".chip 68k"
+				  : /* no outputs */
+				  : "m" (*fpregs.f_fpregs),
+				    "m" (fpregs.f_pcr)
+				  : "memory");
+		err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
+				    sizeof(fpregs));
+	}
+	if (context_size)
+		err |= copy_to_user((long *)&uc->uc_fpstate + 1, fpstate + 4,
+				    context_size);
+	return err;
+}
+
+#endif
+
+static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+			     unsigned long mask)
+{
+	sc->sc_mask = mask;
+	sc->sc_usp = rdusp();
+	sc->sc_d0 = regs->d0;
+	sc->sc_d1 = regs->d1;
+	sc->sc_a0 = regs->a0;
+	sc->sc_a1 = regs->a1;
+	sc->sc_sr = regs->sr;
+	sc->sc_pc = regs->pc;
+	sc->sc_formatvec = regs->format << 12 | regs->vector;
+#ifndef NO_FPU
+	save_fpu_state(sc, regs);
+#endif
+}
+
+static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
+{
+	struct switch_stack *sw = (struct switch_stack *)regs - 1;
+	greg_t *gregs = uc->uc_mcontext.gregs;
+	int err = 0;
+
+	err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
+	err |= __put_user(regs->d0, &gregs[0]);
+	err |= __put_user(regs->d1, &gregs[1]);
+	err |= __put_user(regs->d2, &gregs[2]);
+	err |= __put_user(regs->d3, &gregs[3]);
+	err |= __put_user(regs->d4, &gregs[4]);
+	err |= __put_user(regs->d5, &gregs[5]);
+	err |= __put_user(sw->d6, &gregs[6]);
+	err |= __put_user(sw->d7, &gregs[7]);
+	err |= __put_user(regs->a0, &gregs[8]);
+	err |= __put_user(regs->a1, &gregs[9]);
+	err |= __put_user(regs->a2, &gregs[10]);
+	err |= __put_user(sw->a3, &gregs[11]);
+	err |= __put_user(sw->a4, &gregs[12]);
+	err |= __put_user(sw->a5, &gregs[13]);
+	err |= __put_user(sw->a6, &gregs[14]);
+	err |= __put_user(rdusp(), &gregs[15]);
+	err |= __put_user(regs->pc, &gregs[16]);
+	err |= __put_user(regs->sr, &gregs[17]);
+#ifdef CONFIG_COLDFIRE
+	err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec);
+#endif
+#ifndef NO_FPU
+	err |= rt_save_fpu_state(uc, regs);
+#endif
+	return err;
+}
+
+static inline void push_cache (unsigned long vaddr)
+{
+#if 0 /* DAVIDM - implement this for 5407, maybe */
+	/*
+	 * Using the old cache_push_v() was really a big waste.
+	 *
+	 * What we are trying to do is to flush 8 bytes to ram.
+	 * Flushing 2 cache lines of 16 bytes is much cheaper than
+	 * flushing 1 or 2 pages, as previously done in
+	 * cache_push_v().
+	 *                                                     Jes
+	 */
+	if (CPU_IS_040) {
+		unsigned long temp;
+
+		__asm__ __volatile__ (".chip 68040\n\t"
+				      "nop\n\t"
+				      "ptestr (%1)\n\t"
+				      "movec %%mmusr,%0\n\t"
+				      ".chip 68k"
+				      : "=r" (temp)
+				      : "a" (vaddr));
+
+		temp &= PAGE_MASK;
+		temp |= vaddr & ~PAGE_MASK;
+
+		__asm__ __volatile__ (".chip 68040\n\t"
+				      "nop\n\t"
+				      "cpushl %%bc,(%0)\n\t"
+				      ".chip 68k"
+				      : : "a" (temp));
+	}
+	else if (CPU_IS_060) {
+		unsigned long temp;
+		__asm__ __volatile__ (".chip 68060\n\t"
+				      "plpar (%0)\n\t"
+				      ".chip 68k"
+				      : "=a" (temp)
+				      : "0" (vaddr));
+		__asm__ __volatile__ (".chip 68060\n\t"
+				      "cpushl %%bc,(%0)\n\t"
+				      ".chip 68k"
+				      : : "a" (temp));
+	}
+	else {
+		/*
+		 * 68030/68020 have no writeback cache;
+		 * still need to clear icache.
+		 * Note that vaddr is guaranteed to be long word aligned.
+		 */
+		unsigned long temp;
+		asm volatile ("movec %%cacr,%0" : "=r" (temp));
+		temp += 4;
+		asm volatile ("movec %0,%%caar\n\t"
+			      "movec %1,%%cacr"
+			      : : "r" (vaddr), "r" (temp));
+		asm volatile ("movec %0,%%caar\n\t"
+			      "movec %1,%%cacr"
+			      : : "r" (vaddr + 4), "r" (temp));
+	}
+#endif
+}
+
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	unsigned long usp;
+
+	/* Default to using normal stack.  */
+	usp = rdusp();
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if (ka->sa.sa_flags & SA_ONSTACK) {
+		if (!on_sig_stack(usp))
+			usp = current->sas_ss_sp + current->sas_ss_size;
+	}
+	return (void *)((usp - frame_size) & -8UL);
+}
+
+static void setup_frame (int sig, struct k_sigaction *ka,
+			 sigset_t *set, struct pt_regs *regs)
+{
+	struct sigframe *frame;
+#ifndef CONFIG_COLDFIRE
+	int fsize = frame_extra_sizes[regs->format];
+#endif
+	struct sigcontext context;
+	unsigned long a5;
+	int err = 0;
+
+#ifndef CONFIG_COLDFIRE
+	if (fsize < 0) {
+#ifdef DEBUG
+		printk ("setup_frame: Unknown frame format %#x\n",
+			regs->format);
+#endif
+		goto give_sigsegv;
+	}
+
+	frame = get_sigframe(ka, regs, sizeof(*frame) + fsize);
+
+	if (fsize) {
+		err |= copy_to_user (frame + 1, regs + 1, fsize);
+		regs->stkadj = fsize;
+	}
+#else /* ! CONFIG_COLDFIRE */
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+#endif /* ! CONFIG_COLDFIRE */
+
+	err |= __put_user((current->exec_domain
+			   && current->exec_domain->signal_invmap
+			   && sig < 32
+			   ? current->exec_domain->signal_invmap[sig]
+			   : sig),
+			  &frame->sig);
+
+	err |= __put_user(regs->vector, &frame->code);
+	err |= __put_user(&frame->sc, &frame->psc);
+
+	if (_NSIG_WORDS > 1)
+		err |= copy_to_user(frame->extramask, &set->sig[1],
+				    sizeof(frame->extramask));
+
+	setup_sigcontext(&context, regs, set->sig[0]);
+	err |= copy_to_user (&frame->sc, &context, sizeof(context));
+
+	/* Set up to return from userspace.  */
+	err |= __put_user(frame->retcode, &frame->pretcode);
+
+	/* movea.l #,a5; moveq #,d0; trap #0 */
+	a5 = ((struct switch_stack *)regs - 1)->a5;
+	err |= __put_user(0x2a7c0000 + ((a5 >> 16) & 0xffff),
+			(long *)(frame->retcode + 0));
+	err |= __put_user(0x00007000 + ((a5 & 0xffff) << 16) + __NR_sigreturn,
+			(long *)(frame->retcode + 4));
+	err |= __put_user(0x4e40, (short *)(frame->retcode + 8));
+
+	if (err)
+		goto give_sigsegv;
+
+	push_cache ((unsigned long) &frame->retcode);
+
+	/* Set up registers for signal handler */
+	wrusp ((unsigned long) frame);
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+
+    ((struct switch_stack *)regs -1)->a5 = current->mm->start_data;
+    regs->format = 0x4; /* Set format byte to make stack appear
+                   modulo 4 which it WILL be when we do the rte */
+adjust_stack:
+	/* Prepare to skip over the extra stuff in the exception frame.  */
+	if (regs->stkadj) {
+		struct pt_regs *tregs =
+			(struct pt_regs *)((ulong)regs + regs->stkadj);
+#ifdef DEBUG
+		printk("Performing stackadjust=%04x\n", regs->stkadj);
+#endif
+		/* This must be copied with decreasing addresses to
+                   handle overlaps.  */
+		tregs->vector = 0;
+		tregs->format = 0;
+		tregs->pc = regs->pc;
+		tregs->sr = regs->sr;
+	}
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+	goto adjust_stack;
+}
+
+static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
+			    sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+#ifndef CONFIG_COLDFIRE
+	int fsize = frame_extra_sizes[regs->format];
+#endif
+	unsigned long a5;
+	int err = 0;
+
+#ifndef CONFIG_COLDFIRE
+	if (fsize < 0) {
+#ifdef DEBUG
+		printk ("setup_rt_frame: Unknown frame format %#x\n",
+			regs->format);
+#endif
+		goto give_sigsegv;
+	}
+#endif
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+#ifndef CONFIG_COLDFIRE
+	if (fsize) {
+		err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);
+		regs->stkadj = fsize;
+	}
+#endif
+
+	err |= __put_user((current->exec_domain
+			   && current->exec_domain->signal_invmap
+			   && sig < 32
+			   ? current->exec_domain->signal_invmap[sig]
+			   : sig),
+			  &frame->sig);
+	err |= __put_user(&frame->info, &frame->pinfo);
+	err |= __put_user(&frame->uc, &frame->puc);
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+			  &frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(rdusp()),
+			  &frame->uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= rt_setup_ucontext(&frame->uc, regs);
+	err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	/* Set up to return from userspace.  */
+	err |= __put_user(frame->retcode, &frame->pretcode);
+
+#ifndef CONFIG_COLDFIRE /* notb is no Coldfire opcode */
+
+	/* moveq #,d0; notb d0; movea.l #,a5; trap #0 */
+	a5 = ((struct switch_stack *)regs - 1)->a5;
+	err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
+			  (long *)(frame->retcode + 0));
+	err != __put_user(0x2a7c0000 + ((a5 >> 16) & 0xffff),
+			(long *)(frame->retcode + 4));
+	err != __put_user(0x00004e40 + ((a5 & 0xffff) << 16),
+			(long *)(frame->retcode + 8));
+
+#else
+	/* moveq #,d0; andi.l #,D0 ;movea.l #,a5; trap #0 */
+	a5 = ((struct switch_stack *)regs - 1)->a5;
+	err |= __put_user(0x70AD0280,
+			  (long *)(frame->retcode + 0));
+	err |= __put_user(0x000000ff,(long *)(frame->retcode + 4));
+	err |= __put_user(0x2a7c0000 + ((a5 >> 16) & 0xffff),
+			(long *)(frame->retcode + 8));
+	err |= __put_user(0x00004e40 + ((a5 & 0xffff) << 16),
+			(long *)(frame->retcode + 12));
+#endif
+
+	if (err)
+		goto give_sigsegv;
+
+	push_cache ((unsigned long) &frame->retcode);
+
+	/* Set up registers for signal handler */
+	wrusp ((unsigned long) frame);
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+
+
+    ((struct switch_stack *)regs -1)->a5 = current->mm->start_data;
+    regs->format = 0x4; /* Set format byte to make stack appear
+                   modulo 4 which it WILL be when we do the rte */
+adjust_stack:
+	/* Prepare to skip over the extra stuff in the exception frame.  */
+	if (regs->stkadj) {
+		struct pt_regs *tregs =
+			(struct pt_regs *)((ulong)regs + regs->stkadj);
+#ifdef DEBUG
+		printk("Performing stackadjust=%04x\n", regs->stkadj);
+#endif
+		/* This must be copied with decreasing addresses to
+                   handle overlaps.  */
+		tregs->vector = 0;
+		tregs->format = 0;
+		tregs->pc = regs->pc;
+		tregs->sr = regs->sr;
+	}
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+	goto adjust_stack;
+}
+
+static inline void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
+{
+	switch (regs->d0) {
+	case -ERESTARTNOHAND:
+		if (!has_handler)
+			goto do_restart;
+		regs->d0 = -EINTR;
+		break;
+
+	case -ERESTARTSYS:
+		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
+			regs->d0 = -EINTR;
+			break;
+		}
+	/* fallthrough */
+	case -ERESTARTNOINTR:
+	do_restart:
+		regs->d0 = regs->orig_d0;
+		regs->pc -= 2;
+		break;
+	}
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static void
+handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
+	      sigset_t *oldset, struct pt_regs *regs)
+{
+	/* are we from a system call? */
+	if (regs->orig_d0 >= 0)
+		/* If so, check system call restarting.. */
+		handle_restart(regs, ka, 1);
+
+	/* set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sigmask_lock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending(current);
+		spin_unlock_irq(&current->sigmask_lock);
+	}
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals
+ * that the kernel can handle, and then we build all the user-level signal
+ * handling stack-frames in one go after that.
+ */
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
+{
+	siginfo_t info;
+	struct k_sigaction *ka;
+
+	current->thread.esp0 = (unsigned long) regs;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	for (;;) {
+		int signr;
+
+		spin_lock_irq(&current->sigmask_lock);
+		signr = dequeue_signal(&current->blocked, &info);
+		spin_unlock_irq(&current->sigmask_lock);
+
+		if (!signr)
+			break;
+
+		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			regs->sr &= ~PS_T;
+
+			/* Did we come from a system call? */
+			if (regs->orig_d0 >= 0) {
+				/* Restart the system call the same way as
+				   if the process were not traced.  */
+				struct k_sigaction *ka =
+					&current->sig->action[signr-1];
+				int has_handler =
+					(ka->sa.sa_handler != SIG_IGN &&
+					 ka->sa.sa_handler != SIG_DFL);
+				handle_restart(regs, ka, has_handler);
+			}
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code)) {
+			discard_frame:
+#ifndef CONFIG_COLDFIRE
+			    /* Make sure that a faulted bus cycle isn't
+			       restarted (only needed on the 680[23]0).  */
+			    if (regs->format == 10 || regs->format == 11)
+				regs->stkadj = frame_extra_sizes[regs->format];
+#endif
+			    continue;
+			}
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				goto discard_frame;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD:
+			case SIGWINCH: case SIGURG:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP: {
+				struct signal_struct *sig;
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+                                sig = current->p_pptr->sig;
+                                if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags 
+& SA_NOCLDSTOP))
+                                        notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+			}
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGIOT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+#if defined(CONFIG_NETtel) || defined(CONFIG_SNAPGEAR)
+				printk("%s is core dumping at 0x%x\n", 
+						current->comm, regs->pc);
+				show_regs(regs);
+#endif
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				sig_exit(signr, exit_code, &info);
+				/* NOTREACHED */
+			}
+		}
+
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(signr, ka, &info, oldset, regs);
+		return 1;
+	}
+
+	/* Did we come from a system call? */
+	if (regs->orig_d0 >= 0)
+		/* Restart the system call - no handlers present */
+		handle_restart(regs, NULL, 0);
+
+	/* If we are about to discard some frame stuff we must copy
+	   over the remaining frame. */
+	if (regs->stkadj) {
+		struct pt_regs *tregs =
+		  (struct pt_regs *) ((ulong) regs + regs->stkadj);
+
+		/* This must be copied with decreasing addresses to
+		   handle overlaps.  */
+		tregs->vector = 0;
+		tregs->format = 0;
+		tregs->pc = regs->pc;
+		tregs->sr = regs->sr;
+	}
+	return 0;
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5407/CLEOPATRA/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5407/CLEOPATRA/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5407/CLEOPATRA/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5407/CLEOPATRA/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,200 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for Motorola 5407 eval board.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ *	(C) Copyright 2000, Lineo (www.lineo.com).
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Board setup info.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+#define	MEM_SIZE	0x01000000	/* Memory size 16 */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 *	Setup VBR as per eval board (really dBUG does this).
+	 *	These settings must match it.
+	 */
+	move.l	#VBR_BASE, %a0			/* Note VBR can't be read */
+	movec   %a0, %VBR
+	move.l	%a0, _ramvec			/* Set up vector addr */
+	move.l	%a0, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01040100, %d0		/* Invalidate whole cache */
+	movec	%d0,%CACR
+	nop
+	
+	move.l	#0x0000c000, %d0		/* DRAM cached */
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0
+	movec	%d0, %ACR1
+	move.l	#0x0000c000, %d0
+	movec	%d0, %ACR2
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR3
+
+	/* Enable cache */
+	move.l	#0xa4098400, %d0		/* Write buffer, dflt precise */
+	movec	%d0,%CACR
+	nop
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5407/CLEOPATRA/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5407/CLEOPATRA/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5407/CLEOPATRA/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5407/CLEOPATRA/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,65 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x400, LENGTH = 0x01000000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+			*(.rodata.str1.1)
+		. = ALIGN(0x4) ;
+			*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+			*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+			*(.text.init)
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		. = ALIGN(4);
+		__initcall_end = . ;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5407/config.c linux-2.4.29-uc1/arch/m68knommu/platform/5407/config.c
--- linux-2.4.29/arch/m68knommu/platform/5407/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5407/config.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,344 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/5407/config.c
+ *
+ *	Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *	Copyright (C) 2000, Lineo (www.lineo.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcftimer.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+#include <asm/delay.h>
+#include <asm/system.h>
+
+/***************************************************************************/
+
+void	coldfire_profile_init(void);
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int   dma_base_addr[MAX_DMA_CHANNELS] = {
+        MCF_MBAR + MCFDMA_BASE0,
+        MCF_MBAR + MCFDMA_BASE1,
+        MCF_MBAR + MCFDMA_BASE2,
+        MCF_MBAR + MCFDMA_BASE3,
+};
+
+unsigned int dma_device_address[MAX_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned char	*icrp;
+
+	/* Set up TIMER 1 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE1);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_CLK / 16) / HZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_TIMER1ICR);
+
+#if defined(CONFIG_CLEOPATRA)
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3;
+	request_irq(30, handler, SA_INTERRUPT, "ColdFire Timer",
+		       	(void *)timerp);
+#else
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI3;
+	request_irq(29, handler, SA_INTERRUPT, "ColdFire Timer",
+		       	(void *)timerp);
+#endif
+
+#ifdef CONFIG_HIGHPROFILE
+	coldfire_profile_init();
+#endif
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_TIMER1);
+}
+
+/***************************************************************************/
+
+unsigned long coldfire_timer_offset(void)
+{
+	volatile unsigned short *timerp;
+	unsigned long		trr, tcn, offset;
+
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE1);
+	tcn = timerp[MCFTIMER_TCN];
+	trr = timerp[MCFTIMER_TRR];
+
+	/*
+	 * If we are still in the first half of the upcount and a
+	 * timer interupt is pending, then add on a ticks worth of time.
+	 */
+	offset = ((tcn * (1000000 / HZ)) / trr);
+	if (((offset * 2) < (1000000 / HZ)) && (mcf_getipr() & MCFSIM_IMR_TIMER1))
+		offset += 1000000 / HZ;
+	return offset;	
+}
+
+/***************************************************************************/
+#ifdef CONFIG_HIGHPROFILE
+/***************************************************************************/
+
+#define	PROFILEHZ	1013
+
+/*
+ *	Use the other timer to provide high accuracy profiling info.
+ */
+
+void coldfire_profile_tick(int irq, void *dummy, struct pt_regs *regs)
+{
+	volatile unsigned char	*timerp;
+
+	/* Reset the ColdFire timer2 */
+	timerp = (volatile unsigned char *) (MCF_MBAR + MCFTIMER_BASE2);
+	timerp[MCFTIMER_TER] = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
+
+        if (!user_mode(regs)) {
+                if (prof_buffer && current->pid) {
+                        extern int _stext;
+                        unsigned long ip = instruction_pointer(regs);
+                        ip -= (unsigned long) &_stext;
+                        ip >>= prof_shift;
+                        if (ip < prof_len)
+                                prof_buffer[ip]++;
+                }
+        }
+}
+
+void coldfire_profile_init(void)
+{
+	volatile unsigned short	*timerp;
+	volatile unsigned char	*icrp;
+
+	printk("PROFILE: lodging timer2=%d as profile timer\n", PROFILEHZ);
+
+	/* Set up TIMER 2 as poll clock */
+	timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE2);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE;
+
+	timerp[MCFTIMER_TRR] = (unsigned short) ((MCF_CLK / 16) / PROFILEHZ);
+	timerp[MCFTIMER_TMR] = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_TIMER2ICR);
+
+	*icrp = MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3;
+	request_irq(31, coldfire_profile_tick, (SA_INTERRUPT | IRQ_FLG_FAST),
+		"Profile Timer", timerp);
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_TIMER2);
+}
+
+/***************************************************************************/
+#endif	/* CONFIG_HIGHPROFILE */
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	volatile unsigned char  *mbar;
+
+	if ((vec >= 25) && (vec <= 31)) {
+		mbar = (volatile unsigned char *) MCF_MBAR;
+		vec = 0x1 << (vec - 24);
+		*(mbar + MCFSIM_AVR) |= vec;
+		mcf_setimr(mcf_getimr() & ~vec);
+	}
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void __init coldfire_trap_init(void)
+{
+	int i;
+
+#ifndef ENABLE_dBUG
+	mcf_setimr(MCFSIM_IMR_MASKALL);
+#endif
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+	for (i = 33; (i <= 63); i++)
+		_ramvec[i] = trap;
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+}
+
+/***************************************************************************/
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+
+void dump(struct pt_regs *fp)
+{
+	extern unsigned int sw_usp, sw_ksp;
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk("\nCURRENT PROCESS:\n\n");
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
+			(int) current->mm->start_stack,
+			(int) (((unsigned long) current) + 2 * PAGE_SIZE));
+	}
+
+	printk("PC: %08lx\n", fp->pc);
+	printk("SR: %08lx    SP: %08lx\n", (long) fp->sr, (long) fp);
+	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+		fp->d0, fp->d1, fp->d2, fp->d3);
+	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+		fp->d4, fp->d5, fp->a0, fp->a1);
+	printk("\nUSP: %08x   KSP: %08x   TRAPFRAME: %08x\n",
+		sw_usp, sw_ksp, (unsigned int) fp);
+
+	printk("\nCODE:");
+	tp = ((unsigned char *) fp->pc) - 0x20;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nUSER STACK:");
+	tp = (unsigned char *) (sw_usp - 0x10);
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n\n");
+}
+
+/***************************************************************************/
+
+void coldfire_reset(void)
+{
+	HARD_RESET_NOW();
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+#ifdef CONFIG_BOOTPARAM
+	strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+	commandp[size-1] = 0;
+#elif defined(CONFIG_HW_CLEOPATRA)
+	/* Copy command line from FLASH to local buffer... */
+	memcpy(commandp, (char *) 0xf0004000, size);
+	commandp[size-1] = 0;
+#else
+	memset(commandp, 0, size);
+#endif
+
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+	mach_gettimeoffset = coldfire_timer_offset;
+	mach_reset = coldfire_reset;
+}
+
+/***************************************************************************/
+#ifdef TRAP_DBG_INTERRUPT
+
+asmlinkage void dbginterrupt_c(struct frame *fp)
+{
+	extern void dump(struct pt_regs *fp);
+	printk("%s(%d): BUS ERROR TRAP\n", __FILE__, __LINE__);
+        dump((struct pt_regs *) fp);
+	asm("halt");
+}
+
+#endif
+/***************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5407/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/5407/Makefile
--- linux-2.4.29/arch/m68knommu/platform/5407/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5407/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,50 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+#
+# re-use any 5307/coldfire files that we can.  Perhaps we should create
+# a coldfire directory for shared files ?
+#
+
+VPATH := $(VPATH):../5307
+
+ifdef CONFIG_FULLDEBUG
+	AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+#
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# AFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o ints.o bios32.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
+
+entry.o: entry.S m68k_defs.h
+
+m68k_defs.h: ../../kernel/m68k_defs.c ../../kernel/m68k_defs.head
+	rm -f m68k_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/m68k_defs.c
+	cp ../../kernel/m68k_defs.head m68k_defs.h
+	grep '^#define' m68k_defs.s >> m68k_defs.h
+	rm m68k_defs.s
+-include m68k_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/platform/5407/MOTOROLA/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5407/MOTOROLA/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5407/MOTOROLA/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5407/MOTOROLA/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,201 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for Motorola 5407 eval board.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ *	(C) Copyright 2000, Lineo (www.lineo.com).
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Board setup info.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+#define	MEM_SIZE	0x02000000	/* Memory size 32 */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 *	Setup VBR as per eval board (really dBUG does this).
+	 *	These settings must match it.
+	 */
+	move.l	#VBR_BASE, %a0			/* Note VBR can't be read */
+	movec   %a0, %VBR
+	move.l	%a0, _ramvec			/* Set up vector addr */
+	move.l	%a0, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01040100, %d0		/* Invalidate whole cache */
+	movec	%d0,%CACR
+	nop
+	
+	move.l	#0x000fc000, %d0		/* DRAM cached */
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0
+	movec	%d0, %ACR1
+	move.l	#0x000fc000, %d0
+	movec	%d0, %ACR2
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR3
+
+	/* Enable cache */
+	move.l	#0xb6088400, %d0		/* Enable caches */
+	movec	%d0,%CACR
+	nop
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/5407/MOTOROLA/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5407/MOTOROLA/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5407/MOTOROLA/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5407/MOTOROLA/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,65 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x20000, LENGTH = 0x007E0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+			*(.rodata.str1.1)
+		. = ALIGN(0x4) ;
+			*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+			*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+			*(.text.init)
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		. = ALIGN(4) ;
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5407/Rules.make linux-2.4.29-uc1/arch/m68knommu/platform/5407/Rules.make
--- linux-2.4.29/arch/m68knommu/platform/5407/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5407/Rules.make	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,40 @@
+#
+# 5407/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1999,2001  Greg Ungerer (gerg@snapgear.com)
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uClinux.org>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+# Copyright (C) 2000  Lineo Inc. (www.lineo.com)
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/m5307/libgcc.a
+
+CFLAGS := -fno-builtin -nostdinc $(CFLAGS) -I$(INCGCC) -pipe -DNO_MM -DNO_FPU -m5307 -Wa,-S -Wa,-m5307 -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME=\"uClinux\" -D__linux__
+AFLAGS := $(CFLAGS)
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+            arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f arch/$(ARCH)/platform/$(PLATFORM)/m68k_defs.h
+
diff -urN linux-2.4.29/arch/m68knommu/platform/5407/sed_sios/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/5407/sed_sios/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/5407/sed_sios/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5407/sed_sios/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,316 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for Motorola 5407 eval board.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com).
+ *	(C) Copyright 2000, Lineo (www.lineo.com).
+ *
+ * 	1999/02/24 Modified for the 5307 processor David W. Miller
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Board setup info.
+ */
+#define	MEM_BASE		0x00000000	/* Memory base at address 0 */
+#define	VBR_BASE		MEM_BASE	/* Vector address */
+#define MEM_SIZE		0x01000000
+#define INT_RAM_SUB_SIZE	2048
+#define INT_RAM_SIZE		4096
+#define MCF_MBAR		0x10000000
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+.global __init_begin
+.global __init_end
+.global __kernel_init_image_start
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+.section ".text.bootrom","awx"
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/* Setup internal ram as the stack and for the internalsram section */
+	move.l  #(MEM_SIZE+1),      %d0
+	move.c  %d0,            %RAMBAR0
+	move.l  #(MEM_SIZE+INT_RAM_SUB_SIZE+1), %d0
+	move.c  %d0,            %RAMBAR1
+	move.l  #(MEM_SIZE+INT_RAM_SIZE), %d0
+	move.l  %d0,    %a7
+
+	/* Setup the MBAR */
+	move.l  #(MCF_MBAR+1),  %d0
+	move.c  %d0,        %MBAR
+
+
+	/* Setup CS2 - CPLD registers */
+	move.w  #0x8000,	%d0
+	move.w  %d0,		MCF_MBAR+MCFSIM_CSAR2
+	move.w  #0x0d00,	%d0
+	move.w  %d0,		MCF_MBAR+MCFSIM_CSCR2
+	move.l  #0x00000037,	%d0
+	move.l  %d0,		MCF_MBAR+MCFSIM_CSMR2
+
+	/* Setup CS1 - External UART */
+	move.w  #0x8002,	%d0
+	move.w  %d0,		MCF_MBAR+MCFSIM_CSAR1
+	move.w  #0x0040,	%d0
+	move.w  %d0,		MCF_MBAR+MCFSIM_CSCR1
+	move.l  #0x00000037,	%d0
+	move.l  %d0,		MCF_MBAR+MCFSIM_CSMR1
+
+	/* Setup CS3 - Ethernet */
+	move.w  #0x8003,	%d0
+	move.w  %d0,		MCF_MBAR+MCFSIM_CSAR3
+	move.w  #0x0020,	%d0
+	move.w  %d0,		MCF_MBAR+MCFSIM_CSCR3
+	move.l  #0x00000037,	%d0
+	move.l  %d0,		MCF_MBAR+MCFSIM_CSMR3
+
+	/* Setup CS6 - MUX CPLD */
+	move.w	#0x8001,	%d0
+	move.w	%d0,		MCF_MBAR+MCFSIM_CSAR6
+	move.w	#0x0040,	%d0
+	move.w  %d0,		MCF_MBAR+MCFSIM_CSCR6
+	move.l  #0x00000037,	%d0
+	move.l  %d0,		MCF_MBAR+MCFSIM_CSMR6
+
+	/*
+	 *  Setup VBR as per eval board (really dBUG does this).
+	 *  These settings must match it.
+	 */
+	move.l  #VBR_BASE, %a0          /* Note VBR can't be read */
+	movec   %a0, %VBR
+	move.l  %a0, _ramvec            /* Set up vector addr */
+	move.l  %a0, _rambase           /* Set up base RAM addr */
+
+	/*
+	 *  Zero out the bss region.
+	 */
+	lea.l   _sbss,  %a0         /* Get start of bss */
+	move.l  #_ebss, %d0
+	add.l   #0x10,  %d0
+	move.l  %d0,    %a1         /* Get end of bss */
+	move.l  #0x00,  %d0
+_clear_bss:
+	move.l  %d0, (%a0)+         /* Clear each word */
+	cmp.l   %a0, %a1            /* Check if at end */
+	bne _clear_bss
+
+	/*
+	 * Setup Memory size inforamtion, do it after the copy loops. If I
+	 * do it before the copy loops, stuff gets clobbered bad
+	 */
+	move.l  #MEM_SIZE, %d0
+	move.l  %d0, _ramend                    /* Set end ram addr */
+	move.l  #VBR_BASE, %d0                  /* Note VBR can't be read */
+	move.l  %d0, _ramvec                    /* Set up vector addr */
+	move.l  %d0, _rambase                   /* Set up base RAM addr */
+	move.l  #_ebss, %d0
+	add.l   #0x10,  %d0
+	move.l  %d0,    _ramstart
+
+	move.l  #MEM_SIZE,  %a7
+
+	/*
+	 * Configure the external interrupts. Currently I use interrupt vectors
+	 * 4 and 7. Set all external interrupts to be autovectored. Set the
+	 * actual interrupt pins to generate interrupt levels 4, 3, 1. Note:
+	 * the parallel port is only used for parallel port, not alternate
+	 * functions.
+	 */
+	move.b  #0xfe,  %d0
+	move.b  %d0,    MCF_MBAR+MCFSIM_AVR
+	move.b  #0x80,  %d0
+	move.b  %d0,    MCF_MBAR+MCFSIM_IRQPAR
+
+	/*
+	 *      Enable CPU internal cache.
+	 */
+#if ENABLE_CACHE
+	move.l  #0x01040100, %d0                /* Invalidate whole cache */
+	movec   %d0,%CACR
+	nop
+	move.l  #ACR0_VAL, %d0
+	movec   %d0, %ACR0
+	move.l  #ACR1_VAL, %d0
+	movec   %d0, %ACR1
+	move.l  #ACR2_VAL, %d0
+	movec   %d0, %ACR2
+	move.l  #ACR3_VAL, %d0
+	movec   %d0, %ACR3
+
+	move.l  #CACR_VAL, %d0
+	movec   %d0,%CACR
+#endif
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+dbug:
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
+.section ".data.initvect","awx"
+	.long   0	/* Reset: Initial Stack Pointer                 - 0.  */
+	.long   _start	/* Reset: Initial Program Counter               - 1.  */
+	.long   dbug	/* Bus Error                                    - 2.  */
+	.long   dbug	/* Address Error                                - 3.  */
+	.long   dbug	/* Illegal Instruction                          - 4.  */
+	.long   dbug	/* Divide by zero                               - 5.  */
+	.long   dbug	/* CHK, CHK2 Instructions                       - 6.  */
+	.long   dbug	/* TRAPcc, TRAPV Instructions                   - 7.  */
+	.long   dbug	/* Privilege Violation                          - 8.  */
+	.long   dbug	/* Trace                                        - 9.  */
+	.long   dbug        /* Line 1010 Emulator                           - 10. */
+	.long   dbug        /* Line 1111 Emualtor                           - 11. */
+	.long   dbug        /* Harware Breakpoint                           - 12. */
+	.long   dbug        /* (Reserved for Coprocessor Protocol Violation)- 13. */
+	.long   dbug        /* Format Error                                 - 14. */
+	.long   dbug        /* Uninitialized Interrupt                      - 15. */
+	.long   dbug        /* (Unassigned, Reserver)                       - 16. */
+	.long   dbug        /* (Unassigned, Reserver)                       - 17. */
+	.long   dbug        /* (Unassigned, Reserver)                       - 18. */
+	.long   dbug        /* (Unassigned, Reserver)                       - 19. */
+	.long   dbug        /* (Unassigned, Reserver)                       - 20. */
+	.long   dbug        /* (Unassigned, Reserver)                       - 21. */
+	.long   dbug        /* (Unassigned, Reserver)                       - 22. */
+	.long   dbug        /* (Unassigned, Reserver)                       - 23. */
+	.long   dbug        /* Spurious Interrupt                           - 24. */
+	.long   dbug        /* Level 1 Interrupt Autovector                 - 25. */
+	.long   dbug        /* Level 2 Interrupt Autovector                 - 26. */
+	.long   dbug        /* Level 3 Interrupt Autovector                 - 27. */
+	.long   dbug        /* Level 4 Interrupt Autovector                 - 28. */
+	.long   dbug        /* Level 5 Interrupt Autovector                 - 29. */
+	.long   dbug        /* Level 6 Interrupt Autovector                 - 30. */
+	.long   dbug        /* Level 7 Interrupt Autovector                 - 31. */
+	.long   system_call /* dbug Instruction Vectors 0                   - 32. */
+	.long   dbug        /* Trap Instruction Vectors 1                   - 33. */
+	.long   dbug        /* Trap Instruction Vectors 2                   - 34. */
+	.long   dbug        /* Trap Instruction Vectors 3                   - 35. */
+	.long   dbug        /* Trap Instruction Vectors 4                   - 36. */
+	.long   dbug        /* Trap Instruction Vectors 5                   - 37. */
+	.long   dbug        /* Trap Instruction Vectors 6                   - 38. */
+	.long   dbug        /* Trap Instruction Vectors 7                   - 39. */
+	.long   dbug        /* Trap Instruction Vectors 8                   - 40. */
+	.long   dbug        /* Trap Instruction Vectors 9                   - 41. */
+	.long   dbug        /* Trap Instruction Vectors 10                  - 42. */
+	.long   dbug        /* Trap Instruction Vectors 11                  - 43. */
+	.long   dbug        /* Trap Instruction Vectors 12                  - 44. */
+	.long   dbug        /* Trap Instruction Vectors 13                  - 45. */
+	.long   dbug        /* Trap Instruction Vectors 14                  - 46. */
+	.long   dbug        /* Trap Instruction Vectors 15                  - 47. */
+	.long   0           /* (Reserved for Coprocessor)                   - 48. */
+	.long   0           /* (Reserved for Coprocessor)                   - 49. */
+	.long   0           /* (Reserved for Coprocessor)                   - 50. */
+	.long   0           /* (Reserved for Coprocessor)                   - 51. */
+	.long   0           /* (Reserved for Coprocessor)                   - 52. */
+	.long   0           /* (Reserved for Coprocessor)                   - 53. */
+	.long   0           /* (Reserved for Coprocessor)                   - 54. */
+	.long   0           /* (Reserved for Coprocessor)                   - 55. */
+	.long   0           /* (Reserved for Coprocessor)                   - 56. */
+	.long   0           /* (Reserved for Coprocessor)                   - 57. */
+	.long   0           /* (Reserved for Coprocessor)                   - 58. */
+	.long   0           /* (Unassigned, Reserved)                       - 59. */
+	.long   0           /* (Unassigned, Reserved)                       - 60. */
+	.long   0           /* (Unassigned, Reserved)                       - 61. */
+	.long   0           /* (Unassigned, Reserved)                       - 62. */
+	.long   0           /* (Unassigned, Reserved)                       - 63. */
+	.long   0           /* (User-Defined Vectors 1) CPM Error           - 64. */
+	.long   0           /* (User-Defined Vectors 2) CPM Parallel IO PC11- 65. */
+	.long   0           /* (User-Defined Vectors 3) CPM Parallel IO PC10- 66. */
+	.long   0           /* (User-Defined Vectors 4) CPM SMC2 / PIP      - 67. */
+	.long   0           /* (User-Defined Vectors 5) CPM SMC1            - 68. */
+	.long   0           /* (User-Defined Vectors 6) CPM SPI             - 69. */
+	.long   0           /* (User-Defined Vectors 7) CPM Parallel IO PC9 - 70. */
+	.long   0           /* (User-Defined Vectors 8) CPM Timer 4         - 71. */
+	.long   0           /* (User-Defined Vectors 9) CPM Reserved        - 72. */
+	.long   0           /* (User-Defined Vectors 10) CPM Parallel IO PC8- 73. */
+	.long   0           /* (User-Defined Vectors 11) CPM Parallel IO PC7- 74. */
+	.long   0           /* (User-Defined Vectors 12) CPM Parallel IO PC6- 75. */
+	.long   0           /* (User-Defined Vectors 13) CPM Timer 3        - 76. */
+	.long   0           /* (User-Defined Vectors 14) CPM Reserved       - 77. */
+	.long   0           /* (User-Defined Vectors 15) CPM Parallel IO PC5- 78. */
+	.long   0           /* (User-Defined Vectors 16) CPM Parallel IO PC4- 79. */
+	.long   0           /* (User-Defined Vectors 17) CPM Reserved       - 80. */
+	.long   0           /* (User-Defined Vectors 18) CPM RISC Timer Tbl - 81. */
+	.long   0           /* (User-Defined Vectors 19) CPM Timer 2        - 82. */
+	.long   0           /* (User-Defined Vectors 21) CPM Reserved       - 83. */
+	.long   0           /* (User-Defined Vectors 22) CPM IDMA2          - 84. */
+	.long   0           /* (User-Defined Vectors 23) CPM IDMA1          - 85. */
+	.long   0           /* (User-Defined Vectors 24) CPM SDMA Bus Err   - 86. */
+	.long   0           /* (User-Defined Vectors 25) CPM Parallel IO PC3- 87. */
+	.long   0           /* (User-Defined Vectors 26) CPM Parallel IO PC2- 88. */
+	.long   0           /* (User-Defined Vectors 27) CPM Timer 1        - 89. */
+	.long   0           /* (User-Defined Vectors 28) CPM Parallel IO PC1- 90. */
+	.long   0           /* (User-Defined Vectors 29) CPM SCC 4          - 91. */
+	.long   0           /* (User-Defined Vectors 30) CPM SCC 3          - 92. */
+	.long   0           /* (User-Defined Vectors 31) CPM SCC 2          - 93. */
+	.long   0           /* (User-Defined Vectors 32) CPM SCC 1          - 94. */
+	.long   0           /* (User-Defined Vectors 33) CPM Parallel IO PC0- 95. */
+	/*                  I don't think anything uses the vectors after here.   */
+	.long   0           /* (User-Defined Vectors 34)                    - 96. */
+	.long   0,0,0,0,0               /* (User-Defined Vectors 35  -  39). */
+	.long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 40  -  49). */
+	.long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 50  -  59). */
+	.long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 60  -  69). */
+	.long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 70  -  79). */
+	.long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 80  -  89). */
+	.long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 90  -  99). */
+	.long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 100 - 109). */
+	.long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 110 - 119). */
+	.long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 120 - 129). */
+	.long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 130 - 139). */
+	.long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 140 - 149). */
+	.long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 150 - 159). */
+	.long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 160 - 169). */
+	.long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 170 - 179). */
+	.long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 180 - 189). */
+	.long   0,0,0                   /* (User-Defined Vectors 190 - 192). */
diff -urN linux-2.4.29/arch/m68knommu/platform/5407/sed_sios/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/5407/sed_sios/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/5407/sed_sios/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/5407/sed_sios/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,74 @@
+MEMORY
+{
+	romvec  :ORIGIN = 0x00000000,           LENGTH = 0x400
+	ram     :ORIGIN = 0x00000400,           LENGTH = 0x00100000 - 0x400
+	/* the first 1024 bytes are reseved for the interupt vectors */
+}
+
+SECTIONS {
+	.romvec :
+	{
+		_romvec = . ;
+		__rom_start = . ;
+		*(.data.initvect)
+			. = ALIGN(4);
+	} > romvec
+
+	.text : {
+		_stext = . ;
+		*(.text.bootrom)
+			. = ALIGN(0x4) ;
+		*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+			. = ALIGN(0x4) ;
+		*(.kstrtab)
+			. = ALIGN(16);          /* Exception table    */
+		__start___ex_table = .;
+		*(__ex_table)
+			__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+			__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+		*(.data)
+			*(.data.exit)
+			. = ALIGN(0x2000) ;
+		*(.data.init_task)
+			. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+			*(.text.init)
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		. = ALIGN(4) ;
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+		*(.bss)
+			*(COMMON)
+			. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/547x/config.c linux-2.4.29-uc1/arch/m68knommu/platform/547x/config.c
--- linux-2.4.29/arch/m68knommu/platform/547x/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/547x/config.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,312 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/547x/config.c
+ *
+ *	Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcfslt.h>
+#include <asm/mcfsim.h>
+#include <asm/delay.h>
+
+/***************************************************************************/
+
+void	coldfire_profile_init(void);
+
+/***************************************************************************/
+
+void coldfire_tick(void)
+{
+	volatile struct mcfslt *sp;
+
+	/* Reset the SLT timer */
+	sp = (volatile struct mcfslt *) (MCF_MBAR + MCFSLT_TIMER0);
+	sp->ssr = MCFSLT_SSR_TE;
+}
+
+/***************************************************************************/
+
+void coldfire_timer_init(void (*handler)(int, void *, struct pt_regs *))
+{
+	volatile struct mcfslt *sp;
+	volatile unsigned char *icrp;
+	volatile unsigned int *imrp;
+
+	request_irq(64+54, handler, SA_INTERRUPT, "ColdFire Timer", sp);
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR0 + 54);
+	*icrp = MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI3;
+	imrp = (volatile unsigned int *) (MCF_MBAR + MCFSIM_IMRH);
+	*imrp &= ~(1 << (54 - 32));
+
+	/* Set up SLT TIMER0 as poll clock */
+	sp = (volatile struct mcfslt *) (MCF_MBAR + MCFSLT_TIMER0);
+	sp->scr = 0;
+
+	sp->stcnt = MCF_BUSCLK / HZ;
+	sp->scr = MCFSLT_SCR_RUN | MCFSLT_SCR_IEN | MCFSLT_SCR_TEN;
+
+#ifdef CONFIG_HIGHPROFILE
+	coldfire_profile_init();
+#endif
+}
+
+/***************************************************************************/
+
+unsigned long coldfire_timer_offset(void)
+{
+	volatile struct mcfslt *sp;
+	volatile unsigned int *ipr;
+	unsigned long trr, tcn, offset;
+
+	ipr = (volatile unsigned int *) (MCF_MBAR + MCFSIM_IPRH);
+	sp = (volatile struct mcfslt *) (MCF_MBAR + MCFSLT_TIMER0);
+	tcn = sp->scnt;
+	trr = sp->stcnt;
+
+	/*
+	 * If we are still in the first half of the upcount and a
+	 * timer interupt is pending, then add on a ticks worth of time.
+	 */
+	offset = ((tcn * (1000000 / HZ)) / trr);
+	if (((offset * 2) < (1000000 / HZ)) && (*ipr & (1 << (54 - 32))))
+		offset += 1000000 / HZ;
+	return offset;	
+}
+
+/***************************************************************************/
+#ifdef CONFIG_HIGHPROFILE
+/***************************************************************************/
+
+#define	PROFILEHZ	1013
+
+/*
+ *	Use the other timer to provide high accuracy profiling info.
+ */
+
+void coldfire_profile_tick(int irq, void *dummy, struct pt_regs *regs)
+{
+	volatile struct mcfslt *sp;
+
+	/* Reset the SLT TIMER1 */
+	sp = (volatile struct mcfslt *) (MCF_MBAR + MCFSLT_TIMER1);
+	sp->ssr = MCFSLT_SSR_TE;
+
+        if (!user_mode(regs)) {
+                if (prof_buffer && current->pid) {
+                        extern int _stext;
+                        unsigned long ip = instruction_pointer(regs);
+                        ip -= (unsigned long) &_stext;
+                        ip >>= prof_shift;
+                        if (ip < prof_len)
+                                prof_buffer[ip]++;
+                }
+        }
+}
+
+void coldfire_profile_init(void)
+{
+	volatile struct mcfslt *sp;
+	volatile unsigned char *icrp;
+	volatile unsigned int *imrp;
+
+	printk("PROFILE: lodging slice timer1=%d for profiling\n", PROFILEHZ);
+
+	request_irq(64+53, coldfire_profile_tick, (SA_INTERRUPT | IRQ_FLG_FAST),
+		"Profile Timer", sp);
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR0 + 53);
+	*icrp = MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3;
+	imrp = (volatile unsigned int *) (MCF_MBAR + MCFSIM_IMRH);
+	*imrp &= ~(1 << (53 - 32));
+
+	/* Set up SLT TIMER1 as profiler clock */
+	sp = (volatile struct mcfslt *) (MCF_MBAR + MCFSLT_TIMER1);
+	sp->scr = 0;
+
+	sp->stcnt = MCF_CLK / PROFILEHZ;
+	sp->scr = MCFSLT_SCR_RUN | MCFSLT_SCR_IEN | MCFSLT_SCR_TEN;
+}
+
+/***************************************************************************/
+#endif	/* CONFIG_HIGHPROFILE */
+/***************************************************************************/
+
+/*
+ *	Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+	/* Everything is auto-vectored on the 547x */
+}
+
+/***************************************************************************/
+
+extern e_vector	*_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+	if (vecnum >= 0 && vecnum <= 255)
+		_ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void __init coldfire_trap_init(void)
+{
+	int i;
+
+#ifndef ENABLE_dBUG
+	*((volatile unsigned int *) (MCF_MBAR + MCFSIM_IMRL)) = 0xfffffffe;
+	*((volatile unsigned int *) (MCF_MBAR + MCFSIM_IMRH)) = 0xffffffff;
+#endif
+
+	/*
+	 *	There is a common trap handler and common interrupt
+	 *	handler that handle almost every vector. We treat
+	 *	the system call and bus error special, they get their
+	 *	own first level handlers.
+	 */
+#ifndef ENABLE_dBUG
+	for (i = 3; (i <= 23); i++)
+		_ramvec[i] = trap;
+	for (i = 33; (i <= 63); i++)
+		_ramvec[i] = trap;
+#endif
+
+	for (i = 24; (i <= 30); i++)
+		_ramvec[i] = inthandler;
+#ifndef ENABLE_dBUG
+	_ramvec[31] = inthandler;  // Disables the IRQ7 button
+#endif
+
+	for (i = 64; (i < 255); i++)
+		_ramvec[i] = inthandler;
+	_ramvec[255] = 0;
+
+	_ramvec[2] = buserr;
+	_ramvec[32] = system_call;
+}
+
+/***************************************************************************/
+
+void coldfire_reset(void)
+{
+	HARD_RESET_NOW();
+}
+
+/***************************************************************************/
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+
+void dump(struct pt_regs *fp)
+{
+	extern unsigned int sw_usp, sw_ksp;
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk("\nCURRENT PROCESS:\n\n");
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
+			(int) current->mm->start_stack,
+			(int) (((unsigned long) current) + 2 * PAGE_SIZE));
+	}
+
+	printk("PC: %08lx\n", fp->pc);
+	printk("SR: %08lx    SP: %08lx\n", (long) fp->sr, (long) fp);
+	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+		fp->d0, fp->d1, fp->d2, fp->d3);
+	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+		fp->d4, fp->d5, fp->a0, fp->a1);
+	printk("\nUSP: %08x   KSP: %08x   TRAPFRAME: %08x\n",
+		sw_usp, sw_ksp, (unsigned int) fp);
+
+	printk("\nCODE:");
+	tp = ((unsigned char *) fp->pc) - 0x20;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nUSER STACK:");
+	tp = (unsigned char *) (sw_usp - 0x10);
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n\n");
+}
+
+/***************************************************************************/
+#ifdef TRAP_DBG_INTERRUPT
+
+asmlinkage void dbginterrupt_c(struct frame *fp)
+{
+	extern void dump(struct pt_regs *fp);
+	printk("%s(%d): BUS ERROR TRAP\n", __FILE__, __LINE__);
+        dump((struct pt_regs *) fp);
+	asm("halt");
+}
+
+#endif
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+#ifdef CONFIG_BOOTPARAM
+	strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+	commandp[size-1] = 0;
+#else
+	memset(commandp, 0, size);
+#endif
+
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_trap_init = coldfire_trap_init;
+	mach_reset = coldfire_reset;
+	mach_gettimeoffset = coldfire_timer_offset;
+}
+
+/***************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/547x/M5475EVB/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/547x/M5475EVB/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/547x/M5475EVB/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/547x/M5475EVB/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,198 @@
+/*****************************************************************************/
+
+/*
+ *	crt0_ram.S -- startup code for Motorola 5475 eval board.
+ *
+ *	(C) Copyright 1999-2004, Greg Ungerer (gerg@snapgear.com).
+ */
+
+/*****************************************************************************/
+
+#include "linux/autoconf.h"
+#include "asm/coldfire.h"
+#include "asm/mcfsim.h"
+
+/*****************************************************************************/
+
+/*
+ *	Board setup info.
+ */
+#define	MEM_BASE	0x00000000	/* Memory base at address 0 */
+#define	MEM_SIZE	0x02000000	/* Memory size 32MB */
+#define	VBR_BASE	MEM_BASE	/* Vector address */
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+#if CONFIG_BLK_DEV_INITRD
+/*
+ *	Setup initial RAM disk limits of using INITRD.
+ */
+.extern	initrd_start
+.extern initrd_end
+#endif
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* Filler */
+	move.w	#0x2700, %sr			/* No interrupts */
+
+	/*
+	 *	Setup VBR as per eval board (really dBUG does this).
+	 *	These settings must match it.
+	 */
+	move.l	#VBR_BASE, %a0			/* Note VBR can't be read */
+	movec   %a0, %VBR
+	move.l	%a0, _ramvec			/* Set up vector addr */
+	move.l	%a0, _rambase			/* Set up base RAM addr */
+
+
+	/*
+	 *	Determine size of RAM, then set up initial stack.
+	 */
+	move.l	#MEM_SIZE, %a0
+
+	move.l	%a0, %d0			/* Mem end addr is in a0 */
+	move.l	%d0, %sp			/* Set up initial stack ptr */
+	move.l	%d0, _ramend			/* Set end ram addr */
+
+#if 1
+	/*
+	 *	Enable CPU internal cache.
+	 */
+	move.l	#0x01040100, %d0		/* Invalidate whole cache */
+	movec	%d0,%CACR
+	nop
+	
+	move.l	#0x000fc000, %d0		/* DRAM cached */
+	movec	%d0, %ACR0
+	move.l	#0x00000000, %d0
+	movec	%d0, %ACR1
+	move.l	#0x000fc000, %d0
+	movec	%d0, %ACR2
+	move.l	#0x00000000, %d0		/* No other regions cached */
+	movec	%d0, %ACR3
+
+	/* Enable cache */
+	move.l	#0xb6088400, %d0		/* Enable caches */
+	movec	%d0,%CACR
+	nop
+#endif
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Set up destination  */
+	move.l	%a0, %a2			/* Copy of bss start */
+
+#if CONFIG_BLK_DEV_INITRD
+	move.l	%a1, %d2
+	add.l	#0xfff, %d2			/* Round ROMfs start to page */
+	and.l	#0xfffff000, %d2
+	move.l	%d2, %a1			/* Save result for later */
+#endif
+
+	move.l	8(%a0), %d1			/* Get size of ROMFS */
+	addq.l	#8, %d1				/* Allow for rounding */
+	and.l	#0xfffffffc, %d1		/* Whole words */
+
+	add.l	%d1, %a0			/* Copy from end */
+	add.l	%d1, %a1			/* Copy from end */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+_copy_romfs:
+	move.l	-(%a0), %d0			/* Copy dword */
+	move.l	%d0, -(%a1)
+	cmp.l	%a0, %a2			/* Check if at end */
+	bne	_copy_romfs
+
+#else /* !CONFIG_ROMFS_FS */
+
+	lea.l	_ebss, %a1			/* Get end of bss segment */
+	move.l	%a1, _ramstart			/* Set start of ram */
+
+#endif /* !CONFIG_ROMFS_FS */
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea.l	_sbss, %a0			/* Get start of bss */
+	lea.l	_ebss, %a1			/* Get end of bss */
+	clr.l	%d0				/* Set value */
+_clear_bss:
+	move.l	%d0, (%a0)+			/* Clear each word */
+	cmp.l	%a0, %a1			/* Check if at end */
+	bne	_clear_bss
+
+#if CONFIG_BLK_DEV_INITRD
+# if CONFIG_ROMFS_FS
+	/*
+	 *	Setup up RAMdisk info if using it.
+	 *	(Must do this after clearing the bss :-)
+	 */
+	move.l	%d2, initrd_start		/* Set up start of initrd */
+	add.l	%d1, %d2			/* Calculate end of initrd */
+	move.l	%d2, initrd_end
+
+# else /* !CONFIG_ROMFS_FS */
+
+	/*
+	 * initrd support for Coldfire currently requires romfs.
+	 * Generic initrd support requires a bootloader protocol to 
+	 * tell the kernel where the image is located.
+	 */
+	moveq.l	#0, %d2
+	move.l	%d2, initrd_start
+	move.l	%d2, initrd_end
+
+# endif /* !CONFIG_ROMFS_FS */
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* Start Linux kernel */
+
+_exit:
+	jmp	_exit				/* Should never get here */
+
+/*****************************************************************************/
diff -urN linux-2.4.29/arch/m68knommu/platform/547x/M5475EVB/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/547x/M5475EVB/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/547x/M5475EVB/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/547x/M5475EVB/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,64 @@
+
+MEMORY {
+	ram    : ORIGIN = 0x00020000, LENGTH = 0x003E0000
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		*(.text.exit)
+		*(.text.lock)
+		*(.exitcall.exit)
+		*(.rodata)
+		*(.rodata.str1.1)
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+		*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+		*(.text.init)
+		*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall.init)
+		. = ALIGN(4) ;
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/547x/m68k_defs.h linux-2.4.29-uc1/arch/m68knommu/platform/547x/m68k_defs.h
--- linux-2.4.29/arch/m68knommu/platform/547x/m68k_defs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/547x/m68k_defs.h	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+ * WARNING! This file is automatically generated - DO NOT EDIT!
+ */
+
+#define TS_MAGICKEY	0x5a5a5a5a
+#define TASK_STATE 0
+#define TASK_FLAGS 4
+#define TASK_PTRACE 24
+#define TASK_BLOCKED 766
+#define TASK_COUNTER 32
+#define TASK_SIGPENDING 8
+#define TASK_NEEDRESCHED 20
+#define TASK_THREAD 612
+#define TASK_MM 44
+#define TASK_ACTIVE_MM 80
+#define CPUSTAT_SOFTIRQ_PENDING 0
+#define CPUSTAT_LOCAL_IRQ_COUNT 4
+#define THREAD_KSP 0
+#define THREAD_USP 4
+#define THREAD_SR 8
+#define THREAD_FS 10
+#define THREAD_CRP 12
+#define THREAD_ESP0 20
+#define THREAD_FPREG 24
+#define THREAD_FPCNTL 120
+#define THREAD_FPSTATE 132
+#define PT_D0 32
+#define PT_ORIG_D0 36
+#define PT_D1 0
+#define PT_D2 4
+#define PT_D3 8
+#define PT_D4 12
+#define PT_D5 16
+#define PT_A0 20
+#define PT_A1 24
+#define PT_A2 28
+#define PT_PC 48
+#define PT_SR 46
+#define PT_VECTOR 52
+#define STAT_IRQ 5148
+#define SIGSEGV 11
+#define SEGV_MAPERR 196609
+#define SIGTRAP 5
+#define TRAP_TRACE 196610
+#define PT_PTRACED 1
+#define PT_TRACESYS 2
+#define PT_DTRACE 4
diff -urN linux-2.4.29/arch/m68knommu/platform/547x/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/547x/Makefile
--- linux-2.4.29/arch/m68knommu/platform/547x/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/547x/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,50 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+#
+# re-use any 5307/coldfire files that we can. Perhaps we should create
+# a coldfire directory for shared files?
+#
+
+VPATH := $(VPATH):../5307
+
+ifdef CONFIG_FULLDEBUG
+	AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+#
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# AFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o ints.o bios32.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
+
+entry.o: entry.S m68k_defs.h
+
+m68k_defs.h: ../../kernel/m68k_defs.c ../../kernel/m68k_defs.head
+	rm -f m68k_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/m68k_defs.c
+	cp ../../kernel/m68k_defs.head m68k_defs.h
+	grep '^#define' m68k_defs.s >> m68k_defs.h
+	rm m68k_defs.s
+-include m68k_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/platform/547x/Rules.make linux-2.4.29-uc1/arch/m68knommu/platform/547x/Rules.make
--- linux-2.4.29/arch/m68knommu/platform/547x/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/547x/Rules.make	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,40 @@
+#
+# 547x/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1999-2004  Greg Ungerer (gerg@snapgear.com)
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uClinux.org>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+# Copyright (C) 2000  Lineo Inc. (www.lineo.com)
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/m5200/libgcc.a
+
+CFLAGS := -fno-builtin -nostdinc $(CFLAGS) -I$(INCGCC) -pipe -DNO_MM -DNO_FPU -m5200 -Wa,-S -Wa,-m5200 -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME=\"uClinux\" -D__linux__
+AFLAGS := $(CFLAGS)
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+            arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f arch/$(ARCH)/platform/$(PLATFORM)/m68k_defs.h
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68328/config.c linux-2.4.29-uc1/arch/m68knommu/platform/68328/config.c
--- linux-2.4.29/arch/m68knommu/platform/68328/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68328/config.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,130 @@
+/*
+ *  linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999 D. Jeff Dionne
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * VZ Support/Fixes             Evan Stawnyczy <e@lineo.ca>
+ */
+
+#include <asm/dbg.h>
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <asm/current.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/MC68328.h>
+
+
+void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
+{
+
+#ifdef CONFIG_XCOPILOT_BUGS
+  /*
+   * The only thing I know is that CLK32 is not available on Xcopilot
+   * I have little idea about what frequency SYSCLK has on Xcopilot. 
+   * The values for prescaler and compare registers were simply 
+   * taken from the original source
+   */
+
+  /* Restart mode, Enable int, SYSCLK, Enable timer */
+  TCTL2 = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_SYSCLK | TCTL_TEN;
+  /* Set prescaler */
+  TPRER2 = 2;
+  /* Set compare register */
+  TCMP2 = 0xd7e4;
+#else
+  /* Restart mode, Enable int, 32KHz, Enable timer */
+  TCTL2 = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
+  /* Set prescaler (Divide 32KHz by 32)*/
+  TPRER2 = 31;
+  /* Set compare register  32Khz / 32 / 10 = 100 */
+  TCMP2 = 10;
+#endif
+                                                                    
+  request_irq(TMR2_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+}
+
+void BSP_tick(void)
+{
+  /* Reset Timer2 */
+  TSTAT2 &= 0;
+}
+
+unsigned long BSP_gettimeoffset (void)
+{
+  return 0;
+}
+
+void BSP_gettod (int *yearp, int *monp, int *dayp,
+		   int *hourp, int *minp, int *secp)
+{
+	*yearp = *monp = *dayp = *hourp = *minp = *secp = 0;
+}
+
+int BSP_hwclk(int op, struct hwclk_time *t)
+{
+  if (!op) {
+    /* read */
+  } else {
+    /* write */
+  }
+  return 0;
+}
+
+int BSP_set_clock_mmss (unsigned long nowtime)
+{
+#if 0
+  short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+
+  tod->second1 = real_seconds / 10;
+  tod->second2 = real_seconds % 10;
+  tod->minute1 = real_minutes / 10;
+  tod->minute2 = real_minutes % 10;
+#endif
+  return 0;
+}
+
+void BSP_reset (void)
+{
+  cli();
+  asm volatile ("
+    moveal #0x10c00000, %a0;
+    moveb #0, 0xFFFFF300;
+    moveal 0(%a0), %sp;
+    moveal 4(%a0), %a0;
+    jmp (%a0);
+    ");
+}
+
+void config_BSP(char *command, int len)
+{
+  printk("\n68328 support D. Jeff Dionne <jeff@uclinux.org>\n");
+  printk("68328 support Kenneth Albanowski <kjahds@kjshds.com>\n");
+  printk("68328/Pilot support Bernhard Kuhn <kuhn@lpr.e-technik.tu-muenchen.de>\n");
+
+  mach_sched_init      = BSP_sched_init;
+  mach_tick            = BSP_tick;
+  mach_gettimeoffset   = BSP_gettimeoffset;
+  mach_gettod          = BSP_gettod;
+  mach_hwclk           = NULL;
+  mach_set_clock_mmss  = NULL;
+//  mach_mksound         = NULL;
+  mach_reset           = BSP_reset;
+//  mach_debug_init      = NULL;
+
+  config_M68328_irq();
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68328/entry.S linux-2.4.29-uc1/arch/m68knommu/platform/68328/entry.S
--- linux-2.4.29/arch/m68knommu/platform/68328/entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68328/entry.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,827 @@
+/* -*- mode: asm -*-
+ *
+ *  linux/arch/m68k/kernel/entry.S
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ * Linux/m68k support by Hamish Macdonald
+ *
+ */
+
+/*
+ * entry.S  contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all interrupts
+ * and faults that can result in a task-switch.
+ *
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ *
+ */
+
+/*
+ * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so
+ *               all pointers that used to be 'current' are now entry
+ *               number 0 in the 'current_set' list.
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/errno.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/traps.h>
+
+#include "m68k_defs.h"
+
+#define IMMED #
+#define DBG_PUTC(x) moveb IMMED x,0xfffff907; \
+					moveb IMMED '\r',0xfffff907; \
+					moveb IMMED '\n',0xfffff907
+
+.globl SYMBOL_NAME(system_call), SYMBOL_NAME(buserr), SYMBOL_NAME(trap)
+.globl SYMBOL_NAME(exception3), SYMBOL_NAME(exception4), SYMBOL_NAME(exception5)
+.globl SYMBOL_NAME(exception6), SYMBOL_NAME(exception7), SYMBOL_NAME(exception8)
+.globl SYMBOL_NAME(exception9), SYMBOL_NAME(exception10), SYMBOL_NAME(exception12)
+.globl SYMBOL_NAME(exception14), SYMBOL_NAME(exception15)
+.globl SYMBOL_NAME(trap1), SYMBOL_NAME(trap15)
+.globl SYMBOL_NAME(resume), SYMBOL_NAME(ret_from_exception)
+.globl SYMBOL_NAME(ret_from_signal)
+.globl SYMBOL_NAME(sys_call_table)
+.globl SYMBOL_NAME(sys_fork), SYMBOL_NAME(sys_clone), SYMBOL_NAME(sys_vfork)
+.globl SYMBOL_NAME(ret_from_interrupt), SYMBOL_NAME(bad_interrupt)
+.globl SYMBOL_NAME(inthandler1), SYMBOL_NAME(inthandler2),SYMBOL_NAME(inthandler3)
+.globl SYMBOL_NAME(inthandler4),SYMBOL_NAME(inthandler5),SYMBOL_NAME(inthandler6)
+.globl SYMBOL_NAME(inthandler7)
+
+.text
+ENTRY(buserr)
+	SAVE_ALL_INT 8
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(buserr_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception3)
+	SAVE_ALL_INT 12
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception4)
+	SAVE_ALL_INT 16
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception5)
+	SAVE_ALL_INT 20
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception6)
+	SAVE_ALL_INT 24
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception7)
+	SAVE_ALL_INT 28
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception8)
+	SAVE_ALL_INT 32
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception9)
+	SAVE_ALL_INT 36
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception10)
+	SAVE_ALL_INT 40
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception11)
+	SAVE_ALL_INT 44
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception14)
+	SAVE_ALL_INT 56
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception15)
+	SAVE_ALL_INT 60
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(trap1)
+	SAVE_ALL_INT 132
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(trap15)
+	SAVE_ALL_INT 188
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(reschedule)
+	/* save top of frame*/
+	movel   SYMBOL_NAME(_current_task),%a2
+	movel	%sp,%a2@(TASK_THREAD+THREAD_ESP0)
+
+	pea	SYMBOL_NAME(ret_from_exception)
+	jmp	SYMBOL_NAME(schedule)
+
+	/* After a fork we jump here directly from resume,*/
+	/* so that %d1 contains the previous task*/
+	/* Theoretically only needed on SMP, but let's watch*/
+	/* what happens in schedule_tail() in future...*/
+ENTRY(ret_from_fork)
+	movel	%d1,%sp@-
+	jsr	SYMBOL_NAME(schedule_tail)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+badsys:
+	movel	#-ENOSYS,%sp@(PT_D0)
+	jra	SYMBOL_NAME(ret_from_exception)
+
+do_trace:
+	movel	#-ENOSYS,%sp@(PT_D0)	/* needed for strace*/
+	subql	#4,%sp
+	SAVE_SWITCH_STACK
+	jbsr	SYMBOL_NAME(syscall_trace)
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+	movel	%sp@(PT_ORIG_D0),%d1
+	movel	#-ENOSYS,%d0
+	cmpl	#NR_syscalls,%d1
+	jcc	1f
+/*	jbsr	@(SYMBOL_NAME(sys_call_table),%d1:l:4)@(0) */
+	lsl	#2,%d1
+#if 1
+	lea	SYMBOL_NAME(sys_call_table), %a0
+	movel	%a0@(%d0), %a0
+	jbsr	%a0@
+#else
+	bsrw	SYMBOL_NAME(sys_call_table)@(%d1)
+#endif
+
+1:	movel	%d0,%sp@(PT_D0)		/* save the return value*/
+	subql	#4,%sp			/* dummy return address*/
+	SAVE_SWITCH_STACK
+	jbsr	SYMBOL_NAME(syscall_trace)
+
+SYMBOL_NAME_LABEL(ret_from_signal)
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(system_call)
+	SAVE_ALL_SYS 128
+
+	GET_CURRENT(%d1)
+	/* save top of frame*/
+	movel   SYMBOL_NAME(_current_task),%a2
+	movel	%sp,%a2@(TASK_THREAD+THREAD_ESP0)
+
+	btst	#PF_TRACESYS_BIT,%a2@(TASK_FLAGS+PF_TRACESYS_OFF)
+	jne	do_trace
+	cmpl	#NR_syscalls,%d0
+	jcc	badsys
+/*	jbsr	@(SYMBOL_NAME(sys_call_table),%d0:l:4)@(0) */
+	lsl	#2,%d0
+#if 1
+	lea	SYMBOL_NAME(sys_call_table),%a0
+	movel	%a0@(%d0), %a0
+	jbsr	%a0@
+#else
+	jbsr	SYMBOL_NAME(sys_call_table)@(%d0)
+#endif
+	movel	%d0,%sp@(PT_D0)		/* save the return value*/
+
+SYMBOL_NAME_LABEL(ret_from_exception)
+	btst	#5,%sp@(PT_SR)		/* check if returning to kernel*/
+	bnes	2f			/* if so, skip resched, signals*/
+	/* only allow interrupts when we are really the last one on the*/
+	/* kernel stack, otherwise stack overflow can occur during*/
+	/* heavy interupt load*/
+	andw	#ALLOWINT,%sr
+	movel   SYMBOL_NAME(_current_task),%a2
+	tstl	%a2@(TASK_NEEDRESCHED)
+	jne	SYMBOL_NAME(reschedule)
+#if 0
+	cmpl	#SYMBOL_NAME(task),%a2	/* task[0] cannot have signals*/
+	jeq	2f
+#endif
+					/* check for delayed trace*/
+	bclr	#PF_DTRACE_BIT,%a2@(TASK_FLAGS+PF_DTRACE_OFF)
+	jne	do_delayed_trace
+5:
+	tstl	%a2@(TASK_STATE)	/* state*/
+	jne	SYMBOL_NAME(reschedule)
+
+	tstl	%a2@(TASK_SIGPENDING)
+	jne	Lsignal_return
+2:	RESTORE_ALL
+
+Lsignal_return:
+	subql	#4,%sp			/* dummy return address*/
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	clrl	%sp@-
+	bsrw	SYMBOL_NAME(do_signal)
+	addql	#8,%sp
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+
+	/*
+	 * if an app is getting tricky and using "a5",  the signal handler
+	 * may trigger while "a5" is invalid,  so we have to set it here
+	 */
+	jbsr 	SYMBOL_NAME(get_pic_a5)
+	movel	%d0, %a5
+
+	RESTORE_ALL
+
+do_delayed_trace:
+	bclr	#7,%sp@(PT_SR)		/* clear trace bit in SR*/
+	pea	1			/* send SIGTRAP*/
+	movel	%a2,%sp@-
+	pea	LSIGTRAP
+	jbsr	SYMBOL_NAME(send_sig)
+	addql	#8,%sp
+	addql	#4,%sp
+	jra	5b
+/*
+** This is the main interrupt handler, responsible for calling process_int()
+*/
+SYMBOL_NAME_LABEL(inthandler1)
+	SAVE_ALL_INT 260
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	movel	%sp,%sp@-
+	movel	#65,%sp@- 		/*  put vector # on stack*/
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+SYMBOL_NAME_LABEL(inthandler2)
+	SAVE_ALL_INT 264
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	movel	%sp,%sp@-
+	movel	#66,%sp@- 		/*  put vector # on stack*/
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+SYMBOL_NAME_LABEL(inthandler3)
+	SAVE_ALL_INT 268
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	movel	%sp,%sp@-
+	movel	#67,%sp@- 		/*  put vector # on stack*/
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+SYMBOL_NAME_LABEL(inthandler4)
+	SAVE_ALL_INT 272
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	movel	%sp,%sp@-
+	movel	#68,%sp@- 		/*  put vector # on stack*/
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+SYMBOL_NAME_LABEL(inthandler5)
+	SAVE_ALL_INT 276
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	movel	%sp,%sp@-
+	movel	#69,%sp@- 		/*  put vector # on stack*/
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+SYMBOL_NAME_LABEL(inthandler6)
+	SAVE_ALL_INT 280
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	movel	%sp,%sp@-
+	movel	#70,%sp@- 		/*  put vector # on stack*/
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+SYMBOL_NAME_LABEL(inthandler7)
+	SAVE_ALL_INT 284
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	movel	%sp,%sp@-
+	movel	#71,%sp@- 		/*  put vector # on stack*/
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+#if 0
+SYMBOL_NAME_LABEL(inthandler8)
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+					/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	#72,%sp@- 		/*  put vector # on stack*/
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+SYMBOL_NAME_LABEL(timerhandler)
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+					/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	#0x40,%sp@- 		/*  put vector # on stack*/
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+SYMBOL_NAME_LABEL(serialhandler)
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+					/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	#0x42,%sp@- 		/*  put vector # on stack*/
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+SYMBOL_NAME_LABEL(inthandler_wrap)
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+					/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	%d0,%sp@- 		/*  put vector # on stack*/
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+SYMBOL_NAME_LABEL(inthandler)
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+					/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and	#0x3ff, %d0
+
+	movel	%sp,%sp@-
+	movel	%d0,%sp@- 		/*  put vector # on stack*/
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+#endif
+
+SYMBOL_NAME_LABEL(ret_from_interrupt)
+	subql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	jeq	1f
+2:
+	RESTORE_ALL
+1:
+	moveq   #(~ALLOWINT>>8)&0xff,%d0
+	andb    %sp@(PT_SR),%d0
+	jne 2b
+
+	/* check if we need to do software interrupts */
+
+	movel	SYMBOL_NAME(irq_stat)+CPUSTAT_SOFTIRQ_PENDING,%d0
+	jeq	SYMBOL_NAME(ret_from_exception)
+
+	pea	SYMBOL_NAME(ret_from_exception)
+	jra	SYMBOL_NAME(do_softirq)
+
+
+/* Handler for uninitialized and spurious interrupts */
+
+SYMBOL_NAME_LABEL(trap)
+SYMBOL_NAME_LABEL(bad_interrupt)
+	addql	#1,SYMBOL_NAME(num_spurious)
+	rte
+
+ENTRY(sys_fork)
+	SAVE_SWITCH_STACK	
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(m68k_fork)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_clone)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(m68k_clone)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_vfork)
+	SAVE_SWITCH_STACK	
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(m68k_vfork)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(do_sigsuspend)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(do_rt_sigsuspend)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_sigreturn)
+	SAVE_SWITCH_STACK
+	jbsr	SYMBOL_NAME(do_sigreturn)
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigreturn)
+	SAVE_SWITCH_STACK
+	jbsr	SYMBOL_NAME(do_rt_sigreturn)
+	RESTORE_SWITCH_STACK
+	rts
+
+SYMBOL_NAME_LABEL(resume)
+	/*
+	 * Beware - when entering resume, prev (the current task) is
+	 * in a0, next (the new task) is in a1,so don't change these
+	 * registers until their contents are no longer needed.
+	 */
+
+	/* save sr */
+	movew	%sr,%a0@(TASK_THREAD+THREAD_SR)
+#ifdef USE_SFC_DFC
+	/* save fs (sfc,%dfc) (may be pointing to kernel memory) */
+	movec	%sfc,%d0
+	movew	%d0,%a0@(TASK_THREAD+THREAD_FS)
+#endif
+
+	/* save non-scratch registers on stack */
+	SAVE_SWITCH_STACK
+
+	/* save usp */
+	/* it is better to use a movel here instead of a movew 8*) */
+	movel	%usp,%a2
+	movel	%a2,%a0@(TASK_THREAD+THREAD_USP)
+
+	/* save current kernel stack pointer */
+	movel	%sp,%a0@(TASK_THREAD+THREAD_KSP)
+
+	/* Return previous task in %d1 */
+	movel   SYMBOL_NAME(_current_task),%d1
+
+	/* switch to new task (a1 contains new task) */
+	movel   %a1, SYMBOL_NAME(_current_task)
+
+	/* restore the kernel stack pointer */
+	movel	%a1@(TASK_THREAD+THREAD_KSP),%sp
+
+	/* restore non-scratch registers */
+	RESTORE_SWITCH_STACK
+
+	/* restore user stack pointer */
+	movel	%a1@(TASK_THREAD+THREAD_USP),%a0
+	movel	%a0,%usp
+
+#ifdef USE_SFC_DFC
+	/* restore fs (sfc,%dfc) */
+	movew	%a1@(TASK_THREAD+THREAD_FS),%a0
+	movec	%a0,%sfc
+	movec	%a0,%dfc
+#endif
+	/* restore status register */
+	movew	%a1@(TASK_THREAD+THREAD_SR),%sr
+
+	rts
+
+
+.data
+ALIGN
+SYMBOL_NAME_LABEL(sys_call_table)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 0  -  old "setup()" system call*/
+	.long SYMBOL_NAME(sys_exit)
+	.long SYMBOL_NAME(sys_fork)
+	.long SYMBOL_NAME(sys_read)
+	.long SYMBOL_NAME(sys_write)
+	.long SYMBOL_NAME(sys_open)		/* 5 */
+	.long SYMBOL_NAME(sys_close)
+	.long SYMBOL_NAME(sys_waitpid)
+	.long SYMBOL_NAME(sys_creat)
+	.long SYMBOL_NAME(sys_link)
+	.long SYMBOL_NAME(sys_unlink)		/* 10 */
+	.long SYMBOL_NAME(sys_execve)
+	.long SYMBOL_NAME(sys_chdir)
+	.long SYMBOL_NAME(sys_time)
+	.long SYMBOL_NAME(sys_mknod)
+	.long SYMBOL_NAME(sys_chmod)		/* 15 */
+	.long SYMBOL_NAME(sys_chown16)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old break syscall holder */
+	.long SYMBOL_NAME(sys_stat)
+	.long SYMBOL_NAME(sys_lseek)
+	.long SYMBOL_NAME(sys_getpid)		/* 20 */
+	.long SYMBOL_NAME(sys_mount)
+	.long SYMBOL_NAME(sys_oldumount)
+	.long SYMBOL_NAME(sys_setuid16)
+	.long SYMBOL_NAME(sys_getuid16)
+	.long SYMBOL_NAME(sys_stime)		/* 25 */
+	.long SYMBOL_NAME(sys_ptrace)
+	.long SYMBOL_NAME(sys_alarm)
+	.long SYMBOL_NAME(sys_fstat)
+	.long SYMBOL_NAME(sys_pause)
+	.long SYMBOL_NAME(sys_utime)		/* 30 */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old stty syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old gtty syscall holder */
+	.long SYMBOL_NAME(sys_access)
+	.long SYMBOL_NAME(sys_nice)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 35 */		/* old ftime syscall holder */
+	.long SYMBOL_NAME(sys_sync)
+	.long SYMBOL_NAME(sys_kill)
+	.long SYMBOL_NAME(sys_rename)
+	.long SYMBOL_NAME(sys_mkdir)
+	.long SYMBOL_NAME(sys_rmdir)		/* 40 */
+	.long SYMBOL_NAME(sys_dup)
+	.long SYMBOL_NAME(sys_pipe)
+	.long SYMBOL_NAME(sys_times)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old prof syscall holder */
+	.long SYMBOL_NAME(sys_brk)		/* 45 */
+	.long SYMBOL_NAME(sys_setgid16)
+	.long SYMBOL_NAME(sys_getgid16)
+	.long SYMBOL_NAME(sys_signal)
+	.long SYMBOL_NAME(sys_geteuid16)
+	.long SYMBOL_NAME(sys_getegid16)	/* 50 */
+	.long SYMBOL_NAME(sys_acct)
+	.long SYMBOL_NAME(sys_umount)					/* recycled never used phys() */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old lock syscall holder */
+	.long SYMBOL_NAME(sys_ioctl)
+	.long SYMBOL_NAME(sys_fcntl)		/* 55 */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old mpx syscall holder */
+	.long SYMBOL_NAME(sys_setpgid)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old ulimit syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_umask)		/* 60 */
+	.long SYMBOL_NAME(sys_chroot)
+	.long SYMBOL_NAME(sys_ustat)
+	.long SYMBOL_NAME(sys_dup2)
+	.long SYMBOL_NAME(sys_getppid)
+	.long SYMBOL_NAME(sys_getpgrp)		/* 65 */
+	.long SYMBOL_NAME(sys_setsid)
+	.long SYMBOL_NAME(sys_sigaction)
+	.long SYMBOL_NAME(sys_sgetmask)
+	.long SYMBOL_NAME(sys_ssetmask)
+	.long SYMBOL_NAME(sys_setreuid16)	/* 70 */
+	.long SYMBOL_NAME(sys_setregid16)
+	.long SYMBOL_NAME(sys_sigsuspend)
+	.long SYMBOL_NAME(sys_sigpending)
+	.long SYMBOL_NAME(sys_sethostname)
+	.long SYMBOL_NAME(sys_setrlimit)	/* 75 */
+	.long SYMBOL_NAME(sys_old_getrlimit)
+	.long SYMBOL_NAME(sys_getrusage)
+	.long SYMBOL_NAME(sys_gettimeofday)
+	.long SYMBOL_NAME(sys_settimeofday)
+	.long SYMBOL_NAME(sys_getgroups16)	/* 80 */
+	.long SYMBOL_NAME(sys_setgroups16)
+	.long SYMBOL_NAME(old_select)
+	.long SYMBOL_NAME(sys_symlink)
+	.long SYMBOL_NAME(sys_lstat)
+	.long SYMBOL_NAME(sys_readlink)		/* 85 */
+	.long SYMBOL_NAME(sys_uselib)
+	.long SYMBOL_NAME(sys_swapon)
+	.long SYMBOL_NAME(sys_reboot)
+	.long SYMBOL_NAME(old_readdir)
+	.long SYMBOL_NAME(old_mmap)		/* 90 */
+	.long SYMBOL_NAME(sys_munmap)
+	.long SYMBOL_NAME(sys_truncate)
+	.long SYMBOL_NAME(sys_ftruncate)
+	.long SYMBOL_NAME(sys_fchmod)
+	.long SYMBOL_NAME(sys_fchown16)		/* 95 */
+	.long SYMBOL_NAME(sys_getpriority)
+	.long SYMBOL_NAME(sys_setpriority)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old profil syscall holder */
+	.long SYMBOL_NAME(sys_statfs)
+	.long SYMBOL_NAME(sys_fstatfs)		/* 100 */
+	.long SYMBOL_NAME(sys_ioperm)
+	.long SYMBOL_NAME(sys_socketcall)
+	.long SYMBOL_NAME(sys_syslog)
+	.long SYMBOL_NAME(sys_setitimer)
+	.long SYMBOL_NAME(sys_getitimer)	/* 105 */
+	.long SYMBOL_NAME(sys_newstat)
+	.long SYMBOL_NAME(sys_newlstat)
+	.long SYMBOL_NAME(sys_newfstat)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* iopl for i386 */ /* 110 */
+	.long SYMBOL_NAME(sys_vhangup)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* obsolete idle() syscall */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* vm86old for i386 */
+	.long SYMBOL_NAME(sys_wait4)
+	.long SYMBOL_NAME(sys_swapoff)		/* 115 */
+	.long SYMBOL_NAME(sys_sysinfo)
+	.long SYMBOL_NAME(sys_ipc)
+	.long SYMBOL_NAME(sys_fsync)
+	.long SYMBOL_NAME(sys_sigreturn)
+	.long SYMBOL_NAME(sys_clone)		/* 120 */
+	.long SYMBOL_NAME(sys_setdomainname)
+	.long SYMBOL_NAME(sys_newuname)
+	.long SYMBOL_NAME(sys_cacheflush)	/* modify_ldt for i386 */
+	.long SYMBOL_NAME(sys_adjtimex)
+	.long SYMBOL_NAME(sys_mprotect)		/* 125 */
+	.long SYMBOL_NAME(sys_sigprocmask)
+	.long SYMBOL_NAME(sys_create_module)
+	.long SYMBOL_NAME(sys_init_module)
+	.long SYMBOL_NAME(sys_delete_module)
+	.long SYMBOL_NAME(sys_get_kernel_syms)	/* 130 */
+	.long SYMBOL_NAME(sys_quotactl)
+	.long SYMBOL_NAME(sys_getpgid)
+	.long SYMBOL_NAME(sys_fchdir)
+	.long SYMBOL_NAME(sys_bdflush)
+	.long SYMBOL_NAME(sys_sysfs)		/* 135 */
+	.long SYMBOL_NAME(sys_personality)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for afs_syscall */
+	.long SYMBOL_NAME(sys_setfsuid16)
+	.long SYMBOL_NAME(sys_setfsgid16)
+	.long SYMBOL_NAME(sys_llseek)		/* 140 */
+	.long SYMBOL_NAME(sys_getdents)
+	.long SYMBOL_NAME(sys_select)
+	.long SYMBOL_NAME(sys_flock)
+	.long SYMBOL_NAME(sys_msync)
+	.long SYMBOL_NAME(sys_readv)		/* 145 */
+	.long SYMBOL_NAME(sys_writev)
+	.long SYMBOL_NAME(sys_getsid)
+	.long SYMBOL_NAME(sys_fdatasync)
+	.long SYMBOL_NAME(sys_sysctl)
+	.long SYMBOL_NAME(sys_mlock)		/* 150 */
+	.long SYMBOL_NAME(sys_munlock)
+	.long SYMBOL_NAME(sys_mlockall)
+	.long SYMBOL_NAME(sys_munlockall)
+	.long SYMBOL_NAME(sys_sched_setparam)
+	.long SYMBOL_NAME(sys_sched_getparam)   /* 155 */
+	.long SYMBOL_NAME(sys_sched_setscheduler)
+	.long SYMBOL_NAME(sys_sched_getscheduler)
+	.long SYMBOL_NAME(sys_sched_yield)
+	.long SYMBOL_NAME(sys_sched_get_priority_max)
+	.long SYMBOL_NAME(sys_sched_get_priority_min)  /* 160 */
+	.long SYMBOL_NAME(sys_sched_rr_get_interval)
+	.long SYMBOL_NAME(sys_nanosleep)
+	.long SYMBOL_NAME(sys_mremap)
+	.long SYMBOL_NAME(sys_setresuid16)
+	.long SYMBOL_NAME(sys_getresuid16)	/* 165 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for vm86 */
+	.long SYMBOL_NAME(sys_query_module)
+	.long SYMBOL_NAME(sys_poll)
+	.long SYMBOL_NAME(sys_nfsservctl)
+	.long SYMBOL_NAME(sys_setresgid16)	/* 170 */
+	.long SYMBOL_NAME(sys_getresgid16)
+	.long SYMBOL_NAME(sys_prctl)
+	.long SYMBOL_NAME(sys_rt_sigreturn)
+	.long SYMBOL_NAME(sys_rt_sigaction)
+	.long SYMBOL_NAME(sys_rt_sigprocmask)	/* 175 */
+	.long SYMBOL_NAME(sys_rt_sigpending)
+	.long SYMBOL_NAME(sys_rt_sigtimedwait)
+	.long SYMBOL_NAME(sys_rt_sigqueueinfo)
+	.long SYMBOL_NAME(sys_rt_sigsuspend)
+	.long SYMBOL_NAME(sys_pread)		/* 180 */
+	.long SYMBOL_NAME(sys_pwrite)
+	.long SYMBOL_NAME(sys_lchown16);
+	.long SYMBOL_NAME(sys_getcwd)
+	.long SYMBOL_NAME(sys_capget)
+	.long SYMBOL_NAME(sys_capset)           /* 185 */
+	.long SYMBOL_NAME(sys_sigaltstack)
+	.long SYMBOL_NAME(sys_sendfile)
+	.long SYMBOL_NAME(sys_ni_syscall)		/* streams1 */
+	.long SYMBOL_NAME(sys_ni_syscall)		/* streams2 */
+	.long SYMBOL_NAME(sys_vfork)            /* 190 */
+	.long SYMBOL_NAME(sys_getrlimit)
+	.long SYMBOL_NAME(sys_mmap2)
+	.long SYMBOL_NAME(sys_truncate64)
+	.long SYMBOL_NAME(sys_ftruncate64)
+	.long SYMBOL_NAME(sys_stat64)		/* 195 */
+	.long SYMBOL_NAME(sys_lstat64)
+	.long SYMBOL_NAME(sys_fstat64)
+	.long SYMBOL_NAME(sys_chown)
+	.long SYMBOL_NAME(sys_getuid)
+	.long SYMBOL_NAME(sys_getgid)		/* 200 */
+	.long SYMBOL_NAME(sys_geteuid)
+	.long SYMBOL_NAME(sys_getegid)
+	.long SYMBOL_NAME(sys_setreuid)
+	.long SYMBOL_NAME(sys_setregid)
+	.long SYMBOL_NAME(sys_getgroups)	/* 205 */
+	.long SYMBOL_NAME(sys_setgroups)
+	.long SYMBOL_NAME(sys_fchown)
+	.long SYMBOL_NAME(sys_setresuid)
+	.long SYMBOL_NAME(sys_getresuid)
+	.long SYMBOL_NAME(sys_setresgid)	/* 210 */
+	.long SYMBOL_NAME(sys_getresgid)
+	.long SYMBOL_NAME(sys_lchown)
+	.long SYMBOL_NAME(sys_setuid)
+	.long SYMBOL_NAME(sys_setgid)
+	.long SYMBOL_NAME(sys_setfsuid)		/* 215 */
+	.long SYMBOL_NAME(sys_setfsgid)
+	.long SYMBOL_NAME(sys_pivot_root)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
+	.long SYMBOL_NAME(sys_gettid)
+	.long SYMBOL_NAME(sys_tkill)
+	.long SYMBOL_NAME(sys_setxattr)
+	.long SYMBOL_NAME(sys_lsetxattr)
+	.long SYMBOL_NAME(sys_fsetxattr)	/* 225 */
+	.long SYMBOL_NAME(sys_getxattr)
+	.long SYMBOL_NAME(sys_lgetxattr)
+	.long SYMBOL_NAME(sys_fgetxattr)
+	.long SYMBOL_NAME(sys_listxattr)
+	.long SYMBOL_NAME(sys_llistxattr)	/* 230 */
+	.long SYMBOL_NAME(sys_flistxattr)
+	.long SYMBOL_NAME(sys_removexattr)
+	.long SYMBOL_NAME(sys_lremovexattr)
+	.long SYMBOL_NAME(sys_fremovexattr)
+
+	.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
+		.long SYMBOL_NAME(sys_ni_syscall)
+	.endr
diff -urN linux-2.4.29/arch/m68knommu/platform/68328/fixup.pl linux-2.4.29-uc1/arch/m68knommu/platform/68328/fixup.pl
--- linux-2.4.29/arch/m68knommu/platform/68328/fixup.pl	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68328/fixup.pl	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,91 @@
+#!/usr/bin/perl
+
+#
+# Nasty piece of work, designed to translated linux.bin binary image
+# in to several different formats.
+# 
+# Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>,
+#                    The Silver Hammer Group, Ltd.
+#
+
+@CRC = (
+        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+        0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+        0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+        0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+        0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
+        0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
+        0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
+        0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
+        0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
+        0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
+        0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
+        0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
+        0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+        0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
+        0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
+        0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
+        0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
+        0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
+        0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
+        0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
+        0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
+        0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+        0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
+        0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
+        0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
+        0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+        0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
+        0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
+        0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
+        0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
+        0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
+        0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
+);
+
+sub CrcBlock {
+	my($data,$crc) = @_;
+	my($i);
+	printf "Crc of %d bytes\n", length($data);
+	for ($i=0;$i<length($data);$i++) {
+#		printf "crc = %d, Lookup = %d, CRC[] = %d\n", $crc,						($crc>>8) ^
+#						ord(substr($data,$i,1)),
+#$CRC[						($crc>>8) ^
+#						ord(substr($data,$i,1)) &
+#0xff];
+#
+
+		$crc = ($crc << 8) ^ $CRC[
+						((($crc>>8) & 0xff) ^
+						ord(substr($data,$i,1))) &
+						0xff
+					];
+		$crc &= 0xffff;
+	}
+	return $crc & 0xffff;
+}
+
+open(T,"<linux.bin");
+$/ = undef;
+
+$image = join('', <T>);
+close(T);
+
+$realLength = length($image);
+$image .= "\0" x (0x100000 - $realLength);
+
+$posOfCardLength = 108;
+$posOfChecksum = 112;
+#$crc = CrcBlock(substr($image, 0, $posOfChecksum), 0);
+#$crc = CrcBlock(substr($image, $posOfChecksum+2), $crc);
+
+#substr($image, $posOfCardLength, 4) = pack("N", length($image));
+#substr($image, $posOfChecksum, 2) = pack("n", $crc);
+
+open(O,">linux.trg");
+print O substr($image, 0x10000, (($realLength - 0x10000) + 0xffff) & ~0xffff);
+close(O);
+
+open(O, ">linux.rom");
+print O $image;
+close(O);
diff -urN linux-2.4.29/arch/m68knommu/platform/68328/ints.c linux-2.4.29-uc1/arch/m68knommu/platform/68328/ints.c
--- linux-2.4.29/arch/m68knommu/platform/68328/ints.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68328/ints.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,361 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne <jeff@uclinux.org>
+ * Copyright 2000-2001 Lineo, Inc. D. Jefff Dionne <jeff@uClinux.org>
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+
+#include <asm/MC68328.h>
+
+#define INTERNAL_IRQS (32)
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void exception3(void);
+asmlinkage void exception4(void);
+asmlinkage void exception5(void);
+asmlinkage void exception6(void);
+asmlinkage void exception7(void);
+asmlinkage void exception8(void);
+asmlinkage void exception9(void);
+asmlinkage void exception10(void);
+asmlinkage void exception11(void);
+asmlinkage void exception14(void);
+asmlinkage void exception15(void);
+asmlinkage void bad_interrupt(void);
+asmlinkage void inthandler1(void);
+asmlinkage void inthandler2(void);
+asmlinkage void inthandler3(void);
+asmlinkage void inthandler4(void);
+asmlinkage void inthandler5(void);
+asmlinkage void inthandler6(void);
+asmlinkage void inthandler7(void);
+asmlinkage void system_call(void);
+asmlinkage void trap1(void);
+asmlinkage void trap15(void);
+
+extern e_vector *_ramvec;
+
+/* irq node variables for the 32 (potential) on chip sources */
+static irq_node_t *int_irq_list[INTERNAL_IRQS];
+
+static int int_irq_count[INTERNAL_IRQS];
+static short int_irq_ablecount[INTERNAL_IRQS];
+
+static void int_badint(int irq, void *dev_id, struct pt_regs *fp)
+{
+	num_spurious += 1;
+}
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the amiga IRQ handling routines.
+ */
+
+void M68328_init_IRQ(void)
+{
+	int i;
+
+        /* set up the vectors */
+        for (i=2; i < 32; ++i)
+                _ramvec[i] = bad_interrupt;
+
+        _ramvec[2] = buserr;
+        _ramvec[3] = exception3;
+        _ramvec[4] = exception4;
+        _ramvec[5] = exception5;
+        _ramvec[6] = exception6;
+        _ramvec[7] = exception7;
+        _ramvec[8] = exception8;
+        _ramvec[9] = exception9;
+        _ramvec[10] = exception10;
+        _ramvec[11] = exception11;
+        _ramvec[14] = exception14;
+        _ramvec[15] = exception15;
+        _ramvec[32] = system_call;
+        _ramvec[33] = trap1;
+        _ramvec[47] = trap15;
+
+        _ramvec[64] = bad_interrupt;
+        _ramvec[65] = inthandler1;
+        _ramvec[66] = inthandler2;
+        _ramvec[67] = inthandler3;
+        _ramvec[68] = inthandler4;
+        _ramvec[69] = inthandler5;
+        _ramvec[70] = inthandler6;
+        _ramvec[71] = inthandler7;
+ 
+	IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
+
+	/* initialize handlers */
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		int_irq_list[i] = NULL;
+
+		int_irq_ablecount[i] = 0;
+		int_irq_count[i] = 0;
+	}
+	/* turn off all interrupts */
+	*(unsigned volatile long *)0xfffff304 = 0xffffffff;
+}
+
+void M68328_insert_irq(irq_node_t **list, irq_node_t *node)
+{
+	unsigned long flags;
+	irq_node_t *cur;
+
+	if (!node->dev_id)
+		printk("%s: Warning: dev_id of %s is zero\n",
+		       __FUNCTION__, node->devname);
+
+	save_flags(flags);
+	cli();
+
+	cur = *list;
+
+	while (cur) {
+		list = &cur->next;
+		cur = cur->next;
+	}
+
+	node->next = cur;
+	*list = node;
+
+	restore_flags(flags);
+}
+
+void M68328_delete_irq(irq_node_t **list, void *dev_id)
+{
+	unsigned long flags;
+	irq_node_t *node;
+
+	save_flags(flags);
+	cli();
+
+	for (node = *list; node; list = &node->next, node = *list) {
+		if (node->dev_id == dev_id) {
+			*list = node->next;
+			/* Mark it as free. */
+			node->handler = NULL;
+			restore_flags(flags);
+			return;
+		}
+	}
+	restore_flags(flags);
+	printk ("%s: tried to remove invalid irq\n", __FUNCTION__);
+}
+
+int M68328_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                         unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+	if (!int_irq_list[irq]) {
+		int_irq_list[irq] = new_irq_node();
+		int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	}
+
+	if (!(int_irq_list[irq]->flags & IRQ_FLG_STD)) {
+		if (int_irq_list[irq]->flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+	}
+	int_irq_list[irq]->handler = handler;
+	int_irq_list[irq]->flags   = flags;
+	int_irq_list[irq]->dev_id  = dev_id;
+	int_irq_list[irq]->devname = devname;
+
+	/* enable in the IMR */
+	if (!int_irq_ablecount[irq])
+		*(volatile unsigned long *)0xfffff304 &= ~(1<<irq);
+
+	return 0;
+}
+
+void M68328_free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_list[irq]->dev_id != dev_id)
+		printk("%s: removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, int_irq_list[irq]->devname);
+	int_irq_list[irq]->handler = int_badint;
+	int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	int_irq_list[irq]->dev_id  = NULL;
+	int_irq_list[irq]->devname = NULL;
+
+	*(volatile unsigned long *)0xfffff304 |= 1<<irq;
+}
+
+/*
+ * Enable/disable a particular machine specific interrupt source.
+ * Note that this may affect other interrupts in case of a shared interrupt.
+ * This function should only be called for a _very_ short time to change some
+ * internal data, that may not be changed by the interrupt at the same time.
+ * int_(enable|disable)_irq calls may also be nested.
+ */
+
+void M68328_enable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (--int_irq_ablecount[irq])
+		return;
+
+	/* enable the interrupt */
+	*(volatile unsigned long *)0xfffff304 &= ~(1<<irq);
+}
+
+void M68328_disable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_ablecount[irq]++)
+		return;
+
+	/* disable the interrupt */
+	*(volatile unsigned long *)0xfffff304 |= 1<<irq;
+}
+
+/* The 68k family did not have a good way to determine the source
+ * of interrupts until later in the family.  The EC000 core does
+ * not provide the vector number on the stack, we vector everything
+ * into one vector and look in the blasted mask register...
+ * This code is designed to be fast, almost constant time, not clean!
+ */
+inline int M68328_do_irq(int vec, struct pt_regs *fp)
+{
+	int irq;
+	int mask;
+
+	unsigned long pend = *(volatile unsigned long *)0xfffff310;
+
+	while (pend) {
+		if (pend & 0x0000ffff) {
+			if (pend & 0x000000ff) {
+				if (pend & 0x0000000f) {
+					mask = 0x00000001;
+					irq = 0;
+				} else {
+					mask = 0x00000010;
+					irq = 4;
+				}
+			} else {
+				if (pend & 0x00000f00) {
+					mask = 0x00000100;
+					irq = 8;
+				} else {
+					mask = 0x00001000;
+					irq = 12;
+				}
+			}
+		} else {
+			if (pend & 0x00ff0000) {
+				if (pend & 0x000f0000) {
+					mask = 0x00010000;
+					irq = 16;
+				} else {
+					mask = 0x00100000;
+					irq = 20;
+				}
+			} else {
+				if (pend & 0x0f000000) {
+					mask = 0x01000000;
+					irq = 24;
+				} else {
+					mask = 0x10000000;
+					irq = 28;
+				}
+			}
+		}
+
+		while (! (mask & pend)) {
+			mask <<=1;
+			irq++;
+		}
+
+		if (int_irq_list[irq] && int_irq_list[irq]->handler) {
+			int_irq_list[irq]->handler(irq, int_irq_list[irq]->dev_id, fp);
+			int_irq_count[irq]++;
+		} else {
+			printk("unregistered interrupt %d!\nTurning it off in the IMR...\n", irq);
+			*(volatile unsigned long *)0xfffff304 |= mask;
+		}
+		pend &= ~mask;
+	}
+	return 0;
+}
+
+int M68328_get_irq_list(char *buf)
+{
+	int i, len = 0;
+	irq_node_t *node;
+
+	len += sprintf(buf+len, "Internal 68328 interrupts\n");
+
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		if (!(node = int_irq_list[i]))
+			continue;
+		if (!(node->handler))
+			continue;
+
+		len += sprintf(buf+len, " %2d: %10u    %s\n", i,
+		               int_irq_count[i], int_irq_list[i]->devname);
+	}
+	return len;
+}
+
+void config_M68328_irq(void)
+{
+	mach_default_handler = NULL;
+	mach_init_IRQ        = M68328_init_IRQ;
+	mach_request_irq     = M68328_request_irq;
+	mach_free_irq        = M68328_free_irq;
+	mach_enable_irq      = M68328_enable_irq;
+	mach_disable_irq     = M68328_disable_irq;
+	mach_get_irq_list    = M68328_get_irq_list;
+	mach_process_int     = M68328_do_irq;
+}
+
+
+void init_irq_proc(void);
+void init_irq_proc(void)
+{
+	/* Insert /proc/irq driver here */
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68328/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/68328/Makefile
--- linux-2.4.29/arch/m68knommu/platform/68328/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68328/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,30 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o traps.o ints.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S $(BOARD)/bootlogo.rh
+
+entry.o: entry.S m68k_defs.h
+
+m68k_defs.h: ../../kernel/m68k_defs.c ../../kernel/m68k_defs.head
+	rm -f m68k_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/m68k_defs.c
+	cp ../../kernel/m68k_defs.head m68k_defs.h
+	grep '^#define' m68k_defs.s >> m68k_defs.h
+	rm m68k_defs.s
+-include m68k_defs.d
+
+$(BOARD)/bootlogo.rh: $(BOARD)/bootlogo.h
+	perl tools/bootlogo.pl < $(BOARD)/bootlogo.h > $(BOARD)/bootlogo.rh
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/platform/68328/peng.pl linux-2.4.29-uc1/arch/m68knommu/platform/68328/peng.pl
--- linux-2.4.29/arch/m68knommu/platform/68328/peng.pl	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68328/peng.pl	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,10 @@
+
+$_ = join("", <>);
+
+s/(0x[0-9a-f]{2})/sprintf("0x%.2x",ord(pack("b8",unpack("B8",chr(hex($1))))))/gei;
+
+s/^ /	.byte /gm;
+s/[,};]+$//gm;
+s/^static.*//gm;
+
+print $_;
diff -urN linux-2.4.29/arch/m68knommu/platform/68328/pilot/bootlogo.h linux-2.4.29-uc1/arch/m68knommu/platform/68328/pilot/bootlogo.h
--- linux-2.4.29/arch/m68knommu/platform/68328/pilot/bootlogo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68328/pilot/bootlogo.h	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,270 @@
+#define bootlogo_width 160
+#define bootlogo_height 160
+static unsigned char bootlogo_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x55,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x08, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00,
+  0x00, 0xff, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0xf8, 0x80, 0x0f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x50, 0x04, 0x00, 0x00, 0x00, 0x78, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x03, 0x00, 0x00,
+  0x00, 0x78, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x40,
+  0xa8, 0x02, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x70, 0x28, 0x01, 0x00, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x20, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x70,
+  0x54, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x80, 0x01, 0x3a, 0x78, 0x80, 0x0e,
+  0x50, 0xc0, 0x03, 0x0e, 0x00, 0x20, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00,
+  0x00, 0x3e, 0xf0, 0x83, 0x1f, 0xfc, 0xe0, 0x0f, 0x78, 0xf8, 0x87, 0x1f,
+  0x00, 0x18, 0x00, 0x30, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xf8, 0xc3,
+  0x1f, 0xfc, 0xe0, 0x0f, 0x78, 0xf8, 0x87, 0x0f, 0x00, 0x20, 0x00, 0x10,
+  0x55, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xc0, 0x03, 0x9f, 0xf3, 0x80, 0x0f,
+  0x78, 0x80, 0xc7, 0x0e, 0x00, 0x18, 0x00, 0x20, 0xaa, 0x00, 0x00, 0x00,
+  0x00, 0x1e, 0xe0, 0x03, 0x9f, 0xf1, 0x80, 0x07, 0x78, 0x80, 0x67, 0x00,
+  0x00, 0x24, 0x00, 0x18, 0x55, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x01,
+  0x5e, 0xf0, 0x80, 0x07, 0x3c, 0x00, 0x2f, 0x00, 0x00, 0x14, 0x00, 0x20,
+  0xaa, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x01, 0x7f, 0xf0, 0x80, 0x07,
+  0x3c, 0x00, 0x3f, 0x00, 0x00, 0x08, 0x00, 0x18, 0x55, 0x00, 0x00, 0x00,
+  0x00, 0x0f, 0xe0, 0x00, 0x3f, 0xf0, 0xc0, 0x03, 0x1e, 0x00, 0x1f, 0x00,
+  0x00, 0x14, 0x00, 0x28, 0xaa, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xf0, 0x00,
+  0x1f, 0xf0, 0xc0, 0x03, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x04, 0x00, 0x0c,
+  0x54, 0x00, 0x00, 0x00, 0x80, 0x07, 0x78, 0x00, 0x1f, 0x78, 0xc0, 0x03,
+  0x1f, 0x00, 0x1e, 0x00, 0x00, 0x0a, 0x00, 0x12, 0xa8, 0x00, 0x00, 0x00,
+  0x80, 0x07, 0x78, 0x00, 0x1f, 0x78, 0xe0, 0x03, 0x1f, 0x00, 0x1f, 0x00,
+  0x00, 0x04, 0x00, 0x0a, 0x54, 0x00, 0x00, 0x00, 0x80, 0x07, 0x78, 0x80,
+  0x0f, 0x78, 0xe0, 0x03, 0x1f, 0x00, 0x1e, 0x00, 0x00, 0x0a, 0x00, 0x08,
+  0x50, 0x01, 0x00, 0x00, 0x84, 0x03, 0x78, 0x80, 0x07, 0x3c, 0xe0, 0xc1,
+  0x0f, 0x00, 0x1f, 0x00, 0x00, 0x04, 0x00, 0x06, 0xa8, 0x00, 0x00, 0x00,
+  0xc0, 0x03, 0x78, 0xc0, 0x07, 0x3c, 0xe0, 0xc1, 0x0f, 0x00, 0x1f, 0x00,
+  0x00, 0x0a, 0x00, 0x08, 0x50, 0x01, 0x00, 0x00, 0xc2, 0x01, 0x38, 0xc0,
+  0x07, 0x3c, 0xe0, 0x60, 0x0f, 0x80, 0x1e, 0x00, 0x00, 0x05, 0x00, 0x07,
+  0xa0, 0x00, 0x00, 0x80, 0xe0, 0x01, 0x3c, 0xc0, 0x07, 0x3c, 0xf0, 0xa0,
+  0x07, 0xc0, 0x1c, 0x00, 0x00, 0x0a, 0x80, 0x08, 0xa0, 0x02, 0x00, 0xa0,
+  0xe0, 0x21, 0x1c, 0xc0, 0x03, 0x1c, 0x71, 0x90, 0x47, 0x40, 0x3c, 0x04,
+  0x00, 0x05, 0x80, 0x06, 0xa0, 0x02, 0x00, 0x20, 0xe0, 0x31, 0x1e, 0xc3,
+  0x03, 0x1e, 0x79, 0x98, 0x47, 0x60, 0x38, 0x04, 0x00, 0x15, 0x40, 0x0a,
+  0xa0, 0x0a, 0x00, 0x1a, 0xe0, 0x19, 0x9e, 0xe1, 0x01, 0x9e, 0x78, 0xcc,
+  0xa7, 0x32, 0x78, 0x02, 0x80, 0x2a, 0x40, 0x05, 0x80, 0x2a, 0x00, 0x05,
+  0xe0, 0x0d, 0x9e, 0xe0, 0x01, 0xde, 0x78, 0xc6, 0x97, 0x1b, 0x78, 0x03,
+  0x80, 0x52, 0x30, 0x0a, 0x00, 0x95, 0xd2, 0x0a, 0xe0, 0x0f, 0xfe, 0xe0,
+  0x00, 0x7e, 0xf8, 0x87, 0x9f, 0x0f, 0xf8, 0x01, 0x00, 0xa1, 0x0e, 0x15,
+  0x80, 0x55, 0x55, 0x01, 0xe0, 0x01, 0x3c, 0xf0, 0x00, 0x3c, 0xf0, 0x80,
+  0x8f, 0x0f, 0x70, 0x00, 0x00, 0x81, 0x02, 0x14, 0x00, 0x54, 0x55, 0x00,
+  0xc0, 0x01, 0x3c, 0x00, 0x00, 0x0c, 0x60, 0x00, 0x07, 0x03, 0x70, 0x00,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x01, 0x00, 0x11, 0x09, 0x00, 0x04, 0x00, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+  0x00, 0x20, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x49, 0x32, 0x49, 0x49, 0x91,
+  0x24, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x20, 0x49, 0x0a, 0x09, 0xc9, 0x92, 0x14, 0x81, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x49,
+  0x18, 0x01, 0x49, 0x92, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x49, 0x30, 0x01, 0x49, 0x92,
+  0x14, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x08, 0x69, 0x22, 0x09, 0x49, 0xd2, 0x24, 0x24, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x51,
+  0x1a, 0x09, 0x49, 0xa2, 0x44, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x87, 0x08, 0x00, 0x00, 0x00,
+  0xf2, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0xf0, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x88, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09,
+  0x09, 0x01, 0x10, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x24, 0x80,
+  0x88, 0x86, 0x48, 0x04, 0x09, 0x08, 0x01, 0x01, 0x09, 0x01, 0x10, 0x71,
+  0x88, 0x66, 0x00, 0x00, 0x00, 0x40, 0x24, 0x80, 0x88, 0x89, 0x48, 0x84,
+  0x08, 0x08, 0x01, 0x01, 0x09, 0x01, 0x10, 0x89, 0x88, 0x99, 0x00, 0x00,
+  0x00, 0x40, 0x24, 0x80, 0x88, 0x88, 0x88, 0x82, 0xf8, 0xf0, 0xe0, 0x80,
+  0xf0, 0xf8, 0x13, 0x81, 0x88, 0x88, 0x00, 0x00, 0x00, 0x40, 0x24, 0x80,
+  0x88, 0x88, 0x08, 0x81, 0x08, 0x09, 0x01, 0x41, 0x08, 0x01, 0xf0, 0xf0,
+  0x88, 0x88, 0x00, 0x00, 0x00, 0x40, 0x24, 0x80, 0x88, 0x88, 0x88, 0x42,
+  0x08, 0x09, 0x01, 0x21, 0x08, 0x01, 0x10, 0x88, 0x88, 0x88, 0x00, 0x00,
+  0x00, 0x40, 0x46, 0x88, 0x88, 0x88, 0x4c, 0x44, 0x08, 0x09, 0x09, 0x11,
+  0x08, 0x01, 0x10, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x80, 0x85, 0x87,
+  0x88, 0x08, 0x4b, 0x24, 0xf0, 0xf0, 0xf0, 0xf8, 0xf1, 0x00, 0x10, 0x70,
+  0x89, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x3f, 0x0f, 0x00, 0x00, 0x08, 0x02, 0x04, 0x00,
+  0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0x1f, 0x00, 0x00, 0x48, 0x62, 0xc4, 0x31, 0x4a, 0x18, 0x3c, 0x03,
+  0x21, 0x45, 0x92, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x1f, 0x00, 0x00,
+  0x48, 0x92, 0x24, 0x48, 0xb6, 0x24, 0x88, 0x04, 0x21, 0x4b, 0x92, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xa8, 0xf2, 0x24, 0x48,
+  0x92, 0x3c, 0x88, 0x04, 0x21, 0x49, 0x62, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x10, 0x11, 0x24, 0x48, 0x92, 0x04, 0x88, 0x04,
+  0x21, 0x49, 0x62, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x3f, 0x00, 0x00,
+  0x10, 0x11, 0x24, 0x48, 0x92, 0x04, 0x88, 0x04, 0x21, 0x49, 0x93, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0xcf, 0x7e, 0x00, 0x00, 0x10, 0xe1, 0xc4, 0x31,
+  0x92, 0x38, 0x30, 0x03, 0x2f, 0x89, 0x92, 0x00, 0x00, 0x00, 0x80, 0xe3,
+  0x07, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc1, 0x03, 0x7e, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0xc9, 0x23, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x95,
+  0x33, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xdd, 0xfb, 0x7e, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x1d, 0xf8, 0x7e, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x40, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9b,
+  0x70, 0x7e, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x00, 0x02, 0x00, 0x47, 0x80,
+  0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x80, 0x03, 0x00, 0x7e, 0x00, 0x00,
+  0x3c, 0xa3, 0x20, 0x31, 0x52, 0x02, 0x49, 0xcc, 0x3f, 0xa3, 0x94, 0x08,
+  0x00, 0x00, 0x00, 0x27, 0x02, 0x7e, 0x00, 0x00, 0x88, 0xe4, 0x20, 0x41,
+  0xb2, 0x05, 0x49, 0x90, 0x88, 0xe4, 0x6c, 0x09, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x7e, 0x00, 0x00, 0x88, 0x24, 0xe0, 0x70, 0x92, 0x04, 0x47, 0x9c,
+  0x88, 0x24, 0x24, 0x09, 0x00, 0x00, 0x00, 0x13, 0x48, 0x7e, 0x00, 0x00,
+  0x88, 0x24, 0x20, 0x48, 0x92, 0x04, 0x41, 0x92, 0x88, 0x24, 0x24, 0x01,
+  0x00, 0x00, 0x00, 0x43, 0x00, 0xfe, 0x00, 0x00, 0x88, 0x24, 0x20, 0x48,
+  0x92, 0x04, 0x41, 0x92, 0x88, 0x24, 0x24, 0x09, 0x00, 0x00, 0x00, 0x07,
+  0x94, 0xce, 0x00, 0x00, 0x08, 0x23, 0x20, 0xb0, 0x92, 0x04, 0x41, 0x2c,
+  0x0b, 0x23, 0x24, 0x09, 0x00, 0x00, 0x00, 0x49, 0x02, 0xce, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x11, 0x08, 0xdc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+  0x01, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0xf8, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x01, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01,
+  0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xf0, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x70, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00,
+  0x00, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0xe0, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x3c, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00,
+  0x00, 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xc0, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x1f, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00,
+  0x00, 0x80, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00,
+  0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0xfe, 0x0f,
+  0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x08, 0x00,
+  0x00, 0xc0, 0x03, 0x00, 0x78, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x40, 0x10,
+  0x12, 0x10, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
+  0x84, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x20, 0x26, 0x0a, 0x10, 0x9d, 0x39,
+  0xa6, 0xb2, 0x0a, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x02, 0x00, 0xfe, 0x0f,
+  0x00, 0x00, 0x20, 0x21, 0x06, 0x28, 0x25, 0x4a, 0xa9, 0x8a, 0x09, 0x00,
+  0x00, 0xe0, 0x01, 0x22, 0x02, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x20, 0x21,
+  0x0e, 0x38, 0xa5, 0x4b, 0xa9, 0xb2, 0x09, 0x00, 0x00, 0xf0, 0x01, 0x22,
+  0x02, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x20, 0x21, 0x12, 0x44, 0xa5, 0x4a,
+  0x49, 0xa1, 0x0a, 0x00, 0x00, 0xf8, 0x01, 0x22, 0x02, 0x00, 0xfc, 0x1f,
+  0x00, 0x00, 0x20, 0x26, 0x52, 0x44, 0x9d, 0x4d, 0x46, 0x99, 0x0a, 0x00,
+  0x00, 0xfc, 0x01, 0x22, 0x02, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x40, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0xb2,
+  0x84, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x01, 0x6e, 0x78, 0x00, 0xfc, 0x1f,
+  0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xfc, 0x01, 0x02, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x02,
+  0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0xfc, 0x0f,
+  0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x20, 0x01, 0x02, 0x00, 0x00, 0x00,
+  0x00, 0x24, 0x06, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x40, 0x10,
+  0x1e, 0x20, 0x90, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
+  0x00, 0x80, 0xfc, 0x03, 0x00, 0x00, 0x20, 0x26, 0x22, 0x20, 0xf9, 0x89,
+  0x32, 0xe7, 0x08, 0x00, 0x00, 0x92, 0x38, 0x00, 0x00, 0x00, 0xfc, 0x01,
+  0x00, 0x00, 0x20, 0x21, 0x22, 0xa0, 0x92, 0x88, 0x4a, 0x29, 0x15, 0x00,
+  0x00, 0x00, 0x78, 0x00, 0x00, 0x40, 0xfa, 0x04, 0x00, 0x00, 0x20, 0x21,
+  0x22, 0xa0, 0x93, 0x88, 0x4a, 0x29, 0x1d, 0x00, 0x00, 0x11, 0xf2, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x20, 0x21, 0x22, 0xa8, 0x90, 0x88,
+  0x4a, 0x29, 0x05, 0x00, 0x48, 0x40, 0xf0, 0x01, 0x00, 0x80, 0x14, 0x04,
+  0x00, 0x00, 0x20, 0x26, 0x9e, 0x10, 0x93, 0x78, 0x32, 0x29, 0x19, 0x00,
+  0x00, 0x09, 0xe0, 0x03, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x40, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xc5, 0x03,
+  0x00, 0x40, 0x22, 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0xc0, 0x07, 0x00, 0x20, 0x08, 0x04,
+  0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x50, 0x90, 0x03, 0x00, 0xb0, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
+  0x00, 0x38, 0x22, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x48, 0x04, 0x44, 0x00, 0x00, 0x3c, 0x08, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x20, 0x00, 0x00, 0x00, 0xbf, 0x40, 0x42, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x24, 0x80, 0x48, 0x02,
+  0xc0, 0x1f, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x05, 0xf0, 0x3f, 0x09, 0x00,
+  0x00, 0x10, 0x24, 0x48, 0x10, 0x12, 0x41, 0x52, 0x24, 0x09, 0x46, 0x71,
+  0x90, 0x20, 0x02, 0xfc, 0xff, 0x1f, 0x80, 0x22, 0x00, 0x90, 0x24, 0x49,
+  0x12, 0x92, 0x40, 0xb2, 0x24, 0x09, 0xc9, 0x49, 0x04, 0x80, 0x90, 0xfc,
+  0xff, 0xbf, 0x24, 0x00, 0x00, 0x90, 0x24, 0x49, 0x12, 0x92, 0x40, 0x92,
+  0x24, 0x06, 0x49, 0x48, 0x50, 0x0a, 0x02, 0xfe, 0xff, 0x3f, 0x00, 0x05,
+  0x00, 0x50, 0xa5, 0x4a, 0x15, 0x92, 0x40, 0x92, 0x24, 0x06, 0x49, 0x48,
+  0x80, 0x40, 0x48, 0xfe, 0xff, 0x3f, 0x49, 0x00, 0x00, 0x20, 0x42, 0x84,
+  0x88, 0x1a, 0x41, 0x92, 0x34, 0x49, 0x49, 0x68, 0x00, 0x38, 0x10, 0x07,
+  0x00, 0x60, 0x80, 0x00, 0x00, 0x20, 0x42, 0x84, 0x88, 0x14, 0x4e, 0x92,
+  0x28, 0x49, 0x46, 0x50, 0x00, 0x80, 0x83, 0x01, 0x00, 0xa0, 0x6a, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+  0x00, 0x00, 0xfc, 0x00, 0x00, 0xc0, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, };
diff -urN linux-2.4.29/arch/m68knommu/platform/68328/pilot/crt0_rom.S linux-2.4.29-uc1/arch/m68knommu/platform/68328/pilot/crt0_rom.S
--- linux-2.4.29/arch/m68knommu/platform/68328/pilot/crt0_rom.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68328/pilot/crt0_rom.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,229 @@
+/* linux/arch/m68knommu/kernel/head.S:  A startup file for the MC68332 
+ *
+ * Copyright (C) 1998  D. Jeff Dionne <jeff@uClinux.org>,
+ *                     Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ * (c) 1995, Dionne & Associates
+ * (c) 1995, DKG Display Tech.
+ */
+
+#define ASSEMBLY
+
+#define IMMED #
+#define	DBG_PUTC(x)	moveb IMMED x, 0xfffff907
+
+#include <linux/config.h>
+
+.global _stext
+.global __bss_start
+
+.global _start
+
+.global _rambase
+.global __ramvec
+.global _ramvec
+.global _ramstart
+.global _ramend
+
+.global penguin_bits
+
+#ifdef CONFIG_PILOT
+
+#define IMR 0xFFFFF304
+
+	.data
+	.align 16
+
+penguin_bits:	
+#include "bootlogo.rh"
+
+#endif
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+.text
+	
+_start:
+_stext:
+
+
+#ifdef CONFIG_M68328
+
+#ifdef CONFIG_PILOT
+	.byte 0x4e, 0xfa, 0x00, 0x0a /* Jmp +X bytes */
+	.byte 'b', 'o', 'o', 't'
+	.word 10000
+
+	nop
+#endif
+
+	moveq	#0, %d0
+	movew   %d0, 0xfffff618 /* Watchdog off */
+	movel	#0x00011f07, 0xfffff114 /* CS A1 Mask */
+
+	movew	#0x0800, 0xfffff906 /* Ignore CTS */
+	movew	#0x010b, 0xfffff902 /* BAUD to 9600 */
+
+	movew	#0x2410,	0xfffff200 /* PLLCR */
+	movew	#0x123,	0xfffff202 /* PLLFSR */
+
+#ifdef CONFIG_PILOT
+	moveb	#0,      0xfffffA27 /* LCKCON */
+	movel   #_start, 0xfffffA00 /* LSSA */
+	moveb   #0xa,    0xfffffA05 /* LVPW */
+	movew	#0x9f,   0xFFFFFa08 /* LXMAX */
+	movew	#0x9f,   0xFFFFFa0a /* LYMAX */
+	moveb   #9,      0xfffffa29 /* LBAR */
+	moveb   #0,      0xfffffa25 /* LPXCD */
+	moveb	#0x04,   0xFFFFFa20 /* LPICF */
+	moveb	#0x58,   0xfffffA27 /* LCKCON */
+	moveb	#0x85,	0xfffff429 /* PFDATA */
+	moveb	#0xd8,   0xfffffA27 /* LCKCON */
+	moveb	#0xc5,	0xfffff429 /* PFDATA */
+	moveb	#0xd5,	0xfffff429 /* PFDATA */
+
+	moveal	#0x00100000, %a3
+	moveal	#0x100ffc00, %a4
+
+#endif /* CONFIG_PILOT */
+
+
+#endif /* CONFIG_M68328 */
+
+	movew   #0x2700, %sr
+	lea	%a4@(-4), %sp
+
+	DBG_PUTC('\r')
+	DBG_PUTC('\n')
+	DBG_PUTC('A')
+
+   	moveq   #0,%d0
+	movew	#16384, %d0  /* PLL settle wait loop */
+L0:
+	subw	#1, %d0
+	bne	L0
+
+	DBG_PUTC('B')
+
+	/* Copy command line from beginning of RAM (+16) to end of bss */
+	movel	#__ramvec, %d7
+	addl	#16, %d7
+	moveal	%d7, %a0
+	moveal	#end, %a1
+	lea	%a1@(512), %a2
+
+	DBG_PUTC('C')
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+L2:
+	movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bhi	L2
+
+	/* Copy data segment from ROM to RAM */
+	moveal	#__data_rom_start, %a0
+	moveal	#__data_start, %a1
+	moveal	#__data_end, %a2
+
+	DBG_PUTC('D')
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:
+	movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bhi	LD1
+
+	DBG_PUTC('E')
+
+	moveal	#__bss_start, %a0
+	moveal	#end, %a1
+
+	/* Copy 0 to %a0 until %a0 == %a1 */
+L1:
+	movel	#0, %a0@+
+	cmpal	%a0, %a1
+	bhi	L1
+
+	DBG_PUTC('F')
+
+	/* Copy command line from end of bss to command line */
+	moveal	#end, %a0
+	moveal	#command_line, %a1
+	lea	%a1@(512), %a2
+
+	DBG_PUTC('G')
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+L3:
+	movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bhi	L3
+
+	movel	#_sdata, %d0	
+	movel	%d0,	_rambase	
+	movel	#end,	%d0
+	movel	%d0,	_ramstart
+
+	movel	%a4,	%d0
+	subl	#4096,	%d0	/* Reserve 4K of stack */
+	moveq	#79, %d7
+	movel	%d0,	_ramend
+
+	movel	%a3,	%d0
+	movel	%d0,	rom_length
+
+	pea	0
+	pea	env
+	pea	%sp@(4)
+	pea	0
+
+	DBG_PUTC('H')
+
+#ifdef CONFIG_PILOT
+	
+	movel	#penguin_bits,	0xFFFFFA00
+	moveb	#10,		0xFFFFFA05
+	movew	#160,		0xFFFFFA08
+	movew	#160,		0xFFFFFA0A
+
+#endif /* CONFIG_PILOT */
+
+	DBG_PUTC('I')
+
+	lea     init_task_union,%a2
+	movel	%a2, _current_task
+	lea     0x2000(%a2),%sp
+
+	DBG_PUTC('J')
+	DBG_PUTC('\r')
+	DBG_PUTC('\n')
+
+	jsr	start_kernel
+_exit:
+
+	jmp	_exit
+
+
+	.data
+env:
+	.long	0
diff -urN linux-2.4.29/arch/m68knommu/platform/68328/pilot/fixed.ld linux-2.4.29-uc1/arch/m68knommu/platform/68328/pilot/fixed.ld
--- linux-2.4.29/arch/m68knommu/platform/68328/pilot/fixed.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68328/pilot/fixed.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,98 @@
+SECTIONS
+{
+  .romvec :
+	{
+	_flashstart = . ;
+	_romvec = . ;
+	__rom_start = . ;
+	} > romvec
+
+  .text :
+	{
+	_stext = . ;
+        	*(.text)
+	. = ALIGN(0x4) ;
+		*(.text.*)
+	. = ALIGN(0x4) ;
+		*(.exitcall.exit)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	. = ALIGN(0x4) ;
+	_etext = . ;
+	__data_rom_start = . ;
+        } > flash
+
+  .eflash :
+	{
+	_flashend = . ;
+	} > eflash
+
+  .ramvec :
+	{
+	__ram_start = . ;
+	__ramvec = . ;
+	} > ramvec
+
+  .data :
+	{
+	. = ALIGN(0x4) ;
+	_sdata = . ;
+	__data_start = . ;
+
+	. = ALIGN(0x4) ;
+		*(.rodata)
+	. = ALIGN(0x4) ;
+		*(.rodata.str1.1)
+	. = ALIGN(0x4) ;
+		*(.data)
+	. = ALIGN(0x4) ;
+		*(.data.*)	
+
+	. = ALIGN(0x4) ;
+	__setup_start = .;
+		*(.setup.init)
+	. = ALIGN(0x4) ;
+	__setup_end = .;
+
+	. = ALIGN(0x4) ;
+	__initcall_start = .;
+		*(.initcall.init)
+	. = ALIGN(0x4) ;
+	__initcall_end = .;
+
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	. = ALIGN(0x2000) ;
+
+	_edata = . ;
+        } > ram
+
+  .bss :
+        {
+	. = ALIGN(0x4) ;
+	_sbss = . ;
+          __bss_start = . ;
+          __data_end = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	end = . ;
+	_ebss = . ;
+	_end = . ;
+	} > ram
+
+  .eram :
+	{
+	__ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68328/pilot/rom.ld linux-2.4.29-uc1/arch/m68knommu/platform/68328/pilot/rom.ld
--- linux-2.4.29/arch/m68knommu/platform/68328/pilot/rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68328/pilot/rom.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,11 @@
+MEMORY 
+	{
+	romvec : ORIGIN = 0x10c00000, LENGTH = 0x10400
+	flash  : ORIGIN = 0x10c10400, LENGTH = 0xfec00
+	eflash : ORIGIN = 0x10d00000, LENGTH = 4
+	ramvec : ORIGIN = 0x00000000, LENGTH = 0x400
+	ram    : ORIGIN = 0x10000400, LENGTH = 0x100000-0x400
+	eram   : ORIGIN = 0x10100000, LENGTH = 4
+	}
+INCLUDE arch/m68knommu/platform/68328/pilot/fixed.ld
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68328/pm.c linux-2.4.29-uc1/arch/m68knommu/platform/68328/pm.c
--- linux-2.4.29/arch/m68knommu/platform/68328/pm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68328/pm.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,240 @@
+/* 
+ * 68328 Power Management Routines
+ * 
+ *  Copyright 2002 Daniel Potts <danielp@cse.unsw.edu.au>
+ *                 Embedded Systems, Co., LTD, Korea
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ */
+
+/*
+ *  Debug macros 
+ */
+#define DEBUG 1
+#ifdef DEBUG
+#  define DPRINTK(fmt, args...)	printk("%s: " fmt, __FUNCTION__ , ## args)
+#else
+#  define DPRINTK(fmt, args...)
+#endif
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/sysctl.h>
+
+#include <linux/acpi.h> /* WARNING: included for CTL_ACPI and ACPI_S1_SLP_TYP */
+
+#ifdef CONFIG_M68328
+#include <asm/MC68328.h>
+#endif
+
+#ifdef CONFIG_M68EZ328
+#include <asm/MC68EZ328.h>
+#endif
+
+#ifdef CONFIG_M68VZ328
+#include <asm/MC68VZ328.h>
+#endif
+
+#include <linux/kmod.h>
+#include <linux/interrupt.h> /* for interrupt stuff (that shouldn't be here)*/
+#include <asm/irq.h>
+
+static unsigned long sleep_irq_mask = 0L; /* irqs to enable while in sleep mode */
+
+#if defined (CONFIG_68328_SERIAL)
+void shutdown_console(void);
+void startup_console(void);
+#endif
+
+void set_sleep_mask(unsigned long mask)
+{
+	sleep_irq_mask = mask;
+}
+
+static int cpu_suspend(void)
+{
+	unsigned long flags;
+	unsigned long imr_flags;
+
+	save_flags(flags);
+	cli();
+	imr_flags = IMR;
+
+#if defined (CONFIG_68328_SERIAL)
+	/* Console is shutdown here as a special device,
+	 * to ensure that the kernel will not hang trying to write to console.
+	 */
+	shutdown_console();
+#endif
+
+	/* write out sleep enabled interrupts */
+	IMR = ~(sleep_irq_mask);    
+
+#if defined (CONFIG_PM_DOZE_ONLY)
+	PCTRL = PCTRL_PCEN;
+#else
+	PLLCR |= PLLCR_DISPLL;
+	__asm__("stop #0x2000" : : : "cc");
+#endif
+
+	/* Resume normal operation */
+
+#if defined (CONFIG_68328_SERIAL)
+	startup_console();
+#endif
+
+	IMR = imr_flags;
+	restore_flags(flags);
+
+	return 0;
+}
+
+#if defined (CONFIG_PM_HELPER)
+
+static char pm_helper_path[128] = "/sbin/pm_helper";
+
+static void run_pm_helper(pm_request_t action)
+{
+	int r;
+	char *argv[3], *envp[3];
+
+	if (!pm_helper_path[0])
+		return;
+	if (!current->fs->root)
+		return;
+	if (action != PM_SUSPEND && action != PM_RESUME)
+		return;
+
+	argv[0] = pm_helper_path;
+	argv[1] = (action == PM_RESUME ? "resume" : "suspend");
+	argv[2] = 0;
+
+	/* minimal command environment */
+	envp[0] = "HOME=/tmp";
+	envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+	envp[2] = 0;
+
+	r = call_usermodehelper(argv[0], argv, envp);
+	if (r != 0)
+		printk("pm: user mode pm_helper returned %d\n", r);
+}
+
+/* 
+ * pm_suggest_suspend()
+ *
+ * This gets called elsewhere in the kernel when the system should be placed
+ * into suspend mode. For example, a power button handler.
+ * It calls the user level power management handler.
+ */
+int pm_suggest_suspend(void)
+{
+	run_pm_helper(PM_SUSPEND);
+	return 0;
+}
+#endif
+
+
+#if defined (CONFIG_SYSCTL)
+static int sysctl_pm_do_suspend(ctl_table *table, int write, struct file *filp,
+                  void *buffer, size_t *lenp)
+{
+	int r;
+
+	*lenp = 0;
+
+	DPRINTK("System attempting to suspend.\n");
+	r = pm_send_all(PM_SUSPEND, (void *)2);
+	if (r) {
+		return r;
+	}
+
+	r = cpu_suspend();
+
+	pm_send_all(PM_RESUME, (void *)0);
+#if defined (CONFIG_PM_HELPER)
+	run_pm_helper(PM_RESUME);
+#endif
+
+	DPRINTK("System resumed normal operation.\n");
+	return r;
+}
+
+
+static struct ctl_table pm_table[] = 
+{
+	{ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, (proc_handler *)&sysctl_pm_do_suspend},
+#if defined (CONFIG_PM_HELPER)
+	{2, "pm_helper", pm_helper_path, sizeof(pm_helper_path), 0644, NULL, (proc_handler *)&proc_dostring},
+#endif
+	{0}
+};
+
+static struct ctl_table pm_dir_table[] =
+{
+	{CTL_ACPI, "pm", NULL, 0, 0555, pm_table},
+	{0}
+};
+
+
+/*
+ * Initialize power interface
+ */
+static int __init pm_init(void)
+{
+	printk("Power management driver for 68328, Daniel Potts <danielp@cse.unsw.edu.au>\n");
+
+	register_sysctl_table(pm_dir_table, 1);
+	return 0;
+}
+
+__initcall(pm_init);
+
+#endif /* CONFIG_SYSCTL */
+
+
+#if defined (CONFIG_PM_POWER_BUTTON_IRQ3)
+/* EXAMPLE power button handler:
+ *  Here we use IRQ3 as our wake up from sleep mode interrupt
+ */
+static void power_button_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	
+	ISR |= ISR_IRQ3; /* ack edge interrupt */
+
+	restore_flags(flags);
+}
+
+static int __init power_button(void)
+{
+	int err;
+	
+	/* init interrupt section */
+	PDDIR &= ~PD_IRQ3;
+	PDSEL &= ~PD_IRQ3;
+	
+	ICR |= ICR_ET3;  /* edge sensitive */
+	ISR |= ISR_IRQ3; /* clear it */
+	
+	set_sleep_mask(IMR_MIRQ3);
+	
+	err = request_irq(IRQ3_IRQ_NUM, power_button_irq,
+			  IRQ_FLG_STD, "power button", NULL);
+	
+	if(err)
+		printk("power irq failed\n");
+	return 0;
+}
+
+__initcall(power_button);
+
+#endif /* CONFIG_PM_POWER_BUTTON_IRQ3 */
diff -urN linux-2.4.29/arch/m68knommu/platform/68328/Rules.make linux-2.4.29-uc1/arch/m68knommu/platform/68328/Rules.make
--- linux-2.4.29/arch/m68knommu/platform/68328/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68328/Rules.make	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,72 @@
+#
+# 68EZ328/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 2000,2001  Lineo, Inc. <jeff@uClinux.org> 
+# Copyright (c) 1998,1999  D. Jeff Dionne <jeff@uclinux.org>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+#
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/m68000/libgcc.a
+
+CFLAGS := -fno-builtin -DNO_CACHE $(CFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -m68000 -D__ELF__ -DMAGIC_ROM_PTR -DNO_FORGET -DUTS_SYSNAME=\"uClinux\" -D__linux__
+AFLAGS := $(AFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -m68000 -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME=\"uClinux\" -Wa,--bitwise-or
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+ifdef CONFIG_FRAMEBUFFER
+SUBDIRS := $(SUBDIRS) arch/$(ARCH)/console
+ARCHIVES := $(ARCHIVES) arch/$(ARCH)/console/console.a
+endif
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+romfs.s19: romfs.img arch/$(ARCH)/empty.o
+	$(CROSS_COMPILE)objcopy -v -R .text -R .data -R .bss --add-section=.fs=romfs.img --adjust-section-vma=.fs=0xa0000 arch/$(ARCH)/empty.o romfs.s19
+	$(CROSS_COMPILE)objcopy -O srec romfs.s19
+
+linux.data: linux
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.romvec --remove-section=.text --remove-section=.ramvec --remove-section=.bss --remove-section=.eram linux linux.data
+
+linux.text: linux
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.ramvec --remove-section=.bss --remove-section=.data --remove-section=.eram --set-section-flags=.romvec=CONTENTS,ALLOC,LOAD,READONLY,CODE linux linux.text
+
+romfs.img:
+	echo creating a vmlinux rom image without root filesystem!
+
+linux.bin: linux.text linux.data romfs.img
+	if [ -f romfs.img ]; then\
+		cat linux.text linux.data romfs.img > linux.bin;\
+	else\
+		cat linux.text linux.data > linux.bin;\
+	fi
+
+linux.trg linux.rom: linux.bin
+	perl arch/$(ARCH)/platform/$(PLATFORM)/tools/fixup.pl
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f arch/$(ARCH)/platform/$(PLATFORM)/m68k_defs.h
+	rm -f linux.text linux.data linux.bin linux.rom linux.trg
+	rm -f linux.s19 romfs.s19
+	rm -f linux.img romdisk.img
diff -urN linux-2.4.29/arch/m68knommu/platform/68328/signal.c linux-2.4.29-uc1/arch/m68knommu/platform/68328/signal.c
--- linux-2.4.29/arch/m68knommu/platform/68328/signal.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68328/signal.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,1285 @@
+/*
+ *  linux/arch/m68k/kernel/signal.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * Linux/m68k support by Hamish Macdonald
+ *
+ * 68060 fixes by Jesper Skov
+ *
+ * 1997-12-01  Modified for POSIX.1b signals by Andreas Schwab
+ *
+ * mathemu support by Roman Zippel
+ *  (Note: fpstate in the signal context is completly ignored for the emulator
+ *         and the internal floating point format is put on stack)
+ */
+
+/*
+ * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
+ * Atari :-) Current limitation: Only one sigstack can be active at one time.
+ * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
+ * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
+ * signal handlers!
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/highuid.h>
+#include <linux/personality.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/traps.h>
+#include <asm/ucontext.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage long sys_wait4(pid_t pid, unsigned int * stat_addr, int options,
+			struct rusage * ru);
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
+
+#ifndef CONFIG_UCLINUX
+const int frame_extra_sizes[16] = {
+  0,
+  -1, /* sizeof(((struct frame *)0)->un.fmt1), */
+  sizeof(((struct frame *)0)->un.fmt2),
+  sizeof(((struct frame *)0)->un.fmt3),
+  sizeof(((struct frame *)0)->un.fmt4),
+  -1, /* sizeof(((struct frame *)0)->un.fmt5), */
+  -1, /* sizeof(((struct frame *)0)->un.fmt6), */
+  sizeof(((struct frame *)0)->un.fmt7),
+  -1, /* sizeof(((struct frame *)0)->un.fmt8), */
+  sizeof(((struct frame *)0)->un.fmt9),
+  sizeof(((struct frame *)0)->un.fmta),
+  sizeof(((struct frame *)0)->un.fmtb),
+  -1, /* sizeof(((struct frame *)0)->un.fmtc), */
+  -1, /* sizeof(((struct frame *)0)->un.fmtd), */
+  -1, /* sizeof(((struct frame *)0)->un.fmte), */
+  -1, /* sizeof(((struct frame *)0)->un.fmtf), */
+};
+#endif
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int do_sigsuspend(struct pt_regs *regs)
+{
+	old_sigset_t mask = regs->d3;
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->d0 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+do_rt_sigsuspend(struct pt_regs *regs)
+{
+	sigset_t *unewset = (sigset_t *)regs->d1;
+	size_t sigsetsize = (size_t)regs->d2;
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->d0 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int 
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+{
+	return do_sigaltstack(uss, uoss, rdusp());
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ *
+ * Keep the return code on the stack quadword aligned!
+ * That makes the cache flush below easier.
+ */
+
+struct sigframe
+{
+	char *pretcode;
+	int sig;
+	int code;
+	struct sigcontext *psc;
+	char retcode[8];
+	unsigned long extramask[_NSIG_WORDS-1];
+	struct sigcontext sc;
+};
+
+struct rt_sigframe
+{
+	char *pretcode;
+	int sig;
+	struct siginfo *pinfo;
+	void *puc;
+	char retcode[8];
+	struct siginfo info;
+	struct ucontext uc;
+};
+
+
+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
+{
+	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+		return -EFAULT;
+	if (from->si_code < 0)
+		return __copy_to_user(to, from, sizeof(siginfo_t));
+	else {
+		int err;
+
+		/* If you change siginfo_t structure, please be sure
+		   this code is fixed accordingly.
+		   It should never copy any pad contained in the structure
+		   to avoid security leaks, but must copy the generic
+		   3 ints plus the relevant union member.  */
+		err = __put_user(from->si_signo, &to->si_signo);
+		err |= __put_user(from->si_errno, &to->si_errno);
+		err |= __put_user((short)from->si_code, &to->si_code);
+		/* First 32bits of unions are always present.  */
+		err |= __put_user(from->si_pid, &to->si_pid);
+		switch (from->si_code >> 16) {
+		case __SI_FAULT >> 16:
+			break;
+		case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+			err |= __put_user(from->si_status, &to->si_status);
+		default:
+			err |= __put_user(from->si_uid, &to->si_uid);
+			break;
+		/* case __SI_RT: This is not generated by the kernel as of now.  */
+		}
+		return err;
+	}
+}
+
+#ifndef NO_FPU
+
+static unsigned char fpu_version = 0;	/* version number of fpu, set by setup_frame */
+
+static inline int restore_fpu_state(struct sigcontext *sc)
+{
+	int err = 1;
+
+	if (FPU_IS_EMU) {
+	    /* restore registers */
+	    memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
+	    memcpy(current->thread.fp, sc->sc_fpregs, 24);
+	    return 0;
+	}
+
+	if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
+	    /* Verify the frame format.  */
+	    if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version))
+		goto out;
+	    if (CPU_IS_020_OR_030) {
+		if (m68k_fputype & FPU_68881 &&
+		    !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4))
+		    goto out;
+		if (m68k_fputype & FPU_68882 &&
+		    !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4))
+		    goto out;
+	    } else if (CPU_IS_040) {
+		if (!(sc->sc_fpstate[1] == 0x00 ||
+                      sc->sc_fpstate[1] == 0x28 ||
+                      sc->sc_fpstate[1] == 0x60))
+		    goto out;
+	    } else if (CPU_IS_060) {
+		if (!(sc->sc_fpstate[3] == 0x00 ||
+                      sc->sc_fpstate[3] == 0x60 ||
+		      sc->sc_fpstate[3] == 0xe0))
+		    goto out;
+	    } else
+		goto out;
+
+	    __asm__ volatile (".chip 68k/68881\n\t"
+			      "fmovemx %0,%/fp0-%/fp1\n\t"
+			      "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t"
+			      ".chip 68k"
+			      : /* no outputs */
+			      : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl));
+	}
+	__asm__ volatile (".chip 68k/68881\n\t"
+			  "frestore %0\n\t"
+			  ".chip 68k" : : "m" (*sc->sc_fpstate));
+	err = 0;
+
+out:
+	return err;
+}
+
+#define FPCONTEXT_SIZE	216
+#define uc_fpstate	uc_filler[0]
+#define uc_formatvec	uc_filler[FPCONTEXT_SIZE/4]
+#define uc_extra	uc_filler[FPCONTEXT_SIZE/4+1]
+
+static inline int rt_restore_fpu_state(struct ucontext *uc)
+{
+	unsigned char fpstate[FPCONTEXT_SIZE];
+	int context_size = CPU_IS_060 ? 8 : 0;
+	fpregset_t fpregs;
+	int err = 1;
+
+	if (FPU_IS_EMU) {
+		/* restore fpu control register */
+		if (__copy_from_user(current->thread.fpcntl,
+				&uc->uc_mcontext.fpregs.f_pcr, 12))
+			goto out;
+		/* restore all other fpu register */
+		if (__copy_from_user(current->thread.fp,
+				uc->uc_mcontext.fpregs.f_fpregs, 96))
+			goto out;
+		return 0;
+	}
+
+	if (__get_user(*(long *)fpstate, (long *)&uc->uc_fpstate))
+		goto out;
+	if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
+		if (!CPU_IS_060)
+			context_size = fpstate[1];
+		/* Verify the frame format.  */
+		if (!CPU_IS_060 && (fpstate[0] != fpu_version))
+			goto out;
+		if (CPU_IS_020_OR_030) {
+			if (m68k_fputype & FPU_68881 &&
+			    !(context_size == 0x18 || context_size == 0xb4))
+				goto out;
+			if (m68k_fputype & FPU_68882 &&
+			    !(context_size == 0x38 || context_size == 0xd4))
+				goto out;
+		} else if (CPU_IS_040) {
+			if (!(context_size == 0x00 ||
+			      context_size == 0x28 ||
+			      context_size == 0x60))
+				goto out;
+		} else if (CPU_IS_060) {
+			if (!(fpstate[3] == 0x00 ||
+			      fpstate[3] == 0x60 ||
+			      fpstate[3] == 0xe0))
+				goto out;
+		} else
+			goto out;
+		if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
+				     sizeof(fpregs)))
+			goto out;
+		__asm__ volatile (".chip 68k/68881\n\t"
+				  "fmovemx %0,%/fp0-%/fp7\n\t"
+				  "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t"
+				  ".chip 68k"
+				  : /* no outputs */
+				  : "m" (*fpregs.f_fpregs),
+				    "m" (fpregs.f_pcr));
+	}
+	if (context_size &&
+	    __copy_from_user(fpstate + 4, (long *)&uc->uc_fpstate + 1,
+			     context_size))
+		goto out;
+	__asm__ volatile (".chip 68k/68881\n\t"
+			  "frestore %0\n\t"
+			  ".chip 68k" : : "m" (*fpstate));
+	err = 0;
+
+out:
+	return err;
+}
+
+#endif
+
+static inline int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp,
+		   int *pd0)
+{
+#ifndef CONFIG_UCLINUX
+	int fsize;
+#endif
+	int formatvec;
+	struct sigcontext context;
+	int err = 0;
+
+	/* get previous context */
+	if (copy_from_user(&context, usc, sizeof(context)))
+		goto badframe;
+	
+	/* restore passed registers */
+	regs->d1 = context.sc_d1;
+	regs->a0 = context.sc_a0;
+	regs->a1 = context.sc_a1;
+	regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
+	regs->pc = context.sc_pc;
+	regs->orig_d0 = -1;		/* disable syscall checks */
+	wrusp(context.sc_usp);
+	formatvec = context.sc_formatvec;
+	regs->format = formatvec >> 12;
+	regs->vector = formatvec & 0xfff;
+
+#ifndef NO_FPU
+	err = restore_fpu_state(&context);
+#endif
+
+#ifndef CONFIG_UCLINUX /* has no extra crap */
+	fsize = frame_extra_sizes[regs->format];
+	if (fsize < 0) {
+		/*
+		 * user process trying to return with weird frame format
+		 */
+#if DEBUG
+		printk("user process returning with weird frame format\n");
+#endif
+		goto badframe;
+	}
+
+	/* OK.	Make room on the supervisor stack for the extra junk,
+	 * if necessary.
+	 */
+
+	if (fsize) {
+		struct switch_stack *sw = (struct switch_stack *)regs - 1;
+		regs->d0 = context.sc_d0;
+#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
+		__asm__ __volatile__
+			("   movel %0,%/a0\n\t"
+			 "   subl %1,%/a0\n\t"     /* make room on stack */
+			 "   movel %/a0,%/sp\n\t"  /* set stack pointer */
+			 /* move switch_stack and pt_regs */
+			 "1: movel %0@+,%/a0@+\n\t"
+			 "   dbra %2,1b\n\t"
+			 "   lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
+			 "   lsrl  #2,%1\n\t"
+			 "   subql #1,%1\n\t"
+			 "2: movesl %4@+,%2\n\t"
+			 "3: movel %2,%/a0@+\n\t"
+			 "   dbra %1,2b\n\t"
+			 "   bral " SYMBOL_NAME_STR(ret_from_signal) "\n"
+			 "4:\n"
+			 ".section __ex_table,\"a\"\n"
+			 "   .align 4\n"
+			 "   .long 2b,4b\n"
+			 "   .long 3b,4b\n"
+			 ".previous"
+			 : /* no outputs, it doesn't ever return */
+			 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
+			   "n" (frame_offset), "a" (fp)
+			 : "a0");
+#undef frame_offset
+		/*
+		 * If we ever get here an exception occurred while
+		 * building the above stack-frame.
+		 */
+		goto badframe;
+	}
+#endif /* CONFIG_UCLINUX */
+
+	*pd0 = context.sc_d0;
+	return err;
+
+badframe:
+	return 1;
+}
+
+static inline int
+rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
+		    struct ucontext *uc, int *pd0)
+{
+#ifndef CONFIG_UCLINUX
+	int fsize;
+#endif
+	int temp;
+	greg_t *gregs = uc->uc_mcontext.gregs;
+	unsigned long usp;
+	int err;
+
+	err = __get_user(temp, &uc->uc_mcontext.version);
+	if (temp != MCONTEXT_VERSION)
+		goto badframe;
+	/* restore passed registers */
+	err |= __get_user(regs->d0, &gregs[0]);
+	err |= __get_user(regs->d1, &gregs[1]);
+	err |= __get_user(regs->d2, &gregs[2]);
+	err |= __get_user(regs->d3, &gregs[3]);
+	err |= __get_user(regs->d4, &gregs[4]);
+	err |= __get_user(regs->d5, &gregs[5]);
+	err |= __get_user(sw->d6, &gregs[6]);
+	err |= __get_user(sw->d7, &gregs[7]);
+	err |= __get_user(regs->a0, &gregs[8]);
+	err |= __get_user(regs->a1, &gregs[9]);
+	err |= __get_user(regs->a2, &gregs[10]);
+	err |= __get_user(sw->a3, &gregs[11]);
+	err |= __get_user(sw->a4, &gregs[12]);
+	err |= __get_user(sw->a5, &gregs[13]);
+	err |= __get_user(sw->a6, &gregs[14]);
+	err |= __get_user(usp, &gregs[15]);
+	wrusp(usp);
+	err |= __get_user(regs->pc, &gregs[16]);
+	err |= __get_user(temp, &gregs[17]);
+	regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
+	regs->orig_d0 = -1;		/* disable syscall checks */
+#if DAVIDM /* ifdef uc_formatvec */
+	err |= __get_user(temp, &uc->uc_formatvec);
+#endif
+	regs->format = temp >> 12;
+	regs->vector = temp & 0xfff;
+
+#if DAVIDM /* NO_FPU */
+	err |= rt_restore_fpu_state(uc);
+#endif
+
+	if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
+		goto badframe;
+
+#ifndef CONFIG_UCLINUX
+	fsize = frame_extra_sizes[regs->format];
+	if (fsize < 0) {
+		/*
+		 * user process trying to return with weird frame format
+		 */
+#if DEBUG
+		printk("user process returning with weird frame format\n");
+#endif
+		goto badframe;
+	}
+
+	/* OK.	Make room on the supervisor stack for the extra junk,
+	 * if necessary.
+	 */
+
+	if (fsize) {
+#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
+		__asm__ __volatile__
+			("   movel %0,%/a0\n\t"
+			 "   subl %1,%/a0\n\t"     /* make room on stack */
+			 "   movel %/a0,%/sp\n\t"  /* set stack pointer */
+			 /* move switch_stack and pt_regs */
+			 "1: movel %0@+,%/a0@+\n\t"
+			 "   dbra %2,1b\n\t"
+			 "   lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
+			 "   lsrl  #2,%1\n\t"
+			 "   subql #1,%1\n\t"
+			 "2: movesl %4@+,%2\n\t"
+			 "3: movel %2,%/a0@+\n\t"
+			 "   dbra %1,2b\n\t"
+			 "   bral " SYMBOL_NAME_STR(ret_from_signal) "\n"
+			 "4:\n"
+			 ".section __ex_table,\"a\"\n"
+			 "   .align 4\n"
+			 "   .long 2b,4b\n"
+			 "   .long 3b,4b\n"
+			 ".previous"
+			 : /* no outputs, it doesn't ever return */
+			 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
+			   "n" (frame_offset), "a" (&uc->uc_extra)
+			 : "a0");
+#undef frame_offset
+		/*
+		 * If we ever get here an exception occurred while
+		 * building the above stack-frame.
+		 */
+		goto badframe;
+	}
+#endif /* CONFIG_UCLINUX */
+
+	*pd0 = regs->d0;
+	return err;
+
+badframe:
+	return 1;
+}
+
+asmlinkage int do_sigreturn(unsigned long __unused)
+{
+	struct switch_stack *sw = (struct switch_stack *) &__unused;
+	struct pt_regs *regs = (struct pt_regs *) (sw + 1);
+	unsigned long usp = rdusp();
+	struct sigframe *frame = (struct sigframe *)(usp - 4);
+	sigset_t set;
+	int d0;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
+	    (_NSIG_WORDS > 1 &&
+	     __copy_from_user(&set.sig[1], &frame->extramask,
+			      sizeof(frame->extramask))))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+	
+	if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0))
+		goto badframe;
+	return d0;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int do_rt_sigreturn(unsigned long __unused)
+{
+	struct switch_stack *sw = (struct switch_stack *) &__unused;
+	struct pt_regs *regs = (struct pt_regs *) (sw + 1);
+	unsigned long usp = rdusp();
+	struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
+	sigset_t set;
+	int d0;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+	
+	if (rt_restore_ucontext(regs, sw, &frame->uc, &d0))
+		goto badframe;
+	return d0;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+#ifndef NO_FPU
+/*
+ * Set up a signal frame.
+ */
+
+static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
+{
+	if (FPU_IS_EMU) {
+		/* save registers */
+		memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);
+		memcpy(sc->sc_fpregs, current->thread.fp, 24);
+		return;
+	}
+
+	__asm__ volatile (".chip 68k/68881\n\t"
+			  "fsave %0\n\t"
+			  ".chip 68k"
+			  : : "m" (*sc->sc_fpstate) : "memory");
+
+	if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
+		fpu_version = sc->sc_fpstate[0];
+		if (CPU_IS_020_OR_030 &&
+		    regs->vector >= (VEC_FPBRUC * 4) &&
+		    regs->vector <= (VEC_FPNAN * 4)) {
+			/* Clear pending exception in 68882 idle frame */
+			if (*(unsigned short *) sc->sc_fpstate == 0x1f38)
+				sc->sc_fpstate[0x38] |= 1 << 3;
+		}
+		__asm__ volatile (".chip 68k/68881\n\t"
+				  "fmovemx %/fp0-%/fp1,%0\n\t"
+				  "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t"
+				  ".chip 68k"
+				  : /* no outputs */
+				  : "m" (*sc->sc_fpregs),
+				    "m" (*sc->sc_fpcntl)
+				  : "memory");
+	}
+}
+
+static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs)
+{
+	unsigned char fpstate[FPCONTEXT_SIZE];
+	int context_size = CPU_IS_060 ? 8 : 0;
+	int err = 0;
+
+	if (FPU_IS_EMU) {
+		/* save fpu control register */
+		err |= copy_to_user(&uc->uc_mcontext.fpregs.f_pcr,
+				current->thread.fpcntl, 12);
+		/* save all other fpu register */
+		err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
+				current->thread.fp, 96);
+		return err;
+	}
+
+	__asm__ volatile (".chip 68k/68881\n\t"
+			  "fsave %0\n\t"
+			  ".chip 68k"
+			  : : "m" (*fpstate) : "memory");
+
+	err |= __put_user(*(long *)fpstate, (long *)&uc->uc_fpstate);
+	if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
+		fpregset_t fpregs;
+		if (!CPU_IS_060)
+			context_size = fpstate[1];
+		fpu_version = fpstate[0];
+		if (CPU_IS_020_OR_030 &&
+		    regs->vector >= (VEC_FPBRUC * 4) &&
+		    regs->vector <= (VEC_FPNAN * 4)) {
+			/* Clear pending exception in 68882 idle frame */
+			if (*(unsigned short *) fpstate == 0x1f38)
+				fpstate[0x38] |= 1 << 3;
+		}
+		__asm__ volatile (".chip 68k/68881\n\t"
+				  "fmovemx %/fp0-%/fp7,%0\n\t"
+				  "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t"
+				  ".chip 68k"
+				  : /* no outputs */
+				  : "m" (*fpregs.f_fpregs),
+				    "m" (fpregs.f_pcr)
+				  : "memory");
+		err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
+				    sizeof(fpregs));
+	}
+	if (context_size)
+		err |= copy_to_user((long *)&uc->uc_fpstate + 1, fpstate + 4,
+				    context_size);
+	return err;
+}
+
+#endif
+
+static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+			     unsigned long mask)
+{
+	sc->sc_mask = mask;
+	sc->sc_usp = rdusp();
+	sc->sc_d0 = regs->d0;
+	sc->sc_d1 = regs->d1;
+	sc->sc_a0 = regs->a0;
+	sc->sc_a1 = regs->a1;
+	sc->sc_sr = regs->sr;
+	sc->sc_pc = regs->pc;
+	sc->sc_formatvec = regs->format << 12 | regs->vector;
+#ifndef NO_FPU
+	save_fpu_state(sc, regs);
+#endif
+}
+
+static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
+{
+	struct switch_stack *sw = (struct switch_stack *)regs - 1;
+	greg_t *gregs = uc->uc_mcontext.gregs;
+	int err = 0;
+
+	err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
+	err |= __put_user(regs->d0, &gregs[0]);
+	err |= __put_user(regs->d1, &gregs[1]);
+	err |= __put_user(regs->d2, &gregs[2]);
+	err |= __put_user(regs->d3, &gregs[3]);
+	err |= __put_user(regs->d4, &gregs[4]);
+	err |= __put_user(regs->d5, &gregs[5]);
+	err |= __put_user(sw->d6, &gregs[6]);
+	err |= __put_user(sw->d7, &gregs[7]);
+	err |= __put_user(regs->a0, &gregs[8]);
+	err |= __put_user(regs->a1, &gregs[9]);
+	err |= __put_user(regs->a2, &gregs[10]);
+	err |= __put_user(sw->a3, &gregs[11]);
+	err |= __put_user(sw->a4, &gregs[12]);
+	err |= __put_user(sw->a5, &gregs[13]);
+	err |= __put_user(sw->a6, &gregs[14]);
+	err |= __put_user(rdusp(), &gregs[15]);
+	err |= __put_user(regs->pc, &gregs[16]);
+	err |= __put_user(regs->sr, &gregs[17]);
+#if DAVIDM /* ifdef uc_formatvec */
+	err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec);
+#endif
+#ifndef NO_FPU
+	err |= rt_save_fpu_state(uc, regs);
+#endif
+	return err;
+}
+
+static inline void push_cache (unsigned long vaddr)
+{
+#if 0 /* DAVIDM - implement this for 5407, maybe */
+	/*
+	 * Using the old cache_push_v() was really a big waste.
+	 *
+	 * What we are trying to do is to flush 8 bytes to ram.
+	 * Flushing 2 cache lines of 16 bytes is much cheaper than
+	 * flushing 1 or 2 pages, as previously done in
+	 * cache_push_v().
+	 *                                                     Jes
+	 */
+	if (CPU_IS_040) {
+		unsigned long temp;
+
+		__asm__ __volatile__ (".chip 68040\n\t"
+				      "nop\n\t"
+				      "ptestr (%1)\n\t"
+				      "movec %%mmusr,%0\n\t"
+				      ".chip 68k"
+				      : "=r" (temp)
+				      : "a" (vaddr));
+
+		temp &= PAGE_MASK;
+		temp |= vaddr & ~PAGE_MASK;
+
+		__asm__ __volatile__ (".chip 68040\n\t"
+				      "nop\n\t"
+				      "cpushl %%bc,(%0)\n\t"
+				      ".chip 68k"
+				      : : "a" (temp));
+	}
+	else if (CPU_IS_060) {
+		unsigned long temp;
+		__asm__ __volatile__ (".chip 68060\n\t"
+				      "plpar (%0)\n\t"
+				      ".chip 68k"
+				      : "=a" (temp)
+				      : "0" (vaddr));
+		__asm__ __volatile__ (".chip 68060\n\t"
+				      "cpushl %%bc,(%0)\n\t"
+				      ".chip 68k"
+				      : : "a" (temp));
+	}
+	else {
+		/*
+		 * 68030/68020 have no writeback cache;
+		 * still need to clear icache.
+		 * Note that vaddr is guaranteed to be long word aligned.
+		 */
+		unsigned long temp;
+		asm volatile ("movec %%cacr,%0" : "=r" (temp));
+		temp += 4;
+		asm volatile ("movec %0,%%caar\n\t"
+			      "movec %1,%%cacr"
+			      : : "r" (vaddr), "r" (temp));
+		asm volatile ("movec %0,%%caar\n\t"
+			      "movec %1,%%cacr"
+			      : : "r" (vaddr + 4), "r" (temp));
+	}
+#endif
+}
+
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	unsigned long usp;
+
+	/* Default to using normal stack.  */
+	usp = rdusp();
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if (ka->sa.sa_flags & SA_ONSTACK) {
+		if (!on_sig_stack(usp))
+			usp = current->sas_ss_sp + current->sas_ss_size;
+	}
+	return (void *)((usp - frame_size) & -8UL);
+}
+
+static void setup_frame (int sig, struct k_sigaction *ka,
+			 sigset_t *set, struct pt_regs *regs)
+{
+	struct sigframe *frame;
+	unsigned long a5;
+#ifndef CONFIG_UCLINUX
+	int fsize = frame_extra_sizes[regs->format];
+#endif
+	struct sigcontext context;
+	int err = 0;
+
+#ifndef CONFIG_UCLINUX
+	if (fsize < 0) {
+#ifdef DEBUG
+		printk ("setup_frame: Unknown frame format %#x\n",
+			regs->format);
+#endif
+		goto give_sigsegv;
+	}
+
+	frame = get_sigframe(ka, regs, sizeof(*frame) + fsize);
+
+	if (fsize) {
+		err |= copy_to_user (frame + 1, regs + 1, fsize);
+		regs->stkadj = fsize;
+	}
+#else /* ! CONFIG_UCLINUX */
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+#endif /* ! CONFIG_UCLINUX */
+
+	err |= __put_user((current->exec_domain
+			   && current->exec_domain->signal_invmap
+			   && sig < 32
+			   ? current->exec_domain->signal_invmap[sig]
+			   : sig),
+			  &frame->sig);
+
+	err |= __put_user(regs->vector, &frame->code);
+	err |= __put_user(&frame->sc, &frame->psc);
+
+	if (_NSIG_WORDS > 1)
+		err |= copy_to_user(frame->extramask, &set->sig[1],
+				    sizeof(frame->extramask));
+
+	setup_sigcontext(&context, regs, set->sig[0]);
+	err |= copy_to_user (&frame->sc, &context, sizeof(context));
+
+	/* Set up to return from userspace.  */
+	err |= __put_user(frame->retcode, &frame->pretcode);
+
+	/* movea.l #,a5; moveq #,d0; trap #0 */
+	a5 = ((struct switch_stack *)regs - 1)->a5;
+	err |= __put_user(0x2a7c0000 + ((a5 >> 16) & 0xffff),
+			(long *)(frame->retcode + 0));
+	err |= __put_user(0x00007000 + ((a5 & 0xffff) << 16) + __NR_sigreturn,
+			(long *)(frame->retcode + 4));
+	err |= __put_user(0x4e40, (short *)(frame->retcode + 8));
+
+	if (err)
+		goto give_sigsegv;
+
+	push_cache ((unsigned long) &frame->retcode);
+
+	/* Set up registers for signal handler */
+	wrusp ((unsigned long) frame);
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+
+adjust_stack:
+	/* Prepare to skip over the extra stuff in the exception frame.  */
+	if (regs->stkadj) {
+		struct pt_regs *tregs =
+			(struct pt_regs *)((ulong)regs + regs->stkadj);
+#if DEBUG
+		printk("Performing stackadjust=%04x\n", regs->stkadj);
+#endif
+		/* This must be copied with decreasing addresses to
+                   handle overlaps.  */
+		tregs->vector = 0;
+		tregs->format = 0;
+		tregs->pc = regs->pc;
+		tregs->sr = regs->sr;
+	}
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+	goto adjust_stack;
+}
+
+static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
+			    sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+	unsigned long a5;
+#ifndef CONFIG_UCLINUX
+	int fsize = frame_extra_sizes[regs->format];
+#endif
+	int err = 0;
+
+#ifndef CONFIG_UCLINUX
+	if (fsize < 0) {
+#ifdef DEBUG
+		printk ("setup_frame: Unknown frame format %#x\n",
+			regs->format);
+#endif
+		goto give_sigsegv;
+	}
+#endif
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+#ifndef CONFIG_UCLINUX
+	if (fsize) {
+		err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);
+		regs->stkadj = fsize;
+	}
+#endif
+
+	err |= __put_user((current->exec_domain
+			   && current->exec_domain->signal_invmap
+			   && sig < 32
+			   ? current->exec_domain->signal_invmap[sig]
+			   : sig),
+			  &frame->sig);
+	err |= __put_user(&frame->info, &frame->pinfo);
+	err |= __put_user(&frame->uc, &frame->puc);
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+			  &frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(rdusp()),
+			  &frame->uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= rt_setup_ucontext(&frame->uc, regs);
+	err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	/* Set up to return from userspace.  */
+	err |= __put_user(frame->retcode, &frame->pretcode);
+
+	/* moveq #,d0; notb d0; movea.l #,a5; trap #0 */
+	a5 = ((struct switch_stack *)regs - 1)->a5;
+	err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
+			  (long *)(frame->retcode + 0));
+	err != __put_user(0x2a7c0000 + ((a5 >> 16) & 0xffff),
+			(long *)(frame->retcode + 4));
+	err != __put_user(0x00004e40 + ((a5 & 0xffff) << 16),
+			(long *)(frame->retcode + 8));
+
+	if (err)
+		goto give_sigsegv;
+
+	push_cache ((unsigned long) &frame->retcode);
+
+	/* Set up registers for signal handler */
+	wrusp ((unsigned long) frame);
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+
+adjust_stack:
+	/* Prepare to skip over the extra stuff in the exception frame.  */
+	if (regs->stkadj) {
+		struct pt_regs *tregs =
+			(struct pt_regs *)((ulong)regs + regs->stkadj);
+#if DEBUG
+		printk("Performing stackadjust=%04x\n", regs->stkadj);
+#endif
+		/* This must be copied with decreasing addresses to
+                   handle overlaps.  */
+		tregs->vector = 0;
+		tregs->format = 0;
+		tregs->pc = regs->pc;
+		tregs->sr = regs->sr;
+	}
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+	goto adjust_stack;
+}
+
+static inline void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
+{
+	switch (regs->d0) {
+	case -ERESTARTNOHAND:
+		if (!has_handler)
+			goto do_restart;
+		regs->d0 = -EINTR;
+		break;
+
+	case -ERESTARTSYS:
+		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
+			regs->d0 = -EINTR;
+			break;
+		}
+	/* fallthrough */
+	case -ERESTARTNOINTR:
+	do_restart:
+		regs->d0 = regs->orig_d0;
+		regs->pc -= 2;
+		break;
+	}
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static void
+handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
+	      sigset_t *oldset, struct pt_regs *regs)
+{
+	/* are we from a system call? */
+	if (regs->orig_d0 >= 0)
+		/* If so, check system call restarting.. */
+		handle_restart(regs, ka, 1);
+
+	/* set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sigmask_lock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending(current);
+		spin_unlock_irq(&current->sigmask_lock);
+	}
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals
+ * that the kernel can handle, and then we build all the user-level signal
+ * handling stack-frames in one go after that.
+ */
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
+{
+	siginfo_t info;
+	struct k_sigaction *ka;
+
+	current->thread.esp0 = (unsigned long) regs;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	for (;;) {
+		int signr;
+
+		spin_lock_irq(&current->sigmask_lock);
+		signr = dequeue_signal(&current->blocked, &info);
+		spin_unlock_irq(&current->sigmask_lock);
+
+		if (!signr)
+			break;
+
+		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			regs->sr &= ~PS_T;
+
+			/* Did we come from a system call? */
+			if (regs->orig_d0 >= 0) {
+				/* Restart the system call the same way as
+				   if the process were not traced.  */
+				struct k_sigaction *ka =
+					&current->sig->action[signr-1];
+				int has_handler =
+					(ka->sa.sa_handler != SIG_IGN &&
+					 ka->sa.sa_handler != SIG_DFL);
+				handle_restart(regs, ka, has_handler);
+			}
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code)) {
+			discard_frame:
+#ifndef CONFIG_UCLINUX
+			    /* Make sure that a faulted bus cycle isn't
+			       restarted (only needed on the 680[23]0).  */
+			    if (regs->format == 10 || regs->format == 11)
+				regs->stkadj = frame_extra_sizes[regs->format];
+#endif
+			    continue;
+			}
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				goto discard_frame;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD:
+			case SIGWINCH: case SIGURG:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP: {
+				struct signal_struct *sig;
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+                                sig = current->p_pptr->sig;
+                                if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags 
+& SA_NOCLDSTOP))
+                                        notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+			}
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGIOT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				sig_exit(signr, exit_code, &info);
+				/* NOTREACHED */
+			}
+		}
+
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(signr, ka, &info, oldset, regs);
+		return 1;
+	}
+
+	/* Did we come from a system call? */
+	if (regs->orig_d0 >= 0)
+		/* Restart the system call - no handlers present */
+		handle_restart(regs, NULL, 0);
+
+	/* If we are about to discard some frame stuff we must copy
+	   over the remaining frame. */
+	if (regs->stkadj) {
+		struct pt_regs *tregs =
+		  (struct pt_regs *) ((ulong) regs + regs->stkadj);
+
+		/* This must be copied with decreasing addresses to
+		   handle overlaps.  */
+		tregs->vector = 0;
+		tregs->format = 0;
+		tregs->pc = regs->pc;
+		tregs->sr = regs->sr;
+	}
+	return 0;
+}
+
+
+/*
+ *	return the correct value for a5/start_data,  mainly for signal
+ *	handlers to ensure they get the correct data segment.
+ */
+
+unsigned long
+get_pic_a5()
+{
+#ifdef DEBUG
+  	unsigned long a5;
+
+	__asm__ __volatile__("movel %/a5,%0"
+			     : "=a" (a5));
+
+	if (current->mm->start_data != a5)
+#ifdef CONFIG_BINFMT_SHARED_FLAT
+	{	int i;
+
+		/* It simply isn't sufficient to check for a5 having changed, we
+		 * must verify that the GOT pointers are equal for both segments.
+		 */
+		for (i=0; i<4; i++) {
+			if (*(long *)(current->mm->start_data - 4*i - 4) !=
+					*(long *)(a5 - 4*i - 4)) {
+				printk("%s: broken a5 (%d) 0x%x (0x%x)\n",
+						current->comm,
+						i, a5,
+						current->mm->start_data);
+				break;
+			}
+		}
+	}
+#else
+		printk("broken a5 0x%x != 0x%x\n", current->mm->start_data, a5);
+#endif
+#endif
+	return current->mm->start_data;
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68328/tools/bootlogo.pl linux-2.4.29-uc1/arch/m68knommu/platform/68328/tools/bootlogo.pl
--- linux-2.4.29/arch/m68knommu/platform/68328/tools/bootlogo.pl	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68328/tools/bootlogo.pl	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,10 @@
+
+$_ = join("", <>);
+
+s/(0x[0-9a-f]{2})/sprintf("0x%.2x",ord(pack("b8",unpack("B8",chr(hex($1))))))/gei;
+
+s/^ /	.byte /gm;
+s/[,};]+$//gm;
+s/^static.*//gm;
+
+print $_;
diff -urN linux-2.4.29/arch/m68knommu/platform/68328/tools/fixup.pl linux-2.4.29-uc1/arch/m68knommu/platform/68328/tools/fixup.pl
--- linux-2.4.29/arch/m68knommu/platform/68328/tools/fixup.pl	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68328/tools/fixup.pl	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,91 @@
+#!/usr/bin/perl
+
+#
+# Nasty piece of work, designed to translated linux.bin binary image
+# in to several different formats.
+# 
+# Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>,
+#                    The Silver Hammer Group, Ltd.
+#
+
+@CRC = (
+        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+        0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+        0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+        0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+        0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
+        0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
+        0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
+        0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
+        0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
+        0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
+        0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
+        0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
+        0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+        0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
+        0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
+        0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
+        0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
+        0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
+        0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
+        0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
+        0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
+        0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+        0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
+        0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
+        0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
+        0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+        0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
+        0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
+        0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
+        0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
+        0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
+        0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
+);
+
+sub CrcBlock {
+	my($data,$crc) = @_;
+	my($i);
+	printf "Crc of %d bytes\n", length($data);
+	for ($i=0;$i<length($data);$i++) {
+#		printf "crc = %d, Lookup = %d, CRC[] = %d\n", $crc,						($crc>>8) ^
+#						ord(substr($data,$i,1)),
+#$CRC[						($crc>>8) ^
+#						ord(substr($data,$i,1)) &
+#0xff];
+#
+
+		$crc = ($crc << 8) ^ $CRC[
+						((($crc>>8) & 0xff) ^
+						ord(substr($data,$i,1))) &
+						0xff
+					];
+		$crc &= 0xffff;
+	}
+	return $crc & 0xffff;
+}
+
+open(T,"<linux.bin");
+$/ = undef;
+
+$image = join('', <T>);
+close(T);
+
+$realLength = length($image);
+$image .= "\0" x (0x100000 - $realLength);
+
+$posOfCardLength = 108;
+$posOfChecksum = 112;
+#$crc = CrcBlock(substr($image, 0, $posOfChecksum), 0);
+#$crc = CrcBlock(substr($image, $posOfChecksum+2), $crc);
+
+#substr($image, $posOfCardLength, 4) = pack("N", length($image));
+#substr($image, $posOfChecksum, 2) = pack("n", $crc);
+
+open(O,">linux.trg");
+print O substr($image, 0x10000, (($realLength - 0x10000) + 0xffff) & ~0xffff);
+close(O);
+
+open(O, ">linux.rom");
+print O $image;
+close(O);
diff -urN linux-2.4.29/arch/m68knommu/platform/68328/traps.c linux-2.4.29-uc1/arch/m68knommu/platform/68328/traps.c
--- linux-2.4.29/arch/m68knommu/platform/68328/traps.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68328/traps.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,254 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/traps.c -- general exception handling code
+ *
+ * Cloned from Linux/m68k.
+ *
+ * No original Copyright holder listed,
+ * Probabily original (C) Roman Zippel (assigned DJD, 1999)
+ *
+ * Copyright 2000-2001 Lineo, Inc. D. Jeff Dionne <jeff@uClinux.org>
+ * Copyright 1999-2000 D. Jeff Dionne, <jeff@uclinux.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * VZ Support/Fixes             Evan Stawnyczy <e@lineo.ca>
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/errno.h>
+#include <linux/config.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+
+/* table for system interrupt handlers */
+static irq_handler_t irq_list[SYS_IRQS];
+
+static const char *default_names[SYS_IRQS] = {
+	"spurious int", "int1 handler", "int2 handler", "int3 handler",
+	"int4 handler", "int5 handler", "int6 handler", "int7 handler"
+};
+
+/* The number of spurious interrupts */
+volatile unsigned int num_spurious;
+
+#define NUM_IRQ_NODES 16
+static irq_node_t nodes[NUM_IRQ_NODES];
+
+/* (es) */
+/* note: maybe EZ and VZ should just also define CONFIG_M68328? */
+#if defined( CONFIG_M68328 ) || defined ( CONFIG_M68EZ328 ) || defined ( CONFIG_M68VZ328 )
+ 
+asm (
+	"\t.global _start, __ramend\n"
+#ifdef CONFIG_RELOCATE
+	"\t.global __rom_start\n"
+#endif
+	"\t.section .romvec\n"
+"e_vectors:\n"
+	"\t.long __ramend-4,"
+#ifdef CONFIG_RELOCATE
+		"__rom_start,"
+#else
+		"_start,"
+#endif
+		"buserr, trap, trap, trap, trap, trap\n"
+	"\t.long trap, trap, trap, trap, trap, trap, trap, trap\n"
+	"\t.long trap, trap, trap, trap, trap, trap, trap, trap\n"
+	"\t.long trap, trap, trap, trap\n"
+	"\t.long trap, trap, trap, trap\n"
+	/*"\t.long inthandler, inthandler, inthandler, inthandler\n"
+	  "\t.long inthandler4, inthandler, inthandler, inthandler\n" */
+	/* TRAP #0-15 */
+	"\t.long system_call, trap, trap, trap, trap, trap, trap, trap\n"
+	"\t.long trap, trap, trap, trap, trap, trap, trap, trap\n"
+	"\t.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n"
+	"\t.text\n"
+
+"ignore: rte"
+	);
+
+#endif /* CONFIG_M68328 || CONFIG_M68EZ328 || CONFIG_M68VZ328 */
+/* (/es) */
+
+/*
+ * void init_IRQ(void)
+ *
+ * Parameters:	None
+ *
+ * Returns:	Nothing
+ *
+ * This function should be called during kernel startup to initialize
+ * the IRQ handling routines.
+ */
+
+void init_IRQ(void)
+{
+	int i;
+
+	for (i = 0; i < SYS_IRQS; i++) {
+		if (mach_default_handler)
+			irq_list[i].handler = (*mach_default_handler)[i];
+		else
+			irq_list[i].handler = NULL;
+			irq_list[i].flags   = IRQ_FLG_STD;
+			irq_list[i].dev_id  = NULL;
+			irq_list[i].devname = default_names[i];
+	}
+
+	for (i = 0; i < NUM_IRQ_NODES; i++)
+		nodes[i].handler = NULL;
+
+	mach_init_IRQ ();
+}
+
+irq_node_t *new_irq_node(void)
+{
+	irq_node_t *node;
+	short i;
+
+	for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--)
+		if (!node->handler)
+			return node;
+
+	printk ("new_irq_node: out of nodes\n");
+	return NULL;
+}
+
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                unsigned long flags, const char *devname, void *dev_id)
+{
+    return mach_request_irq(irq, handler, flags, devname, dev_id);
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+    mach_free_irq(irq, dev_id);
+    return;
+}
+
+/*
+ * Do we need these probe functions on the m68k?
+ */
+unsigned long probe_irq_on (void)
+{
+	return 0;
+}
+
+int probe_irq_off (unsigned long irqs)
+{
+	return 0;
+}
+
+asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
+{
+	if (vec >= VEC_INT1 && vec <= VEC_INT7) {
+                vec -= VEC_SPUR;
+                kstat.irqs[0][vec]++;
+                irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
+	} else {
+                if (mach_process_int)
+                        mach_process_int(vec, fp);
+                else
+                        panic("Can't process interrupt vector %ld\n", vec);
+                return;
+	}
+}
+
+int get_irq_list(char *buf)
+{
+        int i, len = 0;
+	
+        /* autovector interrupts */
+        if (mach_default_handler) {
+                for (i = 0; i < SYS_IRQS; i++) {
+                       len += sprintf(buf+len, "auto %2d: %10u ", i,
+		       i ? kstat.irqs[0][i] : num_spurious);
+                       len += sprintf(buf+len, "  ");
+                       len += sprintf(buf+len, "%s\n", irq_list[i].devname);
+
+		}
+        }
+        len += mach_get_irq_list(buf+len);
+        return len;
+}
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+
+void dump(struct pt_regs *fp)
+{
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk("\nCURRENT PROCESS:\n\n");
+#if 0
+{
+	extern int	swt_lastjiffies, swt_reference;
+	printk("WATCHDOG: jiffies=%d lastjiffies=%d [%d] reference=%d\n",
+		jiffies, swt_lastjiffies, (swt_lastjiffies - jiffies),
+		swt_reference);
+}
+#endif
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+		printk("USER-STACK=%08x\n\n",
+			(int) current->mm->start_stack);
+	}
+
+	printk("PC: %08lx\n", fp->pc);
+	printk("SR: %08lx    SP: %08lx\n", (long) fp->sr, (long) fp);
+	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+		fp->d0, fp->d1, fp->d2, fp->d3);
+	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+		fp->d4, fp->d5, fp->a0, fp->a1);
+	printk("\nUSP: %08x   TRAPFRAME: %08x\n",
+			(unsigned int) rdusp(), (unsigned int) fp);
+
+	printk("\nCODE:");
+	tp = ((unsigned char *) fp->pc) - 0x20;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+/*
+       if (STACK_MAGIC != *(unsigned long *)current->kernel_stack_page)
+                printk("(Possibly corrupted stack page??)\n");
+	printk("\n");
+*/
+	printk("\nUSER STACK:");
+	tp = (unsigned char *) (rdusp() - 0x10);
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n\n");
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/config.c linux-2.4.29-uc1/arch/m68knommu/platform/68360/config.c
--- linux-2.4.29/arch/m68knommu/platform/68360/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/config.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,209 @@
+/*
+ *  linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c
+ *
+ *  Copyright (c) 2000 Michael Leslie <mleslie@ArcturusNetworks.com>
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999 D. Jeff Dionne <jeff@uclinux.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+
+#ifdef CONFIG_UCQUICC
+#include "uCquicc/bootstd.h"
+#endif
+
+#ifdef CONFIG_PILOT
+#include "PalmV/romfs.h"
+#endif
+
+#include <asm/m68360.h>
+void M68360_init_IRQ(void);
+
+extern QUICC *pquicc;
+
+/* TODO  DON"T Hard Code this */
+/* calculate properly using the right PLL and prescaller */
+// unsigned int system_clock = 33000000l;
+extern unsigned long int system_clock; //In kernel setup.c
+
+
+//extern void register_console(void (*proc)(const char *));
+
+extern void config_M68360_irq(void);
+
+
+void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
+{
+  unsigned char prescaler;
+  unsigned short tgcr_save;
+  int return_value;
+
+#if 0
+  /* Restart mode, Enable int, 32KHz, Enable timer */
+  TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
+  /* Set prescaler (Divide 32KHz by 32)*/
+  TPRER = 31;
+  /* Set compare register  32Khz / 32 / 10 = 100 */
+  TCMP = 10;                                                              
+
+  request_irq(IRQ_MACHSPEC | 1, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+#endif
+
+  /* General purpose quicc timers: MC68360UM p7-20 */
+
+  /* Set up timer 1 (in [1..4]) to do 100Hz */
+  tgcr_save = pquicc->timer_tgcr & 0xfff0;
+  pquicc->timer_tgcr  = tgcr_save; /* stop and reset timer 1 */
+  /* pquicc->timer_tgcr |= 0x4444; */ /* halt timers when FREEZE (ie bdm freeze) */
+
+  prescaler = 8;
+  pquicc->timer_tmr1 = 0x001a | /* or=1, frr=1, iclk=01b */
+                           (unsigned short)((prescaler - 1) << 8);
+    
+  pquicc->timer_tcn1 = 0x0000; /* initial count */
+  /* calculate interval for 100Hz based on the _system_clock: */
+  pquicc->timer_trr1 = (system_clock/ prescaler) / HZ; /* reference count */
+
+  pquicc->timer_ter1 = 0x0003; /* clear timer events */
+
+  /* enable timer 1 interrupt in CIMR */
+//  request_irq(IRQ_MACHSPEC | CPMVEC_TIMER1, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+  //return_value = request_irq( CPMVEC_TIMER1, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+  return_value = request_irq(CPMVEC_TIMER1 , timer_routine, IRQ_FLG_LOCK,
+          "Timer", NULL);
+
+  /* Start timer 1: */
+  tgcr_save = (pquicc->timer_tgcr & 0xfff0) | 0x0001;
+  pquicc->timer_tgcr  = tgcr_save;
+}
+
+
+void BSP_tick(void)
+{
+  /* Reset Timer1 */
+  /* TSTAT &= 0; */
+
+  pquicc->timer_ter1 = 0x0002; /* clear timer event */  
+}
+
+unsigned long BSP_gettimeoffset (void)
+{
+  return 0;
+}
+
+void BSP_gettod (int *yearp, int *monp, int *dayp,
+		   int *hourp, int *minp, int *secp)
+{
+	*yearp = *monp = *dayp = *hourp = *minp = *secp = 0;
+}
+
+int BSP_hwclk(int op, struct hwclk_time *t)
+{
+  if (!op) {
+    /* read */
+  } else {
+    /* write */
+  }
+  return 0;
+}
+
+int BSP_set_clock_mmss (unsigned long nowtime)
+{
+#if 0
+  short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+
+  tod->second1 = real_seconds / 10;
+  tod->second2 = real_seconds % 10;
+  tod->minute1 = real_minutes / 10;
+  tod->minute2 = real_minutes % 10;
+#endif
+  return 0;
+}
+
+void BSP_reset (void)
+{
+  cli();
+/*   asm volatile (" */
+/*     moveal #0x10c00000, %a0; */
+/*     moveb #0, 0xFFFFF300; */
+/*     moveal 0(%a0), %sp; */
+/*     moveal 4(%a0), %a0; */
+/*     jmp (%a0); */
+/*     "); */
+
+  asm volatile ("
+    moveal #_start, %a0;
+    moveb #0, 0xFFFFF300;
+    moveal 0(%a0), %sp;
+    moveal 4(%a0), %a0;
+    jmp (%a0);
+    ");
+
+
+}
+
+unsigned char *scc1_hwaddr;
+static int errno;
+
+#if defined (CONFIG_UCQUICC)
+_bsc0(char *, getserialnum)
+_bsc1(unsigned char *, gethwaddr, int, a)
+_bsc1(char *, getbenv, char *, a)
+#endif
+
+
+void config_BSP(char *command, int len)
+{
+  unsigned char *p;
+/* #if defined (CONFIG_M68360_SMC_UART) */
+/*   extern void console_print_68360(const char * b); */
+/*   register_console(console_print_68360); */
+/* #endif   */
+
+  printk("\n68360 QUICC support (C) 2000 Lineo Inc.\n");
+
+#if defined(CONFIG_UCQUICC) && 0
+  printk("uCquicc serial string [%s]\n",getserialnum());
+  p = scc1_hwaddr = gethwaddr(0);
+  printk("uCquicc hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+         p[0], p[1], p[2], p[3], p[4], p[5]);
+
+  p = getbenv("APPEND");
+  if (p)
+    strcpy(p,command);
+  else
+    command[0] = 0;
+#else
+  scc1_hwaddr = "\00\01\02\03\04\05";
+#endif
+ 
+  mach_sched_init      = BSP_sched_init;
+  mach_tick            = BSP_tick;
+  mach_gettimeoffset   = BSP_gettimeoffset;
+  mach_gettod          = BSP_gettod;
+  mach_hwclk           = NULL;
+  mach_set_clock_mmss  = NULL;
+//  mach_mksound         = NULL;
+  mach_reset           = BSP_reset;
+  //Kendrick's Change
+  mach_trap_init        = M68360_init_IRQ;
+ // mach_debug_init      = NULL;
+
+  config_M68360_irq();
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/entry.S linux-2.4.29-uc1/arch/m68knommu/platform/68360/entry.S
--- linux-2.4.29/arch/m68knommu/platform/68360/entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/entry.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,608 @@
+/* -*- mode: asm -*-
+ *
+ *  linux/arch/m68knommu/platform/68360/entry.S
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 2001 SED Systems, a Division of Calian Ltd.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ * Linux/m68k support by Hamish Macdonald
+ * M68360 Port by SED Systems, and Lineo.
+ *
+ */
+
+/*
+ * entry.S  contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all interrupts
+ * and faults that can result in a task-switch.
+ *
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ *
+ */
+
+/*
+ * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so
+ *               all pointers that used to be 'current' are now entry
+ *               number 0 in the 'current_set' list.
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+
+#include <asm/entry.h>
+#include <asm/errno.h>
+#include <asm/traps.h>
+
+#include "m68k_defs.h"
+
+#define IMMED #
+#define DBG_PUTC(x) moveb IMMED x,0xfffff907; \
+					moveb IMMED '\r',0xfffff907; \
+					moveb IMMED '\n',0xfffff907
+LD0         =   0x20
+LORIG_D0    =   0x24
+
+.globl SYMBOL_NAME(system_call)
+.globl SYMBOL_NAME(buserr)
+.globl SYMBOL_NAME(trap)
+.globl SYMBOL_NAME(resume)
+.globl SYMBOL_NAME(ret_from_exception)
+.globl SYMBOL_NAME(ret_from_signal)
+.globl SYMBOL_NAME(sys_call_table)
+.globl SYMBOL_NAME(sys_fork)
+.globl SYMBOL_NAME(sys_clone)
+.globl SYMBOL_NAME(sys_vfork)
+.globl SYMBOL_NAME(ret_from_interrupt)
+.globl SYMBOL_NAME(bad_interrupt)
+.globl SYMBOL_NAME(inthandler)
+
+.text
+ENTRY(buserr)
+	SAVE_ALL_INT
+	/* GET_CURRENT(%d0) */
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(buserr_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(trap)
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+    moveq.l #-1,%d0
+    move.l  %d0,%sp@(LORIG_D0)
+/* may have to test for LFORMATVEC here as was done in teh 2.0 module */
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+
+ENTRY(reschedule)
+
+	/* save top of frame*/
+	movel   SYMBOL_NAME(_current_task),%a2
+	movel	%sp,%a2@(TASK_THREAD+THREAD_ESP0)
+
+	pea	SYMBOL_NAME(ret_from_exception)
+	jmp	SYMBOL_NAME(schedule)
+
+	/* After a fork we jump here directly from resume,*/
+	/* so that %d1 contains the previous task*/
+	/* Theoretically only needed on SMP, but let's watch*/
+	/* what happens in schedule_tail() in future...*/
+ENTRY(ret_from_fork)
+	movel	%d1,%sp@-
+	jsr	SYMBOL_NAME(schedule_tail)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+badsys:
+	movel	#-ENOSYS,%sp@(PT_D0)
+	jra	SYMBOL_NAME(ret_from_exception)
+
+do_trace:
+	movel	#-ENOSYS,%sp@(PT_D0)	/* needed for strace*/
+	subql	#4,%sp
+	SAVE_SWITCH_STACK
+	jbsr	SYMBOL_NAME(syscall_trace)
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+	movel	%sp@(PT_ORIG_D0),%d1
+	movel	#-ENOSYS,%d0
+	cmpl	#NR_syscalls,%d1
+	jcc	1f
+/*	jbsr	@(SYMBOL_NAME(sys_call_table),%d1:l:4)@(0) */
+	lsl	#2,%d1
+#if 1
+	lea	SYMBOL_NAME(sys_call_table), %a0
+	jbsr	%a0@(%d1)
+#else
+	bsrw	SYMBOL_NAME(sys_call_table)@(%d1)
+#endif
+
+1:	movel	%d0,%sp@(PT_D0)		/* save the return value*/
+	subql	#4,%sp			/* dummy return address*/
+	SAVE_SWITCH_STACK
+	jbsr	SYMBOL_NAME(syscall_trace)
+
+SYMBOL_NAME_LABEL(ret_from_signal)
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(system_call)
+	SAVE_ALL_SYS
+
+	GET_CURRENT(%d1)
+	/* save top of frame*/
+	movel   SYMBOL_NAME(_current_task),%a2
+	movel	%sp,%a2@(TASK_THREAD+THREAD_ESP0)
+
+	btst	#PF_TRACESYS_BIT,%a2@(TASK_FLAGS+PF_TRACESYS_OFF)
+	jne	do_trace
+	cmpl	#NR_syscalls,%d0
+	jcc	badsys
+/*	jbsr	@(SYMBOL_NAME(sys_call_table),%d0:l:4)@(0) */
+	lsl	#2,%d0
+#if 1
+	lea	SYMBOL_NAME(sys_call_table),%a0
+	movel	%a0@(%d0), %a0
+	jbsr	%a0@
+#else
+	jbsr	SYMBOL_NAME(sys_call_table)@(%d0)
+#endif
+	movel	%d0,%sp@(PT_D0)		/* save the return value*/
+
+SYMBOL_NAME_LABEL(ret_from_exception)
+	btst	#5,%sp@(PT_SR)		/* check if returning to kernel*/
+	bnes	2f			/* if so, skip resched, signals*/
+	/* only allow interrupts when we are really the last one on the*/
+	/* kernel stack, otherwise stack overflow can occur during*/
+	/* heavy interupt load*/
+	andw	#ALLOWINT,%sr
+	movel   SYMBOL_NAME(_current_task),%a2
+	tstl	%a2@(TASK_NEEDRESCHED)
+	jne	SYMBOL_NAME(reschedule)
+#if 0
+	cmpl	#SYMBOL_NAME(task),%a2	/* task[0] cannot have signals*/
+	jeq	2f
+#endif
+					/* check for delayed trace*/
+	bclr	#PF_DTRACE_BIT,%a2@(TASK_FLAGS+PF_DTRACE_OFF)
+	jne	do_delayed_trace
+5:
+	tstl	%a2@(TASK_STATE)	/* state*/
+	jne	SYMBOL_NAME(reschedule)
+
+	tstl	%a2@(TASK_SIGPENDING)
+	jne	Lsignal_return
+2:	RESTORE_ALL
+
+Lsignal_return:
+	subql	#4,%sp			/* dummy return address*/
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	clrl	%sp@-
+	bsrw	SYMBOL_NAME(do_signal)
+	addql	#8,%sp
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+
+	/*
+	 * if an app is getting tricky and using "a5",  the signal handler
+	 * may trigger while "a5" is invalid,  so we have to set it here
+	 */
+	jbsr 	SYMBOL_NAME(get_pic_a5)
+	movel	%d0, %a5
+
+	RESTORE_ALL
+
+do_delayed_trace:
+	bclr	#7,%sp@(PT_SR)		/* clear trace bit in SR*/
+	pea	1			/* send SIGTRAP*/
+	movel	%a2,%sp@-
+	pea	LSIGTRAP
+	jbsr	SYMBOL_NAME(send_sig)
+	addql	#8,%sp
+	addql	#4,%sp
+	jra	5b
+/*
+** This is the main interrupt handler, responsible for calling process_int()
+*/
+
+SYMBOL_NAME_LABEL(inthandler)
+	SAVE_ALL_INT
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+					/*  put exception # in d0*/
+/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
+	movew	%sp@(PT_VECTOR), %d0
+	and.l	#0x3ff, %d0
+    lsr.l   #0x02,  %d0
+
+	movel	%sp,%sp@-
+	movel	%d0,%sp@- 		/*  put vector # on stack*/
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+3:     	addql	#8,%sp			/*  pop parameters off stack*/
+	bra	ret_from_interrupt
+
+SYMBOL_NAME_LABEL(ret_from_interrupt)
+	subql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	jeq	1f
+2:
+	RESTORE_ALL
+1:
+	moveq   #(~ALLOWINT>>8)&0xff,%d0
+	andb    %sp@(PT_SR),%d0
+	jne 2b
+
+	/* check if we need to do software interrupts */
+
+	movel	SYMBOL_NAME(irq_stat)+CPUSTAT_SOFTIRQ_PENDING,%d0
+	jeq	SYMBOL_NAME(ret_from_exception)
+
+	pea	SYMBOL_NAME(ret_from_exception)
+	jra	SYMBOL_NAME(do_softirq)
+
+
+/* Handler for uninitialized and spurious interrupts */
+
+SYMBOL_NAME_LABEL(bad_interrupt)
+	addql	#1,SYMBOL_NAME(num_spurious)
+	rte
+
+ENTRY(sys_fork)
+	SAVE_SWITCH_STACK	
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(m68k_fork)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_clone)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(m68k_clone)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_vfork)
+	SAVE_SWITCH_STACK	
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(m68k_vfork)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(do_sigsuspend)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(do_rt_sigsuspend)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_sigreturn)
+	SAVE_SWITCH_STACK
+	jbsr	SYMBOL_NAME(do_sigreturn)
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigreturn)
+	SAVE_SWITCH_STACK
+	jbsr	SYMBOL_NAME(do_rt_sigreturn)
+	RESTORE_SWITCH_STACK
+	rts
+
+SYMBOL_NAME_LABEL(resume)
+	/*
+	 * Beware - when entering resume, prev (the current task) is
+	 * in a0, next (the new task) is in a1,so don't change these
+	 * registers until their contents are no longer needed.
+	 */
+
+	/* save sr */
+	movew	%sr,%a0@(TASK_THREAD+THREAD_SR)
+#ifdef USE_SFC_DFC
+	/* save fs (sfc,%dfc) (may be pointing to kernel memory) */
+	movec	%sfc,%d0
+	movew	%d0,%a0@(TASK_THREAD+THREAD_FS)
+#endif
+
+	/* save non-scratch registers on stack */
+	SAVE_SWITCH_STACK
+
+	/* save usp */
+	/* it is better to use a movel here instead of a movew 8*) */
+	movel	%usp,%a2
+	movel	%a2,%a0@(TASK_THREAD+THREAD_USP)
+
+	/* save current kernel stack pointer */
+	movel	%sp,%a0@(TASK_THREAD+THREAD_KSP)
+
+	/* Return previous task in %d1 */
+	movel   SYMBOL_NAME(_current_task),%d1
+
+	/* switch to new task (a1 contains new task) */
+	movel   %a1, SYMBOL_NAME(_current_task)
+
+	/* restore the kernel stack pointer */
+	movel	%a1@(TASK_THREAD+THREAD_KSP),%sp
+
+	/* restore non-scratch registers */
+	RESTORE_SWITCH_STACK
+
+	/* restore user stack pointer */
+	movel	%a1@(TASK_THREAD+THREAD_USP),%a0
+	movel	%a0,%usp
+
+#ifdef USE_SFC_DFC
+	/* restore fs (sfc,%dfc) */
+	movew	%a1@(TASK_THREAD+THREAD_FS),%a0
+	movec	%a0,%sfc
+	movec	%a0,%dfc
+#endif
+	/* restore status register */
+	movew	%a1@(TASK_THREAD+THREAD_SR),%sr
+
+	rts
+
+
+.data
+ALIGN
+SYMBOL_NAME_LABEL(sys_call_table)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 0  -  old "setup()" system call*/
+	.long SYMBOL_NAME(sys_exit)
+	.long SYMBOL_NAME(sys_fork)
+	.long SYMBOL_NAME(sys_read)
+	.long SYMBOL_NAME(sys_write)
+	.long SYMBOL_NAME(sys_open)		/* 5 */
+	.long SYMBOL_NAME(sys_close)
+	.long SYMBOL_NAME(sys_waitpid)
+	.long SYMBOL_NAME(sys_creat)
+	.long SYMBOL_NAME(sys_link)
+	.long SYMBOL_NAME(sys_unlink)		/* 10 */
+	.long SYMBOL_NAME(sys_execve)
+	.long SYMBOL_NAME(sys_chdir)
+	.long SYMBOL_NAME(sys_time)
+	.long SYMBOL_NAME(sys_mknod)
+	.long SYMBOL_NAME(sys_chmod)		/* 15 */
+	.long SYMBOL_NAME(sys_chown16)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old break syscall holder */
+	.long SYMBOL_NAME(sys_stat)
+	.long SYMBOL_NAME(sys_lseek)
+	.long SYMBOL_NAME(sys_getpid)		/* 20 */
+	.long SYMBOL_NAME(sys_mount)
+	.long SYMBOL_NAME(sys_oldumount)
+	.long SYMBOL_NAME(sys_setuid16)
+	.long SYMBOL_NAME(sys_getuid16)
+	.long SYMBOL_NAME(sys_stime)		/* 25 */
+	.long SYMBOL_NAME(sys_ptrace)
+	.long SYMBOL_NAME(sys_alarm)
+	.long SYMBOL_NAME(sys_fstat)
+	.long SYMBOL_NAME(sys_pause)
+	.long SYMBOL_NAME(sys_utime)		/* 30 */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old stty syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old gtty syscall holder */
+	.long SYMBOL_NAME(sys_access)
+	.long SYMBOL_NAME(sys_nice)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 35 */		/* old ftime syscall holder */
+	.long SYMBOL_NAME(sys_sync)
+	.long SYMBOL_NAME(sys_kill)
+	.long SYMBOL_NAME(sys_rename)
+	.long SYMBOL_NAME(sys_mkdir)
+	.long SYMBOL_NAME(sys_rmdir)		/* 40 */
+	.long SYMBOL_NAME(sys_dup)
+	.long SYMBOL_NAME(sys_pipe)
+	.long SYMBOL_NAME(sys_times)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old prof syscall holder */
+	.long SYMBOL_NAME(sys_brk)		/* 45 */
+	.long SYMBOL_NAME(sys_setgid16)
+	.long SYMBOL_NAME(sys_getgid16)
+	.long SYMBOL_NAME(sys_signal)
+	.long SYMBOL_NAME(sys_geteuid16)
+	.long SYMBOL_NAME(sys_getegid16)	/* 50 */
+	.long SYMBOL_NAME(sys_acct)
+	.long SYMBOL_NAME(sys_umount)					/* recycled never used phys() */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old lock syscall holder */
+	.long SYMBOL_NAME(sys_ioctl)
+	.long SYMBOL_NAME(sys_fcntl)		/* 55 */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old mpx syscall holder */
+	.long SYMBOL_NAME(sys_setpgid)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old ulimit syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_umask)		/* 60 */
+	.long SYMBOL_NAME(sys_chroot)
+	.long SYMBOL_NAME(sys_ustat)
+	.long SYMBOL_NAME(sys_dup2)
+	.long SYMBOL_NAME(sys_getppid)
+	.long SYMBOL_NAME(sys_getpgrp)		/* 65 */
+	.long SYMBOL_NAME(sys_setsid)
+	.long SYMBOL_NAME(sys_sigaction)
+	.long SYMBOL_NAME(sys_sgetmask)
+	.long SYMBOL_NAME(sys_ssetmask)
+	.long SYMBOL_NAME(sys_setreuid16)	/* 70 */
+	.long SYMBOL_NAME(sys_setregid16)
+	.long SYMBOL_NAME(sys_sigsuspend)
+	.long SYMBOL_NAME(sys_sigpending)
+	.long SYMBOL_NAME(sys_sethostname)
+	.long SYMBOL_NAME(sys_setrlimit)	/* 75 */
+	.long SYMBOL_NAME(sys_old_getrlimit)
+	.long SYMBOL_NAME(sys_getrusage)
+	.long SYMBOL_NAME(sys_gettimeofday)
+	.long SYMBOL_NAME(sys_settimeofday)
+	.long SYMBOL_NAME(sys_getgroups16)	/* 80 */
+	.long SYMBOL_NAME(sys_setgroups16)
+	.long SYMBOL_NAME(old_select)
+	.long SYMBOL_NAME(sys_symlink)
+	.long SYMBOL_NAME(sys_lstat)
+	.long SYMBOL_NAME(sys_readlink)		/* 85 */
+	.long SYMBOL_NAME(sys_uselib)
+	.long SYMBOL_NAME(sys_swapon)
+	.long SYMBOL_NAME(sys_reboot)
+	.long SYMBOL_NAME(old_readdir)
+	.long SYMBOL_NAME(old_mmap)		/* 90 */
+	.long SYMBOL_NAME(sys_munmap)
+	.long SYMBOL_NAME(sys_truncate)
+	.long SYMBOL_NAME(sys_ftruncate)
+	.long SYMBOL_NAME(sys_fchmod)
+	.long SYMBOL_NAME(sys_fchown16)		/* 95 */
+	.long SYMBOL_NAME(sys_getpriority)
+	.long SYMBOL_NAME(sys_setpriority)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old profil syscall holder */
+	.long SYMBOL_NAME(sys_statfs)
+	.long SYMBOL_NAME(sys_fstatfs)		/* 100 */
+	.long SYMBOL_NAME(sys_ioperm)
+	.long SYMBOL_NAME(sys_socketcall)
+	.long SYMBOL_NAME(sys_syslog)
+	.long SYMBOL_NAME(sys_setitimer)
+	.long SYMBOL_NAME(sys_getitimer)	/* 105 */
+	.long SYMBOL_NAME(sys_newstat)
+	.long SYMBOL_NAME(sys_newlstat)
+	.long SYMBOL_NAME(sys_newfstat)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* iopl for i386 */ /* 110 */
+	.long SYMBOL_NAME(sys_vhangup)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* obsolete idle() syscall */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* vm86old for i386 */
+	.long SYMBOL_NAME(sys_wait4)
+	.long SYMBOL_NAME(sys_swapoff)		/* 115 */
+	.long SYMBOL_NAME(sys_sysinfo)
+	.long SYMBOL_NAME(sys_ipc)
+	.long SYMBOL_NAME(sys_fsync)
+	.long SYMBOL_NAME(sys_sigreturn)
+	.long SYMBOL_NAME(sys_clone)		/* 120 */
+	.long SYMBOL_NAME(sys_setdomainname)
+	.long SYMBOL_NAME(sys_newuname)
+	.long SYMBOL_NAME(sys_cacheflush)	/* modify_ldt for i386 */
+	.long SYMBOL_NAME(sys_adjtimex)
+	.long SYMBOL_NAME(sys_mprotect)		/* 125 */
+	.long SYMBOL_NAME(sys_sigprocmask)
+	.long SYMBOL_NAME(sys_create_module)
+	.long SYMBOL_NAME(sys_init_module)
+	.long SYMBOL_NAME(sys_delete_module)
+	.long SYMBOL_NAME(sys_get_kernel_syms)	/* 130 */
+	.long SYMBOL_NAME(sys_quotactl)
+	.long SYMBOL_NAME(sys_getpgid)
+	.long SYMBOL_NAME(sys_fchdir)
+	.long SYMBOL_NAME(sys_bdflush)
+	.long SYMBOL_NAME(sys_sysfs)		/* 135 */
+	.long SYMBOL_NAME(sys_personality)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for afs_syscall */
+	.long SYMBOL_NAME(sys_setfsuid16)
+	.long SYMBOL_NAME(sys_setfsgid16)
+	.long SYMBOL_NAME(sys_llseek)		/* 140 */
+	.long SYMBOL_NAME(sys_getdents)
+	.long SYMBOL_NAME(sys_select)
+	.long SYMBOL_NAME(sys_flock)
+	.long SYMBOL_NAME(sys_msync)
+	.long SYMBOL_NAME(sys_readv)		/* 145 */
+	.long SYMBOL_NAME(sys_writev)
+	.long SYMBOL_NAME(sys_getsid)
+	.long SYMBOL_NAME(sys_fdatasync)
+	.long SYMBOL_NAME(sys_sysctl)
+	.long SYMBOL_NAME(sys_mlock)		/* 150 */
+	.long SYMBOL_NAME(sys_munlock)
+	.long SYMBOL_NAME(sys_mlockall)
+	.long SYMBOL_NAME(sys_munlockall)
+	.long SYMBOL_NAME(sys_sched_setparam)
+	.long SYMBOL_NAME(sys_sched_getparam)   /* 155 */
+	.long SYMBOL_NAME(sys_sched_setscheduler)
+	.long SYMBOL_NAME(sys_sched_getscheduler)
+	.long SYMBOL_NAME(sys_sched_yield)
+	.long SYMBOL_NAME(sys_sched_get_priority_max)
+	.long SYMBOL_NAME(sys_sched_get_priority_min)  /* 160 */
+	.long SYMBOL_NAME(sys_sched_rr_get_interval)
+	.long SYMBOL_NAME(sys_nanosleep)
+	.long SYMBOL_NAME(sys_mremap)
+	.long SYMBOL_NAME(sys_setresuid16)
+	.long SYMBOL_NAME(sys_getresuid16)	/* 165 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for vm86 */
+	.long SYMBOL_NAME(sys_query_module)
+	.long SYMBOL_NAME(sys_poll)
+	.long SYMBOL_NAME(sys_nfsservctl)
+	.long SYMBOL_NAME(sys_setresgid16)	/* 170 */
+	.long SYMBOL_NAME(sys_getresgid16)
+	.long SYMBOL_NAME(sys_prctl)
+	.long SYMBOL_NAME(sys_rt_sigreturn)
+	.long SYMBOL_NAME(sys_rt_sigaction)
+	.long SYMBOL_NAME(sys_rt_sigprocmask)	/* 175 */
+	.long SYMBOL_NAME(sys_rt_sigpending)
+	.long SYMBOL_NAME(sys_rt_sigtimedwait)
+	.long SYMBOL_NAME(sys_rt_sigqueueinfo)
+	.long SYMBOL_NAME(sys_rt_sigsuspend)
+	.long SYMBOL_NAME(sys_pread)		/* 180 */
+	.long SYMBOL_NAME(sys_pwrite)
+	.long SYMBOL_NAME(sys_lchown16);
+	.long SYMBOL_NAME(sys_getcwd)
+	.long SYMBOL_NAME(sys_capget)
+	.long SYMBOL_NAME(sys_capset)           /* 185 */
+	.long SYMBOL_NAME(sys_sigaltstack)
+	.long SYMBOL_NAME(sys_sendfile)
+	.long SYMBOL_NAME(sys_ni_syscall)		/* streams1 */
+	.long SYMBOL_NAME(sys_ni_syscall)		/* streams2 */
+	.long SYMBOL_NAME(sys_vfork)            /* 190 */
+	.long SYMBOL_NAME(sys_getrlimit)
+	.long SYMBOL_NAME(sys_mmap2)
+	.long SYMBOL_NAME(sys_truncate64)
+	.long SYMBOL_NAME(sys_ftruncate64)
+	.long SYMBOL_NAME(sys_stat64)		/* 195 */
+	.long SYMBOL_NAME(sys_lstat64)
+	.long SYMBOL_NAME(sys_fstat64)
+	.long SYMBOL_NAME(sys_chown)
+	.long SYMBOL_NAME(sys_getuid)
+	.long SYMBOL_NAME(sys_getgid)		/* 200 */
+	.long SYMBOL_NAME(sys_geteuid)
+	.long SYMBOL_NAME(sys_getegid)
+	.long SYMBOL_NAME(sys_setreuid)
+	.long SYMBOL_NAME(sys_setregid)
+	.long SYMBOL_NAME(sys_getgroups)	/* 205 */
+	.long SYMBOL_NAME(sys_setgroups)
+	.long SYMBOL_NAME(sys_fchown)
+	.long SYMBOL_NAME(sys_setresuid)
+	.long SYMBOL_NAME(sys_getresuid)
+	.long SYMBOL_NAME(sys_setresgid)	/* 210 */
+	.long SYMBOL_NAME(sys_getresgid)
+	.long SYMBOL_NAME(sys_lchown)
+	.long SYMBOL_NAME(sys_setuid)
+	.long SYMBOL_NAME(sys_setgid)
+	.long SYMBOL_NAME(sys_setfsuid)		/* 215 */
+	.long SYMBOL_NAME(sys_setfsgid)
+	.long SYMBOL_NAME(sys_pivot_root)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
+	.long SYMBOL_NAME(sys_gettid)
+	.long SYMBOL_NAME(sys_tkill)
+	.long SYMBOL_NAME(sys_setxattr)
+	.long SYMBOL_NAME(sys_lsetxattr)
+	.long SYMBOL_NAME(sys_fsetxattr)	/* 225 */
+	.long SYMBOL_NAME(sys_getxattr)
+	.long SYMBOL_NAME(sys_lgetxattr)
+	.long SYMBOL_NAME(sys_fgetxattr)
+	.long SYMBOL_NAME(sys_listxattr)
+	.long SYMBOL_NAME(sys_llistxattr)	/* 230 */
+	.long SYMBOL_NAME(sys_flistxattr)
+	.long SYMBOL_NAME(sys_removexattr)
+	.long SYMBOL_NAME(sys_lremovexattr)
+	.long SYMBOL_NAME(sys_fremovexattr)
+
+	.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
+		.long SYMBOL_NAME(sys_ni_syscall)
+	.endr
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/ints.c linux-2.4.29-uc1/arch/m68knommu/platform/68360/ints.c
--- linux-2.4.29/arch/m68knommu/platform/68360/ints.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/ints.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,414 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2000  Michael Leslie <mleslie@ArcturusNetworks.com>
+ * Copyright (c) 1996 Roman Zippel
+ * Copyright (c) 1999 D. Jeff Dionne <jeff@uclinux.org>
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+
+#include <asm/m68360.h>
+
+
+/* from quicc/commproc.c: */
+extern QUICC *pquicc;
+extern void cpm_interrupt_init(void);
+
+
+
+#define INTERNAL_IRQS (96)
+
+/* assembler routines */
+asmlinkage void system_call(void);
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void bad_interrupt(void);
+asmlinkage void inthandler(void);
+
+extern void *_ramvec[];
+
+/* irq node variables for the 32 (potential) on chip sources */
+static irq_node_t *int_irq_list[INTERNAL_IRQS];
+
+static int int_irq_count[INTERNAL_IRQS];
+static short int_irq_ablecount[INTERNAL_IRQS];
+
+static void int_badint(int irq, void *dev_id, struct pt_regs *fp)
+{
+	num_spurious += 1;
+}
+
+/*
+ * This function should be called during kernel startup to initialize
+ * IRQ handling routines.
+ */
+
+void M68360_init_IRQ(void)
+{
+	int i;
+	int vba = (CPM_VECTOR_BASE<<4);
+
+	/* set up the vectors */
+#if 1
+	_ramvec[2] = buserr;
+	_ramvec[3] = trap;
+	_ramvec[4] = trap;
+	_ramvec[5] = trap;
+	_ramvec[6] = trap;
+	_ramvec[7] = trap;
+	_ramvec[8] = trap;
+	_ramvec[9] = trap;
+	_ramvec[10] = trap;
+	_ramvec[11] = trap;
+	_ramvec[12] = trap;
+	_ramvec[13] = trap;
+	_ramvec[14] = trap;
+	_ramvec[15] = trap;
+#endif
+
+	_ramvec[32] = system_call;
+	_ramvec[33] = trap;
+
+
+	cpm_interrupt_init();
+
+#if 1
+	/* set up CICR for vector base address and irq level */
+	/* irl = 4, hp = 1f - see MC68360UM p 7-377 */
+	pquicc->intr_cicr = 0x00e49f00 | vba;
+
+	/* CPM interrupt vectors: (p 7-376) */
+	_ramvec[vba+CPMVEC_ERROR]       = bad_interrupt; /* Error */
+	_ramvec[vba+CPMVEC_PIO_PC11]    = inthandler;   /* pio - pc11 */
+	_ramvec[vba+CPMVEC_PIO_PC10]    = inthandler;   /* pio - pc10 */
+	_ramvec[vba+CPMVEC_SMC2]        = inthandler;   /* smc2/pip */
+	_ramvec[vba+CPMVEC_SMC1]        = inthandler;   /* smc1 */
+	_ramvec[vba+CPMVEC_SPI]         = inthandler;   /* spi */
+	_ramvec[vba+CPMVEC_PIO_PC9]     = inthandler;   /* pio - pc9 */
+	_ramvec[vba+CPMVEC_TIMER4]      = inthandler;   /* timer 4 */
+	_ramvec[vba+CPMVEC_RESERVED1]   = inthandler;   /* reserved */
+	_ramvec[vba+CPMVEC_PIO_PC8]     = inthandler;   /* pio - pc8 */
+	_ramvec[vba+CPMVEC_PIO_PC7]     = inthandler;  /* pio - pc7 */
+	_ramvec[vba+CPMVEC_PIO_PC6]     = inthandler;  /* pio - pc6 */
+	_ramvec[vba+CPMVEC_TIMER3]      = inthandler;  /* timer 3 */
+	_ramvec[vba+CPMVEC_RISCTIMER]   = inthandler;  /* reserved */
+	_ramvec[vba+CPMVEC_PIO_PC5]     = inthandler;  /* pio - pc5 */
+	_ramvec[vba+CPMVEC_PIO_PC4]     = inthandler;  /* pio - pc4 */
+	_ramvec[vba+CPMVEC_RESERVED2]   = inthandler;  /* reserved */
+	_ramvec[vba+CPMVEC_RISCTIMER]   = inthandler;  /* timer table */
+	_ramvec[vba+CPMVEC_TIMER2]      = inthandler;  /* timer 2 */
+	_ramvec[vba+CPMVEC_RESERVED3]   = inthandler;  /* reserved */
+	_ramvec[vba+CPMVEC_IDMA2]       = inthandler;  /* idma 2 */
+	_ramvec[vba+CPMVEC_IDMA1]       = inthandler;  /* idma 1 */
+	_ramvec[vba+CPMVEC_SDMA_CB_ERR] = inthandler;  /* sdma channel bus error */
+	_ramvec[vba+CPMVEC_PIO_PC3]     = inthandler;  /* pio - pc3 */
+	_ramvec[vba+CPMVEC_PIO_PC2]     = inthandler;  /* pio - pc2 */
+	/* _ramvec[vba+CPMVEC_TIMER1]      = cpm_isr_timer1; */  /* timer 1 */
+	_ramvec[vba+CPMVEC_TIMER1]      = inthandler;  /* timer 1 */
+	_ramvec[vba+CPMVEC_PIO_PC1]     = inthandler;  /* pio - pc1 */
+	_ramvec[vba+CPMVEC_SCC4]        = inthandler;  /* scc 4 */
+	_ramvec[vba+CPMVEC_SCC3]        = inthandler;  /* scc 3 */
+	_ramvec[vba+CPMVEC_SCC2]        = inthandler;  /* scc 2 */
+	_ramvec[vba+CPMVEC_SCC1]        = inthandler;  /* scc 1 */
+	_ramvec[vba+CPMVEC_PIO_PC0]     = inthandler;  /* pio - pc0 */
+
+
+	/* turn off all CPM interrupts */
+	pquicc->intr_cimr = 0x00000000;
+
+#endif
+	/* initialize handlers */
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		int_irq_list[i] = NULL;
+
+		int_irq_ablecount[i] = 0;
+		int_irq_count[i] = 0;
+	}
+
+}
+
+
+void M68360_insert_irq(irq_node_t **list, irq_node_t *node)
+{
+	unsigned long flags;
+	irq_node_t *cur;
+
+	if (!node->dev_id)
+		printk("%s: Warning: dev_id of %s is zero\n",
+		       __FUNCTION__, node->devname);
+
+	save_flags(flags);
+	cli();
+
+	cur = *list;
+
+	while (cur) {
+		list = &cur->next;
+		cur = cur->next;
+	}
+
+	node->next = cur;
+	*list = node;
+
+	restore_flags(flags);
+}
+
+void M68360_delete_irq(irq_node_t **list, void *dev_id)
+{
+	unsigned long flags;
+	irq_node_t *node;
+
+	save_flags(flags);
+	cli();
+
+	for (node = *list; node; list = &node->next, node = *list) {
+		if (node->dev_id == dev_id) {
+			*list = node->next;
+			/* Mark it as free. */
+			node->handler = NULL;
+			restore_flags(flags);
+			return;
+		}
+	}
+	restore_flags(flags);
+	printk ("%s: tried to remove invalid irq\n", __FUNCTION__);
+}
+
+
+int M68360_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                         unsigned long flags, const char *devname, void *dev_id)
+{
+	int mask = (1<<irq);
+
+	irq += (CPM_VECTOR_BASE<<4);
+
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+	if (!int_irq_list[irq]) {
+		int_irq_list[irq] = new_irq_node();
+		int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	}
+
+	if (!(int_irq_list[irq]->flags & IRQ_FLG_STD)) {
+		if (int_irq_list[irq]->flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+	}
+	int_irq_list[irq]->handler = handler;
+	int_irq_list[irq]->flags   = flags;
+	int_irq_list[irq]->dev_id  = dev_id;
+	int_irq_list[irq]->devname = devname;
+
+	/* enable in the CIMR */
+	if (!int_irq_ablecount[irq])
+		pquicc->intr_cimr |= mask;
+	/*      *(volatile unsigned long *)0xfffff304 &= ~(1<<irq); */
+
+	return 0;
+}
+
+
+void M68360_free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_list[irq]->dev_id != dev_id)
+		printk("%s: removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, int_irq_list[irq]->devname);
+	int_irq_list[irq]->handler = int_badint;
+	int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	int_irq_list[irq]->dev_id  = NULL;
+	int_irq_list[irq]->devname = NULL;
+
+	*(volatile unsigned long *)0xfffff304 |= 1<<irq;
+}
+
+/*
+ * Enable/disable a particular machine specific interrupt source.
+ * Note that this may affect other interrupts in case of a shared interrupt.
+ * This function should only be called for a _very_ short time to change some
+ * internal data, that may not be changed by the interrupt at the same time.
+ * int_(enable|disable)_irq calls may also be nested.
+ */
+
+void M68360_enable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (--int_irq_ablecount[irq])
+		return;
+
+	/* enable the interrupt */
+	*(volatile unsigned long *)0xfffff304 &= ~(1<<irq);
+}
+
+void M68360_disable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_ablecount[irq]++)
+		return;
+
+	/* disable the interrupt */
+	*(volatile unsigned long *)0xfffff304 |= 1<<irq;
+}
+
+/* The 68k family did not have a good way to determine the source
+ * of interrupts until later in the family.  The EC000 core does
+ * not provide the vector number on the stack, we vector everything
+ * into one vector and look in the blasted mask register...
+ * This code is designed to be fast, almost constant time, not clean!
+ */
+inline int M68360_do_irq(int vec, struct pt_regs *fp)
+{
+	int irq;
+	int mask;
+
+	/* unsigned long pend = *(volatile unsigned long *)0xfffff30c; */
+
+	/* irq = vec + (CPM_VECTOR_BASE<<4); */
+	irq = vec;
+
+	/* unsigned long pend = *(volatile unsigned long *)pquicc->intr_cipr; */
+
+	/* Bugger all that wierdness. For the moment, I seem to know where I came from;
+	 * vec is passed from a specific ISR, so I'll use it. */
+
+	if (int_irq_list[irq] && int_irq_list[irq]->handler) {
+		int_irq_list[irq]->handler(irq , int_irq_list[irq]->dev_id, fp);
+		int_irq_count[irq]++;
+		pquicc->intr_cisr = (1 << vec); /* indicate that irq has been serviced */
+	} else {
+		printk("unregistered interrupt %d!\nTurning it off in the CIMR...\n", irq);
+		/* *(volatile unsigned long *)0xfffff304 |= mask; */
+		pquicc->intr_cimr &= ~(1 << vec);
+	}
+
+
+/* 	while (pend) { */
+/* 		if (pend & 0x0000ffff) { */
+/* 			if (pend & 0x000000ff) { */
+/* 				if (pend & 0x0000000f) { */
+/* 					mask = 0x00000001; */
+/* 					irq = 0; */
+/* 				} else { */
+/* 					mask = 0x00000010; */
+/* 					irq = 4; */
+/* 				} */
+/* 			} else { */
+/* 				if (pend & 0x00000f00) { */
+/* 					mask = 0x00000100; */
+/* 					irq = 8; */
+/* 				} else { */
+/* 					mask = 0x00001000; */
+/* 					irq = 12; */
+/* 				} */
+/* 			} */
+/* 		} else { */
+/* 			if (pend & 0x00ff0000) { */
+/* 				if (pend & 0x000f0000) { */
+/* 					mask = 0x00010000; */
+/* 					irq = 16; */
+/* 				} else { */
+/* 					mask = 0x00100000; */
+/* 					irq = 20; */
+/* 				} */
+/* 			} else { */
+/* 				if (pend & 0x0f000000) { */
+/* 					mask = 0x01000000; */
+/* 					irq = 24; */
+/* 				} else { */
+/* 					mask = 0x10000000; */
+/* 					irq = 28; */
+/* 				} */
+/* 			} */
+/* 		} */
+
+/* 		while (! (mask & pend)) { */
+/* 			mask <<=1; */
+/* 			irq++; */
+/* 		} */
+
+/* 		if (int_irq_list[irq] && int_irq_list[irq]->handler) { */
+/* 			int_irq_list[irq]->handler(irq | IRQ_MACHSPEC, int_irq_list[irq]->dev_id, fp); */
+/* 			int_irq_count[irq]++; */
+/* 		} else { */
+/* 			printk("unregistered interrupt %d!\nTurning it off in the CIMR...\n", irq); */
+/* 			*(volatile unsigned long *)0xfffff304 |= mask; */
+/* 		} */
+/* 		pend &= ~mask; */
+/* 	} */
+
+  return 0;
+}
+
+int M68360_get_irq_list(char *buf)
+{
+	int i, len = 0;
+	irq_node_t *node;
+
+	len += sprintf(buf+len, "Internal 68360 interrupts\n");
+
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		if (!(node = int_irq_list[i]))
+			continue;
+		if (!(node->handler))
+			continue;
+
+		len += sprintf(buf+len, " %2d: %10u    %s\n", i,
+		               int_irq_count[i], int_irq_list[i]->devname);
+	}
+	return len;
+}
+
+void config_M68360_irq(void)
+{
+	mach_default_handler = NULL;
+	mach_init_IRQ        = M68360_init_IRQ;
+	mach_request_irq     = M68360_request_irq;
+	mach_free_irq        = M68360_free_irq;
+	mach_enable_irq      = M68360_enable_irq;
+	mach_disable_irq     = M68360_disable_irq;
+	mach_get_irq_list    = M68360_get_irq_list;
+	mach_process_int     = M68360_do_irq;
+}
+
+void init_irq_proc(void);
+void init_irq_proc(void)
+{
+    /* Insert /proc/irq driver here */
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/68360/Makefile
--- linux-2.4.29/arch/m68knommu/platform/68360/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,47 @@
+#
+# Makefile for the linux kernel.
+#
+# Reuse any files we can from the 68328 base
+#
+
+VPATH := $(VPATH):../68328
+
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o quicc 
+
+QUICC_OBJS :=	quicc/commproc.o
+
+ifeq ($(CONFIG_M68360_SMC_UART),y)
+QUICC_OBJS += quicc/uart.o
+endif
+
+ifeq ($(CONFIG_M68EN360_ETHERNET),y)
+QUICC_OBJS += quicc/enet.o
+endif
+
+quicc = $(QUICC_OBJS)
+
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S 
+
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o traps.o ints.o $(QUICC_OBJS)
+
+entry.o: entry.S m68k_defs.h
+
+m68k_defs.h: ../../kernel/m68k_defs.c ../../kernel/m68k_defs.head
+	rm -f m68k_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/m68k_defs.c
+	cp ../../kernel/m68k_defs.head m68k_defs.h
+	grep '^#define' m68k_defs.s >> m68k_defs.h
+	rm m68k_defs.s
+-include m68k_defs.d
+
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/quicc/commproc.c linux-2.4.29-uc1/arch/m68knommu/platform/68360/quicc/commproc.c
--- linux-2.4.29/arch/m68knommu/platform/68360/quicc/commproc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/quicc/commproc.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,308 @@
+/*
+ * General Purpose functions for the global management of the
+ * Communication Processor Module.
+ *
+ * Copyright (c) 2000 Michael Leslie <mleslie@ArcturusNetworks.com>
+ * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
+ *
+ * In addition to the individual control of the communication
+ * channels, there are a few functions that globally affect the
+ * communication processor.
+ *
+ * Buffer descriptors must be allocated from the dual ported memory
+ * space.  The allocator for that is here.  When the communication
+ * process is reset, we reclaim the memory available.  There is
+ * currently no deallocator for this memory.
+ * The amount of space available is platform dependent.  On the
+ * MBX, the EPPC software loads additional microcode into the
+ * communication processor, and uses some of the DP ram for this
+ * purpose.  Current, the first 512 bytes and the last 256 bytes of
+ * memory are used.  Right now I am conservative and only use the
+ * memory that can never be used for microcode.  If there are
+ * applications that require more DP ram, we can expand the boundaries
+ * but then we have to be careful of any downloaded microcode.
+ *
+ */
+
+/*
+ * Michael Leslie <mleslie@ArcturusNetworks.com>
+ * adapted Dan Malek's ppc8xx drivers to M68360
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+#include <asm/m68360.h>
+
+#include "commproc.h"
+/* #include <asm/page.h> */
+/* #include <asm/pgtable.h> */
+extern void *_quicc_base;
+extern unsigned int system_clock;
+
+
+static uint dp_alloc_base;	/* Starting offset in DP ram */
+static uint dp_alloc_top;	/* Max offset + 1 */
+
+#if 0
+static	void	*host_buffer;	/* One page of host buffer */
+static	void	*host_end;	    /* end + 1 */
+#endif
+
+/* struct  cpm360_t *cpmp; */         /* Pointer to comm processor space */
+
+QUICC  *pquicc;
+/* QUICC  *quicc_dpram; */ /* mleslie - temporary; use extern pquicc elsewhere instead */
+
+
+/* CPM interrupt vector functions. */
+struct	cpm_action {
+	void	(*handler)(void *);
+	void	*dev_id;
+};
+static	struct	cpm_action cpm_vecs[CPMVEC_NR];
+static	void	cpm_interrupt(int irq, void * dev, struct pt_regs * regs);
+static	void	cpm_error_interrupt(void *);
+
+/* prototypes: */
+void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id);
+void m360_cpm_reset(void);
+
+
+
+
+void m360_cpm_reset()
+{
+/* 	pte_t		   *pte; */
+
+	pquicc = (struct quicc *)(_quicc_base); /* initialized in crt0_rXm.S */
+
+	/* Perform a CPM reset. */
+	pquicc->cp_cr = (SOFTWARE_RESET | CMD_FLAG);
+
+	/* Wait for CPM to become ready (should be 2 clocks). */
+	while (pquicc->cp_cr & CMD_FLAG);
+
+	/* On the recommendation of the 68360 manual, p. 7-60
+	 * - Set sdma interupt service mask to 7
+	 * - Set sdma arbitration ID to 4
+	 */
+	pquicc->sdma_sdcr = 0x0740;
+
+
+	/* Claim the DP memory for our use.
+	 */
+	dp_alloc_base = CPM_DATAONLY_BASE;
+	dp_alloc_top = dp_alloc_base + CPM_DATAONLY_SIZE;
+
+
+	/* Set the host page for allocation.
+	 */
+	/* 	host_buffer = host_page_addr; */
+	/* 	host_end = host_page_addr + PAGE_SIZE; */
+
+	/* 	pte = find_pte(&init_mm, host_page_addr); */
+	/* 	pte_val(*pte) |= _PAGE_NO_CACHE; */
+	/* 	flush_tlb_page(current->mm->mmap, host_buffer); */
+	
+	/* Tell everyone where the comm processor resides.
+	*/
+/* 	cpmp = (cpm360_t *)commproc; */
+}
+
+
+/* This is called during init_IRQ.  We used to do it above, but this
+ * was too early since init_IRQ was not yet called.
+ */
+void
+cpm_interrupt_init(void)
+{
+	/* Initialize the CPM interrupt controller.
+	 * NOTE THAT pquicc had better have been initialized!
+	 * reference: MC68360UM p. 7-377
+	 */
+	pquicc->intr_cicr =
+		(CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
+		(CPM_INTERRUPT << 13) |
+		CICR_HP_MASK |
+		(CPM_VECTOR_BASE << 5) |
+		CICR_SPS;
+
+	/* mask all CPM interrupts from reaching the cpu32 core: */
+	pquicc->intr_cimr = 0;
+
+
+	/* mles - If I understand correctly, the 360 just pops over to the CPM
+	 * specific vector, obviating the necessity to vector through the IRQ
+	 * whose priority the CPM is set to. This needs a closer look, though.
+	 */
+
+	/* Set our interrupt handler with the core CPU. */
+/* 	if (request_irq(CPM_INTERRUPT, cpm_interrupt, 0, "cpm", NULL) != 0) */
+/* 		panic("Could not allocate CPM IRQ!"); */
+
+	/* Install our own error handler.
+	 */
+	/* I think we want to hold off on this one for the moment - mles */
+	/* cpm_install_handler(CPMVEC_ERROR, cpm_error_interrupt, NULL); */
+
+	/* master CPM interrupt enable */
+	/* pquicc->intr_cicr |= CICR_IEN; */ /* no such animal for 360 */
+}
+
+
+
+/* CPM interrupt controller interrupt.
+*/
+static	void
+cpm_interrupt(int irq, void * dev, struct pt_regs * regs)
+{
+	/* uint	vec; */
+
+	/* mles: Note that this stuff is currently being performed by
+	 * M68360_do_irq(int vec, struct pt_regs *fp), in ../ints.c  */
+
+	/* figure out the vector */
+	/* call that vector's handler */
+	/* clear the irq's bit in the service register */
+
+#if 0 /* old 860 stuff: */
+	/* Get the vector by setting the ACK bit and then reading
+	 * the register.
+	 */
+	((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr = 1;
+	vec = ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr;
+	vec >>= 11;
+
+
+	if (cpm_vecs[vec].handler != 0)
+		(*cpm_vecs[vec].handler)(cpm_vecs[vec].dev_id);
+	else
+		((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr &= ~(1 << vec);
+
+	/* After servicing the interrupt, we have to remove the status
+	 * indicator.
+	 */
+	((immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr |= (1 << vec);
+#endif
+	
+}
+
+/* The CPM can generate the error interrupt when there is a race condition
+ * between generating and masking interrupts.  All we have to do is ACK it
+ * and return.  This is a no-op function so we don't need any special
+ * tests in the interrupt handler.
+ */
+static	void
+cpm_error_interrupt(void *dev)
+{
+}
+
+/* Install a CPM interrupt handler.
+*/
+void
+cpm_install_handler(int vec, void (*handler)(void *), void *dev_id)
+{
+
+	request_irq(vec, handler, IRQ_FLG_LOCK, "timer", dev_id);
+
+/* 	if (cpm_vecs[vec].handler != 0) */
+/* 		printk("CPM interrupt %x replacing %x\n", */
+/* 			(uint)handler, (uint)cpm_vecs[vec].handler); */
+/* 	cpm_vecs[vec].handler = handler; */
+/* 	cpm_vecs[vec].dev_id = dev_id; */
+
+	/*              ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr |= (1 << vec); */
+/* 	pquicc->intr_cimr |= (1 << vec); */
+
+}
+
+/* Free a CPM interrupt handler.
+*/
+void
+cpm_free_handler(int vec)
+{
+	cpm_vecs[vec].handler = NULL;
+	cpm_vecs[vec].dev_id = NULL;
+	/* ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr &= ~(1 << vec); */
+	pquicc->intr_cimr &= ~(1 << vec);
+}
+
+
+
+
+/* Allocate some memory from the dual ported ram.  We may want to
+ * enforce alignment restrictions, but right now everyone is a good
+ * citizen.
+ */
+uint
+m360_cpm_dpalloc(uint size)
+{
+        uint    retloc;
+
+        if ((dp_alloc_base + size) >= dp_alloc_top)
+                return(CPM_DP_NOSPACE);
+
+        retloc = dp_alloc_base;
+        dp_alloc_base += size;
+
+        return(retloc);
+}
+
+
+#if 0 /* mleslie - for now these are simply kmalloc'd */
+/* We also own one page of host buffer space for the allocation of
+ * UART "fifos" and the like.
+ */
+uint
+m360_cpm_hostalloc(uint size)
+{
+	uint	retloc;
+
+	if ((host_buffer + size) >= host_end)
+		return(0);
+
+	retloc = host_buffer;
+	host_buffer += size;
+
+	return(retloc);
+}
+#endif
+
+
+/* Set a baud rate generator.  This needs lots of work.  There are
+ * four BRGs, any of which can be wired to any channel.
+ * The internal baud rate clock is the system clock divided by 16.
+ * This assumes the baudrate is 16x oversampled by the uart.
+ */
+/* #define BRG_INT_CLK	(((bd_t *)__res)->bi_intfreq * 1000000) */
+#define BRG_INT_CLK		system_clock
+#define BRG_UART_CLK	(BRG_INT_CLK/16)
+
+void
+m360_cpm_setbrg(uint brg, uint rate)
+{
+	volatile uint	*bp;
+
+	/* This is good enough to get SMCs running.....
+	 */
+	/* bp = (uint *)&cpmp->cp_brgc1; */
+	bp = (volatile uint *)(&pquicc->brgc[0].l);
+	bp += brg;
+	*bp = ((BRG_UART_CLK / rate - 1) << 1) | CPM_BRG_EN;
+}
+
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/quicc/commproc.h linux-2.4.29-uc1/arch/m68knommu/platform/68360/quicc/commproc.h
--- linux-2.4.29/arch/m68knommu/platform/68360/quicc/commproc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/quicc/commproc.h	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,724 @@
+
+/*
+ * 68360 Communication Processor Module.
+ * Copyright (c) 2000 Michael Leslie <mleslie@ArcturusNetworks.com> (mc68360) after:
+ * Copyright (c) 1997 Dan Malek <dmalek@jlc.net> (mpc8xx)
+ *
+ * This file contains structures and information for the communication
+ * processor channels.  Some CPM control and status is available
+ * through the 68360 internal memory map.  See include/asm/360_immap.h for details.
+ * This file is not a complete map of all of the 360 QUICC's capabilities
+ *
+ * On the MBX board, EPPC-Bug loads CPM microcode into the first 512
+ * bytes of the DP RAM and relocates the I2C parameter area to the
+ * IDMA1 space.  The remaining DP RAM is available for buffer descriptors
+ * or other use.
+ */
+#ifndef __CPM_360__
+#define __CPM_360__
+
+#include <linux/config.h>
+/* #include <asm/360_immap.h> */
+
+/* CPM Command register masks: */
+#define CPM_CR_RST	((ushort)0x8000)
+#define CPM_CR_OPCODE	((ushort)0x0f00)
+#define CPM_CR_CHAN	((ushort)0x00f0)
+#define CPM_CR_FLG	((ushort)0x0001)
+
+/* CPM Command set (opcodes): */
+#define CPM_CR_INIT_TRX		((ushort)0x0000)
+#define CPM_CR_INIT_RX		((ushort)0x0001)
+#define CPM_CR_INIT_TX		((ushort)0x0002)
+#define CPM_CR_HUNT_MODE	((ushort)0x0003)
+#define CPM_CR_STOP_TX		((ushort)0x0004)
+#define CPM_CR_GRSTOP_TX	((ushort)0x0005)
+#define CPM_CR_RESTART_TX	((ushort)0x0006)
+#define CPM_CR_CLOSE_RXBD	((ushort)0x0007)
+#define CPM_CR_SET_GADDR	((ushort)0x0008)
+#define CPM_CR_GCI_TIMEOUT	((ushort)0x0009)
+#define CPM_CR_GCI_ABORT	((ushort)0x000a)
+#define CPM_CR_RESET_BCS	((ushort)0x000a)
+
+/* CPM Channel numbers. */
+#define CPM_CR_CH_SCC1	((ushort)0x0000)
+#define CPM_CR_CH_SCC2	((ushort)0x0004)
+#define CPM_CR_CH_SPI	((ushort)0x0005)	/* SPI / Timers */
+#define CPM_CR_CH_TMR	((ushort)0x0005)
+#define CPM_CR_CH_SCC3	((ushort)0x0008)
+#define CPM_CR_CH_SMC1	((ushort)0x0009)	/* SMC1 / IDMA1 */
+#define CPM_CR_CH_IDMA1	((ushort)0x0009)
+#define CPM_CR_CH_SCC4	((ushort)0x000c)
+#define CPM_CR_CH_SMC2	((ushort)0x000d)	/* SMC2 / IDMA2 */
+#define CPM_CR_CH_IDMA2	((ushort)0x000d)
+
+
+#define mk_cr_cmd(CH, CMD)	((CMD << 8) | (CH << 4))
+
+#if 1 /* mleslie: I dinna think we have any such restrictions on
+       * DP RAM aboard the 360 board - see the MC68360UM p.3-3 */
+
+/* The dual ported RAM is multi-functional.  Some areas can be (and are
+ * being) used for microcode.  There is an area that can only be used
+ * as data ram for buffer descriptors, which is all we use right now.
+ * Currently the first 512 and last 256 bytes are used for microcode.
+ */
+/* mleslie: The uCquicc board is using no extra microcode in DPRAM */
+#define CPM_DATAONLY_BASE	((uint)0x0000)
+#define CPM_DATAONLY_SIZE	((uint)0x0800)
+#define CPM_DP_NOSPACE		((uint)0x7fffffff)
+
+#endif
+
+
+/* Export the base address of the communication processor registers
+ * and dual port ram. */
+/* extern	cpm360_t	*cpmp; */		/* Pointer to comm processor */
+extern QUICC *pquicc;
+uint         m360_cpm_dpalloc(uint size);
+/* void         *m360_cpm_hostalloc(uint size); */
+void	      m360_cpm_setbrg(uint brg, uint rate);
+
+#if 0 /* use QUICC_BD declared in include/asm/m68360_quicc.h  */
+/* Buffer descriptors used by many of the CPM protocols. */
+typedef struct cpm_buf_desc {
+	ushort	cbd_sc;		/* Status and Control */
+	ushort	cbd_datlen;	/* Data length in buffer */
+	uint	cbd_bufaddr;	/* Buffer address in host memory */
+} cbd_t;
+#endif
+
+
+/* rx bd status/control bits */
+#define BD_SC_EMPTY	((ushort)0x8000)	/* Recieve is empty */
+#define BD_SC_WRAP	((ushort)0x2000)	/* Last buffer descriptor in table */
+#define BD_SC_INTRPT	((ushort)0x1000)	/* Interrupt on change */
+#define BD_SC_LAST	((ushort)0x0800)	/* Last buffer in frame OR control char */
+
+#define BD_SC_FIRST	((ushort)0x0400)	/* 1st buffer in an HDLC frame */
+#define BD_SC_ADDR	((ushort)0x0400)	/* 1st byte is a multidrop address */
+
+#define BD_SC_CM	((ushort)0x0200)	/* Continous mode */
+#define BD_SC_ID	((ushort)0x0100)	/* Received too many idles */
+
+#define BD_SC_AM	((ushort)0x0080)	/* Multidrop address match */
+#define BD_SC_DE	((ushort)0x0080)	/* DPLL Error (HDLC) */
+
+#define BD_SC_BR	((ushort)0x0020)	/* Break received */
+#define BD_SC_LG	((ushort)0x0020)	/* Frame length violation (HDLC) */
+
+#define BD_SC_FR	((ushort)0x0010)	/* Framing error */
+#define BD_SC_NO	((ushort)0x0010)	/* Nonoctet aligned frame (HDLC) */
+
+#define BD_SC_PR	((ushort)0x0008)	/* Parity error */
+#define BD_SC_AB	((ushort)0x0008)	/* Received abort Sequence (HDLC) */
+
+#define BD_SC_OV	((ushort)0x0002)	/* Overrun */
+#define BD_SC_CD	((ushort)0x0001)	/* Carrier Detect lost */
+
+/* tx bd status/control bits (as differ from rx bd) */
+#define BD_SC_READY	((ushort)0x8000)	/* Transmit is ready */
+#define BD_SC_TC	((ushort)0x0400)	/* Transmit CRC */
+#define BD_SC_P		((ushort)0x0100)	/* xmt preamble */
+#define BD_SC_UN	((ushort)0x0002)	/* Underrun */
+
+
+
+
+/* Parameter RAM offsets. */
+
+
+
+/* In 2.4 ppc, the PROFF_S?C? are used as byte offsets into DPRAM.
+ * In 2.0, we use a more structured C struct map of DPRAM, and so 
+ * instead, we need only a parameter ram `slot'  */
+
+#define PRSLOT_SCC1	0
+#define PRSLOT_SCC2	1
+#define PRSLOT_SCC3	2
+#define PRSLOT_SMC1	2
+#define PRSLOT_SCC4	3
+#define PRSLOT_SMC2	3
+
+
+/* #define PROFF_SCC1	((uint)0x0000) */
+/* #define PROFF_SCC2	((uint)0x0100) */
+/* #define PROFF_SCC3	((uint)0x0200) */
+/* #define PROFF_SMC1	((uint)0x0280) */
+/* #define PROFF_SCC4	((uint)0x0300) */
+/* #define PROFF_SMC2	((uint)0x0380) */
+
+
+/* Define enough so I can at least use the serial port as a UART.
+ * The MBX uses SMC1 as the host serial port.
+ */
+typedef struct smc_uart {
+	ushort	smc_rbase;	/* Rx Buffer descriptor base address */
+	ushort	smc_tbase;	/* Tx Buffer descriptor base address */
+	u_char	smc_rfcr;	/* Rx function code */
+	u_char	smc_tfcr;	/* Tx function code */
+	ushort	smc_mrblr;	/* Max receive buffer length */
+	uint	smc_rstate;	/* Internal */
+	uint	smc_idp;	/* Internal */
+	ushort	smc_rbptr;	/* Internal */
+	ushort	smc_ibc;	/* Internal */
+	uint	smc_rxtmp;	/* Internal */
+	uint	smc_tstate;	/* Internal */
+	uint	smc_tdp;	/* Internal */
+	ushort	smc_tbptr;	/* Internal */
+	ushort	smc_tbc;	/* Internal */
+	uint	smc_txtmp;	/* Internal */
+	ushort	smc_maxidl;	/* Maximum idle characters */
+	ushort	smc_tmpidl;	/* Temporary idle counter */
+	ushort	smc_brklen;	/* Last received break length */
+	ushort	smc_brkec;	/* rcv'd break condition counter */
+	ushort	smc_brkcr;	/* xmt break count register */
+	ushort	smc_rmask;	/* Temporary bit mask */
+} smc_uart_t;
+
+/* Function code bits.
+*/
+#define SMC_EB	((u_char)0x10)	/* Set big endian byte order */
+
+/* SMC uart mode register.
+*/
+#define	SMCMR_REN	((ushort)0x0001)
+#define SMCMR_TEN	((ushort)0x0002)
+#define SMCMR_DM	((ushort)0x000c)
+#define SMCMR_SM_GCI	((ushort)0x0000)
+#define SMCMR_SM_UART	((ushort)0x0020)
+#define SMCMR_SM_TRANS	((ushort)0x0030)
+#define SMCMR_SM_MASK	((ushort)0x0030)
+#define SMCMR_PM_EVEN	((ushort)0x0100)	/* Even parity, else odd */
+#define SMCMR_REVD	SMCMR_PM_EVEN
+#define SMCMR_PEN	((ushort)0x0200)	/* Parity enable */
+#define SMCMR_BS	SMCMR_PEN
+#define SMCMR_SL	((ushort)0x0400)	/* Two stops, else one */
+#define SMCR_CLEN_MASK	((ushort)0x7800)	/* Character length */
+#define smcr_mk_clen(C)	(((C) << 11) & SMCR_CLEN_MASK)
+
+/* SMC2 as Centronics parallel printer.  It is half duplex, in that
+ * it can only receive or transmit.  The parameter ram values for
+ * each direction are either unique or properly overlap, so we can
+ * include them in one structure.
+ */
+typedef struct smc_centronics {
+	ushort	scent_rbase;
+	ushort	scent_tbase;
+	u_char	scent_cfcr;
+	u_char	scent_smask;
+	ushort	scent_mrblr;
+	uint	scent_rstate;
+	uint	scent_r_ptr;
+	ushort	scent_rbptr;
+	ushort	scent_r_cnt;
+	uint	scent_rtemp;
+	uint	scent_tstate;
+	uint	scent_t_ptr;
+	ushort	scent_tbptr;
+	ushort	scent_t_cnt;
+	uint	scent_ttemp;
+	ushort	scent_max_sl;
+	ushort	scent_sl_cnt;
+	ushort	scent_character1;
+	ushort	scent_character2;
+	ushort	scent_character3;
+	ushort	scent_character4;
+	ushort	scent_character5;
+	ushort	scent_character6;
+	ushort	scent_character7;
+	ushort	scent_character8;
+	ushort	scent_rccm;
+	ushort	scent_rccr;
+} smc_cent_t;
+
+/* Centronics Status Mask Register.
+*/
+#define SMC_CENT_F	((u_char)0x08)
+#define SMC_CENT_PE	((u_char)0x04)
+#define SMC_CENT_S	((u_char)0x02)
+
+/* SMC Event and Mask register.
+*/
+#define	SMCM_BRKE	((unsigned char)0x40)	/* When in UART Mode */
+#define	SMCM_BRK	((unsigned char)0x10)	/* When in UART Mode */
+#define	SMCM_TXE	((unsigned char)0x10)	/* When in Transparent Mode */
+#define	SMCM_BSY	((unsigned char)0x04)
+#define	SMCM_TX		((unsigned char)0x02)
+#define	SMCM_RX		((unsigned char)0x01)
+
+/* Baud rate generators.
+*/
+#define CPM_BRG_RST		((uint)0x00020000)
+#define CPM_BRG_EN		((uint)0x00010000)
+#define CPM_BRG_EXTC_INT	((uint)0x00000000)
+#define CPM_BRG_EXTC_CLK2	((uint)0x00004000)
+#define CPM_BRG_EXTC_CLK6	((uint)0x00008000)
+#define CPM_BRG_ATB		((uint)0x00002000)
+#define CPM_BRG_CD_MASK		((uint)0x00001ffe)
+#define CPM_BRG_DIV16		((uint)0x00000001)
+
+/* SCCs.
+*/
+#define SCC_GSMRH_IRP		((uint)0x00040000)
+#define SCC_GSMRH_GDE		((uint)0x00010000)
+#define SCC_GSMRH_TCRC_CCITT	((uint)0x00008000)
+#define SCC_GSMRH_TCRC_BISYNC	((uint)0x00004000)
+#define SCC_GSMRH_TCRC_HDLC	((uint)0x00000000)
+#define SCC_GSMRH_REVD		((uint)0x00002000)
+#define SCC_GSMRH_TRX		((uint)0x00001000)
+#define SCC_GSMRH_TTX		((uint)0x00000800)
+#define SCC_GSMRH_CDP		((uint)0x00000400)
+#define SCC_GSMRH_CTSP		((uint)0x00000200)
+#define SCC_GSMRH_CDS		((uint)0x00000100)
+#define SCC_GSMRH_CTSS		((uint)0x00000080)
+#define SCC_GSMRH_TFL		((uint)0x00000040)
+#define SCC_GSMRH_RFW		((uint)0x00000020)
+#define SCC_GSMRH_TXSY		((uint)0x00000010)
+#define SCC_GSMRH_SYNL16	((uint)0x0000000c)
+#define SCC_GSMRH_SYNL8		((uint)0x00000008)
+#define SCC_GSMRH_SYNL4		((uint)0x00000004)
+#define SCC_GSMRH_RTSM		((uint)0x00000002)
+#define SCC_GSMRH_RSYN		((uint)0x00000001)
+
+#define SCC_GSMRL_SIR		((uint)0x80000000)	/* SCC2 only */
+#define SCC_GSMRL_EDGE_NONE	((uint)0x60000000)
+#define SCC_GSMRL_EDGE_NEG	((uint)0x40000000)
+#define SCC_GSMRL_EDGE_POS	((uint)0x20000000)
+#define SCC_GSMRL_EDGE_BOTH	((uint)0x00000000)
+#define SCC_GSMRL_TCI		((uint)0x10000000)
+#define SCC_GSMRL_TSNC_3	((uint)0x0c000000)
+#define SCC_GSMRL_TSNC_4	((uint)0x08000000)
+#define SCC_GSMRL_TSNC_14	((uint)0x04000000)
+#define SCC_GSMRL_TSNC_INF	((uint)0x00000000)
+#define SCC_GSMRL_RINV		((uint)0x02000000)
+#define SCC_GSMRL_TINV		((uint)0x01000000)
+#define SCC_GSMRL_TPL_128	((uint)0x00c00000)
+#define SCC_GSMRL_TPL_64	((uint)0x00a00000)
+#define SCC_GSMRL_TPL_48	((uint)0x00800000)
+#define SCC_GSMRL_TPL_32	((uint)0x00600000)
+#define SCC_GSMRL_TPL_16	((uint)0x00400000)
+#define SCC_GSMRL_TPL_8		((uint)0x00200000)
+#define SCC_GSMRL_TPL_NONE	((uint)0x00000000)
+#define SCC_GSMRL_TPP_ALL1	((uint)0x00180000)
+#define SCC_GSMRL_TPP_01	((uint)0x00100000)
+#define SCC_GSMRL_TPP_10	((uint)0x00080000)
+#define SCC_GSMRL_TPP_ZEROS	((uint)0x00000000)
+#define SCC_GSMRL_TEND		((uint)0x00040000)
+#define SCC_GSMRL_TDCR_32	((uint)0x00030000)
+#define SCC_GSMRL_TDCR_16	((uint)0x00020000)
+#define SCC_GSMRL_TDCR_8	((uint)0x00010000)
+#define SCC_GSMRL_TDCR_1	((uint)0x00000000)
+#define SCC_GSMRL_RDCR_32	((uint)0x0000c000)
+#define SCC_GSMRL_RDCR_16	((uint)0x00008000)
+#define SCC_GSMRL_RDCR_8	((uint)0x00004000)
+#define SCC_GSMRL_RDCR_1	((uint)0x00000000)
+#define SCC_GSMRL_RENC_DFMAN	((uint)0x00003000)
+#define SCC_GSMRL_RENC_MANCH	((uint)0x00002000)
+#define SCC_GSMRL_RENC_FM0	((uint)0x00001000)
+#define SCC_GSMRL_RENC_NRZI	((uint)0x00000800)
+#define SCC_GSMRL_RENC_NRZ	((uint)0x00000000)
+#define SCC_GSMRL_TENC_DFMAN	((uint)0x00000600)
+#define SCC_GSMRL_TENC_MANCH	((uint)0x00000400)
+#define SCC_GSMRL_TENC_FM0	((uint)0x00000200)
+#define SCC_GSMRL_TENC_NRZI	((uint)0x00000100)
+#define SCC_GSMRL_TENC_NRZ	((uint)0x00000000)
+#define SCC_GSMRL_DIAG_LE	((uint)0x000000c0)	/* Loop and echo */
+#define SCC_GSMRL_DIAG_ECHO	((uint)0x00000080)
+#define SCC_GSMRL_DIAG_LOOP	((uint)0x00000040)
+#define SCC_GSMRL_DIAG_NORM	((uint)0x00000000)
+#define SCC_GSMRL_ENR		((uint)0x00000020)
+#define SCC_GSMRL_ENT		((uint)0x00000010)
+#define SCC_GSMRL_MODE_ENET	((uint)0x0000000c)
+#define SCC_GSMRL_MODE_DDCMP	((uint)0x00000009)
+#define SCC_GSMRL_MODE_BISYNC	((uint)0x00000008)
+#define SCC_GSMRL_MODE_V14	((uint)0x00000007)
+#define SCC_GSMRL_MODE_AHDLC	((uint)0x00000006)
+#define SCC_GSMRL_MODE_PROFIBUS	((uint)0x00000005)
+#define SCC_GSMRL_MODE_UART	((uint)0x00000004)
+#define SCC_GSMRL_MODE_SS7	((uint)0x00000003)
+#define SCC_GSMRL_MODE_ATALK	((uint)0x00000002)
+#define SCC_GSMRL_MODE_HDLC	((uint)0x00000000)
+
+#define SCC_TODR_TOD		((ushort)0x8000)
+
+/* SCC Event and Mask register.
+*/
+#define	SCCM_TXE	((unsigned char)0x10)
+#define	SCCM_BSY	((unsigned char)0x04)
+#define	SCCM_TX		((unsigned char)0x02)
+#define	SCCM_RX		((unsigned char)0x01)
+
+typedef struct scc_param {
+	ushort	scc_rbase;	/* Rx Buffer descriptor base address */
+	ushort	scc_tbase;	/* Tx Buffer descriptor base address */
+	u_char	scc_rfcr;	/* Rx function code */
+	u_char	scc_tfcr;	/* Tx function code */
+	ushort	scc_mrblr;	/* Max receive buffer length */
+	uint	scc_rstate;	/* Internal */
+	uint	scc_idp;	/* Internal */
+	ushort	scc_rbptr;	/* Internal */
+	ushort	scc_ibc;	/* Internal */
+	uint	scc_rxtmp;	/* Internal */
+	uint	scc_tstate;	/* Internal */
+	uint	scc_tdp;	/* Internal */
+	ushort	scc_tbptr;	/* Internal */
+	ushort	scc_tbc;	/* Internal */
+	uint	scc_txtmp;	/* Internal */
+	uint	scc_rcrc;	/* Internal */
+	uint	scc_tcrc;	/* Internal */
+} sccp_t;
+
+
+/* Function code bits.
+ */
+#define SCC_EB	((u_char)0x10)	/* Set big endian byte order */
+#define SCC_FC_DMA ((u_char)0x08) /* Set SDMA */
+
+/* CPM Ethernet through SCC1.
+ */
+typedef struct scc_enet {
+	sccp_t	sen_genscc;
+	uint	sen_cpres;	/* Preset CRC */
+	uint	sen_cmask;	/* Constant mask for CRC */
+	uint	sen_crcec;	/* CRC Error counter */
+	uint	sen_alec;	/* alignment error counter */
+	uint	sen_disfc;	/* discard frame counter */
+	ushort	sen_pads;	/* Tx short frame pad character */
+	ushort	sen_retlim;	/* Retry limit threshold */
+	ushort	sen_retcnt;	/* Retry limit counter */
+	ushort	sen_maxflr;	/* maximum frame length register */
+	ushort	sen_minflr;	/* minimum frame length register */
+	ushort	sen_maxd1;	/* maximum DMA1 length */
+	ushort	sen_maxd2;	/* maximum DMA2 length */
+	ushort	sen_maxd;	/* Rx max DMA */
+	ushort	sen_dmacnt;	/* Rx DMA counter */
+	ushort	sen_maxb;	/* Max BD byte count */
+	ushort	sen_gaddr1;	/* Group address filter */
+	ushort	sen_gaddr2;
+	ushort	sen_gaddr3;
+	ushort	sen_gaddr4;
+	uint	sen_tbuf0data0;	/* Save area 0 - current frame */
+	uint	sen_tbuf0data1;	/* Save area 1 - current frame */
+	uint	sen_tbuf0rba;	/* Internal */
+	uint	sen_tbuf0crc;	/* Internal */
+	ushort	sen_tbuf0bcnt;	/* Internal */
+	ushort	sen_paddrh;	/* physical address (MSB) */
+	ushort	sen_paddrm;
+	ushort	sen_paddrl;	/* physical address (LSB) */
+	ushort	sen_pper;	/* persistence */
+	ushort	sen_rfbdptr;	/* Rx first BD pointer */
+	ushort	sen_tfbdptr;	/* Tx first BD pointer */
+	ushort	sen_tlbdptr;	/* Tx last BD pointer */
+	uint	sen_tbuf1data0;	/* Save area 0 - current frame */
+	uint	sen_tbuf1data1;	/* Save area 1 - current frame */
+	uint	sen_tbuf1rba;	/* Internal */
+	uint	sen_tbuf1crc;	/* Internal */
+	ushort	sen_tbuf1bcnt;	/* Internal */
+	ushort	sen_txlen;	/* Tx Frame length counter */
+	ushort	sen_iaddr1;	/* Individual address filter */
+	ushort	sen_iaddr2;
+	ushort	sen_iaddr3;
+	ushort	sen_iaddr4;
+	ushort	sen_boffcnt;	/* Backoff counter */
+
+	/* NOTE: Some versions of the manual have the following items
+	 * incorrectly documented.  Below is the proper order.
+	 */
+	ushort	sen_taddrh;	/* temp address (MSB) */
+	ushort	sen_taddrm;
+	ushort	sen_taddrl;	/* temp address (LSB) */
+} scc_enet_t;
+
+
+
+#if defined (CONFIG_UCQUICC)
+/* uCquicc has the following signals connected to Ethernet:
+ *  68360    - lxt905
+ * PA0/RXD1  - rxd
+ * PA1/TXD1  - txd
+ * PA8/CLK1  - tclk
+ * PA9/CLK2  - rclk
+ * PC0/!RTS1 - t_en
+ * PC1/!CTS1 - col
+ * PC5/!CD1  - cd
+ */
+#define PA_ENET_RXD	PA_RXD1
+#define PA_ENET_TXD	PA_TXD1
+#define PA_ENET_TCLK	PA_CLK1
+#define PA_ENET_RCLK	PA_CLK2
+#define PC_ENET_TENA	PC_RTS1
+#define PC_ENET_CLSN	PC_CTS1
+#define PC_ENET_RENA	PC_CD1
+
+/* Control bits in the SICR to route TCLK (CLK1) and RCLK (CLK2) to
+ * SCC1.
+ */
+#define SICR_ENET_MASK	((uint)0x000000ff)
+#define SICR_ENET_CLKRT	((uint)0x0000002c)
+
+#endif /* config_ucquicc */
+
+
+#ifdef MBX
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC1 use.  The TCLK and RCLK seem unique
+ * to the MBX860 board.  Any two of the four available clocks could be
+ * used, and the MPC860 cookbook manual has an example using different
+ * clock pins.
+ */
+#define PA_ENET_RXD	((ushort)0x0001)
+#define PA_ENET_TXD	((ushort)0x0002)
+#define PA_ENET_TCLK	((ushort)0x0200)
+#define PA_ENET_RCLK	((ushort)0x0800)
+#define PC_ENET_TENA	((ushort)0x0001)
+#define PC_ENET_CLSN	((ushort)0x0010)
+#define PC_ENET_RENA	((ushort)0x0020)
+
+/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to
+ * SCC1.  Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
+ */
+#define SICR_ENET_MASK	((uint)0x000000ff)
+#define SICR_ENET_CLKRT	((uint)0x0000003d)
+#endif
+
+#ifdef CONFIG_RPXLITE
+/* This ENET stuff is for the MPC850 with ethernet on SCC2.  Some of
+ * this may be unique to the RPX-Lite configuration.
+ * Note TENA is on Port B.
+ */
+#define PA_ENET_RXD	((ushort)0x0004)
+#define PA_ENET_TXD	((ushort)0x0008)
+#define PA_ENET_TCLK	((ushort)0x0200)
+#define PA_ENET_RCLK	((ushort)0x0800)
+#define PB_ENET_TENA	((uint)0x00002000)
+#define PC_ENET_CLSN	((ushort)0x0040)
+#define PC_ENET_RENA	((ushort)0x0080)
+
+#define SICR_ENET_MASK	((uint)0x0000ff00)
+#define SICR_ENET_CLKRT	((uint)0x00003d00)
+#endif
+
+#ifdef CONFIG_BSEIP
+/* This ENET stuff is for the MPC823 with ethernet on SCC2.
+ * This is unique to the BSE ip-Engine board.
+ */
+#define PA_ENET_RXD	((ushort)0x0004)
+#define PA_ENET_TXD	((ushort)0x0008)
+#define PA_ENET_TCLK	((ushort)0x0100)
+#define PA_ENET_RCLK	((ushort)0x0200)
+#define PB_ENET_TENA	((uint)0x00002000)
+#define PC_ENET_CLSN	((ushort)0x0040)
+#define PC_ENET_RENA	((ushort)0x0080)
+
+/* BSE uses port B and C bits for PHY control also.
+*/
+#define PB_BSE_POWERUP	((uint)0x00000004)
+#define PB_BSE_FDXDIS	((uint)0x00008000)
+#define PC_BSE_LOOPBACK	((ushort)0x0800)
+
+#define SICR_ENET_MASK	((uint)0x0000ff00)
+#define SICR_ENET_CLKRT	((uint)0x00002c00)
+#endif
+
+#ifdef CONFIG_RPXCLASSIC
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC1 use.
+ */
+#define PA_ENET_RXD	((ushort)0x0001)
+#define PA_ENET_TXD	((ushort)0x0002)
+#define PA_ENET_TCLK	((ushort)0x0200)
+#define PA_ENET_RCLK	((ushort)0x0800)
+#define PB_ENET_TENA	((uint)0x00001000)
+#define PC_ENET_CLSN	((ushort)0x0010)
+#define PC_ENET_RENA	((ushort)0x0020)
+
+/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to
+ * SCC1.  Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
+ */
+#define SICR_ENET_MASK	((uint)0x000000ff)
+#define SICR_ENET_CLKRT	((uint)0x0000003d)
+#endif
+
+/* SCC Event register as used by Ethernet.
+*/
+#define SCCE_ENET_GRA	((ushort)0x0080)	/* Graceful stop complete */
+#define SCCE_ENET_TXE	((ushort)0x0010)	/* Transmit Error */
+#define SCCE_ENET_RXF	((ushort)0x0008)	/* Full frame received */
+#define SCCE_ENET_BSY	((ushort)0x0004)	/* All incoming buffers full */
+#define SCCE_ENET_TXB	((ushort)0x0002)	/* A buffer was transmitted */
+#define SCCE_ENET_RXB	((ushort)0x0001)	/* A buffer was received */
+
+/* SCC Mode Register (PMSR) as used by Ethernet.
+*/
+#define SCC_PMSR_HBC	((ushort)0x8000)	/* Enable heartbeat */
+#define SCC_PMSR_FC	((ushort)0x4000)	/* Force collision */
+#define SCC_PMSR_RSH	((ushort)0x2000)	/* Receive short frames */
+#define SCC_PMSR_IAM	((ushort)0x1000)	/* Check individual hash */
+#define SCC_PMSR_ENCRC	((ushort)0x0800)	/* Ethernet CRC mode */
+#define SCC_PMSR_PRO	((ushort)0x0200)	/* Promiscuous mode */
+#define SCC_PMSR_BRO	((ushort)0x0100)	/* Catch broadcast pkts */
+#define SCC_PMSR_SBT	((ushort)0x0080)	/* Special backoff timer */
+#define SCC_PMSR_LPB	((ushort)0x0040)	/* Set Loopback mode */
+#define SCC_PMSR_SIP	((ushort)0x0020)	/* Sample Input Pins */
+#define SCC_PMSR_LCW	((ushort)0x0010)	/* Late collision window */
+#define SCC_PMSR_NIB22	((ushort)0x000a)	/* Start frame search */
+#define SCC_PMSR_FDE	((ushort)0x0001)	/* Full duplex enable */
+
+/* Buffer descriptor control/status used by Ethernet receive.
+*/
+#define BD_ENET_RX_EMPTY	((ushort)0x8000)
+#define BD_ENET_RX_WRAP		((ushort)0x2000)
+#define BD_ENET_RX_INTR		((ushort)0x1000)
+#define BD_ENET_RX_LAST		((ushort)0x0800)
+#define BD_ENET_RX_FIRST	((ushort)0x0400)
+#define BD_ENET_RX_MISS		((ushort)0x0100)
+#define BD_ENET_RX_LG		((ushort)0x0020)
+#define BD_ENET_RX_NO		((ushort)0x0010)
+#define BD_ENET_RX_SH		((ushort)0x0008)
+#define BD_ENET_RX_CR		((ushort)0x0004)
+#define BD_ENET_RX_OV		((ushort)0x0002)
+#define BD_ENET_RX_CL		((ushort)0x0001)
+#define BD_ENET_RX_STATS	((ushort)0x013f)	/* All status bits */
+
+/* Buffer descriptor control/status used by Ethernet transmit.
+*/
+#define BD_ENET_TX_READY	((ushort)0x8000)
+#define BD_ENET_TX_PAD		((ushort)0x4000)
+#define BD_ENET_TX_WRAP		((ushort)0x2000)
+#define BD_ENET_TX_INTR		((ushort)0x1000)
+#define BD_ENET_TX_LAST		((ushort)0x0800)
+#define BD_ENET_TX_TC		((ushort)0x0400)
+#define BD_ENET_TX_DEF		((ushort)0x0200)
+#define BD_ENET_TX_HB		((ushort)0x0100)
+#define BD_ENET_TX_LC		((ushort)0x0080)
+#define BD_ENET_TX_RL		((ushort)0x0040)
+#define BD_ENET_TX_RCMASK	((ushort)0x003c)
+#define BD_ENET_TX_UN		((ushort)0x0002)
+#define BD_ENET_TX_CSL		((ushort)0x0001)
+#define BD_ENET_TX_STATS	((ushort)0x03ff)	/* All status bits */
+
+/* SCC as UART
+*/
+typedef struct scc_uart {
+	sccp_t	scc_genscc;
+	uint	scc_res1;	/* Reserved */
+	uint	scc_res2;	/* Reserved */
+	ushort	scc_maxidl;	/* Maximum idle chars */
+	ushort	scc_idlc;	/* temp idle counter */
+	ushort	scc_brkcr;	/* Break count register */
+	ushort	scc_parec;	/* receive parity error counter */
+	ushort	scc_frmec;	/* receive framing error counter */
+	ushort	scc_nosec;	/* receive noise counter */
+	ushort	scc_brkec;	/* receive break condition counter */
+	ushort	scc_brkln;	/* last received break length */
+	ushort	scc_uaddr1;	/* UART address character 1 */
+	ushort	scc_uaddr2;	/* UART address character 2 */
+	ushort	scc_rtemp;	/* Temp storage */
+	ushort	scc_toseq;	/* Transmit out of sequence char */
+	ushort	scc_char1;	/* control character 1 */
+	ushort	scc_char2;	/* control character 2 */
+	ushort	scc_char3;	/* control character 3 */
+	ushort	scc_char4;	/* control character 4 */
+	ushort	scc_char5;	/* control character 5 */
+	ushort	scc_char6;	/* control character 6 */
+	ushort	scc_char7;	/* control character 7 */
+	ushort	scc_char8;	/* control character 8 */
+	ushort	scc_rccm;	/* receive control character mask */
+	ushort	scc_rccr;	/* receive control character register */
+	ushort	scc_rlbc;	/* receive last break character */
+} scc_uart_t;
+
+/* SCC Event and Mask registers when it is used as a UART.
+*/
+#define UART_SCCM_GLR		((ushort)0x1000)
+#define UART_SCCM_GLT		((ushort)0x0800)
+#define UART_SCCM_AB		((ushort)0x0200)
+#define UART_SCCM_IDL		((ushort)0x0100)
+#define UART_SCCM_GRA		((ushort)0x0080)
+#define UART_SCCM_BRKE		((ushort)0x0040)
+#define UART_SCCM_BRKS		((ushort)0x0020)
+#define UART_SCCM_CCR		((ushort)0x0008)
+#define UART_SCCM_BSY		((ushort)0x0004)
+#define UART_SCCM_TX		((ushort)0x0002)
+#define UART_SCCM_RX		((ushort)0x0001)
+
+/* The SCC PMSR when used as a UART.
+*/
+#define SCU_PMSR_FLC		((ushort)0x8000)
+#define SCU_PMSR_SL		((ushort)0x4000)
+#define SCU_PMSR_CL		((ushort)0x3000)
+#define SCU_PMSR_UM		((ushort)0x0c00)
+#define SCU_PMSR_FRZ		((ushort)0x0200)
+#define SCU_PMSR_RZS		((ushort)0x0100)
+#define SCU_PMSR_SYN		((ushort)0x0080)
+#define SCU_PMSR_DRT		((ushort)0x0040)
+#define SCU_PMSR_PEN		((ushort)0x0010)
+#define SCU_PMSR_RPM		((ushort)0x000c)
+#define SCU_PMSR_REVP		((ushort)0x0008)
+#define SCU_PMSR_TPM		((ushort)0x0003)
+#define SCU_PMSR_TEVP		((ushort)0x0003)
+
+/* CPM Transparent mode SCC.
+ */
+typedef struct scc_trans {
+	sccp_t	st_genscc;
+	uint	st_cpres;	/* Preset CRC */
+	uint	st_cmask;	/* Constant mask for CRC */
+} scc_trans_t;
+
+#define BD_SCC_TX_LAST		((ushort)0x0800)
+
+
+
+/* CPM interrupts.  There are nearly 32 interrupts generated by CPM
+ * channels or devices.  All of these are presented to the PPC core
+ * as a single interrupt.  The CPM interrupt handler dispatches its
+ * own handlers, in a similar fashion to the PPC core handler.  We
+ * use the table as defined in the manuals (i.e. no special high
+ * priority and SCC1 == SCCa, etc...).
+ */
+/* #define CPMVEC_NR		32 */
+/* #define	CPMVEC_PIO_PC15		((ushort)0x1f) */
+/* #define	CPMVEC_SCC1		((ushort)0x1e) */
+/* #define	CPMVEC_SCC2		((ushort)0x1d) */
+/* #define	CPMVEC_SCC3		((ushort)0x1c) */
+/* #define	CPMVEC_SCC4		((ushort)0x1b) */
+/* #define	CPMVEC_PIO_PC14		((ushort)0x1a) */
+/* #define	CPMVEC_TIMER1		((ushort)0x19) */
+/* #define	CPMVEC_PIO_PC13		((ushort)0x18) */
+/* #define	CPMVEC_PIO_PC12		((ushort)0x17) */
+/* #define	CPMVEC_SDMA_CB_ERR	((ushort)0x16) */
+/* #define CPMVEC_IDMA1		((ushort)0x15) */
+/* #define CPMVEC_IDMA2		((ushort)0x14) */
+/* #define CPMVEC_TIMER2		((ushort)0x12) */
+/* #define CPMVEC_RISCTIMER	((ushort)0x11) */
+/* #define CPMVEC_I2C		((ushort)0x10) */
+/* #define	CPMVEC_PIO_PC11		((ushort)0x0f) */
+/* #define	CPMVEC_PIO_PC10		((ushort)0x0e) */
+/* #define CPMVEC_TIMER3		((ushort)0x0c) */
+/* #define	CPMVEC_PIO_PC9		((ushort)0x0b) */
+/* #define	CPMVEC_PIO_PC8		((ushort)0x0a) */
+/* #define	CPMVEC_PIO_PC7		((ushort)0x09) */
+/* #define CPMVEC_TIMER4		((ushort)0x07) */
+/* #define	CPMVEC_PIO_PC6		((ushort)0x06) */
+/* #define	CPMVEC_SPI		((ushort)0x05) */
+/* #define	CPMVEC_SMC1		((ushort)0x04) */
+/* #define	CPMVEC_SMC2		((ushort)0x03) */
+/* #define	CPMVEC_PIO_PC5		((ushort)0x02) */
+/* #define	CPMVEC_PIO_PC4		((ushort)0x01) */
+/* #define	CPMVEC_ERROR		((ushort)0x00) */
+
+extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id);
+
+/* CPM interrupt configuration vector.
+*/
+#define	CICR_SCD_SCC4		((uint)0x00c00000)	/* SCC4 @ SCCd */
+#define	CICR_SCC_SCC3		((uint)0x00200000)	/* SCC3 @ SCCc */
+#define	CICR_SCB_SCC2		((uint)0x00040000)	/* SCC2 @ SCCb */
+#define	CICR_SCA_SCC1		((uint)0x00000000)	/* SCC1 @ SCCa */
+#define CICR_IRL_MASK		((uint)0x0000e000)	/* Core interrrupt */
+#define CICR_HP_MASK		((uint)0x00001f00)	/* Hi-pri int. */
+#define CICR_IEN		((uint)0x00000080)	/* Int. enable */
+#define CICR_SPS		((uint)0x00000001)	/* SCC Spread */
+#endif /* __CPM_360__ */
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/quicc/enet.c linux-2.4.29-uc1/arch/m68knommu/platform/68360/quicc/enet.c
--- linux-2.4.29/arch/m68knommu/platform/68360/quicc/enet.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/quicc/enet.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,958 @@
+/*
+ * Ethernet driver for Motorola MPC8xx.
+ * Copyright (c) 2000 Michael Leslie <mleslie@ArcturusNetworks.com>
+ * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
+ *
+ * I copied the basic skeleton from the lance driver, because I did not
+ * know how to write the Linux driver, but I did know how the LANCE worked.
+ *
+ * This version of the driver is somewhat selectable for the different
+ * processor/board combinations.  It works for the boards I know about
+ * now, and should be easily modified to include others.  Some of the
+ * configuration information is contained in "commproc.h" and the
+ * remainder is here.
+ *
+ * Buffer descriptors are kept in the CPM dual port RAM, and the frame
+ * buffers are in the host memory.
+ *
+ * Right now, I am very watseful with the buffers.  I allocate memory
+ * pages and then divide them into 2K frame buffers.  This way I know I
+ * have buffers large enough to hold one frame within one buffer descriptor.
+ * Once I get this working, I will use 64 or 128 byte CPM buffers, which
+ * will be much more memory efficient and will easily handle lots of
+ * small packets.
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/malloc.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+/* #include <linux/init.h> */
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+/* #include <linux/spinlock.h> */
+
+#include <asm/irq.h>
+
+/* for 2.0 compatibility: */
+#include <linux/compatmac.h>
+#define net_device device
+
+#include <asm/m68360.h>
+/* #include <asm/8xx_immap.h> */
+/* #include <asm/pgtable.h> */
+/* #include <asm/mpc8xx.h> */
+#include <asm/bitops.h>
+/* #include <asm/uaccess.h> */
+#include "commproc.h"
+
+
+/*
+ *				Theory of Operation
+ *
+ * The MPC8xx CPM performs the Ethernet processing on SCC1.  It can use
+ * an aribtrary number of buffers on byte boundaries, but must have at
+ * least two receive buffers to prevent constant overrun conditions.
+ *
+ * The buffer descriptors are allocated from the CPM dual port memory
+ * with the data buffers allocated from host memory, just like all other
+ * serial communication protocols.  The host memory buffers are allocated
+ * from the free page pool, and then divided into smaller receive and
+ * transmit buffers.  The size of the buffers should be a power of two,
+ * since that nicely divides the page.  This creates a ring buffer
+ * structure similar to the LANCE and other controllers.
+ *
+ * Like the LANCE driver:
+ * The driver runs as two independent, single-threaded flows of control.  One
+ * is the send-packet routine, which enforces single-threaded use by the
+ * cep->tx_busy flag.  The other thread is the interrupt handler, which is
+ * single threaded by the hardware and other software.
+ *
+ * The send packet thread has partial control over the Tx ring and the
+ * 'cep->tx_busy' flag.  It sets the tx_busy flag whenever it's queuing a Tx
+ * packet. If the next queue slot is empty, it clears the tx_busy flag when
+ * finished otherwise it sets the 'lp->tx_full' flag.
+ *
+ * The MBX has a control register external to the MPC8xx that has some
+ * control of the Ethernet interface.  Information is in the manual for
+ * your board.
+ *
+ * The RPX boards have an external control/status register.  Consult the
+ * programming documents for details unique to your board.
+ *
+ * For the TQM8xx(L) modules, there is no control register interface.
+ * All functions are directly controlled using I/O pins.  See commproc.h.
+ */
+
+
+/* The transmitter timeout
+ */
+#define TX_TIMEOUT	(2*HZ)
+
+/* The number of Tx and Rx buffers.  These are allocated statically here.
+ * We don't need to allocate pages for the transmitter.  We just use
+ * the skbuffer directly.
+ */
+#ifdef CONFIG_ENET_BIG_BUFFERS
+#define RX_RING_SIZE		64
+#define TX_RING_SIZE		64	/* Must be power of two */
+#define TX_RING_MOD_MASK	63	/*   for this to work */
+#else
+#define RX_RING_SIZE		8
+#define TX_RING_SIZE		8	/* Must be power of two */
+#define TX_RING_MOD_MASK	7	/*   for this to work */
+#endif
+
+#define CPM_ENET_RX_FRSIZE  2048 /* overkill left over from ppc page-based allocation */
+static char rx_buf_pool[RX_RING_SIZE * CPM_ENET_RX_FRSIZE];
+
+
+/* The CPM stores dest/src/type, data, and checksum for receive packets.
+ */
+#define PKT_MAXBUF_SIZE		1518
+#define PKT_MINBUF_SIZE		64
+#define PKT_MAXBLR_SIZE		1520
+
+/* The CPM buffer descriptors track the ring buffers.  The rx_bd_base and
+ * tx_bd_base always point to the base of the buffer descriptors.  The
+ * cur_rx and cur_tx point to the currently available buffer.
+ * The dirty_tx tracks the current buffer that is being sent by the
+ * controller.  The cur_tx and dirty_tx are equal under both completely
+ * empty and completely full conditions.  The empty/ready indicator in
+ * the buffer descriptor determines the actual condition.
+ */
+struct scc_enet_private {
+	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
+	struct	sk_buff* tx_skbuff[TX_RING_SIZE];
+	ushort	skb_cur;
+	ushort	skb_dirty;
+
+	/* CPM dual port RAM relative addresses.
+	*/
+	QUICC_BD	*rx_bd_base;		/* Address of Rx and Tx buffers. */
+	QUICC_BD	*tx_bd_base;
+	QUICC_BD	*cur_rx, *cur_tx;		/* The next free ring entry */
+	QUICC_BD	*dirty_tx;	/* The ring entries to be free()ed. */
+	volatile struct scc_regs	*sccp;
+	/* struct	net_device_stats stats; */
+	struct	enet_statistics stats;
+	uint	tx_full;
+	/* spinlock_t lock; */
+	volatile unsigned int lock;
+};
+
+
+
+static int scc_enet_open(struct net_device *dev);
+static int scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static int scc_enet_rx(struct net_device *dev);
+/* static void scc_enet_interrupt(void *dev_id); */
+static void scc_enet_interrupt(int vec, void *dev_id, struct pt_regs *fp);
+static int scc_enet_close(struct net_device *dev);
+/* static struct net_device_stats *scc_enet_get_stats(struct net_device *dev); */
+static struct enet_statistics *scc_enet_get_stats(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
+
+/* Get this from various configuration locations (depends on board).
+*/
+/*static	ushort	my_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };*/
+
+/* Typically, 860(T) boards use SCC1 for Ethernet, and other 8xx boards
+ * use SCC2.  This is easily extended if necessary.
+ */
+
+#define CONFIG_SCC1_ENET /* by default */
+
+#ifdef CONFIG_SCC1_ENET
+#define CPM_CR_ENET CPM_CR_CH_SCC1
+#define PROFF_ENET	PROFF_SCC1
+#define SCC_ENET	0
+#define CPMVEC_ENET	CPMVEC_SCC1
+#endif
+
+#ifdef CONFIG_SCC2_ENET
+#define CPM_CR_ENET	CPM_CR_CH_SCC2
+#define PROFF_ENET	PROFF_SCC2
+#define SCC_ENET	1		/* Index, not number! */
+#define CPMVEC_ENET	CPMVEC_SCC2
+#endif
+
+static int
+scc_enet_open(struct net_device *dev)
+{
+
+	/* I should reset the ring buffers here, but I don't yet know
+	 * a simple way to do that.
+	 * mleslie: That's no biggie. Worth doing, too.
+	 */
+
+	/* netif_start_queue(dev); */
+	return 0;					/* Always succeed */
+}
+
+
+static int
+scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv;
+	volatile QUICC_BD	*bdp;
+
+	/* Fill in a Tx ring entry */
+	bdp = cep->cur_tx;
+
+#ifndef final_version
+	if (bdp->status & BD_ENET_TX_READY) {
+		/* Ooops.  All transmit buffers are full.  Bail out.
+		 * This should not happen, since cep->tx_busy should be set.
+		 */
+		printk("%s: tx queue full!.\n", dev->name);
+		return 1;
+	}
+#endif
+
+	/* Clear all of the status flags.
+	 */
+	bdp->status &= ~BD_ENET_TX_STATS;
+
+	/* If the frame is short, tell CPM to pad it.
+	*/
+	if (skb->len <= ETH_ZLEN)
+		bdp->status |= BD_ENET_TX_PAD;
+	else
+		bdp->status &= ~BD_ENET_TX_PAD;
+
+	/* Set buffer length and buffer pointer.
+	*/
+	bdp->length = skb->len;
+	/* bdp->buf = __pa(skb->data); */
+	bdp->buf = skb->data;
+
+	/* Save skb pointer.
+	*/
+	cep->tx_skbuff[cep->skb_cur] = skb;
+
+	/* cep->stats.tx_bytes += skb->len; */ /* TODO: It would really be nice... */
+
+	cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK;
+	
+
+	/* Push the data cache so the CPM does not get stale memory
+	 * data.
+	 */
+/* 	flush_dcache_range((unsigned long)(skb->data), */
+/* 					(unsigned long)(skb->data + skb->len)); */
+
+	/* spin_lock_irq(&cep->lock); */ /* TODO: SPINLOCK */
+	cli();
+	if (cep->lock > 0) {
+		printk ("scc_enet_start_xmit() lock == %d\n", cep->lock);
+	} else {
+		cep->lock++;
+	}
+
+	/* Send it on its way.  Tell CPM its ready, interrupt when done,
+	 * its the last BD of the frame, and to put the CRC on the end.
+	 */
+	bdp->status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC);
+
+	dev->trans_start = jiffies;
+
+	/* If this was the last BD in the ring, start at the beginning again.
+	*/
+	if (bdp->status & BD_ENET_TX_WRAP)
+		bdp = cep->tx_bd_base;
+	else
+		bdp++;
+
+	if (bdp->status & BD_ENET_TX_READY) {
+		/* netif_stop_queue(dev); */
+		cep->tx_full = 1;
+	}
+
+	cep->cur_tx = (QUICC_BD *)bdp;
+
+	/* spin_unlock_irq(&cep->lock); */ /* TODO: SPINLOCK */
+	cep->lock--;
+	sti();
+
+	return 0;
+}
+
+static void
+scc_enet_timeout(struct net_device *dev)
+{
+	struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv;
+
+	printk("%s: transmit timed out.\n", dev->name);
+	cep->stats.tx_errors++;
+#ifndef final_version
+	{
+		int	i;
+		QUICC_BD	*bdp;
+		printk(" Ring data dump: cur_tx %p%s cur_rx %p.\n",
+		       cep->cur_tx, cep->tx_full ? " (full)" : "",
+		       cep->cur_rx);
+		bdp = cep->tx_bd_base;
+		for (i = 0 ; i < TX_RING_SIZE; i++, bdp++)
+			printk("%04x %04x %08x\n",
+			       bdp->status,
+			       bdp->length,
+			       (int)(bdp->buf));
+		bdp = cep->rx_bd_base;
+		for (i = 0 ; i < RX_RING_SIZE; i++, bdp++)
+			printk("%04x %04x %08x\n",
+			       bdp->status,
+			       bdp->length,
+			       (int)(bdp->buf));
+	}
+#endif
+/* 	if (!cep->tx_full) */
+/* 		netif_wake_queue(dev); */
+}
+
+/* The interrupt handler.
+ * This is called from the CPM handler, not the MPC core interrupt.
+ */
+/* static void scc_enet_interrupt(void *dev_id) */
+static void scc_enet_interrupt(int vec, void *dev_id, struct pt_regs *fp)
+{
+	struct	net_device *dev = (struct net_device *)dev_id;
+	volatile struct	scc_enet_private *cep;
+	volatile QUICC_BD	*bdp;
+	ushort	int_events;
+	int	must_restart;
+
+	cep = (struct scc_enet_private *)dev->priv;
+
+	/* Get the interrupt events that caused us to be here.
+	*/
+	int_events = cep->sccp->scc_scce;
+	cep->sccp->scc_scce = int_events;
+	must_restart = 0;
+
+	/* Handle receive event in its own function.
+	*/
+	if (int_events & SCCE_ENET_RXF)
+		scc_enet_rx(dev_id);
+
+	/* Check for a transmit error.  The manual is a little unclear
+	 * about this, so the debug code until I get it figured out.  It
+	 * appears that if TXE is set, then TXB is not set.  However,
+	 * if carrier sense is lost during frame transmission, the TXE
+	 * bit is set, "and continues the buffer transmission normally."
+	 * I don't know if "normally" implies TXB is set when the buffer
+	 * descriptor is closed.....trial and error :-).
+	 */
+
+	/* Transmit OK, or non-fatal error.  Update the buffer descriptors.
+	*/
+	if (int_events & (SCCE_ENET_TXE | SCCE_ENET_TXB)) {
+	    /* spin_lock(&cep->lock); */ /* TODO: SPINLOCK */
+		/* cli(); */
+		if (cep->lock > 0) {
+			printk ("scc_enet_interrupt() lock == %d\n", cep->lock);
+		} else {
+			cep->lock++;
+		}
+
+	    bdp = cep->dirty_tx;
+	    while ((bdp->status&BD_ENET_TX_READY)==0) {
+		if ((bdp==cep->cur_tx) && (cep->tx_full == 0))
+		    break;
+
+		if (bdp->status & BD_ENET_TX_HB)	/* No heartbeat */
+			cep->stats.tx_heartbeat_errors++;
+		if (bdp->status & BD_ENET_TX_LC)	/* Late collision */
+			cep->stats.tx_window_errors++;
+		if (bdp->status & BD_ENET_TX_RL)	/* Retrans limit */
+			cep->stats.tx_aborted_errors++;
+		if (bdp->status & BD_ENET_TX_UN)	/* Underrun */
+			cep->stats.tx_fifo_errors++;
+		if (bdp->status & BD_ENET_TX_CSL)	/* Carrier lost */
+			cep->stats.tx_carrier_errors++;
+
+
+		/* No heartbeat or Lost carrier are not really bad errors.
+		 * The others require a restart transmit command.
+		 */
+		if (bdp->status &
+		    (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) {
+			must_restart = 1;
+			cep->stats.tx_errors++;
+		}
+
+		cep->stats.tx_packets++;
+
+		/* Deferred means some collisions occurred during transmit,
+		 * but we eventually sent the packet OK.
+		 */
+		if (bdp->status & BD_ENET_TX_DEF)
+			cep->stats.collisions++;
+
+		/* Free the sk buffer associated with this last transmit.
+		*/
+		/* dev_kfree_skb_irq(cep->tx_skbuff[cep->skb_dirty]); */
+		dev_kfree_skb (cep->tx_skbuff[cep->skb_dirty], FREE_WRITE);
+		cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK;
+
+		/* Update pointer to next buffer descriptor to be transmitted.
+		*/
+		if (bdp->status & BD_ENET_TX_WRAP)
+			bdp = cep->tx_bd_base;
+		else
+			bdp++;
+
+		/* I don't know if we can be held off from processing these
+		 * interrupts for more than one frame time.  I really hope
+		 * not.  In such a case, we would now want to check the
+		 * currently available BD (cur_tx) and determine if any
+		 * buffers between the dirty_tx and cur_tx have also been
+		 * sent.  We would want to process anything in between that
+		 * does not have BD_ENET_TX_READY set.
+		 */
+
+		/* Since we have freed up a buffer, the ring is no longer
+		 * full.
+		 */
+		if (cep->tx_full) {
+			cep->tx_full = 0;
+/* 			if (netif_queue_stopped(dev)) */
+/* 				netif_wake_queue(dev); */
+		}
+
+		cep->dirty_tx = (QUICC_BD *)bdp;
+	    }
+
+	    if (must_restart) {
+			volatile QUICC *cp;
+
+		/* Some transmit errors cause the transmitter to shut
+		 * down.  We now issue a restart transmit.  Since the
+		 * errors close the BD and update the pointers, the restart
+		 * _should_ pick up without having to reset any of our
+		 * pointers either.
+		 */
+		cp = pquicc;
+		cp->cp_cr =
+		    mk_cr_cmd(CPM_CR_ENET, CPM_CR_RESTART_TX) | CPM_CR_FLG;
+		while (cp->cp_cr & CPM_CR_FLG);
+	    }
+	    /* spin_unlock(&cep->lock); */ /* TODO: SPINLOCK */
+		/* sti(); */
+		cep->lock--;
+	}
+
+	/* Check for receive busy, i.e. packets coming but no place to
+	 * put them.  This "can't happen" because the receive interrupt
+	 * is tossing previous frames.
+	 */
+	if (int_events & SCCE_ENET_BSY) {
+		cep->stats.rx_dropped++;
+		printk("CPM ENET: BSY can't happen.\n");
+	}
+
+	return;
+}
+
+/* During a receive, the cur_rx points to the current incoming buffer.
+ * When we update through the ring, if the next incoming buffer has
+ * not been given to the system, we just set the empty indicator,
+ * effectively tossing the packet.
+ */
+static int
+scc_enet_rx(struct net_device *dev)
+{
+	struct	scc_enet_private *cep;
+	volatile QUICC_BD	*bdp;
+	struct	sk_buff *skb;
+	ushort	pkt_len;
+
+	cep = (struct scc_enet_private *)dev->priv;
+
+	/* First, grab all of the stats for the incoming packet.
+	 * These get messed up if we get called due to a busy condition.
+	 */
+	bdp = cep->cur_rx;
+
+	for (;;) {
+		if (bdp->status & BD_ENET_RX_EMPTY)
+			break;
+		
+#ifndef final_version
+		/* Since we have allocated space to hold a complete frame, both
+		 * the first and last indicators should be set.
+		 */
+		if ((bdp->status & (BD_ENET_RX_FIRST | BD_ENET_RX_LAST)) !=
+			(BD_ENET_RX_FIRST | BD_ENET_RX_LAST))
+			printk("CPM ENET: rcv is not first+last\n");
+#endif
+
+		/* Frame too long or too short.
+		 */
+		if (bdp->status & (BD_ENET_RX_LG | BD_ENET_RX_SH))
+			cep->stats.rx_length_errors++;
+		if (bdp->status & BD_ENET_RX_NO)	/* Frame alignment */
+			cep->stats.rx_frame_errors++;
+		if (bdp->status & BD_ENET_RX_CR)	/* CRC Error */
+			cep->stats.rx_crc_errors++;
+		if (bdp->status & BD_ENET_RX_OV)	/* FIFO overrun */
+			cep->stats.rx_crc_errors++;
+
+		/* Report late collisions as a frame error.
+		 * On this error, the BD is closed, but we don't know what we
+		 * have in the buffer.  So, just drop this frame on the floor.
+		 */
+		if (bdp->status & BD_ENET_RX_CL) {
+			cep->stats.rx_frame_errors++;
+		}
+		else {
+			
+			/* Process the incoming frame.
+			 */
+			cep->stats.rx_packets++;
+			pkt_len = bdp->length;
+			/* cep->stats.rx_bytes += pkt_len; */  /* TODO: It would really be nice... */
+
+			/* This does 16 byte alignment, much more than we need.
+			 * The packet length includes FCS, but we don't want to
+			 * include that when passing upstream as it messes up
+			 * bridging applications.
+			 */
+			skb = dev_alloc_skb(pkt_len-4);
+
+			if (skb == NULL) {
+				printk("%s: Memory squeeze, dropping packet.\n", dev->name);
+				cep->stats.rx_dropped++;
+			}
+			else {
+				skb->dev = dev;
+				skb_put(skb,pkt_len-4);	/* Make room */
+				eth_copy_and_sum(skb, (unsigned char *)bdp->buf, pkt_len-4, 0);
+				skb->protocol=eth_type_trans(skb,dev);
+				netif_rx(skb);
+			}
+		}
+
+		/* Clear the status flags for this buffer.
+		 */
+		bdp->status &= ~BD_ENET_RX_STATS;
+
+		/* Mark the buffer empty.
+		 */
+		bdp->status |= BD_ENET_RX_EMPTY;
+
+		/* Update BD pointer to next entry.
+		 */
+		if (bdp->status & BD_ENET_RX_WRAP)
+			bdp = cep->rx_bd_base;
+		else
+			bdp++;
+
+	}
+	cep->cur_rx = (QUICC_BD *)bdp;
+
+	return 0;
+}
+
+static int
+scc_enet_close(struct net_device *dev)
+{
+	/* Don't know what to do yet.
+	*/
+	/* netif_stop_queue(dev); */
+
+	return 0;
+}
+
+/* static struct net_device_stats *scc_enet_get_stats(struct net_device *dev) */
+static struct enet_statistics *scc_enet_get_stats(struct net_device *dev)
+{
+	struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv;
+
+	return &cep->stats;
+}
+
+/* Set or clear the multicast filter for this adaptor.
+ * Skeleton taken from sunlance driver.
+ * The CPM Ethernet implementation allows Multicast as well as individual
+ * MAC address filtering.  Some of the drivers check to make sure it is
+ * a group multicast address, and discard those that are not.  I guess I
+ * will do the same for now, but just remove the test if you want
+ * individual filtering as well (do the upper net layers want or support
+ * this kind of feature?).
+ */
+
+static void set_multicast_list(struct net_device *dev)
+{
+	struct	scc_enet_private *cep;
+	struct	dev_mc_list *dmi;
+	u_char	*mcptr, *tdptr;
+	volatile scc_enet_t *ep;
+	int	i, j;
+	volatile QUICC *cp = pquicc;
+
+	cep = (struct scc_enet_private *)dev->priv;
+
+	/* Get pointer to SCC area in parameter RAM.
+	*/
+	ep = (scc_enet_t *)dev->base_addr;
+
+	if (dev->flags&IFF_PROMISC) {
+	  
+		/* Log any net taps. */
+		printk("%s: Promiscuous mode enabled.\n", dev->name);
+		cep->sccp->scc_psmr |= ETHER_PRO; 
+	} else {
+
+		cep->sccp->scc_psmr &= ~ETHER_PRO;
+
+		if (dev->flags & IFF_ALLMULTI) {
+			/* Catch all multicast addresses, so set the
+			 * filter to all 1's.
+			 */
+			ep->sen_gaddr1 = 0xffff;
+			ep->sen_gaddr2 = 0xffff;
+			ep->sen_gaddr3 = 0xffff;
+			ep->sen_gaddr4 = 0xffff;
+		}
+		else {
+			/* Clear filter and add the addresses in the list.
+			*/
+			ep->sen_gaddr1 = 0;
+			ep->sen_gaddr2 = 0;
+			ep->sen_gaddr3 = 0;
+			ep->sen_gaddr4 = 0;
+
+			dmi = dev->mc_list;
+
+			for (i=0; i<dev->mc_count; i++) {
+				
+				/* Only support group multicast for now.
+				*/
+				if (!(dmi->dmi_addr[0] & 1))
+					continue;
+
+				/* The address in dmi_addr is LSB first,
+				 * and taddr is MSB first.  We have to
+				 * copy bytes MSB first from dmi_addr.
+				 */
+				mcptr = (u_char *)dmi->dmi_addr + 5;
+				tdptr = (u_char *)&ep->sen_taddrh;
+				for (j=0; j<6; j++)
+					*tdptr++ = *mcptr--;
+
+				/* Ask CPM to run CRC and set bit in
+				 * filter mask.
+				 */
+				cp->cp_cr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_SET_GADDR) | CPM_CR_FLG;
+				/* this delay is necessary here -- Cort */
+				udelay(10);
+				while (cp->cp_cr & CPM_CR_FLG);
+			}
+		}
+	}
+}
+
+
+/* Initialize the CPM Ethernet on SCC.
+ */
+int scc_enet_init(void)
+{
+	struct net_device *dev;
+	struct scc_enet_private *cep;
+	int i, j;
+	unsigned char	*eap;
+	/* unsigned long	mem_addr; */
+	/* pte_t		*pte; */
+	/* bd_t		*bd; */ /* `board tag' used by ppc - TODO: integrate uC bootloader vars */
+	volatile	QUICC_BD	*bdp;
+	volatile	QUICC	*cp;
+	volatile struct scc_regs	*sccp;
+	volatile struct	ethernet_pram	*ep;
+	/* volatile	immap_t		*immap; */
+
+	cp = pquicc;	/* Get pointer to Communication Processor */
+
+	/* immap = (immap_t *)IMAP_ADDR; */	/* and to internal registers */
+
+	/* bd = (bd_t *)__res; */
+
+	/* Allocate some private information.
+	*/
+	cep = (struct scc_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL);
+	memset(cep, 0, sizeof(*cep));
+	/* __clear_user(cep,sizeof(*cep)); */
+	/* spin_lock_init(&cep->lock); */ /* TODO: SPINLOCK */
+
+	/* Create an Ethernet device instance.
+	 */
+	dev = init_etherdev(0, 0);
+
+	/* Get pointer to SCC area in parameter RAM.
+	*/
+	/* ep = (ethernet_pram *)(&cp->cp_dparam[PROFF_ENET]); */
+	ep = &pquicc->pram[SCC_ENET].enet_scc;
+
+	/* And another to the SCC register area.
+	*/
+	sccp = &pquicc->scc_regs[SCC_ENET];
+	cep->sccp = sccp;		/* Keep the pointer handy */
+
+	/* Disable receive and transmit in case EPPC-Bug started it.
+	*/
+	sccp->scc_gsmr.w.low &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+	/* Set up 360 pins for SCC interface to ethernet transceiver.
+	 * Pin mappings (PA_xx and PC_xx) are defined in commproc.h
+	 */
+
+	/* Configure port A pins for Txd and Rxd.
+	 */
+	pquicc->pio_papar |= (PA_ENET_RXD | PA_ENET_TXD);
+	pquicc->pio_padir &= ~(PA_ENET_RXD | PA_ENET_TXD);
+	pquicc->pio_paodr &= ~PA_ENET_TXD;
+
+	/* Configure port C pins to enable CLSN and RENA.
+	 */
+	pquicc->pio_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+	pquicc->pio_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+	pquicc->pio_pcso |= (PC_ENET_CLSN | PC_ENET_RENA);
+
+	/* Configure port A for TCLK and RCLK.
+	*/
+	pquicc->pio_papar |= (PA_ENET_TCLK | PA_ENET_RCLK);
+	pquicc->pio_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
+
+	/* Configure Serial Interface clock routing.
+	 * First, clear all SCC bits to zero, then set the ones we want.
+	 */
+	pquicc->si_sicr &= ~SICR_ENET_MASK;
+	pquicc->si_sicr |= SICR_ENET_CLKRT;
+
+
+	/* Allocate space for the buffer descriptors in the DP ram.
+	 * These are relative offsets in the DP ram address space.
+	 * Initialize base addresses for the buffer descriptors.
+	 */
+	i = m360_cpm_dpalloc(sizeof(QUICC_BD) * RX_RING_SIZE);
+	ep->rbase = i;
+	cep->rx_bd_base = (QUICC_BD *)((uint)pquicc + i);
+
+	i = m360_cpm_dpalloc(sizeof(QUICC_BD) * TX_RING_SIZE);
+	ep->tbase = i;
+	cep->tx_bd_base = (QUICC_BD *)((uint)pquicc + i);
+
+	cep->dirty_tx = cep->cur_tx = cep->tx_bd_base;
+	cep->cur_rx = cep->rx_bd_base;
+
+	/* Issue init Rx BD command for SCC.
+	 * Manual says to perform an Init Rx parameters here.  We have
+	 * to perform both Rx and Tx because the SCC may have been
+	 * already running. [In uCquicc's case, I don't think that is so - mles]
+	 * In addition, we have to do it later because we don't yet have
+	 * all of the BD control/status set properly.
+	cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_RX) | CPM_CR_FLG;
+	while (cp->cp_cpcr & CPM_CR_FLG);
+	 */
+
+	/* Initialize function code registers for big-endian.
+	*/
+	ep->rfcr = (SCC_EB | SCC_FC_DMA);
+	ep->tfcr = (SCC_EB | SCC_FC_DMA);
+
+	/* Set maximum bytes per receive buffer.
+	 * This appears to be an Ethernet frame size, not the buffer
+	 * fragment size.  It must be a multiple of four.
+	 */
+	ep->mrblr  = PKT_MAXBLR_SIZE;
+
+	/* Set CRC preset and mask.
+	 */
+	ep->c_pres = 0xffffffff;
+	ep->c_mask = 0xdebb20e3; /* see 360UM p. 7-247 */
+
+	ep->crcec  = 0;	/* CRC Error counter */
+	ep->alec   = 0;	/* alignment error counter */
+	ep->disfc  = 0;	/* discard frame counter */
+
+	ep->pads   = 0x8888;	/* Tx short frame pad character */
+	ep->ret_lim = 0x000f;	/* Retry limit threshold */
+
+	ep->mflr   = PKT_MAXBUF_SIZE;	/* maximum frame length register */
+	ep->minflr = PKT_MINBUF_SIZE;	/* minimum frame length register */
+
+	ep->maxd1 = PKT_MAXBLR_SIZE;	/* maximum DMA1 length */
+	ep->maxd2 = PKT_MAXBLR_SIZE;	/* maximum DMA2 length */
+
+	/* Clear hash tables, group and individual.
+	 */
+	ep->gaddr1 = ep->gaddr2 = ep->gaddr3 = ep->gaddr4 = 0;
+	ep->iaddr1 = ep->iaddr2 = ep->iaddr3 = ep->iaddr4 = 0;
+
+	/* Set Ethernet station address.
+	 *
+	 * The uCbootloader provides a hook to the kernel to retrieve
+	 * stuff like the MAC address. This is retrieved in config_BSP()
+	 */
+#if defined (CONFIG_UCQUICC)
+	{
+ 		extern unsigned char *scc1_hwaddr;
+
+		eap = (char *)ep->paddr.b;
+		for (i=5; i>=0; i--)
+			*eap++ = dev->dev_addr[i] = scc1_hwaddr[i];
+	}
+#endif
+
+
+/* #ifndef CONFIG_MBX */
+/* 	eap = (unsigned char *)&(ep->paddrh); */
+
+/* 	for (i=5; i>=0; i--) */
+/* 		*eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i]; */
+/* #else */
+/* 	for (i=5; i>=0; i--) */
+/* 		dev->dev_addr[i] = *eap++; */
+/* #endif */
+
+	ep->p_per   = 0;	/* 'cause the book says so */
+	ep->taddr_l = 0;	/* temp address (LSB) */
+	ep->taddr_m = 0;
+	ep->taddr_h = 0;	/* temp address (MSB) */
+
+	/* Now allocate the host memory pages and initialize the
+	 * buffer descriptors.
+	 */
+	/* initialize rx buffer descriptors */
+	bdp = cep->tx_bd_base;
+	for (j=0; j<(TX_RING_SIZE-1); j++) {
+		bdp->buf = 0;
+		bdp->status = 0;
+		bdp++;
+	}
+	bdp->buf = 0;
+	bdp->status = BD_SC_WRAP;
+
+
+	/* initialize rx buffer descriptors */
+	bdp = cep->rx_bd_base;
+	for (j=0; j<(RX_RING_SIZE-1); j++) {
+		bdp->buf = &rx_buf_pool[j * CPM_ENET_RX_FRSIZE];
+		bdp->status = BD_SC_EMPTY | BD_SC_INTRPT;
+		bdp++;
+	}
+	bdp->buf = &rx_buf_pool[j * CPM_ENET_RX_FRSIZE];
+	bdp->status = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
+
+
+
+	/* Let's re-initialize the channel now.  We have to do it later
+	 * than the manual describes because we have just now finished
+	 * the BD initialization.
+	 */
+	cp->cp_cr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+	while (cp->cp_cr & CPM_CR_FLG);
+
+	cep->skb_cur = cep->skb_dirty = 0;
+
+	sccp->scc_scce = 0xffff;	/* Clear any pending events */
+
+	/* Enable interrupts for transmit error, complete frame
+	 * received, and any transmit buffer we have also set the
+	 * interrupt flag.
+	 */
+	sccp->scc_sccm = (SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB);
+
+	/* Install our interrupt handler.
+	 */
+	/* cpm_install_handler(CPMVEC_ENET, scc_enet_interrupt, dev); */
+	request_irq(IRQ_MACHSPEC | CPMVEC_ENET, scc_enet_interrupt,
+				IRQ_FLG_LOCK, dev->name, (void *)dev);
+
+	/* Set GSMR_H to enable all normal operating modes.
+	 * Set GSMR_L to enable Ethernet to MC68160.
+	 */
+	sccp->scc_gsmr.w.high = 0;
+	sccp->scc_gsmr.w.low  = (SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 |
+							 SCC_GSMRL_TPP_10 | SCC_GSMRL_MODE_ENET);
+
+	/* Set sync/delimiters.
+	 */
+	sccp->scc_dsr = 0xd555;
+
+	/* Set processing mode.  Use Ethernet CRC, catch broadcast, and
+	 * start frame search 22 bit times after RENA.
+	 */
+	sccp->scc_psmr = (SCC_PMSR_ENCRC       /* Ethernet CRC mode */
+			  /* | SCC_PSMR_HBC */ /* Enable heartbeat */
+			  /* | SCC_PMSR_PRO */ /* Promiscuous mode */
+			  /* | SCC_PMSR_FDE */ /* Full duplex enable */
+			  | ETHER_NIB_22);
+	/* sccp->scc_psmr = (SCC_PMSR_PRO | ETHER_CRC_32 | ETHER_NIB_22); */
+
+
+	/* It is now OK to enable the Ethernet transmitter.
+	 * Unfortunately, there are board implementation differences here.
+	 */
+#if defined(CONFIG_UCQUICC)
+/* 	 immap->im_ioport.iop_pcpar |= PC_ENET_TENA; */
+/* 	 immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA; */
+	 cp->pio_pcpar |=  PC_ENET_TENA; /* t_en */
+	 cp->pio_pcdir &= ~PC_ENET_TENA;
+
+	 cp->pip_pbpar &= ~(0x00000200); /* power up ethernet transceiver */
+	 cp->pip_pbdir |=  (0x00000200);
+	 cp->pip_pbdat |=  (0x00000200);
+#endif
+
+
+	dev->base_addr = (unsigned long)ep;
+	dev->priv = cep;
+#if 0
+	dev->name = "CPM_ENET";
+#endif
+
+	/* The CPM Ethernet specific entries in the device structure. */
+	dev->open = scc_enet_open;
+	dev->hard_start_xmit = scc_enet_start_xmit;
+	/* dev->tx_timeout = scc_enet_timeout; */
+	/* dev->watchdog_timeo = TX_TIMEOUT; */
+	dev->stop = scc_enet_close;
+	dev->get_stats = scc_enet_get_stats;
+	dev->set_multicast_list = set_multicast_list;
+
+	/* And last, enable the transmit and receive processing.
+	*/
+	sccp->scc_gsmr.w.low |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+	printk("%s: CPM ENET Version 0.3, ", dev->name);
+	for (i=0; i<5; i++)
+		printk("%02x:", dev->dev_addr[i]);
+	printk("%02x\n", dev->dev_addr[5]);
+
+	return 0;
+}
+
+
+
+int m68360_enet_probe(struct device *dev)
+{
+	scc_enet_init ();	
+}
+
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/quicc/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/68360/quicc/Makefile
--- linux-2.4.29/arch/m68knommu/platform/68360/quicc/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/quicc/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,25 @@
+#
+# Makefile for the linux MC68360 CPM access routines
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET := quicc360.a
+O_OBJS	= commproc.o
+
+ifdef CONFIG_M68360_UART
+O_OBJS += uart.o
+endif
+
+ifdef CONFIG_M68EN360_ETHERNET
+O_OBJS += enet.o
+endif
+
+ifdef CONFIG_M68EN360_HDLC
+O_OBJS += hdlc.o
+endif
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/quicc/uart.c linux-2.4.29-uc1/arch/m68knommu/platform/68360/quicc/uart.c
--- linux-2.4.29/arch/m68knommu/platform/68360/quicc/uart.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/quicc/uart.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,3199 @@
+/*
+ *  UART driver for 68360 CPM SCC or SMC
+ *  Copyright (c) 2000 D. Jeff Dionne <jeff@uclinux.org>,
+ *  Copyright (c) 2000 Michael Leslie <mleslie@ArcturusNetworks.com>
+ *  Copyright (c) 1997 Dan Malek <dmalek@jlc.net>
+ *
+ * I used the serial.c driver as the framework for this driver.
+ * Give credit to those guys.
+ * The original code was written for the MBX860 board.  I tried to make
+ * it generic, but there may be some assumptions in the structures that
+ * have to be fixed later.
+ * To save porting time, I did not bother to change any object names
+ * that are not accessed outside of this file.
+ * It still needs lots of work........When it was easy, I included code
+ * to support the SCCs, but this has never been tested, nor is it complete.
+ * Only the SCCs support modem control, so that is not complete either.
+ *
+ * This module exports the following rs232 io functions:
+ *
+ *	int rs_360_init(void);
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/serialP.h> 
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/mm.h>
+#include <linux/malloc.h>
+/* #include <linux/init.h> */
+#include <linux/delay.h>
+/* #include <asm/uaccess.h> */
+#include <asm/irq.h>
+
+#include <linux/compatmac.h>
+
+#include <asm/m68360.h>
+/* #include <asm/360_immap.h> */ /* more hierarchical than m68360_quicc.h */
+#include "commproc.h"
+
+ 
+#ifdef CONFIG_KGDB
+extern void breakpoint(void);
+extern void set_debug_traps(void);
+extern int  kgdb_output_string (const char* s, unsigned int count);
+#endif
+
+
+/* #ifdef CONFIG_SERIAL_CONSOLE */ /* This seems to be a post 2.0 thing - mles */
+#include <linux/console.h>
+
+/* this defines the index into rs_table for the port to use
+ */
+#ifndef CONFIG_SERIAL_CONSOLE_PORT
+#define CONFIG_SERIAL_CONSOLE_PORT	1 /* ie SMC2 - note USE_SMC2 must be defined */
+#endif
+/* #endif */
+
+#if 0
+/* SCC2 for console
+ */
+#undef CONFIG_SERIAL_CONSOLE_PORT
+#define CONFIG_SERIAL_CONSOLE_PORT	2
+#endif
+
+
+#define TX_WAKEUP	ASYNC_SHARE_IRQ
+
+static char *serial_name = "CPM UART driver";
+static char *serial_version = "0.03";
+
+static DECLARE_TASK_QUEUE(tq_serial);
+
+static struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+int serial_console_setup(struct console *co, char *options);
+
+/*
+ * Serial driver configuration section.  Here are the various options:
+ */
+#define SERIAL_PARANOIA_CHECK
+#define CONFIG_SERIAL_NOPAUSE_IO
+#define SERIAL_DO_RESTART
+
+/* Set of debugging defines */
+
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+
+#define _INLINE_ inline
+  
+#define DBG_CNT(s)
+
+/* We overload some of the items in the data structure to meet our
+ * needs.  For example, the port address is the CPM parameter ram
+ * offset for the SCC or SMC.  The maximum number of ports is 4 SCCs and
+ * 2 SMCs.  The "hub6" field is used to indicate the channel number, with
+ * a flag indicating SCC or SMC, and the number is used as an index into
+ * the CPM parameter area for this device.
+ * The "type" field is currently set to 0, for PORT_UNKNOWN.  It is
+ * not currently used.  I should probably use it to indicate the port
+ * type of SMC or SCC.
+ * The SMCs do not support any modem control signals.
+ */
+#define smc_scc_num	hub6
+#define NUM_IS_SCC	((int)0x00010000)
+#define PORT_NUM(P)	((P) & 0x0000ffff)
+
+
+#if defined (CONFIG_UCQUICC)
+
+volatile extern void *_periph_base;
+/* sipex transceiver
+ *   mode bits for       are on pins
+ *
+ *    SCC2                d16..19
+ *    SCC3                d20..23
+ *    SCC4                d24..27
+ */
+#define SIPEX_MODE(n,m) ((m & 0x0f)<<(16+4*(n-1)))
+
+static uint sipex_mode_bits = 0x00000000;
+
+#endif
+
+/* There is no `serial_state' defined back here in 2.0.
+ * Try to get by with serial_struct
+ */
+/* #define serial_state serial_struct */
+
+/* 2.4 -> 2.0 portability problem: async_icount in 2.4 has a few
+ * extras: */
+
+#if 0
+struct async_icount_24 {
+	__u32   cts, dsr, rng, dcd, tx, rx;
+	__u32   frame, parity, overrun, brk;
+	__u32   buf_overrun;
+} icount;
+#endif
+
+#if 0
+
+struct serial_state {
+        int     magic;
+        int     baud_base;
+        unsigned long   port;
+        int     irq;
+        int     flags;
+        int     hub6;
+        int     type;
+        int     line;
+        int     revision;       /* Chip revision (950) */
+        int     xmit_fifo_size;
+        int     custom_divisor;
+        int     count;
+        u8      *iomem_base;
+        u16     iomem_reg_shift;
+        unsigned short  close_delay;
+        unsigned short  closing_wait; /* time to wait before closing */
+        struct async_icount_24     icount; 
+        struct termios          normal_termios;
+        struct termios          callout_termios;
+        int     io_type;
+        struct async_struct *info;
+};
+#endif
+
+#define SSTATE_MAGIC 0x5302
+
+
+
+/* SMC2 is sometimes used for low performance TDM interfaces.  Define
+ * this as 1 if you want SMC2 as a serial port UART managed by this driver.
+ * Define this as 0 if you wish to use SMC2 for something else.
+ */
+#define USE_SMC2 1
+
+#if 0
+/* Define SCC to ttySx mapping. */
+#define SCC_NUM_BASE	(USE_SMC2 + 1)	/* SCC base tty "number" */
+
+/* Define which SCC is the first one to use for a serial port.  These
+ * are 0-based numbers, i.e. this assumes the first SCC (SCC1) is used
+ * for Ethernet, and the first available SCC for serial UART is SCC2.
+ * NOTE:  IF YOU CHANGE THIS, you have to change the PROFF_xxx and
+ * interrupt vectors in the table below to match.
+ */
+#define SCC_IDX_BASE	1	/* table index */
+#endif
+
+
+/* Processors other than the 860 only get SMCs configured by default.
+ * Either they don't have SCCs or they are allocated somewhere else.
+ * Of course, there are now 860s without some SCCs, so we will need to
+ * address that someday.
+ * The Embedded Planet Multimedia I/O cards use TDM interfaces to the
+ * stereo codec parts, and we use SMC2 to help support that.
+ */
+static struct serial_state rs_table[] = {
+/*  type   line   PORT           IRQ       FLAGS  smc_scc_num (F.K.A. hub6) */
+	{  0,     0, PRSLOT_SMC1, CPMVEC_SMC1,   0,    0 }    /* SMC1 ttyS0 */
+#if USE_SMC2
+	,{ 0,     0, PRSLOT_SMC2, CPMVEC_SMC2,   0,    1 }     /* SMC2 ttyS1 */
+#endif
+
+#if defined(CONFIG_M68360_SCC_UART)
+	,{ 0,     0, PRSLOT_SCC2, CPMVEC_SCC2,   0, (NUM_IS_SCC | 1) }    /* SCC2 ttyS2 */
+	,{ 0,     0, PRSLOT_SCC3, CPMVEC_SCC3,   0, (NUM_IS_SCC | 2) }    /* SCC3 ttyS3 */
+	,{ 0,     0, PRSLOT_SCC4, CPMVEC_SCC4,   0, (NUM_IS_SCC | 3) }    /* SCC4 ttyS4 */
+#endif
+};
+
+#define NR_PORTS	(sizeof(rs_table)/sizeof(struct serial_state))
+
+static struct tty_struct *serial_table[NR_PORTS];
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
+
+/* The number of buffer descriptors and their sizes.
+ */
+#define RX_NUM_FIFO	4
+#define RX_BUF_SIZE	32
+#define TX_NUM_FIFO	4
+#define TX_BUF_SIZE	32
+
+#define CONSOLE_NUM_FIFO 2
+#define CONSOLE_BUF_SIZE 4
+
+char *console_fifos[CONSOLE_NUM_FIFO * CONSOLE_BUF_SIZE];
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+/* The async_struct in serial.h does not really give us what we
+ * need, so define our own here.
+ */
+typedef struct serial_info {
+	int			magic;
+	int			flags;
+
+	struct serial_state		*state;
+ 	/* struct serial_struct	*state; */
+ 	/* struct async_struct	*state; */
+	
+	struct tty_struct 	*tty;
+	int			read_status_mask;
+	int			ignore_status_mask;
+	int			timeout;
+	int			line;
+	int			x_char;	/* xon/xoff character */
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	unsigned long		event;
+	unsigned long		last_active;
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+	struct tq_struct	tqueue;
+	struct tq_struct	tqueue_hangup;
+ 	wait_queue_head_t	open_wait; 
+ 	wait_queue_head_t	close_wait; 
+/*	struct wait_queue     *open_wait; */
+/*	struct wait_queue	   *close_wait;i */
+
+	
+/* CPM Buffer Descriptor pointers.
+	*/
+	QUICC_BD			*rx_bd_base;
+	QUICC_BD			*rx_cur;
+	QUICC_BD			*tx_bd_base;
+	QUICC_BD			*tx_cur;
+} ser_info_t;
+
+
+/* since kmalloc_init() does not get called until much after this initialization: */
+static ser_info_t  quicc_ser_info[NR_PORTS];
+static char rx_buf_pool[NR_PORTS * RX_NUM_FIFO * RX_BUF_SIZE];
+static char tx_buf_pool[NR_PORTS * TX_NUM_FIFO * TX_BUF_SIZE];
+
+static void change_speed(ser_info_t *info);
+static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout);
+
+static inline int serial_paranoia_check(ser_info_t *info,
+					kdev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%s) in %s\n";
+	static const char *badinfo =
+		"Warning: null async_struct for (%s) in %s\n";
+
+	if (!info) {
+		printk(badinfo, kdevname(device), routine);
+		return 1;
+	}
+	if (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, kdevname(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+/*
+ * This is used to figure out the divisor speeds and the timeouts,
+ * indexed by the termio value.  The generic CPM functions are responsible
+ * for setting and assigning baud rate generators for us.
+ */
+static int baud_table[] = {
+	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
+	9600, 19200, 38400, 57600, 115200, 230400, 460800, 0 };
+
+/* This sucks. There is a better way: */
+#if defined(CONFIG_CONSOLE_9600)
+  #define CONSOLE_BAUDRATE 9600
+#elif defined(CONFIG_CONSOLE_19200)
+  #define CONSOLE_BAUDRATE 19200
+#elif defined(CONFIG_CONSOLE_115200)
+  #define CONSOLE_BAUDRATE 115200
+#else
+#error "console baud rate undefined"
+#endif
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_360_stop(struct tty_struct *tty)
+{
+	ser_info_t *info = (ser_info_t *)tty->driver_data;
+	int	idx;
+	unsigned long flags;
+ 	volatile struct scc_regs *sccp;
+ 	volatile struct smc_regs *smcp;
+
+	if (serial_paranoia_check(info, tty->device, "rs_stop"))
+		return;
+	
+	save_flags(flags); cli();
+	idx = PORT_NUM(info->state->smc_scc_num);
+	if (info->state->smc_scc_num & NUM_IS_SCC) {
+		sccp = &pquicc->scc_regs[idx];
+		sccp->scc_sccm &= ~UART_SCCM_TX;
+	} else {
+		/* smcp = &cpmp->cp_smc[idx]; */
+		smcp = &pquicc->smc_regs[idx];
+		smcp->smc_smcm &= ~SMCM_TX;
+	}
+	restore_flags(flags);
+}
+
+
+static void rs_360_start(struct tty_struct *tty)
+{
+	ser_info_t *info = (ser_info_t *)tty->driver_data;
+	int	idx;
+	unsigned long flags;
+	volatile struct scc_regs *sccp;
+	volatile struct smc_regs *smcp;
+
+	if (serial_paranoia_check(info, tty->device, "rs_stop"))
+		return;
+	
+	save_flags(flags); cli();
+	idx = PORT_NUM(info->state->smc_scc_num);
+	if (info->state->smc_scc_num & NUM_IS_SCC) {
+		sccp = &pquicc->scc_regs[idx];
+		sccp->scc_sccm |= UART_SCCM_TX;
+	} else {
+		smcp = &pquicc->smc_regs[idx];
+		smcp->smc_smcm |= SMCM_TX;
+	}
+	restore_flags(flags);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ * 
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assemble code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static _INLINE_ void rs_sched_event(ser_info_t *info,
+				  int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_serial);
+	mark_bh(SERIAL_BH);
+}
+
+static _INLINE_ void receive_chars(ser_info_t *info)
+{
+	struct tty_struct *tty = info->tty;
+	unsigned char ch, *cp;
+	/*int	ignored = 0;*/
+	int	i;
+	ushort	status;
+	 struct	async_icount *icount; 
+	/* struct	async_icount_24 *icount; */
+	volatile QUICC_BD	*bdp;
+
+	icount = &info->state->icount;
+
+	/* Just loop through the closed BDs and copy the characters into
+	 * the buffer.
+	 */
+	bdp = info->rx_cur;
+	for (;;) {
+		if (bdp->status & BD_SC_EMPTY)	/* If this one is empty */
+			break;			/*   we are all done */
+
+		/* The read status mask tell us what we should do with
+		 * incoming characters, especially if errors occur.
+		 * One special case is the use of BD_SC_EMPTY.  If
+		 * this is not set, we are supposed to be ignoring
+		 * inputs.  In this case, just mark the buffer empty and
+		 * continue.
+		 */
+		if (!(info->read_status_mask & BD_SC_EMPTY)) {
+			bdp->status |= BD_SC_EMPTY;
+			bdp->status &=
+				~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV);
+
+			if (bdp->status & BD_SC_WRAP)
+				bdp = info->rx_bd_base;
+			else
+				bdp++;
+			continue;
+		}
+
+		/* Get the number of characters and the buffer pointer.
+		*/
+		i = bdp->length;
+		/* cp = (unsigned char *)__va(bdp->buf); */
+		cp = (char *)bdp->buf;
+		status = bdp->status;
+
+		/* Check to see if there is room in the tty buffer for
+		 * the characters in our BD buffer.  If not, we exit
+		 * now, leaving the BD with the characters.  We'll pick
+		 * them up again on the next receive interrupt (which could
+		 * be a timeout).
+		 */
+		if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE)
+			break;
+
+		while (i-- > 0) {
+			ch = *cp++;
+			*tty->flip.char_buf_ptr = ch;
+			icount->rx++;
+
+#ifdef SERIAL_DEBUG_INTR
+			printk("DR%02x:%02x...", ch, status);
+#endif
+			*tty->flip.flag_buf_ptr = 0;
+			if (status & (BD_SC_BR | BD_SC_FR |
+				       BD_SC_PR | BD_SC_OV)) {
+				/*
+				 * For statistics only
+				 */
+				if (status & BD_SC_BR)
+					icount->brk++;
+				else if (status & BD_SC_PR)
+					icount->parity++;
+				else if (status & BD_SC_FR)
+					icount->frame++;
+				if (status & BD_SC_OV)
+					icount->overrun++;
+
+				/*
+				 * Now check to see if character should be
+				 * ignored, and mask off conditions which
+				 * should be ignored.
+				if (status & info->ignore_status_mask) {
+					if (++ignored > 100)
+						break;
+					continue;
+				}
+				 */
+				status &= info->read_status_mask;
+		
+				if (status & (BD_SC_BR)) {
+#ifdef SERIAL_DEBUG_INTR
+					printk("handling break....");
+#endif
+					*tty->flip.flag_buf_ptr = TTY_BREAK;
+					if (info->flags & ASYNC_SAK)
+						do_SAK(tty);
+				} else if (status & BD_SC_PR)
+					*tty->flip.flag_buf_ptr = TTY_PARITY;
+				else if (status & BD_SC_FR)
+					*tty->flip.flag_buf_ptr = TTY_FRAME;
+				if (status & BD_SC_OV) {
+					/*
+					 * Overrun is special, since it's
+					 * reported immediately, and doesn't
+					 * affect the current character
+					 */
+					if (tty->flip.count < TTY_FLIPBUF_SIZE) {
+						tty->flip.count++;
+						tty->flip.flag_buf_ptr++;
+						tty->flip.char_buf_ptr++;
+						*tty->flip.flag_buf_ptr =
+								TTY_OVERRUN;
+					}
+				}
+			}
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+				break;
+
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+
+		/* This BD is ready to be used again.  Clear status.
+		 * Get next BD.
+		 */
+		bdp->status |= BD_SC_EMPTY;
+		bdp->status &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV);
+
+		if (bdp->status & BD_SC_WRAP)
+			bdp = info->rx_bd_base;
+		else
+			bdp++;
+	}
+
+	info->rx_cur = (QUICC_BD *)bdp;
+
+	queue_task(&tty->flip.tqueue, &tq_timer);
+}
+
+static _INLINE_ void receive_break(ser_info_t *info)
+{
+	struct tty_struct *tty = info->tty;
+
+	info->state->icount.brk++;
+	/* Check to see if there is room in the tty buffer for
+	 * the break.  If not, we exit now, losing the break.  FIXME
+	 */
+	if ((tty->flip.count + 1) >= TTY_FLIPBUF_SIZE)
+		return;
+	*(tty->flip.flag_buf_ptr++) = TTY_BREAK;
+	*(tty->flip.char_buf_ptr++) = 0;
+	tty->flip.count++;
+
+	queue_task(&tty->flip.tqueue, &tq_timer);
+}
+
+static _INLINE_ void transmit_chars(ser_info_t *info)
+{
+
+	if ((info->flags & TX_WAKEUP) ||
+	    (info->tty->flags & (1 << TTY_DO_WRITE_WAKEUP))) {
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+	}
+
+#ifdef SERIAL_DEBUG_INTR
+	printk("THRE...");
+#endif
+}
+
+#ifdef notdef
+	/* I need to do this for the SCCs, so it is left as a reminder.
+	*/
+static _INLINE_ void check_modem_status(struct async_struct *info)
+{
+	int	status;
+	/* struct	async_icount *icount; */
+	struct	async_icount_24 *icount;
+	
+	status = serial_in(info, UART_MSR);
+
+	if (status & UART_MSR_ANY_DELTA) {
+		icount = &info->state->icount;
+		/* update input line counters */
+		if (status & UART_MSR_TERI)
+			icount->rng++;
+		if (status & UART_MSR_DDSR)
+			icount->dsr++;
+		if (status & UART_MSR_DDCD) {
+			icount->dcd++;
+#ifdef CONFIG_HARD_PPS
+			if ((info->flags & ASYNC_HARDPPS_CD) &&
+			    (status & UART_MSR_DCD))
+				hardpps();
+#endif
+		}
+		if (status & UART_MSR_DCTS)
+			icount->cts++;
+		wake_up_interruptible(&info->delta_msr_wait);
+	}
+
+	if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
+#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
+		printk("ttys%d CD now %s...", info->line,
+		       (status & UART_MSR_DCD) ? "on" : "off");
+#endif		
+		if (status & UART_MSR_DCD)
+			wake_up_interruptible(&info->open_wait);
+		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+			   (info->flags & ASYNC_CALLOUT_NOHUP))) {
+#ifdef SERIAL_DEBUG_OPEN
+			printk("scheduling hangup...");
+#endif
+			queue_task(&info->tqueue_hangup,
+					   &tq_scheduler);
+		}
+	}
+	if (info->flags & ASYNC_CTS_FLOW) {
+		if (info->tty->hw_stopped) {
+			if (status & UART_MSR_CTS) {
+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
+				printk("CTS tx start...");
+#endif
+				info->tty->hw_stopped = 0;
+				info->IER |= UART_IER_THRI;
+				serial_out(info, UART_IER, info->IER);
+				rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+				return;
+			}
+		} else {
+			if (!(status & UART_MSR_CTS)) {
+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
+				printk("CTS tx stop...");
+#endif
+				info->tty->hw_stopped = 1;
+				info->IER &= ~UART_IER_THRI;
+				serial_out(info, UART_IER, info->IER);
+			}
+		}
+	}
+}
+#endif
+
+/*
+ * This is the serial driver's interrupt routine for a single port
+ */
+/* static void rs_360_interrupt(void *dev_id) */ /* until and if we start servicing irqs here */
+static void rs_360_interrupt(int vec, void *dev_id, struct pt_regs *fp)
+{
+	u_char	events;
+	int	idx;
+	ser_info_t *info;
+	volatile struct smc_regs *smcp;
+	volatile struct scc_regs *sccp;
+	
+	info = (ser_info_t *)dev_id;
+
+	idx = PORT_NUM(info->state->smc_scc_num);
+	if (info->state->smc_scc_num & NUM_IS_SCC) {
+		sccp = &pquicc->scc_regs[idx];
+		events = sccp->scc_scce;
+		if (events & SCCM_RX)
+			receive_chars(info);
+		if (events & SCCM_TX)
+			transmit_chars(info);
+		sccp->scc_scce = events;
+	} else {
+		smcp = &pquicc->smc_regs[idx];
+		events = smcp->smc_smce;
+		if (events & SMCM_BRKE)
+			receive_break(info);
+		if (events & SMCM_RX)
+			receive_chars(info);
+		if (events & SMCM_TX)
+			transmit_chars(info);
+		smcp->smc_smce = events;
+	}
+	
+#ifdef SERIAL_DEBUG_INTR
+	printk("rs_interrupt_single(%d, %x)...",
+					info->state->smc_scc_num, events);
+#endif
+#ifdef modem_control
+	check_modem_status(info);
+#endif
+	info->last_active = jiffies;
+#ifdef SERIAL_DEBUG_INTR
+	printk("end.\n");
+#endif
+}
+
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+}
+
+static void do_softint(void *private_)
+{
+	ser_info_t	*info = (ser_info_t *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+	}
+}
+
+
+
+
+/*
+ * This routine is called from the scheduler tqueue when the interrupt
+ * routine has signalled that a hangup has occurred.  The path of
+ * hangup processing is:
+ *
+ * 	serial interrupt routine -> (scheduler tqueue) ->
+ * 	do_serial_hangup() -> tty->hangup() -> rs_hangup()
+ * 
+ */
+static void do_serial_hangup(void *private_)
+{
+	struct async_struct	*info = (struct async_struct *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	tty_hangup(tty);
+}
+
+/*static void rs_360_timer(void)
+{
+	printk("rs_360_timer\n");
+}*/
+
+
+static int startup(ser_info_t *info)
+{
+	unsigned long flags;
+	int	retval=0;
+	int	idx;
+	/*struct serial_state *state = info->state;*/
+	volatile struct smc_regs *smcp;
+	volatile struct scc_regs *sccp;
+	volatile struct smc_uart_pram	*up;
+	volatile struct uart_pram	    *scup;
+
+
+	save_flags(flags); cli();
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		goto errout;
+	}
+
+#ifdef maybe
+	if (!state->port || !state->type) {
+		if (info->tty)
+			set_bit(TTY_IO_ERROR, &info->tty->flags);
+		goto errout;
+	}
+#endif
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttys%d (irq %d)...", info->line, state->irq);
+#endif
+
+
+#ifdef modem_control
+	info->MCR = 0;
+	if (info->tty->termios->c_cflag & CBAUD)
+		info->MCR = UART_MCR_DTR | UART_MCR_RTS;
+#endif
+	
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	/*
+	 * and set the speed of the serial port
+	 */
+	change_speed(info);
+
+	idx = PORT_NUM(info->state->smc_scc_num);
+	if (info->state->smc_scc_num & NUM_IS_SCC) {
+		sccp = &pquicc->scc_regs[idx];
+		scup = &pquicc->pram[info->state->port].scc.pscc.u;
+
+		scup->mrblr = RX_BUF_SIZE;
+		scup->max_idl = RX_BUF_SIZE;
+
+		sccp->scc_sccm |= (UART_SCCM_TX | UART_SCCM_RX);
+		sccp->scc_gsmr.w.low |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+	} else {
+		smcp = &pquicc->smc_regs[idx];
+
+		/* Enable interrupts and I/O.
+		*/
+		smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
+		smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN);
+
+		/* We can tune the buffer length and idle characters
+		 * to take advantage of the entire incoming buffer size.
+		 * If mrblr is something other than 1, maxidl has to be
+		 * non-zero or we never get an interrupt.  The maxidl
+		 * is the number of character times we wait after reception
+		 * of the last character before we decide no more characters
+		 * are coming.
+		 */
+		/* up = (smc_uart_t *)&pquicc->cp_dparam[state->port]; */
+		/* holy unionized structures, Batman: */
+		up = &pquicc->pram[info->state->port].scc.pothers.idma_smc.psmc.u;
+
+		up->mrblr = RX_BUF_SIZE;
+		up->max_idl = RX_BUF_SIZE;
+
+		up->brkcr = 1;	/* number of break chars */
+	}
+
+	info->flags |= ASYNC_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+	
+errout:
+	restore_flags(flags);
+	return retval;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(ser_info_t *info)
+{
+	unsigned long	flags;
+	struct serial_state *state;
+	int		idx;
+	volatile struct smc_regs	*smcp;
+	volatile struct scc_regs	*sccp;
+
+	if (!(info->flags & ASYNC_INITIALIZED))
+		return;
+
+	state = info->state;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Shutting down serial port %d (irq %d)....", info->line,
+	       state->irq);
+#endif
+	
+	save_flags(flags); cli(); /* Disable interrupts */
+
+	idx = PORT_NUM(state->smc_scc_num);
+	if (state->smc_scc_num & NUM_IS_SCC) {
+		sccp = &pquicc->scc_regs[idx];
+		sccp->scc_gsmr.w.low &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#ifdef CONFIG_SERIAL_CONSOLE
+		/* We can't disable the transmitter if this is the
+		 * system console.
+		 */
+		if ((state - rs_table) != CONFIG_SERIAL_CONSOLE_PORT)
+#endif
+		sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
+	} else {
+		smcp = &pquicc->smc_regs[idx];
+
+		/* Disable interrupts and I/O.
+		 */
+		smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
+#ifdef CONFIG_SERIAL_CONSOLE
+		/* We can't disable the transmitter if this is the
+		 * system console.
+		 */
+		if ((state - rs_table) != CONFIG_SERIAL_CONSOLE_PORT)
+#endif
+			smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+	}
+	
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~ASYNC_INITIALIZED;
+	restore_flags(flags);
+}
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void change_speed(ser_info_t *info)
+{
+	int	baud_rate;
+	unsigned cflag, cval, scval, prev_mode;
+	int	i, bits, sbits, idx;
+	unsigned long	flags;
+	struct serial_state *state;
+	volatile struct smc_regs	*smcp;
+	volatile struct scc_regs	*sccp;
+
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+
+	state = info->state;
+
+	/* Character length programmed into the mode register is the
+	 * sum of: 1 start bit, number of data bits, 0 or 1 parity bit,
+	 * 1 or 2 stop bits, minus 1.
+	 * The value 'bits' counts this for us.
+	 */
+	cval = 0;
+	scval = 0;
+
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	      case CS5: bits = 5; break;
+	      case CS6: bits = 6; break;
+	      case CS7: bits = 7; break;
+	      case CS8: bits = 8; break;
+	      /* Never happens, but GCC is too dumb to figure it out */
+	      default:  bits = 8; break;
+	}
+	sbits = bits - 5;
+
+	if (cflag & CSTOPB) {
+		cval |= SMCMR_SL;	/* Two stops */
+		scval |= SCU_PMSR_SL;
+		bits++;
+	}
+	if (cflag & PARENB) {
+		cval |= SMCMR_PEN;
+		scval |= SCU_PMSR_PEN;
+		bits++;
+	}
+	if (!(cflag & PARODD)) {
+		cval |= SMCMR_PM_EVEN;
+		scval |= (SCU_PMSR_REVP | SCU_PMSR_TEVP);
+	}
+
+	/* Determine divisor based on baud rate */
+	i = cflag & CBAUD;
+	if (i >= (sizeof(baud_table)/sizeof(int)))
+		baud_rate = 9600;
+	else
+		baud_rate = baud_table[i];
+
+	info->timeout = (TX_BUF_SIZE*HZ*bits);
+	info->timeout += HZ/50;		/* Add .02 seconds of slop */
+
+#ifdef modem_control
+	/* CTS flow control flag and modem status interrupts */
+	info->IER &= ~UART_IER_MSI;
+	if (info->flags & ASYNC_HARDPPS_CD)
+		info->IER |= UART_IER_MSI;
+	if (cflag & CRTSCTS) {
+		info->flags |= ASYNC_CTS_FLOW;
+		info->IER |= UART_IER_MSI;
+	} else
+		info->flags &= ~ASYNC_CTS_FLOW;
+	if (cflag & CLOCAL)
+		info->flags &= ~ASYNC_CHECK_CD;
+	else {
+		info->flags |= ASYNC_CHECK_CD;
+		info->IER |= UART_IER_MSI;
+	}
+	serial_out(info, UART_IER, info->IER);
+#endif
+
+	/*
+	 * Set up parity check flag
+	 */
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+	info->read_status_mask = (BD_SC_EMPTY | BD_SC_OV);
+	if (I_INPCK(info->tty))
+		info->read_status_mask |= BD_SC_FR | BD_SC_PR;
+	if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+		info->read_status_mask |= BD_SC_BR;
+	
+	/*
+	 * Characters to ignore
+	 */
+	info->ignore_status_mask = 0;
+	if (I_IGNPAR(info->tty))
+		info->ignore_status_mask |= BD_SC_PR | BD_SC_FR;
+	if (I_IGNBRK(info->tty)) {
+		info->ignore_status_mask |= BD_SC_BR;
+		/*
+		 * If we're ignore parity and break indicators, ignore 
+		 * overruns too.  (For real raw support).
+		 */
+		if (I_IGNPAR(info->tty))
+			info->ignore_status_mask |= BD_SC_OV;
+	}
+	/*
+	 * !!! ignore all characters if CREAD is not set
+	 */
+	if ((cflag & CREAD) == 0)
+	 info->read_status_mask &= ~BD_SC_EMPTY;
+	 save_flags(flags); cli();
+
+	 /* Start bit has not been added (so don't, because we would just
+	  * subtract it later), and we need to add one for the number of
+	  * stops bits (there is always at least one).
+	  */
+	 bits++;
+	 idx = PORT_NUM(state->smc_scc_num);
+	 if (state->smc_scc_num & NUM_IS_SCC) {
+         sccp = &pquicc->scc_regs[idx];
+         sccp->scc_psmr = (sbits << 12) | scval;
+     } else {
+         smcp = &pquicc->smc_regs[idx];
+
+		/* Set the mode register.  We want to keep a copy of the
+		 * enables, because we want to put them back if they were
+		 * present.
+		 */
+		prev_mode = smcp->smc_smcmr;
+		smcp->smc_smcmr = smcr_mk_clen(bits) | cval |  SMCMR_SM_UART;
+		smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN));
+	}
+
+	m360_cpm_setbrg((state - rs_table), baud_rate);
+
+	restore_flags(flags);
+}
+
+static void rs_360_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	ser_info_t *info = (ser_info_t *)tty->driver_data;
+	volatile QUICC_BD	*bdp;
+
+	if (serial_paranoia_check(info, tty->device, "rs_put_char"))
+		return;
+
+	if (!tty)
+		return;
+
+	bdp = info->tx_cur;
+	while (bdp->status & BD_SC_READY);
+
+	/* *((char *)__va(bdp->buf)) = ch; */
+	*((char *)bdp->buf) = ch;
+	bdp->length = 1;
+	bdp->status |= BD_SC_READY;
+
+	/* Get next BD.
+	*/
+	if (bdp->status & BD_SC_WRAP)
+		bdp = info->tx_bd_base;
+	else
+		bdp++;
+
+	info->tx_cur = (QUICC_BD *)bdp;
+
+}
+
+static int rs_360_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	int	c, ret = 0;
+	ser_info_t *info = (ser_info_t *)tty->driver_data;
+	volatile QUICC_BD *bdp;
+
+#ifdef CONFIG_KGDB
+	/* Try to let stub handle output. Returns true if it did. */ 
+	if (kgdb_output_string(buf, count))
+		return ret;
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_write"))
+		return 0;
+
+	if (!tty) 
+		return 0;
+
+	bdp = info->tx_cur;
+
+	while (1) {
+		c = MIN(count, TX_BUF_SIZE);
+
+		if (c <= 0)
+			break;
+
+		if (bdp->status & BD_SC_READY) {
+			info->flags |= TX_WAKEUP;
+			break;
+		}
+
+		if (from_user) {
+			if (copy_from_user((void *)bdp->buf, buf, c)) {
+				if (!ret)
+					ret = -EFAULT;
+				break;
+			}
+		} else {
+			/* memcpy(__va(bdp->buf), buf, c); */
+			memcpy((void *)bdp->buf, buf, c);
+		}
+
+		bdp->length = c;
+		bdp->status |= BD_SC_READY;
+
+		buf += c;
+		count -= c;
+		ret += c;
+
+		/* Get next BD.
+		*/
+		if (bdp->status & BD_SC_WRAP)
+			bdp = info->tx_bd_base;
+		else
+			bdp++;
+		info->tx_cur = (QUICC_BD *)bdp;
+	}
+	return ret;
+}
+
+static int rs_360_write_room(struct tty_struct *tty)
+{
+	ser_info_t *info = (ser_info_t *)tty->driver_data;
+	int	ret;
+
+	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
+		return 0;
+
+	if ((info->tx_cur->status & BD_SC_READY) == 0) {
+		info->flags &= ~TX_WAKEUP;
+		ret = TX_BUF_SIZE;
+	}
+	else {
+		info->flags |= TX_WAKEUP;
+		ret = 0;
+	}
+	return ret;
+}
+
+/* I could track this with transmit counters....maybe later.
+*/
+static int rs_360_chars_in_buffer(struct tty_struct *tty)
+{
+	ser_info_t *info = (ser_info_t *)tty->driver_data;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+		return 0;
+	return 0;
+}
+
+static void rs_360_flush_buffer(struct tty_struct *tty)
+{
+	ser_info_t *info = (ser_info_t *)tty->driver_data;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+		return;
+
+	/* There is nothing to "flush", whatever we gave the CPM
+	 * is on its way out.
+	 */
+	wake_up_interruptible(&tty->write_wait);
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+	info->flags &= ~TX_WAKEUP;
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void rs_360_send_xchar(struct tty_struct *tty, char ch)
+{
+	volatile QUICC_BD	*bdp;
+
+	ser_info_t *info = (ser_info_t *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_send_char"))
+		return;
+
+	bdp = info->tx_cur;
+	while (bdp->status & BD_SC_READY);
+
+	/* *((char *)__va(bdp->buf)) = ch; */
+	*((char *)bdp->buf) = ch;
+	bdp->length = 1;
+	bdp->status |= BD_SC_READY;
+
+	/* Get next BD.
+	*/
+	if (bdp->status & BD_SC_WRAP)
+		bdp = info->tx_bd_base;
+	else
+		bdp++;
+
+	info->tx_cur = (QUICC_BD *)bdp;
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_360_throttle(struct tty_struct * tty)
+{
+	ser_info_t *info = (ser_info_t *)tty->driver_data;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("throttle %s: %d....\n", _tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+		return;
+	
+	if (I_IXOFF(tty))
+		rs_360_send_xchar(tty, STOP_CHAR(tty));
+
+#ifdef modem_control
+	if (tty->termios->c_cflag & CRTSCTS)
+		info->MCR &= ~UART_MCR_RTS;
+
+	cli();
+	serial_out(info, UART_MCR, info->MCR);
+	sti();
+#endif
+}
+
+static void rs_360_unthrottle(struct tty_struct * tty)
+{
+	ser_info_t *info = (ser_info_t *)tty->driver_data;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("unthrottle %s: %d....\n", _tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+		return;
+	
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			rs_360_send_xchar(tty, START_CHAR(tty));
+	}
+#ifdef modem_control
+	if (tty->termios->c_cflag & CRTSCTS)
+		info->MCR |= UART_MCR_RTS;
+	cli();
+	serial_out(info, UART_MCR, info->MCR);
+	sti();
+#endif
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+#ifdef maybe
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space. 
+ */
+static int get_lsr_info(struct async_struct * info, unsigned int *value)
+{
+	unsigned char status;
+	unsigned int result;
+
+	cli();
+	status = serial_in(info, UART_LSR);
+	sti();
+	result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
+	return put_user(result,value);
+}
+#endif
+
+static int get_modem_info(ser_info_t *info, unsigned int *value)
+{
+	unsigned int result = 0;
+#ifdef modem_control
+	unsigned char control, status;
+
+	control = info->MCR;
+	cli();
+	status = serial_in(info, UART_MSR);
+	sti();
+	result =  ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
+		| ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
+#ifdef TIOCM_OUT1
+		| ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0)
+		| ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0)
+#endif
+		| ((status  & UART_MSR_DCD) ? TIOCM_CAR : 0)
+		| ((status  & UART_MSR_RI) ? TIOCM_RNG : 0)
+		| ((status  & UART_MSR_DSR) ? TIOCM_DSR : 0)
+		| ((status  & UART_MSR_CTS) ? TIOCM_CTS : 0);
+#endif
+	/* return put_user(result,value); */
+	put_user(result,value);
+	return (0);
+}
+
+static int set_modem_info(ser_info_t *info, unsigned int cmd,
+			  unsigned int *value)
+{
+	int error;
+ 	unsigned int arg; 
+
+	error = get_user(arg,value);
+	if (error)
+		return error;
+#ifdef modem_control
+	switch (cmd) {
+	case TIOCMBIS: 
+		if (arg & TIOCM_RTS)
+			info->MCR |= UART_MCR_RTS;
+		if (arg & TIOCM_DTR)
+			info->MCR |= UART_MCR_DTR;
+#ifdef TIOCM_OUT1
+		if (arg & TIOCM_OUT1)
+			info->MCR |= UART_MCR_OUT1;
+		if (arg & TIOCM_OUT2)
+			info->MCR |= UART_MCR_OUT2;
+#endif
+		break;
+	case TIOCMBIC:
+		if (arg & TIOCM_RTS)
+			info->MCR &= ~UART_MCR_RTS;
+		if (arg & TIOCM_DTR)
+			info->MCR &= ~UART_MCR_DTR;
+#ifdef TIOCM_OUT1
+		if (arg & TIOCM_OUT1)
+			info->MCR &= ~UART_MCR_OUT1;
+		if (arg & TIOCM_OUT2)
+			info->MCR &= ~UART_MCR_OUT2;
+#endif
+		break;
+	case TIOCMSET:
+		info->MCR = ((info->MCR & ~(UART_MCR_RTS |
+#ifdef TIOCM_OUT1
+					    UART_MCR_OUT1 |
+					    UART_MCR_OUT2 |
+#endif
+					    UART_MCR_DTR))
+			     | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
+#ifdef TIOCM_OUT1
+			     | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0)
+			     | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0)
+#endif
+			     | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0));
+		break;
+	default:
+		return -EINVAL;
+	}
+	cli();
+	serial_out(info, UART_MCR, info->MCR);
+	sti();
+#endif
+	return 0;
+}
+
+/* Sending a break is a two step process on the SMC/SCC.  It is accomplished
+ * by sending a STOP TRANSMIT command followed by a RESTART TRANSMIT
+ * command.  We take advantage of the begin/end functions to make this
+ * happen.
+ */
+static ushort	smc_chan_map[] = {
+	CPM_CR_CH_SMC1,
+	CPM_CR_CH_SMC2
+};
+
+static ushort	scc_chan_map[] = {
+	CPM_CR_CH_SCC1,
+	CPM_CR_CH_SCC2,
+	CPM_CR_CH_SCC3,
+	CPM_CR_CH_SCC4
+};
+
+static void begin_break(ser_info_t *info)
+{
+	volatile QUICC *cp;
+	ushort	chan;
+	int     idx;
+
+	cp = pquicc;
+
+	idx = PORT_NUM(info->state->smc_scc_num);
+	if (info->state->smc_scc_num & NUM_IS_SCC)
+		chan = scc_chan_map[idx];
+	else
+		chan = smc_chan_map[idx];
+
+	cp->cp_cr = mk_cr_cmd(chan, CPM_CR_STOP_TX) | CPM_CR_FLG;
+	while (cp->cp_cr & CPM_CR_FLG);
+}
+
+static void end_break(ser_info_t *info)
+{
+	volatile QUICC *cp;
+	ushort	chan;
+	int idx;
+
+	cp = pquicc;
+
+	idx = PORT_NUM(info->state->smc_scc_num);
+	if (info->state->smc_scc_num & NUM_IS_SCC)
+		chan = scc_chan_map[idx];
+	else
+		chan = smc_chan_map[idx];
+
+	cp->cp_cr = mk_cr_cmd(chan, CPM_CR_RESTART_TX) | CPM_CR_FLG;
+	while (cp->cp_cr & CPM_CR_FLG);
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void send_break(ser_info_t *info, int duration)
+{
+	current->state = TASK_INTERRUPTIBLE;
+#ifdef SERIAL_DEBUG_SEND_BREAK
+	printk("rs_send_break(%d) jiff=%lu...", duration, jiffies);
+#endif
+	begin_break(info);
+	schedule_timeout(duration);
+	end_break(info);
+#ifdef SERIAL_DEBUG_SEND_BREAK
+	printk("done jiffies=%lu\n", jiffies);
+#endif
+}
+
+
+static int rs_360_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	int error;
+	ser_info_t *info = (ser_info_t *)tty->driver_data;
+	int retval;
+	struct async_icount cnow; 
+	/* struct async_icount_24 cnow;*/ 	/* kernel counter temps */
+	struct serial_icounter_struct *p_cuser;	/* user space */
+
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+	
+	switch (cmd) {
+		case TCSBRK:	/* SVID version: non-zero arg --> no break */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (signal_pending(current))
+				return -EINTR;
+			if (!arg) {
+				send_break(info, HZ/4);	/* 1/4 second */
+				if (signal_pending(current))
+					return -EINTR;
+			}
+			return 0;
+		case TCSBRKP:	/* support for POSIX tcsendbreak() */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (signal_pending(current))
+				return -EINTR;
+			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+			if (signal_pending(current))
+				return -EINTR;
+			return 0;
+		case TIOCSBRK:
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			begin_break(info);
+			return 0;
+		case TIOCCBRK:
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			end_break(info);
+			return 0;
+		case TIOCGSOFTCAR:
+			/* return put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg); */
+			put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg);
+			return 0;
+		case TIOCSSOFTCAR:
+			error = get_user(arg, (unsigned int *) arg); 
+			if (error)
+				return error;
+			tty->termios->c_cflag =
+				((tty->termios->c_cflag & ~CLOCAL) |
+				 (arg ? CLOCAL : 0));
+			return 0;
+		case TIOCMGET:
+			return get_modem_info(info, (unsigned int *) arg);
+		case TIOCMBIS:
+		case TIOCMBIC:
+		case TIOCMSET:
+			return set_modem_info(info, cmd, (unsigned int *) arg);
+#ifdef maybe
+		case TIOCSERGETLSR: /* Get line status register */
+			return get_lsr_info(info, (unsigned int *) arg);
+#endif
+		/*
+		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+		 * - mask passed in arg for lines of interest
+ 		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+		 * Caller should use TIOCGICOUNT to see which one it was
+		 */
+		 case TIOCMIWAIT:
+#ifdef modem_control
+			cli();
+			/* note the counters on entry */
+			cprev = info->state->icount;
+			sti();
+			while (1) {
+				interruptible_sleep_on(&info->delta_msr_wait);
+				/* see if a signal did it */
+				if (signal_pending(current))
+					return -ERESTARTSYS;
+				cli();
+				cnow = info->state->icount; /* atomic copy */
+				sti();
+				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
+				    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+					return -EIO; /* no change => error */
+				if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+				     ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+				     ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
+				     ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
+					return 0;
+				}
+				cprev = cnow;
+			}
+			/* NOTREACHED */
+#else
+			return 0;
+#endif
+
+		/* 
+		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+		 * Return: write counters to the user passed counter struct
+		 * NB: both 1->0 and 0->1 transitions are counted except for
+		 *     RI where only 0->1 is counted.
+		 */
+		case TIOCGICOUNT:
+			cli();
+			cnow = info->state->icount;
+			sti();
+			p_cuser = (struct serial_icounter_struct *) arg;
+/* 			error = put_user(cnow.cts, &p_cuser->cts); */
+/* 			if (error) return error; */
+/* 			error = put_user(cnow.dsr, &p_cuser->dsr); */
+/* 			if (error) return error; */
+/* 			error = put_user(cnow.rng, &p_cuser->rng); */
+/* 			if (error) return error; */
+/* 			error = put_user(cnow.dcd, &p_cuser->dcd); */
+/* 			if (error) return error; */
+
+			put_user(cnow.cts, &p_cuser->cts);
+			put_user(cnow.dsr, &p_cuser->dsr);
+			put_user(cnow.rng, &p_cuser->rng);
+			put_user(cnow.dcd, &p_cuser->dcd);
+			return 0;
+
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+/* FIX UP modem control here someday......
+*/
+static void rs_360_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	ser_info_t *info = (ser_info_t *)tty->driver_data;
+
+	if (   (tty->termios->c_cflag == old_termios->c_cflag)
+	    && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
+		== RELEVANT_IFLAG(old_termios->c_iflag)))
+	  return;
+
+	change_speed(info);
+
+#ifdef modem_control
+	/* Handle transition to B0 status */
+	if ((old_termios->c_cflag & CBAUD) &&
+	    !(tty->termios->c_cflag & CBAUD)) {
+		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
+		cli();
+		serial_out(info, UART_MCR, info->MCR);
+		sti();
+	}
+	
+	/* Handle transition away from B0 status */
+	if (!(old_termios->c_cflag & CBAUD) &&
+	    (tty->termios->c_cflag & CBAUD)) {
+		info->MCR |= UART_MCR_DTR;
+		if (!tty->hw_stopped ||
+		    !(tty->termios->c_cflag & CRTSCTS)) {
+			info->MCR |= UART_MCR_RTS;
+		}
+		cli();
+		serial_out(info, UART_MCR, info->MCR);
+		sti();
+	}
+	
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_360_start(tty);
+	}
+#endif
+
+#if 0
+	/*
+	 * No need to wake up processes in open wait, since they
+	 * sample the CLOCAL flag once, and don't recheck it.
+	 * XXX  It's not clear whether the current behavior is correct
+	 * or not.  Hence, this may change.....
+	 */
+	if (!(old_termios->c_cflag & CLOCAL) &&
+	    (tty->termios->c_cflag & CLOCAL))
+		wake_up_interruptible(&info->open_wait);
+#endif
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_360_close(struct tty_struct *tty, struct file * filp)
+{
+	ser_info_t *info = (ser_info_t *)tty->driver_data;
+	/* struct async_state *state; */
+	struct serial_state *state;
+	unsigned long	flags;
+	int		idx;
+	volatile struct smc_regs	*smcp;
+	volatile struct scc_regs	*sccp;
+
+	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+		return;
+
+	state = info->state;
+	
+	save_flags(flags); cli();
+	
+	if (tty_hung_up_p(filp)) {
+		DBG_CNT("before DEC-hung");
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+	
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
+#endif
+	if ((tty->count == 1) && (state->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  state->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+		       "state->count is %d\n", state->count);
+		state->count = 1;
+	}
+	if (--state->count < 0) {
+		printk("rs_close: bad serial port count for ttys%d: %d\n",
+		       info->line, state->count);
+		state->count = 0;
+	}
+	if (state->count) {
+		DBG_CNT("before DEC-2");
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= ASYNC_CLOSING;
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & ASYNC_NORMAL_ACTIVE)
+		info->state->normal_termios = *tty->termios;
+	if (info->flags & ASYNC_CALLOUT_ACTIVE)
+		info->state->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+	info->read_status_mask &= ~BD_SC_EMPTY;
+	if (info->flags & ASYNC_INITIALIZED) {
+
+		idx = PORT_NUM(info->state->smc_scc_num);
+		if (info->state->smc_scc_num & NUM_IS_SCC) {
+			sccp = &pquicc->scc_regs[idx];
+			sccp->scc_sccm &= ~UART_SCCM_RX;
+			sccp->scc_gsmr.w.low &= ~SCC_GSMRL_ENR;
+		} else {
+			smcp = &pquicc->smc_regs[idx];
+			smcp->smc_smcm &= ~SMCM_RX;
+			smcp->smc_smcmr &= ~SMCMR_REN;
+		}
+		/*
+		 * Before we drop DTR, make sure the UART transmitter
+		 * has completely drained; this is especially
+		 * important if there is a transmit FIFO!
+		 */
+		rs_360_wait_until_sent(tty, info->timeout);
+	}
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
+			 ASYNC_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	MOD_DEC_USE_COUNT;
+	restore_flags(flags);
+}
+
+/*
+ * rs_wait_until_sent() --- wait until the transmitter is empty
+ */
+static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	ser_info_t *info = (ser_info_t *)tty->driver_data;
+	unsigned long orig_jiffies, char_time;
+	/*int lsr;*/
+	volatile QUICC_BD *bdp;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent"))
+		return;
+
+#ifdef maybe
+	if (info->state->type == PORT_UNKNOWN)
+		return;
+#endif
+
+	orig_jiffies = jiffies;
+	/*
+	 * Set the check interval to be 1/5 of the estimated time to
+	 * send a single character, and make it at least 1.  The check
+	 * interval should also be less than the timeout.
+	 * 
+	 * Note: we have to use pretty tight timings here to satisfy
+	 * the NIST-PCTS.
+	 */
+	char_time = 1;
+	if (timeout)
+		char_time = MIN(char_time, timeout);
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
+	printk("jiff=%lu...", jiffies);
+#endif
+
+	/* We go through the loop at least once because we can't tell
+	 * exactly when the last character exits the shifter.  There can
+	 * be at least two characters waiting to be sent after the buffers
+	 * are empty.
+	 */
+	do {
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+		printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
+#endif
+		current->state = TASK_INTERRUPTIBLE;
+/*		current->counter = 0;	 make us low-priority */
+		schedule_timeout(char_time);
+		if (signal_pending(current))
+			break;
+		if (timeout && ((orig_jiffies + timeout) < jiffies))
+			break;
+		/* The 'tx_cur' is really the next buffer to send.  We
+		 * have to back up to the previous BD and wait for it
+		 * to go.  This isn't perfect, because all this indicates
+		 * is the buffer is available.  There are still characters
+		 * in the CPM FIFO.
+		 */
+		bdp = info->tx_cur;
+		if (bdp == info->tx_bd_base)
+			bdp += (TX_NUM_FIFO-1);
+		else
+			bdp--;
+	} while (bdp->status & BD_SC_READY);
+	current->state = TASK_RUNNING;
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
+#endif
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void rs_360_hangup(struct tty_struct *tty)
+{
+	ser_info_t *info = (ser_info_t *)tty->driver_data;
+	struct serial_state *state = info->state;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
+		return;
+
+	state = info->state;
+	
+	rs_360_flush_buffer(tty);
+	shutdown(info);
+	info->event = 0;
+	state->count = 0;
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file * filp,
+			   ser_info_t *info)
+{
+#ifdef DO_THIS_LATER
+	DECLARE_WAITQUEUE(wait, current);
+#endif
+	struct serial_state *state = info->state;
+	int		retval;
+	int		do_clocal = 0;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		if (info->flags & ASYNC_HUP_NOTIFY)
+			return -EAGAIN;
+		else
+			return -ERESTARTSYS;
+#else
+		return -EAGAIN;
+#endif
+	}
+
+
+#if 0 /* FIXME */
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & ASYNC_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+		    return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+		    return -EBUSY;
+		info->flags |= ASYNC_CALLOUT_ACTIVE;
+		return 0;
+	}
+#endif	
+
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 * If this is an SMC port, we don't have modem control to wait
+	 * for, so just get out here.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR)) ||
+	    !(info->state->smc_scc_num & NUM_IS_SCC)) {
+		if (info->flags & ASYNC_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= ASYNC_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
+		if (state->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+	
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, state->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+#ifdef DO_THIS_LATER
+	add_wait_queue(&info->open_wait, &wait);
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready before block: ttys%d, count = %d\n",
+	       state->line, state->count);
+#endif
+	cli();
+	if (!tty_hung_up_p(filp)) 
+		state->count--;
+	sti();
+	info->blocked_open++;
+	while (1) {
+		cli();
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (tty->termios->c_cflag & CBAUD))
+			serial_out(info, UART_MCR,
+				   serial_inp(info, UART_MCR) |
+				   (UART_MCR_DTR | UART_MCR_RTS));
+		sti();
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (tty_hung_up_p(filp) ||
+		    !(info->flags & ASYNC_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & ASYNC_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;	
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    !(info->flags & ASYNC_CLOSING) &&
+		    (do_clocal || (serial_in(info, UART_MSR) &
+				   UART_MSR_DCD)))
+			break;
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef SERIAL_DEBUG_OPEN
+		printk("block_til_ready blocking: ttys%d, count = %d\n",
+		       info->line, state->count);
+#endif
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&info->open_wait, &wait);
+	if (!tty_hung_up_p(filp))
+		state->count++;
+	info->blocked_open--;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready after blocking: ttys%d, count = %d\n",
+	       info->line, state->count);
+#endif
+#endif /* DO_THIS_LATER */
+	if (retval)
+		return retval;
+	info->flags |= ASYNC_NORMAL_ACTIVE;
+	return 0;
+}
+
+static int get_async_struct(int line, ser_info_t **ret_info)
+{
+	struct serial_state *sstate;
+
+	sstate = rs_table + line;
+	if (sstate->info) {
+		sstate->count++;
+		*ret_info = (ser_info_t *)sstate->info;
+		return 0;
+	}
+	else {
+		return -ENOMEM;
+	}
+}
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+static int rs_360_open(struct tty_struct *tty, struct file * filp)
+{
+	ser_info_t	*info;
+	int 		retval, line;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	if ((line < 0) || (line >= NR_PORTS))
+		return -ENODEV;
+	retval = get_async_struct(line, &info);
+	if (retval)
+		return retval;
+	if (serial_paranoia_check(info, tty->device, "rs_open"))
+		return -ENODEV;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+	       info->state->count);
+#endif
+	tty->driver_data = info;
+	info->tty = tty;
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval)
+		return retval;
+
+	MOD_INC_USE_COUNT;
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("rs_open returning after block_til_ready with %d\n",
+		       retval);
+#endif
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+
+	if ((info->state->count == 1) &&
+	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->state->normal_termios;
+		else 
+			*tty->termios = info->state->callout_termios;
+		change_speed(info);
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open ttys%d successful...", info->line);
+#endif
+	return 0;
+}
+
+/*
+ * /proc fs routines....
+ */
+
+static int inline line_info(char *buf, struct serial_state *state)
+{
+#ifdef notdef
+	struct async_struct *info = state->info, scr_info;
+	char	stat_buf[30], control, status;
+#endif
+	int	ret;
+
+	ret = sprintf(buf, "%d: uart:%s port:%X irq:%d",
+		      state->line,
+		      (state->smc_scc_num & NUM_IS_SCC) ? "SCC" : "SMC",
+		      (unsigned int)(state->port), state->irq);
+
+	if (!state->port || (state->type == PORT_UNKNOWN)) {
+		ret += sprintf(buf+ret, "\n");
+		return ret;
+	}
+
+#ifdef notdef
+	/*
+	 * Figure out the current RS-232 lines
+	 */
+	if (!info) {
+		info = &scr_info;	/* This is just for serial_{in,out} */
+
+		info->magic = SERIAL_MAGIC;
+		info->port = state->port;
+		info->flags = state->flags;
+		info->quot = 0;
+		info->tty = 0;
+	}
+	cli();
+	status = serial_in(info, UART_MSR);
+	control = info ? info->MCR : serial_in(info, UART_MCR);
+	sti();
+	
+	stat_buf[0] = 0;
+	stat_buf[1] = 0;
+	if (control & UART_MCR_RTS)
+		strcat(stat_buf, "|RTS");
+	if (status & UART_MSR_CTS)
+		strcat(stat_buf, "|CTS");
+	if (control & UART_MCR_DTR)
+		strcat(stat_buf, "|DTR");
+	if (status & UART_MSR_DSR)
+		strcat(stat_buf, "|DSR");
+	if (status & UART_MSR_DCD)
+		strcat(stat_buf, "|CD");
+	if (status & UART_MSR_RI)
+		strcat(stat_buf, "|RI");
+
+	if (info->quot) {
+		ret += sprintf(buf+ret, " baud:%d",
+			       state->baud_base / info->quot);
+	}
+
+	ret += sprintf(buf+ret, " tx:%d rx:%d",
+		      state->icount.tx, state->icount.rx);
+
+	if (state->icount.frame)
+		ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
+	
+	if (state->icount.parity)
+		ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
+	
+	if (state->icount.brk)
+		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);	
+
+	if (state->icount.overrun)
+		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
+
+	/*
+	 * Last thing is the RS-232 status lines
+	 */
+	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+#endif
+	return ret;
+}
+
+int rs_360_read_proc(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	int i, len = 0;
+	off_t	begin = 0;
+
+	len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
+	for (i = 0; i < NR_PORTS && len < 4000; i++) {
+		len += line_info(page + len, &rs_table[i]);
+		if (len+begin > off+count)
+			goto done;
+		if (len+begin < off) {
+			begin += len;
+			len = 0;
+		}
+	}
+	*eof = 1;
+done:
+	if (off >= len+begin)
+		return 0;
+	*start = page + (begin-off);
+	return ((count < begin+len-off) ? count : begin+len-off);
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * rs_init() and friends
+ *
+ * rs_init() is called at boot-time to initialize the serial driver.
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * This routine prints out the appropriate serial driver version
+ * number, and identifies which options were configured into this
+ * driver.
+ */
+static _INLINE_ void show_serial_version(void)
+{
+ 	printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
+}
+
+
+/*
+ * The serial console driver used during boot.  Note that these names
+ * clash with those found in "serial.c", so we currently can't support
+ * the 16xxx uarts and these at the same time.  I will fix this to become
+ * an indirect function call from tty_io.c (or something).
+ */
+
+#ifdef CONFIG_SERIAL_CONSOLE
+
+/*
+ * Print a string to the serial port trying not to disturb any possible
+ * real use of the port...
+ */
+static void my_console_write(int idx, const char *s,
+				unsigned count)
+{
+	struct		serial_state	*ser;
+	ser_info_t		*info;
+	unsigned		i;
+	QUICC_BD		*bdp, *bdbase;
+	volatile struct smc_uart_pram	*up;
+	volatile	u_char		*cp;
+
+	ser = rs_table + idx;
+
+
+	/* If the port has been initialized for general use, we have
+	 * to use the buffer descriptors allocated there.  Otherwise,
+	 * we simply use the single buffer allocated.
+	 */
+	if ((info = (ser_info_t *)ser->info) != NULL) {
+		bdp = info->tx_cur;
+		bdbase = info->tx_bd_base;
+	}
+	else {
+		/* Pointer to UART in parameter ram.
+		*/
+		/* up = (smc_uart_t *)&cpmp->cp_dparam[ser->port]; */
+		up = &pquicc->pram[ser->port].scc.pothers.idma_smc.psmc.u;
+
+		/* Get the address of the host memory buffer.
+		 */
+		bdp = bdbase = (QUICC_BD *)((uint)pquicc + (uint)up->tbase);
+	}
+
+	/*
+	 * We need to gracefully shut down the transmitter, disable
+	 * interrupts, then send our bytes out.
+	 */
+
+	/*
+	 * Now, do each character.  This is not as bad as it looks
+	 * since this is a holding FIFO and not a transmitting FIFO.
+	 * We could add the complexity of filling the entire transmit
+	 * buffer, but we would just wait longer between accesses......
+	 */
+	for (i = 0; i < count; i++, s++) {
+		/* Wait for transmitter fifo to empty.
+		 * Ready indicates output is ready, and xmt is doing
+		 * that, not that it is ready for us to send.
+		 */
+		while (bdp->status & BD_SC_READY);
+
+		/* Send the character out.
+		 */
+		cp = bdp->buf;
+		*cp = *s;
+		
+		bdp->length = 1;
+		bdp->status |= BD_SC_READY;
+
+		if (bdp->status & BD_SC_WRAP)
+			bdp = bdbase;
+		else
+			bdp++;
+
+		/* if a LF, also do CR... */
+		if (*s == 10) {
+			while (bdp->status & BD_SC_READY);
+			/* cp = __va(bdp->buf); */
+			cp = bdp->buf;
+			*cp = 13;
+			bdp->length = 1;
+			bdp->status |= BD_SC_READY;
+
+			if (bdp->status & BD_SC_WRAP) {
+				bdp = bdbase;
+			}
+			else {
+				bdp++;
+			}
+		}
+	}
+
+	/*
+	 * Finally, Wait for transmitter & holding register to empty
+	 *  and restore the IER
+	 */
+	while (bdp->status & BD_SC_READY);
+
+	if (info)
+		info->tx_cur = (QUICC_BD *)bdp;
+}
+
+static void serial_console_write(struct console *c, const char *s,
+				unsigned count)
+{
+#ifdef CONFIG_KGDB
+	/* Try to let stub handle output. Returns true if it did. */ 
+	if (kgdb_output_string(s, count))
+		return;
+#endif
+	my_console_write(c->index, s, count);
+}
+
+
+
+/*void console_print_68360(const char *p)
+{
+	const char *cp = p;
+	int i;
+
+	for (i=0;cp[i]!=0;i++);
+
+	serial_console_write (p, i);
+
+	//Comment this if you want to have a strict interrupt-driven output
+	//rs_fair_output();
+
+	return;
+}*/
+
+
+
+
+
+
+#ifdef CONFIG_XMON
+int
+xmon_360_write(const char *s, unsigned count)
+{
+	my_console_write(0, s, count);
+	return(count);
+}
+#endif
+
+#ifdef CONFIG_KGDB
+void
+putDebugChar(char ch)
+{
+	my_console_write(0, &ch, 1);
+}
+#endif
+
+/*
+ * Receive character from the serial port.  This only works well
+ * before the port is initialized for real use.
+ */
+static int my_console_wait_key(int idx, int xmon, char *obuf)
+{
+	struct serial_state		*ser;
+	u_char			c, *cp;
+	ser_info_t		*info;
+	QUICC_BD		*bdp;
+	volatile struct smc_uart_pram	*up;
+	int				i;
+
+	ser = rs_table + idx;
+
+	/* Get the address of the host memory buffer.
+	 * If the port has been initialized for general use, we must
+	 * use information from the port structure.
+	 */
+	if ((info = (ser_info_t *)ser->info))
+		bdp = info->rx_cur;
+	else
+		/* bdp = (QUICC_BD *)&cpmp->cp_dpmem[up->smc_rbase]; */
+		bdp = (QUICC_BD *)((uint)pquicc + (uint)up->tbase);
+
+	/* Pointer to UART in parameter ram.
+	 */
+	/* up = (smc_uart_t *)&cpmp->cp_dparam[ser->port]; */
+	up = &pquicc->pram[info->state->port].scc.pothers.idma_smc.psmc.u;
+
+	/*
+	 * We need to gracefully shut down the receiver, disable
+	 * interrupts, then read the input.
+	 * XMON just wants a poll.  If no character, return -1, else
+	 * return the character.
+	 */
+	if (!xmon) {
+		while (bdp->status & BD_SC_EMPTY);
+	}
+	else {
+		if (bdp->status & BD_SC_EMPTY)
+			return -1;
+	}
+
+	cp = (char *)bdp->buf;
+
+	if (obuf) {
+		i = c = bdp->length;
+		while (i-- > 0)
+			*obuf++ = *cp++;
+	}
+	else {
+		c = *cp;
+	}
+	bdp->status |= BD_SC_EMPTY;
+
+	if (info) {
+		if (bdp->status & BD_SC_WRAP) {
+			bdp = info->rx_bd_base;
+		}
+		else {
+			bdp++;
+		}
+		info->rx_cur = (QUICC_BD *)bdp;
+	}
+
+	return((int)c);
+}
+
+#ifdef CONFIG_XMON
+int
+xmon_360_read_poll(void)
+{
+	return(my_console_wait_key(0, 1, NULL));
+}
+
+int
+xmon_360_read_char(void)
+{
+	return(my_console_wait_key(0, 0, NULL));
+}
+#endif
+
+#ifdef CONFIG_KGDB
+static char kgdb_buf[RX_BUF_SIZE], *kgdp;
+static int kgdb_chars;
+
+unsigned char
+getDebugChar(void)
+{
+	if (kgdb_chars <= 0) {
+		kgdb_chars = my_console_wait_key(0, 0, kgdb_buf);
+		kgdp = kgdb_buf;
+	}
+	kgdb_chars--;
+
+	return(*kgdp++);
+}
+
+void kgdb_interruptible(int state)
+{
+}
+void kgdb_map_scc(void)
+{
+	struct		serial_state *ser;
+	uint		mem_addr;
+	volatile	QUICC_BD		*bdp;
+	volatile	smc_uart_t	*up;
+
+	cpmp = (cpm360_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
+
+	/* To avoid data cache CPM DMA coherency problems, allocate a
+	 * buffer in the CPM DPRAM.  This will work until the CPM and
+	 * serial ports are initialized.  At that time a memory buffer
+	 * will be allocated.
+	 * The port is already initialized from the boot procedure, all
+	 * we do here is give it a different buffer and make it a FIFO.
+	 */
+
+	ser = rs_table;
+
+	/* Right now, assume we are using SMCs.
+	*/
+	up = (smc_uart_t *)&cpmp->cp_dparam[ser->port];
+
+	/* Allocate space for an input FIFO, plus a few bytes for output.
+	 * Allocate bytes to maintain word alignment.
+	 */
+	mem_addr = (uint)(&cpmp->cp_dpmem[0x1000]);
+
+	/* Set the physical address of the host memory buffers in
+	 * the buffer descriptors.
+	 */
+	bdp = (QUICC_BD *)&cpmp->cp_dpmem[up->smc_rbase];
+	bdp->buf = mem_addr;
+
+	bdp = (QUICC_BD *)&cpmp->cp_dpmem[up->smc_tbase];
+	bdp->buf = mem_addr+RX_BUF_SIZE;
+
+	up->smc_mrblr = RX_BUF_SIZE;		/* receive buffer length */
+	up->smc_maxidl = RX_BUF_SIZE;
+}
+#endif
+
+static kdev_t serial_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+
+struct console sercons = {
+ 	name:		"ttyS",
+ 	write:		serial_console_write,
+ 	device:		serial_console_device,
+ 	setup:		serial_console_setup,
+ 	flags:		CON_PRINTBUFFER,
+ 	index:		CONFIG_SERIAL_CONSOLE_PORT, 
+};
+
+
+
+/*
+ *	Register console.
+ */
+long console_360_init(long kmem_start, long kmem_end)
+{
+	register_console(&sercons);
+	/*register_console (console_print_68360); - 2.0.38 only required a write
+      function pointer. */
+	return kmem_start;
+}
+
+#endif
+
+/* Index in baud rate table of the default console baud rate.
+*/
+static	int	baud_idx;
+
+
+/* int __init rs_360_init(void) */
+int rs_360_init(void)
+{
+	struct serial_state * state;
+	ser_info_t	*info;
+	void       *mem_addr;
+	uint 		dp_addr, iobits;
+	int		    i, j, idx;
+	ushort		chan;
+	QUICC_BD	*bdp;
+	volatile	QUICC		*cp;
+	volatile	struct smc_regs	*sp;
+	volatile	struct smc_uart_pram	*up;
+	volatile	struct scc_regs	*scp;
+	volatile	struct uart_pram	*sup;
+	/* volatile	immap_t		*immap; */
+	
+	init_bh(SERIAL_BH, do_serial_bh);
+
+	show_serial_version();
+
+	/* Initialize the tty_driver structure */
+	
+	/* __clear_user(&serial_driver,sizeof(struct tty_driver)); */
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+	/* serial_driver.driver_name = "serial"; */
+	serial_driver.name = "ttyS";
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64;
+	serial_driver.num = NR_PORTS;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+	serial_driver.init_termios.c_cflag =
+		baud_idx | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = rs_360_open;
+	serial_driver.close = rs_360_close;
+	serial_driver.write = rs_360_write;
+	serial_driver.put_char = rs_360_put_char;
+	serial_driver.write_room = rs_360_write_room;
+	serial_driver.chars_in_buffer = rs_360_chars_in_buffer;
+	serial_driver.flush_buffer = rs_360_flush_buffer;
+	serial_driver.ioctl = rs_360_ioctl;
+	serial_driver.throttle = rs_360_throttle;
+	serial_driver.unthrottle = rs_360_unthrottle;
+	/* serial_driver.send_xchar = rs_360_send_xchar; */
+	serial_driver.set_termios = rs_360_set_termios;
+	serial_driver.stop = rs_360_stop;
+	serial_driver.start = rs_360_start;
+	serial_driver.hangup = rs_360_hangup;
+	/* serial_driver.wait_until_sent = rs_360_wait_until_sent; */
+	/* serial_driver.read_proc = rs_360_read_proc; */
+	
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+	callout_driver.name = "cua";
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+	/* callout_driver.read_proc = 0; */
+	/* callout_driver.proc_entry = 0; */
+
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register serial driver\n");
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+	
+	cp = pquicc;	/* Get pointer to Communication Processor */
+	/* immap = (immap_t *)IMAP_ADDR; */	/* and to internal registers */
+
+
+	/* Configure SCC2, SCC3, and SCC4 instead of port A parallel I/O.
+	 */
+	/* The "standard" configuration through the 860.
+	*/
+/* 	immap->im_ioport.iop_papar |= 0x00fc; */
+/* 	immap->im_ioport.iop_padir &= ~0x00fc; */
+/* 	immap->im_ioport.iop_paodr &= ~0x00fc; */
+	cp->pio_papar |= 0x00fc;
+	cp->pio_padir &= ~0x00fc;
+	/* cp->pio_paodr &= ~0x00fc; */
+
+
+	/* Since we don't yet do modem control, connect the port C pins
+	 * as general purpose I/O.  This will assert CTS and CD for the
+	 * SCC ports.
+	 */
+	/* FIXME: see 360um p.7-365 and 860um p.34-12 
+	 * I can't make sense of these bits - mleslie*/
+/* 	immap->im_ioport.iop_pcdir |= 0x03c6; */
+/* 	immap->im_ioport.iop_pcpar &= ~0x03c6; */
+
+/* 	cp->pio_pcdir |= 0x03c6; */
+/* 	cp->pio_pcpar &= ~0x03c6; */
+
+
+
+	/* Connect SCC2 and SCC3 to NMSI.  Connect BRG3 to SCC2 and
+	 * BRG4 to SCC3.
+	 */
+	cp->si_sicr &= ~0x00ffff00;
+	cp->si_sicr |=  0x001b1200;
+
+#ifdef CONFIG_PP04
+	/* Frequentis PP04 forced to RS-232 until we know better.
+	 * Port C 12 and 13 low enables RS-232 on SCC3 and SCC4.
+	 */
+	immap->im_ioport.iop_pcdir |= 0x000c;
+	immap->im_ioport.iop_pcpar &= ~0x000c;
+	immap->im_ioport.iop_pcdat &= ~0x000c;
+
+	/* This enables the TX driver.
+	*/
+	cp->cp_pbpar &= ~0x6000;
+	cp->cp_pbdat &= ~0x6000;
+#endif
+
+	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
+		state->magic = SSTATE_MAGIC;
+		state->line = i;
+		state->type = PORT_UNKNOWN;
+		state->custom_divisor = 0;
+		state->close_delay = 5*HZ/10;
+		state->closing_wait = 30*HZ;
+		state->callout_termios = callout_driver.init_termios;
+		state->normal_termios = serial_driver.init_termios;
+		state->icount.cts = state->icount.dsr = 
+			state->icount.rng = state->icount.dcd = 0;
+		state->icount.rx = state->icount.tx = 0;
+		state->icount.frame = state->icount.parity = 0;
+		state->icount.overrun = state->icount.brk = 0;
+		printk(KERN_INFO "ttyS%02d at irq 0x%02x is an %s\n",
+		       i, (unsigned int)(state->irq),
+		       (state->smc_scc_num & NUM_IS_SCC) ? "SCC" : "SMC");
+
+#ifdef CONFIG_SERIAL_CONSOLE
+		/* If we just printed the message on the console port, and
+		 * we are about to initialize it for general use, we have
+		 * to wait a couple of character times for the CR/NL to
+		 * make it out of the transmit buffer.
+		 */
+		if (i == CONFIG_SERIAL_CONSOLE_PORT)
+			mdelay(8);
+
+
+/* 		idx = PORT_NUM(info->state->smc_scc_num); */
+/* 		if (info->state->smc_scc_num & NUM_IS_SCC) */
+/* 			chan = scc_chan_map[idx]; */
+/* 		else */
+/* 			chan = smc_chan_map[idx]; */
+
+/* 		cp->cp_cr = mk_cr_cmd(chan, CPM_CR_STOP_TX) | CPM_CR_FLG; */
+/* 		while (cp->cp_cr & CPM_CR_FLG); */
+
+#endif
+		/* info = kmalloc(sizeof(ser_info_t), GFP_KERNEL); */
+		info = &quicc_ser_info[i];
+		if (info) {
+			/* __clear_user(info,sizeof(ser_info_t)); */
+			memset (info, 0, sizeof(ser_info_t));
+			init_waitqueue_head(&info->open_wait);
+			init_waitqueue_head(&info->close_wait);
+			info->magic = SERIAL_MAGIC;
+			info->flags = state->flags;
+			info->tqueue.routine = do_softint;
+			info->tqueue.data = info;
+			info->tqueue_hangup.routine = do_serial_hangup;
+			info->tqueue_hangup.data = info;
+			info->line = i;
+			info->state = state;
+			state->info = (struct async_struct *)info;
+
+			/* We need to allocate a transmit and receive buffer
+			 * descriptors from dual port ram, and a character
+			 * buffer area from host mem.
+			 */
+			dp_addr = m360_cpm_dpalloc(sizeof(QUICC_BD) * RX_NUM_FIFO);
+
+			/* Allocate space for FIFOs in the host memory.
+			 *  (for now this is from a static array of buffers :(
+			 */
+			/* mem_addr = m360_cpm_hostalloc(RX_NUM_FIFO * RX_BUF_SIZE); */
+			/* mem_addr = kmalloc (RX_NUM_FIFO * RX_BUF_SIZE, GFP_BUFFER); */
+			mem_addr = &rx_buf_pool[i * RX_NUM_FIFO * RX_BUF_SIZE];
+
+			/* Set the physical address of the host memory
+			 * buffers in the buffer descriptors, and the
+			 * virtual address for us to work with.
+			 */
+			bdp = (QUICC_BD *)((uint)pquicc + dp_addr);
+			info->rx_cur = info->rx_bd_base = bdp;
+
+			/* initialize rx buffer descriptors */
+			for (j=0; j<(RX_NUM_FIFO-1); j++) {
+				bdp->buf = &rx_buf_pool[(i * RX_NUM_FIFO + j ) * RX_BUF_SIZE];
+				bdp->status = BD_SC_EMPTY | BD_SC_INTRPT;
+				mem_addr += RX_BUF_SIZE;
+				bdp++;
+			}
+			bdp->buf = &rx_buf_pool[(i * RX_NUM_FIFO + j ) * RX_BUF_SIZE];
+			bdp->status = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
+
+
+			idx = PORT_NUM(info->state->smc_scc_num);
+			if (info->state->smc_scc_num & NUM_IS_SCC) {
+
+#if defined (CONFIG_UCQUICC) && 1
+				/* set the transceiver mode to RS232 */
+				sipex_mode_bits &= ~(uint)SIPEX_MODE(idx,0x0f); /* clear current mode */
+				sipex_mode_bits |= (uint)SIPEX_MODE(idx,0x02);
+				*(uint *)_periph_base = sipex_mode_bits;
+				/* printk ("sipex bits = 0x%08x\n", sipex_mode_bits); */
+#endif
+
+				scp = &pquicc->scc_regs[idx];
+				sup = &pquicc->pram[info->state->port].scc.pscc.u;
+				sup->rbase = dp_addr;
+			}
+			else {
+				sp = &cp->smc_regs[idx];
+				up = &pquicc->pram[info->state->port].scc.pothers.idma_smc.psmc.u;
+				up->rbase = dp_addr;
+			}
+
+			dp_addr = m360_cpm_dpalloc(sizeof(QUICC_BD) * TX_NUM_FIFO);
+
+			/* Allocate space for FIFOs in the host memory.
+			*/
+			/* mem_addr = m360_cpm_hostalloc(TX_NUM_FIFO * TX_BUF_SIZE); */
+			/* mem_addr = kmalloc (TX_NUM_FIFO * TX_BUF_SIZE, GFP_BUFFER); */
+			mem_addr = &tx_buf_pool[i * TX_NUM_FIFO * TX_BUF_SIZE];
+
+			/* Set the physical address of the host memory
+			 * buffers in the buffer descriptors, and the
+			 * virtual address for us to work with.
+			 */
+			/* bdp = (QUICC_BD *)&cp->cp_dpmem[dp_addr]; */
+			bdp = (QUICC_BD *)((uint)pquicc + dp_addr);
+			info->tx_cur = info->tx_bd_base = (QUICC_BD *)bdp;
+
+			/* initialize tx buffer descriptors */
+			for (j=0; j<(TX_NUM_FIFO-1); j++) {
+				bdp->buf = &tx_buf_pool[(i * TX_NUM_FIFO + j ) * TX_BUF_SIZE];
+				bdp->status = BD_SC_INTRPT;
+				mem_addr += TX_BUF_SIZE;
+				bdp++;
+			}
+			bdp->buf = &tx_buf_pool[(i * TX_NUM_FIFO + j ) * TX_BUF_SIZE];
+			bdp->status = (BD_SC_WRAP | BD_SC_INTRPT);
+
+			if (info->state->smc_scc_num & NUM_IS_SCC) {
+				sup->tbase = dp_addr;
+
+				/* Set up the uart parameters in the
+				 * parameter ram.
+				 */
+				sup->rfcr = SMC_EB;
+				sup->tfcr = SMC_EB;
+
+				/* Set this to 1 for now, so we get single
+				 * character interrupts.  Using idle charater
+				 * time requires some additional tuning.
+				 */
+				sup->mrblr = 1;
+				sup->max_idl = 0;
+				sup->brkcr = 1;
+				sup->parec = 0;
+				sup->frmer = 0;
+				sup->nosec = 0;
+				sup->brkec = 0;
+				sup->uaddr1 = 0;
+				sup->uaddr2 = 0;
+				sup->toseq = 0;
+				{
+					int i;
+					for (i=0;i<8;i++)
+						sup->cc[i] = 0x8000;
+				}
+				sup->rccm = 0xc0ff;
+
+				/* Send the CPM an initialize command.
+				*/
+				chan = scc_chan_map[idx];
+
+				/* execute the INIT RX & TX PARAMS command for this channel. */
+				cp->cp_cr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+				while (cp->cp_cr & CPM_CR_FLG);
+
+				/* Set UART mode, 8 bit, no parity, one stop.
+				 * Enable receive and transmit.
+				 */
+				scp->scc_gsmr.w.high = 0;
+				scp->scc_gsmr.w.low = 
+					(SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
+
+				/* Disable all interrupts and clear all pending
+				 * events.
+				 */
+				scp->scc_sccm = 0;
+				scp->scc_scce = 0xffff;
+				scp->scc_dsr = 0x7e7e;
+				scp->scc_psmr = 0x3000;
+
+				/* If the port is the console, enable Rx and Tx.
+				*/
+#ifdef CONFIG_SERIAL_CONSOLE
+				if (i == CONFIG_SERIAL_CONSOLE_PORT)
+					scp->scc_gsmr.w.low |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+			}
+			else {
+				/* Configure SMCs Tx/Rx instead of port B
+				 * parallel I/O.
+				 */
+
+				iobits = 0xc0 << (idx * 4);
+				cp->pip_pbpar |= iobits;
+				cp->pip_pbdir &= ~iobits;
+				cp->pip_pbodr &= ~iobits;
+
+
+				/* Connect the baud rate generator to the
+				 * SMC based upon index in rs_table.  Also
+				 * make sure it is connected to NMSI.
+				 */
+				cp->si_simode &= ~(0xffff << (idx * 16));
+				cp->si_simode |= (i << ((idx * 16) + 12));
+
+				up->tbase = dp_addr;
+
+				/* Set up the uart parameters in the
+				 * parameter ram.
+				 */
+				up->rfcr = SMC_EB;
+				up->tfcr = SMC_EB;
+
+				/* Set this to 1 for now, so we get single
+				 * character interrupts.  Using idle charater
+				 * time requires some additional tuning.
+				 */
+				up->mrblr = 1;
+				up->max_idl = 0;
+				up->brkcr = 1;
+
+				/* Send the CPM an initialize command.
+				*/
+				chan = smc_chan_map[idx];
+
+				cp->cp_cr = mk_cr_cmd(chan,
+									  CPM_CR_INIT_TRX) | CPM_CR_FLG;
+#ifdef CONFIG_SERIAL_CONSOLE
+				if (i == CONFIG_SERIAL_CONSOLE_PORT)
+					printk("");
+#endif
+				while (cp->cp_cr & CPM_CR_FLG);
+
+				/* Set UART mode, 8 bit, no parity, one stop.
+				 * Enable receive and transmit.
+				 */
+				sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
+
+				/* Disable all interrupts and clear all pending
+				 * events.
+				 */
+				sp->smc_smcm = 0;
+				sp->smc_smce = 0xff;
+
+				/* If the port is the console, enable Rx and Tx.
+				*/
+#ifdef CONFIG_SERIAL_CONSOLE
+				if (i == CONFIG_SERIAL_CONSOLE_PORT)
+					sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+#endif
+			}
+
+			/* Install interrupt handler.
+			*/
+			/* cpm_install_handler(IRQ_MACHSPEC | state->irq, rs_360_interrupt, info);  */
+			/*request_irq(IRQ_MACHSPEC | state->irq, rs_360_interrupt, */
+			request_irq(state->irq, rs_360_interrupt,
+						IRQ_FLG_LOCK, serial_driver.name, (void *)info);
+
+			/* Set up the baud rate generator.
+			*/
+			m360_cpm_setbrg(i, baud_table[baud_idx]);
+
+		}
+	}
+
+	return 0;
+}
+
+
+
+
+
+/* This must always be called before the rs_360_init() function, otherwise
+ * it blows away the port control information.
+ */
+//static int __init serial_console_setup( struct console *co, char *options)
+int serial_console_setup( struct console *co, char *options)
+{
+	struct		serial_state	*ser;
+	uint       mem_addr, dp_addr, bidx, idx, iobits;
+	int i;
+	ushort		chan;
+	QUICC_BD	*bdp;
+	volatile	QUICC			*cp;
+	volatile	struct smc_regs	*sp;
+	volatile	struct scc_regs	*scp;
+	volatile	struct smc_uart_pram	*up;
+	volatile	struct uart_pram		*sup;
+
+/* mleslie TODO:
+ * add something to the 68k bootloader to store a desired initial console baud rate */
+
+/* 	bd_t						*bd; */ /* a board info struct used by EPPC-bug */
+/* 	bd = (bd_t *)__res; */
+
+ 	for (bidx = 0; bidx < (sizeof(baud_table) / sizeof(int)); bidx++)
+	 /* if (bd->bi_baudrate == baud_table[bidx]) */
+ 		if (CONSOLE_BAUDRATE == baud_table[bidx])
+			break;
+
+	/* co->cflag = CREAD|CLOCAL|bidx|CS8; */
+	baud_idx = bidx;
+
+	ser = rs_table + CONFIG_SERIAL_CONSOLE_PORT;
+
+	cp = pquicc;	/* Get pointer to Communication Processor */
+
+	idx = PORT_NUM(ser->smc_scc_num);
+	if (ser->smc_scc_num & NUM_IS_SCC) {
+		scp = &cp->scc_regs[idx];
+		/* sup = (scc_uart_t *)&cp->cp_dparam[ser->port]; */
+		sup = &pquicc->pram[ser->port].scc.pscc.u;
+
+		/* TODO: need to set up SCC pin assignment etc. here */
+		
+	}
+	else {
+		sp = &cp->smc_regs[idx];
+		/* up = (smc_uart_t *)&cp->cp_dparam[ser->port]; */
+		up = &pquicc->pram[ser->port].scc.pothers.idma_smc.psmc.u;
+
+		iobits = 0xc0 << (idx * 4);
+		cp->pip_pbpar |= iobits;
+		cp->pip_pbdir &= ~iobits;
+		cp->pip_pbodr &= ~iobits;
+
+		/* Connect the baud rate generator to the
+		 * SMC based upon index in rs_table.  Also
+		 * make sure it is connected to NMSI.
+		 */
+		cp->si_simode &= ~(0xffff << (idx * 16));
+		cp->si_simode |= (idx << ((idx * 16) + 12));
+	}
+
+	/* When we get here, the CPM has been reset, so we need
+	 * to configure the port.
+	 * We need to allocate a transmit and receive buffer descriptor
+	 * from dual port ram, and a character buffer area from host mem.
+	 */
+
+	/* Allocate space for two buffer descriptors in the DP ram.
+	*/
+	dp_addr = m360_cpm_dpalloc(sizeof(QUICC_BD) * CONSOLE_NUM_FIFO);
+
+	/* Allocate space for two 2 byte FIFOs in the host memory.
+	 */
+	/* mem_addr = m360_cpm_hostalloc(8); */
+	mem_addr = (uint)console_fifos;
+
+
+	/* Set the physical address of the host memory buffers in
+	 * the buffer descriptors.
+	 */
+	/* bdp = (QUICC_BD *)&cp->cp_dpmem[dp_addr]; */
+	bdp = (QUICC_BD *)((uint)pquicc + dp_addr);
+	bdp->buf = (char *)mem_addr;
+	(bdp+1)->buf = (char *)(mem_addr+4);
+
+	/* For the receive, set empty and wrap.
+	 * For transmit, set wrap.
+	 */
+	bdp->status = BD_SC_EMPTY | BD_SC_WRAP;
+	(bdp+1)->status = BD_SC_WRAP;
+
+	/* Set up the uart parameters in the parameter ram.
+	 */
+	if (ser->smc_scc_num & NUM_IS_SCC) {
+
+		sup->rbase = dp_addr;
+		sup->tbase = dp_addr + sizeof(QUICC_BD);
+
+		/* Set up the uart parameters in the
+		 * parameter ram.
+		 */
+		sup->rfcr = SMC_EB;
+		sup->tfcr = SMC_EB;
+
+		/* Set this to 1 for now, so we get single
+		 * character interrupts.  Using idle charater
+		 * time requires some additional tuning.
+		 */
+		sup->mrblr = 1;
+		sup->max_idl = 0;
+		sup->brkcr = 1;
+		sup->parec = 0;
+		sup->frmer = 0;
+		sup->nosec = 0;
+		sup->brkec = 0;
+		sup->uaddr1 = 0;
+		sup->uaddr2 = 0;
+		sup->toseq = 0;
+		{
+			int i;
+			for (i=0;i<8;i++)
+				sup->cc[i] = 0x8000;
+		}
+		sup->rccm = 0xc0ff;
+
+		/* Send the CPM an initialize command.
+		*/
+		chan = scc_chan_map[idx];
+
+		cp->cp_cr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+		while (cp->cp_cr & CPM_CR_FLG);
+
+		/* Set UART mode, 8 bit, no parity, one stop.
+		 * Enable receive and transmit.
+		 */
+		scp->scc_gsmr.w.high = 0;
+		scp->scc_gsmr.w.low = 
+			(SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
+
+		/* Disable all interrupts and clear all pending
+		 * events.
+		 */
+		scp->scc_sccm = 0;
+		scp->scc_scce = 0xffff;
+		scp->scc_dsr = 0x7e7e;
+		scp->scc_psmr = 0x3000;
+
+		scp->scc_gsmr.w.low |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+	}
+	else {
+		up->rbase = dp_addr;	/* Base of receive buffer desc. */
+		up->tbase = dp_addr+sizeof(QUICC_BD);	/* Base of xmt buffer desc. */
+		up->rfcr = SMC_EB;
+		up->tfcr = SMC_EB;
+
+		/* Set this to 1 for now, so we get single character interrupts.
+		*/
+		up->mrblr = 1;		/* receive buffer length */
+		up->max_idl = 0;		/* wait forever for next char */
+
+		/* Send the CPM an initialize command.
+		*/
+		chan = smc_chan_map[idx];
+		cp->cp_cr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+		printk("");
+		while (cp->cp_cr & CPM_CR_FLG);
+
+		/* Set UART mode, 8 bit, no parity, one stop.
+		 * Enable receive and transmit.
+		 */
+		sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;
+
+		/* And finally, enable Rx and Tx.
+		*/
+		sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+	}
+
+	/* Set up the baud rate generator.
+	*/
+	/* m360_cpm_setbrg((ser - rs_table), bd->bi_baudrate); */
+	m360_cpm_setbrg((ser - rs_table), CONSOLE_BAUDRATE);
+
+	return 0;
+}
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/Readme.txt linux-2.4.29-uc1/arch/m68knommu/platform/68360/Readme.txt
--- linux-2.4.29/arch/m68knommu/platform/68360/Readme.txt	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/Readme.txt	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,11 @@
+M68360 port of uClinux:
+    May 29, 2001.
+    This port was done by SED Systems, a division of Calian Ltd. for use
+    on the SIOS hardware. This port is based on the 68328 port and uClinux
+    2.0.38.pre7 M68360 support. The devices we have tested are:
+        -Timer 1 as system clock (this should be changed to the PIT)
+        -Console on SMC 2.
+    Included is serial port support for the SCCs. We have had problems with
+    these devices (When both SCCs and SMCs are select, the kernel hangs during
+    boot, I have not tried SCCs only).
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/Rules.make linux-2.4.29-uc1/arch/m68knommu/platform/68360/Rules.make
--- linux-2.4.29/arch/m68knommu/platform/68360/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/Rules.make	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,95 @@
+#
+# 68360/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2000       Michael Leslie <mleslie@ArcturusNetworks.com>,
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uclinux.org>,
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+#
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/m68000/libgcc.a
+
+CFLAGS := -fno-builtin -DNO_CACHE $(CFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -m68332 -D__ELF__ -DMAGIC_ROM_PTR -DNO_FORGET -DUTS_SYSNAME=\"uClinux\" -D__linux__
+AFLAGS := $(AFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -m68332 -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME=\"uClinux\" -Wa,--bitwise-or
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+
+
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+ifdef CONFIG_FRAMEBUFFER
+SUBDIRS := $(SUBDIRS) arch/$(ARCH)/console
+ARCHIVES := $(ARCHIVES) arch/$(ARCH)/console/console.a
+endif
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+image.s19: romfs.img linux
+	$(CROSS_COMPILE)objcopy --adjust-section-vma=.data=0x`$(CROSS_COMPILE)nm linux | awk '/__data_rom_start/ {printf $$1}'` linux image.s19
+	ADDR=`$(CROSS_COMPILE)objdump --headers image.s19 | \
+	grep .data | cut -d' ' -f 13,15 | xargs printf "0x%s 0x%s\n" | \
+	xargs printf "%d + %d\n" |xargs expr |xargs printf "0x%x\n"`;\
+	$(CROSS_COMPILE)objcopy --add-section=.romfs=romfs.img \
+	--adjust-section-vma=.romfs=$${ADDR} --no-adjust-warnings \
+	--set-section-flags=.romfs=alloc,load,data   \
+	image.s19 image.s19 2> /dev/null
+	$(CROSS_COMPILE)objcopy -O srec image.s19 image.s19
+
+linux.data: linux
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.romvec --remove-section=.text --remove-section=.ramvec --remove-section=.bss --remove-section=.eram linux linux.data
+
+linux.text: linux
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.ramvec --remove-section=.bss --remove-section=.data --remove-section=.eram --set-section-flags=.romvec=CONTENTS,ALLOC,LOAD,READONLY,CODE linux linux.text
+
+linux.bin: linux.text linux.data romfs.img
+	if [ -f romfs.img ]; then\
+		cat linux.text linux.data romfs.img > linux.bin;\
+	else\
+		cat linux.text linux.data > linux.bin;\
+	fi
+
+flash.s19: linux.bin arch/$(ARCH)/empty.o
+	$(CROSS_COMPILE)objcopy -v -R .text -R .data -R .bss --add-section=.fs=linux.bin --adjust-section-vma=.fs=$(FLASH_LOAD_ADDR) arch/$(ARCH)/empty.o flash.s19
+	$(CROSS_COMPILE)objcopy -O srec flash.s19
+
+flash.b: flash.s19
+	$(STOB) flash.s19 > flash.b
+
+linux.trg linux.rom: linux.bin
+	perl arch/$(ARCH)/platform/$(PLATFORM)/tools/fixup.pl
+
+linux.s19: linux
+	$(CROSS_COMPILE)objcopy -O srec --adjust-section-vma=.data=0x`$(CROSS_COMPILE)nm linux | awk '/__data_rom_start/ {printf $$1}'` linux linux.s19
+	
+linux.b: linux.s19
+	if [ -f $(INIT_B) ]; then\
+		cp $(INIT_B) linux.b;\
+	fi
+	$(STOB) linux.s19 >> linux.b
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f linux.text linux.data linux.bin linux.rom linux.trg
+	rm -f linux.s19 romfs.s19 flash.s19
+	rm -f linux.img romdisk.img
+	rm -f linux.b romfs.b flash.b
+	rm -f romfs.o
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/traps.c linux-2.4.29-uc1/arch/m68knommu/platform/68360/traps.c
--- linux-2.4.29/arch/m68knommu/platform/68360/traps.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/traps.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,274 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/traps.c -- general exception handling code
+ *
+ * Cloned from Linux/m68k.
+ *
+ * No original Copyright holder listed,
+ * Probabily original (C) Roman Zippel (assigned DJD, 1999)
+ *
+ * Copyright (c) 2000  Michael Leslie <mleslie@ArcturusNetworks.com>
+ * Copyright 1999-2000 D. Jeff Dionne, <jeff@uclinux.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/errno.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+
+/* table for system interrupt handlers */
+static irq_handler_t irq_list[SYS_IRQS];
+
+static const char *default_names[SYS_IRQS] = {
+	"spurious int", "int1 handler", "int2 handler", "int3 handler",
+	"int4 handler", "int5 handler", "int6 handler", "int7 handler"
+};
+
+/* The number of spurious interrupts */
+volatile unsigned int num_spurious;
+
+#define NUM_IRQ_NODES 96
+static irq_node_t nodes[NUM_IRQ_NODES];
+
+/* 
+ * The flash interrupt vector table is in crt0_rom.S. If you are running from
+ * RAM, this may not suite your purposes :-).
+ */
+
+/*
+ * void init_IRQ(void)
+ *
+ * Parameters:	None
+ *
+ * Returns:	Nothing
+ *
+ * This function should be called during kernel startup to initialize
+ * the IRQ handling routines.
+ */
+
+void init_IRQ(void)
+{
+	int i;
+
+	for (i = 0; i < SYS_IRQS; i++) {
+		if (mach_default_handler)
+			irq_list[i].handler = (*mach_default_handler)[i];
+		else
+			irq_list[i].handler = NULL;
+			irq_list[i].flags   = IRQ_FLG_STD;
+			irq_list[i].dev_id  = NULL;
+			irq_list[i].devname = default_names[i];
+	}
+
+	for (i = 0; i < NUM_IRQ_NODES; i++)
+		nodes[i].handler = NULL;
+
+	//mach_init_IRQ ();
+}
+
+irq_node_t *new_irq_node(void)
+{
+	irq_node_t *node;
+	short i;
+
+	for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--)
+		if (!node->handler)
+			return node;
+
+	printk ("new_irq_node: out of nodes\n");
+	return NULL;
+}
+
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq)
+		return mach_request_irq(irq, handler, flags, devname, dev_id);
+
+	if (irq < IRQ1 || irq > IRQ7) {
+		printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+	if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
+		if (irq_list[irq].flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+	}
+	irq_list[irq].handler = handler;
+	irq_list[irq].flags   = flags;
+	irq_list[irq].dev_id  = dev_id;
+	irq_list[irq].devname = devname;
+	return 0;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq) {
+		mach_free_irq(irq, dev_id);
+		return;
+	}
+
+	if (irq < IRQ1 || irq > IRQ7) {
+		printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (irq_list[irq].dev_id != dev_id)
+		printk("%s: Removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, irq_list[irq].devname);
+
+	if (mach_default_handler)
+		irq_list[irq].handler = (*mach_default_handler)[irq];
+	else
+		irq_list[irq].handler = NULL;
+	irq_list[irq].flags   = IRQ_FLG_STD;
+	irq_list[irq].dev_id  = NULL;
+	irq_list[irq].devname = default_names[irq];
+}
+
+/*
+ * Do we need these probe functions on the m68k?
+ */
+unsigned long probe_irq_on (void)
+{
+	return 0;
+}
+
+int probe_irq_off (unsigned long irqs)
+{
+	return 0;
+}
+
+asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
+{
+    if ((vec >= VEC_INT1) && (vec <= VEC_INT7))
+    {
+        vec -= VEC_SPUR;
+        kstat.irqs[0][vec]++;
+        irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
+    }
+    else
+    {
+        if(vec > 255)
+        {
+            panic("Intterrupt vector %ld\n", vec);
+        }
+        else
+        {
+            if (mach_process_int)
+                mach_process_int(vec, fp);
+            else
+                panic("Can't process interrupt vector %ld\n", vec);
+        }
+    }
+    return;
+}
+
+int get_irq_list(char *buf)
+{
+        int i, len = 0;
+	
+        /* autovector interrupts */
+        if (mach_default_handler) {
+                for (i = 0; i < SYS_IRQS; i++) {
+                       len += sprintf(buf+len, "auto %2d: %10u ", i,
+		       i ? kstat.irqs[0][i] : num_spurious);
+                       len += sprintf(buf+len, "  ");
+                       len += sprintf(buf+len, "%s\n", irq_list[i].devname);
+
+		}
+        }
+        len += mach_get_irq_list(buf+len);
+        return len;
+}
+
+/*
+ *	Generic dumping code. Used for panic and debug.
+ */
+
+void dump(struct pt_regs *fp)
+{
+	unsigned long	*sp;
+	unsigned char	*tp;
+	int		i;
+
+	printk("\nCURRENT PROCESS:\n\n");
+#if 0
+{
+	extern int	swt_lastjiffies, swt_reference;
+	printk("WATCHDOG: jiffies=%d lastjiffies=%d [%d] reference=%d\n",
+		jiffies, swt_lastjiffies, (swt_lastjiffies - jiffies),
+		swt_reference);
+}
+#endif
+	printk("COMM=%s PID=%d\n", current->comm, current->pid);
+	if (current->mm) {
+		printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+			(int) current->mm->start_code,
+			(int) current->mm->end_code,
+			(int) current->mm->start_data,
+			(int) current->mm->end_data,
+			(int) current->mm->end_data,
+			(int) current->mm->brk);
+//		printk("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
+		printk("USER-STACK=%08x  \n\n",
+			(int) current->mm->start_stack);
+	}
+
+	printk("PC: %08lx\n", fp->pc);
+	printk("SR: %08lx    SP: %08lx\n", (long) fp->sr, (long) fp);
+	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+		fp->d0, fp->d1, fp->d2, fp->d3);
+	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+		fp->d4, fp->d5, fp->a0, fp->a1);
+	printk("\nUSP: %08x   TRAPFRAME: %08x\n",
+		rdusp(), (unsigned int) fp);
+
+	printk("\nCODE:");
+	tp = ((unsigned char *) fp->pc) - 0x20;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+
+	printk("\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n");
+	/*
+	if (STACK_MAGIC != *(unsigned long *)current->kernel_stack_page)
+                printk("(Possibly corrupted stack page??)\n");*/
+	printk("\n");
+
+	printk("\nUSER STACK:");
+	tp = (unsigned char *) (rdusp() - 0x10);
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
+		if ((i % 0x10) == 0)
+			printk("\n%08x: ", (int) (tp + i));
+		printk("%08x ", (int) *sp++);
+	}
+	printk("\n\n");
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/uCquicc/bootstd.h linux-2.4.29-uc1/arch/m68knommu/platform/68360/uCquicc/bootstd.h
--- linux-2.4.29/arch/m68knommu/platform/68360/uCquicc/bootstd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/uCquicc/bootstd.h	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,132 @@
+/* bootstd.h:  Bootloader system call interface
+ *
+ * (c) 1999, Rt-Control, Inc.
+ */
+
+#ifndef __BOOTSTD_H__
+#define __BOOTSTD_H__
+
+#define NR_BSC 21            /* last used bootloader system call */
+
+#define __BN_reset        0  /* reset and start the bootloader */
+#define __BN_test         1  /* tests the system call interface */
+#define __BN_exec         2  /* executes a bootloader image */
+#define __BN_exit         3  /* terminates a bootloader image */
+#define __BN_program      4  /* program FLASH from a chain */
+#define __BN_erase        5  /* erase sector(s) of FLASH */
+#define __BN_open         6
+#define __BN_write        7
+#define __BN_read         8
+#define __BN_close        9
+#define __BN_mmap         10 /* map a file descriptor into memory */
+#define __BN_munmap       11 /* remove a file to memory mapping */
+#define __BN_gethwaddr    12 /* get the hardware address of my interfaces */
+#define __BN_getserialnum 13 /* get the serial number of this board */
+#define __BN_getbenv      14 /* get a bootloader envvar */
+#define __BN_setbenv      15 /* get a bootloader envvar */
+#define __BN_setpmask     16 /* set the protection mask */
+#define __BN_readenv      17 /* read environment variables */
+#define __BN_flash_chattr_range		18
+#define __BN_flash_erase_range		19
+#define __BN_flash_write_range		20
+
+/* Calling conventions compatible to (uC)linux/68k
+ * We use simmilar macros to call into the bootloader as for uClinux
+ */
+
+#define __bsc_return(type, res) \
+do { \
+   if ((unsigned long)(res) >= (unsigned long)(-64)) { \
+      /* let errno be a function, preserve res in %d0 */ \
+      int __err = -(res); \
+      errno = __err; \
+      res = -1; \
+   } \
+   return (type)(res); \
+} while (0)
+
+#define _bsc0(type,name) \
+type name(void) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc1(type,name,atype,a) \
+type name(atype a) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc2(type,name,atype,a,btype,b) \
+type name(atype a, btype b) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc3(type,name,atype,a,btype,b,ctype,c) \
+type name(atype a, btype b, ctype c) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
+type name(atype a, btype b, ctype c, dtype d) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   register long __d __asm__ ("%d4") = (long)d; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c), "d" (__d) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
+type name(atype a, btype b, ctype c, dtype d, etype e) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   register long __d __asm__ ("%d4") = (long)d; \
+   register long __e __asm__ ("%d5") = (long)e; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c), "d" (__d), "d" (__e) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#endif /* __BOOTSTD_H__ */
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/uCquicc/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/68360/uCquicc/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/68360/uCquicc/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/uCquicc/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,416 @@
+/* arch/m68knommu/platform/68360/uCquicc/crt0_rom.S
+ *
+ * Startup code for Motorola 68360
+ *
+ * Copyright 2001 (C) SED Systems, a Division of Calian Ltd.
+ * Based on: arch/m68knommu/platform/68328/pilot/crt0_rom.S
+ * Based on: arch/m68knommu/platform/68360/uCquicc/crt0_rom.S, 2.0.38.1.pre7
+ *           uClinux Kernel
+ * Copyright (C) Michael Leslie <mleslie@ArcturusNetworks.com>
+ * Based on: arch/m68knommu/platform/68EZ328/ucsimm/crt0_rom.S
+ * Copyright (C) 1998  D. Jeff Dionne <jeff@uclinux.org>,
+ *
+ */
+#define ASSEMBLY
+#include <linux/config.h>
+
+.global _stext
+.global __bss_start
+.global _start
+
+.global _rambase
+.global __ramvec
+.global _ramvec
+.global _ramstart
+.global _ramend
+
+.global _quicc_base
+.global _periph_base
+.global _dprbase
+
+#define REGB                        0x1000
+#define PEPAR                       (_dprbase + REGB + 0x0016)
+#define GMR                         (_dprbase + REGB + 0x0040)
+#define OR0                         (_dprbase + REGB + 0x0054)
+#define BR0                         (_dprbase + REGB + 0x0050)
+#define OR1                         (_dprbase + REGB + 0x0064)
+#define BR1                         (_dprbase + REGB + 0x0060)
+#define OR4                         (_dprbase + REGB + 0x0094)
+#define BR4                         (_dprbase + REGB + 0x0090)
+#define OR6                         (_dprbase + REGB + 0x00b4)
+#define BR6                         (_dprbase + REGB + 0x00b0)
+#define OR7                         (_dprbase + REGB + 0x00c4)
+#define BR7                         (_dprbase + REGB + 0x00c0)
+
+#define MCR                         (_dprbase + REGB + 0x0000)
+#define AVR                         (_dprbase + REGB + 0x0008)
+
+#define SYPCR                       (_dprbase + REGB + 0x0022)
+
+#define PLLCR                       (_dprbase + REGB + 0x0010)
+#define CLKOCR                      (_dprbase + REGB + 0x000C)
+#define CDVCR                       (_dprbase + REGB + 0x0014)
+
+#define BKAR                        (_dprbase + REGB + 0x0030)
+#define BKCR                        (_dprbase + REGB + 0x0034)
+#define SWIV                        (_dprbase + REGB + 0x0023)
+#define PICR                        (_dprbase + REGB + 0x0026)
+#define PITR                        (_dprbase + REGB + 0x002A)
+
+/* Define for all memory configuration */
+#define MCU_SIM_GMR                 0x00000000
+#define SIM_OR_MASK                 0x0fffffff
+
+/* Defines for chip select zero - the flash */
+#define SIM_OR0_MASK                0x20000002
+#define SIM_BR0_MASK                0x00000001
+
+
+/* Defines for chip select one - the RAM */
+#define SIM_OR1_MASK                0x10000000
+#define SIM_BR1_MASK                0x00000001
+
+#define MCU_SIM_MBAR_ADRS           0x0003ff00
+#define MCU_SIM_MBAR_BA_MASK        0xfffff000
+#define MCU_SIM_MBAR_AS_MASK        0x00000001
+
+#define MCU_SIM_PEPAR               0x00B4
+    
+#define MCU_DISABLE_INTRPTS         0x2700
+#define MCU_SIM_AVR                 0x00
+    
+#define MCU_SIM_MCR                 0x00005cff
+
+#define MCU_SIM_CLKOCR              0x00
+#define MCU_SIM_PLLCR               0x8000
+#define MCU_SIM_CDVCR               0x0000
+
+#define MCU_SIM_SYPCR               0x0000
+#define MCU_SIM_SWIV                0x00
+#define MCU_SIM_PICR                0x0000
+#define MCU_SIM_PITR                0x0000
+
+
+#include <asm/m68360_regs.h>
+
+	
+/* By the time this RAM specific code begins to execute, DPRAM
+ * and DRAM should already be mapped and accessible. */
+
+	.text
+_start:
+_stext:
+    nop
+    ori.w   #MCU_DISABLE_INTRPTS,   %sr     /* disable interrupts: */
+    /* We should not need to setup the boot stack the reset should do it. */
+    movea.l	#_boot_stack,           %sp     /*set up stack at the end of DRAM:*/
+
+
+set_mbar_register:
+    moveq.l #0x07,                  %d1     /* Setup MBAR */
+    movec	%d1,                    %dfc
+
+    lea.l   MCU_SIM_MBAR_ADRS,      %a0
+    move.l  #_dprbase,              %d0
+    andi.l  #MCU_SIM_MBAR_BA_MASK,  %d0
+    ori.l   #MCU_SIM_MBAR_AS_MASK,  %d0
+    moves.l %d0,                    %a0@
+
+    moveq.l #0x05,                  %d1
+    movec.l %d1,                    %dfc
+
+/* Now we can begin to access registers in DPRAM */
+
+set_sim_mcr:
+    /* Set Module Configuration Register */
+    move.l  #MCU_SIM_MCR,           MCR
+
+/* to do:	Determine cause of reset */
+
+
+    /*
+    *       configure system clock MC68360 p. 6-40
+    *       (value +1)*osc/128 = system clock
+    */
+set_sim_clock:
+    move.w  #MCU_SIM_PLLCR,         PLLCR
+    move.b  #MCU_SIM_CLKOCR,        CLKOCR
+    move.w  #MCU_SIM_CDVCR,         CDVCR
+
+    // Wait for the PLL to settle
+    move.w      #16384, %d0
+pll_settle_wait:
+    subi.w       #1, %d0
+    bne	pll_settle_wait
+
+    /* Setup the system protection register, and watchdog timer register */
+
+    move.b      #MCU_SIM_SWIV,      SWIV
+    move.w      #MCU_SIM_PICR,      PICR
+    move.w      #MCU_SIM_PITR,      PITR
+    move.w      #MCU_SIM_SYPCR,     SYPCR
+
+/* Clear DPRAM - system + parameter */
+	movea.l	#_dprbase, %a0
+	movea.l	#_dprbase+0x2000, %a1
+
+	/* Copy 0 to %a0 until %a0 == %a1 */
+clear_dpram:
+	movel	#0, %a0@+
+	cmpal	%a0, %a1
+	bhi	clear_dpram
+
+configure_memory_controller:    
+    /*
+    *   Set up Global Memory Register (GMR)
+    */
+    move.l      #MCU_SIM_GMR,   %d0
+    move.l      %d0, GMR
+
+configure_chip_select_0:
+    move.l      #__ramend,      %d0
+    subi.l      #__ramstart,    %d0
+    subq.l      #0x01,          %d0
+    eori.l      #SIM_OR_MASK,   %d0
+    ori.l       #SIM_OR0_MASK,  %d0
+    move.l      %d0,            OR0
+
+    move.l      #__ramstart,    %d0
+    ori.l       #SIM_BR0_MASK,  %d0
+    move.l      %d0,            BR0
+
+
+configure_chip_select_1:
+    move.l      #__flashend,    %d0
+    subi.l      #__flashstart,  %d0
+    subq.l      #0x01,          %d0
+    eori.l      #SIM_OR_MASK,   %d0
+    ori.l       #SIM_OR1_MASK,  %d0
+    move.l      %d0,            OR1
+
+    move.l      #__flashstart,  %d0
+    ori.l       #SIM_BR1_MASK,  %d0
+    move.l      %d0,            BR1
+
+
+    move.w      #MCU_SIM_PEPAR, PEPAR 
+
+/* point to vector table: */
+    move.l  #_romvec,   %a0
+    move.l	#_ramvec,   %a1
+copy_vectors:
+    move.l  %a0@,       %d0
+    move.l  %d0,        %a1@
+    move.l  %a0@,       %a1@
+    addq.l  #0x04,      %a0
+    addq.l  #0x04,      %a1
+    cmp.l   #_start,    %a0
+    blt     copy_vectors
+
+    move.l	#_ramvec, %a1
+    movec	%a1, %vbr
+
+
+	/* Copy data segment from ROM to RAM */
+	moveal	#__data_rom_start, %a0
+	moveal	#__data_start, %a1
+	moveal	#__data_end, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:
+    move.l  %a0@,   %d0
+    addq.l  #0x04,  %a0
+    move.l  %d0,    %a1@
+    addq.l  #0x04,  %a1
+    cmp.l   #__data_end,    %a1
+    blt     LD1
+
+	moveal	#__bss_start, %a0
+	moveal	#end, %a1
+
+	/* Copy 0 to %a0 until %a0 == %a1 */
+L1:
+	movel	#0, %a0@+
+	cmpal	%a0, %a1
+	bhi	L1
+
+load_quicc:
+    move.l  #_dprbase,  _quicc_base
+
+store_ram_size:
+    /* Set ram size information */
+    move.l  #_sdata,    _rambase
+    move.l  #end,       _ramstart
+    move.l  #__ramend,  %d0
+    sub.l   #0x1000,    %d0     /* Reserve 4K for stack space.*/
+    move.l  %d0,        _ramend /* Different from __ramend.*/
+
+store_flash_size:
+    /* Set rom size information */
+    move.l  #__flashend,    %d0
+    sub.l   #__flashstart,  %d0
+    move.l  %d0,            rom_length
+    
+	pea	0
+	pea	env
+	pea	%sp@(4)
+	pea	0
+
+    lea     init_task_union,    %a2
+    move.l  %a2,                _current_task
+    lea     0x2000(%a2),        %sp
+
+lp:
+    jsr	start_kernel
+ /*   jmp lp */
+
+_exit:
+
+	jmp	_exit
+
+
+
+	.data
+    .align 4
+env:
+	.long	0
+_quicc_base:
+	.long	0
+_periph_base:
+	.long	0
+_ramvec:
+    .long   0
+_rambase:
+    .long   0
+_ramstart:
+    .long   0
+_ramend:
+    .long   0
+	.text
+
+    /*
+     * These are the exception vectors at boot up, they are copied into RAM
+     * and then overwritten as needed.
+     */
+ 
+.section ".data.initvect","awx"
+    .long   _boot_stack /* Reset: Initial Stack Pointer                 - 0.  */
+    .long   _start      /* Reset: Initial Program Counter               - 1.  */
+    .long   buserr      /* Bus Error                                    - 2.  */
+    .long   trap        /* Address Error                                - 3.  */
+    .long   trap        /* Illegal Instruction                          - 4.  */
+    .long   trap        /* Divide by zero                               - 5.  */
+    .long   trap        /* CHK, CHK2 Instructions                       - 6.  */
+    .long   trap        /* TRAPcc, TRAPV Instructions                   - 7.  */
+    .long   trap        /* Privilege Violation                          - 8.  */
+    .long   trap        /* Trace                                        - 9.  */
+    .long   trap        /* Line 1010 Emulator                           - 10. */
+    .long   trap        /* Line 1111 Emualtor                           - 11. */
+    .long   trap        /* Harware Breakpoint                           - 12. */
+    .long   trap        /* (Reserved for Coprocessor Protocol Violation)- 13. */
+    .long   trap        /* Format Error                                 - 14. */
+    .long   trap        /* Uninitialized Interrupt                      - 15. */
+    .long   trap        /* (Unassigned, Reserver)                       - 16. */
+    .long   trap        /* (Unassigned, Reserver)                       - 17. */
+    .long   trap        /* (Unassigned, Reserver)                       - 18. */
+    .long   trap        /* (Unassigned, Reserver)                       - 19. */
+    .long   trap        /* (Unassigned, Reserver)                       - 20. */
+    .long   trap        /* (Unassigned, Reserver)                       - 21. */
+    .long   trap        /* (Unassigned, Reserver)                       - 22. */
+    .long   trap        /* (Unassigned, Reserver)                       - 23. */
+    .long   trap        /* Spurious Interrupt                           - 24. */
+    .long   trap        /* Level 1 Interrupt Autovector                 - 25. */
+    .long   trap        /* Level 2 Interrupt Autovector                 - 26. */
+    .long   trap        /* Level 3 Interrupt Autovector                 - 27. */
+    .long   trap        /* Level 4 Interrupt Autovector                 - 28. */
+    .long   trap        /* Level 5 Interrupt Autovector                 - 29. */
+    .long   trap        /* Level 6 Interrupt Autovector                 - 30. */
+    .long   trap        /* Level 7 Interrupt Autovector                 - 31. */
+    .long   system_call /* Trap Instruction Vectors 0                   - 32. */
+    .long   trap        /* Trap Instruction Vectors 1                   - 33. */
+    .long   trap        /* Trap Instruction Vectors 2                   - 34. */
+    .long   trap        /* Trap Instruction Vectors 3                   - 35. */
+    .long   trap        /* Trap Instruction Vectors 4                   - 36. */
+    .long   trap        /* Trap Instruction Vectors 5                   - 37. */
+    .long   trap        /* Trap Instruction Vectors 6                   - 38. */
+    .long   trap        /* Trap Instruction Vectors 7                   - 39. */
+    .long   trap        /* Trap Instruction Vectors 8                   - 40. */
+    .long   trap        /* Trap Instruction Vectors 9                   - 41. */
+    .long   trap        /* Trap Instruction Vectors 10                  - 42. */
+    .long   trap        /* Trap Instruction Vectors 11                  - 43. */
+    .long   trap        /* Trap Instruction Vectors 12                  - 44. */
+    .long   trap        /* Trap Instruction Vectors 13                  - 45. */
+    .long   trap        /* Trap Instruction Vectors 14                  - 46. */
+    .long   trap        /* Trap Instruction Vectors 15                  - 47. */
+    .long   0           /* (Reserved for Coprocessor)                   - 48. */
+    .long   0           /* (Reserved for Coprocessor)                   - 49. */
+    .long   0           /* (Reserved for Coprocessor)                   - 50. */
+    .long   0           /* (Reserved for Coprocessor)                   - 51. */
+    .long   0           /* (Reserved for Coprocessor)                   - 52. */
+    .long   0           /* (Reserved for Coprocessor)                   - 53. */
+    .long   0           /* (Reserved for Coprocessor)                   - 54. */
+    .long   0           /* (Reserved for Coprocessor)                   - 55. */
+    .long   0           /* (Reserved for Coprocessor)                   - 56. */
+    .long   0           /* (Reserved for Coprocessor)                   - 57. */
+    .long   0           /* (Reserved for Coprocessor)                   - 58. */
+    .long   0           /* (Unassigned, Reserved)                       - 59. */
+    .long   0           /* (Unassigned, Reserved)                       - 60. */
+    .long   0           /* (Unassigned, Reserved)                       - 61. */
+    .long   0           /* (Unassigned, Reserved)                       - 62. */
+    .long   0           /* (Unassigned, Reserved)                       - 63. */
+    /*                  The assignment of these vectors to the CPM is         */
+    /*                  dependant on the configuration of the CPM vba         */
+    /*                          fields.                                       */
+    .long   0           /* (User-Defined Vectors 1) CPM Error           - 64. */
+    .long   0           /* (User-Defined Vectors 2) CPM Parallel IO PC11- 65. */
+    .long   0           /* (User-Defined Vectors 3) CPM Parallel IO PC10- 66. */
+    .long   0           /* (User-Defined Vectors 4) CPM SMC2 / PIP      - 67. */
+    .long   0           /* (User-Defined Vectors 5) CPM SMC1            - 68. */
+    .long   0           /* (User-Defined Vectors 6) CPM SPI             - 69. */
+    .long   0           /* (User-Defined Vectors 7) CPM Parallel IO PC9 - 70. */
+    .long   0           /* (User-Defined Vectors 8) CPM Timer 4         - 71. */
+    .long   0           /* (User-Defined Vectors 9) CPM Reserved        - 72. */
+    .long   0           /* (User-Defined Vectors 10) CPM Parallel IO PC8- 73. */
+    .long   0           /* (User-Defined Vectors 11) CPM Parallel IO PC7- 74. */
+    .long   0           /* (User-Defined Vectors 12) CPM Parallel IO PC6- 75. */
+    .long   0           /* (User-Defined Vectors 13) CPM Timer 3        - 76. */
+    .long   0           /* (User-Defined Vectors 14) CPM Reserved       - 77. */
+    .long   0           /* (User-Defined Vectors 15) CPM Parallel IO PC5- 78. */
+    .long   0           /* (User-Defined Vectors 16) CPM Parallel IO PC4- 79. */
+    .long   0           /* (User-Defined Vectors 17) CPM Reserved       - 80. */
+    .long   0           /* (User-Defined Vectors 18) CPM RISC Timer Tbl - 81. */
+    .long   0           /* (User-Defined Vectors 19) CPM Timer 2        - 82. */
+    .long   0           /* (User-Defined Vectors 21) CPM Reserved       - 83. */
+    .long   0           /* (User-Defined Vectors 22) CPM IDMA2          - 84. */
+    .long   0           /* (User-Defined Vectors 23) CPM IDMA1          - 85. */
+    .long   0           /* (User-Defined Vectors 24) CPM SDMA Bus Err   - 86. */
+    .long   0           /* (User-Defined Vectors 25) CPM Parallel IO PC3- 87. */
+    .long   0           /* (User-Defined Vectors 26) CPM Parallel IO PC2- 88. */
+    .long   0           /* (User-Defined Vectors 27) CPM Timer 1        - 89. */
+    .long   0           /* (User-Defined Vectors 28) CPM Parallel IO PC1- 90. */
+    .long   0           /* (User-Defined Vectors 29) CPM SCC 4          - 91. */
+    .long   0           /* (User-Defined Vectors 30) CPM SCC 3          - 92. */
+    .long   0           /* (User-Defined Vectors 31) CPM SCC 2          - 93. */
+    .long   0           /* (User-Defined Vectors 32) CPM SCC 1          - 94. */
+    .long   0           /* (User-Defined Vectors 33) CPM Parallel IO PC0- 95. */
+    /*                  I don't think anything uses the vectors after here.   */
+    .long   0           /* (User-Defined Vectors 34)                    - 96. */
+    .long   0,0,0,0,0               /* (User-Defined Vectors 35  -  39). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 40  -  49). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 50  -  59). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 60  -  69). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 70  -  79). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 80  -  89). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 90  -  99). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 100 - 109). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 110 - 119). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 120 - 129). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 130 - 139). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 140 - 149). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 150 - 159). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 160 - 169). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 170 - 179). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 180 - 189). */
+    .long   0,0,0                   /* (User-Defined Vectors 190 - 192). */
+.text
+ignore: rte
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/uCquicc/crt0_rom.S linux-2.4.29-uc1/arch/m68knommu/platform/68360/uCquicc/crt0_rom.S
--- linux-2.4.29/arch/m68knommu/platform/68360/uCquicc/crt0_rom.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/uCquicc/crt0_rom.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,425 @@
+/* arch/m68knommu/platform/68360/uCquicc/crt0_rom.S
+ *
+ * Startup code for Motorola 68360
+ *
+ * Copyright (C) SED Systems, a Division of Calian Ltd.
+ * Based on: arch/m68knommu/platform/68328/pilot/crt0_rom.S
+ * Based on: arch/m68knommu/platform/68360/uCquicc/crt0_rom.S, 2.0.38.1.pre7
+ *           uClinux Kernel
+ * Copyright (C) Michael Leslie <mleslie@ArcturusNetworks.com>
+ * Based on: arch/m68knommu/platform/68EZ328/ucsimm/crt0_rom.S
+ * Copyright (C) 1998  D. Jeff Dionne <jeff@uclinux.org>,
+ *
+ */
+#define ASSEMBLY
+#include <linux/config.h>
+
+.global _stext
+.global __bss_start
+.global _start
+
+.global _rambase
+.global __ramvec
+.global _ramvec
+.global _ramstart
+.global _ramend
+
+.global _quicc_base
+.global _periph_base
+.global _dprbase
+
+#define REGB                        0x1000
+#define PEPAR                       (_dprbase + REGB + 0x0016)
+#define GMR                         (_dprbase + REGB + 0x0040)
+#define OR0                         (_dprbase + REGB + 0x0054)
+#define BR0                         (_dprbase + REGB + 0x0050)
+
+#define OR1                         (_dprbase + REGB + 0x0064)
+#define BR1                         (_dprbase + REGB + 0x0060)
+
+#define OR2                         (_dprbase + REGB + 0x0074)
+#define BR2                         (_dprbase + REGB + 0x0070)
+
+#define OR3                         (_dprbase + REGB + 0x0084)
+#define BR3                         (_dprbase + REGB + 0x0080)
+
+#define OR4                         (_dprbase + REGB + 0x0094)
+#define BR4                         (_dprbase + REGB + 0x0090)
+
+#define OR5                         (_dprbase + REGB + 0x00A4)
+#define BR5                         (_dprbase + REGB + 0x00A0)
+
+#define OR6                         (_dprbase + REGB + 0x00b4)
+#define BR6                         (_dprbase + REGB + 0x00b0)
+
+#define OR7                         (_dprbase + REGB + 0x00c4)
+#define BR7                         (_dprbase + REGB + 0x00c0)
+
+#define MCR                         (_dprbase + REGB + 0x0000)
+#define AVR                         (_dprbase + REGB + 0x0008)
+
+#define SYPCR                       (_dprbase + REGB + 0x0022)
+
+#define PLLCR                       (_dprbase + REGB + 0x0010)
+#define CLKOCR                      (_dprbase + REGB + 0x000C)
+#define CDVCR                       (_dprbase + REGB + 0x0014)
+
+#define BKAR                        (_dprbase + REGB + 0x0030)
+#define BKCR                        (_dprbase + REGB + 0x0034)
+#define SWIV                        (_dprbase + REGB + 0x0023)
+#define PICR                        (_dprbase + REGB + 0x0026)
+#define PITR                        (_dprbase + REGB + 0x002A)
+
+/* Define for all memory configuration */
+#define MCU_SIM_GMR                 0x00000000
+#define SIM_OR_MASK                 0x0fffffff
+
+/* Defines for chip select zero - the flash */
+#define SIM_OR0_MASK                0x20000000
+#define SIM_BR0_MASK                0x00000001
+
+
+/* Defines for chip select one - the RAM */
+#define SIM_OR1_MASK                0x10000000
+#define SIM_BR1_MASK                0x00000001
+
+#define MCU_SIM_MBAR_ADRS           0x0003ff00
+#define MCU_SIM_MBAR_BA_MASK        0xfffff000
+#define MCU_SIM_MBAR_AS_MASK        0x00000001
+
+#define MCU_SIM_PEPAR               0x00B4
+    
+#define MCU_DISABLE_INTRPTS         0x2700
+#define MCU_SIM_AVR                 0x00
+    
+#define MCU_SIM_MCR                 0x00005cff
+
+#define MCU_SIM_CLKOCR              0x00
+#define MCU_SIM_PLLCR               0x8000
+#define MCU_SIM_CDVCR               0x0000
+
+#define MCU_SIM_SYPCR               0x0000
+#define MCU_SIM_SWIV                0x00
+#define MCU_SIM_PICR                0x0000
+#define MCU_SIM_PITR                0x0000
+
+
+#include <asm/m68360_regs.h>
+
+	
+/* By the time this RAM specific code begins to execute, DPRAM
+ * and DRAM should already be mapped and accessible. */
+
+	.text
+_start:
+_stext:
+    nop
+    ori.w   #MCU_DISABLE_INTRPTS,   %sr     /* disable interrupts: */
+    /* We should not need to setup the boot stack the reset should do it. */
+    movea.l	#_boot_stack,           %sp     /*set up stack at the end of DRAM:*/
+
+
+set_mbar_register:
+    moveq.l #0x07,                  %d1     /* Setup MBAR */
+    movec	%d1,                    %dfc
+
+    lea.l   MCU_SIM_MBAR_ADRS,      %a0
+    move.l  #_dprbase,              %d0
+    andi.l  #MCU_SIM_MBAR_BA_MASK,  %d0
+    ori.l   #MCU_SIM_MBAR_AS_MASK,  %d0
+    moves.l %d0,                    %a0@
+
+    moveq.l #0x05,                  %d1
+    movec.l %d1,                    %dfc
+
+/* Now we can begin to access registers in DPRAM */
+
+set_sim_mcr:
+    /* Set Module Configuration Register */
+    move.l  #MCU_SIM_MCR,           MCR
+
+/* to do:	Determine cause of reset */
+
+
+    /*
+    *       configure system clock MC68360 p. 6-40
+    *       (value +1)*osc/128 = system clock
+    *                    or
+    *       (value + 1)*osc = system clock
+    *       You do not need to divide the oscillator by 128 unless you want to.
+    */
+set_sim_clock:
+    move.w  #MCU_SIM_PLLCR,         PLLCR
+    move.b  #MCU_SIM_CLKOCR,        CLKOCR
+    move.w  #MCU_SIM_CDVCR,         CDVCR
+
+    // Wait for the PLL to settle
+    move.w      #16384, %d0
+pll_settle_wait:
+    subi.w       #1, %d0
+    bne	pll_settle_wait
+
+    /* Setup the system protection register, and watchdog timer register */
+
+    move.b      #MCU_SIM_SWIV,      SWIV
+    move.w      #MCU_SIM_PICR,      PICR
+    move.w      #MCU_SIM_PITR,      PITR
+    move.w      #MCU_SIM_SYPCR,     SYPCR
+
+/* Clear DPRAM - system + parameter */
+	movea.l	#_dprbase, %a0
+	movea.l	#_dprbase+0x2000, %a1
+
+	/* Copy 0 to %a0 until %a0 == %a1 */
+clear_dpram:
+	movel	#0, %a0@+
+	cmpal	%a0, %a1
+	bhi	clear_dpram
+
+configure_memory_controller:    
+    /*
+    *   Set up Global Memory Register (GMR)
+    */
+    move.l      #MCU_SIM_GMR,   %d0
+    move.l      %d0, GMR
+
+configure_chip_select_0:
+    move.l      #0x00400000,    %d0
+    subq.l      #0x01,          %d0
+    eori.l      #SIM_OR_MASK,   %d0
+    ori.l       #SIM_OR0_MASK,  %d0
+    move.l      %d0,            OR0
+
+    move.l      #__flashstart,  %d0
+    ori.l       #SIM_BR0_MASK,  %d0
+    move.l      %d0,            BR0
+
+    move.l      #0x0,           BR1
+    move.l      #0x0,           BR2
+    move.l      #0x0,           BR3
+    move.l      #0x0,           BR4
+    move.l      #0x0,           BR5
+    move.l      #0x0,           BR6
+    move.l      #0x0,           BR7
+
+    move.w      #MCU_SIM_PEPAR, PEPAR 
+
+/* point to vector table: */
+    move.l  #_romvec,   %a0
+    move.l	#_ramvec,   %a1
+copy_vectors:
+    move.l  %a0@,       %d0
+    move.l  %d0,        %a1@
+    move.l  %a0@,       %a1@
+    addq.l  #0x04,      %a0
+    addq.l  #0x04,      %a1
+    cmp.l   #_start,    %a0
+    blt     copy_vectors
+
+    move.l	#_ramvec, %a1
+    movec	%a1, %vbr
+
+
+	/* Copy data segment from ROM to RAM */
+	moveal	#__data_rom_start, %a0
+	moveal	#__data_start, %a1
+	moveal	#__data_end, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:
+    move.l  %a0@,   %d0
+    addq.l  #0x04,  %a0
+    move.l  %d0,    %a1@
+    addq.l  #0x04,  %a1
+    cmp.l   #__data_end,    %a1
+    blt     LD1
+
+	moveal	#__bss_start, %a0
+	moveal	#end, %a1
+
+	/* Copy 0 to %a0 until %a0 == %a1 */
+L1:
+	movel	#0, %a0@+
+	cmpal	%a0, %a1
+	bhi	L1
+
+load_quicc:
+    move.l  #_dprbase,  _quicc_base
+
+store_ram_size:
+    /* Set ram size information */
+    move.l  #_sdata,    _rambase
+    move.l  #end,       _ramstart
+    move.l  #__ramend,  %d0
+    sub.l   #0x1000,    %d0     /* Reserve 4K for stack space.*/
+    move.l  %d0,        _ramend /* Different from __ramend.*/
+
+store_flash_size:
+    /* Set rom size information */
+    move.l  #__flashend,    %d0
+    sub.l   #__flashstart,  %d0
+    move.l  %d0,            rom_length
+    
+	pea	0
+	pea	env
+	pea	%sp@(4)
+	pea	0
+
+    lea     init_task_union,    %a2
+    move.l  %a2,                _current_task
+    lea     0x2000(%a2),        %sp
+
+lp:
+    jsr	start_kernel
+ /*   jmp lp */
+
+_exit:
+
+	jmp	_exit
+
+
+
+	.data
+    .align 4
+env:
+	.long	0
+_quicc_base:
+	.long	0
+_periph_base:
+	.long	0
+_ramvec:
+    .long   0
+_rambase:
+    .long   0
+_ramstart:
+    .long   0
+_ramend:
+    .long   0
+	.text
+
+    /*
+     * These are the exception vectors at boot up, they are copied into RAM
+     * and then overwritten as needed.
+     */
+ 
+.section ".data.initvect","awx"
+    .long   _boot_stack /* Reset: Initial Stack Pointer                 - 0.  */
+    .long   _start      /* Reset: Initial Program Counter               - 1.  */
+    .long   buserr      /* Bus Error                                    - 2.  */
+    .long   trap        /* Address Error                                - 3.  */
+    .long   trap        /* Illegal Instruction                          - 4.  */
+    .long   trap        /* Divide by zero                               - 5.  */
+    .long   trap        /* CHK, CHK2 Instructions                       - 6.  */
+    .long   trap        /* TRAPcc, TRAPV Instructions                   - 7.  */
+    .long   trap        /* Privilege Violation                          - 8.  */
+    .long   trap        /* Trace                                        - 9.  */
+    .long   trap        /* Line 1010 Emulator                           - 10. */
+    .long   trap        /* Line 1111 Emualtor                           - 11. */
+    .long   trap        /* Harware Breakpoint                           - 12. */
+    .long   trap        /* (Reserved for Coprocessor Protocol Violation)- 13. */
+    .long   trap        /* Format Error                                 - 14. */
+    .long   trap        /* Uninitialized Interrupt                      - 15. */
+    .long   trap        /* (Unassigned, Reserver)                       - 16. */
+    .long   trap        /* (Unassigned, Reserver)                       - 17. */
+    .long   trap        /* (Unassigned, Reserver)                       - 18. */
+    .long   trap        /* (Unassigned, Reserver)                       - 19. */
+    .long   trap        /* (Unassigned, Reserver)                       - 20. */
+    .long   trap        /* (Unassigned, Reserver)                       - 21. */
+    .long   trap        /* (Unassigned, Reserver)                       - 22. */
+    .long   trap        /* (Unassigned, Reserver)                       - 23. */
+    .long   trap        /* Spurious Interrupt                           - 24. */
+    .long   trap        /* Level 1 Interrupt Autovector                 - 25. */
+    .long   trap        /* Level 2 Interrupt Autovector                 - 26. */
+    .long   trap        /* Level 3 Interrupt Autovector                 - 27. */
+    .long   trap        /* Level 4 Interrupt Autovector                 - 28. */
+    .long   trap        /* Level 5 Interrupt Autovector                 - 29. */
+    .long   trap        /* Level 6 Interrupt Autovector                 - 30. */
+    .long   trap        /* Level 7 Interrupt Autovector                 - 31. */
+    .long   system_call /* Trap Instruction Vectors 0                   - 32. */
+    .long   trap        /* Trap Instruction Vectors 1                   - 33. */
+    .long   trap        /* Trap Instruction Vectors 2                   - 34. */
+    .long   trap        /* Trap Instruction Vectors 3                   - 35. */
+    .long   trap        /* Trap Instruction Vectors 4                   - 36. */
+    .long   trap        /* Trap Instruction Vectors 5                   - 37. */
+    .long   trap        /* Trap Instruction Vectors 6                   - 38. */
+    .long   trap        /* Trap Instruction Vectors 7                   - 39. */
+    .long   trap        /* Trap Instruction Vectors 8                   - 40. */
+    .long   trap        /* Trap Instruction Vectors 9                   - 41. */
+    .long   trap        /* Trap Instruction Vectors 10                  - 42. */
+    .long   trap        /* Trap Instruction Vectors 11                  - 43. */
+    .long   trap        /* Trap Instruction Vectors 12                  - 44. */
+    .long   trap        /* Trap Instruction Vectors 13                  - 45. */
+    .long   trap        /* Trap Instruction Vectors 14                  - 46. */
+    .long   trap        /* Trap Instruction Vectors 15                  - 47. */
+    .long   0           /* (Reserved for Coprocessor)                   - 48. */
+    .long   0           /* (Reserved for Coprocessor)                   - 49. */
+    .long   0           /* (Reserved for Coprocessor)                   - 50. */
+    .long   0           /* (Reserved for Coprocessor)                   - 51. */
+    .long   0           /* (Reserved for Coprocessor)                   - 52. */
+    .long   0           /* (Reserved for Coprocessor)                   - 53. */
+    .long   0           /* (Reserved for Coprocessor)                   - 54. */
+    .long   0           /* (Reserved for Coprocessor)                   - 55. */
+    .long   0           /* (Reserved for Coprocessor)                   - 56. */
+    .long   0           /* (Reserved for Coprocessor)                   - 57. */
+    .long   0           /* (Reserved for Coprocessor)                   - 58. */
+    .long   0           /* (Unassigned, Reserved)                       - 59. */
+    .long   0           /* (Unassigned, Reserved)                       - 60. */
+    .long   0           /* (Unassigned, Reserved)                       - 61. */
+    .long   0           /* (Unassigned, Reserved)                       - 62. */
+    .long   0           /* (Unassigned, Reserved)                       - 63. */
+    /*                  The assignment of these vectors to the CPM is         */
+    /*                  dependant on the configuration of the CPM vba         */
+    /*                          fields.                                       */
+    .long   0           /* (User-Defined Vectors 1) CPM Error           - 64. */
+    .long   0           /* (User-Defined Vectors 2) CPM Parallel IO PC11- 65. */
+    .long   0           /* (User-Defined Vectors 3) CPM Parallel IO PC10- 66. */
+    .long   0           /* (User-Defined Vectors 4) CPM SMC2 / PIP      - 67. */
+    .long   0           /* (User-Defined Vectors 5) CPM SMC1            - 68. */
+    .long   0           /* (User-Defined Vectors 6) CPM SPI             - 69. */
+    .long   0           /* (User-Defined Vectors 7) CPM Parallel IO PC9 - 70. */
+    .long   0           /* (User-Defined Vectors 8) CPM Timer 4         - 71. */
+    .long   0           /* (User-Defined Vectors 9) CPM Reserved        - 72. */
+    .long   0           /* (User-Defined Vectors 10) CPM Parallel IO PC8- 73. */
+    .long   0           /* (User-Defined Vectors 11) CPM Parallel IO PC7- 74. */
+    .long   0           /* (User-Defined Vectors 12) CPM Parallel IO PC6- 75. */
+    .long   0           /* (User-Defined Vectors 13) CPM Timer 3        - 76. */
+    .long   0           /* (User-Defined Vectors 14) CPM Reserved       - 77. */
+    .long   0           /* (User-Defined Vectors 15) CPM Parallel IO PC5- 78. */
+    .long   0           /* (User-Defined Vectors 16) CPM Parallel IO PC4- 79. */
+    .long   0           /* (User-Defined Vectors 17) CPM Reserved       - 80. */
+    .long   0           /* (User-Defined Vectors 18) CPM RISC Timer Tbl - 81. */
+    .long   0           /* (User-Defined Vectors 19) CPM Timer 2        - 82. */
+    .long   0           /* (User-Defined Vectors 21) CPM Reserved       - 83. */
+    .long   0           /* (User-Defined Vectors 22) CPM IDMA2          - 84. */
+    .long   0           /* (User-Defined Vectors 23) CPM IDMA1          - 85. */
+    .long   0           /* (User-Defined Vectors 24) CPM SDMA Bus Err   - 86. */
+    .long   0           /* (User-Defined Vectors 25) CPM Parallel IO PC3- 87. */
+    .long   0           /* (User-Defined Vectors 26) CPM Parallel IO PC2- 88. */
+    .long   0           /* (User-Defined Vectors 27) CPM Timer 1        - 89. */
+    .long   0           /* (User-Defined Vectors 28) CPM Parallel IO PC1- 90. */
+    .long   0           /* (User-Defined Vectors 29) CPM SCC 4          - 91. */
+    .long   0           /* (User-Defined Vectors 30) CPM SCC 3          - 92. */
+    .long   0           /* (User-Defined Vectors 31) CPM SCC 2          - 93. */
+    .long   0           /* (User-Defined Vectors 32) CPM SCC 1          - 94. */
+    .long   0           /* (User-Defined Vectors 33) CPM Parallel IO PC0- 95. */
+    /*                  I don't think anything uses the vectors after here.   */
+    .long   0           /* (User-Defined Vectors 34)                    - 96. */
+    .long   0,0,0,0,0               /* (User-Defined Vectors 35  -  39). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 40  -  49). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 50  -  59). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 60  -  69). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 70  -  79). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 80  -  89). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 90  -  99). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 100 - 109). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 110 - 119). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 120 - 129). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 130 - 139). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 140 - 149). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 150 - 159). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 160 - 169). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 170 - 179). */
+    .long   0,0,0,0,0,0,0,0,0,0     /* (User-Defined Vectors 180 - 189). */
+    .long   0,0,0                   /* (User-Defined Vectors 190 - 192). */
+.text
+ignore: rte
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/uCquicc/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/68360/uCquicc/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/68360/uCquicc/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/uCquicc/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,105 @@
+MEMORY
+{
+    romvec   : ORIGIN = 0x00000000,                 LENGTH = 1028
+    flash    : ORIGIN = 1028,                       LENGTH = 0x00080000 - 1028
+    eflash   : ORIGIN = 0x00000000 + 0x00100000,    LENGTH = 1
+    ramvec   : ORIGIN = 0x00200000,                 LENGTH = 1028
+    ram      : ORIGIN = 0x00200000 + 1028,          LENGTH = 0x00080000 - 1028
+    eram     : ORIGIN = 0x00200000 + 0x00080000,    LENGTH = 1
+    dpram    : ORIGIN = 0xffffe000,                 LENGTH = 0x00002000
+}
+
+SECTIONS
+{
+    .dpram :
+    {
+        _dprbase = . ;
+    } > dpram
+
+    .romvec :
+    {
+        _romvec = . ;
+        __flashstart = . ;
+        *(.data.initvect)
+        . = ALIGN(4);
+    } > romvec
+
+    .text :
+    {
+        text_start = . ;
+        *(.text)
+        *(.text.*)
+        *(.rodata)
+	*(.rodata.str1.1)
+        *(.fixup)
+	*(.kstrtab)
+	__start___ksymtab = . ;
+	*(__ksymtab)
+        __stop___ksymtab = . ;
+	__start___ex_table = . ;
+	*(___ex_table)
+	__stop___ex_table = . ;
+        . = ALIGN(4) ;_etext = . ;
+        __data_rom_start = ALIGN ( 4 ) ;
+    } > flash
+   
+    .eflash :
+    {
+        __flashend = . ;
+    } > eflash
+
+
+    .ramvec :
+    {
+        __ramstart = . ;
+        _ramvec = . ;
+    } > ramvec
+   
+    .data :
+    {
+        _sdata = . ;
+        __data_start = . ;
+       . = ALIGN(0x2000) ;
+       *(.data.init_task)
+       . = ALIGN(0x2000) ;
+        *(.data)
+        *(.data.*)
+        *(.setup.init)
+       *(.exitcall.exit)
+       . = ALIGN(4096) ;
+        __init_begin = .;
+        *(.text.init)
+        *(.data.init)
+        . = ALIGN(16);
+        __setup_start = .;
+        *(.setup.init)
+        __setup_end = .;
+        __initcall_start = .;
+        *(.initcall.init)
+        . = ALIGN(4) ;
+        __initcall_end = .;
+	__init_end = .;      
+        _edata = . ;
+        edata = .;
+    } > ram
+
+    .bss :
+    {
+        _sbss = ALIGN( 0x10 ) ;
+        __bss_start = ALIGN( 0x10 ) ;
+        __data_end = ALIGN( 0x10 ) ;
+        *(.bss)
+        *(COMMON)
+            _ebss = . ;
+        __bss_end = . ;
+        end = ALIGN( 0x10 ) ;
+        _end = ALIGN( 0x10 ) ;
+    } > ram
+
+    .eram :
+    {
+        _boot_stack = . - 4;
+        __ramend = . ;
+
+    } > eram
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68360/uCquicc/rom.ld linux-2.4.29-uc1/arch/m68knommu/platform/68360/uCquicc/rom.ld
--- linux-2.4.29/arch/m68knommu/platform/68360/uCquicc/rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68360/uCquicc/rom.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,105 @@
+MEMORY
+{
+    romvec   : ORIGIN = 0x00000000,                 LENGTH = 1028
+    flash    : ORIGIN = 1028,                       LENGTH = 0x00200000 - 1028
+    eflash   : ORIGIN = 0x00000000 + 0x00200000,    LENGTH = 1
+    ramvec   : ORIGIN = 0x00200000,                 LENGTH = 1028
+    ram      : ORIGIN = 0x00200000 + 1028,          LENGTH = 0x00200000 - 1028
+    eram     : ORIGIN = 0x00200000 + 0x00200000,    LENGTH = 1
+    dpram    : ORIGIN = 0xffffe000,                 LENGTH = 0x00002000
+}
+
+SECTIONS
+{
+    .dpram :
+    {
+        _dprbase = . ;
+    } > dpram
+
+    .romvec :
+    {
+        _romvec = . ;
+        __flashstart = . ;
+        *(.data.initvect)
+        . = ALIGN(4);
+    } > romvec
+
+    .text :
+    {
+        text_start = . ;
+        *(.text)
+        *(.text.*)
+        *(.rodata)
+	*(.rodata.str1.1)
+        *(.fixup)
+        *(.kstrtab)
+        __start___ksymtab = . ;
+        *(__ksymtab)
+        __stop___ksymtab = . ;
+        __start___ex_table = . ;
+        *(___ex_table)
+        __stop___ex_table = . ;
+        . = ALIGN(4) ;_etext = . ;
+        __data_rom_start = ALIGN ( 4 ) ;
+    } > flash
+   
+    .eflash :
+    {
+        __flashend = . ;
+    } > eflash
+
+
+    .ramvec :
+    {
+        __ramstart = . ;
+        _ramvec = . ;
+    } > ramvec
+   
+    .data :
+    {
+        _sdata = . ;
+        __data_start = . ;
+       . = ALIGN(0x2000) ;
+       *(.data.init_task)
+       . = ALIGN(0x2000) ;
+        *(.data)
+        *(.data.*)
+        *(.setup.init)
+       *(.exitcall.exit)
+       . = ALIGN(4096) ;
+        __init_begin = .;
+        *(.text.init)
+        *(.data.init)
+        . = ALIGN(16);
+        __setup_start = .;
+        *(.setup.init)
+        __setup_end = .;
+        __initcall_start = .;
+        *(.initcall.init)
+        . = ALIGN(4) ;
+        __initcall_end = .;
+        __init_end = .;      
+        _edata = . ;
+        edata = .;
+    } > ram
+
+    .bss :
+    {
+        _sbss = ALIGN( 0x10 ) ;
+        __bss_start = ALIGN( 0x10 ) ;
+        __data_end = ALIGN( 0x10 ) ;
+        *(.bss)
+        *(COMMON)
+        _ebss = . ;
+        __bss_end = . ;
+        end = ALIGN( 0x10 ) ;
+        _end = ALIGN( 0x10 ) ;
+    } > ram
+
+    .eram :
+    {
+        _boot_stack = . - 4;
+        __ramend = . ;
+
+    } > eram
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/config.c linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/config.c
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/config.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,157 @@
+/*
+ *  linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999 D. Jeff Dionne
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#ifdef CONFIG_UCSIMM
+#include "ucsimm/bootstd.h"
+#endif
+#ifdef CONFIG_PILOT
+#include "PalmV/romfs.h"
+#endif
+#include <asm/MC68EZ328.h>
+
+void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
+{
+#ifdef CONFIG_M68EZ328_USE_RTC
+  /* Enable RTC */
+  RTCCTL |= RTCCTL_EN;
+
+  /* Enable 128 Hz interrupt line */
+  RTCIENR |= RTCIENR_SAM5;
+
+  request_irq(SAM_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+#else
+  /* Restart mode, Enable int, 32KHz, Enable timer */
+  TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
+  /* Set prescaler (Divide 32KHz by 32)*/
+  TPRER = 31;
+  /* Set compare register  32Khz / 32 / 10 = 100 */
+  TCMP = 10;                                                              
+
+  request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);  
+#endif
+}
+
+void BSP_tick(void)
+{
+  	/* Reset Timer1 */
+#ifdef CONFIG_M68EZ328_USE_RTC
+	RTCISR |= RTCISR_SAM5;
+#else
+  	TSTAT &= 0;
+#endif
+}
+
+unsigned long BSP_gettimeoffset (void)
+{
+  return 0;
+}
+
+void BSP_gettod (int *yearp, int *monp, int *dayp,
+		   int *hourp, int *minp, int *secp)
+{
+	*yearp = *monp = *dayp = *hourp = *minp = *secp = 0;
+}
+
+int BSP_hwclk(int op, struct hwclk_time *t)
+{
+  if (!op) {
+    /* read */
+  } else {
+    /* write */
+  }
+  return 0;
+}
+
+int BSP_set_clock_mmss (unsigned long nowtime)
+{
+#if 0
+  short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+
+  tod->second1 = real_seconds / 10;
+  tod->second2 = real_seconds % 10;
+  tod->minute1 = real_minutes / 10;
+  tod->minute2 = real_minutes % 10;
+#endif
+  return 0;
+}
+
+void BSP_reset (void)
+{
+  cli();
+  asm volatile ("
+    moveal #0x10c00000, %a0;
+    moveb #0, 0xFFFFF300;
+    moveal 0(%a0), %sp;
+    moveal 4(%a0), %a0;
+    jmp (%a0);
+    ");
+}
+
+unsigned char *cs8900a_hwaddr;
+static int errno;
+
+#ifdef CONFIG_UCSIMM
+_bsc0(char *, getserialnum)
+_bsc1(unsigned char *, gethwaddr, int, a)
+_bsc1(char *, getbenv, char *, a)
+#endif
+
+void config_BSP(char *command, int len)
+{
+  unsigned char *p;
+
+  printk("\n68EZ328 DragonBallEZ support (C) 1999 Rt-Control, Inc\n");
+
+#ifdef CONFIG_UCSIMM
+  printk("uCsimm serial string [%s]\n",getserialnum());
+  p = cs8900a_hwaddr = gethwaddr(0);
+  printk("uCsimm hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+         p[0],
+         p[1],
+         p[2],
+         p[3],
+         p[4],
+         p[5]);
+
+  p = getbenv("APPEND");
+  if (p) strcpy(p,command);
+  else command[0] = 0;
+#endif
+
+#ifdef CONFIG_CWEZ328
+    strcpy(command, "/bin/sh console=ttyS0");
+#endif
+
+  mach_sched_init      = BSP_sched_init;
+  mach_tick            = BSP_tick;
+  mach_gettimeoffset   = BSP_gettimeoffset;
+  mach_gettod          = BSP_gettod;
+  mach_hwclk           = NULL;
+  mach_set_clock_mmss  = NULL;
+  // mach_mksound         = NULL;
+  mach_reset           = BSP_reset;
+  // mach_debug_init      = NULL;
+
+  config_M68EZ328_irq();
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/bootlogo.h linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/bootlogo.h
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/bootlogo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/bootlogo.h	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,3204 @@
+#define splash_width 640
+#define splash_height 480
+static unsigned char splash_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf8, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x7f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xfe, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x7c, 0x00, 0xe0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0xe0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3e, 0xf8, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
+  0x00, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0xfe, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+  0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xe0, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff, 0x07, 0xfe, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0x01, 0xf8, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff,
+  0x00, 0xf0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0xe0, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x03,
+  0x3f, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x3f, 0x00, 0xc0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x0f, 0xfc, 0x00, 0x00, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f,
+  0x00, 0x80, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xff, 0xff, 0x3f, 0xf0, 0x01, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x80, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0xc0, 0xff,
+  0xc1, 0x03, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x07, 0x00, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f,
+  0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x07, 0x00, 0x00, 0xe0, 0x07, 0x0e, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x00,
+  0x3f, 0x1c, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x38, 0x00, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f,
+  0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e,
+  0x00, 0x00, 0x00, 0x00, 0x78, 0x70, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xe0, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc3, 0x01, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f,
+  0x00, 0x80, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x80, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x87, 0x03, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x3f, 0x00, 0xc0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x07, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f,
+  0x00, 0xe0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0e, 0x00, 0xf0, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf0, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x30, 0x0c, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0x01, 0xf8, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1c, 0x00,
+  0xf0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x07, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x38, 0x00, 0xf0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0x38, 0x00, 0xf0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00,
+  0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0xe0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe2, 0x00, 0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00,
+  0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0xc0, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x01, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01,
+  0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x80, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x03, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03,
+  0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07,
+  0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0xfe, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07,
+  0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0xf8, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07,
+  0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0xf0, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x07, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x9f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+  0xf8, 0xff, 0x1f, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0xff, 0xff, 0x00,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x38, 0x00, 0xfe, 0xff, 0x0f, 0x20, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0xf8, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xc0, 0xff, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0xfc, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0xe0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff,
+  0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xfc, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x1f, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+  0xfe, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xf0, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x38, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0xf8, 0xff, 0x01, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xc0, 0xff, 0x01,
+  0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0xfc, 0x01, 0xff, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x41, 0x08, 0x04, 0xb3, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0xe0, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x41, 0x08, 0x04, 0xb3, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x8e, 0x31, 0x7b, 0x30,
+  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x18, 0x8e, 0x31, 0x7b, 0x30, 0x30, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0xf8,
+  0x41, 0xc6, 0x84, 0x0c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0xf8, 0x41, 0xc6, 0x84, 0x0c,
+  0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x0f, 0x00, 0x00, 0x18, 0x0c, 0x08, 0x00, 0x40, 0xc0, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xe4,
+  0xb1, 0xc1, 0x98, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xe4, 0xb1, 0xc1, 0x98, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+  0x08, 0x00, 0x00, 0x1c, 0x02, 0x08, 0x04, 0x4c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0xff, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1c,
+  0x02, 0x08, 0x04, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x1f, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x10, 0x80,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x64, 0x4c, 0x00, 0x00, 0x00,
+  0x36, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x09, 0x00, 0x00, 0x64, 0x4c, 0x00, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x9c,
+  0x01, 0x08, 0x83, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0xf0, 0xff,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x64, 0x8c, 0x01, 0x18, 0x40,
+  0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x0f, 0x00, 0x00, 0x64, 0x8c, 0x01, 0x18, 0x40, 0x30, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0x03, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x9b,
+  0x01, 0xc0, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x40,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0x9b, 0x01, 0xc0, 0x00, 0x00,
+  0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+  0x00, 0x00, 0x00, 0x07, 0x32, 0x06, 0x18, 0x43, 0x00, 0x06, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf0, 0xc1, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x02, 0x02, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x07,
+  0x32, 0x06, 0x18, 0x43, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x10, 0xe0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x7b, 0x00, 0x30, 0x03, 0x0c,
+  0x08, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x07, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x09, 0x00, 0xc0, 0x84, 0x8d, 0x01, 0x80, 0x00, 0xc0, 0x06, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xfd, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xc0, 0x84,
+  0x8d, 0x01, 0x80, 0x00, 0xc0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfd, 0x03, 0xf0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc0, 0x1b, 0x00, 0x30, 0x00, 0x40,
+  0x08, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xfc, 0x01, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0xc0, 0x1b, 0x00, 0x30, 0x00, 0x40, 0x08, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x07, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+  0xf8, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc0, 0x64,
+  0x42, 0x06, 0x1b, 0x03, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x10, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0x64, 0x42, 0x06, 0x1b, 0x03,
+  0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0x03, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x0f, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x80, 0x30, 0x08, 0x86, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x3f, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x1b,
+  0x00, 0x00, 0x80, 0x30, 0x08, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xc3, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0xe0, 0x84, 0x31, 0x30, 0x04, 0x80,
+  0xc1, 0x18, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x09, 0x00, 0xc0, 0x63, 0x02, 0x06, 0x00, 0x00, 0x00, 0x60, 0x6c, 0xfc,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+  0xe0, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x08, 0x00, 0xc0, 0x63,
+  0x02, 0x06, 0x00, 0x00, 0x00, 0x60, 0x6c, 0xfc, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xe0, 0x1c, 0x40, 0x00, 0x1b, 0x4c,
+  0x06, 0x81, 0x80, 0xfd, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x00, 0xf0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0xe0, 0x1c, 0x40, 0x00, 0x1b, 0x4c, 0x06, 0x81, 0x80, 0xfd,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x00, 0x80, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x09, 0x00, 0x20, 0x63,
+  0x0c, 0x08, 0x80, 0x00, 0x30, 0x06, 0x0c, 0xfc, 0xff, 0x7f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x30, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x20, 0x63, 0x0c, 0x08, 0x80, 0x00,
+  0x30, 0x06, 0x0c, 0xfc, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x0f, 0x00, 0xd8, 0x84, 0x01, 0xc0, 0x00, 0x00, 0x06, 0x00, 0x80, 0xf1,
+  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0xf8, 0x1b,
+  0x40, 0x08, 0x84, 0x0c, 0xc0, 0x18, 0x13, 0xcc, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xe0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0xf8, 0x1b, 0x40, 0x08, 0x84, 0x0c,
+  0xc0, 0x18, 0x13, 0xcc, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0xf0, 0xe4, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x09, 0x00, 0x38, 0x80, 0x01, 0x00, 0x18, 0x30, 0x06, 0x01, 0x00, 0xc0,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+  0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x07, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x38, 0x80,
+  0x01, 0x00, 0x18, 0x30, 0x06, 0x01, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x10, 0x84,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xd8, 0x1f, 0x30, 0x36, 0x80, 0x00,
+  0x00, 0x00, 0x03, 0xf2, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x4f, 0x0e, 0x00, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x08, 0x00, 0xd8, 0x1f, 0x30, 0x36, 0x80, 0x00, 0x00, 0x00, 0x03, 0xf2,
+  0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+  0x08, 0x00, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x09, 0x00, 0x3e, 0x00,
+  0x82, 0x01, 0x03, 0x40, 0x30, 0x98, 0x10, 0xf0, 0xe7, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x1f, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0x00, 0x10, 0xe4,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xe6, 0x1b, 0x00, 0x00, 0x18, 0x0c,
+  0x00, 0x00, 0x00, 0xfc, 0xff, 0xfb, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x41, 0x08, 0x00, 0x30, 0x7c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0xe6, 0x1b, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0xfc,
+  0xff, 0xfb, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+  0x08, 0x00, 0x20, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1e, 0x64,
+  0x30, 0xc6, 0x80, 0x80, 0x09, 0x06, 0x63, 0xfe, 0xf9, 0xff, 0xff, 0xff,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x30, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xf8, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0e, 0x00, 0xc0, 0x3c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1e, 0x64, 0x30, 0xc6, 0x80, 0x80,
+  0x09, 0x06, 0x63, 0xfe, 0xf9, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc3, 0x07, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0e, 0x00, 0x39, 0x03, 0x00, 0x00, 0x04, 0x0c, 0xc0, 0x60, 0x80, 0x3f,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0xfc, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x39, 0x03,
+  0x00, 0x00, 0x04, 0x0c, 0xc0, 0x60, 0x80, 0x3f, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3e, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x80, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0xe7, 0x04, 0x42, 0xc6, 0x00, 0x00,
+  0x00, 0x00, 0xec, 0xcf, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x0f, 0xc0, 0x1f, 0x80, 0x01, 0x00, 0x98, 0x4c, 0x06, 0x06, 0xf0, 0x01,
+  0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x01, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x09, 0xc0, 0x1f, 0x80,
+  0x01, 0x00, 0x98, 0x4c, 0x06, 0x06, 0xf0, 0x01, 0x00, 0xe0, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3f, 0x08, 0xc0, 0xe6, 0x04, 0x0c, 0x08, 0x00, 0x00,
+  0xc0, 0x60, 0x7c, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x1f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
+  0x00, 0xc0, 0xe6, 0x04, 0x0c, 0x08, 0x00, 0x00, 0xc0, 0x60, 0x7c, 0x00,
+  0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xc0, 0x19, 0x60,
+  0x40, 0x00, 0x63, 0x30, 0x08, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xf3, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x09, 0xc0, 0x19, 0x60, 0x40, 0x00, 0x63, 0x30,
+  0x08, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xf3, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x78, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0f, 0xc0, 0x27, 0x03, 0x00, 0x30, 0x00, 0x03, 0x00, 0xe6, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0xcf, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xc0, 0x27, 0x03,
+  0x00, 0x30, 0x00, 0x03, 0x00, 0xe6, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x0f, 0xc0, 0xde, 0x04, 0x0c, 0x06, 0x03, 0x80,
+  0xc1, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0f, 0x03, 0x00, 0xf8, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x0f, 0xc0, 0x19, 0x00, 0x32, 0x00, 0x60, 0x30, 0x08, 0xff, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9f,
+  0x07, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x09, 0xc0, 0x19, 0x00,
+  0x32, 0x00, 0x60, 0x30, 0x08, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9f, 0x07, 0x00, 0x18, 0x40,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3f, 0x00, 0xc0, 0x27, 0x63, 0x80, 0x31, 0x04, 0x03,
+  0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+  0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0xfe, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x1f, 0x07, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
+  0x00, 0xc0, 0x27, 0x63, 0x80, 0x31, 0x04, 0x03, 0xf0, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0x7f, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+  0xe0, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x31,
+  0x04, 0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0xd9, 0x04,
+  0x00, 0x08, 0x00, 0x80, 0xf9, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf0, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x1e, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0xfe, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x04, 0x00, 0x60, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x09, 0x00, 0xd9, 0x04, 0x00, 0x08, 0x00, 0x80,
+  0xf9, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x7f, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x78, 0x00, 0xf0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0f, 0xc0, 0x27, 0x00, 0x30, 0xc0, 0x60, 0xb0, 0xff, 0x7f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x60, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0xde, 0x9b,
+  0x8d, 0x01, 0x04, 0xc3, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0xf1, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x03, 0x00, 0xf0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0xde, 0x9b, 0x8d, 0x01, 0x04, 0xc3,
+  0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf1, 0xff,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3e, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0x39, 0x04, 0x00, 0xc8, 0x00, 0xfc, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xf8, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0x39, 0x04,
+  0x00, 0xc8, 0x00, 0xfc, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc6, 0xf8, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0xc0, 0xc7, 0x60, 0x42, 0x00, 0x60, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+  0x00, 0xc0, 0xc7, 0x60, 0x42, 0x00, 0x60, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0xc0, 0xff, 0x07,
+  0xb0, 0x09, 0xe4, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x30, 0x00, 0xfc, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0xde, 0x78, 0x02, 0x00, 0xfb, 0xff,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f, 0xf0, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0xde, 0x78, 0x02, 0x00, 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x1f, 0xf8,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x08,
+  0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x3f, 0x07,
+  0xb0, 0xc9, 0xf8, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x3f, 0x07, 0xb0, 0xc9, 0xf8, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
+  0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x0f, 0x00, 0xe7, 0xfb, 0x43, 0x30, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0xe7, 0xfb,
+  0x43, 0x30, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0xe0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xfe, 0x1c, 0xb2, 0x0f, 0xe0, 0xff,
+  0x07, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0xf8, 0xe7, 0xfd, 0x01, 0xe0, 0xff, 0x07, 0x00, 0xe0, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xe0,
+  0xb1, 0x3f, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xf8,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xc0, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xf8, 0xe7,
+  0xfd, 0x01, 0xe0, 0xff, 0x07, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xe0, 0xb1, 0x3f, 0x00, 0x00,
+  0xf8, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x80, 0xff,
+  0x01, 0x00, 0xe0, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x98, 0x4f, 0x0e, 0x18, 0x00, 0xf8, 0xff, 0xff, 0xff,
+  0x07, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x80, 0xff, 0x01, 0x00, 0xe0, 0x03,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+  0x4f, 0x0e, 0xf8, 0x1f, 0xf6, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xf8, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb1, 0x01, 0xff, 0x1f,
+  0xf6, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xb1, 0x01, 0xff, 0x7f, 0xc0, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0xe0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
+  0x00, 0xce, 0xff, 0x7f, 0xc0, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0xe3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xe0, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0xce, 0xff, 0x7f,
+  0x00, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xc0, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x20, 0x1b, 0xb2, 0x31, 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0xe0, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x01, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0xc0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x1c,
+  0x00, 0xc0, 0xff, 0x73, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf0,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
+  0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xc0, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x1c, 0x00, 0xc0, 0x7f, 0x1c,
+  0x30, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x78, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x38, 0x87, 0x31, 0x06, 0x7c, 0x1c, 0x30, 0xff, 0xff, 0xff,
+  0xff, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x87,
+  0x31, 0x06, 0xfc, 0x0f, 0xc8, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x38,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+  0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe6, 0x04, 0x00, 0x30, 0xe3, 0x0f,
+  0xc8, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xe0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x30, 0xe6, 0x04, 0x00, 0x30, 0x03, 0x00, 0xf0, 0xff, 0xff, 0xff,
+  0xff, 0x03, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x07, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1b,
+  0x4c, 0x00, 0x04, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0xc0, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x07, 0x04, 0x00, 0x06, 0x18, 0x80,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0f, 0x0e, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x02, 0x07, 0x04, 0x00, 0x06, 0x78, 0xf3, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x08, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3e, 0x04,
+  0x02, 0x30, 0x60, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xf8,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0xc0, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3e, 0x04, 0x02, 0x30, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc6, 0x04, 0x40, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x04,
+  0x40, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x08,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x67, 0x00, 0x06, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x06, 0x04, 0x30, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04,
+  0x30, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x08,
+  0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x7e, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3e, 0x9b, 0x01, 0x30, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x30, 0x3e, 0x9b, 0x01, 0x30, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x1c, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x02, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x01, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x1c,
+  0x0c, 0x06, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x38,
+  0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xe0,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0xf0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x1c, 0x0c, 0x06, 0xfb, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x68, 0x7c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf8, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x38, 0x18, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x18, 0xfe, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0x03, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc6, 0x9b,
+  0x81, 0x01, 0x60, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x80,
+  0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xc0, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc6, 0x9b, 0x81, 0x01, 0x00, 0x00,
+  0xf6, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x38, 0x78, 0x0c, 0x30, 0x04, 0x00, 0xf6, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0xe8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x78,
+  0x0c, 0x30, 0x04, 0x00, 0xc8, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xf8,
+  0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x64, 0x40, 0x00, 0x1c, 0x00,
+  0xc8, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xf8, 0x58, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x64, 0x40, 0x00, 0xfc, 0x03, 0xc0, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x78, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe0,
+  0x01, 0x36, 0xfc, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x38,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe0, 0x01, 0x36, 0xfc, 0x1f,
+  0x30, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x8f, 0x01, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc6, 0x87, 0x0f, 0x00, 0xff, 0x1f, 0x30, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xcf, 0x03, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+  0x40, 0xc0, 0xff, 0x7f, 0xc0, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xcf, 0x03, 0x00, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xc0, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x40, 0xc0, 0xff, 0x7f,
+  0x00, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x8f, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x0e, 0xc6, 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x0e, 0xc6, 0xff, 0x7f, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0xf0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x9c, 0x01, 0x30, 0xff, 0x7f,
+  0x00, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x20, 0x9c, 0x01, 0x30, 0xff, 0x63, 0x30, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x07, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+  0x4c, 0x00, 0xff, 0x63, 0x30, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x31, 0xfc, 0x1f,
+  0x00, 0xff, 0xff, 0xfd, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xb2, 0x31, 0xfc, 0x0f, 0x00, 0xff, 0xff, 0x03,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+  0x41, 0x00, 0xe0, 0x0f, 0x00, 0xff, 0xff, 0x03, 0xff, 0x03, 0x00, 0x38,
+  0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x41, 0x00, 0x00, 0x80,
+  0xc9, 0xf9, 0xff, 0x3d, 0xff, 0x03, 0x00, 0x78, 0xc0, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x60, 0x32, 0x08, 0x00, 0x80, 0xc9, 0xf9, 0xff, 0x3d,
+  0xff, 0x03, 0x00, 0xf8, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x02, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+  0x32, 0x08, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xcf, 0xff, 0x00, 0x00, 0xf8,
+  0x81, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0xff,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe0, 0x01, 0xf8, 0x00, 0x00,
+  0xf0, 0xff, 0xff, 0xcf, 0xff, 0x00, 0x00, 0x38, 0x03, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x60, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x03, 0x80, 0xff, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0x38, 0x06, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0c, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xff, 0x03, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x38,
+  0x1e, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x03, 0xfc,
+  0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x38, 0xfc, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x1f, 0x00, 0x00, 0x38, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+  0x80, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x78,
+  0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe0, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xf8, 0xc1, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x60, 0xf8, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
+  0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xc0, 0xff,
+  0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x67,
+  0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x13, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc0, 0xff,
+  0xff, 0xff, 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x67, 0xfe, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xff, 0xff, 0x98, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
+  0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x0f, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x98,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xf8, 0xff,
+  0xff, 0xff, 0x7f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x3f, 0xe7, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xff, 0xfc, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0xff, 0x3f, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x00, 0xc0, 0xff, 0x67, 0x8c, 0xf9, 0xfb, 0x73, 0x00, 0x67, 0x10, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xf8,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xc0, 0xff, 0x67,
+  0x8c, 0xf9, 0xfb, 0x73, 0x00, 0x67, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0xe7, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0xc0, 0x27, 0xfc, 0x73, 0xc6, 0x1c, 0x8c,
+  0x37, 0x80, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff,
+  0xff, 0xff, 0x1f, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0xc0, 0x27, 0xfc, 0x73, 0xc6, 0x1c, 0x8c, 0x37, 0x80, 0x0c, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xfc,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0xc0, 0xfe, 0x03,
+  0x8c, 0x09, 0xe3, 0x73, 0xc8, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0xc0, 0xfe, 0x03, 0x8c, 0x09, 0xe3, 0x73,
+  0xc8, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0xc0, 0x27, 0xe7, 0x31, 0x36, 0x04, 0x8c, 0x01, 0x60, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0xc0, 0xde, 0x18,
+  0x42, 0xc0, 0x98, 0x30, 0x08, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0xc0, 0xde, 0x18, 0x42, 0xc0, 0x98, 0x30,
+  0x08, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0xc0, 0x27, 0x63, 0x00, 0x08, 0x63, 0x03, 0x06, 0x60, 0x10, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x27, 0x63,
+  0x00, 0x08, 0x63, 0x03, 0x06, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0xd9, 0x04, 0xb2, 0x01, 0x00, 0xb0,
+  0x31, 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf9, 0xff,
+  0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0xc0, 0xd9, 0x04, 0xb2, 0x01, 0x00, 0xb0, 0x31, 0x19, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0c, 0xc0, 0x1e, 0x63,
+  0x00, 0x30, 0x04, 0x03, 0xc8, 0x60, 0x00, 0x0e, 0x00, 0x00, 0xfc, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x0e, 0xc0, 0xe1, 0x18, 0x80, 0x01, 0x60, 0xb0,
+  0x01, 0xe7, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x0f, 0xc0, 0xe1, 0x18, 0x80, 0x01, 0x60, 0xb0, 0x01, 0xe7, 0xf3, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x0f, 0xc0, 0x1e, 0x03,
+  0x02, 0x08, 0x04, 0x00, 0xc8, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xd8, 0x0f, 0xc0, 0x1e, 0x03, 0x02, 0x08, 0x04, 0x00,
+  0xc8, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xc0, 0x0f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x0b, 0x00, 0x21, 0x64, 0x40, 0xc0, 0x00, 0xb3, 0xf1, 0xfe, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xfb, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x21, 0x64,
+  0x40, 0xc0, 0x00, 0xb3, 0xf1, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xfb, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0xfb, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfd, 0x00, 0xc0, 0xdf, 0x00, 0x00, 0x06, 0x60, 0x00,
+  0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xf9, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf,
+  0x01, 0xc0, 0xdf, 0x00, 0x00, 0x06, 0x60, 0x00, 0x0e, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xf0, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x0b, 0xc0, 0xc0, 0x84,
+  0x31, 0xc0, 0x00, 0x4c, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x83, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x1e, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0f, 0x0e, 0xc0, 0x3f, 0x18, 0x00, 0x06, 0x84, 0x80,
+  0x09, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xc3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x0c, 0xc0, 0x3f, 0x18, 0x00, 0x06, 0x84, 0x80, 0x09, 0xff, 0xff, 0x3f,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+  0xc1, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0xc0, 0xc1, 0x03,
+  0x4c, 0x00, 0x00, 0x30, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x90, 0x13, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x08, 0xc0, 0xc1, 0x03, 0x4c, 0x00, 0x00, 0x30,
+  0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0xc0, 0x3f, 0x98, 0x01, 0x08, 0x1b, 0x43, 0xc8, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x98,
+  0x01, 0x08, 0x1b, 0x43, 0xc8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0xc6, 0x03, 0x40, 0x00, 0x00, 0x80,
+  0x31, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xef, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+  0x00, 0x00, 0x3f, 0x18, 0x0c, 0x30, 0x60, 0x0c, 0xce, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xef, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x3f, 0x18,
+  0x0c, 0x30, 0x60, 0x0c, 0xce, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xc7, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xde, 0x63, 0x40, 0x06, 0x03, 0x30,
+  0x30, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x83, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e,
+  0x00, 0x00, 0xde, 0x63, 0x40, 0x06, 0x03, 0x30, 0x30, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x04,
+  0x02, 0x00, 0x00, 0x83, 0xc9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x38, 0x04, 0x02, 0x00, 0x00, 0x83,
+  0xc9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x03, 0x00, 0xe0, 0x1b, 0x0c, 0x08, 0x18, 0x40, 0x30, 0xfe, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0xc0, 0x84,
+  0x81, 0x01, 0x03, 0x0c, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0xc0, 0x84, 0x81, 0x01, 0x03, 0x0c,
+  0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x0e, 0x00, 0x00, 0x1b, 0x0c, 0x30, 0x80, 0x00, 0x30, 0xf8, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+  0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x1b,
+  0x0c, 0x30, 0x80, 0x00, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x67, 0xc0, 0x01, 0x04, 0x40,
+  0x00, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x08, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0x67, 0xc0, 0x01, 0x04, 0x40, 0x00, 0xe1, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+  0x30, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x9c,
+  0x01, 0x08, 0x60, 0x0c, 0x06, 0x86, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xbf, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x07, 0x0e, 0x00, 0x00, 0x18, 0x0c, 0xc0, 0x00, 0x00,
+  0xc0, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x9f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x07, 0x00, 0x00, 0x18, 0x0c, 0xc0, 0x00, 0x00, 0xc0, 0x00, 0xfc, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0xe0,
+  0x01, 0x06, 0x00, 0x30, 0x06, 0x86, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xe0, 0x01, 0x06, 0x00, 0x30,
+  0x06, 0x86, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x63, 0x03, 0x30, 0x00, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+  0x30, 0x00, 0x63, 0x03, 0x30, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x80, 0x83, 0x09, 0x18, 0x00,
+  0x00, 0x06, 0x83, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0x80, 0x83, 0x09, 0x18, 0x00, 0x00, 0x06, 0x83, 0xff,
+  0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0x00, 0x8c, 0xc9, 0x60, 0x00, 0xfe, 0xff, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x8e, 0x01, 0x84, 0x40,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x8e, 0x01, 0x84, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x60, 0x83, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+  0x00, 0xc8, 0x60, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x0c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0f, 0x00, 0x00, 0x00, 0x80, 0xc1, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x80, 0xc1, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x60, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf8, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xc6,
+  0x03, 0x00, 0x00, 0x00, 0x40, 0x08, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xef, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xd8, 0xef, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x1c, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xf3,
+  0x0f, 0x00, 0x00, 0x00, 0x80, 0x09, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x33, 0x0c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x88, 0x13, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x13,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x33, 0x0c, 0x00, 0x00, 0x00,
+  0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x88, 0xf3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xe3,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xe1, 0x1f, 0x00, 0x00, 0x00,
+  0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xf0, 0xc1, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00,
+  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc0, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x06, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/bootlogo.rh linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/bootlogo.rh
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/bootlogo.rh	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/bootlogo.rh	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,3204 @@
+#define splash_width 640
+#define splash_height 480
+
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff
+	.byte  0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x07, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f
+	.byte  0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xfe, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f
+	.byte  0xc0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x7f, 0xff, 0xf8
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x3e, 0x00, 0x07, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c
+	.byte  0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x07, 0xfe
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07
+	.byte  0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x3f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f
+	.byte  0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xfc, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x7c, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78
+	.byte  0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x7f, 0xff, 0xf8
+	.byte  0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00
+	.byte  0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe
+	.byte  0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00
+	.byte  0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfe, 0x07
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x07, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x07, 0xff
+	.byte  0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x07, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x07
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff, 0xc0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf8
+	.byte  0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00
+	.byte  0x0f, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x07, 0xff
+	.byte  0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x0f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x07
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x07, 0xff, 0xe0, 0x7f, 0xff, 0xc0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff
+	.byte  0xc0, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x07, 0xff, 0x80, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00
+	.byte  0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff
+	.byte  0x00, 0x0f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
+	.byte  0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x00, 0x07, 0xff, 0xe0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xc0
+	.byte  0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x07, 0xfc, 0x00, 0x03, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0x00, 0x00, 0x00
+	.byte  0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8
+	.byte  0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f
+	.byte  0xff, 0xff, 0xff, 0xfc, 0x0f, 0x80, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x01, 0xff, 0xe0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x03, 0xff
+	.byte  0x83, 0xc0, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x3f, 0xe0, 0xe0, 0x00, 0x00
+	.byte  0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0
+	.byte  0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f
+	.byte  0xe0, 0x00, 0x00, 0x07, 0xe0, 0x70, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0xff, 0xe0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x00
+	.byte  0xfc, 0x38, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x1c, 0x00, 0x00
+	.byte  0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0
+	.byte  0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e
+	.byte  0x00, 0x00, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0xff, 0xe0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00
+	.byte  0x0f, 0x07, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc3, 0x80, 0x00
+	.byte  0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8
+	.byte  0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc
+	.byte  0x00, 0x00, 0x00, 0x00, 0x01, 0xe3, 0xc0, 0x00, 0x1f, 0xff, 0xfe, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x01, 0xff, 0xe0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0xe1, 0xc0, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x07, 0xfc, 0x00, 0x03, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe0, 0x00
+	.byte  0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfe
+	.byte  0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x70, 0x00, 0x0f, 0xff, 0xfe, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x00, 0x0f, 0xff, 0xc0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x0c, 0x30, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x07, 0xff, 0x80, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x38, 0x00
+	.byte  0x0f, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xe0, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x1c, 0x00, 0x0f, 0xff, 0xfe, 0x07
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x01, 0x1c, 0x00, 0x0f, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00
+	.byte  0x07, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x07, 0xff, 0xfe, 0x07
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x47, 0x00, 0x07, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00
+	.byte  0x07, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x03, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x07, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80
+	.byte  0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x01, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x03, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0
+	.byte  0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x03, 0xe0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0
+	.byte  0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
+	.byte  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x7f, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x03, 0xe0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0
+	.byte  0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x1f, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x03, 0xe0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0
+	.byte  0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x0f, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xe0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0
+	.byte  0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f
+	.byte  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf9, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f
+	.byte  0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x38, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38
+	.byte  0x1f, 0xff, 0xf8, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0xff, 0xff, 0x00
+	.byte  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1c, 0x00, 0x7f, 0xff, 0xf0, 0x04, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e
+	.byte  0x00, 0x1f, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x03, 0xff, 0xff
+	.byte  0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x3f, 0xff, 0xfe, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0xc0, 0x00, 0x07, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f
+	.byte  0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff
+	.byte  0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f
+	.byte  0xff, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf8, 0x03, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff
+	.byte  0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38
+	.byte  0x7f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0f, 0xff, 0xff, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1c, 0x00, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e
+	.byte  0x00, 0x1f, 0xff, 0x80, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x03, 0xff, 0x80
+	.byte  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x3f, 0x80, 0xff, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x01, 0x82, 0x10, 0x20, 0xcd, 0xe0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x80, 0x00, 0x07, 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+	.byte  0x82, 0x10, 0x20, 0xcd, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40
+	.byte  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x18, 0x71, 0x8c, 0xde, 0x0c
+	.byte  0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x10, 0x00, 0x00, 0x18, 0x71, 0x8c, 0xde, 0x0c, 0x0c, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x1f
+	.byte  0x82, 0x63, 0x21, 0x30, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x1f, 0x82, 0x63, 0x21, 0x30
+	.byte  0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07
+	.byte  0xf0, 0x00, 0x00, 0x18, 0x30, 0x10, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x27
+	.byte  0x8d, 0x83, 0x19, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0x90, 0x00, 0x00, 0x27, 0x8d, 0x83, 0x19, 0x00
+	.byte  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc
+	.byte  0x10, 0x00, 0x00, 0x38, 0x40, 0x10, 0x20, 0x32, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f
+	.byte  0xff, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38
+	.byte  0x40, 0x10, 0x20, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0x03, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x40, 0x08, 0x01
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x26, 0x32, 0x00, 0x00, 0x00
+	.byte  0x6c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x80, 0x00, 0x40, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
+	.byte  0x90, 0x00, 0x00, 0x26, 0x32, 0x00, 0x00, 0x00, 0x6c, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0xff, 0xc0, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x39
+	.byte  0x80, 0x10, 0xc1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x0f, 0xff
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x26, 0x31, 0x80, 0x18, 0x02
+	.byte  0x0c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f
+	.byte  0xf0, 0x00, 0x00, 0x26, 0x31, 0x80, 0x18, 0x02, 0x0c, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0xff, 0xc0, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0xd9
+	.byte  0x80, 0x03, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xff, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x00, 0x02
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0x90, 0x00, 0x00, 0xd9, 0x80, 0x03, 0x00, 0x00
+	.byte  0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc
+	.byte  0x00, 0x00, 0x00, 0xe0, 0x4c, 0x60, 0x18, 0xc2, 0x00, 0x60, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07
+	.byte  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x0f, 0x83, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0x40, 0x40, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xe0
+	.byte  0x4c, 0x60, 0x18, 0xc2, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x08, 0x07
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x00, 0xde, 0x00, 0x0c, 0xc0, 0x30
+	.byte  0x10, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x07, 0xe0, 0xc0, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
+	.byte  0x90, 0x00, 0x03, 0x21, 0xb1, 0x80, 0x01, 0x00, 0x03, 0x60, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f
+	.byte  0xbf, 0xc0, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03, 0x21
+	.byte  0xb1, 0x80, 0x01, 0x00, 0x03, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xbf, 0xc0, 0x0f, 0xfe
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0xd8, 0x00, 0x0c, 0x00, 0x02
+	.byte  0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0x3f, 0x80, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x10, 0x00, 0x03, 0xd8, 0x00, 0x0c, 0x00, 0x02, 0x10, 0x18, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f
+	.byte  0xe0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc
+	.byte  0x1f, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x26
+	.byte  0x42, 0x60, 0xd8, 0xc0, 0x00, 0x86, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x03, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x08, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, 0x26, 0x42, 0x60, 0xd8, 0xc0
+	.byte  0x00, 0x86, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+	.byte  0xf0, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x01, 0x0c, 0x10, 0x61, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f
+	.byte  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f
+	.byte  0xff, 0xfc, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0xd8
+	.byte  0x00, 0x00, 0x01, 0x0c, 0x10, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc3, 0xc0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x07, 0x21, 0x8c, 0x0c, 0x20, 0x01
+	.byte  0x83, 0x18, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x38, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0x90, 0x00, 0x03, 0xc6, 0x40, 0x60, 0x00, 0x00, 0x00, 0x06, 0x36, 0x3f
+	.byte  0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18
+	.byte  0x07, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x10, 0x00, 0x03, 0xc6
+	.byte  0x40, 0x60, 0x00, 0x00, 0x00, 0x06, 0x36, 0x3f, 0xff, 0xc0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0xff, 0xff, 0xc0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0x38, 0x02, 0x00, 0xd8, 0x32
+	.byte  0x60, 0x81, 0x01, 0xbf, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0e, 0x00, 0x0f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e
+	.byte  0x00, 0x00, 0x07, 0x38, 0x02, 0x00, 0xd8, 0x32, 0x60, 0x81, 0x01, 0xbf
+	.byte  0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07
+	.byte  0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x90, 0x00, 0x04, 0xc6
+	.byte  0x30, 0x10, 0x01, 0x00, 0x0c, 0x60, 0x30, 0x3f, 0xff, 0xfe, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x0c, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x04, 0xc6, 0x30, 0x10, 0x01, 0x00
+	.byte  0x0c, 0x60, 0x30, 0x3f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+	.byte  0xf0, 0x00, 0x1b, 0x21, 0x80, 0x03, 0x00, 0x00, 0x60, 0x00, 0x01, 0x8f
+	.byte  0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
+	.byte  0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x1f, 0xd8
+	.byte  0x02, 0x10, 0x21, 0x30, 0x03, 0x18, 0xc8, 0x33, 0xff, 0xff, 0xf0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x07, 0xfe
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x1f, 0xd8, 0x02, 0x10, 0x21, 0x30
+	.byte  0x03, 0x18, 0xc8, 0x33, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x0f, 0x27, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0x90, 0x00, 0x1c, 0x01, 0x80, 0x00, 0x18, 0x0c, 0x60, 0x80, 0x00, 0x03
+	.byte  0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c
+	.byte  0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f
+	.byte  0xe0, 0x00, 0x0c, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x1c, 0x01
+	.byte  0x80, 0x00, 0x18, 0x0c, 0x60, 0x80, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x08, 0x21
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x1b, 0xf8, 0x0c, 0x6c, 0x01, 0x00
+	.byte  0x00, 0x00, 0xc0, 0x4f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xf2, 0x70, 0x00, 0x08, 0x21, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e
+	.byte  0x10, 0x00, 0x1b, 0xf8, 0x0c, 0x6c, 0x01, 0x00, 0x00, 0x00, 0xc0, 0x4f
+	.byte  0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08
+	.byte  0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f
+	.byte  0xff, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2
+	.byte  0x10, 0x00, 0x08, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x90, 0x00, 0x7c, 0x00
+	.byte  0x41, 0x80, 0xc0, 0x02, 0x0c, 0x19, 0x08, 0x0f, 0xe7, 0xff, 0xff, 0xff
+	.byte  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf8, 0x03, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x10, 0x00, 0x08, 0x27
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x67, 0xd8, 0x00, 0x00, 0x18, 0x30
+	.byte  0x00, 0x00, 0x00, 0x3f, 0xff, 0xdf, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x82, 0x10, 0x00, 0x0c, 0x3e, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x10, 0x00, 0x67, 0xd8, 0x00, 0x00, 0x18, 0x30, 0x00, 0x00, 0x00, 0x3f
+	.byte  0xff, 0xdf, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08
+	.byte  0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79
+	.byte  0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82
+	.byte  0x10, 0x00, 0x04, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x78, 0x26
+	.byte  0x0c, 0x63, 0x01, 0x01, 0x90, 0x60, 0xc6, 0x7f, 0x9f, 0xff, 0xff, 0xff
+	.byte  0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1f, 0xff, 0xff, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x70, 0x00, 0x03, 0x3c
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x78, 0x26, 0x0c, 0x63, 0x01, 0x01
+	.byte  0x90, 0x60, 0xc6, 0x7f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x38, 0x01, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xc3, 0xe0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x70, 0x00, 0x9c, 0xc0, 0x00, 0x00, 0x20, 0x30, 0x03, 0x06, 0x01, 0xfc
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
+	.byte  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c
+	.byte  0x00, 0x3f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43
+	.byte  0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x9c, 0xc0
+	.byte  0x00, 0x00, 0x20, 0x30, 0x03, 0x06, 0x01, 0xfc, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x7c, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x01, 0xff, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0xc0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0xe7, 0x20, 0x42, 0x63, 0x00, 0x00
+	.byte  0x00, 0x00, 0x37, 0xf3, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xf0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f
+	.byte  0xf0, 0x03, 0xf8, 0x01, 0x80, 0x00, 0x19, 0x32, 0x60, 0x60, 0x0f, 0x80
+	.byte  0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07
+	.byte  0x80, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x90, 0x03, 0xf8, 0x01
+	.byte  0x80, 0x00, 0x19, 0x32, 0x60, 0x60, 0x0f, 0x80, 0x00, 0x07, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xfc, 0x10, 0x03, 0x67, 0x20, 0x30, 0x10, 0x00, 0x00
+	.byte  0x03, 0x06, 0x3e, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0xf8, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30
+	.byte  0x00, 0x03, 0x67, 0x20, 0x30, 0x10, 0x00, 0x00, 0x03, 0x06, 0x3e, 0x00
+	.byte  0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f
+	.byte  0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x98, 0x06
+	.byte  0x02, 0x00, 0xc6, 0x0c, 0x10, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x1f
+	.byte  0xff, 0xcf, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x03, 0x90, 0x03, 0x98, 0x06, 0x02, 0x00, 0xc6, 0x0c
+	.byte  0x10, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xcf, 0xff, 0xe0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0xf0, 0x03, 0xe4, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x67, 0xf8, 0x00
+	.byte  0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08
+	.byte  0x07, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f
+	.byte  0xf3, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x03, 0xe4, 0xc0
+	.byte  0x00, 0x0c, 0x00, 0xc0, 0x00, 0x67, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x03
+	.byte  0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff
+	.byte  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0xf0, 0x03, 0x7b, 0x20, 0x30, 0x60, 0xc0, 0x01
+	.byte  0x83, 0x1f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfe
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x7f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xf0, 0xc0, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f
+	.byte  0xf0, 0x03, 0x98, 0x00, 0x4c, 0x00, 0x06, 0x0c, 0x10, 0xff, 0xc0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f
+	.byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf9
+	.byte  0xe0, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x90, 0x03, 0x98, 0x00
+	.byte  0x4c, 0x00, 0x06, 0x0c, 0x10, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x07, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf9, 0xe0, 0x00, 0x18, 0x02
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xfc, 0x00, 0x03, 0xe4, 0xc6, 0x01, 0x8c, 0x20, 0xc0
+	.byte  0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff
+	.byte  0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1f, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x38, 0x7f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x01, 0xf8, 0xe0, 0x00, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30
+	.byte  0x00, 0x03, 0xe4, 0xc6, 0x01, 0x8c, 0x20, 0xc0, 0x0f, 0xff, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f
+	.byte  0xfe, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38
+	.byte  0x07, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8c
+	.byte  0x20, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x9b, 0x20
+	.byte  0x00, 0x10, 0x00, 0x01, 0x9f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x0f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x78, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x7f, 0xff, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x20, 0x00, 0x06, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x03, 0x90, 0x00, 0x9b, 0x20, 0x00, 0x10, 0x00, 0x01
+	.byte  0x9f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff
+	.byte  0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1f, 0xfe, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1e, 0x00, 0x0f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x01, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0xf0, 0x03, 0xe4, 0x00, 0x0c, 0x03, 0x06, 0x0d, 0xff, 0xfe, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
+	.byte  0x06, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
+	.byte  0x00, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82
+	.byte  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x7b, 0xd9
+	.byte  0xb1, 0x80, 0x20, 0xc3, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x01, 0x8f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xc0, 0x00, 0x0f, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x7b, 0xd9, 0xb1, 0x80, 0x20, 0xc3
+	.byte  0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8f, 0xff
+	.byte  0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x7c, 0xc0, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x03, 0x9c, 0x20, 0x00, 0x13, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x1f, 0xff, 0xfc, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff
+	.byte  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, 0x9c, 0x20
+	.byte  0x00, 0x13, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x63, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xf8, 0x00, 0x03, 0xe3, 0x06, 0x42, 0x00, 0x06, 0xff
+	.byte  0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1f, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8
+	.byte  0x00, 0x03, 0xe3, 0x06, 0x42, 0x00, 0x06, 0xff, 0xff, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f
+	.byte  0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x03, 0xff, 0xe0
+	.byte  0x0d, 0x90, 0x27, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x0c, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x70, 0x00, 0x03, 0x7b, 0x1e, 0x40, 0x00, 0xdf, 0xff
+	.byte  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x01, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xf8, 0x0f, 0xff, 0xff, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x03, 0x7b, 0x1e, 0x40, 0x00, 0xdf, 0xff, 0xff, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf8, 0x1f
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x10
+	.byte  0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e
+	.byte  0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0xfc, 0xe0
+	.byte  0x0d, 0x93, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x03, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0xfc, 0xe0, 0x0d, 0x93, 0x1f, 0xff
+	.byte  0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f
+	.byte  0xf0, 0x00, 0xe7, 0xdf, 0xc2, 0x0c, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0xe0, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0xe7, 0xdf
+	.byte  0xc2, 0x0c, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x07, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x7f, 0x38, 0x4d, 0xf0, 0x07, 0xff
+	.byte  0xe0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x03, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0xf0, 0x00, 0x1f, 0xe7, 0xbf, 0x80, 0x07, 0xff, 0xe0, 0x00, 0x07, 0xff
+	.byte  0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x07
+	.byte  0x8d, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x1f
+	.byte  0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x0f, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x1f, 0xe7
+	.byte  0xbf, 0x80, 0x07, 0xff, 0xe0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x07, 0x8d, 0xfc, 0x00, 0x00
+	.byte  0x1f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x01, 0xff
+	.byte  0x80, 0x00, 0x07, 0xc0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x19, 0xf2, 0x70, 0x18, 0x00, 0x1f, 0xff, 0xff, 0xff
+	.byte  0xe0, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0
+	.byte  0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x01, 0xff, 0x80, 0x00, 0x07, 0xc0
+	.byte  0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19
+	.byte  0xf2, 0x70, 0x1f, 0xf8, 0x6f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x10
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+	.byte  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x1f, 0xff
+	.byte  0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x8d, 0x80, 0xff, 0xf8
+	.byte  0x6f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0xe0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x20, 0x10, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1f, 0x8d, 0x80, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xff
+	.byte  0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0xf0, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
+	.byte  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe
+	.byte  0x00, 0x73, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f
+	.byte  0xff, 0xc7, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00
+	.byte  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x07, 0xff
+	.byte  0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x73, 0xff, 0xfe
+	.byte  0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x04, 0xd8, 0x4d, 0x8c, 0xff, 0xfe, 0x00, 0xff, 0xff, 0xff
+	.byte  0xfc, 0x00, 0x00, 0x07, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x01, 0x80, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0xf0, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
+	.byte  0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x38
+	.byte  0x00, 0x03, 0xff, 0xce, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f
+	.byte  0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c
+	.byte  0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0
+	.byte  0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x03, 0xff
+	.byte  0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x38, 0x00, 0x03, 0xfe, 0x38
+	.byte  0x0c, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x1e, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x1c, 0xe1, 0x8c, 0x60, 0x3e, 0x38, 0x0c, 0xff, 0xff, 0xff
+	.byte  0xff, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xe1
+	.byte  0x8c, 0x60, 0x3f, 0xf0, 0x13, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x1c
+	.byte  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c
+	.byte  0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff
+	.byte  0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x03, 0xff
+	.byte  0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x67, 0x20, 0x00, 0x0c, 0xc7, 0xf0
+	.byte  0x13, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x0c, 0x67, 0x20, 0x00, 0x0c, 0xc0, 0x00, 0x0f, 0xff, 0xff, 0xff
+	.byte  0xff, 0xc0, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f
+	.byte  0xe0, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
+	.byte  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xd8
+	.byte  0x32, 0x00, 0x20, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x08
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x80, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x03, 0xff
+	.byte  0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe0, 0x20, 0x00, 0x60, 0x18, 0x01
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xf0, 0x70, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x40, 0xe0, 0x20, 0x00, 0x60, 0x1e, 0xcf, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xe0, 0x00, 0x1f, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0
+	.byte  0x10, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x7c, 0x20
+	.byte  0x40, 0x0c, 0x06, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x1f
+	.byte  0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x03, 0xff
+	.byte  0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x7c, 0x20, 0x40, 0x0c, 0x07, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x63, 0x20, 0x02, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xe0, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0x10, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x20
+	.byte  0x02, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x10
+	.byte  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x70, 0x00, 0x00, 0xff
+	.byte  0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x9c, 0xe6, 0x00, 0x60, 0x07, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xc0, 0xf0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x60, 0x20, 0x0c, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xfc, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x18, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40
+	.byte  0xf0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x20
+	.byte  0x0c, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x10
+	.byte  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00
+	.byte  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0x00, 0x00, 0xff
+	.byte  0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x7e, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x7c, 0xd9, 0x80, 0x0c, 0x07, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x10, 0x06, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x60, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x0c, 0x7c, 0xd9, 0x80, 0x0c, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xfc, 0x00, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x38, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0x00, 0x40, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f
+	.byte  0x80, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x38
+	.byte  0x30, 0x60, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x1c
+	.byte  0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x07
+	.byte  0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0xff
+	.byte  0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x0f, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x38, 0x30, 0x60, 0xdf, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x16, 0x3e, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1f, 0xe0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x1c, 0x18, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xfc, 0x00, 0x03, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x18, 0x7f, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0xff, 0xc0, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f
+	.byte  0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x63, 0xd9
+	.byte  0x81, 0x80, 0x06, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x01
+	.byte  0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfe
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x00, 0xff
+	.byte  0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x03, 0xe0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x63, 0xd9, 0x81, 0x80, 0x00, 0x00
+	.byte  0x6f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x1c, 0x1e, 0x30, 0x0c, 0x20, 0x00, 0x6f, 0xff, 0xff, 0xff
+	.byte  0xff, 0xfc, 0x00, 0x17, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0x00, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c
+	.byte  0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1e
+	.byte  0x30, 0x0c, 0x20, 0x00, 0x13, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x1f
+	.byte  0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c
+	.byte  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff
+	.byte  0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x01, 0xe0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x26, 0x02, 0x00, 0x38, 0x00
+	.byte  0x13, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x1f, 0x1a, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x20, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x03, 0x26, 0x02, 0x00, 0x3f, 0xc0, 0x03, 0xff, 0xff, 0xff
+	.byte  0xff, 0xfc, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0x10, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c
+	.byte  0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x07
+	.byte  0x80, 0x6c, 0x3f, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x1c
+	.byte  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0xff
+	.byte  0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x01, 0xe0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x07, 0x80, 0x6c, 0x3f, 0xf8
+	.byte  0x0c, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x18, 0x02, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xf1, 0x80, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x63, 0xe1, 0xf0, 0x00, 0xff, 0xf8, 0x0c, 0xff, 0xff, 0xff
+	.byte  0xff, 0xe0, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x7f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0xf3, 0xc0, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f
+	.byte  0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18
+	.byte  0x02, 0x03, 0xff, 0xfe, 0x03, 0x7f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x10
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf3, 0xc0, 0x00, 0xff
+	.byte  0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x03, 0xe0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x02, 0x03, 0xff, 0xfe
+	.byte  0x00, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xf1, 0x80, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xc0, 0x70, 0x63, 0xff, 0xfe, 0x00, 0xff, 0xff, 0xff
+	.byte  0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x7f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f
+	.byte  0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0
+	.byte  0x70, 0x63, 0xff, 0xfe, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff
+	.byte  0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x0f, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x39, 0x80, 0x0c, 0xff, 0xfe
+	.byte  0x00, 0x7f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x04, 0x39, 0x80, 0x0c, 0xff, 0xc6, 0x0c, 0xff, 0xff, 0xff
+	.byte  0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0x10, 0x00, 0x00, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
+	.byte  0xe0, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06
+	.byte  0x32, 0x00, 0xff, 0xc6, 0x0c, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0xff
+	.byte  0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x7c, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x8c, 0x3f, 0xf8
+	.byte  0x00, 0xff, 0xff, 0xbf, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x4d, 0x8c, 0x3f, 0xf0, 0x00, 0xff, 0xff, 0xc0
+	.byte  0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x70, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0xf0, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19
+	.byte  0x82, 0x00, 0x07, 0xf0, 0x00, 0xff, 0xff, 0xc0, 0xff, 0xc0, 0x00, 0x1c
+	.byte  0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0xff
+	.byte  0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x82, 0x00, 0x00, 0x01
+	.byte  0x93, 0x9f, 0xff, 0xbc, 0xff, 0xc0, 0x00, 0x1e, 0x03, 0xf0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x06, 0x4c, 0x10, 0x00, 0x01, 0x93, 0x9f, 0xff, 0xbc
+	.byte  0xff, 0xc0, 0x00, 0x1f, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0x40, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06
+	.byte  0x4c, 0x10, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf3, 0xff, 0x00, 0x00, 0x1f
+	.byte  0x81, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xff
+	.byte  0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x07, 0x80, 0x1f, 0x00, 0x00
+	.byte  0x0f, 0xff, 0xff, 0xf3, 0xff, 0x00, 0x00, 0x1c, 0xc0, 0x08, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xff
+	.byte  0xfc, 0x00, 0x00, 0x1c, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f
+	.byte  0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x30, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f
+	.byte  0xff, 0xff, 0xc0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x1c
+	.byte  0x78, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x18, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x70, 0x00, 0x00, 0xff
+	.byte  0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, 0x3f
+	.byte  0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x1c, 0x3f, 0xf8, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0e, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xf8, 0x00, 0x00, 0x1c, 0x1f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c
+	.byte  0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0xf0, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x1e
+	.byte  0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x07, 0xf8, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0xff
+	.byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0x83, 0xe0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x06, 0x1f, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00
+	.byte  0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
+	.byte  0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x03, 0xff
+	.byte  0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf8, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0x80, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x10, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xe6
+	.byte  0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc8, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0xff
+	.byte  0xff, 0xff, 0xf8, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe6, 0x7f, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf8, 0xc0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x0f, 0xff, 0xff, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0
+	.byte  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f
+	.byte  0xf0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x10, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x19
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x0e
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x1f, 0xff
+	.byte  0xff, 0xff, 0xfe, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xfc, 0xe7, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f
+	.byte  0xff, 0xff, 0xfc, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0
+	.byte  0x00, 0x03, 0xff, 0xe6, 0x31, 0x9f, 0xdf, 0xce, 0x00, 0xe6, 0x08, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x1f
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x01
+	.byte  0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x03, 0xff, 0xe6
+	.byte  0x31, 0x9f, 0xdf, 0xce, 0x00, 0xe6, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf8, 0xe7, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xc0, 0x00, 0x03, 0xe4, 0x3f, 0xce, 0x63, 0x38, 0x31
+	.byte  0xec, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff
+	.byte  0xff, 0xff, 0xf8, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40
+	.byte  0x00, 0x03, 0xe4, 0x3f, 0xce, 0x63, 0x38, 0x31, 0xec, 0x01, 0x30, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x3f
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f
+	.byte  0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x03, 0x7f, 0xc0
+	.byte  0x31, 0x90, 0xc7, 0xce, 0x13, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xf0, 0x03, 0x7f, 0xc0, 0x31, 0x90, 0xc7, 0xce
+	.byte  0x13, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0xf0, 0x03, 0xe4, 0xe7, 0x8c, 0x6c, 0x20, 0x31, 0x80, 0x06, 0xc0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
+	.byte  0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x03, 0x7b, 0x18
+	.byte  0x42, 0x03, 0x19, 0x0c, 0x10, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xf0, 0x03, 0x7b, 0x18, 0x42, 0x03, 0x19, 0x0c
+	.byte  0x10, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0x00, 0x03, 0xe4, 0xc6, 0x00, 0x10, 0xc6, 0xc0, 0x60, 0x06, 0x08, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f
+	.byte  0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0xe4, 0xc6
+	.byte  0x00, 0x10, 0xc6, 0xc0, 0x60, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x9b, 0x20, 0x4d, 0x80, 0x00, 0x0d
+	.byte  0x8c, 0x98, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9f, 0xff
+	.byte  0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x7f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0x10, 0x03, 0x9b, 0x20, 0x4d, 0x80, 0x00, 0x0d, 0x8c, 0x98, 0xc0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xe0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x30, 0x03, 0x78, 0xc6
+	.byte  0x00, 0x0c, 0x20, 0xc0, 0x13, 0x06, 0x00, 0x70, 0x00, 0x00, 0x3f, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xc0, 0x70, 0x03, 0x87, 0x18, 0x01, 0x80, 0x06, 0x0d
+	.byte  0x80, 0xe7, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0
+	.byte  0xf0, 0x03, 0x87, 0x18, 0x01, 0x80, 0x06, 0x0d, 0x80, 0xe7, 0xcf, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x20, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0xf0, 0x03, 0x78, 0xc0
+	.byte  0x40, 0x10, 0x20, 0x00, 0x13, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1b, 0xf0, 0x03, 0x78, 0xc0, 0x40, 0x10, 0x20, 0x00
+	.byte  0x13, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x03, 0xf0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f
+	.byte  0xd0, 0x00, 0x84, 0x26, 0x02, 0x03, 0x00, 0xcd, 0x8f, 0x7f, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xdf, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x84, 0x26
+	.byte  0x02, 0x03, 0x00, 0xcd, 0x8f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xdf, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x3f, 0xdf, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xbf, 0x00, 0x03, 0xfb, 0x00, 0x00, 0x60, 0x06, 0x00
+	.byte  0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x7f, 0x9f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd
+	.byte  0x80, 0x03, 0xfb, 0x00, 0x00, 0x60, 0x06, 0x00, 0x70, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07
+	.byte  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x0f, 0xc0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd0, 0x03, 0x03, 0x21
+	.byte  0x8c, 0x03, 0x00, 0x32, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc1, 0xe0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x78, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xf0, 0x70, 0x03, 0xfc, 0x18, 0x00, 0x60, 0x21, 0x01
+	.byte  0x90, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0xc3, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0
+	.byte  0x30, 0x03, 0xfc, 0x18, 0x00, 0x60, 0x21, 0x01, 0x90, 0xff, 0xff, 0xfc
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13
+	.byte  0x83, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0x03, 0x83, 0xc0
+	.byte  0x32, 0x00, 0x00, 0x0c, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0xc8, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x80, 0x10, 0x03, 0x83, 0xc0, 0x32, 0x00, 0x00, 0x0c
+	.byte  0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0x00, 0x03, 0xfc, 0x19, 0x80, 0x10, 0xd8, 0xc2, 0x13, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
+	.byte  0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfc, 0x19
+	.byte  0x80, 0x10, 0xd8, 0xc2, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x18, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x70, 0x00, 0x03, 0x63, 0xc0, 0x02, 0x00, 0x00, 0x01
+	.byte  0x8c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff
+	.byte  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1f, 0xf7, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8
+	.byte  0x00, 0x00, 0xfc, 0x18, 0x30, 0x0c, 0x06, 0x30, 0x73, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f
+	.byte  0xf7, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x18
+	.byte  0x30, 0x0c, 0x06, 0x30, 0x73, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe3, 0xf0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x7b, 0xc6, 0x02, 0x60, 0xc0, 0x0c
+	.byte  0x0c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x03, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70
+	.byte  0x00, 0x00, 0x7b, 0xc6, 0x02, 0x60, 0xc0, 0x0c, 0x0c, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x20
+	.byte  0x40, 0x00, 0x00, 0xc1, 0x93, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x1c, 0x20, 0x40, 0x00, 0x00, 0xc1
+	.byte  0x93, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x03, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x7f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f
+	.byte  0xc0, 0x00, 0x07, 0xd8, 0x30, 0x10, 0x18, 0x02, 0x0c, 0x7f, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f
+	.byte  0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x03, 0x21
+	.byte  0x81, 0x80, 0xc0, 0x30, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x03, 0x21, 0x81, 0x80, 0xc0, 0x30
+	.byte  0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0
+	.byte  0x70, 0x00, 0x00, 0xd8, 0x30, 0x0c, 0x01, 0x00, 0x0c, 0x1f, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18
+	.byte  0x08, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0xd8
+	.byte  0x30, 0x0c, 0x01, 0x00, 0x0c, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x08, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0xe6, 0x03, 0x80, 0x20, 0x02
+	.byte  0x00, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x10, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0x10, 0x00, 0x00, 0xe6, 0x03, 0x80, 0x20, 0x02, 0x00, 0x87, 0xff, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18
+	.byte  0x0c, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x39
+	.byte  0x80, 0x10, 0x06, 0x30, 0x60, 0x61, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff
+	.byte  0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfd, 0xf8, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xe0, 0x70, 0x00, 0x00, 0x18, 0x30, 0x03, 0x00, 0x00
+	.byte  0x03, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x0f, 0xf9, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f
+	.byte  0xe0, 0x00, 0x00, 0x18, 0x30, 0x03, 0x00, 0x00, 0x03, 0x00, 0x3f, 0xff
+	.byte  0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f
+	.byte  0xf8, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x07
+	.byte  0x80, 0x60, 0x00, 0x0c, 0x60, 0x61, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte  0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x07, 0x80, 0x60, 0x00, 0x0c
+	.byte  0x60, 0x61, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f
+	.byte  0x00, 0x00, 0x00, 0x06, 0x0c, 0x00, 0xc6, 0xc0, 0x0c, 0x00, 0x07, 0xff
+	.byte  0xff, 0xff, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06
+	.byte  0x0c, 0x00, 0xc6, 0xc0, 0x0c, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xf0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x01, 0xc1, 0x90, 0x18, 0x00
+	.byte  0x00, 0x60, 0xc1, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0x10, 0x00, 0x00, 0x01, 0xc1, 0x90, 0x18, 0x00, 0x00, 0x60, 0xc1, 0xff
+	.byte  0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x03, 0x00, 0x31, 0x93, 0x06, 0x00, 0x7f, 0xff, 0xff, 0x80, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x71, 0x80, 0x21, 0x02
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff
+	.byte  0xf0, 0x00, 0x00, 0x00, 0x71, 0x80, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00
+	.byte  0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
+	.byte  0x20, 0x00, 0x00, 0x00, 0x00, 0x13, 0x06, 0xc1, 0x80, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00
+	.byte  0x00, 0x13, 0x06, 0xc1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x0c, 0x60, 0x00, 0x30
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0xf0, 0x00, 0x00, 0x00, 0x01, 0x83, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00
+	.byte  0x01, 0x83, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x06, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x1f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x63
+	.byte  0xc0, 0x00, 0x00, 0x00, 0x02, 0x10, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf7, 0xe0, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x1b, 0xf7, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x38, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xcf
+	.byte  0xf0, 0x00, 0x00, 0x00, 0x01, 0x90, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xcc, 0x30, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x11, 0xc8, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xc8
+	.byte  0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xcc, 0x30, 0x00, 0x00, 0x00
+	.byte  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x11, 0xcf, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xc7
+	.byte  0xf0, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x60, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x87, 0xf8, 0x00, 0x00, 0x00
+	.byte  0x00, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x0f, 0x83, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x20, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00
+	.byte  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x06, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x70, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x38, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x40, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x3f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x80, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x70, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x70, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x7f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xe0, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte  
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/bootstd.h linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/bootstd.h
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/bootstd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/bootstd.h	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,132 @@
+/* bootstd.h:  Bootloader system call interface
+ *
+ * (c) 1999, Rt-Control, Inc.
+ */
+
+#ifndef __BOOTSTD_H__
+#define __BOOTSTD_H__
+
+#define NR_BSC 21            /* last used bootloader system call */
+
+#define __BN_reset        0  /* reset and start the bootloader */
+#define __BN_test         1  /* tests the system call interface */
+#define __BN_exec         2  /* executes a bootloader image */
+#define __BN_exit         3  /* terminates a bootloader image */
+#define __BN_program      4  /* program FLASH from a chain */
+#define __BN_erase        5  /* erase sector(s) of FLASH */
+#define __BN_open         6
+#define __BN_write        7
+#define __BN_read         8
+#define __BN_close        9
+#define __BN_mmap         10 /* map a file descriptor into memory */
+#define __BN_munmap       11 /* remove a file to memory mapping */
+#define __BN_gethwaddr    12 /* get the hardware address of my interfaces */
+#define __BN_getserialnum 13 /* get the serial number of this board */
+#define __BN_getbenv      14 /* get a bootloader envvar */
+#define __BN_setbenv      15 /* get a bootloader envvar */
+#define __BN_setpmask     16 /* set the protection mask */
+#define __BN_readenv      17 /* read environment variables */
+#define __BN_flash_chattr_range		18
+#define __BN_flash_erase_range		19
+#define __BN_flash_write_range		20
+
+/* Calling conventions compatible to (uC)linux/68k
+ * We use simmilar macros to call into the bootloader as for uClinux
+ */
+
+#define __bsc_return(type, res) \
+do { \
+   if ((unsigned long)(res) >= (unsigned long)(-64)) { \
+      /* let errno be a function, preserve res in %d0 */ \
+      int __err = -(res); \
+      errno = __err; \
+      res = -1; \
+   } \
+   return (type)(res); \
+} while (0)
+
+#define _bsc0(type,name) \
+type name(void) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc1(type,name,atype,a) \
+type name(atype a) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc2(type,name,atype,a,btype,b) \
+type name(atype a, btype b) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc3(type,name,atype,a,btype,b,ctype,c) \
+type name(atype a, btype b, ctype c) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
+type name(atype a, btype b, ctype c, dtype d) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   register long __d __asm__ ("%d4") = (long)d; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c), "d" (__d) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
+type name(atype a, btype b, ctype c, dtype d, etype e) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   register long __d __asm__ ("%d4") = (long)d; \
+   register long __e __asm__ ("%d5") = (long)e; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c), "d" (__d), "d" (__e) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#endif /* __BOOTSTD_H__ */
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/crt0_fixed.S linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/crt0_fixed.S
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/crt0_fixed.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/crt0_fixed.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,432 @@
+#define CSGBA_ADDR      0xfffff100
+#define CSGBB_ADDR      0xfffff102
+#define CSGBC_ADDR      0xfffff104
+#define CSGBD_ADDR      0xfffff106
+#define CSA_ADDR        0xfffff110
+#define CSB_ADDR        0xfffff112
+#define CSC_ADDR        0xfffff114
+#define CSD_ADDR        0xfffff116
+#define DRAMMC_ADDR     0xfffffc00
+#define DRAMC_ADDR      0xfffffc02
+#define SCR_ADDR	0xfffff000
+#define ICEMSR_ADDR	0xfffffd0e
+#define WATCHDOG_ADDR   0xfffffb0a
+#define PBSEL_ADDR      0xfffff40b              /* Port B Select Register */
+#define PESEL_ADDR      0xfffff423              /* Port E Select Register */
+#define PFSEL_ADDR      0xfffff42b              /* Port F Select Register */
+#define PDSEL_ADDR      0xfffff41b              /* Port D Select Register */
+#define PDDIR_ADDR      0xfffff418              /* Port D direction reg */
+#define ICR_ADDR        0xfffff302
+#define IVR_ADDR        0xfffff300
+#define IMR_ADDR        0xfffff304
+#define PD(x)           (1 << (x))
+#define PD_INT0         0x01    /* Use INT0 as PD[0] */
+#define PD_INT1         0x02    /* Use INT1 as PD[1] */
+#define PD_INT2         0x04    /* Use INT2 as PD[2] */
+#define PD_INT3         0x08    /* Use INT3 as PD[3] */
+#define PD_IRQ1         0x10    /* Use IRQ1 as PD[4] */
+#define PD_IRQ2         0x20    /* Use IRQ2 as PD[5] */
+#define PD_IRQ3         0x40    /* Use IRQ3 as PD[6] */
+#define PD_IRQ6         0x80    /* Use IRQ6 as PD[7] */
+#define PUT_FIELD(field, val) (((val) << field##_SHIFT) & field##_MASK)
+#define GET_FIELD(reg, field) (((reg) & field##_MASK) >> field##_SHIFT)
+#define CSA_EN          0x0001          /* Chip-Select Enable */
+#define CSA_SIZ_MASK    0x000e          /* Chip-Select Size */
+#define CSA_SIZ_SHIFT   1
+#define CSA_WS_MASK     0x0070          /* Wait State */
+#define CSA_WS_SHIFT    4
+#define CSA_BSW         0x0080          /* Data Bus Width */
+#define CSA_FLASH       0x0100          /* FLASH Memory Support */
+#define CSA_RO          0x8000          /* Read-Only */
+#define SCR_WDTH8       0x01    /* 8-Bit Width Select */
+#define SCR_DMAP        0x04    /* Double Map */
+#define SCR_SO          0x08    /* Supervisor Only */
+#define SCR_BETEN       0x10    /* Bus-Error Time-Out Enable */
+#define SCR_PRV         0x20    /* Privilege Violation */
+#define SCR_WPV         0x40    /* Write Protect Violation */
+#define SCR_BETO        0x80    /* Bus-Error TimeOut */
+#define PB_CSC0_RAS0    0x04    /* Use CSC0/RAS0 as PB[2] */    
+#define PB_CSC1_RAS1    0x08    /* Use CSC1/RAS1 as PB[3] */    
+#define PB_CSD0_CAS0    0x10    /* Use CSD0/CAS0 as PB[4] */    
+#define PB_CSD1_CAS1    0x20    /* Use CSD1/CAS1 as PB[5] */
+#define CSD_EN          0x0001          /* Chip-Select Enable */
+#define CSD_SIZ_MASK    0x000e          /* Chip-Select Size */
+#define CSD_SIZ_SHIFT   1
+#define CSD_WS_MASK     0x0070          /* Wait State */
+#define CSD_WS_SHIFT    4
+#define CSD_BSW         0x0080          /* Data Bus Width */
+#define CSD_FLASH       0x0100          /* FLASH Memory Support */
+#define CSD_DRAM        0x0200          /* Dram Selection */
+#define CSD_COMB        0x0400          /* Combining */
+#define CSD_UPSIZ_MASK  0x1800          /* Unprotected memory block size */
+#define CSD_UPSIZ_SHIFT 11
+#define CSD_ROP         0x2000          /* Readonly if protected */
+#define CSD_SOP         0x4000          /* Supervisor only if protected */
+#define CSD_RO          0x8000          /* Read-Only */
+#define PB_CSB0         0x01    /* Use CSB0      as PB[0] */
+#define PE_DWE          0x08    /* Use DWE    as PE[3] */
+#define PE_RXD          0x10    /* Use RXD    as PE[4] */
+#define PE_TXD          0x20    /* Use TXD    as PE[5] */
+#define PF_A20          0x08    /* Use A20       as PF[3] */
+#define PF_A21          0x10    /* Use A21       as PF[4] */
+#define PF_A22          0x20    /* Use A22       as PF[5] */
+#define ICR_POL2        0x4000  /* Polarity Control for IRQ2 */
+#define ICR_POL1        0x8000  /* Polarity Control for IRQ1 */
+#define   DRAMMC_ROW12_PA23     0x8000
+#define DRAMMC_ROW11            0x0800  /* Row address bit for MD11 PA20/PA22 */
+#define DRAMMC_ROW10            0x0400  /* Row address bit for MD10 PA19/PA21 */
+#define DRAMMC_ROW9             0x0200  /* Row address bit for MD9  PA9/PA19 */
+#define DRAMMC_ROW8             0x0100  /* Row address bit for MD8  PA10/PA20 */
+#define DRAMC_EN           0x8000       /* DRAM Controller enable */
+#define DRAMC_EDO          0x0400       /* EDO DRAM */
+#define   DRAMC_PGSZ_1024K 0x0200
+#define DRAMC_MSW          0x0020       /* Slow Multiplexing */
+#define DRAMC_BC_MASK      0x3000       /* Page Access Clock Cycle (FP mode) */
+#define DRAMC_BC_SHIFT     12
+#define DRAMC_DWE          0x0001       /* DRAM Write Enable */
+#define DRAMC_RST          0x0002       /* Reset Burst Refresh Enable */
+#define DRAMC_LPR          0x0004       /* Low-Power Refresh Enable */
+#define USTCNT_TXEN     0x2000  /* Transmitter Enable */
+#define USTCNT_RXEN     0x4000  /* Receiver Enable */
+#define USTCNT_UEN      0x8000  /* UART Enable */
+#define USTCNT_8_7      0x0100  /* Eight or seven-bit transmission */
+#define USTCNT_ADDR     0xfffff900
+#define PLLCR_ADDR      0xfffff200
+#define PLLCR_SYSCLK_SEL_MASK  0x0700   /* System Clock Selection */
+#define PLLCR_SYSCLK_SEL_SHIFT 8
+#define PLLCR_LCDCLK_SEL_MASK  0x3800   /* LCD Clock Selection */
+#define PLLCR_LCDCLK_SEL_SHIFT 11
+#define UBAUD_PRESCALER_MASK    0x003f  /* Actual divisor is 65 - PRESCALER */
+#define UBAUD_PRESCALER_SHIFT   0
+#define UBAUD_DIVIDE_MASK       0x0700  /* Baud Rate freq. divizor */
+#define UBAUD_DIVIDE_SHIFT      8
+#define UBAUD_ADDR      0xfffff902
+#define UTX_ADDR        0xfffff906
+#define LCKCON_ADDR     0xfffffa27
+#define UTX_TXDATA_ADDR 0xfffff907
+#define UTX_TX_AVAIL     0x2000 /* Transmit FIFO has a slot available */
+#define UTX_NOCTS        0x0800 /* Ignore CTS */
+
+
+	.global _start
+	.global _stext
+
+	.global _rambase
+	.global _ramvec
+	.global _ramstart
+	.global _ramend
+	.global splash_bits
+
+#include <linux/config.h>
+
+	.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+
+
+
+splash_bits:
+#include "bootlogo.rh"
+	.text
+_start:
+_stext:
+        /*
+         * Program the basic registers. Only those registers that
+         * are required at startup should be initialized with the
+         * values required for startup. All other registers should
+         * be initialized by related components.
+         */
+/*
+ * Use dual mapping of the CPU register space and allow access to them
+ * from the user mode (this is the default, anyway). Also enable bus
+ * timeout watchdog.
+ */
+#define SCR_INIT (SCR_DMAP | SCR_BETEN)
+
+/*
+ * Disable the watchdog timer for now
+ */
+#define WATCHDOG_INIT 0
+
+/*
+ * Connect internal chip functions to those pins that are required for
+ * startup. Device drivers will do the rest
+ */
+
+/*
+ * Port B. We need:
+ *       CSC[01]/RAS[01] and CSD[01]/CAS[01] for our 2 DRAM  chips
+ *       CSB0 enabled for EXTRN access.
+ */      
+#define PBSEL_INIT (~(PB_CSC0_RAS0 | \
+                      PB_CSD0_CAS0 | \
+                      PB_CSD1_CAS1 | \
+                      PB_CSB0))
+
+/*
+ * Port D. We need
+ *      INT0	function
+ *      INT1	function
+ */
+#define PDSEL_INIT (~(PD_IRQ1 | PD_IRQ2))
+#define PDDIR_INIT (~(PD(12) | PD(13) | PD_IRQ1 | PD_IRQ2))
+#define IRQ_INIT (ICR_POL1 | ICR_POL2)
+
+/*
+ * Port E. We need
+ *	DWE    for DRAM Write Enable
+ *      RXD    RS-232 receive
+ *      TXD    RS-232 Transmit
+ *      RTS    RS-232 RTS
+ *      CTS    RS-232 CTS
+ */
+#define PESEL_INIT (~(PE_DWE | PE_RXD | PE_TXD ))
+
+/*
+ * Port F. We need
+ *	A20..A22 to address the second 8 meg FLASH store
+ */
+#define PFSEL_INIT (~(PF_A20 | PF_A21 | PF_A22))
+
+/*
+ * In-circuit emulation should be disabled
+ */
+
+        moveb   #0x08, 0xfffffd0d           /* disable hardware compare map */
+        moveb   #0x7, ICEMSR_ADDR           /* clear level 7 interrupt. */
+        moveb   #SCR_INIT,      SCR_ADDR 
+        movew   #WATCHDOG_INIT, WATCHDOG_ADDR
+        moveb   #PBSEL_INIT,    PBSEL_ADDR
+        moveb   #PESEL_INIT,    PESEL_ADDR
+        moveb   #PFSEL_INIT,    PFSEL_ADDR
+
+        moveb   #PDSEL_INIT,    PDSEL_ADDR	/* setup ethernet interrupts. */
+        movew   #PDDIR_INIT,    PDDIR_ADDR
+        movew   #IRQ_INIT,      ICR_ADDR
+
+        moveb   #0x40,          IVR_ADDR    /* Use 0x40-0x47 for IRQ 0-7 */
+        movel   #0x00FFFFFF,    IMR_ADDR    /* Mask all h/w interrupts */
+
+        /*
+         * Program Chip selects & DRAM controller
+         *
+         * CSA[0]            FLASH      10000000 -- 107FFFFF
+         * CSB[0]            EXTRN      02000000 -- 0201FFFF
+         * CAS[01]/RAS[01]   DRAM       00000000 -- 007FFFFF
+         */
+
+#define CSGBA_INIT (0x10000000 >> 13)      /* FLASH starts at 0x10000000 */
+#define CSGBB_INIT (0x02000000 >> 13)      /* EXTRN starts at 0x02000000 */
+#define CSGBD_INIT (0x00000000 >> 13)      /* DRAM  starts at 0x00000000 */
+
+#define CSA_INIT \
+        (CSA_FLASH              |       /* CSA controls FLASH memory */ \
+         CSA_BSW                |       /* 16-bit bus Width */          \
+/*       PUT_FIELD(CSA_WS, 2) */|       /* 2 Wait States */             \
+         PUT_FIELD(CSA_SIZ, 5)  |       /* Total FLASH size is 4M */  \
+         CSA_EN)                        /* Enable it */
+
+#define CSB_INIT \
+         (CSA_BSW               |       /* 16-bit bus Width */          \
+         CSA_EN)                        /* Enable it */
+
+#define CSD_INIT \
+        (CSD_DRAM               |       /* CSD Controls DRAM */         \
+         CSD_COMB               |       /* RAS0 operates entire RAM. */ \
+         CSD_BSW                |       /* 16-bit bus width */          \
+/*       PUT_FIELD(CSD_WS, 1) */|       /* 1 Wait State */              \
+         PUT_FIELD(CSD_SIZ, 7)  |       /* The board has 4MB DRAM */   \
+         CSD_EN)                        /* Enable it */
+
+#define DRAMMC_INIT \
+        (DRAMMC_ROW12_PA23      |       /* PA23 -> MD12 */      \
+         DRAMMC_ROW11           |       /* PA22 -> MD11 */      \
+         DRAMMC_ROW10           |       /* PA21 -> MD10 */      \
+         DRAMMC_ROW9            |       /* PA19 -> MD9  */      \
+         DRAMMC_ROW8)                   /* PA20 -> MD8  */      \
+ 
+#define DRAMC_INIT \
+        (DRAMC_EN               |       /* Enable DRAM controller */    \
+         DRAMC_EDO              |       /* We have EDO DRAM */          \
+         DRAMC_PGSZ_1024K       |       /* 1k page. */                  \
+         DRAMC_MSW              |       /* Slow address MUXing. */      \
+/*       PUT_FIELD(DRAMC_WS, 1) */|     /* 1 Wait State */              \
+         PUT_FIELD(DRAMC_BC, 1) |       /* 1 Page Access Clock Cycle.*/ \
+         DRAMC_LPR              |       /* Low-Power Refresh Enable */  \
+         DRAMC_RST              |       /* Reset Burst Refresh Enable */\
+         DRAMC_DWE)                     /* DRAM Write Enable */
+
+        movew   #CSGBA_INIT,  CSGBA_ADDR        /* FLASH */
+        movew   #CSA_INIT,    CSA_ADDR
+
+        movew   #CSGBB_INIT,  CSGBB_ADDR        /* EXTRN */
+        movew   #CSB_INIT,    CSB_ADDR
+
+        movew   #DRAMMC_INIT, DRAMMC_ADDR       /* DRAM */
+        movew   #DRAMC_INIT,  DRAMC_ADDR
+        movew   #CSGBD_INIT,  CSGBD_ADDR
+        movew   #CSD_INIT,    CSD_ADDR
+
+        /*
+         * Program the UART (115200 cs8 -parenb -cstopb -crtscts */
+         */
+#define PLLCR_INIT \
+        (PUT_FIELD(PLLCR_SYSCLK_SEL, 4) | PUT_FIELD(PLLCR_LCDCLK_SEL, 4))
+ 
+#define USTCNT_INIT \
+        (USTCNT_UEN | USTCNT_RXEN | USTCNT_TXEN | USTCNT_8_7)
+ 
+#define UBAUD_INIT \
+        (PUT_FIELD(UBAUD_DIVIDE, 0) | PUT_FIELD(UBAUD_PRESCALER, 0x38))
+ 
+#define UTX_INIT \
+        (UTX_NOCTS)
+ 
+        movew   #(USTCNT_UEN | USTCNT_RXEN), USTCNT_ADDR
+        tstw    USTCNT_ADDR
+        movew   #USTCNT_INIT, USTCNT_ADDR
+        movew   #PLLCR_INIT,  PLLCR_ADDR
+        movew   #UBAUD_INIT,  UBAUD_ADDR
+        moveb   #(UTX_INIT>>8),    UTX_ADDR                                     
+
+	movew	#0x2700, %sr
+
+	moveb   #0,    LCKCON_ADDR		/* LCD is off */
+#if CONFIG_EZSIMM_LCD && CONFIG_EZSIMM_EG9013
+	/* this is for the EG9013 display. */
+	movel	#splash_bits, LSSA_ADDR 	/* LCD starting address. */
+	moveb	#0x28,   LVPW_ADDR 		/* LCD Virtual Page Width Register. */
+	movew	#0x280,  LXMAX_ADDR 		/* LCD Screen Width Register. */
+	movew	#0x1df,  LYMAX_ADDR 		/* LCD Screen Height Register. */
+	moveb	#0,      LRRA_ADDR		/* LCD refresh rate. */
+	moveb	#0,      LPXCD_ADDR		/* LCD Pixel Clock Divider Register. */
+	moveb	#0x08,   LPICF_ADDR		/* LCD Panel Interface Config Register. */
+	moveb	#0x01,   LPOLCF_ADDR		/* LCD Polarity Configuration Register. */
+	moveb	#0x81,   LCKCON_ADDR		/* LCD Clocking Control Register. */
+	movew	#0xff00, PCPDEN_ADDR		/* LCD pins Port C Pull-Down enb. reg */
+#endif
+
+#if CONFIG_EZSIMM_LCD && CONFIG_EZSIMM_LM32019
+	/* this is for the LM32019 display. */
+	movel	#splash_bits, LSSA_ADDR 	/* LCD starting address. */
+	moveb	#0x14,   LVPW_ADDR 		/* LCD Virtual Page Width Register. */
+	movew	#0x140,  LXMAX_ADDR 		/* LCD Screen Width Register. */
+	movew	#0xef,   LYMAX_ADDR 		/* LCD Screen Height Register. */
+	moveb	#0,      LRRA_ADDR		/* LCD refresh rate. */
+	moveb	#1,      LPXCD_ADDR		/* LCD Pixel Clock Divider Register. */
+	moveb	#0x08,   LPICF_ADDR		/* LCD Panel Interface Config Register. */
+	moveb	#0x00,   LPOLCF_ADDR		/* LCD Polarity Configuration Register. */
+	moveb	#0x81,   LCKCON_ADDR		/* LCD Clocking Control Register. */
+	movew	#0xff00, PCPDEN_ADDR		/* LCD pins Port C Pull-Down enb. reg */
+#endif
+
+	/*
+	 * Here we start doing some real things
+	 */
+	moveq	#13, %d7		/* '\r' */
+	jsr putc
+
+	moveq	#10, %d7		/* '\n' */
+	jsr putc
+
+	moveq	#65, %d7		/* 'A' */
+	jsr putc
+
+	movew	#16384, %d0  /* PLL settle wait loop */
+L0:
+	subw	#1, %d0
+	bne	L0
+
+	moveq	#66, %d7		/* 'B' */
+	jsr	putc
+
+	/* Copy data segment from ROM to RAM */
+	moveal	#__data_rom_start, %a0
+	moveal	#_sdata, %a1
+	moveal	#_edata, %a2
+	moveq	#67, %d7		/* 'C' */
+	jsr	putc
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:
+	movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bhi	LD1
+
+	moveq	#68, %d7		/* 'D' */
+	jsr	putc
+
+	moveal	#_sbss,	%a0
+	moveal	#_ebss, %a1
+	/* Copy 0 to %a0 until %a0 == %a1 */
+
+_clear_bss:
+	movel	#0, %a0@+
+	cmpal	%a0, %a1
+	bhi	_clear_bss
+
+	movel	#_sdata, %d0
+	movel	%d0, _rambase
+	movel	#_ebss,  %d0
+	movel	%d0, _ramstart
+	movel   #__ramend, %d0
+
+	movel	%d0, _ramend
+	movel	#__ramvec, %d0
+	movel	%d0, _ramvec
+
+	moveq	#69, %d7		/* 'E' */
+	jsr	putc
+
+	/*
+	 * load the current task pointer and stack
+	 */
+
+	 lea	init_task_union,%a0
+	 movel	%a0, _current_task
+	 lea	0x2000(%a0),%sp
+
+	 moveq	#70, %d7		/* 'F' */
+	 jsr	putc
+
+	 moveq	#13, %d7		/* '\r' */
+	 jsr	putc
+
+	 moveq	#10, %d7		/* '\n' */
+	 jsr	putc
+
+lp:
+	jsr	start_kernel
+	jmp	lp
+_exit:
+
+	jmp	_exit
+
+
+putc:
+	moveb	%d7,UTX_TXDATA_ADDR
+pclp:
+	movew	UTX_ADDR, %d7
+	andw	#UTX_TX_AVAIL, %d7
+	beq	pclp
+	rts
+
+	.data
+env:
+	.long	0
+	.text
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/crt0_himem.S linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/crt0_himem.S
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/crt0_himem.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/crt0_himem.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,172 @@
+	.global __text_start
+	.global __main
+	.global __bss_start
+	.global __bss_end
+	.global __ram_start
+	.global __ram_end
+	.global __rom_start
+	.global __rom_end
+	.global __data_start
+	.global __data_end
+
+        .global _rambase
+        .global _ramstart
+	
+	.global splash_bits
+	.global _start
+	.global _stext
+
+#define DEBUG
+#define ROM_OFFSET 0x10C00000
+#define STACK_GAURD 0x10
+
+	.text
+	
+_start:
+_stext:
+	movew	#0x2700, %sr            /* Exceptions off! */
+
+	/* Init chip registers.  uCsimm specific */
+	moveb	#0x00,   0xfffffb0b	/* Watchdog off */
+	moveb	#0x10,   0xfffff000	/* SCR */
+
+	movew   #0x2400, 0xfffff200	/* PLLCR */
+	movew   #0x0123, 0xfffff202	/* PLLFSR */
+
+	moveb	#0x00,   0xfffff40b	/* enable chip select */
+	moveb	#0x00,   0xfffff423	/* enable /DWE */
+	moveb	#0x08,   0xfffffd0d	/* disable hardmap */
+	moveb	#0x07,   0xfffffd0e	/* level 7 interrupt clear */
+
+	movew	#0x8600, 0xfffff100	/* FLASH at 0x10c00000 */
+	movew	#0x018b, 0xfffff110	/* 2Meg, enable, 0ws */
+
+	movew	#0x8f00, 0xfffffc00	/* DRAM configuration */
+	movew	#0x9667, 0xfffffc02	/* DRAM control */
+	movew	#0x0000, 0xfffff106	/* DRAM at 0x00000000 */
+	movew	#0x068f, 0xfffff116	/* 8Meg, enable, 0ws */
+
+	moveb	#0x40,   0xfffff300	/* IVR */
+	movel	#0x007FFFFF, %d0	/* IMR */
+	movel	%d0,     0xfffff304
+
+	moveb	0xfffff42b, %d0
+	andb	#0xe0,	 %d0
+	moveb	%d0,	 0xfffff42b
+
+	moveb	#0x08,   0xfffff907	/* Ignore CTS */
+	movew	#0x010b, 0xfffff902	/* BAUD to 9600 */
+	movew	#0xe100, 0xfffff900	/* enable */
+
+	movew	#16384, %d0  /* PLL settle wait loop */
+L0:
+	subw	#1, %d0
+	bne	L0
+#ifdef DEBUG
+	moveq	#70, %d7		/* 'F' */
+	moveb	%d7,0xfffff907          /* No absolute addresses */
+pclp1:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	pclp1
+#endif /* DEBUG */
+
+#ifdef CONFIG_RELOCATE
+	/* Copy me to RAM */
+	moveal	#__rom_start, %a0
+	moveal	#__ram_start, %a1
+	moveal	#__data_end, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:
+	movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bhi	LD1
+	
+#ifdef DEBUG
+	moveq	#74, %d7		/* 'J' */
+	moveb	%d7,0xfffff907          /* No absolute addresses */
+pclp2:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	pclp2
+#endif /* DEBUG */
+	/* jump into the RAM copy */
+	jmp     ram_jump
+ram_jump:
+
+#endif /* CONFIG_RELOCATE */
+
+#ifdef DEBUG
+	moveq	#82, %d7		/* 'R' */
+	moveb	%d7,0xfffff907          /* No absolute addresses */
+pclp3:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	pclp3
+#endif /* DEBUG */
+	moveal	#0x007ffff0, %ssp
+	moveal	#__bss_start, %a0
+	moveal	#__bss_end, %a1
+
+	/* Copy 0 to %a0 until %a0 >= %a1 */
+L1:
+	movel	#0, %a0@+
+	cmpal	%a0, %a1
+	bhi	L1
+
+#ifdef DEBUG
+	moveq	#67, %d7                /* 'C' */
+	jsr	putc
+#endif /* DEBUG */
+
+	pea	0
+	pea	env
+	pea	%sp@(4)
+	pea	0
+
+#ifdef DEBUG
+	moveq	#70, %d7		/* 'F' */
+	jsr	putc
+#endif /* DEBUG */
+
+lp:
+	jsr	start_kernel
+        jmp lp
+_exit:
+
+	jmp	_exit
+
+__main:
+	/* nothing */
+	rts
+
+#ifdef DEBUG
+putc:
+	moveb	%d7,0xfffff907
+pclp:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	pclp
+	rts
+#endif /* DEBUG */
+
+	.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+env:
+	.long	0
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/crt0_rom.S linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/crt0_rom.S
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/crt0_rom.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/crt0_rom.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/fixed.ld linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/fixed.ld
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/fixed.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/fixed.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,95 @@
+SECTIONS
+{
+  .romvec :
+	{
+	_flashstart = . ;
+	_romvec = . ;
+	__rom_start = . ;
+	} > romvec
+
+  .text :
+	{
+	_stext = . ;
+        	*(.text)
+	. = ALIGN(0x4) ;
+		*(.text.*)
+	. = ALIGN(0x4) ;
+		*(.exitcall.exit)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	. = ALIGN(0x4) ;
+	_etext = . ;
+	__data_rom_start = . ;
+        } > flash
+
+  .eflash :
+	{
+	_flashend = . ;
+	} > eflash
+
+  .ramvec :
+	{
+	__ram_start = . ;
+	__ramvec = . ;
+	} > ramvec
+
+  .data :
+	{
+	. = ALIGN(0x4) ;
+	_sdata = . ;
+	__data_start = . ;
+
+	. = ALIGN(0x4) ;
+		*(.rodata)
+	. = ALIGN(0x4) ;
+		*(.rodata.str1.1)
+	. = ALIGN(0x4) ;
+		*(.data)
+	. = ALIGN(0x4) ;
+		*(.data.*)	
+
+	. = ALIGN(0x4) ;
+	__setup_start = .;
+		*(.setup.init)
+	. = ALIGN(0x4) ;
+	__setup_end = .;
+
+	. = ALIGN(0x4) ;
+	__initcall_start = .;
+		*(.initcall.init)
+	. = ALIGN(0x4) ;
+	__initcall_end = .;
+
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	. = ALIGN(0x2000) ;
+
+	_edata = . ;
+        } > ram
+
+  .bss :
+        {
+	. = ALIGN(0x4) ;
+	_sbss = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	_ebss = . ;
+	_end = . ;
+	} > ram
+
+  .eram :
+	{
+	__ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/himem.ld linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/himem.ld
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/himem.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/himem.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,11 @@
+MEMORY 
+	{
+        romvec : ORIGIN = 0x00600000, LENGTH = 0x00000400
+        flash  : ORIGIN = 0x00600400, LENGTH = 0x00200000 - 0x00010400
+        eflash : ORIGIN = 0x007f0000, LENGTH = 0
+        ramvec : ORIGIN = 0x00000000, LENGTH = 0x00000400
+        ram    : ORIGIN = 0x00020000, LENGTH = 0x00600000 - 0x00020000
+        eram   : ORIGIN = 0x00600000, LENGTH = 0
+	}
+
+INCLUDE arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,103 @@
+MEMORY 
+	{
+	romvec : ORIGIN = 0x10c10000, LENGTH = 0x00000400
+	flash  : ORIGIN = 0x10c10400, LENGTH = 0x00200000 - 0x00010400
+	eflash : ORIGIN = 0x10e00000, LENGTH = 0
+	ramvec : ORIGIN = 0x00000000, LENGTH = 0x00000400
+	bvec   : ORIGIN = 0x00020000, LENGTH = 0x00000400
+	ram    : ORIGIN = 0x00020400, LENGTH = 0x00800000 - 0x00020400
+	eram   : ORIGIN = 0x00800000, LENGTH = 0
+	}
+
+SECTIONS
+{
+	.fakevec :
+	{
+	} > romvec
+	.rom :
+	{
+	__rom_start = . ;
+	} > flash
+	.eflash :
+	{
+	_flashend = . ;
+	} > eflash
+	.realvec :
+	{
+	_ramvec = . ;
+	} > ramvec
+	.romvec :
+	{
+	_romvec = . ;
+	} > bvec
+        .text :
+	{
+	__ram_start = . ;
+	text_start = . ;
+        	*(.text)
+		*(.text.*)
+		*(.rodata)
+		*(.rodata.str1.1)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	_etext = . ;
+	__data_rom_start = ALIGN ( 4 ) ;
+        } > ram
+        .data :
+	{
+	_sdata = . ;
+	__data_start = . ;
+
+        . = ALIGN(0x2000) ;
+        *(.data.init_task)
+        . = ALIGN(0x2000) ;
+
+        *(.data)
+        *(.data.*)      
+        *(.setup.init)          
+        *(.exitcall.exit)               
+
+        . = ALIGN(4096) ;
+        __init_begin = .;
+        *(.text.init)
+        *(.data.init)
+        . = ALIGN(16);
+        __setup_start = .;
+        *(.setup.init)
+        __setup_end = .;
+        __initcall_start = .;
+        *(.initcall.init)
+        . = ALIGN(4) ;
+        __initcall_end = .;
+        __init_end = .;
+
+	_edata = . ;
+	edata = ALIGN( 0x10 ) ;
+        } > ram
+        .bss :
+        {
+	_sbss = ALIGN( 0x10 ) ;
+	__bss_start = ALIGN( 0x10 ) ;
+	__data_end = ALIGN( 0x10 ) ;
+	*(.bss)
+	*(COMMON)
+	_ebss = . ;
+	__bss_end = . ;
+	end = ALIGN( 0x10 ) ;
+	_end = ALIGN( 0x10 ) ;
+	} > ram
+	.eram :
+	{
+	__ramend = . ;
+	_ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/rom.ld linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/rom.ld
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/cwez328/rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/cwez328/rom.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,11 @@
+MEMORY 
+	{
+        romvec : ORIGIN = 0x10000000, LENGTH = 0x00000400
+        flash  : ORIGIN = 0x10000400, LENGTH = 0x400000 - 0x400
+        eflash : ORIGIN = 0x10400000, LENGTH = 1
+        ramvec : ORIGIN = 0x00000000, LENGTH = 0x400
+        ram    : ORIGIN = 0x00000400, LENGTH = 0x00400000 - 0x00000400
+        eram   : ORIGIN = 0x00400000, LENGTH = 1
+	}
+
+INCLUDE arch/m68knommu/platform/68EZ328/cwez328/fixed.ld
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/ints.c linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ints.c
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/ints.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ints.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,360 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne <jeff@uClinux.org>
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+
+#include <asm/MC68EZ328.h>
+
+#define INTERNAL_IRQS (32)
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void exception3(void);
+asmlinkage void exception4(void);
+asmlinkage void exception5(void);
+asmlinkage void exception6(void);
+asmlinkage void exception7(void);
+asmlinkage void exception8(void);
+asmlinkage void exception9(void);
+asmlinkage void exception10(void);
+asmlinkage void exception11(void);
+asmlinkage void exception14(void);
+asmlinkage void exception15(void);
+asmlinkage void bad_interrupt(void);
+asmlinkage void inthandler1(void);
+asmlinkage void inthandler2(void);
+asmlinkage void inthandler3(void);
+asmlinkage void inthandler4(void);
+asmlinkage void inthandler5(void);
+asmlinkage void inthandler6(void);
+asmlinkage void inthandler7(void);
+asmlinkage void system_call(void);
+asmlinkage void trap1(void);
+asmlinkage void trap15(void);
+
+// extern void *_ramvec[];
+extern e_vector *_ramvec;
+
+/* irq node variables for the 32 (potential) on chip sources */
+static irq_node_t *int_irq_list[INTERNAL_IRQS];
+
+static int int_irq_count[INTERNAL_IRQS];
+static short int_irq_ablecount[INTERNAL_IRQS];
+
+static void int_badint(int irq, void *dev_id, struct pt_regs *fp)
+{
+	num_spurious += 1;
+}
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the amiga IRQ handling routines.
+ */
+
+void M68EZ328_init_IRQ(void)
+{
+	int i;
+
+        /* set up the vectors */
+        for (i=2; i < 32; ++i)
+                _ramvec[i] = bad_interrupt;
+
+        _ramvec[2] = buserr;
+        _ramvec[3] = exception3;
+        _ramvec[4] = exception4;
+        _ramvec[5] = exception5;
+        _ramvec[6] = exception6;
+        _ramvec[7] = exception7;
+        _ramvec[8] = exception8;
+        _ramvec[9] = exception9;
+        _ramvec[10] = exception10;
+        _ramvec[11] = exception11;
+        _ramvec[14] = exception14;
+        _ramvec[15] = exception15;
+        _ramvec[32] = system_call;
+        _ramvec[33] = trap1;
+        _ramvec[47] = trap15;
+
+        _ramvec[64] = bad_interrupt;
+        _ramvec[65] = inthandler1;
+        _ramvec[66] = inthandler2;
+        _ramvec[67] = inthandler3;
+        _ramvec[68] = inthandler4;
+        _ramvec[69] = inthandler5;
+        _ramvec[70] = inthandler6;
+        _ramvec[71] = inthandler7;
+ 
+	IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
+
+	/* initialize handlers */
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		int_irq_list[i] = NULL;
+
+		int_irq_ablecount[i] = 0;
+		int_irq_count[i] = 0;
+	}
+	/* turn off all interrupts */
+	IMR = ~0;
+}
+
+void M68EZ328_insert_irq(irq_node_t **list, irq_node_t *node)
+{
+	unsigned long flags;
+	irq_node_t *cur;
+
+	if (!node->dev_id)
+		printk("%s: Warning: dev_id of %s is zero\n",
+		       __FUNCTION__, node->devname);
+
+	save_flags(flags);
+	cli();
+
+	cur = *list;
+
+	while (cur) {
+		list = &cur->next;
+		cur = cur->next;
+	}
+
+	node->next = cur;
+	*list = node;
+
+	restore_flags(flags);
+}
+
+void M68EZ328_delete_irq(irq_node_t **list, void *dev_id)
+{
+	unsigned long flags;
+	irq_node_t *node;
+
+	save_flags(flags);
+	cli();
+
+	for (node = *list; node; list = &node->next, node = *list) {
+		if (node->dev_id == dev_id) {
+			*list = node->next;
+			/* Mark it as free. */
+			node->handler = NULL;
+			restore_flags(flags);
+			return;
+		}
+	}
+	restore_flags(flags);
+	printk ("%s: tried to remove invalid irq\n", __FUNCTION__);
+}
+
+int M68EZ328_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                         unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+	if (!int_irq_list[irq]) {
+		int_irq_list[irq] = new_irq_node();
+		int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	}
+
+	if (!(int_irq_list[irq]->flags & IRQ_FLG_STD)) {
+		if (int_irq_list[irq]->flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+	}
+	int_irq_list[irq]->handler = handler;
+	int_irq_list[irq]->flags   = flags;
+	int_irq_list[irq]->dev_id  = dev_id;
+	int_irq_list[irq]->devname = devname;
+
+	/* enable in the IMR */
+	if (!int_irq_ablecount[irq])
+		*(volatile unsigned long *)0xfffff304 &= ~(1<<irq);
+
+	return 0;
+}
+
+void M68EZ328_free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_list[irq]->dev_id != dev_id)
+		printk("%s: removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, int_irq_list[irq]->devname);
+	int_irq_list[irq]->handler = int_badint;
+	int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	int_irq_list[irq]->dev_id  = NULL;
+	int_irq_list[irq]->devname = NULL;
+
+	*(volatile unsigned long *)0xfffff304 |= 1<<irq;
+}
+
+/*
+ * Enable/disable a particular machine specific interrupt source.
+ * Note that this may affect other interrupts in case of a shared interrupt.
+ * This function should only be called for a _very_ short time to change some
+ * internal data, that may not be changed by the interrupt at the same time.
+ * int_(enable|disable)_irq calls may also be nested.
+ */
+
+void M68EZ328_enable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (--int_irq_ablecount[irq])
+		return;
+
+	/* enable the interrupt */
+	*(volatile unsigned long *)0xfffff304 &= ~(1<<irq);
+}
+
+void M68EZ328_disable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_ablecount[irq]++)
+		return;
+
+	/* disable the interrupt */
+	*(volatile unsigned long *)0xfffff304 |= 1<<irq;
+}
+
+/* The 68k family did not have a good way to determine the source
+ * of interrupts until later in the family.  The EC000 core does
+ * not provide the vector number on the stack, we vector everything
+ * into one vector and look in the blasted mask register...
+ * This code is designed to be fast, almost constant time, not clean!
+ */
+inline int M68EZ328_do_irq(int vec, struct pt_regs *fp)
+{
+	int irq;
+	int mask;
+
+	unsigned long pend = *(volatile unsigned long *)0xfffff30c;
+
+	while (pend) {
+		if (pend & 0x0000ffff) {
+			if (pend & 0x000000ff) {
+				if (pend & 0x0000000f) {
+					mask = 0x00000001;
+					irq = 0;
+				} else {
+					mask = 0x00000010;
+					irq = 4;
+				}
+			} else {
+				if (pend & 0x00000f00) {
+					mask = 0x00000100;
+					irq = 8;
+				} else {
+					mask = 0x00001000;
+					irq = 12;
+				}
+			}
+		} else {
+			if (pend & 0x00ff0000) {
+				if (pend & 0x000f0000) {
+					mask = 0x00010000;
+					irq = 16;
+				} else {
+					mask = 0x00100000;
+					irq = 20;
+				}
+			} else {
+				if (pend & 0x0f000000) {
+					mask = 0x01000000;
+					irq = 24;
+				} else {
+					mask = 0x10000000;
+					irq = 28;
+				}
+			}
+		}
+
+		while (! (mask & pend)) {
+			mask <<=1;
+			irq++;
+		}
+
+		if (int_irq_list[irq] && int_irq_list[irq]->handler) {
+			int_irq_list[irq]->handler(irq, int_irq_list[irq]->dev_id, fp);
+			int_irq_count[irq]++;
+		} else {
+			printk("unregistered interrupt %d!\nTurning it off in the IMR...\n", irq);
+			*(volatile unsigned long *)0xfffff304 |= mask;
+		}
+		pend &= ~mask;
+	}
+	return 0;
+}
+
+int M68EZ328_get_irq_list(char *buf)
+{
+	int i, len = 0;
+	irq_node_t *node;
+
+	len += sprintf(buf+len, "Internal 68EZ328 interrupts\n");
+
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		if (!(node = int_irq_list[i]))
+			continue;
+		if (!(node->handler))
+			continue;
+
+		len += sprintf(buf+len, " %2d: %10u    %s\n", i,
+		               int_irq_count[i], int_irq_list[i]->devname);
+	}
+	return len;
+}
+
+void config_M68EZ328_irq(void)
+{
+	mach_default_handler = NULL;
+	mach_init_IRQ        = M68EZ328_init_IRQ;
+	mach_request_irq     = M68EZ328_request_irq;
+	mach_free_irq        = M68EZ328_free_irq;
+	mach_enable_irq      = M68EZ328_enable_irq;
+	mach_disable_irq     = M68EZ328_disable_irq;
+	mach_get_irq_list    = M68EZ328_get_irq_list;
+	mach_process_int     = M68EZ328_do_irq;
+}
+
+void init_irq_proc(void);
+void init_irq_proc(void)
+{
+	/* Insert /proc/irq driver here */
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/Makefile
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,37 @@
+#
+# Makefile for the linux kernel.
+#
+# Reuse any files we can from the 68328 base
+#
+
+VPATH := $(VPATH):../68328
+
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o traps.o ints.o
+
+obj-$(CONFIG_PM) += pm.o
+
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S $(BOARD)/bootlogo.rh
+
+entry.o: entry.S m68k_defs.h
+
+m68k_defs.h: ../../kernel/m68k_defs.c ../../kernel/m68k_defs.head
+	rm -f m68k_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/m68k_defs.c
+	cp ../../kernel/m68k_defs.head m68k_defs.h
+	grep '^#define' m68k_defs.s >> m68k_defs.h
+	rm m68k_defs.s
+-include m68k_defs.d
+
+$(BOARD)/bootlogo.rh: $(BOARD)/bootlogo.h
+	perl ../68328/tools/bootlogo.pl < $(BOARD)/bootlogo.h > $(BOARD)/bootlogo.rh
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/Rules.make linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/Rules.make
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/Rules.make	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,72 @@
+#
+# 68EZ328/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 2000,2001  Lineo, Inc. <jeff@uClinux.org> 
+# Copyright (c) 1998,1999  D. Jeff Dionne <jeff@uclinux.org>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+#
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/m68000/libgcc.a
+
+CFLAGS := -fno-builtin -DNO_CACHE $(CFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -m68000 -D__ELF__ -DMAGIC_ROM_PTR -DNO_FORGET -DUTS_SYSNAME=\"uClinux\" -D__linux__
+AFLAGS := $(AFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -m68000 -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME=\"uClinux\" -Wa,--bitwise-or
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+ifdef CONFIG_FRAMEBUFFER
+SUBDIRS := $(SUBDIRS) arch/$(ARCH)/console
+ARCHIVES := $(ARCHIVES) arch/$(ARCH)/console/console.a
+endif
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+romfs.s19: romfs.img arch/$(ARCH)/empty.o
+	$(CROSS_COMPILE)objcopy -v -R .text -R .data -R .bss --add-section=.fs=romfs.img --adjust-section-vma=.fs=0xa0000 arch/$(ARCH)/empty.o romfs.s19
+	$(CROSS_COMPILE)objcopy -O srec romfs.s19
+
+linux.data: linux
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.romvec --remove-section=.text --remove-section=.ramvec --remove-section=.bss --remove-section=.eram linux linux.data
+
+linux.text: linux
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.ramvec --remove-section=.bss --remove-section=.data --remove-section=.eram --set-section-flags=.romvec=CONTENTS,ALLOC,LOAD,READONLY,CODE linux linux.text
+
+romfs.img:
+	echo creating a vmlinux rom image without root filesystem!
+
+linux.bin: linux.text linux.data romfs.img
+	if [ -f romfs.img ]; then\
+		cat linux.text linux.data romfs.img > linux.bin;\
+	else\
+		cat linux.text linux.data > linux.bin;\
+	fi
+
+linux.trg linux.rom: linux.bin
+	perl arch/$(ARCH)/platform/$(PLATFORM)/tools/fixup.pl
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f arch/$(ARCH)/platform/$(PLATFORM)/m68k_defs.h
+	rm -f linux.text linux.data linux.bin linux.rom linux.trg
+	rm -f linux.s19 romfs.s19
+	rm -f linux.img romdisk.img
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/bootlogo.h linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/bootlogo.h
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/bootlogo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/bootlogo.h	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,3204 @@
+#define splash_width 640
+#define splash_height 480
+static unsigned char splash_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf8, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x7f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xfe, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x7c, 0x00, 0xe0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0xe0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3e, 0xf8, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
+  0x00, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0xfe, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+  0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xe0, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff, 0x07, 0xfe, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0x01, 0xf8, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff,
+  0x00, 0xf0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0xe0, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x03,
+  0x3f, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x3f, 0x00, 0xc0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x0f, 0xfc, 0x00, 0x00, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f,
+  0x00, 0x80, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xff, 0xff, 0x3f, 0xf0, 0x01, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x80, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0xc0, 0xff,
+  0xc1, 0x03, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x07, 0x00, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f,
+  0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x07, 0x00, 0x00, 0xe0, 0x07, 0x0e, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x00,
+  0x3f, 0x1c, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x38, 0x00, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f,
+  0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e,
+  0x00, 0x00, 0x00, 0x00, 0x78, 0x70, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xe0, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc3, 0x01, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f,
+  0x00, 0x80, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x80, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x87, 0x03, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x3f, 0x00, 0xc0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x07, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f,
+  0x00, 0xe0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0e, 0x00, 0xf0, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf0, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x30, 0x0c, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0x01, 0xf8, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1c, 0x00,
+  0xf0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x07, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x38, 0x00, 0xf0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0x38, 0x00, 0xf0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00,
+  0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0xe0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe2, 0x00, 0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00,
+  0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0xc0, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x01, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01,
+  0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x80, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x03, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03,
+  0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07,
+  0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0xfe, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07,
+  0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0xf8, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07,
+  0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0xf0, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x07, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x9f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+  0xf8, 0xff, 0x1f, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0xff, 0xff, 0x00,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x38, 0x00, 0xfe, 0xff, 0x0f, 0x20, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0xf8, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xc0, 0xff, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0xfc, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0xe0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff,
+  0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xfc, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x1f, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+  0xfe, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xf0, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x38, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0xf8, 0xff, 0x01, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xc0, 0xff, 0x01,
+  0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0xfc, 0x01, 0xff, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x41, 0x08, 0x04, 0xb3, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0xe0, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x41, 0x08, 0x04, 0xb3, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x8e, 0x31, 0x7b, 0x30,
+  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x18, 0x8e, 0x31, 0x7b, 0x30, 0x30, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0xf8,
+  0x41, 0xc6, 0x84, 0x0c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0xf8, 0x41, 0xc6, 0x84, 0x0c,
+  0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x0f, 0x00, 0x00, 0x18, 0x0c, 0x08, 0x00, 0x40, 0xc0, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xe4,
+  0xb1, 0xc1, 0x98, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xe4, 0xb1, 0xc1, 0x98, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+  0x08, 0x00, 0x00, 0x1c, 0x02, 0x08, 0x04, 0x4c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0xff, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1c,
+  0x02, 0x08, 0x04, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x1f, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x10, 0x80,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x64, 0x4c, 0x00, 0x00, 0x00,
+  0x36, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x09, 0x00, 0x00, 0x64, 0x4c, 0x00, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x9c,
+  0x01, 0x08, 0x83, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0xf0, 0xff,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x64, 0x8c, 0x01, 0x18, 0x40,
+  0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x0f, 0x00, 0x00, 0x64, 0x8c, 0x01, 0x18, 0x40, 0x30, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0x03, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x9b,
+  0x01, 0xc0, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x40,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0x9b, 0x01, 0xc0, 0x00, 0x00,
+  0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+  0x00, 0x00, 0x00, 0x07, 0x32, 0x06, 0x18, 0x43, 0x00, 0x06, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf0, 0xc1, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x02, 0x02, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x07,
+  0x32, 0x06, 0x18, 0x43, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x10, 0xe0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x7b, 0x00, 0x30, 0x03, 0x0c,
+  0x08, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x07, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x09, 0x00, 0xc0, 0x84, 0x8d, 0x01, 0x80, 0x00, 0xc0, 0x06, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xfd, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xc0, 0x84,
+  0x8d, 0x01, 0x80, 0x00, 0xc0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfd, 0x03, 0xf0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc0, 0x1b, 0x00, 0x30, 0x00, 0x40,
+  0x08, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xfc, 0x01, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0xc0, 0x1b, 0x00, 0x30, 0x00, 0x40, 0x08, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x07, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+  0xf8, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc0, 0x64,
+  0x42, 0x06, 0x1b, 0x03, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x10, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0x64, 0x42, 0x06, 0x1b, 0x03,
+  0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0x03, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x0f, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x80, 0x30, 0x08, 0x86, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x3f, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x1b,
+  0x00, 0x00, 0x80, 0x30, 0x08, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xc3, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0xe0, 0x84, 0x31, 0x30, 0x04, 0x80,
+  0xc1, 0x18, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x09, 0x00, 0xc0, 0x63, 0x02, 0x06, 0x00, 0x00, 0x00, 0x60, 0x6c, 0xfc,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+  0xe0, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x08, 0x00, 0xc0, 0x63,
+  0x02, 0x06, 0x00, 0x00, 0x00, 0x60, 0x6c, 0xfc, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xe0, 0x1c, 0x40, 0x00, 0x1b, 0x4c,
+  0x06, 0x81, 0x80, 0xfd, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x00, 0xf0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0xe0, 0x1c, 0x40, 0x00, 0x1b, 0x4c, 0x06, 0x81, 0x80, 0xfd,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x00, 0x80, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x09, 0x00, 0x20, 0x63,
+  0x0c, 0x08, 0x80, 0x00, 0x30, 0x06, 0x0c, 0xfc, 0xff, 0x7f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x30, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x20, 0x63, 0x0c, 0x08, 0x80, 0x00,
+  0x30, 0x06, 0x0c, 0xfc, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x0f, 0x00, 0xd8, 0x84, 0x01, 0xc0, 0x00, 0x00, 0x06, 0x00, 0x80, 0xf1,
+  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0xf8, 0x1b,
+  0x40, 0x08, 0x84, 0x0c, 0xc0, 0x18, 0x13, 0xcc, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xe0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0xf8, 0x1b, 0x40, 0x08, 0x84, 0x0c,
+  0xc0, 0x18, 0x13, 0xcc, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0xf0, 0xe4, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x09, 0x00, 0x38, 0x80, 0x01, 0x00, 0x18, 0x30, 0x06, 0x01, 0x00, 0xc0,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+  0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x07, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x38, 0x80,
+  0x01, 0x00, 0x18, 0x30, 0x06, 0x01, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x10, 0x84,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xd8, 0x1f, 0x30, 0x36, 0x80, 0x00,
+  0x00, 0x00, 0x03, 0xf2, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x4f, 0x0e, 0x00, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x08, 0x00, 0xd8, 0x1f, 0x30, 0x36, 0x80, 0x00, 0x00, 0x00, 0x03, 0xf2,
+  0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+  0x08, 0x00, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x09, 0x00, 0x3e, 0x00,
+  0x82, 0x01, 0x03, 0x40, 0x30, 0x98, 0x10, 0xf0, 0xe7, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x1f, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0x00, 0x10, 0xe4,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xe6, 0x1b, 0x00, 0x00, 0x18, 0x0c,
+  0x00, 0x00, 0x00, 0xfc, 0xff, 0xfb, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x41, 0x08, 0x00, 0x30, 0x7c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0xe6, 0x1b, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0xfc,
+  0xff, 0xfb, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+  0x08, 0x00, 0x20, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1e, 0x64,
+  0x30, 0xc6, 0x80, 0x80, 0x09, 0x06, 0x63, 0xfe, 0xf9, 0xff, 0xff, 0xff,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x30, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xf8, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0e, 0x00, 0xc0, 0x3c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1e, 0x64, 0x30, 0xc6, 0x80, 0x80,
+  0x09, 0x06, 0x63, 0xfe, 0xf9, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc3, 0x07, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0e, 0x00, 0x39, 0x03, 0x00, 0x00, 0x04, 0x0c, 0xc0, 0x60, 0x80, 0x3f,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0xfc, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x39, 0x03,
+  0x00, 0x00, 0x04, 0x0c, 0xc0, 0x60, 0x80, 0x3f, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3e, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x80, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0xe7, 0x04, 0x42, 0xc6, 0x00, 0x00,
+  0x00, 0x00, 0xec, 0xcf, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x0f, 0xc0, 0x1f, 0x80, 0x01, 0x00, 0x98, 0x4c, 0x06, 0x06, 0xf0, 0x01,
+  0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x01, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x09, 0xc0, 0x1f, 0x80,
+  0x01, 0x00, 0x98, 0x4c, 0x06, 0x06, 0xf0, 0x01, 0x00, 0xe0, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3f, 0x08, 0xc0, 0xe6, 0x04, 0x0c, 0x08, 0x00, 0x00,
+  0xc0, 0x60, 0x7c, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x1f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
+  0x00, 0xc0, 0xe6, 0x04, 0x0c, 0x08, 0x00, 0x00, 0xc0, 0x60, 0x7c, 0x00,
+  0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xc0, 0x19, 0x60,
+  0x40, 0x00, 0x63, 0x30, 0x08, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xf3, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x09, 0xc0, 0x19, 0x60, 0x40, 0x00, 0x63, 0x30,
+  0x08, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xf3, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x78, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0f, 0xc0, 0x27, 0x03, 0x00, 0x30, 0x00, 0x03, 0x00, 0xe6, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0xcf, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xc0, 0x27, 0x03,
+  0x00, 0x30, 0x00, 0x03, 0x00, 0xe6, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x0f, 0xc0, 0xde, 0x04, 0x0c, 0x06, 0x03, 0x80,
+  0xc1, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0f, 0x03, 0x00, 0xf8, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x0f, 0xc0, 0x19, 0x00, 0x32, 0x00, 0x60, 0x30, 0x08, 0xff, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9f,
+  0x07, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x09, 0xc0, 0x19, 0x00,
+  0x32, 0x00, 0x60, 0x30, 0x08, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9f, 0x07, 0x00, 0x18, 0x40,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3f, 0x00, 0xc0, 0x27, 0x63, 0x80, 0x31, 0x04, 0x03,
+  0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+  0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0xfe, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x1f, 0x07, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
+  0x00, 0xc0, 0x27, 0x63, 0x80, 0x31, 0x04, 0x03, 0xf0, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0x7f, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+  0xe0, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x31,
+  0x04, 0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0xd9, 0x04,
+  0x00, 0x08, 0x00, 0x80, 0xf9, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf0, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x1e, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0xfe, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x04, 0x00, 0x60, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x09, 0x00, 0xd9, 0x04, 0x00, 0x08, 0x00, 0x80,
+  0xf9, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x7f, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x78, 0x00, 0xf0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0f, 0xc0, 0x27, 0x00, 0x30, 0xc0, 0x60, 0xb0, 0xff, 0x7f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x60, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0xde, 0x9b,
+  0x8d, 0x01, 0x04, 0xc3, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0xf1, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x03, 0x00, 0xf0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0xde, 0x9b, 0x8d, 0x01, 0x04, 0xc3,
+  0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf1, 0xff,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3e, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0x39, 0x04, 0x00, 0xc8, 0x00, 0xfc, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xf8, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0x39, 0x04,
+  0x00, 0xc8, 0x00, 0xfc, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc6, 0xf8, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0xc0, 0xc7, 0x60, 0x42, 0x00, 0x60, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+  0x00, 0xc0, 0xc7, 0x60, 0x42, 0x00, 0x60, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0xc0, 0xff, 0x07,
+  0xb0, 0x09, 0xe4, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x30, 0x00, 0xfc, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0xde, 0x78, 0x02, 0x00, 0xfb, 0xff,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f, 0xf0, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0xde, 0x78, 0x02, 0x00, 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x1f, 0xf8,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x08,
+  0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x3f, 0x07,
+  0xb0, 0xc9, 0xf8, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x3f, 0x07, 0xb0, 0xc9, 0xf8, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
+  0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x0f, 0x00, 0xe7, 0xfb, 0x43, 0x30, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0xe7, 0xfb,
+  0x43, 0x30, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0xe0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xfe, 0x1c, 0xb2, 0x0f, 0xe0, 0xff,
+  0x07, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0xf8, 0xe7, 0xfd, 0x01, 0xe0, 0xff, 0x07, 0x00, 0xe0, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xe0,
+  0xb1, 0x3f, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xf8,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xc0, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xf8, 0xe7,
+  0xfd, 0x01, 0xe0, 0xff, 0x07, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xe0, 0xb1, 0x3f, 0x00, 0x00,
+  0xf8, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x80, 0xff,
+  0x01, 0x00, 0xe0, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x98, 0x4f, 0x0e, 0x18, 0x00, 0xf8, 0xff, 0xff, 0xff,
+  0x07, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x80, 0xff, 0x01, 0x00, 0xe0, 0x03,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+  0x4f, 0x0e, 0xf8, 0x1f, 0xf6, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xf8, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb1, 0x01, 0xff, 0x1f,
+  0xf6, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xb1, 0x01, 0xff, 0x7f, 0xc0, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0xe0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
+  0x00, 0xce, 0xff, 0x7f, 0xc0, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0xe3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xe0, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0xce, 0xff, 0x7f,
+  0x00, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xc0, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x20, 0x1b, 0xb2, 0x31, 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0xe0, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x01, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0xc0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x1c,
+  0x00, 0xc0, 0xff, 0x73, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf0,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
+  0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xc0, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x1c, 0x00, 0xc0, 0x7f, 0x1c,
+  0x30, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x78, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x38, 0x87, 0x31, 0x06, 0x7c, 0x1c, 0x30, 0xff, 0xff, 0xff,
+  0xff, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x87,
+  0x31, 0x06, 0xfc, 0x0f, 0xc8, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x38,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+  0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe6, 0x04, 0x00, 0x30, 0xe3, 0x0f,
+  0xc8, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xe0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x30, 0xe6, 0x04, 0x00, 0x30, 0x03, 0x00, 0xf0, 0xff, 0xff, 0xff,
+  0xff, 0x03, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x07, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1b,
+  0x4c, 0x00, 0x04, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0xc0, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x07, 0x04, 0x00, 0x06, 0x18, 0x80,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0f, 0x0e, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x02, 0x07, 0x04, 0x00, 0x06, 0x78, 0xf3, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x08, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3e, 0x04,
+  0x02, 0x30, 0x60, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xf8,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0xc0, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3e, 0x04, 0x02, 0x30, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc6, 0x04, 0x40, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x04,
+  0x40, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x08,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x67, 0x00, 0x06, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x06, 0x04, 0x30, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04,
+  0x30, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x08,
+  0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x7e, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3e, 0x9b, 0x01, 0x30, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x30, 0x3e, 0x9b, 0x01, 0x30, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x1c, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x02, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x01, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x1c,
+  0x0c, 0x06, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x38,
+  0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xe0,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0xf0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x1c, 0x0c, 0x06, 0xfb, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x68, 0x7c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf8, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x38, 0x18, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x18, 0xfe, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0x03, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc6, 0x9b,
+  0x81, 0x01, 0x60, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x80,
+  0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xc0, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc6, 0x9b, 0x81, 0x01, 0x00, 0x00,
+  0xf6, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x38, 0x78, 0x0c, 0x30, 0x04, 0x00, 0xf6, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0xe8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x78,
+  0x0c, 0x30, 0x04, 0x00, 0xc8, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xf8,
+  0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x64, 0x40, 0x00, 0x1c, 0x00,
+  0xc8, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xf8, 0x58, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x64, 0x40, 0x00, 0xfc, 0x03, 0xc0, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x78, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe0,
+  0x01, 0x36, 0xfc, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x38,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe0, 0x01, 0x36, 0xfc, 0x1f,
+  0x30, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x8f, 0x01, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc6, 0x87, 0x0f, 0x00, 0xff, 0x1f, 0x30, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xcf, 0x03, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+  0x40, 0xc0, 0xff, 0x7f, 0xc0, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xcf, 0x03, 0x00, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xc0, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x40, 0xc0, 0xff, 0x7f,
+  0x00, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x8f, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x0e, 0xc6, 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x0e, 0xc6, 0xff, 0x7f, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0xf0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x9c, 0x01, 0x30, 0xff, 0x7f,
+  0x00, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x20, 0x9c, 0x01, 0x30, 0xff, 0x63, 0x30, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x07, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+  0x4c, 0x00, 0xff, 0x63, 0x30, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x31, 0xfc, 0x1f,
+  0x00, 0xff, 0xff, 0xfd, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xb2, 0x31, 0xfc, 0x0f, 0x00, 0xff, 0xff, 0x03,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+  0x41, 0x00, 0xe0, 0x0f, 0x00, 0xff, 0xff, 0x03, 0xff, 0x03, 0x00, 0x38,
+  0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x41, 0x00, 0x00, 0x80,
+  0xc9, 0xf9, 0xff, 0x3d, 0xff, 0x03, 0x00, 0x78, 0xc0, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x60, 0x32, 0x08, 0x00, 0x80, 0xc9, 0xf9, 0xff, 0x3d,
+  0xff, 0x03, 0x00, 0xf8, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x02, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+  0x32, 0x08, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xcf, 0xff, 0x00, 0x00, 0xf8,
+  0x81, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0xff,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe0, 0x01, 0xf8, 0x00, 0x00,
+  0xf0, 0xff, 0xff, 0xcf, 0xff, 0x00, 0x00, 0x38, 0x03, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x60, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x03, 0x80, 0xff, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0x38, 0x06, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0c, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xff, 0x03, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x38,
+  0x1e, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x03, 0xfc,
+  0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x38, 0xfc, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x1f, 0x00, 0x00, 0x38, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+  0x80, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x78,
+  0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe0, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xf8, 0xc1, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x60, 0xf8, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
+  0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xc0, 0xff,
+  0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x67,
+  0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x13, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc0, 0xff,
+  0xff, 0xff, 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x67, 0xfe, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xff, 0xff, 0x98, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
+  0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x0f, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x98,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xf8, 0xff,
+  0xff, 0xff, 0x7f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x3f, 0xe7, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xff, 0xfc, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0xff, 0x3f, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x00, 0xc0, 0xff, 0x67, 0x8c, 0xf9, 0xfb, 0x73, 0x00, 0x67, 0x10, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xf8,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xc0, 0xff, 0x67,
+  0x8c, 0xf9, 0xfb, 0x73, 0x00, 0x67, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0xe7, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0xc0, 0x27, 0xfc, 0x73, 0xc6, 0x1c, 0x8c,
+  0x37, 0x80, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff,
+  0xff, 0xff, 0x1f, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0xc0, 0x27, 0xfc, 0x73, 0xc6, 0x1c, 0x8c, 0x37, 0x80, 0x0c, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xfc,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0xc0, 0xfe, 0x03,
+  0x8c, 0x09, 0xe3, 0x73, 0xc8, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0xc0, 0xfe, 0x03, 0x8c, 0x09, 0xe3, 0x73,
+  0xc8, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0xc0, 0x27, 0xe7, 0x31, 0x36, 0x04, 0x8c, 0x01, 0x60, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0xc0, 0xde, 0x18,
+  0x42, 0xc0, 0x98, 0x30, 0x08, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0xc0, 0xde, 0x18, 0x42, 0xc0, 0x98, 0x30,
+  0x08, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0xc0, 0x27, 0x63, 0x00, 0x08, 0x63, 0x03, 0x06, 0x60, 0x10, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x27, 0x63,
+  0x00, 0x08, 0x63, 0x03, 0x06, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0xd9, 0x04, 0xb2, 0x01, 0x00, 0xb0,
+  0x31, 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf9, 0xff,
+  0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0xc0, 0xd9, 0x04, 0xb2, 0x01, 0x00, 0xb0, 0x31, 0x19, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0c, 0xc0, 0x1e, 0x63,
+  0x00, 0x30, 0x04, 0x03, 0xc8, 0x60, 0x00, 0x0e, 0x00, 0x00, 0xfc, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x0e, 0xc0, 0xe1, 0x18, 0x80, 0x01, 0x60, 0xb0,
+  0x01, 0xe7, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x0f, 0xc0, 0xe1, 0x18, 0x80, 0x01, 0x60, 0xb0, 0x01, 0xe7, 0xf3, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x0f, 0xc0, 0x1e, 0x03,
+  0x02, 0x08, 0x04, 0x00, 0xc8, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xd8, 0x0f, 0xc0, 0x1e, 0x03, 0x02, 0x08, 0x04, 0x00,
+  0xc8, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xc0, 0x0f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x0b, 0x00, 0x21, 0x64, 0x40, 0xc0, 0x00, 0xb3, 0xf1, 0xfe, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xfb, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x21, 0x64,
+  0x40, 0xc0, 0x00, 0xb3, 0xf1, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xfb, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0xfb, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfd, 0x00, 0xc0, 0xdf, 0x00, 0x00, 0x06, 0x60, 0x00,
+  0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xf9, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf,
+  0x01, 0xc0, 0xdf, 0x00, 0x00, 0x06, 0x60, 0x00, 0x0e, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xf0, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x0b, 0xc0, 0xc0, 0x84,
+  0x31, 0xc0, 0x00, 0x4c, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x83, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x1e, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0f, 0x0e, 0xc0, 0x3f, 0x18, 0x00, 0x06, 0x84, 0x80,
+  0x09, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xc3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x0c, 0xc0, 0x3f, 0x18, 0x00, 0x06, 0x84, 0x80, 0x09, 0xff, 0xff, 0x3f,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+  0xc1, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0xc0, 0xc1, 0x03,
+  0x4c, 0x00, 0x00, 0x30, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x90, 0x13, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x08, 0xc0, 0xc1, 0x03, 0x4c, 0x00, 0x00, 0x30,
+  0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0xc0, 0x3f, 0x98, 0x01, 0x08, 0x1b, 0x43, 0xc8, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x98,
+  0x01, 0x08, 0x1b, 0x43, 0xc8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0xc6, 0x03, 0x40, 0x00, 0x00, 0x80,
+  0x31, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xef, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+  0x00, 0x00, 0x3f, 0x18, 0x0c, 0x30, 0x60, 0x0c, 0xce, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xef, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x3f, 0x18,
+  0x0c, 0x30, 0x60, 0x0c, 0xce, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xc7, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xde, 0x63, 0x40, 0x06, 0x03, 0x30,
+  0x30, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x83, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e,
+  0x00, 0x00, 0xde, 0x63, 0x40, 0x06, 0x03, 0x30, 0x30, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x04,
+  0x02, 0x00, 0x00, 0x83, 0xc9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x38, 0x04, 0x02, 0x00, 0x00, 0x83,
+  0xc9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x03, 0x00, 0xe0, 0x1b, 0x0c, 0x08, 0x18, 0x40, 0x30, 0xfe, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0xc0, 0x84,
+  0x81, 0x01, 0x03, 0x0c, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0xc0, 0x84, 0x81, 0x01, 0x03, 0x0c,
+  0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x0e, 0x00, 0x00, 0x1b, 0x0c, 0x30, 0x80, 0x00, 0x30, 0xf8, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+  0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x1b,
+  0x0c, 0x30, 0x80, 0x00, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x67, 0xc0, 0x01, 0x04, 0x40,
+  0x00, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x08, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0x67, 0xc0, 0x01, 0x04, 0x40, 0x00, 0xe1, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+  0x30, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x9c,
+  0x01, 0x08, 0x60, 0x0c, 0x06, 0x86, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xbf, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x07, 0x0e, 0x00, 0x00, 0x18, 0x0c, 0xc0, 0x00, 0x00,
+  0xc0, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x9f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x07, 0x00, 0x00, 0x18, 0x0c, 0xc0, 0x00, 0x00, 0xc0, 0x00, 0xfc, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0xe0,
+  0x01, 0x06, 0x00, 0x30, 0x06, 0x86, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xe0, 0x01, 0x06, 0x00, 0x30,
+  0x06, 0x86, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x63, 0x03, 0x30, 0x00, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+  0x30, 0x00, 0x63, 0x03, 0x30, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x80, 0x83, 0x09, 0x18, 0x00,
+  0x00, 0x06, 0x83, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0x80, 0x83, 0x09, 0x18, 0x00, 0x00, 0x06, 0x83, 0xff,
+  0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0x00, 0x8c, 0xc9, 0x60, 0x00, 0xfe, 0xff, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x8e, 0x01, 0x84, 0x40,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x8e, 0x01, 0x84, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x60, 0x83, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+  0x00, 0xc8, 0x60, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x0c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0f, 0x00, 0x00, 0x00, 0x80, 0xc1, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x80, 0xc1, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x60, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf8, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xc6,
+  0x03, 0x00, 0x00, 0x00, 0x40, 0x08, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xef, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xd8, 0xef, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x1c, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xf3,
+  0x0f, 0x00, 0x00, 0x00, 0x80, 0x09, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x33, 0x0c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x88, 0x13, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x13,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x33, 0x0c, 0x00, 0x00, 0x00,
+  0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x88, 0xf3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xe3,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xe1, 0x1f, 0x00, 0x00, 0x00,
+  0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xf0, 0xc1, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00,
+  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc0, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x06, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/bootstd.h linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/bootstd.h
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/bootstd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/bootstd.h	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,132 @@
+/* bootstd.h:  Bootloader system call interface
+ *
+ * (c) 1999, Rt-Control, Inc.
+ */
+
+#ifndef __BOOTSTD_H__
+#define __BOOTSTD_H__
+
+#define NR_BSC 21            /* last used bootloader system call */
+
+#define __BN_reset        0  /* reset and start the bootloader */
+#define __BN_test         1  /* tests the system call interface */
+#define __BN_exec         2  /* executes a bootloader image */
+#define __BN_exit         3  /* terminates a bootloader image */
+#define __BN_program      4  /* program FLASH from a chain */
+#define __BN_erase        5  /* erase sector(s) of FLASH */
+#define __BN_open         6
+#define __BN_write        7
+#define __BN_read         8
+#define __BN_close        9
+#define __BN_mmap         10 /* map a file descriptor into memory */
+#define __BN_munmap       11 /* remove a file to memory mapping */
+#define __BN_gethwaddr    12 /* get the hardware address of my interfaces */
+#define __BN_getserialnum 13 /* get the serial number of this board */
+#define __BN_getbenv      14 /* get a bootloader envvar */
+#define __BN_setbenv      15 /* get a bootloader envvar */
+#define __BN_setpmask     16 /* set the protection mask */
+#define __BN_readenv      17 /* read environment variables */
+#define __BN_flash_chattr_range		18
+#define __BN_flash_erase_range		19
+#define __BN_flash_write_range		20
+
+/* Calling conventions compatible to (uC)linux/68k
+ * We use simmilar macros to call into the bootloader as for uClinux
+ */
+
+#define __bsc_return(type, res) \
+do { \
+   if ((unsigned long)(res) >= (unsigned long)(-64)) { \
+      /* let errno be a function, preserve res in %d0 */ \
+      int __err = -(res); \
+      errno = __err; \
+      res = -1; \
+   } \
+   return (type)(res); \
+} while (0)
+
+#define _bsc0(type,name) \
+type name(void) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc1(type,name,atype,a) \
+type name(atype a) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc2(type,name,atype,a,btype,b) \
+type name(atype a, btype b) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc3(type,name,atype,a,btype,b,ctype,c) \
+type name(atype a, btype b, ctype c) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
+type name(atype a, btype b, ctype c, dtype d) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   register long __d __asm__ ("%d4") = (long)d; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c), "d" (__d) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
+type name(atype a, btype b, ctype c, dtype d, etype e) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   register long __d __asm__ ("%d4") = (long)d; \
+   register long __e __asm__ ("%d5") = (long)e; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c), "d" (__d), "d" (__e) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#endif /* __BOOTSTD_H__ */
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/crt0_fixed.S linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/crt0_fixed.S
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/crt0_fixed.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/crt0_fixed.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,115 @@
+#include <linux/config.h>
+	
+	.global _start
+	.global _stext
+
+	.global _rambase
+	.global _ramvec
+	.global _ramstart
+	.global _ramend
+
+#ifdef CONFIG_INIT_LCD
+	.global splash_bits
+#endif
+
+	.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+#ifdef CONFIG_INIT_LCD
+splash_bits:
+#include "bootlogo.rh"
+#endif
+	
+	.text
+_start:
+_stext:	movew	#0x2700,%sr
+#ifdef CONFIG_INIT_LCD
+	movel	#splash_bits, 0xfffffA00 /* LSSA */
+	moveb	#0x28,   0xfffffA05	/* LVPW */
+	movew	#0x280,  0xFFFFFa08	/* LXMAX */
+	movew	#0x1df,  0xFFFFFa0a	/* LYMAX */
+	moveb	#0,      0xfffffa29	/* LBAR */
+	moveb	#0,      0xfffffa25	/* LPXCD */
+	moveb	#0x08,   0xFFFFFa20	/* LPICF */
+	moveb	#0x01,   0xFFFFFA21	/* -ve pol */
+	moveb	#0x81,   0xfffffA27	/* LCKCON */
+	movew	#0xff00, 0xfffff412	/* LCD pins */
+#endif
+
+#ifdef CONFIG_DIRECT_IO_ACCESS
+	moveb	#0x0,	0xfffff000
+#endif
+
+	moveal  #__ramend-CONFIG_MEMORY_RESERVE*0x100000 - 0x10, %sp
+	movew	#32767, %d0  /* PLL settle wait loop */
+1:	subq	#1, %d0
+	bne	1b
+
+	/* Copy data segment from ROM to RAM */
+	moveal	#__data_rom_start, %a0
+	moveal	#_sdata, %a1
+	moveal	#_edata, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+1:	movel	%a0@+, %a1@+
+	cmpal	%a1, %a2
+	bhi	1b
+
+	moveal	#_sbss, %a0
+	moveal	#_ebss, %a1
+	/* Copy 0 to %a0 until %a0 == %a1 */
+	
+1:
+	clrl	%a0@+
+	cmpal	%a0, %a1
+	bhi	1b
+
+        movel   #_sdata, %d0    
+        movel   %d0,    _rambase        
+        movel   #_ebss,  %d0
+        movel   %d0,    _ramstart
+	movel	#__ramend-CONFIG_MEMORY_RESERVE*0x100000, %d0
+	movel	%d0,	_ramend
+	movel	#__ramvec,	%d0
+	movel	%d0,	_ramvec
+	
+/*
+ * load the current task pointer and stack
+ */
+        lea     init_task_union,%a0
+        movel   %a0, _current_task
+        lea     0x2000(%a0),%sp
+
+1:	jsr	start_kernel
+        bra 1b
+_exit:
+
+	jmp	_exit
+
+
+putc:
+	moveb	%d7,0xfffff907
+1:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	1b
+	rts
+
+	.data
+env:
+	.long	0
+	.text
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/crt0_himem.S linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/crt0_himem.S
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/crt0_himem.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/crt0_himem.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/crt0_ram.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,194 @@
+
+#define CONFIG_RELOCATE
+#define DEBUG
+
+#include <linux/config.h>
+	
+	.global _start
+	.global _stext
+
+	.global _rambase
+	.global _ramvec
+	.global _ramstart
+	.global _ramend
+
+#ifdef CONFIG_INIT_LCD
+	.global splash_bits
+#endif
+
+	.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+#ifdef CONFIG_INIT_LCD
+splash_bits:
+#include "bootlogo.rh"
+#endif
+	
+	.text
+_start:
+_stext:	movew	#0x2700,%sr
+
+#ifdef DEBUG
+/* 'K' */
+        moveq   #'K', %d7
+        moveb   %d7,0xfffff907          /* No absolute addresses */
+0:
+        movew   0xfffff906, %d7
+        andw    #0x2000, %d7
+        beq     0b
+#endif	
+
+#ifdef CONFIG_RELOCATE
+	/* Copy me to RAM */
+	moveal	#__rom_start, %a0
+	moveal	#__ram_start, %a1
+	moveal	#__data_end, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:
+	movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bhi	LD1
+	
+#ifdef DEBUG
+	moveq	#74, %d7		/* 'J' */
+	moveb	%d7,0xfffff907          /* No absolute addresses */
+pclp2:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	pclp2
+#endif /* DEBUG */
+	/* jump into the RAM copy */
+	jmp     ram_jump
+ram_jump:
+
+#endif /* CONFIG_RELOCATE */
+
+
+#ifdef CONFIG_INIT_LCD
+	movel	#splash_bits, 0xfffffA00 /* LSSA */
+	moveb	#0x1e,   0xfffffA05	/* LVPW */
+	movew	#0x1e0,  0xFFFFFa08	/* LXMAX */
+	movew	#0xf0,  0xFFFFFa0a	/* LYMAX */
+	moveb	#0,      0xfffffa29	/* LBAR */
+	moveb	#0,      0xfffffa25	/* LPXCD */
+	moveb	#0x08,   0xFFFFFa20	/* LPICF */
+	moveb	#0x00,   0xFFFFFA21	/* -ve pol */
+	moveb	#0x81,   0xfffffA27	/* LCKCON */
+	movew	#0xff00, 0xfffff412	/* LCD pins */
+#endif
+	moveal  #__ramend-CONFIG_MEMORY_RESERVE*0x100000 - 0x10, %sp
+	movew	#32767, %d0  /* PLL settle wait loop */
+1:	subq	#1, %d0
+	bne	1b
+
+#ifdef DEBUG
+/* 'L' */
+        moveq   #'L', %d7
+        moveb   %d7,0xfffff907          /* No absolute addresses */
+0:
+        movew   0xfffff906, %d7
+        andw    #0x2000, %d7
+        beq     0b
+#endif
+
+
+/* Clear BSS  */
+
+	moveal	#_sbss, %a0
+	moveal	#_ebss, %a1
+	
+1:
+	clrl	%a0@+
+	cmpal	%a0, %a1
+	bhi	1b
+
+#ifdef DEBUG
+/* 'D' */
+        moveq   #'D', %d7
+        moveb   %d7,0xfffff907          /* No absolute addresses */
+0:
+        movew   0xfffff906, %d7
+        andw    #0x2000, %d7
+        beq     0b
+#endif
+
+        movel   #_sdata, %d0    
+        movel   %d0,    _rambase        
+        movel   #_ebss,  %d0
+        movel   %d0,    _ramstart
+	movel	#__ramend-CONFIG_MEMORY_RESERVE*0x100000, %d0
+	movel	%d0,	_ramend
+	movel	#__ramvec,	%d0
+	movel	%d0,	_ramvec
+
+#ifdef DEBUG
+/* 'S' */
+        moveq   #'M', %d7
+        moveb   %d7,0xfffff907 
+0:
+        movew   0xfffff906, %d7 
+        andw    #0x2000, %d7
+        beq     0b
+#endif  
+	
+/*
+ * load the current task pointer and stack
+ */
+        lea     init_task_union,%a0
+        movel   %a0, _current_task
+        lea     0x2000(%a0),%sp
+
+#ifdef DEBUG
+/* 'S' */
+        moveq   #'S', %d7
+        moveb   %d7,0xfffff907          /* No absolute addresses */
+0:
+        movew   0xfffff906, %d7
+        andw    #0x2000, %d7
+        beq     0b
+#endif
+
+1:	jsr	start_kernel
+#ifdef DEBUG
+/* '!' */
+        moveq   #'!', %d7
+        moveb   %d7,0xfffff907          /* No absolute addresses */
+0:
+        movew   0xfffff906, %d7
+        andw    #0x2000, %d7
+        beq     0b
+#endif
+        bra 1b
+_exit:
+
+	jmp	_exit
+
+
+putc:
+	moveb	%d7,0xfffff907
+1:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	1b
+	rts
+
+	.data
+env:
+	.long	0
+	.text
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/crt0_rom.S linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/crt0_rom.S
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/crt0_rom.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/crt0_rom.S	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,95 @@
+SECTIONS
+{
+  .romvec :
+	{
+	_flashstart = . ;
+	_romvec = . ;
+	__rom_start = . ;
+	} > romvec
+
+  .text :
+	{
+	_stext = . ;
+        	*(.text)
+	. = ALIGN(0x4) ;
+		*(.text.*)
+	. = ALIGN(0x4) ;
+		*(.exitcall.exit)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	. = ALIGN(0x4) ;
+	_etext = . ;
+	__data_rom_start = . ;
+        } > flash
+
+  .eflash :
+	{
+	_flashend = . ;
+	} > eflash
+
+  .ramvec :
+	{
+	__ram_start = . ;
+	__ramvec = . ;
+	} > ramvec
+
+  .data :
+	{
+	. = ALIGN(0x4) ;
+	_sdata = . ;
+	__data_start = . ;
+
+	. = ALIGN(0x4) ;
+		*(.rodata)
+	. = ALIGN(0x4) ;
+		*(.rodata.str1.1)
+	. = ALIGN(0x4) ;
+		*(.data)
+	. = ALIGN(0x4) ;
+		*(.data.*)	
+
+	. = ALIGN(0x4) ;
+	__setup_start = .;
+		*(.setup.init)
+	. = ALIGN(0x4) ;
+	__setup_end = .;
+
+	. = ALIGN(0x4) ;
+	__initcall_start = .;
+		*(.initcall.init)
+	. = ALIGN(0x4) ;
+	__initcall_end = .;
+
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	. = ALIGN(0x2000) ;
+
+	_edata = . ;
+        } > ram
+
+  .bss :
+        {
+	. = ALIGN(0x4) ;
+	_sbss = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	_ebss = . ;
+	_end = . ;
+	} > ram
+
+  .eram :
+	{
+	__ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/himem.ld linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/himem.ld
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/himem.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/himem.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,11 @@
+MEMORY 
+	{
+        romvec : ORIGIN = 0x00600000, LENGTH = 0x00000400
+        flash  : ORIGIN = 0x00600400, LENGTH = 0x00200000 - 0x00010400
+        eflash : ORIGIN = 0x007f0000, LENGTH = 0
+        ramvec : ORIGIN = 0x00000000, LENGTH = 0x00000400
+        ram    : ORIGIN = 0x00020000, LENGTH = 0x00600000 - 0x00020000
+        eram   : ORIGIN = 0x00600000, LENGTH = 0
+	}
+
+INCLUDE arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/ram.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,102 @@
+MEMORY 
+	{
+	romvec : ORIGIN = 0x10c10000, LENGTH = 0x00000400
+	flash  : ORIGIN = 0x10c10400, LENGTH = 0x00200000 - 0x00010400
+	eflash : ORIGIN = 0x10e00000, LENGTH = 0
+	ramvec : ORIGIN = 0x00000000, LENGTH = 0x00000400
+	bvec   : ORIGIN = 0x00020000, LENGTH = 0x00000400
+	ram    : ORIGIN = 0x00020400, LENGTH = 0x00800000 - 0x00020400
+	eram   : ORIGIN = 0x00800000, LENGTH = 0
+	}
+
+SECTIONS
+{
+	.fakevec :
+	{
+	} > romvec
+	.rom :
+	{
+	__rom_start = . ;
+	} > flash
+	.eflash :
+	{
+	_flashend = . ;
+	} > eflash
+	.realvec :
+	{
+	__ramvec = . ;
+	} > ramvec
+	.romvec :
+	{
+	_romvec = . ;
+	} > bvec
+        .text :
+	{
+	__ram_start = . ;
+	_stext = . ;
+	text_start = . ;
+        	*(.text)
+		*(.text.*)
+		*(.rodata)
+		*(.rodata.str1.1)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	_etext = . ;
+	__data_rom_start = ALIGN ( 4 ) ;
+        } > ram
+        .data :
+	{
+	_sdata = . ;
+	__data_start = . ;
+
+        . = ALIGN(0x2000) ;
+        *(.data.init_task)
+        . = ALIGN(0x2000) ;
+
+        *(.data)
+        *(.data.*)      
+        *(.exitcall.exit)               
+
+        . = ALIGN(4096) ;
+        __init_begin = .;
+        *(.text.init)
+        *(.data.init)
+        . = ALIGN(16);
+        __setup_start = .;
+        *(.setup.init)
+        __setup_end = .;
+        __initcall_start = .;
+        *(.initcall.init)
+        . = ALIGN(4) ;
+        __initcall_end = .;
+        __init_end = .;
+
+	_edata = . ;
+	edata = ALIGN( 0x10 ) ;
+        } > ram
+        .bss :
+        {
+	_sbss = ALIGN( 0x10 ) ;
+	__bss_start = ALIGN( 0x10 ) ;
+	__data_end = ALIGN( 0x10 ) ;
+	*(.bss)
+	*(COMMON)
+	_ebss = . ;
+	__bss_end = . ;
+	end = ALIGN( 0x10 ) ;
+	_end = ALIGN( 0x10 ) ;
+	} > ram
+	.eram :
+	{
+	__ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/rom.ld linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/rom.ld
--- linux-2.4.29/arch/m68knommu/platform/68EZ328/ucsimm/rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68EZ328/ucsimm/rom.ld	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,11 @@
+MEMORY 
+	{
+        romvec : ORIGIN = 0x10c10000, LENGTH = 0x00000400
+        flash  : ORIGIN = 0x10c10400, LENGTH = 0x001fec00
+        eflash : ORIGIN = 0x10d00000, LENGTH = 0
+        ramvec : ORIGIN = 0x00000000, LENGTH = 1024
+        ram    : ORIGIN = 0x00020000, LENGTH = 0x00800000 - 0x00020000
+        eram   : ORIGIN = 0x00800000, LENGTH = 0
+	}
+
+INCLUDE arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/clie/config.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/clie/config.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/clie/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/clie/config.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,128 @@
+/*
+ *  linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999 D. Jeff Dionne
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+
+
+#include <asm/MC68VZ328.h>
+
+void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
+{
+#ifdef CONFIG_DRAGONBALL_USE_RTC
+  /* Enable RTC */
+  RTCCTL|=RTCCTL_EN;
+  /* Enable 128Hz interrupt line */
+  RTCIENR|=RTCIENR_SAM5;
+  request_irq(SAM_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+#else
+  /* Restart mode, Enable int, 32KHz, Enable timer */
+  TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
+  /* Set prescaler (Divide 32.768KHz by 1)*/
+  TPRER = 0;
+  /* Set compare register  32.768Khz / 32 / 10 = 100 */
+  TCMP = 327;
+  request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+#endif
+}
+
+void BSP_tick(void)
+{
+#ifdef CONFIG_DRAGONBALL_USERTC
+        RTCISR|=RTCISR_SAM5;
+#else
+	/* Reset Timer1 */
+        TSTAT &= 0;
+#endif
+
+}
+
+unsigned long BSP_gettimeoffset (void)
+{
+  return 0;
+}
+
+void BSP_gettod (int *yearp, int *monp, int *dayp,
+		   int *hourp, int *minp, int *secp)
+{
+ //rtcgettod(yearp, monp, dayp, hourp, minp, secp);
+ *yearp = *monp = *dayp = *hourp = *minp = *secp = 0;
+}
+
+int BSP_hwclk(int op, struct hwclk_time *t)
+{
+  if (!op) {
+    /* read */
+  } else {
+    /* write */
+  }
+  return 0;
+}
+
+int BSP_set_clock_mmss (unsigned long nowtime)
+{
+#if 0
+  short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+
+  tod->second1 = real_seconds / 10;
+  tod->second2 = real_seconds % 10;
+  tod->minute1 = real_minutes / 10;
+  tod->minute2 = real_minutes % 10;
+#endif
+  return 0;
+}
+
+void BSP_reset (void)
+{
+  cli();
+  asm volatile ("
+    moveal #0x02000000, %a0;
+    moveb #0, 0xFFFFF300;
+    moveal 0(%a0), %sp;
+    moveal 4(%a0), %a0;
+    jmp (%a0);
+    ");
+}
+
+unsigned char cs8900a_hwaddr1[6],cs8900a_hwaddr2[6];
+static int errno;
+
+void config_BSP(char *command, int len)
+{
+  int year, mon, day, hour, min, sec;
+
+  printk("68VZ328 DragonBallVZ support (c) 2001 Lineo, Inc.\n");
+
+  strncpy(command, "console=ttyS0", len);
+
+  mach_sched_init      = BSP_sched_init;
+  mach_tick            = BSP_tick;
+  mach_gettimeoffset   = BSP_gettimeoffset;
+  mach_gettod          = BSP_gettod;
+  mach_hwclk           = NULL;
+  mach_set_clock_mmss  = NULL;
+  // mach_mksound         = NULL;
+  mach_reset           = BSP_reset;
+  // mach_debug_init      = NULL;
+
+  config_M68VZ328_irq();
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/clie/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/clie/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/clie/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/clie/crt0_ram.S	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,154 @@
+#define IMM #
+#define DEBUG(x) \
+	moveb	IMM x, %d7; \
+	moveb	%d7,0xfffff907; \
+    1:  movew	0xfffff906, %d7; \
+	andw	IMM 0x2000, %d7; \
+	beq	1b
+
+
+
+	.global _start
+	.global _stext
+	.global _ramstart
+	.global _ramend
+	.global _rambase
+	.global _ramvec
+
+
+
+	.data
+_ramstart:
+.long   0
+_ramend:
+.long   0
+_rambase:
+.long	0
+_ramvec:
+.long	0
+
+
+
+	.text
+_start:
+_stext:
+
+
+
+	movew	#0x2700, %sr
+        moveb	#0x00,   0xfffffb0b	/* Watchdog off */
+        moveb	#0x00,   0xfffff000	/* SCR */
+        movew	#0x2483, 0xfffff200	/* PLLCR */
+        movew	#0x0347, 0xfffff202	/* PLLFSR */
+	movew	#32767, %d0		/* PLL settle wait loop */
+plllp:	subq	#1, %d0
+	bne	plllp
+
+
+
+	/* UART1 setup */
+	orib	#4,      0xfffff431	/* Magic taken from PalmOS ROM. I'm gonna think this pin is in GPIO mode, even though I can't prove that */
+	moveb	#0xcf,   0xfffff423	/* Dedicated IO */
+	moveb	#0x08,   0xfffff906	/* Transmitter settings */
+	movew	#0x0080, 0xfffff908	/* Misc settings */
+	movew	#0x326,  0xfffff902	/* Baud rate */
+	movew	#0xe100, 0xfffff900	/* Enable */
+
+
+
+	/* Make sure console works */
+	DEBUG('A');
+
+
+
+        /* My parts are scattered, %a0 has a list.  Make me whole */
+	DEBUG('B');
+	moveal	#0x5000, %a2		/* FIXME: Hard coded load address */
+	moveal	%a0@+, %a1		/* Move to page 1 (this is page 0) */
+mvlp0:
+	movew	#1024, %d6
+	moveal	%a0@+, %a1
+	movel	%a1, %d0
+	beq	mvdone
+mvlp1:
+	movel	%a1@+, %d0
+	movel	%d0, %a2@+
+	subw	#1, %d6
+        bne	mvlp1
+        bra	mvlp0
+mvdone:
+
+
+
+	/* Stack */
+	moveal	#__ramend - 0x10, %sp
+
+
+
+	/* Move romfs beyond BSS */
+	DEBUG('C')
+	moveal	#_sbss, %a0
+	moveal	#_ebss, %a1
+	movel	%a0, %a2
+
+	movel	%a0@(8), %d0		/* romfs size */
+	addl	#8, %d0			/* plus header */
+        andl	#0xfffffffc, %d0	/* Whole words */
+	addl	%d0, %a0
+	addl	%d0, %a1
+	movel	%a1, _ramstart		/* set to the END of romfs, not _ebss! */
+
+romlp:  movel	%a0@-, %d0		/* Copy dword */
+        movel	%d0, %a1@-
+        cmpl	%a0, %a2		/* Check if at end */
+        bne	romlp
+
+
+
+	/* Clear bss  */
+	DEBUG('D');
+        moveal	#_sbss, %a0
+        moveal	#_ebss, %a1
+        /* Copy 0 to %a0 until %a0 == %a1 */
+bsslp:	clrl    %a0@+
+        cmpal   %a0, %a1
+        bne     bsslp
+
+
+
+	/* Fill vars */
+	DEBUG('E')
+	movel   #_sdata, %d0
+	movel   %d0, _rambase
+	movel   #__ramend, %d0
+	movel   %d0, _ramend
+        movel   #__ramvec, %d0
+	movel   %d0, _ramvec
+
+
+
+	/* Load the current task pointer and stack */
+	DEBUG('F')
+        lea	init_task_union, %a0
+        movel	%a0, _current_task
+        lea	0x2000(%a0), %sp
+
+ 
+
+	/* Start kernel */
+        DEBUG('G')
+        DEBUG('\n')
+        DEBUG('\r')
+stlp:   jsr	start_kernel
+        DEBUG('!')
+        bra stlp
+ 
+
+
+_exit:
+	jmp	_exit
+
+	.data
+env:
+	.long   0
+	.text
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/clie/ints.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/clie/ints.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/clie/ints.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/clie/ints.c	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,361 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne <jeff@uClinux.org>
+
+ * Phil Wilshire Sept 2002 added dummy init_irq_proc call for SYSCTL
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+
+#include <asm/MC68VZ328.h>
+
+#define INTERNAL_IRQS (32)
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void exception3(void);
+asmlinkage void exception4(void);
+asmlinkage void exception5(void);
+asmlinkage void exception6(void);
+asmlinkage void exception7(void);
+asmlinkage void exception8(void);
+asmlinkage void exception9(void);
+asmlinkage void exception10(void);
+asmlinkage void exception11(void);
+asmlinkage void exception14(void);
+asmlinkage void exception15(void);
+asmlinkage void bad_interrupt(void);
+asmlinkage void inthandler1(void);
+asmlinkage void inthandler2(void);
+asmlinkage void inthandler3(void);
+asmlinkage void inthandler4(void);
+asmlinkage void inthandler5(void);
+asmlinkage void inthandler6(void);
+asmlinkage void inthandler7(void);
+asmlinkage void system_call(void);
+asmlinkage void trap1(void);
+asmlinkage void trap15(void);
+
+// extern void *_ramvec[];
+extern e_vector *_ramvec;
+
+/* irq node variables for the 32 (potential) on chip sources */
+static irq_node_t *int_irq_list[INTERNAL_IRQS];
+
+static int int_irq_count[INTERNAL_IRQS];
+static short int_irq_ablecount[INTERNAL_IRQS];
+
+static void int_badint(int irq, void *dev_id, struct pt_regs *fp)
+{
+	num_spurious += 1;
+}
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the amiga IRQ handling routines.
+ */
+
+void M68VZ328_init_IRQ(void)
+{
+	int i;
+
+        /* set up the vectors */
+        for (i=2; i < 32; ++i)
+                _ramvec[i] = bad_interrupt;
+
+        _ramvec[2] = buserr;
+        _ramvec[3] = exception3;
+        _ramvec[4] = exception4;
+        _ramvec[5] = exception5;
+        _ramvec[6] = exception6;
+        _ramvec[7] = exception7;
+        _ramvec[8] = exception8;
+        _ramvec[9] = exception9;
+        _ramvec[10] = exception10;
+        _ramvec[11] = exception11;
+        _ramvec[14] = exception14;
+        _ramvec[15] = exception15;
+        _ramvec[32] = system_call;
+        _ramvec[33] = trap1;
+        _ramvec[47] = trap15;
+
+        _ramvec[64] = bad_interrupt;
+        _ramvec[65] = inthandler1;
+        _ramvec[66] = inthandler2;
+        _ramvec[67] = inthandler3;
+        _ramvec[68] = inthandler4;
+        _ramvec[69] = inthandler5;
+        _ramvec[70] = inthandler6;
+        _ramvec[71] = inthandler7;
+ 
+	IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
+
+	/* initialize handlers */
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		int_irq_list[i] = NULL;
+
+		int_irq_ablecount[i] = 0;
+		int_irq_count[i] = 0;
+	}
+	/* turn off all interrupts */
+	IMR = ~0;
+}
+
+void M68VZ328_insert_irq(irq_node_t **list, irq_node_t *node)
+{
+	unsigned long flags;
+	irq_node_t *cur;
+
+	if (!node->dev_id)
+		printk("%s: Warning: dev_id of %s is zero\n",
+		       __FUNCTION__, node->devname);
+
+	save_flags(flags);
+	cli();
+
+	cur = *list;
+
+	while (cur) {
+		list = &cur->next;
+		cur = cur->next;
+	}
+
+	node->next = cur;
+	*list = node;
+
+	restore_flags(flags);
+}
+
+void M68VZ328_delete_irq(irq_node_t **list, void *dev_id)
+{
+	unsigned long flags;
+	irq_node_t *node;
+
+	save_flags(flags);
+	cli();
+
+	for (node = *list; node; list = &node->next, node = *list) {
+		if (node->dev_id == dev_id) {
+			*list = node->next;
+			/* Mark it as free. */
+			node->handler = NULL;
+			restore_flags(flags);
+			return;
+		}
+	}
+	restore_flags(flags);
+	printk ("%s: tried to remove invalid irq\n", __FUNCTION__);
+}
+
+int M68VZ328_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                         unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+	if (!int_irq_list[irq]) {
+		int_irq_list[irq] = new_irq_node();
+		int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	}
+
+	if (!(int_irq_list[irq]->flags & IRQ_FLG_STD)) {
+		if (int_irq_list[irq]->flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+	}
+	int_irq_list[irq]->handler = handler;
+	int_irq_list[irq]->flags   = flags;
+	int_irq_list[irq]->dev_id  = dev_id;
+	int_irq_list[irq]->devname = devname;
+
+	/* enable in the IMR */
+	if (!int_irq_ablecount[irq])
+		*(volatile unsigned long *)0xfffff304 &= ~(1<<irq);
+
+	return 0;
+}
+
+void M68VZ328_free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_list[irq]->dev_id != dev_id)
+		printk("%s: removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, int_irq_list[irq]->devname);
+	int_irq_list[irq]->handler = int_badint;
+	int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	int_irq_list[irq]->dev_id  = NULL;
+	int_irq_list[irq]->devname = NULL;
+
+	*(volatile unsigned long *)0xfffff304 |= 1<<irq;
+}
+
+/*
+ * Enable/disable a particular machine specific interrupt source.
+ * Note that this may affect other interrupts in case of a shared interrupt.
+ * This function should only be called for a _very_ short time to change some
+ * internal data, that may not be changed by the interrupt at the same time.
+ * int_(enable|disable)_irq calls may also be nested.
+ */
+
+void M68VZ328_enable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (--int_irq_ablecount[irq])
+		return;
+
+	/* enable the interrupt */
+	*(volatile unsigned long *)0xfffff304 &= ~(1<<irq);
+}
+
+void M68VZ328_disable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_ablecount[irq]++)
+		return;
+
+	/* disable the interrupt */
+	*(volatile unsigned long *)0xfffff304 |= 1<<irq;
+}
+
+/* The 68k family did not have a good way to determine the source
+ * of interrupts until later in the family.  The EC000 core does
+ * not provide the vector number on the stack, we vector everything
+ * into one vector and look in the blasted mask register...
+ * This code is designed to be fast, almost constant time, not clean!
+ */
+inline int M68VZ328_do_irq(int vec, struct pt_regs *fp)
+{
+	int irq;
+	int mask;
+
+	unsigned long pend = *(volatile unsigned long *)0xfffff30c;
+
+	while (pend) {
+		if (pend & 0x0000ffff) {
+			if (pend & 0x000000ff) {
+				if (pend & 0x0000000f) {
+					mask = 0x00000001;
+					irq = 0;
+				} else {
+					mask = 0x00000010;
+					irq = 4;
+				}
+			} else {
+				if (pend & 0x00000f00) {
+					mask = 0x00000100;
+					irq = 8;
+				} else {
+					mask = 0x00001000;
+					irq = 12;
+				}
+			}
+		} else {
+			if (pend & 0x00ff0000) {
+				if (pend & 0x000f0000) {
+					mask = 0x00010000;
+					irq = 16;
+				} else {
+					mask = 0x00100000;
+					irq = 20;
+				}
+			} else {
+				if (pend & 0x0f000000) {
+					mask = 0x01000000;
+					irq = 24;
+				} else {
+					mask = 0x10000000;
+					irq = 28;
+				}
+			}
+		}
+
+		while (! (mask & pend)) {
+			mask <<=1;
+			irq++;
+		}
+
+		if (int_irq_list[irq] && int_irq_list[irq]->handler) {
+			int_irq_list[irq]->handler(irq, int_irq_list[irq]->dev_id, fp);
+			int_irq_count[irq]++;
+		} else {
+			printk("unregistered interrupt %d!\nTurning it off in the IMR...\n", irq);
+			*(volatile unsigned long *)0xfffff304 |= mask;
+		}
+		pend &= ~mask;
+	}
+	return 0;
+}
+
+int M68VZ328_get_irq_list(char *buf)
+{
+	int i, len = 0;
+	irq_node_t *node;
+
+	len += sprintf(buf+len, "Internal 68VZ328 interrupts\n");
+
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		if (!(node = int_irq_list[i]))
+			continue;
+		if (!(node->handler))
+			continue;
+
+		len += sprintf(buf+len, " %2d: %10u    %s\n", i,
+		               int_irq_count[i], int_irq_list[i]->devname);
+	}
+	return len;
+}
+
+void config_M68VZ328_irq(void)
+{
+	mach_default_handler = NULL;
+	mach_init_IRQ        = M68VZ328_init_IRQ;
+	mach_request_irq     = M68VZ328_request_irq;
+	mach_free_irq        = M68VZ328_free_irq;
+	mach_enable_irq      = M68VZ328_enable_irq;
+	mach_disable_irq     = M68VZ328_disable_irq;
+	mach_get_irq_list    = M68VZ328_get_irq_list;
+	mach_process_int     = M68VZ328_do_irq;
+}
+
+/* PSW dummy call to allow SYSCTL kernel option to be enabled */
+void init_irq_proc(void)
+{
+        /* Insert /proc/irq driver here */
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/clie/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/clie/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/clie/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/clie/ram.ld	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,94 @@
+MEMORY
+{
+        ramvec : ORIGIN = 0x0000000, LENGTH = 0x0000400
+	bvec   : ORIGIN = 0x0004000, LENGTH = 0x0000400
+        ram    : ORIGIN = 0x0004400, LENGTH = 0x1000000 - 0x0004400
+        eram   : ORIGIN = 0x01000000, LENGTH = 0
+}
+
+SECTIONS
+{
+  .romvec :
+	{
+	_romvec = . ;
+	} > bvec
+
+  .ramvec :
+	{
+	__ram_start = . ;
+	__ramvec = . ;
+	} > ramvec
+  
+  .text :
+	{
+	_stext = . ;
+        	*(.text)
+	. = ALIGN(0x4) ;
+		*(.text.*)
+	. = ALIGN(0x4) ;
+		*(.exitcall.exit)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);		/* Exception table */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+	__start___ksymtab = .; /* Kernel symbol table */
+		*(__ksymtab)
+	__stop___ksymtab = .;
+
+	. = ALIGN(0x4);
+	_etext = . ;
+	__data_rom_start = . ;
+        } > ram
+
+  .data : 
+	{
+	. = ALIGN(0x4) ;
+	_sdata = . ;
+	__data_start = . ;
+
+	. = ALIGN(0x4) ;
+		*(.rodata)
+	. = ALIGN(0x4) ;
+		*(.data)
+	. = ALIGN(0x4) ;
+		*(.data.*)
+
+	. = ALIGN(0x4) ;
+	__setup_start = .;
+		*(.setup.init)
+	. = ALIGN(0x4) ;
+	__setup_end = .;
+
+	. = ALIGN(0x4) ;
+	__initcall_start = .;
+		*(.initcall.init)
+	. = ALIGN(0x4) ;
+	__initcall_end = .;
+
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	. = ALIGN(0x2000) ;
+
+	_edata = . ;
+        } > ram
+
+  .bss :
+        {
+	. = ALIGN(0x4) ;
+	_sbss = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	_ebss = . ;
+	_end = . ;
+	} > ram
+
+  .eram :
+	{
+        __ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/bootlogo.h linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/bootlogo.h
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/bootlogo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/bootlogo.h	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,325 @@
+#define splash_width 240
+#define splash_height 320
+static unsigned char splash_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf1, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0xf7, 0x0f, 0x00, 0x00,
+ 0x00, 0xf1, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0xf7, 0xef, 0x00, 0x00,
+ 0x00, 0xf1, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0xff, 0xff, 0x08, 0x00,
+ 0x00, 0x70, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x00, 0x10, 0xff, 0xff, 0x0c, 0x00,
+ 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x00, 0x10, 0xff, 0xff, 0x0e, 0x00,
+ 0x00, 0x00, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x00, 0x03, 0x10, 0xff, 0x0e, 0x00,
+ 0x00, 0x10, 0xfe, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x00, 0x0f, 0x00, 0xf0, 0x0e, 0x00,
+ 0x00, 0x30, 0x3e, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x00, 0x0f, 0x00, 0x30, 0x0e, 0x00,
+ 0x00, 0x30, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x00, 0x0f, 0x00, 0x70, 0x0e, 0x00,
+ 0x00, 0x70, 0x0c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x10, 0x0f, 0x00, 0x70, 0x0c, 0x00,
+ 0x00, 0x70, 0x0c, 0xf3, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x10, 0x0f, 0x00, 0xf0, 0x0c, 0x00,
+ 0x00, 0x70, 0x0c, 0xf1, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x10, 0x0e, 0x00, 0xf0, 0x08, 0x00,
+ 0x00, 0x70, 0x0c, 0xf0, 0x0c, 0x00, 0x00, 0x00, 0xc1, 0x00, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x8f, 0x10, 0x0e, 0x00, 0xf1, 0x08, 0x00,
+ 0x00, 0x70, 0x08, 0x70, 0x0c, 0x00, 0x00, 0x00, 0xe3, 0x00, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x8f, 0x10, 0x0e, 0x00, 0xf1, 0x00, 0x00,
+ 0x00, 0x70, 0x08, 0x70, 0x0c, 0x00, 0x00, 0x00, 0xcf, 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x00, 0x00, 0x8f, 0x30, 0x0c, 0x00, 0xe3, 0x00, 0x00,
+ 0x00, 0x70, 0x08, 0x70, 0x0c, 0x0e, 0x00, 0x10, 0x0f, 0x00, 0xcf, 0x00, 0x07, 0x00, 0x60, 0x00, 0x00, 0x00, 0x10, 0x38, 0x8f, 0x00, 0x00, 0x8f, 0x30, 0x0c, 0x00, 0xc7, 0x00, 0x00,
+ 0x00, 0xf0, 0x08, 0x70, 0x1c, 0x8f, 0x00, 0x30, 0x0f, 0x10, 0x8f, 0x00, 0xef, 0x00, 0xf1, 0x00, 0x00, 0x00, 0x30, 0x68, 0x8f, 0x00, 0x00, 0xcf, 0x30, 0x0c, 0x00, 0xcf, 0x00, 0x00,
+ 0x00, 0xf0, 0x08, 0x70, 0x38, 0xcf, 0x00, 0xf0, 0x0c, 0x30, 0x0f, 0x30, 0xff, 0x08, 0xf3, 0x00, 0x00, 0x00, 0x70, 0xc8, 0x0f, 0x00, 0x00, 0xcf, 0x70, 0x08, 0x00, 0x8f, 0x00, 0x00,
+ 0x00, 0xf0, 0x08, 0x70, 0x38, 0xef, 0x00, 0xf1, 0x08, 0x30, 0x0e, 0x70, 0xff, 0x0c, 0xf7, 0x00, 0x00, 0x00, 0x70, 0x8d, 0x0f, 0x00, 0x00, 0xcf, 0x70, 0x08, 0x10, 0x0f, 0x00, 0x00,
+ 0x00, 0xf0, 0x00, 0x70, 0x78, 0xff, 0x00, 0xf3, 0x81, 0x70, 0x0c, 0x70, 0xff, 0x0c, 0xff, 0x00, 0x00, 0x87, 0x70, 0x1f, 0x0e, 0x00, 0x00, 0xc7, 0xf0, 0x00, 0x30, 0x0e, 0x00, 0x00,
+ 0x00, 0xf0, 0x00, 0x70, 0x70, 0xff, 0x00, 0xe7, 0xc3, 0xf0, 0x08, 0xf0, 0x7f, 0x1c, 0xef, 0xf1, 0x00, 0x8f, 0x30, 0x3e, 0x0c, 0x00, 0x00, 0xc7, 0xf0, 0x00, 0x70, 0x0c, 0x00, 0x00,
+ 0x00, 0xf0, 0x00, 0xf0, 0xf0, 0xf1, 0x08, 0xcf, 0xc7, 0xf0, 0x00, 0xf1, 0x3c, 0x1c, 0xef, 0xf3, 0x18, 0x8f, 0x30, 0x7e, 0x08, 0x00, 0x00, 0xc7, 0xf1, 0x00, 0x70, 0x0c, 0x00, 0x00,
+ 0x00, 0xf0, 0x00, 0xf0, 0xe1, 0xf0, 0x18, 0x8f, 0xcf, 0xf1, 0x00, 0xf3, 0x3c, 0x3c, 0xef, 0xf7, 0x38, 0xcf, 0x70, 0x7e, 0x00, 0x00, 0x00, 0xc7, 0xe1, 0x00, 0xf0, 0x08, 0x00, 0x00,
+ 0x00, 0xf0, 0x00, 0xe1, 0xc1, 0xf0, 0x30, 0x1f, 0xcf, 0xf3, 0x00, 0xf7, 0x30, 0x78, 0xc3, 0xff, 0x78, 0xcf, 0xf0, 0xef, 0x00, 0x0c, 0x00, 0xc7, 0xe1, 0x00, 0xf1, 0x00, 0x00, 0x00,
+ 0x00, 0xf1, 0x00, 0xc3, 0x83, 0xf0, 0x70, 0x7e, 0xcf, 0xf7, 0x00, 0xef, 0x70, 0xf8, 0xd3, 0xff, 0xfc, 0xcf, 0xc1, 0xef, 0x30, 0x0c, 0x00, 0xc3, 0xc3, 0x00, 0xe3, 0x00, 0x00, 0x00,
+ 0x00, 0xe1, 0x00, 0xc3, 0x07, 0xf0, 0xf1, 0xfe, 0xe7, 0xff, 0x18, 0xef, 0x70, 0xe1, 0xb7, 0x7c, 0xed, 0xc7, 0x83, 0xcf, 0x70, 0x08, 0x00, 0xe3, 0xc3, 0x00, 0xc7, 0x00, 0x00, 0x00,
+ 0x00, 0xe1, 0x00, 0x87, 0x0e, 0xf0, 0xf3, 0xef, 0xf3, 0xfe, 0x38, 0xeb, 0xe0, 0x83, 0xf7, 0x38, 0xcf, 0xe7, 0x0f, 0xc7, 0xf0, 0x00, 0x00, 0xe3, 0x87, 0x00, 0x87, 0x00, 0x00, 0x00,
+ 0x00, 0xe1, 0x00, 0x1f, 0x0c, 0xe1, 0xb7, 0xcf, 0xf3, 0xf8, 0x7c, 0xe3, 0xc1, 0x07, 0xf7, 0x30, 0x8f, 0xf3, 0x0e, 0xef, 0xc3, 0x00, 0x00, 0xe3, 0x87, 0x00, 0x8f, 0x00, 0x00, 0x00,
+ 0x00, 0xe1, 0x10, 0x3e, 0x08, 0xe1, 0x7f, 0x8f, 0xf1, 0xf0, 0xec, 0xe3, 0xc7, 0x0e, 0xe7, 0x10, 0x0f, 0xf3, 0x1c, 0xff, 0x8f, 0x00, 0x00, 0xe1, 0x0f, 0x10, 0x0f, 0x00, 0x04, 0x00,
+ 0x00, 0xc1, 0x30, 0x0d, 0x00, 0xf1, 0x7e, 0x0f, 0x40, 0x70, 0xcf, 0xf3, 0x0f, 0x08, 0xcf, 0x00, 0x0e, 0xf1, 0x38, 0xf9, 0x0f, 0x00, 0x00, 0xf1, 0x0f, 0x30, 0x0e, 0x10, 0x0c, 0x00,
+ 0x00, 0xc1, 0x70, 0x0e, 0x00, 0xf3, 0x78, 0x0c, 0x00, 0x30, 0xcf, 0xf1, 0x0e, 0x00, 0x8f, 0x00, 0x00, 0xe0, 0x70, 0xf1, 0x0c, 0x00, 0x00, 0xf1, 0x0e, 0x70, 0x0c, 0xf0, 0x0c, 0x00,
+ 0x00, 0xc1, 0xf0, 0x0c, 0x00, 0xf3, 0x10, 0x00, 0x00, 0x10, 0x8f, 0xf1, 0x08, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xe0, 0x70, 0x00, 0x00, 0x00, 0xf0, 0x0e, 0xf0, 0x1c, 0xff, 0x08, 0x00,
+ 0x00, 0x81, 0xf3, 0x08, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0e, 0xf0, 0xff, 0xcf, 0x00, 0x00,
+ 0x00, 0x11, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0e, 0xf1, 0xff, 0x8f, 0x00, 0x00,
+ 0x00, 0x30, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0c, 0xf1, 0xff, 0x0e, 0x00, 0x00,
+ 0x00, 0x70, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xeb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x08, 0xf1, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x70, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00,
+ 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0c, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0e, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x87, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xe1, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xe0, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x70, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x30, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x30, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x30, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x30, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x70, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x78, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x78, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x8f, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xcf, 0x30, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xc7, 0x30, 0x0f, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0x08, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc1, 0x70, 0x0e, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0x0c, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc1, 0x70, 0x06, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xfb, 0x0c, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0xc1, 0xf0, 0x06, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x70, 0x0c, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0xc3, 0xe0, 0x0c, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x10, 0x0c, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x08, 0xc3, 0xe1, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x0c, 0x00, 0x87, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0xc7, 0xd1, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x0f, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x87, 0xd1, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x30, 0x08, 0x00, 0x0f, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x87, 0x93, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0f, 0x00, 0x00, 0x70, 0x08, 0x00, 0x0f, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0xf0, 0x00, 0x8f, 0xb3, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0x00, 0x3c, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x0e, 0xc7, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0xe0, 0x00, 0x0f, 0xe3, 0x00, 0x00, 0x70, 0x08, 0x00, 0x0e, 0x10, 0x6e, 0x0f, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x0e, 0x87, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0xe0, 0x00, 0x0f, 0xe3, 0x00, 0x00, 0xf0, 0x08, 0x10, 0x0e, 0x10, 0xce, 0x0e, 0x00, 0x00, 0xc1, 0x00, 0x10, 0x0e, 0x87, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0xe1, 0x00, 0x0f, 0xc7, 0x00, 0x0e, 0xf1, 0x68, 0x10, 0x0c, 0x10, 0x9f, 0x0c, 0x00, 0x00, 0xc3, 0x00, 0x10, 0x0c, 0x87, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x87, 0x83, 0xe1, 0x00, 0x04, 0xc7, 0x10, 0x0e, 0xf3, 0xf1, 0x30, 0x1c, 0x0c, 0x3f, 0x0c, 0x00, 0x00, 0x87, 0x00, 0x10, 0x0c, 0x87, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x8f, 0x87, 0xe1, 0x00, 0x00, 0x87, 0x30, 0x0e, 0xf7, 0xf3, 0x70, 0x3c, 0x0c, 0x3f, 0x08, 0x00, 0x00, 0x0f, 0x00, 0x10, 0x0c, 0x87, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x8f, 0x87, 0xe7, 0x00, 0x00, 0x07, 0x70, 0x0f, 0xfe, 0xf7, 0xf8, 0x3c, 0x1c, 0xff, 0x10, 0x00, 0x10, 0x0e, 0x00, 0x10, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x30, 0x0f, 0x8f, 0xef, 0x00, 0x00, 0x8f, 0xf0, 0x1f, 0xec, 0xff, 0xf9, 0x7c, 0x7e, 0xe7, 0x70, 0x00, 0x30, 0x0c, 0x00, 0x10, 0x0c, 0x77, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x70, 0x1f, 0xff, 0xed, 0x00, 0x30, 0x8f, 0xc1, 0x3f, 0xf8, 0x7e, 0xff, 0xfc, 0xef, 0xc3, 0xe0, 0x00, 0x30, 0x0c, 0x00, 0x10, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xe0, 0x37, 0xfb, 0xf9, 0x00, 0x30, 0x8b, 0x83, 0xff, 0xf1, 0x38, 0x3f, 0xdd, 0xcf, 0xc3, 0xc1, 0x00, 0x70, 0x08, 0x10, 0x10, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x81, 0xf7, 0xe3, 0xf0, 0x00, 0x60, 0xe3, 0x0f, 0xe7, 0xf1, 0x30, 0x3e, 0x9f, 0x8f, 0xf7, 0x0f, 0x00, 0xf0, 0x00, 0x70, 0x08, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0xe7, 0xc0, 0xf0, 0x08, 0xc0, 0xf3, 0x0e, 0xc7, 0xf1, 0x10, 0x38, 0x0f, 0x06, 0xff, 0x0e, 0x00, 0xe1, 0x00, 0x70, 0x08, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc7, 0x00, 0xf0, 0x08, 0x01, 0xf1, 0x0c, 0x01, 0xe1, 0x00, 0x10, 0x0e, 0x10, 0xfc, 0x0c, 0x00, 0xe3, 0x00, 0x70, 0x08, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x70, 0x0e, 0x07, 0x70, 0x00, 0x00, 0xc3, 0x00, 0x10, 0x0c, 0x30, 0x28, 0x00, 0x00, 0xf3, 0xff, 0x0c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0x0c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0x08, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xef, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x8f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x0e, 0x12, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x0c, 0x11, 0x1e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x0c, 0x90, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0x96, 0xc9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0x0e, 0xfa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0x0e, 0xa2, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0x0e, 0xa4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0x96, 0xa8, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0xf0, 0xe0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x08, 0x41, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x0c, 0x02, 0x00, 0x30, 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x0e, 0x04, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xf7, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x9f, 0x08, 0x00, 0x83, 0x00, 0x00, 0xf1, 0xff, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x48, 0x00, 0x10, 0xff, 0x1c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0x00, 0x70, 0xf1, 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xc9, 0x00, 0xc7, 0xe7, 0x00, 0xf3, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x1c, 0xff, 0x3c, 0x8f, 0x00, 0x70, 0xff, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x0e, 0x00, 0xf0, 0x0f, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0x7c, 0xff, 0x0f, 0x00, 0x00, 0xf3, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x30, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x10, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0xf7, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0x8f, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc7, 0x81, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x6c, 0x03, 0xf1, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x38, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x10, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf7, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7c, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0xff, 0x70, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x70, 0xff, 0xff, 0x8f, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x70, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x0e, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0xf1, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf1, 0xff, 0xff, 0x08, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0xf7, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf3, 0xff, 0xef, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x10, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0x8f, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x70, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0x0e, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0c, 0xf1, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0xff, 0xff, 0x08, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0xf3, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0xff, 0xef, 0x00, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x08, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0xff, 0xcf, 0x00, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x91, 0x10, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0xff, 0x0f, 0x00, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x33, 0x70, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0xff, 0x0c, 0x00, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x26, 0xf1, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0xff, 0x00, 0x00, 0x00, 0x30, 0xff, 0x00, 0x00, 0x00, 0x00, 0x6e, 0xf3, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0xef, 0x00, 0x00, 0x00, 0x30, 0xff, 0x00, 0x00, 0x00, 0x30, 0x4c, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x8f, 0x00, 0x00, 0x00, 0x30, 0xff, 0x00, 0x00, 0x00, 0x70, 0xd8, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x30, 0xff, 0x08, 0x00, 0x00, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0x08, 0x00, 0x00, 0xe3, 0xf1, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0x0c, 0x00, 0x00, 0xcf, 0xf3, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0x0e, 0x00, 0x10, 0x8f, 0xff, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0x8f, 0x00, 0xf0, 0x1e, 0xff, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0xef, 0x00, 0xf7, 0x7c, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xcf, 0xf3, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x1e, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0xff, 0xff, 0x78, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0xff, 0xcf, 0xf3, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0xff, 0x0f, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xff, 0xff, 0x1c, 0xff, 0xff, 0xff, 0x0e, 0x00, 0xf3, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0xfc, 0xff, 0x70, 0xff, 0xff, 0xef, 0x00, 0x00, 0x30, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0xf0, 0xcf, 0xf1, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xe3, 0xf0, 0x89, 0xf7, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x90, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xf3, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xf3, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x0f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x10, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x30, 0xff, 0xef, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x70, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x30, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0xf1, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0xf3, 0x08, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x30, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xf1, 0xff, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x30, 0x0e, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x70, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0e, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf0, 0xff, 0xf9, 0xff, 0xff, 0x0f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0xcf, 0xf1, 0xff, 0xff, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x8f, 0xf3, 0xff, 0x0e, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x01, 0xf7, 0xef, 0x00, 0x10, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0f, 0x00, 0x11, 0xff, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc3, 0x00, 0x73, 0x08, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf0, 0x08, 0xe3, 0x00, 0x00, 0x10, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x8f, 0x87, 0x00, 0x00, 0xf0, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf7, 0x0e, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf1, 0xff, 0x0e, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf1, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/bootstd.h linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/bootstd.h
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/bootstd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/bootstd.h	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,132 @@
+/* bootstd.h:  Bootloader system call interface
+ *
+ * (c) 1999, Rt-Control, Inc.
+ */
+
+#ifndef __BOOTSTD_H__
+#define __BOOTSTD_H__
+
+#define NR_BSC 21            /* last used bootloader system call */
+
+#define __BN_reset        0  /* reset and start the bootloader */
+#define __BN_test         1  /* tests the system call interface */
+#define __BN_exec         2  /* executes a bootloader image */
+#define __BN_exit         3  /* terminates a bootloader image */
+#define __BN_program      4  /* program FLASH from a chain */
+#define __BN_erase        5  /* erase sector(s) of FLASH */
+#define __BN_open         6
+#define __BN_write        7
+#define __BN_read         8
+#define __BN_close        9
+#define __BN_mmap         10 /* map a file descriptor into memory */
+#define __BN_munmap       11 /* remove a file to memory mapping */
+#define __BN_gethwaddr    12 /* get the hardware address of my interfaces */
+#define __BN_getserialnum 13 /* get the serial number of this board */
+#define __BN_getbenv      14 /* get a bootloader envvar */
+#define __BN_setbenv      15 /* get a bootloader envvar */
+#define __BN_setpmask     16 /* set the protection mask */
+#define __BN_readenv      17 /* read environment variables */
+#define __BN_flash_chattr_range		18
+#define __BN_flash_erase_range		19
+#define __BN_flash_write_range		20
+
+/* Calling conventions compatible to (uC)linux/68k
+ * We use simmilar macros to call into the bootloader as for uClinux
+ */
+
+#define __bsc_return(type, res) \
+do { \
+   if ((unsigned long)(res) >= (unsigned long)(-64)) { \
+      /* let errno be a function, preserve res in %d0 */ \
+      int __err = -(res); \
+      errno = __err; \
+      res = -1; \
+   } \
+   return (type)(res); \
+} while (0)
+
+#define _bsc0(type,name) \
+type name(void) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc1(type,name,atype,a) \
+type name(atype a) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc2(type,name,atype,a,btype,b) \
+type name(atype a, btype b) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc3(type,name,atype,a,btype,b,ctype,c) \
+type name(atype a, btype b, ctype c) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
+type name(atype a, btype b, ctype c, dtype d) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   register long __d __asm__ ("%d4") = (long)d; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c), "d" (__d) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
+type name(atype a, btype b, ctype c, dtype d, etype e) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   register long __d __asm__ ("%d4") = (long)d; \
+   register long __e __asm__ ("%d5") = (long)e; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c), "d" (__d), "d" (__e) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#endif /* __BOOTSTD_H__ */
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/config.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/config.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/config.c	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,128 @@
+/*
+ *  linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999 D. Jeff Dionne
+ *  Copyright (C) 2002 Andrew Ip <aip@cwlinux.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+
+#include <asm/MC68VZ328.h>
+
+void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
+{
+#ifdef CONFIG_DRAGONBALL_USE_RTC
+  /* Enable RTC */
+  RTCCTL|=RTCCTL_EN;
+  /* Enable 128Hz interrupt line */
+  RTCIENR|=RTCIENR_SAM5;
+  request_irq(SAM_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+#else
+  /* Restart mode, Enable int, 32KHz, Enable timer */
+  TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
+  /* Set prescaler (Divide 32.768KHz by 1)*/
+  TPRER = 0;
+  /* Set compare register  32.768Khz / 32 / 10 = 100 */
+  TCMP = 327;
+  request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+#endif
+}
+
+void BSP_tick(void)
+{
+#ifdef CONFIG_DRAGONBALL_USERTC
+        RTCISR|=RTCISR_SAM5;
+#else
+	/* Reset Timer1 */
+        TSTAT &= 0;
+#endif
+
+}
+
+unsigned long BSP_gettimeoffset (void)
+{
+  return 0;
+}
+
+void BSP_gettod (int *yearp, int *monp, int *dayp,
+		   int *hourp, int *minp, int *secp)
+{
+ //rtcgettod(yearp, monp, dayp, hourp, minp, secp);
+ *yearp = *monp = *dayp = *hourp = *minp = *secp = 0;
+}
+
+int BSP_hwclk(int op, struct hwclk_time *t)
+{
+  if (!op) {
+    /* read */
+  } else {
+    /* write */
+  }
+  return 0;
+}
+
+int BSP_set_clock_mmss (unsigned long nowtime)
+{
+#if 0
+  short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+
+  tod->second1 = real_seconds / 10;
+  tod->second2 = real_seconds % 10;
+  tod->minute1 = real_minutes / 10;
+  tod->minute2 = real_minutes % 10;
+#endif
+  return 0;
+}
+
+void BSP_reset (void)
+{
+  cli();
+  asm volatile ("
+    moveal #0x02000000, %a0;
+    moveb #0, 0xFFFFF300;
+    moveal 0(%a0), %sp;
+    moveal 4(%a0), %a0;
+    jmp (%a0);
+    ");
+}
+
+unsigned char cs8900a_hwaddr1[6],cs8900a_hwaddr2[6];
+static int errno;
+
+void config_BSP(char *command, int len)
+{
+  int year, mon, day, hour, min, sec;
+
+  printk("68VZ328 DragonBallVZ support (c) 2001 Lineo, Inc.\n");
+
+  command[0] = 0;
+
+  mach_sched_init      = BSP_sched_init;
+  mach_tick            = BSP_tick;
+  mach_gettimeoffset   = BSP_gettimeoffset;
+  mach_gettod          = BSP_gettod;
+  mach_hwclk           = NULL;
+  mach_set_clock_mmss  = NULL;
+  // mach_mksound         = NULL;
+  mach_reset           = BSP_reset;
+  // mach_debug_init      = NULL;
+
+  config_M68VZ328_irq();
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/crt0_fixed.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/crt0_fixed.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/crt0_fixed.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/crt0_fixed.S	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,309 @@
+	.global _start
+	.global _stext
+
+	.global _rambase
+	.global _ramvec
+	.global _ramstart
+	.global _ramend
+	.global splash_bits
+
+#include <linux/config.h>
+#define IMR 0xFFFFF304
+/* #define INIT_LCD */
+#undef INIT_LCD
+
+	.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+splash_bits:
+#include "bootlogo.rh"
+	.text
+_start:
+_stext:
+
+	nop
+
+	moveb	#0x00,   0xfffffb0b	/* Watchdog off */
+	moveb	#0x10,   0xfffff000	/* SCR */
+
+	movew   #0x2483, 0xfffff200	/* PLLCR */
+	movew   #0x0347, 0xfffff202	/* PLLFSR */
+
+        /* Set special purpose bits of ports*/
+	moveb	#0xc0,   0xfffff40b	/* Chip select */
+	moveb	#0x00,   0xfffff413	/* LCD */
+        moveb	#0xcf,   0xfffff423	/* RXD1 and TXD1 */
+        moveb	#0x02,   0xfffff42b	/* A,CSA and CLKO */
+        moveb   #0xfd,   0xfffff443     /* R/W enable for flash*/
+        /*moveb	#0x3c,   0xfffff433*/	/* A0 and DTACK */
+	moveb 	#0x3f,   0xfffff433   	/* Port G as GPIO */
+        moveb	#0x20,   0xfffff44b	/* SDRAM */
+	moveb	#0x08,   0xfffffd0d	/* disable hardmap */
+	moveb	#0x07,   0xfffffd0e	/* level 7 interrupt clear */
+
+        movew   #0x8000, 0xfffff108     /* Full decode A31:A29=0 */
+
+        /* set flash size */
+        movew   #0x1000, 0xfffff100     /* Start at 0x2000000 with flash */
+#if defined ( CONFIG_FLASH2MB )
+        #ifdef CONFIG_FLASH2WS
+                movew	#0x0197, 0xfffff110	/* 2x1Meg, 16bit, enable, 2ws */
+        #else
+	        movew	#0x0187, 0xfffff110	/* 2x1Meg, 16bit, enable, 0ws */
+        #endif
+#elif defined ( CONFIG_FLASH4MB )
+        #ifdef CONFIG_FLASH2WS
+                movew	#0x0199, 0xfffff110	/* 2x2Meg, 16bit, enable, 2ws */
+        #else
+	        movew	#0x0189, 0xfffff110	/* 2x2Meg, 16bit, enable, 0ws */
+        #endif
+#elif defined ( CONFIG_FLASH8MB )
+        #ifdef CONFIG_FLASH2WS
+                movew	#0x019B, 0xfffff110	/* 2x4Meg, 16bit, enable, 2ws */
+        #else
+	        movew	#0x018B, 0xfffff110	/* 2x4Meg, 16bit, enable, 0ws */
+        #endif
+#elif defined ( CONFIG_FLASH16MB )
+        #ifdef CONFIG_FLASH2WS
+                movew	#0x019D, 0xfffff110	/* 2x8Meg, 16bit, enable, 2ws */
+        #else
+	        movew	#0x018D, 0xfffff110	/* 2x8Meg, 16bit, enable, 0ws */
+        #endif
+#else
+        #error "No flash size defined"
+#endif
+
+        movew   #0x2000, 0xfffff102     /* Start at 0x4000000 with FPGA and ethernet */
+
+        /*movew   #0x01ff, 0xfffff112*/     /* use 16MB size, external DTACK */
+	movew   #0x0191, 0xfffff112     /* use 128kB size, 16bit, enable, 2ws */
+#if defined ( CONFIG_RAM8MB )
+        movew   #0x0000, 0xfffff106     /* CSD init at $0 */
+        movew   #0x0281, 0xfffff116     /* enable SDRAM cs */
+        movew   #0x0040, 0xfffff10a     /* chip select control */
+        movew   #0x0000, 0xfffffc02     /* DRAMC disable */
+        movew   #0xc03f, 0xfffffc04     /* SDCTRL use PA22 and PA21, CAS=1, RACL=3CLK */
+        movew   #0x4020, 0xfffffc00     /* DRAMMC double CLK32 for refresh */
+        movew   #0x8000, 0xfffffc02     /* DRAMC */
+        movew   #0xc83f, 0xfffffc04     /* SDCTRL precharge */
+	movew	#32767, %d0  /* PLL settle wait loop */
+SDL0:
+	subw	#1, %d0
+	bne	SDL0
+        movew   #0xD03f, 0xfffffc04     /* SDCTRL enable refresh */
+	movew	#32767, %d0  /* PLL settle wait loop */
+SDL1:
+	subw	#1, %d0
+	bne	SDL1
+        movew   #0xD43f, 0xfffffc04     /* SDCTRL set mode registers in SDRAM */
+        movew	#32767, %d0  /* PLL settle wait loop */
+SDL2:
+	subw	#1, %d0
+	bne	SDL2
+#elif defined ( CONFIG_RAM32MB )
+        movew   #0x0000, 0xfffff106     /* CSD init at $0 */
+        movew   #0x0683, 0xfffff116     /* enable SDRAM cs */
+        movew   #0x0040, 0xfffff10a     /* chip select control */
+        movew   #0x0000, 0xfffffc02     /* DRAMC disable */
+        movew   #0xc03f, 0xfffffc04     /* SDCTRL use PA24 and PA23, CAS=1, RACL=3CLK */
+        movew   #0x0F80, 0xfffffc00     /* DRAMMC double CLK32 for refresh */
+        movew   #0x8000, 0xfffffc02     /* DRAMC */
+        movew   #0xc83f, 0xfffffc04     /* SDCTRL precharge */
+	movew	#32767, %d0  /* PLL settle wait loop */
+SDL0:
+	subw	#1, %d0
+	bne	SDL0
+        movew   #0xD03f, 0xfffffc04     /* SDCTRL enable refresh */
+	movew	#32767, %d0  /* PLL settle wait loop */
+SDL1:
+	subw	#1, %d0
+	bne	SDL1
+        movew   #0xD43f, 0xfffffc04     /* SDCTRL set mode registers in SDRAM */
+        movew	#32767, %d0  /* PLL settle wait loop */
+SDL2:
+	subw	#1, %d0
+	bne	SDL2
+#else
+        #error "No sdram size defined"
+#endif
+
+	moveb	#0x40,   0xfffff300	/* IVR */
+	movel	#0x007FFFFF, %d0	/* IMR */
+	movel	%d0,     0xfffff304
+
+	/*moveb   0xfffff42b, %d0
+	andb    #0xe0,   %d0
+	moveb   %d0,     0xfffff42b*/
+
+	moveb	#0x08,   0xfffff907	/* Ignore CTS */
+	movew	#0x0138, 0xfffff902	/* BAUD to 115.2k */
+	movew	#0xe100, 0xfffff900	/* enable */
+
+	moveb   #0,      0xfffffA27	/* LCKCON - LCD is off */
+#ifdef INIT_LCD
+        /* FIXME add code for display here */
+	movel	#__vram_start, 0xfffffA00 /* LSSA */
+	moveb	#15,   0xfffffA05	/* LVPW */
+	movew	#240,  0xFFFFFa08	/* LXMAX */
+	movew	#320,  0xFFFFFa0a	/* LYMAX */
+	moveb	#0,      0xfffffa29	/* LBAR */
+	moveb	#0,      0xfffffa25	/* LPXCD */
+	moveb	#0x08,   0xFFFFFa20	/* LPICF */
+	moveb	#0x00,   0xFFFFFA21	/* +ve pol (without backlight)*/
+        moveb   #0x0,    0xFFFFFA23     /* LACD toggle rate*/
+	moveb	#0x80,   0xfffffA27	/* LCKCON */
+	movew	#0xff00, 0xfffff412	/* LCD pins */
+        moveb	#0xc0,   0xfffff408	/* DispEn, BLEn both Outputs */
+        moveb	#0xc0,   0xfffff409	/* Enable Display, no backlight */
+        /* Copy data segment from ROM to RAM */
+	moveal	#splash_bits, %a0
+	moveal	#__vram_start, %a1
+	moveal	#__vram_end, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+DC1:
+	movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bhi	DC1
+#endif
+
+	/*moveb	#0xf0,	0xfffff41b
+	moveb	#0xff,	0xfffff418
+	moveb	#0x00,	0xfffff419*/
+
+#ifdef CONFIG_68328_SERIAL_UART2
+	/* Enable RXD TXD port bits to enable UART2 */
+	moveb	#0xcf,	0xfffff43b
+#endif
+
+#if defined ( CONFIG_RAM8MB )
+	moveal  #__ramend - 0x10, %sp
+#elif defined ( CONFIG_RAM32MB )
+        moveal  #__ramend - 0x10, %sp
+#else
+        #error "No sdram size defined"
+#endif
+	movew	#0x2700, %sr
+
+	moveq	#13, %d7		/* '\r' */
+	jsr putc
+
+	moveq	#10, %d7		/* '\n' */
+	jsr putc
+
+	moveq	#65, %d7		/* 'A' */
+	jsr putc
+
+	movew	#32767, %d0  /* PLL settle wait loop */
+L0:
+	subw	#1, %d0
+	bne	L0
+
+	moveq	#66, %d7		/* 'B' */
+	jsr	putc
+
+#if 1
+	/* Copy data segment from ROM to RAM */
+	moveal	#__data_rom_start, %a0
+	moveal	#_sdata, %a1
+	moveal	#_edata, %a2
+	moveq	#67, %d7		/* 'C' */
+	jsr	putc
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:
+	movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bhi	LD1
+#endif
+
+	moveq	#68, %d7		/* 'D' */
+	jsr	putc
+
+	moveal	#_sbss, %a0
+	moveal	#_ebss, %a1
+	/* Copy 0 to %a0 until %a0 == %a1 */
+
+_clear_bss:
+	movel	#0, %a0@+
+	cmpal	%a0, %a1
+	bhi	_clear_bss
+
+        movel   #_sdata, %d0
+        movel   %d0,    _rambase
+        movel   #_ebss,  %d0
+        movel   %d0,    _ramstart
+#if defined ( CONFIG_RAM8MB )
+        movel	#__ramend, %d0
+#elif defined ( CONFIG_RAM32MB )
+        movel	#__ramend, %d0
+#else
+        #error "No sdram size defined"
+#endif
+        
+	movel	%d0,	_ramend
+	movel	#__ramvec,	%d0
+	movel	%d0,	_ramvec
+
+	moveq	#69, %d7		/* 'E' */
+	jsr	putc
+
+        /*
+         * load the current task pointer and stack
+         */
+        lea     init_task_union,%a0
+        movel   %a0, _current_task
+        lea     0x2000(%a0),%sp
+
+	/*
+	pea	0
+	pea	env
+	pea	%sp@(4)
+	pea	0
+	*/
+
+	moveq	#70, %d7		/* 'F' */
+	jsr	putc
+
+ 	moveq	#13, %d7		/* '\r' */
+	jsr putc
+
+	moveq	#10, %d7		/* '\n' */
+	jsr putc
+
+lp:
+	jsr	start_kernel
+        jmp lp
+_exit:
+
+	jmp	_exit
+
+
+putc:
+	moveb	%d7,0xfffff907
+pclp:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	pclp
+	rts
+
+	.data
+env:
+	.long	0
+	.text
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/crt0_rom.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/crt0_rom.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/crt0_rom.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/crt0_rom.S	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/fixed.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/fixed.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/fixed.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/fixed.ld	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,95 @@
+SECTIONS
+{
+  .romvec :
+	{
+	_flashstart = . ;
+	_romvec = . ;
+	__rom_start = . ;
+	} > romvec
+
+  .text :
+	{
+	_stext = . ;
+        	*(.text)
+	. = ALIGN(0x4) ;
+		*(.text.*)
+	. = ALIGN(0x4) ;
+		*(.exitcall.exit)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);		/* Exception table */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+	__start___ksymtab = .; /* Kernel symbol table */
+		*(__ksymtab)
+	__stop___ksymtab = .;
+
+	. = ALIGN(0x4);
+	_etext = . ;
+	__data_rom_start = . ;
+        } > flash
+
+  .eflash :
+	{
+	_flashend = . ;
+	} > eflash
+
+  .ramvec :
+	{
+	__ram_start = . ;
+	__ramvec = . ;
+	} > ramvec
+  
+  .data : 
+	{
+	. = ALIGN(0x4) ;
+	_sdata = . ;
+	__data_start = . ;
+
+	. = ALIGN(0x4) ;
+		*(.rodata)
+	. = ALIGN(0x4) ;
+		*(.rodata.str1.1)
+	. = ALIGN(0x4) ;
+		*(.data)
+	. = ALIGN(0x4) ;
+		*(.data.*)
+
+	. = ALIGN(0x4) ;
+	__setup_start = .;
+		*(.setup.init)
+	. = ALIGN(0x4) ;
+	__setup_end = .;
+
+	. = ALIGN(0x4) ;
+	__initcall_start = .;
+		*(.initcall.init)
+	. = ALIGN(0x4) ;
+	__initcall_end = .;
+
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	. = ALIGN(0x2000) ;
+
+	_edata = . ;
+        } > ram
+
+  .bss :
+        {
+	. = ALIGN(0x4) ;
+	_sbss = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	_ebss = . ;
+	_end = . ;
+	} > ram
+
+  .eram :
+	{
+        __ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/hardware.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/hardware.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/hardware.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/hardware.c	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,312 @@
+/*
+ *  linux/arch/m68knommu/platform/68VZ328/cwvz328/hardware.c
+ *
+ *  (C)  2002 by      Daniel Haensse <daniel.haensse@alumni.ethz.ch>
+ *  Use it under GPL
+ */
+
+/* Common functions */
+
+#include <asm/MC68VZ328.h>
+
+
+
+
+void putC (char ch)
+{
+	UTX_TXDATA = ch;
+	while (!(UTX & 0x2000));
+}
+
+void putS (char * str)
+{
+	while (*str) putC (*(str++));
+}
+void printhex (unsigned long n)
+{
+unsigned long	i;
+	if ((i = n / 16)) printhex (i);
+	if (n % 16 > 9) putC (n % 16 + '7');
+	else putC (n % 16 + '0');
+}
+
+
+void uwait(unsigned long x)
+{
+ int loop;
+ while(x>0)
+ {
+  for(loop=0;loop<10;loop++);
+  x--;
+ }
+}
+
+/* SPI functions */
+
+#define NONE 0
+#define PEN  1
+#define CLK  2
+
+
+unsigned long SPIIO(unsigned char chip, unsigned long shifts, unsigned long out)
+{
+ int loop;
+ unsigned long in=0;
+
+ *(volatile unsigned  char *)0x4000103=(chip&0x03);
+ uwait(5);
+
+ for(loop=shifts;loop>0;loop--)
+ {
+  *(volatile unsigned  char *)0x4000103= (((out&(1<<(loop-1)))!=0 ? 0x10 : 0x00) | (chip&0x03));        /* data out */
+  uwait(1);
+  *(volatile unsigned  char *)0x4000103= (((out&(1<<(loop-1)))!=0 ? 0x10 : 0x00) | (chip&0x03) | 0x04); /* clk */
+  uwait(5);
+  in=(in<<1) | (((*(volatile unsigned  char *)0x4000103)&0x10)>>4);
+  uwait(5);
+  *(volatile unsigned  char *)0x4000103= (((out&(1<<(loop-1)))!=0 ? 0x10 : 0x00) | (chip&0x03));        /* data out */
+  uwait(5);
+ }
+ *(volatile unsigned  char *)0x4000103=0; /* deselect all */
+ return(in);
+}
+
+
+/* I2C Functions */
+
+unsigned char I2CStart()
+{
+ *(volatile unsigned  char *)0x4000102= 0x0f; /* SDA=1 , SCL =1 */
+ uwait(5);
+ *(volatile unsigned  char *)0x4000102= 0x0b; /* SDA=0 , SCL =1 */
+ uwait(5);
+ *(volatile unsigned  char *)0x4000102= 0x0a; /* SDA=0 , SCL =0 */
+ uwait(5);
+}
+
+void I2CACK()
+{
+
+ *(volatile unsigned  char *)0x4000102= 0x0b; /* SDA=0 , SCL =1 */
+ uwait(5);
+ *(volatile unsigned  char *)0x4000102= 0x0a; /* SDA=0 , SCL =0 */
+ uwait(5);
+}
+
+void I2CNACK()
+{
+ *(volatile unsigned  char *)0x4000102= 0x0f; /* SDA=1 , SCL =1 */
+ uwait(5);
+ *(volatile unsigned  char *)0x4000102= 0x0e; /* SDA=1 , SCL =0 */
+ uwait(5);
+}
+
+
+unsigned char I2CSendByte(unsigned char data)
+{
+ int loop;
+ for(loop=0;loop<8;loop++)
+ {
+  if(data&0x80)
+  {
+   *(volatile unsigned  char *)0x4000102= 0x0e; /* SDA=1 , SCL =0 */
+   uwait(1);
+   *(volatile unsigned  char *)0x4000102= 0x0f; /* SDA=1 , SCL =1 */
+   uwait(5);
+   *(volatile unsigned  char *)0x4000102= 0x0e; /* SDA=1 , SCL =0 */
+   uwait(5);
+
+  }
+  else
+  {
+   *(volatile unsigned  char *)0x4000102= 0x0a; /* SDA=0 , SCL =0 */
+   uwait(1);
+   *(volatile unsigned  char *)0x4000102= 0x0b; /* SDA=0 , SCL =1 */
+   uwait(5);
+   *(volatile unsigned  char *)0x4000102= 0x0a; /* SDA=0 , SCL =0 */
+   if(loop!=7)
+   {
+    uwait(5);
+   }
+  }
+  data=data<<1;
+ }
+ *(volatile unsigned  char *)0x4000102= 0x02; /* SDA=Z , SCL =0 */
+ uwait(5);
+ *(volatile unsigned  char *)0x4000102= 0x03; /* SDA=Z , SCL =1 */
+ uwait(5);
+ loop=((*(volatile unsigned  char *)0x4000102) & 0x04)>>2;
+ uwait(5);
+ *(volatile unsigned  char *)0x4000102= 0x0e; /* SDA=1 , SCL =0 */
+ uwait(5);
+}
+
+unsigned char I2CGetByte()
+{
+ int loop;
+ unsigned char data=0;
+ for(loop=0;loop<8;loop++)
+ {
+  *(volatile unsigned  char *)0x4000102= 0x02; /* SDA=Z , SCL =0 */
+  uwait(5);
+  *(volatile unsigned  char *)0x4000102= 0x03; /* SDA=Z , SCL =1 */
+  uwait(5);
+  data|=((*(volatile unsigned  char *)0x4000102) & 0x04)<<5;
+  uwait(5);
+  *(volatile unsigned  char *)0x4000102= 0x02; /* SDA=Z , SCL =0 */
+ }
+ *(volatile unsigned  char *)0x4000102= 0x0a; /* SDA=0 , SCL =0 */
+ uwait(5);
+ return(data);
+}
+
+unsigned char I2CStop()
+{
+ *(volatile unsigned  char *)0x4000102= 0x0a; /* SDA=0 , SCL =0 */
+ uwait(5);
+ *(volatile unsigned  char *)0x4000102= 0x0b; /* SDA=0 , SCL =1 */
+ uwait(5);
+ *(volatile unsigned  char *)0x4000102= 0x0f; /* SDA=1 , SCL =1 */
+ uwait(5);
+}
+
+/* Abstract functions, please keep the functions untouched when we improve the functionality of the FPGA */
+
+unsigned char BCD_TO_BIN(unsigned char val)
+{
+        return( ((val)&15) + ((val)>>4)*10 );
+}
+
+/* Read Real Time Clock Location */
+unsigned char RTCRead(unsigned int addr)
+{
+ return( SPIIO(CLK,16,addr<<8) &0xff );
+}
+
+/* Write Real Time Clock Location */
+void RTCWrite(unsigned int addr,unsigned char data)
+{
+ SPIIO(CLK,16,(addr<<8)|0x8000 | data);
+}
+
+
+/* Set Contrast Voltage, see pdf for table */
+void SetContrast(unsigned char data)
+{
+ I2CStart();                                          /* Send start bit */
+ I2CSendByte(0x58);
+ I2CSendByte(data);
+ I2CStop();
+}
+
+/* Backlight */
+void BacklightOn()
+{
+ *(volatile unsigned  char *) 0xfffff409 &=~0x80;
+}
+
+void BacklightOff()
+{
+ *(volatile unsigned  char *) 0xfffff409 |=0x80;
+}
+
+/* We use the following mapping of the cmos ram */
+/*
+        0x20 xor crc of memory 0x21 to 0x7F
+        0x21 lcdcontrast
+        0x22,0x23,0x24,0x25,0x26,0x27 mac address 1
+        0x28,0x29,0x2a,0x2b,0x2c,0x2d mac address 2
+        0x2e and following are unused
+*/
+
+unsigned char rtccmosinvalid()
+{
+ unsigned char crccalc=0,crc;
+ unsigned int addr;
+ crc=RTCRead(0x20);
+ for(addr=0x21;addr<0x80;addr++)  crccalc^=RTCRead(addr);
+ if(crc!=crccalc)
+ {
+ /* Folks if you use a display that needs a voltage,
+    change this otherwise it will be destroyed  */
+        RTCWrite(0x0f,0x00);    /* Remove write protection */
+        RTCWrite(0x21,0x00);    /* Switch contrast off */
+        RTCWrite(0x22,0x00);    /* Mac 1 */
+        RTCWrite(0x23,0x08);
+        RTCWrite(0x24,0x9D);
+        RTCWrite(0x25,0x00);
+        RTCWrite(0x26,0x00);
+        RTCWrite(0x27,0x00);
+        RTCWrite(0x28,0x00);    /* Mac 2 */
+        RTCWrite(0x29,0x08);
+        RTCWrite(0x2a,0x9D);
+        RTCWrite(0x2b,0x00);
+        RTCWrite(0x2c,0x00);
+        RTCWrite(0x2d,0x01);
+        crccalc=0;
+        for(addr=0x21;addr<0x80;addr++)  crccalc^=RTCRead(addr);
+        RTCWrite(0x20,crccalc); /* Revalidate CMOS, leave time unchanged */
+        RTCWrite(0x0f,0x40);    /* Enable write protection */
+        return(0x01);
+ }
+ else
+        return(0x00);
+}
+
+/* Charge Lithium Battery */
+void rtcchargebattery()
+{
+ RTCWrite(0x0f,0x00);    /* Remove write protection */
+ RTCWrite(0x11,0xa5);    /* 3.9-0.7V = 3.2V Zenervoltage sourced over 200R resistor and 2k serie resistor */
+ RTCWrite(0x0f,0x40);    /* Enable write protection */
+}
+
+void rtcgettod(int *yearp, int *monp, int *dayp, int *hourp, int *minp, int *secp)
+{
+	*secp   =       BCD_TO_BIN(RTCRead(0x00));
+	*minp   =       BCD_TO_BIN(RTCRead(0x01));
+	*hourp  =       BCD_TO_BIN(RTCRead(0x02));
+	*dayp   =       BCD_TO_BIN(RTCRead(0x04));
+	*monp   =       BCD_TO_BIN(RTCRead(0x05));
+	*yearp  =       BCD_TO_BIN(RTCRead(0x06));
+}
+
+/* LCD contrast */
+unsigned char lcdsetcontrast()
+{
+ unsigned char contr=RTCRead(0x21);
+ SetContrast(contr);
+ return(contr);
+}
+
+/* Get hardware address */
+void gethwaddr(unsigned char dev, unsigned char *addr)
+{
+ unsigned char i;
+ if(dev==0) // Mac 1
+ {
+  for(i=0;i<6;i++)
+  {
+   addr[i]=RTCRead(0x22+i);
+  }
+ }
+ else // Mac 2
+ {
+  for(i=0;i<6;i++)
+  {
+   addr[i]=RTCRead(0x28+i);
+  }
+ }
+}
+
+/* Copy date from external to internal RTC */
+void rtcgetintern()
+{
+ /* We must run the RTC in 24 hour mode!!! */
+/* RTCTIME=BCD_TO_BIN(RTCRead(0x00))
+        |(BCD_TO_BIN(RTCRead(0x01))<<16)
+        |(BCD_TO_BIN(RTCRead(0x02))<<24);
+  */
+
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/ints.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/ints.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/ints.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/ints.c	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,375 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne <jeff@uClinux.org>
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+
+#include <asm/MC68VZ328.h>
+
+#define INTERNAL_IRQS (32)
+
+/* assembler routines */
+asmlinkage void system_call(void);
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void trap3(void);
+asmlinkage void trap4(void);
+asmlinkage void trap5(void);
+asmlinkage void trap6(void);
+asmlinkage void trap7(void);
+asmlinkage void trap8(void);
+asmlinkage void trap9(void);
+asmlinkage void trap10(void);
+asmlinkage void trap11(void);
+asmlinkage void trap12(void);
+asmlinkage void trap13(void);
+asmlinkage void trap14(void);
+asmlinkage void trap15(void);
+asmlinkage void trap33(void);
+asmlinkage void trap34(void);
+asmlinkage void trap35(void);
+asmlinkage void trap36(void);
+asmlinkage void trap37(void);
+asmlinkage void trap38(void);
+asmlinkage void trap39(void);
+asmlinkage void trap40(void);
+asmlinkage void trap41(void);
+asmlinkage void trap42(void);
+asmlinkage void trap43(void);
+asmlinkage void trap44(void);
+asmlinkage void trap45(void);
+asmlinkage void trap46(void);
+asmlinkage void trap47(void);
+asmlinkage void bad_interrupt(void);
+asmlinkage void inthandler(void);
+asmlinkage void inthandler1(void);
+asmlinkage void inthandler2(void);
+asmlinkage void inthandler3(void);
+asmlinkage void inthandler4(void);
+asmlinkage void inthandler5(void);
+asmlinkage void inthandler6(void);
+asmlinkage void inthandler7(void);
+
+// extern void *_ramvec[];
+extern e_vector *_ramvec;
+
+/* irq node variables for the 32 (potential) on chip sources */
+static irq_node_t *int_irq_list[INTERNAL_IRQS];
+
+static int int_irq_count[INTERNAL_IRQS];
+static short int_irq_ablecount[INTERNAL_IRQS];
+
+static void int_badint(int irq, void *dev_id, struct pt_regs *fp)
+{
+	num_spurious += 1;
+}
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the amiga IRQ handling routines.
+ */
+
+void M68VZ328_init_IRQ(void)
+{
+	int i;
+
+	/* set up the vectors */
+#if 0
+	_ramvec[2] = buserr;
+	_ramvec[3] = trap3;
+	_ramvec[4] = trap4;
+	_ramvec[5] = trap5;
+	_ramvec[6] = trap6;
+	_ramvec[7] = trap7;
+	_ramvec[8] = trap8;
+	_ramvec[9] = trap9;
+	_ramvec[10] = trap10;
+	_ramvec[11] = trap11;
+	_ramvec[12] = trap12;
+	_ramvec[13] = trap13;
+	_ramvec[14] = trap14;
+	_ramvec[15] = trap15;
+#endif
+	_ramvec[32] = system_call;
+
+	_ramvec[64] = bad_interrupt;
+	_ramvec[65] = inthandler1;
+	_ramvec[66] = inthandler2;
+	_ramvec[67] = inthandler3;
+	_ramvec[68] = inthandler4;
+	_ramvec[69] = inthandler5;
+	_ramvec[70] = inthandler6;
+	_ramvec[71] = inthandler7;
+ 
+	IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
+
+	/* initialize handlers */
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		int_irq_list[i] = NULL;
+
+		int_irq_ablecount[i] = 0;
+		int_irq_count[i] = 0;
+	}
+	/* turn off all interrupts */
+	IMR = ~0;
+}
+
+void M68VZ328_insert_irq(irq_node_t **list, irq_node_t *node)
+{
+	unsigned long flags;
+	irq_node_t *cur;
+
+	if (!node->dev_id)
+		printk("%s: Warning: dev_id of %s is zero\n",
+		       __FUNCTION__, node->devname);
+
+	save_flags(flags);
+	cli();
+
+	cur = *list;
+
+	while (cur) {
+		list = &cur->next;
+		cur = cur->next;
+	}
+
+	node->next = cur;
+	*list = node;
+
+	restore_flags(flags);
+}
+
+void M68VZ328_delete_irq(irq_node_t **list, void *dev_id)
+{
+	unsigned long flags;
+	irq_node_t *node;
+
+	save_flags(flags);
+	cli();
+
+	for (node = *list; node; list = &node->next, node = *list) {
+		if (node->dev_id == dev_id) {
+			*list = node->next;
+			/* Mark it as free. */
+			node->handler = NULL;
+			restore_flags(flags);
+			return;
+		}
+	}
+	restore_flags(flags);
+	printk ("%s: tried to remove invalid irq\n", __FUNCTION__);
+}
+
+int M68VZ328_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                         unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+	if (!int_irq_list[irq]) {
+		int_irq_list[irq] = new_irq_node();
+		int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	}
+
+	if (!(int_irq_list[irq]->flags & IRQ_FLG_STD)) {
+		if (int_irq_list[irq]->flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+	}
+	int_irq_list[irq]->handler = handler;
+	int_irq_list[irq]->flags   = flags;
+	int_irq_list[irq]->dev_id  = dev_id;
+	int_irq_list[irq]->devname = devname;
+
+	/* enable in the IMR */
+	if (!int_irq_ablecount[irq])
+		*(volatile unsigned long *)0xfffff304 &= ~(1<<irq);
+
+	return 0;
+}
+
+void M68VZ328_free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_list[irq]->dev_id != dev_id)
+		printk("%s: removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, int_irq_list[irq]->devname);
+	int_irq_list[irq]->handler = int_badint;
+	int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	int_irq_list[irq]->dev_id  = NULL;
+	int_irq_list[irq]->devname = NULL;
+
+	*(volatile unsigned long *)0xfffff304 |= 1<<irq;
+}
+
+/*
+ * Enable/disable a particular machine specific interrupt source.
+ * Note that this may affect other interrupts in case of a shared interrupt.
+ * This function should only be called for a _very_ short time to change some
+ * internal data, that may not be changed by the interrupt at the same time.
+ * int_(enable|disable)_irq calls may also be nested.
+ */
+
+void M68VZ328_enable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (--int_irq_ablecount[irq])
+		return;
+
+	/* enable the interrupt */
+	*(volatile unsigned long *)0xfffff304 &= ~(1<<irq);
+}
+
+void M68VZ328_disable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_ablecount[irq]++)
+		return;
+
+	/* disable the interrupt */
+	*(volatile unsigned long *)0xfffff304 |= 1<<irq;
+}
+
+/* The 68k family did not have a good way to determine the source
+ * of interrupts until later in the family.  The EC000 core does
+ * not provide the vector number on the stack, we vector everything
+ * into one vector and look in the blasted mask register...
+ * This code is designed to be fast, almost constant time, not clean!
+ */
+inline int M68VZ328_do_irq(int vec, struct pt_regs *fp)
+{
+	int irq;
+	int mask;
+
+	unsigned long pend = *(volatile unsigned long *)0xfffff30c;
+
+	while (pend) {
+		if (pend & 0x0000ffff) {
+			if (pend & 0x000000ff) {
+				if (pend & 0x0000000f) {
+					mask = 0x00000001;
+					irq = 0;
+				} else {
+					mask = 0x00000010;
+					irq = 4;
+				}
+			} else {
+				if (pend & 0x00000f00) {
+					mask = 0x00000100;
+					irq = 8;
+				} else {
+					mask = 0x00001000;
+					irq = 12;
+				}
+			}
+		} else {
+			if (pend & 0x00ff0000) {
+				if (pend & 0x000f0000) {
+					mask = 0x00010000;
+					irq = 16;
+				} else {
+					mask = 0x00100000;
+					irq = 20;
+				}
+			} else {
+				if (pend & 0x0f000000) {
+					mask = 0x01000000;
+					irq = 24;
+				} else {
+					mask = 0x10000000;
+					irq = 28;
+				}
+			}
+		}
+
+		while (! (mask & pend)) {
+			mask <<=1;
+			irq++;
+		}
+
+		if (int_irq_list[irq] && int_irq_list[irq]->handler) {
+			int_irq_list[irq]->handler(irq, int_irq_list[irq]->dev_id, fp);
+			int_irq_count[irq]++;
+		} else {
+			printk("unregistered interrupt %d!\nTurning it off in the IMR...\n", irq);
+			*(volatile unsigned long *)0xfffff304 |= mask;
+		}
+		pend &= ~mask;
+	}
+	return 0;
+}
+
+int M68VZ328_get_irq_list(char *buf)
+{
+	int i, len = 0;
+	irq_node_t *node;
+
+	len += sprintf(buf+len, "Internal 68VZ328 interrupts\n");
+
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		if (!(node = int_irq_list[i]))
+			continue;
+		if (!(node->handler))
+			continue;
+
+		len += sprintf(buf+len, " %2d: %10u    %s\n", i,
+		               int_irq_count[i], int_irq_list[i]->devname);
+	}
+	return len;
+}
+
+void config_M68VZ328_irq(void)
+{
+	mach_default_handler = NULL;
+	mach_init_IRQ        = M68VZ328_init_IRQ;
+	mach_request_irq     = M68VZ328_request_irq;
+	mach_free_irq        = M68VZ328_free_irq;
+	mach_enable_irq      = M68VZ328_enable_irq;
+	mach_disable_irq     = M68VZ328_disable_irq;
+	mach_get_irq_list    = M68VZ328_get_irq_list;
+	mach_process_int     = M68VZ328_do_irq;
+}
+
+/* PSW dummy call to allow SYSCTL kernel option to be enabled */
+void init_irq_proc(void)
+{
+	/* Insert /proc/irq driver here */
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/rom.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/rom.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/cwvz328/rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/cwvz328/rom.ld	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,11 @@
+MEMORY
+	{
+        romvec : ORIGIN = 0x2000000, LENGTH = 0x0000400
+        flash  : ORIGIN = 0x2000400, LENGTH = 0x0200000 - 0x0000400
+        eflash : ORIGIN = 0x2200000, LENGTH = 0
+        ramvec : ORIGIN = 0x0000000, LENGTH = 0x0000400
+        ram    : ORIGIN = 0x0000400, LENGTH = 0x800000 - 0x0000400
+        eram   : ORIGIN = 0x0800000, LENGTH = 0
+	}
+INCLUDE arch/m68knommu/platform/68VZ328/cwvz328/fixed.ld
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/ccfl.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/ccfl.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/ccfl.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/ccfl.c	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,149 @@
+/*
+ *  linux/arch/m68knommu/platform/MC68VZ328/de2/ccfl.c
+ *
+ *  Copyright (C) 2003 Georges Menie, Kurt Stremerch
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <asm/MC68VZ328.h>
+
+#define SmbSCL 0x10
+#define SmbSDA 0x20
+#define SmbDirReg PKDIR
+#define SmbDataReg PKDATA
+
+#define setbb(d,r) (r) |= (d)
+#define clrbb(d,r) (r) &= ~(d)
+#define readb(r) (r)
+
+static void __init delay(int d)
+{
+	int i;
+
+	for (i = 0; i < d * 20; i++);
+}
+
+static void __init smb_scl_high(void)
+{
+	setbb(SmbSCL, SmbDataReg);
+}
+
+static void __init smb_scl_low(void)
+{
+	clrbb(SmbSCL, SmbDataReg);
+}
+
+static void __init smb_sda_high(void)
+{
+	setbb(SmbSDA, SmbDataReg);
+}
+
+static void __init smb_sda_low(void)
+{
+	clrbb(SmbSDA, SmbDataReg);
+}
+
+static void __init smb_scl_out(void)
+{
+	setbb(SmbSCL, SmbDirReg);
+}
+
+static void __init smb_sda_out(void)
+{
+	setbb(SmbSDA, SmbDirReg);
+}
+
+static void __init smb_sda_in(void)
+{
+	clrbb(SmbSDA, SmbDirReg);
+}
+
+static int __init smb_sda_read(void)
+{
+	return (readb(SmbDataReg) & SmbSDA);
+}
+
+static void __init smb_start(void)
+{
+	smb_scl_out();
+	smb_sda_out();
+	smb_scl_high();
+	smb_sda_high();
+	delay(10);
+	smb_sda_low();
+	delay(3);
+	smb_scl_low();
+	delay(7);
+}
+
+static void __init smb_stop(void)
+{
+	smb_scl_high();
+	delay(3);
+	smb_sda_high();
+	delay(7);
+}
+
+static int __init smb_out(unsigned char byte)
+{
+	int i, ret;
+
+	for (i = 0; i < 8; i++) {
+		if (byte & (1 << (7 - i)))
+			smb_sda_high();
+		else
+			smb_sda_low();
+		smb_scl_high();
+		delay(10);
+		smb_scl_low();
+		delay(10);
+	}
+	smb_sda_in();
+	smb_scl_high();
+	delay(10);
+	ret = smb_sda_read();
+	smb_scl_low();
+	delay(10);
+	smb_sda_out();
+	smb_sda_low();
+
+	return ret;
+}
+
+static int __init smb_write(unsigned char adr, unsigned char reg,
+							unsigned char val)
+{
+	int ret;
+
+	adr &= 0xfe;
+	smb_start();
+	ret = smb_out(adr);
+	if (ret == 0) {
+		ret = smb_out(reg);
+		if (ret == 0) {
+			ret = smb_out(val);
+		}
+	}
+	smb_stop();
+
+	return ret;
+}
+
+int __init SetCCFLCurrent(int percent)
+{
+	unsigned char Address = 0x2C;	/* 7-bit wide */
+	unsigned char Command = 0x7F;	/* byte wide */
+	unsigned char Data;			/* byte wide */
+
+	if (percent <= 0)
+		percent = 0;
+	if (percent > 100)
+		percent = 100;
+	Data = (percent * 100) / 109;
+
+	return smb_write(Address << 1, Command, Data);
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/config.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/config.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/config.c	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,210 @@
+/*
+ *  linux/arch/m68knommu/platform/MC68VZ328/de2/config.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999 D. Jeff Dionne
+ *  Copyright (C) 2001 Georges Menie, Ken Desmet
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/kd.h>
+#include <linux/netdevice.h>
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/MC68VZ328.h>
+
+#ifdef CONFIG_INIT_LCD
+#include "screen.h"
+#endif
+
+/* with a 33.16 MHz clock, this will give usec resolution to the time functions */
+#define CLOCK_SOURCE TCTL_CLKSOURCE_SYSCLK
+#define CLOCK_PRE 7
+#define TICKS_PER_JIFFY 41450
+
+static void __init
+dragen2_sched_init(void (*timer_routine) (int, void *, struct pt_regs *))
+{
+	/* disable timer 1 */
+	TCTL = 0;
+
+	/* set ISR */
+	request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+
+	/* Restart mode, Enable int, Set clock source */
+	TCTL = TCTL_OM | TCTL_IRQEN | CLOCK_SOURCE;
+	TPRER = CLOCK_PRE;
+	TCMP = TICKS_PER_JIFFY;
+
+	/* Enable timer 1 */
+	TCTL |= TCTL_TEN;
+}
+
+static void dragen2_tick(void)
+{
+	/* Reset Timer1 */
+	TSTAT &= 0;
+}
+
+static unsigned long dragen2_gettimeoffset(void)
+{
+	unsigned long ticks = TCN, offset = 0;
+
+	/* check for pending interrupt */
+	if (ticks < (TICKS_PER_JIFFY >> 1) && (ISR & (1 << TMR_IRQ_NUM)))
+		offset = 1000000 / HZ;
+
+	ticks = (ticks * 1000000 / HZ) / TICKS_PER_JIFFY;
+
+	return ticks + offset;
+}
+
+static void dragen2_gettod(int *year, int *mon, int *day, int *hour,
+						   int *min, int *sec)
+{
+	long now = RTCTIME;
+
+	*year = *mon = *day = 1;
+	*hour = (now >> 24) % 24;
+	*min = (now >> 16) % 60;
+	*sec = now % 60;
+}
+
+static void dragen2_reset(void)
+{
+	cli();
+
+#ifdef CONFIG_INIT_LCD
+	PBDATA |= 0x20;				/* disable CCFL light */
+	PKDATA |= 0x4;				/* disable LCD controller */
+	LCKCON = 0;
+#endif
+
+	__asm__ __volatile__(
+		"movel #-1, 0xFFFFF304\n\t"
+		"moveb #0, 0xFFFFF300\n\t"
+		"moveal #0x04000000, %a0\n\t"
+		"moveal 0(%a0), %sp\n\t"
+		"moveal 4(%a0), %a0\n\t"
+		"jmp (%a0)"
+	);
+}
+
+int __init dragen2_cs8900_setup(struct net_device *dev)
+{
+	static int nbdev = 0;
+
+	if (++nbdev == 1) {
+		/* Set the ETH hardware address from its flash monitor location */
+		memcpy(dev->dev_addr, (void *) 0x400fffa, 6);
+		dev->irq = INT1_IRQ_NUM;
+		return dev->base_addr = 0x08000041;
+	}
+	return 1;					/* no more interface */
+}
+
+static void __init init_hardware(void)
+{
+#ifdef CONFIG_INIT_LCD
+	extern int SetCCFLCurrent(int percent);
+#endif
+
+#if CONFIG_DIRECT_IO_ACCESS
+	SCR = 0x10;					/* allow user access to internal registers */
+#endif
+
+	/* CSGB Init */
+	CSGBB = 0x4000;
+	CSB = 0x1a1;
+
+	/* CS8900 init */
+	/* PK3: hardware sleep function pin, active low */
+	PKSEL |= PK(3);				/* select pin as I/O */
+	PKDIR |= PK(3);				/* select pin as output */
+	PKDATA |= PK(3);			/* set pin high */
+
+	/* PF5: hardware reset function pin, active high */
+	PFSEL |= PF(5);				/* select pin as I/O */
+	PFDIR |= PF(5);				/* select pin as output */
+	PFDATA &= ~PF(5);			/* set pin low */
+
+	/* cs8900 hardware reset */
+	PFDATA |= PF(5);
+	{ int i; for (i = 0; i < 32000; ++i); }
+	PFDATA &= ~PF(5);
+
+	/* INT1 enable (cs8900 IRQ) */
+	PDPOL &= ~PD(1);			/* active high signal */
+	PDIQEG &= ~PD(1);
+	PDIRQEN |= PD(1);			/* IRQ enabled */
+
+#ifdef CONFIG_68328_SERIAL_UART2
+	/* Enable RXD TXD port bits to enable UART2 */
+	PJSEL &= ~(PJ(5) | PJ(4));
+#endif
+
+#ifdef CONFIG_INIT_LCD
+	/* initialize LCD controller */
+	LSSA = (long) screen_bits;
+	LVPW = 0x14;
+	LXMAX = 0x140;
+	LYMAX = 0xef;
+	LRRA = 0;
+	LPXCD = 3;
+	LPICF = 0x08;
+	LPOLCF = 0;
+	LCKCON = 0x80;
+	PCPDEN = 0xff;
+	PCSEL = 0;
+
+	/* Enable LCD controller */
+	PKDIR |= 0x4;
+	PKSEL |= 0x4;
+	PKDATA &= ~0x4;
+
+	/* set luminosity to 60% */
+	(void)SetCCFLCurrent(60);
+
+	/* Enable CCFL backlighting circuit */
+	PBDIR |= 0x20;
+	PBSEL |= 0x20;
+	PBDATA &= ~0x20;
+
+	/* contrast control register */
+	PFDIR |= 0x1;
+	PFSEL &= ~0x1;
+	PWMR = 0x037F;
+#endif
+}
+
+void __init config_BSP(char *command, int len)
+{
+	void dragen2_trap_init(void);
+
+	printk("68VZ328 DragonBallVZ support (c) 2001 Lineo, Inc.\n");
+	command[0] = '\0';			/* no specific boot option */
+
+	init_hardware();
+
+	mach_sched_init = dragen2_sched_init;
+	mach_tick = dragen2_tick;
+	mach_gettimeoffset = dragen2_gettimeoffset;
+	mach_reset = dragen2_reset;
+	mach_trap_init = dragen2_trap_init;
+	mach_gettod = dragen2_gettod;
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/crt0_fixed.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/crt0_fixed.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/crt0_fixed.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/crt0_fixed.S	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,168 @@
+#include <linux/config.h>
+
+#if defined(CONFIG_HIMEMKERNEL)
+#if defined(CONFIG_RAM32MB)
+#define	MEM_END	0x01e00000	/* Memory size 30Mb */
+#elif defined(CONFIG_RAM16MB)
+#define	MEM_END	0x00e00000	/* Memory size 14Mb */
+#else
+#define	MEM_END	0x00600000	/* Memory size 6Mb */
+#endif
+#else
+#if defined(CONFIG_RAM32MB)
+#define	MEM_END	0x02000000	/* Memory size 32Mb */
+#elif defined(CONFIG_RAM16MB)
+#define	MEM_END	0x01000000	/* Memory size 16Mb */
+#else
+#define	MEM_END	0x00800000	/* Memory size 8Mb */
+#endif
+#endif
+
+#undef CRT_DEBUG
+
+.macro	PUTC CHAR
+#ifdef CRT_DEBUG
+	moveq	#\CHAR, %d7
+	jsr	putc
+#endif
+.endm
+
+	.global	_start
+	.global _rambase
+	.global _ramvec
+	.global	_ramstart
+	.global	_ramend
+
+	.data
+
+/*
+ *	Set up the usable of RAM stuff
+ */
+_rambase:
+	.long	0
+_ramvec:
+	.long	0
+_ramstart:
+	.long	0
+_ramend:
+	.long	0
+
+	.text
+
+_start:
+
+/*
+ * Setup registers, initial stack
+ */
+	movew	#0x2700, %sr
+	movel	#0xffffffff, 0xfffff304	/* disable all interrupts */
+	movel	#MEM_END-4, %sp
+
+	PUTC	'\r'
+	PUTC	'\n'
+	PUTC	'A'
+
+#ifndef CONFIG_RAMKERNEL
+/*
+ * Copy data segment from ROM to RAM
+ */
+	lea	_etext, %a0
+	lea	_sdata, %a1
+	lea	_edata, %a2
+
+1:	cmpal  %a1, %a2
+	beq	2f
+	movel	(%a0)+, (%a1)+
+	bra	1b
+2:
+
+/*
+ * Set start of ram
+ */
+	lea	_ebss, %a1
+	movel	%a1, _ramstart
+
+	PUTC	'B'
+
+#endif
+
+/*
+ *	Determine end of RAM
+ */
+	movel	#MEM_END, %a0
+	movel	%a0, _ramend
+
+	PUTC	'C'
+
+#ifdef CONFIG_RAMKERNEL
+/*
+ *	Move ROM filesystem above bss :-)
+ */
+	moveal	#_sbss, %a0			/* romfs at the start of bss */
+	moveal	#_ebss, %a1			/* Set up destination  */
+	movel	%a0, %a2			/* Copy of bss start */
+
+	movel	8(%a0), %d1			/* Get size of ROMFS */
+	addql	#8, %d1				/* Allow for rounding */
+	andl	#0xfffffffc, %d1	/* Whole words */
+
+	addl	%d1, %a0			/* Copy from end */
+	addl	%d1, %a1			/* Copy from end */
+	movel	%a1, _ramstart		/* Set start of ram */
+
+1:
+	movel	-(%a0), %d0			/* Copy dword */
+	movel	%d0, -(%a1)
+	cmpl	%a0, %a2			/* Check if at end */
+	bne	1b
+
+	PUTC	'D'
+
+#endif
+
+/*
+ * Initialize BSS segment to 0
+ */
+	lea	_sbss, %a0
+	lea	_ebss, %a1
+
+	/* Copy 0 to %a0 until %a0 == %a1 */
+2:	cmpal	%a0, %a1
+	beq	1f
+	clrl	(%a0)+
+	bra	2b
+1:
+
+	PUTC	'E'
+
+/*
+ * Load the current task pointer and stack
+ */
+
+	lea	init_task_union, %a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0), %sp
+
+	PUTC	'F'
+	PUTC	'\r'
+	PUTC	'\n'
+
+/*
+ * Go
+ */
+
+	jmp	start_kernel
+
+/*
+ * Local functions
+ */
+ 
+#ifdef CRT_DEBUG
+putc:
+	moveb	%d7, 0xfffff907
+1:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	1b
+	rts
+#endif
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/crt0_himem.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/crt0_himem.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/crt0_himem.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/crt0_himem.S	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/crt0_ram.S	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/crt0_rom.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/crt0_rom.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/crt0_rom.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/crt0_rom.S	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/entry.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/entry.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/entry.S	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,707 @@
+/* -*- mode: asm -*-
+ *
+ *  linux/arch/m68knommu/platorm/68VZ328/de2/entry.S
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ * Linux/m68k support by Hamish Macdonald
+ * DragonEngine board support by Georges Menie
+ *
+ */
+
+/*
+ * entry.S  contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all interrupts
+ * and faults that can result in a task-switch.
+ *
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ *
+ */
+
+/*
+ * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so
+ *               all pointers that used to be 'current' are now entry
+ *               number 0 in the 'current_set' list.
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/errno.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/traps.h>
+
+#include "m68k_defs.h"
+
+#define IMMED #
+#define DBG_PUTC(x) moveb IMMED x,0xfffff907; \
+					moveb IMMED '\r',0xfffff907; \
+					moveb IMMED '\n',0xfffff907
+
+.globl SYMBOL_NAME(system_call), SYMBOL_NAME(buserr), SYMBOL_NAME(trap)
+.globl SYMBOL_NAME(exception3), SYMBOL_NAME(exception4), SYMBOL_NAME(exception5)
+.globl SYMBOL_NAME(exception6), SYMBOL_NAME(exception7), SYMBOL_NAME(exception8)
+.globl SYMBOL_NAME(exception9), SYMBOL_NAME(exception10), SYMBOL_NAME(exception12)
+.globl SYMBOL_NAME(exception14), SYMBOL_NAME(exception15)
+.globl SYMBOL_NAME(trap1), SYMBOL_NAME(trap15)
+.globl SYMBOL_NAME(resume), SYMBOL_NAME(ret_from_exception)
+.globl SYMBOL_NAME(ret_from_signal)
+.globl SYMBOL_NAME(sys_call_table)
+.globl SYMBOL_NAME(sys_fork), SYMBOL_NAME(sys_clone), SYMBOL_NAME(sys_vfork)
+.globl SYMBOL_NAME(ret_from_interrupt), SYMBOL_NAME(bad_interrupt)
+.globl SYMBOL_NAME(inthandler1), SYMBOL_NAME(inthandler2),SYMBOL_NAME(inthandler3)
+.globl SYMBOL_NAME(inthandler4),SYMBOL_NAME(inthandler5),SYMBOL_NAME(inthandler6)
+.globl SYMBOL_NAME(inthandler7)
+
+.text
+ENTRY(buserr)
+	SAVE_ALL_INT 8
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(buserr_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception3)
+	SAVE_ALL_INT 12
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception4)
+	SAVE_ALL_INT 16
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception5)
+	SAVE_ALL_INT 20
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception6)
+	SAVE_ALL_INT 24
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception7)
+	SAVE_ALL_INT 28
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception8)
+	SAVE_ALL_INT 32
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception9)
+	SAVE_ALL_INT 36
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception10)
+	SAVE_ALL_INT 40
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception11)
+	SAVE_ALL_INT 44
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception14)
+	SAVE_ALL_INT 56
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(exception15)
+	SAVE_ALL_INT 60
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(trap1)
+	SAVE_ALL_INT 132
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(trap15)
+	SAVE_ALL_INT 188
+	GET_CURRENT(%d0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument*/
+	bsrw	SYMBOL_NAME(trap_c)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(reschedule)
+	/* save top of frame*/
+	movel   SYMBOL_NAME(_current_task),%a2
+	movel	%sp,%a2@(TASK_THREAD+THREAD_ESP0)
+
+	pea	SYMBOL_NAME(ret_from_exception)
+	jmp	SYMBOL_NAME(schedule)
+
+	/* After a fork we jump here directly from resume,*/
+	/* so that %d1 contains the previous task*/
+	/* Theoretically only needed on SMP, but let's watch*/
+	/* what happens in schedule_tail() in future...*/
+ENTRY(ret_from_fork)
+	movel	%d1,%sp@-
+	jsr	SYMBOL_NAME(schedule_tail)
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+badsys:
+	movel	#-ENOSYS,%sp@(PT_D0)
+	jra	SYMBOL_NAME(ret_from_exception)
+
+do_trace:
+	movel	#-ENOSYS,%sp@(PT_D0)	/* needed for strace*/
+	subql	#4,%sp
+	SAVE_SWITCH_STACK
+	jbsr	SYMBOL_NAME(syscall_trace)
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+	movel	%sp@(PT_ORIG_D0),%d1
+	movel	#-ENOSYS,%d0
+	cmpl	#NR_syscalls,%d1
+	jcc	1f
+	lsl	#2,%d1
+	lea	SYMBOL_NAME(sys_call_table), %a0
+	jbsr	%a0@(%d1)
+
+1:	movel	%d0,%sp@(PT_D0)		/* save the return value*/
+	subql	#4,%sp			/* dummy return address*/
+	SAVE_SWITCH_STACK
+	jbsr	SYMBOL_NAME(syscall_trace)
+
+SYMBOL_NAME_LABEL(ret_from_signal)
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+	jra	SYMBOL_NAME(ret_from_exception)
+
+ENTRY(system_call)
+	SAVE_ALL_SYS 128
+
+	GET_CURRENT(%d1)
+	/* save top of frame*/
+	movel   SYMBOL_NAME(_current_task),%a2
+	movel	%sp,%a2@(TASK_THREAD+THREAD_ESP0)
+
+	btst	#PF_TRACESYS_BIT,%a2@(TASK_FLAGS+PF_TRACESYS_OFF)
+	jne	do_trace
+	cmpl	#NR_syscalls,%d0
+	jcc	badsys
+	lsl	#2,%d0
+	lea	SYMBOL_NAME(sys_call_table),%a0
+	movel	%a0@(%d0), %a0
+	jbsr	%a0@
+	movel	%d0,%sp@(PT_D0)		/* save the return value*/
+
+SYMBOL_NAME_LABEL(ret_from_exception)
+	btst	#5,%sp@(PT_SR)		/* check if returning to kernel*/
+	bnes	2f			/* if so, skip resched, signals*/
+	/* only allow interrupts when we are really the last one on the*/
+	/* kernel stack, otherwise stack overflow can occur during*/
+	/* heavy interupt load*/
+	andw	#ALLOWINT,%sr
+	movel   SYMBOL_NAME(_current_task),%a2
+	tstl	%a2@(TASK_NEEDRESCHED)
+	jne	SYMBOL_NAME(reschedule)
+					/* check for delayed trace*/
+	bclr	#PF_DTRACE_BIT,%a2@(TASK_FLAGS+PF_DTRACE_OFF)
+	jne	do_delayed_trace
+5:
+	tstl	%a2@(TASK_STATE)	/* state*/
+	jne	SYMBOL_NAME(reschedule)
+
+	tstl	%a2@(TASK_SIGPENDING)
+	jne	Lsignal_return
+2:	RESTORE_ALL
+
+Lsignal_return:
+	subql	#4,%sp			/* dummy return address*/
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	clrl	%sp@-
+	bsrw	SYMBOL_NAME(do_signal)
+	addql	#8,%sp
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+	RESTORE_ALL
+
+do_delayed_trace:
+	bclr	#7,%sp@(PT_SR)		/* clear trace bit in SR*/
+	pea	1			/* send SIGTRAP*/
+	movel	%a2,%sp@-
+	pea	LSIGTRAP
+	jbsr	SYMBOL_NAME(send_sig)
+	addql	#8,%sp
+	addql	#4,%sp
+	jra	5b
+
+SYMBOL_NAME_LABEL(inthandler1)
+	SAVE_ALL_INT 260
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	movel	%sp,%sp@-
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+     	addql	#4,%sp			/*  pop parameters off stack*/
+	bra	SYMBOL_NAME(ret_from_interrupt)
+
+SYMBOL_NAME_LABEL(inthandler2)
+	SAVE_ALL_INT 264
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	movel	%sp,%sp@-
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+     	addql	#4,%sp			/*  pop parameters off stack*/
+	bra	SYMBOL_NAME(ret_from_interrupt)
+
+SYMBOL_NAME_LABEL(inthandler3)
+	SAVE_ALL_INT 268
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	movel	%sp,%sp@-
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+     	addql	#4,%sp			/*  pop parameters off stack*/
+	bra	SYMBOL_NAME(ret_from_interrupt)
+
+SYMBOL_NAME_LABEL(inthandler4)
+	SAVE_ALL_INT 272
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	movel	%sp,%sp@-
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+     	addql	#4,%sp			/*  pop parameters off stack*/
+	bra	SYMBOL_NAME(ret_from_interrupt)
+
+SYMBOL_NAME_LABEL(inthandler5)
+	SAVE_ALL_INT 276
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	movel	%sp,%sp@-
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+     	addql	#4,%sp			/*  pop parameters off stack*/
+	bra	SYMBOL_NAME(ret_from_interrupt)
+
+SYMBOL_NAME_LABEL(inthandler6)
+	SAVE_ALL_INT 280
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	movel	%sp,%sp@-
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+     	addql	#4,%sp			/*  pop parameters off stack*/
+/*	bra	SYMBOL_NAME(ret_from_interrupt)  fall through */
+
+SYMBOL_NAME_LABEL(ret_from_interrupt)
+	subql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	jeq	1f
+2:
+	RESTORE_ALL
+1:
+	moveb	%sp@(PT_SR), %d0	/* Check for nested interrupt.*/
+	and	#7, %d0
+
+#if MAX_NOINT_IPL > 0
+	cmpiw	#MAX_NOINT_IPL,%d0
+#endif
+	jhi	2b
+	/* check if we need to do software interrupts */
+
+	movel	SYMBOL_NAME(irq_stat)+CPUSTAT_SOFTIRQ_PENDING,%d0
+	jeq	SYMBOL_NAME(ret_from_exception)
+
+	pea	SYMBOL_NAME(ret_from_exception)
+	jra	SYMBOL_NAME(do_softirq)
+
+SYMBOL_NAME_LABEL(inthandler7)
+	SAVE_ALL_INT 284
+	GET_CURRENT(%d0)
+	addql	#1,SYMBOL_NAME(irq_stat)+CPUSTAT_LOCAL_IRQ_COUNT
+	movel	%sp,%sp@-
+	jbsr	SYMBOL_NAME(process_int)/*  process the IRQ*/
+     	addql	#4,%sp			/*  pop parameters off stack*/
+	bra	SYMBOL_NAME(ret_from_interrupt)
+
+/* Handler for uninitialized and spurious interrupts */
+
+SYMBOL_NAME_LABEL(trap)
+SYMBOL_NAME_LABEL(bad_interrupt)
+	addql	#1,SYMBOL_NAME(num_spurious)
+	rte
+
+ENTRY(sys_fork)
+	SAVE_SWITCH_STACK	
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(m68k_fork)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_clone)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(m68k_clone)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_vfork)
+	SAVE_SWITCH_STACK	
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(m68k_vfork)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(do_sigsuspend)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	SYMBOL_NAME(do_rt_sigsuspend)
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_sigreturn)
+	SAVE_SWITCH_STACK
+	jbsr	SYMBOL_NAME(do_sigreturn)
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigreturn)
+	SAVE_SWITCH_STACK
+	jbsr	SYMBOL_NAME(do_rt_sigreturn)
+	RESTORE_SWITCH_STACK
+	rts
+
+SYMBOL_NAME_LABEL(resume)
+	/*
+	 * Beware - when entering resume, prev (the current task) is
+	 * in a0, next (the new task) is in a1,so don't change these
+	 * registers until their contents are no longer needed.
+	 */
+
+	/* save sr */
+	movew	%sr,%a0@(TASK_THREAD+THREAD_SR)
+#ifdef USE_SFC_DFC
+	/* save fs (sfc,%dfc) (may be pointing to kernel memory) */
+	movec	%sfc,%d0
+	movew	%d0,%a0@(TASK_THREAD+THREAD_FS)
+#endif
+
+	/* save non-scratch registers on stack */
+	SAVE_SWITCH_STACK
+
+	/* save usp */
+	/* it is better to use a movel here instead of a movew 8*) */
+	movel	%usp,%a2
+	movel	%a2,%a0@(TASK_THREAD+THREAD_USP)
+
+	/* save current kernel stack pointer */
+	movel	%sp,%a0@(TASK_THREAD+THREAD_KSP)
+
+	/* Return previous task in %d1 */
+	movel   SYMBOL_NAME(_current_task),%d1
+
+	/* switch to new task (a1 contains new task) */
+	movel   %a1, SYMBOL_NAME(_current_task)
+
+	/* restore the kernel stack pointer */
+	movel	%a1@(TASK_THREAD+THREAD_KSP),%sp
+
+	/* restore non-scratch registers */
+	RESTORE_SWITCH_STACK
+
+	/* restore user stack pointer */
+	movel	%a1@(TASK_THREAD+THREAD_USP),%a0
+	movel	%a0,%usp
+
+#ifdef USE_SFC_DFC
+	/* restore fs (sfc,%dfc) */
+	movew	%a1@(TASK_THREAD+THREAD_FS),%a0
+	movec	%a0,%sfc
+	movec	%a0,%dfc
+#endif
+	/* restore status register */
+	movew	%a1@(TASK_THREAD+THREAD_SR),%sr
+
+	rts
+
+
+.data
+ALIGN
+SYMBOL_NAME_LABEL(sys_call_table)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 0  -  old "setup()" system call*/
+	.long SYMBOL_NAME(sys_exit)
+	.long SYMBOL_NAME(sys_fork)
+	.long SYMBOL_NAME(sys_read)
+	.long SYMBOL_NAME(sys_write)
+	.long SYMBOL_NAME(sys_open)		/* 5 */
+	.long SYMBOL_NAME(sys_close)
+	.long SYMBOL_NAME(sys_waitpid)
+	.long SYMBOL_NAME(sys_creat)
+	.long SYMBOL_NAME(sys_link)
+	.long SYMBOL_NAME(sys_unlink)		/* 10 */
+	.long SYMBOL_NAME(sys_execve)
+	.long SYMBOL_NAME(sys_chdir)
+	.long SYMBOL_NAME(sys_time)
+	.long SYMBOL_NAME(sys_mknod)
+	.long SYMBOL_NAME(sys_chmod)		/* 15 */
+	.long SYMBOL_NAME(sys_chown16)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old break syscall holder */
+	.long SYMBOL_NAME(sys_stat)
+	.long SYMBOL_NAME(sys_lseek)
+	.long SYMBOL_NAME(sys_getpid)		/* 20 */
+	.long SYMBOL_NAME(sys_mount)
+	.long SYMBOL_NAME(sys_oldumount)
+	.long SYMBOL_NAME(sys_setuid16)
+	.long SYMBOL_NAME(sys_getuid16)
+	.long SYMBOL_NAME(sys_stime)		/* 25 */
+	.long SYMBOL_NAME(sys_ptrace)
+	.long SYMBOL_NAME(sys_alarm)
+	.long SYMBOL_NAME(sys_fstat)
+	.long SYMBOL_NAME(sys_pause)
+	.long SYMBOL_NAME(sys_utime)		/* 30 */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old stty syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old gtty syscall holder */
+	.long SYMBOL_NAME(sys_access)
+	.long SYMBOL_NAME(sys_nice)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 35 */		/* old ftime syscall holder */
+	.long SYMBOL_NAME(sys_sync)
+	.long SYMBOL_NAME(sys_kill)
+	.long SYMBOL_NAME(sys_rename)
+	.long SYMBOL_NAME(sys_mkdir)
+	.long SYMBOL_NAME(sys_rmdir)		/* 40 */
+	.long SYMBOL_NAME(sys_dup)
+	.long SYMBOL_NAME(sys_pipe)
+	.long SYMBOL_NAME(sys_times)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old prof syscall holder */
+	.long SYMBOL_NAME(sys_brk)		/* 45 */
+	.long SYMBOL_NAME(sys_setgid16)
+	.long SYMBOL_NAME(sys_getgid16)
+	.long SYMBOL_NAME(sys_signal)
+	.long SYMBOL_NAME(sys_geteuid16)
+	.long SYMBOL_NAME(sys_getegid16)	/* 50 */
+	.long SYMBOL_NAME(sys_acct)
+	.long SYMBOL_NAME(sys_umount)					/* recycled never used phys() */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old lock syscall holder */
+	.long SYMBOL_NAME(sys_ioctl)
+	.long SYMBOL_NAME(sys_fcntl)		/* 55 */
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old mpx syscall holder */
+	.long SYMBOL_NAME(sys_setpgid)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old ulimit syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_umask)		/* 60 */
+	.long SYMBOL_NAME(sys_chroot)
+	.long SYMBOL_NAME(sys_ustat)
+	.long SYMBOL_NAME(sys_dup2)
+	.long SYMBOL_NAME(sys_getppid)
+	.long SYMBOL_NAME(sys_getpgrp)		/* 65 */
+	.long SYMBOL_NAME(sys_setsid)
+	.long SYMBOL_NAME(sys_sigaction)
+	.long SYMBOL_NAME(sys_sgetmask)
+	.long SYMBOL_NAME(sys_ssetmask)
+	.long SYMBOL_NAME(sys_setreuid16)	/* 70 */
+	.long SYMBOL_NAME(sys_setregid16)
+	.long SYMBOL_NAME(sys_sigsuspend)
+	.long SYMBOL_NAME(sys_sigpending)
+	.long SYMBOL_NAME(sys_sethostname)
+	.long SYMBOL_NAME(sys_setrlimit)	/* 75 */
+	.long SYMBOL_NAME(sys_old_getrlimit)
+	.long SYMBOL_NAME(sys_getrusage)
+	.long SYMBOL_NAME(sys_gettimeofday)
+	.long SYMBOL_NAME(sys_settimeofday)
+	.long SYMBOL_NAME(sys_getgroups16)	/* 80 */
+	.long SYMBOL_NAME(sys_setgroups16)
+	.long SYMBOL_NAME(old_select)
+	.long SYMBOL_NAME(sys_symlink)
+	.long SYMBOL_NAME(sys_lstat)
+	.long SYMBOL_NAME(sys_readlink)		/* 85 */
+	.long SYMBOL_NAME(sys_uselib)
+	.long SYMBOL_NAME(sys_swapon)
+	.long SYMBOL_NAME(sys_reboot)
+	.long SYMBOL_NAME(old_readdir)
+	.long SYMBOL_NAME(old_mmap)		/* 90 */
+	.long SYMBOL_NAME(sys_munmap)
+	.long SYMBOL_NAME(sys_truncate)
+	.long SYMBOL_NAME(sys_ftruncate)
+	.long SYMBOL_NAME(sys_fchmod)
+	.long SYMBOL_NAME(sys_fchown16)		/* 95 */
+	.long SYMBOL_NAME(sys_getpriority)
+	.long SYMBOL_NAME(sys_setpriority)
+	.long SYMBOL_NAME(sys_ni_syscall)				/* old profil syscall holder */
+	.long SYMBOL_NAME(sys_statfs)
+	.long SYMBOL_NAME(sys_fstatfs)		/* 100 */
+	.long SYMBOL_NAME(sys_ioperm)
+	.long SYMBOL_NAME(sys_socketcall)
+	.long SYMBOL_NAME(sys_syslog)
+	.long SYMBOL_NAME(sys_setitimer)
+	.long SYMBOL_NAME(sys_getitimer)	/* 105 */
+	.long SYMBOL_NAME(sys_newstat)
+	.long SYMBOL_NAME(sys_newlstat)
+	.long SYMBOL_NAME(sys_newfstat)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* iopl for i386 */ /* 110 */
+	.long SYMBOL_NAME(sys_vhangup)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* obsolete idle() syscall */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* vm86old for i386 */
+	.long SYMBOL_NAME(sys_wait4)
+	.long SYMBOL_NAME(sys_swapoff)		/* 115 */
+	.long SYMBOL_NAME(sys_sysinfo)
+	.long SYMBOL_NAME(sys_ipc)
+	.long SYMBOL_NAME(sys_fsync)
+	.long SYMBOL_NAME(sys_sigreturn)
+	.long SYMBOL_NAME(sys_clone)		/* 120 */
+	.long SYMBOL_NAME(sys_setdomainname)
+	.long SYMBOL_NAME(sys_newuname)
+	.long SYMBOL_NAME(sys_cacheflush)	/* modify_ldt for i386 */
+	.long SYMBOL_NAME(sys_adjtimex)
+	.long SYMBOL_NAME(sys_mprotect)		/* 125 */
+	.long SYMBOL_NAME(sys_sigprocmask)
+	.long SYMBOL_NAME(sys_create_module)
+	.long SYMBOL_NAME(sys_init_module)
+	.long SYMBOL_NAME(sys_delete_module)
+	.long SYMBOL_NAME(sys_get_kernel_syms)	/* 130 */
+	.long SYMBOL_NAME(sys_quotactl)
+	.long SYMBOL_NAME(sys_getpgid)
+	.long SYMBOL_NAME(sys_fchdir)
+	.long SYMBOL_NAME(sys_bdflush)
+	.long SYMBOL_NAME(sys_sysfs)		/* 135 */
+	.long SYMBOL_NAME(sys_personality)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for afs_syscall */
+	.long SYMBOL_NAME(sys_setfsuid16)
+	.long SYMBOL_NAME(sys_setfsgid16)
+	.long SYMBOL_NAME(sys_llseek)		/* 140 */
+	.long SYMBOL_NAME(sys_getdents)
+	.long SYMBOL_NAME(sys_select)
+	.long SYMBOL_NAME(sys_flock)
+	.long SYMBOL_NAME(sys_msync)
+	.long SYMBOL_NAME(sys_readv)		/* 145 */
+	.long SYMBOL_NAME(sys_writev)
+	.long SYMBOL_NAME(sys_getsid)
+	.long SYMBOL_NAME(sys_fdatasync)
+	.long SYMBOL_NAME(sys_sysctl)
+	.long SYMBOL_NAME(sys_mlock)		/* 150 */
+	.long SYMBOL_NAME(sys_munlock)
+	.long SYMBOL_NAME(sys_mlockall)
+	.long SYMBOL_NAME(sys_munlockall)
+	.long SYMBOL_NAME(sys_sched_setparam)
+	.long SYMBOL_NAME(sys_sched_getparam)   /* 155 */
+	.long SYMBOL_NAME(sys_sched_setscheduler)
+	.long SYMBOL_NAME(sys_sched_getscheduler)
+	.long SYMBOL_NAME(sys_sched_yield)
+	.long SYMBOL_NAME(sys_sched_get_priority_max)
+	.long SYMBOL_NAME(sys_sched_get_priority_min)  /* 160 */
+	.long SYMBOL_NAME(sys_sched_rr_get_interval)
+	.long SYMBOL_NAME(sys_nanosleep)
+	.long SYMBOL_NAME(sys_mremap)
+	.long SYMBOL_NAME(sys_setresuid16)
+	.long SYMBOL_NAME(sys_getresuid16)	/* 165 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* for vm86 */
+	.long SYMBOL_NAME(sys_query_module)
+	.long SYMBOL_NAME(sys_poll)
+	.long SYMBOL_NAME(sys_nfsservctl)
+	.long SYMBOL_NAME(sys_setresgid16)	/* 170 */
+	.long SYMBOL_NAME(sys_getresgid16)
+	.long SYMBOL_NAME(sys_prctl)
+	.long SYMBOL_NAME(sys_rt_sigreturn)
+	.long SYMBOL_NAME(sys_rt_sigaction)
+	.long SYMBOL_NAME(sys_rt_sigprocmask)	/* 175 */
+	.long SYMBOL_NAME(sys_rt_sigpending)
+	.long SYMBOL_NAME(sys_rt_sigtimedwait)
+	.long SYMBOL_NAME(sys_rt_sigqueueinfo)
+	.long SYMBOL_NAME(sys_rt_sigsuspend)
+	.long SYMBOL_NAME(sys_pread)		/* 180 */
+	.long SYMBOL_NAME(sys_pwrite)
+	.long SYMBOL_NAME(sys_lchown16);
+	.long SYMBOL_NAME(sys_getcwd)
+	.long SYMBOL_NAME(sys_capget)
+	.long SYMBOL_NAME(sys_capset)           /* 185 */
+	.long SYMBOL_NAME(sys_sigaltstack)
+	.long SYMBOL_NAME(sys_sendfile)
+	.long SYMBOL_NAME(sys_ni_syscall)		/* streams1 */
+	.long SYMBOL_NAME(sys_ni_syscall)		/* streams2 */
+	.long SYMBOL_NAME(sys_vfork)            /* 190 */
+	.long SYMBOL_NAME(sys_getrlimit)
+	.long SYMBOL_NAME(sys_mmap2)
+	.long SYMBOL_NAME(sys_truncate64)
+	.long SYMBOL_NAME(sys_ftruncate64)
+	.long SYMBOL_NAME(sys_stat64)		/* 195 */
+	.long SYMBOL_NAME(sys_lstat64)
+	.long SYMBOL_NAME(sys_fstat64)
+	.long SYMBOL_NAME(sys_chown)
+	.long SYMBOL_NAME(sys_getuid)
+	.long SYMBOL_NAME(sys_getgid)		/* 200 */
+	.long SYMBOL_NAME(sys_geteuid)
+	.long SYMBOL_NAME(sys_getegid)
+	.long SYMBOL_NAME(sys_setreuid)
+	.long SYMBOL_NAME(sys_setregid)
+	.long SYMBOL_NAME(sys_getgroups)	/* 205 */
+	.long SYMBOL_NAME(sys_setgroups)
+	.long SYMBOL_NAME(sys_fchown)
+	.long SYMBOL_NAME(sys_setresuid)
+	.long SYMBOL_NAME(sys_getresuid)
+	.long SYMBOL_NAME(sys_setresgid)	/* 210 */
+	.long SYMBOL_NAME(sys_getresgid)
+	.long SYMBOL_NAME(sys_lchown)
+	.long SYMBOL_NAME(sys_setuid)
+	.long SYMBOL_NAME(sys_setgid)
+	.long SYMBOL_NAME(sys_setfsuid)		/* 215 */
+	.long SYMBOL_NAME(sys_setfsgid)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
+
+	.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
+		.long SYMBOL_NAME(sys_ni_syscall)
+	.endr
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/fixed.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/fixed.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/fixed.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/fixed.ld	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,58 @@
+SECTIONS {
+
+	.text : {
+		. = ALIGN(4) ;
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+			*(.rodata.str1.1)
+		. = ALIGN(4) ;
+			*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+			*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+			*(.text.init)
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		. = ALIGN(4) ;
+		__initcall_end = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+		__data_rom_start = . ; /* only needed for CONFIG_BLK_DEV_BLKMEM */
+	} > rom
+
+	.data : AT(_etext) {
+		. = ALIGN(4) ;
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.bss : {
+		. = ALIGN(4) ;
+		_sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+	} > ram
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/himem.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/himem.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/himem.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/himem.ld	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+  for a 32MB SDRAM:
+
+	rom : ORIGIN = 0x01e00000, LENGTH = 2M
+
+  for a 16MB SDRAM:
+
+	rom : ORIGIN = 0x00e00000, LENGTH = 2M
+
+  for a 8MB SDRAM:
+
+	rom : ORIGIN = 0x00600000, LENGTH = 2M
+
+  RAM size should now be set using the config options
+  the size here should stay to the maximum possible for
+  any DragonEngine board minus the HIMEM reserved space
+*/
+
+MEMORY {
+	rom : ORIGIN = 0x00600000, LENGTH = 2M
+	ram : ORIGIN = 0x00010000, LENGTH = 6M - 64k
+}
+
+INCLUDE arch/m68knommu/platform/68VZ328/de2/fixed.ld
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/ints.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/ints.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/ints.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/ints.c	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,201 @@
+/*
+ * linux/arch/m68knommu/platform/MC68VZ328/de2/ints.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne <jeff@uClinux.org>
+ * Copyright 2002 Georges Menie
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+#include <asm/MC68VZ328.h>
+
+#include "traps_proto.h"
+
+/* irq node variables for the 32 (potential) on chip sources */
+#define INTERNAL_IRQS 32
+static irq_node_t int_irq_list[INTERNAL_IRQS];
+static int int_irq_count[INTERNAL_IRQS];
+
+/* The number of spurious interrupts */
+volatile unsigned int num_spurious;
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the IRQ handling routines.
+ */
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		int_irq_list[i].handler = NULL;
+		int_irq_count[i] = 0;
+	}
+
+	/* turn off all interrupts */
+	IMR = ~0;
+}
+
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+	if (!(int_irq_list[irq].flags & IRQ_FLG_STD)) {
+		if (int_irq_list[irq].flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, int_irq_list[irq].devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, int_irq_list[irq].devname);
+			return -EBUSY;
+		}
+	}
+
+	int_irq_list[irq].handler = handler;
+	int_irq_list[irq].flags   = flags;
+	int_irq_list[irq].dev_id  = dev_id;
+	int_irq_list[irq].devname = devname;
+
+	IMR &= ~(1<<irq);
+
+	return 0;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_list[irq].dev_id != dev_id)
+		printk("%s: removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, int_irq_list[irq].devname);
+
+	int_irq_list[irq].handler = (void (*)(int, void *, struct pt_regs *))bad_interrupt;
+	int_irq_list[irq].flags   = IRQ_FLG_STD;
+	int_irq_list[irq].dev_id  = NULL;
+	int_irq_list[irq].devname = NULL;
+
+	IMR |= 1<<irq;
+}
+
+int get_irq_list(char *buf)
+{
+	int i, len = 0;
+
+	len += sprintf(buf+len, "IRQ       count    dev\n");
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		if (int_irq_list[i].handler) {
+			len += sprintf(buf+len, " %2d: %10u    %s\n", i,
+		               int_irq_count[i], int_irq_list[i].devname);
+		}
+	}
+	len += sprintf(buf+len, "     %10u    spurious\n", num_spurious);
+	return len;
+}
+
+unsigned long probe_irq_on (void)
+{
+	return 0;
+}
+
+int probe_irq_off (unsigned long irqs)
+{
+	return 0;
+}
+
+/* This code is designed to be fast, almost constant time, not clean!
+ */
+asmlinkage void process_int(struct frame *fp)
+{
+	register int irq;
+	register int mask;
+	register unsigned long pend = ISR;
+
+	while (pend) {
+		if (pend & (1<<TMR_IRQ_NUM)) {
+			mask = 1<<TMR_IRQ_NUM;
+			irq = TMR_IRQ_NUM;
+		}
+		else {
+			if (pend & 0x0000ffff) {
+				if (pend & 0x000000ff) {
+					if (pend & 0x0000000f) {
+						mask = 0x00000001;
+						irq = 0;
+					} else {
+						mask = 0x00000010;
+						irq = 4;
+					}
+				} else {
+					if (pend & 0x00000f00) {
+						mask = 0x00000100;
+						irq = 8;
+					} else {
+						mask = 0x00001000;
+						irq = 12;
+					}
+				}
+			} else {
+				if (pend & 0x00ff0000) {
+					if (pend & 0x000f0000) {
+						mask = 0x00010000;
+						irq = 16;
+					} else {
+						mask = 0x00100000;
+						irq = 20;
+					}
+				} else {
+					if (pend & 0x0f000000) {
+						mask = 0x01000000;
+						irq = 24;
+					} else {
+						mask = 0x10000000;
+						irq = 28;
+					}
+				}
+			}
+
+			while (! (mask & pend)) {
+				mask <<= 1;
+				irq++;
+			}
+		}
+#if NR_IRQS >= INTERNAL_IRQS
+		++kstat.irqs[0][irq];
+#endif
+		if (int_irq_list[irq].handler) {
+			int_irq_list[irq].handler(irq, int_irq_list[irq].dev_id, &fp->ptregs);
+			int_irq_count[irq]++;
+		} else {
+			++num_spurious;
+			printk("unregistered interrupt %d!\nTurning it off in the IMR...\n", irq);
+			IMR |= mask;
+		}
+		pend &= ~mask;
+	}
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/ram.ld	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,69 @@
+/*
+  RAM size should now be set using the config options
+  the size here should stay to the maximum possible for
+  any DragonEngine board
+*/
+
+MEMORY {
+	ram : ORIGIN = 0x00010000, LENGTH = 8M - 64k
+}
+
+SECTIONS {
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+			*(.rodata.str1.1)
+		. = ALIGN(0x4) ;
+			*(.kstrtab)
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+			*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+			*(__ksymtab)
+		__stop___ksymtab = .;
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > ram
+
+	.data BLOCK(0x4) : {
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN(0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN(0x2000) ;
+		_edata = . ;
+	} > ram
+
+	.init BLOCK(4096) : {
+		__init_begin = .;
+			*(.text.init)
+			*(.data.init)
+		. = ALIGN(16);
+		__setup_start = .;
+			*(.setup.init)
+		__setup_end = .;
+		__initcall_start = .;
+			*(.initcall.init)
+		. = ALIGN(4) ;
+		__initcall_end = .;
+		__init_end = .;
+	} > ram
+
+	.bss BLOCK(0x4) : {
+		_sbss = . ;
+			*(.bss)
+			*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+		_end = . ;
+	} > ram
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/rom.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/rom.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/rom.ld	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,11 @@
+/*
+  RAM size should now be set using the config options
+  the size here should stay to the maximum possible for
+  any DragonEngine board
+*/
+
+MEMORY {
+	rom : ORIGIN = 0x04030000, LENGTH = 2M - 196k
+	ram : ORIGIN = 0x00010000, LENGTH = 8M - 64k
+}
+INCLUDE arch/m68knommu/platform/68VZ328/de2/fixed.ld
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/screen.xbm linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/screen.xbm
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/screen.xbm	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/screen.xbm	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,804 @@
+/* Created with The GIMP */
+#define screen_width 320
+#define screen_height 240
+static unsigned char screen_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00,
+   0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x31, 0x03, 0x00, 0x00,
+   0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x3e, 0x00, 0x0c, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+   0x32, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01,
+   0x61, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00,
+   0x00, 0x00, 0x80, 0x01, 0x60, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x06, 0x30, 0xb3, 0x63, 0xcc,
+   0x21, 0x60, 0x04, 0x8f, 0x6d, 0x07, 0x8f, 0x01, 0x60, 0x00, 0x0d, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x06,
+   0x30, 0x73, 0x66, 0x8c, 0x11, 0x60, 0x82, 0x99, 0xe3, 0x8c, 0x99, 0x01,
+   0x60, 0x80, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x63, 0x06, 0x30, 0x33, 0x66, 0x0c, 0x0b, 0x60, 0xc1, 0x98,
+   0x61, 0xcc, 0x98, 0x01, 0x30, 0x80, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x06, 0x30, 0x33, 0x66, 0x0c,
+   0x07, 0xe0, 0xc0, 0x9f, 0x61, 0xcc, 0x9f, 0x01, 0x18, 0x40, 0x0c, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x06,
+   0x30, 0x33, 0x66, 0x0c, 0x0e, 0xe0, 0xc1, 0x80, 0x61, 0xcc, 0x80, 0x01,
+   0x0c, 0xc0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x63, 0x0c, 0x30, 0x33, 0x66, 0x0c, 0x0d, 0x60, 0xc3, 0x80,
+   0x61, 0xcc, 0x80, 0x01, 0x06, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x1c, 0x32, 0x33, 0x66, 0x8e,
+   0x18, 0x60, 0x86, 0x81, 0x61, 0x8c, 0x81, 0x01, 0x03, 0x06, 0x0c, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0xf0,
+   0x31, 0x33, 0xc6, 0x4d, 0x38, 0x60, 0x0c, 0x9f, 0x61, 0x0c, 0x9f, 0x01,
+   0x7f, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00,
+   0x00, 0x00, 0xe0, 0x07, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x80,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x70, 0x40, 0x0b, 0xe9, 0xe8, 0x88,
+   0x0e, 0x1f, 0xf0, 0xe8, 0x80, 0x40, 0x1a, 0xc3, 0xc7, 0xa3, 0x23, 0xd0,
+   0xe1, 0x13, 0x1d, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0xc0,
+   0x08, 0x19, 0x19, 0x89, 0x91, 0x10, 0x08, 0x19, 0x81, 0x40, 0x86, 0x24,
+   0x24, 0x64, 0x24, 0x30, 0x12, 0x12, 0x23, 0x91, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x80, 0x08, 0x40, 0x08, 0x09, 0x09, 0x89, 0x90, 0x10, 0x08, 0x09,
+   0x81, 0x40, 0x02, 0x24, 0x24, 0x24, 0xe4, 0x13, 0x12, 0x12, 0x21, 0x91,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x70, 0x40, 0x08, 0x09, 0x09, 0x89,
+   0x90, 0x10, 0x08, 0x09, 0x81, 0x40, 0x82, 0x27, 0x24, 0x24, 0x24, 0x10,
+   0x12, 0x12, 0x21, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40,
+   0x08, 0x09, 0x09, 0x89, 0x90, 0x10, 0x08, 0x09, 0x81, 0x40, 0x42, 0x24,
+   0x24, 0x24, 0x24, 0x10, 0x12, 0x12, 0x21, 0x81, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x80, 0x80, 0x40, 0x88, 0x09, 0x09, 0x89, 0x90, 0x18, 0x08, 0x09,
+   0x81, 0x20, 0x42, 0x24, 0x26, 0x24, 0x24, 0x10, 0x12, 0x13, 0x21, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x78, 0x40, 0x70, 0x09, 0x09, 0x89,
+   0x10, 0x17, 0xf0, 0x08, 0x81, 0x1f, 0x82, 0xcf, 0xc5, 0x23, 0xe4, 0x17,
+   0xe2, 0x12, 0x21, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00,
+   0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+   0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x03, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+   0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x80, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff,
+   0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x7f, 0xfe, 0x01, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff,
+   0x7f, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xfc, 0xff, 0xff, 0x7f, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x3f, 0xf8, 0x07, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff,
+   0x3f, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff,
+   0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+   0xc1, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x7f, 0xf8, 0xff, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x7f, 0x00, 0xfe, 0x3f, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x3f,
+   0x00, 0xfc, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x1f, 0xe0, 0x3f, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x1f, 0x18, 0xf8, 0x7f, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xc7, 0x1f,
+   0x7e, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xce, 0xcd, 0x1f, 0xde, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0xcd, 0x1f, 0xbf, 0xf0, 0x7f, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0xcb, 0x1f,
+   0xbf, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xce, 0xcb, 0x1f, 0xff, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0x8f, 0x1f, 0xff, 0xf0, 0x7f, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x0f, 0x00,
+   0xff, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x9e, 0x37, 0x18, 0xfe, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x1b, 0x00, 0x7c, 0xf8, 0x7f, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x01, 0x00,
+   0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xfe, 0x00, 0x00, 0xc0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00,
+   0x00, 0xf8, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x0e, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00,
+   0x80, 0xf1, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x3e, 0x00, 0x00, 0xc0, 0xf8, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x78, 0xf8, 0xff, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00,
+   0x0f, 0xfc, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xfe, 0x01, 0xe0, 0x01, 0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x3e, 0xc0, 0xfc, 0xe1, 0x03,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x0f,
+   0xf0, 0xf8, 0xc1, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xfc, 0xf9, 0x01, 0x7c, 0xf8, 0xc3, 0x07, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x03, 0x00, 0x0f, 0xf8, 0xcf, 0x0f,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x07, 0xc0,
+   0x07, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x9e, 0x1f, 0xf8, 0x01, 0xf0, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0xe0, 0xff, 0x3f,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xfe, 0x7f,
+   0x00, 0xc0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xc0, 0x0f, 0xfe, 0x1f, 0x00, 0xc0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0xfc, 0x0f, 0x00, 0x80, 0xff, 0x7f,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xf8, 0x07,
+   0x00, 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0x03, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+   0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00,
+   0x00, 0x00, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff,
+   0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x1f, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff,
+   0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xfc, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+   0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfb, 0xff, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf7,
+   0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xf0, 0xef, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+   0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xdf, 0xff, 0x03, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9f,
+   0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x3f, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xc0, 0xbf, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
+   0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0xff, 0x07, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xbc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f,
+   0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x1f, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x80, 0x7f, 0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+   0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x1f, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+   0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xff, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+   0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf9, 0x1f, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+   0xf9, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x03, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xfe, 0xf9, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+   0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf3, 0x7f, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+   0xf3, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xfc, 0xf3, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf3, 0xff, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+   0xf7, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xfc, 0xe7, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xfe,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xe7, 0xff, 0x01, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xf0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+   0xe7, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7e, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xf8, 0xe7, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7e,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe7, 0xff, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xfc, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+   0xe7, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7e, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xf8, 0xe7, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7e,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf7, 0xff, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xfe, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+   0xf7, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xf8, 0xf3, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfb, 0xff, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xff, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+   0xf9, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x79, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x70, 0xe0, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x79,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xff, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xff, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+   0x3f, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xc3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+   0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x01, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfc,
+   0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x60, 0xf8, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0xf0,
+   0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xf8, 0xff, 0x3f, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x40, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xf0,
+   0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x30, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0xc0,
+   0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe0, 0xff, 0x07, 0x04, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x70, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xc0,
+   0xff, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x30, 0x80, 0xff, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00,
+   0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x3f, 0x00, 0x0c, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xfe, 0x1f, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
+   0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xc7, 0x03, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+   0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00,
+   0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1c, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+   0x01, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
+   0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00,
+   0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00,
+   0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+   0x03, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00,
+   0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x00, 0x00,
+   0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00,
+   0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xc0, 0x0f,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x07, 0x00, 0x00, 0x00, 0x80, 0xff, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00,
+   0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00,
+   0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+   0x00, 0x3f, 0x00, 0x00, 0x00, 0x80, 0x77, 0x00, 0x00, 0x00, 0x00, 0x60,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x0f, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0xc0, 0x77, 0x00,
+   0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+   0x00, 0xe0, 0x77, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
+   0x00, 0x0c, 0x00, 0x00, 0x00, 0xf0, 0x77, 0x00, 0x00, 0x00, 0x00, 0x60,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x07, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0xfc, 0x7b, 0x00,
+   0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x98, 0x07, 0x00,
+   0x00, 0xfe, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00,
+   0x00, 0x30, 0x0f, 0x00, 0x80, 0xff, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x0e,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+   0x03, 0x00, 0x00, 0x00, 0x00, 0x70, 0x3e, 0x00, 0xf8, 0xff, 0x7b, 0x00,
+   0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xfe, 0xff,
+   0xff, 0xff, 0x3b, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0xe0, 0xfc, 0xff, 0xff, 0xff, 0x39, 0x00, 0x00, 0x00, 0x7c, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+   0x01, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfc, 0xff, 0xff, 0xff, 0x39, 0x00,
+   0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfd, 0xff,
+   0xff, 0xff, 0x3c, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00,
+   0x00, 0xe0, 0xfd, 0xff, 0xff, 0xff, 0x3c, 0x00, 0x00, 0xf8, 0x01, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x3f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xfd, 0xff, 0xff, 0xff, 0x7c, 0x00,
+   0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0x00, 0xf0, 0xfd, 0xff,
+   0xff, 0xff, 0x7d, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00,
+   0x00, 0xf0, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x80, 0x1f, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xfe, 0x0f, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+   0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0xf8, 0x0f, 0x00,
+   0x00, 0x00, 0xfe, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f,
+   0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0xfc, 0x01, 0xf8, 0x01, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xc0, 0x7f, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07,
+   0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc7, 0x1f, 0x00, 0x00,
+   0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+   0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xc0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff,
+   0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00,
+   0x00, 0x00, 0x80, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/traps.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/traps.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/traps.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/traps.c	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,73 @@
+/*
+ * linux/arch/m68knommu/platform/MC68VZ328/de2/traps.c -- general exception handling code
+ *
+ * Cloned from Linux/m68k.
+ *
+ * No original Copyright holder listed,
+ * Probabily original (C) Roman Zippel (assigned DJD, 1999)
+ *
+ * Copyright 1999-2000 D. Jeff Dionne, <jeff@uclinux.org>
+ * Copyright 2000-2001 Lineo, Inc. D. Jeff Dionne <jeff@uClinux.org>
+ * Copyright 2002      Georges Menie
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+#include <asm/MC68VZ328.h>
+
+#include "traps_proto.h"
+
+extern e_vector *_ramvec;
+
+void __init dragen2_trap_init(void)
+{
+	int i;
+
+	/* set up the vectors */
+	for (i=2; i < 32; ++i)
+		_ramvec[i] = bad_interrupt;
+
+	_ramvec[2] = buserr;
+	_ramvec[3] = exception3;
+	_ramvec[4] = exception4;
+	_ramvec[5] = exception5;
+	_ramvec[6] = exception6;
+	_ramvec[7] = exception7;
+	_ramvec[8] = exception8;
+	_ramvec[9] = exception9;
+	_ramvec[10] = exception10;
+	_ramvec[11] = exception11;
+
+	_ramvec[14] = exception14;
+	_ramvec[15] = exception15;
+
+	_ramvec[32] = system_call;
+	_ramvec[33] = trap1;
+
+	_ramvec[47] = trap15;
+
+	_ramvec[64] = bad_interrupt;
+	_ramvec[65] = inthandler1;
+	_ramvec[66] = inthandler2;
+	_ramvec[67] = inthandler3;
+	_ramvec[68] = inthandler4;
+	_ramvec[69] = inthandler5;
+	_ramvec[70] = inthandler6;
+	_ramvec[71] = inthandler7;
+ 
+	IVR = 0x40; /* Set interrupt base to 64 */
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/traps_proto.h linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/traps_proto.h
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/traps_proto.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/traps_proto.h	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,23 @@
+asmlinkage void buserr(void);
+asmlinkage void exception3(void);
+asmlinkage void exception4(void);
+asmlinkage void exception5(void);
+asmlinkage void exception6(void);
+asmlinkage void exception7(void);
+asmlinkage void exception8(void);
+asmlinkage void exception9(void);
+asmlinkage void exception10(void);
+asmlinkage void exception11(void);
+asmlinkage void exception14(void);
+asmlinkage void exception15(void);
+asmlinkage void bad_interrupt(void);
+asmlinkage void inthandler1(void);
+asmlinkage void inthandler2(void);
+asmlinkage void inthandler3(void);
+asmlinkage void inthandler4(void);
+asmlinkage void inthandler5(void);
+asmlinkage void inthandler6(void);
+asmlinkage void inthandler7(void);
+asmlinkage void system_call(void);
+asmlinkage void trap1(void);
+asmlinkage void trap15(void);
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/xbm2lcd.pl linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/xbm2lcd.pl
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/xbm2lcd.pl	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/xbm2lcd.pl	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,6 @@
+
+$_ = join("", <>);
+
+s/(0x[0-9a-f]{2})/sprintf("0x%.2x",ord(pack("b8",unpack("B8",chr(~hex($1)&0377)))))/gei;
+
+print $_;
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/zimage/crt0.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/zimage/crt0.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/zimage/crt0.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/zimage/crt0.S	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,78 @@
+/*
+ *  linux/arch/m68knommu/platform/MC68VZ328/de2/zimage/crt0.S
+ *
+ *  Copyright (C) 2002 Georges Menie
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+	.title "de2/zimage/crt0.S"
+
+	.extern unzip_image
+	.extern __stack
+	.extern __text_end
+	.extern __data_start
+	.extern __data_end
+	.extern __bss_start
+	.extern __bss_end
+	.extern start_image
+
+	.text
+	.global start
+start:
+
+        /* initialize the stack */
+        move.l  #__stack,%sp
+
+	/* disable interrupts */
+	move.l	#-1,0xfffff304
+	move.b	#0,0xfffff300
+
+        /* initialize the data section */
+	lea.l	__text_end,%a0
+	lea.l	__data_start,%a1
+	lea.l	__data_end,%a2
+1:	cmpa.l  %a1,%a2
+        jbeq	2f
+	move.l	(%a0)+,(%a1)+
+	jbra	1b
+2:
+        /* initialize the bss section */
+        lea.l   __bss_start,%a0
+        lea.l   __bss_end,%a1
+1:	cmpa.l  %a0,%a1
+        jbeq	2f
+	move.l  #0,(%a0)+
+	jbra	1b
+2:
+	
+/*
+ * Unzip the kernel image
+ */
+	jsr	unzip_image
+
+/*
+ * Start the image
+ */
+	movea.l	#start_image,%a0
+	jmp	(%a0)
+
+/*
+ * Infinite loop for exit
+ */
+        .global exit
+exit:
+	bra	exit
+
+/*
+ * Define putc to send a char to the UART1
+ */
+        .global putc
+putc:
+1:	move.w	0xfffff906,%d0
+	and.w	#0x2000,%d0
+	beq	1b
+	move.b	7(%sp),0xfffff907
+	rts
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/zimage/image.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/zimage/image.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/zimage/image.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/zimage/image.ld	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,99 @@
+STARTUP(crt0.o)
+OUTPUT_ARCH(m68k)
+SEARCH_DIR(.)
+GROUP(-lc -lgcc)
+__DYNAMIC  =  0;
+
+/*
+
+ To test the decompression use:
+
+   rom (rwx) : ORIGIN = 0x400000, LENGTH = 2M
+
+ download and run the compressed zImage.bin at 0x400000.
+ Depending on the build model (RAM,HIMEM,ROM) and
+ the size of the kernel (either compressed or uncompressed)
+ you might need to change this address.
+ 
+ To generate a flashable compressed image, use:
+
+   rom (rwx) : ORIGIN = <addr_in_flash>, LENGTH = <available space>
+
+ store and run the compressed image at <addr_in_flash>
+
+*/
+
+MEMORY
+{
+  ram (rwx) : ORIGIN =   0x1000, LENGTH = 64k-4k
+  rom (rwx) : ORIGIN = 0x400000, LENGTH = 2M
+}
+
+PROVIDE (__stack = 4k - 4);
+
+SECTIONS
+{
+  .text :
+  {
+    __text_start = .;
+    *(.text)
+
+    . = ALIGN(0x4);
+    *(.rodata)
+    *(.rodata.str1.1)
+
+    . = ALIGN(0x4);
+    *(.gcc_except_table) 
+
+    . = ALIGN(0x4);
+    *(.eh_frame)
+
+    . = ALIGN(0x4);
+    *(.lit)
+
+    . = ALIGN(0x4);
+    input_data = .;
+    image.o
+    input_data_end = .;
+
+    . = ALIGN(0x4);
+    __text_end = .;
+  } > rom
+
+  .data : AT(__text_end)
+   {
+    . = ALIGN (0x4);
+    __data_start = .;
+
+    *(.shdata)
+    *(.data)
+    *(.gcc_exc)
+
+    . = ALIGN (0x4);
+    __data_end = .;
+   } > ram
+
+  .bss :
+  {
+    . = ALIGN(0x4);
+    __bss_start = . ;
+
+    *(.shbss)
+    *(.bss)
+    *(COMMON)
+
+    . = ALIGN(0x4);
+    __bss_end = .;
+    _end = .;
+  } > ram
+
+  .stab 0 (NOLOAD) :
+  {
+    *(.stab)
+  }
+
+  .stabstr 0 (NOLOAD) :
+  {
+    *(.stabstr)
+  }
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/zimage/main.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/zimage/main.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/zimage/main.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/zimage/main.c	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,32 @@
+
+/*
+ *  linux/arch/m68knommu/platform/MC68VZ328/de2/zimage/main.c
+ *
+ *  Copyright (C) 2002 Georges Menie
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+extern unsigned char input_data[];
+extern unsigned char input_data_end[];
+extern unsigned char output_data[];
+
+void outstring (char *s)
+{
+	extern void putc (int);
+
+	while (*s)
+		putc (*s++);
+}
+
+void unzip_image (void)
+{
+	void memgunzip (unsigned char *dst, const unsigned char *src,
+					unsigned int sz);
+
+	outstring ("Uncompressing Linux");
+	memgunzip (output_data, input_data, input_data_end - input_data);
+	outstring ("\r\nOk, booting the kernel.\r\n");
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/zimage/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/zimage/Makefile
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/zimage/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/zimage/Makefile	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,46 @@
+
+# Runtime parameters
+UNZIP_ADDRESS := $(shell [ -f $(ROOTDIR)/$(LINUXDIR)/System.map ] && grep ' _stext$$' $(ROOTDIR)/$(LINUXDIR)/System.map | cut -d' ' -f1)
+START_ADDRESS := $(shell [ -f $(ROOTDIR)/$(LINUXDIR)/System.map ] && grep ' _start$$' $(ROOTDIR)/$(LINUXDIR)/System.map | cut -d' ' -f1)
+
+# Compiler and associated tools filenames.
+CC = $(CROSS_COMPILE)gcc
+LD = $(CROSS_COMPILE)ld
+OBJCOPY = $(CROSS_COMPILE)objcopy
+
+# Flags.
+AFLAGS = -m68000 -Wall -I$(ROOTDIR)/$(LINUXDIR)/include
+CFLAGS = -m68000 -Wall -O2 --omit-frame-pointer -I$(ROOTDIR)/$(LINUXDIR)/include
+LFLAGS = -m68000 -nostdlib -Wl,-Map=$(basename $@).map
+
+#
+# Targets
+#
+
+OBJECTS = \
+	main.o \
+	misc.o
+
+all: $(IMAGEDIR)/zImage.bin
+
+crt0.o: crt0.S
+	$(CC) $(AFLAGS) -o $@ -c $+
+
+image.o: $(IMAGEDIR)/image.bin
+	tmpimage=_tmp_$$$$image; \
+	cat $+ | gzip -f -9 > $$tmpimage; \
+	$(LD) -r -o $@ -b binary $$tmpimage; \
+	rm -f $$tmpimage
+
+$(IMAGEDIR)/zImage.bin: crt0.o image.o ${OBJECTS}
+	tmpprog=_tmp_$$$$prog; \
+	tmplnk=_tmp_$$$$lnk; \
+	cp image.ld $$tmplnk; \
+	echo "PROVIDE (output_data = 0x$(UNZIP_ADDRESS));" >> $$tmplnk; \
+	echo "PROVIDE (start_image = 0x$(START_ADDRESS));" >> $$tmplnk; \
+	$(CC) $(LFLAGS) -T $$tmplnk -o $$tmpprog ${OBJECTS}; \
+	$(OBJCOPY) -O binary -j .text -j .data $$tmpprog $@; \
+	rm -f $$tmpprog $$tmplnk
+
+clean:
+	rm -f *.o _tmp_*
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/zimage/misc.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/zimage/misc.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/de2/zimage/misc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/de2/zimage/misc.c	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,151 @@
+
+/*
+ *  linux/arch/m68knommu/platform/MC68VZ328/de2/zimage/misc.c
+ *
+ *  Copyright (C) 2002 Georges Menie
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * gunzip wrapper based on :
+ *
+ * arch/sh/boot/compressed/misc.c
+ * 
+ * This is a collection of several routines from gzip-1.0.3 
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Adapted for SH by Stuart Menefy, Aug 1999
+ *
+ * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
+ */
+
+/*
+ * gzip declarations
+ */
+
+#define NULL 0
+
+#define OF(args)  args
+#define STATIC static
+
+#define memzero(s, n)     memset ((s), 0, (n))
+
+void outstring (const char *);
+void exit (int);
+
+typedef unsigned char uch;
+typedef unsigned short ush;
+typedef unsigned long ulg;
+
+#define WSIZE 0x8000			/* Window size must be at least 32k, */
+								/* and a power of two */
+
+static uch window[WSIZE];		/* Sliding window buffer */
+
+static ulg inptr = 0;			/* index of next byte to be processed in inbuf */
+static ulg outcnt = 0;			/* bytes in output buffer */
+static ulg bytes_out = 0;
+
+/* Diagnostic functions */
+#define Assert(cond,msg)
+#define Trace(x)
+#define Tracev(x)
+#define Tracevv(x)
+#define Tracec(c,x)
+#define Tracecv(c,x)
+
+static void flush_window (void);
+static void *malloc (int size);
+static void free (void *where);
+static void error (char *m);
+static void gzip_mark (void **);
+static void gzip_release (void **);
+
+static const unsigned char *data_in;
+static unsigned char *data_out;
+static unsigned int data_in_len;
+
+#define get_byte() ((inptr < data_in_len)?data_in[inptr++]:(error("ran out of input data\n"),0))
+#define put_byte(c) *data_out++ = c
+
+#include "../../../../../../lib/inflate.c"
+
+#define HEAPSIZE (24*1024)
+static unsigned char heap[HEAPSIZE];
+static unsigned char *free_mem_ptr = heap;
+
+static void *malloc (int size)
+{
+	void *p;
+
+	if (size < 0)
+		error ("Malloc error\n");
+	if (free_mem_ptr == 0)
+		error ("Memory error\n");
+
+	free_mem_ptr = (unsigned char *) (((unsigned long) free_mem_ptr + 3) & ~3);	/* Align */
+
+	p = free_mem_ptr;
+	free_mem_ptr += size;
+
+	if (free_mem_ptr >= &heap[HEAPSIZE])
+		error ("\nOut of memory\n");
+
+	return p;
+}
+
+static void free (void *where)
+{								/* Don't care */
+}
+
+static void gzip_mark (void **ptr)
+{
+	*ptr = free_mem_ptr;
+}
+
+static void gzip_release (void **ptr)
+{
+	free_mem_ptr = *ptr;
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void flush_window (void)
+{
+	ulg c = crc;				/* temporary variable */
+	unsigned n;
+	uch *in, ch;
+
+	in = window;
+	for (n = 0; n < outcnt; n++) {
+		ch = *in++;
+		put_byte (ch);
+		c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8);
+	}
+	crc = c;
+	bytes_out += outcnt;
+	outcnt = 0;
+	outstring (".");
+}
+
+static void error (char *x)
+{
+	outstring ("\r\n\r\n");
+	outstring (x);
+	outstring ("\r\n\r\n -- System halted\r\n");
+	exit (1);
+}
+
+void memgunzip (unsigned char *dst, const unsigned char *src, unsigned int sz)
+{
+	data_out = dst;
+	data_in = src;
+	data_in_len = sz;
+	makecrc ();
+	gunzip ();
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/bootlogo.h linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/bootlogo.h
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/bootlogo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/bootlogo.h	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,325 @@
+#define splash_width 240
+#define splash_height 320
+static unsigned char splash_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf1, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0xf7, 0x0f, 0x00, 0x00,
+ 0x00, 0xf1, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0xf7, 0xef, 0x00, 0x00,
+ 0x00, 0xf1, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0xff, 0xff, 0x08, 0x00,
+ 0x00, 0x70, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x00, 0x10, 0xff, 0xff, 0x0c, 0x00,
+ 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x00, 0x10, 0xff, 0xff, 0x0e, 0x00,
+ 0x00, 0x00, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x00, 0x03, 0x10, 0xff, 0x0e, 0x00,
+ 0x00, 0x10, 0xfe, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x00, 0x0f, 0x00, 0xf0, 0x0e, 0x00,
+ 0x00, 0x30, 0x3e, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x00, 0x0f, 0x00, 0x30, 0x0e, 0x00,
+ 0x00, 0x30, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x00, 0x0f, 0x00, 0x70, 0x0e, 0x00,
+ 0x00, 0x70, 0x0c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x10, 0x0f, 0x00, 0x70, 0x0c, 0x00,
+ 0x00, 0x70, 0x0c, 0xf3, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x10, 0x0f, 0x00, 0xf0, 0x0c, 0x00,
+ 0x00, 0x70, 0x0c, 0xf1, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x10, 0x0e, 0x00, 0xf0, 0x08, 0x00,
+ 0x00, 0x70, 0x0c, 0xf0, 0x0c, 0x00, 0x00, 0x00, 0xc1, 0x00, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x8f, 0x10, 0x0e, 0x00, 0xf1, 0x08, 0x00,
+ 0x00, 0x70, 0x08, 0x70, 0x0c, 0x00, 0x00, 0x00, 0xe3, 0x00, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x8f, 0x10, 0x0e, 0x00, 0xf1, 0x00, 0x00,
+ 0x00, 0x70, 0x08, 0x70, 0x0c, 0x00, 0x00, 0x00, 0xcf, 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x00, 0x00, 0x8f, 0x30, 0x0c, 0x00, 0xe3, 0x00, 0x00,
+ 0x00, 0x70, 0x08, 0x70, 0x0c, 0x0e, 0x00, 0x10, 0x0f, 0x00, 0xcf, 0x00, 0x07, 0x00, 0x60, 0x00, 0x00, 0x00, 0x10, 0x38, 0x8f, 0x00, 0x00, 0x8f, 0x30, 0x0c, 0x00, 0xc7, 0x00, 0x00,
+ 0x00, 0xf0, 0x08, 0x70, 0x1c, 0x8f, 0x00, 0x30, 0x0f, 0x10, 0x8f, 0x00, 0xef, 0x00, 0xf1, 0x00, 0x00, 0x00, 0x30, 0x68, 0x8f, 0x00, 0x00, 0xcf, 0x30, 0x0c, 0x00, 0xcf, 0x00, 0x00,
+ 0x00, 0xf0, 0x08, 0x70, 0x38, 0xcf, 0x00, 0xf0, 0x0c, 0x30, 0x0f, 0x30, 0xff, 0x08, 0xf3, 0x00, 0x00, 0x00, 0x70, 0xc8, 0x0f, 0x00, 0x00, 0xcf, 0x70, 0x08, 0x00, 0x8f, 0x00, 0x00,
+ 0x00, 0xf0, 0x08, 0x70, 0x38, 0xef, 0x00, 0xf1, 0x08, 0x30, 0x0e, 0x70, 0xff, 0x0c, 0xf7, 0x00, 0x00, 0x00, 0x70, 0x8d, 0x0f, 0x00, 0x00, 0xcf, 0x70, 0x08, 0x10, 0x0f, 0x00, 0x00,
+ 0x00, 0xf0, 0x00, 0x70, 0x78, 0xff, 0x00, 0xf3, 0x81, 0x70, 0x0c, 0x70, 0xff, 0x0c, 0xff, 0x00, 0x00, 0x87, 0x70, 0x1f, 0x0e, 0x00, 0x00, 0xc7, 0xf0, 0x00, 0x30, 0x0e, 0x00, 0x00,
+ 0x00, 0xf0, 0x00, 0x70, 0x70, 0xff, 0x00, 0xe7, 0xc3, 0xf0, 0x08, 0xf0, 0x7f, 0x1c, 0xef, 0xf1, 0x00, 0x8f, 0x30, 0x3e, 0x0c, 0x00, 0x00, 0xc7, 0xf0, 0x00, 0x70, 0x0c, 0x00, 0x00,
+ 0x00, 0xf0, 0x00, 0xf0, 0xf0, 0xf1, 0x08, 0xcf, 0xc7, 0xf0, 0x00, 0xf1, 0x3c, 0x1c, 0xef, 0xf3, 0x18, 0x8f, 0x30, 0x7e, 0x08, 0x00, 0x00, 0xc7, 0xf1, 0x00, 0x70, 0x0c, 0x00, 0x00,
+ 0x00, 0xf0, 0x00, 0xf0, 0xe1, 0xf0, 0x18, 0x8f, 0xcf, 0xf1, 0x00, 0xf3, 0x3c, 0x3c, 0xef, 0xf7, 0x38, 0xcf, 0x70, 0x7e, 0x00, 0x00, 0x00, 0xc7, 0xe1, 0x00, 0xf0, 0x08, 0x00, 0x00,
+ 0x00, 0xf0, 0x00, 0xe1, 0xc1, 0xf0, 0x30, 0x1f, 0xcf, 0xf3, 0x00, 0xf7, 0x30, 0x78, 0xc3, 0xff, 0x78, 0xcf, 0xf0, 0xef, 0x00, 0x0c, 0x00, 0xc7, 0xe1, 0x00, 0xf1, 0x00, 0x00, 0x00,
+ 0x00, 0xf1, 0x00, 0xc3, 0x83, 0xf0, 0x70, 0x7e, 0xcf, 0xf7, 0x00, 0xef, 0x70, 0xf8, 0xd3, 0xff, 0xfc, 0xcf, 0xc1, 0xef, 0x30, 0x0c, 0x00, 0xc3, 0xc3, 0x00, 0xe3, 0x00, 0x00, 0x00,
+ 0x00, 0xe1, 0x00, 0xc3, 0x07, 0xf0, 0xf1, 0xfe, 0xe7, 0xff, 0x18, 0xef, 0x70, 0xe1, 0xb7, 0x7c, 0xed, 0xc7, 0x83, 0xcf, 0x70, 0x08, 0x00, 0xe3, 0xc3, 0x00, 0xc7, 0x00, 0x00, 0x00,
+ 0x00, 0xe1, 0x00, 0x87, 0x0e, 0xf0, 0xf3, 0xef, 0xf3, 0xfe, 0x38, 0xeb, 0xe0, 0x83, 0xf7, 0x38, 0xcf, 0xe7, 0x0f, 0xc7, 0xf0, 0x00, 0x00, 0xe3, 0x87, 0x00, 0x87, 0x00, 0x00, 0x00,
+ 0x00, 0xe1, 0x00, 0x1f, 0x0c, 0xe1, 0xb7, 0xcf, 0xf3, 0xf8, 0x7c, 0xe3, 0xc1, 0x07, 0xf7, 0x30, 0x8f, 0xf3, 0x0e, 0xef, 0xc3, 0x00, 0x00, 0xe3, 0x87, 0x00, 0x8f, 0x00, 0x00, 0x00,
+ 0x00, 0xe1, 0x10, 0x3e, 0x08, 0xe1, 0x7f, 0x8f, 0xf1, 0xf0, 0xec, 0xe3, 0xc7, 0x0e, 0xe7, 0x10, 0x0f, 0xf3, 0x1c, 0xff, 0x8f, 0x00, 0x00, 0xe1, 0x0f, 0x10, 0x0f, 0x00, 0x04, 0x00,
+ 0x00, 0xc1, 0x30, 0x0d, 0x00, 0xf1, 0x7e, 0x0f, 0x40, 0x70, 0xcf, 0xf3, 0x0f, 0x08, 0xcf, 0x00, 0x0e, 0xf1, 0x38, 0xf9, 0x0f, 0x00, 0x00, 0xf1, 0x0f, 0x30, 0x0e, 0x10, 0x0c, 0x00,
+ 0x00, 0xc1, 0x70, 0x0e, 0x00, 0xf3, 0x78, 0x0c, 0x00, 0x30, 0xcf, 0xf1, 0x0e, 0x00, 0x8f, 0x00, 0x00, 0xe0, 0x70, 0xf1, 0x0c, 0x00, 0x00, 0xf1, 0x0e, 0x70, 0x0c, 0xf0, 0x0c, 0x00,
+ 0x00, 0xc1, 0xf0, 0x0c, 0x00, 0xf3, 0x10, 0x00, 0x00, 0x10, 0x8f, 0xf1, 0x08, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xe0, 0x70, 0x00, 0x00, 0x00, 0xf0, 0x0e, 0xf0, 0x1c, 0xff, 0x08, 0x00,
+ 0x00, 0x81, 0xf3, 0x08, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0e, 0xf0, 0xff, 0xcf, 0x00, 0x00,
+ 0x00, 0x11, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0e, 0xf1, 0xff, 0x8f, 0x00, 0x00,
+ 0x00, 0x30, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0c, 0xf1, 0xff, 0x0e, 0x00, 0x00,
+ 0x00, 0x70, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xeb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x08, 0xf1, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x70, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00,
+ 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0c, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0e, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x87, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xe1, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xe0, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x70, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x30, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x30, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x30, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x30, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x70, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x78, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x78, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x8f, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xcf, 0x30, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xc7, 0x30, 0x0f, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0x08, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc1, 0x70, 0x0e, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0x0c, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc1, 0x70, 0x06, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xfb, 0x0c, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0xc1, 0xf0, 0x06, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x70, 0x0c, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0xc3, 0xe0, 0x0c, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x10, 0x0c, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x08, 0xc3, 0xe1, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x0c, 0x00, 0x87, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0xc7, 0xd1, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x0f, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x87, 0xd1, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x30, 0x08, 0x00, 0x0f, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x87, 0x93, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0f, 0x00, 0x00, 0x70, 0x08, 0x00, 0x0f, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0xf0, 0x00, 0x8f, 0xb3, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0x00, 0x3c, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x0e, 0xc7, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0xe0, 0x00, 0x0f, 0xe3, 0x00, 0x00, 0x70, 0x08, 0x00, 0x0e, 0x10, 0x6e, 0x0f, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x0e, 0x87, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0xe0, 0x00, 0x0f, 0xe3, 0x00, 0x00, 0xf0, 0x08, 0x10, 0x0e, 0x10, 0xce, 0x0e, 0x00, 0x00, 0xc1, 0x00, 0x10, 0x0e, 0x87, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0xe1, 0x00, 0x0f, 0xc7, 0x00, 0x0e, 0xf1, 0x68, 0x10, 0x0c, 0x10, 0x9f, 0x0c, 0x00, 0x00, 0xc3, 0x00, 0x10, 0x0c, 0x87, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x87, 0x83, 0xe1, 0x00, 0x04, 0xc7, 0x10, 0x0e, 0xf3, 0xf1, 0x30, 0x1c, 0x0c, 0x3f, 0x0c, 0x00, 0x00, 0x87, 0x00, 0x10, 0x0c, 0x87, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x8f, 0x87, 0xe1, 0x00, 0x00, 0x87, 0x30, 0x0e, 0xf7, 0xf3, 0x70, 0x3c, 0x0c, 0x3f, 0x08, 0x00, 0x00, 0x0f, 0x00, 0x10, 0x0c, 0x87, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x8f, 0x87, 0xe7, 0x00, 0x00, 0x07, 0x70, 0x0f, 0xfe, 0xf7, 0xf8, 0x3c, 0x1c, 0xff, 0x10, 0x00, 0x10, 0x0e, 0x00, 0x10, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x30, 0x0f, 0x8f, 0xef, 0x00, 0x00, 0x8f, 0xf0, 0x1f, 0xec, 0xff, 0xf9, 0x7c, 0x7e, 0xe7, 0x70, 0x00, 0x30, 0x0c, 0x00, 0x10, 0x0c, 0x77, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x70, 0x1f, 0xff, 0xed, 0x00, 0x30, 0x8f, 0xc1, 0x3f, 0xf8, 0x7e, 0xff, 0xfc, 0xef, 0xc3, 0xe0, 0x00, 0x30, 0x0c, 0x00, 0x10, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xe0, 0x37, 0xfb, 0xf9, 0x00, 0x30, 0x8b, 0x83, 0xff, 0xf1, 0x38, 0x3f, 0xdd, 0xcf, 0xc3, 0xc1, 0x00, 0x70, 0x08, 0x10, 0x10, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x81, 0xf7, 0xe3, 0xf0, 0x00, 0x60, 0xe3, 0x0f, 0xe7, 0xf1, 0x30, 0x3e, 0x9f, 0x8f, 0xf7, 0x0f, 0x00, 0xf0, 0x00, 0x70, 0x08, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0xe7, 0xc0, 0xf0, 0x08, 0xc0, 0xf3, 0x0e, 0xc7, 0xf1, 0x10, 0x38, 0x0f, 0x06, 0xff, 0x0e, 0x00, 0xe1, 0x00, 0x70, 0x08, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc7, 0x00, 0xf0, 0x08, 0x01, 0xf1, 0x0c, 0x01, 0xe1, 0x00, 0x10, 0x0e, 0x10, 0xfc, 0x0c, 0x00, 0xe3, 0x00, 0x70, 0x08, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x70, 0x0e, 0x07, 0x70, 0x00, 0x00, 0xc3, 0x00, 0x10, 0x0c, 0x30, 0x28, 0x00, 0x00, 0xf3, 0xff, 0x0c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0x0c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0x08, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xef, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x8f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x0e, 0x12, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x0c, 0x11, 0x1e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x0c, 0x90, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0x96, 0xc9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0x0e, 0xfa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0x0e, 0xa2, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0x0e, 0xa4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0x96, 0xa8, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0xf0, 0xe0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x08, 0x41, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x0c, 0x02, 0x00, 0x30, 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x0e, 0x04, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xf7, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x9f, 0x08, 0x00, 0x83, 0x00, 0x00, 0xf1, 0xff, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x48, 0x00, 0x10, 0xff, 0x1c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0x00, 0x70, 0xf1, 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xc9, 0x00, 0xc7, 0xe7, 0x00, 0xf3, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x1c, 0xff, 0x3c, 0x8f, 0x00, 0x70, 0xff, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x0e, 0x00, 0xf0, 0x0f, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0x7c, 0xff, 0x0f, 0x00, 0x00, 0xf3, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x30, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x10, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0xf7, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0x8f, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc7, 0x81, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x6c, 0x03, 0xf1, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x38, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x10, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf7, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7c, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0xff, 0x70, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x70, 0xff, 0xff, 0x8f, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x70, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x0e, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0xf1, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf1, 0xff, 0xff, 0x08, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0xf7, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf3, 0xff, 0xef, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x10, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0x8f, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x70, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0x0e, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0c, 0xf1, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0xff, 0xff, 0x08, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0xf3, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0xff, 0xef, 0x00, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x08, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0xff, 0xcf, 0x00, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x91, 0x10, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0xff, 0x0f, 0x00, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x33, 0x70, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0xff, 0x0c, 0x00, 0x00, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x26, 0xf1, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0xff, 0x00, 0x00, 0x00, 0x30, 0xff, 0x00, 0x00, 0x00, 0x00, 0x6e, 0xf3, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0xef, 0x00, 0x00, 0x00, 0x30, 0xff, 0x00, 0x00, 0x00, 0x30, 0x4c, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x8f, 0x00, 0x00, 0x00, 0x30, 0xff, 0x00, 0x00, 0x00, 0x70, 0xd8, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x30, 0xff, 0x08, 0x00, 0x00, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0x08, 0x00, 0x00, 0xe3, 0xf1, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0x0c, 0x00, 0x00, 0xcf, 0xf3, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0x0e, 0x00, 0x10, 0x8f, 0xff, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0x8f, 0x00, 0xf0, 0x1e, 0xff, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0xef, 0x00, 0xf7, 0x7c, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xcf, 0xf3, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x1e, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0xff, 0xff, 0x78, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0xff, 0xcf, 0xf3, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0xff, 0x0f, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xff, 0xff, 0x1c, 0xff, 0xff, 0xff, 0x0e, 0x00, 0xf3, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0xfc, 0xff, 0x70, 0xff, 0xff, 0xef, 0x00, 0x00, 0x30, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0xf0, 0xcf, 0xf1, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xe3, 0xf0, 0x89, 0xf7, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x90, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xf3, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xf3, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x0f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x10, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x30, 0xff, 0xef, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x70, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x30, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0xf1, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0xf3, 0x08, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x30, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xf1, 0xff, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x30, 0x0e, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x70, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0e, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf0, 0xff, 0xf9, 0xff, 0xff, 0x0f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0xcf, 0xf1, 0xff, 0xff, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x8f, 0xf3, 0xff, 0x0e, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x01, 0xf7, 0xef, 0x00, 0x10, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0f, 0x00, 0x11, 0xff, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc3, 0x00, 0x73, 0x08, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf0, 0x08, 0xe3, 0x00, 0x00, 0x10, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x8f, 0x87, 0x00, 0x00, 0xf0, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf7, 0x0e, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xf1, 0xff, 0x0e, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0xff, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf1, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/bootlogo.rh linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/bootlogo.rh
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/bootlogo.rh	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/bootlogo.rh	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,325 @@
+#define splash_width 240
+#define splash_height 320
+
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x8f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0xef, 0xf0, 0x00, 0x00
+	.byte 0x00, 0x8f, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0xef, 0xf7, 0x00, 0x00
+	.byte 0x00, 0x8f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0xff, 0xff, 0x10, 0x00
+	.byte 0x00, 0x0e, 0xff, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf3, 0x00, 0x08, 0xff, 0xff, 0x30, 0x00
+	.byte 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf3, 0x00, 0x08, 0xff, 0xff, 0x70, 0x00
+	.byte 0x00, 0x00, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf3, 0x00, 0xc0, 0x08, 0xff, 0x70, 0x00
+	.byte 0x00, 0x08, 0x7f, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x00, 0xf0, 0x00, 0x0f, 0x70, 0x00
+	.byte 0x00, 0x0c, 0x7c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x00, 0xf0, 0x00, 0x0c, 0x70, 0x00
+	.byte 0x00, 0x0c, 0x70, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x00, 0xf0, 0x00, 0x0e, 0x70, 0x00
+	.byte 0x00, 0x0e, 0x30, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x08, 0xf0, 0x00, 0x0e, 0x30, 0x00
+	.byte 0x00, 0x0e, 0x30, 0xcf, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x08, 0xf0, 0x00, 0x0f, 0x30, 0x00
+	.byte 0x00, 0x0e, 0x30, 0x8f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x08, 0x70, 0x00, 0x0f, 0x10, 0x00
+	.byte 0x00, 0x0e, 0x30, 0x0f, 0x30, 0x00, 0x00, 0x00, 0x83, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xf1, 0x08, 0x70, 0x00, 0x8f, 0x10, 0x00
+	.byte 0x00, 0x0e, 0x10, 0x0e, 0x30, 0x00, 0x00, 0x00, 0xc7, 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf1, 0x08, 0x70, 0x00, 0x8f, 0x00, 0x00
+	.byte 0x00, 0x0e, 0x10, 0x0e, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x00, 0x00, 0xf1, 0x0c, 0x30, 0x00, 0xc7, 0x00, 0x00
+	.byte 0x00, 0x0e, 0x10, 0x0e, 0x30, 0x70, 0x00, 0x08, 0xf0, 0x00, 0xf3, 0x00, 0xe0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x1c, 0xf1, 0x00, 0x00, 0xf1, 0x0c, 0x30, 0x00, 0xe3, 0x00, 0x00
+	.byte 0x00, 0x0f, 0x10, 0x0e, 0x38, 0xf1, 0x00, 0x0c, 0xf0, 0x08, 0xf1, 0x00, 0xf7, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x0c, 0x16, 0xf1, 0x00, 0x00, 0xf3, 0x0c, 0x30, 0x00, 0xf3, 0x00, 0x00
+	.byte 0x00, 0x0f, 0x10, 0x0e, 0x1c, 0xf3, 0x00, 0x0f, 0x30, 0x0c, 0xf0, 0x0c, 0xff, 0x10, 0xcf, 0x00, 0x00, 0x00, 0x0e, 0x13, 0xf0, 0x00, 0x00, 0xf3, 0x0e, 0x10, 0x00, 0xf1, 0x00, 0x00
+	.byte 0x00, 0x0f, 0x10, 0x0e, 0x1c, 0xf7, 0x00, 0x8f, 0x10, 0x0c, 0x70, 0x0e, 0xff, 0x30, 0xef, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0xf0, 0x00, 0x00, 0xf3, 0x0e, 0x10, 0x08, 0xf0, 0x00, 0x00
+	.byte 0x00, 0x0f, 0x00, 0x0e, 0x1e, 0xff, 0x00, 0xcf, 0x81, 0x0e, 0x30, 0x0e, 0xff, 0x30, 0xff, 0x00, 0x00, 0xe1, 0x0e, 0xf8, 0x70, 0x00, 0x00, 0xe3, 0x0f, 0x00, 0x0c, 0x70, 0x00, 0x00
+	.byte 0x00, 0x0f, 0x00, 0x0e, 0x0e, 0xff, 0x00, 0xe7, 0xc3, 0x0f, 0x10, 0x0f, 0xfe, 0x38, 0xf7, 0x8f, 0x00, 0xf1, 0x0c, 0x7c, 0x30, 0x00, 0x00, 0xe3, 0x0f, 0x00, 0x0e, 0x30, 0x00, 0x00
+	.byte 0x00, 0x0f, 0x00, 0x0f, 0x0f, 0x8f, 0x10, 0xf3, 0xe3, 0x0f, 0x00, 0x8f, 0x3c, 0x38, 0xf7, 0xcf, 0x18, 0xf1, 0x0c, 0x7e, 0x10, 0x00, 0x00, 0xe3, 0x8f, 0x00, 0x0e, 0x30, 0x00, 0x00
+	.byte 0x00, 0x0f, 0x00, 0x0f, 0x87, 0x0f, 0x18, 0xf1, 0xf3, 0x8f, 0x00, 0xcf, 0x3c, 0x3c, 0xf7, 0xef, 0x1c, 0xf3, 0x0e, 0x7e, 0x00, 0x00, 0x00, 0xe3, 0x87, 0x00, 0x0f, 0x10, 0x00, 0x00
+	.byte 0x00, 0x0f, 0x00, 0x87, 0x83, 0x0f, 0x0c, 0xf8, 0xf3, 0xcf, 0x00, 0xef, 0x0c, 0x1e, 0xc3, 0xff, 0x1e, 0xf3, 0x0f, 0xf7, 0x00, 0x30, 0x00, 0xe3, 0x87, 0x00, 0x8f, 0x00, 0x00, 0x00
+	.byte 0x00, 0x8f, 0x00, 0xc3, 0xc1, 0x0f, 0x0e, 0x7e, 0xf3, 0xef, 0x00, 0xf7, 0x0e, 0x1f, 0xcb, 0xff, 0x3f, 0xf3, 0x83, 0xf7, 0x0c, 0x30, 0x00, 0xc3, 0xc3, 0x00, 0xc7, 0x00, 0x00, 0x00
+	.byte 0x00, 0x87, 0x00, 0xc3, 0xe0, 0x0f, 0x8f, 0x7f, 0xe7, 0xff, 0x18, 0xf7, 0x0e, 0x87, 0xed, 0x3e, 0xb7, 0xe3, 0xc1, 0xf3, 0x0e, 0x10, 0x00, 0xc7, 0xc3, 0x00, 0xe3, 0x00, 0x00, 0x00
+	.byte 0x00, 0x87, 0x00, 0xe1, 0x70, 0x0f, 0xcf, 0xf7, 0xcf, 0x7f, 0x1c, 0xd7, 0x07, 0xc1, 0xef, 0x1c, 0xf3, 0xe7, 0xf0, 0xe3, 0x0f, 0x00, 0x00, 0xc7, 0xe1, 0x00, 0xe1, 0x00, 0x00, 0x00
+	.byte 0x00, 0x87, 0x00, 0xf8, 0x30, 0x87, 0xed, 0xf3, 0xcf, 0x1f, 0x3e, 0xc7, 0x83, 0xe0, 0xef, 0x0c, 0xf1, 0xcf, 0x70, 0xf7, 0xc3, 0x00, 0x00, 0xc7, 0xe1, 0x00, 0xf1, 0x00, 0x00, 0x00
+	.byte 0x00, 0x87, 0x08, 0x7c, 0x10, 0x87, 0xfe, 0xf1, 0x8f, 0x0f, 0x37, 0xc7, 0xe3, 0x70, 0xe7, 0x08, 0xf0, 0xcf, 0x38, 0xff, 0xf1, 0x00, 0x00, 0x87, 0xf0, 0x08, 0xf0, 0x00, 0x20, 0x00
+	.byte 0x00, 0x83, 0x0c, 0xb0, 0x00, 0x8f, 0x7e, 0xf0, 0x02, 0x0e, 0xf3, 0xcf, 0xf0, 0x10, 0xf3, 0x00, 0x70, 0x8f, 0x1c, 0x9f, 0xf0, 0x00, 0x00, 0x8f, 0xf0, 0x0c, 0x70, 0x08, 0x30, 0x00
+	.byte 0x00, 0x83, 0x0e, 0x70, 0x00, 0xcf, 0x1e, 0x30, 0x00, 0x0c, 0xf3, 0x8f, 0x70, 0x00, 0xf1, 0x00, 0x00, 0x07, 0x0e, 0x8f, 0x30, 0x00, 0x00, 0x8f, 0x70, 0x0e, 0x30, 0x0f, 0x30, 0x00
+	.byte 0x00, 0x83, 0x0f, 0x30, 0x00, 0xcf, 0x08, 0x00, 0x00, 0x08, 0xf1, 0x8f, 0x10, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x07, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x70, 0x0f, 0x38, 0xff, 0x10, 0x00
+	.byte 0x00, 0x81, 0xcf, 0x10, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x70, 0x0f, 0xff, 0xf3, 0x00, 0x00
+	.byte 0x00, 0x88, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf3, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x70, 0x8f, 0xff, 0xf1, 0x00, 0x00
+	.byte 0x00, 0x0c, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x30, 0x8f, 0xff, 0x70, 0x00, 0x00
+	.byte 0x00, 0x0e, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x10, 0x8f, 0xff, 0x00, 0x00, 0x00
+	.byte 0x00, 0x0e, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00
+	.byte 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x30, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x70, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe1, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x87, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x07, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x0e, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x0c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x0c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0c, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0e, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1e, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3c, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7c, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x70, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xff, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0x08, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf1, 0x08, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xf1, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xf3, 0x0c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xe3, 0x0c, 0xf0, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xff, 0x10, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x83, 0x0e, 0x70, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xff, 0x30, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x83, 0x0e, 0x60, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xdf, 0x30, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x70, 0x83, 0x0f, 0x60, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x0e, 0x30, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0xc3, 0x07, 0x30, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x08, 0x30, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x10, 0xc3, 0x87, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x30, 0x00, 0xe1, 0xc3, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, 0xe3, 0x8b, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0xf0, 0xc3, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xe1, 0x8b, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x0c, 0x10, 0x00, 0xf0, 0xc3, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xe1, 0xc9, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf0, 0x00, 0x00, 0x0e, 0x10, 0x00, 0xf0, 0xc3, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0f, 0x00, 0xf1, 0xcd, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xe0, 0x00, 0x3c, 0xf0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x70, 0xe3, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x07, 0x00, 0xf0, 0xc7, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x70, 0x08, 0x76, 0xf0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x70, 0xe1, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x07, 0x00, 0xf0, 0xc7, 0x00, 0x00, 0x0f, 0x10, 0x08, 0x70, 0x08, 0x73, 0x70, 0x00, 0x00, 0x83, 0x00, 0x08, 0x70, 0xe1, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x87, 0x00, 0xf0, 0xe3, 0x00, 0x70, 0x8f, 0x16, 0x08, 0x30, 0x08, 0xf9, 0x30, 0x00, 0x00, 0xc3, 0x00, 0x08, 0x30, 0xe1, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0xe1, 0xc1, 0x87, 0x00, 0x20, 0xe3, 0x08, 0x70, 0xcf, 0x8f, 0x0c, 0x38, 0x30, 0xfc, 0x30, 0x00, 0x00, 0xe1, 0x00, 0x08, 0x30, 0xe1, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0xf1, 0xe1, 0x87, 0x00, 0x00, 0xe1, 0x0c, 0x70, 0xef, 0xcf, 0x0e, 0x3c, 0x30, 0xfc, 0x10, 0x00, 0x00, 0xf0, 0x00, 0x08, 0x30, 0xe1, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x08, 0xf1, 0xe1, 0xe7, 0x00, 0x00, 0xe0, 0x0e, 0xf0, 0x7f, 0xef, 0x1f, 0x3c, 0x38, 0xff, 0x08, 0x00, 0x08, 0x70, 0x00, 0x08, 0x30, 0xe0, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xf1, 0xf7, 0x00, 0x00, 0xf1, 0x0f, 0xf8, 0x37, 0xff, 0x9f, 0x3e, 0x7e, 0xe7, 0x0e, 0x00, 0x0c, 0x30, 0x00, 0x08, 0x30, 0xee, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x0e, 0xf8, 0xff, 0xb7, 0x00, 0x0c, 0xf1, 0x83, 0xfc, 0x1f, 0x7e, 0xff, 0x3f, 0xf7, 0xc3, 0x07, 0x00, 0x0c, 0x30, 0x00, 0x08, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x07, 0xec, 0xdf, 0x9f, 0x00, 0x0c, 0xd1, 0xc1, 0xff, 0x8f, 0x1c, 0xfc, 0xbb, 0xf3, 0xc3, 0x83, 0x00, 0x0e, 0x10, 0x08, 0x08, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x81, 0xef, 0xc7, 0x0f, 0x00, 0x06, 0xc7, 0xf0, 0xe7, 0x8f, 0x0c, 0x7c, 0xf9, 0xf1, 0xef, 0xf0, 0x00, 0x0f, 0x00, 0x0e, 0x10, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x80, 0xe7, 0x03, 0x0f, 0x10, 0x03, 0xcf, 0x70, 0xe3, 0x8f, 0x08, 0x1c, 0xf0, 0x60, 0xff, 0x70, 0x00, 0x87, 0x00, 0x0e, 0x10, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x0f, 0x10, 0x80, 0x8f, 0x30, 0x80, 0x87, 0x00, 0x08, 0x70, 0x08, 0x3f, 0x30, 0x00, 0xc7, 0x00, 0x0e, 0x10, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x0e, 0x70, 0xe0, 0x0e, 0x00, 0x00, 0xc3, 0x00, 0x08, 0x30, 0x0c, 0x14, 0x00, 0x00, 0xcf, 0xff, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xff, 0x70, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xff, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xff, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xff, 0x10, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf7, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xff, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf1, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x70, 0x48, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x30, 0x88, 0x78, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x30, 0x09, 0x34, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x10, 0x69, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x10, 0x70, 0x5f, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x10, 0x70, 0x45, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x10, 0x70, 0x25, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x10, 0x69, 0x15, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x10, 0x0f, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x10, 0x82, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x30, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0xff, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x70, 0x20, 0x00, 0x07, 0x00, 0x00, 0x00, 0xef, 0xff, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xf9, 0x10, 0x00, 0xc1, 0x00, 0x00, 0x8f, 0xff, 0xff, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x12, 0x00, 0x08, 0xff, 0x38, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x10, 0x00, 0x0e, 0x8f, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x93, 0x00, 0xe3, 0xe7, 0x00, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x38, 0xff, 0x3c, 0xf1, 0x00, 0x0e, 0xff, 0xff, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x70, 0x00, 0x0f, 0xf0, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xff, 0x3e, 0xff, 0xf0, 0x00, 0x00, 0xcf, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xff, 0xff, 0xff, 0x70, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0x30, 0x00, 0x00, 0x0c, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0x30, 0x00, 0x00, 0x08, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, 0xef, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0xf1, 0xff, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xff, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xff, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xff, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xff, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xff, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x08, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x0e, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x08, 0xff, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x0c, 0xff, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe3, 0x81, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x36, 0xc0, 0x8f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x1c, 0x30, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0xcf, 0xff, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x08, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0xef, 0xff, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x3e, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x08, 0xff, 0xff, 0xff, 0x0e, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x0e, 0xff, 0xff, 0xf1, 0x0c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x0e, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x70, 0x0c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x8f, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x8f, 0xff, 0xff, 0x10, 0x0c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x00, 0xef, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0xcf, 0xff, 0xf7, 0x00, 0x0c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x08, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0xff, 0xff, 0xf1, 0x00, 0x0c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x0e, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0xff, 0xff, 0x70, 0x00, 0x0c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x8f, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x08, 0xff, 0xff, 0x10, 0x00, 0x0c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0xcf, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x0c, 0xff, 0xf7, 0x00, 0x00, 0x0c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x10, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x0e, 0xff, 0xf3, 0x00, 0x00, 0x0c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x89, 0x08, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x0e, 0xff, 0xf0, 0x00, 0x00, 0x0c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x0e, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x0e, 0xff, 0x30, 0x00, 0x00, 0x0c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x64, 0x8f, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x0c, 0xff, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcf, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x0e, 0xf7, 0x00, 0x00, 0x00, 0x0c, 0xff, 0x00, 0x00, 0x00, 0x0c, 0x32, 0xff, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x0c, 0xf1, 0x00, 0x00, 0x00, 0x0c, 0xff, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0xff, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0xff, 0x10, 0x00, 0x00, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xc7, 0x8f, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0x30, 0x00, 0x00, 0xf3, 0xcf, 0xff, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0x70, 0x00, 0x08, 0xf1, 0xff, 0xff, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0xf1, 0x00, 0x0f, 0x78, 0xff, 0xff, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0xf7, 0x00, 0xef, 0x3e, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf3, 0xcf, 0xff, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0x78, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xff, 0xff, 0xff, 0x1e, 0xff, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xff, 0xff, 0xf3, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xff, 0xff, 0xf0, 0xef, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xff, 0xff, 0x38, 0xff, 0xff, 0xff, 0x70, 0x00, 0xcf, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xff, 0x3f, 0xff, 0x0e, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x0c, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0x0f, 0xf3, 0x8f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc7, 0x0f, 0x91, 0xef, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x09, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xcf, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0xff, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0c, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0xcf, 0xff, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xf0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x0c, 0xff, 0xf7, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0e, 0xff, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x0c, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x8f, 0xff, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0xcf, 0x10, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0c, 0xff, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x8f, 0xff, 0xff, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x0c, 0x70, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x0e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x0f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xff, 0xff, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x0c, 0xff, 0xff, 0xff, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x0f, 0xff, 0x9f, 0xff, 0xff, 0xf0, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x0c, 0xf3, 0x8f, 0xff, 0xff, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0xf1, 0xcf, 0xff, 0x70, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x10, 0x00, 0x80, 0xef, 0xf7, 0x00, 0x08, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0xf0, 0x00, 0x88, 0xff, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0xc3, 0x00, 0xce, 0x10, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x0f, 0x10, 0xc7, 0x00, 0x00, 0x08, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x08, 0xf1, 0xe1, 0x00, 0x00, 0x0f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0xef, 0x70, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x8f, 0xff, 0x70, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x08, 0xff, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x8f, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	.byte 
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/bootstd.h linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/bootstd.h
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/bootstd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/bootstd.h	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,132 @@
+/* bootstd.h:  Bootloader system call interface
+ *
+ * (c) 1999, Rt-Control, Inc.
+ */
+
+#ifndef __BOOTSTD_H__
+#define __BOOTSTD_H__
+
+#define NR_BSC 21            /* last used bootloader system call */
+
+#define __BN_reset        0  /* reset and start the bootloader */
+#define __BN_test         1  /* tests the system call interface */
+#define __BN_exec         2  /* executes a bootloader image */
+#define __BN_exit         3  /* terminates a bootloader image */
+#define __BN_program      4  /* program FLASH from a chain */
+#define __BN_erase        5  /* erase sector(s) of FLASH */
+#define __BN_open         6
+#define __BN_write        7
+#define __BN_read         8
+#define __BN_close        9
+#define __BN_mmap         10 /* map a file descriptor into memory */
+#define __BN_munmap       11 /* remove a file to memory mapping */
+#define __BN_gethwaddr    12 /* get the hardware address of my interfaces */
+#define __BN_getserialnum 13 /* get the serial number of this board */
+#define __BN_getbenv      14 /* get a bootloader envvar */
+#define __BN_setbenv      15 /* get a bootloader envvar */
+#define __BN_setpmask     16 /* set the protection mask */
+#define __BN_readenv      17 /* read environment variables */
+#define __BN_flash_chattr_range		18
+#define __BN_flash_erase_range		19
+#define __BN_flash_write_range		20
+
+/* Calling conventions compatible to (uC)linux/68k
+ * We use simmilar macros to call into the bootloader as for uClinux
+ */
+
+#define __bsc_return(type, res) \
+do { \
+   if ((unsigned long)(res) >= (unsigned long)(-64)) { \
+      /* let errno be a function, preserve res in %d0 */ \
+      int __err = -(res); \
+      errno = __err; \
+      res = -1; \
+   } \
+   return (type)(res); \
+} while (0)
+
+#define _bsc0(type,name) \
+type name(void) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc1(type,name,atype,a) \
+type name(atype a) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc2(type,name,atype,a,btype,b) \
+type name(atype a, btype b) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc3(type,name,atype,a,btype,b,ctype,c) \
+type name(atype a, btype b, ctype c) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
+type name(atype a, btype b, ctype c, dtype d) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   register long __d __asm__ ("%d4") = (long)d; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c), "d" (__d) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
+type name(atype a, btype b, ctype c, dtype d, etype e) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   register long __d __asm__ ("%d4") = (long)d; \
+   register long __e __asm__ ("%d5") = (long)e; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c), "d" (__d), "d" (__e) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#endif /* __BOOTSTD_H__ */
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/config.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/config.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/config.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,200 @@
+/*
+ *  linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999 D. Jeff Dionne
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+
+
+#ifdef CONFIG_DRAGONIXVZ_JTAGFPGA
+#include "jblaster.h"
+	//extern int jbi_main();
+	extern unsigned char rtccmosinvalid(void);
+	extern void rtcchargebattery(void);
+	extern unsigned char lcdsetcontrast(void);
+        extern void gethwaddr(unsigned char dev, unsigned char *addr);
+        extern void rtcgetintern(void);
+        extern void rtcgettod(int *yearp, int *monp, int *dayp, int *hourp, int *minp, int *secp);
+#ifdef CONFIG_DRAGONIX_SPI
+	/* Include function specific to dragonix hardware */
+	extern void dragonixrtc_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec);
+	extern int dragonixrtc_set_clock_mmss(unsigned long nowtime);
+#endif
+#endif
+
+#include <asm/MC68VZ328.h>
+
+void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
+{
+#ifdef CONFIG_DRAGONBALL_USE_RTC
+  /* Enable RTC */
+  RTCCTL|=RTCCTL_EN;
+  /* Enable 128Hz interrupt line */
+  RTCIENR|=RTCIENR_SAM5;
+  request_irq(SAM_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+#else
+  /* Restart mode, Enable int, 32KHz, Enable timer */
+  TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
+  /* Set prescaler (Divide 32.768KHz by 1)*/
+  TPRER = 0;
+  /* Set compare register  32.768Khz / 32 / 10 = 100 */
+  TCMP = 327;
+  request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+#endif
+}
+
+void BSP_tick(void)
+{
+#ifdef CONFIG_DRAGONBALL_USERTC
+        RTCISR|=RTCISR_SAM5;
+#else
+	/* Reset Timer1 */
+        TSTAT &= 0;
+#endif
+
+}
+
+unsigned long BSP_gettimeoffset (void)
+{
+  return 0;
+}
+
+void BSP_gettod (int *yearp, int *monp, int *dayp,
+		   int *hourp, int *minp, int *secp)
+{
+ rtcgettod(yearp, monp, dayp, hourp, minp, secp);
+}
+
+int BSP_hwclk(int op, struct hwclk_time *t)
+{
+  if (!op) {
+    /* read */
+  } else {
+    /* write */
+  }
+  return 0;
+}
+
+int BSP_set_clock_mmss (unsigned long nowtime)
+{
+#if 0
+  short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+
+  tod->second1 = real_seconds / 10;
+  tod->second2 = real_seconds % 10;
+  tod->minute1 = real_minutes / 10;
+  tod->minute2 = real_minutes % 10;
+#endif
+  return 0;
+}
+
+void BSP_reset (void)
+{
+  cli();
+  asm volatile ("
+    moveal #0x02000000, %a0;
+    moveb #0, 0xFFFFF300;
+    moveal 0(%a0), %sp;
+    moveal 4(%a0), %a0;
+    jmp (%a0);
+    ");
+}
+
+unsigned char cs8900a_hwaddr1[6],cs8900a_hwaddr2[6];
+static int errno;
+
+void config_BSP(char *command, int len)
+{
+  int year, mon, day, hour, min, sec;
+  printk("\nDragonixVZ support by Daniel Haensse daniel.haensse@dragonix.net\n");
+  #ifdef CONFIG_DRAGONIXVZ_JTAGFPGA
+        jb_main();
+        /* FIXME hack to mask fpga interrupt controller */
+        *(volatile unsigned  char *)0x04000100 = 0x07; /* Mask RS232C Interrupts  */
+        *(volatile unsigned  char *)0x04000104 = 0x01; /* Mask Pen IRQ  */
+
+        /* Make serial port ready, looks like this is not done in the serial port driver, because people
+           use to send characters over the first serial line right after start */
+        #ifdef CONFIG_68328_SERIAL
+                #ifdef CONFIG_68328_SERIAL_RTS_CTS
+                        PESEL=(PESEL&0x0f);
+                #else
+                        PESEL=(PESEL&0x0f)|0xc0;
+                #endif
+                #ifdef CONFIG_68328_SERIAL_UART2
+                        #ifdef CONFIG_68328_SERIAL_UART2_RTS_CTS
+                                PJSEL=(PJSEL&0x0f);
+                        #else
+                                PJSEL=(PJSEL&0x0f)|0xc0;
+                        #endif
+                #endif
+        #endif
+        /* No we do some real initialisation */
+        /* First let us check if CMOS content is valid, if not, validate it within the function */
+        if(rtccmosinvalid())
+        {
+         printk("\nOops, CMOS is invalid, defaults set\n");
+        }
+        /* Get date & time */
+        rtcgettod(&year, &mon, &day,&hour, &min, &sec);
+        printk("\n%02d.%02d.20%02d %02d:%02d:%02d\n",day,mon,year,hour,min,sec);
+        /* switch on cell charger because we want it to be valid in the future as well :-) */
+        printk("Lithium cell trickle charger enabled\n");
+        rtcchargebattery();
+        /* Switch on the contrast of the display */
+        printk("Contrast controller set to 0x%x\n",lcdsetcontrast());
+
+        /* CS8900 MAC Address */
+        gethwaddr(0,cs8900a_hwaddr1);
+        printk("1st cs8900: hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+        cs8900a_hwaddr1[0], cs8900a_hwaddr1[1], cs8900a_hwaddr1[2], cs8900a_hwaddr1[3], cs8900a_hwaddr1[4], cs8900a_hwaddr1[5]);
+        /* We probe later in the cs8900 for it */
+        gethwaddr(1,cs8900a_hwaddr2);
+        printk("2st cs8900: hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+        cs8900a_hwaddr2[0], cs8900a_hwaddr2[1], cs8900a_hwaddr2[2], cs8900a_hwaddr2[3], cs8900a_hwaddr2[4], cs8900a_hwaddr2[5]);
+
+        /* Read date from external RTC */
+        rtcgetintern();
+  #endif
+
+  printk("68VZ328 DragonBallVZ support (c) 2001 Lineo, Inc.\n");
+
+  command[0] = 0;
+
+  mach_sched_init      = BSP_sched_init;
+  mach_tick            = BSP_tick;
+#ifdef CONFIG_DRAGONIX_SPI
+  mach_gettimeoffset   = BSP_gettimeoffset;
+  mach_gettod          = dragonixrtc_gettod;
+  mach_hwclk           = NULL;
+  mach_set_clock_mmss  = dragonixrtc_set_clock_mmss;
+#else
+  mach_gettimeoffset   = BSP_gettimeoffset;
+  mach_gettod          = BSP_gettod;
+  mach_hwclk           = NULL;
+  mach_set_clock_mmss  = NULL;
+#endif
+  // mach_mksound         = NULL;
+  mach_reset           = BSP_reset;
+  // mach_debug_init      = NULL;
+
+  config_M68VZ328_irq();
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/crt0_fixed.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/crt0_fixed.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/crt0_fixed.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/crt0_fixed.S	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,312 @@
+	.global _start
+	.global _stext
+
+	.global _rambase
+	.global _ramvec
+	.global _ramstart
+	.global _ramend
+	.global splash_bits
+
+#include <linux/config.h>
+#define IMR 0xFFFFF304
+#define INIT_LCD
+/* #undef INIT_LCD */
+	.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+splash_bits:
+#include "bootlogo.rh"
+	.text
+_start:
+_stext:
+
+	nop
+
+	moveb	#0x00,   0xfffffb0b	/* Watchdog off */
+	moveb	#0x10,   0xfffff000	/* SCR */
+
+	movew   #0x2483, 0xfffff200	/* PLLCR */
+	movew   #0x0347, 0xfffff202	/* PLLFSR */
+
+        /* Set special purpose bits of ports*/
+	moveb	#0xc0,   0xfffff40b	/* Chip select */
+	moveb	#0x00,   0xfffff413	/* LCD */
+        moveb	#0xcf,   0xfffff423	/* RXD1 and TXD1 */
+        moveb	#0x02,   0xfffff42b	/* A,CSA and CLKO */
+        moveb   #0xfd,   0xfffff443     /* R/W enable for flash*/
+        moveb	#0x3c,   0xfffff433	/* A0 and DTACK */
+        moveb	#0x20,   0xfffff44b	/* SDRAM */
+	moveb	#0x08,   0xfffffd0d	/* disable hardmap */
+	moveb	#0x07,   0xfffffd0e	/* level 7 interrupt clear */
+
+        movew   #0x8000, 0xfffff108     /* Full decode A31:A29=0 */
+
+        /* set flash size */
+        movew   #0x1000, 0xfffff100     /* Start at 0x2000000 with flash */
+#if defined ( CONFIG_FLASH2MB )
+        #ifdef CONFIG_FLASH2WS
+                movew	#0x0197, 0xfffff110	/* 2x1Meg, 16bit, enable, 2ws */
+        #else
+	        movew	#0x0187, 0xfffff110	/* 2x1Meg, 16bit, enable, 0ws */
+        #endif
+#elif defined ( CONFIG_FLASH4MB )
+        #ifdef CONFIG_FLASH2WS
+                movew	#0x0199, 0xfffff110	/* 2x2Meg, 16bit, enable, 2ws */
+        #else
+	        movew	#0x0189, 0xfffff110	/* 2x2Meg, 16bit, enable, 0ws */
+        #endif
+#elif defined ( CONFIG_FLASH8MB )
+        #ifdef CONFIG_FLASH2WS
+                movew	#0x019B, 0xfffff110	/* 2x4Meg, 16bit, enable, 2ws */
+        #else
+	        movew	#0x018B, 0xfffff110	/* 2x4Meg, 16bit, enable, 0ws */
+        #endif
+#elif defined ( CONFIG_FLASH16MB )
+        #ifdef CONFIG_FLASH2WS
+                movew	#0x019D, 0xfffff110	/* 2x8Meg, 16bit, enable, 2ws */
+        #else
+	        movew	#0x018D, 0xfffff110	/* 2x8Meg, 16bit, enable, 0ws */
+        #endif
+#else
+        #error "No flash size defined"
+#endif
+
+        movew   #0x2000, 0xfffff102     /* Start at 0x4000000 with FPGA and ethernet */
+
+        movew   #0x01ff, 0xfffff112     /* use 16MB size, external DTACK */
+#if defined ( CONFIG_RAM8MB )
+        movew   #0x0000, 0xfffff106     /* CSD init at $0 */
+        movew   #0x0281, 0xfffff116     /* enable SDRAM cs */
+        movew   #0x0040, 0xfffff10a     /* chip select control */
+        movew   #0x0000, 0xfffffc02     /* DRAMC disable */
+        movew   #0xc03f, 0xfffffc04     /* SDCTRL use PA22 and PA21, CAS=1, RACL=3CLK */
+        movew   #0x4020, 0xfffffc00     /* DRAMMC double CLK32 for refresh */
+        movew   #0x8000, 0xfffffc02     /* DRAMC */
+        movew   #0xc83f, 0xfffffc04     /* SDCTRL precharge */
+	movew	#32767, %d0             /* SDRAM wait loop */
+SDL0:
+	subw	#1, %d0
+	bne	SDL0
+        movew   #0xD03f, 0xfffffc04     /* SDCTRL enable refresh */
+	movew	#32767, %d0             /* SDRAM wait loop */
+SDL1:
+	subw	#1, %d0
+	bne	SDL1
+        movew   #0xD43f, 0xfffffc04     /* SDCTRL set mode registers in SDRAM */
+        movew	#32767, %d0             /* SDRAM wait loop */
+SDL2:
+	subw	#1, %d0
+	bne	SDL2
+#elif defined ( CONFIG_RAM32MB )
+        movew   #0x0000, 0xfffff106     /* CSD init at $0 */
+        movew   #0x0683, 0xfffff116     /* enable SDRAM cs */
+        movew   #0x0040, 0xfffff10a     /* chip select control */
+        movew   #0x0000, 0xfffffc02     /* DRAMC disable */
+        movew   #0xc03f, 0xfffffc04     /* SDCTRL use PA24 and PA23, CAS=1, RACL=3CLK */
+        movew   #0x0F80, 0xfffffc00     /* DRAMMC double CLK32 for refresh */
+        movew   #0x8000, 0xfffffc02     /* DRAMC */
+        movew   #0xc83f, 0xfffffc04     /* SDCTRL precharge */
+	movew	#32767, %d0             /* SDRAM wait loop */
+SDL0:
+	subw	#1, %d0
+	bne	SDL0
+        movew   #0xD03f, 0xfffffc04     /* SDCTRL enable refresh */
+	movew	#32767, %d0             /* SDRAM wait loop */
+SDL1:
+	subw	#1, %d0
+	bne	SDL1
+        movew   #0xD43f, 0xfffffc04     /* SDCTRL set mode registers in SDRAM */
+        movew	#32767, %d0             /* SDRAM wait loop */
+SDL2:
+	subw	#1, %d0
+	bne	SDL2
+#else
+        #error "No sdram size defined"
+#endif
+
+	moveb	#0x40,   0xfffff300	/* IVR */
+	movel	#0x007FFFFF, %d0	/* IMR */
+	movel	%d0,     0xfffff304
+
+	/*moveb   0xfffff42b, %d0
+	andb    #0xe0,   %d0
+	moveb   %d0,     0xfffff42b*/
+
+	moveb	#0x08,   0xfffff907	/* Ignore CTS */
+	movew	#0x0138, 0xfffff902	/* BAUD to 115.2k */
+	movew	#0xe100, 0xfffff900	/* enable */
+
+	moveb   #0,      0xfffffA27	/* LCKCON - LCD is off */
+
+
+#ifdef INIT_LCD
+        /* FIXME add code for display here */
+	movel	#__vram_start, 0xfffffA00 /* LSSA */
+	moveb	#15,   0xfffffA05	/* LVPW */
+	movew	#240,  0xFFFFFa08	/* LXMAX */
+	movew	#320,  0xFFFFFa0a	/* LYMAX */
+	moveb	#0,      0xfffffa29	/* LBAR */
+	moveb	#0,      0xfffffa25	/* LPXCD */
+	moveb	#0x08,   0xFFFFFa20	/* LPICF */
+	moveb	#0x00,   0xFFFFFA21	/* +ve pol (without backlight)*/
+        moveb   #0x0,    0xFFFFFA23     /* LACD toggle rate*/
+	moveb	#0x80,   0xfffffA27	/* LCKCON */
+	movew	#0xff00, 0xfffff412	/* LCD pins */
+        moveb	#0xc0,   0xfffff408	/* DispEn, BLEn both Outputs */
+        moveb	#0xc0,   0xfffff409	/* Enable Display, no backlight */
+        /* Copy data segment from ROM to RAM */
+	moveal	#splash_bits, %a0
+	moveal	#__vram_start, %a1
+	moveal	#__vram_end, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+DC1:
+	movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bhi	DC1
+#endif
+
+#if defined ( CONFIG_RAM8MB )
+	moveal  #__ramend8MB - 0x10, %sp
+#elif defined ( CONFIG_RAM32MB )
+        moveal  #__ramend32MB - 0x10, %sp
+#else
+        #error "No sdram size defined"
+#endif
+	movew	#0x2700, %sr
+
+	moveq	#13, %d7		/* '\r' */
+	jsr putc
+
+	moveq	#10, %d7		/* '\n' */
+	jsr putc
+
+	moveq	#65, %d7		/* 'A' */
+	jsr putc
+
+	movew	#32767, %d0  /* PLL settle wait loop */
+L0:
+	subw	#1, %d0
+	bne	L0
+
+	moveq	#66, %d7		/* 'B' */
+	jsr	putc
+#ifdef CONFIG_RAMKERNEL
+	/* Copy me from ROM to RAM */
+	moveal	#__rom_start, %a0
+	moveal	#__ram_start, %a1
+	moveal	#__data_end, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:    movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bhi	LD1
+        /* jump into the RAM copy */
+        jmp     ram_jump
+ram_jump:
+#else
+	/* Copy data segment from ROM to RAM */
+	moveal	#__data_rom_start, %a0
+	moveal	#_sdata, %a1
+	moveal	#_edata, %a2
+	moveq	#67, %d7		/* 'C' */
+	jsr	putc
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:
+	movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bhi	LD1
+#endif
+
+	moveq	#68, %d7		/* 'D' */
+	jsr	putc
+
+	moveal	#_sbss, %a0
+	moveal	#_ebss, %a1
+	/* Copy 0 to %a0 until %a0 == %a1 */
+
+_clear_bss:
+	movel	#0, %a0@+
+	cmpal	%a0, %a1
+	bhi	_clear_bss
+
+        movel   #_sdata, %d0
+        movel   %d0,    _rambase
+        movel   #_ebss,  %d0
+        movel   %d0,    _ramstart
+#if defined ( CONFIG_RAM8MB )
+        movel	#__ramend8MB, %d0
+#elif defined ( CONFIG_RAM32MB )
+        movel	#__ramend32MB, %d0
+#else
+        #error "No sdram size defined"
+#endif
+        
+	movel	%d0,	_ramend
+	movel	#__ramvec,	%d0
+	movel	%d0,	_ramvec
+
+	moveq	#69, %d7		/* 'E' */
+	jsr	putc
+
+        /*
+         * load the current task pointer and stack
+         */
+        lea     init_task_union,%a0
+        movel   %a0, _current_task
+        lea     0x2000(%a0),%sp
+
+	/*
+	pea	0
+	pea	env
+	pea	%sp@(4)
+	pea	0
+	*/
+
+	moveq	#70, %d7		/* 'F' */
+	jsr	putc
+
+ 	moveq	#13, %d7		/* '\r' */
+	jsr putc
+
+	moveq	#10, %d7		/* '\n' */
+	jsr putc
+
+lp:
+	jsr	start_kernel
+        jmp lp
+_exit:
+
+	jmp	_exit
+
+
+putc:
+	moveb	%d7,0xfffff907
+pclp:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	pclp
+	rts
+
+	.data
+env:
+	.long	0
+	.text
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/crt0_himem.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/crt0_himem.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/crt0_himem.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/crt0_himem.S	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/crt0_ram.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/crt0_rom.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/crt0_rom.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/crt0_rom.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/crt0_rom.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/fixed.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/fixed.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/fixed.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/fixed.ld	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,108 @@
+SECTIONS
+{
+  .romvec :
+	{
+	_flashstart = . ;
+	_romvec = . ;
+	__rom_start = . ;
+	} > romvec
+
+  .text :
+	{
+	_stext = . ;
+        	*(.text)
+	. = ALIGN(0x4) ;
+		*(.text.*)
+	. = ALIGN(0x4) ;
+		*(.exitcall.exit)
+	. = ALIGN(0x4) ;
+                *(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	. = ALIGN(0x4) ;
+	_etext = . ;
+	__data_rom_start = . ;
+        } > flash
+
+  .eflash :
+	{
+	_flashend = . ;
+	} > eflash
+
+  .ramvec :
+	{
+	__ram_start = . ;
+	__ramvec = . ;
+	} > ramvec
+  .framebuf :
+	{
+        __vram_start = . ;
+	} > framebuf
+  .eframebuf :
+	{
+        __vram_end = . ;
+	} > eframebuf
+  .data : AT(_etext)
+	{
+	. = ALIGN(0x4) ;
+	_sdata = . ;
+	__data_start = . ;
+
+	. = ALIGN(0x4) ;
+		*(.rodata)
+	. = ALIGN(0x4) ;
+		*(.rodata.str1.1)
+	. = ALIGN(0x4) ;
+		*(.data)
+	. = ALIGN(0x4) ;
+		*(.data.*)
+
+	. = ALIGN(0x4) ;
+	__setup_start = .;
+		*(.setup.init)
+	. = ALIGN(0x4) ;
+	__setup_end = .;
+
+	. = ALIGN(0x4) ;
+	__initcall_start = .;
+		*(.initcall.init)
+	. = ALIGN(0x4) ;
+	__initcall_end = .;
+
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	. = ALIGN(0x2000) ;
+
+	_edata = . ;
+        } > ram
+
+  .bss :
+        {
+	. = ALIGN(0x4) ;
+	_sbss = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	_ebss = . ;
+	_end = . ;
+	} > ram
+
+  .eram8MB :
+	{
+	__ramend8MB = . ;
+        __ramend = . ;
+	} > eram8MB
+  .eram32MB :
+	{
+	__ramend32MB = . ;
+	} > eram32MB
+
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/hardware.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/hardware.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/hardware.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/hardware.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,312 @@
+/*
+ *  linux/arch/m68knommu/platform/68VZ328/dragonixvz/hardware.c
+ *
+ *  (C)  2002 by      Daniel Haensse <daniel.haensse@alumni.ethz.ch>
+ *  Use it under GPL
+ */
+
+/* Common functions */
+
+#include <asm/MC68VZ328.h>
+
+
+
+
+void putC (char ch)
+{
+	UTX_TXDATA = ch;
+	while (!(UTX & 0x2000));
+}
+
+void putS (char * str)
+{
+	while (*str) putC (*(str++));
+}
+void printhex (unsigned long n)
+{
+unsigned long	i;
+	if ((i = n / 16)) printhex (i);
+	if (n % 16 > 9) putC (n % 16 + '7');
+	else putC (n % 16 + '0');
+}
+
+
+void uwait(unsigned long x)
+{
+ int loop;
+ while(x>0)
+ {
+  for(loop=0;loop<10;loop++);
+  x--;
+ }
+}
+
+/* SPI functions */
+
+#define NONE 0
+#define PEN  1
+#define CLK  2
+
+
+unsigned long SPIIO(unsigned char chip, unsigned long shifts, unsigned long out)
+{
+ int loop;
+ unsigned long in=0;
+
+ *(volatile unsigned  char *)0x4000103=(chip&0x03);
+ uwait(5);
+
+ for(loop=shifts;loop>0;loop--)
+ {
+  *(volatile unsigned  char *)0x4000103= (((out&(1<<(loop-1)))!=0 ? 0x10 : 0x00) | (chip&0x03));        /* data out */
+  uwait(1);
+  *(volatile unsigned  char *)0x4000103= (((out&(1<<(loop-1)))!=0 ? 0x10 : 0x00) | (chip&0x03) | 0x04); /* clk */
+  uwait(5);
+  in=(in<<1) | (((*(volatile unsigned  char *)0x4000103)&0x10)>>4);
+  uwait(5);
+  *(volatile unsigned  char *)0x4000103= (((out&(1<<(loop-1)))!=0 ? 0x10 : 0x00) | (chip&0x03));        /* data out */
+  uwait(5);
+ }
+ *(volatile unsigned  char *)0x4000103=0; /* deselect all */
+ return(in);
+}
+
+
+/* I2C Functions */
+
+unsigned char I2CStart()
+{
+ *(volatile unsigned  char *)0x4000102= 0x0f; /* SDA=1 , SCL =1 */
+ uwait(5);
+ *(volatile unsigned  char *)0x4000102= 0x0b; /* SDA=0 , SCL =1 */
+ uwait(5);
+ *(volatile unsigned  char *)0x4000102= 0x0a; /* SDA=0 , SCL =0 */
+ uwait(5);
+}
+
+void I2CACK()
+{
+
+ *(volatile unsigned  char *)0x4000102= 0x0b; /* SDA=0 , SCL =1 */
+ uwait(5);
+ *(volatile unsigned  char *)0x4000102= 0x0a; /* SDA=0 , SCL =0 */
+ uwait(5);
+}
+
+void I2CNACK()
+{
+ *(volatile unsigned  char *)0x4000102= 0x0f; /* SDA=1 , SCL =1 */
+ uwait(5);
+ *(volatile unsigned  char *)0x4000102= 0x0e; /* SDA=1 , SCL =0 */
+ uwait(5);
+}
+
+
+unsigned char I2CSendByte(unsigned char data)
+{
+ int loop;
+ for(loop=0;loop<8;loop++)
+ {
+  if(data&0x80)
+  {
+   *(volatile unsigned  char *)0x4000102= 0x0e; /* SDA=1 , SCL =0 */
+   uwait(1);
+   *(volatile unsigned  char *)0x4000102= 0x0f; /* SDA=1 , SCL =1 */
+   uwait(5);
+   *(volatile unsigned  char *)0x4000102= 0x0e; /* SDA=1 , SCL =0 */
+   uwait(5);
+
+  }
+  else
+  {
+   *(volatile unsigned  char *)0x4000102= 0x0a; /* SDA=0 , SCL =0 */
+   uwait(1);
+   *(volatile unsigned  char *)0x4000102= 0x0b; /* SDA=0 , SCL =1 */
+   uwait(5);
+   *(volatile unsigned  char *)0x4000102= 0x0a; /* SDA=0 , SCL =0 */
+   if(loop!=7)
+   {
+    uwait(5);
+   }
+  }
+  data=data<<1;
+ }
+ *(volatile unsigned  char *)0x4000102= 0x02; /* SDA=Z , SCL =0 */
+ uwait(5);
+ *(volatile unsigned  char *)0x4000102= 0x03; /* SDA=Z , SCL =1 */
+ uwait(5);
+ loop=((*(volatile unsigned  char *)0x4000102) & 0x04)>>2;
+ uwait(5);
+ *(volatile unsigned  char *)0x4000102= 0x0e; /* SDA=1 , SCL =0 */
+ uwait(5);
+}
+
+unsigned char I2CGetByte()
+{
+ int loop;
+ unsigned char data=0;
+ for(loop=0;loop<8;loop++)
+ {
+  *(volatile unsigned  char *)0x4000102= 0x02; /* SDA=Z , SCL =0 */
+  uwait(5);
+  *(volatile unsigned  char *)0x4000102= 0x03; /* SDA=Z , SCL =1 */
+  uwait(5);
+  data|=((*(volatile unsigned  char *)0x4000102) & 0x04)<<5;
+  uwait(5);
+  *(volatile unsigned  char *)0x4000102= 0x02; /* SDA=Z , SCL =0 */
+ }
+ *(volatile unsigned  char *)0x4000102= 0x0a; /* SDA=0 , SCL =0 */
+ uwait(5);
+ return(data);
+}
+
+unsigned char I2CStop()
+{
+ *(volatile unsigned  char *)0x4000102= 0x0a; /* SDA=0 , SCL =0 */
+ uwait(5);
+ *(volatile unsigned  char *)0x4000102= 0x0b; /* SDA=0 , SCL =1 */
+ uwait(5);
+ *(volatile unsigned  char *)0x4000102= 0x0f; /* SDA=1 , SCL =1 */
+ uwait(5);
+}
+
+/* Abstract functions, please keep the functions untouched when we improve the functionality of the FPGA */
+
+unsigned char BCD_TO_BIN(unsigned char val)
+{
+        return( ((val)&15) + ((val)>>4)*10 );
+}
+
+/* Read Real Time Clock Location */
+unsigned char RTCRead(unsigned int addr)
+{
+ return( SPIIO(CLK,16,addr<<8) &0xff );
+}
+
+/* Write Real Time Clock Location */
+void RTCWrite(unsigned int addr,unsigned char data)
+{
+ SPIIO(CLK,16,(addr<<8)|0x8000 | data);
+}
+
+
+/* Set Contrast Voltage, see pdf for table */
+void SetContrast(unsigned char data)
+{
+ I2CStart();                                          /* Send start bit */
+ I2CSendByte(0x58);
+ I2CSendByte(data);
+ I2CStop();
+}
+
+/* Backlight */
+void BacklightOn()
+{
+ *(volatile unsigned  char *) 0xfffff409 &=~0x80;
+}
+
+void BacklightOff()
+{
+ *(volatile unsigned  char *) 0xfffff409 |=0x80;
+}
+
+/* We use the following mapping of the cmos ram */
+/*
+        0x20 xor crc of memory 0x21 to 0x7F
+        0x21 lcdcontrast
+        0x22,0x23,0x24,0x25,0x26,0x27 mac address 1
+        0x28,0x29,0x2a,0x2b,0x2c,0x2d mac address 2
+        0x2e and following are unused
+*/
+
+unsigned char rtccmosinvalid()
+{
+ unsigned char crccalc=0,crc;
+ unsigned int addr;
+ crc=RTCRead(0x20);
+ for(addr=0x21;addr<0x80;addr++)  crccalc^=RTCRead(addr);
+ if(crc!=crccalc)
+ {
+ /* Folks if you use a display that needs a voltage,
+    change this otherwise it will be destroyed  */
+        RTCWrite(0x0f,0x00);    /* Remove write protection */
+        RTCWrite(0x21,0x00);    /* Switch contrast off */
+        RTCWrite(0x22,0x00);    /* Mac 1 */
+        RTCWrite(0x23,0x08);
+        RTCWrite(0x24,0x9D);
+        RTCWrite(0x25,0x00);
+        RTCWrite(0x26,0x00);
+        RTCWrite(0x27,0x00);
+        RTCWrite(0x28,0x00);    /* Mac 2 */
+        RTCWrite(0x29,0x08);
+        RTCWrite(0x2a,0x9D);
+        RTCWrite(0x2b,0x00);
+        RTCWrite(0x2c,0x00);
+        RTCWrite(0x2d,0x01);
+        crccalc=0;
+        for(addr=0x21;addr<0x80;addr++)  crccalc^=RTCRead(addr);
+        RTCWrite(0x20,crccalc); /* Revalidate CMOS, leave time unchanged */
+        RTCWrite(0x0f,0x40);    /* Enable write protection */
+        return(0x01);
+ }
+ else
+        return(0x00);
+}
+
+/* Charge Lithium Battery */
+void rtcchargebattery()
+{
+ RTCWrite(0x0f,0x00);    /* Remove write protection */
+ RTCWrite(0x11,0xa5);    /* 3.9-0.7V = 3.2V Zenervoltage sourced over 200R resistor and 2k serie resistor */
+ RTCWrite(0x0f,0x40);    /* Enable write protection */
+}
+
+void rtcgettod(int *yearp, int *monp, int *dayp, int *hourp, int *minp, int *secp)
+{
+	*secp   =       BCD_TO_BIN(RTCRead(0x00));
+	*minp   =       BCD_TO_BIN(RTCRead(0x01));
+	*hourp  =       BCD_TO_BIN(RTCRead(0x02));
+	*dayp   =       BCD_TO_BIN(RTCRead(0x04));
+	*monp   =       BCD_TO_BIN(RTCRead(0x05));
+	*yearp  =       BCD_TO_BIN(RTCRead(0x06));
+}
+
+/* LCD contrast */
+unsigned char lcdsetcontrast()
+{
+ unsigned char contr=RTCRead(0x21);
+ SetContrast(contr);
+ return(contr);
+}
+
+/* Get hardware address */
+void gethwaddr(unsigned char dev, unsigned char *addr)
+{
+ unsigned char i;
+ if(dev==0) // Mac 1
+ {
+  for(i=0;i<6;i++)
+  {
+   addr[i]=RTCRead(0x22+i);
+  }
+ }
+ else // Mac 2
+ {
+  for(i=0;i<6;i++)
+  {
+   addr[i]=RTCRead(0x28+i);
+  }
+ }
+}
+
+/* Copy date from external to internal RTC */
+void rtcgetintern()
+{
+ /* We must run the RTC in 24 hour mode!!! */
+/* RTCTIME=BCD_TO_BIN(RTCRead(0x00))
+        |(BCD_TO_BIN(RTCRead(0x01))<<16)
+        |(BCD_TO_BIN(RTCRead(0x02))<<24);
+  */
+
+}
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/himem.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/himem.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/himem.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/himem.ld	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,23 @@
+MEMORY
+	{
+        romvec : ORIGIN = 0x2000000, LENGTH = 0x0000400
+        flash  : ORIGIN = 0x2000400, LENGTH = 0x0200000 - 0x0000400
+        eflash : ORIGIN = 0x2200000, LENGTH = 0
+        ramvec : ORIGIN = 0x0000000, LENGTH = 0x0000400
+        framebuf : ORIGIN = 0x0000400, LENGTH = 0x002fc00
+        eframebuf : ORIGIN = 0x0030000, LENGTH = 0
+        ram    : ORIGIN = 0x0030000, LENGTH = 0x2000000 - 0x0030000
+        eram8MB : ORIGIN = 0x0600000, LENGTH = 0
+        eram32MB : ORIGIN = 0x1e00000, LENGTH = 0
+	}
+MEMORY
+	{
+        romvec : ORIGIN = 0x01e00000, LENGTH = 1k
+        flash  : ORIGIN = 0x01e00400, LENGTH = 2M - 1k
+        eflash : ORIGIN = 0x02000000, LENGTH = 0
+        ramvec : ORIGIN = 0x00000000, LENGTH = 1k
+        ram    : ORIGIN = 0x00010000, LENGTH = 30M - 64k
+        eram   : ORIGIN = 0x01e00000, LENGTH = 0
+	}
+
+INCLUDE arch/m68knommu/platform/68VZ328/dragonixvz/fixed.ld
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/ints.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/ints.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/ints.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/ints.c	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,353 @@
+/*
+ * linux/arch/$(ARCH)/platform/dragonixvz/ints.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne <jeff@uClinux.org>
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+
+#include <asm/MC68VZ328.h>
+
+#define INTERNAL_IRQS (32)
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void exception3(void);
+asmlinkage void exception4(void);
+asmlinkage void exception5(void);
+asmlinkage void exception6(void);
+asmlinkage void exception7(void);
+asmlinkage void exception8(void);
+asmlinkage void exception9(void);
+asmlinkage void exception10(void);
+asmlinkage void exception11(void);
+asmlinkage void exception14(void);
+asmlinkage void exception15(void);
+asmlinkage void bad_interrupt(void);
+asmlinkage void inthandler1(void);
+asmlinkage void inthandler2(void);
+asmlinkage void inthandler3(void);
+asmlinkage void inthandler4(void);
+asmlinkage void inthandler5(void);
+asmlinkage void inthandler6(void);
+asmlinkage void inthandler7(void);
+asmlinkage void system_call(void);
+asmlinkage void trap1(void);
+asmlinkage void trap15(void);
+
+// extern void *_ramvec[];
+extern e_vector *_ramvec;
+
+/* irq node variables for the 32 (potential) on chip sources */
+static irq_node_t *int_irq_list[INTERNAL_IRQS];
+
+static int int_irq_count[INTERNAL_IRQS];
+static short int_irq_ablecount[INTERNAL_IRQS];
+
+static void int_badint(int irq, void *dev_id, struct pt_regs *fp)
+{
+	num_spurious += 1;
+}
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the amiga IRQ handling routines.
+ */
+
+void M68VZ328_init_IRQ(void)
+{
+	int i;
+
+	/* set up the vectors */
+        for (i=2; i < 32; ++i)
+                _ramvec[i] = bad_interrupt;
+
+        _ramvec[2] = buserr;
+        _ramvec[3] = exception3;
+        _ramvec[4] = exception4;
+        _ramvec[5] = exception5;
+        _ramvec[6] = exception6;
+        _ramvec[7] = exception7;
+        _ramvec[8] = exception8;
+        _ramvec[9] = exception9;
+        _ramvec[10] = exception10;
+        _ramvec[11] = exception11;
+        _ramvec[14] = exception14;
+        _ramvec[15] = exception15;
+        _ramvec[32] = system_call;
+        _ramvec[33] = trap1;
+        _ramvec[47] = trap15;
+
+        _ramvec[64] = bad_interrupt;
+        _ramvec[65] = inthandler1;
+        _ramvec[66] = inthandler2;
+        _ramvec[67] = inthandler3;
+        _ramvec[68] = inthandler4;
+        _ramvec[69] = inthandler5;
+        _ramvec[70] = inthandler6;
+        _ramvec[71] = inthandler7;
+ 
+	IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
+
+	/* initialize handlers */
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		int_irq_list[i] = NULL;
+
+		int_irq_ablecount[i] = 0;
+		int_irq_count[i] = 0;
+	}
+	/* turn off all interrupts */
+	IMR = ~0;
+}
+
+void M68VZ328_insert_irq(irq_node_t **list, irq_node_t *node)
+{
+	unsigned long flags;
+	irq_node_t *cur;
+
+	if (!node->dev_id)
+		printk("%s: Warning: dev_id of %s is zero\n",
+		       __FUNCTION__, node->devname);
+
+	save_flags(flags);
+	cli();
+
+	cur = *list;
+
+	while (cur) {
+		list = &cur->next;
+		cur = cur->next;
+	}
+
+	node->next = cur;
+	*list = node;
+
+	restore_flags(flags);
+}
+
+void M68VZ328_delete_irq(irq_node_t **list, void *dev_id)
+{
+	unsigned long flags;
+	irq_node_t *node;
+
+	save_flags(flags);
+	cli();
+
+	for (node = *list; node; list = &node->next, node = *list) {
+		if (node->dev_id == dev_id) {
+			*list = node->next;
+			/* Mark it as free. */
+			node->handler = NULL;
+			restore_flags(flags);
+			return;
+		}
+	}
+	restore_flags(flags);
+	printk ("%s: tried to remove invalid irq\n", __FUNCTION__);
+}
+
+int M68VZ328_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                         unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+	if (!int_irq_list[irq]) {
+		int_irq_list[irq] = new_irq_node();
+		int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	}
+
+	if (!(int_irq_list[irq]->flags & IRQ_FLG_STD)) {
+		if (int_irq_list[irq]->flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+	}
+	int_irq_list[irq]->handler = handler;
+	int_irq_list[irq]->flags   = flags;
+	int_irq_list[irq]->dev_id  = dev_id;
+	int_irq_list[irq]->devname = devname;
+
+	/* enable in the IMR */
+	if (!int_irq_ablecount[irq])
+		*(volatile unsigned long *)0xfffff304 &= ~(1<<irq);
+
+	return 0;
+}
+
+void M68VZ328_free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_list[irq]->dev_id != dev_id)
+		printk("%s: removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, int_irq_list[irq]->devname);
+	int_irq_list[irq]->handler = int_badint;
+	int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	int_irq_list[irq]->dev_id  = NULL;
+	int_irq_list[irq]->devname = NULL;
+
+	*(volatile unsigned long *)0xfffff304 |= 1<<irq;
+}
+
+/*
+ * Enable/disable a particular machine specific interrupt source.
+ * Note that this may affect other interrupts in case of a shared interrupt.
+ * This function should only be called for a _very_ short time to change some
+ * internal data, that may not be changed by the interrupt at the same time.
+ * int_(enable|disable)_irq calls may also be nested.
+ */
+
+void M68VZ328_enable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (--int_irq_ablecount[irq])
+		return;
+
+	/* enable the interrupt */
+	*(volatile unsigned long *)0xfffff304 &= ~(1<<irq);
+}
+
+void M68VZ328_disable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_ablecount[irq]++)
+		return;
+
+	/* disable the interrupt */
+	*(volatile unsigned long *)0xfffff304 |= 1<<irq;
+}
+
+/* The 68k family did not have a good way to determine the source
+ * of interrupts until later in the family.  The EC000 core does
+ * not provide the vector number on the stack, we vector everything
+ * into one vector and look in the blasted mask register...
+ * This code is designed to be fast, almost constant time, not clean!
+ */
+inline int M68VZ328_do_irq(int vec, struct pt_regs *fp)
+{
+	int irq;
+	int mask;
+
+	unsigned long pend = *(volatile unsigned long *)0xfffff30c;
+
+	while (pend) {
+		if (pend & 0x0000ffff) {
+			if (pend & 0x000000ff) {
+				if (pend & 0x0000000f) {
+					mask = 0x00000001;
+					irq = 0;
+				} else {
+					mask = 0x00000010;
+					irq = 4;
+				}
+			} else {
+				if (pend & 0x00000f00) {
+					mask = 0x00000100;
+					irq = 8;
+				} else {
+					mask = 0x00001000;
+					irq = 12;
+				}
+			}
+		} else {
+			if (pend & 0x00ff0000) {
+				if (pend & 0x000f0000) {
+					mask = 0x00010000;
+					irq = 16;
+				} else {
+					mask = 0x00100000;
+					irq = 20;
+				}
+			} else {
+				if (pend & 0x0f000000) {
+					mask = 0x01000000;
+					irq = 24;
+				} else {
+					mask = 0x10000000;
+					irq = 28;
+				}
+			}
+		}
+
+		while (! (mask & pend)) {
+			mask <<=1;
+			irq++;
+		}
+
+		if (int_irq_list[irq] && int_irq_list[irq]->handler) {
+			int_irq_list[irq]->handler(irq, int_irq_list[irq]->dev_id, fp);
+			int_irq_count[irq]++;
+		} else {
+			printk("unregistered interrupt %d!\nTurning it off in the IMR...\n", irq);
+			*(volatile unsigned long *)0xfffff304 |= mask;
+		}
+		pend &= ~mask;
+	}
+	return 0;
+}
+
+int M68VZ328_get_irq_list(char *buf)
+{
+	int i, len = 0;
+	irq_node_t *node;
+
+	len += sprintf(buf+len, "Internal 68VZ328 interrupts\n");
+
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		if (!(node = int_irq_list[i]))
+			continue;
+		if (!(node->handler))
+			continue;
+
+		len += sprintf(buf+len, " %2d: %10u    %s\n", i,
+		               int_irq_count[i], int_irq_list[i]->devname);
+	}
+	return len;
+}
+
+void config_M68VZ328_irq(void)
+{
+	mach_default_handler = NULL;
+	mach_init_IRQ        = M68VZ328_init_IRQ;
+	mach_request_irq     = M68VZ328_request_irq;
+	mach_free_irq        = M68VZ328_free_irq;
+	mach_enable_irq      = M68VZ328_enable_irq;
+	mach_disable_irq     = M68VZ328_disable_irq;
+	mach_get_irq_list    = M68VZ328_get_irq_list;
+	mach_process_int     = M68VZ328_do_irq;
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/jb_cdf.h linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/jb_cdf.h
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/jb_cdf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/jb_cdf.h	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,12 @@
+int device_count = 1;
+unsigned char buffer_0[]={0xFF ,0xFF ,0x62 ,0x7F ,0x39 ,0x0 ,0x80 ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xA0 ,0x9 ,0x94 ,0x81 ,0x32 ,0x50 ,0x6 ,0xC0 ,0x40 ,0x19 ,0x0 ,0x53 ,0x60 ,0xA ,0x4C ,0x80 ,0x29 ,0x30 ,0x50 ,0x6 ,0xCA ,0x0 ,0x18 ,0x0 ,0x3 ,0x66 ,0xA0 ,0xC ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x80 ,0x81 ,0x32 ,0x0 ,0x66 ,0xC0 ,0x0 ,0x18 ,0x28 ,0x3 ,0x65 ,0xA0 ,0xC ,0x34 ,0x1 ,0x32 ,0xE0 ,0x4 ,0xC0 ,0x4 ,0x98 ,0x1 ,0x3 ,0x65 ,0x0 ,0xC ,0x98 ,0x1 ,0x70 ,0xFD ,0x0 ,0x15 ,0xA0 ,0x2 ,0x54 ,0x80 ,0xA ,0x20 ,0x1 ,0x2A ,0x80 ,0xA ,0x50 ,0x1 ,0x3A ,0x40 ,0x5 ,0x48 ,0x80 ,0xA ,0x50 ,0x1 ,0x24 ,0x80 ,0x4 ,0xA8 ,0x0 ,0x15 ,0x40 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x12 ,0x40 ,0x2 ,0x54 ,0x0 ,0x15 ,0x20 ,0x1 ,0x24 ,0x40 ,0x5 ,0xA8 ,0x0 ,0x15 ,0xA0 ,0x2 ,0x5C ,0x80 ,0xA ,0xA0 ,0x3 ,0x54 ,0x80 ,0x4 ,0xA8 ,0x0 ,0x12 ,0xA0 ,0x2 ,0x48 ,0xFD ,0x0 ,0x0 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x4 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x30 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0xA2 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x4 ,0x0 ,0xA0 ,0x0 ,0x14 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x40 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x5 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x50 ,0x0 ,0x8 ,0x40 ,0x1 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x50 ,0x0 ,0x0 ,0x28 ,0x0 ,0x0 ,0xA0 ,0x0 ,0x60 ,0xF9 ,0x0 ,0x0 ,0x80 ,0x4 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x48 ,0x0 ,0x40 ,0x1 ,0x80 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x2 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x1 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x1 ,0x4 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x11 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x20 ,0x0 ,0x88 ,0xFB ,0x20 ,0x1 ,0x34 ,0x80 ,0x0 ,0x10 ,0x4 ,0x2 ,0x40 ,0x3 ,0x48 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x1A ,0x49 ,0x0 ,0x8 ,0x0 ,0xD ,0xA0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x6 ,0x50 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x5 ,0x0 ,0x0 ,0x0 ,0x80 ,0x46 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x81 ,0x1 ,0x0 ,0x34 ,0x0 ,0x30 ,0xFA ,0x80 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x3 ,0x20 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x41 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x2 ,0x0 ,0x0 ,0x80 ,0x6 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x60 ,0xFB ,0x80 ,0x81 ,0x30 ,0x10 ,0x0 ,0x42 ,0x40 ,0x0 ,0x0 ,0x3 ,0x61 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x8 ,0x0 ,0x3 ,0x20 ,0x40 ,0x0 ,0x80 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x42 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x4 ,0x0 ,0x0 ,0x80 ,0x7 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x20 ,0xFA ,0x80 ,0x8 ,0x30 ,0x2 ,0x6 ,0x0 ,0x4 ,0x0 ,0x0 ,0x3 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x80 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x16 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x80 ,0x46 ,0x1 ,0x0 ,0x1A ,0x5 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x12 ,0x48 ,0xF9 ,0x0 ,0x30 ,0x30 ,0x4 ,0x40 ,0x81 ,0x4 ,0x0 ,0x1 ,0x20 ,0x2 ,0x14 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x16 ,0x0 ,0x8 ,0x0 ,0x2 ,0xB ,0x41 ,0x1 ,0x0 ,0x80 ,0x88 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x40 ,0x44 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x2 ,0x0 ,0x80 ,0x4 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x20 ,0x88 ,0xFF ,0x60 ,0x0 ,0x3C ,0x80 ,0x7 ,0x70 ,0x20 ,0x6 ,0xC8 ,0x3 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x34 ,0x40 ,0x1E ,0xC0 ,0x3 ,0x38 ,0x10 ,0xF ,0x62 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0xB2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB ,0x4 ,0x0 ,0x0 ,0x80 ,0x7 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x8 ,0x0 ,0xC ,0x0 ,0x38 ,0xF9 ,0x0 ,0x40 ,0x30 ,0x20 ,0x6 ,0x80 ,0x0 ,0x18 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0xC ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x4 ,0x0 ,0x0 ,0x10 ,0xF0 ,0xFB ,0x0 ,0x5 ,0x30 ,0x0 ,0x16 ,0xC2 ,0x20 ,0x98 ,0x4 ,0x23 ,0x41 ,0x11 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0xC1 ,0x24 ,0x18 ,0x20 ,0x3 ,0x62 ,0x10 ,0xC ,0x1 ,0x1 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x88 ,0x4 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x10 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x40 ,0x4 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x80 ,0x0 ,0x20 ,0xFE ,0x20 ,0x48 ,0x14 ,0x2 ,0x0 ,0xD0 ,0x0 ,0x1A ,0x40 ,0x3 ,0x28 ,0x4 ,0x0 ,0x20 ,0x10 ,0x0 ,0x80 ,0x10 ,0xD8 ,0x0 ,0x82 ,0x40 ,0x10 ,0x8 ,0x21 ,0x1 ,0xA0 ,0x1 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x42 ,0x50 ,0x42 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x85 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8D ,0x1 ,0x0 ,0x4 ,0x1 ,0x64 ,0xFE ,0x0 ,0x0 ,0x20 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x40 ,0x10 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x41 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x81 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x10 ,0xF8 ,0xFA ,0x80 ,0x0 ,0x10 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x21 ,0x0 ,0x0 ,0x80 ,0x80 ,0x0 ,0x0 ,0x4 ,0x2 ,0x0 ,0x8 ,0x8 ,0x2 ,0x1 ,0x0 ,0xC ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0xC2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x18 ,0x4 ,0x0 ,0x0 ,0x0 ,0xC ,0x8 ,0x0 ,0x30 ,0x10 ,0xD0 ,0xF9 ,0x8 ,0x44 ,0x0 ,0x2 ,0x0 ,0x0 ,0x22 ,0x40 ,0x4 ,0x0 ,0x0 ,0x42 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x12 ,0x0 ,0x22 ,0x80 ,0x0 ,0x11 ,0x0 ,0x20 ,0x20 ,0x2 ,0x44 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x44 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0xB0 ,0x0 ,0x7B ,0xFD ,0x80 ,0x11 ,0x10 ,0x4 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1 ,0x23 ,0x22 ,0x42 ,0x0 ,0x80 ,0x85 ,0x0 ,0x0 ,0x10 ,0x0 ,0x8 ,0x50 ,0x4 ,0x8 ,0x21 ,0x4 ,0xC ,0x1 ,0x10 ,0x30 ,0x22 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x4C ,0x0 ,0x0 ,0x0 ,0x2 ,0xE1 ,0xFE ,0xE0 ,0x41 ,0x2C ,0x0 ,0x0 ,0xF0 ,0x20 ,0x1E ,0xC4 ,0x3 ,0x58 ,0x0 ,0x0 ,0xE0 ,0x0 ,0x0 ,0x80 ,0x5 ,0xF4 ,0x20 ,0xE ,0xC0 ,0x2 ,0x78 ,0x10 ,0xF ,0xE0 ,0x41 ,0x3C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x5 ,0x32 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x1 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF ,0x8 ,0x0 ,0x2C ,0x10 ,0xEA ,0xFE ,0x4 ,0x0 ,0x10 ,0x20 ,0x0 ,0xC0 ,0x80 ,0x18 ,0x0 ,0x3 ,0x20 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x4 ,0xC4 ,0x40 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x84 ,0x1 ,0x31 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x4 ,0x4 ,0x0 ,0x30 ,0x20 ,0xD2 ,0xFA ,0x0 ,0x11 ,0x21 ,0x0 ,0x0 ,0xC0 ,0x2 ,0x18 ,0x2 ,0x23 ,0x41 ,0x80 ,0x0 ,0x80 ,0x45 ,0x0 ,0x0 ,0x6 ,0xC0 ,0x4 ,0x58 ,0x4 ,0x3 ,0x64 ,0x22 ,0xC ,0x80 ,0x5 ,0x30 ,0x12 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0xC8 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2C ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4C ,0x0 ,0x0 ,0x30 ,0x1 ,0xE4 ,0xFF ,0x30 ,0x0 ,0x94 ,0x0 ,0x0 ,0xD0 ,0x2 ,0x2 ,0x40 ,0x3 ,0x68 ,0x0 ,0x0 ,0x20 ,0x88 ,0x14 ,0xA0 ,0x10 ,0x18 ,0x0 ,0x12 ,0x41 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x10 ,0x4 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x6 ,0xD0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x28 ,0x1 ,0x45 ,0xA0 ,0x4 ,0x0 ,0x80 ,0x10 ,0x0 ,0x0 ,0x92 ,0x0 ,0x0 ,0x0 ,0x0 ,0x81 ,0x1 ,0x0 ,0x0 ,0x0 ,0xC8 ,0xFD ,0x20 ,0x0 ,0x20 ,0x8 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x81 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x10 ,0x8 ,0x4 ,0x41 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x1A ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0xF9 ,0x60 ,0x0 ,0x10 ,0x10 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x3 ,0x1 ,0x0 ,0x0 ,0x0 ,0x40 ,0x30 ,0x0 ,0x2 ,0xC2 ,0x0 ,0x18 ,0x0 ,0x3 ,0x60 ,0x0 ,0xC ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x20 ,0xC ,0x80 ,0x80 ,0x0 ,0x80 ,0x1 ,0x1 ,0x0 ,0x16 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0xA8 ,0xFA ,0x2C ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x44 ,0x0 ,0x5 ,0x3 ,0x0 ,0x14 ,0x0 ,0x0 ,0x4 ,0x80 ,0x8 ,0x10 ,0x0 ,0x28 ,0x10 ,0x5 ,0x0 ,0x2 ,0x8 ,0x80 ,0x2 ,0x90 ,0x20 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x28 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x20 ,0x2 ,0x10 ,0x0 ,0x80 ,0x40 ,0x0 ,0x0 ,0x5A ,0x4 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x62 ,0xFA ,0x84 ,0x9 ,0x11 ,0x4 ,0x0 ,0x40 ,0x88 ,0x58 ,0x0 ,0x23 ,0x2 ,0x1 ,0x0 ,0x80 ,0x4 ,0x0 ,0x40 ,0x24 ,0xC2 ,0x42 ,0x90 ,0x4 ,0x63 ,0x60 ,0x2 ,0xC ,0x88 ,0x4 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x81 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x98 ,0x4 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x70 ,0xFD ,0xF0 ,0x1 ,0x2C ,0x0 ,0x0 ,0xB0 ,0x0 ,0x1E ,0xD0 ,0x3 ,0x78 ,0x10 ,0x0 ,0x60 ,0x80 ,0xC ,0x80 ,0x3 ,0xF0 ,0x0 ,0xE ,0xC0 ,0x0 ,0x18 ,0x10 ,0xF ,0xE0 ,0x1 ,0xD ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0xF2 ,0x20 ,0x0 ,0x0 ,0x0 ,0x58 ,0x20 ,0x3 ,0x60 ,0x81 ,0x0 ,0x0 ,0x7 ,0x0 ,0x0 ,0x1E ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x8 ,0x0 ,0x0 ,0x0 ,0x30 ,0xFE ,0x88 ,0x1 ,0x10 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x60 ,0x0 ,0x0 ,0x80 ,0x1 ,0x1 ,0x20 ,0x4 ,0x0 ,0x0 ,0x18 ,0x0 ,0x83 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x88 ,0x0 ,0x0 ,0x80 ,0x2 ,0x1 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x41 ,0xFD ,0x80 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x48 ,0x58 ,0x20 ,0x23 ,0x61 ,0x20 ,0x0 ,0x80 ,0x11 ,0xB0 ,0x0 ,0x16 ,0xC2 ,0x82 ,0x58 ,0x4 ,0xB ,0x60 ,0x11 ,0xC ,0x8 ,0x0 ,0xB0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0xC8 ,0x10 ,0x0 ,0x0 ,0x0 ,0x40 ,0x80 ,0x2C ,0x0 ,0x1 ,0x2 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0xFA ,0x20 ,0x4 ,0x14 ,0x1 ,0x0 ,0x10 ,0x0 ,0x82 ,0x44 ,0x0 ,0x8 ,0x40 ,0x0 ,0x20 ,0x0 ,0x34 ,0x80 ,0x10 ,0x18 ,0x24 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x41 ,0xA0 ,0x1 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x20 ,0x11 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x2 ,0x41 ,0x20 ,0x0 ,0x0 ,0x80 ,0x2 ,0x0 ,0x0 ,0x8A ,0x0 ,0x0 ,0x0 ,0x0 ,0xD ,0x0 ,0x0 ,0x84 ,0x20 ,0xDC ,0xFC ,0x0 ,0x80 ,0x20 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x4 ,0x1 ,0x0 ,0xA ,0x4 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0xFE ,0x80 ,0x40 ,0x10 ,0x10 ,0x0 ,0xC0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x21 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x8 ,0x2 ,0x42 ,0x0 ,0x18 ,0x0 ,0x3 ,0x0 ,0x20 ,0x8 ,0x4 ,0x40 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0xC0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x20 ,0x20 ,0x4 ,0x8 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0xE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x78 ,0xFB ,0x8 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x10 ,0x0 ,0x10 ,0x0 ,0x40 ,0x41 ,0x0 ,0x0 ,0x10 ,0x1 ,0x2 ,0x10 ,0x0 ,0x80 ,0x18 ,0x0 ,0x90 ,0x60 ,0x0 ,0x24 ,0x0 ,0x10 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x4 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x4A ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x9B ,0xFD ,0x80 ,0x9 ,0x10 ,0x4 ,0x0 ,0xC0 ,0x80 ,0x18 ,0x11 ,0x20 ,0x2 ,0x4 ,0x0 ,0x80 ,0x5 ,0x2 ,0x1 ,0x24 ,0xC0 ,0x8 ,0x41 ,0x0 ,0x23 ,0x4 ,0x12 ,0x0 ,0x8 ,0x8 ,0x30 ,0xA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x16 ,0xC1 ,0x8 ,0x1 ,0x0 ,0x0 ,0x40 ,0x11 ,0x28 ,0x0 ,0x4 ,0x1 ,0x0 ,0x2 ,0x0 ,0x0 ,0x98 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0xE9 ,0xFA ,0xE0 ,0x41 ,0x2C ,0x0 ,0x0 ,0x30 ,0x0 ,0x1E ,0xC0 ,0x0 ,0x18 ,0x40 ,0x0 ,0x60 ,0x0 ,0x3C ,0x88 ,0x3 ,0xF2 ,0x0 ,0x6 ,0xC8 ,0x3 ,0x78 ,0x0 ,0xB ,0xE0 ,0x41 ,0x3C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0xF0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x38 ,0x0 ,0x7 ,0x68 ,0x0 ,0x0 ,0x80 ,0x4 ,0x0 ,0x0 ,0x1E ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x4 ,0x0 ,0xC ,0x10 ,0xA2 ,0xFB ,0x4 ,0x0 ,0x10 ,0x20 ,0x0 ,0xC0 ,0x0 ,0x18 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x80 ,0x41 ,0x30 ,0x0 ,0x4 ,0xC2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x61 ,0x0 ,0x8 ,0x80 ,0x1 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x10 ,0x8 ,0x80 ,0x1 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0xD2 ,0xFE ,0x0 ,0x11 ,0x21 ,0x0 ,0x0 ,0xC0 ,0x28 ,0x10 ,0x9 ,0x20 ,0x1 ,0x22 ,0x0 ,0x80 ,0x1 ,0x30 ,0x4 ,0x26 ,0x80 ,0x48 ,0x80 ,0x8 ,0x3 ,0x60 ,0x41 ,0x4C ,0x81 ,0x21 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x24 ,0xC0 ,0x88 ,0x0 ,0x0 ,0x0 ,0x60 ,0x4 ,0x2C ,0x82 ,0x51 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x20 ,0x12 ,0xA4 ,0xFE ,0xB0 ,0x1 ,0x14 ,0x9 ,0x0 ,0x10 ,0x8 ,0x2 ,0x40 ,0x22 ,0x8 ,0x41 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x6 ,0x10 ,0x0 ,0x2 ,0x51 ,0x0 ,0x8 ,0x0 ,0xD ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x28 ,0x41 ,0xD ,0xA0 ,0x1 ,0x0 ,0x80 ,0x12 ,0x0 ,0x0 ,0x1A ,0x0 ,0x0 ,0x0 ,0x0 ,0x8D ,0x1 ,0x0 ,0x0 ,0x0 ,0xF0 ,0xFE ,0x80 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x80 ,0x10 ,0x8 ,0x83 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x1 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0xFB ,0x0 ,0x0 ,0x10 ,0x10 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x3 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x82 ,0x1 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x10 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x8 ,0x0 ,0x0 ,0x0 ,0xA8 ,0xFF ,0xC ,0x0 ,0x0 ,0x2 ,0x0 ,0x80 ,0x8 ,0x0 ,0x20 ,0x93 ,0x40 ,0x0 ,0x0 ,0x80 ,0x11 ,0x81 ,0x10 ,0x6 ,0x0 ,0x0 ,0x10 ,0x9 ,0x3 ,0x60 ,0x40 ,0x20 ,0x0 ,0x84 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x42 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0xC ,0x0 ,0x10 ,0x2 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x92 ,0xF8 ,0x4 ,0x10 ,0x11 ,0x4 ,0x0 ,0x0 ,0x0 ,0x49 ,0x0 ,0x8 ,0x0 ,0x80 ,0x0 ,0x0 ,0x10 ,0x30 ,0x2 ,0x6 ,0x2 ,0x42 ,0x80 ,0x8 ,0x8 ,0x0 ,0x11 ,0x40 ,0x82 ,0x5 ,0x32 ,0x42 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x10 ,0xC0 ,0x2 ,0x1 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x48 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x11 ,0x0 ,0x0 ,0x0 ,0x4C ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0xFB ,0x68 ,0x0 ,0x2C ,0x0 ,0x0 ,0x30 ,0x0 ,0x6 ,0xD0 ,0x0 ,0x19 ,0x0 ,0x0 ,0xE0 ,0x41 ,0x3C ,0x90 ,0x7 ,0x30 ,0x0 ,0x1E ,0xC0 ,0x83 ,0x78 ,0x0 ,0xF ,0xE0 ,0x1 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x1 ,0x80 ,0x1 ,0xF1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x3 ,0xE0 ,0x1 ,0x0 ,0x80 ,0x4 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF ,0x8 ,0x0 ,0x0 ,0x0 ,0xD0 ,0xFE ,0x8 ,0x0 ,0x10 ,0x20 ,0x0 ,0x0 ,0x0 ,0x18 ,0x8 ,0x80 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0xC2 ,0x0 ,0x8 ,0x0 ,0x3 ,0x60 ,0x0 ,0xC ,0x0 ,0x0 ,0x30 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x4 ,0x0 ,0x0 ,0x0 ,0x79 ,0xFD ,0x10 ,0x88 ,0x20 ,0x0 ,0x0 ,0x20 ,0x8 ,0x59 ,0x0 ,0xA ,0x10 ,0x84 ,0x0 ,0x80 ,0x85 ,0xB0 ,0x20 ,0x10 ,0xC0 ,0x42 ,0x0 ,0x10 ,0x3 ,0x61 ,0x81 ,0xC ,0x81 ,0x11 ,0x31 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x28 ,0x0 ,0x0 ,0x46 ,0xC0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x60 ,0x20 ,0x0 ,0x80 ,0x21 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x98 ,0x2 ,0x0 ,0x0 ,0x0 ,0x4C ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0xFF ,0xA0 ,0x1 ,0x94 ,0x8 ,0x0 ,0x10 ,0x0 ,0x2 ,0x48 ,0x63 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x81 ,0x44 ,0x10 ,0x4 ,0x2 ,0x40 ,0x10 ,0x8 ,0x2 ,0x1 ,0x20 ,0x0 ,0x4 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x81 ,0x20 ,0x8 ,0x0 ,0x80 ,0x44 ,0x1 ,0x0 ,0x1A ,0x0 ,0x0 ,0x0 ,0x0 ,0x8D ,0x1 ,0x0 ,0x4 ,0x0 ,0x8 ,0xFF ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x20 ,0x6 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x40 ,0x0 ,0x80 ,0x2 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0xFA ,0x0 ,0x0 ,0x10 ,0x10 ,0x0 ,0xC0 ,0x0 ,0x8 ,0x0 ,0x3 ,0x60 ,0x0 ,0x0 ,0x80 ,0x81 ,0x10 ,0x10 ,0x6 ,0x40 ,0x80 ,0x18 ,0x0 ,0x2 ,0x21 ,0x20 ,0xC ,0x82 ,0x80 ,0x10 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x40 ,0x40 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x80 ,0x5 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x8 ,0x0 ,0x30 ,0x10 ,0xE8 ,0xFC ,0x8 ,0x0 ,0x2 ,0x2 ,0x0 ,0x0 ,0x14 ,0x80 ,0x10 ,0x23 ,0x2 ,0xA ,0x0 ,0x80 ,0x1 ,0x0 ,0x1 ,0x16 ,0x8 ,0x0 ,0x0 ,0x2 ,0x11 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x80 ,0x8 ,0x10 ,0x1 ,0x80 ,0x2 ,0x0 ,0x0 ,0x98 ,0x10 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x80 ,0x0 ,0x71 ,0xF9 ,0x0 ,0x44 ,0x10 ,0x4 ,0x0 ,0xC0 ,0x0 ,0x18 ,0x1 ,0x22 ,0x60 ,0x0 ,0x0 ,0x80 ,0x11 ,0x21 ,0x1 ,0x20 ,0x80 ,0x8 ,0x18 ,0x0 ,0x60 ,0x40 ,0x1 ,0xC ,0x8 ,0x9 ,0x20 ,0x9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x26 ,0x80 ,0x2 ,0x0 ,0x0 ,0x0 ,0x60 ,0x21 ,0x8C ,0x81 ,0x49 ,0x0 ,0x0 ,0x3 ,0x2 ,0x0 ,0x40 ,0x10 ,0x0 ,0x0 ,0x0 ,0x44 ,0x0 ,0x0 ,0x30 ,0x20 ,0x63 ,0xFA ,0xE0 ,0x1 ,0x2C ,0x0 ,0x0 ,0x30 ,0x20 ,0x6 ,0xC4 ,0x3 ,0x19 ,0x10 ,0x0 ,0xE0 ,0x1 ,0x1C ,0x88 ,0x1 ,0x72 ,0x20 ,0x6 ,0xD0 ,0x2 ,0x38 ,0x40 ,0xF ,0xE0 ,0x40 ,0x1C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x72 ,0x20 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x3 ,0x60 ,0x0 ,0x0 ,0x80 ,0x6 ,0x0 ,0x0 ,0x1E ,0x0 ,0x0 ,0x0 ,0x0 ,0xF ,0x8 ,0x0 ,0x3C ,0x0 ,0xE0 ,0xFB ,0x84 ,0x1 ,0x10 ,0x20 ,0x0 ,0xC0 ,0x40 ,0x18 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x80 ,0x1 ,0x20 ,0x0 ,0x0 ,0x81 ,0x0 ,0x18 ,0x4 ,0x2 ,0x40 ,0x0 ,0x0 ,0x4 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x81 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x10 ,0xC ,0x88 ,0x81 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x18 ,0x4 ,0x0 ,0x0 ,0x0 ,0xC ,0x4 ,0x0 ,0x30 ,0x0 ,0xC2 ,0xFC ,0x80 ,0x81 ,0x20 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x90 ,0x4 ,0xA0 ,0x60 ,0x10 ,0x0 ,0x80 ,0x91 ,0xB0 ,0x8 ,0x44 ,0xC0 ,0x24 ,0x58 ,0x0 ,0x3 ,0x61 ,0x81 ,0xC ,0x80 ,0x41 ,0xB0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x16 ,0xC0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x60 ,0x1 ,0x8 ,0x0 ,0x9 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0x1 ,0x0 ,0x0 ,0x0 ,0x4C ,0x0 ,0x0 ,0x30 ,0x10 ,0xB8 ,0xFD ,0x30 ,0x10 ,0x4 ,0x80 ,0x0 ,0x10 ,0x8 ,0x42 ,0x50 ,0x3 ,0x68 ,0x0 ,0x21 ,0x28 ,0x10 ,0x4 ,0x82 ,0x0 ,0x10 ,0x82 ,0x42 ,0x50 ,0x0 ,0x8 ,0x41 ,0x1 ,0x22 ,0x10 ,0x4 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x10 ,0x14 ,0x82 ,0x0 ,0x0 ,0x0 ,0x8 ,0x4 ,0x41 ,0x22 ,0x10 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x9 ,0x0 ,0x0 ,0x0 ,0x8D ,0x1 ,0x0 ,0x34 ,0x1 ,0xD8 ,0xFC ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x3 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x30 ,0x10 ,0xC0 ,0xFA ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x80 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x84 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x4 ,0x0 ,0x0 ,0x21 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x18 ,0x8 ,0x0 ,0x0 ,0x0 ,0xC ,0x8 ,0x0 ,0x30 ,0x0 ,0xC0 ,0xFE ,0xC ,0x1 ,0x30 ,0x2 ,0x6 ,0x84 ,0x8 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x8 ,0x20 ,0x0 ,0x6 ,0x80 ,0x8 ,0x10 ,0x1 ,0x0 ,0x40 ,0x4 ,0x0 ,0x8 ,0x11 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x80 ,0x8 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x58 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x30 ,0x10 ,0x72 ,0xF8 ,0x4 ,0x0 ,0x2 ,0x4 ,0x0 ,0x1 ,0x0 ,0x1 ,0x20 ,0xA3 ,0x60 ,0x14 ,0x80 ,0x88 ,0x5 ,0x0 ,0x22 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x60 ,0x0 ,0x80 ,0xC ,0x1 ,0x0 ,0x32 ,0xA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x88 ,0x0 ,0x0 ,0x0 ,0x0 ,0x44 ,0x0 ,0x10 ,0x10 ,0x1 ,0x0 ,0x16 ,0x1 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x44 ,0x0 ,0x0 ,0x80 ,0x10 ,0xD0 ,0xFE ,0x68 ,0x0 ,0xC ,0x80 ,0x7 ,0x30 ,0x0 ,0x6 ,0xC0 ,0x3 ,0x78 ,0x0 ,0x3 ,0xE0 ,0x0 ,0xD ,0x80 ,0x7 ,0x31 ,0x0 ,0x6 ,0xC0 ,0x0 ,0x18 ,0x0 ,0xF ,0x60 ,0x0 ,0x2C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x3 ,0x60 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x16 ,0x10 ,0x0 ,0x0 ,0x0 ,0xF ,0x8 ,0x0 ,0x2C ,0x0 ,0x28 ,0xFC ,0x8 ,0x0 ,0x0 ,0x20 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x61 ,0x0 ,0x0 ,0x80 ,0x41 ,0x0 ,0x0 ,0x6 ,0x4 ,0x0 ,0x0 ,0x0 ,0x3 ,0x1 ,0x0 ,0xC ,0x0 ,0x0 ,0x30 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x4 ,0x0 ,0x30 ,0x20 ,0x89 ,0xFD ,0x50 ,0x10 ,0x2 ,0x0 ,0x6 ,0x22 ,0x8 ,0x5 ,0xA1 ,0x13 ,0x70 ,0x8 ,0x2 ,0x88 ,0x9 ,0x8 ,0x42 ,0x6 ,0x20 ,0x8 ,0x5 ,0x21 ,0x13 ,0x10 ,0x84 ,0x88 ,0x44 ,0x10 ,0x32 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x24 ,0x8 ,0x1 ,0x0 ,0x0 ,0x10 ,0x84 ,0x82 ,0x50 ,0x8 ,0x0 ,0x0 ,0x40 ,0x1 ,0x0 ,0x9C ,0x2 ,0x0 ,0x0 ,0x0 ,0x4C ,0x0 ,0x0 ,0x30 ,0x1 ,0x18 ,0xFF ,0x20 ,0x0 ,0x34 ,0x91 ,0x20 ,0x10 ,0x0 ,0x2 ,0x40 ,0x1 ,0x29 ,0xC ,0x1 ,0x20 ,0x4 ,0x5 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0xA0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x24 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x80 ,0x20 ,0x11 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x81 ,0x1 ,0x0 ,0x34 ,0x0 ,0xF8 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x3 ,0x60 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x8 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x30 ,0x0 ,0xC0 ,0xFC ,0x80 ,0x1 ,0x10 ,0x8 ,0x2 ,0xC2 ,0x0 ,0x18 ,0x10 ,0x1 ,0x20 ,0x0 ,0xC ,0x4 ,0x40 ,0x30 ,0x0 ,0x6 ,0xC0 ,0x40 ,0x18 ,0x0 ,0x1 ,0x60 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x1 ,0x0 ,0x6 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0xC ,0x80 ,0x1 ,0x0 ,0x80 ,0x1 ,0xC1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0xF0 ,0xFF ,0x8 ,0x28 ,0x0 ,0x1 ,0x20 ,0x0 ,0x14 ,0x0 ,0x1 ,0x8A ,0x40 ,0x81 ,0x20 ,0x0 ,0x4 ,0x0 ,0x40 ,0x10 ,0x1 ,0x0 ,0x40 ,0x10 ,0x0 ,0x2 ,0xA ,0x0 ,0x0 ,0x48 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x1 ,0x24 ,0x0 ,0x0 ,0x0 ,0x0 ,0x11 ,0x40 ,0x2 ,0x44 ,0x0 ,0x80 ,0x10 ,0xC0 ,0x0 ,0x88 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x29 ,0xF8 ,0x80 ,0x1 ,0x0 ,0x4 ,0x14 ,0xC0 ,0x42 ,0x58 ,0x4 ,0x93 ,0x60 ,0x22 ,0x2C ,0x80 ,0x4 ,0xB2 ,0x8 ,0x16 ,0xC0 ,0x22 ,0x18 ,0x1 ,0x23 ,0x60 ,0x0 ,0x0 ,0x88 ,0x45 ,0x30 ,0xA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x11 ,0x0 ,0x0 ,0x26 ,0xC0 ,0x22 ,0x0 ,0x0 ,0x0 ,0x60 ,0x2 ,0x2C ,0x82 ,0x45 ,0x0 ,0x0 ,0x0 ,0x2 ,0x10 ,0x98 ,0x4 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x20 ,0x1B ,0xF8 ,0x60 ,0x40 ,0x3C ,0x80 ,0x3 ,0x32 ,0x0 ,0x1E ,0xC0 ,0x3 ,0x78 ,0x0 ,0xF ,0x64 ,0x0 ,0x3C ,0x80 ,0x7 ,0xF2 ,0x0 ,0x6 ,0xC4 ,0x3 ,0x19 ,0x10 ,0x3 ,0xE0 ,0x1 ,0x3C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x1 ,0x80 ,0x7 ,0xF1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x78 ,0x10 ,0xF ,0xE0 ,0x1 ,0x0 ,0x0 ,0x3 ,0x30 ,0x0 ,0x1E ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x8 ,0x0 ,0xC ,0x0 ,0x70 ,0xF9 ,0x84 ,0x1 ,0x0 ,0x20 ,0x4 ,0xC0 ,0x40 ,0x0 ,0x0 ,0x1 ,0x20 ,0x20 ,0x0 ,0x80 ,0x1 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x3 ,0x60 ,0x0 ,0xC ,0x4 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x80 ,0x10 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x1A ,0xFA ,0x80 ,0x51 ,0x30 ,0x0 ,0x6 ,0xC2 ,0x8 ,0x98 ,0x2 ,0x3 ,0x61 ,0x2 ,0x4C ,0x81 ,0x11 ,0x30 ,0x5 ,0x6 ,0xC4 ,0x14 ,0x98 ,0x4 ,0x22 ,0x61 ,0x21 ,0x2C ,0x80 ,0x29 ,0x20 ,0xA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x29 ,0x0 ,0x0 ,0xA6 ,0xC0 ,0x14 ,0x0 ,0x0 ,0x0 ,0x60 ,0xA ,0xC ,0x88 ,0x29 ,0x0 ,0x0 ,0x40 ,0x1 ,0x2 ,0x88 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x80 ,0x0 ,0x38 ,0xFC ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xCC ,0xFB ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x4C ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x1 ,0x10 ,0x0 ,0x4 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0xFB ,0xF8 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC9 ,0xFA ,0x8 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x98 ,0xFF ,0x8 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE3 ,0xFC ,0x30 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x41 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x98 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x80 ,0x2 ,0x0 ,0x0 ,0x2 ,0x40 ,0x0 ,0x0 ,0x0 ,0x1 ,0xA0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA8 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x8 ,0x0 ,0xA0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB0 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xFB ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x9 ,0x28 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x58 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x4 ,0x1 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0xFE ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x80 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x10 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x10 ,0x10 ,0x0 ,0x22 ,0x10 ,0x0 ,0x40 ,0x80 ,0x20 ,0x0 ,0xE8 ,0xF8 ,0x0 ,0x0 ,0x4 ,0x5 ,0x0 ,0x0 ,0x0 ,0x34 ,0xD8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x26 ,0x0 ,0x14 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x26 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0xB0 ,0x14 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x10 ,0x0 ,0xA ,0x40 ,0x0 ,0x20 ,0x30 ,0x5 ,0x5 ,0x58 ,0xFC ,0x0 ,0x41 ,0x20 ,0x8 ,0x0 ,0x80 ,0x1 ,0x80 ,0x0 ,0x43 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x70 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x1 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0xC0 ,0x3 ,0x9 ,0x1 ,0x0 ,0x34 ,0x2C ,0xD0 ,0xFA ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x8 ,0x65 ,0xFC ,0x8 ,0x1 ,0x10 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x81 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x2 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x20 ,0x0 ,0x8 ,0x2 ,0x0 ,0x10 ,0x8 ,0xC5 ,0xF8 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x4 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x60 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x21 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0x0 ,0x78 ,0xFB ,0x0 ,0x0 ,0x4 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x80 ,0x2 ,0x80 ,0x0 ,0x12 ,0x0 ,0x2 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x58 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x9 ,0x0 ,0x0 ,0x8 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x68 ,0xFC ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF0 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x2 ,0x10 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0xC8 ,0x0 ,0x0 ,0x0 ,0x7 ,0x40 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE8 ,0xFE ,0x2A ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x2 ,0x0 ,0x8 ,0x0 ,0x9 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC9 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xD8 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC9 ,0xF8 ,0x42 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x68 ,0xF9 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x4 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x1 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE4 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0xD8 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA8 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x4 ,0xC8 ,0xFF ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x80 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x20 ,0x0 ,0x2 ,0x0 ,0x0 ,0x28 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x8 ,0x10 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0xC0 ,0xFE ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x11 ,0x4 ,0x0 ,0x0 ,0x10 ,0x10 ,0x2 ,0x80 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x18 ,0xFD ,0x8 ,0x24 ,0x0 ,0x0 ,0x0 ,0x40 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x5 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFC ,0x80 ,0x80 ,0x0 ,0x0 ,0x0 ,0x80 ,0x10 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x82 ,0x0 ,0x0 ,0x0 ,0x30 ,0xFA ,0x8 ,0x40 ,0x0 ,0x84 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x10 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x22 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x2 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x84 ,0x0 ,0x4 ,0x0 ,0x40 ,0xFA ,0x40 ,0x80 ,0x1 ,0xA0 ,0xA0 ,0xA0 ,0xC2 ,0x0 ,0x90 ,0x0 ,0x0 ,0xA ,0x28 ,0x0 ,0x0 ,0xA1 ,0x20 ,0x0 ,0x80 ,0x82 ,0x50 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x0 ,0x5 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x28 ,0x0 ,0x0 ,0x14 ,0x84 ,0x2 ,0x0 ,0x40 ,0x0 ,0x48 ,0x1 ,0x1 ,0x28 ,0x5 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x80 ,0x8 ,0x0 ,0x3 ,0x6C ,0x0 ,0xA4 ,0x0 ,0x8 ,0xF8 ,0x0 ,0x5C ,0x10 ,0x22 ,0x22 ,0x80 ,0x10 ,0x8 ,0x0 ,0x22 ,0x42 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x2 ,0x0 ,0x1C ,0x0 ,0x0 ,0xC1 ,0x0 ,0x2 ,0x80 ,0x8 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x1 ,0x80 ,0x8 ,0x0 ,0x0 ,0x0 ,0xC ,0x80 ,0x2 ,0x0 ,0x0 ,0x10 ,0xD0 ,0x0 ,0x9 ,0x1 ,0x5 ,0x20 ,0x24 ,0xA0 ,0xFE ,0x0 ,0x40 ,0x10 ,0x0 ,0x1 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xD8 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x80 ,0x0 ,0x80 ,0x0 ,0x10 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x4 ,0x0 ,0x4 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x8 ,0x42 ,0x0 ,0x20 ,0x8 ,0x88 ,0xFA ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x0 ,0x80 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x83 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFB ,0x12 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x80 ,0x94 ,0xFF ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x1 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA0 ,0xFD ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0xFC ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x20 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2C ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x40 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x44 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x41 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0xFD ,0x0 ,0x80 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0x0 ,0x20 ,0x40 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x4 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x58 ,0xFD ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x58 ,0xFB ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0xFB ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF8 ,0xFB ,0x0 ,0x0 ,0x4 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x85 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x40 ,0x88 ,0x8 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x40 ,0x58 ,0x2 ,0x0 ,0x40 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x14 ,0x10 ,0x90 ,0xFB ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x50 ,0xFC ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x20 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x8 ,0x10 ,0xFA ,0x0 ,0x0 ,0xB0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB ,0x64 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x84 ,0x0 ,0x8 ,0x0 ,0x0 ,0x83 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x8 ,0xFA ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x8 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x18 ,0x0 ,0x0 ,0xA0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x41 ,0x8 ,0xFF ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3C ,0x8 ,0x0 ,0x0 ,0x0 ,0x6 ,0xC0 ,0x82 ,0x58 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0xF1 ,0x0 ,0x0 ,0xC0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3C ,0x0 ,0x28 ,0xFA ,0x0 ,0x0 ,0x20 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x18 ,0x10 ,0x3 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0xFD ,0x0 ,0x0 ,0x30 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x8A ,0x40 ,0x11 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x16 ,0xC0 ,0x0 ,0x1 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x5 ,0xA0 ,0xFD ,0x0 ,0x0 ,0x4 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8D ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x14 ,0x9 ,0x0 ,0x10 ,0x2 ,0x0 ,0x40 ,0x3 ,0x68 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x10 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x1 ,0x1 ,0x0 ,0x84 ,0x0 ,0xC4 ,0xFE ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x3 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0xFF ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x83 ,0x60 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x10 ,0xC0 ,0xFC ,0x8 ,0x0 ,0xB0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA0 ,0x8 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x23 ,0x60 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x44 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4C ,0x0 ,0x0 ,0x30 ,0x2 ,0x53 ,0xFB ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x21 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x63 ,0x60 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x23 ,0x2 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x1 ,0xF8 ,0x0 ,0x0 ,0xC ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x7 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2C ,0x0 ,0x0 ,0xB0 ,0x20 ,0x0 ,0xC0 ,0x0 ,0x18 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB0 ,0x20 ,0x0 ,0xC0 ,0x3 ,0x0 ,0x0 ,0xB ,0x2 ,0x0 ,0x2C ,0x8 ,0xD0 ,0xFA ,0x4 ,0x0 ,0x20 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x30 ,0x0 ,0x93 ,0xFA ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x5 ,0x0 ,0x80 ,0x28 ,0x0 ,0x0 ,0xB ,0x61 ,0xA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x28 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x88 ,0x2 ,0x0 ,0x20 ,0xA ,0x98 ,0xFD ,0x10 ,0x0 ,0x4 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x85 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x14 ,0x1 ,0x0 ,0xD0 ,0x0 ,0x0 ,0x40 ,0x3 ,0x68 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xD0 ,0x0 ,0x82 ,0x40 ,0x10 ,0x0 ,0x0 ,0xD ,0x0 ,0x0 ,0x34 ,0x0 ,0x30 ,0xFF ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x8 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x1 ,0x0 ,0xC ,0x0 ,0x0 ,0x30 ,0x0 ,0xC8 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x10 ,0x0 ,0xC0 ,0x40 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x2 ,0x0 ,0xC ,0x0 ,0x0 ,0x30 ,0x10 ,0x10 ,0xF9 ,0xC ,0x0 ,0x10 ,0x12 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x1 ,0x0 ,0xC0 ,0x4 ,0x0 ,0x0 ,0x23 ,0x60 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x42 ,0x88 ,0x10 ,0x20 ,0x0 ,0x0 ,0x2C ,0x10 ,0x0 ,0x30 ,0x1 ,0x42 ,0xF9 ,0x4 ,0x0 ,0x10 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x63 ,0x60 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x48 ,0x0 ,0xB ,0x0 ,0x0 ,0x80 ,0x2 ,0x0 ,0x0 ,0x41 ,0x58 ,0xFB ,0x8 ,0x0 ,0x3C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2C ,0x10 ,0x0 ,0xF0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x18 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF0 ,0x0 ,0x1E ,0xC4 ,0x82 ,0x0 ,0x0 ,0xF ,0x0 ,0x0 ,0x3C ,0x0 ,0x18 ,0xFE ,0x8 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x18 ,0x4 ,0x83 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x30 ,0x0 ,0xA1 ,0xFC ,0x10 ,0x0 ,0x30 ,0xA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x14 ,0x0 ,0x0 ,0xB ,0x61 ,0xA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x99 ,0x0 ,0x23 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x5 ,0xC8 ,0xFB ,0x0 ,0x0 ,0x84 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8D ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x0 ,0x28 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x20 ,0x68 ,0x24 ,0x1 ,0xA0 ,0x1 ,0x4 ,0x0 ,0x70 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x41 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xFF ,0x0 ,0x0 ,0x20 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0xC0 ,0x3 ,0x38 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x42 ,0x0 ,0xC ,0x80 ,0x41 ,0x30 ,0x0 ,0x8 ,0xFA ,0x8 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x40 ,0xA3 ,0x68 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x14 ,0xC ,0x80 ,0x11 ,0x30 ,0x0 ,0x72 ,0xFF ,0x0 ,0x0 ,0x30 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x9 ,0x0 ,0xC0 ,0x10 ,0x0 ,0x0 ,0x80 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x8 ,0x1 ,0x0 ,0x8B ,0x20 ,0x0 ,0x8C ,0x10 ,0x10 ,0x30 ,0x4 ,0xA8 ,0xF9 ,0x0 ,0x0 ,0x2C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x7 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3C ,0x0 ,0x0 ,0xF0 ,0x0 ,0x0 ,0xC0 ,0x3 ,0x58 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF0 ,0x0 ,0x0 ,0xC0 ,0x3 ,0x68 ,0x0 ,0xF ,0xE0 ,0x81 ,0x3C ,0x0 ,0xE8 ,0xFF ,0x4 ,0x0 ,0x30 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x60 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x81 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x69 ,0xFE ,0x0 ,0x0 ,0xB0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0xB ,0x41 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x42 ,0x0 ,0x0 ,0x3 ,0x20 ,0x0 ,0x20 ,0x10 ,0x90 ,0x0 ,0x1 ,0xE8 ,0xF9 ,0x10 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x85 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x90 ,0x34 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x3 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x0 ,0x40 ,0x0 ,0x1 ,0xA0 ,0x1 ,0x14 ,0x10 ,0x98 ,0xFC ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x3 ,0x78 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x60 ,0x40 ,0x0 ,0x0 ,0x40 ,0x20 ,0x8 ,0xF8 ,0xFD ,0xC ,0x0 ,0x10 ,0x41 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x90 ,0x80 ,0x0 ,0x0 ,0xC0 ,0x44 ,0x0 ,0x40 ,0xA0 ,0x68 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB ,0x41 ,0x0 ,0x4C ,0x4 ,0x8 ,0x80 ,0x0 ,0x2A ,0xF9 ,0x4 ,0x0 ,0x10 ,0x9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4C ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x50 ,0x0 ,0x0 ,0x0 ,0x0 ,0x24 ,0x0 ,0x0 ,0x80 ,0x0 ,0x14 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0xA0 ,0x0 ,0x0 ,0x40 ,0x2 ,0x0 ,0x2 ,0x41 ,0xC0 ,0xFB ,0x8 ,0x0 ,0x3C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x3C ,0x8 ,0x0 ,0xF0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x78 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF0 ,0x40 ,0x0 ,0xC0 ,0x0 ,0x20 ,0x0 ,0xF ,0xE0 ,0x1 ,0xC ,0x0 ,0xE0 ,0xFF ,0x8 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x41 ,0x30 ,0x0 ,0x0 ,0xC0 ,0x20 ,0x0 ,0x0 ,0x83 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0xC ,0x82 ,0x1 ,0x1 ,0x0 ,0x61 ,0xFE ,0x10 ,0x0 ,0x30 ,0x9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x5 ,0x30 ,0x4 ,0x0 ,0xC0 ,0x2 ,0x0 ,0x0 ,0x23 ,0x60 ,0xA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x14 ,0x0 ,0x0 ,0x8B ,0x60 ,0x0 ,0x2C ,0x80 ,0x5 ,0x0 ,0x5 ,0x10 ,0xF9 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8D ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x10 ,0x34 ,0x0 ,0x0 ,0x10 ,0x18 ,0x0 ,0x40 ,0x89 ,0x68 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x40 ,0x52 ,0x2 ,0x0 ,0x40 ,0x0 ,0x0 ,0x1 ,0x81 ,0x21 ,0x0 ,0x4 ,0x0 ,0x74 ,0xFC ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x22 ,0x20 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x58 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x81 ,0x30 ,0x8 ,0x0 ,0x0 ,0x80 ,0x0 ,0xC0 ,0x81 ,0x78 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x20 ,0x0 ,0x0 ,0x2 ,0x62 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x70 ,0xFC ,0x8 ,0x0 ,0x0 ,0x5 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x30 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x40 ,0x13 ,0x8 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x42 ,0x2 ,0x8 ,0x0 ,0x0 ,0x20 ,0x20 ,0xA ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x93 ,0xF9 ,0x0 ,0x0 ,0x30 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x51 ,0x80 ,0x0 ,0x0 ,0xC0 ,0x24 ,0x0 ,0x0 ,0x3 ,0x0 ,0x14 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x18 ,0x0 ,0x0 ,0x8B ,0x40 ,0x0 ,0x4C ,0x2 ,0x0 ,0x32 ,0x11 ,0x91 ,0xFE ,0x0 ,0x0 ,0x3C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x7 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x1 ,0x3C ,0x20 ,0x0 ,0xF0 ,0x0 ,0x0 ,0xC0 ,0x82 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0xF1 ,0x0 ,0x0 ,0xC0 ,0x2 ,0x0 ,0x0 ,0xF ,0x60 ,0x0 ,0x3C ,0x0 ,0x88 ,0xFC ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x41 ,0x0 ,0x0 ,0x0 ,0x40 ,0x20 ,0x0 ,0x0 ,0x3 ,0x60 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x1 ,0x0 ,0x0 ,0x0 ,0x3 ,0x40 ,0x0 ,0x4 ,0x82 ,0x81 ,0x0 ,0x0 ,0x83 ,0xFE ,0x0 ,0x0 ,0x30 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x9 ,0x0 ,0x20 ,0x0 ,0xC0 ,0x4 ,0x0 ,0x0 ,0x12 ,0x61 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0xC0 ,0x0 ,0x1 ,0x0 ,0xA3 ,0x60 ,0x0 ,0xC ,0x80 ,0x11 ,0x80 ,0x10 ,0xB8 ,0xFA ,0x10 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x85 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x10 ,0x6 ,0x8 ,0x0 ,0x50 ,0x28 ,0x0 ,0x40 ,0x3 ,0x8 ,0x14 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x40 ,0x50 ,0x2 ,0x0 ,0x40 ,0x21 ,0x41 ,0x20 ,0x1 ,0x20 ,0x8 ,0x14 ,0x10 ,0x18 ,0xFE ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x40 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x41 ,0x0 ,0x0 ,0x60 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x70 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x82 ,0x20 ,0x0 ,0x0 ,0x3 ,0x60 ,0x40 ,0x3 ,0x0 ,0x0 ,0x20 ,0x8 ,0xB8 ,0xFC ,0xC ,0x0 ,0x10 ,0x41 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x21 ,0x0 ,0x12 ,0x0 ,0xD0 ,0x82 ,0x0 ,0x40 ,0xA0 ,0x40 ,0x22 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x8 ,0x0 ,0x0 ,0x3 ,0x42 ,0x0 ,0x1 ,0x0 ,0x20 ,0x80 ,0x0 ,0xD2 ,0xFE ,0x4 ,0x0 ,0x10 ,0xA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8C ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x51 ,0x10 ,0x0 ,0x0 ,0xC0 ,0x8 ,0x0 ,0x0 ,0xA0 ,0x20 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x18 ,0x0 ,0x0 ,0xA3 ,0x0 ,0x0 ,0x4C ,0x82 ,0x0 ,0x2 ,0x41 ,0xA0 ,0xFD ,0x8 ,0x0 ,0x3C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x3C ,0x8 ,0x0 ,0xB0 ,0x20 ,0x0 ,0xC0 ,0x3 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x5 ,0x31 ,0x0 ,0x0 ,0xC0 ,0x3 ,0x20 ,0x0 ,0xF ,0xE0 ,0x1 ,0x3C ,0x0 ,0x68 ,0xFB ,0x8 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x41 ,0x30 ,0x0 ,0x0 ,0xC0 ,0x40 ,0x0 ,0x0 ,0x83 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x1 ,0x0 ,0x0 ,0x0 ,0x3 ,0x20 ,0x0 ,0xC ,0x80 ,0x81 ,0x0 ,0x0 ,0xF1 ,0xFF ,0x10 ,0x0 ,0x30 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x11 ,0x30 ,0x10 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x13 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x26 ,0x0 ,0x0 ,0x1 ,0x80 ,0x13 ,0x64 ,0x0 ,0xD ,0x80 ,0x1 ,0x30 ,0x5 ,0x70 ,0xFB ,0x0 ,0x0 ,0x4 ,0x12 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8D ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x80 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x50 ,0x2 ,0x2 ,0x43 ,0x23 ,0x21 ,0x4 ,0x5 ,0x22 ,0x0 ,0x94 ,0x0 ,0x10 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x80 ,0x8 ,0x0 ,0x3 ,0x40 ,0x20 ,0x0 ,0x80 ,0x1 ,0x0 ,0x20 ,0xF0 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x7A ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF0 ,0x20 ,0x18 ,0x10 ,0x3 ,0x20 ,0x0 ,0x7 ,0x0 ,0x80 ,0x3C ,0x8 ,0x0 ,0xFE ,0x8 ,0x0 ,0x20 ,0x21 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x28 ,0x80 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0xA ,0x68 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA0 ,0x50 ,0x4 ,0x98 ,0x0 ,0x3 ,0x42 ,0x0 ,0x2D ,0x8 ,0x4 ,0x14 ,0x1 ,0xD2 ,0xFB ,0x0 ,0x0 ,0x20 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x51 ,0x30 ,0x0 ,0x0 ,0xC0 ,0x24 ,0x0 ,0x0 ,0x1 ,0x2 ,0x14 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x80 ,0x8 ,0x0 ,0x1 ,0x20 ,0x24 ,0x0 ,0x8C ,0x80 ,0x1 ,0x22 ,0x2 ,0x78 ,0xFC ,0x0 ,0x0 ,0x3C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x7 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x3C ,0x8 ,0x0 ,0xF0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x78 ,0x0 ,0x3 ,0x4 ,0x0 ,0x0 ,0x80 ,0x7 ,0xF1 ,0x20 ,0x6 ,0xC8 ,0x1 ,0x40 ,0x0 ,0xB ,0xE2 ,0x1 ,0x3C ,0x8 ,0xA0 ,0xFF ,0x4 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x10 ,0xC ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x84 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0xC ,0x0 ,0x0 ,0x20 ,0x0 ,0x71 ,0xFD ,0x0 ,0x0 ,0xB0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x5 ,0xB1 ,0x20 ,0x0 ,0xD0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x61 ,0x4 ,0x8C ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0xC0 ,0x24 ,0x58 ,0x4 ,0x10 ,0x44 ,0x0 ,0x88 ,0x84 ,0x81 ,0x30 ,0x9 ,0x28 ,0xFC ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xCC ,0xFB ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x2C ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x8 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x81 ,0x20 ,0x0 ,0x4 ,0x0 ,0xE3 ,0xF8 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC9 ,0xFA ,0x28 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x8 ,0xFF ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x63 ,0xF8 ,0x30 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x88 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE8 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF8 ,0xFE ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x80 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0xD0 ,0xFB ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x1 ,0x86 ,0x1 ,0x2 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x38 ,0x0 ,0x1 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x60 ,0xFE ,0x8 ,0x0 ,0x0 ,0x0 ,0x4 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x82 ,0x80 ,0x10 ,0x0 ,0x0 ,0x6 ,0x40 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x4 ,0x0 ,0x0 ,0x20 ,0x0 ,0x18 ,0xFD ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x24 ,0x40 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x74 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x78 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0xFF ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x58 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x14 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x8 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x50 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x10 ,0xFE ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF0 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xFD ,0xA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x18 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFE ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA8 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xDC ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0xC8 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x40 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x4 ,0x0 ,0x50 ,0xFC ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0xB0 ,0xFB ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x80 ,0x2 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x78 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x50 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0xA8 ,0xFC ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x8 ,0x0 ,0x0 ,0x0 ,0x78 ,0xF9 ,0xA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x80 ,0x0 ,0x80 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x80 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x8 ,0x88 ,0xFA ,0x0 ,0x40 ,0x10 ,0x0 ,0x0 ,0x80 ,0x81 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x50 ,0x0 ,0x0 ,0x40 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x1 ,0x80 ,0x0 ,0x10 ,0x40 ,0x0 ,0x0 ,0x1 ,0xA ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x24 ,0x0 ,0x4 ,0x20 ,0x88 ,0xFF ,0x0 ,0x8 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x52 ,0x84 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x42 ,0x0 ,0x8 ,0x28 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0x10 ,0x50 ,0x0 ,0x2 ,0x45 ,0x0 ,0x8 ,0x0 ,0x21 ,0x8 ,0xC ,0x28 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x98 ,0xFA ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x14 ,0x0 ,0x0 ,0x0 ,0x81 ,0x0 ,0x10 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x20 ,0x2 ,0x40 ,0x0 ,0x40 ,0x0 ,0x4 ,0x0 ,0x41 ,0x0 ,0x10 ,0xB8 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x12 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x38 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x48 ,0x0 ,0x0 ,0x8 ,0xA0 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0xD8 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x8 ,0x0 ,0x78 ,0xFE ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0xFD ,0x0 ,0x0 ,0x4 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x2 ,0x0 ,0x0 ,0xC ,0x8 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x42 ,0x0 ,0xC ,0x0 ,0x0 ,0x29 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2C ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0xB8 ,0xFF ,0x8 ,0x0 ,0x8 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x29 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x50 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0xF8 ,0xA0 ,0x80 ,0x0 ,0x80 ,0x0 ,0xD0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA0 ,0x1 ,0x4 ,0x92 ,0x22 ,0x0 ,0x0 ,0x2 ,0x40 ,0x0 ,0x28 ,0x2 ,0x0 ,0xA0 ,0x0 ,0x14 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x21 ,0x22 ,0x0 ,0x14 ,0x20 ,0x8 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x1 ,0x0 ,0x0 ,0x0 ,0x82 ,0x40 ,0x10 ,0x0 ,0x80 ,0x81 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x70 ,0xF8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x1 ,0x1C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x20 ,0x8 ,0x70 ,0xFD ,0x0 ,0x8 ,0x1 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x41 ,0x10 ,0x42 ,0x4 ,0x1 ,0x0 ,0x18 ,0x0 ,0x2 ,0x41 ,0x10 ,0x0 ,0x80 ,0x1 ,0x35 ,0x12 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x40 ,0x80 ,0x0 ,0xF0 ,0xF8 ,0x0 ,0x40 ,0x0 ,0x0 ,0x26 ,0xC0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x84 ,0x10 ,0x8 ,0x42 ,0x0 ,0x0 ,0x18 ,0x4 ,0xB ,0x21 ,0x4 ,0x0 ,0x80 ,0x1 ,0xB0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x80 ,0x8 ,0x0 ,0x0 ,0x22 ,0x44 ,0x88 ,0x1 ,0x0 ,0x2 ,0x48 ,0xF8 ,0xE0 ,0x1 ,0x0 ,0x80 ,0x7 ,0x34 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x3C ,0x80 ,0x5 ,0x2 ,0x0 ,0x1E ,0xC0 ,0x0 ,0x58 ,0x20 ,0x0 ,0xE0 ,0x41 ,0x2C ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0x0 ,0xF ,0xE0 ,0x41 ,0xC ,0x20 ,0x58 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x60 ,0x0 ,0xC ,0x4 ,0x0 ,0x0 ,0x0 ,0x60 ,0xFF ,0x80 ,0x85 ,0x0 ,0x0 ,0x20 ,0xC0 ,0x42 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0x30 ,0x8 ,0x86 ,0x0 ,0x0 ,0x58 ,0x4 ,0x40 ,0x60 ,0x8 ,0x0 ,0xC0 ,0x9 ,0x22 ,0x11 ,0x0 ,0x0 ,0x0 ,0x98 ,0x8 ,0x0 ,0x60 ,0x14 ,0xC ,0x80 ,0x91 ,0x80 ,0x10 ,0xE8 ,0xF8 ,0x20 ,0x88 ,0x0 ,0x80 ,0x2 ,0x12 ,0x44 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x84 ,0xA0 ,0x12 ,0x10 ,0x0 ,0x1A ,0x40 ,0x0 ,0x28 ,0x1 ,0x0 ,0xA0 ,0x1 ,0x0 ,0x80 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x68 ,0x0 ,0x81 ,0xA4 ,0x48 ,0x14 ,0x20 ,0xEC ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x1 ,0x0 ,0x18 ,0x0 ,0x0 ,0x62 ,0x10 ,0x0 ,0x80 ,0x81 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x90 ,0xFC ,0x0 ,0x40 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x10 ,0x6 ,0x2 ,0x0 ,0x18 ,0x4 ,0x80 ,0x60 ,0x20 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x80 ,0x0 ,0x20 ,0x8 ,0x80 ,0xFA ,0x88 ,0x1 ,0x0 ,0x0 ,0x20 ,0xC1 ,0x88 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x26 ,0x0 ,0x0 ,0x58 ,0x0 ,0x13 ,0x60 ,0x2 ,0x0 ,0x80 ,0x1 ,0x1 ,0x0 ,0x16 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x11 ,0x84 ,0x10 ,0x5 ,0x81 ,0x0 ,0x2B ,0xF8 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x9 ,0x31 ,0x8 ,0x10 ,0x0 ,0x44 ,0x18 ,0x4 ,0x8 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x46 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x44 ,0x82 ,0x10 ,0x0 ,0x2 ,0x59 ,0xFB ,0x60 ,0x41 ,0x0 ,0x80 ,0x7 ,0xB4 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x2C ,0x80 ,0x5 ,0x32 ,0x0 ,0x6 ,0xC0 ,0x82 ,0x58 ,0x0 ,0x0 ,0xE0 ,0x0 ,0x0 ,0x80 ,0x7 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x78 ,0x20 ,0xF ,0x60 ,0x81 ,0x3C ,0x20 ,0xB0 ,0xFA ,0x84 ,0x1 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0x0 ,0x0 ,0xC0 ,0x40 ,0x18 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0xAB ,0xF9 ,0x0 ,0x51 ,0x0 ,0x0 ,0x16 ,0x82 ,0x22 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0xA ,0x20 ,0xC8 ,0x2 ,0x58 ,0x4 ,0xA2 ,0x0 ,0x24 ,0x0 ,0x0 ,0x8 ,0x2 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x82 ,0x2C ,0x82 ,0x21 ,0xB0 ,0x10 ,0x80 ,0xFB ,0xB0 ,0x1 ,0x0 ,0x80 ,0x0 ,0xD1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA0 ,0x20 ,0x4 ,0x89 ,0x0 ,0x0 ,0x0 ,0x2 ,0x51 ,0x3 ,0x8 ,0x0 ,0x0 ,0xA0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x21 ,0x28 ,0x0 ,0x4 ,0x0 ,0xC0 ,0xFB ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x80 ,0x81 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x38 ,0xFC ,0x80 ,0x81 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x81 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x83 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x4 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xFC ,0x8C ,0x9 ,0x0 ,0x0 ,0x46 ,0xC4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x9 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x3 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x1 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x30 ,0x4 ,0x12 ,0xF8 ,0x4 ,0x40 ,0x0 ,0x0 ,0x20 ,0xC0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x84 ,0x10 ,0x0 ,0x26 ,0x0 ,0x0 ,0x80 ,0x0 ,0x20 ,0x60 ,0x2 ,0x0 ,0x80 ,0x5 ,0x0 ,0x0 ,0x40 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x2 ,0x4C ,0x82 ,0x49 ,0x0 ,0x1 ,0x40 ,0xF9 ,0xE8 ,0x1 ,0x0 ,0x80 ,0x5 ,0x31 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x1 ,0x3C ,0xA0 ,0x7 ,0x1 ,0x0 ,0x6 ,0xC8 ,0x3 ,0x7A ,0x10 ,0x0 ,0xE0 ,0x41 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x78 ,0x20 ,0xB ,0xE0 ,0x1 ,0x2C ,0x8 ,0x48 ,0xFF ,0x88 ,0x1 ,0x0 ,0x0 ,0x6 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x10 ,0x6 ,0x0 ,0x0 ,0x10 ,0x0 ,0x3 ,0x60 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0xC ,0x80 ,0x1 ,0x30 ,0x8 ,0xF9 ,0xF8 ,0x10 ,0x84 ,0x0 ,0x0 ,0x44 ,0xC0 ,0x42 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0x30 ,0x0 ,0x6 ,0x0 ,0x0 ,0x80 ,0x20 ,0x8 ,0x61 ,0x0 ,0x0 ,0xC0 ,0x9 ,0x2 ,0x0 ,0x20 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x8C ,0x82 ,0x1 ,0x20 ,0x2 ,0xB0 ,0xFB ,0x30 ,0x0 ,0x0 ,0x80 ,0x6 ,0xD0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA0 ,0x1 ,0x4 ,0x80 ,0x6 ,0x0 ,0x0 ,0x1A ,0x45 ,0x0 ,0x68 ,0x0 ,0x0 ,0xA0 ,0x1 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x68 ,0x0 ,0x1 ,0x20 ,0x0 ,0x34 ,0x0 ,0x24 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x81 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x81 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x20 ,0xC ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0xF9 ,0x80 ,0x1 ,0x0 ,0x0 ,0x6 ,0x32 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x18 ,0x4 ,0x3 ,0x0 ,0x10 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x20 ,0xC8 ,0xFC ,0x8C ,0x1 ,0x0 ,0x0 ,0x26 ,0x10 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x50 ,0x80 ,0x10 ,0x40 ,0x0 ,0x0 ,0x58 ,0x0 ,0x3 ,0x0 ,0x1 ,0x0 ,0x80 ,0x1 ,0x1 ,0x0 ,0x10 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x14 ,0x20 ,0x4 ,0x0 ,0x30 ,0x1 ,0x1B ,0xFD ,0x84 ,0x5 ,0x0 ,0x0 ,0x10 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x30 ,0x8 ,0x40 ,0x1 ,0x0 ,0x8 ,0x4 ,0xB ,0x0 ,0x12 ,0x0 ,0x0 ,0x8 ,0x2 ,0x0 ,0x40 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4C ,0x2 ,0x88 ,0x0 ,0x2 ,0xD1 ,0xF9 ,0xE8 ,0x81 ,0x0 ,0x80 ,0x7 ,0xF4 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA0 ,0x1 ,0x3C ,0x80 ,0x7 ,0x0 ,0x0 ,0x1E ,0xC0 ,0x3 ,0x79 ,0x0 ,0x0 ,0xE0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x68 ,0x0 ,0xF ,0x60 ,0x0 ,0x3C ,0x20 ,0xE8 ,0xF9 ,0x8 ,0x80 ,0x0 ,0x0 ,0x6 ,0xC0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0x0 ,0x80 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0x0 ,0x93 ,0xF9 ,0x10 ,0x8 ,0x0 ,0x0 ,0x10 ,0xC2 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x30 ,0x11 ,0x26 ,0x4 ,0x0 ,0x58 ,0x4 ,0x0 ,0x60 ,0x42 ,0x0 ,0x0 ,0x8 ,0x2 ,0x0 ,0x16 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x2C ,0x90 ,0x49 ,0x80 ,0x10 ,0x38 ,0xFD ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x24 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x11 ,0x34 ,0x80 ,0x6 ,0x0 ,0x0 ,0x0 ,0x40 ,0x3 ,0x8 ,0x0 ,0x0 ,0xA0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x4 ,0x41 ,0xA0 ,0x1 ,0x4 ,0x0 ,0xC4 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x81 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0xE8 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x31 ,0x8 ,0x6 ,0x1 ,0x0 ,0x0 ,0xC0 ,0x80 ,0x60 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x40 ,0x30 ,0x0 ,0x10 ,0xFA ,0x88 ,0x81 ,0x0 ,0x0 ,0x6 ,0x80 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x11 ,0xB0 ,0x0 ,0x16 ,0x0 ,0x0 ,0x0 ,0x40 ,0x8 ,0x0 ,0x12 ,0x0 ,0x80 ,0x1 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x24 ,0x8 ,0x1 ,0x4 ,0x30 ,0x0 ,0xC3 ,0xFC ,0x0 ,0x48 ,0x0 ,0x0 ,0x16 ,0x40 ,0x42 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x8 ,0x0 ,0x0 ,0x0 ,0x90 ,0x60 ,0x12 ,0x0 ,0x80 ,0x49 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x48 ,0x2 ,0x0 ,0xB0 ,0x0 ,0x39 ,0xFE ,0xE0 ,0x1 ,0x0 ,0x80 ,0x7 ,0x32 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x3C ,0x90 ,0x7 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x3 ,0x78 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0xF ,0xE0 ,0x41 ,0x3C ,0x10 ,0xD8 ,0xFC ,0x84 ,0x41 ,0x0 ,0x0 ,0x0 ,0x42 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0xC ,0x80 ,0x1 ,0x0 ,0x20 ,0x93 ,0xFF ,0x80 ,0x5 ,0x0 ,0x0 ,0x20 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x42 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x93 ,0x60 ,0x22 ,0x0 ,0xC0 ,0x9 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0xC ,0x82 ,0x9 ,0x1 ,0x1 ,0xF8 ,0xF8 ,0x30 ,0x30 ,0x0 ,0x80 ,0x2 ,0x12 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x84 ,0x34 ,0x80 ,0x0 ,0x1 ,0x0 ,0x2 ,0x51 ,0x0 ,0x68 ,0x0 ,0x0 ,0xA0 ,0x1 ,0x4 ,0x80 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0xD ,0xA0 ,0x1 ,0x4 ,0x0 ,0x8 ,0xFC ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x81 ,0x0 ,0x8 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0xF9 ,0x0 ,0x80 ,0x0 ,0x0 ,0x4 ,0xF0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x83 ,0x60 ,0x10 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0xC ,0x82 ,0x41 ,0x0 ,0x0 ,0x80 ,0xFE ,0xC ,0x4 ,0x0 ,0x0 ,0x20 ,0xD1 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x20 ,0x0 ,0x0 ,0x40 ,0x8 ,0x0 ,0x0 ,0x42 ,0xB ,0x60 ,0x0 ,0x0 ,0x80 ,0x1 ,0x31 ,0x4 ,0x16 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x8 ,0xC ,0x80 ,0x1 ,0x0 ,0x0 ,0x22 ,0xFD ,0x84 ,0x49 ,0x0 ,0x0 ,0x10 ,0x0 ,0x24 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x42 ,0x1 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x81 ,0x0 ,0x0 ,0x10 ,0x2 ,0xA ,0x46 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x20 ,0x10 ,0x10 ,0x32 ,0x6 ,0xA8 ,0xFD ,0xE8 ,0x1 ,0x0 ,0x80 ,0x1 ,0xF4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3C ,0xA0 ,0x7 ,0x0 ,0x0 ,0x6 ,0xC8 ,0x83 ,0x78 ,0x0 ,0x0 ,0xE0 ,0x0 ,0x2C ,0x80 ,0x7 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF ,0xE0 ,0x1 ,0x3C ,0x0 ,0xC8 ,0xFF ,0x88 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x30 ,0x20 ,0x6 ,0x4 ,0x0 ,0x10 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x30 ,0x8 ,0x6 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0xA9 ,0xFD ,0x90 ,0x9 ,0x0 ,0x0 ,0x10 ,0xC2 ,0x42 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0xB0 ,0x0 ,0x16 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB ,0x1 ,0x0 ,0x0 ,0x0 ,0x8 ,0x22 ,0x1 ,0x16 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x80 ,0x10 ,0x0 ,0x0 ,0x21 ,0x80 ,0xF9 ,0xA0 ,0x50 ,0x0 ,0x80 ,0x42 ,0xD0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x81 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x1A ,0x51 ,0x3 ,0x8 ,0x10 ,0x0 ,0xA0 ,0x0 ,0x34 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x20 ,0xD ,0x20 ,0x40 ,0x14 ,0x1 ,0x34 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x80 ,0x81 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x10 ,0xB0 ,0xF9 ,0xE0 ,0x0 ,0x1 ,0x80 ,0x7 ,0xF1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x1 ,0x10 ,0x6 ,0x0 ,0x0 ,0x18 ,0xC0 ,0x83 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0x20 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x2 ,0x0 ,0x3C ,0x8 ,0x0 ,0xFD ,0xA8 ,0x1 ,0x0 ,0x80 ,0x2 ,0x10 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x11 ,0x80 ,0x0 ,0x20 ,0x1 ,0x0 ,0x18 ,0x42 ,0x8 ,0x0 ,0x21 ,0x0 ,0x80 ,0x1 ,0x31 ,0x1 ,0x10 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x24 ,0x40 ,0x0 ,0x84 ,0x14 ,0x0 ,0x73 ,0xFC ,0x80 ,0x11 ,0x0 ,0x0 ,0x14 ,0x0 ,0x24 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x46 ,0x1 ,0x0 ,0x90 ,0x0 ,0x0 ,0x20 ,0x12 ,0x0 ,0x80 ,0x51 ,0x30 ,0x2 ,0x40 ,0x2 ,0x44 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x88 ,0x0 ,0xA0 ,0x0 ,0x9 ,0xFB ,0x60 ,0x41 ,0x0 ,0x80 ,0x7 ,0x31 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x3C ,0xA0 ,0x7 ,0x0 ,0x0 ,0x1E ,0xC8 ,0x80 ,0x78 ,0x0 ,0x0 ,0xE0 ,0x1 ,0xC ,0xA0 ,0x1 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0xF ,0xE0 ,0x41 ,0x3C ,0x8 ,0x70 ,0xFB ,0x84 ,0x1 ,0x0 ,0x0 ,0x4 ,0xC0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x10 ,0x83 ,0x60 ,0x40 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0xC4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0xC ,0x88 ,0x1 ,0x21 ,0x0 ,0x2B ,0xF8 ,0x0 ,0x49 ,0x0 ,0x0 ,0x6 ,0xC1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0x11 ,0x46 ,0x2 ,0x0 ,0x58 ,0x0 ,0x3 ,0x60 ,0x1 ,0x0 ,0xC0 ,0x9 ,0xB2 ,0x10 ,0x10 ,0xC0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x2C ,0x80 ,0x5 ,0x30 ,0x8 ,0xE8 ,0xFB ,0x30 ,0x0 ,0x0 ,0x80 ,0x2 ,0x91 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x4 ,0x81 ,0x0 ,0x0 ,0x0 ,0x1A ,0x51 ,0x81 ,0x8 ,0x0 ,0x0 ,0xA0 ,0x1 ,0x34 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x4 ,0x1 ,0x20 ,0x0 ,0x14 ,0x20 ,0x8 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x41 ,0x0 ,0x10 ,0x6 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x80 ,0x81 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x10 ,0xC ,0x80 ,0x1 ,0x0 ,0x0 ,0x80 ,0xFE ,0x60 ,0x0 ,0x0 ,0x80 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x18 ,0xC0 ,0x1 ,0x0 ,0x20 ,0x0 ,0x80 ,0x1 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x4 ,0x80 ,0x20 ,0x8 ,0x80 ,0xF8 ,0x2C ,0x0 ,0x0 ,0x80 ,0x6 ,0x4 ,0x2 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x4 ,0x10 ,0x0 ,0x0 ,0x18 ,0x42 ,0x93 ,0x0 ,0x1 ,0x0 ,0x80 ,0x1 ,0x31 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x3A ,0xFE ,0x84 ,0x49 ,0x0 ,0x0 ,0x46 ,0xC4 ,0x42 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x85 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x20 ,0x8 ,0x46 ,0x1 ,0x0 ,0x90 ,0x0 ,0x23 ,0x60 ,0x12 ,0x0 ,0x0 ,0x30 ,0x30 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4C ,0x88 ,0x1 ,0x0 ,0x2 ,0xF8 ,0xFD ,0xE8 ,0x1 ,0x0 ,0x80 ,0x5 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x3C ,0x80 ,0x7 ,0x0 ,0x0 ,0x1E ,0xC8 ,0x82 ,0x78 ,0x0 ,0x0 ,0xE0 ,0x0 ,0xC ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0xF ,0xE0 ,0x41 ,0x3C ,0x20 ,0xE8 ,0xFC ,0x88 ,0x1 ,0x0 ,0x0 ,0x6 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x3 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x21 ,0xF8 ,0xB0 ,0x1 ,0x0 ,0x0 ,0x14 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x30 ,0x9 ,0x16 ,0x8 ,0x0 ,0x18 ,0x21 ,0x12 ,0x60 ,0x81 ,0x0 ,0x0 ,0x8 ,0xB2 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x2C ,0x90 ,0x1 ,0xB2 ,0x10 ,0xF0 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x24 ,0x0 ,0x6 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0xE9 ,0xFA ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE3 ,0xF8 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x78 ,0xFA ,0x8 ,0x1 ,0x0 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x1A ,0xF8 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x4 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0xD8 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x28 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFE ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0xF1 ,0xF9 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x18 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x1 ,0x4 ,0x40 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x8 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x10 ,0x8 ,0x20 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x1 ,0x4 ,0x80 ,0x50 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x2D ,0x1 ,0x20 ,0x14 ,0x10 ,0x0 ,0x80 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x4 ,0x30 ,0x70 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x11 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x4 ,0x1 ,0x40 ,0x3 ,0x50 ,0x4 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x84 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x20 ,0x0 ,0x19 ,0x0 ,0x0 ,0x90 ,0xE ,0x20 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x10 ,0x50 ,0xFC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x1 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x8 ,0x91 ,0xF9 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x4 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x60 ,0xFE ,0x0 ,0x0 ,0x1 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE8 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x60 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x50 ,0xFA ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0xF0 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xDC ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0xB8 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x50 ,0xFF ,0x0 ,0x1 ,0x0 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0xFA ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0xA ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x40 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x30 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xFF ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA8 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0xF9 ,0x8C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF8 ,0xFB ,0x10 ,0x0 ,0x0 ,0x0 ,0x2 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x1 ,0x1 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x81 ,0x0 ,0x10 ,0x0 ,0x80 ,0x40 ,0x0 ,0x0 ,0x2 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0xC2 ,0xFF ,0x40 ,0x0 ,0x0 ,0x80 ,0xC ,0x10 ,0x78 ,0x0 ,0x3 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x13 ,0x0 ,0x0 ,0x0 ,0x1 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x80 ,0x0 ,0x0 ,0x1 ,0x0 ,0x80 ,0x0 ,0x40 ,0x0 ,0xC2 ,0x40 ,0x0 ,0x20 ,0x3 ,0x1 ,0x80 ,0x0 ,0x10 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x1 ,0x0 ,0xA4 ,0x0 ,0xF0 ,0xFB ,0x80 ,0x0 ,0x0 ,0x0 ,0x10 ,0x20 ,0x8A ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x14 ,0x4 ,0x84 ,0x40 ,0x18 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x21 ,0x20 ,0x4 ,0xC0 ,0xFF ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA0 ,0x0 ,0x4 ,0x20 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x20 ,0x0 ,0x11 ,0x10 ,0x78 ,0xFE ,0x40 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x81 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x80 ,0x0 ,0xC0 ,0xFE ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x40 ,0x0 ,0x0 ,0x80 ,0xA0 ,0xFB ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x51 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x40 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x10 ,0x1 ,0x0 ,0x0 ,0x88 ,0xF9 ,0x16 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x80 ,0x20 ,0xFA ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x68 ,0xFC ,0xA0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x50 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x1 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB0 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF8 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFD ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x34 ,0x80 ,0x40 ,0x50 ,0x8 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x10 ,0x2 ,0x80 ,0x22 ,0x2 ,0x0 ,0x2 ,0x0 ,0x0 ,0x28 ,0x2 ,0x45 ,0x4 ,0x0 ,0x14 ,0x21 ,0xB0 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC1 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x50 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0xC2 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x20 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x8 ,0x58 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x42 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x8 ,0x6 ,0xC0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x21 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x4 ,0x0 ,0x40 ,0x10 ,0x80 ,0x2 ,0x0 ,0x80 ,0x0 ,0x30 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x22 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x11 ,0x20 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x18 ,0x0 ,0x0 ,0x20 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x40 ,0x58 ,0xFC ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3C ,0x80 ,0x5 ,0xF1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0xE0 ,0x41 ,0x0 ,0x80 ,0x7 ,0x0 ,0x0 ,0x1E ,0x4 ,0x0 ,0x58 ,0x20 ,0xF ,0x4 ,0x0 ,0x3C ,0x0 ,0x8 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0xC1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x20 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x68 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x26 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x10 ,0x4 ,0xE0 ,0x4 ,0x1 ,0x0 ,0x0 ,0x60 ,0x4 ,0x0 ,0x80 ,0x41 ,0x0 ,0x0 ,0x6 ,0x4 ,0x0 ,0x18 ,0x20 ,0x0 ,0x60 ,0x82 ,0xC ,0x8 ,0x0 ,0x30 ,0x5 ,0x98 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x80 ,0x42 ,0xD0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x10 ,0x4 ,0xA0 ,0x0 ,0x2 ,0x0 ,0x4A ,0x0 ,0x0 ,0x28 ,0x1 ,0x21 ,0x0 ,0x0 ,0x84 ,0x0 ,0xC ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC1 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x4 ,0x0 ,0x60 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x10 ,0x20 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x3 ,0xC0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x8 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x8 ,0xF8 ,0x8 ,0x0 ,0x0 ,0x0 ,0x46 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x16 ,0xC1 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x90 ,0x30 ,0x0 ,0x6 ,0x0 ,0x0 ,0x50 ,0x10 ,0x0 ,0x60 ,0x41 ,0x8C ,0x8 ,0x0 ,0x30 ,0x0 ,0x4B ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x6 ,0x0 ,0x88 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x20 ,0x20 ,0x2 ,0x0 ,0x80 ,0x0 ,0x21 ,0xFC ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3C ,0x90 ,0x5 ,0x71 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x41 ,0x2C ,0x88 ,0x5 ,0x1 ,0x0 ,0x16 ,0x8 ,0x0 ,0x58 ,0x0 ,0xB ,0x0 ,0x0 ,0x2C ,0x8 ,0xC0 ,0xF9 ,0x4 ,0x0 ,0x0 ,0x0 ,0x4 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x6 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0xC ,0x2 ,0x0 ,0x30 ,0x8 ,0xCB ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x4 ,0x0 ,0x4 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x45 ,0x20 ,0xA ,0x44 ,0x1 ,0x0 ,0x18 ,0x2 ,0x0 ,0x0 ,0x4 ,0x8 ,0x0 ,0x0 ,0x20 ,0x2 ,0x10 ,0xFD ,0x10 ,0x0 ,0x0 ,0x80 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x14 ,0xC1 ,0x10 ,0x50 ,0x8 ,0x1A ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x10 ,0x34 ,0x80 ,0x6 ,0x0 ,0x0 ,0x1A ,0x0 ,0x0 ,0x8 ,0x0 ,0x25 ,0x20 ,0x0 ,0x34 ,0x0 ,0x50 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x6 ,0xC1 ,0x40 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x30 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x30 ,0x0 ,0x50 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x10 ,0x0 ,0xC0 ,0x80 ,0x18 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x81 ,0x30 ,0x0 ,0x6 ,0x2 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x7 ,0x8 ,0x0 ,0x30 ,0x20 ,0x40 ,0xF9 ,0xC ,0x0 ,0x0 ,0x0 ,0x42 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x1 ,0x24 ,0xC2 ,0x4 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x30 ,0x40 ,0x46 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4D ,0x0 ,0x0 ,0x30 ,0x2 ,0x5A ,0xFC ,0x4 ,0x0 ,0x0 ,0x0 ,0x22 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x11 ,0x12 ,0xC2 ,0x2 ,0x58 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x2 ,0xC ,0x0 ,0x84 ,0x80 ,0x40 ,0x58 ,0xFB ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2C ,0x80 ,0x1 ,0xF0 ,0x20 ,0x6 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x41 ,0x3C ,0x80 ,0x7 ,0x0 ,0x0 ,0x1E ,0x4 ,0x0 ,0x78 ,0x10 ,0xB ,0x64 ,0x0 ,0x3C ,0x0 ,0x50 ,0xFC ,0xC ,0x0 ,0x0 ,0x0 ,0x6 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0xC2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0x20 ,0x6 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x60 ,0x0 ,0xC ,0x82 ,0x81 ,0x30 ,0x0 ,0x11 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x46 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x10 ,0x20 ,0xE0 ,0x4 ,0x19 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x51 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x18 ,0x11 ,0x0 ,0x60 ,0x0 ,0x48 ,0x80 ,0x11 ,0x0 ,0x5 ,0xF8 ,0xFE ,0x0 ,0x0 ,0x0 ,0x80 ,0x40 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x34 ,0x92 ,0x6 ,0xD0 ,0x8 ,0x1A ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x68 ,0x0 ,0x1 ,0x0 ,0x0 ,0x14 ,0x21 ,0x58 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x6 ,0xC0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x48 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x6 ,0xC1 ,0x80 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x20 ,0x8 ,0x20 ,0xFD ,0xC ,0x0 ,0x0 ,0x0 ,0x84 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA ,0x16 ,0xC0 ,0x4 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x28 ,0x30 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0xA ,0xFF ,0x4 ,0x0 ,0x0 ,0x0 ,0x24 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x16 ,0x8 ,0x8 ,0x58 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0x22 ,0x46 ,0x0 ,0x0 ,0x58 ,0x0 ,0x0 ,0x0 ,0x14 ,0x4C ,0x0 ,0x0 ,0x80 ,0x40 ,0xC0 ,0xFF ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x34 ,0x80 ,0x1 ,0x70 ,0x80 ,0x6 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x41 ,0x3C ,0x80 ,0x7 ,0x4 ,0x0 ,0x1E ,0x4 ,0x0 ,0x78 ,0x0 ,0xF ,0x8 ,0x0 ,0x3C ,0x0 ,0x60 ,0xFB ,0xC ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x18 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE9 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x16 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0xA6 ,0x0 ,0x4 ,0x19 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x11 ,0x0 ,0x40 ,0x40 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x60 ,0x42 ,0x20 ,0x2 ,0x0 ,0x30 ,0x5 ,0xB0 ,0xFD ,0x0 ,0x0 ,0x0 ,0x80 ,0x10 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x81 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0xA1 ,0x0 ,0x50 ,0x8 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x44 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x68 ,0x0 ,0x5 ,0x8 ,0x0 ,0x4 ,0x0 ,0x58 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x80 ,0x7 ,0xC1 ,0x80 ,0x1E ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x10 ,0xF ,0x2 ,0x0 ,0x30 ,0x0 ,0x70 ,0xFE ,0x8 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x44 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x8 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x91 ,0x46 ,0xC0 ,0x4 ,0x1A ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x30 ,0x11 ,0x26 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x1 ,0x85 ,0x0 ,0x0 ,0x30 ,0x0 ,0x62 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x26 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x44 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x48 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0xC0 ,0x24 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x9 ,0x20 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x88 ,0x0 ,0x0 ,0x30 ,0x4 ,0xA8 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x80 ,0x5 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x80 ,0x7 ,0xF1 ,0x0 ,0x1E ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x3D ,0x80 ,0x7 ,0x0 ,0x0 ,0x6 ,0x4 ,0x0 ,0x78 ,0x0 ,0xF ,0x2 ,0x0 ,0x3C ,0x0 ,0xB0 ,0xFC ,0x4 ,0x0 ,0x0 ,0x0 ,0x6 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x41 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0xC1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0x8 ,0x6 ,0x1 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x20 ,0x8 ,0x0 ,0x0 ,0x0 ,0x20 ,0x29 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x16 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x26 ,0xE0 ,0x4 ,0x19 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0xB1 ,0x0 ,0x16 ,0x0 ,0x0 ,0x98 ,0x10 ,0x0 ,0x0 ,0x0 ,0x4C ,0x2 ,0x0 ,0x0 ,0x2 ,0x68 ,0xF8 ,0x10 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x91 ,0x6 ,0xD0 ,0x8 ,0x2 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA0 ,0x1 ,0x4 ,0x90 ,0x20 ,0x0 ,0x0 ,0x1A ,0x0 ,0x0 ,0x8 ,0x10 ,0xD ,0x0 ,0x0 ,0x4 ,0x0 ,0x14 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0xC0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0xA8 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x80 ,0x7 ,0xC1 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x41 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x18 ,0x4 ,0x0 ,0x0 ,0x0 ,0xC ,0x4 ,0x0 ,0x0 ,0x0 ,0x20 ,0xF9 ,0xC ,0x0 ,0x0 ,0x0 ,0xA0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x84 ,0x20 ,0xC0 ,0x4 ,0x18 ,0x11 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x24 ,0x8C ,0x0 ,0x0 ,0x0 ,0x0 ,0x93 ,0xFD ,0x4 ,0x0 ,0x0 ,0x0 ,0x26 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x10 ,0x0 ,0x84 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0x30 ,0x9 ,0x26 ,0x1 ,0x0 ,0x80 ,0x8 ,0x0 ,0x20 ,0x14 ,0x20 ,0x0 ,0x0 ,0x30 ,0x12 ,0x59 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x71 ,0x0 ,0x16 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x3C ,0x80 ,0x7 ,0x0 ,0x0 ,0x1E ,0x0 ,0x0 ,0x78 ,0x0 ,0xF ,0x4 ,0x0 ,0x3C ,0x0 ,0xA0 ,0xFD ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x6 ,0x1 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x8 ,0x2 ,0x1 ,0x0 ,0x0 ,0x8 ,0x0 ,0x60 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x16 ,0x0 ,0x4 ,0x11 ,0x5 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0x30 ,0x1 ,0x26 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x20 ,0x0 ,0x8 ,0x0 ,0x80 ,0x10 ,0xF8 ,0xFC ,0x10 ,0x0 ,0x0 ,0x80 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x6 ,0x50 ,0x8 ,0x1A ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA0 ,0x1 ,0x14 ,0x8A ,0x42 ,0x1 ,0x0 ,0x2 ,0x4 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x14 ,0x21 ,0x68 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x10 ,0x0 ,0xC0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x10 ,0x0 ,0xC1 ,0x80 ,0x1E ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x1C ,0x80 ,0x3 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0xC ,0x0 ,0x0 ,0x20 ,0x8 ,0x40 ,0xFB ,0xC ,0x0 ,0x0 ,0x0 ,0x22 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x1 ,0x16 ,0xC0 ,0x4 ,0x2 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0xB4 ,0xA0 ,0x26 ,0x0 ,0x0 ,0x0 ,0x9 ,0x0 ,0x0 ,0x12 ,0xC ,0x0 ,0x0 ,0x80 ,0x0 ,0xDA ,0xFC ,0x4 ,0x0 ,0x0 ,0x0 ,0x42 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x16 ,0xC8 ,0x28 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x2 ,0x46 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x60 ,0x14 ,0x8C ,0x0 ,0x0 ,0x80 ,0x40 ,0xB0 ,0xFA ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0xF0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x2D ,0x88 ,0x5 ,0x1 ,0x0 ,0x1E ,0x4 ,0x0 ,0x78 ,0x0 ,0xF ,0x8 ,0x0 ,0xC ,0x0 ,0x70 ,0xFB ,0x8 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x18 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x59 ,0xFD ,0x10 ,0x0 ,0x0 ,0x0 ,0x6 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0xA6 ,0xE0 ,0x4 ,0x19 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x81 ,0x20 ,0x20 ,0x24 ,0x1 ,0x0 ,0x18 ,0x8 ,0x0 ,0x60 ,0x80 ,0x80 ,0x0 ,0x0 ,0x0 ,0x5 ,0x70 ,0xFA ,0x0 ,0x0 ,0x0 ,0x80 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x9 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x80 ,0x0 ,0xD0 ,0x8 ,0x1A ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x45 ,0x4 ,0x0 ,0x14 ,0x22 ,0xA8 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x8 ,0x0 ,0xC0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x48 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x80 ,0x7 ,0xC1 ,0x80 ,0x6 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0xC ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x8 ,0x0 ,0x0 ,0x3C ,0x8 ,0xD0 ,0xFD ,0x4 ,0x0 ,0x0 ,0x0 ,0x22 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8C ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x11 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x80 ,0x26 ,0xC0 ,0x4 ,0x2 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x1 ,0x80 ,0x2 ,0x0 ,0x14 ,0x1 ,0x1A ,0xFD ,0xC ,0x0 ,0x0 ,0x0 ,0x2 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x10 ,0x0 ,0x42 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0x9 ,0x26 ,0x1 ,0x0 ,0x18 ,0x0 ,0x0 ,0x60 ,0x14 ,0x20 ,0x0 ,0x0 ,0x20 ,0x2 ,0x18 ,0xFE ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x80 ,0x7 ,0x71 ,0x0 ,0x1E ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x3D ,0x80 ,0x7 ,0x0 ,0x0 ,0x1E ,0x4 ,0x0 ,0x78 ,0x0 ,0x3 ,0x4 ,0x0 ,0x3C ,0x8 ,0x10 ,0xFD ,0x8 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x30 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x69 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x26 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x11 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0xA6 ,0x0 ,0x4 ,0x99 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x11 ,0x34 ,0x80 ,0x6 ,0x0 ,0x0 ,0x18 ,0x1 ,0x0 ,0x60 ,0x8 ,0x0 ,0x8 ,0x0 ,0x30 ,0x9 ,0xE8 ,0xF8 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xCC ,0xFB ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x2C ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x84 ,0x90 ,0x10 ,0x12 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x53 ,0xFA ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC9 ,0xFA ,0x28 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x58 ,0xFC ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x6B ,0xFB ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF8 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x28 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xD8 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0xE8 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x84 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x4 ,0x86 ,0x1 ,0x82 ,0x16 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x28 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x5 ,0x0 ,0x20 ,0xE8 ,0xFA ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x84 ,0x81 ,0x18 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x19 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x1 ,0xC ,0x0 ,0x0 ,0x30 ,0x0 ,0xA0 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0xFD ,0x8 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x80 ,0x0 ,0x24 ,0x20 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x58 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x22 ,0x0 ,0x0 ,0x80 ,0x40 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0xD0 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x8 ,0x0 ,0x4 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x18 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xD0 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0xFF ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0xA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF0 ,0xF9 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0xB8 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x9C ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xD8 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x5 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x8 ,0x0 ,0x0 ,0x1 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB0 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0xF0 ,0xFD ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x4 ,0x0 ,0x28 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF8 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x80 ,0xCC ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC8 ,0xFD ,0x2 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x70 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0xFB ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x80 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x10 ,0x4 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x80 ,0xA8 ,0xF8 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x1 ,0x0 ,0xA1 ,0x10 ,0x14 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x5 ,0xB0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x40 ,0x1 ,0x0 ,0x4 ,0x0 ,0x60 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x48 ,0x1 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x48 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x84 ,0x81 ,0x0 ,0x12 ,0x2 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x6 ,0x0 ,0x0 ,0x10 ,0x80 ,0x4 ,0x0 ,0x0 ,0xC ,0x20 ,0x2 ,0x0 ,0xC ,0x60 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x10 ,0xB8 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x14 ,0x0 ,0x2 ,0x4 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x10 ,0x20 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x38 ,0xFF ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x70 ,0xFC ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x30 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0xF8 ,0xFD ,0x4 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x8 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF8 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x90 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x48 ,0xFE ,0xA0 ,0x80 ,0x24 ,0x86 ,0x20 ,0x4 ,0x0 ,0x1A ,0x40 ,0x0 ,0x6A ,0x81 ,0x1 ,0xA0 ,0x89 ,0x4 ,0xA2 ,0xC0 ,0xD0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x68 ,0x0 ,0x41 ,0x24 ,0x84 ,0x34 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA0 ,0x89 ,0x0 ,0x80 ,0x2 ,0x4 ,0x0 ,0x0 ,0x40 ,0x10 ,0x1 ,0x0 ,0x0 ,0xA0 ,0x89 ,0x34 ,0x0 ,0x0 ,0x0 ,0x0 ,0x82 ,0x60 ,0x90 ,0x0 ,0x0 ,0x41 ,0x0 ,0x0 ,0x0 ,0x0 ,0x58 ,0xFF ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x40 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x20 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x70 ,0xFB ,0x80 ,0x1 ,0x2C ,0x80 ,0x5 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x10 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x8 ,0x80 ,0x1 ,0x30 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x4 ,0x1 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x18 ,0x10 ,0x81 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0xE0 ,0xFA ,0x0 ,0x84 ,0x4 ,0xA2 ,0x0 ,0x8 ,0x0 ,0x98 ,0x8 ,0x51 ,0x0 ,0x80 ,0x20 ,0x90 ,0x85 ,0x10 ,0x1 ,0xA4 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x60 ,0x84 ,0x20 ,0x4 ,0x91 ,0x30 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x85 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x1 ,0x0 ,0x0 ,0x80 ,0x85 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x10 ,0x1 ,0x0 ,0x0 ,0x0 ,0x4C ,0x0 ,0x0 ,0x0 ,0x0 ,0xB0 ,0xFE ,0x0 ,0x49 ,0x10 ,0x8 ,0x44 ,0x0 ,0x0 ,0x18 ,0x1 ,0x22 ,0x62 ,0x1 ,0x0 ,0x4 ,0x84 ,0x20 ,0x2 ,0x44 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x60 ,0x4 ,0x80 ,0x1 ,0x11 ,0x30 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x10 ,0x2 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x80 ,0x31 ,0xB0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x1 ,0x0 ,0x1 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0xFD ,0xE0 ,0x1 ,0x3C ,0x0 ,0x1 ,0x1 ,0x0 ,0x1E ,0xC8 ,0x0 ,0x78 ,0x10 ,0x3 ,0x60 ,0x1 ,0xC ,0x88 ,0x1 ,0x31 ,0x0 ,0x0 ,0x0 ,0x0 ,0x78 ,0x20 ,0x3 ,0x60 ,0x40 ,0x3C ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x0 ,0x80 ,0x7 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x82 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x3C ,0x8 ,0x0 ,0x0 ,0x0 ,0x6 ,0xC4 ,0x0 ,0x0 ,0x0 ,0xB ,0x2 ,0x0 ,0x0 ,0x0 ,0xA8 ,0xF8 ,0x0 ,0x0 ,0x11 ,0x0 ,0x4 ,0x1 ,0x0 ,0x0 ,0x8 ,0x2 ,0x40 ,0x0 ,0x0 ,0x80 ,0x1 ,0x20 ,0x0 ,0x6 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x82 ,0x81 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x83 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x21 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x2 ,0x0 ,0x0 ,0x0 ,0x68 ,0xF9 ,0x80 ,0x11 ,0x30 ,0x0 ,0x2 ,0x0 ,0x0 ,0x18 ,0x1 ,0x10 ,0x2 ,0x10 ,0x40 ,0x84 ,0x5 ,0x2 ,0x41 ,0x26 ,0x0 ,0x88 ,0x0 ,0x0 ,0x0 ,0x60 ,0x4 ,0x40 ,0x80 ,0x1 ,0x30 ,0x41 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x5 ,0x2 ,0x0 ,0x16 ,0x0 ,0x0 ,0x0 ,0x0 ,0x13 ,0x0 ,0x0 ,0x0 ,0x80 ,0x5 ,0x0 ,0x5 ,0x0 ,0x0 ,0x0 ,0x98 ,0x8 ,0x10 ,0x1 ,0x0 ,0x88 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF8 ,0xF9 ,0xA0 ,0x88 ,0x0 ,0x80 ,0x0 ,0xD4 ,0x0 ,0x42 ,0x60 ,0x3 ,0x48 ,0xC ,0x4D ,0x24 ,0x89 ,0x4 ,0x80 ,0x0 ,0x50 ,0x2 ,0x0 ,0x40 ,0x0 ,0x8 ,0x81 ,0x21 ,0x22 ,0x4 ,0x84 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x88 ,0x0 ,0x80 ,0x40 ,0x8 ,0x0 ,0x42 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x34 ,0x11 ,0x0 ,0x10 ,0x0 ,0x2 ,0x41 ,0x0 ,0x8 ,0x84 ,0xD ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x8 ,0x0 ,0xC ,0x80 ,0x1 ,0x20 ,0x10 ,0x0 ,0x84 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0xF9 ,0x80 ,0x0 ,0x0 ,0x0 ,0x6 ,0xC0 ,0x40 ,0x18 ,0x0 ,0x3 ,0x58 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x6 ,0x42 ,0x0 ,0x0 ,0x0 ,0x3 ,0x60 ,0x0 ,0x4 ,0x82 ,0x1 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x18 ,0x0 ,0x3 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x28 ,0xFF ,0x8 ,0x81 ,0x0 ,0x0 ,0x84 ,0xC0 ,0x8 ,0x10 ,0x20 ,0xB ,0x9 ,0x12 ,0x20 ,0x4 ,0x84 ,0x0 ,0x2 ,0x4 ,0x80 ,0x48 ,0x0 ,0x0 ,0x3 ,0x40 ,0x80 ,0x0 ,0x80 ,0x85 ,0x20 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x84 ,0x0 ,0x0 ,0x26 ,0x0 ,0x0 ,0x90 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x41 ,0x0 ,0x0 ,0x44 ,0x10 ,0x11 ,0x3 ,0x60 ,0x11 ,0x2C ,0x2 ,0x0 ,0x0 ,0x0 ,0x12 ,0xFC ,0x80 ,0x5 ,0x0 ,0x0 ,0x14 ,0xC0 ,0x82 ,0x50 ,0x0 ,0x23 ,0x20 ,0x10 ,0x2C ,0x84 ,0x85 ,0x30 ,0x4 ,0x14 ,0xC0 ,0x10 ,0x0 ,0x0 ,0x8B ,0x40 ,0x1 ,0x20 ,0x8 ,0x20 ,0xA0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x31 ,0x0 ,0x0 ,0x20 ,0x1 ,0x0 ,0x18 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0xB1 ,0x8 ,0x0 ,0xC0 ,0x8 ,0x50 ,0x0 ,0x13 ,0x4 ,0x2 ,0x2C ,0x4 ,0x0 ,0x0 ,0x0 ,0xD0 ,0xFD ,0x60 ,0x41 ,0x0 ,0x80 ,0x1 ,0xF1 ,0x0 ,0x6 ,0xC4 ,0x3 ,0x79 ,0x0 ,0xF ,0xE0 ,0x1 ,0xC ,0x80 ,0x1 ,0xB1 ,0x0 ,0x0 ,0xC0 ,0x3 ,0x18 ,0x10 ,0x3 ,0xE0 ,0x0 ,0xC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x0 ,0x0 ,0x80 ,0x5 ,0x0 ,0x0 ,0x1E ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x3C ,0x0 ,0x0 ,0xB0 ,0x20 ,0x6 ,0xC4 ,0x3 ,0x58 ,0x10 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0xD8 ,0xFF ,0x84 ,0x0 ,0x0 ,0x0 ,0x6 ,0xC1 ,0x0 ,0x18 ,0x0 ,0x0 ,0x20 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x42 ,0x40 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x84 ,0x81 ,0x30 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x1 ,0x0 ,0x8 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x20 ,0x20 ,0x0 ,0xC0 ,0x0 ,0x18 ,0x0 ,0x3 ,0x60 ,0x10 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x19 ,0xF9 ,0x0 ,0x11 ,0x1 ,0x0 ,0x6 ,0xC0 ,0x42 ,0x98 ,0x8 ,0x13 ,0x64 ,0x0 ,0x20 ,0x10 ,0x4 ,0x82 ,0x20 ,0x26 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x61 ,0x84 ,0x20 ,0x80 ,0x1 ,0x30 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x2 ,0x0 ,0x14 ,0x0 ,0x0 ,0x18 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x85 ,0x80 ,0x0 ,0x0 ,0xC0 ,0x22 ,0x98 ,0x8 ,0xB ,0x41 ,0x1 ,0x2C ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0xFF ,0xA0 ,0x88 ,0x0 ,0x80 ,0x80 ,0x10 ,0x20 ,0x2 ,0x50 ,0x8 ,0x6C ,0x40 ,0x85 ,0x22 ,0x88 ,0x84 ,0x90 ,0x40 ,0xD4 ,0x4 ,0x1 ,0x40 ,0x2 ,0x8 ,0x40 ,0x1 ,0x20 ,0x80 ,0x4 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x2 ,0x4 ,0x0 ,0x2 ,0x3 ,0x0 ,0x0 ,0x0 ,0x49 ,0xA0 ,0x89 ,0x34 ,0x21 ,0x0 ,0x10 ,0x18 ,0x4A ,0x40 ,0x20 ,0x28 ,0x1 ,0xD ,0x20 ,0x88 ,0x0 ,0x0 ,0x60 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x1 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x84 ,0x1 ,0x20 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x10 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0xFD ,0x80 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x80 ,0x18 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x10 ,0x6 ,0x4 ,0x80 ,0x0 ,0x0 ,0x1 ,0x60 ,0x0 ,0x0 ,0x84 ,0x1 ,0x31 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x81 ,0x0 ,0x0 ,0x4 ,0x1 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x1 ,0x38 ,0x0 ,0xF ,0x2 ,0x1 ,0x0 ,0x0 ,0x50 ,0xFB ,0x8 ,0x5 ,0x1 ,0x0 ,0x26 ,0x4 ,0x2 ,0x90 ,0x2 ,0x2 ,0x4 ,0xA ,0x20 ,0x10 ,0x84 ,0x0 ,0x0 ,0x14 ,0x0 ,0x8 ,0x0 ,0x0 ,0x2 ,0x40 ,0xA ,0x80 ,0x0 ,0x11 ,0x20 ,0x5 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x11 ,0x0 ,0x0 ,0x0 ,0x40 ,0x84 ,0x85 ,0x0 ,0x10 ,0x0 ,0x0 ,0x88 ,0x80 ,0x8 ,0xA0 ,0x68 ,0x8 ,0x21 ,0x0 ,0x88 ,0x0 ,0x0 ,0x2A ,0xFD ,0x80 ,0x9 ,0x0 ,0x0 ,0x20 ,0x40 ,0x40 ,0x90 ,0x0 ,0x8A ,0x60 ,0x2 ,0x0 ,0x4 ,0x84 ,0x30 ,0x0 ,0x24 ,0xC0 ,0x4 ,0x0 ,0x0 ,0x2 ,0x40 ,0x2 ,0x20 ,0x10 ,0x45 ,0x20 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x5 ,0x2 ,0x0 ,0x10 ,0x2 ,0x0 ,0x40 ,0x10 ,0x0 ,0x0 ,0x0 ,0x48 ,0x82 ,0x31 ,0x30 ,0x1 ,0x0 ,0xC0 ,0x8 ,0x90 ,0x4 ,0x0 ,0x61 ,0x4 ,0x80 ,0x82 ,0x5 ,0x0 ,0x0 ,0xC8 ,0xFC ,0x60 ,0x41 ,0x0 ,0x80 ,0x1 ,0x31 ,0x0 ,0x6 ,0xC4 ,0x0 ,0x78 ,0x10 ,0x3 ,0x60 ,0x0 ,0xC ,0x88 ,0x1 ,0xF1 ,0x20 ,0x0 ,0x40 ,0x1 ,0x18 ,0x10 ,0x3 ,0x60 ,0x0 ,0xC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x0 ,0x80 ,0x7 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x7 ,0xE0 ,0x1 ,0x3C ,0x8 ,0x0 ,0xF0 ,0x20 ,0x1E ,0xC0 ,0x0 ,0x58 ,0x10 ,0x3 ,0x60 ,0x41 ,0x0 ,0x0 ,0x20 ,0xF8 ,0x84 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x18 ,0x0 ,0x3 ,0x40 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x20 ,0x6 ,0x82 ,0x0 ,0x0 ,0x0 ,0x1 ,0x60 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x80 ,0x1 ,0x21 ,0x20 ,0x0 ,0x40 ,0x40 ,0x0 ,0x0 ,0x0 ,0x60 ,0x40 ,0xC ,0x80 ,0x41 ,0x0 ,0x0 ,0x29 ,0xFA ,0x0 ,0x21 ,0x0 ,0x0 ,0x16 ,0x4 ,0x44 ,0x98 ,0x8 ,0xB ,0x1 ,0x10 ,0x40 ,0x4 ,0x0 ,0x80 ,0x0 ,0x26 ,0x0 ,0x2 ,0x1 ,0x0 ,0x2 ,0x60 ,0x84 ,0x2C ,0x84 ,0x5 ,0x32 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x85 ,0x0 ,0x0 ,0x16 ,0x0 ,0x0 ,0x18 ,0x4 ,0x0 ,0x0 ,0x0 ,0x20 ,0x84 ,0x4 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x4 ,0x18 ,0x9 ,0x10 ,0x41 ,0x0 ,0x2C ,0x82 ,0x1 ,0x0 ,0x0 ,0xF0 ,0xFA ,0xA0 ,0x88 ,0x0 ,0x80 ,0x46 ,0x12 ,0x44 ,0x2 ,0x40 ,0x62 ,0x68 ,0x0 ,0xD ,0xA0 ,0x0 ,0x14 ,0x80 ,0x20 ,0xD0 ,0x8 ,0x0 ,0x40 ,0x10 ,0xA ,0x0 ,0x41 ,0x24 ,0x0 ,0x4 ,0x41 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x4 ,0x0 ,0x80 ,0x2 ,0x4 ,0x0 ,0x2 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x88 ,0x34 ,0x1 ,0x0 ,0x10 ,0x0 ,0x2 ,0x61 ,0x12 ,0x69 ,0x0 ,0x45 ,0x20 ,0x0 ,0x0 ,0x0 ,0x68 ,0xF9 ,0x0 ,0x1 ,0x0 ,0x0 ,0x4 ,0xC0 ,0x0 ,0x0 ,0x50 ,0x0 ,0x40 ,0x40 ,0xC ,0x0 ,0x40 ,0x0 ,0x10 ,0x0 ,0x84 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x3 ,0x60 ,0x0 ,0x0 ,0x2 ,0x0 ,0x1 ,0x0 ,0xA8 ,0xF8 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x4 ,0x0 ,0x18 ,0xC8 ,0x2 ,0x0 ,0x20 ,0xC ,0x4 ,0x0 ,0x30 ,0x0 ,0x6 ,0x2 ,0x0 ,0x0 ,0x0 ,0x1 ,0x60 ,0x20 ,0x0 ,0x80 ,0x1 ,0x30 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x10 ,0x0 ,0x0 ,0x80 ,0x0 ,0x18 ,0x0 ,0x0 ,0x60 ,0x40 ,0x7 ,0x2 ,0x1 ,0x0 ,0x0 ,0x30 ,0xFB ,0x4 ,0x91 ,0x0 ,0x0 ,0x14 ,0x0 ,0x42 ,0x10 ,0x40 ,0x88 ,0x0 ,0x0 ,0x8C ,0x0 ,0x40 ,0x0 ,0x21 ,0x44 ,0x0 ,0x88 ,0x0 ,0x0 ,0x2 ,0x40 ,0x0 ,0x20 ,0x4 ,0x9 ,0x21 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x11 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x84 ,0x20 ,0x4 ,0x0 ,0x0 ,0x44 ,0x90 ,0x10 ,0x8 ,0x61 ,0x2 ,0xD ,0x0 ,0x88 ,0x0 ,0x0 ,0xD3 ,0xFE ,0x8C ,0x20 ,0x0 ,0x0 ,0x16 ,0xC1 ,0x42 ,0x90 ,0x4 ,0x21 ,0x60 ,0x12 ,0x20 ,0x4 ,0x80 ,0x20 ,0x41 ,0x24 ,0xC1 ,0x24 ,0x0 ,0x0 ,0x2 ,0x40 ,0x11 ,0x88 ,0x1 ,0x5 ,0xA0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x10 ,0x2 ,0x0 ,0x58 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x30 ,0x8 ,0x0 ,0xC0 ,0x4 ,0x10 ,0x0 ,0xB ,0x4 ,0x12 ,0xC ,0x80 ,0x9 ,0x0 ,0x0 ,0x89 ,0xFC ,0x60 ,0x1 ,0x0 ,0x80 ,0x7 ,0x70 ,0x0 ,0x6 ,0xC0 ,0x83 ,0x78 ,0x0 ,0xF ,0x60 ,0x0 ,0x3C ,0x80 ,0x1 ,0xF0 ,0x0 ,0x0 ,0x40 ,0x1 ,0x18 ,0x0 ,0x3 ,0x60 ,0x40 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x1 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x1E ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x3C ,0x0 ,0x0 ,0xB0 ,0x20 ,0x6 ,0xC4 ,0x3 ,0x78 ,0x0 ,0xB ,0x62 ,0x41 ,0x0 ,0x0 ,0x50 ,0xFF ,0x88 ,0x81 ,0x0 ,0x0 ,0x6 ,0x2 ,0x80 ,0x18 ,0x0 ,0x1 ,0x40 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x82 ,0x0 ,0x0 ,0x0 ,0x1 ,0x60 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x8 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x31 ,0x0 ,0x0 ,0xC0 ,0x20 ,0x18 ,0x0 ,0x0 ,0x60 ,0x40 ,0xC ,0x80 ,0x41 ,0x0 ,0x0 ,0xFB ,0xFD ,0x0 ,0x1 ,0x0 ,0x0 ,0x45 ,0x0 ,0x2 ,0x98 ,0x8 ,0x3 ,0x0 ,0x10 ,0x2C ,0x4 ,0x88 ,0xB0 ,0x20 ,0x26 ,0x0 ,0x2 ,0x1 ,0x0 ,0x2 ,0x60 ,0x84 ,0x20 ,0x90 ,0x5 ,0x32 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x58 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x5 ,0xA8 ,0x10 ,0x0 ,0xC0 ,0x8 ,0x98 ,0x8 ,0x20 ,0x4 ,0x1 ,0x8 ,0x81 ,0x5 ,0x0 ,0x0 ,0xA8 ,0xF9 ,0xA0 ,0x4 ,0x0 ,0x80 ,0x6 ,0x50 ,0x8 ,0x2 ,0x51 ,0x62 ,0x68 ,0x44 ,0x1 ,0x22 ,0x88 ,0x84 ,0x90 ,0x0 ,0xD8 ,0x2 ,0x2 ,0x40 ,0x20 ,0x48 ,0xC ,0x25 ,0x20 ,0x10 ,0x24 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x6 ,0x0 ,0x0 ,0x82 ,0x8 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x10 ,0x34 ,0x0 ,0x0 ,0x10 ,0x18 ,0xA ,0x40 ,0x11 ,0x9 ,0x0 ,0xD ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0xFE ,0x0 ,0x80 ,0x0 ,0x0 ,0x6 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x80 ,0x18 ,0x0 ,0x0 ,0x9 ,0x0 ,0x8 ,0x2 ,0x80 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x30 ,0x0 ,0x0 ,0x40 ,0x0 ,0x10 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x78 ,0xFF ,0x80 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0xD0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x84 ,0x1 ,0x30 ,0x20 ,0x6 ,0x2 ,0x0 ,0x0 ,0x0 ,0x1 ,0x5A ,0x0 ,0xC ,0x80 ,0x1 ,0x2C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x4 ,0x0 ,0x10 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x4 ,0x3 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x70 ,0xFA ,0x8 ,0x81 ,0x0 ,0x0 ,0x6 ,0x0 ,0x28 ,0x50 ,0x40 ,0x8 ,0x4 ,0x1 ,0x88 ,0x0 ,0x85 ,0xA0 ,0x0 ,0x14 ,0x0 ,0x10 ,0x40 ,0x20 ,0x2 ,0x8 ,0x10 ,0x80 ,0x2 ,0x11 ,0x5 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x26 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x44 ,0x30 ,0x0 ,0x0 ,0x0 ,0x88 ,0x50 ,0x0 ,0xB ,0x9 ,0x0 ,0x2C ,0x2 ,0x0 ,0x0 ,0x0 ,0x72 ,0xF9 ,0x80 ,0x51 ,0x0 ,0x0 ,0x16 ,0x0 ,0x40 ,0x50 ,0x4 ,0x2 ,0x60 ,0x11 ,0x20 ,0x4 ,0x84 ,0xA0 ,0x8 ,0x14 ,0xC1 ,0x28 ,0x40 ,0x10 ,0x2 ,0x20 ,0x0 ,0x20 ,0x8 ,0x1 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x10 ,0x2 ,0x0 ,0x98 ,0x4 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x80 ,0x30 ,0x22 ,0x0 ,0xC0 ,0x4 ,0x8 ,0x2 ,0x8 ,0x64 ,0x14 ,0x2C ,0x4 ,0x0 ,0x0 ,0x0 ,0x50 ,0xFE ,0x60 ,0x1 ,0x0 ,0x80 ,0x7 ,0x34 ,0x0 ,0x6 ,0x80 ,0x81 ,0x78 ,0x0 ,0x3 ,0x60 ,0x0 ,0xC ,0x80 ,0x1 ,0xF0 ,0x0 ,0x6 ,0x40 ,0x3 ,0x78 ,0x10 ,0x3 ,0x60 ,0x40 ,0x3C ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x1 ,0x0 ,0x80 ,0x7 ,0x0 ,0x0 ,0x16 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x62 ,0x0 ,0x3C ,0x0 ,0x0 ,0xF0 ,0x20 ,0x16 ,0xC0 ,0x0 ,0x78 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC8 ,0xF8 ,0x84 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x18 ,0x40 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x6 ,0x82 ,0x0 ,0x0 ,0x8 ,0x1 ,0x20 ,0x0 ,0x0 ,0x84 ,0x81 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x4 ,0x0 ,0x18 ,0x4 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x40 ,0x18 ,0x8 ,0x3 ,0x60 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0xD9 ,0xF9 ,0x0 ,0x11 ,0x1 ,0x0 ,0x0 ,0x0 ,0x44 ,0x98 ,0x8 ,0x0 ,0x4 ,0x10 ,0x20 ,0x84 ,0x5 ,0x32 ,0x40 ,0x26 ,0x0 ,0x2 ,0x41 ,0x0 ,0x3 ,0x60 ,0x0 ,0x20 ,0x80 ,0x1 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4C ,0x8 ,0x88 ,0x0 ,0x22 ,0x0 ,0xC0 ,0x8 ,0x10 ,0x0 ,0x23 ,0x6C ,0x0 ,0x2C ,0x0 ,0x0 ,0x0 ,0x0 ,0xF8 ,0xF8 ,0xA0 ,0x88 ,0x0 ,0x80 ,0x16 ,0x12 ,0x0 ,0x82 ,0x40 ,0x0 ,0x6A ,0x2 ,0x1 ,0xA0 ,0x89 ,0x4 ,0xA2 ,0x0 ,0xD0 ,0x0 ,0x2 ,0x44 ,0x0 ,0x8 ,0x44 ,0x4D ,0xA4 ,0x10 ,0x4 ,0x22 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA0 ,0x41 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x41 ,0x20 ,0x8 ,0xB4 ,0x10 ,0x0 ,0x10 ,0x8 ,0x2 ,0x45 ,0x13 ,0x9 ,0x0 ,0x1 ,0x20 ,0x30 ,0x0 ,0x0 ,0xA8 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x40 ,0x40 ,0x0 ,0x82 ,0x1 ,0x0 ,0x0 ,0x0 ,0x82 ,0x40 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x40 ,0x20 ,0x0 ,0x0 ,0x40 ,0x40 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0xFE ,0x80 ,0x80 ,0x0 ,0x0 ,0x0 ,0x4 ,0x80 ,0x18 ,0x8 ,0x3 ,0x0 ,0x20 ,0x4 ,0x4 ,0x0 ,0x30 ,0x10 ,0x6 ,0x0 ,0x0 ,0x0 ,0x8 ,0x3 ,0x60 ,0x40 ,0xC ,0x80 ,0x1 ,0x30 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x41 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x10 ,0x10 ,0x0 ,0x0 ,0x0 ,0x8 ,0x80 ,0x40 ,0x10 ,0x0 ,0x0 ,0x80 ,0x80 ,0x0 ,0x4 ,0x3 ,0x60 ,0x0 ,0xF ,0x2 ,0x0 ,0x0 ,0x0 ,0x30 ,0xFE ,0x8 ,0x9 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x2 ,0x90 ,0x0 ,0x52 ,0x0 ,0x2 ,0x80 ,0x80 ,0x85 ,0x20 ,0x1 ,0x14 ,0x4 ,0x84 ,0x0 ,0x1 ,0x3 ,0x40 ,0x1 ,0x2C ,0x4 ,0x4 ,0xA2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x40 ,0x4 ,0x8 ,0xA0 ,0x40 ,0x0 ,0x40 ,0x2 ,0x80 ,0x0 ,0xB ,0x61 ,0x0 ,0x2D ,0x0 ,0x10 ,0x1 ,0x0 ,0x7A ,0xFA ,0x80 ,0x11 ,0x0 ,0x0 ,0x16 ,0x0 ,0x40 ,0x10 ,0x4 ,0xA2 ,0x60 ,0x14 ,0x20 ,0x84 ,0x85 ,0x20 ,0xA ,0x4 ,0xC1 ,0x2 ,0x80 ,0x0 ,0x3 ,0x40 ,0x14 ,0x84 ,0x1 ,0x51 ,0x20 ,0xA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x80 ,0x0 ,0x0 ,0x16 ,0x4 ,0x0 ,0x58 ,0x4 ,0x0 ,0x0 ,0x0 ,0x2C ,0x2 ,0x80 ,0x30 ,0x0 ,0x0 ,0xC0 ,0x8 ,0x0 ,0x8 ,0x83 ,0x60 ,0x41 ,0x80 ,0x82 ,0x9 ,0x0 ,0x0 ,0x50 ,0xFC ,0x60 ,0x41 ,0x0 ,0x80 ,0x7 ,0x32 ,0x0 ,0x6 ,0xC0 ,0x0 ,0x78 ,0x0 ,0x3 ,0xE0 ,0x1 ,0xC ,0x80 ,0x1 ,0xF0 ,0x20 ,0x6 ,0x50 ,0x3 ,0x18 ,0x0 ,0xF ,0xE0 ,0x1 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x0 ,0x80 ,0x7 ,0x0 ,0x0 ,0x16 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB ,0x60 ,0x0 ,0x3C ,0x8 ,0x0 ,0x30 ,0x20 ,0x16 ,0xC0 ,0x3 ,0x78 ,0x0 ,0xF ,0xE0 ,0x41 ,0x0 ,0x0 ,0x30 ,0xF9 ,0x84 ,0x0 ,0x1 ,0x0 ,0x4 ,0x2 ,0x0 ,0x18 ,0x0 ,0x3 ,0x40 ,0x0 ,0x0 ,0x80 ,0x1 ,0x30 ,0x0 ,0x6 ,0x82 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0xC ,0x0 ,0x0 ,0x30 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x2 ,0x0 ,0x30 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x40 ,0x0 ,0x88 ,0x0 ,0x0 ,0x0 ,0x69 ,0xFF ,0x0 ,0x11 ,0x0 ,0x0 ,0x40 ,0x0 ,0x44 ,0x98 ,0x8 ,0xB ,0x1 ,0x10 ,0x20 ,0x84 ,0x4 ,0x32 ,0x40 ,0x26 ,0x0 ,0x2 ,0x41 ,0x8 ,0x0 ,0x60 ,0x84 ,0x2C ,0x90 ,0x11 ,0x31 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x89 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x18 ,0x5 ,0x0 ,0x0 ,0x0 ,0x4C ,0x0 ,0x88 ,0x28 ,0x5 ,0x0 ,0xE0 ,0x2 ,0x81 ,0x8 ,0xB ,0x4 ,0x2 ,0x2C ,0x80 ,0x9 ,0x2 ,0x0 ,0x30 ,0xF8 ,0xA0 ,0x4 ,0x0 ,0x80 ,0x20 ,0x50 ,0x22 ,0x12 ,0x43 ,0x0 ,0x68 ,0x80 ,0x1 ,0x20 ,0x0 ,0x4 ,0xC0 ,0x0 ,0xD4 ,0x4 ,0x82 ,0x44 ,0x8 ,0x9 ,0x2 ,0x41 ,0xA4 ,0x4 ,0x6 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x88 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x48 ,0x22 ,0x2D ,0xA4 ,0x85 ,0x34 ,0x0 ,0x0 ,0x10 ,0x10 ,0x82 ,0x48 ,0x13 ,0x9 ,0x0 ,0x81 ,0x22 ,0x0 ,0x0 ,0x0 ,0x40 ,0xFC ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x2 ,0x0 ,0x0 ,0x42 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x4 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x80 ,0x1 ,0x30 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0xC ,0x80 ,0x1 ,0x0 ,0x0 ,0xD0 ,0xFE ,0x80 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x40 ,0x16 ,0x0 ,0x3 ,0x1 ,0x20 ,0x0 ,0x84 ,0x1 ,0x30 ,0x20 ,0x6 ,0x0 ,0x40 ,0x0 ,0x8 ,0x1 ,0x60 ,0x20 ,0x0 ,0x80 ,0x80 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0xC ,0x84 ,0x1 ,0x30 ,0x0 ,0x0 ,0x0 ,0x40 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x41 ,0x0 ,0x0 ,0xB8 ,0xFF ,0x4 ,0x5 ,0x1 ,0x0 ,0x20 ,0x2 ,0x8 ,0x2 ,0x4 ,0x2 ,0x0 ,0x1 ,0x80 ,0x0 ,0x4 ,0x22 ,0x2 ,0x4 ,0x8 ,0x0 ,0x0 ,0x1 ,0x2 ,0x40 ,0x2 ,0x20 ,0x4 ,0x5 ,0xA0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x84 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x8 ,0x0 ,0x0 ,0x2 ,0xC ,0x80 ,0x49 ,0x30 ,0x0 ,0x0 ,0xC0 ,0x2 ,0x58 ,0x8 ,0x8 ,0x61 ,0x22 ,0x48 ,0x84 ,0x9 ,0x0 ,0x0 ,0xE3 ,0xFB ,0x8C ,0x41 ,0x0 ,0x0 ,0x46 ,0x1 ,0x42 ,0x8 ,0x0 ,0x12 ,0x60 ,0x2 ,0x2C ,0x4 ,0x80 ,0x20 ,0x8 ,0x4 ,0xC0 ,0x10 ,0x88 ,0x0 ,0x2 ,0x40 ,0x10 ,0x8C ,0x81 ,0x41 ,0x20 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x6 ,0x2 ,0x0 ,0x98 ,0x4 ,0x0 ,0x0 ,0xC ,0x20 ,0x2 ,0x80 ,0xB0 ,0x20 ,0x0 ,0x80 ,0x84 ,0x0 ,0x3 ,0xB ,0x4 ,0x14 ,0x44 ,0x0 ,0x0 ,0x2 ,0x0 ,0xB9 ,0xFD ,0x60 ,0x1 ,0x0 ,0x80 ,0x5 ,0x30 ,0x0 ,0x1E ,0xC4 ,0x0 ,0x7A ,0x20 ,0xF ,0x60 ,0x0 ,0xC ,0x80 ,0x1 ,0xF1 ,0x0 ,0x6 ,0x50 ,0x1 ,0x18 ,0x0 ,0x3 ,0x60 ,0x1 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x80 ,0x7 ,0x0 ,0x0 ,0x1E ,0x0 ,0x0 ,0x18 ,0x0 ,0x3 ,0xE0 ,0x1 ,0x3C ,0x0 ,0x0 ,0x70 ,0x0 ,0x6 ,0xC0 ,0x3 ,0x78 ,0x0 ,0x3 ,0x68 ,0x0 ,0x0 ,0x0 ,0x50 ,0xF9 ,0x88 ,0x0 ,0x0 ,0x0 ,0x6 ,0x1 ,0x0 ,0x8 ,0x0 ,0x3 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x6 ,0x2 ,0x0 ,0x0 ,0x0 ,0x1 ,0x60 ,0x0 ,0x0 ,0x80 ,0x0 ,0x30 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x10 ,0x0 ,0xC0 ,0x0 ,0x8 ,0x10 ,0x2 ,0x60 ,0x10 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x5B ,0xFA ,0x0 ,0x21 ,0x0 ,0x0 ,0x26 ,0x0 ,0x42 ,0x18 ,0x0 ,0xB ,0x1 ,0x10 ,0x20 ,0x4 ,0x88 ,0x30 ,0x40 ,0x26 ,0x40 ,0x2 ,0x41 ,0x8 ,0x2 ,0x60 ,0x84 ,0x20 ,0x10 ,0x91 ,0x30 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x58 ,0x0 ,0x0 ,0x0 ,0x21 ,0x48 ,0x1 ,0x89 ,0x80 ,0x0 ,0x0 ,0xE0 ,0x4 ,0x59 ,0x0 ,0x20 ,0x64 ,0x2 ,0x0 ,0x84 ,0x45 ,0x0 ,0x0 ,0x18 ,0xFD ,0xA0 ,0x4 ,0x34 ,0x80 ,0x20 ,0x10 ,0x0 ,0x2 ,0x60 ,0x62 ,0x68 ,0x0 ,0xD ,0xA0 ,0x48 ,0x4 ,0x80 ,0x20 ,0x98 ,0x4 ,0x3 ,0x40 ,0x1 ,0x9 ,0x80 ,0x1 ,0xA0 ,0x4 ,0x6 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA0 ,0x1 ,0x0 ,0x80 ,0xC2 ,0x0 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0xA0 ,0x89 ,0xB4 ,0x0 ,0x0 ,0x10 ,0x4 ,0x9B ,0x48 ,0x3 ,0x8 ,0x4 ,0xD ,0x20 ,0x0 ,0x0 ,0x0 ,0xE0 ,0xF8 ,0x0 ,0x81 ,0x30 ,0x0 ,0x2 ,0xC4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0xC ,0x80 ,0x1 ,0x20 ,0x20 ,0x0 ,0x40 ,0x0 ,0x18 ,0x0 ,0x3 ,0x20 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xF8 ,0x80 ,0x0 ,0x30 ,0x10 ,0x0 ,0x0 ,0x40 ,0x18 ,0xC8 ,0x2 ,0x60 ,0x0 ,0x0 ,0x0 ,0x40 ,0x30 ,0x0 ,0x6 ,0x4 ,0x0 ,0x0 ,0x0 ,0x1 ,0x60 ,0x20 ,0x0 ,0x80 ,0x0 ,0x30 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x80 ,0x7 ,0x1 ,0x0 ,0x0 ,0x0 ,0x3 ,0x60 ,0x40 ,0xC ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x3 ,0x82 ,0x1 ,0x0 ,0x0 ,0xB0 ,0xFA ,0x8 ,0x91 ,0x30 ,0x0 ,0x0 ,0x2 ,0x8 ,0x50 ,0x40 ,0x9 ,0x64 ,0x10 ,0x20 ,0x10 ,0x4 ,0xA0 ,0x20 ,0x44 ,0x0 ,0x24 ,0x40 ,0x20 ,0x20 ,0x42 ,0x1 ,0x20 ,0x10 ,0x5 ,0xA1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x80 ,0x22 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB ,0x1 ,0x1 ,0x2C ,0x84 ,0x85 ,0x0 ,0x12 ,0x0 ,0xC0 ,0x80 ,0x48 ,0x8 ,0x23 ,0x4 ,0x44 ,0x21 ,0x80 ,0x1 ,0x0 ,0x0 ,0x6A ,0xF9 ,0x80 ,0x20 ,0x30 ,0x0 ,0x46 ,0xC1 ,0x42 ,0x90 ,0x20 ,0x2 ,0x62 ,0x4 ,0x0 ,0x4 ,0x80 ,0x20 ,0x11 ,0x24 ,0x80 ,0x8 ,0x40 ,0x10 ,0x1 ,0x40 ,0x1 ,0x2C ,0x88 ,0x20 ,0x20 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x5 ,0x2 ,0x0 ,0x44 ,0x0 ,0x0 ,0x40 ,0x20 ,0x0 ,0x1 ,0x20 ,0x40 ,0x84 ,0x31 ,0x30 ,0x0 ,0x0 ,0x80 ,0x4 ,0x18 ,0x3 ,0x3 ,0x61 ,0x14 ,0x0 ,0x82 ,0x9 ,0x0 ,0x0 ,0xD0 ,0xFC ,0x60 ,0x1 ,0x3C ,0x90 ,0x7 ,0xF0 ,0x0 ,0x6 ,0x80 ,0x1 ,0x78 ,0x20 ,0x3 ,0x60 ,0x0 ,0xC ,0x80 ,0x1 ,0x72 ,0x40 ,0x6 ,0x40 ,0x1 ,0x18 ,0x40 ,0x3 ,0x60 ,0x1 ,0xC ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0x1 ,0x0 ,0x80 ,0x7 ,0x1 ,0x0 ,0x6 ,0xC0 ,0x0 ,0x18 ,0x0 ,0x3 ,0xE0 ,0x1 ,0x3C ,0x20 ,0x0 ,0x70 ,0x20 ,0x1E ,0xC0 ,0x0 ,0x78 ,0x0 ,0xF ,0xE0 ,0x1 ,0x1 ,0x0 ,0xB8 ,0xFA ,0x84 ,0x81 ,0x0 ,0x10 ,0x2 ,0x0 ,0x0 ,0x18 ,0x40 ,0x2 ,0x60 ,0x20 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x6 ,0x2 ,0x80 ,0x0 ,0x8 ,0x1 ,0x60 ,0x0 ,0x0 ,0x84 ,0x1 ,0x30 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x82 ,0x1 ,0x21 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x18 ,0x10 ,0x3 ,0x20 ,0x10 ,0xC ,0x82 ,0x1 ,0x0 ,0x0 ,0xD1 ,0xFF ,0x0 ,0x1 ,0x30 ,0x2 ,0x6 ,0x4 ,0x42 ,0x98 ,0x8 ,0x1 ,0x4 ,0x4 ,0x40 ,0x4 ,0x88 ,0x30 ,0x40 ,0x26 ,0x0 ,0x8 ,0x40 ,0x0 ,0x1 ,0x60 ,0x84 ,0x20 ,0x0 ,0x85 ,0x30 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x84 ,0x0 ,0x0 ,0x26 ,0x1 ,0x0 ,0x18 ,0x4 ,0x93 ,0x0 ,0x22 ,0x2C ,0x80 ,0x5 ,0x80 ,0x10 ,0x0 ,0xC0 ,0x20 ,0x40 ,0x0 ,0x13 ,0x61 ,0x4 ,0xC ,0x80 ,0x21 ,0x0 ,0x0 ,0x78 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x28 ,0x0 ,0x8 ,0x80 ,0x0 ,0x10 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x10 ,0x0 ,0x1 ,0x20 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x21 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x5A ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x0 ,0x50 ,0xFC ,0x4 ,0x0 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x11 ,0xFD ,0x20 ,0x0 ,0x4 ,0x0 ,0x1 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x18 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x2 ,0x50 ,0x0 ,0x2 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x80 ,0x0 ,0x0 ,0x10 ,0x0 ,0x42 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x2 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x88 ,0xFD ,0x0 ,0x0 ,0x48 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF8 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x2 ,0x0 ,0x0 ,0x0 ,0x4 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x28 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x38 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0xFB ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x8 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x8 ,0x1 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x4 ,0x0 ,0x0 ,0x40 ,0x20 ,0x2 ,0x4 ,0x0 ,0x0 ,0x0 ,0x80 ,0x80 ,0x0 ,0x0 ,0x40 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFB ,0x0 ,0x40 ,0x0 ,0x10 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x20 ,0x40 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x4 ,0x20 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x4 ,0x0 ,0x20 ,0x40 ,0x4 ,0x80 ,0x0 ,0x1 ,0x10 ,0x50 ,0xFD ,0x0 ,0x0 ,0x1 ,0xA0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x8 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x1 ,0x10 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x1 ,0x20 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x90 ,0x0 ,0x8 ,0x40 ,0x1 ,0x20 ,0x0 ,0x1 ,0x20 ,0x0 ,0xFD ,0x0 ,0x8 ,0x60 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x8 ,0x48 ,0x1 ,0x1 ,0x20 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x43 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x80 ,0x0 ,0x4 ,0x80 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xD0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x1 ,0x0 ,0x0 ,0x88 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xFC ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x10 ,0x4 ,0x82 ,0x0 ,0x10 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x81 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x20 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xFD ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x2 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x21 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x2 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x41 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x50 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x58 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0xFF ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF8 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xFF ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x40 ,0x10 ,0x40 ,0x10 ,0x8 ,0x0 ,0x41 ,0x4 ,0x80 ,0x0 ,0x0 ,0xA0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x4 ,0x80 ,0x0 ,0x41 ,0x0 ,0x0 ,0x0 ,0x88 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x68 ,0xFF ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x70 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x20 ,0x0 ,0x1 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x4 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE8 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x70 ,0xFD ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x78 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x24 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x21 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x0 ,0x98 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x70 ,0xF9 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xD8 ,0xFB ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x6 ,0xC0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0xF9 ,0x4 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x20 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x10 ,0x8 ,0x2 ,0x0 ,0x0 ,0x8 ,0x8 ,0x81 ,0x10 ,0x10 ,0x0 ,0x0 ,0x40 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x40 ,0x0 ,0x0 ,0x4 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x4 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xFD ,0x0 ,0x0 ,0x0 ,0x86 ,0x1 ,0x0 ,0x98 ,0x2 ,0x0 ,0x80 ,0x10 ,0x0 ,0x0 ,0x8 ,0x0 ,0x4 ,0xA0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x50 ,0x0 ,0xA ,0x40 ,0x82 ,0x5 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x10 ,0x0 ,0x0 ,0x10 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x1 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x1 ,0x8 ,0x0 ,0x0 ,0x0 ,0x70 ,0xF9 ,0x0 ,0x20 ,0x0 ,0x0 ,0x10 ,0x0 ,0x10 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x80 ,0x0 ,0xC ,0x0 ,0x10 ,0x70 ,0x4 ,0xA2 ,0x5 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x1 ,0x1 ,0x0 ,0x2 ,0x2 ,0x2 ,0x2 ,0x0 ,0x0 ,0x80 ,0x2 ,0x20 ,0x0 ,0x0 ,0x40 ,0x8A ,0x0 ,0x0 ,0x2 ,0xC0 ,0x0 ,0x0 ,0xA ,0xC0 ,0x1 ,0x20 ,0x4 ,0xD0 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0xF0 ,0xFD ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x20 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x44 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x1 ,0x80 ,0x0 ,0x20 ,0x10 ,0x68 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0xD0 ,0xFF ,0x20 ,0x1 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x68 ,0x2 ,0x11 ,0x40 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x20 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x1 ,0x0 ,0x1 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x8 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF0 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xFC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x40 ,0x10 ,0x0 ,0x2 ,0x41 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x41 ,0x0 ,0x0 ,0x0 ,0x80 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xBA ,0xF8 ,0x8 ,0x1 ,0x0 ,0x8 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x80 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x58 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x42 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x28 ,0xFC ,0x40 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x44 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x40 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x50 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x20 ,0x0 ,0x0 ,0x0 ,0xC8 ,0xFC ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x28 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB0 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xF9 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB0 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xD0 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x11 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x68 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x6 ,0x0 ,0x0 ,0x82 ,0x50 ,0x11 ,0x0 ,0x0 ,0x41 ,0x24 ,0x88 ,0x0 ,0x0 ,0xE8 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x82 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x82 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA0 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x8 ,0x8 ,0x1 ,0x1 ,0x0 ,0x30 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x82 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x11 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x1 ,0x0 ,0x0 ,0x2 ,0x82 ,0x0 ,0x0 ,0x80 ,0x0 ,0x10 ,0x0 ,0x0 ,0x8 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x41 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x26 ,0x0 ,0x0 ,0x98 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x18 ,0x4 ,0x1 ,0x0 ,0x0 ,0xC ,0x80 ,0x1 ,0x0 ,0x0 ,0xD0 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x2 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x78 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x4 ,0x0 ,0x1E ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0x0 ,0x0 ,0x1E ,0xC0 ,0x2 ,0x1 ,0x0 ,0xB ,0x62 ,0x41 ,0x0 ,0x0 ,0x20 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x8 ,0x0 ,0x0 ,0x0 ,0xC ,0x80 ,0x41 ,0x0 ,0x0 ,0xD0 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x43 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x24 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x98 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x2 ,0x0 ,0x90 ,0x0 ,0x43 ,0x0 ,0x0 ,0x8C ,0x82 ,0x11 ,0x0 ,0x0 ,0xF0 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x40 ,0x9 ,0x0 ,0x0 ,0x81 ,0x20 ,0x8 ,0x0 ,0x0 ,0x68 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x83 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x83 ,0x0 ,0x0 ,0x8 ,0x4 ,0x80 ,0x0 ,0x0 ,0x68 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x2 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x1 ,0x0 ,0x0 ,0x80 ,0x0 ,0x1 ,0x0 ,0x0 ,0xF8 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x13 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x80 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x13 ,0x0 ,0x0 ,0x80 ,0x8 ,0x10 ,0x0 ,0x0 ,0xA1 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x16 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x26 ,0x0 ,0x0 ,0x18 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x16 ,0x0 ,0x0 ,0x0 ,0x4 ,0x10 ,0x0 ,0x0 ,0xC ,0x82 ,0x11 ,0x0 ,0x0 ,0x6B ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x78 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0x4 ,0x0 ,0x16 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0x1 ,0x0 ,0x6 ,0xC0 ,0x2 ,0x2 ,0x0 ,0xF ,0xE0 ,0x40 ,0x0 ,0x0 ,0xF0 ,0xFD ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x82 ,0x1 ,0x0 ,0x0 ,0xD2 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x86 ,0x0 ,0x0 ,0x58 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x58 ,0x4 ,0x20 ,0x1 ,0x0 ,0x2C ,0x80 ,0x51 ,0x0 ,0x0 ,0xB8 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x82 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x12 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x34 ,0x80 ,0x20 ,0x4 ,0x0 ,0x1A ,0x49 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xFF ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x42 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x11 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0xA ,0x20 ,0x4 ,0x0 ,0x40 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xEA ,0xF9 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x13 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x22 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x26 ,0x0 ,0x0 ,0x80 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA ,0x22 ,0x0 ,0x0 ,0x8 ,0x0 ,0x13 ,0x60 ,0x1 ,0x4C ,0x10 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x83 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x78 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x4 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3C ,0x80 ,0x7 ,0x1 ,0x0 ,0x1A ,0xC0 ,0x83 ,0x78 ,0x20 ,0xF ,0x0 ,0x0 ,0x0 ,0x0 ,0xC8 ,0xFE ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0xA1 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x10 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x6 ,0x4 ,0x0 ,0x8 ,0x0 ,0x3 ,0x60 ,0x20 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0xD8 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x46 ,0x2 ,0x0 ,0x1A ,0x0 ,0x0 ,0x68 ,0x84 ,0x0 ,0x0 ,0x0 ,0x34 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x6 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x81 ,0x10 ,0x0 ,0x34 ,0x80 ,0x46 ,0x2 ,0x0 ,0x10 ,0x40 ,0x3 ,0x68 ,0x0 ,0x1 ,0x20 ,0x30 ,0x0 ,0x0 ,0xF8 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x60 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x18 ,0x4 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x4 ,0x0 ,0x0 ,0x18 ,0x0 ,0x80 ,0x60 ,0x20 ,0xC ,0x80 ,0x80 ,0x0 ,0x0 ,0xE8 ,0xF8 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x1 ,0x0 ,0x58 ,0x0 ,0x0 ,0x0 ,0x14 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x40 ,0x10 ,0x0 ,0x0 ,0x0 ,0x8 ,0x1 ,0x0 ,0x0 ,0x2 ,0x40 ,0x1 ,0x0 ,0x90 ,0x2 ,0x20 ,0x60 ,0x0 ,0x2C ,0x4 ,0x8 ,0x0 ,0x0 ,0x43 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x26 ,0x0 ,0x0 ,0x18 ,0x1 ,0x0 ,0x0 ,0x0 ,0x48 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x60 ,0x2 ,0x20 ,0x82 ,0x11 ,0x0 ,0x0 ,0x79 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x6 ,0x0 ,0x0 ,0x1E ,0x0 ,0x0 ,0x68 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0x4 ,0x0 ,0x6 ,0x4 ,0x0 ,0x0 ,0x0 ,0xF ,0x2 ,0x0 ,0x3C ,0x90 ,0x6 ,0x0 ,0x0 ,0x8 ,0xC0 ,0x3 ,0x78 ,0x40 ,0x3 ,0xE0 ,0x40 ,0x0 ,0x0 ,0x20 ,0xF8 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0x8 ,0x0 ,0x0 ,0x0 ,0xC ,0x2 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0xA3 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x13 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x11 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x22 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x86 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2C ,0x0 ,0x0 ,0x30 ,0x10 ,0x2 ,0x0 ,0x0 ,0x18 ,0x0 ,0x13 ,0x62 ,0x8 ,0x4C ,0x82 ,0x29 ,0x0 ,0x0 ,0x38 ,0xF8 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x4 ,0x0 ,0x0 ,0x80 ,0x40 ,0x3 ,0x8 ,0x0 ,0xD ,0x20 ,0x0 ,0x34 ,0x0 ,0x88 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x2 ,0x0 ,0x8 ,0x10 ,0x0 ,0x60 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0xC0 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x83 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x6 ,0x0 ,0x0 ,0x18 ,0x0 ,0x83 ,0x0 ,0x10 ,0xC ,0x80 ,0x1 ,0x31 ,0x8 ,0x20 ,0xFE ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x14 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x11 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x90 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x14 ,0x1 ,0x0 ,0x8 ,0x2 ,0xB ,0x0 ,0x0 ,0x2C ,0x82 ,0x5 ,0xB0 ,0x0 ,0x12 ,0xF8 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x98 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x20 ,0x61 ,0x22 ,0x20 ,0x2 ,0x44 ,0x0 ,0x6 ,0x68 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x4 ,0x0 ,0x1E ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3C ,0x10 ,0x2 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x3 ,0x78 ,0x0 ,0xF ,0x60 ,0x0 ,0x3C ,0x0 ,0xE8 ,0xFF ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x2 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0xD1 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x98 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x62 ,0x2 ,0x80 ,0x84 ,0x49 ,0x0 ,0x1 ,0xA8 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1A ,0x0 ,0x0 ,0x0 ,0x41 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x4 ,0x0 ,0x0 ,0x0 ,0x81 ,0x0 ,0x0 ,0x84 ,0x0 ,0x0 ,0x2 ,0x0 ,0x10 ,0x48 ,0xA0 ,0x8 ,0x2 ,0x25 ,0xB0 ,0x4 ,0x36 ,0x0 ,0x48 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x20 ,0x8 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x20 ,0xC ,0x80 ,0x1 ,0x0 ,0x0 ,0xA8 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x42 ,0x0 ,0xC ,0x88 ,0x1 ,0x1 ,0x8 ,0xC0 ,0xFC ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x82 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x20 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0x10 ,0x0 ,0x0 ,0x0 ,0x44 ,0x0 ,0x0 ,0x0 ,0x4 ,0x82 ,0x0 ,0x0 ,0x90 ,0x2 ,0x10 ,0x0 ,0x14 ,0x4C ,0x80 ,0x9 ,0x0 ,0x0 ,0xBA ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x9 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x58 ,0x4 ,0x0 ,0x0 ,0x0 ,0x44 ,0x0 ,0x0 ,0x10 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x81 ,0x60 ,0x1 ,0x2C ,0x82 ,0x45 ,0x80 ,0x10 ,0x98 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1E ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x4 ,0x0 ,0x1E ,0x0 ,0x0 ,0x0 ,0x0 ,0xF ,0x2 ,0x0 ,0x3C ,0x10 ,0x0 ,0x0 ,0x0 ,0x8 ,0xC0 ,0x3 ,0x58 ,0x20 ,0xF ,0xE0 ,0x1 ,0x3C ,0x0 ,0xC0 ,0xFE ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC ,0x2 ,0x0 ,0x30 ,0x10 ,0x4 ,0x0 ,0x0 ,0x8 ,0x0 ,0x3 ,0x60 ,0x0 ,0xC ,0x88 ,0x1 ,0x31 ,0x0 ,0xB9 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0x8 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x98 ,0x8 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x30 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0x0 ,0x3 ,0x61 ,0x11 ,0xE ,0xC0 ,0x1 ,0x30 ,0x10 ,0xF0 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x2 ,0x0 ,0x2 ,0x0 ,0x0 ,0x40 ,0x20 ,0x0 ,0x0 ,0x0 ,0x34 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x6 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x81 ,0x0 ,0x0 ,0x94 ,0x40 ,0x24 ,0x2 ,0x0 ,0x48 ,0x40 ,0x0 ,0x8 ,0x0 ,0x2D ,0xB0 ,0x5 ,0x6 ,0x0 ,0x18 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x10 ,0x3 ,0x60 ,0x0 ,0xC ,0x80 ,0x1 ,0x30 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x4 ,0x0 ,0x30 ,0x0 ,0x6 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x61 ,0x20 ,0xC ,0x88 ,0x1 ,0x1 ,0x0 ,0x10 ,0xFA ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x14 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x11 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x30 ,0x20 ,0x14 ,0x1 ,0x0 ,0x10 ,0x0 ,0x8 ,0x60 ,0x0 ,0x4C ,0x80 ,0x9 ,0x0 ,0x12 ,0xF2 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xA3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x26 ,0x0 ,0x0 ,0x40 ,0x4 ,0x0 ,0x0 ,0x0 ,0x4C ,0x0 ,0x0 ,0x30 ,0xA ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x83 ,0x60 ,0x2 ,0x0 ,0x1 ,0x4 ,0xB0 ,0x10 ,0xD8 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0x4 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB ,0x2 ,0x0 ,0x3C ,0x0 ,0x2 ,0x0 ,0x0 ,0x10 ,0xC0 ,0x3 ,0x78 ,0x40 ,0x7 ,0xE0 ,0x80 ,0x3C ,0x0 ,0xC8 ,0xFA ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x18 ,0x8 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0x4 ,0x0 ,0x0 ,0x0 ,0xC ,0x2 ,0x0 ,0x30 ,0x20 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x61 ,0x0 ,0x0 ,0x8 ,0x0 ,0x1 ,0x0 ,0xE1 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x60 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x86 ,0x0 ,0x0 ,0x18 ,0x1 ,0x0 ,0x0 ,0x0 ,0x4C ,0x0 ,0x0 ,0x38 ,0x0 ,0x6 ,0x0 ,0x0 ,0x10 ,0x0 ,0x3 ,0x60 ,0x8 ,0x0 ,0x0 ,0x0 ,0x30 ,0x4 ,0xD0 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x6 ,0x0 ,0x0 ,0x2 ,0x1 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0xB4 ,0x40 ,0x2 ,0x0 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x12 ,0x81 ,0x20 ,0x0 ,0x4 ,0x0 ,0xD0 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x1 ,0x0 ,0x18 ,0x0 ,0x0 ,0x40 ,0x10 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x10 ,0x8 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x30 ,0x0 ,0x4 ,0x1 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x80 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x8 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0xF8 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x6 ,0x0 ,0x0 ,0x0 ,0x11 ,0x0 ,0x0 ,0x0 ,0x40 ,0x1 ,0x0 ,0x30 ,0x20 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0x40 ,0x24 ,0x48 ,0x88 ,0x5 ,0x2 ,0x0 ,0x1A ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x4 ,0x0 ,0x0 ,0x0 ,0xA3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x18 ,0x9 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x26 ,0x0 ,0x0 ,0x58 ,0x4 ,0x0 ,0x0 ,0x0 ,0x4C ,0x0 ,0x0 ,0x0 ,0x10 ,0x2 ,0x0 ,0x0 ,0x18 ,0x4 ,0x83 ,0x60 ,0x22 ,0xC ,0x2 ,0x10 ,0x81 ,0x10 ,0x18 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x80 ,0x1 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x1E ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3C ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x7 ,0x4 ,0x0 ,0x1E ,0x0 ,0x0 ,0x0 ,0x0 ,0xF ,0x2 ,0x0 ,0x1C ,0x0 ,0x4 ,0x0 ,0x0 ,0x1E ,0xC0 ,0x3 ,0x78 ,0x0 ,0xF ,0x60 ,0x0 ,0xC ,0x0 ,0x20 ,0xFA ,0x4 ,0x0 ,0x0 ,0x0 ,0x6 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x20 ,0x2 ,0x0 ,0x0 ,0x18 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x8 ,0x0 ,0x31 ,0x10 ,0x79 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x46 ,0x0 ,0x0 ,0x0 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x98 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x30 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x86 ,0x0 ,0x0 ,0x18 ,0x1 ,0x0 ,0x0 ,0x0 ,0xC ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x90 ,0x8 ,0x3 ,0x64 ,0x14 ,0x8C ,0x0 ,0x8 ,0x30 ,0x2 ,0x0 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x28 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0xA3 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x89 ,0xFE ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x98 ,0xFF ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xEB ,0xF8 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x10 ,0x0 ,0x2 ,0x40 ,0x0 ,0x8 ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0xE8 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x88 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x84 ,0x0 ,0x0 ,0x0 ,0x50 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0xFF ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x21 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x1 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x28 ,0xFC ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0xB4 ,0x14 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x1 ,0x0 ,0x0 ,0x10 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0xA ,0x0 ,0x0 ,0x28 ,0x0 ,0x20 ,0x20 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x86 ,0x84 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x10 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x40 ,0x11 ,0x0 ,0xB8 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x8 ,0x0 ,0x50 ,0xFB ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x21 ,0x0 ,0x8 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xF0 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x40 ,0x80 ,0x0 ,0x0 ,0x0 ,0x2 ,0x40 ,0x4 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x40 ,0x0 ,0x68 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x1 ,0x20 ,0x0 ,0x0 ,0x40 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0xD8 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x90 ,0xF9 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0xC8 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x14 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0xC0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFB ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB8 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x10 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x10 ,0x20 ,0x22 ,0x0 ,0x8 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x20 ,0x0 ,0x8 ,0x0 ,0x0 ,0x10 ,0x0 ,0xB0 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0xF8 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xB0 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0xFF ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x80 ,0x0 ,0x0 ,0x2 ,0x1 ,0x40 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x4 ,0x8 ,0xE0 ,0xF8 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x80 ,0x1 ,0x80 ,0x14 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x4 ,0x20 ,0x28 ,0xFE ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x5 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x84 ,0x14 ,0x1 ,0x0 ,0x40 ,0x24 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x12 ,0x40 ,0x0 ,0x40 ,0x8 ,0x9 ,0x21 ,0x1 ,0x5 ,0x4 ,0xF0 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x20 ,0x10 ,0x2 ,0x2 ,0x1 ,0x0 ,0x10 ,0xA0 ,0xFD ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x4 ,0x80 ,0x0 ,0x1 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0xD0 ,0xFF ,0x2 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x88 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x4 ,0x0 ,0x80 ,0xB0 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x88 ,0xFE ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC9 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC8 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x2 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x88 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x80 ,0x8 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0xE0 ,0xFC ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x10 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xD8 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x80 ,0x0 ,0xF8 ,0xFB ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x40 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x0 ,0x0 ,0x0 ,0x1 ,0x0 ,0x0 ,0x4 ,0x0 ,0x0 ,0x2 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x30 ,0xFF ,0x0 ,0x0 ,0x5 ,0x0 ,0x12 ,0x0 ,0x22 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x90 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x68 ,0xFF ,0x0 ,0x1 ,0x20 ,0x0 ,0x4 ,0x80 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x18 ,0x0 ,0x3 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x12 ,0x0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x41 ,0x0 ,0x0 ,0xE8 ,0xFA ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x98 ,0xFF ,0x0 ,0x17 ,0xE0 ,0x2 ,0x5C ,0x80 ,0xB ,0x50 ,0x1 ,0x2A ,0x40 ,0xB ,0xA8 ,0x0 ,0x15 ,0x40 ,0x2 ,0x54 ,0x0 ,0x9 ,0x20 ,0x1 ,0x2A ,0x40 ,0x5 ,0x90 ,0x0 ,0x12 ,0xE0 ,0x2 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x15 ,0xA0 ,0x2 ,0x48 ,0x0 ,0x9 ,0x70 ,0x1 ,0x2E ,0x80 ,0x4 ,0x90 ,0x0 ,0x12 ,0xA0 ,0x2 ,0x54 ,0x80 ,0xA ,0x70 ,0x1 ,0x2E ,0x40 ,0x5 ,0xA8 ,0x0 ,0x17 ,0xA0 ,0x2 ,0x78 ,0xFC ,0x80 ,0xC ,0x90 ,0x1 ,0x32 ,0x40 ,0x6 ,0x9A ,0x40 ,0x13 ,0x68 ,0x58 ,0x4C ,0x80 ,0x9 ,0x80 ,0x81 ,0x26 ,0x0 ,0x6 ,0xC0 ,0x80 ,0x13 ,0x70 ,0x2 ,0x60 ,0x0 ,0xC ,0x90 ,0x1 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xC0 ,0x9 ,0x34 ,0x1 ,0x30 ,0x0 ,0x6 ,0xC8 ,0x0 ,0x19 ,0x0 ,0x3 ,0x60 ,0x0 ,0xC ,0x34 ,0x81 ,0x26 ,0xD0 ,0x4 ,0xC8 ,0x0 ,0x19 ,0x70 ,0x2 ,0x4E ,0x80 ,0xC ,0x30 ,0x1 ,0xA0 ,0xFA ,0xFF ,0xFF ,0xFF};
+struct list device_list[MAX_DEVICE_ALLOW] = {{
+0x110300DD,
+0xE6,
+0xE6,
+0x50,
+"EP1K30T144",
+buffer_0,
+0xE74F,
+0,
+0xA}};
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/jb_const.h linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/jb_const.h
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/jb_const.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/jb_const.h	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,68 @@
+/******************************************************************/
+/*                                                                */
+/* Module:       jb_const.h                                       */
+/*                                                                */
+/* Descriptions: Contain USER and PROGRAM variables use by        */
+/*               jblaster.c                                       */
+/*                                                                */
+/* Revisions:    1.0 02/22/02                                     */
+/*                                                                */
+/******************************************************************/
+/* $Id$ */
+
+#ifndef JB_CONST_H
+#define JB_CONST_H
+
+/* User Variables */
+
+#define MAX_DEVICE_ALLOW 10
+#define MAX_CONFIG_COUNT 3
+#define INIT_COUNT       200
+
+/* JTAG Configuration Signals */
+#define SIG_TCK  0 /* TCK */
+#define SIG_TMS  1 /* TMS */
+#define SIG_TDI  2 /* TDI */
+#define SIG_TDO  3 /* TDO */
+
+/* Chain Description File (CDF) records string length */
+#define CDF_IDCODE_LEN 32
+#define CDF_PNAME_LEN  20
+#define CDF_PATH_LEN   50
+#define CDF_FILE_LEN   20
+
+extern const int JI_PROGRAM;/*      = 0x002L;*/
+extern const int JI_BYPASS;/*       = 0x3FFL;*/
+extern const int JI_CHECK_STATUS;/* = 0x004L;*/
+extern const int JI_STARTUP;/*      = 0x003L;*/
+
+/* Version Number */
+const char VERSION[4] = "0.1";
+
+int MAX_JTAG_INIT_CLOCK[8] = {
+	30,   /* ACEX      */
+	175,  /* APEX II   */
+	175,  /* APEX 20K  */
+	175,  /* APEX 20KC */
+	175,  /* APEX 20KE */
+	30,   /* FLEX 10KE */
+	175,  /* MERCURY   */
+	175   /* STRATIX   */
+};
+
+int device_family=0; /* Device Family, check jb_device.h for detail */
+
+/* a structure (list) that stores the records of a device */
+struct list{
+	int   idcode;
+	int   jseq_max;
+	int   jseq_conf_done;
+	char  action;
+	char  partname[CDF_PNAME_LEN];
+	unsigned char *buffer;
+	long  buffer_len;
+	char  compress;
+	int   inst_len;
+};
+
+#endif
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/jb_io.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/jb_io.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/jb_io.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/jb_io.c	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,157 @@
+/******************************************************************/
+/*                                                                */
+/* Module:       jb_io.c                                          */
+/*                                                                */
+/* Descriptions: Manages I/O related routines, for the DraginixVZ */
+/*                                                                */
+/* Revisions:    0.1 02/12/07                                     */
+/*                                                                */
+/******************************************************************/
+/* $Id$ */
+
+//#include <stdio.h>
+#include "jb_io.h"
+#include <asm/MC68VZ328.h>
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>			/* For in_interrupt() */
+#include <linux/config.h>
+
+
+/* SIGNALS */
+#define SIG_TCK  0 /* TCK */
+#define SIG_TMS  1 /* TMS */
+#define SIG_TDI  2 /* TDI */
+#define SIG_TDO  3 /* TDO */
+
+/* serial port interface available on all platforms */
+/* we need a direct interface to the serial port, because
+   the serial port driver is not working that early at boottime*/
+extern void putC (char ch);
+extern void putS (char * str);
+
+
+int low_printf(const char *fmt, ...)
+{
+	va_list args;
+	int printed_len;
+
+	static char printk_buf[1024];
+
+	va_start(args, fmt);
+	printed_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
+	va_end(args);
+
+	putS(printk_buf);
+
+	return printed_len;
+}
+
+void initialize_jtag_hardware()
+{
+        // Inititialize ports B,D and M
+        *(volatile unsigned char *) PBSEL_ADDR |= 0x20;
+        *(volatile unsigned char *) PDSEL_ADDR |= 0x03;
+        *(volatile unsigned char *) PMSEL_ADDR  |= 0x20;
+        *(volatile unsigned char *) PBPUEN_ADDR &= ~0x20;
+        *(volatile unsigned char *) PDPUEN_ADDR &= ~0x03;
+        *(volatile unsigned char *) PMPUEN_ADDR &= ~0x20;
+        *(volatile unsigned char *) PBDIR_ADDR  |= 0x20;
+        *(volatile unsigned char *) PDDIR_ADDR  |= 0x03;
+        *(volatile unsigned char *) PMDIR_ADDR  &= ~0x20;
+        *(volatile unsigned char *) PBDATA_ADDR |= 0x20;
+        *(volatile unsigned char *) PDDATA_ADDR |= 0x03;
+        *(volatile unsigned char *) PMDATA_ADDR |= 0x20;
+        //printk("JTAG Hardware Initilized\r\n");
+}
+
+void close_jtag_hardware()
+{
+        *(volatile unsigned char *) PBDIR_ADDR  &= ~0x20;
+        *(volatile unsigned char *) PDDIR_ADDR  &= ~0x03;
+        *(volatile unsigned char *) PMDIR_ADDR  &= ~0x20;
+        //printk("JTAG Hardware Closed\r\n");
+}
+
+
+/******************************************************************/
+/* Name:         ReadTDO                                          */
+/*                                                                */
+/* Parameters:   bit_count,data,inst                              */
+/*               -bit_count is the number of bits to shift out.   */
+/*               -data is the value to shift in from lsb to msb.  */
+/*               -inst determines if the data is an instruction.  */
+/*                if inst=1,the number of bits shifted in/out     */
+/*                equals to bit_count-1;if not,the number of bits */
+/*                does not change.                                */
+/*                                                                */
+/* Return Value: The data shifted out from TDO. The first bit     */
+/*               shifted out is placed at the lsb of the returned */
+/*               integer.                                         */
+/*               		                                          */
+/* Descriptions: Shift out bit_count bits from TDO while shift in */
+/*               data to TDI. During instruction loading, the     */
+/*               number of shifting equals to the instruction     */
+/*               length minus 1                                   */
+/*                                                                */
+/******************************************************************/
+__inline__ int ReadTDO(int bit_count,int data,int inst)
+{
+
+	unsigned int tdi=0,tdo=0,record=0;
+	unsigned int i,max = inst? (bit_count-1):bit_count;
+
+	for(i=0;i<max;i++)
+	{
+		unsigned int mask=1;
+
+		tdo = ((PMDATA&0x20) == 0x20) ? (1<<i):0;
+		record = record | tdo;
+
+		mask = mask << i;
+		tdi = data & mask;
+		tdi = tdi >> i;
+		PDDATA = tdi ? (PDDATA | 0x01) : (PDDATA & 0xfe);
+		PDDATA |= 0x02;
+		PDDATA &= 0xfd;
+		//DriveSignal(SIG_TDI,tdi,1,1);
+	}
+
+	return record;
+}
+
+/******************************************************************/
+/* Name:         DriveSignal                                      */
+/*                                                                */
+/* Parameters:   signal,data,clk,test                             */
+/*               -the name of the signal (SIG_*).                 */
+/*               -the value to be dumped to the signal,'1' or '0' */
+/*               -driving a LOW to HIGH transition to SIG_TCK     */
+/*                together with signal.                           */
+/*               -test is used by WritePort function.             */
+/*                                                                */
+/* Return Value: None.                                            */
+/*                                                                */
+/* Descriptions: Dump data to signal. If clk is '1', a clock pulse*/
+/*               is driven after the data is dumped to signal.    */
+/*                                                                */
+/******************************************************************/
+__inline__ void DriveSignal(int signal,int data,int clk,int test)
+{
+
+	if(signal == SIG_TCK)
+		PDDATA = data ? (PDDATA | 0x02) : (PDDATA & 0xfd);
+	else
+		if(signal == SIG_TMS)
+			PBDATA = data ? (PBDATA | 0x20) : (PBDATA & 0xdf);
+		else
+			if(signal == SIG_TDI)
+				PDDATA = data ? (PDDATA | 0x01) : (PDDATA & 0xfe);
+
+	if(clk)
+	{
+		PDDATA |= 0x02;
+		PDDATA &= 0xfd;
+	}
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/jb_io.h linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/jb_io.h
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/jb_io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/jb_io.h	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,19 @@
+/******************************************************************/
+/*                                                                */
+/* Module:       jb_io.h                                          */
+/*                                                                */
+/* Descriptions: Manages I/O related routines, for the DraginixVZ */
+/*                                                                */
+/* Revisions:    0.1 02/12/07                                     */
+/*                                                                */
+/******************************************************************/
+/* $Id$ */
+
+#ifndef JB_IO_H
+#define JB_IO_H
+void initialize_jtag_hardware(void);
+void close_jtag_hardware(void);
+__inline__ void DriveSignal(int, int, int, int);
+__inline__ int ReadTDO(int, int, int);
+int low_printf(const char *, ...);
+#endif
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/jb_jtag.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/jb_jtag.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/jb_jtag.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/jb_jtag.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,415 @@
+/******************************************************************/
+/*                                                                */
+/* Module:       jb_jtag.c                                        */
+/*                                                                */
+/* Descriptions: Manages JTAG State Machine (JSM), loading of     */
+/*               JTAG instructions                                */
+/*                                                                */
+/* Revisions:    0.1 02/12/07                                     */
+/*                                                                */
+/******************************************************************/
+/* $Id$ */
+
+//#include <stdio.h>
+//#include <string.h>
+#include <asm/MC68VZ328.h>
+#include "jb_jtag.h"
+#include "jb_io.h"
+
+#define MAX_JS_CHAR_COUNT 10
+#define JSM_RESET_COUNT 5
+
+/* JTAG Configuration Signals */
+#define J_SIG_TCK  0 /* TCK */
+#define J_SIG_TMS  1 /* TMS */
+#define J_SIG_TDI  2 /* TDI */
+#define J_SIG_TDO  3 /* TDO */
+
+/* States of JTAG State Machine */
+#define JS_RESET         0
+#define JS_RUNIDLE       1
+#define JS_SELECT_IR     2
+#define JS_CAPTURE_IR    3
+#define JS_SHIFT_IR      4
+#define JS_EXIT1_IR      5
+#define JS_PAUSE_IR      6
+#define JS_EXIT2_IR      7
+#define JS_UPDATE_IR     8
+#define JS_SELECT_DR     9
+#define JS_CAPTURE_DR    10
+#define JS_SHIFT_DR      11
+#define JS_EXIT1_DR      12
+#define JS_PAUSE_DR      13
+#define JS_EXIT2_DR      14
+#define JS_UPDATE_DR     15
+#define JS_UNDEFINE      16
+
+/* JTAG State Machine */
+const int JSM[16][2] = {
+/*-State-      -mode= '0'-    -mode= '1'- */
+/*RESET     */ {JS_RUNIDLE,   JS_RESET    },
+/*RUNIDLE   */ {JS_RUNIDLE,   JS_SELECT_DR},
+/*SELECTIR  */ {JS_CAPTURE_IR,JS_RESET    },
+/*CAPTURE_IR*/ {JS_SHIFT_IR,  JS_EXIT1_IR },
+/*SHIFT_IR  */ {JS_SHIFT_IR,  JS_EXIT1_IR },
+/*EXIT1_IR  */ {JS_PAUSE_IR,  JS_UPDATE_IR},
+/*PAUSE_IR  */ {JS_PAUSE_IR,  JS_EXIT2_IR },
+/*EXIT2_IR  */ {JS_SHIFT_IR,  JS_UPDATE_IR},
+/*UPDATE_IR */ {JS_RUNIDLE,   JS_SELECT_DR},
+/*SELECT_DR */ {JS_CAPTURE_DR,JS_SELECT_IR},
+/*CAPTURE_DR*/ {JS_SHIFT_DR,  JS_EXIT1_DR },
+/*SHIFT_DR  */ {JS_SHIFT_DR,  JS_EXIT1_DR },
+/*EXIT1_DR  */ {JS_PAUSE_DR,  JS_UPDATE_DR},
+/*PAUSE_DR  */ {JS_PAUSE_DR,  JS_EXIT2_DR },
+/*EXIT2_DR  */ {JS_SHIFT_DR,  JS_UPDATE_DR},
+/*UPDATE_DR */ {JS_RUNIDLE,   JS_SELECT_DR}
+};
+
+/* JTAG Instructions */
+const int JI_EXTEST       = 0x000;
+const int JI_PROGRAM      = 0x002;
+const int JI_STARTUP      = 0x003;
+const int JI_CHECK_STATUS = 0x004;
+const int JI_SAMPLE       = 0x005;
+const int JI_IDCODE       = 0x006;
+const int JI_USERCODE     = 0x007;
+const int JI_INTEST       = 0x008;
+const int JI_REGSCAN      = 0x009;
+const int JI_USER0        = 0x00C;
+const int JI_USER1        = 0x00E;
+const int JI_BYPASS       = 0x3FF;
+
+const char JS_NAME[][MAX_JS_CHAR_COUNT+1] = {
+"RESET",
+"RUN/IDLE",
+"SELECT_IR",
+"CAPTURE_IR",
+"SHIFT_IR",
+"EXIT1_IR",
+"PAUSE_IR",
+"EXIT2_IR",
+"UPDATE_IR",
+"SELECT_DR",
+"CAPTURE_DR",
+"SHIFT_DR",
+"EXIT1_DR",
+"PAUSE_DR",
+"EXIT2_DR",
+"UPDATE_DR",
+"UNDEFINE" };
+
+struct states
+{
+	int state;
+} jtag;
+
+/******************************************************************/
+/* Name:         Js_Reset                                         */
+/*                                                                */
+/* Parameters:   None.                                            */
+/*                                                                */
+/* Return Value: None.                                            */
+/*               		                                          */
+/* Descriptions: Reset the JSM by issuing JSM_RESET_COUNT of clock*/
+/*               with the TMS at HIGH.                            */
+/*                                                                */
+/******************************************************************/
+void Js_Reset()
+{
+	int i;
+
+	for(i=0;i<JSM_RESET_COUNT;i++)
+		AdvanceJSM(1);
+}
+
+/******************************************************************/
+/* Name:         Runidle                                          */
+/*                                                                */
+/* Parameters:   None.                                            */
+/*                                                                */
+/* Return Value: None.                                            */
+/*               		                                          */
+/* Descriptions: If the current JSM is not at UPDATE_DR or        */
+/*               UPDATE_IR state, RESET JSM and move to RUNIDLE,  */
+/*               if it is, clock once with TMS LOW and move to    */
+/*               RUNIDLE.                                         */
+/*                                                                */
+/******************************************************************/
+void Js_Runidle()
+{
+	int i=0;
+	
+	/* If the current state is not UPDATE_DR or UPDATE_IR, reset the JSM and move to RUN/IDLE */
+	if(jtag.state!=JS_UPDATE_IR && jtag.state!=JS_UPDATE_DR)
+	{
+		for(i=0;i<JSM_RESET_COUNT;i++)
+			AdvanceJSM(1);
+	}
+
+	AdvanceJSM(0);
+}
+
+/******************************************************************/
+/* Name:         AdvanceJSM                                       */
+/*                                                                */
+/* Parameters:   mode                                             */
+/*               -the input mode to JSM.                          */
+/*                                                                */
+/* Return Value: The current JSM state.                           */
+/*               		                                          */
+/* Descriptions: Function that keep track of the JSM state. It    */
+/*               drives out signals to TMS associated with a      */
+/*               clock pulse at TCK and updates the current state */
+/*               variable.                                        */
+/*                                                                */
+/******************************************************************/
+__inline__ int AdvanceJSM(int mode)
+{
+	PBDATA = mode ? (PBDATA | 0x20) : (PBDATA & 0xdf);
+	PDDATA |= 0x02;
+	PDDATA &= 0xfd;
+	//DriveSignal(J_SIG_TMS,mode,1,1);
+
+	jtag.state = JSM[jtag.state][mode];
+
+	return (jtag.state);
+}
+
+/******************************************************************/
+/* Name:         PrintJS                                          */
+/*                                                                */
+/* Parameters:   None.                                            */
+/*                                                                */
+/* Return Value: None.                                            */
+/*               		                                          */
+/* Descriptions: Print the current state of the JSM.              */
+/*                                                                */
+/******************************************************************/
+void PrintJS()
+{
+	//char state[MAX_JS_CHAR_COUNT+1];
+
+	//strcpy(state, JS_NAME[jtag.state]);
+
+	low_printf("Info: JSM: %s\r\n", JS_NAME[jtag.state]);
+}
+
+/******************************************************************/
+/* Name:         SetupChain                                       */
+/*                                                                */
+/* Parameters:   dev_count,dev_seq,ji_info,action                 */
+/*               -device_count is the total device in chain       */
+/*               -dev_seq is the device sequence in chain         */
+/*               -ji_info is the pointer to an integer array that */
+/*                contains the JTAG instruction length for the    */
+/*                devices in chain.                               */
+/*               -action is the JTAG instruction to load          */
+/*                                                                */
+/* Return Value: None.                                            */
+/*               		                                          */
+/* Descriptions: Move the JSM to SHIFT_IR. Issue the JTAG         */
+/*               instruction, "action" to the target device and   */
+/*               BYPASS to the rest of the devices. Then, move    */
+/*               the JSM to UPDATE_IR.                            */
+/*                                                                */
+/******************************************************************/
+void SetupChain(int dev_count,int dev_seq,int* ji_info,int action)
+{
+	int i,record=0;
+	/* Move Jtag State Machine (JSM) to RUN/IDLE */
+	if(jtag.state!=JS_RUNIDLE && jtag.state!=JS_RESET)
+		Js_Runidle();
+
+	/* Move JSM to SHIFT_IR */
+	AdvanceJSM(0);
+	AdvanceJSM(1);
+	AdvanceJSM(1);
+	AdvanceJSM(0);
+	AdvanceJSM(0);
+
+	for(i=dev_count-1;i>=0;i--)
+	{
+		if(i==dev_seq-1)
+			record = ReadTDO(ji_info[i],action,(i==0)? 1:0);
+		else
+			record = ReadTDO(ji_info[i],JI_BYPASS,(i==0)? 1:0);
+	}
+
+	/* Move JSM to UPDATE_IR */
+	AdvanceJSM(1);
+	AdvanceJSM(1);
+}
+
+/******************************************************************/
+/* Name:         LoadJI                                           */
+/*                                                                */
+/* Parameters:   action,dev_count,ji_info                         */
+/*               -action is the JTAG instruction to load          */
+/*               -dev_count is the maximum number of devices in   */
+/*                chain.                                          */
+/*               -ji_info is the pointer to an integer array that */
+/*                contains the JTAG instruction length for the    */
+/*                devices in chain.                               */
+/*                                                                */
+/* Return Value: 1 if contains error;0 if not.                    */
+/*               		                                          */
+/* Descriptions: Move the JSM to SHIFT_IR. Load in the JTAG       */
+/*               instruction to all devices in chain. Then        */
+/*               advance the JSM to UPDATE_IR. Irrespective of    */
+/*                                                                */
+/******************************************************************/
+__inline__ int LoadJI(int action,int dev_count,int* ji_info)
+{
+	int i,record=0,error=0;
+
+	/* Move Jtag State Machine (JSM) to RUN/IDLE */
+	if(jtag.state!=JS_RUNIDLE && jtag.state!=JS_RESET)
+		Js_Runidle();
+
+	/* Move JSM to SHIFT_IR */
+	AdvanceJSM(0);
+	AdvanceJSM(1);
+	AdvanceJSM(1);
+	AdvanceJSM(0);
+	AdvanceJSM(0);
+
+	for(i=0;i<dev_count;i++)
+	{
+		record = ReadTDO(ji_info[i],action,(i==(dev_count-1))? 1:0);
+
+		if(record!=0x155)
+		{
+			error=1;
+			low_printf("Error: JTAG chain broken!\r\nError: Bits unloaded: 0x%X\r\n", record);
+			return error;
+		}
+	}
+
+	/* Move JSM to UPDATE_IR */
+	AdvanceJSM(1);
+	AdvanceJSM(1);
+
+	return error;
+}
+
+/******************************************************************/
+/* Name:         Js_Shiftdr                                       */
+/*                                                                */
+/* Parameters:   None.                                            */
+/*                                                                */
+/* Return Value: 1 if the current state is not UPDATE_DR or       */
+/*               UPDATE_IR. 0 if the opeation is successful.      */
+/*               		                                          */
+/* Descriptions: Move the JSM to SHIFT_DR. The current state is   */
+/*               expected to be UPDATE_DR or UPDATE_IR.           */
+/*                                                                */
+/******************************************************************/
+int Js_Shiftdr()
+{
+	/* The current JSM state must be in UPDATE_IR or UPDATE_DR */
+	if(jtag.state!=JS_UPDATE_DR && jtag.state!=JS_UPDATE_IR)
+	{
+		if(jtag.state!=JS_RESET && jtag.state!=JS_RUNIDLE)
+			return (1);
+		else
+		{
+			AdvanceJSM(0);
+			AdvanceJSM(0);
+			AdvanceJSM(1);
+			AdvanceJSM(0);
+			AdvanceJSM(0);
+
+			return (0);
+		}
+	}
+
+	AdvanceJSM(1);
+	AdvanceJSM(0);
+	AdvanceJSM(0);
+
+	return (0);
+}
+
+/******************************************************************/
+/* Name:         Js_Updatedr                                      */
+/*                                                                */
+/* Parameters:   None.                                            */
+/*                                                                */
+/* Return Value: 1 if the current state is not SHIFT_DR;0 if the  */
+/*               operation is successful.                         */
+/*               		                                          */
+/* Descriptions: Move the JSM to UPDATE_DR. The current state is  */
+/*               expected to be SHIFT_DR                          */
+/*                                                                */
+/******************************************************************/
+int Js_Updatedr()
+{
+	/* The current JSM state must be in UPDATE_IR or UPDATE_DR */
+	if(jtag.state!=JS_SHIFT_DR)
+		return (1);
+
+	AdvanceJSM(1);
+	AdvanceJSM(1);
+
+	return (0);
+}
+
+int Ji_Extest(int dev_count,int* ji_info)
+{
+	return LoadJI(JI_EXTEST,dev_count,ji_info);
+}
+
+int Ji_Program(int dev_count,int* ji_info)
+{
+	return LoadJI(JI_PROGRAM,dev_count,ji_info);
+}
+
+int Ji_Startup(int dev_count,int* ji_info)
+{
+	return LoadJI(JI_STARTUP,dev_count,ji_info);
+}
+
+int Ji_Checkstatus(int dev_count,int* ji_info)
+{
+	return LoadJI(JI_CHECK_STATUS,dev_count,ji_info);
+}
+
+int Ji_Sample(int dev_count,int* ji_info)
+{
+	return LoadJI(JI_SAMPLE,dev_count,ji_info);
+}
+
+int Ji_Idcode(int dev_count,int* ji_info)
+{
+	return LoadJI(JI_IDCODE,dev_count,ji_info);
+}
+
+int Ji_Usercode(int dev_count,int* ji_info)
+{
+	return LoadJI(JI_USERCODE,dev_count,ji_info);
+}
+
+int Ji_Intest(int dev_count,int* ji_info)
+{
+	return LoadJI(JI_INTEST,dev_count,ji_info);
+}
+
+int Ji_Regscan(int dev_count,int* ji_info)
+{
+	return LoadJI(JI_REGSCAN,dev_count,ji_info);
+}
+
+int Ji_User0(int dev_count,int* ji_info)
+{
+	return LoadJI(JI_USER0,dev_count,ji_info);
+}
+
+int Ji_User1(int dev_count,int* ji_info)
+{
+	return LoadJI(JI_USER1,dev_count,ji_info);
+}
+
+int Ji_Bypass(int dev_count,int* ji_info)
+{
+	return LoadJI(JI_BYPASS,dev_count,ji_info);
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/jb_jtag.h linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/jb_jtag.h
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/jb_jtag.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/jb_jtag.h	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,35 @@
+/******************************************************************/
+/*                                                                */
+/* Module:       jb_jtag.h                                        */
+/*                                                                */
+/* Descriptions: Manages JTAG State Machine (JSM), loading of     */
+/*               JTAG instructions                                */
+/*                                                                */
+/* Revisions:    0.1 02/12/07                                     */
+/*                                                                */
+/******************************************************************/
+/* $Id$ */
+
+#ifndef JB_JTAG_H
+#define JB_JTAG_H
+__inline__ int  AdvanceJSM(int);
+void PrintJS(void);
+void SetupChain(int, int, int *,int);
+__inline__ int  LoadJI(int,int,int *);
+int  Ji_Extest(int, int *);
+int  Ji_Program(int,int *);
+int  Ji_Startup(int, int *);
+int  Ji_Checkstatus(int,int *);
+int  Ji_Sample(int, int *);
+int  Ji_Idcode(int, int *);
+int  Ji_Usercode(int, int *);
+int  Ji_Intest(int, int *);
+int  Ji_Regscan(int, int *);
+int  Ji_User0(int, int *);
+int  Ji_User1(int, int *);
+int  Ji_Bypass(int, int *);
+void Js_Reset(void);
+void Js_Runidle(void);
+int  Js_Shiftdr(void);
+int  Js_Updatedr(void);
+#endif
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/jblaster.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/jblaster.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/jblaster.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/jblaster.c	2005-06-14 02:11:15.000000000 +0100
@@ -0,0 +1,415 @@
+/******************************************************************/
+/*                                                                */
+/* Module:       jblaster.c                                       */
+/*                                                                */
+/* Descriptions: Main source file that manages the configuration  */
+/*               processes.                                       */
+/*                                                                */
+/* Revisions:    0.1 02/12/07                                     */
+/*                                                                */
+/******************************************************************/
+/* $Id* */
+
+#include <asm/MC68VZ328.h>
+#include "jb_io.h"
+#include "jb_jtag.h"
+#include "jb_const.h"
+#include "jb_cdf.h"
+
+#define DEBUG 1
+
+/* JTAG instruction lengths of all devices */
+int  ji_info[MAX_DEVICE_ALLOW] = {0x0};
+
+/* JBlaster Controller Functions */
+int  VerifyChain      (void);
+void Configure        (int, int, int);
+void ProcessFileInput (int);
+int  CheckStatus      (int);
+void Startup          (int);
+
+void jb_main(void)
+{
+	int i=0;
+	int file_id=0;
+	int config_count=0;
+
+	/**********Initialization**********/
+
+	/* Introduction */
+	low_printf("JTAGBlaster (JBlaster) Version %s",VERSION);
+	low_printf("\r\n Altera Corporation ");
+   	low_printf("\r\n Ported to linux by Marcos Lois Bermudez (marcos.lois@securez.org)\r\n");
+
+   /* Setup JTAG interface */
+	initialize_jtag_hardware();
+
+	if(!device_count)
+		return;
+
+	for(i=0;i<device_count;i++)
+	{
+   	ji_info[i] = device_list[i].inst_len;
+		if(!ji_info[i])
+		{
+			low_printf("Error: JTAG instruction length of device #%d NOT specified!\r\n",i);
+			return;
+		}
+	}
+
+	/**********Device Chain Verification**********/
+
+	low_printf("Info: Verifying device chain...\r\n" );
+
+	/* Verify the JTAG-compatible devices chain */
+	if(VerifyChain())
+		return;
+
+#ifdef DEBUG
+	for(i=0;i<device_count;i++)
+	{
+		low_printf("Debug: (Id)0x%X (Action)%c (Part)%s (File Len)%d Bytes (Inst Len)%d\r\n",
+      	device_list[i].idcode,
+			device_list[i].action,device_list[i].partname,
+			device_list[i].buffer_len,device_list[i].inst_len);
+	}
+#endif
+
+	/**********Configuration**********/
+	file_id=0;
+
+	for(i=1;i<device_count+1;i++)
+	{
+		config_count=0;
+
+		if(device_list[i-1].action != 'P')
+			continue;
+
+		while(config_count<MAX_CONFIG_COUNT)
+		{
+			if(!config_count)
+				low_printf("Info: Configuration setup device #%d\r\n",i);
+			else
+				low_printf("Info: Configuration setup device #%d (Retry)\r\n",i);
+
+			config_count++;
+
+			/* Start configuration */
+			Configure(i-1,i,(device_list[i-1].idcode? JI_PROGRAM:JI_BYPASS));
+
+			if(CheckStatus(i))
+			{
+				low_printf("Warning: Configuration of device #%d NOT successful!\r\n",i );
+			}
+			else
+			{
+				Startup(i);
+				config_count=MAX_CONFIG_COUNT;
+				low_printf("Info: Configuration of device #%d successful...\r\n",i );
+			}
+		}
+	}
+
+   // Release JTAG interface
+	close_jtag_hardware();
+
+	return;
+}
+
+
+
+/******************************************************************/
+/* Name:         VerifyChain                                      */
+/*                                                                */
+/* Parameters:   None.                                            */
+/*                                                                */
+/* Return Value: None.                                            */
+/*               		                                          */
+/* Descriptions: Putting all devices in BYPASS mode, a 8-bit      */
+/*               vector is driven to TDI, the number of '0'       */
+/*               detected indicates the number of devices in      */
+/*               chain. The 8-bit vector must follows the zeroes. */
+/*                                                                */
+/******************************************************************/
+int VerifyChain()
+{
+	unsigned int data=0,temp=0,test_vect=0x55;
+	int i,num=0,error=0;
+
+	Js_Reset();
+
+
+	/* Load BYPASS instruction and test JTAG chain with a few vectors */
+	if(Ji_Bypass(device_count,ji_info))
+		return (1);
+	Js_Shiftdr();
+
+	/* Drive a 8-bit vector of "10101010" (right to left) to test */
+	data = ReadTDO(8+device_count,test_vect,0);
+	/* The number of leading '0' detected must equal to the number of devices specified */
+	temp = data;
+
+	for(i=0;i<device_count;i++)
+	{
+		temp = temp&1;
+		if(temp)
+			break;
+		else
+			num++;
+		temp = data>>(i+1);
+	}
+
+	if(temp==test_vect)
+		low_printf("Info: Detected %d device(s) in chain...\r\n", num);
+	else
+	{
+		low_printf("Error: JTAG chain broken or #device in chain unmatch!\r\nError: Bits unloaded: 0x%X\r\n",temp);
+		return (1);
+	}
+
+	Js_Updatedr();
+
+	/* Read device IDCODE */
+	Ji_Idcode(device_count,ji_info);
+	Js_Shiftdr();
+
+	for(i=device_count-1;i>=0;i--)
+	{
+		data = ReadTDO(CDF_IDCODE_LEN,0,0);
+
+		if(device_list[i].idcode)
+		{
+			/* The partname specified in CDF must match with its ID Code */
+			if((unsigned)device_list[i].idcode != data)
+			{
+				low_printf("Error: Expected 0x%X but detected 0x%X!\r\n",device_list[i].idcode,data);
+				error=1;
+			}
+			else
+				low_printf("Info: Dev%d: Altera: 0x%X\r\n",i+1,data);
+		}
+		else
+		{
+			low_printf("Info: Dev%d: Non-Altera: 0x%X\r\n",i+1,data);
+		}
+	}
+
+	Js_Updatedr();
+	Js_Runidle();
+
+	return error;
+}
+
+/******************************************************************/
+/* Name:         Configure                                        */
+/*                                                                */
+/* Parameters:   file_id,dev_seq,action                           */
+/*               -cnum is num of chain (0 first chain)            */
+/*               -dev_seq is the device sequence in chains.       */
+/*               -action is the action to take:BYPASS or PROGRAM  */
+/*                                                                */
+/* Return Value: None.                                            */
+/*               		                                             */
+/* Descriptions: Issue PROGRAM instruction to the device to be    */
+/*               configured and BYPASS for the rest of the devices*/
+/*               Call function that processes the source file.    */
+/*                                                                */
+/******************************************************************/
+void Configure(int cnum,int dev_seq,int action)
+{
+	int i;
+
+	/* Load PROGRAM instruction */
+	SetupChain(device_count,dev_seq,ji_info,action);
+
+	if(action==JI_PROGRAM)
+	{
+		/* Drive TDI HIGH while moving JSM to SHIFTDR */
+		DriveSignal(SIG_TDI,1,0,1);
+		Js_Shiftdr();
+		/* Issue MAX_JTAG_INIT_CLOCK clocks in SHIFTDR state */
+		for(i=0;i<MAX_JTAG_INIT_CLOCK[device_family];i++)
+		{
+			DriveSignal(SIG_TDI,1,1,0);
+		}
+		/* Start dumping configuration bits into TDI and clock with TCK */
+		ProcessFileInput(cnum);
+
+		/* Move JSM to RUNIDLE */
+		Js_Updatedr();
+		Js_Runidle();
+	}
+}
+
+/******************************************************************/
+/* Name:         CheckStatus                                      */
+/*                                                                */
+/* Parameters:   dev_seq                                          */
+/*               -dev_seq is the device sequence in chains.       */
+/*                                                                */
+/* Return Value: '0' if CONF_DONE is HIGH;'1' if it is LOW.       */
+/*               		                                          */
+/* Descriptions: Issue CHECK_STATUS instruction to the device to  */
+/*               be configured and BYPASS for the rest of the     */
+/*               devices.                                         */
+/*                                                                */
+/*               <conf_done_bit> =                                */
+/*                  ((<Maximum JTAG sequence> -                   */
+/*                    <JTAG sequence for CONF_DONE pin>)*3) + 1   */
+/*                                                                */
+/*               The formula calculates the number of bits        */
+/*               to be shifted out from the device, excluding the */
+/*               1-bit register for each device in BYPASS mode.   */
+/*                                                                */
+/******************************************************************/
+int CheckStatus(int dev_seq)
+{
+	int bit,data=0,error=0;
+	int jseq_max=0,jseq_conf_done=0,conf_done_bit=0;
+
+	low_printf("Info: Checking Status\r\n" );
+
+	/* Load CHECK_STATUS instruction */
+	SetupChain(device_count,dev_seq,ji_info,JI_CHECK_STATUS);
+
+	Js_Shiftdr();
+
+	/* Maximum JTAG sequence of the device in chain */
+	jseq_max= device_list[dev_seq-1].jseq_max;
+
+	jseq_conf_done= device_list[dev_seq-1].jseq_conf_done;
+
+	conf_done_bit = ((jseq_max-jseq_conf_done)*3)+1;
+
+	/* Compensate for 1 bit unloaded from every Bypass register */
+	conf_done_bit+= (device_count-dev_seq);
+
+	for(bit=0;bit<conf_done_bit;bit++)
+	{
+		DriveSignal(SIG_TDI,0,1,1);
+	}
+
+	data = ReadTDO(1,0,0);
+
+	if(!data)
+		error++;
+
+	/* Move JSM to RUNIDLE */
+	Js_Updatedr();
+	Js_Runidle();
+
+	return (error);
+}
+
+/******************************************************************/
+/* Name:         Startup                                          */
+/*                                                                */
+/* Parameters:   dev_seq                                          */
+/*               -the device sequence in the chain.               */
+/*                                                                */
+/* Return Value: None.                                            */
+/*               		                                          */
+/* Descriptions: Issue STARTUP instruction to the device to       */
+/*               be configured and BYPASS for the rest of the     */
+/*               devices.                                         */
+/*                                                                */
+/******************************************************************/
+void Startup(int dev_seq)
+{
+	int i;
+
+	/* Load STARTUP instruction to move the device to USER mode */
+	SetupChain(device_count,dev_seq,ji_info,JI_STARTUP);
+
+	Js_Runidle();
+
+	for(i=0;i<INIT_COUNT;i++)
+	{
+		DriveSignal(SIG_TCK,0,0,0);
+		DriveSignal(SIG_TCK,1,0,0);
+	}
+
+	/* Reset JSM after the device is in USER mode */
+	Js_Reset();
+}
+
+/******************************************************************/
+/* Name:         ProcessFileInput                                 */
+/*                                                                */
+/* Parameters:   cnum                                             */
+/*               -num of chain to program (0 first chain)         */
+/*                                                                */
+/* Return Value: None.                                            */
+/*                                                                */
+/* Descriptions: Get programming file size, parse through every   */
+/*               single byte and dump to parallel port.           */
+/*                                                                */
+/******************************************************************/
+void ProcessFileInput(int cnum)
+{
+	unsigned char *one_byte, bit = 0;
+	int i,j,k;
+
  	int nbytes;
+
+	/* Start configuration */
+	low_printf("Info: Start configuration process.\r\n  Please wait...");
+
+   /* Check for compressed data */
+   if(device_list[cnum].compress) {
+   	/* Process compress data */
+		one_byte = device_list[cnum].buffer;
+		for(i=0;i<device_list[cnum].buffer_len;)
+		{
+			nbytes = (*(one_byte) & 0x7f) + 1;
+			if (*(one_byte) & 0x80) {
+				one_byte++; i++; // Get next byte
+         	for(k=0;k<nbytes;k++) {
+					// Write nbytes
+               /* Progaram a byte,from LSb to MSb */
+					for (j=0;j<8;j++ )
+					{
+						bit = *(one_byte) >> j;
+						bit = bit & 0x1;
+
+						/* Dump to TDI and drive a positive edge pulse at the same time */
+						DriveSignal(SIG_TDI,bit,1,0);
+					}
+	         }
+			} else {
+   	   	for(k=0;k<nbytes;k++) {
+      	   	one_byte++; i++; // Get next byte
+					// Write byte
+               /* Progaram a byte,from LSb to MSb */
+					for (j=0;j<8;j++ )
+					{
+						bit = *(one_byte) >> j;
+						bit = bit & 0x1;
+
+						/* Dump to TDI and drive a positive edge pulse at the same time */
+						DriveSignal(SIG_TDI,bit,1,0);
+					}
+	         }
+			}
+      	one_byte++; i++;
+      }
+   } else {
+	/* Loop through every single byte */
+   	one_byte = device_list[cnum].buffer;
+	for(i=device_list[cnum].buffer_len;i;i--)
+	{
+      		bit = 0;
+		/* Progaram a byte,from LSb to MSb */
+		for (j=0;j<8;j++ )
+		{
+			bit = (*(one_byte) >> j) & 0x01;
+			PDDATA = bit ? (PDDATA | 0x01) : (PDDATA & 0xfe);
+			PDDATA |= 0x02;
+			PDDATA &= 0xfd;
+   			/* Dump to TDI and drive a positive edge pulse at the same time */
+			//DriveSignal(SIG_TDI,bit,1,0);
+		}
+		one_byte++;
+	}
+	low_printf(" done\r\n");
+   }
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/jblaster.h linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/jblaster.h
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/jblaster.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/jblaster.h	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,4 @@
+#ifdef JBLASTER_H
+#define JBLASTER_H
+void jb_main(void);
+#endif
\ No newline at end of file
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/ram.ld	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,121 @@
+MEMORY
+	{
+        romvec : ORIGIN = 0x2000000, LENGTH = 0x0000400
+        flash  : ORIGIN = 0x2000400, LENGTH = 0x0200000 - 0x0000400
+        eflash : ORIGIN = 0x2200000, LENGTH = 0
+        ramvec : ORIGIN = 0x0000000, LENGTH = 0x0000400
+        framebuf : ORIGIN = 0x0000400, LENGTH = 0x002fc00
+        eframebuf : ORIGIN = 0x0030000, LENGTH = 0
+        ram    : ORIGIN = 0x0030000, LENGTH = 0x2000000 - 0x0030000
+        eram8MB : ORIGIN = 0x0800000, LENGTH = 0
+        eram32MB : ORIGIN = 0x2000000, LENGTH = 0
+	}
+
+
+SECTIONS
+{
+       	.fakevec :      /* This will be needed after reset */
+	{
+	_flashstart = . ;
+	_romvec = . ;
+	__rom_start = . ;
+	} > romvec
+        .rom :
+        {
+        _start = . ;    /* This is where the assembler init code starts*/
+        } > flash
+	.eflash :
+	{
+	_flashend = . ; /* End of flash */
+	} > eflash
+	.realvec :      /* Vector used by the kernel */
+	{
+	__ramvec = . ;
+	__ram_start = . ;
+        } > ramvec
+
+	.framebuf :     /* Dedicated memory for the framebuffer */
+	{
+	__vram_start = . ;
+	} > framebuf
+	.eframebuf :    /* End of that memory */
+	{
+	__vram_end = . ;
+	} > eframebuf
+
+        .text :         /* Text section */
+	{
+	text_start = . ;
+        	*(.text)
+		*(.text.*)
+		*(.rodata)
+		*(.rodata.str1.1)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	_etext = . ;
+	__data_rom_start = ALIGN ( 4 ) ;
+        } > ram
+        .data :
+	{
+	_sdata = . ;
+	__data_start = . ;
+
+        . = ALIGN(0x2000) ;
+        *(.data.init_task)
+        . = ALIGN(0x2000) ;
+
+        *(.data)
+        *(.data.*)
+        *(.setup.init)
+        *(.exitcall.exit)
+
+        . = ALIGN(4096) ;
+        __init_begin = .;
+        *(.text.init)
+        *(.data.init)
+        . = ALIGN(16);
+        __setup_start = .;
+        *(.setup.init)
+        __setup_end = .;
+        __initcall_start = .;
+        *(.initcall.init)
+        . = ALIGN(4) ;
+        __initcall_end = .;
+        __init_end = .;
+
+	_edata = . ;
+	edata = ALIGN( 0x10 ) ;
+        } > ram
+        .bss :
+        {
+	_sbss = ALIGN( 0x10 ) ;
+	__bss_start = ALIGN( 0x10 ) ;
+	__data_end = ALIGN( 0x10 ) ;
+	*(.bss)
+	*(COMMON)
+	_ebss = . ;
+	__bss_end = . ;
+	end = ALIGN( 0x10 ) ;
+	_end = ALIGN( 0x10 ) ;
+	} > ram
+
+  .eram8MB :    /* Ram end set default to the smallest, will be adjusted by the init code */
+	{
+	__ramend8MB = . ;
+        __ramend = . ;
+	} > eram8MB
+  .eram32MB :
+	{
+	__ramend32MB = . ;
+	} > eram32MB
+
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/ramold.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/ramold.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/ramold.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/ramold.ld	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,122 @@
+MEMORY
+	{
+        romvec : ORIGIN = 0x2000000, LENGTH = 0x0000400
+        flash  : ORIGIN = 0x2000400, LENGTH = 0x0200000 - 0x0000400
+        eflash : ORIGIN = 0x2200000, LENGTH = 0
+        ramvec : ORIGIN = 0x0000000, LENGTH = 0x0000400
+        framebuf : ORIGIN = 0x0000400, LENGTH = 0x002fc00
+        eframebuf : ORIGIN = 0x0030000, LENGTH = 0
+        ram    : ORIGIN = 0x0030000, LENGTH = 0x2000000 - 0x0030000
+        eram8MB : ORIGIN = 0x0800000, LENGTH = 0
+        eram32MB : ORIGIN = 0x2000000, LENGTH = 0
+	}
+
+
+SECTIONS
+{
+        .romvec :
+	{
+	_flashstart = . ;
+	_romvec = . ;
+	__rom_start = . ;
+	} > romvec
+
+	.eflash :
+	{
+	_flashend = . ;
+	} > eflash
+	.realvec :
+	{
+	__ramvec = . ;
+	} > ramvec
+
+	.framebuf :
+	{
+	__vram_start = . ;
+	} > framebuf
+	.eframebuf :
+	{
+	__vram_end = . ;
+	} > eframebuf
+
+	.romvec :
+	{
+	_romvec = . ;
+	} > bvec
+        .text :
+	{
+	__ram_start = . ;
+	text_start = . ;
+        	*(.text)
+		*(.text.*)
+		*(.rodata)
+		*(.rodata.str1.1)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	_etext = . ;
+	__data_rom_start = ALIGN ( 4 ) ;
+        } > ram
+        .data :
+	{
+	_sdata = . ;
+	__data_start = . ;
+
+        . = ALIGN(0x2000) ;
+        *(.data.init_task)
+        . = ALIGN(0x2000) ;
+
+        *(.data)
+        *(.data.*)
+        *(.setup.init)
+        *(.exitcall.exit)
+
+        . = ALIGN(4096) ;
+        __init_begin = .;
+        *(.text.init)
+        *(.data.init)
+        . = ALIGN(16);
+        __setup_start = .;
+        *(.setup.init)
+        __setup_end = .;
+        __initcall_start = .;
+        *(.initcall.init)
+        . = ALIGN(4) ;
+        __initcall_end = .;
+        __init_end = .;
+
+	_edata = . ;
+	edata = ALIGN( 0x10 ) ;
+        } > ram
+        .bss :
+        {
+	_sbss = ALIGN( 0x10 ) ;
+	__bss_start = ALIGN( 0x10 ) ;
+	__data_end = ALIGN( 0x10 ) ;
+	*(.bss)
+	*(COMMON)
+	_ebss = . ;
+	__bss_end = . ;
+	end = ALIGN( 0x10 ) ;
+	_end = ALIGN( 0x10 ) ;
+	} > ram
+
+  .eram8MB :
+	{
+	__ramend8MB = . ;
+        __ramend = . ;
+	} > eram8MB
+  .eram32MB :
+	{
+	__ramend32MB = . ;
+	} > eram32MB
+
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/rom.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/rom.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/dragonixvz/rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/dragonixvz/rom.ld	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,14 @@
+MEMORY
+	{
+        romvec : ORIGIN = 0x2000000, LENGTH = 0x0000400
+        flash  : ORIGIN = 0x2000400, LENGTH = 0x0200000 - 0x0000400
+        eflash : ORIGIN = 0x2200000, LENGTH = 0
+        ramvec : ORIGIN = 0x0000000, LENGTH = 0x0000400
+        framebuf : ORIGIN = 0x0000400, LENGTH = 0x002fc00
+        eframebuf : ORIGIN = 0x0030000, LENGTH = 0
+        ram    : ORIGIN = 0x0030000, LENGTH = 0x2000000 - 0x0030000
+        eram8MB : ORIGIN = 0x0800000, LENGTH = 0
+        eram32MB : ORIGIN = 0x2000000, LENGTH = 0
+	}
+
+INCLUDE arch/m68knommu/platform/68VZ328/dragonixvz/fixed.ld
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/Makefile linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/Makefile
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/Makefile	2005-06-14 02:11:14.000000000 +0100
@@ -0,0 +1,70 @@
+#
+# Makefile for the linux kernel.
+#
+# Reuse any files we can from the 68328 base
+#
+
+VPATH := $(VPATH):$(BOARD):../68328
+
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: $(BOARD)/crt0_$(MODEL).o entry.o platform.o
+O_TARGET := platform.o
+obj-y := entry.o config.o signal.o traps.o ints.o
+
+obj-$(CONFIG_PM) += pm.o
+
+ifdef CONFIG_DRAGONIXVZ
+ifdef CONFIG_DRAGONIXVZ_JTAGFPGA
+obj-y += $(BOARD)/jblaster.o $(BOARD)/jb_jtag.o $(BOARD)/jb_io.o $(BOARD)/hardware.o
+endif
+endif
+
+ifdef CONFIG_DRAGONIXVZ
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S $(BOARD)/bootlogo.rh
+else
+ifeq ($(CONFIG_DRAGEN2),y)
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S $(BOARD)/crt0_fixed.S
+else
+ifeq ($(CONFIG_CWVZ328),y)
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S $(BOARD)/bootlogo.rh
+else
+ifeq ($(CONFIG_CLIE),y)
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
+else
+$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S $(BOARD)/crt0_fixed.S $(BOARD)/bootlogo.rh
+endif
+endif
+endif
+endif
+
+entry.o: entry.S m68k_defs.h
+
+m68k_defs.h: ../../kernel/m68k_defs.c ../../kernel/m68k_defs.head
+	rm -f m68k_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/m68k_defs.c
+	cp ../../kernel/m68k_defs.head m68k_defs.h
+	chmod +w m68k_defs.h
+	grep '^#define' m68k_defs.s >> m68k_defs.h
+	rm m68k_defs.s
+-include m68k_defs.d
+
+ifeq ($(CONFIG_DRAGEN2),y)
+ifeq ($(CONFIG_INIT_LCD),y)
+obj-y += ccfl.o
+config.o: $(BOARD)/screen.h
+
+$(BOARD)/screen.h: $(BOARD)/screen.xbm
+	perl $(BOARD)/xbm2lcd.pl < $(BOARD)/screen.xbm > $(BOARD)/screen.h
+endif
+else
+$(BOARD)/bootlogo.rh: $(BOARD)/bootlogo.h
+	perl ../68328/tools/bootlogo.pl < $(BOARD)/bootlogo.h > $(BOARD)/bootlogo.rh
+endif
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/Rules.make linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/Rules.make
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/Rules.make	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,77 @@
+#
+# 68VZ328/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 2001		Lineo, Inc, <www.lineo.com>
+# Copyright (c) 1998-2001	D. Jeff Dionne <jeff@uClinux.org>
+# Copyright (C) 1998		Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 		Hamish Macdonald
+#
+# 68VZ328 Fixes By		Evan Stawnyczy
+#
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/m68000/libgcc.a
+
+CFLAGS := -fno-builtin -DNO_CACHE $(CFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -m68000 -D__ELF__ -DMAGIC_ROM_PTR -DNO_FORGET -DUTS_SYSNAME=\"uClinux\" -D__linux__
+AFLAGS := $(AFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -m68000 -D__ELF__ -DMAGIC_ROM_PTR -DUTS_SYSNAME=\"uClinux\" -Wa,--bitwise-or
+
+LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
+
+HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
+
+SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
+           arch/$(ARCH)/platform/$(PLATFORM) $(SUBDIRS)
+
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+              arch/$(ARCH)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+
+LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
+
+ifdef CONFIG_FRAMEBUFFER
+SUBDIRS := $(SUBDIRS) arch/$(ARCH)/console
+ARCHIVES := $(ARCHIVES) arch/$(ARCH)/console/console.a
+endif
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+romfs.s19: romfs.img arch/$(ARCH)/empty.o
+	$(CROSS_COMPILE)objcopy -v -R .text -R .data -R .bss --add-section=.fs=romfs.img --adjust-section-vma=.fs=0xa0000 arch/$(ARCH)/empty.o romfs.s19
+	$(CROSS_COMPILE)objcopy -O srec romfs.s19
+
+linux.data: linux
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.romvec --remove-section=.text --remove-section=.ramvec --remove-section=.bss --remove-section=.eram linux linux.data
+
+linux.text: linux
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.ramvec --remove-section=.bss --remove-section=.data --remove-section=.eram --set-section-flags=.romvec=CONTENTS,ALLOC,LOAD,READONLY,CODE linux linux.text
+
+romfs.img:
+	echo creating a vmlinux rom image without root filesystem!
+
+linux.bin: linux.text linux.data romfs.img
+	if [ -f romfs.img ]; then\
+		echo Creating linux.bin with romarray; \
+		cat linux.text linux.data romfs.img > linux.bin;\
+	else\
+		echo Creating linux.bin without romarray; \
+		cat linux.text linux.data > linux.bin;\
+	fi
+
+linux.trg linux.rom: linux.bin
+	perl arch/$(ARCH)/platform/$(PLATFORM)/tools/fixup.pl
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f arch/$(ARCH)/platform/$(PLATFORM)/m68k_defs.h
+	rm -f arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/bootlogo.rh
+	rm -f linux.text linux.data linux.bin linux.rom linux.trg
+	rm -f linux.s19 romfs.s19
+	rm -f linux.img romdisk.img
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/bootlogo.h linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/bootlogo.h
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/bootlogo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/bootlogo.h	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,3204 @@
+#define splash_width 640
+#define splash_height 480
+static unsigned char splash_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf8, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x7f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xfe, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x7c, 0x00, 0xe0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0xe0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3e, 0xf8, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
+  0x00, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0xfe, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+  0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xe0, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xff, 0x07, 0xfe, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0x01, 0xf8, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff,
+  0x00, 0xf0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0xe0, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x03,
+  0x3f, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x3f, 0x00, 0xc0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x0f, 0xfc, 0x00, 0x00, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f,
+  0x00, 0x80, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xff, 0xff, 0x3f, 0xf0, 0x01, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x80, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0xc0, 0xff,
+  0xc1, 0x03, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x07, 0x00, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f,
+  0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x07, 0x00, 0x00, 0xe0, 0x07, 0x0e, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x00,
+  0x3f, 0x1c, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x38, 0x00, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f,
+  0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e,
+  0x00, 0x00, 0x00, 0x00, 0x78, 0x70, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xe0, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc3, 0x01, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f,
+  0x00, 0x80, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x00, 0xf8, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x80, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x87, 0x03, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x3f, 0x00, 0xc0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x07, 0x00,
+  0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f,
+  0x00, 0xe0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0e, 0x00, 0xf0, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf0, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x30, 0x0c, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0x01, 0xf8, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1c, 0x00,
+  0xf0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x07, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x38, 0x00, 0xf0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0x38, 0x00, 0xf0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00,
+  0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0xe0, 0xff, 0x7f, 0xe0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe2, 0x00, 0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00,
+  0xe0, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0xc0, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x01, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01,
+  0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x80, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x03, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03,
+  0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07,
+  0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0xfe, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07,
+  0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0xf8, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07,
+  0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0xf0, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x07, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x9f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+  0xf8, 0xff, 0x1f, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0xff, 0xff, 0x00,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x38, 0x00, 0xfe, 0xff, 0x0f, 0x20, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0xf8, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xc0, 0xff, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0xfc, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0xe0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff,
+  0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xfc, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x1f, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+  0xfe, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xf0, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x38, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0xf8, 0xff, 0x01, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xc0, 0xff, 0x01,
+  0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0xfc, 0x01, 0xff, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x41, 0x08, 0x04, 0xb3, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0xe0, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x41, 0x08, 0x04, 0xb3, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x8e, 0x31, 0x7b, 0x30,
+  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x18, 0x8e, 0x31, 0x7b, 0x30, 0x30, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0xf8,
+  0x41, 0xc6, 0x84, 0x0c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0xf8, 0x41, 0xc6, 0x84, 0x0c,
+  0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x0f, 0x00, 0x00, 0x18, 0x0c, 0x08, 0x00, 0x40, 0xc0, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xe4,
+  0xb1, 0xc1, 0x98, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0xe4, 0xb1, 0xc1, 0x98, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+  0x08, 0x00, 0x00, 0x1c, 0x02, 0x08, 0x04, 0x4c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0xff, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1c,
+  0x02, 0x08, 0x04, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x1f, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x10, 0x80,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x64, 0x4c, 0x00, 0x00, 0x00,
+  0x36, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x09, 0x00, 0x00, 0x64, 0x4c, 0x00, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x9c,
+  0x01, 0x08, 0x83, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0xf0, 0xff,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x64, 0x8c, 0x01, 0x18, 0x40,
+  0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x0f, 0x00, 0x00, 0x64, 0x8c, 0x01, 0x18, 0x40, 0x30, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0x03, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x9b,
+  0x01, 0xc0, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x40,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x09, 0x00, 0x00, 0x9b, 0x01, 0xc0, 0x00, 0x00,
+  0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+  0x00, 0x00, 0x00, 0x07, 0x32, 0x06, 0x18, 0x43, 0x00, 0x06, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf0, 0xc1, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x02, 0x02, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x07,
+  0x32, 0x06, 0x18, 0x43, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x10, 0xe0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x7b, 0x00, 0x30, 0x03, 0x0c,
+  0x08, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x07, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x09, 0x00, 0xc0, 0x84, 0x8d, 0x01, 0x80, 0x00, 0xc0, 0x06, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xfd, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xc0, 0x84,
+  0x8d, 0x01, 0x80, 0x00, 0xc0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfd, 0x03, 0xf0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc0, 0x1b, 0x00, 0x30, 0x00, 0x40,
+  0x08, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xfc, 0x01, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0xc0, 0x1b, 0x00, 0x30, 0x00, 0x40, 0x08, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x07, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+  0xf8, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc0, 0x64,
+  0x42, 0x06, 0x1b, 0x03, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x10, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0x64, 0x42, 0x06, 0x1b, 0x03,
+  0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0x03, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x0f, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x80, 0x30, 0x08, 0x86, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x3f, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x1b,
+  0x00, 0x00, 0x80, 0x30, 0x08, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xc3, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0xe0, 0x84, 0x31, 0x30, 0x04, 0x80,
+  0xc1, 0x18, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x09, 0x00, 0xc0, 0x63, 0x02, 0x06, 0x00, 0x00, 0x00, 0x60, 0x6c, 0xfc,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+  0xe0, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x08, 0x00, 0xc0, 0x63,
+  0x02, 0x06, 0x00, 0x00, 0x00, 0x60, 0x6c, 0xfc, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xe0, 0x1c, 0x40, 0x00, 0x1b, 0x4c,
+  0x06, 0x81, 0x80, 0xfd, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x00, 0xf0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0xe0, 0x1c, 0x40, 0x00, 0x1b, 0x4c, 0x06, 0x81, 0x80, 0xfd,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x00, 0x80, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x09, 0x00, 0x20, 0x63,
+  0x0c, 0x08, 0x80, 0x00, 0x30, 0x06, 0x0c, 0xfc, 0xff, 0x7f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x30, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x20, 0x63, 0x0c, 0x08, 0x80, 0x00,
+  0x30, 0x06, 0x0c, 0xfc, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x0f, 0x00, 0xd8, 0x84, 0x01, 0xc0, 0x00, 0x00, 0x06, 0x00, 0x80, 0xf1,
+  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0xf8, 0x1b,
+  0x40, 0x08, 0x84, 0x0c, 0xc0, 0x18, 0x13, 0xcc, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xe0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0xf8, 0x1b, 0x40, 0x08, 0x84, 0x0c,
+  0xc0, 0x18, 0x13, 0xcc, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0xf0, 0xe4, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x09, 0x00, 0x38, 0x80, 0x01, 0x00, 0x18, 0x30, 0x06, 0x01, 0x00, 0xc0,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+  0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x07, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x38, 0x80,
+  0x01, 0x00, 0x18, 0x30, 0x06, 0x01, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x10, 0x84,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xd8, 0x1f, 0x30, 0x36, 0x80, 0x00,
+  0x00, 0x00, 0x03, 0xf2, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x4f, 0x0e, 0x00, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x08, 0x00, 0xd8, 0x1f, 0x30, 0x36, 0x80, 0x00, 0x00, 0x00, 0x03, 0xf2,
+  0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+  0x08, 0x00, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x09, 0x00, 0x3e, 0x00,
+  0x82, 0x01, 0x03, 0x40, 0x30, 0x98, 0x10, 0xf0, 0xe7, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x1f, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0x00, 0x10, 0xe4,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xe6, 0x1b, 0x00, 0x00, 0x18, 0x0c,
+  0x00, 0x00, 0x00, 0xfc, 0xff, 0xfb, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x41, 0x08, 0x00, 0x30, 0x7c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0xe6, 0x1b, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0xfc,
+  0xff, 0xfb, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+  0x08, 0x00, 0x20, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1e, 0x64,
+  0x30, 0xc6, 0x80, 0x80, 0x09, 0x06, 0x63, 0xfe, 0xf9, 0xff, 0xff, 0xff,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x30, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xf8, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0e, 0x00, 0xc0, 0x3c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1e, 0x64, 0x30, 0xc6, 0x80, 0x80,
+  0x09, 0x06, 0x63, 0xfe, 0xf9, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc3, 0x07, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0e, 0x00, 0x39, 0x03, 0x00, 0x00, 0x04, 0x0c, 0xc0, 0x60, 0x80, 0x3f,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0xfc, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x39, 0x03,
+  0x00, 0x00, 0x04, 0x0c, 0xc0, 0x60, 0x80, 0x3f, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3e, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x80, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0xe7, 0x04, 0x42, 0xc6, 0x00, 0x00,
+  0x00, 0x00, 0xec, 0xcf, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x0f, 0xc0, 0x1f, 0x80, 0x01, 0x00, 0x98, 0x4c, 0x06, 0x06, 0xf0, 0x01,
+  0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x01, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x09, 0xc0, 0x1f, 0x80,
+  0x01, 0x00, 0x98, 0x4c, 0x06, 0x06, 0xf0, 0x01, 0x00, 0xe0, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3f, 0x08, 0xc0, 0xe6, 0x04, 0x0c, 0x08, 0x00, 0x00,
+  0xc0, 0x60, 0x7c, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x1f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
+  0x00, 0xc0, 0xe6, 0x04, 0x0c, 0x08, 0x00, 0x00, 0xc0, 0x60, 0x7c, 0x00,
+  0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xc0, 0x19, 0x60,
+  0x40, 0x00, 0x63, 0x30, 0x08, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xf3, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x09, 0xc0, 0x19, 0x60, 0x40, 0x00, 0x63, 0x30,
+  0x08, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xf3, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x78, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0f, 0xc0, 0x27, 0x03, 0x00, 0x30, 0x00, 0x03, 0x00, 0xe6, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0xcf, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xc0, 0x27, 0x03,
+  0x00, 0x30, 0x00, 0x03, 0x00, 0xe6, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x0f, 0xc0, 0xde, 0x04, 0x0c, 0x06, 0x03, 0x80,
+  0xc1, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0f, 0x03, 0x00, 0xf8, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x0f, 0xc0, 0x19, 0x00, 0x32, 0x00, 0x60, 0x30, 0x08, 0xff, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9f,
+  0x07, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x09, 0xc0, 0x19, 0x00,
+  0x32, 0x00, 0x60, 0x30, 0x08, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9f, 0x07, 0x00, 0x18, 0x40,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3f, 0x00, 0xc0, 0x27, 0x63, 0x80, 0x31, 0x04, 0x03,
+  0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+  0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1c, 0xfe, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x1f, 0x07, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
+  0x00, 0xc0, 0x27, 0x63, 0x80, 0x31, 0x04, 0x03, 0xf0, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0x7f, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+  0xe0, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x31,
+  0x04, 0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0xd9, 0x04,
+  0x00, 0x08, 0x00, 0x80, 0xf9, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf0, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x1e, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0xfe, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x04, 0x00, 0x60, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x09, 0x00, 0xd9, 0x04, 0x00, 0x08, 0x00, 0x80,
+  0xf9, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x7f, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x78, 0x00, 0xf0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0f, 0xc0, 0x27, 0x00, 0x30, 0xc0, 0x60, 0xb0, 0xff, 0x7f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x60, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0xde, 0x9b,
+  0x8d, 0x01, 0x04, 0xc3, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0xf1, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x03, 0x00, 0xf0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0xde, 0x9b, 0x8d, 0x01, 0x04, 0xc3,
+  0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf1, 0xff,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3e, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0x39, 0x04, 0x00, 0xc8, 0x00, 0xfc, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xf8, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0x39, 0x04,
+  0x00, 0xc8, 0x00, 0xfc, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc6, 0xf8, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0xc0, 0xc7, 0x60, 0x42, 0x00, 0x60, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+  0x00, 0xc0, 0xc7, 0x60, 0x42, 0x00, 0x60, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0xc0, 0xff, 0x07,
+  0xb0, 0x09, 0xe4, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x30, 0x00, 0xfc, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0xde, 0x78, 0x02, 0x00, 0xfb, 0xff,
+  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f, 0xf0, 0xff, 0xff, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0xde, 0x78, 0x02, 0x00, 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x1f, 0xf8,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x08,
+  0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x3f, 0x07,
+  0xb0, 0xc9, 0xf8, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x3f, 0x07, 0xb0, 0xc9, 0xf8, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
+  0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x0f, 0x00, 0xe7, 0xfb, 0x43, 0x30, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0xe7, 0xfb,
+  0x43, 0x30, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0xe0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xfe, 0x1c, 0xb2, 0x0f, 0xe0, 0xff,
+  0x07, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0xf8, 0xe7, 0xfd, 0x01, 0xe0, 0xff, 0x07, 0x00, 0xe0, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xe0,
+  0xb1, 0x3f, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xf8,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xc0, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xf8, 0xe7,
+  0xfd, 0x01, 0xe0, 0xff, 0x07, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xe0, 0xb1, 0x3f, 0x00, 0x00,
+  0xf8, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x80, 0xff,
+  0x01, 0x00, 0xe0, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x98, 0x4f, 0x0e, 0x18, 0x00, 0xf8, 0xff, 0xff, 0xff,
+  0x07, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x80, 0xff, 0x01, 0x00, 0xe0, 0x03,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+  0x4f, 0x0e, 0xf8, 0x1f, 0xf6, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xf8, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb1, 0x01, 0xff, 0x1f,
+  0xf6, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xb1, 0x01, 0xff, 0x7f, 0xc0, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0xe0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
+  0x00, 0xce, 0xff, 0x7f, 0xc0, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0xe3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xe0, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0xce, 0xff, 0x7f,
+  0x00, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xc0, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x20, 0x1b, 0xb2, 0x31, 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0xe0, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x01, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0xc0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x1c,
+  0x00, 0xc0, 0xff, 0x73, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf0,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
+  0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xc0, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x1c, 0x00, 0xc0, 0x7f, 0x1c,
+  0x30, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x78, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x38, 0x87, 0x31, 0x06, 0x7c, 0x1c, 0x30, 0xff, 0xff, 0xff,
+  0xff, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x87,
+  0x31, 0x06, 0xfc, 0x0f, 0xc8, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x38,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+  0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe6, 0x04, 0x00, 0x30, 0xe3, 0x0f,
+  0xc8, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xe0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x30, 0xe6, 0x04, 0x00, 0x30, 0x03, 0x00, 0xf0, 0xff, 0xff, 0xff,
+  0xff, 0x03, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x07, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1b,
+  0x4c, 0x00, 0x04, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0xc0, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x07, 0x04, 0x00, 0x06, 0x18, 0x80,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0f, 0x0e, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x02, 0x07, 0x04, 0x00, 0x06, 0x78, 0xf3, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x08, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3e, 0x04,
+  0x02, 0x30, 0x60, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xf8,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0xc0, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3e, 0x04, 0x02, 0x30, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc6, 0x04, 0x40, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x04,
+  0x40, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x08,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x67, 0x00, 0x06, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x06, 0x04, 0x30, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04,
+  0x30, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x08,
+  0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x7e, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3e, 0x9b, 0x01, 0x30, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x30, 0x3e, 0x9b, 0x01, 0x30, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x1c, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x02, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x01, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x1c,
+  0x0c, 0x06, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x38,
+  0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xe0,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0xf0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x1c, 0x0c, 0x06, 0xfb, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x68, 0x7c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf8, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x38, 0x18, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x18, 0xfe, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0x03, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc6, 0x9b,
+  0x81, 0x01, 0x60, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x80,
+  0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xc0, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc6, 0x9b, 0x81, 0x01, 0x00, 0x00,
+  0xf6, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x38, 0x78, 0x0c, 0x30, 0x04, 0x00, 0xf6, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0xe8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x78,
+  0x0c, 0x30, 0x04, 0x00, 0xc8, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xf8,
+  0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x64, 0x40, 0x00, 0x1c, 0x00,
+  0xc8, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xf8, 0x58, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0x64, 0x40, 0x00, 0xfc, 0x03, 0xc0, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x78, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+  0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe0,
+  0x01, 0x36, 0xfc, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x38,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0xff,
+  0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe0, 0x01, 0x36, 0xfc, 0x1f,
+  0x30, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x8f, 0x01, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc6, 0x87, 0x0f, 0x00, 0xff, 0x1f, 0x30, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xcf, 0x03, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+  0x40, 0xc0, 0xff, 0x7f, 0xc0, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xcf, 0x03, 0x00, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xc0, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x40, 0xc0, 0xff, 0x7f,
+  0x00, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x8f, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x0e, 0xc6, 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x0e, 0xc6, 0xff, 0x7f, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff,
+  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0xf0, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x9c, 0x01, 0x30, 0xff, 0x7f,
+  0x00, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x20, 0x9c, 0x01, 0x30, 0xff, 0x63, 0x30, 0xff, 0xff, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0x07, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+  0x4c, 0x00, 0xff, 0x63, 0x30, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x31, 0xfc, 0x1f,
+  0x00, 0xff, 0xff, 0xfd, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xb2, 0x31, 0xfc, 0x0f, 0x00, 0xff, 0xff, 0x03,
+  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+  0x41, 0x00, 0xe0, 0x0f, 0x00, 0xff, 0xff, 0x03, 0xff, 0x03, 0x00, 0x38,
+  0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x41, 0x00, 0x00, 0x80,
+  0xc9, 0xf9, 0xff, 0x3d, 0xff, 0x03, 0x00, 0x78, 0xc0, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x60, 0x32, 0x08, 0x00, 0x80, 0xc9, 0xf9, 0xff, 0x3d,
+  0xff, 0x03, 0x00, 0xf8, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x02, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+  0x32, 0x08, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xcf, 0xff, 0x00, 0x00, 0xf8,
+  0x81, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0xff,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe0, 0x01, 0xf8, 0x00, 0x00,
+  0xf0, 0xff, 0xff, 0xcf, 0xff, 0x00, 0x00, 0x38, 0x03, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x60, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x03, 0x80, 0xff, 0xff, 0xff, 0xff,
+  0x3f, 0x00, 0x00, 0x38, 0x06, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0c, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0xff, 0xff, 0x03, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x38,
+  0x1e, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x03, 0xfc,
+  0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x38, 0xfc, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x1f, 0x00, 0x00, 0x38, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+  0x80, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x78,
+  0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe0, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff,
+  0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xf8, 0xc1, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x60, 0xf8, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
+  0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xc0, 0xff,
+  0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x67,
+  0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x13, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc0, 0xff,
+  0xff, 0xff, 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x67, 0xfe, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0xff, 0xff, 0x98, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
+  0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x0f, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x98,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xf8, 0xff,
+  0xff, 0xff, 0x7f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x3f, 0xe7, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xff, 0xfc, 0xff, 0xff, 0xff, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0xff, 0xff, 0x3f, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x00, 0xc0, 0xff, 0x67, 0x8c, 0xf9, 0xfb, 0x73, 0x00, 0x67, 0x10, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xf8,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xc0, 0xff, 0x67,
+  0x8c, 0xf9, 0xfb, 0x73, 0x00, 0x67, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0xe7, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0xc0, 0x27, 0xfc, 0x73, 0xc6, 0x1c, 0x8c,
+  0x37, 0x80, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff,
+  0xff, 0xff, 0x1f, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0xc0, 0x27, 0xfc, 0x73, 0xc6, 0x1c, 0x8c, 0x37, 0x80, 0x0c, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xfc,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0xc0, 0xfe, 0x03,
+  0x8c, 0x09, 0xe3, 0x73, 0xc8, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0xc0, 0xfe, 0x03, 0x8c, 0x09, 0xe3, 0x73,
+  0xc8, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0xc0, 0x27, 0xe7, 0x31, 0x36, 0x04, 0x8c, 0x01, 0x60, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0xc0, 0xde, 0x18,
+  0x42, 0xc0, 0x98, 0x30, 0x08, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0xc0, 0xde, 0x18, 0x42, 0xc0, 0x98, 0x30,
+  0x08, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0xc0, 0x27, 0x63, 0x00, 0x08, 0x63, 0x03, 0x06, 0x60, 0x10, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x27, 0x63,
+  0x00, 0x08, 0x63, 0x03, 0x06, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0xd9, 0x04, 0xb2, 0x01, 0x00, 0xb0,
+  0x31, 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf9, 0xff,
+  0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0xc0, 0xd9, 0x04, 0xb2, 0x01, 0x00, 0xb0, 0x31, 0x19, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0x07,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0c, 0xc0, 0x1e, 0x63,
+  0x00, 0x30, 0x04, 0x03, 0xc8, 0x60, 0x00, 0x0e, 0x00, 0x00, 0xfc, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x0e, 0xc0, 0xe1, 0x18, 0x80, 0x01, 0x60, 0xb0,
+  0x01, 0xe7, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x0f, 0xc0, 0xe1, 0x18, 0x80, 0x01, 0x60, 0xb0, 0x01, 0xe7, 0xf3, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x0f, 0xc0, 0x1e, 0x03,
+  0x02, 0x08, 0x04, 0x00, 0xc8, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xd8, 0x0f, 0xc0, 0x1e, 0x03, 0x02, 0x08, 0x04, 0x00,
+  0xc8, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xc0, 0x0f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x0b, 0x00, 0x21, 0x64, 0x40, 0xc0, 0x00, 0xb3, 0xf1, 0xfe, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xfb, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x21, 0x64,
+  0x40, 0xc0, 0x00, 0xb3, 0xf1, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xfb, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0xfb, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfd, 0x00, 0xc0, 0xdf, 0x00, 0x00, 0x06, 0x60, 0x00,
+  0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xf9, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf,
+  0x01, 0xc0, 0xdf, 0x00, 0x00, 0x06, 0x60, 0x00, 0x0e, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xf0, 0x03, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x0b, 0xc0, 0xc0, 0x84,
+  0x31, 0xc0, 0x00, 0x4c, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x83, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x1e, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0f, 0x0e, 0xc0, 0x3f, 0x18, 0x00, 0x06, 0x84, 0x80,
+  0x09, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0xc3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x0c, 0xc0, 0x3f, 0x18, 0x00, 0x06, 0x84, 0x80, 0x09, 0xff, 0xff, 0x3f,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+  0xc1, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0xc0, 0xc1, 0x03,
+  0x4c, 0x00, 0x00, 0x30, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x90, 0x13, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x08, 0xc0, 0xc1, 0x03, 0x4c, 0x00, 0x00, 0x30,
+  0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0xc0, 0x3f, 0x98, 0x01, 0x08, 0x1b, 0x43, 0xc8, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x98,
+  0x01, 0x08, 0x1b, 0x43, 0xc8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0xc6, 0x03, 0x40, 0x00, 0x00, 0x80,
+  0x31, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xef, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+  0x00, 0x00, 0x3f, 0x18, 0x0c, 0x30, 0x60, 0x0c, 0xce, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xef, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x3f, 0x18,
+  0x0c, 0x30, 0x60, 0x0c, 0xce, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xc7, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xde, 0x63, 0x40, 0x06, 0x03, 0x30,
+  0x30, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0x83, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e,
+  0x00, 0x00, 0xde, 0x63, 0x40, 0x06, 0x03, 0x30, 0x30, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x04,
+  0x02, 0x00, 0x00, 0x83, 0xc9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x38, 0x04, 0x02, 0x00, 0x00, 0x83,
+  0xc9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+  0x03, 0x00, 0xe0, 0x1b, 0x0c, 0x08, 0x18, 0x40, 0x30, 0xfe, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0xc0, 0x84,
+  0x81, 0x01, 0x03, 0x0c, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0xc0, 0x84, 0x81, 0x01, 0x03, 0x0c,
+  0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+  0x0e, 0x00, 0x00, 0x1b, 0x0c, 0x30, 0x80, 0x00, 0x30, 0xf8, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+  0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x1b,
+  0x0c, 0x30, 0x80, 0x00, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x67, 0xc0, 0x01, 0x04, 0x40,
+  0x00, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x08, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0x67, 0xc0, 0x01, 0x04, 0x40, 0x00, 0xe1, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+  0x30, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x9c,
+  0x01, 0x08, 0x60, 0x0c, 0x06, 0x86, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xbf, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x07, 0x0e, 0x00, 0x00, 0x18, 0x0c, 0xc0, 0x00, 0x00,
+  0xc0, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf0, 0x9f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+  0x07, 0x00, 0x00, 0x18, 0x0c, 0xc0, 0x00, 0x00, 0xc0, 0x00, 0xfc, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0xe0,
+  0x01, 0x06, 0x00, 0x30, 0x06, 0x86, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xe0, 0x01, 0x06, 0x00, 0x30,
+  0x06, 0x86, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+  0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x63, 0x03, 0x30, 0x00, 0xe0, 0xff,
+  0xff, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+  0x30, 0x00, 0x63, 0x03, 0x30, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x80, 0x83, 0x09, 0x18, 0x00,
+  0x00, 0x06, 0x83, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0x80, 0x83, 0x09, 0x18, 0x00, 0x00, 0x06, 0x83, 0xff,
+  0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0xc0, 0x00, 0x8c, 0xc9, 0x60, 0x00, 0xfe, 0xff, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x8e, 0x01, 0x84, 0x40,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+  0x0f, 0x00, 0x00, 0x00, 0x8e, 0x01, 0x84, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00,
+  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x60, 0x83, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+  0x00, 0xc8, 0x60, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x0c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0f, 0x00, 0x00, 0x00, 0x80, 0xc1, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x80, 0xc1, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x60, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf8, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xc6,
+  0x03, 0x00, 0x00, 0x00, 0x40, 0x08, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xef, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xd8, 0xef, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x1c, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xf3,
+  0x0f, 0x00, 0x00, 0x00, 0x80, 0x09, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x33, 0x0c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x88, 0x13, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x13,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x33, 0x0c, 0x00, 0x00, 0x00,
+  0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x88, 0xf3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xe3,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xe1, 0x1f, 0x00, 0x00, 0x00,
+  0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xf0, 0xc1, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00,
+  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc0, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x06, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/bootstd.h linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/bootstd.h
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/bootstd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/bootstd.h	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,132 @@
+/* bootstd.h:  Bootloader system call interface
+ *
+ * (c) 1999, Rt-Control, Inc.
+ */
+
+#ifndef __BOOTSTD_H__
+#define __BOOTSTD_H__
+
+#define NR_BSC 21            /* last used bootloader system call */
+
+#define __BN_reset        0  /* reset and start the bootloader */
+#define __BN_test         1  /* tests the system call interface */
+#define __BN_exec         2  /* executes a bootloader image */
+#define __BN_exit         3  /* terminates a bootloader image */
+#define __BN_program      4  /* program FLASH from a chain */
+#define __BN_erase        5  /* erase sector(s) of FLASH */
+#define __BN_open         6
+#define __BN_write        7
+#define __BN_read         8
+#define __BN_close        9
+#define __BN_mmap         10 /* map a file descriptor into memory */
+#define __BN_munmap       11 /* remove a file to memory mapping */
+#define __BN_gethwaddr    12 /* get the hardware address of my interfaces */
+#define __BN_getserialnum 13 /* get the serial number of this board */
+#define __BN_getbenv      14 /* get a bootloader envvar */
+#define __BN_setbenv      15 /* get a bootloader envvar */
+#define __BN_setpmask     16 /* set the protection mask */
+#define __BN_readenv      17 /* read environment variables */
+#define __BN_flash_chattr_range		18
+#define __BN_flash_erase_range		19
+#define __BN_flash_write_range		20
+
+/* Calling conventions compatible to (uC)linux/68k
+ * We use simmilar macros to call into the bootloader as for uClinux
+ */
+
+#define __bsc_return(type, res) \
+do { \
+   if ((unsigned long)(res) >= (unsigned long)(-64)) { \
+      /* let errno be a function, preserve res in %d0 */ \
+      int __err = -(res); \
+      errno = __err; \
+      res = -1; \
+   } \
+   return (type)(res); \
+} while (0)
+
+#define _bsc0(type,name) \
+type name(void) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc1(type,name,atype,a) \
+type name(atype a) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc2(type,name,atype,a,btype,b) \
+type name(atype a, btype b) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc3(type,name,atype,a,btype,b,ctype,c) \
+type name(atype a, btype b, ctype c) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
+type name(atype a, btype b, ctype c, dtype d) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   register long __d __asm__ ("%d4") = (long)d; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c), "d" (__d) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
+type name(atype a, btype b, ctype c, dtype d, etype e) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   register long __d __asm__ ("%d4") = (long)d; \
+   register long __e __asm__ ("%d5") = (long)e; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c), "d" (__d), "d" (__e) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#endif /* __BOOTSTD_H__ */
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/config.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/config.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/config.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,159 @@
+/*
+ *  linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c
+ *
+ *  Copyright (C) 1993 Hamish Macdonald
+ *  Copyright (C) 1999 D. Jeff Dionne
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/uCbootstrap.h>
+#include <asm/MC68VZ328.h>
+
+#define CLOCK_SOURCE TCTL_CLKSOURCE_SYSCLK
+#define CLOCK_PRE 7
+
+/* sysclock / HZ / TPRER+1
+   The PLL frequency is 32768 with a default multiplier of 2024
+   which results in a PLL clock of 66.322 MHz, resulting in
+   a clock freq of 33.161 MHz */
+#define TICKS_PER_JIFFY 41451
+
+static void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
+{
+#ifdef CONFIG_DRAGONBALL_USE_RTC
+	/* Enable RTC in RTC control register (defined in asm/MC68VZ328.h) */
+	RTCCTL |= RTCCTL_ENABLE;
+	/* Enable 128 Hz interrupt line (defined in asm/MC68VZ328.h) */
+	/* SAM5 == 0x2000 or 128Hz / 150.0000Hz interrupt enable */
+	RTCIENR |= RTCIENR_SAM5;
+	/* SAM_IRQ_NUM = Sampling timer for RTC */
+	request_irq(SAM_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+#else
+	TCTL = 0; /* disable timer 1 */
+	/* set ISR */
+	request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+	/* Restart mode, Enable int, Set clock source */
+	TCTL = TCTL_OM | TCTL_IRQEN | CLOCK_SOURCE;
+	TPRER = CLOCK_PRE;
+	TCMP = TICKS_PER_JIFFY;
+	TCTL |= TCTL_TEN;               /* Enable timer 1 */
+#endif
+}
+
+static void BSP_tick(void)
+{
+#ifdef CONFIG_DRAGONBALL_USE_RTC
+	RTCISR |= RTCISR_SAM5;
+#else
+	/* Reset Timer1 */
+	TSTAT &= 0;
+#endif
+}
+
+static unsigned long BSP_gettimeoffset(void)
+{
+#ifdef CONFIG_DRAGONBALL_USE_RTC
+	return 0;
+#else
+	unsigned long ticks = TCN, offset = 0;
+	
+	/* check for pending interrupt */
+	if (ticks < (TICKS_PER_JIFFY>>1) && (ISR & (1<<TMR_IRQ_NUM)))
+		offset = 1000000/HZ;
+	ticks = (ticks * 1000000/HZ) / TICKS_PER_JIFFY;
+	return ticks + offset;
+#endif
+}
+
+void BSP_gettod (int *yearp, int *monp, int *dayp,
+		   int *hourp, int *minp, int *secp)
+{
+	*yearp = *monp = *dayp = *hourp = *minp = *secp = 0;
+}
+
+int BSP_hwclk(int op, struct hwclk_time *t)
+{
+  if (!op) {
+    /* read */
+  } else {
+    /* write */
+  }
+  return 0;
+}
+
+int BSP_set_clock_mmss (unsigned long nowtime)
+{
+#if 0
+  short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+
+  tod->second1 = real_seconds / 10;
+  tod->second2 = real_seconds % 10;
+  tod->minute1 = real_minutes / 10;
+  tod->minute2 = real_minutes % 10;
+#endif
+  return 0;
+}
+
+void BSP_reset (void)
+{
+  cli();
+  asm volatile ("
+    moveal #0x10c00000, %a0;
+    moveb #0, 0xFFFFF300;
+    moveal 0(%a0), %sp;
+    moveal 4(%a0), %a0;
+    jmp (%a0);
+    ");
+}
+
+unsigned char *cs8900a_hwaddr;
+static int errno;
+
+_bsc0(char *, getserialnum)
+_bsc1(unsigned char *, gethwaddr, int, a)
+_bsc1(char *, getbenv, char *, a)
+
+void config_BSP(char *command, int len)
+{
+  unsigned char *p;
+
+  printk("\n68VZ328 DragonBallVZ support (c) 2003 Arcturus Networks, Inc.\n");
+
+  printk("uCdimm serial string [%s]\n",getserialnum());
+  p = cs8900a_hwaddr = gethwaddr(0);
+  printk("uCdimm hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+         p[0], p[1], p[2], p[3], p[4], p[5]);
+  p = getbenv("APPEND");
+  if (p)
+	  strcpy(command, p);
+  else
+	  command[0] = 0;
+ 
+  mach_sched_init      = BSP_sched_init;
+  mach_tick            = BSP_tick;
+  mach_gettimeoffset   = BSP_gettimeoffset;
+  mach_gettod          = BSP_gettod;
+  mach_hwclk           = NULL;
+  mach_set_clock_mmss  = NULL;
+  // mach_mksound         = NULL;
+  mach_reset           = BSP_reset;
+  // mach_debug_init      = NULL;
+
+  config_M68VZ328_irq();
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/crt0_fixed.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/crt0_fixed.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/crt0_fixed.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/crt0_fixed.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,120 @@
+#include <linux/config.h>
+	
+	.global _start
+	.global _stext
+
+	.global _rambase
+	.global _ramvec
+	.global _ramstart
+	.global _ramend
+
+#ifdef CONFIG_INIT_LCD
+	.global splash_bits
+#endif
+
+	.data
+
+/*
+ *      Set up the usable of RAM stuff. Size of RAM is determined then
+ *      an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+
+#ifdef CONFIG_INIT_LCD
+splash_bits:
+#include "bootlogo.rh"
+#endif
+	
+	.text
+_start:
+_stext:	movew	#0x2700,%sr
+#ifdef CONFIG_INIT_LCD
+	movel	#splash_bits, 0xfffffA00 /* LSSA */
+	moveb	#0x28,   0xfffffA05	/* LVPW */
+	movew	#0x280,  0xFFFFFa08	/* LXMAX */
+	movew	#0x1df,  0xFFFFFa0a	/* LYMAX */
+	moveb	#0,      0xfffffa29	/* LBAR */
+	moveb	#0,      0xfffffa25	/* LPXCD */
+	moveb	#0x08,   0xFFFFFa20	/* LPICF */
+	moveb	#0x01,   0xFFFFFA21	/* -ve pol */
+	moveb	#0x81,   0xfffffA27	/* LCKCON */
+	movew	#0xff00, 0xfffff412	/* LCD pins */
+#endif
+
+#ifdef CONFIG_DIRECT_IO_ACCESS
+	moveb	#0x0,	0xfffff000
+#endif
+
+	moveal  #__ramend-CONFIG_MEMORY_RESERVE*0x100000 - 0x10, %sp
+	movew	#32767, %d0  /* PLL settle wait loop */
+1:	subq	#1, %d0
+	bne	1b
+
+	/* Copy data segment from ROM to RAM */
+	moveal	#__data_rom_start, %a0
+	moveal	#_sdata, %a1
+	moveal	#_edata, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+1:	movel	%a0@+, %a1@+
+	cmpal	%a1, %a2
+	bhi	1b
+
+	moveal	#_sbss, %a0
+	moveal	#_ebss, %a1
+	/* Copy 0 to %a0 until %a0 == %a1 */
+	
+1:
+	clrl	%a0@+
+	cmpal	%a0, %a1
+	bhi	1b
+
+        movel   #_sdata, %d0    
+        movel   %d0,    _rambase        
+        movel   #_ebss,  %d0
+        movel   %d0,    _ramstart
+	movel	#__ramend-CONFIG_MEMORY_RESERVE*0x100000, %d0
+	movel	%d0,	_ramend
+	movel	#__ramvec,	%d0
+	movel	%d0,	_ramvec
+
+#ifdef CONFIG_68328_SERIAL_UART2
+	/* Enable RXD TXD port bits to enable UART2 */
+	moveb	#0xcf,   0xfffff43b
+#endif	
+	
+/*
+ * load the current task pointer and stack
+ */
+        lea     init_task_union,%a0
+        movel   %a0, _current_task
+        lea     0x2000(%a0),%sp
+
+1:	jsr	start_kernel
+        bra 1b
+_exit:
+
+	jmp	_exit
+
+
+putc:
+	moveb	%d7,0xfffff907
+1:
+	movew	0xfffff906, %d7
+	andw	#0x2000, %d7
+	beq	1b
+	rts
+
+	.data
+env:
+	.long	0
+	.text
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/crt0_himem.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/crt0_himem.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/crt0_himem.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/crt0_himem.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/crt0_ram.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/crt0_ram.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/crt0_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/crt0_ram.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,168 @@
+
+#if 1 /* enable DEBUG here */
+#define IMMED #
+#define	DBG_PUTC(x) \
+	   moveb   IMMED x, 0xfffff907; \
+	0: movew   0xfffff906, %d7; \
+	   andw    IMMED 0x2000, %d7; \
+	   beq     0b
+#else
+#defin DBG_PUTC(x)
+#endif
+
+#include <linux/config.h>
+        
+	.global _start
+	.global _stext
+
+	.global _rambase
+	.global _ramvec
+	.global _ramstart
+	.global _ramend
+	.global _data_rom_start
+
+#ifdef CONFIG_INIT_LCD
+	.global splash_bits
+#endif
+
+	.data
+
+/*
+ *	Set up the usable of RAM stuff. Size of RAM is determined then
+ *	an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long   0
+_rambase:
+.long   0
+_ramstart:
+.long   0
+_ramend:
+.long   0
+_data_rom_start:
+.long   0
+
+
+#ifdef CONFIG_INIT_LCD
+splash_bits:
+#include "bootlogo.rh"
+#endif
+        
+	.text
+_start:
+_stext:
+	movew	#0x2700,%sr
+
+	DBG_PUTC('K')
+
+#ifdef CONFIG_RELOCATE
+	DBG_PUTC('R')
+	/* Copy me to RAM */
+	moveal	#__rom_start-0x400, %a0
+	moveal	#__ram_start-0x400, %a1
+	moveal	#__data_end, %a2
+
+	/* Copy %a0 to %a1 until %a1 == %a2 */
+LD1:
+	movel	%a0@+, %d0
+	movel	%d0, %a1@+
+	cmpal	%a1, %a2
+	bne	LD1
+        
+	DBG_PUTC('J')
+
+	/* jump into the RAM copy */
+	moveal	#ram_jump, %a0
+	jmp	(%a0)
+
+ram_jump:
+
+#endif /* CONFIG_RELOCATE */
+
+
+#ifdef CONFIG_INIT_LCD
+	movel	#splash_bits, 0xfffffA00   /* LSSA */
+	moveb	#0x28,   0xfffffA05        /* LVPW */
+	movew	#0x280,  0xFFFFFa08        /* LXMAX */
+	movew	#0x1df,   0xFFFFFa0a       /* LYMAX */
+	moveb	#0,      0xfffffa29        /* LBAR */
+	moveb	#0,      0xfffffa25        /* LPXCD */
+	moveb	#0x08,   0xFFFFFa20        /* LPICF */
+	moveb	#0x01,   0xFFFFFA21        /* -ve pol */
+	moveb	#0x81,   0xfffffA27        /* LCKCON */
+	movew	#0xff00, 0xfffff412        /* LCD pins */
+#endif
+
+#ifdef CONFIG_DIRECT_IO_ACCESS
+	moveb	#0x0,   0xfffff000
+#endif
+
+	moveal	#__ramend-CONFIG_MEMORY_RESERVE*0x100000 - 0x10, %sp
+	movew	#32767, %d0  /* PLL settle wait loop */
+1:	subq	#1, %d0
+	bne	1b
+
+	DBG_PUTC('L')
+
+	/* clear bss  */
+
+	moveal	#_sbss, %a0
+	moveal	#_ebss, %a1
+        
+	/* Copy 0 to %a0 until %a0 == %a1 */
+1:
+	clrl	%a0@+
+	cmpal	%a0, %a1
+	bhi	1b
+
+	DBG_PUTC('D')
+
+	movel	#_sdata,	%d0    
+	movel	%d0,	_rambase        
+	movel	#_ebss,  %d0
+	movel	%d0,	_ramstart
+	movel	#__ramend-CONFIG_MEMORY_RESERVE*0x100000, %d0
+	movel	%d0,	_ramend
+	movel	#__ramvec,	%d0
+	movel	%d0,	_ramvec
+		
+	movel	#__data_end, %d0
+	subl	#__data_start, %d0
+	addl	#__rom_start,	%d0
+		
+	/*ALIGN 4*/
+	addl	#4,	%d0
+	andl	#4,	%d0
+		
+	movel	%d0,	_data_rom_start
+		
+#ifdef CONFIG_68328_SERIAL_UART2
+	/* Enable RXD TXD port bits to enable UART2 */
+	moveb   #0xcf,   0xfffff43b
+#endif
+
+	DBG_PUTC('M')
+        
+/*
+ *	load the current task pointer and stack
+ */
+	lea	init_task_union,%a0
+	movel	%a0, _current_task
+	lea	0x2000(%a0),%sp
+
+	DBG_PUTC('S')
+
+1:	jsr	start_kernel
+	DBG_PUTC('!')
+   	bra 1b
+
+_exit:
+	jmp	_exit
+
+	.data
+env:
+	.long	0
+	.text
+
+
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/crt0_rom.S linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/crt0_rom.S
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/crt0_rom.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/crt0_rom.S	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1 @@
+#include "crt0_fixed.S"
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,95 @@
+SECTIONS
+{
+  .romvec :
+	{
+	_flashstart = . ;
+	_romvec = . ;
+	__rom_start = . ;
+	} > romvec
+
+  .text :
+	{
+	_stext = . ;
+        	*(.text)
+	. = ALIGN(0x4) ;
+		*(.text.*)
+	. = ALIGN(0x4) ;
+		*(.exitcall.exit)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	. = ALIGN(0x4) ;
+	_etext = . ;
+	__data_rom_start = . ;
+        } > flash
+
+  .eflash :
+	{
+	_flashend = . ;
+	} > eflash
+
+  .ramvec :
+	{
+	__ram_start = . ;
+	__ramvec = . ;
+	} > ramvec
+
+  .data :
+	{
+	. = ALIGN(0x4) ;
+	_sdata = . ;
+	__data_start = . ;
+
+	. = ALIGN(0x4) ;
+		*(.rodata)
+	. = ALIGN(0x4) ;
+		*(.rodata.str1.1)
+	. = ALIGN(0x4) ;
+		*(.data)
+	. = ALIGN(0x4) ;
+		*(.data.*)	
+
+	. = ALIGN(0x4) ;
+	__setup_start = .;
+		*(.setup.init)
+	. = ALIGN(0x4) ;
+	__setup_end = .;
+
+	. = ALIGN(0x4) ;
+	__initcall_start = .;
+		*(.initcall.init)
+	. = ALIGN(0x4) ;
+	__initcall_end = .;
+
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	. = ALIGN(0x2000) ;
+
+	_edata = . ;
+        } > ram
+
+  .bss :
+        {
+	. = ALIGN(0x4) ;
+	_sbss = . ;
+		*(.bss)
+	. = ALIGN(0x4) ;
+		*(COMMON)
+	. = ALIGN(0x4) ;
+	_ebss = . ;
+	_end = . ;
+	} > ram
+
+  .eram :
+	{
+	__ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/himem.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/himem.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/himem.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/himem.ld	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,11 @@
+MEMORY 
+	{
+        romvec : ORIGIN = 0x00600000, LENGTH = 0x00000400
+        flash  : ORIGIN = 0x00600400, LENGTH = 0x00200000 - 0x00010400
+        eflash : ORIGIN = 0x007f0000, LENGTH = 0
+        ramvec : ORIGIN = 0x00000000, LENGTH = 0x00000400
+        ram    : ORIGIN = 0x00020000, LENGTH = 0x00600000 - 0x00020000
+        eram   : ORIGIN = 0x00600000, LENGTH = 0
+	}
+
+INCLUDE arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/ints.c linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/ints.c
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/ints.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/ints.c	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,361 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne <jeff@uClinux.org>
+
+ * Phil Wilshire Sept 2002 added dummy init_irq_proc call for SYSCTL
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+
+#include <asm/MC68VZ328.h>
+
+#define INTERNAL_IRQS (32)
+
+/* assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void exception3(void);
+asmlinkage void exception4(void);
+asmlinkage void exception5(void);
+asmlinkage void exception6(void);
+asmlinkage void exception7(void);
+asmlinkage void exception8(void);
+asmlinkage void exception9(void);
+asmlinkage void exception10(void);
+asmlinkage void exception11(void);
+asmlinkage void exception14(void);
+asmlinkage void exception15(void);
+asmlinkage void bad_interrupt(void);
+asmlinkage void inthandler1(void);
+asmlinkage void inthandler2(void);
+asmlinkage void inthandler3(void);
+asmlinkage void inthandler4(void);
+asmlinkage void inthandler5(void);
+asmlinkage void inthandler6(void);
+asmlinkage void inthandler7(void);
+asmlinkage void system_call(void);
+asmlinkage void trap1(void);
+asmlinkage void trap15(void);
+
+// extern void *_ramvec[];
+extern e_vector *_ramvec;
+
+/* irq node variables for the 32 (potential) on chip sources */
+static irq_node_t *int_irq_list[INTERNAL_IRQS];
+
+static int int_irq_count[INTERNAL_IRQS];
+static short int_irq_ablecount[INTERNAL_IRQS];
+
+static void int_badint(int irq, void *dev_id, struct pt_regs *fp)
+{
+	num_spurious += 1;
+}
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the amiga IRQ handling routines.
+ */
+
+void M68VZ328_init_IRQ(void)
+{
+	int i;
+
+        /* set up the vectors */
+        for (i=2; i < 32; ++i)
+                _ramvec[i] = bad_interrupt;
+
+        _ramvec[2] = buserr;
+        _ramvec[3] = exception3;
+        _ramvec[4] = exception4;
+        _ramvec[5] = exception5;
+        _ramvec[6] = exception6;
+        _ramvec[7] = exception7;
+        _ramvec[8] = exception8;
+        _ramvec[9] = exception9;
+        _ramvec[10] = exception10;
+        _ramvec[11] = exception11;
+        _ramvec[14] = exception14;
+        _ramvec[15] = exception15;
+        _ramvec[32] = system_call;
+        _ramvec[33] = trap1;
+        _ramvec[47] = trap15;
+
+        _ramvec[64] = bad_interrupt;
+        _ramvec[65] = inthandler1;
+        _ramvec[66] = inthandler2;
+        _ramvec[67] = inthandler3;
+        _ramvec[68] = inthandler4;
+        _ramvec[69] = inthandler5;
+        _ramvec[70] = inthandler6;
+        _ramvec[71] = inthandler7;
+ 
+	IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
+
+	/* initialize handlers */
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		int_irq_list[i] = NULL;
+
+		int_irq_ablecount[i] = 0;
+		int_irq_count[i] = 0;
+	}
+	/* turn off all interrupts */
+	IMR = ~0;
+}
+
+void M68VZ328_insert_irq(irq_node_t **list, irq_node_t *node)
+{
+	unsigned long flags;
+	irq_node_t *cur;
+
+	if (!node->dev_id)
+		printk("%s: Warning: dev_id of %s is zero\n",
+		       __FUNCTION__, node->devname);
+
+	save_flags(flags);
+	cli();
+
+	cur = *list;
+
+	while (cur) {
+		list = &cur->next;
+		cur = cur->next;
+	}
+
+	node->next = cur;
+	*list = node;
+
+	restore_flags(flags);
+}
+
+void M68VZ328_delete_irq(irq_node_t **list, void *dev_id)
+{
+	unsigned long flags;
+	irq_node_t *node;
+
+	save_flags(flags);
+	cli();
+
+	for (node = *list; node; list = &node->next, node = *list) {
+		if (node->dev_id == dev_id) {
+			*list = node->next;
+			/* Mark it as free. */
+			node->handler = NULL;
+			restore_flags(flags);
+			return;
+		}
+	}
+	restore_flags(flags);
+	printk ("%s: tried to remove invalid irq\n", __FUNCTION__);
+}
+
+int M68VZ328_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                         unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+	if (!int_irq_list[irq]) {
+		int_irq_list[irq] = new_irq_node();
+		int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	}
+
+	if (!(int_irq_list[irq]->flags & IRQ_FLG_STD)) {
+		if (int_irq_list[irq]->flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, int_irq_list[irq]->devname);
+			return -EBUSY;
+		}
+	}
+	int_irq_list[irq]->handler = handler;
+	int_irq_list[irq]->flags   = flags;
+	int_irq_list[irq]->dev_id  = dev_id;
+	int_irq_list[irq]->devname = devname;
+
+	/* enable in the IMR */
+	if (!int_irq_ablecount[irq])
+		*(volatile unsigned long *)0xfffff304 &= ~(1<<irq);
+
+	return 0;
+}
+
+void M68VZ328_free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_list[irq]->dev_id != dev_id)
+		printk("%s: removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, int_irq_list[irq]->devname);
+	int_irq_list[irq]->handler = int_badint;
+	int_irq_list[irq]->flags   = IRQ_FLG_STD;
+	int_irq_list[irq]->dev_id  = NULL;
+	int_irq_list[irq]->devname = NULL;
+
+	*(volatile unsigned long *)0xfffff304 |= 1<<irq;
+}
+
+/*
+ * Enable/disable a particular machine specific interrupt source.
+ * Note that this may affect other interrupts in case of a shared interrupt.
+ * This function should only be called for a _very_ short time to change some
+ * internal data, that may not be changed by the interrupt at the same time.
+ * int_(enable|disable)_irq calls may also be nested.
+ */
+
+void M68VZ328_enable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (--int_irq_ablecount[irq])
+		return;
+
+	/* enable the interrupt */
+	*(volatile unsigned long *)0xfffff304 &= ~(1<<irq);
+}
+
+void M68VZ328_disable_irq(unsigned int irq)
+{
+	if (irq >= INTERNAL_IRQS) {
+		printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (int_irq_ablecount[irq]++)
+		return;
+
+	/* disable the interrupt */
+	*(volatile unsigned long *)0xfffff304 |= 1<<irq;
+}
+
+/* The 68k family did not have a good way to determine the source
+ * of interrupts until later in the family.  The EC000 core does
+ * not provide the vector number on the stack, we vector everything
+ * into one vector and look in the blasted mask register...
+ * This code is designed to be fast, almost constant time, not clean!
+ */
+inline int M68VZ328_do_irq(int vec, struct pt_regs *fp)
+{
+	int irq;
+	int mask;
+
+	unsigned long pend = *(volatile unsigned long *)0xfffff30c;
+
+	while (pend) {
+		if (pend & 0x0000ffff) {
+			if (pend & 0x000000ff) {
+				if (pend & 0x0000000f) {
+					mask = 0x00000001;
+					irq = 0;
+				} else {
+					mask = 0x00000010;
+					irq = 4;
+				}
+			} else {
+				if (pend & 0x00000f00) {
+					mask = 0x00000100;
+					irq = 8;
+				} else {
+					mask = 0x00001000;
+					irq = 12;
+				}
+			}
+		} else {
+			if (pend & 0x00ff0000) {
+				if (pend & 0x000f0000) {
+					mask = 0x00010000;
+					irq = 16;
+				} else {
+					mask = 0x00100000;
+					irq = 20;
+				}
+			} else {
+				if (pend & 0x0f000000) {
+					mask = 0x01000000;
+					irq = 24;
+				} else {
+					mask = 0x10000000;
+					irq = 28;
+				}
+			}
+		}
+
+		while (! (mask & pend)) {
+			mask <<=1;
+			irq++;
+		}
+
+		if (int_irq_list[irq] && int_irq_list[irq]->handler) {
+			int_irq_list[irq]->handler(irq, int_irq_list[irq]->dev_id, fp);
+			int_irq_count[irq]++;
+		} else {
+			printk("unregistered interrupt %d!\nTurning it off in the IMR...\n", irq);
+			*(volatile unsigned long *)0xfffff304 |= mask;
+		}
+		pend &= ~mask;
+	}
+	return 0;
+}
+
+int M68VZ328_get_irq_list(char *buf)
+{
+	int i, len = 0;
+	irq_node_t *node;
+
+	len += sprintf(buf+len, "Internal 68VZ328 interrupts\n");
+
+	for (i = 0; i < INTERNAL_IRQS; i++) {
+		if (!(node = int_irq_list[i]))
+			continue;
+		if (!(node->handler))
+			continue;
+
+		len += sprintf(buf+len, " %2d: %10u    %s\n", i,
+		               int_irq_count[i], int_irq_list[i]->devname);
+	}
+	return len;
+}
+
+void config_M68VZ328_irq(void)
+{
+	mach_default_handler = NULL;
+	mach_init_IRQ        = M68VZ328_init_IRQ;
+	mach_request_irq     = M68VZ328_request_irq;
+	mach_free_irq        = M68VZ328_free_irq;
+	mach_enable_irq      = M68VZ328_enable_irq;
+	mach_disable_irq     = M68VZ328_disable_irq;
+	mach_get_irq_list    = M68VZ328_get_irq_list;
+	mach_process_int     = M68VZ328_do_irq;
+}
+
+/* PSW dummy call to allow SYSCTL kernel option to be enabled */
+void init_irq_proc(void)
+{
+        /* Insert /proc/irq driver here */
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/ram.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/ram.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/ram.ld	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,117 @@
+MEMORY 
+	{
+	romvec : ORIGIN = 0x10c10000, LENGTH = 0x00000400
+	flash  : ORIGIN = 0x10c10400, LENGTH = 0x00200000 - 0x00010400
+	eflash : ORIGIN = 0x10e00000, LENGTH = 0
+	ramvec : ORIGIN = 0x00000000, LENGTH = 0x00000400
+	bvec   : ORIGIN = 0x00020000, LENGTH = 0x00000400
+	ram    : ORIGIN = 0x00020400, LENGTH = 0x00800000 - 0x00020400
+	eram   : ORIGIN = 0x00800000, LENGTH = 0
+	}
+
+
+SECTIONS
+{
+  .flashvec :
+	{
+	_flashstart = . ;
+	__rom_start = . ;
+	} > romvec
+
+
+	.eflash :
+	{
+	_flashend = . ;
+	} > eflash
+
+  .ramvec :
+	{
+	__ramvec = . ;
+	} > ramvec
+
+	.romvec :
+	{
+	_romvec = . ;
+	} > bvec
+
+        .text :
+	{
+	__ram_start = . ;
+	_stext = . ;
+		*(.text)
+	. = ALIGN(0x4) ;
+		*(.text.*)
+	. = ALIGN(0x4) ;
+		*(.exitcall.exit)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	. = ALIGN(0x4) ;
+	_etext = . ;
+        } > ram
+
+        .data :
+	{
+	. = ALIGN(0x4) ;
+	__data_rom_start = . ;
+	_sdata = . ;
+	__data_start = . ;
+
+	. = ALIGN(0x4) ;
+		*(.rodata)
+	. = ALIGN(0x4) ;
+		*(.rodata.str1.1)
+	. = ALIGN(0x4) ;
+        *(.data)
+	. = ALIGN(0x4) ;
+        *(.data.*)      
+
+	. = ALIGN(0x4) ;
+        __setup_start = .;
+        *(.setup.init)
+	. = ALIGN(0x4) ;
+        __setup_end = .;
+
+	. = ALIGN(0x4) ;
+        __initcall_start = .;
+        *(.initcall.init)
+	. = ALIGN(0x4) ;
+        __initcall_end = .;
+
+	. = ALIGN(0x2000) ;
+		*(.data.init_task)
+	. = ALIGN(0x2000) ;
+
+	_edata = . ;
+        } > ram
+
+        .bss :
+        {
+	. = ALIGN(0x4) ;
+	_sbss = . ;
+	*(.bss)
+	. = ALIGN(0x4) ;
+	*(COMMON)
+	. = ALIGN(0x4) ;
+	_ebss = . ;
+	_end = . ;
+	} > ram
+
+  .fs :
+	{
+		__romfs_start = . ;
+	} > ram
+
+	.eram :
+	{
+	__ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/rom.ld linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/rom.ld
--- linux-2.4.29/arch/m68knommu/platform/68VZ328/ucdimm/rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/m68knommu/platform/68VZ328/ucdimm/rom.ld	2005-06-14 02:11:16.000000000 +0100
@@ -0,0 +1,11 @@
+MEMORY 
+	{
+        romvec : ORIGIN = 0x10c10000, LENGTH = 0x00000400
+        flash  : ORIGIN = 0x10c10400, LENGTH = 0x001fec00
+        eflash : ORIGIN = 0x10d00000, LENGTH = 0
+        ramvec : ORIGIN = 0x00000000, LENGTH = 1024
+        ram    : ORIGIN = 0x00020000, LENGTH = 0x00800000 - 0x00020000
+        eram   : ORIGIN = 0x00800000, LENGTH = 0
+	}
+
+INCLUDE arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld
diff -urN linux-2.4.29/arch/microblaze/Boards.mk linux-2.4.29-uc1/arch/microblaze/Boards.mk
--- linux-2.4.29/arch/microblaze/Boards.mk	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/Boards.mk	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,17 @@
+# Put definitions for platforms and boards in here.
+# Microblaze uses PLATFORM, not BOARD
+
+# old targets (mbvanilla, suzaku) must not define PLATFORM
+ifdef CONFIG_MBVANILLA
+endif
+
+ifdef CONFIG_SUZAKU
+PLATFORM := suzaku
+endif
+
+# new targets must define platform
+ifdef CONFIG_UCLINUX_AUTO
+PLATFORM := uclinux-auto
+endif
+
+export PLATFORM
diff -urN linux-2.4.29/arch/microblaze/boot/Makefile linux-2.4.29-uc1/arch/microblaze/boot/Makefile
--- linux-2.4.29/arch/microblaze/boot/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/boot/Makefile	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,7 @@
+
+clean:
+
+archclean:
+
+
+
diff -urN linux-2.4.29/arch/microblaze/config.in linux-2.4.29-uc1/arch/microblaze/config.in
--- linux-2.4.29/arch/microblaze/config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/config.in	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,318 @@
+#############################################################################
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+#
+# based mainly on the arch/i386/config.in and bit of the 2.0, m68knommu
+# config.in
+#
+#############################################################################
+
+mainmenu_name 'uClinux/Microblaze (w/o MMU) Kernel Configuration'
+
+define_bool CONFIG_UCLINUX y
+define_bool CONFIG_UID16 y
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+
+# Turn off some random 386 crap that can affect device config
+define_bool CONFIG_ISA n
+define_bool CONFIG_ISAPNP n
+define_bool CONFIG_EISA n
+define_bool CONFIG_MCA n
+
+
+#############################################################################
+
+mainmenu_option next_comment
+  comment 'Code maturity level options'
+  bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+mainmenu_option next_comment
+  comment 'Loadable module support'
+  bool 'Enable loadable module support' CONFIG_MODULES
+  if [ "$CONFIG_MODULES" = "y" ]; then
+     bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+     bool '  Kernel module loader' CONFIG_KMOD
+  fi
+endmenu
+
+
+#############################################################################
+#### Microblaze-specific config
+
+# Define the architecture
+define_bool CONFIG_MICROBLAZE y
+
+mainmenu_option next_comment
+
+  comment 'Processor type and features'
+
+  #### Microblaze processor-specific config
+
+comment 'Platform'
+  choice 'Platform'						\
+       "uclinux-auto		CONFIG_UCLINUX_AUTO             \
+        MBVanilla		CONFIG_MBVANILLA 		\
+	Egretv0.1		CONFIG_EGRET01			\
+	SUZAKU			CONFIG_SUZAKU"		uclinux-auto
+
+
+
+  ## Are we using the uclinux-auto platform?  If so, just grab 
+  ## the params we need
+  if [ "$CONFIG_UCLINUX_AUTO" = "y" ]; then
+     define_int HZ 100
+     source arch/microblaze/platform/uclinux-auto/auto-config.in
+  fi
+  if [ "$CONFIG_SUZAKU" = "y" ]; then
+     source arch/microblaze/platform/suzaku/auto-config.in
+  fi
+  if [ "$CONFIG_MBVANILLA" = "y" -o \
+       "$CONFIG_EGRET01"   = "y" ]; then
+
+     #bool 'Reset Guard' 		CONFIG_RESET_GUARD
+     int 'CPU CLOCK Frequency' CONFIG_CPU_CLOCK_FREQ 66000000
+     bool 'Use msrset/msrclr insns' CONFIG_MICROBLAZE_MSRSETCLR
+     bool 'Hardware Multiplier'    CONFIG_MICROBLAZE_HARD_MULT
+     bool 'Hardware Divider'       CONFIG_MICROBLAZE_HARD_DIV
+     bool 'Hardware Barrel Shift'  CONFIG_MICROBLAZE_HARD_BARREL
+     bool 'Instruction Cache' 	CONFIG_MICROBLAZE_ICACHE
+     if [ "$CONFIG_MICROBLAZE_ICACHE" = "y" ]; then
+        hex '  Instruction cache address base' 	CONFIG_MICROBLAZE_ICACHE_BASE 0x80000000
+        hex '  Instruction cache byte size'	CONFIG_MICROBLAZE_ICACHE_SIZE 0x8000
+     fi
+     bool 'Data Cache' 		CONFIG_MICROBLAZE_DCACHE
+     if [ "$CONFIG_MICROBLAZE_DCACHE" = "y" ]; then
+        hex '  Data cache address base' 	CONFIG_MICROBLAZE_DCACHE_BASE 0x80000000
+        hex '  Data cache byte size' 	CONFIG_MICROBLAZE_DCACHE_SIZE 0x8000
+     fi
+     define_bool CONFIG_MICROBLAZE_DEBUG_UART y
+  fi
+
+  tristate 'GPIO driver'		CONFIG_XILINX_GPIO
+  tristate 'Ethernet driver'	CONFIG_XILINX_ENET
+  tristate 'SystemAce driver'       CONFIG_XILINX_SYSACE
+  bool 'Kernel cmdline support (needs new bootloader)'	CONFIG_MBVANILLA_CMDLINE
+
+  # Default some stuff
+  if [ "$CONFIG_ZERO_BSS" != "n" ]; then
+    define_bool CONFIG_ZERO_BSS y
+  fi
+
+comment 'Debug Logging'
+	bool 'Enable debug logging' CONFIG_MICROBLAZE_DEBUGGING
+
+endmenu
+
+
+#############################################################################
+
+mainmenu_option next_comment
+  comment 'General setup'
+
+  bool 'Networking support' CONFIG_NET
+
+  # Embedded systems often won't need any hardware disk support, so only clutter
+  # up the menus with it if really necessary
+  bool 'Disk hardware support' CONFIG_DISK
+
+  source drivers/pci/Config.in
+
+  # if [ "$CONFIG_VISWS" != "y" ]; then
+  #    bool 'MCA support' CONFIG_MCA
+  # fi
+
+  bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+
+  if [ "$CONFIG_HOTPLUG" = "y" ] ; then
+     source drivers/pcmcia/Config.in
+  else
+     define_bool CONFIG_PCMCIA n
+  fi
+
+  bool 'System V IPC' CONFIG_SYSVIPC
+  bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+  bool 'Sysctl support' CONFIG_SYSCTL
+  if [ "$CONFIG_PROC_FS" = "y" ]; then
+     choice 'Kernel core (/proc/kcore) format' \
+	  "ELF		CONFIG_KCORE_ELF	\
+	   A.OUT		CONFIG_KCORE_AOUT" ELF
+  fi
+  tristate 'Kernel support for flat binaries' CONFIG_BINFMT_FLAT
+  dep_bool '  Enable ZFLAT support' CONFIG_BINFMT_ZFLAT $CONFIG_BINFMT_FLAT
+  #tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
+  #tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+  #tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+
+  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+     bool 'Non power-of-2 kernel allocator (EXPERIMENTAL)' CONFIG_CONTIGUOUS_PAGE_ALLOC
+     dep_bool '  include /proc/mem_map' CONFIG_MEM_MAP $CONFIG_CONTIGUOUS_PAGE_ALLOC
+  fi
+
+  if [ "$CONFIG_CONTIGUOUS_PAGE_ALLOC" != "y" ]; then
+    bool 'Allow allocating large blocks (> 1MB) of memory' CONFIG_NO_MMU_LARGE_ALLOCS
+  fi
+
+endmenu
+
+#############################################################################
+
+source drivers/mtd/Config.in
+
+if [ "$CONFIG_PCI" != "n" ]; then
+  source drivers/parport/Config.in
+fi
+
+#source drivers/pnp/Config.in
+
+source drivers/block/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   source net/Config.in
+fi
+
+#source drivers/telephony/Config.in
+
+#############################################################################
+
+if [ "$CONFIG_DISK" = "y" ]; then
+  mainmenu_option next_comment
+    comment 'ATA/IDE/MFM/RLL support'
+
+    tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+
+    if [ "$CONFIG_IDE" != "n" ]; then
+      source drivers/ide/Config.in
+    else
+      define_bool CONFIG_BLK_DEV_HD n
+    fi
+  endmenu
+fi
+
+#############################################################################
+
+if [ "$CONFIG_DISK" = "y" ]; then
+  mainmenu_option next_comment
+    comment 'SCSI support'
+
+    tristate 'SCSI support' CONFIG_SCSI
+
+    if [ "$CONFIG_SCSI" != "n" ]; then
+       source drivers/scsi/Config.in
+    fi
+  endmenu
+fi
+
+#############################################################################
+
+if [ "$CONFIG_PCI" = "y" ]; then
+  source drivers/ieee1394/Config.in
+fi
+
+if [ "$CONFIG_NET" = "y" ]; then
+   mainmenu_option next_comment
+     comment 'Network device support'
+
+     bool 'Network device support' CONFIG_NETDEVICES
+     if [ "$CONFIG_NETDEVICES" = "y" ]; then
+	source drivers/net/Config.in
+	if [ "$CONFIG_ATM" = "y" ]; then
+	   source drivers/atm/Config.in
+	fi
+     fi
+   endmenu
+fi
+
+if [ "$CONFIG_NET" = "y" ]; then
+  source net/ax25/Config.in
+fi
+
+source net/irda/Config.in
+
+#############################################################################
+
+if [ "$CONFIG_NET" = "y" ]; then
+  mainmenu_option next_comment
+    comment 'ISDN subsystem'
+
+    tristate 'ISDN support' CONFIG_ISDN
+    if [ "$CONFIG_ISDN" != "n" ]; then
+      source drivers/isdn/Config.in
+    fi
+  endmenu
+fi
+
+#############################################################################
+
+# mainmenu_option next_comment
+#   comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+#
+#   bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+#   if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+#      source drivers/cdrom/Config.in
+#   fi
+# endmenu
+
+#############################################################################
+
+source drivers/char/Config.in
+
+source drivers/misc/Config.in
+
+source fs/Config.in
+
+if [ "$CONFIG_VT" = "y" ]; then
+   mainmenu_option next_comment
+     comment 'Console drivers'
+     bool 'VGA text console' CONFIG_VGA_CONSOLE
+     bool 'Video mode selection support' CONFIG_VIDEO_SELECT
+     if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
+	source drivers/video/Config.in
+     fi
+   endmenu
+fi
+
+#############################################################################
+
+mainmenu_option next_comment
+  comment 'Sound'
+
+  tristate 'Sound card support' CONFIG_SOUND
+  if [ "$CONFIG_SOUND" != "n" ]; then
+     source drivers/sound/Config.in
+  fi
+endmenu
+
+#############################################################################
+
+source drivers/usb/Config.in
+
+#############################################################################
+
+mainmenu_option next_comment
+  comment 'Kernel hacking'
+
+  bool 'Full Symbolic/Source Debugging support' CONFIG_FULLDEBUG
+  #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
+  bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+
+  bool 'Kernel profiling support' CONFIG_PROFILE
+  if [ "$CONFIG_PROFILE" = "y" ]; then
+    int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+    bool 'Use fast second timer for profiling' CONFIG_HIGHPROFILE
+  fi
+
+  bool 'Suppress Kernel BUG Messages' CONFIG_NO_KERNEL_MSG
+
+endmenu
+
+
+#############################################################################
+
+source crypto/Config.in
+source lib/Config.in
+
+#############################################################################
diff -urN linux-2.4.29/arch/microblaze/kernel/bug.c linux-2.4.29-uc1/arch/microblaze/kernel/bug.c
--- linux-2.4.29/arch/microblaze/kernel/bug.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/bug.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,68 @@
+/*
+ * arch/v850/kernel/bug.c -- Bug reporting functions
+ *
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/sched.h>
+
+#include <asm/errno.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+
+void __bug (const char *file, int line, void *data)
+{
+	if (data)
+		printk (KERN_CRIT "kernel BUG at %s:%d (data = %p)!\n",
+			file, line, data);
+	else
+		printk (KERN_CRIT "kernel BUG at %s:%d!\n", file, line);
+
+	machine_halt ();
+}
+
+int bad_trap (int trap_num, struct pt_regs *regs)
+{
+	printk (KERN_CRIT
+		"unimplemented trap %d called at 0x%08lx, pid %d!\n",
+		trap_num, regs->pc, current->pid);
+	return -ENOSYS;
+}
+
+int debug_trap (struct pt_regs *regs)
+{
+	int i;
+	printk (KERN_CRIT "debug trap\n");
+        for(i=0;i<32;i++)
+	{
+		printk("r%i:%08X\t",i,regs->gpr[i]);
+		if((i%4)==3)
+			printk("\n");
+	}
+	printk("pc:%08X\tpsw:%08X\n",regs->pc, regs->psw);
+	return -ENOSYS;
+}
+
+#ifdef CONFIG_RESET_GUARD
+void unexpected_reset (unsigned long ret_addr, unsigned long kmode,
+		       struct task_struct *task, unsigned long sp)
+{
+	printk (KERN_CRIT
+		"unexpected reset in %s mode, pid %d"
+		" (ret_addr = 0x%lx, sp = 0x%lx)\n",
+		kmode ? "kernel" : "user",
+		task ? task->pid : -1,
+		ret_addr, sp);
+
+	machine_halt ();
+}
+#endif /* CONFIG_RESET_GUARD */
diff -urN linux-2.4.29/arch/microblaze/kernel/crtinit.S linux-2.4.29-uc1/arch/microblaze/kernel/crtinit.S
--- linux-2.4.29/arch/microblaze/kernel/crtinit.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/crtinit.S	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,73 @@
+###################################-*-asm*- 
+# 
+# Copyright (c) 2001 Xilinx, Inc.  All rights reserved. 
+# 
+# Xilinx, Inc. CONFIDENTIAL 
+#
+# XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A 
+# COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+# ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR 
+# STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
+# IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE 
+# FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.  
+# XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO 
+# THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO 
+# ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE 
+# FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY 
+# AND FITNESS FOR A PARTICULAR PURPOSE.
+# 
+# crtinit.s 
+# 
+#	C RunTime:
+#	Used for initialization of user's bss area
+#	All external and static variables are initialized 
+# 
+#######################################
+
+	.globl _crtinit
+	.align 2
+	.ent _crtinit
+
+_crtinit:
+	/* Save Link register	 */
+	addi	r1,r1,-4
+	sw	r15,r1,r0
+
+	/* clear sbss */
+	addi	r6,r0,__sbss_start      /* SBSS beginning	*/
+	addi	r7,r0,__sbss_end	/* SBSS end		*/
+	rsub	r18,r6,r7		/* Compare		*/
+	blei	r18,.Lendsbss
+
+.Lloopsbss:	
+	sw	r0,r6,r0
+	addi	r6,r6,4
+	rsub	r18,r6,r7
+	bgti	r18,.Lloopsbss
+.Lendsbss:
+
+	/* clear bss */
+	addi	r6,r0,__bss_start      /* BSS beginning		*/
+	addi	r7,r0,__bss_end		/* BSS end		*/
+
+	rsub	r18,r6,r7		/* Compare		*/
+	blei	r18,.Lendbss
+.Lloopbss:	
+	sw	r0,r6,r0
+	addi	r6,r6,4
+	rsub	r18,r6,r7
+	bgti	r18,.Lloopbss
+.Lendbss:
+
+/* 	Call the init function here 			  */
+	brlid	r15,_program_init
+	nop
+
+/* 	Restore r15 					*/
+	lw	r15,r1,r0
+	addi	r1,r1,4
+
+	rtsd	r15,8
+	nop
+	.end _crtinit
+
diff -urN linux-2.4.29/arch/microblaze/kernel/entry.S linux-2.4.29-uc1/arch/microblaze/kernel/entry.S
--- linux-2.4.29/arch/microblaze/kernel/entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/entry.S	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,1203 @@
+/*
+ * arch/microblaze/kernel/entry.S -- Low-level system-call handling, trap handlers,
+ *	and context-switching
+ *
+ *  Copyright (C) 2003	     John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Heavily modified by John Williams for Microblaze
+ */
+
+#include <linux/sys.h>
+
+#include <asm/entry.h>
+#include <asm/clinkage.h>
+#include <asm/current.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+
+#include "microblaze_defs.h"
+
+
+/* Make a slightly more convenient alias for C_SYMBOL_NAME.  */
+#define CSYM	C_SYMBOL_NAME
+
+/* The offset of the struct pt_regs in a `state save frame' on the stack.  */
+#define PTO	STATE_SAVE_PT_OFFSET
+
+/* Standard way of enabling and disabling interrupts in entry.S */
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+#define ENTRY_CLI(scratch_reg)                                                \
+	msrclr scratch_reg, 0x2;					      \
+	nop;
+
+#define ENTRY_EI(scratch_reg)                                                 \
+	msrset scratch_reg, 0x2;					      \
+	nop;
+
+#else
+
+#define ENTRY_CLI(scratch_reg)                                                \
+        mfs     scratch_reg, rmsr;                                            \
+        andi    scratch_reg, scratch_reg, ~2;                                 \
+        mts     rmsr, scratch_reg;					      \
+	nop;
+
+#define ENTRY_EI(scratch_reg)                                                 \
+	mfs     scratch_reg, rmsr;                                            \
+	ori     scratch_reg, scratch_reg, 2;                                  \
+	mts     rmsr, scratch_reg;					      \
+	nop;
+#endif
+
+/* Various ways of setting and clearing BIP in flags reg.  This is mucky, but
+   necessary */
+//#ifdef CONFIG_MICROBLAZE_BIPDIRECT
+#if 1
+  /* using microblaze version that allows msr ops to write to BIP */
+  #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+	#define BIPCLR(scratch_reg)					      \
+		msrclr 	scratch_reg, 0x8;				      \
+		nop;
+
+	#define BIPSET(scratch_reg)					      \
+		msrset	scratch_reg, 0x8;				      \
+		nop;
+  #else
+	#define BIPCLR(scratch_reg)					      \
+		mfs	scratch_reg, rmsr;				      \
+		andi	scratch_reg, scratch_reg, ~0x8;			      \
+		mts	rmsr, scratch_reg;				      \
+		nop;
+
+	#define BIPSET(scratch_reg)					      \
+		mfs	scratch_reg, rmsr;				      \
+		ori	scratch_reg, scratch_reg, 0x8;			      \
+		mts	rmsr, scratch_reg;				      \
+		nop;
+  #endif
+#else
+  /* Older microblaze version that prevents direct access to BIP bit 
+     We hack around it using the rtbd and brki instructions */
+	#define BIPCLR(scratch_reg)					      \
+		rtbd	r0, 1f;						      \
+		nop;							      \
+	   1:
+
+	#define BIPSET(scratch_reg)					      \
+		brki	r0, 1f;						      \
+	   1:
+#endif
+	
+/* Standard macros to save and restore regs in the pt_regs struct pointed
+   to by the stack pointer (r1) */
+#define SAVE_REG(reg_num) \
+	swi	macrology_paste(r,reg_num), r1, PTO+PT_GPR(reg_num);
+
+#define RESTORE_REG(reg_num) \
+	lwi	macrology_paste(r,reg_num), r1, PTO+PT_GPR(reg_num);
+
+/* Save argument registers to the struct pt_regs pointed to by EP.  */
+#define SAVE_ARG_REGS							      \
+	SAVE_REG(5);							      \
+	SAVE_REG(6);							      \
+	SAVE_REG(7);							      \
+	SAVE_REG(8);							      \
+	SAVE_REG(9);							      \
+	SAVE_REG(10);	
+
+/* Restore argument registers from the struct pt_regs pointed to by EP.  */
+#define RESTORE_ARG_REGS						      \
+	RESTORE_REG(5);							      \
+	RESTORE_REG(6);							      \
+	RESTORE_REG(7);							      \
+	RESTORE_REG(8);							      \
+	RESTORE_REG(9);							      \
+	RESTORE_REG(10);
+
+/* Save value return registers to the struct pt_regs pointed to by EP.  */
+#define SAVE_RVAL_REGS							      \
+	SAVE_REG(3);							      \
+	SAVE_REG(4);							      
+
+/* Restore value return registers from the struct pt_regs pointed to by EP.  */
+#define RESTORE_RVAL_REGS						      \
+	RESTORE_REG(3);							      \
+	RESTORE_REG(4);	
+
+#define SAVE_CALL_CLOBBERED_REGS_BEFORE_ARGS
+
+#define SAVE_CALL_CLOBBERED_REGS_AFTER_RVAL				      \
+	SAVE_REG(11);							      \
+	SAVE_REG(12);							      
+
+#define RESTORE_CALL_CLOBBERED_REGS_BEFORE_ARGS	
+
+#define RESTORE_CALL_CLOBBERED_REGS_AFTER_RVAL				      \
+	RESTORE_REG(11);						      \
+	RESTORE_REG(12);						      
+
+/* Save `call clobbered' registers to the struct pt_regs pointed to by EP.  */
+#define SAVE_CALL_CLOBBERED_REGS					      \
+	SAVE_CALL_CLOBBERED_REGS_BEFORE_ARGS;				      \
+	SAVE_RVAL_REGS;							      \
+	SAVE_ARG_REGS;							      \
+	SAVE_CALL_CLOBBERED_REGS_AFTER_RVAL;
+/* Restore `call clobbered' registers from the struct pt_regs pointed to
+   by EP.  */
+#define RESTORE_CALL_CLOBBERED_REGS					      \
+	RESTORE_CALL_CLOBBERED_REGS_BEFORE_ARGS;			      \
+	RESTORE_RVAL_REGS;						      \
+	RESTORE_ARG_REGS;						      \
+	RESTORE_CALL_CLOBBERED_REGS_AFTER_RVAL;
+
+/* Save `call clobbered' registers except for the return-value registers
+   to the struct pt_regs pointed to by EP.  */
+#define SAVE_CALL_CLOBBERED_REGS_NO_RVAL				      \
+	SAVE_CALL_CLOBBERED_REGS_BEFORE_ARGS;				      \
+	SAVE_ARG_REGS;							      \
+	SAVE_CALL_CLOBBERED_REGS_AFTER_RVAL;
+/* Restore `call clobbered' registers except for the return-value registers
+   from the struct pt_regs pointed to by EP.  */
+#define RESTORE_CALL_CLOBBERED_REGS_NO_RVAL				      \
+	RESTORE_CALL_CLOBBERED_REGS_BEFORE_ARGS;			      \
+	RESTORE_ARG_REGS;						      \
+	RESTORE_CALL_CLOBBERED_REGS_AFTER_RVAL;
+
+#define ZERO_REG(reg_num)						      \
+	add	r ## reg_num, r0, r0;
+
+/* Zero `call clobbered' registers except for the return-value registers.  */
+#define ZERO_CALL_CLOBBERED_REGS_NO_RVAL				      \
+	ZERO_REG(11); ZERO_REG(12);			      
+
+/* Save `call saved' registers to the struct pt_regs pointed to by EP.  */
+#define SAVE_CALL_SAVED_REGS						      \
+	SAVE_REG(19);							      \
+	SAVE_REG(20);							      \
+	SAVE_REG(21);							      \
+	SAVE_REG(22);							      \
+	SAVE_REG(23);							      \
+	SAVE_REG(24);							      \
+	SAVE_REG(25);							      \
+	SAVE_REG(26);							      \
+	SAVE_REG(27);							      \
+	SAVE_REG(28);							      \
+	SAVE_REG(29);							      \
+	SAVE_REG(30);							      \
+ 	SAVE_REG(31);
+
+/* Restore `call saved' registers from the struct pt_regs pointed to by EP.  */
+#define RESTORE_CALL_SAVED_REGS						      \
+	RESTORE_REG(19);						      \
+	RESTORE_REG(20);						      \
+	RESTORE_REG(21);						      \
+	RESTORE_REG(22);						      \
+	RESTORE_REG(23);						      \
+	RESTORE_REG(24);						      \
+	RESTORE_REG(25);						      \
+	RESTORE_REG(26);						      \
+	RESTORE_REG(27);						      \
+	RESTORE_REG(28);						      \
+	RESTORE_REG(29);						      \
+	RESTORE_REG(30);						      \
+	RESTORE_REG(31);
+
+/* Save system registers to the struct pt_regs pointed to by REG.  
+   r11 is clobbered.  */
+#define SAVE_SYS_REGS_FOR_IRQ						      \
+	SAVE_REG(17); \
+	swi	r14, r1, PTO+PT_PC;	/* user's PC, before interrupt */     \
+	mfs	r11, rmsr;	/* & PSW (XXX save this?) */		      \
+	swi	r11, r1, PTO+PT_PSW;	
+
+/* Restore system registers from the struct pt_regs pointed to by EP.         
+   clobber r14 to restore status register, it gets fixed immediately */    
+#define RESTORE_SYS_REGS_FOR_IRQ					      \
+	RESTORE_REG(17); 						      \
+	lwi	r11, r1, PTO+PT_PSW;	/* Processor status word */	      \
+	andi	r11, r11, ~2;		/* Don't re-enable intrs yet */	      \
+	mts	rmsr, r11;						      \
+	lwi	r14, r1, PTO+PT_PC;	/* User's PC before interrupt */      
+
+/* Save system registers to the struct pt_regs pointed to by REG.  
+   r11 is clobbered.  */
+#define SAVE_SYS_REGS_FOR_TRAP						      \
+	SAVE_REG(17); 							      \
+	swi	r14, r1, PTO+PT_PC;	/* user's PC, before trap*/	      \
+	mfs	r11, rmsr;	/* & PSW (XXX save this?) */		      \
+	ori	r11, r11, 0x2;		/* Ensure ints enabled on exit */     \
+	swi	r11, r1, PTO+PT_PSW;	
+
+/* Restore system registers from the struct pt_regs pointed to by EP.         
+   clobber r11 to restore status register */
+#define RESTORE_SYS_REGS_FOR_TRAP					      \
+	RESTORE_REG(17);						      \
+	lwi	r11, r1, PTO+PT_PSW;	/* Processor status word */	      \
+	mts	rmsr, r11;						      \
+	lwi	r14, r1, PTO+PT_PC;	/* User's PC before trap */      
+
+/* Save system registers to the struct pt_regs pointed to by REG.  
+   r11 is clobbered.  */
+#define SAVE_SYS_REGS_FOR_DBTRAP					      \
+	swi	r14, r1, PTO+PT_PC;	/* user's PC, before trap*/	      \
+	mfs	r11, rmsr;		/* & PSW (XXX save this?) */	      \
+	swi	r11, r1, PTO+PT_PSW;	
+
+/* Restore system registers from the struct pt_regs pointed to by EP.         
+   clobber r11 to restore status register */
+#define RESTORE_SYS_REGS_FOR_DBTRAP					      \
+	lwi	r11, r1, PTO+PT_PSW;	/* Processor status word */	      \
+	mts	rmsr, r11;						      \
+	lwi	r14, r1, PTO+PT_PC;	/* User's PC before trap */      
+
+/* Save system registers to the struct pt_regs pointed to by REG.  This is a
+   NMI-specific version, because NMIs save the PC/PSW in a different place
+   than other interrupt requests.  r11 is clobbered.  */
+#define SAVE_SYS_REGS_FOR_NMI						      \
+	swi	r16, r1, PTO+PT_PC;	/* user's PC, before NMI */	      \
+	mfs	r11, rmsr;						      \
+	swi	r11, r1, PTO+PT_PSW;
+
+/* Restore system registers from the struct pt_regs pointed to by EP.  This is
+   a NMI-specific version, because NMIs save the PC/PSW in a different place
+   than other interrupt requests.  r11 is clobbered (it is used as a scratch
+   register because the POP_STATE macro restores it, and this macro is usually
+   used inside POP_STATE).  */
+#define RESTORE_SYS_REGS_FOR_NMI					      \
+	lwi	r11, r1, PTO+PT_PSW;					      \
+	mts	rmsr, r11;						      \
+	lwi	r14, r1, PTO+PT_PC;	/* User's PC before NMI */
+
+/* Push register state, except for the stack pointer, on the stack in the form
+   of a struct pt_regs, in preparation for a system call.  This macro makes
+   sure that `special' registers, system registers; TYPE identifies the set of
+   extra registers to be saved as well.  EP is clobbered.  
+   Uses add(i)k to prevent corrupting carry flags prior to them being saved */
+#ifdef CONFIG_REGISTER_TASK_PTR						      
+#define PUSH_STATE(type)						      \
+	addik	r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack.  */      \
+	SAVE_REG(2);				/* Save SDA */		      \
+	SAVE_REG(13);				/* Save SDA2 */		      \
+	SAVE_REG(15);				/* Save LP */		      \
+	SAVE_REG(18);				/* Save asm scratch reg */    \
+	SAVE_REG(CURRENT_TASK_REGNUM);		/* Save current task reg */   \
+	type ## _STATE_SAVER;
+#else
+#define PUSH_STATE(type)						      \
+	addik	r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack.  */      \
+	SAVE_REG(2);				/* Save SDA */		      \
+	SAVE_REG(13);				/* Save SDA2 */		      \
+	SAVE_REG(15);				/* Save LP */		      \
+	SAVE_REG(18);				/* Save asm scratch reg */    \
+	type ## _STATE_SAVER;
+#endif									      
+
+/* Pop a register state, except for the stack pointer, from the struct pt_regs
+   on the stack.  */
+#ifdef CONFIG_REGISTER_TASK_PTR						      
+#define POP_STATE(type)							      \
+	type ## _STATE_RESTORER;					      \
+	RESTORE_REG(2);				/* Restore SDA */	      \
+	RESTORE_REG(13);			/* Restore SDA2 */	      \
+	RESTORE_REG(15);			/* Restore LP */	      \
+	RESTORE_REG(18);			/* Restore asm scratch reg */ \
+	RESTORE_REG(CURRENT_TASK_REGNUM);	/* Restore cur task reg */    \
+	addik	r1, r1, STATE_SAVE_SIZE		/* Clean up stack space.  */
+#else
+#define POP_STATE(type)							      \
+	type ## _STATE_RESTORER;					      \
+	RESTORE_REG(2);				/* Restore SDA */	      \
+	RESTORE_REG(13);			/* Restore SDA2 */	      \
+	RESTORE_REG(15);			/* Restore LP */	      \
+	RESTORE_REG(18);			/* Restore asm scratch reg */ \
+	addik	r1, r1, STATE_SAVE_SIZE		/* Clean up stack space.  */
+#endif
+
+
+/* Switch to the kernel stack if necessary, and push register state on
+   the stack in the form of a struct pt_regs.  Also load the current
+   task pointer if switching from user mode.  The stack-pointer (r3)
+   should have already been saved to the memory location SP_SAVE_LOC
+   (the reason for this is that the interrupt vectors may be beyond a
+   22-bit signed offset jump from the actual interrupt handler, and this
+   allows them to save the stack-pointer and use that register to do an
+   indirect jump).  This macro makes sure that `special' registers,
+   system registers, and the stack pointer are saved; TYPE identifies
+   the set of extra registers to be saved as well.  SYSCALL_NUM is the
+   register in which the system-call number this state is for is stored
+   (r0 if this isn't a system call).  Interrupts should already be
+   disabled when calling this.  */
+#define SAVE_STATE(type, syscall_num, sp_save_loc)			      \
+	swi	r11, r0, R11_SAVE;	/* Save r11 */			      \
+        lwi	r11, r0, KM;		/* See if already in kernel mode.  */ \
+	beqi	r11, 1f;		/* Jump ahead if coming from user */  \
+	lwi	r11, r0, R11_SAVE;	/* restore r11 */		      \
+        /* Kernel-mode state save.  */					      \
+	lwi	r1, r0, sp_save_loc;	/* Reload kernel stack-pointer.  */   \
+	swi	r1, r1, (PT_GPR(GPR_SP)-PT_SIZE); /* Save original SP. */     \
+        PUSH_STATE(type);						      \
+	addi	r11, r0, 1; 		/* Was in kernel-mode.  */	      \
+        swi	r11, r1, PTO+PT_KERNEL_MODE; 	 			      \
+        brid	2f;							      \
+	nop;				/* Fill delay slot */		      \
+1:      /* User-mode state save.  */					      \
+	lwi	r11, r0, R11_SAVE;	/* restore r11 */		      \
+        lwi	r1, r0, KSP;		/* Switch to kernel stack.  */	      \
+        PUSH_STATE(type);						      \
+	swi	r0, r1, PTO+PT_KERNEL_MODE; /* Was in user-mode.  */	      \
+	lwi	r11, r0, sp_save_loc;					      \
+	swi	r11, r1, PTO+PT_GPR(GPR_SP); /* Store user SP.  */	      \
+	addi	r11, r0, 1;						      \
+	swi	r11, r0, KM;		/* Now we're in kernel-mode.  */      \
+	GET_CURRENT_TASK(CURRENT_TASK);	/* Update the current task pointer.*/ \
+2:      /* Save away the syscall number.  */				      \
+        swi	syscall_num, r1, PTO+PT_SYSCALL
+
+
+/* Save register state not normally saved by PUSH_STATE for TYPE.  */
+#define SAVE_EXTRA_STATE(type)						      \
+	type ## _EXTRA_STATE_SAVER;
+
+/* Restore register state not normally restored by POP_STATE for TYPE.  */
+#define RESTORE_EXTRA_STATE(type)					      \
+	type ## _EXTRA_STATE_RESTORER;
+
+/* Save any call-clobbered registers not normally saved by PUSH_STATE
+   for TYPE.  */
+#define SAVE_EXTRA_STATE_FOR_FUNCALL(type)				      \
+	type ## _FUNCALL_EXTRA_STATE_SAVER;
+
+/* Restore any call-clobbered registers not normally restored by POP_STATE for
+   TYPE.  */
+#define RESTORE_EXTRA_STATE_FOR_FUNCALL(type)				      \
+	type ## _FUNCALL_EXTRA_STATE_RESTORER;
+
+
+/* These are extra_state_saver/restorer values for a user trap.  Note that we
+   save the argument registers so that restarted syscalls will function
+   properly (otherwise it wouldn't be necessary), and we must _not_ restore
+   the return-value registers (so that traps can return a value!), but there
+   are various options for what happens to other call-clobbered registers,
+   selected by preprocessor conditionals.  */
+
+#if TRAPS_PRESERVE_CALL_CLOBBERED_REGS
+   
+/* Traps save/restore all call-clobbered registers (except for rval regs).  */
+#define TRAP_STATE_SAVER						      \
+     SAVE_CALL_CLOBBERED_REGS_NO_RVAL;					      \
+     SAVE_SYS_REGS_FOR_TRAP
+
+#define TRAP_STATE_RESTORER						      \
+     RESTORE_CALL_CLOBBERED_REGS_NO_RVAL;				      \
+     RESTORE_SYS_REGS_FOR_TRAP
+
+#else /* !TRAPS_PRESERVE_CALL_CLOBBERED_REGS */
+
+/* Traps don't save call-clobbered registers (but do still save arg regs).  */
+#define TRAP_STATE_SAVER						      \
+     SAVE_ARG_REGS;							      \
+     SAVE_SYS_REGS_FOR_TRAP
+
+#if TRAPS_ZERO_CALL_CLOBBERED_REGS
+   
+/* Traps zero call-clobbered registers (except for arg/rval regs) before
+   returning from a system call, to avoid any internal values from leaking out
+   of the kernel.  */
+#define TRAP_STATE_RESTORER						      \
+     ZERO_CALL_CLOBBERED_REGS_NO_ARGS_NO_RVAL;				      \
+     RESTORE_ARG_REGS;							      \
+     RESTORE_SYS_REGS_FOR_TRAP
+
+#else /* !TRAPS_ZERO_CALL_CLOBBERED_REGS */
+   
+/* When traps return, they just leave call-clobbered registers (except for arg
+   regs) with whatever value they have from the kernel.  */
+#define TRAP_STATE_RESTORER						      \
+     RESTORE_ARG_REGS;							      \
+     RESTORE_SYS_REGS_FOR_TRAP
+
+#endif /* TRAPS_ZERO_CALL_CLOBBERED_REGS */
+#endif /* TRAPS_PRESERVE_CALL_CLOBBERED_REGS */
+
+/* Save registers not normally saved by traps.  */
+#define TRAP_EXTRA_STATE_SAVER						      \
+   SAVE_RVAL_REGS;							      \
+   SAVE_CALL_SAVED_REGS
+#define TRAP_EXTRA_STATE_RESTORER					      \
+   RESTORE_RVAL_REGS;							      \
+   RESTORE_CALL_SAVED_REGS
+#define TRAP_FUNCALL_EXTRA_STATE_SAVER					      \
+   SAVE_RVAL_REGS
+#define TRAP_FUNCALL_EXTRA_STATE_RESTORER				      \
+   RESTORE_RVAL_REGS
+
+/* Save registers not normally saved by traps.  */
+/* DBTRAP saves everything on entry, so nothing "extra" to save */
+#define DBTRAP_EXTRA_STATE_SAVER
+#define DBTRAP_EXTRA_STATE_RESTORER
+
+#define DBTRAP_FUNCALL_EXTRA_STATE_SAVER
+#define DBTRAP_FUNCALL_EXTRA_STATE_RESTORER
+
+/* The PTRACE syscall expects the entire PT_REGS struct to be correct, so no
+   optimisations allows - we must save all registers immediately upon entry */
+#define DBTRAP_STATE_SAVER						      \
+     SAVE_CALL_SAVED_REGS;						      \
+     SAVE_CALL_CLOBBERED_REGS;						      \
+     SAVE_SYS_REGS_FOR_DBTRAP
+
+#define DBTRAP_STATE_RESTORER						      \
+     RESTORE_CALL_SAVED_REGS;						      \
+     RESTORE_SYS_REGS_FOR_DBTRAP;					      \
+     RESTORE_CALL_CLOBBERED_REGS
+
+
+/* Register saving/restoring for maskable interrupts.  */
+#define IRQ_STATE_SAVER							      \
+   SAVE_CALL_CLOBBERED_REGS;						      \
+   SAVE_SYS_REGS_FOR_IRQ
+
+#define IRQ_STATE_RESTORER						      \
+   RESTORE_SYS_REGS_FOR_IRQ						      \
+   RESTORE_CALL_CLOBBERED_REGS;	
+
+#define IRQ_EXTRA_STATE_SAVER						      \
+   SAVE_CALL_SAVED_REGS
+
+#define IRQ_EXTRA_STATE_RESTORER					      \
+   RESTORE_CALL_SAVED_REGS
+
+#define IRQ_FUNCALL_EXTRA_STATE_SAVER       /* nothing */
+
+#define IRQ_FUNCALL_EXTRA_STATE_RESTORER    /* nothing */
+
+/* Register saving/restoring for non-maskable interrupts.  */
+#define NMI_STATE_SAVER							      \
+   SAVE_CALL_CLOBBERED_REGS;						      \
+   SAVE_SYS_REGS_FOR_NMI
+
+#define NMI_STATE_RESTORER						      \
+   RESTORE_CALL_CLOBBERED_REGS;						      \
+   RESTORE_SYS_REGS_FOR_NMI
+
+#define NMI_EXTRA_STATE_SAVER						      \
+   SAVE_CALL_SAVED_REGS
+
+#define NMI_EXTRA_STATE_RESTORER					      \
+   RESTORE_CALL_SAVED_REGS
+
+#define NMI_FUNCALL_EXTRA_STATE_SAVER       /* nothing */
+
+#define NMI_FUNCALL_EXTRA_STATE_RESTORER    /* nothing */
+   
+/* Register saving/restoring for a context switch.  We don't need to save too
+   many registers, because context-switching looks like a function call (via
+   the function `switch_thread'), so callers will save any call-clobbered
+   registers themselves.  The stack pointer and return value are handled by
+   switch_thread itself.  */
+#define SWITCH_STATE_SAVER						      \
+   SAVE_CALL_SAVED_REGS
+
+#define SWITCH_STATE_RESTORER						      \
+   RESTORE_CALL_SAVED_REGS
+
+/* Instructions to return from an IRQ */
+#define IRQ_RETURN_INST							      \
+	rtid	r14, 0;		/* Follow interrupt link pointer back to */   \
+				/* next insn after interrupt occured */       \
+	nop;			/* Delay slot */		      
+
+/* Instructions to return from a trap */
+/* Note we use rtbd to clear BIP bit on way out */
+/* Return offset is 4, to execute instruction after syscall brki insn*/
+#define TRAP_RETURN_INST						      \
+	rtbd	r14, 4;		/* r14 used as trap link register */	      \
+	nop;
+
+/* Instructions to return from a debug trap */
+/* Note we use rtbd to clear BIP bit on exit */
+/* Return offset is zero, to ensure trapped instruction is re-executed */
+#define DBTRAP_RETURN_INST						      \
+	rtbd	r14, 0;		/* r14 used as trap link register */	      \
+	nop;
+
+/* Code fragment to return from NMI */
+#define NMI_RETURN_INST							      \
+	rtbd	r16, 8;		/* r16 is NMI (brk) link register */	      \
+	nop;
+
+/* Restore register state from the struct pt_regs on the stack, switch back
+   to the user stack if necessary, and return from the trap/interrupt.
+   EXTRA_STATE_RESTORER is a sequence of assembly language statements to
+   restore anything not restored by this macro.  Only registers not saved by
+   the C compiler are restored (that is, R1(sp), R2(gp), R15(lp), and
+   anything restored by EXTRA_STATE_RESTORER).  */
+#define RETURN(type)							      \
+	ENTRY_CLI(r11);							      \
+        lwi	r11, r1, PTO+PT_KERNEL_MODE;				      \
+	bnei	r11, 2f;		/* See if returning to kernel mode, */\
+					/* ... if so, skip resched &c.  */    \
+									      \
+	/* We're returning to user mode, so check for various conditions that \
+	   trigger rescheduling. */					      \
+	/* Get current task ptr into r11 */				      \
+	RETRIEVE_CURRENT_TASK(r11);					      \
+	lwi	r11, r11, TASK_NEED_RESCHED;				      \
+	bnei	r11, 3f;		/* Call the scheduler */	      \
+									      \
+	/* XXX Is PT_DTRACE handling needed here? */			      \
+	/* XXX m68knommu also checks TASK_STATE & TASK_COUNTER here.  */      \
+									      \
+	/* Maybe handle a signal */					      \
+5:	RETRIEVE_CURRENT_TASK(r11);					      \
+	lwi	r11, r11, TASK_SIGPENDING;				      \
+	bnei	r11, 4f;		/* Signals to handle, handle them */  \
+									      \
+	RETRIEVE_CURRENT_TASK(r11);					      \
+	lwi	r11, r11, TASK_PTRACE;					      \
+	bnei	r11, 4f;		/* Signals to handle, handle them */  \
+									      \
+/* Finally, return to user state.  */					      \
+1:	swi	r0, r0, KM;		/* Now officially in user state. */   \
+	POP_STATE(type);						      \
+	swi	r1, r0, KSP;		/* Save the kernel stack pointer. */  \
+	lwi	r1, r1, PT_GPR(GPR_SP)-PT_SIZE;				      \
+					/* Restore user stack pointer. */     \
+	bri	6f;							      \
+									      \
+/* Return to kernel state.  */						      \
+2:	POP_STATE(type);						      \
+6:									      \
+type ## _return:		/* Make global symbol for debugging */	      \
+	type ## _RETURN_INST						      \
+									      \
+/* Call the scheduler before returning from a syscall/trap. */		      \
+3:	SAVE_EXTRA_STATE_FOR_FUNCALL(type); /* Prepare for funcall. */	      \
+	bralid	r15, CSYM(schedule);	/* Call scheduler */		      \
+	nop;				/* delay slot */		      \
+	ENTRY_CLI(r11);		/* The scheduler enables interrupts */	      \
+	RESTORE_EXTRA_STATE_FOR_FUNCALL(type);				      \
+	brid	5b;		/* Back to continue return processing */      \
+	nop;								      \
+									      \
+/* Handle a signal return; Pending signals should be in r18.  */	      \
+4:      /* Not all registers are saved by the normal trap/interrupt entry     \
+	   points (for instance, call-saved registers (because the normal     \
+	   C-compiler calling sequence in the kernel makes sure they're	      \
+	   preserved), and call-clobbered registers in the case of	      \
+	   traps), but signal handlers may want to examine or change the      \
+	   complete register state.  Here we save anything not saved by	      \
+	   the normal entry sequence, so that it may be safely restored	      \
+	   (in a possibly modified form) after do_signal returns.  */	      \
+        SAVE_EXTRA_STATE(type)		/* Save state not saved by entry. */  \
+	la	r5, r1, PTO;		/* Arg 1: struct pt_regs *regs */     \
+	add	r6, r0, r0;		/* Arg 2: sigset_t *oldset */	      \
+	bralid	r15, CSYM(do_signal);	/* Handle any signals */	      \
+	nop;								      \
+	ENTRY_CLI(r11);		/* Sig handling enables interrupts */	      \
+        RESTORE_EXTRA_STATE(type);	/* Restore extra regs.  */	      \
+	brid	1b;							      \
+	nop;	
+
+
+/* Jump to the appropriate function for the system call number in r12
+   (r12 is not preserved), or return an error if r12 is not valid.  The
+   LP register should point to the location where the called function
+   should return.  [note that MAKE_SYS_CALL uses label 1]  */
+#define MAKE_SYS_CALL							      \
+	/* See if the system call number is valid.  */			      \
+	addi	r11, r12, -NR_syscalls;					      \
+	bgei	r11,1f;							      \
+	/* Figure out which function to use for this system call.  */	      \
+	/* Note Microblaze barrel shift is optional, so don't rely on it */   \
+	add	r12, r12, r12;			/* convert num -> ptr */      \
+	add	r12, r12, r12;						      \
+	lwi	r12, r12, CSYM(sys_call_table);	/* Get function pointer */    \
+	/* Make the system call.  */					      \
+	bra	r12;							      \
+	/* The syscall number is invalid, return an error.  */		      \
+1:	addi	r3, r0, -ENOSYS;					      \
+	rtsd	r15,8;		/* looks like a normal subroutine return */
+
+
+	// Ugly kludge to get around some Xilinx mb-gcc wierdness
+	.data
+	.globl CSYM(_shift_temp_loc)
+CSYM(_shift_temp_loc):
+	.long	0
+
+	.text
+
+/*
+ * User trap.
+ *
+ * System calls are handled here.
+ *
+ * Syscall protocol:
+ *   Syscall number in r12, args in r5-r10
+ *   Return value in r3
+ *
+ * Trap entered via brki instruction, so BIP bit is set, and interrupts
+ * are masked.  This is nice, means we don't have to CLI before state save
+ */
+G_ENTRY(trap):
+	swi	r1, r0, ENTRY_SP;	// save stack (emulate v850)
+	SAVE_STATE (TRAP, r12, ENTRY_SP) // Save registers. 
+	BIPCLR(r11);			// Clear BIP
+					// BIP now cleared, interrupts enabled
+	la	r15, r0, ret_from_trap-8// where the trap should return
+					// need -8 to adjust for rtsd r15, 8
+	MAKE_SYS_CALL			// Jump to the syscall function. 
+END(trap)
+
+/* This is just like ret_from_trap, but first restores extra registers
+   saved by some wrappers.  */
+L_ENTRY(restore_extra_regs_and_ret_from_trap):
+	RESTORE_EXTRA_STATE(TRAP)
+	// fall through
+END(restore_extra_regs_and_ret_from_trap)
+
+/* Entry point used to return from a syscall/trap.  */
+/* We re-enable BIP bit before state restore */
+L_ENTRY(ret_from_trap):
+	BIPSET(r11);			//  Ints masked for state restore
+	RETURN(TRAP)
+END(ret_from_trap)
+
+/* This the initial entry point for a new child thread, with an appropriate
+   stack in place that makes it look the the child is in the middle of an
+   syscall.  This function is actually `returned to' from switch_thread
+   (copy_thread makes ret_from_fork the return address in each new thread's
+   saved context).  */
+C_ENTRY(ret_from_fork):
+	bralid	r15, CSYM(schedule_tail); // ...which is schedule_tail's arg
+	add	r3, r5, r0;		// switch_thread returns the prev task.
+					// ( in the delay slot )
+	add	r3, r0, r0;		// Child's fork call should return 0.
+	brid	ret_from_trap		// Do normal trap return.
+	nop;
+C_END(ret_from_fork)
+
+
+#if !TRAPS_PRESERVE_CALL_CLOBBERED_REGS
+	// Make sure r13 and r14 are preserved, in case we have to restart a
+	// system call because of a signal (ep has already been set by caller).
+	//st.w	r13, PTO+PT_GPR(13)[sp]
+	//st.w	r14, PTO+PT_GPR(13)[sp]
+	la	r15, r0, ret_from_long_syscall-8
+#endif /* !TRAPS_PRESERVE_CALL_CLOBBERED_REGS */
+
+	MAKE_SYS_CALL			// Jump to the syscall function.
+END(syscall_long)	
+
+#if !TRAPS_PRESERVE_CALL_CLOBBERED_REGS
+/* Entry point used to return from a long syscall.  Only needed to restore
+   r13/r14 if the general trap mechanism doesnt' do so.  */
+L_ENTRY(ret_from_long_syscall):
+	//ld.w	PTO+PT_GPR(13)[sp], r13 // Restore the extra registers
+	//ld.w	PTO+PT_GPR(13)[sp], r14
+	brid	ret_from_trap;		// The rest is the same as other traps
+	nop;
+END(ret_from_long_syscall)
+#endif /* !TRAPS_PRESERVE_CALL_CLOBBERED_REGS */
+
+
+/* These syscalls need access to the struct pt_regs on the stack, so we
+   implement them in assembly (they're basically all wrappers anyway).  */
+
+L_ENTRY(sys_fork_wrapper):
+#ifdef NO_MM
+	// fork almost works, enough to trick you into looking elsewhere :-(
+	addi	r3, r0, -EINVAL
+	rtsd	r15, 8;
+#else
+	// Save state not saved by entry.  This is actually slight overkill;
+	// it's actually only necessary to save any state restored by
+	// switch_thread that's not saved by the trap entry.
+	SAVE_EXTRA_STATE(TRAP)		// Save state not saved by entry.
+	addi	r5, r0, SIGCHLD		// Arg 0: flags
+	lwi	r6, r1, PTO+PT_GPR(GPR_SP) // Arg 1: child SP (use parent's)
+	la	r7, r1, PTO;		// Arg 2: parent context
+	add	r9. r0, r0;		// Arg 3: (unused)
+	brid	CSYM(do_fork)		// Do real work (tail-call).
+	nop;
+#endif
+END(sys_fork_wrapper)
+
+L_ENTRY(sys_vfork_wrapper):
+	// Save state not saved by entry.  This is actually slight overkill;
+	// it's actually only necessary to save any state restored by
+	// switch_thread that's not saved by the trap entry.
+	SAVE_EXTRA_STATE(TRAP)		// Save state not saved by entry.
+	addi	r5, r0, CLONE_VFORK | CLONE_VM | SIGCHLD // Arg 0: flags
+	lwi	r6, r1, PTO+PT_GPR(GPR_SP) // Arg 1: child SP (use parent's)
+	la	r7, r1, PTO;		// Arg 2: parent context
+	add	r8, r0, r0;			// Arg 3: (unused)
+	brid	CSYM(do_fork)		// Do real work (tail-call).
+	nop
+END(sys_vfork_wrapper)
+
+L_ENTRY(sys_clone_wrapper):
+	// Save state not saved by entry.  This is actually slight overkill;
+	// it's actually only necessary to save any state restored by
+	// switch_thread that's not saved by the trap entry.
+	SAVE_EXTRA_STATE(TRAP)		// Save state not saved by entry.
+	bnei	r6, 1f; 		// See if child SP arg (arg 1) is 0.
+	lwi	r6, r1, PTO+PT_GPR(GPR_SP);	// If so, use paret's stack ptr
+1:	la	r7, r1, PTO;		// Arg 2: parent context
+	add	r8, r0, r0;		// Arg 3: (unused)
+	brid	CSYM(do_fork)		// Do real work (tail-call).
+	nop;
+END(sys_clone_wrapper)
+
+L_ENTRY(sys_execve_wrapper):
+	la	r8, r1, PTO;		// add user context as 4th arg
+	brid	CSYM(sys_execve);	// Do real work (tail-call).
+	nop;
+END(sys_execve_wrapper)
+
+L_ENTRY(sys_sigsuspend_wrapper):
+        SAVE_EXTRA_STATE(TRAP)		// Save state not saved by entry.
+	la	r6, r1, PTO;		// add user context as 2nd arg
+	bralid	r15, CSYM(sys_sigsuspend); // Do real work.
+	nop;
+	brid	restore_extra_regs_and_ret_from_trap;
+	nop;
+END(sys_sigsuspend_wrapper)
+
+L_ENTRY(sys_rt_sigsuspend_wrapper):
+        SAVE_EXTRA_STATE(TRAP)		// Save state not saved by entry.
+	la	r7, r1, PTO;		// add user context as 3rd arg
+	brlid	r15, CSYM(sys_rt_sigsuspend);	// Do real work.
+	nop;
+	brid	restore_extra_regs_and_ret_from_trap;
+	nop;
+END(sys_rt_sigsuspend_wrapper)
+
+L_ENTRY(sys_sigreturn_wrapper):
+        SAVE_EXTRA_STATE(TRAP)		// Save state not saved by entry.
+	la	r5, r1, PTO;		// add user context as 1st arg
+	brlid	r15, CSYM(sys_sigreturn);	// Do real work.
+	nop;
+	brid	restore_extra_regs_and_ret_from_trap;
+	nop;
+END(sys_sigreturn_wrapper)
+
+L_ENTRY(sys_rt_sigreturn_wrapper):
+        SAVE_EXTRA_STATE(TRAP)		// Save state not saved by entry.
+	la	r5, r1, PTO;		// add user context as 1st arg
+	brlid	r15, CSYM(sys_rt_sigreturn)	// Do real work.
+	nop;
+	brid	restore_extra_regs_and_ret_from_trap;
+	nop;
+END(sys_rt_sigreturn_wrapper)
+
+
+/*
+ * Hardware maskable interrupts.
+ *
+ * The stack-pointer (r1) should have already been saved to the memory
+ * location ENTRY_SP.
+ * Currently this is just because the v850 code does it.  This should
+ * be removed at some point to streamline things
+ */
+G_ENTRY(irq):
+	swi	r1, r0, ENTRY_SP;	// save stack (emulate v850)
+	SAVE_STATE (IRQ, r0, ENTRY_SP)	// Save registers. 
+
+	add	r5, r0, r0;		// Clear first param
+	la	r6, r1, PTO;		// User regs are arg2
+
+	// It's up to the high level handler to query the
+	// interrupt controller and get the IRQ number etc
+
+	// Call the high-level interrupt handling code.
+	bralid r15, CSYM(handle_irq);
+	nop;
+
+	// fall through
+
+/* Entry point used to return from an interrupt (also used by exception
+   handle
+s, below).  */
+ret_from_irq:
+	RETURN(IRQ)
+END(irq)
+
+
+/*
+ * Hardware non-maskable interrupts.
+ *
+ * The stack-pointer (r1) should have already been saved to the memory
+ * location ENTRY_SP (the reason for this is that the interrupt vectors may be
+ * beyond a 22-bit signed offset jump from the actual interrupt handler, and
+ * this allows them to save the stack-pointer and use that register to do an
+ * indirect jump).
+ */
+G_ENTRY(nmi):
+	swi	r1, r0, NMI_ENTRY_SP;		/* Save state (emulate v850) */
+	SAVE_STATE (NMI, r0, NMI_ENTRY_SP); /* Save registers.  */
+
+	add	r5, r0, r0;
+	la	r6, r1, PTO;	/* User regs are arg2.  */
+
+	/* Non-maskable interrupts always lie right after maskable interrupts.
+	   Call the generic IRQ handler, with two arguments, the IRQ number,
+	   and a pointer to the user registers, to handle the specifics.
+	   (we subtract one because the first NMI has code 1).  */
+	bralid 	r15, CSYM(handle_irq);
+	nop;
+
+	RETURN(NMI)
+END(nmi0)
+
+
+/*
+ * Illegal instruction trap.
+ *
+ * The stack-pointer (r3) should have already been saved to the memory
+ * location ENTRY_SP (the reason for this is that the interrupt vectors may be
+ * beyond a 22-bit signed offset jump from the actual interrupt handler, and
+ * this allows them to save the stack-pointer and use that register to do an
+ * indirect jump).
+ */
+G_ENTRY(illegal_instruction):
+	swi	r1, r0, ENTRY_SP;	// Save stack (emulate v850)
+	SAVE_STATE (IRQ, r0, ENTRY_SP)	// Save registers. 
+	ENTRY_EI(r11);
+	addi	r5, r0, SIGILL;		// Arg 0: signal number
+	RETRIEVE_CURRENT_TASK(r6);	// Arg 1: task
+	la	r15, r0, ret_from_irq-8	// where the handler should return
+	brid	CSYM(force_sig);
+	nop;
+
+END(illegal_instruction)
+
+
+/*
+ * `Debug' trap
+ *  We enter dbtrap in "BIP" (breakpoint) mode. 
+ *  So we exit the breakpoint mode with an 'rtbd' and proceed with the
+ *  original dbtrap.
+ *  however, wait to save state first
+ */
+G_ENTRY(dbtrap):
+	/* BIP bit is set on entry, no interrupts can occur */
+	swi	r1, r0, ENTRY_SP;	// Save stack (emulate v850)
+	SAVE_STATE (DBTRAP, r0, ENTRY_SP)   // Save registers. 
+	BIPCLR(r11);
+	/* BIP bit now clear, interrupts can occur */
+	// Should insert code to detect illegal traps etc
+
+	// For now, call into kernel for debugging
+	// brlid	r15, CSYM(debug_trap);
+	//la	r5, r1, PTO
+
+	addi	r5, r0, SIGTRAP;	// send the trap signal
+	RETRIEVE_CURRENT_TASK(r6);	// to the current task
+	brlid	r15, CSYM(send_sig);
+	nop;
+
+	BIPSET(r11);		/* Set BIP again, ready for state restore */
+	RETURN(DBTRAP);
+
+END(dbtrap)
+
+G_ENTRY(reset_trap):
+
+	/* BIP bit is set on entry, no interrupts can occur */
+	swi	r1, r0, ENTRY_SP;	// Save stack (emulate v850)
+	SAVE_STATE (DBTRAP, r0, ENTRY_SP)   // Save registers. 
+	BIPCLR(r11);
+
+	// For now, call into kernel for debugging
+	brlid	r15, CSYM(debug_trap);
+	la	r5, r1, PTO
+	// And loop forever! */
+foo:	brid foo
+	nop
+END(reset_trap)
+
+/*
+ * Trap with no handler
+ */
+L_ENTRY(bad_trap_wrapper):
+	add	r5, r0, r19; 		// Arg 0: trap number
+	la	r6, r1, PTO;		// Arg 1: user regs
+	brid	CSYM(bad_trap);		// tail call handler
+	nop;
+
+END(bad_trap_wrapper)
+
+/*
+ * This is where we switch between two threads.  The arguments are:
+ *   r5 -- pointer to the struct thread for the `current' process
+ *   r6 -- pointer to the struct thread for the `new' process.  
+ * when this function returns, it will return to the new thread.
+ */
+C_ENTRY(switch_thread):
+
+	// Return the previous task
+	// Do this before push_state, so that return value is on stack
+	// Update the current task pointer
+	//GET_CURRENT_TASK(CURRENT_TASK)
+	RETRIEVE_CURRENT_TASK(r3);
+
+	// First, push the current processor state on the stack
+	PUSH_STATE(SWITCH)
+
+	// Now save the location of the kernel stack pointer for this thread;
+	// since we've pushed all other state on the stack, this is enough to
+	// restore it all later.
+	swi	r1, r5, THREAD_KSP;
+	// Now restore the stack pointer from the new process
+	lwi	r1, r6, THREAD_KSP;
+	// ... and restore all state from that
+	POP_STATE(SWITCH)
+	// Update the current task pointer
+	GET_CURRENT_TASK(CURRENT_TASK)
+	// Now return into the new thread
+	rtsd	r15,8;
+	nop;
+C_END(switch_thread)
+
+	.section .rodata
+	
+	.align 4
+	.globl CSYM(sys_call_table)
+CSYM(sys_call_table):
+	.long CSYM(sys_ni_syscall)	// 0  -  old "setup()" system call
+	.long CSYM(sys_exit)
+	.long sys_fork_wrapper
+	.long CSYM(sys_read)
+	.long CSYM(sys_write)
+	.long CSYM(sys_open)		// 5
+	.long CSYM(sys_close)
+	.long CSYM(sys_waitpid)
+	.long CSYM(sys_creat)
+	.long CSYM(sys_link)
+	.long CSYM(sys_unlink)		// 10
+	.long sys_execve_wrapper
+	.long CSYM(sys_chdir)
+	.long CSYM(sys_time)
+	.long CSYM(sys_mknod)
+	.long CSYM(sys_chmod)		// 15
+	.long CSYM(sys_chown16)
+	.long CSYM(sys_ni_syscall)	// was: break
+	.long CSYM(sys_ni_syscall)	// was: oldstat (aka stat)
+	.long CSYM(sys_lseek)
+	.long CSYM(sys_getpid)		// 20
+	.long CSYM(sys_mount)
+	.long CSYM(sys_oldumount)
+	.long CSYM(sys_setuid16)
+	.long CSYM(sys_getuid16)
+	.long CSYM(sys_stime)		// 25
+	.long CSYM(sys_ptrace)
+	.long CSYM(sys_alarm)
+	.long CSYM(sys_ni_syscall)	// was: oldfstat (aka fstat)
+	.long CSYM(sys_pause)
+	.long CSYM(sys_utime)		// 30
+	.long CSYM(sys_ni_syscall)	// was: stty
+	.long CSYM(sys_ni_syscall)	// was: gtty
+	.long CSYM(sys_access)
+	.long CSYM(sys_nice)
+	.long CSYM(sys_ni_syscall)	// 35, was: ftime
+	.long CSYM(sys_sync)
+	.long CSYM(sys_kill)
+	.long CSYM(sys_rename)
+	.long CSYM(sys_mkdir)
+	.long CSYM(sys_rmdir)		// 40
+	.long CSYM(sys_dup)
+	.long CSYM(sys_pipe)
+	.long CSYM(sys_times)
+	.long CSYM(sys_ni_syscall)	// was: prof
+	.long CSYM(sys_brk)		// 45
+	.long CSYM(sys_setgid16)
+	.long CSYM(sys_getgid16)
+	.long CSYM(sys_signal)
+	.long CSYM(sys_geteuid16)
+	.long CSYM(sys_getegid16)	// 50
+	.long CSYM(sys_acct)
+	.long CSYM(sys_umount)		// recycled never used phys()
+	.long CSYM(sys_ni_syscall)	// was: lock
+	.long CSYM(sys_ioctl)
+	.long CSYM(sys_fcntl)		// 55
+	.long CSYM(sys_ni_syscall)	// was: mpx
+	.long CSYM(sys_setpgid)
+	.long CSYM(sys_ni_syscall) 	// was: ulimit
+	.long CSYM(sys_ni_syscall)
+	.long CSYM(sys_umask)		// 60
+	.long CSYM(sys_chroot)
+	.long CSYM(sys_ustat)
+	.long CSYM(sys_dup2)
+	.long CSYM(sys_getppid)
+	.long CSYM(sys_getpgrp)		// 65
+	.long CSYM(sys_setsid)
+	.long CSYM(sys_sigaction)
+	.long CSYM(sys_sgetmask)
+	.long CSYM(sys_ssetmask)
+	.long CSYM(sys_setreuid16)	// 70
+	.long CSYM(sys_setregid16)
+	.long sys_sigsuspend_wrapper
+	.long CSYM(sys_sigpending)
+	.long CSYM(sys_sethostname)
+	.long CSYM(sys_setrlimit)	// 75
+	.long CSYM(sys_old_getrlimit)
+	.long CSYM(sys_getrusage)
+	.long CSYM(sys_gettimeofday)
+	.long CSYM(sys_settimeofday)
+	.long CSYM(sys_getgroups16)	// 80
+	.long CSYM(sys_setgroups16)
+	.long CSYM(sys_ni_syscall)	// was: old_select
+	.long CSYM(sys_symlink)
+	.long CSYM(sys_ni_syscall)	// was: oldlstat (aka lstat)
+	.long CSYM(sys_readlink)	// 85
+	.long CSYM(sys_uselib)
+	.long CSYM(sys_swapon)
+	.long CSYM(sys_reboot)
+	.long CSYM(old_readdir)
+	.long CSYM(sys_mmap)		// 90
+	.long CSYM(sys_munmap)
+	.long CSYM(sys_truncate)
+	.long CSYM(sys_ftruncate)
+	.long CSYM(sys_fchmod)
+	.long CSYM(sys_fchown16)	// 95
+	.long CSYM(sys_getpriority)
+	.long CSYM(sys_setpriority)
+	.long CSYM(sys_ni_syscall) 	// was: profil
+	.long CSYM(sys_statfs)
+	.long CSYM(sys_fstatfs)		// 100
+	.long CSYM(sys_ni_syscall)	// i386: ioperm
+	.long CSYM(sys_socketcall)
+	.long CSYM(sys_syslog)
+	.long CSYM(sys_setitimer)
+	.long CSYM(sys_getitimer)	// 105
+	.long CSYM(sys_newstat)
+	.long CSYM(sys_newlstat)
+	.long CSYM(sys_newfstat)
+	.long CSYM(sys_ni_syscall)	// was: olduname (aka uname)
+	.long CSYM(sys_ni_syscall)	// 110, i386: iopl
+	.long CSYM(sys_vhangup)
+	.long CSYM(sys_ni_syscall)	// was: idle
+	.long CSYM(sys_ni_syscall)	// i386: vm86old
+	.long CSYM(sys_wait4)
+	.long CSYM(sys_swapoff)		// 115
+	.long CSYM(sys_sysinfo)
+	.long CSYM(sys_ipc)
+	.long CSYM(sys_fsync)
+	.long sys_sigreturn_wrapper
+	.long sys_clone_wrapper		// 120
+	.long CSYM(sys_setdomainname)
+	.long CSYM(sys_newuname)
+	.long CSYM(sys_ni_syscall)	// i386: modify_ldt, m68k: cacheflush 
+	.long CSYM(sys_adjtimex)
+	.long CSYM(sys_mprotect)	// 125
+	.long CSYM(sys_sigprocmask)
+	.long CSYM(sys_create_module)
+	.long CSYM(sys_init_module)
+	.long CSYM(sys_delete_module)
+	.long CSYM(sys_get_kernel_syms) // 130
+	.long CSYM(sys_quotactl)
+	.long CSYM(sys_getpgid)
+	.long CSYM(sys_fchdir)
+	.long CSYM(sys_bdflush)
+	.long CSYM(sys_sysfs)		// 135
+	.long CSYM(sys_personality)
+	.long CSYM(sys_ni_syscall)	// for afs_syscall
+	.long CSYM(sys_setfsuid16)
+	.long CSYM(sys_setfsgid16)
+	.long CSYM(sys_llseek)		// 140
+	.long CSYM(sys_getdents)
+	.long CSYM(sys_select)
+	.long CSYM(sys_flock)
+	.long CSYM(sys_msync)
+	.long CSYM(sys_readv)		// 145
+	.long CSYM(sys_writev)
+	.long CSYM(sys_getsid)
+	.long CSYM(sys_fdatasync)
+	.long CSYM(sys_sysctl)
+	.long CSYM(sys_mlock)		// 150
+	.long CSYM(sys_munlock)
+	.long CSYM(sys_mlockall)
+	.long CSYM(sys_munlockall)
+	.long CSYM(sys_sched_setparam)
+	.long CSYM(sys_sched_getparam)	// 155
+	.long CSYM(sys_sched_setscheduler)
+	.long CSYM(sys_sched_getscheduler)
+	.long CSYM(sys_sched_yield)
+	.long CSYM(sys_sched_get_priority_max)
+	.long CSYM(sys_sched_get_priority_min)  // 160
+	.long CSYM(sys_sched_rr_get_interval)
+	.long CSYM(sys_nanosleep)
+	.long CSYM(sys_mremap)
+	.long CSYM(sys_setresuid16)
+	.long CSYM(sys_getresuid16)	// 165
+	.long CSYM(sys_ni_syscall)	// for vm86
+	.long CSYM(sys_query_module)
+	.long CSYM(sys_poll)
+	.long CSYM(sys_nfsservctl)
+	.long CSYM(sys_setresgid16)	// 170
+	.long CSYM(sys_getresgid16)
+	.long CSYM(sys_prctl)
+	.long sys_rt_sigreturn_wrapper
+	.long CSYM(sys_rt_sigaction)
+	.long CSYM(sys_rt_sigprocmask)	// 175
+	.long CSYM(sys_rt_sigpending)
+	.long CSYM(sys_rt_sigtimedwait)
+	.long CSYM(sys_rt_sigqueueinfo)
+	.long sys_rt_sigsuspend_wrapper
+	.long CSYM(sys_pread)		// 180
+	.long CSYM(sys_pwrite)
+	.long CSYM(sys_lchown16);
+	.long CSYM(sys_getcwd)
+	.long CSYM(sys_capget)
+	.long CSYM(sys_capset)		// 185
+	.long CSYM(sys_sigaltstack)
+	.long CSYM(sys_sendfile)
+	.long CSYM(sys_ni_syscall)	// streams1
+	.long CSYM(sys_ni_syscall)	// streams2
+	.long sys_vfork_wrapper		// 190
+	.long CSYM(sys_getrlimit)
+	.long CSYM(sys_mmap2)
+	.long CSYM(sys_truncate64)
+	.long CSYM(sys_ftruncate64)
+	.long CSYM(sys_stat64)		// 195
+	.long CSYM(sys_lstat64)
+	.long CSYM(sys_fstat64)
+	.long CSYM(sys_chown)
+	.long CSYM(sys_getuid)
+	.long CSYM(sys_getgid)		// 200
+	.long CSYM(sys_geteuid)
+	.long CSYM(sys_getegid)
+	.long CSYM(sys_setreuid)
+	.long CSYM(sys_setregid)
+	.long CSYM(sys_getgroups)	// 205
+	.long CSYM(sys_setgroups)
+	.long CSYM(sys_fchown)
+	.long CSYM(sys_setresuid)
+	.long CSYM(sys_getresuid)
+	.long CSYM(sys_setresgid)	// 210
+	.long CSYM(sys_getresgid)
+	.long CSYM(sys_lchown)
+	.long CSYM(sys_setuid)
+	.long CSYM(sys_setgid)
+	.long CSYM(sys_setfsuid)	// 215
+	.long CSYM(sys_setfsgid)
+	.long CSYM(sys_pivot_root)
+	.long CSYM(sys_mincore)		// just returns ENOSYS without MMU
+	.long CSYM(sys_madvise)		// just returns ENOSYS without MMU
+	.long CSYM(sys_getdents64)	// 220
+	.long CSYM(sys_fcntl64)
+	.long CSYM(sys_ni_syscall)	// Reserved for TUX
+	.long CSYM(sys_ni_syscall)	// Reserved for `security'
+	.long CSYM(sys_gettid)
+	.long CSYM(sys_ni_syscall)	// 225, sys_readahead on i386
+
+	.space (NR_syscalls-225)*4
diff -urN linux-2.4.29/arch/microblaze/kernel/exceptions.c linux-2.4.29-uc1/arch/microblaze/kernel/exceptions.c
--- linux-2.4.29/arch/microblaze/kernel/exceptions.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/exceptions.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+ *	arch/microblaze/kernel/exceptions.c - generic HW exception handling
+ *
+ * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Currently, Microblaze supports a total of 6 HW generated exceptions, all
+ * of which may be disabled in the hardware via configuration parameters.
+ * Of these, the unaligned access exception is probably the most interesting.
+ * It is exception type 1, and is handled directly in a lovely bit of optimised
+ * code in hw_exception_handler.S.  All other exceptions are dispatched through
+ * the MB_ExceptionVectorTable that is defined and initialised below.
+ * Currently, only the unaligned exception is supported - all others trap
+ * to null handlers, returning immediately.
+ *
+ */
+
+#include <asm/exceptions.h>
+
+/* Forward declararation of null exception handler function */
+void null_exception_handler(unsigned);
+
+/* Define a null exception vector */
+struct mb_exception_vector null_exception_vector={null_exception_handler,0};
+
+/* The actual exception vector table (for all except unaligned exceptions */
+struct mb_exception_vector MB_ExceptionVectorTable[NUM_OTHER_EXCEPTIONS];
+
+/* Initialize_exception_handlers() - called from setup.c/trap_init() */
+void initialize_exception_handlers(void)
+{
+	/* For now, just make all the other exception handlers NULL */
+	int i;
+	for(i=0;i<NUM_OTHER_EXCEPTIONS;i++)
+		MB_ExceptionVectorTable[i] = null_exception_vector;
+
+}
+
+/* Default null handler */
+void null_exception_handler(unsigned int param)
+{
+	return;
+}
+
diff -urN linux-2.4.29/arch/microblaze/kernel/head.S linux-2.4.29-uc1/arch/microblaze/kernel/head.S
--- linux-2.4.29/arch/microblaze/kernel/head.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/head.S	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,104 @@
+/*
+ * arch/microblaze/kernel/head.S -- Lowest-level startup code
+ *
+ *  Copyright (C) 2004       Brett Boren <borenb@eng.uah.edu>
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *                           based upon v850 version
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <asm/clinkage.h>
+#include <asm/current.h>
+#include <asm/entry.h>
+#include <asm/irq.h>
+
+
+/* Make a slightly more convenient alias for C_SYMBOL_NAME.  */
+#define CSYM	C_SYMBOL_NAME 
+
+.global CSYM(_ramstart)
+
+	.data
+CSYM(_ramstart):
+	.long 0
+
+	.text
+
+	// Define `mach_early_init' as a weak symbol
+	.global	CSYM(mach_early_init)
+	.weak	CSYM(mach_early_init)
+
+C_ENTRY(start):
+	// Make sure interrupts are turned off, just in case
+	mfs	r1, rmsr
+	andi	r1, r1, ~2
+	mts	rmsr, r1
+
+	// Set Small Data Anchors
+	la	r13, r0, _KERNEL_SDA_BASE_
+	la	r2, r0, _KERNEL_SDA2_BASE_
+
+	// Initialise the stack pointer
+	// Initial stack is shrunk by 4 bytes (1 word) to permit use of
+	// standard sp->task ptr conversion functions later on
+	la	r1, r0, CSYM(init_task_union)+KERNEL_STACK_SIZE-4;
+
+#ifdef CONFIG_MBVANILLA_CMDLINE
+	// BAB 1/7/04 - Copy off cmdline pointer passed in by bootloader
+	swi	r5, r0, CSYM(bootloader_buf_addr)
+#endif	
+	// See if there's a platform-specific early-initialization routine
+	// defined; it's a weak symbol, so it will have an address of zero if
+	// there's not.
+	la	r6, r0, CSYM(mach_early_init)
+	beqi	r6, 3f
+
+	// There is one, so call it.  If this function is written in C, it
+	// should be very careful -- the stack pointer is valid, but very
+	// little else is (e.g., bss is not zeroed yet).
+	brald	r15, r6			// do call
+	nop				// delay slot
+
+3:
+	// Kernel stack pointer save location
+	swi	r1, r0, KSP
+
+	// Assert that we're in `kernel mode'
+	addi	r19, r0, 1
+	swi	r19, r0, KM
+
+#if 0
+	// Zero bss area, since we can't rely upon any loader to do so
+	addi	r5, r0, CSYM(__bss_start)
+	add	r6, r0, r0
+	addi	r7, r0, CSYM(__bss_end)
+	rsub	r7, r5, r7
+	bralid	r15, CSYM(memset)
+	nop
+
+	// Zero sbss area, since we can't rely upon any loader to do so
+	addi	r5, r0, CSYM(_ssbss)
+	add	r6, r0, r0
+	addi	r7, r0, CSYM(_esbss)
+	rsub	r7, r5, r7
+	bralid	r15, CSYM(memset)
+	nop
+#endif
+
+	// initialise the current task ptr.  This must happen after
+	// we zero BSS, SBSS etc, because "current" is a global C symbol
+	GET_CURRENT_TASK(CURRENT_TASK);
+
+	// Start Linux kernel.
+	// If this call ever returns (which it shouldn't),
+	// set the link pointer to somewhere harmless
+	addi	r15, r0, CSYM(machine_halt)
+	brai	CSYM(start_kernel)
+END(start)
diff -urN linux-2.4.29/arch/microblaze/kernel/highres_timer.c linux-2.4.29-uc1/arch/microblaze/kernel/highres_timer.c
--- linux-2.4.29/arch/microblaze/kernel/highres_timer.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/highres_timer.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,132 @@
+/*
+ * arch/v850/kernel/highres_timer.c -- High resolution timing routines
+ *
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <asm/system.h>
+#include <asm/nb85e_timer_d.h>
+#include <asm/highres_timer.h>
+
+#define HIGHRES_TIMER_USEC_SHIFT   12
+
+/* Pre-calculated constant used for converting ticks to real time
+   units.  We initialize it to prevent it being put into BSS.  */
+static u32 highres_timer_usec_prescale = 1;
+
+void highres_timer_slow_tick_irq (void) __attribute__ ((noreturn));
+void highres_timer_slow_tick_irq (void)
+{
+	/* This is an interrupt handler, so it must be very careful to
+	   not to trash any registers.  At this point, the stack-pointer
+	   (r3) has been saved in the chip ram location ENTRY_SP by the
+	   interrupt vector, so we can use it as a scratch register; we
+	   must also restore it before returning.  */
+	asm ("ld.w	%0[r0], sp;"
+	     "add	1, sp;"
+	     "st.w	sp, %0[r0];"
+	     "ld.w	%1[r0], sp;" /* restore pre-irq stack-pointer */
+	     "reti"
+	     ::
+	      "i" (HIGHRES_TIMER_SLOW_TICKS_ADDR),
+	      "i" (ENTRY_SP_ADDR)
+	     : "memory");
+}
+
+void highres_timer_reset (void)
+{
+	NB85E_TIMER_D_TMD (HIGHRES_TIMER_TIMER_D_UNIT) = 0;
+	HIGHRES_TIMER_SLOW_TICKS = 0;
+}
+
+void highres_timer_start (void)
+{
+	u32 fast_tick_rate;
+
+	/* Start hardware timer.  */
+	nb85e_timer_d_configure (HIGHRES_TIMER_TIMER_D_UNIT,
+				 HIGHRES_TIMER_SLOW_TICK_RATE);
+
+	fast_tick_rate =
+		(cpu_clock_freq
+		 >> NB85E_TIMER_D_DIVLOG2 (HIGHRES_TIMER_TIMER_D_UNIT));
+
+	/* The obvious way of calculating microseconds from fast ticks
+	   is to do:
+
+	     usec = fast_ticks * 10^6 / fast_tick_rate
+
+	   However, divisions are much slower than multiplications, and
+	   the above calculation can overflow, so we do this instead:
+
+	     usec = fast_ticks * (10^6 * 2^12 / fast_tick_rate) / 2^12
+
+           since we can pre-calculate (10^6 * (2^12 / fast_tick_rate))
+	   and use a shift for dividing by 2^12, this avoids division,
+	   and is almost as accurate (it differs by about 2 microseconds
+	   at the extreme value of the fast-tick counter's ranger).  */
+	highres_timer_usec_prescale = ((1000000 << HIGHRES_TIMER_USEC_SHIFT)
+				       / fast_tick_rate);
+
+	/* Enable the interrupt (which is hardwired to this use), and
+	   give it the highest priority.  */
+	NB85E_INTC_IC (IRQ_INTCMD (HIGHRES_TIMER_TIMER_D_UNIT)) = 0;
+}
+
+void highres_timer_stop (void)
+{
+	/* Stop the timer.  */
+	NB85E_TIMER_D_TMCD (HIGHRES_TIMER_TIMER_D_UNIT) =
+		NB85E_TIMER_D_TMCD_CAE;
+	/* Disable its interrupt, just in case.  */
+	nb85e_intc_disable_irq (IRQ_INTCMD (HIGHRES_TIMER_TIMER_D_UNIT));
+}
+
+inline void highres_timer_read_ticks (u32 *slow_ticks, u32 *fast_ticks)
+{
+	int flags;
+	u32 fast_ticks_1, fast_ticks_2, _slow_ticks;
+
+	save_flags_cli (flags);
+	fast_ticks_1 = NB85E_TIMER_D_TMD (HIGHRES_TIMER_TIMER_D_UNIT);
+	_slow_ticks = HIGHRES_TIMER_SLOW_TICKS;
+	fast_ticks_2 = NB85E_TIMER_D_TMD (HIGHRES_TIMER_TIMER_D_UNIT);
+	restore_flags (flags);
+
+	if (fast_ticks_2 < fast_ticks_1)
+		_slow_ticks++;
+
+	*slow_ticks = _slow_ticks;
+	*fast_ticks = fast_ticks_2;
+}
+
+inline void highres_timer_ticks_to_timeval (u32 slow_ticks, u32 fast_ticks,
+					    struct timeval *tv)
+{
+	unsigned long sec, sec_rem, usec;
+
+	usec = ((fast_ticks * highres_timer_usec_prescale)
+		>> HIGHRES_TIMER_USEC_SHIFT);
+
+	sec = slow_ticks / HIGHRES_TIMER_SLOW_TICK_RATE;
+	sec_rem = slow_ticks % HIGHRES_TIMER_SLOW_TICK_RATE;
+
+	usec += sec_rem * (1000000 / HIGHRES_TIMER_SLOW_TICK_RATE);
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+void highres_timer_read (struct timeval *tv)
+{
+	u32 fast_ticks, slow_ticks;
+	highres_timer_read_ticks (&slow_ticks, &fast_ticks);
+	highres_timer_ticks_to_timeval (slow_ticks, fast_ticks, tv);
+}
diff -urN linux-2.4.29/arch/microblaze/kernel/hw_exception_handler.S linux-2.4.29-uc1/arch/microblaze/kernel/hw_exception_handler.S
--- linux-2.4.29/arch/microblaze/kernel/hw_exception_handler.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/hw_exception_handler.S	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,392 @@
+/*///////////////////////////////////////////////////////////////////////////
+//
+// arch/microblaze/kernel/hw_exception_handler.S
+//
+// Unaligned exception handling for Microblaze
+//
+// uClinux customisation (c) 2005 John Williams
+//
+// Original code 
+// Copyright (c) 2004 Xilinx, Inc.  All rights reserved.
+//
+// Xilinx, Inc.
+// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+// COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+// ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
+// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
+// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
+// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
+// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
+// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $Id: hw_exception_handler.S,v 1.1 2005/05/05 14:34:11 gerg Exp $
+//
+//////////////////////////////////////////////////////////////////////////////*/
+
+/*
+ * Microblaze HW Exception Handler
+ * - Non self-modifying exception handler for the following exception conditions
+ *   - Unalignment
+ *   - Instruction bus error
+ *   - Data bus error
+ *   - Illegal instruction opcode
+ *   - Divide-by-zero
+ *
+ * Note we disable interrupts during exception handling, otherwise we will possibly
+ * get multiple re-entrancy if interrupt handles themselves cause exceptions. JW
+ */
+
+#include <linux/config.h>
+#include <asm/exceptions.h>
+
+#if MICROBLAZE_EXCEPTIONS_ENABLED
+
+/* Helpful Macros */
+#define EX_HANDLER_STACK_SIZ            (4*19)
+#define RMSR_OFFSET                     0       
+#define REG_OFFSET(regnum)              (4*regnum)
+#define NUM_TO_REG(num)                 r ## num
+
+#define R3_TO_STACK(regnum)             swi     r3, r1, REG_OFFSET(regnum)
+#define R3_FROM_STACK(regnum)           lwi     r3, r1, REG_OFFSET(regnum)      
+
+#define PUSH_REG(regnum)                swi     NUM_TO_REG(regnum), r1, REG_OFFSET(regnum)
+#define POP_REG(regnum)                 lwi     NUM_TO_REG(regnum), r1, REG_OFFSET(regnum)
+        
+/* Uses r5 */
+#define PUSH_MSR                                                                \
+        mfs     r5, rmsr;                                                       \
+        swi     r5, r1, RMSR_OFFSET;
+
+#define PUSH_MSR_AND_ENABLE_EXC                                                 \
+        mfs     r5, rmsr;                                                       \
+        swi     r5, r1, RMSR_OFFSET;                                            \
+        ori     r5, r5, 0x100;                          /* Turn ON the EE bit*/ \
+	andi	r5, r5, ~2;				/* Disable interrupts */\
+        mts     rmsr, r5;
+        
+/* Uses r5 */
+#define POP_MSR                                                                 \
+        lwi     r5, r1, RMSR_OFFSET;                                            \
+        mts     rmsr, r5;       
+
+#define LWREG_NOP                                                               \
+        bri     ex_handler_unhandled;                                           \
+        nop;
+
+#define SWREG_NOP                                                               \
+        bri     ex_handler_unhandled;                                           \
+        nop;        
+        
+/* r3 is the source */
+#define R3_TO_LWREG_V(regnum)                                                   \
+        R3_TO_STACK (regnum);                                                   \
+        bri     ex_handler_done; 
+
+/* r3 is the source */
+#define R3_TO_LWREG(regnum)                                                     \
+        or      NUM_TO_REG (regnum), r0, r3;                                    \
+        bri     ex_handler_done;                        
+
+/* r3 is the target */          
+#define SWREG_TO_R3_V(regnum)                                                   \
+        R3_FROM_STACK (regnum);                                                 \
+        bri     ex_sw_tail;                                                     
+                
+/* r3 is the target */  
+#define SWREG_TO_R3(regnum)                                                     \
+        or      r3, r0, NUM_TO_REG (regnum);                                    \
+        bri     ex_sw_tail; 
+
+        
+/* Extern declarations */
+.extern MB_ExceptionVectorTable			/* Defined in exception.c */
+
+                
+/* 
+ * hw_exception_handler - Handler for unaligned exceptions
+ * Exception handler notes:     
+ * - Does not handle exceptions other than unaligned exceptions
+ * - Does not handle exceptions during load into r17, r1, r0.
+ * - Does not handle exceptions during store from r17 (cannot be done) and r1 (slows down common case)
+ *
+ *  Relevant register structures
+ *        
+ *  EAR - |----|----|----|----|----|----|----|----|      
+ *      - <  ##   32 bit faulting address     ##  >      
+ *       
+ *  ESR - |----|----|----|----|----| - | - |-----|-----| 
+ *      -                            W   S   REG   EXC
+ *
+ *        
+ * STACK FRAME STRUCTURE
+ * ---------------------
+ *
+ *      +-------------+         + 0
+ *      |     MSR     |
+ *      +-------------+         + 4                
+ *      |     r1      |
+ *      |      .      |
+ *      |      .      |
+ *      |      .      |
+ *      |      .      |
+ *      |     r18     |
+ *      +-------------+         + 76
+ *      |      .      |
+ *      |      .      |        
+ */        
+
+         
+.global _hw_exception_handler                               
+.section .text                                          
+.align 4
+.ent _hw_exception_handler
+_hw_exception_handler:                      
+        addik   r1, r1, -(EX_HANDLER_STACK_SIZ);        /* Create stack frame */
+        PUSH_REG(3);              
+        PUSH_REG(4);              
+        PUSH_REG(5);              
+        PUSH_REG(6);
+        PUSH_REG(17); 
+        PUSH_MSR_AND_ENABLE_EXC;                        /* Exceptions enabled here. This will allow nested exceptions */
+                
+        mfs     r3, resr;    
+        andi    r5, r3, 0x1F;                           /* Extract ESR[EXC]                     */
+
+#if CONFIG_XILINX_MICROBLAZE0_UNALIGNED_EXCEPTIONS
+        xori    r6, r5, 1;                              /* 00001 = Unaligned Exception          */
+        beqi    r6, handle_unaligned_ex ;               /* Jump to unalignment exception handler*/
+#endif  
+
+#if (! (NO_OTHER_EXCEPTIONS))
+handle_other_ex:                                        /* Handle Other exceptions here         */        
+        ori     r6, r0, 6;
+        cmp     r6, r5, r6;                             /* >= 6 are unknown exceptions. Do not handle these */
+        blei    r6, ex_handler_done;
+
+        PUSH_REG(7);                                    /* Save other volatiles before we make procedure calls below   */
+        PUSH_REG(8);             
+        PUSH_REG(9);              
+        PUSH_REG(10);             
+        PUSH_REG(11);             
+        PUSH_REG(12);
+        PUSH_REG(15);
+        PUSH_REG(18);        
+
+        la      r4, r0, MB_ExceptionVectorTable;        /* Load the Exception vector table base address         */
+        addik   r5, r5, -1                              /* Interesting exception numbers start range from 1-5. 
+                                                           Convert to array index. */        
+        addk    r7, r5, r5;                             /* Calculate exception vector offset = r5 * 8           */
+        addk    r7, r7, r7;         
+        addk    r7, r7, r7;
+        addk    r7, r7, r4;                             /* Get pointer to exception vector               */
+        lwi     r6, r7, 4;                              /* Load argument to exception handler from table */
+        lw      r7, r7, r0;                             /* Load vector itself here                       */
+
+        brald   r15, r7;                                /* Branch to handler                             */
+        nop;
+        
+        POP_REG(7);                                     /* Restore other volatiles */
+        POP_REG(8);              
+        POP_REG(9);               
+        POP_REG(10);              
+        POP_REG(11);              
+        POP_REG(12);
+        POP_REG(15);
+        POP_REG(18);        
+#endif /* (! (NO_OTHER_EXCEPTIONS)) */
+
+#if CONFIG_XILINX_MICROBLAZE0_UNALIGNED_EXCEPTIONS
+        bri     ex_handler_done;                        /* Complete exception handling       */        
+handle_unaligned_ex:    
+        andi    r6, r3, 0x3E0;                          /* Mask and extract the register operand */
+        srl     r6, r6;                                 /* r6 >> 5 */
+        srl     r6, r6;
+        srl     r6, r6;
+        srl     r6, r6;
+        srl     r6, r6;
+        sbi     r6, r0, ex_reg_op;                      /* Store the register operand in a temporary location */
+        mfs     r4, rear;                              
+        andi    r6, r3, 0x400;                          /* Extract ESR[S]               */
+        bnei    r6, ex_sw;
+ex_lw:  
+        andi    r6, r3, 0x800;                          /* Extract ESR[W]               */
+        beqi    r6, ex_lhw;
+        lbui    r5, r4, 0;                              /* Exception address in r4      */
+        sbi     r5, r0, ex_tmp_data_loc_0;              /* Load a word, byte-by-byte from destination address and save it in tmp space  */              
+        lbui    r5, r4, 1;
+        sbi     r5, r0, ex_tmp_data_loc_1;
+        lbui    r5, r4, 2;
+        sbi     r5, r0, ex_tmp_data_loc_2;
+        lbui    r5, r4, 3;
+                sbi     r5, r0, ex_tmp_data_loc_3;
+        lwi     r3, r0, ex_tmp_data_loc_0;              /* Get the destination register value into r3   */
+        bri     ex_lw_tail;      
+ex_lhw: 
+        lbui    r5, r4, 0;                              /* Exception address in r4                      */
+        sbi     r5, r0, ex_tmp_data_loc_0;              /* Load a half-word, byte-by-byte from destination address and save it in tmp space */  
+        lbui    r5, r4, 1;                               
+        sbi     r5, r0, ex_tmp_data_loc_1;
+        lhui    r3, r0, ex_tmp_data_loc_0;              /* Get the destination register value into r3   */
+ex_lw_tail:
+        lbui    r5, r0, ex_reg_op;                      /* Get the destination register number into r5  */
+        la      r6, r0, lw_table;                       /* Form load_word jump table offset (lw_table + (8 * regnum)) */
+        addk    r5, r5, r5;                              
+        addk    r5, r5, r5;
+        addk    r5, r5, r5;
+        addk    r5, r5, r6;
+        bra     r5;
+ex_lw_end:                                              /* Exception handling of load word, ends */
+ex_sw:          
+        lbui    r5, r0, ex_reg_op;                      /* Get the destination register number into r5 */
+        la      r6, r0, sw_table;                       /* Form store_word jump table offset (sw_table + (8 * regnum)) */
+        add     r5, r5, r5;                             
+        add     r5, r5, r5;
+        add     r5, r5, r5;
+        add     r5, r5, r6;
+        bra     r5;
+ex_sw_tail:             
+        mfs     r6, resr;                               
+        andi    r6, r6, 0x800;                          /* Extract ESR[W]       */
+        beqi    r6, ex_shw;
+        swi     r3, r0, ex_tmp_data_loc_0;
+        lbui    r3, r0, ex_tmp_data_loc_0;              /* Store the word, byte-by-byte into destination address                */
+        sbi     r3, r4, 0;
+        lbui    r3, r0, ex_tmp_data_loc_1;
+        sbi     r3, r4, 1;
+        lbui    r3, r0, ex_tmp_data_loc_2;
+        sbi     r3, r4, 2;       
+        lbui    r3, r0, ex_tmp_data_loc_3;
+        sbi     r3, r4, 3;                      
+        bri     ex_handler_done;
+ex_shw:         
+        swi     r3, r0, ex_tmp_data_loc_0;              /* Store the lower half-word, byte-by-byte into destination address      */
+        lbui    r3, r0, ex_tmp_data_loc_2;
+        sbi     r3, r4, 0;
+        lbui    r3, r0, ex_tmp_data_loc_3;
+        sbi     r3, r4, 1;
+ex_sw_end:                                              /* Exception handling of store word, ends. */
+        
+#endif  /* CONFIG_MICROBLAZE0_UNALIGNED_EXCEPTIONS */
+                 
+ex_handler_done:
+        POP_MSR;
+        POP_REG(3);               
+        POP_REG(4);               
+        POP_REG(5);               
+        POP_REG(6); 
+        POP_REG(17); 
+        rted    r17, 0
+        addik   r1, r1, (EX_HANDLER_STACK_SIZ);         /* Restore stack frame  */        
+ex_handler_unhandled:   
+        bri 0                                           /* UNHANDLED. TRAP HERE */                                                 
+.end _hw_exception_handler  
+
+#if CONFIG_XILINX_MICROBLAZE0_UNALIGNED_EXCEPTIONS
+/* 
+ * hw_exception_handler Jump Table
+ * - Contains code snippets for each register that caused the unaligned exception.
+ * - Hence exception handler is NOT self-modifying
+ * - Separate table for load exceptions and store exceptions.
+ * - Each table is of size:   (8 * 32) = 256 bytes
+ */
+                
+.section .text
+.align  4
+lw_table:
+lw_r0:  R3_TO_LWREG   (0); 
+lw_r1:  LWREG_NOP;
+lw_r2:  R3_TO_LWREG   (2);
+lw_r3:  R3_TO_LWREG_V (3);
+lw_r4:  R3_TO_LWREG_V (4);
+lw_r5:  R3_TO_LWREG_V (5);
+lw_r6:  R3_TO_LWREG_V (6);
+lw_r7:  R3_TO_LWREG   (7);
+lw_r8:  R3_TO_LWREG   (8);
+lw_r9:  R3_TO_LWREG   (9);
+lw_r10: R3_TO_LWREG   (10);
+lw_r11: R3_TO_LWREG   (11);                             
+lw_r12: R3_TO_LWREG   (12);
+lw_r13: R3_TO_LWREG   (13);
+lw_r14: R3_TO_LWREG   (14);                                                     
+lw_r15: R3_TO_LWREG   (15);                                                     
+lw_r16: R3_TO_LWREG   (16);                                                     
+lw_r17: LWREG_NOP;
+lw_r18: R3_TO_LWREG   (18);                                                     
+lw_r19: R3_TO_LWREG   (19);                                                     
+lw_r20: R3_TO_LWREG   (20);                                                     
+lw_r21: R3_TO_LWREG   (21);
+lw_r22: R3_TO_LWREG   (22);
+lw_r23: R3_TO_LWREG   (23);                                                     
+lw_r24: R3_TO_LWREG   (24);                                                     
+lw_r25: R3_TO_LWREG   (25);                                                     
+lw_r26: R3_TO_LWREG   (26);                                                     
+lw_r27: R3_TO_LWREG   (27);                                                     
+lw_r28: R3_TO_LWREG   (28);                                                     
+lw_r29: R3_TO_LWREG   (29);                                                     
+lw_r30: R3_TO_LWREG   (30);
+lw_r31: R3_TO_LWREG   (31);
+
+sw_table:
+sw_r0:  SWREG_TO_R3   (0); 
+sw_r1:  SWREG_NOP;
+sw_r2:  SWREG_TO_R3   (2);
+sw_r3:  SWREG_TO_R3_V (3);
+sw_r4:  SWREG_TO_R3_V (4);
+sw_r5:  SWREG_TO_R3_V (5);
+sw_r6:  SWREG_TO_R3_V (6);
+sw_r7:  SWREG_TO_R3   (7);
+sw_r8:  SWREG_TO_R3   (8);
+sw_r9:  SWREG_TO_R3   (9);
+sw_r10: SWREG_TO_R3   (10);
+sw_r11: SWREG_TO_R3   (11);                             
+sw_r12: SWREG_TO_R3   (12);
+sw_r13: SWREG_TO_R3   (13);
+sw_r14: SWREG_TO_R3   (14);                                                     
+sw_r15: SWREG_TO_R3   (15);                                                     
+sw_r16: SWREG_TO_R3   (16);                                                     
+sw_r17: SWREG_NOP; 
+sw_r18: SWREG_TO_R3   (18);                                                     
+sw_r19: SWREG_TO_R3   (19);                                                     
+sw_r20: SWREG_TO_R3   (20);                                                     
+sw_r21: SWREG_TO_R3   (21);
+sw_r22: SWREG_TO_R3   (22);
+sw_r23: SWREG_TO_R3   (23);                                                     
+sw_r24: SWREG_TO_R3   (24);                                                     
+sw_r25: SWREG_TO_R3   (25);                                                     
+sw_r26: SWREG_TO_R3   (26);                                                     
+sw_r27: SWREG_TO_R3   (27);                                                     
+sw_r28: SWREG_TO_R3   (28);                                                     
+sw_r29: SWREG_TO_R3   (29);                                                     
+sw_r30: SWREG_TO_R3   (30);
+sw_r31: SWREG_TO_R3   (31);
+
+/* Temporary data structures used in the handler */
+.section .data
+.align 4
+ex_tmp_data_loc_0:      
+        .byte 0
+ex_tmp_data_loc_1:      
+        .byte 0
+ex_tmp_data_loc_2:      
+        .byte 0
+ex_tmp_data_loc_3:      
+        .byte 0                 
+ex_reg_op:
+        .byte 0
+#endif /* CONFIG_XILINX_MICROBLAZE0_UNALIGNED_EXCEPTIONS */
+        
+#else                                                   /* Dummy exception handler, in case exceptions are not present in the processor */
+
+.global _hw_exception_handler                               
+.section .text                                          
+.align 4
+.ent _hw_exception_handler
+_hw_exception_handler:
+        bri     0; 
+.end _hw_exception_handler        
+                                
+#endif  /* MICROBLAZE_EXCEPTIONS_ENABLED */
diff -urN linux-2.4.29/arch/microblaze/kernel/init_microblaze_timer.c linux-2.4.29-uc1/arch/microblaze/kernel/init_microblaze_timer.c
--- linux-2.4.29/arch/microblaze/kernel/init_microblaze_timer.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/init_microblaze_timer.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,51 @@
+/*
+ * arch.microblaze/kernel/microblaze_timer.c  - timer peripheral required in "base" mnicroblaze uClinux system
+ *
+ *  Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/kernel.h>
+
+#include <asm/microblaze_utils.h>
+#include <asm/microblaze_timer.h>
+
+/* Start interval timer TIMER (0-3).  The timer will issue the
+   corresponding INTCMD interrupt RATE times per second.
+   This function does not enable the interrupt.  */
+void nb85e_timer_d_configure (unsigned timer, unsigned rate)
+{
+	unsigned divlog2, count;
+
+	/* Calculate params for timer.  */
+	if (! calc_counter_params (
+		    cpu_clock_freq, rate,
+		    NB85E_TIMER_D_TMCD_CS_MIN, NB85E_TIMER_D_TMCD_CS_MAX, 16,
+		    &divlog2, &count))
+		printk (KERN_WARNING
+			"Cannot find interval timer %d setting suitable"
+			" for rate of %dHz.\n"
+			"Using rate of %ldHz instead.\n",
+			timer, rate, (cpu_clock_freq >> divlog2) >> 16);
+
+	/* Do the actual hardware timer initialization:  */
+
+	/* Enable timer.  */
+	NB85E_TIMER_D_TMCD(timer) = NB85E_TIMER_D_TMCD_CAE;
+	/* Set clock divider.  */
+	NB85E_TIMER_D_TMCD(timer)
+		= NB85E_TIMER_D_TMCD_CAE
+		| NB85E_TIMER_D_TMCD_CS(divlog2);
+	/* Set timer compare register.  */
+	NB85E_TIMER_D_CMD(timer) = count;
+	/* Start counting.  */
+	NB85E_TIMER_D_TMCD(timer)
+		= NB85E_TIMER_D_TMCD_CAE
+		| NB85E_TIMER_D_TMCD_CS(divlog2)
+		| NB85E_TIMER_D_TMCD_CE;
+}
diff -urN linux-2.4.29/arch/microblaze/kernel/intv.S linux-2.4.29-uc1/arch/microblaze/kernel/intv.S
--- linux-2.4.29/arch/microblaze/kernel/intv.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/intv.S	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,49 @@
+/*
+ * arch/microblaze/kernel/intv.S -- Interrupt vectors
+ *
+ *  Copyright (C) 2003	     John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by John Williams <jwilliams@itee.uq.edu.au>
+ */
+
+#include <asm/clinkage.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/entry.h>
+#include <asm/exceptions.h>
+
+	/* These are compiled and loaded into high memory, then
+	   copied into place in mach_early_setup */
+	.section	.intv.common, "ax"
+	.org	0x0
+	brai	C_SYMBOL_NAME(start);	// Kernel entry point
+
+	.org	0x08
+	brai	C_SYMBOL_NAME(trap);	// syscall handler
+
+	.org	0x10
+	brai	C_SYMBOL_NAME(irq);	// Interrupt handler
+
+	.org	0x18
+	brai	C_SYMBOL_NAME(nmi);	// nmi trap handler
+
+#if MICROBLAZE_EXCEPTIONS_ENABLED
+	/* This is tricky - we go under the linux radar, using 
+   	 * the hw exception handler from xilkernel 
+	 */
+	.org	0x20
+	brai	C_SYMBOL_NAME(_hw_exception_handler);	// HW exception handler
+#endif
+
+	.org	0x28
+	//brai	C_SYMBOL_NAME(mmu_ex);	// MMU exception
+
+	.org	0x30
+	brai	C_SYMBOL_NAME(dbtrap);	// debug trap handler
+
diff -urN linux-2.4.29/arch/microblaze/kernel/irq.c linux-2.4.29-uc1/arch/microblaze/kernel/irq.c
--- linux-2.4.29/arch/microblaze/kernel/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/irq.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,744 @@
+/*
+ * arch/microblaze/kernel/irq.c -- High-level interrupt handling
+ *
+ *  Copyright (C) 2003  John Williams <jwilliams@itee.uq.ed.au>
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 1994-2000  Ralf Baechle
+ *  Copyright (C) 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * This file was was derived from the mips version, arch/mips/kernel/irq.c
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+
+#include <asm/system.h>
+#include <asm/microblaze_intc.h>
+
+/*
+ * Controller mappings for all interrupt sources:
+ */
+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
+	{ [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
+
+/*
+ * Special irq handlers.
+ */
+
+void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+
+/*
+ * Generic no controller code
+ */
+
+static void enable_none(unsigned int irq) { }
+static unsigned int startup_none(unsigned int irq) { return 0; }
+static void disable_none(unsigned int irq) { }
+static void ack_none(unsigned int irq)
+{
+	/*
+	 * 'what should we do if we get a hw irq event on an illegal vector'.
+	 * each architecture has to answer this themselves, it doesnt deserve
+	 * a generic callback i think.
+	 */
+	printk("received IRQ %d with unknown interrupt type\n", irq);
+}
+
+/* startup is the same as "enable", shutdown is same as "disable" */
+#define shutdown_none	disable_none
+#define end_none	enable_none
+
+struct hw_interrupt_type no_irq_type = {
+	"none",
+	startup_none,
+	shutdown_none,
+	enable_none,
+	disable_none,
+	ack_none,
+	end_none
+};
+
+volatile unsigned long irq_err_count, spurious_count;
+
+/*
+ * Generic, controller-independent functions:
+ */
+
+int get_irq_list(char *buf)
+{
+	struct irqaction * action;
+	char *p = buf;
+	int i;
+
+	p += sprintf(p, "           ");
+	for (i=0; i < 1 /*smp_num_cpus*/; i++)
+		p += sprintf(p, "CPU%d       ", i);
+	*p++ = '\n';
+
+	for (i = 0 ; i < NR_IRQS ; i++) {
+		action = irq_desc[i].action;
+		if (!action) 
+			continue;
+		p += sprintf(p, "%3d: ",i);
+		p += sprintf(p, "%10u ", kstat_irqs(i));
+		p += sprintf(p, " %14s", irq_desc[i].handler->typename);
+		p += sprintf(p, "  %s", action->name);
+
+		for (action=action->next; action; action = action->next)
+			p += sprintf(p, ", %s", action->name);
+		*p++ = '\n';
+	}
+	p += sprintf(p, "ERR: %10lu\n", irq_err_count);
+	return p - buf;
+}
+
+/*
+ * This should really return information about whether
+ * we should do bottom half handling etc. Right now we
+ * end up _always_ checking the bottom half, which is a
+ * waste of time and is not what some drivers would
+ * prefer.
+ */
+int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
+{
+	int status;
+	int cpu = smp_processor_id();
+
+	irq_enter(cpu, irq);
+
+	status = 1;	/* Force the "do bottom halves" bit */
+
+	if (!(action->flags & SA_INTERRUPT))
+		__sti();
+
+	do {
+		status |= action->flags;
+		action->handler(irq, action->dev_id, regs);
+		action = action->next;
+	} while (action);
+
+	if (status & SA_SAMPLE_RANDOM)
+		add_interrupt_randomness(irq);
+
+	__cli();
+
+	irq_exit(cpu, irq);
+
+	return status;
+}
+
+/*
+ * Generic enable/disable code: this just calls
+ * down into the PIC-specific version for the actual
+ * hardware disable after having gotten the irq
+ * controller lock. 
+ */
+ 
+/**
+ *	disable_irq_nosync - disable an irq without waiting
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line. Disables of an interrupt
+ *	stack. Unlike disable_irq(), this function does not ensure existing
+ *	instances of the IRQ handler have completed before returning.
+ *
+ *	This function may be called from IRQ context.
+ */
+ 
+void inline disable_irq_nosync(unsigned int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	if (!desc->depth++) {
+		desc->status |= IRQ_DISABLED;
+		desc->handler->disable(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/**
+ *	disable_irq - disable an irq and wait for completion
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line. Disables of an interrupt
+ *	stack. That is for two disables you need two enables. This
+ *	function waits for any pending IRQ handlers for this interrupt
+ *	to complete before returning. If you use this function while
+ *	holding a resource the IRQ handler may need you will deadlock.
+ *
+ *	This function may be called - with care - from IRQ context.
+ */
+ 
+void disable_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+
+	if (!local_irq_count(smp_processor_id())) {
+		do {
+			barrier();
+		} while (irq_desc[irq].status & IRQ_INPROGRESS);
+	}
+}
+
+/**
+ *	enable_irq - enable interrupt handling on an irq
+ *	@irq: Interrupt to enable
+ *
+ *	Re-enables the processing of interrupts on this IRQ line
+ *	providing no disable_irq calls are now in effect.
+ *
+ *	This function may be called from IRQ context.
+ */
+ 
+void enable_irq(unsigned int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	switch (desc->depth) {
+	case 1: {
+		unsigned int status = desc->status & ~IRQ_DISABLED;
+		desc->status = status;
+		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+			desc->status = status | IRQ_REPLAY;
+			hw_resend_irq(desc->handler,irq);
+		}
+		desc->handler->enable(irq);
+		/* fall-through */
+	}
+	default:
+		desc->depth--;
+		break;
+	case 0:
+		printk("enable_irq(%u) unbalanced from %p\n", irq,
+		       __builtin_return_address(0));
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/* Handle interrupt IRQ.  REGS are the registers at the time of ther
+   interrupt.  */
+unsigned int handle_irq (int irq, struct pt_regs *regs)
+{
+	int cpu=smp_processor_id();
+	irq_desc_t *desc;
+	struct irqaction * action;
+	unsigned int status;
+
+	/* Note!  Microblaze processor doesn't provide irq number.
+	 * Thus. the irq param is invalid and must be ignored 
+	 * this handler must query the int controller itself! */
+
+	/* 
+	 * We ack quickly, we don't want the irq controller
+	 * thinking we're snobs just because some other CPU has
+	 * disabled global interrupts (we have already done the
+	 * INT_ACK cycles, it's too late to try to pretend to the
+	 * controller that we aren't taking the interrupt).
+	 *
+	 * 0 return value means that this irq is already being
+	 * handled by some other CPU. (or is disabled)
+	 */
+
+	/* 
+	 * Get active IRQ 
+	 * This is a bit low level to go in here, but the only
+	 * alternative is to query the intc in the assembly stub
+	 * in entry.S.
+	 */
+	irq = microblaze_intc_get_active_irq();
+
+	/* Grab the descriptor for this IRQ */
+	desc = irq_desc + irq;
+
+	kstat.irqs[cpu][irq]++;
+	spin_lock(&desc->lock);
+
+	/* This is to acknolwedge receipt of the IRQ.   In microblaze
+	   this is null - we don't wan't to ack until after handling.
+	   We do this in the handler->end(irq) call */
+	desc->handler->ack(irq);
+
+	/*
+	   REPLAY is when Linux resends an IRQ that was dropped earlier
+	   WAITING is used by probe to mark irqs that are being tested
+	   */
+	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
+	status |= IRQ_PENDING; /* we _want_ to handle it */
+
+	/*
+	 * If the IRQ is disabled for whatever reason, we cannot
+	 * use the action we have.
+	 */
+	action = NULL;
+	if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		action = desc->action;
+		status &= ~IRQ_PENDING; /* we commit to handling */
+		status |= IRQ_INPROGRESS; /* we are handling it */
+	}
+	desc->status = status;
+
+	/*
+	 * If there is no IRQ handler or it was disabled, exit early.
+	   Since we set PENDING, if another processor is handling
+	   a different instance of this same irq, the other processor
+	   will take care of it.
+	 */
+	if (!action)
+		goto out;
+
+	/*
+	 * Edge triggered interrupts need to remember
+	 * pending events.
+	 * This applies to any hw interrupts that allow a second
+	 * instance of the same irq to arrive while we are in handle_irq
+	 * or in the handler. But the code here only handles the _second_
+	 * instance of the irq, not the third or fourth. So it is mostly
+	 * useful for irq hardware that does not mask cleanly in an
+	 * SMP environment.
+	 */
+	for (;;) {
+		spin_unlock(&desc->lock);
+		handle_IRQ_event(irq, regs, action);
+		spin_lock(&desc->lock);
+		
+		if (!(desc->status & IRQ_PENDING))
+			break;
+		desc->status &= ~IRQ_PENDING;
+	}
+	desc->status &= ~IRQ_INPROGRESS;
+out:
+	/*
+	 * The ->end() handler has to deal with interrupts which got
+	 * disabled while the handler was running.
+	 */
+
+	desc->handler->end(irq);
+	spin_unlock(&desc->lock);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+
+	return 1;
+}
+
+/**
+ *	request_irq - allocate an interrupt line
+ *	@irq: Interrupt line to allocate
+ *	@handler: Function to be called when the IRQ occurs
+ *	@irqflags: Interrupt type flags
+ *	@devname: An ascii name for the claiming device
+ *	@dev_id: A cookie passed back to the handler function
+ *
+ *	This call allocates interrupt resources and enables the
+ *	interrupt line and IRQ handling. From the point this
+ *	call is made your handler function may be invoked. Since
+ *	your handler function must clear any interrupt the board 
+ *	raises, you must take care both to initialise your hardware
+ *	and to set up the interrupt handler in the right order.
+ *
+ *	Dev_id must be globally unique. Normally the address of the
+ *	device data structure is used as the cookie. Since the handler
+ *	receives this value it makes sense to use it.
+ *
+ *	If your interrupt is shared you must pass a non NULL dev_id
+ *	as this is required when freeing the interrupt.
+ *
+ *	Flags:
+ *
+ *	SA_SHIRQ		Interrupt is shared
+ *
+ *	SA_INTERRUPT		Disable local interrupts while processing
+ *
+ *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
+ *
+ */
+ 
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
+{
+	int retval;
+	struct irqaction * action;
+
+#if 1
+	/*
+	 * Sanity-check: shared interrupts should REALLY pass in
+	 * a real dev-ID, otherwise we'll have trouble later trying
+	 * to figure out which interrupt is which (messes up the
+	 * interrupt freeing logic etc).
+	 */
+	if (irqflags & SA_SHIRQ) {
+		if (!dev_id)
+			printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]);
+	}
+#endif
+
+	if (irq >= NR_IRQS)
+		return -EINVAL;
+	if (!handler)
+		return -EINVAL;
+
+	action = (struct irqaction *)
+			kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = 0;
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_irq(irq, action);
+	if (retval)
+		kfree(action);
+	return retval;
+}
+
+/**
+ *	free_irq - free an interrupt
+ *	@irq: Interrupt line to free
+ *	@dev_id: Device identity to free
+ *
+ *	Remove an interrupt handler. The handler is removed and if the
+ *	interrupt line is no longer in use by any driver it is disabled.
+ *	On a shared IRQ the caller must ensure the interrupt is disabled
+ *	on the card it drives before calling this function. The function
+ *	does not return until any executing interrupts for this IRQ
+ *	have completed.
+ *
+ *	This function may be called from interrupt context. 
+ *
+ *	Bugs: Attempting to free an irq in a handler for the same irq hangs
+ *	      the machine.
+ */
+ 
+void free_irq(unsigned int irq, void *dev_id)
+{
+	irq_desc_t *desc;
+	struct irqaction **p;
+	unsigned long flags;
+
+	if (irq >= NR_IRQS)
+		return;
+
+	desc = irq_desc + irq;
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
+	for (;;) {
+		struct irqaction * action = *p;
+		if (action) {
+			struct irqaction **pp = p;
+			p = &action->next;
+			if (action->dev_id != dev_id)
+				continue;
+
+			/* Found it - now remove it from the list of entries */
+			*pp = action->next;
+			if (!desc->action) {
+				desc->status |= IRQ_DISABLED;
+				desc->handler->shutdown(irq);
+			}
+			spin_unlock_irqrestore(&desc->lock,flags);
+
+#ifdef CONFIG_SMP
+			/* Wait to make sure it's not being used on another CPU */
+			while (desc->status & IRQ_INPROGRESS)
+				barrier();
+#endif
+			kfree(action);
+			return;
+		}
+		printk("Trying to free free IRQ%d\n",irq);
+		spin_unlock_irqrestore(&desc->lock,flags);
+		return;
+	}
+}
+
+/*
+ * IRQ autodetection code..
+ *
+ * This depends on the fact that any interrupt that
+ * comes in on to an unassigned handler will get stuck
+ * with "IRQ_WAITING" cleared and the interrupt
+ * disabled.
+ */
+
+static DECLARE_MUTEX(probe_sem);
+
+/**
+ *	probe_irq_on	- begin an interrupt autodetect
+ *
+ *	Commence probing for an interrupt. The interrupts are scanned
+ *	and a mask of potential interrupt lines is returned.
+ *
+ */
+ 
+unsigned long probe_irq_on(void)
+{
+	unsigned int i;
+	irq_desc_t *desc;
+	unsigned long val;
+	unsigned long delay;
+
+	down(&probe_sem);
+	/* 
+	 * something may have generated an irq long ago and we want to
+	 * flush such a longstanding irq before considering it as spurious. 
+	 */
+	for (i = NR_IRQS-1; i > 0; i--)  {
+		desc = irq_desc + i;
+
+		spin_lock_irq(&desc->lock);
+		if (!irq_desc[i].action) 
+			irq_desc[i].handler->startup(i);
+		spin_unlock_irq(&desc->lock);
+	}
+
+	/* Wait for longstanding interrupts to trigger. */
+	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
+		/* about 20ms delay */ synchronize_irq();
+
+	/*
+	 * enable any unassigned irqs
+	 * (we must startup again here because if a longstanding irq
+	 * happened in the previous stage, it may have masked itself)
+	 */
+	for (i = NR_IRQS-1; i > 0; i--) {
+		desc = irq_desc + i;
+
+		spin_lock_irq(&desc->lock);
+		if (!desc->action) {
+			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
+			if (desc->handler->startup(i))
+				desc->status |= IRQ_PENDING;
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	/*
+	 * Wait for spurious interrupts to trigger
+	 */
+	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
+		/* about 100ms delay */ synchronize_irq();
+
+	/*
+	 * Now filter out any obviously spurious interrupts
+	 */
+	val = 0;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			/* It triggered already - consider it spurious. */
+			if (!(status & IRQ_WAITING)) {
+				desc->status = status & ~IRQ_AUTODETECT;
+				desc->handler->shutdown(i);
+			} else
+				if (i < 32)
+					val |= 1 << i;
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	return val;
+}
+
+/*
+ * Return a mask of triggered interrupts (this
+ * can handle only legacy ISA interrupts).
+ */
+ 
+/**
+ *	probe_irq_mask - scan a bitmap of interrupt lines
+ *	@val:	mask of interrupts to consider
+ *
+ *	Scan the ISA bus interrupt lines and return a bitmap of
+ *	active interrupts. The interrupt probe logic state is then
+ *	returned to its previous value.
+ *
+ *	Note: we need to scan all the irq's even though we will
+ *	only return ISA irq numbers - just so that we reset them
+ *	all to a known state.
+ */
+unsigned int probe_irq_mask(unsigned long val)
+{
+	int i;
+	unsigned int mask;
+
+	mask = 0;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			if (i < 16 && !(status & IRQ_WAITING))
+				mask |= 1 << i;
+
+			desc->status = status & ~IRQ_AUTODETECT;
+			desc->handler->shutdown(i);
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+	up(&probe_sem);
+
+	return mask & val;
+}
+
+/*
+ * Return the one interrupt that triggered (this can
+ * handle any interrupt source).
+ */
+
+/**
+ *	probe_irq_off	- end an interrupt autodetect
+ *	@val: mask of potential interrupts (unused)
+ *
+ *	Scans the unused interrupt lines and returns the line which
+ *	appears to have triggered the interrupt. If no interrupt was
+ *	found then zero is returned. If more than one interrupt is
+ *	found then minus the first candidate is returned to indicate
+ *	their is doubt.
+ *
+ *	The interrupt probe logic state is returned to its previous
+ *	value.
+ *
+ *	BUGS: When used in a module (which arguably shouldnt happen)
+ *	nothing prevents two IRQ probe callers from overlapping. The
+ *	results of this are non-optimal.
+ */
+ 
+int probe_irq_off(unsigned long val)
+{
+	int i, irq_found, nr_irqs;
+
+	nr_irqs = 0;
+	irq_found = 0;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			if (!(status & IRQ_WAITING)) {
+				if (!nr_irqs)
+					irq_found = i;
+				nr_irqs++;
+			}
+			desc->status = status & ~IRQ_AUTODETECT;
+			desc->handler->shutdown(i);
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+	up(&probe_sem);
+
+	if (nr_irqs > 1)
+		irq_found = -irq_found;
+	return irq_found;
+}
+
+/* this was setup_x86_irq but it seems pretty generic */
+int setup_irq(unsigned int irq, struct irqaction * new)
+{
+	int shared = 0;
+	unsigned long flags;
+	struct irqaction *old, **p;
+	irq_desc_t *desc = irq_desc + irq;
+	
+	/*
+	 * Some drivers like serial.c use request_irq() heavily,
+	 * so we have to be careful not to interfere with a
+	 * running system.
+	 */
+	if (new->flags & SA_SAMPLE_RANDOM) {
+		/*
+		 * This function might sleep, we want to call it first,
+		 * outside of the atomic block.
+		 * Yes, this might clear the entropy pool if the wrong
+		 * driver is attempted to be loaded, without actually
+		 * installing a new handler, but is this really a problem,
+		 * only the sysadmin is able to do this.
+		 */
+		rand_initialize_irq(irq);
+	}
+
+	/*
+	 * The following block of code has to be executed atomically
+	 */
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
+	if ((old = *p) != NULL) {
+		/* Can't share interrupts unless both agree to */
+		if (!(old->flags & new->flags & SA_SHIRQ)) {
+			spin_unlock_irqrestore(&desc->lock,flags);
+			return -EBUSY;
+		}
+
+		/* add new interrupt at end of irq queue */
+		do {
+			p = &old->next;
+			old = *p;
+		} while (old);
+		shared = 1;
+	}
+
+	*p = new;
+
+	if (!shared) {
+		desc->depth = 0;
+		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
+		desc->handler->startup(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock,flags);
+
+	/* register_irq_proc(irq); */
+	return 0;
+}
+
+/* Initialize irq handling for IRQs BASE to BASE+NUM-1.  */
+void __init
+init_irq_handlers (int base_irq, int num, struct hw_interrupt_type *irq_type)
+{
+	while (num-- > 0) {
+		irq_desc[base_irq].status  = IRQ_DISABLED;
+		irq_desc[base_irq].action  = NULL;
+		irq_desc[base_irq].depth   = 1;
+		irq_desc[base_irq].handler = irq_type;
+		base_irq++;
+	}
+}
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
+void init_irq_proc(void)
+{
+}
+#endif
+
diff -urN linux-2.4.29/arch/microblaze/kernel/mach.c linux-2.4.29-uc1/arch/microblaze/kernel/mach.c
--- linux-2.4.29/arch/microblaze/kernel/mach.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/mach.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * arch/v850/kernel/mach.c -- Defaults for some things defined by "mach.h"
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include "mach.h"
+
+/* Called with each timer tick, if non-zero.  */
+void (*mach_tick)(void) = 0;
diff -urN linux-2.4.29/arch/microblaze/kernel/mach.h linux-2.4.29-uc1/arch/microblaze/kernel/mach.h
--- linux-2.4.29/arch/microblaze/kernel/mach.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/mach.h	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,60 @@
+/*
+ * arch/microblaze/kernel/mach.h -- Machine-dependent functions used by Microblaze port
+ *
+ *  Copyright (C) 2003	     John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#ifndef __MICROBLAZE_MACH_H__
+#define __MICROBLAZE_MACH_H__
+
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+
+#include <asm/ptrace.h>
+#include <asm/entry.h>
+#include <asm/clinkage.h>
+
+#define DEBUG_MSG printk(KERN_INFO "%s:%s:%s\n",__FILE__,__FUNCTION__, __LINE__)
+
+void mach_heartbeat(unsigned int value);
+void mach_setup (char **cmdline);
+void mach_gettimeofday (struct timeval *tv);
+unsigned long mach_gettimeoffset(void);
+void mach_sched_init (struct irqaction *timer_action);
+void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len);
+void mach_init_irqs (void);
+
+/* If defined, is called very early in the kernel initialization.  The
+   stack pointer is valid, but very little has been initialized (e.g.,
+   bss is not zeroed yet) when this is called, so care must taken.  */
+void mach_early_init (void);
+
+/* If defined, called after the bootmem allocator has been initialized,
+   to allow the platform-dependent code to reserve any areas of RAM that
+   the kernel shouldn't touch.  */
+void mach_reserve_bootmem (void) __attribute__ ((__weak__));
+
+/* Called with each timer tick, if non-zero.  */
+extern void (*mach_tick) (void);
+
+/* The following establishes aliases for various mach_ functions to the
+   name by which the rest of the kernal calls them.  These statements
+   should only have an effect in the file that defines the actual functions. */
+#define MACH_ALIAS(to, from)						      \
+   asm (".global " macrology_stringify (C_SYMBOL_NAME (to)) ";"		      \
+	macrology_stringify (C_SYMBOL_NAME (to))			      \
+	" = " macrology_stringify (C_SYMBOL_NAME (from)))
+/* e.g.: MACH_ALIAS (kernel_name,	arch_spec_name);  */
+
+#endif /* __MICROBLAZE_MACH_H__ */
diff -urN linux-2.4.29/arch/microblaze/kernel/Makefile linux-2.4.29-uc1/arch/microblaze/kernel/Makefile
--- linux-2.4.29/arch/microblaze/kernel/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/Makefile	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,60 @@
+#
+# arch/microblaze/kernel/Makefile
+#
+#  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+#  Copyright (C) 2001,2002  NEC Corporation
+#  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+EXTRA_CFLAGS		+= -I$(TOPDIR)/arch/microblaze/xilinx_ocp
+
+all: head.o kernel.o
+
+USE_STANDARD_AS_RULE	:= true
+
+O_TARGET := kernel.o
+
+ifdef PLATFORM
+obj-y := process.o syscalls.o time.o semaphore.o \
+	signal.o irq.o ptrace.o bug.o hw_exception_handler.o \
+	exceptions.o
+else
+obj-y := intv.o entry.o process.o syscalls.o time.o semaphore.o setup.o \
+	 signal.o irq.o mach.o ptrace.o bug.o hw_exception_handler.o \
+	exceptions.o
+endif
+
+obj-y				+= microblaze_intc.o microblaze_timer.o 
+
+export-objs := microblaze_ksyms.o 
+
+obj-$(CONFIG_MODULES)		+= microblaze_ksyms.o
+# chip-specific code
+
+ifdef CONFIG_XILINX_UARTLITE_0_INSTANCE
+	obj-y += xmbserial.o
+endif
+
+# platform-specific code
+obj-$(CONFIG_MBVANILLA)		+= mbvanilla.o 
+obj-$(CONFIG_MBEGRET01)		+= mbegret.o
+# feature-specific code
+obj-$(CONFIG_PROC_FS)		+= procfs.o
+
+head.o: head.S microblaze_defs.h
+entry.o: entry.S microblaze_defs.h
+
+microblaze_defs.h: microblaze_defs.c microblaze_defs.head
+	rm -f microblaze_defs.d
+	SUNPRO_DEPENDENCIES="microblaze_defs.d microblaze_defs.h" \
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S microblaze_defs.c
+	cp microblaze_defs.head microblaze_defs.h
+	grep '^#define' microblaze_defs.s >> microblaze_defs.h
+	rm microblaze_defs.s
+-include microblaze_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/microblaze/kernel/mbvanilla.c linux-2.4.29-uc1/arch/microblaze/kernel/mbvanilla.c
--- linux-2.4.29/arch/microblaze/kernel/mbvanilla.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/mbvanilla.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,303 @@
+/*
+ * arch/microblaze/kernel/mbvanilla.h -- Machine-dependent defs for
+ *	"vanillia" Microblaze system
+ *
+ *  Copyright (C) 2003	John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+#include <asm/bitops.h>
+
+/* Get base address definitions for core peripherals */
+#include <asm/mbvanilla.h>
+
+/* Declarations of core setup functions */
+#include "mach.h"
+
+/* Get header files for the peripherals */
+#include <asm/microblaze_timer.h>
+#include <asm/microblaze_intc.h>
+#include <asm/microblaze_gpio.h>
+
+/* for 2.6, include asm-generic/sections.h */
+extern char __bss_start[], __bss_stop[];
+
+#define RAM_START (ERAM_ADDR)
+#define RAM_END ((ERAM_ADDR)+(ERAM_SIZE))
+
+extern void memcons_setup (void);
+extern void xmbrs_console_init(void);
+
+
+#define REG_DUMP_ADDR		0x220000
+
+
+extern struct irqaction reg_snap_action; /* fwd decl */
+
+/* Function to drive one of the LED segments */
+void mach_heartbeat(unsigned int value)
+{
+	/* 
+	 * FIXME Strictly speaking this should probably be 
+	 * protected by a semaphore 
+	 */
+
+	/* Read current value on the port */
+	volatile unsigned int cur_val = microblaze_gpio_read(MICROBLAZE_GPIO_BASE_ADDR);
+
+	/* Clear LED bit  */
+	cur_val &= ~0x00010000;
+
+	/* Set it if required */
+	if(value)
+		cur_val |=  0x00010000;
+	
+	microblaze_gpio_write(MICROBLAZE_GPIO_BASE_ADDR,cur_val);
+}
+
+/* mach_gettimeoffset returns the number of microseconds elapsed since the
+   start of the current tick */
+unsigned long mach_gettimeoffset(void)
+{
+	unsigned long tctr=timer_get_time(CONFIG_XILINX_TIMER_0_BASEADDR,0);
+	unsigned long tcmp=timer_get_compare(CONFIG_XILINX_TIMER_0_BASEADDR,0);
+	unsigned long offset;
+
+	/*
+	 * Timer used in count up mode, so subtract load value from
+	 * counter register to get elapsed ticks */
+	offset = (tctr-tcmp)/(CONFIG_XILINX_CPU_CLOCK_FREQ/1000000);
+
+	/*
+	 * If we are still in the first half of the upcount and a
+	 * timer interupt is pending, then add on a tick's worth of time.
+	 */
+
+	if (((offset * 2) < (1000000/HZ)) && 
+		(timer_get_csr(CONFIG_XILINX_TIMER_0_BASEADDR,0)&TIMER_INTERRUPT))
+	{
+		offset += 1000000/HZ;
+	}
+
+	return offset;
+}
+
+/* mach_early_init() is called very early, after the kernel stack and SDA 
+   pointers are configured, but before BSS/SBSS are zeroed etc.  Be careful 
+   what you do in here.  The bss and sbss sections are zeroed in here */
+void __init mach_early_init (void)
+{
+	int i;
+	unsigned int *src, *dst;
+	unsigned int len;
+
+	extern unsigned char _ssbss, _esbss;
+	extern unsigned int _intv_load_end, _intv_load_start;
+	extern unsigned int _ramstart;
+
+	/* Copy interrupt vectors from high memory down to where
+	   they belong. */
+	dst = (unsigned int *)0x0;		
+	src = (unsigned int *)&_intv_load_start;
+
+#if 1	/* JW don't overwrite reset vector */
+	src++;
+	src++;
+	dst++;
+	dst++;
+#endif
+	do {
+		*(dst++) = *(src++);
+	} while (src < &_intv_load_end);
+
+	/* Copy ROMFS above bss */
+	src = (unsigned int *)__bss_start;
+	len = src[2];    /* Bytes to words, round up */
+
+	/* Use memmove to handle likely case of memory overlap */
+	memmove(__bss_stop,__bss_start,len);
+
+        _ramstart = (unsigned long)__bss_stop + len;
+	
+	/* Zero the BSS and SBSS sections */
+	memset(__bss_start,0,__bss_stop-__bss_start);
+	memset(&_ssbss,0,&_esbss-&_ssbss);
+
+}
+
+/* Reserve memory where the root_fs is stored.  
+ * Used when blkmem is the underlying driver, and the symbols
+ * _root_fs_image_start and _end are defined as the bounds of 
+ * the romfs image */
+#if 0
+void __init reserve_blkmem_root_fs(void)
+{
+	extern char _root_fs_image_start, _root_fs_image_end;
+	u32 root_fs_image_start = (u32)&_root_fs_image_start;
+	u32 root_fs_image_end = (u32)&_root_fs_image_end;
+
+	if(root_fs_image_start >= RAM_START && root_fs_image_start < RAM_END)
+	{
+		#ifdef CONFIG_MICROBLAZE_DEBUGGING
+	 	printk("ROMFS (on blkmem):%08X -> %08X (%08X)\n",root_fs_image_start, root_fs_image_end, root_fs_image_end - root_fs_image_start); 
+		#endif
+		reserve_bootmem(root_fs_image_start,
+				root_fs_image_end - root_fs_image_start);
+	}
+	
+}
+#endif
+
+/* Reserve memory where the root_fs is stored.
+ * Used when MTD ram_map is the underlying driver, and
+ * the romfs image is tacked on at __bss_stop, and its length
+ * is derived from the romfs image itself */
+void __init reserve_mtd_ram_root_fs(void)
+{
+	u32 root_fs_image_start = (u32)__bss_stop;
+	u32 root_fs_image_len = ((u32 *)root_fs_image_start)[2];
+
+	if(root_fs_image_start >= RAM_START && root_fs_image_start < RAM_END)
+	{
+		#ifdef CONFIG_MICROBLAZE_DEBUGGING
+	 	printk("ROMFS (on mtd):%08X -> %08X (%08X)\n",root_fs_image_start, root_fs_image_start + root_fs_image_len, root_fs_image_len); 
+		#endif
+		reserve_bootmem(root_fs_image_start,
+				root_fs_image_len);
+	}
+	
+}
+
+void __init mach_reserve_bootmem(void)
+{
+	/* FIXME need a CONFIG_something here to determine which memory
+	   driver is carrying the rootfs */
+	#if 0
+		reserve_blkmem_root_fs();
+		reserve_mtd_ram_root_fs();
+	#endif
+}
+
+void __init mach_setup (char **cmdline)
+{
+	/* Enable the instruction and data caches (if present) */
+	#if CONFIG_XILINX_MICROBLAZE0_USE_ICACHE==1
+	__enable_icache();
+	#endif
+
+	#if CONFIG_XILINX_MICROBLAZE0_USE_DCACHE==1
+	__enable_dcache();
+	#endif
+
+	printk (KERN_INFO "CPU: MICROBLAZE\n");
+
+	/* memcons_setup (); */
+	/* This is defined as an initcall, but doesn't seem to work...*/
+	xmbrs_console_init(); 
+	
+	/* 
+	 * Enable master control on interrupt controller.  Note
+         * this does not enable interrupts in the processor, nor 
+	 * does it enable individual IRQs on the controller.  Just
+         * initialises the intc in preparation for these things */
+	microblaze_intc_master_enable();
+
+	/* Configure the GPIO */
+	/* 8 inputs, 16 outputs */
+	microblaze_gpio_setdir(MICROBLAZE_GPIO_BASE_ADDR,MICROBLAZE_GPIO_DIR);
+}
+
+void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len)
+{
+	*ram_start = ERAM_ADDR;
+	*ram_len = ERAM_SIZE;
+}
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* Initialise timer */
+	microblaze_timer_configure(0,HZ);
+
+	/* And install timer interrupt handler at appropriate vector */
+
+	/* Timer is always attached to interrupt 0 (highest priority) */
+	/* Note we use setup_irq rather than request_irq */
+	setup_irq (CONFIG_XILINX_TIMER_0_IRQ, timer_action);
+}
+
+
+void mach_gettimeofday (struct timeval *tv)
+{
+	tv->tv_sec = 0;
+	tv->tv_usec = 0;
+}
+
+void machine_halt (void) __attribute__ ((noreturn));
+void machine_halt (void)
+{
+	for (;;) {
+		/* Following code should disable interrupts */
+		asm ("nop; nop; nop; nop; nop");
+	}
+}
+
+void machine_restart (char *__unused)
+{
+	machine_halt ();
+}
+
+void machine_power_off (void)
+{
+	machine_halt ();
+}
+
+
+/* Interrupts */
+
+/* Data to initialise interrupt controller functionality */
+struct microblaze_intc_irq_init irq_inits[] = {
+	/* Name, base, num, priority (unused in microblaze) */
+	{ "XINTC", 0, NUM_MACH_IRQS,	7 },
+	{ 0 }
+};
+#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
+
+struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
+
+/* Initialize interrupts.  */
+void __init mach_init_irqs (void)
+{
+	microblaze_intc_init_irq_types (irq_inits, hw_itypes);
+}
+
+
+/* An interrupt handler that copies the registers to a known memory location,
+   for debugging purposes.  */
+
+#if 0
+static void make_reg_snap (int irq, void *dummy, struct pt_regs *regs)
+{
+	(*(unsigned *)REG_DUMP_ADDR)++;
+	(*(struct pt_regs *)(REG_DUMP_ADDR + sizeof (unsigned))) = *regs;
+}
+
+static int reg_snap_dev_id;
+static struct irqaction reg_snap_action = {
+	make_reg_snap, 0, 0, "reg_snap", &reg_snap_dev_id, 0
+};
+#endif
diff -urN linux-2.4.29/arch/microblaze/kernel/memcons.c linux-2.4.29-uc1/arch/microblaze/kernel/memcons.c
--- linux-2.4.29/arch/microblaze/kernel/memcons.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/memcons.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,199 @@
+/*
+ * arch/v850/kernel/memcons.c -- Console I/O to a memory buffer
+ *
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/init.h>
+
+#include <asm/xuartlite_l.h>
+#include <asm/xparameters.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/signal.h>
+
+/* Spinlock protecting memcons_offs.  */
+static spinlock_t memcons_lock = SPIN_LOCK_UNLOCKED;
+
+/* Hacked by JW to outoput directly to the debug console - see what happens! */
+
+static size_t write (const char *buf, size_t len)
+{
+	size_t old_len;
+	int flags;
+	char *point;
+
+	volatile char *uart_write = (char *)0xFFFF2004;
+
+	old_len=len;
+
+	/* Dump to UART console */
+	/* Evil, but I'm going to cli() for this lot */
+	save_flags_cli(flags);
+	
+	while(old_len)
+	{
+		volatile unsigned int *uart_status = (unsigned int *)0xFFFF2008;
+		#define TX_FIFO_FULL (1<<3)
+
+		/* Make sure FIFO isn't full */
+		while((*uart_status) & TX_FIFO_FULL)
+			;
+
+		/* Write the characters */
+		*uart_write=*buf;
+		/* Send CR if necessary */
+
+		if(*buf=='\n')
+		{
+			/* Again, make sure FIFO isn't full */
+			while((*uart_status) & TX_FIFO_FULL)
+				;
+
+			*uart_write=0x0d;
+		}
+		buf++;
+		old_len--;
+	}
+
+	restore_flags(flags);
+
+	return len;
+}
+
+
+/*  Low-level console. */
+
+static void memcons_write (struct console *co, const char *buf, unsigned len)
+{
+	while (len > 0)
+		len -= write (buf, len);
+}
+
+static kdev_t memcons_device (struct console *co)
+{
+        return MKDEV (TTY_MAJOR, 64 + co->index);
+}
+
+static struct console memcons =
+{
+    name:	"memcons",
+    write:	memcons_write,
+    device:	memcons_device,
+    flags:	CON_PRINTBUFFER,
+    index:	-1,
+};
+
+void memcons_setup (void)
+{
+	register_console (&memcons);
+	printk (KERN_INFO "Console: static memory buffer (memcons)\n");
+}
+
+/* Higher level TTY interface.  */
+
+static struct tty_struct *tty_table[1] = { 0 };
+static struct termios *tty_termios[1] = { 0 };
+static struct termios *tty_termios_locked[1] = { 0 };
+static struct tty_driver tty_driver = { 0 };
+static int tty_ref_count = 0;
+
+int memcons_tty_open (struct tty_struct *tty, struct file *filp)
+{
+	return 0;
+}
+
+int memcons_tty_write (struct tty_struct *tty, int from_user,
+		       const unsigned char *buf, int len)
+{
+	return write (buf, len);
+}
+
+int memcons_tty_write_room (struct tty_struct *tty)
+{
+	/* I think this is the amount of room in the buffer */
+	return 16;
+}
+
+int memcons_tty_chars_in_buffer (struct tty_struct *tty)
+{
+	/* We have no buffer.  */
+	return 0;
+}
+
+/* This is the interrupt handler for the memcons console.  It's gross
+   but it may actually work one day */
+void memcons_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* Determine reason for interrupt */
+	unsigned int status = XUartLitE_mGetStatusReg(XPAR_CONSOLE_UART_BASEADDR);
+
+	
+	
+	printk("UART interrupt on IRQ %i!\n",irq);
+}
+
+/* Initialise IRQ handling for console_uart.  IRQ number (1) is hard coded.
+   This is all gross and dodgy but i want to get it working */
+void memcons_irqinit(void)
+{
+	unsigned int flags;
+	unsigned int uart_control;
+
+	#define CONSOLE_UART_IRQ 1
+
+	printk("memcons: Requesting IRQ\n");
+
+	/* Disable uart interrupts so no nasty surprises */
+	XUartLite_mDisableIntr(XPAR_CONSOLE_UART_BASEADDR);
+
+	if(request_irq(CONSOLE_UART_IRQ, memcons_interrupt, SA_INTERRUPT,
+			"console UART", NULL))
+	{
+		printk("memcons.c: Unable to attach memcons interrupt to IRQ %i\n", CONSOLE_UART_IRQ);
+	}
+	else
+		XUartLite_mEnableIntr(XPAR_CONSOLE_UART_BASEADDR);
+}
+
+int __init memcons_tty_init (void)
+{
+	unsigned int flags;
+
+	printk("Registering memcons serial driver.\n");
+	tty_driver.name = "memcons";
+	tty_driver.major = TTY_MAJOR;
+	tty_driver.minor_start = 64;
+	tty_driver.num = 1;
+	tty_driver.type = TTY_DRIVER_TYPE_SYSCONS;
+
+	tty_driver.refcount = &tty_ref_count;
+
+	tty_driver.table = tty_table;
+	tty_driver.termios = tty_termios;
+	tty_driver.termios_locked = tty_termios_locked;
+
+	tty_driver.init_termios = tty_std_termios;
+
+	tty_driver.open = memcons_tty_open;
+	tty_driver.write = memcons_tty_write;
+	tty_driver.write_room = memcons_tty_write_room;
+	tty_driver.chars_in_buffer = memcons_tty_chars_in_buffer;
+
+	tty_register_driver (&tty_driver);
+
+	memcons_irqinit();
+	
+}
+__initcall (memcons_tty_init);
diff -urN linux-2.4.29/arch/microblaze/kernel/microblaze.c linux-2.4.29-uc1/arch/microblaze/kernel/microblaze.c
--- linux-2.4.29/arch/microblaze/kernel/microblaze.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/microblaze.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ * arch/microblaze/kernel/microblaze.c -- Machine-specific code for microblaze CPU
+ *
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+
+#include "mach.h"
+
+unsigned long cpu_clock_freq = CONFIG_XILINX_CPU_CLOCK_FREQ;
diff -urN linux-2.4.29/arch/microblaze/kernel/microblaze_defs.c linux-2.4.29-uc1/arch/microblaze/kernel/microblaze_defs.c
--- linux-2.4.29/arch/microblaze/kernel/microblaze_defs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/microblaze_defs.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,61 @@
+/*
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ */
+
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/irq.h>
+#include <asm/hardirq.h>
+#include <asm/errno.h>
+
+#define DEFINE(sym, val) \
+	asm volatile ("\n#define " #sym " %0" : : "i" (val))
+
+int main (void)
+{
+	/* offsets into the task struct */
+	DEFINE (TASK_STATE, offsetof (struct task_struct, state));
+	DEFINE (TASK_FLAGS, offsetof (struct task_struct, flags));
+	DEFINE (TASK_PTRACE, offsetof (struct task_struct, ptrace));
+	DEFINE (TASK_BLOCKED, offsetof (struct task_struct, blocked));
+	DEFINE (TASK_COUNTER, offsetof (struct task_struct, counter));
+	DEFINE (TASK_SIGPENDING, offsetof (struct task_struct, sigpending));
+	DEFINE (TASK_NEED_RESCHED, offsetof (struct task_struct, need_resched));
+	DEFINE (TASK_THREAD, offsetof (struct task_struct, thread));
+	DEFINE (TASK_MM, offsetof (struct task_struct, mm));
+	DEFINE (TASK_ACTIVE_MM, offsetof (struct task_struct, active_mm));
+	DEFINE (TASK_PID, offsetof (struct task_struct, pid));
+
+	/* offsets into the kernel_stat struct */
+	DEFINE (STAT_IRQ, offsetof (struct kernel_stat, irqs));
+
+
+	/* signal defines */
+	DEFINE (SIGSEGV, SIGSEGV);
+	DEFINE (SEGV_MAPERR, SEGV_MAPERR);
+	DEFINE (SIGTRAP, SIGTRAP);
+	DEFINE (SIGCHLD, SIGCHLD);
+	DEFINE (SIGILL, SIGILL);
+	DEFINE (TRAP_TRACE, TRAP_TRACE);
+
+	/* ptrace flag bits */
+	DEFINE (PT_PTRACED, PT_PTRACED);
+	DEFINE (PT_TRACESYS, PT_TRACESYS);
+	DEFINE (PT_DTRACE, PT_DTRACE);
+
+	/* error values */
+	DEFINE (ENOSYS, ENOSYS);
+
+	/* clone flag bits */
+	DEFINE (CLONE_VFORK, CLONE_VFORK);
+	DEFINE (CLONE_VM, CLONE_VM);
+
+	return 0;
+}
diff -urN linux-2.4.29/arch/microblaze/kernel/microblaze_defs.head linux-2.4.29-uc1/arch/microblaze/kernel/microblaze_defs.head
--- linux-2.4.29/arch/microblaze/kernel/microblaze_defs.head	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/microblaze_defs.head	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * WARNING! This file is automatically generated - DO NOT EDIT!
+ */
+
+#define TS_MAGICKEY	0x5a5a5a5a
diff -urN linux-2.4.29/arch/microblaze/kernel/microblaze_intc.c linux-2.4.29-uc1/arch/microblaze/kernel/microblaze_intc.c
--- linux-2.4.29/arch/microblaze/kernel/microblaze_intc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/microblaze_intc.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,288 @@
+/*
+ * arch/microblaze/kernel/microblaze_intc.c -- Microblaze cpu core interrupt controller (INTC)
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *                           based upon v850 version 
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by John Williams <jwilliams@itee.uq.edu.au>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/microblaze_intc.h>
+
+/* For now, don't ack interrupt until end of interrupt processing */
+/* Same uncertainty exists in PPC xintc driver */
+#define ACKNOWLEDGE_AFTER
+
+static void irq_nop (unsigned irq) { }
+
+/* Master enable to start the intc */
+void microblaze_intc_master_enable(void)
+{
+  __asm__ __volatile__ (
+		"	sw	%0, r0, %1;"
+		:: "r" (MICROBLAZE_INTC_MASTER_ENABLE_MASK | MICROBLAZE_INTC_HARDWARE_ENABLE_MASK), "r" (MICROBLAZE_INTC_MER_OFFSET+CONFIG_XILINX_INTC_0_BASEADDR));
+}
+
+static unsigned microblaze_intc_irq_startup (unsigned irq)
+{
+	microblaze_intc_clear_pending_irq (irq);
+	microblaze_intc_enable_irq (irq);
+	return 0;
+}
+
+/* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
+   INITS (which is terminated by an entry with the name field == 0).  */
+void __init microblaze_intc_init_irq_types (struct microblaze_intc_irq_init *inits,
+				       struct hw_interrupt_type *hw_irq_types)
+{
+	struct microblaze_intc_irq_init *init;
+	for (init = inits; init->name; init++) {
+		int i;
+		struct hw_interrupt_type *hwit = hw_irq_types++;
+
+		hwit->typename = init->name;
+
+		hwit->startup  = microblaze_intc_irq_startup;
+		hwit->shutdown = microblaze_intc_disable_irq;
+		hwit->enable   = microblaze_intc_enable_irq;
+		hwit->disable  = microblaze_intc_disable_irq;
+		hwit->ack      = microblaze_intc_disable_and_ack_irq;
+		hwit->end      = microblaze_intc_end;
+		
+		/* Initialize kernel IRQ infrastructure for this interrupt.  */
+		init_irq_handlers (init->base, init->num, hwit);
+
+		/* 
+		 * Clear and disable all interrupts.
+		 * In the v850 code this also sets the priorities, but
+		 * priorites are fixed in Microblaze (int0 -> highest)
+		 * so we don't do that here 
+		 */
+	
+		for (i = 0; i < init->num; i++) {
+			unsigned irq = init->base + i;
+
+			/* If the interrupt is currently enabled (all
+			   interrupts are initially disabled), then
+			   assume whoever enabled it has set things up
+			   properly, and avoid messing with it.  */
+			if (!microblaze_intc_irq_enabled (irq)) {
+				microblaze_intc_disable_irq(irq);
+				microblaze_intc_clear_pending_irq(irq);
+			}
+		}
+	}
+}
+
+/* Now the actual IRQ controller functions */
+/* 
+ * Get active IRQ from controller 
+ * Returns -1 if no IRQ is active.  This shouldn't happen because 
+ * this is only called from handle_irq()
+ */
+int microblaze_intc_get_active_irq(void)
+{
+
+#if CONFIG_XILINX_INTC_0_HAS_IVR==1
+	int irq;
+	/* Query the IVR register of the INTC */
+	__asm__ __volatile__ ("	lw	%0, r0, %1"
+				: "=r" (irq)
+				: "r" (MICROBLAZE_INTC_IVR_OFFSET+CONFIG_XILINX_INTC_0_BASEADDR)
+				: "memory");
+	return irq;
+#else
+	unsigned int isr, ier, active, irq=0;
+	__asm__ __volatile__ ("	lw	%0, r0, %2;
+				lw	%1, r0, %3"
+				: "=r" (isr),
+				  "=r" (ier)
+				: "r" (MICROBLAZE_INTC_ISR_OFFSET+CONFIG_XILINX_INTC_0_BASEADDR),
+				  "r" (MICROBLAZE_INTC_IER_OFFSET+CONFIG_XILINX_INTC_0_BASEADDR)
+				: "memory");
+	
+	/* Find active and enabled IRQs */
+	active = isr & ier;
+	/* Search higest priority one */
+	while(!(active & 1)) {
+		active >>= 1;
+		irq++;
+	}
+
+	/* Was one found? */
+	if(irq>31)
+		return -1;	/* No?  Return -1 */
+	else
+		return irq;	
+
+#endif /* CONFIG_XILINX_INTC_0_HAS_IVR */
+}
+
+/* Acknowledge irq */
+void microblaze_intc_ack_irq(unsigned irq)
+{
+	unsigned irq_mask = (1 << irq);
+
+	__asm__ __volatile__ ("	sw	%0, r0, %1"
+				:
+				: "r" (irq_mask),
+				  "r" (MICROBLAZE_INTC_IAR_OFFSET+CONFIG_XILINX_INTC_0_BASEADDR)
+				: "memory");
+}
+
+/* Enable interrupt handling for interrupt IRQ.  */
+void microblaze_intc_enable_irq (unsigned irq)
+{
+	/* Convert irq to bit mask */
+	unsigned int irq_mask = 1 << irq;
+	
+#if CONFIG_XILINX_INTC_0_HAS_SIE==1
+	/* Use Set Interrupt Enables register (SIE) to avoid test and set */
+	__asm__ __volatile__ ("sw	%0, r0, %1"
+				: 
+				: "r" (irq_mask),
+				  "r" (MICROBLAZE_INTC_SIE_OFFSET+CONFIG_XILINX_INTC_0_BASEADDR)
+				: "memory");
+#else
+	unsigned int old_mask;
+	/* get old IER, set bit, reset IER */
+	__asm__ __volatile__ ("	lw	%0, r0, %3;
+				ori	%0, %1, %2;
+				sw	%1, r0, %3"
+				:"=r" (old_mask)
+				:"0" (old_mask),
+				 "r" (irq_mask),
+				 "r" (MICROBLAZE_INTC_IER_OFFSET+CONFIG_XILINX_INTC_0_BASEADDR)
+				: "memory");
+#endif /* CONFIG_XILINX_INTC_0_HASE_SIE */
+}
+
+/* Disable interrupt handling for interrupt IRQ.  Note that any
+   interrupts received while disabled will be delivered once the
+   interrupt is enabled again, unless they are explicitly cleared using
+   `microblaze_intc_clear_pending_irq'.  */
+void microblaze_intc_disable_irq (unsigned irq)
+{
+
+#if CONFIG_XILINX_INTC_0_HAS_CIE==1
+	unsigned int irq_mask = 1 << irq;
+	__asm__ __volatile__ ("	sw	%0, r0, %1"
+				:
+				: "r" (irq_mask),
+				  "r" (MICROBLAZE_INTC_CIE_OFFSET+CONFIG_XILINX_INTC_0_BASEADDR)
+				: "memory");
+#else
+	unsigned int old_mask;
+	unsigned int irq_mask = ~(1 << irq);
+	/* get old IER, clear bit, reset IER */
+	__asm__ __volatile__ ("	lw	%0, r0, %3;
+				andi	%0, %1, %2;
+				sw	%1, r0, %3"
+				: "=r" (old_mask)
+				: "0" (old_mask),
+				  "r" (irq_mask),
+				  "r" (MICROBLAZE_INTC_IER_OFFSET+CONFIG_XILINX_INTC_0_BASEADDR)
+				: "memory");
+#endif /* CONFIG_XILINX_INTC_0_HAS_CIE */
+}
+
+/* Return true if interrupt handling for interrupt IRQ is enabled.  */
+int microblaze_intc_irq_enabled (unsigned irq)
+{
+	unsigned int irq_mask;
+	__asm__ __volatile__ ("	lw	%0, r0, %1"
+				: "=r" (irq_mask)
+				: "r" (MICROBLAZE_INTC_IER_OFFSET+CONFIG_XILINX_INTC_0_BASEADDR)
+				: "memory");
+
+	return irq_mask & (1 << irq);
+}
+
+/* Disable irqs from 0 until LIMIT.  */
+void _microblaze_intc_disable_irqs (unsigned limit)
+{
+
+#if CONFIG_XILINX_INTC_0_HAS_CIE==1
+	unsigned int irq_mask = ~((1 << (limit+1)) -1);
+	__asm__ __volatile__ ("	sw	%0, r0, %1"
+				:
+				: "r" (irq_mask),
+				  "r" (MICROBLAZE_INTC_CIE_OFFSET+CONFIG_XILINX_INTC_0_BASEADDR)
+				: "memory");
+#else
+	/* Create a bit mask with all ones except zeros for lower IRQs */
+	unsigned int irq_mask = (1 << (limit+1))-1;
+	unsigned int old_mask;
+	/* get old IER, clear bits, reset IER */
+	__asm__ __volatile__ ("	lw	%0, r0, %3;
+				andi	%0, %1, %2;
+				sw	%1, r0, %3"
+				: "=r" (old_mask)
+				: "0" (old_mask),
+				  "r" (irq_mask),
+				  "r" (MICROBLAZE_INTC_IER_OFFSET+CONFIG_XILINX_INTC_0_BASEADDR)
+				: "memory");
+#endif /* CONFIG_XILINX_INTC_0_HAS_CIE */
+
+}
+
+/* Clear any pending interrupts for IRQ.  */
+void microblaze_intc_clear_pending_irq (unsigned irq)
+{
+	unsigned int irq_mask = 1 << irq;
+	__asm__ __volatile__ ("	sw	%0, r0, %1"
+				:
+				: "r" (irq_mask),
+				  "r" (MICROBLAZE_INTC_IAR_OFFSET+CONFIG_XILINX_INTC_0_BASEADDR)
+				: "memory");
+}
+
+/* Return true if interrupt IRQ is pending (but disabled).  */
+int microblaze_intc_irq_pending (unsigned irq)
+{
+	int irq_mask = 1 << irq;
+	unsigned int ier_mask, isr_mask;
+	
+	__asm__ __volatile__ ("	lw	%0, r0, %2;"
+			      "	lw	%1, r0, %3"
+				: "=r" (ier_mask),
+				  "=r" (isr_mask)
+				: "r" (MICROBLAZE_INTC_IER_OFFSET+CONFIG_XILINX_INTC_0_BASEADDR),
+				  "r" (MICROBLAZE_INTC_ISR_OFFSET+CONFIG_XILINX_INTC_0_BASEADDR)
+				: "memory");
+
+	/* Return 1 if irq in question is pending but disabled */
+	return irq_mask & (isr_mask & ~ier_mask);
+}
+
+  
+void microblaze_intc_disable_and_ack_irq(unsigned irq)
+{
+	microblaze_intc_disable_irq(irq);
+
+	/* Acknowledge edge sensitive interrupts immediately */
+	if(IRQ_EDGE_SENSITIVE(irq,CONFIG_XILINX_INTC_0_KIND_OF_INTR))
+		microblaze_intc_ack_irq(irq);
+}
+
+void microblaze_intc_end(unsigned irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		microblaze_intc_enable_irq(irq);
+		/* Level sensitive interrupts are acked after handling */
+		if(IRQ_LEVEL_SENSITIVE(irq,CONFIG_XILINX_INTC_0_KIND_OF_INTR))
+			microblaze_intc_ack_irq(irq);
+	}
+}
+
diff -urN linux-2.4.29/arch/microblaze/kernel/microblaze_ksyms.c linux-2.4.29-uc1/arch/microblaze/kernel/microblaze_ksyms.c
--- linux-2.4.29/arch/microblaze/kernel/microblaze_ksyms.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/microblaze_ksyms.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,83 @@
+#include <linux/module.h>
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
+
+#include <asm/setup.h>
+#include <asm/pgalloc.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/semaphore.h>
+#include <asm/checksum.h>
+#include <asm/hardirq.h>
+#include <asm/softirq.h>
+#include <asm/current.h>
+
+//for module enable: we may not use trap_table
+//extern void *trap_table;
+//EXPORT_SYMBOL (trap_table);
+
+/* platform dependent support */
+extern void dump_thread (struct pt_regs *, struct user *);
+EXPORT_SYMBOL (dump_thread);
+EXPORT_SYMBOL (kernel_thread);
+EXPORT_SYMBOL (__bug);
+
+EXPORT_SYMBOL (enable_irq);
+EXPORT_SYMBOL (disable_irq);
+EXPORT_SYMBOL (current);
+
+/* Networking helper routines. */
+EXPORT_SYMBOL (csum_partial_copy);
+EXPORT_SYMBOL (csum_partial_copy_from_user);
+EXPORT_SYMBOL (ip_compute_csum);
+EXPORT_SYMBOL (ip_fast_csum);
+
+/* string / mem functions */
+EXPORT_SYMBOL_NOVERS (strcpy);
+EXPORT_SYMBOL_NOVERS (strncpy);
+EXPORT_SYMBOL_NOVERS (strcat);
+EXPORT_SYMBOL_NOVERS (strncat);
+EXPORT_SYMBOL_NOVERS (strcmp);
+EXPORT_SYMBOL_NOVERS (strncmp);
+EXPORT_SYMBOL_NOVERS (strchr);
+EXPORT_SYMBOL_NOVERS (strlen);
+EXPORT_SYMBOL_NOVERS (strnlen);
+EXPORT_SYMBOL_NOVERS (strpbrk);
+EXPORT_SYMBOL_NOVERS (strtok);
+EXPORT_SYMBOL_NOVERS (strrchr);
+EXPORT_SYMBOL_NOVERS (strstr);
+EXPORT_SYMBOL_NOVERS (memset);
+EXPORT_SYMBOL_NOVERS (memcpy);
+EXPORT_SYMBOL_NOVERS (memmove);
+EXPORT_SYMBOL_NOVERS (memcmp);
+EXPORT_SYMBOL_NOVERS (memscan);
+
+/* semaphores */
+EXPORT_SYMBOL_NOVERS (__down);
+EXPORT_SYMBOL_NOVERS (__down_interruptible);
+EXPORT_SYMBOL_NOVERS (__down_trylock);
+EXPORT_SYMBOL_NOVERS (__up);
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler...  (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __ashldi3 (void);
+extern void __ashrdi3 (void);
+extern void __lshrdi3 (void);
+//extern void __muldi3 (void); //for module enable
+extern void __negdi2 (void);
+
+EXPORT_SYMBOL_NOVERS (__ashldi3);
+EXPORT_SYMBOL_NOVERS (__ashrdi3);
+EXPORT_SYMBOL_NOVERS (__lshrdi3);
+//EXPORT_SYMBOL_NOVERS (__muldi3); //for module enable
+EXPORT_SYMBOL_NOVERS (__negdi2);
diff -urN linux-2.4.29/arch/microblaze/kernel/microblaze_timer.c linux-2.4.29-uc1/arch/microblaze/kernel/microblaze_timer.c
--- linux-2.4.29/arch/microblaze/kernel/microblaze_timer.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/microblaze_timer.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+ * arch/microblaze/kernel/microblaze_timer.c
+ *
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <asm/machdep.h>		/* Get timer base addr etc */
+#include <asm/microblaze_timer.h>
+#include <asm/autoconfig.h>		/* Back compatability supprt for old targets */
+
+/* Start interval timer TIMER (0-3).  The timer will issue the
+   corresponding INTCMD interrupt RATE times per second.
+   This function does not enable the interrupt.  */
+void microblaze_timer_configure (unsigned timer, unsigned rate)
+{
+	unsigned count;
+
+	/* 
+	 * Work out timer compare value for a given clock freq 
+	 * and interrupt rate
+	 */
+	count = ((unsigned)-1) - CONFIG_XILINX_CPU_CLOCK_FREQ / rate - 2;
+
+	/* Do the actual hardware timer initialization:  */
+
+	/* Enable timer, enable interrupt generation, and put into count up mode */
+	/* Set the compare counter */
+	timer_set_compare(CONFIG_XILINX_TIMER_0_BASEADDR, timer, count);
+
+	/* Reset timer and clear interrupt */
+	timer_set_csr(CONFIG_XILINX_TIMER_0_BASEADDR, timer, 
+			TIMER_INTERRUPT | TIMER_RESET);
+
+	/* start the timer */
+	timer_set_csr(CONFIG_XILINX_TIMER_0_BASEADDR, timer, 
+			TIMER_ENABLE | TIMER_ENABLE_INTR | TIMER_RELOAD);
+
+}
diff -urN linux-2.4.29/arch/microblaze/kernel/process.c linux-2.4.29-uc1/arch/microblaze/kernel/process.c
--- linux-2.4.29/arch/microblaze/kernel/process.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/process.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,313 @@
+/*
+ * arch/microblaze/kernel/process.c -- Arch-dependent process handling
+ *
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/reboot.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS;
+struct mm_struct init_mm = INIT_MM (init_mm);
+
+union task_union init_task_union
+__attribute__ ((section (".data.init_task"), aligned (KERNEL_STACK_SIZE)))
+	= { task: INIT_TASK (init_task_union.task) };
+
+asmlinkage void ret_from_fork (void);
+
+
+/* The idle loop.  */
+static void default_idle (void)
+{
+	while (1) {
+		while (! current->need_resched)
+		{
+			asm ("nop;nop;nop; nop; nop; nop; nop" ::: "cc");
+		}
+		schedule ();
+	}
+}
+
+void (*idle)(void) = default_idle;
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle (void)
+{
+	/* endless idle loop with no priority at all */
+	init_idle ();
+	current->nice = 20;
+	current->counter = -100;
+	(*idle) ();
+}
+
+struct spec_reg_name {
+	const char *name;
+	int gpr;
+};
+
+struct spec_reg_name spec_reg_names[] = {
+	{ "sp", GPR_SP },
+	{ "gp", GPR_GP },
+	{ "ep", GPR_EP },
+	{ "lp", GPR_LP },
+	{ 0, 0 }
+};
+
+void show_regs (struct pt_regs *regs)
+{
+	int gpr_base, gpr_offs;
+
+	printk ("     pc 0x%08lx    psw 0x%08lx                       kernel_mode %d\n",
+		regs->pc, regs->psw, regs->kernel_mode);
+
+	for (gpr_base = 0; gpr_base < NUM_GPRS; gpr_base += 4) {
+		for (gpr_offs = 0; gpr_offs < 4; gpr_offs++) {
+			int gpr = gpr_base + gpr_offs;
+			long val = regs->gpr[gpr];
+			struct spec_reg_name *srn;
+
+			for (srn = spec_reg_names; srn->name; srn++)
+				if (srn->gpr == gpr)
+					break;
+
+			if (srn->name)
+				printk ("%7s 0x%08lx", srn->name, val);
+			else
+				printk ("    r%02d 0x%08lx", gpr, val);
+		}
+
+		printk ("\n");
+	}
+}
+
+/*
+ * This is the mechanism for creating a new kernel thread.
+ *
+ * NOTE! Only a kernel-only process (ie the swapper or direct descendants who
+ * haven't done an "execve()") should use this: it will work within a system
+ * call from a "real" process, but the process memory space will not be free'd
+ * until both the parent and the child have exited.
+ */
+int arch_kernel_thread (int (*fn)(void *), void *arg, unsigned long flags)
+{
+	register mm_segment_t fs = get_fs ();
+	register unsigned long arg0;
+	register unsigned long ret;
+
+	/* Somewhere to save syscall return value */
+	unsigned long ret_sav;
+
+	set_fs (KERNEL_DS);
+
+	/* Clone this thread.  */
+	arg0 = flags | CLONE_VM;
+	asm volatile (	"addik	r12, r0, %1	\n\t"
+			"addk	r5, r0, %2	\n\t"
+			"brki	r14, 0x8;	\n\t"
+			"addk	%0, r3, r0	\n\t"
+		        : "=r" (ret) 
+			: "i" (__NR_clone), "r" (arg0)
+		        : "r3", "r4", "r5", "r12", "r14", "cc");
+	if (ret == 0) {
+		/* In child thread, call FN and exit.  */
+		arg0 = (*fn) (arg);
+		asm volatile (	"addik	r12, r0, %1	\n\t"
+				"addk	r5, r0, %2	\n\t"
+				"brki	r14, 0x8	\n\t"
+				"addk	%0, r3, r0	\n\t"
+			        : "=r" (ret) 
+				: "i" (__NR_exit), "r" (arg0)
+			        : "r3", "r4", "r5", "r12", "r14", "cc");
+	}
+
+	/* In parent.  */
+	set_fs (fs);
+
+	return ret;
+}
+
+void flush_thread (void)
+{
+	set_fs (USER_DS);
+}
+
+int copy_thread (int nr, unsigned long clone_flags,
+		 unsigned long stack_start, unsigned long stack_size,
+		 struct task_struct *p, struct pt_regs *regs)
+{
+	/* Start pushing stuff from the top of the childs kernel stack.  */
+	unsigned long orig_ksp = (unsigned long)p + KERNEL_STACK_SIZE;
+	unsigned long ksp = orig_ksp;
+
+	/* We push two `state save' stack fames (see entry.S) on the new
+	   kernel stack:
+	     1) The innermost one is what switch_thread would have
+	        pushed, and is used when we context switch to the child
+		thread for the first time.  It's set up to return to
+		ret_from_fork in entry.S.
+	     2) The outermost one (nearest the top) is what a syscall
+	        trap would have pushed, and is set up to return to the
+		same location as the parent thread, but with a return
+		value of 0. */
+	struct pt_regs *child_switch_regs, *child_trap_regs;
+
+	/* Trap frame.  */
+	ksp -= STATE_SAVE_SIZE;
+	child_trap_regs = (struct pt_regs *)(ksp + STATE_SAVE_PT_OFFSET);
+	/* Switch frame.  */
+	ksp -= STATE_SAVE_SIZE;
+	child_switch_regs = (struct pt_regs *)(ksp + STATE_SAVE_PT_OFFSET);
+
+	/* First copy parent's register state to child.  */
+	*child_switch_regs = *regs;
+	*child_trap_regs = *regs;
+
+	/* switch_thread returns to the restored value of the lp
+	   register (r15), so we make that the place where we want to
+	   jump when the child thread begins running.  
+	   switch_thread returns control to a thread via the instruction
+		rtsd r15, 8
+	   so this offset must be factored in here
+         */
+	child_switch_regs->gpr[GPR_LP] = ((microblaze_reg_t)ret_from_fork)-8;
+
+        if (regs->kernel_mode)
+                /* Since we're returning to kernel-mode, make sure the child's
+                   stored kernel stack pointer agrees with what the actual
+                   stack pointer will be at that point (the trap return code
+                   always restores the SP, even when returning to
+                   kernel-mode).  */
+                child_trap_regs->gpr[GPR_SP] = orig_ksp;
+        else
+                /* Set the child's user-mode stack-pointer (the name
+                   `stack_start' is a misnomer, it's just the initial SP
+                   value).  */
+                child_trap_regs->gpr[GPR_SP] = stack_start;
+
+	/* Thread state for the child (everything else is on the stack).  */
+	p->thread.ksp = ksp;
+
+	return 0;
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread (struct pt_regs *regs, struct user *dump)
+{
+#if 0  /* Later.  XXX */
+	dump->magic = CMAGIC;
+	dump->start_code = 0;
+	dump->start_stack = regs->gpr[GPR_SP];
+	dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
+	dump->u_dsize = ((unsigned long) (current->mm->brk +
+					  (PAGE_SIZE-1))) >> PAGE_SHIFT;
+	dump->u_dsize -= dump->u_tsize;
+	dump->u_ssize = 0;
+
+	if (dump->start_stack < TASK_SIZE)
+		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
+
+	dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump);
+	dump->regs = *regs;
+	dump->u_fpvalid = 0;
+#endif
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage int sys_execve (char *name, char **argv, char **envp,
+			    struct pt_regs *regs)
+{
+	char *filename = getname (name);
+	int error = PTR_ERR (filename);
+
+#if 0
+	printk("hello from sys_execve(%s)\n",name);
+#endif
+
+	if (! IS_ERR (filename)) {
+		error = do_execve (filename, argv, envp, regs);
+		putname (filename);
+	}
+
+	return error;
+}
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here (void);
+extern void scheduling_functions_end_here (void);
+#define first_sched	((unsigned long) scheduling_functions_start_here)
+#define last_sched	((unsigned long) scheduling_functions_end_here)
+
+unsigned long get_wchan (struct task_struct *p)
+{
+#if 0  /* Barf.  Figure out the stack-layout later.  XXX  */
+	unsigned long fp, pc;
+	int count = 0;
+
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	pc = thread_saved_pc (&p->thread);
+
+	/* This quite disgusting function walks up the stack, following
+	   saved return address, until it something that's out of bounds
+	   (as defined by `first_sched' and `last_sched').  It then
+	   returns the last PC that was in-bounds.  */
+	do {
+		if (fp < stack_page + sizeof (struct task_struct) ||
+		    fp >= 8184+stack_page)
+			return 0;
+		pc = ((unsigned long *)fp)[1];
+		/* FIXME: This depends on the order of these functions. */
+		if (pc < first_sched || pc >= last_sched)
+			return pc;
+		fp = *(unsigned long *) fp;
+	} while (count++ < 16);
+#endif
+
+	return 0;
+}
+
+void show_trace_task (struct task_struct *t)
+{
+        /* blarg XXX */
+	printk ("show_trace_task: KSP = 0x%lx, USP = 0x%lx, UPC = 0x%lx\n",
+		t->thread.ksp, KSTK_ESP (t), KSTK_EIP (t));
+}
diff -urN linux-2.4.29/arch/microblaze/kernel/procfs.c linux-2.4.29-uc1/arch/microblaze/kernel/procfs.c
--- linux-2.4.29/arch/microblaze/kernel/procfs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/procfs.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,105 @@
+/*
+ * arch/microblaze/kernel/procfs.c -- Introspection functions for /proc filesystem
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *
+ *  based heavily on v850 code that was
+ *
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include "mach.h"
+
+#ifdef CONFIG_XILINX_MICROBLAZE0_INSTANCE
+static int cpuinfo_print (struct seq_file *m, void *v)
+{
+	extern unsigned long loops_per_jiffy;
+	int count=0;
+	count = seq_printf (m,
+		"CPU-Family:	Microblaze\n"
+		"FPGA-Arch:	%s\n"
+		"CPU-Ver:	%s\n"
+		"CPU-MHz:   %lu.%02lu\n"
+		"BogoMips:	%u.%02u\n",
+		CONFIG_XILINX_MICROBLAZE0_FAMILY,
+		CONFIG_XILINX_MICROBLAZE0_HW_VER,
+		CONFIG_XILINX_CPU_CLOCK_FREQ/1000000,
+		CONFIG_XILINX_CPU_CLOCK_FREQ % 1000000,
+		loops_per_jiffy/(500000/HZ),
+		(loops_per_jiffy/(5000/HZ)) % 100);
+
+	count += seq_printf(m,
+		"HW-Div:         %s\n"
+		"HW-Shift:       %s\n",
+		CONFIG_XILINX_MICROBLAZE0_USE_DIV ? "yes":"no",
+		CONFIG_XILINX_MICROBLAZE0_USE_BARREL ? "yes":"no");
+	
+	if(CONFIG_XILINX_MICROBLAZE0_USE_ICACHE)
+		count +=seq_printf (m,
+			"Icache:        %ukB\n",
+			CONFIG_XILINX_MICROBLAZE0_CACHE_BYTE_SIZE >> 10);
+	else
+		count +=seq_printf (m,
+			"Icache:         no\n");
+ 
+	if(CONFIG_XILINX_MICROBLAZE0_USE_DCACHE)
+		count +=seq_printf (m,
+			"Dcache:       %ukB\n",
+			CONFIG_XILINX_MICROBLAZE0_DCACHE_BYTE_SIZE >> 10);
+	else
+		count +=seq_printf (m,
+			"Dcache:         no\n");
+
+	count += seq_printf(m,
+			"HW-Debug:       %s\n",
+			CONFIG_XILINX_MICROBLAZE0_DEBUG_ENABLED ? "yes":"no");
+
+	return count;
+}
+#else
+static int cpuinfo_print (struct seq_file *m, void *v)
+{
+	extern unsigned long loops_per_jiffy;
+	return seq_printf (m,
+			   "CPU-Family:	microblaze\n"
+			   "CPU-Arch:	%s\n"
+			   "CPU-Model:	%s\n"
+			   "CPU-MHz:   %lu.%02lu\n"
+			   "BogoMips:	%u.%02u\n",
+			   CPU_ARCH,
+			   CPU_MODEL,
+			   CONFIG_XILINX_CPU_CLOCK_FREQ/1000000,
+			   CONFIG_XILINX_CPU_CLOCK_FREQ % 1000000,
+			   loops_per_jiffy/(500000/HZ),
+			   (loops_per_jiffy/(5000/HZ)) % 100);
+}
+#endif
+
+static void *cpuinfo_start (struct seq_file *m, loff_t *pos)
+{
+	return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL;
+}
+
+static void *cpuinfo_next (struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return cpuinfo_start (m, pos);
+}
+
+static void cpuinfo_stop (struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+	start:	cpuinfo_start,
+	next:	cpuinfo_next,
+	stop:	cpuinfo_stop,
+	show:	cpuinfo_print
+};
diff -urN linux-2.4.29/arch/microblaze/kernel/ptrace.c linux-2.4.29-uc1/arch/microblaze/kernel/ptrace.c
--- linux-2.4.29/arch/microblaze/kernel/ptrace.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/ptrace.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,313 @@
+/*
+ * arch/microblaze/kernel/ptrace.c -- `ptrace' system call
+ *
+ *  Copyright (C) 2004,05  John Williams <jwilliams.itee.uq.edu.au>
+ *  Copyright (C) 2002,03  NEC Electronics Corporation
+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
+ *
+ * Derived from arch/mips/kernel/ptrace.c:
+ *
+ *  Copyright (C) 1992 Ross Biro
+ *  Copyright (C) Linus Torvalds
+ *  Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle
+ *  Copyright (C) 1996 David S. Miller
+ *  Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ *  Copyright (C) 1999 MIPS Technologies, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/ptrace.h>
+
+#include <asm/errno.h>
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+
+#if 0
+#define DBPRINTK(...) printk(__VA_ARGS__)
+#else
+#define DBPRINTK(...)
+#endif
+
+/* Returns the address where the register at REG_OFFS in P is stashed away.  */
+static microblaze_reg_t *reg_save_addr (unsigned reg_offs, struct task_struct *t)
+{
+	struct pt_regs *regs;
+
+	/* Three basic cases:
+
+	   (1) A register normally saved before calling the scheduler, is
+	       available in the kernel entry pt_regs structure at the top
+	       of the kernel stack.  The kernel trap/irq exit path takes
+	       care to save/restore almost all registers for ptrace'd
+	       processes.
+
+	   (2) A call-clobbered register, where the process P entered the
+	       kernel via [syscall] trap, is not stored anywhere; that's
+	       OK, because such registers are not expected to be preserved
+	       when the trap returns anyway (so we don't actually bother to
+	       test for this case).
+
+	   (3) A few registers not used at all by the kernel, and so
+	       normally never saved except by context-switches, are in the
+	       context switch state.  */
+
+	/* Register saved during kernel entry (or not available).  */
+	regs = task_regs (t);
+
+	return (microblaze_reg_t *)((char *)regs + reg_offs);
+}
+
+/* Makes sure hardware single-stepping is (globally) enabled.
+   Returns true if successful.  */
+static inline int enable_single_stepping (void)
+{
+	static int enabled = 0;	/* Remember whether we already did it.  */
+	return enabled;
+	if (! enabled) {
+		/* Turn on the SE (`single-step enable') bit, 0x100, in the
+		   DIR (`debug information register').  This may fail if a
+		   processor doesn't support it or something.  We also try
+		   to clear bit 0x40 (`INI'), which is necessary to use the
+		   debug stuff on the microblazee2; on the microblazee, clearing 0x40
+		   shouldn't cause any problem.  */
+		microblaze_reg_t dir = set_dir (0x100, 0x40);
+		/* Make sure it really got set.  */
+		if (dir & 0x100)
+			enabled = 1;
+	}
+	return enabled;
+}
+
+/* Try to set CHILD's single-step flag to VAL.  Returns true if successful.  */
+static int set_single_step (struct task_struct *t, int val)
+{
+	microblaze_reg_t *sstep_addr = reg_save_addr(PT_SINGLESTEP, t);
+	if (val) {
+		/* Make sure single-stepping is enabled.  */
+		if (! enable_single_stepping ())
+			return 0;
+		/* Set T's single-step flag.  */
+		*sstep_addr = 1;
+	} else
+		*sstep_addr = 0;
+	return 1;
+}
+
+int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	int rval;
+
+	lock_kernel();
+	DBPRINTK("sys_ptrace - REQUEST:%u  PID:%u  ADDR:%08x  DATA:%08x\n",
+			request, pid,addr,data); 
+
+	if (request == PTRACE_TRACEME) {
+		DBPRINTK("PTRACE_TRACEME\n",addr); 
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED) {
+			rval = -EPERM;
+			goto out;
+		}
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		rval = 0;
+		goto out;
+	}
+	rval = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		goto out;
+
+	rval = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out;
+
+	if (request == PTRACE_ATTACH) {
+		DBPRINTK("PTRACE_ATTACH\n");
+		rval = ptrace_attach(child);
+		goto out_tsk;
+	}
+	rval = -ESRCH;
+	if (!(child->ptrace & PT_PTRACED))
+		goto out_tsk;
+	if (child->state != TASK_STOPPED) {
+		if (request != PTRACE_KILL)
+			goto out_tsk;
+	}
+	if (child->p_pptr != current)
+		goto out_tsk;
+
+	switch (request) {
+		unsigned long val, copied;
+
+	case PTRACE_PEEKTEXT: /* read word at location addr. */
+	case PTRACE_PEEKDATA:
+		DBPRINTK("PEEKTEXT/PEEKDATA at %08X\n",addr); 
+		copied = access_process_vm(child, addr, &val, sizeof(val), 0);
+		rval = -EIO;
+		if (copied != sizeof(val))
+			break;
+		rval = put_user(val, (unsigned long *)data);
+		goto out;
+
+	case PTRACE_POKETEXT: /* write the word at location addr. */
+	case PTRACE_POKEDATA:
+		DBPRINTK("POKETEXT/POKEDATA to %08X\n",addr);
+		rval = 0;
+		if (access_process_vm(child, addr, &data, sizeof(data), 1)
+		    == sizeof(data))
+			break;
+		rval = -EIO;
+		goto out;
+
+	/* Read/write the word at location ADDR in the registers.  */
+	case PTRACE_PEEKUSR:
+	case PTRACE_POKEUSR:
+		DBPRINTK("PEEKUSR/POKEUSR : 0x%08x\n",addr);
+		rval = 0;
+		if (addr >= PT_SIZE && request == PTRACE_PEEKUSR) {
+			/* Special requests that don't actually correspond
+			   to offsets in struct pt_regs.  */
+			if (addr == PT_TEXT_ADDR)
+			{
+				val = child->mm->start_code;
+			}
+			else if (addr == PT_DATA_ADDR)
+			{
+				val = child->mm->start_data;
+			}
+			else if (addr == PT_TEXT_LEN)
+			{
+				val = child->mm->end_code
+					- child->mm->start_code;
+			}
+			else if (addr == PT_DATA_LEN)
+			{
+				val = child->mm->end_data
+					- child->mm->start_data;
+			}
+			else
+			{
+				rval = -EIO;
+			}
+		} else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) {
+			microblaze_reg_t *reg_addr = reg_save_addr(addr, child);
+			if (request == PTRACE_PEEKUSR)
+			{
+				val = *reg_addr;
+			}
+			else
+			{
+				*reg_addr = data;
+			}
+		} else
+			rval = -EIO;
+
+		if (rval == 0 && request == PTRACE_PEEKUSR)
+		{
+			rval = put_user (val, (unsigned long *)data);
+		}
+		goto out;
+
+	/* Continue and stop at next (return from) syscall */
+	case PTRACE_SYSCALL:
+		DBPRINTK("PTRACE_SYSCALL\n");
+	case PTRACE_SINGLESTEP:
+		DBPRINTK("PTRACE_SINGLESTEP\n");
+	/* Restart after a signal.  */
+	case PTRACE_CONT:
+		DBPRINTK("PTRACE_CONT\n"); 
+		rval = -EIO;
+		if ((unsigned long) data > _NSIG)
+			break;
+
+#if 1
+
+		/* Turn CHILD's single-step flag on or off.  */
+		DBPRINTK("calling set_single_step\n"); 
+		if (! set_single_step (child, request == PTRACE_SINGLESTEP))
+			break;
+#endif
+		if (request == PTRACE_SYSCALL)
+			child->ptrace |= PT_TRACESYS;
+		else
+			child->ptrace &= ~PT_TRACESYS;
+
+		child->exit_code = data;
+		DBPRINTK("wakeup_process\n");
+		wake_up_process(child);
+		rval = 0;
+		break;
+
+	/*
+	 * make the child exit.  Best I can do is send it a sigkill.
+	 * perhaps it should be put in the status that it wants to
+	 * exit.
+	 */
+	case PTRACE_KILL:
+		DBPRINTK("PTRACE_KILL\n"); 
+		rval = 0;
+		if (child->state == TASK_ZOMBIE)	/* already dead */
+			break;
+		child->exit_code = SIGKILL;
+		wake_up_process(child);
+		break;
+
+	case PTRACE_DETACH: /* detach a process that was attached. */
+		DBPRINTK("PTRACE_DETACH\n"); 
+		set_single_step (child, 0);  /* Clear single-step flag */
+		rval = ptrace_detach(child, data);
+		break;
+
+	default:
+		rval = -EIO;
+		goto out;
+	}
+
+out_tsk:
+	free_task_struct(child);
+out:
+	unlock_kernel();
+	return rval;
+}
+
+asmlinkage void syscall_trace(void)
+{
+	if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
+			!= (PT_PTRACED|PT_TRACESYS))
+		return;
+	/* The 0x80 provides a way for the tracing parent to distinguish
+	   between a syscall stop and SIGTRAP delivery */
+	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+					? 0x80 : 0);
+	current->state = TASK_STOPPED;
+	notify_parent(current, SIGCHLD);
+	schedule();
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+}
+
+void ptrace_disable (struct task_struct *child)
+{
+	/* nothing to do */
+}
diff -urN linux-2.4.29/arch/microblaze/kernel/semaphore.c linux-2.4.29-uc1/arch/microblaze/kernel/semaphore.c
--- linux-2.4.29/arch/microblaze/kernel/semaphore.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/semaphore.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,164 @@
+/*
+ * arch/v850/kernel/semaphore.c -- Semaphore support
+ *
+ *  Copyright (C) 1998-2000  IBM Corporation
+ *  Copyright (C) 1999  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * This file is a copy of the s390 version, arch/s390/kernel/semaphore.c
+ *    Author(s): Martin Schwidefsky
+ * which was derived from the i386 version, linux/arch/i386/kernel/semaphore.c
+ */
+
+#include <linux/sched.h>
+
+#include <asm/semaphore.h>
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to acquire the semaphore, while the "sleeping"
+ * variable is a count of such acquires.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * "sleeping" and the contention routine ordering is
+ * protected by the semaphore spinlock.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+
+/*
+ * Logic:
+ *  - only on a boundary condition do we need to care. When we go
+ *    from a negative count to a non-negative, we wake people up.
+ *  - when we go from a non-negative count to a negative do we
+ *    (a) synchronize with the "sleeper" count and (b) make sure
+ *    that we're on the wakeup list before we synchronize so that
+ *    we cannot lose wakeup events.
+ */
+
+void __up(struct semaphore *sem)
+{
+	wake_up(&sem->wait);
+}
+
+static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED;
+
+void __down(struct semaphore * sem)
+{
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+	tsk->state = TASK_UNINTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	spin_lock_irq(&semaphore_lock);
+	sem->sleepers++;
+	for (;;) {
+		int sleepers = sem->sleepers;
+
+		/*
+		 * Add "everybody else" into it. They aren't
+		 * playing, because we own the spinlock.
+		 */
+		if (!atomic_add_negative(sleepers - 1, &sem->count)) {
+			sem->sleepers = 0;
+			break;
+		}
+		sem->sleepers = 1;	/* us - see -1 above */
+		spin_unlock_irq(&semaphore_lock);
+
+		schedule();
+		tsk->state = TASK_UNINTERRUPTIBLE;
+		spin_lock_irq(&semaphore_lock);
+	}
+	spin_unlock_irq(&semaphore_lock);
+	remove_wait_queue(&sem->wait, &wait);
+	tsk->state = TASK_RUNNING;
+	wake_up(&sem->wait);
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+	int retval = 0;
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+	tsk->state = TASK_INTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	spin_lock_irq(&semaphore_lock);
+	sem->sleepers ++;
+	for (;;) {
+		int sleepers = sem->sleepers;
+
+		/*
+		 * With signals pending, this turns into
+		 * the trylock failure case - we won't be
+		 * sleeping, and we* can't get the lock as
+		 * it has contention. Just correct the count
+		 * and exit.
+		 */
+		if (signal_pending(current)) {
+			retval = -EINTR;
+			sem->sleepers = 0;
+			atomic_add(sleepers, &sem->count);
+			break;
+		}
+
+		/*
+		 * Add "everybody else" into it. They aren't
+		 * playing, because we own the spinlock. The
+		 * "-1" is because we're still hoping to get
+		 * the lock.
+		 */
+		if (!atomic_add_negative(sleepers - 1, &sem->count)) {
+			sem->sleepers = 0;
+			break;
+		}
+		sem->sleepers = 1;	/* us - see -1 above */
+		spin_unlock_irq(&semaphore_lock);
+
+		schedule();
+		tsk->state = TASK_INTERRUPTIBLE;
+		spin_lock_irq(&semaphore_lock);
+	}
+	spin_unlock_irq(&semaphore_lock);
+	tsk->state = TASK_RUNNING;
+	remove_wait_queue(&sem->wait, &wait);
+	wake_up(&sem->wait);
+	return retval;
+}
+
+/*
+ * Trylock failed - make sure we correct for
+ * having decremented the count.
+ */
+int __down_trylock(struct semaphore * sem)
+{
+        unsigned long flags;
+	int sleepers;
+
+	spin_lock_irqsave(&semaphore_lock, flags);
+	sleepers = sem->sleepers + 1;
+	sem->sleepers = 0;
+
+	/*
+	 * Add "everybody else" and us into it. They aren't
+	 * playing, because we own the spinlock.
+	 */
+	if (!atomic_add_negative(sleepers, &sem->count))
+		wake_up(&sem->wait);
+
+	spin_unlock_irqrestore(&semaphore_lock, flags);
+	return 1;
+}
diff -urN linux-2.4.29/arch/microblaze/kernel/setup.c linux-2.4.29-uc1/arch/microblaze/kernel/setup.c
--- linux-2.4.29/arch/microblaze/kernel/setup.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/setup.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,160 @@
+/*
+ * arch/microblaze/kernel/setup.c -- Arch-dependent initialization functions
+ *
+
+ *  Copyright (C) 2004	     Brett Boren <borenb@eng.uah.edu>
+ *  Copyright (C) 2003	     John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams <jwilliams@itee.uq.edu.au>
+ * Microblaze command line param handling by Brett Boren <borenb@eng.uah.edu>
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+#include <linux/reboot.h>
+#include <linux/personality.h>
+
+#include <asm/irq.h>
+#include <asm/exceptions.h>
+
+#include "mach.h"
+#include "asm/setup.h"
+
+static struct meminfo meminfo __initdata= { 0, };
+
+extern void bootmem_init(struct meminfo *);
+extern void paging_init(struct meminfo *);
+extern unsigned long _ramstart;
+
+#ifndef CONFIG_REGISTER_TASK_PTR
+struct task_struct *current;
+#endif
+
+/* These symbols are all defined in the linker map to delineate various
+   statically allocated regions of memory.  */
+
+// extern char _intv_start, _intv_end;
+/* `kram' is only used if the kernel uses part of normal user RAM.  */
+extern char _kram_start __attribute__ ((__weak__));
+extern char _kram_end __attribute__ ((__weak__));
+
+/* erase following when we port to 2.6, include <asm/sections.h> instead */
+extern char _text[], _stext[], _etext[];
+extern char _data[], _sdata[], _edata[];
+
+char saved_command_line[512];
+#ifdef CONFIG_MBVANILLA_CMDLINE
+/* This pointer gets set with the address of a buffer 
+   allocated (or specified) by the bootloader 
+*/
+/* 
+   BAB 1/8/2004 this initialization is needed to keep bootloader_buf_addr
+   from being placed in bss and getting cleared in mach_early_setup 
+*/
+void *bootloader_buf_addr = 0xFFFFFFFF;
+#else
+char command_line[512];
+#endif
+
+void __init setup_arch (char **cmdline)
+{
+#ifdef CONFIG_MBVANILLA_CMDLINE
+	/* 
+	  If a cmdline has come from the bootlaoder, then this variable
+	  will have been initialised with the addr of the cmdline buffer.
+	  Just point the kernel there. 
+	*/
+	*cmdline = bootloader_buf_addr;
+
+	/* Keep a copy of command line */
+	memcpy (saved_command_line, *cmdline, sizeof saved_command_line);
+#else
+	*cmdline = command_line;
+
+	/* Keep a copy of command line */
+	memcpy (saved_command_line, command_line, sizeof saved_command_line);
+#endif
+	saved_command_line[sizeof saved_command_line - 1] = '\0';
+
+	console_verbose ();
+
+	init_mm.start_code	= (unsigned long) &_stext;
+	init_mm.end_code	= (unsigned long) &_etext;
+	init_mm.end_data	= (unsigned long) _ramstart;
+	init_mm.brk		= (unsigned long) _ramstart;
+#if 0	
+	init_mm.end_data = (unsigned long) &_edata;
+	init_mm.brk = (unsigned long) &_kram_end;
+#endif
+
+	/* Provide default meminfo configuration */
+	/* Any platform using the autoconfig architecture will define
+	   CONFIG_XILINX_ERAM_START... */
+#ifdef CONFIG_XILINX_ERAM_START
+	if(meminfo.nr_banks == 0)
+	{
+		meminfo.nr_banks 	= 1;
+		meminfo.bank[0].start 	= CONFIG_XILINX_ERAM_START;
+		meminfo.bank[0].size	= CONFIG_XILINX_ERAM_SIZE;
+	}
+#else
+	if(meminfo.nr_banks == 0)
+	{
+		meminfo.nr_banks 	= 1;
+		meminfo.bank[0].start 	= PAGE_OFFSET;
+		meminfo.bank[0].size	= ERAM_SIZE;
+	}
+#endif
+
+	/* ... and tell the kernel about it.  */
+	bootmem_init(&meminfo);
+	paging_init (&meminfo);
+
+	/* do machine-specific setups.  */
+	mach_setup (cmdline);
+}
+
+void __init trap_init (void)
+{
+	initialize_exception_handlers();
+	__enable_hw_exceptions();
+}
+
+
+static void irq_nop (unsigned irq) { }
+static unsigned irq_zero (unsigned irq) { return 0; }
+
+static void nmi_end (unsigned irq)
+{
+	if (irq != IRQ_NMI (0)) {
+		printk (KERN_CRIT "NMI %d is unrecoverable; restarting...",
+			irq - IRQ_NMI (0));
+		machine_restart (0);
+	}
+}
+
+static struct hw_interrupt_type nmi_irq_type = {
+	"NMI",
+	irq_zero,		/* startup */
+	irq_nop,		/* shutdown */
+	irq_nop,		/* enable */
+	irq_nop,		/* disable */
+	irq_nop,		/* ack */
+	nmi_end,		/* end */
+};
+
+void __init init_IRQ (void)
+{
+	init_irq_handlers (0, NUM_MACH_IRQS, 0);
+	//init_irq_handlers (IRQ_NMI (0), NUM_NMIS, &nmi_irq_type);
+	mach_init_irqs ();
+}
diff -urN linux-2.4.29/arch/microblaze/kernel/signal.c linux-2.4.29-uc1/arch/microblaze/kernel/signal.c
--- linux-2.4.29/arch/microblaze/kernel/signal.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/signal.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,649 @@
+/*
+ * arch/microblaze/kernel/signal.c -- Signal handling
+ *
+ *  Copyright (C) 2003,2004  John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 1999,2000  Niibe Yutaka & Kaz Kojima
+ *  Copyright (C) 1991,1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * 1997-11-28  Modified for POSIX.1b signals by Richard Henderson
+ *
+ * This file was was derived from the sh version, arch/sh/kernel/signal.c
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/personality.h>
+#include <asm/ucontext.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+
+#define DEBUG_SIG 0
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
+
+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
+{
+	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+		return -EFAULT;
+	if (from->si_code < 0)
+		return __copy_to_user(to, from, sizeof(siginfo_t));
+	else {
+		int err;
+
+		/* If you change siginfo_t structure, please be sure
+		   this code is fixed accordingly.
+		   It should never copy any pad contained in the structure
+		   to avoid security leaks, but must copy the generic
+		   3 ints plus the relevant union member.  */
+		err = __put_user(from->si_signo, &to->si_signo);
+		err |= __put_user(from->si_errno, &to->si_errno);
+		err |= __put_user((short)from->si_code, &to->si_code);
+		/* First 32bits of unions are always present.  */
+		err |= __put_user(from->si_pid, &to->si_pid);
+		switch (from->si_code >> 16) {
+		case __SI_FAULT >> 16:
+			break;
+		case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+			err |= __put_user(from->si_status, &to->si_status);
+		default:
+			err |= __put_user(from->si_uid, &to->si_uid);
+			break;
+		/* case __SI_RT: This is not generated by the kernel as of now.  */
+		}
+		return err;
+	}
+}
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int
+sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs)
+{
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->gpr[GPR_RVAL] = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(regs, &saveset))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
+		  struct pt_regs *regs)
+{
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->gpr[GPR_RVAL] = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(regs, &saveset))
+			return -EINTR;
+	}
+}
+
+asmlinkage int 
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t *uss, stack_t *uoss,
+		struct pt_regs *regs)
+{
+	return do_sigaltstack(uss, uoss, regs->gpr[GPR_SP]);
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+
+struct sigframe
+{
+	struct sigcontext sc;
+	unsigned long extramask[_NSIG_WORDS-1];
+	unsigned long tramp[3];	/* signal trampoline */
+};
+
+struct rt_sigframe
+{
+	struct siginfo *pinfo;
+	void *puc;
+	struct siginfo info;
+	struct ucontext uc;
+	unsigned long tramp[3];	/* signal trampoline */
+};
+
+static int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *rval_p)
+{
+	unsigned int err = 0;
+
+#define COPY(x)		err |= __get_user(regs->x, &sc->regs.x)
+	COPY(gpr[0]);	COPY(gpr[1]);	COPY(gpr[2]);	COPY(gpr[3]);
+	COPY(gpr[4]);	COPY(gpr[5]);	COPY(gpr[6]);	COPY(gpr[7]);
+	COPY(gpr[8]);	COPY(gpr[9]);	COPY(gpr[10]);	COPY(gpr[11]);
+	COPY(gpr[12]);	COPY(gpr[13]);	COPY(gpr[14]);	COPY(gpr[15]);
+	COPY(gpr[16]);	COPY(gpr[17]);	COPY(gpr[18]);	COPY(gpr[19]);
+	COPY(gpr[20]);	COPY(gpr[21]);	COPY(gpr[22]);	COPY(gpr[23]);
+	COPY(gpr[24]);	COPY(gpr[25]);	COPY(gpr[26]);	COPY(gpr[27]);
+	COPY(gpr[28]);	COPY(gpr[29]);	COPY(gpr[30]);	COPY(gpr[31]);
+	COPY(pc);	COPY(psw);
+#undef COPY
+
+	return err;
+}
+
+asmlinkage int sys_sigreturn(struct pt_regs *regs)
+{
+	struct sigframe *frame = (struct sigframe *)regs->gpr[GPR_SP];
+	sigset_t set;
+	int rval;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+
+	if (__get_user(set.sig[0], &frame->sc.oldmask)
+	    || (_NSIG_WORDS > 1
+		&& __copy_from_user(&set.sig[1], &frame->extramask,
+				    sizeof(frame->extramask))))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigcontext(regs, &frame->sc, &rval))
+		goto badframe;
+	return rval;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+{
+	struct rt_sigframe *frame = (struct rt_sigframe *)regs->gpr[GPR_SP];
+	sigset_t set;
+	stack_t st;
+	int rval;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval))
+		goto badframe;
+
+	if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
+		goto badframe;
+	/* It is more difficult to avoid calling this function than to
+	   call it and ignore errors.  */
+	do_sigaltstack(&st, NULL, regs->gpr[GPR_SP]);
+
+	return rval;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}	
+
+/*
+ * Set up a signal frame.
+ */
+
+static int
+setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+		 unsigned long mask)
+{
+	int err = 0;
+
+#define COPY(x)		err |= __put_user(regs->x, &sc->regs.x)
+	COPY(gpr[0]);	COPY(gpr[1]);	COPY(gpr[2]);	COPY(gpr[3]);
+	COPY(gpr[4]);	COPY(gpr[5]);	COPY(gpr[6]);	COPY(gpr[7]);
+	COPY(gpr[8]);	COPY(gpr[9]);	COPY(gpr[10]);	COPY(gpr[11]);
+	COPY(gpr[12]);	COPY(gpr[13]);	COPY(gpr[14]);	COPY(gpr[15]);
+	COPY(gpr[16]);	COPY(gpr[17]);	COPY(gpr[18]);	COPY(gpr[19]);
+	COPY(gpr[20]);	COPY(gpr[21]);	COPY(gpr[22]);	COPY(gpr[23]);
+	COPY(gpr[24]);	COPY(gpr[25]);	COPY(gpr[26]);	COPY(gpr[27]);
+	COPY(gpr[28]);	COPY(gpr[29]);	COPY(gpr[30]);	COPY(gpr[31]);
+	COPY(pc);	COPY(psw);
+#undef COPY
+
+	err |= __put_user(mask, &sc->oldmask);
+
+	return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	/* Default to using normal stack */
+	unsigned long sp = regs->gpr[GPR_SP];
+
+	if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp))
+		sp = current->sas_ss_sp + current->sas_ss_size;
+
+	return (void *)((sp - frame_size) & -8UL);
+}
+
+static void setup_frame(int sig, struct k_sigaction *ka,
+			sigset_t *set, struct pt_regs *regs)
+{
+	struct sigframe *frame;
+	int err = 0;
+	int signal;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	signal = current->exec_domain
+		&& current->exec_domain->signal_invmap
+		&& sig < 32
+		? current->exec_domain->signal_invmap[sig]
+		: sig;
+
+	err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
+
+	if (_NSIG_WORDS > 1) {
+		err |= __copy_to_user(frame->extramask, &set->sig[1],
+				      sizeof(frame->extramask));
+	}
+
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	/* minus 8 is offset to cater for "rtsd r15,8" offset */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		regs->gpr[GPR_LP] = (unsigned long) ka->sa.sa_restorer-8;
+	} else {
+		/* Note, these encodings are _big endian_!  */
+
+		/* addi  r12, r0, __NR_sigreturn  */
+		err |= __put_user(0x31800000 | __NR_sigreturn ,
+				  frame->tramp + 0);
+		/* brki r14, 0x8 */
+		err |= __put_user(0xb9cc0008, frame->tramp + 1);
+
+		regs->gpr[GPR_LP] = (unsigned long)frame->tramp-8;
+
+		flush_cache_sigtramp ((unsigned long)frame->tramp);
+	}
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up registers for signal handler */
+	regs->gpr[GPR_SP] = (unsigned long) frame;
+	regs->gpr[GPR_ARG0] = signal; /* Arg for signal handler */
+	/* Offset of 4 to handle microblaze rtbd r14, 4 */
+	regs->pc = (unsigned long) ka->sa.sa_handler-4;
+
+	set_fs(USER_DS);
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): sp=%p pc=%08lx ra=%08lx\n",
+		current->comm, current->pid, frame, regs->pc, );
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+			   sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+	int err = 0;
+	int signal;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	signal = current->exec_domain
+		&& current->exec_domain->signal_invmap
+		&& sig < 32
+		? current->exec_domain->signal_invmap[sig]
+		: sig;
+
+	err |= __put_user(&frame->info, &frame->pinfo);
+	err |= __put_user(&frame->uc, &frame->puc);
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+			  &frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(regs->gpr[GPR_SP]),
+			  &frame->uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= setup_sigcontext(&frame->uc.uc_mcontext,
+			        regs, set->sig[0]);
+	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	/* minus 8 is offset to cater for "rtsd r15,8" */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		regs->gpr[GPR_LP] = (unsigned long) ka->sa.sa_restorer-8;
+	} else {
+		/* addi  r12, r0, __NR_sigreturn  */
+		err |= __put_user(0x31800000 | __NR_sigreturn ,
+				  frame->tramp + 0);
+		/* brki r14, 0x8 */
+		err |= __put_user(0xb9cc0008, frame->tramp + 1);
+
+		regs->gpr[GPR_LP] = (unsigned long)frame->tramp-8;
+
+		flush_cache_sigtramp ((unsigned long)frame->tramp);
+	}
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up registers for signal handler */
+	regs->gpr[GPR_SP] = (unsigned long) frame;
+	regs->gpr[GPR_ARG0] = signal; /* Arg for signal handler */
+	/* Offset to handle microblaze rtbd r14, 4 */
+	regs->pc = (unsigned long) ka->sa.sa_handler-4;
+
+	set_fs(USER_DS);
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
+		current->comm, current->pid, frame, regs->pc, regs->pr);
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+/*
+ * OK, we're invoking a handler
+ */	
+
+static void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+	      siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
+{
+	/* Are we from a system call? */
+	if (PT_REGS_SYSCALL (regs)) {
+		/* If so, check system call restarting.. */
+		switch (regs->gpr[GPR_RVAL]) {
+			case -ERESTARTNOHAND:
+				regs->gpr[GPR_RVAL] = -EINTR;
+				break;
+
+			case -ERESTARTSYS:
+				if (!(ka->sa.sa_flags & SA_RESTART)) {
+					regs->gpr[GPR_RVAL] = -EINTR;
+					break;
+				}
+			/* fallthrough */
+			case -ERESTARTNOINTR:
+				regs->gpr[12] = PT_REGS_SYSCALL (regs);
+				/* offset of 8 bytes required = 4 for rtbd
+				   offset, plus 4 for size of 
+					"brki r14,8"
+				   instruction. */
+				regs->pc -= 8; 
+		}
+
+		PT_REGS_SET_SYSCALL (regs, 0);
+	}
+
+	/* Set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sigmask_lock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending(current);
+		spin_unlock_irq(&current->sigmask_lock);
+	}
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals that
+ * the kernel can handle, and then we build all the user-level signal handling
+ * stack-frames in one go after that.
+ */
+int do_signal(struct pt_regs *regs, sigset_t *oldset)
+{
+	siginfo_t info;
+	struct k_sigaction *ka;
+
+	/*
+	 * We want the common case to go fast, which
+	 * is why we may in certain cases get here from
+	 * kernel mode. Just return without doing anything
+	 * if so.
+	 */
+	if (!user_mode(regs))
+		return 1;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	for (;;) {
+		unsigned long signr;
+
+		spin_lock_irq(&current->sigmask_lock);
+		signr = dequeue_signal(&current->blocked, &info);
+		spin_unlock_irq(&current->sigmask_lock);
+
+		if (!signr)
+			break;
+
+		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			/* Let the debugger run.  */
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code))
+				// continue;
+				return 1;
+
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				// continue;
+				return 1;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+
+			/* Init gets no signals it doesn't want.  */
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD: case SIGWINCH:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP:
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+					notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGABRT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				sigaddset(&current->pending.signal, signr);
+				recalc_sigpending(current);
+				current->flags |= PF_SIGNALED;
+				do_exit(exit_code);
+				/* NOTREACHED */
+			}
+		}
+
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(signr, ka, &info, oldset, regs);
+		return 1;
+	}
+
+	/* Did we come from a system call? */
+	if (PT_REGS_SYSCALL (regs)) {
+		/* Restart the system call - no handlers present */
+		if (regs->gpr[GPR_RVAL] == -ERESTARTNOHAND ||
+		    regs->gpr[GPR_RVAL] == -ERESTARTSYS ||
+		    regs->gpr[GPR_RVAL] == -ERESTARTNOINTR) {
+			regs->gpr[12] = PT_REGS_SYSCALL (regs);
+			regs->pc -= 8; /* 4 + 8 for microblaze return offset wierdness */
+		}
+	}
+	return 0;
+}
diff -urN linux-2.4.29/arch/microblaze/kernel/syscalls.c linux-2.4.29-uc1/arch/microblaze/kernel/syscalls.c
--- linux-2.4.29/arch/microblaze/kernel/syscalls.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/syscalls.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,246 @@
+/*
+ * arch/v850/kernel/syscalls.c -- Various system-call definitions not
+ * 	defined in machine-independent code
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * This file was derived the ppc version, arch/ppc/kernel/syscalls.c
+ * ... which was derived from "arch/i386/kernel/sys_i386.c" by Gary Thomas;
+ *     modified by Cort Dougan (cort@cs.nmt.edu)
+ *     and Paul Mackerras (paulus@cs.anu.edu.au).
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/sys.h>
+#include <linux/ipc.h>
+#include <linux/utsname.h>
+#include <linux/file.h>
+
+#include <asm/uaccess.h>
+#include <asm/ipc.h>
+#include <asm/semaphore.h>
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+int
+sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	ret = -EINVAL;
+	switch (call) {
+	case SEMOP:
+		ret = sys_semop (first, (struct sembuf *)ptr, second);
+		break;
+	case SEMGET:
+		ret = sys_semget (first, second, third);
+		break;
+	case SEMCTL:
+	{
+		union semun fourth;
+
+		if (!ptr)
+			break;
+		if ((ret = verify_area (VERIFY_READ, ptr, sizeof(long)))
+		    || (ret = get_user(fourth.__pad, (void **)ptr)))
+			break;
+		ret = sys_semctl (first, second, third, fourth);
+		break;
+	}
+	case MSGSND:
+		ret = sys_msgsnd (first, (struct msgbuf *) ptr, second, third);
+		break;
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
+
+			if (!ptr)
+				break;
+			if ((ret = verify_area (VERIFY_READ, ptr, sizeof(tmp)))
+			    || (ret = copy_from_user(&tmp,
+						(struct ipc_kludge *) ptr,
+						sizeof (tmp))))
+				break;
+			ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp,
+					  third);
+			break;
+			}
+		default:
+			ret = sys_msgrcv (first, (struct msgbuf *) ptr,
+					  second, fifth, third);
+			break;
+		}
+		break;
+	case MSGGET:
+		ret = sys_msgget ((key_t) first, second);
+		break;
+	case MSGCTL:
+		ret = sys_msgctl (first, second, (struct msqid_ds *) ptr);
+		break;
+	case SHMAT:
+		switch (version) {
+		default: {
+			ulong raddr;
+
+			if ((ret = verify_area(VERIFY_WRITE, (ulong*) third,
+					       sizeof(ulong))))
+				break;
+			ret = sys_shmat (first, (char *) ptr, second, &raddr);
+			if (ret)
+				break;
+			ret = put_user (raddr, (ulong *) third);
+			break;
+			}
+		case 1:	/* iBCS2 emulator entry point */
+			if (!segment_eq(get_fs(), get_ds()))
+				break;
+			ret = sys_shmat (first, (char *) ptr, second,
+					 (ulong *) third);
+			break;
+		}
+		break;
+	case SHMDT: 
+		ret = sys_shmdt ((char *)ptr);
+		break;
+	case SHMGET:
+		ret = sys_shmget (first, second, third);
+		break;
+	case SHMCTL:
+		ret = sys_shmctl (first, second, (struct shmid_ds *) ptr);
+		break;
+	}
+
+	return ret;
+}
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+int sys_pipe (int *fildes)
+{
+	int fd[2];
+	int error;
+
+	error = do_pipe (fd);
+	if (!error) {
+		if (copy_to_user (fildes, fd, 2*sizeof (int)))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+static inline unsigned long
+do_mmap2 (unsigned long addr, size_t len,
+	 unsigned long prot, unsigned long flags,
+	 unsigned long fd, unsigned long pgoff)
+{
+	struct file * file = NULL;
+	int ret = -EBADF;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (! (flags & MAP_ANONYMOUS)) {
+		if (!(file = fget (fd)))
+			goto out;
+	}
+	
+	down_write (&current->mm->mmap_sem);
+	ret = do_mmap_pgoff (file, addr, len, prot, flags, pgoff);
+	up_write (&current->mm->mmap_sem);
+	if (file)
+		fput (file);
+out:
+	return ret;
+}
+
+unsigned long sys_mmap2 (unsigned long addr, size_t len,
+			unsigned long prot, unsigned long flags,
+			unsigned long fd, unsigned long pgoff)
+{
+	return do_mmap2 (addr, len, prot, flags, fd, pgoff);
+}
+
+unsigned long sys_mmap (unsigned long addr, size_t len,
+		       unsigned long prot, unsigned long flags,
+		       unsigned long fd, off_t offset)
+{
+	int err = -EINVAL;
+
+	if (offset & ~PAGE_MASK)
+		goto out;
+
+	err = do_mmap2 (addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+out:
+	return err;
+}
+
+int sys_pause (void)
+{
+	current->state = TASK_INTERRUPTIBLE;
+	schedule ();
+	return -ERESTARTNOHAND;
+}
+
+int sys_uname (struct old_utsname * name)
+{
+	int err = -EFAULT;
+
+	down_read (&uts_sem);
+	if (name && !copy_to_user (name, &system_utsname, sizeof (*name)))
+		err = 0;
+	up_read (&uts_sem);
+	return err;
+}
+
+int sys_olduname (struct oldold_utsname * name)
+{
+	int error;
+
+	if (!name)
+		return -EFAULT;
+	if (!access_ok (VERIFY_WRITE, name, sizeof (struct oldold_utsname)))
+		return -EFAULT;
+  
+	down_read (&uts_sem);
+	error = __copy_to_user (&name->sysname, &system_utsname.sysname,
+				__OLD_UTS_LEN);
+	error -= __put_user (0, name->sysname + __OLD_UTS_LEN);
+	error -= __copy_to_user (&name->nodename, &system_utsname.nodename,
+				 __OLD_UTS_LEN);
+	error -= __put_user (0, name->nodename + __OLD_UTS_LEN);
+	error -= __copy_to_user (&name->release, &system_utsname.release,
+				 __OLD_UTS_LEN);
+	error -= __put_user (0, name->release + __OLD_UTS_LEN);
+	error -= __copy_to_user (&name->version, &system_utsname.version,
+				 __OLD_UTS_LEN);
+	error -= __put_user (0, name->version + __OLD_UTS_LEN);
+	error -= __copy_to_user (&name->machine, &system_utsname.machine,
+				 __OLD_UTS_LEN);
+	error = __put_user (0, name->machine + __OLD_UTS_LEN);
+	up_read (&uts_sem);
+
+	error = error ? -EFAULT : 0;
+	return error;
+}
diff -urN linux-2.4.29/arch/microblaze/kernel/time.c linux-2.4.29-uc1/arch/microblaze/kernel/time.c
--- linux-2.4.29/arch/microblaze/kernel/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/time.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,180 @@
+/*
+ * linux/arch/v850/kernel/time.c -- Arch-dependent timer functions
+ *
+ *  Copyright (C) 1991, 1992, 1995, 2001, 2002  Linus Torvalds
+ *
+ * This file contains the v850-specific time handling details.
+ * Most of the stuff is located in the machine specific files.
+ *
+ * 1997-09-10	Updated NTP code according to technical memorandum Jan '96
+ *		"A Kernel Model for Precision Timekeeping" by Dave Mills
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+
+#include <linux/timex.h>
+
+#include "mach.h"
+#include <asm/microblaze_timer.h>
+#include <linux/config.h> 
+
+static inline void do_profile (unsigned long pc)
+{
+	if (prof_buffer && current->pid) {
+		extern int _stext;
+		pc -= (unsigned long) &_stext;
+		pc >>= prof_shift;
+		if (pc < prof_len)
+			++prof_buffer[pc];
+		else
+		/*
+		 * Don't ignore out-of-bounds PC values silently,
+		 * put them into the last histogram slot, so if
+		 * present, they will show up as a sharp peak.
+		 */
+			++prof_buffer[prof_len-1];
+	}
+}
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+static void timer_interrupt (int irq, void *dummy, struct pt_regs *regs)
+{
+	/* Read the timer control register */
+	/* timer 0 is hard coded - bleugh */
+	unsigned int csr = timer_get_csr(CONFIG_XILINX_TIMER_0_BASEADDR,0);
+
+	/* may need to kick the hardware timer */
+	if (mach_tick)
+	  mach_tick ();
+
+	do_timer (regs);
+
+	if (! user_mode (regs))
+		do_profile (regs->pc);
+
+	/* Simple tick tock timer */
+	{
+		static int ticks=0, value=0, period=25;
+		if(ticks++>=period)
+		{
+			value=!value;
+			mach_heartbeat(value);
+			ticks=0;
+		}
+
+		
+	}
+
+#if 0
+	/* use power LED as a heartbeat instead -- much more useful
+	   for debugging -- based on the version for PReP by Cort */
+	/* acts like an actual heart beat -- ie thump-thump-pause... */
+	if (mach_heartbeat) {
+	    static unsigned cnt = 0, period = 0, dist = 0;
+
+	    if (cnt == 0 || cnt == dist)
+		mach_heartbeat ( 1 );
+	    else if (cnt == 7 || cnt == dist+7)
+		mach_heartbeat ( 0 );
+
+	    if (++cnt > period) {
+		cnt = 0;
+		/* The hyperbolic function below modifies the heartbeat period
+		 * length in dependency of the current (5min) load. It goes
+		 * through the points f(0)=126, f(1)=86, f(5)=51,
+		 * f(inf)->30. */
+		period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
+		dist = period / 4;
+	    }
+	}
+
+#endif
+	/* write the timer status back to the control register, 
+	 * to clear the interrupt.  Once again, timer 0 is hard coded */
+	timer_set_csr(CONFIG_XILINX_TIMER_0_BASEADDR,0,csr);
+}
+
+extern rwlock_t xtime_lock;
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ * Taken from /arch/m68knommu/kernel/time.c
+ */
+void do_gettimeofday (struct timeval *tv)
+{
+	extern volatile unsigned long wall_jiffies;
+	unsigned long flags;
+	unsigned long usec, sec, lost;
+
+	read_lock_irqsave (&xtime_lock, flags);
+	usec = mach_gettimeoffset ? mach_gettimeoffset () : 0;
+
+	lost = jiffies-wall_jiffies;
+	if (lost)
+		usec += lost * (1000000/HZ);
+	sec = xtime.tv_sec;
+	usec += xtime.tv_usec;
+	read_unlock_irqrestore (&xtime_lock, flags);
+
+	while (usec >= 1000000) {
+		usec -= 1000000;
+		sec++;
+	}
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+void do_settimeofday (struct timeval *tv)
+{
+	write_lock_irq (&xtime_lock);
+	/* This is revolting. We need to set the xtime.tv_usec
+	 * correctly. However, the value in this location is
+	 * is value at the last tick.
+	 * Discover what correction gettimeofday
+	 * would have done, and then undo it!
+	 */
+#if 0
+	tv->tv_usec -= mach_gettimeoffset ();
+#endif
+
+	while (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+
+	xtime = *tv;
+	time_adjust = 0;		/* stop active adjtime () */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+	write_unlock_irq (&xtime_lock);
+}
+
+static int timer_dev_id;
+static struct irqaction timer_irqaction = {
+	timer_interrupt,
+	SA_INTERRUPT,
+	0,
+	"timer",
+	&timer_dev_id,
+	NULL
+};
+
+void time_init (void)
+{
+	/* query RTC (if avail) to set time on startup */
+	mach_gettimeofday (&xtime);
+	mach_sched_init (&timer_irqaction);
+}
diff -urN linux-2.4.29/arch/microblaze/kernel/xmbserial.c linux-2.4.29-uc1/arch/microblaze/kernel/xmbserial.c
--- linux-2.4.29/arch/microblaze/kernel/xmbserial.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/xmbserial.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,1810 @@
+/*
+ * xmbserial.c -- serial driver for Microblaze/Xilinx UARTLITE
+ *
+ * Copyright (c) 2003      John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * Ripped lock, stock and barrel from mcfserial.c, which is
+ *
+ * Copyright (c) 1999-2003 Greg Ungerer <gerg@snapgear.com>
+ * Copyright (C) 2001-2003 SnapGear Inc. <www.snapgear.com> 
+ * Copyright (c) 2000-2001 Lineo, Inc. <www.lineo.com> 
+ *
+ * Based on code from 68332serial.c which was:
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1998 TSHG
+ * Copyright (c) 1999 Rt-Control Inc. <jeff@uclinux.org>
+ */
+ 
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/wait.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/config.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/console.h>
+#include <linux/version.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/semaphore.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+#include "xuartlite_l.h"
+#include <asm/microblaze_intc.h>
+
+#include <asm/uaccess.h>
+
+#include "xmbserial.h"
+
+/*
+ *	the only event we use
+ */
+#undef RS_EVENT_WRITE_WAKEUP
+#define RS_EVENT_WRITE_WAKEUP 0
+
+struct timer_list xmbrs_timer_struct;
+
+/*
+ *	Default console baud rate,  we use this as the default
+ *	for all ports so init can just open /dev/console and
+ *	keep going.  Perhaps one day the cflag settings for the
+ *	console can be used instead.
+ */
+#ifndef CONSOLE_BAUD_RATE
+#define	CONSOLE_BAUD_RATE	9600
+#define	DEFAULT_CBAUD		B9600
+#endif
+
+int xmbrs_console_inited = 0;
+int xmbrs_console_port = -1;
+int xmbrs_console_baud = CONSOLE_BAUD_RATE;
+int xmbrs_console_cbaud = DEFAULT_CBAUD;
+
+DECLARE_TASK_QUEUE(xmb_tq_serial);
+
+/*
+ *	Driver data structures.
+ */
+struct tty_driver	xmbrs_serial_driver, xmbrs_callout_driver;
+static int		xmbrs_serial_refcount;
+
+/* serial subtype definitions */
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+  
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 128
+
+/* Debugging...
+ */
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+
+#define _INLINE_ inline
+
+#if 0
+	#define db_print_char(x) db_print_char_fn(x)
+#else
+	#define db_print_char(x)
+#endif
+
+#ifdef CONFIG_MICROBLAZE_DEBUG_UART
+void SendByte(volatile unsigned int *baseaddr, unsigned char x)
+{
+	while(baseaddr[XUL_STATUS_REG_OFFSET/4] & XUL_SR_TX_FIFO_FULL)
+		;
+
+	baseaddr[XUL_TX_FIFO_OFFSET/4] = x; 
+}
+
+void db_print_char_fn(char x)
+{
+	if(x=='\n')
+		SendByte((unsigned int *)CONFIG_XILINX_UARTLITE_1_BASEADDR, '\r');
+
+	SendByte((unsigned int *)CONFIG_XILINX_UARTLITE_1_BASEADDR,x);
+}
+
+/* Dump ASCII value of x out to debug serial port */
+void db_print_num(char x)
+{
+	int i,j;
+
+	j=x;
+
+	db_print_char((i=j/100)+'0');
+	j=j-i*100;
+	db_print_char((i=j/10)+'0');
+	j=j-i*10;
+	db_print_char((i=j)+'0');
+	db_print_char('\n');
+}
+
+void db_print(char *string)
+{
+	while(*string)
+		db_print_char(*string++);
+}
+#endif /* CONFIG_MICROBLAZE_DEBUG_UART */
+
+/* Routines to clear the TX and RX FIFOs respectively, whie leaving
+   interrupt status unchanged */
+static inline void Reset_RX_FIFO(volatile unsigned int *uartp)
+{
+	/* Grab status reg to determine interrupt state */
+	unsigned int status = uartp[XUL_STATUS_REG_OFFSET/4];
+
+	/* Merge RX_FIFO reset command with interrupt state */
+	uartp[XUL_CONTROL_REG_OFFSET/4] = (status & XUL_CR_ENABLE_INTR) | 
+					XUL_CR_FIFO_RX_RESET;
+}
+
+static inline void Reset_TX_FIFO(volatile unsigned int *uartp)
+{
+	unsigned int status = uartp[XUL_STATUS_REG_OFFSET/4];
+
+	uartp[XUL_CONTROL_REG_OFFSET/4] = (status & XUL_CR_ENABLE_INTR) | 
+					XUL_CR_FIFO_TX_RESET;
+}
+
+/* Disable interrupt generation by UARTlite */
+static inline void DisableInterrupts(volatile unsigned int *uartp)
+{
+	uartp[XUL_CONTROL_REG_OFFSET/4] = 0x00;
+}
+
+/* Enable interrupt generation by UARTlite */
+static inline void EnableInterrupts(volatile unsigned int *uartp)
+{
+	uartp[XUL_CONTROL_REG_OFFSET/4] = XUL_CR_ENABLE_INTR;
+}
+
+/*
+ *	Configuration table, UARTs to look for at startup.
+ */
+static struct xmb_serial xmbrs_table[] = {
+  { 0, CONFIG_XILINX_UARTLITE_0_BASEADDR, 
+       CONFIG_XILINX_UARTLITE_0_IRQ , ASYNC_BOOT_AUTOCONF }, /* ttyS0 */
+#ifdef CONFIG_XILINX_UARTLITE_1_INSTANCE
+  { 0, CONFIG_XILINX_UARTLITE_1_BASEADDR, 
+       CONFIG_XILINX_UARTLITE_1_IRQ,  ASYNC_BOOT_AUTOCONF } /* ttyS1 */
+#endif
+#ifdef CONFIG_XILINX_UARTLITE_2_INSTANCE
+  { 0, CONFIG_XILINX_UARTLITE_2_BASEADDR, 
+       CONFIG_XILINX_UARTLITE_2_IRQ,  ASYNC_BOOT_AUTOCONF } /* ttyS2 */
+#endif
+#ifdef CONFIG_XILINX_UARTLITE_3_INSTANCE
+  { 0, CONFIG_XILINX_UARTLITE_3_BASEADDR, 
+       CONFIG_XILINX_UARTLITE_3_IRQ,  ASYNC_BOOT_AUTOCONF } /* ttyS3 */
+#endif
+};
+
+#define	NR_PORTS	(sizeof(xmbrs_table) / sizeof(struct xmb_serial))
+
+/* Reverse lookup table to quickly determine serial info from IRQ number */
+static struct xmb_serial* irq_lookup[32];
+
+static struct tty_struct	*xmbrs_serial_table[NR_PORTS];
+static struct termios		*xmbrs_serial_termios[NR_PORTS];
+static struct termios		*xmbrs_serial_termios_locked[NR_PORTS];
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+#ifdef CONFIG_MAGIC_SYSRQ
+/*
+ *	Magic system request keys. Used for debugging...
+ */
+extern int	magic_sysrq_key(int ch);
+#endif
+
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the copy_from_user blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static unsigned char xmbrs_tmp_buf[4096]; /* This is cheating */
+static DECLARE_MUTEX(xmbrs_tmp_buf_sem);
+
+/*
+ *	Forward declarations...
+ */
+static void	xmbrs_wait_until_sent(struct tty_struct *tty, int timeout);
+
+
+static inline int serial_paranoia_check(struct xmb_serial *info,
+					dev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%d, %d) in %s\n";
+	static const char *badinfo =
+		"Warning: null xmb_serial for (%d, %d) in %s\n";
+
+	if (!info) {
+		printk(badinfo, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+	if (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+/*
+ *	Function stubs for boards that do not implement DCD and DTR.
+ */
+static __inline__ unsigned int xmb_getppdcd(unsigned int portnr)
+{
+	return(0);
+}
+
+static __inline__ unsigned int xmb_getppdtr(unsigned int portnr)
+{
+	return(0);
+}
+static __inline__ void xmb_setppdtr(unsigned int portnr, unsigned int dtr)
+{
+}
+
+/*
+ * ------------------------------------------------------------
+ * xmbrs_stop() and xmbrs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * ------------------------------------------------------------
+ */
+static void xmbrs_stop(struct tty_struct *tty)
+{
+	volatile unsigned int	*uartp;
+	struct xmb_serial	*info = (struct xmb_serial *)tty->driver_data;
+	unsigned long		flags;
+
+	if (serial_paranoia_check(info, tty->device, "xmbrs_stop"))
+		return;
+	
+	uartp = (volatile unsigned int *) info->addr;
+	save_flags_cli(flags);
+	DisableInterrupts(uartp);
+	restore_flags(flags);
+}
+
+static void xmbrs_start(struct tty_struct *tty)
+{
+	volatile unsigned int *uartp;
+	struct xmb_serial	*info = (struct xmb_serial *)tty->driver_data;
+	unsigned long		flags;
+	
+	if (serial_paranoia_check(info, tty->device, "xmbrs_start"))
+		return;
+	uartp = (volatile unsigned int *) info->addr;
+	save_flags_cli(flags);
+	EnableInterrupts(uartp);
+	restore_flags(flags);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * xmbrs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: xmbrs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * xmbrs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ * 
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assemble code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static _INLINE_ void xmbrs_sched_event(struct xmb_serial *info, int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &xmb_tq_serial);
+	mark_bh(SERIAL_BH);
+}
+
+static _INLINE_ void receive_chars(struct xmb_serial *info, 
+		volatile unsigned int *uartp)
+{
+	struct tty_struct	*tty = info->tty;
+	unsigned char		status, ch;
+	unsigned int 		in_word;
+
+	if (!tty)
+		return;
+
+	while ((status=uartp[XUL_STATUS_REG_OFFSET/4]) & 
+			XUL_SR_RX_FIFO_VALID_DATA)
+	{
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			/*
+			 * can't take any more data.  Turn off receiver
+			 * so that the interrupt doesn't continually
+			 * occur.
+			 */
+			/* XUartLite_mDisableIntr(uartp); */
+			break;
+		}
+
+		/* Grab char from RX FIFO */
+		in_word = uartp[XUL_RX_FIFO_OFFSET/4];
+		ch = (unsigned char)in_word;
+
+		info->stats.rx++;
+		tty->flip.count++;
+		*tty->flip.flag_buf_ptr++ = 0;
+		
+		/* Store recv'd char in buffer */
+		*tty->flip.char_buf_ptr++ = ch;
+	}
+
+	queue_task(&tty->flip.tqueue, &tq_timer);
+	return;
+}
+
+static _INLINE_ void transmit_chars(struct xmb_serial *info,
+		volatile unsigned int *uartp)
+{
+	if (info->x_char) {
+		/* Send special char, probably flow control */
+		unsigned int ch = info->x_char;
+		uartp[XUL_TX_FIFO_OFFSET/4] = ch;
+		info->x_char=0;
+		info->stats.tx++;
+	}
+
+	/* Don't send anything if there's nothing to send or tty is stopped */
+	if ((info->xmit_cnt <= 0) || info->tty->stopped) {
+		return;
+	}
+	
+	/* Fill the UART TX buffer again */
+	while (!(uartp[XUL_STATUS_REG_OFFSET/4] & XUL_SR_TX_FIFO_FULL)) {
+		unsigned int ch = info->xmit_buf[info->xmit_tail++];
+		uartp[XUL_TX_FIFO_OFFSET/4] = ch;
+		info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+		info->stats.tx++;
+		if (--info->xmit_cnt <= 0)
+			break;
+	}
+
+	if (info->xmit_cnt < WAKEUP_CHARS)
+		xmbrs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+	return;
+}
+
+/*
+ * This is the serial driver's generic interrupt routine
+ */
+void xmbrs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct xmb_serial	*info;
+	unsigned int isr;
+	volatile unsigned int *uartp;
+
+	info = irq_lookup[irq];
+	uartp = (volatile unsigned int *) info->addr;
+
+	isr = uartp[XUL_STATUS_REG_OFFSET/4];
+
+	/* Grab any valid chars */
+	if (isr & XUL_SR_RX_FIFO_VALID_DATA)
+		receive_chars(info, uartp);
+
+	/* If the TX fifo has any room then refill it */
+	/* Better to refill now and delay another interrupt overhead */
+	if(!(isr & XUL_SR_TX_FIFO_FULL))
+		transmit_chars(info, uartp); 
+
+	return;
+}
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * xmbrs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using xmbrs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+	run_task_queue(&xmb_tq_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct xmb_serial	*info = (struct xmb_serial *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+	}
+}
+
+
+/*
+ *	Change of state on a DCD line.
+ */
+void xmbrs_modem_change(struct xmb_serial *info, int dcd)
+{
+	if (info->count == 0)
+		return;
+
+	if (info->flags & ASYNC_CHECK_CD) {
+		if (dcd) {
+			wake_up_interruptible(&info->open_wait);
+		} else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_CALLOUT_NOHUP))) {
+			schedule_task(&info->tqueue_hangup);
+		}
+	}
+}
+
+/*
+ * This routine is called from the scheduler tqueue when the interrupt
+ * routine has signalled that a hangup has occurred.  The path of
+ * hangup processing is:
+ *
+ * 	serial interrupt routine -> (scheduler tqueue) ->
+ * 	do_serial_hangup() -> tty->hangup() -> xmbrs_hangup()
+ * 
+ */
+static void do_serial_hangup(void *private_)
+{
+	struct xmb_serial	*info = (struct xmb_serial *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	tty_hangup(tty);
+}
+
+static int startup(struct xmb_serial * info)
+{
+	volatile unsigned int *uartp;
+	unsigned long		flags;
+	
+	if (info->flags & ASYNC_INITIALIZED)
+		return 0;
+
+	if (!info->xmit_buf) {
+		info->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL);
+		if (!info->xmit_buf)
+			return -ENOMEM;
+	}
+
+	save_flags_cli(flags);
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttyS%d (irq %d)...\n", info->line, info->irq);
+#endif
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+
+	/*
+	 * Lastly enable the UART transmitter and receiver, and
+	 * interrupt enables.
+	 */
+	/*
+	 *	Reset UART, get it into known state...
+	 */
+	uartp = (volatile unsigned int *) info->addr;
+	Reset_RX_FIFO(uartp);
+	EnableInterrupts(uartp);
+
+	info->flags |= ASYNC_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct xmb_serial * info)
+{
+	volatile unsigned int *uartp;
+	unsigned long		flags;
+
+	if (!(info->flags & ASYNC_INITIALIZED))
+		return;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Shutting down serial port %d (irq %d)....\n", info->line,
+	       info->irq);
+#endif
+	
+	uartp = (volatile unsigned int *) info->addr;
+	save_flags_cli(flags); 		/* Disable interrupts */
+
+	/* Disable interrupts and clear RX FIFO */
+	DisableInterrupts(uartp);
+	Reset_RX_FIFO(uartp);
+
+	if (info->xmit_buf) {
+		free_page((unsigned long) info->xmit_buf);
+		info->xmit_buf = 0;
+	}
+
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+	
+	info->flags &= ~ASYNC_INITIALIZED;
+	restore_flags(flags);
+}
+
+/* Force a refill of the TX FIFO.  This happens in user space, outside of
+   interrupts so we cli() for the duration to prevent corruption of the
+   output buffer data structure */
+void force_tx_fifo_fill(struct xmb_serial *info)
+{
+	unsigned int flags;
+	volatile unsigned int *uartp=(volatile unsigned int *)info->addr;
+
+	save_flags(flags);
+
+	/* Block until TX FIFO can take more chars */
+	while(uartp[XUL_STATUS_REG_OFFSET/4] & XUL_SR_TX_FIFO_FULL)
+		;
+	cli();
+
+	/* Force out any special character */
+	if (info->x_char) {
+		/* Send special char, probably flow control */
+		unsigned int ch = info->x_char;
+		uartp[XUL_TX_FIFO_OFFSET/4]=ch;
+		info->x_char=0;
+		info->stats.tx++;
+	}
+
+	restore_flags(flags);
+	cli();
+	/* Don't send anything if there's nothing to send or tty is stopped */
+	if ((info->xmit_cnt <= 0) || info->tty->stopped) {
+		restore_flags(flags);
+		return;
+	}
+	restore_flags(flags);
+	
+	/* Fill the UART TX buffer again */
+	while(1) {
+		unsigned int ch;
+
+		if(uartp[XUL_STATUS_REG_OFFSET/4] & XUL_SR_TX_FIFO_FULL)
+			break;
+
+		cli();
+		ch = info->xmit_buf[info->xmit_tail++];
+		uartp[XUL_TX_FIFO_OFFSET/4]=ch;
+		info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+		info->stats.tx++;
+		if (--info->xmit_cnt <= 0)
+			break;
+		restore_flags(flags);
+	}
+
+	restore_flags(flags);
+
+	if (info->xmit_cnt < WAKEUP_CHARS)
+		xmbrs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+	return;
+}
+
+
+static void xmbrs_flush_chars(struct tty_struct *tty)
+{
+	volatile unsigned int *uartp;
+	struct xmb_serial	*info = (struct xmb_serial *)tty->driver_data;
+	unsigned long		flags;
+
+	if (serial_paranoia_check(info, tty->device, "xmbrs_flush_chars"))
+		return;
+
+	uartp = (volatile unsigned int *) info->addr;
+	EnableInterrupts(uartp);
+
+	/* If there are chars waiting in RX buffer then enable interrupt
+	   to permit receiving them */
+	save_flags_cli(flags);
+	if ( (uartp[XUL_STATUS_REG_OFFSET/4] & XUL_SR_RX_FIFO_VALID_DATA) &&
+			(info->flags & ASYNC_INITIALIZED) ) {
+		EnableInterrupts(uartp);
+	}
+
+	/* Any chars pending to go out (and tty not stopped etc)? */
+	if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
+	    !info->xmit_buf)
+		return;
+
+	/* Force remaining chars out */
+	save_flags_cli(flags);
+	EnableInterrupts(uartp);
+	force_tx_fifo_fill(info);
+	restore_flags(flags);
+}
+
+static int xmbrs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	struct xmb_serial	*info = (struct xmb_serial *)tty->driver_data;
+	unsigned long		flags;
+	int			c, total = 0;
+	volatile unsigned int *uartp = (volatile unsigned int *)info->addr;
+
+	if (serial_paranoia_check(info, tty->device, "xmbrs_write"))
+		return 0;
+
+	if (!tty || !info->xmit_buf)
+		return 0;
+	
+	save_flags(flags);
+	while (1) {
+		cli();		
+		c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				   SERIAL_XMIT_SIZE - info->xmit_head));
+
+		if (c <= 0) {
+			restore_flags(flags);
+			break;
+		}
+
+		if (from_user) {
+			down(&xmbrs_tmp_buf_sem);
+			copy_from_user(xmbrs_tmp_buf, buf, c);
+			restore_flags(flags);
+			cli();		
+			c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				       SERIAL_XMIT_SIZE - info->xmit_head));
+			memcpy(info->xmit_buf + info->xmit_head, xmbrs_tmp_buf, c);
+			up(&xmbrs_tmp_buf_sem);
+		} else
+			memcpy(info->xmit_buf + info->xmit_head, buf, c);
+
+		info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+		info->xmit_cnt += c;
+		restore_flags(flags); 
+
+		buf += c;
+		count -= c;
+		total += c;
+	}
+
+	if(!tty->stopped) {
+		cli();
+		EnableInterrupts(uartp);
+
+		/* Kick start the TX FIFO if necessary */
+		if(uartp[XUL_STATUS_REG_OFFSET/4] & XUL_SR_TX_FIFO_EMPTY)
+			force_tx_fifo_fill(info); 
+		restore_flags(flags);
+	}
+
+	return total;
+}
+
+static int xmbrs_write_room(struct tty_struct *tty)
+{
+	struct xmb_serial *info = (struct xmb_serial *)tty->driver_data;
+	int	ret;
+				
+	if (serial_paranoia_check(info, tty->device, "xmbrs_write_room"))
+		return 0;
+	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
+	if (ret < 0)
+		ret = 0;
+	return ret;
+}
+
+static int xmbrs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct xmb_serial *info = (struct xmb_serial *)tty->driver_data;
+					
+	if (serial_paranoia_check(info, tty->device, "xmbrs_chars_in_buffer"))
+		return 0;
+
+	return (info->xmit_cnt);
+}
+
+static void xmbrs_flush_buffer(struct tty_struct *tty)
+{
+	struct xmb_serial	*info = (struct xmb_serial *)tty->driver_data;
+	unsigned long		flags;
+				
+	if (serial_paranoia_check(info, tty->device, "xmbrs_flush_buffer"))
+		return;
+
+	save_flags_cli(flags);
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+	restore_flags(flags);
+
+	wake_up_interruptible(&tty->write_wait);
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * ------------------------------------------------------------
+ * xmbrs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void xmbrs_throttle(struct tty_struct * tty)
+{
+	struct xmb_serial *info = (struct xmb_serial *)tty->driver_data;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("throttle %s: %d....\n", _tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "xmbrs_throttle"))
+		return;
+	
+	if (I_IXOFF(tty)) {
+		/* Force STOP_CHAR (xoff) out */
+		volatile unsigned int *uartp;
+		unsigned long		flags;
+		info->x_char = STOP_CHAR(tty);
+		uartp = (volatile unsigned int *) info->addr;
+		save_flags_cli(flags);
+		EnableInterrupts(uartp);
+		force_tx_fifo_fill(info);
+		restore_flags(flags);
+	}
+
+}
+
+static void xmbrs_unthrottle(struct tty_struct * tty)
+{
+	struct xmb_serial *info = (struct xmb_serial *)tty->driver_data;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("unthrottle %s: %d....\n", _tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "xmbrs_unthrottle"))
+		return;
+	
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else {
+			/* Force START_CHAR (xon) out */
+			volatile unsigned int *uartp;
+			unsigned long		flags;
+			info->x_char = START_CHAR(tty);
+			uartp = (volatile unsigned int *) info->addr;
+			save_flags_cli(flags);
+			EnableInterrupts(uartp);
+			force_tx_fifo_fill(info); 
+			restore_flags(flags);
+		}
+	}
+
+}
+
+/*
+ * ------------------------------------------------------------
+ * xmbrs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int get_serial_info(struct xmb_serial * info,
+			   struct serial_struct * retinfo)
+{
+	struct serial_struct tmp;
+  
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = info->type;
+	tmp.line = info->line;
+	tmp.port = info->addr;
+	tmp.irq = info->irq;
+	tmp.flags = info->flags;
+	tmp.baud_base = info->baud_base;
+	tmp.close_delay = info->close_delay;
+	tmp.closing_wait = info->closing_wait;
+	tmp.custom_divisor = info->custom_divisor;
+	copy_to_user(retinfo,&tmp,sizeof(*retinfo));
+	return 0;
+}
+
+static int set_serial_info(struct xmb_serial * info,
+			   struct serial_struct * new_info)
+{
+	struct serial_struct new_serial;
+	struct xmb_serial old_info;
+	int 			retval = 0;
+
+	if (!new_info)
+		return -EFAULT;
+	copy_from_user(&new_serial,new_info,sizeof(new_serial));
+	old_info = *info;
+
+	if (!suser()) {
+		if ((new_serial.baud_base != info->baud_base) ||
+		    (new_serial.type != info->type) ||
+		    (new_serial.close_delay != info->close_delay) ||
+		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
+		     (info->flags & ~ASYNC_USR_MASK)))
+			return -EPERM;
+		info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+			       (new_serial.flags & ASYNC_USR_MASK));
+		info->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	if (info->count > 1)
+		return -EBUSY;
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+	info->baud_base = new_serial.baud_base;
+	info->flags = ((info->flags & ~ASYNC_FLAGS) |
+			(new_serial.flags & ASYNC_FLAGS));
+	info->type = new_serial.type;
+	info->close_delay = new_serial.close_delay;
+	info->closing_wait = new_serial.closing_wait;
+
+check_and_exit:
+	retval = startup(info);
+	return retval;
+}
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space. 
+ */
+static int get_lsr_info(struct xmb_serial * info, unsigned int *value)
+{
+	volatile unsigned int *uartp;
+	unsigned long		flags;
+	unsigned char		status;
+
+	uartp = (volatile unsigned int *) info->addr;
+	save_flags_cli(flags);
+	/* FIXME */
+	status = (uartp[XUL_STATUS_REG_OFFSET/4] & XUL_SR_TX_FIFO_EMPTY) ? TIOCSER_TEMT : 0;
+	restore_flags(flags);
+
+	put_user(status,value);
+	return 0;
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void send_break(	struct xmb_serial * info, int duration)
+{
+	volatile unsigned int *uartp;
+	unsigned long		flags;
+
+	if (!info->addr)
+		return;
+	current->state = TASK_INTERRUPTIBLE;
+	uartp = (volatile unsigned int *) info->addr;
+
+	save_flags_cli(flags);
+	/* uartp[XMBUART_UCR] = XMBUART_UCR_CMDBREAKSTART; */
+	schedule_timeout(duration);
+	/* uartp[XMBUART_UCR] = XMBUART_UCR_CMDBREAKSTOP; */
+	restore_flags(flags);
+}
+
+static int xmbrs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	struct xmb_serial * info = (struct xmb_serial *)tty->driver_data;
+	unsigned int val;
+	int retval, error;
+	int dtr, rts;
+
+	if (serial_paranoia_check(info, tty->device, "xmbrs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
+	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+	
+	switch (cmd) {
+		case TCSBRK:	/* SVID version: non-zero arg --> no break */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (!arg)
+				send_break(info, HZ/4);	/* 1/4 second */
+			return 0;
+		case TCSBRKP:	/* support for POSIX tcsendbreak() */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+			return 0;
+		case TIOCGSOFTCAR:
+			error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long));
+			if (error)
+				return error;
+			put_user(C_CLOCAL(tty) ? 1 : 0,
+				    (unsigned long *) arg);
+			return 0;
+		case TIOCSSOFTCAR:
+			get_user(arg, (unsigned long *) arg);
+			tty->termios->c_cflag =
+				((tty->termios->c_cflag & ~CLOCAL) |
+				 (arg ? CLOCAL : 0));
+			return 0;
+		case TIOCGSERIAL:
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+						sizeof(struct serial_struct));
+			if (error)
+				return error;
+			return get_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSSERIAL:
+			return set_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSERGETLSR: /* Get line status register */
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+				sizeof(unsigned int));
+			if (error)
+				return error;
+			else
+			    return get_lsr_info(info, (unsigned int *) arg);
+
+		case TIOCSERGSTRUCT:
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+						sizeof(struct xmb_serial));
+			if (error)
+				return error;
+			copy_to_user((struct xmb_serial *) arg,
+				    info, sizeof(struct xmb_serial));
+			return 0;
+			
+		case TIOCMGET:
+			if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+                            sizeof(unsigned int))))
+                                return(error);
+			val = 0;
+			put_user(val, (unsigned int *) arg);
+			break;
+
+                case TIOCMBIS:
+			if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+                            sizeof(unsigned int))))
+				return(error);
+
+			get_user(val, (unsigned int *) arg);
+			rts = (val & TIOCM_RTS) ? 1 : -1;
+			dtr = (val & TIOCM_DTR) ? 1 : -1;
+			break;
+
+                case TIOCMBIC:
+			if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+                            sizeof(unsigned int))))
+				return(error);
+			get_user(val, (unsigned int *) arg);
+			rts = (val & TIOCM_RTS) ? 0 : -1;
+			dtr = (val & TIOCM_DTR) ? 0 : -1;
+			break;
+
+                case TIOCMSET:
+			if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+                            sizeof(unsigned int))))
+				return(error);
+			get_user(val, (unsigned int *) arg);
+			rts = (val & TIOCM_RTS) ? 1 : 0;
+			dtr = (val & TIOCM_DTR) ? 1 : 0;
+			break;
+
+#ifdef TIOCSET422
+		case TIOCSET422:
+			get_user(val, (unsigned int *) arg);
+			xmb_setpa(XMBPP_PA11, (val ? 0 : XMBPP_PA11));
+			break;
+		case TIOCGET422:
+			val = (xmb_getpa() & XMBPP_PA11) ? 0 : 1;
+			put_user(val, (unsigned int *) arg);
+			break;
+#endif
+
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+static void xmbrs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	if (tty->termios->c_cflag == old_termios->c_cflag)
+		return;
+
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+#if 0
+		xmbrs_start(tty);
+#endif
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * xmbrs_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * S structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void xmbrs_close(struct tty_struct *tty, struct file * filp)
+{
+	volatile unsigned int *uartp;
+	struct xmb_serial	*info = (struct xmb_serial *)tty->driver_data;
+	unsigned long		flags;
+
+	if (!info || serial_paranoia_check(info, tty->device, "xmbrs_close"))
+		return;
+	
+	save_flags_cli(flags);
+	
+	if (tty_hung_up_p(filp)) {
+		restore_flags(flags);
+		return;
+	}
+	
+#ifdef SERIAL_DEBUG_OPEN
+	printk("xmbrs_close ttyS%d, count = %d\n", info->line, info->count);
+#endif
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  Info->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("xmbrs_close: bad serial port count; tty->count is 1, "
+		       "info->count is %d\n", info->count);
+		info->count = 1;
+	}
+	if (--info->count < 0) {
+		printk("xmbrs_close: bad serial port count for ttyS%d: %d\n",
+		       info->line, info->count);
+		info->count = 0;
+	}
+	if (info->count) {
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= ASYNC_CLOSING;
+
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & ASYNC_NORMAL_ACTIVE)
+		info->normal_termios = *tty->termios;
+	if (info->flags & ASYNC_CALLOUT_ACTIVE)
+		info->callout_termios = *tty->termios;
+
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+	uartp = (volatile unsigned int *) info->addr;
+	DisableInterrupts(uartp);
+
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (tty->ldisc.num != tty_ldiscs[N_TTY].num) {
+		if (tty->ldisc.close)
+			(tty->ldisc.close)(tty);
+		tty->ldisc = tty_ldiscs[N_TTY];
+		tty->termios->c_line = N_TTY;
+		if (tty->ldisc.open)
+			(tty->ldisc.open)(tty);
+	}
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
+			 ASYNC_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	restore_flags(flags);
+}
+
+/*
+ * xmbrs_wait_until_sent() --- wait until the transmitter is empty
+ */
+static void
+xmbrs_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+
+	struct xmb_serial * info = (struct xmb_serial *)tty->driver_data;
+	volatile unsigned int *uartp;
+	unsigned long orig_jiffies, fifo_time, char_time;
+	
+	if (serial_paranoia_check(info, tty->device, "xmbrs_wait_until_sent"))
+		return;
+	
+	orig_jiffies = jiffies;
+
+	/*
+	 * Set the check interval to be 1/5 of the approximate time
+	 * to send the entire fifo, and make it at least 1.  The check
+	 * interval should also be less than the timeout.
+	 *
+	 * Note: we have to use pretty tight timings here to satisfy
+	 * the NIST-PCTS.
+	 */
+	fifo_time = (XUL_FIFO_SIZE * HZ * 10) / info->baud;
+	char_time = fifo_time / 5;
+	if (char_time == 0)
+		char_time = 1;
+	if (timeout && timeout < char_time)
+		char_time = timeout;
+
+	/*
+	 * Clamp the timeout period at 2 * the time to empty the
+	 * fifo.  Just to be safe, set the minimum at .5 seconds.
+	 */
+	fifo_time *= 2;
+	if (fifo_time < (HZ/2))
+		fifo_time = HZ/2;
+	if (!timeout || timeout > fifo_time)
+		timeout = fifo_time;
+
+	/*
+	 * Account for the number of bytes in the UART
+	 * transmitter FIFO plus any byte being shifted out.
+	 */
+	uartp = (volatile unsigned int *) info->addr;
+	for (;;) {
+		unsigned int status = uartp[XUL_STATUS_REG_OFFSET/4];
+
+		if(status & XUL_SR_TX_FIFO_EMPTY)
+			break;
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(char_time);
+		if (signal_pending(current))
+			break;
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			break;
+	}
+}
+		
+/*
+ * xmbrs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+void xmbrs_hangup(struct tty_struct *tty)
+{
+	struct xmb_serial * info = (struct xmb_serial *)tty->driver_data;
+	
+	if (serial_paranoia_check(info, tty->device, "xmbrs_hangup"))
+		return;
+	
+	xmbrs_flush_buffer(tty);
+	shutdown(info);
+	info->event = 0;
+	info->count = 0;
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * xmbrs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file * filp,
+			   struct xmb_serial *info)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int		retval;
+	int		do_clocal = 0;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (info->flags & ASYNC_CLOSING) {
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		if (info->flags & ASYNC_HUP_NOTIFY)
+			return -EAGAIN;
+		else
+			return -ERESTARTSYS;
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & ASYNC_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+		    return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+		    return -EBUSY;
+		info->flags |= ASYNC_CALLOUT_ACTIVE;
+		return 0;
+	}
+	
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & ASYNC_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= ASYNC_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
+		if (info->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+	
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, info->count is dropped by one, so that
+	 * xmbrs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready before block: ttyS%d, count = %d\n",
+	       info->line, info->count);
+#endif
+	info->count--;
+	info->blocked_open++;
+	while (1) {
+		cli();
+		sti();
+		current->state = TASK_INTERRUPTIBLE;
+		if (tty_hung_up_p(filp) ||
+		    !(info->flags & ASYNC_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & ASYNC_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;	
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    !(info->flags & ASYNC_CLOSING) &&
+		    (do_clocal))
+			break;
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef SERIAL_DEBUG_OPEN
+		printk("block_til_ready blocking: ttyS%d, count = %d\n",
+		       info->line, info->count);
+#endif
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&info->open_wait, &wait);
+	if (!tty_hung_up_p(filp))
+		info->count++;
+	info->blocked_open--;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready after blocking: ttyS%d, count = %d\n",
+	       info->line, info->count);
+#endif
+	if (retval)
+		return retval;
+	info->flags |= ASYNC_NORMAL_ACTIVE;
+	return 0;
+}	
+
+/*
+ * This routine is called whenever a serial port is opened. It
+ * enables interrupts for a serial port, linking in its structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+int xmbrs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct xmb_serial	*info;
+	int 			retval, line;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	if ((line < 0) || (line >= NR_PORTS))
+		return -ENODEV;
+	info = xmbrs_table + line;
+	if (serial_paranoia_check(info, tty->device, "xmbrs_open"))
+		return -ENODEV;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("xmbrs_open ttyS%d, count = %d\n", info->line, info->count);
+#endif
+	info->count++;
+	tty->driver_data = info;
+	info->tty = tty;
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval)
+		return retval;
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("xmbrs_open returning after block_til_ready with %d\n",
+		       retval);
+#endif
+		return retval;
+	}
+
+	if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->normal_termios;
+		else 
+			*tty->termios = info->callout_termios;
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("xmbrs_open ttyS%d successful...\n", info->line);
+#endif
+	return 0;
+}
+
+/*
+ *	Based on the line number set up the internal interrupt stuff.
+ */
+static void xmbrs_irqinit(struct xmb_serial *info)
+{
+	volatile unsigned int *uartp;
+
+	switch (info->line) {
+	case 0:
+	case 1:
+		break;
+	default:
+		printk("SERIAL: don't know how to handle UART %d interrupt?\n",
+			info->line);
+		return;
+	}
+
+	uartp = (volatile unsigned int *) info->addr;
+
+	/* Clear mask, so no surprise interrupts. */
+	DisableInterrupts(uartp);
+
+	if (request_irq(info->irq, xmbrs_interrupt, SA_INTERRUPT,
+	    "Microblaze UARTlite", NULL)) {
+		printk("SERIAL: Unable to attach Xilinx UARTlite %d interrupt "
+			"vector=%d\n", info->line, info->irq);
+	}
+	
+	/* Populate the fast IRQ lookup table */
+	irq_lookup[info->irq] = info;
+
+	/* UART still can't generate interrupts - leave it this way
+	   until it is actually opened */
+
+	return;
+}
+
+char *xmbrs_drivername = "Microblaze UARTlite serial driver version 1.00\n";
+
+/*
+ * Serial stats reporting...
+ */
+int xmbrs_readproc(char *page, char **start, off_t off, int count,
+		         int *eof, void *data)
+{
+	struct xmb_serial	*info;
+	char			str[20];
+	int			len, i;
+
+	len = sprintf(page, xmbrs_drivername);
+	for (i = 0; (i < NR_PORTS); i++) {
+		info = &xmbrs_table[i];
+		len += sprintf((page + len), "%d: port:%x irq=%d baud:%d ",
+			i, info->addr, info->irq, info->baud);
+		if (info->stats.rx || info->stats.tx)
+			len += sprintf((page + len), "tx:%d rx:%d ",
+			info->stats.tx, info->stats.rx);
+		if (info->stats.rxframing)
+			len += sprintf((page + len), "fe:%d ",
+			info->stats.rxframing);
+		if (info->stats.rxparity)
+			len += sprintf((page + len), "pe:%d ",
+			info->stats.rxparity);
+		if (info->stats.rxbreak)
+			len += sprintf((page + len), "brk:%d ",
+			info->stats.rxbreak);
+		if (info->stats.rxoverrun)
+			len += sprintf((page + len), "oe:%d ",
+			info->stats.rxoverrun);
+
+		str[0] = str[1] = 0;
+
+		len += sprintf((page + len), "%s\n", &str[1]);
+	}
+
+	return(len);
+}
+
+
+/* Finally, routines used to initialize the serial driver. */
+
+static void show_serial_version(void)
+{
+	printk(xmbrs_drivername);
+}
+
+/* xmbrs_init inits the driver */
+static int __init
+xmbrs_init(void)
+{
+	struct xmb_serial	*info;
+	unsigned long		flags;
+	int			i;
+
+	init_bh(SERIAL_BH, do_serial_bh);
+
+	show_serial_version();
+
+	/* Initialize the tty_driver structure */
+	memset(&xmbrs_serial_driver, 0, sizeof(struct tty_driver));
+	xmbrs_serial_driver.magic = TTY_DRIVER_MAGIC;
+	xmbrs_serial_driver.name = "ttyS";
+	xmbrs_serial_driver.major = TTY_MAJOR;
+	xmbrs_serial_driver.minor_start = 64;
+	xmbrs_serial_driver.num = NR_PORTS;
+	xmbrs_serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	xmbrs_serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	xmbrs_serial_driver.init_termios = tty_std_termios;
+
+	xmbrs_serial_driver.init_termios.c_cflag =
+		xmbrs_console_cbaud | CS8 | CREAD | HUPCL | CLOCAL;
+	xmbrs_serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	xmbrs_serial_driver.refcount = &xmbrs_serial_refcount;
+	xmbrs_serial_driver.table = xmbrs_serial_table;
+	xmbrs_serial_driver.termios = xmbrs_serial_termios;
+	xmbrs_serial_driver.termios_locked = xmbrs_serial_termios_locked;
+
+	xmbrs_serial_driver.open = xmbrs_open;
+	xmbrs_serial_driver.close = xmbrs_close;
+	xmbrs_serial_driver.write = xmbrs_write;
+ 	xmbrs_serial_driver.flush_chars = xmbrs_flush_chars;	
+	xmbrs_serial_driver.write_room = xmbrs_write_room;	
+	xmbrs_serial_driver.chars_in_buffer = xmbrs_chars_in_buffer;	
+	xmbrs_serial_driver.flush_buffer = xmbrs_flush_buffer;		
+	xmbrs_serial_driver.ioctl = xmbrs_ioctl;			
+	xmbrs_serial_driver.throttle = xmbrs_throttle;			
+	xmbrs_serial_driver.unthrottle = xmbrs_unthrottle;		
+	xmbrs_serial_driver.set_termios = xmbrs_set_termios;		
+	xmbrs_serial_driver.stop = xmbrs_stop;			
+	xmbrs_serial_driver.start = xmbrs_start;
+	xmbrs_serial_driver.hangup = xmbrs_hangup;			
+	xmbrs_serial_driver.read_proc = xmbrs_readproc;			
+	xmbrs_serial_driver.wait_until_sent = xmbrs_wait_until_sent;	
+	xmbrs_serial_driver.driver_name = "serial";
+
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	xmbrs_callout_driver = xmbrs_serial_driver;
+	xmbrs_callout_driver.name = "cua";
+	xmbrs_callout_driver.major = TTYAUX_MAJOR;
+	xmbrs_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+	xmbrs_callout_driver.read_proc = 0;
+	xmbrs_callout_driver.proc_entry = 0;
+
+	if (tty_register_driver(&xmbrs_serial_driver)) {
+		printk("%s: Couldn't register serial driver\n",__FUNCTION__);
+		return(-EBUSY);
+	}
+
+	if (tty_register_driver(&xmbrs_callout_driver)) {
+		printk("%s: Couldn't register callout driver\n",__FUNCTION__);
+		return(-EBUSY);
+	}
+	
+	save_flags_cli(flags); 
+
+	/*
+	 *	Configure all the attached serial ports.
+	 */
+	for (i = 0, info = xmbrs_table; (i < NR_PORTS); i++, info++) {
+		info->magic = SERIAL_MAGIC;
+		info->line = i;
+		info->tty = 0;
+		info->custom_divisor = 16;
+		info->close_delay = 50;
+		info->closing_wait = 3000;
+		info->x_char = 0;
+		info->event = 0;
+		info->count = 0;
+		info->blocked_open = 0;
+		info->tqueue.routine = do_softint;
+		info->tqueue.data = info;
+		info->tqueue_hangup.routine = do_serial_hangup;
+		info->tqueue_hangup.data = info;
+		info->callout_termios = xmbrs_callout_driver.init_termios;
+		info->normal_termios = xmbrs_serial_driver.init_termios;
+		init_waitqueue_head(&info->open_wait);
+		init_waitqueue_head(&info->close_wait);
+
+		xmbrs_irqinit(info);
+
+		printk("%s%d at 0x%04x (irq = %d)", xmbrs_serial_driver.name,
+			info->line, info->addr, info->irq);
+		printk(" is a Microblaze UARTlite\n");
+	}
+
+	restore_flags(flags);
+	return 0;
+}
+
+module_init(xmbrs_init);
+/* module_exit(xmbrs_fini); */
+
+/****************************************************************************/
+/*                          Serial Console                                  */
+/****************************************************************************/
+
+/*
+ *	Quick and dirty UART initialization, for console output.
+ */
+
+void xmbrs_init_console(void)
+{
+	/*
+	 *	Reset UART, get it into known state...
+	 */
+
+	volatile unsigned int *uartp= (volatile unsigned int *) CONFIG_XILINX_UARTLITE_0_BASEADDR;
+
+	/* Reset TX and RX FIFOs */
+	Reset_RX_FIFO(uartp);
+	Reset_TX_FIFO(uartp);
+
+	/* Disable UART interrupt generation */
+	DisableInterrupts(uartp);
+
+	xmbrs_console_inited++;
+	return;
+}
+
+
+/*
+ *	Setup for console. Argument comes from the boot command line.
+ */
+
+int xmbrs_console_setup(struct console *cp, char *arg)
+{
+	if (!cp)
+		return(-1);
+
+	if (!strncmp(cp->name, "ttyS", 4))
+                xmbrs_console_port = cp->index;
+        else if (!strncmp(cp->name, "cua", 3))
+                xmbrs_console_port = cp->index;
+        else
+                return(-1);
+
+	xmbrs_init_console(); 
+	return(0);
+}
+
+
+static kdev_t xmbrs_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+
+/*
+ *	Output a single character, using UART polled mode.
+ *	This is used for console output.
+ */
+
+void xmbrs_put_char(char ch)
+{
+	volatile unsigned int *uartp, out_word=ch;
+	unsigned long		flags;
+	int			i;
+
+	uartp = (volatile unsigned int *) CONFIG_XILINX_UARTLITE_0_BASEADDR;
+
+	save_flags_cli(flags);
+
+	/* wait for tx buffer not full */
+	for (i = 0; (i < 0x10000); i++) {
+		if (!(uartp[XUL_STATUS_REG_OFFSET/4] & XUL_SR_TX_FIFO_FULL))
+			break;
+	}
+
+	/* Did it drain? */
+	if (i < 0x10000) {
+		/* Send the char */
+		uartp[XUL_TX_FIFO_OFFSET/4]=out_word;
+
+		/* Wait for it to go */
+		for (i = 0; (i < 0x10000); i++)
+			if (!(uartp[XUL_STATUS_REG_OFFSET/4] & XUL_SR_TX_FIFO_FULL))
+				break;
+	}
+
+	/* Was it sent? */
+	if (i >= 0x10000)
+		xmbrs_init_console(); /* try and get it back */
+
+	restore_flags(flags);
+
+	return;
+}
+
+
+/*
+ * rs_console_write is registered for printk output.
+ */
+
+void xmbrs_console_write(struct console *cp, const char *p, unsigned len)
+{
+	if (!xmbrs_console_inited)
+		xmbrs_init_console();
+	while (len-- > 0) {
+		if (*p == '\n')
+			xmbrs_put_char('\r');
+		xmbrs_put_char(*p++);
+	}
+}
+
+/*
+ * declare our consoles
+ */
+
+struct console xmbrs_console = {
+	name:		"ttyS",
+	write:		xmbrs_console_write,
+	read:		NULL,
+	device:		xmbrs_console_device,
+	unblank:	NULL,
+	setup:		xmbrs_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+	cflag:		0,
+	next:		NULL
+};
+
+void xmbrs_console_init(void)
+{
+	register_console(&xmbrs_console);
+	printk(KERN_INFO "Console: xmbserial on UARTLite\n");
+}
+
+/****************************************************************************/
+
diff -urN linux-2.4.29/arch/microblaze/kernel/xmbserial.h linux-2.4.29-uc1/arch/microblaze/kernel/xmbserial.h
--- linux-2.4.29/arch/microblaze/kernel/xmbserial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/kernel/xmbserial.h	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,87 @@
+/*
+ * xmbserial.c -- serial driver for Microblaze UARTLite.
+ *
+ * Copyright (c) 2003 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * Based on code from mcfserial.c which was:
+ * 
+ * Copyright (c) 1999 Greg Ungerer <gerg@snapgear.com>
+ * Copyright (c) 2000-2001 Lineo, Inc. <www.lineo.com>
+ * Copyright (c) 2002 SnapGear Inc., <www.snapgear.com>
+ *
+ * Based on code from 68332serial.c which was:
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1998 TSHG
+ * Copyright (c) 1999 Rt-Control Inc. <jeff@uclinux.org>
+ */ 
+#ifndef _XMB_SERIAL_H
+#define _XMB_SERIAL_H
+
+#include <linux/config.h>
+#include <linux/serial.h>
+
+#ifdef __KERNEL__
+
+/*
+ *	Define a local serial stats structure.
+ */
+
+struct xmb_stats {
+	unsigned int	rx;
+	unsigned int	tx;
+	unsigned int	rxbreak;
+	unsigned int	rxframing;
+	unsigned int	rxparity;
+	unsigned int	rxoverrun;
+};
+
+
+/*
+ * This is our internal structure for each serial port's state.
+ * Each serial port has one of these structures associated with it.
+ */
+
+struct xmb_serial {
+	int			magic;
+	unsigned int		addr;		/* UART memory address */
+	int			irq;
+	int			flags; 		/* defined in tty.h */
+	int			type; 		/* UART type */
+	struct tty_struct 	*tty;
+	unsigned int		baud;
+	int			sigs;
+	int			custom_divisor;
+	int			x_char;	/* xon/xoff character */
+	int			baud_base;
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	unsigned long		event;
+	int			line;
+	int			count;	    /* # of fd on device */
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+	unsigned char 		*xmit_buf;
+	int			xmit_head;
+	int			xmit_tail;
+	int			xmit_cnt;
+	struct xmb_stats	stats;
+	struct tq_struct	tqueue;
+	struct tq_struct	tqueue_hangup;
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+#if LINUX_VERSION_CODE <= 0x020100
+	struct wait_queue	*open_wait;
+	struct wait_queue	*close_wait;
+#else
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+#endif
+
+};
+
+#endif /* __KERNEL__ */
+
+#endif /* _XMB_SERIAL_H */
diff -urN linux-2.4.29/arch/microblaze/lib/checksum.c linux-2.4.29-uc1/arch/microblaze/lib/checksum.c
--- linux-2.4.29/arch/microblaze/lib/checksum.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/lib/checksum.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,157 @@
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		IP/TCP/UDP checksumming routines
+ *
+ * Authors:	Jorge Cwik, <jorge@laser.satlink.net>
+ *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ *		Tom May, <ftom@netcom.com>
+ *		Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
+ *		Lots of code moved from tcp.c and ip.c; see those files
+ *		for more names.
+ *
+ * 03/02/96	Jes Sorensen, Andreas Schwab, Roman Hodek:
+ *		Fixed some nasty bugs, causing some horrible crashes.
+ *		A: At some points, the sum (%0) was used as
+ *		length-counter instead of the length counter
+ *		(%1). Thanks to Roman Hodek for pointing this out.
+ *		B: GCC seems to mess up if one uses too many
+ *		data-registers to hold input values and one tries to
+ *		specify d0 and d1 as scratch registers. Letting gcc choose these
+ *      registers itself solves the problem.
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+  
+/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most
+   of the assembly has to go. */
+
+#include <net/checksum.h>
+#include <asm/checksum.h>
+
+static inline unsigned short from32to16(unsigned long x)
+{
+	/* add up 16-bit and 16-bit for 16+c bit */
+	x = (x & 0xffff) + (x >> 16);
+	/* add up carry.. */
+	x = (x & 0xffff) + (x >> 16);
+	return x;
+}
+
+static unsigned long do_csum(const unsigned char * buff, int len)
+{
+	int odd, count;
+	unsigned long result = 0;
+
+	if (len <= 0)
+		goto out;
+	odd = 1 & (unsigned long) buff;
+	if (odd) {
+		result = *buff;
+		len--;
+		buff++;
+	}
+	count = len >> 1;		/* nr of 16-bit words.. */
+	if (count) {
+		if (2 & (unsigned long) buff) {
+			result += *(unsigned short *) buff;
+			count--;
+			len -= 2;
+			buff += 2;
+		}
+		count >>= 1;		/* nr of 32-bit words.. */
+		if (count) {
+		        unsigned long carry = 0;
+			do {
+				unsigned long w = *(unsigned long *) buff;
+				count--;
+				buff += 4;
+				result += carry;
+				result += w;
+				carry = (w > result);
+			} while (count);
+			result += carry;
+			result = (result & 0xffff) + (result >> 16);
+		}
+		if (len & 2) {
+			result += *(unsigned short *) buff;
+			buff += 2;
+		}
+	}
+	if (len & 1)
+		result += (*buff << 8);
+	result = from32to16(result);
+	if (odd)
+		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+	return result;
+}
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ */
+unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
+{
+	return ~do_csum(iph,ihl*4);
+}
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum)
+{
+	unsigned int result = do_csum(buff, len);
+
+	/* add in old sum, and carry.. */
+	result += sum;
+	if(sum > result)
+		result += 1;
+	return result;
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+unsigned short ip_compute_csum(const unsigned char * buff, int len)
+{
+	return ~do_csum(buff,len);
+}
+
+	/*
+ * copy from fs while checksumming, otherwise like csum_partial
+	 */
+
+unsigned int
+csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err)
+{
+	if (csum_err) *csum_err = 0;
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
+
+/*
+ * copy from ds while checksumming, otherwise like csum_partial
+ */
+		
+unsigned int
+csum_partial_copy(const char *src, char *dst, int len, int sum)
+{
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
diff -urN linux-2.4.29/arch/microblaze/lib/Makefile linux-2.4.29-uc1/arch/microblaze/lib/Makefile
--- linux-2.4.29/arch/microblaze/lib/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/lib/Makefile	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,10 @@
+#
+# arch/microblaze/lib/Makefile
+#
+
+L_TARGET = lib.a
+
+obj-y  = memset.o memcpy.o memmove.o checksum.o muldi3_hard.o
+
+include $(TOPDIR)/Rules.make
+
diff -urN linux-2.4.29/arch/microblaze/lib/memcpy.c linux-2.4.29-uc1/arch/microblaze/lib/memcpy.c
--- linux-2.4.29/arch/microblaze/lib/memcpy.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/lib/memcpy.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,126 @@
+/* Filename: memcpy.c
+ *
+ * Reasonably optimised generic C-code for memcpy on Microblaze
+ * This is generic C code to do efficient, alignment-aware memcpy.
+ *
+ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
+ * http://www.embedded.com/showArticle.jhtml?articleID=19205567
+ * 
+ * Attempts were made, unsuccesfully, to contact the original 
+ * author of this code (Michael Morrow, Intel).  Below is the original
+ * copyright notice.
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/compiler.h>
+
+#include <asm/string.h>
+
+/* Macro's for bytebliting unaligned data blocks */
+
+/* Big-endian MACROS */
+
+#define BYTE_BLIT_INIT(s,h,o) \
+(h) = *((unsigned *)(s))++ << (o)
+
+#define BYTE_BLIT_STEP(d,s,h,o) \
+{ register unsigned _v_; _v_ = *((unsigned *)(s))++; \
+ *((unsigned *)(d))++ = (h) | _v_ >> (32-(o)); \
+ (h) = _v_ << (o); \
+}
+
+void *memcpy(void *d, const void *s, __kernel_size_t c)
+{
+  void *r = d;
+
+  if (c >= 4)
+  {
+	unsigned x, a, h, align;
+
+	/* Align the destination to a word boundry. */
+	/* This is done in an endian independant manner. */
+	switch ((unsigned) d & 3)
+	{
+	 case 1: *((char *)d)++ = *((char *)s)++; c--;
+	 case 2: *((char *)d)++ = *((char *)s)++; c--;
+	 case 3: *((char *)d)++ = *((char *)s)++; c--;
+	}
+	/* Choose a copy scheme based on the source */
+	/* alignment relative to destination. */
+	switch((unsigned) s & 3)
+	{
+	 case 0x0: /* Both byte offsets are aligned */
+
+	   for (; c >= 4; c -= 4)
+             *((unsigned *)d)++ = *((unsigned *)s)++;
+
+	   break;
+
+	 case 0x1: /* Unaligned - Off by 1 */
+	   /* Word align the source */
+	   a = (unsigned) s & ~3;
+
+	   /* Load the holding buffer */
+	   BYTE_BLIT_INIT(a,h,8);
+
+	   for (; c >= 4; c -= 4)
+             BYTE_BLIT_STEP(d,a,h,8);
+
+	   /* Realign the source */
+	   (unsigned) s = a - 3;
+	   break;
+
+	 case 0x2: /* Unaligned - Off by 2 */
+	   /* Word align the source */
+	   a = (unsigned) s & ~3;
+
+	   /* Load the holding buffer */
+	   BYTE_BLIT_INIT(a,h,16);
+
+	   for (; c >= 4; c -= 4)
+             BYTE_BLIT_STEP(d,a,h,16);
+
+	   /* Realign the source */
+	   (unsigned) s = a - 2;
+	   break;
+
+	 case 0x3: /* Unaligned - Off by 3 */
+	   /* Word align the source */
+	   a = (unsigned) s & ~3;
+
+	   /* Load the holding buffer */
+	   BYTE_BLIT_INIT(a,h,24);
+
+	   for (; c >= 4; c -= 4)
+             BYTE_BLIT_STEP(d,a,h,24);
+
+	   /* Realign the source */
+	   (unsigned) s = a - 1;
+	   break;
+	}
+
+  }
+ /* Finish off any remaining bytes */
+/* simple fast copy, ... unless a cache boundry is crossed */
+  switch(c)
+  {
+     case 3: *((char *)d)++ = *((char *)s)++;
+     case 2: *((char *)d)++ = *((char *)s)++;
+     case 1: *((char *)d)++ = *((char *)s)++;
+  }
+
+  return r;
+}
+
+
diff -urN linux-2.4.29/arch/microblaze/lib/memmove.c linux-2.4.29-uc1/arch/microblaze/lib/memmove.c
--- linux-2.4.29/arch/microblaze/lib/memmove.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/lib/memmove.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,139 @@
+/* Filename: memmove.c
+ *
+ * Reasonably optimised generic C-code for memcpy on Microblaze
+ * This is generic C code to do efficient, alignment-aware memmove.
+ *
+ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
+ * http://www.embedded.com/showArticle.jhtml?articleID=19205567
+ * 
+ * Attempts were made, unsuccesfully, to contact the original 
+ * author of this code (Michael Morrow, Intel).  Below is the original
+ * copyright notice.
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/compiler.h>
+
+#include <asm/string.h>
+
+/* Macro's for bytebliting unaligned data blocks */
+
+/* Big-endian MACROS */
+
+#define BYTE_BLIT_INIT(s,h,o) \
+(h) = *(--(unsigned *)(s)) >> (32-(o))
+
+#define BYTE_BLIT_STEP(d,s,h,o) \
+{ register unsigned _v_; _v_ = *(--(unsigned *)(s)); \
+ *(--(unsigned *)(d)) = _v_ << (o) | (h); \
+ (h) = _v_ >> (32-(o)); \
+}
+
+void *memmove(void *d, const void *s, __kernel_size_t c)
+{
+  void *r = d;
+
+  /* Use memcpy when source is higher than dest */
+  if(d <= s)
+    return memcpy(d,s,c);
+
+  /* Do a descending copy - this is a bit trickier! */
+  d += c;
+  s += c;
+
+  if (c >= 4)
+  {
+	unsigned x, a, h, align;
+
+	/* Align the destination to a word boundry. */
+	/* This is done in an endian independant manner. */
+	switch ((unsigned) d & 3)
+	{
+         case 3: *(--(char *)d) = *(--(char *)s); c--;
+         case 2: *(--(char *)d) = *(--(char *)s); c--;
+         case 1: *(--(char *)d) = *(--(char *)s); c--;
+	}
+	/* Choose a copy scheme based on the source */
+	/* alignment relative to destination. */
+	switch((unsigned) s & 3)
+	{
+	 case 0x0: /* Both byte offsets are aligned */
+
+	   for (; c >= 4; c -= 4)
+             *(--(unsigned *)d) = *(--(unsigned *)s);
+
+	   break;
+
+	 case 0x1: /* Unaligned - Off by 1 */
+	   /* Word align the source */
+	   a = (unsigned) (s+4) & ~3;
+
+	   /* Load the holding buffer */
+	   BYTE_BLIT_INIT(a,h,8);
+
+	   for (; c >= 4; c -= 4)
+             BYTE_BLIT_STEP(d,a,h,8);
+
+	   /* Realign the source */
+	   (unsigned) s = a + 1;
+	   break;
+
+	 case 0x2: /* Unaligned - Off by 2 */
+	   /* Word align the source */
+	   a = (unsigned) (s+4) & ~3;
+
+	   /* Load the holding buffer */
+	   BYTE_BLIT_INIT(a,h,16);
+
+	   for (; c >= 4; c -= 4)
+             BYTE_BLIT_STEP(d,a,h,16);
+
+	   /* Realign the source */
+	   (unsigned) s = a + 2;
+	   break;
+
+	 case 0x3: /* Unaligned - Off by 3 */
+	   /* Word align the source */
+	   a = (unsigned) (s+4) & ~3;
+
+	   /* Load the holding buffer */
+	   BYTE_BLIT_INIT(a,h,24);
+
+	   for (; c >= 4; c -= 4)
+             BYTE_BLIT_STEP(d,a,h,24);
+
+	   /* Realign the source */
+	   (unsigned) s = a + 3;
+	   break;
+	}
+
+#if 0
+	/* Finish off any remaining bytes */
+	c &= 3;
+	goto finish;
+#endif
+
+  }
+
+	/* simple fast copy, ... unless a cache boundry is crossed */
+	switch(c)
+	{
+	 case 4: *(--(char *)d) = *(--(char *)s);
+	 case 3: *(--(char *)d) = *(--(char *)s);
+	 case 2: *(--(char *)d) = *(--(char *)s);
+	 case 1: *(--(char *)d) = *(--(char *)s);
+	}
+  return r;
+}
+
diff -urN linux-2.4.29/arch/microblaze/lib/memset.c linux-2.4.29-uc1/arch/microblaze/lib/memset.c
--- linux-2.4.29/arch/microblaze/lib/memset.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/lib/memset.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,88 @@
+/* Filename: memset.c
+ *
+ * Reasonably optimised generic C-code for memset on Microblaze
+ * This is generic C code to do efficient, alignment-aware memcpy.
+ *
+ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
+ * http://www.embedded.com/showArticle.jhtml?articleID=19205567
+ * 
+ * Attempts were made, unsuccesfully, to contact the original 
+ * author of this code (Michael Morrow, Intel).  Below is the original
+ * copyright notice. 
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+/* Filename: memcpy.c
+ *
+ * Reasonably optimised generic C-code for memset on Microblaze
+ * Based on demo code originally Copyright 2001 by Intel Corp.
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/compiler.h>
+
+#include <asm/string.h>
+
+void *memset(void *d, int k, __kernel_size_t c)
+{
+  void *r = d;
+  unsigned int wk;
+
+  /* Truncate k to 8 bits */
+  wk=k=(k & 0xFF);
+
+  /* Make a repeating word out of it */
+  wk |= wk << 8;
+  wk |= wk << 8;
+  wk |= wk << 8;
+
+  if (c >= 4)
+  {
+	unsigned x, a, h, align;
+
+	/* Align the destination to a word boundry. */
+	/* This is done in an endian independant manner. */
+	switch ((unsigned) d & 3)
+	{
+	 case 1: *((char *)d)++ = k; c--;
+	 case 2: *((char *)d)++ = k; c--;
+	 case 3: *((char *)d)++ = k; c--;  
+	}
+
+        /* Do as many full-word copies as we can */
+	for (; c >= 4; c -= 4)
+          *((unsigned *)d)++ = wk;
+
+  }
+
+  /* Finish off the rest as byte copies */
+  switch(c)
+  {
+    case 3: *((char *)d)++ = k;	/* fall through */
+    case 2: *((char *)d)++ = k;
+    case 1: *((char *)d)++ = k;
+  }
+  return r;
+}
+
+
diff -urN linux-2.4.29/arch/microblaze/lib/muldi3_hard.S linux-2.4.29-uc1/arch/microblaze/lib/muldi3_hard.S
--- linux-2.4.29/arch/microblaze/lib/muldi3_hard.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/lib/muldi3_hard.S	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,122 @@
+###################################-*-asm*- 
+# 
+# Copyright (c) 2001 Xilinx, Inc.  All rights reserved. 
+# 
+# Xilinx, Inc.  
+# 
+# muldi3_hard.s 
+# 
+# Multiply operation for 64 bit integers, for devices with hard multiply
+#	Input :	Operand1[H] in Reg r5
+#		Operand1[L] in Reg r6		
+#		Operand2[H] in Reg r7
+#		Operand2[L] in Reg r8	
+#	Output: Result[H] in Reg r3
+#		Result[L] in Reg r4	
+# 
+# Explaination:
+#
+# 	Both the input numbers are divided into 16 bit number as follows
+#		op1 = A B C D
+# 		op2 = E F G H
+#	result =    D * H 
+#		 + (C * H + D * G) << 16
+#		 + (B * H + C * G + D * F) << 32
+#		 + (A * H + B * G + C * F + D * E) << 48 
+#
+# 	Only 64 bits of the output are considered
+#
+#######################################
+
+#include <asm/clinkage.h>
+
+	.globl	C_SYMBOL_NAME(muldi3_hardproc)
+	.ent	C_SYMBOL_NAME(muldi3_hardproc)
+
+C_SYMBOL_NAME(muldi3_hardproc):
+	addi	r19,r19,-40
+
+#  Save the input operands on the callers stack
+	swi	r5,r19,44
+	swi	r6,r19,48
+	swi	r7,r19,52
+	swi	r8,r19,56
+
+# Store all the callee saved registers 
+	sw	r20,r19,r0
+	swi	r21,r19,4
+	swi	r22,r19,8
+	swi	r23,r19,12
+	swi	r24,r19,16
+	swi	r25,r19,20
+	swi	r26,r19,24
+	swi	r27,r19,28
+
+# Load all the 16 bit values for A thru H
+	lhui	r20,r19,44   # A
+	lhui	r21,r19,46   # B
+	lhui	r22,r19,48   # C
+	lhui	r23,r19,50   # D
+	lhui	r24,r19,52   # E
+	lhui	r25,r19,54   # F
+	lhui	r26,r19,56   # G
+	lhui	r27,r19,58   # H
+
+# D * H ==> LSB of the result on stack ==> Store1
+	mul	r9,r23,r27
+	swi	r9,r19,36    # Pos2 and Pos3
+
+# Hi (Store1) + C * H + D * G ==> Store2 ==> Pos1 and Pos2
+	lhui	r11,r19,36   # Pos2
+	mul	r9,r22,r27   # C * H
+	mul	r10,r23,r26  # D * G
+	add	r9,r9,r10
+	add	r9,r9,r11
+	shi	r9,r19,36    # Store Pos2
+	swi	r9,r19,32 
+	lhui	r11,r19,32
+	shi	r11,r19,34   # Store Pos1
+
+# Hi (Store2) + B * H + C * G + D * F ==> Store3 ==> Pos0 and Pos1
+	mul	r9,r21,r27  # B * H
+	mul	r10,r22,r26 # C * G
+	add	r9,r9,r11
+	add	r9,r9,r10
+	mul	r10,r23,r25 # D * F
+	add	r9,r9,r10
+	swi	r9,r19,32   # Pos0 and Pos1
+
+# Hi (Store3) + A * H + B * G + C * F + D * E ==> Store3 ==> Pos0
+	lhui	r11,r19,32  # Pos0
+	mul	r9,r20,r27  # A * H
+	mul	r10,r21,r26 # B * G
+	add	r9,r9,r11
+	add 	r9,r9,r10
+	mul	r10,r22,r25 # C * F
+	mul	r11,r23,r24 # D * E
+	add	r9,r9,r10
+	add	r9,r9,r11
+	sext16	r9,r9       # Sign extend the MSB
+	shi	r9,r19,32
+
+# Move results to r3 and r4
+	lwi	r3,r19,32  # Hi Part
+	lwi	r4,r19,36  # Lo Part
+
+# Restore Callee saved registers
+	lw	r20,r19,r0
+	lwi	r21,r19,4
+	lwi	r22,r19,8
+	lwi	r23,r19,12
+	lwi	r24,r19,16
+	lwi	r25,r19,20
+	lwi	r26,r19,24
+	lwi	r27,r19,28
+
+# Restore Frame and return	
+	rtsd	r15,8
+	addi	r19,r19,40
+
+.end C_SYMBOL_NAME(muldi3_hardproc)
+	
+
diff -urN linux-2.4.29/arch/microblaze/linux.ld.in linux-2.4.29-uc1/arch/microblaze/linux.ld.in
--- linux-2.4.29/arch/microblaze/linux.ld.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/linux.ld.in	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,208 @@
+/*
+ * arch/microblaze/linux.ld.in -- kernel linker script for v850 platforms
+ *
+ *  Copyright (C) 2002,03  NEC Electronics Corporation
+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <asm/clinkage.h>
+
+/* The following macros contain the usual definitions for various data areas.
+   The prefix `RAMK_' is used to indicate macros suitable for kernels loaded
+   into RAM, and similarly `ROMK_' for ROM-resident kernels.  Note that all
+   symbols are prefixed with an extra `_' for compatibility with the v850
+   toolchain.  */
+
+	
+/* Interrupt vectors.  */
+#define INTV_CONTENTS							      \
+		. = ALIGN (0x10) ;					      \
+		__intv_start = . ;					      \
+			*(.intv.reset)	/* Reset vector */		      \
+		. = __intv_start + 0x10 ;				      \
+			*(.intv.common)	/* Vectors common to all v850e proc */\
+		. = __intv_start + 0x80 ;				      \
+			*(.intv.mach)	/* Machine-specific int. vectors.  */ \
+		__intv_end = . ;
+
+/* Kernel text segment, and some constant data areas.  */
+#define TEXT_CONTENTS							      \
+		__stext = . ;						      \
+        	*(.text)						      \
+			*(.exit.text)	/* 2.5 convention */		      \
+			*(.text.exit)	/* 2.4 convention */		      \
+			*(.text.lock)					      \
+			*(.exitcall.exit)				      \
+		__real_etext = . ;	/* There may be data after here.  */  \
+			*(.rodata)					      \
+		. = ALIGN (0x4) ;					      \
+			*(.kstrtab)					      \
+		. = ALIGN (4) ;						      \
+		    	*(.call_table_data)				      \
+			*(.call_table_text)				      \
+		. = ALIGN (16) ;	/* Exception table.  */		      \
+		___start___ex_table = . ;				      \
+			*(__ex_table)					      \
+		___stop___ex_table = . ;				      \
+		___start___ksymtab = . ;/* Kernel symbol table.  */	      \
+			*(__ksymtab)					      \
+		___stop___ksymtab = . ;					      \
+		. = ALIGN (4) ;						      \
+		__etext = . ;
+
+/* Kernel data segment.  */
+#define DATA_CONTENTS							      \
+		__sdata = . ;						      \
+        	*(.data)						      \
+			*(.exit.data)	/* 2.5 convention */		      \
+			*(.data.exit)	/* 2.4 convention */		      \
+		. = ALIGN (16) ;					      \
+		*(.data.cacheline_aligned)				      \
+		. = ALIGN (0x2000) ;					      \
+        	*(.data.init_task)					      \
+		. = ALIGN (0x2000) ;					      \
+		__edata = . ;
+
+/* Kernel BSS segment.  */
+#define BSS_CONTENTS							      \
+		__sbss = . ;						      \
+			*(.bss)						      \
+			*(COMMON)					      \
+		. = ALIGN (4) ;						      \
+		__init_stack_end = . ;					      \
+		__ebss = . ;
+
+/* `initcall' tables.  */
+#define INITCALL_CONTENTS						      \
+		. = ALIGN (16) ;					      \
+		___setup_start = . ;					      \
+			*(.init.setup)	/* 2.5 convention */		      \
+			*(.setup.init)	/* 2.4 convention */		      \
+		___setup_end = . ;					      \
+		___start___param = . ;					      \
+			*(__param)					      \
+		___stop___param = . ;					      \
+		___initcall_start = . ;					      \
+			*(.initcall.init)				      \
+			*(.initcall1.init)				      \
+			*(.initcall2.init)				      \
+			*(.initcall3.init)				      \
+			*(.initcall4.init)				      \
+			*(.initcall5.init)				      \
+			*(.initcall6.init)				      \
+			*(.initcall7.init)				      \
+		. = ALIGN (4) ;						      \
+		___initcall_end = . ;
+
+/* Contents of `init' section for a kernel that's loaded into RAM.  */
+#define RAMK_INIT_CONTENTS						      \
+		RAMK_INIT_CONTENTS_NO_END				      \
+		__init_end = . ;
+/* Same as RAMK_INIT_CONTENTS, but doesn't define the `__init_end' symbol.  */
+#define RAMK_INIT_CONTENTS_NO_END					      \
+		. = ALIGN (4096) ;					      \
+		__init_start = . ;					      \
+			*(.init.text)	/* 2.5 convention */		      \
+			*(.init.data)					      \
+			*(.text.init)	/* 2.4 convention */		      \
+			*(.data.init)					      \
+		INITCALL_CONTENTS					      \
+		INITRAMFS_CONTENTS
+
+/* The contents of `init' section for a ROM-resident kernel which
+   should go into RAM.  */	
+#define ROMK_INIT_RAM_CONTENTS						      \
+		. = ALIGN (4096) ;					      \
+		__init_start = . ;					      \
+			*(.init.data)	/* 2.5 convention */		      \
+			*(.data.init)	/* 2.4 convention */		      \
+		__init_end = . ;					      \
+		. = ALIGN (4096) ;
+
+/* The contents of `init' section for a ROM-resident kernel which
+   should go into ROM.  */	
+#define ROMK_INIT_ROM_CONTENTS						      \
+			*(.init.text)	/* 2.5 convention */		      \
+			*(.text.init)	/* 2.4 convention */		      \
+		INITCALL_CONTENTS					      \
+		INITRAMFS_CONTENTS
+
+/* A root filesystem image, for kernels with an embedded root filesystem.  */
+#define ROOT_FS_CONTENTS						      \
+		__root_fs_image_start = . ;				      \
+		*(.root)						      \
+		__root_fs_image_end = . ;
+/* The initramfs archive.  */
+#define INITRAMFS_CONTENTS						      \
+		. = ALIGN (4) ;						      \
+		___initramfs_start = . ;				      \
+			*(.init.ramfs)					      \
+		___initramfs_end = . ;
+/* Where the initial bootmap (bitmap for the boot-time memory allocator) 
+   should be place.  */
+#define BOOTMAP_CONTENTS						      \
+		. = ALIGN (4096) ;					      \
+		__bootmap = . ;						      \
+		. = . + 4096 ;		/* enough for 128MB.   */
+
+/* The contents of a `typical' kram area for a kernel in RAM.  */
+#define RAMK_KRAM_CONTENTS						      \
+		__kram_start = . ;					      \
+		TEXT_CONTENTS						      \
+		DATA_CONTENTS						      \
+		BSS_CONTENTS						      \
+		RAMK_INIT_CONTENTS					      \
+		__kram_end = . ;					      \
+		BOOTMAP_CONTENTS
+
+
+/* Define output sections normally used for a ROM-resident kernel.  
+   ROM and RAM should be appropriate memory areas to use for kernel
+   ROM and RAM data.  This assumes that ROM starts at 0 (and thus can
+   hold the interrupt vectors).  */
+#define ROMK_SECTIONS(ROM, RAM)						      \
+	.rom : {							      \
+		INTV_CONTENTS						      \
+		TEXT_CONTENTS						      \
+		ROMK_INIT_ROM_CONTENTS					      \
+		ROOT_FS_CONTENTS					      \
+	} > ROM								      \
+									      \
+	__rom_copy_src_start = . ;					      \
+									      \
+	.data : {							      \
+		__kram_start = . ;					      \
+		__rom_copy_dst_start = . ;				      \
+		DATA_CONTENTS						      \
+		ROMK_INIT_RAM_CONTENTS					      \
+		__rom_copy_dst_end = . ;				      \
+	} > RAM  AT> ROM						      \
+									      \
+	.bss ALIGN (4) : {						      \
+		BSS_CONTENTS						      \
+		__kram_end = . ;					      \
+		BOOTMAP_CONTENTS					      \
+	} > RAM
+
+
+/* Include an appropriate platform-dependent linker-script (which
+   usually should use the above macros to do most of the work).  */
+
+#ifdef CONFIG_MBVANILLA
+# include "mbvanilla.ld"
+#endif
+
+#ifdef CONFIG_EGRET01
+# include "egret01.ld"
+#endif
+
+#ifdef CONFIG_SUZAKU
+# include "suzaku.ld"
+#endif
diff -urN linux-2.4.29/arch/microblaze/Makefile linux-2.4.29-uc1/arch/microblaze/Makefile
--- linux-2.4.29/arch/microblaze/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/Makefile	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,145 @@
+#
+# arch/microblaze/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+
+#
+# If you want the kernel build to build modules outside of the tree
+# then define this and pass it to the main linux makefile
+#
+ifdef EXTRA_MODULE_DIRS
+SUBDIRS += $(EXTRA_MODULE_DIRS)
+endif
+
+UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\"
+
+ARCH_DIR = arch/$(ARCH)
+
+# work out which gcc version we are using
+GCC_VER = $(shell $(CC) -v 2>&1|grep version|cut -d " " -f 3)
+
+# split into major and minor numbers
+GCC_MAJOR = $(shell echo $(GCC_VER) | cut -d '.' -f 1)
+GCC_MINOR = $(shell echo $(GCC_VER) | cut -d '.' -f 2)  
+
+#setup memory model - default to RAM
+MODEL = ram
+export MODEL
+
+# Find out which board/platform we are compiling for
+include arch/$(ARCH)/Boards.mk
+
+# get the compiler, flags and targets from the platform
+# Microblaze is transitioning towards nice multi-platform build
+# but we must not break old targets yet (Suzaku, mbvanilla_net)
+ifdef PLATFORM
+
+LDFLAGS += --defsym _STACK_SIZE=0x00
+CFLAGS += -DPLATFORM=$(PLATFORM)
+
+include $(ARCH_DIR)/platform/$(PLATFORM)/Rules.make
+
+arch/$(ARCH)/empty.o:
+	$(CROSS_COMPILE)gcc -o arch/$(ARCH)/empty.o -c arch/$(ARCH)/empty.c
+
+bootstrap:
+	@$(MAKEBOOT) bootstrap
+
+archmrproper:
+
+archdep:
+
+else  ##### The old way!
+# old way of doing things, for back-compatability
+# it would be nice to delete this eventually 
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/libgcc.a
+
+# Older mb-gcc requires linking against compiler's libc.a
+ifeq ($(GCC_MAJOR),2)
+	LIBGCC += $(GCC_DIR)/../../../../microblaze/lib/libc.a
+endif
+
+CFLAGS += -fno-builtin
+CFLAGS += -DNO_MM -DNO_FPU -D__ELF__
+CFLAGS += $(UTS_SYSNAME) -D__linux__
+CFLAGS += -I$(INCGCC)
+
+ifdef CONFIG_MICROBLAZE_HARD_MULT
+	CFLAGS += -mno-xl-soft-mul
+endif
+
+ifdef CONFIG_MICROBLAZE_HARD_DIV
+	CFLAGS += -mno-xl-soft-div
+endif
+
+ifdef CONFIG_MICROBLAZE_HARD_BARREL
+	CFLAGS += -mxl-barrel-shift
+endif
+
+LDFLAGS += --defsym _STACK_SIZE=0x00
+
+HEAD := $(ARCH_DIR)/kernel/head.o
+
+SUBDIRS += $(ARCH_DIR)/kernel $(ARCH_DIR)/mm $(ARCH_DIR)/lib $(ARCH_DIR)/xilinx_ocp
+
+CORE_FILES := $(ARCH_DIR)/kernel/kernel.o $(ARCH_DIR)/mm/mm.o $(CORE_FILES)
+CORE_FILES += $(ARCH_DIR)/xilinx_ocp/xilinx_ocp.o
+
+LIBS += $(ARCH_DIR)/lib/lib.a $(LIBGCC)
+
+
+# Deal with the initial contents of the blkmem device
+ifdef ROOT_FS_IMAGE 
+# Embed it in the kernel
+
+ROOT_FS_IMAGE_OBJ = root_fs_image.o
+
+CORE_FILES += $(ROOT_FS_IMAGE_OBJ)
+
+$(LINUX) : $(ROOT_FS_IMAGE_OBJ)
+
+# Note that we use the build-system's objcopy, as the microblaze tools 
+# are fairly old, and don't have the --rename-section option.
+$(ROOT_FS_IMAGE_OBJ): $(ROOT_FS_IMAGE)
+	objcopy -I binary -O elf32-big --rename-section .data=.root,alloc,load,readonly,data,contents $< $@
+
+endif # ROOT_FS_IMAGE
+
+
+#kernel linker script
+LD_SCRIPT := linux.ld
+
+LINKFLAGS = -T $(LD_SCRIPT) --defsym _STACK_SIZE=0x00 
+$(LINUX) : $(LD_SCRIPT)
+$(LD_SCRIPT): $(ARCH_DIR)/linux.ld.in
+	$(CPP) -P -x assembler-with-cpp $(AFLAGS) $< > $@
+
+
+bootstrap:
+	@$(MAKEBOOT) bootstrap
+
+archmrproper:
+
+archdep:
+
+archclean:
+	rm -f $(LD_SCRIPT)
+	rm -f $(LINUX)
+	rm -f $(ARCH_DIR)/kernel/microblaze_defs.h $(ARCH_DIR)/kernel/microblaze_defs.d
+
+endif #PLATFORM
+
+include $(TOPDIR)/Rules.make
+
diff -urN linux-2.4.29/arch/microblaze/mbvanilla.ld linux-2.4.29-uc1/arch/microblaze/mbvanilla.ld
--- linux-2.4.29/arch/microblaze/mbvanilla.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/mbvanilla.ld	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,154 @@
+/* Simple development memory map for Xilinx Microblaze target.
+   Assume that only the interrupt vectors and the small local data
+   area go in LMB RAM, and that some mythical bootloader will 
+   put the kernel into OPB RAM starting from 0xffe00000
+*/
+
+/* Plenty of room to do tricky stuff here.  e.g. for speed, we could
+   put IRQ handlers and the OS scheduling code into LMB.
+   That's just one idea, will look into it more later.
+*/
+  
+MEMORY {
+	/* 8K of LMB RAM */
+	LMB  : ORIGIN = 0x00000000, LENGTH = 0x00002000
+	/* 1MB of OPB SRAM */
+	/* OPB  : ORIGIN = 0xFFE00000, LENGTH = 0x00100000 */
+
+	/* 16 MB of OBP SDRAM */
+	OPB  : ORIGIN = 0x80000000, LENGTH = 0x01000000 
+}
+
+SECTIONS {
+	.text : {
+		/* "untouchable" memory space starts here */
+	        _kram_start = . ;
+	
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+		*(.modinfo)
+		. = ALIGN (0x4) ;
+			*(.kstrtab)
+		. = ALIGN (16) ;	/* Exception table.  */
+		__start___ex_table = . ;
+			*(_ex_table)
+		__stop___ex_table = . ;
+
+		__start___ksymtab = . ; /* All kernel symbols */
+		*(__ksymtab)
+		__stop___ksymtab = . ;
+
+                __start___kallsyms = .; /* All kernel symbols           */
+                        *(__kallsyms)
+                __stop___kallsyms = .;
+
+
+		. = ALIGN (4) ;
+		_etext = . ;
+	} > OPB
+
+	/* Copies of interrupt vector space. They get copied from here into the 
+  	   proper location by mach_early_setup() */ 
+	.intv : {
+		_intv_load_start = . ;
+	        	*(.intv.reset)	/* Reset vector */
+			*(.intv.common) /* Vectors common to all microblaze proc. */
+			*(.intv.mach)   /* Machine-specific int. vectors.  */
+		_intv_load_end = . ;
+	} > OPB
+
+
+	/* sdata2 section can go anywhere, but must be word aligned
+	   and SDA2_BASE must point to the middle of it */
+	.sdata2 : {
+		_ssrw = .;
+		. = ALIGN(0x8);
+		*(.sdata2)
+	. = ALIGN(8);
+	_essrw = .;
+	_ssrw_size = _essrw - _ssrw;
+	_KERNEL_SDA2_BASE_ = _ssrw + (_ssrw_size / 2);
+	} > OPB
+
+
+	.data ALIGN (0x4) : {
+
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN (16) ;
+		*(.data.cacheline_aligned)
+		. = ALIGN (0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN (0x2000) ;
+		_edata = . ;
+	
+		/* Reserve some low RAM for r0 based memory references */
+		. = ALIGN(4) ;
+		C_SYMBOL_NAME(r0_ram) = . ;
+		. = . + 32 ;	/* 32 bytes should be enough */
+	} > OPB
+
+	/* Under the microblaze ABI, .sdata and .sbss must be contiguous */
+	. = ALIGN(8);
+	.sdata : {
+		_ssro = .;
+		*(.sdata)
+	} > OPB
+
+	. = ALIGN(4);
+	.sbss : {
+		_ssbss = . ;
+		_sbss_start = .;
+		*(.sbss)
+		_ssbss_end = .;
+		_esbss = . ;
+
+	. = ALIGN(8);
+	_essro = .;
+	_ssro_size = _essro - _ssro;
+	_KERNEL_SDA_BASE_ = _ssro + (_ssro_size / 2);
+	
+ 	} > OPB
+ 
+	/* Place init and bootmap sections last to reduce fragmentation 
+	   when they are freed */
+ 	.init ALIGN (4096) : {
+ 		_init_start = . ;
+		__init_begin = . ;
+ 			*(.text.init)
+ 			*(.data.init)
+ 		. = ALIGN (16) ;
+ 		__setup_start = . ;
+ 			*(.setup.init)
+ 		__setup_end = . ;
+ 		__initcall_start = . ;
+ 			*(.initcall.init)
+ 		. = ALIGN (4) ;
+ 		__initcall_end = . ;
+		. = ALIGN(4096);
+		__init_end = . ;
+ 		_init_end = . ;
+ 		/* Untouchable kernel ram ends here */
+ 		_kram_end = . ;
+ 	} > OPB
+ 
+	/* .bss must go last, to be compatible with the way the romfs is handled */
+	.bss ALIGN (0x4) : {
+		_sbss = . ;
+		__bss_start = .;
+			*(.bss*)
+			*(COMMON)
+		. = ALIGN (4) ;
+		__bss_stop = . ;
+		_ebss = . ;
+		_end = . ;
+ 	} > OPB
+ 
+}
+
diff -urN linux-2.4.29/arch/microblaze/mm/consistent.c linux-2.4.29-uc1/arch/microblaze/mm/consistent.c
--- linux-2.4.29/arch/microblaze/mm/consistent.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/mm/consistent.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,181 @@
+/*
+ *  Microblaze support for cache consistent memory.
+ *  Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ *  based on 
+ *
+ *  PowerPC version derived from arch/arm/mm/consistent.c
+ *    Copyright (C) 2001 Dan Malek (dmalek@jlc.net)
+ *
+ *  linux/arch/arm/mm/consistent.c
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * Consistent memory allocators.  Used for DMA devices that want to
+ * share uncached memory with the processor core.  
+ * My crufty no-MMU approach is simple.   In the HW platform we can optionally
+ * mirror the DDR up above the processor cacheable region.  So, memory accessed
+ * in this mirror region will not be cached.  It's alloced from the same
+ * pool as normal memory, but the handle we return is shifted up into the 
+ * uncached region.  This will no doubt cause big problems if memory allocated
+ * here is not also freed properly.
+ *						-- JW
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/machdep.h>
+
+extern int map_page(unsigned long va, phys_addr_t pa, int flags);
+
+void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
+{
+	struct page *page, *end, *free;
+	unsigned long order;
+	void *ret, *virt;
+
+	if (in_interrupt())
+		BUG();
+
+	size = PAGE_ALIGN(size);
+	order = get_order(size);
+
+	page = alloc_pages(gfp, order);
+	if (!page)
+		goto no_page;
+
+	/*
+	 * We could do with a page_to_phys and page_to_bus here.
+	 */
+	virt = page_address(page);
+	/* *dma_handle = virt_to_bus(virt); */
+	ret = ioremap(virt_to_phys(virt), size);
+	if (!ret)
+		goto no_remap;
+
+	/* Here's the magic!  Note if the uncached shadow is not implemented, 
+	   it's up to the calling code to also test that condition and make
+	   other arranegments, such as manually flushing the cache and so on.
+	*/
+#if CONFIG_XILINX_UNCACHED_SHADOW
+	ret = (void *)((unsigned) ret | UNCACHED_SHADOW_MASK);
+#endif
+	/* For !MMU, dma_handle is same as physical (shadowed) address */
+	*dma_handle = ret;
+
+	/*
+	 * free wasted pages.  We skip the first page since we know
+	 * that it will have count = 1 and won't require freeing.
+	 * We also mark the pages in use as reserved so that
+	 * remap_page_range works.
+	 */
+	page = virt_to_page(virt);
+	free = page + (size >> PAGE_SHIFT);
+	end  = page + (1 << order);
+
+	for (; page < end; page++) {
+		set_page_count(page, 1);
+		if (page >= free)
+			__free_page(page);
+		else
+			SetPageReserved(page);
+	}
+
+	return ret;
+no_remap:
+	__free_pages(page, order);
+no_page:
+	return NULL;
+}
+
+/*
+ * free page(s) as defined by the above mapping.
+ */
+void consistent_free(void *vaddr)
+{
+	struct page *page, *end;
+	void *virt; 
+	 
+	if (in_interrupt())
+		BUG();
+
+	/* Clear SHADOW_MASK bit in address, and free as per usual */
+#if CONFIG_XILINX_UNCACHED_SHADOW
+	vaddr = (void *)((unsigned)vaddr & ~UNCACHED_SHADOW_MASK);
+#endif
+	vfree(vaddr);
+}
+
+/*
+ * make an area consistent.
+ */
+void consistent_sync(void *vaddr, size_t size, int direction)
+{
+	unsigned long start; 
+	unsigned long end;
+
+	start=(unsigned long)vaddr;
+
+	/* Convert start address back down to unshadowed memory region */
+#if CONFIG_XILINX_UNCACHED_SHADOW
+	start &= UNCACHED_SHADOW_MASK;
+#endif
+	end = start+size;
+
+	switch (direction) {
+	case PCI_DMA_NONE:
+		BUG();
+	case PCI_DMA_FROMDEVICE:	/* invalidate only */
+		flush_dcache_range(start, end);
+		break;
+	case PCI_DMA_TODEVICE:		/* writeback only */
+		flush_dcache_range(start, end);
+		break;
+	case PCI_DMA_BIDIRECTIONAL:	/* writeback and invalidate */
+		flush_dcache_range(start, end);
+		break;
+	}
+}
+
+
+/*
+ * consistent_sync_page makes memory consistent. identical
+ * to consistent_sync, but takes a struct page instead of a
+ * virtual address
+ */
+void consistent_sync_page(struct page *page, unsigned long offset,
+	size_t size, int direction)
+{
+	unsigned long start = (unsigned long)page_address(page) + offset; 
+	consistent_sync((void *)start, size, direction);
+}
diff -urN linux-2.4.29/arch/microblaze/mm/init.c linux-2.4.29-uc1/arch/microblaze/mm/init.c
--- linux-2.4.29/arch/microblaze/mm/init.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/mm/init.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,585 @@
+/*
+ *  arch/microblaze/mm/init.c
+ *
+ *  Copyright (C) 2004 John Williams
+ *  Copyright (C) 2004 Atmark Techno, Inc.
+ *
+ *  John Williams <jwilliams@itee.uq.edu.au>
+ *  Yasushi SHOJI <yashi@atmark-techno.com>
+ *
+ *  Based on
+ *        arch/microblaze/setup.c
+ *   and
+ *        arch/arm/mm/init.c
+ *        arch/sparc/mm/init.c
+ *        arch/ia64/mm/init.c
+ *        arch/m68knommu/kernel/setup.c
+ *        arch/h8300/kernel/setup.c
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+#include <asm/map.h>
+
+/* Locally used struct to describe the memory nodes */
+struct node_info {
+	unsigned int start;
+	unsigned int end;
+	int	bootmap_pages;
+};
+
+/* these function prototypes are taken form arch/microblaze/kernel/mach.h */
+extern void mach_reserve_bootmem (void) __attribute__ ((__weak__));
+extern void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len);
+
+extern char _kram_start __attribute__ ((__weak__));
+extern char _kram_end __attribute__ ((__weak__));
+
+/* erase following when we port to 2.6, include <asm/sections.h> instead */
+extern char _text[], _stext[], _etext[];
+extern char _data[], _sdata[], _edata[];
+extern char _end[];
+
+extern char __bss_start[], __bss_stop[];
+extern char __init_begin[], __init_end[];
+extern char _sinittext[], _einittext[];
+
+extern unsigned long _ramstart;
+
+/* Physical System RAM.  */
+static unsigned long ram_start = 0, ram_len = 0;
+
+#define ADDR_TO_PAGE_UP(x)   ((((unsigned long)x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define ADDR_TO_PAGE(x)	     (((unsigned long)x) >> PAGE_SHIFT)
+#define PAGE_TO_ADDR(x)	     (((unsigned long)x) << PAGE_SHIFT)
+
+#define O_PFN_DOWN(x)	((x) >> PAGE_SHIFT)
+#define V_PFN_DOWN(x)	O_PFN_DOWN(__pa(x))
+
+#define O_PFN_UP(x)	(PAGE_ALIGN(x) >> PAGE_SHIFT)
+#define V_PFN_UP(x)	O_PFN_UP(__pa(x))
+
+#define PFN_SIZE(x)	((x) >> PAGE_SHIFT)
+#define PFN_RANGE(s,e)	PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \
+				(((unsigned long)(s)) & PAGE_MASK))
+
+
+#ifndef CONFIG_DISCONTIGMEM
+#define NR_NODES	1
+#else
+#define NR_NODES	4
+#endif
+
+/* Somewhere to store "local" copy of meminfo structure. */
+static struct meminfo meminfo __initdata = { 0, };
+
+struct page *empty_zero_page;
+
+/* Memory not used by the kernel.  */
+
+void show_mem(void)
+{
+	int free = 0, total = 0, reserved = 0;
+	int shared = 0, cached = 0, node;
+
+	printk("Mem-info:\n");
+	show_free_areas();
+	printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+
+	for (node = 0; node < numnodes; node++) {
+		struct page *page, *end;
+
+		page = NODE_MEM_MAP(node);
+		end  = page + NODE_DATA(node)->node_size;
+
+		do {
+/* This is currently broken
+ * PG_skip is used on sparc/sparc64 architectures to "skip" certain
+ * parts of the address space.
+ *
+ * #define PG_skip	10
+ * #define PageSkip(page) (machine_is_riscpc() && test_bit(PG_skip, &(page)->flags))
+ *			if (PageSkip(page)) {
+ *				page = page->next_hash;
+ *				if (page == NULL)
+ *					break;
+ *			}
+ */
+			total++;
+			if (PageReserved(page))
+				reserved++;
+			else if (PageSwapCache(page))
+				cached++;
+			else if (!page_count(page))
+				free++;
+			else
+				shared += atomic_read(&page->count) - 1;
+			page++;
+		} while (page < end);
+	}
+
+	printk("%d pages of RAM\n", total);
+	printk("%d free pages\n", free);
+	printk("%d reserved pages\n", reserved);
+	printk("%d pages shared\n", shared);
+	printk("%d pages swap cached\n", cached);
+/* #ifndef CONFIG_NO_PGT_CACHE */
+#if 0
+	printk("%ld page tables cached\n", pgtable_cache_size);
+#endif
+	show_buffers();
+}
+
+/* for 2.4, declare totalram_pages here.  for 2.6, totalram_pages is
+ * declared in mm/page_alloc.c. remove from here and include
+ * linux/swap.h, instead.  - yashi Apr 10, 2004 */
+static unsigned long totalram_pages;
+
+static inline void free_memmap(int node, unsigned long start, unsigned long end)
+{
+	unsigned long pg, pgend;
+
+	start = __phys_to_virt(start);
+	end   = __phys_to_virt(end);
+
+	pg    = PAGE_ALIGN((unsigned long)(virt_to_page(start)));
+	pgend = ((unsigned long)(virt_to_page(end))) & PAGE_MASK;
+
+	start = __virt_to_phys(pg);
+	end   = __virt_to_phys(pgend);
+
+	free_bootmem_node(NODE_DATA(node), start, end - start);
+}
+
+static inline void free_unused_memmap_node(int node, struct meminfo *mi)
+{
+	unsigned long bank_start, prev_bank_end = 0;
+	unsigned int i;
+
+	/*
+	 * [FIXME] This relies on each bank being in address order.  This
+	 * may not be the case, especially if the user has provided the
+	 * information on the command line.
+	 */
+	for (i = 0; i < mi->nr_banks; i++) {
+		if (mi->bank[i].size == 0 || mi->bank[i].node != node)
+			continue;
+
+		bank_start = mi->bank[i].start & PAGE_MASK;
+
+		/*
+		 * If we had a previous bank, and there is a space
+		 * between the current bank and the previous, free it.
+		 */
+		if (prev_bank_end && prev_bank_end != bank_start)
+			free_memmap(node, prev_bank_end, bank_start);
+
+		prev_bank_end = PAGE_ALIGN(mi->bank[i].start +
+					   mi->bank[i].size);
+	}
+}
+
+/*
+ * The mem_map array can get very big.  Free
+ * the unused area of the memory map.
+ */
+void __init create_memmap_holes(struct meminfo *mi)
+{
+	int node;
+
+	for (node = 0; node < numnodes; node++)
+		free_unused_memmap_node(node, mi);
+}
+
+/*
+ * mem_init() marks the free areas in the mem_map and tells us how much
+ * memory is free.  This is done after various parts of the system have
+ * claimed their memory after the kernel image.
+ */
+void __init mem_init(void)
+{
+	unsigned int codepages, datapages, initpages;
+	int i, node;
+
+	codepages = (unsigned long)&_etext - (unsigned long)&_stext;
+	datapages = _ramstart - ((unsigned int)&_etext);
+	initpages = (unsigned long)&__init_end - (unsigned long)&__init_begin;
+
+	high_memory = (void *)__va(meminfo.end);
+	max_mapnr   = virt_to_page(high_memory) - mem_map;
+
+	/*
+	 * We may have non-contiguous memory.
+	 */
+	if (meminfo.nr_banks != 1)
+		create_memmap_holes(&meminfo);
+
+	/* this will put all unused low memory onto the freelists */
+	for (node = 0; node < numnodes; node++)
+		totalram_pages += free_all_bootmem_node(NODE_DATA(node));
+
+	//	SetPageReserved(virt_to_page(PAGE_OFFSET));
+	/*
+	 * Since our memory may not be contiguous, calculate the
+	 * real number of pages we have in this system
+	 */
+	printk(KERN_INFO "Memory:");
+
+	num_physpages = 0;
+	for (i = 0; i < meminfo.nr_banks; i++) {
+		num_physpages += meminfo.bank[i].size >> PAGE_SHIFT;
+		printk(" %ldMB", meminfo.bank[i].size >> 20);
+	}
+
+	printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
+	printk(KERN_NOTICE "Memory: %luKB available (%dK code, "
+		"%dK data, %dK init)\n",
+		(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+		codepages >> 10, datapages >> 10, initpages >> 10);
+
+	#if CONFIG_XILINX_UNCACHED_SHADOW
+	printk(KERN_INFO "Memory: Uncached shadow enabled (0x%08X-0x%08X)\n",
+		CONFIG_XILINX_ERAM_START | UNCACHED_SHADOW_MASK,
+		(CONFIG_XILINX_ERAM_START | UNCACHED_SHADOW_MASK) + 
+			CONFIG_XILINX_ERAM_SIZE - 1);
+	#endif
+
+	if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
+		extern int sysctl_overcommit_memory;
+		/*
+		 * On a machine this small we won't get
+		 * anywhere without overcommit, so turn
+		 * it on by default.
+		 */
+		sysctl_overcommit_memory = 1;
+	}
+}
+
+/*
+ * Free memory area area bounded by the range (addr, end)
+ */
+static inline void free_area(unsigned long addr, unsigned long end, char *s)
+{
+	unsigned int size = (end - addr) >> 10;
+
+	for (; addr < end; addr += PAGE_SIZE) {
+		struct page *page = virt_to_page(addr);
+		ClearPageReserved(page);
+		set_page_count(page, 1);
+		free_page(addr);
+		totalram_pages++;
+	}
+
+	if (size)
+		printk("Freeing %s memory: %dK\n", s, size);
+}
+
+void free_initmem(void)
+{
+	free_area((unsigned long)(&__init_begin),
+		  (unsigned long)(&__init_end),
+		  "init");
+}
+
+/*
+ * Scan the memory info structure and pull out:
+ *  - the end of memory
+ *  - the number of nodes
+ *  - the pfn range of each node
+ *  - the number of bootmem bitmap pages
+ */
+static unsigned int __init
+find_memend_and_nodes(struct meminfo *mi, struct node_info *np)
+{
+	unsigned int i, bootmem_pages = 0, memend_pfn = 0;
+
+	for (i = 0; i < NR_NODES; i++) {
+		np[i].start = -1U;
+		np[i].end = 0;
+		np[i].bootmap_pages = 0;
+	}
+
+	for (i = 0; i < mi->nr_banks; i++) {
+		unsigned long start, end;
+		int node;
+
+		if (mi->bank[i].size == 0) {
+			/*
+			 * Mark this bank with an invalid node number
+			 */
+			mi->bank[i].node = -1;
+			continue;
+		}
+
+		node = mi->bank[i].node;
+
+		if (node >= numnodes) {
+			numnodes = node + 1;
+
+			/*
+			 * Make sure we haven't exceeded the maximum number
+			 * of nodes that we have in this configuration.  If
+			 * we have, we're in trouble.  (maybe we ought to
+			 * limit, instead of bugging?)
+			 */
+			if (numnodes > NR_NODES)
+				BUG();
+		}
+
+		/*
+		 * Get the start and end pfns for this bank
+		 */
+		start = O_PFN_UP(mi->bank[i].start);
+		end   = O_PFN_DOWN(mi->bank[i].start + mi->bank[i].size);
+
+		if (np[node].start > start)
+			np[node].start = start;
+
+		if (np[node].end < end)
+			np[node].end = end;
+
+		if (memend_pfn < end)
+			memend_pfn = end;
+	}
+
+	/*
+	 * Calculate the number of pages we require to
+	 * store the bootmem bitmaps.
+	 */
+	for (i = 0; i < numnodes; i++) {
+		if (np[i].end == 0)
+			continue;
+
+		np[i].bootmap_pages = bootmem_bootmap_pages(np[i].end -
+							    np[i].start);
+		bootmem_pages += np[i].bootmap_pages;
+	}
+
+	/*
+	 * This doesn't seem to be used by the Linux memory
+	 * manager any more.  If we can get rid of it, we
+	 * also get rid of some of the stuff above as well.
+	 */
+	/* HACK! */
+	#define PHYS_OFFSET (PAGE_OFFSET)
+	max_low_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
+//	max_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
+	mi->end = memend_pfn << PAGE_SHIFT;
+
+	return bootmem_pages;
+}
+
+/*
+ * Reserve the various regions of node 0
+ */
+static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int bootmap_pages)
+{
+	/* Handle to Node 0*/
+	pg_data_t *pgdat = NODE_DATA(0);
+
+	unsigned long kram_start = (unsigned long )&_kram_start;
+	unsigned long kram_end  = (unsigned long )&_kram_end;
+
+	/* Machine specific bootmem reserve function */
+	void (*volatile mrb) (void) = mach_reserve_bootmem;
+
+	/*
+	 * Register the kernel text and data with bootmem.
+	 * Note that this can only be in node 0.
+	 */
+	if(kram_end > kram_start)
+		reserve_bootmem_node(pgdat, __pa(kram_start), 
+						(kram_end-kram_start));
+
+        /* Reserve space for the bss segment.  Also save space for
+         * rootfs as well. because bss and romfs is contiguous, we
+         * reserve from start of bss to end of romfs which is
+         * _ramstart */
+        reserve_bootmem_node(pgdat, __pa(__bss_start), 
+			_ramstart - (unsigned long)__bss_start);
+
+	/*
+	 * And don't forget to reserve the allocator bitmap,
+	 * which will be freed later.
+	 */
+	reserve_bootmem_node(pgdat, bootmap_pfn << PAGE_SHIFT,
+			     bootmap_pages << PAGE_SHIFT);
+
+	/* Let the platform-dependent code reserve some too.  */
+	if (mrb)
+		(*mrb) ();
+}
+
+/*
+ * FIXME: We really want to avoid allocating the bootmap bitmap
+ * over the top of the initrd.  Hopefully, this is located towards
+ * the start of a bank, so if we allocate the bootmap bitmap at
+ * the end, we won't clash.
+ */
+static unsigned int __init
+find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
+{
+	unsigned int start_pfn, bank, bootmap_pfn;
+
+	start_pfn   = V_PFN_UP(_ramstart);
+	bootmap_pfn = 0;
+
+	for (bank = 0; bank < mi->nr_banks; bank ++) {
+		unsigned int start, end;
+
+		if (mi->bank[bank].node != node)
+			continue;
+
+		start = O_PFN_UP(mi->bank[bank].start);
+		end   = O_PFN_DOWN(mi->bank[bank].size +
+				   mi->bank[bank].start);
+
+		if (end < start_pfn)
+			continue;
+
+		if (start < start_pfn)
+			start = start_pfn;
+
+		if (end <= start)
+			continue;
+
+		if (end - start >= bootmap_pages) {
+			bootmap_pfn = start;
+			break;
+		}
+	}
+
+	if (bootmap_pfn == 0)
+		BUG();
+
+	return bootmap_pfn;
+}
+
+/*
+ * Register all available RAM in this node with the bootmem allocator.
+ */
+static inline void free_bootmem_node_bank(int node, struct meminfo *mi)
+{
+	pg_data_t *pgdat = NODE_DATA(node);
+	int bank;
+
+	for (bank = 0; bank < mi->nr_banks; bank++)
+		if (mi->bank[bank].node == node)
+			free_bootmem_node(pgdat, mi->bank[bank].start,
+				mi->bank[bank].size);
+}
+
+
+/* Initialize the `bootmem allocator'.  RAM_START and RAM_LEN identify
+   what RAM may be used.  */
+void __init bootmem_init (struct meminfo *mi)
+{
+	struct node_info node_info[NR_NODES], *np = node_info;
+	unsigned int bootmap_pages, bootmap_pfn, map_pg;
+	int node, initrd_node;
+
+	bootmap_pages	= find_memend_and_nodes(mi,np);
+	bootmap_pfn 	= find_bootmap_pfn(0, mi, bootmap_pages);
+	initrd_node	= 0; /*check_initrd(mi); */
+
+	map_pg = bootmap_pfn;
+
+	np += numnodes - 1;
+	for (node = numnodes - 1; node >= 0; node--, np--)
+	{
+		if(np->end == 0)
+		{
+			if(node == 0)
+				BUG();
+			continue;
+		}
+
+		init_bootmem_node(NODE_DATA(node), map_pg, np->start, np->end);
+		free_bootmem_node_bank(node, mi);
+		map_pg += np->bootmap_pages;
+
+		if(node == 0)
+			reserve_node_zero(bootmap_pfn, bootmap_pages);
+	}
+
+	if(map_pg != bootmap_pfn + bootmap_pages)
+		BUG();
+
+}
+
+/* Setup memory zone. We don't have no page table to warry about.
+ * Initialize memory zone and call free_area_init_node().
+ *
+ * Note: One we get discon mem support, we need to chage the function
+ */
+void __init paging_init (struct meminfo *mi)
+{
+	unsigned i;
+	unsigned long zones_size[MAX_NR_ZONES];
+	void *zero_page;
+	int node;
+
+	/* Copy the meminfo struct locally */
+	memcpy(&meminfo, mi, sizeof(meminfo));
+	
+	zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
+	
+	for (node = 0; node < numnodes; node++)
+	{
+		unsigned long zone_size[MAX_NR_ZONES];
+		unsigned long zhole_size[MAX_NR_ZONES];
+		struct bootmem_data *bdata;
+		pg_data_t *pgdat;
+		int i;
+
+		for(i=0; i < MAX_NR_ZONES; i++)
+		{
+			zone_size[i] = 0;
+			zhole_size[i] = 0;
+		}
+
+		pgdat = NODE_DATA(node);
+		bdata = pgdat->bdata;
+
+		zone_size[0] = bdata->node_low_pfn - 
+			(bdata->node_boot_start >> PAGE_SHIFT);
+	
+		zhole_size[0] = zone_size[0];
+		for (i=0; i < mi->nr_banks; i++)
+		{
+			if (mi->bank[i].node != node)
+				continue;
+
+			zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT;
+		}
+
+		free_area_init_node(node, pgdat, 0, zone_size,
+			bdata->node_boot_start, zhole_size);
+	}
+
+	memset(zero_page, 0, PAGE_SIZE);
+	empty_zero_page = virt_to_page(zero_page);
+	flush_dcache_page(empty_zero_page);
+}
+
+/* For 2.6, remove this function. mm/page_alloc.c has generic one. */
+void si_meminfo (struct sysinfo *info)
+{
+	info->totalram = totalram_pages;
+	info->sharedram = 0;
+	info->freeram = nr_free_pages ();
+	info->bufferram = atomic_read (&buffermem_pages);
+	info->totalhigh = 0;
+	info->freehigh = 0;
+	info->mem_unit = PAGE_SIZE;
+}
diff -urN linux-2.4.29/arch/microblaze/mm/Makefile linux-2.4.29-uc1/arch/microblaze/mm/Makefile
--- linux-2.4.29/arch/microblaze/mm/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/mm/Makefile	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,20 @@
+#
+# Makefile for the linux microblaze specific parts of the memory manager
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET	:= mm.o
+
+obj-y		:= init.o consistent.o
+obj-m		:=
+obj-n		:=
+obj-		:=
+export-objs	:= 
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/microblaze/platform/ml401/auto-config.in linux-2.4.29-uc1/arch/microblaze/platform/ml401/auto-config.in
--- linux-2.4.29/arch/microblaze/platform/ml401/auto-config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/ml401/auto-config.in	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,637 @@
+############################################################
+# 
+# CAUTION: This file is automatically generated by libgen.
+# Version: Xilinx EDK 6.3 EDK_Gmm.12.3 
+# Description: uClinux Configuration File
+# 
+############################################################
+
+
+
+# MAIN_MEMORY Settings
+define_hex CONFIG_XILINX_ERAM_START 0x10000000
+define_hex CONFIG_XILINX_ERAM_SIZE 0x04000000
+
+# FLASH_MEMORY Settings
+define_hex CONFIG_XILINX_FLASH_START 0x28000000
+define_hex CONFIG_XILINX_FLASH_SIZE 0x00800000
+
+# LMB_MEMORY Settings
+define_hex CONFIG_XILINX_LMB_START 0x00000000
+define_hex CONFIG_XILINX_LMB_SIZE 0x00010000
+
+# System Clock Frequency
+define_int CONFIG_XILINX_CPU_CLOCK_FREQ 66666667
+
+# Definitions for MICROBLAZE0
+define_string CONFIG_XILINX_MICROBLAZE0_INSTANCE microblaze_0
+define_string CONFIG_XILINX_MICROBLAZE0_FAMILY virtex4
+define_string CONFIG_XILINX_MICROBLAZE0_INSTANCE microblaze_0
+define_int CONFIG_XILINX_MICROBLAZE0_D_OPB 1
+define_int CONFIG_XILINX_MICROBLAZE0_D_LMB 1
+define_int CONFIG_XILINX_MICROBLAZE0_I_OPB 1
+define_int CONFIG_XILINX_MICROBLAZE0_I_LMB 1
+define_int CONFIG_XILINX_MICROBLAZE0_USE_BARREL 1
+define_int CONFIG_XILINX_MICROBLAZE0_USE_DIV 1
+define_int CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR 0
+define_int CONFIG_XILINX_MICROBLAZE0_UNALIGNED_EXCEPTIONS 1
+define_int CONFIG_XILINX_MICROBLAZE0_ILL_OPCODE_EXCEPTION 1
+define_int CONFIG_XILINX_MICROBLAZE0_IOPB_BUS_EXCEPTION 1
+define_int CONFIG_XILINX_MICROBLAZE0_DOPB_BUS_EXCEPTION 1
+define_int CONFIG_XILINX_MICROBLAZE0_DIV_ZERO_EXCEPTION 1
+define_int CONFIG_XILINX_MICROBLAZE0_DEBUG_ENABLED 1
+define_int CONFIG_XILINX_MICROBLAZE0_NUMBER_OF_PBRK 2
+define_int CONFIG_XILINX_MICROBLAZE0_NUMBER_OF_RD_ADDR_BRK 1
+define_int CONFIG_XILINX_MICROBLAZE0_NUMBER_OF_WR_ADDR_BRK 1
+define_int CONFIG_XILINX_MICROBLAZE0_INTERRUPT_IS_EDGE 0
+define_int CONFIG_XILINX_MICROBLAZE0_EDGE_IS_POSITIVE 1
+define_int CONFIG_XILINX_MICROBLAZE0_FSL_LINKS 1
+define_int CONFIG_XILINX_MICROBLAZE0_FSL_DATA_SIZE 32
+define_hex CONFIG_XILINX_MICROBLAZE0_ICACHE_BASEADDR 0x10000000
+define_hex CONFIG_XILINX_MICROBLAZE0_ICACHE_HIGHADDR 0x13FFFFFF
+define_int CONFIG_XILINX_MICROBLAZE0_USE_ICACHE 1
+define_int CONFIG_XILINX_MICROBLAZE0_ALLOW_ICACHE_WR 1
+define_int CONFIG_XILINX_MICROBLAZE0_ADDR_TAG_BITS 12
+define_int CONFIG_XILINX_MICROBLAZE0_CACHE_BYTE_SIZE 16384
+define_int CONFIG_XILINX_MICROBLAZE0_ICACHE_USE_FSL 0
+define_hex CONFIG_XILINX_MICROBLAZE0_DCACHE_BASEADDR 0x10000000
+define_hex CONFIG_XILINX_MICROBLAZE0_DCACHE_HIGHADDR 0x13FFFFFF
+define_int CONFIG_XILINX_MICROBLAZE0_USE_DCACHE 1
+define_int CONFIG_XILINX_MICROBLAZE0_ALLOW_DCACHE_WR 1
+define_int CONFIG_XILINX_MICROBLAZE0_DCACHE_ADDR_TAG 12
+define_int CONFIG_XILINX_MICROBLAZE0_DCACHE_BYTE_SIZE 16384
+define_int CONFIG_XILINX_MICROBLAZE0_DCACHE_USE_FSL 0
+define_string CONFIG_XILINX_MICROBLAZE0_INSTANCE microblaze_0
+define_string CONFIG_XILINX_MICROBLAZE0_HW_VER 3.00.a
+
+# Definitions for LMB_BRAM_IF_CNTLR_0
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_INSTANCE lmb_bram_if_cntlr_0
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_BASEADDR 0x00000000
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_HIGHADDR 0x0000FFFF
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_MASK 0x38000000
+define_int CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_LMB_AWIDTH 32
+define_int CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_LMB_DWIDTH 32
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_INSTANCE lmb_bram_if_cntlr_0
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_HW_VER 1.00.b
+
+# Definitions for LMB_BRAM_IF_CNTLR_1
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_INSTANCE lmb_bram_if_cntlr_1
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_BASEADDR 0x00000000
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_HIGHADDR 0x0000FFFF
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_MASK 0x38000000
+define_int CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_LMB_AWIDTH 32
+define_int CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_LMB_DWIDTH 32
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_INSTANCE lmb_bram_if_cntlr_1
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_HW_VER 1.00.b
+
+# Definitions for MDM_0
+define_string CONFIG_XILINX_MDM_0_INSTANCE opb_mdm_0
+define_hex CONFIG_XILINX_MDM_0_BASEADDR 0xFFFE8000
+define_hex CONFIG_XILINX_MDM_0_HIGHADDR 0xFFFE80FF
+define_int CONFIG_XILINX_MDM_0_OPB_DWIDTH 32
+define_int CONFIG_XILINX_MDM_0_OPB_AWIDTH 32
+define_string CONFIG_XILINX_MDM_0_FAMILY virtex4
+define_int CONFIG_XILINX_MDM_0_MB_DBG_PORTS 1
+define_int CONFIG_XILINX_MDM_0_USE_UART 1
+define_int CONFIG_XILINX_MDM_0_UART_WIDTH 8
+define_int CONFIG_XILINX_MDM_0_WRITE_FSL_PORTS 1
+define_string CONFIG_XILINX_MDM_0_INSTANCE opb_mdm_0
+define_string CONFIG_XILINX_MDM_0_HW_VER 2.01.a
+define_int CONFIG_XILINX_MDM_0_IRQ 11
+
+# Definitions for UARTLITE_0
+define_string CONFIG_XILINX_UARTLITE_0_INSTANCE console_uart
+define_hex CONFIG_XILINX_UARTLITE_0_BASEADDR 0xA0000000
+define_hex CONFIG_XILINX_UARTLITE_0_HIGHADDR 0xA0001FFF
+define_int CONFIG_XILINX_UARTLITE_0_OPB_DWIDTH 32
+define_int CONFIG_XILINX_UARTLITE_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_UARTLITE_0_DATA_BITS 8
+define_int CONFIG_XILINX_UARTLITE_0_CLK_FREQ 66666667
+define_int CONFIG_XILINX_UARTLITE_0_BAUDRATE 115200
+define_int CONFIG_XILINX_UARTLITE_0_USE_PARITY 0
+define_int CONFIG_XILINX_UARTLITE_0_ODD_PARITY 0
+define_string CONFIG_XILINX_UARTLITE_0_INSTANCE console_uart
+define_string CONFIG_XILINX_UARTLITE_0_HW_VER 1.00.b
+define_int CONFIG_XILINX_UARTLITE_0_IRQ 10
+
+# Definitions for INTC_0
+define_string CONFIG_XILINX_INTC_0_INSTANCE opb_intc_0
+define_string CONFIG_XILINX_INTC_0_FAMILY virtex4
+define_int CONFIG_XILINX_INTC_0_Y 0
+define_int CONFIG_XILINX_INTC_0_X 0
+define_string CONFIG_XILINX_INTC_0_U_SET intc
+define_int CONFIG_XILINX_INTC_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_INTC_0_OPB_DWIDTH 32
+define_hex CONFIG_XILINX_INTC_0_BASEADDR 0xD1000FC0
+define_hex CONFIG_XILINX_INTC_0_HIGHADDR 0xD1000FDF
+define_int CONFIG_XILINX_INTC_0_NUM_INTR_INPUTS 12
+define_hex CONFIG_XILINX_INTC_0_KIND_OF_INTR 0x00000C00
+define_hex CONFIG_XILINX_INTC_0_KIND_OF_EDGE 0x00000C00
+define_hex CONFIG_XILINX_INTC_0_KIND_OF_LVL 0x000003FF
+define_int CONFIG_XILINX_INTC_0_HAS_IPR 1
+define_int CONFIG_XILINX_INTC_0_HAS_SIE 1
+define_int CONFIG_XILINX_INTC_0_HAS_CIE 1
+define_int CONFIG_XILINX_INTC_0_HAS_IVR 1
+define_int CONFIG_XILINX_INTC_0_IRQ_IS_LEVEL 1
+define_int CONFIG_XILINX_INTC_0_IRQ_ACTIVE 1
+define_string CONFIG_XILINX_INTC_0_INSTANCE opb_intc_0
+define_string CONFIG_XILINX_INTC_0_HW_VER 1.00.c
+
+# Definitions for TIMER_0
+define_string CONFIG_XILINX_TIMER_0_INSTANCE opb_timer_0
+define_string CONFIG_XILINX_TIMER_0_FAMILY virtex4
+define_int CONFIG_XILINX_TIMER_0_COUNT_WIDTH 32
+define_int CONFIG_XILINX_TIMER_0_ONE_TIMER_ONLY 0
+define_int CONFIG_XILINX_TIMER_0_TRIG0_ASSERT 1
+define_int CONFIG_XILINX_TIMER_0_TRIG1_ASSERT 1
+define_int CONFIG_XILINX_TIMER_0_GEN0_ASSERT 1
+define_int CONFIG_XILINX_TIMER_0_GEN1_ASSERT 1
+define_int CONFIG_XILINX_TIMER_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_TIMER_0_OPB_DWIDTH 32
+define_hex CONFIG_XILINX_TIMER_0_BASEADDR 0xA2000000
+define_hex CONFIG_XILINX_TIMER_0_HIGHADDR 0xA20000FF
+define_string CONFIG_XILINX_TIMER_0_INSTANCE opb_timer_0
+define_string CONFIG_XILINX_TIMER_0_HW_VER 1.00.b
+define_int CONFIG_XILINX_TIMER_0_IRQ 0
+
+# Definitions for GPIO_0
+define_string CONFIG_XILINX_GPIO_0_INSTANCE opb_gpio_0
+define_hex CONFIG_XILINX_GPIO_0_BASEADDR 0x90000000
+define_hex CONFIG_XILINX_GPIO_0_HIGHADDR 0x900001FF
+define_int CONFIG_XILINX_GPIO_0_USER_ID_CODE 3
+define_int CONFIG_XILINX_GPIO_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_GPIO_0_OPB_DWIDTH 32
+define_string CONFIG_XILINX_GPIO_0_FAMILY virtex4
+define_int CONFIG_XILINX_GPIO_0_GPIO_WIDTH 27
+define_int CONFIG_XILINX_GPIO_0_ALL_INPUTS 0
+define_int CONFIG_XILINX_GPIO_0_INTERRUPT_PRESENT 0
+define_int CONFIG_XILINX_GPIO_0_IS_BIDIR 1
+define_hex CONFIG_XILINX_GPIO_0_DOUT_DEFAULT 0x00000000
+define_hex CONFIG_XILINX_GPIO_0_TRI_DEFAULT 0x04FFFE00
+define_int CONFIG_XILINX_GPIO_0_IS_DUAL 1
+define_int CONFIG_XILINX_GPIO_0_ALL_INPUTS_2 0
+define_int CONFIG_XILINX_GPIO_0_IS_BIDIR_2 0
+define_hex CONFIG_XILINX_GPIO_0_DOUT_DEFAULT_2 0x00000000
+define_hex CONFIG_XILINX_GPIO_0_TRI_DEFAULT_2 0x00000003
+define_string CONFIG_XILINX_GPIO_0_INSTANCE opb_gpio_0
+define_string CONFIG_XILINX_GPIO_0_HW_VER 3.01.a
+
+# Definitions for GPIO_1
+define_string CONFIG_XILINX_GPIO_1_INSTANCE opb_gpio_exp_hdr_0
+define_hex CONFIG_XILINX_GPIO_1_BASEADDR 0x90001000
+define_hex CONFIG_XILINX_GPIO_1_HIGHADDR 0x900011FF
+define_int CONFIG_XILINX_GPIO_1_USER_ID_CODE 3
+define_int CONFIG_XILINX_GPIO_1_OPB_AWIDTH 32
+define_int CONFIG_XILINX_GPIO_1_OPB_DWIDTH 32
+define_string CONFIG_XILINX_GPIO_1_FAMILY virtex4
+define_int CONFIG_XILINX_GPIO_1_GPIO_WIDTH 32
+define_int CONFIG_XILINX_GPIO_1_ALL_INPUTS 0
+define_int CONFIG_XILINX_GPIO_1_INTERRUPT_PRESENT 0
+define_int CONFIG_XILINX_GPIO_1_IS_BIDIR 1
+define_hex CONFIG_XILINX_GPIO_1_DOUT_DEFAULT 0x00000000
+define_hex CONFIG_XILINX_GPIO_1_TRI_DEFAULT 0xFFFFFFFF
+define_int CONFIG_XILINX_GPIO_1_IS_DUAL 1
+define_int CONFIG_XILINX_GPIO_1_ALL_INPUTS_2 0
+define_int CONFIG_XILINX_GPIO_1_IS_BIDIR_2 1
+define_hex CONFIG_XILINX_GPIO_1_DOUT_DEFAULT_2 0x00000000
+define_hex CONFIG_XILINX_GPIO_1_TRI_DEFAULT_2 0xFFFFFFFF
+define_string CONFIG_XILINX_GPIO_1_INSTANCE opb_gpio_exp_hdr_0
+define_string CONFIG_XILINX_GPIO_1_HW_VER 3.01.a
+
+# Definitions for GPIO_2
+define_string CONFIG_XILINX_GPIO_2_INSTANCE opb_gpio_char_lcd_0
+define_hex CONFIG_XILINX_GPIO_2_BASEADDR 0x90002000
+define_hex CONFIG_XILINX_GPIO_2_HIGHADDR 0x900021FF
+define_int CONFIG_XILINX_GPIO_2_USER_ID_CODE 3
+define_int CONFIG_XILINX_GPIO_2_OPB_AWIDTH 32
+define_int CONFIG_XILINX_GPIO_2_OPB_DWIDTH 32
+define_string CONFIG_XILINX_GPIO_2_FAMILY virtex4
+define_int CONFIG_XILINX_GPIO_2_GPIO_WIDTH 7
+define_int CONFIG_XILINX_GPIO_2_ALL_INPUTS 0
+define_int CONFIG_XILINX_GPIO_2_INTERRUPT_PRESENT 0
+define_int CONFIG_XILINX_GPIO_2_IS_BIDIR 1
+define_hex CONFIG_XILINX_GPIO_2_DOUT_DEFAULT 0x00000000
+define_hex CONFIG_XILINX_GPIO_2_TRI_DEFAULT 0xFFFFFFFF
+define_int CONFIG_XILINX_GPIO_2_IS_DUAL 0
+define_int CONFIG_XILINX_GPIO_2_ALL_INPUTS_2 0
+define_int CONFIG_XILINX_GPIO_2_IS_BIDIR_2 1
+define_hex CONFIG_XILINX_GPIO_2_DOUT_DEFAULT_2 0x00000000
+define_hex CONFIG_XILINX_GPIO_2_TRI_DEFAULT_2 0xFFFFFFFF
+define_string CONFIG_XILINX_GPIO_2_INSTANCE opb_gpio_char_lcd_0
+define_string CONFIG_XILINX_GPIO_2_HW_VER 3.01.a
+
+# Definitions for PS2_DUAL_REF_0
+define_string CONFIG_XILINX_PS2_DUAL_REF_0_INSTANCE opb_ps2_dual_ref_0
+define_string CONFIG_XILINX_PS2_DUAL_REF_0_BASEADDR 0xA9000000
+define_string CONFIG_XILINX_PS2_DUAL_REF_0_HIGHADDR 0xA9001FFF
+define_string CONFIG_XILINX_PS2_DUAL_REF_0_INSTANCE opb_ps2_dual_ref_0
+define_string CONFIG_XILINX_PS2_DUAL_REF_0_HW_VER 1.00.a
+define_int CONFIG_XILINX_PS2_DUAL_REF_0_SYS_INTR1_IRQ 9
+define_int CONFIG_XILINX_PS2_DUAL_REF_0_SYS_INTR2_IRQ 8
+
+# Definitions for IIC_0
+define_string CONFIG_XILINX_IIC_0_INSTANCE opb_iic_0
+define_int CONFIG_XILINX_IIC_0_CLK_FREQ 100000000
+define_int CONFIG_XILINX_IIC_0_IIFREQ 100000
+define_int CONFIG_XILINX_IIC_0_TEN_BIT_ADR 0
+define_int CONFIG_XILINX_IIC_0_GPO_WIDTH 1
+define_int CONFIG_XILINX_IIC_0_DEV_BLK_ID 0
+define_int CONFIG_XILINX_IIC_0_DEV_MIR_ENABLE 0
+define_hex CONFIG_XILINX_IIC_0_BASEADDR 0xA8000000
+define_hex CONFIG_XILINX_IIC_0_HIGHADDR 0xA80001FF
+define_int CONFIG_XILINX_IIC_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_IIC_0_OPB_DWIDTH 32
+define_string CONFIG_XILINX_IIC_0_INSTANCE opb_iic_0
+define_string CONFIG_XILINX_IIC_0_HW_VER 1.01.c
+define_int CONFIG_XILINX_IIC_0_IRQ 7
+
+# Definitions for AC97_CONTROLLER_REF_0
+define_string CONFIG_XILINX_AC97_CONTROLLER_REF_0_INSTANCE opb_ac97_controller_ref_0
+define_hex CONFIG_XILINX_AC97_CONTROLLER_REF_0_BASEADDR 0xA6000000
+define_hex CONFIG_XILINX_AC97_CONTROLLER_REF_0_HIGHADDR 0xA60000FF
+define_int CONFIG_XILINX_AC97_CONTROLLER_REF_0_OPB_DWIDTH 32
+define_int CONFIG_XILINX_AC97_CONTROLLER_REF_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_AC97_CONTROLLER_REF_0_PLAYBACK 1
+define_int CONFIG_XILINX_AC97_CONTROLLER_REF_0_RECORD 1
+define_int CONFIG_XILINX_AC97_CONTROLLER_REF_0_PLAY_INTR_LEVEL 2
+define_int CONFIG_XILINX_AC97_CONTROLLER_REF_0_REINTR_LEVEL 3
+define_string CONFIG_XILINX_AC97_CONTROLLER_REF_0_INSTANCE opb_ac97_controller_ref_0
+define_string CONFIG_XILINX_AC97_CONTROLLER_REF_0_HW_VER 1.00.a
+define_int CONFIG_XILINX_AC97_CONTROLLER_REF_0_PLAYBACK_INTERRUPT_IRQ 6
+define_int CONFIG_XILINX_AC97_CONTROLLER_REF_0_RECORD_INTERRUPT_IRQ 5
+
+# Definitions for V34_0
+define_string CONFIG_XILINX_V34_0_INSTANCE plb_v34_0
+define_int CONFIG_XILINX_V34_0_PLB_NUM_MASTERS 3
+define_int CONFIG_XILINX_V34_0_PLB_NUM_SLAVES 2
+define_int CONFIG_XILINX_V34_0_PLB_MID_WIDTH 2
+define_int CONFIG_XILINX_V34_0_PLB_AWIDTH 32
+define_int CONFIG_XILINX_V34_0_PLB_DWIDTH 64
+define_int CONFIG_XILINX_V34_0_DCR_INTFCE 1
+define_hex CONFIG_XILINX_V34_0_BASEADDR 0x00000010
+define_hex CONFIG_XILINX_V34_0_HIGHADDR 0x0000001F
+define_int CONFIG_XILINX_V34_0_DCR_AWIDTH 10
+define_int CONFIG_XILINX_V34_0_DCR_DWIDTH 32
+define_int CONFIG_XILINX_V34_0_EXT_RESET_HIGH 1
+define_int CONFIG_XILINX_V34_0_IRQ_ACTIVE 1
+define_int CONFIG_XILINX_V34_0_NUM_OPBCLK_PLB2OPB_REARB 100
+define_string CONFIG_XILINX_V34_0_INSTANCE plb_v34_0
+define_string CONFIG_XILINX_V34_0_HW_VER 1.02.a
+
+# Definitions for DDR_0
+define_string CONFIG_XILINX_DDR_0_INSTANCE plb_ddr_0
+define_int CONFIG_XILINX_DDR_0_INCLUDE_BURST_CACHELN_SUPPORT 1
+define_int CONFIG_XILINX_DDR_0_REG_DIMM 0
+define_int CONFIG_XILINX_DDR_0_NUM_BANKS_MEM 1
+define_int CONFIG_XILINX_DDR_0_NUM_CLK_PAIRS 1
+define_string CONFIG_XILINX_DDR_0_FAMILY virtex4
+define_int CONFIG_XILINX_DDR_0_INCLUDE_ECSUPPORT 0
+define_int CONFIG_XILINX_DDR_0_ENABLE_ECREG 0
+define_int CONFIG_XILINX_DDR_0_ECDEFAULT_ON 1
+define_int CONFIG_XILINX_DDR_0_INCLUDE_ECINTR 0
+define_int CONFIG_XILINX_DDR_0_INCLUDE_ECTEST 0
+define_int CONFIG_XILINX_DDR_0_ECSETHRESHOLD 1
+define_int CONFIG_XILINX_DDR_0_ECDETHRESHOLD 1
+define_int CONFIG_XILINX_DDR_0_ECPETHRESHOLD 1
+define_int CONFIG_XILINX_DDR_0_NUM_ECBITS 7
+define_int CONFIG_XILINX_DDR_0_DDR_TMRD 20000
+define_int CONFIG_XILINX_DDR_0_DDR_TWR 20000
+define_int CONFIG_XILINX_DDR_0_DDR_TWTR 1
+define_int CONFIG_XILINX_DDR_0_DDR_TRAS 60000
+define_int CONFIG_XILINX_DDR_0_DDR_TRC 90000
+define_int CONFIG_XILINX_DDR_0_DDR_TRFC 80000
+define_int CONFIG_XILINX_DDR_0_DDR_TRCD 30000
+define_int CONFIG_XILINX_DDR_0_DDR_TRRD 15000
+define_int CONFIG_XILINX_DDR_0_DDR_TREFC 70300000
+define_int CONFIG_XILINX_DDR_0_DDR_TREFI 7800000
+define_int CONFIG_XILINX_DDR_0_DDR_TRP 30000
+define_int CONFIG_XILINX_DDR_0_DDR_CAS_LAT 2
+define_int CONFIG_XILINX_DDR_0_DDR_DWIDTH 32
+define_int CONFIG_XILINX_DDR_0_DDR_AWIDTH 13
+define_int CONFIG_XILINX_DDR_0_DDR_COL_AWIDTH 9
+define_int CONFIG_XILINX_DDR_0_DDR_BANK_AWIDTH 2
+define_hex CONFIG_XILINX_DDR_0_MEM0_BASEADDR 0x10000000
+define_hex CONFIG_XILINX_DDR_0_MEM0_HIGHADDR 0x1FFFFFFF
+define_hex CONFIG_XILINX_DDR_0_MEM1_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_DDR_0_MEM1_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_DDR_0_MEM2_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_DDR_0_MEM2_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_DDR_0_MEM3_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_DDR_0_MEM3_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_DDR_0_ECBASEADDR 0x0F000000
+define_hex CONFIG_XILINX_DDR_0_ECHIGHADDR 0x0F000FFF
+define_int CONFIG_XILINX_DDR_0_PLB_NUM_MASTERS 3
+define_int CONFIG_XILINX_DDR_0_PLB_MID_WIDTH 2
+define_int CONFIG_XILINX_DDR_0_PLB_AWIDTH 32
+define_int CONFIG_XILINX_DDR_0_PLB_DWIDTH 64
+define_int CONFIG_XILINX_DDR_0_PLB_CLK_PERIOD_PS 15000
+define_int CONFIG_XILINX_DDR_0_SIM_INIT_TIME_PS 200000000
+define_string CONFIG_XILINX_DDR_0_INSTANCE plb_ddr_0
+define_string CONFIG_XILINX_DDR_0_HW_VER 1.10.a
+
+# Definitions for CYPRESS_USB_0
+define_string CONFIG_XILINX_CYPRESS_USB_0_INSTANCE opb_emc_usb_0
+define_int CONFIG_XILINX_CYPRESS_USB_0_NUM_BANKS_MEM 1
+define_int CONFIG_XILINX_CYPRESS_USB_0_INCLUDE_NEGEDGE_IOREGS 0
+define_hex CONFIG_XILINX_CYPRESS_USB_0_BASEADDR 0xA5100000
+define_hex CONFIG_XILINX_CYPRESS_USB_0_HIGHADDR 0xA51001FF
+define_hex CONFIG_XILINX_CYPRESS_USB_0_MEM0_BASEADDR 0xA5000000
+define_hex CONFIG_XILINX_CYPRESS_USB_0_MEM0_HIGHADDR 0xA50000FF
+define_hex CONFIG_XILINX_CYPRESS_USB_0_MEM1_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_CYPRESS_USB_0_MEM1_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_CYPRESS_USB_0_MEM2_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_CYPRESS_USB_0_MEM2_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_CYPRESS_USB_0_MEM3_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_CYPRESS_USB_0_MEM3_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_CYPRESS_USB_0_MEM4_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_CYPRESS_USB_0_MEM4_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_CYPRESS_USB_0_MEM5_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_CYPRESS_USB_0_MEM5_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_CYPRESS_USB_0_MEM6_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_CYPRESS_USB_0_MEM6_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_CYPRESS_USB_0_MEM7_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_CYPRESS_USB_0_MEM7_HIGHADDR 0x00000000
+define_int CONFIG_XILINX_CYPRESS_USB_0_MEM0_WIDTH 32
+define_int CONFIG_XILINX_CYPRESS_USB_0_MEM1_WIDTH 32
+define_int CONFIG_XILINX_CYPRESS_USB_0_MEM2_WIDTH 32
+define_int CONFIG_XILINX_CYPRESS_USB_0_MEM3_WIDTH 32
+define_int CONFIG_XILINX_CYPRESS_USB_0_MEM4_WIDTH 32
+define_int CONFIG_XILINX_CYPRESS_USB_0_MEM5_WIDTH 32
+define_int CONFIG_XILINX_CYPRESS_USB_0_MEM6_WIDTH 32
+define_int CONFIG_XILINX_CYPRESS_USB_0_MEM7_WIDTH 32
+define_int CONFIG_XILINX_CYPRESS_USB_0_MAX_MEM_WIDTH 32
+define_int CONFIG_XILINX_CYPRESS_USB_0_INCLUDE_DATAWIDTH_MATCHING_0 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_INCLUDE_DATAWIDTH_MATCHING_1 1
+define_int CONFIG_XILINX_CYPRESS_USB_0_INCLUDE_DATAWIDTH_MATCHING_2 1
+define_int CONFIG_XILINX_CYPRESS_USB_0_INCLUDE_DATAWIDTH_MATCHING_3 1
+define_int CONFIG_XILINX_CYPRESS_USB_0_INCLUDE_DATAWIDTH_MATCHING_4 1
+define_int CONFIG_XILINX_CYPRESS_USB_0_INCLUDE_DATAWIDTH_MATCHING_5 1
+define_int CONFIG_XILINX_CYPRESS_USB_0_INCLUDE_DATAWIDTH_MATCHING_6 1
+define_int CONFIG_XILINX_CYPRESS_USB_0_INCLUDE_DATAWIDTH_MATCHING_7 1
+define_int CONFIG_XILINX_CYPRESS_USB_0_SYNCH_MEM_0 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_SYNCH_PIPEDELAY_0 2
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_ADDR_TO_OUT_SLOW_PS_0 21000
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_ADDR_TO_OUT_SLOW_PS_0 42000
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_MIN_PULSE_WIDTH_PS_0 24000
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_ADDR_TO_OUT_FAST_PS_0 210000
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_ADDR_TO_OUT_FAST_PS_0 42000
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_RECOVERY_BEFORE_WRITE_PS_0 84000
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_RECOVERY_BEFORE_READ_PS_0 84000
+define_int CONFIG_XILINX_CYPRESS_USB_0_SYNCH_MEM_1 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_SYNCH_PIPEDELAY_1 2
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_ADDR_TO_OUT_SLOW_PS_1 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_ADDR_TO_OUT_SLOW_PS_1 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_MIN_PULSE_WIDTH_PS_1 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_ADDR_TO_OUT_FAST_PS_1 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_ADDR_TO_OUT_FAST_PS_1 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_RECOVERY_BEFORE_WRITE_PS_1 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_RECOVERY_BEFORE_READ_PS_1 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_SYNCH_MEM_2 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_SYNCH_PIPEDELAY_2 2
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_ADDR_TO_OUT_SLOW_PS_2 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_ADDR_TO_OUT_SLOW_PS_2 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_MIN_PULSE_WIDTH_PS_2 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_ADDR_TO_OUT_FAST_PS_2 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_ADDR_TO_OUT_FAST_PS_2 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_RECOVERY_BEFORE_WRITE_PS_2 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_RECOVERY_BEFORE_READ_PS_2 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_SYNCH_MEM_3 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_SYNCH_PIPEDELAY_3 2
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_ADDR_TO_OUT_SLOW_PS_3 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_ADDR_TO_OUT_SLOW_PS_3 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_MIN_PULSE_WIDTH_PS_3 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_ADDR_TO_OUT_FAST_PS_3 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_ADDR_TO_OUT_FAST_PS_3 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_RECOVERY_BEFORE_WRITE_PS_3 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_RECOVERY_BEFORE_READ_PS_3 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_SYNCH_MEM_4 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_SYNCH_PIPEDELAY_4 2
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_ADDR_TO_OUT_SLOW_PS_4 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_ADDR_TO_OUT_SLOW_PS_4 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_MIN_PULSE_WIDTH_PS_4 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_ADDR_TO_OUT_FAST_PS_4 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_ADDR_TO_OUT_FAST_PS_4 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_RECOVERY_BEFORE_WRITE_PS_4 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_RECOVERY_BEFORE_READ_PS_4 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_SYNCH_MEM_5 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_SYNCH_PIPEDELAY_5 2
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_ADDR_TO_OUT_SLOW_PS_5 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_ADDR_TO_OUT_SLOW_PS_5 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_MIN_PULSE_WIDTH_PS_5 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_ADDR_TO_OUT_FAST_PS_5 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_ADDR_TO_OUT_FAST_PS_5 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_RECOVERY_BEFORE_WRITE_PS_5 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_RECOVERY_BEFORE_READ_PS_5 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_SYNCH_MEM_6 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_SYNCH_PIPEDELAY_6 2
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_ADDR_TO_OUT_SLOW_PS_6 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_ADDR_TO_OUT_SLOW_PS_6 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_MIN_PULSE_WIDTH_PS_6 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_ADDR_TO_OUT_FAST_PS_6 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_ADDR_TO_OUT_FAST_PS_6 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_RECOVERY_BEFORE_WRITE_PS_6 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_RECOVERY_BEFORE_READ_PS_6 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_SYNCH_MEM_7 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_SYNCH_PIPEDELAY_7 2
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_ADDR_TO_OUT_SLOW_PS_7 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_ADDR_TO_OUT_SLOW_PS_7 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_MIN_PULSE_WIDTH_PS_7 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_ADDR_TO_OUT_FAST_PS_7 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_ADDR_TO_OUT_FAST_PS_7 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_READ_RECOVERY_BEFORE_WRITE_PS_7 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_WRITE_RECOVERY_BEFORE_READ_PS_7 0
+define_int CONFIG_XILINX_CYPRESS_USB_0_OPB_DWIDTH 32
+define_int CONFIG_XILINX_CYPRESS_USB_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_CYPRESS_USB_0_OPB_CLK_PERIOD_PS 15000
+define_int CONFIG_XILINX_CYPRESS_USB_0_DEV_BLK_ID 1
+define_int CONFIG_XILINX_CYPRESS_USB_0_DEV_MIR_ENABLE 0
+define_string CONFIG_XILINX_CYPRESS_USB_0_INSTANCE opb_emc_usb_0
+define_string CONFIG_XILINX_CYPRESS_USB_0_HW_VER 1.10.b
+
+# Definitions for TFT_CNTLR_REF_0
+define_string CONFIG_XILINX_TFT_CNTLR_REF_0_INSTANCE plb_tft_cntlr_ref_0
+define_hex CONFIG_XILINX_TFT_CNTLR_REF_0_DCR_BASEADDR 0x00000080
+define_hex CONFIG_XILINX_TFT_CNTLR_REF_0_DCR_HIGHADDR 0x00000081
+define_hex CONFIG_XILINX_TFT_CNTLR_REF_0_DEFAULT_TFT_BASE_ADDR 0x0000009F
+define_int CONFIG_XILINX_TFT_CNTLR_REF_0_DPS_INIT 0b1
+define_int CONFIG_XILINX_TFT_CNTLR_REF_0_ON_INIT 1
+define_string CONFIG_XILINX_TFT_CNTLR_REF_0_INSTANCE plb_tft_cntlr_ref_0
+define_string CONFIG_XILINX_TFT_CNTLR_REF_0_HW_VER 1.00.b
+
+# Definitions for ETHERNET_0
+define_string CONFIG_XILINX_ETHERNET_0_INSTANCE plb_ethernet_0
+define_int CONFIG_XILINX_ETHERNET_0_DEV_BLK_ID 0
+define_int CONFIG_XILINX_ETHERNET_0_PLB_CLK_PERIOD_PS 15000
+define_string CONFIG_XILINX_ETHERNET_0_FAMILY virtex4
+define_int CONFIG_XILINX_ETHERNET_0_IPIF_FIFO_DEPTH 65536
+define_hex CONFIG_XILINX_ETHERNET_0_BASEADDR 0x08000000
+define_hex CONFIG_XILINX_ETHERNET_0_HIGHADDR 0x08003FFF
+define_int CONFIG_XILINX_ETHERNET_0_DEV_MIR_ENABLE 1
+define_int CONFIG_XILINX_ETHERNET_0_RESET_PRESENT 1
+define_int CONFIG_XILINX_ETHERNET_0_INCLUDE_DEV_PENCODER 1
+define_int CONFIG_XILINX_ETHERNET_0_DMA_PRESENT 3
+define_int CONFIG_XILINX_ETHERNET_0_DMA_INTR_COALESCE 1
+define_int CONFIG_XILINX_ETHERNET_0_PLB_NUM_MASTERS 3
+define_int CONFIG_XILINX_ETHERNET_0_PLB_MID_WIDTH 2
+define_int CONFIG_XILINX_ETHERNET_0_PLB_AWIDTH 32
+define_int CONFIG_XILINX_ETHERNET_0_PLB_DWIDTH 64
+define_hex CONFIG_XILINX_ETHERNET_0_MIIM_CLKDVD 0x00000013
+define_int CONFIG_XILINX_ETHERNET_0_SOURCE_ADDR_INSERT_EXIST 1
+define_int CONFIG_XILINX_ETHERNET_0_PAD_INSERT_EXIST 1
+define_int CONFIG_XILINX_ETHERNET_0_FCS_INSERT_EXIST 1
+define_int CONFIG_XILINX_ETHERNET_0_MAFIFO_DEPTH 64
+define_int CONFIG_XILINX_ETHERNET_0_HALF_DUPLEX_EXIST 1
+define_int CONFIG_XILINX_ETHERNET_0_ERR_COUNT_EXIST 1
+define_int CONFIG_XILINX_ETHERNET_0_MII_EXIST 1
+define_string CONFIG_XILINX_ETHERNET_0_INSTANCE plb_ethernet_0
+define_string CONFIG_XILINX_ETHERNET_0_HW_VER 1.01.a
+define_int CONFIG_XILINX_ETHERNET_0_IRQ 2
+
+# Definitions for EMC_0
+define_string CONFIG_XILINX_EMC_0_INSTANCE opb_emc_0
+define_int CONFIG_XILINX_EMC_0_NUM_BANKS_MEM 2
+define_int CONFIG_XILINX_EMC_0_INCLUDE_NEGEDGE_IOREGS 0
+define_hex CONFIG_XILINX_EMC_0_BASEADDR 0x24000000
+define_hex CONFIG_XILINX_EMC_0_HIGHADDR 0x240001FF
+define_hex CONFIG_XILINX_EMC_0_MEM0_BASEADDR 0x20000000
+define_hex CONFIG_XILINX_EMC_0_MEM0_HIGHADDR 0x200FFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM1_BASEADDR 0x28000000
+define_hex CONFIG_XILINX_EMC_0_MEM1_HIGHADDR 0x287FFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM2_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM2_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_EMC_0_MEM3_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM3_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_EMC_0_MEM4_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM4_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_EMC_0_MEM5_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM5_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_EMC_0_MEM6_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM6_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_EMC_0_MEM7_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM7_HIGHADDR 0x00000000
+define_int CONFIG_XILINX_EMC_0_MEM0_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM1_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM2_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM3_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM4_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM5_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM6_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM7_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MAX_MEM_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_0 0
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_1 0
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_2 1
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_3 1
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_4 1
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_5 1
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_6 1
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_7 1
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_0 1
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_0 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_0 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_0 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_0 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_0 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_0 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_0 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_0 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_1 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_1 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_1 110000
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_1 55000
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_1 70000
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_1 110000
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_1 55000
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_1 10000
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_1 35000
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_2 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_2 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_2 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_2 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_2 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_2 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_2 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_2 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_2 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_3 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_3 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_3 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_3 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_3 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_3 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_3 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_3 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_3 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_4 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_4 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_4 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_4 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_4 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_4 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_4 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_4 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_4 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_5 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_5 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_5 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_5 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_5 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_5 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_5 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_5 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_5 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_6 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_6 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_6 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_6 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_6 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_6 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_6 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_6 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_6 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_7 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_7 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_7 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_7 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_7 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_7 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_7 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_7 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_7 0
+define_int CONFIG_XILINX_EMC_0_OPB_DWIDTH 32
+define_int CONFIG_XILINX_EMC_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_EMC_0_OPB_CLK_PERIOD_PS 15000
+define_int CONFIG_XILINX_EMC_0_DEV_BLK_ID 1
+define_int CONFIG_XILINX_EMC_0_DEV_MIR_ENABLE 0
+define_string CONFIG_XILINX_EMC_0_INSTANCE opb_emc_0
+define_string CONFIG_XILINX_EMC_0_HW_VER 1.10.b
+
+# Definitions for SYSACE_0
+define_string CONFIG_XILINX_SYSACE_0_INSTANCE opb_sysace_0
+define_hex CONFIG_XILINX_SYSACE_0_BASEADDR 0xCF000000
+define_hex CONFIG_XILINX_SYSACE_0_HIGHADDR 0xCF0001FF
+define_int CONFIG_XILINX_SYSACE_0_MEM_WIDTH 16
+define_int CONFIG_XILINX_SYSACE_0_OPB_DWIDTH 32
+define_int CONFIG_XILINX_SYSACE_0_OPB_AWIDTH 32
+define_string CONFIG_XILINX_SYSACE_0_INSTANCE opb_sysace_0
+define_string CONFIG_XILINX_SYSACE_0_HW_VER 1.00.b
+define_int CONFIG_XILINX_SYSACE_0_IRQ 4
+
+# Peripheral counts
+define_int CONFIG_XILINX_SYSACE_NUM_INSTANCES 1
+define_int CONFIG_XILINX_TIMER_NUM_INSTANCES 1
+define_int CONFIG_XILINX_UARTLITE_NUM_INSTANCES 1
+define_int CONFIG_XILINX_CYPRESS_USB_NUM_INSTANCES 1
+define_int CONFIG_XILINX_AC97_CONTROLLER_REF_NUM_INSTANCES 1
+define_int CONFIG_XILINX_TFT_CNTLR_REF_NUM_INSTANCES 1
+define_int CONFIG_XILINX_LMB_BRAM_IF_CNTLR_NUM_INSTANCES 2
+define_int CONFIG_XILINX_V34_NUM_INSTANCES 1
+define_int CONFIG_XILINX_INTC_NUM_INSTANCES 1
+define_int CONFIG_XILINX_DDR_NUM_INSTANCES 1
+define_int CONFIG_XILINX_EMC_NUM_INSTANCES 1
+define_int CONFIG_XILINX_IIC_NUM_INSTANCES 1
+define_int CONFIG_XILINX_MDM_NUM_INSTANCES 1
+define_int CONFIG_XILINX_PS2_DUAL_REF_NUM_INSTANCES 1
+define_int CONFIG_XILINX_ETHERNET_NUM_INSTANCES 1
+define_int CONFIG_XILINX_GPIO_NUM_INSTANCES 3
+
diff -urN linux-2.4.29/arch/microblaze/platform/ml401/head_ram.S linux-2.4.29-uc1/arch/microblaze/platform/ml401/head_ram.S
--- linux-2.4.29/arch/microblaze/platform/ml401/head_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/ml401/head_ram.S	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,104 @@
+/*
+ * arch/microblaze/kernel/head.S -- Lowest-level startup code
+ *
+ *  Copyright (C) 2004       Brett Boren <borenb@eng.uah.edu>
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *                           based upon v850 version
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <asm/clinkage.h>
+#include <asm/current.h>
+#include <asm/entry.h>
+#include <asm/irq.h>
+
+
+/* Make a slightly more convenient alias for C_SYMBOL_NAME.  */
+#define CSYM	C_SYMBOL_NAME 
+
+.global CSYM(_ramstart)
+
+	.data
+CSYM(_ramstart):
+	.long 0
+
+	.text
+
+	// Define `mach_early_init' as a weak symbol
+	.global	CSYM(mach_early_init)
+	.weak	CSYM(mach_early_init)
+
+C_ENTRY(start):
+	// Make sure interrupts are turned off, just in case
+	mfs	r1, rmsr
+	andi	r1, r1, ~2
+	mts	rmsr, r1
+
+	// Set Small Data Anchors
+	la	r13, r0, _KERNEL_SDA_BASE_
+	la	r2, r0, _KERNEL_SDA2_BASE_
+
+	// Initialise the stack pointer
+	// Initial stack is shrunk by 4 bytes (1 word) to permit use of
+	// standard sp->task ptr conversion functions later on
+	la	r1, r0, CSYM(init_task_union)+KERNEL_STACK_SIZE-4;
+
+#ifdef CONFIG_MBVANILLA_CMDLINE
+	// BAB 1/7/04 - Copy off cmdline pointer passed in by bootloader
+	swi	r5, r0, CSYM(bootloader_buf_addr)
+#endif	
+	// See if there's a platform-specific early-initialization routine
+	// defined; it's a weak symbol, so it will have an address of zero if
+	// there's not.
+	la	r6, r0, CSYM(mach_early_init)
+	beqi	r6, 3f
+
+	// There is one, so call it.  If this function is written in C, it
+	// should be very careful -- the stack pointer is valid, but very
+	// little else is (e.g., bss is not zeroed yet).
+	brald	r15, r6			// do call
+	nop				// delay slot
+
+3:
+	// Kernel stack pointer save location
+	swi	r1, r0, KSP
+
+	// Assert that we're in `kernel mode'
+	addi	r19, r0, 1
+	swi	r19, r0, KM
+
+#if 0
+	// Zero bss area, since we can't rely upon any loader to do so
+	addi	r5, r0, CSYM(__bss_start)
+	add	r6, r0, r0
+	addi	r7, r0, CSYM(__bss_end)
+	rsub	r7, r5, r7
+	bralid	r15, CSYM(memset)
+	nop
+
+	// Zero sbss area, since we can't rely upon any loader to do so
+	addi	r5, r0, CSYM(_ssbss)
+	add	r6, r0, r0
+	addi	r7, r0, CSYM(_esbss)
+	rsub	r7, r5, r7
+	bralid	r15, CSYM(memset)
+	nop
+#endif
+
+	// initialise the current task ptr.  This must happen after
+	// we zero BSS, SBSS etc, because "current" is a global C symbol
+	GET_CURRENT_TASK(CURRENT_TASK);
+
+	// Start Linux kernel.
+	// If this call ever returns (which it shouldn't),
+	// set the link pointer to somewhere harmless
+	addi	r15, r0, CSYM(machine_halt)
+	brai	CSYM(start_kernel)
+END(start)
diff -urN linux-2.4.29/arch/microblaze/platform/ml401/machine.c linux-2.4.29-uc1/arch/microblaze/platform/ml401/machine.c
--- linux-2.4.29/arch/microblaze/platform/ml401/machine.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/ml401/machine.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,309 @@
+/*
+ * arch/microblaze/platform/uclinux-auto/machine.h -- Machine-dependent defs for
+ *	auto-configured Microblaze system
+ *
+ *  Copyright (C) 2003	John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+#include <asm/bitops.h>
+#include <asm/pgalloc.h>
+
+/* Declarations of core setup functions */
+#include <asm/mach.h>
+
+/* Get header files for the peripherals */
+#include <asm/microblaze_timer.h>
+#include <asm/microblaze_intc.h>
+#include <asm/microblaze_gpio.h>
+
+/* for 2.6, include asm-generic/sections.h */
+extern char __bss_start[], __bss_stop[];
+
+#define RAM_START (ERAM_ADDR)
+#define RAM_END ((ERAM_ADDR)+(ERAM_SIZE))
+
+extern void memcons_setup (void);
+extern void xmbrs_console_init(void);
+
+unsigned int __vram_start;
+
+#define REG_DUMP_ADDR		0x220000
+
+
+extern struct irqaction reg_snap_action; /* fwd decl */
+
+/* Called with each timer tick, if non-zero.  */
+void (*mach_tick)(void) = 0;
+
+/* Function to drive one of the LED segments */
+void mach_heartbeat(unsigned int value)
+{
+	/* 
+	 * FIXME Strictly speaking this should probably be 
+	 * protected by a semaphore 
+	 */
+
+#ifdef CONFIG_XILINX_GPIO_0_INSTANCE
+	/* Read current value on the port */
+	volatile unsigned int cur_val = microblaze_gpio_read(CONFIG_XILINX_GPIO_0_BASEADDR);
+
+	/* Clear LED bit  */
+	cur_val &= ~0x00010000;
+
+	/* Set it if required */
+	if(value)
+		cur_val |=  0x00010000;
+	
+	microblaze_gpio_write(CONFIG_XILINX_GPIO_0_BASEADDR,cur_val);
+#endif
+}
+
+/* mach_gettimeoffset returns the number of microseconds elapsed since the
+   start of the current tick */
+unsigned long mach_gettimeoffset(void)
+{
+	unsigned long tctr=timer_get_time(CONFIG_XILINX_TIMER_0_BASEADDR,0);
+	unsigned long tcmp=timer_get_compare(CONFIG_XILINX_TIMER_0_BASEADDR,0);
+	unsigned long offset;
+
+	/*
+	 * Timer used in count up mode, so subtract load value from
+	 * counter register to get elapsed ticks */
+	offset = (tctr-tcmp)/(CONFIG_XILINX_CPU_CLOCK_FREQ/1000000);
+
+	/*
+	 * If we are still in the first half of the upcount and a
+	 * timer interupt is pending, then add on a tick's worth of time.
+	 */
+
+	if (((offset * 2) < (1000000/HZ)) && 
+		(timer_get_csr(CONFIG_XILINX_TIMER_0_BASEADDR,0)&TIMER_INTERRUPT))
+	{
+		offset += 1000000/HZ;
+	}
+
+	return offset;
+}
+
+/* Return starting point of romfs image */
+inline unsigned *get_romfs_base(void)
+{
+	/* For now, assume "Standard" model of bss_start */
+	return (unsigned *)&__bss_start;
+}
+
+/* Handle both romfs and cramfs types, without generating unnecessary
+   code (ie no point checking for CRAMFS if it's not even enabled) */
+inline unsigned get_romfs_len(unsigned long *addr)
+{
+#ifdef CONFIG_ROMFS_FS
+	if (memcmp(&addr[0], "-rom1fs-", 8) == 0)       /* romfs */
+		return be32_to_cpu(addr[2]);
+#endif
+
+#ifdef CONFIG_CRAMFS
+	if (addr[0] == le32_to_cpu(0x28cd3d45))	/* cramfs */
+		return le32_to_cpu(addr[1]);
+#endif
+	return 0;
+}
+
+/* mach_early_init() is called very early, after the kernel stack and SDA 
+   pointers are configured, but before BSS/SBSS are zeroed etc.  Be careful 
+   what you do in here.  The bss and sbss sections are zeroed in here */
+void __init mach_early_init (void)
+{
+	unsigned int *src, *dst;
+	unsigned int len;
+
+	extern unsigned char _ssbss, _esbss;
+	extern unsigned int _intv_load_end, _intv_load_start;
+	extern unsigned int _ramstart;
+
+	/* Copy interrupt vectors from high memory down to where
+	   they belong. */
+	dst = (unsigned int *)0x0;		
+	src = (unsigned int *)&_intv_load_start;
+
+#if 1	/* JW don't overwrite reset vector */
+	src++;
+	src++;
+	dst++;
+	dst++;
+#endif
+	do {
+		*(dst++) = *(src++);
+	} while (src < &_intv_load_end);
+
+	/* Copy ROMFS above bss */
+	src=get_romfs_base();
+	len=get_romfs_len(src);
+
+	if(len)
+	{
+		/* Use memmove to handle likely case of memory overlap */
+		memmove(__bss_stop,__bss_start,len);
+	}
+
+        _ramstart = (unsigned long)__bss_stop + len;
+	
+	/* Zero the BSS and SBSS sections */
+	memset(__bss_start,0,__bss_stop-__bss_start);
+	memset(&_ssbss,0,&_esbss-&_ssbss);
+}
+
+void __init mach_reserve_bootmem(void)
+{
+	unsigned *vmem_reg_addr;
+	void *vram_mem;
+
+	/* Reserve memory for the framebuffer */
+//#ifdef CONFIG_XILINX_TFT_CNTLR_REF_0_INSTANCE
+#if 0
+	/* Get address of DCR across the OPB->DCR bridge */
+	vmem_reg_addr = (unsigned *) 
+		(CONFIG_XILINX_TFT_CNTLR_REF_0_DCR_BASEADDR*4 +
+		0xD0000000);
+
+	/* Let's take 2MB off the top of RAM */
+	vram_mem=CONFIG_XILINX_ERAM_START+CONFIG_XILINX_ERAM_SIZE;
+	vram_mem-=0x200000;
+
+	printk("Reserving 2MB for video memory (0x%08x-0x%08x)\n",
+			(vram_mem), vram_mem + 0x1fffff);
+	reserve_bootmem(__pa(vram_mem),0x200000);
+	/* Set the vmem address on the controller */
+	*vmem_reg_addr = vram_mem;
+
+	/* Tell the video driver where to find the video mem */
+	__vram_start = vram_mem;
+#endif
+}
+
+void __init mach_setup (char **cmdline)
+{
+	/* Enable the instruction and data caches (if present) */
+	#if CONFIG_XILINX_MICROBLAZE0_USE_ICACHE==1
+	__flush_icache_all();
+	__enable_icache();
+	#endif
+
+	#if CONFIG_XILINX_MICROBLAZE0_USE_DCACHE==1
+	__flush_dcache_all();
+	__enable_dcache();
+	#endif
+
+	printk (KERN_INFO "CPU: MICROBLAZE\n");
+
+	/* Now called from tty_io.c:init_console(), where it should be (/
+	/* xmbrs_console_init();  */
+	
+	/* 
+	 * Enable master control on interrupt controller.  Note
+         * this does not enable interrupts in the processor, nor 
+	 * does it enable individual IRQs on the controller.  Just
+         * initialises the intc in preparation for these things */
+	microblaze_intc_master_enable();
+
+#ifdef CONFIG_XILINX_GPIO_0_INSTANCE
+	/* Configure the GPIO */
+	/* 8 inputs, 16 outputs */
+	/* microblaze_gpio_setdir(CONFIG_XILINX_GPIO_0_BASEADDR,MICROBLAZE_GPIO_DIR); */
+#endif
+}
+
+void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len)
+{
+	*ram_start = CONFIG_XILINX_ERAM_START;
+	*ram_len = CONFIG_XILINX_ERAM_SIZE;
+}
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* Initialise timer */
+	microblaze_timer_configure(0,HZ);
+
+	/* And install timer interrupt handler at appropriate vector */
+
+	/* Timer is always attached to interrupt 0 (highest priority) */
+	/* Note we use setup_irq rather than request_irq */
+	setup_irq (CONFIG_XILINX_TIMER_0_IRQ, timer_action);
+}
+
+
+void mach_gettimeofday (struct timeval *tv)
+{
+	tv->tv_sec = 0;
+	tv->tv_usec = 0;
+}
+
+void machine_halt (void) __attribute__ ((noreturn));
+void machine_halt (void)
+{
+	for (;;) {
+		/* Following code should disable interrupts */
+		asm ("nop; nop; nop; nop; nop");
+	}
+}
+
+void machine_restart (char *__unused)
+{
+	machine_halt ();
+}
+
+void machine_power_off (void)
+{
+	machine_halt ();
+}
+
+
+/* Interrupts */
+
+/* Data to initialise interrupt controller functionality */
+struct microblaze_intc_irq_init irq_inits[] = {
+	/* Name, base, num, priority (unused in microblaze) */
+	{ "XINTC", 0, NUM_MACH_IRQS,	7 },
+	{ 0 }
+};
+#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
+
+struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
+
+/* Initialize interrupts.  */
+void __init mach_init_irqs (void)
+{
+	microblaze_intc_init_irq_types (irq_inits, hw_itypes);
+}
+
+
+/* An interrupt handler that copies the registers to a known memory location,
+   for debugging purposes.  */
+
+#if 0
+static void make_reg_snap (int irq, void *dummy, struct pt_regs *regs)
+{
+	(*(unsigned *)REG_DUMP_ADDR)++;
+	(*(struct pt_regs *)(REG_DUMP_ADDR + sizeof (unsigned))) = *regs;
+}
+
+static int reg_snap_dev_id;
+static struct irqaction reg_snap_action = {
+	make_reg_snap, 0, 0, "reg_snap", &reg_snap_dev_id, 0
+};
+#endif
diff -urN linux-2.4.29/arch/microblaze/platform/ml401/Makefile linux-2.4.29-uc1/arch/microblaze/platform/ml401/Makefile
--- linux-2.4.29/arch/microblaze/platform/ml401/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/ml401/Makefile	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,42 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+#
+# re-use any microblaze files that we can.  Perhaps we should create
+# a microblaze directory for shared files ?
+
+VPATH := $(VPATH):../../kernel
+
+ifdef CONFIG_FULLDEBUG
+	AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+# Work out special CPU flags needed
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: head_$(MODEL).o entry.o platform.o
+
+O_TARGET := platform.o
+
+obj-y := intv.o entry.o machine.o setup.o
+
+head_$(MODEL).o: head_$(MODEL).S
+
+entry.o: entry.S microblaze_defs.h
+
+microblaze_defs.h: ../../kernel/microblaze_defs.c ../../kernel/microblaze_defs.head
+	rm -f microblaze_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/microblaze_defs.c
+	cp ../../kernel/microblaze_defs.head microblaze_defs.h
+	grep '^#define' microblaze_defs.s >> microblaze_defs.h
+	rm microblaze_defs.s
+-include microblaze_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/microblaze/platform/ml401/ram.ld.in linux-2.4.29-uc1/arch/microblaze/platform/ml401/ram.ld.in
--- linux-2.4.29/arch/microblaze/platform/ml401/ram.ld.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/ml401/ram.ld.in	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,150 @@
+/* Simple development memory map for Xilinx Microblaze target.
+   Assume that only the interrupt vectors and the small local data
+   area go in LMB RAM, and that some mythical bootloader will 
+   put the kernel into EXT_RAM 
+*/
+
+/* Get all the autoconfigure addresses etc */
+#include <linux/config.h>
+#include <asm/clinkage.h>
+
+MEMORY {
+	LMB  : ORIGIN = CONFIG_XILINX_LMB_START, 
+	       LENGTH = CONFIG_XILINX_LMB_SIZE
+	ERAM  : ORIGIN = CONFIG_XILINX_ERAM_START,
+                LENGTH = CONFIG_XILINX_ERAM_SIZE
+}
+
+SECTIONS {
+	.text : {
+		/* "untouchable" memory space starts here */
+	        _kram_start = . ;
+	
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+		*(.modinfo)
+		. = ALIGN (0x4) ;
+			*(.kstrtab)
+		. = ALIGN (16) ;	/* Exception table.  */
+		__start___ex_table = . ;
+			*(_ex_table)
+		__stop___ex_table = . ;
+
+		__start___ksymtab = . ; /* All kernel symbols */
+		*(__ksymtab)
+		__stop___ksymtab = . ;
+
+                __start___kallsyms = .; /* All kernel symbols           */
+                        *(__kallsyms)
+                __stop___kallsyms = .;
+
+
+		. = ALIGN (4) ;
+		_etext = . ;
+	} > ERAM
+
+	/* Copies of interrupt vector space. They get copied from here into the 
+  	   proper location by mach_early_setup() */ 
+	.intv : {
+		_intv_load_start = . ;
+	        	*(.intv.reset)	/* Reset vector */
+			*(.intv.common) /* Vectors common to all microblaze proc. */
+			*(.intv.mach)   /* Machine-specific int. vectors.  */
+		_intv_load_end = . ;
+	} > ERAM
+
+
+	/* sdata2 section can go anywhere, but must be word aligned
+	   and SDA2_BASE must point to the middle of it */
+	.sdata2 : {
+		_ssrw = .;
+		. = ALIGN(0x8);
+		*(.sdata2)
+	. = ALIGN(8);
+	_essrw = .;
+	_ssrw_size = _essrw - _ssrw;
+	_KERNEL_SDA2_BASE_ = _ssrw + (_ssrw_size / 2);
+	} > ERAM
+
+
+	.data ALIGN (0x4) : {
+
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN (16) ;
+		*(.data.cacheline_aligned)
+		. = ALIGN (0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN (0x2000) ;
+		_edata = . ;
+	
+		/* Reserve some low RAM for r0 based memory references */
+		. = ALIGN(4) ;
+		C_SYMBOL_NAME(r0_ram) = . ;
+		. = . + 32 ;	/* 32 bytes should be enough */
+	} > ERAM
+
+	/* Under the microblaze ABI, .sdata and .sbss must be contiguous */
+	. = ALIGN(8);
+	.sdata : {
+		_ssro = .;
+		*(.sdata)
+	} > ERAM
+
+	. = ALIGN(4);
+	.sbss : {
+		_ssbss = . ;
+		_sbss_start = .;
+		*(.sbss)
+		_ssbss_end = .;
+		_esbss = . ;
+
+	. = ALIGN(8);
+	_essro = .;
+	_ssro_size = _essro - _ssro;
+	_KERNEL_SDA_BASE_ = _ssro + (_ssro_size / 2);
+	
+ 	} > ERAM
+ 
+	/* Place init and bootmap sections last to reduce fragmentation 
+	   when they are freed */
+ 	.init ALIGN (4096) : {
+ 		_init_start = . ;
+		__init_begin = . ;
+ 			*(.text.init)
+ 			*(.data.init)
+ 		. = ALIGN (16) ;
+ 		__setup_start = . ;
+ 			*(.setup.init)
+ 		__setup_end = . ;
+ 		__initcall_start = . ;
+ 			*(.initcall.init)
+ 		. = ALIGN (4) ;
+ 		__initcall_end = . ;
+		. = ALIGN(4096);
+		__init_end = . ;
+ 		_init_end = . ;
+ 		/* Untouchable kernel ram ends here */
+ 		_kram_end = . ;
+ 	} > ERAM
+ 
+	/* .bss must go last, to be compatible with the way the romfs is handled */
+	.bss ALIGN (0x4) : {
+		_sbss = . ;
+		__bss_start = .;
+			*(.bss*)
+			*(COMMON)
+		. = ALIGN (4) ;
+		__bss_stop = . ;
+		_ebss = . ;
+		_end = . ;
+ 	} > ERAM
+ 
+}
+
diff -urN linux-2.4.29/arch/microblaze/platform/ml401/Rules.make linux-2.4.29-uc1/arch/microblaze/platform/ml401/Rules.make
--- linux-2.4.29/arch/microblaze/platform/ml401/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/ml401/Rules.make	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,6 @@
+# Platform specific rules.make
+
+# Nothing special, just use the standard rules
+include arch/microblaze/platform/Rules.make
+
+
diff -urN linux-2.4.29/arch/microblaze/platform/Rules.make linux-2.4.29-uc1/arch/microblaze/platform/Rules.make
--- linux-2.4.29/arch/microblaze/platform/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/Rules.make	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,86 @@
+#
+# arch/microblaze/platform/Rules.make
+#
+# This file is included by the global makefile so that you can add your own
+# platform-specific flags and dependencies.
+# This is the generic platform Rules.make
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2004       Atmark Techno <yashi@atmark-techno.com>
+# Copyright (C) 2004       John Williams <jwilliams@itee.uq.edu.au>
+# Copyright (C) 1999,2001  Greg Ungerer (gerg@snapgear.com)
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uClinux.org>
+# Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+# Copyright (C) 1994 by Hamish Macdonald
+# Copyright (C) 2000  Lineo Inc. (www.lineo.com)
+
+GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
+
+INCGCC = $(GCC_DIR)/include
+LIBGCC = $(GCC_DIR)/libgcc.a
+
+# Early versions of mb-gcc did silly things with libs, we need to also
+# link against the compiler's libc.a
+ifeq ($(GCC_MAJOR),2)
+	LIBGCC += $(GCC_DIR)/../../../../microblaze/lib/libc.a
+endif
+
+ARCH_DIR = arch/$(ARCH)
+PLAT_DIR = $(ARCH_DIR)/platform/$(PLATFORM)
+
+CFLAGS += -O2
+CFLAGS += -fno-builtin
+CFLAGS += -DNO_MM -DNO_FPU -D__ELF__
+CFLAGS += $(UTS_SYSNAME) -D__linux__
+CFLAGS += -I$(INCGCC)
+
+ifeq ($(CONFIG_XILINX_MICROBLAZE0_USE_BARREL),1)
+   CFLAGS += -mxl-barrel-shift
+endif
+
+ifeq ($(CONFIG_XILINX_MICROBLAZE0_USE_DIV),1)
+    CFLAGS += -mno-xl-soft-div
+endif
+
+# Is the HW multiply instruction available?
+# check if C_FAMILY contains spartan3, virtex2 or virtex4
+ifneq (,$(findstring virtex2,$(CONFIG_XILINX_MICROBLAZE0_FAMILY)))
+    CFLAGS += -mno-xl-soft-mul
+endif
+ifneq (,$(findstring virtex4,$(CONFIG_XILINX_MICROBLAZE0_FAMILY)))
+    CFLAGS += -mno-xl-soft-mul
+endif
+ifneq (,$(findstring spartan3,$(CONFIG_XILINX_MICROBLAZE0_FAMILY)))
+    CFLAGS += -mno-xl-soft-mul
+endif
+
+LD_SCRIPT := linux.ld
+LINKFLAGS = -T $(LD_SCRIPT) --defsym _STACK_SIZE=0x00
+
+#kernel linker script is preprocessed first
+$(LINUX) : $(LD_SCRIPT)
+$(LD_SCRIPT): $(PLAT_DIR)/$(MODEL).ld.in $(PLAT_DIR)/auto-config.in
+	$(CPP) -P -x assembler-with-cpp $(AFLAGS) $< > $@
+
+HEAD := $(ARCH_DIR)/platform/$(PLATFORM)/head_$(MODEL).o
+
+SUBDIRS := $(ARCH_DIR)/kernel $(ARCH_DIR)/mm $(ARCH_DIR)/lib \
+	   $(ARCH_DIR)/xilinx_ocp \
+           $(ARCH_DIR)/platform/$(PLATFORM) $(SUBDIRS)
+
+CORE_FILES := $(ARCH_DIR)/kernel/kernel.o $(ARCH_DIR)/mm/mm.o \
+	    $(ARCH_DIR)/xilinx_ocp/xilinx_ocp.o \
+            $(ARCH_DIR)/platform/$(PLATFORM)/platform.o $(CORE_FILES)
+
+LIBS += $(ARCH_DIR)/lib/lib.a $(LIBGCC)
+
+MAKEBOOT = $(MAKE) -C $(ARCH_DIR)/boot
+
+archclean:
+	@$(MAKEBOOT) clean
+	rm -f $(LD_SCRIPT)
+	rm -f $(ARCH_DIR)/platform/$(PLATFORM)/microblaze_defs.h
+
diff -urN linux-2.4.29/arch/microblaze/platform/suzaku/auto-config.in linux-2.4.29-uc1/arch/microblaze/platform/suzaku/auto-config.in
--- linux-2.4.29/arch/microblaze/platform/suzaku/auto-config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/suzaku/auto-config.in	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,264 @@
+# Main Memory Settings
+define_hex CONFIG_XILINX_ERAM_START 0x80000000
+define_hex CONFIG_XILINX_ERAM_SIZE 0x01000000
+
+# Lmb Memory Settings
+define_hex CONFIG_XILINX_LMB_BASEADDR 0x00000000
+define_hex CONFIG_XILINX_LMB_SIZE 0x00000800
+
+# System Clock Frequency
+define_int CONFIG_XILINX_CPU_CLOCK_FREQ 51609600
+
+# Definitions for MICROBLAZE0
+define_string CONFIG_XILINX_MICROBLAZE0_INSTANCE microblaze0
+define_string CONFIG_XILINX_MICROBLAZE0_FAMILY virtex2p
+define_int CONFIG_XILINX_MICROBLAZE0_D_OPB 1
+define_int CONFIG_XILINX_MICROBLAZE0_D_LMB 1
+define_int CONFIG_XILINX_MICROBLAZE0_I_OPB 1
+define_int CONFIG_XILINX_MICROBLAZE0_I_LMB 1
+define_int CONFIG_XILINX_MICROBLAZE0_USE_BARREL 1
+define_int CONFIG_XILINX_MICROBLAZE0_USE_DIV 1
+define_int CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR 0
+define_int CONFIG_XILINX_MICROBLAZE0_DEBUG_ENABLED 1
+define_int CONFIG_XILINX_MICROBLAZE0_NUMBER_OF_PBRK 4
+define_int CONFIG_XILINX_MICROBLAZE0_NUMBER_OF_RD_ADDR_BRK 1
+define_int CONFIG_XILINX_MICROBLAZE0_NUMBER_OF_WR_ADDR_BRK 1
+define_int CONFIG_XILINX_MICROBLAZE0_INTERRUPT_IS_EDGE 0
+define_int CONFIG_XILINX_MICROBLAZE0_EDGE_IS_POSITIVE 1
+define_hex CONFIG_XILINX_MICROBLAZE0_ICACHE_BASEADDR 0x80000000
+define_hex CONFIG_XILINX_MICROBLAZE0_ICACHE_HIGHADDR 0x80FFFFFF
+define_int CONFIG_XILINX_MICROBLAZE0_USE_ICACHE 1
+define_int CONFIG_XILINX_MICROBLAZE0_ALLOW_ICACHE_WR 1
+define_int CONFIG_XILINX_MICROBLAZE0_ADDR_TAG_BITS 11
+define_int CONFIG_XILINX_MICROBLAZE0_CACHE_BYTE_SIZE 8192
+define_hex CONFIG_XILINX_MICROBLAZE0_DCACHE_BASEADDR 0x80000000
+define_hex CONFIG_XILINX_MICROBLAZE0_DCACHE_HIGHADDR 0x81FFFFFF
+define_int CONFIG_XILINX_MICROBLAZE0_USE_DCACHE 0
+define_int CONFIG_XILINX_MICROBLAZE0_ALLOW_DCACHE_WR 1
+define_int CONFIG_XILINX_MICROBLAZE0_DCACHE_ADDR_TAG 11
+define_int CONFIG_XILINX_MICROBLAZE0_DCACHE_BYTE_SIZE 16384
+define_string CONFIG_XILINX_MICROBLAZE0_HW_VER 2.10.a
+
+# Definitions for LMB_BRAM_IF_CNTLR_0
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_INSTANCE dlmbcntlr
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_BASEADDR 0x00000000
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_HIGHADDR 0x00001FFF
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_MASK 0x80000000
+define_int CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_LMB_AWIDTH 32
+define_int CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_LMB_DWIDTH 32
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_INSTANCE dlmbcntlr
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_HW_VER 1.00.b
+
+# Definitions for LMB_BRAM_IF_CNTLR_1
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_INSTANCE ilmbcntlr
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_BASEADDR 0x00000000
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_HIGHADDR 0x00001FFF
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_MASK 0x80000000
+define_int CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_LMB_AWIDTH 32
+define_int CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_LMB_DWIDTH 32
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_INSTANCE ilmbcntlr
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_HW_VER 1.00.b
+
+# No. of instances for LMB_BRAM_IF_CNTLR
+define_int CONFIG_XILINX_LMB_BRAM_IF_CNTLR_NUM_INSTANCES 2
+
+# Definitions for EMC_0
+define_string CONFIG_XILINX_EMC_0_INSTANCE sramflash
+define_string CONFIG_XILINX_EMC_0_NUM_BANKS_MEM 2
+define_string CONFIG_XILINX_EMC_0_INCLUDE_NEGEDGE_IOREGS 0
+define_hex CONFIG_XILINX_EMC_0_BASEADDR 0xFFFF0000
+define_hex CONFIG_XILINX_EMC_0_HIGHADDR 0xFFFF01FF
+define_hex CONFIG_XILINX_EMC_0_MEM0_BASEADDR 0xFFE00000
+define_hex CONFIG_XILINX_EMC_0_MEM0_HIGHADDR 0xFFEFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM1_BASEADDR 0xFF000000
+define_hex CONFIG_XILINX_EMC_0_MEM1_HIGHADDR 0xFF7FFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM2_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM2_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_EMC_0_MEM3_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM3_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_EMC_0_MEM4_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM4_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_EMC_0_MEM5_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM5_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_EMC_0_MEM6_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM6_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_EMC_0_MEM7_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM7_HIGHADDR 0x00000000
+define_int CONFIG_XILINX_EMC_0_MEM0_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM1_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM2_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM3_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM4_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM5_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM6_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM7_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MAX_MEM_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_0 0
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_1 0
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_2 1
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_3 1
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_4 1
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_5 1
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_6 1
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_7 1
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_0 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_0 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_0 150000
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_0 55000
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_0 70000
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_0 150000
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_0 55000
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_0 15000
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_0 35000
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_1 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_1 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_1 150000
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_1 55000
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_1 70000
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_1 150000
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_1 55000
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_1 15000
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_1 35000
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_2 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_2 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_2 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_2 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_2 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_2 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_2 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_2 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_2 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_3 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_3 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_3 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_3 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_3 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_3 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_3 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_3 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_3 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_4 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_4 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_4 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_4 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_4 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_4 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_4 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_4 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_4 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_5 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_5 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_5 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_5 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_5 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_5 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_5 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_5 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_5 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_6 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_6 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_6 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_6 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_6 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_6 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_6 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_6 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_6 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_7 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_7 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_7 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_7 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_7 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_7 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_7 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_7 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_7 0
+define_int CONFIG_XILINX_EMC_0_OPB_DWIDTH 32
+define_int CONFIG_XILINX_EMC_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_EMC_0_OPB_CLK_PERIOD_PS 15000
+define_int CONFIG_XILINX_EMC_0_DEV_BLK_ID 1
+define_int CONFIG_XILINX_EMC_0_DEV_MIR_ENABLE 1
+define_string CONFIG_XILINX_EMC_0_INSTANCE sramflash
+define_string CONFIG_XILINX_EMC_0_HW_VER 1.10.b
+
+# No. of instances for EMC
+define_int CONFIG_XILINX_EMC_NUM_INSTANCES 1
+
+# Definitions for UARTLITE_0
+define_string CONFIG_XILINX_UARTLITE_0_INSTANCE consoleuart
+define_hex CONFIG_XILINX_UARTLITE_0_BASEADDR 0xFFFF2000
+define_hex CONFIG_XILINX_UARTLITE_0_HIGHADDR 0xFFFF20FF
+define_int CONFIG_XILINX_UARTLITE_0_OPB_DWIDTH 32
+define_int CONFIG_XILINX_UARTLITE_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_UARTLITE_0_DATA_BITS 8
+define_int CONFIG_XILINX_UARTLITE_0_CLK_FREQ 51609600
+define_int CONFIG_XILINX_UARTLITE_0_BAUDRATE 115200
+define_int CONFIG_XILINX_UARTLITE_0_USE_PARITY 0
+define_int CONFIG_XILINX_UARTLITE_0_ODD_PARITY 0
+define_string CONFIG_XILINX_UARTLITE_0_INSTANCE consoleuart
+define_string CONFIG_XILINX_UARTLITE_0_HW_VER 1.00.b
+define_int CONFIG_XILINX_UARTLITE_0_IRQ 1
+
+# No. of instances for UARTLITE
+define_int CONFIG_XILINX_UARTLITE_NUM_INSTANCES 1
+
+# Definitions for INTC_0
+define_string CONFIG_XILINX_INTC_0_INSTANCE systemintc
+define_string CONFIG_XILINX_INTC_0_FAMILY virtex2p
+define_int CONFIG_XILINX_INTC_0_Y 0
+define_int CONFIG_XILINX_INTC_0_X 0
+define_string CONFIG_XILINX_INTC_0_U_SET intc
+define_int CONFIG_XILINX_INTC_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_INTC_0_OPB_DWIDTH 32
+define_hex CONFIG_XILINX_INTC_0_BASEADDR 0xFFFF3000
+define_hex CONFIG_XILINX_INTC_0_HIGHADDR 0xFFFF30FF
+define_int CONFIG_XILINX_INTC_0_NUM_INTR_INPUTS 3
+define_hex CONFIG_XILINX_INTC_0_KIND_OF_INTR 0x00000006
+define_hex CONFIG_XILINX_INTC_0_KIND_OF_EDGE 0x00000006
+define_hex CONFIG_XILINX_INTC_0_KIND_OF_LVL 0x00000009
+define_int CONFIG_XILINX_INTC_0_HAS_IPR 1
+define_int CONFIG_XILINX_INTC_0_HAS_SIE 1
+define_int CONFIG_XILINX_INTC_0_HAS_CIE 1
+define_int CONFIG_XILINX_INTC_0_HAS_IVR 1
+define_int CONFIG_XILINX_INTC_0_IRQ_IS_LEVEL 1
+define_int CONFIG_XILINX_INTC_0_IRQ_ACTIVE 1
+define_string CONFIG_XILINX_INTC_0_INSTANCE systemintc
+define_string CONFIG_XILINX_INTC_0_HW_VER 1.00.c
+
+# No. of instances for INTC
+define_int CONFIG_XILINX_INTC_NUM_INSTANCES 1
+
+# Definitions for TIMER_0
+define_string CONFIG_XILINX_TIMER_0_INSTANCE systemtimer
+define_string CONFIG_XILINX_TIMER_0_FAMILY spartan3
+define_int CONFIG_XILINX_TIMER_0_COUNT_WIDTH 32
+define_int CONFIG_XILINX_TIMER_0_ONE_TIMER_ONLY 0
+define_int CONFIG_XILINX_TIMER_0_TRIG0_ASSERT 1
+define_int CONFIG_XILINX_TIMER_0_TRIG1_ASSERT 1
+define_int CONFIG_XILINX_TIMER_0_GEN0_ASSERT 1
+define_int CONFIG_XILINX_TIMER_0_GEN1_ASSERT 1
+define_int CONFIG_XILINX_TIMER_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_TIMER_0_OPB_DWIDTH 32
+define_hex CONFIG_XILINX_TIMER_0_BASEADDR 0xFFFF1000
+define_hex CONFIG_XILINX_TIMER_0_HIGHADDR 0xFFFF10FF
+define_string CONFIG_XILINX_TIMER_0_INSTANCE systemtimer
+define_string CONFIG_XILINX_TIMER_0_HW_VER 1.00.b
+define_int CONFIG_XILINX_TIMER_0_IRQ 0
+
+# No. of instances for TIMER
+define_int CONFIG_XILINX_TIMER_NUM_INSTANCES 1
+
+# Definitions for GPIO_0
+define_string CONFIG_XILINX_GPIO_0_INSTANCE systemgpio
+define_hex CONFIG_XILINX_GPIO_0_BASEADDR 0xFFFFA000
+define_hex CONFIG_XILINX_GPIO_0_HIGHADDR 0xFFFFA0FF
+define_int CONFIG_XILINX_GPIO_0_OPB_DWIDTH 32
+define_int CONFIG_XILINX_GPIO_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_GPIO_0_GPIO_WIDTH 24
+define_int CONFIG_XILINX_GPIO_0_ALL_INPUTS 0
+define_string CONFIG_XILINX_GPIO_0_INSTANCE systemgpio
+define_string CONFIG_XILINX_GPIO_0_HW_VER 1.00.a
+
+# No. of instances for GPIO
+define_int CONFIG_XILINX_GPIO_NUM_INSTANCES 1
+
diff -urN linux-2.4.29/arch/microblaze/platform/suzaku/head_ram.S linux-2.4.29-uc1/arch/microblaze/platform/suzaku/head_ram.S
--- linux-2.4.29/arch/microblaze/platform/suzaku/head_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/suzaku/head_ram.S	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,104 @@
+/*
+ * arch/microblaze/kernel/head.S -- Lowest-level startup code
+ *
+ *  Copyright (C) 2004       Brett Boren <borenb@eng.uah.edu>
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *                           based upon v850 version
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <asm/clinkage.h>
+#include <asm/current.h>
+#include <asm/entry.h>
+#include <asm/irq.h>
+
+
+/* Make a slightly more convenient alias for C_SYMBOL_NAME.  */
+#define CSYM	C_SYMBOL_NAME 
+
+.global CSYM(_ramstart)
+
+	.data
+CSYM(_ramstart):
+	.long 0
+
+	.text
+
+	// Define `mach_early_init' as a weak symbol
+	.global	CSYM(mach_early_init)
+	.weak	CSYM(mach_early_init)
+
+C_ENTRY(start):
+	// Make sure interrupts are turned off, just in case
+	mfs	r1, rmsr
+	andi	r1, r1, ~2
+	mts	rmsr, r1
+
+	// Set Small Data Anchors
+	la	r13, r0, _KERNEL_SDA_BASE_
+	la	r2, r0, _KERNEL_SDA2_BASE_
+
+	// Initialise the stack pointer
+	// Initial stack is shrunk by 4 bytes (1 word) to permit use of
+	// standard sp->task ptr conversion functions later on
+	la	r1, r0, CSYM(init_task_union)+KERNEL_STACK_SIZE-4;
+
+#ifdef CONFIG_MBVANILLA_CMDLINE
+	// BAB 1/7/04 - Copy off cmdline pointer passed in by bootloader
+	swi	r5, r0, CSYM(bootloader_buf_addr)
+#endif	
+	// See if there's a platform-specific early-initialization routine
+	// defined; it's a weak symbol, so it will have an address of zero if
+	// there's not.
+	la	r6, r0, CSYM(mach_early_init)
+	beqi	r6, 3f
+
+	// There is one, so call it.  If this function is written in C, it
+	// should be very careful -- the stack pointer is valid, but very
+	// little else is (e.g., bss is not zeroed yet).
+	brald	r15, r6			// do call
+	nop				// delay slot
+
+3:
+	// Kernel stack pointer save location
+	swi	r1, r0, KSP
+
+	// Assert that we're in `kernel mode'
+	addi	r19, r0, 1
+	swi	r19, r0, KM
+
+#if 0
+	// Zero bss area, since we can't rely upon any loader to do so
+	addi	r5, r0, CSYM(__bss_start)
+	add	r6, r0, r0
+	addi	r7, r0, CSYM(__bss_end)
+	rsub	r7, r5, r7
+	bralid	r15, CSYM(memset)
+	nop
+
+	// Zero sbss area, since we can't rely upon any loader to do so
+	addi	r5, r0, CSYM(_ssbss)
+	add	r6, r0, r0
+	addi	r7, r0, CSYM(_esbss)
+	rsub	r7, r5, r7
+	bralid	r15, CSYM(memset)
+	nop
+#endif
+
+	// initialise the current task ptr.  This must happen after
+	// we zero BSS, SBSS etc, because "current" is a global C symbol
+	GET_CURRENT_TASK(CURRENT_TASK);
+
+	// Start Linux kernel.
+	// If this call ever returns (which it shouldn't),
+	// set the link pointer to somewhere harmless
+	addi	r15, r0, CSYM(machine_halt)
+	brai	CSYM(start_kernel)
+END(start)
diff -urN linux-2.4.29/arch/microblaze/platform/suzaku/intv.S linux-2.4.29-uc1/arch/microblaze/platform/suzaku/intv.S
--- linux-2.4.29/arch/microblaze/platform/suzaku/intv.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/suzaku/intv.S	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ * arch/microblaze/kernel/intv.S -- Interrupt vectors
+ *
+ *  Copyright (C) 2003	     John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by John Williams <jwilliams@itee.uq.edu.au>
+ */
+
+#include <asm/clinkage.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/entry.h>
+
+	/* These are compiled and loaded into high memory, then
+	   copied into place in mach_early_setup */
+	.section	.intv.common, "ax"
+	.org	0x0
+	brai	C_SYMBOL_NAME(start);	// Kernel entry point (0x00)
+
+	.org	0x08
+	brai	C_SYMBOL_NAME(trap);	// Exception handler  (0x08)
+
+	.org	0x10
+	brai	C_SYMBOL_NAME(irq);	// Interrupt handler  (0x10)
+
+	.org	0x18
+	brai	C_SYMBOL_NAME(dbtrap);	// debug trap handler (0x18)
diff -urN linux-2.4.29/arch/microblaze/platform/suzaku/machine.c linux-2.4.29-uc1/arch/microblaze/platform/suzaku/machine.c
--- linux-2.4.29/arch/microblaze/platform/suzaku/machine.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/suzaku/machine.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,205 @@
+/*
+ * arch/microblaze/platform/suzaku/machine.c -- platform dependant code
+ *
+ *  Copyright (C) 2004  Atmark Techno, Inc. <yashi@atmark-techno.com>
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/irq.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/param.h>
+#include <asm/cache.h>
+#include <asm/microblaze_timer.h>
+#include <asm/microblaze_intc.h>
+#include <asm/pgalloc.h>
+
+/* Called with each timer tick, if non-zero.  */
+void (*mach_tick)(void) = 0;
+
+/* for 2.6, include asm-generic/sections.h */
+extern char __bss_start[], __bss_stop[];
+
+void mach_heartbeat(unsigned int value)
+{
+}
+
+/* mach_gettimeoffset returns the number of microseconds elapsed since the
+   start of the current tick */
+unsigned long mach_gettimeoffset(void)
+{
+	unsigned long tctr=timer_get_time(CONFIG_XILINX_TIMER_0_BASEADDR,0);
+	unsigned long tcmp=timer_get_compare(CONFIG_XILINX_TIMER_0_BASEADDR,0);
+	unsigned long offset;
+
+	/*
+	 * Timer used in count up mode, so subtract load value from
+	 * counter register to get elapsed ticks */
+	offset = (tctr-tcmp)/(CONFIG_XILINX_CPU_CLOCK_FREQ/1000000);
+
+	/*
+	 * If we are still in the first half of the upcount and a
+	 * timer interupt is pending, then add on a tick's worth of time.
+	 */
+
+	if (((offset * 2) < (1000000/HZ)) && 
+		(timer_get_csr(CONFIG_XILINX_TIMER_0_BASEADDR,0)&TIMER_INTERRUPT))
+	{
+		offset += 1000000/HZ;
+	}
+
+	return offset;
+}
+
+/* Bytes to words, round up */
+#define get_romfs_len(addr) (((unsigned int *)(addr))[2])
+
+#define ROMFS_LOCATION (__bss_start)
+#define MOVE_ROMFS(dst, src, len) ({memmove(__bss_stop,__bss_start,len);})
+
+/* mach_early_init() is called very early, after the kernel stack and SDA 
+   pointers are configured, but before BSS/SBSS are zeroed etc.  Be careful 
+   what you do in here.  The bss and sbss sections are zeroed in here */
+void __init mach_early_init (void)
+{
+	unsigned int *src, *dst;
+	unsigned int len;
+
+	extern unsigned char _ssbss, _esbss;
+	extern unsigned int _intv_load_end, _intv_load_start;
+	extern unsigned long _ramstart;
+
+	/* Copy interrupt vectors from high memory down to where
+	   they belong. */
+	dst = (unsigned int *)0x0;		
+	src = (unsigned int *)&_intv_load_start;
+
+#if 1	/* JW don't overwrite reset vector */
+	src++;
+	src++;
+	dst++;
+	dst++;
+#endif
+	do {
+		*(dst++) = *(src++);
+	} while (src < &_intv_load_end);
+
+        _ramstart = (unsigned long)__bss_stop;
+
+#ifdef CONFIG_MTD_UCLINUX
+        /* if CONFIG_MTD_UCLINUX is defined, assume ROMFS is at the
+         * end of kernel, which is ROMFS_LOCATION defined above. */
+	len = get_romfs_len(ROMFS_LOCATION);
+        _ramstart += len;
+
+ /* Use memmove to handle likely case of memory overlap */
+	MOVE_ROMFS(__bss_stop,__bss_start,len);
+#endif
+
+	/* Zero the BSS and SBSS sections */
+	memset(__bss_start,0,__bss_stop-__bss_start);
+	memset(&_ssbss,0,&_esbss-&_ssbss);
+
+}
+
+void __init mach_reserve_bootmem(void)
+{
+}
+
+void __init mach_setup (char **cmdline)
+{
+	/* Enable the instruction and data caches (if present) */
+	#if CONFIG_XILINX_MICROBLAZE0_USE_ICACHE==1
+	__flush_icache_all();
+	__enable_icache();
+	#endif
+
+	#if CONFIG_XILINX_MICROBLAZE0_USE_DCACHE==1
+	__flush_dcache_all();
+	__enable_dcache();
+	#endif
+
+	printk (KERN_INFO "CPU: MICROBLAZE\n");
+
+	/* this is now called from drivers/tty_io.c, as it should be */
+	/* xmbrs_console_init();  */
+	
+	/* 
+	 * Enable master control on interrupt controller.  Note
+         * this does not enable interrupts in the processor, nor 
+	 * does it enable individual IRQs on the controller.  Just
+         * initialises the intc in preparation for these things */
+	microblaze_intc_master_enable();
+}
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* Initialise timer */
+	microblaze_timer_configure(0,HZ);
+
+	/* And install timer interrupt handler at appropriate vector */
+
+	/* Timer is always attached to interrupt 0 (highest priority) */
+	/* Note we use setup_irq rather than request_irq */
+	setup_irq (CONFIG_XILINX_TIMER_0_IRQ, timer_action);
+}
+
+void mach_gettimeofday (struct timeval *tv)
+{
+	tv->tv_sec = 0;
+	tv->tv_usec = 0;
+}
+
+void machine_halt (void) __attribute__ ((noreturn));
+void machine_halt (void)
+{
+	for (;;) {
+		/* Following code should disable interrupts */
+		asm ("nop; nop; nop; nop; nop");
+	}
+}
+
+void machine_restart (char *__unused)
+{
+        /* wait till "Restarting system\n" is out of uart fifo */
+        mdelay(20);
+        writel(MICROBLAZE_SYSREG_RECONFIGURE, MICROBLAZE_SYSREG_BASE_ADDR);
+        machine_halt();
+}
+
+void machine_power_off (void)
+{
+	machine_halt ();
+}
+
+
+/* Interrupts */
+
+/* Data to initialise interrupt controller functionality */
+struct microblaze_intc_irq_init irq_inits[] = {
+	/* Name, base, num, priority (unused in microblaze) */
+	{ "XINTC", 0, NUM_MACH_IRQS,	7 },
+	{ 0 }
+};
+#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
+
+struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
+
+/* Initialize interrupts.  */
+void __init mach_init_irqs (void)
+{
+	microblaze_intc_init_irq_types (irq_inits, hw_itypes);
+}
diff -urN linux-2.4.29/arch/microblaze/platform/suzaku/Makefile linux-2.4.29-uc1/arch/microblaze/platform/suzaku/Makefile
--- linux-2.4.29/arch/microblaze/platform/suzaku/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/suzaku/Makefile	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,54 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+#
+# re-use any microblaze files that we can.  Perhaps we should create
+# a microblaze directory for shared files ?
+
+VPATH := $(VPATH):../../kernel
+
+ifdef CONFIG_FULLDEBUG
+	AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+#
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# AFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+# Work out special CPU flags needed
+
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: head_$(MODEL).o entry.o platform.o
+
+O_TARGET := platform.o
+
+obj-y := intv.o entry.o machine.o setup.o
+
+head_$(MODEL).o: head_$(MODEL).S
+
+entry.o: entry.S microblaze_defs.h
+
+microblaze_defs.h: ../../kernel/microblaze_defs.c ../../kernel/microblaze_defs.head
+	rm -f microblaze_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/microblaze_defs.c
+	cp ../../kernel/microblaze_defs.head microblaze_defs.h
+	grep '^#define' microblaze_defs.s >> microblaze_defs.h
+	rm microblaze_defs.s
+-include microblaze_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/microblaze/platform/suzaku/ram.ld.in linux-2.4.29-uc1/arch/microblaze/platform/suzaku/ram.ld.in
--- linux-2.4.29/arch/microblaze/platform/suzaku/ram.ld.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/suzaku/ram.ld.in	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,151 @@
+/* Simple development memory map for Xilinx Microblaze target.
+   Assume that only the interrupt vectors and the small local data
+   area go in LMB RAM, and that some mythical bootloader will 
+   put the kernel into OPB RAM starting from 0xffe00000
+*/
+
+/* Get all the autoconfigure addresses etc */
+#include <linux/config.h>
+#include <asm/clinkage.h>
+  
+MEMORY {
+	/* 2K of LMB RAM */
+	LMB  : ORIGIN = CONFIG_XILINX_LMB_BASEADDR, LENGTH = CONFIG_XILINX_LMB_SIZE
+
+	/* 16 MB of OBP SDRAM */
+	OPB  : ORIGIN = CONFIG_XILINX_ERAM_START, LENGTH = CONFIG_XILINX_ERAM_SIZE
+}
+
+SECTIONS {
+	.text : {
+		/* "untouchable" memory space starts here */
+	        _kram_start = . ;
+	
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+		*(.modinfo)
+		. = ALIGN (0x4) ;
+			*(.kstrtab)
+		. = ALIGN (16) ;	/* Exception table.  */
+		__start___ex_table = . ;
+			*(_ex_table)
+		__stop___ex_table = . ;
+
+		__start___ksymtab = . ; /* All kernel symbols */
+		*(__ksymtab)
+		__stop___ksymtab = . ;
+
+                __start___kallsyms = .; /* All kernel symbols           */
+                        *(__kallsyms)
+                __stop___kallsyms = .;
+
+
+		. = ALIGN (4) ;
+		_etext = . ;
+	} > OPB
+
+	/* Copies of interrupt vector space. They get copied from here into the 
+  	   proper location by mach_early_setup() */ 
+	.intv : {
+		_intv_load_start = . ;
+	        	*(.intv.reset)	/* Reset vector */
+			*(.intv.common) /* Vectors common to all microblaze proc. */
+			*(.intv.mach)   /* Machine-specific int. vectors.  */
+		_intv_load_end = . ;
+	} > OPB
+
+
+	/* sdata2 section can go anywhere, but must be word aligned
+	   and SDA2_BASE must point to the middle of it */
+	.sdata2 : {
+		_ssrw = .;
+		. = ALIGN(0x8);
+		*(.sdata2)
+	. = ALIGN(8);
+	_essrw = .;
+	_ssrw_size = _essrw - _ssrw;
+	_KERNEL_SDA2_BASE_ = _ssrw + (_ssrw_size / 2);
+	} > OPB
+
+
+	.data ALIGN (0x4) : {
+
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN (16) ;
+		*(.data.cacheline_aligned)
+		. = ALIGN (0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN (0x2000) ;
+		_edata = . ;
+	
+		/* Reserve some low RAM for r0 based memory references */
+		. = ALIGN(4) ;
+		C_SYMBOL_NAME(r0_ram) = . ;
+		. = . + 32 ;	/* 32 bytes should be enough */
+	} > OPB
+
+	/* Under the microblaze ABI, .sdata and .sbss must be contiguous */
+	. = ALIGN(8);
+	.sdata : {
+		_ssro = .;
+		*(.sdata)
+	} > OPB
+
+	. = ALIGN(4);
+	.sbss : {
+		_ssbss = . ;
+		_sbss_start = .;
+		*(.sbss)
+		_ssbss_end = .;
+		_esbss = . ;
+
+	. = ALIGN(8);
+	_essro = .;
+	_ssro_size = _essro - _ssro;
+	_KERNEL_SDA_BASE_ = _ssro + (_ssro_size / 2);
+	
+ 	} > OPB
+ 
+	/* Place init and bootmap sections last to reduce fragmentation 
+	   when they are freed */
+ 	.init ALIGN (4096) : {
+		_init_start = . ;
+ 		__init_begin = . ;
+ 			*(.text.init)
+ 			*(.data.init)
+ 		. = ALIGN (16) ;
+ 		__setup_start = . ;
+ 			*(.setup.init)
+ 		__setup_end = . ;
+ 		__initcall_start = . ;
+ 			*(.initcall.init)
+ 		. = ALIGN (4) ;
+ 		__initcall_end = . ;
+		. = ALIGN(4096) ;
+ 		__init_end = . ;
+ 		_init_end = . ;
+ 		/* Untouchable kernel ram ends here */
+ 		_kram_end = . ;
+ 	} > OPB
+ 
+	/* .bss must go last, to be compatible with the way the romfs is handled */
+	.bss ALIGN (0x4) : {
+		_sbss = . ;
+		__bss_start = . ;
+			*(.bss*)
+			*(COMMON)
+		. = ALIGN (4) ;
+		__bss_stop = . ;
+		_ebss = . ;
+		_end = . ;
+ 	} > OPB
+ 
+}
+
diff -urN linux-2.4.29/arch/microblaze/platform/suzaku/Rules.make linux-2.4.29-uc1/arch/microblaze/platform/suzaku/Rules.make
--- linux-2.4.29/arch/microblaze/platform/suzaku/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/suzaku/Rules.make	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,6 @@
+# Platform specific rules.make
+
+# Nothing special, just use the standard rules
+include arch/microblaze/platform/Rules.make
+
+
diff -urN linux-2.4.29/arch/microblaze/platform/suzaku/setup.c linux-2.4.29-uc1/arch/microblaze/platform/suzaku/setup.c
--- linux-2.4.29/arch/microblaze/platform/suzaku/setup.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/suzaku/setup.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,123 @@
+/*
+ * arch/microblaze/platform/suzaku/setup.c -- Arch-dependent initialization functions
+ *
+ *  Copyright (C) 2004       Atmark Techno, Inc. <yashi@atmark-techno.com>
+ *  Copyright (C) 2004	     Brett Boren <borenb@eng.uah.edu>
+ *  Copyright (C) 2003	     John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams <jwilliams@itee.uq.edu.au>
+ * Microblaze command line param handling by Brett Boren <borenb@eng.uah.edu>
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+#include <linux/reboot.h>
+#include <linux/personality.h>
+
+#include <asm/irq.h>
+
+#include "asm/setup.h"
+
+static struct meminfo meminfo __initdata= { 0, };
+
+extern void bootmem_init(struct meminfo *);
+extern void paging_init(struct meminfo *);
+extern void mach_setup(char **);
+extern void mach_init_irqs(void);
+extern unsigned long _ramstart;
+
+#ifndef CONFIG_REGISTER_TASK_PTR
+struct task_struct *current;
+#endif
+
+/* These symbols are all defined in the linker map to delineate various
+   statically allocated regions of memory.  */
+
+// extern char _intv_start, _intv_end;
+/* `kram' is only used if the kernel uses part of normal user RAM.  */
+extern char _kram_start __attribute__ ((__weak__));
+extern char _kram_end __attribute__ ((__weak__));
+
+/* erase following when we port to 2.6, include <asm/sections.h> instead */
+extern char _text[], _stext[], _etext[];
+extern char _data[], _sdata[], _edata[];
+
+char saved_command_line[512];
+#ifdef CONFIG_MBVANILLA_CMDLINE
+/* This pointer gets set with the address of a buffer 
+   allocated (or specified) by the bootloader 
+*/
+/* 
+   BAB 1/8/2004 this initialization is needed to keep bootloader_buf_addr
+   from being placed in bss and getting cleared in mach_early_setup 
+*/
+void *bootloader_buf_addr = 0xFFFFFFFF;
+#else
+char command_line[512];
+#endif
+
+void __init setup_arch (char **cmdline)
+{
+#ifdef CONFIG_MBVANILLA_CMDLINE
+	/* 
+	  If a cmdline has come from the bootlaoder, then this variable
+	  will have been initialised with the addr of the cmdline buffer.
+	  Just point the kernel there. 
+	*/
+	*cmdline = bootloader_buf_addr;
+
+	/* Keep a copy of command line */
+	memcpy (saved_command_line, *cmdline, sizeof saved_command_line);
+#else
+	*cmdline = command_line;
+
+	/* Keep a copy of command line */
+	memcpy (saved_command_line, command_line, sizeof saved_command_line);
+#endif
+	saved_command_line[sizeof saved_command_line - 1] = '\0';
+
+	console_verbose ();
+
+	init_mm.start_code	= (unsigned long) &_stext;
+	init_mm.end_code	= (unsigned long) &_etext;
+	init_mm.end_data	= (unsigned long) _ramstart;
+	init_mm.brk		= (unsigned long) _ramstart;
+#if 0	
+	init_mm.end_data = (unsigned long) &_edata;
+	init_mm.brk = (unsigned long) &_kram_end;
+#endif
+
+	/* Provide default meminfo configuration */
+	if(meminfo.nr_banks == 0)
+	{
+		meminfo.nr_banks 	= 1;
+		meminfo.bank[0].start 	= CONFIG_XILINX_ERAM_START;
+		meminfo.bank[0].size	= CONFIG_XILINX_ERAM_SIZE;
+	}
+
+	/* ... and tell the kernel about it.  */
+	bootmem_init(&meminfo);
+	paging_init (&meminfo);
+
+	/* do machine-specific setups.  */
+	mach_setup (cmdline);
+}
+
+void __init trap_init (void)
+{
+}
+
+void __init init_IRQ (void)
+{
+	init_irq_handlers (0, NUM_MACH_IRQS, 0);
+	mach_init_irqs ();
+}
diff -urN linux-2.4.29/arch/microblaze/platform/uclinux-auto/auto-config.in linux-2.4.29-uc1/arch/microblaze/platform/uclinux-auto/auto-config.in
--- linux-2.4.29/arch/microblaze/platform/uclinux-auto/auto-config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/uclinux-auto/auto-config.in	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,363 @@
+
+# Main Memory Settings
+define_hex CONFIG_XILINX_ERAM_START 0x80000000
+define_hex CONFIG_XILINX_ERAM_SIZE 0x02000000
+
+# Lmb Memory Settings
+define_hex CONFIG_XILINX_LMB_START 0x00000000
+define_hex CONFIG_XILINX_LMB_SIZE 0x00004000
+
+# System Clock Frequency
+define_int CONFIG_XILINX_CPU_CLOCK_FREQ 66666667
+
+# Definitions for MICROBLAZE0
+define_string CONFIG_XILINX_MICROBLAZE0_INSTANCE microblaze0
+define_string CONFIG_XILINX_MICROBLAZE0_FAMILY virtex2p
+define_string CONFIG_XILINX_MICROBLAZE0_INSTANCE microblaze0
+define_int CONFIG_XILINX_MICROBLAZE0_D_OPB 1
+define_int CONFIG_XILINX_MICROBLAZE0_D_LMB 1
+define_int CONFIG_XILINX_MICROBLAZE0_I_OPB 1
+define_int CONFIG_XILINX_MICROBLAZE0_I_LMB 1
+define_int CONFIG_XILINX_MICROBLAZE0_USE_BARREL 1
+define_int CONFIG_XILINX_MICROBLAZE0_USE_DIV 1
+define_int CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR 0
+define_int CONFIG_XILINX_MICROBLAZE0_DEBUG_ENABLED 1
+define_int CONFIG_XILINX_MICROBLAZE0_NUMBER_OF_PBRK 4
+define_int CONFIG_XILINX_MICROBLAZE0_NUMBER_OF_RD_ADDR_BRK 1
+define_int CONFIG_XILINX_MICROBLAZE0_NUMBER_OF_WR_ADDR_BRK 1
+define_int CONFIG_XILINX_MICROBLAZE0_INTERRUPT_IS_EDGE 0
+define_int CONFIG_XILINX_MICROBLAZE0_EDGE_IS_POSITIVE 1
+define_int CONFIG_XILINX_MICROBLAZE0_FSL_LINKS 1
+define_int CONFIG_XILINX_MICROBLAZE0_FSL_DATA_SIZE 32
+define_hex CONFIG_XILINX_MICROBLAZE0_ICACHE_BASEADDR 0x80000000
+define_hex CONFIG_XILINX_MICROBLAZE0_ICACHE_HIGHADDR 0x81FFFFFF
+define_int CONFIG_XILINX_MICROBLAZE0_USE_ICACHE 1
+define_int CONFIG_XILINX_MICROBLAZE0_ALLOW_ICACHE_WR 1
+define_int CONFIG_XILINX_MICROBLAZE0_ADDR_TAG_BITS 11
+define_int CONFIG_XILINX_MICROBLAZE0_CACHE_BYTE_SIZE 16384
+define_hex CONFIG_XILINX_MICROBLAZE0_DCACHE_BASEADDR 0x80000000
+define_hex CONFIG_XILINX_MICROBLAZE0_DCACHE_HIGHADDR 0x81FFFFFF
+define_int CONFIG_XILINX_MICROBLAZE0_USE_DCACHE 1
+define_int CONFIG_XILINX_MICROBLAZE0_ALLOW_DCACHE_WR 1
+define_int CONFIG_XILINX_MICROBLAZE0_DCACHE_ADDR_TAG 11
+define_int CONFIG_XILINX_MICROBLAZE0_DCACHE_BYTE_SIZE 16384
+define_string CONFIG_XILINX_MICROBLAZE0_INSTANCE microblaze0
+define_string CONFIG_XILINX_MICROBLAZE0_HW_VER 2.10.a
+
+# Definitions for LMB_BRAM_IF_CNTLR_0
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_INSTANCE dlmbcntlr
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_BASEADDR 0x00000000
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_HIGHADDR 0x00003FFF
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_MASK 0x80000000
+define_int CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_LMB_AWIDTH 32
+define_int CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_LMB_DWIDTH 32
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_INSTANCE dlmbcntlr
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_0_HW_VER 1.00.b
+
+# Definitions for LMB_BRAM_IF_CNTLR_1
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_INSTANCE ilmbcntlr
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_BASEADDR 0x00000000
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_HIGHADDR 0x00003FFF
+define_hex CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_MASK 0x80000000
+define_int CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_LMB_AWIDTH 32
+define_int CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_LMB_DWIDTH 32
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_INSTANCE ilmbcntlr
+define_string CONFIG_XILINX_LMB_BRAM_IF_CNTLR_1_HW_VER 1.00.b
+
+# No. of instances for LMB_BRAM_IF_CNTLR
+define_int CONFIG_XILINX_LMB_BRAM_IF_CNTLR_NUM_INSTANCES 2
+
+# Definitions for MDM_0
+define_string CONFIG_XILINX_MDM_0_INSTANCE debugmodule
+define_hex CONFIG_XILINX_MDM_0_BASEADDR 0xFFFFC000
+define_hex CONFIG_XILINX_MDM_0_HIGHADDR 0xFFFFC0FF
+define_int CONFIG_XILINX_MDM_0_OPB_DWIDTH 32
+define_int CONFIG_XILINX_MDM_0_OPB_AWIDTH 32
+define_string CONFIG_XILINX_MDM_0_FAMILY virtex2p
+define_int CONFIG_XILINX_MDM_0_MB_DBG_PORTS 1
+define_int CONFIG_XILINX_MDM_0_USE_UART 0
+define_int CONFIG_XILINX_MDM_0_UART_WIDTH 8
+define_int CONFIG_XILINX_MDM_0_WRITE_FSL_PORTS 1
+define_string CONFIG_XILINX_MDM_0_INSTANCE debugmodule
+define_string CONFIG_XILINX_MDM_0_HW_VER 2.00.a
+
+# No. of instances for MDM
+define_int CONFIG_XILINX_MDM_NUM_INSTANCES 1
+
+# Definitions for DDR_0
+define_string CONFIG_XILINX_DDR_0_INSTANCE ddrcontroller
+define_hex CONFIG_XILINX_DDR_0_BASEADDR 0x80000000
+define_hex CONFIG_XILINX_DDR_0_HIGHADDR 0x81FFFFFF
+define_int CONFIG_XILINX_DDR_0_OPB_DWIDTH 32
+define_int CONFIG_XILINX_DDR_0_OPB_AWIDTH 32
+define_string CONFIG_XILINX_DDR_0_FAMILY virtex2p
+define_int CONFIG_XILINX_DDR_0_OPB_CLK_PERIOD_PS 15000
+define_int CONFIG_XILINX_DDR_0_INCLUDE_BURST_SUPPORT 0
+define_int CONFIG_XILINX_DDR_0_DQS_PULLUPS 1
+define_int CONFIG_XILINX_DDR_0_REG_DIMM 0
+define_int CONFIG_XILINX_DDR_0_DDR_TMRD 15000
+define_int CONFIG_XILINX_DDR_0_DDR_TWR 15000
+define_int CONFIG_XILINX_DDR_0_DDR_TWTR 1
+define_int CONFIG_XILINX_DDR_0_DDR_TRAS 40000
+define_int CONFIG_XILINX_DDR_0_DDR_TRC 65000
+define_int CONFIG_XILINX_DDR_0_DDR_TRFC 75000
+define_int CONFIG_XILINX_DDR_0_DDR_TRCD 20000
+define_int CONFIG_XILINX_DDR_0_DDR_TRRD 15000
+define_int CONFIG_XILINX_DDR_0_DDR_TREFC 70000000
+define_int CONFIG_XILINX_DDR_0_DDR_TREFI 7800000
+define_int CONFIG_XILINX_DDR_0_DDR_TRP 20000
+define_int CONFIG_XILINX_DDR_0_DDR_CAS_LAT 2
+define_int CONFIG_XILINX_DDR_0_DDR_DWIDTH 16
+define_int CONFIG_XILINX_DDR_0_DDR_AWIDTH 13
+define_int CONFIG_XILINX_DDR_0_DDR_COL_AWIDTH 9
+define_int CONFIG_XILINX_DDR_0_DDR_BANK_AWIDTH 2
+define_string CONFIG_XILINX_DDR_0_INSTANCE ddrcontroller
+define_string CONFIG_XILINX_DDR_0_HW_VER 1.00.b
+
+# No. of instances for DDR
+define_int CONFIG_XILINX_DDR_NUM_INSTANCES 1
+
+# Definitions for EMC_0
+define_string CONFIG_XILINX_EMC_0_INSTANCE sramflash
+define_string CONFIG_XILINX_EMC_0_NUM_BANKS_MEM 2
+define_string CONFIG_XILINX_EMC_0_INCLUDE_NEGEDGE_IOREGS 0
+define_hex CONFIG_XILINX_EMC_0_BASEADDR 0xFFFF0000
+define_hex CONFIG_XILINX_EMC_0_HIGHADDR 0xFFFF01FF
+define_hex CONFIG_XILINX_EMC_0_MEM0_BASEADDR 0xFFE00000
+define_hex CONFIG_XILINX_EMC_0_MEM0_HIGHADDR 0xFFEFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM1_BASEADDR 0xFF000000
+define_hex CONFIG_XILINX_EMC_0_MEM1_HIGHADDR 0xFF7FFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM2_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM2_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_EMC_0_MEM3_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM3_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_EMC_0_MEM4_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM4_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_EMC_0_MEM5_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM5_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_EMC_0_MEM6_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM6_HIGHADDR 0x00000000
+define_hex CONFIG_XILINX_EMC_0_MEM7_BASEADDR 0xFFFFFFFF
+define_hex CONFIG_XILINX_EMC_0_MEM7_HIGHADDR 0x00000000
+define_int CONFIG_XILINX_EMC_0_MEM0_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM1_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM2_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM3_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM4_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM5_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM6_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MEM7_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_MAX_MEM_WIDTH 32
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_0 0
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_1 0
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_2 1
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_3 1
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_4 1
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_5 1
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_6 1
+define_int CONFIG_XILINX_EMC_0_INCLUDE_DATAWIDTH_MATCHING_7 1
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_0 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_0 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_0 150000
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_0 55000
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_0 70000
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_0 150000
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_0 55000
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_0 15000
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_0 35000
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_1 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_1 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_1 150000
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_1 55000
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_1 70000
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_1 150000
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_1 55000
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_1 15000
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_1 35000
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_2 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_2 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_2 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_2 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_2 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_2 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_2 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_2 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_2 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_3 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_3 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_3 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_3 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_3 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_3 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_3 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_3 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_3 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_4 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_4 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_4 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_4 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_4 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_4 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_4 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_4 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_4 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_5 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_5 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_5 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_5 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_5 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_5 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_5 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_5 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_5 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_6 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_6 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_6 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_6 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_6 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_6 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_6 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_6 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_6 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_MEM_7 0
+define_int CONFIG_XILINX_EMC_0_SYNCH_PIPEDELAY_7 2
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_SLOW_PS_7 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_SLOW_PS_7 0
+define_int CONFIG_XILINX_EMC_0_WRITE_MIN_PULSE_WIDTH_PS_7 0
+define_int CONFIG_XILINX_EMC_0_READ_ADDR_TO_OUT_FAST_PS_7 0
+define_int CONFIG_XILINX_EMC_0_WRITE_ADDR_TO_OUT_FAST_PS_7 0
+define_int CONFIG_XILINX_EMC_0_READ_RECOVERY_BEFORE_WRITE_PS_7 0
+define_int CONFIG_XILINX_EMC_0_WRITE_RECOVERY_BEFORE_READ_PS_7 0
+define_int CONFIG_XILINX_EMC_0_OPB_DWIDTH 32
+define_int CONFIG_XILINX_EMC_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_EMC_0_OPB_CLK_PERIOD_PS 15000
+define_int CONFIG_XILINX_EMC_0_DEV_BLK_ID 1
+define_int CONFIG_XILINX_EMC_0_DEV_MIR_ENABLE 1
+define_string CONFIG_XILINX_EMC_0_INSTANCE sramflash
+define_string CONFIG_XILINX_EMC_0_HW_VER 1.10.b
+
+# No. of instances for EMC
+define_int CONFIG_XILINX_EMC_NUM_INSTANCES 1
+
+# Definitions for UARTLITE_0
+define_string CONFIG_XILINX_UARTLITE_0_INSTANCE consoleuart
+define_hex CONFIG_XILINX_UARTLITE_0_BASEADDR 0xFFFF2000
+define_hex CONFIG_XILINX_UARTLITE_0_HIGHADDR 0xFFFF20FF
+define_int CONFIG_XILINX_UARTLITE_0_OPB_DWIDTH 32
+define_int CONFIG_XILINX_UARTLITE_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_UARTLITE_0_DATA_BITS 8
+define_int CONFIG_XILINX_UARTLITE_0_CLK_FREQ 66666667
+define_int CONFIG_XILINX_UARTLITE_0_BAUDRATE 57600
+define_int CONFIG_XILINX_UARTLITE_0_USE_PARITY 0
+define_int CONFIG_XILINX_UARTLITE_0_ODD_PARITY 0
+define_string CONFIG_XILINX_UARTLITE_0_INSTANCE consoleuart
+define_string CONFIG_XILINX_UARTLITE_0_HW_VER 1.00.b
+define_int CONFIG_XILINX_UARTLITE_0_IRQ 1
+
+# Definitions for UARTLITE_1
+define_string CONFIG_XILINX_UARTLITE_1_INSTANCE debuguart
+define_hex CONFIG_XILINX_UARTLITE_1_BASEADDR 0xFFFF4000
+define_hex CONFIG_XILINX_UARTLITE_1_HIGHADDR 0xFFFF40FF
+define_int CONFIG_XILINX_UARTLITE_1_OPB_DWIDTH 32
+define_int CONFIG_XILINX_UARTLITE_1_OPB_AWIDTH 32
+define_int CONFIG_XILINX_UARTLITE_1_DATA_BITS 8
+define_int CONFIG_XILINX_UARTLITE_1_CLK_FREQ 66666667
+define_int CONFIG_XILINX_UARTLITE_1_BAUDRATE 115200
+define_int CONFIG_XILINX_UARTLITE_1_USE_PARITY 0
+define_int CONFIG_XILINX_UARTLITE_1_ODD_PARITY 0
+define_string CONFIG_XILINX_UARTLITE_1_INSTANCE debuguart
+define_string CONFIG_XILINX_UARTLITE_1_HW_VER 1.00.b
+define_int CONFIG_XILINX_UARTLITE_1_IRQ 2
+
+# No. of instances for UARTLITE
+define_int CONFIG_XILINX_UARTLITE_NUM_INSTANCES 2
+
+# Definitions for INTC_0
+define_string CONFIG_XILINX_INTC_0_INSTANCE systemintc
+define_string CONFIG_XILINX_INTC_0_FAMILY virtex2p
+define_int CONFIG_XILINX_INTC_0_Y 0
+define_int CONFIG_XILINX_INTC_0_X 0
+define_string CONFIG_XILINX_INTC_0_U_SET intc
+define_int CONFIG_XILINX_INTC_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_INTC_0_OPB_DWIDTH 32
+define_hex CONFIG_XILINX_INTC_0_BASEADDR 0xFFFF3000
+define_hex CONFIG_XILINX_INTC_0_HIGHADDR 0xFFFF30FF
+define_int CONFIG_XILINX_INTC_0_NUM_INTR_INPUTS 4
+define_hex CONFIG_XILINX_INTC_0_KIND_OF_INTR 0x00000006
+define_hex CONFIG_XILINX_INTC_0_KIND_OF_EDGE 0x00000006
+define_hex CONFIG_XILINX_INTC_0_KIND_OF_LVL 0x00000009
+define_int CONFIG_XILINX_INTC_0_HAS_IPR 1
+define_int CONFIG_XILINX_INTC_0_HAS_SIE 1
+define_int CONFIG_XILINX_INTC_0_HAS_CIE 1
+define_int CONFIG_XILINX_INTC_0_HAS_IVR 1
+define_int CONFIG_XILINX_INTC_0_IRQ_IS_LEVEL 1
+define_int CONFIG_XILINX_INTC_0_IRQ_ACTIVE 1
+define_string CONFIG_XILINX_INTC_0_INSTANCE systemintc
+define_string CONFIG_XILINX_INTC_0_HW_VER 1.00.c
+
+# No. of instances for INTC
+define_int CONFIG_XILINX_INTC_NUM_INSTANCES 1
+
+# Definitions for TIMER_0
+define_string CONFIG_XILINX_TIMER_0_INSTANCE systemtimer
+define_string CONFIG_XILINX_TIMER_0_FAMILY virtex2p
+define_int CONFIG_XILINX_TIMER_0_COUNT_WIDTH 32
+define_int CONFIG_XILINX_TIMER_0_ONE_TIMER_ONLY 0
+define_int CONFIG_XILINX_TIMER_0_TRIG0_ASSERT 1
+define_int CONFIG_XILINX_TIMER_0_TRIG1_ASSERT 1
+define_int CONFIG_XILINX_TIMER_0_GEN0_ASSERT 1
+define_int CONFIG_XILINX_TIMER_0_GEN1_ASSERT 1
+define_int CONFIG_XILINX_TIMER_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_TIMER_0_OPB_DWIDTH 32
+define_hex CONFIG_XILINX_TIMER_0_BASEADDR 0xFFFF1000
+define_hex CONFIG_XILINX_TIMER_0_HIGHADDR 0xFFFF10FF
+define_string CONFIG_XILINX_TIMER_0_INSTANCE systemtimer
+define_string CONFIG_XILINX_TIMER_0_HW_VER 1.00.b
+define_int CONFIG_XILINX_TIMER_0_IRQ 0
+
+# No. of instances for TIMER
+define_int CONFIG_XILINX_TIMER_NUM_INSTANCES 1
+
+# Definitions for GPIO_0
+define_string CONFIG_XILINX_GPIO_0_INSTANCE systemgpio
+define_hex CONFIG_XILINX_GPIO_0_BASEADDR 0xFFFF5000
+define_hex CONFIG_XILINX_GPIO_0_HIGHADDR 0xFFFF50FF
+define_int CONFIG_XILINX_GPIO_0_OPB_DWIDTH 32
+define_int CONFIG_XILINX_GPIO_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_GPIO_0_GPIO_WIDTH 24
+define_int CONFIG_XILINX_GPIO_0_ALL_INPUTS 0
+define_string CONFIG_XILINX_GPIO_0_INSTANCE systemgpio
+define_string CONFIG_XILINX_GPIO_0_HW_VER 1.00.a
+
+# No. of instances for GPIO
+define_int CONFIG_XILINX_GPIO_NUM_INSTANCES 1
+
+# Definitions for ETHERNET_0
+define_string CONFIG_XILINX_ETHERNET_0_INSTANCE ethernet
+define_int CONFIG_XILINX_ETHERNET_0_DEV_BLK_ID 1
+define_int CONFIG_XILINX_ETHERNET_0_DEV_MIR_ENABLE 1
+define_hex CONFIG_XILINX_ETHERNET_0_BASEADDR 0xC0000000
+define_hex CONFIG_XILINX_ETHERNET_0_HIGHADDR 0xC0003FFF
+define_int CONFIG_XILINX_ETHERNET_0_RESET_PRESENT 1
+define_int CONFIG_XILINX_ETHERNET_0_INCLUDE_DEV_PENCODER 1
+define_int CONFIG_XILINX_ETHERNET_0_DMA_PRESENT 1
+define_int CONFIG_XILINX_ETHERNET_0_DMA_INTR_COALESCE 1
+define_int CONFIG_XILINX_ETHERNET_0_OPB_AWIDTH 32
+define_int CONFIG_XILINX_ETHERNET_0_OPB_DWIDTH 32
+define_int CONFIG_XILINX_ETHERNET_0_OPB_CLK_PERIOD_PS 15000
+define_string CONFIG_XILINX_ETHERNET_0_FAMILY virtex2p
+define_int CONFIG_XILINX_ETHERNET_0_IPIF_FIFO_DEPTH 32768
+define_int CONFIG_XILINX_ETHERNET_0_SOURCE_ADDR_INSERT_EXIST 1
+define_int CONFIG_XILINX_ETHERNET_0_PAD_INSERT_EXIST 1
+define_int CONFIG_XILINX_ETHERNET_0_FCS_INSERT_EXIST 1
+define_int CONFIG_XILINX_ETHERNET_0_MAFIFO_DEPTH 16
+define_int CONFIG_XILINX_ETHERNET_0_HALF_DUPLEX_EXIST 1
+define_int CONFIG_XILINX_ETHERNET_0_ERR_COUNT_EXIST 1
+define_int CONFIG_XILINX_ETHERNET_0_MII_EXIST 1
+define_string CONFIG_XILINX_ETHERNET_0_INSTANCE ethernet
+define_string CONFIG_XILINX_ETHERNET_0_HW_VER 1.00.m
+define_int CONFIG_XILINX_ETHERNET_0_IRQ 3
+
+# No. of instances for ETHERNET
+define_int CONFIG_XILINX_ETHERNET_NUM_INSTANCES 1
+
diff -urN linux-2.4.29/arch/microblaze/platform/uclinux-auto/head_ram.S linux-2.4.29-uc1/arch/microblaze/platform/uclinux-auto/head_ram.S
--- linux-2.4.29/arch/microblaze/platform/uclinux-auto/head_ram.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/uclinux-auto/head_ram.S	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,104 @@
+/*
+ * arch/microblaze/kernel/head.S -- Lowest-level startup code
+ *
+ *  Copyright (C) 2004       Brett Boren <borenb@eng.uah.edu>
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *                           based upon v850 version
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <asm/clinkage.h>
+#include <asm/current.h>
+#include <asm/entry.h>
+#include <asm/irq.h>
+
+
+/* Make a slightly more convenient alias for C_SYMBOL_NAME.  */
+#define CSYM	C_SYMBOL_NAME 
+
+.global CSYM(_ramstart)
+
+	.data
+CSYM(_ramstart):
+	.long 0
+
+	.text
+
+	// Define `mach_early_init' as a weak symbol
+	.global	CSYM(mach_early_init)
+	.weak	CSYM(mach_early_init)
+
+C_ENTRY(start):
+	// Make sure interrupts are turned off, just in case
+	mfs	r1, rmsr
+	andi	r1, r1, ~2
+	mts	rmsr, r1
+
+	// Set Small Data Anchors
+	la	r13, r0, _KERNEL_SDA_BASE_
+	la	r2, r0, _KERNEL_SDA2_BASE_
+
+	// Initialise the stack pointer
+	// Initial stack is shrunk by 4 bytes (1 word) to permit use of
+	// standard sp->task ptr conversion functions later on
+	la	r1, r0, CSYM(init_task_union)+KERNEL_STACK_SIZE-4;
+
+#ifdef CONFIG_MBVANILLA_CMDLINE
+	// BAB 1/7/04 - Copy off cmdline pointer passed in by bootloader
+	swi	r5, r0, CSYM(bootloader_buf_addr)
+#endif	
+	// See if there's a platform-specific early-initialization routine
+	// defined; it's a weak symbol, so it will have an address of zero if
+	// there's not.
+	la	r6, r0, CSYM(mach_early_init)
+	beqi	r6, 3f
+
+	// There is one, so call it.  If this function is written in C, it
+	// should be very careful -- the stack pointer is valid, but very
+	// little else is (e.g., bss is not zeroed yet).
+	brald	r15, r6			// do call
+	nop				// delay slot
+
+3:
+	// Kernel stack pointer save location
+	swi	r1, r0, KSP
+
+	// Assert that we're in `kernel mode'
+	addi	r19, r0, 1
+	swi	r19, r0, KM
+
+#if 0
+	// Zero bss area, since we can't rely upon any loader to do so
+	addi	r5, r0, CSYM(__bss_start)
+	add	r6, r0, r0
+	addi	r7, r0, CSYM(__bss_end)
+	rsub	r7, r5, r7
+	bralid	r15, CSYM(memset)
+	nop
+
+	// Zero sbss area, since we can't rely upon any loader to do so
+	addi	r5, r0, CSYM(_ssbss)
+	add	r6, r0, r0
+	addi	r7, r0, CSYM(_esbss)
+	rsub	r7, r5, r7
+	bralid	r15, CSYM(memset)
+	nop
+#endif
+
+	// initialise the current task ptr.  This must happen after
+	// we zero BSS, SBSS etc, because "current" is a global C symbol
+	GET_CURRENT_TASK(CURRENT_TASK);
+
+	// Start Linux kernel.
+	// If this call ever returns (which it shouldn't),
+	// set the link pointer to somewhere harmless
+	addi	r15, r0, CSYM(machine_halt)
+	brai	CSYM(start_kernel)
+END(start)
diff -urN linux-2.4.29/arch/microblaze/platform/uclinux-auto/machine.c linux-2.4.29-uc1/arch/microblaze/platform/uclinux-auto/machine.c
--- linux-2.4.29/arch/microblaze/platform/uclinux-auto/machine.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/uclinux-auto/machine.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,285 @@
+/*
+ * arch/microblaze/platform/uclinux-auto/machine.h -- Machine-dependent defs for
+ *	auto-configured Microblaze system
+ *
+ *  Copyright (C) 2003	John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+#include <asm/bitops.h>
+#include <asm/pgalloc.h>
+
+/* Declarations of core setup functions */
+#include <asm/mach.h>
+
+/* Get header files for the peripherals */
+#include <asm/microblaze_timer.h>
+#include <asm/microblaze_intc.h>
+#include <asm/microblaze_gpio.h>
+
+/* for 2.6, include asm-generic/sections.h */
+extern char __bss_start[], __bss_stop[];
+
+#define RAM_START (ERAM_ADDR)
+#define RAM_END ((ERAM_ADDR)+(ERAM_SIZE))
+
+extern void memcons_setup (void);
+extern void xmbrs_console_init(void);
+
+
+#define REG_DUMP_ADDR		0x220000
+
+
+extern struct irqaction reg_snap_action; /* fwd decl */
+
+/* Called with each timer tick, if non-zero.  */
+void (*mach_tick)(void) = 0;
+
+/* Function to drive one of the LED segments */
+void mach_heartbeat(unsigned int value)
+{
+	/* 
+	 * FIXME Strictly speaking this should probably be 
+	 * protected by a semaphore 
+	 */
+
+#ifdef CONFIG_XILINX_GPIO_0_INSTANCE
+	/* Read current value on the port */
+	volatile unsigned int cur_val = microblaze_gpio_read(CONFIG_XILINX_GPIO_0_BASEADDR);
+
+	/* Clear LED bit  */
+	cur_val &= ~0x00010000;
+
+	/* Set it if required */
+	if(value)
+		cur_val |=  0x00010000;
+	
+	microblaze_gpio_write(CONFIG_XILINX_GPIO_0_BASEADDR,cur_val);
+#endif
+}
+
+/* mach_gettimeoffset returns the number of microseconds elapsed since the
+   start of the current tick */
+unsigned long mach_gettimeoffset(void)
+{
+	unsigned long tctr=timer_get_time(CONFIG_XILINX_TIMER_0_BASEADDR,0);
+	unsigned long tcmp=timer_get_compare(CONFIG_XILINX_TIMER_0_BASEADDR,0);
+	unsigned long offset;
+
+	/*
+	 * Timer used in count up mode, so subtract load value from
+	 * counter register to get elapsed ticks */
+	offset = (tctr-tcmp)/(CONFIG_XILINX_CPU_CLOCK_FREQ/1000000);
+
+	/*
+	 * If we are still in the first half of the upcount and a
+	 * timer interupt is pending, then add on a tick's worth of time.
+	 */
+
+	if (((offset * 2) < (1000000/HZ)) && 
+		(timer_get_csr(CONFIG_XILINX_TIMER_0_BASEADDR,0)&TIMER_INTERRUPT))
+	{
+		offset += 1000000/HZ;
+	}
+
+	return offset;
+}
+
+/* Return starting point of romfs image */
+inline unsigned *get_romfs_base(void)
+{
+	/* For now, assume "Standard" model of bss_start */
+	return (unsigned *)&__bss_start;
+}
+
+/* Handle both romfs and cramfs types, without generating unnecessary
+   code (ie no point checking for CRAMFS if it's not even enabled) */
+inline unsigned get_romfs_len(unsigned long *addr)
+{
+#ifdef CONFIG_ROMFS_FS
+	if (memcmp(&addr[0], "-rom1fs-", 8) == 0)       /* romfs */
+		return be32_to_cpu(addr[2]);
+#endif
+
+#ifdef CONFIG_CRAMFS
+	if (addr[0] == le32_to_cpu(0x28cd3d45))	/* cramfs */
+		return le32_to_cpu(addr[1]);
+#endif
+	return 0;
+}
+
+/* mach_early_init() is called very early, after the kernel stack and SDA 
+   pointers are configured, but before BSS/SBSS are zeroed etc.  Be careful 
+   what you do in here.  The bss and sbss sections are zeroed in here */
+void __init mach_early_init (void)
+{
+	unsigned int *src, *dst;
+	unsigned int len;
+
+	extern unsigned char _ssbss, _esbss;
+	extern unsigned int _intv_load_end, _intv_load_start;
+	extern unsigned int _ramstart;
+
+	/* Copy interrupt vectors from high memory down to where
+	   they belong. */
+	dst = (unsigned int *)0x0;		
+	src = (unsigned int *)&_intv_load_start;
+
+#if 1	/* JW don't overwrite reset vector */
+	src++;
+	src++;
+	dst++;
+	dst++;
+#endif
+	do {
+		*(dst++) = *(src++);
+	} while (src < &_intv_load_end);
+
+	/* Copy ROMFS above bss */
+	src=get_romfs_base();
+	len=get_romfs_len(src);
+
+	if(len)
+	{
+		/* Use memmove to handle likely case of memory overlap */
+		memmove(__bss_stop,__bss_start,len);
+	}
+
+        _ramstart = (unsigned long)__bss_stop + len;
+	
+	/* Zero the BSS and SBSS sections */
+	memset(__bss_start,0,__bss_stop-__bss_start);
+	memset(&_ssbss,0,&_esbss-&_ssbss);
+}
+
+void __init mach_reserve_bootmem(void)
+{
+}
+
+void __init mach_setup (char **cmdline)
+{
+	/* Enable the instruction and data caches (if present) */
+	#if CONFIG_XILINX_MICROBLAZE0_USE_ICACHE==1
+	__flush_icache_all();
+	__enable_icache();
+	#endif
+
+	#if CONFIG_XILINX_MICROBLAZE0_USE_DCACHE==1
+	__flush_dcache_all();
+	__enable_dcache();
+	#endif
+
+	printk (KERN_INFO "CPU: MICROBLAZE\n");
+
+	/* now called from drivers/char/tty_io.c:console_init(), 
+	   where it should be! */
+	/* xmbrs_console_init();  */
+	
+	/* 
+	 * Enable master control on interrupt controller.  Note
+         * this does not enable interrupts in the processor, nor 
+	 * does it enable individual IRQs on the controller.  Just
+         * initialises the intc in preparation for these things */
+	microblaze_intc_master_enable();
+
+#ifdef CONFIG_XILINX_GPIO_0_INSTANCE
+	/* Configure the GPIO */
+	/* 8 inputs, 16 outputs */
+	/* microblaze_gpio_setdir(CONFIG_XILINX_GPIO_0_BASEADDR,MICROBLAZE_GPIO_DIR); */
+#endif
+}
+
+void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len)
+{
+	*ram_start = CONFIG_XILINX_ERAM_START;
+	*ram_len = CONFIG_XILINX_ERAM_SIZE;
+}
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* Initialise timer */
+	microblaze_timer_configure(0,HZ);
+
+	/* And install timer interrupt handler at appropriate vector */
+
+	/* Timer is always attached to interrupt 0 (highest priority) */
+	/* Note we use setup_irq rather than request_irq */
+	setup_irq (CONFIG_XILINX_TIMER_0_IRQ, timer_action);
+}
+
+
+void mach_gettimeofday (struct timeval *tv)
+{
+	tv->tv_sec = 0;
+	tv->tv_usec = 0;
+}
+
+void machine_halt (void) __attribute__ ((noreturn));
+void machine_halt (void)
+{
+	for (;;) {
+		/* Following code should disable interrupts */
+		asm ("nop; nop; nop; nop; nop");
+	}
+}
+
+void machine_restart (char *__unused)
+{
+	machine_halt ();
+}
+
+void machine_power_off (void)
+{
+	machine_halt ();
+}
+
+
+/* Interrupts */
+
+/* Data to initialise interrupt controller functionality */
+struct microblaze_intc_irq_init irq_inits[] = {
+	/* Name, base, num, priority (unused in microblaze) */
+	{ "XINTC", 0, NUM_MACH_IRQS,	7 },
+	{ 0 }
+};
+#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
+
+struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
+
+/* Initialize interrupts.  */
+void __init mach_init_irqs (void)
+{
+	microblaze_intc_init_irq_types (irq_inits, hw_itypes);
+}
+
+
+/* An interrupt handler that copies the registers to a known memory location,
+   for debugging purposes.  */
+
+#if 0
+static void make_reg_snap (int irq, void *dummy, struct pt_regs *regs)
+{
+	(*(unsigned *)REG_DUMP_ADDR)++;
+	(*(struct pt_regs *)(REG_DUMP_ADDR + sizeof (unsigned))) = *regs;
+}
+
+static int reg_snap_dev_id;
+static struct irqaction reg_snap_action = {
+	make_reg_snap, 0, 0, "reg_snap", &reg_snap_dev_id, 0
+};
+#endif
diff -urN linux-2.4.29/arch/microblaze/platform/uclinux-auto/Makefile linux-2.4.29-uc1/arch/microblaze/platform/uclinux-auto/Makefile
--- linux-2.4.29/arch/microblaze/platform/uclinux-auto/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/uclinux-auto/Makefile	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,42 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+#
+# re-use any microblaze files that we can.  Perhaps we should create
+# a microblaze directory for shared files ?
+
+VPATH := $(VPATH):../../kernel
+
+ifdef CONFIG_FULLDEBUG
+	AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+# Work out special CPU flags needed
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
+
+all: head_$(MODEL).o entry.o platform.o
+
+O_TARGET := platform.o
+
+obj-y := intv.o entry.o machine.o setup.o
+
+head_$(MODEL).o: head_$(MODEL).S
+
+entry.o: entry.S microblaze_defs.h
+
+microblaze_defs.h: ../../kernel/microblaze_defs.c ../../kernel/microblaze_defs.head
+	rm -f microblaze_defs.d
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S ../../kernel/microblaze_defs.c
+	cp ../../kernel/microblaze_defs.head microblaze_defs.h
+	grep '^#define' microblaze_defs.s >> microblaze_defs.h
+	rm microblaze_defs.s
+-include microblaze_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/microblaze/platform/uclinux-auto/ram.ld.in linux-2.4.29-uc1/arch/microblaze/platform/uclinux-auto/ram.ld.in
--- linux-2.4.29/arch/microblaze/platform/uclinux-auto/ram.ld.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/uclinux-auto/ram.ld.in	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,150 @@
+/* Simple development memory map for Xilinx Microblaze target.
+   Assume that only the interrupt vectors and the small local data
+   area go in LMB RAM, and that some mythical bootloader will 
+   put the kernel into EXT_RAM 
+*/
+
+/* Get all the autoconfigure addresses etc */
+#include <linux/config.h>
+#include <asm/clinkage.h>
+
+MEMORY {
+	LMB  : ORIGIN = CONFIG_XILINX_LMB_START, 
+	       LENGTH = CONFIG_XILINX_LMB_SIZE
+	ERAM  : ORIGIN = CONFIG_XILINX_ERAM_START,
+                LENGTH = CONFIG_XILINX_ERAM_SIZE
+}
+
+SECTIONS {
+	.text : {
+		/* "untouchable" memory space starts here */
+	        _kram_start = . ;
+	
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+		*(.modinfo)
+		. = ALIGN (0x4) ;
+			*(.kstrtab)
+		. = ALIGN (16) ;	/* Exception table.  */
+		__start___ex_table = . ;
+			*(_ex_table)
+		__stop___ex_table = . ;
+
+		__start___ksymtab = . ; /* All kernel symbols */
+		*(__ksymtab)
+		__stop___ksymtab = . ;
+
+                __start___kallsyms = .; /* All kernel symbols           */
+                        *(__kallsyms)
+                __stop___kallsyms = .;
+
+
+		. = ALIGN (4) ;
+		_etext = . ;
+	} > ERAM
+
+	/* Copies of interrupt vector space. They get copied from here into the 
+  	   proper location by mach_early_setup() */ 
+	.intv : {
+		_intv_load_start = . ;
+	        	*(.intv.reset)	/* Reset vector */
+			*(.intv.common) /* Vectors common to all microblaze proc. */
+			*(.intv.mach)   /* Machine-specific int. vectors.  */
+		_intv_load_end = . ;
+	} > ERAM
+
+
+	/* sdata2 section can go anywhere, but must be word aligned
+	   and SDA2_BASE must point to the middle of it */
+	.sdata2 : {
+		_ssrw = .;
+		. = ALIGN(0x8);
+		*(.sdata2)
+	. = ALIGN(8);
+	_essrw = .;
+	_ssrw_size = _essrw - _ssrw;
+	_KERNEL_SDA2_BASE_ = _ssrw + (_ssrw_size / 2);
+	} > ERAM
+
+
+	.data ALIGN (0x4) : {
+
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN (16) ;
+		*(.data.cacheline_aligned)
+		. = ALIGN (0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN (0x2000) ;
+		_edata = . ;
+	
+		/* Reserve some low RAM for r0 based memory references */
+		. = ALIGN(4) ;
+		C_SYMBOL_NAME(r0_ram) = . ;
+		. = . + 32 ;	/* 32 bytes should be enough */
+	} > ERAM
+
+	/* Under the microblaze ABI, .sdata and .sbss must be contiguous */
+	. = ALIGN(8);
+	.sdata : {
+		_ssro = .;
+		*(.sdata)
+	} > ERAM
+
+	. = ALIGN(4);
+	.sbss : {
+		_ssbss = . ;
+		_sbss_start = .;
+		*(.sbss)
+		_ssbss_end = .;
+		_esbss = . ;
+
+	. = ALIGN(8);
+	_essro = .;
+	_ssro_size = _essro - _ssro;
+	_KERNEL_SDA_BASE_ = _ssro + (_ssro_size / 2);
+	
+ 	} > ERAM
+ 
+	/* Place init and bootmap sections last to reduce fragmentation 
+	   when they are freed */
+ 	.init ALIGN (4096) : {
+ 		_init_start = . ;
+		__init_begin = . ;
+ 			*(.text.init)
+ 			*(.data.init)
+ 		. = ALIGN (16) ;
+ 		__setup_start = . ;
+ 			*(.setup.init)
+ 		__setup_end = . ;
+ 		__initcall_start = . ;
+ 			*(.initcall.init)
+ 		. = ALIGN (4) ;
+ 		__initcall_end = . ;
+		. = ALIGN(4096);
+		__init_end = . ;
+ 		_init_end = . ;
+ 		/* Untouchable kernel ram ends here */
+ 		_kram_end = . ;
+ 	} > ERAM
+ 
+	/* .bss must go last, to be compatible with the way the romfs is handled */
+	.bss ALIGN (0x4) : {
+		_sbss = . ;
+		__bss_start = .;
+			*(.bss*)
+			*(COMMON)
+		. = ALIGN (4) ;
+		__bss_stop = . ;
+		_ebss = . ;
+		_end = . ;
+ 	} > ERAM
+ 
+}
+
diff -urN linux-2.4.29/arch/microblaze/platform/uclinux-auto/Rules.make linux-2.4.29-uc1/arch/microblaze/platform/uclinux-auto/Rules.make
--- linux-2.4.29/arch/microblaze/platform/uclinux-auto/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/platform/uclinux-auto/Rules.make	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,6 @@
+# Platform specific rules.make
+
+# Nothing special, just use the standard rules
+include arch/microblaze/platform/Rules.make
+
+
diff -urN linux-2.4.29/arch/microblaze/README linux-2.4.29-uc1/arch/microblaze/README
--- linux-2.4.29/arch/microblaze/README	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/README	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,31 @@
+This is the port of uClinux to the Microblaze softcore processor.
+
+Please note, the port is still experimental!  Many things simply do 
+not work, and more have never been tested.
+
+The port is based *heavily* on the NEC v850 port by Miles Bader.  
+This has potentially introduced some strange coding and design decisions
+in the Microblaze code.  In particular, the low level stuff in entry.S
+may seem a bit odd.  It was done this way to simplify the porting process.
+
+No effort has been made to streamline the low level kernel code.  As Hoare
+said (and restated by Knuth), 
+
+	"Premature optimisation is the root of all Evil"
+
+Words to live by.
+
+As of April 2003, the only hardware target supported is a ficticious 
+Microblaze system called MBVANILLA.  The mhs, mss and other design
+files necessary to synthesise this platform are found in 
+/Vendors/Insight/XC2V1K/hardware.
+
+Contributions to the Microblaze porting effort are welcome!
+Contact jwilliams@itee.uq.edu.au for more info.  Please place the text
+"microblaze uclinux" in the subject line.
+
+Have fun.
+
+John Williams
+2nd April 2003
+
diff -urN linux-2.4.29/arch/microblaze/suzaku.ld linux-2.4.29-uc1/arch/microblaze/suzaku.ld
--- linux-2.4.29/arch/microblaze/suzaku.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/suzaku.ld	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,152 @@
+/* Simple development memory map for Xilinx Microblaze target.
+   Assume that only the interrupt vectors and the small local data
+   area go in LMB RAM, and that some mythical bootloader will 
+   put the kernel into OPB RAM starting from 0xffe00000
+*/
+
+/* Plenty of room to do tricky stuff here.  e.g. for speed, we could
+   put IRQ handlers and the OS scheduling code into LMB.
+   That's just one idea, will look into it more later.
+*/
+  
+MEMORY {
+	/* 2K of LMB RAM */
+	LMB  : ORIGIN = 0x00000000, LENGTH = 0x00000800
+
+	/* 16 MB of OBP SDRAM */
+	OPB  : ORIGIN = 0x80000000, LENGTH = 0x01000000 
+}
+
+SECTIONS {
+	.text : {
+		/* "untouchable" memory space starts here */
+	        _kram_start = . ;
+	
+		_stext = . ;
+        	*(.text)
+			*(.text.exit)
+			*(.text.lock)
+			*(.exitcall.exit)
+			*(.rodata)
+		*(.modinfo)
+		. = ALIGN (0x4) ;
+			*(.kstrtab)
+		. = ALIGN (16) ;	/* Exception table.  */
+		__start___ex_table = . ;
+			*(_ex_table)
+		__stop___ex_table = . ;
+
+		__start___ksymtab = . ; /* All kernel symbols */
+		*(__ksymtab)
+		__stop___ksymtab = . ;
+
+                __start___kallsyms = .; /* All kernel symbols           */
+                        *(__kallsyms)
+                __stop___kallsyms = .;
+
+
+		. = ALIGN (4) ;
+		_etext = . ;
+	} > OPB
+
+	/* Copies of interrupt vector space. They get copied from here into the 
+  	   proper location by mach_early_setup() */ 
+	.intv : {
+		_intv_load_start = . ;
+	        	*(.intv.reset)	/* Reset vector */
+			*(.intv.common) /* Vectors common to all microblaze proc. */
+			*(.intv.mach)   /* Machine-specific int. vectors.  */
+		_intv_load_end = . ;
+	} > OPB
+
+
+	/* sdata2 section can go anywhere, but must be word aligned
+	   and SDA2_BASE must point to the middle of it */
+	.sdata2 : {
+		_ssrw = .;
+		. = ALIGN(0x8);
+		*(.sdata2)
+	. = ALIGN(8);
+	_essrw = .;
+	_ssrw_size = _essrw - _ssrw;
+	_KERNEL_SDA2_BASE_ = _ssrw + (_ssrw_size / 2);
+	} > OPB
+
+
+	.data ALIGN (0x4) : {
+
+		_sdata = . ;
+		__data_start = . ;
+        	*(.data)
+			*(.data.exit)
+		. = ALIGN (16) ;
+		*(.data.cacheline_aligned)
+		. = ALIGN (0x2000) ;
+        	*(.data.init_task)
+		. = ALIGN (0x2000) ;
+		_edata = . ;
+	
+		/* Reserve some low RAM for r0 based memory references */
+		. = ALIGN(4) ;
+		C_SYMBOL_NAME(r0_ram) = . ;
+		. = . + 32 ;	/* 32 bytes should be enough */
+	} > OPB
+
+	/* Under the microblaze ABI, .sdata and .sbss must be contiguous */
+	. = ALIGN(8);
+	.sdata : {
+		_ssro = .;
+		*(.sdata)
+	} > OPB
+
+	. = ALIGN(4);
+	.sbss : {
+		_ssbss = . ;
+		_sbss_start = .;
+		*(.sbss)
+		_ssbss_end = .;
+		_esbss = . ;
+
+	. = ALIGN(8);
+	_essro = .;
+	_ssro_size = _essro - _ssro;
+	_KERNEL_SDA_BASE_ = _ssro + (_ssro_size / 2);
+	
+ 	} > OPB
+ 
+	/* Place init and bootmap sections last to reduce fragmentation 
+	   when they are freed */
+ 	.init ALIGN (4096) : {
+		_init_start = . ;
+ 		__init_begin = . ;
+ 			*(.text.init)
+ 			*(.data.init)
+ 		. = ALIGN (16) ;
+ 		__setup_start = . ;
+ 			*(.setup.init)
+ 		__setup_end = . ;
+ 		__initcall_start = . ;
+ 			*(.initcall.init)
+ 		. = ALIGN (4) ;
+ 		__initcall_end = . ;
+		. = ALIGN(4096) ;
+ 		__init_end = . ;
+ 		_init_end = . ;
+ 		/* Untouchable kernel ram ends here */
+ 		_kram_end = . ;
+ 	} > OPB
+ 
+	/* .bss must go last, to be compatible with the way the romfs is handled */
+	.bss ALIGN (0x4) : {
+		_sbss = . ;
+		__bss_start = . ;
+			*(.bss*)
+			*(COMMON)
+		. = ALIGN (4) ;
+		__bss_stop = . ;
+		_ebss = . ;
+		_end = . ;
+ 	} > OPB
+ 
+}
+
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/Makefile linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/Makefile
--- linux-2.4.29/arch/microblaze/xilinx_ocp/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/Makefile	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,21 @@
+#
+# Makefile for the Xilinx On Chip Peripheral support code
+#
+
+list-multi		:= xilinx_ocp.o
+
+all: xilinx_ocp.o
+
+USE_STANDARD_AS_RULE		:= TRUE
+
+O_TARGET := xilinx_ocp.o
+
+# The Xilinx OS independent code.
+obj-y := xbasic_types.o xdma_channel.o xdma_channel_sg.o \
+	   xipif_v1_23_b.o xpacket_fifo_v2_00_a.o \
+	   xpacket_fifo_l_v2_00_a.o xversion.o
+
+# Linux file to EXPORT_SYMBOL all of the Xilinx entries.
+export-objs		+= xilinx_syms.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xbasic_types.c linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xbasic_types.c
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xbasic_types.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xbasic_types.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,165 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xbasic_types.c
+*
+* This file contains basic functions for Xilinx software IP.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a rpm  11/07/03 Added XNullHandler function as a stub interrupt handler
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Variable Definitions *****************************/
+
+/**
+ * This variable allows testing to be done easier with asserts. An assert
+ * sets this variable such that a driver can evaluate this variable
+ * to determine if an assert occurred.
+ */
+unsigned int XAssertStatus;
+
+/**
+ * This variable allows the assert functionality to be changed for testing
+ * such that it does not wait infinitely. Use the debugger to disable the
+ * waiting during testing of asserts.
+ */
+u32 XWaitInAssert = TRUE;
+
+/* The callback function to be invoked when an assert is taken */
+static XAssertCallback XAssertCallbackRoutine = (XAssertCallback) NULL;
+
+/************************** Function Prototypes ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Implements assert. Currently, it calls a user-defined callback function
+* if one has been set.  Then, it potentially enters an infinite loop depending
+* on the value of the XWaitInAssert variable.
+*
+* @param    File is the name of the filename of the source
+* @param    Line is the linenumber within File
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XAssert(char *File, int Line)
+{
+	/* if the callback has been set then invoke it */
+	if (XAssertCallbackRoutine != NULL) {
+		(*XAssertCallbackRoutine) (File, Line);
+	}
+
+	/* if specified, wait indefinitely such that the assert will show up
+	 * in testing
+	 */
+	while (XWaitInAssert) {
+	}
+}
+
+/*****************************************************************************/
+/**
+*
+* Sets up a callback function to be invoked when an assert occurs. If there
+* was already a callback installed, then it is replaced.
+*
+* @param    Routine is the callback to be invoked when an assert is taken
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* This function has no effect if NDEBUG is set
+*
+******************************************************************************/
+void
+XAssertSetCallback(XAssertCallback Routine)
+{
+	XAssertCallbackRoutine = Routine;
+}
+
+/*****************************************************************************/
+/**
+*
+* Null handler function. This follows the XInterruptHandler signature for
+* interrupt handlers. It can be used to assign a null handler (a stub) to an
+* interrupt controller vector table.
+*
+* @param    NullParameter is an arbitrary void pointer and not used.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XNullHandler(void *NullParameter)
+{
+}
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xbasic_types.h linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xbasic_types.h
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xbasic_types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xbasic_types.h	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,289 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xbasic_types.h
+*
+* This file contains basic types for Xilinx software IP.  These types do not
+* follow the standard naming convention with respect to using the component
+* name in front of each name because they are considered to be primitives.
+*
+* @note
+*
+* This file contains items which are architecture dependent.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a rmm  12/14/01 First release
+*       rmm  05/09/03 Added "xassert always" macros to rid ourselves of diab
+*                     compiler warnings
+* 1.00a rpm  11/07/03 Added XNullHandler function as a stub interrupt handler
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XBASIC_TYPES_H		/* prevent circular inclusions */
+#define XBASIC_TYPES_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+/************************** Constant Definitions *****************************/
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+/** Null */
+
+#define XCOMPONENT_IS_READY     0x11111111	/* component has been initialized */
+#define XCOMPONENT_IS_STARTED   0x22222222	/* component has been started */
+
+/* the following constants and declarations are for unit test purposes and are
+ * designed to be used in test applications.
+ */
+#define XTEST_PASSED    0
+#define XTEST_FAILED    1
+
+#define XASSERT_NONE     0
+#define XASSERT_OCCURRED 1
+
+extern unsigned int XAssertStatus;
+extern void XAssert(char *, int);
+
+/**************************** Type Definitions *******************************/
+
+/** @name Primitive types
+ * These primitive types are created for transportability.
+ * They are dependent upon the target architecture.
+ * @{
+ */
+#include <linux/types.h>
+
+typedef struct {
+	u32 Upper;
+	u32 Lower;
+} Xuint64;
+
+/*@}*/
+
+/**
+ * This data type defines an interrupt handler for a device.
+ * The argument points to the instance of the component
+ */
+typedef void (*XInterruptHandler) (void *InstancePtr);
+
+/**
+ * This data type defines a callback to be invoked when an
+ * assert occurs. The callback is invoked only when asserts are enabled
+ */
+typedef void (*XAssertCallback) (char *FilenamePtr, int LineNumber);
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/**
+* Return the most significant half of the 64 bit data type.
+*
+* @param x is the 64 bit word.
+*
+* @return
+*
+* The upper 32 bits of the 64 bit word.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XUINT64_MSW(x) ((x).Upper)
+
+/*****************************************************************************/
+/**
+* Return the least significant half of the 64 bit data type.
+*
+* @param x is the 64 bit word.
+*
+* @return
+*
+* The lower 32 bits of the 64 bit word.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XUINT64_LSW(x) ((x).Lower)
+
+#ifndef NDEBUG
+
+/*****************************************************************************/
+/**
+* This assert macro is to be used for functions that do not return anything
+* (void). This in conjunction with the XWaitInAssert boolean can be used to
+* accomodate tests so that asserts which fail allow execution to continue.
+*
+* @param expression is the expression to evaluate. If it evaluates to false,
+*        the assert occurs.
+*
+* @return
+*
+* Returns void unless the XWaitInAssert variable is true, in which case
+* no return is made and an infinite loop is entered.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XASSERT_VOID(expression)                   \
+{                                                  \
+    if (expression)                                \
+    {                                              \
+        XAssertStatus = XASSERT_NONE;              \
+    }                                              \
+    else                                           \
+    {                                              \
+        XAssert(__FILE__, __LINE__);               \
+                XAssertStatus = XASSERT_OCCURRED;  \
+        return;                                    \
+    }                                              \
+}
+
+/*****************************************************************************/
+/**
+* This assert macro is to be used for functions that do return a value. This in
+* conjunction with the XWaitInAssert boolean can be used to accomodate tests so
+* that asserts which fail allow execution to continue.
+*
+* @param expression is the expression to evaluate. If it evaluates to false,
+*        the assert occurs.
+*
+* @return
+*
+* Returns 0 unless the XWaitInAssert variable is true, in which case
+* no return is made and an infinite loop is entered.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XASSERT_NONVOID(expression)                \
+{                                                  \
+    if (expression)                                \
+    {                                              \
+        XAssertStatus = XASSERT_NONE;              \
+    }                                              \
+    else                                           \
+    {                                              \
+        XAssert(__FILE__, __LINE__);               \
+                XAssertStatus = XASSERT_OCCURRED;  \
+        return 0;                                  \
+    }                                              \
+}
+
+/*****************************************************************************/
+/**
+* Always assert. This assert macro is to be used for functions that do not 
+* return anything (void). Use for instances where an assert should always
+* occur.
+*
+* @return
+*
+* Returns void unless the XWaitInAssert variable is true, in which case
+* no return is made and an infinite loop is entered.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XASSERT_VOID_ALWAYS()                      \
+{                                                  \
+   XAssert(__FILE__, __LINE__);                    \
+           XAssertStatus = XASSERT_OCCURRED;       \
+   return;                                         \
+}
+
+/*****************************************************************************/
+/**
+* Always assert. This assert macro is to be used for functions that do return
+* a value. Use for instances where an assert should always occur.
+*
+* @return
+*
+* Returns void unless the XWaitInAssert variable is true, in which case
+* no return is made and an infinite loop is entered.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XASSERT_NONVOID_ALWAYS()                   \
+{                                                  \
+   XAssert(__FILE__, __LINE__);                    \
+           XAssertStatus = XASSERT_OCCURRED;       \
+   return 0;                                       \
+}
+
+#else
+
+#define XASSERT_VOID(expression)
+#define XASSERT_VOID_ALWAYS()
+#define XASSERT_NONVOID(expression)
+#define XASSERT_NONVOID_ALWAYS()
+#endif
+
+/************************** Function Prototypes ******************************/
+
+void XAssertSetCallback(XAssertCallback Routine);
+void XNullHandler(void *NullParameter);
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xbuf_descriptor.h linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xbuf_descriptor.h
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xbuf_descriptor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xbuf_descriptor.h	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,253 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+* FILENAME:
+*
+* xbuf_descriptor.h
+*
+* DESCRIPTION:
+*
+* This file contains the interface for the XBufDescriptor component.
+* The XBufDescriptor component is a passive component that only maps over
+* a buffer descriptor data structure shared by the scatter gather DMA hardware
+* and software. The component's primary purpose is to provide encapsulation of
+* the buffer descriptor processing.  See the source file xbuf_descriptor.c for
+* details.
+*
+* NOTES:
+*
+* Most of the functions of this component are implemented as macros in order
+* to optimize the processing.  The names are not all uppercase such that they
+* can be switched between macros and functions easily.
+*
+******************************************************************************/
+
+#ifndef XBUF_DESCRIPTOR_H	/* prevent circular inclusions */
+#define XBUF_DESCRIPTOR_H	/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xdma_channel_i.h"
+
+/************************** Constant Definitions *****************************/
+
+/* The following constants allow access to all fields of a buffer descriptor
+ * and are necessary at this level of visibility to allow macros to access
+ * and modify the fields of a buffer descriptor.  It is not expected that the
+ * user of a buffer descriptor would need to use these constants.
+ */
+
+#define XBD_DEVICE_STATUS_OFFSET    0
+#define XBD_CONTROL_OFFSET          1
+#define XBD_SOURCE_OFFSET           2
+#define XBD_DESTINATION_OFFSET      3
+#define XBD_LENGTH_OFFSET           4
+#define XBD_STATUS_OFFSET           5
+#define XBD_NEXT_PTR_OFFSET         6
+#define XBD_ID_OFFSET               7
+#define XBD_FLAGS_OFFSET            8
+#define XBD_RQSTED_LENGTH_OFFSET    9
+
+#define XBD_SIZE_IN_WORDS           10
+
+/*
+ * The following constants define the bits of the flags field of a buffer
+ * descriptor
+ */
+
+#define XBD_FLAGS_LOCKED_MASK       1UL
+
+/**************************** Type Definitions *******************************/
+
+typedef u32 XBufDescriptor[XBD_SIZE_IN_WORDS];
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/* each of the following macros are named the same as functions rather than all
+ * upper case in order to allow either the macros or the functions to be
+ * used, see the source file xbuf_descriptor.c for documentation
+ */
+
+#define XBufDescriptor_Initialize(InstancePtr)                  \
+{                                                               \
+    (*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) = 0);       \
+    (*((u32 *)InstancePtr + XBD_SOURCE_OFFSET) = 0);        \
+    (*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET) = 0);   \
+    (*((u32 *)InstancePtr + XBD_LENGTH_OFFSET) = 0);        \
+    (*((u32 *)InstancePtr + XBD_STATUS_OFFSET) = 0);        \
+    (*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET) = 0); \
+    (*((u32 *)InstancePtr + XBD_NEXT_PTR_OFFSET) = 0);      \
+    (*((u32 *)InstancePtr + XBD_ID_OFFSET) = 0);            \
+    (*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) = 0);         \
+    (*((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET) = 0); \
+}
+
+#define XBufDescriptor_GetControl(InstancePtr)   \
+    (u32)(*((u32 *)InstancePtr + XBD_CONTROL_OFFSET))
+
+#define XBufDescriptor_SetControl(InstancePtr, Control)  \
+    (*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) = (u32)Control)
+
+#define XBufDescriptor_IsLastControl(InstancePtr) \
+    (u32)((*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) & \
+               XDC_CONTROL_LAST_BD_MASK) == XDC_CONTROL_LAST_BD_MASK)
+
+#define XBufDescriptor_SetLast(InstancePtr) \
+    (*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) |= XDC_CONTROL_LAST_BD_MASK)
+
+#define XBufDescriptor_GetSrcAddress(InstancePtr) \
+    ((u32 *)(*((u32 *)InstancePtr + XBD_SOURCE_OFFSET)))
+
+#define XBufDescriptor_SetSrcAddress(InstancePtr, Source) \
+    (*((u32 *)InstancePtr + XBD_SOURCE_OFFSET) = (u32)Source)
+
+#define XBufDescriptor_GetDestAddress(InstancePtr) \
+    ((u32 *)(*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET)))
+
+#define XBufDescriptor_SetDestAddress(InstancePtr, Destination) \
+    (*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET) = (u32)Destination)
+
+#define XBufDescriptor_GetLength(InstancePtr)                           \
+    (u32)(*((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET) -    \
+              *((u32 *)InstancePtr + XBD_LENGTH_OFFSET))
+
+#define XBufDescriptor_SetLength(InstancePtr, Length)                       \
+{                                                                           \
+    (*((u32 *)InstancePtr + XBD_LENGTH_OFFSET) = (u32)(Length));    \
+    (*((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET) = (u32)(Length));\
+}
+
+#define XBufDescriptor_GetStatus(InstancePtr)    \
+    (u32)(*((u32 *)InstancePtr + XBD_STATUS_OFFSET))
+
+#define XBufDescriptor_SetStatus(InstancePtr, Status)    \
+    (*((u32 *)InstancePtr + XBD_STATUS_OFFSET) = (u32)Status)
+
+#define XBufDescriptor_IsLastStatus(InstancePtr) \
+    (u32)((*((u32 *)InstancePtr + XBD_STATUS_OFFSET) & \
+               XDC_STATUS_LAST_BD_MASK) == XDC_STATUS_LAST_BD_MASK)
+
+#define XBufDescriptor_GetDeviceStatus(InstancePtr) \
+    ((u32)(*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET)))
+
+#define XBufDescriptor_SetDeviceStatus(InstancePtr, Status) \
+    (*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET) = (u32)Status)
+
+#define XBufDescriptor_GetNextPtr(InstancePtr) \
+    (XBufDescriptor *)(*((u32 *)InstancePtr + XBD_NEXT_PTR_OFFSET))
+
+#define XBufDescriptor_SetNextPtr(InstancePtr, NextPtr) \
+    (*((u32 *)InstancePtr + XBD_NEXT_PTR_OFFSET) = (u32)NextPtr)
+
+#define XBufDescriptor_GetId(InstancePtr) \
+    (u32)(*((u32 *)InstancePtr + XBD_ID_OFFSET))
+
+#define XBufDescriptor_SetId(InstancePtr, Id) \
+    (*((u32 *)InstancePtr + XBD_ID_OFFSET) = (u32)Id)
+
+#define XBufDescriptor_GetFlags(InstancePtr) \
+    (u32)(*((u32 *)InstancePtr + XBD_FLAGS_OFFSET))
+
+#define XBufDescriptor_SetFlags(InstancePtr, Flags) \
+    (*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) = (u32)Flags)
+
+#define XBufDescriptor_Lock(InstancePtr) \
+    (*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) |= XBD_FLAGS_LOCKED_MASK)
+
+#define XBufDescriptor_Unlock(InstancePtr) \
+    (*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) &= ~XBD_FLAGS_LOCKED_MASK)
+
+#define XBufDescriptor_IsLocked(InstancePtr) \
+    (u32) ((*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) & \
+        XBD_FLAGS_LOCKED_MASK) == XBD_FLAGS_LOCKED_MASK)
+
+/************************** Function Prototypes ******************************/
+
+/* The following prototypes are provided to allow each of the functions to
+ * be implemented as a function rather than a macro, and to provide the
+ * syntax to allow users to understand how to call the macros, they are
+ * commented out to prevent linker errors
+ *
+
+u32 XBufDescriptor_Initialize(XBufDescriptor* InstancePtr);
+
+u32 XBufDescriptor_GetControl(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetControl(XBufDescriptor* InstancePtr, u32 Control);
+
+u32 XBufDescriptor_IsLastControl(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetLast(XBufDescriptor* InstancePtr);
+
+u32 XBufDescriptor_GetLength(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetLength(XBufDescriptor* InstancePtr, u32 Length);
+
+u32 XBufDescriptor_GetStatus(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetStatus(XBufDescriptor* InstancePtr, u32 Status);
+u32 XBufDescriptor_IsLastStatus(XBufDescriptor* InstancePtr);
+
+u32 XBufDescriptor_GetDeviceStatus(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetDeviceStatus(XBufDescriptor* InstancePtr,
+                                    u32 Status);
+
+u32 XBufDescriptor_GetSrcAddress(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetSrcAddress(XBufDescriptor* InstancePtr,
+                                  u32 SourceAddress);
+
+u32 XBufDescriptor_GetDestAddress(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetDestAddress(XBufDescriptor* InstancePtr,
+                                   u32 DestinationAddress);
+
+XBufDescriptor* XBufDescriptor_GetNextPtr(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetNextPtr(XBufDescriptor* InstancePtr,
+                               XBufDescriptor* NextPtr);
+
+u32 XBufDescriptor_GetId(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetId(XBufDescriptor* InstancePtr, u32 Id);
+
+u32 XBufDescriptor_GetFlags(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetFlags(XBufDescriptor* InstancePtr, u32 Flags);
+
+void XBufDescriptor_Lock(XBufDescriptor* InstancePtr);
+void XBufDescriptor_Unlock(XBufDescriptor* InstancePtr);
+u32 XBufDescriptor_IsLocked(XBufDescriptor* InstancePtr);
+
+void XBufDescriptor_Copy(XBufDescriptor* InstancePtr,
+                         XBufDescriptor* DestinationPtr);
+
+*/
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xdma_channel.c linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xdma_channel.c
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xdma_channel.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xdma_channel.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,738 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+* FILENAME:
+*
+* xdma_channel.c
+*
+* DESCRIPTION:
+*
+* This file contains the DMA channel component. This component supports
+* a distributed DMA design in which each device can have it's own dedicated
+* DMA channel, as opposed to a centralized DMA design. This component
+* performs processing for DMA on all devices.
+*
+* See xdma_channel.h for more information about this component.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xdma_channel.h"
+#include "xbasic_types.h"
+#include "xio.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_Initialize
+*
+* DESCRIPTION:
+*
+* This function initializes a DMA channel.  This function must be called
+* prior to using a DMA channel.  Initialization of a channel includes setting
+* up the registers base address, and resetting the channel such that it's in a
+* known state.  Interrupts for the channel are disabled when the channel is
+* reset.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* BaseAddress contains the base address of the registers for the DMA channel.
+*
+* RETURN VALUE:
+*
+* XST_SUCCESS indicating initialization was successful.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XDmaChannel_Initialize(XDmaChannel * InstancePtr, u32 BaseAddress)
+{
+	/* assert to verify input arguments, don't assert base address */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+
+	/* setup the base address of the registers for the DMA channel such
+	 * that register accesses can be done
+	 */
+	InstancePtr->RegBaseAddress = BaseAddress;
+
+	/* initialize the scatter gather list such that it indicates it has not
+	 * been created yet and the DMA channel is ready to use (initialized)
+	 */
+	InstancePtr->GetPtr = NULL;
+	InstancePtr->PutPtr = NULL;
+	InstancePtr->CommitPtr = NULL;
+	InstancePtr->LastPtr = NULL;
+
+	InstancePtr->TotalDescriptorCount = 0;
+	InstancePtr->ActiveDescriptorCount = 0;
+	InstancePtr->IsReady = XCOMPONENT_IS_READY;
+
+	/* initialize the version of the component
+	 */
+	XVersion_FromString(&InstancePtr->Version, "1.00a");
+
+	/* reset the DMA channel such that it's in a known state and ready
+	 * and indicate the initialization occured with no errors, note that
+	 * the is ready variable must be set before this call or reset will assert
+	 */
+	XDmaChannel_Reset(InstancePtr);
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_IsReady
+*
+* DESCRIPTION:
+*
+* This function determines if a DMA channel component has been successfully
+* initialized such that it's ready to use.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* RETURN VALUE:
+*
+* TRUE if the DMA channel component is ready, FALSE otherwise.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32
+XDmaChannel_IsReady(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments used by the base component */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+
+	return InstancePtr->IsReady == XCOMPONENT_IS_READY;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetVersion
+*
+* DESCRIPTION:
+*
+* This function gets the software version for the specified DMA channel
+* component.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* RETURN VALUE:
+*
+* A pointer to the software version of the specified DMA channel.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+XVersion *
+XDmaChannel_GetVersion(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* return a pointer to the version of the DMA channel */
+
+	return &InstancePtr->Version;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SelfTest
+*
+* DESCRIPTION:
+*
+* This function performs a self test on the specified DMA channel.  This self
+* test is destructive as the DMA channel is reset and a register default is
+* verified.
+*
+* ARGUMENTS:
+*
+* InstancePtr is a pointer to the DMA channel to be operated on.
+*
+* RETURN VALUE:
+*
+* XST_SUCCESS is returned if the self test is successful, or one of the
+* following errors.
+*
+*	XST_DMA_RESET_REGISTER_ERROR 		Indicates the control register value
+*										after a reset was not correct
+*
+* NOTES:
+*
+* This test does not performs a DMA transfer to test the channel because the
+* DMA hardware will not currently allow a non-local memory transfer to non-local
+* memory (memory copy), but only allows a non-local memory to or from the device
+* memory (typically a FIFO).
+*
+******************************************************************************/
+
+#define XDC_CONTROL_REG_RESET_MASK  0x98000000UL	/* control reg reset value */
+
+XStatus
+XDmaChannel_SelfTest(XDmaChannel * InstancePtr)
+{
+	u32 ControlReg;
+
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* reset the DMA channel such that it's in a known state before the test
+	 * it resets to no interrupts enabled, the desired state for the test
+	 */
+	XDmaChannel_Reset(InstancePtr);
+
+	/* this should be the first test to help prevent a lock up with the polling
+	 * loop that occurs later in the test, check the reset value of the DMA
+	 * control register to make sure it's correct, return with an error if not
+	 */
+	ControlReg = XDmaChannel_GetControl(InstancePtr);
+	if (ControlReg != XDC_CONTROL_REG_RESET_MASK) {
+		return XST_DMA_RESET_REGISTER_ERROR;
+	}
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_Reset
+*
+* DESCRIPTION:
+*
+* This function resets the DMA channel. This is a destructive operation such
+* that it should not be done while a channel is being used.  If the DMA channel
+* is transferring data into other blocks, such as a FIFO, it may be necessary
+* to reset other blocks.  This function does not modify the contents of a
+* scatter gather list for a DMA channel such that the user is responsible for
+* getting buffer descriptors from the list if necessary.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+void
+XDmaChannel_Reset(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* reset the DMA channel such that it's in a known state, the reset
+	 * register is self clearing such that it only has to be set
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_RST_REG_OFFSET,
+		  XDC_RESET_MASK);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetControl
+*
+* DESCRIPTION:
+*
+* This function gets the control register contents of the DMA channel.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* RETURN VALUE:
+*
+* The control register contents of the DMA channel. One or more of the
+* following values may be contained the register.  Each of the values are
+* unique bit masks.
+*
+*	XDC_DMACR_SOURCE_INCR_MASK	Increment the source address
+*	XDC_DMACR_DEST_INCR_MASK	Increment the destination address
+*	XDC_DMACR_SOURCE_LOCAL_MASK Local source address
+*	XDC_DMACR_DEST_LOCAL_MASK	Local destination address
+*	XDC_DMACR_SG_ENABLE_MASK	Scatter gather enable
+*	XDC_DMACR_GEN_BD_INTR_MASK	Individual buffer descriptor interrupt
+*	XDC_DMACR_LAST_BD_MASK		Last buffer descriptor in a packet
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32
+XDmaChannel_GetControl(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* return the contents of the DMA control register */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SetControl
+*
+* DESCRIPTION:
+*
+* This function sets the control register of the specified DMA channel.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* Control contains the value to be written to the control register of the DMA
+* channel. One or more of the following values may be contained the register.
+* Each of the values are unique bit masks such that they may be ORed together
+* to enable multiple bits or inverted and ANDed to disable multiple bits.
+*
+*	XDC_DMACR_SOURCE_INCR_MASK	Increment the source address
+*	XDC_DMACR_DEST_INCR_MASK	Increment the destination address
+*	XDC_DMACR_SOURCE_LOCAL_MASK Local source address
+*	XDC_DMACR_DEST_LOCAL_MASK	Local destination address
+*	XDC_DMACR_SG_ENABLE_MASK	Scatter gather enable
+*	XDC_DMACR_GEN_BD_INTR_MASK	Individual buffer descriptor interrupt
+*	XDC_DMACR_LAST_BD_MASK		Last buffer descriptor in a packet
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+void
+XDmaChannel_SetControl(XDmaChannel * InstancePtr, u32 Control)
+{
+	/* assert to verify input arguments except the control which can't be
+	 * asserted since all values are valid
+	 */
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* set the DMA control register to the specified value */
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET, Control);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetStatus
+*
+* DESCRIPTION:
+*
+* This function gets the status register contents of the DMA channel.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* RETURN VALUE:
+*
+* The status register contents of the DMA channel. One or more of the
+* following values may be contained the register. Each of the values are
+* unique bit masks.
+*
+*	XDC_DMASR_BUSY_MASK			The DMA channel is busy
+*	XDC_DMASR_BUS_ERROR_MASK	A bus error occurred
+*	XDC_DMASR_BUS_TIMEOUT_MASK	A bus timeout occurred
+*	XDC_DMASR_LAST_BD_MASK		The last buffer descriptor of a packet
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32
+XDmaChannel_GetStatus(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* return the contents of the DMA status register */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAS_REG_OFFSET);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SetIntrStatus
+*
+* DESCRIPTION:
+*
+* This function sets the interrupt status register of the specified DMA channel.
+* Setting any bit of the interrupt status register will clear the bit to
+* indicate the interrupt processing has been completed. The definitions of each
+* bit in the register match the definition of the bits in the interrupt enable
+* register.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* Status contains the value to be written to the status register of the DMA
+* channel.  One or more of the following values may be contained the register.
+* Each of the values are unique bit masks such that they may be ORed together
+* to enable multiple bits or inverted and ANDed to disable multiple bits.
+*
+*	XDC_IXR_DMA_DONE_MASK		The dma operation is done
+*	XDC_IXR_DMA_ERROR_MASK	    The dma operation had an error
+*	XDC_IXR_PKT_DONE_MASK	    A packet is complete
+*	XDC_IXR_PKT_THRESHOLD_MASK 	The packet count threshold reached
+*	XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached
+*	XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed
+*	XDC_IXR_BD_MASK				A buffer descriptor is done
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+void
+XDmaChannel_SetIntrStatus(XDmaChannel * InstancePtr, u32 Status)
+{
+	/* assert to verify input arguments except the status which can't be
+	 * asserted since all values are valid
+	 */
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* set the interrupt status register with the specified value such that
+	 * all bits which are set in the register are cleared effectively clearing
+	 * any active interrupts
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET, Status);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetIntrStatus
+*
+* DESCRIPTION:
+*
+* This function gets the interrupt status register of the specified DMA channel.
+* The interrupt status register indicates which interrupts are active
+* for the DMA channel.  If an interrupt is active, the status register must be
+* set (written) with the bit set for each interrupt which has been processed
+* in order to clear the interrupts.  The definitions of each bit in the register
+* match the definition of the bits in the interrupt enable register.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* RETURN VALUE:
+*
+* The interrupt status register contents of the specified DMA channel.
+* One or more of the following values may be contained the register.
+* Each of the values are unique bit masks.
+*
+*	XDC_IXR_DMA_DONE_MASK		The dma operation is done
+*	XDC_IXR_DMA_ERROR_MASK	    The dma operation had an error
+*	XDC_IXR_PKT_DONE_MASK	    A packet is complete
+*	XDC_IXR_PKT_THRESHOLD_MASK 	The packet count threshold reached
+*	XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached
+*	XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed
+*	XDC_IXR_SG_END_MASK			Current descriptor was the end of the list
+*	XDC_IXR_BD_MASK				A buffer descriptor is done
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32
+XDmaChannel_GetIntrStatus(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* return the contents of the interrupt status register */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SetIntrEnable
+*
+* DESCRIPTION:
+*
+* This function sets the interrupt enable register of the specified DMA
+* channel.  The interrupt enable register contains bits which enable
+* individual interrupts for the DMA channel.  The definitions of each bit
+* in the register match the definition of the bits in the interrupt status
+* register.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* Enable contains the interrupt enable register contents to be written
+* in the DMA channel. One or more of the following values may be contained
+* the register. Each of the values are unique bit masks such that they may be
+* ORed together to enable multiple bits or inverted and ANDed to disable
+* multiple bits.
+*
+*	XDC_IXR_DMA_DONE_MASK		The dma operation is done
+*	XDC_IXR_DMA_ERROR_MASK	    The dma operation had an error
+*	XDC_IXR_PKT_DONE_MASK	    A packet is complete
+*	XDC_IXR_PKT_THRESHOLD_MASK 	The packet count threshold reached
+*	XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached
+*	XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed
+*	XDC_IXR_SG_END_MASK			Current descriptor was the end of the list
+*	XDC_IXR_BD_MASK				A buffer descriptor is done
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+void
+XDmaChannel_SetIntrEnable(XDmaChannel * InstancePtr, u32 Enable)
+{
+	/* assert to verify input arguments except the enable which can't be
+	 * asserted since all values are valid
+	 */
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* set the interrupt enable register to the specified value */
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_IE_REG_OFFSET, Enable);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetIntrEnable
+*
+* DESCRIPTION:
+*
+* This function gets the interrupt enable of the DMA channel.  The
+* interrupt enable contains flags which enable individual interrupts for the
+* DMA channel. The definitions of each bit in the register match the definition
+* of the bits in the interrupt status register.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* RETURN VALUE:
+*
+* The interrupt enable of the DMA channel.  One or more of the following values
+* may be contained the register. Each of the values are unique bit masks.
+*
+*	XDC_IXR_DMA_DONE_MASK		The dma operation is done
+*	XDC_IXR_DMA_ERROR_MASK	    The dma operation had an error
+*	XDC_IXR_PKT_DONE_MASK	    A packet is complete
+*	XDC_IXR_PKT_THRESHOLD_MASK 	The packet count threshold reached
+*	XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached
+*	XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed
+*	XDC_IXR_BD_MASK				A buffer descriptor is done
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32
+XDmaChannel_GetIntrEnable(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* return the contents of the interrupt enable register */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_IE_REG_OFFSET);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_Transfer
+*
+* DESCRIPTION:
+*
+* This function starts the DMA channel transferring data from a memory source
+* to a memory destination. This function only starts the operation and returns
+* before the operation may be complete.  If the interrupt is enabled, an
+* interrupt will be generated when the operation is complete, otherwise it is
+* necessary to poll the channel status to determine when it's complete.  It is
+* the responsibility of the caller to determine when the operation is complete
+* by handling the generated interrupt or polling the status.  It is also the
+* responsibility of the caller to ensure that the DMA channel is not busy with
+* another transfer before calling this function.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* SourcePtr contains a pointer to the source memory where the data is to
+* be tranferred from and must be 32 bit aligned.
+*
+* DestinationPtr contains a pointer to the destination memory where the data
+* is to be transferred and must be 32 bit aligned.
+*
+* ByteCount contains the number of bytes to transfer during the DMA operation.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* The DMA h/w will not currently allow a non-local memory transfer to non-local
+* memory (memory copy), but only allows a non-local memory to or from the device
+* memory (typically a FIFO).
+*
+* It is the responsibility of the caller to ensure that the cache is
+* flushed and invalidated both before and after the DMA operation completes
+* if the memory pointed to is cached. The caller must also ensure that the
+* pointers contain a physical address rather than a virtual address
+* if address translation is being used.
+*
+******************************************************************************/
+void
+XDmaChannel_Transfer(XDmaChannel * InstancePtr,
+		     u32 * SourcePtr, u32 * DestinationPtr, u32 ByteCount)
+{
+	/* assert to verify input arguments and the alignment of any arguments
+	 * which have expected alignments
+	 */
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(SourcePtr != NULL);
+	XASSERT_VOID(((u32) SourcePtr & 3) == 0);
+	XASSERT_VOID(DestinationPtr != NULL);
+	XASSERT_VOID(((u32) DestinationPtr & 3) == 0);
+	XASSERT_VOID(ByteCount != 0);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* setup the source and destination address registers for the transfer */
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_SA_REG_OFFSET,
+		  (u32) SourcePtr);
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_DA_REG_OFFSET,
+		  (u32) DestinationPtr);
+
+	/* start the DMA transfer to copy from the source buffer to the
+	 * destination buffer by writing the length to the length register
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_LEN_REG_OFFSET, ByteCount);
+}
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xdma_channel.h linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xdma_channel.h
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xdma_channel.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xdma_channel.h	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,294 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+* FILENAME:
+*
+* xdma_channel.h
+*
+* DESCRIPTION:
+*
+* This file contains the DMA channel component implementation. This component
+* supports a distributed DMA design in which each device can have it's own
+* dedicated DMA channel, as opposed to a centralized DMA design.
+* A device which uses DMA typically contains two DMA channels, one for
+* sending data and the other for receiving data.
+*
+* This component is designed to be used as a basic building block for
+* designing a device driver. It provides registers accesses such that all
+* DMA processing can be maintained easier, but the device driver designer
+* must still understand all the details of the DMA channel.
+*
+* The DMA channel allows a CPU to minimize the CPU interaction required to move
+* data between a memory and a device.  The CPU requests the DMA channel to
+* perform a DMA operation and typically continues performing other processing
+* until the DMA operation completes.  DMA could be considered a primitive form
+* of multiprocessing such that caching and address translation can be an issue.
+*
+* Scatter Gather Operations
+*
+* The DMA channel may support scatter gather operations. A scatter gather
+* operation automates the DMA channel such that multiple buffers can be
+* sent or received with minimal software interaction with the hardware.  Buffer
+* descriptors, contained in the XBufDescriptor component, are used by the
+* scatter gather operations of the DMA channel to describe the buffers to be
+* processed.
+*
+* Scatter Gather List Operations
+*
+* A scatter gather list may be supported by each DMA channel.  The scatter
+* gather list allows buffer descriptors to be put into the list by a device
+* driver which requires scatter gather.  The hardware processes the buffer
+* descriptors which are contained in the list and modifies the buffer
+* descriptors to reflect the status of the DMA operations.  The device driver
+* is notified by interrupt that specific DMA events occur including scatter
+* gather events.  The device driver removes the completed buffer descriptors
+* from the scatter gather list to evaluate the status of each DMA operation.
+*
+* The scatter gather list is created and buffer descriptors are inserted into
+* the list.  Buffer descriptors are never removed from the list after it's
+* creation such that a put operation copies from a temporary buffer descriptor
+* to a buffer descriptor in the list.  Get operations don't copy from the list
+* to a temporary, but return a pointer to the buffer descriptor in the list.
+* A buffer descriptor in the list may be locked to prevent it from being
+* overwritten by a put operation.  This allows the device driver to get a
+* descriptor from a scatter gather list and prevent it from being overwritten
+* until the buffer associated with the buffer descriptor has been processed.
+*
+* Typical Scatter Gather Processing
+*
+* The following steps illustrate the typical processing to use the
+* scatter gather features of a DMA channel.
+*
+* 1. Create a scatter gather list for the DMA channel which puts empty buffer
+*    descriptors into the list.
+* 2. Create buffer descriptors which describe the buffers to be filled with
+* 	 receive data or the buffers which contain data to be sent.
+* 3. Put buffer descriptors into the DMA channel scatter list such that scatter
+*    gather operations are requested.
+* 4. Commit the buffer descriptors in the list such that they are ready to be
+*    used by the DMA channel hardware.
+* 5. Start the scatter gather operations of the DMA channel.
+* 6. Process any interrupts which occur as a result of the scatter gather
+*    operations or poll the DMA channel to determine the status.
+*
+* Interrupts
+*
+* Each DMA channel has the ability to generate an interrupt.  This component
+* does not perform processing for the interrupt as this processing is typically
+* tightly coupled with the device which is using the DMA channel.  It is the
+* responsibility of the caller of DMA functions to manage the interrupt
+* including connecting to the interrupt and enabling/disabling the interrupt.
+*
+* Critical Sections
+*
+* It is the responsibility of the device driver designer to use critical
+* sections as necessary when calling functions of the DMA channel.  This
+* component does not use critical sections and it does access registers using
+* read-modify-write operations.  Calls to DMA functions from a main thread
+* and from an interrupt context could produce unpredictable behavior such that
+* the caller must provide the appropriate critical sections.
+*
+* Address Translation
+*
+* All addresses of data structures which are passed to DMA functions must
+* be physical (real) addresses as opposed to logical (virtual) addresses.
+*
+* Caching
+*
+* The memory which is passed to the function which creates the scatter gather
+* list must not be cached such that buffer descriptors are non-cached.  This
+* is necessary because the buffer descriptors are kept in a ring buffer and
+* not directly accessible to the caller of DMA functions.
+*
+* The caller of DMA functions is responsible for ensuring that any data
+* buffers which are passed to the DMA channel are cache-line aligned if
+* necessary.
+*
+* The caller of DMA functions is responsible for ensuring that any data
+* buffers which are passed to the DMA channel have been flushed from the cache.
+*
+* The caller of DMA functions is responsible for ensuring that the cache is
+* invalidated prior to using any data buffers which are the result of a DMA
+* operation.
+*
+* Memory Alignment
+*
+* The addresses of data buffers which are passed to DMA functions must be
+* 32 bit word aligned since the DMA hardware performs 32 bit word transfers.
+*
+* Mutual Exclusion
+*
+* The functions of the DMA channel are not thread safe such that the caller
+* of all DMA functions is responsible for ensuring mutual exclusion for a
+* DMA channel.  Mutual exclusion across multiple DMA channels is not
+* necessary.
+*
+* NOTES:
+*
+* Many of the provided functions which are register accessors don't provide
+* a lot of error detection. The caller is expected to understand the impact
+* of a function call based upon the current state of the DMA channel.  This
+* is done to minimize the overhead in this component.
+*
+******************************************************************************/
+
+#ifndef XDMA_CHANNEL_H		/* prevent circular inclusions */
+#define XDMA_CHANNEL_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xdma_channel_i.h"	/* constants shared with buffer descriptor */
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xversion.h"
+#include "xbuf_descriptor.h"
+
+/************************** Constant Definitions *****************************/
+
+/* the following constants provide access to the bit fields of the DMA control
+ * register (DMACR)
+ */
+#define XDC_DMACR_SOURCE_INCR_MASK	0x80000000UL	/* increment source address */
+#define XDC_DMACR_DEST_INCR_MASK	0x40000000UL	/* increment dest address */
+#define XDC_DMACR_SOURCE_LOCAL_MASK 0x20000000UL	/* local source address */
+#define XDC_DMACR_DEST_LOCAL_MASK	0x10000000UL	/* local dest address */
+#define XDC_DMACR_SG_DISABLE_MASK	0x08000000UL	/* scatter gather disable */
+#define XDC_DMACR_GEN_BD_INTR_MASK	0x04000000UL	/* descriptor interrupt */
+#define XDC_DMACR_LAST_BD_MASK		XDC_CONTROL_LAST_BD_MASK	/* last buffer */
+									/*     descriptor  */
+#define XDC_DMACR_DRE_MODE_MASK		0x01000000UL	/* DRE/normal mode */
+
+/* the following constants provide access to the bit fields of the DMA status
+ * register (DMASR)
+ */
+#define XDC_DMASR_BUSY_MASK			0x80000000UL	/* channel is busy */
+#define XDC_DMASR_BUS_ERROR_MASK	0x40000000UL	/* bus error occurred */
+#define XDC_DMASR_BUS_TIMEOUT_MASK	0x20000000UL	/* bus timeout occurred */
+#define XDC_DMASR_LAST_BD_MASK		XDC_STATUS_LAST_BD_MASK	/* last buffer */
+								/* descriptor  */
+#define XDC_DMASR_SG_BUSY_MASK		0x08000000UL	/* scatter gather is busy */
+
+/* the following constants provide access to the bit fields of the interrupt
+ * status register (ISR) and the interrupt enable register (IER), bit masks
+ * match for both registers such that they are named IXR
+ */
+#define XDC_IXR_DMA_DONE_MASK		0x1UL	/* dma operation done */
+#define XDC_IXR_DMA_ERROR_MASK	    0x2UL	/* dma operation error */
+#define XDC_IXR_PKT_DONE_MASK	    0x4UL	/* packet done */
+#define XDC_IXR_PKT_THRESHOLD_MASK 	0x8UL	/* packet count threshold */
+#define XDC_IXR_PKT_WAIT_BOUND_MASK 0x10UL	/* packet wait bound reached */
+#define XDC_IXR_SG_DISABLE_ACK_MASK 0x20UL	/* scatter gather disable
+						   acknowledge occurred */
+#define XDC_IXR_SG_END_MASK			0x40UL	/* last buffer descriptor
+							   disabled scatter gather */
+#define XDC_IXR_BD_MASK				0x80UL	/* buffer descriptor done */
+
+/**************************** Type Definitions *******************************/
+
+/*
+ * the following structure contains data which is on a per instance basis
+ * for the XDmaChannel component
+ */
+typedef struct XDmaChannelTag {
+	XVersion Version;	/* version of the driver */
+	u32 RegBaseAddress;	/* base address of registers */
+	u32 IsReady;		/* device is initialized and ready */
+
+	XBufDescriptor *PutPtr;	/* keep track of where to put into list */
+	XBufDescriptor *GetPtr;	/* keep track of where to get from list */
+	XBufDescriptor *CommitPtr;	/* keep track of where to commit in list */
+	XBufDescriptor *LastPtr;	/* keep track of the last put in the list */
+	void *VirtPtr;		/* virtual base of memory */
+	void *PhyPtr;		/* physical base of memory */
+	u32 TotalDescriptorCount;	/* total # of descriptors in the list */
+	u32 ActiveDescriptorCount;	/* # of descriptors pointing to buffers
+					   * in the buffer descriptor list */
+} XDmaChannel;
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+XStatus XDmaChannel_Initialize(XDmaChannel * InstancePtr, u32 BaseAddress);
+u32 XDmaChannel_IsReady(XDmaChannel * InstancePtr);
+XVersion *XDmaChannel_GetVersion(XDmaChannel * InstancePtr);
+XStatus XDmaChannel_SelfTest(XDmaChannel * InstancePtr);
+void XDmaChannel_Reset(XDmaChannel * InstancePtr);
+
+/* Control functions */
+
+u32 XDmaChannel_GetControl(XDmaChannel * InstancePtr);
+void XDmaChannel_SetControl(XDmaChannel * InstancePtr, u32 Control);
+
+/* Status functions */
+
+u32 XDmaChannel_GetStatus(XDmaChannel * InstancePtr);
+void XDmaChannel_SetIntrStatus(XDmaChannel * InstancePtr, u32 Status);
+u32 XDmaChannel_GetIntrStatus(XDmaChannel * InstancePtr);
+void XDmaChannel_SetIntrEnable(XDmaChannel * InstancePtr, u32 Enable);
+u32 XDmaChannel_GetIntrEnable(XDmaChannel * InstancePtr);
+
+/* DMA without scatter gather functions */
+
+void XDmaChannel_Transfer(XDmaChannel * InstancePtr,
+			  u32 * SourcePtr, u32 * DestinationPtr, u32 ByteCount);
+
+/* Scatter gather functions */
+
+XStatus XDmaChannel_SgStart(XDmaChannel * InstancePtr);
+XStatus XDmaChannel_SgStop(XDmaChannel * InstancePtr,
+			   XBufDescriptor ** BufDescriptorPtr);
+XStatus XDmaChannel_CreateSgList(XDmaChannel * InstancePtr,
+				 u32 * MemoryPtr, u32 ByteCount, void *PhyPtr);
+u32 XDmaChannel_IsSgListEmpty(XDmaChannel * InstancePtr);
+
+XStatus XDmaChannel_PutDescriptor(XDmaChannel * InstancePtr,
+				  XBufDescriptor * BufDescriptorPtr);
+XStatus XDmaChannel_CommitPuts(XDmaChannel * InstancePtr);
+XStatus XDmaChannel_GetDescriptor(XDmaChannel * InstancePtr,
+				  XBufDescriptor ** BufDescriptorPtr);
+
+/* Packet functions for interrupt collescing */
+
+u32 XDmaChannel_GetPktCount(XDmaChannel * InstancePtr);
+void XDmaChannel_DecrementPktCount(XDmaChannel * InstancePtr);
+XStatus XDmaChannel_SetPktThreshold(XDmaChannel * InstancePtr, u8 Threshold);
+u8 XDmaChannel_GetPktThreshold(XDmaChannel * InstancePtr);
+void XDmaChannel_SetPktWaitBound(XDmaChannel * InstancePtr, u32 WaitBound);
+u32 XDmaChannel_GetPktWaitBound(XDmaChannel * InstancePtr);
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xdma_channel_i.h linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xdma_channel_i.h
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xdma_channel_i.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xdma_channel_i.h	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,110 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+* FILENAME:
+*
+* xdma_channel_i.h
+*
+* DESCRIPTION:
+*
+* This file contains data which is shared internal data for the DMA channel
+* component. It is also shared with the buffer descriptor component which is
+* very tightly coupled with the DMA channel component.
+*
+* NOTES:
+*
+* The last buffer descriptor constants must be located here to prevent a
+* circular dependency between the DMA channel component and the buffer
+* descriptor component.
+*
+******************************************************************************/
+
+#ifndef XDMA_CHANNEL_I_H	/* prevent circular inclusions */
+#define XDMA_CHANNEL_I_H	/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xversion.h"
+
+/************************** Constant Definitions *****************************/
+
+#define XDC_DMA_CHANNEL_V1_00_A		"1.00a"
+
+/* the following constant provides access to the bit fields of the DMA control
+ * register (DMACR) which must be shared between the DMA channel component
+ * and the buffer descriptor component
+ */
+#define XDC_CONTROL_LAST_BD_MASK	0x02000000UL	/* last buffer descriptor */
+
+/* the following constant provides access to the bit fields of the DMA status
+ * register (DMASR) which must be shared between the DMA channel component
+ * and the buffer descriptor component
+ */
+#define XDC_STATUS_LAST_BD_MASK		0x10000000UL	/* last buffer descriptor */
+
+/* the following constants provide access to each of the registers of a DMA
+ * channel
+ */
+#define XDC_RST_REG_OFFSET	0	/* reset register */
+#define XDC_MI_REG_OFFSET	0	/* module information register */
+#define XDC_DMAC_REG_OFFSET	4	/* DMA control register */
+#define XDC_SA_REG_OFFSET	8	/* source address register */
+#define XDC_DA_REG_OFFSET	12	/* destination address register */
+#define XDC_LEN_REG_OFFSET	16	/* length register */
+#define XDC_DMAS_REG_OFFSET	20	/* DMA status register */
+#define XDC_BDA_REG_OFFSET	24	/* buffer descriptor address register */
+#define XDC_SWCR_REG_OFFSET 28	/* software control register */
+#define XDC_UPC_REG_OFFSET	32	/* unserviced packet count register */
+#define	XDC_PCT_REG_OFFSET	36	/* packet count threshold register */
+#define XDC_PWB_REG_OFFSET	40	/* packet wait bound register */
+#define XDC_IS_REG_OFFSET	44	/* interrupt status register */
+#define XDC_IE_REG_OFFSET	48	/* interrupt enable register */
+
+/* the following constant is written to the reset register to reset the
+ * DMA channel
+ */
+#define XDC_RESET_MASK				0x0000000AUL
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xdma_channel_sg.c linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xdma_channel_sg.c
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xdma_channel_sg.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xdma_channel_sg.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,1321 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+* FILENAME:
+*
+* xdma_channel_sg.c
+*
+* DESCRIPTION:
+*
+* This file contains the implementation of the XDmaChannel component which is
+* related to scatter gather operations.
+*
+* Scatter Gather Operations
+*
+* The DMA channel may support scatter gather operations. A scatter gather
+* operation automates the DMA channel such that multiple buffers can be
+* sent or received with minimal software interaction with the hardware.  Buffer
+* descriptors, contained in the XBufDescriptor component, are used by the
+* scatter gather operations of the DMA channel to describe the buffers to be
+* processed.
+*
+* Scatter Gather List Operations
+*
+* A scatter gather list may be supported by each DMA channel.  The scatter
+* gather list allows buffer descriptors to be put into the list by a device
+* driver which requires scatter gather.  The hardware processes the buffer
+* descriptors which are contained in the list and modifies the buffer
+* descriptors to reflect the status of the DMA operations.  The device driver
+* is notified by interrupt that specific DMA events occur including scatter
+* gather events.  The device driver removes the completed buffer descriptors
+* from the scatter gather list to evaluate the status of each DMA operation.
+*
+* The scatter gather list is created and buffer descriptors are inserted into
+* the list.  Buffer descriptors are never removed from the list after it's
+* creation such that a put operation copies from a temporary buffer descriptor
+* to a buffer descriptor in the list.  Get operations don't copy from the list
+* to a temporary, but return a pointer to the buffer descriptor in the list.
+* A buffer descriptor in the list may be locked to prevent it from being
+* overwritten by a put operation.  This allows the device driver to get a
+* descriptor from a scatter gather list and prevent it from being overwritten
+* until the buffer associated with the buffer descriptor has been processed.
+*
+* The get and put functions only operate on the list and are asynchronous from
+* the hardware which may be using the list of descriptors.  This is important
+* because there are no checks in the get and put functions to ensure that the
+* hardware has processed the descriptors.  This must be handled by the driver
+* using the DMA scatter gather channel through the use of the other functions.
+* When a scatter gather operation is started, the start function does ensure
+* that the descriptor to start has not already been processed by the hardware
+* and is not the first of a series of descriptors that have not been committed
+* yet.
+*
+* Descriptors are put into the list but not marked as ready to use by the
+* hardware until a commit operation is done.  This allows multiple descriptors
+* which may contain a single packet of information for a protocol to be
+* guaranteed not to cause any underflow conditions during transmission. The
+* hardware design only allows descriptors to cause it to stop after a descriptor
+* has been processed rather than before it is processed.  A series of
+* descriptors are put into the list followed by a commit operation, or each
+* descriptor may be commited.  A commit operation is performed by changing a
+* single descriptor, the first of the series of puts, to indicate that the
+* hardware may now use all descriptors after it.  The last descriptor in the
+* list is always set to cause the hardware to stop after it is processed.
+*
+* Typical Scatter Gather Processing
+*
+* The following steps illustrate the typical processing to use the
+* scatter gather features of a DMA channel.
+*
+* 1. Create a scatter gather list for the DMA channel which puts empty buffer
+*    descriptors into the list.
+* 2. Create buffer descriptors which describe the buffers to be filled with
+*    receive data or the buffers which contain data to be sent.
+* 3. Put buffer descriptors into the DMA channel scatter list such that scatter
+*    gather operations are requested.
+* 4. Commit the buffer descriptors in the list such that they are ready to be
+*    used by the DMA channel hardware.
+* 5. Start the scatter gather operations of the DMA channel.
+* 6. Process any interrupts which occur as a result of the scatter gather
+*    operations or poll the DMA channel to determine the status.  This may
+*    be accomplished by getting the packet count for the channel and then
+*    getting the appropriate number of descriptors from the list for that
+*    number of packets.
+*
+* Minimizing Interrupts
+*
+* The Scatter Gather operating mode is designed to reduce the amount of CPU
+* throughput necessary to manage the hardware for devices. A key to the CPU
+* throughput is the number and rate of interrupts that the CPU must service.
+* Devices with higher data rates can cause larger numbers of interrupts and
+* higher frequency interrupts. Ideally the number of interrupts can be reduced
+* by only generating an interrupt when a specific amount of data has been
+* received from the interface. This design suffers from a lack of interrupts
+* when the amount of data received is less than the specified amount of data
+* to generate an interrupt. In order to help minimize the number of interrupts
+* which the CPU must service, an algorithm referred to as "interrupt coalescing"
+* is utilized.
+*
+* Interrupt Coalescing
+*
+* The principle of interrupt coalescing is to wait before generating an
+* interrupt until a certain number of packets have been received or sent. An
+* interrupt is also generated if a smaller number of packets have been received
+* followed by a certain period of time with no packet reception. This is a
+* trade-off of latency for bandwidth and is accomplished using several
+* mechanisms of the hardware including a counter for packets received or
+* transmitted and a packet timer. These two hardware mechanisms work in
+* combination to allow a reduction in the number of interrupts processed by the
+* CPU for packet reception.
+*
+* Unserviced Packet Count
+*
+* The purpose of the packet counter is to count the number of packets received
+* or transmitted and provide an interrupt when a specific number of packets
+* have been processed by the hardware. An interrupt is generated whenever the
+* counter is greater than or equal to the Packet Count Threshold. This counter
+* contains an accurate count of the number of packets that the hardware has
+* processed, either received or transmitted, and the software has not serviced.
+*
+* The packet counter allows the number of interrupts to be reduced by waiting
+* to generate an interrupt until enough packets are received. For packet
+* reception, packet counts of less than the number to generate an interrupt
+* would not be serviced without the addition of a packet timer. This counter is
+* continuously updated by the hardware, not latched to the value at the time
+* the interrupt occurred.
+*
+* The packet counter can be used within the interrupt service routine for the
+* device to reduce the number of interrupts. The interrupt service routine
+* loops while performing processing for each packet which has been received or
+* transmitted and decrements the counter by a specified value. At the same time,
+* the hardware is possibly continuing to receive or transmit more packets such
+* that the software may choose, based upon the value in the packet counter, to
+* remain in the interrupt service routine rather than exiting and immediately
+* returning. This feature should be used with caution as reducing the number of
+* interrupts is beneficial, but unbounded interrupt processing is not desirable.
+*
+* Since the hardware may be incrementing the packet counter simultaneously
+* with the software decrementing the counter, there is a need for atomic
+* operations. The hardware ensures that the operation is atomic such that
+* simultaneous accesses are properly handled.
+*
+* Packet Wait Bound
+*
+* The purpose of the packet wait bound is to augment the unserviced packet
+* count. Whenever there is no pending interrupt for the channel and the
+* unserviced packet count is non-zero, a timer starts counting timeout at the
+* value contained the the packet wait bound register.  If the timeout is
+* reached, an interrupt is generated such that the software may service the
+* data which was buffered.
+*
+* NOTES:
+*
+* Special Test Conditions:
+*
+* The scatter gather list processing must be thoroughly tested if changes are
+* made.  Testing should include putting and committing single descriptors and
+* putting multiple descriptors followed by a single commit.  There are some
+* conditions in the code which handle the exception conditions.
+*
+* The Put Pointer points to the next location in the descriptor list to copy
+* in a new descriptor. The Get Pointer points to the next location in the
+* list to get a descriptor from.  The Get Pointer only allows software to
+* have a traverse the list after the hardware has finished processing some
+* number of descriptors.  The Commit Pointer points to the descriptor in the
+* list which is to be committed.  It is also used to determine that no
+* descriptor is waiting to be commited (NULL).  The Last Pointer points to
+* the last descriptor that was put into the list.  It typically points
+* to the previous descriptor to the one pointed to by the Put Pointer.
+* Comparisons are done between these pointers to determine when the following
+* special conditions exist.
+
+* Single Put And Commit
+*
+* The buffer descriptor is ready to be used by the hardware so it is important
+* for the descriptor to not appear to be waiting to be committed.  The commit
+* pointer is reset when a commit is done indicating there are no descriptors
+* waiting to be committed.  In all cases but this one, the descriptor is
+* changed to cause the hardware to go to the next descriptor after processing
+* this one.  But in this case, this is the last descriptor in the list such
+* that it must not be changed.
+*
+* 3 Or More Puts And Commit
+*
+* A series of 3 or more puts followed by a single commit is different in that
+* only the 1st descriptor put into the list is changed when the commit is done.
+* This requires each put starting on the 3rd to change the previous descriptor
+* so that it allows the hardware to continue to the next descriptor in the list.
+*
+* The 1st Put Following A Commit
+*
+* The commit caused the commit pointer to be NULL indicating that there are no
+* descriptors waiting to be committed.  It is necessary for the next put to set
+* the commit pointer so that a commit must follow the put for the hardware to
+* use the descriptor.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ------------------------------------------------------
+* 1.00a rpm  02/03/03 Removed the XST_DMA_SG_COUNT_EXCEEDED return code
+*                     from SetPktThreshold.
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xdma_channel.h"
+#include "xbasic_types.h"
+#include "xio.h"
+#include "xbuf_descriptor.h"
+#include "xstatus.h"
+
+/* simple virt<-->phy pointer conversions for a single dma channel */
+#define P_TO_V(p) \
+	((p) ? \
+	 (InstancePtr->VirtPtr + ((u32)(p) - (u32)InstancePtr->PhyPtr)) : \
+	 0)
+
+#define V_TO_P(v) \
+	((v) ? \
+	 (InstancePtr->PhyPtr + ((u32)(v) - (u32)InstancePtr->VirtPtr)) : \
+	 0)
+
+/************************** Constant Definitions *****************************/
+
+#define XDC_SWCR_SG_ENABLE_MASK 0x80000000UL	/* scatter gather enable */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/* the following macro copies selected fields of a buffer descriptor to another
+ * buffer descriptor, this was provided by the buffer descriptor component but
+ * was moved here since it is only used internally to this component and since
+ * it does not copy all fields
+ */
+#define CopyBufferDescriptor(InstancePtr, DestinationPtr)          \
+{                                                                  \
+    *((u32 *)DestinationPtr + XBD_CONTROL_OFFSET) =            \
+        *((u32 *)InstancePtr + XBD_CONTROL_OFFSET);            \
+    *((u32 *)DestinationPtr + XBD_SOURCE_OFFSET) =             \
+        *((u32 *)InstancePtr + XBD_SOURCE_OFFSET);             \
+    *((u32 *)DestinationPtr + XBD_DESTINATION_OFFSET) =        \
+        *((u32 *)InstancePtr + XBD_DESTINATION_OFFSET);        \
+    *((u32 *)DestinationPtr + XBD_LENGTH_OFFSET) =             \
+        *((u32 *)InstancePtr + XBD_LENGTH_OFFSET);             \
+    *((u32 *)DestinationPtr + XBD_STATUS_OFFSET) =             \
+        *((u32 *)InstancePtr + XBD_STATUS_OFFSET);             \
+    *((u32 *)DestinationPtr + XBD_DEVICE_STATUS_OFFSET) =      \
+        *((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET);      \
+    *((u32 *)DestinationPtr + XBD_ID_OFFSET) =                 \
+        *((u32 *)InstancePtr + XBD_ID_OFFSET);                 \
+    *((u32 *)DestinationPtr + XBD_FLAGS_OFFSET) =              \
+        *((u32 *)InstancePtr + XBD_FLAGS_OFFSET);              \
+    *((u32 *)DestinationPtr + XBD_RQSTED_LENGTH_OFFSET) =      \
+        *((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET);      \
+}
+
+/************************** Variable Definitions *****************************/
+
+/************************** Function Prototypes ******************************/
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SgStart
+*
+* DESCRIPTION:
+*
+* This function starts a scatter gather operation for a scatter gather
+* DMA channel.  The first buffer descriptor in the buffer descriptor list
+* will be started with the scatter gather operation.  A scatter gather list
+* should have previously been created for the DMA channel and buffer
+* descriptors put into the scatter gather list such that there are scatter
+* operations ready to be performed.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* A status containing XST_SUCCESS if scatter gather was started successfully
+* for the DMA channel.
+*
+* A value of XST_DMA_SG_NO_LIST indicates the scatter gather list has not
+* been created.
+*
+* A value of XST_DMA_SG_LIST_EMPTY indicates scatter gather was not started
+* because the scatter gather list of the DMA channel does not contain any
+* buffer descriptors that are ready to be processed by the hardware.
+*
+* A value of XST_DMA_SG_IS_STARTED indicates scatter gather was not started
+* because the scatter gather was not stopped, but was already started.
+*
+* A value of XST_DMA_SG_BD_NOT_COMMITTED indicates the buffer descriptor of
+* scatter gather list which was to be started is not committed to the list.
+* This status is more likely if this function is being called from an ISR
+* and non-ISR processing is putting descriptors into the list.
+*
+* A value of XST_DMA_SG_NO_DATA indicates that the buffer descriptor of the
+* scatter gather list which was to be started had already been used by the
+* hardware for a DMA transfer that has been completed.
+*
+* NOTES:
+*
+* It is the responsibility of the caller to get all the buffer descriptors
+* after performing a stop operation and before performing a start operation.
+* If buffer descriptors are not retrieved between stop and start operations,
+* buffer descriptors may be processed by the hardware more than once.
+*
+******************************************************************************/
+XStatus
+XDmaChannel_SgStart(XDmaChannel * InstancePtr)
+{
+	u32 Register;
+	XBufDescriptor *LastDescriptorPtr;
+
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if a scatter gather list has not been created yet, return a status */
+
+	if (InstancePtr->TotalDescriptorCount == 0) {
+		return XST_DMA_SG_NO_LIST;
+	}
+
+	/* if the scatter gather list exists but is empty then return a status */
+
+	if (XDmaChannel_IsSgListEmpty(InstancePtr)) {
+		return XST_DMA_SG_LIST_EMPTY;
+	}
+
+	/* if scatter gather is busy for the DMA channel, return a status because
+	 * restarting it could lose data
+	 */
+
+	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAS_REG_OFFSET);
+	if (Register & XDC_DMASR_SG_BUSY_MASK) {
+		return XST_DMA_SG_IS_STARTED;
+	}
+
+	/* get the address of the last buffer descriptor which the DMA hardware
+	 * finished processing
+	 */
+	LastDescriptorPtr = (XBufDescriptor *)
+	    P_TO_V(XIo_In32(InstancePtr->RegBaseAddress + XDC_BDA_REG_OFFSET));
+
+	/* setup the first buffer descriptor that will be sent when the scatter
+	 * gather channel is enabled, this is only necessary one time since
+	 * the BDA register of the channel maintains the last buffer descriptor
+	 * processed
+	 */
+	if (LastDescriptorPtr == NULL) {
+		XIo_Out32(InstancePtr->RegBaseAddress + XDC_BDA_REG_OFFSET,
+			  (u32) V_TO_P(InstancePtr->GetPtr));
+	} else {
+		XBufDescriptor *NextDescriptorPtr;
+
+		/* get the next descriptor to be started, if the status indicates it
+		 * hasn't already been used by the h/w, then it's OK to start it,
+		 * s/w sets the status of each descriptor to busy and then h/w clears
+		 * the busy when it is complete
+		 */
+		NextDescriptorPtr =
+		    P_TO_V(XBufDescriptor_GetNextPtr(LastDescriptorPtr));
+
+		if ((XBufDescriptor_GetStatus(NextDescriptorPtr) &
+		     XDC_DMASR_BUSY_MASK) == 0) {
+			return XST_DMA_SG_NO_DATA;
+		}
+		/* don't start the DMA SG channel if the descriptor to be processed
+		 * by h/w is to be committed by the s/w, this function can be called
+		 * such that it interrupts a thread that was putting into the list
+		 */
+		if (NextDescriptorPtr == InstancePtr->CommitPtr) {
+			return XST_DMA_SG_BD_NOT_COMMITTED;
+		}
+	}
+
+	/* start the scatter gather operation by clearing the stop bit in the
+	 * control register and setting the enable bit in the s/w control register,
+	 * both of these are necessary to cause it to start, right now the order of
+	 * these statements is important, the software control register should be
+	 * set 1st.  The other order can cause the CPU to have a loss of sync
+	 * because it cannot read/write the register while the DMA operation is
+	 * running
+	 */
+
+	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET);
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET,
+		  Register | XDC_SWCR_SG_ENABLE_MASK);
+
+	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET,
+		  Register & ~XDC_DMACR_SG_DISABLE_MASK);
+
+	/* indicate the DMA channel scatter gather operation was started
+	 * successfully
+	 */
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SgStop
+*
+* DESCRIPTION:
+*
+* This function stops a scatter gather operation for a scatter gather
+* DMA channel. This function starts the process of stopping a scatter
+* gather operation that is in progress and waits for the stop to be completed.
+* Since it waits for the operation to stopped before returning, this function
+* could take an amount of time relative to the size of the DMA scatter gather
+* operation which is in progress.  The scatter gather list of the DMA channel
+* is not modified by this function such that starting the scatter gather
+* channel after stopping it will cause it to resume.  This operation is
+* considered to be a graceful stop in that the scatter gather operation
+* completes the current buffer descriptor before stopping.
+*
+* If the interrupt is enabled, an interrupt will be generated when the
+* operation is stopped and the caller is responsible for handling the
+* interrupt.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* BufDescriptorPtr is also a return value which contains a pointer to the
+* buffer descriptor which the scatter gather operation completed when it
+* was stopped.
+*
+* RETURN VALUE:
+*
+* A status containing XST_SUCCESS if scatter gather was stopped successfully
+* for the DMA channel.
+*
+* A value of XST_DMA_SG_IS_STOPPED indicates scatter gather was not stoppped
+* because the scatter gather is not started, but was already stopped.
+*
+* BufDescriptorPtr contains a pointer to the buffer descriptor which was
+* completed when the operation was stopped.
+*
+* NOTES:
+*
+* This function implements a loop which polls the hardware for an infinite
+* amount of time. If the hardware is not operating correctly, this function
+* may never return.
+*
+******************************************************************************/
+XStatus
+XDmaChannel_SgStop(XDmaChannel * InstancePtr,
+		   XBufDescriptor ** BufDescriptorPtr)
+{
+	u32 Register;
+
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufDescriptorPtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* get the contents of the software control register, if scatter gather is not
+	 * enabled (started), then return a status because the disable acknowledge
+	 * would not be generated
+	 */
+	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET);
+
+	if ((Register & XDC_SWCR_SG_ENABLE_MASK) == 0) {
+		return XST_DMA_SG_IS_STOPPED;
+	}
+
+	/* disable scatter gather by writing to the software control register
+	 * without modifying any other bits of the register
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET,
+		  Register & ~XDC_SWCR_SG_ENABLE_MASK);
+
+	/* scatter gather does not disable immediately, but after the current
+	 * buffer descriptor is complete, so wait for the DMA channel to indicate
+	 * the disable is complete
+	 */
+	do {
+		Register =
+		    XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAS_REG_OFFSET);
+	}
+	while (Register & XDC_DMASR_SG_BUSY_MASK);
+
+	/* set the specified buffer descriptor pointer to point to the buffer
+	 * descriptor that the scatter gather DMA channel was processing
+	 */
+	*BufDescriptorPtr = (XBufDescriptor *)
+	    P_TO_V(XIo_In32(InstancePtr->RegBaseAddress + XDC_BDA_REG_OFFSET));
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_CreateSgList
+*
+* DESCRIPTION:
+*
+* This function creates a scatter gather list in the DMA channel.  A scatter
+* gather list consists of a list of buffer descriptors that are available to
+* be used for scatter gather operations.  Buffer descriptors are put into the
+* list to request a scatter gather operation to be performed.
+*
+* A number of buffer descriptors are created from the specified memory and put
+* into a buffer descriptor list as empty buffer descriptors. This function must
+* be called before non-empty buffer descriptors may be put into the DMA channel
+* to request scatter gather operations.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* MemoryPtr contains a pointer to the memory which is to be used for buffer
+* descriptors and must not be cached (virtual).
+*
+* ByteCount contains the number of bytes for the specified memory to be used
+* for buffer descriptors.
+*
+* PhyPtr contains a pointer to the physical memory use for buffer descriptors.
+*
+* RETURN VALUE:
+*
+* A status contains XST_SUCCESS if the scatter gather list was successfully
+* created.
+*
+* A value of XST_DMA_SG_LIST_EXISTS indicates that the scatter gather list
+* was not created because the list has already been created.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XDmaChannel_CreateSgList(XDmaChannel * InstancePtr,
+			 u32 * MemoryPtr, u32 ByteCount, void *PhyPtr)
+{
+	XBufDescriptor *BufferDescriptorPtr = (XBufDescriptor *) MemoryPtr;
+	XBufDescriptor *PreviousDescriptorPtr = NULL;
+	XBufDescriptor *StartOfListPtr = BufferDescriptorPtr;
+	u32 UsedByteCount;
+
+	/* assert to verify valid input arguments, alignment for those
+	 * arguments that have alignment restrictions, and at least enough
+	 * memory for one buffer descriptor
+	 */
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(MemoryPtr != NULL);
+	XASSERT_NONVOID(((u32) MemoryPtr & 3) == 0);
+	XASSERT_NONVOID(ByteCount != 0);
+	XASSERT_NONVOID(ByteCount >= sizeof (XBufDescriptor));
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if the scatter gather list has already been created, then return
+	 * with a status
+	 */
+	if (InstancePtr->TotalDescriptorCount != 0) {
+		return XST_DMA_SG_LIST_EXISTS;
+	}
+
+	/* save this up front so V_TO_P() works correctly */
+	InstancePtr->VirtPtr = MemoryPtr;
+	InstancePtr->PhyPtr = PhyPtr;
+
+	/* loop thru the specified memory block and create as many buffer
+	 * descriptors as possible putting each into the list which is
+	 * implemented as a ring buffer, make sure not to use any memory which
+	 * is not large enough for a complete buffer descriptor
+	 */
+	UsedByteCount = 0;
+	while ((UsedByteCount + sizeof (XBufDescriptor)) <= ByteCount) {
+		/* setup a pointer to the next buffer descriptor in the memory and
+		 * update # of used bytes to know when all of memory is used
+		 */
+		BufferDescriptorPtr = (XBufDescriptor *) ((u32) MemoryPtr +
+							  UsedByteCount);
+
+		/* initialize the new buffer descriptor such that it doesn't contain
+		 * garbage which could be used by the DMA hardware
+		 */
+		XBufDescriptor_Initialize(BufferDescriptorPtr);
+
+		/* if this is not the first buffer descriptor to be created,
+		 * then link it to the last created buffer descriptor
+		 */
+		if (PreviousDescriptorPtr != NULL) {
+			XBufDescriptor_SetNextPtr(PreviousDescriptorPtr,
+						  V_TO_P(BufferDescriptorPtr));
+		}
+
+		/* always keep a pointer to the last created buffer descriptor such
+		 * that they can be linked together in the ring buffer
+		 */
+		PreviousDescriptorPtr = BufferDescriptorPtr;
+
+		/* keep a count of the number of descriptors in the list to allow
+		 * error processing to be performed
+		 */
+		InstancePtr->TotalDescriptorCount++;
+
+		UsedByteCount += sizeof (XBufDescriptor);
+	}
+
+	/* connect the last buffer descriptor created and inserted in the list
+	 * to the first such that a ring buffer is created
+	 */
+	XBufDescriptor_SetNextPtr(BufferDescriptorPtr, V_TO_P(StartOfListPtr));
+
+	/* initialize the ring buffer to indicate that there are no
+	 * buffer descriptors in the list which point to valid data buffers
+	 */
+	InstancePtr->PutPtr = BufferDescriptorPtr;
+	InstancePtr->GetPtr = BufferDescriptorPtr;
+	InstancePtr->CommitPtr = NULL;
+	InstancePtr->LastPtr = BufferDescriptorPtr;
+	InstancePtr->ActiveDescriptorCount = 0;
+
+	/* indicate the scatter gather list was successfully created */
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_IsSgListEmpty
+*
+* DESCRIPTION:
+*
+* This function determines if the scatter gather list of a DMA channel is
+* empty with regard to buffer descriptors which are pointing to buffers to be
+* used for scatter gather operations.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* A value of TRUE if the scatter gather list is empty, otherwise a value of
+* FALSE.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32
+XDmaChannel_IsSgListEmpty(XDmaChannel * InstancePtr)
+{
+	/* assert to verify valid input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if the number of descriptors which are being used in the list is zero
+	 * then the list is empty
+	 */
+	return (InstancePtr->ActiveDescriptorCount == 0);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_PutDescriptor
+*
+* DESCRIPTION:
+*
+* This function puts a buffer descriptor into the DMA channel scatter
+* gather list. A DMA channel maintains a list of buffer descriptors which are
+* to be processed.  This function puts the specified buffer descriptor
+* at the next location in the list.  Note that since the list is already intact,
+* the information in the parameter is copied into the list (rather than modify
+* list pointers on the fly).
+*
+* After buffer descriptors are put into the list, they must also be committed
+* by calling another function.  This allows multiple buffer descriptors which
+* span a single packet to be put into the list while preventing the hardware
+* from starting the first buffer descriptor of the packet.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* BufferDescriptorPtr is a pointer to the buffer descriptor to be put into
+* the next available location of the scatter gather list.
+*
+* RETURN VALUE:
+*
+* A status which indicates XST_SUCCESS if the buffer descriptor was
+* successfully put into the scatter gather list.
+*
+* A value of XST_DMA_SG_NO_LIST indicates the scatter gather list has not
+* been created.
+*
+* A value of XST_DMA_SG_LIST_FULL indicates the buffer descriptor was not
+* put into the list because the list was full.
+*
+* A value of XST_DMA_SG_BD_LOCKED indicates the buffer descriptor was not
+* put into the list because the buffer descriptor in the list which is to
+* be overwritten was locked.  A locked buffer descriptor indicates the higher
+* layered software is still using the buffer descriptor.
+*
+* NOTES:
+*
+* It is necessary to create a scatter gather list for a DMA channel before
+* putting buffer descriptors into it.
+*
+******************************************************************************/
+XStatus
+XDmaChannel_PutDescriptor(XDmaChannel * InstancePtr,
+			  XBufDescriptor * BufferDescriptorPtr)
+{
+	u32 Control;
+
+	/* assert to verify valid input arguments and alignment for those
+	 * arguments that have alignment restrictions
+	 */
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufferDescriptorPtr != NULL);
+	XASSERT_NONVOID(((u32) BufferDescriptorPtr & 3) == 0);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if a scatter gather list has not been created yet, return a status */
+
+	if (InstancePtr->TotalDescriptorCount == 0) {
+		return XST_DMA_SG_NO_LIST;
+	}
+
+	/* if the list is full because all descriptors are pointing to valid
+	 * buffers, then indicate an error, this code assumes no list or an
+	 * empty list is detected above
+	 */
+	if (InstancePtr->ActiveDescriptorCount ==
+	    InstancePtr->TotalDescriptorCount) {
+		return XST_DMA_SG_LIST_FULL;
+	}
+
+	/* if the buffer descriptor in the list which is to be overwritten is
+	 * locked, then don't overwrite it and return a status
+	 */
+	if (XBufDescriptor_IsLocked(InstancePtr->PutPtr)) {
+		return XST_DMA_SG_BD_LOCKED;
+	}
+
+	/* set the scatter gather stop bit in the control word of the descriptor
+	 * to cause the h/w to stop after it processes this descriptor since it
+	 * will be the last in the list
+	 */
+	Control = XBufDescriptor_GetControl(BufferDescriptorPtr);
+	XBufDescriptor_SetControl(BufferDescriptorPtr,
+				  Control | XDC_DMACR_SG_DISABLE_MASK);
+
+	/* set both statuses in the descriptor so we tell if they are updated with
+	 * the status of the transfer, the hardware should change the busy in the
+	 * DMA status to be false when it completes
+	 */
+	XBufDescriptor_SetStatus(BufferDescriptorPtr, XDC_DMASR_BUSY_MASK);
+	XBufDescriptor_SetDeviceStatus(BufferDescriptorPtr, 0);
+
+	/* copy the descriptor into the next position in the list so it's ready to
+	 * be used by the h/w, this assumes the descriptor in the list prior to this
+	 * one still has the stop bit in the control word set such that the h/w
+	 * use this one yet
+	 */
+	CopyBufferDescriptor(BufferDescriptorPtr, InstancePtr->PutPtr);
+
+	/* only the last in the list and the one to be committed have scatter gather
+	 * disabled in the control word, a commit requires only one descriptor
+	 * to be changed, when # of descriptors to commit > 2 all others except the
+	 * 1st and last have scatter gather enabled
+	 */
+	if ((InstancePtr->CommitPtr != InstancePtr->LastPtr) &&
+	    (InstancePtr->CommitPtr != NULL)) {
+		Control = XBufDescriptor_GetControl(InstancePtr->LastPtr);
+		XBufDescriptor_SetControl(InstancePtr->LastPtr,
+					  Control & ~XDC_DMACR_SG_DISABLE_MASK);
+	}
+
+	/* update the list data based upon putting a descriptor into the list,
+	 * these operations must be last
+	 */
+	InstancePtr->ActiveDescriptorCount++;
+
+	/* only update the commit pointer if it is not already active, this allows
+	 * it to be deactivated after every commit such that a single descriptor
+	 * which is committed does not appear to be waiting to be committed
+	 */
+	if (InstancePtr->CommitPtr == NULL) {
+		InstancePtr->CommitPtr = InstancePtr->LastPtr;
+	}
+
+	/* these updates MUST BE LAST after the commit pointer update in order for
+	 * the commit pointer to track the correct descriptor to be committed
+	 */
+	InstancePtr->LastPtr = InstancePtr->PutPtr;
+	InstancePtr->PutPtr =
+	    P_TO_V(XBufDescriptor_GetNextPtr(InstancePtr->PutPtr));
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_CommitPuts
+*
+* DESCRIPTION:
+*
+* This function commits the buffer descriptors which have been put into the
+* scatter list for the DMA channel since the last commit operation was
+* performed.  This enables the calling functions to put several buffer
+* descriptors into the list (e.g.,a packet's worth) before allowing the scatter
+* gather operations to start.  This prevents the DMA channel hardware from
+* starting to use the buffer descriptors in the list before they are ready
+* to be used (multiple buffer descriptors for a single packet).
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* A status indicating XST_SUCCESS if the buffer descriptors of the list were
+* successfully committed.
+*
+* A value of XST_DMA_SG_NOTHING_TO_COMMIT indicates that the buffer descriptors
+* were not committed because there was nothing to commit in the list.  All the
+* buffer descriptors which are in the list are commited.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XDmaChannel_CommitPuts(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if the buffer descriptor to be committed is already committed or
+	 * the list is empty (none have been put in), then indicate an error
+	 */
+	if ((InstancePtr->CommitPtr == NULL) ||
+	    XDmaChannel_IsSgListEmpty(InstancePtr)) {
+		return XST_DMA_SG_NOTHING_TO_COMMIT;
+	}
+
+	/* last descriptor in the list must have scatter gather disabled so the end
+	 * of the list is hit by h/w, if descriptor to commit is not last in list,
+	 * commit descriptors by enabling scatter gather in the descriptor
+	 */
+	if (InstancePtr->CommitPtr != InstancePtr->LastPtr) {
+		u32 Control;
+
+		Control = XBufDescriptor_GetControl(InstancePtr->CommitPtr);
+		XBufDescriptor_SetControl(InstancePtr->CommitPtr, Control &
+					  ~XDC_DMACR_SG_DISABLE_MASK);
+	}
+	/* Update the commit pointer to indicate that there is nothing to be
+	 * committed, this state is used by start processing to know that the
+	 * buffer descriptor to start is not waiting to be committed
+	 */
+	InstancePtr->CommitPtr = NULL;
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetDescriptor
+*
+* DESCRIPTION:
+*
+* This function gets a buffer descriptor from the scatter gather list of the
+* DMA channel. The buffer descriptor is retrieved from the scatter gather list
+* and the scatter gather list is updated to not include the retrieved buffer
+* descriptor.  This is typically done after a scatter gather operation
+* completes indicating that a data buffer has been successfully sent or data
+* has been received into the data buffer. The purpose of this function is to
+* allow the device using the scatter gather operation to get the results of the
+* operation.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* BufDescriptorPtr is a pointer to a pointer to the buffer descriptor which
+* was retrieved from the list.  The buffer descriptor is not really removed
+* from the list, but it is changed to a state such that the hardware will not
+* use it again until it is put into the scatter gather list of the DMA channel.
+*
+* RETURN VALUE:
+*
+* A status indicating XST_SUCCESS if a buffer descriptor was retrieved from
+* the scatter gather list of the DMA channel.
+*
+* A value of XST_DMA_SG_NO_LIST indicates the scatter gather list has not
+* been created.
+*
+* A value of XST_DMA_SG_LIST_EMPTY indicates no buffer descriptor was
+* retrieved from the list because there are no buffer descriptors to be
+* processed in the list.
+*
+* BufDescriptorPtr is updated to point to the buffer descriptor which was
+* retrieved from the list if the status indicates success.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XDmaChannel_GetDescriptor(XDmaChannel * InstancePtr,
+			  XBufDescriptor ** BufDescriptorPtr)
+{
+	u32 Control;
+
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufDescriptorPtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if a scatter gather list has not been created yet, return a status */
+
+	if (InstancePtr->TotalDescriptorCount == 0) {
+		return XST_DMA_SG_NO_LIST;
+	}
+
+	/* if the buffer descriptor list is empty, then indicate an error */
+
+	if (XDmaChannel_IsSgListEmpty(InstancePtr)) {
+		return XST_DMA_SG_LIST_EMPTY;
+	}
+
+	/* retrieve the next buffer descriptor which is ready to be processed from
+	 * the buffer descriptor list for the DMA channel, set the control word
+	 * such that hardware will stop after the descriptor has been processed
+	 */
+	Control = XBufDescriptor_GetControl(InstancePtr->GetPtr);
+	XBufDescriptor_SetControl(InstancePtr->GetPtr,
+				  Control | XDC_DMACR_SG_DISABLE_MASK);
+
+	/* set the input argument, which is also an output, to point to the
+	 * buffer descriptor which is to be retrieved from the list
+	 */
+	*BufDescriptorPtr = InstancePtr->GetPtr;
+
+	/* update the pointer of the DMA channel to reflect the buffer descriptor
+	 * was retrieved from the list by setting it to the next buffer descriptor
+	 * in the list and indicate one less descriptor in the list now
+	 */
+	InstancePtr->GetPtr =
+	    P_TO_V(XBufDescriptor_GetNextPtr(InstancePtr->GetPtr));
+	InstancePtr->ActiveDescriptorCount--;
+
+	return XST_SUCCESS;
+}
+
+/*********************** Interrupt Collescing Functions **********************/
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetPktCount
+*
+* DESCRIPTION:
+*
+* This function returns the value of the unserviced packet count register of
+* the DMA channel.  This count represents the number of packets that have been
+* sent or received by the hardware, but not processed by software.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* The unserviced packet counter register contents for the DMA channel.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32
+XDmaChannel_GetPktCount(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* get the unserviced packet count from the register and return it */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_DecrementPktCount
+*
+* DESCRIPTION:
+*
+* This function decrements the value of the unserviced packet count register.
+* This informs the hardware that the software has processed a packet.  The
+* unserviced packet count register may only be decremented by one in the
+* hardware.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+void
+XDmaChannel_DecrementPktCount(XDmaChannel * InstancePtr)
+{
+	u32 Register;
+
+	/* assert to verify input arguments */
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if the unserviced packet count register can be decremented (rather
+	 * than rolling over) decrement it by writing a 1 to the register,
+	 * this is the only valid write to the register as it serves as an
+	 * acknowledge that a packet was handled by the software
+	 */
+	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET);
+	if (Register > 0) {
+		XIo_Out32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET,
+			  1UL);
+	}
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SetPktThreshold
+*
+* DESCRIPTION:
+*
+* This function sets the value of the packet count threshold register of the
+* DMA channel.  It reflects the number of packets that must be sent or
+* received before generating an interrupt.  This value helps implement
+* a concept called "interrupt coalescing", which is used to reduce the number
+* of interrupts from devices with high data rates.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* Threshold is the value that is written to the threshold register of the
+* DMA channel.
+*
+* RETURN VALUE:
+*
+* A status containing XST_SUCCESS if the packet count threshold was
+* successfully set.
+*
+* NOTES:
+*
+* The packet threshold could be set to larger than the number of descriptors
+* allocated to the DMA channel. In this case, the wait bound will take over
+* and always indicate data arrival. There was a check in this function that
+* returned an error if the treshold was larger than the number of descriptors,
+* but that was removed because users would then have to set the threshold
+* only after they set descriptor space, which is an order dependency that
+* caused confustion.
+*
+******************************************************************************/
+XStatus
+XDmaChannel_SetPktThreshold(XDmaChannel * InstancePtr, u8 Threshold)
+{
+	/* assert to verify input arguments, don't assert the threshold since
+	 * it's range is unknown
+	 */
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* set the packet count threshold in the register such that an interrupt
+	 * may be generated, if enabled, when the packet count threshold is
+	 * reached or exceeded
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_PCT_REG_OFFSET,
+		  (u32) Threshold);
+
+	/* indicate the packet count threshold was successfully set */
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetPktThreshold
+*
+* DESCRIPTION:
+*
+* This function gets the value of the packet count threshold register of the
+* DMA channel.  This value reflects the number of packets that must be sent or
+* received before generating an interrupt.  This value helps implement a concept
+* called "interrupt coalescing", which is used to reduce the number of
+* interrupts from devices with high data rates.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* The packet threshold register contents for the DMA channel and is a value in
+* the range 0 - 1023.  A value of 0 indicates the packet wait bound timer is
+* disabled.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u8
+XDmaChannel_GetPktThreshold(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* get the packet count threshold from the register and return it,
+	 * since only 8 bits are used, cast it to return only those bits */
+
+	return (u8) XIo_In32(InstancePtr->RegBaseAddress + XDC_PCT_REG_OFFSET);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SetPktWaitBound
+*
+* DESCRIPTION:
+*
+* This function sets the value of the packet wait bound register of the
+* DMA channel.  This value reflects the timer value used to trigger an
+* interrupt when not enough packets have been received to reach the packet
+* count threshold.
+*
+* The timer is in millisecond units with +/- 33% accuracy.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* WaitBound is the value, in milliseconds, to be stored in the wait bound
+* register of the DMA channel and is a value in the range 0  - 1023.  A value
+* of 0 disables the packet wait bound timer.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+void
+XDmaChannel_SetPktWaitBound(XDmaChannel * InstancePtr, u32 WaitBound)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(WaitBound < 1024);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* set the packet wait bound in the register such that interrupt may be
+	 * generated, if enabled, when packets have not been handled for a specific
+	 * amount of time
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_PWB_REG_OFFSET, WaitBound);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetPktWaitBound
+*
+* DESCRIPTION:
+*
+* This function gets the value of the packet wait bound register of the
+* DMA channel.  This value contains the timer value used to trigger an
+* interrupt when not enough packets have been received to reach the packet
+* count threshold.
+*
+* The timer is in millisecond units with +/- 33% accuracy.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* The packet wait bound register contents for the DMA channel.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32
+XDmaChannel_GetPktWaitBound(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* get the packet wait bound from the register and return it */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_PWB_REG_OFFSET);
+}
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xilinx_syms.c linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xilinx_syms.c
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xilinx_syms.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xilinx_syms.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,66 @@
+/*
+ * xilinx_syms.c
+ *
+ * This file EXPORT_SYMBOL's all of the Xilinx entry points.
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under the terms
+ * of the GNU General Public License version 2.  This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+
+#include "xbasic_types.h"
+EXPORT_SYMBOL(XAssert);
+EXPORT_SYMBOL(XAssertSetCallback);
+EXPORT_SYMBOL(XAssertStatus);
+extern u32 XWaitInAssert;
+EXPORT_SYMBOL(XWaitInAssert);
+
+#include "xdma_channel.h"
+EXPORT_SYMBOL(XDmaChannel_CommitPuts);
+EXPORT_SYMBOL(XDmaChannel_CreateSgList);
+EXPORT_SYMBOL(XDmaChannel_DecrementPktCount);
+EXPORT_SYMBOL(XDmaChannel_GetControl);
+EXPORT_SYMBOL(XDmaChannel_GetDescriptor);
+EXPORT_SYMBOL(XDmaChannel_GetIntrEnable);
+EXPORT_SYMBOL(XDmaChannel_GetIntrStatus);
+EXPORT_SYMBOL(XDmaChannel_GetPktCount);
+EXPORT_SYMBOL(XDmaChannel_GetPktThreshold);
+EXPORT_SYMBOL(XDmaChannel_GetPktWaitBound);
+EXPORT_SYMBOL(XDmaChannel_GetStatus);
+EXPORT_SYMBOL(XDmaChannel_GetVersion);
+EXPORT_SYMBOL(XDmaChannel_Initialize);
+EXPORT_SYMBOL(XDmaChannel_IsReady);
+EXPORT_SYMBOL(XDmaChannel_IsSgListEmpty);
+EXPORT_SYMBOL(XDmaChannel_PutDescriptor);
+EXPORT_SYMBOL(XDmaChannel_Reset);
+EXPORT_SYMBOL(XDmaChannel_SelfTest);
+EXPORT_SYMBOL(XDmaChannel_SetControl);
+EXPORT_SYMBOL(XDmaChannel_SetIntrEnable);
+EXPORT_SYMBOL(XDmaChannel_SetIntrStatus);
+EXPORT_SYMBOL(XDmaChannel_SetPktThreshold);
+EXPORT_SYMBOL(XDmaChannel_SetPktWaitBound);
+EXPORT_SYMBOL(XDmaChannel_SgStart);
+EXPORT_SYMBOL(XDmaChannel_SgStop);
+EXPORT_SYMBOL(XDmaChannel_Transfer);
+
+#include "xipif_v1_23_b.h"
+EXPORT_SYMBOL(XIpIfV123b_SelfTest);
+
+#include "xpacket_fifo_v2_00_a.h"
+EXPORT_SYMBOL(XPacketFifoV200a_Initialize);
+EXPORT_SYMBOL(XPacketFifoV200a_Read);
+EXPORT_SYMBOL(XPacketFifoV200a_SelfTest);
+EXPORT_SYMBOL(XPacketFifoV200a_Write);
+
+#include "xversion.h"
+EXPORT_SYMBOL(XVersion_Copy);
+EXPORT_SYMBOL(XVersion_FromString);
+EXPORT_SYMBOL(XVersion_IsEqual);
+EXPORT_SYMBOL(XVersion_Pack);
+EXPORT_SYMBOL(XVersion_ToString);
+EXPORT_SYMBOL(XVersion_UnPack);
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xio.h linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xio.h
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xio.h	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,63 @@
+/*
+ * xio.h
+ *
+ * Defines XIo functions for Xilinx OCP in terms of Linux primitives
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under the terms
+ * of the GNU General Public License version 2.  This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+#ifndef XIO_H
+#define XIO_H
+
+#include "xbasic_types.h"
+#include <asm/io.h>
+
+typedef u32 XIo_Address;
+
+extern inline u8
+XIo_In8(XIo_Address InAddress)
+{
+	return (u8) in_8((volatile unsigned char *) InAddress);
+}
+extern inline u16
+XIo_In16(XIo_Address InAddress)
+{
+	return (u16) in_be16((volatile unsigned short *) InAddress);
+}
+extern inline u32
+XIo_In32(XIo_Address InAddress)
+{
+	return (u32) in_be32((volatile unsigned *) InAddress);
+}
+extern inline void
+XIo_Out8(XIo_Address OutAddress, u8 Value)
+{
+	out_8((volatile unsigned char *) OutAddress, Value);
+}
+extern inline void
+XIo_Out16(XIo_Address OutAddress, u16 Value)
+{
+	out_be16((volatile unsigned short *) OutAddress, Value);
+}
+extern inline void
+XIo_Out32(XIo_Address OutAddress, u32 Value)
+{
+	out_be32((volatile unsigned *) OutAddress, Value);
+}
+
+#define XIo_ToLittleEndian16(s,d) (*(u16*)(d) = cpu_to_le16((u16)(s)))
+#define XIo_ToLittleEndian32(s,d) (*(u32*)(d) = cpu_to_le32((u32)(s)))
+#define XIo_ToBigEndian16(s,d) (*(u16*)(d) = cpu_to_be16((u16)(s)))
+#define XIo_ToBigEndian32(s,d) (*(u32*)(d) = cpu_to_be32((u32)(s)))
+
+#define XIo_FromLittleEndian16(s,d) (*(u16*)(d) = le16_to_cpu((u16)(s)))
+#define XIo_FromLittleEndian32(s,d) (*(u32*)(d) = le32_to_cpu((u32)(s)))
+#define XIo_FromBigEndian16(s,d) (*(u16*)(d) = be16_to_cpu((u16)(s)))
+#define XIo_FromBigEndian32(s,d) (*(u32*)(d) = be32_to_cpu((u32)(s)))
+
+#endif				/* XIO_H */
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xipif_v1_23_b.c linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xipif_v1_23_b.c
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xipif_v1_23_b.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xipif_v1_23_b.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,348 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/******************************************************************************
+*
+* FILENAME:
+*
+* xipif.c
+*
+* DESCRIPTION:
+*
+* This file contains the implementation of the XIpIf component. The
+* XIpIf component encapsulates the IPIF, which is the standard interface
+* that IP must adhere to when connecting to a bus.  The purpose of this
+* component is to encapsulate the IPIF processing such that maintainability
+* is increased.  This component does not provide a lot of abstraction from
+* from the details of the IPIF as it is considered a building block for
+* device drivers.  A device driver designer must be familiar with the
+* details of the IPIF hardware to use this component.
+*
+* The IPIF hardware provides a building block for all hardware devices such
+* that each device does not need to reimplement these building blocks. The
+* IPIF contains other building blocks, such as FIFOs and DMA channels, which
+* are also common to many devices.  These blocks are implemented as separate
+* hardware blocks and instantiated within the IPIF.  The primary hardware of
+* the IPIF which is implemented by this software component is the interrupt
+* architecture.  Since there are many blocks of a device which may generate
+* interrupts, all the interrupt processing is contained in the common part
+* of the device, the IPIF.  This interrupt processing is for the device level
+* only and does not include any processing for the interrupt controller.
+*
+* A device is a mechanism such as an Ethernet MAC.  The device is made
+* up of several parts which include an IPIF and the IP.  The IPIF contains most
+* of the device infrastructure which is common to all devices, such as
+* interrupt processing, DMA channels, and FIFOs.  The infrastructure may also
+* be referred to as IPIF internal blocks since they are part of the IPIF and
+* are separate blocks that can be selected based upon the needs of the device.
+* The IP of the device is the logic that is unique to the device and interfaces
+* to the IPIF of the device.
+*
+* In general, there are two levels of registers within the IPIF.  The first
+* level, referred to as the device level, contains registers which are for the
+* entire device.  The second level, referred to as the IP level, contains
+* registers which are specific to the IP of the device.  The two levels of
+* registers are designed to be hierarchical such that the device level is
+* is a more general register set above the more specific registers of the IP.
+* The IP level of registers provides functionality which is typically common
+* across all devices and allows IP designers to focus on the unique aspects
+* of the IP.
+*
+* The interrupt registers of the IPIF are parameterizable such that the only
+* the number of bits necessary for the device are implemented. The functions
+* of this component do not attempt to validate that the passed in arguments are
+* valid based upon the number of implemented bits.  This is necessary to
+* maintain the level of performance required for the common components.  Bits
+* of the registers are assigned starting at the least significant bit of the
+* registers.
+*
+* Critical Sections
+*
+* It is the responsibility of the device driver designer to use critical
+* sections as necessary when calling functions of the IPIF.  This component
+* does not use critical sections and it does access registers using
+* read-modify-write operations.  Calls to IPIF functions from a main thread
+* and from an interrupt context could produce unpredictable behavior such that
+* the caller must provide the appropriate critical sections.
+*
+* Mutual Exclusion
+*
+* The functions of the IPIF are not thread safe such that the caller of all
+* functions is responsible for ensuring mutual exclusion for an IPIF.  Mutual
+* exclusion across multiple IPIF components is not necessary.
+*
+* NOTES:
+*
+* None.
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.23b jhl  02/27/01 Repartioned to reduce size
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xipif_v1_23_b.h"
+#include "xio.h"
+
+/************************** Constant Definitions *****************************/
+
+/* the following constant is used to generate bit masks for register testing
+ * in the self test functions, it defines the starting bit mask that is to be
+ * shifted from the LSB to MSB in creating a register test mask
+ */
+#define XIIF_V123B_FIRST_BIT_MASK     1UL
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Variable Definitions *****************************/
+
+/************************** Function Prototypes ******************************/
+
+static XStatus IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth);
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XIpIf_SelfTest
+*
+* DESCRIPTION:
+*
+* This function performs a self test on the specified IPIF component.  Many
+* of the registers in the IPIF are tested to ensure proper operation.  This
+* function is destructive because the IPIF is reset at the start of the test
+* and at the end of the test to ensure predictable results.  The IPIF reset
+* also resets the entire device that uses the IPIF.  This function exits with
+* all interrupts for the device disabled.
+*
+* ARGUMENTS:
+*
+* InstancePtr points to the XIpIf to operate on.
+*
+* DeviceRegistersWidth contains the number of bits in the device interrupt
+* registers. The hardware is parameterizable such that only the number of bits
+* necessary to support a device are implemented.  This value must be between 0
+* and 32 with 0 indicating there are no device interrupt registers used.
+*
+* IpRegistersWidth contains the number of bits in the IP interrupt registers
+* of the device.  The hardware is parameterizable such that only the number of
+* bits necessary to support a device are implemented.  This value must be
+* between 0 and 32 with 0 indicating there are no IP interrupt registers used.
+*
+* RETURN VALUE:
+*
+* A value of XST_SUCCESS indicates the test was successful with no errors.
+* Any one of the following error values may also be returned.
+*
+*   XST_IPIF_RESET_REGISTER_ERROR       The value of a register at reset was
+*                                       not valid
+*   XST_IPIF_IP_STATUS_ERROR            A write to the IP interrupt status
+*                                       register did not read back correctly
+*   XST_IPIF_IP_ACK_ERROR               One or more bits in the IP interrupt
+*                                       status register did not reset when acked
+*   XST_IPIF_IP_ENABLE_ERROR            The IP interrupt enable register
+*                                       did not read back correctly based upon
+*                                       what was written to it
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+
+/* the following constant defines the maximum number of bits which may be
+ * used in the registers at the device and IP levels, this is based upon the
+ * number of bits available in the registers
+ */
+#define XIIF_V123B_MAX_REG_BIT_COUNT 32
+
+XStatus
+XIpIfV123b_SelfTest(u32 RegBaseAddress, u8 IpRegistersWidth)
+{
+	XStatus Status;
+
+	/* assert to verify arguments are valid */
+
+	XASSERT_NONVOID(IpRegistersWidth <= XIIF_V123B_MAX_REG_BIT_COUNT);
+
+	/* reset the IPIF such that it's in a known state before the test
+	 * and interrupts are globally disabled
+	 */
+	XIIF_V123B_RESET(RegBaseAddress);
+
+	/* perform the self test on the IP interrupt registers, if
+	 * it is not successful exit with the status
+	 */
+	Status = IpIntrSelfTest(RegBaseAddress, IpRegistersWidth);
+	if (Status != XST_SUCCESS) {
+		return Status;
+	}
+
+	/* reset the IPIF such that it's in a known state before exiting test */
+
+	XIIF_V123B_RESET(RegBaseAddress);
+
+	/* reaching this point means there were no errors, return success */
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* IpIntrSelfTest
+*
+* DESCRIPTION:
+*
+* Perform a self test on the IP interrupt registers of the IPIF. This
+* function modifies registers of the IPIF such that they are not guaranteed
+* to be in the same state when it returns.  Any bits in the IP interrupt
+* status register which are set are assumed to be set by default after a reset
+* and are not tested in the test.
+*
+* ARGUMENTS:
+*
+* InstancePtr points to the XIpIf to operate on.
+*
+* IpRegistersWidth contains the number of bits in the IP interrupt registers
+* of the device.  The hardware is parameterizable such that only the number of
+* bits necessary to support a device are implemented.  This value must be
+* between 0 and 32 with 0 indicating there are no IP interrupt registers used.
+*
+* RETURN VALUE:
+*
+* A status indicating XST_SUCCESS if the test was successful.  Otherwise, one
+* of the following values is returned.
+*
+*   XST_IPIF_RESET_REGISTER_ERROR       The value of a register at reset was
+*                                       not valid
+*   XST_IPIF_IP_STATUS_ERROR            A write to the IP interrupt status
+*                                       register did not read back correctly
+*   XST_IPIF_IP_ACK_ERROR               One or more bits in the IP status
+*                                       register did not reset when acked
+*   XST_IPIF_IP_ENABLE_ERROR            The IP interrupt enable register
+*                                       did not read back correctly based upon
+*                                       what was written to it
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+static XStatus
+IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth)
+{
+	/* ensure that the IP interrupt interrupt enable register is  zero
+	 * as it should be at reset, the interrupt status is dependent upon the
+	 * IP such that it's reset value is not known
+	 */
+	if (XIIF_V123B_READ_IIER(RegBaseAddress) != 0) {
+		return XST_IPIF_RESET_REGISTER_ERROR;
+	}
+
+	/* if there are any used IP interrupts, then test all of the interrupt
+	 * bits in all testable registers
+	 */
+	if (IpRegistersWidth > 0) {
+		u32 BitCount;
+		u32 IpInterruptMask = XIIF_V123B_FIRST_BIT_MASK;
+		u32 Mask = XIIF_V123B_FIRST_BIT_MASK;	/* bits assigned MSB to LSB */
+		u32 InterruptStatus;
+
+		/* generate the register masks to be used for IP register tests, the
+		 * number of bits supported by the hardware is parameterizable such
+		 * that only that number of bits are implemented in the registers, the
+		 * bits are allocated starting at the MSB of the registers
+		 */
+		for (BitCount = 1; BitCount < IpRegistersWidth; BitCount++) {
+			Mask = Mask << 1;
+			IpInterruptMask |= Mask;
+		}
+
+		/* get the current IP interrupt status register contents, any bits
+		 * already set must default to 1 at reset in the device and these
+		 * bits can't be tested in the following test, remove these bits from
+		 * the mask that was generated for the test
+		 */
+		InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
+		IpInterruptMask &= ~InterruptStatus;
+
+		/* set the bits in the device status register and verify them by reading
+		 * the register again, all bits of the register are latched
+		 */
+		XIIF_V123B_WRITE_IISR(RegBaseAddress, IpInterruptMask);
+		InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
+		if ((InterruptStatus & IpInterruptMask) != IpInterruptMask)
+		{
+			return XST_IPIF_IP_STATUS_ERROR;
+		}
+
+		/* test to ensure that the bits set in the IP interrupt status register
+		 * can be cleared by acknowledging them in the IP interrupt status
+		 * register then read it again and verify it was cleared
+		 */
+		XIIF_V123B_WRITE_IISR(RegBaseAddress, IpInterruptMask);
+		InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
+		if ((InterruptStatus & IpInterruptMask) != 0) {
+			return XST_IPIF_IP_ACK_ERROR;
+		}
+
+		/* set the IP interrupt enable set register and then read the IP
+		 * interrupt enable register and verify the interrupts were enabled
+		 */
+		XIIF_V123B_WRITE_IIER(RegBaseAddress, IpInterruptMask);
+		if (XIIF_V123B_READ_IIER(RegBaseAddress) != IpInterruptMask) {
+			return XST_IPIF_IP_ENABLE_ERROR;
+		}
+
+		/* clear the IP interrupt enable register and then read the
+		 * IP interrupt enable register and verify the interrupts were disabled
+		 */
+		XIIF_V123B_WRITE_IIER(RegBaseAddress, 0);
+		if (XIIF_V123B_READ_IIER(RegBaseAddress) != 0) {
+			return XST_IPIF_IP_ENABLE_ERROR;
+		}
+	}
+	return XST_SUCCESS;
+}
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xipif_v1_23_b.h linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xipif_v1_23_b.h
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xipif_v1_23_b.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xipif_v1_23_b.h	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,763 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/******************************************************************************
+*
+* FILENAME:
+*
+* xipif.h
+*
+* DESCRIPTION:
+*
+* The XIpIf component encapsulates the IPIF, which is the standard interface
+* that IP must adhere to when connecting to a bus.  The purpose of this
+* component is to encapsulate the IPIF processing such that maintainability
+* is increased.  This component does not provide a lot of abstraction from
+* from the details of the IPIF as it is considered a building block for
+* device drivers.  A device driver designer must be familiar with the
+* details of the IPIF hardware to use this component.
+*
+* The IPIF hardware provides a building block for all hardware devices such
+* that each device does not need to reimplement these building blocks. The
+* IPIF contains other building blocks, such as FIFOs and DMA channels, which
+* are also common to many devices.  These blocks are implemented as separate
+* hardware blocks and instantiated within the IPIF.  The primary hardware of
+* the IPIF which is implemented by this software component is the interrupt
+* architecture.  Since there are many blocks of a device which may generate
+* interrupts, all the interrupt processing is contained in the common part
+* of the device, the IPIF.  This interrupt processing is for the device level
+* only and does not include any processing for the interrupt controller.
+*
+* A device is a mechanism such as an Ethernet MAC.  The device is made
+* up of several parts which include an IPIF and the IP.  The IPIF contains most
+* of the device infrastructure which is common to all devices, such as
+* interrupt processing, DMA channels, and FIFOs.  The infrastructure may also
+* be referred to as IPIF internal blocks since they are part of the IPIF and
+* are separate blocks that can be selected based upon the needs of the device.
+* The IP of the device is the logic that is unique to the device and interfaces
+* to the IPIF of the device.
+*
+* In general, there are two levels of registers within the IPIF.  The first
+* level, referred to as the device level, contains registers which are for the
+* entire device.  The second level, referred to as the IP level, contains
+* registers which are specific to the IP of the device.  The two levels of
+* registers are designed to be hierarchical such that the device level is
+* is a more general register set above the more specific registers of the IP.
+* The IP level of registers provides functionality which is typically common
+* across all devices and allows IP designers to focus on the unique aspects
+* of the IP.
+*
+* Critical Sections
+*
+* It is the responsibility of the device driver designer to use critical
+* sections as necessary when calling functions of the IPIF.  This component
+* does not use critical sections and it does access registers using
+* read-modify-write operations.  Calls to IPIF functions from a main thread
+* and from an interrupt context could produce unpredictable behavior such that
+* the caller must provide the appropriate critical sections.
+*
+* Mutual Exclusion
+*
+* The functions of the IPIF are not thread safe such that the caller of all
+* functions is responsible for ensuring mutual exclusion for an IPIF.  Mutual
+* exclusion across multiple IPIF components is not necessary.
+*
+* NOTES:
+*
+* None.
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.23b jhl  02/27/01 Repartioned to minimize size
+*
+******************************************************************************/
+
+#ifndef XIPIF_H			/* prevent circular inclusions */
+#define XIPIF_H			/* by using protection macros */
+
+/***************************** Include Files *********************************/
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xversion.h"
+
+/************************** Constant Definitions *****************************/
+
+/* the following constants define the register offsets for the registers of the
+ * IPIF, there are some holes in the memory map for reserved addresses to allow
+ * other registers to be added and still match the memory map of the interrupt
+ * controller registers
+ */
+#define XIIF_V123B_DISR_OFFSET     0UL	/* device interrupt status register */
+#define XIIF_V123B_DIPR_OFFSET     4UL	/* device interrupt pending register */
+#define XIIF_V123B_DIER_OFFSET     8UL	/* device interrupt enable register */
+#define XIIF_V123B_DIIR_OFFSET     24UL	/* device interrupt ID register */
+#define XIIF_V123B_DGIER_OFFSET    28UL	/* device global interrupt enable reg */
+#define XIIF_V123B_IISR_OFFSET     32UL	/* IP interrupt status register */
+#define XIIF_V123B_IIER_OFFSET     40UL	/* IP interrupt enable register */
+#define XIIF_V123B_RESETR_OFFSET   64UL	/* reset register */
+
+#define XIIF_V123B_RESET_MASK             0xAUL
+
+/* the following constant is used for the device global interrupt enable
+ * register, to enable all interrupts for the device, this is the only bit
+ * in the register
+ */
+#define XIIF_V123B_GINTR_ENABLE_MASK      0x80000000UL
+
+/* the following constants contain the masks to identify each internal IPIF
+ * condition in the device registers of the IPIF, interrupts are assigned
+ * in the register from LSB to the MSB
+ */
+#define XIIF_V123B_ERROR_MASK             1UL	/* LSB of the register */
+
+/* The following constants contain interrupt IDs which identify each internal
+ * IPIF condition, this value must correlate with the mask constant for the
+ * error
+ */
+#define XIIF_V123B_ERROR_INTERRUPT_ID     0	/* interrupt bit #, (LSB = 0) */
+#define XIIF_V123B_NO_INTERRUPT_ID        128	/* no interrupts are pending */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_RESET
+*
+* DESCRIPTION:
+*
+* Reset the IPIF component and hardware.  This is a destructive operation that
+* could cause the loss of data since resetting the IPIF of a device also
+* resets the device using the IPIF and any blocks, such as FIFOs or DMA
+* channels, within the IPIF.  All registers of the IPIF will contain their
+* reset value when this function returns.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+
+/* the following constant is used in the reset register to cause the IPIF to
+ * reset
+ */
+#define XIIF_V123B_RESET(RegBaseAddress) \
+    XIo_Out32(RegBaseAddress + XIIF_V123B_RESETR_OFFSET, XIIF_V123B_RESET_MASK)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_WRITE_DISR
+*
+* DESCRIPTION:
+*
+* This function sets the device interrupt status register to the value.
+* This register indicates the status of interrupt sources for a device
+* which contains the IPIF.  The status is independent of whether interrupts
+* are enabled and could be used for polling a device at a higher level rather
+* than a more detailed level.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* device which contains the IPIF.  With the exception of some internal IPIF
+* conditions, the contents of this register are not latched but indicate
+* the live status of the interrupt sources within the device.  Writing any of
+* the non-latched bits of the register will have no effect on the register.
+*
+* For the latched bits of this register only, setting a bit which is zero
+* within this register causes an interrupt to generated.  The device global
+* interrupt enable register and the device interrupt enable register must be set
+* appropriately to allow an interrupt to be passed out of the device. The
+* interrupt is cleared by writing to this register with the bits to be
+* cleared set to a one and all others to zero.  This register implements a
+* toggle on write functionality meaning any bits which are set in the value
+* written cause the bits in the register to change to the opposite state.
+*
+* This function writes the specified value to the register such that
+* some bits may be set and others cleared.  It is the caller's responsibility
+* to get the value of the register prior to setting the value to prevent a
+* destructive behavior.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* Status contains the value to be written to the interrupt status register of
+* the device.  The only bits which can be written are the latched bits which
+* contain the internal IPIF conditions.  The following values may be used to
+* set the status register or clear an interrupt condition.
+*
+*   XIIF_V123B_ERROR_MASK     Indicates a device error in the IPIF
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_WRITE_DISR(RegBaseAddress, Status) \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_DISR_OFFSET, (Status))
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_READ_DISR
+*
+* DESCRIPTION:
+*
+* This function gets the device interrupt status register contents.
+* This register indicates the status of interrupt sources for a device
+* which contains the IPIF.  The status is independent of whether interrupts
+* are enabled and could be used for polling a device at a higher level.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* device which contains the IPIF.  With the exception of some internal IPIF
+* conditions, the contents of this register are not latched but indicate
+* the live status of the interrupt sources within the device.
+*
+* For only the latched bits of this register, the interrupt may be cleared by
+* writing to these bits in the status register.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* A status which contains the value read from the interrupt status register of
+* the device. The bit definitions are specific to the device with
+* the exception of the latched internal IPIF condition bits. The following
+* values may be used to detect internal IPIF conditions in the status.
+*
+*   XIIF_V123B_ERROR_MASK     Indicates a device error in the IPIF
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_READ_DISR(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_DISR_OFFSET)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_WRITE_DIER
+*
+* DESCRIPTION:
+*
+* This function sets the device interrupt enable register contents.
+* This register controls which interrupt sources of the device are allowed to
+* generate an interrupt.  The device global interrupt enable register must also
+* be set appropriately for an interrupt to be passed out of the device.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* device which contains the IPIF.  Setting a bit in this register enables that
+* interrupt source to generate an interrupt.  Clearing a bit in this register
+* disables interrupt generation for that interrupt source.
+*
+* This function writes only the specified value to the register such that
+* some interrupts source may be enabled and others disabled.  It is the
+* caller's responsibility to get the value of the interrupt enable register
+* prior to setting the value to prevent an destructive behavior.
+*
+* An interrupt source may not be enabled to generate an interrupt, but can
+* still be polled in the interrupt status register.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* Enable contains the value to be written to the interrupt enable register
+* of the device.  The bit definitions are specific to the device with
+* the exception of the internal IPIF conditions. The following
+* values may be used to enable the internal IPIF conditions interrupts.
+*
+*   XIIF_V123B_ERROR_MASK     Indicates a device error in the IPIF
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* Signature: u32 XIIF_V123B_WRITE_DIER(u32 RegBaseAddress,
+*                                         u32 Enable)
+*
+******************************************************************************/
+#define XIIF_V123B_WRITE_DIER(RegBaseAddress, Enable) \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_DIER_OFFSET, (Enable))
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_READ_DIER
+*
+* DESCRIPTION:
+*
+* This function gets the device interrupt enable register contents.
+* This register controls which interrupt sources of the device
+* are allowed to generate an interrupt.  The device global interrupt enable
+* register and the device interrupt enable register must also be set
+* appropriately for an interrupt to be passed out of the device.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* device which contains the IPIF.  Setting a bit in this register enables that
+* interrupt source to generate an interrupt if the global enable is set
+* appropriately.  Clearing a bit in this register disables interrupt generation
+* for that interrupt source regardless of the global interrupt enable.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* The value read from the interrupt enable register of the device.  The bit
+* definitions are specific to the device with the exception of the internal
+* IPIF conditions. The following values may be used to determine from the
+* value if the internal IPIF conditions interrupts are enabled.
+*
+*   XIIF_V123B_ERROR_MASK     Indicates a device error in the IPIF
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_READ_DIER(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_DIER_OFFSET)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_READ_DIPR
+*
+* DESCRIPTION:
+*
+* This function gets the device interrupt pending register contents.
+* This register indicates the pending interrupt sources, those that are waiting
+* to be serviced by the software, for a device which contains the IPIF.
+* An interrupt must be enabled in the interrupt enable register of the IPIF to
+* be pending.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* the device which contains the IPIF.  With the exception of some internal IPIF
+* conditions, the contents of this register are not latched since the condition
+* is latched in the IP interrupt status register, by an internal block of the
+* IPIF such as a FIFO or DMA channel, or by the IP of the device.  This register
+* is read only and is not latched, but it is necessary to acknowledge (clear)
+* the interrupt condition by performing the appropriate processing for the IP
+* or block within the IPIF.
+*
+* This register can be thought of as the contents of the interrupt status
+* register ANDed with the contents of the interrupt enable register.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* The value read from the interrupt pending register of the device.  The bit
+* definitions are specific to the device with the exception of the latched
+* internal IPIF condition bits. The following values may be used to detect
+* internal IPIF conditions in the value.
+*
+*   XIIF_V123B_ERROR_MASK     Indicates a device error in the IPIF
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_READ_DIPR(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_DIPR_OFFSET)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_READ_DIIR
+*
+* DESCRIPTION:
+*
+* This function gets the device interrupt ID for the highest priority interrupt
+* which is pending from the interrupt ID register. This function provides
+* priority resolution such that faster interrupt processing is possible.
+* Without priority resolution, it is necessary for the software to read the
+* interrupt pending register and then check each interrupt source to determine
+* if an interrupt is pending.  Priority resolution becomes more important as the
+* number of interrupt sources becomes larger.
+*
+* Interrupt priorities are based upon the bit position of the interrupt in the
+* interrupt pending register with bit 0 being the highest priority. The
+* interrupt ID is the priority of the interrupt, 0 - 31, with 0 being the
+* highest priority. The interrupt ID register is live rather than latched such
+* that multiple calls to this function may not yield the same results.  A
+* special value, outside of the interrupt priority range of 0 - 31, is
+* contained in the register which indicates that no interrupt is pending.  This
+* may be useful for allowing software to continue processing interrupts in a
+* loop until there are no longer any interrupts pending.
+*
+* The interrupt ID is designed to allow a function pointer table to be used
+* in the software such that the interrupt ID is used as an index into that
+* table.  The function pointer table could contain an instance pointer, such
+* as to DMA channel, and a function pointer to the function which handles
+* that interrupt.  This design requires the interrupt processing of the device
+* driver to be partitioned into smaller more granular pieces based upon
+* hardware used by the device, such as DMA channels and FIFOs.
+*
+* It is not mandatory that this function be used by the device driver software.
+* It may choose to read the pending register and resolve the pending interrupt
+* priorities on it's own.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* An interrupt ID, 0 - 31, which identifies the highest priority interrupt
+* which is pending.  A value of XIIF_NO_INTERRUPT_ID indicates that there is
+* no interrupt pending. The following values may be used to identify the
+* interrupt ID for the internal IPIF interrupts.
+*
+*   XIIF_V123B_ERROR_INTERRUPT_ID     Indicates a device error in the IPIF
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_READ_DIIR(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_DIIR_OFFSET)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_GLOBAL_INTR_DISABLE
+*
+* DESCRIPTION:
+*
+* This function disables all interrupts for the device by writing to the global
+* interrupt enable register.  This register provides the ability to disable
+* interrupts without any modifications to the interrupt enable register such
+* that it is minimal effort to restore the interrupts to the previous enabled
+* state.  The corresponding function, XIpIf_GlobalIntrEnable, is provided to
+* restore the interrupts to the previous enabled state.  This function is
+* designed to be used in critical sections of device drivers such that it is
+* not necessary to disable other device interrupts.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_GINTR_DISABLE(RegBaseAddress) \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_DGIER_OFFSET, 0)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_GINTR_ENABLE
+*
+* DESCRIPTION:
+*
+* This function writes to the global interrupt enable register to enable
+* interrupts from the device.  This register provides the ability to enable
+* interrupts without any modifications to the interrupt enable register such
+* that it is minimal effort to restore the interrupts to the previous enabled
+* state.  This function does not enable individual interrupts as the interrupt
+* enable register must be set appropriately.  This function is designed to be
+* used in critical sections of device drivers such that it is not necessary to
+* disable other device interrupts.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_GINTR_ENABLE(RegBaseAddress)           \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_DGIER_OFFSET, \
+               XIIF_V123B_GINTR_ENABLE_MASK)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_IS_GINTR_ENABLED
+*
+* DESCRIPTION:
+*
+* This function determines if interrupts are enabled at the global level by
+* reading the gloabl interrupt register. This register provides the ability to
+* disable interrupts without any modifications to the interrupt enable register
+* such that it is minimal effort to restore the interrupts to the previous
+* enabled state.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* TRUE if interrupts are enabled for the IPIF, FALSE otherwise.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_IS_GINTR_ENABLED(RegBaseAddress)             \
+    (XIo_In32((RegBaseAddress) + XIIF_V123B_DGIER_OFFSET) ==    \
+              XIIF_V123B_GINTR_ENABLE_MASK)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_WRITE_IISR
+*
+* DESCRIPTION:
+*
+* This function sets the IP interrupt status register to the specified value.
+* This register indicates the status of interrupt sources for the IP of the
+* device.  The IP is defined as the part of the device that connects to the
+* IPIF.  The status is independent of whether interrupts are enabled such that
+* the status register may also be polled when interrupts are not enabled.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* IP.  All bits of this register are latched. Setting a bit which is zero
+* within this register causes an interrupt to be generated.  The device global
+* interrupt enable register and the device interrupt enable register must be set
+* appropriately to allow an interrupt to be passed out of the device. The
+* interrupt is cleared by writing to this register with the bits to be
+* cleared set to a one and all others to zero.  This register implements a
+* toggle on write functionality meaning any bits which are set in the value
+* written cause the bits in the register to change to the opposite state.
+*
+* This function writes only the specified value to the register such that
+* some status bits may be set and others cleared.  It is the caller's
+* responsibility to get the value of the register prior to setting the value
+* to prevent an destructive behavior.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* Status contains the value to be written to the IP interrupt status
+* register.  The bit definitions are specific to the device IP.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_WRITE_IISR(RegBaseAddress, Status) \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_IISR_OFFSET, (Status))
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_READ_IISR
+*
+* DESCRIPTION:
+*
+* This function gets the contents of the IP interrupt status register.
+* This register indicates the status of interrupt sources for the IP of the
+* device.  The IP is defined as the part of the device that connects to the
+* IPIF. The status is independent of whether interrupts are enabled such
+* that the status register may also be polled when interrupts are not enabled.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* device.  All bits of this register are latched.  Writing a 1 to a bit within
+* this register causes an interrupt to be generated if enabled in the interrupt
+* enable register and the global interrupt enable is set.  Since the status is
+* latched, each status bit must be acknowledged in order for the bit in the
+* status register to be updated.  Each bit can be acknowledged by writing a
+* 0 to the bit in the status register.
+
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* A status which contains the value read from the IP interrupt status register.
+* The bit definitions are specific to the device IP.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_READ_IISR(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_IISR_OFFSET)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_WRITE_IIER
+*
+* DESCRIPTION:
+*
+* This function sets the IP interrupt enable register contents.  This register
+* controls which interrupt sources of the IP are allowed to generate an
+* interrupt.  The global interrupt enable register and the device interrupt
+* enable register must also be set appropriately for an interrupt to be
+* passed out of the device containing the IPIF and the IP.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* IP.  Setting a bit in this register enables the interrupt source to generate
+* an interrupt.  Clearing a bit in this register disables interrupt generation
+* for that interrupt source.
+*
+* This function writes only the specified value to the register such that
+* some interrupt sources may be enabled and others disabled.  It is the
+* caller's responsibility to get the value of the interrupt enable register
+* prior to setting the value to prevent an destructive behavior.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* Enable contains the value to be written to the IP interrupt enable register.
+* The bit definitions are specific to the device IP.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_WRITE_IIER(RegBaseAddress, Enable) \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_IIER_OFFSET, (Enable))
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_READ_IIER
+*
+* DESCRIPTION:
+*
+*
+* This function gets the IP interrupt enable register contents.  This register
+* controls which interrupt sources of the IP are allowed to generate an
+* interrupt.  The global interrupt enable register and the device interrupt
+* enable register must also be set appropriately for an interrupt to be
+* passed out of the device containing the IPIF and the IP.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* IP.  Setting a bit in this register enables the interrupt source to generate
+* an interrupt.  Clearing a bit in this register disables interrupt generation
+* for that interrupt source.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* The contents read from the IP interrupt enable register.  The bit definitions
+* are specific to the device IP.
+*
+* NOTES:
+*
+* Signature: u32 XIIF_V123B_READ_IIER(u32 RegBaseAddress)
+*
+******************************************************************************/
+#define XIIF_V123B_READ_IIER(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_IIER_OFFSET)
+
+/************************** Function Prototypes ******************************/
+
+/*
+ * Initialization Functions
+ */
+XStatus XIpIfV123b_SelfTest(u32 RegBaseAddress, u8 IpRegistersWidth);
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xpacket_fifo_l_v2_00_a.c linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xpacket_fifo_l_v2_00_a.c
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xpacket_fifo_l_v2_00_a.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xpacket_fifo_l_v2_00_a.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,839 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/*
+*
+* @file xpacket_fifo_l_v2_00_a.c
+*
+* Contains low-level (Level 0) functions for the XPacketFifoV200a driver.
+* See xpacket_fifo_v2_00_a.h for information about the high-level (Level 1)
+* driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ------------------------------------------------------
+* 2.00a rpm  10/22/03  First release. Moved most of Level 1 driver functions
+*                      into this layer.
+* 2.00a rmm  02/24/04  Added L0WriteDRE function.
+* </pre>
+*
+*****************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+#include "xpacket_fifo_l_v2_00_a.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************* Variable Definitions ******************************/
+
+/************************** Function Prototypes ******************************/
+
+static XStatus Write32(u32 RegBaseAddress, u32 DataBaseAddress,
+		       u8 * BufferPtr, u32 ByteCount);
+
+static XStatus Write64(u32 RegBaseAddress, u32 DataBaseAddress,
+		       u8 * BufferPtr, u32 ByteCount);
+
+static XStatus Read32(u32 RegBaseAddress, u32 DataBaseAddress,
+		      u8 * BufferPtr, u32 ByteCount);
+
+static XStatus Read64(u32 RegBaseAddress, u32 DataBaseAddress,
+		      u8 * BufferPtr, u32 ByteCount);
+
+/*****************************************************************************/
+/*
+*
+* Read data from a FIFO and puts it into a specified buffer. The packet FIFO is
+* currently 32 or 64 bits wide such that an input buffer which is a series of
+* bytes is filled from the FIFO a word at a time. If the requested byte count
+* is not a multiple of 32/64 bit words, it is necessary for this function to
+* format the remaining 32/64 bit word from the FIFO into a series of bytes in
+* the buffer. There may be up to 3/7 extra bytes which must be extracted from
+* the last word of the FIFO and put into the buffer.
+*
+* @param RegBaseAddress is the base address of the FIFO registers.
+* @param DataBaseAddress is the base address of the FIFO keyhole.
+* @param BufferPtr points to the memory buffer to write the data into. This
+*        buffer must be 32 bit aligned or an alignment exception could be
+*        generated. Since this buffer is a byte buffer, the data is assumed to
+*        be endian independent.
+* @param ByteCount contains the number of bytes to read from the FIFO. This
+*        number of bytes must be present in the FIFO or an error will be
+*        returned.
+*
+* @return
+*
+* XST_SUCCESS indicates the operation was successful.  If the number of
+* bytes specified by the byte count is not present in the FIFO
+* XST_PFIFO_LACK_OF_DATA is returned.
+*
+* If the function was successful, the specified buffer is modified to contain
+* the bytes which were removed from the FIFO.
+*
+* @note
+*
+* Note that the exact number of bytes which are present in the FIFO is
+* not known by this function.  It can only check for a number of 32/64 bit
+* words such that if the byte count specified is incorrect, but is still
+* possible based on the number of words in the FIFO, up to 3/7 garbage bytes
+* may be present at the end of the buffer.
+* <br><br>
+* This function assumes that if the device consuming data from the FIFO is
+* a byte device, the order of the bytes to be consumed is from the most
+* significant byte to the least significant byte of a 32/64 bit word removed
+* from the FIFO.
+*
+******************************************************************************/
+XStatus
+XPacketFifoV200a_L0Read(u32 RegBaseAddress, u32 DataBaseAddress,
+			u8 * BufferPtr, u32 ByteCount)
+{
+	u32 Width;
+	XStatus Result = XST_FIFO_ERROR;
+
+	/* determine the width of the FIFO
+	 */
+	Width = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+	    XPF_V200A_FIFO_WIDTH_MASK;
+
+	if ((Width == XPF_V200A_FIFO_WIDTH_LEGACY_TYPE) ||
+	    (Width == XPF_V200A_FIFO_WIDTH_32BITS_TYPE)) {
+		Result =
+		    Read32(RegBaseAddress, DataBaseAddress, BufferPtr,
+			   ByteCount);
+	} else if (Width == XPF_V200A_FIFO_WIDTH_64BITS_TYPE) {
+		Result =
+		    Read64(RegBaseAddress, DataBaseAddress, BufferPtr,
+			   ByteCount);
+	}
+
+	return Result;
+
+}
+
+/*****************************************************************************/
+/*
+*
+* Write data into a packet FIFO. The packet FIFO is currently 32 or 64 bits
+* wide such that an input buffer which is a series of bytes must be written
+* into the FIFO a word at a time. If the buffer is not a multiple of 32 bit
+* words, it is necessary for this function to format the remaining bytes into
+* a single 32 bit word to be inserted into the FIFO. This is necessary to
+* avoid any accesses past the end of the buffer.
+*
+* @param RegBaseAddress is the base address of the FIFO registers.
+* @param DataBaseAddress is the base address of the FIFO keyhole.
+* @param BufferPtr points to the memory buffer that data is to be read from
+*        and written into the FIFO. Since this buffer is a byte buffer, the
+*        data is assumed to be endian independent. This buffer must be 32 bit
+*        aligned or an alignment exception could be generated.
+* @param ByteCount contains the number of bytes to read from the buffer and to
+*        write to the FIFO.
+*
+* @return
+*
+* XST_SUCCESS is returned if the operation succeeded.  If there is not enough
+* room in the FIFO to hold the specified bytes, XST_PFIFO_NO_ROOM is
+* returned.
+*
+* @note
+*
+* This function assumes that if the device inserting data into the FIFO is
+* a byte device, the order of the bytes in each 32/64 bit word is from the most
+* significant byte to the least significant byte.
+*
+******************************************************************************/
+XStatus
+XPacketFifoV200a_L0Write(u32 RegBaseAddress,
+			 u32 DataBaseAddress, u8 * BufferPtr, u32 ByteCount)
+{
+	u32 Width;
+	XStatus Result = XST_FIFO_ERROR;
+
+	/* determine the width of the FIFO
+	 */
+	Width = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+	    XPF_V200A_FIFO_WIDTH_MASK;
+
+	if ((Width == XPF_V200A_FIFO_WIDTH_LEGACY_TYPE) ||
+	    (Width == XPF_V200A_FIFO_WIDTH_32BITS_TYPE)) {
+		Result =
+		    Write32(RegBaseAddress, DataBaseAddress, BufferPtr,
+			    ByteCount);
+	} else if (Width == XPF_V200A_FIFO_WIDTH_64BITS_TYPE) {
+		Result =
+		    Write64(RegBaseAddress, DataBaseAddress, BufferPtr,
+			    ByteCount);
+	}
+
+	return Result;
+
+}
+
+/*****************************************************************************/
+/*
+*
+* Write data into a packet FIFO configured for the Data Realignment Engine
+* (DRE). A packet FIFO channel configured in this way will accept any
+* combination of byte, half-word, or word writes. The DRE will shift the data
+* into the correct byte lane.
+*
+* @param RegBaseAddress is the base address of the FIFO registers.
+* @param DataBaseAddress is the base address of the FIFO keyhole.
+* @param BufferPtr points to the memory buffer that data is to be read from
+*        and written into the FIFO. Since this buffer is a byte buffer, the
+*        data is assumed to be endian independent. There are no alignment
+*        restrictions.
+* @param ByteCount contains the number of bytes to read from the buffer and to
+*        write to the FIFO.
+*
+* @return
+*
+* XST_SUCCESS is returned if the operation succeeded.  If there is not enough
+* room in the FIFO to hold the specified bytes, XST_PFIFO_NO_ROOM is
+* returned.
+*
+* @note
+*
+* This function assumes that if the device inserting data into the FIFO is
+* a byte device, the order of the bytes in each 32/64 bit word is from the most
+* significant byte to the least significant byte.
+*
+******************************************************************************/
+XStatus
+XPacketFifoV200a_L0WriteDre(u32 RegBaseAddress,
+			    u32 DataBaseAddress, u8 * BufferPtr, u32 ByteCount)
+{
+	u32 FifoRoomLeft;
+	u32 BytesLeft;
+	u32 Width;
+
+	/* calculate how many slots are left in the FIFO
+	 */
+	FifoRoomLeft =
+	    XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET)
+	    & XPF_V200A_COUNT_MASK;
+
+	/* determine the width of the FIFO
+	 */
+	Width = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+	    XPF_V200A_FIFO_WIDTH_MASK;
+
+	/* from the width, determine how many bytes can be written to the FIFO
+	 */
+	if ((Width == XPF_V200A_FIFO_WIDTH_LEGACY_TYPE) ||
+	    (Width == XPF_V200A_FIFO_WIDTH_32BITS_TYPE)) {
+		FifoRoomLeft *= 4;
+	} else if (Width == XPF_V200A_FIFO_WIDTH_64BITS_TYPE) {
+		FifoRoomLeft *= 8;
+	}
+
+	/* Make sure there's enough room in the fifo */
+	if (FifoRoomLeft < ByteCount) {
+		return XST_PFIFO_NO_ROOM;
+	}
+
+	/* Determine the number of bytes to write until 32 bit alignment is
+	 * reached, then write those bytes to the fifo one byte at a time
+	 */
+	BytesLeft = (unsigned) BufferPtr % sizeof (u32);
+	ByteCount -= BytesLeft;
+	while (BytesLeft--) {
+		XIo_Out8(DataBaseAddress, *BufferPtr++);
+	}
+
+	/* Write as many 32 bit words as we can */
+	BytesLeft = ByteCount;
+	while (BytesLeft >= sizeof (u32)) {
+		XIo_Out32(DataBaseAddress, *(u32 *) BufferPtr);
+		BufferPtr += sizeof (u32);
+		BytesLeft -= sizeof (u32);
+	}
+
+	/* Write remaining bytes */
+	while (BytesLeft--) {
+		XIo_Out8(DataBaseAddress, *BufferPtr++);
+	}
+
+	return XST_SUCCESS;
+
+}
+
+/*****************************************************************************/
+/*
+*
+* Read data from a FIFO and puts it into a specified buffer. The packet FIFO
+* is 32 bits wide such that an input buffer which is a series of bytes is
+* filled from the FIFO a word at a time. If the requested byte count is not
+* a multiple of 32 bit words, it is necessary for this function to format the
+* remaining 32 bit word from the FIFO into a series of bytes in the buffer.
+* There may be up to 3 extra bytes which must be extracted from the last word
+* of the FIFO and put into the buffer.
+*
+* @param RegBaseAddress is the base address of the FIFO registers.
+* @param DataBaseAddress is the base address of the FIFO keyhole.
+* @param BufferPtr points to the memory buffer to write the data into. This
+*        buffer must be 32 bit aligned or an alignment exception could be
+*        generated. Since this buffer is a byte buffer, the data is assumed to
+*        be endian independent.
+* @param ByteCount contains the number of bytes to read from the FIFO. This
+*        number of bytes must be present in the FIFO or an error will be
+*        returned.
+*
+* @return
+*
+* XST_SUCCESS indicates the operation was successful.  If the number of
+* bytes specified by the byte count is not present in the FIFO
+* XST_PFIFO_LACK_OF_DATA is returned.
+*
+* If the function was successful, the specified buffer is modified to contain
+* the bytes which were removed from the FIFO.
+*
+* @note
+*
+* Note that the exact number of bytes which are present in the FIFO is
+* not known by this function.  It can only check for a number of 32 bit
+* words such that if the byte count specified is incorrect, but is still
+* possible based on the number of words in the FIFO, up to 3 garbage bytes
+* may be present at the end of the buffer.
+* <br><br>
+* This function assumes that if the device consuming data from the FIFO is
+* a byte device, the order of the bytes to be consumed is from the most
+* significant byte to the least significant byte of a 32 bit word removed
+* from the FIFO.
+*
+******************************************************************************/
+static XStatus
+Read32(u32 RegBaseAddress, u32 DataBaseAddress, u8 * BufferPtr, u32 ByteCount)
+{
+	u32 FifoCount;
+	u32 WordCount;
+	u32 ExtraByteCount;
+	u32 *WordBuffer = (u32 *) BufferPtr;
+
+	/* get the count of how many 32 bit words are in the FIFO, if there
+	 * aren't enough words to satisfy the request, return an error
+	 */
+
+	FifoCount =
+	    XIo_In32(RegBaseAddress +
+		     XPF_V200A_COUNT_STATUS_REG_OFFSET) & XPF_V200A_COUNT_MASK;
+
+	if ((FifoCount * XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT) < ByteCount) {
+		return XST_PFIFO_LACK_OF_DATA;
+	}
+
+	/* calculate the number of words to read from the FIFO before the word
+	 * containing the extra bytes, and calculate the number of extra bytes
+	 * the extra bytes are defined as those at the end of the buffer when
+	 * the buffer does not end on a 32 bit boundary
+	 */
+	WordCount = ByteCount / XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT;
+	ExtraByteCount = ByteCount % XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT;
+
+	/* Read the 32 bit words from the FIFO for all the buffer except the
+	 * last word which contains the extra bytes, the following code assumes
+	 * that the buffer is 32 bit aligned, otherwise an alignment exception
+	 * could be generated
+	 */
+	for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
+		WordBuffer[FifoCount] = XIo_In32(DataBaseAddress);
+	}
+
+	/* if there are extra bytes to handle, read the last word from the FIFO
+	 * and insert the extra bytes into the buffer
+	 */
+	if (ExtraByteCount > 0) {
+		u32 LastWord;
+		u8 *WordPtr;
+		u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount);
+
+		/* get the last word from the FIFO for the extra bytes */
+
+		LastWord = XIo_In32(DataBaseAddress);
+
+		/* one extra byte in the last word, put the byte into the next
+		 * location of the buffer, bytes in a word of the FIFO are ordered
+		 * from most significant byte to least
+		 */
+		WordPtr = (u8 *) & LastWord;
+		if (ExtraByteCount == 1) {
+			ExtraBytesBuffer[0] = WordPtr[0];
+		}
+
+		/* two extra bytes in the last word, put each byte into the next
+		 * two locations of the buffer
+		 */
+		else if (ExtraByteCount == 2) {
+			ExtraBytesBuffer[0] = WordPtr[0];
+			ExtraBytesBuffer[1] = WordPtr[1];
+		}
+		/* three extra bytes in the last word, put each byte into the next
+		 * three locations of the buffer
+		 */
+		else if (ExtraByteCount == 3) {
+			ExtraBytesBuffer[0] = WordPtr[0];
+			ExtraBytesBuffer[1] = WordPtr[1];
+			ExtraBytesBuffer[2] = WordPtr[2];
+		}
+	}
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/*
+*
+* Read data from a FIFO and puts it into a specified buffer. The packet FIFO
+* is 64 bits wide such that an input buffer which is a series of bytes is
+* filled from the FIFO a word at a time. If the requested byte count is not
+* a multiple of 64 bit words, it is necessary for this function to format the
+* remaining 64 bit word from the FIFO into a series of bytes in the buffer.
+* There may be up to 7 extra bytes which must be extracted from the last word
+* of the FIFO and put into the buffer.
+*
+* @param RegBaseAddress is the base address of the FIFO registers.
+* @param DataBaseAddress is the base address of the FIFO keyhole.
+* @param BufferPtr points to the memory buffer to write the data into. This
+*        buffer must be 32 bit aligned or an alignment exception could be
+*        generated. Since this buffer is a byte buffer, the data is assumed to
+*        be endian independent.
+* @param ByteCount contains the number of bytes to read from the FIFO. This
+*        number of bytes must be present in the FIFO or an error will be
+*        returned.
+*
+* @return
+*
+* XST_SUCCESS indicates the operation was successful.  If the number of
+* bytes specified by the byte count is not present in the FIFO
+* XST_PFIFO_LACK_OF_DATA is returned.
+*
+* If the function was successful, the specified buffer is modified to contain
+* the bytes which were removed from the FIFO.
+*
+* @note
+*
+* Note that the exact number of bytes which are present in the FIFO is
+* not known by this function.  It can only check for a number of 64 bit
+* words such that if the byte count specified is incorrect, but is still
+* possible based on the number of words in the FIFO, up to 7 garbage bytes
+* may be present at the end of the buffer.
+* <br><br>
+* This function assumes that if the device consuming data from the FIFO is
+* a byte device, the order of the bytes to be consumed is from the most
+* significant byte to the least significant byte of a 64 bit word removed
+* from the FIFO.
+*
+******************************************************************************/
+static XStatus
+Read64(u32 RegBaseAddress, u32 DataBaseAddress, u8 * BufferPtr, u32 ByteCount)
+{
+	u32 FifoCount;
+	u32 WordCount;
+	u32 ExtraByteCount;
+	u32 *WordBuffer = (u32 *) BufferPtr;
+
+	/* get the count of how many 64 bit words are in the FIFO, if there
+	 * aren't enought words to satisfy the request, return an error
+	 */
+
+	FifoCount =
+	    XIo_In32(RegBaseAddress +
+		     XPF_V200A_COUNT_STATUS_REG_OFFSET) & XPF_V200A_COUNT_MASK;
+
+	if ((FifoCount * XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT) < ByteCount) {
+		return XST_PFIFO_LACK_OF_DATA;
+	}
+
+	/* calculate the number of words to read from the FIFO before the word
+	 * containing the extra bytes, and calculate the number of extra bytes
+	 * the extra bytes are defined as those at the end of the buffer when
+	 * the buffer does not end on a 32 bit boundary
+	 */
+	WordCount = ByteCount / XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT;
+	ExtraByteCount = ByteCount % XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT;
+
+	/* Read the 64 bit words from the FIFO for all the buffer except the
+	 * last word which contains the extra bytes, the following code assumes
+	 * that the buffer is 32 bit aligned, otherwise an alignment exception
+	 * could be generated. The MSWord must be read first followed by the
+	 * LSWord
+	 */
+	for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
+		WordBuffer[(FifoCount * 2)] = XIo_In32(DataBaseAddress);
+		WordBuffer[(FifoCount * 2) + 1] = XIo_In32(DataBaseAddress + 4);
+	}
+
+	/* if there are extra bytes to handle, read the last word from the FIFO
+	 * and insert the extra bytes into the buffer
+	 */
+	if (ExtraByteCount > 0) {
+		u32 MSLastWord;
+		u32 LSLastWord;
+		u8 *WordPtr;
+		u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + (WordCount * 2));
+		u8 Index = 0;
+
+		/* get the last word from the FIFO for the extra bytes */
+
+		MSLastWord = XIo_In32(DataBaseAddress);
+		LSLastWord = XIo_In32(DataBaseAddress + 4);
+
+		/* four or more extra bytes in the last word, put the byte into
+		 * the next location of the buffer, bytes in a word of the FIFO
+		 * are ordered from most significant byte to least
+		 */
+		WordPtr = (u8 *) & MSLastWord;
+		if (ExtraByteCount >= 4) {
+			ExtraBytesBuffer[Index] = WordPtr[0];
+			ExtraBytesBuffer[Index + 1] = WordPtr[1];
+			ExtraBytesBuffer[Index + 2] = WordPtr[2];
+			ExtraBytesBuffer[Index + 3] = WordPtr[3];
+			ExtraByteCount = ExtraByteCount - 4;
+			MSLastWord = LSLastWord;
+			Index = 4;
+		}
+
+		/* one extra byte in the last word, put the byte into the next
+		 * location of the buffer, bytes in a word of the FIFO are
+		 * ordered from most significant byte to least
+		 */
+		if (ExtraByteCount == 1) {
+			ExtraBytesBuffer[Index] = WordPtr[0];
+		}
+
+		/* two extra bytes in the last word, put each byte into the next
+		 * two locations of the buffer
+		 */
+		else if (ExtraByteCount == 2) {
+			ExtraBytesBuffer[Index] = WordPtr[0];
+			ExtraBytesBuffer[Index + 1] = WordPtr[1];
+		}
+		/* three extra bytes in the last word, put each byte into the next
+		 * three ocations of the buffer
+		 */
+		else if (ExtraByteCount == 3) {
+			ExtraBytesBuffer[Index] = WordPtr[0];
+			ExtraBytesBuffer[Index + 1] = WordPtr[1];
+			ExtraBytesBuffer[Index + 2] = WordPtr[2];
+		}
+	}
+
+	return XST_SUCCESS;
+
+}
+
+/*****************************************************************************/
+/*
+*
+* Write data into a 32 bit packet FIFO. The packet FIFO is 32 bits wide in this
+* function call such that an input buffer which is a series of bytes must be
+* written into the FIFO a word at a time. If the buffer is not a multiple of
+* 32 bit words, it is necessary for this function to format the remaining bytes
+* into a single 32 bit word to be inserted into the FIFO. This is necessary to
+* avoid any accesses past the end of the buffer.
+*
+* @param RegBaseAddress is the base address of the FIFO registers.
+* @param DataBaseAddress is the base address of the FIFO keyhole.
+* @param BufferPtr points to the memory buffer that data is to be read from
+*        and written into the FIFO. Since this buffer is a byte buffer, the
+*        data is assumed to be endian independent. This buffer must be 32 bit
+*        aligned or an alignment exception could be generated.
+* @param ByteCount contains the number of bytes to read from the buffer and to
+*        write to the FIFO.
+*
+* @return
+*
+* XST_SUCCESS is returned if the operation succeeded.  If there is not enough
+* room in the FIFO to hold the specified bytes, XST_PFIFO_NO_ROOM is
+* returned.
+*
+* @note
+*
+* This function assumes that if the device inserting data into the FIFO is
+* a byte device, the order of the bytes in each 32 bit word is from the most
+* significant byte to the least significant byte.
+*
+******************************************************************************/
+static XStatus
+Write32(u32 RegBaseAddress, u32 DataBaseAddress, u8 * BufferPtr, u32 ByteCount)
+{
+	u32 FifoCount;
+	u32 WordCount;
+	u32 ExtraByteCount;
+	u32 *WordBuffer = (u32 *) BufferPtr;
+
+	/* get the count of how many words may be inserted into the FIFO */
+
+	FifoCount =
+	    XIo_In32(RegBaseAddress +
+		     XPF_V200A_COUNT_STATUS_REG_OFFSET) & XPF_V200A_COUNT_MASK;
+
+	/* Calculate the number of 32 bit words required to insert the
+	 * specified number of bytes in the FIFO and determine the number
+	 * of extra bytes if the buffer length is not a multiple of 32 bit
+	 * words
+	 */
+
+	WordCount = ByteCount / XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT;
+	ExtraByteCount = ByteCount % XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT;
+
+	/* take into account the extra bytes in the total word count */
+
+	if (ExtraByteCount > 0) {
+		WordCount++;
+	}
+
+	/* if there's not enough room in the FIFO to hold the specified
+	 * number of bytes, then indicate an error,
+	 */
+	if (FifoCount < WordCount) {
+		return XST_PFIFO_NO_ROOM;
+	}
+
+	/* readjust the word count to not take into account the extra bytes */
+
+	if (ExtraByteCount > 0) {
+		WordCount--;
+	}
+
+	/* Write all the bytes of the buffer which can be written as 32 bit
+	 * words into the FIFO, waiting to handle the extra bytes seperately
+	 */
+	for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
+		XIo_Out32(DataBaseAddress, WordBuffer[FifoCount]);
+	}
+
+	/* if there are extra bytes to handle, extract them from the buffer
+	 * and create a 32 bit word and write it to the FIFO
+	 */
+	if (ExtraByteCount > 0) {
+		u32 LastWord = 0;
+		u8 *WordPtr;
+		u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount);
+
+		/* one extra byte in the buffer, put the byte into the last word
+		 * to be inserted into the FIFO, perform this processing inline
+		 * rather than in a loop to help performance
+		 */
+		WordPtr = (u8 *) & LastWord;
+		if (ExtraByteCount == 1) {
+			WordPtr[0] = ExtraBytesBuffer[0];
+		}
+
+		/* two extra bytes in the buffer, put each byte into the last word
+		 * to be inserted into the FIFO
+		 */
+		else if (ExtraByteCount == 2) {
+			WordPtr[0] = ExtraBytesBuffer[0];
+			WordPtr[1] = ExtraBytesBuffer[1];
+		}
+
+		/* three extra bytes in the buffer, put each byte into the last
+		 * word to be inserted into the FIFO
+		 */
+		else if (ExtraByteCount == 3) {
+			WordPtr[0] = ExtraBytesBuffer[0];
+			WordPtr[1] = ExtraBytesBuffer[1];
+			WordPtr[2] = ExtraBytesBuffer[2];
+		}
+
+		/* write the last 32 bit word to the FIFO and return with
+		 * no errors
+		 */
+
+		XIo_Out32(DataBaseAddress, LastWord);
+	}
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/*
+*
+* Write data into a 64 bit packet FIFO. The packet FIFO is 64 bits wide in this
+* function call such that an input buffer which is a series of bytes must be
+* written into the FIFO a word at a time. If the buffer is not a multiple of
+* 64 bit words, it is necessary for this function to format the remaining bytes
+* into two 32 bit words to be inserted into the FIFO. This is necessary to
+* avoid any accesses past the end of the buffer.
+*
+* @param RegBaseAddress is the base address of the FIFO registers.
+* @param DataBaseAddress is the base address of the FIFO keyhole.
+* @param BufferPtr points to the memory buffer that data is to be read from
+*        and written into the FIFO. Since this buffer is a byte buffer, the
+*        data is assumed to be endian independent. This buffer must be 32 bit
+*        aligned or an alignment exception could be generated.
+* @param ByteCount contains the number of bytes to read from the buffer and to
+*        write to the FIFO.
+*
+* @return
+*
+* XST_SUCCESS is returned if the operation succeeded.  If there is not enough
+* room in the FIFO to hold the specified bytes, XST_PFIFO_NO_ROOM is
+* returned.
+*
+* @note
+*
+* This function assumes that if the device inserting data into the FIFO is
+* a byte device, the order of the bytes in each 64 bit word is from the most
+* significant byte to the least significant byte.
+*
+******************************************************************************/
+static XStatus
+Write64(u32 RegBaseAddress, u32 DataBaseAddress, u8 * BufferPtr, u32 ByteCount)
+{
+	u32 FifoCount;
+	u32 WordCount;
+	u32 ExtraByteCount;
+	u32 *WordBuffer = (u32 *) BufferPtr;
+
+	/* get the count of how many words may be inserted into the FIFO */
+
+	FifoCount =
+	    XIo_In32(RegBaseAddress +
+		     XPF_V200A_COUNT_STATUS_REG_OFFSET) & XPF_V200A_COUNT_MASK;
+
+	/* Calculate the number of 64 bit words required to insert the
+	 * specified number of bytes in the FIFO and determine the number
+	 * of extra bytes if the buffer length is not a multiple of 64 bit
+	 * words
+	 */
+
+	WordCount = ByteCount / XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT;
+	ExtraByteCount = ByteCount % XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT;
+
+	/* take into account the extra bytes in the total word count */
+
+	if (ExtraByteCount > 0) {
+		WordCount++;
+	}
+
+	/* if there's not enough room in the FIFO to hold the specified
+	 * number of bytes, then indicate an error,
+	 */
+	if (FifoCount < WordCount) {
+		return XST_PFIFO_NO_ROOM;
+	}
+
+	/* readjust the word count to not take into account the extra bytes */
+
+	if (ExtraByteCount > 0) {
+		WordCount--;
+	}
+
+	/* Write all the bytes of the buffer which can be written as 32 bit
+	 * words into the FIFO, waiting to handle the extra bytes seperately
+	 * The MSWord must be written first followed by the LSWord
+	 */
+	for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
+		XIo_Out32(DataBaseAddress, WordBuffer[(FifoCount * 2)]);
+		XIo_Out32(DataBaseAddress + 4, WordBuffer[(FifoCount * 2) + 1]);
+	}
+
+	/* if there are extra bytes to handle, extract them from the buffer
+	 * and create two 32 bit words and write to the FIFO
+	 */
+	if (ExtraByteCount > 0) {
+
+		u32 MSLastWord = 0;
+		u32 LSLastWord = 0;
+		u8 Index = 0;
+		u8 *WordPtr;
+		u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + (WordCount * 2));
+
+		/* four extra bytes in the buffer, put the bytes into the last word
+		 * to be inserted into the FIFO, perform this processing inline
+		 * rather than in a loop to help performance
+		 */
+		WordPtr = (u8 *) & MSLastWord;
+
+		if (ExtraByteCount >= 4) {
+			WordPtr[0] = ExtraBytesBuffer[Index];
+			WordPtr[1] = ExtraBytesBuffer[Index + 1];
+			WordPtr[2] = ExtraBytesBuffer[Index + 2];
+			WordPtr[3] = ExtraBytesBuffer[Index + 3];
+			ExtraByteCount = ExtraByteCount - 4;
+			WordPtr = (u8 *) & LSLastWord;
+			Index = 4;
+		}
+
+		/* one extra byte in the buffer, put the byte into the last word
+		 * to be inserted into the FIFO, perform this processing inline
+		 * rather than in a loop to help performance
+		 */
+		if (ExtraByteCount == 1) {
+			WordPtr[0] = ExtraBytesBuffer[Index];
+		}
+
+		/* two extra bytes in the buffer, put each byte into the last word
+		 * to be inserted into the FIFO
+		 */
+		else if (ExtraByteCount == 2) {
+			WordPtr[0] = ExtraBytesBuffer[Index];
+			WordPtr[1] = ExtraBytesBuffer[Index + 1];
+		}
+
+		/* three extra bytes in the buffer, put each byte into the last
+		 * word to be inserted into the FIFO
+		 */
+		else if (ExtraByteCount == 3) {
+			WordPtr[0] = ExtraBytesBuffer[Index];
+			WordPtr[1] = ExtraBytesBuffer[Index + 1];
+			WordPtr[2] = ExtraBytesBuffer[Index + 2];
+		}
+
+		/* write the last 64 bit word to the FIFO and return with no errors
+		 * The MSWord must be written first followed by the LSWord
+		 */
+		XIo_Out32(DataBaseAddress, MSLastWord);
+		XIo_Out32(DataBaseAddress + 4, LSLastWord);
+	}
+
+	return XST_SUCCESS;
+}
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xpacket_fifo_l_v2_00_a.h linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xpacket_fifo_l_v2_00_a.h
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xpacket_fifo_l_v2_00_a.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xpacket_fifo_l_v2_00_a.h	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,137 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/*
+*
+* @file xpacket_fifo_l_v2_00_a.h
+*
+* This header file contains identifiers and low-level (Level 0) driver
+* functions (or macros) that can be used to access the FIFO.  High-level driver
+* (Level 1) functions are defined in xpacket_fifo_v2_00_a.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ------------------------------------------------------
+* 2.00a rpm  10/22/03  First release. Moved most of Level 1 driver functions
+*                      into this layer.
+* 2.00a rmm  02/24/04  Added L0WriteDre function.
+* </pre>
+*
+*****************************************************************************/
+#ifndef XPACKET_FIFO_L_V200A_H	/* prevent circular inclusions */
+#define XPACKET_FIFO_L_V200A_H	/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * These constants specify the FIFO type and are mutually exclusive
+ */
+#define XPF_V200A_READ_FIFO_TYPE      0	/* a read FIFO */
+#define XPF_V200A_WRITE_FIFO_TYPE     1	/* a write FIFO */
+
+/*
+ * These constants define the offsets to each of the registers from the
+ * register base address, each of the constants are a number of bytes
+ */
+#define XPF_V200A_RESET_REG_OFFSET            0UL
+#define XPF_V200A_MODULE_INFO_REG_OFFSET      0UL
+#define XPF_V200A_COUNT_STATUS_REG_OFFSET     4UL
+
+/*
+ * This constant is used with the Reset Register
+ */
+#define XPF_V200A_RESET_FIFO_MASK             0x0000000A
+
+/*
+ * These constants are used with the Occupancy/Vacancy Count Register. This
+ * register also contains FIFO status
+ */
+#define XPF_V200A_COUNT_MASK                  0x00FFFFFF
+#define XPF_V200A_DEADLOCK_MASK               0x20000000
+#define XPF_V200A_ALMOST_EMPTY_FULL_MASK      0x40000000
+#define XPF_V200A_EMPTY_FULL_MASK             0x80000000
+#define XPF_V200A_VACANCY_SCALED_MASK         0x10000000
+
+/*
+ * This constant is used to mask the Width field
+ */
+#define XPF_V200A_FIFO_WIDTH_MASK             0x0E000000
+
+/*
+ * These constants are used with the Width field
+ */
+#define XPF_V200A_FIFO_WIDTH_LEGACY_TYPE      0x00000000
+#define XPF_V200A_FIFO_WIDTH_8BITS_TYPE       0x02000000
+#define XPF_V200A_FIFO_WIDTH_16BITS_TYPE      0x04000000
+#define XPF_V200A_FIFO_WIDTH_32BITS_TYPE      0x06000000
+#define XPF_V200A_FIFO_WIDTH_64BITS_TYPE      0x08000000
+#define XPF_V200A_FIFO_WIDTH_128BITS_TYPE     0x0A000000
+#define XPF_V200A_FIFO_WIDTH_256BITS_TYPE     0x0C000000
+#define XPF_V200A_FIFO_WIDTH_512BITS_TYPE     0x0E000000
+
+/* Width of a FIFO word */
+#define XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT       4
+#define XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT       8
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+XStatus XPacketFifoV200a_L0Read(u32 RegBaseAddress,
+				u32 DataBaseAddress,
+				u8 * ReadBufferPtr, u32 ByteCount);
+
+XStatus XPacketFifoV200a_L0Write(u32 RegBaseAddress,
+				 u32 DataBaseAddress,
+				 u8 * WriteBufferPtr, u32 ByteCount);
+
+XStatus XPacketFifoV200a_L0WriteDre(u32 RegBaseAddress,
+				    u32 DataBaseAddress,
+				    u8 * BufferPtr, u32 ByteCount);
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xpacket_fifo_v1_00_b.c linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xpacket_fifo_v1_00_b.c
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xpacket_fifo_v1_00_b.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xpacket_fifo_v1_00_b.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,424 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2003 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/*
+*
+* @file xpacket_fifo_v1_00_b.c
+*
+* Contains functions for the XPacketFifoV100b component. See xpacket_fifo_v1_00_b.h
+* for more information about the component.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00b rpm 03/26/02  First release
+* </pre>
+*
+*****************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+#include "xstatus.h"
+#include "xpacket_fifo_v1_00_b.h"
+#include <asm/unaligned.h>
+
+
+/************************** Constant Definitions *****************************/
+
+/* width of a FIFO word */
+
+#define XPF_FIFO_WIDTH_BYTE_COUNT       4UL
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************* Variable Definitions ******************************/
+
+/************************** Function Prototypes ******************************/
+
+/*****************************************************************************/
+/*
+*
+* This function initializes a packet FIFO.  Initialization resets the
+* FIFO such that it's empty and ready to use.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+* @param RegBaseAddress contains the base address of the registers for
+*        the packet FIFO.
+* @param DataBaseAddress contains the base address of the data for
+*        the packet FIFO.
+*
+* @return
+*
+* Always returns XST_SUCCESS.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XPacketFifoV100b_Initialize(XPacketFifoV100b * InstancePtr,
+			    u32 RegBaseAddress, u32 DataBaseAddress)
+{
+	/* initialize the component variables to the specified state */
+
+	InstancePtr->RegBaseAddress = RegBaseAddress;
+	InstancePtr->DataBaseAddress = DataBaseAddress;
+	InstancePtr->IsReady = XCOMPONENT_IS_READY;
+
+	/* reset the FIFO such that it's empty and ready to use and indicate the
+	 * initialization was successful, note that the is ready variable must be
+	 * set prior to calling the reset function to prevent an assert
+	 */
+	XPF_V100B_RESET(InstancePtr);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/*
+*
+* This function performs a self-test on the specified packet FIFO.  The self
+* test resets the FIFO and reads a register to determine if it is the correct
+* reset value.  This test is destructive in that any data in the FIFO will
+* be lost.
+*
+* @param InstancePtr is a pointer to the packet FIFO to be operated on.
+*
+* @param FifoType specifies the type of FIFO, read or write, for the self test.
+*        The FIFO type is specified by the values XPF_READ_FIFO_TYPE or
+*        XPF_WRITE_FIFO_TYPE.
+*
+* @return
+*
+* XST_SUCCESS is returned if the selftest is successful, or
+* XST_PFIFO_BAD_REG_VALUE indicating that the value readback from the
+* occupancy/vacancy count register after a reset does not match the
+* specified reset value.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XPacketFifoV100b_SelfTest(XPacketFifoV100b * InstancePtr, u32 FifoType)
+{
+	u32 Register;
+
+	/* reset the fifo and then check to make sure the occupancy/vacancy
+	 * register contents are correct for a reset condition
+	 */
+	XPF_V100B_RESET(InstancePtr);
+
+	Register = XIo_In32(InstancePtr->RegBaseAddress +
+			    XPF_COUNT_STATUS_REG_OFFSET);
+
+	/* check the value of the register to ensure that it's correct for the
+	 * specified FIFO type since both FIFO types reset to empty, but a bit
+	 * in the register changes definition based upon FIFO type
+	 */
+
+	if (FifoType == XPF_READ_FIFO_TYPE) {
+		/* check the regiser value for a read FIFO which should be empty */
+
+		if (Register != XPF_EMPTY_FULL_MASK) {
+			return XST_PFIFO_BAD_REG_VALUE;
+		}
+	} else {
+		/* check the register value for a write FIFO which should not be full
+		 * on reset
+		 */
+		if ((Register & XPF_EMPTY_FULL_MASK) != 0) {
+			return XST_PFIFO_BAD_REG_VALUE;
+		}
+	}
+
+	/* the test was successful */
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/*
+*
+* Read data from a FIFO and puts it into a specified buffer. The packet FIFO is
+* currently 32 bits wide such that an input buffer which is a series of bytes
+* is filled from the FIFO a word at a time. If the requested byte count is not
+* a multiple of 32 bit words, it is necessary for this function to format the
+* remaining 32 bit word from the FIFO into a series of bytes in the buffer.
+* There may be up to 3 extra bytes which must be extracted from the last word
+* of the FIFO and put into the buffer.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+* @param BufferPtr points to the memory buffer to write the data into. This
+*        buffer must be 32 bit aligned or an alignment exception could be
+*        generated. Since this buffer is a byte buffer, the data is assumed to
+*        be endian independent.
+* @param ByteCount contains the number of bytes to read from the FIFO. This
+*        number of bytes must be present in the FIFO or an error will be
+*        returned.
+*
+* @return
+*
+* XST_SUCCESS indicates the operation was successful.  If the number of
+* bytes specified by the byte count is not present in the FIFO
+* XST_PFIFO_LACK_OF_DATA is returned.
+*
+* If the function was successful, the specified buffer is modified to contain
+* the bytes which were removed from the FIFO.
+*
+* @note
+*
+* Note that the exact number of bytes which are present in the FIFO is
+* not known by this function.  It can only check for a number of 32 bit
+* words such that if the byte count specified is incorrect, but is still
+* possible based on the number of words in the FIFO, up to 3 garbage bytes
+* may be present at the end of the buffer.
+* <br><br>
+* This function assumes that if the device consuming data from the FIFO is
+* a byte device, the order of the bytes to be consumed is from the most
+* significant byte to the least significant byte of a 32 bit word removed
+* from the FIFO.
+*
+******************************************************************************/
+XStatus
+XPacketFifoV100b_Read(XPacketFifoV100b * InstancePtr,
+		      u8 * BufferPtr, u32 ByteCount)
+{
+	u32 FifoCount;
+	u32 WordCount;
+	u32 ExtraByteCount;
+	u32 *WordBuffer = (u32 *) BufferPtr;
+
+	/* assert to verify valid input arguments including 32 bit alignment of
+	 * the buffer pointer
+	 */
+
+	/* get the count of how many 32 bit words are in the FIFO, if there aren't
+	 * enought words to satisfy the request, return an error
+	 */
+
+	FifoCount = XIo_In32(InstancePtr->RegBaseAddress +
+			     XPF_COUNT_STATUS_REG_OFFSET) & XPF_COUNT_MASK;
+
+	if ((FifoCount * XPF_FIFO_WIDTH_BYTE_COUNT) < ByteCount) {
+		return XST_PFIFO_LACK_OF_DATA;
+	}
+
+	/* calculate the number of words to read from the FIFO before the word
+	 * containing the extra bytes, and calculate the number of extra bytes
+	 * the extra bytes are defined as those at the end of the buffer when
+	 * the buffer does not end on a 32 bit boundary
+	 */
+	WordCount = ByteCount / XPF_FIFO_WIDTH_BYTE_COUNT;
+	ExtraByteCount = ByteCount % XPF_FIFO_WIDTH_BYTE_COUNT;
+
+	/* Read the 32 bit words from the FIFO for all the buffer except the
+	 * last word which contains the extra bytes, the following code assumes
+	 * that the buffer is 32 bit aligned, otherwise an alignment exception could
+	 * be generated
+	 */
+	for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
+		WordBuffer[FifoCount] = XIo_In32(InstancePtr->DataBaseAddress);
+/* 		put_unaligned(XIo_In32(InstancePtr->DataBaseAddress),WordBuffer+FifoCount); */
+	}
+
+	/* if there are extra bytes to handle, read the last word from the FIFO
+	 * and insert the extra bytes into the buffer
+	 */
+	if (ExtraByteCount > 0) {
+		u32 LastWord;
+		u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount);
+
+		/* get the last word from the FIFO for the extra bytes */
+
+		LastWord = XIo_In32(InstancePtr->DataBaseAddress);
+
+		/* one extra byte in the last word, put the byte into the next location
+		 * of the buffer, bytes in a word of the FIFO are ordered from most
+		 * significant byte to least
+		 */
+		if (ExtraByteCount == 1) {
+			ExtraBytesBuffer[0] = (u8) (LastWord >> 24);
+		}
+
+		/* two extra bytes in the last word, put each byte into the next two
+		 * locations of the buffer
+		 */
+		else if (ExtraByteCount == 2) {
+			ExtraBytesBuffer[0] = (u8) (LastWord >> 24);
+			ExtraBytesBuffer[1] = (u8) (LastWord >> 16);
+		}
+		/* three extra bytes in the last word, put each byte into the next three
+		 * locations of the buffer
+		 */
+		else if (ExtraByteCount == 3) {
+			ExtraBytesBuffer[0] = (u8) (LastWord >> 24);
+			ExtraBytesBuffer[1] = (u8) (LastWord >> 16);
+			ExtraBytesBuffer[2] = (u8) (LastWord >> 8);
+		}
+	}
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/*
+*
+* Write data into a packet FIFO. The packet FIFO is currently 32 bits wide
+* such that an input buffer which is a series of bytes must be written into the
+* FIFO a word at a time. If the buffer is not a multiple of 32 bit words, it is
+* necessary for this function to format the remaining bytes into a single 32
+* bit word to be inserted into the FIFO. This is necessary to avoid any
+* accesses past the end of the buffer.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+* @param BufferPtr points to the memory buffer that data is to be read from
+*        and written into the FIFO. Since this buffer is a byte buffer, the data
+*        is assumed to be endian independent. This buffer must be 32 bit aligned
+*        or an alignment exception could be generated.
+* @param ByteCount contains the number of bytes to read from the buffer and to
+*        write to the FIFO.
+*
+* @return
+*
+* XST_SUCCESS is returned if the operation succeeded.  If there is not enough
+* room in the FIFO to hold the specified bytes, XST_PFIFO_NO_ROOM is
+* returned.
+*
+* @note
+*
+* This function assumes that if the device inserting data into the FIFO is
+* a byte device, the order of the bytes in each 32 bit word is from the most
+* significant byte to the least significant byte.
+*
+******************************************************************************/
+XStatus
+XPacketFifoV100b_Write(XPacketFifoV100b * InstancePtr,
+		       u8 * BufferPtr, u32 ByteCount)
+{
+	u32 FifoCount;
+	u32 WordCount;
+	u32 ExtraByteCount;
+	u32 *WordBuffer = (u32 *) BufferPtr;
+
+	/* get the count of how many words may be inserted into the FIFO */
+
+	FifoCount = XIo_In32(InstancePtr->RegBaseAddress +
+			     XPF_COUNT_STATUS_REG_OFFSET) & XPF_COUNT_MASK;
+
+	/* Calculate the number of 32 bit words required to insert the specified
+	 * number of bytes in the FIFO and determine the number of extra bytes
+	 * if the buffer length is not a multiple of 32 bit words
+	 */
+
+	WordCount = ByteCount / XPF_FIFO_WIDTH_BYTE_COUNT;
+	ExtraByteCount = ByteCount % XPF_FIFO_WIDTH_BYTE_COUNT;
+
+	/* take into account the extra bytes in the total word count */
+
+	if (ExtraByteCount > 0) {
+		WordCount++;
+	}
+
+	/* if there's not enough room in the FIFO to hold the specified
+	 * number of bytes, then indicate an error,
+	 */
+	if (FifoCount < WordCount) {
+		return XST_PFIFO_NO_ROOM;
+	}
+
+	/* readjust the word count to not take into account the extra bytes */
+
+	if (ExtraByteCount > 0) {
+		WordCount--;
+	}
+
+	/* Write all the bytes of the buffer which can be written as 32 bit
+	 * words into the FIFO, waiting to handle the extra bytes seperately
+	 */
+	for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
+		XIo_Out32(InstancePtr->DataBaseAddress, WordBuffer[FifoCount]);
+	}
+
+	/* if there are extra bytes to handle, extract them from the buffer
+	 * and create a 32 bit word and write it to the FIFO
+	 */
+	if (ExtraByteCount > 0) {
+		u32 LastWord = 0;
+		u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount);
+
+		/* one extra byte in the buffer, put the byte into the last word
+		 * to be inserted into the FIFO, perform this processing inline rather
+		 * than in a loop to help performance
+		 */
+		if (ExtraByteCount == 1) {
+			LastWord = ExtraBytesBuffer[0] << 24;
+		}
+
+		/* two extra bytes in the buffer, put each byte into the last word
+		 * to be inserted into the FIFO
+		 */
+		else if (ExtraByteCount == 2) {
+			LastWord = ExtraBytesBuffer[0] << 24 |
+			    ExtraBytesBuffer[1] << 16;
+		}
+
+		/* three extra bytes in the buffer, put each byte into the last word
+		 * to be inserted into the FIFO
+		 */
+		else if (ExtraByteCount == 3) {
+			LastWord = ExtraBytesBuffer[0] << 24 |
+			    ExtraBytesBuffer[1] << 16 |
+			    ExtraBytesBuffer[2] << 8;
+		}
+
+		/* write the last 32 bit word to the FIFO and return with no errors */
+
+		XIo_Out32(InstancePtr->DataBaseAddress, LastWord);
+	}
+
+	return XST_SUCCESS;
+}
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xpacket_fifo_v1_00_b.h linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xpacket_fifo_v1_00_b.h
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xpacket_fifo_v1_00_b.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xpacket_fifo_v1_00_b.h	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,306 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2003 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/*
+*
+* @file xpacket_fifo_v1_00_b.h
+*
+* This component is a common component because it's primary purpose is to
+* prevent code duplication in drivers. A driver which must handle a packet
+* FIFO uses this component rather than directly manipulating a packet FIFO.
+*
+* A FIFO is a device which has dual port memory such that one user may be
+* inserting data into the FIFO while another is consuming data from the FIFO.
+* A packet FIFO is designed for use with packet protocols such as Ethernet and
+* ATM.  It is typically only used with devices when DMA and/or Scatter Gather
+* is used.  It differs from a nonpacket FIFO in that it does not provide any
+* interrupts for thresholds of the FIFO such that it is less useful without
+* DMA.
+*
+* @note
+*
+* This component has the capability to generate an interrupt when an error
+* condition occurs.  It is the user's responsibility to provide the interrupt
+* processing to handle the interrupt. This component provides the ability to
+* determine if that interrupt is active, a deadlock condition, and the ability
+* to reset the FIFO to clear the condition. In this condition, the device which
+* is using the FIFO should also be reset to prevent other problems. This error
+* condition could occur as a normal part of operation if the size of the FIFO
+* is not setup correctly.  See the hardware IP specification for more details.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00b rpm 03/26/02  First release
+* </pre>
+*
+*****************************************************************************/
+#ifndef XPACKET_FIFO_H		/* prevent circular inclusions */
+#define XPACKET_FIFO_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * These constants specify the FIFO type and are mutually exclusive
+ */
+#define XPF_READ_FIFO_TYPE      0	/* a read FIFO */
+#define XPF_WRITE_FIFO_TYPE     1	/* a write FIFO */
+
+/*
+ * These constants define the offsets to each of the registers from the
+ * register base address, each of the constants are a number of bytes
+ */
+#define XPF_RESET_REG_OFFSET            0UL
+#define XPF_MODULE_INFO_REG_OFFSET      0UL
+#define XPF_COUNT_STATUS_REG_OFFSET     4UL
+
+/*
+ * This constant is used with the Reset Register
+ */
+#define XPF_RESET_FIFO_MASK             0x0000000A
+
+/*
+ * These constants are used with the Occupancy/Vacancy Count Register. This
+ * register also contains FIFO status
+ */
+#define XPF_COUNT_MASK                  0x0000FFFF
+#define XPF_DEADLOCK_MASK               0x20000000
+#define XPF_ALMOST_EMPTY_FULL_MASK      0x40000000
+#define XPF_EMPTY_FULL_MASK             0x80000000
+
+/**************************** Type Definitions *******************************/
+
+/*
+ * The XPacketFifo driver instance data. The driver is required to allocate a
+ * variable of this type for every packet FIFO in the device.
+ */
+typedef struct {
+	u32 RegBaseAddress;	/* Base address of registers */
+	u32 IsReady;		/* Device is initialized and ready */
+	u32 DataBaseAddress;	/* Base address of data for FIFOs */
+} XPacketFifoV100b;
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/*
+*
+* Reset the specified packet FIFO.  Resetting a FIFO will cause any data
+* contained in the FIFO to be lost.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XPF_V100B_RESET(XPacketFifoV100b *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V100B_RESET(InstancePtr) \
+    XIo_Out32((InstancePtr)->RegBaseAddress + XPF_RESET_REG_OFFSET, XPF_RESET_FIFO_MASK);
+
+/*****************************************************************************/
+/*
+*
+* Get the occupancy count for a read packet FIFO and the vacancy count for a
+* write packet FIFO. These counts indicate the number of 32-bit words
+* contained (occupancy) in the FIFO or the number of 32-bit words available
+* to write (vacancy) in the FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* The occupancy or vacancy count for the specified packet FIFO.
+*
+* @note
+*
+* Signature: u32 XPF_V100B_GET_COUNT(XPacketFifoV100b *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V100B_GET_COUNT(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
+    XPF_COUNT_MASK)
+
+/*****************************************************************************/
+/*
+*
+* Determine if the specified packet FIFO is almost empty. Almost empty is
+* defined for a read FIFO when there is only one data word in the FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is almost empty, FALSE otherwise.
+*
+* @note
+*
+* Signature: u32 XPF_V100B_IS_ALMOST_EMPTY(XPacketFifoV100b *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V100B_IS_ALMOST_EMPTY(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
+    XPF_ALMOST_EMPTY_FULL_MASK)
+
+/*****************************************************************************/
+/*
+*
+* Determine if the specified packet FIFO is almost full. Almost full is
+* defined for a write FIFO when there is only one available data word in the
+* FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is almost full, FALSE otherwise.
+*
+* @note
+*
+* Signature: u32 XPF_V100B_IS_ALMOST_FULL(XPacketFifoV100b *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V100B_IS_ALMOST_FULL(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
+    XPF_ALMOST_EMPTY_FULL_MASK)
+
+/*****************************************************************************/
+/*
+*
+* Determine if the specified packet FIFO is empty. This applies only to a
+* read FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is empty, FALSE otherwise.
+*
+* @note
+*
+* Signature: u32 XPF_V100B_IS_EMPTY(XPacketFifoV100b *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V100B_IS_EMPTY(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
+    XPF_EMPTY_FULL_MASK)
+
+/*****************************************************************************/
+/*
+*
+* Determine if the specified packet FIFO is full. This applies only to a
+* write FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is full, FALSE otherwise.
+*
+* @note
+*
+* Signature: u32 XPF_V100B_IS_FULL(XPacketFifoV100b *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V100B_IS_FULL(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
+    XPF_EMPTY_FULL_MASK)
+
+/*****************************************************************************/
+/*
+*
+* Determine if the specified packet FIFO is deadlocked.  This condition occurs
+* when the FIFO is full and empty at the same time and is caused by a packet
+* being written to the FIFO which exceeds the total data capacity of the FIFO.
+* It occurs because of the mark/restore features of the packet FIFO which allow
+* retransmission of a packet. The software should reset the FIFO and any devices
+* using the FIFO when this condition occurs.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is deadlocked, FALSE otherwise.
+*
+* @note
+*
+* This component has the capability to generate an interrupt when an error
+* condition occurs.  It is the user's responsibility to provide the interrupt
+* processing to handle the interrupt. This function provides the ability to
+* determine if a deadlock condition, and the ability to reset the FIFO to
+* clear the condition.
+*
+* In this condition, the device which is using the FIFO should also be reset
+* to prevent other problems. This error condition could occur as a normal part
+* of operation if the size of the FIFO is not setup correctly.
+*
+* Signature: u32 XPF_V100B_IS_DEADLOCKED(XPacketFifoV100b *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V100B_IS_DEADLOCKED(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
+    XPF_DEADLOCK_MASK)
+
+/************************** Function Prototypes ******************************/
+
+/* Standard functions */
+
+XStatus XPacketFifoV100b_Initialize(XPacketFifoV100b * InstancePtr,
+				    u32 RegBaseAddress, u32 DataBaseAddress);
+XStatus XPacketFifoV100b_SelfTest(XPacketFifoV100b * InstancePtr, u32 FifoType);
+
+/* Data functions */
+
+XStatus XPacketFifoV100b_Read(XPacketFifoV100b * InstancePtr,
+			      u8 * ReadBufferPtr, u32 ByteCount);
+XStatus XPacketFifoV100b_Write(XPacketFifoV100b * InstancePtr,
+			       u8 * WriteBufferPtr, u32 ByteCount);
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xpacket_fifo_v2_00_a.c linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xpacket_fifo_v2_00_a.c
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xpacket_fifo_v2_00_a.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xpacket_fifo_v2_00_a.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,336 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/*
+*
+* @file xpacket_fifo_v2_00_a.c
+*
+* Contains functions for the XPacketFifoV200a component. See
+* xpacket_fifo_v2_00_a.h for more information about the component.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 2.00a ecm 12/30/02  First release
+* 2.00a rmm 05/14/03  Fixed diab compiler warnings
+* 2.00a rpm 10/22/03  Created and made use of Level 0 driver
+* 2.00a rmm 02/24/04  Added WriteDRE function.
+* </pre>
+*
+*****************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+#include "xstatus.h"
+#include "xpacket_fifo_v2_00_a.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************* Variable Definitions ******************************/
+
+/************************** Function Prototypes ******************************/
+
+/*****************************************************************************/
+/*
+*
+* This function initializes a packet FIFO.  Initialization resets the
+* FIFO such that it's empty and ready to use.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+* @param RegBaseAddress contains the base address of the registers for
+*        the packet FIFO.
+* @param DataBaseAddress contains the base address of the data for
+*        the packet FIFO.
+*
+* @return
+*
+* Always returns XST_SUCCESS.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XPacketFifoV200a_Initialize(XPacketFifoV200a * InstancePtr,
+			    u32 RegBaseAddress, u32 DataBaseAddress)
+{
+	/* assert to verify input argument are valid */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+
+	/* initialize the component variables to the specified state */
+
+	InstancePtr->RegBaseAddress = RegBaseAddress;
+	InstancePtr->DataBaseAddress = DataBaseAddress;
+	InstancePtr->IsReady = XCOMPONENT_IS_READY;
+
+	/* reset the FIFO such that it's empty and ready to use and indicate the
+	 * initialization was successful, note that the is ready variable must be
+	 * set prior to calling the reset function to prevent an assert
+	 */
+	XPF_V200A_RESET(InstancePtr);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/*
+*
+* This function performs a self-test on the specified packet FIFO.  The self
+* test resets the FIFO and reads a register to determine if it is the correct
+* reset value.  This test is destructive in that any data in the FIFO will
+* be lost.
+*
+* @param InstancePtr is a pointer to the packet FIFO to be operated on.
+*
+* @param FifoType specifies the type of FIFO, read or write, for the self test.
+*        The FIFO type is specified by the values XPF_V200A_READ_FIFO_TYPE or
+*        XPF_V200A_WRITE_FIFO_TYPE.
+*
+* @return
+*
+* XST_SUCCESS is returned if the selftest is successful, or
+* XST_PFIFO_BAD_REG_VALUE indicating that the value readback from the
+* occupancy/vacancy count register after a reset does not match the
+* specified reset value.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XPacketFifoV200a_SelfTest(XPacketFifoV200a * InstancePtr, u32 FifoType)
+{
+	u32 Register;
+
+	/* assert to verify valid input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID((FifoType == XPF_V200A_READ_FIFO_TYPE) ||
+			(FifoType == XPF_V200A_WRITE_FIFO_TYPE));
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* reset the fifo and then check to make sure the occupancy/vacancy
+	 * register contents are correct for a reset condition
+	 */
+	XPF_V200A_RESET(InstancePtr);
+
+	Register = XIo_In32(InstancePtr->RegBaseAddress +
+			    XPF_V200A_COUNT_STATUS_REG_OFFSET);
+
+	/* check the value of the register to ensure that it's correct for the
+	 * specified FIFO type since both FIFO types reset to empty, but a bit
+	 * in the register changes definition based upon FIFO type
+	 */
+
+	if (FifoType == XPF_V200A_READ_FIFO_TYPE) {
+		/* check the register value for a read FIFO which should be empty */
+
+		if ((Register & ~(XPF_V200A_FIFO_WIDTH_MASK)) !=
+		    XPF_V200A_EMPTY_FULL_MASK) {
+			return XST_PFIFO_BAD_REG_VALUE;
+		}
+	} else {
+		/* check the register value for a write FIFO which should not be full
+		 * on reset
+		 */
+		if (((Register & ~(XPF_V200A_FIFO_WIDTH_MASK) &
+		      XPF_V200A_EMPTY_FULL_MASK)) != 0) {
+			return XST_PFIFO_BAD_REG_VALUE;
+		}
+	}
+
+	/* check the register value for the proper FIFO width */
+
+	Register &= ~XPF_V200A_EMPTY_FULL_MASK;
+
+	if (((Register & XPF_V200A_FIFO_WIDTH_MASK) !=
+	     XPF_V200A_FIFO_WIDTH_LEGACY_TYPE) &&
+	    ((Register & XPF_V200A_FIFO_WIDTH_MASK) !=
+	     XPF_V200A_FIFO_WIDTH_32BITS_TYPE) &&
+	    ((Register & XPF_V200A_FIFO_WIDTH_MASK) !=
+	     XPF_V200A_FIFO_WIDTH_64BITS_TYPE)) {
+		return XST_PFIFO_BAD_REG_VALUE;
+	}
+
+	/* the test was successful */
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/*
+*
+* Read data from a FIFO and puts it into a specified buffer. This function
+* invokes the Level 0 driver function to read the FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+* @param BufferPtr points to the memory buffer to write the data into. This
+*        buffer must be 32 bit aligned or an alignment exception could be
+*        generated. Since this buffer is a byte buffer, the data is assumed to
+*        be endian independent.
+* @param ByteCount contains the number of bytes to read from the FIFO. This
+*        number of bytes must be present in the FIFO or an error will be
+*        returned.
+*
+* @return
+*
+* - XST_SUCCESS if the operation was successful
+* - XST_PFIFO_LACK_OF_DATA if the number of bytes specified by the byte count
+*   is not present in the FIFO.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XPacketFifoV200a_Read(XPacketFifoV200a * InstancePtr,
+		      u8 * BufferPtr, u32 ByteCount)
+{
+	/* assert to verify valid input arguments including 32 bit alignment of
+	 * the buffer pointer
+	 */
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufferPtr != NULL);
+	XASSERT_NONVOID(((u32) BufferPtr &
+			 (XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT - 1)) == 0);
+	XASSERT_NONVOID(ByteCount != 0);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	return XPacketFifoV200a_L0Read(InstancePtr->RegBaseAddress,
+				       InstancePtr->DataBaseAddress,
+				       BufferPtr, ByteCount);
+}
+
+/*****************************************************************************/
+/*
+*
+* Write data into a packet FIFO. This function invokes the Level 0 driver
+* function to read the FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+* @param BufferPtr points to the memory buffer that data is to be read from
+*        and written into the FIFO. Since this buffer is a byte buffer, the
+*        data is assumed to be endian independent. This buffer must be 32 bit
+*        aligned or an alignment exception could be generated.
+* @param ByteCount contains the number of bytes to read from the buffer and to
+*        write to the FIFO.
+*
+* @return
+*
+* - XST_SUCCESS is returned if the operation succeeded.
+* - XST_PFIFO_NO_ROOM is returned if there is not enough room in the FIFO to
+*   hold the specified bytes.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XPacketFifoV200a_Write(XPacketFifoV200a * InstancePtr,
+		       u8 * BufferPtr, u32 ByteCount)
+{
+	/* assert to verify valid input arguments including 32 bit alignment of
+	 * the buffer pointer
+	 */
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufferPtr != NULL);
+	XASSERT_NONVOID(((u32) BufferPtr &
+			 (XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT - 1)) == 0);
+	XASSERT_NONVOID(ByteCount != 0);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	return XPacketFifoV200a_L0Write(InstancePtr->RegBaseAddress,
+					InstancePtr->DataBaseAddress,
+					BufferPtr, ByteCount);
+}
+
+/*****************************************************************************/
+/*
+*
+* Write data into a packet FIFO configured with the Data Realignment engine
+* (DRE). There are no alignment restrictions. The FIFO can be written on any
+* byte boundary. The FIFO must be at least 32 bits wide.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+* @param BufferPtr points to the memory buffer that data is to be read from
+*        and written into the FIFO. Since this buffer is a byte buffer, the
+*        data is assumed to be endian independent. 
+* @param ByteCount contains the number of bytes to read from the buffer and to
+*        write to the FIFO.
+*
+* @return
+*
+* XST_SUCCESS is returned if the operation succeeded.  If there is not enough
+* room in the FIFO to hold the specified bytes, XST_PFIFO_NO_ROOM is
+* returned.
+*
+* @note
+*
+* This function assumes that if the device inserting data into the FIFO is
+* a byte device, the order of the bytes in each 32/64 bit word is from the most
+* significant byte to the least significant byte.
+*
+******************************************************************************/
+XStatus
+XPacketFifoV200a_WriteDre(XPacketFifoV200a * InstancePtr,
+			  u8 * BufferPtr, u32 ByteCount)
+{
+	/* assert to verify valid input arguments */
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufferPtr != NULL);
+	XASSERT_NONVOID(ByteCount != 0);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	return XPacketFifoV200a_L0WriteDre(InstancePtr->RegBaseAddress,
+					   InstancePtr->DataBaseAddress,
+					   BufferPtr, ByteCount);
+}
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xpacket_fifo_v2_00_a.h linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xpacket_fifo_v2_00_a.h
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xpacket_fifo_v2_00_a.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xpacket_fifo_v2_00_a.h	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,285 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/*
+*
+* @file xpacket_fifo_v2_00_a.h
+*
+* This component is a common component because it's primary purpose is to
+* prevent code duplication in drivers. A driver which must handle a packet
+* FIFO uses this component rather than directly manipulating a packet FIFO.
+*
+* A FIFO is a device which has dual port memory such that one user may be
+* inserting data into the FIFO while another is consuming data from the FIFO.
+* A packet FIFO is designed for use with packet protocols such as Ethernet and
+* ATM.  It is typically only used with devices when DMA and/or Scatter Gather
+* is used.  It differs from a nonpacket FIFO in that it does not provide any
+* interrupts for thresholds of the FIFO such that it is less useful without
+* DMA.
+*
+* @note
+*
+* This component has the capability to generate an interrupt when an error
+* condition occurs.  It is the user's responsibility to provide the interrupt
+* processing to handle the interrupt. This component provides the ability to
+* determine if that interrupt is active, a deadlock condition, and the ability
+* to reset the FIFO to clear the condition. In this condition, the device which
+* is using the FIFO should also be reset to prevent other problems. This error
+* condition could occur as a normal part of operation if the size of the FIFO
+* is not setup correctly.  See the hardware IP specification for more details.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 2.00a ecm 12/30/02  First release
+* 2.00a rpm 10/22/03  Created and made use of Level 0 driver
+* 2.00a rmm 02/24/04  Added WriteDre function.
+* </pre>
+*
+*****************************************************************************/
+#ifndef XPACKET_FIFO_V200A_H	/* prevent circular inclusions */
+#define XPACKET_FIFO_V200A_H	/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xpacket_fifo_l_v2_00_a.h"
+
+/************************** Constant Definitions *****************************/
+
+/* See the low-level header file for constant definitions */
+
+/**************************** Type Definitions *******************************/
+
+/*
+ * The XPacketFifo driver instance data. The driver is required to allocate a
+ * variable of this type for every packet FIFO in the device.
+ */
+typedef struct {
+	u32 RegBaseAddress;	/* Base address of registers */
+	u32 IsReady;		/* Device is initialized and ready */
+	u32 DataBaseAddress;	/* Base address of data for FIFOs */
+} XPacketFifoV200a;
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/*
+*
+* Reset the specified packet FIFO.  Resetting a FIFO will cause any data
+* contained in the FIFO to be lost.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XPF_V200A_RESET(XPacketFifoV200a *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V200A_RESET(InstancePtr) \
+    XIo_Out32((InstancePtr)->RegBaseAddress + XPF_V200A_RESET_REG_OFFSET, XPF_V200A_RESET_FIFO_MASK);
+
+/*****************************************************************************/
+/*
+*
+* Get the occupancy count for a read packet FIFO and the vacancy count for a
+* write packet FIFO. These counts indicate the number of 32-bit words
+* contained (occupancy) in the FIFO or the number of 32-bit words available
+* to write (vacancy) in the FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* The occupancy or vacancy count for the specified packet FIFO.
+*
+* @note
+*
+* Signature: u32 XPF_V200A_GET_COUNT(XPacketFifoV200a *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V200A_GET_COUNT(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) & \
+    XPF_V200A_COUNT_MASK)
+
+/*****************************************************************************/
+/*
+*
+* Determine if the specified packet FIFO is almost empty. Almost empty is
+* defined for a read FIFO when there is only one data word in the FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is almost empty, FALSE otherwise.
+*
+* @note
+*
+* Signature: u32 XPF_V200A_IS_ALMOST_EMPTY(XPacketFifoV200a *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V200A_IS_ALMOST_EMPTY(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) & \
+    XPF_V200A_ALMOST_EMPTY_FULL_MASK)
+
+/*****************************************************************************/
+/*
+*
+* Determine if the specified packet FIFO is almost full. Almost full is
+* defined for a write FIFO when there is only one available data word in the
+* FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is almost full, FALSE otherwise.
+*
+* @note
+*
+* Signature: u32 XPF_V200A_IS_ALMOST_FULL(XPacketFifoV200a *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V200A_IS_ALMOST_FULL(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) & \
+    XPF_V200A_ALMOST_EMPTY_FULL_MASK)
+
+/*****************************************************************************/
+/*
+*
+* Determine if the specified packet FIFO is empty. This applies only to a
+* read FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is empty, FALSE otherwise.
+*
+* @note
+*
+* Signature: u32 XPF_V200A_IS_EMPTY(XPacketFifoV200a *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V200A_IS_EMPTY(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) & \
+    XPF_V200A_EMPTY_FULL_MASK)
+
+/*****************************************************************************/
+/*
+*
+* Determine if the specified packet FIFO is full. This applies only to a
+* write FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is full, FALSE otherwise.
+*
+* @note
+*
+* Signature: u32 XPF_V200A_IS_FULL(XPacketFifoV200a *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V200A_IS_FULL(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) & \
+    XPF_V200A_EMPTY_FULL_MASK)
+
+/*****************************************************************************/
+/*
+*
+* Determine if the specified packet FIFO is deadlocked.  This condition occurs
+* when the FIFO is full and empty at the same time and is caused by a packet
+* being written to the FIFO which exceeds the total data capacity of the FIFO.
+* It occurs because of the mark/restore features of the packet FIFO which allow
+* retransmission of a packet. The software should reset the FIFO and any devices
+* using the FIFO when this condition occurs.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is deadlocked, FALSE otherwise.
+*
+* @note
+*
+* This component has the capability to generate an interrupt when an error
+* condition occurs.  It is the user's responsibility to provide the interrupt
+* processing to handle the interrupt. This function provides the ability to
+* determine if a deadlock condition, and the ability to reset the FIFO to
+* clear the condition.
+*
+* In this condition, the device which is using the FIFO should also be reset
+* to prevent other problems. This error condition could occur as a normal part
+* of operation if the size of the FIFO is not setup correctly.
+*
+* Signature: u32 XPF_V200A_IS_DEADLOCKED(XPacketFifoV200a *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V200A_IS_DEADLOCKED(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) & \
+    XPF_V200A_DEADLOCK_MASK)
+
+/************************** Function Prototypes ******************************/
+
+/* Standard functions */
+
+XStatus XPacketFifoV200a_Initialize(XPacketFifoV200a * InstancePtr,
+				    u32 RegBaseAddress, u32 DataBaseAddress);
+XStatus XPacketFifoV200a_SelfTest(XPacketFifoV200a * InstancePtr, u32 FifoType);
+
+/* Data functions */
+
+XStatus XPacketFifoV200a_Read(XPacketFifoV200a * InstancePtr,
+			      u8 * ReadBufferPtr, u32 ByteCount);
+XStatus XPacketFifoV200a_Write(XPacketFifoV200a * InstancePtr,
+			       u8 * WriteBufferPtr, u32 ByteCount);
+XStatus XPacketFifoV200a_WriteDre(XPacketFifoV200a * InstancePtr,
+				  u8 * WriteBufferPtr, u32 ByteCount);
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xstatus.h linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xstatus.h
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xstatus.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xstatus.h	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,347 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xstatus.h
+*
+* This file contains Xilinx software status codes.  Status codes have their
+* own data type called XStatus.  These codes are used throughout the Xilinx
+* device drivers.
+*
+******************************************************************************/
+
+#ifndef XSTATUS_H		/* prevent circular inclusions */
+#define XSTATUS_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+
+/************************** Constant Definitions *****************************/
+
+/*********************** Common statuses 0 - 500 *****************************/
+
+#define XST_SUCCESS                     0L
+#define XST_FAILURE                     1L
+#define XST_DEVICE_NOT_FOUND            2L
+#define XST_DEVICE_BLOCK_NOT_FOUND      3L
+#define XST_INVALID_VERSION             4L
+#define XST_DEVICE_IS_STARTED           5L
+#define XST_DEVICE_IS_STOPPED           6L
+#define XST_FIFO_ERROR                  7L	/* an error occurred during an
+						   operation with a FIFO such as
+						   an underrun or overrun, this
+						   error requires the device to
+						   be reset */
+#define XST_RESET_ERROR                 8L	/* an error occurred which requires
+						   the device to be reset */
+#define XST_DMA_ERROR                   9L	/* a DMA error occurred, this error
+						   typically requires the device
+						   using the DMA to be reset */
+#define XST_NOT_POLLED                  10L	/* the device is not configured for
+						   polled mode operation */
+#define XST_FIFO_NO_ROOM                11L	/* a FIFO did not have room to put
+						   the specified data into */
+#define XST_BUFFER_TOO_SMALL            12L	/* the buffer is not large enough
+						   to hold the expected data */
+#define XST_NO_DATA                     13L	/* there was no data available */
+#define XST_REGISTER_ERROR              14L	/* a register did not contain the
+						   expected value */
+#define XST_INVALID_PARAM               15L	/* an invalid parameter was passed
+						   into the function */
+#define XST_NOT_SGDMA                   16L	/* the device is not configured for
+						   scatter-gather DMA operation */
+#define XST_LOOPBACK_ERROR              17L	/* a loopback test failed */
+#define XST_NO_CALLBACK                 18L	/* a callback has not yet been
+						 * registered */
+#define XST_NO_FEATURE                  19L	/* device is not configured with
+						 * the requested feature */
+#define XST_NOT_INTERRUPT               20L	/* device is not configured for
+						 * interrupt mode operation */
+#define XST_DEVICE_BUSY                 21L	/* device is busy */
+#define XST_ERROR_COUNT_MAX             22L	/* the error counters of a device
+						 * have maxed out */
+#define XST_IS_STARTED                  23L	/* used when part of device is
+						 * already started i.e.
+						 * sub channel */
+#define XST_IS_STOPPED                  24L	/* used when part of device is
+						 * already stopped i.e.
+						 * sub channel */
+
+/***************** Utility Component statuses 401 - 500  *********************/
+
+#define XST_MEMTEST_FAILED              401L	/* memory test failed */
+
+/***************** Common Components statuses 501 - 1000 *********************/
+
+/********************* Packet Fifo statuses 501 - 510 ************************/
+
+#define XST_PFIFO_LACK_OF_DATA          501L	/* not enough data in FIFO   */
+#define XST_PFIFO_NO_ROOM               502L	/* not enough room in FIFO   */
+#define XST_PFIFO_BAD_REG_VALUE         503L	/* self test, a register value
+						   was invalid after reset */
+
+/************************** DMA statuses 511 - 530 ***************************/
+
+#define XST_DMA_TRANSFER_ERROR          511L	/* self test, DMA transfer
+						   failed */
+#define XST_DMA_RESET_REGISTER_ERROR    512L	/* self test, a register value
+						   was invalid after reset */
+#define XST_DMA_SG_LIST_EMPTY           513L	/* scatter gather list contains
+						   no buffer descriptors ready
+						   to be processed */
+#define XST_DMA_SG_IS_STARTED           514L	/* scatter gather not stopped */
+#define XST_DMA_SG_IS_STOPPED           515L	/* scatter gather not running */
+#define XST_DMA_SG_LIST_FULL            517L	/* all the buffer desciptors of
+						   the scatter gather list are
+						   being used */
+#define XST_DMA_SG_BD_LOCKED            518L	/* the scatter gather buffer
+						   descriptor which is to be
+						   copied over in the scatter
+						   list is locked */
+#define XST_DMA_SG_NOTHING_TO_COMMIT    519L	/* no buffer descriptors have been
+						   put into the scatter gather
+						   list to be commited */
+#define XST_DMA_SG_COUNT_EXCEEDED       521L	/* the packet count threshold
+						   specified was larger than the
+						   total # of buffer descriptors
+						   in the scatter gather list */
+#define XST_DMA_SG_LIST_EXISTS          522L	/* the scatter gather list has
+						   already been created */
+#define XST_DMA_SG_NO_LIST              523L	/* no scatter gather list has
+						   been created */
+#define XST_DMA_SG_BD_NOT_COMMITTED     524L	/* the buffer descriptor which was
+						   being started was not committed
+						   to the list */
+#define XST_DMA_SG_NO_DATA              525L	/* the buffer descriptor to start
+						   has already been used by the
+						   hardware so it can't be reused
+						 */
+
+/************************** IPIF statuses 531 - 550 ***************************/
+
+#define XST_IPIF_REG_WIDTH_ERROR        531L	/* an invalid register width
+						   was passed into the function */
+#define XST_IPIF_RESET_REGISTER_ERROR   532L	/* the value of a register at
+						   reset was not valid */
+#define XST_IPIF_DEVICE_STATUS_ERROR    533L	/* a write to the device interrupt
+						   status register did not read
+						   back correctly */
+#define XST_IPIF_DEVICE_ACK_ERROR       534L	/* the device interrupt status
+						   register did not reset when
+						   acked */
+#define XST_IPIF_DEVICE_ENABLE_ERROR    535L	/* the device interrupt enable
+						   register was not updated when
+						   other registers changed */
+#define XST_IPIF_IP_STATUS_ERROR        536L	/* a write to the IP interrupt
+						   status register did not read
+						   back correctly */
+#define XST_IPIF_IP_ACK_ERROR           537L	/* the IP interrupt status register
+						   did not reset when acked */
+#define XST_IPIF_IP_ENABLE_ERROR        538L	/* IP interrupt enable register was
+						   not updated correctly when other
+						   registers changed */
+#define XST_IPIF_DEVICE_PENDING_ERROR   539L	/* The device interrupt pending
+						   register did not indicate the
+						   expected value */
+#define XST_IPIF_DEVICE_ID_ERROR        540L	/* The device interrupt ID register
+						   did not indicate the expected
+						   value */
+
+/****************** Device specific statuses 1001 - 4095 *********************/
+
+/********************* Ethernet statuses 1001 - 1050 *************************/
+
+#define XST_EMAC_MEMORY_SIZE_ERROR  1001L	/* Memory space is not big enough
+						 * to hold the minimum number of
+						 * buffers or descriptors */
+#define XST_EMAC_MEMORY_ALLOC_ERROR 1002L	/* Memory allocation failed */
+#define XST_EMAC_MII_READ_ERROR     1003L	/* MII read error */
+#define XST_EMAC_MII_BUSY           1004L	/* An MII operation is in progress */
+#define XST_EMAC_OUT_OF_BUFFERS     1005L	/* Adapter is out of buffers */
+#define XST_EMAC_PARSE_ERROR        1006L	/* Invalid adapter init string */
+#define XST_EMAC_COLLISION_ERROR    1007L	/* Excess deferral or late
+						 * collision on polled send */
+
+/*********************** UART statuses 1051 - 1075 ***************************/
+#define XST_UART
+
+#define XST_UART_INIT_ERROR         1051L
+#define XST_UART_START_ERROR        1052L
+#define XST_UART_CONFIG_ERROR       1053L
+#define XST_UART_TEST_FAIL          1054L
+#define XST_UART_BAUD_ERROR         1055L
+#define XST_UART_BAUD_RANGE         1056L
+
+/************************ IIC statuses 1076 - 1100 ***************************/
+
+#define XST_IIC_SELFTEST_FAILED         1076	/* self test failed            */
+#define XST_IIC_BUS_BUSY                1077	/* bus found busy              */
+#define XST_IIC_GENERAL_CALL_ADDRESS    1078	/* mastersend attempted with   */
+					     /* general call address        */
+#define XST_IIC_STAND_REG_RESET_ERROR   1079	/* A non parameterizable reg   */
+					     /* value after reset not valid */
+#define XST_IIC_TX_FIFO_REG_RESET_ERROR 1080	/* Tx fifo included in design  */
+					     /* value after reset not valid */
+#define XST_IIC_RX_FIFO_REG_RESET_ERROR 1081	/* Rx fifo included in design  */
+					     /* value after reset not valid */
+#define XST_IIC_TBA_REG_RESET_ERROR     1082	/* 10 bit addr incl in design  */
+					     /* value after reset not valid */
+#define XST_IIC_CR_READBACK_ERROR       1083	/* Read of the control register */
+					     /* didn't return value written */
+#define XST_IIC_DTR_READBACK_ERROR      1084	/* Read of the data Tx reg     */
+					     /* didn't return value written */
+#define XST_IIC_DRR_READBACK_ERROR      1085	/* Read of the data Receive reg */
+					     /* didn't return value written */
+#define XST_IIC_ADR_READBACK_ERROR      1086	/* Read of the data Tx reg     */
+					     /* didn't return value written */
+#define XST_IIC_TBA_READBACK_ERROR      1087	/* Read of the 10 bit addr reg */
+					     /* didn't return written value */
+#define XST_IIC_NOT_SLAVE               1088	/* The device isn't a slave    */
+
+/*********************** ATMC statuses 1101 - 1125 ***************************/
+
+#define XST_ATMC_ERROR_COUNT_MAX    1101L	/* the error counters in the ATM
+						   controller hit the max value
+						   which requires the statistics
+						   to be cleared */
+
+/*********************** Flash statuses 1126 - 1150 **************************/
+
+#define XST_FLASH_BUSY                1126L	/* Flash is erasing or programming */
+#define XST_FLASH_READY               1127L	/* Flash is ready for commands */
+#define XST_FLASH_ERROR               1128L	/* Flash had detected an internal
+						   error. Use XFlash_DeviceControl
+						   to retrieve device specific codes */
+#define XST_FLASH_ERASE_SUSPENDED     1129L	/* Flash is in suspended erase state */
+#define XST_FLASH_WRITE_SUSPENDED     1130L	/* Flash is in suspended write state */
+#define XST_FLASH_PART_NOT_SUPPORTED  1131L	/* Flash type not supported by
+						   driver */
+#define XST_FLASH_NOT_SUPPORTED       1132L	/* Operation not supported */
+#define XST_FLASH_TOO_MANY_REGIONS    1133L	/* Too many erase regions */
+#define XST_FLASH_TIMEOUT_ERROR       1134L	/* Programming or erase operation
+						   aborted due to a timeout */
+#define XST_FLASH_ADDRESS_ERROR       1135L	/* Accessed flash outside its
+						   addressible range */
+#define XST_FLASH_ALIGNMENT_ERROR     1136L	/* Write alignment error */
+#define XST_FLASH_BLOCKING_CALL_ERROR 1137L	/* Couldn't return immediately from
+						   write/erase function with
+						   XFL_NON_BLOCKING_WRITE/ERASE
+						   option cleared */
+#define XST_FLASH_CFI_QUERY_ERROR     1138L	/* Failed to query the device */
+
+/*********************** SPI statuses 1151 - 1175 ****************************/
+
+#define XST_SPI_MODE_FAULT          1151	/* master was selected as slave */
+#define XST_SPI_TRANSFER_DONE       1152	/* data transfer is complete */
+#define XST_SPI_TRANSMIT_UNDERRUN   1153	/* slave underruns transmit register */
+#define XST_SPI_RECEIVE_OVERRUN     1154	/* device overruns receive register */
+#define XST_SPI_NO_SLAVE            1155	/* no slave has been selected yet */
+#define XST_SPI_TOO_MANY_SLAVES     1156	/* more than one slave is being
+						 * selected */
+#define XST_SPI_NOT_MASTER          1157	/* operation is valid only as master */
+#define XST_SPI_SLAVE_ONLY          1158	/* device is configured as slave-only */
+#define XST_SPI_SLAVE_MODE_FAULT    1159	/* slave was selected while disabled */
+
+/********************** OPB Arbiter statuses 1176 - 1200 *********************/
+
+#define XST_OPBARB_INVALID_PRIORITY  1176	/* the priority registers have either
+						 * one master assigned to two or more
+						 * priorities, or one master not
+						 * assigned to any priority
+						 */
+#define XST_OPBARB_NOT_SUSPENDED     1177	/* an attempt was made to modify the
+						 * priority levels without first
+						 * suspending the use of priority
+						 * levels
+						 */
+#define XST_OPBARB_PARK_NOT_ENABLED  1178	/* bus parking by id was enabled but
+						 * bus parking was not enabled
+						 */
+#define XST_OPBARB_NOT_FIXED_PRIORITY 1179	/* the arbiter must be in fixed
+						 * priority mode to allow the
+						 * priorities to be changed
+						 */
+
+/************************ Intc statuses 1201 - 1225 **************************/
+
+#define XST_INTC_FAIL_SELFTEST      1201	/* self test failed */
+#define XST_INTC_CONNECT_ERROR      1202	/* interrupt already in use */
+
+/********************** TmrCtr statuses 1226 - 1250 **************************/
+
+#define XST_TMRCTR_TIMER_FAILED     1226	/* self test failed */
+
+/********************** WdtTb statuses 1251 - 1275 ***************************/
+
+#define XST_WDTTB_TIMER_FAILED      1251L
+
+/********************** PlbArb statuses 1276 - 1300 **************************/
+
+#define XST_PLBARB_FAIL_SELFTEST    1276L
+
+/********************** Plb2Opb statuses 1301 - 1325 *************************/
+
+#define XST_PLB2OPB_FAIL_SELFTEST   1301L
+
+/********************** Opb2Plb statuses 1326 - 1350 *************************/
+
+#define XST_OPB2PLB_FAIL_SELFTEST   1326L
+
+/********************** SysAce statuses 1351 - 1360 **************************/
+
+#define XST_SYSACE_NO_LOCK          1351L	/* No MPU lock has been granted */
+
+/********************** PCI Bridge statuses 1361 - 1375 **********************/
+
+#define XST_PCI_INVALID_ADDRESS     1361L
+
+/**************************** Type Definitions *******************************/
+
+/**
+ * The status typedef.
+ */
+typedef u32 XStatus;
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xuartlite_l.h linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xuartlite_l.h
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xuartlite_l.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xuartlite_l.h	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,256 @@
+/*****************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002 Xilinx Inc.
+*       All rights reserved.
+*
+*****************************************************************************/
+/****************************************************************************/
+/**
+*
+* @file xuartlite_l.h
+*
+* This header file contains identifiers and low-level driver functions (or
+* macros) that can be used to access the device.  High-level driver functions
+* are defined in xuartlite.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00b rpm  04/25/02 First release
+* </pre>
+*
+*****************************************************************************/
+
+#ifndef XUARTLITE_L_H /* prevent circular inclusions */
+#define XUARTLITE_L_H /* by using protection macros */
+
+/***************************** Include Files ********************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+
+/************************** Constant Definitions ****************************/
+
+/* UART Lite register offsets */
+
+#define XUL_RX_FIFO_OFFSET              0   /* receive FIFO, read only */
+#define XUL_TX_FIFO_OFFSET              4   /* transmit FIFO, write only */
+#define XUL_STATUS_REG_OFFSET           8   /* status register, read only */
+#define XUL_CONTROL_REG_OFFSET          12  /* control register, write only */
+
+/* control register bit positions */
+
+#define XUL_CR_ENABLE_INTR              0x10    /* enable interrupt */
+#define XUL_CR_FIFO_RX_RESET            0x02    /* reset receive FIFO */
+#define XUL_CR_FIFO_TX_RESET            0x01    /* reset transmit FIFO */
+
+/* status register bit positions */
+
+#define XUL_SR_PARITY_ERROR             0x80
+#define XUL_SR_FRAMING_ERROR            0x40
+#define XUL_SR_OVERRUN_ERROR            0x20
+#define XUL_SR_INTR_ENABLED             0x10    /* interrupt enabled */
+#define XUL_SR_TX_FIFO_FULL             0x08    /* transmit FIFO full */
+#define XUL_SR_TX_FIFO_EMPTY            0x04    /* transmit FIFO empty */
+#define XUL_SR_RX_FIFO_FULL             0x02    /* receive FIFO full */
+#define XUL_SR_RX_FIFO_VALID_DATA       0x01    /* data in receive FIFO */
+
+/* the following constant specifies the size of the FIFOs, the size of the
+ * FIFOs includes the transmitter and receiver such that it is the total number
+ * of bytes that the UART can buffer
+ */
+#define XUL_FIFO_SIZE               16
+
+/* Stop bits are fixed at 1. Baud, parity, and data bits are fixed on a
+ * per instance basis
+ */
+#define XUL_STOP_BITS               1
+
+/* Parity definitions
+ */
+#define XUL_PARITY_NONE             0
+#define XUL_PARITY_ODD              1
+#define XUL_PARITY_EVEN             2
+
+/**************************** Type Definitions ******************************/
+
+/***************** Macros (Inline Functions) Definitions ********************/
+
+/*****************************************************************************
+*
+* Low-level driver macros and functions. The list below provides signatures
+* to help the user use the macros.
+*
+* void XUartLite_mSetControlReg(u32 BaseAddress, u32 Mask)
+* u32 XUartLite_mGetControlReg(u32 BaseAddress)
+* u32 XUartLite_mGetStatusReg(u32 BaseAddress)
+*
+* Xboolean XUartLite_mIsReceiveEmpty(u32 BaseAddress)
+* Xboolean XUartLite_mIsTransmitFull(u32 BaseAddress)
+* Xboolean XUartLite_mIsIntrEnabled(u32 BaseAddress)
+*
+* void XUartLite_mEnableIntr(u32 BaseAddress)
+* void XUartLite_mDisableIntr(u32 BaseAddress)
+*
+* void XUartLite_SendByte(u32 BaseAddress, u8 Data);
+* u8 XUartLite_RecvByte(u32 BaseAddress);
+*
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*
+* Set the contents of the control register. Use the XUL_CR_* constants defined
+* above to create the bit-mask to be written to the register.
+*
+* @param    BaseAddress is the base address of the device
+* @param    Mask is the 32-bit value to write to the control register
+*
+* @return   None.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XUartLite_mSetControlReg(BaseAddress, Mask) \
+                    XIo_Out32((BaseAddress) + XUL_CONTROL_REG_OFFSET, (Mask))
+
+
+/****************************************************************************/
+/**
+*
+* Get the contents of the control register. Use the XUL_CR_* constants defined
+* above to interpret the bit-mask returned.
+*
+* @param    BaseAddress is the  base address of the device
+*
+* @return   A 32-bit value representing the contents of the control register.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XUartLite_mGetControlReg(BaseAddress) \
+                    XIo_In32((BaseAddress) + XUL_CONTROL_REG_OFFSET)
+
+
+/****************************************************************************/
+/**
+*
+* Get the contents of the status register. Use the XUL_SR_* constants defined
+* above to interpret the bit-mask returned.
+*
+* @param    BaseAddress is the  base address of the device
+*
+* @return   A 32-bit value representing the contents of the status register.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XUartLite_mGetStatusReg(BaseAddress) \
+                    XIo_In32((BaseAddress) + XUL_STATUS_REG_OFFSET)
+
+
+/****************************************************************************/
+/**
+*
+* Check to see if the receiver has data.
+*
+* @param    BaseAddress is the  base address of the device
+*
+* @return   XTRUE if the receiver is empty, XFALSE if there is data present.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XUartLite_mIsReceiveEmpty(BaseAddress) \
+          (!(XUartLite_mGetStatusReg((BaseAddress)) & XUL_SR_RX_FIFO_VALID_DATA))
+
+
+/****************************************************************************/
+/**
+*
+* Check to see if the transmitter is full.
+*
+* @param    BaseAddress is the  base address of the device
+*
+* @return   XTRUE if the transmitter is full, XFALSE otherwise.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XUartLite_mIsTransmitFull(BaseAddress) \
+                (XUartLite_mGetStatusReg((BaseAddress)) & XUL_SR_TX_FIFO_FULL)
+
+
+/****************************************************************************/
+/**
+*
+* Check to see if the interrupt is enabled.
+*
+* @param    BaseAddress is the  base address of the device
+*
+* @return   XTRUE if the interrupt is enabled, XFALSE otherwise.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XUartLite_mIsIntrEnabled(BaseAddress) \
+                (XUartLite_mGetStatusReg((BaseAddress)) & XUL_SR_INTR_ENABLED)
+
+
+/****************************************************************************/
+/**
+*
+* Enable the device interrupt. Preserve the contents of the control register.
+*
+* @param    BaseAddress is the  base address of the device
+*
+* @return   None.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XUartLite_mEnableIntr(BaseAddress) \
+               XUartLite_mSetControlReg((BaseAddress), \
+                   XUartLite_mGetControlReg((BaseAddress)) | XUL_CR_ENABLE_INTR)
+
+
+/****************************************************************************/
+/**
+*
+* Disable the device interrupt. Preserve the contents of the control register.
+*
+* @param    BaseAddress is the  base address of the device
+*
+* @return   None.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XUartLite_mDisableIntr(BaseAddress) \
+              XUartLite_mSetControlReg((BaseAddress), \
+                  XUartLite_mGetControlReg((BaseAddress)) & ~XUL_CR_ENABLE_INTR)
+
+
+/************************** Function Prototypes *****************************/
+
+void XUartLite_SendByte(u32 BaseAddress, u8 Data);
+u8 XUartLite_RecvByte(u32 BaseAddress);
+
+
+#endif            /* end of protection macro */
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xversion.c linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xversion.c
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xversion.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xversion.c	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,350 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************
+*
+* This file contains the implementation of the XVersion component. This
+* component represents a version ID.  It is encapsulated within a component
+* so that it's type and implementation can change without affecting users of
+* it.
+*
+* The version is formatted as X.YYZ where X = 0 - 9, Y = 00 - 99, Z = a - z
+* X is the major revision, YY is the minor revision, and Z is the
+* compatability revision.
+*
+* Packed versions are also utilized for the configuration ROM such that
+* memory is minimized. A packed version consumes only 16 bits and is
+* formatted as follows.
+*
+* <pre>
+* Revision                  Range       Bit Positions
+*
+* Major Revision            0 - 9       Bits 15 - 12
+* Minor Revision            0 - 99      Bits 11 - 5
+* Compatability Revision    a - z       Bits 4 - 0
+</pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xversion.h"
+
+/************************** Constant Definitions *****************************/
+
+/* the following constants define the masks and shift values to allow the
+ * revisions to be packed and unpacked, a packed version is packed into a 16
+ * bit value in the following format, XXXXYYYYYYYZZZZZ, where XXXX is the
+ * major revision, YYYYYYY is the minor revision, and ZZZZZ is the compatability
+ * revision
+ */
+#define XVE_MAJOR_SHIFT_VALUE       12
+#define XVE_MINOR_ONLY_MASK         0x0FE0
+#define XVE_MINOR_SHIFT_VALUE       5
+#define XVE_COMP_ONLY_MASK          0x001F
+
+/* the following constants define the specific characters of a version string
+ * for each character of the revision, a version string is in the following
+ * format, "X.YYZ" where X is the major revision (0 - 9), YY is the minor
+ * revision (00 - 99), and Z is the compatability revision (a - z)
+ */
+#define XVE_MAJOR_CHAR      0	/* major revision 0 - 9 */
+#define XVE_MINOR_TENS_CHAR 2	/* minor revision tens 0 - 9 */
+#define XVE_MINOR_ONES_CHAR 3	/* minor revision ones 0 - 9 */
+#define XVE_COMP_CHAR       4	/* compatability revision a - z */
+#define XVE_END_STRING_CHAR 5
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static u32 IsVersionStringValid(s8 * StringPtr);
+
+/*****************************************************************************
+*
+* Unpacks a packed version into the specified version. Versions are packed
+* into the configuration ROM to reduce the amount storage. A packed version
+* is a binary format as oppossed to a non-packed version which is implemented
+* as a string.
+*
+* @param    InstancePtr points to the version to unpack the packed version into.
+* @param    PackedVersion contains the packed version to unpack.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XVersion_UnPack(XVersion * InstancePtr, u16 PackedVersion)
+{
+	/* not implemented yet since CROM related */
+}
+
+/*****************************************************************************
+*
+* Packs a version into the specified packed version. Versions are packed into
+* the configuration ROM to reduce the amount storage.
+*
+* @param    InstancePtr points to the version to pack.
+* @param    PackedVersionPtr points to the packed version which will receive
+*           the new packed version.
+*
+* @return
+*
+* A status, XST_SUCCESS, indicating the packing was accomplished
+* successfully, or an error, XST_INVALID_VERSION, indicating the specified
+* input version was not valid such that the pack did not occur
+* <br><br>
+* The packed version pointed to by PackedVersionPtr is modified with the new
+* packed version if the status indicates success.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XVersion_Pack(XVersion * InstancePtr, u16 * PackedVersionPtr)
+{
+	/* not implemented yet since CROM related */
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************
+*
+* Determines if two versions are equal.
+*
+* @param    InstancePtr points to the first version to be compared.
+* @param    VersionPtr points to a second version to be compared.
+*
+* @return
+*
+* TRUE if the versions are equal, FALSE otherwise.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32
+XVersion_IsEqual(XVersion * InstancePtr, XVersion * VersionPtr)
+{
+	u8 *Version1 = (u8 *) InstancePtr;
+	u8 *Version2 = (u8 *) VersionPtr;
+	int Index;
+
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(VersionPtr != NULL);
+
+	/* check each byte of the versions to see if they are the same,
+	 * return at any point a byte differs between them
+	 */
+	for (Index = 0; Index < sizeof (XVersion); Index++) {
+		if (Version1[Index] != Version2[Index]) {
+			return FALSE;
+		}
+	}
+
+	/* No byte was found to be different between the versions, so indicate
+	 * the versions are equal
+	 */
+	return TRUE;
+}
+
+/*****************************************************************************
+*
+* Converts a version to a null terminated string.
+*
+* @param    InstancePtr points to the version to convert.
+* @param    StringPtr points to the string which will be the result of the
+*           conversion. This does not need to point to a null terminated
+*           string as an input, but must point to storage which is an adequate
+*           amount to hold the result string.
+*
+* @return
+*
+* The null terminated string is inserted at the location pointed to by
+* StringPtr if the status indicates success.
+*
+* @note
+*
+* It is necessary for the caller to have already allocated the storage to
+* contain the string.  The amount of memory necessary for the string is
+* specified in the version header file.
+*
+******************************************************************************/
+void
+XVersion_ToString(XVersion * InstancePtr, s8 * StringPtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(StringPtr != NULL);
+
+	/* since version is implemented as a string, just copy the specified
+	 * input into the specified output
+	 */
+	XVersion_Copy(InstancePtr, (XVersion *) StringPtr);
+}
+
+/*****************************************************************************
+*
+* Initializes a version from a null terminated string. Since the string may not
+* be a format which is compatible with the version, an error could occur.
+*
+* @param    InstancePtr points to the version which is to be initialized.
+* @param    StringPtr points to a null terminated string which will be
+*           converted to a version.  The format of the string must match the
+*           version string format which is X.YYX where X = 0 - 9, YY = 00 - 99,
+*           Z = a - z.
+*
+* @return
+*
+* A status, XST_SUCCESS, indicating the conversion was accomplished
+* successfully, or XST_INVALID_VERSION indicating the version string format
+* was not valid.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XVersion_FromString(XVersion * InstancePtr, s8 * StringPtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(StringPtr != NULL);
+
+	/* if the version string specified is not valid, return an error */
+
+	if (!IsVersionStringValid(StringPtr)) {
+		return XST_INVALID_VERSION;
+	}
+
+	/* copy the specified string into the specified version and indicate the
+	 * conversion was successful
+	 */
+	XVersion_Copy((XVersion *) StringPtr, InstancePtr);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************
+*
+* Copies the contents of a version to another version.
+*
+* @param    InstancePtr points to the version which is the source of data for
+*           the copy operation.
+* @param    VersionPtr points to another version which is the destination of
+*           the copy operation.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XVersion_Copy(XVersion * InstancePtr, XVersion * VersionPtr)
+{
+	u8 *Source = (u8 *) InstancePtr;
+	u8 *Destination = (u8 *) VersionPtr;
+	int Index;
+
+	/* assert to verify input arguments */
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(VersionPtr != NULL);
+
+	/* copy each byte of the source version to the destination version */
+
+	for (Index = 0; Index < sizeof (XVersion); Index++) {
+		Destination[Index] = Source[Index];
+	}
+}
+
+/*****************************************************************************
+*
+* Determines if the specified version is valid.
+*
+* @param    StringPtr points to the string to be validated.
+*
+* @return
+*
+* TRUE if the version string is a valid format, FALSE otherwise.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static u32
+IsVersionStringValid(s8 * StringPtr)
+{
+	/* if the input string is not a valid format, "X.YYZ" where X = 0 - 9,
+	 * YY = 00 - 99, and Z = a - z, then indicate it's not valid
+	 */
+	if ((StringPtr[XVE_MAJOR_CHAR] < '0') ||
+	    (StringPtr[XVE_MAJOR_CHAR] > '9') ||
+	    (StringPtr[XVE_MINOR_TENS_CHAR] < '0') ||
+	    (StringPtr[XVE_MINOR_TENS_CHAR] > '9') ||
+	    (StringPtr[XVE_MINOR_ONES_CHAR] < '0') ||
+	    (StringPtr[XVE_MINOR_ONES_CHAR] > '9') ||
+	    (StringPtr[XVE_COMP_CHAR] < 'a') ||
+	    (StringPtr[XVE_COMP_CHAR] > 'z')) {
+		return FALSE;
+	}
+
+	return TRUE;
+}
diff -urN linux-2.4.29/arch/microblaze/xilinx_ocp/xversion.h linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xversion.h
--- linux-2.4.29/arch/microblaze/xilinx_ocp/xversion.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/microblaze/xilinx_ocp/xversion.h	2005-06-14 02:11:13.000000000 +0100
@@ -0,0 +1,97 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************
+*
+* This file contains the interface for the XVersion component. This
+* component represents a version ID.  It is encapsulated within a component
+* so that it's type and implementation can change without affecting users of
+* it.
+*
+* The version is formatted as X.YYZ where X = 0 - 9, Y = 00 - 99, Z = a - z
+* X is the major revision, YY is the minor revision, and Z is the
+* compatability revision.
+*
+* Packed versions are also utilized for the configuration ROM such that
+* memory is minimized. A packed version consumes only 16 bits and is
+* formatted as follows.
+*
+* <pre>
+* Revision                  Range       Bit Positions
+*
+* Major Revision            0 - 9       Bits 15 - 12
+* Minor Revision            0 - 99      Bits 11 - 5
+* Compatability Revision    a - z       Bits 4 - 0
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XVERSION_H		/* prevent circular inclusions */
+#define XVERSION_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/* the following data type is used to hold a null terminated version string
+ * consisting of the following format, "X.YYX"
+ */
+typedef s8 XVersion[6];
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+void XVersion_UnPack(XVersion * InstancePtr, u16 PackedVersion);
+
+XStatus XVersion_Pack(XVersion * InstancePtr, u16 * PackedVersion);
+
+u32 XVersion_IsEqual(XVersion * InstancePtr, XVersion * VersionPtr);
+
+void XVersion_ToString(XVersion * InstancePtr, s8 * StringPtr);
+
+XStatus XVersion_FromString(XVersion * InstancePtr, s8 * StringPtr);
+
+void XVersion_Copy(XVersion * InstancePtr, XVersion * VersionPtr);
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/arch/mips/au1000/common/prom.c linux-2.4.29-uc1/arch/mips/au1000/common/prom.c
--- linux-2.4.29/arch/mips/au1000/common/prom.c	2005-01-19 14:09:26.000000000 +0000
+++ linux-2.4.29-uc1/arch/mips/au1000/common/prom.c	2005-06-14 02:11:18.000000000 +0100
@@ -39,6 +39,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/string.h>
+#include <linux/config.h>
 
 #include <asm/bootinfo.h>
 
@@ -57,6 +58,14 @@
 
 char * prom_getcmdline(void)
 {
+#ifdef CONFIG_MIPS_VEGAS
+	unsigned long 	*reg;
+		
+	if ((*(volatile unsigned long *)0xbfc20000) != 0xffffffff) {
+		reg = (unsigned long *) 0xbfc20000;
+		strcpy(arcs_cmdline, reg);
+	}
+#endif
 	return &(arcs_cmdline[0]);
 }
 
diff -urN linux-2.4.29/arch/mips/au1000/common/setup.c linux-2.4.29-uc1/arch/mips/au1000/common/setup.c
--- linux-2.4.29/arch/mips/au1000/common/setup.c	2005-01-19 14:09:26.000000000 +0000
+++ linux-2.4.29-uc1/arch/mips/au1000/common/setup.c	2005-06-14 02:11:18.000000000 +0100
@@ -73,6 +73,14 @@
 extern void au1xxx_timer_setup(void);
 extern void set_cpuspec(void);
 
+#ifdef CONFIG_CPU_HAS_WB
+void (*__wbflush) (void);
+void au1000_wbflush(void)
+{
+	__asm__ volatile ("sync");
+}
+#endif
+
 void __init au1x00_setup(void)
 {
 	struct	cpu_spec *sp;
@@ -151,6 +159,9 @@
 	strcat(argptr, " au1000_audio=vra");
 	argptr = prom_getcmdline();
 #endif
+#ifdef CONFIG_CPU_HAS_WB
+	__wbflush = au1000_wbflush;
+#endif
 	_machine_restart = au1000_restart;
 	_machine_halt = au1000_halt;
 	_machine_power_off = au1000_power_off;
diff -urN linux-2.4.29/arch/mips/au1000/vegas/board_setup.c linux-2.4.29-uc1/arch/mips/au1000/vegas/board_setup.c
--- linux-2.4.29/arch/mips/au1000/vegas/board_setup.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/mips/au1000/vegas/board_setup.c	2005-06-14 02:11:18.000000000 +0100
@@ -0,0 +1,138 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Alchemy Pb1100 board setup.
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/keyboard.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/au1000.h>
+#include <asm/vegas.h>
+
+#ifdef CONFIG_USB_OHCI
+// Enable the workaround for the OHCI DoneHead
+// register corruption problem.
+#define CONFIG_AU1000_OHCI_FIX
+#endif
+
+#ifdef CONFIG_RTC
+extern struct rtc_ops pb1500_rtc_ops;
+#endif
+
+void __init board_setup(void)
+{
+	u32 pin_func;
+	u32 sys_freqctrl, sys_clksrc;
+
+	// set AUX clock to 12MHz * 8 = 96 MHz
+	au_writel(8, SYS_AUXPLL);
+	au_writel(0, SYS_PININPUTEN);
+	udelay(100);
+
+#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+#ifdef CONFIG_USB_OHCI
+	if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) {
+	        char usb_args[80];
+		argptr = prom_getcmdline();
+		memset(usb_args, 0, sizeof(usb_args));
+		sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d",
+			USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT);
+		strcat(argptr, usb_args);
+	}
+#endif
+	// configure pins GPIO[14:9] as GPIO
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80);
+
+	/* zero and disable FREQ2 */
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/* zero and disable USBH/USBD/IrDA clock */
+	sys_clksrc = au_readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x0000001F;
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+
+	sys_clksrc = au_readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x0000001F;
+
+	// FREQ2 = aux/2 = 48 MHz
+	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/*
+	 * Route 48MHz FREQ2 into USBH/USBD/IrDA
+	 */
+	sys_clksrc |= ((4<<2) | (0<<1) | 0 );
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+	/* setup the static bus controller */
+	au_writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
+	au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
+	au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
+
+	// get USB Functionality pin state (device vs host drive pins)
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
+#ifndef CONFIG_AU1X00_USB_DEVICE
+	// 2nd USB port is USB host
+	pin_func |= 0x8000;
+#endif
+	au_writel(pin_func, SYS_PINFUNC);
+#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+
+	au_writel(0x00000060, 0xb190003c);
+
+#ifdef CONFIG_RTC
+	rtc_ops = &pb1500_rtc_ops;
+	// Enable the RTC if not already enabled
+	if (!(readb(0xac000028) & 0x20)) {
+		writeb(readb(0xac000028) | 0x20, 0xac000028);
+		au_sync();
+	}
+	// Put the clock in BCD mode
+	if (readb(0xac00002C) & 0x4) { /* reg B */
+		writeb(readb(0xac00002c) & ~0x4, 0xac00002c);
+		au_sync();
+	}
+#endif
+}
diff -urN linux-2.4.29/arch/mips/au1000/vegas/init.c linux-2.4.29-uc1/arch/mips/au1000/vegas/init.c
--- linux-2.4.29/arch/mips/au1000/vegas/init.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/mips/au1000/vegas/init.c	2005-06-14 02:11:18.000000000 +0100
@@ -0,0 +1,74 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Pb1100 board setup
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void  __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+	return "Velseis Vegas";
+}
+
+int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
+{
+	unsigned char *memsize_str;
+	unsigned long memsize;
+
+	prom_argc = argc;
+	prom_argv = argv;
+	prom_envp = envp;
+
+	mips_machgroup = MACH_GROUP_ALCHEMY;
+	mips_machtype = MACH_PB1000;  
+
+	//prom_init_cmdline();
+	memsize = 0x01000000;
+	//memsize_str = prom_getenv("memsize");
+	//if (!memsize_str) {
+	//	memsize = 0x04000000;
+	//} else {
+	//	memsize = simple_strtol(memsize_str, NULL, 0);
+	//}
+	add_memory_region(0, memsize, BOOT_MEM_RAM);
+	return 0;
+}
diff -urN linux-2.4.29/arch/mips/au1000/vegas/irqmap.c linux-2.4.29-uc1/arch/mips/au1000/vegas/irqmap.c
--- linux-2.4.29/arch/mips/au1000/vegas/irqmap.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/mips/au1000/vegas/irqmap.c	2005-06-14 02:11:18.000000000 +0100
@@ -0,0 +1,100 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1xxx irq map table
+ *
+ * Copyright 2003 Embedded Edge, LLC
+ *		dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/au1000.h>
+
+au1xxx_irq_map_t au1xxx_irq_map[] = {
+	{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
+
+	{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0},
+
+	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
+
+	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
+
+	{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+
+	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
+
+	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card Fully_Interted#
+	{ AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card STSCHG#
+	{ AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card IRQ#
+	{ AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, // DC_IRQ#
+	{ AU1000_GPIO_23, INTC_INT_LOW_LEVEL, 0 }, // 2-wire SCL
+
+	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+
+	/* Careful if you change match 2 request!
+	 * The interrupt handler is called directly
+	 * from the low level dispatch code.
+	 */
+	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+};
+
+int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff -urN linux-2.4.29/arch/mips/au1000/vegas/Makefile linux-2.4.29-uc1/arch/mips/au1000/vegas/Makefile
--- linux-2.4.29/arch/mips/au1000/vegas/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/mips/au1000/vegas/Makefile	2005-06-14 02:11:18.000000000 +0100
@@ -0,0 +1,19 @@
+#
+#  Copyright 2000,2001 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Alchemy Semiconductor Pb1100 board.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET := vegas.o
+
+obj-y := init.o board_setup.o irqmap.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/mips/config-shared.in linux-2.4.29-uc1/arch/mips/config-shared.in
--- linux-2.4.29/arch/mips/config-shared.in	2005-01-19 14:09:27.000000000 +0000
+++ linux-2.4.29-uc1/arch/mips/config-shared.in	2005-06-14 02:11:20.000000000 +0100
@@ -33,6 +33,7 @@
 dep_bool 'Support for Alchemy PB1550 board' CONFIG_MIPS_PB1550 $CONFIG_MIPS32
 dep_bool 'Support for MyCable XXS1500 board' CONFIG_MIPS_XXS1500 $CONFIG_MIPS32
 dep_bool 'Support for 4G Systems MTX-1 board' CONFIG_MIPS_MTX1 $CONFIG_MIPS32
+dep_bool 'Support for Velseis Vegas board' CONFIG_MIPS_VEGAS $CONFIG_MIPS32
 dep_bool 'Support for Cogent CSB250 board' CONFIG_COGENT_CSB250 $CONFIG_MIPS32
 dep_bool 'Support for BAGET MIPS series (EXPERIMENTAL)' CONFIG_BAGET_MIPS $CONFIG_MIPS32 $CONFIG_EXPERIMENTAL
 bool 'Support for CASIO CASSIOPEIA E-10/15/55/65' CONFIG_CASIO_E55
@@ -346,6 +347,19 @@
    define_int CONFIG_L1_CACHE_SHIFT 4
    define_bool CONFIG_NONCOHERENT_IO y
 fi
+if [ "$CONFIG_MIPS_VEGAS" = "y" ]; then
+   define_bool CONFIG_SOC_AU1X00 y
+   define_bool CONFIG_SOC_AU1100 y
+   define_bool CONFIG_PCI n
+   define_bool CONFIG_PCI_AUTO n
+   define_bool CONFIG_NEW_PCI n
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB n
+   define_bool CONFIG_SWAP_IO_SPACE_W y
+   define_bool CONFIG_SWAP_IO_SPACE_L y
+   define_bool CONFIG_AU1X00_USB_DEVICE n
+   define_bool CONFIG_NEW_TIME_C n
+fi
 if [ "$CONFIG_MIPS_EV64120" = "y" ]; then
    define_bool CONFIG_MIPS_GT64120 y
    define_bool CONFIG_NONCOHERENT_IO y
@@ -729,6 +743,7 @@
      "$CONFIG_MIPS_PB1000" = "y" -o \
      "$CONFIG_MIPS_PB1100" = "y" -o \
      "$CONFIG_MIPS_PB1500" = "y" -o \
+     "$CONFIG_MIPS_VEGAS" = "y" -o \
      "$CONFIG_NEC_OSPREY" = "y" -o \
      "$CONFIG_NEC_EAGLE" = "y" -o \
      "$CONFIG_NINO" = "y" -o \
diff -urN linux-2.4.29/arch/mips/defconfig-vegas linux-2.4.29-uc1/arch/mips/defconfig-vegas
--- linux-2.4.29/arch/mips/defconfig-vegas	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/mips/defconfig-vegas	2005-06-14 02:11:17.000000000 +0100
@@ -0,0 +1,846 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+CONFIG_MIPS_VEGAS=y 
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_SOC_AU1X00=y
+CONFIG_SOC_AU1100=y
+# CONFIG_PCI is not set
+# CONFIG_PCI_AUTO is not set
+# CONFIG_NEW_PCI is not set
+CONFIG_NONCOHERENT_IO=y
+# CONFIG_PC_KEYB is not set
+# CONFIG_NEW_TIME_C is not set
+CONFIG_SWAP_IO_SPACE_W=y
+CONFIG_SWAP_IO_SPACE_L=y
+CONFIG_AU1X00_USB_DEVICE=y
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_VTAG_ICACHE is not set
+CONFIG_64BIT_PHYS_ADDR=y
+CONFIG_CPU_ADVANCED=y
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_LLDSCD is not set
+CONFIG_CPU_HAS_WB=y
+CONFIG_CPU_HAS_SYNC=y
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_NET=y
+CONFIG_PCI_NAMES=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_MIPS32_O32 is not set
+# CONFIG_MIPS32_N32 is not set
+# CONFIG_BINFMT_ELF32 is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PB1000 is not set
+# CONFIG_MTD_PB1500 is not set
+CONFIG_MTD_PB1100=y
+CONFIG_MTD_PB1500_BOOT=y
+CONFIG_MTD_PB1500_USER=y
+# CONFIG_MTD_CSTM_MIPS_IXX is not set
+# CONFIG_MTD_OCELOT is not set
+# CONFIG_MTD_LASAT is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_MS02NV is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MIPS_AU1X00_ENET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+CONFIG_IRDA=y
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+# CONFIG_IRNET is not set
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+# CONFIG_IRTTY_SIR is not set
+# CONFIG_IRPORT_SIR is not set
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_NSC_FIR is not set
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_TOSHIBA_FIR is not set
+CONFIG_AU1000_FIR=y
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VLSI_FIR is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_VT_CONSOLE is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+# CONFIG_SERIAL_TX3912 is not set
+# CONFIG_SERIAL_TX3912_CONSOLE is not set
+CONFIG_AU1X00_UART=y
+CONFIG_AU1X00_SERIAL_CONSOLE=y
+# CONFIG_TXX927_SERIAL is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS_FS=m
+CONFIG_JFFS_FS_VERBOSE=0
+CONFIG_JFFS_PROC_FS=y
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_CRAMFS=m
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_SMB_NLS=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_E1356 is not set
+CONFIG_FB_AU1100=y
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_CFB24 is not set
+# CONFIG_FBCON_CFB32 is not set
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_ALI5455 is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_AU1X00 is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff -urN linux-2.4.29/arch/mips/kernel/cpu-probe.c linux-2.4.29-uc1/arch/mips/kernel/cpu-probe.c
--- linux-2.4.29/arch/mips/kernel/cpu-probe.c	2005-01-19 14:09:29.000000000 +0000
+++ linux-2.4.29-uc1/arch/mips/kernel/cpu-probe.c	2005-06-14 02:11:19.000000000 +0100
@@ -5,6 +5,7 @@
 #include <asm/cpu.h>
 #include <asm/fpu.h>
 #include <asm/mipsregs.h>
+#include <asm/processor.h>
 
 /*
  * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
diff -urN linux-2.4.29/arch/mips/kernel/head.S linux-2.4.29-uc1/arch/mips/kernel/head.S
--- linux-2.4.29/arch/mips/kernel/head.S	2005-01-19 14:09:29.000000000 +0000
+++ linux-2.4.29-uc1/arch/mips/kernel/head.S	2005-06-14 02:11:20.000000000 +0100
@@ -33,7 +33,8 @@
 		 * Reserved space for exception handlers.
 		 * Necessary for machines which link their kernels at KSEG0.
 		 */
-		.fill	0x400
+		jal	kernel_entry
+		.balign  0x400
 
 		/* The following two symbols are used for kernel profiling. */
 		EXPORT(stext)
diff -urN linux-2.4.29/arch/mips/kernel/setup.c linux-2.4.29-uc1/arch/mips/kernel/setup.c
--- linux-2.4.29/arch/mips/kernel/setup.c	2005-01-19 14:09:29.000000000 +0000
+++ linux-2.4.29-uc1/arch/mips/kernel/setup.c	2005-06-14 02:11:19.000000000 +0100
@@ -265,7 +265,21 @@
 	 * Partially used pages are not usable - thus
 	 * we are rounding upwards.
 	 */
-	start_pfn = PFN_UP(__pa(&_end));
+	{
+		unsigned long	*sp, len = 0;
+
+		sp = (unsigned long *) &_end;
+		
+		if (memcmp(&sp[0], "-rom1fs-", 8) == 0) { /* romfs */
+			len = be32_to_cpu(sp[2]);
+			printk("romfs reserved %d\n", len);
+		} else if (sp[0] == 0x28cd3d45) { /* cramfs */
+			len = sp[1];
+			printk("cramfs reserved %d\n", len);
+		} else
+			printk("NOFS reserved @ 0x%x\n", sp);
+		start_pfn = PFN_UP(__pa(&_end + len));
+	}
 #endif	/* CONFIG_BLK_DEV_INITRD */
 
 	/* Find the highest page frame number we have available.  */
diff -urN linux-2.4.29/arch/mips/Makefile linux-2.4.29-uc1/arch/mips/Makefile
--- linux-2.4.29/arch/mips/Makefile	2005-01-19 14:09:26.000000000 +0000
+++ linux-2.4.29-uc1/arch/mips/Makefile	2005-06-14 02:11:17.000000000 +0100
@@ -17,7 +17,7 @@
 # Select the object file format to substitute into the linker script.
 #
 ifdef CONFIG_CPU_LITTLE_ENDIAN
-tool-prefix	= mipsel-linux-
+tool-prefix	= mips_fp_le-
 ld-emul		= elf32ltsmip
 else
 tool-prefix	= mips-linux-
@@ -306,6 +306,16 @@
 LOADADDR      += 0x80100000
 endif
 
+#
+# Velseis Vegas board
+#
+ifdef CONFIG_MIPS_VEGAS
+LIBS          += arch/mips/au1000/vegas/vegas.o \
+                 arch/mips/au1000/common/au1000.o
+SUBDIRS       += arch/mips/au1000/vegas arch/mips/au1000/common
+LOADADDR      += 0x80100000
+endif
+
 ifdef CONFIG_MIPS_PB1550
 LIBS          += arch/mips/au1000/pb1550/pb1550.o \
                  arch/mips/au1000/common/au1000.o
diff -urN linux-2.4.29/arch/niosnommu/boot/Makefile linux-2.4.29-uc1/arch/niosnommu/boot/Makefile
--- linux-2.4.29/arch/niosnommu/boot/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/boot/Makefile	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,5 @@
+clean:
+	rm -f *.[oa]
+
+dep depend:
+	:
diff -urN linux-2.4.29/arch/niosnommu/config.in linux-2.4.29-uc1/arch/niosnommu/config.in
--- linux-2.4.29/arch/niosnommu/config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/config.in	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,178 @@
+#
+# For a description of the syntax of this configuration file,
+# see the Configure script.
+#
+mainmenu_name 'uClinux/Nios (w/o MMU) Kernel Configuration'
+
+define_bool CONFIG_UCLINUX y
+define_bool CONFIG_UID16 y
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_RAMKERNEL y
+
+mainmenu_option next_comment
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+# if [ "$CONFIG_MODULES" = "y" ]; then
+#   bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
+#   bool 'Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD
+# fi
+endmenu
+
+
+mainmenu_option next_comment
+comment 'Platform dependant setup'
+
+choice 'CPU' \
+	"NIOS	CONFIG_NIOS" NIOS
+
+comment 'Platform'
+
+choice 'Platform' \
+	"EXCALIBUR	CONFIG_EXCALIBUR" EXCALIBUR
+
+# choice 'Kernel executes from' \
+#	"RAM	CONFIG_RAMKERNEL \
+#	 ROM	CONFIG_ROMKERNEL" ROM
+
+bool 'Flash CRC support' CONFIG_CRC_CHECK
+if [ "$CONFIG_CRC_CHECK" = "y" ]; then
+  bool '  Prompt for action on failure' CONFIG_PROMPT_ON_MISSING_CRC_TABLES
+fi
+
+endmenu
+
+mainmenu_option next_comment
+comment 'General setup'
+
+# bool 'PCI bios support' CONFIG_PCI
+# if [ "$CONFIG_PCI" = "y" ]; then
+#	bool '    PCI device list support' CONFIG_PCIDEVLIST
+# fi
+
+bool 'Networking support' CONFIG_NET
+bool 'System V IPC' CONFIG_SYSVIPC
+# bool 'Reduced memory footprint' CONFIG_REDUCED_MEMORY
+bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   choice 'Kernel core (/proc/kcore) format' \
+	"ELF		CONFIG_KCORE_ELF	\
+	 A.OUT		CONFIG_KCORE_AOUT" ELF
+fi
+tristate 'Kernel support for flat binaries' CONFIG_BINFMT_FLAT
+# tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
+# tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF
+bool 'Kernel support for remote GDB client' CONFIG_KGDB
+if [ "$CONFIG_KGDB" = "y" ]; then
+  bool '  Include breakpoint trap on kernel startup' CONFIG_BREAK_ON_START
+fi
+endmenu
+
+define_string CONFIG_CMDLINE "CONSOLE=/dev/ttyS0 root=/dev/rom0 ro"
+
+# source drivers/mtd/Config.in
+# source drivers/pnp/Config.in
+
+source drivers/block/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+  source net/Config.in
+fi
+
+mainmenu_option next_comment
+comment 'ATA/IDE/MFM/RLL support'
+
+tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+
+if [ "$CONFIG_IDE" != "n" ]; then
+  source drivers/ide/Config.in
+else
+  define_bool CONFIG_BLK_DEV_HD n
+fi
+endmenu
+
+# mainmenu_option next_comment
+# comment 'SCSI support'
+# tristate 'SCSI support' CONFIG_SCSI
+# if [ "$CONFIG_SCSI" != "n" ]; then
+#   source drivers/scsi/Config.in
+# fi
+# endmenu
+
+source drivers/ieee1394/Config.in
+
+# source drivers/i2o/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Network device support'
+
+   bool 'Network device support' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+      if [ "$CONFIG_ATM" = "y" ]; then
+         source drivers/atm/Config.in
+      fi
+   fi
+   endmenu
+fi
+
+# source net/ax25/Config.in
+
+# source net/irda/Config.in
+
+# mainmenu_option next_comment
+# comment 'ISDN subsystem'
+# if [ "$CONFIG_NET" != "n" ]; then
+#   tristate 'ISDN support' CONFIG_ISDN
+#   if [ "$CONFIG_ISDN" != "n" ]; then
+#      source drivers/isdn/Config.in
+#   fi
+# fi
+# endmenu
+
+# mainmenu_option next_comment
+# comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+
+# bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+# if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+#    source drivers/cdrom/Config.in
+# fi
+# endmenu
+
+source drivers/char/Config.in
+
+source fs/Config.in
+
+if [ "$CONFIG_VT" = "y" ]; then
+  source drivers/video/Config.in
+fi
+
+source drivers/usb/Config.in
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+bool 'Full Symbolic/Source Debugging support' CONFIG_FULLDEBUG
+#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
+bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+
+bool 'Kernel profiling support' CONFIG_PROFILE
+if [ "$CONFIG_PROFILE" = "y" ]; then
+  int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+  bool 'Use fast second timer for profiling' CONFIG_HIGHPROFILE
+fi
+
+bool 'Suppress Kernel BUG Messages' CONFIG_NO_KERNEL_MSG
+
+endmenu
+
+source crypto/Config.in
+source lib/Config.in
diff -urN linux-2.4.29/arch/niosnommu/defconfig linux-2.4.29-uc1/arch/niosnommu/defconfig
--- linux-2.4.29/arch/niosnommu/defconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/defconfig	2005-06-14 02:11:08.000000000 +0100
@@ -0,0 +1,366 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Top level menu options
+#
+CONFIG_UCLINUX=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_RAMKERNEL=y
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+
+#
+# Platform dependant setup
+#
+CONFIG_NIOS=y
+
+#
+# Platform
+#
+CONFIG_EXCALIBUR=y
+# CONFIG_CRC_CHECK is not set
+
+#
+# General setup
+#
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_FLAT=y
+CONFIG_KERNEL_ELF=y
+CONFIG_KGDB=y
+# CONFIG_BREAK_ON_START is not set
+CONFIG_CMDLINE="root=/dev/rom0 ro"
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_BLKMEM=y
+CONFIG_NOFLASH=y
+# CONFIG_AMDFLASH is not set
+# CONFIG_INTELFLASH is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+CONFIG_IDE_CHIPSETS=y
+
+#
+# Note: most of these also require special kernel boot parameters
+#
+# CONFIG_BLK_DEV_4DRIVES is not set
+# CONFIG_BLK_DEV_ALI14XX is not set
+# CONFIG_BLK_DEV_DTC2278 is not set
+# CONFIG_BLK_DEV_HT6560B is not set
+CONFIG_BLK_DEV_OCIDEC=y
+# CONFIG_BLK_DEV_QD65XX is not set
+# CONFIG_BLK_DEV_UMC8672 is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+# CONFIG_ULTRAMCA is not set
+# CONFIG_ULTRA is not set
+# CONFIG_ULTRA32 is not set
+# CONFIG_SMC9194 is not set
+CONFIG_SMC91111=y
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FEC is not set
+CONFIG_CS89x0=y
+# CONFIG_UCCS89x0_HW_SWAP is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Character devices
+#
+CONFIG_NIOS_SERIAL=y
+CONFIG_NIOS_SPI=y
+# CONFIG_LEDMAN is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_SERIO is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFSD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+
+#
+# USB Device Class drivers
+#
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+# USB Imaging devices
+#
+
+#
+# USB Multimedia devices
+#
+
+#
+# USB Network adaptors
+#
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+
+#
+# USB Miscellaneous drivers
+#
+
+#
+# Kernel hacking
+#
+# CONFIG_FULLDEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_PROFILE is not set
+# CONFIG_NO_KERNEL_MSG is not set
diff -urN linux-2.4.29/arch/niosnommu/kernel/bootcfg.h linux-2.4.29-uc1/arch/niosnommu/kernel/bootcfg.h
--- linux-2.4.29/arch/niosnommu/kernel/bootcfg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/bootcfg.h	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,35 @@
+/* common parameters */
+
+/* CPU frequency */
+#define CPU_FREQ  20000000
+
+/* desired uart baud rate */
+#define BAUD_RATE 9600
+
+/* RAM window start */
+#define RAM_WINDOW 0x40000000
+
+/* memory size of each ram bank (bytes) */
+#define RAM_BANK_SIZE 0x80000
+
+/* number of memory banks */
+#define RAM_BANKS 1
+
+/* init value for memory configuration register 1, PROM 3ws, 2M*/
+#define MEMCFG1_VAL	0x00020033
+
+/* init value for memory configuration register 2, RAM  2ws, 512k */
+/* DEPENDS ON RAM_BANK_SIZE!!! */
+#define MEMCFG2_VAL 0xc0a
+
+
+/* AUTOMATICALLY GENERATED */
+
+/* init value for timer pre-scaler */
+#define TIMER_SCALER_VAL (CPU_FREQ -1)
+
+/* init value for uart pre-scaler */
+#define UART_SCALER_VAL  ((CPU_FREQ / (8 * BAUD_RATE)) - 1)
+
+/* stack pointer for boot application */
+#define STACK_INIT	(((RAM_BANK_SIZE * RAM_BANKS) - 16) + RAM_WINDOW)
diff -urN linux-2.4.29/arch/niosnommu/kernel/entry.S linux-2.4.29-uc1/arch/niosnommu/kernel/entry.S
--- linux-2.4.29/arch/niosnommu/kernel/entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/entry.S	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,1135 @@
+/*
+ * arch/niosnommu/kernel/entry.S:  NIOS trap low-level entry points.
+ *
+ * Copyright (C) 2001 Vic Phillips (vic@microtronix.com)
+ *
+ * based on sparcnommu
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/errno.h>
+
+#include "nios_defs.h"
+
+#include <asm/niosasm.h>
+#include <asm/ptrace.h>
+#include <asm/cprefix.h>
+#include <asm/winmacro.h>
+#include <asm/asmmacro.h>
+
+
+
+	.macro	SAVE_LAST_WINDOW
+
+	pfx	8
+	wrctl	%g5				; disable interrupts
+	 nop
+	 nop
+
+;	pfx	0
+	rdctl	%g5				; read STATUS
+	ANDIP	%g5, PSR_CWP	; isolate CWP
+
+	pfx	2
+	rdctl	%g4				; read WVALID
+	lsri	%g4, 1			; get HI_LIMIT into CWP position
+	ANDIP	%g4, PSR_CWP	; isolate it
+
+	GET_CURRENT	g6
+	ADDIP %g6, TASK_THREAD+THREAD_SPARE_W_SAVED
+	st [%g6], %fp			; save sp for parent
+
+	SUBIP %g6, THREAD_SPARE_W_SAVED-THREAD_SPARE_REG_WINDOW
+
+	cmp	%g5, %g4			; reached HI_LIMIT yet ?
+	BNE	6f					; No
+	nop
+
+	; copy l, i regs from [fp] to [g6]
+
+
+	mov %g4, %fp
+	movi %g7, 16
+5:	
+	; for (i=0;i<g7;i++) [g4++]->[g6++]
+	ld %g5, [%g4]		
+	st [%g6], %g5
+	addi %g4, 4
+	subi %g7, 1
+	BNE 5b
+	addi %g6, 4				; delay slot
+
+	br 7f	
+	nop
+
+6:
+	; copy 1, i regs from last reg windows to [g6]
+	mov %g5, %sp
+	restore
+	mov %g4, %sp			; save sp
+	mov %sp, %g6			; 
+	STORE_WINDOW
+	mov %sp, %g4
+	save %sp, 0
+	mov %sp, %g5
+7:
+	pfx	9
+	wrctl	%g5				; enable interrupts
+
+	.endm
+
+
+
+	.macro	LOAD_LAST_WINDOW
+	pfx	8
+	wrctl	%g5				; disable interrupts
+	 nop
+	 nop
+
+	; copy back the registers from thread_struct to user stack
+
+
+	GET_CURRENT	g6
+	ADDIP %g6, TASK_THREAD+THREAD_SPARE_W_SAVED
+	ld %fp, [%g6]			; get the saved sp
+	SUBIP %g6, THREAD_SPARE_W_SAVED-THREAD_SPARE_REG_WINDOW
+
+
+	mov %g4, %fp
+	movi %g7, 16
+3:	
+	; for (i=0;i<g7;i++) [g6++]->[g4++]
+	ld %g5, [%g6]		
+	st [%g4], %g5
+	addi %g4, 4
+	subi %g7, 1
+	BNE 3b
+	addi %g6, 4				; delay slot
+
+;	pfx	0
+	rdctl	%g5				; read STATUS
+	ANDIP	%g5, PSR_CWP	; isolate CWP
+
+	pfx	2
+	rdctl	%g4				; read WVALID
+	lsri	%g4, 1			; get HI_LIMIT into CWP position
+	ANDIP	%g4, PSR_CWP	; isolate it
+
+	cmp	%g5, %g4			; reached HI_LIMIT yet ?
+	BEQ	4f					; No
+	nop
+
+	; refresh the last register window
+	mov %g5, %sp
+	restore
+	LOAD_WINDOW
+	save %sp,0
+	mov %sp, %g5
+
+4:
+	pfx	9
+	wrctl	%g5				; enable interrupts
+
+	.endm
+	
+
+/* define a macro for calling syscall_trace */
+	.macro	SYS_CALL_TRACE
+#if 0
+	GET_CURRENT	l3
+	ldp	%l3, [%l3, TASK_FLAGS/4]
+	skp1	%l3, 5				; 0x20 = bit 5
+	br	ret\@
+	 nop
+	MOVIA	%l3,C_LABEL(syscall_trace)@h
+	call	%l3
+	 nop
+ret\@:
+#endif
+	.endm
+
+/* All trap entry points _must_ begin with this macro or else you
+ * lose.  It makes sure the kernel has a proper window so that
+ * c-code can be called.
+ */
+.macro	SAVE_ALL
+	MOVIA	%l7, ret\@@h
+	br	trap_setup
+	 nop
+ret\@:
+.endm
+
+/* All traps low-level code here must end with this macro.
+ */
+.macro	RESTORE_ALL
+	br	ret_trap_entry
+	 nop
+.endm
+
+
+	.text
+	/* fs/binfmt_flat.c loader debug trap handler.
+	 * Set debug in the current task's thread flags.
+	 * This flags binfmt_flat loader to cause a gdb trap when
+	 * the application starts.
+	 */
+	.align	2
+	.globl	binfmt_flat_debug_handler
+binfmt_flat_debug_handler:
+
+	/* WARNING! Never, ever, put a GDB breakpoint (or single step thru)
+	 *          here!  The bpt trap will stomp the ISTATUS.
+	 */
+	LOAD_CURRENT	l3
+	ADDIP	%l3, TASK_THREAD+THREAD_FLAGS
+	ld	%l2, [%l3]
+	ORIP	%l2, NIOS_FLAG_DEBUG
+	st	[%l3], %l2
+	tret	%o7
+
+	
+.ifdef na_ide_interface
+	.align	2
+	.globl	ocidec_handler
+ocidec_handler:
+
+	/* WARNING! Never, ever, put a GDB breakpoint (or single step thru)
+	 *          here!  The bpt trap will stomp the ISTATUS.
+	 */
+
+	MOVIP	%l0,na_ide_interface+4	; get ocidec address - status word
+	movi	%l1,0			; write zero to clear interrupt
+	st	[%l0],%l1		; 
+	br	real_irq_entry		; continue with common interrupt handling
+	 nop				; 
+.endif
+
+	.align	2
+	.globl	timer_handler
+timer_handler:
+
+	/* WARNING! Never, ever, put a GDB breakpoint (or single step thru)
+	 *          here!  The bpt trap will stomp the ISTATUS.
+	 */
+
+	MOVIP	%o1,na_timer0		; get timer address
+	movi	%o0,0			; 
+	pfx	np_timerstatus		;
+	st	[%o1],%o0		; clear interrupt condition
+;;;	br	real_irq_entry		; continue with common interrupt handling
+;;;	 nop				; 
+
+
+/* For now all IRQ's not registered get sent here. handler_irq() will
+ * see if a routine is registered to handle this interrupt and if not
+ * it will say so on the console.
+ */
+
+	.align	2
+	.globl	real_irq_entry
+real_irq_entry:
+
+	/* WARNING! Never, ever, put a GDB breakpoint (or single step thru)
+	 *          here!  The bpt trap will stomp the ISTATUS.
+	 */
+	SAVE_ALL			; common interrupt setup
+
+	/* Enable under/over traps w/IRQs off, so we can call c-code properly. */
+;;;	pfx	0			;
+	rdctl	%g0			; get status
+	mov	%o0, %g0		; copy to preserve IPRI
+	ANDNIP	%g0, PSR_IPRI		; remove old IPRI
+	ORIP	%g0, PSR_IE | PSR_IPRI_3
+;;;	pfx	0			;
+	wrctl	%g0			; reset to allow only o/u/flow traps
+	 nop
+	 nop
+
+	ANDIP	%o0, PSR_IPRI		; isolate the IPRI
+	mov	%o1, %sp
+	ADDIP	%o1, REGWIN_SZ		; arg1 = pt_regs ptr
+	MOVIA	%l5, C_LABEL(process_int)@h
+	call	%l5
+	 lsri	%o0, 9			; arg0 = vector/irq #
+
+	RESTORE_ALL
+
+
+	/* This routine handles invalid traps/interrupts
+	 */
+	.align	2
+	.globl	bad_trap_handler
+bad_trap_handler:
+
+	/* WARNING! Never, ever, put a GDB breakpoint (or single step thru)
+	 *          here!  The bpt trap will stomp the ISTATUS.
+	 */
+	SAVE_ALL
+;;;	pfx	0			;
+	rdctl	%g0			; get status
+	mov	%o0, %g0		; copy to preserve IPRI
+	ANDNIP	%g0, PSR_IPRI		; remove old IPRI
+	ORIP	%g0, PSR_IE | PSR_IPRI_3
+;;;	pfx	0			;
+	wrctl	%g0			; to allow only o/u/f traps
+	 nop
+	 nop
+	ANDIP	%o0, PSR_IPRI		; isolate the IPRI
+	lsri	%o0, 9					; arg0 = vector/irq #
+	lds	%o1, [%sp, (REGWIN_SZ + PT_PSR)/4]	; arg1 = psr
+	MOVIA	%l5, C_LABEL(do_hw_interrupt)@h
+	call	%l5
+	 lds	%o2, [%sp, (REGWIN_SZ + PT_PC)/4]	; arg2 = pc
+	RESTORE_ALL
+
+
+	/* Linux native system calls enter here... */
+
+	/* inputs are:
+	 *  %g1 = syscall #
+	 *  %i0 = first argument (if any)
+	 *  %i1 = second argument (if any)
+	 *  %i2 = third argument (if any)
+	 *  %i3 = fourth argument (if any)
+	 *  %i4 = fifth argument (if any)
+	 *  %i5 = sixth argument (if any)
+	 *
+	 *  %i6 = %fp
+	 *
+	 *  %o7 = return address
+	 *
+	 */
+
+	.align	2
+	.globl	C_LABEL(system_call)
+C_LABEL(system_call):
+	/* TODO: When we have ptrace working test for PF_TRACESYS in task flags. */
+
+	SAVE_ALL				; common interrupt setup (%g1 preserved)
+
+/* FIXME - What if IPRI has IRQ's blocked when the syscall trap was done ?
+ *         Doesn't this mean we're enabling interrupts prematurely?
+ *         Maybe we should restore IPRI from ISTATUS.
+ */
+	pfx	9				; 
+	wrctl	%g0				; enable interrupts
+
+	CMPIP	%g1, NR_syscalls		; syscall # in range ?
+	ifs	cc_lt
+	br	1f
+	 lsli	%g1,2				;  (delay slot) index * 4
+	
+	MOVIA	%l7,C_LABEL(sys_ni_syscall)@h	; No, use "not implemented"
+	br	2f
+	 nop
+1:
+	MOVIA	%l7,sys_call_table		; Yes, get ptr to syscall table
+	add	%l7, %g1			; get table entry
+	ld	%l7, [%l7] 
+	sts	[%sp, (REGWIN_SZ + PT_SYSC_NO)/4], %g1	; save syscall # (checked by do_signal)
+2:
+	SYS_CALL_TRACE
+
+	lds	%o0, [%sp, (REGWIN_SZ + PT_I0)/4]	; get args into %o0-5
+	lds	%o1, [%sp, (REGWIN_SZ + PT_I1)/4]
+	lds	%o2, [%sp, (REGWIN_SZ + PT_I2)/4]
+	lds	%o3, [%sp, (REGWIN_SZ + PT_I3)/4]
+	lds	%o4, [%sp, (REGWIN_SZ + PT_I4)/4]
+	lds	%o5, [%sp, (REGWIN_SZ + PT_I5)/4]
+
+	sts	[%sp, (REGWIN_SZ + PT_ORIG_I0)/4], %o0	; save first arg for restarting syscalls
+
+	call	%l7					; call syscall handler
+	 nop
+
+	sts	[%sp, (REGWIN_SZ + PT_I0)/4], %o0	; save the returned arg
+
+
+	.globl	C_LABEL(ret_sys_call)
+C_LABEL(ret_sys_call):
+	lds	%o0, [%sp, (REGWIN_SZ + PT_I0)/4]	; retrieve returned arg
+	SYS_CALL_TRACE
+	RESTORE_ALL
+
+
+
+/* At trap time, interrupts and all generic traps do the following:
+ *
+ * SAVE_ALL macro which does:
+ *
+ * 	MOVIA	%l7,return_address@h
+ * 	br	trap_setup
+ * 	 nop
+ * return_address:
+ *
+ * The entering values are:
+ *
+ *  %g1 = possible syscall #
+ *  %i0 - %i5 - possible syscall arguments
+ *  %fp = interruptee's stack ptr
+ *  %l7 = return address of caller
+ *
+ * The returning values are:
+ *
+ *  %g1 = possible syscall # (preserved)
+ *  %sp = kernel stack ptr with PT_REGS structure stored
+ *
+ */
+
+	.align 2
+	.globl	C_LABEL(trap_setup)
+C_LABEL(trap_setup):
+
+	pfx	1
+	rdctl	%l1				; read ISTATUS (interruptee's psr)
+	ext16s	%l1, 0				; clear upper part
+
+	MOVIA	%l0, nios_status		; get STATUS extension
+	ld	%l2, [%l0]			; 
+	ANDNIP	%l2, 0xffff			; clear lower stuff
+	or	%l1, %l2			; save as extended ISTATUS
+	bgen	%l3, PSR_SUPERVISOR_BIT		; set supervisor mode
+	st	[%l0], %l3			; into current extended STATUS
+
+	/* See if from user or kernel */
+	skp0	%l2, PSR_SUPERVISOR_BIT		; interrupted mode = supervisor ?
+	br	1f				; yes, from kernel
+	 mov	%sp, %fp			; assume from kernel: get kernel stack ptr
+	LOAD_CURRENT	l0			; from user: get kernel stack pointer
+	ADDIP	%l0,THREAD_SIZE			;vic; start from the top of stack again ?
+	mov	%sp, %l0			;vic;
+
+1:
+	SUBIP	%sp, REGWIN_SZ+TRACEREG_SZ	; allocate more stack
+	STORE_PT_ALL	l1, o7			; save interruptee's %g's, %o's, STATUS, return address
+
+	bgen	%g0, 0
+	neg	%g0				; -1 -> g0
+	sts	[%sp, (REGWIN_SZ + PT_SYSC_NO)/4], %g0	; init the place of saved syscall no by -1
+	
+	/* See if we are in the last window (LO_LIMIT-1). */
+;;;	pfx	0
+	rdctl	%g0				; read STATUS (interrupt psr)
+	ANDIP	%g0, PSR_CWP			; isolate CWP
+
+	pfx	2
+	rdctl	%g4				; read WVALID
+	mov	%g3, %g4			; get LO_LIMIT into CWP position
+	lsli	%g3, 4
+	ANDIP	%g3, PSR_CWP			; isolate it
+	cmp	%g0, %g3			; CWP < LO_LIMIT ?
+	BLT	2f				; Yes - big overhead coming
+	 nop
+	jmp	%l7				; return to caller
+	 nop
+
+	/* In last window (LO_LIMIT-1) - need to flush and reopen register file.
+	 * The current window will be switched to HI_LIMIT and left pointing
+	 * at the same stack frame.  The only other register that needs to be
+	 * preserved and restored into the new window is the frame ptr (%fp).
+	 * No other %o or %l registers need to be preserved as these are ours
+	 * only and we really haven't used them yet.  The other %i registers
+	 * don't need to be preserved here since they are saved and restored
+	 * from the pt_regs frame.  So we start flushing register windows into
+	 * the stack frames starting with LO_LIMIT and ending at HI_LIMIT.
+	 */
+2:
+	mov	%g6, %sp			; save stack ptr
+	mov	%g7, %l7			; and caller's return address
+
+	lsri	%g4, 1				; get HI_LIMIT into CWP position
+	ANDIP	%g4, PSR_CWP			; isolate it
+	STORE_WINDOW				; save %i's & %l's in register window
+3:
+	restore					; CWP ++
+	STORE_WINDOW				; save %i's & %l's from this register window
+	addi	%g0, 0x10			; step our value for CWP
+	cmp	%g0, %g4			; reached HI_LIMIT yet ?
+	BNE	3b				; No
+	 nop
+						; Yes, CWP = HI_LIMIT
+	mov	%sp, %g6			; restore stack pointer into it
+	LOAD_WINDOW				; restore %i's & %l's into this window
+	jmp	%g7				; return to caller (saved %l7)
+	 nop
+
+
+/* All interrupt routines return thru here via RESTORE_ALL
+ *
+ * We need to check for a few things which are:
+ * 1) The need to call schedule() because this process's quantum is up.
+ * 2) Pending signals for this process.  If any exist we need to call
+ *     do_signal() to do the needy.
+ *
+ * Else we just check if the tret would land us in an invalid window,
+ * if so we need to refill the register file from the user/kernel stack first.
+ */
+
+	.align 2
+	.globl	ret_trap_entry
+ret_trap_entry:
+
+#if 0
+	/* disable other interrupts */
+;;;	pfx	0			;
+	rdctl	%g0			; get status
+	ANDNIP	%g0, PSR_IPRI		; remove old IPRI
+	ORIP	%g0, PSR_IE | PSR_IPRI_3
+;;;	pfx	0			;
+	wrctl	%g0			; reset to allow only o/u/flow traps
+	 nop
+	 nop
+#endif
+
+	lds	%l5, [%sp, (REGWIN_SZ + PT_PSR)/4]	; get ISTATUS
+	skp0	%l5, PSR_SUPERVISOR_BIT		; from supervisor ?
+	br	ret_trap_kernel			; Yes
+	 nop
+	
+	GET_CURRENT	l3			; from user - check scheduling
+	ldp	%l4, [%l3, TASK_NEED_RESCHED/4]
+	skprnz	%l4
+	br	signal_p
+	 nop
+	MOVIA	%l6, C_LABEL(schedule)@h
+	call	%l6
+	 nop
+
+	/* Try to return again... We are a different process,
+	 * most likely so load and then check if going back
+	 * to user or kernel this time.
+	 */
+	br	ret_trap_entry
+	 nop
+
+signal_p:
+	/* No signals for swapper. */
+	GET_CURRENT	l3
+
+	MOVIA	%l5, C_LABEL(init_task_union)
+	cmp	%l5, %l3		; task 0 ?
+	BEQ	ret_trap_continue	; Yes
+	 nop
+
+	ldp	%l4, [%l3, TASK_SIGPENDING/4]
+	skprnz	%l4
+	 br	ret_trap_continue
+	 xor  %o0, %o0			; oldset shall be NULL when called from here
+	mov	%o1, %sp
+	ADDIP	%o1, REGWIN_SZ		; pt_regs ptr
+	MOVIA	%l6, C_LABEL(do_signal)@h
+	call	%l6
+	 nop
+	/* Fall through... */
+
+ret_trap_continue:
+ret_trap_kernel:
+	pfx	8
+	wrctl	%g0			; disable interrupts
+	 nop
+	 nop
+
+	lds	%l1, [%sp, (REGWIN_SZ + PT_PSR)/4]  ; get saved ISTATUS
+	ANDIP	%l1, PSR_CWP		; isolate saved CWP
+;;;	pfx	0
+	rdctl	%g0			; read STATUS (note IE = 0)
+	mov	%g1, %g0		
+	ANDIP	%g1, PSR_CWP		; isolate CWP
+
+	subi	%l1, 0x0010		; decrement saved CWP to what it
+					;   would have been after the trap
+	cmp	%g1, %l1		; this should equal current CWP
+	BEQ	4f			; it does ... whew!
+	 nop
+
+	/* The CWP being returned to is not one-off the current
+	 * find out if the original trap did a flush.
+	 */
+
+	pfx	2
+	rdctl	%g3			; read WVALID
+	mov	%g4, %g3		; get HI_LIMIT into CWP position
+	lsri	%g4, 1			; 
+	ANDIP	%g4, PSR_CWP		; isolate it
+	lsli	%g3, 4			; Get LO_LIMIT into CWP position
+	ANDIP	%g3, PSR_CWP		; isolate it
+	subi	%g3, 0x0010		; set to LO_LIMIT-1
+
+	cmp	%l1, %g3		; saved CWP-1 = LO_LIMIT-1 ?
+	BNE	1f			; No
+	 nop
+	cmp	%g1, %g4		; CWP = HI_LIMIT ?
+	BEQ	2f			; Yes
+	 nop
+1:
+	trap	5			;vic; yikes ! panic time ! what's wrong here ?
+2:
+
+	/* Refill register file from corresponding stacked register
+	 * windows.  At this point, saved ISTATUS has CWP = LO_LIMIT
+	 * which means the trap that got us here had to flush the
+	 * register file to the stack and reopen the file to the top
+	 * and CWP went from LO_LIMIT-1 to HI_LIMIT where we are now.
+	 *
+	 * ie, STATUS.CWP = HI_LIMIT and must end up at LO_LIMIT-1
+	 *            to which the PT_REGS.i are restored
+	 * so that the tret restoring ISTATUS.CWP = LO_LIMIT has the
+	 *            %o's in the right place.
+	 */
+
+	; %g0 = current STATUS
+	; %g1 = current CWP
+	; %sp -> pt_regs
+
+
+	; transfer window from HI_LIMIT to LO_LIMIT-1
+	; then climb the reg file
+
+#ifdef DEBUG
+	/* What if current %fp is not the same as the pt_fp ? */
+	lds	%l6, [%sp, (REGWIN_SZ + PT_I6)/4]
+	cmp	%fp, %l6		; the same?
+	skps	cc_z			; yes
+	trap	5			; no, call me
+#endif
+	mov	%g6, %sp		; save stack ptr
+
+	ANDNIP	%g0, PSR_CWP		; remove current CWP from STATUS value
+	mov	%g1, %g3		; replace with LO_LIMIT - 1 
+	or	%g0, %g1		;
+;;;	pfx	0			;
+	wrctl	%g0			; set new CWP
+	 nop
+	 nop
+	mov	%sp, %g6		; transfer stack ptr into it
+3:
+	LOAD_WINDOW			; refill window from corresponding stack	
+	restore				; goto next window
+	cmp	%g1, %g4		; CWP = HI_LIMIT ?
+	BNE	3b			; nope
+	 addi	%g1, 0x0010		; bump to next window
+
+	ANDNIP	%g0, PSR_CWP		; remove current CWP from STATUS value
+	or	%g0, %g3		; replace with LO_LIMIT - 1 
+;;;	pfx	0			;
+	wrctl	%g0			; set CWP to LO_LIMIT-1 again
+	 nop
+	 nop
+	mov	%sp, %g6		; retrieve stack ptr
+4:
+	LOAD_PT_ALL	l1, o7		; reload g's & i's, get ISTATUS & ret addr
+
+	/* WARNING! Never, ever, put a GDB breakpoint (or single step thru)
+	 *          here!  The bpt trap will stomp the ISTATUS.
+	 */
+	pfx	1
+	wrctl	%l1			; write ISTATUS (for tret to make current)
+	ANDNIP	%l1, 0xffff		; clear lower part
+	MOVIA	%l0, nios_status	; set STATUS extension
+	st	[%l0], %l1		;
+	tret	%o7			; return to whoever (could be task switch)
+	nop
+
+
+	/* Note how we really return to ret_sys_call because we share the
+	 * register window with our caller.
+	 */
+
+	.align	2
+	.globl	C_LABEL(sys_ptrace)
+C_LABEL(sys_ptrace):
+	mov	%o0, %sp
+	ADDIP	%o0, REGWIN_SZ			; pt_regs *regs arg
+	MOVIA	%l7, C_LABEL(do_ptrace)@h
+	call	%l7
+	 nop
+	SYS_CALL_TRACE
+	RESTORE_ALL
+
+
+	.align	2
+	.globl	C_LABEL(sys_execve)
+C_LABEL(sys_execve):
+	;; xwt: here we move the current window to the high limit
+	pfx	8
+	wrctl	%g5				; disable interrupts
+	 nop
+	 nop
+	FLUSH_WINDOWS
+	
+	mov		%g6, %sp;			; keep %sp
+	
+	;; change CWP
+	pfx	2
+	rdctl	%g4				; read WVALID
+	lsri	%g4, 1			; get HI_LIMIT into CWP position
+	MOVIP  %g7, PSR_CWP
+	AND 	%g4, %g7	; isolate it
+	;pfx	0
+	rdctl	%g5				; read STATUS
+	ANDN   %g5, %g7			; clear CWP
+	or	   %g5, %g4
+	;pfx	0
+	wrctl	%g5				; update STATUS
+	 nop
+	 nop
+
+	mov		%sp, %g6		; read back %sp, output regs
+	lds	%i6, [%sp, RW_I6/4]	; LOAD_WINDOW is OK, but actually only %fp is enough
+
+
+	pfx	9
+	wrctl	%g5				; enable interrupts
+	;; xwt: ok, we can go nios_execve.
+
+
+	mov	%o0, %sp
+	ADDIP	%o0, REGWIN_SZ			; pt_regs *regs arg
+	MOVIA	%l7, C_LABEL(nios_execve)@h
+	call	%l7
+	 nop
+	sts	[%sp,(REGWIN_SZ + PT_I0)/4],%o0	; save the returned arg
+
+	;; xwt: if nios_execve succeeds, we move the current window
+	;;      to HI_LIMIT-1, otherwise we restore the saved CWP
+	pfx	8
+	wrctl	%g5				; disable interrupts
+	 nop
+	 nop
+
+	MOVIP  %g7, PSR_CWP
+	lds    %g4, [%sp, (REGWIN_SZ + PT_PSR)/4]		; get saved ISTATUS
+	and    %g4, %g7			; get ICWP
+
+	mov		%g6, %sp;			; keep %sp
+
+	pfx	2
+	rdctl	%g5				; read WVALID
+	mov		%g3, %g5
+	lsli	%g3, 4			; get LO_LIMIT into CWP position
+	and		%g3, %g7		; isolate it
+	cmp		%g4, %g3		; ICWP == LO_LIMIT ?
+	BNE	2f
+	nop
+
+	lsri	%g5, 1			; get HI_LIMIT into CWP position
+	and		%g5, %g7		; isolate it
+	br		3f
+	mov		%g4, %g5		; delay slot
+
+2:
+	SUBIP  %g4, 0x0010		; get CWP we shall change to
+3:
+	;pfx	0
+	rdctl	%g5				; read STATUS
+;;	MOVIP  %g7, PSR_CWP
+	ANDN   %g5, %g7			; clear CWP
+	or	   %g5, %g4
+	;pfx	0
+	wrctl	%g5				; update STATUS
+	 nop
+	 nop
+
+	mov		%sp, %g6		; read back %sp, output regs
+
+	FILL_WINDOWS
+	pfx	9
+	wrctl	%g5				; enable interrupts
+	;; xwt: ok, we can continue
+
+	br	ret_sys_call			;
+	 nop
+
+
+	.align	2
+	.globl	C_LABEL(sys_sigaltstack)
+C_LABEL(sys_sigaltstack):
+	/* Note: %o0, %o1 (arg0, arg1) already have correct value... */
+//vic FIXME  is this right ?
+	lds	%o2, [%sp, (REGWIN_SZ + PT_I6)/4] ; arg2 = user's stack (fp)
+	MOVIA	%l7, C_LABEL(do_sigaltstack)@h
+	call	%l7
+	 nop
+	SYS_CALL_TRACE
+	/* We are returning to a signal handler. */
+	RESTORE_ALL
+
+
+	.align	2
+	.globl	C_LABEL(sys_sigsuspend)
+C_LABEL(sys_sigsuspend):
+	/* Note: %o0 (arg0) already has correct value... */
+	mov	%o1, %sp
+	ADDIP	%o1, REGWIN_SZ			; arg1 = pt_regs *regs arg
+	MOVIA	%l7, C_LABEL(do_sigsuspend)@h
+	call	%l7
+	 nop
+	SYS_CALL_TRACE
+	/* We are returning to a signal handler. */
+	RESTORE_ALL
+
+
+	.align	2
+	.globl	C_LABEL(sys_rt_sigsuspend)
+C_LABEL(sys_rt_sigsuspend):
+	/* Note: %o0, %o1 (arg0, arg1) already have correct value... */
+	mov	%o2, %sp
+	ADDIP	%o2, REGWIN_SZ			; arg 2 = pt_regs *regs arg
+	MOVIA	%l7, C_LABEL(do_rt_sigsuspend)@h
+	call	%l7
+	 nop
+	SYS_CALL_TRACE
+	/* We are returning to a signal handler. */
+	RESTORE_ALL
+
+
+	.align	2
+	.globl	C_LABEL(sys_sigreturn)
+C_LABEL(sys_sigreturn):
+	mov	%o0, %sp
+	ADDIP	%o0, REGWIN_SZ			; pt_regs *regs arg
+	MOVIA	%l7, C_LABEL(do_sigreturn)@h
+	call	%l7
+	 nop
+	SYS_CALL_TRACE
+	/* We don't want to muck with user registers like a
+	 * normal syscall, just return.
+	 */
+	RESTORE_ALL
+
+
+	.align	2
+	.globl	C_LABEL(sys_rt_sigreturn)
+C_LABEL(sys_rt_sigreturn):
+	mov	%o0, %sp
+	ADDIP	%o0, REGWIN_SZ			; pt_regs *regs arg
+	MOVIA	%l7, C_LABEL(do_rt_sigreturn)@h
+	call	%l7
+	 nop
+	SYS_CALL_TRACE
+	/* We don't want to muck with user registers like a
+	 * normal syscall, just return.
+	 */
+	RESTORE_ALL
+
+
+	.align	2
+	.globl	C_LABEL(sys_fork)
+C_LABEL(sys_fork):
+	.globl	C_LABEL(sys_vfork)
+C_LABEL(sys_vfork):
+	
+	SAVE_LAST_WINDOW
+;;;	pfx	0
+	rdctl	%g4				; Get STATUS
+	ANDIP	%g4, 0xffff			; clear upper stuff
+#if 1
+	pfx	8
+	wrctl	%g0				; disable interrupts
+	 nop
+	 nop
+#endif
+	STORE_WINDOW
+
+	MOVIA	%l2, nios_status		; add STATUS extension
+	ld	%l2, [%l2]			; 
+	ANDNIP	%l2, 0xffff			; clear lower stuff
+	or	%g4, %l2			;
+
+	GET_CURRENT	g6
+	ADDIP %g6, TASK_THREAD+THREAD_FORK_KPSR
+	st	[%g6], %g4
+#if 1
+	pfx	9
+	wrctl	%g0				; enable interrupts
+#endif
+	MOVIA	%o0, SIGCHLD | CLONE_VM | CLONE_VFORK	; arg0:	clone flags
+	lds	%o1, [%sp, (REGWIN_SZ + PT_FP)/4]	; arg1:	usp
+	mov	%o2, %sp
+	ADDIP	%o2, REGWIN_SZ				; arg2:	pt_regs ptr
+	movi	%o3, 0					; arg3: stack size (not used)
+	MOVIA	%g5, C_LABEL(do_fork)@h
+	call	%g5
+	 nop
+	sts	[%sp, (REGWIN_SZ + PT_I0)/4], %o0	; save the returned arg
+	LOAD_LAST_WINDOW
+	br	ret_sys_call				;
+	 nop
+	
+
+	.align	2
+	.globl	C_LABEL(sys_clone)
+C_LABEL(sys_clone):
+
+;;;	pfx	0
+	rdctl	%g4				; get STATUS
+	ANDIP	%g4, 0xffff			; clear upper stuff
+#if 1
+	pfx	8
+	wrctl	%g0				; disable interrupts
+	 nop
+	 nop
+	FLUSH_WINDOWS
+#endif
+	MOVIA	%l2, nios_status		; add STATUS extension
+	ld	%l2, [%l2]			; 
+	ANDNIP	%l2, 0xffff			; clear lower stuff
+	or	%g4, %l2			; 
+
+	GET_CURRENT	g6
+	ADDIP %g6, TASK_THREAD+THREAD_FORK_KPSR
+	st	[%g6], %g4
+#if 1
+	pfx	9
+	wrctl	%g0				; enable interrupts
+#endif
+	lds	%o0, [%sp, (REGWIN_SZ + PT_I0)/4]	; arg0: flags
+	lds	%o1, [%sp, (REGWIN_SZ + PT_I1)/4]	; arg1: usp
+	cmpi	%o1, 0x0				; Is new_usp NULL?
+	skps	cc_ne
+	lds	%o1, [%sp, (REGWIN_SZ + PT_FP)/4]	; yes, use current usp
+	mov	%o2, %sp
+	ADDIP	%o2, REGWIN_SZ				; arg2:	pt_regs ptr
+	movi	%o3, 0					; arg3: stack size (not used)
+
+	MOVIA	%g5, C_LABEL(do_fork)@h
+	call	%g5
+	 nop
+	sts	[%sp, (REGWIN_SZ + PT_I0)/4], %o0	; save the returned arg
+	br	ret_sys_call				;
+	 nop
+
+
+	.data
+	.align	2
+	.globl C_LABEL(sys_call_table)
+C_LABEL(sys_call_table):
+	.long C_LABEL(sys_ni_syscall)@h		/* 0  -  old "setup()" system call*/
+	.long C_LABEL(sys_exit)@h
+	.long C_LABEL(sys_fork)@h
+	.long C_LABEL(sys_read)@h
+	.long C_LABEL(sys_write)@h
+	.long C_LABEL(sys_open)@h		/* 5 */
+	.long C_LABEL(sys_close)@h
+	.long C_LABEL(sys_waitpid)@h
+	.long C_LABEL(sys_creat)@h
+	.long C_LABEL(sys_link)@h
+	.long C_LABEL(sys_unlink)@h		/* 10 */
+	.long C_LABEL(sys_execve)@h
+	.long C_LABEL(sys_chdir)@h
+	.long C_LABEL(sys_time)@h
+	.long C_LABEL(sys_mknod)@h
+	.long C_LABEL(sys_chmod)@h		/* 15 */
+	.long C_LABEL(sys_chown)@h
+	.long C_LABEL(sys_ni_syscall)@h				/* old break syscall holder */
+	.long C_LABEL(sys_stat)@h
+	.long C_LABEL(sys_lseek)@h
+	.long C_LABEL(sys_getpid)@h		/* 20 */
+	.long C_LABEL(sys_mount)@h
+	.long C_LABEL(sys_umount)@h
+	.long C_LABEL(sys_setuid)@h
+	.long C_LABEL(sys_getuid)@h
+	.long C_LABEL(sys_stime)@h		/* 25 */
+	.long C_LABEL(sys_ptrace)@h
+	.long C_LABEL(sys_alarm)@h
+	.long C_LABEL(sys_fstat)@h
+	.long C_LABEL(sys_pause)@h
+	.long C_LABEL(sys_utime)@h		/* 30 */
+	.long C_LABEL(sys_ni_syscall)@h				/* old stty syscall holder */
+	.long C_LABEL(sys_ni_syscall)@h				/* old gtty syscall holder */
+	.long C_LABEL(sys_access)@h
+	.long C_LABEL(sys_nice)@h
+	.long C_LABEL(sys_ni_syscall)@h		/* 35 */	/* old ftime syscall holder */
+	.long C_LABEL(sys_sync)@h
+	.long C_LABEL(sys_kill)@h
+	.long C_LABEL(sys_rename)@h
+	.long C_LABEL(sys_mkdir)@h
+	.long C_LABEL(sys_rmdir)@h		/* 40 */
+	.long C_LABEL(sys_dup)@h
+	.long C_LABEL(sys_pipe)@h
+	.long C_LABEL(sys_times)@h
+	.long C_LABEL(sys_ni_syscall)@h				/* old prof syscall holder */
+	.long C_LABEL(sys_brk)@h		/* 45 */
+	.long C_LABEL(sys_setgid)@h
+	.long C_LABEL(sys_getgid)@h
+	.long C_LABEL(sys_signal)@h
+	.long C_LABEL(sys_geteuid)@h
+	.long C_LABEL(sys_getegid)@h		/* 50 */
+	.long C_LABEL(sys_acct)@h
+	.long C_LABEL(sys_umount)@h				/* recycled never used phys() */
+	.long C_LABEL(sys_ni_syscall)@h				/* old lock syscall holder */
+	.long C_LABEL(sys_ioctl)@h
+	.long C_LABEL(sys_fcntl)@h		/* 55 */
+	.long C_LABEL(sys_ni_syscall)@h				/* old mpx syscall holder */
+	.long C_LABEL(sys_setpgid)@h
+	.long C_LABEL(sys_ni_syscall)@h				/* old ulimit syscall holder */
+	.long C_LABEL(sys_ni_syscall)@h
+	.long C_LABEL(sys_umask)@h		/* 60 */
+	.long C_LABEL(sys_chroot)@h
+	.long C_LABEL(sys_ustat)@h
+	.long C_LABEL(sys_dup2)@h
+	.long C_LABEL(sys_getppid)@h
+	.long C_LABEL(sys_getpgrp)@h		/* 65 */
+	.long C_LABEL(sys_setsid)@h
+	.long C_LABEL(sys_sigaction)@h
+	.long C_LABEL(sys_sgetmask)@h
+	.long C_LABEL(sys_ssetmask)@h
+	.long C_LABEL(sys_setreuid)@h		/* 70 */
+	.long C_LABEL(sys_setregid)@h
+	.long C_LABEL(sys_sigsuspend)@h
+	.long C_LABEL(sys_sigpending)@h
+	.long C_LABEL(sys_sethostname)@h
+	.long C_LABEL(sys_setrlimit)@h		/* 75 */
+	.long C_LABEL(sys_old_getrlimit)@h
+	.long C_LABEL(sys_getrusage)@h
+	.long C_LABEL(sys_gettimeofday)@h
+	.long C_LABEL(sys_settimeofday)@h
+	.long C_LABEL(sys_getgroups)@h		/* 80 */
+	.long C_LABEL(sys_setgroups)@h
+	.long C_LABEL(old_select)@h
+	.long C_LABEL(sys_symlink)@h
+	.long C_LABEL(sys_lstat)@h
+	.long C_LABEL(sys_readlink)@h		/* 85 */
+	.long C_LABEL(sys_uselib)@h
+	.long C_LABEL(sys_swapon)@h
+	.long C_LABEL(sys_reboot)@h
+	.long C_LABEL(old_readdir)@h
+	.long C_LABEL(old_mmap)@h		/* 90 */
+	.long C_LABEL(sys_munmap)@h
+	.long C_LABEL(sys_truncate)@h
+	.long C_LABEL(sys_ftruncate)@h
+	.long C_LABEL(sys_fchmod)@h
+	.long C_LABEL(sys_fchown)@h		/* 95 */
+	.long C_LABEL(sys_getpriority)@h
+	.long C_LABEL(sys_setpriority)@h
+	.long C_LABEL(sys_ni_syscall)@h				/* old profil syscall holder */
+	.long C_LABEL(sys_statfs)@h
+	.long C_LABEL(sys_fstatfs)@h		/* 100 */
+	.long C_LABEL(sys_ioperm)@h
+	.long C_LABEL(sys_socketcall)@h
+	.long C_LABEL(sys_syslog)@h
+	.long C_LABEL(sys_setitimer)@h
+	.long C_LABEL(sys_getitimer)@h		/* 105 */
+	.long C_LABEL(sys_newstat)@h
+	.long C_LABEL(sys_newlstat)@h
+	.long C_LABEL(sys_newfstat)@h
+	.long C_LABEL(sys_ni_syscall)@h		//vic old sys_uname
+	.long C_LABEL(sys_ni_syscall)@h		/* iopl for i386 */ /* 110 */
+	.long C_LABEL(sys_vhangup)@h
+	.long C_LABEL(sys_ni_syscall)@h		/* obsolete idle() syscall */
+	.long C_LABEL(sys_ni_syscall)@h		/* vm86 for i386 */
+	.long C_LABEL(sys_wait4)@h
+	.long C_LABEL(sys_swapoff)@h		/* 115 */
+	.long C_LABEL(sys_sysinfo)@h
+	.long C_LABEL(sys_ipc)@h
+	.long C_LABEL(sys_fsync)@h
+	.long C_LABEL(sys_sigreturn)@h
+	.long C_LABEL(sys_clone)@h		/* 120 */
+	.long C_LABEL(sys_setdomainname)@h
+	.long C_LABEL(sys_newuname)@h
+	.long C_LABEL(sys_cacheflush)@h		/* modify_ldt for i386 */
+	.long C_LABEL(sys_adjtimex)@h
+	.long C_LABEL(sys_mprotect)@h		/* 125 */
+	.long C_LABEL(sys_sigprocmask)@h
+	.long C_LABEL(sys_create_module)@h
+	.long C_LABEL(sys_init_module)@h
+	.long C_LABEL(sys_delete_module)@h
+	.long C_LABEL(sys_get_kernel_syms)@h	/* 130 */
+	.long C_LABEL(sys_quotactl)@h
+	.long C_LABEL(sys_getpgid)@h
+	.long C_LABEL(sys_fchdir)@h
+	.long C_LABEL(sys_bdflush)@h
+	.long C_LABEL(sys_sysfs)@h		/* 135 */
+	.long C_LABEL(sys_personality)@h
+	.long C_LABEL(sys_ni_syscall)@h		/* for afs_syscall */
+	.long C_LABEL(sys_setfsuid)@h
+	.long C_LABEL(sys_setfsgid)@h
+	.long C_LABEL(sys_llseek)@h		/* 140 */
+	.long C_LABEL(sys_getdents)@h
+	.long C_LABEL(sys_select)@h
+	.long C_LABEL(sys_flock)@h
+	.long C_LABEL(sys_msync)@h
+	.long C_LABEL(sys_readv)@h		/* 145 */
+	.long C_LABEL(sys_writev)@h
+	.long C_LABEL(sys_getsid)@h
+	.long C_LABEL(sys_fdatasync)@h
+	.long C_LABEL(sys_sysctl)@h
+	.long C_LABEL(sys_mlock)@h		/* 150 */
+	.long C_LABEL(sys_munlock)@h
+	.long C_LABEL(sys_mlockall)@h
+	.long C_LABEL(sys_munlockall)@h
+	.long C_LABEL(sys_sched_setparam)@h
+	.long C_LABEL(sys_sched_getparam)@h   	/* 155 */
+	.long C_LABEL(sys_sched_setscheduler)@h
+	.long C_LABEL(sys_sched_getscheduler)@h
+	.long C_LABEL(sys_sched_yield)@h
+	.long C_LABEL(sys_sched_get_priority_max)@h
+	.long C_LABEL(sys_sched_get_priority_min)@h  /* 160 */
+	.long C_LABEL(sys_sched_rr_get_interval)@h
+	.long C_LABEL(sys_nanosleep)@h
+	.long C_LABEL(sys_mremap)@h
+//vic - add new syscalls
+	.long C_LABEL(sys_setresuid16)@h
+	.long C_LABEL(sys_getresuid16)@h	/* 165 */
+	.long C_LABEL(sys_ni_syscall)@h		/* for vm86 */
+	.long C_LABEL(sys_query_module)@h
+	.long C_LABEL(sys_poll)@h
+	.long C_LABEL(sys_nfsservctl)@h
+	.long C_LABEL(sys_setresgid16)@h	/* 170 */
+	.long C_LABEL(sys_getresgid16)@h
+	.long C_LABEL(sys_prctl)@h
+	.long C_LABEL(sys_rt_sigreturn)@h
+	.long C_LABEL(sys_rt_sigaction)@h
+	.long C_LABEL(sys_rt_sigprocmask)@h	/* 175 */
+	.long C_LABEL(sys_rt_sigpending)@h
+	.long C_LABEL(sys_rt_sigtimedwait)@h
+	.long C_LABEL(sys_rt_sigqueueinfo)@h
+	.long C_LABEL(sys_rt_sigsuspend)@h
+	.long C_LABEL(sys_pread)@h		/* 180 */
+	.long C_LABEL(sys_pwrite)@h
+	.long C_LABEL(sys_lchown16)@h
+	.long C_LABEL(sys_getcwd)@h
+	.long C_LABEL(sys_capget)@h
+	.long C_LABEL(sys_capset)@h           	/* 185 */
+	.long C_LABEL(sys_sigaltstack)@h
+	.long C_LABEL(sys_sendfile)@h
+	.long C_LABEL(sys_ni_syscall)@h		/* streams1 */
+	.long C_LABEL(sys_ni_syscall)@h		/* streams2 */
+	.long C_LABEL(sys_vfork)@h            	/* 190 */
+	.long C_LABEL(sys_getrlimit)@h
+	.long C_LABEL(sys_mmap2)@h
+	.long C_LABEL(sys_truncate64)@h
+	.long C_LABEL(sys_ftruncate64)@h
+	.long C_LABEL(sys_stat64)@h		/* 195 */
+	.long C_LABEL(sys_lstat64)@h
+	.long C_LABEL(sys_fstat64)@h
+	.long C_LABEL(sys_chown)@h
+	.long C_LABEL(sys_getuid)@h
+	.long C_LABEL(sys_getgid)@h		/* 200 */
+	.long C_LABEL(sys_geteuid)@h
+	.long C_LABEL(sys_getegid)@h
+	.long C_LABEL(sys_setreuid)@h
+	.long C_LABEL(sys_setregid)@h
+	.long C_LABEL(sys_getgroups)@h		/* 205 */
+	.long C_LABEL(sys_setgroups)@h
+	.long C_LABEL(sys_fchown)@h
+	.long C_LABEL(sys_setresuid)@h
+	.long C_LABEL(sys_getresuid)@h
+	.long C_LABEL(sys_setresgid)@h		/* 210 */
+	.long C_LABEL(sys_getresgid)@h
+	.long C_LABEL(sys_lchown)@h
+	.long C_LABEL(sys_setuid)@h
+	.long C_LABEL(sys_setgid)@h
+	.long C_LABEL(sys_setfsuid)@h		/* 215 */
+	.long C_LABEL(sys_setfsgid)@h
+
+//vic	.rept	NR_syscalls-216			/* 216 - 255 */
+	.rept	256-216			/* 216 - 255 */
+	.long C_LABEL(sys_ni_syscall)@h
+	.endr
+
+/* End of entry.S */
+
diff -urN linux-2.4.29/arch/niosnommu/kernel/gdb_stub.c linux-2.4.29-uc1/arch/niosnommu/kernel/gdb_stub.c
--- linux-2.4.29/arch/niosnommu/kernel/gdb_stub.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/gdb_stub.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,796 @@
+// Modified for uClinux - Vic - Dec 2001
+// From:
+
+// File: nios_gdb_stub.c
+// Date: 2000 June 20
+// Author dvb \ Altera Santa Cruz
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/nios.h>
+#include "gdb_stub.h"
+
+extern int _etext;
+
+static void puts( unsigned char *s )
+{
+	while(*s) {
+		while (!(nasys_printf_uart->np_uartstatus & np_uartstatus_trdy_mask));
+		nasys_printf_uart->np_uarttxdata = *s++;
+	}
+}
+
+enum
+{
+  na_BreakpointTrap     = 3,
+  na_SingleStepTrap     = 4,
+  na_StartGDBTrap       = 5
+};
+
+// --------------------------------
+// Local Prototypes
+
+#if GDB_DEBUG_PRINT
+static void StringFit(char *s,int w);
+#endif
+
+// --------------------------------
+// Debugging The Debugger
+
+#if GDB_DEBUG_PRINT
+void GDB_RawMessage(char *s)
+	{
+	StringFit(s,32);
+	nr_pio_lcdwritescreen(s);
+	}
+#else
+	#define GDB_RawMessage(a,b,c)	// define away to nothing
+#endif
+
+#if GDB_DEBUG_PRINT
+void GDB_Print2(char *s,int n1,int n2)
+	{
+	char st[1000];
+
+	sprintf(st,s,n1,n2);
+	GDB_RawMessage(st);
+	}
+#else
+	#define GDB_Print2(a,b,c)	// define away to nothing
+#endif
+
+// If string is longer than w, cut out the middle.
+
+#if GDB_DEBUG_PRINT
+int StringLen(char *s)
+	{
+	int l = 0;
+
+	while(*s++)
+		l++;
+	return l;
+	}
+
+void StringFit(char *s,int w)
+	{
+	if(StringLen(s) > w)
+		{
+		int i;
+
+
+		w = w / 2;
+
+		for(i = 0; i < w; i++)
+			{
+			s[i + w] = s[StringLen(s) - w + i];
+			}
+		s[w + w] = 0;
+		}
+	}
+#endif
+
+
+// ---------------------------------------------
+// Generic routines for dealing with
+// hex input, output, and parsing
+// (Adapted from other stubs.)
+
+
+#define kTextBufferSize 2048
+#define kMaximumBreakpoints 4
+
+/*
+ * This register structure must match
+ * its counterpart in the GDB host, since
+ * it is blasted across in byte notation.
+ */
+typedef struct
+	{
+	int r[32];
+	long pc;
+	short ctl0;
+	short ctl1;
+	short ctl2;
+	short filler;
+	} NiosGDBRegisters;
+
+typedef struct
+	{
+	short *address;
+	short oldContents;
+	} NiosGDBBreakpoint;
+
+typedef struct
+	{
+	NiosGDBRegisters registers;
+	int trapNumber;				// stashed by ISR, to distinguish types
+	char textBuffer[kTextBufferSize];
+	int breakpointCount;			// breakpoints used for stepping
+	NiosGDBBreakpoint breakpoint[kMaximumBreakpoints];
+	} NiosGDBGlobals;
+
+NiosGDBGlobals g = {0};		// not static: the ISR uses it!
+
+static char dHexChars[16] = "0123456789abcdef";
+
+/*
+ * HexCharToValue -- convert a single character
+ *                   to its hex value, or -1 if not.
+ */
+int HexCharToValue(char c)
+	{
+	if(c >= '0' && c <= '9')
+		return c - '0';
+	if(c >= 'a' && c <= 'f')
+		return c - 'a' + 10;
+	if(c >= 'A' && c <= 'A')
+		return c - 'A' + 10;
+	return -1;
+	}
+
+/*
+ * HexToMem -- convert a string to a specified
+ *            number of bytes in memory.
+ */
+char *HexToMem(char *hexIn, char *memOut, int memByteCount)
+	{
+	int i;
+	unsigned char x;
+
+	for(i = 0; i < memByteCount; i++)
+		{
+		x = HexCharToValue(*hexIn++) << 4;
+		x += HexCharToValue(*hexIn++);
+		*memOut++ = x;
+		}
+
+	return hexIn;
+	}
+
+/*
+ * Read forward until a non-hex character, then stop.
+ */
+
+char *Hex2Value(char *hexIn, int *valueOut)
+	{
+	char c;
+	int digitValue;
+	int value = 0;
+
+	while(1)
+		{
+		c = *hexIn;
+		digitValue = HexCharToValue(c);
+//printf("\n %c to %d \n",c,digitValue);
+		if(digitValue < 0)
+			{
+			*valueOut = value;
+			return hexIn;
+			}
+		hexIn++;
+		value = (value << 4) + digitValue;
+		}
+	}
+
+char *MemToHex(char *memIn, char *hexOut, int memByteCount)
+	{
+	int i;
+	unsigned char x;
+
+	for(i = 0; i < memByteCount; i++)
+		{
+		x = (unsigned char) *memIn++;
+
+		*hexOut++ = dHexChars[x >> 4];
+		*hexOut++ = dHexChars[x & 15];
+		}
+
+	*hexOut = 0;
+
+	return hexOut;
+	}
+
+/*
+ * Once a $ comes in, use GetGDBPacket to
+ * retrieve a full gdb packet, and verify
+ * checksum, and reply + or -.
+ */
+int GetGDBPacket(char *aBuffer)
+	{
+	int checksum;
+	int length;
+	char c;
+	int x;
+
+startPacket:
+	length = 0;
+	checksum = 0;
+
+	while((c = GDBGetChar()) != '#')
+		{
+		if(c == '$')
+			goto startPacket;
+
+		checksum += c;
+		aBuffer[length++] = c;
+		aBuffer[length] = 0;
+		}
+
+	c = GDBGetChar();
+	x = HexCharToValue(c) << 4;
+	c = GDBGetChar();
+	x += HexCharToValue(c);
+
+	checksum &= 0xff;
+
+	if(checksum != x)
+		{
+		GDBPutChar('-');
+		length = 0;
+		}
+	else
+		{
+		GDBPutChar('+');
+		}
+
+	GDB_Print2("GetPacket %d",length,0);
+	return length;
+	}
+
+/*
+ * Send a packet, preceded by $,
+ * and followed by #checksum.
+ */
+void PutGDBPacket(char *aBuffer)
+	{
+	int checksum;
+	char c;
+
+	GDBPutChar('$');
+	checksum = 0;
+	while((c = *aBuffer++) != 0)
+		{
+		checksum += c;
+		GDBPutChar(c);
+		}
+	GDBPutChar('#');
+	GDBPutChar(dHexChars[(checksum >> 4) & 15]);
+	GDBPutChar(dHexChars[checksum & 15]);
+	}
+
+void PutGDBOKPacket(char *aBuffer)
+	{
+	aBuffer[0] = 'O';
+	aBuffer[1] = 'K';
+	aBuffer[2] = 0;
+	PutGDBPacket(aBuffer);
+	}
+
+void DoGDBCommand_m(char *aBuffer)
+	{
+	char *w;
+	int startAddr,byteCount;
+
+	w = aBuffer;
+	w++;				// past 'm'
+	w = Hex2Value(w,&startAddr);
+	w++;				// past ','
+	w = Hex2Value(w,&byteCount);
+
+//printf("\n%d , %d\n",startAddr,byteCount);
+
+	// mA,L -- request memory
+
+	w = aBuffer;
+	w = MemToHex((char *)startAddr,w,byteCount);
+	PutGDBPacket(aBuffer);
+	}
+
+void DoGDBCommand_M(char *aBuffer)
+	{
+	char *w;
+	int startAddr,byteCount;
+
+	w = aBuffer;
+	w++;				// past 'M'
+	w = Hex2Value(w,&startAddr);
+	w++;				// past ','
+	w = Hex2Value(w,&byteCount);
+	w++;				// past ':'
+
+	GDB_Print2("M from %x to %x",startAddr,byteCount);
+
+	// MA,L:values -- write to memory
+
+	w = HexToMem(w,(char *)startAddr,byteCount);
+
+	// Send "OK"
+	PutGDBOKPacket(aBuffer);
+	}
+
+// Return the values of all the registers
+void DoGDBCommand_g(NiosGDBGlobals *g)
+	{
+	char *w;
+
+	w = g->textBuffer;
+	w = MemToHex((char *)(&g->registers),w,sizeof(g->registers));
+	PutGDBPacket(g->textBuffer);
+	GDB_Print2("Sent            Registers",0,0);
+	}
+
+// Set the values of all the registers
+void DoGDBCommand_G(NiosGDBGlobals *g)
+	{
+	char *w;
+
+	w = g->textBuffer;
+	w++;	// skip past 'G'
+	w = HexToMem(w,(char *)(&g->registers),sizeof(g->registers));
+
+
+	// Send "OK"
+	PutGDBOKPacket(g->textBuffer);
+
+	GDB_Print2("Received        Registers",0,0);
+	}
+
+// Return last signal value
+void DoGDBCommand_qm(NiosGDBGlobals *g)
+	{
+	char *w;
+
+	w = g->textBuffer;
+
+	*w++ = 'S';
+	*w++ = '2';
+	*w++ = '3';	// make up a signal for now...
+	*w++ = 0;
+	PutGDBPacket(g->textBuffer);
+	}
+
+
+void GDBInsertBreakpoint(NiosGDBGlobals *g,short *address)
+	{
+	NiosGDBBreakpoint *b;
+
+	GDB_Print2("breakpoint 0x%x",(int)address,0);
+	if(g->breakpointCount < kMaximumBreakpoints)
+		{
+		b = &g->breakpoint[g->breakpointCount++];
+		b->address = address;
+		b->oldContents = *b->address;
+		*b->address = 0x7904;
+		}
+	}
+
+void GDBRemoveBreakpoints(NiosGDBGlobals *g)
+	{
+	NiosGDBBreakpoint *b;
+	int i;
+
+	for(i = 0; i < g->breakpointCount; i++)
+		{
+		b = &g->breakpoint[i];
+		*b->address = b->oldContents;
+		b->address = 0;
+		}
+
+	g->breakpointCount = 0;
+	}
+
+int NiosInstructionIsTrap5(unsigned short instruction)
+	{
+	return instruction == 0x7905;
+	}
+
+int NiosInstructionIsPrefix(unsigned short instruction)
+	{
+	return (instruction >> 11) == 0x13;
+	}
+
+int NiosInstructionIsSkip(unsigned short instruction)
+	{
+	int op6;
+	int op11;
+
+	op6 = (instruction >> 10);
+	op11 = (instruction >> 5);
+
+	return (op6 == 0x14		// SKP0
+		|| op6 == 0x15		// SKP1
+		|| op11 == 0x3f6	// SKPRz
+		|| op11 == 0x3f7	// SKPS
+		|| op11 == 0x3fa);	// SKPRnz
+	}
+
+int NiosInstructionIsBranch(unsigned short instruction,short *pc,short **branchTargetOut)
+	{
+	int op4;
+	int op7;
+	int op10;
+	short *branchTarget = 0;
+	int result = 0;
+
+	op4 = (instruction >> 12);
+	op7 = (instruction >> 9);
+	op10 = (instruction >> 6);
+
+	if(op4 == 0x08)		// BR, BSR
+		{
+		int offset;
+
+		result = 1;
+		offset = instruction & 0x07ff;
+		if(offset & 0x400)	// sign extend
+			offset |= 0xffffF800;
+		branchTarget = pc + offset + 1;	// short * gets x2 scaling automatically
+		}
+	else if(op10 == 0x1ff)	// JMP, CALL
+		{
+		result = 1;
+		branchTarget = (short *)(g.registers.r[instruction & 31] * 2);
+		}
+	else if(op7 == 0x3d)	// JMPC, CALLC
+		{
+		result = 1;
+		branchTarget = pc + 1 + (instruction & 0x0ffff);
+#ifdef __nios32__
+		branchTarget = (short *)((int)branchTarget & 0xffffFFFc);	// align 32...
+#else
+		branchTarget = (short *)((int)branchTarget & 0xFFFe);		// align 16...
+#endif
+		branchTarget = (short *)(*(int *)branchTarget);
+		}
+
+	if(branchTargetOut)
+		*branchTargetOut = branchTarget;
+
+	return result;
+	}
+
+// -------------------------
+// Step at address
+//
+// "stepping" involves inserting a
+// breakpoint at some reasonable
+// spot later than the current program
+// counter
+//
+// On the Nios processor, this is
+// nontrivial. For example, we should
+// not break up a PFX instruction.
+
+void DoGDBCommand_s(NiosGDBGlobals *g)
+	{
+	char *w;
+	int x;
+	short *pc;
+	short *branchTarget;
+	unsigned short instruction;
+	int stepType;
+
+	/*
+	 * First, if there's an argument to the packet,
+	 * set the new program-counter value
+	 */
+
+	w = g->textBuffer;
+	w++;
+	if(HexCharToValue(*w) >= 0)
+		{
+		w = Hex2Value(w,&x);
+		g->registers.pc = x;
+		}
+
+	/*
+	 * Scan forward to see what the
+	 * most appropriate location(s) for
+	 * a breakpoint will be.
+	 *
+	 * The rules are:
+	 *  1. If *pc == PFX, break after modified instruction.
+	 *  2. If *pc == BR,BSR,JMP,CALL, break at destination
+	 *  3. If *pc == SKIP, break right after SKIP AND after optional instruction,
+	                 which might, of course, be prefixed.
+	 *  4. Anything else, just drop in the breakpoint.
+	 */
+
+	pc = (short *)(int)g->registers.pc;
+
+	instruction = *pc;
+	stepType = 0;
+
+	if(NiosInstructionIsPrefix(instruction))
+		{
+		/*
+		 * PFX instruction: skip til after it
+		 */
+		while(NiosInstructionIsPrefix(instruction))
+			{
+			pc++;
+			instruction = *pc;
+			}
+
+		GDBInsertBreakpoint(g,pc + 1);
+		stepType = 1;
+		}
+	else if(NiosInstructionIsBranch(instruction,pc,&branchTarget))
+		{
+		GDBInsertBreakpoint(g,branchTarget);
+		stepType = 2;
+		}
+	else if(NiosInstructionIsSkip(instruction))
+		{
+		short *pc2;
+		stepType = 3;
+
+		/*
+		 * Skip gets to breaks: one after the skippable instruction,
+		 * and the skippable instruction itself.
+		 *
+		 * Since Skips know how to skip over PFX's, we have to, too.
+		 */
+		pc2 = pc;	// the Skip instruction
+		do
+			{
+			pc2++;
+			} while(NiosInstructionIsPrefix(*pc2));
+		// pc2 now points to first non-PFX after Skip
+		GDBInsertBreakpoint(g,pc2+1);
+		GDBInsertBreakpoint(g,pc+1);
+		}
+	else
+		GDBInsertBreakpoint(g,pc+1);		// the genericest case
+
+	GDB_Print2("Program Steppingat 0x%x (%d)",g->registers.pc,stepType);
+	}
+
+// -----------------------------
+// Continue at address
+
+void DoGDBCommand_c(NiosGDBGlobals *g)
+	{
+	char *w;
+	int x;
+	w = g->textBuffer;
+
+	w++;		// past command
+
+	// Anything in the packet? if so,
+	// use it to set the PC value
+
+	if(HexCharToValue(*w) >= 0)
+		{
+		w = Hex2Value(w,&x);
+		g->registers.pc = x;
+		}
+
+	GDB_Print2("Program Running at 0x%x",g->registers.pc,0);
+	}
+
+// ----------------------
+// Kill
+
+void DoGDBCommand_k(NiosGDBGlobals *g)
+	{
+	return;
+	}
+
+
+/*
+ * If we've somehow skidded
+ * to a stop just after a PFX instruction
+ * back up the program counter by one.
+ *
+ * That way, we can't end up with an accidentally-unprefixed
+ * instruction.
+ *
+ * We do this just before we begin running
+ * again, so that when the host queries our
+ * registers, we report the place we actually
+ * stopped.
+ */
+
+void MaybeAdjustProgramCounter(NiosGDBGlobals *g)
+	{
+	short instruction;
+	if(g->registers.pc)
+		{
+		instruction = *(short *)(int)(g->registers.pc - 2);
+		if(NiosInstructionIsPrefix(instruction))
+			g->registers.pc -= 2;
+		else
+			{
+			// If the *current* instruction is Trap5, we must skip it!
+			instruction = *(short *)(int)(g->registers.pc);
+			if(NiosInstructionIsTrap5(instruction))
+				g->registers.pc += 2;
+			}
+		}
+	}
+
+// ----------main------------
+
+void GDBMain(void)
+	{
+	char c;
+	int i;
+
+	for(i = 0; i < kTextBufferSize; i++)
+		g.textBuffer[i] = i;
+
+	GDBRemoveBreakpoints(&g);
+
+	// Send "S05" for breakpoint encountered. No other signals.
+
+	g.textBuffer[0] = 'S';
+	g.textBuffer[1] = '0';
+	g.textBuffer[2] = '5';
+	g.textBuffer[3] = 0;
+	PutGDBPacket(g.textBuffer);
+
+	GDB_Print2("Trap %2d         At 0x%x",
+		g.trapNumber,g.registers.pc);
+
+/* Vic  2001-11-26
+ * Inform the user that they need to add the symbol file for the application
+ * that is just starting up.  Display the  .text  .data  .bss  regions.
+ */
+	if (g.trapNumber == 5) {
+		sprintf(g.textBuffer,
+				"\r\n\nGDB: trap 5 at 0x%08lX", g.registers.pc);
+		puts(g.textBuffer);
+		if ( current->mm->start_code > _etext ) {
+			sprintf(g.textBuffer,
+				"\r\nGDB: Enter the following command in the nios-elf-gdb Console Window:"
+				"\r\nGDB:    add-symbol-file [path]%s.abself 0x%08lX 0x%08lX 0x%08lX\r\n\n",
+				current->comm,
+				(unsigned long)current->mm->start_code,
+				(unsigned long)current->mm->start_data,
+				(unsigned long)current->mm->end_data );
+		} else {
+			if (current)
+				sprintf(g.textBuffer,
+					", kernel process: %s\r\n", current->comm );
+			else
+				sprintf(g.textBuffer,
+					", kernel process unknown\r\n" );
+		}
+		puts(g.textBuffer);
+	}
+
+	while(1)
+		{
+		c = GDBGetChar();
+		if(c == '$')
+			{
+			GetGDBPacket(g.textBuffer);
+
+			GDB_Print2(g.textBuffer,0,0);
+
+			switch(g.textBuffer[0])
+				{
+				case 's':
+					DoGDBCommand_s(&g);
+					goto startRunning;
+					break;
+
+				case 'c':	// continue
+					DoGDBCommand_c(&g);
+
+					// if the PC is something other than 0, it's
+					// probably ok to exit and go there
+
+				startRunning:
+					if(g.registers.pc)
+						{
+						MaybeAdjustProgramCounter(&g);
+						return;
+						}
+					break;
+
+				case 'm':	// memory read
+					DoGDBCommand_m(g.textBuffer);
+					break;
+
+				case 'M':	// memory set
+					DoGDBCommand_M(g.textBuffer);
+					break;
+
+				case 'g':	// registers read
+					DoGDBCommand_g(&g);
+					break;
+
+				case 'G':	//registers set
+					DoGDBCommand_G(&g);
+					break;
+
+				case 'k':	//kill process
+					DoGDBCommand_k(&g);
+					break;
+
+				case '?':	// last exception value
+					DoGDBCommand_qm(&g);
+					break;
+
+				default:	// return empty packet, means "yeah yeah".
+					g.textBuffer[0] = 0;
+					PutGDBPacket(g.textBuffer);
+					break;
+				}
+			}
+		}
+	}
+
+/*
+ * int main(void)
+ *
+ * All we really do here is install our trap # 3,
+ * and call it once, so that we're living down in
+ * the GDBMain, trap handler.
+ */
+
+extern int StubBreakpointHandler;
+extern int StubHarmlessHandler;
+
+void nios_gdb_install(int active)
+	{
+	unsigned int *vectorTable;
+	unsigned int stubBreakpointHandler;
+	unsigned int stubHarmlessHandler;
+
+	g.breakpointCount = 0;
+	g.textBuffer[0] = 0;
+
+	vectorTable = (int *)nasys_vector_table;
+	stubBreakpointHandler = ( (unsigned int)(&StubBreakpointHandler) ) >> 1;
+	stubHarmlessHandler = ( (unsigned int)(&StubHarmlessHandler) ) >> 1;
+
+	/*
+	 * Breakpoint & single step both go here
+	 */
+	vectorTable[na_BreakpointTrap] = stubBreakpointHandler;
+	vectorTable[na_SingleStepTrap] = stubBreakpointHandler;
+	vectorTable[na_StartGDBTrap] = active ? stubBreakpointHandler : stubHarmlessHandler;
+	}
+
+#ifdef nios_gdb_breakpoint
+	#undef nios_gdb_breakpoint
+#endif
+
+void nios_gdb_breakpoint(void)
+	{
+	/*
+	 * If you arrived here, you didn't include
+	 * the file "nios_peripherals.h", which
+	 * defines nios_gdb_breakpoint as a
+	 * macro that expands to TRAP 5.
+	 *
+	 * (No problem, you can step out
+	 * of this routine.)
+	 */
+	asm("TRAP 5");
+	}
+
+// end of file
diff -urN linux-2.4.29/arch/niosnommu/kernel/gdb_stub.h linux-2.4.29-uc1/arch/niosnommu/kernel/gdb_stub.h
--- linux-2.4.29/arch/niosnommu/kernel/gdb_stub.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/gdb_stub.h	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,53 @@
+// Modified for uClinux - Vic - Dec 2001
+// From:
+
+// file: nios_gdb_stub.h
+// Author: Altera Santa Cruz \ 2000
+//
+// You can modify this header file to
+// enable some features useful for
+// debugging the debugger. They're
+// good features also to just show
+// signs of life on your Nios board.
+// But they consume valuable peripherals!
+//
+// The 'GDB_DEBUG_PRINT' option ties
+// up the LCD living on the 5v port,
+// showing useful internals of the stub.
+//
+// dvb@altera.com
+//
+
+#ifndef GDB_DEBUG_PRINT
+	#define GDB_DEBUG_PRINT 0
+#endif
+
+//vic void GDB_Main(void);	// initialize gdb and begin.
+
+//vic void GDB_Print2(char *s,int v1,int v2);
+
+
+// Single character I/O for Nios GDB Stub
+
+#ifdef nasys_gdb_uart
+	#define GDB_UART nasys_gdb_uart
+#endif
+
+static inline char GDBGetChar(void)
+	{
+	char c = 0;
+#ifdef GDB_UART
+	while (!(GDB_UART->np_uartstatus & np_uartstatus_rrdy_mask));
+	c = GDB_UART->np_uartrxdata;
+#endif
+	return c;
+	}
+
+static inline void GDBPutChar(char c)
+	{
+#ifdef GDB_UART
+	while (!(GDB_UART->np_uartstatus & np_uartstatus_trdy_mask));
+	GDB_UART->np_uarttxdata = c;
+#endif
+	}
+
diff -urN linux-2.4.29/arch/niosnommu/kernel/gdb_stub_isr.S linux-2.4.29-uc1/arch/niosnommu/kernel/gdb_stub_isr.S
--- linux-2.4.29/arch/niosnommu/kernel/gdb_stub_isr.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/gdb_stub_isr.S	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,370 @@
+; Modified for uClinux - Vic - Dec 2001
+; From: 
+  
+; File: nios_gdb_stub_isr.s
+; Date: 2000 June 20
+; Author dvb \ Altera Santa Cruz
+
+;
+; Assembly language portions of Nios GDB Stub
+;
+; Stack set up, register clearing, all kinds of
+; clever things.
+;
+
+#include <asm/niosasm.h>
+
+; Manual additions .. - AF 9/4/2000
+; Eventually these items will be in the SDK.
+
+  GEQU na_BreakpointTrap     , 3
+  GEQU na_SingleStepTrap     , 4
+
+
+; End of manual additions.
+	;
+	; Word size (32-bit) offsets
+	; for register storage
+	;
+
+	.equ	gdbRegistersGeneral,0
+	.equ	gdbRegistersPC,32
+.if __nios32__
+	.equ	gdbRegistersCtl0Ctl1,33
+	.equ	gdbRegistersCtl2,34
+	.equ	gdbTrapNumber,35		; ISR can report trap number here
+.else
+	.equ	gdbRegistersCtl0,34
+	.equ	gdbRegistersCtl1,35
+	.equ	gdbRegistersCtl2,36
+	.equ	gdbTrapNumber,38
+.endif
+
+
+	.text
+
+	.global	StubBreakpointHandler
+	.global	StubHarmlessHandler
+//	.global	StubButtonHandler
+	.global	GDBMain
+
+	.comm	_gdb_stub_stack,1024,4	; Local stack, statically allocated.
+	.equ	gdbStubStacktop,_gdb_stub_stack+992
+
+
+;
+; If nios_gdb_install(0) is invoked, the stub is present,
+; and linked in, but harmless. This, so that you can "turn off"
+; the debugger with minimal change in your code footprint.
+;
+; This is the harmless breakpoint handler.
+
+StubHarmlessHandler:
+	TRET	%o7		; pretty darned minimal. Better stuff below.
+
+
+
+
+;
+; When we get here, in response to
+; a breakpoint (trap 3 poked into code),
+; we need to save the state of all the registers,
+; every last one! So we can restore them, you see,
+; and then set up to call the debugger. Major
+; context switching here! Neat, eh?
+;
+; We arrive here with CWP down 1 from
+; its authentic state (fortunately!)
+;
+; the %l's and %o's are all ours
+; down here. again, fortunately.
+;
+; We save the current interruptee's
+; registers into the register structure
+; that the C portion uses.
+;
+; Then, after popping CWP up one level,
+; we reenable interrupts, and jump
+; to the debugger's main.
+;
+; With interrupts enabled, the CWP manager will
+; operate normally; if an underflow occurs, registers
+; from the debugged program will get stored in
+; their own local stack frame, since their own %sp's
+; are used for the task. The debugger's will
+; go in its own frame.
+;
+
+StubBreakpointHandler:
+
+	;
+	; Save the globals first.
+	; Then, when we up the CWP, they're
+	; ours to play with a bit.
+	;
+
+	MOVIA	%l0,g		; g is the C side's globals. starts with registers.
+	STP	[%l0,0],%g0
+	STP	[%l0,1],%g1
+	STP	[%l0,2],%g2
+	STP	[%l0,3],%g3
+	STP	[%l0,4],%g4
+	STP	[%l0,5],%g5
+	STP	[%l0,6],%g6
+	STP	[%l0,7],%g7
+
+	;
+	; Save the %o registers, which
+	; appear to us, down here, as
+	; %i registers
+	;
+	STP	[%l0,8],%i0
+	STP	[%l0,9],%i1
+	STP	[%l0,10],%i2
+	STP	[%l0,11],%i3
+	STP	[%l0,12],%i4
+	STP	[%l0,13],%i5
+	STP	[%l0,14],%i6
+	STP	[%l0,15],%i7
+
+	;
+	; Read the trap number from CTL0, store in struct
+	;
+	RDCTL	%g4
+	LSRI	%g4,9
+	ANDIP	%g4,0x3f
+	PFX	gdbTrapNumber
+	ST	[%l0],%g4
+
+	;
+	; Read and pack the control
+	; registers. Annoyingly, they
+	; are shorts.
+	;
+	; But we never *really* know
+	; what was in CTL1. In fact,
+	; we're going to report CTL1
+	; as zero, and read CTL1 and
+	; use it for the returned value
+	; of CTL0, since thats what it was.
+	; Clear? Good!
+
+	PFX	1
+	RDCTL	%g0			; will pretend to be ctl0 (low) and ctl 1(zeroes) high
+.if __nios32__
+	PFX	gdbRegistersCtl0Ctl1
+	ST	[%l0],%g0
+.else
+	PFX	gdbRegistersCtl0
+	ST	[%l0],%g0
+	PFX	gdbRegistersCtl1
+	ST	[%l0],%g0
+.endif
+
+	;
+	; Silly to save this one, it's fixed, but it's
+	; in the vars, so ok.
+	;
+
+	PFX	2
+	RDCTL	%g0
+	PFX	gdbRegistersCtl2
+	ST	[%l0],%g0
+
+	;
+	; Save the %pc register, which
+	; is now in %o7 cut in half
+	;
+
+	LSLI	%o7,1
+	CMPI	%g4,na_SingleStepTrap	; %g4 = trap number we got, now
+	IFS	cc_le
+	 SUBI	%o7,2		; back it up one, to before the breakpoint, if breakpoint or step
+
+	PFX	gdbRegistersPC
+	ST	[%l0],%o7
+
+	;
+	; Ascend the CWP, and grab
+	; the last %l's and %i's
+	;
+
+	MOV	%g0,%l0
+	RESTORE
+	PFX	16		; save %l0 first, so we can use it for the rest
+	ST	[%g0],%l0
+
+	MOV	%l0,%g0
+	STP	[%l0,17],%l1
+	STP	[%l0,18],%l2
+	STP	[%l0,19],%l3
+	STP	[%l0,20],%l4
+	STP	[%l0,21],%l5
+	STP	[%l0,22],%l6
+	STP	[%l0,23],%l7
+
+	STP	[%l0,24],%i0
+	STP	[%l0,25],%i1
+	STP	[%l0,26],%i2
+	STP	[%l0,27],%i3
+	STP	[%l0,28],%i4
+	STP	[%l0,29],%i5
+	STP	[%l0,30],%i6
+	STP	[%l0,31],%i7
+
+	;
+	; Now, everything is saved.
+	; If we set ctl0 and ctl1
+	; from the gdb globals, we
+	; can restore the registers
+	; as they were, and use
+	; a TRET to bump the CWP
+	; at the same time that we
+	; jump somewheres.
+	;
+	; So what we shall like to
+	; do now is set up the
+	; local stack and stuff
+	; to call into the debugger!
+	;
+
+	MOVIA	%sp,gdbStubStacktop
+	PFX	9
+	WRCTL	%g0			; enable traps (below 3, for cwp underflow action)
+
+	;
+	; We CALL to our debugger, so
+	; that we can ensure it balances
+	; its calling sequence before
+	; returning here. Once back, we'll
+	; unwind all the trickery we've
+	; done, and TRET
+	;
+
+	MOVIA	%g0,GDBMain@h
+	CALL	%g0
+	NOP
+
+	;
+	; Zero'th order, as we say, is to disable interrupts.
+	;
+
+	PFX	8
+	WRCTL	%g0			; disable interrupts.
+
+	;
+	; We're back. We assume nothing; everything
+	; may have changed. "Everything" of course
+	; means the state of the memory, and the
+	; state of the registers in the GDB globals.
+	;
+	; We'll start by instantiating CTL0 and CTL1
+	; from those globals, bump down a level, tinker
+	; a bit more, and TRET.
+	;
+
+	MOVIA	%g0,g		; g is the C side's globals. starts with registers.
+
+.if __nios32__
+	PFX	gdbRegistersCtl0Ctl1
+.else
+	PFX	gdbRegistersCtl0
+.endif
+	LD	%g1,[%g0]
+
+	; CTL0 in the low 16 bits; the high 16 bits are CTL1 which we hate
+	; And yet, we'll write them into CTL1, so that the TRET
+	; puts them back for real.
+
+.if __nios32__
+	EXT16s	%g1,0	; clear the upper 16 bits
+.endif
+
+	PFX	1
+	WRCTL	%g1
+
+	;
+	; And to start, we shall set CWP to where
+	; we'll return to, and restore what we can
+	; the one we're gonna return to
+	; with interrupts carefully disabled
+	;
+
+	ANDIP	%g1,0x00007fff	; mask off TE bit
+	WRCTL	%g1
+
+	MOV	%l0,%g0		; %l0 --> C globals now, for restoring registers
+
+	; restore %i registers
+
+	LDP	%i0,[%l0,24]
+	LDP	%i1,[%l0,25]
+	LDP	%i2,[%l0,26]
+	LDP	%i3,[%l0,27]
+	LDP	%i4,[%l0,28]
+	LDP	%i5,[%l0,29]
+	LDP	%i6,[%l0,30]
+	LDP	%i7,[%l0,31]
+
+	; restore %l registers
+
+
+	LDP	%l7,[%l0,23]
+	LDP	%l6,[%l0,22]
+	LDP	%l5,[%l0,21]
+	LDP	%l4,[%l0,20]
+	LDP	%l3,[%l0,19]
+	LDP	%l2,[%l0,18]
+	LDP	%l1,[%l0,17]
+	LDP	%l0,[%l0,16]	; %l0 kills itself!
+
+	;
+	; Bump CWP down 1, so we have some %l to play with
+	;
+
+	SAVE	%sp,0
+	MOV	%l0,%g0
+
+	; Restore %o's (visible from down here as %i's)
+
+	LDP	%i0,[%l0,8]
+	LDP	%i1,[%l0,9]
+	LDP	%i2,[%l0,10]
+	LDP	%i3,[%l0,11]
+	LDP	%i4,[%l0,12]
+	LDP	%i5,[%l0,13]
+	LDP	%i6,[%l0,14]
+	LDP	%i7,[%l0,15]
+
+	; restore %g's
+
+	LDP	%g0,[%l0,0]
+	LDP	%g1,[%l0,1]
+	LDP	%g2,[%l0,2]
+	LDP	%g3,[%l0,3]
+	LDP	%g4,[%l0,4]
+	LDP	%g5,[%l0,5]
+	LDP	%g6,[%l0,6]
+	LDP	%g7,[%l0,7]
+
+	;
+	; Set up local %o7, from PC, for TRET
+	; (Could use any register, but
+	; %o7 is ours, and it's traditional.)
+	;
+
+	PFX	gdbRegistersPC
+	LD	%o7,[%l0]
+	LSRI	%o7,1
+
+	;
+	; I'm so glad we had this time together,
+	; Just to have a laugh or sing a song.
+	; Seems we just get started and before you know it
+	; Comes the time we have to say, "So long."
+	;   Carol Burnett, 1967
+	;
+
+	TRET %o7		; so long!
+
+; end of file
diff -urN linux-2.4.29/arch/niosnommu/kernel/head.S linux-2.4.29-uc1/arch/niosnommu/kernel/head.S
--- linux-2.4.29/arch/niosnommu/kernel/head.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/head.S	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,495 @@
+/*
+ * head.S for Altera's Excalibur development board with nios processor
+ *
+ * (c) Vic Phillips, Microtronix Datacom Ltd., 2001
+ *
+ * Based on the following from the Excalibur sdk distribution:
+ *	NA_MemoryMap.s, NR_JumpToStart.s, NR_Setup.s, NR_CWPManager.s
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <asm/niosasm.h>
+#include <asm/winmacro.h>
+#include <asm/psr.h>
+
+#include <linux/config.h>
+#include "nios_defs.h"
+
+#ifdef CONFIG_CRC_CHECK
+/**********************************************/
+/* Define where the CRC table lives in flash. */
+/* The __CRC_Sector_Size is the flash sector  */
+/* size for the address range.                */
+/**********************************************/
+
+	GEQU	__CRC_Table_Begin,(na_flash)+0x4000   /* Second sector of main board flash */
+	GEQU	__CRC_Sector_Size,0x2000
+#endif
+
+	GEQU	NA_ResetTrap,0
+	GEQU	NA_UnderflowTrap,1
+	GEQU	NA_OverflowTrap,2
+
+	GEQU	_nios_flash_start,NIOS_FLASH_START
+	GEQU	_kernel_flash_start,KERNEL_FLASH_START
+
+	GEQU	_romfs_start,LINUX_ROMFS_START
+
+/*
+ * This global variable is used as an extension to the nios'
+ * STATUS register to emulate a user/supervisor mode.
+ */
+	.data
+	.align	2
+	.global	nios_status
+nios_status:
+	.long	0
+
+/*
+ * First executable code - detected and jumped to by the ROM bootstrap
+ * if the code resides in flash (looks for "Nios" at offset 0x0c from
+ * the potential executable image).
+ */
+	.text
+	.global _start
+_start:
+	PFX	8			; 0x00 (%ctl8 = CLR_IE)
+	WRCTL	%g0			; 0x02 disable interrupts
+	NOP				; 0x04
+	MOV	%g7,%o7			; 0x06 save %o7 (return address to germs)
+	BSR	NR_MoveStart		; 0x08 skip signature and load %o7 with absolute address
+	NOP				; 0x0a
+	.byte	'N','i','o','s'		; 0x0c - Signature for ROM bootstrap to find
+
+NR_MoveStart:
+ 	MOV	%l0, %o7		;  (LMA(_start) + 4 )/2 ->l0
+	LSLI	%l0, 1			;  %l0=(LMA(_start) + 4 )
+	ANDNIP	%l0,0xf			;  %l0 = LMA(_start)
+	
+	MOVIA	%l1, _start		; VMA(_start)->l1, the dest address
+	
+	CMP	%l0, %l1
+	IFS	cc_eq			; source and des are the same, no move
+	 BR	finish_move
+	NOP
+	
+	MOVIA	%l2, __data_end		; VMA(__data_end) -> l2, the last dest
+loop_move:				; l0: src, l1: dest, l2: last dest
+	LD 	%g0, [%l0]		; load a word from [%l0]
+	ST 	[%l1], %g0		; stort a word to dest [%l1]
+	ADDI 	%l0, 4			; inc the src addr
+	ADDI	%l1, 4			; inc the dest addr
+	CMP	%l1, %l2;		; if finished?
+	IFS	cc_lt
+	 BR loop_move
+	NOP
+		
+	MOVIA	%l1, finish_move@h	; VMA(_start)->l1
+	JMP	%l1			; jmp to _start	
+	NOP
+finish_move:
+
+/*
+ * Set up the stack pointer, put the register window to the top,
+ * initialize CWP trap vectors, and call to "main".
+ *
+ * If "main" returns, TRAP 0 is executed to return to ROM monitor
+ */
+
+
+	;---------------------
+	; Preset CWP up to top
+	; 
+	PFX	2
+	RDCTL	%g1			; g1 = contents of WVALID reg
+	LSRI	%g1,1
+	ANDIP	%g1,PSR_CWP		; g1 = HI_LIMIT in position for ctl0
+
+;;;	PFX	0
+;;;	RDCTL	%g0			; g0 = contents of STATUS register
+;;;	ANDNIP	%g0,PSR_CWP		; mask off old CWP
+	MOVIP	%g0,PSR_IE | PSR_IPRI_3	; set IPRI to 3, interupts enabled
+
+	OR	%g0,%g1			; put in new CWP
+;;;	PFX	0
+	WRCTL	%g0			; put new STATUS
+	NOP
+
+	;------------------------------------
+	; Disable interrupts on known devices
+	;
+.ifdef na_enet
+.ifdef na_enet_reset
+	MOVIP	%g1, na_enet_reset	; ethernet reset address
+	movi	%g0,0			; reset
+	st	[%g1],%g0		;
+.endif
+.ifdef na_enet_reset_n
+	MOVIP	%g1, na_enet_reset_n	; ethernet reset address
+	movi	%g0,0			; reset
+	st	[%g1],%g0		;
+.endif
+	nop				; give it some time
+	nop				;
+	nop				;
+	nop				;
+.endif
+.ifdef na_timer0
+	MOVIP	%g1,na_timer0		; get timer address
+	movi	%g0,0			; 
+	pfx	np_timercontrol		;
+	st	[%g1],%g0		; clear interrupt enable
+	pfx	np_timerstatus		;
+	st	[%g1],%g0		; clear interrupt condition
+.endif
+.ifdef na_uart0
+	movi	%g0,0			; 
+	MOVIP	%g1, na_uart0		; 
+	pfx	np_uartcontrol		;
+	st	[%g1],%g0		; clear interrupt enable
+	pfx	np_uartstatus		;
+	st	[%g1],%g0		; clear interrupt status
+.endif
+.ifdef na_uart1
+	movi	%g0,0			; 
+	MOVIP	%g1, na_uart1		; 
+	pfx	np_uartcontrol		;
+	st	[%g1],%g0		; clear interrupt enable
+	pfx	np_uartstatus		;
+	st	[%g1],%g0		; clear interrupt status
+.endif
+.ifdef na_uart2
+	movi	%g0,0			; 
+	MOVIP	%g1, na_uart2		; 
+	pfx	np_uartcontrol		;
+	st	[%g1],%g0		; clear interrupt enable
+	pfx	np_uartstatus		;
+	st	[%g1],%g0		; clear interrupt status
+.endif
+.ifdef na_uart3
+	movi	%g0,0			; 
+	MOVIP	%g1, na_uart3		; 
+	pfx	np_uartcontrol		;
+	st	[%g1],%g0		; clear interrupt enable
+	pfx	np_uartstatus		;
+	st	[%g1],%g0		; clear interrupt status
+.endif
+.ifdef na_ide_interface
+	movi	%g0,1			; ATA reset
+	MOVIP	%g1,na_ide_interface	; 
+	st	[%g1],%g0		; write to control register
+.endif
+.ifdef na_enet
+.ifdef na_enet_reset
+	MOVIP	%g1, na_enet_reset	; ethernet reset address
+	movi	%g0,1			; reset
+	st	[%g1],%g0		;
+.endif
+.ifdef na_enet_reset_n
+	MOVIP	%g1, na_enet_reset_n	; ethernet reset address
+	movi	%g0,1			; reset
+	st	[%g1],%g0		;
+.endif
+.endif
+
+	;------------------------------------------------------
+	; Zero out the .bss segment (uninitialized common data)
+	;
+	MOVIA	%g2,__bss_start		; presume nothing is between
+	MOVIA	%g1,_end		; the .bss and _end.
+	SUBI	%g1,1			; %g1 = last byte address
+	MOVI	%r0,0			; %r0 (%g0) is always ST8d's source.
+1:
+	ST8d	[%g2],%r0
+	CMP	%g2,%g1
+	IFS	cc_ne
+	 BR	1b
+	ADDI	%g2,1			; (delay slot)
+
+	;------------------------------------------------
+	; Install the CWP Underflow/Overflow trap vectors
+	; (assumes vectors are in RAM ...)
+	;
+	MOVIA	%g0,nasys_vector_table
+	MOVIA	%g1,CWPUnderflowTrapHandler@h
+	PFX	NA_UnderflowTrap
+	ST	[%g0],%g1
+	MOVIA	%g1,CWPOverflowTrapHandler@h
+	PFX	NA_OverflowTrap
+	ST	[%g0],%g1
+
+	;---------------------------------------------
+	; Set the reset trap (usually 0) to restart
+	; the monitor.
+	;
+	MOV	%g1,%g7				; for returning to where the monitor called us from
+;;;	MOVIA	%g1,nasys_reset_address@h	; set to the start address of the monitor
+	PFX	NA_ResetTrap
+	ST	[%g0],%g1
+
+	;------------------------------------------------------
+	; Call main() with interrupts enabled, priority level 3
+	; This blocks all interrupts EXCEPT under/overflow traps
+	;
+	MOVIA	%g0,nios_status		; get the STATUS extension address
+	bgen	%g1, PSR_SUPERVISOR_BIT	; set initial mode = supervisor
+	st	[%g0], %g1
+	
+	MOVIA	%g1, init_task_union	; load the current task ptr
+	MOVIA	%g0, _current_task
+	st	[%g0], %g1
+
+	ADDIP	%g1, 0x2000-0x40	; set stack at top of the task union
+	mov	%sp, %g1		; and reserve some space for reg win
+
+	MOVIA	%g0,main@h		; call main as a subroutine
+	CALL	%g0
+	 NOP
+
+	PFX	8			; (%ctl8 = CLR_IE)
+	WRCTL	%g0			; disable interrupts
+
+	;------------------------------------------------------------------
+	; If we return from main, do a Trap Zero to go back to the monitor.
+	;
+	TRAP	0
+;vic;	MOVIP	%g0,nasys_reset_address>>1	; this will be safer than 'trap 0'
+;vic;	JMP	%g0				;  (vector 0 may be corrupt)
+;vic;	 NOP					;
+
+	/* End of startup code */
+
+
+
+	.align	2
+	.global CWPUnderflowTrapHandler
+CWPUnderflowTrapHandler:
+
+; Current state:
+; CWP=LO_LIMIT has just performed a SAVE, which completes normally
+; except that now CWP=LO_LIMIT-1, which is not allowed.
+; So, we wind up here, and we shall make CWP=HI_LIMIT-1 seem like CWP=LO_LIMIT-1.
+
+;	CWP = LO_LIMIT-1 (usually 0) - new %l's and %o's
+;	%o6 (%sp) points to interrupted process's new and virgin stack frame
+;	%o7 (%r15) is the interrupted process's return address
+
+; As we march up the CWP frames, only the %g's can be relied on, as they're fixed.
+
+; Save the %g registers in the interrupted process's new stack frame.
+; Don't need to save the %l's because none have been used yet
+
+	sts	[%sp,0],%g0		; save the %g's where the %l's usually go
+	sts	[%sp,1],%g1
+	sts	[%sp,2],%g2
+	sts	[%sp,3],%g3
+	sts	[%sp,4],%g4
+	sts	[%sp,5],%g5
+	sts	[%sp,6],%g6
+	sts	[%sp,7],%g7
+
+	sts	[%sp, 8],%i0		; save the %i's (these are restored later)
+	sts	[%sp, 9],%i1
+	sts	[%sp,10],%i2
+	sts	[%sp,11],%i3
+	sts	[%sp,12],%i4
+	sts	[%sp,13],%i5
+	sts	[%sp,14],%i6
+	sts	[%sp,15],%i7
+
+	mov	%g6,%sp			; %g6 = stack ptr (%o6)
+	mov	%g7,%o7			; %g7 = return address
+
+	; Figure out HI- and LO-limit...
+
+	pfx	2			; read WVALID 
+	rdctl	%g2
+	lsri	%g2,1
+	ANDIP	%g2,PSR_CWP		; %g2 = CWP HI_LIMIT, in CTL 0 position
+
+	; Store the %l's and %i's on the stack in the 16 words that every routine provides.
+1:
+	restore				; move to previous reg window (CWP += 1)
+	STORE_WINDOW			; save the %l's and %i's at this CWP's stack ptr
+;;;	pfx	0			; read STATUS
+	rdctl	%g0
+	ANDIP	%g0,PSR_CWP		; isolate CWP
+	cmp	%g0,%g2			; compare to HI_LIMIT
+	BNE	1b			; not reached yet
+	 nop
+
+	; Now, get LO_LIMIT's %o's (LO_LIMIT-1'S %i's) into HI_LIMIT's %i's.
+	; CTL 0 is at HI_LIMIT and %g6 still points to the stashed registers.
+
+	; Modify CTL 1, which is the saved status register, so that
+	; the only difference upon return that instead of CWP = 0, we're
+	; at CWP = HI_LIMIT...
+	pfx	1			; read ISTATUS
+	rdctl	%g0			; %g0 has status stored before this rude interrupt
+	ANDNIP	%g0,PSR_CWP		; CTL 0 with old CWP masked out
+	or	%g0,%g2			; Insert HI_LIMIT
+	pfx	1			; write ISTATUS
+	wrctl	%g0			; Now, a TRET will land here.
+
+	; Restore the stack pointer and return address from CWP=0...
+	mov	%sp,%g6
+	mov	%o7,%g7
+
+	lds	%g0,[%sp,0]		; restore the %g's
+	lds	%g1,[%sp,1]
+	lds	%g2,[%sp,2]
+	lds	%g3,[%sp,3]
+	lds	%g4,[%sp,4]
+	lds	%g5,[%sp,5]
+	lds	%g6,[%sp,6]
+	lds	%g7,[%sp,7]
+
+	lds	%i0,[%sp, 8]		; restore the %i's
+	lds	%i1,[%sp, 9]
+	lds	%i2,[%sp,10]
+	lds	%i3,[%sp,11]
+	lds	%i4,[%sp,12]
+	lds	%i5,[%sp,13]
+	lds	%i6,[%sp,14]
+	lds	%i7,[%sp,15]
+
+	tret	%o7			; return to interrupted process
+
+
+	.align	2
+	.global CWPOverflowTrapHandler
+CWPOverflowTrapHandler:
+
+	; After RESTORE-ing too many times, we get
+	; a trap that puts us right here.
+	;
+	; We get here with CWP=HI_LIMIT and ISTATUS CWP=HI_LIMIT+1.
+	; We should leave here with CWP=LO_LIMIT, and lots of registers
+	; restored from how we stashed em on the stack.
+	;
+	; Since %i6 was the stack pointer at CWP=HI_LIMIT,
+	; it will now be %o6 here at CWP=HI_LIMIT+1.
+	;
+	; Up at CWP=HI_LIMIT+1, there are no %l or %i registers.
+	; The %l's alias to the %g's, in fact.
+	;
+
+	; Start by saving the globals, since that's our only safe space...
+
+	; Interrupted process has done a RESTORE which means they're done
+	; with %l's, most of %o's (except o6,o7), and the stack frame to which
+	; %sp (%o6) points.  We can use this abandoned stack frame to save
+	; the %g's and %i's which need to be restored.
+
+; Save the %g registers in the interrupted process's old stack frame.
+; Don't need to save the %l's because all have been abandoned.
+
+	sts	[%sp,0],%g0		; save the %g's (where %l's usually go)
+	sts	[%sp,1],%g1
+	sts	[%sp,2],%g2
+	sts	[%sp,3],%g3
+	sts	[%sp,4],%g4
+	sts	[%sp,5],%g5
+	sts	[%sp,6],%g6
+	sts	[%sp,7],%g7
+
+	sts	[%sp, 8],%i0		; save the %i's (these are restored later)
+	sts	[%sp, 9],%i1
+	sts	[%sp,10],%i2
+	sts	[%sp,11],%i3
+	sts	[%sp,12],%i4
+	sts	[%sp,13],%i5
+	sts	[%sp,14],%i6
+	sts	[%sp,15],%i7
+
+	mov	%g6,%sp			; save stack ptr (%o6)
+	mov	%g7,%o7			; save return address
+
+	; Figure out HI- and LO-limit...
+	pfx	2			; read WVALID
+	rdctl	%g0
+	mov	%g1,%g0
+	lsli	%g1,4			; %g1 in position to mask into CTL 0
+	ANDIP	%g1,PSR_CWP		; %g1 = CWP LO_LIMIT, in CTL 0 position
+	mov	%g2,%g0
+	lsri	%g2,1
+	ANDIP	%g2,PSR_CWP		; %g2 = CWP HI_LIMIT, in CTL 0 position
+
+	; Move to CWP=LO_LIMIT-1 and start climbing...
+;;;	pfx	0
+	rdctl	%g0			; read STATUS
+	ANDNIP	%g0,PSR_CWP		; mask off CWP
+	subi	%g1,0x0010		; %g1 = LO_LIMIT-1
+	or	%g0,%g1			; put into CWP
+;;;	pfx	0
+	wrctl	%g0
+	nop
+
+	mov	%sp,%g6			; Get stack pointer
+	lds	%i7,[%sp,15]		; load up the %i's from CWP=HI_LIMIT
+	lds	%i6,[%sp,14]
+	lds	%i5,[%sp,13]
+	lds	%i4,[%sp,12]
+	lds	%i3,[%sp,11]
+	lds	%i2,[%sp,10]
+	lds	%i1,[%sp, 9]
+	lds	%i0,[%sp, 8]
+
+
+	; The first  RESTORE puts CWP=LO_LIMIT and the %o's ready for action.
+	; This includes %sp, so CWP=LO_LIMIT can load up its %l's and %i's, and so on.
+1:
+	restore				; CWP += 1, next %sp
+	LOAD_WINDOW			; Restore %l's & %i's from where %sp points.
+;;;	pfx	0
+	rdctl	%g0			; read STATUS
+	ANDIP	%g0,PSR_CWP		; isolate CWP
+	cmp	%g2,%g0			; reached HI_LIMIT ?
+	BNE	1b			; not yet - keep going
+	 nop
+
+	; Set CWP = LO_LIMIT-1 so we can load up his %i's
+;;;	pfx	0			; read STATUS
+	rdctl	%g0
+	ANDNIP	%g0,PSR_CWP		; mask out CWP
+	or	%g0,%g1			; put LO_LIMIT-1 into CWP
+;;;	pfx	0			; write STATUS
+	wrctl	%g0
+	nop
+
+	; modify CTL 1 (ISTATUS) so that TRET takes us back to CWP=LO_LIMIT
+	pfx	1			; read saved status (ISTATUS)
+	rdctl	%g0
+	ANDNIP	%g0,PSR_CWP		; mask off saved CWP
+	addi	%g1,0x0010		; get LO_LIMIT
+	or	%g0,%g1			; put into saved CWP
+	pfx	1			; write ISTATUS
+	wrctl	%g0
+
+	mov	%o7,%g7			; retrieve return address
+	mov	%sp,%g6			; retrieve saved stack pointer
+
+	lds	%g7,[%sp,7]		; restore %g's from where %l's are usually stored
+	lds	%g6,[%sp,6]
+	lds	%g5,[%sp,5]
+	lds	%g4,[%sp,4]
+	lds	%g3,[%sp,3]
+	lds	%g2,[%sp,2]
+	lds	%g1,[%sp,1]
+	lds	%g0,[%sp,0]
+
+	tret	%o7
diff -urN linux-2.4.29/arch/niosnommu/kernel/hex.h linux-2.4.29-uc1/arch/niosnommu/kernel/hex.h
--- linux-2.4.29/arch/niosnommu/kernel/hex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/hex.h	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,30 @@
+#if 1
+#define outchar(X) { \
+		while (!(nasys_printf_uart->np_uartstatus & np_uartstatus_trdy_mask)); \
+		nasys_printf_uart->np_uarttxdata = (X); }
+#else
+#define outchar(X) putchar(X)
+#endif
+#define outhex(X,Y) { \
+		unsigned long __w; \
+		__w = ((X) >> (Y)) & 0xf; \
+		__w = __w > 0x9 ? 'A' + __w - 0xa : '0' + __w; \
+		outchar(__w); }
+#define outhex8(X) { \
+		outhex(X,4); \
+		outhex(X,0); }
+#define outhex16(X) { \
+		outhex(X,12); \
+		outhex(X,8); \
+		outhex(X,4); \
+		outhex(X,0); }
+#define outhex32(X) { \
+		outhex(X,28); \
+		outhex(X,24); \
+		outhex(X,20); \
+		outhex(X,16); \
+		outhex(X,12); \
+		outhex(X,8); \
+		outhex(X,4); \
+		outhex(X,0); }
+
diff -urN linux-2.4.29/arch/niosnommu/kernel/io.c linux-2.4.29-uc1/arch/niosnommu/kernel/io.c
--- linux-2.4.29/arch/niosnommu/kernel/io.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/io.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,66 @@
+/*
+ * Optimized IO string functions.
+ */
+
+
+#include <asm/io.h>
+
+
+void insw(unsigned long port, void *dst, unsigned long count)
+{
+	if (count > 8) {
+		/* Long word align buffer ptr */
+		if	((unsigned long)dst & 2) {
+			*(((unsigned short *)dst)++) = inw(port);
+			count--;
+		}
+
+		/* Input pairs of short and store as longs */
+		while (count >= 8) {
+			*(((unsigned long *)dst)++) = inw(port) + (inw(port) << 16);
+			*(((unsigned long *)dst)++) = inw(port) + (inw(port) << 16);
+			*(((unsigned long *)dst)++) = inw(port) + (inw(port) << 16);
+			*(((unsigned long *)dst)++) = inw(port) + (inw(port) << 16);
+			count -= 8;
+		}
+	}
+
+	/* Input remaining shorts */
+	while (count--)
+		*(((unsigned short *)dst)++) = inw(port);
+}
+
+
+void outsw(unsigned long port, void *src, unsigned long count)
+{
+	unsigned int lw;
+
+	if (count > 8) {
+		/* Long word align buffer ptr */
+		if	((unsigned long)src & 2) {
+			outw( *(((unsigned short *)src)++), port );
+			count--;
+		}
+
+		/* Read long words and output as pairs of short */
+		while (count >= 8) {
+			lw = *(((unsigned long *)src)++);
+			outw(lw, port);
+			outw((lw >> 16), port);
+			lw = *(((unsigned long *)src)++);
+			outw(lw, port);
+			outw((lw >> 16), port);
+			lw = *(((unsigned long *)src)++);
+			outw(lw, port);
+			outw((lw >> 16), port);
+			lw = *(((unsigned long *)src)++);
+			outw(lw, port);
+			outw((lw >> 16), port);
+			count -= 8;
+		}
+	}
+
+	/* Output remaining shorts */
+	while (count--) 
+		outw( *(((unsigned short *)src)++), port );
+}
diff -urN linux-2.4.29/arch/niosnommu/kernel/irq.c linux-2.4.29-uc1/arch/niosnommu/kernel/irq.c
--- linux-2.4.29/arch/niosnommu/kernel/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/irq.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,235 @@
+/*
+ * linux/arch/$(ARCH)/irq.c -- general exception handling code
+ *
+ * Cloned from Linux/m68k.
+ *
+ * No original Copyright holder listed,
+ * Probabily original (C) Roman Zippel (assigned DJD, 1999)
+ *
+ * Copyright 1999-2000 D. Jeff Dionne, <jeff@uClinux.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/nios.h>
+#include <asm/hardirq.h>
+
+/* assembler routines */
+asmlinkage void system_call(void);
+asmlinkage void real_irq_entry(void);
+asmlinkage void bad_trap_handler(void);
+asmlinkage void timer_handler(void);
+asmlinkage void binfmt_flat_debug_handler(void);
+asmlinkage void ocidec_handler(void);
+
+/* table for system interrupt handlers */
+static irq_handler_t irq_list[SYS_IRQS];
+
+static const char *default_names[SYS_IRQS] = {
+	"huh", "EDAC", "UART 1", "UART 2",
+	"pio0 handler", "pio1 handler", "pio2 handler", "pio3 handler",
+	"Timer 1", "Timer 2",
+};
+
+/* The number of spurious interrupts */
+volatile unsigned int num_spurious;
+
+#define NUM_IRQ_NODES 16
+static irq_node_t nodes[NUM_IRQ_NODES];
+
+void __init init_irq_proc(void)
+{
+	/* Insert /proc/irq driver here */
+}
+
+/*
+ * void init_IRQ(void)
+ *
+ * Parameters:	None
+ *
+ * Returns:	Nothing
+ *
+ * This function should be called during kernel startup to initialize
+ * the IRQ handling routines.
+ */
+
+void __init init_IRQ(void)
+{
+	int i;
+	unsigned int *vectorTable;
+
+	vectorTable = (int *)nasys_vector_table;
+
+/* Vic - RAM vector table inits */
+	/* set up the vectors */
+//	_ramvec[0] = 0;					/* hard reset  */
+//	_ramvec[1] = 0;					/* underflow   */
+//	_ramvec[2] = 0;					/* overflow    */
+//	_ramvec[3] = 0;					/* breakpoint  */
+//	_ramvec[4] = 0;					/* single step */
+//	_ramvec[5] = 0;					/* GDB start   */
+//      _ramvec[6] = 0;                                 /* binfmt_flat_debug_flag */
+	vectorTable[7] = bad_trap_handler;
+//	_ramvec[8] = 0;					/* debug/trace */
+
+	for (i = 9; i <= 15; i++)
+		vectorTable[i] = bad_trap_handler;
+	for (i = 16; i <= 62 ; i++)
+		vectorTable[i] = real_irq_entry;
+
+	vectorTable [6] = binfmt_flat_debug_handler;
+	vectorTable[63] = system_call;
+
+	vectorTable[na_timer0_irq] = timer_handler;
+#ifdef na_ide_interface_irq
+	vectorTable[na_ide_interface_irq] = ocidec_handler;
+#endif
+
+/* Vic - end of RAM vector table inits */
+
+	for (i = 0; i < SYS_IRQS; i++) {
+		irq_list[i].handler = NULL;
+		irq_list[i].flags   = IRQ_FLG_STD;
+		irq_list[i].dev_id  = NULL;
+		irq_list[i].devname = default_names[i];
+	}
+
+	for (i = 0; i < NUM_IRQ_NODES; i++)
+		nodes[i].handler = NULL;
+#ifdef DEBUG
+	printk("init_IRQ done\n");
+#endif
+}
+
+irq_node_t *new_irq_node(void)
+{
+	irq_node_t *node;
+	short i;
+
+	for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--)
+		if (!node->handler)
+			return node;
+
+	printk ("new_irq_node: out of nodes\n");
+	return NULL;
+}
+
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq < IRQMIN || irq > IRQMAX) {
+		printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+	if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
+		if (irq_list[irq].flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+	}
+	irq_list[irq].handler = handler;
+	irq_list[irq].flags   = flags;
+	irq_list[irq].dev_id  = dev_id;
+	irq_list[irq].devname = devname;
+	return 0;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq < IRQMIN || irq > IRQMAX) {
+		printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (irq_list[irq].dev_id != dev_id)
+		printk("%s: Removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, irq_list[irq].devname);
+
+	irq_list[irq].handler = NULL;
+	irq_list[irq].flags   = IRQ_FLG_STD;
+	irq_list[irq].dev_id  = NULL;
+	irq_list[irq].devname = default_names[irq];
+}
+
+/* usually not useful in embedded systems */
+unsigned long probe_irq_on (void)
+{
+	return 0;
+}
+
+int probe_irq_off (unsigned long irqs)
+{
+	return 0;
+}
+
+void enable_irq(unsigned int irq)
+{
+}
+
+void disable_irq(unsigned int irq)
+{
+}
+
+asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
+{
+	/* give the machine specific code a crack at it first */
+	irq_enter(0, irq);
+	kstat.irqs[0][vec]++;
+	if (irq_list[vec].handler) {
+		irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
+	} else
+#ifdef DEBUG
+		{
+		printk("No interrupt handler for level %ld\n", vec);
+////		asm("trap 5");
+		}
+#else
+  #if 1
+		printk("Ignoring interrupt %ld: no handler\n", vec);
+  #else
+		panic("No interrupt handler for level %ld\n", vec);
+  #endif
+#endif
+
+	irq_exit(0, irq);
+	if (softirq_pending(0))
+		do_softirq();
+
+}
+
+int get_irq_list(char *buf)
+{
+	int i, len = 0;
+
+	/* autovector interrupts */
+	for (i = 0; i < SYS_IRQS; i++) {
+		if (irq_list[i].handler) {
+			len += sprintf(buf+len, "auto %2d: %10u ", i,
+			               i ? kstat.irqs[0][i] : num_spurious);
+			if (irq_list[i].flags & IRQ_FLG_LOCK)
+				len += sprintf(buf+len, "L ");
+			else
+				len += sprintf(buf+len, "  ");
+			len += sprintf(buf+len, "%s\n", irq_list[i].devname);
+		}
+	}
+	return len;
+}
diff -urN linux-2.4.29/arch/niosnommu/kernel/Makefile linux-2.4.29-uc1/arch/niosnommu/kernel/Makefile
--- linux-2.4.29/arch/niosnommu/kernel/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/Makefile	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,42 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+.S.s:
+	$(CPP) -D__ASSEMBLY__ $(AFLAGS) -ansi $< -o $*.s
+
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c $< -o $*.o
+
+all: kernel.o head.o
+
+O_TARGET := kernel.o
+
+obj-y   := entry.o switch.o traps.o irq.o \
+	    process.o signal.o setup.o sys_nios.o \
+	    semaphore.o nios_flat.o io.o \
+	    time.o ptrace.o start.o nios_module.o nios_ksyms.o
+
+export-objs := nios_ksyms.o
+
+obj-$(CONFIG_KGDB) += nios_gdb_stub_isr.o nios_gdb_stub_io.o nios_gdb_stub.o
+
+entry.o: entry.S nios_defs.h
+head.o: head.S nios_defs.h
+switch.o: switch.S nios_defs.h
+
+nios_defs.h: nios_defs.c nios_defs.head
+	rm -f nios_defs.d
+	SUNPRO_DEPENDENCIES="nios_defs.d nios_defs.h" \
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S nios_defs.c
+	cp nios_defs.head nios_defs.h
+	grep '^#define' nios_defs.s >> nios_defs.h
+	rm nios_defs.s
+-include nios_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/niosnommu/kernel/nios_defs.c linux-2.4.29-uc1/arch/niosnommu/kernel/nios_defs.c
--- linux-2.4.29/arch/niosnommu/kernel/nios_defs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/nios_defs.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,96 @@
+//vic Copied from m68knommu architecture
+/*
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ */
+
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/irq.h>
+#include <asm/hardirq.h>
+#include <asm/errno.h>
+#include <asm/niosconf.h>
+
+#define DEFINE(sym, val) \
+	asm volatile ("\n#define " #sym " %0" : : "i" (val))
+
+int main (void)
+{
+	/* offsets into the task struct */
+//vic	DEFINE(TASK_STATE, offsetof(struct task_struct, state));
+	DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
+//vic	DEFINE (TASK_PTRACE, offsetof(struct task_struct, ptrace));
+	DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
+//vic	DEFINE(TASK_COUNTER, offsetof(struct task_struct, counter));
+	DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, sigpending));
+	DEFINE(TASK_NEED_RESCHED, offsetof(struct task_struct, need_resched));
+	DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
+//vic	DEFINE(TASK_MM, offsetof(struct task_struct, mm));
+//vic	DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
+
+	/* offsets into the cpu status struct */
+//vic	DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
+//vic	DEFINE(CPUSTAT_LOCAL_IRQ_COUNT, offsetof(irq_cpustat_t, __local_irq_count));
+
+	/* offsets into the thread struct */
+	DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
+	DEFINE(THREAD_KPC, offsetof(struct thread_struct, kpc));
+	DEFINE(THREAD_KPSR, offsetof(struct thread_struct, kpsr));
+	DEFINE(THREAD_FORK_KPSR, offsetof(struct thread_struct, fork_kpsr));
+	DEFINE(THREAD_SPARE_REG_WINDOW, offsetof (struct thread_struct, spare_reg_window));
+	DEFINE(THREAD_SPARE_W_SAVED, offsetof (struct thread_struct, spare_w_saved));
+	DEFINE(THREAD_FLAGS, offsetof(struct thread_struct, flags));
+
+	/* thread flag bits */
+	DEFINE(NIOS_FLAG_KTHREAD, NIOS_FLAG_KTHREAD);
+	DEFINE(NIOS_FLAG_COPROC, NIOS_FLAG_COPROC);
+	DEFINE(NIOS_FLAG_DEBUG, NIOS_FLAG_DEBUG);
+
+	/* register window struct */
+	DEFINE(REGWIN_SZ, REGWIN_SZ);
+
+	/* ptrace register struct */
+	DEFINE(TRACEREG_SZ, TRACEREG_SZ);
+
+	/* task / stack size */
+	DEFINE(THREAD_SIZE, THREAD_SIZE);
+
+//vic	/* offsets into the kernel_stat struct */
+//vic	DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
+
+	/* signal defines */
+	DEFINE(SIGCHLD, SIGCHLD);
+
+	/* ptrace flag bits */
+//vic	DEFINE(PT_PTRACED, PT_PTRACED);
+//vic	DEFINE(PT_TRACESYS, PT_TRACESYS);
+//vic	DEFINE(PT_DTRACE, PT_DTRACE);
+
+	/* error values */
+//vic	DEFINE(ENOSYS, ENOSYS);
+
+	/* clone flag bits */
+	DEFINE(CLONE_VFORK, CLONE_VFORK);
+	DEFINE(CLONE_VM, CLONE_VM);
+
+	/* the flash chip */
+	DEFINE(NIOS_FLASH_START, NIOS_FLASH_START);
+	
+	/* the kernel placement in the flash*/
+	DEFINE(KERNEL_FLASH_START, KERNEL_FLASH_START);
+	
+	/* the romdisk placement in the flash */
+	DEFINE(LINUX_ROMFS_START, LINUX_ROMFS_START);
+	DEFINE(LINUX_ROMFS_END, LINUX_ROMFS_END);
+	
+	/* the sdram */
+	DEFINE(LINUX_SDRAM_START, LINUX_SDRAM_START);
+	
+	return 0;
+}
diff -urN linux-2.4.29/arch/niosnommu/kernel/nios_defs.h linux-2.4.29-uc1/arch/niosnommu/kernel/nios_defs.h
--- linux-2.4.29/arch/niosnommu/kernel/nios_defs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/nios_defs.h	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,31 @@
+/*
+ * WARNING! This file is automatically generated - DO NOT EDIT!
+ */
+
+#define TS_MAGICKEY	0x5a5a5a5a
+#define TASK_FLAGS 4
+#define TASK_BLOCKED 788
+#define TASK_SIGPENDING 8
+#define TASK_NEED_RESCHED 20
+#define TASK_THREAD 620
+#define THREAD_KSP 16
+#define THREAD_KPC 20
+#define THREAD_KPSR 24
+#define THREAD_FORK_KPSR 32
+#define THREAD_SPARE_REG_WINDOW 40
+#define THREAD_SPARE_W_SAVED 104
+#define THREAD_FLAGS 108
+#define NIOS_FLAG_KTHREAD 1
+#define NIOS_FLAG_COPROC 2
+#define NIOS_FLAG_DEBUG 4
+#define REGWIN_SZ 64
+#define TRACEREG_SZ 80
+#define THREAD_SIZE 8192
+#define SIGCHLD 17
+#define CLONE_VFORK 16384
+#define CLONE_VM 256
+#define NIOS_FLASH_START 8388608
+#define KERNEL_FLASH_START 8388608
+#define LINUX_ROMFS_START 10485760
+#define LINUX_ROMFS_END 16777216
+#define LINUX_SDRAM_START 16777472
diff -urN linux-2.4.29/arch/niosnommu/kernel/nios_defs.head linux-2.4.29-uc1/arch/niosnommu/kernel/nios_defs.head
--- linux-2.4.29/arch/niosnommu/kernel/nios_defs.head	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/nios_defs.head	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * WARNING! This file is automatically generated - DO NOT EDIT!
+ */
+
+#define TS_MAGICKEY	0x5a5a5a5a
diff -urN linux-2.4.29/arch/niosnommu/kernel/nios_flat.c linux-2.4.29-uc1/arch/niosnommu/kernel/nios_flat.c
--- linux-2.4.29/arch/niosnommu/kernel/nios_flat.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/nios_flat.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,406 @@
+#include <linux/module.h>
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/flat.h>
+#include <linux/elf.h>
+
+#include <asm/flat.h>
+
+#define RELOC_OK            0
+#define RELOC_UNSUPPORTED  -1
+#define RELOC_OVERFLOW     -2
+#define RELOC_BAD_SECTION  -3
+#define RELOC_UNKNOWN_TYPE -4
+
+/* temporary turning offthe trace */
+#undef TRACE
+#define TRACE 0
+#undef TRACE_MAX
+#define TRACE_MAX 1
+static int do_nios32_reloc( reloc_struct *pReloc, unsigned long entry )
+{
+  	int             status = RELOC_OK;
+
+	char           *pSrcSect; // SrcSect is section of the stuff being referenced. Def'n as char * for easy ptr. arithmetic
+	char           *pDstSect; // DstSect is the section of the stuff that needs to be fixed up.
+        unsigned short *pDst;     // ptr to the instruction
+	unsigned short  insn;  	  // The 16-bit instruction
+	unsigned long   value;    // The src address value
+
+	// Reduce code size: Dereference variables that are used in all case blocks.
+	signed long     addend    = pReloc->addend;
+	signed long     srcOffset = pReloc->src_offset;
+	signed long     dstOffset = pReloc->offset;
+#if TRACE >= TRACE_MAX
+	char           *srcSectName, *dstSectName, *relocName;
+#endif
+
+	/* Setup the DstSect. */
+	switch ( pReloc->dest_section )
+	{
+	    case FLAT_RELOC_TYPE_TEXT :
+		pDstSect = (char *)(current->mm->start_code);
+#if TRACE >= TRACE_MAX
+		dstSectName = ".text";
+#endif
+		break;
+
+	    case FLAT_RELOC_TYPE_DATA :
+		pDstSect = (char *)(current->mm->start_data);
+#if TRACE >= TRACE_MAX
+		dstSectName = ".data";
+#endif
+		break;
+
+	    case FLAT_RELOC_TYPE_BSS:
+		pDstSect = (char *)(current->mm->end_data);
+#if TRACE >= TRACE_MAX
+		dstSectName = ".bss";
+#endif
+		break;
+
+  	    default :
+		return RELOC_BAD_SECTION;
+	}
+
+
+	/* Setup the SrcSect. */
+	switch ( pReloc->src_section )
+	{
+	    case FLAT_RELOC_TYPE_TEXT :
+	        pSrcSect = (char *)(current->mm->start_code);
+#if TRACE >= TRACE_MAX
+		srcSectName = ".text";
+#endif
+		break;
+
+	    case FLAT_RELOC_TYPE_DATA :
+		pSrcSect = (char *)(current->mm->start_data);
+#if TRACE >= TRACE_MAX
+		srcSectName = ".data";
+#endif
+		break;
+
+	    case FLAT_RELOC_TYPE_BSS:
+		pSrcSect = (char *)(current->mm->end_data);
+#if TRACE >= TRACE_MAX
+		srcSectName = ".bss";
+#endif
+		break;
+
+  	    default :
+		return RELOC_BAD_SECTION;
+	}
+
+
+	dstOffset -= entry;
+        pDst       = (unsigned short *)(pDstSect + dstOffset);
+	value      = (unsigned long)(pSrcSect + srcOffset);
+	insn       = *pDst;
+
+
+  	switch( pReloc->reloc_type )
+	{
+	    case R_NIOS_NONE :                          // A no-op reloc (should not exist).
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_NONE";
+#endif
+	  	status =  -1;
+		break;
+
+	    case R_NIOS_32 :                            // A 32 bit absolute relocation.
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_32";
+#endif
+		*(long *)pDst = value + addend;
+		break;
+
+	    case R_NIOS_LO16_LO5 :                      // A LO-16 5 bit absolute relocation.
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_LO16_LO5";
+#endif
+	        value += addend;
+		value  = (value & 0x001f);
+		insn   = ((insn & 0xfc1f) | (value << 5));
+		*pDst  = insn;
+		break;
+
+  	    case R_NIOS_LO16_HI11 :                     // A LO-16 top 11 bit absolute relocation.
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_LO16_HI11";
+#endif
+                value += addend;
+		value  = ((value & 0xffff) >> 5);
+		insn   = (insn & 0xf800) | value;
+		*pDst  = insn;
+		break;
+
+
+	    case R_NIOS_HI16_LO5 :                      // A HI-16 5 bit absolute relocation.
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_HI16_LO5";
+#endif
+                value  += addend;
+		value   = ((value >> 16) & 0x001f);
+		value <<= 5;
+		insn    = ((insn & 0xfc1f) | value);
+		*pDst   = insn;
+		break;
+
+	    case R_NIOS_HI16_HI11 :                     // A HI-16 top 11 bit absolute relocation.
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_HI16_HI11";
+#endif
+	        value += addend;
+		value  = (value >> 21);
+		insn   = ((insn & 0xf800) | value);
+		*pDst  = insn;
+		break;
+
+	    case R_NIOS_PCREL6 :                        // A 6 bit relative relocation.
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_PCREL6";
+#endif
+	        value  -= (unsigned long)pDst;
+		value  += addend;
+		value  -= 4;
+		value >>= 2;
+
+		if ( (long)value > 0x3F || (long)value < 0 )
+		    return -2;  // overflow
+
+		value &= 0x3f;
+		insn   = insn & 0xf800;
+		insn   = insn | (value << 5);
+		*pDst  = insn;
+		break;
+
+
+	    case R_NIOS_PCREL8 :                        // An 8 bit relative relocation.
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_PCREL8";
+#endif
+	        value  -= (unsigned long)pDst;
+		value  += addend;
+		value  -= 2;
+		value >>= 1;
+		if ((long) value > 0xff || (long) value < 0)
+		{
+		    status = RELOC_OVERFLOW;
+		    break;
+		}
+
+		insn  = insn & 0x701f;
+		insn  = insn | (value << 5);
+		*pDst = insn;
+		break;
+
+	    case R_NIOS_PCREL11 :                       // An 11 bit relative relocation.    
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_PCREL11";
+#endif
+	        value -= (unsigned long)pDst;
+		value += addend;
+		/* insn uses bottom 11 bits of relocation value times 2 */
+		value = (value & 0x7ff) >> 1;
+
+		if ((long) value > 0x7ff)
+		{
+		    status = RELOC_OVERFLOW;
+		    break;
+		}
+
+		insn  = insn & 0xf800;
+		insn  = insn | value;
+		*pDst = insn;
+		break;
+
+	    case R_NIOS_16 :                             // A 16 bit absolute relocation. (Should not see these here).
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_16";
+#endif
+	        value  += addend;
+		value >>= 1;
+		*pDst   = (unsigned short)value;
+		break;
+
+
+	    case R_NIOS_H_LO5 :                         // Low 5-bits of absolute relocation in halfwords.
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_H_LO5";
+#endif
+	        value += addend;
+		value  = ((value >> 1) & 0x001f);
+		insn   = ((insn & 0xfc1f) | (value << 5));
+		*pDst  = insn;
+		break;
+
+
+	    case R_NIOS_H_HI11 :                        // Top 11 bits of 16-bit absolute relocation in halfwords.
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_H_HI11";
+#endif
+	        value += addend;
+		value  = ((value & 0x1fffe) >> 6);
+                insn   = (insn & 0xf800) | value;
+		*pDst  = insn;
+		break;
+
+
+	    case R_NIOS_H_XLO5 :                        // Low 5 bits of top 16-bits of 32-bit absolute relocation in halfwords.
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_H_XLO5";
+#endif
+	        value  += addend;
+	        value   = ((value >> 17) & 0x001f);
+		value <<= 5;
+		insn    = ((insn & 0xfc1f) | value);
+		*pDst   = insn;
+		break;
+
+
+	    case R_NIOS_H_XHI11 :                       // Top 11 bits of top 16-bits of 32-bit absolute relocation in halfwords.
+#if TRACE >= TRACE_MAX
+	      relocName = "R_NIOS_H_XHI11";
+#endif
+	        value  += addend;
+		value >>= 22;
+		insn    = ((insn & 0xf800) | value);
+		*pDst   = insn;
+		break;
+
+
+	    case R_NIOS_H_16 :                          // Half-word @h value.
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_H_XH111";
+#endif
+	        value  += addend;
+		value >>= 1;
+
+		if (value > 0xffff)
+		{
+		    status = RELOC_OVERFLOW;
+		    break;
+		}
+
+		*pDst = insn;
+		break;
+
+
+	    case R_NIOS_H_32 :                          // Word @h value.
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_H_32";
+#endif
+	        value  += addend;
+	        value >>= 1;
+	        *(unsigned long *)pDst = value;
+	        break;
+
+
+	    case R_NIOS_GNU_VTINHERIT :                 // GNU extension to record C++ vtable hierarchy.
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_GNU_VTINHERIT";
+#endif
+		status = RELOC_UNSUPPORTED;
+		break;
+
+
+ 	    case R_NIOS_GNU_VTENTRY :                   // GNU extension to record C++ vtable member usage.
+#if TRACE >= TRACE_MAX
+	        relocName = "R_NIOS_GNU_VTENTRY";
+#endif
+	        status = RELOC_UNSUPPORTED;
+		break;
+  
+
+	    default :
+#if TRACE >= TRACE_MAX
+	        relocName = "UNKNOWN RELOC TYPE";
+#endif
+	        status = RELOC_UNKNOWN_TYPE;
+	        break;
+	}
+
+#if TRACE >= TRACE_MAX
+	printk( "Reloc[%ul] dst_section = %s, dst_offset = 0x%08lX (%ld), reloc_type %s\n"
+                "           src_section = %s, src_offset = 0x%08lX (%ld), addend = 0x%08lX (%ld)\n",
+		0, dstSectName, dstOffset, dstOffset, relocName,
+                srcSectName, srcOffset, srcOffset, addend, addend );
+#endif
+	return status;
+}
+
+
+/**************************************************/
+/* reloc_struct's offset indicated where relative */
+/* to mm->start_data to adjust an address value.  */
+/* flat_struct's type indicates the section in    */
+/* which the value resides: Add the appropriate   */
+/* adjustment based upon the section type. Note:  */
+/* This behaviour is appropriate for the original */
+/* binfmt_flat format for 68K-based systems. The  */
+/* Nios uses the extended format where the type   */
+/* field indicates the extended format and the    */
+/* reloc_type field indicated the kind of reloc.  */
+/* to perform.                                    */
+/**************************************************/
+void nios_old_reloc(reloc_struct *r, unsigned long entry)
+{
+  	long	       offset;
+  	unsigned long *pLong;
+	void          *pVoid;
+	int            i;
+	int            status;
+
+	/* Do the endian flip. */
+	for ( i = sizeof(reloc_struct) / sizeof(unsigned long), pLong = (unsigned long *)r; i; i--, pLong++ )
+		*pLong = htonl( *pLong );
+
+
+	offset = r->offset;
+	pVoid = (void *)current->mm->start_data + offset;	// Points at stuff to relocate: start_data is the origin
+
+
+#ifdef DEBUG0 /* wentao */
+	printk("TEXTSEG=%x, DATASEG=%x, BSSSEG=%x\n",
+		current->mm->start_code,
+		current->mm->start_data,
+		current->mm->end_data);
+
+	printk("Relocation type = %d, offset = %d\n", r->type, r->offset);
+#endif
+
+	
+	switch (r->type) {
+	case FLAT_RELOC_TYPE_TEXT:
+	  *(long *)pVoid += current->mm->start_code;
+	  break;
+	case FLAT_RELOC_TYPE_DATA:
+	  *(long *)pVoid += current->mm->start_data;
+	  break;
+	case FLAT_RELOC_TYPE_BSS:
+	  *(long *)pVoid += current->mm->end_data;
+	  break;
+
+	case FLAT_RELOC_EXTENDED:
+	  status = do_nios32_reloc( r, entry );
+#if TRACE >= TRACE_MAX
+	  switch ( status )
+          {
+	      case RELOC_OK          :                                                 break;
+  	      case RELOC_OVERFLOW    :  printk( "reloc overflow\n" );                  break;
+	      case RELOC_UNSUPPORTED :  printk( "reloc unsupported type\n" );          break;
+	      case RELOC_UNKNOWN_TYPE:  printk( "reloc unknown type\n" );              break;
+	      case RELOC_BAD_SECTION :  printk( "reloc bad section\n" );               break;
+    	      default                :  printk( "reloc unknown status %d\n", status ); break;
+	  }
+#endif
+	  break;
+
+
+	default:
+	  printk("Unknown relocation\n");
+	}
+}		
\ No newline at end of file
diff -urN linux-2.4.29/arch/niosnommu/kernel/nios_gdb_stub.c linux-2.4.29-uc1/arch/niosnommu/kernel/nios_gdb_stub.c
--- linux-2.4.29/arch/niosnommu/kernel/nios_gdb_stub.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/nios_gdb_stub.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,1454 @@
+// Modified for uClinux - Vic - Apr 2002
+// From:
+
+// File: nios_gdb_stub.c
+// Date: 2000 June 20
+// Author dvb \ Altera Santa Cruz
+
+#ifndef __KERNEL__
+#include "nios.h"
+#else
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/nios.h>
+#endif
+
+#include "nios_gdb_stub.h"
+
+#define na_debug_peripheral_irq 8
+
+enum
+{
+  na_BreakpointTrap     = 3,
+  na_SingleStepTrap     = 4,
+  na_StartGDBTrap       = 5
+};
+
+
+#ifdef __KERNEL__
+
+extern int _etext;
+
+static void puts( unsigned char *s )
+{
+	while(*s) {
+		while (!(nasys_printf_uart->np_uartstatus & np_uartstatus_trdy_mask));
+		nasys_printf_uart->np_uarttxdata = *s++;
+	}
+}
+
+#endif	// __KERNEL__
+
+// --------------------------------
+// Local Prototypes
+
+static void StringFit(char *s,int w);
+
+// --------------------------------
+// Debugging The Debugger
+
+#if GDB_DEBUG_PRINT
+void GDB_RawMessage(char *s)
+	{
+	StringFit(s,32);
+	nr_pio_lcdwritescreen(s);
+	}
+#else
+	#define GDB_RawMessage(a,b,c)	// define away to nothing
+#endif
+
+#if GDB_DEBUG_PRINT
+void GDB_Print2(char *s,int n1,int n2)
+	{
+	char st[1000];
+
+	sprintf(st,s,n1,n2);
+	GDB_RawMessage(st);
+	}
+#else
+	#define GDB_Print2(a,b,c)	// define away to nothing
+#endif
+
+// If string is longer than w, cut out the middle.
+
+#if GDB_DEBUG_PRINT
+int StringLen(char *s)
+	{
+	int l = 0;
+
+	while(*s++)
+		l++;
+	return l;
+	}
+
+void StringFit(char *s,int w)
+	{
+	if(StringLen(s) > w)
+		{
+		int i;
+
+
+		w = w / 2;
+
+		for(i = 0; i < w; i++)
+			{
+			s[i + w] = s[StringLen(s) - w + i];
+			}
+		s[w + w] = 0;
+		}
+	}
+#endif
+
+// ---------------------------------------------
+// Generic routines for dealing with
+// hex input, output, and parsing
+// (Adapted from other stubs.)
+
+NiosGDBGlobals gdb = {0};		// not static: the ISR uses it!
+
+static char dHexChars[16] = "0123456789abcdef";
+
+/*
+ * HexCharToValue -- convert a characters
+ *                   to its hex value, or -1 if not.
+ */
+char HexCharToValue(char c)
+{
+	char result=0;
+
+	if(c >= '0' && c <= '9')
+		result = c - '0';
+	else if(c >= 'a' && c <= 'f')
+		result = c - 'a' + 10;
+	else if(c >= 'A' && c <= 'F')
+		result = c - 'A' + 10;
+	else
+		result = -1;
+	return result;
+}
+
+/*
+ * HexStringToValue -- convert a 2*byte_width string of characters
+ *                   to its little endian hex value,
+ *		     or -1 if not.
+ *		This routine is for strings of hex values
+ */
+unsigned long HexStringToValue(char *c, int byte_width)
+{
+	unsigned long result=0;
+	unsigned char a,b;
+	int i=0;
+
+	while (i < byte_width)
+	{
+		a = HexCharToValue(*c++);
+		if (a & 0x80) return a;
+		b = HexCharToValue(*c++);
+		if (b & 0x80) return b;
+		b = (a<<4) | (b&0x0f);
+		result |= b << (i*8);
+		i++;
+	}
+	return result;
+}
+
+/*
+ * Hex2Value -- convert a non-hex char delimited string
+ * 		to its big endian hex value.
+ *		This routine is for address and byte count values
+ */
+
+char *Hex2Value(char *hexIn, int *valueOut)
+	{
+	char c;
+	int digitValue;
+	int value = 0;
+
+	while(1)
+		{
+		c = *hexIn;
+		digitValue = HexCharToValue(c);
+		if(digitValue < 0)
+			{
+			*valueOut = value;
+			return hexIn;
+			}
+		hexIn++;
+		value = (value << 4) + digitValue;
+		}
+	}
+
+/*
+ * HexToMem -- convert a string to a specified
+ *             number of bytes in memory.
+ *
+ *		JMB -- make this thing a bit smarter so
+ *			   that it selects the byte width to
+ *			   write based on the number of bytes
+ *			   and the destination address alignment.
+ *			   This is to support writes to non-byte enabled
+ *			   peripheral registers...I don't like it.
+ *			   Beware! there are cases where it wont work
+ */
+char *HexToMem(char *hexIn, char *memOut, int memByteCount)
+{
+	int i;
+	unsigned long x;
+	short *memOutS;
+	long *memOutL;
+	int byte_width;
+
+	//determine maximum byte width
+	if (((memByteCount%2) != 0) || (((unsigned int)memOut%2) != 0))
+		byte_width = 1;
+	else if (((memByteCount % 4) != 0) || (((unsigned int)memOut % 4) != 0))
+	{
+		byte_width = 2;
+		memOutS = (short *)memOut;
+	}
+	else
+	{
+		byte_width = 4;
+		memOutL = (long *)memOut;
+	}
+	for(i = 0; i < memByteCount; i+=byte_width)
+	{
+		x = HexStringToValue(hexIn,byte_width);
+		hexIn += byte_width*2;
+		switch (byte_width)
+		{
+		case 1:
+			*memOut++ = (unsigned char) 0x000000ff & x;
+			break;
+		case 2:
+			*memOutS++ = (unsigned short) 0x0000ffff & x;
+			break;
+		case 4:
+			*memOutL++ = x;
+			break;
+		default:
+			//How could this ever happen???
+			break;
+		}
+	}
+
+	return hexIn;
+}
+
+char *MemToHex(char *memIn, char *hexOut, int memByteCount)
+{
+	int i,j;
+	int byte_width;
+	unsigned long x;
+	unsigned short *memInS;
+	unsigned long *memInL;
+
+	//determine maximum byte width
+	if (((memByteCount % 2) != 0) || (((unsigned int)memIn % 2) != 0))
+		byte_width = 1;
+	else if (((memByteCount % 4) != 0) || (((unsigned int)memIn % 4) != 0))
+	{
+		byte_width = 2;
+		memInS = (short *)memIn;
+	}
+	else
+	{
+		byte_width = 4;
+		memInL = (long *)memIn;
+	}
+
+	for(i = 0; i < memByteCount; i+=byte_width)
+	{
+		switch (byte_width)
+		{
+		case 1:
+			x = *memIn++;
+			break;
+		case 2:
+			x = *memInS++;
+			break;
+		case 4:
+			x = *memInL++;
+			break;
+		default:
+			//How would we get here?
+			break;
+		}
+
+		for (j=0; j<byte_width; j++)
+		{
+			*hexOut++ = dHexChars[(x&0x000000f0)>>4];
+			*hexOut++ = dHexChars[x&0x0000000f];
+			x = x>>8;
+		}
+	}
+
+	*hexOut = 0;
+
+	return hexOut;
+}
+
+//Send just the + or - to indicate
+//ACK or NACK
+void GDBPutAck (char ack)
+{
+	if (gdb.comlink == ne_gdb_serial)
+		GDBPutChar (ack);
+#ifdef ETHER_DEBUG
+#ifdef ethernet_exists
+	else
+	{
+		if (gdb.host_ip_address != 0)
+			nr_plugs_send_to (gdb.gdb_eth_plug, &ack, 1, 0,
+				gdb.host_ip_address,
+				gdb.host_port_number);
+	}
+#endif
+#endif
+}
+
+/*
+ * Once a $ comes in, use GetGDBPacket to
+ * retrieve a full gdb packet, and verify
+ * checksum, and reply + or -.
+ */
+int GetGDBPacket(char *aBuffer)
+{
+	int checksum;
+	int length;
+	char c;
+	int x;
+
+	if (gdb.comlink == ne_gdb_serial)
+	{
+		while ((c = GDBGetChar ()) != '$') ;
+
+startPacket:
+		length = 0;
+		checksum = 0;
+		while(((c = GDBGetChar()) != '#') && (length < kTextBufferSize))
+		{
+			if(c == '$')
+				goto startPacket;
+			checksum += c;
+			aBuffer[length++] = c;
+			aBuffer[length] = 0;
+		}
+
+		c = GDBGetChar();
+		x = HexCharToValue(c) << 4;
+		c = GDBGetChar();
+		x += HexCharToValue(c);
+
+
+		checksum &= 0xff;
+
+		GDB_Print2("GetPacket %d",length,0);
+	}
+#ifdef ETHER_DEBUG
+#ifdef ethernet_exists
+	else
+	{
+		int srcidx;
+		// wait till beginning of packet
+		while (gdb.textBuffer[0] != '$') nr_plugs_idle();
+startEPacket:
+		length = 0;
+		checksum = 0;
+		srcidx = 1;
+
+		//loop until packet terminator
+		//leave enough room for the checksum at the end
+		while (((c = gdb.textBuffer[srcidx++]) != '#') && (srcidx < kTextBufferSize-2))
+		{
+			if (c == '$')
+				goto startEPacket;
+
+			checksum += c;
+			aBuffer[length++] = c;
+		}
+
+		c = gdb.textBuffer[srcidx++];
+		x = HexCharToValue(c) << 4;
+		c = gdb.textBuffer[srcidx++];
+		x += HexCharToValue (c);
+
+		aBuffer[length++] = 0;
+
+		checksum &= 0xff;
+
+		GDB_Print2("GetPacket %d",length,0);
+	}
+#endif
+#endif
+
+	if(checksum != x)
+	{
+		GDBPutAck('-');
+		length = 0;
+	}
+	else
+	{
+		GDBPutAck('+');
+	}
+	return length;
+}
+
+//Wait for acknowledgement
+//Should we have some way of timing out???
+//return TRUE if ACK
+//return FALSE if NACK
+int GDBGetACK ()
+{
+	char c;
+	if (gdb.comlink == ne_gdb_serial)
+	{
+		while (1)
+		{
+			c = GDBGetChar ();
+			if (c == '+') return (1);
+			else if (c == '-') return (0);
+		}
+
+	}
+#ifdef ETHER_DEBUG
+#ifdef ethernet_exists
+	else
+	{
+		gdb.ACKstatus = ne_gdb_ack_waiting;
+		while (1)
+		{
+			nr_plugs_idle ();
+			if (gdb.ACKstatus == ne_gdb_ack_acked)
+			{
+				gdb.ACKstatus = ne_gdb_ack_notwaiting;
+				return (1);
+			}
+			else if (gdb.ACKstatus == ne_gdb_ack_nacked)
+			{
+				gdb.ACKstatus = ne_gdb_ack_notwaiting;
+				return (0);
+			}
+		}
+	}
+#endif
+#endif
+}
+
+/*
+ * Send a packet, preceded by $,
+ * and followed by #checksum.
+ */
+void PutGDBPacket(char *aBuffer)
+{
+	int checksum;
+	char c;
+	char *origPtr;
+	int cnt=0;
+
+	origPtr = aBuffer; // Remember in case we get a NACK
+	if (gdb.comlink == ne_gdb_serial)
+	{
+startPutSerial:
+		GDBPutChar('$');
+		checksum = 0;
+		while((c = *aBuffer++) != 0)
+		{
+			checksum += c;
+			GDBPutChar(c);
+		}
+		GDBPutChar('#');
+		GDBPutChar(dHexChars[(checksum >> 4) & 15]);
+		GDBPutChar(dHexChars[checksum & 15]);
+
+		if (!GDBGetACK ())
+		{
+		  aBuffer = origPtr;
+			if (++cnt < GDB_RETRY_CNT) goto startPutSerial;
+		}
+	}
+#ifdef ETHER_DEBUG
+#ifdef ethernet_exists
+	else
+	{
+		if (gdb.host_ip_address != 0)
+		{
+			int i;
+			int result;
+			char c1;
+
+			i = 0;
+			c = aBuffer[i];
+			if (c==0) return; //there is no data in packet, so why bother sending
+			aBuffer[i++] = '$';
+			checksum = 0;
+			do
+			{
+				checksum += c;
+				c1 = aBuffer[i];
+				aBuffer[i++] = c;
+				c = c1;
+			} while (c != 0);
+
+			aBuffer[i++] = '#';
+			aBuffer[i++] = dHexChars[(checksum >> 4) & 15];
+			aBuffer[i++] = dHexChars[checksum & 15];
+			aBuffer[i++] = 0;
+startPutEth:
+			result = nr_plugs_send_to (gdb.gdb_eth_plug, aBuffer, i, 0,
+				gdb.host_ip_address,
+				gdb.host_port_number);
+
+			if (!GDBGetACK ())
+			{
+				if (++cnt < GDB_RETRY_CNT) goto startPutEth;
+			}
+			aBuffer[0] = 0; //clear packet to
+		}
+	}
+#endif
+#endif
+}
+
+int PutTracePacket(char *aBuffer, int size)
+{
+	int checksum;
+	char c;
+	int i;
+	int cnt=0;
+
+	if (gdb.comlink == ne_gdb_serial)
+	{
+startPutSerial:
+		GDBPutChar('$');
+		checksum = 0;
+		for (i=0; i<size; i++)
+		{
+			checksum += aBuffer[i];
+			GDBPutChar (aBuffer[i]);
+		}
+		GDBPutChar('#');
+		GDBPutChar(dHexChars[(checksum >> 4) & 15]);
+		GDBPutChar(dHexChars[checksum & 15]);
+
+		if (!GDBGetACK ())
+		{
+			if (++cnt < GDB_RETRY_CNT) goto startPutSerial;
+		}
+	}
+#ifdef ETHER_DEBUG
+#ifdef ethernet_exists
+	else
+	{
+		int result;
+		char c1;
+
+		checksum = 0;
+		c = '$';
+		for (i=0; i<size; i++)
+		{
+			checksum += aBuffer[i];
+			c1 = aBuffer[i];
+			aBuffer[i] = c;
+			c = c1;
+		}
+		aBuffer[i++] = c;
+
+		aBuffer[i++] = '#';
+		aBuffer[i++] = dHexChars[(checksum >> 4) & 15];
+		aBuffer[i++] = dHexChars[checksum & 15];
+		aBuffer[i++] = 0;
+ethResend:
+		if (gdb.host_ip_address != 0)
+		{
+			result = nr_plugs_send_to (gdb.gdb_eth_plug, aBuffer, i, 0,
+				gdb.host_ip_address,
+				gdb.host_port_number);
+		}
+		if (!GDBGetACK ())
+		{
+			if (++cnt < GDB_RETRY_CNT) goto ethResend;
+		}
+		aBuffer[0]=0;
+	}
+#endif
+#endif
+	if (cnt < GDB_RETRY_CNT) return 1;
+	else return 0;
+}
+
+void PutGDBOKPacket(char *aBuffer)
+	{
+	aBuffer[0] = 'O';
+	aBuffer[1] = 'K';
+	aBuffer[2] = 0;
+	PutGDBPacket(aBuffer);
+	}
+
+#if nasys_debug_core
+
+//some defines used exclusively for TRACE data xfer
+//stepsize is the ascii hex step value i.e. twice the binary length
+#define stepsize (2*(2*sizeof(int) + sizeof (char)))
+#define MAX_TRACE_BYTES	(((int)((2*MAX_DATA_SIZE-2)/stepsize))*stepsize)
+
+int Trace_Read_Intercept (char *aBuffer)
+{
+	int cnt=0;
+	unsigned int data;
+	unsigned char code;
+	int byteCount;
+	unsigned char *w;
+	unsigned short dataAccumulate;
+	int status;
+
+	w = aBuffer;
+	w++;	//skip past the m
+	if (*w++ == 't')  //see if this is a special "memory trace" packet
+	{
+		w = Hex2Value(w,&byteCount); //get the number of bytes to transfer
+
+		//turn byteCount to a multiple of stepsize
+		byteCount = ((int)(byteCount/stepsize))*stepsize;
+
+		//wait until fifo empties
+		nm_debug_get_reg(status, np_debug_write_status);
+		while (status&np_debug_write_status_writing_mask) nm_debug_get_reg(status,np_debug_write_status);
+
+		// loop through total size
+		while (byteCount > 0)
+		{
+			w=aBuffer;	//reset w to beginning of buffer
+
+			//calculate the number of bytes in this packet
+			if (byteCount > MAX_TRACE_BYTES) dataAccumulate = MAX_TRACE_BYTES;
+			else dataAccumulate = byteCount;
+
+			//insert data size at beginning of packet
+			w = MemToHex((char *)&dataAccumulate, w, sizeof (dataAccumulate));
+
+			byteCount -= dataAccumulate; //decrement byteCount
+
+			// accumulate a full buffer
+			for (cnt=0; cnt<dataAccumulate; cnt+=stepsize)
+			{
+				int valid;
+				nm_debug_set_reg (1, np_debug_read_sample); //begin transaction
+
+				//wait until data is ready
+				nm_debug_get_reg (valid, np_debug_data_valid);
+				while (!valid) nm_debug_get_reg(valid,np_debug_data_valid) ;
+
+				nm_debug_get_reg (data, np_debug_trace_address);
+				w = MemToHex ((char *)&data, w, sizeof (int));
+
+				nm_debug_get_reg (data, np_debug_trace_data);
+				w = MemToHex ((char *)&data, w, sizeof (int));
+
+				nm_debug_get_reg (data, np_debug_trace_code);
+				w = MemToHex ((char *)&data, w, sizeof (char));
+			}
+
+			//if one of our data packets doesn't make it, stop sending them
+			//if (PutTracePacket (aBuffer,dataAccumulate+4) != 1) //+4 for size filed
+			//	byteCount = 0;
+			/* kenw - My module can't handle the incoming data fast enough.  So
+			 * send this one packet, and wait for another mt command.
+			 */
+			PutTracePacket (aBuffer,dataAccumulate+4);
+			byteCount = 0;
+		}
+		return 1;
+	}
+	return 0;
+}
+
+/*
+#undef stepsize
+#undef MAX_TRACE_BYTES
+*/
+
+#endif
+
+void DoGDBCommand_m(char *aBuffer)
+	{
+	char *w;
+	int startAddr,byteCount;
+
+#if nasys_debug_core
+	/* intercept some access to the dbg peripheral */
+	if (Trace_Read_Intercept (aBuffer)) return;
+#endif
+
+	w = aBuffer;
+	w++;				// past 'm'
+	w = Hex2Value(w,&startAddr);
+	w++;				// past ','
+	w = Hex2Value(w,&byteCount);
+
+	if (byteCount > MAX_DATA_SIZE) byteCount = MAX_DATA_SIZE;
+
+	// mA,L -- request memory
+	w = aBuffer;
+	w = MemToHex((char *)startAddr,w,byteCount);
+	PutGDBPacket(aBuffer);
+	}
+
+void DoGDBCommand_M(char *aBuffer)
+	{
+	char *w;
+	int startAddr,byteCount;
+
+	w = aBuffer;
+	w++;				// past 'M'
+	w = Hex2Value(w,&startAddr);
+	w++;				// past ','
+	w = Hex2Value(w,&byteCount);
+	w++;				// past ':'
+
+	GDB_Print2("M from %x to %x",startAddr,byteCount);
+
+	// MA,L:values -- write to memory
+
+	w = HexToMem(w,(char *)startAddr,byteCount);
+
+	// Send "OK"
+	PutGDBOKPacket(aBuffer);
+	}
+
+int Debug_Read_Intercept (char *aBuffer)
+{
+	int cnt=0;
+	unsigned int data;
+	int index;
+	unsigned char *w;
+
+	w = aBuffer;
+	w++;	//skip past the g
+	if (*w++ == 'g')  //see if this is a special "register read" packet
+	{
+	    w = Hex2Value(w,&index); //get the index of the register to be read
+
+	    nm_debug_get_reg (data, index);
+
+	    //assemble the output packet
+	    w=aBuffer;	//reset w to beginning of buffer
+	    w = MemToHex((char *)&data, w, sizeof (data));
+	    *w++ = 0;
+
+	    //now send it
+	    PutTracePacket (aBuffer,sizeof (data) * 2);
+
+	    return 1;
+	}
+	return 0;
+}
+
+// Return the values of all the registers
+void DoGDBCommand_g(NiosGDBGlobals *g)
+	{
+	char *w;
+
+	if (Debug_Read_Intercept (g->textBuffer)) return;
+
+	w = g->textBuffer;
+
+	w = MemToHex((char *)(&g->registers),w,sizeof(g->registers));
+	PutGDBPacket(g->textBuffer);
+	GDB_Print2("Sent            Registers",0,0);
+	}
+
+int Debug_Write_Intercept (char *aBuffer)
+{
+	int cnt=0;
+	unsigned int data;
+	unsigned char code;
+	int index;
+	unsigned char *w;
+	unsigned short dataAccumulate;
+	int status;
+
+	w = aBuffer;
+	w++;	//skip past the g
+	if (*w++ == 'g')  //see if this is a special "register read" packet
+	{
+	    w = Hex2Value(w,&index); //get the index of the register to be written
+	    w++;				// past ','
+	    w = Hex2Value(w,&data);
+
+	    nm_debug_set_reg (data, index);
+
+	    //now send it
+	    // Send "OK"
+	    PutGDBOKPacket(aBuffer);
+
+	    return 1;
+	}
+	return 0;
+}
+
+void DoGDBCommand_G(NiosGDBGlobals *g)
+	{
+	char *w;
+
+	if (Debug_Write_Intercept (g->textBuffer)) return;
+
+	w = g->textBuffer;
+	w++;	// skip past 'G'
+	w = HexToMem(w,(char *)(&g->registers), sizeof(g->registers) );
+
+	// Send "OK"
+	PutGDBOKPacket(g->textBuffer);
+
+	GDB_Print2("Received        Registers",0,0);
+	}
+
+// Return last signal value
+void DoGDBCommand_qm(NiosGDBGlobals *g)
+	{
+	char *w;
+
+	w = g->textBuffer;
+
+	*w++ = 'S';
+	*w++ = '2';
+	*w++ = '3';	// make up a signal for now...
+	*w++ = 0;
+	PutGDBPacket(g->textBuffer);
+	}
+
+void DoGDBCommand_q(NiosGDBGlobals *g)
+{
+	short int* ssram_exists;
+	char *w;
+	w = g->textBuffer;
+
+	w++;	/* skip past the q */
+	switch (*w) {
+		case ('A'):
+			w = g->textBuffer;
+
+			/* handle intialization information */
+			/* is nios_ocd available? */
+#ifdef nasys_debug_core
+			*w++ = nasys_debug_core + '0';
+#else
+			*w++ = '0';
+#endif
+			*w++ = ',';
+
+			/* determine if the SSRAM debugger board is
+			 * physically present */
+#ifdef na_ssram_detect_in
+			ssram_exists = (short int*) na_ssram_detect_in;
+			*w++ = !(*ssram_exists) + '0';
+#else
+			*w++ = '0';
+#endif
+			*w++ = ',';
+
+			/* print out the max size of a trace packet */
+#if nasys_debug_core
+			sprintf (w, "%04x", MAX_TRACE_BYTES);
+#else
+			sprintf (w, "0000");
+#endif
+
+			break;
+		case ('B'):
+			w = g->textBuffer;
+
+			/* returns 1 if it was an OCD interrupt
+			 * returns 0 if it was software breakpoint */
+			if (gdb.trapNumber == nasys_debug_core_irq) {
+				*w++ = '1';
+			} else {
+				*w++ = '0';
+			}
+
+			*w++ = 0;
+			break;
+		default:
+			w = g->textBuffer;
+
+			*w = 0;
+			break;
+	}
+
+	PutGDBPacket(g->textBuffer);
+}
+
+
+void GDBInsertBreakpoint(NiosGDBGlobals *g,short *address)
+	{
+	NiosGDBBreakpoint *b;
+
+	GDB_Print2("breakpoint 0x%x",(int)address,0);
+	if(g->breakpointCount < kMaximumBreakpoints)
+		{
+		b = &g->breakpoint[g->breakpointCount++];
+		b->address = address;
+		b->oldContents = *b->address;
+		*b->address = 0x7904;
+		}
+	}
+
+void GDBRemoveBreakpoints(NiosGDBGlobals *g)
+	{
+	NiosGDBBreakpoint *b;
+	int i;
+
+	for(i = 0; i < g->breakpointCount; i++)
+		{
+		b = &g->breakpoint[i];
+		*b->address = b->oldContents;
+		b->address = 0;
+		}
+
+	g->breakpointCount = 0;
+	}
+
+int NiosInstructionIsTrap5(unsigned short instruction)
+	{
+	return instruction == 0x7905;
+	}
+
+int NiosInstructionIsPrefix(unsigned short instruction)
+	{
+	return (instruction >> 11) == 0x13;
+	}
+
+int NiosInstructionIsSkip(unsigned short instruction)
+	{
+	int op6;
+	int op11;
+
+	op6 = (instruction >> 10);
+	op11 = (instruction >> 5);
+
+	return (op6 == 0x14		// SKP0
+		|| op6 == 0x15		// SKP1
+		|| op11 == 0x3f6	// SKPRz
+		|| op11 == 0x3f7	// SKPS
+		|| op11 == 0x3fa);	// SKPRnz
+	}
+
+int NiosInstructionIsBranch(unsigned short instruction,short *pc,short **branchTargetOut)
+	{
+	int op4;
+	int op7;
+	int op10;
+	short *branchTarget = 0;
+	int result = 0;
+
+	op4 = (instruction >> 12);
+	op7 = (instruction >> 9);
+	op10 = (instruction >> 6);
+
+	if(op4 == 0x08)		// BR, BSR
+		{
+		int offset;
+
+		result = 1;
+		offset = instruction & 0x07ff;
+		if(offset & 0x400)	// sign extend
+			offset |= 0xffffF800;
+		branchTarget = pc + offset + 1;	// short * gets x2 scaling automatically
+		}
+	else if(op10 == 0x1ff)	// JMP, CALL
+		{
+		result = 1;
+		branchTarget = (short *)(gdb.registers.r[instruction & 31] * 2);
+		}
+	else if(op7 == 0x3d)	// JMPC, CALLC
+		{
+		result = 1;
+		branchTarget = pc + 1 + (instruction & 0x0ffff);
+#ifdef __nios32__
+		branchTarget = (short *)((int)branchTarget & 0xffffFFFc);	// align 32...
+#else
+		branchTarget = (short *)((int)branchTarget & 0xFFFe);		// align 16...
+#endif
+		branchTarget = (short *)(*(int *)branchTarget);
+		}
+
+	if(branchTargetOut)
+		*branchTargetOut = branchTarget;
+
+	return result;
+	}
+
+// -------------------------
+// Step at address
+//
+// "stepping" involves inserting a
+// breakpoint at some reasonable
+// spot later than the current program
+// counter
+//
+// On the Nios processor, this is
+// nontrivial. For example, we should
+// not break up a PFX instruction.
+
+void DoGDBCommand_s(NiosGDBGlobals *g)
+	{
+	char *w;
+	int x;
+	short *pc;
+	short *branchTarget;
+	unsigned short instruction;
+	int stepType;
+
+	/*
+	 * First, if there's an argument to the packet,
+	 * set the new program-counter value
+	 */
+
+	w = g->textBuffer;
+	w++;
+	if(HexCharToValue(*w) >= 0)
+		{
+		w = Hex2Value(w,&x);
+		g->registers.pc = x;
+		}
+
+	/*
+	 * Scan forward to see what the
+	 * most appropriate location(s) for
+	 * a breakpoint will be.
+	 *
+	 * The rules are:
+	 *  1. If *pc == PFX, break after modified instruction.
+	 *  2. If *pc == BR,BSR,JMP,CALL, break at destination
+	 *  3. If *pc == SKIP, break right after SKIP AND after optional instruction,
+	                 which might, of course, be prefixed.
+	 *  4. Anything else, just drop in the breakpoint.
+	 */
+
+	pc = (short *)(int)g->registers.pc;
+
+	instruction = *pc;
+	stepType = 0;
+
+	if(NiosInstructionIsPrefix(instruction))
+		{
+		/*
+		 * PFX instruction: skip til after it
+		 */
+		while(NiosInstructionIsPrefix(instruction))
+			{
+			pc++;
+			instruction = *pc;
+			}
+
+		GDBInsertBreakpoint(g,pc + 1);
+		stepType = 1;
+		}
+	else if(NiosInstructionIsBranch(instruction,pc,&branchTarget))
+		{
+		GDBInsertBreakpoint(g,branchTarget);
+		stepType = 2;
+		}
+	else if(NiosInstructionIsSkip(instruction))
+		{
+		short *pc2;
+		stepType = 3;
+
+		/*
+		 * Skip gets to breaks: one after the skippable instruction,
+		 * and the skippable instruction itself.
+		 *
+		 * Since Skips know how to skip over PFX's, we have to, too.
+		 */
+		pc2 = pc;	// the Skip instruction
+		do
+			{
+			pc2++;
+			} while(NiosInstructionIsPrefix(*pc2));
+		// pc2 now points to first non-PFX after Skip
+		GDBInsertBreakpoint(g,pc2+1);
+		GDBInsertBreakpoint(g,pc+1);
+		}
+	else
+		GDBInsertBreakpoint(g,pc+1);		// the genericest case
+
+	GDB_Print2("Program Steppingat 0x%x (%d)",g->registers.pc,stepType);
+	}
+
+// -----------------------------
+// Continue at address
+
+void DoGDBCommand_c(NiosGDBGlobals *g)
+	{
+	char *w;
+	int x;
+	w = g->textBuffer;
+
+	w++;		// past command
+
+	// Anything in the packet? if so,
+	// use it to set the PC value
+
+	if(HexCharToValue(*w) >= 0)
+		{
+		w = Hex2Value(w,&x);
+		g->registers.pc = x;
+		}
+
+	GDB_Print2("Program Running at 0x%x",g->registers.pc,0);
+	}
+
+// ----------------------
+// Kill
+
+void DoGDBCommand_k(NiosGDBGlobals *g)
+	{
+	return;
+	}
+
+
+/*
+ * If we've somehow skidded
+ * to a stop just after a PFX instruction
+ * back up the program counter by one.
+ *
+ * That way, we can't end up with an accidentally-unprefixed
+ * instruction.
+ *
+ * We do this just before we begin running
+ * again, so that when the host queries our
+ * registers, we report the place we actually
+ * stopped.
+ */
+
+void MaybeAdjustProgramCounter(NiosGDBGlobals *g)
+	{
+	short instruction;
+	if(g->registers.pc)
+		{
+		instruction = *(short *)(int)(g->registers.pc - 2);
+		if(NiosInstructionIsPrefix(instruction))
+			g->registers.pc -= 2;
+		else
+			{
+			// If the *current* instruction is Trap5, we must skip it!
+			instruction = *(short *)(int)(g->registers.pc);
+			if(NiosInstructionIsTrap5(instruction))
+				g->registers.pc += 2;
+			}
+		}
+	}
+
+/*
+ * GDBMainLoop - this is the main processing loop
+ * for the GDB stub.
+ */
+void GDBMainLoop ()
+{
+	while(1)
+	{
+		if (GetGDBPacket(gdb.textBuffer) > 0)
+		{
+
+			GDB_Print2(gdb.textBuffer,0,0);
+			switch(gdb.textBuffer[0])
+			{
+			case 's':
+				DoGDBCommand_s(&gdb);
+				goto startRunning;
+				break;
+
+			case 'c':	// continue
+				DoGDBCommand_c(&gdb);
+
+				// if the PC is something other than 0, it's
+				// probably ok to exit and go there
+
+			startRunning:
+				if(gdb.registers.pc)
+				{
+					MaybeAdjustProgramCounter(&gdb);
+					return;
+				}
+				break;
+
+			case 'm':	// memory read
+				DoGDBCommand_m(gdb.textBuffer);
+				break;
+
+			case 'M':	// memory set
+				DoGDBCommand_M(gdb.textBuffer);
+				break;
+
+			case 'g':	// registers read
+				DoGDBCommand_g(&gdb);
+				break;
+
+			case 'G':	//registers set
+				DoGDBCommand_G(&gdb);
+				break;
+
+			case 'k':	//kill process
+				DoGDBCommand_k(&gdb);
+				break;
+
+			case '?':	// last exception value
+				DoGDBCommand_qm(&gdb);
+				break;
+
+			case 'q':
+				DoGDBCommand_q(&gdb);
+				break;
+
+			default:	// return empty packet, means "yeah yeah".
+				gdb.textBuffer[0] = 0;
+				PutGDBPacket(gdb.textBuffer);
+			break;
+			}
+		}
+	}
+
+}
+
+// ----------main------------
+void GDBMain(void)
+{
+	char c;
+	int i;
+
+	for(i = 0; i < kTextBufferSize; i++)
+		gdb.textBuffer[i] = i;
+
+	GDBRemoveBreakpoints(&gdb);
+
+#ifdef __KERNEL__
+/*
+ * Inform the user that they need to add the symbol file for the application
+ * that is just starting up.  Display the  .text  .data  .bss  regions.
+ */
+	if (gdb.trapNumber == 5) {
+		extern struct task_struct *_current_task;
+		sprintf(gdb.textBuffer,
+				"\r\n\nGDB: trap 5 at 0x%08lX", gdb.registers.pc);
+		puts(gdb.textBuffer);
+		if (_current_task) {
+			if ( _current_task->mm->start_code > _etext )
+				sprintf(gdb.textBuffer,
+					"\r\nGDB: Enter the following command in the nios-elf-gdb Console Window:"
+					"\r\nGDB:    add-symbol-file %s.abself 0x%08lX 0x%08lX 0x%08lX\r\n\n",
+					_current_task->comm,
+					(unsigned long)_current_task->mm->start_code,
+					(unsigned long)_current_task->mm->start_data,
+					(unsigned long)_current_task->mm->end_data );
+			else
+				sprintf(gdb.textBuffer,
+					", kernel process: %s\r\n", _current_task->comm );
+		} else
+			sprintf(gdb.textBuffer,
+				", kernel process unknown\r\n" );
+		puts(gdb.textBuffer);
+	}
+#endif
+
+	// Send trapnumber for breakpoint encountered. No other signals.
+
+	gdb.textBuffer[0] = 'S';
+	gdb.textBuffer[1] = '0';
+
+#if nasys_debug_core
+	if (gdb.trapNumber == nasys_debug_core_irq)
+	{
+	    /* gdb.textBuffer[2] = '8'; */
+	    gdb.textBuffer[2] = '5';
+	}
+	else
+	{
+	    gdb.textBuffer[2] = '5';
+	}
+#else
+	gdb.textBuffer[2] = '5';
+#endif
+	gdb.textBuffer[3] = 0;
+	PutGDBPacket(gdb.textBuffer);
+
+	GDB_Print2("Trap %2d         At 0x%x",
+		gdb.trapNumber,gdb.registers.pc);
+//	printf ("Trap %d at 0x%x\n",gdb.trapNumber,gdb.registers.pc);
+//	for (i=0;i<32;i++) printf ("	register[%d] = 0x%x\n",i,gdb.registers.r[i]);
+
+	GDBMainLoop (GDB_WHOLE_PACKET);
+}
+
+// +----------------------------------
+// | gdb_eth_proc -- gets called for udp packets
+// | from the host bound for gdb stub
+#ifdef ETHER_DEBUG
+#ifdef ethernet_exists
+int gdb_eth_proc(int plug_handle,
+		void *context,
+		ns_plugs_packet *p,
+		void *payload,
+		int payload_length)
+{
+	int i;
+	char *buf = (char *)payload;
+	// if this is a stop request, set a flag to stop after nr_plugs_idle
+	// leave it up to the host to prevent stops from being sent while stub is running???
+
+	if (*buf == 3) gdb.stop = 1;
+
+	// if we're waiting for an ack, check that here
+	if (gdb.ACKstatus == ne_gdb_ack_waiting)
+	{
+		if (buf[0] == '+')
+		{
+			gdb.ACKstatus = ne_gdb_ack_acked;
+			return 0;
+		}
+		else if (buf[0] == '-')
+		{
+			gdb.ACKstatus = ne_gdb_ack_nacked;
+			return 0;
+		}
+	}
+	strcpy (gdb.textBuffer, buf);	//all commands should be zero terminated strings
+
+	gdb.textBuffer[payload_length] = 0;	//terminate string
+
+	gdb.host_ip_address=((ns_plugs_ip_packet *)(p[ne_plugs_ip].header))->source_ip_address;
+	gdb.host_port_number=((ns_plugs_udp_packet *)(p[ne_plugs_udp].header))->source_port;
+
+	return 0;
+}
+
+int nr_dbg_plugs_idle (void)
+{
+	int result;
+
+	result = nr_plugs_idle ();
+	if (gdb.stop)
+	{
+		gdb.stop = 0;
+		asm ("TRAP #5");
+	}
+	return result;
+}
+#endif
+#endif
+
+
+/*
+ * int main(void)
+ *
+ * All we really do here is install our trap # 3,
+ * and call it once, so that we're living down in
+ * the GDBMain, trap handler.
+ */
+
+extern int StubBreakpointHandler;
+extern int StubHarmlessHandler;
+#if nasys_debug_core
+extern int StubHWBreakpointHandler;
+#endif
+#ifdef nasys_debug_uart
+extern int StubUartHandler;
+#endif
+
+void gdb_local_install(int active)
+{
+	unsigned int *vectorTable;
+	unsigned int stubBreakpointHandler;
+	unsigned int stubHarmlessHandler;
+	unsigned int stubHWBreakpointHandler;
+
+	gdb.breakpointCount = 0;
+	gdb.textBuffer[0] = 0;
+
+	vectorTable = (int *)nasys_vector_table;
+	stubBreakpointHandler = ( (unsigned int)(&StubBreakpointHandler) ) >> 1;
+	stubHarmlessHandler = ( (unsigned int)(&StubHarmlessHandler) ) >> 1;
+#if nasys_debug_core
+	stubHWBreakpointHandler = ( (unsigned int)(&StubHWBreakpointHandler) ) >> 1;
+#endif
+
+	/*
+	 * Breakpoint & single step both go here
+	 */
+	vectorTable[na_BreakpointTrap] = stubBreakpointHandler;
+	vectorTable[na_SingleStepTrap] = stubBreakpointHandler;
+	vectorTable[na_StartGDBTrap] = active ? stubBreakpointHandler : stubHarmlessHandler;
+	/*
+	 * If it exists, Hardware Breakpoint has a different entry point
+	 */
+#if nasys_debug_core
+	vectorTable[na_debug_peripheral_irq] = stubHWBreakpointHandler;
+#endif
+
+#ifndef __KERNEL__
+#ifdef nasys_debug_uart
+	if (gdb.comlink == ne_gdb_serial)
+	{
+		np_uart *uart = (np_uart *)nasys_debug_uart;
+		unsigned int stubUartHandler = ((unsigned int)(&StubUartHandler)) >> 1;
+
+		vectorTable[nasys_debug_uart_irq] = stubUartHandler;	  //set Uart int vector
+		uart->np_uartcontrol = np_uartcontrol_irrdy_mask; //enable Rx intr
+	}
+#endif
+#endif
+}
+
+void nios_gdb_install(int active)
+{
+	gdb.comlink = ne_gdb_serial;
+	gdb_local_install (active);
+}
+
+#ifdef ETHER_DEBUG
+#ifdef ethernet_exists
+void nios_gdb_install_ethernet (int active)
+{
+	int result;
+	host_16	host_port = GDB_ETH_PORT;
+
+	gdb.comlink = ne_gdb_ethernet;
+	gdb_local_install (active);
+
+	result = nr_plugs_create (&gdb.gdb_eth_plug, ne_plugs_udp, host_port, gdb_eth_proc, 0, 0);
+	//if unabled to open ethernet plug, switch back to default serial interface
+	if (result)
+	{
+		printf ("nr_plugs_create failed %d\n",result);
+		gdb.comlink = ne_gdb_serial;
+		return;
+	}
+	result = nr_plugs_connect (gdb.gdb_eth_plug, 0, -1, -1);
+	if (result)
+	{
+		printf ("nr_plugs_connect fialed %d\n",result);
+		gdb.comlink = ne_gdb_serial;
+		return;
+	}
+}
+#endif
+#endif
+
+#ifdef nios_gdb_breakpoint
+	#undef nios_gdb_breakpoint
+#endif
+
+void nios_gdb_breakpoint(void)
+	{
+	/*
+	 * If you arrived here, you didn't include
+	 * the file "nios_peripherals.h", which
+	 * defines nios_gdb_breakpoint as a
+	 * macro that expands to TRAP 5.
+	 *
+	 * (No problem, you can step out
+	 * of this routine.)
+	 */
+	asm("TRAP 5");
+	}
+
+// end of file
diff -urN linux-2.4.29/arch/niosnommu/kernel/nios_gdb_stub.h linux-2.4.29-uc1/arch/niosnommu/kernel/nios_gdb_stub.h
--- linux-2.4.29/arch/niosnommu/kernel/nios_gdb_stub.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/nios_gdb_stub.h	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,105 @@
+// file: nios_gdb_stub.h
+// Author: Altera Santa Cruz \ 2000
+//
+// You can modify this header file to
+// enable some features useful for
+// debugging the debugger. They're
+// good features also to just show
+// signs of life on your Nios board.
+// But they consume valuable peripherals!
+//
+// The 'GDB_DEBUG_PRINT' option ties
+// up the LCD living on the 5v port,
+// showing useful internals of the stub.
+//
+// dvb@altera.com
+//
+
+#ifdef ETHER_DEBUG
+#ifdef na_enet
+#define ethernet_exists
+#endif
+#endif
+
+#ifdef ETHER_DEBUG
+#ifdef ethernet_exists
+#include "plugs.h"
+#endif
+#endif
+
+#define MAX_DATA_SIZE		650
+#define kTextBufferSize		((2*MAX_DATA_SIZE)+4)
+#define kMaximumBreakpoints	4
+#define GDB_ETH_PORT		7070
+#define	GDB_WHOLE_PACKET	0
+#define	GDB_SKIP_FIRST		1
+#define GDB_RETRY_CNT		3
+
+/*
+ * This register structure must match
+ * its counterpart in the GDB host, since
+ * it is blasted across in byte notation.
+ */
+typedef struct
+	{
+	int r[32];
+	long pc;
+	short ctl0;
+	short ctl1;
+	short ctl2;
+	short ctl3;
+	} NiosGDBRegisters;
+
+typedef struct
+	{
+	short *address;
+	short oldContents;
+	} NiosGDBBreakpoint;
+
+typedef struct
+	{
+	NiosGDBRegisters registers;
+	int trapNumber;				// stashed by ISR, to distinguish types
+	char textBuffer[kTextBufferSize];
+	int breakpointCount;			// breakpoints used for stepping
+	int comlink;
+	int stop;
+	int gdb_eth_plug;
+	NiosGDBBreakpoint breakpoint[kMaximumBreakpoints];
+#ifdef ETHER_DEBUG
+#ifdef ethernet_exists
+	volatile int ACKstatus;
+	net_32 host_ip_address;
+	net_16 host_port_number;
+#endif
+#endif
+	} NiosGDBGlobals;
+
+#ifdef ETHER_DEBUG
+#ifdef ethernet_exists
+enum
+{
+	ne_gdb_ack_notwaiting,
+	ne_gdb_ack_waiting,
+	ne_gdb_ack_acked,
+	ne_gdb_ack_nacked
+};
+#endif
+#endif
+
+enum 
+{
+	ne_gdb_serial,
+	ne_gdb_ethernet
+};
+
+#ifndef GDB_DEBUG_PRINT
+	#define GDB_DEBUG_PRINT 0
+#endif
+
+void GDB_Main(void);	// initialize gdb and begin.
+
+char GDBGetChar(void);
+void GDBPutChar(char c);
+void GDB_Print2(char *s,int v1,int v2);
+
diff -urN linux-2.4.29/arch/niosnommu/kernel/nios_gdb_stub_io.c linux-2.4.29-uc1/arch/niosnommu/kernel/nios_gdb_stub_io.c
--- linux-2.4.29/arch/niosnommu/kernel/nios_gdb_stub_io.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/nios_gdb_stub_io.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,39 @@
+// Modified for uClinux - Vic - Apr 2002
+// From:
+
+// file: nios_gdb_stub_IO.c
+//
+// Single character I/O for Nios GDB Stub
+
+#ifndef __KERNEL__
+#include "nios.h"
+#else
+#include <asm/nios.h>
+#endif
+
+#include "nios_gdb_stub.h"
+
+#ifdef nasys_debug_uart
+	#define GDB_UART nasys_debug_uart
+#endif
+
+char GDBGetChar(void)
+{
+	char c = 0;
+
+#ifdef GDB_UART
+	while( (c = (char)nr_uart_rxchar(GDB_UART)) < 0 )
+			;
+#endif
+
+	return c;
+}
+
+void GDBPutChar(char c)
+{
+#ifdef GDB_UART
+	nr_uart_txchar(c, GDB_UART);
+#endif
+}
+
+// End of file
diff -urN linux-2.4.29/arch/niosnommu/kernel/nios_gdb_stub_isr.S linux-2.4.29-uc1/arch/niosnommu/kernel/nios_gdb_stub_isr.S
--- linux-2.4.29/arch/niosnommu/kernel/nios_gdb_stub_isr.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/nios_gdb_stub_isr.S	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,573 @@
+; Modified for uClinux - Vic - Apr 2002
+; From: 
+   
+;
+; Assembly language portions of Nios GDB Stub
+;
+; Stack set up, register clearing, all kinds of
+; clever things.
+;
+
+#ifndef __KERNEL__
+	.include "nios.s"
+#else
+	#include <asm/niosasm.h>
+#endif
+
+.ifdef ETHER_DEBUG
+.ifdef na_enet
+	.equ	ethernet_exists, 1
+.endif
+.endif
+
+; Manual additions .. - AF 9/4/2000
+; Eventually these items will be in the SDK.
+
+  GEQU na_BreakpointTrap     , 3
+  GEQU na_SingleStepTrap     , 4
+
+
+; End of manual additions.
+	;
+	; Word size (32-bit) offsets
+	; for register storage
+	;
+
+	.equ	gdbRegistersGeneral,0
+	.equ	gdbRegistersPC,32
+.if __nios32__
+	.equ	gdbRegistersCtl0Ctl1,33
+	.equ	gdbRegistersCtl2Ctl3,34
+	.equ	gdbTrapNumber,35		; ISR can report trap number here
+.else
+	.equ	gdbRegistersCtl0,34
+	.equ	gdbRegistersCtl1,35
+	.equ	gdbRegistersCtl2,36
+	.equ	gdbRegistersCtl3,37
+	.equ	gdbTrapNumber,38
+.endif
+
+
+	.text
+
+	.global	StubBreakpointHandler
+	.global	StubHarmlessHandler
+	.global	StubButtonHandler
+	.global StubHWBreakpointHandler
+	.global	GDBMain
+
+.ifdef ETHER_DEBUG
+.ifdef ethernet_exists
+	.comm	_gdb_stub_stack,8192,4	; Local stack, statically allocated.
+	.equ	gdbStubStacktop,_gdb_stub_stack+7936
+.else
+	.comm	_gdb_stub_stack,1024,4	; Local stack, statically allocated.
+	.equ	gdbStubStacktop,_gdb_stub_stack+992
+.endif
+.else
+	.comm	_gdb_stub_stack,1024,4	; Local stack, statically allocated.
+	.equ	gdbStubStacktop,_gdb_stub_stack+992
+.endif
+
+
+
+;
+; If nios_gdb_install(0) is invoked, the stub is present,
+; and linked in, but harmless. This, so that you can "turn off"
+; the debugger with minimal change in your code footprint.
+;
+; This is the harmless breakpoint handler.
+
+StubHarmlessHandler:
+	TRET	%o7		; pretty darned minimal. Better stuff below.
+
+; StubUart Handler checks to see if we are getting a stop requrest from the
+; host.  If we are it jumps directly to the breakpoint stub. Otherwise
+; it returns after clearing the interrupt
+
+.ifdef nasys_debug_uart
+	.equ	gdbBreakChar,0x3
+	.global	StubUartHandler
+
+StubUartHandler:
+	;verify Rx interrupt
+	MOVIA	%l0, nasys_debug_uart
+	LDP		%l1, [%l0,np_uartcontrol]
+	SKP0	%l1, np_uartcontrol_irrdy_bit
+	BR		StubUartRx
+	NOP
+	TRET	%o7
+
+StubUartRx:
+	LDP		%l1, [%l0,np_uartrxdata]	;clears interrupt bit
+	CMPI	%l1, gdbBreakChar
+	SKPS	cc_nz
+	BR		StubBreakpointHandler
+	NOP
+	TRET	%o7
+.endif
+
+;
+; The Hardware Breakpoint needs to do a few additional thing
+; before it enters the regular breakpoint handler
+
+.if nasys_debug_core
+StubHWBreakpointHandler:
+	; write to stop register to halt trace
+	MOVI	%l1, 9		;np_debug_stop register
+	PFX	3
+	WRCTL	%l1
+	PFX	4
+	WRCTL	%l1
+	; now PASS THROUGH to the normal breakpoint handler
+	; NO BRANCH HERE
+	; DON'T INSERT CODE BELOW
+
+.endif
+
+
+;
+; When we get here, in response to
+; a breakpoint (trap 3 poked into code),
+; we need to save the state of all the registers,
+; every last one! So we can restore them, you see,
+; and then set up to call the debugger. Major
+; context switching here! Neat, eh?
+;
+; We arrive here with CWP down 1 from
+; its authentic state (fortunately!)
+;
+; the %l's and %o's are all ours
+; down here. again, fortunately.
+;
+; We save the current interruptee's
+; registers into the register structure
+; that the C portion uses.
+;
+; Then, after popping CWP up one level,
+; we reenable interrupts, and jump
+; to the debugger's main.
+;
+; With interrupts enabled, the CWP manager will
+; operate normally; if an underflow occurs, registers
+; from the debugged program will get stored in
+; their own local stack frame, since their own %sp's
+; are used for the task. The debugger's will
+; go in its own frame.
+;
+
+StubBreakpointHandler:
+
+.if nasys_debug_core
+	; if there is a deubbing peripheral,
+	; me must stop it on interrupt
+	; write to stop register to halt trace
+	MOVI	%l1, 9		;np_debug_stop register
+	PFX	3
+	WRCTL	%l1
+	PFX	4
+	WRCTL	%l1
+.endif
+	;
+	; Save the globals first.
+	; Then, when we up the CWP, they're
+	; ours to play with a bit.
+	;
+
+	MOVIA	%l0,gdb		; g is the C side's globals. starts with registers.
+	STP	[%l0,0],%g0
+	STP	[%l0,1],%g1
+	STP	[%l0,2],%g2
+	STP	[%l0,3],%g3
+	STP	[%l0,4],%g4
+	STP	[%l0,5],%g5
+	STP	[%l0,6],%g6
+	STP	[%l0,7],%g7
+
+	;
+	; Save the %o registers, which
+	; appear to us, down here, as
+	; %i registers
+	;
+	STP	[%l0,8],%i0
+	STP	[%l0,9],%i1
+	STP	[%l0,10],%i2
+	STP	[%l0,11],%i3
+	STP	[%l0,12],%i4
+	STP	[%l0,13],%i5
+	STP	[%l0,14],%i6
+	STP	[%l0,15],%i7
+
+	;
+	; Read the trap number from CTL0, store in struct
+	;
+	RDCTL	%g4
+	LSRI	%g4,9
+	ANDIP	%g4,0x3f
+	PFX	gdbTrapNumber
+	ST	[%l0],%g4
+
+	;
+	; Read and pack the control
+	; registers. Annoyingly, they
+	; are shorts.
+	;
+	; But we never *really* know
+	; what was in CTL1. In fact,
+	; we're going to report CTL1
+	; as zero, and read CTL1 and
+	; use it for the returned value
+	; of CTL0, since thats what it was.
+	; Clear? Good!
+
+	PFX	1
+	RDCTL	%g0			; will pretend to be ctl0 (low) and ctl 1(zeroes) high
+.if __nios32__
+	PFX	gdbRegistersCtl0Ctl1
+	ST	[%l0],%g0
+.else
+	PFX	gdbRegistersCtl0
+	ST	[%l0],%g0
+	PFX	gdbRegistersCtl1
+	ST	[%l0],%g0
+.endif
+
+	;
+	; Silly to save these two, they're fixed, but they're
+	; in the vars, so ok.
+	;
+
+	PFX	2
+	RDCTL	%g1
+.if __nios32__
+	PFX 3
+	RDCTL	%g0
+	LSLI	%g0, 16
+	OR		%g0, %g1
+	PFX gdbRegistersCtl2Ctl3
+.else
+	PFX gdbRegistersCtl2
+	ST	[%l0],%g1
+	PFX 3
+	RDCTL	%g0
+	PFX gdbRegistersCtl3
+.endif
+	ST	[%l0],%g0
+
+	;
+	; Save the %pc register, which
+	; is now in %o7 cut in half
+	;
+
+	LSLI	%o7,1
+	CMPI	%g4,na_SingleStepTrap	; %g4 = trap number we got, now
+	IFS	cc_le
+	 SUBI	%o7,2		; back it up one, to before the breakpoint, if breakpoint or step
+
+	PFX	gdbRegistersPC
+	ST	[%l0],%o7
+
+	;
+	; Ascend the CWP, and grab
+	; the last %l's and %i's
+	;
+
+	MOV	%g0,%l0
+	RESTORE
+	PFX	16		; save %l0 first, so we can use it for the rest
+	ST	[%g0],%l0
+
+	MOV	%l0,%g0
+	STP	[%l0,17],%l1
+	STP	[%l0,18],%l2
+	STP	[%l0,19],%l3
+	STP	[%l0,20],%l4
+	STP	[%l0,21],%l5
+	STP	[%l0,22],%l6
+	STP	[%l0,23],%l7
+
+	STP	[%l0,24],%i0
+	STP	[%l0,25],%i1
+	STP	[%l0,26],%i2
+	STP	[%l0,27],%i3
+	STP	[%l0,28],%i4
+	STP	[%l0,29],%i5
+	STP	[%l0,30],%i6
+	STP	[%l0,31],%i7
+
+	PFX	9
+	WRCTL	%g0			; enable traps (below 3, for cwp underflow action)
+	NOP
+
+	; JMB - Before execute GDBMain, we need to flush the register file to the stack
+	; for call trace visibility. Do this on the user stack, cuz our stack is minimal
+	; The global registers are ours, and nothing happens to them on save, so lets use them.
+
+	;First get the CWP
+	RDCTL	%g0
+	LSRI	%g0, 4
+	MOVI	%g2, 0x1f
+	AND	%g0, %g2
+
+	;Now get the LO_LIMIT
+	PFX	2
+	RDCTL	%g1
+	AND	%g1, %g2
+
+	;Now calculate how many times to save/restore
+	SUB	%g0, %g1
+	MOV	%g1, %g0
+
+GDBSaveLoop:
+	SAVE	%sp, -16
+	nop
+	SUBI	%g0, 1
+	SKPS	cc_mi
+	BR	GDBSaveLoop
+	NOP
+
+GDBRestoreLoop:
+	RESTORE
+	nop
+	SUBI	%g1, 1
+	SKPS	cc_mi
+	BR	GDBRestoreLoop
+	NOP
+
+	;
+	; Now, everything is saved.
+	; If we set ctl0 and ctl1
+	; from the gdb globals, we
+	; can restore the registers
+	; as they were, and use
+	; a TRET to bump the CWP
+	; at the same time that we
+	; jump somewheres.
+	;
+	; So what we shall like to
+	; do now is set up the
+	; local stack and stuff
+	; to call into the debugger!
+	;
+
+	MOVIA	%sp,gdbStubStacktop
+
+	;
+	; We CALL to our debugger, so
+	; that we can ensure it balances
+	; its calling sequence before
+	; returning here. Once back, we'll
+	; unwind all the trickery we've
+	; done, and TRET
+	;
+
+	MOVIA	%g0,GDBMain@h
+	CALL	%g0
+	NOP
+
+	;
+	; Zero'th order, as we say, is to disable interrupts.
+	;
+
+	PFX	8
+	WRCTL	%g0			; disable interrupts.
+
+	;
+	; We're back. We assume nothing; everything
+	; may have changed. "Everything" of course
+	; means the state of the memory, and the
+	; state of the registers in the GDB globals.
+	;
+	; We'll start by instantiating CTL0 and CTL1
+	; from those globals, bump down a level, tinker
+	; a bit more, and TRET.
+	;
+
+	MOVIA	%g0,gdb		; g is the C side's globals. starts with registers.
+
+.if __nios32__
+	PFX	gdbRegistersCtl0Ctl1
+.else
+	PFX	gdbRegistersCtl0
+.endif
+	LD	%g1,[%g0]
+
+	; CTL0 in the low 16 bits; the high 16 bits are CTL1 which we hate
+	; And yet, we'll write them into CTL1, so that the TRET
+	; puts them back for real.
+
+.if __nios32__
+	EXT16s	%g1,0	; clear the upper 16 bits
+.endif
+
+	PFX	1
+	WRCTL	%g1
+
+	;
+	; And to start, we shall set CWP to where
+	; we'll return to, and restore what we can
+	; the one we're gonna return to
+	; with interrupts carefully disabled
+	;
+
+	ANDIP	%g1,0x00007fff	; mask off TE bit
+	WRCTL	%g1
+
+	MOV	%l0,%g0		; %l0 --> C globals now, for restoring registers
+
+	; restore %i registers
+
+	LDP	%i0,[%l0,24]
+	LDP	%i1,[%l0,25]
+	LDP	%i2,[%l0,26]
+	LDP	%i3,[%l0,27]
+	LDP	%i4,[%l0,28]
+	LDP	%i5,[%l0,29]
+	LDP	%i6,[%l0,30]
+	LDP	%i7,[%l0,31]
+
+	; restore %l registers
+
+
+	LDP	%l7,[%l0,23]
+	LDP	%l6,[%l0,22]
+	LDP	%l5,[%l0,21]
+	LDP	%l4,[%l0,20]
+	LDP	%l3,[%l0,19]
+	LDP	%l2,[%l0,18]
+	LDP	%l1,[%l0,17]
+	LDP	%l0,[%l0,16]	; %l0 kills itself!
+
+	;
+	; Bump CWP down 1, so we have some %l to play with
+	;
+
+	SAVE	%sp,0
+	MOV	%l0,%g0
+
+	; Restore %o's (visible from down here as %i's)
+
+	LDP	%i0,[%l0,8]
+	LDP	%i1,[%l0,9]
+	LDP	%i2,[%l0,10]
+	LDP	%i3,[%l0,11]
+	LDP	%i4,[%l0,12]
+	LDP	%i5,[%l0,13]
+	LDP	%i6,[%l0,14]
+	LDP	%i7,[%l0,15]
+
+	; restore %g's
+
+	LDP	%g0,[%l0,0]
+	LDP	%g1,[%l0,1]
+	LDP	%g2,[%l0,2]
+	LDP	%g3,[%l0,3]
+	LDP	%g4,[%l0,4]
+	LDP	%g5,[%l0,5]
+	LDP	%g6,[%l0,6]
+	LDP	%g7,[%l0,7]
+
+	;
+	; Set up local %o7, from PC, for TRET
+	; (Could use any register, but
+	; %o7 is ours, and it's traditional.)
+	;
+
+	PFX	gdbRegistersPC
+	LD	%o7,[%l0]
+	LSRI	%o7,1
+
+.if nasys_debug_core
+	; if there is a deubbing peripheral,
+	; me must start it before returning
+	; write to stop register to halt trace
+	MOVI	%l1, 8		;np_debug_start register
+	PFX	3
+	WRCTL	%l1
+	PFX	4
+	WRCTL	%l1
+.endif
+
+	;
+	;
+	; I'm so glad we had this time together,
+	; Just to have a laugh or sing a song.
+	; Seems we just get started and before you know it
+	; Comes the time we have to say, "So long."
+	;   Carol Burnett, 1967
+	;
+
+	TRET %o7		; so long!
+
+; end of file
+
+#ifdef __KERNEL__
+;----------------------------------------
+;         Name: nr_uart_rxchar
+;  Description: Read character if available
+;        Input: %o0: UART base to use
+;       Output: %o0 = character 0-0xff, or -1 if none present
+; Side Effects: %g0 & %g1 altered
+;    CWP Depth: 0
+;
+
+	.global	nr_uart_rxchar
+nr_uart_rxchar:
+
+.ifdef nasys_printf_uart
+	IFRnz	%o0		; if %o0 is zero, use "default" uart
+	BR	rxCharA
+	NOP
+	MOVIA   %o0,nasys_printf_uart
+.endif ; nasys_printf_uart
+
+rxCharA:
+
+	MOV	%g0,%o0		; %g0 -> uart
+	MOVI	%o0,1
+	NEG	%o0		; %o0 gets -1 by default
+	PFX	#2
+	LD	%g1,[%g0]	; status register
+	SKP0	%g1,7		; rx buffer empty? if no, keep the -1
+	LD	%o0,[%g0]	; something for us? read into %o0.
+
+	JMP	%o7
+	CMPI	%o0,0		; Set condition flags as per char.
+
+
+;----------------------------------------
+;         Name: nr_uart_txchar
+;  Description: Send a single byte out the UART
+;        Input: %o0 = A character
+;               %o1 = the UART to use, 0 for default
+;       Output: none
+; Side Effects: %g0 & %g1 altered, CPU waits for UART
+;    CWP Depth: 0
+;
+
+; nr_uart_txchar
+		.global	nr_uart_txchar
+nr_uart_txchar:
+
+.ifdef nasys_printf_uart
+	IFRnz	%o1
+	 BR	txCharWait
+	NOP
+	MOVIA	%o1,nasys_printf_uart
+.endif ; nasys_printf_uart
+
+txCharWait:
+	PFX	np_uartstatus			; status register for uart
+	LD	%g1,[%o1]
+	SKP1	%g1,np_uartstatus_trdy_bit	; check the ready bit
+	BR	txCharWait			; loop until empty
+	NOP
+
+	; Put character to out & return
+
+	PFX	np_uarttxdata
+	ST	[%o1],%o0	; put char into UART
+	JMP	%o7
+	NOP
+
+#endif
diff -urN linux-2.4.29/arch/niosnommu/kernel/nios_ksyms.c linux-2.4.29-uc1/arch/niosnommu/kernel/nios_ksyms.c
--- linux-2.4.29/arch/niosnommu/kernel/nios_ksyms.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/nios_ksyms.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,102 @@
+//vic - copied from v850
+
+#include <linux/module.h>
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
+
+#include <asm/setup.h>
+#include <asm/pgalloc.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/semaphore.h>
+#include <asm/checksum.h>
+#include <asm/hardirq.h>
+#include <asm/softirq.h>
+#include <asm/current.h>
+
+extern void dump_thread(struct pt_regs *, struct user *);
+extern int dump_fpu(elf_fpregset_t *);
+extern void hard_reset_now(void);
+/* platform dependent support */
+
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
+EXPORT_SYMBOL(dump_fpu);
+EXPORT_SYMBOL(dump_thread);
+EXPORT_SYMBOL(strnlen);
+EXPORT_SYMBOL(strrchr);
+EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strcat);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strcmp);
+EXPORT_SYMBOL(strncmp);
+
+EXPORT_SYMBOL(kernel_thread);
+EXPORT_SYMBOL(hard_reset_now);
+
+/* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial_copy);
+
+EXPORT_SYMBOL_NOVERS(memcpy);
+EXPORT_SYMBOL_NOVERS(memset);
+EXPORT_SYMBOL_NOVERS(memcmp);
+EXPORT_SYMBOL_NOVERS(memscan);
+EXPORT_SYMBOL_NOVERS(memmove);
+
+EXPORT_SYMBOL_NOVERS(__down_interruptible);
+EXPORT_SYMBOL_NOVERS(__down_trylock);
+EXPORT_SYMBOL_NOVERS(__up);
+
+EXPORT_SYMBOL(get_wchan);
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler...  (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __gcc_bcmp(void);
+extern void __ashldi3(void);
+extern void __ashrdi3(void);
+extern void __cmpdi2(void);
+extern void __divdi3(void);
+extern void __divsi3(void);
+extern void __lshrdi3(void);
+extern void __moddi3(void);
+extern void __modsi3(void);
+extern void __muldi3(void);
+extern void __mulsi3(void);
+extern void __negdi2(void);
+extern void __ucmpdi2(void);
+extern void __udivdi3(void);
+extern void __udivmoddi4(void);
+extern void __udivsi3(void);
+extern void __umoddi3(void);
+extern void __umodsi3(void);
+
+        /* gcc lib functions */
+EXPORT_SYMBOL_NOVERS(__gcc_bcmp);
+EXPORT_SYMBOL_NOVERS(__ashldi3);
+EXPORT_SYMBOL_NOVERS(__ashrdi3);
+EXPORT_SYMBOL_NOVERS(__cmpdi2);
+EXPORT_SYMBOL_NOVERS(__divdi3);
+EXPORT_SYMBOL_NOVERS(__divsi3);
+EXPORT_SYMBOL_NOVERS(__lshrdi3);
+EXPORT_SYMBOL_NOVERS(__moddi3);
+EXPORT_SYMBOL_NOVERS(__modsi3);
+EXPORT_SYMBOL_NOVERS(__muldi3);
+EXPORT_SYMBOL_NOVERS(__mulsi3);
+EXPORT_SYMBOL_NOVERS(__negdi2);
+EXPORT_SYMBOL_NOVERS(__ucmpdi2);
+EXPORT_SYMBOL_NOVERS(__udivdi3);
+EXPORT_SYMBOL_NOVERS(__udivmoddi4);
+EXPORT_SYMBOL_NOVERS(__udivsi3);
+EXPORT_SYMBOL_NOVERS(__umoddi3);
+EXPORT_SYMBOL_NOVERS(__umodsi3);
diff -urN linux-2.4.29/arch/niosnommu/kernel/nios_module.c linux-2.4.29-uc1/arch/niosnommu/kernel/nios_module.c
--- linux-2.4.29/arch/niosnommu/kernel/nios_module.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/nios_module.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,23 @@
+#include <linux/module.h>
+#include <asm/module.h>
+#include <asm/nios.h>
+
+unsigned long arch_init_modules(struct module *mod)
+{
+	struct module_symbol *msym;
+	unsigned int j;
+	
+	/* fix the init and cleanup routine*/
+	if (mod->init)
+		((unsigned long)mod->init)>>=1;
+	if (mod->cleanup)
+		((unsigned long)mod->cleanup)>>=1;
+
+	for (j = 0, msym = mod->syms; j < mod->nsyms; ++j, ++msym) {
+		/* no better way we can find to determine if it is a func */
+		if (msym && (msym->value < (unsigned int)nasys_program_mem))
+			msym->value <<=1;
+	}
+	
+	return 0;	
+}
diff -urN linux-2.4.29/arch/niosnommu/kernel/process.c linux-2.4.29-uc1/arch/niosnommu/kernel/process.c
--- linux-2.4.29/arch/niosnommu/kernel/process.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/process.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,348 @@
+/*
+ *  Mar 2, 2001 - Ken Hill
+ *     Implement Nios architecture specifics
+ *
+ *  linux/arch/sparc/kernel/process.c
+ *
+ *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+#define __KERNEL_SYSCALLS__
+#include <stdarg.h>
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+
+#include <asm/uaccess.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/delay.h>
+#include <asm/processor.h>
+#include <asm/psr.h>
+
+/*
+ * Initial task structure. Make this a per-architecture thing,
+ * because different architectures tend to have different
+ * alignment requirements and potentially different initial
+ * setup.
+ */
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS;
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+union task_union init_task_union
+__attribute__((section(".data.init_task"), aligned(THREAD_SIZE)))
+	= { task: INIT_TASK(init_task_union.task) };
+
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle(void)
+{
+	/* endless idle loop with no priority at all */
+	init_idle();
+	current->nice = 20;
+	current->counter = -100;
+
+	while (1) {
+		while (!current->need_resched) {
+		}
+		schedule();
+	}
+}
+
+extern char saved_command_line[];
+
+void machine_restart(char * __unused)
+{
+	//vic FIXME - what should we really do here ?
+	asm("trap 0");
+}
+
+void machine_halt(void)
+{
+	asm("trap 0");				/* trap to deamon */
+}
+
+void machine_power_off(void)
+{
+	//vic FIXME - what should we really do here ?
+	asm("trap 0");
+}
+
+void hard_reset_now(void)
+{
+#if 0
+	panic("Reboot failed!");
+#else
+	asm("trap 0");				/* this traps back to monitor */
+#endif
+}
+
+void show_regwindow(struct reg_window *rw)
+{
+	printk("l0:%08lx l1:%08lx l2:%08lx l3:%08lx l4:%08lx l5:%08lx l6:%08lx l7:%08lx\n",
+	       rw->locals[0], rw->locals[1], rw->locals[2], rw->locals[3],
+	       rw->locals[4], rw->locals[5], rw->locals[6], rw->locals[7]);
+	printk("i0:%08lx i1:%08lx i2:%08lx i3:%08lx i4:%08lx i5:%08lx i6:%08lx i7:%08lx\n",
+	       rw->ins[0], rw->ins[1], rw->ins[2], rw->ins[3],
+	       rw->ins[4], rw->ins[5], rw->ins[6], rw->ins[7]);
+}
+
+void show_regs(struct pt_regs * regs)
+{
+        printk("PSR: %08lx PC: %08lx\n", regs->psr, regs->pc);
+	printk("%%g0: %08lx %%g1: %08lx %%g2: %08lx %%g3: %08lx\n",
+	       regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
+	       regs->u_regs[3]);
+	printk("%%g4: %08lx %%g5: %08lx %%g6: %08lx %%g7: %08lx\n",
+	       regs->u_regs[4], regs->u_regs[5], regs->u_regs[6],
+	       regs->u_regs[7]);
+	printk("%%o0: %08lx %%o1: %08lx %%o2: %08lx %%o3: %08lx\n",
+	       regs->u_regs[8], regs->u_regs[9], regs->u_regs[10],
+	       regs->u_regs[11]);
+	printk("%%o4: %08lx %%o5: %08lx %%sp: %08lx %%ret_pc: %08lx\n",
+	       regs->u_regs[12], regs->u_regs[13], regs->u_regs[14],
+	       regs->u_regs[15]);
+}
+
+/*
+ * Free current thread data structures etc..
+ */
+void exit_thread(void)
+{
+}
+
+/*
+ * Free old dead task when we know it can never be on the cpu again.
+ */
+void release_thread(struct task_struct *dead_task)
+{
+	/* nothing to do ... */
+}
+
+void flush_thread(void)
+{
+	current->thread.sig_address = 0;
+	current->thread.sig_desc = 0;
+
+	/* Now, this task is no longer a kernel thread. */
+	current->thread.flags &= ~NIOS_FLAG_KTHREAD;
+}
+
+/*
+ * Copy a Nios thread.  The fork() return value conventions:
+ * 
+ * Parent -->  %o0 == childs  pid, %o1 == 0
+ * Child  -->  %o0 == 0, 	   %o1 == 1
+ *
+ * NOTE: We have a separate fork kpsr because
+ *       the parent could change this value between
+ *       sys_fork invocation and when we reach here
+ *       if the parent should sleep while trying to
+ *       allocate the task_struct and kernel stack in
+ *       do_fork().
+ */
+extern void ret_sys_call(void);
+
+int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+		unsigned long unused,
+		 struct task_struct *p, struct pt_regs *regs)
+{
+	struct pt_regs *childregs;
+	struct reg_window *old_stack, *new_stack;
+	unsigned long stack_offset;
+
+	/* Calculate offset to stack_frame & pt_regs */
+	stack_offset = (THREAD_SIZE - TRACEREG_SZ);
+
+	if(regs->psr & PSR_SUPERVISOR)
+		stack_offset -= REGWIN_SZ;
+	childregs = ((struct pt_regs *) ((unsigned long) p + stack_offset));
+	*childregs = *regs;
+	new_stack = (((struct reg_window *) childregs) - 1);
+	old_stack = (((struct reg_window *) regs) - 1);
+	*new_stack = *old_stack;
+	p->thread.ksp = (unsigned long) new_stack;
+	p->thread.kpc = (((unsigned long) ret_sys_call));
+	/* Start the new process with a fresh register window */
+	p->thread.kpsr = (current->thread.fork_kpsr & ~PSR_CWP) | ((get_hi_limit() - 1) << 4);
+
+	/* If we decide to split the register file up for multiple
+	   task usage we will need this. Single register file usage
+	   for now so do not use.
+
+	p->thread.kwvalid = current->thread.fork_kwvalid;
+	*/
+
+	p->thread.kregs = childregs;
+	/* Start the new process with a fresh register window */
+	childregs->psr = (childregs->psr & ~PSR_CWP) | (get_hi_limit() << 4);
+
+	if(regs->psr & PSR_SUPERVISOR) {
+		stack_offset += TRACEREG_SZ;
+		childregs->u_regs[UREG_FP] = (unsigned long) p + stack_offset;
+		new_stack->ins[6]=childregs->u_regs[UREG_FP];
+		memcpy(childregs->u_regs[UREG_FP], regs->u_regs[UREG_FP], REGWIN_SZ);
+		p->thread.flags |= NIOS_FLAG_KTHREAD;
+	} else {
+		if (sp!=childregs->u_regs[UREG_FP]){
+			/* clone */
+			childregs->u_regs[UREG_FP] = (unsigned long) sp - REGWIN_SZ;
+			new_stack->ins[6]=childregs->u_regs[UREG_FP];
+			memcpy(childregs->u_regs[UREG_FP], regs->u_regs[UREG_FP], REGWIN_SZ);
+		}
+		p->thread.flags &= ~NIOS_FLAG_KTHREAD;
+	}
+
+	/* Set the return value for the child. */
+	childregs->u_regs[UREG_I0] = 0;
+	childregs->u_regs[UREG_I1] = 1;
+
+	/* Set the return value for the parent. */
+	regs->u_regs[UREG_I1] = 0;
+
+	return 0;
+}
+
+/*
+ * This is the mechanism for creating a new kernel thread.
+ *
+ * NOTE! Only a kernel-only process(ie the swapper or direct descendants
+ * who haven't done an "execve()") should use this: it will work within
+ * a system call from a "real" process, but the process memory space will
+ * not be free'd until both the parent and the child have exited.
+ */
+pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	long retval;
+	register long clone_arg __asm__ ("%o0") = flags | CLONE_VM;
+	__asm__ __volatile(
+		"pfx	%%hi(%1)\n\t"
+		"movi	%%g1,%%lo(%1)\n\t"	/* syscall # */
+		"movi	%%o1, 0\n\t"			/* usp arg == 0 */
+		"trap	63\n\t"					/* Linux/nios clone(). */
+		"cmpi	%%o1, 0\n\t"			/* 2nd arg returned in %o1 */
+		"skps	cc_ne\n\t"
+		"br	1f\n\t"					/* The parent, just return. */
+		"nop\n\t"						/* Delay slot. */
+		"call	%3\n\t"					/* Call the function. */
+		"mov	%%o0, %4\n\t"			/* Get the arg (in delay slot) */
+		"pfx	%%hi(%2)\n\t"
+		"movi	%%g1, %%lo(%2)\n\t"	/* syscall # */
+		"trap	63\n\t"					/* Linux/nios exit(). */
+		   /* Not reached by child. */
+		"1:"
+		"mov	%0, %%o0\n\t"			/* arg returned in o0 */
+		: "=r" (retval)
+		: "i" (__NR_clone), "i" (__NR_exit), "r" (fn), "r" (arg), "r" (clone_arg)
+		: "g1","o0","o1");
+	return retval;
+//vic - may not be able to return argument in %g1 - "ret_trap_entry"
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs * regs, struct user * dump)
+{
+	unsigned long first_stack_page;
+
+	dump->magic = CMAGIC;
+	dump->start_code = 0;
+	dump->start_stack = regs->u_regs[UREG_FP] & ~(PAGE_SIZE - 1);
+	dump->regs.psr = regs->psr;
+	dump->regs.pc = regs->pc;
+	/* fuck me plenty */
+	memcpy(&dump->regs, regs, sizeof(regs));
+	dump->u_tsize = (((unsigned long) current->mm->end_code) -
+		((unsigned long) current->mm->start_code)) & ~(PAGE_SIZE - 1);
+	dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1)));
+	dump->u_dsize -= dump->u_tsize;
+	dump->u_dsize &= ~(PAGE_SIZE - 1);
+	first_stack_page = (regs->u_regs[UREG_FP] & ~(PAGE_SIZE - 1));
+	dump->u_ssize = (TASK_SIZE - first_stack_page) & ~(PAGE_SIZE - 1);
+}
+
+/*
+ * fill in the fpu structure for a core dump.
+ */
+int dump_fpu (void *fpu_structure)
+{
+	/* Currently we report that we couldn't dump the fpu structure */
+	return 0;
+}
+
+/*
+ * nios_execve() executes a new program after the asm stub has set
+ * things up for us.  This should basically do what I want it to.
+ */
+asmlinkage int nios_execve(struct pt_regs *regs)
+{
+	int error;
+	char *filename;
+
+	filename = getname((char *)regs->u_regs[UREG_I0]);
+	error = PTR_ERR(filename);
+	if(IS_ERR(filename))
+		return error;
+
+	error = do_execve(filename, (char **) regs->u_regs[UREG_I1],
+			  (char **) regs->u_regs[UREG_I2], regs);
+	putname(filename);
+	return error;
+}
+
+void show_trace_task(struct task_struct *tsk)
+{
+	printk("STACK ksp=0x%lx\n", tsk->thread.ksp);
+}
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+#define first_sched	((unsigned long) scheduling_functions_start_here)
+#define last_sched	((unsigned long) scheduling_functions_end_here)
+
+unsigned long get_wchan(struct task_struct *p)
+{
+	unsigned long fp,pc;
+	unsigned long stack_page;
+	int count = 0;
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	stack_page = (unsigned long)p;
+	fp = p->thread.ksp;
+	do {
+		if (fp < stack_page+sizeof(struct task_struct) ||
+		    fp >= THREAD_SIZE-REGWIN_SZ+stack_page)
+			return 0;
+		pc = ((struct reg_window *)fp)->ins[7]; /* saved return address */
+		if (pc < first_sched || pc >= last_sched)
+			return pc;
+		fp = ((struct reg_window *)fp)->ins[6];
+	} while (count++ < 16);
+	return 0;
+}
diff -urN linux-2.4.29/arch/niosnommu/kernel/ptrace.c linux-2.4.29-uc1/arch/niosnommu/kernel/ptrace.c
--- linux-2.4.29/arch/niosnommu/kernel/ptrace.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/ptrace.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,591 @@
+//vic FIXME - bad struct member: signal
+/* ptrace.c: Sparc process tracing support.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu)
+ *
+ * Based upon code written by Ross Biro, Linus Torvalds, Bob Manson,
+ * and David Mosberger.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+
+#include <asm/pgtable.h>
+#include <asm/system.h>
+
+#if 0
+/* Returning from ptrace is a bit tricky because the syscall return
+ * low level code assumes any value returned which is negative and
+ * is a valid errno will mean setting the condition codes to indicate
+ * an error return.  This doesn't work, so we have this hook.
+ */
+static inline void pt_error_return(struct pt_regs *regs, unsigned long error)
+{
+	regs->u_regs[UREG_I0] = error;
+	regs->psr |= PSR_C;
+	regs->pc = regs->npc;
+	regs->npc += 4;
+}
+
+static inline void pt_succ_return(struct pt_regs *regs, unsigned long value)
+{
+	regs->u_regs[UREG_I0] = value;
+	regs->psr &= ~PSR_C;
+	regs->pc = regs->npc;
+	regs->npc += 4;
+}
+
+/* Fuck me gently with a chainsaw... */
+static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset,
+				   struct task_struct *tsk)
+{
+	struct pt_regs *cregs = tsk->thread.kregs;
+	struct thread_struct *t = &tsk->thread;
+
+	if(offset >= 1024)
+		offset -= 1024; /* whee... */
+	if(offset & ((sizeof(unsigned long) - 1))) {
+		pt_error_return(regs, EIO);
+		return;
+	}
+	if(offset >= 16 && offset < 784) {
+		offset -= 16; offset >>= 2;
+		pt_succ_return(regs, *(((unsigned long *)(&t->reg_window[0]))+offset));	
+		return;
+	}
+	if(offset >= 784 && offset < 832) {
+		offset -= 784; offset >>= 2;
+		pt_succ_return(regs, *(((unsigned long *)(&t->rwbuf_stkptrs[0]))+offset));
+		return;
+	}
+	switch(offset) {
+	case 0:
+		regs->u_regs[UREG_I0] = t->ksp;
+		break;
+	case 4:
+		regs->u_regs[UREG_I0] = t->kpc;
+		break;
+	case 8:
+		regs->u_regs[UREG_I0] = t->kpsr;
+		break;
+	case 12:
+		regs->u_regs[UREG_I0] = t->uwinmask;
+		break;
+	case 832:
+		regs->u_regs[UREG_I0] = t->w_saved;
+		break;
+	case 896:
+		regs->u_regs[UREG_I0] = cregs->u_regs[UREG_I0];
+		break;
+	case 900:
+		regs->u_regs[UREG_I0] = cregs->u_regs[UREG_I1];
+		break;
+	case 904:
+		regs->u_regs[UREG_I0] = cregs->u_regs[UREG_I2];
+		break;
+	case 908:
+		regs->u_regs[UREG_I0] = cregs->u_regs[UREG_I3];
+		break;
+	case 912:
+		regs->u_regs[UREG_I0] = cregs->u_regs[UREG_I4];
+		break;
+	case 916:
+		regs->u_regs[UREG_I0] = cregs->u_regs[UREG_I5];
+		break;
+	case 920:
+		regs->u_regs[UREG_I0] = cregs->u_regs[UREG_I6];
+		break;
+	case 924:
+		if(tsk->thread.flags & 0x80000000)
+			regs->u_regs[UREG_I0] = cregs->u_regs[UREG_G1];
+		else
+			regs->u_regs[UREG_I0] = 0;
+		break;
+	case 940:
+		regs->u_regs[UREG_I0] = cregs->u_regs[UREG_I0];
+		break;
+	case 944:
+		regs->u_regs[UREG_I0] = cregs->u_regs[UREG_I1];
+		break;
+
+	case 948:
+		/* Isn't binary compatibility _fun_??? */
+		if(cregs->psr & PSR_C)
+			regs->u_regs[UREG_I0] = cregs->u_regs[UREG_I0] << 24;
+		else
+			regs->u_regs[UREG_I0] = 0;
+		break;
+
+		/* Rest of them are completely unsupported. */
+	default:
+		printk("%s [%d]: Wants to read user offset %d\n",
+		       current->comm, current->pid, offset);
+		pt_error_return(regs, EIO);
+		return;
+	}
+	regs->psr &= ~PSR_C;
+	regs->pc = regs->npc;
+	regs->npc += 4;
+	return;
+}
+
+static inline void write_sunos_user(struct pt_regs *regs, unsigned long offset,
+				    struct task_struct *tsk)
+{
+	struct pt_regs *cregs = tsk->thread.kregs;
+	struct thread_struct *t = &tsk->thread;
+	unsigned long value = regs->u_regs[UREG_I3];
+
+	if(offset >= 1024)
+		offset -= 1024; /* whee... */
+	if(offset & ((sizeof(unsigned long) - 1)))
+		goto failure;
+	if(offset >= 16 && offset < 784) {
+		offset -= 16; offset >>= 2;
+		*(((unsigned long *)(&t->reg_window[0]))+offset) = value;
+		goto success;
+	}
+	if(offset >= 784 && offset < 832) {
+		offset -= 784; offset >>= 2;
+		*(((unsigned long *)(&t->rwbuf_stkptrs[0]))+offset) = value;
+		goto success;
+	}
+	switch(offset) {
+	case 896:
+		cregs->u_regs[UREG_I0] = value;
+		break;
+	case 900:
+		cregs->u_regs[UREG_I1] = value;
+		break;
+	case 904:
+		cregs->u_regs[UREG_I2] = value;
+		break;
+	case 908:
+		cregs->u_regs[UREG_I3] = value;
+		break;
+	case 912:
+		cregs->u_regs[UREG_I4] = value;
+		break;
+	case 916:
+		cregs->u_regs[UREG_I5] = value;
+		break;
+	case 920:
+		cregs->u_regs[UREG_I6] = value;
+		break;
+	case 924:
+		cregs->u_regs[UREG_I7] = value;
+		break;
+	case 940:
+		cregs->u_regs[UREG_I0] = value;
+		break;
+	case 944:
+		cregs->u_regs[UREG_I1] = value;
+		break;
+
+		/* Rest of them are completely unsupported or "no-touch". */
+	default:
+		printk("%s [%d]: Wants to write user offset %d\n",
+		       current->comm, current->pid, offset);
+		goto failure;
+	}
+success:
+	pt_succ_return(regs, 0);
+	return;
+failure:
+	pt_error_return(regs, EIO);
+	return;
+}
+
+/* #define ALLOW_INIT_TRACING */
+/* #define DEBUG_PTRACE */
+
+#endif /* 0 */
+
+asmlinkage void do_ptrace(struct pt_regs *regs)
+{
+#if 1
+	return -ENOSYS;
+#else /* 0 */
+	unsigned long request = regs->u_regs[UREG_I0];
+	unsigned long pid = regs->u_regs[UREG_I1];
+	unsigned long addr = regs->u_regs[UREG_I2];
+	unsigned long data = regs->u_regs[UREG_I3];
+	unsigned long addr2 = regs->u_regs[UREG_I4];
+	struct task_struct *child;
+
+#ifdef DEBUG_PTRACE
+	printk("do_ptrace: rq=%d pid=%d addr=%08lx data=%08lx addr2=%08lx\n",
+	       (int) request, (int) pid, addr, data, addr2);
+#endif
+	if(request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->flags & PT_PTRACED) {
+			pt_error_return(regs, EPERM);
+			return;
+		}
+		/* set the ptrace bit in the process flags. */
+		current->flags |= PT_PTRACED;
+		pt_succ_return(regs, 0);
+		return;
+	}
+#ifndef ALLOW_INIT_TRACING
+	if(pid == 1) {
+		/* Can't dork with init. */
+		pt_error_return(regs, EPERM);
+		return;
+	}
+#endif
+	if(!(child = get_task(pid))) {
+		pt_error_return(regs, ESRCH);
+		return;
+	}
+
+	if(request == PTRACE_SUNATTACH) {
+		if(child == current) {
+			/* Try this under SunOS/Solaris, bwa haha
+			 * You'll never be able to kill the process. ;-)
+			 */
+			pt_error_return(regs, EPERM);
+			return;
+		}
+		if((!child->dumpable ||
+		    (current->uid != child->euid) ||
+		    (current->uid != child->uid) ||
+		    (current->gid != child->egid) ||
+		    (current->gid != child->gid)) && !suser()) {
+			pt_error_return(regs, EPERM);
+			return;
+		}
+		/* the same process cannot be attached many times */
+		if (child->flags & PT_PTRACED) {
+			pt_error_return(regs, EPERM);
+			return;
+		}
+		child->flags |= PT_PTRACED;
+		if(child->p_pptr != current) {
+			REMOVE_LINKS(child);
+			child->p_pptr = current;
+			SET_LINKS(child);
+		}
+		send_sig(SIGSTOP, child, 1);
+		pt_succ_return(regs, 0);
+		return;
+	}
+	if(!(child->flags & PT_PTRACED)) {
+		pt_error_return(regs, ESRCH);
+		return;
+	}
+	if(child->state != TASK_STOPPED) {
+		if(request != PTRACE_KILL) {
+			pt_error_return(regs, ESRCH);
+			return;
+		}
+	}
+	if(child->p_pptr != current) {
+		pt_error_return(regs, ESRCH);
+		return;
+	}
+	switch(request) {
+	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+	case PTRACE_PEEKDATA: {
+		unsigned long tmp;
+		int res;
+
+		/* Non-word alignment _not_ allowed on Sparc. */
+		if(addr & (sizeof(unsigned long) - 1)) {
+			pt_error_return(regs, EINVAL);
+			return;
+		}
+		res = read_long(child, addr, &tmp);
+		if (res < 0) {
+			pt_error_return(regs, -res);
+			return;
+		}
+		pt_succ_return(regs, tmp);
+		return;
+	}
+
+	case PTRACE_PEEKUSR:
+		read_sunos_user(regs, addr, child);
+		return;
+
+	case PTRACE_POKEUSR:
+		write_sunos_user(regs, addr, child);
+		return;
+
+	case PTRACE_POKETEXT: /* write the word at location addr. */
+	case PTRACE_POKEDATA: {
+		struct vm_area_struct *vma;
+		int res;
+
+		/* Non-word alignment _not_ allowed on Sparc. */
+		if(addr & (sizeof(unsigned long) - 1)) {
+			pt_error_return(regs, EINVAL);
+			return;
+		}
+		vma = find_extend_vma(child, addr);
+		if(vma && request == PTRACE_POKEDATA && (vma->vm_flags & VM_EXEC)) {
+			pt_error_return(regs, EIO);
+			return;
+		}
+		res = write_long(child, addr, data);
+		if(res < 0)
+			pt_error_return(regs, -res);
+		else
+			pt_succ_return(regs, res);
+		return;
+	}
+
+	case PTRACE_GETREGS: {
+		struct pt_regs *pregs = (struct pt_regs *) addr;
+		struct pt_regs *cregs = child->thread.kregs;
+		int rval;
+
+		rval = verify_area(VERIFY_WRITE, pregs, sizeof(struct pt_regs) - 4);
+		if(rval) {
+			pt_error_return(regs, rval);
+			return;
+		}
+		pregs->psr = cregs->psr;
+		pregs->pc = cregs->pc;
+		pregs->npc = cregs->npc;
+		pregs->y = cregs->y;
+		for(rval = 1; rval < 16; rval++)
+			pregs->u_regs[rval - 1] = cregs->u_regs[rval];
+		pt_succ_return(regs, 0);
+		return;
+	}
+
+	case PTRACE_SETREGS: {
+		struct pt_regs *pregs = (struct pt_regs *) addr;
+		struct pt_regs *cregs = child->thread.kregs;
+		unsigned long psr;
+		int rval, i;
+
+		rval = verify_area(VERIFY_READ, pregs, sizeof(struct pt_regs) - 4);
+		if(rval) {
+			pt_error_return(regs, rval);
+			return;
+		}
+		/* Must be careful, tracing process can only set certain
+		 * bits in the psr.
+		 */
+		psr = (pregs->psr) & PSR_ICC;
+		cregs->psr &= ~PSR_ICC;
+		cregs->psr |= psr;
+		if(!((pregs->pc | pregs->npc) & 3)) {
+			cregs->pc = pregs->pc;
+			cregs->npc = pregs->npc;
+		}
+		cregs->y = pregs->y;
+		for(i = 1; i < 16; i++)
+			cregs->u_regs[i] = pregs->u_regs[i-1];
+		pt_succ_return(regs, 0);
+		return;
+	}
+
+	case PTRACE_GETFPREGS: {
+		struct fps {
+			unsigned long regs[32];
+			unsigned long fsr;
+			unsigned long flags;
+			unsigned long extra;
+			unsigned long fpqd;
+			struct fq {
+				unsigned long *insnaddr;
+				unsigned long insn;
+			} fpq[16];
+		} *fps = (struct fps *) addr;
+		int rval, i;
+
+		rval = verify_area(VERIFY_WRITE, fps, sizeof(struct fps));
+		if(rval) { pt_error_return(regs, rval); return; }
+		for(i = 0; i < 32; i++)
+			fps->regs[i] = child->thread.float_regs[i];
+		fps->fsr = child->thread.fsr;
+		fps->fpqd = child->thread.fpqdepth;
+		fps->flags = fps->extra = 0;
+		for(i = 0; i < 16; i++) {
+			fps->fpq[i].insnaddr = child->thread.fpqueue[i].insn_addr;
+			fps->fpq[i].insn = child->thread.fpqueue[i].insn;
+		}
+		pt_succ_return(regs, 0);
+		return;
+	}
+
+	case PTRACE_SETFPREGS: {
+		struct fps {
+			unsigned long regs[32];
+			unsigned long fsr;
+			unsigned long flags;
+			unsigned long extra;
+			unsigned long fpqd;
+			struct fq {
+				unsigned long *insnaddr;
+				unsigned long insn;
+			} fpq[16];
+		} *fps = (struct fps *) addr;
+		int rval, i;
+
+		rval = verify_area(VERIFY_READ, fps, sizeof(struct fps));
+		if(rval) { pt_error_return(regs, rval); return; }
+		for(i = 0; i < 32; i++)
+			child->thread.float_regs[i] = fps->regs[i];
+		child->thread.fsr = fps->fsr;
+		child->thread.fpqdepth = fps->fpqd;
+		for(i = 0; i < 16; i++) {
+			child->thread.fpqueue[i].insn_addr = fps->fpq[i].insnaddr;
+			child->thread.fpqueue[i].insn = fps->fpq[i].insn;
+		}
+		pt_succ_return(regs, 0);
+		return;
+	}
+
+	case PTRACE_READTEXT:
+	case PTRACE_READDATA: {
+		unsigned char *dest = (unsigned char *) addr2;
+		unsigned long src = addr;
+		unsigned char tmp;
+		int res, len = data;
+
+		res = verify_area(VERIFY_WRITE, (void *) dest, len);
+		if(res) {
+			pt_error_return(regs, -res);
+			return;
+		}
+		while(len) {
+			res = read_byte(child, src, &tmp);
+			if(res < 0) {
+				pt_error_return(regs, -res);
+				return;
+			}
+			*dest = tmp;
+			src++; dest++; len--;
+		}
+		pt_succ_return(regs, 0);
+		return;
+	}
+
+	case PTRACE_WRITETEXT:
+	case PTRACE_WRITEDATA: {
+		unsigned char *src = (unsigned char *) addr2;
+		unsigned long dest = addr;
+		int res, len = data;
+
+		res = verify_area(VERIFY_READ, (void *) src, len);
+		if(res) {
+			pt_error_return(regs, -res);
+			return;
+		}
+		while(len) {
+			res = write_byte(child, dest, *src);
+			if(res < 0) {
+				pt_error_return(regs, -res);
+				return;
+			}
+			src++; dest++; len--;
+		}
+		pt_succ_return(regs, 0);
+		return;
+	}
+
+	case PTRACE_SYSCALL: /* continue and stop at (return from) syscall */
+		data = 0;
+		addr = 1;
+
+	case PTRACE_CONT: { /* restart after signal. */
+		if ((unsigned long) data > NSIG) {
+			pt_error_return(regs, EIO);
+			return;
+		}
+		if (request == PTRACE_SYSCALL)
+			child->flags |= PT_TRACESYS;
+		else
+			child->flags &= ~PT_TRACESYS;
+		child->exit_code = data;
+		if((addr != 1) & !(addr & 3)) {
+			child->thread.kregs->pc = addr;
+			child->thread.kregs->npc = addr + 4;
+		}
+		wake_up_process(child);
+		pt_succ_return(regs, 0);
+		return;
+	}
+
+/*
+ * make the child exit.  Best I can do is send it a sigkill. 
+ * perhaps it should be put in the status that it wants to 
+ * exit.
+ */
+	case PTRACE_KILL: {
+		if (child->state == TASK_ZOMBIE) {	/* already dead */
+			pt_succ_return(regs, 0);
+			return;
+		}
+		wake_up_process(child);
+		child->exit_code = SIGKILL;
+		pt_succ_return(regs, 0);
+		return;
+	}
+
+	case PTRACE_SUNDETACH: { /* detach a process that was attached. */
+		if ((unsigned long) data > NSIG) {
+			pt_error_return(regs, EIO);
+			return;
+		}
+		child->flags &= ~(PT_PTRACED|PT_TRACESYS);
+		wake_up_process(child);
+		child->exit_code = data;
+		REMOVE_LINKS(child);
+		child->p_pptr = child->p_opptr;
+		SET_LINKS(child);
+		pt_succ_return(regs, 0);
+		return;
+	}
+
+	/* PTRACE_DUMPCORE unsupported... */
+
+	default:
+		pt_error_return(regs, EIO);
+		return;
+	}
+#endif /* 0 */
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure the single step bit is not set.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+	//vic - FIXME - ptrace not really implemented anyway
+}
+
+asmlinkage void syscall_trace(void)
+{
+#ifdef DEBUG_PTRACE
+	printk("%s [%d]: syscall_trace\n", current->comm, current->pid);
+#endif
+	if ((current->flags & (PT_PTRACED|PT_TRACESYS))
+			!= (PT_PTRACED|PT_TRACESYS))
+		return;
+	current->exit_code = SIGTRAP;
+	current->state = TASK_STOPPED;
+	current->thread.flags ^= 0x80000000;
+	notify_parent(current, SIGTRAP);
+	schedule();
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+//vic FIXME - is this ever used ? - needs work to update signals
+//vic	if (current->exit_code)
+//vic		current->signal |= (1 << (current->exit_code - 1));
+	current->exit_code = 0;
+}
diff -urN linux-2.4.29/arch/niosnommu/kernel/semaphore.c linux-2.4.29-uc1/arch/niosnommu/kernel/semaphore.c
--- linux-2.4.29/arch/niosnommu/kernel/semaphore.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/semaphore.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,164 @@
+/*
+ * arch/v850/kernel/semaphore.c -- Semaphore support
+ *
+ *  Copyright (C) 1998-2000  IBM Corporation
+ *  Copyright (C) 1999  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * This file is a copy of the s390 version, arch/s390/kernel/semaphore.c
+ *    Author(s): Martin Schwidefsky
+ * which was derived from the i386 version, linux/arch/i386/kernel/semaphore.c
+ */
+
+#include <linux/sched.h>
+
+#include <asm/semaphore.h>
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to acquire the semaphore, while the "sleeping"
+ * variable is a count of such acquires.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * "sleeping" and the contention routine ordering is
+ * protected by the semaphore spinlock.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+
+/*
+ * Logic:
+ *  - only on a boundary condition do we need to care. When we go
+ *    from a negative count to a non-negative, we wake people up.
+ *  - when we go from a non-negative count to a negative do we
+ *    (a) synchronize with the "sleeper" count and (b) make sure
+ *    that we're on the wakeup list before we synchronize so that
+ *    we cannot lose wakeup events.
+ */
+
+void __up(struct semaphore *sem)
+{
+	wake_up(&sem->wait);
+}
+
+static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED;
+
+void __down(struct semaphore * sem)
+{
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+	tsk->state = TASK_UNINTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	spin_lock_irq(&semaphore_lock);
+	sem->sleepers++;
+	for (;;) {
+		int sleepers = sem->sleepers;
+
+		/*
+		 * Add "everybody else" into it. They aren't
+		 * playing, because we own the spinlock.
+		 */
+		if (!atomic_add_negative(sleepers - 1, &sem->count)) {
+			sem->sleepers = 0;
+			break;
+		}
+		sem->sleepers = 1;	/* us - see -1 above */
+		spin_unlock_irq(&semaphore_lock);
+
+		schedule();
+		tsk->state = TASK_UNINTERRUPTIBLE;
+		spin_lock_irq(&semaphore_lock);
+	}
+	spin_unlock_irq(&semaphore_lock);
+	remove_wait_queue(&sem->wait, &wait);
+	tsk->state = TASK_RUNNING;
+	wake_up(&sem->wait);
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+	int retval = 0;
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+	tsk->state = TASK_INTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	spin_lock_irq(&semaphore_lock);
+	sem->sleepers ++;
+	for (;;) {
+		int sleepers = sem->sleepers;
+
+		/*
+		 * With signals pending, this turns into
+		 * the trylock failure case - we won't be
+		 * sleeping, and we* can't get the lock as
+		 * it has contention. Just correct the count
+		 * and exit.
+		 */
+		if (signal_pending(current)) {
+			retval = -EINTR;
+			sem->sleepers = 0;
+			atomic_add(sleepers, &sem->count);
+			break;
+		}
+
+		/*
+		 * Add "everybody else" into it. They aren't
+		 * playing, because we own the spinlock. The
+		 * "-1" is because we're still hoping to get
+		 * the lock.
+		 */
+		if (!atomic_add_negative(sleepers - 1, &sem->count)) {
+			sem->sleepers = 0;
+			break;
+		}
+		sem->sleepers = 1;	/* us - see -1 above */
+		spin_unlock_irq(&semaphore_lock);
+
+		schedule();
+		tsk->state = TASK_INTERRUPTIBLE;
+		spin_lock_irq(&semaphore_lock);
+	}
+	spin_unlock_irq(&semaphore_lock);
+	tsk->state = TASK_RUNNING;
+	remove_wait_queue(&sem->wait, &wait);
+	wake_up(&sem->wait);
+	return retval;
+}
+
+/*
+ * Trylock failed - make sure we correct for
+ * having decremented the count.
+ */
+int __down_trylock(struct semaphore * sem)
+{
+        unsigned long flags;
+	int sleepers;
+
+	spin_lock_irqsave(&semaphore_lock, flags);
+	sleepers = sem->sleepers + 1;
+	sem->sleepers = 0;
+
+	/*
+	 * Add "everybody else" and us into it. They aren't
+	 * playing, because we own the spinlock.
+	 */
+	if (!atomic_add_negative(sleepers, &sem->count))
+		wake_up(&sem->wait);
+
+	spin_unlock_irqrestore(&semaphore_lock, flags);
+	return 1;
+}
diff -urN linux-2.4.29/arch/niosnommu/kernel/setup.c linux-2.4.29-uc1/arch/niosnommu/kernel/setup.c
--- linux-2.4.29/arch/niosnommu/kernel/setup.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/setup.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,377 @@
+/*
+  21Mar2001    1.1    dgt/microtronix: Altera Excalibur/Nios32 port
+*/
+
+/*
+ *  linux/arch/niosnommu/kernel/setup.c
+ *
+ *  Copyright (C) 2001       Vic Phillips {vic@microtronix.com}
+ *  Copyleft  (C) 2000       James D. Schettine {james@telos-systems.com}
+ *  Copyright (C) 1999       Greg Ungerer (gerg@moreton.com.au)
+ *  Copyright (C) 1998,2000  D. Jeff Dionne <jeff@uClinux.org>
+ *  Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ *  Copyright (C) 1995       Hamish Macdonald
+ */
+
+/*
+ * This file handles the architecture-dependent parts of system setup
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/genhd.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/major.h>
+#include <linux/bootmem.h>
+#include <linux/seq_file.h>
+
+#include <asm/irq.h>
+#include <asm/byteorder.h>
+#include <asm/niosconf.h>
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <linux/blk.h>
+#include <asm/pgtable.h>
+#endif
+
+#ifdef CONFIG_NIOS_SPI
+#include <asm/spi.h>
+extern ssize_t spi_write(struct file *filp, const char *buf, size_t count, loff_t *ppos);
+extern ssize_t spi_read (struct file *filp, char *buf, size_t count, loff_t *ppos);
+extern loff_t spi_lseek (struct file *filp, loff_t offset, int origin);
+extern int spi_open     (struct inode *inode, struct file *filp);
+extern int spi_release  (struct inode *inode, struct file *filp);
+#endif
+
+unsigned long rom_length;
+unsigned long memory_start;
+unsigned long memory_end;
+
+struct task_struct *_current_task;
+
+#define COMMAND_LINE_SIZE 256
+
+#ifndef CONFIG_CMDLINE
+#define CONFIG_CMDLINE	"CONSOLE=/dev/ttyS0 root=/dev/rom0 ro"
+#endif
+
+static char default_command_line[] = CONFIG_CMDLINE;
+static char command_line[COMMAND_LINE_SIZE] = { 0, };
+       char saved_command_line[COMMAND_LINE_SIZE];
+
+char console_device[16];
+char console_default[] = "/dev/ttyS0";
+
+extern int cpu_idle(void);
+static struct pt_regs fake_regs = { 0, (unsigned long)cpu_idle, 0, 0, {0,}};
+
+#define CPU "NIOS"
+
+#if defined (CONFIG_CS89x0) || (CONFIG_SMC91111)
+unsigned char *cs8900a_hwaddr;
+unsigned char cs8900a_hwaddr_array[6];
+#endif
+
+inline void flash_command(int base, int offset, short data)
+{
+	volatile unsigned short * ptr=(unsigned short*) (base);
+
+	ptr[0x555]=0xaa;
+	ptr[0x2aa]=0x55;
+	ptr[offset]=data;
+}
+
+inline void exit_se_flash(int base)  
+{ 
+	flash_command(base, 0x555, 0x90);
+	*(unsigned short*)base=0;
+}
+
+void setup_arch(char **cmdline_p)
+{
+	int bootmap_size;
+	extern int _stext, _etext;
+	extern int _edata, _end;
+#ifdef DEBUG
+	extern int _sdata, _sbss, _ebss;
+#ifdef CONFIG_BLK_DEV_BLKMEM
+	extern int *romarray;
+#endif
+#endif
+	unsigned char *psrc=(unsigned char *)((NIOS_FLASH_START + NIOS_FLASH_END)>>1);
+	int i=0;
+
+	memory_start = (unsigned long)&_end;
+	memory_end = (int) nasys_program_mem_end;
+
+	/* copy the command line from booting paramter region */
+	flash_command((int)psrc, 0x555, 0x88);
+	while ((*psrc!=0xFF) && (i<sizeof(command_line))) {
+		command_line[i++]=*psrc++;
+	}
+	command_line[i]=0;
+	exit_se_flash(((NIOS_FLASH_START + NIOS_FLASH_END)>>1) );
+	if (command_line[0]==0)
+		memcpy(command_line, default_command_line, sizeof(default_command_line));
+
+	printk("\x0F\r\n\nuClinux/NIOS\n");
+	printk("Altera NIOS Excalibur support (C) 2001 Microtronix Datacom Ltd.\n");
+
+#ifdef DEBUG
+	printk("KERNEL -> TEXT=0x%08x-0x%08x DATA=0x%08x-0x%08x "
+		"BSS=0x%08x-0x%08x\n", (int) &_stext, (int) &_etext,
+		(int) &_sdata, (int) &_edata,
+		(int) &_sbss, (int) &_ebss);
+	printk("KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x "
+		"STACK=0x%06x-0x%06x\n",
+#ifdef CONFIG_BLK_DEV_BLKMEM
+	       (int) romarray, ((int) romarray) + ntohl(romarray[2]),
+#else
+	       (int) &_ebss, (int) memory_start,
+#endif
+		(int) memory_start, (int) memory_end,
+		(int) memory_end, (int) nasys_program_mem_end);
+#endif
+
+	init_mm.start_code = (unsigned long) &_stext;
+	init_mm.end_code = (unsigned long) &_etext;
+	init_mm.end_data = (unsigned long) &_edata;
+	init_mm.brk = (unsigned long) 0; 
+//vic FIXME - this necessary ?
+	init_task.thread.kregs = &fake_regs;
+
+#if 0
+	ROOT_DEV = MKDEV(BLKMEM_MAJOR,0);
+#endif
+
+	/* Keep a copy of command line */
+	*cmdline_p = &command_line[0];
+
+	memcpy(saved_command_line, command_line, sizeof(saved_command_line));
+	saved_command_line[sizeof(saved_command_line)-1] = 0;
+
+#ifdef DEBUG
+	if (strlen(*cmdline_p)) 
+		printk("Command line: '%s'\n", *cmdline_p);
+	else
+		printk("No Command line passed\n");
+#endif
+
+
+#if defined (CONFIG_CS89x0) || (CONFIG_SMC91111)
+	/* now read the hwaddr of the ethernet --wentao*/
+	flash_command(NIOS_FLASH_START, 0x555, 0x88);
+	memcpy(cs8900a_hwaddr_array,(void*)NIOS_FLASH_START,6);
+	exit_se_flash(NIOS_FLASH_START);
+	/* now do the checking, make sure we got a valid addr */
+	if (cs8900a_hwaddr_array[0] & (unsigned char)1)
+	{
+		printk("Invalid ethernet hardware addr, fixed\n");
+		cs8900a_hwaddr_array[0] ^= (unsigned char)1;
+	}
+	cs8900a_hwaddr=cs8900a_hwaddr_array;
+#ifdef DEBUG
+	printk("Setup the hardware addr for ethernet\n\t %02x %02x %02x %02x %02x %02x\n",
+		cs8900a_hwaddr[0],cs8900a_hwaddr[1],
+		cs8900a_hwaddr[2],cs8900a_hwaddr[3],
+		cs8900a_hwaddr[4],cs8900a_hwaddr[5]);
+#endif
+#endif
+
+
+	/*
+	 * give all the memory to the bootmap allocator,  tell it to put the
+	 * boot mem_map at the start of memory
+	 */
+	bootmap_size = init_bootmem_node(
+			NODE_DATA(0),
+			memory_start >> PAGE_SHIFT, /* map goes here */
+			PAGE_OFFSET >> PAGE_SHIFT,	/* 0 on coldfire */
+			memory_end >> PAGE_SHIFT);
+	/*
+	 * free the usable memory,  we have to make sure we do not free
+	 * the bootmem bitmap so we then reserve it after freeing it :-)
+	 */
+	free_bootmem(memory_start, memory_end - memory_start);
+	reserve_bootmem(memory_start, bootmap_size);
+	/*
+	 * get kmalloc into gear
+	 */
+	paging_init();
+#ifdef CONFIG_VT
+#if defined(CONFIG_DUMMY_CONSOLE)
+	conswitchp = &dummy_con;
+#endif
+#endif
+
+#ifdef DEBUG
+	printk("Done setup_arch\n");
+#endif
+
+}
+ 
+int get_cpuinfo(char * buffer)
+{
+    char *cpu, *mmu, *fpu;
+    u_long clockfreq;
+
+    cpu = CPU;
+    mmu = "none";
+    fpu = "none";
+ 
+    clockfreq = nasys_clock_freq;
+
+    return(sprintf(buffer, "CPU:\t\t%s\n"
+		   "MMU:\t\t%s\n"
+		   "FPU:\t\t%s\n"
+		   "Clocking:\t%lu.%1luMHz\n"
+		   "BogoMips:\t%lu.%02lu\n"
+		   "Calibration:\t%lu loops\n",
+		   cpu, mmu, fpu,
+		   clockfreq/1000000,(clockfreq/100000)%10,
+		   (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
+		   (loops_per_jiffy*HZ)));
+
+}
+
+/*
+ *	Get CPU information for use by the procfs.
+ */
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+    char *cpu, *mmu, *fpu;
+    u_long clockfreq, clockfactor=1;
+
+    cpu = CPU;
+    mmu = "none";
+    fpu = "none";
+
+    clockfreq = nasys_clock_freq;
+
+    seq_printf(m, "CPU:\t\t%s\n"
+		   "MMU:\t\t%s\n"
+		   "FPU:\t\t%s\n"
+		   "Clocking:\t%lu.%1luMHz\n"
+		   "BogoMips:\t%lu.%02lu\n"
+		   "Calibration:\t%lu loops\n",
+		   cpu, mmu, fpu,
+		   clockfreq/1000000,(clockfreq/100000)%10,
+		   (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
+		   (loops_per_jiffy*HZ));
+
+	return 0;
+}
+
+static int bcd2char( int x )
+{
+        if ( (x & 0xF) > 0x90 || (x & 0x0F) > 0x09 )
+                return 99;
+
+        return (((x & 0xF0) >> 4) * 10) + (x & 0x0F);
+}
+
+
+
+void arch_gettod(int *year, int *month, int *date, int *hour, int *min, int *sec)
+{
+#ifdef CONFIG_NIOS_SPI
+        /********************************************************************/
+  	/* Read the CMOS clock on the Microtronix Datacom O/S Support card. */
+  	/* Use the SPI driver code, but circumvent the file system by using */
+        /* its internal functions.                                          */
+        /********************************************************************/
+        int  hr;
+
+	struct                               /*********************************/
+        {                                    /* The SPI payload. Warning: the */
+	      unsigned short register_addr;  /* sizeof() operator will return */
+	      unsigned char  value;          /* a length of 4 instead of 3!   */
+        } spi_data;                          /*********************************/
+
+
+	if ( spi_open( NULL, NULL ) )
+	{
+	    printk( "Cannot open SPI driver to read system CMOS clock.\n" );
+	    *year = *month = *date = *hour = *min = *sec = 0;
+	    return;
+	}
+
+	spi_lseek( NULL, clockCS, 0 /* == SEEK_SET */ );
+
+	spi_data.register_addr = clock_write_control;
+	spi_data.value         = 0x40; // Write protect
+	spi_write( NULL, (const char *)&spi_data, 3, NULL  );
+
+	spi_data.register_addr = clock_read_sec;
+	spi_data.value         = 0;
+	spi_read( NULL, (char *)&spi_data, 3, NULL );
+	*sec = (int)bcd2char( spi_data.value );
+
+	spi_data.register_addr = clock_read_min;
+	spi_data.value         = 0;
+	spi_read( NULL, (char *)&spi_data, 3, NULL  );
+	*min = (int)bcd2char( spi_data.value );
+
+	spi_data.register_addr = clock_read_hour;
+	spi_data.value         = 0;
+	spi_read( NULL, (char *)&spi_data, 3, NULL  );
+	hr = (int)bcd2char( spi_data.value );
+	if ( hr & 0x40 )  // Check 24-hr bit
+ 	    hr = (hr & 0x3F) + 12;     // Convert to 24-hr
+
+	*hour = hr;
+
+
+
+	spi_data.register_addr = clock_read_date;
+	spi_data.value         = 0;
+	spi_read( NULL, (char *)&spi_data, 3, NULL  );
+	*date = (int)bcd2char( spi_data.value );
+
+	spi_data.register_addr = clock_read_month;
+	spi_data.value         = 0;
+	spi_read( NULL, (char *)&spi_data, 3, NULL  );
+	*month = (int)bcd2char( spi_data.value );
+
+	spi_data.register_addr = clock_read_year;
+	spi_data.value         = 0;
+	spi_read( NULL, (char *)&spi_data, 3, NULL  );
+	*year = (int)bcd2char( spi_data.value );
+
+
+	spi_release( NULL, NULL );
+#else
+	*year = *month = *date = *hour = *min = *sec = 0;
+
+#endif
+}
+
+static void *cpuinfo_start (struct seq_file *m, loff_t *pos)
+{
+	return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL;
+}
+
+static void *cpuinfo_next (struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return cpuinfo_start (m, pos);
+}
+
+static void cpuinfo_stop (struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+	start:	cpuinfo_start,
+	next:	cpuinfo_next,
+	stop:	cpuinfo_stop,
+	show:	show_cpuinfo
+};
diff -urN linux-2.4.29/arch/niosnommu/kernel/signal.c linux-2.4.29-uc1/arch/niosnommu/kernel/signal.c
--- linux-2.4.29/arch/niosnommu/kernel/signal.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/signal.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,673 @@
+/*
+ *  linux/arch/niosnommu/kernel/signal.c
+ *
+ * Copied/hacked from:
+ */
+
+/*
+ *  linux/arch/m68k/kernel/signal.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * Linux/m68k support by Hamish Macdonald
+ *
+ * 68060 fixes by Jesper Skov
+ *
+ * 1997-12-01  Modified for POSIX.1b signals by Andreas Schwab
+ *
+ * mathemu support by Roman Zippel
+ *  (Note: fpstate in the signal context is completly ignored for the emulator
+ *         and the internal floating point format is put on stack)
+ */
+
+/*
+ * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
+ * Atari :-) Current limitation: Only one sigstack can be active at one time.
+ * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
+ * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
+ * signal handlers!
+ */
+
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/highuid.h>
+#include <linux/personality.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/traps.h>
+#include <asm/ucontext.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage long sys_wait4(pid_t pid, unsigned int * stat_addr, int options,
+			struct rusage * ru);
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int
+do_sigsuspend(old_sigset_t *pmask, struct pt_regs *regs)
+{
+	old_sigset_t mask;
+	sigset_t saveset;
+	
+	if (copy_from_user(&mask, pmask, sizeof(mask)))
+		return -EFAULT;
+		
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->u_regs[UREG_I0] = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+do_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, struct pt_regs *regs)
+{
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->u_regs[UREG_I0] = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int 
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ *
+ */
+
+struct sigframe
+{
+	struct reg_window	sig_window;
+	//char *pretcode;
+	int sig;
+	int code;
+	//struct sigcontext *psc;
+	char retcode[8];
+	unsigned long extramask[_NSIG_WORDS-1];
+	struct sigcontext sc;
+};
+
+struct rt_sigframe
+{
+	struct reg_window	sig_window;
+	//char *pretcode;
+	int sig;
+	//struct siginfo *pinfo;
+	//void *puc;
+	char retcode[8];
+	struct siginfo info;
+	struct ucontext uc;
+};
+
+
+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
+{
+	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+		return -EFAULT;
+	if (from->si_code < 0)
+		return __copy_to_user(to, from, sizeof(siginfo_t));
+	else {
+		int err;
+
+		/* If you change siginfo_t structure, please be sure
+		   this code is fixed accordingly.
+		   It should never copy any pad contained in the structure
+		   to avoid security leaks, but must copy the generic
+		   3 ints plus the relevant union member.  */
+		err = __put_user(from->si_signo, &to->si_signo);
+		err |= __put_user(from->si_errno, &to->si_errno);
+		err |= __put_user((short)from->si_code, &to->si_code);
+		/* First 32bits of unions are always present.  */
+		err |= __put_user(from->si_pid, &to->si_pid);
+		switch (from->si_code >> 16) {
+		case __SI_FAULT >> 16:
+			break;
+		case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+			err |= __put_user(from->si_status, &to->si_status);
+		default:
+			err |= __put_user(from->si_uid, &to->si_uid);
+			break;
+		/* case __SI_RT: This is not generated by the kernel as of now.  */
+		}
+		return err;
+	}
+}
+
+static inline int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc,
+					int *rval_p)
+{
+	int err = 0;
+
+	/* restore the regs from &sc->regs (same as sc, since regs is first)
+	 * (sc is already checked for VERIFY_READ since the sigframe was
+	 *  checked in sys_sigreturn previously)
+	 */
+	if (__copy_from_user(regs, &sc->regs, sizeof(struct pt_regs)))
+		goto badframe;
+
+	regs->sysc_no = -1;		/* disable syscall checks */
+
+	*rval_p=regs->u_regs[UREG_I0];
+	return err;
+
+badframe:
+	return 1;
+}
+
+static inline int
+rt_restore_ucontext(struct pt_regs *regs, /*struct switch_stack *sw,*/
+		    struct ucontext *uc, int *rval_p)
+{
+	int err=0;
+
+	if (__copy_from_user(regs, &uc->uc_mcontext.regs, sizeof(struct pt_regs)))
+		goto badframe;
+
+	regs->sysc_no = -1;		/* disable syscall checks */
+
+	//if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
+	//	goto badframe;
+
+	*rval_p=regs->u_regs[UREG_I0];
+	return err;
+
+badframe:
+	return 1;
+}
+
+
+asmlinkage int do_sigreturn(struct pt_regs *regs)
+{
+	struct sigframe *frame = (struct sigframe *) regs->u_regs [UREG_FP];
+	sigset_t set;
+	int rval;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__get_user(set.sig[0], &frame->sc.oldmask) ||
+	    (_NSIG_WORDS > 1 &&
+	     __copy_from_user(&set.sig[1], &frame->extramask,
+			      sizeof(frame->extramask))))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+	
+	if (restore_sigcontext(regs, &frame->sc, &rval))
+		goto badframe;
+	return rval;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int do_rt_sigreturn(struct pt_regs *regs)
+{
+	struct rt_sigframe *frame = (struct rt_sigframe *) regs->u_regs [UREG_FP];
+	sigset_t set;
+	int rval;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+	
+	if (rt_restore_ucontext(regs, &frame->uc, &rval))
+		goto badframe;
+	return rval;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+/*
+ * Set up a signal frame.
+ */
+
+static int
+setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+			     unsigned long mask)
+{
+	int err = 0;
+
+	/* copy the regs. they are first in sc  */
+	err |= __copy_to_user(&sc->regs, regs, sizeof(struct pt_regs));
+	/* then some other stuff */
+	err |= __put_user(mask, &sc->oldmask);
+
+	return err;
+}
+
+static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
+{
+	int err = 0;
+
+	err |= __copy_to_user(&uc->uc_mcontext.regs, regs, sizeof(struct pt_regs));
+
+	return err;
+}
+
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	unsigned long sp = regs->u_regs[UREG_FP];
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if (ka->sa.sa_flags & SA_ONSTACK) {
+		if (!on_sig_stack(sp))
+			sp = current->sas_ss_sp + current->sas_ss_size;
+	}
+	return (void *)((sp - frame_size) & -4UL);
+}
+
+static void setup_frame (int sig, struct k_sigaction *ka,
+			 sigset_t *set, struct pt_regs *regs)
+{
+	struct sigframe *frame;
+	unsigned long retcode;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+		goto give_sigsegv;
+
+	err |= __put_user((current->exec_domain
+			   && current->exec_domain->signal_invmap
+			   && sig < 32
+			   ? current->exec_domain->signal_invmap[sig]
+			   : sig),
+			  &frame->sig);
+
+	//err |= __put_user(&frame->sc, &frame->psc);
+
+	if (_NSIG_WORDS > 1)
+		err |= copy_to_user(frame->extramask, &set->sig[1],
+				    sizeof(frame->extramask));
+
+	/* for uClinux, we can access directly */
+	err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
+//vic	err |= copy_to_user (&frame->sc, &context, sizeof(context));
+
+
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		regs->u_regs[UREG_I7] = (unsigned long)ka->sa.sa_restorer;
+		//err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
+	} else {
+		regs->u_regs[UREG_I7] = ((unsigned long)(&frame->retcode[0])) >>1;
+		//err |= __put_user(frame->retcode, &frame->pretcode);
+		/* pfx __NR_sigreturn (0x9803)*/
+		err |= __put_user(0x9800 + (__NR_sigreturn >> 5),
+						(short *)(frame->retcode + 0));
+		/* movi %g1,__NR_sigreturn (0x36e1)*/
+		err |= __put_user(0x3401 + ((__NR_sigreturn & 0x1f) << 5),
+						(short *)(frame->retcode + 2));
+	 	/* trap 63 ; syscall (0x793f)*/
+		err |= __put_user(0x793f, (short *)(frame->retcode + 4));
+	 	/* trap 5 ; gdb trap */
+		err |= __put_user(0x7905, (short *)(frame->retcode + 6));
+	}
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up registers for signal handler */
+	regs->u_regs[UREG_FP] = (unsigned long) frame;
+	regs->u_regs[UREG_I0] = sig;
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
+			    sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	err |= __put_user((current->exec_domain
+			   && current->exec_domain->signal_invmap
+			   && sig < 32
+			   ? current->exec_domain->signal_invmap[sig]
+			   : sig),
+			  &frame->sig);
+	//err |= __put_user(&frame->info, &frame->pinfo);
+	//err |= __put_user(&frame->uc, &frame->puc);
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+			  &frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]),
+			  &frame->uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= rt_setup_ucontext(&frame->uc, regs);
+	err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	/* Set up to return from userspace.  */
+	regs->u_regs[UREG_I7] = ((unsigned long)(&frame->retcode[0])) >>1;
+	//err |= __put_user(frame->retcode, &frame->pretcode);
+	/* pfx __NR_rt_sigreturn */
+	err |= __put_user(0x9800 + (__NR_rt_sigreturn >> 5),
+					(short *)(frame->retcode + 0));
+	/* movi %g1,__NR_rt_sigreturn */
+	err |= __put_user(0x3401 + ((__NR_rt_sigreturn & 0x1f) << 5),
+					(short *)(frame->retcode + 2));
+ 	/* trap 63 ; syscall */
+	err |= __put_user(0x793f, (short *)(frame->retcode + 4));
+ 	/* trap 5 ; gdb trap */
+	err |= __put_user(0x7905, (short *)(frame->retcode + 6));
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up registers for signal handler */
+	//vic	wrusp ((unsigned long) frame);
+	regs->u_regs[UREG_FP] = (unsigned long) frame;
+	regs->u_regs[UREG_I0] = sig;
+	regs->u_regs[UREG_I1] = (unsigned long)(&frame->info);
+	regs->u_regs[UREG_I2] = (unsigned long)(&frame->uc);
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static inline void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
+{
+	switch (regs->u_regs[UREG_I0]) {
+	case -ERESTARTNOHAND:
+		if (!has_handler)
+			goto do_restart;
+		regs->u_regs[UREG_I0] = -EINTR;
+		break;
+
+	case -ERESTARTSYS:
+		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
+			regs->u_regs[UREG_I0] = -EINTR;
+			break;
+		}
+	/* fallthrough */
+	case -ERESTARTNOINTR:
+	do_restart:
+		regs->u_regs[UREG_I0] = regs->orig_i0;
+		regs->pc -= 2;
+		break;
+	}
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+			siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
+{
+	/* are we from a system call? */
+	if (regs->sysc_no >= 0)
+		/* If so, check system call restarting.. */
+		handle_restart(regs, ka, 1);
+
+	/* set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sigmask_lock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending(current);
+		spin_unlock_irq(&current->sigmask_lock);
+	}
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals
+ * that the kernel can handle, and then we build all the user-level signal
+ * handling stack-frames in one go after that.
+ */
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
+{
+	siginfo_t info;
+	struct k_sigaction *ka;
+
+//vic	current->thread.esp0 = (unsigned long) regs;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	for (;;) {
+		unsigned long signr;
+
+		spin_lock_irq(&current->sigmask_lock);
+		signr = dequeue_signal(&current->blocked, &info);
+		spin_unlock_irq(&current->sigmask_lock);
+
+		if (!signr)
+			break;
+
+		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+
+			/* Did we come from a system call? */
+			if (regs->sysc_no >= 0) {
+				/* Restart the system call the same way as
+				   if the process were not traced.  */
+				struct k_sigaction *ka =
+					&current->sig->action[signr-1];
+				int has_handler =
+					(ka->sa.sa_handler != SIG_IGN &&
+					 ka->sa.sa_handler != SIG_DFL);
+				handle_restart(regs, ka, has_handler);
+			}
+
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code))
+			    continue;
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+			    continue;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+
+			/* Init gets no signals it doesn't want.  */
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD:	
+			case SIGWINCH: case SIGURG:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP:
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
+					  SA_NOCLDSTOP))
+					notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGIOT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				sigaddset(&current->pending.signal, signr);
+				recalc_sigpending(current);
+				current->flags |= PF_SIGNALED;
+				do_exit(exit_code);
+				/* NOTREACHED */
+			}
+		}
+
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(signr, ka, &info, oldset, regs);
+		return 1;
+	}
+
+	/* Did we come from a system call? */
+	if (regs->sysc_no >= 0)
+		/* Restart the system call - no handlers present */
+		handle_restart(regs, NULL, 0);
+
+	return 0;
+}
diff -urN linux-2.4.29/arch/niosnommu/kernel/start.c linux-2.4.29-uc1/arch/niosnommu/kernel/start.c
--- linux-2.4.29/arch/niosnommu/kernel/start.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/start.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,424 @@
+#include <asm/system.h>
+#include <asm/nios.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <linux/time.h>
+#include "hex.h"
+
+
+
+static void putsNoNewLine( unsigned char *s )
+{
+	while(*s) {
+		while (!(nasys_printf_uart->np_uartstatus & np_uartstatus_trdy_mask));
+		nasys_printf_uart->np_uarttxdata = *s++;
+	}
+}
+
+#define NL "\r\n"
+static void puts(unsigned char *s)
+{
+        putsNoNewLine( s );
+	putsNoNewLine( NL );
+}
+
+#if 0
+static unsigned long testvar = 0xdeadbeef;
+#endif
+	
+
+/******************************************************/
+
+
+#ifdef CONFIG_CRC_CHECK
+extern unsigned long __CRC_Table_Begin;
+
+typedef unsigned char  U8;
+typedef unsigned long  U32;
+
+/* Table of CRC-32's of all single byte values */
+const U32 crc_32_tab[] = {
+   0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+   0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+   0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+   0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+   0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+   0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+   0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+   0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+   0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+   0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+   0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+   0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+   0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+   0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+   0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+   0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+   0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+   0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+   0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+   0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+   0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+   0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+   0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+   0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+   0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+   0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+   0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+   0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+   0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+   0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+   0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+   0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+   0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+   0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+   0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+   0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+   0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+   0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+   0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+   0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+   0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+   0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+   0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+   0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+   0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+   0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+   0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+   0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+   0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+   0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+   0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+   0x2d02ef8dL
+};
+
+U32 Calc_CRC( const U8 *p, U32 len )
+{
+    U32 crc = (U32)~0L;
+    while (len--)
+       crc = crc_32_tab[0xFF & (crc ^ *p++)] ^ (crc >> 8);
+   
+    return crc ^ (U32)~0L;
+}
+
+
+
+/******************************************************/
+
+
+/* hjz: Following time stuff is hacked and modified from uC-libc (various files), which in turn was... */
+/* This is adapted from glibc */
+/* Copyright (C) 1991, 1993 Free Software Foundation, Inc */
+
+#define SECS_PER_HOUR 3600L
+#define SECS_PER_DAY  86400L
+typedef unsigned long time_t;
+
+
+static const unsigned short int __mon_lengths[2][12] = {
+	/* Normal years.  */
+	{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+	/* Leap years.  */
+	{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
+};
+/* This global is exported to the wide world in keeping
+ * with the interface in time.h */
+long int timezone = 0;
+
+static const char *dayOfWeek[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+static const char *month[]     = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+                                   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+/* Nonzero if YEAR is a leap year (every 4 years,
+   except every 100th isn't, and every 400th is).  */
+# define __isleap(year)	((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
+
+struct tm
+{
+  int tm_sec;			/* Seconds.	[0-60] (1 leap second) */
+  int tm_min;			/* Minutes.	[0-59] */
+  int tm_hour;			/* Hours.	[0-23] */
+  int tm_mday;			/* Day.		[1-31] */
+  int tm_mon;			/* Month.	[0-11] */
+  int tm_year;			/* Year	- 1900.  */
+  int tm_wday;			/* Day of week.	[0-6] */
+  int tm_yday;			/* Days in year.[0-365]	*/
+  int tm_isdst;			/* DST.		[-1/0/1]*/
+
+# ifdef	__USE_BSD
+  long int tm_gmtoff;		/* Seconds east of UTC.  */
+  __const char *tm_zone;	/* Timezone abbreviation.  */
+# else
+  long int __tm_gmtoff;		/* Seconds east of UTC.  */
+  __const char *__tm_zone;	/* Timezone abbreviation.  */
+# endif
+};
+
+void  __tm_conv(struct tm *tmbuf, time_t *t, time_t offset)
+{
+	long days, rem;
+	register int y;
+	register const unsigned short int *ip;
+
+	timezone = -offset;
+
+	days = *t / SECS_PER_DAY;
+	rem = *t % SECS_PER_DAY;
+	rem += offset;
+	while (rem < 0)
+        {
+	    rem += SECS_PER_DAY;
+	    days--;
+	}
+	while (rem >= SECS_PER_DAY)
+        {
+	    rem -= SECS_PER_DAY;
+	    days++;
+	}
+
+	tmbuf->tm_hour = rem / SECS_PER_HOUR;
+	rem           %= SECS_PER_HOUR;
+	tmbuf->tm_min  = rem / 60;
+	tmbuf->tm_sec  = rem % 60;
+
+	/* January 1, 1970 was a Thursday.  */
+	tmbuf->tm_wday = (4 + days) % 7;
+	if (tmbuf->tm_wday < 0)
+	    tmbuf->tm_wday += 7;
+
+	y = 1970;
+	while (days >= (rem = __isleap(y) ? 366 : 365))
+        {
+	    y++;
+	    days -= rem;
+	}
+
+	while (days < 0)
+        {
+	    y--;
+	    days += __isleap(y) ? 366 : 365;
+	}
+
+	tmbuf->tm_year = y - 1900;
+	tmbuf->tm_yday = days;
+
+	ip = __mon_lengths[__isleap(y)];
+	for (y = 0; days >= ip[y]; ++y)
+	    days -= ip[y];
+
+	tmbuf->tm_mon   = y;
+	tmbuf->tm_mday  = days + 1;
+	tmbuf->tm_isdst = -1;
+}
+
+
+
+/* hjz: NOT your traditional ctime: This one includes timezone */
+/* (UTC) and excludes the traditional trailing newline.        */
+char *CTime( time_t *t )
+{
+    static char theTime[29];
+    struct tm tm;
+
+    __tm_conv( &tm, t, 0 );
+    sprintf( theTime, "%s %s %02d %02d:%02d:%02d UTC %04d",
+             dayOfWeek[tm.tm_wday], month[tm.tm_mon], tm.tm_mday,
+	     tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year + 1900 );
+
+    return theTime;
+}
+
+/******************************************************/
+
+
+/* hjz: polled-I/O: Get a char if one is ready, or return -1 */
+int getc( void )
+{
+    if ( nasys_printf_uart->np_uartstatus & np_uartstatus_rrdy_mask )
+        return nasys_printf_uart->np_uartrxdata;
+    else
+      return -1;
+}
+
+
+typedef unsigned long off_t;
+typedef struct
+{
+    U8    *startAddr;
+    U8    *endAddr;
+    U32    CRC;
+    time_t mtime;
+    off_t  size;    // File size
+    char id[44];    // Filename. If path exceeds available size, name is "..." + last 40 chars of given filename
+    char host[32];  // hostname. If name exceeds available size name is first 28 chars of hostname + "..."
+} FLASH_REGION_DESC;
+
+
+int  Test_Flash_Regions(void)
+{
+    FLASH_REGION_DESC *pRegion = (FLASH_REGION_DESC *)&__CRC_Table_Begin;
+    U32  crc;
+    char cBuff[256];
+    int  nrFailedRegions = 0;
+    int  regionStatus;
+    int  i;
+    unsigned int startAddr = (int) pRegion->startAddr;
+    unsigned int endAddr = (int) pRegion->endAddr;
+
+    puts( "***Checking flash CRC's" );
+    if ( (startAddr == -1) || (startAddr >= endAddr) 
+     || !( ((startAddr >= (int) NIOS_FLASH_START) && (endAddr < (int) NIOS_FLASH_END))
+           || ((startAddr >= (int) na_flash)     && (endAddr < (int) na_flash_end)) ) )
+    {
+	puts( "   No Flash regions defined." );
+        return -1;
+    }
+
+
+    for ( i = 0; pRegion->startAddr && pRegion->startAddr != (U8 *)~0L; pRegion++, i++ )
+    {
+        crc = Calc_CRC( pRegion->startAddr, pRegion->endAddr - pRegion->startAddr );
+	if ( crc != pRegion->CRC )
+	{
+	    regionStatus = 1;
+	    nrFailedRegions++;
+	}
+	else
+	    regionStatus = 0;
+
+        sprintf( cBuff, "   Region %d: 0x%08lX - 0x%08lX, CRC = 0x%08lX --> %s" NL
+                        "        From file `%s' on host `%s'" NL
+		        "        Dated %s, size = %lu bytes",
+                 i, (U32)pRegion->startAddr, (U32)pRegion->endAddr, pRegion->CRC,
+		 regionStatus ? "***Failed" : "Passed",
+                 pRegion->id, pRegion->host, CTime( &pRegion->mtime ), pRegion->size
+               );
+	puts( cBuff );
+    }
+
+    return nrFailedRegions;
+}
+#endif /* CONFIG_CRC_CHECK */
+
+
+int main(void) {
+	extern void start_kernel(void);
+
+#if 0
+	extern unsigned long __data_rom_start;
+	extern unsigned long __data_start;
+	extern unsigned long __data_end;
+	extern unsigned long __bss_start;
+	extern unsigned long __bss_end;
+
+	unsigned long *src;
+	unsigned long *dest;
+	unsigned long tmp;
+#endif
+
+
+#ifdef DEBUG
+	puts("MAIN: starting c\n");
+#endif
+
+#ifdef CONFIG_KGDB				/* builtin GDB stub */
+
+/* Set up GDB stub, and make the first trap into it */
+	nios_gdb_install(1); 
+#ifdef CONFIG_BREAK_ON_START
+	puts( "MAIN: trapping to debugger - make sure nios-elf-gdb is running on host." );
+	nios_gdb_breakpoint(); 
+	nop();
+#endif
+
+#endif	/* CONFIG_KGDB */
+
+
+#if 0
+	puts("Testing RAM\n");
+
+	puts("Write...\n");
+	for (dest = (unsigned long *)0x40000000; dest < (unsigned long *)0x40080000; dest++) {
+		*dest = (unsigned long)0x5a5a5a5a ^ (unsigned long)dest;
+	}
+ 
+	puts("Read...\n");
+	for (dest = (unsigned long *)0x40000000; dest < (unsigned long *)0x40080000; dest++) {
+		tmp = (unsigned long)0x5a5a5a5a ^ (unsigned long)dest;
+		if (*dest != tmp) {
+			puts("Failed.");
+			outhex32((unsigned long)dest);
+			puts("is");
+			outhex32(*dest);
+			puts("wrote");
+			outhex32(tmp);
+			while(1);
+		}
+	}
+ 
+	puts("512k RAM\n");
+	if (testvar == 0xdeadbeef) puts("Found my key\n");
+	else puts("My keys are missing!\n");
+
+	src = &__data_rom_start;
+	dest = &__data_start;
+	while (dest < &__data_end) *(dest++) = *(src++);
+
+	dest = &__bss_start;
+	while (dest < &__bss_end) *(dest++) = 0;
+
+	puts("Moved .data\n");
+	if (testvar == 0xdeadbeef) puts("Found my key\n");
+	else puts("My keys are missing!\n");
+
+	testvar = 0;
+#endif
+
+
+#ifdef CONFIG_CRC_CHECK
+    #ifdef CONFIG_PROMPT_ON_MISSING_CRC_TABLES
+	if ( Test_Flash_Regions() )
+    #else
+	if ( Test_Flash_Regions() > 0 )
+    #endif
+	{
+	    int  c;
+            char tmp[3];
+	    while ( getc() != -1 ) // flush input
+	        ;
+
+	    putsNoNewLine( "   Do you wish to continue (Y/N) ?  " );
+	    while ( 1 )
+	    {
+	        c = getc();
+		if ( c == -1 )
+		    continue;
+
+		if ( !isprint( c ) )
+		    c = '?';
+
+	        sprintf( tmp, "\b%c", c );
+	        putsNoNewLine( tmp );
+		c = toupper( c );
+                if ( c == 'Y' )
+		{
+		    puts( "" );
+		    break;
+                }
+
+		if ( c == 'N' )
+		{
+		    puts( NL "***Trapping to monitor..." );
+		    return -1;
+		}
+	    }
+        }
+	puts( "***Starting kernel..." );
+
+#endif
+
+	start_kernel();
+	return 0;
+}
+
diff -urN linux-2.4.29/arch/niosnommu/kernel/switch.S linux-2.4.29-uc1/arch/niosnommu/kernel/switch.S
--- linux-2.4.29/arch/niosnommu/kernel/switch.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/switch.S	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,80 @@
+//vic - change use of current_set to just current - needs verification
+/*
+ * Feb 26, 2001 Ken Hill
+ *	Port to Nios architecture
+ *
+ * switch.S: Sparc task switch code.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <asm/cprefix.h>
+#include <asm/psr.h>
+#include <asm/asmmacro.h>
+#include <asm/niosasm.h>
+//vic#include <asm/ptrace.h>
+#include <asm/winmacro.h>
+
+#include "nios_defs.h"
+
+#define sw_ntask     g0
+#define sw_tmp       g1
+#define sw_psr       g2
+#define sw_epsr      g3
+
+/* Context switch code.  The new process's task_struct
+ * ptr is passed as the first parameter.
+ *
+ * First successful task switch 05/13/95 21:52:37
+ */
+	.align 4
+	.globl	C_LABEL(nios_switch_to)
+C_LABEL(nios_switch_to):
+	mov	%sw_ntask, %o1
+
+	/* Save kernel state. */
+	
+	pfx	8
+	wrctl	%g5				; disable interrupts
+	 nop
+	 nop
+
+	FLUSH_WINDOWS				/* flush reg file to stack */
+
+	MOVIA	%sw_epsr, nios_status		/* get STATUS extension ptr */
+	rdctl	%sw_psr				/* read STATUS (IE=0) */
+	ANDIP	%sw_psr, 0xffff			/* clear upper */
+	ld	%sw_tmp, [%sw_epsr]		/* get STATUS extension */
+	ANDNIP	%sw_tmp, 0xffff			/* clear lower */
+	or	%sw_psr, %sw_tmp
+	mov	%sw_tmp, %o0			/* get 'prev' task ptr */
+	STBO	%sw_tmp, (TASK_THREAD+THREAD_KPSR), %sw_psr	/* save STATUS & ESTATUS  */
+	STBO	%sw_tmp, (TASK_THREAD+THREAD_KSP), %sp	/* save current stack ptr */
+	STBO	%sw_tmp, (TASK_THREAD+THREAD_KPC), %o7	/* save current return pc */
+
+	/* Load new kernel state. */
+
+	MOVIA	%sw_tmp,C_LABEL(_current_task)	/* set new task as current */
+	st	[%sw_tmp], %sw_ntask
+	LDBO	%sw_psr, %sw_ntask, (TASK_THREAD+THREAD_KPSR)	/* get saved STATUS & ESTATUS */
+	ANDNIP	%sw_psr, PSR_IE			/* Clear IE bit */
+	wrctl	%sw_psr				/* set new STATUS (IE=0) */
+	 nop
+	 nop
+	ANDNIP	%sw_psr, 0xffff			/* clear lower */
+	st	[%sw_epsr], %sw_psr		/* set new STATUS extension */
+	LDBO	%sp, %sw_ntask, (TASK_THREAD+THREAD_KSP)	/* set new stack ptr */
+	LDBO	%o7, %sw_ntask, (TASK_THREAD+THREAD_KPC)	/* set new return pc */
+
+	FILL_WINDOWS				/* fill reg file from stack */
+
+	pfx	9				/* Ok to interrupt now */
+	wrctl	%g0
+
+	lret
+	 nop
+
+
+
+
+
diff -urN linux-2.4.29/arch/niosnommu/kernel/sys_nios.c linux-2.4.29-uc1/arch/niosnommu/kernel/sys_nios.c
--- linux-2.4.29/arch/niosnommu/kernel/sys_nios.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/sys_nios.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,239 @@
+/*
+ * linux/arch/m68k/kernel/sys_m68k.c
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/m68k
+ * platform.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/traps.h>
+#include <asm/ipc.h>
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+asmlinkage int sys_pipe(unsigned long * fildes)
+{
+	int fd[2];
+	int error;
+
+	error = do_pipe(fd);
+	if (!error) {
+		if (copy_to_user(fildes, fd, 2*sizeof(int)))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+/* common code for old and new mmaps */
+static inline long do_mmap2(
+	unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	int error = -EBADF;
+	struct file * file = NULL;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (!(flags & MAP_ANONYMOUS)) {
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
+/*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
+ * handle more than 4 system call parameters, so these system calls
+ * used a memory block for parameter passing..
+ */
+
+struct mmap_arg_struct {
+	unsigned long addr;
+	unsigned long len;
+	unsigned long prot;
+	unsigned long flags;
+	unsigned long fd;
+	unsigned long offset;
+};
+
+asmlinkage int old_mmap(struct mmap_arg_struct *arg)
+{
+	struct mmap_arg_struct a;
+	int error = -EFAULT;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		goto out;
+
+	error = -EINVAL;
+	if (a.offset & ~PAGE_MASK)
+		goto out;
+
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+out:
+	return error;
+}
+
+extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+
+struct sel_arg_struct {
+	unsigned long n;
+	fd_set *inp, *outp, *exp;
+	struct timeval *tvp;
+};
+
+asmlinkage int old_select(struct sel_arg_struct *arg)
+{
+	struct sel_arg_struct a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+	/* sys_select() does the appropriate kernel locking */
+	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
+}
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+asmlinkage int sys_ipc (uint call, int first, int second,
+			int third, void *ptr, long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	if (call <= SEMCTL)
+		switch (call) {
+		case SEMOP:
+			return sys_semop (first, (struct sembuf *)ptr, second);
+		case SEMGET:
+			return sys_semget (first, second, third);
+		case SEMCTL: {
+			union semun fourth;
+			if (!ptr)
+				return -EINVAL;
+			if (get_user(fourth.__pad, (void **) ptr))
+				return -EFAULT;
+			return sys_semctl (first, second, third, fourth);
+			}
+		default:
+			return -EINVAL;
+		}
+	if (call <= MSGCTL) 
+		switch (call) {
+		case MSGSND:
+			return sys_msgsnd (first, (struct msgbuf *) ptr, 
+					  second, third);
+		case MSGRCV:
+			switch (version) {
+			case 0: {
+				struct ipc_kludge tmp;
+				if (!ptr)
+					return -EINVAL;
+				if (copy_from_user (&tmp,
+						    (struct ipc_kludge *)ptr,
+						    sizeof (tmp)))
+					return -EFAULT;
+				return sys_msgrcv (first, tmp.msgp, second,
+						   tmp.msgtyp, third);
+				}
+			default:
+				return sys_msgrcv (first,
+						   (struct msgbuf *) ptr,
+						   second, fifth, third);
+			}
+		case MSGGET:
+			return sys_msgget ((key_t) first, second);
+		case MSGCTL:
+			return sys_msgctl (first, second,
+					   (struct msqid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+
+	if (call <= SHMCTL) 
+		switch (call) {
+		case SHMAT:
+			switch (version) {
+			default: {
+				ulong raddr;
+				ret = sys_shmat (first, (char *) ptr,
+						 second, &raddr);
+				if (ret)
+					return ret;
+				return put_user (raddr, (ulong *) third);
+			}
+			}
+		case SHMDT: 
+			return sys_shmdt ((char *)ptr);
+		case SHMGET:
+			return sys_shmget (first, second, third);
+		case SHMCTL:
+			return sys_shmctl (first, second,
+					   (struct shmid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+	return -EINVAL;
+}
+
+asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
+{
+  return -ENOSYS;
+}
+
+sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
+{ }
+
+asmlinkage int sys_getpagesize(void)
+{
+	return PAGE_SIZE;
+}
+
+/*
+ * Old cruft
+ */
+asmlinkage int sys_pause(void)
+{
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	return -ERESTARTNOHAND;
+}
diff -urN linux-2.4.29/arch/niosnommu/kernel/time.c linux-2.4.29-uc1/arch/niosnommu/kernel/time.c
--- linux-2.4.29/arch/niosnommu/kernel/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/time.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,129 @@
+/*
+ *  linux/arch/niosnommu/kernel/time.c
+ *
+ *  Copyright (C) 1998-2000  D. Jeff Dionne <jeff@uClinux.org>,
+ *                           Kenneth Albanowski <kjahds@kjahds.com>,
+ *
+ *  Copied/hacked from:
+ *
+ *  linux/arch/m68knommu/kernel/time.c
+ *
+ *  Copied/hacked from:
+ *
+ *  linux/arch/m68k/kernel/time.c
+ *
+ *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *
+ * This file contains the m68k-specific time handling details.
+ * Most of the stuff is located in the machine specific files.
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/nios.h>
+
+#include <linux/timex.h>
+
+
+static inline int set_rtc_mmss(unsigned long nowtime)
+{
+  return -1;
+}
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
+{
+	/* last time the cmos clock got updated */
+	static long last_rtc_update=0;
+	
+
+	do_timer(regs);
+
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec > 500000 - (tick >> 1) &&
+	    xtime.tv_usec < 500000 + (tick >> 1)) {
+	  if (set_rtc_mmss(xtime.tv_sec) == 0)
+	    last_rtc_update = xtime.tv_sec;
+	  else
+	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	}
+
+}
+
+void time_init(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+
+	extern void arch_gettod(int *year, int *mon, int *day, int *hour,
+				int *min, int *sec);
+
+	arch_gettod(&year, &mon, &day, &hour, &min, &sec);
+
+	if ((year += 1900) < 1970)
+		year += 100;
+	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+	xtime.tv_usec = 0;
+
+	request_irq(na_timer0_irq, timer_interrupt, IRQ_FLG_LOCK, "timer", NULL);
+
+	na_timer0->np_timerperiodl = (nasys_clock_freq/HZ)-1;
+	na_timer0->np_timerperiodh = ((nasys_clock_freq/HZ)-1) >> 16;
+
+	/* interrupt enable + continuous + start */
+	na_timer0->np_timercontrol = np_timercontrol_start_mask
+										+ np_timercontrol_cont_mask
+										+ np_timercontrol_ito_mask;
+}
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned long flags;
+	
+	save_flags(flags);
+	cli();
+	*tv = xtime;
+	restore_flags(flags);
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+	cli();
+	/* This is revolting. We need to set the xtime.tv_usec
+	 * correctly. However, the value in this location is
+	 * is value at the last tick.
+	 * Discover what correction gettimeofday
+	 * would have done, and then undo it!
+	 */
+
+	if (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+
+	xtime = *tv;
+	time_state = TIME_BAD;
+	time_maxerror = MAXPHASE;
+	time_esterror = MAXPHASE;
+	sti();
+}
+
diff -urN linux-2.4.29/arch/niosnommu/kernel/traps.c linux-2.4.29-uc1/arch/niosnommu/kernel/traps.c
--- linux-2.4.29/arch/niosnommu/kernel/traps.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/kernel/traps.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,124 @@
+/*FIXME - some unimplemented stuff to do */
+
+/*
+ * arch/niosnommu/kernel/traps.c
+ *
+ * Copyright 2001 Vic Phillips
+ *
+ * hacked from:
+ *
+ * arch/sparcnommu/kernel/traps.c
+ *
+ * Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <linux/sched.h>  /* for jiffies */
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/signal.h>
+
+#include <asm/delay.h>
+#include <asm/system.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/unistd.h>
+#include <asm/traps.h>
+
+#include <asm/nios.h>
+#include "hex.h"
+
+/* #define TRAP_DEBUG */
+
+static void puts(unsigned char *s) {
+	while(*s) {
+		while (!(nasys_printf_uart->np_uartstatus & np_uartstatus_trdy_mask));
+		nasys_printf_uart->np_uarttxdata = *s++;
+	}
+	while (!(nasys_printf_uart->np_uartstatus & np_uartstatus_trdy_mask));
+	nasys_printf_uart->np_uarttxdata = '\r';
+	while (!(nasys_printf_uart->np_uartstatus & np_uartstatus_trdy_mask));
+	nasys_printf_uart->np_uarttxdata = '\n';
+}
+
+#if 0
+void dumpit(unsigned long l1, unsigned long l2)
+{
+	outhex32(l1);
+	puts("l1");
+	outhex32(l2);
+	puts("l2");
+	while(1);
+}
+
+struct trap_trace_entry {
+	unsigned long pc;
+	unsigned long type;
+};
+
+int trap_curbuf = 0;
+struct trap_trace_entry trapbuf[1024];
+
+void syscall_trace_entry(struct pt_regs *regs)
+{
+	printk("%s[%d]: ", current->comm, current->pid);
+	printk("scall<%d> (could be %d)\n", (int) regs->u_regs[UREG_G1],
+	       (int) regs->u_regs[UREG_I0]);
+}
+
+void syscall_trace_exit(struct pt_regs *regs)
+{
+}
+#endif
+
+void die_if_kernel(char *str, struct pt_regs *pregs)
+{
+	unsigned long pc;
+
+	pc = pregs->pc;
+	puts("");
+	outhex32(pc);
+	puts(" trapped to die_if_kernel");
+	show_regs(pregs);
+#if 0
+	if(pregs->psr & PSR_SUPERVISOR)
+		do_exit(SIGKILL);
+	do_exit(SIGSEGV);
+#endif
+}
+
+void do_hw_interrupt(unsigned long type, unsigned long psr, unsigned long pc)
+{
+	if(type < 0x10) {
+		printk("Unimplemented Nios TRAP, type = %02lx\n", type);
+		die_if_kernel("Whee... Hello Mr. Penguin", current->thread.kregs);
+	}	
+#if 0
+	if(type == SP_TRAP_SBPT) {
+		send_sig(SIGTRAP, current, 1);
+		return;
+	}
+	current->thread.sig_desc = SUBSIG_BADTRAP(type - 0x80);
+	current->thread.sig_address = pc;
+	send_sig(SIGILL, current, 1);
+#endif
+}
+
+#if 0
+void handle_watchpoint(struct pt_regs *regs, unsigned long pc, unsigned long psr)
+{
+#ifdef TRAP_DEBUG
+	printk("Watchpoint detected at PC %08lx PSR %08lx\n", pc, psr);
+#endif
+	if(psr & PSR_SUPERVISOR)
+		panic("Tell me what a watchpoint trap is, and I'll then deal "
+		      "with such a beast...");
+}
+#endif
+
+void trap_init(void)
+{
+#ifdef DEBUG
+	printk("trap_init reached\n");
+#endif
+}
diff -urN linux-2.4.29/arch/niosnommu/lib/checksum.c linux-2.4.29-uc1/arch/niosnommu/lib/checksum.c
--- linux-2.4.29/arch/niosnommu/lib/checksum.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/lib/checksum.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,148 @@
+#include <net/checksum.h>
+#include <asm/checksum.h>
+
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
+{
+#if 0
+	__asm__ __volatile__("
+		movi	%%g5, 0		; g5 = result
+		cmpi	%1, 0
+		skps	cc_hi
+		br	9f
+		mov	%%g7, %0
+		skp1	%%g7, 0		; g7 = odd
+		br	1f
+		 nop
+		subi	%1, 1		; if(odd) { result = *buff;
+		ld	%%g5, [%0]	;           len--;
+		ext8d	%%g5, %0	;	    postion byte (bits 0..7)
+        lsli    %%g5, 8     ; little endian
+		addi	%0, 1		;           buff++ }
+1:
+		mov	%%g6, %1
+		lsri	%%g6, 1	        ; g6 = count = (len >> 1)
+		cmpi	%%g6, 0		; if (count) {
+		skps	cc_nz
+		br	8f
+		 nop
+		skp1	%0, 1		; if (2 & buff) {
+		br	1f
+		 nop
+		subi	%1, 2		;	result += *(unsigned short *) buff;
+		ld	%%g1, [%0]	;	count--; 
+		ext16d	%%g1, %0	;	postion half word (bits 0..15)
+		subi	%%g6, 1		;	len -= 2;
+		add	%%g5, %%g1	;	buff += 2; 
+		addi	%0, 2		; }
+1:
+		lsri	%%g6, 1		; Now have number of 32 bit values
+		cmpi	%%g6, 0		; if (count) {
+		skps	cc_nz
+		br	2f
+		 nop
+1:						; do {
+		ld	%%g1, [%0]		; csum aligned 32bit words
+		addi	%0, 4
+		add	%%g5, %%g1
+		skps	cc_nc
+		addi	%%g5, 1			; add carry
+		subi	%%g6, 1
+		skps	cc_z
+		br	1b			; } while (count)
+		 nop
+		mov	%%g2, %%g5
+		lsri	%%g2, 16
+		ext16s	%%g5, 0		       	; g5 & 0x0000ffff
+		add	%%g5, %%g2	; }
+2:
+		skp1	%1, 1		; if (len & 2) {
+		br	8f
+		 nop
+		ld	%%g1, [%0]	;	result += *(unsigned short *) buff; 
+		ext16d	%%g1, %0	;	position half word (bits 0..15)
+		add	%%g5, %%g1	;	buff += 2; 
+		addi	%0, 2		; }
+8:
+		skp1	%1, 0		; if (len & 1) {
+		br	1f
+		 nop
+		ld	%%g1, [%0]
+		ext8d	%%g1, %0	;	position byte (bits 0..7)
+		add	%%g5, %%g1	; }	result += (*buff); 
+1:
+		mov	%%g1, %%g5
+		lsli	%%g1, 16
+		add	%%g5, %%g1	; result = from32to16(result);
+		lsri	%%g5, 16
+		skps	cc_nc
+		addi	%%g5, 1		; add carry
+		skp1	%%g7, 0		; if(odd) {
+		br	9f
+		 nop
+		mov	%%g2, %%g5	;	result = ((result >> 8) & 0xff) |
+                pfx     %%hi(0xff)
+		and	%%g2, %%lo(0xff);	((result & 0xff) << 8);
+		lsli	%%g2, 8
+		lsri	%%g5, 8
+		or	%%g5, %%g2	; }
+9:
+		add	%2, %%g5	; add result and sum with carry
+		skps	cc_nc
+		addi	%2, 1		; add carry
+		mov	%%g5,%2		; result = from32to16(result)
+		lsli	%%g5,16
+		add	%2,%%g5
+		lsri	%2,16
+		skps	cc_nc
+		addi	%2, 1
+	" 
+	:"=&r" (buff), "=&r" (len), "=&r" (sum)
+	:"0" (buff), "1" (len), "2" (sum)
+	:"g1", "g2", "g5", "g6", "g7"); 
+
+
+	return sum;
+#else
+	unsigned int result = do_csum(buff, len);
+
+	/* add in old sum, and carry.. */
+	result += sum;
+	if (sum > result)
+		result += 1;
+	return result;
+#endif
+}
+
+
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+
+/*
+ * the same as csum_partial, but copies from fs:src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum)
+{
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+
+}
diff -urN linux-2.4.29/arch/niosnommu/lib/COPYING.LIB linux-2.4.29-uc1/arch/niosnommu/lib/COPYING.LIB
--- linux-2.4.29/arch/niosnommu/lib/COPYING.LIB	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/lib/COPYING.LIB	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,481 @@
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+                    675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it.  You can use it for
+your libraries, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library.  If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software.  To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+  Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs.  This
+license, the GNU Library General Public License, applies to certain
+designated libraries.  This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+  The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it.  Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program.  However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+  Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries.  We
+concluded that weaker conditions might promote sharing better.
+
+  However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves.  This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them.  (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.)  The hope is that this
+will lead to faster development of free libraries.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+  Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License").  Each licensee is
+addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    c) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    d) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+     Appendix: How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff -urN linux-2.4.29/arch/niosnommu/lib/Makefile linux-2.4.29-uc1/arch/niosnommu/lib/Makefile
--- linux-2.4.29/arch/niosnommu/lib/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/lib/Makefile	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,11 @@
+# 
+# Makefile for Nios library files..
+#
+
+.S.o:
+	$(CC) $(AFLAGS) -D__ASSEMBLY__ -traditional -c $< -o $@
+
+L_TARGET := lib.a
+obj-y  =checksum.o string.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/niosnommu/lib/string.c linux-2.4.29-uc1/arch/niosnommu/lib/string.c
--- linux-2.4.29/arch/niosnommu/lib/string.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/lib/string.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,167 @@
+#include <linux/types.h>
+#include <linux/autoconf.h>
+#include <asm/string.h>
+
+#ifdef __HAVE_ARCH_MEMSET
+void * memset(void * s,int c,size_t count)
+{
+
+    if (count > 8) {
+	int dummy0, dummy1, dummy2;
+	__asm__ __volatile__ (
+	 /* memset a char to make s word-aligned */
+	 "skp1	%0, 0\n\t"
+	 "br	1f\n\t"
+	 "fill8 %%r0, %3\n\t"	/* delay slot */
+	 "dec	%1\n\t"
+	 "st8d  [%0], %%r0\n\t"
+	 "inc	%0\n\t"
+
+	 /* memset a word to make s dword-aligned */
+	 "1: skp1	%0, 1\n\t"
+	 "br	2f\n\t"
+	 "mov	%2, %1\n\t"		/* delay slot */
+	 "subi	%1, 2\n\t"
+	 "st16d [%0], %%r0\n\t"
+	 "addi  %0,   2\n\t"
+
+	 /* %2 is how many dwords to set */
+	 "mov	%2, %1\n\t"
+	 "2:lsri	%2, 2\n\t"
+
+	 /* store dwords */
+	 "3:st	[%0], %%r0\n\t"
+	 "dec	%2\n\t"
+	 "skprz	%2\n\t"
+	 "br	3b\n\t"
+	 "addi	%0, 4\n\t"		/* delay slot */
+
+	 /* store a word if necessary*/
+	 "skp1	%1, 1\n\t"
+	 "br	4f\n\t"
+	 "nop\n\t"
+	 "st16d [%0], %%r0\n\t"
+	 "addi	%0, 2\n\t"
+
+	 /* store a char if necessary*/
+	 "4:skp0 %1, 0\n\t"
+	 "st8d  [%0], %%r0\n\t"
+
+	:"=r"(dummy0), "=r" (dummy1), "=r" (dummy2)
+	:"r" (c), "0" (s), "1" (count)
+	:"r0", "memory");
+	}
+	else {
+	char* xs=(char*)s;
+	while (count--)
+		*xs++ = c;
+	}
+	return s;
+}
+#endif
+
+#ifdef __HAVE_ARCH_MEMCPY
+void * memcpy(void * d, const void * s, size_t count)
+{
+    unsigned long dst, src;
+	dst = (unsigned long) d;
+	src = (unsigned long) s;
+
+	if ((count < 8) || ((dst ^ src) & 3))
+	    goto restup;
+
+	if (dst & 1) {
+		*(char*)dst++=*(char*)src++;
+	    count--;
+	}
+	if (dst & 2) {
+		*(short*)dst=*(short*)src;
+	    src += 2;
+	    dst += 2;
+	    count -= 2;
+	}
+	while (count > 3) {
+		*(long*)dst=*(long*)src;
+	    src += 4;
+	    dst += 4;
+	    count -= 4;
+	}
+
+    restup:
+	while (count--)
+		*(char*)dst++=*(char*)src++;
+
+	return d;
+} 
+#endif
+
+#ifdef __HAVE_ARCH_MEMMOVE
+void * memmove(void * d, const void * s, size_t count)
+{
+    unsigned long dst, src;
+
+    if (d < s) {
+	dst = (unsigned long) d;
+	src = (unsigned long) s;
+
+	if ((count < 8) || ((dst ^ src) & 3))
+	    goto restup;
+
+	if (dst & 1) {
+		*(char*)dst++=*(char*)src++;
+	    count--;
+	}
+	if (dst & 2) {
+		*(short*)dst=*(short*)src;
+	    src += 2;
+	    dst += 2;
+	    count -= 2;
+	}
+	while (count > 3) {
+		*(long*)dst=*(long*)src;
+	    src += 4;
+	    dst += 4;
+	    count -= 4;
+	}
+
+    restup:
+	while (count--)
+		*(char*)dst++=*(char*)src++;
+    } else {
+	dst = (unsigned long) d + count;
+	src = (unsigned long) s + count;
+
+	if ((count < 8) || ((dst ^ src) & 3))
+	    goto restdown;
+
+	if (dst & 1) {
+	    src--;
+	    dst--;
+	    count--;
+		*(char*)dst=*(char*)src;
+	}
+	if (dst & 2) {
+	    src -= 2;
+	    dst -= 2;
+	    count -= 2;
+		*(short*)dst=*(short*)src;
+	}
+	while (count > 3) {
+	    src -= 4;
+	    dst -= 4;
+	    count -= 4;
+		*(long*)dst=*(long*)src;
+	}
+
+    restdown:
+	while (count--) {
+	    src--;
+	    dst--;
+		*(char*)dst=*(char*)src;
+	}
+    }
+
+    return d;	
+
+}
+#endif
\ No newline at end of file
diff -urN linux-2.4.29/arch/niosnommu/Makefile linux-2.4.29-uc1/arch/niosnommu/Makefile
--- linux-2.4.29/arch/niosnommu/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/Makefile	2005-06-14 02:11:08.000000000 +0100
@@ -0,0 +1,72 @@
+# arch/niosnommu/Makefile
+#
+# Makefile for the architecture dependent flags and dependencies on the
+# nios.
+#
+# Copyright (C) 2001 Vic Phillips (vic@microtronix.com)
+#
+# based on sparcnommu/Makefile:
+#
+# Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+#
+KERNELLOAD = ${shell echo `grep "nasys_program_mem " include/asm/nios.h | sed 's/^.*\*)//' | sed 's/)//'`}
+
+CFLAGS := $(CFLAGS) -m32 -DNO_MM -pipe -D__linux__ -D__ELF__ -g
+CFLAGS := $(CFLAGS) -funaligned-struct-hack -mno-zero-extend
+
+# Uncomment this if you are doing gdb source level
+# debugging of the kernel to get the proper debugging information.
+#
+#CFLAGS := $(CFLAGS) -DDEBUG
+
+# This undefines the "__init" type used in defining initialization
+# procedures.  When defined, the procedures are put into an 'init' data
+# section that GDB doesn't recognize as source.
+#
+CFLAGS := $(CFLAGS) -DNO_TEXT_SECTIONS
+
+AFLAGS := $(AFLAGS) -m32 -DNO_MM -funaligned-struct-hack -g
+
+LINKFLAGS = -T arch/niosnommu/ram.ld -Ttext $(KERNELLOAD)
+
+# add this to avoid multiple '_stack' and '_vecbase' definition errors
+#
+ifdef niosgnu
+# Include the path to the lib directory where the ldscripts are found to fix
+# a problem with the cygwin/bash environment.
+LDSCRIPTS:=$(shell nios-elf-gcc -print-file-name=ldscripts)
+EXTRA_LDFLAGS := -melfnios32 -L $(LDSCRIPTS)/..
+else
+EXTRA_LDFLAGS = -melfnios32
+endif
+export EXTRA_LDFLAGS
+
+# vic - add this to get name of nios gcc library
+GCCLIB	:= `$(CC) -m32 --print-libgcc-file-name`
+
+HEAD := arch/niosnommu/kernel/head.o
+
+SUBDIRS := $(SUBDIRS) arch/niosnommu/kernel arch/niosnommu/lib arch/niosnommu/mm
+
+CORE_FILES := arch/niosnommu/kernel/kernel.o arch/niosnommu/mm/mm.o $(CORE_FILES)
+
+LIBS := $(LIBS) $(GCCLIB) \
+	$(TOPDIR)/arch/niosnommu/lib/lib.a
+
+archclean:
+	rm -f $(TOPDIR)/arch/niosnommu/kernel/nios_defs.h
+	rm -f $(TOPDIR)/arch/niosnommu/kernel/nios_defs.d
+	rm -f $(TOPDIR)/arch/niosnommu/boot/boot
+	rm -f $(TOPDIR)/linux.srec
+	rm -f $(TOPDIR)/linux.flash
+	rm -f $(TOPDIR)/linux.bin
+	rm -f $(TOPDIR)/linux.bin.srec
+
+linuxsrec: linux
+	$(OBJCOPY) -O srec $(LINUX) linux.srec
+
+archmrproper:
+	rm -f $(TOPDIR)/include/asm/nios.h
+	rm -f $(TOPDIR)/include/asm/niosasm.h
+
+archdep:
diff -urN linux-2.4.29/arch/niosnommu/mm/fault.c linux-2.4.29-uc1/arch/niosnommu/mm/fault.c
--- linux-2.4.29/arch/niosnommu/mm/fault.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/mm/fault.c	2005-06-14 02:11:08.000000000 +0100
@@ -0,0 +1,10 @@
+/*
+ * fault.c:  Page fault handlers for the Nios.
+ *
+ * Copyright (C) 2001 Vic Phillips  vic@microtronix.com
+ */
+
+
+int is_in_rom() {
+	return 0;
+}
diff -urN linux-2.4.29/arch/niosnommu/mm/init.c linux-2.4.29-uc1/arch/niosnommu/mm/init.c
--- linux-2.4.29/arch/niosnommu/mm/init.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/mm/init.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,282 @@
+/*  linux/arch/niosnommu/mm/init.c, based on:
+ *
+ *  linux/arch/m68knommu/mm/init.c
+ *
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@uClinux.org>,
+ *                      Kenneth Albanowski <kjahds@kjahds.com>,
+ *  Copyright (C) 2000  Lineo, Inc.
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68k/mm/init.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ *
+ *  JAN/1999 -- hacked to support ColdFire (gerg@lineo.com)
+ *  DEC/2000 -- linux 2.4 support <davidm@lineo.com>
+ */
+
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#ifdef CONFIG_BLK_DEV_RAM
+#include <linux/blk.h>
+#endif
+#include <linux/bootmem.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/virtconvert.h>
+
+#undef DEBUG
+
+static unsigned long totalram_pages = 0;
+
+extern void die_if_kernel(char *,struct pt_regs *,long);
+
+extern void free_initmem(void);
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+static unsigned long empty_bad_page_table;
+
+static unsigned long empty_bad_page;
+
+unsigned long empty_zero_page;
+
+extern unsigned long rom_length;
+
+void show_mem(void)
+{
+    unsigned long i;
+    int free = 0, total = 0, reserved = 0, shared = 0;
+    int cached = 0;
+
+    printk("\nMem-info:\n");
+    show_free_areas();
+#if 0
+    printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+#endif
+    i = max_mapnr;
+    while (i-- > 0) {
+	total++;
+	if (PageReserved(mem_map+i))
+	    reserved++;
+	else if (PageSwapCache(mem_map+i))
+	    cached++;
+	else if (!page_count(mem_map+i))
+	    free++;
+	else
+	    shared += page_count(mem_map+i) - 1;
+    }
+    printk("%d pages of RAM\n",total);
+    printk("%d free pages\n",free);
+    printk("%d reserved pages\n",reserved);
+    printk("%d pages shared\n",shared);
+    printk("%d pages swap cached\n",cached);
+#if 0
+    printk("%ld pages in page table cache\n",pgtable_cache_size);
+#endif
+    show_buffers();
+}
+
+extern unsigned long memory_start;
+extern unsigned long memory_end;
+
+/*
+ * paging_init() continues the virtual memory environment setup which
+ * was begun by the code in arch/head.S.
+ * The parameters are pointers to where to stick the starting and ending
+ * addresses  of available kernel virtual memory.
+ */
+void paging_init(void)
+{
+	/*
+	 * make sure start_mem is page aligned,  otherwise bootmem and
+	 * page_alloc get different views og the world
+	 */
+#ifdef DEBUG
+	unsigned long start_mem = PAGE_ALIGN(memory_start);
+#endif
+	unsigned long end_mem   = memory_end & PAGE_MASK;
+
+#ifdef DEBUG
+	printk ("start_mem is %#lx\nvirtual_end is %#lx\n",
+		start_mem, end_mem);
+#endif
+
+	/*
+	 * initialize the bad page table and bad page to point
+	 * to a couple of allocated pages
+	 */
+	empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+	memset((void *)empty_zero_page, 0, PAGE_SIZE);
+
+	/*
+	 * Set up SFC/DFC registers (user data space)
+	 */
+	set_fs (USER_DS);
+
+#ifdef DEBUG
+	printk ("before free_area_init\n");
+
+	printk ("free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n",
+		start_mem, end_mem);
+#endif
+
+	{
+		unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+
+		zones_size[ZONE_DMA]     = 0 >> PAGE_SHIFT;
+		zones_size[ZONE_NORMAL]  = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
+#ifdef CONFIG_HIGHMEM
+		zones_size[ZONE_HIGHMEM] = 0;
+#endif
+		free_area_init_node(0, NULL, NULL, zones_size, PAGE_OFFSET, NULL);
+	}
+}
+
+void mem_init(void)
+{
+	int codek = 0, datak = 0, initk = 0;
+	/* DAVIDM look at setup memory map generically with reserved area */
+	unsigned long tmp;
+#ifdef CONFIG_UCLINUX
+	extern char _etext, _stext, _sdata, _ebss, __init_begin, __init_end;
+	unsigned long len = na_sdram_size;
+#else
+	extern char _etext, _romvec, __data_start;
+	unsigned long len = end_mem-(unsigned long)&__data_start;
+	int datapages = 0;
+#endif
+	unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */
+	unsigned long end_mem   = memory_end; /* DAVIDM - this must not include kernel stack at top */
+
+	/* Bloody watchdog... */
+#ifdef CONFIG_SHGLCORE
+       (*((volatile unsigned char*)0xFFFA21)) = 128 | 64/* | 32 | 16*/;
+       (*((volatile unsigned short*)0xFFFA24)) &= ~512;
+       (*((volatile unsigned char*)0xFFFA27)) = 0x55;
+       (*((volatile unsigned char*)0xFFFA27)) = 0xAA;
+       
+       /*printk("Initiated watchdog, SYPCR = %x\n", *(volatile char*)0xFFFA21);*/
+#endif	                
+
+#ifdef DEBUG
+	printk("Mem_init: start=%lx, end=%lx\n", start_mem, end_mem);
+#endif
+
+	end_mem &= PAGE_MASK;
+	high_memory = (void *) end_mem;
+
+	start_mem = PAGE_ALIGN(start_mem);
+	max_mapnr = num_physpages = MAP_NR(high_memory);
+
+	/* this will put all memory onto the freelists */
+	totalram_pages = free_all_bootmem();
+
+#ifdef CONFIG_UCLINUX
+	codek = (&_etext - &_stext) >> 10;
+	datak = (&_ebss - &_sdata) >> 10;
+	initk = (&__init_begin - &__init_end) >> 10;
+#else
+	for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
+		if (PageReserved(mem_map+MAP_NR(tmp))) {
+			datapages++;
+			continue;
+		}
+	}
+	
+	codek = (&_etext - &_romvec) >> 10;
+	datak = datapages << (PAGE_SHIFT-10);
+	initk = 0;
+#endif
+
+	tmp = nr_free_pages() << PAGE_SHIFT;
+	printk("Memory available: %luk/%luk RAM, %luk/%luk ROM (%dk kernel code, %dk data)\n",
+	       tmp >> 10,
+	       len >> 10,
+	       (rom_length > 0) ? ((rom_length >> 10) - codek) : 0,
+	       rom_length >> 10,
+	       codek,
+	       datak
+	       );
+}
+
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	int pages = 0;
+	for (; start < end; start += PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(start));
+		set_page_count(virt_to_page(start), 1);
+		free_page(start);
+		totalram_pages++;
+		pages++;
+	}
+	printk ("Freeing initrd memory: %dk freed\n", pages);
+}
+#endif
+
+
+void si_meminfo(struct sysinfo *val)
+{
+    unsigned long i;
+
+    i = max_mapnr;
+    val->totalram = totalram_pages;
+    val->sharedram = 0;
+    val->freeram = nr_free_pages();
+    val->bufferram = atomic_read(&buffermem_pages);
+    val->totalhigh = 0;
+    val->freehigh = 0;
+    val->mem_unit = PAGE_SIZE;
+    return;
+}
+
+
+void
+free_initmem()
+{
+#ifdef CONFIG_RAMKERNEL
+	unsigned long addr;
+	extern char __init_begin, __init_end;
+/*
+ *	the following code should be cool even if these sections
+ *	are not page aligned.
+ */
+	addr = PAGE_ALIGN((unsigned long)(&__init_begin));
+	/* next to check that the page we free is not a partial page */
+	for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(addr));
+		set_page_count(virt_to_page(addr), 1);
+		free_page(addr);
+		totalram_pages++;
+	}
+	printk("Freeing unused kernel memory: %ldk freed\n",
+			(addr - PAGE_ALIGN((long) &__init_begin)) >> 10);
+#endif
+}
+
diff -urN linux-2.4.29/arch/niosnommu/mm/init.c-original linux-2.4.29-uc1/arch/niosnommu/mm/init.c-original
--- linux-2.4.29/arch/niosnommu/mm/init.c-original	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/mm/init.c-original	2005-06-14 02:11:08.000000000 +0100
@@ -0,0 +1,226 @@
+/*
+ *  linux/arch/m68knommu/mm/init.c
+ *
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@uClinux.org>,
+ *                      Kenneth Albanowski <kjahds@kjahds.com>,
+ *                      The Silver Hammer Group, Ltd.
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68k/mm/init.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ *
+ *  JAN/1999 -- hacked to support ColdFire (gerg@moreton.com.au)
+ */
+
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#ifdef CONFIG_BLK_DEV_RAM
+#include <linux/blk.h>
+#endif
+
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+
+#ifndef PAGE_OFFSET
+#define PAGE_OFFSET 0
+#endif
+
+extern void die_if_kernel(char *,struct pt_regs *,long);
+extern void show_net_buffers(void);
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+static unsigned long empty_bad_page_table;
+
+static unsigned long empty_bad_page;
+
+unsigned long empty_zero_page;
+
+unsigned long rom_length;
+
+void show_mem(void)
+{
+    unsigned long i;
+    int free = 0, total = 0, reserved = 0, nonshared = 0, shared = 0;
+
+    printk("\nMem-info:\n");
+    show_free_areas();
+    printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+    i = (high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
+    while (i-- > 0) {
+	total++;
+	if (PageReserved(mem_map+i))
+	    reserved++;
+	else if (!mem_map[i].count)
+	    free++;
+	else if (mem_map[i].count == 1)
+	    nonshared++;
+	else
+	    shared += mem_map[i].count-1;
+    }
+    printk("%d pages of RAM\n",total);
+    printk("%d free pages\n",free);
+    printk("%d reserved pages\n",reserved);
+    printk("%d pages nonshared\n",nonshared);
+    printk("%d pages shared\n",shared);
+    show_buffers();
+#ifdef CONFIG_NET
+    show_net_buffers();
+#endif
+}
+
+extern unsigned long free_area_init(unsigned long, unsigned long);
+
+/*
+ * paging_init() continues the virtual memory environment setup which
+ * was begun by the code in arch/head.S.
+ * The parameters are pointers to where to stick the starting and ending
+ * addresses  of available kernel virtual memory.
+ */
+unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
+{
+#ifdef DEBUG
+	printk ("start_mem is %#lx\nvirtual_end is %#lx\n",
+		start_mem, end_mem);
+#endif
+
+	/*
+	 * initialize the bad page table and bad page to point
+	 * to a couple of allocated pages
+	 */
+	empty_bad_page_table = start_mem;
+	start_mem += PAGE_SIZE;
+	empty_bad_page = start_mem;
+	start_mem += PAGE_SIZE;
+	empty_zero_page = start_mem;
+	start_mem += PAGE_SIZE;
+	memset((void *)empty_zero_page, 0, PAGE_SIZE);
+
+	/*
+	 * Set up SFC/DFC registers (user data space)
+	 */
+	set_fs (USER_DS);
+
+#ifdef DEBUG
+	printk ("before free_area_init\n");
+
+	printk ("free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n",
+		start_mem, end_mem);
+#endif
+
+	return PAGE_ALIGN(free_area_init (start_mem, end_mem));
+}
+
+void mem_init(unsigned long start_mem, unsigned long end_mem)
+{
+	int codek = 0;
+	int datapages = 0;
+	unsigned long tmp;
+#if defined( CONFIG_COLDFIRE ) || defined( CONFIG_EXCALIBUR )
+	extern char _etext, _stext, __data_start;
+#else
+	extern char _etext, _romvec, __data_start;
+#endif
+	unsigned long len = end_mem-(unsigned long)&__data_start;
+
+	/* Bloody watchdog... */
+#ifdef CONFIG_SHGLCORE
+       (*((volatile unsigned char*)0xFFFA21)) = 128 | 64/* | 32 | 16*/;
+       (*((volatile unsigned short*)0xFFFA24)) &= ~512;
+       (*((volatile unsigned char*)0xFFFA27)) = 0x55;
+       (*((volatile unsigned char*)0xFFFA27)) = 0xAA;
+       
+       /*printk("Initiated watchdog, SYPCR = %x\n", *(volatile char*)0xFFFA21);*/
+#endif	                
+
+#ifdef DEBUG
+	printk("Mem_init: start=%lx, end=%lx\n", start_mem, end_mem);
+#endif
+
+	end_mem &= PAGE_MASK;
+	high_memory = end_mem;
+
+	start_mem = PAGE_ALIGN(start_mem);
+	while (start_mem < high_memory) {
+		clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
+		start_mem += PAGE_SIZE;
+	}
+
+	for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
+
+#ifdef MAX_DMA_ADDRESS
+		if (VTOP (tmp) >= MAX_DMA_ADDRESS)
+			clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
+#endif
+
+		if (PageReserved(mem_map+MAP_NR(tmp))) {
+			datapages++;
+			continue;
+		}
+		mem_map[MAP_NR(tmp)].count = 1;
+#ifdef CONFIG_BLK_DEV_INITRD
+		if (!initrd_start ||
+		    (tmp < (initrd_start & PAGE_MASK) || tmp >= initrd_end))
+#endif
+			free_page(tmp);
+	}
+	
+#if defined( CONFIG_COLDFIRE ) || defined( CONFIG_EXCALIBUR )
+	codek = (&_etext - &_stext) >> 10;
+#else
+	codek = (&_etext - &_romvec) >> 10;
+#endif
+	tmp = nr_free_pages << PAGE_SHIFT;
+	printk("Memory available: %luk/%luk RAM, %luk/%luk ROM (%dk kernel data, %dk code)\n",
+	       tmp >> 10,
+	       len >> 10,
+	       (rom_length > 0) ? ((rom_length >> 10) - codek) : 0,
+	       rom_length >> 10,
+	       datapages << (PAGE_SHIFT-10),
+	       codek
+	       );
+}
+
+void si_meminfo(struct sysinfo *val)
+{
+    unsigned long i;
+
+    i = (high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
+    val->totalram = 0;
+    val->sharedram = 0;
+    val->freeram = nr_free_pages << PAGE_SHIFT;
+    val->bufferram = buffermem;
+    while (i-- > 0) {
+	if (PageReserved(mem_map+i))
+	    continue;
+	val->totalram++;
+	if (!mem_map[i].count)
+	    continue;
+	val->sharedram += mem_map[i].count-1;
+    }
+    val->totalram <<= PAGE_SHIFT;
+    val->sharedram <<= PAGE_SHIFT;
+    return;
+}
+
diff -urN linux-2.4.29/arch/niosnommu/mm/ioremap.c linux-2.4.29-uc1/arch/niosnommu/mm/ioremap.c
--- linux-2.4.29/arch/niosnommu/mm/ioremap.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/mm/ioremap.c	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,47 @@
+/*  linux/arch/niosnommu/mm/ioremap.c, based on:
+ *
+ *  linux/arch/m68knommu/mm/kmap.c
+ *
+ *  Copyright (C) 2000 Lineo, <davidm@lineo.com>
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/malloc.h>
+#include <linux/vmalloc.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+/*
+ * Map some physical address range into the kernel address space.
+ */
+
+void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
+{
+	return (void *)physaddr;
+}
+
+/*
+ * Unmap a ioremap()ed region again
+ */
+void iounmap(void *addr)
+{
+}
+
+/*
+ * __iounmap unmaps nearly everything, so be careful
+ * it doesn't free currently pointer/page tables anymore but it
+ * wans't used anyway and might be added later.
+ */
+void __iounmap(void *addr, unsigned long size)
+{
+}
+
diff -urN linux-2.4.29/arch/niosnommu/mm/Makefile linux-2.4.29-uc1/arch/niosnommu/mm/Makefile
--- linux-2.4.29/arch/niosnommu/mm/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/mm/Makefile	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,12 @@
+# Makefile for the linux Sparc-specific parts of the memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET := mm.o
+obj-y    := fault.o init.o ioremap.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/niosnommu/ram.ld linux-2.4.29-uc1/arch/niosnommu/ram.ld
--- linux-2.4.29/arch/niosnommu/ram.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/ram.ld	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,130 @@
+OUTPUT_FORMAT("elf32-nios", "elf32-nios", "elf32-nios")
+OUTPUT_ARCH(nios)
+ENTRY(_start)	/* Defined in head.S */
+
+SECTIONS
+{
+        .text :
+	{
+	__ram_start = . ;
+	_stext = . ;
+	text_start = . ;
+        	*(.text)
+		*(.rodata)
+	. = ALIGN(0x4) ;
+		*(.kstrtab)
+	. = ALIGN(16);          /* Exception table              */
+	__start___ex_table = .;
+		*(__ex_table)
+	__stop___ex_table = .;
+
+        __start___ksymtab = .;  /* Kernel symbol table          */
+		 *(__ksymtab)
+	__stop___ksymtab = .;
+
+	_etext = . ;
+	__data_rom_start = ALIGN ( 4 ) ;
+        } > ram
+
+        .data :
+	{
+	_sdata = . ;
+	__data_start = . ;
+
+        . = ALIGN(0x2000) ;
+        *(.data.init_task)
+        . = ALIGN(0x2000) ;
+
+        *(.data)
+
+        . = ALIGN(4096) ;
+        __init_begin = .;
+        *(.text.init)
+        *(.data.init)
+        . = ALIGN(16);
+        __setup_start = .;
+        *(.setup.init)
+        __setup_end = .;
+        __initcall_start = .;
+        *(.initcall.init)
+        __initcall_end = .;
+        __init_end = .;
+        . = ALIGN(4096) ;
+
+	_edata = . ;
+	_kernel_footprint = . -__ram_start ;
+	edata = ALIGN( 0x10 ) ;
+/*	. = ALIGN( 0x10 );		*/
+/*	*(.romf)			*/
+        } > ram
+
+        .bss :
+        {
+	_sbss = ALIGN( 0x10 ) ;
+	__bss_start = ALIGN( 0x10 ) ;
+	__data_end = ALIGN( 0x10 ) ;
+	*(.bss)
+	*(COMMON)
+	_ebss = . ;
+	__bss_end = . ;
+/*	end = ALIGN( 0x10 ) ;		*/
+/*	_end = ALIGN( 0x10 ) ;		*/
+	end = ALIGN( 0x1000 ) ;
+	_end = ALIGN( 0x1000 ) ;
+	} > ram
+
+	.eram :
+	{
+	__ramend = . ;
+	_ramend = . ;
+	} > eram
+
+ /* Sections to be discarded */
+  /DISCARD/ : {
+	*(.text.exit)
+	*(.data.exit)
+	*(.exitcall.exit)
+	}
+
+  /*
+   * ------------------------------------------------------------
+   * dvb say: "I'll leave all this stuff down here exactly
+   * as I found it, for debugging info, without
+   * understanding it."
+   */
+
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  /* These must appear regardless of  .  */
+}
diff -urN linux-2.4.29/arch/niosnommu/rom.ld linux-2.4.29-uc1/arch/niosnommu/rom.ld
--- linux-2.4.29/arch/niosnommu/rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/niosnommu/rom.ld	2005-06-14 02:11:09.000000000 +0100
@@ -0,0 +1,57 @@
+MEMORY 
+	{
+	flash  : ORIGIN = 0x00100000, LENGTH = 0x100000
+	eflash : ORIGIN = 0x00200000, LENGTH = 1
+	ramvec : ORIGIN = 0x00040000, LENGTH = 0x100
+	ram    : ORIGIN = 0x00040100, LENGTH = 0x03FF00
+	eram   : ORIGIN = 0x00080000, LENGTH = 1
+	}
+
+SECTIONS
+{
+        .text :
+	{
+	_romvec = . ;
+	__rom_start = . ;
+	*(.romvec)
+	_stext = . ;
+	text_start = . ;
+        *(.text)
+	*(.rodata)
+	_etext = . ;
+	__data_rom_start = ALIGN ( 4 ) ;
+        } > flash
+	.eflash :
+	{
+	_flashend = . ;
+	} > eflash
+	.ramvec :
+	{
+	__ram_start = . ;
+	_ramvec = . ;
+	} > ramvec
+        .data :
+	{
+	_sdata = . ;
+	__data_start = . ;
+        *(.data)
+	_edata = . ;
+	edata = ALIGN( 0x10 ) ;
+        } > ram
+        .bss :
+        {
+	_sbss = ALIGN( 0x10 ) ;
+	__bss_start = ALIGN( 0x10 ) ;
+	__data_end = ALIGN( 0x10 ) ;
+	*(.bss)
+	*(COMMON)
+	_ebss = . ;
+	__bss_end = . ;
+	end = ALIGN( 0x10 ) ;
+	_end = ALIGN( 0x10 ) ;
+	} > ram
+	.eram :
+	{
+	_ramend = . ;
+	} > eram
+}
diff -urN linux-2.4.29/arch/sh/config.in linux-2.4.29-uc1/arch/sh/config.in
--- linux-2.4.29/arch/sh/config.in	2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.29-uc1/arch/sh/config.in	2005-06-14 02:10:58.000000000 +0100
@@ -44,7 +44,7 @@
 	 CAT68701		CONFIG_SH_CAT68701		\
 	 BigSur			CONFIG_SH_BIGSUR		\
 	 SH2000			CONFIG_SH_SH2000		\
-	 HS7729PCI		CONFIG_SH_HS7729PCI		\
+	 HS7729PCI              CONFIG_SH_HS7729PCI		\
 	 ADX			CONFIG_SH_ADX			\
 	 SecureEdge5410		CONFIG_SH_SECUREEDGE5410	\
 	 KeyWest		CONFIG_SH_KEYWEST		\
@@ -162,6 +162,7 @@
    define_hex CONFIG_MEMORY_START 08000000
    define_hex CONFIG_MEMORY_SIZE 01000000
    define_bool CONFIG_MEMORY_SET y
+   bool 'Serial console is on ttySC0 (not ttySC1)' CONFIG_SH_CONSOLE_TTYSC0
 fi
 if [ "$CONFIG_SH_HS7729PCI" = "y" ]; then
    define_hex CONFIG_MEMORY_START 0c000000
@@ -173,9 +174,21 @@
    hex 'Physical memory start address' CONFIG_MEMORY_START 08000000
    hex 'Physical memory size' CONFIG_MEMORY_SIZE 00400000
 fi
+if [ "$CONFIG_SH_SECUREEDGE5410" = "y" -o "$CONFIG_SH_BIGSUR" = "y" -o \
+     "$CONFIG_SH_KEYWEST" = "y" ]; then
+   bool 'SnapGear romfs/bootarg support' CONFIG_SH_SNAPGEAR
+fi
 
 hex 'Link address offset for booting' CONFIG_BOOT_LINK_OFFSET 00210000
 
+if [ "$CONFIG_SH_BIGSUR" = "y" ]; then
+   bool 'Boot kernel from ROM' CONFIG_SH_ROMBOOT
+fi
+
+if [ "$CONFIG_SH_ROMBOOT" = "y" ]; then
+	hex 'Offset into ROM to store image at' CONFIG_ROM_STORE_OFFSET 100000
+fi
+
 dep_bool 'Enable OC RAM zone (experimental)' CONFIG_SCRATCH_SPACE $CONFIG_EXPERIMENTAL
 bool 'DSP mode support' CONFIG_SH_DSP
 
@@ -423,6 +436,12 @@
 if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then
    source drivers/char/pcmcia/Config.in
 fi
+bool 'LED Manager support (ledman)' CONFIG_LEDMAN
+bool 'SnapGear Watchdog Support' CONFIG_SNAPDOG
+bool 'Fast Timer Support' CONFIG_FAST_TIMER
+if [ "$CONFIG_SH_DSP" = "y" ]; then
+  bool 'X/Y memory driver for SH3-DSP' CONFIG_XYMEM
+fi
 endmenu
 
 source fs/Config.in
@@ -434,6 +453,7 @@
    comment 'Console drivers'
    bool 'VGA text console' CONFIG_VGA_CONSOLE
    bool 'Video mode selection support' CONFIG_VIDEO_SELECT
+   bool 'VGA dummy console' CONFIG_DUMMY_CONSOLE
    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
       tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
       source drivers/video/Config.in
@@ -451,6 +471,8 @@
 fi
 endmenu
 
+source drivers/usb/Config.in
+
 mainmenu_option next_comment
 comment 'Kernel hacking'
 
@@ -459,6 +481,11 @@
 if [ "$CONFIG_SH_STANDARD_BIOS" = "y" ]; then
    bool 'Early printk support' CONFIG_SH_EARLY_PRINTK
 fi
+bool 'Specify Command Line' CONFIG_COMMAND_LINE
+if [ "$CONFIG_COMMAND_LINE" != "n" ]; then
+  string 'Command Line' CONFIG_COMMAND_LINE_VALUE ""
+fi
+
 bool 'Include KGDB kernel debugger' CONFIG_SH_KGDB
 if [ "$CONFIG_SH_KGDB" = "y" ]; then
    bool ' Enter KGDB on NMI' CONFIG_KGDB_NMI
diff -urN linux-2.4.29/arch/sh/kernel/entry.S linux-2.4.29-uc1/arch/sh/kernel/entry.S
--- linux-2.4.29/arch/sh/kernel/entry.S	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-uc1/arch/sh/kernel/entry.S	2005-06-14 02:10:58.000000000 +0100
@@ -322,6 +322,27 @@
 1:	.long	SYMBOL_NAME(do_exception_error)
 
 
+#ifdef CONFIG_SH_DSP
+/*
+ *	Return if this processor has the DSP unit present
+ */
+ENTRY(sh3_dsp)
+	stc	sr, r0			! Get current SR
+	mov	r0, r1			! Keep copy of SR to restore
+	mov.l	1f, r2			! Get DSP bit mask
+	or	r2, r0			! Turn on DSP bit
+	ldc	r0, sr			! Write SR with DSP bit set
+	nop
+	stc	sr, r0			! Get SR again
+	ldc	r1, sr			! Restore SR to original
+	rts
+	 and	r2, r0			! Return if DSP bit still set
+
+1:	.long	0x00001000		! DSP bit set
+
+#endif
+
+
 !
 !
 !
@@ -633,6 +654,7 @@
 1:	.long	0x00008000	! FD
 2:	.long	0xffff7f0f	! ~(IMASK+FD)
 3:	.long	0x00080000	! SZ=0, PR=1
+31:	.long	0x00001000	! DSP bit set
 #if defined(CONFIG_KGDB_NMI)
 4:	.long	SYMBOL_NAME(in_nmi)
 #endif
@@ -792,12 +814,15 @@
 	mov.l	@r9, r9
 	jmp	@r9
 	 nop
+
+
 	.align	2
 1:	.long	SYMBOL_NAME(exception_handling_table)
 3:	.long	0x000000f0	! FD=0, IMASK=15
 4:	.long	0x00001000	! DSP bit set
 5:	.long	0xcfffffff	! RB=0, BL=0
 6:	.long	0x00080000	! SZ=0, PR=1
+7:	.long	0x00001000	! DSP bit set
 
 none:
 	rts
@@ -1339,8 +1364,8 @@
 	.long SYMBOL_NAME(sys_rt_sigtimedwait)
 	.long SYMBOL_NAME(sys_rt_sigqueueinfo)
 	.long SYMBOL_NAME(sys_rt_sigsuspend)
-	.long SYMBOL_NAME(sys_pread_wrapper)	/* 180 */
-	.long SYMBOL_NAME(sys_pwrite_wrapper)
+	.long SYMBOL_NAME(sys_pread)		/* 180 */
+	.long SYMBOL_NAME(sys_pwrite)
 	.long SYMBOL_NAME(sys_chown16)
 	.long SYMBOL_NAME(sys_getcwd)
 	.long SYMBOL_NAME(sys_capget)
diff -urN linux-2.4.29/arch/sh/kernel/head.S linux-2.4.29-uc1/arch/sh/kernel/head.S
--- linux-2.4.29/arch/sh/kernel/head.S	2003-08-25 12:44:40.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/kernel/head.S	2005-06-14 02:10:58.000000000 +0100
@@ -9,11 +9,30 @@
  * for more details.
  *
  * Head.S contains the SH exception handlers and startup code.
+ *
+ * Modified by Rahul Chaturvedi on 22/06/2004 (justanotheraliasforrahul@yahoo.com)
+ * to add support for booting the kernel from ROM
+ *
  */
 #include <linux/linkage.h>
 
 	.section	.empty_zero_page, "aw"
 ENTRY(empty_zero_page)
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	.long	1		/* MOUNT_ROOT_RDONLY */
+	.long	0x4000		/* RAMDISK_FLAGS */
+	.long	0x0100		/* ORIG_ROOT_DEV */
+	.long	1		/* LOADER_TYPE */
+#if defined(CONFIG_SH_SNAPGEAR)
+	.long	_end		/* INITRD_START */
+	.long	0x000000	/* INITRD_SIZE */
+#else
+	.long	0x00360000	/* INITRD_START */
+	.long	0x000a0000	/* INITRD_SIZE */
+#endif
+	.long	0
+#else
 	.long	1		/* MOUNT_ROOT_RDONLY */
 	.long	0		/* RAMDISK_FLAGS */
 	.long	0x0200		/* ORIG_ROOT_DEV */
@@ -21,8 +40,22 @@
 	.long	0x00360000	/* INITRD_START */
 	.long	0x000a0000	/* INITRD_SIZE */
 	.long	0
-	.balign 4096,0,4096
+#endif
+#if defined(CONFIG_SH_SNAPGEAR)
+	.balign 256,0,256
+cmdline:
+#if defined(CONFIG_SH_SECUREEDGE5410)
+# if defined(CONFIG_SH_CONSOLE_TTYSC0)
+	.ascii	"mem=16M console=ttySC0,57600\0"
+# else
+	.ascii	"mem=16M console=ttySC1,57600\0"
+# endif
+#else
+	.ascii	"mem=32M console=ttySC1,57600\0"
+#endif
+#endif
 
+	.balign 4096,0,4096
 	.text	
 /*
  * Condition at the entry of _stext:
@@ -36,6 +69,51 @@
  *
  */
 ENTRY(_stext)
+
+#if defined(CONFIG_SH_ROMBOOT)
+!			Copy zero page to RAM
+
+	mov.l	11f, r1		! r1 = src (zero page in ROM - _rom_store)
+	mov.l	12f, r2		! r2 = dest (zero page dest in RAM - _mem_start)
+
+	mov.l	13f, r0		! r0 = sizeof zero page (4k)
+	add	r2, r0		! r0 = end of dest 
+
+10:
+	mov.b	@r1, r3
+	mov.b	r3, @r2
+
+	add #1, r1
+	add #1, r2
+	
+	cmp/eq r2, r0
+	bf 10b
+
+
+
+!			Copy everything from _etext to __bss_start to RAM
+
+	mov.l	7f, r2		! r2 = dest (_etext)
+	mov	r2, r1
+	mov.l	12f, r3	
+	sub	r3, r1 		! r1 = _etext - _mem_start
+	mov.l	11f, r3	
+	add	r3, r1		! r1 = _etext - (_mem_start - _rom_store) = src
+	
+	mov.l	3f, r0		! r0 = end of dest (__bss_start)
+
+14:
+	mov.b	@r1, r3
+	mov.b	r3, @r2
+
+	add #1, r1
+	add #1, r2
+	
+	cmp/eq r2, r0
+	bf 14b
+
+#endif
+
 	!			Initialize Status Register
 	mov.l	1f, r0		! MD=1, RB=0, BL=0, IMASK=0xF
 	ldc	r0, sr
@@ -53,7 +131,20 @@
 	!			Enable cache
 	mov.l	6f, r0
 	jsr	@r0
-	 nop
+	nop
+
+#if defined(CONFIG_SH_SNAPGEAR)
+	! (re)set the peripheral bus dividor to 1/2
+	mov.l   FRQCR, r1
+	mov.w   FRQCR_data, r0
+	mov.w   r0, @r1
+	! move the romfs to after the bss
+	mov.l	fix_romfs, r0
+	jsr @r0
+#endif
+	nop
+
+
 	!			Clear BSS area
 	mov.l	3f, r1
 	add	#4, r1
@@ -61,11 +152,12 @@
 	mov	#0, r0
 9:	cmp/hs	r2, r1
 	bf/s	9b		! while (r1 < r2)
-	 mov.l	r0,@-r2
+	mov.l	r0,@-r2
+
 	!			Start kernel
 	mov.l	5f, r0
 	jmp	@r0
-	 nop
+	nop
 
 	.balign 4
 1:	.long	0x400080F0		! MD=1, RB=0, BL=0, FD=1, IMASK=0xF
@@ -74,3 +166,18 @@
 4:	.long	SYMBOL_NAME(_end)
 5:	.long	SYMBOL_NAME(start_kernel)
 6:	.long	SYMBOL_NAME(cache_init)
+
+
+#if defined(CONFIG_SH_ROMBOOT)
+7:	.long	SYMBOL_NAME(_etext);
+11:	.long	SYMBOL_NAME(_rom_store)	
+12:	.long	SYMBOL_NAME(_mem_start)
+13:	.long	0x1000
+#endif
+
+#if defined(CONFIG_SH_SNAPGEAR)
+fix_romfs: .long copy_romfs
+FRQCR:     .long 0xffc00000
+FRQCR_data:.word 0x0e08
+           .word 0x0000
+#endif
diff -urN linux-2.4.29/arch/sh/kernel/io_snapgear.c linux-2.4.29-uc1/arch/sh/kernel/io_snapgear.c
--- linux-2.4.29/arch/sh/kernel/io_snapgear.c	2003-08-25 12:44:40.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/kernel/io_snapgear.c	2005-06-14 02:10:58.000000000 +0100
@@ -22,7 +22,7 @@
 #include <asm/pci-sh7751.h>
 
 #ifdef CONFIG_SH_SECUREEDGE5410
-unsigned short secureedge5410_ioport;
+unsigned short secureedge5410_ioport = 0x7e; /* only power LED on by default */
 #endif
 
 /*
diff -urN linux-2.4.29/arch/sh/kernel/irq.c linux-2.4.29-uc1/arch/sh/kernel/irq.c
--- linux-2.4.29/arch/sh/kernel/irq.c	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-uc1/arch/sh/kernel/irq.c	2005-06-14 02:10:58.000000000 +0100
@@ -434,8 +434,8 @@
 	 */
 	val = 0;
 	for (i=0; i<NR_IRQS; i++) {
-		desc = irq_desc + i;
 		unsigned int status;
+		desc = irq_desc + i;
 
 		spin_lock_irq(&desc->lock);
 		status = desc->status;
@@ -547,3 +547,13 @@
 {
 }
 #endif
+
+
+/* This guy is needed for PCMCIA,  we just dummy it */
+unsigned int
+probe_irq_mask(unsigned long bits)
+{
+	printk("%s(0x%x) returning 0\n", __FUNCTION__, bits);
+	return(0);
+}
+
diff -urN linux-2.4.29/arch/sh/kernel/irq_ipr.c linux-2.4.29-uc1/arch/sh/kernel/irq_ipr.c
--- linux-2.4.29/arch/sh/kernel/irq_ipr.c	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-uc1/arch/sh/kernel/irq_ipr.c	2005-06-14 02:10:58.000000000 +0100
@@ -241,6 +241,31 @@
 	 * registers to their power on values
 	 */ 
 
+#ifdef CONFIG_SH_KEYWEST
+	/*
+	 * XXX: I think that this is the job of boot loader. -- gniibe
+	 *
+	 * When Takeshi released new boot loader following setting
+	 * will be removed shortly.
+	 */
+	ctrl_outb(0, INTC_IRR0);
+	ctrl_outb(0, INTC_IRR1);
+	ctrl_outb(0, INTC_IRR2);
+
+	ctrl_outw(0, INTC_ICR0);
+	/*
+	 * we have to run hd64465 (IRQ1) in level mode or we get spurious ints
+	 */
+	ctrl_outw(0x0108, INTC_ICR1);
+	ctrl_outw(0x0003, INTC_ICR2);
+	ctrl_outw(0, INTC_INTER);
+	ctrl_outw(0, INTC_IPRA);
+	ctrl_outw(0, INTC_IPRB);
+	ctrl_outw(0, INTC_IPRC);
+	ctrl_outw(0, INTC_IPRD);
+	ctrl_outw(0, INTC_IPRE);
+#endif
+
 	/*
 	 * Enable external irq (INTC IRQ mode).
 	 * You should set corresponding bits of PFC to "00"
diff -urN linux-2.4.29/arch/sh/kernel/Makefile linux-2.4.29-uc1/arch/sh/kernel/Makefile
--- linux-2.4.29/arch/sh/kernel/Makefile	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-uc1/arch/sh/kernel/Makefile	2005-06-14 02:10:58.000000000 +0100
@@ -13,6 +13,9 @@
 O_TARGET := kernel.o
 
 export-objs	:= io.o io_generic.o io_hd64461.o setup_hd64461.o sh_ksyms.o \
+		   hd64465_gpio.o io_hd64465.o setup_keywest.o io_keywest.o \
+		   io_bigsur.o \
+		   setup_hd64465.o \
 		   dma.o
 
 obj-y	:= process.o signal.o entry.o traps.o irq.o irq_ipr.o \
@@ -63,6 +66,13 @@
 obj-$(CONFIG_SH_BIGSUR)		+= mach_bigsur.o setup_bigsur.o io_bigsur.o led_bigsur.o
 machine-specific-objs		+= mach_bigsur.o setup_bigsur.o io_bigsur.o led_bigsur.o
 
+obj-$(CONFIG_SH_SECUREEDGE5410)+= mach_snapgear.o setup_snapgear.o io_snapgear.o
+machine-specific-objs		 += mach_snapgear.o setup_snapgear.o io_snapgear.o
+ifeq ($(CONFIG_RTC),y)
+obj-$(CONFIG_SH_SECUREEDGE5410) += rtc-snapgear.o
+machine-specific-objs		    += rtc-snapgear.o
+endif
+
 obj-$(CONFIG_SH_SH2000)		+= setup_sh2000.o io_sh2000.o
 machine-specific-objs		+= setup_sh2000.o io_sh2000.o
 
@@ -72,6 +82,9 @@
 obj-$(CONFIG_SH_CQREEK)		+= setup_cqreek.o
 machine-specific-objs		+= setup_cqreek.o
 
+obj-$(CONFIG_SH_KEYWEST)    += mach_keywest.o setup_keywest.o io_keywest.o
+machine-specific-objs       += mach_keywest.o setup_keywest.o io_keywest.o
+
 obj-$(CONFIG_SH_UNKNOWN)	+= mach_unknown.o io_unknown.o
 machine-specific-objs		+= mach_unknown.o io_unknown.o
 
diff -urN linux-2.4.29/arch/sh/kernel/pci-bigsur.c linux-2.4.29-uc1/arch/sh/kernel/pci-bigsur.c
--- linux-2.4.29/arch/sh/kernel/pci-bigsur.c	2001-06-27 21:55:29.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/kernel/pci-bigsur.c	2005-06-14 02:10:58.000000000 +0100
@@ -156,8 +156,8 @@
      * Therefor the IRQ mapping is somewhat use dependent... I'l assume a linear map for
      * now, i.e. INTA=slot0,pin0... INTD=slot3,pin0...
      */ 
-    int irq = (slot + pin-1)%4 + BIGSUR_SH7751_PCI_IRQ_BASE;
-    PCIDBG(2,"PCI: Mapping Big Sur IRQ for slot %d, pin %c to irq %d\n", slot, pin-1+'A', irq);
+    int irq = (/* slot +*/ pin-1)%4 + BIGSUR_SH7751_PCI_IRQ_BASE;
+    printk("PCI: Mapping Big Sur IRQ for slot %d, pin %c to irq %d\n", slot, pin-1+'A', irq);
     return irq;
      
 }
diff -urN linux-2.4.29/arch/sh/kernel/pcibios.c linux-2.4.29-uc1/arch/sh/kernel/pcibios.c
--- linux-2.4.29/arch/sh/kernel/pcibios.c	2003-06-13 15:51:32.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/kernel/pcibios.c	2005-06-14 02:10:58.000000000 +0100
@@ -97,7 +97,7 @@
 	if (dev->resource[PCI_ROM_RESOURCE].start)
 		cmd |= PCI_COMMAND_MEMORY;
 	if (cmd != old_cmd) {
-		printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", dev->name, old_cmd, cmd);
+		printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
 		pci_write_config_word(dev, PCI_COMMAND, cmd);
 	}
 	return 0;
diff -urN linux-2.4.29/arch/sh/kernel/pci-dma.c linux-2.4.29-uc1/arch/sh/kernel/pci-dma.c
--- linux-2.4.29/arch/sh/kernel/pci-dma.c	2001-09-08 20:29:09.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/kernel/pci-dma.c	2005-06-14 02:10:58.000000000 +0100
@@ -24,7 +24,7 @@
 	ret = (void *) __get_free_pages(gfp, get_order(size));
 
 	if (ret != NULL) {
-	        /* Is it neccessary to do the memset? */
+		/* Is it neccessary to do the memset? */
 		memset(ret, 0, size);
 		*dma_handle = virt_to_bus(ret);
 	}
diff -urN linux-2.4.29/arch/sh/kernel/pci-v320usc.h linux-2.4.29-uc1/arch/sh/kernel/pci-v320usc.h
--- linux-2.4.29/arch/sh/kernel/pci-v320usc.h	2003-08-25 12:44:40.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/kernel/pci-v320usc.h	2005-06-14 02:10:58.000000000 +0100
@@ -2,8 +2,6 @@
  * v320usc.h: Register defines for the V320USC family of devices.
  *
  * Copyright (C) 1999,2000 Dan Aizenstros (dan@vcubed.com)
- *
- * $Id: pci-v320usc.h,v 1.1 2003/02/20 04:26:36 gerg Exp $
  */
 
 #ifndef _V320USC_H_
diff -urN linux-2.4.29/arch/sh/kernel/process.c linux-2.4.29-uc1/arch/sh/kernel/process.c
--- linux-2.4.29/arch/sh/kernel/process.c	2003-08-25 12:44:40.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/kernel/process.c	2005-06-14 02:10:58.000000000 +0100
@@ -66,6 +66,12 @@
 
 void machine_restart(char * __unused)
 {
+#ifdef CONFIG_SH_KEYWEST
+	cli();
+	* (unsigned short *) 0xa4000106 = 0xaa5a;
+	* (unsigned char *) 0xa4000126 = 0xff;
+	* (unsigned char *) 0xa4000126 = 0x00;
+#endif
 	/* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
 	asm volatile("ldc %0, sr\n\t"
 		     "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001));
@@ -73,6 +79,12 @@
 
 void machine_halt(void)
 {
+#ifdef CONFIG_SH_KEYWEST
+	cli();
+	* (unsigned short *) 0xa4000106 = 0xaa5a;
+	* (unsigned char *) 0xa4000126 = 0xff;
+	* (unsigned char *) 0xa4000126 = 0x00;
+#endif
 	while (1)
 		asm volatile("sleep" : : : "memory");
 }
diff -urN linux-2.4.29/arch/sh/kernel/ptrace.c linux-2.4.29-uc1/arch/sh/kernel/ptrace.c
--- linux-2.4.29/arch/sh/kernel/ptrace.c	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-uc1/arch/sh/kernel/ptrace.c	2005-06-14 02:10:58.000000000 +0100
@@ -145,6 +145,10 @@
 	struct user * dummy = NULL;
 	int ret;
 
+#if 0
+	printk("%s(%d): sys_ptrace(request=%d,pid=%d,addr=%x)\n",
+		__FILE__, __LINE__, (int)request, (int)pid, (int) addr);
+#endif
 	lock_kernel();
 	ret = -EPERM;
 	if (request == PTRACE_TRACEME) {
diff -urN linux-2.4.29/arch/sh/kernel/rtc.c linux-2.4.29-uc1/arch/sh/kernel/rtc.c
--- linux-2.4.29/arch/sh/kernel/rtc.c	2003-08-25 12:44:40.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/kernel/rtc.c	2005-06-14 02:10:58.000000000 +0100
@@ -68,6 +68,7 @@
 
 	if (badval || yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
 	    hr > 23 || min > 59 || sec > 59 || (yr100 != 19 && yr100 != 20)) {
+bad_time:
 		printk(KERN_ERR
 		       "SH RTC: invalid value, resetting to 1 Jan 2000\n");
 		ctrl_outb(RCR2_RESET, RCR2);  /* Reset & Stop */
@@ -92,6 +93,8 @@
 #endif
 
 	tv->tv_sec = mktime(yr100 * 100 + yr, mon, day, hr, min, sec);
+	if (tv->tv_sec < 0)
+		goto bad_time;
 	tv->tv_usec = (sec128 * 1000000) / 128;
 }
 
diff -urN linux-2.4.29/arch/sh/kernel/rtc-snapgear.c linux-2.4.29-uc1/arch/sh/kernel/rtc-snapgear.c
--- linux-2.4.29/arch/sh/kernel/rtc-snapgear.c	2003-08-25 12:44:40.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/kernel/rtc-snapgear.c	2005-06-14 02:10:58.000000000 +0100
@@ -16,6 +16,7 @@
 #include <linux/time.h>
 #include <linux/rtc.h>
 #include <linux/mc146818rtc.h>
+#include <linux/delay.h>
 
 #include <asm/io.h>
 #include <asm/rtc.h>
@@ -49,8 +50,8 @@
 
 #define set_dirp(x)
 #define get_dirp(x) 0
-#define set_dp(x)	SECUREEDGE_WRITE_IOPORT(x, 0x1c00)
-#define get_dp(x)	SECUREEDGE_READ_IOPORT()
+#define set_dp(x)	({ udelay(2); SECUREEDGE_WRITE_IOPORT(x, 0x1c00); })
+#define get_dp(x)	({ udelay(2); SECUREEDGE_READ_IOPORT(); })
 
 static void ds1302_sendbits(unsigned int val)
 {
diff -urN linux-2.4.29/arch/sh/kernel/setup_bigsur.c linux-2.4.29-uc1/arch/sh/kernel/setup_bigsur.c
--- linux-2.4.29/arch/sh/kernel/setup_bigsur.c	2001-09-08 20:29:09.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/kernel/setup_bigsur.c	2005-06-14 02:10:58.000000000 +0100
@@ -64,7 +64,7 @@
 	unsigned long flags;
 	unsigned char mask;
 	unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
-	unsigned char bit =  (1 << ((irq - MGATE_IRQ_LOW)%8) );
+	unsigned char bit =  (1 << ((irq - BIGSUR_IRQ_LOW)%8) );
 
 	if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {	
    		DPRINTK("Disable L1 IRQ %d\n", irq);
@@ -86,7 +86,7 @@
 	unsigned long flags;
 	unsigned char mask;
 	unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
-	unsigned char bit =  (1 << ((irq - MGATE_IRQ_LOW)%8) );
+	unsigned char bit =  (1 << ((irq - BIGSUR_IRQ_LOW)%8) );
 
 	if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {	
 	   	DPRINTK("Enable L1 IRQ %d\n", irq);
diff -urN linux-2.4.29/arch/sh/kernel/setup.c linux-2.4.29-uc1/arch/sh/kernel/setup.c
--- linux-2.4.29/arch/sh/kernel/setup.c	2003-08-25 12:44:40.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/kernel/setup.c	2005-06-14 02:10:58.000000000 +0100
@@ -4,6 +4,9 @@
  *
  *  Copyright (C) 1999  Niibe Yutaka
  *
+ * Modified by Rahul Chaturvedi on 22/06/2004 (justanotheraliasforrahul@yahoo.com)
+ * Lines 158-164 (For copying the ROMFS from the .bss image in ROM instead of RAM)
+ * 
  */
 
 /*
@@ -43,6 +46,7 @@
 #ifdef CONFIG_SH_EARLY_PRINTK
 #include <asm/sh_bios.h>
 #endif
+#include <asm/byteorder.h>
 
 #ifdef CONFIG_SH_KGDB
 #include <asm/kgdb.h>
@@ -96,7 +100,7 @@
 #define RAMDISK_FLAGS (*(unsigned long *) (PARAM+0x004))
 #define ORIG_ROOT_DEV (*(unsigned long *) (PARAM+0x008))
 #define LOADER_TYPE (*(unsigned long *) (PARAM+0x00c))
-#define INITRD_START (*(unsigned long *) (PARAM+0x010))
+#define INITRD_START __pa(*(unsigned long *) (PARAM+0x010))
 #define INITRD_SIZE (*(unsigned long *) (PARAM+0x014))
 /* ... */
 #define COMMAND_LINE ((char *) (PARAM+0x100))
@@ -106,6 +110,10 @@
 #define RAMDISK_PROMPT_FLAG		0x8000
 #define RAMDISK_LOAD_FLAG		0x4000	
 
+#ifdef CONFIG_COMMAND_LINE
+#undef COMMAND_LINE
+static char COMMAND_LINE[COMMAND_LINE_SIZE] = CONFIG_COMMAND_LINE_VALUE;
+#endif
 static char command_line[COMMAND_LINE_SIZE] = { 0, };
        char saved_command_line[COMMAND_LINE_SIZE];
 
@@ -135,14 +143,102 @@
 
 unsigned long memory_start, memory_end;
 
+
+#if defined(CONFIG_SH_SNAPGEAR)
+
+/*
+ * do not call printk in here,  bad things will happen,  the kernel isn't
+ * actually up yet,  we are called from head.S before BSS is cleared.
+ */
+
+extern void copy_romfs(void);
+void copy_romfs()
+{
+	unsigned long	*sp, *dp, len;
+	extern int __bss_start;
+#ifdef CONFIG_SH_ROMBOOT
+	extern int _mem_start, _rom_store;
+
+	sp = (unsigned long *) &__bss_start - ((_mem_start - _rom_store) / 4);
+#else
+	sp = (unsigned long *) &__bss_start;
+#endif
+	dp = (unsigned long *) &_end;
+
+	if (memcmp(&sp[0], "-rom1fs-", 8) == 0) { /* romfs */
+		len = be32_to_cpu(sp[2]);
+	} else if (sp[0] == 0x28cd3d45) { /* cramfs */
+		len = sp[1];
+	} else {
+		*dp = 0; /* make sure we don't see an old FS there */
+		return;
+	}
+
+	len = (len + 0xfff) & ~0xfff; /* make it a multiple of a page */
+	INITRD_SIZE = len;
+
+	sp += (len / 4);
+	dp += (len / 4);
+
+	/* copy backwards to avoid writing over ourselves */
+	while (dp >= ((unsigned long *) &_end))
+		*dp-- = *sp--;
+}
+#endif
+
+
+
 #ifdef CONFIG_SH_EARLY_PRINTK
+
+#ifndef CONFIG_SH_STANDARD_BIOS
+/*
+ * if we don't have a BIOS, assume the debug serial port for now.
+ */
+#if defined(__sh3__)
+#define SCBASE	0xa4000150
+#define	SCSSRT	short
+#define SCTDR ((volatile unsigned char *)   (SCBASE + 0x6))
+#define SCSSR ((volatile unsigned SCSSRT *) (SCBASE + 0x8))
+#elif defined(__SH4__)
+#define SCBASE	0xffe80000
+#define	SCSSRT	short
+#define SCTDR ((volatile unsigned char *)   (SCBASE + 0xc))
+#define SCSSR ((volatile unsigned SCSSRT *) (SCBASE + 0x10))
+#else
+#error "Unknown CPU type"
+#endif
+
+static void sci_put_char(char ch)
+{
+	unsigned SCSSRT status = 0;
+	while ((*SCSSR & 0x20) == 0)
+		;
+	*SCTDR = ch;
+	status = *SCSSR;
+	*SCSSR = status & ~0x20;
+}
+
+#endif
+
+
 /*
  *	Print a string through the BIOS
  */
 static void sh_console_write(struct console *co, const char *s,
 				 unsigned count)
 {
-    	sh_bios_console_write(s, count);
+#ifdef CONFIG_SH_STANDARD_BIOS
+	sh_bios_console_write(s, count);
+#else
+	int flags;
+	save_and_cli(flags);
+	while (count-- > 0) {
+		if (*s == '\n')
+			sci_put_char('\r');
+		sci_put_char(*s++);
+	}
+	restore_flags(flags);
+#endif
 }
 
 static kdev_t sh_console_device(struct console *c)
@@ -168,7 +264,7 @@
 	 *  	no idea what serial settings the BIOS is using, or
 	 *  	even if its using the serial port at all.
 	 */
-    	cflag |= B115200 | CS8 | /*no parity*/0;
+	cflag |= B115200 | CS8 | /*no parity*/0;
 
 	co->cflag = cflag;
 
@@ -176,7 +272,11 @@
 }
 
 static struct console sh_console = {
+#ifdef CONFIG_SH_STANDARD_BIOS
 	name:		"bios",
+#else
+	name:		"sci",
+#endif
 	write:		sh_console_write,
 	device:		sh_console_device,
 	setup:		sh_console_setup,
@@ -387,6 +487,11 @@
 	 * Partially used pages are not usable - thus
 	 * we are rounding upwards:
  	 */
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (INITRD_START == __pa(&_end))
+		start_pfn = PFN_UP(__pa(&_end) + INITRD_SIZE);
+	else
+#endif
 	start_pfn = PFN_UP(__pa(&_end));
 	/*
 	 * Find a proper area for the bootmem bitmap. After this
@@ -437,11 +542,15 @@
 	reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE);
 
 #ifdef CONFIG_BLK_DEV_INITRD
-	if (LOADER_TYPE && INITRD_START) {
+	if (LOADER_TYPE && INITRD_START && INITRD_SIZE) {
 		if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
-			reserve_bootmem_node(NODE_DATA(0), INITRD_START+__MEMORY_START, INITRD_SIZE);
-			initrd_start =
-				INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0;
+			if (INITRD_START == __pa(&_end)) {
+				initrd_start = INITRD_START + PAGE_OFFSET;
+			} else {
+				reserve_bootmem_node(NODE_DATA(0), INITRD_START+__MEMORY_START, INITRD_SIZE);
+				initrd_start =
+					INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0;
+			}
 			initrd_end = initrd_start + INITRD_SIZE;
 		} else {
 			printk("initrd extends beyond end of memory "
@@ -532,6 +641,13 @@
 #if defined(__sh3__)
 	seq_printf(m, "cpu family\t: SH-3\n"
 		      "cache size\t: 8K-byte\n");
+#if defined(CONFIG_SH_DSP)
+{
+	extern int sh3_dsp(void);
+	seq_printf(m, "dsp unit\t: %s\n",
+			(sh3_dsp() ? "present" : "not present"));
+}
+#endif
 #elif defined(__SH4__)
 	seq_printf(m, "cpu family\t: SH-4\n"
 		      "cache size\t: 8K-byte/16K-byte\n");
diff -urN linux-2.4.29/arch/sh/kernel/setup_hd64465.c linux-2.4.29-uc1/arch/sh/kernel/setup_hd64465.c
--- linux-2.4.29/arch/sh/kernel/setup_hd64465.c	2001-09-08 20:29:09.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/kernel/setup_hd64465.c	2005-06-14 02:10:58.000000000 +0100
@@ -199,7 +199,7 @@
 	outw(smscr & (~HD64465_SMSCR_UARTST), HD64465_REG_SMSCR);
 
 	/* remap IO ports for first ISA serial port to HD64465 UART */
-	hd64465_port_map(0x3f8, 8, CONFIG_HD64465_IOBASE + 0x8000, 1);
+	mach_port_map(0x3f8, 8, CONFIG_HD64465_IOBASE + 0x8000, 1);
 #endif
 
 	return 0;
diff -urN linux-2.4.29/arch/sh/kernel/setup_snapgear.c linux-2.4.29-uc1/arch/sh/kernel/setup_snapgear.c
--- linux-2.4.29/arch/sh/kernel/setup_snapgear.c	2003-08-25 12:44:40.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/kernel/setup_snapgear.c	2005-06-14 02:10:58.000000000 +0100
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/timer.h>
+#include <linux/ledman.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/sched.h>
@@ -34,7 +35,8 @@
 {
 #if defined(CONFIG_SH_SECUREEDGE5410)
 {
-	volatile char dummy = * (volatile char *) 0xb8000000;
+	volatile char dummy;
+	dummy = * (volatile char *) 0xb8000000;
 }
 #endif
 #ifdef CONFIG_LEDMAN
@@ -87,100 +89,25 @@
 
 /****************************************************************************/
 /*
- *	Fast poll interrupt simulator.
- */
-
-#define FAST_POLL	1000
-//#define FAST_POLL_INTR
-
-#define FASTTIMER_IRQ   17
-#define FASTTIMER_IPR_ADDR  INTC_IPRA
-#define FASTTIMER_IPR_POS    2
-#define FASTTIMER_PRIORITY   3
-
-#ifdef FAST_POLL_INTR
-#define TMU1_TCR_INIT	0x0020
-#else
-#define TMU1_TCR_INIT	0
-#endif
-#define TMU_TSTR_INIT	1
-#define TMU1_TCR_CALIB	0x0000
-#define TMU_TOCR	0xffd80000	/* Byte access */
-#define TMU_TSTR	0xffd80004	/* Byte access */
-#define TMU1_TCOR	0xffd80014	/* Long access */
-#define TMU1_TCNT	0xffd80018	/* Long access */
-#define TMU1_TCR	0xffd8001c	/* Word access */
-
-
-#ifdef FAST_POLL_INTR
-static void fast_timer_irq(int irq, void *dev_instance, struct pt_regs *regs)
-{
-	unsigned long timer_status;
-    timer_status = ctrl_inw(TMU1_TCR);
-	timer_status &= ~0x100;
-	ctrl_outw(timer_status, TMU1_TCR);
-}
-#endif
-
-/*
- * return the current ticks on the fast timer
+ * Initialize the board
  */
 
-unsigned long
-fast_timer_count(void)
+void __init
+setup_snapgear(void)
 {
-	return(ctrl_inl(TMU1_TCNT));
-}
+	extern void secureedge5410_rtc_init(void);
 
-/*
- * setup a fast timer for profiling etc etc
- */
-
-static void
-setup_fast_timer()
+#if defined(CONFIG_SH_SECUREEDGE5410)
 {
-	unsigned long interval;
-
-#ifdef FAST_POLL_INTR
-	interval = (current_cpu_data.module_clock/4 + FAST_POLL/2) / FAST_POLL;
-
-	make_ipr_irq(FASTTIMER_IRQ, FASTTIMER_IPR_ADDR, FASTTIMER_IPR_POS,
-			FASTTIMER_PRIORITY);
-
-	printk("SnapGear: %dHz fast timer on IRQ %d\n",FAST_POLL,FASTTIMER_IRQ);
-
-	if (request_irq(FASTTIMER_IRQ, fast_timer_irq, 0, "SnapGear fast timer",
-			NULL) != 0)
-		printk("%s(%d): request_irq() failed?\n", __FILE__, __LINE__);
-#else
-	printk("SnapGear: fast timer running\n",FAST_POLL,FASTTIMER_IRQ);
-	interval = 0xffffffff;
-#endif
-
-	ctrl_outb(ctrl_inb(TMU_TSTR) & ~0x2, TMU_TSTR); /* disable timer 1 */
-	ctrl_outw(TMU1_TCR_INIT, TMU1_TCR);
-	ctrl_outl(interval, TMU1_TCOR);
-	ctrl_outl(interval, TMU1_TCNT);
-	ctrl_outb(ctrl_inb(TMU_TSTR) | 0x2, TMU_TSTR); /* enable timer 1 */
-
-	printk("Timer count 1 = 0x%x\n", fast_timer_count());
-	udelay(1000);
-	printk("Timer count 2 = 0x%x\n", fast_timer_count());
+	volatile char dummy;
+	dummy = * (volatile char *) 0xb8000000;
 }
+#endif
 
-/****************************************************************************/
-/*
- * Initialize the board
- */
-
-void __init
-setup_snapgear(void)
-{
 	/* XXX: RTC setting comes here */
 #ifdef CONFIG_RTC
 	secureedge5410_rtc_init();
 #endif
- 	// setup_fast_timer();
 }
 
 /****************************************************************************/
diff -urN linux-2.4.29/arch/sh/kernel/sh_ksyms.c linux-2.4.29-uc1/arch/sh/kernel/sh_ksyms.c
--- linux-2.4.29/arch/sh/kernel/sh_ksyms.c	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-uc1/arch/sh/kernel/sh_ksyms.c	2005-06-14 02:10:58.000000000 +0100
@@ -81,8 +81,8 @@
 /* semaphore exports */
 EXPORT_SYMBOL(__up);
 EXPORT_SYMBOL(__down);
-EXPORT_SYMBOL(__down_interruptible);
 EXPORT_SYMBOL(__down_trylock);
+EXPORT_SYMBOL(__down_interruptible);
 
 /* Delay loops */
 EXPORT_SYMBOL(__ndelay);
@@ -99,8 +99,15 @@
 DECLARE_EXPORT(__lshrdi3);
 DECLARE_EXPORT(__movstr);
 
+#if defined(__sh3__) || defined(__SH4__)
+EXPORT_SYMBOL(__flush_purge_region);
+EXPORT_SYMBOL(__flush_wback_region);
+EXPORT_SYMBOL(__flush_invalidate_region);
+#endif
+
 #ifdef __SH4__
  
+DECLARE_EXPORT(__sdivsi3_i4);
 DECLARE_EXPORT(__movstr_i4_even);
 DECLARE_EXPORT(__movstr_i4_odd);
 
diff -urN linux-2.4.29/arch/sh/kernel/sys_sh.c linux-2.4.29-uc1/arch/sh/kernel/sys_sh.c
--- linux-2.4.29/arch/sh/kernel/sys_sh.c	2003-08-25 12:44:40.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/kernel/sys_sh.c	2005-06-14 02:10:58.000000000 +0100
@@ -253,7 +253,7 @@
 			break;
 	}
 	if (op & CACHEFLUSH_I) {
-		__flush_icache_all();
+		flush_icache_all();
 	}
 
 	return 0;
diff -urN linux-2.4.29/arch/sh/kernel/time.c linux-2.4.29-uc1/arch/sh/kernel/time.c
--- linux-2.4.29/arch/sh/kernel/time.c	2003-08-25 12:44:40.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/kernel/time.c	2005-06-14 02:10:58.000000000 +0100
@@ -37,7 +37,15 @@
 #include <linux/timex.h>
 #include <linux/irq.h>
 
+#ifdef CONFIG_KEYWEST
+#define PHCR 0xa400010e
+#define PHCR_IINT (~0xc000)
+#define TMU_TOCR_INIT	0x01
+#else
 #define TMU_TOCR_INIT	0x00	/* Don't output RTC clock */
+#endif
+#define TMU0_TCR_INIT	0x0020
+#define TMU_TSTR_INIT	1
 
 #define TMU0_TCR_INIT	0x0020	/* Clock/4, rising edge; interrupt on */
 #define TMU0_TCR_CALIB	0x0000	/* Clock/4, rising edge; no interrupt */
@@ -271,7 +279,6 @@
 	timer_status = ctrl_inw(TMU0_TCR);
 	timer_status &= ~0x100;
 	ctrl_outw(timer_status, TMU0_TCR);
-
 	/*
 	 * Here we are in the timer irq handler. We just have irqs locally
 	 * disabled but we don't know if the timer_bh is running on the other
@@ -294,7 +301,7 @@
 	/* Setup the timer:  We don't want to generate interrupts, just
 	 * have it count down at its natural rate.
 	 */
-	ctrl_outb(0, TMU_TSTR);
+	ctrl_outb(ctrl_inb(TMU_TSTR) & ~1, TMU_TSTR);
 #if !defined(CONFIG_CPU_SUBTYPE_SH7300)
 	ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
 #endif
@@ -302,17 +309,17 @@
 	ctrl_outl(0xffffffff, TMU0_TCOR);
 	ctrl_outl(0xffffffff, TMU0_TCNT);
 
-	rtc_gettimeofday(&tv2);
+	sh_rtc_gettimeofday(&tv2);
 
 	do {
-		rtc_gettimeofday(&tv1);
+		sh_rtc_gettimeofday(&tv1);
 	} while (tv1.tv_usec == tv2.tv_usec && tv1.tv_sec == tv2.tv_sec);
 
 	/* actually start the timer */
-	ctrl_outb(TMU0_TSTR_INIT, TMU_TSTR);
+	ctrl_outb(ctrl_inb(TMU_TSTR) | TMU_TSTR_INIT, TMU_TSTR);
 
 	do {
-		rtc_gettimeofday(&tv2);
+		sh_rtc_gettimeofday(&tv2);
 	} while (tv1.tv_usec == tv2.tv_usec && tv1.tv_sec == tv2.tv_sec);
 
 	freq = 0xffffffff - ctrl_inl(TMU0_TCNT);
@@ -434,6 +441,8 @@
 
 	setup_irq(TIMER_IRQ, &irq0);
 
+	timer_freq = get_timer_frequency();
+
 	if( sh_pclk_freq ){
 		module_clock = sh_pclk_freq;
 	}else{
@@ -534,8 +543,6 @@
 	       (module_clock/1000000), (module_clock % 1000000)/10000);
 	interval = (module_clock/4 + HZ/2) / HZ;
 
-	printk("Interval = %ld\n", interval);
-
 	current_cpu_data.cpu_clock    = cpu_clock;
 	current_cpu_data.master_clock = master_clock;
 	current_cpu_data.bus_clock    = bus_clock;
@@ -544,8 +551,14 @@
 #endif
 	current_cpu_data.module_clock = module_clock;
 
+#ifdef CONFIG_SH_KEYWEST
+#ifdef CONFIG_FB_MQ400
+	ctrl_outw(ctrl_inw(PHCR) & PHCR_INIT, PHCR); /* for MQ200 */
+#endif
+#endif
+
 	/* Stop all timers */
-	ctrl_outb(0, TMU_TSTR);
+	ctrl_outb(ctrl_inb(TMU_TSTR) & ~1, TMU_TSTR);
 #if !defined(CONFIG_CPU_SUBTYPE_SH7300)
 	ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
 #endif
@@ -554,7 +567,7 @@
 	ctrl_outw(TMU0_TCR_INIT, TMU0_TCR);
 	ctrl_outl(interval, TMU0_TCOR);
 	ctrl_outl(interval, TMU0_TCNT);
-	ctrl_outb(TMU0_TSTR_INIT, TMU_TSTR);
+	ctrl_outb(ctrl_inb(TMU_TSTR) | TMU_TSTR_INIT, TMU_TSTR);
 
 #if defined(CONFIG_START_TMU1)
 	/* Start TMU1 (free-running) */
diff -urN linux-2.4.29/arch/sh/kernel/traps.c linux-2.4.29-uc1/arch/sh/kernel/traps.c
--- linux-2.4.29/arch/sh/kernel/traps.c	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-uc1/arch/sh/kernel/traps.c	2005-06-14 02:10:58.000000000 +0100
@@ -653,3 +653,4 @@
 {
 	show_task((unsigned long *)tsk->thread.sp);
 }
+
diff -urN linux-2.4.29/arch/sh/lib/Makefile linux-2.4.29-uc1/arch/sh/lib/Makefile
--- linux-2.4.29/arch/sh/lib/Makefile	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-uc1/arch/sh/lib/Makefile	2005-06-14 02:10:58.000000000 +0100
@@ -3,9 +3,18 @@
 #
 
 L_TARGET = lib.a
-obj-y  = delay.o memcpy.o memset.o memmove.o memchr.o old-checksum.o \
+obj-y  = delay.o memset.o memmove.o memchr.o old-checksum.o \
 	 checksum.o strcasecmp.o strlen.o udivdi3.o div64.o
 
+ifeq ($(findstring y, \
+		$(CONFIG_CPU_SUBTYPE_SH7750) \
+		$(CONFIG_CPU_SUBTYPE_SH7751) \
+		),y)
+	obj-y += sh4-memcpy.o
+else
+	obj-y += memcpy.o
+endif
+
 USE_STANDARD_AS_RULE := true
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/sh/lib/sh4-memcpy.S linux-2.4.29-uc1/arch/sh/lib/sh4-memcpy.S
--- linux-2.4.29/arch/sh/lib/sh4-memcpy.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/lib/sh4-memcpy.S	2005-06-14 02:10:58.000000000 +0100
@@ -0,0 +1,800 @@
+/*
+ * "memcpy" implementation of SuperH
+ *
+ * Copyright (C) 1999  Niibe Yutaka
+ * Copyright (c) 2002  STMicroelectronics Ltd
+ *   Modified from memcpy.S and micro-optimised for SH4
+ *   Stuart Menefy (stuart.menefy@st.com)
+ *
+ */
+
+/*
+ * void *memcpy(void *dst, const void *src, size_t n);
+ *
+ * It is assumed that there is no overlap between src and dst.
+ * If there is an overlap, then the results are undefined.
+ */
+
+#include <linux/linkage.h>
+
+	!
+	!	GHIJ KLMN OPQR -->  ...G HIJK LMNO PQR.
+	!
+	
+	! Size is 16 or greater, and may have trailing bytes
+
+	.balign	32
+.Lcase1:
+	! Read a long word and write a long word at once
+	! At the start of each iteration, r7 contains last long load
+	add	#-1,r5		!  79 EX
+	mov	r4,r2		!   5 MT (0 cycles latency)
+
+	mov.l	@(r0,r5),r7	!  21 LS (2 cycles latency)
+	add	#-4,r5		!  50 EX
+
+	add	#7,r2		!  79 EX
+	!
+#ifdef __LITTLE_ENDIAN__
+	! 6 cycles, 4 bytes per iteration
+3:	mov.l	@(r0,r5),r1	!  21 LS (latency=2)	! NMLK
+	mov	r7, r3		!   5 MT (latency=0)	! RQPO
+	
+	cmp/hi	r2,r0		!  57 MT
+	shll16	r3		! 103 EX
+
+	mov	r1,r6		!   5 MT (latency=0)
+	shll8	r3		! 102 EX		! Oxxx
+
+	shlr8	r6		! 106 EX		! xNML
+	mov	r1, r7		!   5 MT (latency=0)
+	
+	or	r6,r3		!  82 EX		! ONML
+	bt/s	3b		! 109 BR
+
+	 mov.l	r3,@-r0		!  30 LS
+#else
+3:	mov.l	@(r0,r5),r1	!  21 LS (latency=2)	! KLMN
+	mov	r7,r3		!   5 MT (latency=0)	! OPQR
+
+	cmp/hi	r2,r0		!  57 MT
+	shlr16	r3		! 107 EX
+
+	shlr8	r3		! 106 EX		! xxxO
+	mov	r1,r6		!   5 MT (latency=0)
+
+	shll8	r6		! 102 EX		! LMNx
+	mov	r1,r7		!   5 MT (latency=0)
+
+	or	r6,r3		!  82 EX		! LMNO
+	bt/s	3b		! 109 BR
+
+	 mov.l	r3,@-r0		!  30 LS
+#endif
+	! Finally, copy a byte at once, if necessary
+
+	add	#4,r5		!  50 EX
+	cmp/eq	r4,r0		!  54 MT
+
+	add	#-6,r2		!  50 EX
+	bt	9f		! 109 BR
+
+8:	cmp/hi	r2,r0		!  57 MT
+	mov.b	@(r0,r5),r1	!  20 LS (latency=2)
+	
+	bt/s	8b		! 109 BR
+
+	 mov.b	r1,@-r0		!  29 LS
+
+9:	rts
+	 nop
+
+	
+	!
+	!	GHIJ KLMN OPQR -->  .GHI JKLM NOPQ R...
+	!
+	
+	! Size is 16 or greater, and may have trailing bytes
+
+	.balign	32
+.Lcase3:
+	! Read a long word and write a long word at once
+	! At the start of each iteration, r7 contains last long load
+	add	#-3,r5		! 79 EX
+	mov	r4,r2		!  5 MT (0 cycles latency)
+
+	mov.l	@(r0,r5),r7	! 21 LS (2 cycles latency)
+	add	#-4,r5		! 50 EX
+
+	add	#7,r2		!  79 EX
+	!
+#ifdef __LITTLE_ENDIAN__
+	! 6 cycles, 4 bytes per iteration
+3:	mov.l	@(r0,r5),r1	!  21 LS (latency=2)	! NMLK
+	mov	r7, r3		!   5 MT (latency=0)	! RQPO
+	
+	cmp/hi	r2,r0		!  57 MT
+	shll8	r3		! 102 EX		! QPOx
+
+	mov	r1,r6		!   5 MT (latency=0)
+	shlr16	r6		! 107 EX
+
+	shlr8	r6		! 106 EX		! xxxN
+	mov	r1, r7		!   5 MT (latency=0)
+	
+	or	r6,r3		!  82 EX		! QPON
+	bt/s	3b		! 109 BR
+
+	 mov.l	r3,@-r0		!  30 LS
+#else
+3:	mov	r1,r3		! OPQR
+	shlr8	r3		! xOPQ
+	mov.l	@(r0,r5),r1	! KLMN
+	mov	r1,r6
+	shll16	r6
+	shll8	r6		! Nxxx
+	or	r6,r3		! NOPQ
+	cmp/hi	r2,r0
+	bt/s	3b
+	 mov.l	r3,@-r0
+#endif
+
+	! Finally, copy a byte at once, if necessary
+
+	add	#6,r5		!  50 EX
+	cmp/eq	r4,r0		!  54 MT
+
+	add	#-6,r2		!  50 EX
+	bt	9f		! 109 BR
+
+8:	cmp/hi	r2,r0		!  57 MT
+	mov.b	@(r0,r5),r1	!  20 LS (latency=2)
+	
+	bt/s	8b		! 109 BR
+
+	 mov.b	r1,@-r0		!  29 LS
+
+9:	rts
+	 nop
+	
+ENTRY(memcpy)
+
+	! Calculate the invariants which will be used in the remainder
+	! of the code:
+	!
+	!      r4   -->  [ ...  ] DST             [ ...  ] SRC
+	!	         [ ...  ]                 [ ...  ]
+	!	           :                        :
+	!      r0   -->  [ ...  ]       r0+r5 --> [ ...  ]
+	!
+	!
+	
+	! Short circuit the common case of src, dst and len being 32 bit aligned
+	! and test for zero length move
+
+	mov	r6, r0		!   5 MT (0 cycle latency)
+	or	r4, r0		!  82 EX
+
+	or	r5, r0		!  82 EX
+	tst	r6, r6		!  86 MT
+
+	bt/s	99f		! 111 BR		(zero len)
+	 tst	#3, r0		!  87 MT
+
+	mov	r4, r0		!   5 MT (0 cycle latency)
+	add	r6, r0		!  49 EX
+
+	mov	#16, r1		!   6 EX
+	bt/s	.Lcase00	! 111 BR		(aligned)
+
+	 sub	r4, r5		!  75 EX
+
+	! Arguments are not nicely long word aligned or zero len.
+	! Check for small copies, and if so do a simple byte at a time copy.
+	!
+	! Deciding on an exact value of 'small' is not easy, as the point at which
+	! using the optimised routines become worthwhile varies (these are the
+	! cycle counts for differnet sizes using byte-at-a-time vs. optimised):
+	!	size	byte-at-time	long	word	byte
+	!	16	42		39-40	46-50	50-55
+	!	24	58		43-44	54-58	62-67
+	!	36	82		49-50	66-70	80-85
+	! However the penalty for getting it 'wrong' is much higher for long word
+	! aligned data (and this is more common), so use a value of 16.
+	
+	cmp/gt	r6,r1		!  56 MT
+
+	add	#-1,r5		!  50 EX
+	bf/s	6f		! 108 BR		(not small)
+
+	 mov	r5, r3		!   5 MT (latency=0)
+	shlr	r6		! 104 EX
+
+	mov.b	@(r0,r5),r1	!  20 LS (latency=2)
+	bf/s	4f		! 111 BR
+	
+	 add	#-1,r3		!  50 EX
+	tst	r6, r6		!  86 MT
+
+	bt/s	98f		! 110 BR
+	 mov.b	r1,@-r0		!  29 LS
+
+	! 4 cycles, 2 bytes per iteration
+3:	mov.b	@(r0,r5),r1	!  20 LS (latency=2)
+
+4:	mov.b	@(r0,r3),r2	!  20 LS (latency=2)
+	dt	r6		!  67 EX
+
+	mov.b	r1,@-r0		!  29 LS
+	bf/s	3b		! 111 BR
+
+	 mov.b	r2,@-r0		!  29 LS
+98:
+	rts
+	 nop
+
+99:	rts
+	 mov	r4, r0
+
+	! Size is not small, so its worthwhile looking for optimisations.
+	! First align destination to a long word boundary.
+	!
+	! r5 = normal value -1
+
+6:	tst	#3, r0		!  87 MT
+        mov	#3, r3		!   6 EX
+
+	bt/s	2f		! 111 BR
+	 and	r0,r3		!  78 EX
+
+	! 3 cycles, 1 byte per iteration	
+1:	dt	r3		!  67 EX
+	mov.b	@(r0,r5),r1	!  19 LS (latency=2)
+
+	add	#-1, r6		!  79 EX
+	bf/s	1b		! 109 BR
+
+	 mov.b	r1,@-r0		!  28 LS
+
+2:	add	#1, r5		!  79 EX
+	
+	! Now select the appropriate bulk transfer code based on relative
+	! alignment of src and dst.
+	
+	mov	r0, r3		!   5 MT (latency=0)
+
+	mov	r5, r0		!   5 MT (latency=0)
+	tst	#1, r0		!  87 MT
+
+	bf/s	1f		! 111 BR
+	 mov	#64, r7		!   6 EX
+
+	! bit 0 clear
+		
+	cmp/ge	r7, r6		!  55 MT
+
+	bt/s	2f		! 111 BR
+	 tst	#2, r0		!  87 MT
+
+	! small
+	bt/s	.Lcase0
+	 mov	r3, r0
+
+	bra	.Lcase2
+	 nop
+
+	! big
+2:	bt/s	.Lcase0b
+	 mov	r3, r0
+
+	bra	.Lcase2b
+	 nop
+	
+	! bit 0 set
+1:	tst	#2, r0		! 87 MT
+
+	bt/s	.Lcase1
+	 mov	r3, r0
+
+	bra	.Lcase3
+	 nop
+	
+
+	!
+	!	GHIJ KLMN OPQR -->  GHIJ KLMN OPQR
+	!
+
+	! src, dst and size are all long word aligned
+	! size is non-zero
+	
+	.balign	32
+.Lcase00:
+	mov	#64, r1		!   6 EX
+	mov	r5, r3		!   5 MT (latency=0)
+
+	cmp/gt	r6, r1		!  56 MT
+	add	#-4, r5		!  50 EX
+
+	bf	.Lcase00b	! 108 BR		(big loop)
+	shlr2	r6		! 105 EX
+
+	shlr	r6		! 104 EX
+	mov.l	@(r0, r5), r1	!  21 LS (latency=2)	
+
+	bf/s	4f		! 111 BR
+	 add	#-8, r3		!  50 EX
+
+	tst	r6, r6		!  86 MT
+	bt/s	5f		! 110 BR
+
+	 mov.l	r1,@-r0		!  30 LS
+
+	! 4 cycles, 2 long words per iteration
+3:	mov.l	@(r0, r5), r1	!  21 LS (latency=2)
+
+4:	mov.l	@(r0, r3), r2	!  21 LS (latency=2)
+	dt	r6		!  67 EX
+
+	mov.l	r1, @-r0	!  30 LS
+	bf/s	3b		! 109 BR
+
+	 mov.l	r2, @-r0	!  30 LS
+
+5:	rts
+	 nop
+
+	
+	! Size is 16 or greater and less than 64, but may have trailing bytes
+
+	.balign	32
+.Lcase0:
+	add	#-4, r5		!  50 EX
+	mov	r4, r7		!   5 MT (latency=0)
+
+	mov.l	@(r0, r5), r1	!  21 LS (latency=2)	
+	mov	#4, r2		!   6 EX
+
+	add	#11, r7		!  50 EX
+	tst	r2, r6		!  86 MT
+
+	mov	r5, r3		!   5 MT (latency=0)
+	bt/s	4f		! 111 BR
+
+	 add	#-4, r3		!  50 EX
+	mov.l	r1,@-r0		!  30 LS
+
+	! 4 cycles, 2 long words per iteration
+3:	mov.l	@(r0, r5), r1	!  21 LS (latency=2)
+
+4:	mov.l	@(r0, r3), r2	!  21 LS (latency=2)
+	cmp/hi	r7, r0
+
+	mov.l	r1, @-r0	!  30 LS
+	bt/s	3b		! 109 BR
+
+	 mov.l	r2, @-r0	!  30 LS
+
+	! Copy the final 0-3 bytes
+
+	add	#3,r5		!  50 EX
+	
+	cmp/eq	r0, r4		!  54 MT
+	add	#-10, r7	!  50 EX
+
+	bt	9f		! 110 BR
+
+	! 3 cycles, 1 byte per iteration
+1:	mov.b	@(r0,r5),r1	!  19 LS
+	cmp/hi	r7,r0		!  57 MT
+	
+	bt/s	1b		! 111 BR
+	 mov.b	r1,@-r0		!  28 LS
+
+9:	rts
+	 nop
+
+	! Size is at least 64 bytes, so will be going round the big loop at least once.
+	!
+	!   r2 = rounded up r4
+	!   r3 = rounded down r0
+
+	.balign	32
+.Lcase0b:
+	add	#-4, r5		!  50 EX
+
+.Lcase00b:
+	mov	r0, r3		!   5 MT (latency=0)
+	mov	#(~0x1f), r1	!   6 EX
+
+	and	r1, r3		!  78 EX
+	mov	r4, r2		!   5 MT (latency=0)
+
+	cmp/eq	r3, r0		!  54 MT
+	add	#0x1f, r2	!  50 EX
+
+	bt/s	1f		! 110 BR
+	 and	r1, r2		!  78 EX
+
+	! copy initial words until cache line aligned
+
+	mov.l	@(r0, r5), r1	!  21 LS (latency=2)
+	tst	#4, r0		!  87 MT
+
+	mov	r5, r6		!   5 MT (latency=0)
+	add	#-4, r6		!  50 EX
+
+	bt/s	4f		! 111 BR
+	 add	#8, r3		!  50 EX
+
+	tst	#0x18, r0	!  87 MT
+	
+	bt/s	1f		! 109 BR
+	 mov.l	r1,@-r0		!  30 LS
+	
+	! 4 cycles, 2 long words per iteration
+3:	mov.l	@(r0, r5), r1	!  21 LS (latency=2)
+
+4:	mov.l	@(r0, r6), r7	!  21 LS (latency=2)
+	cmp/eq	r3, r0		!  54 MT
+
+	mov.l	r1, @-r0	!  30 LS
+	bf/s	3b		! 109 BR
+
+	 mov.l	r7, @-r0	!  30 LS
+
+	! Copy the cache line aligned blocks
+	!
+	! In use: r0, r2, r4, r5
+	! Scratch: r1, r3, r6, r7
+	!
+	! We could do this with the four scratch registers, but if src
+	! and dest hit the same cache line, this will thrash, so make
+	! use of additional registers.
+	! 
+	! We also need r0 as a temporary (for movca), so 'undo' the invariant:
+	!   r5:	 src (was r0+r5)
+	!   r1:	 dest (was r0)
+	! this can be reversed at the end, so we don't need to save any extra
+	! state.
+	!
+1:	mov.l	r8, @-r15	!  30 LS
+	add	r0, r5		!  49 EX
+	
+	mov.l	r9, @-r15	!  30 LS
+	mov	r0, r1		!   5 MT (latency=0)
+	
+	mov.l	r10, @-r15	!  30 LS
+	add	#-0x1c, r5	!  50 EX
+	
+	mov.l	r11, @-r15	!  30 LS			
+
+	! 16 cycles, 32 bytes per iteration
+2:	mov.l	@(0x00,r5),r0	! 18 LS (latency=2)
+	add	#-0x20, r1	! 50 EX
+	mov.l	@(0x04,r5),r3	! 18 LS (latency=2)
+	mov.l	@(0x08,r5),r6	! 18 LS (latency=2)
+	mov.l	@(0x0c,r5),r7	! 18 LS (latency=2)
+	mov.l	@(0x10,r5),r8	! 18 LS (latency=2)
+	mov.l	@(0x14,r5),r9	! 18 LS (latency=2)
+	mov.l	@(0x18,r5),r10	! 18 LS (latency=2)
+	mov.l	@(0x1c,r5),r11	! 18 LS (latency=2)
+	movca.l	r0,@r1		! 40 LS (latency=3-7)
+	mov.l	r3,@(0x04,r1)	! 33 LS
+	mov.l	r6,@(0x08,r1)	! 33 LS
+	mov.l	r7,@(0x0c,r1)	! 33 LS
+
+	mov.l	r8,@(0x10,r1)	! 33 LS
+	add	#-0x20, r5	! 50 EX
+
+	mov.l	r9,@(0x14,r1)	! 33 LS
+	cmp/eq	r2,r1		! 54 MT
+
+	mov.l	r10,@(0x18,r1)	!  33 LS
+	bf/s	2b		! 109 BR
+
+	 mov.l	r11,@(0x1c,r1)	!  33 LS
+
+	mov	r1, r0		!   5 MT (latency=0)
+
+	mov.l	@r15+, r11	!  15 LS
+	sub	r1, r5		!  75 EX
+
+	mov.l	@r15+, r10	!  15 LS
+	cmp/eq	r4, r0		!  54 MT
+
+	bf/s	1f		! 109 BR
+	 mov.l	 @r15+, r9	!  15 LS
+
+	rts
+1:	 mov.l	@r15+, r8	!  15 LS
+	sub	r4, r1		!  75 EX		(len remaining)
+
+	! number of trailing bytes is non-zero
+	!	
+	! invariants restored (r5 already decremented by 4)
+	! also r1=num bytes remaining
+	
+	mov	#4, r2		!   6 EX
+	mov	r4, r7		!   5 MT (latency=0)
+
+	add	#0x1c, r5	!  50 EX		(back to -4)
+	cmp/hs	r2, r1		!  58 MT
+
+	bf/s	5f		! 108 BR
+	 add	 #11, r7	!  50 EX
+
+	mov.l	@(r0, r5), r6	!  21 LS (latency=2)	
+	tst	r2, r1		!  86 MT
+
+	mov	r5, r3		!   5 MT (latency=0)
+	bt/s	4f		! 111 BR
+
+	 add	#-4, r3		!  50 EX
+	cmp/hs	r2, r1		!  58 MT
+
+	bt/s	5f		! 111 BR
+	 mov.l	r6,@-r0		!  30 LS
+
+	! 4 cycles, 2 long words per iteration
+3:	mov.l	@(r0, r5), r6	!  21 LS (latency=2)
+
+4:	mov.l	@(r0, r3), r2	!  21 LS (latency=2)
+	cmp/hi	r7, r0
+
+	mov.l	r6, @-r0	!  30 LS
+	bt/s	3b		! 109 BR
+
+	 mov.l	r2, @-r0	!  30 LS
+
+	! Copy the final 0-3 bytes
+
+5:	cmp/eq	r0, r4		!  54 MT
+	add	#-10, r7	!  50 EX
+
+	bt	9f		! 110 BR
+	add	#3,r5		!  50 EX
+	
+	! 3 cycles, 1 byte per iteration
+1:	mov.b	@(r0,r5),r1	!  19 LS
+	cmp/hi	r7,r0		!  57 MT
+	
+	bt/s	1b		! 111 BR
+	 mov.b	r1,@-r0		!  28 LS
+
+9:	rts
+	 nop
+
+	!
+	!	GHIJ KLMN OPQR -->  ..GH IJKL MNOP QR..
+	!
+		
+	.balign	32
+.Lcase2:
+	! Size is 16 or greater and less then 64, but may have trailing bytes
+
+2:	mov	r5, r6		!   5 MT (latency=0)
+	add	#-2,r5		!  50 EX
+
+	mov	r4,r2		!   5 MT (latency=0)
+	add	#-4,r6		!  50 EX
+
+	add	#7,r2		!  50 EX
+3:	mov.w	@(r0,r5),r1	!  20 LS (latency=2)
+
+	mov.w	@(r0,r6),r3	!  20 LS (latency=2)
+	cmp/hi	r2,r0		!  57 MT
+
+	mov.w	r1,@-r0		!  29 LS
+	bt/s	3b		! 111 BR
+
+	 mov.w	r3,@-r0		!  29 LS
+
+	bra	10f
+	 nop
+
+
+	.balign	32
+.Lcase2b:
+	! Size is at least 64 bytes, so will be going round the big loop at least once.
+	!
+	!   r2 = rounded up r4
+	!   r3 = rounded down r0
+
+	mov	r0, r3		!   5 MT (latency=0)
+	mov	#(~0x1f), r1	!   6 EX
+
+	and	r1, r3		!  78 EX
+	mov	r4, r2		!   5 MT (latency=0)
+
+	cmp/eq	r3, r0		!  54 MT
+	add	#0x1f, r2	!  50 EX
+	
+	add	#-2, r5		!  50 EX
+	bt/s	1f		! 110 BR
+	 and	r1, r2		!  78 EX
+	
+	! Copy a short word one at a time until we are cache line aligned
+	!   Normal values: r0, r2, r3, r4
+	!   Unused: r1, r6, r7
+	!   Mod: r5 (=r5-2)
+	!
+	add	#2, r3		!  50 EX
+	
+2:	mov.w	@(r0,r5),r1	!  20 LS (latency=2)
+	cmp/eq	r3,r0		!  54 MT
+		
+	bf/s	2b		! 111 BR
+
+	 mov.w	r1,@-r0		!  29 LS
+
+	! Copy the cache line aligned blocks
+	!
+	! In use: r0, r2, r4, r5 (=r5-2)
+	! Scratch: r1, r3, r6, r7
+	!
+	! We could do this with the four scratch registers, but if src
+	! and dest hit the same cache line, this will thrash, so make
+	! use of additional registers.
+	! 
+	! We also need r0 as a temporary (for movca), so 'undo' the invariant:
+	!   r5:	 src (was r0+r5)
+	!   r1:	 dest (was r0)
+	! this can be reversed at the end, so we don't need to save any extra
+	! state.
+	!
+1:	mov.l	r8, @-r15	!  30 LS
+	add	r0, r5		!  49 EX
+	
+	mov.l	r9, @-r15	!  30 LS
+	mov	r0, r1		!   5 MT (latency=0)
+	
+	mov.l	r10, @-r15	!  30 LS
+	add	#-0x1e, r5	!  50 EX
+	
+	mov.l	r11, @-r15	!  30 LS			
+	
+	mov.l	r12, @-r15	!  30 LS			
+
+	! 17 cycles, 32 bytes per iteration
+#ifdef __LITTLE_ENDIAN__
+2:	mov.w	@r5+, r0	!  14 LS (latency=2)		..JI
+	add	#-0x20, r1	!  50 EX
+
+	mov.l	@r5+, r3	!  15 LS (latency=2)		NMLK
+
+	mov.l	@r5+, r6	!  15 LS (latency=2)		RQPO
+	shll16	r0		! 103 EX			JI..
+
+	mov.l	@r5+, r7	!  15 LS (latency=2)
+	xtrct	r3, r0		!  48 EX			LKJI
+
+	mov.l	@r5+, r8	!  15 LS (latency=2)
+	xtrct	r6, r3		!  48 EX			PONM
+
+	mov.l	@r5+, r9	!  15 LS (latency=2)
+	xtrct	r7, r6		!  48 EX
+
+	mov.l	@r5+, r10	!  15 LS (latency=2)
+	xtrct	r8, r7		!  48 EX
+
+	mov.l	@r5+, r11	!  15 LS (latency=2)
+	xtrct	r9, r8		!  48 EX
+
+	mov.w	@r5+, r12	!  15 LS (latency=2)
+	xtrct	r10, r9		!  48 EX
+
+	movca.l	r0,@r1		!  40 LS (latency=3-7)
+	xtrct	r11, r10	!  48 EX
+
+	mov.l	r3, @(0x04,r1)	!  33 LS
+	xtrct	r12, r11	!  48 EX
+
+	mov.l	r6, @(0x08,r1)	!  33 LS
+	
+	mov.l	r7, @(0x0c,r1)	!  33 LS
+
+	mov.l	r8, @(0x10,r1)	!  33 LS
+	add	#-0x40, r5	!  50 EX
+
+	mov.l	r9, @(0x14,r1)	!  33 LS
+	cmp/eq	r2,r1		!  54 MT
+
+	mov.l	r10, @(0x18,r1)	!  33 LS
+	bf/s	2b		! 109 BR
+
+	 mov.l	r11, @(0x1c,r1)	!  33 LS
+#else
+2:	mov.w	@(0x1e,r5), r0	!  17 LS (latency=2)
+	add	#-2, r5		!  50 EX
+
+	mov.l	@(0x1c,r5), r3	!  18 LS (latency=2)
+	add	#-4, r1		!  50 EX
+
+	mov.l	@(0x18,r5), r6	!  18 LS (latency=2)
+	shll16	r0		! 103 EX
+
+	mov.l	@(0x14,r5), r7	!  18 LS (latency=2)
+	xtrct	r3, r0		!  48 EX
+
+	mov.l	@(0x10,r5), r8	!  18 LS (latency=2)
+	xtrct	r6, r3		!  48 EX
+
+	mov.l	@(0x0c,r5), r9	!  18 LS (latency=2)
+	xtrct	r7, r6		!  48 EX
+
+	mov.l	@(0x08,r5), r10	!  18 LS (latency=2)
+	xtrct	r8, r7		!  48 EX
+
+	mov.l	@(0x04,r5), r11	!  18 LS (latency=2)
+	xtrct	r9, r8		!  48 EX
+
+	mov.w	@(0x02,r5), r12	!  18 LS (latency=2)
+	xtrct	r10, r9		!  48 EX
+
+	movca.l	r0,@r1		!  40 LS (latency=3-7)
+	add	#-0x1c, r1	!  50 EX
+
+	mov.l	r3, @(0x1c,r1)	!  33 LS
+	xtrct	r11, r10	!  48 EX
+
+	mov.l	r6, @(0x18,r1)	!  33 LS
+	xtrct	r12, r11	!  48 EX
+	
+	mov.l	r7, @(0x14,r1)	!  33 LS
+
+	mov.l	r8, @(0x10,r1)	!  33 LS
+	add	#-0x3e, r5	!  50 EX
+
+	mov.l	r9, @(0x0c,r1)	!  33 LS
+	cmp/eq	r2,r1		!  54 MT
+
+	mov.l	r10, @(0x08,r1)	!  33 LS
+	bf/s	2b		! 109 BR
+
+	 mov.l	r11, @(0x04,r1)	!  33 LS
+#endif
+
+	mov.l	@r15+, r12
+	mov	r1, r0		!   5 MT (latency=0)
+
+	mov.l	@r15+, r11	!  15 LS
+	sub	r1, r5		!  75 EX
+
+	mov.l	@r15+, r10	!  15 LS
+	cmp/eq	r4, r0		!  54 MT
+
+	bf/s	1f		! 109 BR
+	 mov.l	 @r15+, r9	!  15 LS
+
+	rts
+1:	 mov.l	@r15+, r8	!  15 LS
+
+	add	#0x1e, r5	!  50 EX
+	
+	! Finish off a short word at a time
+	! r5 must be invariant - 2
+10:	mov	r4,r2		!   5 MT (latency=0)
+	add	#1,r2		!  50 EX
+
+	cmp/hi	r2, r0		!  57 MT
+	bf/s	1f		! 109 BR
+
+	 add	#2, r2		!  50 EX
+	
+3:	mov.w	@(r0,r5),r1	!  20 LS
+	cmp/hi	r2,r0		!  57 MT
+
+	bt/s	3b		! 109 BR
+
+	 mov.w	r1,@-r0		!  29 LS
+1:
+		
+	!
+	! Finally, copy the last byte if necessary
+	cmp/eq	r4,r0		!  54 MT
+	bt/s	9b
+	 add	#1,r5
+	mov.b	@(r0,r5),r1
+	rts
+	 mov.b	r1,@-r0
+
diff -urN linux-2.4.29/arch/sh/Makefile linux-2.4.29-uc1/arch/sh/Makefile
--- linux-2.4.29/arch/sh/Makefile	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-uc1/arch/sh/Makefile	2005-06-14 02:10:58.000000000 +0100
@@ -11,6 +11,9 @@
 # for "archclean" and "archdep" for cleaning up and making dependencies for
 # this architecture
 #
+# Modified by Rahul Chaturvedi on 22/06/2004 (justanotheraliasforrahul@yahoo.com)
+# to add support to use the vmlinux.lds.rom.S file when specified by the user
+#
 
 ifdef CONFIG_CPU_LITTLE_ENDIAN
 CFLAGS		+= -ml
@@ -49,10 +52,15 @@
 AFLAGS		+= -m3
 endif
 ifdef CONFIG_CPU_SH4
-CFLAGS		+= -m4 -mno-implicit-fp
-AFLAGS		+= -m4 -mno-implicit-fp
+CFLAGS		+= -m4 -m4-nofpu # -mno-implicit-fp
+AFLAGS		+= -m4 -m4-nofpu # -mno-implicit-fp
 endif
 
+cpuincdir-$(CONFIG_CPU_SH2) := cpu-sh2
+cpuincdir-$(CONFIG_CPU_SH3) := cpu-sh3
+cpuincdir-$(CONFIG_CPU_SH4) := cpu-sh4
+
+
 #
 # Choosing incompatible machines durings configuration will result in
 # error messages during linking.  Select a default linkscript if
@@ -66,7 +74,7 @@
 endif
 
 #
-CFLAGS		+= -pipe
+CFLAGS		+= -pipe -O1
 
 HEAD := arch/sh/kernel/head.o arch/sh/kernel/init_task.o
 
@@ -76,6 +84,14 @@
 LIBS := $(TOPDIR)/arch/sh/lib/lib.a $(LIBS) $(TOPDIR)/arch/sh/lib/lib.a \
 	$(LIBGCC)
 
+#
+# If you want the kernel build to build modules outside of the tree
+# then define this and pass it to the main linux makefile
+#
+ifdef EXTRA_MODULE_DIRS
+SUBDIRS += $(EXTRA_MODULE_DIRS)
+endif
+
 MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
 
 ifneq ($(CONFIG_SH_GENERIC)$(CONFIG_SH_STB1_HARP)$(CONFIG_SH_STB1_OVERDRIVE),)
@@ -85,8 +101,19 @@
 
 vmlinux: arch/sh/vmlinux.lds
 
+.PHONY: target_links
+target_links:
+	@echo '  Making asm-sh/cpu -> asm-sh/$(cpuincdir-y) link'
+	@rm -f include/asm-sh/cpu
+	@ln -sf $(cpuincdir-y) include/asm-sh/cpu
+
+ifdef CONFIG_SH_ROMBOOT
+arch/sh/vmlinux.lds: arch/sh/vmlinux.lds.rom.S FORCE
+	$(CPP) -traditional -C -P -I$(HPATH) -Ush arch/sh/vmlinux.lds.rom.S >arch/sh/vmlinux.lds
+else
 arch/sh/vmlinux.lds: arch/sh/vmlinux.lds.S FORCE
 	$(CPP) -traditional -C -P -I$(HPATH) -Ush arch/sh/vmlinux.lds.S >arch/sh/vmlinux.lds
+endif
 
 FORCE: ;
 
@@ -107,5 +134,6 @@
 archmrproper:
 	rm -f arch/sh/vmlinux.lds
 
-archdep:
+archdep: target_links
 	@$(MAKEBOOT) dep
+
diff -urN linux-2.4.29/arch/sh/mm/cache-sh3.c linux-2.4.29-uc1/arch/sh/mm/cache-sh3.c
--- linux-2.4.29/arch/sh/mm/cache-sh3.c	2001-10-15 21:36:48.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/mm/cache-sh3.c	2005-06-14 02:10:58.000000000 +0100
@@ -1,9 +1,9 @@
-/* $Id: cache-sh3.c,v 1.6 2001/09/10 08:59:59 dwmw2 Exp $
+/* $Id: cache-sh3.c,v 1.7 2003/08/28 16:16:09 lethal Exp $
  *
  *  linux/arch/sh/mm/cache-sh3.c
  *
  * Copyright (C) 1999, 2000  Niibe Yutaka
- *
+ * Copyright (C) 2002 Paul Mundt
  */
 
 #include <linux/init.h>
@@ -19,71 +19,9 @@
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
 
-
-#define CCR		0xffffffec	/* Address of Cache Control Register */
-
-#define CCR_CACHE_CE	0x01	/* Cache Enable */
-#define CCR_CACHE_WT	0x02	/* Write-Through (for P0,U0,P3) (else writeback) */
-#define CCR_CACHE_CB	0x04	/* Write-Back (for P1) (else writethrough) */
-#define CCR_CACHE_CF	0x08	/* Cache Flush */
-#define CCR_CACHE_RA	0x20	/* RAM mode */
-
-#define CCR_CACHE_VAL	(CCR_CACHE_CB|CCR_CACHE_CE)	/* 8k-byte cache, P1-wb, enable */
-#define CCR_CACHE_INIT	(CCR_CACHE_CF|CCR_CACHE_VAL)	/* 8k-byte cache, CF, P1-wb, enable */
-
-#define CACHE_OC_ADDRESS_ARRAY 0xf0000000
-#define CACHE_VALID	  1
-#define CACHE_UPDATED	  2
-#define CACHE_PHYSADDR_MASK 0x1ffffc00
-
-/* 7709A/7729 has 16K cache (256-entry), while 7702 has only 2K(direct)
-   7702 is not supported (yet) */
-struct _cache_system_info {
-	int way_shift;
-	int entry_mask;
-	int num_entries;
-};
-
-/* Data at BSS is cleared after setting this variable.
-   So, we Should not placed this variable at BSS section.
-   Initialize this, it is placed at data section. */
-static struct _cache_system_info cache_system_info = {0,};
-
-#define CACHE_OC_WAY_SHIFT	(cache_system_info.way_shift)
-#define CACHE_OC_ENTRY_SHIFT    4
-#define CACHE_OC_ENTRY_MASK	(cache_system_info.entry_mask)
-#define CACHE_OC_NUM_ENTRIES	(cache_system_info.num_entries)
-#define CACHE_OC_NUM_WAYS	4
-#define CACHE_OC_ASSOC_BIT    (1<<3)
-
-
-/*
- * Write back all the cache.
- *
- * For SH-4, we only need to flush (write back) Operand Cache,
- * as Instruction Cache doesn't have "updated" data.
- *
- * Assumes that this is called in interrupt disabled context, and P2.
- * Shuld be INLINE function.
- */
-static inline void cache_wback_all(void)
-{
-	unsigned long addr, data, i, j;
-
-	for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
-		for (j=0; j<CACHE_OC_NUM_WAYS; j++) {
-			addr = CACHE_OC_ADDRESS_ARRAY|(j<<CACHE_OC_WAY_SHIFT)|
-				(i<<CACHE_OC_ENTRY_SHIFT);
-			data = ctrl_inl(addr);
-			if ((data & (CACHE_UPDATED|CACHE_VALID))
-			    == (CACHE_UPDATED|CACHE_VALID))
-				ctrl_outl(data & ~CACHE_UPDATED, addr);
-		}
-	}
-}
-
-static void __init
+int __init
 detect_cpu_and_cache_system(void)
 {
 	unsigned long addr0, addr1, data0, data1, data2, data3;
@@ -99,54 +37,55 @@
 
 	/* First, write back & invalidate */
 	data0  = ctrl_inl(addr0);
-	ctrl_outl(data0&~(CACHE_VALID|CACHE_UPDATED), addr0);
+	ctrl_outl(data0&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr0);
 	data1  = ctrl_inl(addr1);
-	ctrl_outl(data1&~(CACHE_VALID|CACHE_UPDATED), addr1);
+	ctrl_outl(data1&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr1);
 
 	/* Next, check if there's shadow or not */
 	data0 = ctrl_inl(addr0);
-	data0 ^= CACHE_VALID;
+	data0 ^= SH_CACHE_VALID;
 	ctrl_outl(data0, addr0);
 	data1 = ctrl_inl(addr1);
-	data2 = data1 ^ CACHE_VALID;
+	data2 = data1 ^ SH_CACHE_VALID;
 	ctrl_outl(data2, addr1);
 	data3 = ctrl_inl(addr0);
 
 	/* Lastly, invaliate them. */
-	ctrl_outl(data0&~CACHE_VALID, addr0);
-	ctrl_outl(data2&~CACHE_VALID, addr1);
+	ctrl_outl(data0&~SH_CACHE_VALID, addr0);
+	ctrl_outl(data2&~SH_CACHE_VALID, addr1);
+
 	back_to_P1();
 
+	cpu_data->dcache.ways		= 4;
+	cpu_data->dcache.entry_shift	= 4;
+	cpu_data->dcache.linesz		= L1_CACHE_BYTES;
+	cpu_data->dcache.flags		= 0;
+
+	/*
+	 * 7709A/7729 has 16K cache (256-entry), while 7702 has only
+	 * 2K(direct) 7702 is not supported (yet)
+	 */
 	if (data0 == data1 && data2 == data3) {	/* Shadow */
-		cache_system_info.way_shift = 11;
-		cache_system_info.entry_mask = 0x7f0;
-		cache_system_info.num_entries = 128;
+		cpu_data->dcache.way_shift	= 11;
+		cpu_data->dcache.entry_mask	= 0x7f0;
+		cpu_data->dcache.sets		= 128;
 		cpu_data->type = CPU_SH7708;
+
+		set_bit(CPU_HAS_MMU_PAGE_ASSOC, &(cpu_data->flags));
 	} else {				/* 7709A or 7729  */
-		cache_system_info.way_shift = 12;
-		cache_system_info.entry_mask = 0xff0;
-		cache_system_info.num_entries = 256;
+		cpu_data->dcache.way_shift	= 12;
+		cpu_data->dcache.entry_mask	= 0xff0;
+		cpu_data->dcache.sets		= 256;
 		cpu_data->type = CPU_SH7729;
 	}
-}
 
-void __init cache_init(void)
-{
-	unsigned long ccr;
-
-	detect_cpu_and_cache_system();
-
-	jump_to_P2();
-	ccr = ctrl_inl(CCR);
-	if (ccr & CCR_CACHE_CE)
-		/*
-		 * XXX: Should check RA here. 
-		 * If RA was 1, we only need to flush the half of the caches.
-		 */
-		cache_wback_all();
+	/*
+	 * SH-3 doesn't have separate caches
+	 */
+	cpu_data->dcache.flags |= SH_CACHE_COMBINED;
+	cpu_data->icache = cpu_data->dcache;
 
-	ctrl_outl(CCR_CACHE_INIT, CCR);
-	back_to_P1();
+	return 0;
 }
 
 /*
@@ -170,23 +109,24 @@
 		& ~(L1_CACHE_BYTES-1);
 
 	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
-		for (j=0; j<CACHE_OC_NUM_WAYS; j++) {
+		for (j = 0; j < cpu_data->dcache.ways; j++) {
 			unsigned long data, addr, p;
 
 			p = __pa(v);
-			addr = CACHE_OC_ADDRESS_ARRAY|(j<<CACHE_OC_WAY_SHIFT)|
-				(v&CACHE_OC_ENTRY_MASK);
-			save_and_cli(flags);
+			addr = CACHE_OC_ADDRESS_ARRAY |
+				(j << cpu_data->dcache.way_shift)|
+				(v & cpu_data->dcache.entry_mask);
+			local_irq_save(flags);
 			data = ctrl_inl(addr);
 			
 			if ((data & CACHE_PHYSADDR_MASK) ==
 			    (p & CACHE_PHYSADDR_MASK)) {
-				data &= ~CACHE_UPDATED;
+				data &= ~SH_CACHE_UPDATED;
 				ctrl_outl(data, addr);
-				restore_flags(flags);
+				local_irq_restore(flags);
 				break;
 			}
-			restore_flags(flags);
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -210,8 +150,8 @@
 		unsigned long data, addr;
 
 		data = (v & 0xfffffc00); /* _Virtual_ address, ~U, ~V */
-		addr = CACHE_OC_ADDRESS_ARRAY | (v&CACHE_OC_ENTRY_MASK) | 
-			CACHE_OC_ASSOC_BIT;
+		addr = CACHE_OC_ADDRESS_ARRAY |
+			(v & cpu_data->dcache.entry_mask) | SH_CACHE_ASSOC;
 		ctrl_outl(data, addr);
 	}
 }
diff -urN linux-2.4.29/arch/sh/mm/cache-sh4.c linux-2.4.29-uc1/arch/sh/mm/cache-sh4.c
--- linux-2.4.29/arch/sh/mm/cache-sh4.c	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-uc1/arch/sh/mm/cache-sh4.c	2005-06-14 02:10:58.000000000 +0100
@@ -1,8 +1,9 @@
-/* $Id: cache-sh4.c,v 1.1.1.1.2.8 2003/07/09 09:59:30 trent Exp $
+/* $Id: cache-sh4.c,v 1.22 2003/07/15 18:40:12 lethal Exp $
  *
  *  linux/arch/sh/mm/cache-sh4.c
  *
  * Copyright (C) 1999, 2000, 2002  Niibe Yutaka
+ * Copyright (C) 2001, 2002, 2003  Paul Mundt
  */
 
 #include <linux/config.h>
@@ -19,131 +20,112 @@
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
 
-#define CCR		 0xff00001c	/* Address of Cache Control Register */
+extern void __flush_cache_4096_all(unsigned long start);
+static void __flush_cache_4096_all_ex(unsigned long start);
+extern void __flush_dcache_all(void);
+static void __flush_dcache_all_ex(void);
 
-#define CCR_CACHE_OCE	0x0001	/* Operand Cache Enable */
-#define CCR_CACHE_WT	0x0002	/* Write-Through (for P0,U0,P3) (else writeback)*/
-#define CCR_CACHE_CB	0x0004	/* Copy-Back (for P1) (else writethrough) */
-#define CCR_CACHE_OCI	0x0008	/* OC Invalidate */
-#define CCR_CACHE_ORA	0x0020	/* OC RAM Mode */
-#define CCR_CACHE_OIX	0x0080	/* OC Index Enable */
-#define CCR_CACHE_ICE	0x0100	/* Instruction Cache Enable */
-#define CCR_CACHE_ICI	0x0800	/* IC Invalidate */
-#define CCR_CACHE_IIX	0x8000	/* IC Index Enable */
-
-
-
-#if defined(CONFIG_SH_CACHE_ASSOC)
-#define CCR_CACHE_EMODE 0x80000000
-/* CCR setup for associative mode: 16k+32k 2-way, P1 copy-back, enable */
-#define CCR_CACHE_VAL	(CCR_CACHE_EMODE|CCR_CACHE_ENABLE|CCR_CACHE_CB)
-#else
-/* Default CCR setup: 8k+16k-byte cache, P1-copy-back, enable */
-#define CCR_CACHE_VAL	(CCR_CACHE_ENABLE|CCR_CACHE_CB)
-#endif
-
-#define CCR_CACHE_INIT	(CCR_CACHE_VAL|CCR_CACHE_OCI|CCR_CACHE_ICI)
-#define CCR_CACHE_ENABLE (CCR_CACHE_OCE|CCR_CACHE_ICE)
-
-#define CACHE_IC_ADDRESS_ARRAY 0xf0000000
-#define CACHE_OC_ADDRESS_ARRAY 0xf4000000
-#define CACHE_VALID	  1
-#define CACHE_UPDATED	  2
-#define CACHE_ASSOC	  8
-
-#define CACHE_OC_WAY_SHIFT       14
-#define CACHE_IC_WAY_SHIFT       13
-#define CACHE_OC_ENTRY_SHIFT      5
-#define CACHE_IC_ENTRY_SHIFT      5
-#define CACHE_OC_ENTRY_MASK		0x3fe0
-#define CACHE_OC_ENTRY_PHYS_MASK	0x0fe0
-#define CACHE_IC_ENTRY_MASK		0x1fe0
-#define CACHE_IC_NUM_ENTRIES	256
-#define CACHE_OC_NUM_ENTRIES	512
-
-#define CACHE_NUM_WAYS 2
-
-static void __init
-detect_cpu_and_cache_system(void)
-{
-#ifdef CONFIG_CPU_SUBTYPE_ST40
-	cpu_data->type = CPU_ST40;
-#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751)
-	cpu_data->type = CPU_SH7750;
-#elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
-	cpu_data->type = CPU_SH4202;
-#else
-#error Unknown SH4 CPU type
-#endif
-}
-
-void __init cache_init(void)
+int __init detect_cpu_and_cache_system(void)
 {
-	unsigned long ccr;
+	unsigned long pvr, prr, ccr;
 
-	detect_cpu_and_cache_system();
+	pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffff;
+	prr = (ctrl_inl(CCN_PRR) >> 4) & 0xff;
 
-	jump_to_P2();
-	ccr = ctrl_inl(CCR);
-	if (ccr & CCR_CACHE_ENABLE) {
-		/*
-		 * XXX: Should check RA here. 
-		 * If RA was 1, we only need to flush the half of the caches.
-		 */
-		unsigned long addr, data;
+	/*
+	 * Setup some sane SH-4 defaults for the icache
+	 */
+	cpu_data->icache.way_shift	= 13;
+	cpu_data->icache.entry_shift	= 5;
+	cpu_data->icache.entry_mask	= 0x1fe0;
+	cpu_data->icache.sets		= 256;
+	cpu_data->icache.ways		= 1;
+	cpu_data->icache.linesz		= L1_CACHE_BYTES;
 
-#if defined(CONFIG_SH_CACHE_ASSOC)
-                unsigned long way;
+	/*
+	 * And again for the dcache ..
+	 */
+	cpu_data->dcache.way_shift	= 14;
+	cpu_data->dcache.entry_shift	= 5;
+	cpu_data->dcache.entry_mask	= 0x3fe0;
+	cpu_data->dcache.sets		= 512;
+	cpu_data->dcache.ways		= 1;
+	cpu_data->dcache.linesz		= L1_CACHE_BYTES;
+
+	/*
+	 * Probe the underlying processor version/revision and
+	 * adjust cpu_data setup accordingly.
+	 */
+	switch (pvr) {
+	case 0x205:
+		cpu_data->type = CPU_SH7750;
+		set_bit(CPU_HAS_P2_FLUSH_BUG, &(cpu_data->flags));
+		break;
+	case 0x206:
+		cpu_data->type = CPU_SH7750S;
+
+		/* 
+		 * FIXME: This is needed for 7750, but do we need it for the
+		 * 7750S and 7750R too? For now, assume we do.. -- PFM
+		 */
+		set_bit(CPU_HAS_P2_FLUSH_BUG, &(cpu_data->flags));
+		break;
+	case 0x1100:
+		cpu_data->type = CPU_SH7751;
+		break;
+	case 0x8000:
+		cpu_data->type = CPU_ST40RA;
+		break;
+	case 0x8100:
+		cpu_data->type = CPU_ST40GX1;
+		break;
+	case 0x500:
+		if (prr == 0x10) {
+			cpu_data->type = CPU_SH7750R;
+			set_bit(CPU_HAS_P2_FLUSH_BUG, &(cpu_data->flags));
+		} else {
+			cpu_data->type = CPU_SH7751R;
+		}
 
-                for (way = 0; way <= CACHE_NUM_WAYS; ++way) {
-                        unsigned long waybit = way << CACHE_OC_WAY_SHIFT;
+		jump_to_P2();
+		ccr = ctrl_inl(CCR);
+		if (cpu_data->type == CPU_SH7751R) {
+			ccr |= CCR_CACHE_EMODE;
+			ctrl_outl(ccr, CCR);
+		}
+		back_to_P1();
 
-		        for (addr = CACHE_OC_ADDRESS_ARRAY + waybit;
-		             addr < (CACHE_OC_ADDRESS_ARRAY + waybit +
-			             (CACHE_OC_NUM_ENTRIES << 
-                                      CACHE_OC_ENTRY_SHIFT));
-		             addr += (1 << CACHE_OC_ENTRY_SHIFT)) {
-
-			        data = ctrl_inl(addr);
-
-			        if ((data & (CACHE_UPDATED|CACHE_VALID))
-			            == (CACHE_UPDATED|CACHE_VALID))
-				        ctrl_outl(data & ~CACHE_UPDATED, addr);
-		        }
-                }
-#else
-		for (addr = CACHE_OC_ADDRESS_ARRAY;
-		     addr < (CACHE_OC_ADDRESS_ARRAY+
-			     (CACHE_OC_NUM_ENTRIES << CACHE_OC_ENTRY_SHIFT));
-		     addr += (1 << CACHE_OC_ENTRY_SHIFT)) {
-			data = ctrl_inl(addr);
-			if ((data & (CACHE_UPDATED|CACHE_VALID))
-			    == (CACHE_UPDATED|CACHE_VALID))
-				ctrl_outl(data & ~CACHE_UPDATED, addr);
+		if (ccr & CCR_CACHE_EMODE) {
+			cpu_data->icache.ways = 2;
+			cpu_data->dcache.ways = 2;
 		}
-#endif
+		break;
+	default:
+		cpu_data->type = CPU_SH_NONE;
+		break;
 	}
 
-	ctrl_outl(CCR_CACHE_INIT, CCR);
-	back_to_P1();
+	/*
+	 * For now, all SH-4's have an FPU ..
+	 */
+	cpu_data->flags |= CPU_HAS_FPU;
+
+	return 0;
 }
 
 /*
  * SH-4 has virtually indexed and physically tagged cache.
  */
 
-static struct semaphore p3map_sem[4];
+struct semaphore p3map_sem[4];
 
 void __init p3_cache_init(void)
 {
-	/* In ioremap.c */
-	extern int remap_area_pages(unsigned long address,
-				    unsigned long phys_addr,
-				    unsigned long size, unsigned long flags);
-
 	if (remap_area_pages(P3SEG, 0, PAGE_SIZE*4, _PAGE_CACHABLE))
 		panic("%s failed.", __FUNCTION__);
+
 	sema_init (&p3map_sem[0], 1);
 	sema_init (&p3map_sem[1], 1);
 	sema_init (&p3map_sem[2], 1);
@@ -211,15 +193,38 @@
 	}
 }
 
-void __flush_icache_all(void)
+static void __flush_dcache_all_ex(void)
 {
-	unsigned long flags;
+	unsigned long addr, end_addr, entry_offset;
 
-	save_and_cli(flags);
-	jump_to_P2();
-	ctrl_outl(CCR_CACHE_VAL|CCR_CACHE_ICI, CCR);
-	back_to_P1();
-	restore_flags(flags);
+	end_addr = CACHE_OC_ADDRESS_ARRAY + (cpu_data->dcache.sets << cpu_data->dcache.entry_shift) * cpu_data->dcache.ways;
+	entry_offset = 1 << cpu_data->dcache.entry_shift;
+	for (addr = CACHE_OC_ADDRESS_ARRAY; addr < end_addr; addr += entry_offset) {
+		ctrl_outl(0, addr);
+	}
+}
+
+static void __flush_cache_4096_all_ex(unsigned long start)
+{
+	unsigned long addr, entry_offset;
+	int i;
+
+	entry_offset = 1 << cpu_data->dcache.entry_shift;
+	for (i = 0; i < cpu_data->dcache.ways; i++, start += (1 << cpu_data->dcache.way_shift)) {
+		for (addr = CACHE_OC_ADDRESS_ARRAY + start;
+		     addr < CACHE_OC_ADDRESS_ARRAY + 4096 + start;
+		     addr += entry_offset) {
+			ctrl_outl(0, addr);
+		}
+	}
+}
+
+void flush_cache_4096_all(unsigned long start)
+{
+	if (cpu_data->dcache.ways == 1)
+		__flush_cache_4096_all(start);
+	else
+		__flush_cache_4096_all_ex(start);
 }
 
 /*
@@ -234,29 +239,28 @@
 
 /*
  * Write back the D-cache and purge the I-cache for signal trampoline. 
+ * .. which happens to be the same behavior as flush_icache_range().
+ * So, we simply flush out a line.
  */
 void flush_cache_sigtramp(unsigned long addr)
 {
 	unsigned long v, index;
 	unsigned long flags; 
+	int i;
 
 	v = addr & ~(L1_CACHE_BYTES-1);
 	asm volatile("ocbwb	%0"
 		     : /* no output */
 		     : "m" (__m(v)));
 
-	index = CACHE_IC_ADDRESS_ARRAY| (v&CACHE_IC_ENTRY_MASK);
-	save_and_cli(flags);
-	jump_to_P2();
-	ctrl_outl(0, index);	/* Clear out Valid-bit */
-
-#if defined(CONFIG_SH_CACHE_ASSOC)
-	/* Must invalidate both ways for associative cache */
-	ctrl_outl(0, index | (1 << CACHE_IC_WAY_SHIFT));
-#endif
+	index = CACHE_IC_ADDRESS_ARRAY | (v & cpu_data->icache.entry_mask);
 
+	local_irq_save(flags);
+	jump_to_P2();
+	for(i = 0; i < cpu_data->icache.ways; i++, index += (1 << cpu_data->icache.way_shift))
+		ctrl_outl(0, index);	/* Clear out Valid-bit */
 	back_to_P1();
-	restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static inline void flush_cache_4096(unsigned long start,
@@ -265,19 +269,16 @@
 	unsigned long flags; 
 	extern void __flush_cache_4096(unsigned long addr, unsigned long phys, unsigned long exec_offset);
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_ST40) || defined(CONFIG_CPU_SUBTYPE_SH4_202)
-	if (start >= CACHE_OC_ADDRESS_ARRAY) {
-		/*
-		 * SH7751 and ST40 have no restriction to handle cache.
-		 * (While SH7750 must do that at P2 area.)
-		 */
-		__flush_cache_4096(start | CACHE_ASSOC, phys | 0x80000000, 0);
-	} else
-#endif
-	{
-		save_and_cli(flags);
-		__flush_cache_4096(start | CACHE_ASSOC, phys | 0x80000000, 0x20000000);
-		restore_flags(flags);
+	/*
+	 * SH7751, SH7751R, and ST40 have no restriction to handle cache.
+	 * (While SH7750 must do that at P2 area.)
+	 */
+	if (test_bit(CPU_HAS_P2_FLUSH_BUG, &(cpu_data->flags))) {
+		local_irq_save(flags);
+		__flush_cache_4096(start | SH_CACHE_ASSOC, phys | 0x80000000, 0x20000000);
+		local_irq_restore(flags);
+	} else if (start >= CACHE_OC_ADDRESS_ARRAY) {
+		__flush_cache_4096(start | SH_CACHE_ASSOC, phys | 0x80000000, 0);
 	}
 }
 
@@ -298,23 +299,28 @@
 	}
 }
 
-static inline void flush_icache_all(void)
+void flush_icache_all(void)
 {
-	unsigned long flags;
+	unsigned long flags, ccr;
 
-	save_and_cli(flags);
+	local_irq_save(flags);
 	jump_to_P2();
+
 	/* Flush I-cache */
-	ctrl_outl(CCR_CACHE_VAL|CCR_CACHE_ICI, CCR);
+	ccr = ctrl_inl(CCR);
+	ccr |= CCR_CACHE_ICI;
+	ctrl_outl(ccr, CCR);
+
 	back_to_P1();
-	restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 void flush_cache_all(void)
 {
-	extern void __flush_dcache_all(void);
-
-	__flush_dcache_all();
+	if (cpu_data->dcache.ways == 1)
+		__flush_dcache_all();
+	else
+		__flush_dcache_all_ex();
 	flush_icache_all();
 }
 
@@ -370,8 +376,6 @@
 void flush_cache_range(struct mm_struct *mm, unsigned long start,
 		       unsigned long end)
 {
-	extern void flush_cache_4096_all(unsigned long start);
-
 	unsigned long p = start & PAGE_MASK;
 	pgd_t *dir;
 	pmd_t *pmd;
@@ -416,7 +420,8 @@
 		flush_cache_4096_all(0x2000);
 	if (d & 8)
 		flush_cache_4096_all(0x3000);
-	flush_icache_all();
+	if (1 /* vma->vm_flags & VM_EXEC DAVIDM FIX ME */)
+		flush_icache_all();
 }
 
 /*
@@ -446,6 +451,20 @@
 }
 
 /*
+ * flush_icache_user_range
+ * @vma: VMA of the process
+ * @page: page
+ * @addr: U0 address
+ * @len: length of the range (< page size)
+ */
+void flush_icache_user_range(struct vm_area_struct *vma,
+			     struct page *page, unsigned long addr, int len)
+{
+	__flush_cache_page(vma, addr, PHYSADDR(page_address(page)));
+}
+
+
+/*
  * clear_user_page
  * @to: P1 address
  * @address: U0 address to be mapped
@@ -523,65 +542,6 @@
 }
 
 
-/****************************************************************************/
-
-#if defined(CONFIG_SH_CACHE_ASSOC)
-/*
- * It is no possible to use the approach implement in clear_page.S when we 
- * are in 2-way set associative mode as it would only clear half the cache, in 
- * general. For the moment we simply implement it as a iteration through the 
- * cache flushing both ways, this in itself is not optimial as the delay latency 
- * for interupts is probably longer than necessary!
- *
- * benedict.gaster.superh.com
- */
-void __flush_dcache_all(void)
-{
-	unsigned long flags;
-	unsigned long addr;
-        unsigned long way;
-
-	save_and_cli(flags);
-#if !defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH4_202)
-	jump_to_P2();
-#endif
-        /* Clear the U and V bits for each line and each way. On SH-4, this
-         * causes write-back if both U and V are set before the address write.
-         */
-	for (way = 0; way <= 1; ++way) {
-	        unsigned long waybit = way << CACHE_OC_WAY_SHIFT;
-
-	        /* Loop all the D-cache */
-                for (addr = CACHE_OC_ADDRESS_ARRAY + waybit;
-	             addr < (CACHE_OC_ADDRESS_ARRAY + waybit
-		             + (CACHE_OC_NUM_ENTRIES << CACHE_OC_ENTRY_SHIFT));
-	             addr += (1 << CACHE_OC_ENTRY_SHIFT)) {
-			ctrl_outl(0, addr);
-                }
-	}
-
-#if !defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH4_202)
-	back_to_P1();
-#endif 
-	restore_flags(flags);
-}
-
-void flush_cache_4096_all(unsigned long start)
-{
-  unsigned long phys = PHYSADDR(start);
-
-  /* Loop all the D-cache */
-  flush_cache_4096(CACHE_OC_ADDRESS_ARRAY,          phys);
-}
-#endif
-
-
-
-
-
-
-/****************************************************************************/
-
 #if defined(CONFIG_SH_CACHE_ASSOC)
 /*
  * It is no possible to use the approach implement in clear_page.S when we 
@@ -632,7 +592,3 @@
 }
 #endif
 
-
-
-
-
diff -urN linux-2.4.29/arch/sh/mm/clear_page.S linux-2.4.29-uc1/arch/sh/mm/clear_page.S
--- linux-2.4.29/arch/sh/mm/clear_page.S	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-uc1/arch/sh/mm/clear_page.S	2005-06-14 02:10:58.000000000 +0100
@@ -1,4 +1,4 @@
-/* $Id: clear_page.S,v 1.1.1.1.2.8 2003/04/18 10:53:25 sugioka Exp $
+/* $Id: clear_page.S,v 1.13 2003/08/25 17:03:10 lethal Exp $
  *
  * __clear_user_page, __clear_user, clear_page implementation of SuperH
  *
@@ -10,7 +10,7 @@
 #include <linux/linkage.h>
 
 /*
- * clear_page
+ * clear_page_slow
  * @to: P1 address
  *
  * void clear_page(void *to)
@@ -28,9 +28,9 @@
 	mov	#0,r0
 	!
 1:
-#if defined(__sh3__)
+#if defined(CONFIG_CPU_SH3)
 	mov.l	r0,@r4
-#elif defined(__SH4__)
+#elif defined(CONFIG_CPU_SH4)
 	movca.l	r0,@r4
 	mov	r4,r1
 #endif
@@ -42,7 +42,7 @@
 	mov.l	r0,@-r4
 	mov.l	r0,@-r4
 	mov.l	r0,@-r4
-#if defined(__SH4__)
+#if defined(CONFIG_CPU_SH4)
 	ocbwb	@r1
 #endif
 	cmp/eq	r5,r4
@@ -92,7 +92,7 @@
 	bf	.Larea2
 	!
 	! Clear area 1
-#if defined(__SH4__)
+#if defined(CONFIG_CPU_SH4)
 1:	movca.l	r0, @r2
 #else
 1:	mov.l	r0, @r2
@@ -152,10 +152,10 @@
 	.long	9b, .Lbad_clear_user
 .previous
 
-#if defined(__SH4__)
+#if defined(CONFIG_CPU_SH4)
 /*
  * __clear_user_page
- * @to: P1 address (with same color)
+ * @to: P3 address (with same color)
  * @orig_to: P1 address
  *
  * void __clear_user_page(void *to, void *orig_to)
@@ -350,12 +350,11 @@
 
 	.align	2
 2:	.long	0xffffc000
-
 3:	.long	SYMBOL_NAME(empty_zero_page)
 4:	.long	0x10000000	! BL bit
 
-/* flush_cache_4096_all(unsigned long addr) */
-ENTRY(flush_cache_4096_all)
+/* __flush_cache_4096_all(unsigned long addr) */
+ENTRY(__flush_cache_4096_all)
 	mov.l	2f,r0
 	mov.l	3f,r2
 	and	r0,r2
@@ -430,7 +429,7 @@
 
 	.align	2
 2:	.long	0xffffc000
-3:	.long	SYMBOL_NAME(empty_zero_page)
+3:	.long	empty_zero_page
 4:	.long	0x10000000	! BL bit
 	
 #endif
diff -urN linux-2.4.29/arch/sh/mm/init.c linux-2.4.29-uc1/arch/sh/mm/init.c
--- linux-2.4.29/arch/sh/mm/init.c	2003-08-25 12:44:40.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/mm/init.c	2005-06-14 02:10:58.000000000 +0100
@@ -219,3 +219,80 @@
 	val->mem_unit = PAGE_SIZE;
 	return;
 }
+
+/*
+ * Generic first-level cache init
+ */
+void __init cache_init(void)
+{
+	extern int detect_cpu_and_cache_system(void);
+	unsigned long ccr, flags = 0;
+
+	detect_cpu_and_cache_system();
+
+	if (cpu_data->type == CPU_SH_NONE)
+		panic("Unknown CPU");
+
+	jump_to_P2();
+	ccr = ctrl_inl(CCR);
+
+	/*
+	 * If the cache is already enabled .. flush it.
+	 */
+	if (ccr & CCR_CACHE_ENABLE) {
+		unsigned long entries, i, j;
+
+		entries = cpu_data->dcache.sets;
+
+		/*
+		 * If the OC is already in RAM mode, we only have
+		 * half of the entries to flush..
+		 */
+		if (ccr & CCR_CACHE_ORA)
+			entries >>= 1;
+
+		for (i = 0; i < entries; i++) {
+			for (j = 0; j < cpu_data->dcache.ways; j++) {
+				unsigned long data, addr;
+
+				addr = CACHE_OC_ADDRESS_ARRAY |
+					(j << cpu_data->dcache.way_shift) |
+					(i << cpu_data->dcache.entry_shift);
+
+				data = ctrl_inl(addr);
+
+				if ((data & (SH_CACHE_UPDATED | SH_CACHE_VALID))
+					== (SH_CACHE_UPDATED | SH_CACHE_VALID))
+					ctrl_outl(data & ~SH_CACHE_UPDATED, addr);
+			}
+		}
+	}
+
+	/* 
+	 * Default CCR values .. enable the caches
+	 * and flush them immediately..
+	 */
+	flags |= CCR_CACHE_ENABLE | CCR_CACHE_INVALIDATE |
+#ifdef CCR_CACHE_EMODE
+			(ccr & CCR_CACHE_EMODE) |
+#endif
+			0;
+
+#ifdef CONFIG_SH_WRITETHROUGH
+	/* Turn on Write-through caching */
+	flags |= CCR_CACHE_WT;
+#else
+	/* .. or default to Write-back */
+	flags |= CCR_CACHE_CB;
+#endif
+
+#ifdef CONFIG_SH_OCRAM
+	/* Turn on OCRAM -- halve the OC */
+	flags |= CCR_CACHE_ORA;
+	cpu_data->dcache.sets >>= 1;
+#endif
+
+	ctrl_outl(flags, CCR);
+	back_to_P1();
+}
+
diff -urN linux-2.4.29/arch/sh/vmlinux.lds.rom.S linux-2.4.29-uc1/arch/sh/vmlinux.lds.rom.S
--- linux-2.4.29/arch/sh/vmlinux.lds.rom.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/sh/vmlinux.lds.rom.S	2005-06-14 02:10:58.000000000 +0100
@@ -0,0 +1,163 @@
+/* $Id: vmlinux.lds.in,v 1.5 2001/07/27 11:45:55 gniibe Exp $
+ * ld script to make SuperH Linux kernel (for booting from ROM)
+ * Written by Niibe Yutaka
+ *
+ * Modified by Rahul Chaturvedi on 22/06/2004 (justanotheraliasforrahul@yahoo.com)
+ * to add support to boot from a ROM image
+ */
+#include <linux/config.h>
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux")
+#else
+OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux")
+#endif
+OUTPUT_ARCH(sh)
+ENTRY(_start)
+SECTIONS
+{
+  _mem_start  = 0x80000000 + CONFIG_MEMORY_START + 0x1000;
+  _rom_store = 0x80000000 + CONFIG_ROM_STORE_OFFSET;
+
+  . = _mem_start;
+  .empty_zero_page : {
+	*(.empty_zero_page)
+	} = 0
+
+  . = _rom_store;
+  _text = .;			/* Text and read-only data */
+  text = .;			/* Text and read-only data */
+
+  .text _rom_store + SIZEOF(.empty_zero_page) : 
+		AT (_mem_start + SIZEOF(.empty_zero_page)) {
+	*(.text)
+	*(.fixup)
+	*(.gnu.warning)
+	} = 0x0009
+
+
+
+  .rodata : 
+	      AT( ADDR(.text) + SIZEOF(.text) + (_mem_start - _rom_store)) 	{ *(.rodata) *(.rodata.*) }
+
+  .kstrtab : AT ( ADDR(.rodata) + SIZEOF(.rodata) + (_mem_start - _rom_store)) { *(.kstrtab) }
+
+
+
+  _ctr = .;
+  . = ALIGN(16);		/* Exception table */
+  _ctr = _ctr - .;
+  __start___ex_table = .;
+  __ex_table : AT( ADDR(.kstrtab) + SIZEOF(.kstrtab) + 
+				(_mem_start - _rom_store)) { *(__ex_table) }
+  __stop___ex_table = .;
+
+  __start___ksymtab = .;	/* Kernel symbol table */
+  __ksymtab : AT( ADDR(__ex_table) + SIZEOF(__ex_table) + 
+				(_mem_start - _rom_store)) { *(__ksymtab) }
+  __stop___ksymtab = .;
+
+  __start___kallsyms = .;	/* All kernel symbols */
+  __kallsyms : AT( ADDR(__ksymtab) + SIZEOF(__ksymtab) + 
+				(_mem_start - _rom_store)) { *(__kallsyms) }
+  __stop___kallsyms = .;
+
+  . = ADDR(__kallsyms) + SIZEOF(__kallsyms)
+				+ (_mem_start - _rom_store) + _ctr;
+
+  _etext = .;			/* End of text section */
+
+  .data : {			/* Data */
+	*(.data)
+	CONSTRUCTORS
+	}
+
+  _edata = .;			/* End of data section */
+
+  . = ALIGN(8192);		/* init_task */
+  .data.init_task : { *(.data.init_task) }
+  /* stack */
+  .stack : { stack = .;  _stack = .; }
+
+  . = ALIGN(4096);		/* Init code and data */
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(16);
+  __setup_start = .;
+  .setup.init : { *(.setup.init) }
+  __setup_end = .;
+  __initcall_start = .;
+  .initcall.init : { *(.initcall.init) }
+  __initcall_end = .;
+  __machvec_start = .;
+  .machvec.init : { *(.machvec.init) }
+  __machvec_end = .;
+  . = ALIGN(4096);
+  __init_end = .;
+
+  . = ALIGN(4096);
+  .data.page_aligned : { *(.data.idt) }
+
+#ifdef CONFIG_CPU_SH3	
+  . = ALIGN(16);
+#else
+  . = ALIGN(32);
+#endif	
+  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+  . = ALIGN(4);
+  __bss_start = .;		/* BSS */
+  _initrd_rom = . - (_mem_start - _rom_store);
+
+  .bss : {
+	*(.bss)
+	}
+  . = ALIGN(4096);
+  _end = . ;
+
+  /* When something in the kernel is NOT compiled as a module, the
+   * module cleanup code and data are put into these segments.  Both
+   * can then be thrown away, as cleanup code is never called unless
+   * it's a module.
+   */
+  /DISCARD/ : {
+	*(.text.exit)
+	*(.data.exit)
+	*(.exitcall.exit)
+	}
+
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging section are relative to the beginning
+     of the section so we begin .debug at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  /* These must appear regardless of  .  */
+}
diff -urN linux-2.4.29/arch/sh/vmlinux.lds.S linux-2.4.29-uc1/arch/sh/vmlinux.lds.S
--- linux-2.4.29/arch/sh/vmlinux.lds.S	2002-02-25 19:37:56.000000000 +0000
+++ linux-2.4.29-uc1/arch/sh/vmlinux.lds.S	2005-06-14 02:10:58.000000000 +0100
@@ -85,7 +85,7 @@
   .bss : {
 	*(.bss)
 	}
-  . = ALIGN(4);
+  . = ALIGN(4096);
   _end = . ;
 
   /* When something in the kernel is NOT compiled as a module, the
diff -urN linux-2.4.29/arch/v850/config.in linux-2.4.29-uc1/arch/v850/config.in
--- linux-2.4.29/arch/v850/config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/config.in	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,458 @@
+#############################################################################
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+#
+# based mainly on the arch/i386/config.in and bit of the 2.0, m68knommu
+# config.in
+#
+#############################################################################
+
+mainmenu_name 'uClinux/v850 (w/o MMU) Kernel Configuration'
+
+define_bool CONFIG_MMU n
+define_bool CONFIG_UCLINUX y
+define_bool CONFIG_UID16 n
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+
+# Turn off some random 386 crap that can affect device config
+define_bool CONFIG_ISA n
+define_bool CONFIG_ISAPNP n
+define_bool CONFIG_EISA n
+define_bool CONFIG_MCA n
+
+
+#############################################################################
+
+mainmenu_option next_comment
+   comment 'Code maturity level options'
+   bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+mainmenu_option next_comment
+   comment 'Loadable module support'
+   bool 'Enable loadable module support' CONFIG_MODULES
+   if [ "$CONFIG_MODULES" = "y" ]; then
+       bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+       bool '  Kernel module loader' CONFIG_KMOD
+   fi
+endmenu
+
+
+#############################################################################
+#### v850-specific config
+
+# Define the architecture
+define_bool CONFIG_V850 y
+
+mainmenu_option next_comment
+   comment 'Processor type and features'
+
+   choice 'Platform'						\
+	  "GDB			CONFIG_V850E_SIM		\
+	   RTE-V850E/MA1-CB	CONFIG_RTE_CB_MA1		\
+	   RTE-V850E/NB85E-CB	CONFIG_RTE_CB_NB85E		\
+	   RTE-V850E/ME2-CB	CONFIG_RTE_CB_ME2		\
+	   AS85EP1		CONFIG_V850E_AS85EP1		\
+	   sim85e2c		CONFIG_V850E2_SIM85E2C		\
+	   sim85e2s		CONFIG_V850E2_SIM85E2S		\
+	   NA85E2C-FPGA		CONFIG_V850E2_FPGA85E2C		\
+	   Anna			CONFIG_V850E2_ANNA"		\
+	  GDB
+
+
+   #### V850E processor-specific config
+
+   # All CPUs currently supported use the v850e architecture
+   define_bool CONFIG_V850E y
+
+   # The RTE-V850E/MA1-CB is the only type of V850E/MA1 platform we
+   # currently support
+   define_bool CONFIG_V850E_MA1 $CONFIG_RTE_CB_MA1
+   # Similarly for the RTE-V850E/NB85E-CB - V850E/TEG
+   define_bool CONFIG_V850E_TEG $CONFIG_RTE_CB_NB85E
+   # ... and the RTE-V850E/ME2-CB - V850E/ME2
+   define_bool CONFIG_V850E_ME2 $CONFIG_RTE_CB_ME2
+
+   if [	  "$CONFIG_V850E_MA1" = "y"      \
+       -o "$CONFIG_V850E_ME2" = "y"      \
+       -o "$CONFIG_V850E_TEG" = "y"      \
+       -o "$CONFIG_V850E2_ANNA" = "y"    \
+       -o "$CONFIG_V850E_AS85EP1" = "y" ]
+   then
+      bool 'NEC V850E on-chip UART support' CONFIG_V850E_UART
+
+      if [ "$CONFIG_V850E_UART" = "y" ]; then
+        # the V850E/ME2 uses UARTB
+        define_bool CONFIG_V850E_UARTB $CONFIG_V850E_ME2
+      fi
+
+      dep_bool '  Use NEC V850E on-chip UART for console' \
+          CONFIG_V850E_UART_CONSOLE $CONFIG_V850E_UART
+   else
+      define_bool CONFIG_V850E_UART n
+   fi
+
+
+   #### V850E2 processor-specific config
+
+   # Common simulator stuff
+   if [   "$CONFIG_V850E2_SIM85E2C" = "y"  \
+       -o "$CONFIG_V850E2_SIM85E2S" = "y" ]
+   then
+      define_bool CONFIG_V850E2_SIM85E2 y
+   else
+      define_bool CONFIG_V850E2_SIM85E2 n
+   fi
+
+   # V850E2 processors
+   if [	  "$CONFIG_V850E2_SIM85E2" = "y"    \
+       -o "$CONFIG_V850E2_FPGA85E2C" = "y"  \
+       -o "$CONFIG_V850E2_ANNA" = "y"	   ]
+   then
+      define_bool CONFIG_V850E2 y
+   else
+      define_bool CONFIG_V850E2 n
+   fi
+
+
+   #### sim85e2 platform-specific config
+
+   if [ "$CONFIG_V850E2_SIM85E2" = "y" ]; then
+      # Don't bother, as it's already zeroed by the simulator
+      define_bool CONFIG_ZERO_BSS n
+
+      # The crappy-ass zone allocator requires that the start of allocatable
+      # memory be aligned to the largest possible allocation.
+      define_int CONFIG_FORCE_MAX_ZONEORDER 8
+   fi
+
+
+   #### fpga85e2c platform-specific config
+
+   if [ "$CONFIG_V850E2_FPGA85E2C" = "y" ]; then
+      # The crappy-ass zone allocator requires that the start of allocatable
+      # memory be aligned to the largest possible allocation.
+      define_int CONFIG_FORCE_MAX_ZONEORDER 8
+   fi
+
+
+   #### AS85EP1 platform-specific config
+
+   if [ "$CONFIG_V850E_AS85EP1" = "y" ]; then
+      # The crappy-ass zone allocator requires that the start of allocatable
+      # memory be aligned to the largest possible allocation.
+      define_int CONFIG_FORCE_MAX_ZONEORDER 11
+   fi
+
+
+   #### RTE-CB platform-specific config
+
+   # Boards in the RTE-x-CB series
+   if [   "$CONFIG_RTE_CB_MA1" = "y"    \
+       -o "$CONFIG_RTE_CB_ME2" = "y"    \
+       -o "$CONFIG_RTE_CB_NB85E" = "y" ]
+   then
+      define_bool CONFIG_RTE_CB y
+   else
+      define_bool CONFIG_RTE_CB n
+   fi
+
+   if [ "$CONFIG_RTE_CB_MA1" = "y" ]; then
+     # Currently, we only support RTE-MA1-CB boards using the Multi ROM
+     define_bool CONFIG_RTE_CB_MULTI $CONFIG_RTE_CB
+   else
+     dep_bool 'Multi monitor ROM support' CONFIG_RTE_CB_MULTI $CONFIG_RTE_CB
+   fi
+
+   dep_bool 'Pass illegal insn trap / dbtrap to kernel' \
+      CONFIG_RTE_CB_MULTI_DBTRAP $CONFIG_RTE_CB_MULTI
+
+   dep_bool 'Kernel in SRAM (limits size of kernel)' CONFIG_RTE_CB_MA1_KSRAM \
+      $CONFIG_RTE_CB_MA1 $CONFIG_RTE_CB_MULTI
+
+   dep_bool 'Mother-A PCI support' CONFIG_RTE_MB_A_PCI $CONFIG_RTE_CB
+
+   # The GBUS is used to talk to the RTE-MOTHER-A board
+   define_bool CONFIG_RTE_GBUS_INT $CONFIG_RTE_MB_A_PCI
+
+   # The only PCI bus we support is on the RTE-MOTHER-A board
+   define_bool CONFIG_PCI $CONFIG_RTE_MB_A_PCI
+
+
+   #### Some feature-specific configs
+
+   # Everything except for the GDB simulator uses the same interrupt controller
+   if [ "$CONFIG_V850E_SIM" = "n" ]; then
+      define_bool CONFIG_V850E_INTC y
+   else
+      define_bool CONFIG_V850E_INTC n
+   fi
+
+   # Everything except for the various simulators uses the "Timer D" unit
+   if [ "$CONFIG_V850E_SIM" = "n" -a "$CONFIG_V850E2_SIM85E2" = "n" ]; then
+      define_bool CONFIG_V850E_TIMER_D y
+   else
+      define_bool CONFIG_V850E_TIMER_D n
+   fi
+
+   # Cache control used on some v850e1 processors
+   if [ "$CONFIG_V850E_TEG" = "y" -o "$CONFIG_V850E_ME2" = "y" ]; then
+      define_bool CONFIG_V850E_CACHE y
+   else
+      define_bool CONFIG_V850E_CACHE n
+   fi
+
+   # Cache control used on v850e2 processors; I think this should
+   # actually apply to more, but currently only the SIM85E2S uses it
+   define_bool CONFIG_V850E2_CACHE $CONFIG_V850E2_SIM85E2S
+
+   if [ "$CONFIG_V850E_CACHE" = n -a "$CONFIG_V850E2_CACHE" = "n" ]; then
+      define_bool CONFIG_NO_CACHE y
+   else
+      define_bool CONFIG_NO_CACHE n
+   fi
+
+
+   #### Misc config
+
+   if [   "$CONFIG_V850E2_ANNA" = "y"    \
+       -o "$CONFIG_V850E_AS85EP1" = "y"  \
+       -o "$CONFIG_V850E_ME2" = "y"     ]
+   then
+      bool 'Kernel in ROM' CONFIG_ROM_KERNEL
+   fi
+   
+   dep_bool 'High resolution timer support' CONFIG_V850E_HIGHRES_TIMER $CONFIG_V850E_TIMER_D
+   dep_bool '  Time bootup' CONFIG_TIME_BOOTUP $CONFIG_V850E_HIGHRES_TIMER
+
+   bool 'Reset Guard' CONFIG_RESET_GUARD
+
+   # Default some stuff
+   if [ "$CONFIG_ZERO_BSS" != "n" ]; then
+      define_bool CONFIG_ZERO_BSS y
+   fi
+
+endmenu
+
+
+#############################################################################
+
+mainmenu_option next_comment
+   comment 'General setup'
+
+   bool 'Networking support' CONFIG_NET
+
+   # Embedded systems often won't need any hardware disk support, so
+   # only clutter up the menus with it if really necessary
+   bool 'Disk hardware support' CONFIG_DISK
+
+   source drivers/pci/Config.in
+
+   # if [ "$CONFIG_VISWS" != "y" ]; then
+   #	bool 'MCA support' CONFIG_MCA
+   # fi
+
+   bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+
+   if [ "$CONFIG_HOTPLUG" = "y" ] ; then
+      source drivers/pcmcia/Config.in
+   else
+      define_bool CONFIG_PCMCIA n
+   fi
+
+   bool 'System V IPC' CONFIG_SYSVIPC
+   bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+   bool 'Sysctl support' CONFIG_SYSCTL
+   if [ "$CONFIG_PROC_FS" = "y" ]; then
+      choice 'Kernel core (/proc/kcore) format' \
+	     "ELF	CONFIG_KCORE_ELF	\
+	      A.OUT	CONFIG_KCORE_AOUT" ELF
+   fi
+   tristate 'Kernel support for flat binaries' CONFIG_BINFMT_FLAT
+   dep_bool '  Enable ZFLAT support' CONFIG_BINFMT_ZFLAT $CONFIG_BINFMT_FLAT
+   #tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
+   #tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+   tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+
+   # bool 'Power Management support' CONFIG_PM
+   #
+   # dep_bool '	 ACPI support' CONFIG_ACPI $CONFIG_PM
+   # if [ "$CONFIG_ACPI" != "n" ]; then
+   #	if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   #	   bool '    ACPI interpreter (EXPERIMENTAL)' CONFIG_ACPI_INTERPRETER
+   #	   bool '    Enter S1 for sleep (EXPERIMENTAL)' CONFIG_ACPI_S1_SLEEP
+   #	fi
+   # fi
+
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      bool 'Non power-of-2 kernel allocator (EXPERIMENTAL)' CONFIG_CONTIGUOUS_PAGE_ALLOC
+      dep_bool '   include /proc/mem_map' CONFIG_MEM_MAP $CONFIG_CONTIGUOUS_PAGE_ALLOC
+   fi
+
+   if [ "$CONFIG_CONTIGUOUS_PAGE_ALLOC" != "y" ]; then
+      bool 'Allow allocating large blocks (> 1MB) of memory' CONFIG_NO_MMU_LARGE_ALLOCS
+   fi
+
+endmenu
+
+#############################################################################
+
+#source drivers/mtd/Config.in
+
+if [ "$CONFIG_PCI" != "n" ]; then
+   source drivers/parport/Config.in
+fi
+
+#source drivers/pnp/Config.in
+
+source drivers/block/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+    source net/Config.in
+fi
+
+#source drivers/telephony/Config.in
+
+#############################################################################
+
+if [ "$CONFIG_DISK" = "y" ]; then
+   mainmenu_option next_comment
+      comment 'ATA/IDE/MFM/RLL support'
+
+      tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+
+      if [ "$CONFIG_IDE" != "n" ]; then
+	 source drivers/ide/Config.in
+      else
+	 define_bool CONFIG_BLK_DEV_HD n
+      fi
+   endmenu
+fi
+
+#############################################################################
+
+if [ "$CONFIG_DISK" = "y" ]; then
+   mainmenu_option next_comment
+      comment 'SCSI support'
+
+      tristate 'SCSI support' CONFIG_SCSI
+
+      if [ "$CONFIG_SCSI" != "n" ]; then
+	 source drivers/scsi/Config.in
+      fi
+   endmenu
+fi
+
+#############################################################################
+
+if [ "$CONFIG_PCI" = "y" ]; then
+   source drivers/ieee1394/Config.in
+fi
+
+if [ "$CONFIG_NET" = "y" ]; then
+   mainmenu_option next_comment
+      comment 'Network device support'
+
+      bool 'Network device support' CONFIG_NETDEVICES
+      if [ "$CONFIG_NETDEVICES" = "y" ]; then
+	 source drivers/net/Config.in
+	 if [ "$CONFIG_ATM" = "y" ]; then
+	    source drivers/atm/Config.in
+	 fi
+      fi
+   endmenu
+fi
+
+if [ "$CONFIG_NET" = "y" ]; then
+   source net/ax25/Config.in
+fi
+
+source net/irda/Config.in
+
+#############################################################################
+
+if [ "$CONFIG_NET" = "y" ]; then
+   mainmenu_option next_comment
+      comment 'ISDN subsystem'
+
+      tristate 'ISDN support' CONFIG_ISDN
+      if [ "$CONFIG_ISDN" != "n" ]; then
+	 source drivers/isdn/Config.in
+      fi
+   endmenu
+fi
+
+#############################################################################
+
+# mainmenu_option next_comment
+#    comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+#
+#    bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+#    if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+#	  source drivers/cdrom/Config.in
+#    fi
+# endmenu
+
+#############################################################################
+
+source drivers/char/Config.in
+
+#source drivers/misc/Config.in
+
+source fs/Config.in
+
+if [ "$CONFIG_VT" = "y" ]; then
+   mainmenu_option next_comment
+      comment 'Console drivers'
+      bool 'VGA text console' CONFIG_VGA_CONSOLE
+      bool 'Video mode selection support' CONFIG_VIDEO_SELECT
+      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	 tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
+	 source drivers/video/Config.in
+      fi
+   endmenu
+fi
+
+#############################################################################
+
+mainmenu_option next_comment
+   comment 'Sound'
+
+   tristate 'Sound card support' CONFIG_SOUND
+   if [ "$CONFIG_SOUND" != "n" ]; then
+      source drivers/sound/Config.in
+   fi
+endmenu
+
+#############################################################################
+
+source drivers/usb/Config.in
+
+#############################################################################
+
+mainmenu_option next_comment
+   comment 'Kernel hacking'
+
+   bool 'Full Symbolic/Source Debugging support' CONFIG_FULLDEBUG
+   #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
+   bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+
+   bool 'Kernel profiling support' CONFIG_PROFILE
+   if [ "$CONFIG_PROFILE" = "y" ]; then
+      int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+      bool 'Use fast second timer for profiling' CONFIG_HIGHPROFILE
+   fi
+
+   bool 'Suppress Kernel BUG Messages' CONFIG_NO_KERNEL_MSG
+
+endmenu
+
+
+#############################################################################
+
+source crypto/Config.in
+source lib/Config.in
+
+#############################################################################
diff -urN linux-2.4.29/arch/v850/kernel/anna.c linux-2.4.29-uc1/arch/v850/kernel/anna.c
--- linux-2.4.29/arch/v850/kernel/anna.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/anna.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,214 @@
+/*
+ * arch/v850/kernel/anna.c -- Anna V850E2 evaluation chip/board
+ *
+ *  Copyright (C) 2002,03  NEC Electronics Corporation
+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/major.h>
+#include <linux/irq.h>
+
+#include <asm/machdep.h>
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/v850e_timer_d.h>
+#include <asm/v850e_uart.h>
+
+#include "mach.h"
+
+
+/* SRAM and SDRAM are vaguely contiguous (with a big hole in between; see
+   mach_reserve_bootmem for details); use both as one big area.  */
+#define RAM_START 	SRAM_ADDR
+#define RAM_END		(SDRAM_ADDR + SDRAM_SIZE)
+
+/* The bits of this port are connected to an 8-LED bar-graph.  */
+#define LEDS_PORT	0
+
+
+static void anna_led_tick (void);
+
+
+void __init mach_early_init (void)
+{
+	ANNA_ILBEN    = 0;
+
+	V850E2_CSC(0) = 0x402F;
+	V850E2_CSC(1) = 0x4000;
+	V850E2_BPC    = 0;
+	V850E2_BSC    = 0xAAAA;
+	V850E2_BEC    = 0;
+
+#if 0
+	V850E2_BHC    = 0xFFFF;	/* icache all memory, dcache all */
+#else
+	V850E2_BHC    = 0;	/* cache no memory */
+#endif
+	V850E2_BCT(0) = 0xB088;
+	V850E2_BCT(1) = 0x0008;
+	V850E2_DWC(0) = 0x0027;
+	V850E2_DWC(1) = 0;
+	V850E2_BCC    = 0x0006;
+	V850E2_ASC    = 0;
+	V850E2_LBS    = 0x0089;
+	V850E2_SCR(3) = 0x21A9;
+	V850E2_RFS(3) = 0x8121;
+
+	v850e_intc_disable_irqs ();
+}
+
+void __init mach_setup (char **cmdline)
+{
+	ANNA_PORT_PM (LEDS_PORT) = 0;	/* Make all LED pins output pins.  */
+	mach_tick = anna_led_tick;
+	ROOT_DEV = MKDEV (BLKMEM_MAJOR, 0);
+}
+
+void __init mach_get_physical_ram (unsigned long *ram_start,
+				   unsigned long *ram_len)
+{
+	*ram_start = RAM_START;
+	*ram_len = RAM_END - RAM_START;
+}
+
+void __init mach_reserve_bootmem ()
+{
+	extern char _root_fs_image_start, _root_fs_image_end;
+	u32 root_fs_image_start = (u32)&_root_fs_image_start;
+	u32 root_fs_image_end = (u32)&_root_fs_image_end;
+
+	/* The space between SRAM and SDRAM is filled with duplicate
+	   images of SRAM.  Prevent the kernel from using them.  */
+	reserve_bootmem (SRAM_ADDR + SRAM_SIZE,
+			 SDRAM_ADDR - (SRAM_ADDR + SRAM_SIZE));
+
+	/* Reserve the memory used by the root filesystem image if it's
+	   in RAM.  */
+	if (root_fs_image_end > root_fs_image_start
+	    && root_fs_image_start >= RAM_START
+	    && root_fs_image_start < RAM_END)
+		reserve_bootmem (root_fs_image_start,
+				 root_fs_image_end - root_fs_image_start);
+}
+
+void mach_gettimeofday (struct timeval *tv)
+{
+	tv->tv_sec = 0;
+	tv->tv_usec = 0;
+}
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* Start hardware timer.  */
+	v850e_timer_d_configure (0, HZ);
+	/* Install timer interrupt handler.  */
+	setup_irq (IRQ_INTCMD(0), timer_action);
+}
+
+static struct v850e_intc_irq_init irq_inits[] = {
+	{ "IRQ", 0, 		NUM_MACH_IRQS,	1, 7 },
+	{ "PIN", IRQ_INTP(0),   IRQ_INTP_NUM,   1, 4 },
+	{ "CCC", IRQ_INTCCC(0),	IRQ_INTCCC_NUM, 1, 5 },
+	{ "CMD", IRQ_INTCMD(0), IRQ_INTCMD_NUM,	1, 5 },
+	{ "DMA", IRQ_INTDMA(0), IRQ_INTDMA_NUM,	1, 2 },
+	{ "DMXER", IRQ_INTDMXER,1,		1, 2 },
+	{ "SRE", IRQ_INTSRE(0), IRQ_INTSRE_NUM,	3, 3 },
+	{ "SR",	 IRQ_INTSR(0),	IRQ_INTSR_NUM, 	3, 4 },
+	{ "ST",  IRQ_INTST(0), 	IRQ_INTST_NUM, 	3, 5 },
+	{ 0 }
+};
+#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
+
+static struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
+
+void __init mach_init_irqs (void)
+{
+	v850e_intc_init_irq_types (irq_inits, hw_itypes);
+}
+
+void machine_restart (char *__unused)
+{
+#ifdef CONFIG_RESET_GUARD
+	disable_reset_guard ();
+#endif
+	asm ("jmp r0"); /* Jump to the reset vector.  */
+}
+
+void machine_halt (void)
+{
+#ifdef CONFIG_RESET_GUARD
+	disable_reset_guard ();
+#endif
+	local_irq_disable ();	/* Ignore all interrupts.  */
+	ANNA_PORT_IO(LEDS_PORT) = 0xAA;	/* Note that we halted.  */
+	for (;;)
+		asm ("halt; nop; nop; nop; nop; nop");
+}
+
+void machine_power_off (void)
+{
+	machine_halt ();
+}
+
+/* Called before configuring an on-chip UART.  */
+void anna_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud)
+{
+	/* The Anna connects some general-purpose I/O pins on the CPU to
+	   the RTS/CTS lines of UART 1's serial connection.  I/O pins P07
+	   and P37 are RTS and CTS respectively.  */
+	if (chan == 1) {
+		ANNA_PORT_PM(0) &= ~0x80; /* P07 in output mode */
+		ANNA_PORT_PM(3) |=  0x80; /* P37 in input mode */
+	}
+}
+
+/* Minimum and maximum bounds for the moving upper LED boundary in the
+   clock tick display.  We can't use the last bit because it's used for
+   UART0's CTS output.  */
+#define MIN_MAX_POS 0
+#define MAX_MAX_POS 6
+
+/* There are MAX_MAX_POS^2 - MIN_MAX_POS^2 cycles in the animation, so if
+   we pick 6 and 0 as above, we get 49 cycles, which is when divided into
+   the standard 100 value for HZ, gives us an almost 1s total time.  */
+#define TICKS_PER_FRAME \
+	(HZ / (MAX_MAX_POS * MAX_MAX_POS - MIN_MAX_POS * MIN_MAX_POS))
+
+static void anna_led_tick ()
+{
+	static unsigned counter = 0;
+	
+	if (++counter == TICKS_PER_FRAME) {
+		static int pos = 0, max_pos = MAX_MAX_POS, dir = 1;
+
+		if (dir > 0 && pos == max_pos) {
+			dir = -1;
+			if (max_pos == MIN_MAX_POS)
+				max_pos = MAX_MAX_POS;
+			else
+				max_pos--;
+		} else {
+			if (dir < 0 && pos == 0)
+				dir = 1;
+
+			if (pos + dir <= max_pos) {
+				/* Each bit of port 0 has a LED. */
+				clear_bit (pos, &ANNA_PORT_IO(LEDS_PORT));
+				pos += dir;
+				set_bit (pos, &ANNA_PORT_IO(LEDS_PORT));
+			}
+		}
+
+		counter = 0;
+	}
+}
diff -urN linux-2.4.29/arch/v850/kernel/anna.ld linux-2.4.29-uc1/arch/v850/kernel/anna.ld
--- linux-2.4.29/arch/v850/kernel/anna.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/anna.ld	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,20 @@
+/* Linker script for the Midas labs Anna V850E2 evaluation board
+   (CONFIG_V850E2_ANNA).  */
+
+MEMORY {
+	/* 256KB of internal memory (followed by one mirror).  */
+	iMEM0 : ORIGIN = 0,	     LENGTH = 0x00040000
+	/* 256KB of internal memory (followed by one mirror).  */
+	iMEM1 : ORIGIN = 0x00040000, LENGTH = 0x00040000
+
+	/* 1MB of static RAM.  This memory is mirrored 64 times.  */
+	SRAM  : ORIGIN = SRAM_ADDR,  LENGTH = SRAM_SIZE
+	/* 64MB of DRAM.  */
+	SDRAM : ORIGIN = SDRAM_ADDR, LENGTH = SDRAM_SIZE
+}
+
+SECTIONS {
+	.intv : { INTV_CONTENTS } > iMEM0
+	.sram : { RAMK_KRAM_CONTENTS } > SRAM
+	.root : { ROOT_FS_CONTENTS } > SDRAM
+}
diff -urN linux-2.4.29/arch/v850/kernel/anna-rom.ld linux-2.4.29-uc1/arch/v850/kernel/anna-rom.ld
--- linux-2.4.29/arch/v850/kernel/anna-rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/anna-rom.ld	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,16 @@
+/* Linker script for the Midas labs Anna V850E2 evaluation board
+   (CONFIG_V850E2_ANNA), with kernel in ROM (CONFIG_ROM_KERNEL).  */
+
+MEMORY {
+	/* 8MB of flash ROM.  */
+	ROM   : ORIGIN = 0,          LENGTH = 0x00800000
+
+	/* 1MB of static RAM.  This memory is mirrored 64 times.  */
+	SRAM  : ORIGIN = SRAM_ADDR,  LENGTH = SRAM_SIZE
+	/* 64MB of DRAM.  */
+	SDRAM : ORIGIN = SDRAM_ADDR, LENGTH = SDRAM_SIZE
+}
+
+SECTIONS {
+	ROMK_SECTIONS(ROM, SRAM)
+}
diff -urN linux-2.4.29/arch/v850/kernel/as85ep1.c linux-2.4.29-uc1/arch/v850/kernel/as85ep1.c
--- linux-2.4.29/arch/v850/kernel/as85ep1.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/as85ep1.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,246 @@
+/*
+ * arch/v850/kernel/as85ep1.c -- AS85EP1 V850E evaluation chip/board
+ *
+ *  Copyright (C) 2002,03  NEC Electronics Corporation
+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/major.h>
+#include <linux/irq.h>
+
+#include <asm/machdep.h>
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/v850e_timer_d.h>
+#include <asm/v850e_uart.h>
+
+#include "mach.h"
+
+
+/* SRAM and SDRAM are vaguely contiguous (with a big hole in between; see
+   mach_reserve_bootmem for details); use both as one big area.  */
+#define RAM_START 	SRAM_ADDR
+#define RAM_END		(SDRAM_ADDR + SDRAM_SIZE)
+
+/* The bits of this port are connected to an 8-LED bar-graph.  */
+#define LEDS_PORT	4
+
+
+static void as85ep1_led_tick (void);
+
+extern char _intv_copy_src_start, _intv_copy_src_end;
+extern char _intv_copy_dst_start;
+
+
+void __init mach_early_init (void)
+{
+#ifndef CONFIG_ROM_KERNEL
+	const u32 *src;
+	register u32 *dst asm ("ep");
+#endif
+
+	AS85EP1_CSC(0) = 0x0403;
+	AS85EP1_BCT(0) = 0xB8B8;
+	AS85EP1_DWC(0) = 0x0104;
+	AS85EP1_BCC    = 0x0012;
+	AS85EP1_ASC    = 0;
+	AS85EP1_LBS    = 0x00A9;
+
+	AS85EP1_PORT_PMC(6)  = 0xFF; /* A20-25, A0,A1 $BM-8z(B */
+	AS85EP1_PORT_PMC(7)  = 0x0E; /* CS1,2,3       $BM-8z(B */
+	AS85EP1_PORT_PMC(9)  = 0xFF; /* D16-23        $BM-8z(B */
+	AS85EP1_PORT_PMC(10) = 0xFF; /* D24-31        $BM-8z(B */
+
+	AS85EP1_RFS(1) = 0x800c;
+	AS85EP1_RFS(3) = 0x800c;
+	AS85EP1_SCR(1) = 0x20A9;
+	AS85EP1_SCR(3) = 0x20A9;
+
+#ifndef CONFIG_ROM_KERNEL
+	/* The early chip we have is buggy, and writing the interrupt
+	   vectors into low RAM may screw up, so for non-ROM kernels, we
+	   only rely on the reset vector being downloaded, and copy the
+	   rest of the interrupt vectors into place here.  The specific bug
+	   is that writing address N, where (N & 0x10) == 0x10, will _also_
+	   write to address (N - 0x10).  We avoid this (effectively) by
+	   writing in 16-byte chunks backwards from the end.  */
+
+	AS85EP1_IRAMM = 0x3;	/* $BFbB"L?Na(BRAM$B$O!V(Bwrite-mode$B!W$K$J$j$^$9(B */
+
+	src = (u32 *)(((u32)&_intv_copy_src_end - 1) & ~0xF);
+	dst = (u32 *)&_intv_copy_dst_start
+		+ (src - (u32 *)&_intv_copy_src_start);
+	do {
+		u32 t0 = src[0], t1 = src[1], t2 = src[2], t3 = src[3];
+		dst[0] = t0; dst[1] = t1; dst[2] = t2; dst[3] = t3;
+		dst -= 4;
+		src -= 4;
+	} while (src > (u32 *)&_intv_copy_src_start);
+
+	AS85EP1_IRAMM = 0x0;	/* $BFbB"L?Na(BRAM$B$O!V(Bread-mode$B!W$K$J$j$^$9(B */
+#endif /* !CONFIG_ROM_KERNEL */
+
+	v850e_intc_disable_irqs ();
+}
+
+void __init mach_setup (char **cmdline)
+{
+	AS85EP1_PORT_PMC (LEDS_PORT) = 0; /* Make the LEDs port an I/O port. */
+	AS85EP1_PORT_PM (LEDS_PORT) = 0; /* Make all the bits output pins.  */
+	mach_tick = as85ep1_led_tick;
+	ROOT_DEV = MKDEV (BLKMEM_MAJOR, 0);
+}
+
+void __init mach_get_physical_ram (unsigned long *ram_start,
+				   unsigned long *ram_len)
+{
+	*ram_start = RAM_START;
+	*ram_len = RAM_END - RAM_START;
+}
+
+/* Convenience macros.  */
+#define SRAM_END	(SRAM_ADDR + SRAM_SIZE)
+#define SDRAM_END	(SDRAM_ADDR + SDRAM_SIZE)
+
+void __init mach_reserve_bootmem ()
+{
+	extern char _root_fs_image_start, _root_fs_image_end;
+	u32 root_fs_image_start = (u32)&_root_fs_image_start;
+	u32 root_fs_image_end = (u32)&_root_fs_image_end;
+
+	if (SDRAM_ADDR < RAM_END && SDRAM_ADDR > RAM_START)
+		/* We can't use the space between SRAM and SDRAM, so
+		   prevent the kernel from trying.  */
+		reserve_bootmem (SRAM_END, SDRAM_ADDR - SRAM_END);
+
+	/* Reserve the memory used by the root filesystem image if it's
+	   in RAM.  */
+	if (root_fs_image_end > root_fs_image_start
+	    && root_fs_image_start >= RAM_START
+	    && root_fs_image_start < RAM_END)
+		reserve_bootmem (root_fs_image_start,
+				 root_fs_image_end - root_fs_image_start);
+}
+
+void mach_gettimeofday (struct timeval *tv)
+{
+	tv->tv_sec = 0;
+	tv->tv_usec = 0;
+}
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* Start hardware timer.  */
+	v850e_timer_d_configure (0, HZ);
+	/* Install timer interrupt handler.  */
+	setup_irq (IRQ_INTCMD(0), timer_action);
+}
+
+static struct v850e_intc_irq_init irq_inits[] = {
+	{ "IRQ", 0, 		NUM_MACH_IRQS,	1, 7 },
+	{ "CCC", IRQ_INTCCC(0),	IRQ_INTCCC_NUM, 1, 5 },
+	{ "CMD", IRQ_INTCMD(0), IRQ_INTCMD_NUM,	1, 5 },
+	{ "SRE", IRQ_INTSRE(0), IRQ_INTSRE_NUM,	3, 3 },
+	{ "SR",	 IRQ_INTSR(0),	IRQ_INTSR_NUM, 	3, 4 },
+	{ "ST",  IRQ_INTST(0), 	IRQ_INTST_NUM, 	3, 5 },
+	{ 0 }
+};
+#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
+
+static struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
+
+void __init mach_init_irqs (void)
+{
+	v850e_intc_init_irq_types (irq_inits, hw_itypes);
+}
+
+void machine_restart (char *__unused)
+{
+#ifdef CONFIG_RESET_GUARD
+	disable_reset_guard ();
+#endif
+	asm ("jmp r0"); /* Jump to the reset vector.  */
+}
+
+void machine_halt (void)
+{
+#ifdef CONFIG_RESET_GUARD
+	disable_reset_guard ();
+#endif
+	local_irq_disable ();	/* Ignore all interrupts.  */
+	AS85EP1_PORT_IO (LEDS_PORT) = 0xAA;	/* Note that we halted.  */
+	for (;;)
+		asm ("halt; nop; nop; nop; nop; nop");
+}
+
+void machine_power_off (void)
+{
+	machine_halt ();
+}
+
+/* Called before configuring an on-chip UART.  */
+void as85ep1_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud)
+{
+	/* Make the shared uart/port pins be uart pins.  */
+	AS85EP1_PORT_PMC(3) |= (0x5 << chan);
+
+	/* The AS85EP1 connects some general-purpose I/O pins on the CPU to
+	   the RTS/CTS lines of UART 1's serial connection.  I/O pins P53
+	   and P54 are RTS and CTS respectively.  */
+	if (chan == 1) {
+		/* Put P53 & P54 in I/O port mode.  */
+		AS85EP1_PORT_PMC(5) &= ~0x18;
+		/* Make P53 an output, and P54 an input.  */
+		AS85EP1_PORT_PM(5) |=  0x10;
+	}
+}
+
+/* Minimum and maximum bounds for the moving upper LED boundary in the
+   clock tick display.  */
+#define MIN_MAX_POS 0
+#define MAX_MAX_POS 7
+
+/* There are MAX_MAX_POS^2 - MIN_MAX_POS^2 cycles in the animation, so if
+   we pick 6 and 0 as above, we get 49 cycles, which is when divided into
+   the standard 100 value for HZ, gives us an almost 1s total time.  */
+#define TICKS_PER_FRAME \
+	(HZ / (MAX_MAX_POS * MAX_MAX_POS - MIN_MAX_POS * MIN_MAX_POS))
+
+static void as85ep1_led_tick ()
+{
+	static unsigned counter = 0;
+	
+	if (++counter == TICKS_PER_FRAME) {
+		static int pos = 0, max_pos = MAX_MAX_POS, dir = 1;
+
+		if (dir > 0 && pos == max_pos) {
+			dir = -1;
+			if (max_pos == MIN_MAX_POS)
+				max_pos = MAX_MAX_POS;
+			else
+				max_pos--;
+		} else {
+			if (dir < 0 && pos == 0)
+				dir = 1;
+
+			if (pos + dir <= max_pos) {
+				/* Each bit of port 0 has a LED. */
+				set_bit (pos, &AS85EP1_PORT_IO(LEDS_PORT));
+				pos += dir;
+				clear_bit (pos, &AS85EP1_PORT_IO(LEDS_PORT));
+			}
+		}
+
+		counter = 0;
+	}
+}
diff -urN linux-2.4.29/arch/v850/kernel/as85ep1.ld linux-2.4.29-uc1/arch/v850/kernel/as85ep1.ld
--- linux-2.4.29/arch/v850/kernel/as85ep1.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/as85ep1.ld	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,49 @@
+/* Linker script for the NEC AS85EP1 V850E evaluation board
+   (CONFIG_V850E_AS85EP1).  */
+
+MEMORY {
+	/* 1MB of internal memory (ÆâÂ¢Ì¿ÎáRAM).  */
+	iMEM0 : ORIGIN = 0,	     LENGTH = 0x00100000
+
+	/* 1MB of static RAM.  */
+	SRAM  : ORIGIN = SRAM_ADDR,  LENGTH = SRAM_SIZE
+
+	/* About 58MB of DRAM.  This can actually be at one of two
+	   positions, determined by jump JP3; we have to use the first
+	   position because the second is partially out of processor
+	   instruction addressing range (though in the second position
+	   there's actually 64MB available).  */
+	SDRAM : ORIGIN = SDRAM_ADDR, LENGTH = SDRAM_SIZE
+}
+
+SECTIONS {
+	.resetv : {
+		__intv_start = . ;
+			*(.intv.reset)	/* Reset vector */
+	} > iMEM0
+
+	.sram : {
+		RAMK_KRAM_CONTENTS
+
+		/* We stick most of the interrupt vectors here; they'll be
+		   copied into the proper location by the early init code (we
+		   can't put them directly in the right place because of
+		   hardware bugs).  The vectors shouldn't need to be
+		   relocated, so we don't have to use `> ...  AT> ...' to
+		   split the load/vm addresses (and we can't because of
+		   problems with the loader).  */
+		. = ALIGN (0x10) ;
+		__intv_copy_src_start = . ;
+			*(.intv.common)	/* Vectors common to all v850e proc. */
+			*(.intv.mach)	/* Machine-specific int. vectors.  */
+		. = ALIGN (0x10) ;
+		__intv_copy_src_end = . ;
+	} > SRAM
+
+	/* Where we end up putting the vectors.  */
+	__intv_copy_dst_start = 0x10 ;
+	__intv_copy_dst_end = __intv_copy_dst_start + (__intv_copy_src_end - __intv_copy_src_start) ;
+	__intv_end = __intv_copy_dst_end ;
+
+	.root : { ROOT_FS_CONTENTS } > SDRAM
+}
diff -urN linux-2.4.29/arch/v850/kernel/as85ep1-rom.ld linux-2.4.29-uc1/arch/v850/kernel/as85ep1-rom.ld
--- linux-2.4.29/arch/v850/kernel/as85ep1-rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/as85ep1-rom.ld	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,21 @@
+/* Linker script for the NEC AS85EP1 V850E evaluation board
+   (CONFIG_V850E_AS85EP1), with kernel in ROM (CONFIG_ROM_KERNEL).  */
+
+MEMORY {
+	/* 4MB of flash ROM.  */
+	ROM   : ORIGIN = 0,          LENGTH = 0x00400000
+
+	/* 1MB of static RAM.  */
+	SRAM  : ORIGIN = SRAM_ADDR,  LENGTH = SRAM_SIZE
+
+	/* About 58MB of DRAM.  This can actually be at one of two
+	   positions, determined by jumper JP3; we have to use the first
+	   position because the second is partially out of processor
+	   instruction addressing range (though in the second position
+	   there's actually 64MB available).  */
+	SDRAM : ORIGIN = SDRAM_ADDR, LENGTH = SDRAM_SIZE
+}
+
+SECTIONS {
+	ROMK_SECTIONS(ROM, SRAM)
+}
diff -urN linux-2.4.29/arch/v850/kernel/bug.c linux-2.4.29-uc1/arch/v850/kernel/bug.c
--- linux-2.4.29/arch/v850/kernel/bug.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/bug.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,56 @@
+/*
+ * arch/v850/kernel/bug.c -- Bug reporting functions
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/sched.h>
+
+#include <asm/errno.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+
+/* We should use __builtin_return_address, but it doesn't work in gcc-2.90
+   (which is currently our standard compiler on the v850).  */
+#define ret_addr() ({ register u32 lp asm ("lp"); lp; })
+#define stack_addr() ({ register u32 sp asm ("sp"); sp; })
+
+void __bug ()
+{
+	printk (KERN_CRIT "kernel BUG at PC 0x%x (SP ~0x%x)!\n",
+		ret_addr() - 4, /* - 4 for `jarl' */
+		stack_addr());
+	machine_halt ();
+}
+
+int bad_trap (int trap_num, struct pt_regs *regs)
+{
+	printk (KERN_CRIT
+		"unimplemented trap %d called at 0x%08lx, pid %d!\n",
+		trap_num, regs->pc, current->pid);
+	return -ENOSYS;
+}
+
+#ifdef CONFIG_RESET_GUARD
+void unexpected_reset (unsigned long ret_addr, unsigned long kmode,
+		       struct task_struct *task, unsigned long sp)
+{
+	printk (KERN_CRIT
+		"unexpected reset in %s mode, pid %d"
+		" (ret_addr = 0x%lx, sp = 0x%lx)\n",
+		kmode ? "kernel" : "user",
+		task ? task->pid : -1,
+		ret_addr, sp);
+
+	machine_halt ();
+}
+#endif /* CONFIG_RESET_GUARD */
diff -urN linux-2.4.29/arch/v850/kernel/entry.S linux-2.4.29-uc1/arch/v850/kernel/entry.S
--- linux-2.4.29/arch/v850/kernel/entry.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/entry.S	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,1113 @@
+/*
+ * arch/v850/kernel/entry.S -- Low-level system-call handling, trap handlers,
+ *	and context-switching
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/sys.h>
+
+#include <asm/entry.h>
+#include <asm/current.h>
+#include <asm/clinkage.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <asm/errno.h>
+
+#include "v850_defs.h"
+
+
+/* Make a slightly more convenient alias for C_SYMBOL_NAME.  */
+#define CSYM	C_SYMBOL_NAME
+
+
+/* The offset of the struct pt_regs in a state-save-frame on the stack.  */
+#define PTO	STATE_SAVE_PT_OFFSET
+
+
+/* Save argument registers to the state-save-frame pointed to by EP.  */
+#define SAVE_ARG_REGS							      \
+	sst.w	r6, PTO+PT_GPR(6)[ep];					      \
+	sst.w	r7, PTO+PT_GPR(7)[ep];					      \
+	sst.w	r8, PTO+PT_GPR(8)[ep];					      \
+	sst.w	r9, PTO+PT_GPR(9)[ep]
+/* Restore argument registers from the state-save-frame pointed to by EP.  */
+#define RESTORE_ARG_REGS						      \
+	sld.w	PTO+PT_GPR(6)[ep], r6;					      \
+	sld.w	PTO+PT_GPR(7)[ep], r7;					      \
+	sld.w	PTO+PT_GPR(8)[ep], r8;					      \
+	sld.w	PTO+PT_GPR(9)[ep], r9
+
+/* Save value return registers to the state-save-frame pointed to by EP.  */
+#define SAVE_RVAL_REGS							      \
+	sst.w	r10, PTO+PT_GPR(10)[ep];				      \
+	sst.w	r11, PTO+PT_GPR(11)[ep]
+/* Restore value return registers from the state-save-frame pointed to by EP.  */
+#define RESTORE_RVAL_REGS						      \
+	sld.w	PTO+PT_GPR(10)[ep], r10;				      \
+	sld.w	PTO+PT_GPR(11)[ep], r11
+
+
+#define SAVE_CALL_CLOBBERED_REGS_BEFORE_ARGS				      \
+	sst.w	r1, PTO+PT_GPR(1)[ep];					      \
+	sst.w	r5, PTO+PT_GPR(5)[ep]
+#define SAVE_CALL_CLOBBERED_REGS_AFTER_RVAL				      \
+	sst.w	r12, PTO+PT_GPR(12)[ep];				      \
+	sst.w	r13, PTO+PT_GPR(13)[ep];				      \
+	sst.w	r14, PTO+PT_GPR(14)[ep];				      \
+	sst.w	r15, PTO+PT_GPR(15)[ep];				      \
+	sst.w	r16, PTO+PT_GPR(16)[ep];				      \
+	sst.w	r17, PTO+PT_GPR(17)[ep];				      \
+	sst.w	r18, PTO+PT_GPR(18)[ep];				      \
+	sst.w	r19, PTO+PT_GPR(19)[ep]
+#define RESTORE_CALL_CLOBBERED_REGS_BEFORE_ARGS				      \
+	sld.w	PTO+PT_GPR(1)[ep], r1;					      \
+	sld.w	PTO+PT_GPR(5)[ep], r5
+#define RESTORE_CALL_CLOBBERED_REGS_AFTER_RVAL				      \
+	sld.w	PTO+PT_GPR(12)[ep], r12;				      \
+	sld.w	PTO+PT_GPR(13)[ep], r13;				      \
+	sld.w	PTO+PT_GPR(14)[ep], r14;				      \
+	sld.w	PTO+PT_GPR(15)[ep], r15;				      \
+	sld.w	PTO+PT_GPR(16)[ep], r16;				      \
+	sld.w	PTO+PT_GPR(17)[ep], r17;				      \
+	sld.w	PTO+PT_GPR(18)[ep], r18;				      \
+	sld.w	PTO+PT_GPR(19)[ep], r19
+
+/* Save `call clobbered' registers to the state-save-frame pointed to by EP.  */
+#define SAVE_CALL_CLOBBERED_REGS					      \
+	SAVE_CALL_CLOBBERED_REGS_BEFORE_ARGS;				      \
+	SAVE_ARG_REGS;							      \
+	SAVE_RVAL_REGS;							      \
+	SAVE_CALL_CLOBBERED_REGS_AFTER_RVAL
+/* Restore `call clobbered' registers from the state-save-frame pointed to
+   by EP.  */
+#define RESTORE_CALL_CLOBBERED_REGS					      \
+	RESTORE_CALL_CLOBBERED_REGS_BEFORE_ARGS;			      \
+	RESTORE_ARG_REGS;						      \
+	RESTORE_RVAL_REGS;						      \
+	RESTORE_CALL_CLOBBERED_REGS_AFTER_RVAL
+
+/* Save `call clobbered' registers except for the return-value registers
+   to the state-save-frame pointed to by EP.  */
+#define SAVE_CALL_CLOBBERED_REGS_NO_RVAL				      \
+	SAVE_CALL_CLOBBERED_REGS_BEFORE_ARGS;				      \
+	SAVE_ARG_REGS;							      \
+	SAVE_CALL_CLOBBERED_REGS_AFTER_RVAL
+/* Restore `call clobbered' registers except for the return-value registers
+   from the state-save-frame pointed to by EP.  */
+#define RESTORE_CALL_CLOBBERED_REGS_NO_RVAL				      \
+	RESTORE_CALL_CLOBBERED_REGS_BEFORE_ARGS;			      \
+	RESTORE_ARG_REGS;						      \
+	RESTORE_CALL_CLOBBERED_REGS_AFTER_RVAL
+
+/* Save `call saved' registers to the state-save-frame pointed to by EP.  */
+#define SAVE_CALL_SAVED_REGS						      \
+	sst.w	r2, PTO+PT_GPR(2)[ep];					      \
+	sst.w	r20, PTO+PT_GPR(20)[ep];				      \
+	sst.w	r21, PTO+PT_GPR(21)[ep];				      \
+	sst.w	r22, PTO+PT_GPR(22)[ep];				      \
+	sst.w	r23, PTO+PT_GPR(23)[ep];				      \
+	sst.w	r24, PTO+PT_GPR(24)[ep];				      \
+	sst.w	r25, PTO+PT_GPR(25)[ep];				      \
+	sst.w	r26, PTO+PT_GPR(26)[ep];				      \
+	sst.w	r27, PTO+PT_GPR(27)[ep];				      \
+	sst.w	r28, PTO+PT_GPR(28)[ep];				      \
+	sst.w	r29, PTO+PT_GPR(29)[ep]
+/* Restore `call saved' registers from the state-save-frame pointed to by EP.  */
+#define RESTORE_CALL_SAVED_REGS						      \
+	sld.w	PTO+PT_GPR(2)[ep], r2;					      \
+	sld.w	PTO+PT_GPR(20)[ep], r20;				      \
+	sld.w	PTO+PT_GPR(21)[ep], r21;				      \
+	sld.w	PTO+PT_GPR(22)[ep], r22;				      \
+	sld.w	PTO+PT_GPR(23)[ep], r23;				      \
+	sld.w	PTO+PT_GPR(24)[ep], r24;				      \
+	sld.w	PTO+PT_GPR(25)[ep], r25;				      \
+	sld.w	PTO+PT_GPR(26)[ep], r26;				      \
+	sld.w	PTO+PT_GPR(27)[ep], r27;				      \
+	sld.w	PTO+PT_GPR(28)[ep], r28;				      \
+	sld.w	PTO+PT_GPR(29)[ep], r29
+
+
+/* Save the PC stored in the special register SAVEREG to the state-save-frame
+   pointed to by EP.  r19 is clobbered.  */
+#define SAVE_PC(savereg)						      \
+	stsr	SR_ ## savereg, r19;					      \
+	sst.w	r19, PTO+PT_PC[ep]
+/* Restore the PC from the state-save-frame pointed to by EP, to the special
+   register SAVEREG.  LP is clobbered (it is used as a scratch register
+   because the POP_STATE macro restores it, and this macro is usually used
+   inside POP_STATE).  */
+#define RESTORE_PC(savereg)						      \
+	sld.w	PTO+PT_PC[ep], lp;					      \
+	ldsr	lp, SR_ ## savereg
+/* Save the PSW register stored in the special register SAVREG to the
+   state-save-frame pointed to by EP.  r19 is clobbered.  */
+#define SAVE_PSW(savereg)						      \
+	stsr	SR_ ## savereg, r19;					      \
+	sst.w	r19, PTO+PT_PSW[ep]
+/* Restore the PSW register from the state-save-frame pointed to by EP, to
+   the special register SAVEREG.  LP is clobbered (it is used as a scratch
+   register because the POP_STATE macro restores it, and this macro is
+   usually used inside POP_STATE).  */
+#define RESTORE_PSW(savereg)						      \
+	sld.w	PTO+PT_PSW[ep], lp;					      \
+	ldsr	lp, SR_ ## savereg
+
+/* Save CTPC/CTPSW/CTBP registers to the state-save-frame pointed to by REG.
+   r19 is clobbered.  */
+#define SAVE_CT_REGS							      \
+	stsr	SR_CTPC, r19;						      \
+	sst.w	r19, PTO+PT_CTPC[ep];					      \
+	stsr	SR_CTPSW, r19;						      \
+	sst.w	r19, PTO+PT_CTPSW[ep];					      \
+	stsr	SR_CTBP, r19;						      \
+	sst.w	r19, PTO+PT_CTBP[ep]
+/* Restore CTPC/CTPSW/CTBP registers from the state-save-frame pointed to by EP.
+   LP is clobbered (it is used as a scratch register because the POP_STATE
+   macro restores it, and this macro is usually used inside POP_STATE).  */
+#define RESTORE_CT_REGS							      \
+	sld.w	PTO+PT_CTPC[ep], lp;					      \
+	ldsr	lp, SR_CTPC;						      \
+	sld.w	PTO+PT_CTPSW[ep], lp;					      \
+	ldsr	lp, SR_CTPSW;						      \
+	sld.w	PTO+PT_CTBP[ep], lp;					      \
+	ldsr	lp, SR_CTBP
+
+
+/* Push register state, except for the stack pointer, on the stack in the
+   form of a state-save-frame (plus some extra padding), in preparation for
+   a system call.  This macro makes sure that the EP, GP, and LP
+   registers are saved, and TYPE identifies the set of extra registers to
+   be saved as well.  Also copies (the new value of) SP to EP.  */
+#define PUSH_STATE(type)						      \
+	addi	-STATE_SAVE_SIZE, sp, sp; /* Make room on the stack.  */      \
+	st.w	ep, PTO+PT_GPR(GPR_EP)[sp];				      \
+	mov	sp, ep;							      \
+	sst.w	gp, PTO+PT_GPR(GPR_GP)[ep];				      \
+	sst.w	lp, PTO+PT_GPR(GPR_LP)[ep];				      \
+	type ## _STATE_SAVER
+/* Pop a register state pushed by PUSH_STATE, except for the stack pointer,
+   from the the stack.  */
+#define POP_STATE(type)							      \
+	mov	sp, ep;							      \
+	type ## _STATE_RESTORER;					      \
+	sld.w	PTO+PT_GPR(GPR_GP)[ep], gp;				      \
+	sld.w	PTO+PT_GPR(GPR_LP)[ep], lp;				      \
+	sld.w	PTO+PT_GPR(GPR_EP)[ep], ep;				      \
+	addi	STATE_SAVE_SIZE, sp, sp /* Clean up our stack space.  */
+
+
+/* Switch to the kernel stack if necessary, and push register state on the
+   stack in the form of a state-save-frame.  Also load the current task
+   pointer if switching from user mode.  The stack-pointer (r3) should have
+   already been saved to the memory location SP_SAVE_LOC (the reason for
+   this is that the interrupt vectors may be beyond a 22-bit signed offset
+   jump from the actual interrupt handler, and this allows them to save the
+   stack-pointer and use that register to do an indirect jump).  This macro
+   makes sure that `special' registers, system registers, and the stack
+   pointer are saved; TYPE identifies the set of extra registers to be
+   saved as well.  SYSCALL_NUM is the register in which the system-call
+   number this state is for is stored (r0 if this isn't a system call).
+   Interrupts should already be disabled when calling this.  */
+#define SAVE_STATE(type, syscall_num, sp_save_loc)			      \
+	tst1	0, KM;			/* See if already in kernel mode.  */ \
+	bz	1f;							      \
+	ld.w	sp_save_loc, sp;	/* ... yes, use saved SP.  */	      \
+	br	2f;							      \
+1:	ld.w	KSP, sp;		/* ... no, switch to kernel stack. */ \
+2:	PUSH_STATE(type);						      \
+	ld.b	KM, r19;		/* Remember old kernel-mode.  */      \
+	sst.w	r19, PTO+PT_KERNEL_MODE[ep];				      \
+	ld.w	sp_save_loc, r19;	/* Remember old SP.  */		      \
+	sst.w	r19, PTO+PT_GPR(GPR_SP)[ep];				      \
+	mov	1, r19;			/* Now definitely in kernel-mode. */  \
+	st.b	r19, KM;						      \
+	GET_CURRENT_TASK(CURRENT_TASK);	/* Fetch the current task pointer. */ \
+	/* Save away the syscall number.  */				      \
+	sst.w	syscall_num, PTO+PT_CUR_SYSCALL[ep]
+
+
+/* Save register state not normally saved by PUSH_STATE for TYPE, to the
+   state-save-frame on the stack; also copies SP to EP.  r19 may be trashed. */
+#define SAVE_EXTRA_STATE(type)						      \
+	mov	sp, ep;							      \
+	type ## _EXTRA_STATE_SAVER
+/* Restore register state not normally restored by POP_STATE for TYPE,
+   from the state-save-frame on the stack; also copies SP to EP.
+   r19 may be trashed.  */
+#define RESTORE_EXTRA_STATE(type)					      \
+	mov	sp, ep;							      \
+	type ## _EXTRA_STATE_RESTORER
+
+/* Save any call-clobbered registers not normally saved by PUSH_STATE for
+   TYPE, to the state-save-frame on the stack.
+   EP may be trashed, but is not guaranteed to contain a copy of SP
+   (unlike after most SAVE_... macros).  r19 may be trashed.  */
+#define SAVE_EXTRA_STATE_FOR_SCHEDULE(type)				      \
+	type ## _SCHEDULE_EXTRA_STATE_SAVER
+/* Restore any call-clobbered registers not normally restored by
+   POP_STATE for TYPE, to the state-save-frame on the stack.
+   EP may be trashed, but is not guaranteed to contain a copy of SP
+   (unlike after most RESTORE_... macros).  r19 may be trashed.  */
+#define RESTORE_EXTRA_STATE_FOR_SCHEDULE(type)				      \
+	type ## _SCHEDULE_EXTRA_STATE_RESTORER
+
+
+/* These are extra_state_saver/restorer values for a user trap.  Note
+   that we save the argument registers so that restarted syscalls will
+   function properly (otherwise it wouldn't be necessary), and we must
+   _not_ restore the return-value registers (so that traps can return a
+   value!), but call-clobbered registers are not saved at all, as the
+   caller of the syscall function should have saved them.  */
+
+#define TRAP_RET reti
+/* Traps don't save call-clobbered registers (but do still save arg regs).
+   We preserve PSw to keep long-term state, namely interrupt status (for traps
+   from kernel-mode), and the single-step flag (for user traps).  */
+#define TRAP_STATE_SAVER						      \
+	SAVE_ARG_REGS;							      \
+	SAVE_PC(EIPC);							      \
+	SAVE_PSW(EIPSW)
+/* When traps return, they just leave call-clobbered registers (except for arg
+   regs) with whatever value they have from the kernel.  Traps don't preserve
+   the PSW, but we zero EIPSW to ensure it doesn't contain anything dangerous
+   (in particular, the single-step flag).  */
+#define TRAP_STATE_RESTORER						      \
+	RESTORE_ARG_REGS;						      \
+	RESTORE_PC(EIPC);						      \
+	RESTORE_PSW(EIPSW)
+/* Save registers not normally saved by traps.  We need to save r12, even
+   though it's nominally call-clobbered, because it's used when restarting
+   a system call (the signal-handling path uses SAVE_EXTRA_STATE, and
+   expects r12 to be restored when the trap returns).  */
+#define TRAP_EXTRA_STATE_SAVER						      \
+	SAVE_RVAL_REGS;							      \
+	sst.w	r12, PTO+PT_GPR(12)[ep];				      \
+	SAVE_CALL_SAVED_REGS;						      \
+	SAVE_CT_REGS
+#define TRAP_EXTRA_STATE_RESTORER					      \
+	RESTORE_RVAL_REGS;						      \
+	sld.w	PTO+PT_GPR(12)[ep], r12;				      \
+	RESTORE_CALL_SAVED_REGS;					      \
+	RESTORE_CT_REGS
+/* Save registers prior to calling scheduler (just before trap returns).
+   We have to save the return-value registers to preserve the trap's return
+   value.  Note that ..._SCHEDULE_EXTRA_STATE_SAVER, unlike most ..._SAVER
+   macros, is required to setup EP itself if EP is needed (this is because
+   in many cases, the macro is empty).  */
+#define TRAP_SCHEDULE_EXTRA_STATE_SAVER					      \
+	mov sp, ep;							      \
+	SAVE_RVAL_REGS
+/* Note that ..._SCHEDULE_EXTRA_STATE_RESTORER, unlike most ..._RESTORER
+   macros, is required to setup EP itself if EP is needed (this is because
+   in many cases, the macro is empty).  */
+#define TRAP_SCHEDULE_EXTRA_STATE_RESTORER				      \
+	mov sp, ep;							      \
+	RESTORE_RVAL_REGS
+
+/* Register saving/restoring for maskable interrupts.  */
+#define IRQ_RET reti
+#define IRQ_STATE_SAVER							      \
+	SAVE_CALL_CLOBBERED_REGS;					      \
+	SAVE_PC(EIPC);							      \
+	SAVE_PSW(EIPSW)
+#define IRQ_STATE_RESTORER						      \
+	RESTORE_CALL_CLOBBERED_REGS;					      \
+	RESTORE_PC(EIPC);						      \
+	RESTORE_PSW(EIPSW)
+#define IRQ_EXTRA_STATE_SAVER						      \
+	SAVE_CALL_SAVED_REGS;						      \
+	SAVE_CT_REGS
+#define IRQ_EXTRA_STATE_RESTORER					      \
+	RESTORE_CALL_SAVED_REGS;					      \
+	RESTORE_CT_REGS
+#define IRQ_SCHEDULE_EXTRA_STATE_SAVER	     /* nothing */
+#define IRQ_SCHEDULE_EXTRA_STATE_RESTORER    /* nothing */
+
+/* Register saving/restoring for non-maskable interrupts.  */
+#define NMI_RET reti
+#define NMI_STATE_SAVER							      \
+	SAVE_CALL_CLOBBERED_REGS;					      \
+	SAVE_PC(FEPC);							      \
+	SAVE_PSW(FEPSW);
+#define NMI_STATE_RESTORER						      \
+	RESTORE_CALL_CLOBBERED_REGS;					      \
+	RESTORE_PC(FEPC);						      \
+	RESTORE_PSW(FEPSW);
+#define NMI_EXTRA_STATE_SAVER						      \
+	SAVE_CALL_SAVED_REGS;						      \
+	SAVE_CT_REGS
+#define NMI_EXTRA_STATE_RESTORER					      \
+	RESTORE_CALL_SAVED_REGS;					      \
+	RESTORE_CT_REGS
+#define NMI_SCHEDULE_EXTRA_STATE_SAVER	     /* nothing */
+#define NMI_SCHEDULE_EXTRA_STATE_RESTORER    /* nothing */
+
+/* Register saving/restoring for debug traps.  */
+#define DBTRAP_RET .long 0x014607E0 /* `dbret', but gas doesn't support it. */
+#define DBTRAP_STATE_SAVER						      \
+	SAVE_CALL_CLOBBERED_REGS;					      \
+	SAVE_PC(DBPC);							      \
+	SAVE_PSW(DBPSW)
+#define DBTRAP_STATE_RESTORER						      \
+	RESTORE_CALL_CLOBBERED_REGS;					      \
+	RESTORE_PC(DBPC);						      \
+	RESTORE_PSW(DBPSW)
+#define DBTRAP_EXTRA_STATE_SAVER					      \
+	SAVE_CALL_SAVED_REGS;						      \
+	SAVE_CT_REGS
+#define DBTRAP_EXTRA_STATE_RESTORER					      \
+	RESTORE_CALL_SAVED_REGS;					      \
+	RESTORE_CT_REGS
+#define DBTRAP_SCHEDULE_EXTRA_STATE_SAVER	/* nothing */
+#define DBTRAP_SCHEDULE_EXTRA_STATE_RESTORER	/* nothing */
+
+/* Register saving/restoring for a context switch.  We don't need to save
+   too many registers, because context-switching looks like a function call
+   (via the function `switch_thread'), so callers will save any
+   call-clobbered registers themselves.  We do need to save the CT regs, as
+   they're normally not saved during kernel entry (the kernel doesn't use
+   them).  We save PSW so that interrupt-status state will correctly follow
+   each thread (mostly NMI vs. normal-IRQ/trap), though for the most part
+   it doesn't matter since threads are always in almost exactly the same
+   processor state during a context switch.  The stack pointer and return
+   value are handled by switch_thread itself.  */
+#define SWITCH_STATE_SAVER						      \
+	SAVE_CALL_SAVED_REGS;						      \
+	SAVE_PSW(PSW);							      \
+	SAVE_CT_REGS
+#define SWITCH_STATE_RESTORER						      \
+	RESTORE_CALL_SAVED_REGS;					      \
+	RESTORE_PSW(PSW);						      \
+	RESTORE_CT_REGS
+
+
+/* Restore register state from the state-save-frame on the stack, switch back
+   to the user stack if necessary, and return from the trap/interrupt.
+   EXTRA_STATE_RESTORER is a sequence of assembly language statements to
+   restore anything not restored by this macro.  Only registers not saved by
+   the C compiler are restored (that is, R3(sp), R4(gp), R31(lp), and
+   anything restored by EXTRA_STATE_RESTORER).  */
+#define RETURN(type)							      \
+	ld.b	PTO+PT_KERNEL_MODE[sp], r19;				      \
+	di;				/* Disable interrupts */	      \
+	cmp	r19, r0;		/* See if returning to kernel mode, */\
+	bne	2f;			/* ... if so, skip resched &c.  */    \
+									      \
+	/* We're returning to user mode, so check for various conditions that \
+	   trigger rescheduling. */					      \
+	ld.w	TASK_NEED_RESCHED[CURRENT_TASK], r18;			      \
+	cmp	r18, r0;						      \
+	bnz	3f;			/* Call the scheduler.  */	      \
+									      \
+	/* Maybe handle a signal or ptraced process */			      \
+5:	ld.w	TASK_SIGPENDING[CURRENT_TASK], r18; /* Pending signals */     \
+	ld.w	TASK_PTRACE[CURRENT_TASK], r19; /* ptrace flags */	      \
+	or	r18, r19;		/* see if either is non-zero */	      \
+	bnz	4f;			/* if so, handle them */	      \
+									      \
+/* Return to user state.  */						      \
+1:	st.b	r0, KM;			/* Now officially in user state. */   \
+									      \
+/* Final return.  The stack-pointer fiddling is not needed when returning     \
+   to kernel-mode, but they don't hurt, and this way we can share the	      \
+   (sometimes rather lengthy) POP_STATE macro.  */			      \
+2:	POP_STATE(type);						      \
+	st.w	sp, KSP;		/* Save the kernel stack pointer. */  \
+	ld.w	PT_GPR(GPR_SP)-PT_SIZE[sp], sp; /* Restore stack pointer. */  \
+	type ## _RET;			/* Return from the trap/interrupt. */ \
+									      \
+/* Call the scheduler before returning from a syscall/trap. */		      \
+3:	SAVE_EXTRA_STATE_FOR_SCHEDULE(type); /* Prepare to call scheduler. */ \
+	jarl	call_scheduler, lp;	/* Call scheduler */		      \
+	di;				/* The scheduler enables interrupts */\
+	RESTORE_EXTRA_STATE_FOR_SCHEDULE(type);				      \
+	br	5b;			/* Continue with return path. */      \
+									      \
+/* Handle a signal or ptraced process return.				      \
+   r18 should be non-zero if there are pending signals.  */		      \
+4:	/* Not all registers are saved by the normal trap/interrupt entry     \
+	   points (for instance, call-saved registers (because the normal     \
+	   C-compiler calling sequence in the kernel makes sure they're	      \
+	   preserved), and call-clobbered registers in the case of	      \
+	   traps), but signal handlers may want to examine or change the      \
+	   complete register state.  Here we save anything not saved by	      \
+	   the normal entry sequence, so that it may be safely restored	      \
+	   (in a possibly modified form) after do_signal returns.  */	      \
+	SAVE_EXTRA_STATE(type);		/* Save state not saved by entry. */  \
+	jarl	handle_signal_or_ptrace_return, lp;			      \
+	RESTORE_EXTRA_STATE(type);	/* Restore extra regs.  */	      \
+	br	1b
+
+
+/* Jump to the appropriate function for the system call number in r12
+   (r12 is not preserved), or return an error if r12 is not valid.  The
+   LP register should point to the location where the called function
+   should return.  [note that MAKE_SYS_CALL uses label 1]  */
+#define MAKE_SYS_CALL							      \
+	/* Figure out which function to use for this system call.  */	      \
+	shl	2, r12;							      \
+	/* See if the system call number is valid.  */			      \
+	addi	lo(CSYM(sys_call_table) - sys_call_table_end), r12, r0;	      \
+	bnh	1f;							      \
+	mov	hilo(CSYM(sys_call_table)), r19;			      \
+	add	r19, r12;						      \
+	ld.w	0[r12], r12;						      \
+	/* Make the system call.  */					      \
+	jmp	[r12];							      \
+	/* The syscall number is invalid, return an error.  */		      \
+1:	addi	-ENOSYS, r0, r10;					      \
+	jmp	[lp]
+
+
+	.text
+
+/*
+ * User trap.
+ *
+ * Trap 0 system calls are also handled here.
+ *
+ * The stack-pointer (r3) should have already been saved to the memory
+ * location ENTRY_SP (the reason for this is that the interrupt vectors may be
+ * beyond a 22-bit signed offset jump from the actual interrupt handler, and
+ * this allows them to save the stack-pointer and use that register to do an
+ * indirect jump).
+ *
+ * Syscall protocol:
+ *   Syscall number in r12, args in r6-r9
+ *   Return value in r10
+ */
+G_ENTRY(trap):
+	SAVE_STATE (TRAP, r12, ENTRY_SP) // Save registers.
+	stsr	SR_ECR, r19		// Find out which trap it was.
+	ei				// Enable interrupts.
+	mov	hilo(ret_from_trap), lp	// where the trap should return
+
+	// The following two shifts (1) clear out extraneous NMI data in the
+	// upper 16-bits, (2) convert the 0x40 - 0x5f range of trap ECR
+	// numbers into the (0-31) << 2 range we want, (3) set the flags.
+	shl	27, r19			// chop off all high bits
+	shr	25, r19			// scale back down and then << 2
+	bnz	2f			// See if not trap 0.
+
+	// Trap 0 is a `short' system call, skip general trap table.
+	MAKE_SYS_CALL			// Jump to the syscall function.
+
+2:	// For other traps, use a table lookup.
+	mov	hilo(CSYM(trap_table)), r18
+	add	r19, r18
+	ld.w	0[r18], r18
+	jmp	[r18]			// Jump to the trap handler.
+END(trap)
+
+/* This is just like ret_from_trap, but first restores extra registers
+   saved by some wrappers.  */
+L_ENTRY(restore_extra_regs_and_ret_from_trap):
+	RESTORE_EXTRA_STATE(TRAP)
+	// fall through
+END(restore_extra_regs_and_ret_from_trap)
+
+/* Entry point used to return from a syscall/trap.  */
+L_ENTRY(ret_from_trap):
+	RETURN(TRAP)
+END(ret_from_trap)
+
+
+/* This the initial entry point for a new child thread, with an appropriate
+   stack in place that makes it look the the child is in the middle of an
+   syscall.  This function is actually `returned to' from switch_thread
+   (copy_thread makes ret_from_fork the return address in each new thread's
+   saved context).  */
+C_ENTRY(ret_from_fork):
+	mov	r10, r6			// switch_thread returns the prev task.
+	jarl	CSYM(schedule_tail), lp	// ...which is schedule_tail's arg
+	mov	r0, r10			// Child's fork call should return 0.
+	br	ret_from_trap		// Do normal trap return.
+C_END(ret_from_fork)
+
+
+/*
+ * Trap 1: `long' system calls
+ * `Long' syscall protocol:
+ *   Syscall number in r12, args in r6-r9, r13-r14
+ *   Return value in r10
+ */
+L_ENTRY(syscall_long):
+	// Push extra arguments on the stack.  Note that by default, the trap
+	// handler reserves enough stack space for 6 arguments, so we don't
+	// have to make any additional room.
+	st.w	r13, 16[sp]		// arg 5
+	st.w	r14, 20[sp]		// arg 6
+
+	// Make sure r13 and r14 are preserved, in case we have to restart a
+	// system call because of a signal (ep has already been set by caller).
+	st.w	r13, PTO+PT_GPR(13)[sp]
+	st.w	r14, PTO+PT_GPR(13)[sp]
+	mov	hilo(ret_from_long_syscall), lp
+
+	MAKE_SYS_CALL			// Jump to the syscall function.
+END(syscall_long)
+
+/* Entry point used to return from a long syscall.  Only needed to restore
+   r13/r14 if the general trap mechanism doesnt' do so.  */
+L_ENTRY(ret_from_long_syscall):
+	ld.w	PTO+PT_GPR(13)[sp], r13 // Restore the extra registers
+	ld.w	PTO+PT_GPR(13)[sp], r14
+	br	ret_from_trap		// The rest is the same as other traps
+END(ret_from_long_syscall)
+
+
+/* These syscalls need access to the struct pt_regs on the stack, so we
+   implement them in assembly (they're basically all wrappers anyway).  */
+
+L_ENTRY(sys_fork_wrapper):
+#ifdef CONFIG_MMU
+	addi	SIGCHLD, r0, r6		// Arg 0: flags
+	ld.w	PTO+PT_GPR(GPR_SP)[sp], r7 // Arg 1: child SP (use parent's)
+	movea	PTO, sp, r8		// Arg 2: parent context
+	mov	r0, r9			// Arg 3: (unused)
+	mov	hilo(CSYM(do_fork)), r18// Where the real work gets done
+	br	save_extra_state_tramp	// Save state and go there
+#else
+	// fork almost works, enough to trick you into looking elsewhere :-(
+	addi	-EINVAL, r0, r10
+	jmp	[lp]
+#endif
+END(sys_fork_wrapper)
+
+L_ENTRY(sys_vfork_wrapper):
+	addi	CLONE_VFORK | CLONE_VM | SIGCHLD, r0, r6 // Arg 0: flags
+	ld.w	PTO+PT_GPR(GPR_SP)[sp], r7 // Arg 1: child SP (use parent's)
+	movea	PTO, sp, r8		// Arg 2: parent context
+	mov	r0, r9			// Arg 3: (unused)
+	mov	hilo(CSYM(do_fork)), r18// Where the real work gets done
+	br	save_extra_state_tramp	// Save state and go there
+END(sys_vfork_wrapper)
+
+L_ENTRY(sys_clone_wrapper):
+	ld.w	PTO+PT_GPR(GPR_SP)[sp], r19 // parent's stack pointer
+	cmp	r7, r0			// See if child SP arg (arg 1) is 0.
+	cmov	z, r19, r7, r7		// ... and use the parent's if so.
+	movea	PTO, sp, r8		// Arg 2: parent context
+	mov	r0, r9			// Arg 3: (unused)
+	mov	hilo(CSYM(do_fork)), r18// Where the real work gets done
+	br	save_extra_state_tramp	// Save state and do it (tail-call)
+END(sys_clone_wrapper)
+
+
+L_ENTRY(sys_execve_wrapper):
+	movea	PTO, sp, r9		// add user context as 4th arg
+	jr	CSYM(sys_execve)	// Do real work (tail-call).
+END(sys_execve_wrapper)
+
+
+L_ENTRY(sys_sigsuspend_wrapper):
+	movea	PTO, sp, r7		// add user context as 2nd arg
+	mov	hilo(CSYM(sys_sigsuspend)), r18	// syscall function
+	jarl	save_extra_state_tramp, lp	// Save state and do it
+	br	restore_extra_regs_and_ret_from_trap
+END(sys_sigsuspend_wrapper)
+L_ENTRY(sys_rt_sigsuspend_wrapper):
+	movea	PTO, sp, r8		// add user context as 3rd arg
+	mov	hilo(CSYM(sys_rt_sigsuspend)), r18 // syscall function
+	jarl	save_extra_state_tramp, lp	   // Save state and do it
+	br	restore_extra_regs_and_ret_from_trap
+END(sys_rt_sigsuspend_wrapper)
+
+L_ENTRY(sys_sigreturn_wrapper):
+	movea	PTO, sp, r6		// add user context as 1st arg
+	mov	hilo(CSYM(sys_sigreturn)), r18	// syscall function
+	jarl	save_extra_state_tramp, lp	// Save state and do it
+	br	restore_extra_regs_and_ret_from_trap
+END(sys_sigreturn_wrapper)
+L_ENTRY(sys_rt_sigreturn_wrapper):
+	movea	PTO, sp, r6		// add user context as 1st arg
+	mov	hilo(CSYM(sys_rt_sigreturn)), r18// syscall function
+	jarl	save_extra_state_tramp, lp	 // Save state and do it
+	br	restore_extra_regs_and_ret_from_trap
+END(sys_rt_sigreturn_wrapper)
+
+
+/* Save any state not saved by SAVE_STATE(TRAP), and jump to r18.
+   It's main purpose is to share the rather lengthy code sequence that
+   SAVE_STATE expands into among the above wrapper functions.  */
+L_ENTRY(save_extra_state_tramp):
+	SAVE_EXTRA_STATE(TRAP)		// Save state not saved by entry.
+	jmp	[r18]			// Do the work the caller wants
+END(save_extra_state_tramp)
+
+
+/*
+ * Hardware maskable interrupts.
+ *
+ * The stack-pointer (r3) should have already been saved to the memory
+ * location ENTRY_SP (the reason for this is that the interrupt vectors may be
+ * beyond a 22-bit signed offset jump from the actual interrupt handler, and
+ * this allows them to save the stack-pointer and use that register to do an
+ * indirect jump).
+ */
+G_ENTRY(irq):
+	SAVE_STATE (IRQ, r0, ENTRY_SP)	// Save registers.
+
+	stsr	SR_ECR, r6		// Find out which interrupt it was.
+	movea	PTO, sp, r7		// User regs are arg2
+
+	// All v850 implementations I know about encode their interrupts as
+	// multiples of 0x10, starting at 0x80 (after NMIs and software
+	// interrupts).  Convert this number into a simple IRQ index for the
+	// rest of the kernel.  We also clear the upper 16 bits, which hold
+	// NMI info, and don't appear to be cleared when a NMI returns.
+	shl	16, r6			// clear upper 16 bits
+	shr	20, r6			// shift back, and remove lower nibble
+	add	-8, r6			// remove bias for irqs
+
+	// Call the high-level interrupt handling code.
+	jarl	CSYM(handle_irq), lp
+
+	RETURN(IRQ)
+END(irq)
+
+
+/*
+ * Debug trap / illegal-instruction exception
+ *
+ * The stack-pointer (r3) should have already been saved to the memory
+ * location ENTRY_SP (the reason for this is that the interrupt vectors may be
+ * beyond a 22-bit signed offset jump from the actual interrupt handler, and
+ * this allows them to save the stack-pointer and use that register to do an
+ * indirect jump).
+ */
+G_ENTRY(dbtrap):
+	SAVE_STATE (DBTRAP, r0, ENTRY_SP)// Save registers.
+
+	/* First see if we came from kernel mode; if so, the dbtrap
+	   instruction has a special meaning, to set the DIR (`debug
+	   information register') register.  This is because the DIR register
+	   can _only_ be manipulated/read while in `debug mode,' and debug
+	   mode is only active while we're inside the dbtrap handler.  The
+	   exact functionality is:  { DIR = (DIR | r6) & ~r7; return DIR; }. */
+	ld.b	PTO+PT_KERNEL_MODE[sp], r19
+	cmp	r19, r0
+	bz	1f
+
+	stsr	SR_DIR, r10
+	or	r6, r10
+	not	r7, r7
+	and	r7, r10
+	ldsr	r10, SR_DIR
+	stsr	SR_DIR, r10		// Confirm the value we set
+	st.w	r10, PTO+PT_GPR(10)[sp]	// return it
+	br	3f
+
+1:	ei				// Enable interrupts.
+
+	/* The default signal type we raise.  */
+	mov	SIGTRAP, r6
+
+	/* See if it's a single-step trap.  */
+	stsr	SR_DBPSW, r19
+	andi	0x0800, r19, r19
+	bnz	2f
+
+	/* Look to see if the preceding instruction was is a dbtrap or not,
+	   to decide which signal we should use.  */
+	stsr	SR_DBPC, r19		// PC following trapping insn
+	ld.hu	-2[r19], r19
+	ori	0xf840, r0, r20		// DBTRAP insn
+	cmp	r19, r20		// Was this trap caused by DBTRAP?
+	cmov	ne, SIGILL, r6, r6	// Choose signal appropriately
+
+	/* Raise the desired signal.  */
+2:	mov	CURRENT_TASK, r7	// Arg 1: task
+	jarl	CSYM(send_sig), lp	// tail call
+
+3:	RETURN(DBTRAP)
+END(dbtrap)
+
+
+/*
+ * Hardware non-maskable interrupts.
+ *
+ * The stack-pointer (r3) should have already been saved to the memory
+ * location ENTRY_SP (the reason for this is that the interrupt vectors may be
+ * beyond a 22-bit signed offset jump from the actual interrupt handler, and
+ * this allows them to save the stack-pointer and use that register to do an
+ * indirect jump).
+ */
+G_ENTRY(nmi):
+	SAVE_STATE (NMI, r0, NMI_ENTRY_SP); /* Save registers.  */
+
+	stsr	SR_ECR, r6;		/* Find out which nmi it was.  */
+	shr	20, r6;			/* Extract NMI code in bits 20-24. */
+	movea	PTO, sp, r7;		/* User regs are arg2.  */
+
+	/* Non-maskable interrupts always lie right after maskable interrupts.
+	   Call the generic IRQ handler, with two arguments, the IRQ number,
+	   and a pointer to the user registers, to handle the specifics.
+	   (we subtract one because the first NMI has code 1).  */
+	addi	FIRST_NMI - 1, r6, r6
+	jarl	CSYM(handle_irq), lp
+
+	RETURN(NMI)
+END(nmi)
+
+
+/*
+ * Trap with no handler
+ */
+L_ENTRY(bad_trap_wrapper):
+	mov	r19, r6			// Arg 0: trap number
+	movea	PTO, sp, r7		// Arg 1: user regs
+	jr	CSYM(bad_trap)		// tail call handler
+END(bad_trap_wrapper)
+
+
+/*
+ * Invoke the scheduler, called from the trap/irq kernel exit path.
+ *
+ * This basically just calls `schedule', but also arranges for extra
+ * registers to be saved for ptrace'd processes, so ptrace can modify them.
+ */
+L_ENTRY(call_scheduler):
+	ld.w	TASK_PTRACE[CURRENT_TASK], r19	// See if task is ptrace'd
+	cmp	r19, r0
+	bnz	1f			// ... yes, do special stuff
+	jr	CSYM(schedule)		// ... no, just tail-call scheduler
+
+	// Save extra regs for ptrace'd task.  We want to save anything
+	// that would otherwise only be `implicitly' saved by the normal
+	// compiler calling-convention.
+1:	mov	sp, ep			// Setup EP for SAVE_CALL_SAVED_REGS
+	SAVE_CALL_SAVED_REGS		// Save call-saved registers to stack
+	mov	lp, r20			// Save LP in a callee-saved register
+
+	jarl	CSYM(schedule), lp	// Call scheduler
+
+	mov	r20, lp
+	mov	sp, ep			// We can't rely on EP after return
+	RESTORE_CALL_SAVED_REGS		// Restore (possibly modified) regs
+	jmp	[lp]			// Return to the return path
+END(call_scheduler)
+
+
+/*
+ * This is an out-of-line handler for two special cases during the kernel
+ * trap/irq exit sequence:
+ *
+ *  (1) If r18 is non-zero then a signal needs to be handled, which is
+ *	done, and then the caller returned to.
+ *
+ *  (2) If r18 is non-zero then we're returning to a ptraced process, which
+ *	has several special cases -- single-stepping and trap tracing, both
+ *	of which require using the `dbret' instruction to exit the kernel
+ *	instead of the normal `reti' (this is because the CPU not correctly
+ *	single-step after a reti).  In this case, of course, this handler
+ *	never returns to the caller.
+ *
+ * In either case, all registers should have been saved to the current
+ * state-save-frame on the stack, except for callee-saved registers.
+ *
+ * [These two different cases are combined merely to avoid bloating the
+ * macro-inlined code, not because they really make much sense together!]
+ */
+L_ENTRY(handle_signal_or_ptrace_return):
+	cmp	r18, r0			// See if handling a signal
+	bz	1f			// ... nope, go do ptrace return
+
+	// Handle a signal
+	mov	lp, r20			// Save link-pointer
+	mov	r10, r21		// Save return-values (for trap)
+	mov	r11, r22
+
+	movea	PTO, sp, r6		// Arg 1: struct pt_regs *regs
+	mov	r0, r7			// Arg 2: sigset_t *oldset
+	jarl	CSYM(do_signal), lp	// Handle the signal
+	di				// sig handling enables interrupts
+
+	mov	r20, lp			// Restore link-pointer
+	mov	r21, r10		// Restore return-values (for trap)
+	mov	r22, r11
+	ld.w	TASK_PTRACE[CURRENT_TASK], r19  // check ptrace flags too
+	cmp	r19, r0
+	bnz	1f			// ... some set, so look more
+2:	jmp	[lp]			// ... none set, so return normally
+
+	// ptrace return
+1:	ld.w	PTO+PT_PSW[sp], r19	// Look at user-processes's flags
+	andi	0x0800, r19, r19	// See if single-step flag is set
+	bz	2b			// ... nope, return normally
+
+	// Return as if from a dbtrap insn
+	st.b	r0, KM			// Now officially in user state.
+	POP_STATE(DBTRAP)		// Restore regs
+	st.w	sp, KSP			// Save the kernel stack pointer.
+	ld.w	PT_GPR(GPR_SP)-PT_SIZE[sp], sp // Restore user stack pointer.
+	DBTRAP_RET			// Return from the trap/interrupt.
+END(handle_signal_or_ptrace_return)
+
+
+/*
+ * This is where we switch between two threads.  The arguments are:
+ *   r6 -- pointer to the struct thread for the `current' process
+ *   r7 -- pointer to the struct thread for the `new' process.
+ * when this function returns, it will return to the new thread.
+ */
+C_ENTRY(switch_thread):
+	// Return the previous task (r10 is not clobbered by restore below)
+	mov	CURRENT_TASK, r10
+	// First, push the current processor state on the stack
+	PUSH_STATE(SWITCH)
+	// Now save the location of the kernel stack pointer for this thread;
+	// since we've pushed all other state on the stack, this is enough to
+	// restore it all later.
+	st.w	sp, THREAD_KSP[r6]
+	// Now restore the stack pointer from the new process
+	ld.w	THREAD_KSP[r7], sp
+	// ... and restore all state from that
+	POP_STATE(SWITCH)
+	// Update the current task pointer
+	GET_CURRENT_TASK(CURRENT_TASK)
+	// Now return into the new thread
+	jmp	[lp]
+C_END(switch_thread)
+
+
+	.data
+
+	.align 4
+C_DATA(trap_table):
+	.long bad_trap_wrapper		// trap 0, doesn't use trap table.
+	.long syscall_long		// trap 1, `long' syscall.
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+	.long bad_trap_wrapper
+C_END(trap_table)
+
+
+	.section .rodata
+
+	.align 4
+C_DATA(sys_call_table):
+	.long CSYM(sys_ni_syscall)	// 0  -	 old "setup()" system call
+	.long CSYM(sys_exit)
+	.long sys_fork_wrapper
+	.long CSYM(sys_read)
+	.long CSYM(sys_write)
+	.long CSYM(sys_open)		// 5
+	.long CSYM(sys_close)
+	.long CSYM(sys_waitpid)
+	.long CSYM(sys_creat)
+	.long CSYM(sys_link)
+	.long CSYM(sys_unlink)		// 10
+	.long sys_execve_wrapper
+	.long CSYM(sys_chdir)
+	.long CSYM(sys_time)
+	.long CSYM(sys_mknod)
+	.long CSYM(sys_chmod)		// 15
+	.long CSYM(sys_chown)
+	.long CSYM(sys_ni_syscall)	// was: break
+	.long CSYM(sys_ni_syscall)	// was: oldstat (aka stat)
+	.long CSYM(sys_lseek)
+	.long CSYM(sys_getpid)		// 20
+	.long CSYM(sys_mount)
+	.long CSYM(sys_oldumount)
+	.long CSYM(sys_setuid)
+	.long CSYM(sys_getuid)
+	.long CSYM(sys_stime)		// 25
+	.long CSYM(sys_ptrace)
+	.long CSYM(sys_alarm)
+	.long CSYM(sys_ni_syscall)	// was: oldfstat (aka fstat)
+	.long CSYM(sys_pause)
+	.long CSYM(sys_utime)		// 30
+	.long CSYM(sys_ni_syscall)	// was: stty
+	.long CSYM(sys_ni_syscall)	// was: gtty
+	.long CSYM(sys_access)
+	.long CSYM(sys_nice)
+	.long CSYM(sys_ni_syscall)	// 35, was: ftime
+	.long CSYM(sys_sync)
+	.long CSYM(sys_kill)
+	.long CSYM(sys_rename)
+	.long CSYM(sys_mkdir)
+	.long CSYM(sys_rmdir)		// 40
+	.long CSYM(sys_dup)
+	.long CSYM(sys_pipe)
+	.long CSYM(sys_times)
+	.long CSYM(sys_ni_syscall)	// was: prof
+	.long CSYM(sys_brk)		// 45
+	.long CSYM(sys_setgid)
+	.long CSYM(sys_getgid)
+	.long CSYM(sys_signal)
+	.long CSYM(sys_geteuid)
+	.long CSYM(sys_getegid)		// 50
+	.long CSYM(sys_acct)
+	.long CSYM(sys_umount)		// recycled never used phys()
+	.long CSYM(sys_ni_syscall)	// was: lock
+	.long CSYM(sys_ioctl)
+	.long CSYM(sys_fcntl)		// 55
+	.long CSYM(sys_ni_syscall)	// was: mpx
+	.long CSYM(sys_setpgid)
+	.long CSYM(sys_ni_syscall)	// was: ulimit
+	.long CSYM(sys_ni_syscall)
+	.long CSYM(sys_umask)		// 60
+	.long CSYM(sys_chroot)
+	.long CSYM(sys_ustat)
+	.long CSYM(sys_dup2)
+	.long CSYM(sys_getppid)
+	.long CSYM(sys_getpgrp)		// 65
+	.long CSYM(sys_setsid)
+	.long CSYM(sys_sigaction)
+	.long CSYM(sys_sgetmask)
+	.long CSYM(sys_ssetmask)
+	.long CSYM(sys_setreuid)	// 70
+	.long CSYM(sys_setregid)
+	.long sys_sigsuspend_wrapper
+	.long CSYM(sys_sigpending)
+	.long CSYM(sys_sethostname)
+	.long CSYM(sys_setrlimit)	// 75
+	.long CSYM(sys_getrlimit)
+	.long CSYM(sys_getrusage)
+	.long CSYM(sys_gettimeofday)
+	.long CSYM(sys_settimeofday)
+	.long CSYM(sys_getgroups)	// 80
+	.long CSYM(sys_setgroups)
+	.long CSYM(sys_select)
+	.long CSYM(sys_symlink)
+	.long CSYM(sys_ni_syscall)	// was: oldlstat (aka lstat)
+	.long CSYM(sys_readlink)	// 85
+	.long CSYM(sys_uselib)
+	.long CSYM(sys_swapon)
+	.long CSYM(sys_reboot)
+	.long CSYM(old_readdir)
+	.long CSYM(sys_mmap)		// 90
+	.long CSYM(sys_munmap)
+	.long CSYM(sys_truncate)
+	.long CSYM(sys_ftruncate)
+	.long CSYM(sys_fchmod)
+	.long CSYM(sys_fchown)		// 95
+	.long CSYM(sys_getpriority)
+	.long CSYM(sys_setpriority)
+	.long CSYM(sys_ni_syscall)	// was: profil
+	.long CSYM(sys_statfs)
+	.long CSYM(sys_fstatfs)		// 100
+	.long CSYM(sys_ni_syscall)	// i386: ioperm
+	.long CSYM(sys_socketcall)
+	.long CSYM(sys_syslog)
+	.long CSYM(sys_setitimer)
+	.long CSYM(sys_getitimer)	// 105
+	.long CSYM(sys_newstat)
+	.long CSYM(sys_newlstat)
+	.long CSYM(sys_newfstat)
+	.long CSYM(sys_ni_syscall)	// was: olduname (aka uname)
+	.long CSYM(sys_ni_syscall)	// 110, i386: iopl
+	.long CSYM(sys_vhangup)
+	.long CSYM(sys_ni_syscall)	// was: idle
+	.long CSYM(sys_ni_syscall)	// i386: vm86old
+	.long CSYM(sys_wait4)
+	.long CSYM(sys_swapoff)		// 115
+	.long CSYM(sys_sysinfo)
+	.long CSYM(sys_ipc)
+	.long CSYM(sys_fsync)
+	.long sys_sigreturn_wrapper
+	.long sys_clone_wrapper		// 120
+	.long CSYM(sys_setdomainname)
+	.long CSYM(sys_newuname)
+	.long CSYM(sys_ni_syscall)	// i386: modify_ldt, m68k: cacheflush
+	.long CSYM(sys_adjtimex)
+	.long CSYM(sys_ni_syscall)	// 125 - sys_mprotect
+	.long CSYM(sys_sigprocmask)
+	.long CSYM(sys_create_module)
+	.long CSYM(sys_init_module)
+	.long CSYM(sys_delete_module)
+	.long CSYM(sys_get_kernel_syms) // 130
+	.long CSYM(sys_quotactl)
+	.long CSYM(sys_getpgid)
+	.long CSYM(sys_fchdir)
+	.long CSYM(sys_bdflush)
+	.long CSYM(sys_sysfs)		// 135
+	.long CSYM(sys_personality)
+	.long CSYM(sys_ni_syscall)	// for afs_syscall
+	.long CSYM(sys_setfsuid)
+	.long CSYM(sys_setfsgid)
+	.long CSYM(sys_llseek)		// 140
+	.long CSYM(sys_getdents)
+	.long CSYM(sys_select)		// for backward compat; remove someday
+	.long CSYM(sys_flock)
+	.long CSYM(sys_ni_syscall)	// sys_msync
+	.long CSYM(sys_readv)		// 145
+	.long CSYM(sys_writev)
+	.long CSYM(sys_getsid)
+	.long CSYM(sys_fdatasync)
+	.long CSYM(sys_sysctl)
+	.long CSYM(sys_ni_syscall)	// 150 - sys_mlock
+	.long CSYM(sys_ni_syscall)	// sys_munlock
+	.long CSYM(sys_ni_syscall)	// sys_mlockall
+	.long CSYM(sys_ni_syscall)	// sys_munlockall
+	.long CSYM(sys_sched_setparam)
+	.long CSYM(sys_sched_getparam)	// 155
+	.long CSYM(sys_sched_setscheduler)
+	.long CSYM(sys_sched_getscheduler)
+	.long CSYM(sys_sched_yield)
+	.long CSYM(sys_sched_get_priority_max)
+	.long CSYM(sys_sched_get_priority_min)	// 160
+	.long CSYM(sys_sched_rr_get_interval)
+	.long CSYM(sys_nanosleep)
+	.long CSYM(sys_ni_syscall)	// sys_mremap
+	.long CSYM(sys_setresuid)
+	.long CSYM(sys_getresuid)	// 165
+	.long CSYM(sys_ni_syscall)	// for vm86
+	.long CSYM(sys_query_module)
+	.long CSYM(sys_poll)
+	.long CSYM(sys_nfsservctl)
+	.long CSYM(sys_setresgid)	// 170
+	.long CSYM(sys_getresgid)
+	.long CSYM(sys_prctl)
+	.long sys_rt_sigreturn_wrapper
+	.long CSYM(sys_rt_sigaction)
+	.long CSYM(sys_rt_sigprocmask)	// 175
+	.long CSYM(sys_rt_sigpending)
+	.long CSYM(sys_rt_sigtimedwait)
+	.long CSYM(sys_rt_sigqueueinfo)
+	.long sys_rt_sigsuspend_wrapper
+	.long CSYM(sys_pread)		// 180
+	.long CSYM(sys_pwrite)
+	.long CSYM(sys_lchown)
+	.long CSYM(sys_getcwd)
+	.long CSYM(sys_capget)
+	.long CSYM(sys_capset)		// 185
+	.long CSYM(sys_sigaltstack)
+	.long CSYM(sys_sendfile)
+	.long CSYM(sys_ni_syscall)	// streams1
+	.long CSYM(sys_ni_syscall)	// streams2
+	.long sys_vfork_wrapper		// 190
+	.long CSYM(sys_ni_syscall)
+	.long CSYM(sys_mmap2)
+	.long CSYM(sys_truncate64)
+	.long CSYM(sys_ftruncate64)
+	.long CSYM(sys_stat64)		// 195
+	.long CSYM(sys_lstat64)
+	.long CSYM(sys_fstat64)
+	.long CSYM(sys_fcntl64)
+	.long CSYM(sys_getdents64)
+	.long CSYM(sys_pivot_root)	// 200
+	.long CSYM(sys_gettid)
+	.long CSYM(sys_tkill)
+sys_call_table_end:
+C_END(sys_call_table)
diff -urN linux-2.4.29/arch/v850/kernel/fpga85e2c.c linux-2.4.29-uc1/arch/v850/kernel/fpga85e2c.c
--- linux-2.4.29/arch/v850/kernel/fpga85e2c.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/fpga85e2c.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,165 @@
+/*
+ * arch/v850/kernel/fpga85e2c.h -- Machine-dependent defs for
+ *	FPGA implementation of V850E2/NA85E2C
+ *
+ *  Copyright (C) 2002,03  NEC Electronics Corporation
+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+#include <asm/bitops.h>
+
+#include "mach.h"
+
+extern void memcons_setup (void);
+
+
+#define REG_DUMP_ADDR		0x220000
+
+
+extern struct irqaction reg_snap_action; /* fwd decl */
+
+
+void __init mach_early_init (void)
+{
+	int i;
+	const u32 *src;
+	register u32 *dst asm ("ep");
+	extern int panic_timeout;
+	extern u32 _intv_end, _intv_load_start;
+
+	/* Set bus sizes: CS0 32-bit, CS1 16-bit, CS7 8-bit,
+	   everything else 32-bit.  */
+	V850E2_BSC = 0x2AA6;
+	for (i = 2; i <= 6; i++)
+		CSDEV(i) = 0;	/* 32 bit */
+
+	/* Ensure that the simulator halts on a panic, instead of going
+	   into an infinite loop inside the panic function.  */
+	panic_timeout = -1;
+
+	/* Move the interrupt vectors into their real location.  Note that
+	   any relocations there are relative to the real location, so we
+	   don't have to fix anything up.  We use a loop instead of calling
+	   memcpy to keep this a leaf function (to avoid a function
+	   prologue being generated).  */
+	dst = 0x10;		/* &_intv_start + 0x10.  */
+	src = &_intv_load_start;
+	do {
+		u32 t0 = src[0], t1 = src[1], t2 = src[2], t3 = src[3];
+		u32 t4 = src[4], t5 = src[5], t6 = src[6], t7 = src[7];
+		dst[0] = t0; dst[1] = t1; dst[2] = t2; dst[3] = t3;
+		dst[4] = t4; dst[5] = t5; dst[6] = t6; dst[7] = t7;
+		dst += 8;
+		src += 8;
+	} while (dst < &_intv_end);
+}
+
+void __init mach_setup (char **cmdline)
+{
+	memcons_setup ();
+
+	/* Setup up NMI0 to copy the registers to a known memory location.
+	   The FGPA board has a button that produces NMI0 when pressed, so
+	   this allows us to push the button, and then look at memory to see
+	   what's in the registers (there's no other way to easily do so).
+	   We have to use `setup_irq' instead of `request_irq' because it's
+	   still too early to do memory allocation.  */
+	setup_irq (IRQ_NMI (0), &reg_snap_action);
+}
+
+void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len)
+{
+	*ram_start = ERAM_ADDR;
+	*ram_len = ERAM_SIZE;
+}
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* Setup up the timer interrupt.  The FPGA peripheral control
+	   registers _only_ work with single-bit writes (set1/clr1)!  */
+	__clear_bit (RPU_GTMC_CE_BIT, &RPU_GTMC);
+	__clear_bit (RPU_GTMC_CLK_BIT, &RPU_GTMC);
+	__set_bit (RPU_GTMC_CE_BIT, &RPU_GTMC);
+
+	/* We use the first RPU interrupt, which occurs every 8.192ms.  */
+	setup_irq (IRQ_RPU (0), timer_action);
+}
+
+
+void mach_gettimeofday (struct timeval *tv)
+{
+	tv->tv_sec = 0;
+	tv->tv_usec = 0;
+}
+
+void machine_halt (void) __attribute__ ((noreturn));
+void machine_halt (void)
+{
+	for (;;) {
+		DWC(0) = 0x7777;
+		DWC(1) = 0x7777;
+		ASC = 0xffff;
+		FLGREG(0) = 1;	/* Halt immediately.  */
+		asm ("di; halt; nop; nop; nop; nop; nop");
+	}
+}
+
+void machine_restart (char *__unused)
+{
+	machine_halt ();
+}
+
+void machine_power_off (void)
+{
+	machine_halt ();
+}
+
+
+/* Interrupts */
+
+struct v850e_intc_irq_init irq_inits[] = {
+	{ "IRQ", 0, 		NUM_MACH_IRQS,	1, 7 },
+	{ "RPU", IRQ_RPU(0),	IRQ_RPU_NUM,	1, 6 },
+	{ 0 }
+};
+#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
+
+struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
+
+/* Initialize interrupts.  */
+void __init mach_init_irqs (void)
+{
+	v850e_intc_init_irq_types (irq_inits, hw_itypes);
+}
+
+
+/* An interrupt handler that copies the registers to a known memory location,
+   for debugging purposes.  */
+
+static void make_reg_snap (int irq, void *dummy, struct pt_regs *regs)
+{
+	(*(unsigned *)REG_DUMP_ADDR)++;
+	(*(struct pt_regs *)(REG_DUMP_ADDR + sizeof (unsigned))) = *regs;
+}
+
+static int reg_snap_dev_id;
+static struct irqaction reg_snap_action = {
+	make_reg_snap, 0, 0, "reg_snap", &reg_snap_dev_id, 0
+};
diff -urN linux-2.4.29/arch/v850/kernel/fpga85e2c.ld linux-2.4.29-uc1/arch/v850/kernel/fpga85e2c.ld
--- linux-2.4.29/arch/v850/kernel/fpga85e2c.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/fpga85e2c.ld	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,62 @@
+/* Linker script for the FPGA implementation of the V850E2 NA85E2C cpu core
+   (CONFIG_V850E2_FPGA85E2C).  */
+
+MEMORY {
+	/* Reset vector.  */
+	RESET	 : ORIGIN = 0, LENGTH = 0x10
+	/* Interrupt vectors.  */
+	INTV      : ORIGIN = 0x10, LENGTH = 0x470
+	/* The `window' in RAM were we're allowed to load stuff.  */
+	RAM_LOW   : ORIGIN = 0x480, LENGTH = 0x0005FB80
+	/* Some more ram above the window were we can put bss &c.  */
+	RAM_HIGH  : ORIGIN = 0x00060000, LENGTH = 0x000A0000
+	/* This is the area visible from the outside world (we can use
+	   this only for uninitialized data).  */
+	VISIBLE   : ORIGIN = 0x00200000, LENGTH = 0x00060000
+}
+
+SECTIONS {
+	.reset : {
+		__kram_start = . ;
+		__intv_start = . ;
+	        	*(.intv.reset)	/* Reset vector */
+	} > RESET
+
+	.ram_low : {
+		__r0_ram = . ;		/* Must be near address 0.  */
+		. = . + 32 ;
+
+		TEXT_CONTENTS
+		DATA_CONTENTS
+		ROOT_FS_CONTENTS
+		RAMK_INIT_CONTENTS_NO_END
+		INITRAMFS_CONTENTS
+	} > RAM_LOW
+
+        /* Where the interrupt vectors are initially loaded.  */
+	__intv_load_start = . ;
+
+	.intv : {
+			*(.intv.common)	/* Vectors common to all v850e proc. */
+			*(.intv.mach)	/* Machine-specific int. vectors.  */
+		__intv_end = . ;
+	} > INTV  AT> RAM_LOW
+
+	.ram_high : {
+		/* This is here so that when we free init memory the
+		   load-time copy of the interrupt vectors and any empty
+		   space at the end of the `RAM_LOW' area is freed too.  */
+		. = ALIGN (4096);
+		__init_end = . ;
+
+		BSS_CONTENTS
+		__kram_end = . ;
+		BOOTMAP_CONTENTS
+	} > RAM_HIGH
+
+	.visible : {
+		_memcons_output = . ;
+		. = . + 0x8000 ;
+		_memcons_output_end = . ;
+	} > VISIBLE
+}
diff -urN linux-2.4.29/arch/v850/kernel/gbus_int.c linux-2.4.29-uc1/arch/v850/kernel/gbus_int.c
--- linux-2.4.29/arch/v850/kernel/gbus_int.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/gbus_int.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,267 @@
+/*
+ * arch/v850/kernel/gbus_int.c -- Midas labs GBUS interrupt support
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/sched.h>	/* For some unfathomable reason,
+				   request_irq/free_irq are declared here.  */
+
+#include <asm/machdep.h>
+#include <asm/irq.h>
+
+
+/* The number of shared GINT interrupts. */
+#define NUM_GINTS   	4
+
+/* For each GINT interrupt, how many GBUS interrupts are using it.  */
+static unsigned gint_num_active_irqs[NUM_GINTS] = { 0 };
+
+/* A table of GINTn interrupts we actually use.
+   Note that we don't use GINT0 because all the boards we support treat it
+   specially.  */
+struct used_gint {
+	unsigned gint;
+	unsigned priority;
+} used_gint[] = {
+	{ 1, GBUS_INT_PRIORITY_HIGH },
+	{ 3, GBUS_INT_PRIORITY_LOW }
+};
+#define NUM_USED_GINTS	(sizeof used_gint / sizeof used_gint[0])
+
+/* A table of which GINT is used by each GBUS interrupts (they are
+   assigned based on priority).  */
+static unsigned char gbus_int_gint[IRQ_GBUS_INT_NUM];
+
+
+/* Interrupt enabling/disabling.  */
+
+/* Enable interrupt handling for interrupt IRQ.  */
+void gbus_int_enable_irq (unsigned irq)
+{
+	unsigned gint = gbus_int_gint[irq - GBUS_INT_BASE_IRQ];
+	GBUS_INT_ENABLE (GBUS_INT_IRQ_WORD(irq), gint)
+		|= GBUS_INT_IRQ_MASK (irq);
+}
+
+/* Disable interrupt handling for interrupt IRQ.  Note that any
+   interrupts received while disabled will be delivered once the
+   interrupt is enabled again, unless they are explicitly cleared using
+   `gbus_int_clear_pending_irq'.  */
+void gbus_int_disable_irq (unsigned irq)
+{
+	unsigned gint = gbus_int_gint[irq - GBUS_INT_BASE_IRQ];
+	GBUS_INT_ENABLE (GBUS_INT_IRQ_WORD(irq), gint)
+		&= ~GBUS_INT_IRQ_MASK (irq);
+}
+
+/* Return true if interrupt handling for interrupt IRQ is enabled.  */
+int gbus_int_irq_enabled (unsigned irq)
+{
+	unsigned gint = gbus_int_gint[irq - GBUS_INT_BASE_IRQ];
+	return (GBUS_INT_ENABLE (GBUS_INT_IRQ_WORD(irq), gint)
+		& GBUS_INT_IRQ_MASK(irq));
+}
+
+/* Disable all GBUS irqs.  */
+void gbus_int_disable_irqs ()
+{
+	unsigned w, n;
+	for (w = 0; w < GBUS_INT_NUM_WORDS; w++)
+		for (n = 0; n < IRQ_GINT_NUM; n++)
+			GBUS_INT_ENABLE (w, n) = 0;
+}
+
+/* Clear any pending interrupts for IRQ.  */
+void gbus_int_clear_pending_irq (unsigned irq)
+{
+	GBUS_INT_CLEAR (GBUS_INT_IRQ_WORD(irq)) = GBUS_INT_IRQ_MASK (irq);
+}
+
+/* Return true if interrupt IRQ is pending (but disabled).  */
+int gbus_int_irq_pending (unsigned irq)
+{
+	return (GBUS_INT_STATUS (GBUS_INT_IRQ_WORD(irq))
+		& GBUS_INT_IRQ_MASK(irq));
+}
+
+
+/* Delegating interrupts.  */
+
+/* Handle a shared GINT interrupt by passing to the appropriate GBUS
+   interrupt handler.  */
+static void gbus_int_handle_irq (int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned w;
+	unsigned gint = irq - IRQ_GINT (0);
+
+	for (w = 0; w < GBUS_INT_NUM_WORDS; w++) {
+		unsigned status = GBUS_INT_STATUS (w);
+		unsigned enable = GBUS_INT_ENABLE (w, gint);
+
+		/* Only pay attention to enabled interrupts.  */
+		status &= enable;
+		if (status) {
+			irq = IRQ_GBUS_INT (w * GBUS_INT_BITS_PER_WORD);
+			do {
+				/* There's an active interrupt in word
+				   W, find out which one, and call its
+				   handler.  */
+
+				while (! (status & 0x1)) {
+					irq++;
+					status >>= 1;
+				}
+				status &= ~0x1;
+
+				/* Recursively call handle_irq to handle it. */
+				handle_irq (irq, regs);
+			} while (status);
+		}
+	}
+
+	/* Toggle the `all enable' bit back and forth, which should cause
+	   another edge transition if there are any other interrupts
+	   still pending, and so result in another CPU interrupt.  */
+	GBUS_INT_ENABLE (0, gint) &= ~0x1;
+	GBUS_INT_ENABLE (0, gint) |=  0x1;
+}
+
+
+/* Initialize GBUS interrupt sources.  */
+
+static void irq_nop (unsigned irq) { }
+
+static unsigned gbus_int_startup_irq (unsigned irq)
+{
+	unsigned gint = gbus_int_gint[irq - GBUS_INT_BASE_IRQ];
+
+	if (gint_num_active_irqs[gint] == 0) {
+		/* First enable the CPU interrupt.  */
+		int rval =
+			request_irq (IRQ_GINT(gint), gbus_int_handle_irq,
+				     SA_INTERRUPT,
+				     "gbus_int_handler",
+				     &gint_num_active_irqs[gint]);
+		if (rval != 0)
+			return rval;
+	}
+
+	gint_num_active_irqs[gint]++;
+
+	gbus_int_clear_pending_irq (irq);
+	gbus_int_enable_irq (irq);
+
+	return 0;
+}
+
+static void gbus_int_shutdown_irq (unsigned irq)
+{
+	unsigned gint = gbus_int_gint[irq - GBUS_INT_BASE_IRQ];
+
+	gbus_int_disable_irq (irq);
+
+	if (--gint_num_active_irqs[gint] == 0)
+		/* Disable the CPU interrupt.  */
+		free_irq (IRQ_GINT(gint), &gint_num_active_irqs[gint]);
+}
+
+/* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
+   INITS (which is terminated by an entry with the name field == 0).  */
+void __init gbus_int_init_irq_types (struct gbus_int_irq_init *inits,
+				     struct hw_interrupt_type *hw_irq_types)
+{
+	struct gbus_int_irq_init *init;
+	for (init = inits; init->name; init++) {
+		unsigned i;
+		struct hw_interrupt_type *hwit = hw_irq_types++;
+
+		hwit->typename = init->name;
+
+		hwit->startup  = gbus_int_startup_irq;
+		hwit->shutdown = gbus_int_shutdown_irq;
+		hwit->enable   = gbus_int_enable_irq;
+		hwit->disable  = gbus_int_disable_irq;
+		hwit->ack      = irq_nop;
+		hwit->end      = irq_nop;
+		
+		/* Initialize kernel IRQ infrastructure for this interrupt.  */
+		init_irq_handlers(init->base, init->num, init->interval, hwit);
+
+		/* Set the interrupt priorities.  */
+		for (i = 0; i < init->num; i++) {
+			unsigned j;
+			for (j = 0; j < NUM_USED_GINTS; j++)
+				if (used_gint[j].priority > init->priority)
+					break;
+			/* Wherever we stopped looking is one past the
+			   GINT we want. */
+			gbus_int_gint[init->base + i * init->interval
+				      - GBUS_INT_BASE_IRQ]
+				= used_gint[j > 0 ? j - 1 : 0].gint;
+		}
+	}
+}
+
+
+/* Initialize IRQS.  */
+
+/* Chip interrupts (GINTn) shared among GBUS interrupts.  */
+static struct hw_interrupt_type gint_hw_itypes[NUM_USED_GINTS];
+
+
+/* GBUS interrupts themselves.  */
+
+struct gbus_int_irq_init gbus_irq_inits[] __initdata = {
+	/* First set defaults.  */
+	{ "GBUS_INT", IRQ_GBUS_INT(0), IRQ_GBUS_INT_NUM, 1, 6},
+	{ 0 }
+};
+#define NUM_GBUS_IRQ_INITS  \
+   ((sizeof gbus_irq_inits / sizeof gbus_irq_inits[0]) - 1)
+
+static struct hw_interrupt_type gbus_hw_itypes[NUM_GBUS_IRQ_INITS];
+
+
+/* Initialize GBUS interrupts.  */
+void __init gbus_int_init_irqs (void)
+{
+	unsigned i;
+
+	/* First initialize the shared gint interrupts.  */
+	for (i = 0; i < NUM_USED_GINTS; i++) {
+		unsigned gint = used_gint[i].gint;
+		struct v850e_intc_irq_init gint_irq_init[2];
+
+		/* We initialize one GINT interrupt at a time.  */
+		gint_irq_init[0].name = "GINT";
+		gint_irq_init[0].base = IRQ_GINT (gint);
+		gint_irq_init[0].num = 1;
+		gint_irq_init[0].interval = 1;
+		gint_irq_init[0].priority = used_gint[i].priority;
+
+		gint_irq_init[1].name = 0; /* Terminate the vector.  */
+
+		v850e_intc_init_irq_types (gint_irq_init, gint_hw_itypes);
+	}
+
+	/* Then the GBUS interrupts.  */
+	gbus_int_disable_irqs ();
+	gbus_int_init_irq_types (gbus_irq_inits, gbus_hw_itypes);
+	/* Turn on the `all enable' bits, which are ANDed with
+	   individual interrupt enable bits; we only want to bother with
+	   the latter.  They are the first bit in the first word of each
+	   interrupt-enable area.  */
+	for (i = 0; i < NUM_USED_GINTS; i++)
+		GBUS_INT_ENABLE (0, used_gint[i].gint) = 0x1;
+}
diff -urN linux-2.4.29/arch/v850/kernel/head.S linux-2.4.29-uc1/arch/v850/kernel/head.S
--- linux-2.4.29/arch/v850/kernel/head.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/head.S	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,126 @@
+/*
+ * arch/v850/kernel/head.S -- Lowest-level startup code
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <asm/clinkage.h>
+#include <asm/current.h>
+#include <asm/entry.h>
+#include <asm/irq.h>
+
+
+/* Make a slightly more convenient alias for C_SYMBOL_NAME.  */
+#define CSYM	C_SYMBOL_NAME
+
+
+	.text
+
+	// Define `mach_early_init' as a weak symbol
+	.global	CSYM(mach_early_init)
+	.weak	CSYM(mach_early_init)
+
+C_ENTRY(start):
+	// Make sure interrupts are turned off, just in case
+	di
+
+#ifdef CONFIG_RESET_GUARD
+	// See if we got here via an unexpected reset
+	ld.w	RESET_GUARD, r19	// Check current value of reset guard
+	mov	RESET_GUARD_ACTIVE, r20
+	cmp	r19, r20
+	bne	1f			// Guard was not active
+
+	// If we get here, the reset guard was active.  Load up some
+	// interesting values as arguments, and jump to the handler.
+	st.w	r0, RESET_GUARD		// Allow further resets to succeed
+	mov	lp, r6			// Arg 0: return address
+	ld.b	KM, r7			// Arg 1: kernel mode
+	mov	sp, r9			// Arg 3: stack pointer
+	ld.w	KSP, r19		// maybe switch to kernel stack
+	cmp	r7, r0			// see if already in kernel mode
+	cmov	z, r19, sp, sp		//  and switch to kernel stack if not
+	GET_CURRENT_TASK(r8)		// Arg 2: task pointer
+	jr	CSYM(unexpected_reset)
+
+1:	st.w	r20, RESET_GUARD	// Turn on reset guard
+#endif /* CONFIG_RESET_GUARD */
+
+	// Setup a temporary stack for doing pre-initialization function calls.
+	// 
+	// We can't use the initial kernel stack, because (1) it may be
+	// located in memory we're not allowed to touch, and (2) since
+	// it's in the data segment, calling memcpy to initialize that
+	// area from ROM will overwrite memcpy's return address.
+	mov	hilo(CSYM(_init_stack_end) - 4), sp
+
+	// See if there's a platform-specific early-initialization routine
+	// defined; it's a weak symbol, so it will have an address of zero if
+	// there's not.
+	mov	hilo(CSYM(mach_early_init)), r6
+	cmp	r6, r0
+	bz	3f
+
+	// There is one, so call it.  If this function is written in C, it
+	// should be very careful -- the stack pointer is valid, but very
+	// little else is (e.g., bss is not zeroed yet, and initialized data
+	// hasn't been).
+	jarl	2f, lp			// first figure out return address
+2:	add	3f - ., lp
+	jmp	[r6]			// do call
+3:
+
+#ifdef CONFIG_ROM_KERNEL
+	// Copy the data area from ROM to RAM
+	mov	hilo(CSYM(_rom_copy_dst_start)), r6
+	mov	hilo(CSYM(_rom_copy_src_start)), r7
+	mov	hilo(CSYM(_rom_copy_dst_end)), r8
+	sub	r6, r8
+	jarl	CSYM(memcpy), lp
+#endif
+
+	// Load the current task pointer (in r16) and initial kernel stack.
+	mov	hilo(CSYM(init_task_union)), CURRENT_TASK
+	movea	KERNEL_STACK_SIZE, CURRENT_TASK, sp
+
+#ifdef CONFIG_TIME_BOOTUP
+	/* This stuff must come after mach_early_init, because interrupts may
+	   not work until after its been called.  */
+	jarl	CSYM(highres_timer_reset), lp
+	jarl	CSYM(highres_timer_start), lp
+#endif
+
+	// Kernel stack pointer save location
+	st.w	sp, KSP
+
+	// Assert that we're in `kernel mode'
+	mov	1, r19
+	st.w	r19, KM
+
+#ifdef CONFIG_ZERO_BSS
+	// Zero bss area, since we can't rely upon any loader to do so
+	mov	hilo(CSYM(_sbss)), r6
+	mov	r0, r7
+	mov	hilo(CSYM(_ebss)), r8
+	sub	r6, r8
+	jarl	CSYM(memset), lp
+#endif
+
+	// What happens if the main kernel function returns (it shouldn't)
+	mov	hilo(CSYM(machine_halt)), lp
+
+	// Start the linux kernel.  We use an indirect jump to get extra
+	// range, because on some platforms this initial startup code
+	// (and the associated platform-specific code in mach_early_init)
+	// are located far away from the main kernel, e.g. so that they
+	// can initialize RAM first and copy the kernel or something.
+	mov	hilo(CSYM(start_kernel)), r12
+	jmp	[r12]
+C_END(start)
diff -urN linux-2.4.29/arch/v850/kernel/highres_timer.c linux-2.4.29-uc1/arch/v850/kernel/highres_timer.c
--- linux-2.4.29/arch/v850/kernel/highres_timer.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/highres_timer.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,132 @@
+/*
+ * arch/v850/kernel/highres_timer.c -- High resolution timing routines
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <asm/system.h>
+#include <asm/v850e_timer_d.h>
+#include <asm/highres_timer.h>
+
+#define HIGHRES_TIMER_USEC_SHIFT   12
+
+/* Pre-calculated constant used for converting ticks to real time
+   units.  We initialize it to prevent it being put into BSS.  */
+static u32 highres_timer_usec_prescale = 1;
+
+void highres_timer_slow_tick_irq (void) __attribute__ ((noreturn));
+void highres_timer_slow_tick_irq (void)
+{
+	/* This is an interrupt handler, so it must be very careful to
+	   not to trash any registers.  At this point, the stack-pointer
+	   (r3) has been saved in the chip ram location ENTRY_SP by the
+	   interrupt vector, so we can use it as a scratch register; we
+	   must also restore it before returning.  */
+	asm ("ld.w	%0[r0], sp;"
+	     "add	1, sp;"
+	     "st.w	sp, %0[r0];"
+	     "ld.w	%1[r0], sp;" /* restore pre-irq stack-pointer */
+	     "reti"
+	     ::
+	      "i" (HIGHRES_TIMER_SLOW_TICKS_ADDR),
+	      "i" (ENTRY_SP_ADDR)
+	     : "memory");
+}
+
+void highres_timer_reset (void)
+{
+	V850E_TIMER_D_TMD (HIGHRES_TIMER_TIMER_D_UNIT) = 0;
+	HIGHRES_TIMER_SLOW_TICKS = 0;
+}
+
+void highres_timer_start (void)
+{
+	u32 fast_tick_rate;
+
+	/* Start hardware timer.  */
+	v850e_timer_d_configure (HIGHRES_TIMER_TIMER_D_UNIT,
+				 HIGHRES_TIMER_SLOW_TICK_RATE);
+
+	fast_tick_rate =
+		(V850E_TIMER_D_BASE_FREQ
+		 >> V850E_TIMER_D_DIVLOG2 (HIGHRES_TIMER_TIMER_D_UNIT));
+
+	/* The obvious way of calculating microseconds from fast ticks
+	   is to do:
+
+	     usec = fast_ticks * 10^6 / fast_tick_rate
+
+	   However, divisions are much slower than multiplications, and
+	   the above calculation can overflow, so we do this instead:
+
+	     usec = fast_ticks * (10^6 * 2^12 / fast_tick_rate) / 2^12
+
+           since we can pre-calculate (10^6 * (2^12 / fast_tick_rate))
+	   and use a shift for dividing by 2^12, this avoids division,
+	   and is almost as accurate (it differs by about 2 microseconds
+	   at the extreme value of the fast-tick counter's ranger).  */
+	highres_timer_usec_prescale = ((1000000 << HIGHRES_TIMER_USEC_SHIFT)
+				       / fast_tick_rate);
+
+	/* Enable the interrupt (which is hardwired to this use), and
+	   give it the highest priority.  */
+	V850E_INTC_IC (IRQ_INTCMD (HIGHRES_TIMER_TIMER_D_UNIT)) = 0;
+}
+
+void highres_timer_stop (void)
+{
+	/* Stop the timer.  */
+	V850E_TIMER_D_TMCD (HIGHRES_TIMER_TIMER_D_UNIT) =
+		V850E_TIMER_D_TMCD_CAE;
+	/* Disable its interrupt, just in case.  */
+	v850e_intc_disable_irq (IRQ_INTCMD (HIGHRES_TIMER_TIMER_D_UNIT));
+}
+
+inline void highres_timer_read_ticks (u32 *slow_ticks, u32 *fast_ticks)
+{
+	int flags;
+	u32 fast_ticks_1, fast_ticks_2, _slow_ticks;
+
+	local_irq_save (flags);
+	fast_ticks_1 = V850E_TIMER_D_TMD (HIGHRES_TIMER_TIMER_D_UNIT);
+	_slow_ticks = HIGHRES_TIMER_SLOW_TICKS;
+	fast_ticks_2 = V850E_TIMER_D_TMD (HIGHRES_TIMER_TIMER_D_UNIT);
+	local_irq_restore (flags);
+
+	if (fast_ticks_2 < fast_ticks_1)
+		_slow_ticks++;
+
+	*slow_ticks = _slow_ticks;
+	*fast_ticks = fast_ticks_2;
+}
+
+inline void highres_timer_ticks_to_timeval (u32 slow_ticks, u32 fast_ticks,
+					    struct timeval *tv)
+{
+	unsigned long sec, sec_rem, usec;
+
+	usec = ((fast_ticks * highres_timer_usec_prescale)
+		>> HIGHRES_TIMER_USEC_SHIFT);
+
+	sec = slow_ticks / HIGHRES_TIMER_SLOW_TICK_RATE;
+	sec_rem = slow_ticks % HIGHRES_TIMER_SLOW_TICK_RATE;
+
+	usec += sec_rem * (1000000 / HIGHRES_TIMER_SLOW_TICK_RATE);
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+void highres_timer_read (struct timeval *tv)
+{
+	u32 fast_ticks, slow_ticks;
+	highres_timer_read_ticks (&slow_ticks, &fast_ticks);
+	highres_timer_ticks_to_timeval (slow_ticks, fast_ticks, tv);
+}
diff -urN linux-2.4.29/arch/v850/kernel/intv.S linux-2.4.29-uc1/arch/v850/kernel/intv.S
--- linux-2.4.29/arch/v850/kernel/intv.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/intv.S	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,87 @@
+/*
+ * arch/v850/kernel/intv.S -- Interrupt vectors
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <asm/clinkage.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/entry.h>
+
+#ifdef CONFIG_V850E_HIGHRES_TIMER
+#include <asm/highres_timer.h>
+#endif
+
+/* Jump to an interrupt/trap handler.  These handlers (defined in entry.S)
+   expect the stack-pointer to be saved in ENTRY_SP, so we use sp to do an
+   indirect jump (which avoids problems when the handler is more than a signed
+   22-bit offset away).  */
+#define JUMP_TO_HANDLER(name, sp_save_loc)				      \
+	st.w	sp, sp_save_loc;					      \
+	mov	hilo(name), sp;						      \
+	jmp	[sp]
+
+
+	/* Reset vector.  */
+	.section	.intv.reset, "ax"
+	.org	0x0
+	mov	hilo(C_SYMBOL_NAME(start)), r1;
+	jmp	[r1]
+
+
+	/* Generic interrupt vectors.  */
+	.section	.intv.common, "ax"
+	.balign	0x10
+	JUMP_TO_HANDLER (nmi, NMI_ENTRY_SP)	// 0x10 - NMI0
+	.balign	0x10
+	JUMP_TO_HANDLER (nmi, NMI_ENTRY_SP)	// 0x20 - NMI1
+	.balign	0x10
+	JUMP_TO_HANDLER (nmi, NMI_ENTRY_SP)	// 0x30 - NMI2
+	
+	.balign	0x10
+	JUMP_TO_HANDLER (trap, ENTRY_SP)	// 0x40 - TRAP0n
+	.balign	0x10
+	JUMP_TO_HANDLER (trap, ENTRY_SP)	// 0x50 - TRAP1n
+
+	.balign	0x10
+	JUMP_TO_HANDLER (dbtrap, ENTRY_SP)	// 0x60 - Illegal op / DBTRAP insn
+
+
+	/* Hardware interrupt vectors.  */
+	.section	.intv.mach, "ax"
+	.org	0x0
+
+#if defined (CONFIG_V850E_HIGHRES_TIMER) && defined (IRQ_INTCMD)
+
+	/* Interrupts before the highres timer interrupt.  */
+	.rept	IRQ_INTCMD (HIGHRES_TIMER_TIMER_D_UNIT)
+	.balign	0x10
+	JUMP_TO_HANDLER (irq, ENTRY_SP)
+	.endr
+
+	/* The highres timer interrupt.  */
+	.balign	0x10
+	JUMP_TO_HANDLER (C_SYMBOL_NAME (highres_timer_slow_tick_irq), ENTRY_SP)
+
+	/* Interrupts after the highres timer interrupt.  */
+	.rept	NUM_CPU_IRQS - IRQ_INTCMD (HIGHRES_TIMER_TIMER_D_UNIT) - 1
+	.balign	0x10
+	JUMP_TO_HANDLER (irq, ENTRY_SP)
+	.endr
+
+#else /* No highres timer */
+
+	.rept	NUM_CPU_IRQS
+	.balign	0x10
+	JUMP_TO_HANDLER (irq, ENTRY_SP)
+	.endr
+
+#endif /* Highres timer */
diff -urN linux-2.4.29/arch/v850/kernel/irq.c linux-2.4.29-uc1/arch/v850/kernel/irq.c
--- linux-2.4.29/arch/v850/kernel/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/irq.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,735 @@
+/*
+ * arch/v850/kernel/irq.c -- High-level interrupt handling
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 1994-2000  Ralf Baechle
+ *  Copyright (C) 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * This file was was derived from the mips version, arch/mips/kernel/irq.c
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+
+#include <asm/system.h>
+
+/*
+ * Controller mappings for all interrupt sources:
+ */
+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
+	[0 ... NR_IRQS-1] = {
+		.handler = &no_irq_type,
+		.lock = SPIN_LOCK_UNLOCKED
+	}
+};
+
+/*
+ * Special irq handlers.
+ */
+
+void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+
+/*
+ * Generic no controller code
+ */
+
+static void enable_none(unsigned int irq) { }
+static unsigned int startup_none(unsigned int irq) { return 0; }
+static void disable_none(unsigned int irq) { }
+static void ack_none(unsigned int irq)
+{
+	/*
+	 * 'what should we do if we get a hw irq event on an illegal vector'.
+	 * each architecture has to answer this themselves, it doesn't deserve
+	 * a generic callback i think.
+	 */
+	printk("received IRQ %d with unknown interrupt type\n", irq);
+}
+
+/* startup is the same as "enable", shutdown is same as "disable" */
+#define shutdown_none	disable_none
+#define end_none	enable_none
+
+struct hw_interrupt_type no_irq_type = {
+	"none",
+	startup_none,
+	shutdown_none,
+	enable_none,
+	disable_none,
+	ack_none,
+	end_none
+};
+
+volatile unsigned long irq_err_count, spurious_count;
+
+/*
+ * Generic, controller-independent functions:
+ */
+
+int get_irq_list(char *buf)
+{
+	struct irqaction * action;
+	char *p = buf;
+	int i;
+
+	p += sprintf(p, "           ");
+	for (i=0; i < 1 /*smp_num_cpus*/; i++)
+		p += sprintf(p, "CPU%d       ", i);
+	*p++ = '\n';
+
+	for (i = 0 ; i < NR_IRQS ; i++) {
+		int j, count, num;
+		const char *type_name = irq_desc[i].handler->typename;
+
+		action = irq_desc[i].action;
+		if (!action) 
+			continue;
+
+		count = 0;
+		num = -1;
+		for (j = 0; j < NR_IRQS; j++)
+			if (irq_desc[j].handler->typename == type_name) {
+				if (i == j)
+					num = count;
+				count++;
+			}
+
+		p += sprintf(p, "%3d: ",i);
+		p += sprintf(p, "%10u ", kstat_irqs(i));
+		if (count > 1) {
+			int prec = (num >= 100 ? 3 : num >= 10 ? 2 : 1);
+			p += sprintf(p, " %*s%d", 14 - prec, type_name, num);
+		} else
+			p += sprintf(p, " %14s", type_name);
+		p += sprintf(p, "  %s", action->name);
+
+		for (action=action->next; action; action = action->next)
+			p += sprintf(p, ", %s", action->name);
+		*p++ = '\n';
+	}
+	p += sprintf(p, "ERR: %10lu\n", irq_err_count);
+	return p - buf;
+}
+
+/*
+ * This should really return information about whether
+ * we should do bottom half handling etc. Right now we
+ * end up _always_ checking the bottom half, which is a
+ * waste of time and is not what some drivers would
+ * prefer.
+ */
+int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
+{
+	int status;
+	int cpu = smp_processor_id();
+
+	irq_enter(cpu, irq);
+
+	status = 1;	/* Force the "do bottom halves" bit */
+
+	if (!(action->flags & SA_INTERRUPT))
+		local_irq_enable();
+
+	do {
+		status |= action->flags;
+		action->handler(irq, action->dev_id, regs);
+		action = action->next;
+	} while (action);
+	if (status & SA_SAMPLE_RANDOM)
+		add_interrupt_randomness(irq);
+	local_irq_disable();
+
+	irq_exit(cpu, irq);
+
+	return status;
+}
+
+/*
+ * Generic enable/disable code: this just calls
+ * down into the PIC-specific version for the actual
+ * hardware disable after having gotten the irq
+ * controller lock. 
+ */
+ 
+/**
+ *	disable_irq_nosync - disable an irq without waiting
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line. Disables of an interrupt
+ *	stack. Unlike disable_irq(), this function does not ensure existing
+ *	instances of the IRQ handler have completed before returning.
+ *
+ *	This function may be called from IRQ context.
+ */
+ 
+void inline disable_irq_nosync(unsigned int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	if (!desc->depth++) {
+		desc->status |= IRQ_DISABLED;
+		desc->handler->disable(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/**
+ *	disable_irq - disable an irq and wait for completion
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line. Disables of an interrupt
+ *	stack. That is for two disables you need two enables. This
+ *	function waits for any pending IRQ handlers for this interrupt
+ *	to complete before returning. If you use this function while
+ *	holding a resource the IRQ handler may need you will deadlock.
+ *
+ *	This function may be called - with care - from IRQ context.
+ */
+ 
+void disable_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+
+	if (!local_irq_count(smp_processor_id())) {
+		do {
+			barrier();
+		} while (irq_desc[irq].status & IRQ_INPROGRESS);
+	}
+}
+
+/**
+ *	enable_irq - enable interrupt handling on an irq
+ *	@irq: Interrupt to enable
+ *
+ *	Re-enables the processing of interrupts on this IRQ line
+ *	providing no disable_irq calls are now in effect.
+ *
+ *	This function may be called from IRQ context.
+ */
+ 
+void enable_irq(unsigned int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	switch (desc->depth) {
+	case 1: {
+		unsigned int status = desc->status & ~IRQ_DISABLED;
+		desc->status = status;
+		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+			desc->status = status | IRQ_REPLAY;
+			hw_resend_irq(desc->handler,irq);
+		}
+		desc->handler->enable(irq);
+		/* fall-through */
+	}
+	default:
+		desc->depth--;
+		break;
+	case 0:
+		printk("enable_irq(%u) unbalanced from %p\n", irq,
+		       __builtin_return_address(0));
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/* Handle interrupt IRQ.  REGS are the registers at the time of ther
+   interrupt.  */
+unsigned int handle_irq (int irq, struct pt_regs *regs)
+{
+	/* 
+	 * We ack quickly, we don't want the irq controller
+	 * thinking we're snobs just because some other CPU has
+	 * disabled global interrupts (we have already done the
+	 * INT_ACK cycles, it's too late to try to pretend to the
+	 * controller that we aren't taking the interrupt).
+	 *
+	 * 0 return value means that this irq is already being
+	 * handled by some other CPU. (or is disabled)
+	 */
+	int cpu = smp_processor_id();
+	irq_desc_t *desc = irq_desc + irq;
+	struct irqaction * action;
+	unsigned int status;
+
+	kstat.irqs[cpu][irq]++;
+	spin_lock(&desc->lock);
+	desc->handler->ack(irq);
+	/*
+	   REPLAY is when Linux resends an IRQ that was dropped earlier
+	   WAITING is used by probe to mark irqs that are being tested
+	   */
+	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
+	status |= IRQ_PENDING; /* we _want_ to handle it */
+
+	/*
+	 * If the IRQ is disabled for whatever reason, we cannot
+	 * use the action we have.
+	 */
+	action = NULL;
+	if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		action = desc->action;
+		status &= ~IRQ_PENDING; /* we commit to handling */
+		status |= IRQ_INPROGRESS; /* we are handling it */
+	}
+	desc->status = status;
+
+	/*
+	 * If there is no IRQ handler or it was disabled, exit early.
+	   Since we set PENDING, if another processor is handling
+	   a different instance of this same irq, the other processor
+	   will take care of it.
+	 */
+	if (!action)
+		goto out;
+
+	/*
+	 * Edge triggered interrupts need to remember
+	 * pending events.
+	 * This applies to any hw interrupts that allow a second
+	 * instance of the same irq to arrive while we are in handle_irq
+	 * or in the handler. But the code here only handles the _second_
+	 * instance of the irq, not the third or fourth. So it is mostly
+	 * useful for irq hardware that does not mask cleanly in an
+	 * SMP environment.
+	 */
+	for (;;) {
+		spin_unlock(&desc->lock);
+		handle_IRQ_event(irq, regs, action);
+		spin_lock(&desc->lock);
+		
+		if (!(desc->status & IRQ_PENDING))
+			break;
+		desc->status &= ~IRQ_PENDING;
+	}
+	desc->status &= ~IRQ_INPROGRESS;
+out:
+	/*
+	 * The ->end() handler has to deal with interrupts which got
+	 * disabled while the handler was running.
+	 */
+	desc->handler->end(irq);
+	spin_unlock(&desc->lock);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+
+	return 1;
+}
+
+/**
+ *	request_irq - allocate an interrupt line
+ *	@irq: Interrupt line to allocate
+ *	@handler: Function to be called when the IRQ occurs
+ *	@irqflags: Interrupt type flags
+ *	@devname: An ascii name for the claiming device
+ *	@dev_id: A cookie passed back to the handler function
+ *
+ *	This call allocates interrupt resources and enables the
+ *	interrupt line and IRQ handling. From the point this
+ *	call is made your handler function may be invoked. Since
+ *	your handler function must clear any interrupt the board 
+ *	raises, you must take care both to initialise your hardware
+ *	and to set up the interrupt handler in the right order.
+ *
+ *	Dev_id must be globally unique. Normally the address of the
+ *	device data structure is used as the cookie. Since the handler
+ *	receives this value it makes sense to use it.
+ *
+ *	If your interrupt is shared you must pass a non NULL dev_id
+ *	as this is required when freeing the interrupt.
+ *
+ *	Flags:
+ *
+ *	SA_SHIRQ		Interrupt is shared
+ *
+ *	SA_INTERRUPT		Disable local interrupts while processing
+ *
+ *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
+ *
+ */
+ 
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
+{
+	int retval;
+	struct irqaction * action;
+
+#if 1
+	/*
+	 * Sanity-check: shared interrupts should REALLY pass in
+	 * a real dev-ID, otherwise we'll have trouble later trying
+	 * to figure out which interrupt is which (messes up the
+	 * interrupt freeing logic etc).
+	 */
+	if (irqflags & SA_SHIRQ) {
+		if (!dev_id)
+			printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]);
+	}
+#endif
+
+	if (irq >= NR_IRQS)
+		return -EINVAL;
+	if (!handler)
+		return -EINVAL;
+
+	action = (struct irqaction *)
+			kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = 0;
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_irq(irq, action);
+	if (retval)
+		kfree(action);
+	return retval;
+}
+
+/**
+ *	free_irq - free an interrupt
+ *	@irq: Interrupt line to free
+ *	@dev_id: Device identity to free
+ *
+ *	Remove an interrupt handler. The handler is removed and if the
+ *	interrupt line is no longer in use by any driver it is disabled.
+ *	On a shared IRQ the caller must ensure the interrupt is disabled
+ *	on the card it drives before calling this function. The function
+ *	does not return until any executing interrupts for this IRQ
+ *	have completed.
+ *
+ *	This function may be called from interrupt context. 
+ *
+ *	Bugs: Attempting to free an irq in a handler for the same irq hangs
+ *	      the machine.
+ */
+ 
+void free_irq(unsigned int irq, void *dev_id)
+{
+	irq_desc_t *desc;
+	struct irqaction **p;
+	unsigned long flags;
+
+	if (irq >= NR_IRQS)
+		return;
+
+	desc = irq_desc + irq;
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
+	for (;;) {
+		struct irqaction * action = *p;
+		if (action) {
+			struct irqaction **pp = p;
+			p = &action->next;
+			if (action->dev_id != dev_id)
+				continue;
+
+			/* Found it - now remove it from the list of entries */
+			*pp = action->next;
+			if (!desc->action) {
+				desc->status |= IRQ_DISABLED;
+				desc->handler->shutdown(irq);
+			}
+			spin_unlock_irqrestore(&desc->lock,flags);
+
+#ifdef CONFIG_SMP
+			/* Wait to make sure it's not being used on another CPU */
+			while (desc->status & IRQ_INPROGRESS)
+				barrier();
+#endif
+			kfree(action);
+			return;
+		}
+		printk("Trying to free free IRQ%d\n",irq);
+		spin_unlock_irqrestore(&desc->lock,flags);
+		return;
+	}
+}
+
+/*
+ * IRQ autodetection code..
+ *
+ * This depends on the fact that any interrupt that
+ * comes in on to an unassigned handler will get stuck
+ * with "IRQ_WAITING" cleared and the interrupt
+ * disabled.
+ */
+
+static DECLARE_MUTEX(probe_sem);
+
+/**
+ *	probe_irq_on	- begin an interrupt autodetect
+ *
+ *	Commence probing for an interrupt. The interrupts are scanned
+ *	and a mask of potential interrupt lines is returned.
+ *
+ */
+ 
+unsigned long probe_irq_on(void)
+{
+	unsigned int i;
+	irq_desc_t *desc;
+	unsigned long val;
+	unsigned long delay;
+
+	down(&probe_sem);
+	/* 
+	 * something may have generated an irq long ago and we want to
+	 * flush such a longstanding irq before considering it as spurious. 
+	 */
+	for (i = NR_IRQS-1; i > 0; i--)  {
+		desc = irq_desc + i;
+
+		spin_lock_irq(&desc->lock);
+		if (!irq_desc[i].action) 
+			irq_desc[i].handler->startup(i);
+		spin_unlock_irq(&desc->lock);
+	}
+
+	/* Wait for longstanding interrupts to trigger. */
+	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
+		/* about 20ms delay */ synchronize_irq();
+
+	/*
+	 * enable any unassigned irqs
+	 * (we must startup again here because if a longstanding irq
+	 * happened in the previous stage, it may have masked itself)
+	 */
+	for (i = NR_IRQS-1; i > 0; i--) {
+		desc = irq_desc + i;
+
+		spin_lock_irq(&desc->lock);
+		if (!desc->action) {
+			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
+			if (desc->handler->startup(i))
+				desc->status |= IRQ_PENDING;
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	/*
+	 * Wait for spurious interrupts to trigger
+	 */
+	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
+		/* about 100ms delay */ synchronize_irq();
+
+	/*
+	 * Now filter out any obviously spurious interrupts
+	 */
+	val = 0;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			/* It triggered already - consider it spurious. */
+			if (!(status & IRQ_WAITING)) {
+				desc->status = status & ~IRQ_AUTODETECT;
+				desc->handler->shutdown(i);
+			} else
+				if (i < 32)
+					val |= 1 << i;
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	return val;
+}
+
+/*
+ * Return a mask of triggered interrupts (this
+ * can handle only legacy ISA interrupts).
+ */
+ 
+/**
+ *	probe_irq_mask - scan a bitmap of interrupt lines
+ *	@val:	mask of interrupts to consider
+ *
+ *	Scan the ISA bus interrupt lines and return a bitmap of
+ *	active interrupts. The interrupt probe logic state is then
+ *	returned to its previous value.
+ *
+ *	Note: we need to scan all the irq's even though we will
+ *	only return ISA irq numbers - just so that we reset them
+ *	all to a known state.
+ */
+unsigned int probe_irq_mask(unsigned long val)
+{
+	int i;
+	unsigned int mask;
+
+	mask = 0;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			if (i < 16 && !(status & IRQ_WAITING))
+				mask |= 1 << i;
+
+			desc->status = status & ~IRQ_AUTODETECT;
+			desc->handler->shutdown(i);
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+	up(&probe_sem);
+
+	return mask & val;
+}
+
+/*
+ * Return the one interrupt that triggered (this can
+ * handle any interrupt source).
+ */
+
+/**
+ *	probe_irq_off	- end an interrupt autodetect
+ *	@val: mask of potential interrupts (unused)
+ *
+ *	Scans the unused interrupt lines and returns the line which
+ *	appears to have triggered the interrupt. If no interrupt was
+ *	found then zero is returned. If more than one interrupt is
+ *	found then minus the first candidate is returned to indicate
+ *	their is doubt.
+ *
+ *	The interrupt probe logic state is returned to its previous
+ *	value.
+ *
+ *	BUGS: When used in a module (which arguably shouldnt happen)
+ *	nothing prevents two IRQ probe callers from overlapping. The
+ *	results of this are non-optimal.
+ */
+ 
+int probe_irq_off(unsigned long val)
+{
+	int i, irq_found, nr_irqs;
+
+	nr_irqs = 0;
+	irq_found = 0;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			if (!(status & IRQ_WAITING)) {
+				if (!nr_irqs)
+					irq_found = i;
+				nr_irqs++;
+			}
+			desc->status = status & ~IRQ_AUTODETECT;
+			desc->handler->shutdown(i);
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+	up(&probe_sem);
+
+	if (nr_irqs > 1)
+		irq_found = -irq_found;
+	return irq_found;
+}
+
+/* this was setup_x86_irq but it seems pretty generic */
+int setup_irq(unsigned int irq, struct irqaction * new)
+{
+	int shared = 0;
+	unsigned long flags;
+	struct irqaction *old, **p;
+	irq_desc_t *desc = irq_desc + irq;
+
+	/*
+	 * Some drivers like serial.c use request_irq() heavily,
+	 * so we have to be careful not to interfere with a
+	 * running system.
+	 */
+	if (new->flags & SA_SAMPLE_RANDOM) {
+		/*
+		 * This function might sleep, we want to call it first,
+		 * outside of the atomic block.
+		 * Yes, this might clear the entropy pool if the wrong
+		 * driver is attempted to be loaded, without actually
+		 * installing a new handler, but is this really a problem,
+		 * only the sysadmin is able to do this.
+		 */
+		rand_initialize_irq(irq);
+	}
+
+	/*
+	 * The following block of code has to be executed atomically
+	 */
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
+	if ((old = *p) != NULL) {
+		/* Can't share interrupts unless both agree to */
+		if (!(old->flags & new->flags & SA_SHIRQ)) {
+			spin_unlock_irqrestore(&desc->lock,flags);
+			return -EBUSY;
+		}
+
+		/* add new interrupt at end of irq queue */
+		do {
+			p = &old->next;
+			old = *p;
+		} while (old);
+		shared = 1;
+	}
+
+	*p = new;
+
+	if (!shared) {
+		desc->depth = 0;
+		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
+		desc->handler->startup(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock,flags);
+
+	/* register_irq_proc(irq); */
+	return 0;
+}
+
+/* Initialize irq handling for IRQs.
+   BASE_IRQ, BASE_IRQ+INTERVAL, ..., BASE_IRQ+NUM*INTERVAL
+   to IRQ_TYPE.  An IRQ_TYPE of 0 means to use a generic interrupt type.  */
+void __init
+init_irq_handlers (int base_irq, int num, int interval,
+		   struct hw_interrupt_type *irq_type)
+{
+	while (num-- > 0) {
+		irq_desc[base_irq].status  = IRQ_DISABLED;
+		irq_desc[base_irq].action  = NULL;
+		irq_desc[base_irq].depth   = 1;
+		irq_desc[base_irq].handler = irq_type;
+		base_irq += interval;
+	}
+}
diff -urN linux-2.4.29/arch/v850/kernel/linux.ld.in linux-2.4.29-uc1/arch/v850/kernel/linux.ld.in
--- linux-2.4.29/arch/v850/kernel/linux.ld.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/linux.ld.in	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,250 @@
+/*
+ * arch/v850/linux.ld.in -- kernel linker script for v850 platforms
+ *
+ *  Copyright (C) 2002,03  NEC Electronics Corporation
+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+
+/* For most platforms, this will define useful things like RAM addr/size.  */
+#include <asm/machdep.h>
+
+
+/* The following macros contain the usual definitions for various data areas.
+   The prefix `RAMK_' is used to indicate macros suitable for kernels loaded
+   into RAM, and similarly `ROMK_' for ROM-resident kernels.  Note that all
+   symbols are prefixed with an extra `_' for compatibility with the v850
+   toolchain.  */
+
+	
+/* Interrupt vectors.  */
+#define INTV_CONTENTS							      \
+		. = ALIGN (0x10) ;					      \
+		__intv_start = . ;					      \
+			*(.intv.reset)	/* Reset vector */		      \
+		. = __intv_start + 0x10 ;				      \
+			*(.intv.common)	/* Vectors common to all v850e proc */\
+		. = __intv_start + 0x80 ;				      \
+			*(.intv.mach)	/* Machine-specific int. vectors.  */ \
+		__intv_end = . ;
+
+/* Kernel text segment, and some constant data areas.  */
+#define TEXT_CONTENTS							      \
+		__stext = . ;						      \
+        	*(.text)						      \
+			*(.exit.text)	/* 2.5 convention */		      \
+			*(.text.exit)	/* 2.4 convention */		      \
+			*(.text.lock)					      \
+			*(.exitcall.exit)				      \
+		__real_etext = . ;	/* There may be data after here.  */  \
+			*(.rodata)					      \
+		. = ALIGN (0x4) ;					      \
+			*(.kstrtab)					      \
+		. = ALIGN (4) ;						      \
+		    	*(.call_table_data)				      \
+			*(.call_table_text)				      \
+		. = ALIGN (16) ;	/* Exception table.  */		      \
+		___start___ex_table = . ;				      \
+			*(__ex_table)					      \
+		___stop___ex_table = . ;				      \
+		___start___ksymtab = . ;/* Kernel symbol table.  */	      \
+			*(__ksymtab)					      \
+		___stop___ksymtab = . ;					      \
+		. = ALIGN (4) ;						      \
+		__etext = . ;
+
+/* Kernel data segment.  */
+#define DATA_CONTENTS							      \
+		__sdata = . ;						      \
+        	*(.data)						      \
+			*(.exit.data)	/* 2.5 convention */		      \
+			*(.data.exit)	/* 2.4 convention */		      \
+		. = ALIGN (16) ;					      \
+		*(.data.cacheline_aligned)				      \
+		. = ALIGN (0x2000) ;					      \
+        	*(.data.init_task)					      \
+		. = ALIGN (0x2000) ;					      \
+		__edata = . ;
+
+/* Kernel BSS segment.  */
+#define BSS_CONTENTS							      \
+		__sbss = . ;						      \
+			*(.bss)						      \
+			*(COMMON)					      \
+		. = ALIGN (4) ;						      \
+		__init_stack_end = . ;					      \
+		__ebss = . ;
+
+/* `initcall' tables.  */
+#define INITCALL_CONTENTS						      \
+		. = ALIGN (16) ;					      \
+		___setup_start = . ;					      \
+			*(.init.setup)	/* 2.5 convention */		      \
+			*(.setup.init)	/* 2.4 convention */		      \
+		___setup_end = . ;					      \
+		___start___param = . ;					      \
+			*(__param)					      \
+		___stop___param = . ;					      \
+		___initcall_start = . ;					      \
+			*(.initcall.init)				      \
+			*(.initcall1.init)				      \
+			*(.initcall2.init)				      \
+			*(.initcall3.init)				      \
+			*(.initcall4.init)				      \
+			*(.initcall5.init)				      \
+			*(.initcall6.init)				      \
+			*(.initcall7.init)				      \
+		. = ALIGN (4) ;						      \
+		___initcall_end = . ;
+
+/* Contents of `init' section for a kernel that's loaded into RAM.  */
+#define RAMK_INIT_CONTENTS						      \
+		RAMK_INIT_CONTENTS_NO_END				      \
+		__init_end = . ;
+/* Same as RAMK_INIT_CONTENTS, but doesn't define the `__init_end' symbol.  */
+#define RAMK_INIT_CONTENTS_NO_END					      \
+		. = ALIGN (4096) ;					      \
+		__init_start = . ;					      \
+			*(.init.text)	/* 2.5 convention */		      \
+			*(.init.data)					      \
+			*(.text.init)	/* 2.4 convention */		      \
+			*(.data.init)					      \
+		INITCALL_CONTENTS					      \
+		INITRAMFS_CONTENTS
+
+/* The contents of `init' section for a ROM-resident kernel which
+   should go into RAM.  */	
+#define ROMK_INIT_RAM_CONTENTS						      \
+		. = ALIGN (4096) ;					      \
+		__init_start = . ;					      \
+			*(.init.data)	/* 2.5 convention */		      \
+			*(.data.init)	/* 2.4 convention */		      \
+		__init_end = . ;					      \
+		. = ALIGN (4096) ;
+
+/* The contents of `init' section for a ROM-resident kernel which
+   should go into ROM.  */	
+#define ROMK_INIT_ROM_CONTENTS						      \
+			*(.init.text)	/* 2.5 convention */		      \
+			*(.text.init)	/* 2.4 convention */		      \
+		INITCALL_CONTENTS					      \
+		INITRAMFS_CONTENTS
+
+/* A root filesystem image, for kernels with an embedded root filesystem.  */
+#define ROOT_FS_CONTENTS						      \
+		__root_fs_image_start = . ;				      \
+		*(.root)						      \
+		__root_fs_image_end = . ;
+/* The initramfs archive.  */
+#define INITRAMFS_CONTENTS						      \
+		. = ALIGN (4) ;						      \
+		___initramfs_start = . ;				      \
+			*(.init.ramfs)					      \
+		___initramfs_end = . ;
+/* Where the initial bootmap (bitmap for the boot-time memory allocator) 
+   should be place.  */
+#define BOOTMAP_CONTENTS						      \
+		. = ALIGN (4096) ;					      \
+		__bootmap = . ;						      \
+		. = . + 4096 ;		/* enough for 128MB.   */
+
+/* The contents of a `typical' kram area for a kernel in RAM.  */
+#define RAMK_KRAM_CONTENTS						      \
+		__kram_start = . ;					      \
+		TEXT_CONTENTS						      \
+		DATA_CONTENTS						      \
+		BSS_CONTENTS						      \
+		RAMK_INIT_CONTENTS					      \
+		__kram_end = . ;					      \
+		BOOTMAP_CONTENTS
+
+
+/* Define output sections normally used for a ROM-resident kernel.  
+   ROM and RAM should be appropriate memory areas to use for kernel
+   ROM and RAM data.  This assumes that ROM starts at 0 (and thus can
+   hold the interrupt vectors).  */
+#define ROMK_SECTIONS(ROM, RAM)						      \
+	.rom : {							      \
+		INTV_CONTENTS						      \
+		TEXT_CONTENTS						      \
+		ROMK_INIT_ROM_CONTENTS					      \
+		ROOT_FS_CONTENTS					      \
+	} > ROM								      \
+									      \
+	__rom_copy_src_start = . ;					      \
+									      \
+	.data : {							      \
+		__kram_start = . ;					      \
+		__rom_copy_dst_start = . ;				      \
+		DATA_CONTENTS						      \
+		ROMK_INIT_RAM_CONTENTS					      \
+		__rom_copy_dst_end = . ;				      \
+	} > RAM  AT> ROM						      \
+									      \
+	.bss ALIGN (4) : {						      \
+		BSS_CONTENTS						      \
+		__kram_end = . ;					      \
+		BOOTMAP_CONTENTS					      \
+	} > RAM
+
+
+/* Include an appropriate platform-dependent linker-script (which
+   usually should use the above macros to do most of the work).  */
+
+#ifdef CONFIG_V850E_SIM
+# include "sim.ld"
+#endif
+
+#ifdef CONFIG_V850E2_SIM85E2
+# include "sim85e2.ld"
+#endif
+
+#ifdef CONFIG_V850E2_FPGA85E2C
+# include "fpga85e2c.ld"
+#endif
+
+#ifdef CONFIG_V850E2_ANNA
+# ifdef CONFIG_ROM_KERNEL
+#  include "anna-rom.ld"
+# else
+#  include "anna.ld"
+# endif
+#endif
+
+#ifdef CONFIG_V850E_AS85EP1
+# ifdef CONFIG_ROM_KERNEL
+#  include "as85ep1-rom.ld"
+# else
+#  include "as85ep1.ld"
+# endif
+#endif
+
+#ifdef CONFIG_RTE_CB_MA1
+# ifdef CONFIG_ROM_KERNEL
+#  include "rte_ma1_cb-rom.ld"
+# else
+#  include "rte_ma1_cb.ld"
+# endif
+#endif
+
+#ifdef CONFIG_RTE_CB_NB85E
+# ifdef CONFIG_ROM_KERNEL
+#  include "rte_nb85e_cb-rom.ld"
+# elif defined(CONFIG_RTE_CB_MULTI)
+#  include "rte_nb85e_cb-multi.ld"
+# else
+#  include "rte_nb85e_cb.ld"
+# endif
+#endif
+
+#ifdef CONFIG_RTE_CB_ME2
+#  include "rte_me2_cb.ld"
+#endif
+
diff -urN linux-2.4.29/arch/v850/kernel/ma.c linux-2.4.29-uc1/arch/v850/kernel/ma.c
--- linux-2.4.29/arch/v850/kernel/ma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/ma.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,70 @@
+/*
+ * arch/v850/kernel/ma.c -- V850E/MA series of cpu chips
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+#include <asm/v850e_timer_d.h>
+
+#include "mach.h"
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* Start hardware timer.  */
+	v850e_timer_d_configure (0, HZ);
+	/* Install timer interrupt handler.  */
+	setup_irq (IRQ_INTCMD(0), timer_action);
+}
+
+static struct v850e_intc_irq_init irq_inits[] = {
+	{ "IRQ", 0, 		NUM_MACH_IRQS,	1, 7 },
+	{ "CMD", IRQ_INTCMD(0), IRQ_INTCMD_NUM,	1, 5 },
+	{ "DMA", IRQ_INTDMA(0), IRQ_INTDMA_NUM,	1, 2 },
+	{ "CSI", IRQ_INTCSI(0), IRQ_INTCSI_NUM,	4, 4 },
+	{ "SER", IRQ_INTSER(0), IRQ_INTSER_NUM,	4, 3 },
+	{ "SR",	 IRQ_INTSR(0),	IRQ_INTSR_NUM, 	4, 4 },
+	{ "ST",  IRQ_INTST(0), 	IRQ_INTST_NUM, 	4, 5 },
+	{ 0 }
+};
+#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
+
+static struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
+
+/* Initialize MA chip interrupts.  */
+void __init ma_init_irqs (void)
+{
+	v850e_intc_init_irq_types (irq_inits, hw_itypes);
+}
+
+/* Called before configuring an on-chip UART.  */
+void ma_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud)
+{
+	/* We only know about the first two UART channels (though
+	   specific chips may have more).  */
+	if (chan < 2) {
+		unsigned bits = 0x3 << (chan * 3);
+		/* Specify that the relevant pins on the chip should do
+		   serial I/O, not direct I/O.  */
+		MA_PORT4_PMC |= bits;
+		/* Specify that we're using the UART, not the CSI device.  */
+		MA_PORT4_PFC |= bits;
+	}
+}
diff -urN linux-2.4.29/arch/v850/kernel/mach.c linux-2.4.29-uc1/arch/v850/kernel/mach.c
--- linux-2.4.29/arch/v850/kernel/mach.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/mach.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * arch/v850/kernel/mach.c -- Defaults for some things defined by "mach.h"
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include "mach.h"
+
+/* Called with each timer tick, if non-zero.  */
+void (*mach_tick)(void) = 0;
diff -urN linux-2.4.29/arch/v850/kernel/mach.h linux-2.4.29-uc1/arch/v850/kernel/mach.h
--- linux-2.4.29/arch/v850/kernel/mach.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/mach.h	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,56 @@
+/*
+ * arch/v850/kernel/mach.h -- Machine-dependent functions used by v850 port
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_MACH_H__
+#define __V850_MACH_H__
+
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+
+#include <asm/ptrace.h>
+#include <asm/entry.h>
+#include <asm/clinkage.h>
+
+void mach_setup (char **cmdline);
+void mach_gettimeofday (struct timeval *tv);
+void mach_sched_init (struct irqaction *timer_action);
+void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len);
+void mach_init_irqs (void);
+
+/* If defined, is called very early in the kernel initialization.  The
+   stack pointer is valid, but very little has been initialized (e.g.,
+   bss is not zeroed yet) when this is called, so care must taken.  */
+void mach_early_init (void);
+
+/* If defined, called after the bootmem allocator has been initialized,
+   to allow the platform-dependent code to reserve any areas of RAM that
+   the kernel shouldn't touch.  */
+void mach_reserve_bootmem (void) __attribute__ ((__weak__));
+
+/* Called with each timer tick, if non-zero.  */
+extern void (*mach_tick) (void);
+
+/* The following establishes aliases for various mach_ functions to the
+   name by which the rest of the kernel calls them.  These statements
+   should only have an effect in the file that defines the actual functions. */
+#define MACH_ALIAS(to, from)						      \
+   asm (".global " macrology_stringify (C_SYMBOL_NAME (to)) ";"		      \
+	macrology_stringify (C_SYMBOL_NAME (to))			      \
+	" = " macrology_stringify (C_SYMBOL_NAME (from)))
+/* e.g.: MACH_ALIAS (kernel_name,	arch_spec_name);  */
+
+#endif /* __V850_MACH_H__ */
diff -urN linux-2.4.29/arch/v850/kernel/Makefile linux-2.4.29-uc1/arch/v850/kernel/Makefile
--- linux-2.4.29/arch/v850/kernel/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/Makefile	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,59 @@
+#
+# arch/v850/kernel/Makefile
+#
+#  Copyright (C) 2001,02,03  NEC Electronics Corporation
+#  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+
+all: head.o kernel.o
+
+USE_STANDARD_AS_RULE	:= true
+
+O_TARGET := kernel.o
+obj-y := intv.o entry.o process.o syscalls.o time.o semaphore.o setup.o \
+	 signal.o irq.o mach.o ptrace.o bug.o
+export-objs := v850_ksyms.o rte_mb_a_pci.o
+
+obj-$(CONFIG_MODULES)		+= v850_ksyms.o
+# chip-specific code
+obj-$(CONFIG_V850E_MA1)		+= ma.o
+obj-$(CONFIG_V850E_ME2)		+= me2.o
+obj-$(CONFIG_V850E_TEG)		+= teg.o
+obj-$(CONFIG_V850E_AS85EP1)	+= as85ep1.o
+obj-$(CONFIG_V850E2_ANNA)	+= anna.o
+# platform-specific code
+obj-$(CONFIG_V850E_SIM)		+= sim.o simcons.o
+obj-$(CONFIG_V850E2_SIM85E2)	+= sim85e2.o memcons.o
+obj-$(CONFIG_V850E2_FPGA85E2C)	+= fpga85e2c.o memcons.o
+obj-$(CONFIG_RTE_CB)		+= rte_cb.o rte_cb_leds.o
+obj-$(CONFIG_RTE_CB_MA1)	+= rte_ma1_cb.o
+obj-$(CONFIG_RTE_CB_ME2)	+= rte_me2_cb.o
+obj-$(CONFIG_RTE_CB_NB85E)	+= rte_nb85e_cb.o
+obj-$(CONFIG_RTE_CB_MULTI)	+= rte_cb_multi.o
+obj-$(CONFIG_RTE_MB_A_PCI)	+= rte_mb_a_pci.o
+obj-$(CONFIG_RTE_GBUS_INT)	+= gbus_int.o
+# feature-specific code
+obj-$(CONFIG_V850E_INTC)	+= v850e_intc.o
+obj-$(CONFIG_V850E_TIMER_D)	+= v850e_timer_d.o v850e_utils.o
+obj-$(CONFIG_V850E_CACHE)	+= v850e_cache.o
+obj-$(CONFIG_V850E2_CACHE)	+= v850e2_cache.o
+obj-$(CONFIG_V850E_HIGHRES_TIMER) += highres_timer.o
+obj-$(CONFIG_PROC_FS)		+= procfs.o
+
+head.o: head.S v850_defs.h
+entry.o: entry.S v850_defs.h
+
+v850_defs.h: v850_defs.c v850_defs.head
+	rm -f v850_defs.d
+	SUNPRO_DEPENDENCIES="v850_defs.d v850_defs.h" \
+	$(CC) $(filter-out -MD,$(CFLAGS)) -S v850_defs.c
+	cp v850_defs.head v850_defs.h
+	grep '^#define' v850_defs.s >> v850_defs.h
+	rm v850_defs.s
+-include v850_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/v850/kernel/me2.c linux-2.4.29-uc1/arch/v850/kernel/me2.c
--- linux-2.4.29/arch/v850/kernel/me2.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/me2.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,74 @@
+/*
+ * arch/v850/kernel/me2.c -- V850E/ME2 chip-specific support
+ *
+ *  Copyright (C) 2003  NEC Corporation
+ *  Copyright (C) 2003  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+#include <asm/v850e_timer_d.h>
+
+#include "mach.h"
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* Start hardware timer.  */
+	v850e_timer_d_configure (0, HZ);
+	/* Install timer interrupt handler.  */
+	setup_irq (IRQ_INTCMD(0), timer_action);
+}
+
+static struct v850e_intc_irq_init irq_inits[] = {
+	{ "IRQ",    0,                NUM_CPU_IRQS,      1, 7 },
+	{ "INTP",   IRQ_INTP(0),      IRQ_INTP_NUM,      1, 5 },
+	{ "CMD",    IRQ_INTCMD(0),    IRQ_INTCMD_NUM,    1, 3 },
+	{ "UBTIRE", IRQ_INTUBTIRE(0), IRQ_INTUBTIRE_NUM, 5, 4 },
+	{ "UBTIR",  IRQ_INTUBTIR(0),  IRQ_INTUBTIR_NUM,  5, 4 },
+	{ "UBTIT",  IRQ_INTUBTIT(0),  IRQ_INTUBTIT_NUM,  5, 4 },
+	{ "UBTIF",  IRQ_INTUBTIF(0),  IRQ_INTUBTIF_NUM,  5, 4 },
+	{ "UBTITO", IRQ_INTUBTITO(0), IRQ_INTUBTITO_NUM, 5, 4 },
+	{ 0 }
+};
+#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
+
+static struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
+
+/* Initialize V850E/ME2 chip interrupts.  */
+void __init me2_init_irqs (void)
+{
+	v850e_intc_init_irq_types (irq_inits, hw_itypes);
+}
+
+/* Called before configuring an on-chip UART.  */
+void me2_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud)
+{
+	if (chan == 0) {
+		/* Specify that the relevent pins on the chip should do
+		   serial I/O, not direct I/O.  */
+		ME2_PORT1_PMC |= 0xC;
+		/* Specify that we're using the UART, not the CSI device. */
+		ME2_PORT1_PFC |= 0xC;
+	} else if (chan == 1) {
+		/* Specify that the relevent pins on the chip should do
+		   serial I/O, not direct I/O.  */
+		ME2_PORT2_PMC |= 0x6;
+		/* Specify that we're using the UART, not the CSI device. */
+		ME2_PORT2_PFC |= 0x6;
+	}
+}
diff -urN linux-2.4.29/arch/v850/kernel/memcons.c linux-2.4.29-uc1/arch/v850/kernel/memcons.c
--- linux-2.4.29/arch/v850/kernel/memcons.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/memcons.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,134 @@
+/*
+ * arch/v850/kernel/memcons.c -- Console I/O to a memory buffer
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/init.h>
+
+/* If this device is enabled, the linker map should define start and
+   end points for its buffer. */
+extern char memcons_output[], memcons_output_end;
+
+/* Current offset into the buffer.  */
+static unsigned long memcons_offs = 0;
+
+/* Spinlock protecting memcons_offs.  */
+static spinlock_t memcons_lock = SPIN_LOCK_UNLOCKED;
+
+
+static size_t write (const char *buf, size_t len)
+{
+	int flags;
+	char *point;
+
+	spin_lock_irqsave (memcons_lock, flags);
+
+	point = memcons_output + memcons_offs;
+	if (point + len >= &memcons_output_end) {
+		len = &memcons_output_end - point;
+		memcons_offs = 0;
+	} else
+		memcons_offs += len;
+
+	spin_unlock_irqrestore (memcons_lock, flags);
+
+	memcpy (point, buf, len);
+
+	return len;
+}
+
+
+/*  Low-level console. */
+
+static void memcons_write (struct console *co, const char *buf, unsigned len)
+{
+	while (len > 0)
+		len -= write (buf, len);
+}
+
+static kdev_t memcons_device (struct console *co)
+{
+        return MKDEV (TTY_MAJOR, 64 + co->index);
+}
+
+static struct console memcons =
+{
+    .name	= "memcons",
+    .write	= memcons_write,
+    .device	= memcons_device,
+    .flags	= CON_PRINTBUFFER,
+    .index	= -1,
+};
+
+void memcons_setup (void)
+{
+	register_console (&memcons);
+	printk (KERN_INFO "Console: static memory buffer (memcons)\n");
+}
+
+/* Higher level TTY interface.  */
+
+static struct tty_struct *tty_table[1] = { 0 };
+static struct termios *tty_termios[1] = { 0 };
+static struct termios *tty_termios_locked[1] = { 0 };
+static struct tty_driver tty_driver = { 0 };
+static int tty_ref_count = 0;
+
+int memcons_tty_open (struct tty_struct *tty, struct file *filp)
+{
+	return 0;
+}
+
+int memcons_tty_write (struct tty_struct *tty, int from_user,
+		       const unsigned char *buf, int len)
+{
+	return write (buf, len);
+}
+
+int memcons_tty_write_room (struct tty_struct *tty)
+{
+	return &memcons_output_end - (memcons_output + memcons_offs);
+}
+
+int memcons_tty_chars_in_buffer (struct tty_struct *tty)
+{
+	/* We have no buffer.  */
+	return 0;
+}
+
+int __init memcons_tty_init (void)
+{
+	tty_driver.name = "memcons";
+	tty_driver.major = TTY_MAJOR;
+	tty_driver.minor_start = 64;
+	tty_driver.num = 1;
+	tty_driver.type = TTY_DRIVER_TYPE_SYSCONS;
+
+	tty_driver.refcount = &tty_ref_count;
+
+	tty_driver.table = tty_table;
+	tty_driver.termios = tty_termios;
+	tty_driver.termios_locked = tty_termios_locked;
+
+	tty_driver.init_termios = tty_std_termios;
+
+	tty_driver.open = memcons_tty_open;
+	tty_driver.write = memcons_tty_write;
+	tty_driver.write_room = memcons_tty_write_room;
+	tty_driver.chars_in_buffer = memcons_tty_chars_in_buffer;
+
+	tty_register_driver (&tty_driver);
+}
+__initcall (memcons_tty_init);
diff -urN linux-2.4.29/arch/v850/kernel/process.c linux-2.4.29-uc1/arch/v850/kernel/process.c
--- linux-2.4.29/arch/v850/kernel/process.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/process.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,300 @@
+/*
+ * arch/v850/kernel/process.c -- Arch-dependent process handling
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/reboot.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS;
+struct mm_struct init_mm = INIT_MM (init_mm);
+
+union task_union init_task_union
+__attribute__ ((section (".data.init_task"), aligned (KERNEL_STACK_SIZE)))
+	= { task: INIT_TASK (init_task_union.task) };
+
+asmlinkage void ret_from_fork (void);
+
+
+/* The idle loop.  */
+static void default_idle (void)
+{
+	while (1) {
+		while (! current->need_resched)
+			asm ("halt; nop; nop; nop; nop; nop" ::: "cc");
+		schedule ();
+	}
+}
+
+void (*idle)(void) = default_idle;
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle (void)
+{
+	/* endless idle loop with no priority at all */
+	init_idle ();
+	current->nice = 20;
+	current->counter = -100;
+	(*idle) ();
+}
+
+struct spec_reg_name {
+	const char *name;
+	int gpr;
+};
+
+struct spec_reg_name spec_reg_names[] = {
+	{ "sp", GPR_SP },
+	{ "gp", GPR_GP },
+	{ "tp", GPR_TP },
+	{ "ep", GPR_EP },
+	{ "lp", GPR_LP },
+	{ 0, 0 }
+};
+
+void show_regs (struct pt_regs *regs)
+{
+	int gpr_base, gpr_offs;
+
+	printk ("     pc 0x%08lx    psw 0x%08lx                       kernel_mode %d\n",
+		regs->pc, regs->psw, regs->kernel_mode);
+	printk ("   ctpc 0x%08lx  ctpsw 0x%08lx   ctbp 0x%08lx\n",
+		regs->ctpc, regs->ctpsw, regs->ctbp);
+
+	for (gpr_base = 0; gpr_base < NUM_GPRS; gpr_base += 4) {
+		for (gpr_offs = 0; gpr_offs < 4; gpr_offs++) {
+			int gpr = gpr_base + gpr_offs;
+			long val = regs->gpr[gpr];
+			struct spec_reg_name *srn;
+
+			for (srn = spec_reg_names; srn->name; srn++)
+				if (srn->gpr == gpr)
+					break;
+
+			if (srn->name)
+				printk ("%7s 0x%08lx", srn->name, val);
+			else
+				printk ("    r%02d 0x%08lx", gpr, val);
+		}
+
+		printk ("\n");
+	}
+}
+
+/*
+ * This is the mechanism for creating a new kernel thread.
+ *
+ * NOTE! Only a kernel-only process (ie the swapper or direct descendants who
+ * haven't done an "execve()") should use this: it will work within a system
+ * call from a "real" process, but the process memory space will not be free'd
+ * until both the parent and the child have exited.
+ */
+int arch_kernel_thread (int (*fn)(void *), void *arg, unsigned long flags)
+{
+	register mm_segment_t fs = get_fs ();
+	register unsigned long syscall asm (SYSCALL_NUM);
+	register unsigned long arg0 asm (SYSCALL_ARG0);
+	register unsigned long ret asm (SYSCALL_RET);
+
+	set_fs (KERNEL_DS);
+
+	/* Clone this thread.  Note that we don't pass the clone syscall's
+	   second argument -- it's ignored for calls from kernel mode (the
+	   child's SP is always set to the top of the kernel stack).  */
+	arg0 = flags | CLONE_VM;
+	syscall = __NR_clone;
+	asm volatile ("trap " SYSCALL_SHORT_TRAP
+		      : "=r" (ret), "=r" (syscall)
+		      : "1" (syscall), "r" (arg0)
+		      : SYSCALL_SHORT_CLOBBERS);
+
+	if (ret == 0) {
+		/* In child thread, call FN and exit.  */
+		arg0 = (*fn) (arg);
+		syscall = __NR_exit;
+		asm volatile ("trap " SYSCALL_SHORT_TRAP
+			      : "=r" (ret), "=r" (syscall)
+			      : "1" (syscall), "r" (arg0)
+			      : SYSCALL_SHORT_CLOBBERS);
+	}
+
+	/* In parent.  */
+	set_fs (fs);
+
+	return ret;
+}
+
+void flush_thread (void)
+{
+	set_fs (USER_DS);
+}
+
+int copy_thread (int nr, unsigned long clone_flags,
+		 unsigned long stack_start, unsigned long stack_size,
+		 struct task_struct *p, struct pt_regs *regs)
+{
+	/* Start pushing stuff from the top of the child's kernel stack.  */
+	unsigned long orig_ksp = (unsigned long)p + KERNEL_STACK_SIZE;
+	unsigned long ksp = orig_ksp;
+	/* We push two `state save' stack fames (see entry.S) on the new
+	   kernel stack:
+	     1) The innermost one is what switch_thread would have
+	        pushed, and is used when we context switch to the child
+		thread for the first time.  It's set up to return to
+		ret_from_fork in entry.S.
+	     2) The outermost one (nearest the top) is what a syscall
+	        trap would have pushed, and is set up to return to the
+		same location as the parent thread, but with a return
+		value of 0. */
+	struct pt_regs *child_switch_regs, *child_trap_regs;
+
+	/* Trap frame.  */
+	ksp -= STATE_SAVE_SIZE;
+	child_trap_regs = (struct pt_regs *)(ksp + STATE_SAVE_PT_OFFSET);
+	/* Switch frame.  */
+	ksp -= STATE_SAVE_SIZE;
+	child_switch_regs = (struct pt_regs *)(ksp + STATE_SAVE_PT_OFFSET);
+
+	/* First copy parent's register state to child.  */
+	*child_switch_regs = *regs;
+	*child_trap_regs = *regs;
+
+	/* switch_thread returns to the restored value of the lp
+	   register (r31), so we make that the place where we want to
+	   jump when the child thread begins running.  */
+	child_switch_regs->gpr[GPR_LP] = (v850_reg_t)ret_from_fork;
+
+	if (regs->kernel_mode)
+		/* Since we're returning to kernel-mode, make sure the child's
+		   stored kernel stack pointer agrees with what the actual
+		   stack pointer will be at that point (the trap return code
+		   always restores the SP, even when returning to
+		   kernel-mode).  */
+		child_trap_regs->gpr[GPR_SP] = orig_ksp;
+	else
+		/* Set the child's user-mode stack-pointer (the name
+		   `stack_start' is a misnomer, it's just the initial SP
+		   value).  */
+		child_trap_regs->gpr[GPR_SP] = stack_start;
+
+	/* Thread state for the child (everything else is on the stack).  */
+	p->thread.ksp = ksp;
+
+	return 0;
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread (struct pt_regs *regs, struct user *dump)
+{
+#if 0  /* Later.  XXX */
+	dump->magic = CMAGIC;
+	dump->start_code = 0;
+	dump->start_stack = regs->gpr[GPR_SP];
+	dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
+	dump->u_dsize = ((unsigned long) (current->mm->brk +
+					  (PAGE_SIZE-1))) >> PAGE_SHIFT;
+	dump->u_dsize -= dump->u_tsize;
+	dump->u_ssize = 0;
+
+	if (dump->start_stack < TASK_SIZE)
+		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
+
+	dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump);
+	dump->regs = *regs;
+	dump->u_fpvalid = 0;
+#endif
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+int sys_execve (char *name, char **argv, char **envp, struct pt_regs *regs)
+{
+	char *filename = getname (name);
+	int error = PTR_ERR (filename);
+
+	if (! IS_ERR (filename)) {
+		error = do_execve (filename, argv, envp, regs);
+		putname (filename);
+	}
+
+	return error;
+}
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here (void);
+extern void scheduling_functions_end_here (void);
+#define first_sched	((unsigned long) scheduling_functions_start_here)
+#define last_sched	((unsigned long) scheduling_functions_end_here)
+
+unsigned long get_wchan (struct task_struct *p)
+{
+#if 0  /* Barf.  Figure out the stack-layout later.  XXX  */
+	unsigned long fp, pc;
+	int count = 0;
+
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	pc = thread_saved_pc (&p->thread);
+
+	/* This quite disgusting function walks up the stack, following
+	   saved return address, until it something that's out of bounds
+	   (as defined by `first_sched' and `last_sched').  It then
+	   returns the last PC that was in-bounds.  */
+	do {
+		if (fp < stack_page + sizeof (struct task_struct) ||
+		    fp >= 8184+stack_page)
+			return 0;
+		pc = ((unsigned long *)fp)[1];
+		/* FIXME: This depends on the order of these functions. */
+		if (pc < first_sched || pc >= last_sched)
+			return pc;
+		fp = *(unsigned long *) fp;
+	} while (count++ < 16);
+#endif
+
+	return 0;
+}
+
+void show_trace_task (struct task_struct *t)
+{
+        /* blarg XXX */
+	printk ("show_trace_task: KSP = 0x%lx, USP = 0x%lx, UPC = 0x%lx\n",
+		t->thread.ksp, KSTK_ESP (t), KSTK_EIP (t));
+}
diff -urN linux-2.4.29/arch/v850/kernel/procfs.c linux-2.4.29-uc1/arch/v850/kernel/procfs.c
--- linux-2.4.29/arch/v850/kernel/procfs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/procfs.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,67 @@
+/*
+ * arch/v850/kernel/procfs.c -- Introspection functions for /proc filesystem
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include "mach.h"
+
+static int cpuinfo_print (struct seq_file *m, void *v)
+{
+	extern unsigned long loops_per_jiffy;
+	
+	seq_printf (m, "CPU-Family:	v850\nCPU-Arch:	%s\n", CPU_ARCH);
+
+#ifdef CPU_MODEL_LONG
+	seq_printf (m, "CPU-Model:	%s (%s)\n", CPU_MODEL, CPU_MODEL_LONG);
+#else
+	seq_printf (m, "CPU-Model:	%s\n", CPU_MODEL);
+#endif
+
+#ifdef CPU_CLOCK_FREQ
+	seq_printf (m, "CPU-Clock:	%ld (%ld MHz)\n",
+		    (long)CPU_CLOCK_FREQ,
+		    (long)CPU_CLOCK_FREQ / 1000000);
+#endif
+
+	seq_printf (m, "BogoMips:	%lu.%02lu\n",
+		    loops_per_jiffy/(500000/HZ),
+		    (loops_per_jiffy/(5000/HZ)) % 100);
+
+#ifdef PLATFORM_LONG
+	seq_printf (m, "Platform:	%s (%s)\n", PLATFORM, PLATFORM_LONG);
+#elif defined (PLATFORM)
+	seq_printf (m, "Platform:	%s\n", PLATFORM);
+#endif
+
+	return 0;
+}
+
+static void *cpuinfo_start (struct seq_file *m, loff_t *pos)
+{
+	return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL;
+}
+
+static void *cpuinfo_next (struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return cpuinfo_start (m, pos);
+}
+
+static void cpuinfo_stop (struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+	.start	= cpuinfo_start,
+	.next	= cpuinfo_next,
+	.stop	= cpuinfo_stop,
+	.show	= cpuinfo_print
+};
diff -urN linux-2.4.29/arch/v850/kernel/ptrace.c linux-2.4.29-uc1/arch/v850/kernel/ptrace.c
--- linux-2.4.29/arch/v850/kernel/ptrace.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/ptrace.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,290 @@
+/*
+ * arch/v850/kernel/ptrace.c -- `ptrace' system call
+ *
+ *  Copyright (C) 2002,03  NEC Electronics Corporation
+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
+ *
+ * Derived from arch/mips/kernel/ptrace.c:
+ *
+ *  Copyright (C) 1992 Ross Biro
+ *  Copyright (C) Linus Torvalds
+ *  Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle
+ *  Copyright (C) 1996 David S. Miller
+ *  Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ *  Copyright (C) 1999 MIPS Technologies, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/ptrace.h>
+
+#include <asm/errno.h>
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+
+/* Returns the address where the register at REG_OFFS in P is stashed away.  */
+static v850_reg_t *reg_save_addr (unsigned reg_offs, struct task_struct *t)
+{
+	struct pt_regs *regs;
+
+	/* Three basic cases:
+
+	   (1) A register normally saved before calling the scheduler, is
+	       available in the kernel entry pt_regs structure at the top
+	       of the kernel stack.  The kernel trap/irq exit path takes
+	       care to save/restore almost all registers for ptrace'd
+	       processes.
+
+	   (2) A call-clobbered register, where the process P entered the
+	       kernel via [syscall] trap, is not stored anywhere; that's
+	       OK, because such registers are not expected to be preserved
+	       when the trap returns anyway (so we don't actually bother to
+	       test for this case).
+
+	   (3) A few registers not used at all by the kernel, and so
+	       normally never saved except by context-switches, are in the
+	       context switch state.  */
+
+	if (reg_offs == PT_CTPC || reg_offs == PT_CTPSW || reg_offs == PT_CTBP)
+		/* Register saved during context switch.  */
+		regs = thread_saved_regs (&t->thread);
+	else
+		/* Register saved during kernel entry (or not available).  */
+		regs = task_regs (t);
+
+	return (v850_reg_t *)((char *)regs + reg_offs);
+}
+
+/* Set the bits SET and clear the bits CLEAR in the v850e DIR
+   (`debug information register').  Returns the new value of DIR.  */
+static inline v850_reg_t set_dir (v850_reg_t set, v850_reg_t clear)
+{
+	register v850_reg_t rval asm ("r10");
+	register v850_reg_t arg0 asm ("r6") = set;
+	register v850_reg_t arg1 asm ("r7") = clear;
+
+	/* The dbtrap handler has exactly this functionality when called
+	   from kernel mode.  0xf840 is a `dbtrap' insn.  */
+	asm (".short 0xf840" : "=r" (rval) : "r" (arg0), "r" (arg1));
+
+	return rval;
+}
+
+/* Makes sure hardware single-stepping is (globally) enabled.
+   Returns true if successful.  */
+static inline int enable_single_stepping (void)
+{
+	static int enabled = 0;	/* Remember whether we already did it.  */
+	if (! enabled) {
+		/* Turn on the SE (`single-step enable') bit, 0x100, in the
+		   DIR (`debug information register').  This may fail if a
+		   processor doesn't support it or something.  We also try
+		   to clear bit 0x40 (`INI'), which is necessary to use the
+		   debug stuff on the v850e2; on the v850e, clearing 0x40
+		   shouldn't cause any problem.  */
+		v850_reg_t dir = set_dir (0x100, 0x40);
+		/* Make sure it really got set.  */
+		if (dir & 0x100)
+			enabled = 1;
+	}
+	return enabled;
+}
+
+/* Try to set CHILD's single-step flag to VAL.  Returns true if successful.  */
+static int set_single_step (struct task_struct *t, int val)
+{
+	v850_reg_t *psw_addr = reg_save_addr(PT_PSW, t);
+	if (val) {
+		/* Make sure single-stepping is enabled.  */
+		if (! enable_single_stepping ())
+			return 0;
+		/* Set T's single-step flag.  */
+		*psw_addr |= 0x800;
+	} else
+		*psw_addr &= ~0x800;
+	return 1;
+}
+
+int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	int rval;
+
+	lock_kernel();
+
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED) {
+			rval = -EPERM;
+			goto out;
+		}
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		rval = 0;
+		goto out;
+	}
+	rval = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		goto out;
+
+	rval = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out;
+
+	if (request == PTRACE_ATTACH) {
+		rval = ptrace_attach(child);
+		goto out_tsk;
+	}
+	rval = -ESRCH;
+	if (!(child->ptrace & PT_PTRACED))
+		goto out_tsk;
+	if (child->state != TASK_STOPPED) {
+		if (request != PTRACE_KILL)
+			goto out_tsk;
+	}
+	if (child->p_pptr != current)
+		goto out_tsk;
+
+	switch (request) {
+		unsigned long val, copied;
+
+	case PTRACE_PEEKTEXT: /* read word at location addr. */
+	case PTRACE_PEEKDATA:
+		copied = access_process_vm(child, addr, &val, sizeof(val), 0);
+		rval = -EIO;
+		if (copied != sizeof(val))
+			break;
+		rval = put_user(val, (unsigned long *)data);
+		goto out;
+
+	case PTRACE_POKETEXT: /* write the word at location addr. */
+	case PTRACE_POKEDATA:
+		rval = 0;
+		if (access_process_vm(child, addr, &data, sizeof(data), 1)
+		    == sizeof(data))
+			break;
+		rval = -EIO;
+		goto out;
+
+	/* Read/write the word at location ADDR in the registers.  */
+	case PTRACE_PEEKUSR:
+	case PTRACE_POKEUSR:
+		rval = 0;
+		if (addr >= PT_SIZE && request == PTRACE_PEEKUSR) {
+			/* Special requests that don't actually correspond
+			   to offsets in struct pt_regs.  */
+			if (addr == PT_TEXT_ADDR)
+				val = child->mm->start_code;
+			else if (addr == PT_DATA_ADDR)
+				val = child->mm->start_data;
+			else if (addr == PT_TEXT_LEN)
+				val = child->mm->end_code
+					- child->mm->start_code;
+			else
+				rval = -EIO;
+		} else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) {
+			v850_reg_t *reg_addr = reg_save_addr(addr, child);
+			if (request == PTRACE_PEEKUSR)
+				val = *reg_addr;
+			else
+				*reg_addr = data;
+		} else
+			rval = -EIO;
+
+		if (rval == 0 && request == PTRACE_PEEKUSR)
+			rval = put_user (val, (unsigned long *)data);
+		goto out;
+
+	/* Continue and stop at next (return from) syscall */
+	case PTRACE_SYSCALL:
+	/* Restart after a signal.  */
+	case PTRACE_CONT:
+	/* Execute a single instruction. */
+	case PTRACE_SINGLESTEP:
+		rval = -EIO;
+		if ((unsigned long) data > _NSIG)
+			break;
+
+		/* Turn CHILD's single-step flag on or off.  */
+		if (! set_single_step (child, request == PTRACE_SINGLESTEP))
+			break;
+
+		if (request == PTRACE_SYSCALL)
+			child->ptrace |= PT_TRACESYS;
+		else
+			child->ptrace &= ~PT_TRACESYS;
+
+		child->exit_code = data;
+		wake_up_process(child);
+		rval = 0;
+		break;
+
+	/*
+	 * make the child exit.  Best I can do is send it a sigkill.
+	 * perhaps it should be put in the status that it wants to
+	 * exit.
+	 */
+	case PTRACE_KILL:
+		rval = 0;
+		if (child->state == TASK_ZOMBIE)	/* already dead */
+			break;
+		child->exit_code = SIGKILL;
+		wake_up_process(child);
+		break;
+
+	case PTRACE_DETACH: /* detach a process that was attached. */
+		set_single_step (child, 0);  /* Clear single-step flag */
+		rval = ptrace_detach(child, data);
+		break;
+
+	default:
+		rval = -EIO;
+		goto out;
+	}
+
+out_tsk:
+	free_task_struct(child);
+out:
+	unlock_kernel();
+	return rval;
+}
+
+asmlinkage void syscall_trace(void)
+{
+	if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
+			!= (PT_PTRACED|PT_TRACESYS))
+		return;
+	/* The 0x80 provides a way for the tracing parent to distinguish
+	   between a syscall stop and SIGTRAP delivery */
+	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+					? 0x80 : 0);
+	current->state = TASK_STOPPED;
+	notify_parent(current, SIGCHLD);
+	schedule();
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+}
+
+void ptrace_disable (struct task_struct *child)
+{
+	/* nothing to do */
+}
diff -urN linux-2.4.29/arch/v850/kernel/rte_cb.c linux-2.4.29-uc1/arch/v850/kernel/rte_cb.c
--- linux-2.4.29/arch/v850/kernel/rte_cb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/rte_cb.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,196 @@
+/*
+ * include/asm-v850/rte_cb.c -- Midas lab RTE-CB series of evaluation boards
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/fs.h>
+#include <linux/major.h>
+
+#include <asm/machdep.h>
+#include <asm/v850e_uart.h>
+
+#include "mach.h"
+
+static void led_tick (void);
+
+/* LED access routines.  */
+extern unsigned read_leds (int pos, char *buf, int len);
+extern unsigned write_leds (int pos, const char *buf, int len);
+
+#ifdef CONFIG_RTE_CB_MULTI
+extern void multi_init (void);
+#endif
+
+
+void __init rte_cb_early_init (void)
+{
+	v850e_intc_disable_irqs ();
+
+#ifdef CONFIG_RTE_CB_MULTI
+	multi_init ();
+#endif
+}
+
+void __init mach_setup (char **cmdline)
+{
+#ifdef CONFIG_RTE_MB_A_PCI
+	/* Probe for Mother-A, and print a message if we find it.  */
+	*(volatile unsigned long *)MB_A_SRAM_ADDR = 0xDEADBEEF;
+	if (*(volatile unsigned long *)MB_A_SRAM_ADDR == 0xDEADBEEF) {
+		*(volatile unsigned long *)MB_A_SRAM_ADDR = 0x12345678;
+		if (*(volatile unsigned long *)MB_A_SRAM_ADDR == 0x12345678)
+			printk (KERN_INFO
+				"          NEC SolutionGear/Midas lab"
+				" RTE-MOTHER-A motherboard\n");
+	}
+#endif /* CONFIG_RTE_MB_A_PCI */
+
+	mach_tick = led_tick;
+
+	ROOT_DEV = MKDEV (BLKMEM_MAJOR, 0);
+}
+
+void machine_restart (char *__unused)
+{
+#ifdef CONFIG_RESET_GUARD
+	disable_reset_guard ();
+#endif
+	asm ("jmp r0"); /* Jump to the reset vector.  */
+}
+
+/* This says `HALt.' in LEDese.  */
+static unsigned char halt_leds_msg[] = { 0x76, 0x77, 0x38, 0xF8 };
+
+void machine_halt (void)
+{
+#ifdef CONFIG_RESET_GUARD
+	disable_reset_guard ();
+#endif
+
+	/* Ignore all interrupts.  */
+	local_irq_disable ();
+
+	/* Write a little message.  */
+	write_leds (0, halt_leds_msg, sizeof halt_leds_msg);
+
+	/* Really halt.  */
+	for (;;)
+		asm ("halt; nop; nop; nop; nop; nop");
+}
+
+void machine_power_off (void)
+{
+	machine_halt ();
+}
+
+
+/* Animated LED display for timer tick.  */
+
+#define TICK_UPD_FREQ	6
+static int tick_frames[][10] = {
+	{ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, -1 },
+	{ 0x63, 0x5c, -1 },
+	{ 0x5c, 0x00, -1 },
+	{ 0x63, 0x00, -1 },
+	{ -1 }
+};
+
+static void led_tick ()
+{
+	static unsigned counter = 0;
+	
+	if (++counter == (HZ / TICK_UPD_FREQ)) {
+		/* Which frame we're currently displaying for each digit.  */
+		static unsigned frame_nums[LED_NUM_DIGITS] = { 0 };
+		/* Display image.  */
+		static unsigned char image[LED_NUM_DIGITS] = { 0 };
+		unsigned char prev_image[LED_NUM_DIGITS];
+		int write_to_leds = 1; /* true if we should actually display */
+		int digit;
+
+		/* We check to see if the physical LEDs contains what we last
+		   wrote to them; if not, we suppress display (this is so that
+		   users can write to the LEDs, and not have their output
+		   overwritten).  As a special case, we start writing again if
+		   all the LEDs are blank, or our display image is all zeros
+		   (indicating that this is the initial update, when the actual
+		   LEDs might contain random data).  */
+		read_leds (0, prev_image, LED_NUM_DIGITS);
+		for (digit = 0; digit < LED_NUM_DIGITS; digit++)
+			if (image[digit] != prev_image[digit]
+			    && image[digit] && prev_image[digit])
+			{
+				write_to_leds = 0;
+				break;
+			}
+
+		/* Update display image.  */
+		for (digit = 0;
+		     digit < LED_NUM_DIGITS && tick_frames[digit][0] >= 0;
+		     digit++)
+		{
+			int frame = tick_frames[digit][frame_nums[digit]];
+			if (frame < 0) {
+				image[digit] = tick_frames[digit][0];
+				frame_nums[digit] = 1;
+			} else {
+				image[digit] = frame;
+				frame_nums[digit]++;
+				break;
+			}
+		}
+
+		if (write_to_leds)
+			/* Write the display image to the physical LEDs.  */
+			write_leds (0, image, LED_NUM_DIGITS);
+
+		counter = 0;
+	}
+}
+
+
+/* Mother-A interrupts.  */
+
+#ifdef CONFIG_RTE_GBUS_INT
+
+#define L GBUS_INT_PRIORITY_LOW
+#define M GBUS_INT_PRIORITY_MEDIUM
+#define H GBUS_INT_PRIORITY_HIGH
+
+static struct gbus_int_irq_init gbus_irq_inits[] = {
+#ifdef CONFIG_RTE_MB_A_PCI
+	{ "MB_A_LAN",	IRQ_MB_A_LAN,		1,		     1, L },
+	{ "MB_A_PCI1",	IRQ_MB_A_PCI1(0),	IRQ_MB_A_PCI1_NUM,   1, L },
+	{ "MB_A_PCI2",	IRQ_MB_A_PCI2(0),	IRQ_MB_A_PCI2_NUM,   1, L },
+	{ "MB_A_EXT",	IRQ_MB_A_EXT(0),	IRQ_MB_A_EXT_NUM,    1, L },
+	{ "MB_A_USB_OC",IRQ_MB_A_USB_OC(0),	IRQ_MB_A_USB_OC_NUM, 1, L },
+	{ "MB_A_PCMCIA_OC",IRQ_MB_A_PCMCIA_OC,	1,		     1, L },
+#endif
+	{ 0 }
+};
+#define NUM_GBUS_IRQ_INITS  \
+   ((sizeof gbus_irq_inits / sizeof gbus_irq_inits[0]) - 1)
+
+static struct hw_interrupt_type gbus_hw_itypes[NUM_GBUS_IRQ_INITS];
+
+#endif /* CONFIG_RTE_GBUS_INT */
+
+
+void __init rte_cb_init_irqs (void)
+{
+#ifdef CONFIG_RTE_GBUS_INT
+	gbus_int_init_irqs ();
+	gbus_int_init_irq_types (gbus_irq_inits, gbus_hw_itypes);
+#endif /* CONFIG_RTE_GBUS_INT */
+}
diff -urN linux-2.4.29/arch/v850/kernel/rte_cb_leds.c linux-2.4.29-uc1/arch/v850/kernel/rte_cb_leds.c
--- linux-2.4.29/arch/v850/kernel/rte_cb_leds.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/rte_cb_leds.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,138 @@
+/*
+ * include/asm-v850/rte_cb_leds.c -- Midas lab RTE-CB board LED device support
+ *
+ *  Copyright (C) 2002,03  NEC Electronics Corporation
+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+
+#include <asm/uaccess.h>
+
+#define LEDS_MINOR	169	/* Minor device number, using misc major.  */
+
+/* The actual LED hardware is write-only, so we hold the contents here too.  */
+static unsigned char leds_image[LED_NUM_DIGITS] = { 0 };
+
+/* Spinlock protecting the above leds.  */
+static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED;
+
+/* Common body of LED read/write functions, checks POS and LEN for
+   correctness, declares a variable using IMG_DECL, initialized pointing at
+   the POS position in the LED image buffer, and and iterates COPY_EXPR
+   until BUF is equal to the last buffer position; finally, sets LEN to be
+   the amount actually copied.  IMG should be a variable declaration
+   (without an initializer or a terminating semicolon); POS, BUF, and LEN
+   should all be simple variables.  */
+#define DO_LED_COPY(img_decl, pos, buf, len, copy_expr)			\
+do {									\
+	if (pos > LED_NUM_DIGITS)					\
+		len = 0;						\
+	else {								\
+		if (pos + len > LED_NUM_DIGITS)				\
+			len = LED_NUM_DIGITS - pos;			\
+									\
+		if (len > 0) {						\
+			int _flags;					\
+			const char *_end = buf + len;			\
+			img_decl = &leds_image[pos];			\
+									\
+			spin_lock_irqsave (leds_lock, _flags);		\
+			do						\
+				(copy_expr);				\
+			while (buf != _end);				\
+			spin_unlock_irqrestore (leds_lock, _flags);	\
+		}							\
+	}								\
+} while (0)
+
+/* Read LEN bytes from LEDs at position POS, into BUF.
+   Returns actual amount read.  */
+unsigned read_leds (unsigned pos, char *buf, unsigned len)
+{
+	DO_LED_COPY (const char *img, pos, buf, len, *buf++ = *img++);
+	return len;
+}
+
+/* Write LEN bytes to LEDs at position POS, from BUF.
+   Returns actual amount written.  */
+unsigned write_leds (unsigned pos, const char *buf, unsigned len)
+{
+	/* We write the actual LED values backwards, because
+	   increasing memory addresses reflect LEDs right-to-left. */
+	volatile char *led = &LED (LED_NUM_DIGITS - pos - 1);
+	/* We invert the value written to the hardware, because 1 = off,
+	   and 0 = on.  */
+	DO_LED_COPY (char *img, pos, buf, len,
+		     *led-- = 0xFF ^ (*img++ = *buf++));
+	return len;
+}
+
+
+/* Device functions.  */
+
+static ssize_t leds_dev_read (struct file *file, char *buf, size_t len,
+			      loff_t *pos)
+{
+	char temp_buf[LED_NUM_DIGITS];
+	len = read_leds (*pos, temp_buf, len);
+	if (copy_to_user (buf, temp_buf, len))
+		return -EFAULT;
+	*pos += len;
+	return len;
+}
+
+static ssize_t leds_dev_write (struct file *file, const char *buf, size_t len,
+			       loff_t *pos)
+{
+	char temp_buf[LED_NUM_DIGITS];
+	if (copy_from_user (temp_buf, buf, min_t(size_t, len, LED_NUM_DIGITS)))
+		return -EFAULT;
+	len = write_leds (*pos, temp_buf, len);
+	*pos += len;
+	return len;
+}
+
+static loff_t leds_dev_lseek (struct file *file, loff_t offs, int whence)
+{
+	if (whence == 1)
+		offs += file->f_pos; /* relative */
+	else if (whence == 2)
+		offs += LED_NUM_DIGITS; /* end-relative */
+
+	if (offs < 0 || offs > LED_NUM_DIGITS)
+		return -EINVAL;
+
+	file->f_pos = offs;
+
+	return 0;
+}
+
+static struct file_operations leds_fops = {
+	.read		= leds_dev_read,
+	.write		= leds_dev_write,
+	.llseek		= leds_dev_lseek
+};
+
+static struct miscdevice leds_miscdev = {
+	.name		= "leds",
+	.minor		= LEDS_MINOR,
+	.fops		= &leds_fops
+};
+
+int __init leds_dev_init (void)
+{
+	return misc_register (&leds_miscdev);
+}
+
+__initcall (leds_dev_init);
diff -urN linux-2.4.29/arch/v850/kernel/rte_cb_multi.c linux-2.4.29-uc1/arch/v850/kernel/rte_cb_multi.c
--- linux-2.4.29/arch/v850/kernel/rte_cb_multi.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/rte_cb_multi.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,121 @@
+/*
+ * include/asm-v850/rte_multi.c -- Support for Multi debugger monitor ROM
+ * 	on Midas lab RTE-CB series of evaluation boards
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/init.h>
+
+#include <asm/machdep.h>
+
+#define IRQ_ADDR(irq) (0x80 + (irq) * 0x10)
+
+/* A table of which interrupt vectors to install, since blindly
+   installing all of them makes the debugger stop working.  This is a
+   list of offsets in the interrupt vector area; each entry means to
+   copy that particular 16-byte vector.  An entry less than zero ends
+   the table.  */
+static long multi_intv_install_table[] = {
+	/* Trap vectors */
+	0x40, 0x50,		
+
+#ifdef CONFIG_RTE_CB_MULTI_DBTRAP
+	/* Illegal insn / dbtrap.  These are used by multi, so only handle
+	   them if configured to do so.  */
+	0x60,
+#endif
+
+	/* GINT1 - GINT3 (note, not GINT0!) */
+	IRQ_ADDR (IRQ_GINT(1)),
+	IRQ_ADDR (IRQ_GINT(2)),
+	IRQ_ADDR (IRQ_GINT(3)),
+
+	/* Timer D interrupts (up to 4 timers) */
+	IRQ_ADDR (IRQ_INTCMD(0)),
+#if IRQ_INTCMD_NUM > 1
+	IRQ_ADDR (IRQ_INTCMD(1)),
+#if IRQ_INTCMD_NUM > 2
+	IRQ_ADDR (IRQ_INTCMD(2)),
+#if IRQ_INTCMD_NUM > 3
+	IRQ_ADDR (IRQ_INTCMD(3)),
+#endif
+#endif
+#endif
+	
+	/* UART interrupts (up to 3 channels) */
+	IRQ_ADDR (IRQ_INTSER (0)), /* err */
+	IRQ_ADDR (IRQ_INTSR  (0)), /* rx */
+	IRQ_ADDR (IRQ_INTST  (0)), /* tx */
+#if IRQ_INTSR_NUM > 1
+	IRQ_ADDR (IRQ_INTSER (1)), /* err */
+	IRQ_ADDR (IRQ_INTSR  (1)), /* rx */
+	IRQ_ADDR (IRQ_INTST  (1)), /* tx */
+#if IRQ_INTSR_NUM > 2
+	IRQ_ADDR (IRQ_INTSER (2)), /* err */
+	IRQ_ADDR (IRQ_INTSR  (2)), /* rx */
+	IRQ_ADDR (IRQ_INTST  (2)), /* tx */
+#endif
+#endif
+
+	-1
+};
+
+/* Early initialization for kernel using Multi debugger ROM monitor.  */
+void __init multi_init (void)
+{
+	/* We're using the Multi debugger monitor, so we have to install
+	   the interrupt vectors.  The monitor doesn't allow them to be
+	   initially downloaded into their final destination because
+	   it's in the monitor's scratch-RAM area.  Unfortunately, Multi
+	   also doesn't deal correctly with ELF sections where the LMA
+	   and VMA differ -- it just ignores the LMA -- so we can't use
+	   that feature to work around the problem.  What we do instead
+	   is just put the interrupt vectors into a normal section, and
+	   do the necessary copying and relocation here.  Since the
+	   interrupt vector basically only contains `jr' instructions
+	   and no-ops, it's not that hard.  */
+	extern unsigned long _intv_load_start, _intv_start;
+	register unsigned long *src = &_intv_load_start;
+	register unsigned long *dst = (unsigned long *)INTV_BASE;
+	register unsigned long jr_fixup = (char *)&_intv_start - (char *)dst;
+	register long *ii;
+
+	/* Copy interrupt vectors as instructed by multi_intv_install_table. */
+	for (ii = multi_intv_install_table; *ii >= 0; ii++) {
+		/* Copy 16-byte interrupt vector at offset *ii.  */
+		int boffs;
+		for (boffs = 0; boffs < 0x10; boffs += sizeof *src) {
+			/* Copy a single word, fixing up the jump offs
+			   if it's a `jr' instruction.  */
+			int woffs = (*ii + boffs) / sizeof *src;
+			unsigned long word = src[woffs];
+
+			if ((word & 0xFC0) == 0x780) {
+				/* A `jr' insn, fix up its offset (and yes, the
+				   weird half-word swapping is intentional). */
+				unsigned short hi = word & 0xFFFF;
+				unsigned short lo = word >> 16;
+				unsigned long udisp22
+					= lo + ((hi & 0x3F) << 16);
+				long disp22 = (long)(udisp22 << 10) >> 10;
+
+				disp22 += jr_fixup;
+
+				hi = ((disp22 >> 16) & 0x3F) | 0x780;
+				lo = disp22 & 0xFFFF;
+
+				word = hi + (lo << 16);
+			}
+
+			dst[woffs] = word;
+		}
+	}
+}
diff -urN linux-2.4.29/arch/v850/kernel/rte_ma1_cb.c linux-2.4.29-uc1/arch/v850/kernel/rte_ma1_cb.c
--- linux-2.4.29/arch/v850/kernel/rte_ma1_cb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/rte_ma1_cb.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,116 @@
+/*
+ * arch/v850/kernel/rte_ma1_cb.c -- Midas labs RTE-V850E/MA1-CB board
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/ma1.h>
+#include <asm/rte_ma1_cb.h>
+#include <asm/v850e_timer_c.h>
+
+#include "mach.h"
+
+
+/* SRAM and SDRAM are almost contiguous (with a small hole in between;
+   see mach_reserve_bootmem for details), so just use both as one big area.  */
+#define RAM_START 	SRAM_ADDR
+#define RAM_END		(SDRAM_ADDR + SDRAM_SIZE)
+
+
+void __init mach_early_init (void)
+{
+	rte_cb_early_init ();
+}
+
+void __init mach_get_physical_ram (unsigned long *ram_start,
+				   unsigned long *ram_len)
+{
+	*ram_start = RAM_START;
+	*ram_len = RAM_END - RAM_START;
+}
+
+void __init mach_reserve_bootmem ()
+{
+	extern char _root_fs_image_start, _root_fs_image_end;
+	u32 root_fs_image_start = (u32)&_root_fs_image_start;
+	u32 root_fs_image_end = (u32)&_root_fs_image_end;
+
+#ifdef CONFIG_RTE_CB_MULTI
+	/* Prevent the kernel from touching the monitor's scratch RAM.  */
+	reserve_bootmem (MON_SCRATCH_ADDR, MON_SCRATCH_SIZE);
+#endif
+
+	/* The space between SRAM and SDRAM is filled with duplicate
+	   images of SRAM.  Prevent the kernel from using them.  */
+	reserve_bootmem (SRAM_ADDR + SRAM_SIZE,
+			 SDRAM_ADDR - (SRAM_ADDR + SRAM_SIZE));
+
+	/* Reserve the memory used by the root filesystem image if it's
+	   in RAM.  */
+	if (root_fs_image_start >= RAM_START && root_fs_image_start < RAM_END)
+		reserve_bootmem (root_fs_image_start,
+				 root_fs_image_end - root_fs_image_start);
+}
+
+void mach_gettimeofday (struct timeval *tv)
+{
+	tv->tv_sec = 0;
+	tv->tv_usec = 0;
+}
+
+/* Called before configuring an on-chip UART.  */
+void rte_ma1_cb_uart_pre_configure (unsigned chan,
+				    unsigned cflags, unsigned baud)
+{
+	/* The RTE-MA1-CB connects some general-purpose I/O pins on the
+	   CPU to the RTS/CTS lines of UART 0's serial connection.
+	   I/O pins P42 and P43 are RTS and CTS respectively.  */
+	if (chan == 0) {
+		/* Put P42 & P43 in I/O port mode.  */
+		MA_PORT4_PMC &= ~0xC;
+		/* Make P42 an output, and P43 an input.  */
+		MA_PORT4_PM = (MA_PORT4_PM & ~0xC) | 0x8;
+	}
+
+	/* Do pre-configuration for the actual UART.  */
+	ma_uart_pre_configure (chan, cflags, baud);
+}
+
+void __init mach_init_irqs (void)
+{
+	unsigned tc;
+
+	/* Initialize interrupts.  */
+	ma_init_irqs ();
+	rte_cb_init_irqs ();
+
+	/* Use falling-edge-sensitivity for interrupts .  */
+	V850E_TIMER_C_SESC (0) &= ~0xC;
+	V850E_TIMER_C_SESC (1) &= ~0xF;
+
+	/* INTP000-INTP011 are shared with `Timer C', so we have to set
+	   up Timer C to pass them through as raw interrupts.  */
+	for (tc = 0; tc < 2; tc++)
+		/* Turn on the timer.  */
+		V850E_TIMER_C_TMCC0 (tc) |= V850E_TIMER_C_TMCC0_CAE;
+
+	/* Make sure the relevant port0/port1 pins are assigned
+	   interrupt duty.  We used INTP001-INTP011 (don't screw with
+	   INTP000 because the monitor uses it).  */
+	MA_PORT0_PMC |= 0x4;	/* P02 (INTP001) in IRQ mode.  */
+	MA_PORT1_PMC |= 0x6;	/* P11 (INTP010) & P12 (INTP011) in IRQ mode.*/
+}
diff -urN linux-2.4.29/arch/v850/kernel/rte_ma1_cb.ld linux-2.4.29-uc1/arch/v850/kernel/rte_ma1_cb.ld
--- linux-2.4.29/arch/v850/kernel/rte_ma1_cb.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/rte_ma1_cb.ld	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,57 @@
+/* Linker script for the Midas labs RTE-V850E/MA1-CB evaluation board
+   (CONFIG_RTE_CB_MA1), with kernel in SDRAM, under Multi debugger.  */
+
+MEMORY {
+	/* 1MB of SRAM; we can't use the last 32KB, because it's used by
+	   the monitor scratch-RAM.  This memory is mirrored 4 times.  */
+	SRAM  : ORIGIN = SRAM_ADDR,  LENGTH = (SRAM_SIZE - MON_SCRATCH_SIZE)
+	/* Monitor scratch RAM; only the interrupt vectors should go here.  */
+	MRAM  : ORIGIN = MON_SCRATCH_ADDR,  LENGTH = MON_SCRATCH_SIZE
+	/* 32MB of SDRAM.  */
+	SDRAM : ORIGIN = SDRAM_ADDR, LENGTH = SDRAM_SIZE
+}
+
+#ifdef CONFIG_RTE_CB_MA1_KSRAM
+# define KRAM SRAM
+#else
+# define KRAM SDRAM
+#endif
+
+SECTIONS {
+	/* We can't use RAMK_KRAM_CONTENTS because that puts the whole
+	   kernel in a single ELF segment, and the Multi debugger (which
+	   we use to load the kernel) appears to have bizarre problems
+	   dealing with it.  */
+
+	.text : {
+		__kram_start = . ;
+		TEXT_CONTENTS
+	} > KRAM
+
+	.data : {
+		DATA_CONTENTS
+		BSS_CONTENTS
+		RAMK_INIT_CONTENTS
+		__kram_end = . ;
+		BOOTMAP_CONTENTS
+
+		/* The address at which the interrupt vectors are initially
+		   loaded by the loader.  We can't load the interrupt vectors
+		   directly into their target location, because the monitor
+		   ROM for the GHS Multi debugger barfs if we try.
+		   Unfortunately, Multi also doesn't deal correctly with ELF
+		   sections where the LMA and VMA differ (it just ignores the
+		   LMA), so we can't use that feature to work around the
+		   problem!  What we do instead is just put the interrupt
+		   vectors into a normal section, and have the
+		   `mach_early_init' function for Midas boards do the
+		   necessary copying and relocation at runtime (this section
+		   basically only contains `jr' instructions, so it's not
+		   that hard).  */
+		. = ALIGN (0x10) ;
+		__intv_load_start = . ;
+		INTV_CONTENTS
+	} > KRAM
+
+	.root ALIGN (4096) : { ROOT_FS_CONTENTS } > SDRAM
+}
diff -urN linux-2.4.29/arch/v850/kernel/rte_ma1_cb-rom.ld linux-2.4.29-uc1/arch/v850/kernel/rte_ma1_cb-rom.ld
--- linux-2.4.29/arch/v850/kernel/rte_ma1_cb-rom.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/rte_ma1_cb-rom.ld	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,14 @@
+/* Linker script for the Midas labs RTE-V850E/MA1-CB evaluation board
+   (CONFIG_RTE_CB_MA1), with kernel in ROM.  */
+
+MEMORY {
+	ROM   : ORIGIN = 0x00000000, LENGTH = 0x00100000
+	/* 1MB of SRAM.  This memory is mirrored 4 times.  */
+	SRAM  : ORIGIN = SRAM_ADDR,  LENGTH = SRAM_SIZE
+	/* 32MB of SDRAM.  */
+	SDRAM : ORIGIN = SDRAM_ADDR, LENGTH = SDRAM_SIZE
+}
+
+SECTIONS {
+	ROMK_SECTIONS(ROM, SRAM)
+}
diff -urN linux-2.4.29/arch/v850/kernel/rte_mb_a_pci.c linux-2.4.29-uc1/arch/v850/kernel/rte_mb_a_pci.c
--- linux-2.4.29/arch/v850/kernel/rte_mb_a_pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/rte_mb_a_pci.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,790 @@
+/*
+ * arch/v850/kernel/mb_a_pci.c -- PCI support for Midas lab RTE-MOTHER-A board
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/pci.h>
+
+#include <asm/machdep.h>
+
+/* __nomods_init is like __devinit, but is a no-op when modules are enabled.
+   This is used by some routines that can be called either during boot
+   or by a module.  */
+#ifdef CONFIG_MODULES
+#define __nomods_init /*nothing*/
+#else
+#define __nomods_init __devinit
+#endif
+
+/* PCI devices on the Mother-A board can only do DMA to/from the MB SRAM
+   (the RTE-V850E/MA1-CB cpu board doesn't support PCI access to
+   CPU-board memory), and since linux DMA buffers are allocated in
+   normal kernel memory, we basically have to copy DMA blocks around
+   (this is like a `bounce buffer').  When a DMA block is `mapped', we
+   allocate an identically sized block in MB SRAM, and if we're doing
+   output to the device, copy the CPU-memory block to the MB-SRAM block.
+   When an active block is `unmapped', we will copy the block back to
+   CPU memory if necessary, and then deallocate the MB SRAM block.
+   Ack.  */
+
+/* Where the motherboard SRAM is in the PCI-bus address space (the
+   first 512K of it is also mapped at PCI address 0).  */
+#define PCI_MB_SRAM_ADDR 0x800000
+
+/* Convert CPU-view MB SRAM address to/from PCI-view addresses of the
+   same memory.  */
+#define MB_SRAM_TO_PCI(mb_sram_addr) \
+   ((dma_addr_t)mb_sram_addr - MB_A_SRAM_ADDR + PCI_MB_SRAM_ADDR)
+#define PCI_TO_MB_SRAM(pci_addr)     \
+   (void *)(pci_addr - PCI_MB_SRAM_ADDR + MB_A_SRAM_ADDR)
+
+static void pcibios_assign_resources (void);
+
+struct mb_pci_dev_irq {
+	unsigned dev;		/* PCI device number */
+	unsigned irq_base;	/* First IRQ  */
+	unsigned query_pin;	/* True if we should read the device's
+				   Interrupt Pin info, and allocate
+				   interrupt IRQ_BASE + PIN.  */
+};
+
+/* PCI interrupts are mapped statically to GBUS interrupts.  */
+static struct mb_pci_dev_irq mb_pci_dev_irqs[] = {
+	/* Motherboard SB82558 ethernet controller */
+	{ 10,	IRQ_MB_A_LAN,		0 },
+	/* PCI slot 1 */
+	{ 8, 	IRQ_MB_A_PCI1(0),	1 },
+	/* PCI slot 2 */
+	{ 9, 	IRQ_MB_A_PCI2(0),	1 }
+};
+#define NUM_MB_PCI_DEV_IRQS \
+  (sizeof mb_pci_dev_irqs / sizeof mb_pci_dev_irqs[0])
+
+
+/* PCI configuration primitives.  */
+
+#define CONFIG_DMCFGA(dev, offs)					      \
+   (0x80000000								      \
+    | ((offs) & ~0x3)							      \
+    | ((dev)->devfn << 8)						      \
+    | ((dev)->bus->number << 16))
+
+#define DEF_MB_PCI_READ_CONFIG_OP(pci_type, c_type)			      \
+static int								      \
+mb_pci_read_config_ ## pci_type (struct pci_dev *dev, int offs, c_type *rval) \
+{									      \
+	int flags;							      \
+	save_flags_cli (flags);						      \
+									      \
+	MB_A_PCI_PCICR = 0x7;						      \
+	MB_A_PCI_DMCFGA = CONFIG_DMCFGA (dev, offs);			      \
+									      \
+	*rval = *(volatile c_type *)(MB_A_PCI_IO_ADDR + (offs & 0x3));	      \
+									      \
+        if (MB_A_PCI_PCISR & 0x2000) {					      \
+		MB_A_PCI_PCISR = 0x2000;				      \
+		*rval = ~0;						      \
+        }								      \
+									      \
+	MB_A_PCI_DMCFGA = 0;						      \
+									      \
+	restore_flags (flags);						      \
+									      \
+	return PCIBIOS_SUCCESSFUL;					      \
+}
+
+#define DEF_MB_PCI_WRITE_CONFIG_OP(pci_type, c_type)			      \
+static int								      \
+mb_pci_write_config_ ## pci_type (struct pci_dev *dev, int offs, c_type val)  \
+{									      \
+	int flags;							      \
+	save_flags_cli (flags);						      \
+									      \
+	MB_A_PCI_PCICR = 0x7;						      \
+	MB_A_PCI_DMCFGA = CONFIG_DMCFGA (dev, offs);			      \
+									      \
+	*(volatile c_type *)(MB_A_PCI_IO_ADDR + (offs & 0x3)) = val;	      \
+									      \
+        if (MB_A_PCI_PCISR & 0x2000)					      \
+		MB_A_PCI_PCISR = 0x2000;				      \
+									      \
+	MB_A_PCI_DMCFGA = 0;						      \
+									      \
+	restore_flags (flags);						      \
+									      \
+	return PCIBIOS_SUCCESSFUL;					      \
+}
+
+DEF_MB_PCI_READ_CONFIG_OP (byte, u8);
+DEF_MB_PCI_WRITE_CONFIG_OP (byte, u8);
+DEF_MB_PCI_READ_CONFIG_OP (word, u16);
+DEF_MB_PCI_WRITE_CONFIG_OP (word, u16);
+DEF_MB_PCI_READ_CONFIG_OP (dword, u32);
+DEF_MB_PCI_WRITE_CONFIG_OP (dword, u32);
+
+static struct pci_ops mb_pci_config_ops = {
+	mb_pci_read_config_byte,
+	mb_pci_read_config_word,
+	mb_pci_read_config_dword,
+	mb_pci_write_config_byte,
+	mb_pci_write_config_word,
+	mb_pci_write_config_dword
+};
+
+
+/* PCI Initialization.  */
+
+static struct pci_bus *mb_pci_bus = 0;
+
+/* Do initial PCI setup.  */
+void __devinit pcibios_init (void)
+{
+	u32 id = MB_A_PCI_PCIHIDR;
+	u16 vendor = id & 0xFFFF;
+	u16 device = (id >> 16) & 0xFFFF;
+
+	if (vendor == PCI_VENDOR_ID_PLX && device == PCI_DEVICE_ID_PLX_9080) {
+		printk (KERN_INFO
+			"PCI: PLX Technology PCI9080 HOST/PCI bridge\n");
+
+		MB_A_PCI_PCICR = 0x147;
+
+		MB_A_PCI_PCIBAR0 = 0x007FFF00;
+		MB_A_PCI_PCIBAR1 = 0x0000FF00;
+		MB_A_PCI_PCIBAR2 = 0x00800000;
+
+		MB_A_PCI_PCILTR = 0x20;
+
+		MB_A_PCI_PCIPBAM |= 0x3;
+
+		MB_A_PCI_PCISR =  ~0; /* Clear errors.  */
+
+		/* Reprogram the motherboard's IO/config address space,
+		   as we don't support the GCS7 address space that the
+		   default uses.  */
+
+		/* Significant address bits used for decoding PCI GCS5 space
+		   accessess.  */
+		MB_A_PCI_DMRR = ~(MB_A_PCI_MEM_SIZE - 1);
+
+		/* I don't understand this, but the SolutionGear example code
+		   uses such an offset, and it doesn't work without it.  XXX */
+#if GCS5_SIZE == 0x00800000
+#define GCS5_CFG_OFFS 0x00800000
+#else
+#define GCS5_CFG_OFFS 0
+#endif
+
+		/* Address bit values for matching.  Note that we have to give
+		   the address from the motherboard's point of view, which is
+		   different than the CPU's.  */
+		/* PCI memory space.  */
+		MB_A_PCI_DMLBAM = GCS5_CFG_OFFS + 0x0;
+		/* PCI I/O space.  */
+		MB_A_PCI_DMLBAI =
+			GCS5_CFG_OFFS + (MB_A_PCI_IO_ADDR - GCS5_ADDR);
+
+		mb_pci_bus = pci_scan_bus (0, &mb_pci_config_ops, 0);
+
+		pcibios_assign_resources ();
+	} else
+		printk (KERN_ERR "PCI: HOST/PCI bridge not found\n");
+}
+
+char __devinit *pcibios_setup (char *option)
+{
+	/* Don't handle any options. */
+	return option;
+}
+
+
+int __nomods_init pcibios_enable_device (struct pci_dev *dev, int mask)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for (idx = 0; idx < 6; idx++) {
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR "PCI: Device %s not available because "
+			       "of resource collisions\n", dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (cmd != old_cmd) {
+		printk("PCI: Enabling device %s (%04x -> %04x)\n",
+		       dev->slot_name, old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+
+/* Resource allocation.  */
+static void __devinit pcibios_assign_resources (void)
+{
+	struct pci_dev *dev;
+	struct resource *r;
+
+	pci_for_each_dev (dev) {
+		unsigned di_num;
+		unsigned class = dev->class >> 8;
+
+		if (class && class != PCI_CLASS_BRIDGE_HOST) {
+			unsigned r_num;
+			for(r_num = 0; r_num < 6; r_num++) {
+				r = &dev->resource[r_num];
+				if (!r->start && r->end)
+					pci_assign_resource (dev, r_num);
+			}
+		}
+
+		/* Assign interrupts.  */
+		for (di_num = 0; di_num < NUM_MB_PCI_DEV_IRQS; di_num++) {
+			struct mb_pci_dev_irq *di = &mb_pci_dev_irqs[di_num];
+
+			if (di->dev == PCI_SLOT (dev->devfn)) {
+				unsigned irq = di->irq_base;
+
+				if (di->query_pin) {
+					/* Find out which interrupt pin
+					   this device uses (each PCI
+					   slot has 4).  */
+					u8 irq_pin;
+
+					pci_read_config_byte (dev,
+							     PCI_INTERRUPT_PIN,
+							      &irq_pin);
+
+					if (irq_pin == 0)
+						/* Doesn't use interrupts.  */ 
+						continue;
+					else
+						irq += irq_pin - 1;
+				}
+
+				pcibios_update_irq (dev, irq);
+			}
+		}
+	}
+}
+
+void __devinit pcibios_update_irq (struct pci_dev *dev, int irq)
+{
+	dev->irq = irq;
+	pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
+}
+
+void __nomods_init
+pcibios_update_resource (struct pci_dev *dev, struct resource *root,
+			 struct resource *r, int resource)
+{
+	u32 new, check;
+	int reg;
+
+	if (r->flags & IORESOURCE_IO)
+		new = (((r->start - MB_A_PCI_IO_ADDR)
+			& PCI_BASE_ADDRESS_IO_MASK)
+		       | PCI_BASE_ADDRESS_SPACE_IO);
+	else if (r->flags & IORESOURCE_MEM)
+		new = (((r->start - MB_A_PCI_MEM_ADDR)
+			& PCI_BASE_ADDRESS_MEM_MASK)
+		       | PCI_BASE_ADDRESS_MEM_TYPE_32
+		       | ((r->flags & IORESOURCE_PREFETCH)
+			  ? PCI_BASE_ADDRESS_MEM_PREFETCH
+			  : 0)
+		       | PCI_BASE_ADDRESS_SPACE_MEMORY);
+	else
+		panic ("pcibios_update_resource: unknown resource type");
+
+	if (resource < 6)
+		reg = PCI_BASE_ADDRESS_0 + 4*resource;
+	else if (resource == PCI_ROM_RESOURCE) {
+		r->flags |= PCI_ROM_ADDRESS_ENABLE;
+		new |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else
+		return;
+	
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
+		printk (KERN_ERR "PCI: Error while updating region "
+			"%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+			new, check);
+	}
+}
+
+
+/* Stubs for things we don't use.  */
+
+struct pci_fixup pcibios_fixups[] = { { 0 } };
+
+/* Called after each bus is probed, but before its children are examined. */
+void pcibios_fixup_bus(struct pci_bus *b)
+{
+}
+
+void
+pcibios_align_resource (void *data, struct resource *res,
+			unsigned long size, unsigned long align)
+{
+}
+
+void pcibios_set_master (struct pci_dev *dev)
+{
+}
+
+
+/* Mother-A SRAM memory allocation.  This is a simple first-fit allocator.  */
+
+/* A memory free-list node.  */
+struct mb_sram_free_area {
+	void *mem;
+	unsigned long size;
+	struct mb_sram_free_area *next;
+};
+
+/* The tail of the free-list, which starts out containing all the SRAM.  */
+static struct mb_sram_free_area mb_sram_free_tail = {
+	(void *)MB_A_SRAM_ADDR, MB_A_SRAM_SIZE, 0
+};
+
+/* The free-list.  */
+static struct mb_sram_free_area *mb_sram_free_areas = &mb_sram_free_tail;
+
+/* The free-list of free free-list nodes. (:-)  */
+static struct mb_sram_free_area *mb_sram_free_free_areas = 0;
+
+/* Spinlock protecting the above globals.  */
+static spinlock_t mb_sram_lock = SPIN_LOCK_UNLOCKED;
+
+/* Allocate a memory block at least SIZE bytes long in the Mother-A SRAM
+   space.  */
+static void *alloc_mb_sram (size_t size)
+{
+	struct mb_sram_free_area *prev, *fa;
+	int flags;
+	void *mem = 0;
+
+	spin_lock_irqsave (mb_sram_lock, flags);
+
+	/* Look for a free area that can contain SIZE bytes.  */
+	for (prev = 0, fa = mb_sram_free_areas; fa; prev = fa, fa = fa->next)
+		if (fa->size >= size) {
+			/* Found one!  */
+			mem = fa->mem;
+
+			if (fa->size == size) {
+				/* In fact, it fits exactly, so remove
+				   this node from the free-list.  */
+				if (prev)
+					prev->next = fa->next;
+				else
+					mb_sram_free_areas = fa->next;
+				/* Put it on the free-list-entry-free-list. */
+				fa->next = mb_sram_free_free_areas;
+				mb_sram_free_free_areas = fa;
+			} else {
+				/* FA is bigger than SIZE, so just
+				   reduce its size to account for this
+				   allocation.  */
+				fa->mem += size;
+				fa->size -= size;
+			}
+
+			break;
+		}
+
+	spin_unlock_irqrestore (mb_sram_lock, flags);
+
+	return mem;
+}
+
+/* Return the memory area MEM of size SIZE to the MB SRAM free pool.  */
+static void free_mb_sram (void *mem, size_t size)
+{
+	struct mb_sram_free_area *prev, *fa, *new_fa;
+	int flags;
+	void *end = mem + size;
+
+	spin_lock_irqsave (mb_sram_lock, flags);
+
+ retry:
+	/* Find an adjacent free-list entry.  */
+	for (prev = 0, fa = mb_sram_free_areas; fa; prev = fa, fa = fa->next)
+		if (fa->mem == end) {
+			/* FA is just after MEM, grow down to encompass it. */
+			fa->mem = mem;
+			fa->size += size;
+			goto done;
+		} else if (fa->mem + fa->size == mem) {
+			struct mb_sram_free_area *next_fa = fa->next;
+
+			/* FA is just before MEM, expand to encompass it. */
+			fa->size += size;
+
+			/* See if FA can now be merged with its successor. */
+			if (next_fa && fa->mem + fa->size == next_fa->mem) {
+				/* Yup; merge NEXT_FA's info into FA.  */
+				fa->size += next_fa->size;
+				fa->next = next_fa->next;
+				/* Free NEXT_FA.  */
+				next_fa->next = mb_sram_free_free_areas;
+				mb_sram_free_free_areas = next_fa;
+			}
+			goto done;
+		} else if (fa->mem > mem)
+			/* We've reached the right spot in the free-list
+			   without finding an adjacent free-area, so add
+			   a new free area to hold mem. */
+			break;
+
+	/* Make a new free-list entry.  */
+
+	/* First, get a free-list entry.  */
+	if (! mb_sram_free_free_areas) {
+		/* There are none, so make some.  */
+		void *block;
+		size_t block_size = sizeof (struct mb_sram_free_area) * 8;
+
+		/* Don't hold the lock while calling kmalloc (I'm not
+		   sure whether it would be a problem, since we use
+		   GFP_ATOMIC, but it makes me nervous).  */
+		spin_unlock_irqrestore (mb_sram_lock, flags);
+
+		block = kmalloc (block_size, GFP_ATOMIC);
+		if (! block)
+			panic ("free_mb_sram: can't allocate free-list entry");
+
+		/* Now get the lock back.  */
+		spin_lock_irqsave (mb_sram_lock, flags);
+
+		/* Add the new free free-list entries.  */
+		while (block_size > 0) {
+			struct mb_sram_free_area *nfa = block;
+			nfa->next = mb_sram_free_free_areas;
+			mb_sram_free_free_areas = nfa;
+			block += sizeof *nfa;
+			block_size -= sizeof *nfa;
+		}
+
+		/* Since we dropped the lock to call kmalloc, the
+		   free-list could have changed, so retry from the
+		   beginning.  */
+		goto retry;
+	}
+
+	/* Remove NEW_FA from the free-list of free-list entries.  */
+	new_fa = mb_sram_free_free_areas;
+	mb_sram_free_free_areas = new_fa->next;
+
+	/* NEW_FA initially holds only MEM.  */
+	new_fa->mem = mem;
+	new_fa->size = size;
+
+	/* Insert NEW_FA in the free-list between PREV and FA. */
+	new_fa->next = fa;
+	if (prev)
+		prev->next = new_fa;
+	else
+		mb_sram_free_areas = new_fa;
+
+ done:
+	spin_unlock_irqrestore (mb_sram_lock, flags);
+}
+
+
+/* Maintainence of CPU -> Mother-A DMA mappings.  */
+
+struct dma_mapping {
+	void *cpu_addr;
+	void *mb_sram_addr;
+	size_t size;
+	struct dma_mapping *next;
+};
+
+/* A list of mappings from CPU addresses to MB SRAM addresses for active
+   DMA blocks (that have been `granted' to the PCI device).  */
+static struct dma_mapping *active_dma_mappings = 0;
+
+/* A list of free mapping objects.  */
+static struct dma_mapping *free_dma_mappings = 0;
+
+/* Spinlock protecting the above globals.  */
+static spinlock_t dma_mappings_lock = SPIN_LOCK_UNLOCKED;
+
+static struct dma_mapping *new_dma_mapping (size_t size)
+{
+	int flags;
+	struct dma_mapping *mapping;
+	void *mb_sram_block = alloc_mb_sram (size);
+
+	if (! mb_sram_block)
+		return 0;
+
+	spin_lock_irqsave (dma_mappings_lock, flags);
+
+	if (! free_dma_mappings) {
+		/* We're out of mapping structures, make more.  */
+		void *mblock;
+		size_t mblock_size = sizeof (struct dma_mapping) * 8;
+
+		/* Don't hold the lock while calling kmalloc (I'm not
+		   sure whether it would be a problem, since we use
+		   GFP_ATOMIC, but it makes me nervous).  */
+		spin_unlock_irqrestore (dma_mappings_lock, flags);
+
+		mblock = kmalloc (mblock_size, GFP_ATOMIC);
+		if (! mblock) {
+			free_mb_sram (mb_sram_block, size);
+			return 0;
+		}
+
+		/* Get the lock back.  */
+		spin_lock_irqsave (dma_mappings_lock, flags);
+
+		/* Add the new mapping structures to the free-list.  */
+		while (mblock_size > 0) {
+			struct dma_mapping *fm = mblock;
+			fm->next = free_dma_mappings;
+			free_dma_mappings = fm;
+			mblock += sizeof *fm;
+			mblock_size -= sizeof *fm;
+		}
+	}
+
+	/* Get a mapping struct from the freelist.  */
+	mapping = free_dma_mappings;
+	free_dma_mappings = mapping->next;
+
+	/* Initialize the mapping.  Other fields should be filled in by
+	   caller.  */
+	mapping->mb_sram_addr = mb_sram_block;
+	mapping->size = size;
+
+	/* Add it to the list of active mappings.  */
+	mapping->next = active_dma_mappings;
+	active_dma_mappings = mapping;
+
+	spin_unlock_irqrestore (dma_mappings_lock, flags);
+
+	return mapping;
+}
+
+static struct dma_mapping *find_dma_mapping (void *mb_sram_addr)
+{
+	int flags;
+	struct dma_mapping *mapping;
+
+	spin_lock_irqsave (dma_mappings_lock, flags);
+
+	for (mapping = active_dma_mappings; mapping; mapping = mapping->next)
+		if (mapping->mb_sram_addr == mb_sram_addr) {
+			spin_unlock_irqrestore (dma_mappings_lock, flags);
+			return mapping;
+		}
+
+	panic ("find_dma_mapping: unmapped PCI DMA addr 0x%x",
+	       MB_SRAM_TO_PCI (mb_sram_addr));
+}
+
+static struct dma_mapping *deactivate_dma_mapping (void *mb_sram_addr)
+{
+	int flags;
+	struct dma_mapping *mapping, *prev;
+
+	spin_lock_irqsave (dma_mappings_lock, flags);
+
+	for (prev = 0, mapping = active_dma_mappings;
+	     mapping;
+	     prev = mapping, mapping = mapping->next)
+	{
+		if (mapping->mb_sram_addr == mb_sram_addr) {
+			/* This is the MAPPING; deactivate it.  */
+			if (prev)
+				prev->next = mapping->next;
+			else
+				active_dma_mappings = mapping->next;
+
+			spin_unlock_irqrestore (dma_mappings_lock, flags);
+
+			return mapping;
+		}
+	}
+
+	panic ("deactivate_dma_mapping: unmapped PCI DMA addr 0x%x",
+	       MB_SRAM_TO_PCI (mb_sram_addr));
+}
+
+/* Return MAPPING to the freelist.  */
+static inline void
+free_dma_mapping (struct dma_mapping *mapping)
+{
+	int flags;
+
+	free_mb_sram (mapping->mb_sram_addr, mapping->size);
+
+	spin_lock_irqsave (dma_mappings_lock, flags);
+
+	mapping->next = free_dma_mappings;
+	free_dma_mappings = mapping;
+
+	spin_unlock_irqrestore (dma_mappings_lock, flags);
+}
+
+
+/* Single PCI DMA mappings.  */
+
+/* `Grant' to PDEV the memory block at CPU_ADDR, for doing DMA.  The
+   32-bit PCI bus mastering address to use is returned.  the device owns
+   this memory until either pci_unmap_single or pci_dma_sync_single is
+   performed.  */
+dma_addr_t
+pci_map_single (struct pci_dev *pdev, void *cpu_addr, size_t size, int dir)
+{
+	struct dma_mapping *mapping = new_dma_mapping (size);
+
+	if (! mapping)
+		return 0;
+
+	mapping->cpu_addr = cpu_addr;
+
+	if (dir == PCI_DMA_BIDIRECTIONAL || dir == PCI_DMA_TODEVICE)
+		memcpy (mapping->mb_sram_addr, cpu_addr, size);
+
+	return MB_SRAM_TO_PCI (mapping->mb_sram_addr);
+}
+
+/* Return to the CPU the PCI DMA memory block previously `granted' to
+   PDEV, at DMA_ADDR.  */
+void pci_unmap_single (struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
+		       int dir)
+{
+	void *mb_sram_addr = PCI_TO_MB_SRAM (dma_addr);
+	struct dma_mapping *mapping = deactivate_dma_mapping (mb_sram_addr);
+
+	if (size != mapping->size)
+		panic ("pci_unmap_single: size (%d) doesn't match"
+		       " size of mapping at PCI DMA addr 0x%x (%d)\n",
+		       size, dma_addr, mapping->size);
+
+	/* Copy back the DMA'd contents if necessary.  */
+	if (dir == PCI_DMA_BIDIRECTIONAL || dir == PCI_DMA_FROMDEVICE)
+		memcpy (mapping->cpu_addr, mb_sram_addr, size);
+
+	/* Return mapping to the freelist.  */
+	free_dma_mapping (mapping);
+}
+
+/* Make physical memory consistent for a single streaming mode DMA
+   translation after a transfer.
+
+   If you perform a pci_map_single() but wish to interrogate the
+   buffer using the cpu, yet do not wish to teardown the PCI dma
+   mapping, you must call this function before doing so.  At the next
+   point you give the PCI dma address back to the card, the device
+   again owns the buffer.  */
+void
+pci_dma_sync_single (struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
+		     int dir)
+{
+	void *mb_sram_addr = PCI_TO_MB_SRAM (dma_addr);
+	struct dma_mapping *mapping = find_dma_mapping (mb_sram_addr);
+
+	/* Synchronize the DMA buffer with the CPU buffer if necessary.  */
+	if (dir == PCI_DMA_FROMDEVICE)
+		memcpy (mapping->cpu_addr, mb_sram_addr, size);
+	else if (dir == PCI_DMA_TODEVICE)
+		memcpy (mb_sram_addr, mapping->cpu_addr, size);
+	else
+		panic("pci_dma_sync_single: unsupported sync dir: %d", dir);
+}
+
+
+/* Scatter-gather PCI DMA mappings.  */
+
+/* Do multiple DMA mappings at once.  */
+int
+pci_map_sg (struct pci_dev *pdev, struct scatterlist *sg, int sg_len, int dir)
+{
+	BUG ();
+	return 0;
+}
+
+/* Unmap multiple DMA mappings at once.  */
+void
+pci_unmap_sg (struct pci_dev *pdev, struct scatterlist *sg, int sg_len,int dir)
+{
+	BUG ();
+}
+
+/* Make physical memory consistent for a set of streaming mode DMA
+   translations after a transfer.  The same as pci_dma_sync_single but
+   for a scatter-gather list, same rules and usage.  */
+
+void
+pci_dma_sync_sg (struct pci_dev *dev, struct scatterlist *sg, int sg_len,
+		 int dir)
+{
+	BUG ();
+}
+
+
+/* PCI mem mapping.  */
+
+/* Allocate and map kernel buffer using consistent mode DMA for PCI
+   device.  Returns non-NULL cpu-view pointer to the buffer if
+   successful and sets *DMA_ADDR to the pci side dma address as well,
+   else DMA_ADDR is undefined.  */
+void *
+pci_alloc_consistent (struct pci_dev *pdev, size_t size, dma_addr_t *dma_addr)
+{
+	void *mb_sram_mem = alloc_mb_sram (size);
+	if (mb_sram_mem)
+		*dma_addr = MB_SRAM_TO_PCI (mb_sram_mem);
+	return mb_sram_mem;
+}
+
+/* Free and unmap a consistent DMA buffer.  CPU_ADDR and DMA_ADDR must
+   be values that were returned from pci_alloc_consistent.  SIZE must be
+   the same as what as passed into pci_alloc_consistent.  References to
+   the memory and mappings assosciated with CPU_ADDR or DMA_ADDR past
+   this call are illegal.  */
+void
+pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr,
+		     dma_addr_t dma_addr)
+{
+	void *mb_sram_mem = PCI_TO_MB_SRAM (dma_addr);
+	free_mb_sram (mb_sram_mem, size);
+}
+
+
+/* symbol exports (for modules) */
+
+EXPORT_SYMBOL (pci_map_single);
+EXPORT_SYMBOL (pci_unmap_single);
+EXPORT_SYMBOL (pci_alloc_consistent);
+EXPORT_SYMBOL (pci_free_consistent);
+EXPORT_SYMBOL (pci_dma_sync_single);
diff -urN linux-2.4.29/arch/v850/kernel/rte_me2_cb.c linux-2.4.29-uc1/arch/v850/kernel/rte_me2_cb.c
--- linux-2.4.29/arch/v850/kernel/rte_me2_cb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/rte_me2_cb.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,308 @@
+/*
+ * arch/v850/kernel/rte_me2_cb.c -- Midas labs RTE-V850E/ME2-CB board
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+#include <linux/fs.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/me2.h>
+#include <asm/rte_me2_cb.h>
+#include <asm/machdep.h>
+#include <asm/v850e_intc.h>
+#include <asm/v850e_cache.h>
+#include <asm/irq.h>
+
+#include "mach.h"
+
+extern unsigned long *_intv_start;
+extern unsigned long *_intv_end;
+
+/* LED access routines.  */
+extern unsigned read_leds (int pos, char *buf, int len);
+extern unsigned write_leds (int pos, const char *buf, int len);
+
+
+/* SDRAM are almost contiguous (with a small hole in between;
+   see mach_reserve_bootmem for details), so just use both as one big area.  */
+#define RAM_START 	SDRAM_ADDR
+#define RAM_END		(SDRAM_ADDR + SDRAM_SIZE)
+
+
+void __init mach_get_physical_ram (unsigned long *ram_start,
+				   unsigned long *ram_len)
+{
+	*ram_start = RAM_START;
+	*ram_len = RAM_END - RAM_START;
+}
+
+void __init mach_reserve_bootmem ()
+{
+	extern char _root_fs_image_start, _root_fs_image_end;
+	u32 root_fs_image_start = (u32)&_root_fs_image_start;
+	u32 root_fs_image_end = (u32)&_root_fs_image_end;
+
+	/* Reserve the memory used by the root filesystem image if it's
+	   in RAM.  */
+	if (root_fs_image_start >= RAM_START && root_fs_image_start < RAM_END)
+		reserve_bootmem (root_fs_image_start,
+				 root_fs_image_end - root_fs_image_start);
+}
+
+void mach_gettimeofday (struct timeval *tv)
+{
+	tv->tv_sec = 0;
+	tv->tv_usec = 0;
+}
+
+/* Called before configuring an on-chip UART.  */
+void rte_me2_cb_uart_pre_configure (unsigned chan,
+				    unsigned cflags, unsigned baud)
+{
+	/* The RTE-V850E/ME2-CB connects some general-purpose I/O
+	   pins on the CPU to the RTS/CTS lines of UARTB channel 0's
+	   serial connection.
+	   I/O pins P21 and P22 are RTS and CTS respectively.  */
+	if (chan == 0) {
+		/* Put P21 & P22 in I/O port mode.  */
+		ME2_PORT2_PMC &= ~0x6;
+		/* Make P21 and output, and P22 an input.  */
+		ME2_PORT2_PM = (ME2_PORT2_PM & ~0xC) | 0x4;
+	}
+
+	me2_uart_pre_configure (chan, cflags, baud);
+}
+
+void __init mach_init_irqs (void)
+{
+	/* Initialize interrupts.  */
+	me2_init_irqs ();
+	rte_me2_cb_init_irqs ();
+}
+
+#ifdef CONFIG_ROM_KERNEL
+/* Initialization for kernel in ROM.  */
+static inline rom_kernel_init (void)
+{
+	/* If the kernel is in ROM, we have to copy any initialized data
+	   from ROM into RAM.  */
+	extern unsigned long _data_load_start, _sdata, _edata;
+	register unsigned long *src = &_data_load_start;
+	register unsigned long *dst = &_sdata, *end = &_edata;
+
+	while (dst != end)
+		*dst++ = *src++;
+}
+#endif /* CONFIG_ROM_KERNEL */
+
+static void install_interrupt_vectors (void)
+{
+	unsigned long *p1, *p2;
+
+	ME2_IRAMM = 0x03; /* V850E/ME2 iRAM write mode */
+
+	/* vector copy to iRAM */
+	p1 = (unsigned long *)0; /* v85x vector start */
+	p2 = (unsigned long *)&_intv_start;
+	while (p2 < (unsigned long *)&_intv_end)
+		*p1++ = *p2++;
+
+	ME2_IRAMM = 0x00; /* V850E/ME2 iRAM read mode */
+}
+
+/* CompactFlash */
+
+static void cf_power_on (void)
+{
+	/* CF card detected? */
+	if (CB_CF_STS0 & 0x0030)
+		return;
+
+	CB_CF_REG0 = 0x0002; /* reest on */
+	mdelay (10);
+	CB_CF_REG0 = 0x0003; /* power on */
+	mdelay (10);
+	CB_CF_REG0 = 0x0001; /* reset off */
+	mdelay (10);
+}
+
+static void cf_power_off (void)
+{
+	CB_CF_REG0 = 0x0003; /* power on */
+	mdelay (10);
+	CB_CF_REG0 = 0x0002; /* reest on */
+	mdelay (10);
+}
+
+void __init mach_early_init (void)
+{
+	install_interrupt_vectors ();
+
+	/* CS1 SDRAM instruction cache enable */
+	v850e_cache_enable (0x04, 0x03, 0);
+
+	rte_cb_early_init ();
+
+	/* CompactFlash power on */
+	cf_power_on ();
+
+#if defined (CONFIG_ROM_KERNEL)
+	rom_kernel_init ();
+#endif
+}
+
+
+/* RTE-V850E/ME2-CB Programmable Interrupt Controller.  */
+
+static struct cb_pic_irq_init cb_pic_irq_inits[] = {
+	{ "CB_EXTTM0",       IRQ_CB_EXTTM0,       1, 1, 6 },
+	{ "CB_EXTSIO",       IRQ_CB_EXTSIO,       1, 1, 6 },
+	{ "CB_TOVER",        IRQ_CB_TOVER,        1, 1, 6 },
+	{ "CB_GINT0",        IRQ_CB_GINT0,        1, 1, 6 },
+	{ "CB_USB",          IRQ_CB_USB,          1, 1, 6 },
+	{ "CB_LANC",         IRQ_CB_LANC,         1, 1, 6 },
+	{ "CB_USB_VBUS_ON",  IRQ_CB_USB_VBUS_ON,  1, 1, 6 },
+	{ "CB_USB_VBUS_OFF", IRQ_CB_USB_VBUS_OFF, 1, 1, 6 },
+	{ "CB_EXTTM1",       IRQ_CB_EXTTM1,       1, 1, 6 },
+	{ "CB_EXTTM2",       IRQ_CB_EXTTM2,       1, 1, 6 },
+	{ 0 }
+};
+#define NUM_CB_PIC_IRQ_INITS  \
+   ((sizeof cb_pic_irq_inits / sizeof cb_pic_irq_inits[0]) - 1)
+
+static struct hw_interrupt_type cb_pic_hw_itypes[NUM_CB_PIC_IRQ_INITS];
+static unsigned char cb_pic_active_irqs = 0;
+
+void __init rte_me2_cb_init_irqs (void)
+{
+	cb_pic_init_irq_types (cb_pic_irq_inits, cb_pic_hw_itypes);
+
+	/* Initalize on board PIC1 (not PIC0) enable */
+	CB_PIC_INT0M  = 0x0000;
+	CB_PIC_INT1M  = 0x0000;
+	CB_PIC_INTR   = 0x0000;
+	CB_PIC_INTEN |= CB_PIC_INT1EN;
+
+	ME2_PORT2_PMC 	 |= 0x08;	/* INTP23/SCK1 mode */
+	ME2_PORT2_PFC 	 &= ~0x08;	/* INTP23 mode */
+	ME2_INTR(2) 	 &= ~0x08;	/* INTP23 falling-edge detect */
+	ME2_INTF(2) 	 &= ~0x08;	/*   " */
+
+	rte_cb_init_irqs ();	/* gbus &c */
+}
+
+
+/* Enable interrupt handling for interrupt IRQ.  */
+void cb_pic_enable_irq (unsigned irq)
+{
+	CB_PIC_INT1M |= 1 << (irq - CB_PIC_BASE_IRQ);
+}
+
+void cb_pic_disable_irq (unsigned irq)
+{
+	CB_PIC_INT1M &= ~(1 << (irq - CB_PIC_BASE_IRQ));
+}
+
+void cb_pic_shutdown_irq (unsigned irq)
+{
+	cb_pic_disable_irq (irq);
+
+	if (--cb_pic_active_irqs == 0)
+		free_irq (IRQ_CB_PIC, 0);
+
+	CB_PIC_INT1M &= ~(1 << (irq - CB_PIC_BASE_IRQ));
+}
+
+static void cb_pic_handle_irq (int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned status = CB_PIC_INTR;
+	unsigned enable = CB_PIC_INT1M;
+
+	/* Only pay attention to enabled interrupts.  */
+	status &= enable;
+
+	CB_PIC_INTEN &= ~CB_PIC_INT1EN;
+
+	if (status) {
+		unsigned mask = 1;
+
+		irq = CB_PIC_BASE_IRQ;
+		do {
+			/* There's an active interrupt, find out which one,
+			   and call its handler.  */
+			while (! (status & mask)) {
+				irq++;
+				mask <<= 1;
+			}
+			status &= ~mask;
+
+			CB_PIC_INTR = mask;
+
+			/* Recursively call handle_irq to handle it. */
+			handle_irq (irq, regs);
+		} while (status);
+	}
+
+	CB_PIC_INTEN |= CB_PIC_INT1EN;
+}
+
+
+static void irq_nop (unsigned irq) { }
+
+static unsigned cb_pic_startup_irq (unsigned irq)
+{
+	int rval;
+
+	if (cb_pic_active_irqs == 0) {
+		rval = request_irq (IRQ_CB_PIC, cb_pic_handle_irq,
+				    SA_INTERRUPT, "cb_pic_handler", 0);
+		if (rval != 0)
+			return rval;
+	}
+
+	cb_pic_active_irqs++;
+
+	cb_pic_enable_irq (irq);
+
+	return 0;
+}
+
+/* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
+   INITS (which is terminated by an entry with the name field == 0).  */
+void __init cb_pic_init_irq_types (struct cb_pic_irq_init *inits,
+				   struct hw_interrupt_type *hw_irq_types)
+{
+	struct cb_pic_irq_init *init;
+	for (init = inits; init->name; init++) {
+		struct hw_interrupt_type *hwit = hw_irq_types++;
+
+		hwit->typename = init->name;
+
+		hwit->startup  = cb_pic_startup_irq;
+		hwit->shutdown = cb_pic_shutdown_irq;
+		hwit->enable   = cb_pic_enable_irq;
+		hwit->disable  = cb_pic_disable_irq;
+		hwit->ack      = irq_nop;
+		hwit->end      = irq_nop;
+
+		/* Initialize kernel IRQ infrastructure for this interrupt.  */
+		init_irq_handlers(init->base, init->num, init->interval, hwit);
+	}
+}
diff -urN linux-2.4.29/arch/v850/kernel/rte_me2_cb.ld linux-2.4.29-uc1/arch/v850/kernel/rte_me2_cb.ld
--- linux-2.4.29/arch/v850/kernel/rte_me2_cb.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/rte_me2_cb.ld	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,30 @@
+/* Linker script for the Midas labs RTE-V850E/ME2-CB evaluation board
+   (CONFIG_RTE_CB_ME2), with kernel in SDRAM.  */
+
+MEMORY {
+	/* 128Kbyte of IRAM */
+	IRAM : ORIGIN = 0x00000000, LENGTH = 0x00020000
+
+	/* 32MB of SDRAM.  */
+	SDRAM : ORIGIN = SDRAM_ADDR, LENGTH = SDRAM_SIZE
+}
+
+#define KRAM SDRAM
+
+SECTIONS {
+	.text : {
+		__kram_start = . ;
+		TEXT_CONTENTS
+		INTV_CONTENTS	/* copy to iRAM (0x0-0x620) */
+	} > KRAM
+
+	.data : {
+		DATA_CONTENTS
+		BSS_CONTENTS
+		RAMK_INIT_CONTENTS
+		__kram_end = . ;
+		BOOTMAP_CONTENTS
+	} > KRAM
+	
+	.root ALIGN (4096) : { ROOT_FS_CONTENTS } > SDRAM
+}
diff -urN linux-2.4.29/arch/v850/kernel/rte_nb85e_cb.c linux-2.4.29-uc1/arch/v850/kernel/rte_nb85e_cb.c
--- linux-2.4.29/arch/v850/kernel/rte_nb85e_cb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/rte_nb85e_cb.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,97 @@
+/*
+ * arch/v850/kernel/rte_nb85e_cb.c -- Midas labs RTE-V850E/NB85E-CB board
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/v850e.h>
+#include <asm/rte_nb85e_cb.h>
+
+#include "mach.h"
+
+void __init mach_early_init (void)
+{
+	/* Configure caching; some possible settings:
+
+	     BHC = 0x0000, DCC = 0x0000	 -- all caching disabled
+	     BHC = 0x0040, DCC = 0x0000	 -- SDRAM: icache only
+	     BHC = 0x0080, DCC = 0x0C00	 -- SDRAM: write-back dcache only
+	     BHC = 0x00C0, DCC = 0x0C00	 -- SDRAM: icache + write-back dcache
+	     BHC = 0x00C0, DCC = 0x0800	 -- SDRAM: icache + write-thru dcache
+
+	   We can only cache SDRAM (we can't use cache SRAM because it's in
+	   the same memory region as the on-chip RAM and I/O space).
+
+	   Unfortunately, the dcache seems to be buggy, so we only use the
+	   icache for now.  */
+	v850e_cache_enable (0x0040 /*BHC*/, 0x0003 /*ICC*/, 0x0000 /*DCC*/);
+
+	rte_cb_early_init ();
+}
+
+void __init mach_get_physical_ram (unsigned long *ram_start,
+				   unsigned long *ram_len)
+{
+	/* We just use SDRAM here.  */
+	*ram_start = SDRAM_ADDR;
+	*ram_len = SDRAM_SIZE;
+}
+
+void __init mach_reserve_bootmem ()
+{
+	extern char _root_fs_image_start, _root_fs_image_end;
+	u32 root_fs_image_start = (u32)&_root_fs_image_start;
+	u32 root_fs_image_end = (u32)&_root_fs_image_end;
+
+	/* Reserve the memory used by the root filesystem image if it's
+	   in SDRAM.  */
+	if (root_fs_image_end > root_fs_image_start
+	    && root_fs_image_start >= SDRAM_ADDR
+	    && root_fs_image_start < (SDRAM_ADDR + SDRAM_SIZE))
+		reserve_bootmem (root_fs_image_start,
+				 root_fs_image_end - root_fs_image_start);
+}
+
+void mach_gettimeofday (struct timeval *tv)
+{
+	tv->tv_sec = 0;
+	tv->tv_usec = 0;
+}
+
+/* Called before configuring an on-chip UART.  */
+void rte_nb85e_cb_uart_pre_configure (unsigned chan,
+				    unsigned cflags, unsigned baud)
+{
+	/* The RTE-NB85E-CB connects some general-purpose I/O pins on the
+	   CPU to the RTS/CTS lines the UART's serial connection, as follows:
+	   P00 = CTS (in), P01 = DSR (in), P02 = RTS (out), P03 = DTR (out). */
+
+	TEG_PORT0_PM = 0x03;	/* P00 and P01 inputs, P02 and P03 outputs */
+	TEG_PORT0_IO = 0x03;	/* Accept input */
+
+	/* Do pre-configuration for the actual UART.  */
+	teg_uart_pre_configure (chan, cflags, baud);
+}
+
+void __init mach_init_irqs (void)
+{
+	teg_init_irqs ();
+	rte_cb_init_irqs ();
+}
diff -urN linux-2.4.29/arch/v850/kernel/rte_nb85e_cb.ld linux-2.4.29-uc1/arch/v850/kernel/rte_nb85e_cb.ld
--- linux-2.4.29/arch/v850/kernel/rte_nb85e_cb.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/rte_nb85e_cb.ld	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,22 @@
+/* Linker script for the Midas labs RTE-NB85E-CB evaluation board
+   (CONFIG_RTE_CB_NB85E).  */
+
+MEMORY {
+	LOW   : ORIGIN = 0x0,	     LENGTH = 0x00100000
+	/* 1MB of SRAM  This memory is mirrored 4 times.  */
+	SRAM  : ORIGIN = SRAM_ADDR,  LENGTH = SRAM_SIZE
+	/* 16MB of SDRAM.  */
+	SDRAM : ORIGIN = SDRAM_ADDR, LENGTH = SDRAM_SIZE
+}
+
+#ifdef CONFIG_RTE_CB_NB85E_KSRAM
+# define KRAM SRAM
+#else
+# define KRAM SDRAM
+#endif
+
+SECTIONS {
+	.intv : { INTV_CONTENTS } > LOW
+	.sram : { RAMK_KRAM_CONTENTS } > KRAM
+	.root : { ROOT_FS_CONTENTS } > SDRAM
+}
diff -urN linux-2.4.29/arch/v850/kernel/rte_nb85e_cb-multi.ld linux-2.4.29-uc1/arch/v850/kernel/rte_nb85e_cb-multi.ld
--- linux-2.4.29/arch/v850/kernel/rte_nb85e_cb-multi.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/rte_nb85e_cb-multi.ld	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,57 @@
+/* Linker script for the Midas labs RTE-NB85E-CB evaluation board
+   (CONFIG_RTE_CB_NB85E), with the Multi debugger ROM monitor .  */
+
+MEMORY {
+	/* 1MB of SRAM; we can't use the last 96KB, because it's used by
+	   the monitor scratch-RAM.  This memory is mirrored 4 times.  */
+	SRAM  : ORIGIN = SRAM_ADDR,  LENGTH = (SRAM_SIZE - MON_SCRATCH_SIZE)
+	/* Monitor scratch RAM; only the interrupt vectors should go here.  */
+	MRAM  : ORIGIN = MON_SCRATCH_ADDR,  LENGTH = MON_SCRATCH_SIZE
+	/* 16MB of SDRAM.  */
+	SDRAM : ORIGIN = SDRAM_ADDR, LENGTH = SDRAM_SIZE
+}
+
+#ifdef CONFIG_RTE_CB_NB85E_KSRAM
+# define KRAM SRAM
+#else
+# define KRAM SDRAM
+#endif
+
+SECTIONS {
+	/* We can't use RAMK_KRAM_CONTENTS because that puts the whole
+	   kernel in a single ELF segment, and the Multi debugger (which
+	   we use to load the kernel) appears to have bizarre problems
+	   dealing with it.  */
+
+	.text : {
+		__kram_start = . ;
+		TEXT_CONTENTS
+	} > KRAM
+
+	.data : {
+		DATA_CONTENTS
+		BSS_CONTENTS
+		RAMK_INIT_CONTENTS
+		__kram_end = . ;
+		BOOTMAP_CONTENTS
+
+		/* The address at which the interrupt vectors are initially
+		   loaded by the loader.  We can't load the interrupt vectors
+		   directly into their target location, because the monitor
+		   ROM for the GHS Multi debugger barfs if we try.
+		   Unfortunately, Multi also doesn't deal correctly with ELF
+		   sections where the LMA and VMA differ (it just ignores the
+		   LMA), so we can't use that feature to work around the
+		   problem!  What we do instead is just put the interrupt
+		   vectors into a normal section, and have the
+		   `mach_early_init' function for Midas boards do the
+		   necessary copying and relocation at runtime (this section
+		   basically only contains `jr' instructions, so it's not
+		   that hard).  */
+		. = ALIGN (0x10) ;
+		__intv_load_start = . ;
+		INTV_CONTENTS
+	} > KRAM
+
+	.root ALIGN (4096) : { ROOT_FS_CONTENTS } > SDRAM
+}
diff -urN linux-2.4.29/arch/v850/kernel/semaphore.c linux-2.4.29-uc1/arch/v850/kernel/semaphore.c
--- linux-2.4.29/arch/v850/kernel/semaphore.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/semaphore.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,164 @@
+/*
+ * arch/v850/kernel/semaphore.c -- Semaphore support
+ *
+ *  Copyright (C) 1998-2000  IBM Corporation
+ *  Copyright (C) 1999  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * This file is a copy of the s390 version, arch/s390/kernel/semaphore.c
+ *    Author(s): Martin Schwidefsky
+ * which was derived from the i386 version, linux/arch/i386/kernel/semaphore.c
+ */
+
+#include <linux/sched.h>
+
+#include <asm/semaphore.h>
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to acquire the semaphore, while the "sleeping"
+ * variable is a count of such acquires.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * "sleeping" and the contention routine ordering is
+ * protected by the semaphore spinlock.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+
+/*
+ * Logic:
+ *  - only on a boundary condition do we need to care. When we go
+ *    from a negative count to a non-negative, we wake people up.
+ *  - when we go from a non-negative count to a negative do we
+ *    (a) synchronize with the "sleeper" count and (b) make sure
+ *    that we're on the wakeup list before we synchronize so that
+ *    we cannot lose wakeup events.
+ */
+
+void __up(struct semaphore *sem)
+{
+	wake_up(&sem->wait);
+}
+
+static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED;
+
+void __down(struct semaphore * sem)
+{
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+	tsk->state = TASK_UNINTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	spin_lock_irq(&semaphore_lock);
+	sem->sleepers++;
+	for (;;) {
+		int sleepers = sem->sleepers;
+
+		/*
+		 * Add "everybody else" into it. They aren't
+		 * playing, because we own the spinlock.
+		 */
+		if (!atomic_add_negative(sleepers - 1, &sem->count)) {
+			sem->sleepers = 0;
+			break;
+		}
+		sem->sleepers = 1;	/* us - see -1 above */
+		spin_unlock_irq(&semaphore_lock);
+
+		schedule();
+		tsk->state = TASK_UNINTERRUPTIBLE;
+		spin_lock_irq(&semaphore_lock);
+	}
+	spin_unlock_irq(&semaphore_lock);
+	remove_wait_queue(&sem->wait, &wait);
+	tsk->state = TASK_RUNNING;
+	wake_up(&sem->wait);
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+	int retval = 0;
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+	tsk->state = TASK_INTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	spin_lock_irq(&semaphore_lock);
+	sem->sleepers ++;
+	for (;;) {
+		int sleepers = sem->sleepers;
+
+		/*
+		 * With signals pending, this turns into
+		 * the trylock failure case - we won't be
+		 * sleeping, and we* can't get the lock as
+		 * it has contention. Just correct the count
+		 * and exit.
+		 */
+		if (signal_pending(current)) {
+			retval = -EINTR;
+			sem->sleepers = 0;
+			atomic_add(sleepers, &sem->count);
+			break;
+		}
+
+		/*
+		 * Add "everybody else" into it. They aren't
+		 * playing, because we own the spinlock. The
+		 * "-1" is because we're still hoping to get
+		 * the lock.
+		 */
+		if (!atomic_add_negative(sleepers - 1, &sem->count)) {
+			sem->sleepers = 0;
+			break;
+		}
+		sem->sleepers = 1;	/* us - see -1 above */
+		spin_unlock_irq(&semaphore_lock);
+
+		schedule();
+		tsk->state = TASK_INTERRUPTIBLE;
+		spin_lock_irq(&semaphore_lock);
+	}
+	spin_unlock_irq(&semaphore_lock);
+	tsk->state = TASK_RUNNING;
+	remove_wait_queue(&sem->wait, &wait);
+	wake_up(&sem->wait);
+	return retval;
+}
+
+/*
+ * Trylock failed - make sure we correct for
+ * having decremented the count.
+ */
+int __down_trylock(struct semaphore * sem)
+{
+        unsigned long flags;
+	int sleepers;
+
+	spin_lock_irqsave(&semaphore_lock, flags);
+	sleepers = sem->sleepers + 1;
+	sem->sleepers = 0;
+
+	/*
+	 * Add "everybody else" and us into it. They aren't
+	 * playing, because we own the spinlock.
+	 */
+	if (!atomic_add_negative(sleepers, &sem->count))
+		wake_up(&sem->wait);
+
+	spin_unlock_irqrestore(&semaphore_lock, flags);
+	return 1;
+}
diff -urN linux-2.4.29/arch/v850/kernel/setup.c linux-2.4.29-uc1/arch/v850/kernel/setup.c
--- linux-2.4.29/arch/v850/kernel/setup.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/setup.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,255 @@
+/*
+ * arch/v850/kernel/setup.c -- Arch-dependent initialization functions
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+#include <linux/reboot.h>
+#include <linux/personality.h>
+
+#include <asm/irq.h>
+
+#include "mach.h"
+
+/* These symbols are all defined in the linker map to delineate various
+   statically allocated regions of memory.  */
+
+extern char _intv_start, _intv_end;
+/* `kram' is only used if the kernel uses part of normal user RAM.  */
+extern char _kram_start __attribute__ ((__weak__));
+extern char _kram_end __attribute__ ((__weak__));
+extern char _init_start, _init_end;
+extern char _bootmap;
+extern char _stext, _etext, _sdata, _edata, _sbss, _ebss;
+
+
+char command_line[512];
+char saved_command_line[512];
+
+/* Memory not used by the kernel.  */
+static unsigned long total_ram_pages;
+
+/* System RAM.  */
+static unsigned long ram_start = 0, ram_len = 0;
+
+
+#define ADDR_TO_PAGE_UP(x)   ((((unsigned long)x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define ADDR_TO_PAGE(x)	     (((unsigned long)x) >> PAGE_SHIFT)
+#define PAGE_TO_ADDR(x)	     (((unsigned long)x) << PAGE_SHIFT)
+
+static void init_mem_alloc (unsigned long ram_start, unsigned long ram_len);
+
+
+void __init setup_arch (char **cmdline)
+{
+	/* Keep a copy of command line */
+	*cmdline = command_line;
+	memcpy (saved_command_line, command_line, sizeof saved_command_line);
+	saved_command_line[sizeof saved_command_line - 1] = '\0';
+
+	console_verbose ();
+
+	init_mm.start_code = (unsigned long) &_stext;
+	init_mm.end_code = (unsigned long) &_etext;
+	init_mm.end_data = (unsigned long) &_edata;
+	init_mm.brk = (unsigned long) &_kram_end;
+
+	/* Find out what mem this machine has.  */
+	mach_get_physical_ram (&ram_start, &ram_len);
+	/* ... and tell the kernel about it.  */
+	init_mem_alloc (ram_start, ram_len);
+
+	printk (KERN_INFO "CPU: %s\nPlatform: %s\n",
+		CPU_MODEL_LONG, PLATFORM_LONG);
+
+	/* do machine-specific setups.  */
+	mach_setup (cmdline);
+}
+
+void __init trap_init (void)
+{
+}
+
+
+static void irq_nop (unsigned irq) { }
+static unsigned irq_zero (unsigned irq) { return 0; }
+
+static void nmi_end (unsigned irq)
+{
+	if (irq != IRQ_NMI (0)) {
+		printk (KERN_CRIT "NMI %d is unrecoverable; restarting...",
+			irq - IRQ_NMI (0));
+		machine_restart (0);
+	}
+}
+
+static struct hw_interrupt_type nmi_irq_type = {
+	"NMI",
+	irq_zero,		/* startup */
+	irq_nop,		/* shutdown */
+	irq_nop,		/* enable */
+	irq_nop,		/* disable */
+	irq_nop,		/* ack */
+	nmi_end,		/* end */
+};
+
+void __init init_IRQ (void)
+{
+	init_irq_handlers (0, NUM_MACH_IRQS, 1, 0);
+	init_irq_handlers (IRQ_NMI (0), NUM_NMIS, 1, &nmi_irq_type);
+	mach_init_irqs ();
+}
+
+
+void __init mem_init (void)
+{
+	max_mapnr = MAP_NR (ram_start + ram_len);
+
+	num_physpages = ADDR_TO_PAGE (ram_len);
+
+	total_ram_pages = free_all_bootmem ();
+
+	printk (KERN_INFO
+		"Memory: %luK/%luK available"
+		" (%luK kernel code, %luK data)\n",
+		PAGE_TO_ADDR (nr_free_pages()) / 1024,
+		ram_len / 1024,
+		((unsigned long)&_etext - (unsigned long)&_stext) / 1024,
+		((unsigned long)&_ebss - (unsigned long)&_sdata) / 1024);
+}
+
+void free_initmem (void)
+{
+	unsigned long ram_end = ram_start + ram_len;
+	unsigned long start = PAGE_ALIGN ((unsigned long)(&_init_start));
+
+	if (start >= ram_start && start < ram_end) {
+		unsigned long addr;
+		unsigned long end = PAGE_ALIGN ((unsigned long)(&_init_end));
+
+		if (end > ram_end)
+			end = ram_end;
+
+		printk("Freeing unused kernel memory: %ldK freed\n",
+		       (end - start) / 1024);
+
+		for (addr = start; addr < end; addr += PAGE_SIZE) {
+			mem_map_t *page = virt_to_page (addr);
+			ClearPageReserved (page);
+			set_page_count (page, 1);
+			__free_page (page);
+			total_ram_pages++;
+		}
+	}
+}
+
+void si_meminfo (struct sysinfo *info)
+{
+	info->totalram = total_ram_pages;
+	info->sharedram = 0;
+	info->freeram = nr_free_pages ();
+	info->bufferram = atomic_read (&buffermem_pages);
+	info->totalhigh = 0;
+	info->freehigh = 0;
+	info->mem_unit = PAGE_SIZE;
+}
+
+
+/* Initialize the `bootmem allocator'.  RAM_START and RAM_LEN identify
+   what RAM may be used.  */
+static void __init
+init_bootmem_alloc (unsigned long ram_start, unsigned long ram_len)
+{
+	/* The part of the kernel that's in the same managed RAM space
+	   used for general allocation.  */
+	unsigned long kram_start = (unsigned long)&_kram_start;
+	unsigned long kram_end = (unsigned long)&_kram_end;
+	/* End of the managed RAM space.  */
+	unsigned long ram_end = ram_start + ram_len;
+	/* Address range of the interrupt vector table.  */
+	unsigned long intv_start = (unsigned long)&_intv_start;
+	unsigned long intv_end = (unsigned long)&_intv_end;
+	/* True if the interrupt vectors are in the managed RAM area.  */
+	int intv_in_ram = (intv_end > ram_start && intv_start < ram_end);
+	/* True if the interrupt vectors are inside the kernel's RAM.  */
+	int intv_in_kram = (intv_end > kram_start && intv_start < kram_end);
+	/* A pointer to an optional function that reserves platform-specific
+	   memory regions.  We declare the pointer `volatile' to avoid gcc
+	   turning the call into a static call (the problem is that since
+	   it's a weak symbol, a static call may end up trying to reference
+	   the location 0x0, which is not always reachable).  */
+	void (*volatile mrb) (void) = mach_reserve_bootmem;
+	/* The bootmem allocator's allocation bitmap.  */
+	unsigned long bootmap = (unsigned long)&_bootmap;
+	unsigned long bootmap_len;
+
+	/* Round bootmap location up to next page.  */
+	bootmap = PAGE_TO_ADDR (ADDR_TO_PAGE_UP (bootmap));
+
+	/* Initialize bootmem allocator.  */
+	bootmap_len = init_bootmem_node (NODE_DATA (0),
+					 ADDR_TO_PAGE (bootmap),
+					 ADDR_TO_PAGE (PAGE_OFFSET),
+					 ADDR_TO_PAGE (ram_end));
+
+	/* Now make the RAM actually allocatable (it starts out `reserved'). */
+	free_bootmem (ram_start, ram_len);
+
+	if (kram_end > kram_start)
+		/* Reserve the RAM part of the kernel's address space, so it
+		   doesn't get allocated.  */
+		reserve_bootmem (kram_start, kram_end - kram_start);
+	
+	if (intv_in_ram && !intv_in_kram)
+		/* Reserve the interrupt vector space.  */
+		reserve_bootmem (intv_start, intv_end - intv_start);
+
+	if (bootmap >= ram_start && bootmap < ram_end)
+		/* Reserve the bootmap space.  */
+		reserve_bootmem (bootmap, bootmap_len);
+
+	/* Let the platform-dependent code reserve some too.  */
+	if (mrb)
+		(*mrb) ();
+}
+
+/* Tell the kernel about what RAM it may use for memory allocation.  */
+static void __init
+init_mem_alloc (unsigned long ram_start, unsigned long ram_len)
+{
+	unsigned i;
+	unsigned long zones_size[MAX_NR_ZONES];
+
+	init_bootmem_alloc (ram_start, ram_len);
+
+	for (i = 0; i < MAX_NR_ZONES; i++)
+		zones_size[i] = 0;
+
+	/* We stuff all the memory into one area, which includes the
+	   initial gap from PAGE_OFFSET to ram_start.  */
+	zones_size[ZONE_DMA]
+		= ADDR_TO_PAGE (ram_len + (ram_start - PAGE_OFFSET));
+
+	/* The allocator is very picky about the address of the first
+	   allocatable page -- it must be at least as aligned as the
+	   maximum allocation -- so try to detect cases where it will get
+	   confused and signal them at compile time (this is a common
+	   problem when porting to a new platform with ).  There is a
+	   similar runtime check in free_area_init_core.  */
+#if ((PAGE_OFFSET >> PAGE_SHIFT) & ((1UL << (MAX_ORDER - 1)) - 1))
+#error MAX_ORDER is too large for given PAGE_OFFSET (use CONFIG_FORCE_MAX_ZONEORDER to change it)
+#endif
+
+	free_area_init_node (0, 0, 0, zones_size, PAGE_OFFSET, 0);
+}
diff -urN linux-2.4.29/arch/v850/kernel/signal.c linux-2.4.29-uc1/arch/v850/kernel/signal.c
--- linux-2.4.29/arch/v850/kernel/signal.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/signal.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,645 @@
+/*
+ * arch/v850/kernel/signal.c -- Signal handling
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 1999,2000  Niibe Yutaka & Kaz Kojima
+ *  Copyright (C) 1991,1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * 1997-11-28  Modified for POSIX.1b signals by Richard Henderson
+ *
+ * This file was derived from the sh version, arch/sh/kernel/signal.c
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/personality.h>
+#include <asm/ucontext.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+
+#define DEBUG_SIG 0
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
+
+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
+{
+	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+		return -EFAULT;
+	if (from->si_code < 0)
+		return __copy_to_user(to, from, sizeof(siginfo_t));
+	else {
+		int err;
+
+		/* If you change siginfo_t structure, please be sure
+		   this code is fixed accordingly.
+		   It should never copy any pad contained in the structure
+		   to avoid security leaks, but must copy the generic
+		   3 ints plus the relevant union member.  */
+		err = __put_user(from->si_signo, &to->si_signo);
+		err |= __put_user(from->si_errno, &to->si_errno);
+		err |= __put_user((short)from->si_code, &to->si_code);
+		/* First 32bits of unions are always present.  */
+		err |= __put_user(from->si_pid, &to->si_pid);
+		switch (from->si_code >> 16) {
+		case __SI_FAULT >> 16:
+			break;
+		case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+			err |= __put_user(from->si_status, &to->si_status);
+		default:
+			err |= __put_user(from->si_uid, &to->si_uid);
+			break;
+		/* case __SI_RT: This is not generated by the kernel as of now.  */
+		}
+		return err;
+	}
+}
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int
+sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs)
+{
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->gpr[GPR_RVAL] = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(regs, &saveset))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
+		  struct pt_regs *regs)
+{
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	regs->gpr[GPR_RVAL] = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(regs, &saveset))
+			return -EINTR;
+	}
+}
+
+asmlinkage int 
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t *uss, stack_t *uoss,
+		struct pt_regs *regs)
+{
+	return do_sigaltstack(uss, uoss, regs->gpr[GPR_SP]);
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+
+struct sigframe
+{
+	struct sigcontext sc;
+	unsigned long extramask[_NSIG_WORDS-1];
+	unsigned long tramp[2];	/* signal trampoline */
+};
+
+struct rt_sigframe
+{
+	struct siginfo info;
+	struct ucontext uc;
+	unsigned long tramp[2];	/* signal trampoline */
+};
+
+static int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *rval_p)
+{
+	unsigned int err = 0;
+
+#define COPY(x)		err |= __get_user(regs->x, &sc->regs.x)
+	COPY(gpr[0]);	COPY(gpr[1]);	COPY(gpr[2]);	COPY(gpr[3]);
+	COPY(gpr[4]);	COPY(gpr[5]);	COPY(gpr[6]);	COPY(gpr[7]);
+	COPY(gpr[8]);	COPY(gpr[9]);	COPY(gpr[10]);	COPY(gpr[11]);
+	COPY(gpr[12]);	COPY(gpr[13]);	COPY(gpr[14]);	COPY(gpr[15]);
+	COPY(gpr[16]);	COPY(gpr[17]);	COPY(gpr[18]);	COPY(gpr[19]);
+	COPY(gpr[20]);	COPY(gpr[21]);	COPY(gpr[22]);	COPY(gpr[23]);
+	COPY(gpr[24]);	COPY(gpr[25]);	COPY(gpr[26]);	COPY(gpr[27]);
+	COPY(gpr[28]);	COPY(gpr[29]);	COPY(gpr[30]);	COPY(gpr[31]);
+	COPY(pc);	COPY(psw);
+	COPY(ctpc);	COPY(ctpsw);	COPY(ctbp);
+#undef COPY
+
+	return err;
+}
+
+asmlinkage int sys_sigreturn(struct pt_regs *regs)
+{
+	struct sigframe *frame = (struct sigframe *)regs->gpr[GPR_SP];
+	sigset_t set;
+	int rval;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+
+	if (__get_user(set.sig[0], &frame->sc.oldmask)
+	    || (_NSIG_WORDS > 1
+		&& __copy_from_user(&set.sig[1], &frame->extramask,
+				    sizeof(frame->extramask))))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigcontext(regs, &frame->sc, &rval))
+		goto badframe;
+	return rval;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+{
+	struct rt_sigframe *frame = (struct rt_sigframe *)regs->gpr[GPR_SP];
+	sigset_t set;
+	stack_t st;
+	int rval;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = set;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval))
+		goto badframe;
+
+	if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
+		goto badframe;
+	/* It is more difficult to avoid calling this function than to
+	   call it and ignore errors.  */
+	do_sigaltstack(&st, NULL, regs->gpr[GPR_SP]);
+
+	return rval;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}	
+
+/*
+ * Set up a signal frame.
+ */
+
+static int
+setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+		 unsigned long mask)
+{
+	int err = 0;
+
+#define COPY(x)		err |= __put_user(regs->x, &sc->regs.x)
+	COPY(gpr[0]);	COPY(gpr[1]);	COPY(gpr[2]);	COPY(gpr[3]);
+	COPY(gpr[4]);	COPY(gpr[5]);	COPY(gpr[6]);	COPY(gpr[7]);
+	COPY(gpr[8]);	COPY(gpr[9]);	COPY(gpr[10]);	COPY(gpr[11]);
+	COPY(gpr[12]);	COPY(gpr[13]);	COPY(gpr[14]);	COPY(gpr[15]);
+	COPY(gpr[16]);	COPY(gpr[17]);	COPY(gpr[18]);	COPY(gpr[19]);
+	COPY(gpr[20]);	COPY(gpr[21]);	COPY(gpr[22]);	COPY(gpr[23]);
+	COPY(gpr[24]);	COPY(gpr[25]);	COPY(gpr[26]);	COPY(gpr[27]);
+	COPY(gpr[28]);	COPY(gpr[29]);	COPY(gpr[30]);	COPY(gpr[31]);
+	COPY(pc);	COPY(psw);
+	COPY(ctpc);	COPY(ctpsw);	COPY(ctbp);
+#undef COPY
+
+	err |= __put_user(mask, &sc->oldmask);
+
+	return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	/* Default to using normal stack */
+	unsigned long sp = regs->gpr[GPR_SP];
+
+	if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp))
+		sp = current->sas_ss_sp + current->sas_ss_size;
+
+	return (void *)((sp - frame_size) & -8UL);
+}
+
+static void setup_frame(int sig, struct k_sigaction *ka,
+			sigset_t *set, struct pt_regs *regs)
+{
+	struct sigframe *frame;
+	int err = 0;
+	int signal;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	signal = current->exec_domain
+		&& current->exec_domain->signal_invmap
+		&& sig < 32
+		? current->exec_domain->signal_invmap[sig]
+		: sig;
+
+	err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
+
+	if (_NSIG_WORDS > 1) {
+		err |= __copy_to_user(frame->extramask, &set->sig[1],
+				      sizeof(frame->extramask));
+	}
+
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		regs->gpr[GPR_LP] = (unsigned long) ka->sa.sa_restorer;
+	} else {
+		/* Note, these encodings are _little endian_!  */
+
+		/* addi  __NR_sigreturn, r0, r12  */
+		err |= __put_user(0x6600 | (__NR_sigreturn << 16),
+				  frame->tramp + 0);
+		/* trap 0 */
+		err |= __put_user(0x010007e0,
+				  frame->tramp + 1);
+
+		regs->gpr[GPR_LP] = (unsigned long)frame->tramp;
+
+		flush_cache_sigtramp (regs->gpr[GPR_LP]);
+	}
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up registers for signal handler.  */
+	regs->pc = (v850_reg_t) ka->sa.sa_handler;
+	regs->gpr[GPR_SP] = (v850_reg_t)frame;
+	/* Signal handler args:  */
+	regs->gpr[GPR_ARG0] = signal; /* arg 0: signum */
+	regs->gpr[GPR_ARG1] = (v850_reg_t)&frame->sc;/* arg 1: sigcontext */
+
+	set_fs(USER_DS);
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): sp=%p pc=%08lx ra=%08lx\n",
+		current->comm, current->pid, frame, regs->pc, );
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+			   sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+	int err = 0;
+	int signal;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	signal = current->exec_domain
+		&& current->exec_domain->signal_invmap
+		&& sig < 32
+		? current->exec_domain->signal_invmap[sig]
+		: sig;
+
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+			  &frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(regs->gpr[GPR_SP]),
+			  &frame->uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= setup_sigcontext(&frame->uc.uc_mcontext,
+			        regs, set->sig[0]);
+	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		regs->gpr[GPR_LP] = (unsigned long) ka->sa.sa_restorer;
+	} else {
+		/* Note, these encodings are _little endian_!  */
+
+		/* addi  __NR_sigreturn, r0, r12  */
+		err |= __put_user(0x6600 | (__NR_sigreturn << 16),
+				  frame->tramp + 0);
+		/* trap 0 */
+		err |= __put_user(0x010007e0,
+				  frame->tramp + 1);
+
+		regs->gpr[GPR_LP] = (unsigned long)frame->tramp;
+
+		flush_cache_sigtramp (regs->gpr[GPR_LP]);
+	}
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up registers for signal handler.  */
+	regs->pc = (v850_reg_t) ka->sa.sa_handler;
+	regs->gpr[GPR_SP] = (v850_reg_t)frame;
+	/* Signal handler args:  */
+	regs->gpr[GPR_ARG0] = signal; /* arg 0: signum */
+	regs->gpr[GPR_ARG1] = (v850_reg_t)&frame->info; /* arg 1: siginfo */
+	regs->gpr[GPR_ARG2] = (v850_reg_t)&frame->uc; /* arg 2: ucontext */
+
+	set_fs(USER_DS);
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
+		current->comm, current->pid, frame, regs->pc, regs->pr);
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+/*
+ * OK, we're invoking a handler
+ */	
+
+static void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+	      siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
+{
+	/* Are we from a system call? */
+	if (PT_REGS_SYSCALL (regs)) {
+		/* If so, check system call restarting.. */
+		switch (regs->gpr[GPR_RVAL]) {
+			case -ERESTARTNOHAND:
+				regs->gpr[GPR_RVAL] = -EINTR;
+				break;
+
+			case -ERESTARTSYS:
+				if (!(ka->sa.sa_flags & SA_RESTART)) {
+					regs->gpr[GPR_RVAL] = -EINTR;
+					break;
+				}
+			/* fallthrough */
+			case -ERESTARTNOINTR:
+				regs->gpr[12] = PT_REGS_SYSCALL (regs);
+				regs->pc -= 4; /* Size of `trap 0' insn.  */
+		}
+
+		PT_REGS_SET_SYSCALL (regs, 0);
+	}
+
+	/* Set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sigmask_lock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending(current);
+		spin_unlock_irq(&current->sigmask_lock);
+	}
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals that
+ * the kernel can handle, and then we build all the user-level signal handling
+ * stack-frames in one go after that.
+ */
+int do_signal(struct pt_regs *regs, sigset_t *oldset)
+{
+	siginfo_t info;
+	struct k_sigaction *ka;
+
+	/*
+	 * We want the common case to go fast, which
+	 * is why we may in certain cases get here from
+	 * kernel mode. Just return without doing anything
+	 * if so.
+	 */
+	if (!user_mode(regs))
+		return 1;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	for (;;) {
+		unsigned long signr;
+
+		spin_lock_irq(&current->sigmask_lock);
+		signr = dequeue_signal(&current->blocked, &info);
+		spin_unlock_irq(&current->sigmask_lock);
+
+		if (!signr)
+			break;
+
+		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			/* Let the debugger run.  */
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			notify_parent(current, SIGCHLD);
+			schedule();
+
+			/* We're back.  Did the debugger cancel the sig?  */
+			if (!(signr = current->exit_code))
+				continue;
+			current->exit_code = 0;
+
+			/* The debugger continued.  Ignore SIGSTOP.  */
+			if (signr == SIGSTOP)
+				continue;
+
+			/* Update the siginfo structure.  Is this good?  */
+			if (signr != info.si_signo) {
+				info.si_signo = signr;
+				info.si_errno = 0;
+				info.si_code = SI_USER;
+				info.si_pid = current->p_pptr->pid;
+				info.si_uid = current->p_pptr->uid;
+			}
+
+			/* If the (new) signal is now blocked, requeue it.  */
+			if (sigismember(&current->blocked, signr)) {
+				send_sig_info(signr, &info, current);
+				continue;
+			}
+		}
+
+		ka = &current->sig->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* Check for SIGCHLD: it's special.  */
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+				/* nothing */;
+			continue;
+		}
+
+		if (ka->sa.sa_handler == SIG_DFL) {
+			int exit_code = signr;
+
+			/* Init gets no signals it doesn't want.  */
+			if (current->pid == 1)
+				continue;
+
+			switch (signr) {
+			case SIGCONT: case SIGCHLD: case SIGWINCH:
+				continue;
+
+			case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (is_orphaned_pgrp(current->pgrp))
+					continue;
+				/* FALLTHRU */
+
+			case SIGSTOP:
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+					notify_parent(current, SIGCHLD);
+				schedule();
+				continue;
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGABRT: case SIGFPE: case SIGSEGV:
+			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
+				if (do_coredump(signr, regs))
+					exit_code |= 0x80;
+				/* FALLTHRU */
+
+			default:
+				sigaddset(&current->pending.signal, signr);
+				recalc_sigpending(current);
+				current->flags |= PF_SIGNALED;
+				do_exit(exit_code);
+				/* NOTREACHED */
+			}
+		}
+
+		/* Whee!  Actually deliver the signal.  */
+		handle_signal(signr, ka, &info, oldset, regs);
+		return 1;
+	}
+
+	/* Did we come from a system call? */
+	if (PT_REGS_SYSCALL (regs)) {
+		/* Restart the system call - no handlers present */
+		if (regs->gpr[GPR_RVAL] == (v850_reg_t)-ERESTARTNOHAND ||
+		    regs->gpr[GPR_RVAL] == (v850_reg_t)-ERESTARTSYS ||
+		    regs->gpr[GPR_RVAL] == (v850_reg_t)-ERESTARTNOINTR)
+		{
+			regs->gpr[12] = PT_REGS_SYSCALL (regs);
+			regs->pc -= 4; /* Size of `trap 0' insn.  */
+		}
+	}
+	return 0;
+}
diff -urN linux-2.4.29/arch/v850/kernel/sim85e2.c linux-2.4.29-uc1/arch/v850/kernel/sim85e2.c
--- linux-2.4.29/arch/v850/kernel/sim85e2.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/sim85e2.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,211 @@
+/*
+ * arch/v850/kernel/sim85e2.c -- Machine-specific stuff for
+ *	V850E2 RTL simulator
+ *
+ *  Copyright (C) 2002,03  NEC Electronics Corporation
+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+
+#include "mach.h"
+
+
+/* There are 4 possible areas we can use:
+
+     IRAM (1MB) is fast for instruction fetches, but slow for data
+     DRAM (1020KB) is fast for data, but slow for instructions
+     ERAM is cached, so should be fast for both insns and data
+     SDRAM is external DRAM, similar to ERAM
+*/
+
+#define INIT_MEMC_FOR_SDRAM
+#define USE_SDRAM_AREA
+#define KERNEL_IN_SDRAM_AREA
+
+#define DCACHE_MODE	V850E2_CACHE_BTSC_DCM_WT
+/*#define DCACHE_MODE	V850E2_CACHE_BTSC_DCM_WB_ALLOC*/
+
+#ifdef USE_SDRAM_AREA
+#define RAM_START 	SDRAM_ADDR
+#define RAM_END		(SDRAM_ADDR + SDRAM_SIZE)
+#else
+/* When we use DRAM, we need to account for the fact that the end of it is
+   used for R0_RAM.  */
+#define RAM_START	DRAM_ADDR
+#define RAM_END		R0_RAM_ADDR
+#endif
+
+
+extern void memcons_setup (void);
+
+
+#ifdef KERNEL_IN_SDRAM_AREA
+#define EARLY_INIT_SECTION_ATTR __attribute__ ((section (".early.text")))
+#else
+#define EARLY_INIT_SECTION_ATTR __init
+#endif
+
+void EARLY_INIT_SECTION_ATTR mach_early_init (void)
+{
+	extern int panic_timeout;
+
+	/* The sim85e2 simulator tracks `undefined' values, so to make
+	   debugging easier, we begin by zeroing out all otherwise
+	   undefined registers.  This is not strictly necessary.
+
+	   The registers we zero are:
+	       Every GPR except:
+	           stack-pointer (r3)
+		   task-pointer (r16)
+		   our return addr (r31)
+	       Every system register (SPR) that we know about except for
+	       the PSW (SPR 5), which we zero except for the
+	       disable-interrupts bit.
+	*/
+
+	/* GPRs */
+	asm volatile ("             mov r0, r1 ; mov r0, r2              ");
+	asm volatile ("mov r0, r4 ; mov r0, r5 ; mov r0, r6 ; mov r0, r7 ");
+	asm volatile ("mov r0, r8 ; mov r0, r9 ; mov r0, r10; mov r0, r11");
+	asm volatile ("mov r0, r12; mov r0, r13; mov r0, r14; mov r0, r15");
+	asm volatile ("             mov r0, r17; mov r0, r18; mov r0, r19");
+	asm volatile ("mov r0, r20; mov r0, r21; mov r0, r22; mov r0, r23");
+	asm volatile ("mov r0, r24; mov r0, r25; mov r0, r26; mov r0, r27");
+	asm volatile ("mov r0, r28; mov r0, r29; mov r0, r30");
+
+	/* SPRs */
+	asm volatile ("ldsr r0, 0;  ldsr r0, 1;  ldsr r0, 2;  ldsr r0, 3");
+	asm volatile ("ldsr r0, 4");
+	asm volatile ("addi 0x20, r0, r1; ldsr r1, 5"); /* PSW */
+	asm volatile ("ldsr r0, 16; ldsr r0, 17; ldsr r0, 18; ldsr r0, 19");
+	asm volatile ("ldsr r0, 20");
+
+
+#ifdef INIT_MEMC_FOR_SDRAM
+	/* Settings for SDRAM controller.  */
+	V850E2_VSWC   = 0x0042;
+	V850E2_BSC    = 0x9286;
+	V850E2_BCT(0) = 0xb000;	/* was: 0 */
+	V850E2_BCT(1) = 0x000b;
+	V850E2_ASC    = 0;
+	V850E2_LBS    = 0xa9aa;	/* was: 0xaaaa */
+	V850E2_LBC(0) = 0;
+	V850E2_LBC(1) = 0;	/* was: 0x3 */
+	V850E2_BCC    = 0;
+	V850E2_RFS(4) = 0x800a;	/* was: 0xf109 */
+	V850E2_SCR(4) = 0x2091;	/* was: 0x20a1 */
+	V850E2_RFS(3) = 0x800c;
+	V850E2_SCR(3) = 0x20a1;
+	V850E2_DWC(0) = 0;
+	V850E2_DWC(1) = 0;
+#endif
+
+#if 0
+#ifdef CONFIG_V850E2_SIM85E2S
+	/* Turn on the caches.  */
+	V850E2_CACHE_BTSC = V850E2_CACHE_BTSC_ICM | DCACHE_MODE;
+	V850E2_BHC  = 0x1010;
+#elif CONFIG_V850E2_SIM85E2C
+	V850E2_CACHE_BTSC |= (V850E2_CACHE_BTSC_ICM | V850E2_CACHE_BTSC_DCM0);
+	V850E2_BUSM_BHC = 0xFFFF;
+#endif
+#else
+	V850E2_BHC  = 0;
+#endif
+
+	/* Don't stop the simulator at `halt' instructions.  */
+	SIM85E2_NOTHAL = 1;
+
+	/* Ensure that the simulator halts on a panic, instead of going
+	   into an infinite loop inside the panic function.  */
+	panic_timeout = -1;
+}
+
+void __init mach_setup (char **cmdline)
+{
+	memcons_setup ();
+}
+
+void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len)
+{
+	*ram_start = RAM_START;
+	*ram_len = RAM_END - RAM_START;
+}
+
+void __init mach_reserve_bootmem ()
+{
+	extern char _root_fs_image_start, _root_fs_image_end;
+	u32 root_fs_image_start = (u32)&_root_fs_image_start;
+	u32 root_fs_image_end = (u32)&_root_fs_image_end;
+
+	/* Reserve the memory used by the root filesystem image if it's
+	   in RAM.  */
+	if (root_fs_image_end > root_fs_image_start
+	    && root_fs_image_start >= RAM_START
+	    && root_fs_image_start < RAM_END)
+		reserve_bootmem (root_fs_image_start,
+				 root_fs_image_end - root_fs_image_start);
+}
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* The simulator actually cycles through all interrupts
+	   periodically.  We just pay attention to IRQ0, which gives us
+	   1/64 the rate of the periodic interrupts.  */
+	setup_irq (0, timer_action);
+}
+
+void mach_gettimeofday (struct timeval *tv)
+{
+	tv->tv_sec = 0;
+	tv->tv_usec = 0;
+}
+
+/* Interrupts */
+
+struct v850e_intc_irq_init irq_inits[] = {
+	{ "IRQ", 0, NUM_MACH_IRQS, 1, 7 },
+	{ 0 }
+};
+struct hw_interrupt_type hw_itypes[1];
+
+/* Initialize interrupts.  */
+void __init mach_init_irqs (void)
+{
+	v850e_intc_init_irq_types (irq_inits, hw_itypes);
+}
+
+
+void machine_halt (void) __attribute__ ((noreturn));
+void machine_halt (void)
+{
+	SIM85E2_SIMFIN = 0;	/* Halt immediately.  */
+	for (;;) {}
+}
+
+void machine_restart (char *__unused)
+{
+	machine_halt ();
+}
+
+void machine_power_off (void)
+{
+	machine_halt ();
+}
diff -urN linux-2.4.29/arch/v850/kernel/sim85e2.ld linux-2.4.29-uc1/arch/v850/kernel/sim85e2.ld
--- linux-2.4.29/arch/v850/kernel/sim85e2.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/sim85e2.ld	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,36 @@
+/* Linker script for the sim85e2c simulator, which is a verilog simulation of
+   the V850E2 NA85E2C cpu core (CONFIG_V850E2_SIM85E2C).  */
+
+MEMORY {
+	/* 1MB of `instruction RAM', starting at 0.
+	   Instruction fetches are much faster from IRAM than from DRAM.  */
+	IRAM : ORIGIN = IRAM_ADDR, LENGTH = IRAM_SIZE
+
+	/* 1MB of `data RAM', below and contiguous with the I/O space.
+	   Data fetches are much faster from DRAM than from IRAM.  */
+	DRAM : ORIGIN = DRAM_ADDR, LENGTH = DRAM_SIZE
+
+	/* `external ram' (CS1 area), comes after IRAM.  */
+	ERAM : ORIGIN = ERAM_ADDR, LENGTH = ERAM_SIZE
+
+	/* Dynamic RAM; uses memory controller.  */
+	SDRAM : ORIGIN = SDRAM_ADDR, LENGTH = SDRAM_SIZE
+}
+
+SECTIONS {
+	.iram : {
+		INTV_CONTENTS
+		*arch/v850/kernel/head.o
+		*(.early.text)
+	} > IRAM
+	.dram : {
+		_memcons_output = . ;
+		. = . + 0x8000 ;
+		_memcons_output_end = . ;
+	} > DRAM
+	.sdram : {
+		/* We stick console output into a buffer here.  */
+		RAMK_KRAM_CONTENTS
+		ROOT_FS_CONTENTS
+	} > SDRAM
+}
diff -urN linux-2.4.29/arch/v850/kernel/sim.c linux-2.4.29-uc1/arch/v850/kernel/sim.c
--- linux-2.4.29/arch/v850/kernel/sim.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/sim.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,183 @@
+/*
+ * arch/v850/kernel/sim.c -- Machine-specific stuff for GDB v850e simulator
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+#include <asm/simsyscall.h>
+
+#include "mach.h"
+
+/* The name of a file containing the root filesystem.  */
+#define ROOT_FS "rootfs.image"
+
+extern void simcons_setup (void);
+extern void simcons_poll_ttys (void);
+
+/* These are where `blkmem' device 0 is allocated.  We put the root
+   filesystem there.  */
+unsigned long root_fs_image_addr, root_fs_image_len;
+/* Make the root filesystem R/W.  */
+int root_fs_image_rw = 1;
+
+static int read_file (const char *name,
+		      unsigned long *addr, unsigned long *len,
+		      const char **err);
+
+void __init mach_setup (char **cmdline)
+{
+	const char *err;
+
+	simcons_setup ();
+
+	printk (KERN_INFO "Reading root filesystem: %s", ROOT_FS);
+	if (read_file (ROOT_FS, &root_fs_image_addr, &root_fs_image_len, &err)) {
+		printk (" (size %luK)\n", root_fs_image_len / 1024);
+		ROOT_DEV = MKDEV (BLKMEM_MAJOR, 0);
+	} else {
+		static char bogus_blkmem_array[1];
+
+		printk ("...%s failed!\n", err);
+
+		/* blkmem is going to attempt to read the device even if
+		   we don't specify it as the root, so make sure it
+		   points to something innocuous.  */
+		root_fs_image_addr = (unsigned long)bogus_blkmem_array;
+		root_fs_image_len = 0;
+	}
+}
+
+void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len)
+{
+	*ram_start = RAM_ADDR;
+	*ram_len = RAM_SIZE;
+}
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* ...do magic timer initialization?...  */
+	mach_tick = simcons_poll_ttys;
+	setup_irq (0, timer_action);
+}
+
+
+static void irq_nop (unsigned irq) { }
+static unsigned irq_zero (unsigned irq) { return 0; }
+
+static struct hw_interrupt_type sim_irq_type = {
+	"IRQ",
+	irq_zero,		/* startup */
+	irq_nop,		/* shutdown */
+	irq_nop,		/* enable */
+	irq_nop,		/* disable */
+	irq_nop,		/* ack */
+	irq_nop,		/* end */
+};
+
+void __init mach_init_irqs (void)
+{
+	init_irq_handlers (0, NUM_MACH_IRQS, 1, &sim_irq_type);
+}
+
+
+void mach_gettimeofday (struct timeval *tv)
+{
+	long timeval[2], timezone[2];
+	int rval = V850_SIM_SYSCALL (gettimeofday, timeval, timezone);
+	if (rval == 0) {
+		tv->tv_sec = timeval[0];
+		tv->tv_usec = timeval[1];
+	}
+}
+
+void machine_restart (char *__unused)
+{
+	V850_SIM_SYSCALL (write, 1, "RESTART\n", 8);
+	V850_SIM_SYSCALL (exit, 0);
+}
+
+void machine_halt (void)
+{
+	V850_SIM_SYSCALL (write, 1, "HALT\n", 5);
+	V850_SIM_SYSCALL (exit, 0);
+}
+
+void machine_power_off (void)
+{
+	V850_SIM_SYSCALL (write, 1, "POWER OFF\n", 10);
+	V850_SIM_SYSCALL (exit, 0);
+}
+
+
+/* Load data from a file called NAME into ram.  The address and length
+   of the data image are returned in ADDR and LEN.  */
+static int __init
+read_file (const char *name,
+	   unsigned long *addr, unsigned long *len,
+	   const char **err)
+{
+	int rval, fd;
+	unsigned long cur, left;
+	/* Note this is not a normal stat buffer, it's an ad-hoc
+	   structure defined by the simulator.  */
+	unsigned long stat_buf[10];
+
+	/* Stat the file to find out the length.  */
+	rval = V850_SIM_SYSCALL (stat, name, stat_buf);
+	if (rval < 0) {
+		if (err) *err = "stat";
+		return 0;
+	}
+	*len = stat_buf[4];
+
+	/* Open the file; `0' is O_RDONLY.  */
+	fd = V850_SIM_SYSCALL (open, name, 0);
+	if (fd < 0) {
+		if (err) *err = "open";
+		return 0;
+	}
+
+	*addr = (unsigned long)alloc_bootmem(*len);
+	if (! *addr) {
+		V850_SIM_SYSCALL (close, fd);
+		if (err) *err = "alloc_bootmem";
+		return 0;
+	}
+
+	cur = *addr;
+	left = *len;
+	while (left > 0) {
+		int chunk = V850_SIM_SYSCALL (read, fd, cur, left);
+		if (chunk <= 0)
+			break;
+		cur += chunk;
+		left -= chunk;
+	}
+	V850_SIM_SYSCALL (close, fd);
+	if (left > 0) {
+		/* Some read failed.  */
+		free_bootmem (*addr, *len);
+		if (err) *err = "read";
+		return 0;
+	}
+
+	return 1;
+}
diff -urN linux-2.4.29/arch/v850/kernel/simcons.c linux-2.4.29-uc1/arch/v850/kernel/simcons.c
--- linux-2.4.29/arch/v850/kernel/simcons.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/simcons.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,158 @@
+/*
+ * arch/v850/kernel/simcons.c -- Console I/O for GDB v850e simulator
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/tty_driver.h>
+#include <linux/init.h>
+
+#include <asm/poll.h>
+#include <asm/simsyscall.h>
+
+
+/*  Low-level console. */
+
+static void simcons_write (struct console *co, const char *buf, unsigned len)
+{
+	V850_SIM_SYSCALL (write, 1, buf, len);
+}
+
+static int simcons_read (struct console *co, char *buf, unsigned len)
+{
+	return V850_SIM_SYSCALL (read, 0, buf, len);
+}
+
+static kdev_t simcons_device (struct console *c)
+{
+        return MKDEV (TTY_MAJOR, 64 + c->index);
+}
+
+static struct console simcons =
+{
+    .name	= "simcons",
+    .write	= simcons_write,
+    .read	= simcons_read,
+    .device	= simcons_device,
+    .flags	= CON_PRINTBUFFER,
+    .index	= -1,
+};
+
+/* Higher level TTY interface.  */
+
+static struct tty_struct *tty_table[1] = { 0 };
+static struct termios *tty_termios[1] = { 0 };
+static struct termios *tty_termios_locked[1] = { 0 };
+static struct tty_driver tty_driver = { 0 };
+static int tty_refcount = 0;
+
+int simcons_tty_open (struct tty_struct *tty, struct file *filp)
+{
+	return 0;
+}
+
+int simcons_tty_write (struct tty_struct *tty, int from_user,
+		       const unsigned char *buf, int count)
+{
+	return V850_SIM_SYSCALL (write, 1, buf, count);
+}
+
+int simcons_tty_write_room (struct tty_struct *tty)
+{
+	/* Completely arbitrary.  */
+	return 0x100000;
+}
+
+int simcons_tty_chars_in_buffer (struct tty_struct *tty)
+{
+	/* We have no buffer.  */
+	return 0;
+}
+
+int __init simcons_tty_init (void)
+{
+	tty_driver.name = "simcons";
+	tty_driver.major = TTY_MAJOR;
+	tty_driver.minor_start = 64;
+	tty_driver.num = 1;
+	tty_driver.type = TTY_DRIVER_TYPE_SYSCONS;
+
+	tty_driver.refcount = &tty_refcount;
+
+	tty_driver.table = tty_table;
+	tty_driver.termios = tty_termios;
+	tty_driver.termios_locked = tty_termios_locked;
+
+	tty_driver.init_termios = tty_std_termios;
+
+	tty_driver.open = simcons_tty_open;
+	tty_driver.write = simcons_tty_write;
+	tty_driver.write_room = simcons_tty_write_room;
+	tty_driver.chars_in_buffer = simcons_tty_chars_in_buffer;
+
+	tty_register_driver (&tty_driver);
+}
+__initcall (simcons_tty_init);
+
+/* Poll for input on the console, and if there's any, deliver it to the
+   tty driver.  */
+void simcons_poll_tty (struct tty_struct *tty)
+{
+	int flip = 0, send_break = 0;
+	struct pollfd pfd;
+	pfd.fd = 0;
+	pfd.events = POLLIN;
+
+	if (V850_SIM_SYSCALL (poll, &pfd, 1, 0) > 0) {
+		if (pfd.revents & POLLIN) {
+			int left = TTY_FLIPBUF_SIZE - tty->flip.count;
+
+			if (left > 0) {
+				unsigned char *buf = tty->flip.char_buf_ptr;
+				int rd = V850_SIM_SYSCALL (read, 0, buf, left);
+
+				if (rd > 0) {
+					tty->flip.count += rd;
+					tty->flip.char_buf_ptr += rd;
+					memset (tty->flip.flag_buf_ptr, 0, rd);
+					tty->flip.flag_buf_ptr += rd;
+					flip = 1;
+				} else
+					send_break = 1;
+			}
+		} else if (pfd.revents & POLLERR)
+			send_break = 1;
+	}
+
+	if (send_break) {
+		tty_insert_flip_char (tty, 0, TTY_BREAK);		
+		flip = 1;
+	}
+
+	if (flip)
+		tty_schedule_flip (tty);
+}
+
+void simcons_poll_ttys (void)
+{
+	if (tty_table[0])
+		simcons_poll_tty (tty_table[0]);
+}
+
+void simcons_setup (void)
+{
+	V850_SIM_SYSCALL (make_raw, 0);
+	register_console (&simcons);
+	printk (KERN_INFO "Console: GDB V850E simulator stdio\n");
+}
diff -urN linux-2.4.29/arch/v850/kernel/sim.ld linux-2.4.29-uc1/arch/v850/kernel/sim.ld
--- linux-2.4.29/arch/v850/kernel/sim.ld	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/sim.ld	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,13 @@
+/* Linker script for the gdb v850e simulator (CONFIG_V850E_SIM).  */
+
+MEMORY {
+	/* Interrupt vectors.  */
+	INTV  : ORIGIN = 0x0, LENGTH = 0xe0
+	/* Main RAM.  */
+	RAM   : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE
+}
+
+SECTIONS {
+	.intv : { INTV_CONTENTS } > INTV
+	.ram : { RAMK_KRAM_CONTENTS } > RAM
+}
diff -urN linux-2.4.29/arch/v850/kernel/syscalls.c linux-2.4.29-uc1/arch/v850/kernel/syscalls.c
--- linux-2.4.29/arch/v850/kernel/syscalls.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/syscalls.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,205 @@
+/*
+ * arch/v850/kernel/syscalls.c -- Various system-call definitions not
+ * 	defined in machine-independent code
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * This file was derived the ppc version, arch/ppc/kernel/syscalls.c
+ * ... which was derived from "arch/i386/kernel/sys_i386.c" by Gary Thomas;
+ *     modified by Cort Dougan (cort@cs.nmt.edu)
+ *     and Paul Mackerras (paulus@cs.anu.edu.au).
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/sys.h>
+#include <linux/ipc.h>
+#include <linux/utsname.h>
+#include <linux/file.h>
+
+#include <asm/uaccess.h>
+#include <asm/ipc.h>
+#include <asm/semaphore.h>
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+int
+sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	ret = -EINVAL;
+	switch (call) {
+	case SEMOP:
+		ret = sys_semop (first, (struct sembuf *)ptr, second);
+		break;
+	case SEMGET:
+		ret = sys_semget (first, second, third);
+		break;
+	case SEMCTL:
+	{
+		union semun fourth;
+
+		if (!ptr)
+			break;
+		if ((ret = verify_area (VERIFY_READ, ptr, sizeof(long)))
+		    || (ret = get_user(fourth.__pad, (void **)ptr)))
+			break;
+		ret = sys_semctl (first, second, third, fourth);
+		break;
+	}
+	case MSGSND:
+		ret = sys_msgsnd (first, (struct msgbuf *) ptr, second, third);
+		break;
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
+
+			if (!ptr)
+				break;
+			if ((ret = verify_area (VERIFY_READ, ptr, sizeof(tmp)))
+			    || (ret = copy_from_user(&tmp,
+						(struct ipc_kludge *) ptr,
+						sizeof (tmp))))
+				break;
+			ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp,
+					  third);
+			break;
+			}
+		default:
+			ret = sys_msgrcv (first, (struct msgbuf *) ptr,
+					  second, fifth, third);
+			break;
+		}
+		break;
+	case MSGGET:
+		ret = sys_msgget ((key_t) first, second);
+		break;
+	case MSGCTL:
+		ret = sys_msgctl (first, second, (struct msqid_ds *) ptr);
+		break;
+	case SHMAT:
+		switch (version) {
+		default: {
+			ulong raddr;
+
+			if ((ret = verify_area(VERIFY_WRITE, (ulong*) third,
+					       sizeof(ulong))))
+				break;
+			ret = sys_shmat (first, (char *) ptr, second, &raddr);
+			if (ret)
+				break;
+			ret = put_user (raddr, (ulong *) third);
+			break;
+			}
+		case 1:	/* iBCS2 emulator entry point */
+			if (!segment_eq(get_fs(), get_ds()))
+				break;
+			ret = sys_shmat (first, (char *) ptr, second,
+					 (ulong *) third);
+			break;
+		}
+		break;
+	case SHMDT: 
+		ret = sys_shmdt ((char *)ptr);
+		break;
+	case SHMGET:
+		ret = sys_shmget (first, second, third);
+		break;
+	case SHMCTL:
+		ret = sys_shmctl (first, second, (struct shmid_ds *) ptr);
+		break;
+	}
+
+	return ret;
+}
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+int sys_pipe (int *fildes)
+{
+	int fd[2];
+	int error;
+
+	error = do_pipe (fd);
+	if (!error) {
+		if (copy_to_user (fildes, fd, 2*sizeof (int)))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+static inline unsigned long
+do_mmap2 (unsigned long addr, size_t len,
+	 unsigned long prot, unsigned long flags,
+	 unsigned long fd, unsigned long pgoff)
+{
+	struct file * file = NULL;
+	int ret = -EBADF;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (! (flags & MAP_ANONYMOUS)) {
+		if (!(file = fget (fd)))
+			goto out;
+	}
+	
+	down_write (&current->mm->mmap_sem);
+	ret = do_mmap_pgoff (file, addr, len, prot, flags, pgoff);
+	up_write (&current->mm->mmap_sem);
+	if (file)
+		fput (file);
+out:
+	return ret;
+}
+
+unsigned long sys_mmap2 (unsigned long addr, size_t len,
+			unsigned long prot, unsigned long flags,
+			unsigned long fd, unsigned long pgoff)
+{
+	return do_mmap2 (addr, len, prot, flags, fd, pgoff);
+}
+
+unsigned long sys_mmap (unsigned long addr, size_t len,
+		       unsigned long prot, unsigned long flags,
+		       unsigned long fd, off_t offset)
+{
+	int err = -EINVAL;
+
+	if (offset & ~PAGE_MASK)
+		goto out;
+
+	err = do_mmap2 (addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+out:
+	return err;
+}
+
+int sys_pause (void)
+{
+	current->state = TASK_INTERRUPTIBLE;
+	schedule ();
+	return -ERESTARTNOHAND;
+}
+
diff -urN linux-2.4.29/arch/v850/kernel/teg.c linux-2.4.29-uc1/arch/v850/kernel/teg.c
--- linux-2.4.29/arch/v850/kernel/teg.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/teg.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,63 @@
+/*
+ * arch/v850/kernel/teg.c -- NB85E-TEG cpu chip
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+#include <asm/v850e_timer_d.h>
+
+#include "mach.h"
+
+void __init mach_sched_init (struct irqaction *timer_action)
+{
+	/* Select timer interrupt instead of external pin.  */
+	TEG_ISS |= 0x1;
+	/* Start hardware timer.  */
+	v850e_timer_d_configure (0, HZ);
+	/* Install timer interrupt handler.  */
+	setup_irq (IRQ_INTCMD(0), timer_action);
+}
+
+static struct v850e_intc_irq_init irq_inits[] = {
+	{ "IRQ", 0,		NUM_CPU_IRQS,	1, 7 },
+	{ "CMD", IRQ_INTCMD(0),	IRQ_INTCMD_NUM,	1, 5 },
+	{ "SER", IRQ_INTSER(0),	IRQ_INTSER_NUM,	1, 3 },
+	{ "SR",	 IRQ_INTSR(0),	IRQ_INTSR_NUM,	1, 4 },
+	{ "ST",	 IRQ_INTST(0),	IRQ_INTST_NUM,	1, 5 },
+	{ 0 }
+};
+#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
+
+static struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
+
+/* Initialize MA chip interrupts.  */
+void __init teg_init_irqs (void)
+{
+	v850e_intc_init_irq_types (irq_inits, hw_itypes);
+}
+
+/* Called before configuring an on-chip UART.  */
+void teg_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud)
+{
+	/* Enable UART I/O pins instead of external interrupt pins, and
+	   UART interrupts instead of external pin interrupts.  */
+	TEG_ISS |= 0x4E;
+}
diff -urN linux-2.4.29/arch/v850/kernel/time.c linux-2.4.29-uc1/arch/v850/kernel/time.c
--- linux-2.4.29/arch/v850/kernel/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/time.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,185 @@
+/*
+ * linux/arch/v850/kernel/time.c -- Arch-dependent timer functions
+ *
+ *  Copyright (C) 1991, 1992, 1995, 2001, 2002  Linus Torvalds
+ *
+ * This file contains the v850-specific time handling details.
+ * Most of the stuff is located in the machine specific files.
+ *
+ * 1997-09-10	Updated NTP code according to technical memorandum Jan '96
+ *		"A Kernel Model for Precision Timekeeping" by Dave Mills
+ */
+
+#include <linux/config.h> /* CONFIG_HEARTBEAT */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+
+#include <linux/timex.h>
+
+#include "mach.h"
+
+static inline void do_profile (unsigned long pc)
+{
+	if (prof_buffer && current->pid) {
+		extern int _stext;
+		pc -= (unsigned long) &_stext;
+		pc >>= prof_shift;
+		if (pc < prof_len)
+			++prof_buffer[pc];
+		else
+		/*
+		 * Don't ignore out-of-bounds PC values silently,
+		 * put them into the last histogram slot, so if
+		 * present, they will show up as a sharp peak.
+		 */
+			++prof_buffer[prof_len-1];
+	}
+}
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+static void timer_interrupt (int irq, void *dummy, struct pt_regs *regs)
+{
+#if 0
+	/* last time the cmos clock got updated */
+	static long last_rtc_update=0;
+#endif
+
+	/* may need to kick the hardware timer */
+	if (mach_tick)
+	  mach_tick ();
+
+	do_timer (regs);
+
+	if (! user_mode (regs))
+		do_profile (regs->pc);
+
+#if 0
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
+	    xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
+	  if (set_rtc_mmss (xtime.tv_sec) == 0)
+	    last_rtc_update = xtime.tv_sec;
+	  else
+	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	}
+#ifdef CONFIG_HEARTBEAT
+	/* use power LED as a heartbeat instead -- much more useful
+	   for debugging -- based on the version for PReP by Cort */
+	/* acts like an actual heart beat -- ie thump-thump-pause... */
+	if (mach_heartbeat) {
+	    static unsigned cnt = 0, period = 0, dist = 0;
+
+	    if (cnt == 0 || cnt == dist)
+		mach_heartbeat ( 1 );
+	    else if (cnt == 7 || cnt == dist+7)
+		mach_heartbeat ( 0 );
+
+	    if (++cnt > period) {
+		cnt = 0;
+		/* The hyperbolic function below modifies the heartbeat period
+		 * length in dependency of the current (5min) load. It goes
+		 * through the points f(0)=126, f(1)=86, f(5)=51,
+		 * f(inf)->30. */
+		period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
+		dist = period / 4;
+	    }
+	}
+#endif /* CONFIG_HEARTBEAT */
+#endif /* 0 */
+}
+
+extern rwlock_t xtime_lock;
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ */
+void do_gettimeofday (struct timeval *tv)
+{
+#if 0 /* DAVIDM later if possible */
+	extern volatile unsigned long lost_ticks;
+	unsigned long lost;
+#endif
+	unsigned long flags;
+	unsigned long usec, sec;
+
+	read_lock_irqsave (&xtime_lock, flags);
+#if 0
+	usec = mach_gettimeoffset ? mach_gettimeoffset () : 0;
+#else
+	usec = 0;
+#endif
+#if 0 /* DAVIDM later if possible */
+	lost = lost_ticks;
+	if (lost)
+		usec += lost * (1000000/HZ);
+#endif
+	sec = xtime.tv_sec;
+	usec += xtime.tv_usec;
+	read_unlock_irqrestore (&xtime_lock, flags);
+
+	while (usec >= 1000000) {
+		usec -= 1000000;
+		sec++;
+	}
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+void do_settimeofday (struct timeval *tv)
+{
+	write_lock_irq (&xtime_lock);
+	/* This is revolting. We need to set the xtime.tv_usec
+	 * correctly. However, the value in this location is
+	 * is value at the last tick.
+	 * Discover what correction gettimeofday
+	 * would have done, and then undo it!
+	 */
+#if 0
+	tv->tv_usec -= mach_gettimeoffset ();
+#endif
+
+	while (tv->tv_usec < 0) {
+		tv->tv_usec += 1000000;
+		tv->tv_sec--;
+	}
+
+	xtime = *tv;
+	time_adjust = 0;		/* stop active adjtime () */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+	write_unlock_irq (&xtime_lock);
+}
+
+static int timer_dev_id;
+static struct irqaction timer_irqaction = {
+	timer_interrupt,
+	SA_INTERRUPT,
+	0,
+	"timer",
+	&timer_dev_id,
+	NULL
+};
+
+void time_init (void)
+{
+	mach_gettimeofday (&xtime);
+	mach_sched_init (&timer_irqaction);
+}
diff -urN linux-2.4.29/arch/v850/kernel/v850_defs.c linux-2.4.29-uc1/arch/v850/kernel/v850_defs.c
--- linux-2.4.29/arch/v850/kernel/v850_defs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/v850_defs.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,61 @@
+/*
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ */
+
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/irq.h>
+#include <asm/hardirq.h>
+#include <asm/errno.h>
+
+#define DEFINE(sym, val) \
+	asm volatile ("\n#define " #sym " %0" : : "i" (val))
+
+int main (void)
+{
+	/* offsets into the task struct */
+	DEFINE (TASK_STATE, offsetof (struct task_struct, state));
+	DEFINE (TASK_FLAGS, offsetof (struct task_struct, flags));
+	DEFINE (TASK_PTRACE, offsetof (struct task_struct, ptrace));
+	DEFINE (TASK_BLOCKED, offsetof (struct task_struct, blocked));
+	DEFINE (TASK_COUNTER, offsetof (struct task_struct, counter));
+	DEFINE (TASK_SIGPENDING, offsetof (struct task_struct, sigpending));
+	DEFINE (TASK_NEED_RESCHED, offsetof (struct task_struct, need_resched));
+	DEFINE (TASK_THREAD, offsetof (struct task_struct, thread));
+	DEFINE (TASK_MM, offsetof (struct task_struct, mm));
+	DEFINE (TASK_ACTIVE_MM, offsetof (struct task_struct, active_mm));
+	DEFINE (TASK_PID, offsetof (struct task_struct, pid));
+
+	/* offsets into the kernel_stat struct */
+	DEFINE (STAT_IRQ, offsetof (struct kernel_stat, irqs));
+
+
+	/* signal defines */
+	DEFINE (SIGSEGV, SIGSEGV);
+	DEFINE (SEGV_MAPERR, SEGV_MAPERR);
+	DEFINE (SIGTRAP, SIGTRAP);
+	DEFINE (SIGCHLD, SIGCHLD);
+	DEFINE (SIGILL, SIGILL);
+	DEFINE (TRAP_TRACE, TRAP_TRACE);
+
+	/* ptrace flag bits */
+	DEFINE (PT_PTRACED, PT_PTRACED);
+	DEFINE (PT_TRACESYS, PT_TRACESYS);
+	DEFINE (PT_DTRACE, PT_DTRACE);
+
+	/* error values */
+	DEFINE (ENOSYS, ENOSYS);
+
+	/* clone flag bits */
+	DEFINE (CLONE_VFORK, CLONE_VFORK);
+	DEFINE (CLONE_VM, CLONE_VM);
+
+	return 0;
+}
diff -urN linux-2.4.29/arch/v850/kernel/v850_defs.head linux-2.4.29-uc1/arch/v850/kernel/v850_defs.head
--- linux-2.4.29/arch/v850/kernel/v850_defs.head	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/v850_defs.head	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * WARNING! This file is automatically generated - DO NOT EDIT!
+ */
+
+#define TS_MAGICKEY	0x5a5a5a5a
diff -urN linux-2.4.29/arch/v850/kernel/v850e2_cache.c linux-2.4.29-uc1/arch/v850/kernel/v850e2_cache.c
--- linux-2.4.29/arch/v850/kernel/v850e2_cache.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/v850e2_cache.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,127 @@
+/*
+ * arch/v850/kernel/v850e2_cache.c -- Cache control for V850E2 cache
+ * 	memories
+ *
+ *  Copyright (C) 2003  NEC Electronics Corporation
+ *  Copyright (C) 2003  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/mm.h>
+
+#include <asm/v850e2_cache.h>
+
+/* Cache operations we can do.  The encoding corresponds directly to the
+   value we need to write into the COPR register.  */
+enum cache_op {
+	OP_SYNC_IF_DIRTY 	   = V850E2_CACHE_COPR_CFC(0), /* 000 */
+	OP_SYNC_IF_VALID 	   = V850E2_CACHE_COPR_CFC(1), /* 001 */
+	OP_SYNC_IF_VALID_AND_CLEAR = V850E2_CACHE_COPR_CFC(3), /* 011 */
+	OP_WAY_CLEAR 		   = V850E2_CACHE_COPR_CFC(4), /* 100 */
+	OP_FILL 		   = V850E2_CACHE_COPR_CFC(5), /* 101 */
+	OP_CLEAR 		   = V850E2_CACHE_COPR_CFC(6), /* 110 */
+	OP_CREATE_DIRTY 	   = V850E2_CACHE_COPR_CFC(7)  /* 111 */
+};
+
+/* Which cache to use.  This encoding also corresponds directly to the
+   value we need to write into the COPR register. */
+enum cache {
+	ICACHE = 0,
+	DCACHE = V850E2_CACHE_COPR_LBSL
+};
+
+/* Returns ADDR rounded down to the beginning of its cache-line.  */
+#define CACHE_LINE_ADDR(addr)  \
+   ((addr) & ~(V850E2_CACHE_LINE_SIZE - 1))
+/* Returns END_ADDR rounded up to the `limit' of its cache-line.  */
+#define CACHE_LINE_END_ADDR(end_addr)  \
+   CACHE_LINE_ADDR(end_addr + (V850E2_CACHE_LINE_SIZE - 1))
+
+
+/* Low-level cache ops.  */
+
+/* Apply cache-op OP to all entries in CACHE.  */
+static inline void cache_op_all (enum cache_op op, enum cache cache)
+{
+	int cmd = op | cache | V850E2_CACHE_COPR_WSLE | V850E2_CACHE_COPR_STRT;
+
+	if (op != OP_WAY_CLEAR) {
+		/* The WAY_CLEAR operation does the whole way, but other
+		   ops take begin-index and count params; we just indicate
+		   the entire cache.  */
+		V850E2_CACHE_CADL = 0;
+		V850E2_CACHE_CADH = 0;
+		V850E2_CACHE_CCNT = V850E2_CACHE_WAY_SIZE - 1;
+	}
+
+	V850E2_CACHE_COPR = cmd | V850E2_CACHE_COPR_WSL(0); /* way 0 */
+	V850E2_CACHE_COPR = cmd | V850E2_CACHE_COPR_WSL(1); /* way 1 */
+	V850E2_CACHE_COPR = cmd | V850E2_CACHE_COPR_WSL(2); /* way 2 */
+	V850E2_CACHE_COPR = cmd | V850E2_CACHE_COPR_WSL(3); /* way 3 */
+}
+
+/* Apply cache-op OP to all entries in CACHE covering addresses ADDR
+   through ADDR+LEN.  */
+static inline void cache_op_range (enum cache_op op, u32 addr, u32 len,
+				   enum cache cache)
+{
+	u32 start = CACHE_LINE_ADDR (addr);
+	u32 end = CACHE_LINE_END_ADDR (addr + len);
+	u32 num_lines = (end - start) >> V850E2_CACHE_LINE_SIZE_BITS;
+
+	V850E2_CACHE_CADL = start & 0xFFFF;
+	V850E2_CACHE_CADH = start >> 16;
+	V850E2_CACHE_CCNT = num_lines - 1;
+
+	V850E2_CACHE_COPR = op | cache | V850E2_CACHE_COPR_STRT;
+}
+
+
+/* High-level ops.  */
+
+static void cache_exec_after_store_all (void)
+{
+	cache_op_all (OP_SYNC_IF_DIRTY, DCACHE);
+	cache_op_all (OP_WAY_CLEAR, ICACHE);
+}
+
+static void cache_exec_after_store_range (u32 start, u32 len)
+{
+	cache_op_range (OP_SYNC_IF_DIRTY, start, len, DCACHE);
+	cache_op_range (OP_CLEAR, start, len, ICACHE);
+}
+
+
+/* Exported functions.  */
+
+void flush_icache (void)
+{
+	cache_exec_after_store_all ();
+}
+
+void flush_icache_range (unsigned long start, unsigned long end)
+{
+	cache_exec_after_store_range (start, end - start);
+}
+
+void flush_icache_page (struct vm_area_struct *vma, struct page *page)
+{
+	cache_exec_after_store_range (page_to_virt (page), PAGE_SIZE);
+}
+
+void flush_icache_user_range (struct vm_area_struct *vma, struct page *page,
+			      unsigned long addr, int len)
+{
+	cache_exec_after_store_range (addr, len);
+}
+
+void flush_cache_sigtramp (unsigned long addr)
+{
+	/* For the exact size, see signal.c, but 16 bytes should be enough.  */
+	cache_exec_after_store_range (addr, 16);
+}
diff -urN linux-2.4.29/arch/v850/kernel/v850e_cache.c linux-2.4.29-uc1/arch/v850/kernel/v850e_cache.c
--- linux-2.4.29/arch/v850/kernel/v850e_cache.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/v850e_cache.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,173 @@
+/*
+ * arch/v850/kernel/v850e_cache.c -- Cache control for V850E cache memories
+ *
+ *  Copyright (C) 2003  NEC Electronics Corporation
+ *  Copyright (C) 2003  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+/* This file implements cache control for the rather simple cache used on
+   some V850E CPUs, specifically the NB85E/TEG CPU-core and the V850E/ME2
+   CPU.  V850E2 processors have their own (better) cache
+   implementation.  */
+
+#include <asm/entry.h>
+#include <asm/v850e_cache.h>
+
+#define WAIT_UNTIL_CLEAR(value) while (value) {}
+
+/* Set caching params via the BHC and DCC registers.  */
+void v850e_cache_enable (u16 bhc, u16 icc, u16 dcc)
+{
+	unsigned long *r0_ram = (unsigned long *)R0_RAM_ADDR;
+	register u16 bhc_val asm ("r6") = bhc;
+
+	/* Read the instruction cache control register (ICC) and confirm
+	   that bits 0 and 1 (TCLR0, TCLR1) are all cleared.  */
+	WAIT_UNTIL_CLEAR (V850E_CACHE_ICC & 0x3);
+	V850E_CACHE_ICC = icc;
+
+#ifdef V850E_CACHE_DCC
+	/* Configure data-cache.  */
+	V850E_CACHE_DCC = dcc;
+#endif /* V850E_CACHE_DCC */
+
+	/* Configure caching for various memory regions by writing the BHC
+	   register.  The documentation says that an instruction _cannot_
+	   enable/disable caching for the memory region in which the
+	   instruction itself exists; to work around this, we store
+	   appropriate instructions into the on-chip RAM area (which is never
+	   cached), and briefly jump there to do the work.  */
+#ifdef V850E_CACHE_WRITE_IBS
+	*r0_ram++ 	= 0xf0720760;	/* st.h r0, 0xfffff072[r0] */
+#endif
+	*r0_ram++ 	= 0xf06a3760;	/* st.h r6, 0xfffff06a[r0] */
+	*r0_ram 	= 0x5640006b;	/* jmp [r11] */
+
+	asm ("mov hilo(1f), r11; jmp [%1]; 1:;"
+	     :: "r" (bhc_val), "r" (R0_RAM_ADDR) : "r11");
+}
+
+static void clear_icache (void)
+{
+	/* 1. Read the instruction cache control register (ICC) and confirm
+	      that bits 0 and 1 (TCLR0, TCLR1) are all cleared.  */
+	WAIT_UNTIL_CLEAR (V850E_CACHE_ICC & 0x3);
+
+	/* 2. Read the ICC register and confirm that bit 12 (LOCK0) is
+  	      cleared.  Bit 13 of the ICC register is always cleared.  */
+	WAIT_UNTIL_CLEAR (V850E_CACHE_ICC & 0x1000);
+
+	/* 3. Set the TCLR0 and TCLR1 bits of the ICC register as follows,
+	      when clearing way 0 and way 1 at the same time:
+	        (a) Set the TCLR0 and TCLR1 bits.
+		(b) Read the TCLR0 and TCLR1 bits to confirm that these bits
+		    are cleared.
+		(c) Perform (a) and (b) above again.  */
+	V850E_CACHE_ICC |= 0x3;
+	WAIT_UNTIL_CLEAR (V850E_CACHE_ICC & 0x3);
+
+#ifdef V850E_CACHE_REPEAT_ICC_WRITE
+	/* Do it again.  */
+	V850E_CACHE_ICC |= 0x3;
+	WAIT_UNTIL_CLEAR (V850E_CACHE_ICC & 0x3);
+#endif
+}
+
+#ifdef V850E_CACHE_DCC
+/* Flush or clear (or both) the data cache, depending on the value of FLAGS;
+   the procedure is the same for both, just the control bits used differ (and
+   both may be performed simultaneously).  */
+static void dcache_op (unsigned short flags)
+{
+	/* 1. Read the data cache control register (DCC) and confirm that bits
+	      0, 1, 4, and 5 (DC00, DC01, DC04, DC05) are all cleared.  */
+	WAIT_UNTIL_CLEAR (V850E_CACHE_DCC & 0x33);
+
+	/* 2. Clear DCC register bit 12 (DC12), bit 13 (DC13), or both
+	      depending on the way for which tags are to be cleared.  */
+	V850E_CACHE_DCC &= ~0xC000;
+
+	/* 3. Set DCC register bit 0 (DC00), bit 1 (DC01) or both depending on
+	      the way for which tags are to be cleared.
+	      ...
+	      Set DCC register bit 4 (DC04), bit 5 (DC05), or both depending
+	      on the way to be data flushed.  */
+	V850E_CACHE_DCC |= flags;
+
+	/* 4. Read DCC register bit DC00, DC01 [DC04, DC05], or both depending
+	      on the way for which tags were cleared [flushed] and confirm
+	      that that bit is cleared.  */
+	WAIT_UNTIL_CLEAR (V850E_CACHE_DCC & flags);
+}
+#endif /* V850E_CACHE_DCC */
+
+/* Flushes the contents of the dcache to memory.  */
+static inline void flush_dcache (void)
+{
+#ifdef V850E_CACHE_DCC
+	/* We only need to do something if in write-back mode.  */
+	if (V850E_CACHE_DCC & 0x0400)
+		dcache_op (0x30);
+#endif /* V850E_CACHE_DCC */
+}
+
+/* Flushes the contents of the dcache to memory, and then clears it.  */
+static inline void clear_dcache (void)
+{
+#ifdef V850E_CACHE_DCC
+	/* We only need to do something if the dcache is enabled.  */
+	if (V850E_CACHE_DCC & 0x0C00)
+		dcache_op (0x33);
+#endif /* V850E_CACHE_DCC */
+}
+
+/* Clears the dcache without flushing to memory first.  */
+static inline void clear_dcache_no_flush (void)
+{
+#ifdef V850E_CACHE_DCC
+	/* We only need to do something if the dcache is enabled.  */
+	if (V850E_CACHE_DCC & 0x0C00)
+		dcache_op (0x3);
+#endif /* V850E_CACHE_DCC */
+}
+
+static inline void cache_exec_after_store (void)
+{
+	flush_dcache ();
+	clear_icache ();
+}
+
+
+/* Exported functions.  */
+
+void flush_icache (void)
+{
+	cache_exec_after_store ();
+}
+
+void flush_icache_range (unsigned long start, unsigned long end)
+{
+	cache_exec_after_store ();
+}
+
+void flush_icache_page (struct vm_area_struct *vma, struct page *page)
+{
+	cache_exec_after_store ();
+}
+
+void flush_icache_user_range (struct vm_area_struct *vma, struct page *page,
+			      unsigned long adr, int len)
+{
+	cache_exec_after_store ();
+}
+
+void flush_cache_sigtramp (unsigned long addr)
+{
+	cache_exec_after_store ();
+}
diff -urN linux-2.4.29/arch/v850/kernel/v850e_intc.c linux-2.4.29-uc1/arch/v850/kernel/v850e_intc.c
--- linux-2.4.29/arch/v850/kernel/v850e_intc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/v850e_intc.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,104 @@
+/*
+ * arch/v850/kernel/v850e_intc.c -- V850E interrupt controller (INTC)
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/v850e_intc.h>
+
+static void irq_nop (unsigned irq) { }
+
+static unsigned v850e_intc_irq_startup (unsigned irq)
+{
+	v850e_intc_clear_pending_irq (irq);
+	v850e_intc_enable_irq (irq);
+	return 0;
+}
+
+static void v850e_intc_end_irq (unsigned irq)
+{
+	unsigned long psw, temp;
+
+	/* Clear the highest-level bit in the In-service priority register
+	   (ISPR), to allow this interrupt (or another of the same or
+	   lesser priority) to happen again.
+
+	   The `reti' instruction normally does this automatically when the
+	   PSW bits EP and NP are zero, but we can't always rely on reti
+	   being used consistently to return after an interrupt (another
+	   process can be scheduled, for instance, which can delay the
+	   associated reti for a long time, or this process may be being
+	   single-stepped, which uses the `dbret' instruction to return
+	   from the kernel).
+
+	   We also set the PSW EP bit, which prevents reti from also
+	   trying to modify the ISPR itself.  */
+
+	/* Get PSW and disable interrupts.  */
+	asm volatile ("stsr psw, %0; di" : "=r" (psw));
+	/* We don't want to do anything for NMIs (they don't use the ISPR).  */
+	if (! (psw & 0xC0)) {
+		/* Transition to `trap' state, so that an eventual real
+		   reti instruction won't modify the ISPR.  */
+		psw |= 0x40;
+		/* Fake an interrupt return, which automatically clears the
+		   appropriate bit in the ISPR.  */
+		asm volatile ("mov hilo(1f), %0;"
+			      "ldsr %0, eipc; ldsr %1, eipsw;"
+			      "reti;"
+			      "1:"
+			      : "=&r" (temp) : "r" (psw));
+	}
+}
+
+/* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
+   INITS (which is terminated by an entry with the name field == 0).  */
+void __init v850e_intc_init_irq_types (struct v850e_intc_irq_init *inits,
+				       struct hw_interrupt_type *hw_irq_types)
+{
+	struct v850e_intc_irq_init *init;
+	for (init = inits; init->name; init++) {
+		unsigned i;
+		struct hw_interrupt_type *hwit = hw_irq_types++;
+
+		hwit->typename = init->name;
+
+		hwit->startup  = v850e_intc_irq_startup;
+		hwit->shutdown = v850e_intc_disable_irq;
+		hwit->enable   = v850e_intc_enable_irq;
+		hwit->disable  = v850e_intc_disable_irq;
+		hwit->ack      = irq_nop;
+		hwit->end      = v850e_intc_end_irq;
+		
+		/* Initialize kernel IRQ infrastructure for this interrupt.  */
+		init_irq_handlers(init->base, init->num, init->interval, hwit);
+
+		/* Set the interrupt priorities.  */
+		for (i = 0; i < init->num; i++) {
+			unsigned irq = init->base + i * init->interval;
+
+			/* If the interrupt is currently enabled (all
+			   interrupts are initially disabled), then
+			   assume whoever enabled it has set things up
+			   properly, and avoid messing with it.  */
+			if (! v850e_intc_irq_enabled (irq))
+				/* This write also (1) disables the
+				   interrupt, and (2) clears any pending
+				   interrupts.  */
+				V850E_INTC_IC (irq)
+					= (V850E_INTC_IC_PR (init->priority)
+					   | V850E_INTC_IC_MK);
+		}
+	}
+}
diff -urN linux-2.4.29/arch/v850/kernel/v850e_timer_d.c linux-2.4.29-uc1/arch/v850/kernel/v850e_timer_d.c
--- linux-2.4.29/arch/v850/kernel/v850e_timer_d.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/v850e_timer_d.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,54 @@
+/*
+ * include/asm-v850/v850e_timer_d.c -- `Timer D' component often used
+ *	with V850E CPUs
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/kernel.h>
+
+#include <asm/v850e_utils.h>
+#include <asm/v850e_timer_d.h>
+
+/* Start interval timer TIMER (0-3).  The timer will issue the
+   corresponding INTCMD interrupt RATE times per second.
+   This function does not enable the interrupt.  */
+void v850e_timer_d_configure (unsigned timer, unsigned rate)
+{
+	unsigned divlog2, count;
+
+	/* Calculate params for timer.  */
+	if (! calc_counter_params (
+		    V850E_TIMER_D_BASE_FREQ, rate,
+		    V850E_TIMER_D_TMCD_CS_MIN, V850E_TIMER_D_TMCD_CS_MAX, 16,
+		    &divlog2, &count))
+		printk (KERN_WARNING
+			"Cannot find interval timer %d setting suitable"
+			" for rate of %dHz.\n"
+			"Using rate of %dHz instead.\n",
+			timer, rate,
+			(V850E_TIMER_D_BASE_FREQ >> divlog2) >> 16);
+
+	/* Do the actual hardware timer initialization:  */
+
+	/* Enable timer.  */
+	V850E_TIMER_D_TMCD(timer) = V850E_TIMER_D_TMCD_CAE;
+	/* Set clock divider.  */
+	V850E_TIMER_D_TMCD(timer)
+		= V850E_TIMER_D_TMCD_CAE
+		| V850E_TIMER_D_TMCD_CS(divlog2);
+	/* Set timer compare register.  */
+	V850E_TIMER_D_CMD(timer) = count;
+	/* Start counting.  */
+	V850E_TIMER_D_TMCD(timer)
+		= V850E_TIMER_D_TMCD_CAE
+		| V850E_TIMER_D_TMCD_CS(divlog2)
+		| V850E_TIMER_D_TMCD_CE;
+}
diff -urN linux-2.4.29/arch/v850/kernel/v850e_utils.c linux-2.4.29-uc1/arch/v850/kernel/v850e_utils.c
--- linux-2.4.29/arch/v850/kernel/v850e_utils.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/v850e_utils.c	2005-06-14 02:11:05.000000000 +0100
@@ -0,0 +1,62 @@
+/*
+ * include/asm-v850/v850e_utils.h -- Utility functions associated with
+ *	V850E CPUs
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <asm/v850e_utils.h>
+
+/* Calculate counter clock-divider and count values to attain the
+   desired frequency RATE from the base frequency BASE_FREQ.  The
+   counter is expected to have a clock-divider, which can divide the
+   system cpu clock by a power of two value from MIN_DIVLOG2 to
+   MAX_DIV_LOG2, and a word-size of COUNTER_SIZE bits (the counter
+   counts up and resets whenever it's equal to the compare register,
+   generating an interrupt or whatever when it does so).  The returned
+   values are: *DIVLOG2 -- log2 of the desired clock divider and *COUNT
+   -- the counter compare value to use.  Returns true if it was possible
+   to find a reasonable value, otherwise false (and the other return
+   values will be set to be as good as possible).  */
+int calc_counter_params (unsigned long base_freq,
+			 unsigned long rate,
+			 unsigned min_divlog2, unsigned max_divlog2,
+			 unsigned counter_size,
+			 unsigned *divlog2, unsigned *count)
+{
+	unsigned _divlog2;
+	int ok = 0;
+
+	/* Find the lowest clock divider setting that can represent RATE.  */
+	for (_divlog2 = min_divlog2; _divlog2 <= max_divlog2; _divlog2++) {
+		/* Minimum interrupt rate possible using this divider.  */
+		unsigned min_int_rate
+			= (base_freq >> _divlog2) >> counter_size;
+
+		if (min_int_rate <= rate) {
+			/* This setting is the highest resolution
+			   setting that's slow enough enough to attain
+			   RATE interrupts per second, so use it.  */
+			ok = 1;
+			break;
+		}
+	}
+
+	if (_divlog2 > max_divlog2)
+		/* Can't find correct setting.  */
+		_divlog2 = max_divlog2;
+
+	if (divlog2)
+		*divlog2 = _divlog2;
+	if (count)
+		*count = ((base_freq >> _divlog2) + rate/2) / rate;
+
+	return ok;
+}
diff -urN linux-2.4.29/arch/v850/kernel/v850_ksyms.c linux-2.4.29-uc1/arch/v850/kernel/v850_ksyms.c
--- linux-2.4.29/arch/v850/kernel/v850_ksyms.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/kernel/v850_ksyms.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,78 @@
+#include <linux/module.h>
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
+
+#include <asm/pgalloc.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/semaphore.h>
+#include <asm/checksum.h>
+#include <asm/hardirq.h>
+#include <asm/softirq.h>
+#include <asm/current.h>
+
+
+extern void *trap_table;
+EXPORT_SYMBOL (trap_table);
+
+/* platform dependent support */
+extern void dump_thread (struct pt_regs *, struct user *);
+EXPORT_SYMBOL (dump_thread);
+EXPORT_SYMBOL (kernel_thread);
+EXPORT_SYMBOL (__bug);
+
+/* Networking helper routines. */
+EXPORT_SYMBOL (csum_partial_copy);
+EXPORT_SYMBOL (csum_partial_copy_from_user);
+EXPORT_SYMBOL (ip_compute_csum);
+EXPORT_SYMBOL (ip_fast_csum);
+
+/* string / mem functions */
+EXPORT_SYMBOL_NOVERS (strcpy);
+EXPORT_SYMBOL_NOVERS (strncpy);
+EXPORT_SYMBOL_NOVERS (strcat);
+EXPORT_SYMBOL_NOVERS (strncat);
+EXPORT_SYMBOL_NOVERS (strcmp);
+EXPORT_SYMBOL_NOVERS (strncmp);
+EXPORT_SYMBOL_NOVERS (strchr);
+EXPORT_SYMBOL_NOVERS (strlen);
+EXPORT_SYMBOL_NOVERS (strnlen);
+EXPORT_SYMBOL_NOVERS (strpbrk);
+EXPORT_SYMBOL_NOVERS (strtok);
+EXPORT_SYMBOL_NOVERS (strrchr);
+EXPORT_SYMBOL_NOVERS (strstr);
+EXPORT_SYMBOL_NOVERS (memset);
+EXPORT_SYMBOL_NOVERS (memcpy);
+EXPORT_SYMBOL_NOVERS (memmove);
+EXPORT_SYMBOL_NOVERS (memcmp);
+EXPORT_SYMBOL_NOVERS (memscan);
+
+/* semaphores */
+EXPORT_SYMBOL_NOVERS (__down);
+EXPORT_SYMBOL_NOVERS (__down_interruptible);
+EXPORT_SYMBOL_NOVERS (__down_trylock);
+EXPORT_SYMBOL_NOVERS (__up);
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler...  (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __ashldi3 (void);
+extern void __ashrdi3 (void);
+extern void __lshrdi3 (void);
+extern void __muldi3 (void);
+extern void __negdi2 (void);
+
+EXPORT_SYMBOL_NOVERS (__ashldi3);
+EXPORT_SYMBOL_NOVERS (__ashrdi3);
+EXPORT_SYMBOL_NOVERS (__lshrdi3);
+EXPORT_SYMBOL_NOVERS (__muldi3);
+EXPORT_SYMBOL_NOVERS (__negdi2);
diff -urN linux-2.4.29/arch/v850/lib/ashldi3.c linux-2.4.29-uc1/arch/v850/lib/ashldi3.c
--- linux-2.4.29/arch/v850/lib/ashldi3.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/lib/ashldi3.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,62 @@
+/* ashldi3.c extracted from gcc-2.95.2/libgcc2.c which is: */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define BITS_PER_UNIT 8
+
+typedef 	 int SItype	__attribute__ ((mode (SI)));
+typedef unsigned int USItype	__attribute__ ((mode (SI)));
+typedef		 int DItype	__attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
+DItype
+__ashldi3 (DItype u, word_type b)
+{
+  DIunion w;
+  word_type bm;
+  DIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ll = u;
+
+  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      w.s.low = 0;
+      w.s.high = (USItype)uu.s.low << -bm;
+    }
+  else
+    {
+      USItype carries = (USItype)uu.s.low >> bm;
+      w.s.low = (USItype)uu.s.low << b;
+      w.s.high = ((USItype)uu.s.high << b) | carries;
+    }
+
+  return w.ll;
+}
diff -urN linux-2.4.29/arch/v850/lib/ashrdi3.c linux-2.4.29-uc1/arch/v850/lib/ashrdi3.c
--- linux-2.4.29/arch/v850/lib/ashrdi3.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/lib/ashrdi3.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,63 @@
+/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define BITS_PER_UNIT 8
+
+typedef 	 int SItype	__attribute__ ((mode (SI)));
+typedef unsigned int USItype	__attribute__ ((mode (SI)));
+typedef		 int DItype	__attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
+DItype
+__ashrdi3 (DItype u, word_type b)
+{
+  DIunion w;
+  word_type bm;
+  DIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ll = u;
+
+  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      /* w.s.high = 1..1 or 0..0 */
+      w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
+      w.s.low = uu.s.high >> -bm;
+    }
+  else
+    {
+      USItype carries = (USItype)uu.s.high << bm;
+      w.s.high = uu.s.high >> b;
+      w.s.low = ((USItype)uu.s.low >> b) | carries;
+    }
+
+  return w.ll;
+}
diff -urN linux-2.4.29/arch/v850/lib/checksum.c linux-2.4.29-uc1/arch/v850/lib/checksum.c
--- linux-2.4.29/arch/v850/lib/checksum.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/lib/checksum.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,151 @@
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		MIPS specific IP/TCP/UDP checksumming routines
+ *
+ * Authors:	Ralf Baechle, <ralf@waldorf-gmbh.de>
+ *		Lots of code moved from tcp.c and ip.c; see those files
+ *		for more names.
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ *
+ * $Id: checksum.c,v 1.3 1997/12/01 17:57:34 ralf Exp $
+ */
+#include <net/checksum.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <asm/string.h>
+#include <asm/uaccess.h>
+
+static inline unsigned short from32to16 (unsigned long sum)
+{
+	unsigned int result;
+	/*
+			        %0		%1
+	      hsw %1, %0	H     L		L     H
+	      add %1, %0	H     L		H+L+C H+L
+	*/
+	asm ("hsw %1, %0; add %1, %0" : "=&r" (result) : "r" (sum));
+	return result >> 16;
+}
+
+static inline unsigned int do_csum(const unsigned char * buff, int len)
+{
+	int odd, count;
+	unsigned int result = 0;
+
+	if (len <= 0)
+		goto out;
+	odd = 1 & (unsigned long) buff;
+	if (odd) {
+		result = be16_to_cpu(*buff);
+		len--;
+		buff++;
+	}
+	count = len >> 1;		/* nr of 16-bit words.. */
+	if (count) {
+		if (2 & (unsigned long) buff) {
+			result += *(unsigned short *) buff;
+			count--;
+			len -= 2;
+			buff += 2;
+		}
+		count >>= 1;		/* nr of 32-bit words.. */
+		if (count) {
+			unsigned int carry = 0;
+			do {
+				unsigned int w = *(unsigned int *) buff;
+				count--;
+				buff += 4;
+				result += carry;
+				result += w;
+				carry = (w > result);
+			} while (count);
+			result += carry;
+			result = (result & 0xffff) + (result >> 16);
+		}
+		if (len & 2) {
+			result += *(unsigned short *) buff;
+			buff += 2;
+		}
+	}
+	if (len & 1)
+		result += le16_to_cpu(*buff);
+	result = from32to16(result);
+	if (odd)
+		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+	return result;
+}
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ */
+unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
+{
+	return ~do_csum(iph,ihl*4);
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+unsigned short ip_compute_csum(const unsigned char * buff, int len)
+{
+	return ~do_csum(buff,len);
+}
+
+/*
+ * computes a partial checksum, e.g. for TCP/UDP fragments
+ */
+unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum)
+{
+	unsigned int result = do_csum(buff, len);
+
+	/* add in old sum, and carry.. */
+	result += sum;
+	if(sum > result)
+		result += 1;
+	return result;
+}
+
+/*
+ * copy while checksumming, otherwise like csum_partial
+ */
+unsigned int csum_partial_copy(const char *src, char *dst, 
+                               int len, unsigned int sum)
+{
+	/*
+	 * It's 2:30 am and I don't feel like doing it real ...
+	 * This is lots slower than the real thing (tm)
+	 */
+	sum = csum_partial(src, len, sum);
+	memcpy(dst, src, len);
+
+	return sum;
+}
+
+/*
+ * Copy from userspace and compute checksum.  If we catch an exception
+ * then zero the rest of the buffer.
+ */
+unsigned int csum_partial_copy_from_user (const char *src, char *dst,
+                                          int len, unsigned int sum,
+                                          int *err_ptr)
+{
+	int missing;
+
+	missing = copy_from_user(dst, src, len);
+	if (missing) {
+		memset(dst + len - missing, 0, missing);
+		*err_ptr = -EFAULT;
+	}
+		
+	return csum_partial(dst, len, sum);
+}
diff -urN linux-2.4.29/arch/v850/lib/lshrdi3.c linux-2.4.29-uc1/arch/v850/lib/lshrdi3.c
--- linux-2.4.29/arch/v850/lib/lshrdi3.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/lib/lshrdi3.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,62 @@
+/* lshrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define BITS_PER_UNIT 8
+
+typedef 	 int SItype	__attribute__ ((mode (SI)));
+typedef unsigned int USItype	__attribute__ ((mode (SI)));
+typedef		 int DItype	__attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
+DItype
+__lshrdi3 (DItype u, word_type b)
+{
+  DIunion w;
+  word_type bm;
+  DIunion uu;
+
+  if (b == 0)
+    return u;
+
+  uu.ll = u;
+
+  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+  if (bm <= 0)
+    {
+      w.s.high = 0;
+      w.s.low = (USItype)uu.s.high >> -bm;
+    }
+  else
+    {
+      USItype carries = (USItype)uu.s.high << bm;
+      w.s.high = (USItype)uu.s.high >> b;
+      w.s.low = ((USItype)uu.s.low >> b) | carries;
+    }
+
+  return w.ll;
+}
diff -urN linux-2.4.29/arch/v850/lib/Makefile linux-2.4.29-uc1/arch/v850/lib/Makefile
--- linux-2.4.29/arch/v850/lib/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/lib/Makefile	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,9 @@
+#
+# arch/v850/lib/Makefile
+#
+
+L_TARGET = lib.a
+obj-y  = ashrdi3.o ashldi3.o lshrdi3.o muldi3.o negdi2.o \
+	 checksum.o memcpy.o memset.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/v850/lib/memcpy.c linux-2.4.29-uc1/arch/v850/lib/memcpy.c
--- linux-2.4.29/arch/v850/lib/memcpy.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/lib/memcpy.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,97 @@
+/*
+ * arch/v850/lib/memcpy.c -- Memory copying
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/types.h>
+#include <asm/string.h>
+
+#define CHUNK_SIZE		32 /* bytes */
+#define CHUNK_ALIGNED(addr)	(((unsigned long)addr & 0x3) == 0)
+
+/* Note that this macro uses 8 call-clobbered registers (not including
+   R1), which are few enough so that the following functions don't need
+   to spill anything to memory.  It also uses R1, which is nominally
+   reserved for the assembler, but here it should be OK.  */
+#define COPY_CHUNK(src, dst)			\
+   asm ("mov %0, ep;"				\
+	"sld.w 0[ep], r1; sld.w 4[ep], r12;"	\
+	"sld.w 8[ep], r13; sld.w 12[ep], r14;"	\
+	"sld.w 16[ep], r15; sld.w 20[ep], r17;"	\
+	"sld.w 24[ep], r18; sld.w 28[ep], r19;"	\
+	"mov %1, ep;"				\
+	"sst.w r1, 0[ep]; sst.w r12, 4[ep];"	\
+	"sst.w r13, 8[ep]; sst.w r14, 12[ep];"	\
+	"sst.w r15, 16[ep]; sst.w r17, 20[ep];"	\
+	"sst.w r18, 24[ep]; sst.w r19, 28[ep]"	\
+	:: "r" (src), "r" (dst)			\
+	: "r1", "r12", "r13", "r14", "r15",	\
+	  "r17", "r18", "r19", "ep", "memory");
+
+void *memcpy (void *dst, const void *src, __kernel_size_t size)
+{
+	char *_dst = dst;
+	const char *_src = src;
+
+	if (size >= CHUNK_SIZE && CHUNK_ALIGNED(_src) && CHUNK_ALIGNED(_dst)) {
+		/* Copy large blocks efficiently.  */
+		unsigned count;
+		for (count = size / CHUNK_SIZE; count; count--) {
+			COPY_CHUNK (_src, _dst);
+			_src += CHUNK_SIZE;
+			_dst += CHUNK_SIZE;
+		}
+		size %= CHUNK_SIZE;
+	}
+
+	if (size > 0)
+		do
+			*_dst++ = *_src++;
+		while (--size);
+
+	return dst;
+}
+
+void bcopy (const char *src, char *dst, int size)
+{
+	memcpy (dst, src, size);
+}
+
+void *memmove (void *dst, const void *src, __kernel_size_t size)
+{
+	if ((unsigned long)dst < (unsigned long)src
+	    || (unsigned long)src + size < (unsigned long)dst)
+		return memcpy (dst, src, size);
+	else {
+		char *_dst = dst + size;
+		const char *_src = src + size;
+
+		if (size >= CHUNK_SIZE
+		    && CHUNK_ALIGNED (_src) && CHUNK_ALIGNED (_dst))
+		{
+			/* Copy large blocks efficiently.  */
+			unsigned count;
+			for (count = size / CHUNK_SIZE; count; count--) {
+				_src -= CHUNK_SIZE;
+				_dst -= CHUNK_SIZE;
+				COPY_CHUNK (_src, _dst);
+			}
+			size %= CHUNK_SIZE;
+		}
+
+		if (size > 0)
+			do
+				*--_dst = *--_src;
+			while (--size);
+
+		return _dst;
+	}
+}
diff -urN linux-2.4.29/arch/v850/lib/memset.c linux-2.4.29-uc1/arch/v850/lib/memset.c
--- linux-2.4.29/arch/v850/lib/memset.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/lib/memset.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,61 @@
+/*
+ * arch/v850/lib/memset.c -- Memory initialization
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <linux/types.h>
+
+void *memset (void *dst, int val, __kernel_size_t count)
+{
+	if (count) {
+		register unsigned loop;
+		register void *ptr asm ("ep") = dst;
+
+		/* replicate VAL into a long.  */
+		val &= 0xff;
+		val |= val << 8;
+		val |= val << 16;
+
+		/* copy initial unaligned bytes.  */
+		if ((long)ptr & 1) {
+			*((char *)ptr)++ = val;
+			count--;
+		}
+		if (count > 2 && ((long)ptr & 2)) {
+			*((short *)ptr)++ = val;
+			count -= 2;
+		}
+
+		/* 32-byte copying loop.  */
+		for (loop = count / 32; loop; loop--) {
+			asm ("sst.w %0, 0[ep]; sst.w %0, 4[ep];"
+			     "sst.w %0, 8[ep]; sst.w %0, 12[ep];"
+			     "sst.w %0, 16[ep]; sst.w %0, 20[ep];"
+			     "sst.w %0, 24[ep]; sst.w %0, 28[ep]"
+			     :: "r" (val) : "memory");
+			ptr += 32;
+		}
+		count %= 32;
+
+		/* long copying loop.  */
+		for (loop = count / 4; loop; loop--)
+			*((long *)ptr)++ = val;
+		count %= 4;
+
+		/* finish up with any trailing bytes.  */
+		if (count & 2)
+			*((short *)ptr)++ = val;
+		if (count & 1)
+			*(char *)ptr = val;
+	}
+
+	return dst;
+}
diff -urN linux-2.4.29/arch/v850/lib/muldi3.c linux-2.4.29-uc1/arch/v850/lib/muldi3.c
--- linux-2.4.29/arch/v850/lib/muldi3.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/lib/muldi3.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,61 @@
+/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and 
+			   gcc-2.7.2.3/longlong.h which is: */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 2001 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define umul_ppmm(w1, w0, u, v) \
+  __asm__ ("mulu %3, %0, %1"						\
+           : "=r" ((USItype)(w0)),					\
+             "=r" ((USItype)(w1))					\
+           : "%0" ((USItype)(u)),					\
+             "r" ((USItype)(v)))
+
+#define __umulsidi3(u, v) \
+  ({DIunion __w;							\
+    umul_ppmm (__w.s.high, __w.s.low, u, v);				\
+    __w.ll; })
+
+typedef 	 int SItype	__attribute__ ((mode (SI)));
+typedef unsigned int USItype	__attribute__ ((mode (SI)));
+typedef		 int DItype	__attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
+DItype
+__muldi3 (DItype u, DItype v)
+{
+  DIunion w;
+  DIunion uu, vv;
+
+  uu.ll = u,
+  vv.ll = v;
+
+  w.ll = __umulsidi3 (uu.s.low, vv.s.low);
+  w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
+	       + (USItype) uu.s.high * (USItype) vv.s.low);
+
+  return w.ll;
+}
diff -urN linux-2.4.29/arch/v850/lib/negdi2.c linux-2.4.29-uc1/arch/v850/lib/negdi2.c
--- linux-2.4.29/arch/v850/lib/negdi2.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/lib/negdi2.c	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ * arch/v850/lib/negdi2.c -- 64-bit negation
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+typedef		 int DItype	__attribute__ ((mode (DI)));
+
+DItype __negdi2 (DItype x)
+{
+	__asm__ __volatile__
+		("not	r6, r10;"
+		 "add	1, r10;"
+		 "setf	c, r6;"
+		 "not	r7, r11;"
+		 "add	r6, r11"
+		 ::: "r6", "r7", "r10", "r11");
+}
diff -urN linux-2.4.29/arch/v850/Makefile linux-2.4.29-uc1/arch/v850/Makefile
--- linux-2.4.29/arch/v850/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/Makefile	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,82 @@
+#
+# arch/v850/Makefile
+#
+#  Copyright (C) 2001,02,03  NEC Corporation
+#  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+
+UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\"
+
+
+CFLAGS += -mv850e
+# r16 is a fixed pointer to the current task
+CFLAGS += -ffixed-r16 -mno-prolog-function
+CFLAGS += -fno-builtin
+CFLAGS += -DNO_MM
+CFLAGS += $(UTS_SYSNAME) -D__linux__
+
+
+ARCH_DIR = arch/$(ARCH)
+
+
+HEAD := $(ARCH_DIR)/kernel/head.o
+
+SUBDIRS += $(ARCH_DIR)/kernel $(ARCH_DIR)/lib
+CORE_FILES := $(ARCH_DIR)/kernel/kernel.o $(CORE_FILES)
+LIBS += $(ARCH_DIR)/lib/lib.a
+
+
+# Deal with the initial contents of the blkmem device
+ifdef ROOT_FS_IMAGE
+ifndef CONFIG_SIM
+# Embed it in the kernel
+
+ROOT_FS_IMAGE_OBJ = root_fs_image.o
+
+CORE_FILES += $(ROOT_FS_IMAGE_OBJ)
+
+$(LINUX) : $(ROOT_FS_IMAGE_OBJ)
+
+# Note that we use the build-system's objcopy, as the v850 tools are fairly
+# old, and don't have the --rename-section option.
+$(ROOT_FS_IMAGE_OBJ): $(ROOT_FS_IMAGE)
+	objcopy -I binary -O elf32-little -B i386 --rename-section .data=.root,alloc,load,readonly,data,contents $< $@
+
+endif # !CONFIG_SIM
+endif # ROOT_FS_IMAGE
+
+
+# kernel linker script
+LINKFLAGS = -T linux.ld
+$(LINUX) : linux.ld
+linux.ld: $(ARCH_DIR)/kernel/linux.ld.in
+	$(CPP) -P -x assembler-with-cpp $(AFLAGS) $< > $@
+
+
+# If you want the kernel build to build modules outside of the tree
+# then define this and pass it to the main linux makefile
+ifdef EXTRA_MODULE_DIRS
+SUBDIRS += $(EXTRA_MODULE_DIRS)
+endif
+
+bootstrap:
+	@$(MAKEBOOT) bootstrap
+
+archmrproper:
+
+archdep:
+
+archclean:
+	rm -f $(LINUX) linux.ld
+	rm -f $(ARCH_DIR)/kernel/v850_defs.h $(ARCH_DIR)/kernel/v850_defs.d
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/arch/v850/README linux-2.4.29-uc1/arch/v850/README
--- linux-2.4.29/arch/v850/README	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/README	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,33 @@
+This port to the NEC V850E processor supports the following platforms:
+
+   + The gdb v850e simulator (CONFIG_V850E_SIM); see the subdirectory `sim'
+     for some more support files for this.
+
+   + The Midas labs RTE-V850E/MA1-CB and RTE-V850E/NB85E-CB evaluation boards
+     (CONFIG_RTE_CB_MA1 and CONFIG_RTE_CB_NB85E).  This support has only been
+     tested when running with the Multi-debugger monitor ROM (for the Green
+     Hills Multi debugger).  The optional NEC Solution Gear RTE-MOTHER-A
+     motherboard is also supported, which allows PCI boards to be used
+     (CONFIG_RTE_MB_A_PCI).
+
+   + The Midas labs RTE-V850E/ME2-CB evaluation board (CONFIG_RTE_CB_ME2).
+     This has only been tested using a kernel downloaded via an ICE connection
+     using the Multi debugger.  Support for the RTE-MOTHER-A is present, but
+     hasn't been tested (unlike the other Midas labs cpu boards, the
+     RTE-V850E/ME2-CB includes an ethernet adaptor).
+
+   + The NEC AS85EP1 V850E evaluation chip/board (CONFIG_V850E_AS85EP1).
+
+   + The NEC `Anna' (board/chip) implementation of the V850E2 processor
+     (CONFIG_V850E2_ANNA).
+
+   + The sim85e2c and sim85e2s simulators, which are verilog simulations of
+     the V850E2 NA85E2C/NA85E2S cpu cores (CONFIG_V850E2_SIM85E2C and
+     CONFIG_V850E2_SIM85E2S).
+
+   + A FPGA implementation of the V850E2 NA85E2C cpu core
+     (CONFIG_V850E2_FPGA85E2C).
+
+Porting to anything with a V850E/MA1 or MA2 processor should be simple.
+See the file <asm-v850/machdep.h> and the files it includes for an example of
+how to add platform/chip-specific support.
diff -urN linux-2.4.29/arch/v850/sim/gdb-scripts/example.gdbinit linux-2.4.29-uc1/arch/v850/sim/gdb-scripts/example.gdbinit
--- linux-2.4.29/arch/v850/sim/gdb-scripts/example.gdbinit	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/gdb-scripts/example.gdbinit	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,38 @@
+# Copy this file to `.gdbinit' in the directory where you will run linux
+# (for instance, the top-level of the kernel build tree).  Invoking gdb
+# will then start the simulator and load linux into it.  You should
+# start gdb using a command like `v850e-elf-gdb vmlinux'.
+
+set $linux_banner = *(char **)&linux_banner
+set $vers_2_4 = ($linux_banner[16] == '4')
+
+set architecture v850e
+set height 0
+set pagination off
+
+disp/i $pc
+
+target sim
+sim architecture v850e
+
+sim memory delete all
+sim memory region 0,0xe0
+sim memory region 0x8F000000,0x02000000
+sim memory region 0xFFFF0000,0x10000
+
+# Protect the kernel's text segment against writing.  These addresses
+# are somewhat conservative, but might need to be changed if the kernel
+# text-segment shrinks appreciably.
+#sim read-protect-low-memory 0x4a000
+#sim write-protect-low-memory 0x4a000
+
+# 24Hz @1/10 speed = 2.4Hz
+sim watch-clock-intov1 +420
+
+sim stdio off
+
+if ($vers_2_4)
+  load linux
+else
+  load vmlinux
+end
diff -urN linux-2.4.29/arch/v850/sim/gdb-scripts/README linux-2.4.29-uc1/arch/v850/sim/gdb-scripts/README
--- linux-2.4.29/arch/v850/sim/gdb-scripts/README	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/gdb-scripts/README	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,17 @@
+This directory contains some shell and gdb scripts useful for debugging.
+
+
+   example.gdbinit	An example `.gdbinit' file that sets things up
+			to run linux in the gdb v850 simulator.  It
+			assumes that all the patch files in ../patches
+			have been applied.
+
+
+The following are gdb scripts that when loaded into gdb (using the `source'
+command) will install breakpoints which print out information at interesting
+times:
+
+   trace-loadproc.gdb	Print a message for each process exec.
+   trace-switch.gdb	Print a message for each context switch.
+   trace-irq.gdb	Print messages for interrupts/interrupt returns.
+   trace-traps.gdb	Print messages for traps (syscalls) & trap returns.
diff -urN linux-2.4.29/arch/v850/sim/gdb-scripts/trace-irq.gdb linux-2.4.29-uc1/arch/v850/sim/gdb-scripts/trace-irq.gdb
--- linux-2.4.29/arch/v850/sim/gdb-scripts/trace-irq.gdb	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/gdb-scripts/trace-irq.gdb	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,13 @@
+break *irq
+command
+  silent
+  printf "[irq %d]\n", ($ecr - 0x80) / 16
+  cont
+end
+
+break *ret_from_irq
+command
+  silent
+  printf "[ret_from_irq]\n"
+  cont
+end
diff -urN linux-2.4.29/arch/v850/sim/gdb-scripts/trace-loadproc.gdb linux-2.4.29-uc1/arch/v850/sim/gdb-scripts/trace-loadproc.gdb
--- linux-2.4.29/arch/v850/sim/gdb-scripts/trace-loadproc.gdb	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/gdb-scripts/trace-loadproc.gdb	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,8 @@
+# This breakpoint, being at an absolute address, breaks constantly,
+# however I've not found a better place to put it.
+break binfmt_flat.c:879
+command
+  silent
+  printf "[loaded process `%s'  text 0x%x, data 0x%x, bss 0x%x]\n", bprm->filename, current->mm->start_code, current->mm->start_data, current->mm->end_data
+  cont
+end
diff -urN linux-2.4.29/arch/v850/sim/gdb-scripts/trace-switch.gdb linux-2.4.29-uc1/arch/v850/sim/gdb-scripts/trace-switch.gdb
--- linux-2.4.29/arch/v850/sim/gdb-scripts/trace-switch.gdb	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/gdb-scripts/trace-switch.gdb	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,17 @@
+set $linux_banner = *(char **)_linux_banner
+set $vers_2_5 = ($linux_banner[16] == '5')
+
+break *_switch_thread
+command
+  silent
+  set $old_task = (struct task_struct *)$r16
+  set $new_kernel_sp = *(unsigned long *)$r7 - 1
+  if ($vers_2_5)
+    set $new_thread_info = (struct thread_info *)(($new_kernel_sp - 1) & -8192)
+    set $new_task = $new_thread_info->task
+  else
+    set $new_task = (struct task_struct *)(($new_kernel_sp - 1) & -8192)
+  end
+  printf "[pid %d: switch_thread pid %d]\n", $old_task->pid, $new_task->pid
+  cont
+end
diff -urN linux-2.4.29/arch/v850/sim/gdb-scripts/trace-traps.gdb linux-2.4.29-uc1/arch/v850/sim/gdb-scripts/trace-traps.gdb
--- linux-2.4.29/arch/v850/sim/gdb-scripts/trace-traps.gdb	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/gdb-scripts/trace-traps.gdb	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,39 @@
+set $linux_banner = *(char **)_linux_banner
+set $vers_2_5 = ($linux_banner[16] == '5')
+
+set $r0_ram = (unsigned long *)((*((long *)&trap) >> 16) - 4)
+
+break *trap
+command
+  silent
+  set $km = ($r0_ram[1] & 0x1)
+  if ($km)
+    # kernel mode
+    set $task = (struct task_struct *)$r16
+    printf "[pid %d <km>: trap %d, %d]\n", $task->pid, ($ecr - 0x40), $r12
+  else
+    # user mode
+    set $kernel_sp = $r0_ram[0]
+    if ($vers_2_5)
+      set $thread_info = (struct thread_info *)(($kernel_sp - 1) & -8192)
+      set $task = $thread_info->task
+    else
+      set $task = (struct task_struct *)(($kernel_sp - 1) & -8192)
+    end
+    printf "[pid %d: trap %d, %d]\n", $task->pid, ($ecr - 0x40), $r12
+  end
+  cont
+end
+
+break *ret_from_trap
+command
+  silent
+  set $task = (struct task_struct *)$r16
+  set $regs = ((struct pt_regs *)($sp + 24))
+  if ($regs->kernel_mode)
+    printf "[pid %d <km>: ret_from_trap %d, 0x%x]\n", $task->pid, $regs->gpr[0], $r10
+  else
+    printf "[pid %d: ret_from_trap %d, 0x%x]\n", $task->pid, $regs->gpr[0], $r10
+  end
+  cont
+end
diff -urN linux-2.4.29/arch/v850/sim/patches/gdb-sim-inftty.patch linux-2.4.29-uc1/arch/v850/sim/patches/gdb-sim-inftty.patch
--- linux-2.4.29/arch/v850/sim/patches/gdb-sim-inftty.patch	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/patches/gdb-sim-inftty.patch	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,175 @@
+2001-09-05  Miles Bader  <miles@gnu.org>
+
+	* remote-sim.c (gdbsim_create_inferior): Call target_terminal_init.
+	(stdin_serial, our_ttystate, inferior_ttystate, terminal_is_ours):
+	New variables.
+	(gdbsim_terminal_init, gdbsim_terminal_inferior) 
+	(gdbsim_terminal_ours_for_output, gdbsim_terminal_ours) 
+	(gdbsim_terminal_ours_1): New functions.
+	(init_gdbsim_ops): Add terminal control ops.
+
+diff -up gdb/remote-sim.c.\~1\~ gdb/remote-sim.c
+--- gdb/remote-sim.c.~1~	Wed Jan 17 20:52:03 2001
++++ gdb/remote-sim.c	Wed Sep  5 11:48:50 2001
+@@ -469,6 +469,8 @@ gdbsim_create_inferior (exec_file, args,
+ 		     (exec_file ? exec_file: "(NULL)"),
+ 		     args);
+ 
++  target_terminal_init ();
++
+   gdbsim_kill ();	 
+   remove_breakpoints ();
+   init_wait_for_inferior ();
+@@ -922,6 +924,135 @@ simulator_command (args, from_tty)
+      something funny. */
+   registers_changed (); 
+ }
++
++/* Record terminal status separately for debugger and inferior.  */
++static serial_t stdin_serial;
++
++/* Our own tty state, which we restore every time we need to deal with the
++   terminal.  We only set it once, when GDB first starts.  The settings of
++   flags which readline saves and restores and unimportant.  */
++static serial_ttystate our_ttystate;
++
++/* TTY state for the inferior.  We save it whenever the inferior stops, and
++   restore it when it resumes.  */
++static serial_ttystate inferior_ttystate;
++
++/* Nonzero if our terminal settings are in effect.  Zero if the
++   inferior's settings are in effect.  Ignored if stdin isn't a terminal.  */
++extern int terminal_is_ours;
++
++
++/* Initialize the terminal settings we record for the inferior,
++   before we actually run the inferior.  */
++void
++gdbsim_terminal_init ()
++{
++  if (! stdin_serial)
++    {
++      stdin_serial = SERIAL_FDOPEN (0);
++      if (stdin_serial)
++	our_ttystate = SERIAL_GET_TTY_STATE (stdin_serial);
++    }
++
++  if (stdin_serial)
++    {
++      if (inferior_ttystate)
++	free (inferior_ttystate);
++      inferior_ttystate = SERIAL_GET_TTY_STATE (stdin_serial);
++    }
++
++  terminal_is_ours = 1;
++}
++
++/* Put the inferior's terminal settings into effect.
++   This is preparation for starting or resuming the inferior.  */
++void
++gdbsim_terminal_inferior ()
++{
++  if (stdin_serial && terminal_is_ours)
++    /* Because we were careful to not change in or out of raw mode in
++       terminal_ours, we will not change in our out of raw mode with
++       this call, so we don't flush any input.  */
++    if (SERIAL_SET_TTY_STATE (stdin_serial, inferior_ttystate) == -1)
++      fprintf_unfiltered
++	(gdb_stderr,
++	 "[setting tty state failed in terminal_inferior: %s]\n",
++	 strerror (errno));
++  terminal_is_ours = 0;
++}
++
++static void gdbsim_terminal_ours_1 PARAMS ((int));
++
++/* Put some of our terminal settings into effect,
++   enough to get proper results from our output,
++   but do not change into or out of RAW mode
++   so that no input is discarded.
++
++   After doing this, either terminal_ours or terminal_inferior
++   should be called to get back to a normal state of affairs.  */
++void
++gdbsim_terminal_ours_for_output ()
++{
++  gdbsim_terminal_ours_1 (1);
++}
++
++/* Put our terminal settings into effect.
++   First record the inferior's terminal settings
++   so they can be restored properly later.  */
++void
++gdbsim_terminal_ours ()
++{
++  gdbsim_terminal_ours_1 (0);
++}
++
++/* output_only is not used, and should not be used unless we introduce
++   separate terminal_is_ours and terminal_is_ours_for_output
++   flags.  */
++static void
++gdbsim_terminal_ours_1 (output_only)
++     int output_only;
++{
++  if (stdin_serial && !terminal_is_ours)
++    {
++      terminal_is_ours = 1;
++
++      /* Here we used to set ICANON in our ttystate, but I believe this
++	 was an artifact from before when we used readline.  Readline sets
++	 the tty state when it needs to.
++	 FIXME-maybe: However, query() expects non-raw mode and doesn't
++	 use readline.  Maybe query should use readline (on the other hand,
++	 this only matters for HAVE_SGTTY, not termio or termios, I think).  */
++
++      /* Set tty state to our_ttystate.  We don't change in our out of raw
++	 mode, to avoid flushing input.  We need to do the same thing
++	 regardless of output_only, because we don't have separate
++	 terminal_is_ours and terminal_is_ours_for_output flags.  It's OK,
++	 though, since readline will deal with raw mode when/if it needs to.
++	 */
++
++      SERIAL_NOFLUSH_SET_TTY_STATE (stdin_serial, our_ttystate,
++				    inferior_ttystate);
++    }
++}
++
++/* ARGSUSED */
++void
++gdbsim_terminal_info (args, from_tty)
++     char *args;
++     int from_tty;
++{
++  if (stdin_serial)
++    {
++      printf_filtered ("Inferior's terminal status (currently saved by GDB):\n");
++      SERIAL_PRINT_TTY_STATE (stdin_serial, inferior_ttystate);
++    }
++  else
++    {
++      printf_filtered ("This GDB does not control a terminal.\n");
++      return;
++    }
++}
++
+ 
+ /* Define the target subroutine names */
+ 
+@@ -950,11 +1081,11 @@ init_gdbsim_ops(void)
+   gdbsim_ops.to_files_info  =   gdbsim_files_info;	
+   gdbsim_ops.to_insert_breakpoint =   gdbsim_insert_breakpoint;
+   gdbsim_ops.to_remove_breakpoint =   gdbsim_remove_breakpoint;
+-  gdbsim_ops.to_terminal_init  =   NULL;		
+-  gdbsim_ops.to_terminal_inferior =   NULL;		
+-  gdbsim_ops.to_terminal_ours_for_output =   NULL;
+-  gdbsim_ops.to_terminal_ours  =   NULL;
+-  gdbsim_ops.to_terminal_info  =   NULL;
++  gdbsim_ops.to_terminal_init  =   gdbsim_terminal_init;
++  gdbsim_ops.to_terminal_inferior =   gdbsim_terminal_inferior;
++  gdbsim_ops.to_terminal_ours_for_output =  gdbsim_terminal_ours_for_output;
++  gdbsim_ops.to_terminal_ours  =   gdbsim_terminal_ours;
++  gdbsim_ops.to_terminal_info  =   gdbsim_terminal_info;
+   gdbsim_ops.to_kill  =   gdbsim_kill;	
+   gdbsim_ops.to_load  =   gdbsim_load;	
+   gdbsim_ops.to_lookup_symbol =   NULL;	
diff -urN linux-2.4.29/arch/v850/sim/patches/README linux-2.4.29-uc1/arch/v850/sim/patches/README
--- linux-2.4.29/arch/v850/sim/patches/README	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/patches/README	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,62 @@
+This directory contains patches to gdb and the gdb v850 simulator.
+Some are necessary to run uclinux, others are useful for debugging.
+
+
+ Bug fixes:
+
+   sim-bitop-bug.patch	  Fixes a bug in the simulator implementation of
+			  bit operators.
+
+   sim-trap-addr.patch	  Fixes a bug where the simulator uses the wrong
+			  address for vectoring to a software trap.
+
+
+ New features (necessary):
+
+   sim-interrupt-priority.patch
+			  Adds interrupt priorities to the simulator's
+			  implementation of `hardware' interrupts.
+
+   sim-halt.patch	  Makes the `halt' instruction work like a real
+			  hardware halt instruction.  The implementation
+			  is non-optimal -- it simply busy-waits.
+
+
+ New features (optional):
+
+   gdb-sim-inftty.patch   A patches to make gdb manage tty modes in the
+			  simulator the same way it does with a real
+			  process inferior.  This allows the simulator
+			  to switch to raw mode without interfering with
+			  debugging.
+
+   sim-makeraw.patch      Adds a simulator `syscall' named `make_raw', which
+			  allows a program running on the simulator to
+			  switch the real terminal into raw mode.
+
+   sim-raw-stdio.patch	  Adds the simulator command `stdio on|off',
+			  which allows switching on or off special
+			  treatment of stdio I/O.
+
+   sim-poll.patch	  Adds `poll' as a simulator `syscall', allowing
+			  polling of real file descriptors by the
+			  simulated program.
+
+
+Debugging aids:
+
+These patches must be applied in order, since later patches depend on
+features added by earlier ones.
+
+   sim-record-branches.patch	Adds the simulator command `recent-branches'
+				which will dump information about the last
+				32 branches taken by the simulated program.
+
+   sim-lomem-protect.patch	Adds the simulator commands
+				`read-protect-low-memory BOUNDARY',
+				`write-protect-low-memory BOUNDARY', and
+				`protected-low-memory-info'.
+
+   sim-himem-trace.patch	Adds the simulator command
+				`trace-io-writes on|off' (which traces
+				writes to `I/O space' (above 0xFFFFF000).
diff -urN linux-2.4.29/arch/v850/sim/patches/sim-bitop-bug.patch linux-2.4.29-uc1/arch/v850/sim/patches/sim-bitop-bug.patch
--- linux-2.4.29/arch/v850/sim/patches/sim-bitop-bug.patch	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/patches/sim-bitop-bug.patch	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,21 @@
+diff -up /proj/soft2/uclinux/src/v850ice-000414-nmit-RELEASE-20010327/sim/v850/simops.c.\~1\~ /proj/soft2/uclinux/src/v850ice-000414-nmit-RELEASE-20010327/sim/v850/simops.c
+--- /proj/soft2/uclinux/src/v850ice-000414-nmit-RELEASE-20010327/sim/v850/simops.c.~1~	Mon Mar 26 13:20:00 2001
++++ /proj/soft2/uclinux/src/v850ice-000414-nmit-RELEASE-20010327/sim/v850/simops.c	Fri Aug 24 15:38:19 2001
+@@ -1892,7 +1892,7 @@ OP_E607E0 (void)
+   temp = load_mem (State.regs[ OP[0] ], 1);
+   
+   PSW &= ~PSW_Z;
+-  if ((temp & (1 << State.regs[ OP[1] & 0x7 ])) == 0)
++  if ((temp & (1 << (State.regs[ OP[1] ] & 0x7))) == 0)
+     PSW |= PSW_Z;
+   
+   trace_output (OP_BIT);
+@@ -1919,7 +1919,7 @@ OP_22207E0 (void)
+   						\
+   trace_input (name, OP_BIT_CHANGE, 0);		\
+   						\
+-  bit  = 1 << State.regs[ OP[1] & 0x7 ];	\
++  bit  = 1 << (State.regs[ OP[1] ] & 0x7);	\
+   temp = load_mem (State.regs[ OP[0] ], 1);	\
+ 						\
+   PSW &= ~PSW_Z;				\
diff -urN linux-2.4.29/arch/v850/sim/patches/sim-halt.patch linux-2.4.29-uc1/arch/v850/sim/patches/sim-halt.patch
--- linux-2.4.29/arch/v850/sim/patches/sim-halt.patch	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/patches/sim-halt.patch	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,22 @@
+2001-08-27  Miles Bader  <miles@gnu.org>
+
+	* simops.c (OP_12007E0): Don't halt the simulator, just let the
+	halt insn loop (the loop will be exited by any interrupt).
+
+diff -up sim/v850/simops.c.\~2\~ sim/v850/simops.c
+--- sim/v850/simops.c.~2~	Fri Aug 24 15:38:19 2001
++++ sim/v850/simops.c	Mon Aug 27 15:34:48 2001
+@@ -1575,10 +1575,10 @@ int
+ OP_12007E0 ()
+ {
+   trace_input ("halt", OP_NONE, 0);
+-  /* FIXME this should put processor into a mode where NMI still handled */
+   trace_output (OP_NONE);
+-  sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC,
+-		   sim_stopped, SIM_SIGTRAP);
++  /* We use a PC adjustment of 0, so the halt insn keeps looping, but
++     interrupts handle it specially, and will cause the halt insn to
++     complete.  */
+   return 0;
+ }
+ 
diff -urN linux-2.4.29/arch/v850/sim/patches/sim-himem-trace.patch linux-2.4.29-uc1/arch/v850/sim/patches/sim-himem-trace.patch
--- linux-2.4.29/arch/v850/sim/patches/sim-himem-trace.patch	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/patches/sim-himem-trace.patch	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,113 @@
+diff -up sim/v850/sim-main.h.\~5\~ sim/v850/sim-main.h
+--- sim/v850/sim-main.h.~5~	Fri Sep  7 13:56:29 2001
++++ sim/v850/sim-main.h	Tue Sep 18 16:06:02 2001
+@@ -208,6 +208,14 @@ extern address_word sim_lomem_write_prot
+ 			    address_word addr, unsigned len,
+ 			    sim_cia cia, int is_write);
+ 
++/* Boundary above which writes are traced.  */
++extern address_word sim_himem_trace_boundary;
++/* Called to trace loads/stores to memory above sim_himem_trace_boundary.  */
++extern void sim_trace_himem_fw (SIM_DESC sd, sim_cpu *cpu,
++				address_word addr, unsigned len,
++				unsigned long val,
++				sim_cia cia, int is_write);
++
+ #define load_mem(ADDR,LEN)						      \
+   ({									      \
+     address_word _addr = (ADDR);					      \
+@@ -229,6 +237,8 @@ extern void sim_lomem_falt (SIM_DESC sd,
+     sim_cpu *cpu = STATE_CPU (sd, 0);					      \
+     if (_addr < sim_lomem_write_protect_boundary)			      \
+       sim_lomem_fault (sd, cpu, _addr, LEN, PC, 1);			      \
++    else if (_addr > sim_himem_trace_boundary)				      \
++      sim_trace_himem_rw (sd, cpu, _addr, LEN, (unsigned long)_data, PC, 1);  \
+     else								      \
+       sim_core_write_unaligned_##LEN (cpu, PC, write_map, _addr, _data);      \
+   })
+diff -up sim/v850/interp.c.\~5\~ sim/v850/interp.c
+--- sim/v850/interp.c.~5~	Fri Sep  7 14:33:22 2001
++++ sim/v850/interp.c	Tue Sep 18 16:09:22 2001
+@@ -32,6 +32,13 @@ static const char * get_insn_name (sim_c
+ SIM_DESC simulator;
+ 
+ 
++#define stringify(sym)		stringify_1(sym)
++#define stringify_1(sym)	#sym
++
++
++#define IO_MEM_BOUNDARY 0xFFFFF000
++
++
+ 
+ /* Options.  */
+ 
+@@ -39,7 +46,8 @@ enum {
+   OPTION_V850_RECENT_BRANCHES = OPTION_START,
+   OPTION_V850_READ_PROTECT_LOMEM,
+   OPTION_V850_WRITE_PROTECT_LOMEM,
+-  OPTION_V850_PROTECTED_LOMEM_INFO
++  OPTION_V850_PROTECTED_LOMEM_INFO,
++  OPTION_V850_TRACE_IO_WRITES
+ };
+ 
+ static DECLARE_OPTION_HANDLER (v850_option_handler);
+@@ -61,6 +69,11 @@ static const OPTION v850_options[] =
+      OPTION_V850_PROTECTED_LOMEM_INFO },
+     '\0', NULL, "Show which low-memory addresses are protected from reading/writing",
+     v850_option_handler },
++  { {"trace-io-writes", required_argument, NULL,
++     OPTION_V850_TRACE_IO_WRITES },
++    '\0', "on|off",
++    "Trace writes to I/O memory (above " stringify(IO_MEM_BOUNDARY) ")",
++    v850_option_handler },
+   { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
+ };
+ 
+@@ -113,6 +126,20 @@ v850_option_handler (SIM_DESC sd, sim_cp
+       }
+       return SIM_RC_OK;
+ 
++    case OPTION_V850_TRACE_IO_WRITES:
++      {
++	if (strcmp (arg, "on") == 0 || strcmp (arg, "yes") == 0)
++	  sim_himem_trace_boundary = IO_MEM_BOUNDARY;
++	else if (strcmp (arg, "off") == 0 || strcmp (arg, "no") == 0)
++	  sim_himem_trace_boundary = 0xFFFFFFF;
++	else
++	  {
++	    sim_io_eprintf (sd, "Invalid argument `%s'\n", arg);
++	    return SIM_RC_FAIL;
++	  }	  
++      }
++      return SIM_RC_OK;
++
+     default:
+       sim_io_eprintf (sd, "Unknown v850 option %d\n", opt);
+       return SIM_RC_FAIL;
+@@ -527,4 +554,25 @@ address_word sim_lomem_read_protect_boun
+ 	  "core: %d byte %s protected low memory address 0x%lx at 0x%lx\n",
+ 		  len, is_write ? "write to" : "read from", addr, cia);
+   sim_engine_halt (sd, cpu, NULL, cia, sim_stopped, SIM_SIGSEGV);
++}
++
++/* Boundary above which writes are traced.  */
++address_word sim_himem_trace_boundary;
++
++/* Called to trace loads/stores to memory above sim_himem_trace_boundary.  */
++void
++sim_trace_himem_rw (SIM_DESC sd, sim_cpu *cpu,
++		    address_word addr, unsigned len, unsigned long val,
++		    sim_cia cia, int is_write)
++{
++  const char *v = is_write ? "write" : "read";
++  const char *p = is_write ? "to" : "from";
++  if (len == 1 && isascii (val) && isprint ((char)val))
++    sim_io_printf (sd,
++		   "core: %d byte %s at 0x%lx %s high memory address 0x%lx: 0x%02lx ('%c')\n",
++		   len, v, cia, p, addr, val, (char)val);
++  else
++    sim_io_printf (sd,
++		   "core: %d byte %s at 0x%lx %s high memory address 0x%lx: 0x%0*lx (%ld)\n",
++		   len, v, cia, p, addr, len * 2, val, val);
+ }
diff -urN linux-2.4.29/arch/v850/sim/patches/sim-interrupt-priority.patch linux-2.4.29-uc1/arch/v850/sim/patches/sim-interrupt-priority.patch
--- linux-2.4.29/arch/v850/sim/patches/sim-interrupt-priority.patch	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/patches/sim-interrupt-priority.patch	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,206 @@
+2001-08-24  Miles Bader  <miles@gnu.org>
+
+	* sim-main.h (struct _sim_cpu): New fields `current_interrupts'
+	and `pending_interrupts'.
+	* interp.c (do_interrupt): Don't deliver a maskable interrupt
+	unless it's `higher priority' than any interrupt currently being
+	serviced.  Update current interrupt active/pending state.
+	Automatically adjust the resume address if the PC is currently
+	pointing at a `halt' instruction, to resume at the next insn.
+	* v850.igen ("reti"): Remove the highest-priority interrupt's bit
+	from the current-interrupts mask.
+
+diff -up sim/v850/sim-main.h.\~1\~ sim/v850/sim-main.h
+--- sim/v850/sim-main.h.~1~	Mon Jan 22 13:50:38 2001
++++ sim/v850/sim-main.h	Mon Aug 27 15:14:29 2001
+@@ -50,6 +50,12 @@ struct _sim_cpu
+   sim_event *pending_nmi;
+   /* ... base type ... */
+   sim_cpu_base base;
++  /* One bit for each interrupt currently being serviced.  */
++  unsigned current_interrupts;
++  /* One bit for each interrupt that's been blocked because of a higher
++     priority interrupt.  This is used to avoid multiple pending
++     interrupts stacking up.  */
++  unsigned pending_interrupts;
+ };
+ 
+ #define CIA_GET(CPU) ((CPU)->reg.pc + 0)
+diff -up sim/v850/interp.c.\~1\~ sim/v850/interp.c
+--- sim/v850/interp.c.~1~	Thu Oct  5 19:59:56 2000
++++ sim/v850/interp.c	Mon Aug 27 16:15:01 2001
+@@ -66,8 +66,9 @@ do_interrupt (sd, data)
+      void *data;
+ {
+   char **interrupt_name = (char**)data;
+-  enum interrupt_type inttype;
+-  inttype = (interrupt_name - STATE_WATCHPOINTS (sd)->interrupt_names);
++  enum interrupt_type inttype
++    = (interrupt_name - STATE_WATCHPOINTS (sd)->interrupt_names);
++  unsigned pc_adjust;
+ 
+   /* For a hardware reset, drop everything and jump to the start
+      address */
+@@ -79,6 +80,14 @@ do_interrupt (sd, data)
+       sim_engine_restart (sd, NULL, NULL, NULL_CIA);
+     }
+ 
++  /* How to adjust the PC upon return from this interrupt.  This is zero
++     for everything but a `halt' instruction.  */
++  if (load_mem (PC, 2) == 0x07e0 && load_mem (PC + 2, 2) == 0x0120)
++    /* PC is pointing to a `halt' insn.  */
++    pc_adjust = 4;
++  else
++    pc_adjust = 0;
++
+   /* Deliver an NMI when allowed */
+   if (inttype == int_nmi)
+     {
+@@ -100,7 +109,7 @@ do_interrupt (sd, data)
+ 	  /* NMI can be delivered.  Do not deschedule pending_nmi as
+              that, if still in the event queue, is a second NMI that
+              needs to be delivered later. */
+-	  FEPC = PC;
++	  FEPC = PC + pc_adjust;
+ 	  FEPSW = PSW;
+ 	  /* Set the FECC part of the ECR. */
+ 	  ECR &= 0x0000ffff;
+@@ -116,16 +125,74 @@ do_interrupt (sd, data)
+   /* deliver maskable interrupt when allowed */
+   if (inttype > int_nmi && inttype < num_int_types)
+     {
+-      if ((PSW & PSW_NP) || (PSW & PSW_ID))
++      unsigned int_code, int_pc, int_num, int_mask;
++
++      switch (inttype)
++	{
++	case int_intov1:
++	  int_pc = 0x80;
++	  int_code = 0x80;
++	  int_num = 0;
++	  break;
++	case int_intp10:
++	  int_pc = 0x90;
++	  int_code = 0x90;
++	  int_num = 1;
++	  break;
++	case int_intp11:
++	  int_pc = 0xa0;
++	  int_code = 0xa0;
++	  int_num = 2;
++	  break;
++	case int_intp12:
++	  int_pc = 0xb0;
++	  int_code = 0xb0;
++	  int_num = 3;
++	  break;
++	case int_intp13:
++	  int_pc = 0xc0;
++	  int_code = 0xc0;
++	  int_num = 4;
++	  break;
++	case int_intcm4:
++	  int_pc = 0xd0;
++	  int_code = 0xd0;
++	  int_num = 5;
++	  break;
++	default:
++	  /* Should never be possible.  */
++	  sim_engine_abort (sd, NULL, NULL_CIA,
++			    "do_interrupt - internal error - bad switch");
++	  break;
++	}
++
++      int_mask = 1 << int_num;
++
++      /* A maskable interrupt can't be delivered if:
++  	   (1) A NMI is currently being serviced, or
++	   (2) The interrupt-disable bit is set, or
++	   (3) It's `lower-priority' than the interrupt currently being
++	       serviced.  Here, `lower-priority' really means `has a
++	       higher interrupt number'.  */
++      if ((PSW & PSW_NP) || (PSW & PSW_ID)
++	  || (STATE_CPU (sd, 0)->current_interrupts & (int_mask - 1)))
+ 	{
+-	  /* Can't deliver this interrupt, reschedule it for later */
+-	  sim_events_schedule (sd, 1, do_interrupt, data);
++	  /* Can't deliver this interrupt, reschedule it for later.  If
++	     the interrupt is already pending, though, don't bother,
++	     since there's already an event queued for it (and we only
++	     want to deliver one interrupt when it becomes possible to
++	     do so).  */
++	  if (! (STATE_CPU (sd, 0)->pending_interrupts & int_mask))
++	    {
++	      sim_events_schedule (sd, 1, do_interrupt, data);
++	      STATE_CPU (sd, 0)->pending_interrupts |= int_mask;
++	    }
+ 	  return;
+ 	}
+       else
+ 	{
+ 	  /* save context */
+-	  EIPC = PC;
++	  EIPC = PC + pc_adjust;
+ 	  EIPSW = PSW;
+ 	  /* Disable further interrupts.  */
+ 	  PSW |= PSW_ID;
+@@ -133,38 +200,13 @@ do_interrupt (sd, data)
+ 	  PSW &= ~PSW_EP;
+ 	  /* Clear the EICC part of the ECR, will set below. */
+ 	  ECR &= 0xffff0000;
+-	  switch (inttype)
+-	    {
+-	    case int_intov1:
+-	      PC = 0x80;
+-	      ECR |= 0x80;
+-	      break;
+-	    case int_intp10:
+-	      PC = 0x90;
+-	      ECR |= 0x90;
+-	      break;
+-	    case int_intp11:
+-	      PC = 0xa0;
+-	      ECR |= 0xa0;
+-	      break;
+-	    case int_intp12:
+-	      PC = 0xb0;
+-	      ECR |= 0xb0;
+-	      break;
+-	    case int_intp13:
+-	      PC = 0xc0;
+-	      ECR |= 0xc0;
+-	      break;
+-	    case int_intcm4:
+-	      PC = 0xd0;
+-	      ECR |= 0xd0;
+-	      break;
+-	    default:
+-	      /* Should never be possible.  */
+-	      sim_engine_abort (sd, NULL, NULL_CIA,
+-				"do_interrupt - internal error - bad switch");
+-	      break;
+-	    }
++
++	  /* Set the new program counter and ECR.  */
++	  PC = int_pc;
++	  ECR |= int_code;
++
++	  STATE_CPU (sd, 0)->current_interrupts |= int_mask;
++	  STATE_CPU (sd, 0)->pending_interrupts &= ~int_mask;
+ 	}
+       sim_engine_restart (sd, NULL, NULL, NULL_CIA);
+     }
+diff -up sim/v850/v850.igen.\~1\~ sim/v850/v850.igen
+--- sim/v850/v850.igen.~1~	Mon Mar 26 13:20:00 2001
++++ sim/v850/v850.igen	Mon Aug 27 15:55:47 2001
+@@ -742,6 +742,10 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI
+     {
+       nia = (EIPC & ~1);
+       PSW = EIPSW;
++      // We must be returning from the highest priority interrupt, so
++      // clear its bit.
++      STATE_CPU (SD, CPU)->current_interrupts
++        &= (STATE_CPU (SD, CPU)->current_interrupts - 1);
+     }
+   TRACE_BRANCH1 (PSW);
+ }
diff -urN linux-2.4.29/arch/v850/sim/patches/sim-lomem-protect.patch linux-2.4.29-uc1/arch/v850/sim/patches/sim-lomem-protect.patch
--- linux-2.4.29/arch/v850/sim/patches/sim-lomem-protect.patch	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/patches/sim-lomem-protect.patch	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,197 @@
+2001-09-07  Miles Bader  <miles@gnu.org>
+
+	* v850.igen ("switch r<reg1>"): Use IMEM16 instead of load_mem.
+	* interp.c (do_interrupt): Use IMEM16 instead of load_mem to look
+	for a `halt' instruction.
+	* sim-main.h (IMEM16): Use `STATE_CPU(sd,0)' instead of `CPU',
+	as IMEM16_IMMED does.
+
+	* sim-main.h (sim_lomem_read_protect_boundary)
+	(sim_lomem_write_protect_boundary): New declarations.
+	(sim_lomem_fault): New declaration.
+	(load_mem, store_mem): Test reads/writes against the appropriate
+	boundary and signal an error if below it.
+
+	* interp.c (v850_options): Add entries for read/write-protect-lomem.
+	(v850_option_handler): Parse them.
+	(OPTION_V850_READ_PROTECT_LOMEM, OPTION_V850_WRITE_PROTECT_LOMEM):
+	New enums.
+
+diff -up sim/v850/sim-main.h.\~3\~ sim/v850/sim-main.h
+--- sim/v850/sim-main.h.~3~	Mon Aug 27 15:14:29 2001
++++ sim/v850/sim-main.h	Fri Sep  7 13:56:29 2001
+@@ -195,21 +195,44 @@ nia = PC
+ 
+ /* Function declarations.  */
+ 
++
+ #define IMEM16(EA) \
+-sim_core_read_aligned_2 (CPU, PC, exec_map, (EA))
++sim_core_read_aligned_2 (STATE_CPU (sd, 0), PC, exec_map, (EA))
+ 
+ #define IMEM16_IMMED(EA,N) \
+ sim_core_read_aligned_2 (STATE_CPU (sd, 0), \
+ 			 PC, exec_map, (EA) + (N) * 2)
+ 
+-#define load_mem(ADDR,LEN) \
+-sim_core_read_unaligned_##LEN (STATE_CPU (simulator, 0), \
+-			       PC, read_map, (ADDR))
+-
+-#define store_mem(ADDR,LEN,DATA) \
+-sim_core_write_unaligned_##LEN (STATE_CPU (simulator, 0), \
+-				PC, write_map, (ADDR), (DATA))
+-
++/* Boundary below which memory is write-protected.  */
++extern address_word sim_lomem_write_protect_boundary;
++/* Boundary below which memory is read-protected.  */
++extern address_word sim_lomem_read_protect_boundary;
++/* Called if there's an invalid read/write.  */
++extern void sim_lomem_fault (SIM_DESC sd, sim_cpu *cpu,
++			    address_word addr, unsigned len,
++			    sim_cia cia, int is_write);
++
++#define load_mem(ADDR,LEN)						      \
++  ({									      \
++    address_word _addr = (ADDR);					      \
++    SIM_DESC sd = simulator;						      \
++    sim_cpu *cpu = STATE_CPU (sd, 0);					      \
++    if (_addr < sim_lomem_read_protect_boundary)			      \
++      sim_lomem_fault (sd, cpu, _addr, LEN, PC, 0);			      \
++    sim_core_read_unaligned_##LEN (cpu, PC, read_map, _addr);		      \
++  })
++
++#define store_mem(ADDR,LEN,DATA)					      \
++  ({									      \
++    address_word _addr = (ADDR);					      \
++    unsigned_##LEN _data = (DATA);					      \
++    SIM_DESC sd = simulator;						      \
++    sim_cpu *cpu = STATE_CPU (sd, 0);					      \
++    if (_addr < sim_lomem_write_protect_boundary)			      \
++      sim_lomem_fault (sd, cpu, _addr, LEN, PC, 1);			      \
++    else								      \
++      sim_core_write_unaligned_##LEN (cpu, PC, write_map, _addr, _data);      \
++  })
+ 
+ /* compare cccc field against PSW */
+ int condition_met (unsigned code);
+diff -up sim/v850/interp.c.\~4\~ sim/v850/interp.c
+--- sim/v850/interp.c.~4~	Wed Sep  5 16:24:37 2001
++++ sim/v850/interp.c	Fri Sep  7 14:33:22 2001
+@@ -37,6 +37,9 @@ SIM_DESC simulator;
+ 
+ enum {
+   OPTION_V850_RECENT_BRANCHES = OPTION_START,
++  OPTION_V850_READ_PROTECT_LOMEM,
++  OPTION_V850_WRITE_PROTECT_LOMEM,
++  OPTION_V850_PROTECTED_LOMEM_INFO
+ };
+ 
+ static DECLARE_OPTION_HANDLER (v850_option_handler);
+@@ -46,6 +49,18 @@ static const OPTION v850_options[] =
+   { {"recent-branches", no_argument, NULL, OPTION_V850_RECENT_BRANCHES },
+       '\0', NULL, "Show a list of recent branches",
+       v850_option_handler },
++  { {"read-protect-low-memory", required_argument, NULL,
++     OPTION_V850_READ_PROTECT_LOMEM },
++    '\0', "BOUNDARY", "Signal a fault for any reads below address BOUNDARY",
++    v850_option_handler },
++  { {"write-protect-low-memory", required_argument, NULL,
++     OPTION_V850_WRITE_PROTECT_LOMEM },
++    '\0', "BOUNDARY", "Signal a fault for any writes below address BOUNDARY",
++    v850_option_handler },
++  { {"protected-low-memory-info", no_argument, NULL,
++     OPTION_V850_PROTECTED_LOMEM_INFO },
++    '\0', NULL, "Show which low-memory addresses are protected from reading/writing",
++    v850_option_handler },
+   { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
+ };
+ 
+@@ -60,6 +75,44 @@ v850_option_handler (SIM_DESC sd, sim_cp
+     case OPTION_V850_RECENT_BRANCHES:
+       show_recent_branches (sd);
+       return SIM_RC_OK;
++
++    case OPTION_V850_READ_PROTECT_LOMEM:
++    case OPTION_V850_WRITE_PROTECT_LOMEM:
++      {
++	char *tail;
++	int is_write = (opt == OPTION_V850_WRITE_PROTECT_LOMEM);
++	address_word addr = strtol (arg, &tail, 0);
++	if (addr == 0 && tail == arg)
++	  {
++	    sim_io_eprintf (sd, "Invalid %s-protect boundary `%s'\n",
++			    is_write ? "write" : "read", arg);
++	    return SIM_RC_FAIL;
++	  }
++	if (is_write)
++	  sim_lomem_write_protect_boundary = addr;
++	else
++	  sim_lomem_read_protect_boundary = addr;
++      }
++      return SIM_RC_OK;
++
++    case OPTION_V850_PROTECTED_LOMEM_INFO:
++      {
++	if (sim_lomem_read_protect_boundary == 0)
++	  sim_io_printf (sd, "No addresses protected against reading\n");
++	else
++	  sim_io_printf (sd,
++			 "Addresses below 0x%lx protected against reading\n",
++			 sim_lomem_read_protect_boundary);
++
++	if (sim_lomem_write_protect_boundary == 0)
++	  sim_io_printf (sd, "No addresses protected against writing\n");
++	else
++	  sim_io_printf (sd,
++			 "Addresses below 0x%lx protected against writing\n",
++			 sim_lomem_write_protect_boundary);
++      }
++      return SIM_RC_OK;
++
+     default:
+       sim_io_eprintf (sd, "Unknown v850 option %d\n", opt);
+       return SIM_RC_FAIL;
+@@ -116,7 +169,7 @@ do_interrupt (sd, data)
+ 
+   /* How to adjust the PC upon return from this interrupt.  This is zero
+      for everything but a `halt' instruction.  */
+-  if (load_mem (PC, 2) == 0x07e0 && load_mem (PC + 2, 2) == 0x0120)
++  if (IMEM16 (PC) == 0x07e0 && IMEM16 (PC + 2) == 0x0120)
+     /* PC is pointing to a `halt' insn.  */
+     pc_adjust = 4;
+   else
+@@ -464,4 +517,22 @@ show_recent_branches (SIM_DESC sd)
+ 	  wrapped = 1;
+ 	}
+     }
++}
++
++
++/* Boundary below which memory is write-protected.  */
++address_word sim_lomem_write_protect_boundary = 0;
++/* Boundary below which memory is read-protected.  */
++address_word sim_lomem_read_protect_boundary = 0;
++
++/* Called if there's an invalid read/write.  */
++void
++sim_lomem_fault (SIM_DESC sd, sim_cpu *cpu,
++		 address_word addr, unsigned len,
++		 sim_cia cia, int is_write)
++{
++  sim_io_eprintf (sd,
++	  "core: %d byte %s protected low memory address 0x%lx at 0x%lx\n",
++		  len, is_write ? "write to" : "read from", addr, cia);
++  sim_engine_halt (sd, cpu, NULL, cia, sim_stopped, SIM_SIGSEGV);
+ }
+diff -up sim/v850/v850.igen.\~3\~ sim/v850/v850.igen
+--- sim/v850/v850.igen.~3~	Mon Aug 27 15:55:47 2001
++++ sim/v850/v850.igen	Fri Sep  7 14:31:32 2001
+@@ -1049,7 +1049,7 @@ rrrrr,001100,RRRRR:I:::subr
+   SAVE_1;
+   trace_input ("switch", OP_REG, 0);
+   adr = (cia + 2) + (State.regs[ reg1 ] << 1);
+-  nia = (cia + 2) + (EXTEND16 (load_mem (adr, 2)) << 1);
++  nia = (cia + 2) + (EXTEND16 (IMEM16 (adr)) << 1);
+   trace_output (OP_REG);
+ }
+ 
diff -urN linux-2.4.29/arch/v850/sim/patches/sim-makeraw.patch linux-2.4.29-uc1/arch/v850/sim/patches/sim-makeraw.patch
--- linux-2.4.29/arch/v850/sim/patches/sim-makeraw.patch	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/patches/sim-makeraw.patch	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,41 @@
+diff -up sim/v850/simops.c.\~4\~ sim/v850/simops.c
+--- sim/v850/simops.c.~4~	Mon Sep  3 15:50:09 2001
++++ sim/v850/simops.c	Wed Sep  5 11:08:43 2001
+@@ -37,6 +37,11 @@
+ #include <sys/time.h>
+ #endif
+ 
++#ifdef HAVE_TERMIOS_H
++#include <termios.h>
++#define TARGET_SYS_make_raw 1024
++#endif
++
+ /* This is an array of the bit positions of registers r20 .. r31 in
+    that order in a prepare/dispose instruction.  */
+ int type1_regs[12] = { 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 0, 21 };
+@@ -1898,6 +1903,25 @@ OP_10007E0 ()
+ 	  }
+ 	  break;
+ #endif
++#endif
++
++#ifdef TARGET_SYS_make_raw
++	case TARGET_SYS_make_raw:
++	  {
++	    struct termios termios;
++	    int fd = PARM1;
++	    int rval = tcgetattr (fd, &termios);
++
++	    if (rval >= 0)
++	      {
++		cfmakeraw (&termios);
++		termios.c_oflag |= OPOST;
++		rval = tcsetattr (fd, TCSANOW, &termios);
++	      }
++
++	    RETVAL = rval;
++	  }
++	  break;
+ #endif
+ 
+ 	default:
diff -urN linux-2.4.29/arch/v850/sim/patches/sim-poll.patch linux-2.4.29-uc1/arch/v850/sim/patches/sim-poll.patch
--- linux-2.4.29/arch/v850/sim/patches/sim-poll.patch	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/patches/sim-poll.patch	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,105 @@
+sim/v850/ChangeLog:
+2001-09-03  Miles Bader  <miles@gnu.org>
+
+	* simops.c (OP_10007E0): Add handling of `poll' system call.
+	* configure.in (AC_CHECK_FUNCS): Add `poll'.
+	(AC_CHECK_HEADERS): Add `poll.h'.
+
+libgloss/ChangeLog:
+2001-09-03  Miles Bader  <miles@gnu.org>
+
+	* v850/sys/syscall.h (SYS_poll): New syscall.
+
+diff -up sim/v850/simops.c.\~3\~ sim/v850/simops.c
+--- sim/v850/simops.c.~3~	Mon Aug 27 17:34:08 2001
++++ sim/v850/simops.c	Mon Sep  3 15:50:09 2001
+@@ -22,6 +22,10 @@
+ #endif
+ #endif
+ 
++#ifdef HAVE_POLL_H
++#include <poll.h>
++#endif
++
+ #include "targ-vals.h"
+ 
+ #include "libiberty.h"
+@@ -1773,6 +1777,44 @@ OP_10007E0 ()
+ 	    store_mem (buf + 20, 4, host_stat.st_atime);
+ 	    store_mem (buf + 28, 4, host_stat.st_mtime);
+ 	    store_mem (buf + 36, 4, host_stat.st_ctime);
++	  }
++	  break;
++#endif
++#endif
++
++#ifdef HAVE_POLL
++#ifdef TARGET_SYS_poll
++	case TARGET_SYS_poll:
++	  {
++	    reg_t sfds;
++	    int fd, nevents;
++	    int nfds = PARM2;
++	    int fds_len = nfds * sizeof (struct pollfd);
++	    struct pollfd *fds = zalloc (fds_len);
++
++	    /* Copy the fd structures from sim memory to real memory. */
++	    for (fd = 0, sfds = PARM1; fd < nfds; fd++, sfds += 8)
++	      {
++		fds[fd].fd = load_mem (sfds, 4);
++		fds[fd].events = load_mem (sfds + 4, 2);
++		fds[fd].revents = load_mem (sfds + 6, 2);
++	      }
++
++	    nevents = poll (fds, nfds, PARM3);
++	    RETVAL = nevents;
++
++	    for (fd = 0, sfds = PARM1;
++		 fd < nfds && nevents > 0;
++		 fd++, sfds += 8)
++	      {
++		if (fds[fd].revents)
++		  {
++		    store_mem (sfds + 6, 2, fds[fd].revents);
++		    nevents--;
++		  }
++	      }
++
++	    zfree (fds);
+ 	  }
+ 	  break;
+ #endif
+diff -up sim/v850/configure.in.\~1\~ sim/v850/configure.in
+--- sim/v850/configure.in.~1~	Mon Mar 26 13:20:00 2001
++++ sim/v850/configure.in	Mon Sep  3 13:54:13 2001
+@@ -12,7 +12,7 @@ SIM_AC_OPTION_WARNINGS
+ SIM_AC_OPTION_RESERVED_BITS
+ SIM_AC_OPTION_BITSIZE(32,31)
+ 
+-AC_CHECK_FUNCS(time chmod utime fork execve execv chown)
+-AC_CHECK_HEADERS(unistd.h stdlib.h string.h strings.h utime.h time.h)
++AC_CHECK_FUNCS(time chmod utime fork execve execv chown poll)
++AC_CHECK_HEADERS(unistd.h stdlib.h string.h strings.h utime.h time.h poll.h)
+ 
+ SIM_AC_OUTPUT
+diff -up libgloss/v850/sys/syscall.h.\~1\~ libgloss/v850/sys/syscall.h
+--- libgloss/v850/sys/syscall.h.~1~	Thu Oct  5 19:59:59 2000
++++ libgloss/v850/sys/syscall.h	Mon Sep  3 16:05:02 2001
+@@ -25,14 +25,14 @@
+ #define SYS_fstat       22
+ #define SYS_time        23
+ 
+-
+ #define SYS_ARG         24
+-#define SYS_stat        38
+ 
++#define SYS_stat        38
++#define SYS_poll	29
+ 
+ #define SYS_pipe        42
+ #define SYS_execve      59
+-#define   SYS_times       43
++#define SYS_times       43
+ #define SYS_gettimeofday 116
+ 
+ #define SYS_utime       201 /* not really a system call */
diff -urN linux-2.4.29/arch/v850/sim/patches/sim-raw-stdio.patch linux-2.4.29-uc1/arch/v850/sim/patches/sim-raw-stdio.patch
--- linux-2.4.29/arch/v850/sim/patches/sim-raw-stdio.patch	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/patches/sim-raw-stdio.patch	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,71 @@
+diff -up sim/common/sim-options.c.\~1\~ sim/common/sim-options.c
+--- sim/common/sim-options.c.~1~	Thu Oct  5 19:59:52 2000
++++ sim/common/sim-options.c	Tue Sep  4 13:50:12 2001
+@@ -1,5 +1,5 @@
+ /* Simulator option handling.
+-   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
++   Copyright (C) 1996, 1997, 2001 Free Software Foundation, Inc.
+    Contributed by Cygnus Support.
+ 
+ This file is part of GDB, the GNU debugger.
+@@ -111,6 +111,7 @@ typedef enum {
+ #ifdef SIM_H8300 /* FIXME: Should be movable to h8300 dir.  */
+   OPTION_H8300,
+ #endif
++  OPTION_STDIO,
+ } STANDARD_OPTIONS;
+ 
+ static const OPTION standard_options[] =
+@@ -182,6 +183,10 @@ static const OPTION standard_options[] =
+       '\0', "BFDNAME", "Specify the object-code format for the object files",
+       standard_option_handler },
+ 
++  { {"stdio", required_argument, NULL, OPTION_STDIO},
++    '\0', "on|off", "Turn special treatment of stdio on or off",
++    standard_option_handler},
++
+   { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
+ };
+ 
+@@ -399,6 +404,18 @@ standard_option_handler (SIM_DESC sd, si
+       if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
+ 	exit (0);
+       /* FIXME: 'twould be nice to do something similar if gdb.  */
++      break;
++
++    case OPTION_STDIO:
++      if (strcmp (arg, "on") == 0)
++	current_stdio = DO_USE_STDIO;
++      else if (strcmp (arg, "off") == 0)
++	current_stdio = DONT_USE_STDIO;
++      else
++	{
++	  sim_io_eprintf (sd, "Argument `%s' for `--stdio' invalid, `on' or `off' expected\n", arg);
++	  return SIM_RC_FAIL;
++	}
+       break;
+     }
+ 
+diff -up sim/common/callback.c.\~1\~ sim/common/callback.c
+--- sim/common/callback.c.~1~	Thu Oct  5 19:59:52 2000
++++ sim/common/callback.c	Tue Sep  4 14:46:50 2001
+@@ -289,18 +289,7 @@ os_write (p, fd, buf, len)
+   if (result)
+     return result;
+   real_fd = fdmap (p, fd);
+-  switch (real_fd)
+-    {
+-    default:
+-      result = wrap (p, write (real_fd, buf, len));
+-      break;
+-    case 1:
+-      result = p->write_stdout (p, buf, len);
+-      break;
+-    case 2:
+-      result = p->write_stderr (p, buf, len);
+-      break;
+-    }
++  result = wrap (p, write (real_fd, buf, len));
+   return result;
+ }
+ 
diff -urN linux-2.4.29/arch/v850/sim/patches/sim-record-branches.patch linux-2.4.29-uc1/arch/v850/sim/patches/sim-record-branches.patch
--- linux-2.4.29/arch/v850/sim/patches/sim-record-branches.patch	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/patches/sim-record-branches.patch	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,158 @@
+2001-09-05  Miles Bader  <miles@gnu.org>
+
+	* sim-main.h (NUM_RECENT_BRANCHES, RECENT_BRANCH): New macros.
+	(struct recent_branch): New type.
+	(recent_branches, next_recent_branch): New declarations.
+	(TRACE_BRANCH0, TRACE_BRANCH1, TRACE_BRANCH2, TRACE_BRANCH3): Use
+	`RECENT_BRANCH'.
+	* interp.c (show_recent_branches, v850_option_handler): New functions.
+	(OPTION_V850_RECENT_BRANCHES): New enum.
+	(v850_options): New variable.
+
+diff -up sim/v850/sim-main.h.\~3\~ sim/v850/sim-main.h
+--- sim/v850/sim-main.h.~3~	Mon Aug 27 15:14:29 2001
++++ sim/v850/sim-main.h	Wed Sep  5 16:14:07 2001
+@@ -264,8 +264,30 @@ extern unsigned32 trace_pc;
+ extern const char *trace_name;
+ extern int trace_module;
+ 
++#define NUM_RECENT_BRANCHES 32
++struct recent_branch {
++  unsigned long from, to, arg1, arg2, arg3;
++  const char *insn_name;
++};
++extern struct recent_branch recent_branches[NUM_RECENT_BRANCHES];
++extern int next_recent_branch;
++#define RECORD_BRANCH(_from, _to, _insn_name, _arg1, _arg2, _arg3)	      \
++do {									      \
++  struct recent_branch *rb;						      \
++  if (next_recent_branch == NUM_RECENT_BRANCHES)			      \
++    next_recent_branch = 0;						      \
++  rb = &recent_branches[next_recent_branch++];				      \
++  rb->from = _from;							      \
++  rb->to = _to;								      \
++  rb->insn_name = _insn_name;						      \
++  rb->arg1 = _arg1;							      \
++  rb->arg2 = _arg2;							      \
++  rb->arg3 = _arg3;							      \
++} while (0)
++
+ #define TRACE_BRANCH0() \
+ do { \
++  RECORD_BRANCH (cia, nia, itable[MY_INDEX].name, 0, 0, 0); \
+   if (TRACE_BRANCH_P (CPU)) { \
+     trace_module = TRACE_BRANCH_IDX; \
+     trace_pc = cia; \
+@@ -277,6 +299,7 @@ do { \
+ 
+ #define TRACE_BRANCH1(IN1) \
+ do { \
++  RECORD_BRANCH (cia, nia, itable[MY_INDEX].name, IN1, 0, 0); \
+   if (TRACE_BRANCH_P (CPU)) { \
+     trace_module = TRACE_BRANCH_IDX; \
+     trace_pc = cia; \
+@@ -289,6 +312,7 @@ do { \
+ 
+ #define TRACE_BRANCH2(IN1, IN2) \
+ do { \
++  RECORD_BRANCH (cia, nia, itable[MY_INDEX].name, IN1, IN2, 0); \
+   if (TRACE_BRANCH_P (CPU)) { \
+     trace_module = TRACE_BRANCH_IDX; \
+     trace_pc = cia; \
+@@ -302,6 +326,7 @@ do { \
+ 
+ #define TRACE_BRANCH3(IN1, IN2, IN3) \
+ do { \
++  RECORD_BRANCH (cia, nia, itable[MY_INDEX].name, IN1, IN2, IN3); \
+   if (TRACE_BRANCH_P (CPU)) { \
+     trace_module = TRACE_BRANCH_IDX; \
+     trace_pc = cia; \
+diff -up sim/v850/interp.c.\~3\~ sim/v850/interp.c
+--- sim/v850/interp.c.~3~	Mon Aug 27 16:15:01 2001
++++ sim/v850/interp.c	Wed Sep  5 16:24:37 2001
+@@ -32,7 +32,41 @@ static const char * get_insn_name (sim_c
+ SIM_DESC simulator;
+ 
+ 
++
++/* Options.  */
+ 
++enum {
++  OPTION_V850_RECENT_BRANCHES = OPTION_START,
++};
++
++static DECLARE_OPTION_HANDLER (v850_option_handler);
++
++static const OPTION v850_options[] =
++{
++  { {"recent-branches", no_argument, NULL, OPTION_V850_RECENT_BRANCHES },
++      '\0', NULL, "Show a list of recent branches",
++      v850_option_handler },
++  { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
++};
++
++static void show_recent_branches (SIM_DESC sd);
++
++static SIM_RC
++v850_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
++		     char *arg, int is_command)
++{
++  switch (opt)
++    {
++    case OPTION_V850_RECENT_BRANCHES:
++      show_recent_branches (sd);
++      return SIM_RC_OK;
++    default:
++      sim_io_eprintf (sd, "Unknown v850 option %d\n", opt);
++      return SIM_RC_FAIL;
++    }
++}
++
++
+ /* v850 interrupt model */
+ 
+ enum interrupt_type
+@@ -269,6 +303,8 @@ sim_open (kind, cb, abfd, argv)
+   /* similarly if in the internal RAM region */
+   sim_do_command (sd, "memory region 0xffe000,0x1000,1024");
+ 
++  sim_add_option_table (sd, NULL, v850_options);
++
+   /* getopt will print the error message so we just have to exit if this fails.
+      FIXME: Hmmm...  in the case of gdb we need getopt to call
+      print_filtered.  */
+@@ -398,5 +434,34 @@ sim_do_command (sd, cmd)
+ 	sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n");
+       else
+ 	sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
++    }
++}
++
++
++
++struct recent_branch recent_branches[NUM_RECENT_BRANCHES] = { 0 };
++int next_recent_branch = 0;
++
++static void
++show_recent_branches (SIM_DESC sd)
++{
++  int wrapped = 0, index = 0, i;
++
++  for (i = next_recent_branch; i != next_recent_branch || !wrapped;)
++    {
++      if (recent_branches[i].insn_name)
++	{
++	  struct recent_branch *rb = &recent_branches[i];
++	  sim_io_printf (sd, "%2d: 0x%08x -> 0x%08x   %s %d, %d, %d\n",
++			 index++,
++			 rb->from, rb->to,
++			 rb->insn_name, rb->arg1, rb->arg2, rb->arg3);
++	}
++
++      if (++i == NUM_RECENT_BRANCHES)
++	{
++	  i = 0;
++	  wrapped = 1;
++	}
+     }
+ }
diff -urN linux-2.4.29/arch/v850/sim/patches/sim-trap-addr.patch linux-2.4.29-uc1/arch/v850/sim/patches/sim-trap-addr.patch
--- linux-2.4.29/arch/v850/sim/patches/sim-trap-addr.patch	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/patches/sim-trap-addr.patch	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,16 @@
+2001-08-27  Miles Bader  <miles@gnu.org>
+
+	* simops.c (OP_10007E0): Don't subtract 4 from the new trap PC.
+
+diff -up sim/v850/simops.c.\~2\~ sim/v850/simops.c
+--- sim/v850/simops.c.~2~	Fri Aug 24 15:38:19 2001
++++ sim/v850/simops.c	Mon Aug 27 17:34:08 2001
+@@ -1875,7 +1875,7 @@ OP_10007E0 ()
+       ECR |= 0x40 + OP[0];
+       /* Flag that we are now doing exception processing.  */
+       PSW |= PSW_EP | PSW_ID;
+-      PC = ((OP[0] < 0x10) ? 0x40 : 0x50) - 4;
++      PC = (OP[0] < 0x10) ? 0x40 : 0x50;
+ 
+       return 0;
+     }
diff -urN linux-2.4.29/arch/v850/sim/README linux-2.4.29-uc1/arch/v850/sim/README
--- linux-2.4.29/arch/v850/sim/README	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/README	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,13 @@
+This directory contains some useful files for debugging using the gdb
+v850 simulator.
+
+
+   gdb-scripts/		An example .gdbrc and useful gdb scripts.
+
+   patches/		Patches for the simulator and gdb
+
+   updroot		A shell script that copies a directory tree called
+			`root' into an ext2 filesystem image called
+			`root.ext2', which is the name the simulator-specific
+			startup code in the uclinux v850 port looks for to
+			initialize the root filesystem.
diff -urN linux-2.4.29/arch/v850/sim/updroot linux-2.4.29-uc1/arch/v850/sim/updroot
--- linux-2.4.29/arch/v850/sim/updroot	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/arch/v850/sim/updroot	2005-06-14 02:11:04.000000000 +0100
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+SIZE=1024
+SRC=root
+DST=root.ext2
+
+TMP=/tmp/root.ext2
+MNT=/tmp/root.mnt
+
+dd if=/dev/zero of=$TMP bs=1024 count=$SIZE 2>&1 | grep -v 'records \(in\|out\)' 1>&2
+mke2fs -m0 -q -F $TMP 2>&1 | grep -v '^mke2fs ' 1>&2
+
+mkdir -p $MNT
+sudo mount -t ext2 $TMP $MNT -o loop
+
+mkdir -p $MNT/dev
+
+rm -rf $MNT/lost+found
+
+# Not need with devfs
+#sudo mknod $MNT/dev/console c 5 1
+
+(cd $SRC; tar cf - .) | (cd $MNT; tar xvf -)
+
+sudo umount $MNT
+
+mv $TMP .
diff -urN linux-2.4.29/CREDITS linux-2.4.29-uc1/CREDITS
--- linux-2.4.29/CREDITS	2005-01-19 14:09:22.000000000 +0000
+++ linux-2.4.29-uc1/CREDITS	2005-06-14 02:11:54.000000000 +0100
@@ -157,6 +157,14 @@
 S: Calgary, Alberta
 S: Canada
 
+N: Miles Bader
+E: miles@gnu.org
+D: v850 port (uClinux)
+S: NEC Corporation
+S: 1753 Shimonumabe, Nakahara-ku
+S: Kawasaki 211-8666
+S: Japan
+
 N: Ralf Baechle
 E: ralf@gnu.org
 P: 1024/AF7B30C1 CF 97 C2 CC 6D AE A7 FE  C8 BA 9C FC 88 DE 32 C3
diff -urN linux-2.4.29/crypto/Config.in linux-2.4.29-uc1/crypto/Config.in
--- linux-2.4.29/crypto/Config.in	2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.29-uc1/crypto/Config.in	2005-06-14 02:10:53.000000000 +0100
@@ -11,7 +11,9 @@
      "$CONFIG_INET6_AH" = "y" -o \
      "$CONFIG_INET6_AH" = "m" -o \
      "$CONFIG_INET6_ESP" = "y" -o \
-     "$CONFIG_INET6_ESP" = "m" ]; then
+     "$CONFIG_INET6_ESP" = "m" -o \
+     "$CONFIG_IPV6_PRIVACY" = "y" -o \
+     "$CONFIG_IPV6_NODEINFO" = "y" ]; then
   define_bool CONFIG_CRYPTO y
 else
   bool 'Cryptographic API' CONFIG_CRYPTO
@@ -39,7 +41,9 @@
        "$CONFIG_INET6_AH" = "y" -o \
        "$CONFIG_INET6_AH" = "m" -o \
        "$CONFIG_INET6_ESP" = "y" -o \
-       "$CONFIG_INET6_ESP" = "m" ]; then
+       "$CONFIG_INET6_ESP" = "m" -o \
+       "$CONFIG_IPV6_PRIVACY" = "y" -o \
+       "$CONFIG_IPV6_NODEINFO" = "y" ]; then
     define_bool CONFIG_CRYPTO_MD5 y
   else
     tristate       '  MD5 digest algorithm' CONFIG_CRYPTO_MD5
diff -urN linux-2.4.29/Documentation/arm/FASS_ARM_Linux_Implementation linux-2.4.29-uc1/Documentation/arm/FASS_ARM_Linux_Implementation
--- linux-2.4.29/Documentation/arm/FASS_ARM_Linux_Implementation	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/Documentation/arm/FASS_ARM_Linux_Implementation	2005-06-14 02:10:53.000000000 +0100
@@ -0,0 +1,260 @@
+ARM Linux Fast Address-Space Switching (FASS)
+
+	This is current (hopefully) as of patch
+diff-2.4.18-rmk4-fass4.
+It gives an overview of the design and describes bits of the
+implementation, its structure and status.
+	If you have any comments/corrections please let me know at
+<awiggins@cse.unsw.edu.au>
+
+	Cheers, Adam
+
+Basic Idea:
+
+  OK the basic Idea is as follows. Rather then switch page directories
+  (pg_dir) which requires cache and TLB flushes a single pg_dir is
+  used. I call this global pg_dir the "Caching Page Directory" or
+  CPD. It can be thought of as a software TLB.
+
+  The CPD stores pg_dir entries from multiple user page directories as
+  well as the kernel's pg_dir entries. The pg_dir entries are tagged
+  with ARM domains which are assigned uniquely to user tasks as well
+  as a small set being reserved for tagging kernel mappings.
+
+  A context switch from one user process to another is carried out by
+  disabling the domain of the old process and enabling the domain of
+  the new process. The set of domains allocated to the kernel mappings
+  are manipulated as in the unmodified ARM Linux kernel.
+
+  Using this technique the caches and TLBs need only be flushed if one
+  of two events happen:
+
+	1) An entry in the CPD is replace by one owned by a different user
+	process, hence tagged with a different domain.
+
+	2) A domain is currently owned by one user process is
+	reallocated to another one.
+
+  These issues both present a challenge to the design. 1) is a problem
+  since the Unix address-space layout is typically the same for every
+  process.  2) is a problem since typically we have many more
+  processes then ARM domains which are fixed at 16 by the
+  architecture.
+
+  These problems are solved as follows:
+
+    1) A dual approach is used here to handle the two types of memory
+    regions used in a user process:
+
+	a) All memory regions with run time address bindings, i.e.,
+	those mapped in by mmap() without the MAP_FIXED flag, are
+	grouped into 1MB regions (because pg_dir entries cover 1MB)
+	that are already being used by the process.  If the new
+	mapping doesn't fit in an existing 1MB region allocated to the
+	user process, a new one will be allocated. The newly allocated
+	region will be one that causes the least contention with other
+	processes using that same 1MB region, or the virtual
+	address-space. Multiple processes can use the same 1MB region
+	safely because of the domain tags and CPD mechanism. 'Least
+	contention' can be defined as either fewest processes
+	sharing a domain (likelihood of a contention) or least number
+	of previous conflicts (history of contention) or some
+	combination of the these.
+
+	b) All memory regions with compile time address bindings, the
+	text/data/bss/etc which are mapped in by mmap() with the
+	MAP_FIXED flag, are as much as possible compiled to be within
+	the first 32MB, i.e., below 0x02000000.  The mappings are then
+	relocated using the ARM PID register into one of the 32MB
+	slots in the first 2GBs of the address-space. The relocation
+	staggers 64 user processes uniquely then PIDs well have to be
+	shared. Again the overlapping is safe as the CPD mechanism
+	handles the contention. As there are more PIDs then domains
+	the number shouldn't be an issue. 
+
+	The stack is also set to the top of the 32MB region, even
+	though this could be placed anywhere, hence, staggered by 
+	1a) it is placed in the PID relocation area because fork()ing will
+	keep the same stack pointer causing a collision between the
+	two processes. While this will limit the size of brk() to be
+	inside the 32MB area it does not limit malloc() as it will use
+	mmap() to allocate new heaps if brk() fails. If the stack is
+	simply staggered by 1a) the brk() grows past the PID relocation
+	area as the PID relocation is transparent to the user process
+	and most of the kernel.  Only the CPD mechanism is aware of
+	it. Actual allocation of PIDs is still up in the air. At the
+	moment it simply round-robins through them. Smarter allocation
+	schemes might take into account the number of address-spaces
+	using the PID and allocate the one with the least usage or
+	with the least busy address-spaces, etc. To minimise
+	collisions due to fork mappings flagged MAP_PRIVATE are as
+	much as possible allocated in the 32MB relocation area.
+
+  2) At the moment the approach is to revoke what causes the least
+  amount of work.  First we look for a clean domain to revoke. This
+  means no cache flush and only invalidating the CPD entries tagged
+  with the victim domain. If no clean domains are available then a
+  dirty one is used. In both cases the one with the least number of
+  entries in the CPD is used. This might not be the most optimal way
+  of doing it as tasks newly allocated a domain may be preempted first
+  in times of domain thrashing.
+
+Data Cache Aliasing:
+
+  Aliases occur when the same physical frame is mapped to more then
+  one virtual address. This can happen within the same address-space
+  or between different address-spaces. It is only a problem for
+  writable pages as the different address lines will map to different
+  cache lines. If one is modified the other will not see the change so
+  accesses to that virtual address will access stale data.  The
+  problem can be address in one of two ways:
+
+	1) Mark the shared mapping as uncachable. This slows down
+	accesses to the shared mappings but never requires cache
+	flushing. ARM Linux currently uses this method for shared
+	mappings within the same address-space.
+
+	2) Only activate one mapping at a time. When another mapping
+	is accessed it will fault. At that stage the page in question
+	is cleaned/flushed from the DCache, the old mapping is
+	deactivated, and the accessed mapping is activated.  faster
+	accesses on the shared mappings but will cause slow downs when
+	the frame changes mappings.
+
+  I plan to implement and benchmark both solutions. Or at least
+  analyse it further, possibly have a flag to set which one is used.
+
+  If the shared mapping uses the same virtual address in each
+  address-space no cache flushing or uncachable setting is
+  needed. Although this will cause a CPD conflict anyway so no
+  gain. Separate domains for unique sharing groups could solve this
+  but is definitely future work.
+
+Lazy Cache/TLB Flushing:
+
+  All the cache and TLB flushing routines used to flush user mappings
+  make use of the following fact. If the CPD entry/entries mapping in
+  the flush range are not tagged with the domain tag of the
+  address-space being flushed, the caches cannot contain any data from
+  that address-space and the TLBs cannot contain any mappings for that
+  address-space. This is used to avoid many cache flushes.  Another
+  bit of information can be used: when the caches/TLBs are flushed all
+  domains are marked as clean with respect to them. They remain clean
+  until the domain is activated. This way an address-space with CPD
+  entries in the flush region may still be clean if none of its
+  mappings have been touched.  This technique of lazy flushing could
+  be used by normal ARM Linux using the single user domain.
+
+Shared Domains:
+
+  As well as using domains as a kind of address-space identifier
+  (ASID) tagging address-spaces uniquely, they can be used to tag
+  shared mappings that map to the same virtual addresses with the same
+  size/permissions in each of the sharing address-spaces. This is
+  known as shared domains. To support this every vm_area_struct (Linux
+  mapping representation) is allocated a region, and one is also
+  allocated to the address-space. Mappings that are private to the
+  address-space simply use the address-space's region. Domains are now
+  mapped to regions not address spaces and when we switch to a new
+  address space we enable the domains, if any, allocated to the
+  regions accessible by the address-space.
+
+Implementation Details:
+
+  The implementation is spread around a LOT of the ARM specific files.
+  However FASS slides nicely into Linux with only ARM arch specific
+  modifications.  The main part of FASS, the CPD mechanism, fits in
+  the following way:
+
+  * Entries are added into the CPD by ARM Data/Prefetch Aborts in
+    arch/arm/mm/fault-armv.c the abort handlers are modified and the
+    functions do_cpd_fault() and do_domain_fault() are added. This
+    functions go on to call CPD management functions in
+    arch/arm/mm/cpd.c
+
+  * Entries are removed from the CPD by the functions in arch/arm/mm/cpd.c
+    this includes cpd_set_pmd() which updates the CPD to reflect
+    changes in the user pg_dir. CPD entries are also removed in
+    cpd_load() due to a conflict (replacement) and in
+    domain_unallocate() due to domain preemption or the address-space
+    being torn down.
+
+  * The cache/TLB flush routines in include/asm-arm/proc-armv/cache.h all
+    call an equivalent CPD_*() functions in arch/arm/mm/cpd.c to
+    implement lazy flushing of caches/TLBs.
+
+  * ARM PID management code is in arch/arm/mm/pid.c and
+    include/asm-arm/proc-armv/pid.h
+
+  * ARM domain management code is in arch/arm/mm/cpd.c ,
+    include/asm-arm/proc-armv/cpd.h and
+    include/asm-arm/proc-armv/domain.h
+
+  * An address-space mmu_context is defined in include/asm-arm/mmu.h and
+    include/asm-arm/mmu_context.h defining a domain/PID allocated to
+    the address-space.
+
+  * Some architecture independent code changes have been made to the
+    code that deals with vma's to add a new field 'vm_sharing_data'
+    which points to the region data structure in ARM and should be
+    used for similar TLB sharing support in other architectures like
+    IA-64. 'vm_private_data' was not used as it is unclear how this
+    field is used by other Linux code such as drivers.
+
+All other changes should be clear from the patch.
+
+TO DO: 
+
+  * arch/arm/mm/pid.c:pid_allocate() simply finds a PID with the lowest
+    number of address-spaces using it. There could possibly be a
+    better way of doing this. It also needs to decide when a ARM PID
+    of 0, i.e., no VM relocation is used, this might have to be
+    decided by the caller of pid_allocate(). Binaries located outside
+    of the relocation area cause problems.
+
+  * arch/arm/mm/fault-armv.c:update_mmu_cache() allocates region_structs
+    to shared mapping to support shared domains. However at the moment
+    it doesn't check the size or protection rights of the mapping
+    allowing the max of each out the process set to be accessible to
+    all address-spaces sharing the mapping. This is incorrect
+    behaviour and needs to be dealt fixed up some how.
+
+  * arch/arm/mm/cpd.c:cpd_get_domain()/cpd_get_active_domain(), these
+    functions should be updated to use the address-spaces private
+    region's domain if the shared region has a count of one. This is
+    to minimise domain thrashing, it may not provide much benefit and
+    is a little tricky to do correctly.
+
+  * The code in cpd.c could probably be split up into separate files,
+    it really should only have the cpd_load function and some helpers.
+
+Future Work:
+
+  * Using sub-pages to deal with Cache Aliasing. This is another
+    experimental idea. If you look at the StrongARM-1 Core the cache
+    is made up of 1KB colours, if you don't understand cache colouring
+    ignore this. But basically we use the (de)activation technique 2)
+    for dealing with cache aliases except we (de)activate the 1KB
+    sub-pages and flush 1KB sub-pages at a time. This better targets
+    the flush and should reduce the overall cost. The implementation
+    might be tricky though.
+
+  * Modifying the architectural independent scheduling goodness() function
+    to schedule around flushes, ie delay the flush as long as possible
+    within a scheduling epoch. This is maybe not worth the trouble.
+
+  * Domain-less CPD entries. This is only applicable to write-back caches
+    that do not require a TLB access to retrieve the physical address
+    of a write-back such at the ARM9 with it's TAG-RAM. What we can do
+    is tag the CPD entry with a inactive domain (reserved for this
+    task) effectively disabling the region and allowing the entries to
+    get cleaned by normal operation. These domain-list CPD entries can
+    then be cleared removed on a cache flush. Very experimental idea,
+    needs a lot more thought and probably won't work. Needs an ARM9
+    core too. This actually works on the StrongARM as well. I need to
+    think about it more though.
+
+  * Anything I've forgotten, basically tuning the implementation and
+    experimenting with idea's for choosing a domain to preempt for
+    recycling, choosing an ARM PID, and choosing 1MB regions for
+    mmap().
diff -urN linux-2.4.29/Documentation/arm/mem_alignment linux-2.4.29-uc1/Documentation/arm/mem_alignment
--- linux-2.4.29/Documentation/arm/mem_alignment	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/Documentation/arm/mem_alignment	2005-06-14 02:10:53.000000000 +0100
@@ -0,0 +1,58 @@
+Too many problems poped up because of unnoticed misaligned memory access in
+kernel code lately.  Therefore the alignment fixup is now unconditionally
+configured in for SA11x0 based targets.  According to Alan Cox, this is a
+bad idea to configure it out, but Russell King has some good reasons for
+doing so on some f***ed up ARM architectures like the EBSA110.  However
+this is not the case on many design I'm aware of, like all SA11x0 based
+ones.
+
+Of course this is a bad idea to rely on the alignment trap to perform
+unaligned memory access in general.  If those access are predictable, you
+are better to use the macros provided by include/asm/unaligned.h.  The
+alignment trap can fixup misaligned access for the exception cases, but at
+a high performance cost.  It better be rare.
+
+Now for user space applications, it is possible to configure the alignment
+trap to SIGBUS any code performing unaligned access (good for debugging bad
+code), or even fixup the access by software like for kernel code.  The later
+mode isn't recommended for performance reasons (just think about the
+floating point emulation that works about the same way).  Fix your code
+instead!
+
+Please note that randomly changing the behaviour without good thought is
+real bad - it changes the behaviour of all unaligned instructions in user
+space, and might cause programs to fail unexpectedly.
+
+To change the alignment trap behavior, simply echo a number into
+/proc/sys/debug/alignment.  The number is made up from various bits:
+
+bit		behavior when set
+---		-----------------
+
+0		A user process performing an unaligned memory access
+		will cause the kernel to print a message indicating
+		process name, pid, pc, instruction, address, and the
+		fault code.
+
+1		The kernel will attempt to fix up the user process
+		performing the unaligned access.  This is of course
+		slow (think about the floating point emulator) and
+		not recommended for production use.
+
+2		The kernel will send a SIGBUS signal to the user process
+		performing the unaligned access.
+
+Note that not all combinations are supported - only values 0 through 5.
+(6 and 7 don't make sense).
+
+For example, the following will turn on the warnings, but without
+fixing up or sending SIGBUS signals:
+
+	echo 1 > /proc/sys/debug/alignment
+
+You can also read the content of the same file to get statistical
+information on unaligned access occurrences plus the current mode of
+operation for user space code.
+
+
+Nicolas Pitre, Mar 13, 2001.  Modified Russell King, Nov 30, 2001.
diff -urN linux-2.4.29/Documentation/Configure.help linux-2.4.29-uc1/Documentation/Configure.help
--- linux-2.4.29/Documentation/Configure.help	2005-01-19 14:09:22.000000000 +0000
+++ linux-2.4.29-uc1/Documentation/Configure.help	2005-06-14 02:10:55.000000000 +0100
@@ -1,3 +1,4 @@
+# $USAGI: Configure.help,v 1.104 2004/01/26 06:00:08 yoshfuji Exp $
 # Maintained by:
 #	Eric S. Raymond <mailto:esr@thyrsus.com>
 #	Steven Cole <mailto:elenstev@mesatop.com>
@@ -2697,6 +2698,13 @@
   byte order. These modes require different kernels. Say Y if your
   machine is little endian, N if it's a big endian machine.
 
+Generate big endian code
+CONFIG_CPU_BIG_ENDIAN
+  Some ARM machines can be configured for either little or big endian
+  byte order. These modes require different kernels. Say Y if your
+  machine is big endian (like the ARM7TDMI based S3C3410x from 
+  Samsung), N if it's a little endian machine.
+
 Use power LED as a heartbeat
 CONFIG_HEARTBEAT
   Use the power-on LED on your machine as a load meter.  The exact
@@ -2831,6 +2839,41 @@
   If you want to compile it as a module, say 'M' here and read
   Documentation/modules.txt.  If unsure, say 'N'.
 
+PPTP conntrack and NAT support
+CONFIG_IP_NF_PPTP
+  This module adds support for PPTP (Point to Point Tunnelling Protocol, 
+  RFC2637) conncection tracking and NAT. 
+
+  If you are running PPTP sessions over a stateful firewall or NAT box,
+  you may want to enable this feature.  
+
+  Please note that not all PPTP modes of operation are supported yet.
+  For more info, read top of the file net/ipv4/netfilter/ip_conntrack_pptp.c
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+GRE protocol conntrack and NAT support
+CONFIG_IP_NF_CT_PROTO_GRE
+  This module adds generic support for connection tracking and NAT of the
+  GRE protocol (RFC1701, RFC2784).  Please note that this will only work
+  with GRE connections using the key field of the GRE header.
+
+  You will need GRE support to enable PPTP support.
+
+  If you want to compile it as a module, say `M' here and read
+  Documentation/modules.txt.  If unsire, say `N'.
+
+H.323 (netmeeting) support
+CONFIG_IP_NF_H323
+  H.323 is a standard signalling protocol used by teleconferencing
+  softwares like netmeeting. With the ip_conntrack_h323 and
+  the ip_nat_h323 modules you can support the protocol on a connection
+  tracking/NATing firewall.
+
+  If you want to compile it as a module, say 'M' here and read
+  Documentation/modules.txt.  If unsure, say 'N'.
+
 TFTP protocol support
 CONFIG_IP_NF_TFTP
   TFTP connection tracking helper, this is required depending
@@ -2841,6 +2884,28 @@
   If you want to compile it as a module, say M here and read
   Documentation/modules.txt.  If unsure, say `Y'.
 
+Per connection mark support
+CONFIG_IP_NF_CONNTRACK_MARK
+  This option enables support for connection marks, used by the
+  `CONNMARK' target and `connmark' match. Similar to the mark value
+  of packets, but this mark value is kept in the conntrack session
+  instead of the individual packets.
+
+CONNMARK target support
+CONFIG_IP_NF_TARGET_CONNMARK
+  This option adds a `CONNMARK' target, which allows one to manipulate
+  the connection mark value.  Similar to the MARK target, but
+  affects the connection mark value rather than the packet mark value.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  The module will be called
+  ipt_CONNMARK.o.  If unsure, say `N'.
+
+connmark match support
+CONFIP_IP_NF_MATCH_CONNMARK
+  This option adds a `connmark' match, which allows you to match the
+  connection mark value previously set for the session by `CONNMARK'. 
+
 FTP protocol support
 CONFIG_IP_NF_FTP
   Tracking FTP connections is problematic: special helpers are
@@ -2858,6 +2923,14 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+Connection tracking events
+CONFIG_IP_NF_CONNTRACK_EVENTS
+  If this option is enabled, the connection tracking code will
+  provide a notifier chain that can be used by other kernel code
+  to get notified about changes in the connection tracking state.
+
+  If unsure, say `N'.
+
 IP tables support (required for filtering/masq/NAT)
 CONFIG_IP_NF_IPTABLES
   iptables is a general, extensible packet identification framework.
@@ -2971,6 +3044,28 @@
 
  
 
+iprange match support
+CONFIG_IP_NF_MATCH_IPRANGE
+  This option makes possible to match IP addresses against
+  IP address ranges.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
+
+TIME patch support
+CONFIG_IP_NF_MATCH_TIME
+  This option adds a `time' match, which allows you
+  to matchbased on the packet arrival time
+  (arrival time at the machine which the netfilter is running on) or
+  departure time (for locally generated packets).
+
+  If you say Y here, try iptables -m time --help for more information.
+ 
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+
 TOS match support
 CONFIG_IP_NF_MATCH_TOS
   TOS matching allows you to match packets based on the Type Of
@@ -3000,6 +3095,14 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+String match support (EXPERIMENTAL)
+CONFIG_IP_NF_MATCH_STRING
+  String matching alows you to match packets which contain a
+  specified string of characters.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
 Unclean match support
 CONFIG_IP_NF_MATCH_UNCLEAN
   Unclean packet matching matches any strange or invalid packets, by
@@ -3076,6 +3179,17 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+NETMAP target support
+CONFIG_IP_NF_TARGET_NETMAP
+  NETMAP is an implementation of static 1:1 NAT mapping of network
+  addresses. It maps the network address part, while keeping the
+  host address part intact. It is similar to Fast NAT, except that
+  Netfilter's connection tracking doesn't work well with Fast NAT.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  The module will be called
+  ipt_NETMAP.o.  If unsure, say `N'.
+
 REDIRECT target support
 CONFIG_IP_NF_TARGET_REDIRECT
   REDIRECT is a special case of NAT: all incoming connections are
@@ -3134,6 +3248,22 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+IMQ target support
+CONFIG_IP_NF_TARGET_IMQ
+  This option adds a `IMQ' target which is used to specify if and
+  to which imq device packets should get enqueued/dequeued.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
+IMQ target support
+CONFIG_IP6_NF_TARGET_IMQ
+  This option adds a `IMQ' target which is used to specify if and
+  to which imq device packets should get enqueued/dequeued.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
 MARK target support
 CONFIG_IP_NF_TARGET_MARK
   This option adds a `MARK' target, which allows you to create rules
@@ -3209,6 +3339,14 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+CONNLOG target support
+CONFIG_IP_NF_TARGET_CONNLOG
+  This option adds a `CONNLOG' target, which allows one to request
+  logging of the creation and destruction of a connnection tracking entry.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
 ipchains (2.2-style) support
 CONFIG_IP_NF_COMPAT_IPCHAINS
   This option places ipchains (with masquerading and redirection
@@ -3231,6 +3369,20 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+Increase default conntrack table size
+CONFIG_IP_NF_BIG_CONNTRACK
+  Increase default hash table and conntrack table size for dedicated
+  routers.  Allows all of memory to be used; since that's just as bad
+  as having a full conntrack table.
+
+IPv6 Extension Headers Match (EXPERIMENTAL)
+CONFIG_IP6_NF_MATCH_IPV6HEADER
+  extension header matching allows you to controll the packets based
+  on their extension headers.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
 EUI64 address check (EXPERIMENTAL)
 CONFIG_IP6_NF_MATCH_EUI64
   This module performs checking on the IPv6 source address
@@ -3240,6 +3392,42 @@
   If you want to compile it as a module, say M here and read
   Documentation/modules.txt.  If unsure, say `N'.
 
+AH/ESP match support (EXPERIMENTAL)
+CONFIG_IP6_NF_MATCH_AHESP
+  These two match extensions (`ah' and `esp') allow you to match a
+  range of SPIs inside AH or ESP headers of IPv6 packets.
+ 
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+
+Fragmentation header match support (EXPERIMENTAL)
+CONFIG_IP6_NF_MATCH_FRAG
+  This match extension (`frag') allow you to select the packet based on the
+  fileds of the fragmentation header of the IPv6 packets.
+ 
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+
+Fragmentation header match support (EXPERIMENTAL)
+CONFIG_IP6_NF_MATCH_OPTS
+  These match extensions (`hbh' and `dst') allow you to select the packet 
+  based on the fileds of the option header of the IPv6 packets.
+ 
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+
+Fragmentation header match support (EXPERIMENTAL)
+CONFIG_IP6_NF_MATCH_RT
+  This match extension (`rt') allow you to select the packet based on the
+  fileds of the routing header of the IPv6 packets.
+ 
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+
 MAC address match support
 CONFIG_IP6_NF_MATCH_MAC
   mac matching allows you to match packets based on the source
@@ -3265,6 +3453,14 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+length match support
+CONFIG_IP6_NF_MATCH_LENGTH
+  This option allows you to match the length of a packet against a
+  specific value or range of values.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
 Multiple port match support
 CONFIG_IP6_NF_MATCH_MULTIPORT
   Multiport matching allows you to match TCP or UDP packets based on
@@ -3308,6 +3504,16 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+REJECT target support
+CONFIG_IP6_NF_TARGET_REJECT
+  The REJECT target allows a filtering rule to specify that an ICMPv6
+  error should be issued in response to an incoming packet, rather
+  than silently being dropped.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+ULOG target support
 Packet mangling
 CONFIG_IP6_NF_MANGLE
   This option adds a `mangle' table to iptables: see the man page for
@@ -6127,6 +6333,11 @@
   can be gotten from the document
   <http://www.csn.tu-chemnitz.de/~mha/linux-ip-nat/diplom/nat.html>.
 
+Increase default route cache size
+CONFIG_IP_ROUTE_BIG_RT_CACHE
+  Increase default maximum route cache size for dedicated routers.
+  Uses mem>>11 as the goal for rt_max_size rather than mem>>14.
+
 Kernel level IP autoconfiguration
 CONFIG_IP_PNP
   This enables automatic configuration of IP addresses of devices and
@@ -6176,6 +6387,15 @@
   operating on your network. Read <file:Documentation/nfsroot.txt> for
   details.
 
+ARP Limiting
+CONFIG_NET_ARP_LIMIT
+  Limits the maximum number of active MAC addresses in the kernel ARP
+  cache.
+  This is to restrict the number of clients that can use the computer
+  as a gateway.  This solution is not entirely exact, as it will still
+  respond to different ARP requests in different circumstances, but
+  will only reliably talk to the specified maximum number
+
 IP tunneling
 CONFIG_NET_IPIP
   Tunneling means encapsulating data of one protocol type within
@@ -6197,6 +6417,12 @@
   <file:Documentation/modules.txt>. The module will be called
   ipip.o
 
+IPv6 over IPv4 tunneling support (replaces sitXX devices)
+CONFIG_NET_IPIP_IPV6
+  If you say Y here, you can transport IPv6 packet over the tunlXX 
+  devices;  The sitXX devices will be dissappeared with this option.
+  Note: tunnel manipulation commands such as iptunnel should be updated.
+
 GRE tunnels over IP
 CONFIG_NET_IPGRE
   Tunneling means encapsulating data of one protocol type within
@@ -6251,6 +6477,12 @@
   gated-5). This routing protocol is not used widely, so say N unless
   you want to play with it.
 
+Restrict SO_REUSEADDR only for same user
+CONFIG_NET_RESTRICTED_REUSE
+  With this option, kernel restrict effect of SO_REUSEADDR to prevent 
+  other users from performing 'binding closer' type attacks like NFS 
+  theft.  Say Y.
+
 Unix domain sockets
 CONFIG_UNIX
   If you say Y here, you will include support for Unix domain sockets;
@@ -6294,7 +6526,165 @@
   want). The module will be called ipv6.o. If you want to compile it
   as a module, say M here and read <file:Documentation/modules.txt>.
 
-  It is safe to say N here for now.
+  Say Y. :-)
+
+IPv6: Verbose debugging messages
+CONFIG_IPV6_DEBUG
+  Verbose kernel message for debugging IPv6 stack.
+  If unsure, it is safe to say N.
+
+IPv6: inter-module support.
+CONFIG_IPV6_IM
+  Export some interface via the inter-module feature.
+  This is needed if you want to use generic tunnel (CONFIG_NET_IPGRE)
+  with modulized ipv6.  Say Y in such case, otherwise say N.
+
+IPv6: enable gre tunnel support with modulized ipv6
+CONFIG_IPV6_MODULE_IP_GRE
+  Use generic tunnel support with modulized ipv6 via
+  inter-module interface.
+ 
+IPv6: drop packets with fake ipv4-mapped address(es)
+CONFIG_IPV6_DROP_FAKE_V4MAPPED
+  Drop incoming packets with fake ipv4-mapped address(es) that
+  may cause security problems.  It is safe and recommended to 
+  say Y.
+
+IPv6: Anycast support
+  Anycast support for IPv6.  If unsure, say N.
+
+IPv6: 6to4 Address in NextHop Support
+CONFIG_IPV6_6TO4_NEXTHOP
+   It is a transition mechanism which is defined by RFC2529.
+   It configures dynamic IPv6 over IPv4 tunnel according to 6to4
+   addresses which are registerd in DNS. If you want to use 6to4
+   protocol, Say Y. If unsure, Say N.
+
+IPv6: Privacy Extensions (RFC 3041) support
+CONFIG_IPV6_PRIVACY
+  Privacy Extensions for Stateless Address Autoconfiguration in IPv6
+  support.  With this option, additional periodically-alter 
+  pseudo-random global-scope unicast address(es) will assigned to
+  your interface(s).
+
+  By default, kernel generates temporary addresses but it won't use 
+  them unless application explicitly bind them.  To prefer temporary 
+  address, do
+
+    echo 2 >/proc/sys/net/ipv6/conf/all/use_tempaddr 
+
+  This option depends on Cryptograpghic API (CONFIG_CRYPTO) and MD5 
+  message digest algorithm (CONFIG_CRYPTO_MD5).
+
+IPv6: Anycast Address support (EXPERIMENTAL)
+CONFIG_IPV6_ANYCAST
+  Supporting anycast address in kernel. Say N.
+
+IPv6: Loose scope_id
+CONFIG_IPV6_LOOSE_SCOPE_ID
+  It is recommended to say N.
+  NOTE: This option is disabled by default.
+
+IPv6: Restrict "double binding" only for same user
+CONFIG_IPV6_RESTRICTED_DOUBLE_BIND
+  With this option, kernel doesn't allow bind the same port 
+  number of socket which already binded by other user with
+  other protocol.  For example, If user A binds #8000 port with
+  IPv6 protocol kernel doesn't allow to bind #8000 port with IPv4
+  protocol other than user A. For security reason, we recommend
+  say Y.
+
+  If you say Y here, note that "double binding" restriction is not
+  enabled by default; you can enable this by setting net.ipv6.conf.all.
+  binv6only_restriction to 1.
+
+  If you want to compile IPv6 as a module, you also need to say Y
+  to "inter-module support" to enable this option.
+
+IPv6: IPv6 over IPv6 Tunneling (EXPERIMENTAL)
+CONFIG_IPV6_IPV6_TUNNEL
+  Experimental IP6-IP6 tunneling.
+
+  If you don't want IP6-IP6 tunnels, say N.
+
+IPv6: Prefix List support
+CONFIG_IPV6_PREFIXLIST
+  Added Prefix List described as a conceptual data structure in RFC2461.
+  Say N at this moment.
+
+IPv6: Neighbor Discovery debugging
+CONFIG_IPV6_NDISC_DEBUG
+  Verbose kernel message to debug Neighbor Discovery Protocol for 
+  IPv6.  Say N.
+
+IPv6: Stateless Address Autoconfiguration debugging
+CONFIG_IPV6_ACONF_DEBUG
+  Verbose kernel message to debug the IPv6 Stateless Address 
+  Autoconfiguration.  Say N.
+
+IPv6: IPv6: Debug on source address selection
+CONFIG_IPV6_ACONF_DEBUG_SADDR
+  Verbose kernel messages for debugging IPv6 Source Address Selection
+  Algorithm. Say N.
+
+IPv6: ignore too small Valid Lifetime for Address Autoconfiguration
+CONFIG_IPV6_ACONF_MIN_VALID_LFT
+  Do not update valid-lifetime with small value to avoid particular 
+  DoS attack.  See RFC 2461 section 6.3.6 and RFC 2462 section 5.5.3.
+  Say Y.
+
+IPv6: Routing Information debugging
+CONFIG_IPV6_RT6_DEBUG
+  Verbose kernel messages for debugging IPv6 routing.  Say N.
+
+IPv6: sub-tree in routing table support (just for testing)
+CONFIG_IPV6_SUBTREES
+  Sub-tree in IPv6 routing table to have routes by source
+  address.  This is just for testing.  Say N.
+
+IPv6: Default Router Preference support
+CONFIG_IPV6_ROUTER_PREF
+  Default Router Preferences support.
+  See <draft-ietf-ipv6-router-selection-02.txt> for details.
+
+IPv6: Route Information Option support
+CONFIG_IPV6_ROUTE_INFO
+  Route Information Option is RA message support.
+  If unsure, say N.
+
+IPv6: Multicast Listener Discovery debugging
+CONFIG_IPV6_MLD6_DEBUG
+  Verbose kernel message to debug Multicast Listeners
+  Discovery for IPv6.  Say N.
+
+IPv6: Disable optimization of MLD6 Done message
+CONFIG_IPV6_MLD6_ALL_DONE
+  When a node ceases to listen to a multicast address on an
+  interface, it should send a single Done message.  If its recent
+  Report was suppressed by hearing another Report, it MAY send 
+  nothing.  You can turn off this optimization by 
+  CONFIG_IPV6_MLD6_ALL_DONE.  See RFC 2710.
+  Say N.  
+
+IPv6: enable Node Information Queries
+CONFIG_IPV6_NODEINFO
+  Support ICMPv6 Node Information Queries defined in 
+  draft-ietf-ipngwg-icmp-name-lookups-07.txt.
+
+  This option depends on Cryptograpghic API (CONFIG_CRYPTO) and MD5 
+  message digest algorithm (CONFIG_CRYPTO_MD5).
+
+IPv6: regard NIS domain as DNS domain
+CONFIG_IPV6_NODEINFO_USE_UTS_DOMAIN
+  When the NI DNS Query requests FQDN of your Linux box, it will 
+  try to add the (NIS) domain to your hostname.  Generally, this is 
+  not a good idea, so say N; your box will reply as FQDN if its
+  hostname includes two or more dots, otherwise it will reply
+  as hostname.
+
+IPv6: ICMPv6 NI debug message (very verbose)
+CONFIG_IPV6_NODEINFO_DEBUG
+  Very verbose debug message.  Say N.
 
 The SCTP Protocol (EXPERIMENTAL)
 CONFIG_IP_SCTP
@@ -6382,6 +6772,10 @@
   The kHTTPd is experimental. Be careful when using it on a production
   machine. Also note that kHTTPd doesn't support virtual servers yet.
 
+Use IPv6 socket for khttpd
+CONFIG_KHTTPD_IPV6
+  Use IPv6 socket for khttpd module.
+
 The IPX protocol
 CONFIG_IPX
   This is support for the Novell networking protocol, IPX, commonly
@@ -7182,6 +7576,11 @@
   briefly removed during revalidation. If you say Y here, packets to
   such neighbours are silently discarded instead.
 
+IPv6 Enhance for ATM (EXPERIMENTAL)
+CONFIG_ATM_IPV6
+  IPv6 support on a PVC link. To install and for usage, please refer
+  usagi/doc/HOWTO/ATM. If unsure, say N.
+
 RFC1483/2684 Bridged protocols
 CONFIG_ATM_BR2684
   ATM PVCs can carry ethernet PDUs according to rfc2684 (formerly 1483)
@@ -7625,6 +8024,59 @@
   the performances of the driver, and the size of your syslog files!
   Keep the debugging level to 0 during normal operations.
 
+IP Security Protocol (IPSEC) (EXPERIMENTAL)
+CONFIG_IPSEC
+  This unit is experimental code.
+  Pick 'y' for static linking, 'm' for module support or 'n' for none.
+  This option adds support for network layer packet encryption and/or
+  authentication with participating hosts.  The standards start with:
+  RFCs 2411, 2407 and 2401.  Others are mentioned where they refer to
+  specific features below.  There are more pending which can be found
+  at:  ftp://ftp.ietf.org/internet-drafts/draft-ietf-ipsec-*.
+  A description of each document can also be found at: 
+  http://ietf.org/ids.by.wg/ipsec.html.
+  Their charter can be found at: 
+  http://www.ietf.org/html.charters/ipsec-charter.html
+  Snapshots and releases of the current work can be found at: 
+  http://www.freeswan.org/
+
+IPSEC: IP-in-IP encapsulation
+CONFIG_IPSEC_IPIP
+  This option provides support for tunnel mode IPSEC.  It is recommended
+  to enable this.
+
+IPSEC: Authentication Header
+CONFIG_IPSEC_AH
+  This option provides support for the IPSEC Authentication Header
+  (IP protocol 51) which provides packet layer sender and content
+  authentication.  It is recommended to enable this.  RFC2402
+
+HMAC-MD5 algorithm
+CONFIG_IPSEC_AUTH_HMAC_MD5
+  Provides support for authentication using the HMAC MD5
+  algorithm with 96 bits of hash used as the authenticator.  RFC2403
+
+HMAC-SHA1 algorithm
+CONFIG_IPSEC_AUTH_HMAC_SHA1
+  Provides support for Authentication Header using the HMAC SHA1
+  algorithm with 96 bits of hash used as the authenticator.  RFC2404
+
+IPSEC: Encapsulating Security Payload
+CONFIG_IPSEC_ESP
+  This option provides support for the IPSEC Encapsulation Security
+  Payload (IP protocol 50) which provides packet layer content
+  hiding.  It is recommended to enable this.  RFC2406
+
+3DES algorithm
+CONFIG_IPSEC_ENC_3DES
+  Provides support for Encapsulation Security Payload protocol, using
+  the triple DES encryption algorithm.  RFC2451
+
+IPSEC Debugging Option
+CONFIG_IPSEC_DEBUG
+  Enables IPSEC kernel debugging.  It is further controlled by the
+  user space utility 'klipsdebug'.
+
 ForeRunner HE Series
 CONFIG_ATM_HE
   This is a driver for the Marconi ForeRunner HE-series ATM adapter
@@ -9798,6 +10250,20 @@
   say M here and read <file:Documentation/modules.txt>.  The module
   will be called bonding.o.
 
+Intermediate queueing device support
+CONFIG_IMQ
+  The imq device(s) is used as placeholder for QoS queueing disciplines.
+  Every packet entering/leaving the ip stack can be directed through
+  the imq device where it's enqueued/dequeued to the attached qdisc.
+  This allows you to treat network devices as classes and distribute
+  bandwidth among them. Iptables is used to specify through which imq
+  device, if any, packets travel.
+
+  If you want to compile this as a module ( = code which ca be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called imq.o
+
 SLIP (serial line) support
 CONFIG_SLIP
   Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to
@@ -11920,6 +12386,22 @@
   say M here and read Documentation/modules.txt. This is recommended.
   The module will be called 8139cp.o.
 
+Support for external PHY's on RTL-8139C+.
+CONFIG_8139CP_EXTERNAL_PHY
+  If you want to have access to external PHY's, then enable this.  Unless
+  you also change CONFIG_8139CP_PHY_NUM, then you will continue using the
+  internal PHY.
+
+  It is unlikely you want to change this.
+
+Which PHY should the RTL-8139C+ MAC use.
+CONFIG_8139CP_PHY_NUM
+  If you have the MAC hooked up to some external PHY's then you might want
+  to use one besides the internal one.  The internal PHY is 32.
+
+  If you don't know what you are doing, it is unlikely you want to change
+  this.
+
 RealTek RTL-8139 PCI Fast Ethernet Adapter support
 CONFIG_8139TOO
   This is a driver for the Fast Ethernet PCI network cards based on
@@ -12070,6 +12552,8 @@
   by this driver:
 	    - 3Com 3C940 Gigabit LOM Ethernet Adapter
 	    - 3Com 3C941 Gigabit LOM Ethernet Adapter
+	    - Abocom EFE3K - 10/100 Ethernet Expresscard
+	    - Abocom EGE5K - Giga Ethernet Expresscard
 	    - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter
 	    - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter
 	    - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter
@@ -12078,30 +12562,72 @@
 	    - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter
 	    - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter
 	    - Allied Telesyn AT-2971T Gigabit Ethernet Adapter
+	    - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45
 	    - DGE-530T Gigabit Ethernet Adapter
 	    - EG1032 v2 Instant Gigabit Network Adapter
 	    - EG1064 v2 Instant Gigabit Network Adapter
-	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit)
-	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron)
-	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus)
-	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS)
-	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox)
-	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn)
-	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
-	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
+	    - Marvell 88E8001 Gigabit Ethernet Controller (Abit)
+	    - Marvell 88E8001 Gigabit Ethernet Controller (Albatron)
+	    - Marvell 88E8001 Gigabit Ethernet Controller (Asus)
+	    - Marvell 88E8001 Gigabit Ethernet Controller (Chaintech)
+	    - Marvell 88E8001 Gigabit Ethernet Controller (ECS)
+	    - Marvell 88E8001 Gigabit Ethernet Controller (Epox)
+	    - Marvell 88E8001 Gigabit Ethernet Controller (Foxconn)
+	    - Marvell 88E8001 Gigabit Ethernet Controller (Gigabyte)
+	    - Marvell 88E8001 Gigabit Ethernet Controller (Iwill)
+	    - Marvell 88E8035 Fast Ethernet Controller (LGE)
+	    - Marvell 88E8035 Fast Ethernet Controller (Toshiba)
+	    - Marvell 88E8036 Fast Ethernet Controller (Arima)
+	    - Marvell 88E8036 Fast Ethernet Controller (Compal)
+	    - Marvell 88E8036 Fast Ethernet Controller (Inventec)
+	    - Marvell 88E8036 Fast Ethernet Controller (LGE)
+	    - Marvell 88E8036 Fast Ethernet Controller (Toshiba)
+	    - Marvell 88E8036 Fast Ethernet Controller (Wistron)
+	    - Marvell 88E8050 Gigabit Ethernet Controller (Intel)
+	    - Marvell 88E8052 Gigabit Ethernet Controller (ASRock)
+	    - Marvell 88E8052 Gigabit Ethernet Controller (Aopen)
+	    - Marvell 88E8052 Gigabit Ethernet Controller (Asus)
+	    - Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte)
+	    - Marvell 88E8052 Gigabit Ethernet Controller (MSI)
+	    - Marvell 88E8052 Gigabit Ethernet Controller (Wistron)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (ASRock)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (Albatron)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (Aopen)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (Arima)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (Asus)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (Chaintech)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (Clevo)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (Compal)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (DFI)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (Epox)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (Inventec)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (MSI)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (Quanta)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (SOYO)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (Toshiba)
+	    - Marvell 88E8053 Gigabit Ethernet Controller (Trigem)
+	    - Marvell RDK-8001 
 	    - Marvell RDK-8001 Adapter
 	    - Marvell RDK-8002 Adapter
+	    - Marvell RDK-8003 
 	    - Marvell RDK-8003 Adapter
 	    - Marvell RDK-8004 Adapter
 	    - Marvell RDK-8006 Adapter
 	    - Marvell RDK-8007 Adapter
 	    - Marvell RDK-8008 Adapter
 	    - Marvell RDK-8009 Adapter
-	    - Marvell RDK-8010 Adapter
+	    - Marvell RDK-8010 
 	    - Marvell RDK-8011 Adapter
 	    - Marvell RDK-8012 Adapter
-	    - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit)
-	    - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit)
+	    - Marvell RDK-8035 
+	    - Marvell RDK-8036 
+	    - Marvell RDK-8052 
+	    - Marvell RDK-8053 
+	    - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (32 bit)
+	    - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (64 bit)
 	    - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
 	    - SK-9521 10/100/1000Base-T Adapter
 	    - SK-9521 V2.0 10/100/1000Base-T Adapter
@@ -12137,6 +12663,9 @@
   say M here and read Documentation/modules.txt. This is recommended.
   The module will be called sk98lin.o.
 
+CONFIG_SK98LIN_NAPI
+  NAPI is a new driver API designed to reduce CPU and interrupt load
+  when the driver is receiving lots of packets from the card.
 
 Sun GEM support
 CONFIG_SUNGEM
@@ -14144,6 +14673,14 @@
   <linux-mtd@lists.infradead.org> if you want to help to make it more
   reliable.
 
+INFTL (Inverse Flash Translation Layer) support
+CONFIG_INFTL
+  This provides support for the Inverse NAND Flash Translation Layer which
+  is used on M-Systems' DiskOnChip devices (in particular the newer
+  Millennium Plus parts). It uses a kind of pseudo filesystem on a flash
+  device to emulate a block device with 512-byte sectors, on top of which
+  you put a 'normal' file system.
+ 
 Detect flash chips by Common Flash Interface (CFI) probe
 CONFIG_MTD_CFI
   The Common Flash Interface specification was developed by Intel,
@@ -14637,6 +15174,16 @@
   <file:Documentation/modules.txt>. The module will be called
   doc2001.o
 
+Millennium Plus support
+CONFIG_MTD_DOC2001PLUS
+  This is a driver for the M-Systems DiskOnChip Millennium Plus
+  devices.
+  
+  If you use this device, you probably also want to enable the NFTL
+  'NAND Flash Translation Layer' option below, which is used to
+  emulate a block device by using a kind of file system on the flash
+  chips.
+
 Probe for DiskOnChip devices
 CONFIG_MTD_DOCPROBE
   This isn't a real config option, it's derived.
@@ -19365,6 +19912,27 @@
   <file:Documentation/modules.txt>.
   The module will be called i2c-velleman.o.
 
+Motorla Coldfire GPIO adapter
+CONFIG_I2C_MCF_GPIO
+  This driver supports using a pair of GPIO pins on the Motorola 
+  Coldfire series of microcontrollers as an I2C adapter.  Say Y if 
+  you have need for an I2C interface on such a processor.  You will 
+  be further prompted to select which GPIO pins will be used for 
+  I2C data (SDA) and I2C clock (SCL).
+  
+  Currently, this driver supports the MCF5204, MCF5206, MCF5206e, 
+  MCF5249, MCF5272, MCF5307, and MCF5407 processors.  The MCF5282 
+  is not currently supported.
+
+  This driver has only undergone basic testing on MCF5272 hardware.  
+  Please be aware that issues may be present when attempting to use 
+  this driver with untested processors.
+  
+  This support is also available as a module.  If you want to compile
+  it as a module, say M here and read
+  <file:Documentation/modules.txt>.
+  The module will be called i2c-adap-mcf_gpio.o.
+  
 I2C PCF 8584 interfaces
 CONFIG_I2C_ALGOPCF
   This allows you to use a range of I2C adapters called PCF adapters.
@@ -20448,6 +21016,24 @@
   get killed. If you say Y here, the watchdog cannot be stopped once
   it has been started.
 
+SnapGear Watchdog Driver
+CONFIG_SNAPDOG
+  If you have a SnapGear device that is not coldfire based,  there is a good
+  chance you will need this driver to boot.  It is harmless on devices it
+  does not support (unless you have another watchdog configured that is).
+  
+Triscend A7 Watchdog timer
+CONFIG_TA7_WDT
+  If you would like to add support for the Triscend A7 watchdog
+  device, say Y here, otherwise N. The watchdog device remains
+  disabled until the first time data is written to it. The watchdog
+  can be pinged, stopped, started, or have its timeout value changed
+  using ioctl calls. The watchdog timeout specified should be in
+  clock cycles. Reading from the watchdog device returns 4 bytes
+  containing the watchdogs current value. Writing to the watchdog
+  device is the equivalent of pinging it. If the watchdog is not
+  pinged within the timeout period, the A7 is reset.
+
 WDT Watchdog timer
 CONFIG_WDT
   If you have a WDT500P or WDT501P watchdog board, say Y here,
@@ -22274,6 +22860,16 @@
   hardware debugging with a logic analyzer and need to see all traffic
   on the bus.
 
+AU1000 serial console
+CONFIG_AU1000_SERIAL_CONSOLE
+  If you have an Alchemy AU1000 processor (MIPS based) and you want
+  to use a console on a serial port, say Y.  Otherwise, say N.
+
+AU1000 serial support
+CONFIG_AU1000_UART
+  If you have an Alchemy AU1000 processor (MIPS based) and you want
+  to use serial ports, say Y.  Otherwise, say N.
+
 AU1000 ethernet controller on SGI MIPS system
 CONFIG_MIPS_AU1000_ENET
   If you have an Alchemy Semi AU1000 ethernet controller
@@ -25931,6 +26527,12 @@
   Say Y if you want support for the ARM920T processor.
   Otherwise, say N.
 
+Support EP93xx MaverickCrunch
+CONFIG_EP93XX_CRUNCH
+  This option allows you to run MaverickCrunch(tm) powered Linux applications
+  on EP93xx based platforms.  Saying 'Y' here is harmless and will not slow
+  down performance.
+  
 Support ARM1020 processor
 CONFIG_CPU_ARM1020
   The ARM1020 is the cached version of the ARM10 processor,
@@ -25989,6 +26591,57 @@
   Say Y if you want support for the SA-110 processor.
   Otherwise, say N.
 
+NET+ARM Processor type
+CONFIG_NETARM_NET15
+  The NET+ARM(tm) processor family by NETsilicon(R) is an
+  implementation of the ARM7TDMI architecture, with some integrated
+  peripherals for serial, parallel and ethernet interfaces. These
+  chips differ in cache, speed and other capabilities.
+  Please select your processor type.
+
+NET+ARM NET+40 board Rev2
+CONFIG_NETARM_NET40_REV2
+  This refers to the NET+40 board revision, not processor version.
+  The board can have different DRAM configurations, Rev. 2 uses one
+  bank of SDRAM.
+  If unsure, say N.
+
+NET+ARM NET+40 board Rev4
+CONFIG_NETARM_NET40_REV4
+  This refers to the NET+40 board revision, not processor version.
+  The board can have different DRAM configurations, Rev. 4 uses two
+  banks of FastPage or EDO DRAM.
+  If unsure, say Y.
+
+NET+ARM PLL Bypass Patch
+CONFIG_NETARM_PLL_BYPASS
+  Say Y here if your NetARM is set to PLL bypass mode, i.e. the
+  PLLTST* input is driven low and the system clock is provided
+  by an external TTL oscillator.
+  This was necessary for some early revisions of the Net+40 chip,
+  where the internal PLL did not work properly. It is also used
+  on the NETsilicon NET+40 development board (at least on the
+  one I know).
+  If unsure, say N.
+
+NET+ARM EMLIN Board
+CONFIG_NETARM_EMLIN
+  The EMLIN is an in-house prototype of a NetARM board with
+  additional peripherals and slightly different memory layout.
+  Say Y here if you are using one. If unsure, say N.
+
+System uses an external crystal oscillator
+CONFIG_USE_OSC
+  If the system clock is derived from an external crystal oscillator,
+  say Y here, otherwise N. If you say Y here, you will be required to
+  specify the frequency of the oscillator in Hz.
+
+Set flash/sdram size and base addr
+CONFIG_SET_MEM_PARAM
+  If you want to use a memory configuration that differs from
+  the default values, say Y here and enter the parameters in
+  the next 4 fields. If unsure, say N.
+
 Tulsa
 CONFIG_SA1100_PFS168
   The Radisys Corp. PFS-168 (aka Tulsa) is an Intel® StrongArm® SA-1110 based
@@ -26174,6 +26827,10 @@
   time by entering them here. As a minimum, you should specify the
   memory size and the root device (e.g., mem=64M root=/dev/nfs).
 
+CONFIG_CMDLINE_FORCE
+  Set this to have arguments from the default kernel command string
+  override those passed by the boot loader.
+
 Kernel-mode alignment trap handler
 CONFIG_ALIGNMENT_TRAP
   ARM processors can not fetch/store information which is not
@@ -26184,6 +26841,24 @@
   correct operation of some network protocols. With an IP-only
   configuration it is safe to say N, otherwise say Y.
 
+Attached romfs in RAM
+CONFIG_RAM_ATTACHED_ROMFS
+  Attempts to properly handle an attached romfs by moving it from the
+  start of the bss region to the end of the bss and then reserving it
+  with the rest of kernel memory. This allows it to be used with the
+  Generic uClinux RAM/ROM filesystem support MTD driver selectable via
+  CONFIG_MTD_UCLINUX. This requires support in the entry code in order
+  to work right. 
+  
+  Only implemented for NetARM thus far.
+
+RAM Kernel self loades from ROM
+CONFIG_RELOCATE
+  The kernel runs from RAM,  but is started from ROM.  It copies itself
+  to it's final destination and then starts running from RAM.
+
+  This allows a RAM kernel to be booted from flash on a uCdimm for example.
+  
 DC21285 serial port support
 CONFIG_SERIAL_21285
   If you have a machine based on a 21285 (Footbridge) StrongARM(R)/
@@ -27732,6 +28407,64 @@
   To use this option, you have to check that the "/proc file system
   support" (CONFIG_PROC_FS) is enabled, too.
 
+C5471 serial port support
+CONFIG_SERIAL_C5471
+  If you are using a C5471, and want to use /dev/ttyS*, then say Y here.
+  Also, turn off CONFIG_SERIAL. The C5471 does not employ a 16550
+  compatible UART, so the standard Linux serial driver won't work.
+
+C5471 watchdog support
+CONFIG_C5471_WDT
+  If you want watchdog functionality (see CONFIG_WATCHDOG) and you
+  have a C5471 EVM, say Y here, otherwise N.  This will build in
+  watchdog functionality using a C5471 timer.
+
+C5471 general purpose I/O Support
+CONFIG_C5471_GIO
+  If you want support for user-space access to the C5471 general
+  purpose I/O (GIO) pins, say Y here, otherwise N.
+  This will build in the GIO device driver (for /dev/gio[n])
+
+DSC21 serial port support
+CONFIG_SERIAL_DSC21
+  If you are using a DSC21, and want to use /dev/ttyS*, then say Y here.
+  Also, turn off CONFIG_SERIAL. The dsc21 does not employ a 16550
+  compatible UART, so the standard Linux serial driver won't work.
+
+DSC21 serial console support
+CONFIG_SERIAL_DSC21_CONSOLE
+  If you want to have a printk/login console over the DSC21's serial
+  port then say Y here. Note that if you do this, you won't be able
+  to use that port for anything else.
+
+Disable BDM signals
+CONFIG_BDM_DISABLE
+  This option turns off the ColdFire debug module early in the boot process.
+  This helps to reduce the electromagnetic emmissions from the BDM header.
+  Since this is a software disable, it can be prevented via the BDM.
+
+Alternative kernel page allocator
+CONFIG_CONTIGUOUS_PAGE_ALLOC
+  On systems with very little memory,  a power of 2 allocator can
+  rapidly reduce the amount of free memory leaving a lot of that allocated
+  memory unused.  Say you nneed to allocate 34K,  you would actually
+  allocate 64K and waste 28K doing so.  This allocator allocates on 4K
+  boundaries reducing this wastage significantly.  It is perhaps a little
+  slower and can suffer a little more from fragmentation, although in
+  practice it is still better than uses a power of two.  Contact
+  davidm@snapgear.com with any problems usesing this allocator.
+
+Look at memory allocation
+CONFIG_MEM_MAP
+  Provides and entry "/proc/mem_map" that gives you an ascii representation
+  of the page allocations in the kernel,  and what they are being used for.
+
+Reduce kernel task size
+CONFIG_SMALL_TASKS
+  By default,  8K is used for a task in the m68k kernel.  This option
+  reduces it to 4K,  of which approximately 3.2K is kernel stack.  Be
+  warned,  this substantially reduces the kernel stack.
+
 PPC4xx DMA controller support
 CONFIG_PPC4xx_DMA
   Select this to enable support for the PPC4xx general purpose DMA
@@ -28554,6 +29287,15 @@
 
   If unsure, say N.
 
+Printk debugging info on coredump
+CONFIG_COREDUMP_PRINTK
+  When a user process coredumps then we printk a whole lot of information.
+  This is v. useful for debugging.
+
+  If you select this option and the build complains about not being able to
+  find user_stack, then you need to define it in you
+  include/arch/asm-arch/ptrace.h file.
+
 Hotplug firmware loading support (EXPERIMENTAL)
 CONFIG_FW_LOADER
   This option is provided for the case where no in-kernel-tree modules require
diff -urN linux-2.4.29/Documentation/intlat.txt linux-2.4.29-uc1/Documentation/intlat.txt
--- linux-2.4.29/Documentation/intlat.txt	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/Documentation/intlat.txt	2005-06-14 02:10:56.000000000 +0100
@@ -0,0 +1,114 @@
+Documentation/intlat.txt
+http://www.uow.edu.au/~andrewm/linux/
+
+Andrew Morton <andrewm@uow.edu.au>
+25 March 2000
+
+NOTE-NOTE-NOTE
+==============
+
+The intlat patch alters include/linux/threads.h! It changes NR_CPUS
+from 32 to 2.  If you have more than two CPUs then you should change
+this appropriately.
+
+This is because intlat generates a _lot_ of storage for its data
+structures - about 6,000 structures whose size is O(NR_CPUS *
+N_TIMEPEG_ARCS).  THis can create a kernel which has a sixty megabyte
+footprint! Setting NR_CPUS to 2 results in a ~4 MByte kernel.
+
+
+Installation and Usage
+======================
+
+1: Grab the timepeg+intlat patch and the 'tpt' tool from the above
+   URL.  Build tpt and install it somewhere.
+
+2: Apply the patch to your kernel.
+
+3: Run 'make menuconfig' or whatever.
+
+4: Enable timepegs under 'Kernel Hacking'
+
+5: Enable intlat under 'Kernel Hacking'
+
+5: make clean && make dep && make bzImage && make modules
+
+Now run your kernel, and once it has booted run 'tpt'.  This will dump
+all the current timepegs and zero the timepeg accumulators.  You
+probably want to do this because the kernel boot process introduces
+once-off metrics which you aren't likely to be interested in.
+
+Now force the kernel to traverse the code paths which you are
+interested in (run some n/w traffic, force paging, etc).
+
+Now run
+
+	tpt -s | sort -nr +5
+
+to display the sorted list of interrupt blockages.
+
+
+Details
+=======
+
+intlat is a tool which allows you to measure the amount of time which
+the kernel spends with interrupts disabled.  intlat considers
+interrupts to be disabled in two circumstances:
+
+1: The processor's IF status register flag is cleared in
+   non-interrupt context and
+
+2: The processor is in interrupt context and has not set the IF
+   flag.
+
+The output is in timepeg format.  It displays the file-and-line at
+which interrupts were disabled and the file-and-line at which they were
+reenabled.  The min, max and average interrupts-off times are
+displayed, as is the number of times this path was traversed.  All
+times are in microseconds.
+
+Example:
+
+foo()
+{
+	local_irq_save();
+	...
+	local_irq_save();
+	...
+	local_irq_restore();
+	...
+	local_irq_restore();
+}
+
+In this case intlat will tell you the amount of time between the first
+local_irq_save() and the last local_irq_restore().
+
+Another example:
+
+interrupt_routine()
+{
+	...
+	__sti();
+	...
+	__cli();
+	...
+}
+
+In this case intlat will tell you:
+
+1: The amount of time between the interrupt being taken and the __sti() and 
+
+2: the amount of time between the __cli() and the return from interrupt.
+
+These two times represent periods when interrupts are blocked.
+
+Note that the figures here will be a little inaccurate (low) because
+the intlat library doesn't notice the start-of-interupt until we hit
+do_IRQ() and it assumes that the interrupt completes at the end of
+do_IRQ().  This probably makes 5-10 uSecs difference.
+
+Because it is based on timepegs, intlat accumulates statistics on a
+per-CPU basis.  The per-CPU data is aggregated by the offline 'tpt'
+tool.
+
+
diff -urN linux-2.4.29/Documentation/microblaze/AddingPlatforms.txt linux-2.4.29-uc1/Documentation/microblaze/AddingPlatforms.txt
--- linux-2.4.29/Documentation/microblaze/AddingPlatforms.txt	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/Documentation/microblaze/AddingPlatforms.txt	2005-06-14 02:10:56.000000000 +0100
@@ -0,0 +1,142 @@
+Adding new Microblaze platforms with the auto-configuration
+architecture.
+
+(c) 2005 John Williams <jwilliams@itee.uq.edu.au>
+
+
+Any new platforms added to Microblaze should use the
+auto-configuration architecture.  This is a mechanism whereby the EDK
+tools (specifically libgen) are used to output a configuration file -
+auto-config.in - that completely specifies all parameters of the
+target hardware.  By including this file into the uClinux kernel
+build, we avoid the tedious and error-prone task of setting these
+parameters manually. 
+
+There is already a generic auto-configured platform in the source tree
+- uclinux-auto.  Use this as a starting point to create your own.  The
+process is best described by example.  Here, we will add support for a
+hypothetical new platform, which we will call NewPlatform. 
+
+1. Create a vendors subdirectory for the new platform.  These live in
+   the uClinux-dist tree.  For example, a new Xilinx board directory
+   might be created under uClinux-dist/vendors/Xilinx/NewPlatform. 
+
+  $ cd uClinux-dist/vendors/Xilinx
+  $ cp -rf uclinux-auto NewPlatform
+
+2. Create a new kernel directory for the board.  Again, this is based
+   on the uclinux-auto platform: 
+
+  $ cd uClinux-dist/linux-2.4.x/arch/microblaze/platforms
+  $ cp -rf uclinux-auto NewPlatform
+
+3. Add your new platform to the list of supported platforms.  First,
+   edit the file "linux-2.4.x/arch/microblaze/Boards.mk".  Add your
+   new board like this: 
+
+ifdef CONFIG_NEWPLATFORM
+PLATFORM := NewPlatform
+endif
+
+A few points here - you must set the PLATFORM variable to exactly the
+same name as the directory you created under the
+arch/microblaze/platforms subdirectory.  The CONFIG_NEWPLATFORM is a
+kernel configuration variable that will be set, when your new platform
+is being targeted.  This variable name can be just about anything, but
+it makes sense to base it on the actual name of your platform - and
+always include the CONFIG_ prefix.  Remember this variable, we'll use
+it in the next step. 
+
+4. Add your new platform to the kernel configuration process.  Edit
+   the file linux-2.4.x/arch/microblaze/config.in.  Add your new
+   platform in the "Platforms" list.  It will look a bit like this: 
+
+  #### Microblaze processor-specific config
+
+comment 'Platform'
+  choice 'Platform'                                             \
+       "uclinux-auto            CONFIG_UCLINUX_AUTO             \
+	...
+        MBVanilla               CONFIG_MBVANILLA                \
+        Egretv0.1               CONFIG_EGRET01                  \
+        SUZAKU                  CONFIG_SUZAKU"          uclinux-auto
+
+Add a new line like this:
+
+        NewPlatform		CONFIG_NEWPLATFORM		\
+
+Don't forget that trailing backslash character, to continue the line.
+
+Then, just below, add a snippet like this:
+
+  if [ "$CONFIG_NEWPLATFORM" = "y" ]; then
+    define_int HZ 100
+    source arch/microblaze/platform/NewPlatform/auto-config.in
+  fi
+
+This will cause the auto-config.in file to be read from the new kernel
+platform directory. 
+
+5. You are now ready to build your new platform.  From the
+  uClinux-dist directory, launch the uClinux menu configuration tool: 
+
+  $ make menuconfig
+
+Enter the Vendor/Product menu, and select your new platform.
+Enter the Kernel/Library/Defaults selection, and choose "Customize
+Kernel Settings".
+
+Enter the "Processor Type and features" submenu, and select your new platform
+from the "Platforms" list.
+
+Exit the menu config, and save your new configuration.
+
+The build tools will clean out any existing kernel builds, then the
+kernel configuration menu will launch.  Before the menu launches, you
+may be prompted to provide values for any undefined kernel
+configuration parameters, just press enter to accept the
+default. e.g.: 
+
+netperf (CONFIG_USER_NETPERF_NETPERF) [N/y/?] (NEW) 
+
+Pressing enter will accept the default (No).
+
+Once the menu launches, go into the "Processor Type and Features"
+submenu.  Change the Platform setting to your new platform -
+"NewPlatform" in this case. 
+
+Exit the menus and save your changes.
+
+This is important - launch the menuconfig again, and again go into the
+  kernel configuration submenu: 
+
+  $ make menuconfig
+
+  (Kernel/Library/Defaults Selection)
+     [X] Customize Kernel Settings
+
+Exit and save again.  Once the kernel configuration menu re-appears,
+simply exit and save. 
+
+This second invocation of the kernel configuration menu is required to
+pickup the changes with your new platform.  Failing to do this step
+may cause strange behaviour, so don't forget! 
+
+Your new platform is now ready to build.  You may now wish to look
+more closely at the kernel and vendor configurations, enabling any
+particular options or applications that you require.  It may also be a
+good idea to save the default settings for this new platform.  You can
+do this under the main config menu -> Kernel/Library/Defaults ->
+Update Default Vendor Settings option. 
+
+Now you are ready to build your new kernel and filesystem image.  From
+uClinux-dist: 
+
+  $ make dep
+  $ make all
+
+For a first build, it is advised to use only the generic uClinux MTD
+mapping.  In the kernel config menu, under "Memory Technology Devices
+Settings" -> "Mapping drivers for chip access", select only the
+"Generic uClinux RAM/ROM filesystem support".
+
diff -urN linux-2.4.29/Documentation/networking/ip-sysctl.txt linux-2.4.29-uc1/Documentation/networking/ip-sysctl.txt
--- linux-2.4.29/Documentation/networking/ip-sysctl.txt	2004-08-08 00:26:04.000000000 +0100
+++ linux-2.4.29-uc1/Documentation/networking/ip-sysctl.txt	2005-06-14 02:10:53.000000000 +0100
@@ -600,7 +600,21 @@
 		TRUE: disable IPv4-mapped address feature
 		FALSE: enable IPv4-mapped address feature
 
-	Default: FALSE (as specified in RFC2553bis)
+	Default: FALSE (as specified in RFC3493)
+
+IPv6 Fragmentation:
+
+ip6frag_high_thresh - INTEGER
+	Maximum memory used to reassemble IPv6 fragments. When 
+	ip6frag_high_thresh bytes of memory is allocated for this purpose,
+	the fragment handler will toss packets until ip6frag_low_thresh
+	is reached.
+	
+ip6frag_low_thresh - INTEGER
+	See ip6frag_high_thresh	
+
+ip6frag_time - INTEGER
+	Time in seconds to keep an IPv6 fragment in memory.
 
 conf/default/*:
 	Change the interface-specific default settings.
@@ -702,6 +716,43 @@
 	routers are present.
 	Default: 3
 
+use_tempaddr - INTEGER
+	Preference for Privacy Extensions (RFC3041).
+	  <= 0 : disable Privacy Extensions
+	  == 1 : enable Privacy Extensions, but prefer public
+	         addresses over temporary addresses.
+	  >  1 : enable Privacy Extensions and prefer temporary
+	         addresses over public addresses.
+	Default:  1 (for most devices)
+		 -1 (for point-to-point devices and loopback devices)
+
+temp_valid_lft - INTEGER
+	valid lifetime (in seconds) for temporary addresses.
+	Default: 604800 (7 days)
+
+temp_prefered_lft - INTEGER
+	Preferred lifetime (in seconds) for temorary addresses.
+	Default: 86400 (1 day)
+
+max_desync_factor - INTEGER
+	Maximum value for DESYNC_FACTOR, which is a random value
+	that ensures that clients don't synchronize with each 
+	other and generage new addresses at exactly the same time.
+	value is in seconds.
+	Default: 600
+	
+regen_max_retry - INTEGER
+	Number of attempts before give up attempting to generate
+	valid temporary addresses.
+	Default: 5
+
+max_addresses - INTEGER
+	Number of maximum addresses per interface.  0 disables limitation.
+	It is recommended not set too large value (or 0) because it would 
+	be too easy way to crash kernel to allow to create too much of 
+	autoconfigured addresses.
+	Default: 16
+
 icmp/*:
 ratelimit - INTEGER
 	Limit the maximal rates for sending ICMPv6 packets.
diff -urN linux-2.4.29/Documentation/networking/sk98lin.txt linux-2.4.29-uc1/Documentation/networking/sk98lin.txt
--- linux-2.4.29/Documentation/networking/sk98lin.txt	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-uc1/Documentation/networking/sk98lin.txt	2005-06-14 02:10:53.000000000 +0100
@@ -1,11 +1,11 @@
-(C)Copyright 1999-2003 Marvell(R).
+(C)Copyright 1999-2004 Marvell(R).
 All rights reserved
 ===========================================================================
 
-sk98lin.txt created 15-Dec-2003
+sk98lin.txt created 20-Aug-2004
 
-Readme File for sk98lin v6.21
-Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX
+Readme File for sk98lin v7.06
+Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter driver for LINUX
 
 This file contains
  1  Overview
@@ -110,13 +110,13 @@
    
    NOTE 1: If you have more than one Marvell Yukon or SysKonnect SK-98xx 
            adapter installed, the adapters will be listed as 'eth0', 
-                   'eth1', 'eth2', etc.
-                   For each adapter, repeat steps 3 and 4 below.
+           'eth1', 'eth2', etc.
+           For each adapter, repeat steps 3 and 4 below.
 
    NOTE 2: If you have other Ethernet adapters installed, your Marvell
            Yukon or SysKonnect SK-98xx adapter will be mapped to the 
-                   next available number, e.g. 'eth1'. The mapping is executed 
-                   automatically.
+           next available number, e.g. 'eth1'. The mapping is executed 
+           automatically.
            The module installation message (displayed either in a system
            log file or on the console) prints a line for each adapter 
            found containing the corresponding 'ethX'.
diff -urN linux-2.4.29/Documentation/README.NetARM linux-2.4.29-uc1/Documentation/README.NetARM
--- linux-2.4.29/Documentation/README.NetARM	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/Documentation/README.NetARM	2005-06-14 02:10:53.000000000 +0100
@@ -0,0 +1,90 @@
+
+  Release Notes for the NetARM Version 
+ ======================================
+
+
+This is a port of uClinux to the NetSilicon's NET+ARM processor. It
+has been tested on a NET+40 development kit and on our own board
+named "emlin".
+
+It is not yet finished (by far) and should be seen as something like
+an alpha version.
+
+The kernel can boot from a built-in ramdisk image (download separately,
+or ask me). This image file named "ramdisk.inc" is included by
+arch/armnommu/kernel/head-arm-netarm.S. You can place a symbolic link
+to your actual image file there.
+
+Serial and ethernet drivers are working so far. Ethernet is much more
+stable when the kernel is compiled with the arm-elf toolchain (instead
+of arm-uclinux).
+MTD flash erase and write functions work.
+/proc file system is available.
+Various ethernet functions work (ifconfig, route, nfs).
+
+Most other features are not yet tested.
+
+
+Differences to the CVS repository of uClinux 2.4.17, as of Apr 02, 2002:
+------------------------------------------------------------------------
+new files:
+
+Documentation/README.NetARM (this file)
+include/asm-armnommu/arch-netarm/*
+arch/armnommu/mach-netarm/*
+arch/armnommu/def-configs/netarm
+arch/armnommu/kernel/head-arm-netarm.S	(startup code)
+arch/armnommu/kernel/ramdisk.inc	(symbolic link to a ramdisk image)
+drivers/char/serial_netarm.c	(driver for the NetARM's built-in serial interfaces)
+drivers/net/netarmeth.c		(driver for the NetARM's built-in ethernet controller)
+drivers/net/netarmeth.h
+
+modified files:
+
+Documentation/Configure.help 	(a few new entries)
+Makefile 			(architecture armnommu, cross-compiler arm-elf-)
+arch/armnommu/Makefile 		(new case #if CONFIG_ARCH_NETARM...)
+arch/armnommu/config.in 	(new system type)
+arch/armnommu/kernel/Makefile 
+arch/armnommu/kernel/arch.c 	(NetARM fixup)
+arch/armnommu/kernel/entry-armv.S (NetARM macros)
+arch/armnommu/kernel/setup.c 
+arch/armnommu/mm/fault-common.c 
+arch/armnommu/mm/init.c 	(special treatment for NetARM in free_initmem)
+arch/armnommu/mm/proc-arm6,7.S 
+arch/armnommu/tools/mach-types 	(replace with recent list from Russel King)
+arch/armnommu/vmlinux-armv.lds.in 
+drivers/block/Config.in 
+drivers/block/rd.c 
+drivers/char/Config.in 
+drivers/char/Makefile 		(added serial_netarm.o)
+drivers/char/tty_io.c 		(added #ifdef CONFIG_SERIAL_NETARM_CONSOLE...)
+drivers/ieee1394/Config.in 	(preparations for a new 1394 driver, not essential)
+drivers/ieee1394/Makefile 	(dto.)
+drivers/mtd/mtdblock.c 		(some more debug output, not essential)
+drivers/mtd/mtdblock_ro.c 	(dto.)
+drivers/mtd/mtdchar.c 		(dto.)
+drivers/net/Config.in 
+drivers/net/Makefile 
+fs/binfmt_flat.c 
+include/asm-armnommu/io.h 
+include/asm-armnommu/mach/dma.h 
+include/asm-armnommu/uaccess.h 
+include/linux/compiler.h 
+mmnommu/bootmem.c 	(invalid address warning in function reserve_bootmem_core)
+------------------------------------------------------------------------
+
+
+To do:
+------
+Rework memory management parameters, so that all RAM is controlled by the
+memory manager (and the ramdisk data can be freed after unpacking).
+Currently the lowest 2 MB are "off limits" for the memory manager.
+
+Implement a "real" boot loader, separate boot loader, kernel, ramdisk image.
+
+
+
+Rolf Peukert
+IMMS gGmbH
+rolf.peukert@imms.de
diff -urN linux-2.4.29/Documentation/timepeg.txt linux-2.4.29-uc1/Documentation/timepeg.txt
--- linux-2.4.29/Documentation/timepeg.txt	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/Documentation/timepeg.txt	2005-06-14 02:10:53.000000000 +0100
@@ -0,0 +1,456 @@
+Documentation/timepegs.txt
+http://www.uow.edu.au/~andrewm/linux/
+
+Andrew Morton <andrewm@uow.edu.au>
+25 March 2000
+
+
+Quick start
+===========
+
+1: Grab the timepeg patch and the 'tpt' tool from the above URL. 
+   Build tpt and install it somewhere.
+
+2: Apply the patch it to your kernel.
+
+3: Run 'make menuconfig' or whatever.
+
+4: Enable timepegs under 'Kernel Hacking'
+
+5: make clean && make dep && make bzImage && make modules
+
+6: Decide what timing within the kernel you need to test.  For
+   example, let's see how long alloc_skb() takes:
+
+#include <asm/timepeg.h>
+foo()
+{
+	struct sk_buff *skb;
+
+	TIMEPEG("call alloc_skb");
+	skb = alloc_skb(1000, GFP_ATOMIC);
+	TIMEPEG("alloc_skb finished");
+}
+
+7: Compile this up, run the kernel and type:
+
+        tpt
+
+You will see output like:
+
+
+           Destination  Count     Average       Min           Max
+
+call alloc_skb ->
+    alloc_skb finished  4            8.01      7.04          9.36
+
+alloc_skb finished ->
+  call alloc_skb        4      409,940.74  2,883.09  1,388,510.40
+
+
+
+Which tells you that alloc_skb takes 8 microseconds.  Of course it gets
+more complicated than this...
+
+
+Overview
+========
+
+Timepegs provide a means of precisely measuring elapsed time within the
+kernel.  They use the Pentuim 'rdtsc' instruction for this.  They
+_may_ work on the Alpha - the code is there but untested.
+
+Example: suppose the programmer wishes to know how long it takes to get
+from sys_sento() right down into the network device driver he would
+use:
+
+In socket.c:
+
+#include <asm/timepeg.h>
+
+...
+
+asmlinkage long sys_sendto(int fd, void * buff, size_t len, unsigned flags,
+               struct sockaddr *addr, int addr_len)
+{
+	    struct socket *sock;
+	    char address[MAX_SOCK_ADDR];
+	    int err;
+	    struct msghdr msg;
+	    struct iovec iov;
+	
+	TIMEPEG("sys_sendto");
+	...
+
+and in the device driver:
+
+#include <asm/timepeg.h>
+
+static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+	TIMEPEG("net_send_packet");
+	...
+
+
+Build this kernel, run some net traffic and then use the command
+
+	tpt
+
+to display the average, minimum, and maximum latency between these two
+timepegs.
+
+
+More details
+============
+
+If there are more than two timepegs in the entire kernel then things
+get more complicated because each timepeg can have an arbitrary number
+of predecessors (most-recently-encountered timepegs).
+
+For example:
+
+	final()
+	{
+		TIMEPEG("final");
+	}
+
+	middle_1()
+	{
+		TIMEPEG("middle_1");
+		final();
+	}
+
+	middle_2()
+	{
+		TIMEPEG("middle_2");
+		final();
+	)
+
+	first(int cond)
+	{
+		TIMEPEG("first");
+		if (cond)
+			middle_1();
+		else
+			middle_2();
+	}
+
+Generates the following timepeg graph:
+
+                   final
+                   /   \
+             w1   /     \  w2
+                 /       \
+                /         \
+            middle_1    middle_2
+                \         /
+                 \       /
+             w3   \     /  w4
+                   \   /
+                   first
+
+Where the nodes are timepeg-encounters and the weights on the edges are
+the minimum, maximum and average time to transit between the respective
+timepegs.
+
+The kernel's timepeg driver maintains a data structure which precisely
+models this graph.  It is a directed graph where each node represents a
+timepeg and each edge is the min, max and average transit time from the
+most previous timepeg ON THIS CPU!
+
+Timepeg transit times are accumulated on a per-CPU basis because it
+probably doesn't make a lot of sense to measure cross-CPU intervals.
+
+The timepeg graph may be read from the kernel at any time via the
+/proc/timepeg virtual file.
+
+When /proc/timepeg is open all timepeg instrumentation accumulation is
+suspended - this ensures that the read is consistent.
+
+When the read of /proc/timepeg completes all the kernel timepeg
+instrumentation is reset to zero values.  This allows you to rerun a
+scenario.
+
+There is a user-space application called 'tpt' (available from
+http://www.uow.edu.au/~andrewm/linux/) which may be used to display the
+/proc/timepeg information in a more understandable form.  It reverses
+the direction of all the edges (so they are displayed in time-order)
+and converts the raw 'rdtsc' information into microseconds (10 nSec
+resolution).
+
+Here is a sample output from 'tpt':
+
+
+                  Callee  Count     Average       Min           Max
+
+sock_sendmsg ->
+      dev_queue_xmit_nit  54      24,877.74     30.44    311,667.07
+            sock_sendmsg  42         377.93    338.23        667.07
+
+dev_queue_xmit_nit ->
+  cs89x0_net_send_packet  589         17.43       .75        169.78
+      dev_queue_xmit_nit  38          14.97      3.96         27.92
+
+cs89x0_net_send_packet ->
+  cs89x0_net_send_packet  211        796.56     96.28      1,617.11
+      dev_queue_xmit_nit  535     34,124.08     12.50  3,997,946.66
+            sock_sendmsg  54     821,295.57  1,114.60  6,414,591.98
+
+
+This shows that the latency between sock_sendmsg() and
+dev_queue_xmit_nit() is a minimum of 30.44 microseconds.
+
+It is possible to accumulate these results to obtain the time interval
+between timepegs which have one or more intervening timepegs (tpt could
+do this, but doesn't).  But be aware that the graph may have several
+paths from the first to the last.  You need to know what's going on in
+there.
+
+If tpt is invoked with the '-s' argument it produces an output format
+which is compatible with sort(1).  Use something like:
+
+	tpt -s | sort -nr +5
+
+Directed timepegs
+=================
+
+Normally a timepeg uses the time since the most-recently-hit timepeg on
+this CPU.  But suppose we want to know the time interval between two
+places (A and E) in the code which have a lot of intervening timepegs
+(B, C and D).  We would have to accumulate the timepeg information
+across all possible paths through these five nodes - calculate the min
+and max, calculate the average by weighting each node by the number of
+traversals.
+
+[ Actually, even this doesn't work, because the call graph could be:
+
+     A   X
+      \ /
+       B
+       |
+       C
+       |
+       D
+      / \
+     E   Y
+
+and we can't separate the X->Y path from the A->E path ]
+
+A 'directed timepeg' is one which accumulates the transit time from a
+particular nominated other timepeg, rather than from the
+most-recently-encountered timepeg.
+
+A directed timepeg is used in a similar manner to a normal timepeg:
+
+	DTIMEPEG("this_timepeg_id", "other_timepeg_id");
+
+Example:
+
+#include <asm/timepeg.h>
+
+E()
+{
+	TIMEPEG("E_tp");
+}
+
+D()
+{
+	TIMEPEG("D_tp");
+	E();
+}
+
+C()
+{
+	TIMEPEG("C_tp");
+	D();
+}
+
+B()
+{
+	TIMEPEG("B_tp");
+	C();
+}
+
+A()
+{
+	TIMEPEG("A_tp");
+	B();
+	DTIMEPEG("A_exit_tp", "A_tp");
+}
+
+The final DTIMEPEG() invokation will cause the 'A_exit_tp' timepeg to
+measure the time taken to travel from 'A_tp' to itself.
+
+The output of tpt would look like:
+
+A_tp ->
+   B_tp        1    11        1.56     1.56      1.56
+   A_exit_tp   1    40        4.44     4.44      4.44
+
+Telling us that it took 1.56 uSecs to get from A_tp to B_tp and that it
+took 4.44 uSecs to get from A_tp to A_exit_tp.
+
+Be aware that while normal timepegs compensate for the time spent
+within themselves, directed timepegs do not.  (They could, but that's
+not there yet).  In this example the time for the A_tp->A_exit_tp
+includes all the time spent calculating the intervening timepeg values.
+
+On my 400MHz Celeron a timepeg takes 2.33 microseconds.  See the
+'measure_2' and 'measure_4' timepegs in timepeg.c for how this was
+measured.
+
+
+Start and stop timepegs
+=======================
+
+[ New in 2.3.99-pre3-1 ]
+
+Normal timepegs and directed timepegs may be considered to do two
+things:
+
+1: They record the elapsed time since the more recent timepeg and
+
+2: They act as a starting time for the next timepeg.
+
+This is sometimes not the desired behaviour.  For example, the code:
+
+foo()
+{
+	TIMEPEG("tp1");
+	...
+	TIMEPEG("tp2");
+}
+
+will record two arcs (provided foo() is executed more than once).  One
+arc is tp1->tp2 and the other is tp2->tp1.  The latter is probably not
+interesting.
+
+Plus I found that the default (entry + exit) behaviour of timepegs got
+in the way for the intlat (interrupt latency) measurement work.  In
+this case I needed timepegs which act as starting points but not as
+stopping points and vice-versa.
+
+So 'stop' and 'start' timepegs may be used thusly:
+
+foo()
+{
+	TIMEPEG_MODE("tp1", TPH_MODE_START);
+	...
+	TIMEPEG_MODE("tp2", TPH_MODE_STOP);
+}
+
+Now, only one arc will be recorded.
+
+Another application:
+
+foo()
+{
+	TIMEPEG_MODE("tp1", TPH_MODE_START);
+	...
+	TIMEPEG_MODE("tp2", TPH_MODE_STOP);
+	...
+	TIMEPEG_MODE("tp3", TPH_MODE_STOP);
+	...
+	TIMEPEG_MODE("tp4", TPH_MODE_STOP);
+}
+
+In this case, the timepegs tp2, tp3 and tp4 will _each_ record the time
+since tp1, not the time since their most immediate predecessor.
+
+
+Usage details
+=============
+
+- Do not simply fill your code with timepegs and expect to be able to
+  decipher the output.  There is a lot going on in the kernel and you
+  will probably be swamped by the result.  Three or four timepegs are
+  probably a practical limit, but more would be reasonable if the call
+  chain is straightforward.
+
+- Of course interrupts make timepegs harder to understand.  They
+  cause more time variance and they also complicate the graph by
+  interposing interrupt-based timepeg nodes in places where you
+  wouldn't expect them.  This is usually OK as long as you understand
+  what your code is doing!
+
+  I guess it would be possible to eliminate interrupt noise from the
+  timepeg statistics by appropriate interception of the interrupt
+  front-end.  The need for this work will have to be demonstrated :)
+
+- Do NOT expect timepegs to work as you expect when they are used in
+  inline functions in header files:
+
+foo.h:
+
+    extern inline fast_func()
+    {
+        TIMEPEG("fast_func");
+        ...
+    }
+
+bar.c:
+    #include "foo.h"
+
+    f1()
+    {
+        fast_func();
+    }
+
+zot.c:
+
+    f2()
+    {
+        fast_func();
+    }
+
+In this example, the storage for the 'fast_func' timepeg will be
+created as static storage in both 'bar.o' and 'zot.o'.  They both have
+the same name and the downstream timepeg processing tools will blow up
+in mysterious ways.
+
+If the inline function is private to a particular translation unit then
+it is fine: even if the inline function is expanded several times, its
+static storage is commoned up.
+
+- When the system is booted, timepeg accounting is disabled.  The
+  first time /proc/timepeg is read from, this acts as a trigger to turn
+  on timepeg accounting.
+
+
+Implementation details
+======================
+
+- The timepg patch aims to be unintrusive.  Basically three new files
+  and a three-liner in arch/i386/kernel/config.in.  The files are:
+
+  arch/i386/kernel/timepeg.c
+  include/asm-i386/timepeg.h
+  Documentation/timepeg.txt
+
+- The timepeg code cannot be put in a library (.a) because it may be
+  used by kernel modules exclusively.
+
+- You may leave invokations of the TIMEPEG() and DTIMEPEG() macro in
+  your code - they evaluate to nothing if CONFIG_TIMEPEGS is not
+  enabled.
+
+- If a kernel module uses timepegs and it is removed, reading
+  /proc/timepeg will crash your machine.  Sorry.  One thing you can do
+  is to disable the periodic 'rmmod' which some systems run - on
+  RedHat-like systems, edit /etc/cron.d/kmod.
+
+- The tpt application is very cheesy, but does the job.
+
+- The tpt application uses the output of the local machine's
+  /proc/cpuinfo to determine your procesor frequency.  If 'tpt' is not
+  running on the machine under test, use its '-m' option to set the CPU
+  frequency (in MHz).
+
+- The TIMEPEG macros make a sterling effort to not perturb the thing
+  which is being measured - they read the processor's timestamp
+  registers at the earliest and latest possible opportunities and
+  compensate for the time in between.  But even with this, the timings
+  which the timepegs tell you may be greater than with uninstrumented
+  code because the timepeg code itself will compete for your caches.
+
+
diff -urN linux-2.4.29/drivers/at91/i2c/at91_i2c.c linux-2.4.29-uc1/drivers/at91/i2c/at91_i2c.c
--- linux-2.4.29/drivers/at91/i2c/at91_i2c.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/i2c/at91_i2c.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,257 @@
+/*
+    i2c Support for Atmel's AT91RM9200 Two-Wire Interface
+
+    (c) Rick Bronson
+
+    Borrowed heavily from original work by:
+    Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+
+#include <asm/arch/AT91RM9200_TWI.h>
+#include <asm/arch/pio.h>
+#include "at91_i2c.h"
+
+#define DBG(x...) do {\
+	if (debug > 0) \
+		printk(KERN_DEBUG "i2c:" x); \
+	} while(0)
+
+int debug = 0;
+
+static struct at91_i2c_local *at91_i2c_device;
+
+/*
+ * Poll the i2c status register until the specified bit is set.
+ * Returns 0 if timed out (100 msec)
+ */
+static short at91_poll_status(AT91PS_TWI twi, unsigned long bit) {
+	int loop_cntr = 10000;
+	do {
+		udelay(10);
+	} while (!(twi->TWI_SR & bit) && (--loop_cntr > 0));
+
+	return (loop_cntr > 0);
+}
+
+/*
+ * Generic i2c master transfer entrypoint
+ */
+static int at91_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+{
+	struct at91_i2c_local *device = (struct at91_i2c_local *) adap->data;
+	AT91PS_TWI twi = (AT91PS_TWI) device->base_addr;
+
+	struct i2c_msg *pmsg;
+	int length;
+	unsigned char *buf;
+
+	/*
+	 * i2c_smbus_xfer_emulated() in drivers/i2c/i2c-core.c states:
+	 * "... In the case of writing, we need to use only one message;
+	 * when reading, we need two..."
+	 */
+
+	pmsg = msgs;		/* look at 1st message, it contains the address/command */
+	if (num >= 1 && num <= 2) {
+		DBG("xfer: doing %s %d bytes to 0x%02x - %d messages\n",
+		    pmsg->flags & I2C_M_RD ? "read" : "write",
+		    pmsg->len, pmsg->buf[0], num);
+
+		/* Set the TWI Master Mode Register */
+		twi->TWI_MMR = (pmsg->addr << 16) | (pmsg->len << 8)
+			| ((pmsg + 1)->flags & I2C_M_RD ? AT91C_TWI_MREAD : 0);
+
+		/* Set TWI Internal Address Register with first messages data field */
+		if (pmsg->len == 1)
+			twi->TWI_IADR = pmsg->buf[0];
+		else if (pmsg->len == 2)
+			twi->TWI_IADR = pmsg->buf[0] << 8 | pmsg->buf[1];
+		else			/* must be 3 */
+			twi->TWI_IADR =  pmsg->buf[0] << 16 | pmsg->buf[1] << 8 | pmsg->buf[2];
+
+		/* 1st message contains the address/command */
+		if (num > 1)
+			pmsg++;		/* go to real message */
+
+		length = pmsg->len;
+		buf = pmsg->buf;
+		if (length && buf) {	/* sanity check */
+			if (pmsg->flags & I2C_M_RD) {
+				twi->TWI_CR = AT91C_TWI_START;
+				while (length--) {
+					if (!length)
+						twi->TWI_CR = AT91C_TWI_STOP;
+					/* Wait until transfer is finished */
+					if (!at91_poll_status(twi, AT91C_TWI_RXRDY)) {
+						printk(KERN_ERR "at91_i2c: timeout 1\n");
+						return 0;
+					}
+					*buf++ = twi->TWI_RHR;
+				}
+				if (!at91_poll_status(twi, AT91C_TWI_TXCOMP)) {
+					printk(KERN_ERR "at91_i2c: timeout 2\n");
+					return 0;
+				}
+			} else {
+				twi->TWI_CR = AT91C_TWI_START;
+				while (length--) {
+					twi->TWI_THR = *buf++;
+					if (!length)
+						twi->TWI_CR = AT91C_TWI_STOP;
+					if (!at91_poll_status(twi, AT91C_TWI_TXRDY)) {
+						printk(KERN_ERR "at91_i2c: timeout 3\n");
+						return 0;
+					}
+				}
+				/* Wait until transfer is finished */
+				if (!at91_poll_status(twi, AT91C_TWI_TXCOMP)) {
+					printk(KERN_ERR "at91_i2c: timeout 4\n");
+					return 0;
+				}
+			}
+		}
+		DBG("transfer complete\n");
+		return num;
+	}
+	else {
+		printk(KERN_ERR "at91_i2c: unexpected number of messages: %d\n", num);
+		return 0;
+	}
+}
+
+/*
+ * Return list of supported functionality
+ */
+static u32 at91_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE
+		| I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA
+		| I2C_FUNC_SMBUS_BLOCK_DATA;
+}
+
+/*
+ * Open
+ */
+static void at91_inc(struct i2c_adapter *adapter)
+{
+	MOD_INC_USE_COUNT;
+}
+
+/*
+ * Close
+ */
+static void at91_dec(struct i2c_adapter *adapter)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+/* For now, we only handle combined mode (smbus) */
+static struct i2c_algorithm at91_algorithm = {
+	name:"at91 i2c",
+	id:I2C_ALGO_SMBUS,
+	master_xfer:at91_xfer,
+	functionality:at91_func,
+};
+
+/*
+ * Main initialization routine
+ */
+static int __init i2c_at91_init(void)
+{
+	AT91PS_TWI twi = (AT91PS_TWI) AT91C_VA_BASE_TWI;
+	struct at91_i2c_local *device;
+	int rc;
+
+	AT91_CfgPIO_TWI();
+	AT91_SYS->PMC_PCER = 1 << AT91C_ID_TWI;		/* enable peripheral clock */
+
+	twi->TWI_IDR = 0x3ff;				/* Disable all interrupts */
+	twi->TWI_CR = AT91C_TWI_SWRST;			/* Reset peripheral */
+	twi->TWI_CR = AT91C_TWI_MSEN | AT91C_TWI_SVDIS;	/* Set Master mode */
+
+	/* Here, CKDIV = 1 and CHDIV=CLDIV  ==> CLDIV = CHDIV = 1/4*((Fmclk/FTWI) -6) */
+	twi->TWI_CWGR = AT91C_TWI_CKDIV1 | AT91C_TWI_CLDIV3 | (AT91C_TWI_CLDIV3 << 8);
+
+	device = (struct at91_i2c_local *) kmalloc(sizeof(struct at91_i2c_local), GFP_KERNEL);
+	if (device == NULL) {
+		printk(KERN_ERR "at91_i2c: can't allocate inteface!\n");
+		return -ENOMEM;
+	}
+	memset(device, 0, sizeof(struct at91_i2c_local));
+	at91_i2c_device = device;
+
+	sprintf(device->adapter.name, "AT91RM9200");
+	device->adapter.data = (void *) device;
+	device->adapter.id = I2C_ALGO_SMBUS;
+	device->adapter.algo = &at91_algorithm;
+	device->adapter.algo_data = NULL;
+	device->adapter.inc_use = at91_inc;
+	device->adapter.dec_use = at91_dec;
+	device->adapter.client_register = NULL;
+	device->adapter.client_unregister = NULL;
+	device->base_addr = AT91C_VA_BASE_TWI;
+
+	rc = i2c_add_adapter(&device->adapter);
+	if (rc) {
+		printk(KERN_ERR "at91_i2c: Adapter %s registration failed\n", device->adapter.name);
+		device->adapter.data = NULL;
+		kfree(device);
+	}
+	else
+		printk(KERN_INFO "Found AT91 i2c\n");
+	return rc;
+}
+
+/*
+ * Clean up routine
+ */
+static void __exit i2c_at91_cleanup(void)
+{
+	struct at91_i2c_local *device = at91_i2c_device;
+	int rc;
+
+	rc = i2c_del_adapter(&device->adapter);
+	device->adapter.data = NULL;
+	kfree(device);
+	
+	AT91_SYS->PMC_PCDR = 1 << AT91C_ID_TWI;		/* disable peripheral clock */
+
+	/* We aren't that prepared to deal with this... */
+	if (rc)
+		printk(KERN_ERR "at91_i2c: i2c_del_adapter failed (%i), that's bad!\n", rc);
+}
+
+module_init(i2c_at91_init);
+module_exit(i2c_at91_cleanup);
+
+MODULE_AUTHOR("Rick Bronson");
+MODULE_DESCRIPTION("I2C driver for Atmel AT91RM9200");
+MODULE_LICENSE("GPL");
+MODULE_PARM(debug, "i");
+
+EXPORT_NO_SYMBOLS;
diff -urN linux-2.4.29/drivers/at91/i2c/at91_i2c.h linux-2.4.29-uc1/drivers/at91/i2c/at91_i2c.h
--- linux-2.4.29/drivers/at91/i2c/at91_i2c.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/i2c/at91_i2c.h	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,43 @@
+/*
+    i2c Support for Atmel's AT91RM9200 Two-Wire Interface
+
+    (c) Rick Bronson
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef AT91_I2C_H
+#define AT91_I2C_H
+
+#define AT91C_TWI_CLOCK		100000
+#define AT91C_TWI_SCLOCK	(10 * AT91C_MASTER_CLOCK / AT91C_TWI_CLOCK)
+#define AT91C_TWI_CKDIV1	(2 << 16)	/* TWI clock divider.  NOTE: see Errata #22 */
+
+#if (AT91C_TWI_SCLOCK % 10) >= 5
+#define AT91C_TWI_CLDIV2 ((AT91C_TWI_SCLOCK / 10) - 5)
+#else
+#define AT91C_TWI_CLDIV2 ((AT91C_TWI_SCLOCK / 10) - 6)
+#endif
+#define AT91C_TWI_CLDIV3 ((AT91C_TWI_CLDIV2 + (4 - AT91C_TWI_CLDIV2 % 4)) >> 2)
+
+#define AT91C_EEPROM_I2C_ADDRESS        (0x50 << 16)
+
+/* Physical interface */
+struct at91_i2c_local {
+	struct i2c_adapter adapter;
+	unsigned long base_addr;
+};
+
+#endif
diff -urN linux-2.4.29/drivers/at91/i2c/Makefile linux-2.4.29-uc1/drivers/at91/i2c/Makefile
--- linux-2.4.29/drivers/at91/i2c/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/i2c/Makefile	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,15 @@
+# File: drivers/at91/i2c/Makefile
+#
+# Makefile for the Atmel AT91RM9200 I2C (TWI) device drivers
+#
+
+O_TARGET := at91i2c.o
+
+obj-y	:=
+obj-m	:=
+obj-n	:=
+obj-	:=
+
+obj-$(CONFIG_I2C_AT91) += at91_i2c.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/at91/Makefile linux-2.4.29-uc1/drivers/at91/Makefile
--- linux-2.4.29/drivers/at91/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/Makefile	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,23 @@
+#
+# Makefile for the AT91RM9200-specific Linux kernel device drivers.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (not a .c file).
+
+O_TARGET := at91drv.o
+
+subdir-y :=	serial net watchdog rtc usb i2c spi mtd
+subdir-m :=	$(subdir-y)
+
+obj-$(CONFIG_SERIAL_AT91)		+= serial/at91serial.o
+obj-$(CONFIG_AT91_ETHER)		+= net/at91net.o
+obj-$(CONFIG_AT91_WATCHDOG)		+= watchdog/at91wdt.o
+obj-$(CONFIG_AT91_RTC)			+= rtc/at91rtc.o
+obj-$(CONFIG_USB)			+= usb/at91usb.o
+obj-$(CONFIG_I2C_AT91)			+= i2c/at91i2c.o
+obj-$(CONFIG_AT91_SPIDEV)		+= spi/at91spi.o
+obj-$(CONFIG_MTD_AT91_DATAFLASH)	+= spi/at91spi.o mtd/at91mtd.o
+obj-$(CONFIG_MTD_AT91_SMARTMEDIA)	+= mtd/at91mtd.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/at91/mtd/at91_dataflash.c linux-2.4.29-uc1/drivers/at91/mtd/at91_dataflash.c
--- linux-2.4.29/drivers/at91/mtd/at91_dataflash.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/mtd/at91_dataflash.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,540 @@
+/*
+ * Atmel DataFlash driver for Atmel AT91RM9200 (Thunder)
+ *
+ * (c) SAN People (Pty) Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+*/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/arch/AT91RM9200_SPI.h>
+#include <asm/arch/pio.h>
+#include "at91_dataflash.h"
+#include "../spi/at91_spi.h"
+
+#undef DEBUG_DATAFLASH
+
+/* Detected DataFlash devices */
+static struct mtd_info* mtd_devices[DATAFLASH_MAX_DEVICES];
+static int nr_devices = 0;
+
+/* ......................................................................... */
+
+#ifdef CONFIG_MTD_PARTITIONS
+
+static struct mtd_partition *mtd_parts = 0;
+static int mtd_parts_nr = 0;
+
+#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
+
+static struct mtd_partition static_partitions[] =
+{
+	{
+		name:		"bootloader",
+		offset:		0,
+		size:		64 * 1024,		/* 64 Kb */
+		mask_flags:	MTD_WRITEABLE		/* read-only */
+	},
+	{
+		name:		"kernel",
+		offset:		MTDPART_OFS_NXTBLK,
+		size:		768 *1024,		/* 768 Kb */
+	},
+	{
+		name:		"filesystem",
+		offset:		MTDPART_OFS_NXTBLK,
+		size:		MTDPART_SIZ_FULL,
+	}
+};
+
+int parse_cmdline_partitions(struct mtd_info *master,
+		struct mtd_partition **pparts, const char *mtd_id);
+
+#endif
+
+/* ......................................................................... */
+
+/* Allocate a single SPI transfer descriptor.  We're assuming that if multiple
+   SPI transfers occur at the same time, spi_access_bus() will serialize them.
+   If this is not valid, then either (i) each dataflash 'priv' structure
+   needs it's own transfer descriptor, (ii) we lock this one, or (iii) use
+   another mechanism.   */
+static struct spi_transfer_list* spi_transfer_desc;
+
+/*
+ * Perform a SPI transfer to access the DataFlash device.
+ */
+static int do_spi_transfer(int nr, char* tx, int tx_len, char* rx, int rx_len,
+		char* txnext, int txnext_len, char* rxnext, int rxnext_len)
+{
+	struct spi_transfer_list* list = spi_transfer_desc;
+
+	list->tx[0] = tx;	list->txlen[0] = tx_len;
+	list->rx[0] = rx;	list->rxlen[0] = rx_len;
+
+	list->tx[1] = txnext; 	list->txlen[1] = txnext_len;
+	list->rx[1] = rxnext;	list->rxlen[1] = rxnext_len;
+
+	list->nr_transfers = nr;
+
+	return spi_transfer(list);
+}
+
+/* ......................................................................... */
+
+/*
+ * Poll the DataFlash device until it is READY.
+ */
+static void at91_dataflash_waitready(void)
+{
+	char* command = kmalloc(2, GFP_KERNEL);
+
+	if (!command)
+		return;
+
+	do {
+		command[0] = OP_READ_STATUS;
+		command[1] = 0;
+
+		do_spi_transfer(1, command, 2, command, 2, NULL, 0, NULL, 0);
+	} while ((command[1] & 0x80) == 0);
+
+	kfree(command);
+}
+
+/*
+ * Return the status of the DataFlash device.
+ */
+static unsigned short at91_dataflash_status(void)
+{
+	unsigned short status;
+	char* command = kmalloc(2, GFP_KERNEL);
+
+	if (!command)
+		return 0;
+
+	command[0] = OP_READ_STATUS;
+	command[1] = 0;
+
+	do_spi_transfer(1, command, 2, command, 2, NULL, 0, NULL, 0);
+	status = command[1];
+
+	kfree(command);
+	return status;
+}
+
+/* ......................................................................... */
+
+/*
+ * Erase blocks of flash.
+ */
+static int at91_dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	struct dataflash_local *priv = (struct dataflash_local *) mtd->priv;
+	unsigned int pageaddr;
+	char* command;
+
+#ifdef DEBUG_DATAFLASH
+	printk("dataflash_erase: addr=%i len=%i\n", instr->addr, instr->len);
+#endif
+
+	/* Sanity checks */
+	if (instr->addr + instr->len > mtd->size)
+		return -EINVAL;
+	if ((instr->len % mtd->erasesize != 0) || (instr->len % priv->page_size != 0))
+		return -EINVAL;
+	if ((instr->addr % priv->page_size) != 0)
+		return -EINVAL;
+
+	command = kmalloc(4, GFP_KERNEL);
+	if (!command)
+		return -ENOMEM;
+
+	while (instr->len > 0) {
+		/* Calculate flash page address */
+		pageaddr = (instr->addr / priv->page_size) << priv->page_offset;
+
+		command[0] = OP_ERASE_PAGE;
+		command[1] = (pageaddr & 0x00FF0000) >> 16;
+		command[2] = (pageaddr & 0x0000FF00) >> 8;
+		command[3] = 0;
+#ifdef DEBUG_DATAFLASH
+		printk("ERASE: (%x) %x %x %x [%i]\n", command[0], command[1], command[2], command[3], pageaddr);
+#endif
+
+		/* Send command to SPI device */
+		spi_access_bus(priv->spi);
+		do_spi_transfer(1, command, 4, command, 4, NULL, 0, NULL, 0);
+
+		at91_dataflash_waitready();		/* poll status until ready */
+		spi_release_bus(priv->spi);
+
+		instr->addr += priv->page_size;		/* next page */
+		instr->len -= priv->page_size;
+	}
+
+	kfree(command);
+
+	/* Inform MTD subsystem that erase is complete */
+	instr->state = MTD_ERASE_DONE;
+	if (instr->callback)
+		instr->callback(instr);
+
+	return 0;
+}
+
+/*
+ * Read from the DataFlash device.
+ *   from   : Start offset in flash device
+ *   len    : Amount to read
+ *   retlen : About of data actually read
+ *   buf    : Buffer containing the data
+ */
+static int at91_dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
+{
+	struct dataflash_local *priv = (struct dataflash_local *) mtd->priv;
+	unsigned int addr;
+	char* command;
+
+#ifdef DEBUG_DATAFLASH
+	printk("dataflash_read: %lli .. %lli\n", from, from+len);
+#endif
+
+	*retlen = 0;
+
+	/* Sanity checks */
+	if (!len)
+		return 0;
+	if (from + len > mtd->size)
+		return -EINVAL;
+
+	/* Calculate flash page/byte address */
+	addr = (((unsigned)from / priv->page_size) << priv->page_offset) + ((unsigned)from % priv->page_size);
+
+	command = kmalloc(8, GFP_KERNEL);
+	if (!command)
+		return -ENOMEM;
+
+	command[0] = OP_READ_CONTINUOUS;
+	command[1] = (addr & 0x00FF0000) >> 16;
+	command[2] = (addr & 0x0000FF00) >> 8;
+	command[3] = (addr & 0x000000FF);
+#ifdef DEBUG_DATAFLASH
+	printk("READ: (%x) %x %x %x\n", command[0], command[1], command[2], command[3]);
+#endif
+
+	/* Send command to SPI device */
+	spi_access_bus(priv->spi);
+	do_spi_transfer(2, command, 8, command, 8, buf, len, buf, len);
+	spi_release_bus(priv->spi);
+
+	*retlen = len;
+	kfree(command);
+	return 0;
+}
+
+/*
+ * Write to the DataFlash device.
+ *   to     : Start offset in flash device
+ *   len    : Amount to write
+ *   retlen : Amount of data actually written
+ *   buf    : Buffer containing the data
+ */
+static int at91_dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
+{
+	struct dataflash_local *priv = (struct dataflash_local *) mtd->priv;
+	unsigned int pageaddr, addr, offset, writelen;
+	size_t remaining;
+	u_char *writebuf;
+	unsigned short status;
+	int res = 0;
+	char* command;
+	char* tmpbuf = NULL;
+
+#ifdef DEBUG_DATAFLASH
+	printk("dataflash_write: %lli .. %lli\n", to, to+len);
+#endif
+
+	*retlen = 0;
+
+	/* Sanity checks */
+	if (!len)
+		return 0;
+	if (to + len > mtd->size)
+		return -EINVAL;
+
+	command = kmalloc(4, GFP_KERNEL);
+	if (!command)
+		return -ENOMEM;
+
+	pageaddr = ((unsigned)to / priv->page_size);
+	offset = ((unsigned)to % priv->page_size);
+	if (offset + len > priv->page_size)
+		writelen = priv->page_size - offset;
+	else
+		writelen = len;
+	writebuf = buf;
+	remaining = len;
+
+	/* Allocate temporary buffer */
+	tmpbuf = kmalloc(priv->page_size, GFP_KERNEL);
+	if (!tmpbuf) {
+		kfree(command);
+		return -ENOMEM;
+	}
+
+	/* Gain access to the SPI bus */
+	spi_access_bus(priv->spi);
+
+	while (remaining > 0) {
+#ifdef DEBUG_DATAFLASH
+		printk("write @ %i:%i len=%i\n", pageaddr, offset, writelen);
+#endif
+
+		/* (1) Transfer to Buffer1 */
+		if (writelen != priv->page_size) {
+			addr = pageaddr << priv->page_offset;
+			command[0] = OP_TRANSFER_BUF1;
+			command[1] = (addr & 0x00FF0000) >> 16;
+			command[2] = (addr & 0x0000FF00) >> 8;
+			command[3] = 0;
+#ifdef DEBUG_DATAFLASH
+			printk("TRANSFER: (%x) %x %x %x\n", command[0], command[1], command[2], command[3]);
+#endif
+			do_spi_transfer(1, command, 4, command, 4, NULL, 0, NULL, 0);
+			at91_dataflash_waitready();
+		}
+
+		/* (2) Program via Buffer1 */
+		addr = (pageaddr << priv->page_offset) + offset;
+		command[0] = OP_PROGRAM_VIA_BUF1;
+		command[1] = (addr & 0x00FF0000) >> 16;
+		command[2] = (addr & 0x0000FF00) >> 8;
+		command[3] = (addr & 0x000000FF);
+#ifdef DEBUG_DATAFLASH
+		printk("PROGRAM: (%x) %x %x %x\n", command[0], command[1], command[2], command[3]);
+#endif
+		do_spi_transfer(2, command, 4, command, 4, writebuf, writelen, tmpbuf, writelen);
+		at91_dataflash_waitready();
+
+		/* (3) Compare to Buffer1 */
+		addr = pageaddr << priv->page_offset;
+		command[0] = OP_COMPARE_BUF1;
+		command[1] = (addr & 0x00FF0000) >> 16;
+		command[2] = (addr & 0x0000FF00) >> 8;
+		command[3] = 0;
+#ifdef DEBUG_DATAFLASH
+		printk("COMPARE: (%x) %x %x %x\n", command[0], command[1], command[2], command[3]);
+#endif
+		do_spi_transfer(1, command, 4, command, 4, NULL, 0, NULL, 0);
+		at91_dataflash_waitready();
+
+		/* Get result of the compare operation */
+		status = at91_dataflash_status();
+		if ((status & 0x40) == 1) {
+			printk("at91_dataflash: Write error on page %i\n", pageaddr);
+			remaining = 0;
+			res = -EIO;
+		}
+
+		remaining = remaining - writelen;
+		pageaddr++;
+		offset = 0;
+		writebuf += writelen;
+		*retlen += writelen;
+
+		if (remaining > priv->page_size)
+			writelen = priv->page_size;
+		else
+			writelen = remaining;
+	}
+
+	/* Release SPI bus */
+	spi_release_bus(priv->spi);
+
+	kfree(tmpbuf);
+	kfree(command);
+	return res;
+}
+
+/* ......................................................................... */
+
+/*
+ * Initialize and register DataFlash device with MTD subsystem.
+ */
+static int add_dataflash(int channel, char *name, int IDsize, int nr_pages, int pagesize, int pageoffset)
+{
+	struct mtd_info *device;
+	struct dataflash_local *priv;
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+	char mtdID[14];
+#endif
+
+	if (nr_devices >= DATAFLASH_MAX_DEVICES) {
+		printk(KERN_ERR "at91_dataflash: Too many devices detected\n");
+		return 0;
+	}
+
+	device = (struct mtd_info *) kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
+	if (!device)
+		return -ENOMEM;
+	memset(device, 0, sizeof(struct mtd_info));
+
+	device->name = name;
+	device->size = nr_pages * pagesize;
+	device->erasesize = pagesize;
+	device->module = THIS_MODULE;
+	device->type = MTD_NORFLASH;
+	device->flags = MTD_CAP_NORFLASH;
+	device->erase = at91_dataflash_erase;
+	device->read = at91_dataflash_read;
+	device->write = at91_dataflash_write;
+
+	priv = (struct dataflash_local *) kmalloc(sizeof(struct dataflash_local), GFP_KERNEL);
+	if (!priv) {
+		kfree(device);
+		return -ENOMEM;
+	}
+	memset(priv, 0, sizeof(struct dataflash_local));
+
+	priv->spi = channel;
+	priv->page_size = pagesize;
+	priv->page_offset = pageoffset;
+	device->priv = priv;
+
+	mtd_devices[nr_devices] = device;
+	nr_devices++;
+	printk("at91_dataflash: %s detected [spi%i] (%i bytes)\n", name, channel, device->size);
+
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+	sprintf(mtdID, "dataflash%i", nr_devices-1);
+	mtd_parts_nr = parse_cmdline_partitions(device, &mtd_parts, mtdID);
+#endif
+	if (mtd_parts_nr <= 0) {
+		mtd_parts = static_partitions;
+		mtd_parts_nr = NB_OF(static_partitions);
+	}
+
+	if (mtd_parts_nr > 0) {
+#ifdef DATAFLASH_ALWAYS_ADD_DEVICE
+		add_mtd_device(device);
+#endif
+		return add_mtd_partitions(device, mtd_parts, mtd_parts_nr);
+	}
+#endif
+	return add_mtd_device(device);		/* add whole device */
+}
+
+/*
+ * Detect and initialize DataFlash device connected to specified SPI channel.
+ *
+ *   Device            Density         ID code                 Nr Pages        Page Size       Page offset
+ *   AT45DB011B        1Mbit   (128K)  xx0011xx (0x0c)         512             264             9
+ *   AT45DB021B        2Mbit   (256K)  xx0101xx (0x14)         1025            264             9
+ *   AT45DB041B        4Mbit   (512K)  xx0111xx (0x1c)         2048            264             9
+ *   AT45DB081B        8Mbit   (1M)    xx1001xx (0x24)         4096            264             9
+ *   AT45DB0161B       16Mbit  (2M)    xx1011xx (0x2c)         4096            528             10
+ *   AT45DB0321B       32Mbit  (4M)    xx1101xx (0x34)         8192            528             10
+ *   AT45DB0642        64Mbit  (8M)    xx1111xx (0x3c)         8192            1056            11
+ *   AT45DB1282        128Mbit (16M)   xx0100xx (0x10)         16384           1056            11
+ */
+static int at91_dataflash_detect(int channel)
+{
+	int res = 0;
+	unsigned short status;
+
+	spi_access_bus(channel);
+	status = at91_dataflash_status();
+	if (status != 0xff) {			/* no dataflash device there */
+		switch (status & 0x3c) {
+			case 0x0c:	/* 0 0 1 1 */
+				res = add_dataflash(channel, "Atmel AT45DB011B", SZ_128K, 512, 264, 9);
+				break;
+			case 0x14:	/* 0 1 0 1 */
+				res = add_dataflash(channel, "Atmel AT45DB021B", SZ_256K, 1025, 264, 9);
+				break;
+			case 0x1c:	/* 0 1 1 1 */
+				res = add_dataflash(channel, "Atmel AT45DB041B", SZ_512K, 2048, 264, 9);
+				break;
+			case 0x24:	/* 1 0 0 1 */
+				res = add_dataflash(channel, "Atmel AT45DB081B", SZ_1M, 4096, 264, 9);
+				break;
+			case 0x2c:	/* 1 0 1 1 */
+				res = add_dataflash(channel, "Atmel AT45DB161B", SZ_2M, 4096, 528, 10);
+				break;
+			case 0x34:	/* 1 1 0 1 */
+				res = add_dataflash(channel, "Atmel AT45DB321B", SZ_4M, 8192, 528, 10);
+				break;
+			case 0x3c:	/* 1 1 1 1 */
+				res = add_dataflash(channel, "Atmel AT45DB642", SZ_8M, 8192, 1056, 11);
+				break;
+// Currently unsupported since Atmel removed the "Main Memory Program via Buffer" commands.
+//			case 0x10:	/* 0 1 0 0 */
+//				res = add_dataflash(channel, "Atmel AT45DB1282", SZ_16M, 16384, 1056, 11);
+//				break;
+			default:
+				printk(KERN_ERR "at91_dataflash: Unknown device (%x)\n", status & 0x3c);
+		}
+	}
+	spi_release_bus(channel);
+
+	return res;
+}
+
+static int __init at91_dataflash_init(void)
+{
+	spi_transfer_desc = kmalloc(sizeof(struct spi_transfer_list), GFP_KERNEL);
+	if (!spi_transfer_desc)
+		return -ENOMEM;
+
+	/* DataFlash (SPI chip select 0) */
+	at91_dataflash_detect(0);
+
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+	/* DataFlash card (SPI chip select 3) */
+	AT91_CfgPIO_DataFlashCard();
+	at91_dataflash_detect(3);
+#endif
+
+	return 0;
+}
+
+static void __exit at91_dataflash_exit(void)
+{
+	int i;
+
+	for (i = 0; i < DATAFLASH_MAX_DEVICES; i++) {
+		if (mtd_devices[i]) {
+#ifdef CONFIG_MTD_PARTITIONS
+			del_mtd_partitions(mtd_devices[i]);
+#else
+			del_mtd_device(mtd_devices[i]);
+#endif
+			kfree(mtd_devices[i]->priv);
+			kfree(mtd_devices[i]);
+		}
+	}
+	nr_devices = 0;
+	kfree(spi_transfer_desc);
+}
+
+
+EXPORT_NO_SYMBOLS;
+
+module_init(at91_dataflash_init);
+module_exit(at91_dataflash_exit);
+
+MODULE_LICENSE("GPL")
+MODULE_AUTHOR("Andrew Victor")
+MODULE_DESCRIPTION("DataFlash driver for Atmel AT91RM9200")
diff -urN linux-2.4.29/drivers/at91/mtd/at91_dataflash.h linux-2.4.29-uc1/drivers/at91/mtd/at91_dataflash.h
--- linux-2.4.29/drivers/at91/mtd/at91_dataflash.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/mtd/at91_dataflash.h	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,43 @@
+/*
+ * Atmel DataFlash driver for the Atmel AT91RM9200 (Thunder)
+ *
+ * (c) SAN People (Pty) Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef AT91_DATAFLASH_H
+#define AT91_DATAFLASH_H
+
+#define DATAFLASH_MAX_DEVICES	4	/* max number of dataflash devices */
+#undef	DATAFLASH_ALWAYS_ADD_DEVICE	/* always add whole device when using partitions? */
+
+#define OP_READ_CONTINUOUS	0xE8
+#define OP_READ_PAGE		0xD2
+#define OP_READ_BUFFER1		0xD4
+#define OP_READ_BUFFER2		0xD6
+#define OP_READ_STATUS		0xD7
+
+#define OP_ERASE_PAGE		0x81
+#define OP_ERASE_BLOCK		0x50
+
+#define OP_TRANSFER_BUF1	0x53
+#define OP_TRANSFER_BUF2	0x55
+#define OP_COMPARE_BUF1		0x60
+#define OP_COMPARE_BUF2		0x61
+
+#define OP_PROGRAM_VIA_BUF1	0x82
+#define OP_PROGRAM_VIA_BUF2	0x85
+
+struct dataflash_local
+{
+	int spi;			/* SPI chip-select number */
+
+	unsigned int page_size;		/* number of bytes per page */
+	unsigned short page_offset;	/* page offset in flash address */
+};
+
+#endif
diff -urN linux-2.4.29/drivers/at91/mtd/at91_nand.c linux-2.4.29-uc1/drivers/at91/mtd/at91_nand.c
--- linux-2.4.29/drivers/at91/mtd/at91_nand.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/mtd/at91_nand.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,328 @@
+/*
+ * drivers/at91/mtd/at91_nand.c
+ *
+ *  Copyright (c) 2003 Rick Bronson
+ *
+ *  Derived from drivers/mtd/nand/autcpu12.c
+ *	 Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
+ *
+ *  Derived from drivers/mtd/spia.c
+ *	 Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/sizes.h>
+
+#include <asm/arch/pio.h>
+#include "at91_nand.h"
+
+/*
+ * MTD structure for AT91 board
+ */
+static struct mtd_info *at91_mtd = NULL;
+static struct nand_chip *my_nand_chip = NULL;
+
+static int at91_fio_base;
+
+#ifdef CONFIG_MTD_PARTITIONS
+
+/*
+ * Define partitions for flash devices
+ */
+
+static struct mtd_partition partition_info32k[] = {
+	{ name: "AT91 NAND partition 1, kernel",
+	  offset:  0,
+	  size:   1 * SZ_1M },
+	{ name: "AT91 NAND partition 2, filesystem",
+	  offset:  1 * SZ_1M,
+	  size:   16 * SZ_1M },
+	{ name: "AT91 NAND partition 3a, storage",
+	  offset: (1 * SZ_1M) + (16 * SZ_1M),
+	  size:   1 * SZ_1M },
+	{ name: "AT91 NAND partition 3b, storage",
+	  offset: (2 * SZ_1M) + (16 * SZ_1M),
+	  size:   1 * SZ_1M },
+	{ name: "AT91 NAND partition 3c, storage",
+	  offset: (3 * SZ_1M) + (16 * SZ_1M),
+	  size:   1 * SZ_1M },
+	{ name: "AT91 NAND partition 3d, storage",
+	  offset: (4 * SZ_1M) + (16 * SZ_1M),
+	  size:   1 * SZ_1M },
+};
+
+static struct mtd_partition partition_info64k[] = {
+	{ name: "AT91 NAND partition 1, kernel",
+	  offset:  0,
+	  size:   1 * SZ_1M },
+	{ name: "AT91 NAND partition 2, filesystem",
+	  offset:  1 * SZ_1M,
+	  size:   16 * SZ_1M },
+	{ name: "AT91 NAND partition 3, storage",
+	  offset: (1 * SZ_1M) + (16 * SZ_1M),
+	  size:   47 * SZ_1M },
+};
+
+#endif
+
+/*
+ * Hardware specific access to control-lines
+ */
+static void at91_hwcontrol(int cmd)
+{
+	struct nand_chip *my_nand = my_nand_chip;
+	switch(cmd)
+	{
+	case NAND_CTL_SETCLE:
+		my_nand->IO_ADDR_W = at91_fio_base + AT91_SMART_MEDIA_CLE;
+		break;
+	case NAND_CTL_CLRCLE:
+		my_nand->IO_ADDR_W = at91_fio_base;
+		break;
+	case NAND_CTL_SETALE:
+		my_nand->IO_ADDR_W = at91_fio_base + AT91_SMART_MEDIA_ALE;
+		break;
+	case NAND_CTL_CLRALE:
+		my_nand->IO_ADDR_W = at91_fio_base;
+		break;
+	case NAND_CTL_SETNCE:
+		break;
+	case NAND_CTL_CLRNCE:
+		break;
+	}
+}
+
+/*
+ * Send command to NAND device
+ */
+static void at91_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
+{
+	register struct nand_chip *my_nand = mtd->priv;
+
+	/* Begin command latch cycle */
+	register unsigned long NAND_IO_ADDR = my_nand->IO_ADDR_W + AT91_SMART_MEDIA_CLE;
+
+	/*
+	 * Write out the command to the device.
+	 */
+	if (command != NAND_CMD_SEQIN)
+		writeb (command, NAND_IO_ADDR);
+	else {
+		if (mtd->oobblock == 256 && column >= 256) {
+			column -= 256;
+			writeb (NAND_CMD_RESET, NAND_IO_ADDR);
+			writeb (NAND_CMD_READOOB, NAND_IO_ADDR);
+			writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
+		}
+		else
+			if (mtd->oobblock == 512 && column >= 256) {
+				if (column < 512) {
+					column -= 256;
+					writeb (NAND_CMD_READ1, NAND_IO_ADDR);
+					writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
+				} else {
+					column -= 512;
+					writeb (NAND_CMD_READOOB, NAND_IO_ADDR);
+					writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
+				}
+			} else {
+				writeb (NAND_CMD_READ0, NAND_IO_ADDR);
+				writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
+			}
+	}
+
+	/* Set ALE and clear CLE to start address cycle */
+	NAND_IO_ADDR = at91_fio_base;
+
+	if (column != -1 || page_addr != -1)
+		NAND_IO_ADDR += AT91_SMART_MEDIA_ALE;
+
+	/* Serially input address */
+	if (column != -1)
+		writeb (column, NAND_IO_ADDR);
+	if (page_addr != -1) {
+		writeb ((unsigned char) (page_addr & 0xff), NAND_IO_ADDR);
+		writeb ((unsigned char) ((page_addr >> 8) & 0xff), NAND_IO_ADDR);
+		/* One more address cycle for higher density devices */
+		if (mtd->size & 0x0c000000) {
+			writeb ((unsigned char) ((page_addr >> 16) & 0x0f), NAND_IO_ADDR);
+		}
+	}
+
+	/* wait until command is processed */
+	while (!my_nand->dev_ready())
+		;
+}
+
+/*
+ * Read the Device Ready pin.
+ */
+static int at91_device_ready(void)
+{
+	return AT91_PIO_SmartMedia_RDY();
+}
+/*
+ * Main initialization routine
+ */
+static int __init at91_init (void)
+{
+	struct nand_chip *my_nand;
+	int err = 0;
+
+	/* Allocate memory for MTD device structure and private data */
+	at91_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), GFP_KERNEL);
+	if (!at91_mtd) {
+		printk ("Unable to allocate AT91 NAND MTD device structure.\n");
+		err = -ENOMEM;
+		goto out;
+	}
+
+	/* map physical adress */
+	at91_fio_base = (unsigned long) ioremap(AT91_SMARTMEDIA_BASE, SZ_8M);
+	if(!at91_fio_base) {
+		printk("ioremap AT91 NAND failed\n");
+		err = -EIO;
+		goto out_mtd;
+	}
+
+	/* Get pointer to private data */
+	my_nand_chip = my_nand = (struct nand_chip *) (&at91_mtd[1]);
+
+	/* Initialize structures */
+	memset((char *) at91_mtd, 0, sizeof(struct mtd_info));
+	memset((char *) my_nand, 0, sizeof(struct nand_chip));
+
+	/* Link the private data with the MTD structure */
+	at91_mtd->priv = my_nand;
+
+	/* Set address of NAND IO lines */
+	my_nand->IO_ADDR_R = at91_fio_base;
+	my_nand->IO_ADDR_W = at91_fio_base;
+	my_nand->hwcontrol = at91_hwcontrol;
+	my_nand->dev_ready = at91_device_ready;
+	my_nand->cmdfunc = at91_nand_command;	/* we need our own */
+	my_nand->eccmode = NAND_ECC_SOFT;	/* enable ECC */
+	/* 20 us command delay time */
+	my_nand->chip_delay = 20;
+
+	/* Setup Smart Media, first enable the address range of CS3 */
+	AT91_SYS->EBI_CSA |= AT91C_EBI_CS3A_SMC_SmartMedia;
+	/* set the bus interface characteristics based on
+	   tDS Data Set up Time 30 - ns
+	   tDH Data Hold Time 20 - ns
+	   tALS ALE Set up Time 20 - ns
+	   16ns at 60 MHz ~= 3  */
+#define AT91C_SM_ID_RWH	(5 << 28)		/* orig = 5 */
+#define AT91C_SM_RWH	(1 << 28)		/* orig = 1 */
+#define AT91C_SM_RWS	(0 << 24)		/* orig = 0 */
+#define AT91C_SM_TDF	(1 << 8)		/* orig = 1 */
+#define AT91C_SM_NWS	(5)			/* orig = 3 */
+	AT91_SYS->EBI_SMC2_CSR[3] = ( AT91C_SM_RWH | AT91C_SM_RWS |
+					 AT91C_SMC2_ACSS_STANDARD |
+					 AT91C_SMC2_DBW_8 | AT91C_SM_TDF |
+					 AT91C_SMC2_WSEN | AT91C_SM_NWS);
+
+	AT91_CfgPIO_SmartMedia();
+
+	if (AT91_PIO_SmartMedia_CardDetect())
+		printk ("No ");
+	printk ("SmartMedia card inserted.\n");
+
+	/* Scan to find existance of the device */
+	if (nand_scan (at91_mtd)) {
+		err = -ENXIO;
+		goto out_ior;
+	}
+
+	/* Allocate memory for internal data buffer */
+	my_nand->data_buf = kmalloc (sizeof(u_char) * (at91_mtd->oobblock + at91_mtd->oobsize), GFP_KERNEL);
+	if (!my_nand->data_buf) {
+		printk ("Unable to allocate AT91 NAND data buffer.\n");
+		err = -ENOMEM;
+		goto out_ior;
+	}
+
+	/* Allocate memory for internal data buffer */
+	my_nand->data_cache = kmalloc (sizeof(u_char) * (at91_mtd->oobblock + at91_mtd->oobsize), GFP_KERNEL);
+	if (!my_nand->data_cache) {
+		printk ("Unable to allocate AT91 NAND data cache.\n");
+		err = -ENOMEM;
+		goto out_buf;
+	}
+	my_nand->cache_page = -1;
+
+#ifdef CONFIG_MTD_PARTITIONS
+	/* Register the partitions */
+	switch(at91_mtd->size)
+	{
+	case SZ_32M:
+		err = add_mtd_partitions(at91_mtd, partition_info32k,
+				ARRAY_SIZE (partition_info32k));
+		break;
+	case SZ_64M:
+		err = add_mtd_partitions(at91_mtd, partition_info64k,
+				ARRAY_SIZE (partition_info64k));
+		break;
+	default:
+		printk ("Unsupported SmartMedia device\n");
+		err = -ENXIO;
+		goto out_cac;
+	}
+#else
+	err = add_mtd_device(at91_mtd);
+#endif
+	goto out;
+
+ out_cac:
+	kfree (my_nand->data_cache);
+ out_buf:
+	kfree (my_nand->data_buf);
+ out_ior:
+	iounmap((void *)at91_fio_base);
+ out_mtd:
+	kfree (at91_mtd);
+ out:
+	return err;
+}
+
+/*
+ * Clean up routine
+ */
+static void __exit at91_cleanup (void)
+{
+	struct nand_chip *my_nand = (struct nand_chip *) &at91_mtd[1];
+
+	/* Unregister partitions */
+	del_mtd_partitions(at91_mtd);
+
+	/* Unregister the device */
+	del_mtd_device (at91_mtd);
+
+	/* Free internal data buffers */
+	kfree (my_nand->data_buf);
+	kfree (my_nand->data_cache);
+
+	/* unmap physical adress */
+	iounmap((void *)at91_fio_base);
+
+	/* Free the MTD device structure */
+	kfree (at91_mtd);
+}
+
+module_init(at91_init);
+module_exit(at91_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Rick Bronson");
+MODULE_DESCRIPTION("Glue layer for SmartMediaCard on ATMEL AT91RM9200");
diff -urN linux-2.4.29/drivers/at91/mtd/at91_nand.h linux-2.4.29-uc1/drivers/at91/mtd/at91_nand.h
--- linux-2.4.29/drivers/at91/mtd/at91_nand.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/mtd/at91_nand.h	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,27 @@
+/*
+ * AT91RM9200 specific NAND (SmartMedia) defines
+ *
+ * (c) 2003 Rick Bronson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+#ifndef __AT91_NAND_H
+#define __AT91_NAND_H
+
+#define AT91_SMART_MEDIA_ALE (1 << 22)  /* our ALE is AD22 */
+#define AT91_SMART_MEDIA_CLE (1 << 21)  /* our CLE is AD21 */
+
+#endif
diff -urN linux-2.4.29/drivers/at91/mtd/Makefile linux-2.4.29-uc1/drivers/at91/mtd/Makefile
--- linux-2.4.29/drivers/at91/mtd/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/mtd/Makefile	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,19 @@
+# File: drivers/at91/mtd/Makefile
+#
+# Makefile for the Atmel AT91RM9200 MTD devices.
+#   Includes: NAND flash (SmartMedia) & DataFlash
+#
+
+O_TARGET := at91mtd.o
+
+export-objs :=
+
+obj-y	:=
+obj-m	:=
+obj-n	:=
+obj-	:=
+
+obj-$(CONFIG_MTD_AT91_DATAFLASH) += at91_dataflash.o
+obj-$(CONFIG_MTD_AT91_SMARTMEDIA) += at91_nand.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/at91/net/at91_ether.c linux-2.4.29-uc1/drivers/at91/net/at91_ether.c
--- linux-2.4.29/drivers/at91/net/at91_ether.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/net/at91_ether.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,877 @@
+/*
+ * Ethernet driver for the Atmel AT91RM9200 (Thunder)
+ *
+ * (c) SAN People (Pty) Ltd
+ *
+ * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc.
+ * Initial version by Rick Bronson 01/11/2003
+ *
+ * Intel LXT971A PHY support by Christopher Bahns & David Knickerbocker
+ *   (Polaroid Corporation)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/mii.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <asm/io.h>
+#include <linux/pci.h>
+#include <linux/crc32.h>
+#include <asm/uaccess.h>
+#include <linux/ethtool.h>
+
+#include <asm/arch/AT91RM9200_EMAC.h>
+#include <asm/arch/pio.h>
+#include "at91_ether.h"
+
+static struct net_device at91_dev;
+
+/* ........................... PHY INTERFACE ........................... */
+
+/*
+ * Enable the MDIO bit in MAC control register
+ * When not called from an interrupt-handler, access to the PHY must be
+ *  protected by a spinlock.
+ */
+static void enable_mdi(AT91PS_EMAC regs)
+{
+	regs->EMAC_CTL |= AT91C_EMAC_MPE;	/* enable management port */
+}
+
+/*
+ * Disable the MDIO bit in the MAC control register
+ */
+static void disable_mdi(AT91PS_EMAC regs)
+{
+	regs->EMAC_CTL &= ~AT91C_EMAC_MPE;	/* disable management port */
+}
+
+/*
+ * Write value to the a PHY register
+ * Note: MDI interface is assumed to already have been enabled.
+ */
+static void write_phy(AT91PS_EMAC regs, unsigned char phy_addr, unsigned char address, unsigned int value)
+{
+	regs->EMAC_MAN = (AT91C_EMAC_HIGH | AT91C_EMAC_CODE_802_3 | AT91C_EMAC_RW_W
+		| ((phy_addr & 0x1f) << 23) | (address << 18)) + (value & 0xffff);
+
+	/* Wait until IDLE bit in Network Status register is cleared */
+	// TODO: Enforce some maximum loop-count?
+	while (!(regs->EMAC_SR & AT91C_EMAC_IDLE)) { barrier(); }
+}
+
+/*
+ * Read value stored in a PHY register.
+ * Note: MDI interface is assumed to already have been enabled.
+ */
+static void read_phy(AT91PS_EMAC regs, unsigned char phy_addr, unsigned char address, unsigned int *value)
+{
+	regs->EMAC_MAN = AT91C_EMAC_HIGH | AT91C_EMAC_CODE_802_3 | AT91C_EMAC_RW_R
+		| ((phy_addr & 0x1f) << 23) | (address << 18);
+
+	/* Wait until IDLE bit in Network Status register is cleared */
+	// TODO: Enforce some maximum loop-count?
+	while (!(regs->EMAC_SR & AT91C_EMAC_IDLE)) { barrier(); }
+
+	*value = (regs->EMAC_MAN & 0x0000ffff);
+}
+
+/* ........................... PHY MANAGEMENT .......................... */
+
+/*
+ * Access the PHY to determine the current Link speed and Mode, and update the
+ * MAC accordingly.
+ * If no link or auto-negotiation is busy, then no changes are made.
+ * Returns:  0 : OK
+ *          -1 : No link
+ *          -2 : AutoNegotiation still in progress
+ */
+static int update_linkspeed(struct net_device *dev, AT91PS_EMAC regs) {
+	unsigned int bmsr, bmcr, lpa, mac_cfg;
+	unsigned int speed, duplex;
+
+	/* Link status is latched, so read twice to get current value */
+	read_phy(regs, 0, MII_BMSR, &bmsr);
+	read_phy(regs, 0, MII_BMSR, &bmsr);
+	if (!(bmsr & BMSR_LSTATUS)) return -1;			/* no link */
+
+	read_phy(regs, 0, MII_BMCR, &bmcr);
+	if (bmcr & BMCR_ANENABLE) {				/* AutoNegotiation is enabled */
+		if (!(bmsr & BMSR_ANEGCOMPLETE)) return -2;	/* auto-negotitation in progress */
+
+		read_phy(regs, 0, MII_LPA, &lpa);
+		if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF)) speed = SPEED_100;
+		else speed = SPEED_10;
+		if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL)) duplex = DUPLEX_FULL;
+		else duplex = DUPLEX_HALF;
+	} else {
+		speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10;
+		duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
+	}
+
+	/* Update the MAC */
+	mac_cfg = regs->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
+	if (speed == SPEED_100) {
+		if (duplex == DUPLEX_FULL)		/* 100 Full Duplex */
+			regs->EMAC_CFG = mac_cfg | AT91C_EMAC_SPD | AT91C_EMAC_FD;
+		else					/* 100 Half Duplex */
+			regs->EMAC_CFG = mac_cfg | AT91C_EMAC_SPD;
+	} else {
+		if (duplex == DUPLEX_FULL)		/* 10 Full Duplex */
+			regs->EMAC_CFG = mac_cfg | AT91C_EMAC_FD;
+		else					/* 10 Half Duplex */
+			regs->EMAC_CFG = mac_cfg;
+	}
+
+	printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex");
+	return 0;
+}
+
+/*
+ * Handle interrupts from the PHY
+ */
+static void at91ether_phy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *) dev_id;
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	AT91PS_EMAC emac = (AT91PS_EMAC) dev->base_addr;
+	int status;
+	unsigned int phy;
+
+	enable_mdi(emac);
+	if (lp->phy_type == MII_DM9161_ID)
+		read_phy(emac, 0, MII_DSINTR_REG, &phy);	/* ack interrupt in Davicom PHY */
+	else if (lp->phy_type == MII_LXT971A_ID)
+		read_phy(emac, 0, MII_ISINTS_REG, &phy);	/* ack interrupt in Intel PHY */
+		
+	status = AT91_SYS->PIOC_ISR;		/* acknowledge interrupt in PIO */
+
+	status = update_linkspeed(dev, emac);
+	if (status == -1) {			/* link is down */
+		netif_carrier_off(dev);
+		printk(KERN_INFO "%s: Link down.\n", dev->name);
+	} else if (status == -2) {		/* auto-negotiation in progress */
+		/* Do nothing - another interrupt generated when negotiation complete */
+	} else {				/* link is operational */
+		netif_carrier_on(dev);
+	}
+	disable_mdi(emac);
+}
+
+/*
+ * Initialize and enable the PHY interrupt when link-state changes
+ */
+static void enable_phyirq(struct net_device *dev, AT91PS_EMAC regs)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	unsigned int dsintr, status;
+
+	// TODO: Check error code.  Really need a generic PIO (interrupt)
+	// layer since we're really only interested in the PC4 (DK) or PC2 (CSB337) line.
+	(void) request_irq(AT91C_ID_PIOC, at91ether_phy_interrupt, 0, dev->name, dev);
+
+	status = AT91_SYS->PIOC_ISR;		/* clear any pending PIO interrupts */
+#ifdef CONFIG_MACH_CSB337
+	AT91_SYS->PIOC_IER = AT91C_PIO_PC2;	/* Enable interrupt */
+#else
+	AT91_SYS->PIOC_IER = AT91C_PIO_PC4;	/* Enable interrupt */
+#endif
+
+	spin_lock_irq(&lp->lock);
+	enable_mdi(regs);
+		
+	if (lp->phy_type == MII_DM9161_ID) {		/* for Davicom PHY */
+		read_phy(regs, 0, MII_DSINTR_REG, &dsintr);
+		dsintr = dsintr & ~0xf00;		/* clear bits 8..11 */
+		write_phy(regs, 0, MII_DSINTR_REG, dsintr);
+	}
+	else if (lp->phy_type == MII_LXT971A_ID) {	/* for Intel PHY */
+		read_phy(regs, 0, MII_ISINTE_REG, &dsintr);
+		dsintr = dsintr | 0xf2;			/* set bits 1, 4..7 */
+		write_phy(regs, 0, MII_ISINTE_REG, dsintr);
+	}
+		
+	disable_mdi(regs);
+	spin_unlock_irq(&lp->lock);
+}
+
+/*
+ * Disable the PHY interrupt
+ */
+static void disable_phyirq(struct net_device *dev, AT91PS_EMAC regs)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	unsigned int dsintr;
+
+	spin_lock_irq(&lp->lock);
+	enable_mdi(regs);
+
+	if (lp->phy_type == MII_DM9161_ID) {		/* for Davicom PHY */
+		read_phy(regs, 0, MII_DSINTR_REG, &dsintr);
+		dsintr = dsintr | 0xf00;			/* set bits 8..11 */
+		write_phy(regs, 0, MII_DSINTR_REG, dsintr);
+	}
+	else if (lp->phy_type == MII_LXT971A_ID) {	/* for Intel PHY */
+		read_phy(regs, 0, MII_ISINTE_REG, &dsintr);
+		dsintr = dsintr & ~0xf2;			/* clear bits 1, 4..7 */
+		write_phy(regs, 0, MII_ISINTE_REG, dsintr);
+	}
+
+	disable_mdi(regs);
+	spin_unlock_irq(&lp->lock);
+
+#ifdef CONFIG_MACH_CSB337
+	AT91_SYS->PIOC_IDR = AT91C_PIO_PC2;		/* Disable interrupt */
+#else
+	AT91_SYS->PIOC_IDR = AT91C_PIO_PC4;		/* Disable interrupt */
+#endif
+	free_irq(AT91C_ID_PIOC, dev);			/* Free interrupt handler */
+}
+
+/*
+ * Perform a software reset of the PHY.
+ */
+static void reset_phy(struct net_device *dev, AT91PS_EMAC regs)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	unsigned int bmcr;
+
+	spin_lock_irq(&lp->lock);
+	enable_mdi(regs);
+
+	/* Perform PHY reset */
+	write_phy(regs, 0, MII_BMCR, BMCR_RESET);
+
+	/* Wait until PHY reset is complete */
+	do {
+		read_phy(regs, 0, MII_BMCR, &bmcr);
+	} while (!(bmcr && BMCR_RESET));
+
+	disable_mdi(regs);
+	spin_unlock_irq(&lp->lock);
+}
+
+
+/* ......................... ADDRESS MANAGEMENT ........................ */
+
+/*
+ * Set the ethernet MAC address in dev->dev_addr
+ */
+static void get_mac_address(struct net_device *dev) {
+	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
+	char addr[6];
+	unsigned int hi, lo;
+
+	/* Check if bootloader set address in Specific-Address 1 */
+	hi = regs->EMAC_SA1H;
+	lo = regs->EMAC_SA1L;
+	addr[0] = (lo & 0xff);
+	addr[1] = (lo & 0xff00) >> 8;
+	addr[2] = (lo & 0xff0000) >> 16;
+	addr[3] = (lo & 0xff000000) >> 24;
+	addr[4] = (hi & 0xff);
+	addr[5] = (hi & 0xff00) >> 8;
+
+	if (is_valid_ether_addr(addr)) {
+		memcpy(dev->dev_addr, &addr, 6);
+		return;
+	}
+
+	/* Check if bootloader set address in Specific-Address 2 */
+	hi = regs->EMAC_SA2H;
+	lo = regs->EMAC_SA2L;
+	addr[0] = (lo & 0xff);
+	addr[1] = (lo & 0xff00) >> 8;
+	addr[2] = (lo & 0xff0000) >> 16;
+	addr[3] = (lo & 0xff000000) >> 24;
+	addr[4] = (hi & 0xff);
+	addr[5] = (hi & 0xff00) >> 8;
+
+	if (is_valid_ether_addr(addr)) {
+		memcpy(dev->dev_addr, &addr, 6);
+		return;
+	}
+}
+
+/*
+ * Program the hardware MAC address from dev->dev_addr.
+ */
+static void update_mac_address(struct net_device *dev)
+{
+	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
+
+	regs->EMAC_SA1L = (dev->dev_addr[3] << 24) | (dev->dev_addr[2] << 16) | (dev->dev_addr[1] << 8) | (dev->dev_addr[0]);
+	regs->EMAC_SA1H = (dev->dev_addr[5] << 8) | (dev->dev_addr[4]);
+}
+
+#ifdef AT91_ETHER_ADDR_CONFIGURABLE
+/*
+ * Store the new hardware address in dev->dev_addr, and update the MAC.
+ */
+static int set_mac_address(struct net_device *dev, void* addr)
+{
+	struct sockaddr *address = addr;
+
+	if (!is_valid_ether_addr(address->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memcpy(dev->dev_addr, address->sa_data, dev->addr_len);
+	update_mac_address(dev);
+
+	printk("%s: Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
+		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+
+	return 0;
+}
+#endif
+
+/*
+ * Add multicast addresses to the internal multicast-hash table.
+ */
+static void at91ether_sethashtable(struct net_device *dev, AT91PS_EMAC regs)
+{
+	struct dev_mc_list *curr;
+	unsigned char mc_filter[2];
+	unsigned int i, bitnr;
+
+	mc_filter[0] = mc_filter[1] = 0;
+
+	curr = dev->mc_list;
+	for (i = 0; i < dev->mc_count; i++, curr = curr->next) {
+		if (!curr) break;	/* unexpected end of list */
+
+		bitnr = ether_crc(ETH_ALEN, curr->dmi_addr) >> 26;
+		mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
+	}
+
+	regs->EMAC_HSH = mc_filter[1];
+	regs->EMAC_HSL = mc_filter[0];
+}
+
+/*
+ * Enable/Disable promiscuous and multicast modes.
+ */
+static void at91ether_set_rx_mode(struct net_device *dev)
+{
+	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
+
+	if (dev->flags & IFF_PROMISC) {			/* Enable promiscuous mode */
+		regs->EMAC_CFG |= AT91C_EMAC_CAF;
+	} else if (dev->flags & (~IFF_PROMISC)) {	/* Disable promiscuous mode */
+		regs->EMAC_CFG &= ~AT91C_EMAC_CAF;
+	}
+
+	if (dev->flags & IFF_ALLMULTI) {		/* Enable all multicast mode */
+		regs->EMAC_HSH = -1;
+		regs->EMAC_HSL = -1;
+		regs->EMAC_CFG |= AT91C_EMAC_MTI;
+	} else if (dev->mc_count > 0) {			/* Enable specific multicasts */
+		at91ether_sethashtable(dev, regs);
+		regs->EMAC_CFG |= AT91C_EMAC_MTI;
+	} else if (dev->flags & (~IFF_ALLMULTI)) {	/* Disable all multicast mode */
+		regs->EMAC_HSH = 0;
+		regs->EMAC_HSL = 0;
+		regs->EMAC_CFG &= ~AT91C_EMAC_MTI;
+	}
+}
+
+/* ............................... IOCTL ............................... */
+
+static int mdio_read(struct net_device *dev, int phy_id, int location)
+{
+	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
+	unsigned int value;
+
+	read_phy(regs, phy_id, location, &value);
+	return value;
+}
+
+static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
+{
+	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
+
+	write_phy(regs, phy_id, location, value);
+}
+
+/*
+ * ethtool support.
+ */
+static int at91ether_ethtool_ioctl (struct net_device *dev, void *useraddr)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
+	u32 ethcmd;
+	int res = 0;
+
+	if (copy_from_user (&ethcmd, useraddr, sizeof (ethcmd)))
+		return -EFAULT;
+
+	spin_lock_irq(&lp->lock);
+	enable_mdi(regs);
+
+	switch (ethcmd) {
+	case ETHTOOL_GSET: {
+		struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+		res = mii_ethtool_gset(&lp->mii, &ecmd);
+		if (lp->phy_media == PORT_FIBRE) {		/* override media type since mii.c doesn't know */
+			ecmd.supported = SUPPORTED_FIBRE;
+			ecmd.port = PORT_FIBRE;
+		}
+		if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
+			res = -EFAULT;
+		break;
+	}
+	case ETHTOOL_SSET: {
+		struct ethtool_cmd ecmd;
+		if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
+			res = -EFAULT;
+		else
+			res = mii_ethtool_sset(&lp->mii, &ecmd);
+		break;
+	}
+	case ETHTOOL_NWAY_RST: {
+		res = mii_nway_restart(&lp->mii);
+		break;
+	}
+	case ETHTOOL_GLINK: {
+		struct ethtool_value edata = { ETHTOOL_GLINK };
+		edata.data = mii_link_ok(&lp->mii);
+		if (copy_to_user(useraddr, &edata, sizeof(edata)))
+			res = -EFAULT;
+		break;
+	}
+	default:
+		res = -EOPNOTSUPP;
+	}
+
+	disable_mdi(regs);
+	spin_unlock_irq(&lp->lock);
+
+	return res;
+}
+
+/*
+ * User-space ioctl interface.
+ */
+static int at91ether_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	switch(cmd) {
+	case SIOCETHTOOL:
+		return at91ether_ethtool_ioctl(dev, (void *) rq->ifr_data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+/* ................................ MAC ................................ */
+
+/*
+ * Initialize and start the Receiver and Transmit subsystems
+ */
+static void at91ether_start(struct net_device *dev)
+{
+	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	int i;
+	struct recv_desc_bufs *dlist, *dlist_phys;
+
+	dlist = lp->dlist;
+	dlist_phys = lp->dlist_phys;
+
+	for (i = 0; i < MAX_RX_DESCR; i++) {
+		dlist->descriptors[i].addr = (unsigned int) &dlist_phys->recv_buf[i][0];
+		dlist->descriptors[i].size = 0;
+	}
+
+	/* Set the Wrap bit on the last descriptor */
+	dlist->descriptors[i-1].addr |= EMAC_DESC_WRAP;
+
+	/* Reset buffer index */
+	lp->rxBuffIndex = 0;
+
+	/* Program address of descriptor list in Rx Buffer Queue register */
+	regs->EMAC_RBQP = (AT91_REG) dlist_phys;
+
+	/* Enable Receive and Transmit */
+	regs->EMAC_CTL |= (AT91C_EMAC_RE | AT91C_EMAC_TE);
+}
+
+/*
+ * Open the ethernet interface
+ */
+static int at91ether_open(struct net_device *dev)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
+
+        if (!is_valid_ether_addr(dev->dev_addr))
+        	return -EADDRNOTAVAIL;
+
+	AT91_SYS->PMC_PCER = 1 << AT91C_ID_EMAC;	/* Re-enable Peripheral clock */
+	regs->EMAC_CTL |= AT91C_EMAC_CSR;		/* Clear internal statistics */
+
+	/* Enable PHY interrupt */
+	enable_phyirq(dev, regs);
+
+	/* Enable MAC interrupts */
+	regs->EMAC_IER = AT91C_EMAC_RCOM | AT91C_EMAC_RBNA
+			| AT91C_EMAC_TUND | AT91C_EMAC_RTRY | AT91C_EMAC_TCOM
+			| AT91C_EMAC_ROVR | AT91C_EMAC_HRESP;
+
+	/* Determine current link speed */
+	spin_lock_irq(&lp->lock);
+	enable_mdi(regs);
+	(void) update_linkspeed(dev, regs);
+	disable_mdi(regs);
+	spin_unlock_irq(&lp->lock);
+
+	at91ether_start(dev);
+	netif_start_queue(dev);
+	return 0;
+}
+
+/*
+ * Close the interface
+ */
+static int at91ether_close(struct net_device *dev)
+{
+	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
+
+	/* Disable Receiver and Transmitter */
+	regs->EMAC_CTL &= ~(AT91C_EMAC_TE | AT91C_EMAC_RE);
+
+	/* Disable PHY interrupt */
+	disable_phyirq(dev, regs);
+
+	/* Disable MAC interrupts */
+	regs->EMAC_IDR = AT91C_EMAC_RCOM | AT91C_EMAC_RBNA
+			| AT91C_EMAC_TUND | AT91C_EMAC_RTRY | AT91C_EMAC_TCOM
+			| AT91C_EMAC_ROVR | AT91C_EMAC_HRESP;
+
+	netif_stop_queue(dev);
+
+	AT91_SYS->PMC_PCDR = 1 << AT91C_ID_EMAC;	/* Disable Peripheral clock */
+
+	return 0;
+}
+
+/*
+ * Transmit packet.
+ */
+static int at91ether_tx(struct sk_buff *skb, struct net_device *dev)
+{
+	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+
+	if (regs->EMAC_TSR & AT91C_EMAC_BNQ) {
+		netif_stop_queue(dev);
+
+		/* Store packet information (to free when Tx completed) */
+		lp->skb = skb;
+		lp->skb_length = skb->len;
+		lp->skb_physaddr = pci_map_single(NULL, skb->data, skb->len, PCI_DMA_TODEVICE);
+		lp->stats.tx_bytes += skb->len;
+
+		/* Set address of the data in the Transmit Address register */
+		regs->EMAC_TAR = lp->skb_physaddr;
+		/* Set length of the packet in the Transmit Control register */
+		regs->EMAC_TCR = skb->len;
+
+		dev->trans_start = jiffies;
+	} else {
+		printk(KERN_ERR "at91_ether.c: at91ether_tx() called, but device is busy!\n");
+		return 1;	/* if we return anything but zero, dev.c:1055 calls kfree_skb(skb)
+				on this skb, he also reports -ENETDOWN and printk's, so either
+				we free and return(0) or don't free and return 1 */
+	}
+
+	return 0;
+}
+
+/*
+ * Update the current statistics from the internal statistics registers.
+ */
+static struct net_device_stats *at91ether_stats(struct net_device *dev)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
+	int ale, lenerr, seqe, lcol, ecol;
+
+	if (netif_running(dev)) {
+		lp->stats.rx_packets += regs->EMAC_OK;			/* Good frames received */
+		ale = regs->EMAC_ALE;
+		lp->stats.rx_frame_errors += ale;			/* Alignment errors */
+		lenerr = regs->EMAC_ELR + regs->EMAC_USF;
+		lp->stats.rx_length_errors += lenerr;			/* Excessive Length or Undersize Frame error */
+		seqe = regs->EMAC_SEQE;
+		lp->stats.rx_crc_errors += seqe;			/* CRC error */
+		lp->stats.rx_fifo_errors += regs->EMAC_DRFC;		/* Receive buffer not available */
+		lp->stats.rx_errors += (ale + lenerr + seqe + regs->EMAC_CDE + regs->EMAC_RJB);
+
+		lp->stats.tx_packets += regs->EMAC_FRA;			/* Frames successfully transmitted */
+		lp->stats.tx_fifo_errors += regs->EMAC_TUE;		/* Transmit FIFO underruns */
+		lp->stats.tx_carrier_errors += regs->EMAC_CSE;		/* Carrier Sense errors */
+		lp->stats.tx_heartbeat_errors += regs->EMAC_SQEE;	/* Heartbeat error */
+
+		lcol = regs->EMAC_LCOL;
+		ecol = regs->EMAC_ECOL;
+		lp->stats.tx_window_errors += lcol;			/* Late collisions */
+		lp->stats.tx_aborted_errors += ecol;			/* 16 collisions */
+
+		lp->stats.collisions += (regs->EMAC_SCOL + regs->EMAC_MCOL + lcol + ecol);
+	}
+	return &lp->stats;
+}
+
+/*
+ * Extract received frame from buffer descriptors and sent to upper layers.
+ * (Called from interrupt context)
+ */
+static void at91ether_rx(struct net_device *dev)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	struct recv_desc_bufs *dlist;
+	unsigned char *p_recv;
+	struct sk_buff *skb;
+	unsigned int pktlen;
+
+	dlist = lp->dlist;
+	while (dlist->descriptors[lp->rxBuffIndex].addr & EMAC_DESC_DONE) {
+		p_recv = dlist->recv_buf[lp->rxBuffIndex];
+		pktlen = dlist->descriptors[lp->rxBuffIndex].size & 0x7ff;	/* Length of frame including FCS */
+		skb = alloc_skb(pktlen + 2, GFP_ATOMIC);
+		if (skb != NULL) {
+			skb_reserve(skb, 2);
+			memcpy(skb_put(skb, pktlen), p_recv, pktlen);
+
+			skb->dev = dev;
+			skb->protocol = eth_type_trans(skb, dev);
+			skb->len = pktlen;
+			dev->last_rx = jiffies;
+			lp->stats.rx_bytes += pktlen;
+			netif_rx(skb);
+		}
+		else {
+			lp->stats.rx_dropped += 1;
+			printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
+		}
+
+		if (dlist->descriptors[lp->rxBuffIndex].size & EMAC_MULTICAST)
+			lp->stats.multicast++;
+
+		dlist->descriptors[lp->rxBuffIndex].addr &= ~EMAC_DESC_DONE;	/* reset ownership bit */
+		if (lp->rxBuffIndex == MAX_RX_DESCR-1)				/* wrap after last buffer */
+			lp->rxBuffIndex = 0;
+		else
+			lp->rxBuffIndex++;
+	}
+}
+
+/*
+ * MAC interrupt handler
+ */
+static void at91ether_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *) dev_id;
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	AT91PS_EMAC emac = (AT91PS_EMAC) dev->base_addr;
+	unsigned long intstatus;
+
+	/* MAC Interrupt Status register indicates what interrupts are pending.
+	   It is automatically cleared once read. */
+	intstatus = emac->EMAC_ISR;
+
+	if (intstatus & AT91C_EMAC_RCOM)		/* Receive complete */
+		at91ether_rx(dev);
+
+	if (intstatus & AT91C_EMAC_TCOM) {		/* Transmit complete */
+		/* The TCOM bit is set even if the transmission failed. */
+		if (intstatus & (AT91C_EMAC_TUND | AT91C_EMAC_RTRY))
+			lp->stats.tx_errors += 1;
+
+		dev_kfree_skb_irq(lp->skb);
+		pci_unmap_single(NULL, lp->skb_physaddr, lp->skb_length, PCI_DMA_TODEVICE);
+		netif_wake_queue(dev);
+	}
+
+	if (intstatus & AT91C_EMAC_RBNA)
+		printk("%s: RBNA error\n", dev->name);
+	if (intstatus & AT91C_EMAC_ROVR)
+		printk("%s: ROVR error\n", dev->name);
+}
+
+/*
+ * Initialize the ethernet interface
+ */
+static int at91ether_setup(struct net_device *dev, unsigned long phy_type)
+{
+	struct at91_private *lp;
+	AT91PS_EMAC regs;
+	static int already_initialized = 0;
+	unsigned int val;
+
+	if (already_initialized)
+		return 0;
+
+	dev = init_etherdev(dev, sizeof(struct at91_private));
+	dev->base_addr = AT91C_VA_BASE_EMAC;
+	dev->irq = AT91C_ID_EMAC;
+	SET_MODULE_OWNER(dev);
+
+	/* Install the interrupt handler */
+	if (request_irq(dev->irq, at91ether_interrupt, 0, dev->name, dev))
+		return -EBUSY;
+
+	/* Allocate memory for private data structure */
+	lp = (struct at91_private *) kmalloc(sizeof(struct at91_private), GFP_KERNEL);
+	if (lp == NULL) {
+		free_irq(dev->irq, dev);
+		return -ENOMEM;
+	}
+	memset(lp, 0, sizeof(struct at91_private));
+	dev->priv = lp;
+
+	/* Allocate memory for DMA Receive descriptors */
+	lp->dlist = (struct recv_desc_bufs *) consistent_alloc(GFP_DMA | GFP_KERNEL, sizeof(struct recv_desc_bufs), (dma_addr_t *) &lp->dlist_phys);
+	if (lp->dlist == NULL) {
+		kfree(dev->priv);
+		free_irq(dev->irq, dev);
+		return -ENOMEM;
+	}
+
+	spin_lock_init(&lp->lock);
+
+	ether_setup(dev);
+	dev->open = at91ether_open;
+	dev->stop = at91ether_close;
+	dev->hard_start_xmit = at91ether_tx;
+	dev->get_stats = at91ether_stats;
+	dev->set_multicast_list = at91ether_set_rx_mode;
+	dev->do_ioctl = at91ether_ioctl;
+
+#ifdef AT91_ETHER_ADDR_CONFIGURABLE
+	dev->set_mac_address = set_mac_address;
+#endif
+
+	get_mac_address(dev);		/* Get ethernet address and store it in dev->dev_addr */
+	update_mac_address(dev);	/* Program ethernet address into MAC */
+
+	regs = (AT91PS_EMAC) dev->base_addr;
+	regs->EMAC_CTL = 0;
+
+#ifdef CONFIG_AT91_ETHER_RMII
+	regs->EMAC_CFG = AT91C_EMAC_BIG | AT91C_EMAC_RMII;
+#else
+	regs->EMAC_CFG = AT91C_EMAC_BIG;
+#endif
+	if (phy_type == MII_LXT971A_ID)
+		regs->EMAC_CFG |= AT91C_EMAC_CLK_HCLK_64;	/* MDIO clock = system clock/64 */
+
+	if (phy_type == MII_DM9161_ID) {
+		spin_lock_irq(&lp->lock);
+		enable_mdi(regs);
+
+		read_phy(regs, 0, MII_DSCR_REG, &val);
+		if ((val & (1 << 10)) == 0)			/* DSCR bit 10 is 0 -- fiber mode */
+			lp->phy_media = PORT_FIBRE;
+
+		disable_mdi(regs);
+		spin_unlock_irq(&lp->lock);
+	}
+
+	lp->mii.dev = dev;		/* Support for ethtool */
+	lp->mii.mdio_read = mdio_read;
+	lp->mii.mdio_write = mdio_write;
+	
+	lp->phy_type = phy_type;	/* Type of PHY connected */
+
+	/* Determine current link speed */
+	spin_lock_irq(&lp->lock);
+	enable_mdi(regs);
+	(void) update_linkspeed(dev, regs);
+	disable_mdi(regs);
+	spin_unlock_irq(&lp->lock);
+
+	/* Display ethernet banner */
+	printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%02x:%02x:%02x:%02x:%02x:%02x)\n",
+		dev->name, (uint) dev->base_addr, dev->irq,
+		regs->EMAC_CFG & AT91C_EMAC_SPD ? "100-" : "10-",
+		regs->EMAC_CFG & AT91C_EMAC_FD ? "FullDuplex" : "HalfDuplex",
+		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+	if (phy_type == MII_DM9161_ID)
+		printk(KERN_INFO "%s: Davicom 9196 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)");
+	else if (phy_type == MII_LXT971A_ID)
+		printk(KERN_INFO "%s: Intel LXT971A PHY\n", dev->name);
+
+	already_initialized = 1;
+	return 0;
+}
+
+/*
+ * Detect MAC and PHY and perform initialization
+ */
+static int at91ether_probe(struct net_device *dev)
+{
+	AT91PS_EMAC regs = (AT91PS_EMAC) AT91C_VA_BASE_EMAC;
+	unsigned int phyid1, phyid2;
+	int detected = -1;
+
+	/* Configure the hardware - RMII vs MII mode */
+#ifdef CONFIG_AT91_ETHER_RMII
+	AT91_CfgPIO_EMAC_RMII();
+#else
+	AT91_CfgPIO_EMAC_MII();
+#endif
+
+	AT91_CfgPIO_EMAC_PHY();				/* Configure PHY interrupt */
+	AT91_SYS->PMC_PCER = 1 << AT91C_ID_EMAC;	/* Enable Peripheral clock */
+
+	/* Read the PHY ID registers */
+	enable_mdi(regs);
+	read_phy(regs, 0, MII_PHYSID1, &phyid1);
+	read_phy(regs, 0, MII_PHYSID2, &phyid2);
+	disable_mdi(regs);
+
+	/* Davicom 9161: PHY_ID1 = 0x181  PHY_ID2 = B881 */
+	if (((phyid1 << 16) | (phyid2 & 0xfff0)) == MII_DM9161_ID) {
+		detected = at91ether_setup(dev, MII_DM9161_ID);
+	}
+	/* Intel LXT971A: PHY_ID1 = 0x13  PHY_ID2 = 78E0 */
+	else if (((phyid1 << 16) | (phyid2 & 0xfff0)) == MII_LXT971A_ID) {
+		detected = at91ether_setup(dev, MII_LXT971A_ID);
+	}
+
+	AT91_SYS->PMC_PCDR = 1 << AT91C_ID_EMAC;	/* Disable Peripheral clock */
+
+	return detected;
+}
+
+static int __init at91ether_init(void)
+{
+	if (!at91ether_probe(&at91_dev))
+		return register_netdev(&at91_dev);
+
+	return -1;
+}
+
+static void __exit at91ether_exit(void)
+{
+	unregister_netdev(&at91_dev);
+}
+
+module_init(at91ether_init)
+module_exit(at91ether_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("AT91RM9200 EMAC Ethernet driver");
+MODULE_AUTHOR("Andrew Victor");
diff -urN linux-2.4.29/drivers/at91/net/at91_ether.h linux-2.4.29-uc1/drivers/at91/net/at91_ether.h
--- linux-2.4.29/drivers/at91/net/at91_ether.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/net/at91_ether.h	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,81 @@
+/*
+ * Ethernet driver for the Atmel AT91RM9200 (Thunder)
+ *
+ * (c) SAN People (Pty) Ltd
+ *
+ * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc.
+ * Initial version by Rick Bronson.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef AT91_ETHERNET
+#define AT91_ETHERNET
+
+#undef AT91_ETHER_ADDR_CONFIGURABLE	/* MAC address can be changed? */
+
+
+/* Davicom 9161 PHY */
+#define MII_DM9161_ID   0x0181b880
+
+/* Davicom specific registers */
+#define MII_DSCR_REG	16
+#define MII_DSCSR_REG   17
+#define MII_DSINTR_REG  21
+
+/* Intel LXT971A PHY */
+#define MII_LXT971A_ID	0x001378E0
+
+/* Intel specific registers */
+#define MII_ISINTE_REG	18
+#define MII_ISINTS_REG	19
+
+/* ........................................................................ */
+
+#define MAX_RBUFF_SZ	0x600		/* 1518 rounded up */
+#define MAX_RX_DESCR	9		/* max number of receive buffers */
+
+#define EMAC_DESC_DONE	0x00000001	/* bit for if DMA is done */
+#define EMAC_DESC_WRAP	0x00000002	/* bit for wrap */
+
+#define EMAC_BROADCAST	0x80000000	/* broadcast address */
+#define EMAC_MULTICAST	0x40000000	/* multicast address */
+#define EMAC_UNICAST	0x20000000	/* unicast address */
+
+struct rbf_t
+{
+	unsigned int addr;
+	unsigned long size;
+};
+
+struct recv_desc_bufs
+{
+	struct rbf_t descriptors[MAX_RX_DESCR];		/* must be on sizeof (rbf_t) boundary */
+	char recv_buf[MAX_RX_DESCR][MAX_RBUFF_SZ];	/* must be on long boundary */
+};
+
+struct at91_private
+{
+	struct net_device_stats stats;
+	struct mii_if_info mii;			/* ethtool support */
+
+	/* PHY */
+	unsigned long phy_type;			/* type of PHY (PHY_ID) */
+	spinlock_t lock;			/* lock for MDI interface */
+	short phy_media;			/* media interface type */
+
+	/* Transmit */
+	struct sk_buff *skb;			/* holds skb until xmit interrupt completes */
+	dma_addr_t skb_physaddr;		/* phys addr from pci_map_single */
+	int skb_length;				/* saved skb length for pci_unmap_single */
+
+	/* Receive */
+	int rxBuffIndex;			/* index into receive descriptor list */
+	struct recv_desc_bufs *dlist;		/* descriptor list address */
+	struct recv_desc_bufs *dlist_phys;	/* descriptor list physical address */
+};
+
+#endif
diff -urN linux-2.4.29/drivers/at91/net/Makefile linux-2.4.29-uc1/drivers/at91/net/Makefile
--- linux-2.4.29/drivers/at91/net/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/net/Makefile	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,15 @@
+# File: drivers/at91/net/Makefile
+#
+# Makefile for the Atmel AT91RM9200 ethernet device drivers
+#
+
+O_TARGET := at91net.o
+
+obj-y   :=
+obj-m   :=
+obj-n   :=
+obj-	:=
+
+obj-$(CONFIG_AT91_ETHER) += at91_ether.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/at91/rtc/at91_rtc.c linux-2.4.29-uc1/drivers/at91/rtc/at91_rtc.c
--- linux-2.4.29/drivers/at91/rtc/at91_rtc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/rtc/at91_rtc.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,441 @@
+/*
+ *	Real Time Clock interface for Linux on Atmel AT91RM9200
+ *
+ *	Copyright (c) 2002 Rick Bronson
+ *
+ *      Based on sa1100-rtc.c by Nils Faerber
+ *	Based on rtc.c by Paul Gortmaker
+ *	Date/time conversion routines taken from arch/arm/kernel/time.c
+ *			by Linus Torvalds and Russell King
+ *		and the GNU C Library
+ *	( ... I love the GPL ... just take what you need! ;)
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <asm/bitops.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <linux/rtc.h>
+
+#define AT91_RTC_FREQ	1
+#define EPOCH		1970
+
+/* Those are the bits from a classic RTC we want to mimic */
+#define AT91_RTC_IRQF	0x80	/* any of the following 3 is active */
+#define AT91_RTC_PF	0x40
+#define AT91_RTC_AF	0x20
+#define AT91_RTC_UF	0x10
+
+#define BCD2BIN(val) (((val)&15) + ((val)>>4)*10)
+#define BIN2BCD(val) ((((val)/10)<<4) + (val)%10)
+
+static unsigned long rtc_status = 0;
+static unsigned long rtc_irq_data;
+static unsigned int at91_alarm_year = EPOCH;
+
+static struct fasync_struct *at91_rtc_async_queue;
+static DECLARE_WAIT_QUEUE_HEAD(at91_rtc_wait);
+static DECLARE_WAIT_QUEUE_HEAD(at91_rtc_update);
+static spinlock_t at91_rtc_updlock;	/* some spinlocks for saving/restoring interrupt levels */
+extern spinlock_t at91_rtc_lock;
+
+static const unsigned char days_in_mo[] =
+    { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+#define is_leap(year) \
+	((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
+
+static const unsigned short int __mon_yday[2][13] =
+{
+	/* Normal years.  */
+	{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
+	/* Leap years.  */
+	{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
+};
+
+/*
+ * Returns day since start of the year [0-365]
+ *  (from drivers/char/efirtc.c)
+ */
+static inline int compute_yday(int year, int month, int day)
+{
+	return  __mon_yday[is_leap(year)][month] + day-1;
+}
+
+/*
+ * Set current time and date in RTC
+ */
+static void at91_rtc_settime(struct rtc_time *tval)
+{
+	unsigned long flags;
+
+	/* Stop Time/Calendar from counting */
+	AT91_SYS->RTC_CR |= (AT91C_RTC_UPDCAL | AT91C_RTC_UPDTIM);
+
+	spin_lock_irqsave(&at91_rtc_updlock, flags);	/* stop int's else we wakeup b4 we sleep */
+	AT91_SYS->RTC_IER = AT91C_RTC_ACKUPD;
+	interruptible_sleep_on(&at91_rtc_update);	/* wait for ACKUPD interrupt to hit */
+	spin_unlock_irqrestore(&at91_rtc_updlock, flags);
+	AT91_SYS->RTC_IDR = AT91C_RTC_ACKUPD;
+
+	AT91_SYS->RTC_TIMR = BIN2BCD(tval->tm_sec) << 0
+			| BIN2BCD(tval->tm_min) << 8
+			| BIN2BCD(tval->tm_hour) << 16;
+
+	AT91_SYS->RTC_CALR = BIN2BCD((tval->tm_year + 1900) / 100)	/* century */
+	    		| BIN2BCD(tval->tm_year % 100) << 8	/* year */
+	    		| BIN2BCD(tval->tm_mon + 1) << 16	/* tm_mon starts at zero */
+	    		| BIN2BCD(tval->tm_wday + 1) << 21	/* day of the week [0-6], Sunday=0 */
+			| BIN2BCD(tval->tm_mday) << 24;
+
+	/* Restart Time/Calendar */
+	AT91_SYS->RTC_CR &= ~(AT91C_RTC_UPDCAL | AT91C_RTC_UPDTIM);
+}
+
+/*
+ * Decode time/date into rtc_time structure
+ */
+static void at91_rtc_decodetime(AT91_REG *timereg, AT91_REG *calreg, struct rtc_time *tval)
+{
+	unsigned int time, date;
+
+	do {			/* must read twice in case it changes */
+		time = *timereg;
+		date = *calreg;
+	} while ((time != *timereg) || (date != *calreg));
+
+	tval->tm_sec = BCD2BIN((time & AT91C_RTC_SEC) >> 0);
+	tval->tm_min = BCD2BIN((time & AT91C_RTC_MIN) >> 8);
+	tval->tm_hour = BCD2BIN((time & AT91C_RTC_HOUR) >> 16);
+
+	/* The Calendar Alarm register does not have a field for
+	   the year - so these will return an invalid value.  When an
+	   alarm is set, at91_alarm_year wille store the current year. */
+	tval->tm_year = BCD2BIN(date & AT91C_RTC_CENT) * 100;		/* century */
+	tval->tm_year += BCD2BIN((date & AT91C_RTC_YEAR) >> 8);		/* year */
+
+	tval->tm_wday = BCD2BIN((date & AT91C_RTC_DAY) >> 21) - 1;	/* day of the week [0-6], Sunday=0 */
+	tval->tm_mon = BCD2BIN(((date & AT91C_RTC_MONTH) >> 16) - 1);
+	tval->tm_mday = BCD2BIN((date & AT91C_RTC_DATE) >> 24);
+}
+
+/*
+ * IRQ handler for the RTC
+ */
+static void at91_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int rtsr = AT91_SYS->RTC_SR & AT91_SYS->RTC_IMR;
+
+	/* update irq data & counter */
+	if (rtsr) {		/* this interrupt is shared!  Is it ours? */
+		if (rtsr & AT91C_RTC_ALARM)
+			rtc_irq_data |= (AT91_RTC_AF | AT91_RTC_IRQF);
+		if (rtsr & AT91C_RTC_SECEV)
+			rtc_irq_data |= (AT91_RTC_UF | AT91_RTC_IRQF);
+		if (rtsr & AT91C_RTC_ACKUPD)
+			wake_up_interruptible(&at91_rtc_update);
+		rtc_irq_data += 0x100;
+		AT91_SYS->RTC_SCCR = rtsr;		/* clear status reg */
+
+		/* wake up waiting process */
+		wake_up_interruptible(&at91_rtc_wait);
+		kill_fasync(&at91_rtc_async_queue, SIGIO, POLL_IN);
+	}
+}
+
+static int at91_rtc_open(struct inode *inode, struct file *file)
+{
+	if (test_and_set_bit(1, &rtc_status))
+		return -EBUSY;
+	rtc_irq_data = 0;
+	return 0;
+}
+
+static int at91_rtc_release(struct inode *inode, struct file *file)
+{
+	rtc_status = 0;
+	return 0;
+}
+
+static int at91_rtc_fasync(int fd, struct file *filp, int on)
+{
+	return fasync_helper(fd, filp, on, &at91_rtc_async_queue);
+}
+
+static unsigned int at91_rtc_poll(struct file *file, poll_table * wait)
+{
+	poll_wait(file, &at91_rtc_wait, wait);
+	return (rtc_irq_data) ? 0 : POLLIN | POLLRDNORM;
+}
+
+static ssize_t at91_rtc_read(struct file * file, char *buf, size_t count, loff_t * ppos)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	unsigned long data;
+	ssize_t retval;
+
+	if (count < sizeof(unsigned long))
+		return -EINVAL;
+
+	add_wait_queue(&at91_rtc_wait, &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
+	for (;;) {
+		spin_lock_irq(&at91_rtc_lock);
+		data = rtc_irq_data;
+		if (data != 0) {
+			rtc_irq_data = 0;
+			break;
+		}
+		spin_unlock_irq(&at91_rtc_lock);
+
+		if (file->f_flags & O_NONBLOCK) {
+			retval = -EAGAIN;
+			goto out;
+		}
+
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			goto out;
+		}
+
+		schedule();
+	}
+	spin_unlock_irq(&at91_rtc_lock);
+
+	data -= 0x100;		/* the first IRQ wasn't actually missed */
+	retval = put_user(data, (unsigned long *) buf);
+	if (!retval)
+		retval = sizeof(unsigned long);
+
+out:
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&at91_rtc_wait, &wait);
+	return retval;
+}
+
+/*
+ * Handle commands from user-space
+ */
+static int at91_rtc_ioctl(struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg)
+{
+	struct rtc_time tm, tm2;
+	int ret = 0;
+
+	spin_lock_irq(&at91_rtc_lock);
+	switch (cmd) {
+	case RTC_AIE_OFF:	/* alarm off */
+		AT91_SYS->RTC_IDR = AT91C_RTC_ALARM;
+		rtc_irq_data = 0;
+		break;
+	case RTC_AIE_ON:	/* alarm on */
+		AT91_SYS->RTC_IER = AT91C_RTC_ALARM;
+		rtc_irq_data = 0;
+		break;
+	case RTC_UIE_OFF:	/* update off */
+		AT91_SYS->RTC_IDR = AT91C_RTC_SECEV;
+		rtc_irq_data = 0;
+		break;
+	case RTC_UIE_ON:	/* update on */
+		AT91_SYS->RTC_IER = AT91C_RTC_SECEV;
+		rtc_irq_data = 0;
+		break;
+	case RTC_PIE_OFF:	/* periodic off */
+		AT91_SYS->RTC_IDR = AT91C_RTC_SECEV;
+		rtc_irq_data = 0;
+		break;
+	case RTC_PIE_ON:	/* periodic on */
+		AT91_SYS->RTC_IER = AT91C_RTC_SECEV;
+		rtc_irq_data = 0;
+		break;
+	case RTC_ALM_READ:	/* read alarm */
+		memset(&tm, 0, sizeof(struct rtc_time));
+		at91_rtc_decodetime(&(AT91_SYS->RTC_TIMALR), &(AT91_SYS->RTC_CALALR), &tm);
+		tm.tm_yday = compute_yday(tm.tm_year, tm.tm_mon, tm.tm_mday);
+		tm.tm_year = at91_alarm_year - 1900;
+		ret = copy_to_user((void *) arg, &tm, sizeof(tm)) ? -EFAULT : 0;
+		break;
+	case RTC_ALM_SET:	/* set alarm */
+		if (copy_from_user(&tm2, (struct rtc_time *) arg, sizeof(tm2)))
+			ret = -EFAULT;
+		else {
+			at91_rtc_decodetime(&(AT91_SYS->RTC_TIMR), &(AT91_SYS->RTC_CALR), &tm);
+			at91_alarm_year = tm.tm_year;
+			if ((unsigned) tm2.tm_hour < 24)	/* do some range checking */
+				tm.tm_hour = tm2.tm_hour;
+			if ((unsigned) tm2.tm_min < 60)
+				tm.tm_min = tm2.tm_min;
+			if ((unsigned) tm2.tm_sec < 60)
+				tm.tm_sec = tm2.tm_sec;
+			AT91_SYS->RTC_TIMALR = BIN2BCD(tm.tm_sec) << 0
+				| BIN2BCD(tm.tm_min) << 8
+				| BIN2BCD(tm.tm_hour) << 16
+				| AT91C_RTC_HOUREN | AT91C_RTC_MINEN
+				| AT91C_RTC_SECEN;
+			AT91_SYS->RTC_CALALR = BIN2BCD(tm.tm_mon + 1) << 16	/* tm_mon starts at zero */
+				| BIN2BCD(tm.tm_mday) << 24
+				| AT91C_RTC_DATEEN | AT91C_RTC_MONTHEN;
+		}
+		break;
+	case RTC_RD_TIME:	/* read time */
+		memset(&tm, 0, sizeof(struct rtc_time));
+		at91_rtc_decodetime(&(AT91_SYS->RTC_TIMR), &(AT91_SYS->RTC_CALR), &tm);
+		tm.tm_yday = compute_yday(tm.tm_year, tm.tm_mon, tm.tm_mday);
+		tm.tm_year = tm.tm_year - 1900;
+		ret = copy_to_user((void *) arg, &tm, sizeof(tm)) ? -EFAULT : 0;
+		break;
+	case RTC_SET_TIME:	/* set time */
+		if (!capable(CAP_SYS_TIME))
+			ret = -EACCES;
+		else {
+			if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(tm)))
+				ret = -EFAULT;
+			else {
+				int tm_year = tm.tm_year + 1900;
+				if (tm_year < EPOCH
+				    || (unsigned) tm.tm_mon >= 12
+				    || tm.tm_mday < 1
+				    || tm.tm_mday > (days_in_mo[tm.tm_mon] + (tm.tm_mon == 1 && is_leap(tm_year)))
+				    || (unsigned) tm.tm_hour >= 24
+				    || (unsigned) tm.tm_min >= 60
+				    || (unsigned) tm.tm_sec >= 60)
+					ret = -EINVAL;
+				else
+					at91_rtc_settime(&tm);
+			}
+		}
+		break;
+	case RTC_IRQP_READ:	/* read periodic alarm frequency */
+		ret = put_user(AT91_RTC_FREQ, (unsigned long *) arg);
+		break;
+	case RTC_IRQP_SET:	/* set periodic alarm frequency */
+		if (arg != AT91_RTC_FREQ)
+			ret = -EINVAL;
+		break;
+	case RTC_EPOCH_READ:	/* read epoch */
+		ret = put_user(EPOCH, (unsigned long *) arg);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	spin_unlock_irq(&at91_rtc_lock);
+	return ret;
+}
+
+/*
+ * Provide RTC information in /proc/driver/rtc
+ */
+static int at91_rtc_read_proc(char *page, char **start, off_t off,
+			      int count, int *eof, void *data)
+{
+	char *p = page;
+	int len;
+	struct rtc_time tm;
+
+	at91_rtc_decodetime(&(AT91_SYS->RTC_TIMR), &(AT91_SYS->RTC_CALR), &tm);
+	p += sprintf(p, "rtc_time\t: %02d:%02d:%02d\n"
+			"rtc_date\t: %04d-%02d-%02d\n"
+			"rtc_epoch\t: %04d\n",
+			tm.tm_hour, tm.tm_min, tm.tm_sec,
+			tm.tm_year, tm.tm_mon + 1, tm.tm_mday, EPOCH);
+	at91_rtc_decodetime(&(AT91_SYS->RTC_TIMALR), &(AT91_SYS->RTC_CALALR), &tm);
+	p += sprintf(p, "alrm_time\t: %02d:%02d:%02d\n"
+			"alrm_date\t: %04d-%02d-%02d\n",
+			tm.tm_hour, tm.tm_min, tm.tm_sec,
+			at91_alarm_year, tm.tm_mon + 1, tm.tm_mday);
+	p += sprintf(p, "alarm_IRQ\t: %s\n", (AT91_SYS->RTC_IMR & AT91C_RTC_ALARM) ? "yes" : "no");
+	p += sprintf(p, "update_IRQ\t: %s\n", (AT91_SYS->RTC_IMR & AT91C_RTC_ACKUPD) ? "yes" : "no");
+	p += sprintf(p, "periodic_IRQ\t: %s\n", (AT91_SYS->RTC_IMR & AT91C_RTC_SECEV) ? "yes" : "no");
+	p += sprintf(p, "periodic_freq\t: %ld\n", (unsigned long) AT91_RTC_FREQ);
+
+	len = (p - page) - off;
+	if (len < 0)
+		len = 0;
+
+	*eof = (len <= count) ? 1 : 0;
+	*start = page + off;
+
+	return len;
+}
+
+static struct file_operations at91_rtc_fops = {
+	owner:THIS_MODULE,
+	llseek:no_llseek,
+	read:at91_rtc_read,
+	poll:at91_rtc_poll,
+	ioctl:at91_rtc_ioctl,
+	open:at91_rtc_open,
+	release:at91_rtc_release,
+	fasync:at91_rtc_fasync,
+};
+
+static struct miscdevice at91_rtc_miscdev = {
+	minor:RTC_MINOR,
+	name:"rtc",
+	fops:&at91_rtc_fops,
+};
+
+/*
+ * Initialize and install RTC driver
+ */
+static int __init at91_rtc_init(void)
+{
+	int ret;
+
+	AT91_SYS->RTC_CR = 0;
+	AT91_SYS->RTC_MR = 0;	/* put in 24 hour format */
+	/* Disable all interrupts */
+	AT91_SYS->RTC_IDR = AT91C_RTC_ACKUPD | AT91C_RTC_ALARM | AT91C_RTC_SECEV | AT91C_RTC_TIMEV | AT91C_RTC_CALEV;
+
+	spin_lock_init(&at91_rtc_updlock);
+	spin_lock_init(&at91_rtc_lock);
+
+	misc_register(&at91_rtc_miscdev);
+	create_proc_read_entry("driver/rtc", 0, 0, at91_rtc_read_proc, NULL);
+	ret = request_irq(AT91C_ID_SYS, at91_rtc_interrupt, SA_SHIRQ,
+			"at91_rtc", &rtc_status);
+	if (ret) {
+		printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n", AT91C_ID_SYS);
+		remove_proc_entry("driver/rtc", NULL);
+		misc_deregister(&at91_rtc_miscdev);
+		return ret;
+	}
+
+	printk(KERN_INFO "AT91 Real Time Clock driver\n");
+	return 0;
+}
+
+/*
+ * Disable and remove the RTC driver
+ */
+static void __exit at91_rtc_exit(void)
+{
+	/* Disable all interrupts */
+	AT91_SYS->RTC_IDR = AT91C_RTC_ACKUPD | AT91C_RTC_ALARM | AT91C_RTC_SECEV | AT91C_RTC_TIMEV | AT91C_RTC_CALEV;
+	free_irq(AT91C_ID_SYS, &rtc_status);
+
+	rtc_status = 0;
+	remove_proc_entry("driver/rtc", NULL);
+	misc_deregister(&at91_rtc_miscdev);
+}
+
+module_init(at91_rtc_init);
+module_exit(at91_rtc_exit);
+
+MODULE_AUTHOR("Rick Bronson");
+MODULE_DESCRIPTION("AT91 Realtime Clock Driver (AT91_RTC)");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -urN linux-2.4.29/drivers/at91/rtc/Makefile linux-2.4.29-uc1/drivers/at91/rtc/Makefile
--- linux-2.4.29/drivers/at91/rtc/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/rtc/Makefile	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,15 @@
+# File: drivers/at91/rtc/Makefile
+#
+# Makefile for the Atmel AT91RM9200 real time clock device drivers
+#
+
+O_TARGET := at91rtc.o
+
+obj-y	:=
+obj-m	:=
+obj-n	:=
+obj-	:=
+
+obj-$(CONFIG_AT91_RTC) += at91_rtc.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/at91/serial/at91_serial.c linux-2.4.29-uc1/drivers/at91/serial/at91_serial.c
--- linux-2.4.29/drivers/at91/serial/at91_serial.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/serial/at91_serial.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,882 @@
+/*
+ *  linux/drivers/char/at91_serial.c
+ *
+ *  Driver for Atmel AT91RM9200 Serial ports
+ *
+ *  Copyright (c) Rick Bronson
+ *
+ *  Based on drivers/char/serial_sa1100.c, by Deep Blue Solutions Ltd.
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/config.h>
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+
+#include <asm/arch/AT91RM9200_USART.h>
+#include <asm/mach/serial_at91rm9200.h>
+#include <asm/arch/pio.h>
+
+
+#if defined(CONFIG_SERIAL_AT91_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+
+#define SERIAL_AT91_MAJOR	TTY_MAJOR
+#define CALLOUT_AT91_MAJOR	TTYAUX_MAJOR
+#define MINOR_START		64
+
+#define AT91C_VA_BASE_DBGU	((unsigned long) &(AT91_SYS->DBGU_CR))
+#define AT91_ISR_PASS_LIMIT	256
+
+#define UART_PUT_CR(port,v)	((AT91PS_USART)(port)->membase)->US_CR = v
+#define UART_GET_MR(port)	((AT91PS_USART)(port)->membase)->US_MR
+#define UART_PUT_MR(port,v)	((AT91PS_USART)(port)->membase)->US_MR = v
+#define UART_PUT_IER(port,v)	((AT91PS_USART)(port)->membase)->US_IER = v
+#define UART_PUT_IDR(port,v)	((AT91PS_USART)(port)->membase)->US_IDR = v
+#define UART_GET_IMR(port)	((AT91PS_USART)(port)->membase)->US_IMR
+#define UART_GET_CSR(port)	((AT91PS_USART)(port)->membase)->US_CSR
+#define UART_GET_CHAR(port)	((AT91PS_USART)(port)->membase)->US_RHR
+#define UART_PUT_CHAR(port,v)	((AT91PS_USART)(port)->membase)->US_THR = v
+#define UART_GET_BRGR(port)	((AT91PS_USART)(port)->membase)->US_BRGR
+#define UART_PUT_BRGR(port,v)	((AT91PS_USART)(port)->membase)->US_BRGR = v
+#define UART_PUT_RTOR(port,v)	((AT91PS_USART)(port)->membase)->US_RTOR = v
+
+// #define UART_GET_CR(port)	((AT91PS_USART)(port)->membase)->US_CR		// is write-only
+
+ /* PDC registers */
+#define UART_PUT_PTCR(port,v)	((AT91PS_USART)(port)->membase)->US_PTCR = v
+#define UART_PUT_RPR(port,v)	((AT91PS_USART)(port)->membase)->US_RPR = v
+#define UART_PUT_RCR(port,v)	((AT91PS_USART)(port)->membase)->US_RCR = v
+#define UART_GET_RCR(port)	((AT91PS_USART)(port)->membase)->US_RCR
+#define UART_PUT_RNPR(port,v)	((AT91PS_USART)(port)->membase)->US_RNPR = v
+#define UART_PUT_RNCR(port,v)	((AT91PS_USART)(port)->membase)->US_RNCR = v
+
+static struct tty_driver normal, callout;
+static struct tty_struct *at91_table[AT91C_NR_UART];
+static struct termios *at91_termios[AT91C_NR_UART], *at91_termios_locked[AT91C_NR_UART];
+static int (*at91_open)(struct uart_port *);
+static void (*at91_close)(struct uart_port *);
+
+const int at91_serialmap[AT91C_NR_UART] = AT91C_UART_MAP;
+
+/*
+ * We wrap our port structure around the generic uart_port.
+ */
+struct at91_serial_port {
+	struct uart_port	uart;
+};
+
+static struct at91_serial_port at91_ports[AT91C_NR_UART];
+
+#ifdef SUPPORT_SYSRQ
+static struct console at91_console;
+#endif
+
+/*
+ * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty.
+ */
+static u_int at91_tx_empty(struct uart_port *uart)
+{
+	return UART_GET_CSR(uart) & AT91C_US_TXEMPTY ? TIOCSER_TEMT : 0;
+}
+
+/*
+ * Set state of the modem control output lines
+ */
+static void at91_set_mctrl(struct uart_port *uart, u_int mctrl)
+{
+	unsigned int control = 0;
+
+	if (mctrl & TIOCM_RTS)
+		control |= AT91C_US_RTSEN;
+	else
+		control |= AT91C_US_RTSDIS;
+
+	if (mctrl & TIOCM_DTR)
+		control |= AT91C_US_DTREN;
+	else
+		control |=  AT91C_US_DTRDIS;
+
+	UART_PUT_CR(uart, control);
+}
+
+/*
+ * Get state of the modem control input lines
+ */
+static u_int at91_get_mctrl(struct uart_port *uart)
+{
+	unsigned int status, ret = 0;
+
+	status = UART_GET_CSR(uart);
+	if (status & AT91C_US_DCD)
+		ret |= TIOCM_CD;
+	if (status & AT91C_US_CTS)
+		ret |= TIOCM_CTS;
+	if (status & AT91C_US_DSR)
+		ret |= TIOCM_DSR;
+	if (status & AT91C_US_RI)
+		ret |= TIOCM_RI;
+
+	return ret;
+}
+
+/*
+ * Stop transmitting.
+ */
+static void at91_stop_tx(struct uart_port *uart, u_int from_tty)
+{
+	UART_PUT_IDR(uart, AT91C_US_TXRDY);
+	uart->read_status_mask &= ~AT91C_US_TXRDY;
+}
+
+/*
+ * Start transmitting.
+ */
+static void at91_start_tx(struct uart_port *uart, u_int from_tty)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	uart->read_status_mask |= AT91C_US_TXRDY;
+	UART_PUT_IER(uart, AT91C_US_TXRDY);
+	local_irq_restore(flags);
+}
+
+/*
+ * Stop receiving - port is in process of being closed.
+ */
+static void at91_stop_rx(struct uart_port *uart)
+{
+	UART_PUT_IDR(uart, AT91C_US_RXRDY);
+}
+
+/*
+ * Enable modem status interrupts
+ */
+static void at91_enable_ms(struct uart_port *uart)
+{
+	UART_PUT_IER(uart, AT91C_US_RIIC | AT91C_US_DSRIC | AT91C_US_DCDIC | AT91C_US_CTSIC);
+}
+
+/*
+ * Control the transmission of a break signal
+ */
+static void at91_break_ctl(struct uart_port *uart, int break_state)
+{
+	if (break_state != 0)
+		UART_PUT_CR(uart, AT91C_US_STTBRK);	/* start break */
+	else
+		UART_PUT_CR(uart, AT91C_US_STPBRK);	/* stop break */
+}
+
+/*
+ * Characters received (called from interrupt handler)
+ */
+static void at91_rx_chars(struct at91_serial_port *port, struct pt_regs *regs)
+{
+	struct uart_port *uart = &port->uart;
+	struct tty_struct *tty = uart->info->tty;
+	unsigned int status, ch, flg, ignored = 0;
+
+	status = UART_GET_CSR(uart);
+	while (status & (AT91C_US_RXRDY)) {
+		ch = UART_GET_CHAR(uart);
+
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			goto ignore_char;
+		uart->icount.rx++;
+
+		flg = TTY_NORMAL;
+
+		/*
+		 * note that the error handling code is
+		 * out of the main execution path
+		 */
+		if (status & (AT91C_US_PARE | AT91C_US_FRAME | AT91C_US_OVRE))
+			goto handle_error;
+
+		if (uart_handle_sysrq_char(uart, ch, regs))
+			goto ignore_char;
+
+	error_return:
+		*tty->flip.flag_buf_ptr++ = flg;
+		*tty->flip.char_buf_ptr++ = ch;
+		tty->flip.count++;
+	ignore_char:
+		status = UART_GET_CSR(uart);
+	}
+out:
+	tty_flip_buffer_push(tty);
+	return;
+
+handle_error:
+	if (status & (AT91C_US_PARE | AT91C_US_FRAME | AT91C_US_OVRE))
+		UART_PUT_CR(uart, AT91C_US_RSTSTA);	/* clear error */
+	if (status & (AT91C_US_PARE))
+		uart->icount.parity++;
+	else if (status & (AT91C_US_FRAME))
+		uart->icount.frame++;
+	if (status & (AT91C_US_OVRE))
+		uart->icount.overrun++;
+
+	if (status & uart->ignore_status_mask) {
+		if (++ignored > 100)
+			goto out;
+		goto ignore_char;
+	}
+
+	status &= uart->read_status_mask;
+
+	UART_PUT_CR(uart, AT91C_US_RSTSTA);	/* clear error */
+	if (status & AT91C_US_PARE)
+		flg = TTY_PARITY;
+	else if (status & AT91C_US_FRAME)
+		flg = TTY_FRAME;
+
+	if (status & AT91C_US_OVRE) {
+		/*
+		 * overrun does *not* affect the character
+		 * we read from the FIFO
+		 */
+		*tty->flip.flag_buf_ptr++ = flg;
+		*tty->flip.char_buf_ptr++ = ch;
+		tty->flip.count++;
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			goto ignore_char;
+		ch = 0;
+		flg = TTY_OVERRUN;
+	}
+#ifdef SUPPORT_SYSRQ
+	uart->sysrq = 0;
+#endif
+	goto error_return;
+}
+
+/*
+ * Transmit characters (called from interrupt handler)
+ */
+static void at91_tx_chars(struct at91_serial_port *port)
+{
+	struct uart_port *uart = &port->uart;
+	struct circ_buf *xmit = &uart->info->xmit;
+
+	if (uart->x_char) {
+		UART_PUT_CHAR(uart, uart->x_char);
+		uart->icount.tx++;
+		uart->x_char = 0;
+		return;
+	}
+
+	if (uart_circ_empty(xmit) || uart_tx_stopped(uart)) {
+		at91_stop_tx(uart, 0);
+		return;
+	}
+
+	while (UART_GET_CSR(uart) & AT91C_US_TXRDY) {
+		UART_PUT_CHAR(uart, xmit->buf[xmit->tail]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		uart->icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	}
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(uart);
+
+	if (uart_circ_empty(xmit))
+		at91_stop_tx(uart, 0);
+}
+
+/*
+ * Interrupt handler
+ */
+static void at91_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct at91_serial_port *port = dev_id;
+	struct uart_port *uart = &port->uart;
+	unsigned int status, pending, pass_counter = 0;
+
+	status = UART_GET_CSR(uart);
+	pending = status & uart->read_status_mask;
+	if (pending) {
+		do {
+			if (pending & AT91C_US_RXRDY)
+				at91_rx_chars(port, regs);
+
+			/* Clear the relevent break bits */
+			if (pending & AT91C_US_RXBRK) {
+				UART_PUT_CR(uart, AT91C_US_RSTSTA);
+				uart->icount.brk++;
+#ifdef SUPPORT_SYSRQ
+				if (uart->line == at91_console.index && !uart->sysrq) {
+					uart->sysrq = jiffies + HZ*5;
+				}
+#endif
+			}
+
+			// TODO: All reads to CSR will clear these interrupts!
+			if (pending & AT91C_US_RIIC) uart->icount.rng++;
+			if (pending & AT91C_US_DSRIC) uart->icount.dsr++;
+			if (pending & AT91C_US_DCDIC) {
+				uart->icount.dcd++;
+				uart_handle_dcd_change(uart, status & AT91C_US_DCD);
+			}
+			if (pending & AT91C_US_CTSIC) {
+				uart->icount.cts++;
+				uart_handle_cts_change(uart, status & AT91C_US_CTS);
+			}
+			if (pending & (AT91C_US_RIIC | AT91C_US_DSRIC | AT91C_US_DCDIC | AT91C_US_CTSIC))
+				wake_up_interruptible(&uart->info->delta_msr_wait);
+
+			if (pending & AT91C_US_TXRDY)
+				at91_tx_chars(port);
+
+			if (pass_counter++ > AT91_ISR_PASS_LIMIT)
+				break;
+
+			status = UART_GET_CSR(uart);
+			pending = status & uart->read_status_mask;
+		} while (pending);
+	}
+}
+
+/*
+ * Perform initialization and enable port for reception
+ */
+static int at91_startup(struct uart_port *uart)
+{
+	int retval;
+
+	/*
+	 * Allocate the IRQ
+	 */
+	retval = request_irq(uart->irq, at91_interrupt, SA_SHIRQ, "at91_serial", uart);
+	if (retval) {
+		printk("at91_serial: at91_startup - Can't get irq\n");
+		return retval;
+	}
+	/*
+	 * If there is a specific "open" function (to register
+	 * control line interrupts)
+	 */
+	if (at91_open) {
+		retval = at91_open(uart);
+		if (retval) {
+			free_irq(uart->irq, uart);
+			return retval;
+		}
+	}
+
+	/* Enable peripheral clock if required */
+	if (uart->irq != AT91C_ID_SYS)
+		AT91_SYS->PMC_PCER = 1 << uart->irq;
+
+	uart->read_status_mask = AT91C_US_RXRDY | AT91C_US_TXRDY | AT91C_US_OVRE
+			| AT91C_US_FRAME | AT91C_US_PARE | AT91C_US_RXBRK;
+	/*
+	 * Finally, clear and enable interrupts
+	 */
+	UART_PUT_IDR(uart, -1);
+	UART_PUT_CR(uart, AT91C_US_TXEN | AT91C_US_RXEN);	/* enable xmit & rcvr */
+	UART_PUT_IER(uart, AT91C_US_RXRDY);	/* do receive only */
+	return 0;
+}
+
+/*
+ * Disable the port
+ */
+static void at91_shutdown(struct uart_port *uart)
+{
+	/*
+	 * Free the interrupt
+	 */
+	free_irq(uart->irq, uart);
+
+	/*
+	 * If there is a specific "close" function (to unregister
+	 * control line interrupts)
+	 */
+	if (at91_close)
+		at91_close(uart);
+
+	/*
+	 * Disable all interrupts, port and break condition.
+	 */
+	UART_PUT_CR(uart, AT91C_US_RSTSTA);
+	UART_PUT_IDR(uart, -1);
+
+	/* Disable peripheral clock if required */
+	if (uart->irq != AT91C_ID_SYS)
+		AT91_SYS->PMC_PCDR = 1 << uart->irq;
+}
+
+static struct uart_ops at91_pops;		/* forward declaration */
+
+/*
+ * Change the port parameters
+ */
+static void at91_change_speed(struct uart_port *uart, u_int cflag, u_int iflag, u_int quot)
+{
+	unsigned long flags;
+	unsigned int mode, imr;
+
+	/* Get current mode register */
+	mode = UART_GET_MR(uart) & ~(AT91C_US_CHRL | AT91C_US_NBSTOP | AT91C_US_PAR);
+
+	/* byte size */
+	switch (cflag & CSIZE) {
+	case CS5:
+		mode |= AT91C_US_CHRL_5_BITS;
+		break;
+	case CS6:
+		mode |= AT91C_US_CHRL_6_BITS;
+		break;
+	case CS7:
+		mode |= AT91C_US_CHRL_7_BITS;
+		break;
+	default:
+		mode |= AT91C_US_CHRL_8_BITS;
+		break;
+	}
+
+	/* stop bits */
+	if (cflag & CSTOPB)
+		mode |= AT91C_US_NBSTOP_2_BIT;
+
+	/* parity */
+	if (cflag & PARENB) {
+		if (cflag & CMSPAR) {			/* Mark or Space parity */
+			if (cflag & PARODD)
+				mode |= AT91C_US_PAR_MARK;
+			else
+				mode |= AT91C_US_PAR_SPACE;
+		}
+		else if (cflag & PARODD)
+			mode |= AT91C_US_PAR_ODD;
+		else
+			mode |= AT91C_US_PAR_EVEN;
+	}
+	else
+		mode |= AT91C_US_PAR_NONE;
+
+	uart->read_status_mask |= AT91C_US_OVRE;
+	if (iflag & INPCK)
+		uart->read_status_mask |= AT91C_US_FRAME | AT91C_US_PARE;
+	if (iflag & (BRKINT | PARMRK))
+		uart->read_status_mask |= AT91C_US_RXBRK;
+
+	/*
+	 * Characters to ignore
+	 */
+	uart->ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		uart->ignore_status_mask |= (AT91C_US_FRAME | AT91C_US_PARE);
+	if (iflag & IGNBRK) {
+		uart->ignore_status_mask |= AT91C_US_RXBRK;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			uart->ignore_status_mask |= AT91C_US_OVRE;
+	}
+
+	// TODO: Ignore all characters if CREAD is set.
+
+	/* first, disable interrupts and drain transmitter */
+	local_irq_save(flags);
+	imr = UART_GET_IMR(uart);	/* get interrupt mask */
+	UART_PUT_IDR(uart, -1);		/* disable all interrupts */
+	local_irq_restore(flags);
+	while (!(UART_GET_CSR(uart) & AT91C_US_TXEMPTY)) { barrier(); }
+
+	/* disable receiver and transmitter */
+	UART_PUT_CR(uart, AT91C_US_TXDIS | AT91C_US_RXDIS);
+
+	/* set the parity, stop bits and data size */
+	UART_PUT_MR(uart, mode);
+
+	/* set the baud rate */
+	UART_PUT_BRGR(uart, quot);
+	UART_PUT_CR(uart, AT91C_US_TXEN | AT91C_US_RXEN);
+
+	/* restore interrupts */
+	UART_PUT_IER(uart, imr);
+
+	/* CTS flow-control and modem-status interrupts */
+	if (UART_ENABLE_MS(uart, cflag))
+		at91_pops.enable_ms(uart);
+}
+
+/*
+ * Return string describing the specified port
+ */
+static const char *at91_type(struct uart_port *uart)
+{
+	return uart->type == PORT_AT91RM9200 ? "AT91_SERIAL" : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'.
+ */
+static void at91_release_port(struct uart_port *uart)
+{
+	release_mem_region(uart->mapbase,
+		uart->mapbase == AT91C_VA_BASE_DBGU ? 512 : SZ_16K);
+}
+
+/*
+ * Request the memory region(s) being used by 'port'.
+ */
+static int at91_request_port(struct uart_port *uart)
+{
+	return request_mem_region(uart->mapbase,
+		uart->mapbase == AT91C_VA_BASE_DBGU ? 512 : SZ_16K,
+		"at91_serial") != NULL ? 0 : -EBUSY;
+
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void at91_config_port(struct uart_port *uart, int flags)
+{
+	if (flags & UART_CONFIG_TYPE) {
+		uart->type = PORT_AT91RM9200;
+		at91_request_port(uart);
+	}
+}
+
+/*
+ * Verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int at91_verify_port(struct uart_port *uart, struct serial_struct *ser)
+{
+	int ret = 0;
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_AT91RM9200)
+		ret = -EINVAL;
+	if (uart->irq != ser->irq)
+		ret = -EINVAL;
+	if (ser->io_type != SERIAL_IO_MEM)
+		ret = -EINVAL;
+	if (uart->uartclk / 16 != ser->baud_base)
+		ret = -EINVAL;
+	if ((void *)uart->mapbase != ser->iomem_base)
+		ret = -EINVAL;
+	if (uart->iobase != ser->port)
+		ret = -EINVAL;
+	if (ser->hub6 != 0)
+		ret = -EINVAL;
+	return ret;
+}
+
+static struct uart_ops at91_pops = {
+	tx_empty:	at91_tx_empty,
+	set_mctrl:	at91_set_mctrl,
+	get_mctrl:	at91_get_mctrl,
+	stop_tx:	at91_stop_tx,
+	start_tx:	at91_start_tx,
+	stop_rx:	at91_stop_rx,
+	enable_ms:	at91_enable_ms,
+	break_ctl:	at91_break_ctl,
+	startup:	at91_startup,
+	shutdown:	at91_shutdown,
+	change_speed:	at91_change_speed,
+	type:		at91_type,
+	release_port:	at91_release_port,
+	request_port:	at91_request_port,
+	config_port:	at91_config_port,
+	verify_port:	at91_verify_port,
+};
+
+void __init at91_init_ports(void)
+{
+	static int first = 1;
+	int i;
+
+	if (!first)
+		return;
+	first = 0;
+
+	for (i = 0; i < AT91C_NR_UART; i++) {
+		at91_ports[i].uart.iotype	= SERIAL_IO_MEM;
+		at91_ports[i].uart.flags	= ASYNC_BOOT_AUTOCONF;
+		at91_ports[i].uart.uartclk	= AT91C_MASTER_CLOCK;
+		at91_ports[i].uart.ops		= &at91_pops;
+		at91_ports[i].uart.fifosize	= 1;
+		at91_ports[i].uart.line		= i;
+	}
+}
+
+void __init at91_register_uart_fns(struct at91rm9200_port_fns *fns)
+{
+	if (fns->enable_ms)
+		at91_pops.enable_ms = fns->enable_ms;
+	if (fns->get_mctrl)
+		at91_pops.get_mctrl = fns->get_mctrl;
+	if (fns->set_mctrl)
+		at91_pops.set_mctrl = fns->set_mctrl;
+	at91_open          = fns->open;
+	at91_close         = fns->close;
+	at91_pops.pm       = fns->pm;
+	at91_pops.set_wake = fns->set_wake;
+}
+
+/*
+ * Setup ports.
+ */
+void __init at91_register_uart(int idx, int port)
+{
+	if ((idx < 0) || (idx >= AT91C_NR_UART)) {
+		printk(KERN_ERR __FUNCTION__ ": bad index number %d\n", idx);
+		return;
+	}
+
+	switch (port) {
+	case 0:
+		at91_ports[idx].uart.membase = (void *) AT91C_VA_BASE_US0;
+		at91_ports[idx].uart.mapbase = AT91C_VA_BASE_US0;
+		at91_ports[idx].uart.irq     = AT91C_ID_US0;
+		AT91_CfgPIO_USART0();
+		break;
+	case 1:
+		at91_ports[idx].uart.membase = (void *) AT91C_VA_BASE_US1;
+		at91_ports[idx].uart.mapbase = AT91C_VA_BASE_US1;
+		at91_ports[idx].uart.irq     = AT91C_ID_US1;
+		AT91_CfgPIO_USART1();
+		break;
+	case 2:
+		at91_ports[idx].uart.membase = (void *) AT91C_VA_BASE_US2;
+		at91_ports[idx].uart.mapbase = AT91C_VA_BASE_US2;
+		at91_ports[idx].uart.irq     = AT91C_ID_US2;
+		AT91_CfgPIO_USART2();
+		break;
+	case 3:
+		at91_ports[idx].uart.membase = (void *) AT91C_VA_BASE_US3;
+		at91_ports[idx].uart.mapbase = AT91C_VA_BASE_US3;
+		at91_ports[idx].uart.irq     = AT91C_ID_US3;
+		AT91_CfgPIO_USART3();
+		break;
+	case 4:
+		at91_ports[idx].uart.membase = (void *) AT91C_VA_BASE_DBGU;
+		at91_ports[idx].uart.mapbase = AT91C_VA_BASE_DBGU;
+		at91_ports[idx].uart.irq     = AT91C_ID_SYS;
+		AT91_CfgPIO_DBGU();
+		break;
+	default:
+		printk(KERN_ERR __FUNCTION__ ": bad port number %d\n", port);
+	}
+}
+
+#ifdef CONFIG_SERIAL_AT91_CONSOLE
+
+/*
+ * Interrupts are disabled on entering
+ */
+static void at91_console_write(struct console *co, const char *s, u_int count)
+{
+	struct uart_port *uart = &at91_ports[co->index].uart;
+	unsigned int status, i, imr;
+
+	/*
+	 *	First, save IMR and then disable interrupts
+	 */
+	imr = UART_GET_IMR(uart);	/* get interrupt mask */
+	UART_PUT_IDR(uart, AT91C_US_RXRDY | AT91C_US_TXRDY);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++) {
+		do {
+			status = UART_GET_CSR(uart);
+		} while (!(status & AT91C_US_TXRDY));
+		UART_PUT_CHAR(uart, s[i]);
+		if (s[i] == '\n') {
+			do {
+				status = UART_GET_CSR(uart);
+			} while (!(status & AT91C_US_TXRDY));
+			UART_PUT_CHAR(uart, '\r');
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore IMR
+	 */
+	do {
+		status = UART_GET_CSR(uart);
+	} while (status & AT91C_US_TXRDY);
+	UART_PUT_IER(uart, imr);	/* set interrupts back the way they were */
+}
+
+static kdev_t at91_console_device(struct console *co)
+{
+	return MKDEV(SERIAL_AT91_MAJOR, MINOR_START + co->index);
+}
+
+/*
+ * If the port was already initialised (eg, by a boot loader), try to determine
+ * the current setup.
+ */
+static void __init at91_console_get_options(struct uart_port *uart, int *baud, int *parity, int *bits)
+{
+	unsigned int mr, quot;
+
+// TODO: CR is a write-only register
+//	unsigned int cr;
+//
+//	cr = UART_GET_CR(uart) & (AT91C_US_RXEN | AT91C_US_TXEN);
+//	if (cr == (AT91C_US_RXEN | AT91C_US_TXEN)) {
+//		/* ok, the port was enabled */
+//
+//		mr = UART_GET_MR(port) & AT91C_US_PAR;
+//
+//		*parity = 'n';
+//		if (mr == AT91C_US_PAR_EVEN)
+//			*parity = 'e';
+//		else if (mr == AT91C_US_PAR_ODD)
+//			*parity = 'o';
+//	}
+
+	mr = UART_GET_MR(uart) & AT91C_US_CHRL;
+	if (mr == AT91C_US_CHRL_8_BITS)
+		*bits = 8;
+	else
+		*bits = 7;
+
+	quot = UART_GET_BRGR(uart);
+	*baud = uart->uartclk / (16 * (quot));
+}
+
+static int __init at91_console_setup(struct console *co, char *options)
+{
+	struct uart_port *uart;
+	int baud = AT91C_CONSOLE_DEFAULT_BAUDRATE;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (co->index >= AT91C_NR_UART)
+		co->index = 0;
+	uart = &at91_ports[co->index].uart;
+
+	// TODO: The console port should be initialized, and clock enabled if
+	//  we're not relying on the bootloader to do it.
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else
+		at91_console_get_options(uart, &baud, &parity, &bits);
+
+	return uart_set_options(uart, co, baud, parity, bits, flow);
+}
+
+static struct console at91_console = {
+	name:		"ttyS",
+	write:		at91_console_write,
+	device:		at91_console_device,
+	setup:		at91_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		AT91C_CONSOLE,
+};
+
+#define AT91_CONSOLE_DEVICE	&at91_console
+
+void __init at91_console_init(void)
+{
+	at91_init_ports();
+	register_console(&at91_console);
+}
+
+#else
+#define AT91_CONSOLE_DEVICE	NULL
+#endif
+
+static struct uart_driver at91_uart = {
+	owner:			THIS_MODULE,
+	normal_major:		SERIAL_AT91_MAJOR,
+#ifdef CONFIG_DEVFS_FS
+	normal_name:		"ttyS%d",
+	callout_name:		"cua%d",
+#else
+	normal_name:		"ttyS",
+	callout_name:		"cua",
+#endif
+	normal_driver:		&normal,
+	callout_major:		CALLOUT_AT91_MAJOR,
+	callout_driver:		&callout,
+	table:			at91_table,
+	termios:		at91_termios,
+	termios_locked:		at91_termios_locked,
+	minor:			MINOR_START,
+	nr:			AT91C_NR_UART,
+	cons:			AT91_CONSOLE_DEVICE,
+};
+
+static int __init at91_serial_init(void)
+{
+	int ret, i;
+
+	at91_init_ports();
+
+	ret = uart_register_driver(&at91_uart);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < AT91C_NR_UART; i++) {
+		if (at91_serialmap[i] >= 0)
+			uart_add_one_port(&at91_uart, &at91_ports[i].uart);
+	}
+
+	return 0;
+}
+
+static void __exit at91_serial_exit(void)
+{
+	int i;
+
+	for (i = 0; i < AT91C_NR_UART; i++) {
+		if (at91_serialmap[i] >= 0)
+			uart_remove_one_port(&at91_uart, &at91_ports[i].uart);
+	}
+
+	uart_unregister_driver(&at91_uart);
+}
+
+module_init(at91_serial_init);
+module_exit(at91_serial_exit);
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("Rick Bronson");
+MODULE_DESCRIPTION("AT91 generic serial port driver");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/drivers/at91/serial/Makefile linux-2.4.29-uc1/drivers/at91/serial/Makefile
--- linux-2.4.29/drivers/at91/serial/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/serial/Makefile	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,15 @@
+# File: drivers/at91/serial/Makefile
+#
+# Makefile for the Atmel AT91RM9200 serial and console device drivers
+#
+
+O_TARGET := at91serial.o
+
+obj-y	:=
+obj-m	:=
+obj-n	:=
+obj-	:=
+
+obj-$(CONFIG_SERIAL_AT91) += at91_serial.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/at91/spi/at91_spi.c linux-2.4.29-uc1/drivers/at91/spi/at91_spi.c
--- linux-2.4.29/drivers/at91/spi/at91_spi.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/spi/at91_spi.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,275 @@
+/*
+ * Serial Peripheral Interface (SPI) driver for the Atmel AT91RM9200 (Thunder)
+ *
+ * (c) SAN People (Pty) Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <asm/semaphore.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+
+#include <asm/arch/AT91RM9200_SPI.h>
+#include <asm/arch/pio.h>
+#include "at91_spi.h"
+
+#undef DEBUG_SPI
+
+static struct spi_local spi_dev[NR_SPI_DEVICES];	/* state of the SPI devices */
+static int spi_enabled = 0;
+static struct semaphore spi_lock;			/* protect access to SPI bus */
+static int current_device = -1;				/* currently selected SPI device */
+
+DECLARE_COMPLETION(transfer_complete);
+
+/* SPI controller device */
+static AT91PS_SPI controller = (AT91PS_SPI) AT91C_VA_BASE_SPI;
+
+/* ......................................................................... */
+
+/*
+ * Access and enable the SPI bus.
+ * This MUST be called before any transfers are performed.
+ */
+void spi_access_bus(short device)
+{
+	/* Ensure that requested device is valid */
+	if ((device < 0) || (device >= NR_SPI_DEVICES))
+		panic("at91_spi: spi_access_bus called with invalid device");
+
+	if (spi_enabled == 0) {
+		AT91_SYS->PMC_PCER = 1 << AT91C_ID_SPI;	/* Enable Peripheral clock */
+		controller->SPI_CR = AT91C_SPI_SPIEN;	/* Enable SPI */
+#ifdef DEBUG_SPI
+		printk("SPI on\n");
+#endif
+	}
+	MOD_INC_USE_COUNT;
+	spi_enabled++;
+
+	/* Lock the SPI bus */
+	down(&spi_lock);
+	current_device = device;
+
+	/* Enable PIO */
+	if (!spi_dev[device].pio_enabled) {
+		switch (device) {
+			case 0: AT91_CfgPIO_SPI_CS0();
+			case 1: AT91_CfgPIO_SPI_CS1();
+			case 2: AT91_CfgPIO_SPI_CS2();
+			case 3: AT91_CfgPIO_SPI_CS3();
+		}
+		spi_dev[device].pio_enabled = 1;
+#ifdef DEBUG_SPI
+		printk("SPI CS%i enabled\n", device);
+#endif
+	}
+
+	/* Configure SPI bus for device */
+	controller->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | (spi_dev[device].pcs << 16);
+}
+
+/*
+ * Relinquish control of the SPI bus.
+ */
+void spi_release_bus(short device)
+{
+	if (device != current_device)
+		panic("at91_spi: spi_release called with invalid device");
+
+	/* Release the SPI bus */
+	current_device = -1;
+	up(&spi_lock);
+
+	spi_enabled--;
+	MOD_DEC_USE_COUNT;
+	if (spi_enabled == 0) {
+		controller->SPI_CR = AT91C_SPI_SPIDIS;	/* Disable SPI */
+		AT91_SYS->PMC_PCER = 1 << AT91C_ID_SPI;	/* Disable Peripheral clock */
+#ifdef DEBUG_SPI
+		printk("SPI off\n");
+#endif
+	}
+}
+
+/*
+ * Perform a data transfer over the SPI bus
+ */
+int spi_transfer(struct spi_transfer_list* list)
+{
+	struct spi_local *device = (struct spi_local *) &spi_dev[current_device];
+
+	if (!list)
+		panic("at91_spi: spi_transfer called with NULL transfer list");
+	if (current_device == -1)
+		panic("at91_spi: spi_transfer called without acquiring bus");
+
+#ifdef DEBUG_SPI
+	printk("SPI transfer start [%i]\n", list->nr_transfers);
+#endif
+
+	/* Store transfer list */
+	device->xfers = list;
+	list->curr = 0;
+
+	/* Assume there must be at least one transfer */
+	device->tx = pci_map_single(NULL, list->tx[0], list->txlen[0], PCI_DMA_TODEVICE);
+	device->rx = pci_map_single(NULL, list->rx[0], list->rxlen[0], PCI_DMA_FROMDEVICE);
+
+	/* Program PDC registers */
+	controller->SPI_TPR = device->tx;
+	controller->SPI_RPR = device->rx;
+	controller->SPI_TCR = list->txlen[0];
+	controller->SPI_RCR = list->rxlen[0];
+
+	/* Is there a second transfer? */
+	if (list->nr_transfers > 1) {
+		device->txnext = pci_map_single(NULL, list->tx[1], list->txlen[1], PCI_DMA_TODEVICE);
+		device->rxnext = pci_map_single(NULL, list->rx[1], list->rxlen[1], PCI_DMA_FROMDEVICE);
+
+		/* Program Next PDC registers */
+		controller->SPI_TNPR = device->txnext;
+		controller->SPI_RNPR = device->rxnext;
+		controller->SPI_TNCR = list->txlen[1];
+		controller->SPI_RNCR = list->rxlen[1];
+	}
+	else {
+		device->txnext = 0;
+		device->rxnext = 0;
+		controller->SPI_TNCR = 0;
+		controller->SPI_RNCR = 0;
+	}
+
+	// TODO: If we are doing consecutive transfers (at high speed, or
+	//   small buffers), then it might be worth modifying the 'Delay between
+	//   Consecutive Transfers' in the CSR registers.
+	//   This is an issue if we cannot chain the next buffer fast enough
+	//   in the interrupt handler.
+
+	/* Enable transmitter and receiver */
+	controller->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
+
+	controller->SPI_IER = AT91C_SPI_SPENDRX;	/* enable buffer complete interrupt */
+	wait_for_completion(&transfer_complete);
+
+#ifdef DEBUG_SPI
+	printk("SPI transfer end\n");
+#endif
+
+	return 0;
+}
+
+/* ......................................................................... */
+
+/*
+ * Handle interrupts from the SPI controller.
+ */
+static void spi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ 	unsigned int status;
+	struct spi_local *device = (struct spi_local *) &spi_dev[current_device];
+	struct spi_transfer_list *list = device->xfers;
+
+#ifdef DEBUG_SPI
+	printk("SPI interrupt %i\n", current_device);
+#endif
+
+	if (!list)
+		panic("at91_spi: spi_interrupt with a NULL transfer list");
+
+       	status = controller->SPI_SR & controller->SPI_IMR;	/* read status */
+
+	pci_unmap_single(NULL, device->tx, list->txlen[list->curr], PCI_DMA_TODEVICE);
+	pci_unmap_single(NULL, device->rx, list->rxlen[list->curr], PCI_DMA_FROMDEVICE);
+
+	device->tx = device->txnext;	/* move next transfer to current transfer */
+	device->rx = device->rxnext;
+
+	list->curr = list->curr + 1;
+	if (list->curr == list->nr_transfers) {		/* all transfers complete */
+		controller->SPI_IDR = AT91C_SPI_SPENDRX;	/* disable interrupt */
+
+		/* Disable transmitter and receiver */
+		controller->SPI_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
+
+		device->xfers = NULL;
+		complete(&transfer_complete);
+	}
+	else if (list->curr+1 == list->nr_transfers) {	/* no more next transfers */
+		device->txnext = 0;
+		device->rxnext = 0;
+		controller->SPI_TNCR = 0;
+		controller->SPI_RNCR = 0;
+	}
+	else {
+		int i = (list->curr)+1;
+
+		device->txnext = pci_map_single(NULL, list->tx[i], list->txlen[i], PCI_DMA_TODEVICE);
+		device->rxnext = pci_map_single(NULL, list->rx[i], list->rxlen[i], PCI_DMA_FROMDEVICE);
+		controller->SPI_TNPR = device->txnext;
+		controller->SPI_RNPR = device->rxnext;
+		controller->SPI_TNCR = list->txlen[i];
+		controller->SPI_RNCR = list->rxlen[i];
+	}
+}
+
+/* ......................................................................... */
+
+/*
+ * Initialize the SPI controller
+ */
+static int __init at91_spi_init(void)
+{
+	init_MUTEX(&spi_lock);
+
+	AT91_CfgPIO_SPI();
+
+	controller->SPI_CR = AT91C_SPI_SWRST;	/* software reset of SPI controller */
+
+	/* Set Chip Select registers to good defaults */
+	controller->SPI_CSR0 = AT91C_SPI_CPOL | AT91C_SPI_BITS_8 | (16 << 16) | (DEFAULT_SPI_BAUD << 8);
+	controller->SPI_CSR1 = AT91C_SPI_CPOL | AT91C_SPI_BITS_8 | (16 << 16) | (DEFAULT_SPI_BAUD << 8);
+	controller->SPI_CSR2 = AT91C_SPI_CPOL | AT91C_SPI_BITS_8 | (16 << 16) | (DEFAULT_SPI_BAUD << 8);
+	controller->SPI_CSR3 = AT91C_SPI_CPOL | AT91C_SPI_BITS_8 | (16 << 16) | (DEFAULT_SPI_BAUD << 8);
+
+	controller->SPI_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
+
+	memset(&spi_dev, 0, sizeof(spi_dev));
+	spi_dev[0].pcs = 0xE;
+	spi_dev[1].pcs = 0xD;
+	spi_dev[2].pcs = 0xB;
+	spi_dev[3].pcs = 0x7;
+
+	if (request_irq(AT91C_ID_SPI, spi_interrupt, 0, "spi", NULL))
+		return -EBUSY;
+
+	controller->SPI_CR = AT91C_SPI_SPIEN;		/* Enable SPI */
+
+	return 0;
+}
+
+static void at91_spi_exit(void)
+{
+	controller->SPI_CR = AT91C_SPI_SPIDIS;		/* Disable SPI */
+
+	free_irq(AT91C_ID_SPI, 0);
+}
+
+
+EXPORT_SYMBOL(spi_access_bus);
+EXPORT_SYMBOL(spi_release_bus);
+EXPORT_SYMBOL(spi_transfer);
+
+module_init(at91_spi_init);
+module_exit(at91_spi_exit);
+
+MODULE_LICENSE("GPL")
+MODULE_AUTHOR("Andrew Victor")
+MODULE_DESCRIPTION("SPI driver for Atmel AT91RM9200")
diff -urN linux-2.4.29/drivers/at91/spi/at91_spidev.c linux-2.4.29-uc1/drivers/at91/spi/at91_spidev.c
--- linux-2.4.29/drivers/at91/spi/at91_spidev.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/spi/at91_spidev.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,226 @@
+/*
+ * User-space interface to the SPI bus on Atmel AT91RM9200
+ *
+ * (c) SAN People (Pty) Ltd
+ *
+ * Based on SPI driver by Rick Bronson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/iobuf.h>
+#include <linux/highmem.h>
+
+#ifdef CONFIG_DEVFS_FS
+#include <linux/devfs_fs_kernel.h>
+#endif
+
+#include "at91_spi.h"
+
+#undef DEBUG_SPIDEV
+
+#ifdef CONFIG_DEVFS_FS
+static devfs_handle_t devfs_handle = NULL;
+static devfs_handle_t devfs_spi[NR_SPI_DEVICES];
+#endif
+
+/* ......................................................................... */
+
+/*
+ * Read or Write to SPI bus.
+ */
+static ssize_t spidev_rd_wr(struct file *file, char *buf, size_t count, loff_t *offset)
+{
+	unsigned int spi_device = (unsigned int) file->private_data;
+	struct kiobuf *iobuf;
+	unsigned int ofs, pagelen;
+	int res, i;
+
+	struct spi_transfer_list* list = kmalloc(sizeof(struct spi_transfer_list), GFP_KERNEL);
+	if (!list)
+		return -ENOMEM;
+
+	res = alloc_kiovec(1, &iobuf);
+	if (res) {
+		kfree(list);
+		return res;
+	}
+
+	res = map_user_kiobuf(READ, iobuf, (unsigned long) buf, count);
+	if (res) {
+		free_kiovec(1, &iobuf);
+		kfree(list);
+		return res;
+	}
+
+	/* More pages than transfer slots in spi_transfer_list */
+	if (iobuf->nr_pages >= MAX_SPI_TRANSFERS) {
+		unmap_kiobuf(iobuf);
+		free_kiovec(1, &iobuf);
+		kfree(list);
+		return -EFBIG;
+	}
+
+#ifdef DEBUG_SPIDEV
+	printk("spidev_rd_rw: %i %i\n", count, iobuf->nr_pages);
+#endif
+
+	/* Set default return value = transfer length */
+	res = count;
+
+	/*
+	 * At this point, the virtual area buf[0] .. buf[count-1] will have
+	 * corresponding pages mapped in the physical memory and locked until
+	 * we unmap the kiobuf.  The pages cannot be swapped out or moved
+	 * around.
+	 */
+	ofs = iobuf->offset;
+	pagelen = PAGE_SIZE - iobuf->offset;
+	if (count < pagelen)
+		pagelen = count;
+
+	for (i = 0; i < iobuf->nr_pages; i++) {
+		list->tx[i] = list->rx[i] = page_address(iobuf->maplist[i]) + ofs;
+		list->txlen[i] = list->rxlen[i] = pagelen;
+
+#ifdef DEBUG_SPIDEV
+		printk("  %i: %x  (%i)\n", i, list->tx[i], list->txlen[i]);
+#endif
+
+		ofs = 0;	/* all subsequent transfers start at beginning of a page */
+		count = count - pagelen;
+		pagelen = (count < PAGE_SIZE) ? count : PAGE_SIZE;
+	}
+	list->nr_transfers = iobuf->nr_pages;
+
+	/* Perform transfer on SPI bus */
+	spi_access_bus(spi_device);
+	spi_transfer(list);
+	spi_release_bus(spi_device);
+
+	unmap_kiobuf(iobuf);
+	free_kiovec(1, &iobuf);
+	kfree(list);
+
+	return res;
+}
+
+static int spidev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int spi_device = MINOR(inode->i_rdev);
+
+	if (spi_device >= NR_SPI_DEVICES)
+		return -ENODEV;
+
+	// TODO: This interface can be used to configure the SPI bus.
+	// Configurable options could include: Speed, Clock Polarity, Clock Phase
+
+	switch(cmd) {
+		default:
+			return -ENOIOCTLCMD;
+	}
+}
+
+/*
+ * Open the SPI device
+ */
+static int spidev_open(struct inode *inode, struct file *file)
+{
+	unsigned int spi_device = MINOR(inode->i_rdev);
+
+	if (spi_device >= NR_SPI_DEVICES)
+		return -ENODEV;
+
+	MOD_INC_USE_COUNT;
+
+	/*
+	 * 'private_data' is actually a pointer, but we overload it with the
+	 * value we want to store.
+	 */
+	(unsigned int) file->private_data = spi_device;
+
+	return 0;
+}
+
+/*
+ * Close the SPI device
+ */
+static int spidev_close(struct inode *inode, struct file *file)
+{
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+/* ......................................................................... */
+
+static struct file_operations spidev_fops = {
+	owner:		THIS_MODULE,
+	llseek:		no_llseek,
+	read:		spidev_rd_wr,
+	write:		spidev_rd_wr,
+	ioctl:		spidev_ioctl,
+	open:		spidev_open,
+	release:	spidev_close,
+};
+
+/*
+ * Install the SPI /dev interface driver
+ */
+static int __init at91_spidev_init(void)
+{
+	int i;
+	char name[3];
+
+#ifdef CONFIG_DEVFS_FS
+	if (devfs_register_chrdev(SPI_MAJOR, "spi", &spidev_fops)) {
+#else
+	if (register_chrdev(SPI_MAJOR, "spi", &spidev_fops)) {
+#endif
+		printk(KERN_ERR "at91_spidev: Unable to get major %d for SPI bus\n", SPI_MAJOR);
+		return -EIO;
+	}
+
+#ifdef CONFIG_DEVFS_FS
+	devfs_handle = devfs_mk_dir(NULL, "spi", NULL);
+
+	for (i = 0; i < NR_SPI_DEVICES; i++) {
+		sprintf (name, "%d", i);
+		devfs_spi[i] = devfs_register (devfs_handle, name,
+			DEVFS_FL_DEFAULT, SPI_MAJOR, i, S_IFCHR | S_IRUSR | S_IWUSR,
+			&spidev_fops, NULL);
+	}
+#endif
+	printk(KERN_INFO "AT91 SPI driver loaded\n");
+
+	return 0;
+}
+
+/*
+ * Remove the SPI /dev interface driver
+ */
+static void __exit at91_spidev_exit(void)
+{
+#ifdef CONFIG_DEVFS_FS
+	devfs_unregister(devfs_handle);
+	if (devfs_unregister_chrdev(SPI_MAJOR, "spi")) {
+#else
+	if (unregister_chrdev(SPI_MAJOR,"spi")) {
+#endif
+		printk(KERN_ERR "at91_spidev: Unable to release major %d for SPI bus\n", SPI_MAJOR);
+		return;
+	}
+}
+
+module_init(at91_spidev_init);
+module_exit(at91_spidev_exit);
+
+MODULE_LICENSE("GPL")
+MODULE_AUTHOR("Andrew Victor")
+MODULE_DESCRIPTION("SPI /dev interface for Atmel AT91RM9200")
diff -urN linux-2.4.29/drivers/at91/spi/at91_spi.h linux-2.4.29-uc1/drivers/at91/spi/at91_spi.h
--- linux-2.4.29/drivers/at91/spi/at91_spi.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/spi/at91_spi.h	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,56 @@
+/*
+ * Serial Peripheral Interface (SPI) driver for the Atmel AT91RM9200
+ *
+ * (c) SAN People (Pty) Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef AT91_SPI_H
+#define AT91_SPI_H
+
+/* Maximum number of buffers in a single SPI transfer.
+ *  DataFlash uses maximum of 2
+ *  spidev interface supports up to 8.
+ */
+#define MAX_SPI_TRANSFERS	8
+
+#define NR_SPI_DEVICES  	4	/* number of devices on SPI bus */
+
+#define DATAFLASH_CLK		6000000
+#define DEFAULT_SPI_BAUD	AT91C_MASTER_CLOCK / (2 * DATAFLASH_CLK)
+
+#define SPI_MAJOR		153	/* registered device number */
+
+/*
+ * Describes the buffers for a SPI transfer.
+ * A transmit & receive buffer must be specified for each transfer
+ */
+struct spi_transfer_list {
+	void* tx[MAX_SPI_TRANSFERS];	/* transmit */
+	int txlen[MAX_SPI_TRANSFERS];
+	void* rx[MAX_SPI_TRANSFERS];	/* receive */
+	int rxlen[MAX_SPI_TRANSFERS];
+	int nr_transfers;		/* number of transfers */
+	int curr;			/* current transfer */
+};
+
+struct spi_local {
+	unsigned int pcs;		/* Peripheral Chip Select value */
+	short pio_enabled;		/* has PIO been enabled? */
+
+	struct spi_transfer_list *xfers;	/* current transfer list */
+	dma_addr_t tx, rx;		/* DMA address for current transfer */
+	dma_addr_t txnext, rxnext;	/* DMA address for next transfer */
+};
+
+
+/* Exported functions */
+extern void spi_access_bus(short device);
+extern void spi_release_bus(short device);
+extern int spi_transfer(struct spi_transfer_list* list);
+
+#endif
diff -urN linux-2.4.29/drivers/at91/spi/Makefile linux-2.4.29-uc1/drivers/at91/spi/Makefile
--- linux-2.4.29/drivers/at91/spi/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/spi/Makefile	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,17 @@
+# File: drivers/at91/spi/Makefile
+#
+# Makefile for the Atmel AT91RM9200 SPI device drivers
+#
+
+O_TARGET := at91spi.o
+
+export-objs := at91_spi.o
+
+obj-y	:= at91_spi.o
+obj-m	:=
+obj-n	:=
+obj-	:=
+
+obj-$(CONFIG_AT91_SPIDEV) += at91_spidev.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/at91/usb/at91_usb-ohci.c linux-2.4.29-uc1/drivers/at91/usb/at91_usb-ohci.c
--- linux-2.4.29/drivers/at91/usb/at91_usb-ohci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/usb/at91_usb-ohci.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,81 @@
+/*
+ *  linux/drivers/at91/usb/at91_usb_ohci-at91.c
+ *
+ *  (c) Rick Bronson
+ *
+ *  The outline of this code was taken from Brad Parkers <brad@heeltoe.com>
+ *  original OHCI driver modifications, and reworked into a cleaner form
+ *  by Russell King <rmk@arm.linux.org.uk>.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/arch/AT91RM9200_UHP.h>
+
+/*
+  NOTE:
+  The following is so that we don't have to include usb-ohci.h or pci.h as the
+  usb-ohci.c driver needs these routines even when the architecture
+  has no PCI bus...
+*/
+
+extern int __devinit hc_add_ohci(struct pci_dev *dev, int irq, void *membase,
+	    unsigned long flags, void *ohci, const char *name,
+	    const char *slot_name);
+extern void hc_remove_ohci(void *ohci);
+
+static void *at91_ohci;
+AT91PS_UHP ohci_regs;
+
+static int __init at91_ohci_init(void)
+{
+	int ret;
+
+	ohci_regs = ioremap(AT91_UHP_BASE, SZ_4K);
+	if (!ohci_regs) {
+		printk(KERN_ERR "at91_usb-ohci: ioremap failed\n");
+		return -EIO;
+	}
+
+	/* Now, enable the USB clock */
+	AT91_SYS->PMC_SCER = AT91C_PMC_UHP;	/* enable system clock */
+	AT91_SYS->PMC_PCER = 1 << AT91C_ID_UHP;	/* enable peripheral clock */
+
+	/* Take Hc out of reset */
+	ohci_regs->UHP_HcControl = 2 << 6;
+
+	/* Initialise the generic OHCI driver. */
+	ret = hc_add_ohci((struct pci_dev *) 1, AT91C_ID_UHP,
+			  (void *)ohci_regs, 0, &at91_ohci,
+			  "usb-ohci", "at91");
+	if (ret)
+		iounmap(ohci_regs);
+
+	return ret;
+}
+
+static void __exit at91_ohci_exit(void)
+{
+	hc_remove_ohci(at91_ohci);
+
+	/* Force UHP_Hc to reset */
+	ohci_regs->UHP_HcControl = 0;
+
+	 /* Stop the USB clock. */
+	AT91_SYS->PMC_SCDR = AT91C_PMC_UHP;	/* disable system clock */
+	AT91_SYS->PMC_PCDR = 1 << AT91C_ID_UHP;	/* disable peripheral clock */
+
+	iounmap(ohci_regs);
+}
+
+module_init(at91_ohci_init);
+module_exit(at91_ohci_exit);
diff -urN linux-2.4.29/drivers/at91/usb/Makefile linux-2.4.29-uc1/drivers/at91/usb/Makefile
--- linux-2.4.29/drivers/at91/usb/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/usb/Makefile	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,17 @@
+# File: drivers/at91/usb/Makefile
+#
+# Makefile for the Atmel AT91RM9200 USB device drivers
+#
+
+O_TARGET := at91usb.o
+
+export-objs :=
+
+obj-y	:=
+obj-m	:=
+obj-n	:=
+obj-	:=
+
+obj-$(CONFIG_USB_OHCI_AT91) += at91_usb-ohci.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/at91/watchdog/at91_wdt.c linux-2.4.29-uc1/drivers/at91/watchdog/at91_wdt.c
--- linux-2.4.29/drivers/at91/watchdog/at91_wdt.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/watchdog/at91_wdt.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,193 @@
+/*
+ * Watchdog driver for Atmel AT91RM9200 (Thunder)
+ *
+ * (c) SAN People (Pty) Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <asm/uaccess.h>
+#include <linux/init.h>
+
+#define WDT_DEFAULT_TIME 5	/* 5 seconds */
+#define WDT_MAX_TIME 256	/* 256 seconds */
+
+static int at91wdt_time = WDT_DEFAULT_TIME;
+static int at91wdt_busy;
+
+/* ......................................................................... */
+
+/*
+ * Disable the watchdog.
+ */
+static void at91_wdt_stop(void)
+{
+	AT91_SYS->ST_WDMR = AT91C_ST_EXTEN;
+}
+
+/*
+ * Enable and reset the watchdog.
+ */
+static void at91_wdt_start(void)
+{
+	AT91_SYS->ST_WDMR = AT91C_ST_EXTEN | AT91C_ST_RSTEN | (((65536 * at91wdt_time) >> 8) & AT91C_ST_WDV);
+	AT91_SYS->ST_CR = AT91C_ST_WDRST;
+}
+
+/* ......................................................................... */
+
+/*
+ * Watchdog device is opened, and watchdog starts running.
+ */
+static int at91_wdt_open(struct inode *inode, struct file *file)
+{
+	if (test_and_set_bit(1, &at91wdt_busy))
+		return -EBUSY;
+	MOD_INC_USE_COUNT;
+
+	/*
+	 * All counting occurs at SLOW_CLOCK / 128 = 0.256 Hz
+	 *
+	 * Since WDV is a 16-bit counter, the maximum period is
+	 * 65536 / 0.256 = 256 seconds.
+	 */
+
+	at91_wdt_start();
+	return 0;
+}
+
+/*
+ * Close the watchdog device.
+ * If CONFIG_WATCHDOG_NOWAYOUT is NOT defined then the watchdog is also
+ *  disabled.
+ */
+static int at91_wdt_close(struct inode *inode, struct file *file)
+{
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+	/* Disable the watchdog when file is closed */
+	at91_wdt_stop();
+#endif
+
+	at91wdt_busy = 0;
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+/*
+ * Handle commands from user-space.
+ */
+static int at91_wdt_ioctl(struct inode *inode, struct file *file,
+		unsigned int cmd, unsigned long arg)
+{
+	unsigned int new_value;
+	static struct watchdog_info info = {
+		identity: "at91 watchdog",
+		options:  WDIOF_SETTIMEOUT,
+	};
+
+	switch(cmd) {
+		case WDIOC_KEEPALIVE:
+			AT91_SYS->ST_CR = AT91C_ST_WDRST;	/* Pat the watchdog */
+			return 0;
+
+		case WDIOC_GETSUPPORT:
+			return copy_to_user((struct watchdog_info *)arg, &info, sizeof(info));
+
+		case WDIOC_SETTIMEOUT:
+			if (get_user(new_value, (int *)arg))
+				return -EFAULT;
+			if ((new_value <= 0) || (new_value > WDT_MAX_TIME))
+				return -EINVAL;
+
+			/* Restart watchdog with new time */
+			at91wdt_time = new_value;
+			at91_wdt_start();
+
+			/* Return current value */
+			return put_user(at91wdt_time, (int *)arg);
+
+		case WDIOC_GETTIMEOUT:
+			return put_user(at91wdt_time, (int *)arg);
+
+		case WDIOC_GETSTATUS:
+			return put_user(0, (int *)arg);
+
+		case WDIOC_SETOPTIONS:
+			if (get_user(new_value, (int *)arg))
+				return -EFAULT;
+			if (new_value & WDIOS_DISABLECARD)
+				at91_wdt_stop();
+			if (new_value & WDIOS_ENABLECARD)
+				at91_wdt_start();
+			return 0;
+
+		default:
+			return -ENOIOCTLCMD;
+	}
+}
+
+/*
+ * Pat the watchdog whenever device is written to.
+ */
+static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+{
+	/*  Can't seek (pwrite) on this device  */
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+
+	if (len) {
+		AT91_SYS->ST_CR = AT91C_ST_WDRST;	/* Pat the watchdog */
+		return len;
+	}
+
+	return 0;
+}
+
+/* ......................................................................... */
+
+static struct file_operations at91wdt_fops =
+{
+	.owner		= THIS_MODULE,
+	.ioctl		= at91_wdt_ioctl,
+	.open		= at91_wdt_open,
+	.release	= at91_wdt_close,
+	.write		= at91_wdt_write,
+};
+
+static struct miscdevice at91wdt_miscdev =
+{
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &at91wdt_fops,
+};
+
+static int __init at91_wdt_init(void)
+{
+	int res;
+
+	res = misc_register(&at91wdt_miscdev);
+	if (res)
+		return res;
+
+	printk("AT91 Watchdog Timer enabled (%d seconds)\n", WDT_DEFAULT_TIME);
+	return 0;
+}
+
+static void __exit at91_wdt_exit(void)
+{
+	misc_deregister(&at91wdt_miscdev);
+}
+
+module_init(at91_wdt_init);
+module_exit(at91_wdt_exit);
+
+MODULE_LICENSE("GPL")
+MODULE_AUTHOR("Andrew Victor")
+MODULE_DESCRIPTION("Watchdog driver for Atmel AT91RM9200")
diff -urN linux-2.4.29/drivers/at91/watchdog/Makefile linux-2.4.29-uc1/drivers/at91/watchdog/Makefile
--- linux-2.4.29/drivers/at91/watchdog/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/at91/watchdog/Makefile	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,15 @@
+# File: drivers/at91/watchdog/Makefile
+#
+# Makefile for the Atmel AT91RM9200 watchdog device driver
+#
+
+O_TARGET := at91wdt.o
+
+obj-y	:=
+obj-m	:=
+obj-n	:=
+obj-	:=
+
+obj-$(CONFIG_AT91_WATCHDOG) += at91_wdt.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/block/blkmem.c linux-2.4.29-uc1/drivers/block/blkmem.c
--- linux-2.4.29/drivers/block/blkmem.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/block/blkmem.c	2005-06-14 02:11:55.000000000 +0100
@@ -0,0 +1,2990 @@
+/* blkmem.c: Block access to memory spaces
+ *
+ * Copyright (C) 2001  SnapGear Inc. <davidm@snapgear.com>
+ * Copyright (C) 2000  Lineo, Inc.  (www.lineo.com)   
+ * Copyright (C) 1997, 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *                           Kenneth Albanowski <kjahds@kjahds.com>,
+ * Copyright (C) 1999-2003   Greg Ungerer <gerg@snapgear.com>
+ *
+ * Based z2ram - Amiga pseudo-driver to access 16bit-RAM in ZorroII space
+ * Copyright (C) 1994 by Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  This software is provided "as is" without express or
+ * implied warranty.
+ *
+ * NOV/2000 -- hacked for Linux kernel 2.2 and NETtel/x86 (gerg@snapgear.com)
+ * VZ Support/Fixes             Evan Stawnyczy <e@lineo.ca>
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/major.h>
+#include <linux/slab.h>
+#include <linux/reboot.h>
+#include <linux/ledman.h>
+#include <linux/init.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/tqueue.h>
+#include <asm/semaphore.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#undef VERBOSE
+#undef DEBUG
+
+#define TRUE                  (1)
+#define FALSE                 (0)
+
+#define	BLKMEM_MAJOR	31
+
+#define MAJOR_NR BLKMEM_MAJOR
+
+#if defined(CONFIG_ARCH_CX821XX)
+#ifdef CONFIG_BD_TIBURON
+#define	FIXED_ROMARRAY	0x4b0000
+#else
+#define	FIXED_ROMARRAY	0x500000
+#endif
+#elif defined(CONFIG_ARCH_CNXT)
+#define	CONFIG_FLASH_SNAPGEAR	1
+#define DEVEL  1 /* everything in SDRAM for now */
+#endif
+
+// #define DEVICE_NAME "blkmem"
+#define DEVICE_REQUEST do_blkmem_request
+#define DEVICE_NR(device) (MINOR(device))
+#define DEVICE_ON(device)
+#define DEVICE_OFF(device)
+#define DEVICE_NO_RANDOM
+#define TIMEOUT_VALUE (6 * HZ)
+
+#include <linux/blkmem.h>
+#include <linux/blk.h>
+
+#ifdef CONFIG_LEDMAN
+#include <linux/ledman.h>
+#endif
+
+#include <asm/bitops.h>
+#include <asm/delay.h>
+#include <asm/semaphore.h>
+
+/*
+ *	Timeout loop counter for FLASH operations.
+ *
+ * On the flash part on the M5272C3, it can take up to 60 seconds for a write
+ * in a non-ideal environment.  The counter above wasn't enough even in an
+ * ideal one.
+ */
+#define	FTIMEOUT	990000000
+
+
+/*
+ * Please, configure the ROMFS for your system here
+ */
+
+
+/* Samsung S3C4510-SNDS100 arch */
+#ifdef CONFIG_BOARD_SNDS100
+extern char romfs_data[];
+extern char romfs_data_end[];
+#endif
+
+/* v850e; this config stuff is ugly, ugly, ugly! */
+#ifdef CONFIG_V850E
+#include <asm/blkmem.h>
+#endif
+
+#ifdef CONFIG_MICROBLAZE
+#include <asm/blkmem.h>
+#endif
+
+#if defined(CONFIG_ARCH_TA7S) || defined(CONFIG_ARCH_TA7V)
+#include <asm/arch/blkmem.h>
+#endif
+
+#ifdef CONFIG_ARCH_DM270
+#include <asm/arch/blkmem.h>
+#endif
+
+/* (es) */
+/* note: this is configured somewhere in arch/m68knommu/kernel/setup.c */
+/* does it need to be here? */
+#if defined( CONFIG_M68328 ) || defined ( CONFIG_M68EZ328 ) || defined( CONFIG_M68VZ328)
+#include <asm/shglports.h>
+#define CAT_ROMARRAY
+#endif
+/* (/es) */
+
+#if defined( CONFIG_PILOT ) && defined( CONFIG_M68EZ328 )
+extern char _flashstart[];
+#define FIXED_ROMARRAY _flashstart
+#endif
+
+/* (es) */
+#if defined(CONFIG_UCSIMM) || defined(CONFIG_UCDIMM) || defined (CONFIG_DRAGEN2) || defined (CONFIG_CWEZ328) || defined (CONFIG_CWVZ328)
+#define CAT_ROMARRAY
+#endif
+/* (/es) */
+
+#ifdef CONFIG_M68EZ328ADS
+#ifdef CONFIG_M68EZ328ADS_RAM
+extern char _flashstart[];
+#define FIXED_ROMARRAY _flashstart
+#else
+#define CAT_ROMARRAY
+#endif 
+#endif 
+
+#ifdef CONFIG_ARCH_TRIO
+#define FIXED_ROMARRAY (char*)(3512*1024)
+#endif
+
+#ifdef CONFIG_EXCALIBUR
+extern char _romfs_start[];
+#define FIXED_ROMARRAY _romfs_start
+#endif
+
+#ifdef CONFIG_ALMA_ANS
+#ifdef CONFIG_ALMA_ANS_RAM
+extern char _flashstart[];
+#define FIXED_ROMARRAY _flashstart
+#else
+#define CAT_ROMARRAY
+#endif 
+#endif 
+
+#ifdef CONFIG_COLDFIRE
+#ifdef CONFIG_TELOS
+#define CAT_ROMARRAY
+#else
+unsigned char *romarray;
+extern char _ebss;
+
+#ifndef CONFIG_ROMFS_FROM_ROM
+  #define FIXUP_ARENAS 	arena[0].address = (unsigned long) &_ebss;
+#else
+  #define FIXUP_ARENAS	{ \
+		register char *sp = (char *) arena[4].address; \
+		register char *ep = sp + arena[4].length; \
+		if (strncmp((char *) &_ebss, "-rom1fs-", 8) == 0) { \
+			sp = (char *) &_ebss; \
+		} else { \
+			while (sp < ep && strncmp(sp, "-rom1fs-", 8)) \
+				sp++; \
+			if (sp >= ep) \
+				sp = &_ebss; \
+		} \
+		arena[0].address = (unsigned long) sp; \
+	}
+#endif /* CONFIG_ROMFS_FROM_ROM */
+
+/*
+ *  Stub out the LED functions for now.
+ */
+#define SET_ALARM_LED(x)
+#define GET_COMM_STATUS_LED(x)
+#define SET_COMM_STATUS_LED(x)
+#define SET_COMM_ERROR_LED(x)
+#endif /* CONFIG_TELOS */
+#endif /* CONFIG_COLDFIRE */
+
+
+#if defined(CONFIG_ARCH_DSC21) || defined(CONFIG_ARCH_ATMEL)
+#define FIXED_ROMARRAY (char *)(FLASH_MEM_BASE)
+#endif
+
+#if defined( CONFIG_M68360 )
+#define CAT_ROMARRAY
+#endif
+
+/*
+ *	Lineo hardware has similar FLASH layouts on all devices.
+ */
+#if defined(CONFIG_NETtel) ||	\
+    defined(CONFIG_eLIA) ||	\
+    defined(CONFIG_DISKtel) ||	\
+    defined(CONFIG_SECUREEDGEMP3) || \
+    defined(CONFIG_SE1100) || \
+    defined(CONFIG_GILBARCONAP)
+#define	CONFIG_FLASH_SNAPGEAR	1
+#endif
+
+#if defined(CONFIG_CPU_H8300H) || defined(CONFIG_CPU_H8S)
+#  if defined(CONFIG_INTELFLASH)
+#    define CONFIG_FLASH_SNAPGEAR	1
+     extern char _ebss;
+#    define FIXUP_ARENAS 	arena[0].address = ((unsigned long) &_ebss);
+#  else
+#    ifndef CONFIG_BLKDEV_RESERVE
+#      ifdef CONFIG_ROMKERNEL
+         extern char _blkimg[];
+#        define FIXED_ROMARRAY _blkimg
+#      else
+         extern char _ebss[];
+#        define FIXED_ROMARRAY _ebss
+#      endif
+#    else
+#      define FIXED_ROMARRAY (CONFIG_BLKDEV_RESERVE_ADDRESS)
+#    endif
+#  endif
+#endif
+
+#if defined(CONFIG_BOARD_SMDK40100)
+extern char __romfs_start[];
+#define FIXED_ROMARRAY __romfs_start
+#endif
+
+#if defined(CONFIG_CLIE)
+extern char _ebss;
+#define FIXUP_ARENAS  arena[0].address = (unsigned long) &_ebss;
+#endif
+
+/******* END OF BOARD-SPECIFIC CONFIGURATION ************/
+
+/* Simple romfs, at internal, cat on the end of kernel, or seperate fixed adderess romfs. */
+
+#ifdef INTERNAL_ROMARRAY
+#include "romdisk.c"
+#endif
+
+#ifdef CAT_ROMARRAY
+unsigned char *romarray;
+extern char __data_rom_start[];
+extern char _edata[];
+extern char __data_start[];
+#ifndef FIXUP_ARENAS
+#define FIXUP_ARENAS \
+	arena[0].address = (unsigned long)__data_rom_start + (unsigned long)_edata - (unsigned long)__data_start;
+#endif
+#endif
+
+#if defined(CONFIG_WATCHDOG)
+extern void watchdog_disable(void);
+extern void watchdog_enable(void);
+#endif
+
+#ifdef FIXED_ROMARRAY
+unsigned char *romarray = (char *)(FIXED_ROMARRAY);
+#endif
+
+/* If defined, ROOT_ARENA causes the root device to be the specified arena, useful with romfs */
+
+/* Now defining ROOT_DEV in arch/setup.c */
+/*#define ROOT_ARENA 0*/
+
+struct arena_t;
+
+typedef void (*xfer_func_t)(struct arena_t *, unsigned long address, unsigned long length, char * buffer);
+typedef void (*erase_func_t)(struct arena_t *, unsigned long address);
+typedef void (*program_func_t)(struct arena_t *, struct blkmem_program_t * prog);
+
+#ifndef CONFIG_COLDFIRE
+void program_main(struct arena_t *, struct blkmem_program_t *);
+void read_spare(struct arena_t *, unsigned long, unsigned long, char *);
+void write_spare(struct arena_t *, unsigned long, unsigned long, char *);
+void erase_spare(struct arena_t *, unsigned long);
+#endif
+
+#if defined(CONFIG_ARNEWSH) || defined(CONFIG_M5206eC3)
+void flash_amd8_pair_write(struct arena_t *, unsigned long, unsigned long, char *);
+void flash_amd8_pair_erase(struct arena_t *, unsigned long);
+#endif
+
+#if defined(CONFIG_M5272C3) || defined(CONFIG_COBRA5272) || defined(CONFIG_COBRA5282)
+/*
+ *	M5272C3 evaluation board with 16bit AMD FLASH.
+ *	(The COBRA5272 has the same flash)
+ */
+static void flash_amd16_writeall(struct arena_t *, struct blkmem_program_t *);
+static void flash_amd16_write(struct arena_t *, unsigned long, unsigned long, char *);
+static void flash_amd16_erase(struct arena_t *, unsigned long);
+#define	flash_erase	flash_amd16_erase
+#define	flash_write	flash_amd16_write
+#define	flash_writeall	flash_amd16_writeall
+#endif
+
+
+#if defined(CONFIG_FLASH_SNAPGEAR)
+#if defined(CONFIG_INTELFLASH)
+/*
+ *	Lineo hardware with INTEL FLASH.
+ */
+static void flash_intel_writeall(struct arena_t *, struct blkmem_program_t *);
+static void flash_intel_write(struct arena_t *, unsigned long, unsigned long, char *);
+static void flash_intel_erase(struct arena_t *, unsigned long);
+#define	flash_erase	flash_intel_erase
+#define	flash_write	flash_intel_write
+#define	flash_writeall	flash_intel_writeall
+#else
+#ifdef CONFIG_FLASH8BIT
+/*
+ *	Lineo hardware with 8bit AMD FLASH.
+ */
+static void flash_amd8_writeall(struct arena_t *, struct blkmem_program_t *);
+static void flash_amd8_write(struct arena_t *, unsigned long, unsigned long, char *);
+static void flash_amd8_erase(struct arena_t *, unsigned long);
+#define	flash_erase	flash_amd8_erase
+#define	flash_write	flash_amd8_write
+#define	flash_writeall	flash_amd8_writeall
+#else
+/*
+ *	Lineo hardware with 16bit AMD FLASH (this is the default).
+ */
+static void flash_amd16_writeall(struct arena_t *, struct blkmem_program_t *);
+static void flash_amd16_write(struct arena_t *, unsigned long, unsigned long, char *);
+static void flash_amd16_erase(struct arena_t *, unsigned long);
+#define	flash_erase	flash_amd16_erase
+#define	flash_write	flash_amd16_write
+#define	flash_writeall	flash_amd16_writeall
+#endif /* !COFNIG_FLASH8BIT */
+#endif /* !CONFIG_INTELFLASH */
+#endif /* CONFIG_FLASH_SNAPGEAR */
+
+#if defined(CONFIG_HW_FEITH)
+/*
+ *	Feith hardware with 16bit AMD FLASH (this is the default).
+ */
+static void flash_amd16_writeall(struct arena_t *, struct blkmem_program_t *);
+static void flash_amd16_write(struct arena_t *, unsigned long, unsigned long, char *);
+static void flash_amd16_erase(struct arena_t *, unsigned long);
+#define	flash_erase	flash_amd16_erase
+#define	flash_write	flash_amd16_write
+#define	flash_writeall	flash_amd16_writeall
+#endif
+
+#ifdef CONFIG_BLACKFIN
+extern char ramdisk_begin;
+extern char ramdisk_end;
+#define	FIXUP_ARENAS	arena[0].length=&ramdisk_end - &ramdisk_begin;
+#endif
+
+/* This array of structures defines the actual set of memory arenas, including
+   access functions (if the memory isn't part of the main address space) */
+
+struct arena_t {
+	int rw;
+
+	unsigned long address; /* Address of memory arena */
+	unsigned long length;  /* Length of memory arena. If -1, try to get size from romfs header */
+
+	program_func_t program_func; /* Function to program in one go */
+
+	xfer_func_t read_func; /* Function to transfer data to main memory, or zero if none needed */
+	xfer_func_t write_func; /* Function to transfer data from main memory, zero if none needed */
+
+	erase_func_t erase_func; /* Function to erase a block of memory to zeros, or 0 if N/A */
+	unsigned long blksize; /* Size of block that can be erased at one time, or 0 if N/A */
+	unsigned long unitsize;
+	unsigned char erasevalue; /* Contents of sectors when erased */
+	
+	/*unsigned int auto_erase_bits;
+	unsigned int did_erase_bits;*/
+	
+} arena[] = {
+#ifdef CONFIG_BLACKFIN
+	{0, &ramdisk_begin, 0},
+#endif
+
+#ifdef INTERNAL_ROMARRAY
+	{0, (unsigned long)romarray, sizeof(romarray)},
+#endif
+
+#ifdef CAT_ROMARRAY
+	{0, 0, -1},
+#endif
+
+#ifdef FIXED_ROMARRAY
+	{0, (unsigned long) FIXED_ROMARRAY, -1},
+#endif
+
+#ifdef CONFIG_BOARD_SNDS100
+	{0, romfs_data, -1},
+#endif
+
+#ifdef CONFIG_ARCH_DM270
+	{0, 0, -1},
+#endif
+
+#if defined(CONFIG_ARCH_CNXT) && !defined(CONFIG_ARCH_CX821XX)
+    /*  AM29LV004T flash
+     *  rom0 -- root file-system
+     */
+#ifdef DEVEL
+	/*
+	 * rom0 currently  in RAM
+	 */
+	{1, 0x800000, 0x100000,0,0, flash_write, flash_erase, 0x10000, 0x10000, 0xff},
+#else	
+	{1, 0x400000, 0x10000,0,0, flash_write, flash_erase, 0x10000, 0x10000, 0xff},
+	{1, 0x410000, 0xf0000,0,0, flash_write, flash_erase, 0x10000, 0x10000, 0xff},
+	{1, 0x500000,0x100000,0,0, flash_write, flash_erase, 0x10000,0x10000,0xff},
+	{1, 0x600000,0x200000,0,0, flash_write, flash_erase,0x10000,0x10000,0xff},
+	{1, 0x801000,0xff000,0,0, flash_write,flash_erase,0xff000,0xff000,0xff},
+#endif
+
+#endif /* CONFIG_ARCH_CNXT*/
+
+#if (defined(CONFIG_CPU_H8300H) || defined(CONFIG_CPU_H8S)) && \
+		defined(CONFIG_INTELFLASH)
+    {0, 0, -1}, /* In RAM romfs */
+    {1,0x00000000,0x020000,0,0,flash_write,flash_erase,0x20000,0x20000,0xff},
+    {1,0x00020000,0x020000,0,0,flash_write,flash_erase,0x20000,0x20000,0xff},
+    {1,0x00040000,0x3c0000,0,0,flash_write,flash_erase,0x20000,0x20000,0xff},
+    {1,0x00000000,0x400000,0,0,flash_write,flash_erase,0x20000,0x20000,0xff},
+#endif
+
+#ifdef CONFIG_COLDFIRE
+    /*
+     *	The ROM file-system is RAM resident on the ColdFire eval boards.
+     *	This arena is defined for access to it.
+     */
+    {0, 0, -1},
+
+#ifdef CONFIG_ARN5206
+    /*
+     *	The spare FLASH segment on the Arnewsh 5206 board.
+     */
+    {1,0xffe20000,0x20000,0,0,flash_amd8_pair_write,flash_amd8_pair_erase,0x8000,0x20000,0xff},
+#endif
+
+#if defined(CONFIG_ARN5307) || defined(CONFIG_M5206eC3)
+    /*  pair of AM29LV004T flash for 1Mbyte total
+     *  rom0 -- root file-system (actually in RAM)
+     *  rom1 -- FLASH SA0   128K boot
+     *  rom2 -- FLASH SA1-6 768k kernel & romfs
+     *  rom3 -- FLASH SA7   64k spare
+     *  rom4 -- FLASH SA8   16k spare
+     *  rom5 -- FLASH SA9   16k spare
+     *  rom6 -- FLASH SA10  32k spare
+     */
+    {1,0xffe00000,0x20000,0,0,flash_amd8_pair_write,flash_amd8_pair_erase,0x20000,0x20000,0xff},
+    {1,0xffe20000,0xc0000,0,0,flash_amd8_pair_write,flash_amd8_pair_erase,0x20000,0xc0000,0xff},
+    {1,0xffee0000,0x10000,0,0,flash_amd8_pair_write,flash_amd8_pair_erase,0x10000,0x10000,0xff},
+    {1,0xffef0000,0x4000,0,0,flash_amd8_pair_write,flash_amd8_pair_erase,0x4000,0x4000,0xff},
+    {1,0xffef4000,0x4000,0,0,flash_amd8_pair_write,flash_amd8_pair_erase,0x4000,0x4000,0xff},
+    {1,0xffef8000,0x8000,0,0,flash_amd8_pair_write,flash_amd8_pair_erase,0x8000,0x8000,0xff},
+#endif /* CONFIG_ARNEWSH || CONFING_M5206eC3 */
+
+#if defined(CONFIG_SIGNAL_MCP751)
+/*
+ *	Signal MCP751 board with 4MB FLASH.
+ *	The following devices are supported:
+ *		rom0 -- root file-system (actually in RAM)
+ *		rom1 -- FLASH boot block 
+ *		rom2 -- FLASH low boot chunks 
+ *		rom3 -- FLASH jbc
+ *		rom4 -- FLASH kernel+file-system binary 
+ *		rom5 -- FLASH user
+ *		rom6 -- FLASH user2
+ *		rom7 -- FLASH the whole thing (4MB)!
+ */
+    {1,0xff000000,0x020000,flash_writeall, 0, 0, 0,    0x02000,0x020000,0xff}, 
+    {1,0xff004000,0x002000,flash_writeall, 0, 0, 0,    0x02000,0x002000,0xff}, 
+    {1,0xff020000,0x020000,flash_writeall, 0, 0, 0,    0x10000,0x020000,0xff}, 
+    {1,0xff040000,0x180000,0,0,flash_write,flash_erase,0x10000,0x180000,0xff}, 
+    {1,0xff1c0000,0x140000,0,0,flash_write,flash_erase,0x10000,0x140000,0xff}, 
+    {1,0xff300000,0x100000,0,0,flash_write,flash_erase,0x10000,0x100000,0xff}, 
+    {1,0xff000000,0x400000,flash_writeall, 0, 0, 0,    0x10000,0x400000,0xff}, 
+#endif
+
+#if defined(CONFIG_M5272C3) || defined(CONFIG_COBRA5272)
+/*
+ *	Motorola M5272C3 evaluation board with 2MB FLASH.
+ *	The following devices are supported:
+ *		rom0 -- root file-system (actually in RAM)
+ *		rom1 -- FLASH boot block (256k)
+ *		rom2 -- FLASH low boot chunks (32k total)
+ *		rom3 -- FLASH high large boot area hunk (224k)
+ *		rom4 -- FLASH kernel+file-system binary (1792k)
+ *		rom5 -- FLASH config file-system (top 1024k)
+ *		rom6 -- FLASH the whole thing (2MB)!
+ *
+ * (The COBRA5272 board has the same flash layout)
+ */
+    {1,0xffe00000,0x040000,flash_writeall, 0, 0, 0,    0x40000,0x040000,0xff},
+    {1,0xffe00000,0x008000,flash_writeall, 0, 0, 0,    0x08000,0x008000,0xff},
+    {1,0xffe08000,0x038000,0,0,flash_write,flash_erase,0x38000,0x038000,0xff},
+    {1,0xffe40000,0x1c0000,0,0,flash_write,flash_erase,0x40000,0x1c0000,0xff},
+    {1,0xfff00000,0x100000,0,0,flash_write,flash_erase,0x40000,0x100000,0xff},
+    {1,0xffe00000,0x200000,flash_writeall, 0, 0, 0,    0x40000,0x200000,0xff},
+#endif
+
+#if defined(CONFIG_COBRA5282)
+/*
+ *	senTec COBRA5282 board with 4MB FLASH.
+ *	The following devices are supported:
+ *		rom0 -- root file-system (actually in RAM)
+ *		rom1 -- FLASH boot block (256k)
+ *		rom2 -- FLASH low boot chunks (32k total)
+ *		rom3 -- FLASH high large boot area hunk (224k)
+ *		rom4 -- FLASH kernel+file-system binary (3840k)
+ *		rom5 -- FLASH config file-system (top 1024k)
+ *		rom6 -- FLASH the whole thing (4MB)!
+ *
+ * (The COBRA5272 board has the same flash layout)
+ */
+    {1,0xffc00000,0x040000,flash_writeall, 0, 0, 0,    0x40000,0x040000,0xff},
+    {1,0xffc00000,0x008000,flash_writeall, 0, 0, 0,    0x08000,0x008000,0xff},
+    {1,0xffc08000,0x038000,0,0,flash_write,flash_erase,0x38000,0x038000,0xff},
+    {1,0xffc40000,0x3c0000,0,0,flash_write,flash_erase,0x40000,0x3c0000,0xff},
+    {1,0xffd00000,0x100000,0,0,flash_write,flash_erase,0x40000,0x100000,0xff},
+    {1,0xffc00000,0x400000,flash_writeall, 0, 0, 0,    0x40000,0x400000,0xff},
+#endif
+
+
+    
+#if defined(CONFIG_SE1100)
+/* SE1100 hardware has a slightly different layout to the standard
+ * snapgear image.  We've got a disproportionately large config area which
+ * we've splatted to the end of the flash, rather than the start.  This lets
+ * us adjust sizes more easily later but hurts if we change flash size.
+ *	The following devices are supported:
+ *		rom0 -- root file-system (actually in RAM)
+ *		rom1 -- FLASH boot block (16k)
+ *		rom2 -- FLASH boot arguments (8k)
+ *		rom3 -- FLASH MAC addresses (8k)
+ *		rom4 -- FLASH kernel+file-system binary (1792k)
+ *		rom5 -- FLASH config file-system (192k)
+ *		rom6 -- FLASH the whole damn thing (2Mb)!
+ *		rom7 -- FLASH spare block (32k)
+ */
+    {1,0xf0000000,0x004000,flash_writeall, 0, 0, 0,    0x04000,0x004000,0xff},
+    {1,0xf0004000,0x002000,0,0,flash_write,flash_erase,0x02000,0x002000,0xff},
+    {1,0xf0006000,0x002000,0,0,flash_write,flash_erase,0x02000,0x002000,0xff},
+    {1,0xf0010000,0x1c0000,flash_writeall, 0, 0, 0,    0x10000,0x1e0000,0xff},
+    {1,0xf01d0000,0x030000,0,0,flash_write,flash_erase,0x10000,0x010000,0xff},
+    {1,0xf0000000,0x200000,flash_writeall, 0, 0, 0,    0x10000,0x200000,0xff},
+    {1,0xf0008000,0x08000,flash_writeall,0,flash_write,flash_erase,0x08000,0x08000,0xff},
+#elif defined(CONFIG_FLASH_SNAPGEAR)
+#if defined(CONFIG_FLASH8MB)
+/*
+ *	SnapGear hardware with 8MB FLASH.
+ *	The following devices are supported:
+ *		rom0 -- root file-system (actually in RAM)
+ *		rom1 -- FLASH boot block (128k)
+ *		rom2 -- FLASH boot arguments (128k)
+ *		rom3 -- FLASH MAC addresses (128k)
+ *		rom4 -- FLASH kernel+file-system binary (7mb)
+ *		rom5 -- FLASH config file-system (512k)
+ *		rom6 -- FLASH the whole damn thing (8Mb)!
+ *		rom7 -- FLASH spare block (128k)
+ */
+    {1,0xf0000000,0x020000,flash_writeall, 0, 0, 0,    0x20000,0x020000,0xff},
+    {1,0xf0020000,0x020000,0,0,flash_write,flash_erase,0x20000,0x020000,0xff},
+    {1,0xf0040000,0x020000,0,0,flash_write,flash_erase,0x20000,0x020000,0xff},
+    {1,0xf0100000,0x700000,flash_writeall, 0, 0, 0,    0x20000,0x700000,0xff},
+    {1,0xf0080000,0x080000,0,0,flash_write,flash_erase,0x20000,0x080000,0xff},
+    {1,0xf0000000,0x800000,flash_writeall, 0, 0, 0,    0x20000,0x800000,0xff},
+    {1,0xf0060000,0x020000,flash_writeall,0,flash_write,flash_erase,0x20000,0x02000,0xff},
+#if defined(CONFIG_EXTRA_FLASH)
+/*
+ *		rom8 -- FLASH extra.
+ */
+    {1,0xf0800000,0x800000,flash_writeall, 0, 0, 0,  0x10000,0x800000,0xff},
+#endif /* CONFIG_EXTRA_FLASH */
+#elif defined(CONFIG_FLASH4MB)
+/*
+ *	SnapGear hardware with 4MB FLASH.
+ *	The following devices are supported:
+ *		rom0 -- root file-system (actually in RAM)
+ *		rom1 -- FLASH boot block (16k)
+ *		rom2 -- FLASH boot arguments (8k)
+ *		rom3 -- FLASH MAC addresses (8k)
+ *		rom4 -- FLASH kernel+file-system binary (3920k)
+ *		rom5 -- FLASH config file-system (64k)
+ *		rom6 -- FLASH the whole damn thing (4Mb)!
+ *		rom7 -- FLASH spare block (32k)
+ */
+    {1,0xf0000000,0x004000,flash_writeall, 0, 0, 0,    0x04000,0x004000,0xff},
+    {1,0xf0004000,0x002000,0,0,flash_write,flash_erase,0x02000,0x002000,0xff},
+    {1,0xf0006000,0x002000,0,0,flash_write,flash_erase,0x02000,0x002000,0xff},
+    {1,0xf0020000,0x3e0000,flash_writeall, 0, 0, 0,    0x10000,0x3e0000,0xff},
+    {1,0xf0010000,0x010000,0,0,flash_write,flash_erase,0x10000,0x010000,0xff},
+    {1,0xf0000000,0x400000,flash_writeall, 0, 0, 0,    0x10000,0x400000,0xff},
+    {1,0xf0008000,0x08000,flash_writeall,0,flash_write,flash_erase,0x08000,0x08000,0xff},
+#if defined(CONFIG_EXTRA_FLASH)
+/*
+ *		rom8 -- FLASH extra.
+ */
+    {1,0xf0400000,0x400000,flash_writeall, 0, 0, 0,  0x10000,0x400000,0xff},
+#endif /* CONFIG_EXTRA_FLASH */
+#elif defined(CONFIG_FLASH2MB)
+/*
+ *	SnapGear hardware with primary 2MB FLASH.
+ *	The following devices are supported:
+ *		rom0 -- root file-system (actually in RAM)
+ *		rom1 -- FLASH boot block (16k)
+ *		rom2 -- FLASH boot arguments (8k)
+ *		rom3 -- FLASH MAC addresses (8k)
+ *		rom4 -- FLASH kernel+file-system binary (1920k)
+ *		rom5 -- FLASH config file-system (64k)
+ *		rom6 -- FLASH the whole damn thing (2Mb)!
+ *		rom7 -- FLASH spare block (32k)
+ */
+    {1,0xf0000000,0x004000,flash_writeall, 0, 0, 0,    0x04000,0x004000,0xff},
+    {1,0xf0004000,0x002000,0,0,flash_write,flash_erase,0x02000,0x002000,0xff},
+    {1,0xf0006000,0x002000,0,0,flash_write,flash_erase,0x02000,0x002000,0xff},
+    {1,0xf0020000,0x1e0000,flash_writeall, 0, 0, 0,    0x10000,0x1e0000,0xff},
+    {1,0xf0010000,0x010000,0,0,flash_write,flash_erase,0x10000,0x010000,0xff},
+    {1,0xf0000000,0x200000,flash_writeall, 0, 0, 0,    0x10000,0x200000,0xff},
+    {1,0xf0008000,0x08000,flash_writeall,0,flash_write,flash_erase,0x08000,0x08000,0xff},
+#if defined(CONFIG_EXTRA_FLASH)
+/*
+ *		rom8 -- FLASH extra.
+ */
+    {1,0xf0200000,0x200000,flash_writeall, 0, 0, 0,  0x10000,0x200000,0xff},
+#endif /* CONFIG_EXTRA_FLASH */
+#else
+/*
+ *	SnapGear hardware FLASH erase/program entry points (1MB FLASH).
+ *	The following devices are supported:
+ *		rom0 -- root file-system (actually in RAM)
+ *		rom1 -- FLASH boot block (16k)
+ *		rom2 -- FLASH boot arguments (8k)
+ *		rom3 -- FLASH MAC addresses (8k)
+ *		rom4 -- FLASH kernel+file-system binary (896k)
+ *		rom5 -- FLASH config file-system (64k)
+ *		rom6 -- FLASH the whole damn thing (1Mb)!
+ *		rom7 -- FLASH spare block (32k)
+ */
+    {1,0xf0000000,0x04000,flash_writeall, 0, 0, 0,    0x04000,0x04000,0xff},
+    {1,0xf0004000,0x02000,0,0,flash_write,flash_erase,0x02000,0x02000,0xff},
+    {1,0xf0006000,0x02000,0,0,flash_write,flash_erase,0x02000,0x02000,0xff},
+    {1,0xf0010000,0xe0000,flash_writeall, 0, 0, 0,    0x10000,0xe0000,0xff},
+    {1,0xf00f0000,0x10000,0,0,flash_write,flash_erase,0x10000,0x10000,0xff},
+    {1,0xf0000000,0x100000,flash_writeall, 0, 0, 0,  0x10000,0x100000,0xff},
+    {1,0xf0008000,0x08000,flash_writeall,0,flash_write,flash_erase,0x08000,0x08000,0xff},
+#if defined(CONFIG_EXTRA_FLASH)
+/*
+ *		rom8 -- FLASH extra. where the NETtel3540 stores the dsl image
+ */
+    {1,0xf0100000,0x100000,flash_writeall, 0, 0, 0,  0x10000,0x100000,0xff},
+#endif /* CONFIG_EXTRA_FLASH */
+#endif /* CONFIG_FLASH2MB */
+#endif /* CONFIG_FLASH_SNAPGEAR */
+
+#if defined(CONFIG_HW_FEITH)
+
+#if defined(CONFIG_CLEOPATRA) || defined(CONFIG_SCALES)
+/*
+ *	CLEOPATRA with 2MB/4MB FLASH erase/program entry points.
+ *	The following devices are supported:
+ *		rom0 -- root file-system (actually in RAM)
+ *		rom1 -- FLASH boot block (16k)
+ *		rom2 -- FLASH boot arguments (8k)
+ *		rom3 -- FLASH MAC addresses (8k)
+ *		rom4 -- FLASH kernel+file-system binary (1792k)
+ *		rom5 -- FLASH config file-system (64k)
+ *		rom6 -- FLASH the whole damn thing (2Mb)!
+ *		rom7 -- FLASH spare block (32k)
+ *		rom8 -- FLASH application config (128k)
+ *		rom9 -- FLASH user block (1536k) (4MB only)
+ *		rom10-- FLASH user block (512k) (4MB only)
+ *		rom11-- FLASH user block (2048k) (6MB only)
+ */
+    {1,0xf0000000,0x004000,flash_writeall, 0, 0, 0,    0x04000,0x004000,0xff},
+    {1,0xf0004000,0x002000,0,0,flash_write,flash_erase,0x02000,0x002000,0xff},
+    {1,0xf0006000,0x002000,0,0,flash_write,flash_erase,0x02000,0x002000,0xff},
+    {1,0xf0020000,0x1c0000,flash_writeall, 0, 0, 0,    0x10000,0x1c0000,0xff},
+    {1,0xf0010000,0x010000,0,0,flash_write,flash_erase,0x10000,0x010000,0xff},
+    {1,0xf0000000,0x200000,flash_writeall, 0, 0, 0,    0x10000,0x200000,0xff},
+    {1,0xf0008000,0x08000,flash_writeall,0,flash_write,flash_erase,0x08000,0x08000,0xff},
+    {1,0xf01e0000,0x020000,0,0,flash_write,flash_erase,0x10000,0x020000,0xff},
+#if defined(CONFIG_FLASH4MB)
+    {1,0xf0200000,0x180000,0,0,flash_write,flash_erase,0x10000,0x180000,0xff},
+    {1,0xf0380000,0x080000,0,0,flash_write,flash_erase,0x10000,0x080000,0xff},
+#endif
+
+#if defined(CONFIG_FLASH6MB)
+    {1,0xf0200000,0x180000,0,0,flash_write,flash_erase,0x10000,0x180000,0xff},
+    {1,0xf0380000,0x080000,0,0,flash_write,flash_erase,0x10000,0x080000,0xff},
+	 // old settings
+    {1,0xf0400000,0x200000,0,0,flash_write,flash_erase,0x10000,0x200000,0xff},
+	// new settings
+//    {1,0xf0410000,0x040000,flash_writeall,0, flash_write,flash_erase,0x10000,0x040000,0xff},
+//    {1,0xf0450000,0x1b0000,0,0,flash_write,flash_erase,0x10000,0x1b0000,0xff},
+
+#endif
+#endif /* CONFIG_CLEOPATRA || CONFIG_SCALES */
+
+#if defined(CONFIG_CANCam)
+/*
+ *	CanCam with 8MB FLASH erase/program entry points.
+ *	The following devices are supported:
+ *		rom0 -- root file-system (actually in RAM)
+ *		rom1 -- FLASH boot block (64k)
+ *		rom2 -- FLASH boot arguments (64k)
+ *		rom3 -- FLASH MAC addresses (64k)
+ *		rom4 -- FLASH kernel+file-system binary (1728k)
+ *		rom5 -- FLASH config file-system (64k)
+ *		rom6 -- FLASH the whole damn thing (8Mb)!
+ *		rom7 -- FLASH spare block (64k)
+ *		rom8 -- FLASH user block (6MB)
+ */
+    {1,0xf0000000,0x010000,flash_writeall, 0, 0, 0,    0x10000,0x010000,0xff},
+    {1,0xf0010000,0x010000,0,0,flash_write,flash_erase,0x10000,0x010000,0xff},
+    {1,0xf0020000,0x010000,0,0,flash_write,flash_erase,0x10000,0x010000,0xff},
+    {1,0xf0050000,0x1b0000,flash_writeall, 0, 0, 0,    0x10000,0x1b0000,0xff},
+    {1,0xf0040000,0x010000,0,0,flash_write,flash_erase,0x10000,0x010000,0xff},
+    {1,0xf0000000,0x800000,flash_writeall, 0, 0, 0,    0x10000,0x800000,0xff},
+    {1,0xf0030000,0x010000,flash_writeall,0,flash_write,flash_erase,0x10000,0x10000,0xff},
+    {1,0xf0200000,0x600000,0,0,flash_write,flash_erase,0x10000,0x600000,0xff},
+#endif /* CONFIG_CanCam */
+#endif /* CONFIG_HW_FEITH */
+
+#endif /* CONFIG_COLDFIRE */
+
+
+#ifdef CONFIG_SHGLCORE
+
+#ifdef CONFIG_SHGLCORE_2MEG
+	{0, 0x0A0000, 0x200000-0x0A0000},	/* ROM FS */
+	{1, SHGLCORE_FLASH_BANK_0_ADDR, 0x80000, 0, 0, write_spare, erase_spare, 0x10000, 0x80000, 0xff},
+	{1, 0x000000, 0x200000, program_main, 0,0,0, 0x20000, 0x100000}, /* All main FLASH */
+#else
+	{0, 0x0A0000, 0x100000-0x0A0000},	/* ROM FS */
+	{1, SHGLCORE_FLASH_BANK_0_ADDR, 0x80000, 0, 0, write_spare, erase_spare, 0x10000, 0x80000, 0xff},
+	{1, 0x000000, 0x100000, program_main, 0,0,0, 0x20000, 0x100000}, /* All main FLASH */
+#endif
+
+#define FIXUP_ARENAS \
+	extern unsigned long rom_length; \
+	arena[0].length = (unsigned long)rom_length - 0xA0000; \
+	arena[2].length = (unsigned long)rom_length;
+
+#endif
+};
+
+#define arenas (sizeof(arena) / sizeof(struct arena_t))
+
+
+static int blkmem_blocksizes[arenas];
+static int blkmem_sizes[arenas];
+static devfs_handle_t devfs_handle;
+
+
+#if defined(CONFIG_ARNEWSH) || defined(CONFIG_M5206eC3)
+
+static DECLARE_MUTEX(spare_lock);
+
+/*
+ *	FLASH erase and programming routines for the odd/even FLASH
+ *	pair on the ColdFire eval boards.
+ */
+
+void flash_amd8_pair_write(struct arena_t * a, unsigned long pos, unsigned long length, char * buffer)
+{
+  volatile unsigned short *address;
+  unsigned short *wbuf, word;
+  unsigned short result, prevresult;
+  unsigned long flags, start;
+  unsigned long fbase = a->address;
+  int i;
+  
+#if 0
+  printk("%s(%d): flash_amd8_pair_write(a=%x,pos=%x,length=%d,buf=%x)\n",
+	__FILE__, __LINE__, (int) a, (int) pos, (int) length, (int) buffer);
+#endif
+
+  down(&spare_lock);
+
+  start = jiffies;
+  address = (unsigned volatile short *) (fbase + pos);
+  wbuf = (unsigned short *) buffer;
+
+  for (length >>= 1; (length > 0); length--, address++) {
+  
+    word = *wbuf++;
+
+    if (*address != word) {
+      save_flags(flags); cli();
+
+      *((unsigned volatile short *) (fbase | (0x5555 << 1))) = 0xaaaa;
+      *((unsigned volatile short *) (fbase | (0x2aaa << 1))) = 0x5555;
+      *((unsigned volatile short *) (fbase | (0x5555 << 1))) = 0xa0a0;
+      *address = word;
+      udelay(1);
+
+      /* Wait for write to complete, timeout after a few tries */
+      for (prevresult = 0, i = 0; (i < 0x10000); i++) {
+        result = *address;
+        if ((result & 0x8080) == (word & 0x8080))
+          break;
+	if ((result & 0x4040) == (prevresult & 0x4040))
+	  break;
+	prevresult = result;
+      }
+ 
+      if (*address != word) {
+          printk("%s(%d): FLASH write failed, address %p, write value %x"
+		" (now %x, previous %x), count=%d\n", __FILE__, __LINE__,
+		address, word, *address, prevresult, i);
+	  printk("%s(%d): count=%d word=%x prevresult=%x result=%x\n",
+                __FILE__, __LINE__, i, word, prevresult, result);
+          *((unsigned volatile short *) fbase) = 0xf0f0; /* Reset */
+      }
+      restore_flags(flags);
+    }
+  }
+  
+  up(&spare_lock);
+}
+
+void flash_amd8_pair_erase(struct arena_t * a, unsigned long pos)
+{
+  unsigned volatile short *address;
+  unsigned short result;
+  unsigned long fbase = a->address;
+  unsigned long flags;
+  
+#if 0
+    printk("%s(%d): flash_amd8_pair_erase(): addr:%x, len:%x, pos:%x\n",
+	__FILE__, __LINE__, a->address, a->length, pos);
+#endif
+
+  if (pos >= a->length)
+    return;
+
+  address = (unsigned volatile short *) (fbase + pos);
+
+  /* Mutex all access to FLASH memory */
+  down(&spare_lock);
+  save_flags(flags); cli();
+
+  /* Initiate erase of FLASH sector */
+#ifdef CONFIG_ARN5206
+  *((unsigned volatile short *) (fbase | (0x5555 << 1))) = 0xaaaa;
+  *((unsigned volatile short *) (fbase | (0x2aaa << 1))) = 0x5555;
+  *((unsigned volatile short *) (fbase | (0x5555 << 1))) = 0x8080;
+  *((unsigned volatile short *) (fbase | (0x5555 << 1))) = 0xaaaa;
+  *((unsigned volatile short *) (fbase | (0x2aaa << 1))) = 0x5555;
+  *address = 0x3030;
+#else
+  *((unsigned volatile short *) (fbase | (0x0555 << 1))) = 0xaaaa;/*first*/
+  *((unsigned volatile short *) (fbase | (0x02aa << 1))) = 0x5555;/*second*/
+  *((unsigned volatile short *) (fbase | (0x0555 << 1))) = 0x8080;/*third*/
+  *((unsigned volatile short *) (fbase | (0x0555 << 1))) = 0xaaaa;/*fourth*/
+  *((unsigned volatile short *) (fbase | (0x02aa << 1))) = 0x5555;/*fifth*/
+  *address = 0x3030;    /* sixth (0x30 to sector address) */
+#endif
+
+    for (;;) {
+	result = *address;
+/*	printk("result: %x\n", result);    */
+	if ((result & 0x8080) == 0x8080)
+	    break;    /* sucessful erase */
+	if (((result & 0xff00) != 0xff00) && (result & 0x2000)) {
+	     printk("%s(%d): erase failed: high byte, address %p\n",
+		    __FILE__, __LINE__, address);
+	     *((unsigned volatile short *) fbase) = 0xf0f0; /* Reset */
+	    break;
+	}    
+	if (((result & 0x00ff) != 0x00ff) && (result & 0x0020)) {
+	     printk("%s(%d): erase failed: low byte, address %p\n",
+		    __FILE__, __LINE__, address);
+	     *((unsigned volatile short *) fbase) = 0xf0f0; /* Reset */
+	    break;
+	}
+    }
+
+  restore_flags(flags);
+  up(&spare_lock);
+}
+#endif    /* CONFIG_ARNEWSH || CONFIG_M5206eC3 */
+
+/****************************************************************************/
+/*                       SNAPGEAR FLASH SUPPORT                             */
+/****************************************************************************/
+
+#if defined(CONFIG_FLASH_SNAPGEAR) || defined(CONFIG_HW_FEITH) || defined(CONFIG_M5272C3) || defined(CONFIG_COBRA5272) || defined(CONFIG_COBRA5282)
+
+static DECLARE_MUTEX(spare_lock);
+
+/*
+ *	Offsets to support the small boot segments of bottom booter flash.
+ */
+unsigned long flash_bootsegs[] = {
+#if defined(CONFIG_FLASH4MB)
+	/* This supports the AMD 29lv320 -- 8 * 8k segments */
+	0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000,
+#else
+	/* This supports the AMD 29lv800, 29lv160, etc -- 16k + 8k + 8k + 32k */
+	0x4000, 0x2000, 0x2000, 0x8000,
+#endif
+};
+
+#if defined(CONFIG_FLASH2MB)
+#define	FLASHMASK	0x001fffff
+#elif defined(CONFIG_FLASH4MB)
+#define	FLASHMASK	0x003fffff
+#elif defined(CONFIG_FLASH8MB)
+#define	FLASHMASK	0x007fffff
+#elif defined(CONFIG_FLASH16MB)
+#define	FLASHMASK	0x00ffffff
+#else
+#define	FLASHMASK	0x000fffff
+#endif
+
+/*
+ *	Support erasing and dumping to scratch FLASH segment.
+ */
+unsigned long	flash_dumpoffset = 0;
+
+void flash_erasedump(void)
+{
+	flash_erase(arena + 7, 0);
+}
+
+void flash_writedump(char *buf, int len)
+{
+	flash_write(arena + 7, 0, len, (char *) buf);
+}
+
+/****************************************************************************/
+/*                            AMD 8bit FLASH                                */
+/****************************************************************************/
+
+#if defined(CONFIG_FLASH8BIT)
+
+/*
+ *	FLASH erase routine for the AMD 29LVX00 family devices.
+ */
+
+static void flash_amd8_erase(struct arena_t *a, unsigned long pos)
+{
+  unsigned volatile char *address;
+  unsigned long fbase = a->address;
+  unsigned long flags;
+  unsigned char status;
+  int i;
+  
+#if 0
+  printk("%s(%d): flash_amd8_erase(a=%x,pos=%x)\n", __FILE__, __LINE__,
+    (int) a, (int) pos);
+#endif
+
+  if (pos >= a->length)
+    return;
+
+  address = (unsigned volatile char *) (fbase + pos);
+
+  /* Mutex all access to FLASH memory */
+  down(&spare_lock);
+  save_flags(flags); cli();
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_disable();
+#endif
+
+  /* Erase this sector */
+  *((volatile unsigned char *) (fbase | 0xaaa)) = 0xaa;
+  *((volatile unsigned char *) (fbase | 0x555)) = 0x55;
+  *((volatile unsigned char *) (fbase | 0xaaa)) = 0x80;
+  *((volatile unsigned char *) (fbase | 0xaaa)) = 0xaa;
+  *((volatile unsigned char *) (fbase | 0x555)) = 0x55;
+  *address = 0x30;
+
+  for (i = 0; (i < FTIMEOUT); i++) {
+    status = *address;
+    if ((status & 0x80) || (status & 0x20))
+      break;
+  }
+
+  if (*address != 0xff) {
+     printk("%s(%d): FLASH erase failed, address %p iteration=%d status=%x\n",
+		__FILE__, __LINE__, address, i, status);
+     *((unsigned volatile char *) fbase) = 0xf0; /* Reset */
+  }
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_enable();
+#endif
+
+  restore_flags(flags);
+  up(&spare_lock);
+}
+
+/*
+ *	FLASH programming routine for the 29LVX00 device family.
+ */
+
+static void flash_amd8_write(struct arena_t * a, unsigned long pos, unsigned long length, char * buffer)
+{
+  volatile unsigned char *address;
+  unsigned long flags, fbase = a->address;
+  unsigned char *wbuf, status;
+  int i;
+  
+#if 0
+  printk("%s(%d): flash_amd8_write(a=%x,pos=%x,length=%d,buf=%x)\n",
+	__FILE__, __LINE__, (int) a, (int) pos, (int) length, (int) buffer);
+#endif
+
+  down(&spare_lock);
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_disable();
+#endif
+
+  address = (unsigned volatile char *) (fbase + pos);
+  wbuf = (unsigned char *) buffer;
+
+  for (; (length > 0); length--, address++, wbuf++) {
+  
+    if (*address != *wbuf) {
+      save_flags(flags); cli();
+
+      *((volatile unsigned char *) (fbase | 0xaaa)) = 0xaa;
+      *((volatile unsigned char *) (fbase | 0x555)) = 0x55;
+      *((volatile unsigned char *) (fbase | 0xaaa)) = 0xa0;
+      *address = *wbuf;
+
+      for (i = 0; (i < FTIMEOUT); i++) {
+	status = *address;
+	if (status == *wbuf) {
+	  /* Program complete */
+	  break;
+	}
+      }
+
+      if (*address != *wbuf) {
+          printk("%s(%d): FLASH write failed i=%d, address %p -> %x(%x)\n",
+		__FILE__, __LINE__, i, address, *wbuf, *address);
+          *((unsigned volatile char *) fbase) = 0xf0; /* Reset */
+      }
+
+      restore_flags(flags);
+    }
+  }
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_enable();
+#endif
+
+  up(&spare_lock);
+}
+
+
+/*
+ *	Program a complete FLASH image. This runs from DRAM, so no
+ *	need to worry about writing to what we are running from...
+ */
+
+static void flash_amd8_writeall(struct arena_t * a, struct blkmem_program_t * prog)
+{
+  unsigned long		base, offset, erased;
+  unsigned long		ptr, min, max;
+  unsigned char		*w, status;
+  int			failures;
+  int			i, j, l;
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_disable();
+#endif
+  
+#if 0
+  printk("FLASH: programming");
+#endif
+  failures = 0;
+  erased = 0;
+
+  cli();
+  
+  for (i = 0; (i < prog->blocks); i++) {
+
+#if 0
+    printk("%s(%d): block=%d address=%x pos=%x length=%x range=%x-%x\n",
+      __FILE__, __LINE__, i, (int) a->address, (int) prog->block[i].pos,
+      (int) prog->block[i].length, (int) (prog->block[i].pos + a->address),
+      (int) (prog->block[i].pos + prog->block[i].length - 1 + a->address));
+#endif
+
+    /*
+     *	Erase FLASH sectors for this program block...
+     */
+    for (l = prog->block[i].pos / a->blksize;
+	l <= ((prog->block[i].pos+prog->block[i].length-1) / a->blksize);
+	l++) {
+
+      if (erased & (0x1 << l))
+	continue;
+
+      ptr = l * a->blksize;
+      offset = ptr % a->unitsize;
+      base = ptr - offset;
+	
+      base += a->address;
+      ptr += a->address;
+      j = 0;
+
+flash_redo:
+
+#if 0
+      printk("%s(%d): ERASE BLOCK sector=%d base=%x offset=%x ptr=%x\n",
+	  __FILE__, __LINE__, l, (int) base, (int) offset, (int) ptr);
+#endif
+
+      /* Erase this sector */
+      *((volatile unsigned char *) (base | 0xaaa)) = 0xaa;
+      *((volatile unsigned char *) (base | 0x555)) = 0x55;
+      *((volatile unsigned char *) (base | 0xaaa)) = 0x80;
+      *((volatile unsigned char *) (base | 0xaaa)) = 0xaa;
+      *((volatile unsigned char *) (base | 0x555)) = 0x55;
+      *((volatile unsigned char *) ptr) = 0x30;
+
+      for (;;) {
+	status = *((volatile unsigned char *) ptr);
+	if (status & 0x80) {
+	  /* Erase complete */
+	  break;
+	}
+	if (status & 0x20) {
+	  printk("FLASH: (%d) erase failed\n", __LINE__);
+	  /* Reset FLASH unit */
+	  *((volatile unsigned char *) base) = 0xf0;
+	  failures++;
+	  /* Continue (with unerased sector) */
+	  break;
+	}
+      }
+
+      /*
+       * Some flash have a set of small segments at the top or bottom.
+       * These need to be erased individually, even better, different
+       * devices uses different segment sizes :-(
+       * This code currently only handles bottom booters...
+       */
+      if ((ptr & FLASHMASK) < 64*1024) {
+	ptr += flash_bootsegs[j++];
+        if ((ptr - base) < a->length)
+	  goto flash_redo;
+      }
+
+      erased |= (0x1 << l);
+    }
+
+    /*
+     *	Program FLASH with the block data...
+     */
+    min = prog->block[i].pos+a->address;
+    max = prog->block[i].pos+prog->block[i].length+a->address;
+    w = (unsigned char *) prog->block[i].data;
+
+    /* Progress indicators... */
+    printk(".");
+#ifdef CONFIG_LEDMAN
+	if (i & 1) {
+		ledman_cmd(LEDMAN_CMD_OFF, LEDMAN_NVRAM_1);
+		ledman_cmd(LEDMAN_CMD_ON,  LEDMAN_NVRAM_2);
+	} else {
+		ledman_cmd(LEDMAN_CMD_ON,  LEDMAN_NVRAM_1);
+		ledman_cmd(LEDMAN_CMD_OFF, LEDMAN_NVRAM_2);
+	}
+#endif
+
+#if 0
+    printk("%s(%d): PROGRAM BLOCK min=%x max=%x\n", __FILE__, __LINE__,
+      (int) min, (int) max);
+#endif
+
+    for (ptr = min; (ptr < max); ptr++, w++) {
+      
+      offset = (ptr - a->address) % a->unitsize;
+      base = ptr - offset;
+
+#if 0
+      printk("%s(%d): PROGRAM base=%x offset=%x ptr=%x value=%x\n",
+	  __FILE__, __LINE__, (int) base, (int) offset, (int) ptr, (int) *w);
+#endif
+
+      *((volatile unsigned char *) (base | 0xaaa)) = 0xaa;
+      *((volatile unsigned char *) (base | 0x555)) = 0x55;
+      *((volatile unsigned char *) (base | 0xaaa)) = 0xa0;
+      *((volatile unsigned char *) ptr) = *w;
+
+      for (j = 0; (j < FTIMEOUT); j++) {
+	status = *((volatile unsigned char *) ptr);
+	if (status == *w) {
+	  /* Program complete */
+	  break;
+	}
+      }
+
+      status = *((volatile unsigned char *) ptr);
+      if (status != *w) {
+	printk("FLASH: (%d) write failed, addr=%x val=%x status=%x cnt=%d\n",
+		__LINE__, (int) ptr, *w, status, j);
+	/* Reset FLASH unit */
+	*((volatile unsigned char *) ptr) = 0xf0;
+	failures++;
+      }
+    }
+  }
+
+#ifdef CONFIG_LEDMAN
+  ledman_cmd(LEDMAN_CMD_RESET, LEDMAN_NVRAM_1);
+  ledman_cmd(LEDMAN_CMD_RESET, LEDMAN_NVRAM_2);
+#endif
+
+  if (failures > 0) {
+    printk("FLASH: %d failures programming FLASH!\n", failures);
+    return;
+  }
+
+#if 0
+  printk("\nFLASH: programming successful!\n");
+#endif
+  if (prog->reset) {
+    printk("FLASH: rebooting...\n\n");
+    HARD_RESET_NOW();
+  }
+}
+
+/****************************************************************************/
+/*                            AMD 16bit FLASH                               */
+/****************************************************************************/
+
+#else
+
+/*
+ *	FLASH erase routine for the AMD 29LVxxx family devices.
+ */
+
+static void flash_amd16_erase(struct arena_t *a, unsigned long pos)
+{
+  unsigned volatile short *address;
+  unsigned long fbase = a->address;
+  unsigned long flags;
+  unsigned short status;
+  int i;
+  
+#if 0
+  printk("%s(%d): flash_amd16_erase(a=%x,pos=%x)\n", __FILE__, __LINE__,
+    (int) a, (int) pos);
+#endif
+
+  if (pos >= a->length)
+    return;
+
+  address = (unsigned volatile short *) (fbase + pos);
+
+  /* Mutex all access to FLASH memory */
+  down(&spare_lock);
+  save_flags(flags); cli();
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_disable();
+#endif
+
+  /* Erase this sector */
+  *((volatile unsigned short *) (fbase | (0x555 << 1))) = 0xaaaa;
+  *((volatile unsigned short *) (fbase | (0x2aa << 1))) = 0x5555;
+  *((volatile unsigned short *) (fbase | (0x555 << 1))) = 0x8080;
+  *((volatile unsigned short *) (fbase | (0x555 << 1))) = 0xaaaa;
+  *((volatile unsigned short *) (fbase | (0x2aa << 1))) = 0x5555;
+  *address = 0x3030;
+
+  for (i = 0; (i < FTIMEOUT); i++) {
+    status = *address;
+    if ((status & 0x0080) || (status & 0x0020))
+      break;
+  }
+
+  if (*address != 0xffff) {
+     printk("%s(%d): FLASH erase failed, address %p iteration=%d status=%x\n",
+		__FILE__, __LINE__, address, i, status);
+     *((unsigned volatile short *) fbase) = 0xf0f0; /* Reset */
+  }
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_enable();
+#endif
+
+  restore_flags(flags);
+  up(&spare_lock);
+}
+
+/*
+ *	FLASH programming routine for the 29LVxxx device family.
+ */
+
+static void flash_amd16_write(struct arena_t * a, unsigned long pos, unsigned long length, char * buffer)
+{
+  volatile unsigned short *address;
+  unsigned long flags, fbase = a->address;
+  unsigned short *wbuf, status;
+  int i;
+  
+#if 0
+  printk("%s(%d): flash_amd16_write(a=%x,pos=%x,length=%d,buf=%x)\n",
+	__FILE__, __LINE__, (int) a, (int) pos, (int) length, (int) buffer);
+#endif
+
+  down(&spare_lock);
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_disable();
+#endif
+
+  address = (unsigned volatile short *) (fbase + pos);
+  wbuf = (unsigned short *) buffer;
+
+  length += 1;   /* Fix it so that an odd number of bytes gets written correctly */
+  for (length >>= 1; (length > 0); length--, address++, wbuf++) {
+  
+    if (*address != *wbuf) {
+      save_flags(flags); cli();
+
+      *((volatile unsigned short *) (fbase | (0x555 << 1))) = 0xaaaa;
+      *((volatile unsigned short *) (fbase | (0x2aa << 1))) = 0x5555;
+      *((volatile unsigned short *) (fbase | (0x555 << 1))) = 0xa0a0;
+      *address = *wbuf;
+
+      for (i = 0; (i < FTIMEOUT); i++) {
+	status = *address;
+	if (status == *wbuf) {
+	  /* Program complete */
+	  break;
+	}
+      }
+
+      if (*address != *wbuf) {
+          printk("%s(%d): FLASH write failed i=%d, address %p -> %x(%x)\n",
+		__FILE__, __LINE__, i, address, *wbuf, *address);
+          *((unsigned volatile short *) fbase) = 0xf0f0; /* Reset */
+      }
+
+      restore_flags(flags);
+    }
+  }
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_enable();
+#endif
+
+  up(&spare_lock);
+}
+
+
+/*
+ *	Program a complete FLASH image. This runs from DRAM, so no
+ *	need to worry about writing to what we are running from...
+ */
+
+static void flash_amd16_writeall(struct arena_t * a, struct blkmem_program_t * prog)
+{
+  unsigned long		base, offset, erased;
+  unsigned long		ptr, min, max;
+  unsigned short	*w, status;
+  int			failures;
+  int			i, j, l;
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_disable();
+#endif
+  
+#if 0
+  printk("FLASH: programming");
+#endif
+  failures = 0;
+  erased = 0;
+
+  cli();
+  
+  for (i = 0; (i < prog->blocks); i++) {
+
+#if 0
+    printk("%s(%d): block=%d address=%x pos=%x length=%x range=%x-%x\n",
+      __FILE__, __LINE__, i, (int) a->address, (int) prog->block[i].pos,
+      (int) prog->block[i].length, (int) (prog->block[i].pos + a->address),
+      (int) (prog->block[i].pos + prog->block[i].length - 1 + a->address));
+#endif
+
+    /*
+     *	Erase FLASH sectors for this program block...
+     */
+    for (l = prog->block[i].pos / a->blksize;
+	l <= ((prog->block[i].pos+prog->block[i].length-1) / a->blksize);
+	l++) {
+
+      if (erased & (0x1 << l))
+	continue;
+
+      ptr = l * a->blksize;
+      offset = ptr % a->unitsize;
+      base = ptr - offset;
+	
+      base += a->address;
+      ptr += a->address;
+      j = 0;
+
+flash_redo:
+
+#if 0
+      printk("%s(%d): ERASE BLOCK sector=%d base=%x offset=%x ptr=%x\n",
+	  __FILE__, __LINE__, l, (int) base, (int) offset, (int) ptr);
+#endif
+
+      /* Erase this sector */
+      /* FIX: check which byte lane the value needs to be on */
+      *((volatile unsigned short *) (base | (0x555 << 1))) = 0xaaaa;
+      *((volatile unsigned short *) (base | (0x2aa << 1))) = 0x5555;
+      *((volatile unsigned short *) (base | (0x555 << 1))) = 0x8080;
+      *((volatile unsigned short *) (base | (0x555 << 1))) = 0xaaaa;
+      *((volatile unsigned short *) (base | (0x2aa << 1))) = 0x5555;
+      *((volatile unsigned short *) ptr) = 0x3030;
+
+      for (;;) {
+	status = *((volatile unsigned short *) ptr);
+	if (status & 0x0080) {
+	  /* Erase complete */
+	  break;
+	}
+	if (status & 0x0020) {
+	  printk("FLASH: (%d) erase failed\n", __LINE__);
+	  /* Reset FLASH unit */
+	  *((volatile unsigned short *) base) = 0xf0f0;
+	  failures++;
+	  /* Continue (with unerased sector) */
+	  break;
+	}
+      }
+
+      /*
+       * Some flash have a set of small segments at the top or bottom.
+       * These need to be erased individually, even better, different
+       * devices uses different segment sizes :-(
+       * This code currently only handles bottom booters...
+       */
+      if ((ptr & FLASHMASK) < 64*1024) {
+	ptr += flash_bootsegs[j++];
+        if ((ptr - base) < a->length)
+	  goto flash_redo;
+      }
+
+      erased |= (0x1 << l);
+    }
+
+    /*
+     *	Program FLASH with the block data...
+     */
+    min = prog->block[i].pos+a->address;
+    max = prog->block[i].pos+prog->block[i].length+a->address;
+    w = (unsigned short *) prog->block[i].data;
+
+    /* Progress indicators... */
+    printk(".");
+#ifdef CONFIG_LEDMAN
+	if (i & 1) {
+		ledman_cmd(LEDMAN_CMD_OFF, LEDMAN_NVRAM_1);
+		ledman_cmd(LEDMAN_CMD_ON,  LEDMAN_NVRAM_2);
+	} else {
+		ledman_cmd(LEDMAN_CMD_ON,  LEDMAN_NVRAM_1);
+		ledman_cmd(LEDMAN_CMD_OFF, LEDMAN_NVRAM_2);
+	}
+#endif
+
+#if 0
+    printk("%s(%d): PROGRAM BLOCK min=%x max=%x\n", __FILE__, __LINE__,
+      (int) min, (int) max);
+#endif
+
+    for (ptr = min; (ptr < max); ptr += 2, w++) {
+      
+      offset = (ptr - a->address) % a->unitsize;
+      base = ptr - offset;
+
+#if 0
+      printk("%s(%d): PROGRAM base=%x offset=%x ptr=%x value=%x\n",
+	  __FILE__, __LINE__, (int) base, (int) offset, (int) ptr, (int) *w);
+#endif
+
+      *((volatile unsigned short *) (base | (0x555 << 1))) = 0xaaaa;
+      *((volatile unsigned short *) (base | (0x2aa << 1))) = 0x5555;
+      *((volatile unsigned short *) (base | (0x555 << 1))) = 0xa0a0;
+      *((volatile unsigned short *) ptr) = *w;
+
+      for (j = 0; (j < FTIMEOUT); j++) {
+	status = *((volatile unsigned short *) ptr);
+	if (status == *w) {
+	  /* Program complete */
+	  break;
+	}
+      }
+
+      status = *((volatile unsigned short *) ptr);
+      if (status != *w) {
+	printk("FLASH: (%d) write failed, addr=%x val=%x status=%x cnt=%d\n",
+		__LINE__, (int) ptr, *w, status, j);
+	/* Reset FLASH unit */
+	*((volatile unsigned short *) ptr) = 0xf0f0;
+	failures++;
+      }
+    }
+  }
+
+#ifdef CONFIG_LEDMAN
+  ledman_cmd(LEDMAN_CMD_RESET, LEDMAN_NVRAM_1);
+  ledman_cmd(LEDMAN_CMD_RESET, LEDMAN_NVRAM_2);
+#endif
+
+  if (failures > 0) {
+    printk("FLASH: %d failures programming FLASH!\n", failures);
+    return;
+  }
+
+#if 0
+  printk("\nFLASH: programming successful!\n");
+#endif
+  if (prog->reset) {
+    printk("FLASH: rebooting...\n\n");
+    HARD_RESET_NOW();
+  }
+}
+
+#endif /* !CONFIG_FLASH8BIT */
+
+/****************************************************************************/
+/*                             INTEL FLASH                                  */
+/****************************************************************************/
+#if defined(CONFIG_INTELFLASH)
+#if defined(CONFIG_FLASH16BIT)
+	typedef unsigned short itype;
+#else
+	typedef unsigned char itype;
+#endif
+
+/*
+ *	FLASH erase routine for the Intel Strata FLASH.
+ */
+
+void flash_intel_erase(struct arena_t *a, unsigned long pos)
+{
+  volatile itype *address;
+  unsigned long fbase = a->address;
+  unsigned long flags;
+  itype status;
+  int i;
+  
+#if 0
+  printk("%s(%d): flash_intel_erase(a=%x,pos=%x)\n", __FILE__, __LINE__,
+    (int) a, (int) pos);
+#endif
+
+  if (pos >= a->length)
+    return;
+
+#ifdef CONFIG_LEDMAN
+    ledman_cmd(LEDMAN_CMD_OFF, (pos&0x20000) ? LEDMAN_NVRAM_1 : LEDMAN_NVRAM_2);
+    ledman_cmd(LEDMAN_CMD_ON, (pos&0x20000) ? LEDMAN_NVRAM_2 : LEDMAN_NVRAM_1);
+#endif
+
+  address = (volatile itype *) (fbase + pos);
+
+  /* Mutex all access to FLASH memory */
+  down(&spare_lock);
+  save_flags(flags); cli();
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_disable();
+#endif
+
+#if 0
+  /* add this in if you want sectors unlocked as you erase them */
+  /* Unlock this sector */
+  *address = 0x60;
+  *address = 0xd0;
+
+  for (i = 0; (i < FTIMEOUT); i++) {
+    status = *address;
+    if (status & 0x80)
+      break;
+  }
+
+  /* Restore FLASH to normal read mode */
+  *address = 0xff;
+#endif
+
+  *address = 0x20;
+  *address = 0xd0;
+
+  for (i = 0; (i < FTIMEOUT); i++) {
+    status = *address;
+    if (status & 0x80)
+      break;
+  }
+
+  /* Restore FLASH to normal read mode */
+  *address = 0xff;
+
+  if (*address != (itype) 0xffff) {
+     printk("FLASH: (%d): erase failed, address %p iteration=%d "
+		"status=%x\n", __LINE__, address, i, (int) status);
+  }
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_enable();
+#endif
+
+  restore_flags(flags);
+  up(&spare_lock);
+}
+
+
+/*
+ *	FLASH programming routine for Intel Strata FLASH.
+ */
+
+void flash_intel_write(struct arena_t * a, unsigned long pos, unsigned long length, char * buffer)
+{
+  unsigned long		flags, ptr, min, max;
+  itype			*lp, *lp0, status;
+  int			failures, j, k, l;
+  
+#if 0
+  printk("%s(%d): flash_intel_write(a=%x,pos=%x,length=%d,buf=%x)\n",
+	__FILE__, __LINE__, (int) a, (int) pos, (int) length, (int) buffer);
+#endif
+
+  down(&spare_lock);
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_disable();
+#endif
+
+  min = (a->address + pos);
+  max = min + length;
+  lp = (itype *) buffer;
+
+  for (ptr = min; (ptr < max); ptr += l) {
+
+      save_flags(flags); cli();
+
+      /* Determine write size */
+      lp0 = lp;
+      j = max - ptr;
+      l = (j < 32) ? j : 32;
+      if ((ptr & ~0x1f) != ptr) {
+	j = 32 - (ptr & 0x1f);
+	l = (l < j) ? l : j;
+      }
+
+      /* Program next buffer bytes */
+      for (j = 0; (j < FTIMEOUT); j++) {
+	*((volatile itype *) ptr) = 0xe8;
+	status = *((volatile itype *) ptr);
+	if (status & 0x80)
+	  break;
+      }
+      if ((status & 0x80) == 0)
+	goto writealldone;
+
+      *((volatile itype *) ptr) = (l-1)/sizeof(itype);
+      for (j = 0; j < l; j += sizeof(itype))
+	*((volatile itype *) (ptr+j)) = *lp++;
+
+      *((volatile itype *) ptr) = 0xd0;
+
+      for (j = 0; (j < FTIMEOUT); j++) {
+	status = *((volatile itype *) ptr);
+	if (status & 0x80) {
+	  /* Program complete */
+	  break;
+	}
+      }
+
+writealldone:
+      /* Restore FLASH to normal read mode */
+      *((volatile itype *) ptr) = 0xff;
+
+      for (k = 0; k < l; k += sizeof(itype), lp0++) {
+      	status = *((volatile itype *) (ptr+k));
+        if (status != *lp0) {
+		printk("FLASH: (%d): write failed, addr=%08x wrote=%x "
+		"read=%x cnt=%d len=%d\n",
+		__LINE__, (int) (ptr+k), (int) *lp0, (int) status, j, l);
+		failures++;
+	}
+      }
+
+      restore_flags(flags);
+    }
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_enable();
+#endif
+
+  up(&spare_lock);
+}
+
+
+#if 0
+/*
+ *	Slow FLASH programming routine for Intel Strata FLASH.
+ */
+void flash_intel_writeslow(struct arena_t * a, unsigned long pos, unsigned long length, char * buffer)
+{
+  volatile unsigned char *address;
+  unsigned long flags, fbase = a->address;
+  unsigned char *lbuf, status;
+  int i;
+  
+#if 0
+  printk("%s(%d): flash_intel_write(a=%x,pos=%x,length=%d,buf=%x)\n",
+	__FILE__, __LINE__, (int) a, (int) pos, (int) length, (int) buffer);
+#endif
+
+  down(&spare_lock);
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_disable();
+#endif
+
+  address = (unsigned volatile char *) (fbase + pos);
+  lbuf = (unsigned char *) buffer;
+
+  for (; (length > 0); length--, address++, lbuf++) {
+  
+    if (*address != *lbuf) {
+      save_flags(flags); cli();
+
+      *address = 0x40;
+      *address = *lbuf;
+
+      for (i = 0; (i < FTIMEOUT); i++) {
+	status = *address;
+	if (status & 0x80) {
+	  /* Program complete */
+	  break;
+	}
+      }
+
+      /* Restore FLASH to normal read mode */
+      *address = 0xff;
+
+      if (*address != *lbuf) {
+          printk("FLASH: (%d): write failed i=%d, address %p -> %x(%x)\n",
+		__LINE__, i, address, (int) *lbuf, (int) *address);
+      }
+
+      restore_flags(flags);
+    }
+  }
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_enable();
+#endif
+
+  up(&spare_lock);
+}
+#endif
+
+
+/*
+ *	Program a complete FLASH image into an Intel Strata FLASH part.
+ *	This runs from DRAM, so no need to worry about writing to what
+ *	we are running from...
+ */
+
+void flash_intel_writeall(struct arena_t * a, struct blkmem_program_t * prog)
+{
+  unsigned long		erased[16];
+  unsigned long		base, offset, ptr, min, max;
+  unsigned char		*lp, *lp0, status;
+  int			failures, i, j, k, l;
+
+#if defined(CONFIG_WATCHDOG)
+  watchdog_disable();
+#endif
+
+#if 0
+  printk("FLASH: programming");
+#endif
+  failures = 0;
+  memset(&erased[0], 0, sizeof(erased));
+
+  cli();
+  
+  for (i = 0; (i < prog->blocks); i++) {
+
+#if 0
+    printk("%s(%d): block=%d address=%x pos=%x length=%x range=%x-%x\n",
+      __FILE__, __LINE__, i, (int) a->address, (int) prog->block[i].pos,
+      (int) prog->block[i].length, (int) (prog->block[i].pos + a->address),
+      (int) (prog->block[i].pos + prog->block[i].length - 1 + a->address));
+#endif
+
+    /*
+     *	Erase FLASH sectors for this program block...
+     */
+    for (l = prog->block[i].pos / a->blksize;
+	l <= ((prog->block[i].pos+prog->block[i].length-1) / a->blksize);
+	l++) {
+
+      if (erased[(l / 32)] & (0x1 << (l % 32)))
+	continue;
+
+      ptr = l * a->blksize;
+      offset = ptr % a->unitsize;
+      base = ptr - offset;
+
+      base += a->address;
+      ptr += a->address;
+      j = 0;
+
+#if 0
+      printk("%s(%d): ERASE BLOCK sector=%d ptr=%x\n",
+	  __FILE__, __LINE__, l, (int) ptr);
+#endif
+
+      /* Erase this sector */
+      *((volatile unsigned char *) ptr) = 0x20;
+      *((volatile unsigned char *) ptr) = 0xd0;
+
+      for (k = 0; (k < FTIMEOUT); k++) {
+	status = *((volatile unsigned char *) ptr);
+	if (status & 0x80) {
+	  /* Erase complete */
+	  status = *((volatile unsigned char *) ptr);
+	  break;
+	}
+      }
+
+      /* Restore FLASH to normal read mode */
+      *((volatile unsigned char *) ptr) = 0xff;
+
+      if (k >= FTIMEOUT) {
+	  printk("FLASH: (%d) erase failed, status=%08x\n",
+		__LINE__, (int) status);
+	  failures++;
+	  /* Continue (with unerased sector) */
+	  break;
+      }
+
+      erased[(l / 32)] |= (0x1 << (l % 32));
+    }
+
+    /*
+     *	Program FLASH with the block data...
+     */
+    min = prog->block[i].pos+a->address;
+    max = prog->block[i].pos+prog->block[i].length+a->address;
+    lp = (unsigned char *) prog->block[i].data;
+
+    /* Progress indicators... */
+    printk(".");
+#ifdef CONFIG_LEDMAN
+    ledman_cmd(LEDMAN_CMD_OFF, (i & 1) ? LEDMAN_NVRAM_1 : LEDMAN_NVRAM_2);
+    ledman_cmd(LEDMAN_CMD_ON, (i & 1) ? LEDMAN_NVRAM_2 : LEDMAN_NVRAM_1);
+#endif
+
+#if 0
+    printk("%s(%d): PROGRAM BLOCK min=%x max=%x\n", __FILE__, __LINE__,
+      (int) min, (int) max);
+#endif
+
+
+    for (ptr = min; (ptr < max); ptr += l) {
+
+      /* Determine write size */
+      lp0 = lp;
+      j = max - ptr;
+      l = (j < 32) ? j : 32;
+      if ((ptr & ~0x1f) != ptr) {
+	j = 32 - (ptr & 0x1f);
+	l = (l < j) ? l : j;
+      }
+
+#if 0
+      printk("%s(%d): PROGRAM ptr=%x l=%d\n", __FILE__, __LINE__, (int) ptr, l);
+#endif
+
+      /* Program next buffer bytes */
+      for (j = 0; (j < FTIMEOUT); j++) {
+	*((volatile unsigned char *) ptr) = 0xe8;
+	status = *((volatile unsigned char *) ptr);
+	if (status & 0x80)
+	  break;
+      }
+      if ((status & 0x80) == 0)
+	goto intelwritealldone;
+
+      *((volatile unsigned char *) ptr) = (l-1);
+      for (j = 0; (j < l); j++)
+	*((volatile unsigned char *) (ptr+j)) = *lp++;
+
+      *((volatile unsigned char *) ptr) = 0xd0;
+
+      for (j = 0; (j < FTIMEOUT); j++) {
+	status = *((volatile unsigned char *) ptr);
+	if (status & 0x80) {
+	  /* Program complete */
+	  break;
+	}
+      }
+
+intelwritealldone:
+      /* Restore FLASH to normal read mode */
+      *((volatile unsigned char *) ptr) = 0xff;
+
+      for (k = 0; (k < l); k++, lp0++) {
+      	status = *((volatile unsigned char *) (ptr+k));
+        if (status != *lp0) {
+		printk("FLASH: (%d): write failed, addr=%08x wrote=%02x "
+		"read=%02x cnt=%d len=%d\n",
+		__LINE__, (int) (ptr+k), (int) *lp0, (int) status, j, l);
+		failures++;
+	}
+      }
+    }
+  }
+
+#ifdef CONFIG_LEDMAN
+  ledman_cmd(LEDMAN_CMD_RESET, LEDMAN_NVRAM_1);
+  ledman_cmd(LEDMAN_CMD_RESET, LEDMAN_NVRAM_2);
+#endif
+
+  if (failures > 0) {
+    printk("FLASH: %d failures programming FLASH!\n", failures);
+    return;
+  }
+
+#if 0
+  printk("\nFLASH: programming successful!\n");
+#endif
+  if (prog->reset) {
+    printk("FLASH: rebooting...\n\n");
+    HARD_RESET_NOW();
+  }
+}
+
+#endif /* defined(CONFIG_INTELFLASH) */
+/****************************************************************************/
+#endif /* CONFIG_FLASH_SNAPGEAR */
+/****************************************************************************/
+
+
+#ifdef CONFIG_SHGLCORE
+
+static DECLARE_MUTEX(spare_lock);
+
+void read_spare(struct arena_t * a, unsigned long pos, unsigned long length, char * buffer)
+{
+
+#ifdef DEBUG
+  printk("rsl\n");
+#endif
+  
+  /* Mutex all access to FLASH */
+  down(&spare_lock);
+  
+#ifdef DEBUG
+  printk("rsld\n");
+#endif
+  
+  /* Just copy the data into target buffer */
+  memcpy( buffer, (void*)(a->address+pos), length);
+
+  /* Release MUTEX */
+  up(&spare_lock);
+  
+#ifdef DEBUG
+  printk("rsud\n");
+#endif
+}
+
+void write_spare(struct arena_t * a, unsigned long pos, unsigned long length, char * buffer)
+{
+  unsigned long start;
+  unsigned char c;
+  volatile unsigned char * address;
+  unsigned char result;
+  unsigned long fbase = a->address;
+  unsigned long flags;
+  
+#if 0
+  for(i = pos / a->blksize; i <= ((pos+length-1) / a->blksize); i++) {
+    if (test_bit(i, &a->auto_erase_bits)) {
+      /* erase sector start */
+      printk("Autoerase of sector %d\n", i);
+      erase_spare(a, i * a->blksize);
+      clear_bit(i, &a->auto_erase_bits);
+    }
+  }
+#endif
+
+#ifdef DEBUG
+  printk("wsl\n");
+#endif
+  
+  down(&spare_lock);
+  
+#ifdef DEBUG
+  printk("wsld\n");
+#endif
+  
+  start = jiffies;
+  
+  address = (unsigned volatile char*)(fbase+pos);
+  
+  while (length>0) {
+  
+    c = *buffer++;
+    
+    /*printk("Checking spare_flash program of byte %lx, at address %p, value %x (%c), current %x (%c)\n", pos, address, c, c, *address, *address);*/
+
+    if (*address != c) {
+  
+      /*printk("Starting spare_flash program of byte %lx, at address %p\n", pos, address);*/
+      
+      
+      if (c & ~*address) {
+        printk("Unable to write byte at %p (impossible bit transition in %x, actual %x)\n", address, c, *address);
+        /*continue;*/
+      }
+
+	save_flags(flags); cli();
+
+      *(unsigned volatile char *)(fbase | 0x5555)=0x0aa;
+      *(unsigned volatile char *)(fbase | 0x2aaa)=0x055;
+      *(unsigned volatile char *)(fbase | 0x5555)=0x0a0;
+      
+      *address = c;
+               
+      for(;;) {
+        result = *address;
+        /*printk("Read value %x (%c)\n", result, result);*/
+        if ((result & 0x80) == (c & 0x80))
+          break;
+        if (result & 0x20) {
+          printk("timeout of FLASH write at address %p of value %x (actual %x)\n", address, c, *address);
+          *(unsigned volatile char *)(fbase)=0x0f0; /* Reset */
+          break;
+        }
+      }
+      
+      restore_flags(flags);
+
+      /*printk("Completed spare_flash program of byte %lx, at address %p\n", pos, address);*/
+        
+#if 0
+      if (jiffies != start) {
+        /*printk("Spare_flash rescheduling in write\n");*/
+        current->state = TASK_INTERRUPTIBLE;
+        current->timeout = jiffies;
+        schedule();
+        current->timeout = 0;
+        /*schedule();*/
+        start = jiffies;
+      }
+#endif
+    }
+
+    address++;
+    length--;
+  }
+  
+  up(&spare_lock);
+  
+#ifdef DEBUG
+  printk("wsud\n");
+#endif
+}
+
+void erase_spare(struct arena_t * a, unsigned long pos)
+{
+  unsigned long fbase = a->address;
+  int delay;
+  unsigned volatile char * address;
+  unsigned long flags;
+  
+  if (pos >= a->length)
+    return;
+  
+  /* Mutex all access to FLASH memory */
+  
+#ifdef DEBUG
+  printk("esl\n");
+#endif
+  
+  down(&spare_lock);
+
+#ifdef DEBUG
+  printk("esld\n");
+#endif
+
+  address = (unsigned volatile char*)(fbase + pos);
+
+  printk("Starting spare_flash erase of byte %lx, at address %p\n", pos, address);
+  
+  save_flags(flags); cli();
+
+again:
+
+  delay = HZ/4+1;
+  
+  /* Initiate erase of FLASH sector */
+  
+  *(unsigned volatile char *)(fbase | 0x5555)=0x0aa;
+  *(unsigned volatile char *)(fbase | 0x2aaa)=0x055;
+  *(unsigned volatile char *)(fbase | 0x5555)=0x080;
+  *(unsigned volatile char *)(fbase | 0x5555)=0x0aa;
+  *(unsigned volatile char *)(fbase | 0x2aaa)=0x055;
+                       
+  *address = 0x030;
+  
+  /* Delay until erase is complete */
+     
+  for (;;) {
+    unsigned char result;
+#ifdef original_spare_erase_delay
+    struct wait_queue *wait = NULL;
+#ifdef DEBUG
+    printk("Spare_flash erase delaying for %d ticks, status is %x\n", delay, (unsigned int)*address);
+#endif
+    
+    current->timeout = jiffies + delay;
+#if 0    
+    current->state = TASK_INTERRUPTIBLE;
+    schedule();
+    current->timeout = 0;
+#endif
+    interruptible_sleep_on(&wait);
+#endif
+    udelay(100000);
+    
+    result = *address;
+    if (result & 0x80)
+       break;
+    if (result & 0x20) {
+       printk("timeout of Spare_flash erase of address %p\n", address);
+       *(unsigned volatile char *)(fbase)=0x0f0; /* Reset */
+       printk("Sleeping a second and retrying\n");
+
+       udelay(1000000);
+       
+       goto again;
+    }
+  }
+  
+  restore_flags(flags);
+
+#ifdef DEBUG
+  printk("Completed spare_flash erase of byte %lx, at address %p\n", pos, address);
+#endif
+  
+  up(&spare_lock);
+
+#ifdef DEBUG
+  printk("esud\n");
+#endif
+
+}
+
+#define VSP(X) (*(volatile unsigned short *)(X))
+#define VSC(X) (*(volatile unsigned char *)(X))
+
+#define SCSR  VSP(0xfffc0c)
+#define SCSR_TDRE (1<<8)
+
+#define SCDR  VSP(0xfffC0e)
+
+#define print_char(x) ({			\
+	while (!(SCSR & SCSR_TDRE))		\
+		;				\
+	SCDR = (x);				\
+})
+
+#define print_hexdigit(x) ({			\
+	int digit = (x) & 0xf;			\
+	if (digit>9)				\
+		print_char('a'+digit-10);	\
+	else					\
+		print_char('0'+digit);		\
+						\
+})
+
+#define print_num(x) ({				\
+	unsigned long num = (x);		\
+	print_hexdigit(num >> 28);		\
+	print_hexdigit(num >> 24);		\
+	print_hexdigit(num >> 20);		\
+	print_hexdigit(num >> 16);		\
+	print_hexdigit(num >> 12);		\
+	print_hexdigit(num >> 8);		\
+	print_hexdigit(num >> 4);		\
+	print_hexdigit(num >> 0);		\
+})
+
+/* Note: sub_program_main must not reference _any_ data or code outside of itself,
+   or leave interrupts enabled, due to the fact that it is probably erasing
+   & reloading the kernel. */
+
+#define SET_SHORT(x,y) VSP((x)) = (y)
+/*#define SET_SHORT(x,y) ({})*/ /*print_char('>');print_num(x);*/ /*printk("%8.8lx <= %04x\n", (x), (y))*/
+
+#define SET_CHAR(x,y) VSC((x)) = (y)
+/*#define SET_CHAR(x,y) ({})*/ /*print_char('>');print_num(x);*/ /*printk("%8.8lx <= %02x\n", (x), (y))*/
+
+#define GET_SHORT(x) VSP((x))
+/*#define GET_SHORT(x) ({0;})*/ /*({print_char('<');print_num(x);0;})*/ /*(printk("%8.8lx => ....\n", (x)),0)*/
+
+#define GET_CHAR(x) VSC((x))
+/*#define GET_CHAR(x) ({0;})*/ /*({print_char('<');print_num(x);0;})*/ /*(printk("%8.8lx => ..\n", (x)),0)*/
+
+
+void sub_program_main(struct arena_t * a, struct blkmem_program_t * prog)
+{
+  volatile int i,l;
+  unsigned long base, offset, ptr, min, max;
+  unsigned char * c;
+  unsigned int erased = 0;
+  int failures;
+  int retry;
+  
+  cli();
+
+  retry = 0;
+
+again:
+
+  SET_ALARM_LED(1);
+  
+  retry++;
+  
+  if (retry>5) {
+  	goto give_up;
+  }
+
+    print_char('\r');
+    print_char('\n');
+    print_char('R');
+    print_char('0' + retry);
+
+  failures = 0;
+  erased = 0;
+  
+/*  for(i=prog->blocks-1;i>=0;i--) {*/
+  for(i=0;i<prog->blocks;i++) {
+
+    SET_COMM_STATUS_LED(!GET_COMM_STATUS_LED());
+
+    print_char('\r');
+    print_char('\n');
+    print_num(prog->block[i].pos+a->address);
+    print_char('-');
+    print_num(prog->block[i].pos+prog->block[i].length-1+a->address);
+    print_char('\r');
+    print_char('\n');
+
+    if(prog->block[i].length > 0xE0000)
+      break;
+
+    for(l=prog->block[i].pos / a->blksize; l <= ((prog->block[i].pos+prog->block[i].length-1) / a->blksize); l++) {
+      if (!test_bit(l, &erased)) {
+        
+ 	print_char('E');
+ 	print_char('0' + l / 10);
+ 	print_char('0' + l % 10);
+ 	print_char('\r');
+ 	print_char('\n');
+ 	
+ 	if (l <  1)
+ 	  break;
+ 	/*if (l >= 8)
+ 	  break;*/
+
+	ptr = l * a->blksize;
+	offset = ptr % a->unitsize;
+	base = ptr - offset;
+	
+	base += a->address;
+	ptr += a->address;
+	
+	print_char('b');
+	print_char('a');
+	print_char('s');
+	print_char('e');
+	print_char(' ');
+	print_num(base);
+	print_char('\r');
+	print_char('\n');
+	print_char('o');
+	print_char('f');
+	print_char('f');
+	print_char(' ');
+	print_num(offset);
+	print_char('\r');
+	print_char('\n');
+	print_char('p');
+	print_char('t');
+	print_char('r');
+	print_char(' ');
+	print_num(ptr);
+	print_char('\r');
+	print_char('\n');
+
+        set_bit(l, &erased);
+
+        if (ptr <  0x020000)
+          break;
+        /*if (ptr >= 0x100000)
+          break;*/
+        
+        print_num(ptr);
+        
+ 	SET_COMM_ERROR_LED(1);
+ 	
+        /* Erase even half of sector */
+        SET_SHORT( (base | (0x5555 << 1)), 0xaa00);
+        SET_SHORT( (base | (0x2aaa << 1)), 0x5500);
+        SET_SHORT( (base | (0x5555 << 1)), 0x8000);
+        SET_SHORT( (base | (0x5555 << 1)), 0xaa00);
+        SET_SHORT( (base | (0x2aaa << 1)), 0x5500);
+
+        SET_SHORT( ptr, 0x3000);
+#ifdef original_erase_logic
+        while (!(GET_SHORT(ptr) & 0x8000))
+          ;
+#else
+	for (;;) {
+		unsigned int status = GET_SHORT(ptr);
+		if (status & 0x8000) {
+			/* Erase complete */
+			break;
+		}
+		if (status & 0x2000) {
+			/* Check again */
+			status = GET_SHORT(ptr);
+			if (status & 0x8000) {
+				/* Erase complete */
+				break;
+			}
+			
+			/* Erase failed */
+			print_char('F');
+			
+			/* Reset FLASH unit */
+			SET_SHORT( base, 0xf000);
+			
+			failures++;
+			
+			/* Continue (with unerased sector) */
+			break;
+		}
+        }
+#endif
+
+        print_char(':');
+
+        /* Erase odd half of sector */
+        SET_SHORT( (base | (0x5555 << 1)), 0x00aa);
+        SET_SHORT( (base | (0x2aaa << 1)), 0x0055);
+        SET_SHORT( (base | (0x5555 << 1)), 0x0080);
+        SET_SHORT( (base | (0x5555 << 1)), 0x00aa);
+        SET_SHORT( (base | (0x2aaa << 1)), 0x0055);
+
+        SET_SHORT( ptr, 0x0030);
+#ifdef original_erase_logic
+        while (!(GET_SHORT(ptr) & 0x0080))
+          ;
+#else
+	for (;;) {
+		unsigned int status = GET_SHORT(ptr);
+		if (status & 0x0080) {
+			/* Erase complete */
+			break;
+		}
+		if (status & 0x0020) {
+		
+			/* Check again */			
+			status = GET_SHORT(ptr);
+			if (status & 0x0080) {
+				/* Erase complete */
+				break;
+			}
+
+			/* Erase failed */
+			print_char('F');
+			
+			/* Reset FLASH unit */
+			SET_SHORT( base, 0x00f0);
+			
+			failures++;
+			
+			/* Continue (with unerased sector) */
+			break;
+		}
+        }
+#endif
+
+        print_char(':');
+          
+#if 0
+        probe = (volatile unsigned short*)(fbase + a->blksize * l);
+        *probe = 0x3000;
+        while (!(*probe & 0x8000))
+          ;
+          
+        print_char('.');
+        
+        /* Erase odd half of sector */
+        *(unsigned volatile short *)(fbase | (0x5555 << 1))=0x00aa;
+        *(unsigned volatile short *)(fbase | (0x2aaa << 1))=0x0055;
+        *(unsigned volatile short *)(fbase | (0x5555 << 1))=0x0080;
+        *(unsigned volatile short *)(fbase | (0x5555 << 1))=0x00aa;
+        *(unsigned volatile short *)(fbase | (0x2aaa << 1))=0x0055;
+
+        probe = (volatile unsigned short*)(fbase + a->blksize * l);
+        *probe = 0x0030;
+        while (!(*probe & 0x0080))
+          break;
+          
+        print_char('.');
+#endif
+
+ 	SET_COMM_ERROR_LED(0);
+      }
+    }
+    
+    
+    min = prog->block[i].pos+a->address;
+    max = prog->block[i].pos+prog->block[i].length+a->address;
+    for(ptr=min, c=prog->block[i].data; ptr<max; ptr++, c++) {
+      
+      offset = (ptr-a->address) % a->unitsize;
+      base = ptr - offset;
+
+      if (ptr <  0x020000)
+        break;
+      /*if (ptr >= 0x100000)
+        break;*/
+
+      /*print_char('.');*/
+      
+#if 0
+      if ((fbase & 1) == 0) { /* Even bank */
+        *(unsigned volatile short *)(fbase | (0x5555 << 1))=0xaa00;
+        *(unsigned volatile short *)(fbase | (0x2aaa << 1))=0x5500;
+        *(unsigned volatile short *)(fbase | (0x5555 << 1))=0xa000;
+        *(unsigned volatile short *)(fbase + (b & ~1))     =*c << 8;
+      } else { /* Odd bank */
+        *(unsigned volatile short *)(fbase | (0x5555 << 1))=0x00aa;
+        *(unsigned volatile short *)(fbase | (0x2aaa << 1))=0x0055;
+        *(unsigned volatile short *)(fbase | (0x5555 << 1))=0x00a0;
+        *(unsigned volatile short *)(fbase + (b & ~1))     =*c;
+      }
+            
+      probe = (volatile unsigned char*)(fbase + b);
+      while (*probe != *c)
+          break;
+#endif
+
+      if ((ptr & 1) == 0) { /* Even bank */
+        SET_SHORT( (base | (0x5555 << 1)), 0xaa00);
+        SET_SHORT( (base | (0x2aaa << 1)), 0x5500);
+        SET_SHORT( (base | (0x5555 << 1)), 0xa000);
+        SET_SHORT( (ptr & ~1),      *c << 8);
+      } else { /* Odd bank */
+        SET_SHORT( (base | (0x5555 << 1)), 0x00aa);
+        SET_SHORT( (base | (0x2aaa << 1)), 0x0055);
+        SET_SHORT( (base | (0x5555 << 1)), 0x00a0);
+        SET_SHORT( (ptr & ~1),      *c);
+      }
+      
+#ifdef original_write_logic
+      while (GET_CHAR(ptr) != *c)
+        ;
+#else
+	for (;;) {
+		unsigned char status = GET_CHAR(ptr);
+		if ((status & 0x80) == (*c & 0x80)) {
+			/* Program complete */
+			break;
+		}
+		if (status & 0x20) {
+			/* Check again */
+			status = GET_CHAR(ptr);
+			if ((status & 0x80) == (*c & 0x80)) {
+				/* Program complete */
+				break;
+			}
+			
+			/* Program failed */
+			print_char('F');
+			
+			/* Reset FLASH unit */
+			if ((ptr & 1) == 0) { /* Even bank */
+				SET_SHORT( base, 0xf000);
+			} else { /* Odd bank */
+				SET_SHORT( base, 0x00f0);
+			}
+			
+			failures++;
+			
+			/* Continue */
+			break;
+		}
+        }
+#endif
+      
+      /*print_char(' ');*/
+    }
+  }
+  
+  if (failures > 0) {
+  	/* There were failures erasing the FLASH, so go back to the beginning and
+  	try it all again -- for lack of anything better to do. */
+  	
+  	print_char('!');
+  	goto again;
+  }
+
+give_up:
+
+  SET_ALARM_LED(1);
+  
+  
+  HARD_RESET_NOW();
+  
+  i = 1;
+  while(i)
+    ;
+  
+}
+
+void program_main(struct arena_t * a, struct blkmem_program_t * prog)
+{
+  int len;
+  void (*code)(struct arena_t*, struct blkmem_program_t *);
+  
+  printk("program_main entered, blocks = %d\n", prog->blocks);
+  
+  len = &program_main-&sub_program_main;
+  code = kmalloc(len, GFP_KERNEL);
+  memcpy(code, &sub_program_main, len);
+  
+  code(a, prog);
+
+  kfree(code);
+  
+  /*sub_program_main(a, prog);*/
+}
+#endif /* CONFIG_SHGLCORE */
+
+
+int general_program_func(struct inode * inode, struct file * file, struct arena_t * a, struct blkmem_program_t * prog)
+{
+  int i,block;
+  unsigned int erased = 0;
+
+  /* Mandatory flush of all dirty buffers */
+  fsync_dev(inode->i_rdev);
+  invalidate_buffers(inode->i_rdev);
+
+  for(i=0;i<prog->blocks;i++) {
+    int min= prog->block[i].pos / a->blksize;
+    int max = (prog->block[i].pos + prog->block[i].length - 1) / a->blksize;
+    for(block=min; block <= max; block++) {
+      if (!test_bit(block, &erased)) {
+	printk("Erase of sector at pos %lx of arena %d (address %p)\n", block * a->blksize, MINOR(inode->i_rdev), (void*)(a->address+block*a->blksize));
+    
+        /* Invoke erase function */
+        a->erase_func(a, block * a->blksize);
+        set_bit(block, &erased);
+      }
+    }
+    
+    printk("Write of %lu bytes at pos %lu (data at %p)\n", prog->block[i].length, prog->block[i].pos, prog->block[i].data);
+    
+    a->write_func(a, prog->block[i].pos, prog->block[i].length, prog->block[i].data);
+    
+    schedule();
+  }
+
+#ifdef CONFIG_UCLINUX
+  if (prog->reset)
+  	HARD_RESET_NOW();
+#endif
+  return 0;
+}
+
+
+#if 0
+
+static void complete_request(void * data);
+
+static struct tq_struct complete_tq = {
+		routine: complete_request,
+		data: NULL
+};
+
+static void
+delay_request( void )
+{
+  schedule_task(&complete_tq);
+}
+
+
+static void
+complete_request( void * data)
+{
+  unsigned long start;
+  unsigned long len;
+  struct arena_t * a = arena + CURRENT_DEV;
+
+  for(;;) {
+  
+  INIT_REQUEST;
+
+  /* sectors are 512 bytes */
+  start = CURRENT->sector << 9;
+  len  = CURRENT->current_nr_sectors << 9;
+
+  /*printk("blkmem: re-request %d\n", CURRENT->cmd);*/
+    
+  if ( CURRENT->cmd == READ ) {
+    /*printk("BMre-Read: %lx:%lx > %p\n", a->address + start, len, * CURRENT->buffer);*/
+	if (a->read_func)
+    a->read_func(a, start, len, CURRENT->buffer);
+	else {
+	printk("read from unreadable !\n");
+	asm volatile ("halt");
+	}
+  }
+  else if (CURRENT->cmd == WRITE) {
+    /*printk("BMre-Write: %p > %lx:%lx\n", CURRENT->buffer, a->address + start, len);*/
+	if (a->write_func)
+    a->write_func(a, start, len, CURRENT->buffer);
+	else {
+	printk("write to unwritable !\n");
+	asm volatile ("halt");
+	}
+  }
+  /*printk("ending blkmem request\n");*/
+  end_request( TRUE );
+  
+  }
+}
+
+#endif
+
+
+static void
+do_blkmem_request(request_queue_t *q)
+{
+  unsigned long start;
+  unsigned long len;
+  struct arena_t * a = arena + CURRENT_DEV;
+
+#if 0
+  printk( KERN_ERR DEVICE_NAME ": request\n");
+#endif
+
+  while ( TRUE ) {
+    INIT_REQUEST;
+    
+    /* sectors are 512 bytes */
+    start = CURRENT->sector << 9;
+    len  = CURRENT->current_nr_sectors << 9;
+
+    if ((start + len) > a->length) {
+      printk( KERN_ERR DEVICE_NAME ": bad access: block=%ld, count=%ld (pos=%lx, len=%lx)\n",
+	      CURRENT->sector,
+	      CURRENT->current_nr_sectors,
+	      start+len,
+	      a->length);
+      end_request( FALSE );
+      continue;
+    }
+
+    /*printk("blkmem: request %d\n", current->cmd);*/
+    
+    if ( ( CURRENT->cmd != READ ) 
+	 && ( CURRENT->cmd != WRITE ) 
+	 ) {
+      printk( KERN_ERR DEVICE_NAME ": bad command: %d\n", CURRENT->cmd );
+      end_request( FALSE );
+      continue;
+    }
+    
+    if ( CURRENT->cmd == READ ) {
+      if (a->read_func) {
+#if 0
+        delay_request();
+        return;
+#else
+        a->read_func(a, start, len, CURRENT->buffer);
+#endif
+      } else
+        memcpy( CURRENT->buffer, (void*)(a->address + start), len );
+
+    } else if (CURRENT->cmd == WRITE) {
+
+      if (a->write_func) {
+#if 0
+        delay_request();
+        return;
+#else
+        a->write_func(a, start, len, CURRENT->buffer);
+#endif
+      } else
+        memcpy( (void*)(a->address + start), CURRENT->buffer, len );
+    }
+
+    /* printk("ending blkmem request\n"); */
+    end_request( TRUE );
+  }
+}
+
+#ifdef MAGIC_ROM_PTR
+static int
+blkmem_romptr( kdev_t dev, struct vm_area_struct * vma)
+{
+  struct arena_t * a = arena + MINOR(dev);
+
+  if (a->read_func)
+    return -ENOSYS; /* Can't do it, as this arena isn't in the main address space */
+
+  vma->vm_start = a->address + vma->vm_offset;
+  return 0;
+}
+#endif
+
+static int blkmem_ioctl (struct inode *inode, struct file *file,
+                         unsigned int cmd, unsigned long arg)
+{
+  struct arena_t * a = arena + MINOR(inode->i_rdev);
+
+  switch (cmd) {
+
+  case BMGETSIZES:   /* Return device size in sectors */
+    if (!arg)
+      return -EINVAL;
+    return(put_user(a->blksize ? (a->length / a->blksize) : 0, (unsigned long *) arg));
+    break;
+
+  case BMGETSIZEB:   /* Return device size in bytes */
+    return(put_user(a->length, (unsigned long *) arg));
+    break;
+
+  case BMSERASE:
+    if (a->erase_func) {
+
+      if (arg >= a->length)
+        return -EINVAL;
+    
+      /* Mandatory flush of all dirty buffers */
+      fsync_dev(inode->i_rdev);
+      
+      /* Invoke erase function */
+      a->erase_func(a, arg);
+    } else
+      return -EINVAL;
+    break;
+    
+  case BMSGSIZE:
+    return(put_user(a->blksize, (unsigned long*)arg));
+    break;
+
+  case BMSGERASEVALUE:
+    return(put_user(a->erasevalue, (unsigned char *) arg));
+    break;
+
+  case BMPROGRAM:
+  {
+    struct blkmem_program_t *prog = NULL, dummy;
+    int i, rc = 0, size;
+
+    if (copy_from_user(&dummy, (void *) arg, sizeof(dummy)))
+      return(-EFAULT);
+
+    if ((dummy.magic1 != BMPROGRAM_MAGIC_1) ||
+        (dummy.magic2 != BMPROGRAM_MAGIC_2))
+      return(-EINVAL);
+
+	size = sizeof(dummy) + sizeof(dummy.block[0]) * dummy.blocks;
+
+    prog = (struct blkmem_program_t *) kmalloc(size, GFP_KERNEL);
+    if (prog == NULL)
+      return(-ENOMEM);
+
+    if (copy_from_user(prog, (void *) arg, size)) {
+      rc = -EFAULT;
+      goto early_exit;
+	}
+
+    for(i=0;i<prog->blocks;i++) {
+      if(prog->block[i].magic3 != BMPROGRAM_MAGIC_3) {
+        rc = -EINVAL;
+        goto early_exit;
+      }
+    }
+
+    for(i=0;i<prog->blocks;i++)
+      if ((prog->block[i].pos > a->length) ||
+          ((prog->block[i].pos+prog->block[i].length-1) > a->length)) {
+        rc = -EINVAL;
+        goto early_exit;
+      }
+
+    if (a->program_func)
+      a->program_func(a, prog);
+    else
+      rc = general_program_func(inode, file, a, prog);
+
+  early_exit:
+    if (prog)
+      kfree(prog);
+    return(rc);
+  }
+
+  default:
+    return -EINVAL;
+  }
+  return 0;
+}
+
+static int
+blkmem_open( struct inode *inode, struct file *filp )
+{
+  int device;
+  struct arena_t * a;
+
+  device = DEVICE_NR( inode->i_rdev );
+
+#if 0
+  printk( KERN_ERR DEVICE_NAME ": open: %d\n", device );
+#endif
+
+  if ((MINOR(device) < 0) || (MINOR(device) >= arenas))  {
+    printk("arena open of %d failed!\n", MINOR(device));
+    return -ENODEV;
+  }
+  
+  a = &arena[MINOR(device)];
+
+#if defined(MODULE)
+  MOD_INC_USE_COUNT;
+#endif
+  return 0;
+}
+
+static int 
+blkmem_release( struct inode *inode, struct file *filp )
+{
+#if 0
+  printk( KERN_ERR DEVICE_NAME ": release: %d\n", current_device );
+#endif
+
+  fsync_dev( inode->i_rdev );
+
+#if defined(MODULE)
+  MOD_DEC_USE_COUNT;
+#endif
+
+  return(0);
+}
+
+static struct block_device_operations blkmem_fops=
+{
+	open:		blkmem_open,
+	release:	blkmem_release,
+	ioctl:		blkmem_ioctl,
+#ifdef MAGIC_ROM_PTR
+	romptr:		blkmem_romptr,
+#endif
+};
+
+
+int __init blkmem_init( void )
+{
+  int i;
+  unsigned long realaddrs[arenas];
+
+#ifdef FIXUP_ARENAS
+  {
+  FIXUP_ARENAS
+  }
+#endif
+
+  for(i=0;i<arenas;i++) {
+    if (arena[i].length == -1)
+      arena[i].length = ntohl(*(volatile unsigned long *)(arena[i].address+8));
+    blkmem_blocksizes[i] = 1024;
+    blkmem_sizes[i] = (arena[i].length + (1 << 10) - 1) >> 10; /* Round up */
+    arena[i].length = blkmem_sizes[i] << 10;
+
+    realaddrs[i] = arena[i].address;
+    arena[i].address = (unsigned long) ioremap_nocache((int) arena[i].address, arena[i].length);
+  }
+
+
+  printk("Blkmem copyright 1998,1999 D. Jeff Dionne\nBlkmem copyright 1998 Kenneth Albanowski\nBlkmem %d disk images:\n", (int) arenas);
+
+  for(i=0;i<arenas;i++) {
+    printk("%d: %lX-%lX [VIRTUAL %lX-%lX] (%s)\n", i,
+	realaddrs[i], realaddrs[i]+arena[i].length-1,
+	arena[i].address, arena[i].address+arena[i].length-1,
+    	arena[i].rw 
+    		? "RW"
+    		: "RO"
+    );
+  }
+
+  if (register_blkdev(MAJOR_NR, DEVICE_NAME, &blkmem_fops )) {
+    printk( KERN_ERR DEVICE_NAME ": Unable to get major %d\n",
+            MAJOR_NR );
+    return -EBUSY;
+  }
+
+  devfs_handle = devfs_mk_dir(NULL, "blkmem", NULL);
+  devfs_register_series(devfs_handle, "%u", arenas,
+      DEVFS_FL_DEFAULT, MAJOR_NR, 0, S_IFBLK | S_IRUSR | S_IWUSR,
+      &blkmem_fops, NULL);
+
+  blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &do_blkmem_request);
+
+  read_ahead[ MAJOR_NR ] = 0;
+  blksize_size[ MAJOR_NR ] = blkmem_blocksizes;
+  blk_size[ MAJOR_NR ] = blkmem_sizes;
+  
+#ifdef ROOT_ARENA
+  ROOT_DEV = MKDEV(MAJOR_NR,ROOT_ARENA);
+#endif
+#if !defined(MODULE)
+#if !defined(CONFIG_COLDFIRE) && !defined(CONFIG_M68328) && !defined(CONFIG_EXCALIBUR) && !defined(CONFIG_ARCH_TA7S) && !defined(CONFIG_ARCH_TA7V)
+  /*if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {*/
+  /*
+   * This used to set the minor # to 1, which didn't work...
+   * --gmcnutt
+   */
+    ROOT_DEV = MKDEV(MAJOR_NR,0);
+  /*}*/
+#endif
+#endif
+  return 0;
+}
+
+static void __exit
+blkmem_exit(void )
+{
+  int i;
+
+  for(i=0;i<arenas;i++)
+      iounmap((void *) arena[i].address);
+
+  if ( unregister_blkdev( MAJOR_NR, DEVICE_NAME ) != 0 )
+    printk( KERN_ERR DEVICE_NAME ": unregister of device failed\n");
+}
+
+EXPORT_NO_SYMBOLS;
+
+module_init(blkmem_init);
+module_exit(blkmem_exit);
+
diff -urN linux-2.4.29/drivers/block/Config.in linux-2.4.29-uc1/drivers/block/Config.in
--- linux-2.4.29/drivers/block/Config.in	2004-08-08 00:26:04.000000000 +0100
+++ linux-2.4.29-uc1/drivers/block/Config.in	2005-06-14 02:11:55.000000000 +0100
@@ -28,6 +28,12 @@
       tristate '  Atari SLM laser printer support' CONFIG_ATARI_SLM
    fi
 fi
+if [ "$CONFIG_COBRA5282" = "y" ]; then
+   tristate 'Multi Media Card support for COBRA5282' CONFIG_BLK_DEV_MMC
+fi
+if [ "$CONFIG_COBRA5272" = "y" ]; then
+   tristate 'Multi Media Card support for COBRA5272' CONFIG_BLK_DEV_MMC
+fi
 dep_tristate 'XT hard disk support' CONFIG_BLK_DEV_XD $CONFIG_ISA
 dep_tristate 'Parallel port IDE device support' CONFIG_PARIDE $CONFIG_PARPORT
 if [ "$CONFIG_PARIDE" = "y" -o "$CONFIG_PARIDE" = "m" ]; then
@@ -49,6 +55,32 @@
    int '  Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096
 fi
 dep_bool '  Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK_DEV_RAM
+dep_bool '  RAM disk data block compiled in' CONFIG_BLK_DEV_RAMDISK_DATA $CONFIG_BLK_DEV_INITRD
+
+tristate 'ROM disk memory block device (blkmem)' CONFIG_BLK_DEV_BLKMEM $CONFIG_BLK_DEV_BLKMEM
+if [ "$CONFIG_BLK_DEV_BLKMEM" = "y" -o "$CONFIG_BLK_DEV_BLKMEM" = "m" ]; then
+    choice '  FLASH type' \
+        "NONE   CONFIG_NOFLASH \
+         AMD    CONFIG_AMDFLASH \
+         INTEL  CONFIG_INTELFLASH" NONE
+    if [ "$CONFIG_AMDFLASH" = "y" -o "$CONFIG_INTELFLASH" = "y" ]; then
+        choice '  FLASH size' \
+                " AUTO  CONFIG_FLASHAUTO \
+                 128KB  CONFIG_FLASH128KB \
+                   1MB  CONFIG_FLASH1MB \
+                   2MB  CONFIG_FLASH2MB \
+                   4MB  CONFIG_FLASH4MB \
+                   6MB  CONFIG_FLASH6MB \
+                   8MB  CONFIG_FLASH8MB \
+                  16MB  CONFIG_FLASH16MB" AUTO
+        choice '  FLASH bit width' \
+                " AUTO  CONFIG_FLASHAUTOBIT \
+                  8bit  CONFIG_FLASH8BIT \
+                 16bit  CONFIG_FLASH16BIT \
+                 32bit  CONFIG_FLASH32bit" AUTO
+        bool '  2nd flash in /dev/rom8' CONFIG_EXTRA_FLASH
+    fi
+fi
 
 bool 'Per partition statistics in /proc/partitions' CONFIG_BLK_STATS
 
diff -urN linux-2.4.29/drivers/block/floppy.c linux-2.4.29-uc1/drivers/block/floppy.c
--- linux-2.4.29/drivers/block/floppy.c	2005-01-19 14:09:42.000000000 +0000
+++ linux-2.4.29-uc1/drivers/block/floppy.c	2005-06-14 02:11:55.000000000 +0100
@@ -4134,7 +4134,9 @@
 	{ "no_unexpected_interrupts", 0, &print_unex, 0, 0 },
 	{ "L40SX", 0, &print_unex, 0, 0 }
 
+#ifdef EXTRA_FLOPPY_PARAMS
 	EXTRA_FLOPPY_PARAMS
+#endif
 };
 
 static int __init floppy_setup(char *str)
diff -urN linux-2.4.29/drivers/block/Makefile linux-2.4.29-uc1/drivers/block/Makefile
--- linux-2.4.29/drivers/block/Makefile	2004-08-08 00:26:04.000000000 +0100
+++ linux-2.4.29-uc1/drivers/block/Makefile	2005-06-14 02:11:55.000000000 +0100
@@ -22,6 +22,7 @@
 obj-$(CONFIG_ATARI_ACSI)	+= acsi.o
 obj-$(CONFIG_ATARI_SLM)		+= acsi_slm.o
 obj-$(CONFIG_AMIGA_Z2RAM)	+= z2ram.o
+obj-$(CONFIG_BLK_DEV_BLKMEM)+= blkmem.o
 obj-$(CONFIG_BLK_DEV_RAM)	+= rd.o
 obj-$(CONFIG_BLK_DEV_LOOP)	+= loop.o
 obj-$(CONFIG_BLK_DEV_PS2)	+= ps2esdi.o
@@ -31,8 +32,19 @@
 obj-$(CONFIG_BLK_DEV_DAC960)	+= DAC960.o
 obj-$(CONFIG_BLK_DEV_UMEM)	+= umem.o
 obj-$(CONFIG_BLK_DEV_NBD)	+= nbd.o
+obj-$(CONFIG_BLK_DEV_MMC)	+= mmc_COBRA52xx.o
 obj-$(CONFIG_BLK_DEV_SX8)	+= sx8.o
 
 subdir-$(CONFIG_PARIDE) += paride
 
+mod-subdirs			+= xilinx_sysace
+subdir-$(CONFIG_XILINX_SYSACE)	+= xilinx_sysace
+obj-$(CONFIG_XILINX_SYSACE)	+= xilinx_sysace/xilinx_sysace.o
+
+ifeq ($(CONFIG_ARCH_ACORN),y)
+mod-subdirs	+= ../acorn/block
+subdir-y	+= ../acorn/block
+obj-y		+= ../acorn/block/acorn-block.o
+endif
+
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/block/mmc_COBRA52xx.c linux-2.4.29-uc1/drivers/block/mmc_COBRA52xx.c
--- linux-2.4.29/drivers/block/mmc_COBRA52xx.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/block/mmc_COBRA52xx.c	2005-06-14 02:11:55.000000000 +0100
@@ -0,0 +1,617 @@
+/*
+ * linux-2.4.x/drivers/block/mmc_COBRA52xx.c 
+ *
+ * MMC/SD-Card driver
+ *
+ * Copyright (C) 2004 senTec Elektronik (wolfgang.elsner@sentec-elektronik.de)
+ * 
+ * It is a adapted version of the mmc.c at http://www.blumba.de that is
+ * Copyright (C) 2003 Thomas Fehrenbacher <thomas@blumba.de>
+ */
+
+#include <asm/uaccess.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+#include <linux/delay.h>
+#include <linux/timer.h>
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/blkpg.h>
+#include <linux/hdreg.h>
+#include <linux/major.h>
+
+#define DEVICE_NAME "mmc"
+#define DEVICE_NR(device) (MINOR(device))
+#define DEVICE_ON(device)
+#define DEVICE_OFF(device)
+#define MAJOR_NR 121
+
+#include <linux/blk.h>
+
+#if defined(CONFIG_COBRA5282)
+#include <linux/mmc-COBRA5282.h>
+#elif defined(CONFIG_COBRA5272)
+#include <linux/mmc-COBRA5272.h>
+#endif
+
+
+MODULE_AUTHOR("Wolfgang Elsner <wolfgang.elsner@sentec-elektronik.de>");
+MODULE_DESCRIPTION("Driver for MMC/SD-Cards");
+#if defined(CONFIG_COBRA5282)
+   MODULE_SUPPORTED_DEVICE("Motorola MCF5282");
+#elif defined(CONFIG_COBRA5272)
+   MODULE_SUPPORTED_DEVICE("Motorola MCF5272");
+#endif
+MODULE_LICENSE("GPL");
+
+
+/* we have only one device */
+static int mmc_blk_sizes[1] = {0};
+static int mmc_blksize_sizes[1] = {0};
+static int mmc_hardsect_sizes[1] = {0};
+static int mmc_sectors = 0;
+
+static struct timer_list mmc_timer;
+static int mmc_media_detect = 0;
+static int mmc_media_changed = 1;
+
+
+unsigned char mmc_spi_io(unsigned char data_out)
+{
+	unsigned char data_in;
+
+   QAR = COMMAND_RAM_START;
+   QDR = QCR_CONT | QCR_CS; //QSPI_CS
+
+	QAR = TX_RAM_START;
+	QDR = data_out;
+	QIR = 0x0001;
+	QDLYR = QDLYR_SPE;
+	while (!((QIR) & QIR_SPIF) ) ;
+	QAR = RX_RAM_START;
+	data_in = QDR;
+
+	return(data_in);
+}
+
+int mmc_write_block(unsigned int dest_addr, unsigned int src_addr)
+{
+	char *data;
+	unsigned int address;
+	unsigned char r = 0;
+	unsigned char ab0, ab1, ab2, ab3;
+	int i;
+
+	data = (char *)src_addr;
+	address = dest_addr;
+
+	ab3 = 0xff & (address >> 24);
+	ab2 = 0xff & (address >> 16);
+	ab1 = 0xff & (address >> 8);
+	ab0 = 0xff & address;
+	
+   for (i = 0; i < 4; i++) mmc_spi_io(0xff);
+	mmc_spi_io(0x58);
+	mmc_spi_io(ab3); /* msb */
+	mmc_spi_io(ab2);
+	mmc_spi_io(ab1);
+	mmc_spi_io(ab0); /* lsb */
+	mmc_spi_io(0xff);
+	for (i = 0; i < 8; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0x00) break;
+	}
+	if (r != 0x00)
+	{
+		mmc_spi_io(0xff);
+		return(1);
+	}
+	mmc_spi_io(0xff);
+	mmc_spi_io(0xfe);
+	for (i = 0; i < 512; i++) mmc_spi_io(data[i]);
+	for (i = 0; i < 2; i++) mmc_spi_io(0xff);
+	r = mmc_spi_io(0xff);
+	if ((r & 0x05) != 0x05)
+	{
+		mmc_spi_io(0xff);
+		return(2);
+	}
+	for (i = 0; i < 1000000; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r != 0x00) break;
+	}
+	if (r == 0x00)
+	{
+		mmc_spi_io(0xff);
+		return(3);
+	}
+	mmc_spi_io(0xff);
+	return(0);
+}
+
+int mmc_read_block(unsigned int dest_addr, unsigned int src_addr)
+{
+	char *data;
+	unsigned int address;
+	unsigned char r = 0;
+	unsigned char ab0, ab1, ab2, ab3;
+	int i;
+
+	data = (char *)dest_addr;
+	address = src_addr;
+
+	ab3 = 0xff & (address >> 24);
+	ab2 = 0xff & (address >> 16);
+	ab1 = 0xff & (address >> 8);
+	ab0 = 0xff & address;
+
+	for (i = 0; i < 4; i++) mmc_spi_io(0xff);
+	mmc_spi_io(0x51);
+	mmc_spi_io(ab3); /* msb */
+	mmc_spi_io(ab2);
+	mmc_spi_io(ab1);
+	mmc_spi_io(ab0); /* lsb */
+
+	mmc_spi_io(0xff);
+	for (i = 0; i < 8; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0x00) break;
+	}
+	if (r != 0x00)
+	{
+		mmc_spi_io(0xff);
+		return(1);
+	}
+	for (i = 0; i < 100000; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0xfe) break;
+	}
+	if (r != 0xfe)
+	{
+		mmc_spi_io(0xff);
+		return(2);
+	}
+	for (i = 0; i < 512; i++)
+	{
+		r = mmc_spi_io(0xff);
+		data[i] = r;
+	}
+	for (i = 0; i < 2; i++)
+	{
+		r = mmc_spi_io(0xff);
+	}
+	mmc_spi_io(0xff);
+
+	return(0);
+}
+
+void mmc_request(request_queue_t *q)
+{
+	unsigned int mmc_address;
+	unsigned int buffer_address;
+	int nr_sectors;
+	int i;
+	int cmd;
+	int rc;
+
+	//printk("mmc_request\n"); 
+	while(1)
+	{
+		INIT_REQUEST;
+		mmc_address = CURRENT->sector * mmc_hardsect_sizes[0];
+		buffer_address = (unsigned int)CURRENT->buffer;
+		nr_sectors = CURRENT->current_nr_sectors;
+		cmd = CURRENT->cmd;
+		if (((CURRENT->sector + CURRENT->current_nr_sectors) >= mmc_sectors) || (mmc_media_detect == 0))
+		{
+			end_request(0);
+			continue;
+		}
+		else if (cmd == READ)
+		{
+			for (i = 0; i < nr_sectors; i++)
+			{
+				rc = mmc_read_block(buffer_address, mmc_address);
+				if (rc != 0)
+				{
+					printk("mmc: error in mmc_read_block (%d)\n", rc);
+					end_request(0);
+					continue;
+				}
+				else
+				{
+					mmc_address += mmc_hardsect_sizes[0];
+					buffer_address += mmc_hardsect_sizes[0];
+				}
+			}
+			end_request(1);
+
+		}
+		else if (cmd == WRITE)
+		{
+			for (i = 0; i < nr_sectors; i++)
+			{
+				rc = mmc_write_block(mmc_address, buffer_address);
+				if (rc != 0)
+				{
+					printk("mmc: error in mmc_read_block (%d)\n", rc);
+					end_request(0);
+					continue;
+				}
+				else
+				{
+					mmc_address += mmc_hardsect_sizes[0];
+					buffer_address += mmc_hardsect_sizes[0];
+				}
+			}
+			end_request(1);
+		}
+		else
+		{
+			end_request(0);
+			continue;
+		}
+	}
+}
+
+
+int mmc_open(struct inode *inode, struct file *filp)
+{
+	int device;
+	
+	//printk("mmc_open\n"); 
+
+	if (mmc_media_detect == 0) return -ENODEV;
+	device = DEVICE_NR(inode->i_rdev);
+	if (MINOR(device) != 0)
+	{
+		printk("mmc_open of %d failed\n", MINOR(device));
+		return -ENODEV;
+	}
+#if defined(MODULE)
+	MOD_INC_USE_COUNT;
+#endif
+	return 0;
+}
+
+int mmc_release(struct inode *inode, struct file *filp)
+{
+	//printk("mmc_release\n"); 
+
+	fsync_dev(inode->i_rdev);
+        invalidate_buffers(inode->i_rdev);
+
+#if defined(MODULE)
+	MOD_DEC_USE_COUNT;
+#endif
+	return 0;
+}
+
+int mmc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	struct hd_geometry geometry;
+	
+	//printk("mmc_ioctl\n"); 
+
+	if (cmd == BLKGETSIZE)
+	{
+		//printk("   BLKGETSIZE\n");
+		if (!arg) return -EINVAL;
+		if (copy_to_user((long *) arg, (long *) &mmc_sectors, sizeof(long))) return -EFAULT;
+		return 0;
+	}
+	else if (cmd == HDIO_GETGEO)
+	{
+		//printk("   HDIO_GETGEO\n");
+		if (!arg) return -EINVAL;
+		geometry.sectors = mmc_sectors;
+		geometry.heads = 0;
+		geometry.cylinders = 0;
+		geometry.start = 0;
+		if (copy_to_user((void *) arg, &geometry, sizeof(geometry))) return -EFAULT;
+		return 0;
+	}
+	else return blk_ioctl(inode->i_rdev, cmd, arg);
+}
+
+int mmc_card_init(void)
+{
+	unsigned char r = 0;
+	short i, j;
+	unsigned long flags;
+
+	//printk("mmc_card_init\n"); 
+
+	save_flags(flags);
+	cli();
+
+	for (i = 0; i < 10; i++) mmc_spi_io(0xff);
+
+	for (i = 0; i < 4; i++) mmc_spi_io(0xff);
+	mmc_spi_io(0x40);
+	for (i = 0; i < 4; i++) mmc_spi_io(0x00);
+	mmc_spi_io(0x95);
+	for (i = 0; i < 8; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0x01) break;
+	}
+	mmc_spi_io(0xff);
+	if (r != 0x01)
+	{
+		restore_flags(flags);
+		return(1);
+	}
+
+	for (j = 0; j < 10000; j++)
+	{
+		for (i = 0; i < 4; i++) mmc_spi_io(0xff);
+		mmc_spi_io(0x41);
+		for (i = 0; i < 4; i++) mmc_spi_io(0x00);
+		mmc_spi_io(0xff);
+		for (i = 0; i < 8; i++)
+		{
+			r = mmc_spi_io(0xff);
+			if (r == 0x00) break;
+		}
+		mmc_spi_io(0xff);
+		if (r == 0x00)
+		{
+			restore_flags(flags);
+			return(0);
+		}
+	}
+	restore_flags(flags);
+
+	return(2);
+}
+
+int mmc_card_config(void)
+{
+	unsigned char r = 0;
+	short i;
+	unsigned char csd[32];
+	unsigned int c_size;
+	unsigned int c_size_mult;
+	unsigned int mult;
+	unsigned int read_bl_len;
+	unsigned int blocknr = 0;
+	unsigned int block_len = 0;
+	unsigned int size = 0;
+
+	//printk("mmc_card_config\n"); 
+
+	for (i = 0; i < 4; i++) mmc_spi_io(0xff);
+	mmc_spi_io(0x49);
+	for (i = 0; i < 4; i++) mmc_spi_io(0x00);
+	mmc_spi_io(0xff);
+	for (i = 0; i < 8; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0x00) break;
+	}
+	if (r != 0x00)
+	{
+		mmc_spi_io(0xff);
+		return(1);
+	}
+	for (i = 0; i < 8; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0xfe) break;
+	}
+	if (r != 0xfe)
+	{
+		mmc_spi_io(0xff);
+		return(2);
+	}
+	for (i = 0; i < 16; i++)
+	{
+		r = mmc_spi_io(0xff);
+		csd[i] = r;
+	}
+	for (i = 0; i < 2; i++)
+	{
+		r = mmc_spi_io(0xff);
+	}
+	mmc_spi_io(0xff);
+	if (r == 0x00) return(3);
+
+	c_size = csd[8] + csd[7] * 256 + (csd[6] & 0x03) * 256 * 256;
+	c_size >>= 6;
+	c_size_mult = csd[10] + (csd[9] & 0x03) * 256;
+	c_size_mult >>= 7;
+	read_bl_len = csd[5] & 0x0f;
+	mult = 1;
+	mult <<= c_size_mult + 2;
+	blocknr = (c_size + 1) * mult;
+	block_len = 1;
+	block_len <<= read_bl_len;
+	size = block_len * blocknr;
+	size >>= 10;
+
+	mmc_blk_sizes[0] = size;
+	mmc_blksize_sizes[0] = 1024;
+	mmc_hardsect_sizes[0] = block_len;
+	mmc_sectors = blocknr;
+
+	return 0;
+}
+
+int mmc_hardware_init(void)
+{
+	//printk("mmc_hardware_init\n"); 
+ 
+#if defined(CONFIG_COBRA5282)
+   *(unsigned char  *)(MCF_IPSBAR + 0x100059) |= 0x7f; //QSPI
+   *(unsigned char  *)(MCF_IPSBAR + MCF5282_GPTSCR1) = 0x00; 
+   *(unsigned char  *)(MCF_IPSBAR + MCF5282_GPTDDR) = 0x00;
+#elif defined(CONFIG_COBRA5272)
+   // QSPI_CS[3..1] Output
+   *(unsigned int  *)(MCF_MBAR + MCFSIM_PACNT) |= 0x00804000;
+   *(unsigned int  *)(MCF_MBAR + MCFSIM_PDCNT) |= 0x00000030;
+   // PA10 Output
+   *(unsigned long  *)(MCF_MBAR + MCFSIM_PACNT) &= 0xffcfffff;
+   *(unsigned short *)(MCF_MBAR + MCFSIM_PADDR) &= 0xfbff;
+#endif
+
+   
+	QMR = 0xa302; /* 8 bits, baud, 16MHz clk */
+	QWR   = 0x1000;
+	QIR = 0x0001;
+	QDLYR = QDLYR_SPE;
+	QAR = COMMAND_RAM_START;
+	QDR = 0x0000;
+
+	return 0;
+}
+
+int mmc_init(void)
+{
+	int rc;
+
+   //printk("mmc_init\n");
+	rc = mmc_hardware_init(); 
+
+	if ( rc != 0)
+	{
+		printk("mmc: error in mmc_hardware_init (%d)\n", rc);
+		return -1;
+	}
+
+	rc = mmc_card_init(); 
+	if ( rc != 0)
+	{
+		printk("mmc: error in mmc_card_init (%d)\n", rc);
+		return -1;
+	}
+
+	rc = mmc_card_config(); 
+	if ( rc != 0)
+	{
+		printk("mmc: error in mmc_card_config (%d)\n", rc);
+		return -1;
+	}
+
+	blk_size[MAJOR_NR] = mmc_blk_sizes;
+	blksize_size[MAJOR_NR] = mmc_blksize_sizes;
+	hardsect_size[MAJOR_NR] = mmc_hardsect_sizes;
+
+	return 0;
+}
+
+void mmc_exit(void)
+{
+   //printk("mmc_exit\n"); 
+
+	blk_size[MAJOR_NR] = NULL;
+	blksize_size[MAJOR_NR] = NULL;
+	hardsect_size[MAJOR_NR] = NULL;
+	mmc_sectors = 0;
+}
+
+int mmc_check_media_change(kdev_t dev)
+{
+	//printk("mmc_check_media_change\n"); 
+	if (mmc_media_changed == 1)
+	{
+		mmc_media_changed = 0;
+		return 1;
+	}
+	else return 0;
+}
+
+int mmc_revalidate(kdev_t dev)
+{
+	//printk("mmc_revalidate\n"); 
+	if (mmc_media_detect == 0) return -ENODEV;
+	return 0;
+}
+
+static struct block_device_operations mmc_bdops = 
+{
+	open: mmc_open,
+	release: mmc_release,
+	ioctl: mmc_ioctl,
+	check_media_change: mmc_check_media_change,
+	revalidate: mmc_revalidate,
+};
+
+static void mmc_check_media(void)
+{
+	int old_state;
+	int rc;
+   volatile unsigned short carddedect;
+  
+   //printk("mmc_check_media\n");
+   
+	old_state = mmc_media_detect; 
+
+#if defined(CONFIG_COBRA5282) 
+   carddedect = *(volatile unsigned char *)(MCF_IPSBAR + MCF5282_GPTPORT) & 0x04;
+#elif defined(CONFIG_COBRA5272)
+   carddedect = *(unsigned short  *)(MCF_MBAR + MCFSIM_PADAT) & 0x0400;
+#endif
+ 
+   mmc_media_detect = (carddedect == 0) ? 1 : 0;
+  
+   //printk("carddedect: %x\n", carddedect);
+   
+	if (old_state != mmc_media_detect) 
+	{
+		mmc_media_changed = 1;
+		if (mmc_media_detect == 1)
+		{
+			rc = mmc_init();
+			if (rc != 0) printk("mmc: error in mmc_init (%d)\n", rc);
+		}
+		else 
+		{
+			mmc_exit();
+		}
+	}
+	del_timer(&mmc_timer);
+	mmc_timer.expires = jiffies + HZ;
+	add_timer(&mmc_timer);
+}
+int __init mmc_driver_init(void)
+{
+	int rc;
+
+	printk("mmc_driver_init\n");
+
+	rc = register_blkdev(MAJOR_NR, "mmc", &mmc_bdops);
+	if (rc < 0)
+	{
+		printk(KERN_WARNING "mmc: can't get major %d\n", MAJOR_NR);
+		return rc;
+	}
+	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mmc_request);
+
+	init_timer(&mmc_timer);
+	mmc_timer.expires = jiffies + HZ;
+	mmc_timer.function = (void *)mmc_check_media;
+	add_timer(&mmc_timer);
+
+	return 0;
+}
+
+void __exit mmc_driver_exit(void)
+{
+	//printk("mmc_driver_exit\n"); 
+	del_timer(&mmc_timer);
+	fsync_dev(MKDEV(MAJOR_NR, 0));
+	unregister_blkdev(MAJOR_NR, "mmc");
+	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+	mmc_exit();
+}
+
+module_init(mmc_driver_init);
+module_exit(mmc_driver_exit);
diff -urN linux-2.4.29/drivers/block/rd.c linux-2.4.29-uc1/drivers/block/rd.c
--- linux-2.4.29/drivers/block/rd.c	2004-08-08 00:26:04.000000000 +0100
+++ linux-2.4.29-uc1/drivers/block/rd.c	2005-06-14 02:11:55.000000000 +0100
@@ -40,6 +40,10 @@
  *
  * Make block size and block size shift for RAM disks a global macro
  * and set blk_size for -ENOSPC,     Werner Fink <werner@suse.de>, Apr '99
+ *
+ * Some #ifdef fine tuning to make the decompression of a built-in data
+ * block work on the Net+ARM (option CONFIG_BLK_DEV_RAMDISK_DATA), 
+ *                           Rolf Peukert <rolf.peukert@imms.de>, May 2001
  */
 
 #include <linux/config.h>
@@ -50,6 +54,7 @@
 #include <linux/devfs_fs_kernel.h>
 #include <linux/smp_lock.h>
 #include <asm/uaccess.h>
+#include <asm/byteorder.h>
 
 /*
  * 35 has been officially registered as the RAMDISK major number, but
@@ -341,6 +346,8 @@
 {
 	extern void free_initrd_mem(unsigned long, unsigned long);
 
+#ifndef CONFIG_BLK_DEV_RAMDISK_DATA
+	/* don't free ramdisk if data is compiled in */
 	lock_kernel();
 	if (!--initrd_users) {
 		free_initrd_mem(initrd_start, initrd_end);
@@ -348,6 +355,7 @@
 	}
 	unlock_kernel();
 	blkdev_put(inode->i_bdev, BDEV_FILE);
+#endif
 	return 0;
 }
 
diff -urN linux-2.4.29/drivers/block/xilinx_sysace/adapter.c linux-2.4.29-uc1/drivers/block/xilinx_sysace/adapter.c
--- linux-2.4.29/drivers/block/xilinx_sysace/adapter.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/block/xilinx_sysace/adapter.c	2005-06-14 02:11:55.000000000 +0100
@@ -0,0 +1,874 @@
+/*
+ * adapter.c
+ *
+ * Xilinx System ACE Adapter component to interface System ACE to Linux
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under the terms
+ * of the GNU General Public License version 2.  This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+/*
+ * Through System ACE, the processor can access the CompactFlash and the
+ * JTAG chain.  In addition, the System ACE controls system reset and
+ * which configuration will be loaded into the JTAG chain at that time.
+ * This driver provides two different interfaces.  The first is handling
+ * reset by tying into the system's reset code as well as providing a
+ * /proc interface to read and write which configuration should be used
+ * when the system is reset.  The second is to expose a block interface
+ * to the CompactFlash.
+ * 
+ * This driver is a bit unusual in that it is composed of two logical
+ * parts where one part is the OS independent code and the other part is
+ * the OS dependent code.  Xilinx provides their drivers split in this
+ * fashion.  This file represents the Linux OS dependent part known as
+ * the Linux adapter.  The other files in this directory are the OS
+ * independent files as provided by Xilinx with no changes made to them.
+ * The names exported by those files begin with XSysAce_.  All functions
+ * in this file that are called by Linux have names that begin with
+ * xsysace_.  Any other functions are static helper functions.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/hdreg.h>
+#include <linux/slab.h>
+#include <linux/blkpg.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#define NR_HD		1	/* System ACE only handles one CompactFlash */
+#define PARTN_BITS 4		/* Only allow 15 partitions. */
+
+/* Dynamically allocate a major number. */
+static int xsa_major = 0;
+#define MAJOR_NR (xsa_major)
+#define MAJOR_NAME "xsysace"
+
+#define DEVICE_NAME "System ACE"
+#define DEVICE_REQUEST xsysace_do_request
+#define DEVICE_NR(device) (MINOR(device) >> PARTN_BITS)
+#include <linux/blk.h>
+#include <linux/blkdev.h>
+
+#include <xbasic_types.h>
+#include "xsysace.h"
+#include <asm/autoconfig.h>
+
+MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
+MODULE_DESCRIPTION("Xilinx System ACE block driver");
+MODULE_LICENSE("GPL");
+
+/*
+ * We have to wait for a lock and for the CompactFlash to not be busy
+ * via polling.  If dont_spin is non-zero, we will use schedule_timeout
+ * in a loop to check for these conditions.  If dont_spin is zero, we
+ * will tight loop without a schedule_timeout as long as need_resched is
+ * false.  If need_resched is true, we'll fall back to using
+ * schedule_timeout.  This could obviously be made run-time settable.
+ */
+static const int dont_spin = 0;
+
+static u32 save_BaseAddress;	/* Saved physical base address */
+// FIXME this was used in the ppc version. Sometime it has to
+//       be adopted to the microblaze
+//static void (*old_restart) (char *cmd) = NULL;	/* old ppc_md.restart *
+static unsigned char heads;
+static unsigned char sectors;
+static unsigned short cylinders;
+
+static int access_count = 0;
+static char revalidating = 0;
+static DECLARE_WAIT_QUEUE_HEAD(revalidate_wait);
+
+/*
+ * The following variables are used to keep track of what all has been
+ * done to make error handling easier.
+ */
+static char reqirq = 0;		/* Has request_irq() been called? */
+static char registered = 0;	/* Has devfs_register_blkdev() been called? */
+
+/*
+ * The underlying OS independent code needs space as well.  A pointer to
+ * the following XSysAce structure will be passed to any XSysAce_
+ * function that requires it.  However, we treat the data as an opaque
+ * object in this file (meaning that we never reference any of the
+ * fields inside of the structure).
+ */
+static XSysAce SysAce;
+
+/* These tables are indexed by major and minor numbers. */
+static int xsa_sizes[NR_HD << PARTN_BITS];	/* Size of the device, kb */
+static int xsa_blocksizes[NR_HD << PARTN_BITS];	/* Block size, bytes */
+static int xsa_hardsectsizes[NR_HD << PARTN_BITS];	/* Sector size, bytes */
+static int xsa_maxsect[NR_HD << PARTN_BITS];	/* Max request size, sectors */
+static struct hd_struct xsa_hd[NR_HD << PARTN_BITS];	/* Partition Table */
+
+/*
+ * In general, requests enter this driver through xsysace_do_request()
+ * which then schedules the xsa_thread.  The xsa_thread sends the
+ * request down to the Xilinx OS independent layer.  When the request
+ * completes, EventHandler() will get called as a result of an
+ * interrupt.  The following variables support this flow.
+ */
+static struct task_struct *xsa_task = NULL;	/* xsa_thread pointer */
+static struct completion task_sync;	/* xsa_thread start/stop syncing */
+static char task_shutdown = 0;	/* Set to non-zero when task should quit.  */
+/*
+ * req_fnc will be either NULL or a pointer to XSysAce_SectorRead or
+ * XSysAce_SectorWrite.  It will be set to point to one of the XSysAce*
+ * functions by xsysace_do_request and then xsa_thread will be scheduled.
+ * The xsa_thread will then NULL req_fnc after it has copied the pointer.
+ */
+static XStatus(*req_fnc) (XSysAce * InstancePtr, u32 StartSector,
+			  int NumSectors, u8 * BufferPtr);
+/* xsa_thread waits on req_wait until xsysace_do_request does wake_up on it */
+static DECLARE_WAIT_QUEUE_HEAD(req_wait);
+/* req_active is a simple flag that says a request is being serviced. */
+static char req_active = 0;
+/* req_str will be used for errors and will be either "reading" or "writing" */
+static char *req_str;
+
+
+/* SAATODO: Xilinx is going to add this function.  Nuke when they do. */
+unsigned int
+XSysAce_GetCfgAddr(XSysAce * InstancePtr)
+{
+	u32 Status;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	Status = XSysAce_mGetControlReg(InstancePtr->BaseAddress);
+	if (!(Status & XSA_CR_FORCECFGADDR_MASK))
+		Status = XSysAce_mGetStatusReg(InstancePtr->BaseAddress);
+
+	return (unsigned int) ((Status & XSA_SR_CFGADDR_MASK) >>
+			       XSA_CR_CFGADDR_SHIFT);
+}
+
+/* SAATODO: Nuke the following line when Config stuff moved out. */
+extern XSysAce_Config XSysAce_ConfigTable[];
+/* SAATODO: This function will be moved into the Xilinx code. */
+/*****************************************************************************/
+/**
+*
+* Lookup the device configuration based on the sysace instance.  The table
+* XSysAce_ConfigTable contains the configuration info for each device in the system.
+*
+* @param Instance is the index of the interface being looked up.
+*
+* @return
+*
+* A pointer to the configuration table entry corresponding to the given
+* device ID, or NULL if no match is found.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XSysAce_Config *
+XSysAce_GetConfig(int Instance)
+{
+	if (Instance < 0 || Instance >= CONFIG_XILINX_SYSACE_NUM_INSTANCES) {
+		return NULL;
+	}
+
+	return &XSysAce_ConfigTable[Instance];
+}
+
+/*
+ * The following block of code implements the reset handling.  The first
+ * part implements /proc/xsysace/cfgaddr.  When read, it will yield a
+ * number from 0 to 7 that represents which configuration will be used
+ * next (the configuration address).  Writing a number to it will change
+ * the configuration address.  After that is the function that is hooked
+ * into the system's reset handler.
+ */
+#ifndef CONFIG_PROC_FS
+#define proc_init() 0
+#define proc_cleanup()
+#else
+#define CFGADDR_NAME "cfgaddr"
+static struct proc_dir_entry *xsysace_dir = NULL;
+static struct proc_dir_entry *cfgaddr_file = NULL;
+
+static int
+cfgaddr_read(char *page, char **start,
+	     off_t off, int count, int *eof, void *data)
+{
+	unsigned int cfgaddr;
+
+	/* Make sure we have room for a digit (0-7), a newline and a NULL */
+	if (count < 3)
+		return -EINVAL;
+
+	MOD_INC_USE_COUNT;
+
+	cfgaddr = XSysAce_GetCfgAddr(&SysAce);
+
+	count = sprintf(page + off, "%d\n", cfgaddr);
+	*eof = 1;
+
+	MOD_DEC_USE_COUNT;
+
+	return count;
+}
+
+static int
+cfgaddr_write(struct file *file,
+	      const char *buffer, unsigned long count, void *data)
+{
+	char val[2];
+
+	if (count < 1 || count > 2)
+		return -EINVAL;
+
+	MOD_INC_USE_COUNT;
+
+	if (copy_from_user(val, buffer, count)) {
+		MOD_DEC_USE_COUNT;
+		return -EFAULT;
+	}
+
+	if (val[0] < '0' || val[0] > '7' || (count == 2 && !(val[1] == '\n' ||
+							     val[1] == '\0'))) {
+		MOD_DEC_USE_COUNT;
+		return -EINVAL;
+	}
+
+	XSysAce_SetCfgAddr(&SysAce, val[0] - '0');
+
+	MOD_DEC_USE_COUNT;
+
+	return count;
+}
+
+static int
+proc_init(void)
+{
+	xsysace_dir = proc_mkdir(MAJOR_NAME, NULL);
+	if (!xsysace_dir)
+		return -ENOMEM;
+	xsysace_dir->owner = THIS_MODULE;
+
+	cfgaddr_file = create_proc_entry(CFGADDR_NAME, 0644, xsysace_dir);
+	if (!cfgaddr_file) {
+		remove_proc_entry(MAJOR_NAME, NULL);
+		return -ENOMEM;
+	}
+	cfgaddr_file->read_proc = cfgaddr_read;
+	cfgaddr_file->write_proc = cfgaddr_write;
+	cfgaddr_file->owner = THIS_MODULE;
+	return 0;
+}
+
+static void
+proc_cleanup(void)
+{
+	if (cfgaddr_file)
+		remove_proc_entry(CFGADDR_NAME, xsysace_dir);
+	if (xsysace_dir)
+		remove_proc_entry(MAJOR_NAME, NULL);
+}
+#endif
+
+// FIXME At the moment this funtion is not used in 
+//       the microblaze port
+static void 
+xsysace_restart(char *cmd) 
+{ 
+	XSysAce_ResetCfg(&SysAce);
+
+	/* Wait for reset. */ 
+	for (;;) ; 
+} 
+
+/*
+ * The code to handle the block device starts here.
+ */
+
+/*
+ * This is just a small helper function to clean up a request that has
+ * been given to the xsa_thread.
+ */
+static void
+xsa_complete_request(int uptodate)
+{
+	unsigned long flags;
+
+	XSysAce_Unlock(&SysAce);
+	spin_lock_irqsave(&io_request_lock, flags);
+	end_request(uptodate);
+	req_active = 0;
+	/* If there's something in the queue, */
+	if (!QUEUE_EMPTY)
+		xsysace_do_request(NULL);	/* handle it. */
+	spin_unlock_irqrestore(&io_request_lock, flags);
+}
+
+/* Small helper function used inside polling loops. */
+static inline void
+xsa_short_delay(void)
+{
+	/* If someone else needs the CPU, go to sleep. */
+	if (dont_spin || current->need_resched) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ / 100);
+	}
+}
+
+/* Simple function that hands an interrupt to the Xilinx code. */
+static void
+xsysace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	XSysAce_InterruptHandler(&SysAce);
+}
+
+/* Called by the Xilinx interrupt handler to give us an event. */
+static void
+EventHandler(void *CallbackRef, int Event)
+{
+	u32 ErrorMask;
+
+	switch (Event) {
+	case XSA_EVENT_DATA_DONE:
+		xsa_complete_request(1);	/* The request succeeded. */
+		break;
+
+	case XSA_EVENT_ERROR:
+		ErrorMask = XSysAce_GetErrors(&SysAce);
+
+		/* Print out what went wrong. */
+		if (ErrorMask & XSA_ER_CARD_RESET)
+			printk(KERN_ERR "CompactFlash failed to reset\n");
+		if (ErrorMask & XSA_ER_CARD_READY)
+			printk(KERN_ERR "CompactFlash failed to ready\n");
+		if (ErrorMask & XSA_ER_CARD_READ)
+			printk(KERN_ERR "CompactFlash read command failed\n");
+		if (ErrorMask & XSA_ER_CARD_WRITE)
+			printk(KERN_ERR "CompactFlash write command failed\n");
+		if (ErrorMask & XSA_ER_SECTOR_READY)
+			printk(KERN_ERR
+			       "CompactFlash sector failed to ready\n");
+		if (ErrorMask & XSA_ER_BAD_BLOCK)
+			printk(KERN_ERR "CompactFlash bad block detected\n");
+		if (ErrorMask & XSA_ER_UNCORRECTABLE)
+			printk(KERN_ERR "CompactFlash uncorrectable error\n");
+		if (ErrorMask & XSA_ER_SECTOR_ID)
+			printk(KERN_ERR "CompactFlash sector ID not found\n");
+		if (ErrorMask & XSA_ER_ABORT)
+			printk(KERN_ERR "CompactFlash command aborted\n");
+		if (ErrorMask & XSA_ER_GENERAL)
+			printk(KERN_ERR "CompactFlash general error\n");
+
+		if (ErrorMask & XSA_ER_CFG_READ)
+			printk(KERN_ERR
+			       "JTAG controller couldn't read configuration from the CompactFlash\n");
+		if (ErrorMask & XSA_ER_CFG_ADDR)
+			printk(KERN_ERR
+			       "Invalid address given to JTAG controller\n");
+		if (ErrorMask & XSA_ER_CFG_FAIL)
+			printk(KERN_ERR
+			       "JTAG controller failed to configure a device\n");
+		if (ErrorMask & XSA_ER_CFG_INSTR)
+			printk(KERN_ERR
+			       "Invalid instruction during JTAG configuration\n");
+		if (ErrorMask & XSA_ER_CFG_INIT)
+			printk(KERN_ERR "JTAG CFGINIT pin error\n");
+
+		/* Check for errors that should reset the CompactFlash */
+		if (ErrorMask & (XSA_ER_CARD_RESET |
+				 XSA_ER_CARD_READY |
+				 XSA_ER_CARD_READ |
+				 XSA_ER_CARD_WRITE |
+				 XSA_ER_SECTOR_READY |
+				 XSA_ER_BAD_BLOCK |
+				 XSA_ER_UNCORRECTABLE |
+				 XSA_ER_SECTOR_ID | XSA_ER_ABORT |
+				 XSA_ER_GENERAL)) {
+			if (XSysAce_ResetCF(&SysAce) != XST_SUCCESS)
+				printk(KERN_ERR
+				       "Could not reset CompactFlash\n");
+			xsa_complete_request(0); /* The request failed. */
+		}
+		break;
+	case XSA_EVENT_CFG_DONE:
+		printk(KERN_WARNING "XSA_EVENT_CFG_DONE not handled yet.\n");
+		break;
+	default:
+		printk(KERN_ERR "%s: unrecognized event %d\n",
+		       DEVICE_NAME, Event);
+		break;
+	}
+}
+
+/*
+ * This task takes care of sending requests down to the Xilinx OS independent
+ * code.  A task is necessary because there isn't an interrupt telling us
+ * when the hardware is ready to accept another request, so we have to poll.
+ */
+static int
+xsa_thread(void *arg)
+{
+	XStatus stat;
+	unsigned long sector;
+
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+	xsa_task = tsk;
+
+	daemonize();
+	reparent_to_init();
+	strcpy(xsa_task->comm, MAJOR_NAME);
+	xsa_task->tty = NULL;
+
+	/* only want to receive SIGKILL */
+	spin_lock_irq(&xsa_task->sigmask_lock);
+	siginitsetinv(&xsa_task->blocked, sigmask(SIGKILL));
+	recalc_sigpending(xsa_task);
+	spin_unlock_irq(&xsa_task->sigmask_lock);
+
+	complete(&task_sync);
+
+	add_wait_queue(&req_wait, &wait);
+	for (;;) {
+		XStatus(*cur_req) (XSysAce * InstancePtr, u32 StartSector,
+				   int NumSectors, u8 * BufferPtr);
+
+		/* Block waiting for request */
+		for (;;) {
+			set_task_state(tsk, TASK_INTERRUPTIBLE);
+			cur_req = req_fnc;
+			if (cur_req != NULL) {
+				req_fnc = NULL;
+				break;	/* We've got a request. */
+			}
+			while (signal_pending(tsk)) {
+				siginfo_t info;
+
+				/* Only honor the signal if we're cleaning up */
+				if (task_shutdown)
+					goto exit;
+				/*
+				 * Someone else sent us a kill (probably
+				 * the shutdown scripts "Sending all
+				 * processes the KILL signal").  Just
+				 * dequeue it and ignore it.
+				 */
+				spin_lock_irq(&current->sigmask_lock);
+				(void)dequeue_signal(&current->blocked, &info);
+				spin_unlock_irq(&current->sigmask_lock);
+			}
+			schedule();
+		}
+		set_task_state(tsk, TASK_RUNNING);
+
+		/* We have a request. */
+		sector = (CURRENT->sector +
+			  xsa_hd[MINOR(CURRENT->rq_dev)].start_sect);
+
+		while ((stat = XSysAce_Lock(&SysAce, 0)) == XST_DEVICE_BUSY)
+			xsa_short_delay();
+		if (stat != XST_SUCCESS) {
+			printk(KERN_ERR "%s: Error %d when locking.\n",
+			       DEVICE_NAME, stat);
+			xsa_complete_request(0);	/* Request failed. */
+		}
+
+		while ((stat = cur_req(&SysAce, sector,
+				       CURRENT->current_nr_sectors,
+				       CURRENT->buffer)) == XST_DEVICE_BUSY)
+			xsa_short_delay();
+		/*
+		 * If the stat is XST_SUCCESS, we have successfully
+		 * gotten the request started on the hardware.  The
+		 * completion (or error) interrupt will unlock the
+		 * CompactFlash and complete the request, so we don't
+		 * need to do anything except just loop around and wait
+		 * for the next request.  If the status is not
+		 * XST_SUCCESS, we need to finish the request with an
+		 * error before waiting for the next request.
+		 */
+		if (stat != XST_SUCCESS) {
+			printk(KERN_ERR "%s: Error %d when %s sector %lu.\n",
+			       DEVICE_NAME, stat, req_str, sector);
+			xsa_complete_request(0);	/* Request failed. */
+		}
+	}
+
+      exit:
+	remove_wait_queue(&req_wait, &wait);
+
+	xsa_task = NULL;
+	complete_and_exit(&task_sync, 0);
+}
+
+static void
+xsysace_do_request(request_queue_t * q)
+{
+	/* We're already handling a request.  Don't accept another. */
+	if (req_active)
+		return;
+
+	for (;;) {
+		INIT_REQUEST;
+
+		switch (CURRENT->cmd) {
+		case READ:
+			req_str = "reading";
+			req_fnc = XSysAce_SectorRead;
+			break;
+		case WRITE:
+			req_str = "writing";
+			req_fnc = XSysAce_SectorWrite;
+			break;
+		default:
+			printk(KERN_CRIT "%s: unknown request %d.\n",
+			       DEVICE_NAME, CURRENT->cmd);
+			end_request(0);	/* Bad request.  End it and onwards. */
+			continue;	/* Go on to the next request. */
+		}
+
+		req_active = 1;
+		wake_up(&req_wait);	/* Schedule task to take care of it */
+		/*
+		 * It is up to the task or interrupt handler to complete
+		 * the request.  We return now so the io_request_lock
+		 * will get cleared and requests can be queued.
+		 */
+		return;
+	}
+}
+
+extern struct gendisk xsa_gendisk;
+static int
+xsa_revalidate(kdev_t kdev, int max_access)
+{
+	int target, max_p, start, i;
+	long flags;
+
+	target = DEVICE_NR(kdev);
+
+	save_flags(flags);
+	cli();
+	if (revalidating || access_count > max_access) {
+		restore_flags(flags);
+		return -EBUSY;
+	}
+	revalidating = 1;
+	restore_flags(flags);
+
+	max_p = xsa_gendisk.max_p;
+	start = target << PARTN_BITS;
+	for (i = max_p - 1; i >= 0; i--) {
+		int minor = start + i;
+		invalidate_device(MKDEV(MAJOR_NR, minor), 1);
+		xsa_gendisk.part[minor].start_sect = 0;
+		xsa_gendisk.part[minor].nr_sects = 0;
+	}
+
+	grok_partitions(&xsa_gendisk, target, NR_HD << PARTN_BITS,
+			(long) cylinders * (long) heads * (long) sectors);
+	revalidating = 0;
+	wake_up(&revalidate_wait);
+	return 0;
+}
+
+/*
+ * For right now, there isn't a way to tell the hardware to spin down
+ * the drive.  For IBM Microdrives, which is what the ML300 ships with,
+ * removing them without a spindown is probably not very good.  Thus, we
+ * don't even want to have the System ACE driver handle removable media.
+ * For now, placeholder code has been surrounded by ifdef XSA_REMOVABLE
+ * (which is not defined) in a few places in this file.  Something that
+ * is not handled in the placeholder code is identifying the new drive.
+ */
+#ifdef XSA_REMOVABLE
+static int
+xsysace_revalidate(kdev_t kdev)
+{
+	return xsa_revalidate(kdev, 0);
+}
+
+static int
+xsysace_check_change(kdev_t kdev)
+{
+	/*
+	 * If and when we do support removable media, we'll need to
+	 * figure out how to tell if the media was changed.  For now,
+	 * just always say that the media was changed, which is safe,
+	 * but not optimal.
+	 */
+	return 1;
+}
+#endif
+
+static int
+xsysace_open(struct inode *inode, struct file *file)
+{
+	wait_event(revalidate_wait, !revalidating);
+	access_count++;
+
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+static int
+xsysace_release(struct inode *inode, struct file *file)
+{
+	access_count--;
+
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+static int
+xsysace_ioctl(struct inode *inode, struct file *file,
+	      unsigned int cmd, unsigned long arg)
+{
+	if (!inode || !inode->i_rdev)
+		return -EINVAL;
+
+	switch (cmd) {
+	case BLKGETSIZE:
+		return put_user(xsa_hd[MINOR(inode->i_rdev)].nr_sects,
+				(unsigned long *) arg);
+	case BLKGETSIZE64:
+		return put_user((u64) xsa_hd[MINOR(inode->i_rdev)].
+				nr_sects, (u64 *) arg);
+	case BLKRRPART:
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
+
+		return xsa_revalidate(inode->i_rdev, 1);
+
+	case HDIO_GETGEO:
+		{
+			struct hd_geometry *loc, g;
+			loc = (struct hd_geometry *) arg;
+			if (!loc)
+				return -EINVAL;
+			g.heads = heads;
+			g.sectors = sectors;
+			g.cylinders = cylinders;
+			g.start = xsa_hd[MINOR(inode->i_rdev)].start_sect;
+			return copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0;
+		}
+	default:
+		/* Let the block layer handle all the others. */
+		return blk_ioctl(inode->i_rdev, cmd, arg);
+	}
+}
+
+static struct block_device_operations xsa_fops = {
+	open:xsysace_open,
+	release:xsysace_release,
+	ioctl:xsysace_ioctl,
+#ifdef XSA_REMOVABLE
+	check_media_change:xsysace_check_change,
+	revalidate:xsysace_revalidate
+#endif
+};
+static struct gendisk xsa_gendisk = {	/* Generic Hard Disk */
+	major_name:MAJOR_NAME,
+	minor_shift:PARTN_BITS,
+	max_p:NR_HD << PARTN_BITS,
+	part:xsa_hd,
+	sizes:xsa_sizes,
+	fops:&xsa_fops
+};
+
+/* FIXME hardcoded IRQ for sysace at IRQ 4 */
+#if 1
+#define XSA_IRQ (CONFIG_XILINX_SYSACE_0_IRQ)
+#else
+#define XSA_IRQ (31 - XPAR_INTC_0_SYSACE_0_VEC_ID)
+#endif
+
+static void
+cleanup(void)
+{
+	XSysAce_Config *cfg;
+	int i;
+
+	/* Make sure everything is flushed. */
+	for (i = 0; i < (NR_HD << PARTN_BITS); i++)
+		fsync_dev(MKDEV(xsa_major, i));
+
+	proc_cleanup();
+
+	if (registered) {
+		blk_cleanup_queue(BLK_DEFAULT_QUEUE(xsa_major));
+		del_gendisk(&xsa_gendisk);
+		if (devfs_unregister_blkdev(xsa_major, DEVICE_NAME) != 0) {
+			printk(KERN_ERR "%s: unable to release major %d\n",
+			       DEVICE_NAME, xsa_major);
+		}
+	}
+
+	/* Tidy up a little. */
+	read_ahead[xsa_major] = 0;
+	blk_size[xsa_major] = NULL;
+	blksize_size[xsa_major] = NULL;
+	hardsect_size[xsa_major] = NULL;
+	max_sectors[xsa_major] = NULL;
+
+	if (xsa_task) {
+		task_shutdown = 1;
+		send_sig(SIGKILL, xsa_task, 1);
+		wait_for_completion(&task_sync);
+	}
+
+	if (reqirq) {
+		XSysAce_DisableInterrupt(&SysAce);
+		disable_irq(XSA_IRQ);
+		free_irq(XSA_IRQ, NULL);
+	}
+
+	cfg = XSysAce_GetConfig(0);
+	iounmap((void *) cfg->BaseAddress);
+	cfg->BaseAddress = save_BaseAddress;
+
+	// FIXME this is left over from the ppc version of this
+        //       file. Sometime it has to be ported to the
+        //       microblaze
+	//	if (old_restart) 
+	//		ppc_md.restart = old_restart; 
+}
+
+static int __init
+xsysace_init(void)
+{
+	static const unsigned long remap_size
+	    = CONFIG_XILINX_SYSACE_0_HIGHADDR - CONFIG_XILINX_SYSACE_0_BASEADDR + 1;
+	XSysAce_Config *cfg;
+	XSysAce_CFParameters ident;
+	XStatus stat;
+	long size;
+	int i;
+
+	printk("Initializing SystemAce driver\n");
+	/* Find the config for our device. */
+	cfg = XSysAce_GetConfig(0);
+	if (!cfg)
+		return -ENODEV;
+
+	/* Change the addresses to be virtual; save the old ones to restore. */
+	save_BaseAddress = cfg->BaseAddress;
+	cfg->BaseAddress = (u32) ioremap(save_BaseAddress, remap_size);
+
+	/* Tell the Xilinx code to bring this interface up. */
+	if (XSysAce_Initialize(&SysAce, cfg->DeviceId) != XST_SUCCESS) {
+		printk(KERN_ERR "%s: Could not initialize device.\n",
+		       DEVICE_NAME);
+		cleanup();
+		return -ENODEV;
+	}
+
+	i = request_irq(XSA_IRQ, xsysace_interrupt, 0, DEVICE_NAME, NULL);
+	if (i) {
+		printk(KERN_ERR "%s: Could not allocate interrupt %d.\n",
+		       DEVICE_NAME, XSA_IRQ);
+		cleanup();
+		return i;
+	}
+	reqirq = 1;
+	XSysAce_SetEventHandler(&SysAce, EventHandler, (void *) NULL);
+	XSysAce_EnableInterrupt(&SysAce);
+
+	/* Time to identify the drive. */
+	while (XSysAce_Lock(&SysAce, 0) == XST_DEVICE_BUSY)
+		xsa_short_delay();
+	while ((stat = XSysAce_IdentifyCF(&SysAce, &ident)) == XST_DEVICE_BUSY)
+		xsa_short_delay();
+	XSysAce_Unlock(&SysAce);
+	if (stat != XST_SUCCESS) {
+		printk(KERN_ERR "%s: Could not send identify command.\n",
+		       DEVICE_NAME);
+		cleanup();
+		return -ENODEV;
+	}
+
+	/* Fill in what we learned. */
+	heads = ident.NumHeads;
+	sectors = ident.NumSectorsPerTrack;
+	cylinders = ident.NumCylinders;
+	size = (long) cylinders * (long) heads * (long) sectors;
+
+	/* Start up our task. */
+	init_completion(&task_sync);
+	if ((i = kernel_thread(xsa_thread, 0, 0)) < 0) {
+		cleanup();
+		return i;
+	}
+	wait_for_completion(&task_sync);
+
+	i = devfs_register_blkdev(xsa_major, DEVICE_NAME, &xsa_fops);
+	if (i < 0) {
+		printk(KERN_ERR "%s: unable to register device\n", DEVICE_NAME);
+		cleanup();
+		return i;
+	}
+	if (xsa_major == 0)
+		xsa_major = i;
+	registered = 1;
+	xsa_gendisk.major = xsa_major;
+
+	blk_init_queue(BLK_DEFAULT_QUEUE(xsa_major), xsysace_do_request);
+
+	read_ahead[xsa_major] = 8;	/* 8 sector (4kB) read-ahead */
+	add_gendisk(&xsa_gendisk);
+
+	/* Start with zero-sized partitions, and correctly sized unit */
+	memset(xsa_sizes, 0, sizeof(xsa_sizes));
+	xsa_sizes[0] = size / 2;	/* convert sectors to kilobytes */
+	blk_size[xsa_major] = xsa_sizes;
+	memset(xsa_hd, 0, sizeof(xsa_hd));
+	xsa_hd[0].nr_sects = size;
+	for (i = 0; i < (NR_HD << PARTN_BITS); i++) {
+		xsa_blocksizes[i] = 1024;
+		xsa_hardsectsizes[i] = 512;
+		/* XSysAce_Sector{Read,Write} will allow up to 256 sectors. */
+		xsa_maxsect[i] = 256;
+	}
+	blksize_size[xsa_major] = xsa_blocksizes;
+	hardsect_size[xsa_major] = xsa_hardsectsizes;
+	max_sectors[xsa_major] = xsa_maxsect;
+
+	xsa_gendisk.nr_real = NR_HD;
+
+	register_disk(&xsa_gendisk, MKDEV(xsa_major, 0),
+		      NR_HD << PARTN_BITS, &xsa_fops, size);
+
+	printk(KERN_INFO
+	       "%s at 0x%08X mapped to 0x%08X, irq=%d, %ldKB\n",
+	       DEVICE_NAME, save_BaseAddress, cfg->BaseAddress, XSA_IRQ,
+	       size / 2);
+
+	/* Hook our reset function into system's restart code. */
+        /* FIXME Still has to be ported to microblaze */
+	//	old_restart = ppc_md.restart; 
+	//	ppc_md.restart = xsysace_restart; 
+
+	if (proc_init())
+		printk(KERN_WARNING "%s: could not register /proc interface.\n",
+		       DEVICE_NAME);
+
+	return 0;
+}
+
+static void __exit
+xsysace_exit(void)
+{
+	cleanup();
+}
+
+EXPORT_NO_SYMBOLS;
+
+module_init(xsysace_init);
+module_exit(xsysace_exit);
diff -urN linux-2.4.29/drivers/block/xilinx_sysace/Makefile linux-2.4.29-uc1/drivers/block/xilinx_sysace/Makefile
--- linux-2.4.29/drivers/block/xilinx_sysace/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/block/xilinx_sysace/Makefile	2005-06-14 02:11:55.000000000 +0100
@@ -0,0 +1,21 @@
+#
+# Makefile for the Xilinx System ACE driver
+#
+
+EXTRA_CFLAGS		+= -I$(TOPDIR)/arch/microblaze/xilinx_ocp
+
+list-multi		:= xilinx_sysace.o
+
+# The Linux adapter for the Xilinx driver code.
+xilinx_sysace-objs	+= adapter.o
+
+# The Xilinx OS independent code.
+xilinx_sysace-objs	+= xsysace.o xsysace_g.o xsysace_intr.o xsysace_l.o
+xilinx_sysace-objs	+= xsysace_compactflash.o xsysace_jtagcfg.o
+
+obj-$(CONFIG_XILINX_SYSACE) := xilinx_sysace.o
+
+xilinx_sysace.o: $(xilinx_sysace-objs)
+	$(LD) -r -o $@ $(xilinx_sysace-objs)
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/block/xilinx_sysace/xsysace.c linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace.c
--- linux-2.4.29/drivers/block/xilinx_sysace/xsysace.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace.c	2005-06-14 02:11:55.000000000 +0100
@@ -0,0 +1,377 @@
+/* $Id: xsysace.c,v 1.6 2003/05/14 13:53:30 robertm Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xsysace.c
+*
+* The Xilinx System ACE driver component. This driver supports the Xilinx
+* System Advanced Configuration Environment (ACE) controller. It currently
+* supports only the CompactFlash solution. See xsysace.h for a detailed
+* description of the driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  06/17/02 work in progress
+* 1.00a rmm  05/14/03 Fixed diab compiler warnings relating to asserts
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+//#include <asm/xparameters.h>
+#include "xsysace.h"
+#include "xsysace_l.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+static void StubEventHandler(void *CallBackRef, int Event);
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+*
+* Initialize a specific XSysAce instance. The configuration information for
+* the given device ID is found and the driver instance data is initialized
+* appropriately.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+* @param DeviceId is the unique id of the device controlled by this XSysAce
+*        instance.
+*
+* @return
+*
+* XST_SUCCESS if successful, or XST_DEVICE_NOT_FOUND if the device was not
+* found in the configuration table in xsysace_g.c.
+*
+* @note
+*
+* We do not want to reset the configuration controller here since this could
+* cause a reconfiguration of the JTAG target chain, depending on how the
+* CFGMODEPIN of the device is wired.
+*
+******************************************************************************/
+XStatus XSysAce_Initialize(XSysAce *InstancePtr, u16 DeviceId)
+{
+    XSysAce_Config *ConfigPtr;
+
+    XASSERT_NONVOID(InstancePtr != NULL);
+
+    InstancePtr->IsReady = 0;
+
+    /*
+     * Lookup configuration data in the device configuration table.
+     * Use this configuration info down below when initializing this component.
+     */
+    ConfigPtr = XSysAce_LookupConfig(DeviceId);
+
+    if (ConfigPtr == (XSysAce_Config *)NULL)
+    {
+        return XST_DEVICE_NOT_FOUND;
+    }
+
+    /*
+     * Set some default values for the instance data
+     */
+    InstancePtr->BaseAddress = ConfigPtr->BaseAddress;
+    InstancePtr->EventHandler = StubEventHandler;
+    InstancePtr->NumRequested = 0;
+    InstancePtr->NumRemaining = 0;
+    InstancePtr->BufferPtr = NULL;
+
+    /*
+     * Put the device into 16-bit mode or 8-bit mode depending on compile-time
+     * parameter
+     */
+#if (CONFIG_XILINX_SYSACE_0_MEM_WIDTH == 16)
+    XSysAce_RegWrite16(InstancePtr->BaseAddress + XSA_BMR_OFFSET,
+                       XSA_BMR_16BIT_MASK);
+#else
+    XSysAce_RegWrite16(InstancePtr->BaseAddress + XSA_BMR_OFFSET, 0);
+#endif
+
+    /*
+     * Disable interrupts. Interrupts must be enabled by the user using
+     * XSysAce_EnableInterrupt(). Put the interrupt request line in reset and
+     * clear the interrupt enable bits.
+     */
+    XSysAce_mOrControlReg(InstancePtr->BaseAddress, XSA_CR_RESETIRQ_MASK);
+    XSysAce_mAndControlReg(InstancePtr->BaseAddress, ~(XSA_CR_DATARDYIRQ_MASK |
+                           XSA_CR_ERRORIRQ_MASK | XSA_CR_CFGDONEIRQ_MASK));
+
+    /*
+     * Indicate the instance is now ready to use, initialized without error
+     */
+    InstancePtr->IsReady = XCOMPONENT_IS_READY;
+
+    return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Attempt to lock access to the CompactFlash. The CompactFlash may be accessed
+* by the MPU port as well as the JTAG configuration port within the System ACE
+* device. This function requests exclusive access to the CompactFlash for the
+* MPU port. This is a non-blocking request. If access cannot be locked
+* (because the configuration controller has the lock), an appropriate status is
+* returned. In this case, the user should call this function again until
+* successful.
+*
+* If the user requests a forced lock, the JTAG configuration controller will
+* be put into a reset state in case it currently has a lock on the CompactFlash.
+* This effectively aborts any operation the configuration controller had in
+* progress and makes the configuration controller restart its process the
+* next time it is able to get a lock.
+*
+* A lock must be granted to the user before attempting to read or write the
+* CompactFlash device.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+* @param Force is a boolean value that, when set to TRUE, will force the MPU
+*        lock to occur in the System ACE.  When set to FALSE, the lock is
+*        requested and the device arbitrates between the MPU request and
+*        JTAG requests. Forcing the MPU lock resets the configuration
+*        controller, thus aborting any configuration operations in progress.
+*
+* @return
+*
+* XST_SUCCESS if the lock was granted, or XST_DEVICE_BUSY if the lock was
+* not granted because the configuration controller currently has access to
+* the CompactFlash.
+*
+* @note
+*
+* If the lock is not granted to the MPU immediately, this function removes its
+* request for a lock so that a lock is not later granted at a time when the
+* application is (a) not ready for the lock, or (b) cannot be informed
+* asynchronously about the granted lock since there is no such interrupt event.
+*
+******************************************************************************/
+XStatus XSysAce_Lock(XSysAce *InstancePtr, u32 Force)
+{
+    u32 IsLocked;
+
+    XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    /*
+     * Check to see if the configuration controller currently has the lock
+     */
+    IsLocked = (XSysAce_mGetStatusReg(InstancePtr->BaseAddress) &
+                XSA_SR_CFGLOCK_MASK);
+
+    if (Force)
+    {
+        /*
+         * Reset the configuration controller if it has the lock. Per ASIC
+         * designer, this eliminates a potential deadlock if the FORCELOCK and
+         * LOCKREQ bits are both set and the RDYFORCFCMD is not set.
+         */
+        if (IsLocked)
+        {
+            /* Reset the configuration controller */
+            XSysAce_mOrControlReg(InstancePtr->BaseAddress,
+                                  XSA_CR_CFGRESET_MASK);
+        }
+
+        /* Force the MPU lock. The lock will occur immediately. */
+        XSysAce_mOrControlReg(InstancePtr->BaseAddress, XSA_CR_LOCKREQ_MASK |
+                              XSA_CR_FORCELOCK_MASK);
+    }
+    else
+    {
+        /*
+         * Check to see if the configuration controller has the lock. If so,
+         * return a busy status.
+         */
+        if (IsLocked)
+        {
+            return XST_DEVICE_BUSY;
+        }
+
+        /* Request the lock, but do not force it */
+        XSysAce_mOrControlReg(InstancePtr->BaseAddress, XSA_CR_LOCKREQ_MASK);
+    }
+
+    /*
+     * See if the lock was granted. Note that it is guaranteed to occur if
+     * the user forced it.
+     */
+    if (!XSysAce_mIsMpuLocked(InstancePtr->BaseAddress))
+    {
+        /* Lock was not granted, so remove request and return a busy */
+        XSysAce_mAndControlReg(InstancePtr->BaseAddress,
+                               ~(XSA_CR_LOCKREQ_MASK | XSA_CR_FORCELOCK_MASK));
+
+        return XST_DEVICE_BUSY;
+    }
+
+    /*
+     * Lock has been granted.
+     *
+     * If the configuration controller had the lock and has been reset,
+     * go ahead and release it from reset as it will not be able to get
+     * the lock again until the MPU lock is released.
+     */
+    if (IsLocked && Force)
+    {
+        /* Release the reset of the configuration controller */
+        XSysAce_mAndControlReg(InstancePtr->BaseAddress, ~XSA_CR_CFGRESET_MASK);
+    }
+
+    return XST_SUCCESS;
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Release the MPU lock to the CompactFlash. If a lock is not currently granted
+* to the MPU port, this function has no effect.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XSysAce_Unlock(XSysAce *InstancePtr)
+{
+    XASSERT_VOID(InstancePtr != NULL);
+    XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    /*
+     * Blindly clear the lock and force-lock request bits of the control
+     * register
+     */
+    XSysAce_mAndControlReg(InstancePtr->BaseAddress,
+                ~(XSA_CR_LOCKREQ_MASK | XSA_CR_FORCELOCK_MASK));
+}
+
+/*****************************************************************************/
+/**
+*
+* Get all outstanding errors. Errors include the inability to read or write
+* CompactFlash and the inability to successfully configure FPGA devices along
+* the target FPGA chain.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+*
+* @return
+*
+* A 32-bit mask of error values. See xsysace_l.h for a description of possible
+* values. The error identifiers are prefixed with XSA_ER_*.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32 XSysAce_GetErrors(XSysAce *InstancePtr)
+{
+    XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    return XSysAce_mGetErrorReg(InstancePtr->BaseAddress);
+}
+
+/*****************************************************************************/
+/**
+*
+* Stub for the asynchronous event callback. The stub is here in case the upper
+* layers forget to set the handler.
+*
+* @param    CallBackRef is a pointer to the upper layer callback reference
+* @param    Event is the event that occurs
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void StubEventHandler(void *CallBackRef, int Event)
+{
+    XASSERT_VOID_ALWAYS();
+}
+
+/*****************************************************************************/
+/**
+*
+* Looks up the device configuration based on the unique device ID. The table
+* XSysAce_ConfigTable contains the configuration info for each device in the
+* system.
+*
+* @param DeviceId is the unique device ID to look for.
+*
+* @return
+*
+* A pointer to the configuration data for the device, or NULL if no match is
+* found.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XSysAce_Config *XSysAce_LookupConfig(u16 DeviceId)
+{
+    extern XSysAce_Config XSysAce_ConfigTable[];
+    XSysAce_Config *CfgPtr = NULL;
+    int i;
+
+    for (i=0; i < CONFIG_XILINX_SYSACE_NUM_INSTANCES; i++)
+    {
+        if (XSysAce_ConfigTable[i].DeviceId == DeviceId)
+        {
+            CfgPtr = &XSysAce_ConfigTable[i];
+            break;
+        }
+    }
+
+    return CfgPtr;
+}
+
diff -urN linux-2.4.29/drivers/block/xilinx_sysace/xsysace_compactflash.c linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace_compactflash.c
--- linux-2.4.29/drivers/block/xilinx_sysace/xsysace_compactflash.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace_compactflash.c	2005-06-14 02:11:55.000000000 +0100
@@ -0,0 +1,773 @@
+/* $Id: xsysace_compactflash.c,v 1.9 2002/08/12 15:27:55 moleres Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xsysace_compactflash.c
+*
+* Contains functions to reset, read, and write the CompactFlash device via
+* the System ACE controller.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  06/17/02 work in progress
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xsysace.h"
+#include "xsysace_l.h"
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * Indices into the parameter information from the CompactFlash.  When the
+ * user calls XSysAce_IdentifyCF(), the parameter information is read into a
+ * byte buffer.  The byte buffer is then mapped to a XSysAce_CFParameters
+ * structure using these indices into the byte buffer.
+ */
+#define XSA_CFPARM_SIGNATURE    0
+#define XSA_CFPARM_NUMCYLS      2
+#define XSA_CFPARM_RESERVED1    4
+#define XSA_CFPARM_NUMHEADS     6
+#define XSA_CFPARM_BYTES_TRACK  8
+#define XSA_CFPARM_BYTES_SECT   10
+#define XSA_CFPARM_SECTS_TRK    12
+#define XSA_CFPARM_SECTS_HI     14
+#define XSA_CFPARM_SECTS_LO     16
+#define XSA_CFPARM_VENDOR1      18
+#define XSA_CFPARM_SERIAL_NO    20
+#define XSA_CFPARM_BUFFER_TYPE  40
+#define XSA_CFPARM_BUFFER_SIZE  42
+#define XSA_CFPARM_ECC_BYTES    44
+#define XSA_CFPARM_FW_VERSION   46
+#define XSA_CFPARM_MODEL_NO     54
+#define XSA_CFPARM_MAX_SECTORS  94
+#define XSA_CFPARM_DBL_WORD     96
+#define XSA_CFPARM_CAPS         98
+#define XSA_CFPARM_RESERVED2    100
+#define XSA_CFPARM_PIO_MODE     102
+#define XSA_CFPARM_DMA_MODE     104
+#define XSA_CFPARM_TRANSLATE    106
+#define XSA_CFPARM_CURCYLS      108
+#define XSA_CFPARM_CURHEADS     110
+#define XSA_CFPARM_CURSECTS_TRK 112
+#define XSA_CFPARM_CURSECTS     114
+#define XSA_CFPARM_MULTIPLE     118
+#define XSA_CFPARM_LBA_SECTS    120
+#define XSA_CFPARM_RESERVED3    124
+#define XSA_CFPARM_SECURITY     256
+#define XSA_CFPARM_VENDOR2      258
+#define XSA_CFPARM_POWER        320
+#define XSA_CFPARM_RESERVED4    322
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+static void ByteCopy(u8 *SourcePtr, u8 *DestPtr, int NumBytes);
+static void FillParam(XSysAce_CFParameters *ParamPtr, u8 *BufPtr);
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+*
+* Reset the CompactFlash device. This function does not reset the System ACE
+* controller.  An ATA soft-reset of the CompactFlash is performed.
+*
+* An MPU lock, obtained using XSysAce_Lock(), must be granted before calling
+* this function. If a lock has not been granted, no action is taken and an
+* error is returned.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+*
+* @return
+*
+* - XST_SUCCESS if the reset was done successfully
+* - XST_SYSACE_NO_LOCK if no MPU lock has yet been granted
+* - XST_DEVICE_BUSY if the CompactFlash is not ready for a command
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus XSysAce_ResetCF(XSysAce *InstancePtr)
+{
+    XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    /* If a lock has not been granted, return an error */
+    if (!XSysAce_mIsMpuLocked(InstancePtr->BaseAddress))
+    {
+        return XST_SYSACE_NO_LOCK;
+    }
+
+    /* See if the CF is ready for a command */
+    if (!XSysAce_mIsReadyForCmd(InstancePtr->BaseAddress))
+    {
+        return XST_DEVICE_BUSY;
+    }
+
+    /*
+     * If interrupts are enabled, enable the error interrupt. A reset clears
+     * the error status, so we're going to re-enable the interrupt here so any
+     * new errors will be caught.
+     */
+    if (XSysAce_mIsIntrEnabled(InstancePtr->BaseAddress))
+    {
+        XSysAce_mOrControlReg(InstancePtr->BaseAddress, XSA_CR_ERRORIRQ_MASK);
+    }
+
+    /*
+     * Send the reset command
+     */
+    XSysAce_RegWrite16(InstancePtr->BaseAddress + XSA_SCCR_OFFSET,
+                        XSA_SCCR_RESET_MASK);
+
+    return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Abort the CompactFlash operation currently in progress.
+*
+* An MPU lock, obtained using XSysAce_Lock(), must be granted before calling
+* this function. If a lock has not been granted, no action is taken and an
+* error is returned.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+*
+* @return
+*
+* - XST_SUCCESS if the abort was done successfully
+* - XST_SYSACE_NO_LOCK if no MPU lock has yet been granted
+* - XST_DEVICE_BUSY if the CompactFlash is not ready for a command
+*
+* @note
+*
+* According to the ASIC designer, the abort command has not been well tested.
+*
+******************************************************************************/
+XStatus XSysAce_AbortCF(XSysAce *InstancePtr)
+{
+    XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    /* If a lock has not been granted, return an error */
+    if (!XSysAce_mIsMpuLocked(InstancePtr->BaseAddress))
+    {
+        return XST_SYSACE_NO_LOCK;
+    }
+
+    /*
+     * See if the CF is ready for a command
+     *
+     * TODO: make sure this check works, or possibly the abort can be done
+     * if it is not ready for a command (e.g., that's what we're aborting)?
+     */
+    if (!XSysAce_mIsReadyForCmd(InstancePtr->BaseAddress))
+    {
+        return XST_DEVICE_BUSY;
+    }
+
+    /*
+     * Send the abort command
+     */
+    XSysAce_RegWrite16(InstancePtr->BaseAddress + XSA_SCCR_OFFSET,
+                        XSA_SCCR_ABORT_MASK);
+
+    return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Identify the CompactFlash device. Retrieves the parameters for the
+* CompactFlash storage device. Note that this is a polled read of one sector
+* of data. The data is read from the CompactFlash into a byte buffer, which
+* is then copied into the XSysAce_CFParameters structure passed in by the
+* user.  The copy is necessary since we don't know how the compiler packs
+* the XSysAce_CFParameters structure.
+*
+* An MPU lock, obtained using XSysAce_Lock(), must be granted before calling
+* this function. If a lock has not been granted, no action is taken and an
+* error is returned.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+* @param ParamPtr is a pointer to a XSysAce_CFParameters structure where the
+*        information for the CompactFlash device will be stored. See xsysace.h
+*        for details on the XSysAce_CFParameters structure.
+*
+* @return
+*
+* - XST_SUCCESS if the identify was done successfully
+* - XST_FAILURE if an error occurs. Use XSysAce_GetErrors() to determine cause.
+* - XST_SYSACE_NO_LOCK if no MPU lock has yet been granted
+* - XST_DEVICE_BUSY if the CompactFlash is not ready for a command
+*
+* @note
+*
+* None.
+*
+* @internal
+*
+* The identify command has the same protocol as the read sector command
+* according to the CompactFlash specification.  However, there is a discepency
+* in that same specification on the size of the parameter structure. The word
+* addresses defined in the spec indicate the parameter information is a full
+* 512 bytes, the same size as a sector. The total bytes defined in the spec,
+* however, indicate that the parameter information is only 500 bytes. We
+* defined the parameter structure in xsysace.h assuming the parameters are the
+* full 512 bytes since that makes sense, and therefore ignored the "Total
+* Bytes" column in the spec.
+*
+* The SectorData variable was made static to avoid putting 512 bytes on the
+* stack every time this function is called.
+*
+******************************************************************************/
+XStatus XSysAce_IdentifyCF(XSysAce *InstancePtr, XSysAce_CFParameters *ParamPtr)
+{
+    int NumRead;
+    u32 InterruptsOn;
+    static u8 SectorData[XSA_CF_SECTOR_SIZE];
+
+    XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(ParamPtr != NULL);
+    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    /* If a lock has not been granted, return an error */
+    if (!XSysAce_mIsMpuLocked(InstancePtr->BaseAddress))
+    {
+        return XST_SYSACE_NO_LOCK;
+    }
+
+    /* See if the CF is ready for a command */
+    if (!XSysAce_mIsReadyForCmd(InstancePtr->BaseAddress))
+    {
+        return XST_DEVICE_BUSY;
+    }
+
+    /*
+     * If interrupts are enabled, we disable them because we want to do this
+     * identify in polled mode - due to the buffer endian conversion and copy
+     * that takes place.
+     */
+    InterruptsOn = XSysAce_mIsIntrEnabled(InstancePtr->BaseAddress);
+    if (InterruptsOn)
+    {
+        XSysAce_DisableInterrupt(InstancePtr);
+    }
+
+    /*
+     * Send the identify command
+     */
+    XSysAce_RegWrite16(InstancePtr->BaseAddress + XSA_SCCR_OFFSET,
+                        XSA_SCCR_IDENTIFY_MASK);
+
+    /*
+     * Read a sector of data from the data buffer. The parameter info is
+     * the same size as a sector.
+     */
+    NumRead = XSysAce_ReadDataBuffer(InstancePtr->BaseAddress, SectorData,
+                                     XSA_CF_SECTOR_SIZE);
+
+    /* If interrupts were on, re-enable interrupts (regardless of error) */
+    if (InterruptsOn)
+    {
+        XSysAce_EnableInterrupt(InstancePtr);
+    }
+
+    if (NumRead == 0)
+    {
+        /* an error occurred */
+        return XST_FAILURE;
+    }
+
+    /*
+     * Copy the byte buffer to the parameter structure
+     */
+    FillParam(ParamPtr, SectorData);
+
+    return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Check to see if the CompactFlash is ready for a command. The CompactFlash
+* may delay after one operation before it is ready for the next. This function
+* helps the user determine when it is ready before invoking a CompactFlash
+* operation such as XSysAce_SectorRead() or XSysAce_SectorWrite();
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+*
+* @return
+*
+* TRUE if the CompactFlash is ready for a command, and FALSE otherwise.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32 XSysAce_IsCFReady(XSysAce *InstancePtr)
+{
+    XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    return XSysAce_mIsReadyForCmd(InstancePtr->BaseAddress);
+}
+
+/*****************************************************************************/
+/**
+*
+* Read at least one sector of data from the CompactFlash. The user specifies
+* the starting sector ID and the number of sectors to be read. The minimum unit
+* that can be read from the CompactFlash is a sector, which is 512 bytes.
+*
+* In polled mode, this read is blocking. If there are other tasks in the system
+* that must run, it is best to keep the number of sectors to be read to a
+* minimum (e.g., 1). In interrupt mode, this read is non-blocking and an event,
+* XSA_EVENT_DATA_DONE, is returned to the user in the asynchronous event
+* handler when the read is complete. The user must call
+* XSysAce_EnableInterrupt() to put the driver/device into interrupt mode.
+*
+* An MPU lock, obtained using XSysAce_Lock(), must be granted before calling
+* this function. If a lock has not been granted, no action is taken and an
+* error is returned.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+* @param StartSector is the starting sector ID from where data will be read.
+*        Sector IDs range from 0 (first sector) to 0x10000000.
+* @param NumSectors is the number of sectors to read. The range can be from
+*        1 to 256.
+* @param BufferPtr is a pointer to a buffer where the data will be stored.
+*        The user must ensure it is big enough to hold (512 * NumSectors) bytes.
+*
+* @return
+*
+* - XST_SUCCESS if the read was successful. In interrupt mode, this does not
+*   mean the read is complete, only that it has begun. An event is returned
+*   to the user when the read is complete.
+* - XST_SYSACE_NO_LOCK if no MPU lock has yet been granted
+* - XST_DEVICE_BUSY if the ACE controller is not ready for a command
+* - XST_FAILURE if an error occurred during the read. The user should call
+*   XSysAce_GetErrors() to determine the cause of the error.
+*
+* @note
+*
+* None.
+*
+* @internal
+*
+* Polled mode is blocking under the assumption that a single sector can be
+* transferred at a very fast rate (>20 Mbps).  So, the user can choose to
+* transfer only single sectors when in polled mode, thus allowing time for
+* other work to be done. The biggest issue is that although data transfer
+* rates are high, seek time for CompactFlash cards is slow (5-20 ms on
+* average, depending on the type of device). We could move to a non-blocking
+* solution that transfers 32 bytes at a time (the entire data buffer) and
+* then returns. The user would then need to increment its buffer pointer
+* appropriately and call the read/write again. The driver would need some way
+* to know not to issue a new command to the CompactFlash, but instead continue
+* with the previous command.  This can be done either with a NumSectors argument
+* of zero to indicate that there is already an operation in progress, or by
+* having the driver keep state to know there is an operation in progress. The
+* interface for either seems a bit awkward. Also, the hit for seek time needs
+* to be taken regardless of the blocking or non-blocking nature of the call, so
+* the additional few microseconds to transfer a sector of data seems acceptable.
+*
+******************************************************************************/
+XStatus XSysAce_SectorRead(XSysAce *InstancePtr, u32 StartSector,
+                           int NumSectors, u8 *BufferPtr)
+{
+    u16 SectorCmd;
+    int BytesToRecv;
+
+    XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(NumSectors > 0 && NumSectors <= (XSA_SCCR_COUNT_MASK + 1));
+    XASSERT_NONVOID(BufferPtr != NULL);
+    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+   /* If a lock has not been granted, return an error */
+    if (!XSysAce_mIsMpuLocked(InstancePtr->BaseAddress))
+    {
+        return XST_SYSACE_NO_LOCK;
+    }
+
+    /* See if the CF is ready for a command */
+    if (!XSysAce_mIsReadyForCmd(InstancePtr->BaseAddress))
+    {
+        return XST_DEVICE_BUSY;
+    }
+
+    BytesToRecv = XSA_CF_SECTOR_SIZE * NumSectors;
+
+    /*
+     * If in interrupt mode, set up the state variables and enable the
+     * data-buffer-ready interrupt. This needs to be done before the command
+     * is sent to the ACE, which will cause the interrupt to occur.
+     */
+    if (XSysAce_mIsIntrEnabled(InstancePtr->BaseAddress))
+    {
+        InstancePtr->NumRequested = BytesToRecv;
+        InstancePtr->NumRemaining = BytesToRecv;
+        InstancePtr->BufferPtr = BufferPtr;
+
+        XSysAce_mOrControlReg(InstancePtr->BaseAddress, XSA_CR_DATARDYIRQ_MASK);
+    }
+
+    /* Write the sector ID (LBA) */
+    XSysAce_RegWrite32(InstancePtr->BaseAddress + XSA_MLR_OFFSET, StartSector);
+
+    /*
+     * Send the read command for the number of sectors specified
+     */
+    SectorCmd = (NumSectors & XSA_SCCR_COUNT_MASK) | XSA_SCCR_READDATA_MASK;
+    XSysAce_RegWrite16(InstancePtr->BaseAddress + XSA_SCCR_OFFSET, SectorCmd);
+
+    /*
+     * If in polled mode, receive the entire amount requested
+     */
+    if (!XSysAce_mIsIntrEnabled(InstancePtr->BaseAddress))
+    {
+        int NumRead;
+
+        NumRead = XSysAce_ReadDataBuffer(InstancePtr->BaseAddress, BufferPtr,
+                                         BytesToRecv);
+        if (NumRead != BytesToRecv)
+        {
+            /* an error occurred, report this to the user */
+            return XST_FAILURE;
+        }
+    }
+
+    return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Write data to the CompactFlash. The user specifies the starting sector ID
+* and the number of sectors to be written. The minimum unit that can be written
+* to the CompactFlash is a sector, which is 512 bytes.
+*
+* In polled mode, this write is blocking. If there are other tasks in the
+* system that must run, it is best to keep the number of sectors to be written
+* to a minimum (e.g., 1). In interrupt mode, this write is non-blocking and an
+* event, XSA_EVENT_DATA_DONE, is returned to the user in the asynchronous
+* event handler when the write is complete. The user must call
+* XSysAce_EnableInterrupt() to put the driver/device into interrupt mode.
+*
+* An MPU lock, obtained using XSysAce_Lock(), must be granted before calling
+* this function. If a lock has not been granted, no action is taken and an
+* error is returned.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+* @param StartSector is the starting sector ID from where data will be written.
+*        Sector IDs range from 0 (first sector) to 0x10000000.
+* @param NumSectors is the number of sectors to write. The range can be from
+*        1 to 256.
+* @param BufferPtr is a pointer to the data buffer to be written. This buffer
+*        must have at least (512 * NumSectors) bytes.
+*
+* @return
+*
+* - XST_SUCCESS if the write was successful. In interrupt mode, this does not
+*   mean the write is complete, only that it has begun. An event is returned
+*   to the user when the write is complete.
+* - XST_SYSACE_NO_LOCK if no MPU lock has yet been granted
+* - XST_DEVICE_BUSY if the ACE controller is not ready for a command
+* - XST_FAILURE if an error occurred during the write. The user should call
+*   XSysAce_GetErrors() to determine the cause of the error.
+*
+* @note
+*
+* None.
+*
+* @internal
+*
+* Polled mode is blocking under the assumption that a single sector can be
+* transferred at a very fast rate (>20 Mbps).  So, the user can choose to
+* transfer only single sectors when in polled mode, thus allowing time for
+* other work to be done. The biggest issue is that although data transfer
+* rates are high, seek time for CompactFlash cards is slow (5-20 ms on
+* average, depending on the type of device). We could move to a non-blocking
+* solution that transfers 32 bytes at a time (the entire data buffer) and
+* then returns. The user would then need to increment its buffer pointer
+* appropriately and call the read/write again. The driver would need some way
+* to know not to issue a new command to the CompactFlash, but instead continue
+* with the previous command.  This can be done either with a NumSectors argument
+* of zero to indicate that there is already an operation in progress, or by
+* having the driver keep state to know there is an operation in progress. The
+* interface for either seems a bit awkward. Also, the hit for seek time needs
+* to be taken regardless of the blocking or non-blocking nature of the call, so
+* the additional few microseconds to transfer a sector of data seems acceptable.
+*
+******************************************************************************/
+XStatus XSysAce_SectorWrite(XSysAce *InstancePtr, u32 StartSector,
+                            int NumSectors, u8 *BufferPtr)
+{
+    u16 SectorCmd;
+    int NumSent;
+    int BytesToSend;
+
+    XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(NumSectors > 0 && NumSectors <= (XSA_SCCR_COUNT_MASK + 1));
+    XASSERT_NONVOID(BufferPtr != NULL);
+    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+   /* If a lock has not been granted, return an error */
+    if (!XSysAce_mIsMpuLocked(InstancePtr->BaseAddress))
+    {
+        return XST_SYSACE_NO_LOCK;
+    }
+
+    /* See if the CF is ready for a command */
+    if (!XSysAce_mIsReadyForCmd(InstancePtr->BaseAddress))
+    {
+        return XST_DEVICE_BUSY;
+    }
+
+    /* Write the sector ID (LBA) */
+    XSysAce_RegWrite32(InstancePtr->BaseAddress + XSA_MLR_OFFSET, StartSector);
+
+    /*
+     * Send the write command for the number of sectors specified
+     */
+    SectorCmd = (NumSectors & XSA_SCCR_COUNT_MASK) | XSA_SCCR_WRITEDATA_MASK;
+    XSysAce_RegWrite16(InstancePtr->BaseAddress + XSA_SCCR_OFFSET, SectorCmd);
+
+    BytesToSend = XSA_CF_SECTOR_SIZE * NumSectors;
+
+    /*
+     * If in interrupt mode, set up the state variables and enable the
+     * data-buffer-ready interrupt. We do this after the write command above
+     * is done in order to guarantee that the interrupt occurs only after the
+     * first data buffer write is done below (an interrupt may or may not occur
+     * after the write command is issued)
+     */
+    if (XSysAce_mIsIntrEnabled(InstancePtr->BaseAddress))
+    {
+        /*
+         * Set the state variables. We're going to send one data buffer here in
+         * this routine, so adjust the buffer pointer and number remaining to
+         * reflect this.
+         */
+        InstancePtr->NumRequested = BytesToSend;
+        InstancePtr->NumRemaining = BytesToSend - XSA_DATA_BUFFER_SIZE;
+        InstancePtr->BufferPtr = BufferPtr + XSA_DATA_BUFFER_SIZE;
+
+        /* Send only one data buffer in interrupt mode */
+        BytesToSend = XSA_DATA_BUFFER_SIZE;
+
+        XSysAce_mOrControlReg(InstancePtr->BaseAddress, XSA_CR_DATARDYIRQ_MASK);
+    }
+
+    NumSent = XSysAce_WriteDataBuffer(InstancePtr->BaseAddress, BufferPtr,
+                                      BytesToSend);
+    if (NumSent != BytesToSend)
+    {
+        /* an error occurred, report this to the user */
+        return XST_FAILURE;
+    }
+
+    return XST_SUCCESS;
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Get the status of the FAT filesystem on the first valid partition of the
+* CompactFlash device such as the boot record and FAT types found.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+*
+* @return
+*
+* A 16-bit mask of status values. These values are defined in xsysace_l.h
+* with the prefix XSA_FAT_*.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u16 XSysAce_GetFatStatus(XSysAce *InstancePtr)
+{
+    XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    return XSysAce_RegRead16(InstancePtr->BaseAddress + XSA_FSR_OFFSET);
+}
+
+/*****************************************************************************/
+/**
+*
+* This bit of ugliness allows us to present a structure to the user. The
+* byte buffer which was read from the CompactFlash is converted into the
+* XSysAce_CFParameters structure. The byte buffer is accessed by the indices
+* of the fields as defined at the top of this file. We do not read from
+* CompactFlash directly into the CF Parameter structure because of structure
+* packing problems.
+*
+* Note that we also need to perform endian conversion here since the System
+* ACE device gives us little endian data and we're (possibly) on a big endian
+* processor.
+*
+* @param ParamPtr is the structure to fill
+* @param BufPtr is the byte buffer containing the CF parameter data
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void FillParam(XSysAce_CFParameters *ParamPtr, u8 *BufPtr)
+{
+    u16 HiWord;
+    u16 LoWord;
+
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_SIGNATURE]),
+                        &ParamPtr->Signature);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_NUMCYLS]),
+                        &ParamPtr->NumCylinders);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_RESERVED1]),
+                        &ParamPtr->Reserved);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_NUMHEADS]),
+                        &ParamPtr->NumHeads);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_BYTES_TRACK]),
+                        &ParamPtr->NumBytesPerTrack);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_BYTES_SECT]),
+                        &ParamPtr->NumBytesPerSector);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_SECTS_TRK]),
+                        &ParamPtr->NumSectorsPerTrack);
+
+    /* NumSectorsPerCard is stored as two half-words, MSW first */
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_SECTS_HI]),
+                        &HiWord);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_SECTS_LO]),
+                        &LoWord);
+    ParamPtr->NumSectorsPerCard = ((u32)HiWord << 16) | (u32)LoWord;
+
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_VENDOR1]),
+                        &ParamPtr->VendorUnique);
+
+    ByteCopy(&BufPtr[XSA_CFPARM_SERIAL_NO], ParamPtr->SerialNo, 20);
+
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_BUFFER_TYPE]),
+                        &ParamPtr->BufferType);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_BUFFER_SIZE]),
+                        &ParamPtr->BufferSize);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_ECC_BYTES]),
+                        &ParamPtr->NumEccBytes);
+
+    ByteCopy(&BufPtr[XSA_CFPARM_FW_VERSION], ParamPtr->FwVersion, 8);
+    ByteCopy(&BufPtr[XSA_CFPARM_MODEL_NO], ParamPtr->ModelNo, 40);
+
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_MAX_SECTORS]),
+                        &ParamPtr->MaxSectors);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_DBL_WORD]),
+                        &ParamPtr->DblWord);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_CAPS]),
+                        &ParamPtr->Capabilities);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_RESERVED2]),
+                        &ParamPtr->Reserved2);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_PIO_MODE]),
+                        &ParamPtr->PioMode);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_DMA_MODE]),
+                        &ParamPtr->DmaMode);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_TRANSLATE]),
+                        &ParamPtr->TranslationValid);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_CURCYLS]),
+                        &ParamPtr->CurNumCylinders);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_CURHEADS]),
+                        &ParamPtr->CurNumHeads);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_CURSECTS_TRK]),
+                        &ParamPtr->CurSectorsPerTrack);
+    XIo_FromLittleEndian32(*((u32 *)&BufPtr[XSA_CFPARM_CURSECTS]),
+                        &ParamPtr->CurSectorsPerCard);
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_MULTIPLE]),
+                        &ParamPtr->MultipleSectors);
+    XIo_FromLittleEndian32(*((u32 *)&BufPtr[XSA_CFPARM_LBA_SECTS]),
+                        &ParamPtr->LbaSectors);
+
+    ByteCopy(&BufPtr[XSA_CFPARM_RESERVED3], ParamPtr->Reserved3, 132);
+
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_SECURITY]),
+                        &ParamPtr->SecurityStatus);
+
+    ByteCopy(&BufPtr[XSA_CFPARM_VENDOR2], ParamPtr->VendorUniqueBytes, 62);
+
+    XIo_FromLittleEndian16(*((u16 *)&BufPtr[XSA_CFPARM_POWER]),
+                        &ParamPtr->PowerDesc);
+
+    ByteCopy(&BufPtr[XSA_CFPARM_RESERVED4], ParamPtr->Reserved4, 190);
+
+}
+
+/*****************************************************************************/
+/**
+*
+* Utility to copy bytes.
+*
+* @param SourcePtr is a pointer to the source byte buffer
+* @param DestPtr is a pointer to the destination byte buffer
+* @param NumBytes is the number of bytes to copy
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void ByteCopy(u8 *SourcePtr, u8 *DestPtr, int NumBytes)
+{
+    int i;
+
+    for (i=0; i < NumBytes; i++)
+    {
+        DestPtr[i] = SourcePtr[i];
+    }
+}
+
diff -urN linux-2.4.29/drivers/block/xilinx_sysace/xsysace_g.c linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace_g.c
--- linux-2.4.29/drivers/block/xilinx_sysace/xsysace_g.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace_g.c	2005-06-14 02:11:55.000000000 +0100
@@ -0,0 +1,27 @@
+
+/*******************************************************************
+*
+* CAUTION: This file is automatically generated by libgen.
+* Version: Xilinx EDK 3.2.2 EDK_Cm.22
+* DO NOT EDIT.
+*
+* Copyright (c) 2003 Xilinx, Inc.  All rights reserved. 
+* 
+* Description: Driver configuration
+*
+*******************************************************************/
+
+//#include <asm/xparameters.h>
+#include "xsysace.h"
+
+/*
+* The configuration table for devices
+*/
+
+XSysAce_Config XSysAce_ConfigTable[] =
+{
+	{
+		0,
+		CONFIG_XILINX_SYSACE_0_BASEADDR
+	}
+};
diff -urN linux-2.4.29/drivers/block/xilinx_sysace/xsysace.h linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace.h
--- linux-2.4.29/drivers/block/xilinx_sysace/xsysace.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace.h	2005-06-14 02:11:55.000000000 +0100
@@ -0,0 +1,320 @@
+/* $Id: xsysace.h,v 1.8 2002/11/04 23:44:21 moleres Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xsysace.h
+*
+* The Xilinx System ACE driver. This driver supports the Xilinx System Advanced
+* Configuration Environment (ACE) controller. It currently supports only the
+* CompactFlash solution. The driver makes use of the Microprocessor (MPU)
+* interface to communicate with the device.
+*
+* The driver provides a user the ability to access the CompactFlash through
+* the System ACE device.  The user can read and write CompactFlash sectors,
+* identify the flash device, and reset the flash device.  Also, the driver
+* provides a user the ability to configure FPGA devices by selecting a
+* configuration file (.ace file) resident on the CompactFlash, or directly
+* configuring the FPGA devices via the MPU port and the configuration JTAG
+* port of the controller.
+*
+* <b>Bus Mode</b>
+*
+* The System ACE device supports both 8-bit and 16-bit access to its registers.
+* The driver defaults to 8-bit access, but can be changed to use 16-bit access
+* at compile-time.  The compile-time constant XPAR_XSYSACE_MEM_WIDTH must be
+* defined equal to 16 to make the driver use 16-bit access. This constant is
+* typically defined in xparameters.h.
+*
+* <b>Endianness</b>
+*
+* The System ACE device is little-endian. If being accessed by a big-endian
+* processor, the endian conversion will be done by the device driver. The
+* endian conversion is encapsulated inside the XSysAce_RegRead/Write functions
+* so that it can be removed if the endian conversion is moved to hardware.
+*
+* <b>Hardware Access</b>
+*
+* The device driver expects the System ACE controller to be a memory-mapped
+* device. Access to the System ACE controller is typically achieved through
+* the External Memory Controller (EMC) IP core. The EMC is simply a pass-through
+* device that allows access to the off-chip System ACE device. There is no
+* software-based setup or configuration necessary for the EMC.
+*
+* The System ACE registers are expected to be byte-addressable. If for some
+* reason this is not possible, the register offsets defined in xsysace_l.h must
+* be changed accordingly.
+*
+* <b>Reading or Writing CompactFlash</b>
+*
+* The smallest unit that can be read from or written to CompactFlash is one
+* sector. A sector is 512 bytes.  The functions provided by this driver allow
+* the user to specify a starting sector ID and the number of sectors to be read
+* or written. At most 256 sectors can be read or written in one operation. The
+* user must ensure that the buffer passed to the functions is big enough to
+* hold (512 * NumSectors), where NumSectors is the number of sectors specified.
+*
+* <b>Interrupt Mode</b>
+*
+* By default, the device and driver are in polled mode. The user is required to
+* enable interrupts using XSysAce_EnableInterrupt(). In order to use interrupts,
+* it is necessary for the user to connect the driver's interrupt handler,
+* XSysAce_InterruptHandler(), to the interrupt system of the application. This
+* function does not save and restore the processor context. An event handler
+* must also be set by the user, using XSysAce_SetEventHandler(), for the driver
+* such that the handler is called when interrupt events occur. The handler is
+* called from interrupt context and allows application-specific processing to
+* be performed.
+*
+* In interrupt mode, the only available interrupt is data buffer ready, so
+* the size of a data transfer between interrupts is 32 bytes (the size of the
+* data buffer).
+*
+* <b>Polled Mode</b>
+*
+* The sector read and write functions are blocking when in polled mode. This
+* choice was made over non-blocking since sector transfer rates are high
+* (>20Mbps) and the user can limit the number of sectors transferred in a single
+* operation to 1 when in polled mode, plus the API for non-blocking polled
+* functions was a bit awkward. Below is some more information on the sector
+* transfer rates given the current state of technology (year 2002). Although
+* the seek times for CompactFlash cards is high, this average hit needs to be
+* taken every time a new read/write operation is invoked by the user. So the
+* additional few microseconds to transfer an entire sector along with seeking
+* is miniscule.
+*
+* - Microdrives are slower than CompactFlash cards by a significant factor,
+*   especially if the MD is asleep.
+*     - Microdrive:
+*           - Power-up/wake-up time is approx. 150 to 1000 ms.
+*           - Average seek time is approx. 15 to 20 ms.
+*     - CompactFlash:
+*           - Power-up/reset time is approx. 50 to 400 ms and wake-up time is
+*             approx. 3 ms.
+*           - "Seek time" here means how long it takes the internal controller
+*             to process the command until the sector data is ready for transfer
+*             by the ACE controller.  This time is approx. 2 ms per sector.
+*
+*  - Once the sector data is ready in the CF device buffer (i.e., "seek time" is
+*    over) the ACE controller can read 2 bytes from the MD/CF device every 11
+*    clock cycles, assuming no wait cycles happen.  For instance, if the clock
+*    is 33 MHz, then then the max. rate that the ACE controller can transfer is
+*    6 MB/sec.  However, due to other overhead (e.g., time for data buffer
+*    transfers over MPU port, etc.), a better estimate is 3-5 MB/sec.
+*
+* <b>Mutual Exclusion</b>
+*
+* This driver is not thread-safe. The System ACE device has a single data
+* buffer and therefore only one operation can be active at a time. The device
+* driver does not prevent the user from starting an operation while a previous
+* operation is still in progress. It is up to the user to provide this mutual
+* exclusion.
+*
+* <b>Errors</b>
+*
+* Error causes are defined in xsysace_l.h using the prefix XSA_ER_*. The
+* user can use XSysAce_GetErrors() to retrieve all outstanding errors.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  06/17/02 work in progress
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XSYSACE_H /* prevent circular inclusions */
+#define XSYSACE_H /* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xsysace_l.h"
+
+/************************** Constant Definitions *****************************/
+
+/** @name Asynchronous Events
+ *
+ * Asynchronous events passed to the event handler when in interrupt mode.
+ *
+ * Note that when an error event occurs, the only way to clear this condition
+ * is to reset the CompactFlash or the System ACE configuration controller,
+ * depending on where the error occurred. The driver does not reset either
+ * and leaves this task to the user.
+ * @{
+ */
+#define XSA_EVENT_CFG_DONE  1  /**< Configuration of JTAG chain is done */
+#define XSA_EVENT_DATA_DONE 2  /**< Data transfer to/from CompactFlash is done */
+#define XSA_EVENT_ERROR     3  /**< An error occurred. Use XSysAce_GetErrors()
+                                *   to determine the cause of the error(s).
+                                */
+/*@}*/
+
+
+/**************************** Type Definitions *******************************/
+
+/**
+ * Typedef for CompactFlash identify drive parameters. Use XSysAce_IdentifyCF()
+ * to retrieve this information from the CompactFlash storage device.
+ */
+typedef struct
+{
+    u16 Signature;          /**< CompactFlash signature is 0x848a */
+    u16 NumCylinders;       /**< Default number of cylinders */
+    u16 Reserved;
+    u16 NumHeads;           /**< Default number of heads */
+    u16 NumBytesPerTrack;   /**< Number of unformatted bytes per track */
+    u16 NumBytesPerSector;  /**< Number of unformatted bytes per sector */
+    u16 NumSectorsPerTrack; /**< Default number of sectors per track */
+    u32 NumSectorsPerCard;  /**< Default number of sectors per card */
+    u16 VendorUnique;       /**< Vendor unique */
+    u8 SerialNo[20];        /**< ASCII serial number */
+    u16 BufferType;         /**< Buffer type */
+    u16 BufferSize;         /**< Buffer size in 512-byte increments */
+    u16 NumEccBytes;        /**< Number of ECC bytes on R/W Long cmds */
+    u8 FwVersion[8];        /**< ASCII firmware version */
+    u8 ModelNo[40];         /**< ASCII model number */
+    u16 MaxSectors;         /**< Max sectors on R/W Multiple cmds */
+    u16 DblWord;            /**< Double Word not supported */
+    u16 Capabilities;       /**< Device capabilities */
+    u16 Reserved2;
+    u16 PioMode;            /**< PIO data transfer cycle timing mode */
+    u16 DmaMode;            /**< DMA data transfer cycle timing mode */
+    u16 TranslationValid;   /**< Translation parameters are valid */
+    u16 CurNumCylinders;    /**< Current number of cylinders */
+    u16 CurNumHeads;        /**< Current number of heads */
+    u16 CurSectorsPerTrack; /**< Current number of sectors per track */
+    u32 CurSectorsPerCard;  /**< Current capacity in sectors */
+    u16 MultipleSectors;    /**< Multiple sector setting */
+    u32 LbaSectors;         /**< Number of addressable sectors in LBA mode */
+    u8 Reserved3[132];
+    u16 SecurityStatus;     /**< Security status */
+    u8 VendorUniqueBytes[62]; /**< Vendor unique bytes */
+    u16 PowerDesc;          /**< Power requirement description */
+    u8 Reserved4[190];
+
+} XSysAce_CFParameters;
+
+
+/**
+ * Callback when an asynchronous event occurs during interrupt mode.
+ *
+ * @param CallBackRef is a callback reference passed in by the upper layer
+ *        when setting the callback functions, and passed back to the upper
+ *        layer when the callback is invoked.
+ * @param Event is the event that occurred.  See xsysace.h and the event
+ *        identifiers prefixed with XSA_EVENT_* for a description of possible
+ *        events.
+ */
+typedef void (*XSysAce_EventHandler)(void *CallBackRef, int Event);
+
+/**
+ * This typedef contains configuration information for the device.
+ */
+typedef struct
+{
+    u16 DeviceId;       /**< Unique ID  of device */
+    u32 BaseAddress;    /**< Register base address */
+
+} XSysAce_Config;
+
+/**
+ * The XSysAce driver instance data. The user is required to allocate a
+ * variable of this type for every System ACE device in the system. A
+ * pointer to a variable of this type is then passed to the driver API
+ * functions.
+ */
+typedef struct
+{
+    u32 BaseAddress;                /* Base address of ACE device */
+    u32 IsReady;                    /* Device is initialized and ready */
+
+    /* interrupt-related data */
+    int NumRequested;                   /* Number of bytes to read/write */
+    int NumRemaining;                   /* Number of bytes left to read/write */
+    u8 *BufferPtr;                  /* Buffer being read/written */
+    XSysAce_EventHandler EventHandler;  /* Callback for asynchronous events */
+    void *EventRef;                     /* Callback reference */
+
+} XSysAce;
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+/*
+ * Required functions in xsysace.c
+ */
+XStatus XSysAce_Initialize(XSysAce *InstancePtr, u16 DeviceId);
+XStatus XSysAce_Lock(XSysAce *InstancePtr, u32 Force);
+void XSysAce_Unlock(XSysAce *InstancePtr);
+u32 XSysAce_GetErrors(XSysAce *InstancePtr);
+XSysAce_Config *XSysAce_LookupConfig(u16 DeviceId);
+
+/*
+ * CompactFlash access functions in xsysace_compactflash.c
+ */
+XStatus XSysAce_ResetCF(XSysAce *InstancePtr);
+XStatus XSysAce_AbortCF(XSysAce *InstancePtr);
+XStatus XSysAce_IdentifyCF(XSysAce *InstancePtr,
+                           XSysAce_CFParameters *ParamPtr);
+u32 XSysAce_IsCFReady(XSysAce *InstancePtr);
+XStatus XSysAce_SectorRead(XSysAce *InstancePtr, u32 StartSector,
+                           int NumSectors, u8 *BufferPtr);
+XStatus XSysAce_SectorWrite(XSysAce *InstancePtr, u32 StartSector,
+                            int NumSectors, u8 *BufferPtr);
+u16 XSysAce_GetFatStatus(XSysAce *InstancePtr);
+
+/*
+ * JTAG configuration interface functions in xsysace_jtagcfg.c
+ */
+void XSysAce_ResetCfg(XSysAce *InstancePtr);
+void XSysAce_SetCfgAddr(XSysAce *InstancePtr, unsigned int Address);
+void XSysAce_SetStartMode(XSysAce *InstancePtr, u32 ImmedOnReset,
+                          u32 SetStart);
+u32 XSysAce_IsCfgDone(XSysAce *InstancePtr);
+u32 XSysAce_GetCfgSector(XSysAce *InstancePtr);
+XStatus XSysAce_ProgramChain(XSysAce *InstancePtr, u8 *BufferPtr, int NumBytes);
+
+/*
+ * General interrupt-related functions in xsysace_intr.c
+ */
+void XSysAce_EnableInterrupt(XSysAce *InstancePtr);
+void XSysAce_DisableInterrupt(XSysAce *InstancePtr);
+void XSysAce_SetEventHandler(XSysAce *InstancePtr, XSysAce_EventHandler FuncPtr,
+                             void *CallBackRef);
+void XSysAce_InterruptHandler(void *InstancePtr);      /* interrupt handler */
+
+/*
+ * Diagnostic functions in xsysace_selftest.c
+ */
+XStatus XSysAce_SelfTest(XSysAce *InstancePtr);
+u16 XSysAce_GetVersion(XSysAce *InstancePtr);
+
+
+#endif            /* end of protection macro */
+
diff -urN linux-2.4.29/drivers/block/xilinx_sysace/xsysace_intr.c linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace_intr.c
--- linux-2.4.29/drivers/block/xilinx_sysace/xsysace_intr.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace_intr.c	2005-06-14 02:11:55.000000000 +0100
@@ -0,0 +1,418 @@
+/* $Id: xsysace_intr.c,v 1.5 2002/07/22 20:44:34 moleres Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xsysace_intr.c
+*
+* Contains functions related to System ACE interrupt mode. The driver's
+* interrupt handler, XSysAce_InterruptHandler(), must be connected by the
+* user to the interrupt controller.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  06/17/02 work in progress
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xsysace.h"
+#include "xsysace_l.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/************************** Function Prototypes ******************************/
+
+static void HandleDataBuffer(XSysAce *InstancePtr, u32 StatusReg);
+static void DataComplete(XSysAce *InstancePtr);
+
+
+/*****************************************************************************/
+/**
+*
+* Enable System ACE interrupts. There are three interrupts that can be enabled.
+* The error interrupt enable serves as the driver's means to determine whether
+* interrupts have been enabled or not. The configuration-done interrupt is not
+* enabled here, instead it is enabled during a reset - which can cause a
+* configuration process to start. The data-buffer-ready interrupt is not enabled
+* here either. It is enabled when a read or write operation is started. The
+* reason for not enabling the latter two interrupts are because the status bits
+* may be set as a leftover of an earlier occurrence of the interrupt.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to work on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XSysAce_EnableInterrupt(XSysAce *InstancePtr)
+{
+    XASSERT_VOID(InstancePtr != NULL);
+    XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    /* By default, enable only the error interrupt */
+    XSysAce_mOrControlReg(InstancePtr->BaseAddress, XSA_CR_ERRORIRQ_MASK);
+
+    /* Clear the reset on the interrupt line if it was in reset */
+    XSysAce_mAndControlReg(InstancePtr->BaseAddress, ~XSA_CR_RESETIRQ_MASK);
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Disable all System ACE interrupts and hold the interrupt request line of
+* the device in reset.
+*
+* @param InstancePtr is a pointer to the XSysAce instance that just interrupted.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XSysAce_DisableInterrupt(XSysAce *InstancePtr)
+{
+    XASSERT_VOID(InstancePtr != NULL);
+    XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    /* Put the interrupt request line in reset */
+    XSysAce_mOrControlReg(InstancePtr->BaseAddress, XSA_CR_RESETIRQ_MASK);
+
+    /* Clear the interrupt enable bits */
+    XSysAce_mAndControlReg(InstancePtr->BaseAddress, ~(XSA_CR_DATARDYIRQ_MASK |
+                           XSA_CR_ERRORIRQ_MASK | XSA_CR_CFGDONEIRQ_MASK));
+}
+
+
+/*****************************************************************************/
+/**
+*
+* The interrupt handler for the System ACE driver. This handler must be
+* connected by the user to an interrupt controller or source. This function
+* does not save or restore context.
+*
+* This function continues reading or writing to the compact flash if such an
+* operation is in progress, and notifies the upper layer software through
+* the event handler once the operation is complete or an error occurs. On an
+* error, any command currently in progress is aborted.
+*
+* @param InstancePtr is a pointer to the XSysAce instance that just interrupted.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XSysAce_InterruptHandler(void *InstancePtr)
+{
+    u32 StatusReg;
+    XSysAce *AcePtr = (XSysAce *)InstancePtr;
+
+    XASSERT_VOID(InstancePtr != NULL);
+
+    /*
+     * Get the status in order to process each interrupt that has occurred
+     */
+    StatusReg = XSysAce_mGetStatusReg(AcePtr->BaseAddress);
+
+    /*
+     * Reset the interrupt line to effectively clear the interrupt conditions.
+     * We need to set the bit to clear the interrupts, then clear the bit so
+     * that new interrupts can be generated.
+     */
+    XSysAce_mOrControlReg(AcePtr->BaseAddress, XSA_CR_RESETIRQ_MASK);
+    XSysAce_mAndControlReg(AcePtr->BaseAddress, ~XSA_CR_RESETIRQ_MASK);
+
+    /*
+     * Check for data buffer ready, which means an operation (either read or
+     * write) is in progress.
+     */
+    if (StatusReg & XSA_SR_DATABUFRDY_MASK)
+    {
+        /*
+         * Handles the data buffer, and invokes the callback to the user for
+         * data transfer completion.
+         */
+        HandleDataBuffer(AcePtr, StatusReg);
+    }
+
+    /*
+     * Check for completion of JTAG configuration and report the event up.
+     * We only do this if the CFGDONE interrupt is enabled since the CFGDONE
+     * status only gets cleared when the confguration controller is reset,
+     * which we do not do unless requested by the user because it may cause
+     * a configuration process to start. We could have gotten into this
+     * interrupt handler by another interrupt, yet have a leftover CFGDONE
+     * status from an earlier configuration process.
+     */
+    if ((StatusReg & XSA_SR_CFGDONE_MASK) &&
+        (XSysAce_mGetControlReg(AcePtr->BaseAddress) & XSA_CR_CFGDONEIRQ_MASK))
+    {
+        /*
+         * Clear the bit indicating MPU is the source of configuration data
+         * since we're done configuring from the MPU for now. Also clear the
+         * force CFGMODE bit and the CFGSTART bit, basically undoing what was
+         * done in XSysAce_ProgramChain(). Disable the interrupts since the
+         * CFGDONE status does not get cleared unless a reset occurs - and in
+         * the meantime we may get into this interrupt handler again.
+         */
+        XSysAce_mAndControlReg(AcePtr->BaseAddress, ~(XSA_CR_CFGSEL_MASK |
+                           XSA_CR_CFGSTART_MASK | XSA_CR_CFGDONEIRQ_MASK |
+                           XSA_CR_DATARDYIRQ_MASK | XSA_CR_FORCECFGMODE_MASK));
+
+        AcePtr->EventHandler(AcePtr->EventRef, XSA_EVENT_CFG_DONE);
+    }
+
+    /*
+     * Check for errors and report the event (the user is responsible for
+     * retrieving and interpreting the errors). We only do this if the error
+     * interrupt is enabled since the error status only gets cleared when the
+     * CompactFlash or confguration controller is reset, which we do not do
+     * because it may cause a configuration process to start. We could have
+     * entered this interrupt handler by another interrupt and have a leftover
+     * error status from a previous error.
+     */
+    if ((StatusReg & (XSA_SR_CFGERROR_MASK | XSA_SR_CFCERROR_MASK)) &&
+        (XSysAce_mGetControlReg(AcePtr->BaseAddress) & XSA_CR_ERRORIRQ_MASK))
+    {
+        /* Clear the transfer state to effectively abort the operation */
+        AcePtr->NumRequested = 0;
+        AcePtr->NumRemaining = 0;
+        AcePtr->BufferPtr = NULL;
+
+        /*
+         * Disable the error interrupt since the only way to clear the
+         * error status is to reset the CF or the configuration controller,
+         * neither of which we want to do here since the consequences may
+         * be undesirable (i.e., may cause a reconfiguration). The user
+         * will need to perform the reset based on the error event.
+         */
+        XSysAce_mAndControlReg(AcePtr->BaseAddress, ~XSA_CR_ERRORIRQ_MASK);
+
+        AcePtr->EventHandler(AcePtr->EventRef, XSA_EVENT_ERROR);
+    }
+}
+
+/*****************************************************************************/
+/**
+*
+* Set the callback function for handling events. The upper layer software
+* should call this function during initialization. The events are passed
+* asynchronously to the upper layer software. The events are described in
+* xsysace.h and are named XSA_EVENT_*.
+*
+* Note that the callback is invoked by the driver within interrupt context, so
+* it needs to do its job quickly. If there are potentially slow operations
+* within the callback, these should be done at task-level.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+* @param FuncPtr is the pointer to the callback function.
+* @param CallBackRef is a reference pointer to be passed back to the upper
+*        layer.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XSysAce_SetEventHandler(XSysAce *InstancePtr, XSysAce_EventHandler FuncPtr,
+                             void *CallBackRef)
+{
+    XASSERT_VOID(InstancePtr != NULL);
+    XASSERT_VOID(FuncPtr != NULL);
+    XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    InstancePtr->EventHandler = FuncPtr;
+    InstancePtr->EventRef = CallBackRef;
+}
+
+/*****************************************************************************/
+/**
+*
+* Handle a data-buffer-ready interrupt. If we get the interrupt when reading,
+* it means there is still data to read since the interrupt does not occur after
+* reading the last data buffer. If we get the interrupt when writing, there
+* may or may not be data left to write since the interrupt does occur after the
+* last data buffer is written.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+* @param StatusReg is the contents of the status register, read at the start
+*        of the interrupt service routine.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void HandleDataBuffer(XSysAce *InstancePtr, u32 StatusReg)
+{
+    /* By default, transfer a whole data buffer */
+    int BytesToTransfer = XSA_DATA_BUFFER_SIZE;
+
+    /*
+     * Check to see if number of bytes remaining is less than the data buffer
+     * size. If it is, we need to adjust the remaining bytes to transfer.
+     */
+    if (InstancePtr->NumRemaining < XSA_DATA_BUFFER_SIZE)
+    {
+        BytesToTransfer = InstancePtr->NumRemaining;
+    }
+
+    /*
+     * Transfer only one data buffer at a time, which is 32 bytes. Note that
+     * errors will be handled by an error interrupt occurring, so no need to
+     * check for them here.
+     */
+    if (StatusReg & XSA_SR_DATABUFMODE_MASK)
+    {
+        /*
+         * A write operation in progress, so if there is data remaining then
+         * write the buffer. If no data is remaining, clean up.
+         */
+        if (InstancePtr->NumRemaining > 0)
+        {
+            (void)XSysAce_WriteDataBuffer(InstancePtr->BaseAddress,
+                                          InstancePtr->BufferPtr,
+                                          BytesToTransfer);
+
+            /*
+             * Decrement the number of bytes remaining to be transferred and
+             * adjust the buffer pointer appropriately.
+             */
+            InstancePtr->NumRemaining -= BytesToTransfer;
+            InstancePtr->BufferPtr += BytesToTransfer;
+        }
+        else
+        {
+            /* Done writing data, so clean up */
+            DataComplete(InstancePtr);
+        }
+    }
+    else
+    {
+        /* A read operation in progress, so read the buffer */
+        (void)XSysAce_ReadDataBuffer(InstancePtr->BaseAddress,
+                                     InstancePtr->BufferPtr,
+                                     BytesToTransfer);
+
+        /*
+         * Decrement the number of bytes remaining to be transferred and
+         * adjust the buffer pointer appropriately. If it was the last buffer,
+         * we're done and we can cleanup.
+         */
+        InstancePtr->NumRemaining -= BytesToTransfer;
+        InstancePtr->BufferPtr += BytesToTransfer;
+
+        if (InstancePtr->NumRemaining == 0)
+        {
+            /* Done reading data, so clean up */
+            DataComplete(InstancePtr);
+        }
+    }
+}
+
+/*****************************************************************************/
+/**
+*
+* Handle cleanup when a data transfer is complete. This means intializing the
+* state variables, disabling the data-buffer-ready interrupt, and sending the
+* event to the user.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void DataComplete(XSysAce *InstancePtr)
+{
+    InstancePtr->NumRequested = 0;
+    InstancePtr->NumRemaining = 0;
+    InstancePtr->BufferPtr = NULL;
+
+    /*
+     * Disable the data-buffer-ready interrupt. This isn't necessary when
+     * reading since the DATABUFRDY status bit is cleared by the ACE after
+     * the last data buffer is read.  However, the ACE isn't currently
+     * smart enough to clear the DATABUFRDY status bit after the last data
+     * buffer is written during a write operation.  So, we need to use the
+     * enable/disable interrupt bit to control its usefulness.
+     */
+    XSysAce_mAndControlReg(InstancePtr->BaseAddress, ~XSA_CR_DATARDYIRQ_MASK);
+
+    /*
+     * The same code is executed for JTAG configuration as well as CompactFlash
+     * transfers, so we need to distinguish between JTAG config done and CF
+     * data transfer done. We look at the CFGSEL value in the control register
+     * to determine if an MPU JTAG config process has just completed. The
+     * CFG_DONE event is passed up later by the main interrupt handler.
+     */
+    if ((XSysAce_mGetControlReg(InstancePtr->BaseAddress)
+        & XSA_CR_CFGSEL_MASK) == 0)
+    {
+        /* no JTAG configuration in progress */
+        InstancePtr->EventHandler(InstancePtr->EventRef, XSA_EVENT_DATA_DONE);
+    }
+}
+
diff -urN linux-2.4.29/drivers/block/xilinx_sysace/xsysace_jtagcfg.c linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace_jtagcfg.c
--- linux-2.4.29/drivers/block/xilinx_sysace/xsysace_jtagcfg.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace_jtagcfg.c	2005-06-14 02:11:55.000000000 +0100
@@ -0,0 +1,457 @@
+/* $Id: xsysace_jtagcfg.c,v 1.6 2002/07/24 21:01:49 moleres Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xsysace_jtagcfg.c
+*
+* Contains functions to control the configuration of the target FPGA chain on
+* the System ACE via the JTAG configuration port.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  06/17/02 work in progress
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xsysace.h"
+#include "xsysace_l.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+*
+* Reset the JTAG configuration controller. This comprises a reset of the JTAG
+* configuration controller and the CompactFlash controller (if it is currently
+* being accessed by the configuration controller). Note that the MPU controller
+* is not reset, meaning the MPU registers remain unchanged. The configuration
+* controller is reset then released from reset in this function.
+*
+* The CFGDONE status (and therefore interrupt) is cleared when the configuration
+* controller is reset. If interrupts have been enabled, we go ahead and enable
+* the CFGDONE interrupt here. This means that if and when a configuration
+* process starts as a result of this reset, an interrupt will be received when
+* it is complete.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* This function is not thread-safe.
+*
+******************************************************************************/
+void XSysAce_ResetCfg(XSysAce *InstancePtr)
+{
+    XASSERT_VOID(InstancePtr != NULL);
+    XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    /* Reset the configuration controller */
+    XSysAce_mOrControlReg(InstancePtr->BaseAddress, XSA_CR_CFGRESET_MASK);
+
+    /*
+     * If in interrupt mode, enable the CFGDONE and error interrupts.
+     * A reset clears the CFGDONE and error statuses, so we're going to
+     * re-enable the interrupts here so any new errors or CFGDONEs will be
+     * caught.
+     */
+    if (XSysAce_mIsIntrEnabled(InstancePtr->BaseAddress))
+    {
+        XSysAce_mOrControlReg(InstancePtr->BaseAddress, XSA_CR_CFGDONEIRQ_MASK |
+                              XSA_CR_ERRORIRQ_MASK);
+    }
+
+    /* Release the reset of the configuration controller */
+    XSysAce_mAndControlReg(InstancePtr->BaseAddress, ~XSA_CR_CFGRESET_MASK);
+}
+
+/*****************************************************************************/
+/**
+*
+* Select the configuration address (or file) from the CompactFlash to be used
+* for configuration of the target FPGA chain.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+* @param Address is the address or file number to be used as the bitstream to
+*        configure the target FPGA devices. There are 8 possible files, so
+*        the value of this parameter can range from 0 to 7.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XSysAce_SetCfgAddr(XSysAce *InstancePtr, unsigned int Address)
+{
+    XASSERT_VOID(InstancePtr != NULL);
+    XASSERT_VOID(Address < 8);
+    XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    /*
+     * Set the control register with the address and the bit that forces
+     * the use of the control register address bits instead of the address
+     * pins on the device.
+     */
+    XSysAce_mSetCfgAddr(InstancePtr->BaseAddress, Address);
+}
+
+/*****************************************************************************/
+/**
+*
+* Set the start mode for configuration of the target FPGA chain from
+* CompactFlash. The configuration process only starts after a reset. The
+* user can indicate that the configuration should start immediately after a
+* reset, or the configuration process can be delayed until the user commands
+* it to start (using this function). The configuration controller can be
+* reset using XSysAce_ResetCfg().
+*
+* The user can select which configuration file on the CompactFlash to use using
+* the XSysAce_SetCfgAddr() function. If the user intends to configure the target
+* FPGA chain directly from the MPU port, this function is not needed. Instead,
+* the user would simply call XSysAce_ProgramChain().
+*
+* The user can use XSysAce_IsCfgDone() when in polled mode to determine if
+* the configuration is complete. If in interrupt mode, the event
+* XSA_EVENT_CFG_DONE will be returned asynchronously to the user when the
+* configuration is complete. The user must call XSysAce_EnableInterrupt() to put
+* the device/driver into interrupt mode.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+* @param ImmedOnReset can be set to TRUE to indicate the configuration process
+*        will start immediately after a reset of the ACE configuration
+*        controller, or it can be set to FALSE to indicate the configuration
+*        process is delayed after a reset until the user starts it (using this
+*        function).
+* @param StartCfg is a boolean indicating whether to start the configuration
+*        process or not. When ImmedOnReset is set to TRUE, this value is
+*        ignored. When ImmedOnReset is set to FALSE, then this value controls
+*        when the configuration process is started. When set to TRUE the
+*        configuration process starts (assuming a reset of the device has
+*        occurred), and when set to FALSE the configuration process does not
+*        start.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XSysAce_SetStartMode(XSysAce *InstancePtr, u32 ImmedOnReset,
+                          u32 StartCfg)
+{
+    u32 Control;
+
+    XASSERT_VOID(InstancePtr != NULL);
+    XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    /* Get the current contents of the control register */
+    Control = XSysAce_mGetControlReg(InstancePtr->BaseAddress);
+
+    /*
+     * Since the user has called this function, we want to tell the ACE
+     * controller to look at the CFGMODE bit of the control register rather
+     * than the CFGMODE pin of the device to determine when to start a
+     * configuration process.
+     */
+    Control |= XSA_CR_FORCECFGMODE_MASK;
+
+    /* Set or clear the CFGMODE bit of the control register */
+    if (ImmedOnReset)
+    {
+        Control |= XSA_CR_CFGMODE_MASK;     /* immediate on reset */
+    }
+    else
+    {
+        Control &= ~XSA_CR_CFGMODE_MASK;    /* wait for start bit */
+    }
+
+
+    /* Set or clear the CFGSTART bit of the control register */
+    if (StartCfg)
+    {
+        Control |= XSA_CR_CFGSTART_MASK;
+    }
+    else
+    {
+        Control &= ~XSA_CR_CFGSTART_MASK;
+    }
+
+    XSysAce_mSetControlReg(InstancePtr->BaseAddress, Control);
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Program the target FPGA chain through the configuration JTAG port. This
+* allows the user to program the devices on the target FPGA chain from the MPU
+* port instead of from CompactFlash. The user specifies a buffer and the number
+* of bytes to write. The buffer should be equivalent to an ACE (.ace) file.
+*
+* Note that when loading the ACE file via the MPU port, the first sector of the
+* ACE file is discarded. The CF filesystem controller in the System ACE device
+* knows to skip the first sector when the ACE file comes from the CF, but the
+* CF filesystem controller is bypassed when the ACE file comes from the MPU
+* port. For this reason, this function skips the first sector of the buffer
+* passed in.
+*
+* In polled mode, the write is blocking. In interrupt mode, the write is
+* non-blocking and an event, XSA_EVENT_CFG_DONE, is returned to the user in
+* the asynchronous event handler when the configuration is complete.
+*
+* An MPU lock, obtained using XSysAce_Lock(), must be granted before calling
+* this function. If a lock has not been granted, no action is taken and an
+* error is returned.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+* @param BufferPtr is a pointer to a buffer that will be used to program
+*        the configuration JTAG devices.
+* @param NumBytes is the number of bytes in the buffer. We assume that there
+*        is at least one sector of data in the .ace file, which is the
+*        information sector.
+*
+* @return
+*
+* - XST_SUCCESS if the write was successful. In interrupt mode, this does not
+*   mean the write is complete, only that it has begun. An event is returned
+*   to the user when the write is complete.
+* - XST_SYSACE_NO_LOCK if no MPU lock has yet been granted
+* - XST_FAILURE if an error occurred during the write. The user should call
+*   XSysAce_GetErrors() to determine the cause of the error.
+*
+* @note
+*
+* None.
+*
+* @internal
+*
+* The System ACE controller has a 32-byte buffer which holds data. The entire
+* buffer must be written to ensure that it gets sent to the configuration
+* JTAG port. If the number of bytes specified by the user is not a multiple
+* of 32, the driver will pad the remaining bytes of the System ACE buffer with
+* zeroes in order to write the entire buffer.
+*
+******************************************************************************/
+XStatus XSysAce_ProgramChain(XSysAce *InstancePtr, u8 *BufferPtr,
+                             int NumBytes)
+{
+    u32 ControlMask;
+    int BytesToSend;
+    int NumSent;
+
+    XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(BufferPtr != NULL);
+    XASSERT_NONVOID(NumBytes > XSA_CF_SECTOR_SIZE);
+    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    /* If a lock has not been granted, return an error */
+    if (!XSysAce_mIsMpuLocked(InstancePtr->BaseAddress))
+    {
+        return XST_SYSACE_NO_LOCK;
+    }
+
+    /*
+     * Set up the configuration controller to use the MPU port as the
+     * source of configuration data (instead of the CF). The following
+     * control flow comes directly from the System ACE specification, except
+     * the reset was moved to after the other control register bits are set.
+     * Putting it into reset before the bits are set seemed to produce
+     * configuration errors occasionally.
+     */
+    ControlMask = XSysAce_mGetControlReg(InstancePtr->BaseAddress);
+
+     /* Select MPU as the source */
+    ControlMask |= XSA_CR_CFGSEL_MASK;
+    XSysAce_mSetControlReg(InstancePtr->BaseAddress, ControlMask);
+
+    /* Tell controller to wait for start bit from MPU */
+    ControlMask |= XSA_CR_FORCECFGMODE_MASK;
+    ControlMask &= ~XSA_CR_CFGMODE_MASK;
+    XSysAce_mSetControlReg(InstancePtr->BaseAddress, ControlMask);
+
+    /* Set the start bit */
+    ControlMask |= XSA_CR_CFGSTART_MASK;
+    XSysAce_mSetControlReg(InstancePtr->BaseAddress, ControlMask);
+
+    /* Put the configuration controller into a reset condition */
+    ControlMask |= XSA_CR_CFGRESET_MASK;
+    XSysAce_mSetControlReg(InstancePtr->BaseAddress, ControlMask);
+
+    /* Clear the reset condition, which starts the process */
+    ControlMask &= ~XSA_CR_CFGRESET_MASK;
+    XSysAce_mSetControlReg(InstancePtr->BaseAddress, ControlMask);
+
+    /*
+     * Set up number of bytes to send. Default to the entire buffer, which
+     * will be true in polled mode. In interrupt mode, modify this value to
+     * send only one data buffer of data.  Always skip the first sector per
+     * the comment above.
+     */
+    BytesToSend = NumBytes - XSA_CF_SECTOR_SIZE;
+
+    /*
+     * The number of bytes to write depends on interrupt or polled mode
+     */
+    if (XSysAce_mIsIntrEnabled(InstancePtr->BaseAddress))
+    {
+        /*
+         * In interrupt mode, so enable the data-buffer-ready and
+         * configuration-done interrupts. Also, set up the state variables for
+         * the interrupt handler to transfer the remaining data after the
+         * initial write below. We need to write one data buffer here in this
+         * function in order to cause the data-buffer-ready interrupt to occur
+         * for subsequent writes.
+         */
+        ControlMask |= XSA_CR_DATARDYIRQ_MASK | XSA_CR_CFGDONEIRQ_MASK;
+        XSysAce_mSetControlReg(InstancePtr->BaseAddress, ControlMask);
+
+        /* Send only one data buffer to begin with (if there is that much) */
+        if (BytesToSend > XSA_DATA_BUFFER_SIZE)
+        {
+            BytesToSend = XSA_DATA_BUFFER_SIZE;
+        }
+
+        /*
+         * Setup state variables for the interrupt handler. Skip the first
+         * sector per the comment above, and also skip the first data buffer
+         * since it is written below.
+         */
+        InstancePtr->NumRequested = NumBytes - XSA_CF_SECTOR_SIZE;
+        InstancePtr->BufferPtr = BufferPtr + XSA_CF_SECTOR_SIZE + BytesToSend;
+        InstancePtr->NumRemaining = NumBytes - XSA_CF_SECTOR_SIZE - BytesToSend;
+    }
+
+    NumSent = XSysAce_WriteDataBuffer(InstancePtr->BaseAddress,
+                                      BufferPtr + XSA_CF_SECTOR_SIZE,
+                                      BytesToSend);
+    if (NumSent != BytesToSend)
+    {
+        /* an error occurred, report this to the user */
+        return XST_FAILURE;
+    }
+
+    /*
+     * If in polled mode, restore the control register to the way it was
+     */
+    if (!XSysAce_mIsIntrEnabled(InstancePtr->BaseAddress))
+    {
+         /*
+          * Unselect MPU as the source, tell controller to use CFGMODE pin,
+          * and clear the start bit.
+          */
+        ControlMask &= ~(XSA_CR_CFGSEL_MASK | XSA_CR_FORCECFGMODE_MASK |
+                         XSA_CR_CFGSTART_MASK);
+        XSysAce_mSetControlReg(InstancePtr->BaseAddress, ControlMask);
+    }
+
+    return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Check to see if the configuration of the target FPGA chain is complete. This
+* function is typically only used in polled mode. In interrupt mode, an event
+* (XSA_EVENT_CFG_DONE) is returned to the user in the asynchronous event
+* handler.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+*
+* @return
+*
+* TRUE if the configuration is complete. FALSE otherwise.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32 XSysAce_IsCfgDone(XSysAce *InstancePtr)
+{
+    XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    /* Use the layer 0 macro by the same name */
+
+    return XSysAce_mIsCfgDone(InstancePtr->BaseAddress);
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Get the sector ID of the CompactFlash sector being used for configuration of
+* the target FPGA chain. This sector ID (or logical block address) only affects
+* transfers between the ACE configuration logic and the CompactFlash card.
+* This function is typically used for debug purposes to determine which sector
+* was being accessed when an error occurred.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+*
+* @return
+*
+* The sector ID (logical block address) being used for data transfers between
+* the ACE configuration logic and the CompactFlash. Sector IDs range from 0
+* to 0x10000000.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32 XSysAce_GetCfgSector(XSysAce *InstancePtr)
+{
+    XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    return XSysAce_RegRead32(InstancePtr->BaseAddress + XSA_CLR_OFFSET);
+}
diff -urN linux-2.4.29/drivers/block/xilinx_sysace/xsysace_l.c linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace_l.c
--- linux-2.4.29/drivers/block/xilinx_sysace/xsysace_l.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace_l.c	2005-06-14 02:11:55.000000000 +0100
@@ -0,0 +1,586 @@
+/* $Id: xsysace_l.c,v 1.8 2002/11/04 23:44:21 moleres Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xsysace_l.c
+*
+* This file contains low-level functions to read and write CompactFlash
+* sectors and ACE controller registers. These functions can be used when only
+* the low-level functionality of the driver is desired. The user would
+* typically use the high-level driver functions defined in xsysace.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  06/14/02 work in progress
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xsysace_l.h"
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * Set up the access width of the MPU registers based on compile-time constants.
+ * If hardware requires 32-bit aligned addresses (XSA_ADDR_ALIGN=4) to access
+ * the MPU registers, then access all of them as 32 bits. If hardware allows
+ * 8-bit aligned addresses (XSA_ADDR_ALIGN=1, or not 4) to access the MPU
+ * registers, access them as 8 or 16 bits depending on the bus mode of the ACE
+ * controller.
+ */
+#if (XSA_ADDR_ALIGN == 4)
+
+#define XIo_In   XIo_In32
+#define XIo_Out  XIo_Out32
+
+#else
+
+#if (CONFIG_XILINX_SYSACE_0_MEM_WIDTH == 16)
+#define XIo_In   XIo_In16
+#define XIo_Out  XIo_Out16
+#else /* CONFIG_XILINX_SYSACE_0_MEM_WIDTH  */
+#define XIo_In   XIo_In8
+#define XIo_Out  XIo_Out8
+#endif /* CONFIG_XILINX_SYSACE_0_MEM_WIDTH  */
+
+#endif /* (XSA_ADDR_ALIGN == 4) */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+/************************** Variable Definitions *****************************/
+
+/*****************************************************************************/
+/**
+*
+* Read a 32-bit value from the given address. Based on a compile-time
+* constant, do the read in two 16-bit reads or four 8-bit reads.
+*
+* @param    Address is the address to read from.
+*
+* @return   The 32-bit value of the address.
+*
+* @note     No need for endian conversion in 8-bit mode since this function
+*           gets the bytes into their proper lanes in the 32-bit word.
+*
+******************************************************************************/
+#if (CONFIG_XILINX_SYSACE_0_MEM_WIDTH == 16)
+u32 XSysAce_RegRead32(u32 Address)
+{
+    u16 Data;
+    u16 ConvertedData;
+    u32 Value = 0;
+
+    /*
+     * Need to endian convert each 32-bit value. The ACE registers are little-
+     * endian, so we read the two LSBs first, endian convert, then put them
+     * in the LSB lanes of the 32-bit word. etc...
+     */
+    Data = (u16)XIo_In(Address);
+    XIo_FromLittleEndian16(Data, &ConvertedData);
+    Value = (u32)ConvertedData;
+
+    Data = (u16)XIo_In(Address + (2 * XSA_ADDR_ALIGN));
+    XIo_FromLittleEndian16(Data, &ConvertedData);
+    Value |= ((u32)ConvertedData << 16);
+
+    return Value;
+}
+#else
+u32 XSysAce_RegRead32(u32 Address)
+{
+    u32 Value = 0;
+
+    /*
+     * The ACE registers are little-endian always. This code reads each 8-bit
+     * register value, in order from LSB to MSB, and shifts it to the correct
+     * byte lane of the 32-bit word. This code should work on both
+     * little-endian and big-endian processors.
+     */
+    Value = (u32)XIo_In(Address);
+    Value |= ((u32)XIo_In(Address + (1 * XSA_ADDR_ALIGN)) << 8);
+    Value |= ((u32)XIo_In(Address + (2 * XSA_ADDR_ALIGN)) << 16);
+    Value |= ((u32)XIo_In(Address + (3 * XSA_ADDR_ALIGN)) << 24);
+
+    return Value;
+}
+#endif
+
+
+/*****************************************************************************/
+/**
+*
+* Read a 16-bit value from the given address. Based on a compile-time
+* constant, do the read in one 16-bit read or two 8-bit reads.
+*
+* @param    Address is the address to read from.
+*
+* @return   The 16-bit value of the address.
+*
+* @note     No need for endian conversion in 8-bit mode since this function
+*           gets the bytes into their proper lanes in the 16-bit word.
+*
+******************************************************************************/
+#if (CONFIG_XILINX_SYSACE_0_MEM_WIDTH == 16)
+u16 XSysAce_RegRead16(u32 Address)
+{
+    u16 Data;
+    u16 ConvertedData;
+
+    /*
+     * Need to endian convert the 16-bit value. The ACE registers are little-
+     * endian.
+     */
+    Data = (u16)XIo_In(Address);
+    XIo_FromLittleEndian16(Data, &ConvertedData);
+    return ConvertedData;
+}
+#else
+u16 XSysAce_RegRead16(u32 Address)
+{
+    u16 Value = 0;
+
+    /*
+     * The ACE registers are little-endian always. This code reads each 8-bit
+     * register value, in order from LSB to MSB, and shifts it to the correct
+     * byte lane of the 32-bit word. This code should work on both
+     * little-endian and big-endian processors.
+     */
+    Value = (u16)XIo_In(Address);
+    Value |= ((u16)XIo_In(Address + (1 * XSA_ADDR_ALIGN)) << 8);
+
+    return Value;
+}
+#endif
+
+
+/*****************************************************************************/
+/**
+*
+* Write a 32-bit value to the given address. Based on a compile-time
+* constant, do the write in two 16-bit writes or four 8-bit writes.
+*
+* @param    Address is the address to write to.
+* @param    Data is the value to write
+*
+* @return   None.
+*
+* @note     No need for endian conversion in 8-bit mode since this function
+*           writes the bytes into their proper lanes based on address.
+*
+******************************************************************************/
+#if (CONFIG_XILINX_SYSACE_0_MEM_WIDTH == 16)
+void XSysAce_RegWrite32(u32 Address, u32 Data)
+{
+    u16 Hword;
+    u16 ConvertedData;
+
+    /*
+     * The ACE registers are little-endian always. This code takes each 16-bit
+     * value of the incoming 32-bit word and endian converts it, then writes it
+     * to the ACE register.
+     */
+    Hword = (u16)Data;
+    XIo_ToLittleEndian16(Hword, &ConvertedData);
+    XIo_Out(Address, ConvertedData);
+
+    Hword = (u16)(Data >> 16);
+    XIo_ToLittleEndian16(Hword, &ConvertedData);
+    XIo_Out(Address + (2 * XSA_ADDR_ALIGN), ConvertedData);
+}
+#else
+void XSysAce_RegWrite32(u32 Address, u32 Data)
+{
+    /*
+     * The ACE registers are little-endian always. This code reads each 8-bit
+     * register value, in order from LSB to MSB, and shifts it to the correct
+     * byte lane of the 32-bit word. This code should work on both
+     * little-endian and big-endian processors.
+     */
+    XIo_Out(Address, (u8)Data);
+    XIo_Out(Address + (1 * XSA_ADDR_ALIGN), (u8)(Data >> 8));
+    XIo_Out(Address + (2 * XSA_ADDR_ALIGN), (u8)(Data >> 16));
+    XIo_Out(Address + (3 * XSA_ADDR_ALIGN), (u8)(Data >> 24));
+}
+#endif
+
+
+/*****************************************************************************/
+/**
+*
+* Write a 16-bit value to the given address. Based on a compile-time
+* constant, do the write in one 16-bit write or two 8-bit writes.
+*
+* @param    Address is the address to write to.
+* @param    Data is the value to write
+*
+* @return   None.
+*
+* @note     No need for endian conversion in 8-bit mode since this function
+*           writes the bytes into their proper lanes based on address.
+*
+******************************************************************************/
+#if (CONFIG_XILINX_SYSACE_0_MEM_WIDTH == 16)
+void XSysAce_RegWrite16(u32 Address, u16 Data)
+{
+    u16 ConvertedData;
+
+    /*
+     * The ACE registers are little-endian always. This code takes the incoming
+     * 16-bit and endian converts it, then writes it to the ACE register.
+     */
+    XIo_ToLittleEndian16(Data, &ConvertedData);
+    XIo_Out(Address, ConvertedData);
+}
+#else
+void XSysAce_RegWrite16(u32 Address, u16 Data)
+{
+    /*
+     * The ACE registers are little-endian always. This code reads each 8-bit
+     * register value, in order from LSB to MSB, and shifts it to the correct
+     * byte lane of the 32-bit word. This code should work on both
+     * little-endian and big-endian processors.
+     */
+    XIo_Out(Address, (u8)Data);
+    XIo_Out(Address + (1 * XSA_ADDR_ALIGN), (u8)(Data >> 8));
+}
+#endif
+
+
+/*****************************************************************************/
+/**
+*
+* Read a CompactFlash sector. This is a blocking, low-level function which
+* does not return until the specified sector is read.
+*
+* @param BaseAddress is the base address of the device
+* @param SectorId is the id of the sector to read
+* @param BufferPtr is a pointer to a buffer where the data will be stored.
+*
+* @return
+*
+* The number of bytes read. If this number is not equal to the sector size,
+* 512 bytes, then an error occurred.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+int XSysAce_ReadSector(u32 BaseAddress, u32 SectorId, u8 *BufferPtr)
+{
+    int NumRead;
+
+    /* Request and wait for the lock */
+    XSysAce_mWaitForLock(BaseAddress);
+
+    /* See if the CF is ready for a command */
+    if (!XSysAce_mIsReadyForCmd(BaseAddress))
+    {
+        return 0;
+    }
+
+    /* Write the sector ID (LBA) */
+    XSysAce_RegWrite32(BaseAddress + XSA_MLR_OFFSET, SectorId);
+
+    /* Send a read command of one sector to the controller */
+    XSysAce_RegWrite16(BaseAddress + XSA_SCCR_OFFSET,
+                        XSA_SCCR_READDATA_MASK | 1);
+
+    /* Reset configuration controller (be sure to keep the lock) */
+    XSysAce_mOrControlReg(BaseAddress, XSA_CR_CFGRESET_MASK);
+
+    /* Read a sector of data from the data buffer */
+    NumRead = XSysAce_ReadDataBuffer(BaseAddress, BufferPtr,
+                                     XSA_CF_SECTOR_SIZE);
+
+    /* Clear reset of configuration controller and locks */
+    XSysAce_mAndControlReg(BaseAddress, ~(XSA_CR_CFGRESET_MASK |
+                           XSA_CR_LOCKREQ_MASK));
+
+    return NumRead;
+}
+
+/*****************************************************************************/
+/**
+*
+* Write a CompactFlash sector. This is a blocking, low-level function which
+* does not return until the specified sector is written in its entirety.
+*
+* @param BaseAddress is the base address of the device
+* @param SectorId is the id of the sector to write
+* @param BufferPtr is a pointer to a buffer used to write the sector.
+*
+* @return
+*
+* The number of bytes written. If this number is not equal to the sector size,
+* 512 bytes, then an error occurred.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+int XSysAce_WriteSector(u32 BaseAddress, u32 SectorId, u8 *BufferPtr)
+{
+    int NumSent;
+
+    /* Get the lock */
+    XSysAce_mWaitForLock(BaseAddress);
+
+    /* See if the CF is ready for a command */
+    if (!XSysAce_mIsReadyForCmd(BaseAddress))
+    {
+        return 0;
+    }
+
+    /* Write the sector ID (LBA) */
+    XSysAce_RegWrite32(BaseAddress + XSA_MLR_OFFSET, SectorId);
+
+    /* Send a write command of one sector to the controller */
+    XSysAce_RegWrite16(BaseAddress + XSA_SCCR_OFFSET,
+                        XSA_SCCR_READDATA_MASK | 1);
+
+    /* Reset configuration controller (be sure to keep the lock) */
+    XSysAce_mOrControlReg(BaseAddress, XSA_CR_CFGRESET_MASK);
+
+    /* Write a sector of data to the data buffer */
+    NumSent = XSysAce_WriteDataBuffer(BaseAddress, BufferPtr,
+                                      XSA_CF_SECTOR_SIZE);
+
+    /* Clear reset of configuration controller and locks */
+    XSysAce_mAndControlReg(BaseAddress, ~(XSA_CR_CFGRESET_MASK |
+                           XSA_CR_LOCKREQ_MASK));
+
+    return NumSent;
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Read the specified number of bytes from the data buffer of the ACE
+* controller. The data buffer, which is 32 bytes, can only be read two bytes
+* at a time.  Once the data buffer is read, we wait for it to be filled again
+* before reading the next buffer's worth of data.
+*
+* @param BaseAddress is the base address of the device
+* @param BufferPtr is a pointer to a buffer in which to store data.
+* @param Size is the number of bytes to read
+*
+* @return
+*
+* The total number of bytes read, or 0 if an error occurred.
+*
+* @note
+*
+* If Size is not aligned with the size of the data buffer (32 bytes), this
+* function will read the entire data buffer, dropping the extra bytes on the
+* floor since the user did not request them. This is necessary to get the
+* data buffer to be ready again.
+*
+******************************************************************************/
+int XSysAce_ReadDataBuffer(u32 BaseAddress, u8 *BufferPtr, int Size)
+{
+    int DataBytes;         /* number of data bytes written */
+    int BufferBytes;
+    u16 Data;
+
+    /*
+     * Read data two bytes at a time. We need to wait for the data
+     * buffer to be ready before reading the buffer.
+     */
+    BufferBytes = 0;
+    for (DataBytes = 0; DataBytes < Size;)
+    {
+        /*
+         * If at any point during this read an error occurs, exit early
+         */
+        if (XSysAce_mGetErrorReg(BaseAddress) != 0)
+        {
+            return 0;
+        }
+
+        if (BufferBytes == 0)
+        {
+            /*
+             * Wait for CF data buffer to ready, then reset buffer byte count
+             */
+            while ((XSysAce_mGetStatusReg(BaseAddress)
+                    & XSA_SR_DATABUFRDY_MASK) == 0);
+
+            BufferBytes = XSA_DATA_BUFFER_SIZE;
+        }
+
+        /*
+         * Need to read two bytes. Put the first one in the output buffer
+         * because if we're here we know one more is needed. Put the second one
+         * in the output buffer if there is still room, or just drop it on the
+         * floor if the requested number of bytes have already been read.
+         */
+        Data = XSysAce_RegRead16(BaseAddress + XSA_DBR_OFFSET);
+        *BufferPtr++ = (u8)Data;
+        DataBytes++;
+
+        if (DataBytes < Size)
+        {
+            /* Still more room in the output buffer */
+            *BufferPtr++ = (u8)(Data >> 8);
+            DataBytes++;
+        }
+
+        BufferBytes -= 2;
+    }
+
+    /*
+     * If a complete data buffer was not read, read and ignore the remaining
+     * bytes
+     */
+    while (BufferBytes != 0)
+    {
+        /*
+         * If at any point during this read an error occurs, exit early
+         */
+        if (XSysAce_mGetErrorReg(BaseAddress) != 0)
+        {
+            return 0;
+        }
+
+        (void)XSysAce_RegRead16(BaseAddress + XSA_DBR_OFFSET);
+        BufferBytes -= 2;
+    }
+
+    return DataBytes;
+}
+
+/*****************************************************************************/
+/**
+*
+* Write the specified number of bytes to the data buffer of the ACE controller.
+* The data buffer, which is 32 bytes, can only be written two bytes at a time.
+* Once the data buffer is written, we wait for it to be empty again before
+* writing the next buffer's worth of data. If the size of the incoming buffer
+* is not aligned with the System ACE data buffer size (32 bytes), then this
+* routine pads out the data buffer with zeros so the entire data buffer is
+* written. This is necessary for the ACE controller to process the data buffer.
+*
+* @param BaseAddress is the base address of the device
+* @param BufferPtr is a pointer to a buffer used to write to the controller.
+* @param Size is the number of bytes to write
+*
+* @return
+*
+* The total number of bytes written (not including pad bytes), or 0 if an
+* error occurs.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+int XSysAce_WriteDataBuffer(u32 BaseAddress, u8 *BufferPtr, int Size)
+{
+    int DataBytes;         /* number of data bytes written */
+    int BufferBytes;
+    u16 Data;
+
+    /*
+     * Write a sector two bytes at a time. We need to wait for the data
+     * buffer to be ready before writing the buffer.
+     */
+    BufferBytes = 0;
+    for (DataBytes = 0; DataBytes < Size;)
+    {
+        /*
+         * If at any point during this write an error occurs, exit early
+         */
+        if (XSysAce_mGetErrorReg(BaseAddress) != 0)
+        {
+            return 0;
+        }
+
+        if (BufferBytes == 0)
+        {
+            /*
+             * Wait for CF read data buffer to ready, then reset buffer byte
+             * count
+             */
+            while ((XSysAce_mGetStatusReg(BaseAddress)
+                    & XSA_SR_DATABUFRDY_MASK) == 0);
+
+            BufferBytes = XSA_DATA_BUFFER_SIZE;
+        }
+
+        /*
+         * Need to send two bytes. Grab the first one from the incoming buffer
+         * because if we're here we know one more exists. Grab the second one
+         * from the incoming buffer if there are still any bytes remaining, or
+         * send a pad byte if the incoming buffer has been expired.
+         */
+        Data = *BufferPtr++;
+        DataBytes++;
+
+        if (DataBytes < Size)
+        {
+            /* Still more data in the incoming buffer */
+            Data |= ((u16)*BufferPtr++ << 8);
+            DataBytes++;
+        }
+        else
+        {
+            /* No more data in the incoming buffer, send a pad byte of 0 */
+            Data |= ((u16)0 << 8);
+        }
+
+        XSysAce_RegWrite16(BaseAddress + XSA_DBR_OFFSET, Data);
+
+        BufferBytes -= 2;
+    }
+
+    /*
+     * If a complete data buffer was not filled, fill it with pad bytes (zeros)
+     */
+    while (BufferBytes != 0)
+    {
+        /*
+         * If at any point during this write an error occurs, exit early
+         */
+        if (XSysAce_mGetErrorReg(BaseAddress) != 0)
+        {
+            return 0;
+        }
+
+        XSysAce_RegWrite16(BaseAddress + XSA_DBR_OFFSET, 0);
+        BufferBytes -= 2;
+    }
+
+    return DataBytes;
+}
diff -urN linux-2.4.29/drivers/block/xilinx_sysace/xsysace_l.h linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace_l.h
--- linux-2.4.29/drivers/block/xilinx_sysace/xsysace_l.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace_l.h	2005-06-14 02:11:55.000000000 +0100
@@ -0,0 +1,503 @@
+/* $Id: xsysace_l.h,v 1.13 2002/10/24 20:51:00 moleres Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xsysace_l.h
+*
+* Defines identifiers and low-level macros/functions for the XSysAce driver.
+* These identifiers include register offsets and bit masks. A high-level driver
+* interface is defined in xsysace.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  06/14/02 work in progress
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XSYSACE_L_H /* prevent circular inclusions */
+#define XSYSACE_L_H /* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * Constant used to align the register offsets to the proper address. This was
+ * used during development to handle both byte-addressable (alignment=1) and
+ * word addressable (alignment=4) registers. The #ifndef allows the user to
+ * modify this at compile-time.
+ */
+#ifndef XSA_ADDR_ALIGN
+#define XSA_ADDR_ALIGN      1
+#endif
+
+/** @name Register Offsets
+ * System ACE register offsets
+ * @{
+ */
+#define XSA_BMR_OFFSET   (XSA_ADDR_ALIGN * 0)  /**< Bus mode (BUSMODEREG) */
+#define XSA_SR_OFFSET    (XSA_ADDR_ALIGN * 4)  /**< Status (STATUSREG) */
+#define XSA_ER_OFFSET    (XSA_ADDR_ALIGN * 8)  /**< Error (ERRORREG) */
+#define XSA_CLR_OFFSET   (XSA_ADDR_ALIGN * 12) /**< Config LBA (CFGLBAREG) */
+#define XSA_MLR_OFFSET   (XSA_ADDR_ALIGN * 16) /**< MPU LBA (MPULBAREG) */
+#define XSA_SCCR_OFFSET  (XSA_ADDR_ALIGN * 20) /**< Sector cnt (SECCNTCMDREG) */
+#define XSA_VR_OFFSET    (XSA_ADDR_ALIGN * 22) /**< Version (VERSIONREG) */
+#define XSA_CR_OFFSET    (XSA_ADDR_ALIGN * 24) /**< Control (CONTROLREG) */
+#define XSA_FSR_OFFSET   (XSA_ADDR_ALIGN * 28) /**< FAT status (FATSTATREG) */
+#define XSA_DBR_OFFSET   (XSA_ADDR_ALIGN * 64) /**< Data buffer (DATABUFREG) */
+/*@}*/
+
+/*
+ * Bus Mode Register masks
+ */
+#define XSA_BMR_16BIT_MASK      0x0101  /**< 16-bit access to ACE controller */
+
+
+/** @name Status Values
+ * Status Register masks
+ * @{
+ */
+#define XSA_SR_CFGLOCK_MASK     0x00000001  /**< Config port lock status */
+#define XSA_SR_MPULOCK_MASK     0x00000002  /**< MPU port lock status */
+#define XSA_SR_CFGERROR_MASK    0x00000004  /**< Config port error status */
+#define XSA_SR_CFCERROR_MASK    0x00000008  /**< CF error status */
+#define XSA_SR_CFDETECT_MASK    0x00000010  /**< CF detect flag */
+#define XSA_SR_DATABUFRDY_MASK  0x00000020  /**< Data buffer ready status */
+#define XSA_SR_DATABUFMODE_MASK 0x00000040  /**< Data buffer mode status */
+#define XSA_SR_CFGDONE_MASK     0x00000080  /**< Configuration done status */
+#define XSA_SR_RDYFORCMD_MASK   0x00000100  /**< Ready for CF command */
+#define XSA_SR_CFGMODE_MASK     0x00000200  /**< Configuration mode status */
+#define XSA_SR_CFGADDR_MASK     0x0000E000  /**< Configuration address  */
+#define XSA_SR_CFBSY_MASK       0x00020000  /**< CF busy (BSY bit) */
+#define XSA_SR_CFRDY_MASK       0x00040000  /**< CF ready (RDY bit) */
+#define XSA_SR_CFDWF_MASK       0x00080000  /**< CF data write fault (DWF bit) */
+#define XSA_SR_CFDSC_MASK       0x00100000  /**< CF ready (DSC bit) */
+#define XSA_SR_CFDRQ_MASK       0x00200000  /**< CF data request (DRQ) */
+#define XSA_SR_CFCORR_MASK      0x00400000  /**< CF correctable error (CORR bit) */
+#define XSA_SR_CFERR_MASK       0x00800000  /**< CF error (ERR bit) */
+/*@}*/
+
+
+/** @name Error Values
+ * Error Register masks.
+ * @{
+ */
+#define XSA_ER_CARD_RESET    0x00000001  /**< CF card failed to reset */
+#define XSA_ER_CARD_READY    0x00000002  /**< CF card failed to ready */
+#define XSA_ER_CARD_READ     0x00000004  /**< CF read command failed */
+#define XSA_ER_CARD_WRITE    0x00000008  /**< CF write command failed */
+#define XSA_ER_SECTOR_READY  0x00000010  /**< CF sector failed to ready */
+#define XSA_ER_CFG_ADDR      0x00000020  /**< Cfg address is invalid */
+#define XSA_ER_CFG_FAIL      0x00000040  /**< Failed to configure a device */
+#define XSA_ER_CFG_READ      0x00000080  /**< Cfg read of CF failed */
+#define XSA_ER_CFG_INSTR     0x00000100  /**< Invalid instruction during cfg */
+#define XSA_ER_CFG_INIT      0x00000200  /**< CFGINIT pin error - did not
+                                          *   go high within 500ms of start */
+#define XSA_ER_RESERVED      0x00000400  /**< reserved */
+#define XSA_ER_BAD_BLOCK     0x00000800  /**< CF bad block detected */
+#define XSA_ER_UNCORRECTABLE 0x00001000  /**< CF uncorrectable error */
+#define XSA_ER_SECTOR_ID     0x00002000  /**< CF sector ID not found */
+#define XSA_ER_ABORT         0x00004000  /**< CF command aborted */
+#define XSA_ER_GENERAL       0x00008000  /**< CF general error */
+/*@}*/
+
+
+/**
+ * Config LBA Register - address mask
+ */
+#define XSA_CLR_LBA_MASK    0x0FFFFFFF  /* Logical Block Address mask */
+
+/**
+ * MPU LBA Register - address mask
+ */
+#define XSA_MLR_LBA_MASK    0x0FFFFFFF  /* Logical Block Address mask */
+
+
+/** @name Sector Cound/Command Values
+ * Sector Count Command Register masks
+ * @{
+ */
+#define XSA_SCCR_COUNT_MASK     0x00FF   /**< Sector count mask */
+#define XSA_SCCR_RESET_MASK     0x0100   /**< Reset CF card command */
+#define XSA_SCCR_IDENTIFY_MASK  0x0200   /**< Identify CF card command */
+#define XSA_SCCR_READDATA_MASK  0x0300   /**< Read CF card command */
+#define XSA_SCCR_WRITEDATA_MASK 0x0400   /**< Write CF card command */
+#define XSA_SCCR_ABORT_MASK     0x0600   /**< Abort CF command */
+#define XSA_SCCR_CMD_MASK       0x0700   /**< Command mask */
+/*@}*/
+
+
+/*
+ * Version Register masks
+ */
+#define XSA_VR_BUILD_MASK   0x00FF      /* Revision/build number */
+#define XSA_VR_MINOR_MASK   0x0F00      /* Minor version number */
+#define XSA_VR_MAJOR_MASK   0xF000      /* Major version number */
+
+
+/** @name Control Values
+ * Control Register masks
+ * @{
+ */
+#define XSA_CR_FORCELOCK_MASK       0x00000001  /**< Force lock request */
+#define XSA_CR_LOCKREQ_MASK         0x00000002  /**< MPU lock request */
+#define XSA_CR_FORCECFGADDR_MASK    0x00000004  /**< Force CFG address */
+#define XSA_CR_FORCECFGMODE_MASK    0x00000008  /**< Force CFG mode */
+#define XSA_CR_CFGMODE_MASK         0x00000010  /**< CFG mode */
+#define XSA_CR_CFGSTART_MASK        0x00000020  /**< CFG start */
+#define XSA_CR_CFGSEL_MASK          0x00000040  /**< CFG select */
+#define XSA_CR_CFGRESET_MASK        0x00000080  /**< CFG reset */
+#define XSA_CR_DATARDYIRQ_MASK      0x00000100  /**< Enable data ready IRQ */
+#define XSA_CR_ERRORIRQ_MASK        0x00000200  /**< Enable error IRQ */
+#define XSA_CR_CFGDONEIRQ_MASK      0x00000400  /**< Enable CFG done IRQ */
+#define XSA_CR_RESETIRQ_MASK        0x00000800  /**< Reset IRQ line */
+#define XSA_CR_CFGPROG_MASK         0x00001000  /**< Inverted CFGPROG pin */
+#define XSA_CR_CFGADDR_MASK         0x0000E000  /**< Config address mask */
+#define XSA_CR_CFGADDR_SHIFT                13  /**< Config address shift */
+/*@}*/
+
+
+/** @name FAT Status
+ *
+ * FAT filesystem status masks. The first valid partition of the CF
+ * is a FAT partition.
+ * @{
+ */
+#define XSA_FAT_VALID_BOOT_REC  0x0001  /**< Valid master boot record */
+#define XSA_FAT_VALID_PART_REC  0x0002  /**< Valid partition boot record */
+#define XSA_FAT_12_BOOT_REC     0x0004  /**< FAT12 in master boot rec */
+#define XSA_FAT_12_PART_REC     0x0008  /**< FAT12 in parition boot rec */
+#define XSA_FAT_16_BOOT_REC     0x0010  /**< FAT16 in master boot rec */
+#define XSA_FAT_16_PART_REC     0x0020  /**< FAT16 in partition boot rec */
+#define XSA_FAT_12_CALC         0x0040  /**< Calculated FAT12 from clusters */
+#define XSA_FAT_16_CALC         0x0080  /**< Calculated FAT16 from clusters */
+/*@}*/
+
+
+#define XSA_DATA_BUFFER_SIZE    32   /**< Size of System ACE data buffer */
+#define XSA_CF_SECTOR_SIZE     512   /**< Number of bytes in a CF sector */
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************
+*
+* Low-level driver macros and functions. The list below provides signatures
+* to help the user use the macros.
+*
+* u32 XSysAce_mGetControlReg(u32 BaseAddress)
+* void XSysAce_mSetControlReg(u32 BaseAddress, u32 Data)
+* void XSysAce_mOrControlReg(u32 BaseAddress, u32 Data)
+* void XSysAce_mAndControlReg(u32 BaseAddress, u32 Data)
+* u32 XSysAce_mGetErrorReg(u32 BaseAddress)
+* u32 XSysAce_mGetStatusReg(u32 BaseAddress)
+*
+* void XSysAce_mSetCfgAddr(u32 BaseAddress, unsigned int Address)
+* void XSysAce_mWaitForLock(u32 BaseAddress)
+* void XSysAce_mEnableIntr(u32 BaseAddress, u32 Mask)
+* void XSysAce_mDisableIntr(u32 BaseAddress, u32 Mask)
+*
+* u32 XSysAce_mIsReadyForCmd(u32 BaseAddress)
+* u32 XSysAce_mIsCfgDone(u32 BaseAddress)
+* u32 XSysAce_mIsMpuLocked(u32 BaseAddress)
+* u32 XSysAce_mIsIntrEnabled(u32 BaseAddress)
+*
+*****************************************************************************/
+
+
+/*****************************************************************************/
+/**
+*
+* Get the contents of the control register.
+*
+* @param    BaseAddress is the base address of the device.
+*
+* @return   The 32-bit value of the control register.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XSysAce_mGetControlReg(BaseAddress) \
+                XSysAce_RegRead32((BaseAddress) + XSA_CR_OFFSET)
+
+
+/*****************************************************************************/
+/**
+*
+* Set the contents of the control register.
+*
+* @param    BaseAddress is the base address of the device.
+* @param    Data is the 32-bit value to write to the register.
+*
+* @return   None.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XSysAce_mSetControlReg(BaseAddress, Data) \
+                XSysAce_RegWrite32((BaseAddress) + XSA_CR_OFFSET, (Data))
+
+
+/*****************************************************************************/
+/**
+*
+* Set the contents of the control register to the value specified OR'ed with
+* its current contents.
+*
+* @param    BaseAddress is the base address of the device.
+* @param    Data is the 32-bit value to OR with the register.
+*
+* @return   None.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XSysAce_mOrControlReg(BaseAddress, Data) \
+                XSysAce_mSetControlReg((BaseAddress), \
+                        XSysAce_mGetControlReg(BaseAddress) | (Data))
+
+
+/*****************************************************************************/
+/**
+*
+* Set the contents of the control register to the value specified AND'ed with
+* its current contents.
+*
+* @param    BaseAddress is the base address of the device.
+* @param    Data is the 32-bit value to AND with the register.
+*
+* @return   None.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XSysAce_mAndControlReg(BaseAddress, Data) \
+                XSysAce_mSetControlReg((BaseAddress), \
+                        XSysAce_mGetControlReg(BaseAddress) & (Data))
+
+
+/*****************************************************************************/
+/**
+*
+* Get the contents of the error register.
+*
+* @param    BaseAddress is the base address of the device.
+*
+* @return   The 32-bit value of the register.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XSysAce_mGetErrorReg(BaseAddress) \
+                XSysAce_RegRead32((BaseAddress) + XSA_ER_OFFSET)
+
+
+/*****************************************************************************/
+/**
+*
+* Get the contents of the status register.
+*
+* @param    BaseAddress is the base address of the device.
+*
+* @return   The 32-bit value of the register.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XSysAce_mGetStatusReg(BaseAddress) \
+                XSysAce_RegRead32((BaseAddress) + XSA_SR_OFFSET)
+
+
+/*****************************************************************************/
+/**
+*
+* Set the configuration address, or file, of the CompactFlash. This address
+* indicates which .ace bitstream to use to configure the target FPGA chain.
+*
+* @param    BaseAddress is the base address of the device.
+* @param    Address ranges from 0 to 7 and represents the eight possible .ace
+*           bitstreams that can reside on the CompactFlash.
+*
+* @return   None.
+*
+* @note     Used cryptic var names to avoid conflict with caller's var names.
+*
+******************************************************************************/
+#define XSysAce_mSetCfgAddr(BaseAddress, Address)                             \
+{                                                                             \
+    u32 A66rMask = ((Address) << XSA_CR_CFGADDR_SHIFT) & XSA_CR_CFGADDR_MASK; \
+    u32 C0ntr0l = XSysAce_mGetControlReg(BaseAddress);                    \
+    C0ntr0l &= ~XSA_CR_CFGADDR_MASK;    /* clear current address */           \
+    C0ntr0l |= (A66rMask | XSA_CR_FORCECFGADDR_MASK);                         \
+    XSysAce_mSetControlReg((BaseAddress), C0ntr0l);                           \
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Request then wait for the MPU lock. This is not a forced lock, so we must
+* contend with the configuration controller.
+*
+* @param    BaseAddress is the base address of the device.
+*
+* @return   None.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XSysAce_mWaitForLock(BaseAddress)                                    \
+{                                                                            \
+    XSysAce_mOrControlReg((BaseAddress), XSA_CR_LOCKREQ_MASK);               \
+    while ((XSysAce_mGetStatusReg(BaseAddress) & XSA_SR_MPULOCK_MASK) == 0); \
+}
+
+/*****************************************************************************/
+/**
+*
+* Enable ACE controller interrupts.
+*
+* @param    BaseAddress is the base address of the device.
+*
+* @return   None.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XSysAce_mEnableIntr(BaseAddress, Mask) \
+            XSysAce_mOrControlReg((BaseAddress), (Mask));
+
+
+/*****************************************************************************/
+/**
+*
+* Disable ACE controller interrupts.
+*
+* @param    BaseAddress is the base address of the device.
+*
+* @return   None.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XSysAce_mDisableIntr(BaseAddress, Mask) \
+            XSysAce_mAndControlReg((BaseAddress), ~(Mask));
+
+
+/*****************************************************************************/
+/**
+*
+* Is the CompactFlash ready for a command?
+*
+* @param    BaseAddress is the base address of the device.
+*
+* @return   TRUE if it is ready, FALSE otherwise.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XSysAce_mIsReadyForCmd(BaseAddress) \
+            (XSysAce_mGetStatusReg(BaseAddress) & XSA_SR_RDYFORCMD_MASK)
+
+
+/*****************************************************************************/
+/**
+*
+* Is the ACE controller locked for MPU access?
+*
+* @param    BaseAddress is the base address of the device.
+*
+* @return   TRUE if it is locked, FALSE otherwise.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XSysAce_mIsMpuLocked(BaseAddress) \
+                (XSysAce_mGetStatusReg(BaseAddress) & XSA_SR_MPULOCK_MASK)
+
+
+/*****************************************************************************/
+/**
+*
+* Is the CompactFlash configuration of the target FPGA chain complete?
+*
+* @param    BaseAddress is the base address of the device.
+*
+* @return   TRUE if it is ready, FALSE otherwise.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XSysAce_mIsCfgDone(BaseAddress) \
+            (XSysAce_mGetStatusReg(BaseAddress) & XSA_SR_CFGDONE_MASK)
+
+
+/*****************************************************************************/
+/**
+*
+* Have interrupts been enabled by the user? We look for the interrupt reset
+* bit to be clear (meaning interrupts are armed, even though none may be
+* individually enabled).
+*
+* @param    BaseAddress is the base address of the device.
+*
+* @return   TRUE if it is enabled, FALSE otherwise.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XSysAce_mIsIntrEnabled(BaseAddress) \
+            ((XSysAce_mGetControlReg(BaseAddress) & XSA_CR_RESETIRQ_MASK) == 0)
+
+
+/************************** Function Prototypes ******************************/
+
+int XSysAce_ReadSector(u32 BaseAddress, u32 SectorId,
+                       u8 *BufferPtr);
+int XSysAce_WriteSector(u32 BaseAddress, u32 SectorId,
+                        u8 *BufferPtr);
+
+/*
+ * Utility functions to read and write registers and data buffer
+ */
+u32 XSysAce_RegRead32(u32 Address);
+u16 XSysAce_RegRead16(u32 Address);
+void XSysAce_RegWrite32(u32 Address, u32 Data);
+void XSysAce_RegWrite16(u32 Address, u16 Data);
+
+int XSysAce_ReadDataBuffer(u32 BaseAddress, u8 *BufferPtr,
+                           int NumBytes);
+int XSysAce_WriteDataBuffer(u32 BaseAddress, u8 *BufferPtr,
+                            int NumBytes);
+
+#endif            /* end of protection macro */
+
diff -urN linux-2.4.29/drivers/block/xilinx_sysace/xsysace_selftest.c linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace_selftest.c
--- linux-2.4.29/drivers/block/xilinx_sysace/xsysace_selftest.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/block/xilinx_sysace/xsysace_selftest.c	2005-06-14 02:11:55.000000000 +0100
@@ -0,0 +1,152 @@
+/* $Id: xsysace_selftest.c,v 1.4 2002/06/28 17:24:52 moleres Exp $ */
+/******************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002 Xilinx Inc.
+*       All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xsysace_selftest.c
+*
+* Contains diagnostic functions for the System ACE device and driver. This
+* includes a self-test to make sure communication to the device is possible
+* and the ability to retrieve the ACE controller version.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  06/17/02 work in progress
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xsysace.h"
+#include "xsysace_l.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+*
+* A self-test that simply proves communication to the ACE controller from the
+* device driver by obtaining an MPU lock, verifying it, then releasing it.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+*
+* @return
+*
+* XST_SUCCESS if self-test passes, or XST_FAILURE if an error occurs.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus XSysAce_SelfTest(XSysAce *InstancePtr)
+{
+    XStatus Result;
+
+    XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    /*
+     * Grab a lock (expect immediate success)
+     */
+    Result = XSysAce_Lock(InstancePtr, TRUE);
+    if (Result != XST_SUCCESS)
+    {
+        return Result;
+    }
+
+    /*
+     * Verify the lock was retrieved
+     */
+    if (!XSysAce_mIsMpuLocked(InstancePtr->BaseAddress))
+    {
+        return XST_FAILURE;
+    }
+
+    /*
+     * Release the lock
+     */
+    XSysAce_Unlock(InstancePtr);
+
+    /*
+     * Verify the lock was released
+     */
+    if (XSysAce_mIsMpuLocked(InstancePtr->BaseAddress))
+    {
+        return XST_FAILURE;
+    }
+
+    /*
+     * If there are currently any errors on the device, fail self-test
+     */
+    if (XSysAce_mGetErrorReg(InstancePtr->BaseAddress) != 0)
+    {
+        return XST_FAILURE;
+    }
+
+    return XST_SUCCESS;
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Retrieve the version of the System ACE device.
+*
+* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
+*
+* @return
+*
+* A 16-bit version where the 4 most significant bits are the major version
+* number, the next four bits are the minor version number, and the least
+* significant 8 bits are the revision or build number.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u16 XSysAce_GetVersion(XSysAce *InstancePtr)
+{
+    XASSERT_NONVOID(InstancePtr != NULL);
+    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+    return XSysAce_RegRead16(InstancePtr->BaseAddress + XSA_VR_OFFSET);
+}
+
diff -urN linux-2.4.29/drivers/cdrom/cdrom.c linux-2.4.29-uc1/drivers/cdrom/cdrom.c
--- linux-2.4.29/drivers/cdrom/cdrom.c	2005-01-19 14:09:43.000000000 +0000
+++ linux-2.4.29-uc1/drivers/cdrom/cdrom.c	2005-06-14 02:11:57.000000000 +0100
@@ -246,8 +246,8 @@
 #define CD_DVD		0x80
 
 /* Define this to remove _all_ the debugging messages */
-/* #define ERRLOGMASK CD_NOTHING */
-#define ERRLOGMASK (CD_WARNING)
+#define ERRLOGMASK CD_NOTHING
+/* #define ERRLOGMASK (CD_WARNING) */
 /* #define ERRLOGMASK (CD_WARNING|CD_OPEN|CD_COUNT_TRACKS|CD_CLOSE) */
 /* #define ERRLOGMASK (CD_WARNING|CD_REG_UNREG|CD_DO_IOCTL|CD_OPEN|CD_CLOSE|CD_COUNT_TRACKS) */
 
diff -urN linux-2.4.29/drivers/char/68328serial.c linux-2.4.29-uc1/drivers/char/68328serial.c
--- linux-2.4.29/drivers/char/68328serial.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/68328serial.c	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,1738 @@
+/* 68328serial.c: Serial port driver for 68328 microcontroller
+ *
+ * Copyright (C) 1995       David S. Miller    <davem@caip.rutgers.edu>
+ * Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ * Copyright (C) 1998, 1999 D. Jeff Dionne     <jeff@uclinux.org>
+ * Copyright (C) 1999       Vladimir Gurevich  <vgurevic@cisco.com>
+ * Copyright (C) 2002       David McCullough   <davidm@snapgear.com>
+ *
+ * VZ Support/Fixes             Evan Stawnyczy <e@lineo.ca>
+ * Multiple UART support        Daniel Potts <danielp@cse.unsw.edu.au>
+ * Power management support     Daniel Potts <danielp@cse.unsw.edu.au>
+ * VZ Second Serial Port enable Phil Wilshire
+ * 2.4 support                  David McCullough
+ */
+
+#include <asm/dbg.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/config.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/reboot.h>
+#include <linux/keyboard.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+#include <asm/uaccess.h>
+
+/* (es) */
+/* note: perhaps we can murge these files, so that you can just
+ * 	 define 1 of them, and they can sort that out for themselves
+ */
+#if defined(CONFIG_M68EZ328)
+#include <asm/MC68EZ328.h>
+#else
+#if defined(CONFIG_M68VZ328)
+#include <asm/MC68VZ328.h>
+#else
+#include <asm/MC68328.h>
+#endif /* CONFIG_M68VZ328 */
+#endif /* CONFIG_M68EZ328 */
+
+#include "68328serial.h"
+
+/* Turn off usage of real serial interrupt code, to "support" Copilot */
+#ifdef CONFIG_XCOPILOT_BUGS
+#undef USE_INTS
+#else
+#define USE_INTS
+#endif
+
+static struct m68k_serial m68k_soft[NR_PORTS];
+struct m68k_serial *IRQ_ports[NR_IRQS];
+
+static unsigned int uart_irqs[NR_PORTS] = UART_IRQ_DEFNS;
+
+/* multiple ports are contiguous in memory */
+m68328_uart *uart_addr = (m68328_uart *) USTCNT_ADDR;
+
+struct tty_struct m68k_ttys;
+struct m68k_serial *m68k_consinfo = 0;
+
+#define M68K_CLOCK (16667000) /* FIXME: 16MHz is likely wrong */
+
+DECLARE_TASK_QUEUE(tq_serial);
+
+struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+/* serial subtype definitions */
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+  
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+/* Debugging... DEBUG_INTR is bad to use when one of the zs
+ * lines is your console ;(
+ */
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+
+#define RS_ISR_PASS_LIMIT 256
+
+#define _INLINE_ inline
+
+static void change_speed(struct m68k_serial *info);
+
+static struct tty_struct *serial_table[NR_PORTS];
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+/*
+ *	Setup for console. Argument comes from the boot command line.
+ */
+
+#if defined(CONFIG_M68EZ328ADS) || defined(CONFIG_ALMA_ANS) || defined(CONFIG_DRAGONIXVZ) || defined(CONFIG_CWEZ328) || defined(CONFIG_CWVZ328)
+#define	CONSOLE_BAUD_RATE	115200
+#define	DEFAULT_CBAUD		B115200
+#elif defined(CONFIG_CLIE)
+#define CONSOLE_BAUD_RATE       9600
+#define DEFAULT_CBAUD           9600
+#else
+	/* (es) */
+	/* note: this is messy, but it works, again, perhaps defined somewhere else?*/
+	#ifdef CONFIG_M68VZ328
+	#define CONSOLE_BAUD_RATE	19200
+	#define DEFAULT_CBAUD		B19200
+	#endif
+	/* (/es) */
+#endif
+
+#ifndef CONSOLE_BAUD_RATE
+#define	CONSOLE_BAUD_RATE	9600
+#define	DEFAULT_CBAUD		B9600
+#endif
+
+
+static int m68328_console_initted = 0;
+static int m68328_console_baud    = CONSOLE_BAUD_RATE;
+static int m68328_console_cbaud   = DEFAULT_CBAUD;
+
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the memcpy_fromfs blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static unsigned char tmp_buf[SERIAL_XMIT_SIZE]; /* This is cheating */
+DECLARE_MUTEX(tmp_buf_sem);
+
+static inline int serial_paranoia_check(struct m68k_serial *info,
+					dev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%d, %d) in %s\n";
+	static const char *badinfo =
+		"Warning: null m68k_serial for (%d, %d) in %s\n";
+
+	if (!info) {
+		printk(badinfo, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+	if (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+/*
+ * This is used to figure out the divisor speeds and the timeouts
+ */
+static int baud_table[] = {
+	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
+	9600, 19200, 38400, 57600, 115200, 0 };
+
+#define BAUD_TABLE_SIZE (sizeof(baud_table)/sizeof(baud_table[0]))
+
+/* Sets or clears DTR/RTS on the requested line */
+static inline void m68k_rtsdtr(struct m68k_serial *ss, int set)
+{
+	if (set) {
+		/* set the RTS/CTS line */
+	} else {
+		/* clear it */
+	}
+	return;
+}
+
+/* Utility routines */
+static inline int get_baud(struct m68k_serial *ss)
+{
+	unsigned long result = 115200;
+	unsigned short int baud = uart_addr[ss->line].ubaud;
+	if (GET_FIELD(baud, UBAUD_PRESCALER) == 0x38) result = 38400;
+	result >>= GET_FIELD(baud, UBAUD_DIVIDE);
+
+	return result;
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+	struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
+	m68328_uart *uart = &uart_addr[info->line];
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_stop"))
+		return;
+	
+	save_flags(flags); cli();
+	uart->ustcnt &= ~USTCNT_TXEN;
+	restore_flags(flags);
+}
+
+static void rs_put_char(char ch)
+{
+        int flags, loops = 0;
+
+        save_flags(flags); cli();
+
+	while (!(UTX & UTX_TX_AVAIL) && (loops < 1000)) {
+        	loops++;
+        	udelay(5);
+        }
+
+	UTX_TXDATA = ch;
+        udelay(5);
+        restore_flags(flags);
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+	struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
+	m68328_uart *uart = &uart_addr[info->line];
+	unsigned long flags;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_start"))
+		return;
+	
+	save_flags(flags); cli();
+	if (info->xmit_cnt && info->xmit_buf && !(uart->ustcnt & USTCNT_TXEN)) {
+#ifdef USE_INTS
+		uart->ustcnt |= USTCNT_TXEN | USTCNT_TX_INTR_MASK;
+#else
+		uart->ustcnt |= USTCNT_TXEN;
+#endif
+	}
+	restore_flags(flags);
+}
+
+/* Drop into either the boot monitor or kadb upon receiving a break
+ * from keyboard/console input.
+ */
+static void batten_down_hatches(void)
+{
+	/* Drop into the debugger */
+}
+
+static _INLINE_ void status_handle(struct m68k_serial *info, unsigned short status)
+{
+#if 0
+	if(status & DCD) {
+		if((info->tty->termios->c_cflag & CRTSCTS) &&
+		   ((info->curregs[3] & AUTO_ENAB)==0)) {
+			info->curregs[3] |= AUTO_ENAB;
+			info->pendregs[3] |= AUTO_ENAB;
+			write_zsreg(info->m68k_channel, 3, info->curregs[3]);
+		}
+	} else {
+		if((info->curregs[3] & AUTO_ENAB)) {
+			info->curregs[3] &= ~AUTO_ENAB;
+			info->pendregs[3] &= ~AUTO_ENAB;
+			write_zsreg(info->m68k_channel, 3, info->curregs[3]);
+		}
+	}
+#endif
+	/* If this is console input and this is a
+	 * 'break asserted' status change interrupt
+	 * see if we can drop into the debugger
+	 */
+	if((status & URX_BREAK) && info->break_abort)
+		batten_down_hatches();
+	return;
+}
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static _INLINE_ void rs_sched_event(struct m68k_serial *info,
+				    int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_serial);
+	mark_bh(SERIAL_BH);
+}
+
+static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *regs, unsigned short rx)
+{
+	struct tty_struct *tty = info->tty;
+#ifndef CONFIG_XCOPILOT_BUGS
+	m68328_uart *uart = &uart_addr[info->line];
+#endif
+	unsigned char ch;
+
+	/*
+	 * This do { } while() loop will get ALL chars out of Rx FIFO 
+         */
+#ifndef CONFIG_XCOPILOT_BUGS
+	do {
+#endif	
+		ch = GET_FIELD(rx, URX_RXDATA);
+	
+		if(info->is_cons) {
+			if(URX_BREAK & rx) { /* whee, break received */
+				status_handle(info, rx);
+				return;
+#ifdef CONFIG_MAGIC_SYSRQ
+			} else if (ch == 0x10) { /* ^P */
+				show_state();
+				show_free_areas();
+				show_buffers();
+/*				show_net_buffers(); */
+				return;
+			} else if (ch == 0x12) { /* ^R */
+				machine_restart(NULL);
+				return;
+#endif /* CONFIG_MAGIC_SYSRQ */
+			}
+		}
+
+		if(!tty)
+			goto clear_and_exit;
+		
+		/*
+		 * Make sure that we do not overflow the buffer
+		 */
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			queue_task(&tty->flip.tqueue, &tq_timer);
+			return;
+		}
+
+		if(rx & URX_PARITY_ERROR) {
+			*tty->flip.flag_buf_ptr++ = TTY_PARITY;
+			status_handle(info, rx);
+		} else if(rx & URX_OVRUN) {
+			*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+			status_handle(info, rx);
+		} else if(rx & URX_FRAME_ERROR) {
+			*tty->flip.flag_buf_ptr++ = TTY_FRAME;
+			status_handle(info, rx);
+		} else {
+			*tty->flip.flag_buf_ptr++ = 0; /* XXX */
+		}
+                *tty->flip.char_buf_ptr++ = ch;
+		tty->flip.count++;
+
+#ifndef CONFIG_XCOPILOT_BUGS
+	} while((rx = uart->urx.w) & URX_DATA_READY);
+#endif
+
+	queue_task(&tty->flip.tqueue, &tq_timer);
+
+clear_and_exit:
+	return;
+}
+
+static _INLINE_ void transmit_chars(struct m68k_serial *info)
+{
+	m68328_uart *uart = &uart_addr[info->line];
+
+	if (info->x_char) {
+		/* Send next char */
+		uart->utx.b.txdata = info->x_char;
+		info->x_char = 0;
+		goto clear_and_return;
+	}
+
+	if((info->xmit_cnt <= 0) || info->tty->stopped) {
+		/* That's peculiar... TX ints off */
+		uart->ustcnt &= ~USTCNT_TX_INTR_MASK;
+		goto clear_and_return;
+	}
+
+	/* Send char */
+	uart->utx.b.txdata = info->xmit_buf[info->xmit_tail++];
+	info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+	info->xmit_cnt--;
+
+	if (info->xmit_cnt < WAKEUP_CHARS)
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+	if(info->xmit_cnt <= 0) {
+		/* All done for now... TX ints off */
+		uart->ustcnt &= ~USTCNT_TX_INTR_MASK;
+		goto clear_and_return;
+	}
+
+clear_and_return:
+	/* Clear interrupt (should be auto)*/
+	return;
+}
+
+/*
+ * This is the serial driver's generic interrupt routine
+ */
+void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct m68k_serial * info;
+	m68328_uart *uart;
+	unsigned short rx;
+#ifdef USE_INTS
+	unsigned short tx;
+#endif
+
+	info = IRQ_ports[irq];
+	if(!info)
+	    return;
+
+	uart = &uart_addr[info->line];
+	rx = uart->urx.w;
+
+#ifdef USE_INTS
+	tx = uart->utx.w;
+
+	if (rx & URX_DATA_READY) receive_chars(info, regs, rx);
+	if (tx & UTX_TX_AVAIL)   transmit_chars(info);
+#else
+	receive_chars(info, regs, rx);		
+#endif
+	return;
+}
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct m68k_serial	*info = (struct m68k_serial *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+#if 0
+	if (clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+	}
+#endif   
+}
+
+/*
+ * This routine is called from the scheduler tqueue when the interrupt
+ * routine has signalled that a hangup has occurred.  The path of
+ * hangup processing is:
+ *
+ * 	serial interrupt routine -> (scheduler tqueue) ->
+ * 	do_serial_hangup() -> tty->hangup() -> rs_hangup()
+ * 
+ */
+static void do_serial_hangup(void *private_)
+{
+	struct m68k_serial	*info = (struct m68k_serial *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	tty_hangup(tty);
+}
+
+
+static int startup(struct m68k_serial * info)
+{
+	m68328_uart *uart = &uart_addr[info->line];
+	unsigned long flags;
+	
+	if (info->flags & S_INITIALIZED)
+		return 0;
+
+	if (!info->xmit_buf) {
+		info->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL);
+		if (!info->xmit_buf)
+			return -ENOMEM;
+	}
+
+	save_flags(flags); cli();
+
+	/*
+	 * Clear the FIFO buffers and disable them
+	 * (they will be reenabled in change_speed())
+	 */
+
+	uart->ustcnt = USTCNT_UEN;
+	info->xmit_fifo_size = 1;
+	uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_TXEN;
+	(void)uart->urx.w;
+
+	/*
+	 * Finally, enable sequencing and interrupts
+	 */
+#ifdef USE_INTS
+	uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | 
+                 USTCNT_RX_INTR_MASK | USTCNT_TX_INTR_MASK;
+#else
+	uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_RX_INTR_MASK;
+#endif
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+
+	/*
+	 * and set the speed of the serial port
+	 */
+
+	change_speed(info);
+
+	info->flags |= S_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct m68k_serial * info)
+{
+	m68328_uart *uart = &uart_addr[info->line];
+	unsigned long	flags;
+
+	uart->ustcnt = 0; /* All off! */
+	if (!(info->flags & S_INITIALIZED))
+		return;
+
+	save_flags(flags); cli(); /* Disable interrupts */
+	
+	if (info->xmit_buf) {
+		free_page((unsigned long) info->xmit_buf);
+		info->xmit_buf = 0;
+	}
+
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+	
+	info->flags &= ~S_INITIALIZED;
+	restore_flags(flags);
+}
+
+struct {
+	int divisor, prescale;
+}
+#ifndef CONFIG_M68VZ328
+ hw_baud_table[18] = {
+	{0,0}, /* 0 */
+	{0,0}, /* 50 */
+	{0,0}, /* 75 */
+	{0,0}, /* 110 */
+	{0,0}, /* 134 */
+	{0,0}, /* 150 */
+	{0,0}, /* 200 */
+	{7,0x26}, /* 300 */
+	{6,0x26}, /* 600 */
+	{5,0x26}, /* 1200 */
+	{0,0}, /* 1800 */
+	{4,0x26}, /* 2400 */
+	{3,0x26}, /* 4800 */
+	{2,0x26}, /* 9600 */
+	{1,0x26}, /* 19200 */
+	{0,0x26}, /* 38400 */
+	{1,0x38}, /* 57600 */
+	{0,0x38}, /* 115200 */
+};
+#else
+ hw_baud_table[18] = {
+                 {0,0}, /* 0 */
+                 {0,0}, /* 50 */
+                 {0,0}, /* 75 */
+                 {0,0}, /* 110 */
+                 {0,0}, /* 134 */
+                 {0,0}, /* 150 */
+                 {0,0}, /* 200 */
+                 {0,0}, /* 300 */
+                 {7,0x26}, /* 600 */
+                 {6,0x26}, /* 1200 */
+                 {0,0}, /* 1800 */
+                 {5,0x26}, /* 2400 */
+                 {4,0x26}, /* 4800 */
+                 {3,0x26}, /* 9600 */
+                 {2,0x26}, /* 19200 */
+                 {1,0x26}, /* 38400 */
+                 {2,0x38}, /* 57600 */
+                 {1,0x38}, /* 115200 */
+}; 
+#endif
+/* rate = 1036800 / ((65 - prescale) * (1<<divider)) */
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void change_speed(struct m68k_serial *info)
+{
+	m68328_uart *uart = &uart_addr[info->line];
+	unsigned short port;
+	unsigned short ustcnt;
+	unsigned cflag;
+	int	i;
+
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+	if (!(port = info->port))
+		return;
+
+	ustcnt = uart->ustcnt;
+	uart->ustcnt = ustcnt & ~USTCNT_TXEN;
+
+	i = cflag & CBAUD;
+        if (i & CBAUDEX) {
+                i = (i & ~CBAUDEX) + B38400;
+        }
+
+	info->baud = baud_table[i];
+	uart->ubaud = PUT_FIELD(UBAUD_DIVIDE,    hw_baud_table[i].divisor) | 
+		PUT_FIELD(UBAUD_PRESCALER, hw_baud_table[i].prescale);
+
+	ustcnt &= ~(USTCNT_PARITYEN | USTCNT_ODD_EVEN | USTCNT_STOP | USTCNT_8_7);
+	
+	if ((cflag & CSIZE) == CS8)
+		ustcnt |= USTCNT_8_7;
+		
+	if (cflag & CSTOPB)
+		ustcnt |= USTCNT_STOP;
+
+	if (cflag & PARENB)
+		ustcnt |= USTCNT_PARITYEN;
+	if (cflag & PARODD)
+		ustcnt |= USTCNT_ODD_EVEN;
+	
+#ifdef CONFIG_68328_SERIAL_RTS_CTS
+	if (cflag & CRTSCTS) {
+		uart->utx.w &= ~ UTX_NOCTS;
+	} else {
+		uart->utx.w |= UTX_NOCTS;
+	}
+#endif
+
+	ustcnt |= USTCNT_TXEN;
+	
+	uart->ustcnt = ustcnt;
+	return;
+}
+
+/*
+ * Fair output driver allows a process to speak.
+ */
+static void rs_fair_output(void)
+{
+	int left;		/* Output no more than that */
+	unsigned long flags;
+	struct m68k_serial *info = &m68k_soft[0];
+	char c;
+
+	if (info == 0) return;
+	if (info->xmit_buf == 0) return;
+
+	save_flags(flags);  cli();
+	left = info->xmit_cnt;
+	while (left != 0) {
+		c = info->xmit_buf[info->xmit_tail];
+		info->xmit_tail = (info->xmit_tail+1) & (SERIAL_XMIT_SIZE-1);
+		info->xmit_cnt--;
+		restore_flags(flags);
+
+		rs_put_char(c);
+
+		save_flags(flags);  cli();
+		left = MIN(info->xmit_cnt, left-1);
+	}
+
+	/* Last character is being transmitted now (hopefully). */
+	udelay(5);
+
+	restore_flags(flags);
+	return;
+}
+
+/*
+ * m68k_console_print is registered for printk.
+ */
+void console_print_68328(const char *p)
+{
+	char c;
+	
+	while((c=*(p++)) != 0) {
+		if(c == '\n')
+			rs_put_char('\r');
+		rs_put_char(c);
+	}
+
+	/* Comment this if you want to have a strict interrupt-driven output */
+	rs_fair_output();
+
+	return;
+}
+
+static void rs_set_ldisc(struct tty_struct *tty)
+{
+	struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_set_ldisc"))
+		return;
+
+	info->is_cons = (tty->termios->c_line == N_TTY);
+	
+	printk("ttyS%d console mode %s\n", info->line, info->is_cons ? "on" : "off");
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
+	m68328_uart *uart = &uart_addr[info->line];
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
+		return;
+#ifndef USE_INTS
+	for(;;) {
+#endif
+
+	/* Enable transmitter */
+	save_flags(flags); cli();
+
+	if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
+			!info->xmit_buf) {
+		restore_flags(flags);
+		return;
+	}
+
+#ifdef USE_INTS
+	uart->ustcnt |= USTCNT_TXEN | USTCNT_TX_INTR_MASK;
+#else
+	uart->ustcnt |= USTCNT_TXEN;
+#endif
+
+#ifdef USE_INTS
+	if (uart->utx.w & UTX_TX_AVAIL) {
+#else
+	if (1) {
+#endif
+		/* Send char */
+		uart->utx.b.txdata = info->xmit_buf[info->xmit_tail++];
+		info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+		info->xmit_cnt--;
+	}
+
+#ifndef USE_INTS
+	while (!(uart->utx.w & UTX_TX_AVAIL)) udelay(5);
+	}
+#endif
+	restore_flags(flags);
+}
+
+extern void console_printn(const char * b, int count);
+
+static int rs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	int	c, total = 0;
+	struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
+	m68328_uart *uart = &uart_addr[info->line];
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_write"))
+		return 0;
+
+	if (!tty || !info->xmit_buf)
+		return 0;
+
+	save_flags(flags);
+	while (1) {
+		cli();		
+		c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				   SERIAL_XMIT_SIZE - info->xmit_head));
+		if (c <= 0)
+			break;
+
+		if (from_user) {
+			down(&tmp_buf_sem);
+			copy_from_user(tmp_buf, buf, c);
+			c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				       SERIAL_XMIT_SIZE - info->xmit_head));
+			memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
+			up(&tmp_buf_sem);
+		} else
+			memcpy(info->xmit_buf + info->xmit_head, buf, c);
+		info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+		info->xmit_cnt += c;
+		restore_flags(flags);
+		buf += c;
+		count -= c;
+		total += c;
+	}
+
+	if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
+		/* Enable transmitter */
+		cli();		
+#ifndef USE_INTS
+		while(info->xmit_cnt) {
+#endif
+
+		uart->ustcnt |= USTCNT_TXEN;
+#ifdef USE_INTS
+		uart->ustcnt |= USTCNT_TX_INTR_MASK;
+#else
+		while (!(uart->utx.w & UTX_TX_AVAIL)) udelay(5);
+#endif
+		if (uart->utx.w & UTX_TX_AVAIL) {
+			uart->utx.b.txdata = info->xmit_buf[info->xmit_tail++];
+			info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+			info->xmit_cnt--;
+		}
+
+#ifndef USE_INTS
+		}
+#endif
+		restore_flags(flags);
+	}
+	restore_flags(flags);
+	return total;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
+	int	ret;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
+		return 0;
+	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
+	if (ret < 0)
+		ret = 0;
+	return ret;
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+		return 0;
+	return info->xmit_cnt;
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+		return;
+	cli();
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+	sti();
+	wake_up_interruptible(&tty->write_wait);
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct * tty)
+{
+	struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+		return;
+	
+	if (I_IXOFF(tty))
+		info->x_char = STOP_CHAR(tty);
+
+	/* Turn off RTS line (do this atomic) */
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+	struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+		return;
+	
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			info->x_char = START_CHAR(tty);
+	}
+
+	/* Assert RTS line (do this atomic) */
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int get_serial_info(struct m68k_serial * info,
+			   struct serial_struct * retinfo)
+{
+	struct serial_struct tmp;
+  
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = info->type;
+	tmp.line = info->line;
+	tmp.port = info->port;
+	tmp.irq = info->irq;
+	tmp.flags = info->flags;
+	tmp.baud_base = info->baud_base;
+	tmp.close_delay = info->close_delay;
+	tmp.closing_wait = info->closing_wait;
+	tmp.custom_divisor = info->custom_divisor;
+	copy_to_user(retinfo,&tmp,sizeof(*retinfo));
+	return 0;
+}
+
+static int set_serial_info(struct m68k_serial * info,
+			   struct serial_struct * new_info)
+{
+	struct serial_struct new_serial;
+	struct m68k_serial old_info;
+	int 			retval = 0;
+
+	if (!new_info)
+		return -EFAULT;
+	copy_from_user(&new_serial,new_info,sizeof(new_serial));
+	old_info = *info;
+
+	if (!suser()) {
+		if ((new_serial.baud_base != info->baud_base) ||
+		    (new_serial.type != info->type) ||
+		    (new_serial.close_delay != info->close_delay) ||
+		    ((new_serial.flags & ~S_USR_MASK) !=
+		     (info->flags & ~S_USR_MASK)))
+			return -EPERM;
+		info->flags = ((info->flags & ~S_USR_MASK) |
+			       (new_serial.flags & S_USR_MASK));
+		info->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	if (info->count > 1)
+		return -EBUSY;
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+	info->baud_base = new_serial.baud_base;
+	info->flags = ((info->flags & ~S_FLAGS) |
+			(new_serial.flags & S_FLAGS));
+	info->type = new_serial.type;
+	info->close_delay = new_serial.close_delay;
+	info->closing_wait = new_serial.closing_wait;
+
+check_and_exit:
+	retval = startup(info);
+	return retval;
+}
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space. 
+ */
+static int get_lsr_info(struct m68k_serial * info, unsigned int *value)
+{
+#ifdef CONFIG_68328_SERIAL_RTS_CTS
+	m68328_uart *uart = &uart_addr[info->line];
+#endif
+	unsigned char status;
+
+	cli();
+#ifdef CONFIG_68328_SERIAL_RTS_CTS
+	status = (uart->utx.w & UTX_CTS_STAT) ? 1 : 0;
+#else
+	status = 0;
+#endif
+	sti();
+	put_user(status,value);
+	return 0;
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void send_break(	struct m68k_serial * info, int duration)
+{
+#ifdef USE_INTS	
+	m68328_uart *uart = &uart_addr[info->line];
+#endif
+	unsigned long flags;
+	if (!info->port)
+		return;
+	current->state = TASK_INTERRUPTIBLE;
+	save_flags(flags);
+	cli();
+#ifdef USE_INTS	
+	uart->utx.w |= UTX_SEND_BREAK;
+	schedule_timeout(duration);
+	uart->utx.w &= ~UTX_SEND_BREAK;
+#endif		
+	restore_flags(flags);
+}
+
+static int rs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	int error;
+	struct m68k_serial * info = (struct m68k_serial *)tty->driver_data;
+	int retval;
+
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
+	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+	
+	switch (cmd) {
+		case TCSBRK:	/* SVID version: non-zero arg --> no break */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (!arg)
+				send_break(info, HZ/4);	/* 1/4 second */
+			return 0;
+		case TCSBRKP:	/* support for POSIX tcsendbreak() */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+			return 0;
+		case TIOCGSOFTCAR:
+			error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long));
+			if (error)
+				return error;
+			put_user(C_CLOCAL(tty) ? 1 : 0,
+				    (unsigned long *) arg);
+			return 0;
+		case TIOCSSOFTCAR:
+			get_user(arg, (unsigned long *) arg);
+			tty->termios->c_cflag =
+				((tty->termios->c_cflag & ~CLOCAL) |
+				 (arg ? CLOCAL : 0));
+			return 0;
+		case TIOCGSERIAL:
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+						sizeof(struct serial_struct));
+			if (error)
+				return error;
+			return get_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSSERIAL:
+			return set_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSERGETLSR: /* Get line status register */
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+				sizeof(unsigned int));
+			if (error)
+				return error;
+			else
+			    return get_lsr_info(info, (unsigned int *) arg);
+
+		case TIOCSERGSTRUCT:
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+						sizeof(struct m68k_serial));
+			if (error)
+				return error;
+			copy_to_user((struct m68k_serial *) arg,
+				    info, sizeof(struct m68k_serial));
+			return 0;
+			
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
+
+	if (tty->termios->c_cflag == old_termios->c_cflag)
+		return;
+
+	change_speed(info);
+
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+	
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * S structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+	struct m68k_serial * info = (struct m68k_serial *)tty->driver_data;
+	m68328_uart *uart = &uart_addr[info->line];
+	unsigned long flags;
+
+	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+		return;
+	
+	save_flags(flags); cli();
+	
+	if (tty_hung_up_p(filp)) {
+		restore_flags(flags);
+		return;
+	}
+	
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  Info->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+		       "info->count is %d\n", info->count);
+		info->count = 1;
+	}
+	if (--info->count < 0) {
+		printk("rs_close: bad serial port count for ttyS%d: %d\n",
+		       info->line, info->count);
+		info->count = 0;
+	}
+	if (info->count) {
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= S_CLOSING;
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & S_NORMAL_ACTIVE)
+		info->normal_termios = *tty->termios;
+	if (info->flags & S_CALLOUT_ACTIVE)
+		info->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != S_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+
+	uart->ustcnt &= ~USTCNT_RXEN;
+	uart->ustcnt &= ~(USTCNT_RXEN | USTCNT_RX_INTR_MASK);
+
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (tty->ldisc.num != tty_ldiscs[N_TTY].num) {
+		if (tty->ldisc.close)
+			(tty->ldisc.close)(tty);
+		tty->ldisc = tty_ldiscs[N_TTY];
+		tty->termios->c_line = N_TTY;
+		if (tty->ldisc.open)
+			(tty->ldisc.open)(tty);
+	}
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(S_NORMAL_ACTIVE|S_CALLOUT_ACTIVE|
+			 S_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	restore_flags(flags);
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+void rs_hangup(struct tty_struct *tty)
+{
+	struct m68k_serial * info = (struct m68k_serial *)tty->driver_data;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
+		return;
+	
+	rs_flush_buffer(tty);
+	shutdown(info);
+	info->event = 0;
+	info->count = 0;
+	info->flags &= ~(S_NORMAL_ACTIVE|S_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file * filp,
+			   struct m68k_serial *info)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int		retval;
+	int		do_clocal = 0;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (info->flags & S_CLOSING) {
+		interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		if (info->flags & S_HUP_NOTIFY)
+			return -EAGAIN;
+		else
+			return -ERESTARTSYS;
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & S_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+		    (info->flags & S_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+		    return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+		    (info->flags & S_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+		    return -EBUSY;
+		info->flags |= S_CALLOUT_ACTIVE;
+		return 0;
+	}
+	
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & S_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= S_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & S_CALLOUT_ACTIVE) {
+		if (info->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+	
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, info->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+
+	info->count--;
+	info->blocked_open++;
+	while (1) {
+		cli();
+		if (!(info->flags & S_CALLOUT_ACTIVE))
+			m68k_rtsdtr(info, 1);
+		sti();
+		current->state = TASK_INTERRUPTIBLE;
+		if (tty_hung_up_p(filp) ||
+		    !(info->flags & S_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & S_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;	
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & S_CALLOUT_ACTIVE) &&
+		    !(info->flags & S_CLOSING) && do_clocal)
+			break;
+                if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&info->open_wait, &wait);
+	if (!tty_hung_up_p(filp))
+		info->count++;
+	info->blocked_open--;
+
+	if (retval)
+		return retval;
+	info->flags |= S_NORMAL_ACTIVE;
+	return 0;
+}	
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its S structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+int rs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct m68k_serial	*info;
+	int 			retval, line;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	
+	if (line >= NR_PORTS || line < 0) /* we have exactly one */
+		return -ENODEV;
+
+	info = &m68k_soft[line];
+
+	if (serial_paranoia_check(info, tty->device, "rs_open"))
+		return -ENODEV;
+
+	info->count++;
+	tty->driver_data = info;
+	info->tty = tty;
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval)
+		return retval;
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+		return retval;
+	}
+
+	if ((info->count == 1) && (info->flags & S_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->normal_termios;
+		else 
+			*tty->termios = info->callout_termios;
+		change_speed(info);
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+	return 0;
+}
+
+/* Finally, routines used to initialize the serial driver. */
+
+static void show_serial_version(void)
+{
+	printk("MC68328 serial driver version 1.00\n");
+}
+
+#ifdef CONFIG_PM
+/* Serial Power management
+ *  The console (currently fixed at line 0) is a special case for power
+ *  management because the kernel is so chatty. The console will be 
+ *  explicitly disabled my our power manager as the last minute, so we won't
+ *  mess with it here.
+ */
+static struct pm_dev *serial_pm[NR_PORTS];
+
+static int serial_pm_callback(struct pm_dev *dev, pm_request_t request, void *data)
+{
+	struct m68k_serial *info = (struct m68k_serial *)dev->data;
+
+	if(info == NULL)
+		return -1;
+
+	/* special case for line 0 - pm restores it */
+	if(info->line == 0)
+		return 0; 
+
+	switch (request) {
+	case PM_SUSPEND:
+		shutdown(info);
+		break;
+
+	case PM_RESUME:
+		startup(info);
+		break;
+	}
+	return 0;
+}
+
+void shutdown_console(void)
+{
+	struct m68k_serial *info = &m68k_soft[0];
+
+	/* HACK: wait a bit for any pending printk's to be dumped */
+	{
+		int i = 10000;
+		while(i--);
+	}
+
+	shutdown(info);
+}
+
+void startup_console(void)
+{
+	struct m68k_serial *info = &m68k_soft[0];
+	startup(info);
+}
+#endif
+
+
+/* rs_init inits the driver */
+static int __init
+rs68328_init(void)
+{
+	int flags, i;
+	struct m68k_serial *info;
+	
+	/* Setup base handler, and timer table. */
+	init_bh(SERIAL_BH, do_serial_bh);
+	show_serial_version();
+
+	/* Initialize the tty_driver structure */
+	/* SPARC: Not all of this is exactly right for us. */
+	
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+	serial_driver.name = "ttyS";
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64;
+	serial_driver.num = NR_PORTS;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+	serial_driver.init_termios.c_cflag = 
+			m68328_console_cbaud | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = rs_open;
+	serial_driver.close = rs_close;
+	serial_driver.write = rs_write;
+	serial_driver.flush_chars = rs_flush_chars;
+	serial_driver.write_room = rs_write_room;
+	serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	serial_driver.flush_buffer = rs_flush_buffer;
+	serial_driver.ioctl = rs_ioctl;
+	serial_driver.throttle = rs_throttle;
+	serial_driver.unthrottle = rs_unthrottle;
+	serial_driver.set_termios = rs_set_termios;
+	serial_driver.stop = rs_stop;
+	serial_driver.start = rs_start;
+	serial_driver.hangup = rs_hangup;
+	serial_driver.set_ldisc = rs_set_ldisc;
+
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+	callout_driver.name = "cua";
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register serial driver\n");
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+	
+	save_flags(flags); cli();
+
+	for(i=0;i<NR_PORTS;i++) {
+
+	    info = &m68k_soft[i];
+	    info->magic = SERIAL_MAGIC;
+	    info->port = &uart_addr[i];
+	    info->tty = 0;
+	    info->irq = uart_irqs[i];
+	    info->custom_divisor = 16;
+	    info->close_delay = 50;
+	    info->closing_wait = 3000;
+	    info->x_char = 0;
+	    info->event = 0;
+	    info->count = 0;
+	    info->blocked_open = 0;
+	    info->tqueue.routine = do_softint;
+	    info->tqueue.data = info;
+	    info->tqueue_hangup.routine = do_serial_hangup;
+	    info->tqueue_hangup.data = info;
+	    info->callout_termios =callout_driver.init_termios;
+	    info->normal_termios = serial_driver.init_termios;
+	    init_waitqueue_head(&info->open_wait);
+	    init_waitqueue_head(&info->close_wait);
+	    info->line = i;
+	    info->is_cons = 1; /* Means shortcuts work */
+	    
+	    printk("%s%d at 0x%08x (irq = %d)", serial_driver.name, info->line, 
+		   info->port, info->irq);
+	    printk(" is a builtin MC68328 UART\n");
+	    
+	    IRQ_ports[info->irq] = info;	/* waste of space */
+
+#ifdef CONFIG_M68VZ328
+		if (i > 0)
+			PJSEL &= 0xCF;  /* PSW enable second port output */
+#endif
+
+	    if (request_irq(uart_irqs[i],
+			    rs_interrupt,
+			    IRQ_FLG_STD,
+			    "M68328_UART", NULL))
+                panic("Unable to attach 68328 serial interrupt\n");
+#ifdef CONFIG_PM
+	    serial_pm[i] = pm_register(PM_SYS_DEV, PM_SYS_COM, serial_pm_callback);
+	    if (serial_pm[i])
+		    serial_pm[i]->data = info;
+#endif
+	}
+	restore_flags(flags);
+	return 0;
+}
+
+
+
+/*
+ * register_serial and unregister_serial allows for serial ports to be
+ * configured at run-time, to support PCMCIA modems.
+ */
+/* SPARC: Unused at this time, just here to make things link. */
+int register_serial(struct serial_struct *req)
+{
+	return -1;
+}
+
+void unregister_serial(int line)
+{
+	return;
+}
+	
+module_init(rs68328_init);
+/* DAVIDM module_exit(rs68328_fini); */
+
+
+
+static void m68328_set_baud(void)
+{
+	unsigned short ustcnt;
+	int	i;
+
+	ustcnt = USTCNT;
+	USTCNT = ustcnt & ~USTCNT_TXEN;
+
+again:
+	for (i = 0; i < sizeof(baud_table) / sizeof(baud_table[0]); i++)
+		if (baud_table[i] == m68328_console_baud)
+			break;
+	if (i >= sizeof(baud_table) / sizeof(baud_table[0])) {
+		m68328_console_baud = 9600;
+		goto again;
+	}
+
+	UBAUD = PUT_FIELD(UBAUD_DIVIDE,    hw_baud_table[i].divisor) | 
+		PUT_FIELD(UBAUD_PRESCALER, hw_baud_table[i].prescale);
+	ustcnt &= ~(USTCNT_PARITYEN | USTCNT_ODD_EVEN | USTCNT_STOP | USTCNT_8_7);
+	ustcnt |= USTCNT_8_7;
+	ustcnt |= USTCNT_TXEN;
+	USTCNT = ustcnt;
+	m68328_console_initted = 1;
+	return;
+}
+
+
+int m68328_console_setup(struct console *cp, char *arg)
+{
+	int		i, n = CONSOLE_BAUD_RATE;
+
+	if (!cp)
+		return(-1);
+
+	if (arg)
+		n = simple_strtoul(arg,NULL,0);
+
+	for (i = 0; i < BAUD_TABLE_SIZE; i++)
+		if (baud_table[i] == n)
+			break;
+	if (i < BAUD_TABLE_SIZE) {
+		m68328_console_baud = n;
+		m68328_console_cbaud = 0;
+		if (i > 15) {
+			m68328_console_cbaud |= CBAUDEX;
+			i -= 15;
+		}
+		m68328_console_cbaud |= i;
+	}
+
+	m68328_set_baud(); /* make sure baud rate changes */
+	return(0);
+}
+
+
+static kdev_t m68328_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+
+void m68328_console_write (struct console *co, const char *str,
+			   unsigned int count)
+{
+	if (!m68328_console_initted)
+		m68328_set_baud();
+    while (count--) {
+        if (*str == '\n')
+           rs_put_char('\r');
+        rs_put_char( *str++ );
+    }
+}
+
+
+static struct console m68328_driver = {
+	name:		"ttyS",
+	write:		m68328_console_write,
+	read:		NULL,
+	device:		m68328_console_device,
+	unblank:	NULL,
+	setup:		m68328_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+	cflag:		0,
+	next:		NULL
+};
+
+
+void m68328_console_init(void)
+{
+	register_console(&m68328_driver);
+}
+
diff -urN linux-2.4.29/drivers/char/68328serial.h linux-2.4.29-uc1/drivers/char/68328serial.h
--- linux-2.4.29/drivers/char/68328serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/68328serial.h	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,198 @@
+/* 68328serial.h: Definitions for the mc68328 serial driver.
+ *
+ * Copyright (C) 1995       David S. Miller    <davem@caip.rutgers.edu>
+ * Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ * Copyright (C) 1998, 1999 D. Jeff Dionne     <jeff@uclinux.org>
+ * Copyright (C) 1999       Vladimir Gurevich  <vgurevic@cisco.com>
+ *
+ * VZ Support/Fixes             Evan Stawnyczy <e@lineo.ca>
+ */
+
+#ifndef _MC683XX_SERIAL_H
+#define _MC683XX_SERIAL_H
+
+#include <linux/config.h>
+
+struct serial_struct {
+	int	type;
+	int	line;
+	int	port;
+	int	irq;
+	int	flags;
+	int	xmit_fifo_size;
+	int	custom_divisor;
+	int	baud_base;
+	unsigned short	close_delay;
+	char	reserved_char[2];
+	int	hub6;  /* FIXME: We don't have AT&T Hub6 boards! */
+	unsigned short	closing_wait; /* time to wait before closing */
+	unsigned short	closing_wait2; /* no longer used... */
+	int	reserved[4];
+};
+
+/*
+ * For the close wait times, 0 means wait forever for serial port to
+ * flush its output.  65535 means don't wait at all.
+ */
+#define S_CLOSING_WAIT_INF	0
+#define S_CLOSING_WAIT_NONE	65535
+
+/*
+ * Definitions for S_struct (and serial_struct) flags field
+ */
+#define S_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes 
+				   on the callout port */
+#define S_FOURPORT  0x0002	/* Set OU1, OUT2 per AST Fourport settings */
+#define S_SAK	0x0004	/* Secure Attention Key (Orange book) */
+#define S_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
+
+#define S_SPD_MASK	0x0030
+#define S_SPD_HI	0x0010	/* Use 56000 instead of 38400 bps */
+
+#define S_SPD_VHI	0x0020  /* Use 115200 instead of 38400 bps */
+#define S_SPD_CUST	0x0030  /* Use user-specified divisor */
+
+#define S_SKIP_TEST	0x0040 /* Skip UART test during autoconfiguration */
+#define S_AUTO_IRQ  0x0080 /* Do automatic IRQ during autoconfiguration */
+#define S_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
+#define S_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
+#define S_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
+
+#define S_FLAGS	0x0FFF	/* Possible legal S flags */
+#define S_USR_MASK 0x0430	/* Legal flags that non-privileged
+				 * users can set or reset */
+
+/* Internal flags used only by kernel/chr_drv/serial.c */
+#define S_INITIALIZED	0x80000000 /* Serial port was initialized */
+#define S_CALLOUT_ACTIVE	0x40000000 /* Call out device is active */
+#define S_NORMAL_ACTIVE	0x20000000 /* Normal device is active */
+#define S_BOOT_AUTOCONF	0x10000000 /* Autoconfigure port on bootup */
+#define S_CLOSING		0x08000000 /* Serial port is closing */
+#define S_CTS_FLOW		0x04000000 /* Do CTS flow control */
+#define S_CHECK_CD		0x02000000 /* i.e., CLOCAL */
+
+/* Software state per channel */
+
+#ifdef __KERNEL__
+
+/*
+ * I believe this is the optimal setting that reduces the number of interrupts.
+ * At high speeds the output might become a little "bursted" (use USTCNT_TXHE
+ * if that bothers you), but in most cases it will not, since we try to 
+ * transmit characters every time rs_interrupt is called. Thus, quite often
+ * you'll see that a receive interrupt occures before the transmit one.
+ *                                  -- Vladimir Gurevich
+ */
+#define USTCNT_TX_INTR_MASK (USTCNT_TXEE)
+
+/*
+ * 68328 and 68EZ328 UARTS are a little bit different. EZ328 has special
+ * "Old data interrupt" which occures whenever the data stay in the FIFO
+ * longer than 30 bits time. This allows us to use FIFO without compromising
+ * latency. '328 does not have this feature and without the real  328-based
+ * board I would assume that RXRE is the safest setting.
+ *
+ * For EZ328 I use RXHE (Half empty) interrupt to reduce the number of
+ * interrupts. RXFE (receive queue full) causes the system to loose data
+ * at least at 115200 baud
+ *
+ * If your board is busy doing other stuff, you might consider to use
+ * RXRE (data ready intrrupt) instead.
+ *
+ * The other option is to make these INTR masks run-time configurable, so
+ * that people can dynamically adapt them according to the current usage.
+ *                                  -- Vladimir Gurevich
+ */
+
+/* (es) */
+#if defined(CONFIG_M68EZ328) || defined(CONFIG_M68VZ328)
+#define USTCNT_RX_INTR_MASK (USTCNT_RXHE | USTCNT_ODEN)
+#elif defined(CONFIG_M68328)
+#define USTCNT_RX_INTR_MASK (USTCNT_RXRE)
+#else
+#error Please, define the Rx interrupt events for your CPU
+#endif
+/* (/es) */
+
+/*
+ * This is our internal structure for each serial port's state.
+ * 
+ * Many fields are paralleled by the structure used by the serial_struct
+ * structure.
+ *
+ * For definitions of the flags field, see tty.h
+ */
+
+struct m68k_serial {
+	char soft_carrier;  /* Use soft carrier on this channel */
+	char break_abort;   /* Is serial console in, so process brk/abrt */
+	char is_cons;       /* Is this our console. */
+
+	/* We need to know the current clock divisor
+	 * to read the bps rate the chip has currently
+	 * loaded.
+	 */
+	unsigned char clk_divisor;  /* May be 1, 16, 32, or 64 */
+	int baud;
+	int			magic;
+	int			baud_base;
+	int			port;
+	int			irq;
+	int			flags; 		/* defined in tty.h */
+	int			type; 		/* UART type */
+	struct tty_struct 	*tty;
+	int			read_status_mask;
+	int			ignore_status_mask;
+	int			timeout;
+	int			xmit_fifo_size;
+	int			custom_divisor;
+	int			x_char;	/* xon/xoff character */
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int			count;	    /* # of fd on device */
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+	unsigned char 		*xmit_buf;
+	int			xmit_head;
+	int			xmit_tail;
+	int			xmit_cnt;
+	struct tq_struct	tqueue;
+	struct tq_struct	tqueue_hangup;
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+};
+
+
+#define SERIAL_MAGIC 0x5301
+
+/*
+ * The size of the serial xmit buffer is 1 page, or 4096 bytes
+ */
+#define SERIAL_XMIT_SIZE 4096
+
+/*
+ * Events are used to schedule things to happen at timer-interrupt
+ * time, instead of at rs interrupt time.
+ */
+#define RS_EVENT_WRITE_WAKEUP	0
+
+/* 
+ * Define the number of ports supported and their irqs.
+ */
+#ifndef CONFIG_68328_SERIAL_UART2
+#define NR_PORTS 1
+#define UART_IRQ_DEFNS {UART_IRQ_NUM}
+#else
+#define NR_PORTS 2
+#define UART_IRQ_DEFNS {UART1_IRQ_NUM, UART2_IRQ_NUM}
+#endif
+
+#endif /* __KERNEL__ */
+#endif /* !(_MC683XX_SERIAL_H) */
diff -urN linux-2.4.29/drivers/char/bf533_serial.c linux-2.4.29-uc1/drivers/char/bf533_serial.c
--- linux-2.4.29/drivers/char/bf533_serial.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/bf533_serial.c	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,1601 @@
+/* bf533_serial.c: Serial driver for BlackFin BF533 DSP internal UART.
+ * Copyright (c) 2003	Bas Vermeulen <bas@buyways.nl>,
+ * 			BuyWays B.V. (www.buyways.nl)
+ *
+ * Based heavily on blkfinserial.c
+ * blkfinserial.c: Serial driver for BlackFin DSP internal USRTs.
+ * Copyright(c) 2003	Metrowerks	<mwaddel@metrowerks.com>
+ * Copyright(c)	2001	Tony Z. Kou	<tonyko@arcturusnetworks.com>
+ * Copyright(c)	2001-2002 Arcturus Networks Inc. <www.arcturusnetworks.com>
+ * 
+ * Based on code from 68328 version serial driver imlpementation which was:
+ * Copyright (C) 1995       David S. Miller    <davem@caip.rutgers.edu>
+ * Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ * Copyright (C) 1998, 1999 D. Jeff Dionne     <jeff@uclinux.org>
+ * Copyright (C) 1999       Vladimir Gurevich  <vgurevic@cisco.com> 
+ */
+ 
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/config.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/reboot.h>
+#include <linux/keyboard.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+#include <asm/uaccess.h>
+
+#include "bf533_serial.h"
+
+#define USE_INTS
+#define SERIAL_PARANOIA_CHECK
+
+#define SYNC_ALL	__asm__ __volatile__ ("ssync;\n")
+#define ACCESS_LATCH(idx)	UART_LCR(idx) |= UART_LCR_DLAB;
+#define ACCESS_PORT_IER(idx)	UART_LCR(idx) &= (~UART_LCR_DLAB);
+#ifndef CONFIG_SERIAL_CONSOLE_PORT
+#define	CONFIG_SERIAL_CONSOLE_PORT 0 /* default UART1 as serial console */
+#endif
+
+#if 0
+struct tty_struct bf533_ttys;
+struct bf533_serial *bf533_consinfo = 0;
+#endif
+
+/*
+ *	Setup for console. Argument comes from the boot command line.
+ */
+
+#define	CONSOLE_BAUD_RATE	57600
+#define	DEFAULT_CBAUD		B57600 /* valid only upon test */
+
+static int bf533_console_initted = 0;
+static int bf533_console_baud    = CONSOLE_BAUD_RATE;
+static int bf533_console_cbaud   = DEFAULT_CBAUD;
+/* static int bf533_console_port = -1;		*/
+
+DECLARE_TASK_QUEUE(tq_serial);
+
+/*
+ *	Driver data structures.
+ */
+struct tty_driver bf533_serial_driver, bf533_callout_driver;
+static int bf533_serial_refcount;
+
+/* serial subtype definitions */
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+  
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+
+#define _INLINE_ inline
+
+static struct bf533_serial bf533_soft[] = {
+/*    magic    hub2     irq   flags           */
+  {	0, 	0, 	IRQ_UART, 	0 }, /* ttyS0 */
+};
+
+#define NR_PORTS (sizeof(bf533_soft) / sizeof(struct bf533_serial))
+
+static struct tty_struct *bf533_serial_table[NR_PORTS];
+static struct termios *bf533_serial_termios[NR_PORTS];
+static struct termios *bf533_serial_termios_locked[NR_PORTS];
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+
+/*
+ * This is used to figure out the divisor speeds and the timeouts
+ */
+
+static int baud_table[] = {
+	0, 114, 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 0 };
+
+struct { unsigned short dl_high, dl_low;
+	} hw_baud_table[] = {
+	{0xff, 0xff}, /* approximately 0 */
+	{0xff, 0xff}, /* 114 */
+	{0x61, 0xa8}, /* 300 */
+	{0x18, 0x6a}, /* 1200 */
+	{0xc, 0x35},  /* 2400 */
+	{0x6, 0x1a},  /* 4800 */
+	{0x3, 0x0d},  /* 9600 */
+	{0x1, 0x86},  /* 19200 */
+	{0x0, 0xc3},  /* 38400 */
+	{0x0, 0x3a},  /* 57600 */
+	{0x0, 0x41},  /* 115200 */
+		      /* rate = SCLK / (16 * DL) - SCLK = 120MHz
+   			 DL = (dl_high:dl_low) */
+};	
+
+#define BAUD_TABLE_SIZE (sizeof(baud_table)/sizeof(baud_table[0]))
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the memcpy_fromfs blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static unsigned char tmp_buf[SERIAL_XMIT_SIZE]; /* This is cheating */
+DECLARE_MUTEX(tmp_buf_sem);
+
+/* Forward declarations.... */
+static void bf533_change_speed(struct bf533_serial *info);
+static void bf533_set_baud( void );
+static void rs_stop(struct tty_struct *tty);
+static void rs_put_char(struct tty_struct *tty, char ch);
+static void rs_start(struct tty_struct *tty);
+
+/****************************************************************************/
+static inline int serial_paranoia_check(struct bf533_serial *info,
+					dev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%d,%d) in %s\n";
+	static const char *badinfo =
+		"Warning: null bf533_serial for (%d, %d) in %s\n";
+
+	if (!info) {
+		printk(badinfo, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+	if (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+/* Sets or clears DTR/RTS on the requested line */
+static inline void bf533_rtsdtr(struct bf533_serial *info, int set)
+{
+	unsigned long           flags = 0;
+#ifdef SERIAL_DEBUG_OPEN
+        printk("%s(%d): bf533_rtsdtr(info=%x,set=%d)\n",
+                __FILE__, __LINE__, info, set);
+#endif
+
+        save_flags(flags); cli(); 
+	if (set) {
+		/* set the RTS/CTS line */
+	} else {
+		/* clear it */
+	}
+        restore_flags(flags);
+	return;
+}
+
+/* Utility routines */
+static inline int get_baud(struct bf533_serial *info)
+{
+        unsigned long result = 115200;
+        unsigned short int baud_lo, baud_hi;
+        int i, idx = info->hub2;
+ 
+        ACCESS_LATCH(idx) /* change access to divisor latch */
+        baud_lo = UART_DLL(idx);
+        baud_hi = UART_DLH(idx);
+ 
+        for (i=0; i<BAUD_TABLE_SIZE ; i++){
+                if ( baud_lo == hw_baud_table[i].dl_low && baud_hi == hw_baud_table[i].dl_high)
+                {    result = baud_table[i];
+                     break;
+                }
+        }
+ 
+        return result; 
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+	struct bf533_serial *info = (struct bf533_serial *)tty->driver_data;
+	unsigned long flags = 0;
+	unsigned int idx = (unsigned int) info->hub2;
+
+	if (serial_paranoia_check(info, tty->device, "rs_stop"))
+		return;
+	
+	save_flags(flags); cli();
+	   ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+	   UART_IER(idx) = 0;
+	restore_flags(flags);
+}
+
+extern void cache_delay(void);
+
+static void local_put_char(int hub2, char ch)
+{
+	int flags = 0;
+
+	if (hub2 < 0 || hub2 >= NR_PORTS) {
+		printk("Error: Invalid serial port requested.\n");
+		return; /* validate port op(UART 0) */
+	}
+
+	save_flags(flags); cli();
+
+	while (!(UART_LSR(hub2) & UART_LSR_THRE)) {
+		SYNC_ALL;
+	}
+
+	ACCESS_PORT_IER(hub2)
+	UART_THR(hub2) = ch;
+	SYNC_ALL;
+
+	/*while (UART_LSR(hub2) & UART_LSR_THRE) {
+		udelay(5);
+	}*/
+
+	restore_flags(flags);
+}
+
+static void rs_put_char(struct tty_struct *tty, char ch)
+{
+	rs_write(tty, 1, &ch, 1);
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+	struct bf533_serial *info = (struct bf533_serial *)tty->driver_data;
+	unsigned long flags = 0;
+	unsigned int idx = (unsigned int) info->hub2;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_start"))
+		return;
+	
+	save_flags(flags); cli();
+	ACCESS_PORT_IER(idx)	/* Change access to IER & data port */
+	if (info->xmit_cnt && info->xmit_buf && !(UART_IER(idx) & UART_IER_ETBEI))
+		UART_IER(idx) |= UART_IER_ETBEI;
+	 
+	restore_flags(flags);
+}
+
+/* Drop into either the boot monitor or kgdb upon receiving a break
+ * from keyboard/console input.
+ */
+static void batten_down_hatches(void)
+{
+	/* Drop into the debugger */
+}
+
+static _INLINE_ void status_handle(struct bf533_serial *info, unsigned short status)
+{
+	/* If this is console input and this is a
+	 * 'break asserted' status change interrupt
+	 * see if we can drop into the debugger
+	 */
+	if((status & UART_LSR_BI) && info->break_abort)
+		batten_down_hatches();
+	return;
+}
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static _INLINE_ void rs_sched_event(struct bf533_serial *info,
+				    int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_serial);
+	mark_bh(SERIAL_BH);
+}
+
+static void receive_chars(struct bf533_serial *info, struct pt_regs *regs, unsigned short rx)
+{
+	struct tty_struct *tty = info->tty;
+	unsigned char ch;
+	int idx = info->hub2;
+
+	/*
+	 * This do { } while() loop will get ALL chars out of Rx FIFO 
+         */
+	do {
+		ch = (unsigned char) rx;
+	
+		if(info->is_cons) {
+			if (UART_LSR(idx) & UART_LSR_BI){ /* break received */ 
+				status_handle(info, UART_LSR(idx));
+				return;
+			} else if (ch == 0x10) { /* ^P */
+				show_state();
+				show_free_areas();
+				show_buffers();
+/*				show_net_buffers(); */
+				return;
+			} else if (ch == 0x12) { /* ^R */
+				machine_restart(NULL);
+				return;
+			}
+		}
+
+		if(!tty){
+			printk("no tty\n");
+			goto clear_and_exit;
+		}
+		
+		/*
+		 * Make sure that we do not overflow the buffer
+		 */
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			queue_task(&tty->flip.tqueue, &tq_timer);
+			return;
+		}
+
+		if(UART_LSR(idx) & UART_LSR_PE) {
+			*tty->flip.flag_buf_ptr++ = TTY_PARITY;
+			status_handle(info, UART_LSR(idx));
+		} else if(UART_LSR(idx) & UART_LSR_OE) {
+			*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+			status_handle(info, UART_LSR(idx));
+		} else if(UART_LSR(idx) & UART_LSR_FE) {
+			*tty->flip.flag_buf_ptr++ = TTY_FRAME;
+			status_handle(info, UART_LSR(idx));
+		} else {
+			*tty->flip.flag_buf_ptr++ = 0; /* XXX */
+		}
+
+		tty->flip.count++;
+                *tty->flip.char_buf_ptr++ = ch;
+
+		ACCESS_PORT_IER(idx) /* change access to port data */
+		rx = UART_RBR(idx);
+	} while(UART_LSR(idx) & UART_LSR_DR);
+
+	queue_task(&tty->flip.tqueue, &tq_timer);
+
+clear_and_exit:
+	return;
+}
+
+static void transmit_chars(struct bf533_serial *info)
+{
+	int idx = info->hub2;
+
+	if (info->x_char) { /* Send next char */
+		local_put_char(idx, info->x_char);
+		info->x_char = 0;
+		goto clear_and_return;
+	}
+
+	if((info->xmit_cnt <= 0) || info->tty->stopped) { /* TX ints off */
+		ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+		UART_IER(idx) &= ~UART_IER_ETBEI;
+		goto clear_and_return;
+	}
+
+	/* Send char */
+	local_put_char(idx,info->xmit_buf[info->xmit_tail++]);
+	info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+	info->xmit_cnt--;
+
+	if (info->xmit_cnt < WAKEUP_CHARS)
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+	if(info->xmit_cnt <= 0) { /* All done for now... TX ints off */
+		ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+		UART_IER(idx) &= ~UART_IER_ETBEI;
+		goto clear_and_return;
+	}
+
+clear_and_return:
+	/* Clear interrupt (should be auto)*/
+	return;
+}
+
+#define UART_INVOKED	3
+/*
+ * This is the serial driver's generic interrupt routine
+ * Note: Generally it should be attached to general interrupt 10, responsile 
+ *       for UART0&1 RCV and XMT interrupt, to make sure the invoked interrupt
+ *       source, look into bit 10-13 of SIC_ISR(peripheral interrupt status reg.
+ *       Finally, to see what can be done about request_irq(......)
+ */
+void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct bf533_serial *info; // = &bf533_soft[CONFIG_SERIAL_CONSOLE_PORT];
+	unsigned short iir; /* Interrupt Identification Register */
+	unsigned short rx, idx = 0;
+	unsigned int sic_status = SIC_ISR;
+
+	if (sic_status & 0xC000)
+	{ 
+		/* test bit 10-11 and 12-13 */
+		iir = UART_IIR(idx);
+		info = &bf533_soft[idx];
+
+		if (!(iir & UART_IIR_NOINT))
+		{
+			switch (iir & UART_IIR_STATUS)
+			{
+		   	case UART_IIR_LSR:
+				printk("Line status changed for serial port %d.\n", idx);
+				break;
+		   	case UART_IIR_RBR:
+		   		/* Change access to IER & data port */
+				ACCESS_PORT_IER(idx) 
+				if (UART_LSR(idx) & UART_LSR_DR){
+				   rx = UART_RBR(idx);
+				   receive_chars(info, regs, rx);
+				}
+				break;
+		   	case UART_IIR_THR:
+		   		/* Change access to IER & data port */
+				ACCESS_PORT_IER(idx) 
+				if (UART_LSR(idx) & UART_LSR_THRE){
+				    transmit_chars(info);
+//				    do{
+//					transmit_chars(info);
+//				    }while(info->xmit_cnt > 0);
+				}
+				break;
+		   	case UART_IIR_MSR:
+				printk("Modem status changed for serial port.\n");
+	   	   	}
+		}
+	}	
+	return;
+}
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct bf533_serial	*info = (struct bf533_serial *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+	}
+}
+
+/*
+ * This routine is called from the scheduler tqueue when the interrupt
+ * routine has signalled that a hangup has occurred.  The path of
+ * hangup processing is:
+ *
+ * 	serial interrupt routine -> (scheduler tqueue) ->
+ * 	do_serial_hangup() -> tty->hangup() -> rs_hangup()
+ * 
+ */
+static void do_serial_hangup(void *private_)
+{
+	struct bf533_serial	*info = (struct bf533_serial *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	tty_hangup(tty);
+}
+
+
+static int startup(struct bf533_serial * info)
+{
+	unsigned long flags = 0;
+	int idx	= info->hub2;
+	
+	if (info->flags & S_INITIALIZED)
+		return 0;
+
+	if (!info->xmit_buf) {
+		info->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL);
+		if (!info->xmit_buf)
+			return -ENOMEM;
+	}
+
+	local_irq_save(flags);
+
+	/*
+	 * Clear the FIFO buffers and disable them
+	 * (they will be reenabled in bf533_change_speed())
+	 */
+
+	info->xmit_fifo_size = 1;
+	ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+		
+	UART_GCTL(idx) |= UART_GCTL_UCEN;
+
+	UART_IER(idx) = UART_IER_ERBFI | UART_IER_ETBEI | UART_IER_ELSI | UART_IER_EDDSI;
+	(void)UART_RBR(idx);
+
+	/*
+	 * Finally, enable sequencing and interrupts
+	 */
+	UART_IER(idx) = UART_IER_ERBFI | UART_IER_ELSI | UART_IER_EDDSI;
+	bf533_rtsdtr(info, 1);
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+
+	/*
+	 * and set the speed of the serial port
+	 */
+
+	bf533_change_speed(info);
+
+	info->flags |= S_INITIALIZED;
+	local_irq_restore(flags);
+	return 0;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct bf533_serial * info)
+{
+	unsigned long	flags = 0;
+	int idx = info->hub2;
+
+        if (!(info->flags & S_INITIALIZED))
+                return; 
+
+#ifdef SERIAL_DEBUG_OPEN
+        printk("Shutting down serial port %d (irq %d)....\n", info->hub2,
+               info->irq);
+#endif
+      
+	save_flags(flags); cli(); /* Disable interrupts */
+
+	UART_LCR(idx) = 0;
+	ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+	UART_IER(idx) = 0;
+
+	UART_GCTL(idx) &= ~UART_GCTL_UCEN;
+
+	
+        if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+                bf533_rtsdtr(info, 0);
+	
+	if (info->xmit_buf) {
+		free_page((unsigned long) info->xmit_buf);
+		info->xmit_buf = 0;
+	}
+
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~S_INITIALIZED;
+	restore_flags(flags);
+}
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void bf533_change_speed(struct bf533_serial *info)
+{
+	unsigned short uart_lcr;
+	unsigned cflag, flags = 0;
+	int	i, idx = info->hub2;
+
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+
+	local_irq_save(flags);
+	ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+//	UART_IER(idx) = 0;  /* disable all interrupts for UART0 */
+
+	i = cflag & CBAUD;
+        if (i & CBAUDEX) {
+                i = (i & ~CBAUDEX) + B38400;
+        }
+
+	info->baud = baud_table[i];
+	ACCESS_LATCH(idx)	/* change to access of divisor latch */
+	UART_DLL(idx) = hw_baud_table[i].dl_low;
+	UART_DLH(idx) = hw_baud_table[i].dl_high;
+
+	UART_LCR(idx) &= UART_LCR_DLAB; /* clear all except DLAB bit */
+	uart_lcr = UART_LCR(idx);
+
+	switch (cflag & CSIZE) {
+	case CS6:	uart_lcr |= UART_LCR_WLS6; break;
+	case CS7:	uart_lcr |= UART_LCR_WLS7; break;
+	case CS8:	uart_lcr |= UART_LCR_WLS8; break;
+	default: 	break;
+	}
+		
+	if (cflag & CSTOPB)
+		uart_lcr |= UART_LCR_STB;
+
+	if (cflag & PARENB){
+		uart_lcr |= UART_LCR_PEN;
+		if (cflag & PARODD)
+		uart_lcr &= ~(UART_LCR_EPS | UART_LCR_SP);
+	}
+
+        if (cflag & CRTSCTS) {
+		uart_lcr |= UART_LCR_SB;
+        }
+		UART_LCR(idx) = uart_lcr;
+
+        restore_flags(flags);	
+	return;
+}
+
+static void rs_set_ldisc(struct tty_struct *tty)
+{
+	struct bf533_serial *info = (struct bf533_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_set_ldisc"))
+		return;
+
+	info->is_cons = (tty->termios->c_line == N_TTY);
+	
+	printk("ttyS%d console mode %s\n", info->line, info->is_cons ? "on" : "off");
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct bf533_serial *info = (struct bf533_serial *)tty->driver_data;
+	unsigned long flags = 0;
+	int idx = info->hub2;
+
+	if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
+		return;
+#ifndef USE_INTS
+	for(;;) {
+#endif
+		if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || 
+	   	   !info->xmit_buf)
+			return;
+
+		save_flags(flags); cli();
+
+		ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+#ifdef USE_INTS
+		UART_IER(idx) |= UART_IER_ETBEI;
+		if (UART_LSR(idx) & UART_LSR_TEMT) {
+#else
+		UART_IER(idx) = 0; /* disable all interrupts for UART0  */
+		if (1) {
+#endif
+			/* Send char */
+			local_put_char(idx,info->xmit_buf[info->xmit_tail++]);
+			info->xmit_tail = info->xmit_tail&(SERIAL_XMIT_SIZE-1);
+			info->xmit_cnt--;
+		}
+
+#ifndef USE_INTS
+		while (!(UART_LSR(idx) & UART_LSR_TEMT)) 
+			SYNC_ALL;
+	}
+#endif
+	restore_flags(flags);
+}
+
+static int rs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	int	c, total = 0;
+	struct bf533_serial *info = (struct bf533_serial *)tty->driver_data;
+	unsigned long flags = 0;
+	int	idx = info->hub2;
+
+	if (serial_paranoia_check(info, tty->device, "rs_write"))
+		return 0;
+
+	if (!tty || !info->xmit_buf)
+		return 0;
+
+	while (1) {
+		c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				   SERIAL_XMIT_SIZE - info->xmit_head));
+		if (c <= 0)
+			break;
+
+		save_flags(flags); cli();		
+		if (from_user) {
+			down(&tmp_buf_sem);
+			copy_from_user(tmp_buf, buf, c);
+			c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				       SERIAL_XMIT_SIZE - info->xmit_head));
+			memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
+			up(&tmp_buf_sem);
+		} else
+			memcpy(info->xmit_buf + info->xmit_head, buf, c);
+		info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+		info->xmit_cnt += c;
+		restore_flags(flags);
+		buf += c;
+		count -= c;
+		total += c;
+	}
+
+	if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
+		/* Enable transmitter */
+		save_flags(flags); cli();		
+#ifdef USE_INTS
+		ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+		UART_IER(idx) |= UART_IER_ETBEI;
+#else
+		while(info->xmit_cnt) {
+#endif
+		while (!(UART_LSR(idx) & UART_LSR_TEMT))
+			SYNC_ALL;
+
+		if (UART_LSR(idx) & UART_LSR_TEMT) {
+			local_put_char(idx,info->xmit_buf[info->xmit_tail++]);
+			info->xmit_tail = info->xmit_tail&(SERIAL_XMIT_SIZE-1);
+			info->xmit_cnt--;
+		}
+
+#ifndef USE_INTS
+		}
+#endif
+		restore_flags(flags);
+	}
+	return total;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct bf533_serial *info = (struct bf533_serial *)tty->driver_data;
+	int	ret;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
+		return 0;
+	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
+	if (ret < 0)
+		ret = 0;
+	return ret;
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct bf533_serial *info = (struct bf533_serial *)tty->driver_data;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+		return 0;
+	return info->xmit_cnt;
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	struct bf533_serial *info = (struct bf533_serial *)tty->driver_data;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+		return;
+	cli();
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+	sti();
+	wake_up_interruptible(&tty->write_wait);
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct * tty)
+{
+	struct bf533_serial *info = (struct bf533_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+		return;
+	
+	if (I_IXOFF(tty))
+		info->x_char = STOP_CHAR(tty);
+
+	/* Turn off RTS line (do this atomic) */
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+	struct bf533_serial *info = (struct bf533_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+		return;
+	
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			info->x_char = START_CHAR(tty);
+	}
+
+	/* Assert RTS line (do this atomic) */
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int get_serial_info(struct bf533_serial * info,
+			   struct serial_struct * retinfo)
+{
+	struct serial_struct tmp;
+  
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = info->type;
+	tmp.line = info->line;
+	tmp.hub2 = info->hub2;
+	tmp.irq = info->irq;
+	tmp.flags = info->flags;
+	tmp.baud_base = info->baud_base;
+	tmp.close_delay = info->close_delay;
+	tmp.closing_wait = info->closing_wait;
+	tmp.custom_divisor = info->custom_divisor;
+	copy_to_user(retinfo,&tmp,sizeof(*retinfo));
+	return 0;
+}
+
+static int set_serial_info(struct bf533_serial * info,
+			   struct serial_struct * new_info)
+{
+	struct serial_struct new_serial;
+	struct bf533_serial old_info;
+	int    retval = 0;
+
+	if (!new_info)
+		return -EFAULT;
+	copy_from_user(&new_serial,new_info,sizeof(new_serial));
+	old_info = *info;
+
+	if (!suser()) {
+		if ((new_serial.baud_base != info->baud_base) ||
+		    (new_serial.type != info->type) ||
+		    (new_serial.close_delay != info->close_delay) ||
+		    ((new_serial.flags & ~S_USR_MASK) !=
+		     (info->flags & ~S_USR_MASK)))
+			return -EPERM;
+		info->flags = ((info->flags & ~S_USR_MASK) |
+			       (new_serial.flags & S_USR_MASK));
+		info->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	if (info->count > 1)
+		return -EBUSY;
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+	info->baud_base = new_serial.baud_base;
+	info->flags = ((info->flags & ~S_FLAGS) |
+			(new_serial.flags & S_FLAGS));
+	info->type = new_serial.type;
+	info->close_delay = new_serial.close_delay;
+	info->closing_wait = new_serial.closing_wait;
+
+check_and_exit:
+	retval = startup(info);
+	return retval;
+}
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space. 
+ */
+static int get_lsr_info(struct bf533_serial * info, unsigned int *value)
+{
+	unsigned char status;
+
+	cli();
+
+	status = 0; /* no CTS status pin in BlackFin Serial */
+	sti();
+	put_user(status,value);
+	return 0;
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void send_break(	struct bf533_serial * info, int duration)
+{
+        unsigned long flags = 0;
+	int	 idx = info->hub2;
+
+        current->state = TASK_INTERRUPTIBLE;
+        save_flags(flags);
+        cli();
+	UART_LCR(idx) |= UART_LCR_SB;
+        schedule_timeout(duration);
+	UART_LCR(idx) &= ~UART_LCR_SB;
+        restore_flags(flags);
+}
+
+static int rs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	int error;
+	struct bf533_serial * info = (struct bf533_serial *)tty->driver_data;
+	int retval;
+
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
+	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+	
+	switch (cmd) {
+		case TCSBRK:	/* SVID version: non-zero arg --> no break */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (!arg)
+				send_break(info, HZ/4);	/* 1/4 second */
+			return 0;
+		case TCSBRKP:	/* support for POSIX tcsendbreak() */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+			return 0;
+		case TIOCGSOFTCAR:
+			error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long));
+			if (error)
+				return error;
+			put_user(C_CLOCAL(tty) ? 1 : 0,
+				    (unsigned long *) arg);
+			return 0;
+		case TIOCSSOFTCAR:
+			get_user(arg, (unsigned long *) arg);
+			tty->termios->c_cflag =
+				((tty->termios->c_cflag & ~CLOCAL) |
+				 (arg ? CLOCAL : 0));
+			return 0;
+		case TIOCGSERIAL:
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+						sizeof(struct serial_struct));
+			if (error)
+				return error;
+			return get_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSSERIAL:
+			return set_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSERGETLSR: /* Get line status register */
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+				sizeof(unsigned int));
+			if (error)
+				return error;
+			else
+			    return get_lsr_info(info, (unsigned int *) arg);
+
+		case TIOCSERGSTRUCT:
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+						sizeof(struct bf533_serial));
+			if (error)
+				return error;
+			copy_to_user((struct bf533_serial *) arg,
+				    info, sizeof(struct bf533_serial));
+			return 0;
+			
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	struct bf533_serial *info = (struct bf533_serial *)tty->driver_data;
+
+	if (tty->termios->c_cflag == old_termios->c_cflag)
+		return;
+
+	bf533_change_speed(info);
+
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+	
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * S structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+	struct bf533_serial * info = (struct bf533_serial *)tty->driver_data;
+	unsigned long flags = 0;
+	int	 idx = info->hub2;
+
+	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+		return;
+	
+	save_flags(flags); cli();
+	
+	if (tty_hung_up_p(filp)) {
+		restore_flags(flags);
+		return;
+	}
+	
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  Info->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+		       "info->count is %d\n", info->count);
+		info->count = 1;
+	}
+	if (--info->count < 0) {
+		printk("rs_close: bad serial port count for ttyS%d: %d\n",
+		       info->line, info->count);
+		info->count = 0;
+	}
+	if (info->count) {
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= S_CLOSING;
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & S_NORMAL_ACTIVE)
+		info->normal_termios = *tty->termios;
+	if (info->flags & S_CALLOUT_ACTIVE)
+		info->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != S_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+
+	ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+	UART_IER(idx) = 0;
+
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (tty->ldisc.num != tty_ldiscs[N_TTY].num) {
+		if (tty->ldisc.close)
+			(tty->ldisc.close)(tty);
+		tty->ldisc = tty_ldiscs[N_TTY];
+		tty->termios->c_line = N_TTY;
+		if (tty->ldisc.open)
+			(tty->ldisc.open)(tty);
+	}
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(S_NORMAL_ACTIVE|S_CALLOUT_ACTIVE|
+			 S_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	restore_flags(flags);
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+void rs_hangup(struct tty_struct *tty)
+{
+	struct bf533_serial * info = (struct bf533_serial *)tty->driver_data;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
+		return;
+	
+	rs_flush_buffer(tty);
+	shutdown(info);
+	info->event = 0;
+	info->count = 0;
+	info->flags &= ~(S_NORMAL_ACTIVE|S_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file * filp,
+			   struct bf533_serial *info)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int		retval;
+	int		do_clocal = 0;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (info->flags & S_CLOSING) {
+		interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		if (info->flags & S_HUP_NOTIFY)
+			return -EAGAIN;
+		else
+			return -ERESTARTSYS;
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & S_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+		    (info->flags & S_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+		    return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+		    (info->flags & S_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+		    return -EBUSY;
+		info->flags |= S_CALLOUT_ACTIVE;
+		return 0;
+	}
+	
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & S_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= S_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & S_CALLOUT_ACTIVE) {
+		if (info->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+	
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, info->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+
+	info->count--;
+	info->blocked_open++;
+	while (1) {
+		cli();
+		if (!(info->flags & S_CALLOUT_ACTIVE))
+			bf533_rtsdtr(info, 1);
+		sti();
+		current->state = TASK_INTERRUPTIBLE;
+		if (tty_hung_up_p(filp) ||
+		    !(info->flags & S_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & S_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;	
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & S_CALLOUT_ACTIVE) &&
+		    !(info->flags & S_CLOSING) && do_clocal)
+			break;
+                if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&info->open_wait, &wait);
+	if (!tty_hung_up_p(filp))
+		info->count++;
+	info->blocked_open--;
+
+	if (retval)
+		return retval;
+	info->flags |= S_NORMAL_ACTIVE;
+	return 0;
+}	
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its S structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+int rs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct bf533_serial	*info;
+	int 			retval, line;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	
+	if ((line < 0) || (line >= NR_PORTS)) 
+		return -ENODEV;
+
+	info = bf533_soft + line;
+
+	if (serial_paranoia_check(info, tty->device, "rs_open"))
+		return -ENODEV;
+#ifdef SERIAL_DEBUG_OPEN
+        printk("bf533_open %s%d, count = %d\n", tty->driver.name, info->line,
+               info->count);
+#endif
+
+	info->count++;
+	tty->driver_data = info;
+	info->tty = tty;
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval)
+		return retval;
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+                printk("bf533_open returning after block_til_ready with %d\n",
+                       retval);
+#endif 
+		return retval;
+	}
+
+	if ((info->count == 1) && (info->flags & S_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->normal_termios;
+		else 
+			*tty->termios = info->callout_termios;
+		bf533_change_speed(info);
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+	return 0;
+}
+
+/* Finally, routines used to initialize the serial driver. */
+
+static void show_serial_version(void)
+{
+	printk("BlackFin BF533 serial driver version 1.00\n");
+}
+
+/* rs_bf533_init inits the driver *
+static */ int __init rs_bf533_init(void)
+{
+	int i, flags = 0;
+	struct bf533_serial *info;
+	
+	/* Setup base handler, and timer table. */
+	init_bh(SERIAL_BH, do_serial_bh);
+	show_serial_version();
+
+	/* Initialize the tty_driver structure */
+	/* NOTE: Not all of this is exactly right for us. */
+	
+	memset(&bf533_serial_driver, 0, sizeof(struct tty_driver));
+	bf533_serial_driver.magic = TTY_DRIVER_MAGIC;
+	bf533_serial_driver.name = "ttyS";
+	bf533_serial_driver.major = TTY_MAJOR;
+	bf533_serial_driver.minor_start = 64; 
+	bf533_serial_driver.num = NR_PORTS;
+	bf533_serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	bf533_serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	bf533_serial_driver.init_termios = tty_std_termios;
+	bf533_serial_driver.init_termios.c_cflag = 
+			bf533_console_cbaud | CS8 | CREAD | HUPCL | CLOCAL;
+	bf533_serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	bf533_serial_driver.refcount = &bf533_serial_refcount;
+	bf533_serial_driver.table = bf533_serial_table;
+	bf533_serial_driver.termios = bf533_serial_termios;
+	bf533_serial_driver.termios_locked = bf533_serial_termios_locked;
+
+	bf533_serial_driver.open = rs_open;
+	bf533_serial_driver.close = rs_close;
+	bf533_serial_driver.write = rs_write;
+	bf533_serial_driver.flush_chars = rs_flush_chars;
+	bf533_serial_driver.put_char = rs_put_char;
+	bf533_serial_driver.write_room = rs_write_room;
+	bf533_serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	bf533_serial_driver.flush_buffer = rs_flush_buffer;
+	bf533_serial_driver.ioctl = rs_ioctl;
+	bf533_serial_driver.throttle = rs_throttle;
+	bf533_serial_driver.unthrottle = rs_unthrottle;
+/*	bf533_serial_driver.send_xchar = ????	*/
+	bf533_serial_driver.set_termios = rs_set_termios;
+	bf533_serial_driver.stop = rs_stop;
+	bf533_serial_driver.start = rs_start;
+	bf533_serial_driver.hangup = rs_hangup;
+	bf533_serial_driver.set_ldisc = rs_set_ldisc;
+/*	bf533_serial_driver.wait_until_sent = ????	*/
+/*	bf533_serial_driver.read_proc = ????	*/
+
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code. ??? --tonyko
+	 */
+	bf533_callout_driver = bf533_serial_driver;
+	bf533_callout_driver.name = "cua";
+	bf533_callout_driver.major = TTYAUX_MAJOR;
+	bf533_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+
+	if (tty_register_driver(&bf533_serial_driver))
+		panic("Couldn't register serial driver\n");
+	if (tty_register_driver(&bf533_callout_driver))
+		panic("Couldn't register callout driver\n");
+	
+	save_flags(flags); cli();
+
+        /*
+         *      Configure all the attached serial ports.
+         */
+	info = bf533_soft;
+	info->magic = SERIAL_MAGIC;
+	info->tty = 0;
+	info->custom_divisor = 16;
+	info->close_delay = 50;
+	info->closing_wait = 3000;
+	info->x_char = 0;
+	info->event = 0;
+	info->count = 0;
+	info->blocked_open = 0;
+	info->tqueue.routine = do_softint;
+	info->tqueue.data = info;
+	info->tqueue_hangup.routine = do_serial_hangup;
+	info->tqueue_hangup.data = info;
+	info->callout_termios =bf533_callout_driver.init_termios;
+	info->normal_termios = bf533_serial_driver.init_termios;
+	init_waitqueue_head(&info->open_wait);
+	init_waitqueue_head(&info->close_wait);
+	info->line = 0;
+	info->is_cons = 1; /* Means shortcuts work */
+	info->irq = IRQ_UART;
+	
+	printk("%s0 at irq = %d", \
+		bf533_serial_driver.name, info->irq);
+	printk(" is a builtin BlackFin BF533 UART\n");
+
+	restore_flags(flags);
+
+	if (request_irq(IRQ_UART, rs_interrupt, IRQ_FLG_STD, "BF533_UART", NULL))
+		panic("Unable to attach BlackFin UART interrupt\n");
+	
+	printk("Enabling Serial UART Interrupts\n");
+	
+	enable_irq(IRQ_UART);
+
+	return 0;
+}
+
+/*
+ * register_serial and unregister_serial allows for serial ports to be
+ * configured at run-time, to support PCMCIA modems.
+ */
+/* NOTE : Unused at this time, just here to make things link. */
+/*int register_serial(struct serial_struct *req)
+{
+	return -1;
+}
+
+void unregister_serial(int line)
+{
+	return;
+}*/
+	
+module_init(rs_bf533_init);
+
+
+/* setting console baud rate: CONFIG_SERIAL_CONSOLE_PORT */
+static void bf533_set_baud( void )
+{
+	int	i;
+
+	/* Change access to IER & data port */
+	ACCESS_PORT_IER(CONFIG_SERIAL_CONSOLE_PORT) 
+	UART_IER(CONFIG_SERIAL_CONSOLE_PORT) &= ~UART_IER_ETBEI;
+
+again:
+	for (i = 0; i < sizeof(baud_table) / sizeof(baud_table[0]); i++)
+		if (baud_table[i] == bf533_console_baud)
+			break;
+	if (i >= sizeof(baud_table) / sizeof(baud_table[0])) {
+		bf533_console_baud = 9600;
+		goto again;
+	}
+
+	ACCESS_LATCH(CONFIG_SERIAL_CONSOLE_PORT) /*Set to access divisor latch*/
+	UART_DLL(CONFIG_SERIAL_CONSOLE_PORT) = hw_baud_table[i].dl_low;
+	UART_DLH(CONFIG_SERIAL_CONSOLE_PORT) = hw_baud_table[i].dl_high;
+
+	UART_LCR(CONFIG_SERIAL_CONSOLE_PORT) |= UART_LCR_WLS8;
+	UART_LCR(CONFIG_SERIAL_CONSOLE_PORT) &= ~UART_LCR_PEN;
+
+	/* Change access to IER & data port */
+	ACCESS_PORT_IER(CONFIG_SERIAL_CONSOLE_PORT) 
+        UART_IER(CONFIG_SERIAL_CONSOLE_PORT) |=(UART_IER_ETBEI | UART_IER_ELSI);
+	/* Enable the UART */
+	UART_GCTL(idx) |= UART_GCTL_UCEN;
+
+	bf533_console_initted = 1;
+	return;
+}
+
+
+int bf533_console_setup(struct console *cp, char *arg)
+{
+	int	i, n = CONSOLE_BAUD_RATE;
+
+	if (!cp)
+		return(-1);
+
+	if (arg)
+		n = simple_strtoul(arg,NULL,0);
+
+	for (i = 0; i < BAUD_TABLE_SIZE; i++)
+		if (baud_table[i] == n)
+			break;
+	if (i < BAUD_TABLE_SIZE) {
+		bf533_console_baud = n;
+		bf533_console_cbaud = 0;
+		if (i > 15) {
+			bf533_console_cbaud |= CBAUDEX;
+			i -= 15;
+		}
+		bf533_console_cbaud |= i;
+	}
+
+	bf533_set_baud(); /* make sure baud rate changes */
+	return(0);
+}
+
+static kdev_t bf533_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+void bf533_console_write (struct console *co, const char *str,
+			   unsigned int count)
+{
+    if (!bf533_console_initted)
+	bf533_set_baud();
+    while (count--) {
+        if (*str == '\n')	/* if a LF, also do CR... */
+           local_put_char( CONFIG_SERIAL_CONSOLE_PORT, '\r');
+        local_put_char( CONFIG_SERIAL_CONSOLE_PORT, *str++ );
+    }
+}
+
+static struct console bf533_driver = {
+	name:		"ttyS",
+	write:		bf533_console_write,
+	read:		NULL,
+	device:		bf533_console_device,
+	unblank:	NULL,
+	setup:		bf533_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		CONFIG_SERIAL_CONSOLE_PORT,
+	cflag:		0,
+	next:		NULL
+};
+
+void bf533_console_init(void)
+{
+	register_console(&bf533_driver);
+}
diff -urN linux-2.4.29/drivers/char/bf533_serial.h linux-2.4.29-uc1/drivers/char/bf533_serial.h
--- linux-2.4.29/drivers/char/bf533_serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/bf533_serial.h	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,158 @@
+/* bf533_serial.h: Definitions for the BlackFin BF533 DSP serial driver.
+ * Copyright (C) 2003	Bas Vermeulen <bas@buyways.nl>
+ * 			BuyWays B.V. (www.buyways.nl)
+ *
+ * Based heavily on:
+ * blkfinserial.h: Definitions for the BlackFin DSP serial driver.
+ *
+ * Copyright (C) 2001	Tony Z. Kou	tonyko@arcturusnetworks.com
+ * Copyright (C) 2001   Arcturus Networks Inc. <www.arcturusnetworks.com>
+ *
+ * Based on code from 68328serial.c which was: 
+ * Copyright (C) 1995       David S. Miller    <davem@caip.rutgers.edu>
+ * Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ * Copyright (C) 1998, 1999 D. Jeff Dionne     <jeff@uclinux.org>
+ * Copyright (C) 1999       Vladimir Gurevich  <vgurevic@cisco.com>
+ */
+
+#ifndef _Bf533_SERIAL_H
+#define _Bf533_SERIAL_H
+
+#include <linux/config.h>
+#include <asm/blackfin.h>
+
+struct serial_struct { /****** ??do we need a specific serial_struct */
+	int	type;
+	int	line;
+	int	hub2;
+	int	irq;
+	int	flags;
+	int	xmit_fifo_size;
+	int	custom_divisor;
+	int	baud_base;
+	unsigned short	close_delay;
+	char	reserved_char[2];
+	int	hub6;  /* FIXME: We don't have AT&T Hub6 boards! */
+	unsigned short	closing_wait; /* time to wait before closing */
+	unsigned short	closing_wait2; /* no longer used... */
+	int	reserved[4];
+};
+
+/*
+ * For the close wait times, 0 means wait forever for serial port to
+ * flush its output.  65535 means don't wait at all.
+ */
+#define S_CLOSING_WAIT_INF	0
+#define S_CLOSING_WAIT_NONE	65535
+
+/*
+ * Definitions for S_struct (and serial_struct) flags field
+ */
+#define S_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes 
+				   on the callout port */
+#define S_FOURPORT  0x0002	/* Set OU1, OUT2 per AST Fourport settings */
+#define S_SAK	0x0004	/* Secure Attention Key (Orange book) */
+#define S_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
+
+#define S_SPD_MASK	0x0030
+#define S_SPD_HI	0x0010	/* Use 56000 instead of 38400 bps */
+
+#define S_SPD_VHI	0x0020  /* Use 115200 instead of 38400 bps */
+#define S_SPD_CUST	0x0030  /* Use user-specified divisor */
+
+#define S_SKIP_TEST	0x0040   /* Skip UART test during autoconfiguration */
+#define S_AUTO_IRQ	0x0080   /* Do automatic IRQ during autoconfiguration */
+#define S_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
+#define S_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
+#define S_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
+
+#define S_FLAGS		0x0FFF	 /* Possible legal S flags */
+#define S_USR_MASK	0x0430	 /* Legal flags that non-privileged
+				  * users can set or reset */
+
+/* Internal flags used only by kernel/chr_drv/serial.c */
+#define S_INITIALIZED		0x80000000 /* Serial port was initialized */
+#define S_CALLOUT_ACTIVE	0x40000000 /* Call out device is active */
+#define S_NORMAL_ACTIVE		0x20000000 /* Normal device is active */
+#define S_BOOT_AUTOCONF		0x10000000 /* Autoconfigure port on bootup */
+#define S_CLOSING		0x08000000 /* Serial port is closing */
+#define S_CTS_FLOW		0x04000000 /* Do CTS flow control */
+#define S_CHECK_CD		0x02000000 /* i.e., CLOCAL */
+
+/* Software state per channel */
+
+#ifdef __KERNEL__
+
+/*
+ * This is our internal structure for each serial port's state.
+ * 
+ * Many fields are paralleled by the structure used by the serial_struct
+ * structure.
+ *
+ * For definitions of the flags field, see tty.h
+ */
+
+struct bf533_serial {
+	/* We need to know the current clock divisor
+	 * to read the bps rate the chip has currently
+	 * loaded.
+	 */
+	int			magic;
+	int			hub2;
+	int			irq;
+	int			flags; 		/* defined in tty.h */
+
+	char soft_carrier;  /* Use soft carrier on this channel */
+	char break_abort;   /* Is serial console in, so process brk/abrt */
+	char is_cons;       /* Is this our console. */
+
+	unsigned char		clk_divisor; 
+	int			baud;
+	int			baud_base;
+	int			type; 		/* UART type */
+	struct tty_struct 	*tty;
+	int			read_status_mask;
+	int			ignore_status_mask;
+	int			timeout;
+	int			xmit_fifo_size;
+	int			custom_divisor;
+	int			x_char;	/* xon/xoff character */
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int			count;	    /* # of fd on device */
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+	unsigned char 		*xmit_buf;
+	int			xmit_head;
+	int			xmit_tail;
+	int			xmit_cnt;
+	struct tq_struct	tqueue;
+	struct tq_struct	tqueue_hangup;
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+};
+
+
+#define SERIAL_MAGIC 0x5301	/******* ?? value for BlackFin Serial */
+#define UART_IRQ_NUM	10	/* change accordingly */
+
+/*
+ * The size of the serial xmit buffer is 1 page, or 4096 bytes
+ */
+#define SERIAL_XMIT_SIZE 4096
+
+/*
+ * Events are used to schedule things to happen at timer-interrupt
+ * time, instead of at rs interrupt time.
+ */
+#define RS_EVENT_WRITE_WAKEUP	0
+
+#endif /* __KERNEL__ */
+#endif /* (_Bf533_SERIAL_H) */
diff -urN linux-2.4.29/drivers/char/bf535_serial.c linux-2.4.29-uc1/drivers/char/bf535_serial.c
--- linux-2.4.29/drivers/char/bf535_serial.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/bf535_serial.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,1625 @@
+/* bf535_serial.c: Serial driver for BlackFin DSP internal USRTs.
+ * Copyright(c) 2003	Metrowerks	<mwaddel@metrowerks.com>
+ * Copyright(c)	2001	Tony Z. Kou	<tonyko@arcturusnetworks.com>
+ * Copyright(c)	2001-2002 Arcturus Networks Inc. <www.arcturusnetworks.com>
+ * 
+ * Based on code from 68328 version serial driver imlpementation which was:
+ * Copyright (C) 1995       David S. Miller    <davem@caip.rutgers.edu>
+ * Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ * Copyright (C) 1998, 1999 D. Jeff Dionne     <jeff@uclinux.org>
+ * Copyright (C) 1999       Vladimir Gurevich  <vgurevic@cisco.com> 
+ */
+ 
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/config.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/reboot.h>
+#include <linux/keyboard.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+#include <asm/uaccess.h>
+
+#include "bf535_serial.h"
+#define USE_INTS
+#define SERIAL_PARANOIA_CHECK
+
+#define SYNC_ALL	__asm__ __volatile__ ("ssync;\n")
+#define ACCESS_LATCH(idx)	UART_LCR(idx) |= UART_LCR_DLAB;
+#define ACCESS_PORT_IER(idx)	UART_LCR(idx) &= (~UART_LCR_DLAB);
+#ifndef CONFIG_SERIAL_CONSOLE_PORT
+#define	CONFIG_SERIAL_CONSOLE_PORT 1 /* default UART1 as serial console */
+#endif
+
+#if 0
+struct tty_struct bf535_ttys;
+struct bf535_serial *bf535_consinfo = 0;
+#endif
+
+/*
+ *	Setup for console. Argument comes from the boot command line.
+ */
+
+#define	CONSOLE_BAUD_RATE	57600
+#define	DEFAULT_CBAUD		B57600 /* valid only upon test */
+
+static int bf535_console_initted = 0;
+static int bf535_console_baud    = CONSOLE_BAUD_RATE;
+static int bf535_console_cbaud   = DEFAULT_CBAUD;
+/* static int bf535_console_port = -1;		*/
+
+DECLARE_TASK_QUEUE(tq_serial);
+
+/*
+ *	Driver data structures.
+ */
+struct tty_driver bf535_serial_driver, bf535_callout_driver;
+static int bf535_serial_refcount;
+
+/* serial subtype definitions */
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+  
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+
+#define _INLINE_ inline
+
+static struct bf535_serial bf535_soft[] = {
+/*    magic    hub2     irq   flags           */
+  {	0, 	0, 	IRQ_UART0, 	0 }, /* ttyS0 */
+  {	0, 	1, 	IRQ_UART1, 	0 }, /* ttyS1 */
+};
+
+#define NR_PORTS (sizeof(bf535_soft) / sizeof(struct bf535_serial))
+
+static struct tty_struct *bf535_serial_table[NR_PORTS];
+static struct termios *bf535_serial_termios[NR_PORTS];
+static struct termios *bf535_serial_termios_locked[NR_PORTS];
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+
+/*
+ * This is used to figure out the divisor speeds and the timeouts
+ */
+
+#ifndef CONFIG_PUB
+static int baud_table[] = {
+	0, 114, 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 0 };
+
+struct { unsigned short dl_high, dl_low;
+	} hw_baud_table[] = {
+	{0xff, 0xff}, /* approximately 0 */
+	{0xff, 0xff}, /* 114 */
+	{0x61, 0xa8}, /* 300 */
+	{0x18, 0x6a}, /* 1200 */
+	{0xc, 0x35},  /* 2400 */
+	{0x6, 0x1a},  /* 4800 */
+	{0x3, 0x0d},  /* 9600 */
+	{0x1, 0x86},  /* 19200 */
+	{0x0, 0xc3},  /* 38400 */
+	{0x0, 0x82},  /* 57600 */
+	{0x0, 0x41},  /* 115200 */
+		      /* rate = SCLK / (16 * DL) - SCLK = 120MHz
+   			 DL = (dl_high:dl_low) */
+};	
+#else
+static int baud_table[] = {
+	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
+	9600, 19200, 38400, 57600, 115200, 0 };
+struct { unsigned short dl_high, dl_low;
+	} hw_baud_table[] = {
+ 	{0xff, 0xff}, /* approximately 0 */
+	{0xff, 0xff}, /* 50 */
+	{0xf4, 0x24}, /* 75 */
+	{0xa6, 0x75}, /* 110 */
+	{0x88, 0xa5}, /* 134 */
+	{0x7a, 0x12}, /* 150 */
+	{0x5b, 0x8d}, /* 200 */
+	{0x3d, 0x09}, /* 300 */
+	{0x1e, 0x84}, /* 600 */
+	{0xf, 0x42}, /* 1200 */
+	{0xa, 0x2c}, /* 1800 */
+	{0x7, 0xa1}, /* 2400 */
+	{0x3, 0xd0}, /* 4800 */
+	{0x1, 0xe8}, /* 9600 */
+	{0x0, 0xf4}, /* 19200 */
+	{0x0, 0x7a}, /* 38400 */
+	{0x0, 0x54}, /* 57600 */
+	{0x0, 0x28}, /* 115200 */
+};		     /* rate = SCLK / (16 * DL)   
+	   		DL = (dl_high:dl_low) and above.
+	   		Valid under case: SCLK = 75MHz */
+#endif
+
+#define BAUD_TABLE_SIZE (sizeof(baud_table)/sizeof(baud_table[0]))
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the memcpy_fromfs blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static unsigned char tmp_buf[SERIAL_XMIT_SIZE]; /* This is cheating */
+DECLARE_MUTEX(tmp_buf_sem);
+
+/* Forward declarations.... */
+static void bf535_change_speed(struct bf535_serial *info);
+static void bf535_set_baud( void );
+
+/****************************************************************************/
+static inline int serial_paranoia_check(struct bf535_serial *info,
+					dev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%d,%d) in %s\n";
+	static const char *badinfo =
+		"Warning: null bf535_serial for (%d, %d) in %s\n";
+
+	if (!info) {
+		printk(badinfo, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+	if (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+/* Sets or clears DTR/RTS on the requested line */
+static inline void bf535_rtsdtr(struct bf535_serial *info, int set)
+{
+	unsigned long           flags = 0;
+#ifdef SERIAL_DEBUG_OPEN
+        printk("%s(%d): bf535_rtsdtr(info=%x,set=%d)\n",
+                __FILE__, __LINE__, info, set);
+#endif
+
+        save_flags(flags); cli(); 
+	if (set) {
+		/* set the RTS/CTS line */
+	} else {
+		/* clear it */
+	}
+        restore_flags(flags);
+	return;
+}
+
+/* Utility routines */
+static inline int get_baud(struct bf535_serial *info)
+{
+        unsigned long result = 115200;
+        unsigned short int baud_lo, baud_hi;
+        int i, idx = info->hub2;
+ 
+        ACCESS_LATCH(idx) /* change access to divisor latch */
+        baud_lo = UART_DLL(idx);
+        baud_hi = UART_DLH(idx);
+ 
+        for (i=0; i<BAUD_TABLE_SIZE ; i++){
+                if ( baud_lo == hw_baud_table[i].dl_low && baud_hi == hw_baud_table[i].dl_high)
+                {    result = baud_table[i];
+                     break;
+                }
+        }
+ 
+        return result; 
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+	struct bf535_serial *info = (struct bf535_serial *)tty->driver_data;
+	unsigned long flags = 0;
+	unsigned int idx = (unsigned int) info->hub2;
+
+	if (serial_paranoia_check(info, tty->device, "rs_stop"))
+		return;
+	
+	save_flags(flags); cli();
+	   ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+	   UART_IER(idx) = 0;
+	restore_flags(flags);
+}
+
+extern void cache_delay();
+
+static void local_put_char(int hub2, char ch)
+{
+	int flags = 0;
+
+	if (hub2 < 0 || hub2 > 1) {
+		printk("Error: Invalid serial port requested.\n");
+		return; /* validate port op(UART 0|1) */
+	}
+
+	save_flags(flags); cli();
+
+	while (!(UART_LSR(hub2) & UART_LSR_THRE)) {
+		SYNC_ALL;
+	}
+
+	ACCESS_PORT_IER(hub2)
+	UART_THR(hub2) = ch;
+	SYNC_ALL;
+
+	while (UART_LSR(hub2) & UART_LSR_THRE) {
+		udelay(5);
+	}
+
+	restore_flags(flags);
+}
+
+static void rs_put_char(struct tty_struct *tty, char ch)
+{
+	rs_write(tty, 1, &ch, 1);
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+	struct bf535_serial *info = (struct bf535_serial *)tty->driver_data;
+	unsigned long flags = 0;
+	unsigned int idx = (unsigned int) info->hub2;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_start"))
+		return;
+	
+	save_flags(flags); cli();
+	ACCESS_PORT_IER(idx)	/* Change access to IER & data port */
+	if (info->xmit_cnt && info->xmit_buf && !(UART_IER(idx) & UART_IER_ETBEI))
+		UART_IER(idx) |= UART_IER_ETBEI;
+	 
+	restore_flags(flags);
+}
+
+/* Drop into either the boot monitor or kgdb upon receiving a break
+ * from keyboard/console input.
+ */
+static void batten_down_hatches(void)
+{
+	/* Drop into the debugger */
+}
+
+static _INLINE_ void status_handle(struct bf535_serial *info, unsigned short status)
+{
+	/* If this is console input and this is a
+	 * 'break asserted' status change interrupt
+	 * see if we can drop into the debugger
+	 */
+	if((status & UART_LSR_BI) && info->break_abort)
+		batten_down_hatches();
+	return;
+}
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static _INLINE_ void rs_sched_event(struct bf535_serial *info,
+				    int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_serial);
+	mark_bh(SERIAL_BH);
+}
+
+static _INLINE_ void receive_chars(struct bf535_serial *info, struct pt_regs *regs, unsigned short rx)
+{
+	struct tty_struct *tty = info->tty;
+	unsigned char ch;
+	int idx = info->hub2;
+
+	/*
+	 * This do { } while() loop will get ALL chars out of Rx FIFO 
+         */
+	do {
+		ch = (unsigned char) rx;
+	
+		if(info->is_cons) {
+			if (UART_LSR(idx) & UART_LSR_BI){ /* break received */ 
+				status_handle(info, UART_LSR(idx));
+				return;
+			} else if (ch == 0x10) { /* ^P */
+				show_state();
+				show_free_areas();
+				show_buffers();
+/*				show_net_buffers(); */
+				return;
+			} else if (ch == 0x12) { /* ^R */
+				machine_restart(NULL);
+				return;
+			}
+		}
+
+		if(!tty){
+			printk("no tty\n");
+			goto clear_and_exit;
+		}
+		
+		/*
+		 * Make sure that we do not overflow the buffer
+		 */
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			queue_task(&tty->flip.tqueue, &tq_timer);
+			return;
+		}
+
+		if(UART_LSR(idx) & UART_LSR_PE) {
+			*tty->flip.flag_buf_ptr++ = TTY_PARITY;
+			status_handle(info, UART_LSR(idx));
+		} else if(UART_LSR(idx) & UART_LSR_OE) {
+			*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+			status_handle(info, UART_LSR(idx));
+		} else if(UART_LSR(idx) & UART_LSR_FE) {
+			*tty->flip.flag_buf_ptr++ = TTY_FRAME;
+			status_handle(info, UART_LSR(idx));
+		} else {
+			*tty->flip.flag_buf_ptr++ = 0; /* XXX */
+		}
+
+		tty->flip.count++;
+                *tty->flip.char_buf_ptr++ = ch;
+
+		ACCESS_PORT_IER(idx) /* change access to port data */
+		rx = UART_RBR(idx);
+	} while(UART_LSR(idx) & UART_LSR_DR);
+
+	queue_task(&tty->flip.tqueue, &tq_timer);
+
+clear_and_exit:
+	return;
+}
+
+static _INLINE_ void transmit_chars(struct bf535_serial *info)
+{
+	int idx = info->hub2;
+
+	if (info->x_char) { /* Send next char */
+		local_put_char(idx, info->x_char);
+		info->x_char = 0;
+		goto clear_and_return;
+	}
+
+	if((info->xmit_cnt <= 0) || info->tty->stopped) { /* TX ints off */
+		ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+		UART_IER(idx) &= ~UART_IER_ETBEI;
+		goto clear_and_return;
+	}
+
+	/* Send char */
+	local_put_char(idx,info->xmit_buf[info->xmit_tail++]);
+	info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+	info->xmit_cnt--;
+
+	if (info->xmit_cnt < WAKEUP_CHARS)
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+	if(info->xmit_cnt <= 0) { /* All done for now... TX ints off */
+		ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+		UART_IER(idx) &= ~UART_IER_ETBEI;
+		goto clear_and_return;
+	}
+
+clear_and_return:
+	/* Clear interrupt (should be auto)*/
+	return;
+}
+
+#define UART_INVOKED	3
+/*
+ * This is the serial driver's generic interrupt routine
+ * Note: Generally it should be attached to general interrupt 10, responsile 
+ *       for UART0&1 RCV and XMT interrupt, to make sure the invoked interrupt
+ *       source, look into bit 10-13 of SIC_ISR(peripheral interrupt status reg.
+ *       Finally, to see what can be done about request_irq(......)
+ */
+void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct bf535_serial *info; // = &bf535_soft[CONFIG_SERIAL_CONSOLE_PORT];
+	unsigned short iir; /* Interrupt Identification Register */
+	unsigned short rx, idx;
+	unsigned int sic_status = SIC_ISR;
+
+	for (idx = 0; idx < NR_PORTS; idx++){
+	   if (sic_status & (UART_INVOKED << 2*(idx + 5))){ 
+	   	/* test bit 10-11 and 12-13 */
+		iir = UART_IIR(idx);
+		info = &bf535_soft[idx];
+
+		if (!(iir & UART_IIR_NOINT)){
+		   switch (iir & UART_IIR_STATUS){
+		   case UART_IIR_LSR:
+				printk("Line status changed for serial port %d.\n", idx);
+				break;
+		   case UART_IIR_RBR:
+		   		/* Change access to IER & data port */
+				ACCESS_PORT_IER(idx) 
+				if (UART_LSR(idx) & UART_LSR_DR){
+				   rx = UART_RBR(idx);
+				   receive_chars(info, regs, rx);
+				}
+				break;
+		   case UART_IIR_THR:
+		   		/* Change access to IER & data port */
+				ACCESS_PORT_IER(idx) 
+				if (UART_LSR(idx) & UART_LSR_THRE){
+				    transmit_chars(info);
+//				    do{
+//					transmit_chars(info);
+//				    }while(info->xmit_cnt > 0);
+				}
+				break;
+		   case UART_IIR_MSR:
+				printk("Modem status changed for serial port.\n");
+			
+	   	   }
+		}
+	   }
+	}	
+	return;
+}
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct bf535_serial	*info = (struct bf535_serial *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+	}
+}
+
+/*
+ * This routine is called from the scheduler tqueue when the interrupt
+ * routine has signalled that a hangup has occurred.  The path of
+ * hangup processing is:
+ *
+ * 	serial interrupt routine -> (scheduler tqueue) ->
+ * 	do_serial_hangup() -> tty->hangup() -> rs_hangup()
+ * 
+ */
+static void do_serial_hangup(void *private_)
+{
+	struct bf535_serial	*info = (struct bf535_serial *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	tty_hangup(tty);
+}
+
+
+static int startup(struct bf535_serial * info)
+{
+	unsigned long flags = 0;
+	int idx	= info->hub2;
+	
+	if (info->flags & S_INITIALIZED)
+		return 0;
+
+	if (!info->xmit_buf) {
+		info->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL);
+		if (!info->xmit_buf)
+			return -ENOMEM;
+	}
+
+	local_irq_save(flags);
+
+	/*
+	 * Clear the FIFO buffers and disable them
+	 * (they will be reenabled in bf535_change_speed())
+	 */
+
+	info->xmit_fifo_size = 1;
+	ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+	UART_IER(idx) = UART_IER_ERBFI | UART_IER_ETBEI | UART_IER_ELSI | UART_IER_EDDSI;
+	(void)UART_RBR(idx);
+
+	/*
+	 * Finally, enable sequencing and interrupts
+	 */
+	UART_IER(idx) = UART_IER_ERBFI | UART_IER_ELSI | UART_IER_EDDSI;
+	bf535_rtsdtr(info, 1);
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+
+	/*
+	 * and set the speed of the serial port
+	 */
+
+	bf535_change_speed(info);
+
+	info->flags |= S_INITIALIZED;
+	local_irq_restore(flags);
+	return 0;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct bf535_serial * info)
+{
+	unsigned long	flags = 0;
+	int idx = info->hub2;
+
+        if (!(info->flags & S_INITIALIZED))
+                return; 
+
+#ifdef SERIAL_DEBUG_OPEN
+        printk("Shutting down serial port %d (irq %d)....\n", info->hub2,
+               info->irq);
+#endif
+      
+	save_flags(flags); cli(); /* Disable interrupts */
+
+	UART_LCR(idx) = 0;
+	ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+	UART_IER(idx) = 0;
+	
+        if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+                bf535_rtsdtr(info, 0);
+	
+	if (info->xmit_buf) {
+		free_page((unsigned long) info->xmit_buf);
+		info->xmit_buf = 0;
+	}
+
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~S_INITIALIZED;
+	restore_flags(flags);
+}
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void bf535_change_speed(struct bf535_serial *info)
+{
+	unsigned short uart_lcr;
+	unsigned cflag, flags = 0;
+	int	i, idx = info->hub2;
+
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+
+	local_irq_save(flags);
+	ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+//	UART_IER(idx) = 0;  /* disable all interrupts for UART0 */
+
+	i = cflag & CBAUD;
+        if (i & CBAUDEX) {
+                i = (i & ~CBAUDEX) + B38400;
+        }
+
+	info->baud = baud_table[i];
+	ACCESS_LATCH(idx)	/* change to access of divisor latch */
+	UART_DLL(idx) = hw_baud_table[i].dl_low;
+	UART_DLH(idx) = hw_baud_table[i].dl_high;
+
+	UART_LCR(idx) &= UART_LCR_DLAB; /* clear all except DLAB bit */
+	uart_lcr = UART_LCR(idx);
+
+	switch (cflag & CSIZE) {
+	case CS6:	uart_lcr |= UART_LCR_WLS6; break;
+	case CS7:	uart_lcr |= UART_LCR_WLS7; break;
+	case CS8:	uart_lcr |= UART_LCR_WLS8; break;
+	default: 	break;
+	}
+		
+	if (cflag & CSTOPB)
+		uart_lcr |= UART_LCR_STB;
+
+	if (cflag & PARENB){
+		uart_lcr |= UART_LCR_PEN;
+		if (cflag & PARODD)
+		uart_lcr &= ~(UART_LCR_EPS | UART_LCR_SP);
+	}
+
+        if (cflag & CRTSCTS) {
+		uart_lcr |= UART_LCR_SB;
+        }
+		UART_LCR(idx) = uart_lcr;
+
+        restore_flags(flags);	
+	return;
+}
+
+static void rs_set_ldisc(struct tty_struct *tty)
+{
+	struct bf535_serial *info = (struct bf535_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_set_ldisc"))
+		return;
+
+	info->is_cons = (tty->termios->c_line == N_TTY);
+	
+	printk("ttyS%d console mode %s\n", info->line, info->is_cons ? "on" : "off");
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct bf535_serial *info = (struct bf535_serial *)tty->driver_data;
+	unsigned long flags = 0;
+	int idx = info->hub2;
+
+	if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
+		return;
+#ifndef USE_INTS
+	for(;;) {
+#endif
+		if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || 
+	   	   !info->xmit_buf)
+			return;
+
+		save_flags(flags); cli();
+
+		ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+#ifdef USE_INTS
+		UART_IER(idx) |= UART_IER_ETBEI;
+		if (UART_LSR(idx) & UART_LSR_TEMT) {
+#else
+		UART_IER(idx) = 0; /* disable all interrupts for UART0  */
+		if (1) {
+#endif
+			/* Send char */
+			local_put_char(idx,info->xmit_buf[info->xmit_tail++]);
+			info->xmit_tail = info->xmit_tail&(SERIAL_XMIT_SIZE-1);
+			info->xmit_cnt--;
+		}
+
+#ifndef USE_INTS
+		while (!(UART_LSR(idx) & UART_LSR_TEMT)) 
+			SYNC_ALL;
+	}
+#endif
+	restore_flags(flags);
+}
+
+static int rs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	int	c, total = 0;
+	struct bf535_serial *info = (struct bf535_serial *)tty->driver_data;
+	unsigned long flags = 0;
+	int	idx = info->hub2;
+
+	if (serial_paranoia_check(info, tty->device, "rs_write"))
+		return 0;
+
+	if (!tty || !info->xmit_buf)
+		return 0;
+
+	while (1) {
+		c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				   SERIAL_XMIT_SIZE - info->xmit_head));
+		if (c <= 0)
+			break;
+
+		save_flags(flags); cli();		
+		if (from_user) {
+			down(&tmp_buf_sem);
+			copy_from_user(tmp_buf, buf, c);
+			c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				       SERIAL_XMIT_SIZE - info->xmit_head));
+			memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
+			up(&tmp_buf_sem);
+		} else
+			memcpy(info->xmit_buf + info->xmit_head, buf, c);
+		info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+		info->xmit_cnt += c;
+		restore_flags(flags);
+		buf += c;
+		count -= c;
+		total += c;
+	}
+
+	if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
+		/* Enable transmitter */
+		save_flags(flags); cli();		
+#ifdef USE_INTS
+		ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+		UART_IER(idx) |= UART_IER_ETBEI;
+#else
+		while(info->xmit_cnt) {
+#endif
+		while (!(UART_LSR(idx) & UART_LSR_TEMT))
+			SYNC_ALL;
+
+		if (UART_LSR(idx) & UART_LSR_TEMT) {
+			local_put_char(idx,info->xmit_buf[info->xmit_tail++]);
+			info->xmit_tail = info->xmit_tail&(SERIAL_XMIT_SIZE-1);
+			info->xmit_cnt--;
+		}
+
+#ifndef USE_INTS
+		}
+#endif
+		restore_flags(flags);
+	}
+	return total;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct bf535_serial *info = (struct bf535_serial *)tty->driver_data;
+	int	ret;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
+		return 0;
+	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
+	if (ret < 0)
+		ret = 0;
+	return ret;
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct bf535_serial *info = (struct bf535_serial *)tty->driver_data;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+		return 0;
+	return info->xmit_cnt;
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	struct bf535_serial *info = (struct bf535_serial *)tty->driver_data;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+		return;
+	cli();
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+	sti();
+	wake_up_interruptible(&tty->write_wait);
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct * tty)
+{
+	struct bf535_serial *info = (struct bf535_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+		return;
+	
+	if (I_IXOFF(tty))
+		info->x_char = STOP_CHAR(tty);
+
+	/* Turn off RTS line (do this atomic) */
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+	struct bf535_serial *info = (struct bf535_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+		return;
+	
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			info->x_char = START_CHAR(tty);
+	}
+
+	/* Assert RTS line (do this atomic) */
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int get_serial_info(struct bf535_serial * info,
+			   struct serial_struct * retinfo)
+{
+	struct serial_struct tmp;
+  
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = info->type;
+	tmp.line = info->line;
+	tmp.hub2 = info->hub2;
+	tmp.irq = info->irq;
+	tmp.flags = info->flags;
+	tmp.baud_base = info->baud_base;
+	tmp.close_delay = info->close_delay;
+	tmp.closing_wait = info->closing_wait;
+	tmp.custom_divisor = info->custom_divisor;
+	copy_to_user(retinfo,&tmp,sizeof(*retinfo));
+	return 0;
+}
+
+static int set_serial_info(struct bf535_serial * info,
+			   struct serial_struct * new_info)
+{
+	struct serial_struct new_serial;
+	struct bf535_serial old_info;
+	int    retval = 0;
+
+	if (!new_info)
+		return -EFAULT;
+	copy_from_user(&new_serial,new_info,sizeof(new_serial));
+	old_info = *info;
+
+	if (!suser()) {
+		if ((new_serial.baud_base != info->baud_base) ||
+		    (new_serial.type != info->type) ||
+		    (new_serial.close_delay != info->close_delay) ||
+		    ((new_serial.flags & ~S_USR_MASK) !=
+		     (info->flags & ~S_USR_MASK)))
+			return -EPERM;
+		info->flags = ((info->flags & ~S_USR_MASK) |
+			       (new_serial.flags & S_USR_MASK));
+		info->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	if (info->count > 1)
+		return -EBUSY;
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+	info->baud_base = new_serial.baud_base;
+	info->flags = ((info->flags & ~S_FLAGS) |
+			(new_serial.flags & S_FLAGS));
+	info->type = new_serial.type;
+	info->close_delay = new_serial.close_delay;
+	info->closing_wait = new_serial.closing_wait;
+
+check_and_exit:
+	retval = startup(info);
+	return retval;
+}
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space. 
+ */
+static int get_lsr_info(struct bf535_serial * info, unsigned int *value)
+{
+	unsigned char status;
+
+	cli();
+
+	status = 0; /* no CTS status pin in BlackFin Serial */
+	sti();
+	put_user(status,value);
+	return 0;
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void send_break(	struct bf535_serial * info, int duration)
+{
+        unsigned long flags = 0;
+	int	 idx = info->hub2;
+
+        current->state = TASK_INTERRUPTIBLE;
+        save_flags(flags);
+        cli();
+	UART_LCR(idx) |= UART_LCR_SB;
+        schedule_timeout(duration);
+	UART_LCR(idx) &= ~UART_LCR_SB;
+        restore_flags(flags);
+}
+
+static int rs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	int error;
+	struct bf535_serial * info = (struct bf535_serial *)tty->driver_data;
+	int retval;
+
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
+	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+	
+	switch (cmd) {
+		case TCSBRK:	/* SVID version: non-zero arg --> no break */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (!arg)
+				send_break(info, HZ/4);	/* 1/4 second */
+			return 0;
+		case TCSBRKP:	/* support for POSIX tcsendbreak() */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+			return 0;
+		case TIOCGSOFTCAR:
+			error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long));
+			if (error)
+				return error;
+			put_user(C_CLOCAL(tty) ? 1 : 0,
+				    (unsigned long *) arg);
+			return 0;
+		case TIOCSSOFTCAR:
+			get_user(arg, (unsigned long *) arg);
+			tty->termios->c_cflag =
+				((tty->termios->c_cflag & ~CLOCAL) |
+				 (arg ? CLOCAL : 0));
+			return 0;
+		case TIOCGSERIAL:
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+						sizeof(struct serial_struct));
+			if (error)
+				return error;
+			return get_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSSERIAL:
+			return set_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSERGETLSR: /* Get line status register */
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+				sizeof(unsigned int));
+			if (error)
+				return error;
+			else
+			    return get_lsr_info(info, (unsigned int *) arg);
+
+		case TIOCSERGSTRUCT:
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+						sizeof(struct bf535_serial));
+			if (error)
+				return error;
+			copy_to_user((struct bf535_serial *) arg,
+				    info, sizeof(struct bf535_serial));
+			return 0;
+			
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	struct bf535_serial *info = (struct bf535_serial *)tty->driver_data;
+
+	if (tty->termios->c_cflag == old_termios->c_cflag)
+		return;
+
+	bf535_change_speed(info);
+
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+	
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * S structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+	struct bf535_serial * info = (struct bf535_serial *)tty->driver_data;
+	unsigned long flags = 0;
+	int	 idx = info->hub2;
+
+	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+		return;
+	
+	save_flags(flags); cli();
+	
+	if (tty_hung_up_p(filp)) {
+		restore_flags(flags);
+		return;
+	}
+	
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  Info->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+		       "info->count is %d\n", info->count);
+		info->count = 1;
+	}
+	if (--info->count < 0) {
+		printk("rs_close: bad serial port count for ttyS%d: %d\n",
+		       info->line, info->count);
+		info->count = 0;
+	}
+	if (info->count) {
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= S_CLOSING;
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & S_NORMAL_ACTIVE)
+		info->normal_termios = *tty->termios;
+	if (info->flags & S_CALLOUT_ACTIVE)
+		info->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != S_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+
+	ACCESS_PORT_IER(idx) /* Change access to IER & data port */
+	UART_IER(idx) = 0;
+
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (tty->ldisc.num != ldiscs[N_TTY].num) {
+		if (tty->ldisc.close)
+			(tty->ldisc.close)(tty);
+		tty->ldisc = ldiscs[N_TTY];
+		tty->termios->c_line = N_TTY;
+		if (tty->ldisc.open)
+			(tty->ldisc.open)(tty);
+	}
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(S_NORMAL_ACTIVE|S_CALLOUT_ACTIVE|
+			 S_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	restore_flags(flags);
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+void rs_hangup(struct tty_struct *tty)
+{
+	struct bf535_serial * info = (struct bf535_serial *)tty->driver_data;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
+		return;
+	
+	rs_flush_buffer(tty);
+	shutdown(info);
+	info->event = 0;
+	info->count = 0;
+	info->flags &= ~(S_NORMAL_ACTIVE|S_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file * filp,
+			   struct bf535_serial *info)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int		retval;
+	int		do_clocal = 0;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (info->flags & S_CLOSING) {
+		interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		if (info->flags & S_HUP_NOTIFY)
+			return -EAGAIN;
+		else
+			return -ERESTARTSYS;
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & S_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+		    (info->flags & S_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+		    return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+		    (info->flags & S_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+		    return -EBUSY;
+		info->flags |= S_CALLOUT_ACTIVE;
+		return 0;
+	}
+	
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & S_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= S_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & S_CALLOUT_ACTIVE) {
+		if (info->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+	
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, info->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+
+	info->count--;
+	info->blocked_open++;
+	while (1) {
+		cli();
+		if (!(info->flags & S_CALLOUT_ACTIVE))
+			bf535_rtsdtr(info, 1);
+		sti();
+		current->state = TASK_INTERRUPTIBLE;
+		if (tty_hung_up_p(filp) ||
+		    !(info->flags & S_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & S_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;	
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & S_CALLOUT_ACTIVE) &&
+		    !(info->flags & S_CLOSING) && do_clocal)
+			break;
+                if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&info->open_wait, &wait);
+	if (!tty_hung_up_p(filp))
+		info->count++;
+	info->blocked_open--;
+
+	if (retval)
+		return retval;
+	info->flags |= S_NORMAL_ACTIVE;
+	return 0;
+}	
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its S structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+int rs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct bf535_serial	*info;
+	int 			retval, line;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	
+	if ((line < 0) || (line >= NR_PORTS)) 
+		return -ENODEV;
+
+	info = bf535_soft + line;
+
+	if (serial_paranoia_check(info, tty->device, "rs_open"))
+		return -ENODEV;
+#ifdef SERIAL_DEBUG_OPEN
+        printk("bf535_open %s%d, count = %d\n", tty->driver.name, info->line,
+               info->count);
+#endif
+
+	info->count++;
+	tty->driver_data = info;
+	info->tty = tty;
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval)
+		return retval;
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+                printk("bf535_open returning after block_til_ready with %d\n",
+                       retval);
+#endif 
+		return retval;
+	}
+
+	if ((info->count == 1) && (info->flags & S_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->normal_termios;
+		else 
+			*tty->termios = info->callout_termios;
+		bf535_change_speed(info);
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+	return 0;
+}
+
+/* Finally, routines used to initialize the serial driver. */
+
+static void show_serial_version(void)
+{
+	printk("BlackFin serial driver version 1.00\n");
+}
+
+/* rsbf535_init inits the driver *
+static */ int __init rsbf535_init(void)
+{
+	int i, flags = 0;
+	struct bf535_serial *info;
+	
+	/* Setup base handler, and timer table. */
+	init_bh(SERIAL_BH, do_serial_bh);
+	show_serial_version();
+
+	/* Initialize the tty_driver structure */
+	/* NOTE: Not all of this is exactly right for us. */
+	
+	memset(&bf535_serial_driver, 0, sizeof(struct tty_driver));
+	bf535_serial_driver.magic = TTY_DRIVER_MAGIC;
+	bf535_serial_driver.name = "ttyS";
+	bf535_serial_driver.major = TTY_MAJOR;
+	bf535_serial_driver.minor_start = 64; 
+	bf535_serial_driver.num = NR_PORTS;
+	bf535_serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	bf535_serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	bf535_serial_driver.init_termios = tty_std_termios;
+	bf535_serial_driver.init_termios.c_cflag = 
+			bf535_console_cbaud | CS8 | CREAD | HUPCL | CLOCAL;
+	bf535_serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	bf535_serial_driver.refcount = &bf535_serial_refcount;
+	bf535_serial_driver.table = bf535_serial_table;
+	bf535_serial_driver.termios = bf535_serial_termios;
+	bf535_serial_driver.termios_locked = bf535_serial_termios_locked;
+
+	bf535_serial_driver.open = rs_open;
+	bf535_serial_driver.close = rs_close;
+	bf535_serial_driver.write = rs_write;
+	bf535_serial_driver.flush_chars = rs_flush_chars;
+	bf535_serial_driver.put_char = rs_put_char;
+	bf535_serial_driver.write_room = rs_write_room;
+	bf535_serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	bf535_serial_driver.flush_buffer = rs_flush_buffer;
+	bf535_serial_driver.ioctl = rs_ioctl;
+	bf535_serial_driver.throttle = rs_throttle;
+	bf535_serial_driver.unthrottle = rs_unthrottle;
+/*	bf535_serial_driver.send_xchar = ????	*/
+	bf535_serial_driver.set_termios = rs_set_termios;
+	bf535_serial_driver.stop = rs_stop;
+	bf535_serial_driver.start = rs_start;
+	bf535_serial_driver.hangup = rs_hangup;
+	bf535_serial_driver.set_ldisc = rs_set_ldisc;
+/*	bf535_serial_driver.wait_until_sent = ????	*/
+/*	bf535_serial_driver.read_proc = ????	*/
+
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code. ??? --tonyko
+	 */
+	bf535_callout_driver = bf535_serial_driver;
+	bf535_callout_driver.name = "cua";
+	bf535_callout_driver.major = TTYAUX_MAJOR;
+	bf535_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+
+	if (tty_register_driver(&bf535_serial_driver))
+		panic("Couldn't register serial driver\n");
+	if (tty_register_driver(&bf535_callout_driver))
+		panic("Couldn't register callout driver\n");
+	
+	save_flags(flags); cli();
+
+        /*
+         *      Configure all the attached serial ports.
+         */
+	for (i = 0, info = bf535_soft; (i < NR_PORTS); i++, info++){
+		info->magic = SERIAL_MAGIC;
+		info->tty = 0;
+		info->custom_divisor = 16;
+		info->close_delay = 50;
+		info->closing_wait = 3000;
+		info->x_char = 0;
+		info->event = 0;
+		info->count = 0;
+		info->blocked_open = 0;
+		info->tqueue.routine = do_softint;
+		info->tqueue.data = info;
+		info->tqueue_hangup.routine = do_serial_hangup;
+		info->tqueue_hangup.data = info;
+		info->callout_termios =bf535_callout_driver.init_termios;
+		info->normal_termios = bf535_serial_driver.init_termios;
+		init_waitqueue_head(&info->open_wait);
+		init_waitqueue_head(&info->close_wait);
+		info->line = i;
+		info->is_cons = 1; /* Means shortcuts work */
+	
+		switch(i){
+			case 0:
+				info->irq = IRQ_UART0;
+				break;
+			case 1:
+				info->irq = IRQ_UART1;
+				break;
+		}
+		
+		printk("%s%d at irq = %d", \
+			bf535_serial_driver.name, i, info->irq);
+		printk(" is a builtin BlackFin UART\n");
+	}
+	restore_flags(flags);
+
+	if (request_irq(IRQ_UART0, rs_interrupt, IRQ_FLG_STD, 
+                        "BlkFin_UART0", NULL))
+	    panic("Unable to attach BlackFin UART0 interrupt\n");
+	if (request_irq(IRQ_UART1, rs_interrupt, IRQ_FLG_STD, 
+                        "BlkFin_UART1", NULL))
+	    panic("Unable to attach BlackFin UART1 interrupt\n");
+	printk("Enabling Serial UART0/1 Interrupts\n");
+	enable_irq(IRQ_UART0);
+	enable_irq(IRQ_UART1);
+
+	return 0;
+}
+
+/*
+ * register_serial and unregister_serial allows for serial ports to be
+ * configured at run-time, to support PCMCIA modems.
+ */
+/* NOTE : Unused at this time, just here to make things link. */
+/*int register_serial(struct serial_struct *req)
+{
+	return -1;
+}
+
+void unregister_serial(int line)
+{
+	return;
+}*/
+	
+module_init(rsbf535_init);
+/* DAVIDM module_exit(rsbf535_fini); */
+
+
+/* setting console baud rate: CONFIG_SERIAL_CONSOLE_PORT */
+static void bf535_set_baud( void )
+{
+	int	i;
+
+	/* Change access to IER & data port */
+	ACCESS_PORT_IER(CONFIG_SERIAL_CONSOLE_PORT) 
+	UART_IER(CONFIG_SERIAL_CONSOLE_PORT) &= ~UART_IER_ETBEI;
+
+again:
+	for (i = 0; i < sizeof(baud_table) / sizeof(baud_table[0]); i++)
+		if (baud_table[i] == bf535_console_baud)
+			break;
+	if (i >= sizeof(baud_table) / sizeof(baud_table[0])) {
+		bf535_console_baud = 9600;
+		goto again;
+	}
+
+	ACCESS_LATCH(CONFIG_SERIAL_CONSOLE_PORT) /*Set to access divisor latch*/
+	UART_DLL(CONFIG_SERIAL_CONSOLE_PORT) = hw_baud_table[i].dl_low;
+	UART_DLH(CONFIG_SERIAL_CONSOLE_PORT) = hw_baud_table[i].dl_high;
+
+	UART_LCR(CONFIG_SERIAL_CONSOLE_PORT) |= UART_LCR_WLS8;
+	UART_LCR(CONFIG_SERIAL_CONSOLE_PORT) &= ~UART_LCR_PEN;
+
+	/* Change access to IER & data port */
+	ACCESS_PORT_IER(CONFIG_SERIAL_CONSOLE_PORT) 
+        UART_IER(CONFIG_SERIAL_CONSOLE_PORT) |=(UART_IER_ETBEI | UART_IER_ELSI);
+	bf535_console_initted = 1;
+	return;
+}
+
+
+int bf535_console_setup(struct console *cp, char *arg)
+{
+	int	i, n = CONSOLE_BAUD_RATE;
+
+	if (!cp)
+		return(-1);
+
+	if (arg)
+		n = simple_strtoul(arg,NULL,0);
+
+	for (i = 0; i < BAUD_TABLE_SIZE; i++)
+		if (baud_table[i] == n)
+			break;
+	if (i < BAUD_TABLE_SIZE) {
+		bf535_console_baud = n;
+		bf535_console_cbaud = 0;
+		if (i > 15) {
+			bf535_console_cbaud |= CBAUDEX;
+			i -= 15;
+		}
+		bf535_console_cbaud |= i;
+	}
+
+	bf535_set_baud(); /* make sure baud rate changes */
+	return(0);
+}
+
+static kdev_t bf535_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+void bf535_console_write (struct console *co, const char *str,
+			   unsigned int count)
+{
+    if (!bf535_console_initted)
+	bf535_set_baud();
+    while (count--) {
+        if (*str == '\n')	/* if a LF, also do CR... */
+           local_put_char( CONFIG_SERIAL_CONSOLE_PORT, '\r');
+        local_put_char( CONFIG_SERIAL_CONSOLE_PORT, *str++ );
+    }
+}
+
+static struct console bf535_driver = {
+	name:		"ttyS",
+	write:		bf535_console_write,
+	read:		NULL,
+	device:		bf535_console_device,
+	unblank:	NULL,
+	setup:		bf535_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		CONFIG_SERIAL_CONSOLE_PORT,
+	cflag:		0,
+	next:		NULL
+};
+
+void bf535_console_init(void)
+{
+	register_console(&bf535_driver);
+}
diff -urN linux-2.4.29/drivers/char/bf535_serial.h linux-2.4.29-uc1/drivers/char/bf535_serial.h
--- linux-2.4.29/drivers/char/bf535_serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/bf535_serial.h	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,153 @@
+/* bf535_serial.h: Definitions for the BlackFin DSP serial driver.
+ *
+ * Copyright (C) 2001	Tony Z. Kou	tonyko@arcturusnetworks.com
+ * Copyright (C) 2001   Arcturus Networks Inc. <www.arcturusnetworks.com>
+ *
+ * Based on code from 68328serial.c which was: 
+ * Copyright (C) 1995       David S. Miller    <davem@caip.rutgers.edu>
+ * Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ * Copyright (C) 1998, 1999 D. Jeff Dionne     <jeff@uclinux.org>
+ * Copyright (C) 1999       Vladimir Gurevich  <vgurevic@cisco.com>
+ */
+
+#ifndef _BLKFin_SERIAL_H
+#define _BLKFin_SERIAL_H
+
+#include <linux/config.h>
+#include <asm/blackfin.h>
+
+struct serial_struct { /****** ??do we need a specific serial_struct */
+	int	type;
+	int	line;
+	int	hub2;
+	int	irq;
+	int	flags;
+	int	xmit_fifo_size;
+	int	custom_divisor;
+	int	baud_base;
+	unsigned short	close_delay;
+	char	reserved_char[2];
+	int	hub6;  /* FIXME: We don't have AT&T Hub6 boards! */
+	unsigned short	closing_wait; /* time to wait before closing */
+	unsigned short	closing_wait2; /* no longer used... */
+	int	reserved[4];
+};
+
+/*
+ * For the close wait times, 0 means wait forever for serial port to
+ * flush its output.  65535 means don't wait at all.
+ */
+#define S_CLOSING_WAIT_INF	0
+#define S_CLOSING_WAIT_NONE	65535
+
+/*
+ * Definitions for S_struct (and serial_struct) flags field
+ */
+#define S_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes 
+				   on the callout port */
+#define S_FOURPORT  0x0002	/* Set OU1, OUT2 per AST Fourport settings */
+#define S_SAK	0x0004	/* Secure Attention Key (Orange book) */
+#define S_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
+
+#define S_SPD_MASK	0x0030
+#define S_SPD_HI	0x0010	/* Use 56000 instead of 38400 bps */
+
+#define S_SPD_VHI	0x0020  /* Use 115200 instead of 38400 bps */
+#define S_SPD_CUST	0x0030  /* Use user-specified divisor */
+
+#define S_SKIP_TEST	0x0040   /* Skip UART test during autoconfiguration */
+#define S_AUTO_IRQ	0x0080   /* Do automatic IRQ during autoconfiguration */
+#define S_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
+#define S_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
+#define S_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
+
+#define S_FLAGS		0x0FFF	 /* Possible legal S flags */
+#define S_USR_MASK	0x0430	 /* Legal flags that non-privileged
+				  * users can set or reset */
+
+/* Internal flags used only by kernel/chr_drv/serial.c */
+#define S_INITIALIZED		0x80000000 /* Serial port was initialized */
+#define S_CALLOUT_ACTIVE	0x40000000 /* Call out device is active */
+#define S_NORMAL_ACTIVE		0x20000000 /* Normal device is active */
+#define S_BOOT_AUTOCONF		0x10000000 /* Autoconfigure port on bootup */
+#define S_CLOSING		0x08000000 /* Serial port is closing */
+#define S_CTS_FLOW		0x04000000 /* Do CTS flow control */
+#define S_CHECK_CD		0x02000000 /* i.e., CLOCAL */
+
+/* Software state per channel */
+
+#ifdef __KERNEL__
+
+/*
+ * This is our internal structure for each serial port's state.
+ * 
+ * Many fields are paralleled by the structure used by the serial_struct
+ * structure.
+ *
+ * For definitions of the flags field, see tty.h
+ */
+
+struct bf535_serial {
+	/* We need to know the current clock divisor
+	 * to read the bps rate the chip has currently
+	 * loaded.
+	 */
+	int			magic;
+	int			hub2;
+	int			irq;
+	int			flags; 		/* defined in tty.h */
+
+	char soft_carrier;  /* Use soft carrier on this channel */
+	char break_abort;   /* Is serial console in, so process brk/abrt */
+	char is_cons;       /* Is this our console. */
+
+	unsigned char		clk_divisor; 
+	int			baud;
+	int			baud_base;
+	int			type; 		/* UART type */
+	struct tty_struct 	*tty;
+	int			read_status_mask;
+	int			ignore_status_mask;
+	int			timeout;
+	int			xmit_fifo_size;
+	int			custom_divisor;
+	int			x_char;	/* xon/xoff character */
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int			count;	    /* # of fd on device */
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+	unsigned char 		*xmit_buf;
+	int			xmit_head;
+	int			xmit_tail;
+	int			xmit_cnt;
+	struct tq_struct	tqueue;
+	struct tq_struct	tqueue_hangup;
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+};
+
+
+#define SERIAL_MAGIC 0x5301	/******* ?? value for BlackFin Serial */
+#define UART_IRQ_NUM	10	/* change accordingly */
+
+/*
+ * The size of the serial xmit buffer is 1 page, or 4096 bytes
+ */
+#define SERIAL_XMIT_SIZE 4096
+
+/*
+ * Events are used to schedule things to happen at timer-interrupt
+ * time, instead of at rs interrupt time.
+ */
+#define RS_EVENT_WRITE_WAKEUP	0
+
+#endif /* __KERNEL__ */
+#endif /* (_BLKFin_SERIAL_H) */
diff -urN linux-2.4.29/drivers/char/can4linux/can4linux.h linux-2.4.29-uc1/drivers/char/can4linux/can4linux.h
--- linux-2.4.29/drivers/char/can4linux/can4linux.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can4linux.h	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,193 @@
+/*
+ * can4linux.h - can4linux CAN driver module
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001 port GmbH Halle/Saale
+ *------------------------------------------------------------------
+ * $Header: /var/cvs/uClinux-2.4.x/drivers/char/can4linux/can4linux.h,v 1.1 2003/07/18 00:11:46 gerg Exp $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: can4linux.h,v $
+ * Revision 1.1  2003/07/18 00:11:46  gerg
+ * I followed as much rules as possible (I hope) and generated a patch for the
+ * uClinux distribution. It contains an additional driver, the CAN driver, first
+ * for an SJA1000 CAN controller:
+ *   uClinux-dist/linux-2.4.x/drivers/char/can4linux
+ * In the "user" section two entries
+ *   uClinux-dist/user/can4linux     some very simple test examples
+ *   uClinux-dist/user/horch         more sophisticated CAN analyzer example
+ *
+ * Patch submitted by Heinz-Juergen Oertel <oe@port.de>.
+ *
+ *
+ *
+ *
+ *--------------------------------------------------------------------------
+ */
+
+
+/**
+* \file can.h
+* \author Heinz-Jürgen Oertel, port GmbH
+* $Revision: 1.1 $
+* $Date: 2003/07/18 00:11:46 $
+*
+* can4linux interface definitions
+*
+*
+*
+*/
+
+
+#ifndef __CAN_H
+#define __CAN_H
+
+
+#ifndef __KERNEL__
+#include <sys/time.h>
+#endif
+ /*---------- the can message structure */
+
+#define CAN_MSG_LENGTH 8		/**< maximum length of a CAN frame */
+
+
+#define MSG_RTR		(1<<0)		/**< RTR Message */
+#define MSG_OVR		(1<<1)		/**< CAN controller Msg overflow error */
+#define MSG_EXT		(1<<2)		/**< extended message format */
+#define MSG_PASSIVE	(1<<4)		/**< controller in error passive */
+#define MSG_BUSOFF      (1<<5)		/**< controller Bus Off  */
+#define MSG_       	(1<<6)		/**<  */
+#define MSG_BOVR	(1<<7)		/**< receive/transmit buffer overflow */
+/**
+* mask used for detecting CAN errors in the canmsg_t flags field
+*/
+#define MSG_ERR_MASK	(MSG_OVR + MSG_PASSIVE + MSG_BUSOFF + MSG_BOVR)
+
+/**
+* The CAN message structure.
+* Used for all data transfers between the application and the driver
+* using read() or write().
+*/
+typedef struct {
+    /** flags, indicating or controlling special message properties */
+    int             flags;
+    int             cob;	 /**< CAN object number, used in Full CAN  */
+    unsigned   long id;		 /**< CAN message ID, 4 bytes  */
+    struct timeval  timestamp;	 /**< time stamp for received messages */
+    short      int  length;	 /**< number of bytes in the CAN message */
+    unsigned   char data[CAN_MSG_LENGTH]; /**< data, 0...8 bytes */
+} canmsg_t;
+
+
+
+/**
+---------- IOCTL requests */
+
+#define COMMAND 	 0	/**< IOCTL command request */
+#define CONFIG 		 1	/**< IOCTL configuration request */
+#define SEND 		 2	/**< IOCTL request */
+#define RECEIVE 	 3	/**< IOCTL request */
+#define CONFIGURERTR 	 4	/**< IOCTL request */
+#define STATUS           5      /**< IOCTL status request */
+
+/*---------- CAN ioctl parameter types */
+
+/**
+ IOCTL Command request parameter structure */
+typedef struct Command_par {
+    int cmd;			/**< special driver command */
+    int error;	 		/**< return value */
+    unsigned long retval;	/**< return value */
+} Command_par_t ;
+
+
+/**
+ IOCTL Configuration request parameter structure */
+typedef struct Config_par {
+    int target;			/**< special configuration target */
+    unsigned long val1;		/**< 1. parameter for the target */
+    unsigned long val2;		/**< 2. parameter for the target */
+    int error;	 		/**< return value for errno */
+    unsigned long retval;	/**< return value */
+} Config_par_t ;
+
+/**
+ IOCTL generic CAN controller status request parameter structure */
+typedef struct CanStatusPar { 
+    unsigned int baud;			/**< actual bit rate */
+    unsigned int status;		/**< CAN controller status register */
+    unsigned int error_warning_limit;	/**< the error warning limit */
+    unsigned int rx_errors;		/**< content of RX error counter */
+    unsigned int tx_errors;		/**< content of TX error counter */
+    unsigned int error_code;		/**< content of error code register */
+    unsigned int rx_buffer_size;	/**< size of rx buffer  */
+    unsigned int rx_buffer_used;	/**< number of messages */
+    unsigned int tx_buffer_size;	/**< size of tx buffer  */
+    unsigned int tx_buffer_used;	/**< number of messages */
+    unsigned long retval;		/**< return value */
+    unsigned int type;			/**< CAN controller / driver type */
+} CanStatusPar_t;
+
+/**
+ IOCTL  CanStatusPar.type CAN controller hardware chips */
+#define CAN_TYPE_UNSPEC		0
+#define CAN_TYPE_SJA1000	1
+#define CAN_TYPE_FlexCAN	2
+#define CAN_TYPE_TouCAN		3
+#define CAN_TYPE_82527		4
+#define CAN_TYPE_TwinCAN	5
+
+
+/**
+ IOCTL Send request parameter structure */
+typedef struct Send_par {
+    canmsg_t *Tx;		/**< CAN message struct  */
+    int error;	 		/**< return value for errno */
+    unsigned long retval;	/**< return value */
+} Send_par_t ;
+
+/**
+ IOCTL Receive request parameter structure */
+typedef struct Receive_par {
+    canmsg_t *Rx;		/**< CAN message struct  */
+    int error;	 		/**< return value for errno */
+    unsigned long retval;	/**< return value */
+} Receive_par_t ;
+
+/**
+IOCTL ConfigureRTR request parameter structure */
+typedef struct ConfigureRTR_par {
+    unsigned message;		/**< CAN message ID */
+    canmsg_t *Tx;		/**< CAN message struct  */
+    int error;	 		/**< return value for errno */
+    unsigned long retval;	/**< return value */
+} ConfigureRTR_par_t ;
+
+/**
+---------- IOCTL Command subcommands */
+
+# define CMD_START	1
+# define CMD_STOP 	2
+# define CMD_RESET	3
+
+
+/**
+---------- IOCTL Configure targets */
+
+# define CONF_ACC   	0	/* mask and code */
+# define CONF_ACCM   	1	/* mask only */
+# define CONF_ACCC   	2	/* code only */
+# define CONF_TIMING	3	/* bit timing */
+# define CONF_OMODE 	4	/* output control register */
+# define CONF_FILTER	5
+# define CONF_FENABLE	6
+# define CONF_FDISABLE	7
+
+#endif 	/* __CAN_H */
diff -urN linux-2.4.29/drivers/char/can4linux/can_close.c linux-2.4.29-uc1/drivers/char/can4linux/can_close.c
--- linux-2.4.29/drivers/char/can4linux/can_close.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_close.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,106 @@
+/*
+ * can_close - can4linux CAN driver module
+ *
+ * can4linux -- LINUX CAN device driver source
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ * 
+ * Copyright (c) 2001 port GmbH Halle/Saale
+ * (c) 2001 Heinz-Jürgen Oertel (oe@port.de)
+ *          Claus Schroeter (clausi@chemie.fu-berlin.de)
+ * derived from the the LDDK can4linux version
+ *     (c) 1996,1997 Claus Schroeter (clausi@chemie.fu-berlin.de)
+ *------------------------------------------------------------------
+ * $Header: $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: can_close.c,v $
+ *
+ *
+ *
+ *
+ *--------------------------------------------------------------------------
+ */
+
+
+/**
+* \file can_close.c
+* \author Heinz-Jürgen Oertel, port GmbH
+* $Revision: 1.5 $
+* $Date: 2002/08/08 17:57:24 $
+*
+*
+*/
+/*
+*
+*/
+#include "can_defs.h"
+
+extern int Can_isopen[];   		/* device minor already opened */
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+/***************************************************************************/
+/**
+*
+* \brief int close(int fd);
+* close a file descriptor
+* \param fd The descriptor to close.
+*
+* \b close closes a file descriptor, so that it no longer
+*  refers to any device and may be reused.
+* \returns
+* close returns zero on success, or -1 if an error occurred.
+* \par ERRORS
+*
+* the following errors can occur
+*
+* \arg \c BADF \b fd isn't a valid open file descriptor 
+*
+
+*/
+__LDDK_CLOSE_TYPE can_close ( __LDDK_CLOSE_PARAM )
+{
+    DBGin("can_close");
+    {
+	unsigned int minor = __LDDK_MINOR;
+
+	CAN_StopChip(minor);
+
+        /* since Vx.y (2.4?) macros defined in ioport.h,
+           called is  __release_region()  */
+#if defined(CAN_PORT_IO) 
+	release_region(Base[minor], can_range[minor] );
+#else
+	release_mem_region(Base[minor], can_range[minor] );
+#endif
+
+#ifdef CAN_USE_FILTER
+	Can_FilterCleanup(minor);
+#endif
+	Can_FreeIrq(minor, IRQ[minor]);
+#if !defined(CONFIG_PPC)
+	/* printk("CAN module %d has been closed\n",minor); */
+#endif
+
+	if(Can_isopen[minor] > 0) {
+	    --Can_isopen[minor];		/* flag device as free */
+	    MOD_DEC_USE_COUNT;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)
+	    return 0;
+#endif
+	}
+	
+    }
+    DBGout();
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)
+    return -EBADF;
+#endif
+}
diff -urN linux-2.4.29/drivers/char/can4linux/can_core.c linux-2.4.29-uc1/drivers/char/can4linux/can_core.c
--- linux-2.4.29/drivers/char/can4linux/can_core.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_core.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,388 @@
+/*
+ * can_core - can4linux CAN driver module
+ *
+ * can4linux -- LINUX CAN device driver source
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ * 
+ * Copyright (c) 2001 port GmbH Halle/Saale
+ * (c) 2001 Heinz-Jürgen Oertel (oe@port.de)
+ *          Claus Schroeter (clausi@chemie.fu-berlin.de)
+ *------------------------------------------------------------------
+ * $Header: /var/cvs/uClinux-2.4.x/drivers/char/can4linux/can_core.c,v 1.1 2003/07/18 00:11:46 gerg Exp $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: can_core.c,v $
+ * Revision 1.1  2003/07/18 00:11:46  gerg
+ * I followed as much rules as possible (I hope) and generated a patch for the
+ * uClinux distribution. It contains an additional driver, the CAN driver, first
+ * for an SJA1000 CAN controller:
+ *   uClinux-dist/linux-2.4.x/drivers/char/can4linux
+ * In the "user" section two entries
+ *   uClinux-dist/user/can4linux     some very simple test examples
+ *   uClinux-dist/user/horch         more sophisticated CAN analyzer example
+ *
+ * Patch submitted by Heinz-Juergen Oertel <oe@port.de>.
+ *
+ *
+ *
+ *
+ *
+ *--------------------------------------------------------------------------
+ */
+
+
+/**
+* \file can_core.c
+* \author Heinz-Jürgen Oertel, port GmbH
+* $Revision: 1.1 $
+* $Date: 2003/07/18 00:11:46 $
+*
+* Contains the code for module initialization.
+* The functions herein are never called directly by the user
+* but when the driver module is loaded into the kernel space
+* or unloaded.
+*
+* The driver is highly configurable using the \b sysctl interface.
+* For a description see main page.
+
+*/
+
+
+/****************************************************************************/
+/**
+* \mainpage  can4linx - CAN network device driver
+*
+The LINUX CAN driver can be used to control the CAN bus
+connected with the  AT-CAN-MINI  PC interface card.
+This project was done in cooperation with the  LINUX LLP Project
+to control laboratory or automation devices via CAN.
+
+The full featured can4linux supports many different interface boards.
+It is possible to use different kinds of boards at the same time.
+Up to four boards can be placed in one computer.
+With this feature it is possible to use /dev/can0 and
+/dev/can2 for two boards AT-CAN-MINI with SJA1000
+and /dev/can1 and /dev/can3 with two CPC-XT equipped with Intel 82527.
+In all these configurations
+the programmer sees the same driver interface with
+open(), close(), read(), write() and ioctl() calls
+( can_open(), can_close(), can_read(), can_write(), can_ioctl() ).
+
+The driver itself is highly configurable
+using the /proc interface of the LINUX kernel. 
+
+The following listing shows a typical configuration with three boards: 
+
+\code
+$ grep . /proc/sys/Can/\*
+/proc/sys/Can/AccCode:  -1       -1      -1      -1
+/proc/sys/Can/AccMask:  -1       -1      -1      -1
+/proc/sys/Can/Base:     800      672     832     896
+/proc/sys/Can/Baud:     125      125     125     250
+/proc/sys/Can/Chipset:  SJA1000
+/proc/sys/Can/IOModel:  pppp
+/proc/sys/Can/IRQ:      5     7       3       5
+/proc/sys/Can/Outc:     250   250     250     0
+/proc/sys/Can/Overrun:  0     0       0       0
+/proc/sys/Can/RxErr:    0     0       0       0
+/proc/sys/Can/Timeout:  100   100     100     100
+/proc/sys/Can/TxErr:    0     0       0       0
+/proc/sys/Can/dbgMask:  0
+/proc/sys/Can/version:  3.0_ATCANMINI_PELICAN
+\endcode
+
+
+This above mentioned full flexibility
+is not needed in embedded applications.
+For this applications, a stripped-down version exists.
+It uses the same programming interface
+but does the most configurations at compile time.
+That means especially that only one CAN controller support with
+a special register access method is compiled into the driver.
+Actually the only CAN controller supported by this version
+is the Philips SJA 1000 in both the compatibility mode 
+\b BasicCAN and the Philips \PeliCAN mode (compile time selectable).
+
+
+
+The following sections are describing the \e sysctl entries.
+
+\par AccCode/AccMask
+contents of the message acceptance mask and acceptance code registers
+of 82x200/SJA1000 compatible CAN controllers (see can_ioctl()).
+\par Base
+CAN controllers base address for each board.
+Depending of the \e IOModel entry that can be a memory or I/O address.
+(read-only for PCI boards)
+\par Baud
+used bit rate for this board
+\par Chipset
+name of the supported CAN chip used with this boards
+Read only for this version.
+\par IOModel
+one letter for each port. Readonly.
+Read the CAN register access model.
+The following models are currently supported:
+\li m - memory access, the registers are directly mapped into memory
+\li f - fast register access, special mode for the 82527
+     uses memory locations for register addresses 
+     (ELIMA)
+\li p - port I/O,  80x86 specific I/O address range
+     (AT-CAN-MINI)
+\li b - special mode for the B&R CAN card,
+     two special I/O addresses for register addressing and access
+Since version 2.4 set at compile time.
+\par IRQ
+used IRQ numbers, one value for each board.
+(read-only for PCI boards)
+\par Outc
+value of the output control register of the CAN controller
+Since version 2.4 set at compile time.
+A board specific value is used when the module the first time is loaded.
+This board specific value can be reloded by writing the value 0
+to \e Outc .
+\par Overrun
+counter for overrun conditions in the CAN controller
+\par RxErr
+counter for CAN controller rx error conditions
+\par Timeout
+time out value for waiting for a successful transmission
+\par TxErr
+counter for CAN controller tx error conditions
+\par dbgMask
+if compiled with debugging support, writing a value greater then 0 
+enables debugging to \b syslogd
+\par version
+read only entry containing the drivers version number
+
+
+Please see also at can_ioctl() for some additional descriptions.
+
+For initially writing these sysctl entries after loading the driver
+(or at any time) a shell script utility does exist.
+It uses a board configuration file that is written over \e /proc/sys/Can .
+\code
+utils/cansetup port.conf
+\endcode
+or, like used in the Makefile:
+\code
+CONFIG := $(shell uname -n)
+
+# load host specific CAN configuration
+load:
+	@echo "Loading etc/$(CONFIG).conf CAN configuration"
+	utils/cansetup etc/$(CONFIG).conf
+	echo 0 >/proc/sys/Can/dbgMask
+\endcode
+Example *.conf files are located in the \e etc/ directory.
+
+\note
+This documentation was created using the wonderful tool
+\b Doxygen http://www.doxygen.org/index.html .
+Die Dokumentation wurde unter Verwendung von
+\b Doxygen http://www.doxygen.org/index.html
+erstellt
+
+*/
+
+#include "can_defs.h"
+/* #include <linux/version.h> */
+
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("H.-J. Oertel <oe@port.de>");
+MODULE_DESCRIPTION("CAN fieldbus driver");
+
+
+char kernel_version[] = UTS_RELEASE;
+
+int IRQ_requested[MAX_CHANNELS];
+int Can_minors[MAX_CHANNELS];			/* used as IRQ dev_id */
+#define LDDK_USE_REGISTER 1
+#ifdef LDDK_USE_REGISTER
+    int Can_major = Can_MAJOR; 
+#endif
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+struct file_operations can_fops = { 
+#if LINUX_VERSION_CODE >= 0x020400
+				/* This started being used during 2.4.0-test */
+    owner:		THIS_MODULE,
+#endif
+#if LINUX_VERSION_CODE >= 0x020201 
+    llseek:	NULL, 
+#else
+    lseek:	NULL, 
+#endif
+    read:	can_read,
+    write:	can_write,
+    readdir:	NULL, 
+#if LINUX_VERSION_CODE >= 0x020203 
+    poll:	can_select,
+#else
+    select:	can_select,
+#endif 
+    ioctl:	can_ioctl,
+    mmap:	NULL, 
+    open:	can_open,
+#if LINUX_VERSION_CODE >= 0x020203
+    flush:	NULL, /* flush call */
+#endif 
+    release:	can_close,
+    fsync:	NULL,
+    fasync:	NULL,
+};
+
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+
+/* int init_module(void) */
+int can_init(void)
+{
+int i;
+#if LDDK_USE_BLKREQUEST
+  extern int Can_request ();
+#endif
+
+  DBGin("init_module");
+#ifdef LDDK_USE_REGISTER
+    if( register_chrdev(Can_major, "Can", &can_fops) ) {
+	  printk("can't get Major %d\n", Can_major);
+      return(-EIO);
+    }
+  
+
+#endif
+    {
+	printk(__CAN_TYPE__ "CAN Driver " VERSION " (c) " __DATE__  " " __TIME__ "\n");
+	printk(" H.J. Oertel (oe@port.de)\n");
+	/* printk(" C.Schroeter (clausi@chemie.fu-berlin.de), H.D. Stich\n");  */
+	    
+    }
+
+    /*
+    initialize the variables layed down in /proc/sys/Can
+    */
+    for (i = 0; i < MAX_CHANNELS; i++) {
+	IOModel[i]       = IO_MODEL;
+	Baud[i]          = 125;
+
+	AccCode[i]       = AccMask[i] =  STD_MASK;
+	Timeout[i]       = 100;
+	Outc[i]          = CAN_OUTC_VAL;
+	IRQ_requested[i] = 0;
+	Can_minors[i]    = i;		/* used as IRQ dev_id */
+
+#if defined(MCF5282)
+	/* we have a really fixed address here */
+	Base[i] = (MCF_MBAR + 0x1c0000);
+	/* Because the MCF FlexCAN is using more then 1 Interrupt vector,
+	 * what should be specified here ?
+	 * For information purpose let's only specify  the first used here
+	 */
+	IRQ[i] = 136;
+#endif
+
+#if defined(CCPC104)
+        pc104_irqsetup();
+        IRQ[i]           = 67;          /* The only possible vector on CTRLink's 5282 CPU */
+        Base[i]          = 0x40000280;
+#endif
+    }
+    /* after initializing channel based parameters
+     * finisch some entries 
+     * and do drivers specific initialization
+     */
+    IOModel[i] = '\0';
+
+    /* CAN_register_dump(); */
+
+#if CAN4LINUX_PCI
+    /* make some sysctl entries read only
+     * IRQ number
+     * Base address
+     * and access mode
+     * are fixed and provided by the PCI BIOS
+     */
+    Can_sysctl_table[SYSCTL_IRQ - 1].mode = 0444;
+    Can_sysctl_table[SYSCTL_BASE - 1].mode = 0444;
+    /* printk("CAN pci test loaded\n"); */
+    /* dbgMask = 0; */
+    pcimod_scan();
+#endif
+#if defined(CCPC104)
+    /* The only possible interrupt could be IRQ4 on the PC104 Board */
+    Can_sysctl_table[SYSCTL_IRQ - 1].mode = 0444;
+#endif
+#if defined(MCF5282)
+    Can_sysctl_table[SYSCTL_BASE - 1].mode = 0444;
+#endif
+
+/* #if LDDK_USE_PROCINFO */
+/* #error procinfo */
+    /* register_procinfo(); */
+/* #endif */
+/* #if LDDK_USE_SYSCTL */
+    register_systables();
+/* #endif */
+
+#if LDDK_USE_BLKREQUEST
+    blk_dev[Can_major].request_fn = Can_request ;
+#endif
+
+    DBGout();
+    return 0;
+}
+
+/* void cleanup_module(void) */
+void can_exit(void)
+{
+    DBGin("cleanup_module");
+#ifndef MODULE
+    if (MOD_IN_USE) {
+      printk("Can : device busy, remove delayed\n");
+    }
+    /* printk("CAN: removed successfully \n"); */
+#endif
+	
+
+#if LDDK_USE_BLKREQUEST
+    blk_dev[Can_major].request_fn = NULL ;
+#endif
+#ifdef LDDK_USE_REGISTER
+    if( unregister_chrdev(Can_major, "Can") != 0 ){
+        printk("can't unregister Can, device busy \n");
+    } else {
+        printk("Can successfully removed\n");
+    }
+
+#endif
+#if LDDK_USE_PROCINFO
+    unregister_procinfo();
+#endif
+#if LDDK_USE_SYSCTL
+    unregister_systables();
+#endif
+    DBGout();
+}
+
+
+module_init(can_init);
+module_exit(can_exit);
+EXPORT_NO_SYMBOLS;
+
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
diff -urN linux-2.4.29/drivers/char/can4linux/can_debug.c linux-2.4.29-uc1/drivers/char/can4linux/can_debug.c
--- linux-2.4.29/drivers/char/can4linux/can_debug.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_debug.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,109 @@
+/* Can_debug
+ *
+ * can4linux -- LINUX CAN device driver source
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * 
+ * Copyright (c) 2001 port GmbH Halle/Saale
+ * (c) 2001 Heinz-Jürgen Oertel (oe@port.de)
+ *          Claus Schroeter (clausi@chemie.fu-berlin.de)
+ *------------------------------------------------------------------
+ * $Header: $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: Can_debug.c,v $
+ *
+ *
+ */
+#include "can_defs.h"
+
+
+/* default debugging level */
+
+#if DEBUG
+# ifndef DEFAULT_DEBUG
+  unsigned int   dbgMask  = \
+    (DBG_ENTRY | DBG_EXIT | DBG_BRANCH | DBG_DATA | DBG_INTR | DBG_1PPL)
+    & ~DBG_ALL;
+# else
+unsigned int   dbgMask  = 0;
+# endif
+#else
+unsigned int   dbgMask  = 0;
+#endif
+
+/* Print the string to the appropriate tty, the one
+ * the current task uses */
+#ifdef DEBUG
+void print_tty(const char *fmt, ...)
+{
+  /* The tty for the current task */
+  struct tty_struct *my_tty = current->tty;
+  /* If my_tty is NULL, it means that the current task
+   * has no tty you can print to (this is possible, for
+   * example, if it's a daemon). In this case, there's
+   * nothing we can do. */
+  if(my_tty != NULL)
+  {
+    va_list args;
+    static char str[1024];
+    int strlength = 0;
+
+    va_start(args, fmt);
+    strcpy(str, "can: ");
+    strlength = vsprintf(str+6, fmt, args);
+    strlength += 6;
+    va_end(args);
+
+    /* my_tty->driver is a struct which holds the tty's
+     * functions, one of which (write) is used to
+     * write strings to the tty. It can be used to take
+     * a string either from the user's memory segment
+     * or the kernel's memory segment.
+     *
+     * The function's first parameter is the tty to
+     * write to, because the  same function would
+     * normally be used for all tty's of a certain type.
+     * The second parameter controls whether the
+     * function receives a string from kernel memory
+     * (false, 0) or from user memory (true, non zero).
+     * The third parameter is a pointer to a string,
+     * and the fourth parameter is the length of
+     * the string.
+     */
+    (*(my_tty->driver).write)( my_tty, /* The tty itself */
+           0, /* We don't take the string from user space */
+           str, /* String */
+           strlength);  /* Length */
+
+    /* ttys were originally hardware devices, which
+     * (usually) adhered strictly to the ASCII standard.
+     * According to ASCII, to move to a new line you
+     * need two characters, a carriage return and a
+     * line feed. In Unix, on the other hand, the
+     * ASCII line feed is used for both purposes - so
+     * we can't just use \n, because it wouldn't have
+     * a carriage return and the next line will
+     * start at the column right
+     *                          after the line feed.
+     *
+     * BTW, this is the reason why the text file
+     * format is different between Unix and Windows.
+     * In CP/M and its derivatives, such as MS-DOS and
+     * Windows, the ASCII standard was strictly
+     * adhered to, and therefore a new line requires
+     * both a line feed and a carriage return.
+     */
+    (*(my_tty->driver).write)(my_tty,  0, "\015\012", 2);
+  }
+}
+#else
+#endif /* DEBUG */
+
diff -urN linux-2.4.29/drivers/char/can4linux/can_debug.h linux-2.4.29-uc1/drivers/char/can4linux/can_debug.h
--- linux-2.4.29/drivers/char/can4linux/can_debug.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_debug.h	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,53 @@
+/*
+ * can4linux project
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+*/
+#ifndef __DEBUG_INCLUDED
+#if DEBUG       
+
+#define DRIVER_NAME "Can"
+
+#define DBG_ALL      (1 << 0)
+#define DBG_ENTRY   ((1 << 1) | DBG_ALL)
+#define DBG_EXIT    ((1 << 2) | DBG_ALL)
+#define DBG_BRANCH  ((1 << 3) | DBG_ALL)
+#define DBG_DATA    ((1 << 4) | DBG_ALL)
+#define DBG_INTR    ((1 << 5) | DBG_ALL)
+#define DBG_REG     ((1 << 6) | DBG_ALL)
+#define DBG_SPEC    ((1 << 7) | DBG_ALL)
+#define DBG_1PPL     (1 << 8)		/* one DBG print statement/line */
+
+extern unsigned int dbgMask;
+
+
+/* class of debug statements allowed		*/
+
+extern int   fidx;     
+extern char *fstk[];
+extern char *ffmt[];
+
+#define DBGprint(ms,ar)	{ if (dbgMask && (dbgMask & ms)) \
+	{ printk("Can: - :"); printk ar; printk("\n"); } }
+#define DBGin(id)	{ DBGprint(DBG_ENTRY, ("in  " id)); }
+#define DBGout()	{ DBGprint(DBG_EXIT, ("out  ")); }
+
+#define DEBUG_TTY(n, args...) if(dbgMask >= (n)) print_tty(args);
+
+#else					
+#define DBGprint(ms,ar)	{ }
+#define DBGin(id)	{ }
+#define DBGout()	{ }
+#define DEBUG_TTY(n, args...)
+extern unsigned int dbgMask;
+
+#endif					
+
+#define __DEBUG_INCLUDED
+#endif
+
+
+
diff -urN linux-2.4.29/drivers/char/can4linux/can_defs.h linux-2.4.29-uc1/drivers/char/can4linux/can_defs.h
--- linux-2.4.29/drivers/char/can4linux/can_defs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_defs.h	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,711 @@
+/*
+ * can_read - can4linux CAN driver module
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001 port GmbH Halle/Saale
+ *------------------------------------------------------------------
+ * $Header: /var/cvs/uClinux-2.4.x/drivers/char/can4linux/can_defs.h,v 1.1 2003/07/18 00:11:46 gerg Exp $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: can_defs.h,v $
+ * Revision 1.1  2003/07/18 00:11:46  gerg
+ * I followed as much rules as possible (I hope) and generated a patch for the
+ * uClinux distribution. It contains an additional driver, the CAN driver, first
+ * for an SJA1000 CAN controller:
+ *   uClinux-dist/linux-2.4.x/drivers/char/can4linux
+ * In the "user" section two entries
+ *   uClinux-dist/user/can4linux     some very simple test examples
+ *   uClinux-dist/user/horch         more sophisticated CAN analyzer example
+ *
+ * Patch submitted by Heinz-Juergen Oertel <oe@port.de>.
+ *
+ *
+ *
+ *
+ *
+ *--------------------------------------------------------------------------
+ */
+
+
+/**
+* \file can_defs.h
+* \author Name, port GmbH
+* $Revision: 1.1 $
+* $Date: 2003/07/18 00:11:46 $
+*
+* Module Desription 
+* see Doxygen Doc for all possibilites
+*
+*
+*
+*/
+
+#if 0   /* auf uClinux statisch ?? */
+#ifndef NOMODULE
+#define __NO_VERSION__
+#define MODULE
+#endif
+#endif
+
+#ifdef __KERNEL__
+#ifndef KERNEL_VERSION
+#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#endif
+
+#ifdef __KERNEL__
+#include <linux/init.h>
+#include <linux/module.h>
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,12)
+# include <linux/slab.h>
+#else
+# include <linux/malloc.h>
+#endif
+
+#include <linux/wrapper.h>
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
+#include <linux/poll.h>
+#endif
+
+#include <asm/io.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+
+#include <linux/mm.h>
+#include <linux/signal.h>
+#include <linux/timer.h>
+
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
+#include <asm/uaccess.h>
+
+#define __lddk_copy_from_user(a,b,c) copy_from_user(a,b,c)
+#define __lddk_copy_to_user(a,b,c) copy_to_user(a,b,c)
+
+#else
+
+/* #define __lddk_copy_from_user(a,b,c) memcpy_fromio(a,b,c) */
+/* #define __lddk_copy_to_user(a,b,c) memcpy_toio(a,b,c) */
+#define __lddk_copy_from_user(a,b,c) memcpy_fromfs(a,b,c)
+#define __lddk_copy_to_user(a,b,c) memcpy_tofs(a,b,c)
+
+
+#include <linux/sched.h>
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
+#include <linux/ioport.h>
+#endif
+#include <linux/ioport.h>
+
+#endif
+
+#if CAN4LINUX_PCI
+# define _BUS_TYPE "PCI-"
+/* the only one supported: EMS CPC-PCI */
+# define PCI_VENDOR 0x110a
+# define PCI_DEVICE 0x2104
+
+#else
+# define _BUS_TYPE "ISA-"
+#endif
+
+#if 1 
+#ifdef CAN_PELICANMODE
+
+# ifdef  CAN_PORT_IO
+#  define __CAN_TYPE__ _BUS_TYPE "PeliCAN-port I/O "
+# else
+#  define __CAN_TYPE__ _BUS_TYPE "PeliCAN-memory mapped "
+# endif
+
+#else
+
+# ifdef  CAN_PORT_IO
+#  define __CAN_TYPE__ _BUS_TYPE "Philips-Basic-CAN port I/O "
+# else
+#  define __CAN_TYPE__ _BUS_TYPE "Philips-Basic-CAN memory mapped "
+# endif
+
+#endif
+#endif
+
+/* Length of the "version" string entry in /proc/.../version */
+#define PROC_VER_LENGTH 30 
+/* Length of the "Chipset" string entry in /proc/.../version */
+#define PROC_CHIPSET_LENGTH 30 
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+/* kernels higher 2.3.x have a f****** new kernel interface ******************/
+#define __LDDK_WRITE_TYPE	ssize_t
+#define __LDDK_CLOSE_TYPE	int
+#define __LDDK_READ_TYPE	ssize_t
+#define __LDDK_OPEN_TYPE	int
+#define __LDDK_IOCTL_TYPE	int
+#define __LDDK_SELECT_TYPE	unsigned int
+
+#define __LDDK_SEEK_PARAM 	struct file *file, loff_t off, size_t count
+#define __LDDK_READ_PARAM 	struct file *file, char *buffer, size_t count, loff_t *loff
+#define __LDDK_WRITE_PARAM 	struct file *file, const char *buffer, size_t count, loff_t *loff
+#define __LDDK_READDIR_PARAM 	struct file *file, void *dirent, filldir_t count
+#define __LDDK_SELECT_PARAM 	struct file *file, struct poll_table_struct *wait
+#define __LDDK_IOCTL_PARAM 	struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg
+#define __LDDK_MMAP_PARAM 	struct file *file, struct vm_area_struct * vma
+#define __LDDK_OPEN_PARAM 	struct inode *inode, struct file *file 
+#define __LDDK_FLUSH_PARAM	struct file *file 
+#define __LDDK_CLOSE_PARAM 	struct inode *inode, struct file *file 
+#define __LDDK_FSYNC_PARAM 	struct file *file, struct dentry *dentry, int datasync
+#define __LDDK_FASYNC_PARAM 	struct file *file, int count 
+#define __LDDK_CCHECK_PARAM 	kdev_t dev
+#define __LDDK_REVAL_PARAM 	kdev_t dev
+
+#define __LDDK_MINOR MINOR(file->f_dentry->d_inode->i_rdev)
+#define __LDDK_INO_MINOR MINOR(inode->i_rdev)
+
+
+#ifndef SLOW_DOWN_IO
+# define SLOW_DOWN_IO __SLOW_DOWN_IO
+#endif
+
+
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+/* kernels higher 2.2.x have a f****** new kernel interface ******************/
+#define __LDDK_READ_TYPE	ssize_t
+#define __LDDK_WRITE_TYPE	ssize_t
+#define __LDDK_SELECT_TYPE	unsigned int
+#define __LDDK_IOCTL_TYPE	int
+#define __LDDK_OPEN_TYPE	int
+#define __LDDK_CLOSE_TYPE	int
+
+#define __LDDK_SEEK_PARAM 	struct file *file, loff_t off, int count
+#define __LDDK_READ_PARAM 	struct file *file, char *buffer, size_t count, loff_t *loff
+#define __LDDK_WRITE_PARAM 	struct file *file, const char *buffer, size_t count, loff_t *loff
+#define __LDDK_READDIR_PARAM 	struct file *file, struct dirent *dirent, int count
+#define __LDDK_SELECT_PARAM 	struct file *file, poll_table *wait
+#define __LDDK_IOCTL_PARAM 	struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg
+#define __LDDK_MMAP_PARAM 	struct file *file, struct vm_area_struct * vma
+#define __LDDK_OPEN_PARAM 	struct inode *inode, struct file *file 
+#define __LDDK_FLUSH_PARAM	struct file *file 
+#define __LDDK_CLOSE_PARAM 	struct inode *inode, struct file *file 
+#define __LDDK_FSYNC_PARAM 	struct file *file
+#define __LDDK_FASYNC_PARAM 	struct file *file, int count 
+#define __LDDK_CCHECK_PARAM 	kdev_t dev
+#define __LDDK_REVAL_PARAM 	kdev_t dev
+
+#define __LDDK_MINOR MINOR(file->f_dentry->d_inode->i_rdev)
+#define __LDDK_INO_MINOR MINOR(inode->i_rdev)
+
+#ifndef SLOW_DOWN_IO
+# define SLOW_DOWN_IO __SLOW_DOWN_IO
+#endif
+
+#else
+/* kernels < 2.3.x **********************************************************/
+ /* 2.0.x */
+#define __LDDK_WRITE_TYPE	int
+#define __LDDK_CLOSE_TYPE	void
+#define __LDDK_READ_TYPE
+#define __LDDK_OPEN_TYPE
+#define __LDDK_IOCTL_TYPE
+#define __LDDK_SELECT_TYPE	int
+
+#define __LDDK_SEEK_PARAM 	struct inode *inode, struct file *file, off_t off, int count
+#define __LDDK_READ_PARAM 	struct inode *inode, struct file *file, char *buffer, int count
+#define __LDDK_WRITE_PARAM 	struct inode *inode, struct file *file, const char *buffer, int count
+#define __LDDK_READDIR_PARAM 	struct inode *inode, struct file *file, struct dirent *dirent, int count
+#define __LDDK_SELECT_PARAM 	struct inode *inode, struct file *filp, int sel_type, select_table * wait
+#define __LDDK_IOCTL_PARAM 	struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg
+#define __LDDK_MMAP_PARAM 	struct inode *inode, struct file *file, struct vm_area_struct * vma
+#define __LDDK_OPEN_PARAM 	struct inode *inode, struct file *file 
+#define __LDDK_CLOSE_PARAM 	struct inode *inode, struct file *file 
+#define __LDDK_FSYNC_PARAM 	struct inode *inode, struct file *file
+#define __LDDK_FASYNC_PARAM 	struct inode *inode, struct file *file, int count 
+#define __LDDK_CCHECK_PARAM 	kdev_t dev
+#define __LDDK_REVAL_PARAM 	kdev_t dev
+
+#define __LDDK_MINOR MINOR(inode->i_rdev)
+#define __LDDK_INO_MINOR MINOR(inode->i_rdev)
+
+#endif
+
+
+
+/************************************************************************/
+#include "can_debug.h"
+/************************************************************************/
+/* #include <can_Proto.h> */
+#ifdef __KERNEL__
+extern int can_read (__LDDK_READ_PARAM); 
+extern __LDDK_WRITE_TYPE can_write (__LDDK_WRITE_PARAM); 
+extern __LDDK_SELECT_TYPE can_select ( __LDDK_SELECT_PARAM ); 
+extern int can_ioctl ( __LDDK_IOCTL_PARAM ); 
+extern int can_open ( __LDDK_OPEN_PARAM ); 
+extern __LDDK_CLOSE_TYPE can_close (__LDDK_CLOSE_PARAM); 
+#endif 
+
+
+/*---------- Default Outc value for some known boards
+ * this depends on the transceiver configuration
+ * 
+ * the port board uses optocoupler configuration as denoted in the philips
+ * application notes, so the OUTC value is 0xfa
+ *
+ */
+
+#if   defined(ATCANMINI_BASIC) || defined(ATCANMINI_PELICAN)
+# define CAN_OUTC_VAL           0xfa
+# define IO_MODEL		'p'
+# define STD_MASK		0xFFFFFFFF 
+# include "can_sja1000.h"
+#elif defined(IME_SLIMLINE)
+# define CAN_OUTC_VAL           0xda
+# define IO_MODEL		'm'
+# define STD_MASK		0xFFFFFFFF 
+# include "can_sja1000.h"
+#elif defined(CPC_PCI)
+# define CAN_OUTC_VAL           0xda
+# define IO_MODEL		'm'
+# define STD_MASK		0xFFFFFFFF 
+# include "can_sja1000.h"
+#elif defined(IXXAT_PCI03)
+# define CAN_OUTC_VAL           0x5e
+# define IO_MODEL		'm'
+# define STD_MASK		0xFFFFFFFF 
+# include "can_sja1000.h"
+#elif defined(PCM3680)
+# define CAN_OUTC_VAL           0x5e
+# define IO_MODEL		'm'
+# define STD_MASK		0xFFFFFFFF 
+# include "can_sja1000.h"
+#elif defined(CCPC104)
+# define CAN_OUTC_VAL           0xfa
+# define IO_MODEL		'm'
+# define STD_MASK		0xFFFFFFFF 
+# include "can_sja1000.h"
+#elif defined(MCF5282)
+# define CAN_OUTC_VAL           0x5e
+# define IO_MODEL		'm'
+# define STD_MASK		0
+# include "can_mcf5282.h"
+#else 
+# define CAN_OUTC_VAL           0x00
+# define IO_MODEL		'm'
+# define STD_MASK		0xFFFFFFFF 
+# include "can_sja1000.h"
+/* #error no CAN_OUTC_VAL */
+#endif
+
+/************************************************************************/
+#include "can4linux.h"
+/************************************************************************/
+ extern volatile int irq2minormap[];
+ extern volatile int irq2pidmap[];
+ extern u32 Can_pitapci_control[];
+
+
+/* number of supported CAN channels */
+#ifndef MAX_CHANNELS
+# define MAX_CHANNELS 4
+#endif
+
+/* #define MAX_BUFSIZE 64 */
+#define MAX_BUFSIZE 200
+/* #define MAX_BUFSIZE 4 */
+
+#define BUF_EMPTY    0
+#define BUF_OK       1
+#define BUF_FULL     BUF_OK
+#define BUF_OVERRUN  2
+#define BUF_UNDERRUN 3
+
+
+ typedef struct {
+	int head;
+        int tail;
+        int status;
+	int active;
+	char free[MAX_BUFSIZE];
+        canmsg_t data[MAX_BUFSIZE];
+ } msg_fifo_t;
+
+
+
+#ifdef CAN_USE_FILTER
+ #define MAX_ID_LENGTH 11
+ #define MAX_ID_NUMBER (1<<11)
+
+ typedef struct {
+	unsigned    use;
+	unsigned    signo[3];
+	struct {
+		unsigned    enable    : 1;
+		unsigned    timestamp : 1;
+		unsigned    signal    : 2;
+		canmsg_t    *rtr_response;
+	} filter[MAX_ID_NUMBER];
+ } msg_filter_t;
+
+
+
+ extern msg_filter_t Rx_Filter[];
+#endif
+
+ extern msg_fifo_t Tx_Buf[];
+ extern msg_fifo_t Rx_Buf[];
+
+ typedef void (*irqservice_t)(int irq, void *unused, struct pt_regs *ptregs);
+
+ extern int Can_RequestIrq(int minor, int irq, irqservice_t handler);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1)
+ extern wait_queue_head_t CanWait[];
+#else
+ extern struct wait_queue *CanWait[];
+#endif
+
+ extern unsigned char *can_base[];
+ extern unsigned int   can_range[];
+#endif
+
+extern int IRQ_requested[];
+extern int Can_minors[];			/* used as IRQ dev_id */
+
+
+/************************************************************************/
+#define LDDK_USE_SYSCTL 1
+#ifdef __KERNEL__
+#include <linux/sysctl.h>
+
+extern ctl_table Can_sysctl_table[];
+extern ctl_table Can_sys_table[];
+
+
+
+ /* ------ Global Definitions for version */
+
+extern char version[];
+#define SYSCTL_VERSION 1
+ 
+ /* ------ Global Definitions for Chpset */
+
+extern char Chipset[];
+#define SYSCTL_CHIPSET 2
+ 
+ /* ------ Global Definitions for IOModel */
+
+extern char IOModel[];
+#define SYSCTL_IOMODEL 3
+ 
+ /* ------ Global Definitions for IRQ */
+
+extern  int IRQ[];
+#define SYSCTL_IRQ 4
+ 
+ /* ------ Global Definitions for Base */
+
+extern  unsigned int Base[];
+#define SYSCTL_BASE 5
+ 
+ /* ------ Global Definitions for Baud */
+
+extern  int Baud[];
+#define SYSCTL_BAUD 6
+ 
+ /* ------ Global Definitions for AccCode */
+
+extern  unsigned int AccCode[];
+#define SYSCTL_ACCCODE 7
+ 
+ /* ------ Global Definitions for AccMask */
+
+extern  unsigned int AccMask[];
+#define SYSCTL_ACCMASK 8
+ 
+ /* ------ Global Definitions for Timeout */
+
+extern  int Timeout[];
+#define SYSCTL_TIMEOUT 9
+ 
+ /* ------ Global Definitions for Outc */
+
+extern  int Outc[];
+#define SYSCTL_OUTC 10
+ 
+ /* ------ Global Definitions for TxErr */
+
+extern  int TxErr[];
+#define SYSCTL_TXERR 11
+ 
+ /* ------ Global Definitions for RxErr */
+
+extern  int RxErr[];
+#define SYSCTL_RXERR 12
+ 
+ /* ------ Global Definitions for Overrun */
+
+extern  int Overrun[];
+#define SYSCTL_OVERRUN 13
+ 
+ /* ------ Global Definitions for dbgMask */
+
+extern unsigned int dbgMask;
+#define SYSCTL_DBGMASK 14
+
+ /* ------ Global Definitions for Test  */
+extern  int Cnt1[];
+#define SYSCTL_CNT1 15
+extern  int Cnt2[];
+#define SYSCTL_CNT2 16
+ 
+ 
+#endif
+/************************************************************************/
+
+
+
+#ifndef Can_MAJOR
+#define Can_MAJOR 91
+#endif
+
+extern int Can_errno;
+
+#ifdef USE_LDDK_RETURN
+#define LDDK_RETURN(arg) DBGout();return(arg)
+#else
+#define LDDK_RETURN(arg) return(arg)
+#endif
+
+
+/************************************************************************/
+/* function prototypes */
+/************************************************************************/
+extern int CAN_ChipReset(int);
+extern int CAN_SetTiming(int, int);
+extern int CAN_StartChip(int);
+extern int CAN_StopChip(int);
+extern int CAN_SetMask(int, unsigned int, unsigned int);
+extern int CAN_SetOMode(int,int);
+extern int CAN_SendMessage(int, canmsg_t *);
+extern int CAN_GetMessage(int , canmsg_t *);
+extern void CAN_Interrupt(int irq, void *unused, struct pt_regs *ptregs );
+extern int CAN_VendorInit(int);
+
+extern void register_systables(void);
+extern void unregister_systables(void);
+
+/* can_82c200funcs.c */
+extern int CAN_ShowStat (int board);
+
+/* can_mcf5282funcs.c */
+void mcf_irqreset(void);
+void mcf_irqsetup(void);
+
+/* util.c */
+extern int Can_FifoInit(int minor);
+extern int Can_FilterCleanup(int minor);
+extern int Can_FilterInit(int minor);
+extern int Can_FilterMessage(int minor, unsigned message, unsigned enable);
+extern int Can_FilterOnOff(int minor, unsigned on);
+extern int Can_FilterSigNo(int minor, unsigned signo, unsigned signal);
+extern int Can_FilterSignal(int minor, unsigned id, unsigned signal);
+extern int Can_FilterTimestamp(int minor, unsigned message, unsigned stamp);
+extern int Can_FreeIrq(int minor, int irq );
+extern int Can_WaitInit(int minor);
+extern void Can_StartTimer(unsigned long v);
+extern void Can_StopTimer(void);
+extern void Can_TimerInterrupt(unsigned long unused);
+extern void Can_dump(int minor);
+extern void Can_dump(int minor);
+extern void CAN_register_dump(void);
+extern void CAN_object_dump(int object);
+extern void print_tty(const char *fmt, ...);
+
+/* PCI support */
+extern int pcimod_scan(void);
+
+/************************************************************************/
+/* hardware access functions or macros */
+/************************************************************************/
+#ifdef  CAN_PORT_IO
+/* #error Intel port I/O access */
+/* using port I/O with inb()/outb() for Intel architectures like 
+   AT-CAN-MINI ISA board */
+
+#ifdef IODEBUG
+#  define CANout(bd,adr,v)	\
+	(printk("Cout: (%x)=%x\n", (int)&((canregs_t *)Base[bd])->adr, v), \
+		outb(v, (int) &((canregs_t *)Base[bd])->adr ))
+#else
+#  define CANout(bd,adr,v)	\
+		(outb(v, (int) &((canregs_t *)Base[bd])->adr ))
+#endif
+#define CANin(bd,adr)		\
+		(inb ((int) &((canregs_t *)Base[bd])->adr  ))
+#define CANset(bd,adr,m)	\
+	outb((inb((int) &((canregs_t *)Base[bd])->adr)) \
+		| m ,(int) &((canregs_t *)Base[bd])->adr )
+#define CANreset(bd,adr,m)	\
+	outb((inb((int) &((canregs_t *)Base[bd])->adr)) \
+		& ~m,(int) &((canregs_t *)Base[bd])->adr )
+#define CANtest(bd,adr,m)	\
+	(inb((int) &((canregs_t *)Base[bd])->adr  ) & m )
+
+#else 	/* CAN_PORT_IO */
+/* using memory acces with readb(), writeb() */
+/* #error  memory I/O access */
+/* #define can_base Base */
+#ifdef IODEBUG
+#  define CANout(bd,adr,v)	\
+	(printk("Cout: (%x)=%x\n", (u32)&((canregs_t *)can_base[bd])->adr, v), \
+		writeb(v, (u32) &((canregs_t *)can_base[bd])->adr ))
+
+#define CANset(bd,adr,m)     do	{\
+	unsigned char v;	\
+        v = (readb((u32) &((canregs_t *)can_base[bd])->adr)); \
+	printk("CANset %x |= %x\n", (v), (m)); \
+	writeb( v | (m) , (u32) &((canregs_t *)can_base[bd])->adr ); \
+	} while (0)
+
+#define CANreset(bd,adr,m)	do {\
+	unsigned char v; \
+        v = (readb((u32) &((canregs_t *)can_base[bd])->adr)); \
+	printk("CANreset %x &= ~%x\n", (v), (m)); \
+	writeb( v & ~(m) , (u32) &((canregs_t *)can_base[bd])->adr ); \
+	} while (0)
+
+#else
+   /* Memory Byte access */
+#define CANout(bd,adr,v)	\
+		(writeb(v, (u32) &((canregs_t *)can_base[bd])->adr ))
+#define CANset(bd,adr,m)	\
+	writeb((readb((u32) &((canregs_t *)can_base[bd])->adr)) \
+		| (m) , (u32) &((canregs_t *)can_base[bd])->adr )
+#define CANreset(bd,adr,m)	\
+	writeb((readb((u32) &((canregs_t *)can_base[bd])->adr)) \
+		& ~(m), (u32) &((canregs_t *)can_base[bd])->adr )
+#endif
+#define CANin(bd,adr)		\
+		(readb ((u32) &((canregs_t *)can_base[bd])->adr  ))
+#define CANtest(bd,adr,m)	\
+	(readb((u32) &((canregs_t *)can_base[bd])->adr  ) & (m) )
+
+
+   /* Memory word access */
+#define CANoutw(bd,adr,v)	\
+		(writew(v, (u32) &((canregs_t *)can_base[bd])->adr ))
+#define CANsetw(bd,adr,m)	\
+	writew((readw((u32) &((canregs_t *)can_base[bd])->adr)) \
+		| (m) , (u32) &((canregs_t *)can_base[bd])->adr )
+#define CANresetw(bd,adr,m)	\
+	writew((readw((u32) &((canregs_t *)can_base[bd])->adr)) \
+		& ~(m), (u32) &((canregs_t *)can_base[bd])->adr )
+#define CANinw(bd,adr)		\
+		(readw ((u32) &((canregs_t *)can_base[bd])->adr  ))
+#define CANtestw(bd,adr,m)	\
+	(readw((u32) &((canregs_t *)can_base[bd])->adr  ) & (m) )
+
+
+   /* Memory long word access */
+#define CANoutl(bd,adr,v)	\
+		(writel(v, (u32) &((canregs_t *)can_base[bd])->adr ))
+#define CANsetl(bd,adr,m)	\
+	writel((readl((u32) &((canregs_t *)can_base[bd])->adr)) \
+		| (m) , (u32) &((canregs_t *)can_base[bd])->adr )
+#define CANresetl(bd,adr,m)	\
+	writel((readl((u32) &((canregs_t *)can_base[bd])->adr)) \
+		& ~(m), (u32) &((canregs_t *)can_base[bd])->adr )
+#define CANinl(bd,adr)		\
+		(readl ((u32) &((canregs_t *)can_base[bd])->adr  ))
+#define CANtestl(bd,adr,m)	\
+	(readl((u32) &((canregs_t *)can_base[bd])->adr  ) & (m) )
+
+
+#endif 		/* CAN_PORT_IO */
+
+/*________________________E_O_F_____________________________________________*/
+
+
+#if 0
+/*
+There is a special access mode for the 82527 CAN controller
+called fast register access.
+This mode is sometimes used instead of normal Mem-Read/Write
+and substitutes  MEM_In/MEM_Out
+
+*/
+
+u8 MEM_In (unsigned long  adr ) { 
+#if IODEBUG
+        int ret = readb(adr);
+        printk("MIn: 0x%x=0x%x\n", adr, ret);
+        return ret;
+#else
+	SLOW_DOWN_IO;	SLOW_DOWN_IO;
+	return readb(adr);
+#endif
+}
+
+u8 fastMEM_In (unsigned long  adr ) {
+        /* Fast access:
+         * first read desired register,
+         * after that read register 4
+         */
+	int ret = readb(adr);
+        if((adr & 0x000000FF) == 0x02) {
+        	return ret;
+	}
+	/* 250 ns delay, SLOW_DOWN_IO is empty on ELIMA */
+	asm volatile("nop;nop;nop;nop");
+	asm volatile("nop;nop;nop;nop");
+	asm volatile("nop;nop;nop;nop");
+	asm volatile("nop;nop;nop;nop");
+	ret = readb((adr & 0xFFFFFF00) + 4);
+#if IODEBUG
+        printk("MfIn: 0x%x=0x%x\n", adr, ret);
+#endif
+        return ret;
+}
+
+void MEM_Out(u8 v, unsigned long adr ) {
+#if IODEBUG
+        printk("MOut: 0x%x->0x%x\n", v, adr);
+#endif
+	SLOW_DOWN_IO;
+        writeb(v, adr);
+	SLOW_DOWN_IO; 
+#if defined(CONFIG_PPC)
+	/* 250 ns delay, SLOW_DOWN_IO is empty on ELIMA */
+	asm volatile("nop;nop;nop;nop");
+	asm volatile("nop;nop;nop;nop");
+	asm volatile("nop;nop;nop;nop");
+	asm volatile("nop;nop;nop;nop");
+#endif
+}
+
+#endif
+
+
+
+
+
+
+
diff -urN linux-2.4.29/drivers/char/can4linux/can_error.c linux-2.4.29-uc1/drivers/char/can4linux/can_error.c
--- linux-2.4.29/drivers/char/can4linux/can_error.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_error.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,34 @@
+/* Can_error
+ *
+ * can4linux -- LINUX CAN device driver source
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * 
+ * Copyright (c) 2001 port GmbH Halle/Saale
+ * (c) 2001 Heinz-Jürgen Oertel (oe@port.de)
+ *          Claus Schroeter (clausi@chemie.fu-berlin.de)
+ *------------------------------------------------------------------
+ * $Header: $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: Can_error.c,v $
+ *
+ *
+ */
+#include "can_defs.h"
+
+int Can_errno = 0;
+
+
+int Error(int err)
+{
+    Can_errno = err;
+    return 0;
+}
diff -urN linux-2.4.29/drivers/char/can4linux/can_ioctl.c linux-2.4.29-uc1/drivers/char/can4linux/can_ioctl.c
--- linux-2.4.29/drivers/char/can4linux/can_ioctl.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_ioctl.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,411 @@
+/*
+ * can_ioctl - can4linux CAN driver module
+ *
+ * can4linux -- LINUX CAN device driver source
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ * 
+ * Copyright (c) 2001 port GmbH Halle/Saale
+ * (c) 2001 Heinz-Jürgen Oertel (oe@port.de)
+ *          Claus Schroeter (clausi@chemie.fu-berlin.de)
+ *------------------------------------------------------------------
+ * $Header: /var/cvs/uClinux-2.4.x/drivers/char/can4linux/can_ioctl.c,v 1.1 2003/07/18 00:11:46 gerg Exp $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: can_ioctl.c,v $
+ * Revision 1.1  2003/07/18 00:11:46  gerg
+ * I followed as much rules as possible (I hope) and generated a patch for the
+ * uClinux distribution. It contains an additional driver, the CAN driver, first
+ * for an SJA1000 CAN controller:
+ *   uClinux-dist/linux-2.4.x/drivers/char/can4linux
+ * In the "user" section two entries
+ *   uClinux-dist/user/can4linux     some very simple test examples
+ *   uClinux-dist/user/horch         more sophisticated CAN analyzer example
+ *
+ * Patch submitted by Heinz-Juergen Oertel <oe@port.de>.
+ *
+ *
+ *
+ *--------------------------------------------------------------------------
+ */
+
+
+/**
+* \file can_ioctl.c
+* \author Heinz-Jürgen Oertel, port GmbH
+* $Revision: 1.1 $
+* $Date: 2003/07/18 00:11:46 $
+*
+*
+*/
+
+#include "can_defs.h"
+
+int can_Command(struct inode *inode, int cmd);
+int can_Send(struct inode *inode, canmsg_t *Tx);
+int can_Receive(struct inode *inode, canmsg_t *Rx);
+int can_GetStat(struct inode *inode, CanStatusPar_t *s);
+int can_Config(struct inode *inode, int target, unsigned long val1,
+					       unsigned long val2);
+
+/***************************************************************************/
+/**
+*
+\brief int ioctl(int fd, int request, ...);
+the CAN controllers control interface
+\param fd The descriptor to change properties
+\param request special configuration request
+\param ...  traditional a \a char *argp
+
+The \a ioctl function manipulates the underlying device
+parameters of the CAN special device.
+In particular, many operating characteristics of
+character CAN driver may be controlled with \a ioctl requests.
+The argument \a fd must be an open file descriptor.
+
+An ioctl request has encoded in it whether the argument is
+an \b in parameter or \b out parameter,
+and the size of the argument argp in bytes.
+Macros and defines used in specifying an \a ioctl request
+are located  in  the  file can4linux.h .
+
+The following \a requests are defined:
+
+\li \c COMMAND some commands for
+start, stop and reset the CAN controller chip
+\li \c CONFIG configure some of the device properties
+like acceptance filtering, bit timings, mode of the output control register
+or the optional software message filter configuration(not implemented yet).
+\li \c STATUS request the CAN controllers status
+\li \c SEND a single message over the \a ioctl interface 
+\li \c RECEIVE poll a receive message
+\li \c CONFIGURERTR configure automatic rtr responses(not implemented)
+
+The third argument is a parameter structure depending on the request.
+These are
+\code
+struct Command_par
+struct Config_par
+struct CanSja1000Status_par
+struct ConfigureRTR_par
+struct Receive_par
+struct Send_par
+\endcode
+described in can4linux.h
+
+\par Acceptance Filtering
+
+\b Basic \b CAN.
+In the case of using standard identifiers in Basic CAN mode
+for receiving CAN messages
+only the low bytes are used to set acceptance code and mask
+for bits ID.10 ... ID.3
+
+\par
+\b PeliCAN.
+For acceptance filtering the entries \c AccCode and \c AccMask are used
+like specified in the controllers manual for
+\b Single \b Filter \b Configuration .
+Both are 4 byte entries.
+In the case of using standard identifiers for receiving CAN messages
+also all 4 bytes can be used.
+In this case two bytes are used for acceptance code and mask
+for all 11 identifier bits plus additional the first two data bytes.
+The SJA1000 is working in the \b Single \b Filter \ Mode .
+\code
+       Bits
+ mask  31 30 .....           4  3  2  1  0
+ code
+ -------------------------------------------
+ ID    28 27 .....           1  0  R  +--+-> unused
+                                   T
+                                   R
+\endcode
+
+\returns
+On success, zero is returned.
+On error, -1 is returned, and errno is set appropriately.
+
+\par Example
+\code
+Config_par_t  cfg;
+volatile Command_par_t cmd;
+
+
+    cmd.cmd = CMD_STOP;
+    ioctl(can_fd, COMMAND, &cmd);
+
+    cfg.target = CONF_ACCM; 
+    cfg.val    = acc_mask;
+    ioctl(can_fd, CONFIG, &cfg);
+    cfg.target = CONF_ACCC; 
+    cfg.val    = acc_code;
+    ioctl(can_fd, CONFIG, &cfg);
+
+    cmd.cmd = CMD_START;
+    ioctl(can_fd, COMMAND, &cmd);
+
+\endcode
+
+*/
+int can_ioctl( __LDDK_IOCTL_PARAM )
+{
+void *argp;
+int retval = -EIO;
+  
+  DBGin("can_ioctl");
+  DBGprint(DBG_DATA,("cmd=%d", cmd));
+  Can_errno = 0;
+  
+  switch(cmd){
+
+        case COMMAND:
+	  if( verify_area(VERIFY_READ, (void *)arg, sizeof(Command_par_t))) {
+	     DBGout(); return(retval); 
+	  }
+	  if( verify_area(VERIFY_WRITE, (void *)arg, sizeof(Command_par_t))) {
+	     DBGout(); return(retval); 
+	  }
+	  argp = (void *) kmalloc( sizeof(Command_par_t) +1 , GFP_KERNEL );
+	  __lddk_copy_from_user( (void *) argp,(Command_par_t *) arg,
+	  					sizeof(Command_par_t));
+	  ((Command_par_t *) argp)->retval =
+	  		can_Command(inode, ((Command_par_t *) argp)->cmd );
+	  ((Command_par_t *) argp)->error = Can_errno;
+	  __lddk_copy_to_user( (Command_par_t *)arg, (void *)argp,
+	  					sizeof(Command_par_t));
+	  kfree(argp);
+	  break;
+      case CONFIG:
+	  if( verify_area(VERIFY_READ, (void *) arg, sizeof(Config_par_t))) {
+	     DBGout(); return(retval); 
+	  }
+	  if( verify_area(VERIFY_WRITE, (void *) arg, sizeof(Config_par_t))) {
+	     DBGout(); return(retval); 
+	  }
+	  argp = (void *) kmalloc( sizeof(Config_par_t) +1 ,GFP_KERNEL);
+	  __lddk_copy_from_user( (void *) argp,(Config_par_t *) arg,
+	  					sizeof(Config_par_t));
+	  ((Config_par_t *) argp)->retval =
+	  		can_Config(inode, ((Config_par_t *) argp)->target, 
+			     ((Config_par_t *) argp)->val1,
+			     ((Config_par_t *) argp)->val2 );
+	  ((Config_par_t *) argp)->error = Can_errno;
+	  __lddk_copy_to_user( (Config_par_t *) arg, (void *) argp,
+	  					sizeof(Config_par_t));
+	  kfree(argp);
+	  break;
+      case SEND:
+	  if( verify_area(VERIFY_READ, (void *) arg, sizeof(Send_par_t))) {
+	     DBGout(); return(retval); 
+	  }
+	  if( verify_area(VERIFY_WRITE, (void *) arg, sizeof(Send_par_t))) {
+	     DBGout(); return(retval); 
+	  }
+	  argp = (void *)kmalloc( sizeof(Send_par_t) +1 ,GFP_KERNEL );
+	  __lddk_copy_from_user( (void *) argp, (Send_par_t *)arg,
+	  				sizeof(Send_par_t));
+	  ((Send_par_t *) argp)->retval =
+	  		can_Send(inode, ((Send_par_t *) argp)->Tx );
+	  ((Send_par_t *) argp)->error = Can_errno;
+	  __lddk_copy_to_user( (Send_par_t *) arg, (void *)argp,
+	  				sizeof(Send_par_t));
+	  kfree(argp);
+	  break;
+      case RECEIVE:
+	  if( verify_area(VERIFY_READ, (void *) arg, sizeof(Receive_par_t))) {
+	     DBGout(); return(retval); 
+	  }
+	  if( verify_area(VERIFY_WRITE, (void *) arg, sizeof(Receive_par_t))) {
+	     DBGout(); return(retval); 
+	  }
+	  argp = (void *)kmalloc( sizeof(Receive_par_t) +1 ,GFP_KERNEL );
+	  __lddk_copy_from_user( (void *)argp, (Receive_par_t *)arg,
+	  				sizeof(Receive_par_t));
+	  ((Receive_par_t *) argp)->retval =
+	  		can_Receive(inode, ((Receive_par_t *) argp)->Rx);
+	  ((Receive_par_t *) argp)->error = Can_errno;
+	  __lddk_copy_to_user( (Receive_par_t *)arg, (void *) argp,
+	  				sizeof(Receive_par_t));
+	  kfree(argp);
+	  break;
+      case STATUS:
+	  if( verify_area(VERIFY_READ, (void *) arg,
+	  				sizeof(CanStatusPar_t))) {
+	     DBGout(); return(retval); 
+	  }
+	  if( verify_area(VERIFY_WRITE, (void *) arg,
+	  			sizeof(CanStatusPar_t))) {
+	     DBGout(); return(retval); 
+	  }
+	  argp = (void *)kmalloc( sizeof(CanStatusPar_t) +1 ,GFP_KERNEL );
+	  ((CanStatusPar_t *) argp)->retval =
+	  		can_GetStat(inode, ((CanStatusPar_t *)argp));
+	  __lddk_copy_to_user( (CanStatusPar_t *)arg, (void *) argp,
+	  				sizeof(CanStatusPar_t));
+	  kfree(argp);
+	  break;
+
+#ifdef CAN_RTR_CONFIG
+      case CONFIGURERTR:
+	  if( verify_area(VERIFY_READ, (void *) arg,
+	  			sizeof(ConfigureRTR_par_t))){
+	     DBGout(); return(retval); 
+	  }
+	  if( verify_area(VERIFY_WRITE, (void *) arg,
+	  			sizeof(ConfigureRTR_par_t))){
+	     DBGout(); return(retval); 
+	  }
+	  argp = (void *)kmalloc( sizeof(ConfigureRTR_par_t) +1 ,GFP_KERNEL );
+	  __lddk_copy_from_user( (void *) argp,(ConfigureRTR_par_t *) arg,
+	  			sizeof(ConfigureRTR_par_t));
+	  ((ConfigureRTR_par_t *) argp)->retval =
+	  	can_ConfigureRTR(inode,
+	  			((ConfigureRTR_par_t *) argp)->message, 
+				((ConfigureRTR_par_t *) argp)->Tx );
+	  ((ConfigureRTR_par_t *) argp)->error = Can_errno;
+	  __lddk_copy_to_user( (ConfigureRTR_par_t *) arg, (void *) argp,
+	  			sizeof(ConfigureRTR_par_t));
+	  kfree(argp);
+	  break;
+
+#endif  	/* CAN_RTR_CONFIG */
+  
+      default:
+        DBGout();
+	return -EINVAL;
+    }
+    DBGout();
+    return 1;
+}
+
+
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+
+/* 
+* ioctl functions are following here 
+*/
+
+
+int can_Command(struct inode *inode, int cmd)
+{
+unsigned int minor = MINOR(inode->i_rdev);
+
+    DBGprint(DBG_DATA,("cmd=%d", cmd));
+    switch (cmd) {
+      case CMD_START:
+	    CAN_StartChip(minor);
+	    break;
+      case CMD_STOP:
+	    CAN_StopChip(minor);
+	    break;
+      case CMD_RESET:
+	    CAN_ChipReset(minor);
+	    break;
+      default:
+	    DBGout();
+	    return(-EINVAL);
+    }
+    return 0;
+}
+
+/* is not very useful! use it if you are sure the tx queu is empty */
+int can_Send(struct inode *inode, canmsg_t *Tx)
+{
+unsigned int minor = MINOR(inode->i_rdev);	
+canmsg_t tx;
+
+    if( verify_area(VERIFY_READ,Tx,sizeof(canmsg_t)) ) {
+	    return -EINVAL;
+    }
+    __lddk_copy_from_user((canmsg_t *) &tx, (canmsg_t *) Tx,sizeof(canmsg_t));
+    return CAN_SendMessage(minor, &tx);
+}
+
+
+int can_Receive(
+	struct inode *inode,
+	canmsg_t *Rx
+	)
+{
+
+unsigned int minor = MINOR(inode->i_rdev);
+canmsg_t rx;
+int len;
+
+    len = CAN_GetMessage(minor,&rx);
+
+    if( len > 0 ){
+       /* printk("\nrx[ ] got id 0x%x len %d adr00x%lx\n",rx.id,rx.length,Rx); */
+       if( verify_area(VERIFY_WRITE,Rx,sizeof(canmsg_t) ) ) {
+	    return -EINVAL;
+       }
+       __lddk_copy_to_user((canmsg_t *) Rx, (canmsg_t *) &rx,
+       						sizeof(canmsg_t));
+       return rx.length;
+    } else {
+     /* no message availiable */
+     return 0;
+    }
+}
+
+
+int can_Config(
+	struct inode *inode,
+	int target,
+	unsigned long val1,
+	unsigned long val2
+	)
+{
+unsigned int minor = MINOR(inode->i_rdev);	
+
+    switch(target) {
+      case CONF_ACC:
+    DBGprint(DBG_DATA,("mask = 0x%lx, code = 0x%lx", val1, val2));
+	   AccMask[minor] = val1;
+	   AccCode[minor] = val2;
+	   CAN_SetMask(minor, AccCode[minor], AccMask[minor]);		
+	   break;
+      case CONF_ACCM:
+    DBGprint(DBG_DATA,("acc_mask=0x%lx", val1));
+	   AccMask[minor] = val1;
+	   CAN_SetMask(minor, AccCode[minor], AccMask[minor]);		
+	   break;
+      case CONF_ACCC:
+    DBGprint(DBG_DATA,("acc_code=0x%lx", val1));
+	   AccCode[minor] = val1;
+	   CAN_SetMask(minor, AccCode[minor], AccMask[minor]);		
+	   break;
+      case CONF_TIMING:
+	   Baud[minor] = val1;
+	   CAN_SetTiming(minor,(int) val1);   
+	   break;                    
+      case CONF_OMODE:
+	   CAN_SetOMode( minor, (int) val1);
+	   break;			
+#if CAN_USE_FILTER
+      case CONF_FILTER:
+	   Can_FilterOnOff( minor, (int) val1 );
+	   break;
+      case CONF_FENABLE:
+	   Can_FilterMessage( minor, (int) val1, 1);
+	   break;
+      case CONF_FDISABLE:
+	   Can_FilterMessage( minor, (int) val1, 0);
+	   break;
+#endif
+      default:
+	    DBGout();
+	    return(-EINVAL);
+    }
+    return 0;
+}
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
diff -urN linux-2.4.29/drivers/char/can4linux/can_mcf5282funcs.c linux-2.4.29-uc1/drivers/char/can4linux/can_mcf5282funcs.c
--- linux-2.4.29/drivers/char/can4linux/can_mcf5282funcs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_mcf5282funcs.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,927 @@
+/* can_mcf5282funcs.c  - Motorola FlexCAN functions
+ *
+ * can4linux -- LINUX CAN device driver source
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * 
+ * Copyright (c) 2003 port GmbH Halle/Saale
+ * (c) 2003 Heinz-Jürgen Oertel (oe@port.de)
+ *------------------------------------------------------------------
+ * $Header: $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ *
+ *  TRAMSMIT_OBJ  - used to transmit messages, possible are:
+ *  	standard, extended, standard RTR, extended RTR
+ *  RECEIVE_RTR_OBJ
+ *  RECEIVE_STD_OBJ
+ *  RECEIVE_EXT_OBJ
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: $
+ *
+ *
+ */
+#include "can_defs.h"
+#include <asm/delay.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+# error use the Coldfire FLexCAN only with Kernel > 2.4 
+#endif
+
+/* int	CAN_Open = 0; */
+
+/* timing values */
+static const BTR_TAB_TOUCAN_T can_btr_tab_toucan[] = {
+ { 10, CAN_PRESDIV_10K, CAN_PROPSEG_10K, CAN_PSEG1_10K, CAN_PSEG2_10K },
+ { 20, CAN_PRESDIV_20K, CAN_PROPSEG_20K, CAN_PSEG1_20K, CAN_PSEG2_20K },
+ { 50, CAN_PRESDIV_50K, CAN_PROPSEG_50K, CAN_PSEG1_50K, CAN_PSEG2_50K },
+ { 100, CAN_PRESDIV_100K, CAN_PROPSEG_100K, CAN_PSEG1_100K, CAN_PSEG2_100K },
+ { 125, CAN_PRESDIV_125K, CAN_PROPSEG_125K, CAN_PSEG1_125K, CAN_PSEG2_125K },
+ { 250, CAN_PRESDIV_250K, CAN_PROPSEG_250K, CAN_PSEG1_250K, CAN_PSEG2_250K },
+ { 500, CAN_PRESDIV_500K, CAN_PROPSEG_500K, CAN_PSEG1_500K, CAN_PSEG2_500K },
+ { 800, CAN_PRESDIV_800K, CAN_PROPSEG_800K, CAN_PSEG1_800K, CAN_PSEG2_800K },
+ { 1000, CAN_PRESDIV_1000K, CAN_PROPSEG_1000K, CAN_PSEG1_1000K, CAN_PSEG2_1000K },
+ {0, 0, 0, 0, 0}  /* last entry */
+};
+
+
+
+
+/* Board reset
+   means the following procedure:
+  set Reset Request
+  wait for Rest request is changing - used to see if board is available
+  initialize board (with valuse from /proc/sys/Can)
+    set output control register
+    set timings
+    set acceptance mask
+*/
+
+
+#ifdef DEBUG
+int CAN_ShowStat (int board)
+{
+    if (dbgMask && (dbgMask & DBG_DATA)) {
+    printk(" MCR 0x%x,", CANinw(board, canmcr));
+    printk(" ESTAT 0x%x,", CANinw(board, estat));
+    printk(" IFLAGS 0x%x,", CANinw(board, iflag));
+    printk(" IMASK 0x%x,", CANinw(board, imask));
+    printk("\n");
+    }
+    return 0;
+}
+#endif
+
+
+/* can_GetStat - read back as many status information as possible 
+*
+* Because the CAN protocol itself describes different kind of information
+* already, and the driver has some generic information
+* (e.g about it's buffers)
+* we can define a more or less hardware independent format.
+*
+*
+* exception:
+* ERROR WARNING LIMIT REGISTER (EWLR)
+* The SJA1000 defines a EWLR, reaching this Error Warning Level
+* an Error Warning interrupt can be generated.
+* The default value (after hardware reset) is 96. In reset
+* mode this register appears to the CPU as a read/write
+* memory. In operating mode it is read only.
+* Note, that a content change of the EWLR is only possible,
+* if the reset mode was entered previously. An error status
+* change (see status register; Table 14) and an error
+* warning interrupt forced by the new register content will not
+* occur until the reset mode is cancelled again.
+*/
+
+int can_GetStat(
+	struct inode *inode,
+	CanStatusPar_t *stat
+	)
+{
+unsigned int board = MINOR(inode->i_rdev);	
+msg_fifo_t *Fifo;
+unsigned long flags;
+
+
+    stat->type = CAN_TYPE_FlexCAN;
+
+    stat->baud = Baud[board];
+    /* printk(" STAT ST 0x%x\n", CANin(board, canstat)); */
+    stat->status = CANinw(board, estat);
+    /* not available in the FlexCAN, lets fill 127 here */
+    stat->error_warning_limit = 127;
+    stat->rx_errors = CANin(board, rxectr);
+    stat->tx_errors = CANin(board, txectr);
+    /* error code is not available, use estat again */
+    stat->error_code= CANinw(board, estat);
+
+    /* Disable CAN Interrupts */
+    /* !!!!!!!!!!!!!!!!!!!!! */
+    save_flags(flags); cli();
+    Fifo = &Rx_Buf[board];
+    stat->rx_buffer_size = MAX_BUFSIZE;	/**< size of rx buffer  */
+    /* number of messages */
+    stat->rx_buffer_used =
+    	(Fifo->head < Fifo->tail)
+    	? (MAX_BUFSIZE - Fifo->tail + Fifo->head) : (Fifo->head - Fifo->tail);
+    Fifo = &Tx_Buf[board];
+    stat->tx_buffer_size = MAX_BUFSIZE;	/* size of tx buffer  */
+    /* number of messages */
+    stat->tx_buffer_used = 
+    	(Fifo->head < Fifo->tail)
+    	? (MAX_BUFSIZE - Fifo->tail + Fifo->head) : (Fifo->head - Fifo->tail);
+    /* Enable CAN Interrupts */
+    /* !!!!!!!!!!!!!!!!!!!!! */
+    restore_flags(flags);
+    return 0;
+}
+
+
+
+/* 
+ * CAN_ChipReset - performs the first initialization or re-iniatalization of the chip
+ *
+ *
+ */
+int CAN_ChipReset (int board)
+{
+int i;
+
+    DBGin("CAN_ChipReset " __TIME__);
+	
+    /* 
+     * Initialize Port AS PAR to have Can TX/RX signals enabled 
+     */
+#define MCF5282_GPIO_PASPAR  	(*(volatile u16 *)(void *)(0x40100056))
+    MCF5282_GPIO_PASPAR = 0x0FF0;
+    /* printk("I/O %p %04x\n", (volatile u16 *)(void *)(0x40100056), MCF5282_GPIO_PASPAR); */
+	
+
+    /*
+     * go to INIT mode
+     * Any configuration change/initialization requires that the TouCAN be
+     * frozen by either asserting the HALT bit in the
+     * module configuration register or by reset.
+     * For Init_CAN() we choose reset.
+     */
+    CANresetw(board, canmcr, CAN_MCR_FRZ);
+    /* CANoutw(board, canmcr, 0x0080); */
+    CANsetw(board, canmcr, CAN_MCR_SOFT_RST);
+    udelay(10);
+    /* Test Reset Status */
+    if(CANtestw(board, canmcr, CAN_MCR_SOFT_RST) != 0) {
+	MOD_DEC_USE_COUNT;
+	DBGout();return -1;
+    }
+
+    udelay(10);
+    /* Initialize the transmit and receive pin modes in control register 0 */
+    CANout(board, canctrl0, 
+    	  CAN_CTRL0_DISABLE_BOFF_INT	/* disable Bus-Off Interrupt	*/
+    	+ CAN_CTRL0_DISABLE_ERR_INT	/* disable Error Interrupt	*/
+    	+ 0				/*  4 , logic RX level		*/
+    	+ 0				/*  1 , logic TX level		*/
+    	);
+    /* CANresetw(board, canmcr, CAN_MCR_HALT); */
+
+
+    CAN_SetTiming(board, Baud[board]);
+
+    /*
+     * Select the internal arbitration mode
+     * LBUF in CANCTRL1
+     * LBUF Lowest Buffer Transmitted First
+     * The LBUF bit defines the transmit-first scheme.
+     * 0 = Message buffer with lowest ID is transmitted first.
+     * 1 = Lowest numbered buffer ist transmitted first.
+     *
+     * should have no impact heree, the driver is using only one 
+     * TX object
+     *
+     * !! change the order of the next two statements  !!
+     */
+     
+    CANset(board, canctrl1, CAN_CTRL1_LBUF);
+    CANreset(board, canctrl1, CAN_CTRL1_LBUF);
+
+    /*
+     * Initialize message buffers.
+     * The control/status word of all message buffers are written
+     * as an inactive receive message buffer.
+     */
+    for(i = 0; i < 16; i++) {
+	CAN_WRITE_CTRL(i, REC_CODE_NOT_ACTIVE, 0);
+    }
+
+    /* create a transmit object, that can be used for all kinds of messages */
+
+    /* some receive objects
+     * - RECEIVE_OJ to receive all standard frames
+     * - ??
+     */
+    CAN_WRITE_CTRL(RECEIVE_OBJ, REC_CODE_NOT_ACTIVE, 0);
+    CAN_WRITE_OID(RECEIVE_OBJ, 0);	/* set IDE - extended bit to zero */
+    CAN_SetMask  (board, AccCode[board], AccMask[board] );
+    CAN_WRITE_CTRL(RECEIVE_OBJ, REC_CODE_EMPTY, 8);
+
+    /*
+     * - Initialize IARB[3:0] to a non zero value in CANMCR
+     *   ( This is done in CAN-ChipReset() )
+     * - Set the required mask bits in the IMASK register (for all message
+     *  buffer interrupts) in CANCTRL0 for bus off and error interrupts,
+     *  and in CANMCR for WAKE interrupt.
+     */
+
+    /* dont't forget error int's ! */
+    CANsetw(board, canmcr, 1);
+    CANoutw(board, imask, (1 << RECEIVE_OBJ)+(1 << TRANSMIT_OBJ));
+
+/* printk("imask at %p \n", &((canregs_t *)can_base[board])->imask ); */
+
+    /* CAN_register_dump(); */
+    DBGout();
+    return 0;
+}
+
+/* change the bit timings of the selected CAN channel */
+int CAN_SetTiming (int board, int baud)
+{
+/* int custom=0; */
+BTR_TAB_TOUCAN_T * table = (BTR_TAB_TOUCAN_T*)can_btr_tab_toucan;
+
+    DBGin("CAN_SetTiming");
+    DBGprint(DBG_DATA, ("baud[%d]=%d", board, baud));
+    /* enable changing of bit timings */
+    CANsetw(board, canmcr, CAN_MCR_HALT);
+    /* search for data from table */
+    while(1) {
+        if (table->rate == 0 || table->rate == baud) {
+    	    break;
+    	}	
+    	table++;
+    }
+    if (table->rate == 0) {
+	/* try to use baud  as custom specific bit rate 
+	 * not implemented yet
+	 */
+	return -ENXIO;
+    }
+
+    /*
+     * Set Timing Register values.
+     * Initialize the bit timing parameters PROPSEG, PSEG1, PSEG2 and RJW
+     * in control registers 1 and 2.
+     *
+     * The TouCAN module uses three 8-bit registers to set-up
+     * the bit timing parameters required by the CAN protocol.
+     * Control registers 1 and 2 contain the PROPSEG, PSEG1, PSEG2
+     * and RJW fields which allow the user to configure
+     * the bit timing parameters.
+     * The prescaler divide register (PRESDIV) allows the user to select
+     * the ratio used to derive the S-Clock from the system clock.
+     * The time quanta clock operates at the S-clock frequency. 
+     */
+    CANout(board, presdiv, table->presdiv);
+    CANout(board, canctrl2, ((table->pseg1 << 3)+ table->pseg2));
+    CANout(board, canctrl1, (
+    	  0		/* SAMP = 0 , 0/0x80		*/	
+    	+ 0		/* LOOP = 0 , 0/0x40		*/	
+    	+ 0		/* TSYNC= 0 , 0/0x20		*/
+    	+ 0		/* LBUF = 0 , 0/0x10		*/
+    	+ 0		/* RSVD = 0 , 0/0x08		*/
+    	+ table->propseg)
+    	);
+
+    /* 
+     * Stay in configuration mode; a call to Start-CAN() is necessary to
+     * activate the CAN controller with the new bit rate
+     */
+    DBGprint(DBG_DATA,("canctrl2=0x%x presdiv=0x%x",
+    		CANin(board, canctrl2), CANin(board, presdiv)) );
+
+    DBGout();
+    return 0;
+}
+
+
+int CAN_StartChip (int board)
+{
+/* int i; */
+    RxErr[board] = TxErr[board] = 0L;
+    DBGin("CAN_StartChip");
+
+
+    /* clear interrupts */
+    CANinw(board, iflag);
+    CANoutw(board, iflag, 0xffff); /* 5282 overwrites with '1' */
+
+    CANresetw(board, canmcr, CAN_MCR_HALT | CAN_MCR_FRZ);
+    /* Interrupts on Rx, TX, any Status change and data overrun */
+    /* Initialize the transmit and receive pin modes in control register 0 */
+    CANset(board, canctrl0, 
+    	  CAN_CTRL0_ENABLE_BOFF_INT	/* enable Bus-Off Interrupt	*/
+    	+ CAN_CTRL0_ENABLE_ERR_INT	/* enable Error Interrupt	*/
+    	);
+
+
+    /* to do */
+    /* CAN_register_dump(); */
+    
+    DBGout();
+    return 0;
+}
+
+
+/* Disable all CAN activities */
+int CAN_StopChip (int board)
+{
+    DBGin("CAN_StopChip");
+    CANset(board, canmcr, CAN_MCR_HALT);
+    CANset(board, canctrl0, 
+    	  CAN_CTRL0_DISABLE_BOFF_INT	/* disable Bus-Off Interrupt	*/
+    	+ CAN_CTRL0_DISABLE_ERR_INT	/* disable Error Interrupt	*/
+    	);
+    DBGout();
+    return 0;
+}
+
+/* set value of the output control register */
+int CAN_SetOMode (int board, int arg)
+{
+
+    DBGin("CAN_SetOMode");
+	DBGprint(DBG_DATA,("[%d] outc=0x%x", board, arg));
+
+    DBGout();
+    return 0;
+}
+
+
+/* FlexCAN only knows a 'mask' value, code is ignored */
+int CAN_SetMask (int board, unsigned int code, unsigned int mask)
+{
+
+    DBGin("CAN_SetMask");
+    DBGprint(DBG_DATA,("[%d] acc=0x%x mask=0x%x",  board, code, mask));
+    CANoutw(board, rxgmskhi, mask >> 16);
+    CANoutw(board, rxgmsklo, mask && 16);
+
+    DBGout();
+    return 0;
+}
+
+
+int CAN_SendMessage (int board, canmsg_t *tx)
+{
+int i = 0;
+u16 stat;
+
+    DBGin("CAN_SendMessage");
+
+    /* 
+    IDLE - Idle Status. The IDLE bit indicates, when there is activity
+    on the CAN bus
+    1 - The CAn bus is Idle
+
+    TX/RX - Transmission/receive status. Indicates when the FlexCAN module
+    is transmitting or receiving a message. TX/RX has no meaning,
+    when IDLE = 1
+    0 - FlexCAN is receiving when IDLE = 0
+    1 - FlexCAN is transmitting when IDLE = 0
+    */
+
+    while ( 
+    	    ((stat = CANinw(board, estat)) & (CAN_ESTAT_IDLE + CAN_ESTAT_TX_RX))
+    	    == CAN_ESTAT_TX_RX
+    	  ) {
+
+	    if( current->need_resched ) schedule();
+	    /* if( need_resched ) schedule(); */
+    }
+
+    /* DBGprint(DBG_DATA,( */
+    		/* "CAN[%d]: tx.flags=%d tx.id=0x%lx tx.length=%d stat=0x%x", */
+		/* board, tx->flags, tx->id, tx->length, stat)); */
+
+    tx->length %= 9;			/* limit CAN message length to 8 */
+
+
+    /* Writing Control/Status word to hold TX Message Object inactive */
+    CAN_WRITE_CTRL(TRANSMIT_OBJ, TRANS_CODE_NOT_READY, 1);
+
+    /* fill the frame info and identifier fields , ID-Low and ID-High */
+    if(tx->flags & MSG_EXT) {
+    	/* use ID in extended message format */
+	DBGprint(DBG_DATA, ("---> send ext message \n"));
+	if( tx->flags & MSG_RTR) {
+	    CAN_WRITE_XOID_RTR(TRANSMIT_OBJ, tx->id);
+	} else {
+	    CAN_WRITE_XOID(TRANSMIT_OBJ, tx->id);
+	}
+    } else {
+	DBGprint(DBG_DATA, ("---> send std message \n"));
+	if( tx->flags & MSG_RTR) {
+	    CAN_WRITE_OID_RTR(TRANSMIT_OBJ, tx->id);
+	} else {
+	    CAN_WRITE_OID(TRANSMIT_OBJ, tx->id);
+	}
+    }
+
+    /* - fill data ---------------------------------------------------- */
+
+    for(i = 0; i < tx->length; i++) {
+    	CAN_OBJ[TRANSMIT_OBJ].msg[i] = tx->data[i];
+    }
+    /* Writing Control/Status word (active code, length) */
+    CAN_WRITE_CTRL(TRANSMIT_OBJ, TRANS_CODE_TRANSMIT_ONCE, tx->length);
+
+    /* - /end --------------------------------------------------------- */
+    DBGout();return i;
+}
+
+
+/* look if one of the receive message objects has something received */
+int CAN_GetMessage (int board, canmsg_t *rx )
+{
+int stat;
+int i = 0;
+int ctrl;
+  
+    DBGin("CAN_GetMessage");
+    stat = CANinw(board, estat);
+    DBGprint(DBG_DATA,("0x%x: stat=0x%x iflag=0x%x imask=0x%x" ,
+    			Base[board], stat,
+    			CANinw(board, iflag),
+    			CANinw(board, imask)));
+
+    rx->flags  = 0;
+    rx->length = 0;
+
+    /* CAN_register_dump(); */
+    /* CAN_object_dump(RECEIVE_OBJ); */
+    i = CANinw(board, iflag);
+    if( i & (1 << RECEIVE_OBJ)) {
+	/* reading the control status word of the identified message
+	 * buffer triggers a lock for that buffer.
+	 * A new received message frame which maches the message buffer
+	 * can not be written into this buffer while it is locked
+	 */
+        while (((ctrl = CAN_READ_CTRL(RECEIVE_OBJ)) & (REC_CODE_BUSY << 4)) == (REC_CODE_BUSY << 4)) {
+	    /* 20 cycles maximum wait */
+	    /* printf1("CAN_int, rx REC_CODE_BUSY"); */
+	}
+	/* printk("message received 0x%x\n", ctrl); */
+	rx->length = ctrl & 0x0f;
+	rx->id =  CAN_READ_OID(RECEIVE_OBJ);
+	memcpy(&rx->data[0], &(CAN_OBJ[RECEIVE_OBJ].MSG0), 8);
+
+	/* clear interrupts */
+	/* Int is cleared when the CPU reads the intrerupt flag register iflag
+	 * while the associated bit is set, and then writes it back as '1'
+	 * (and no new event of the same type occurs
+	 * between the read and write action.)
+	 * ! This is opposit to the TouCAN module, where the iflag bit
+	 * has to be written back with '0'
+	 */
+	CANsetw(board, iflag, (1 << RECEIVE_OBJ));
+	/* Reset message object */
+	CAN_WRITE_CTRL(RECEIVE_OBJ, REC_CODE_EMPTY, 8);
+	/* reading the free running timer will unlock any message buffers */
+	(void) CANinw(board, timer);
+	i = 1; /* signal one received message */
+    } else {
+	i = 0;
+    }
+
+    DBGout();
+    return i;
+
+}
+
+int CAN_VendorInit (int minor)
+{
+    DBGin("CAN_VendorInit");
+/* 1. Vendor specific part ------------------------------------------------ */
+    can_range[minor] = 0x180;
+
+/* End: 1. Vendor specific part ------------------------------------------- */
+
+    /* Request the controllers address space */
+
+    /* looks like not needed in uClinux with internal ressources ? */
+    /* It's Memory I/O */
+    if(NULL == request_mem_region(Base[minor], can_range[minor], "CAN-IO")) {
+	return -EBUSY;
+    }
+
+    /* not necessary in uClinux, but ... */
+    can_base[minor] = ioremap(Base[minor], can_range[minor]);
+    /* now the virtual address can be used for the register address macros */
+
+/* 2. Vendor specific part ------------------------------------------------ */
+
+
+
+/* End: 2. Vendor specific part ------------------------------------------- */
+
+    if( IRQ[minor] > 0 ) {
+        if( Can_RequestIrq( minor, IRQ[minor] , CAN_Interrupt) ) {
+	     printk("Can[%d]: Can't request IRQ %d \n", minor, IRQ[minor]);
+	     DBGout(); return -EBUSY;
+        }
+    }
+    DBGout(); return 1;
+
+}
+
+
+/*
+ * The plain CAN interrupt
+ *
+ *				RX ISR           TX ISR
+ *                              8/0 byte
+ *                               _____            _   ___
+ *                         _____|     |____   ___| |_|   |__
+ *---------------------------------------------------------------------------
+ * 1) Motorola ColdFire 5282
+ *  66 MHz, xxxxxx bogomips
+ *                              __/__µs            __ µs
+ * 
+ * 1) 1Byte = (42-27)/8 =      µs
+ * 2) 1Byte = (24-12)/8 =      µs
+ *
+ *
+ *
+ * RX Int with to Receive channels:
+ * 1)                _____   ___
+ *             _____|     |_|   |__
+ *                   30    5  20  µs
+ *   first ISR normal length,
+ *   time between the two ISR -- short
+ *   sec. ISR shorter than first, why? it's the same message
+ */
+
+void CAN_Interrupt ( int irq, void *dev_id, struct pt_regs *ptregs )
+{
+int		board;
+int		estat;
+unsigned long	flags;
+int		ctrl;
+int 		irqsrc, dummy;
+msg_fifo_t	*RxFifo; 
+msg_fifo_t	*TxFifo;
+int		last_tx_id;
+
+/* do we have some LEDS on the ColdFire EVA ?? */
+#if CONFIG_TIME_MEASURE   
+    
+#endif
+  /* printk(" CAN ISR %d\n", irq);  */
+
+
+    board = *(int *)dev_id;
+
+    RxFifo = &Rx_Buf[board]; 
+    TxFifo = &Tx_Buf[board];
+
+
+
+    /* One of the following can actually occur:
+       BusOff
+       ErrInt - in this case:
+       	bits 4-5 - FCS - Fault confinment state tells us
+       	 00 - all ok, error active mode
+       	 01 - error passive mode
+        bit 8 - RX warning level reached
+        bit 9 - Tx warning level reached
+
+       At the moment we aren't interested in more information
+
+       all bits in estat are read only except for
+       BOFF_INT WAKE_INT und ERR_INT which are interrupt sources 
+       and can be written by the host to '0' to reset Interrupt
+       conditions.
+    */
+    estat = CANinw(board, estat);
+#if 0
+if (irq == 152) {
+CAN_register_dump();
+	CANresetw(board, estat, 7);
+CAN_register_dump();
+CAN_object_dump(0);
+}
+#endif
+    if (estat &
+       (CAN_ESTAT_BOFF_INT + CAN_ESTAT_ERR_INT + CAN_ESTAT_WAKE_INT))  {
+	/* we have an error interrupt
+	 * later on we can move this error handling at the end of the ISR
+	 * to heve better RX response times */
+	/* printk(" error status 0x%04x \n", estat); */
+	/* reset all error conditions, we have saved them in estat 
+	 * BusOff disables the Interrupt generation itself by resetting
+	 * the mask in canctrl0.
+	 * ErrInt - to clear this bit, first read it (already done)
+	 * then write as a zero.
+	 *
+	 * we do reset all possible interrupts and look what we got later
+	 */
+	CANresetw(board, estat, 
+	    (CAN_ESTAT_BOFF_INT + CAN_ESTAT_ERR_INT + CAN_ESTAT_WAKE_INT));
+
+	/* check for Bus Off condition */
+	if (estat & CAN_ESTAT_BOFF_INT) {
+	    CAN_StopChip (board);
+	    printk("We are BusOff now\n");
+	}
+#if 0
+	if (CAN_ESTAT_TX_WARN == (estat & (CAN_ESTAT_ERR_INT + CAN_ESTAT_TX_WARN))) {
+	    printk("Tx Warning level reached\n");
+	}
+	if (CAN_ESTAT_RX_WARN == (estat & (CAN_ESTAT_ERR_INT + CAN_ESTAT_RX_WARN))) {
+	    printk("Rx Warning level reached\n");
+	}
+	if (estat & (CAN_ESTAT_ERR_INT + CAN_ESTAT_FCS)) {
+	    if(0 == (estat & CAN_ESTAT_FCS)) {
+		printk("Going error active\n");
+	    }
+	    if(CAN_ESTAT_FCS0 == (estat & CAN_ESTAT_FCS)) {
+		printk("Going error passive\n");
+	    }
+	}
+#endif
+    }
+
+    /* check for message object interrupts */ 
+    irqsrc = CANinw(board, iflag);
+    if(irqsrc == 0) {
+         /* first call to ISR, it's not for me ! */
+	 goto IRQdone_doneNothing;
+    }
+    do {
+    /* loop as long as the CAN controller shows interrupts */
+
+    do_gettimeofday(&(RxFifo->data[RxFifo->head]).timestamp);
+
+    /* preset flags */
+    (RxFifo->data[RxFifo->head]).flags =
+        		(RxFifo->status & BUF_OVERRUN ? MSG_BOVR : 0);
+
+    /*========== receive interrupt */
+    if( irqsrc & (1 << RECEIVE_OBJ)) {
+DBGprint(DBG_DATA, (" => got  RX IRQ[%d]: 0x%0x\n", board, irqsrc));
+        while (((ctrl = CAN_READ_CTRL(RECEIVE_OBJ)) 
+                       & (REC_CODE_BUSY << 4)) == (REC_CODE_BUSY << 4)) {
+	    /* 20 cycles maximum wait */
+	    /* printf1("CAN_int, rx REC_CODE_BUSY"); */
+	}
+	last_tx_id = CAN_READ_OID_AND_RTR(TRANSMIT_OBJ);
+	if (CAN_READ_OID_AND_RTR(RECEIVE_OBJ) == last_tx_id) {
+          /*
+	    This is obviously a message we sent ourselves recently.
+	    There is no point in delivering this to the upper layer.
+	    We rely on the fact
+	    that no other node will ever send a message with the same OID.
+           */
+
+	} else {
+
+	    (RxFifo->data[RxFifo->head]).id =  CAN_READ_OID(RECEIVE_OBJ);
+
+	    /* get message length,  strip length code */ 
+	    dummy = ctrl & 0x0f;
+	    (RxFifo->data[RxFifo->head]).length = dummy;
+	    dummy %= 9;	/* limit count to 8 bytes */
+	    memcpy(&(RxFifo->data[RxFifo->head]).data[0], &(CAN_OBJ[RECEIVE_OBJ].MSG0), dummy);
+	    RxFifo->status = BUF_OK;
+	    RxFifo->head = ++(RxFifo->head) % MAX_BUFSIZE;
+
+	    if(RxFifo->head == RxFifo->tail) {
+		    printk("CAN[%d] RX: FIFO overrun\n", board);
+		    RxFifo->status = BUF_OVERRUN;
+	    } 
+	    /*---------- kick the select() call  -*/
+	    /* __wake_up(struct wait_queue ** p, unsigned int mode); */
+	    /* __wake_up(struct wait_queue_head_t *q, unsigned int mode); */
+	    /*
+	    void wake_up(struct wait_queue**condition)                                                                  
+	    */
+	    /* This function will wake up all processes
+	       that are waiting on this event queue,
+	       that are in interruptible sleep
+	    */
+	    wake_up_interruptible(  &CanWait[board] ); 
+
+
+	    /* check for CAN controller overrun */
+	    /* ToDo */
+        }
+
+	/* CANinw(board, iflag); */
+	/* CANoutw(board, iflag, 1 << RECEIVE_OBJ); */
+	/* 5282 overwrites with '1' */
+	CANsetw(board, iflag, (1 << RECEIVE_OBJ));
+	CAN_WRITE_CTRL(RECEIVE_OBJ, REC_CODE_EMPTY, 8);
+
+   }
+    /*========== transmit interrupt */
+    if( irqsrc & (1 << TRANSMIT_OBJ)) {
+DBGprint(DBG_DATA, (" => got  TX IRQ[%d]: 0x%0x\n", board, irqsrc));
+/* CAN_register_dump(); */
+	if( TxFifo->free[TxFifo->tail] == BUF_EMPTY ) {
+	    /* printk("TXE\n"); */
+	    TxFifo->status = BUF_EMPTY;
+            TxFifo->active = 0;
+            goto Tx_done;
+	} else {
+	    /* printk("TX\n"); */
+	}
+
+
+
+        /* enter critical section */
+        save_flags(flags);cli();
+
+        while ((CAN_READ_CTRL(TRANSMIT_OBJ) & (REC_CODE_BUSY << 4)) == (REC_CODE_BUSY << 4)) {
+        	/* printk("CAN_int, tx REC_CODE_BUSY"); */
+        	;
+	}
+
+	/* now we can check here if an RTR was received with this TX channel */
+	if ((CAN_READ_CTRL(TRANSMIT_OBJ) & (REC_CODE_FULL << 4)) == (REC_CODE_FULL << 4))
+	{
+            printk("CAN_int, got receive interrupt on transmit channel,  OID= %d\n",
+            						CAN_READ_OID(TRANSMIT_OBJ));
+	} else {
+	    /* Real Transmit Interrupt */
+
+	    /* Writing Control/Status word to hold TX Message Object inactive */
+	    CAN_WRITE_CTRL(TRANSMIT_OBJ, TRANS_CODE_NOT_READY, 1);
+
+	    /* fill the frame info and identifier fields , ID-Low and ID-High */
+	    if( (TxFifo->data[TxFifo->tail]).flags & MSG_EXT ) {
+		/* use ID in extended message format */
+		DBGprint(DBG_DATA, ("---> send ext message \n"));
+		if( (TxFifo->data[TxFifo->tail]).flags & MSG_RTR) {
+		    CAN_WRITE_XOID_RTR(TRANSMIT_OBJ, (TxFifo->data[TxFifo->tail]).id);
+		} else {
+		    CAN_WRITE_XOID(TRANSMIT_OBJ, (TxFifo->data[TxFifo->tail]).id);
+		}
+	    } else {
+		DBGprint(DBG_DATA, ("---> send std message \n"));
+		if( (TxFifo->data[TxFifo->tail]).flags & MSG_RTR) {
+		    CAN_WRITE_OID_RTR(TRANSMIT_OBJ, (TxFifo->data[TxFifo->tail]).id);
+		} else {
+		    CAN_WRITE_OID(TRANSMIT_OBJ, (TxFifo->data[TxFifo->tail]).id);
+		}
+	    }
+
+	    memcpy( &(CAN_OBJ[TRANSMIT_OBJ].MSG0),
+		&(TxFifo->data[TxFifo->tail]).data[0],
+		(TxFifo->data[TxFifo->tail]).length);
+
+
+	    /* Writing Control/Status word (active code, length) */
+	    CAN_WRITE_CTRL(TRANSMIT_OBJ, TRANS_CODE_TRANSMIT_ONCE,
+		    (TxFifo->data[TxFifo->tail]).length);
+
+	    TxFifo->free[TxFifo->tail] = BUF_EMPTY; /* now this entry is EMPTY */
+	    TxFifo->tail = ++(TxFifo->tail) % MAX_BUFSIZE;
+
+	    /* leave critical section */
+	    restore_flags(flags);
+	}
+
+	/* Reset Interrupt pending at Transmit Object */
+	CANsetw(board, iflag, (1 << TRANSMIT_OBJ));
+   }
+Tx_done:
+#if 0
+   /*========== error status */
+   if( irqsrc & CAN_ERROR_INT ) {
+   int s;
+	printk("CAN[%d]: Tx err!\n", board);
+        TxErr[board]++;
+
+        /* insert error */
+        s = CANin(board,canstat);
+        if(s & CAN_BUS_STATUS )
+	    (RxFifo->data[RxFifo->head]).flags += MSG_BUSOFF; 
+        if(s & CAN_ERROR_STATUS)
+	    (RxFifo->data[RxFifo->head]).flags += MSG_PASSIVE; 
+
+	(RxFifo->data[RxFifo->head]).id = 0xFFFFFFFF;
+        /* (RxFifo->data[RxFifo->head]).length = 0; */
+	/* (RxFifo->data[RxFifo->head]).data[i] = 0; */
+	RxFifo->status = BUF_OK;
+        RxFifo->head = ++(RxFifo->head) % MAX_BUFSIZE;
+	if(RxFifo->head == RxFifo->tail) {
+		printk("CAN[%d] RX: FIFO overrun\n", board);
+		RxFifo->status = BUF_OVERRUN;
+        } 
+	
+   }
+   if( irqsrc & CAN_OVERRUN_INT ) {
+   int s;
+	printk("CAN[%d]: overrun!\n", board);
+        Overrun[board]++;
+
+        /* insert error */
+        s = CANin(board,canstat);
+        if(s & CAN_DATA_OVERRUN)
+	    (RxFifo->data[RxFifo->head]).flags += MSG_OVR; 
+
+	(RxFifo->data[RxFifo->head]).id = 0xFFFFFFFF;
+        /* (RxFifo->data[RxFifo->head]).length = 0; */
+	/* (RxFifo->data[RxFifo->head]).data[i] = 0; */
+	RxFifo->status = BUF_OK;
+        RxFifo->head = ++(RxFifo->head) % MAX_BUFSIZE;
+	if(RxFifo->head == RxFifo->tail) {
+		printk("CAN[%d] RX: FIFO overrun\n", board);
+		RxFifo->status = BUF_OVERRUN;
+        } 
+
+        CANout(board, cancmd, CAN_CLEAR_OVERRUN_STATUS );
+   } 
+#endif
+   } while( (irqsrc = CANinw(board, iflag)) != 0);
+    /* CANoutw(board, iflag, 0xffff); */
+
+/* IRQdone: */
+    DBGprint(DBG_DATA, (" => leave IRQ[%d]\n", board));
+IRQdone_doneNothing:
+}
+
+
+
+void CAN_register_dump(void)
+{
+volatile flex_can_t *tou_can = (flex_can_t *)(MCF_MBAR + 0x1c0000);
+
+    printk("Flex CAN register layout\n");
+
+#define  printregister(s, name) printk(s, &name , name)
+    
+    /* printk(" %p: 0x%x \n", tou_can, *(unsigned char *)tou_can); */
+    /* printk(" %p: 0x%x \n", (unsigned char *)tou_can + 1, *(((unsigned char *)tou_can) + 1)); */
+
+    printregister(" CAN_ModulConfigRegister      %p %0x\n", CAN_ModulConfigRegister);
+    printregister(" CAN_ControlReg0              %p %0x\n", CAN_ControlReg0);
+    printregister(" CAN_ControlReg1              %p %0x\n", CAN_ControlReg1);
+    printregister(" CAN_ControlReg2              %p %0x\n", CAN_ControlReg2);
+
+    printregister(" CAN_PrescalerDividerRegister %p %0x\n", CAN_PrescalerDividerRegister);
+    printregister(" CAN_TimerRegister            %p %0x\n", CAN_TimerRegister);
+#if 0
+    printregister(" CAN_ReceiveGlobalMask        %p %0x\n", CAN_ReceiveGlobalMask);
+    printregister(" CAN_ReceiveBuffer14Mask      %p %0x\n", CAN_ReceiveBuffer14Mask);
+    printregister(" CAN_ReceiveBuffer15Mask      %p %0x\n", CAN_ReceiveBuffer15Mask);
+#else
+    printregister(" CAN_ReceiveGlobalMaskHigh    %p %0x\n", CAN_ReceiveGlobalMaskHigh);
+    printregister(" CAN_ReceiveGlobalMaskLow     %p %0x\n", CAN_ReceiveGlobalMaskLow);
+    printregister(" CAN_ReceiveBuffer14MaskHigh  %p %0x\n", CAN_ReceiveBuffer14MaskHigh);
+    printregister(" CAN_ReceiveBuffer14MaskLow   %p %0x\n", CAN_ReceiveBuffer14MaskLow);
+    printregister(" CAN_ReceiveBuffer15MaskHigh  %p %0x\n", CAN_ReceiveBuffer15MaskHigh);
+    printregister(" CAN_ReceiveBuffer15MaskLow   %p %0x\n", CAN_ReceiveBuffer15MaskLow);
+#endif
+    printregister(" CAN_ErrorStatusRegister      %p %0x\n", CAN_ErrorStatusRegister);
+    printregister(" CAN_InterruptMasks           %p %0x\n", CAN_InterruptMasks);
+    printregister(" CAN_InterruptFlags           %p %0x\n", CAN_InterruptFlags);
+    printregister(" CAN_ReceiveErrorCounter      %p %0x\n", CAN_ReceiveErrorCounter);
+    printregister(" CAN_TransmitErrorCounter     %p %0x\n", CAN_TransmitErrorCounter);
+}
+
+
+void CAN_object_dump(int object)
+{
+int board = 0;   /* be prepared for an board paramter, if later on .. */
+unsigned int vh;
+unsigned int vl;
+
+    volatile unsigned char *cp = (unsigned char *)(MCF_MBAR + 0x1c0080 + (0x10 * object));
+    for(vl = 0; vl < 16; vl++) {
+	printk("%2x ", *(cp + vl));
+    }
+    printk("\n");
+
+
+    printk("Flex CAN object %d\n", object);
+    vl = CAN_OBJ[object].ctl_status;
+    printk(" Ctrl/Status 0x%x\n", vl);
+    vh = CAN_OBJ[object].id_high.id_high;
+    printk(" Id high 0x%x\n", vh);
+    vl = CAN_OBJ[object].id_low.id_low;
+    printk(" Id low 0x%x\n", vl);
+    printk(" StdId  %d/0x%x\n", vh >> 5, vh >> 5);
+    vh =  (vl >> 1) + ((vh & 7) << 15) + ((vh & 0xffe0) << 13);
+    printk(" ExtId  %d/0x%x\n", vh, vh);
+}
diff -urN linux-2.4.29/drivers/char/can4linux/can_mcf5282.h linux-2.4.29-uc1/drivers/char/can4linux/can_mcf5282.h
--- linux-2.4.29/drivers/char/can4linux/can_mcf5282.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_mcf5282.h	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ * can_mc5282.h - can4linux CAN driver module
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2003 port GmbH Halle/Saale
+ *------------------------------------------------------------------
+ * $Header: Exp $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: $
+ *
+ *
+ *
+ *--------------------------------------------------------------------------
+ */
+
+
+extern unsigned int Base[];
+
+
+#define CAN_SYSCLK 32
+
+/* define some types, header file comes from CANopen */
+#define UNSIGNED8 u8
+#define UNSIGNED16 u16
+
+
+#define MCFFLEXCAN_BASE (MCF_MBAR + 0x1c0000)	/* Base address FlexCAN module */
+
+
+/* can4linux does not use all the full CAN features, partly because it doesn't
+   make sense.
+ */
+
+/* We use only one transmit object of all messages to be transmitted */
+#define TRANSMIT_OBJ 0
+#define RECEIVE_OBJ 1
+
+
+#include "TouCAN.h"
+
+
+
diff -urN linux-2.4.29/drivers/char/can4linux/can_open.c linux-2.4.29-uc1/drivers/char/can4linux/can_open.c
--- linux-2.4.29/drivers/char/can4linux/can_open.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_open.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,197 @@
+/*
+ * can_open - can4linux CAN driver module
+ *
+ * can4linux -- LINUX CAN device driver source
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * 
+ * Copyright (c) 2001 port GmbH Halle/Saale
+ * (c) 2001 Heinz-Jürgen Oertel (oe@port.de)
+ *          Claus Schroeter (clausi@chemie.fu-berlin.de)
+ *------------------------------------------------------------------
+ * $Header: /var/cvs/uClinux-2.4.x/drivers/char/can4linux/can_open.c,v 1.1 2003/07/18 00:11:46 gerg Exp $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: can_open.c,v $
+ * Revision 1.1  2003/07/18 00:11:46  gerg
+ * I followed as much rules as possible (I hope) and generated a patch for the
+ * uClinux distribution. It contains an additional driver, the CAN driver, first
+ * for an SJA1000 CAN controller:
+ *   uClinux-dist/linux-2.4.x/drivers/char/can4linux
+ * In the "user" section two entries
+ *   uClinux-dist/user/can4linux     some very simple test examples
+ *   uClinux-dist/user/horch         more sophisticated CAN analyzer example
+ *
+ * Patch submitted by Heinz-Juergen Oertel <oe@port.de>.
+ *
+ *
+ *
+ *--------------------------------------------------------------------------
+ */
+
+
+/**
+* \file can_open.c
+* \author Heinz-Jürgen Oertel, port GmbH
+* $Revision: 1.1 $
+* $Date: 2003/07/18 00:11:46 $
+*
+*
+*/
+
+
+/* header of standard C - libraries */
+/* #include <linux/module.h>			 */
+
+/* header of common types */
+
+/* shared common header */
+
+/* header of project specific types */
+
+/* project headers */
+#include "can_defs.h"
+
+/* local header */
+
+/* constant definitions
+---------------------------------------------------------------------------*/
+
+/* local defined data types
+---------------------------------------------------------------------------*/
+
+/* list of external used functions, if not in headers
+---------------------------------------------------------------------------*/
+
+/* list of global defined functions
+---------------------------------------------------------------------------*/
+
+/* list of local defined functions
+---------------------------------------------------------------------------*/
+
+/* external variables
+---------------------------------------------------------------------------*/
+
+/* global variables
+---------------------------------------------------------------------------*/
+int Can_isopen[4] = { 0, 0, 0, 0};   /* device minor already opened */
+
+/* local defined variables
+---------------------------------------------------------------------------*/
+/* static char _rcsid[] = "$Id: can_open.c,v 1.1 2003/07/18 00:11:46 gerg Exp $"; */
+
+
+/***************************************************************************/
+/**
+*
+* \brief int open(const char *pathname, int flags);
+* opens the CAN device for following operations
+* \param pathname device pathname, usual /dev/can?
+* \param flags is one of \c O_RDONLY, \c O_WRONLY or \c O_RDWR which request
+*       opening  the  file  read-only,  write-only  or read/write,
+*       respectively.
+*
+*
+* The open call is used to "open" the device.
+* Doing a first initialization according the to values in the /proc/sys/Can
+* file system.
+* Additional an ISR function is assigned to the IRQ.
+*
+* The CLK OUT pin is configured for creating the same frequency
+* like the chips input frequency fclk (XTAL). 
+*
+* If Vendor Option \a VendOpt is set to 's' the driver performs
+* an hardware reset befor initializing the chip.
+*
+* \returns
+* open return the new file descriptor,
+* or -1 if an error occurred (in which case, errno is set appropriately).
+*
+* \par ERRORS
+* the following errors can occur
+* \arg \c ENXIO  the file is a device special file
+* and no corresponding device exists.
+* \arg \c EINVAL illegal \b minor device number
+* \arg \c EINVAL wrong IO-model format in /proc/sys/Can/IOmodel
+* \arg \c EBUSY  IRQ for hardware is not available
+* \arg \c EBUSY  I/O region for hardware is not available
+
+*/
+int can_open( __LDDK_OPEN_PARAM )
+{
+int retval = 0;
+
+    DBGin("can_open");
+    {
+
+	int lasterr;	
+
+	unsigned int minor = __LDDK_MINOR;
+
+	if( minor > MAX_CHANNELS )
+	{
+	    printk("CAN: Illegal minor number %d\n", minor);
+	    DBGout();
+	    return -EINVAL;
+	}
+	/* check if device is already open, should be used only by one process */
+
+#ifdef UNSAFE
+	/* if(Can_isopen[minor]) { */
+	    /* MOD_DEC_USE_COUNT; */
+	    /* DBGout(); */
+	    /* return -ENXIO; */
+	/* } */
+	++Can_isopen[minor];		/* flag device in use */
+#else
+	if(Can_isopen[minor] == 1) {
+	    DBGout();
+	    return -ENXIO;
+	}
+	Can_isopen[minor] = 1;		/* flag device in use */
+#endif
+	if( Base[minor] == 0x00) {
+	    /* No device available */
+	    printk("CAN[%d]: no device available\n", minor);
+	    DBGout();
+	    return -ENXIO;
+	}
+
+	/* the following does all the board specific things
+	   also memory remapping if necessary */
+	if( (lasterr = CAN_VendorInit(minor)) < 0 ){
+	    DBGout();
+	    return lasterr;
+	}
+	/* Access macros based in can_base[] should work now */
+	/* CAN_ShowStat(minor); */
+
+/* controller_available(curr + 0x400, 4); */
+	Can_WaitInit(minor);	/* initialize wait queue for select() */
+	Can_FifoInit(minor);
+#if CAN_USE_FILTER
+	Can_FilterInit(minor);
+#endif
+
+	if( CAN_ChipReset(minor) < 0 ) {
+	    DBGout();
+	    return -EINVAL;
+	}
+	CAN_StartChip(minor);
+#if DEBUG
+    CAN_ShowStat(minor);
+#endif
+    }
+
+    MOD_INC_USE_COUNT;
+    DBGout();
+    return retval;
+}
+
diff -urN linux-2.4.29/drivers/char/can4linux/can_read.c linux-2.4.29-uc1/drivers/char/can4linux/can_read.c
--- linux-2.4.29/drivers/char/can4linux/can_read.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_read.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,169 @@
+/*
+ * can_read - can4linux CAN driver module
+ *
+ * can4linux -- LINUX CAN device driver source
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * 
+ * Copyright (c) 2001 port GmbH Halle/Saale
+ * (c) 2001 Heinz-Jürgen Oertel (oe@port.de)
+ *          Claus Schroeter (clausi@chemie.fu-berlin.de)
+ *------------------------------------------------------------------
+ * $Header: $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: can_read.c,v $
+ *
+ *
+ *
+ *--------------------------------------------------------------------------
+ */
+
+
+/**
+* \file can_read.c
+* \author Heinz-Jürgen Oertel, port GmbH
+* $Revision: 1.4 $
+* $Date: 2001/09/14 14:58:09 $
+*
+* Module Description 
+* see Doxygen Doc for all possibilities
+*
+*
+*
+*/
+
+
+/* header of standard C - libraries */
+
+/* header of common types */
+
+/* shared common header */
+
+/* header of project specific types */
+
+/* project headers */
+#include "can_defs.h"
+
+/* local header */
+
+/* constant definitions
+---------------------------------------------------------------------------*/
+
+/* local defined data types
+---------------------------------------------------------------------------*/
+
+/* list of external used functions, if not in headers
+---------------------------------------------------------------------------*/
+
+/* list of global defined functions
+---------------------------------------------------------------------------*/
+
+/* list of local defined functions
+---------------------------------------------------------------------------*/
+
+/* external variables
+---------------------------------------------------------------------------*/
+
+/* global variables
+---------------------------------------------------------------------------*/
+
+/* local defined variables
+---------------------------------------------------------------------------*/
+/* static char _rcsid[] = "$Id: can_read.c,v 1.4 2001/09/14 14:58:09 oe Exp $"; */
+
+
+
+/***************************************************************************/
+/**
+*
+* \brief ssize_t read(int fd, void *buf, size_t count);
+* the read system call
+* \param fd The descriptor to read from.
+* \param buf The destination data buffer (array of CAN canmsg_t).
+* \param count The number of bytes to read.
+*
+* read() attempts to read up to \a count CAN messages from file
+* descriptor fd into the buffer starting at buf.
+* buf must be large enough to hold count times the size of 
+* one CAN message structure \b canmsg_t.
+* 
+* \code
+int got;
+canmsg_t rx[80];			// receive buffer for read()
+
+    got = read(can_fd, rx , 80 );
+    if( got > 0) {
+      ...
+    } else {
+	// read returned with error
+	fprintf(stderr, "- Received got = %d\n", got);
+	fflush(stderr);
+    }
+
+
+* \endcode
+*
+* \par ERRORS
+*
+* the following errors can occur
+*
+* \arg \c EINVAL \b buf points not to an large enough area,
+*
+* \returns
+* On success, the number of bytes read is returned
+* (zero indicates end of file).
+* It is not an  error if this number is
+* smaller than the number of bytes requested;
+* this may happen for example
+* because fewer bytes are actually available right now,
+* or because read() was interrupted by a signal.
+* On error, -1 is returned, and errno is set  appropriately.
+*
+* \internal
+*/
+
+int can_read( __LDDK_READ_PARAM )
+{
+  int retval=0;
+
+  DBGin("can_read");
+  {
+	unsigned int minor = __LDDK_MINOR;
+	msg_fifo_t *RxFifo = &Rx_Buf[minor];
+	canmsg_t *addr; 
+	int written = 0;
+
+	addr = (canmsg_t *)buffer;
+	
+	if( verify_area( VERIFY_WRITE, buffer, count * sizeof(canmsg_t) )) {
+	   DBGout();
+	   return -EINVAL;
+	}
+	while( written < count && RxFifo->status == BUF_OK ) {
+	    if( RxFifo->tail == RxFifo->head ) {
+		RxFifo->status = BUF_EMPTY;
+		break;
+	    }	
+
+	    __lddk_copy_to_user( (canmsg_t *) &addr[written], 
+			(canmsg_t *) &(RxFifo->data[RxFifo->tail]),
+			sizeof(canmsg_t) );
+	    written++;
+	    RxFifo->tail = ++(RxFifo->tail) % MAX_BUFSIZE;
+	}
+	DBGout();
+	return(written);
+	
+    } 
+    DBGout();
+    return retval;
+}
+
diff -urN linux-2.4.29/drivers/char/can4linux/can_select.c linux-2.4.29-uc1/drivers/char/can4linux/can_select.c
--- linux-2.4.29/drivers/char/can4linux/can_select.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_select.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,127 @@
+/* can_select
+*
+* can4linux -- LINUX CAN device driver source
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * 
+ * Copyright (c) 2001 port GmbH Halle/Saale
+ * (c) 2001 Heinz-Jürgen Oertel (oe@port.de)
+ *          Claus Schroeter (clausi@chemie.fu-berlin.de)
+ *------------------------------------------------------------------
+ * $Header: $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: can_select.c,v $
+ *
+ *
+ */
+#include "can_defs.h"
+
+#if  LINUX_VERSION_CODE >= 0x020200
+unsigned int can_select( __LDDK_SELECT_PARAM )
+#else
+int can_select( __LDDK_SELECT_PARAM )
+#endif
+{
+
+unsigned int minor = __LDDK_MINOR;
+msg_fifo_t *RxFifo = &Rx_Buf[minor];
+    DBGin("can_select");
+	    DBGprint(DBG_DATA,("minor = %d", minor));
+#if 0
+	    DBGprint(DBG_DATA,("file = %p", file));
+	    ;
+	    DBGprint(DBG_DATA,("s(CanWait[]) = %2d", sizeof(CanWait[0])));
+	    ;
+	    /* DBGprint(DBG_DATA,("s(CanWait)   = %2d", sizeof(CanWait))); */
+	    ;
+	    DBGprint(DBG_DATA,("&CanWait[] = %p", &CanWait[0]));
+	    DBGprint(DBG_DATA,("CanWait[minor].task_list.n = %p", CanWait[minor].task_list.next));
+	    DBGprint(DBG_DATA,("CanWait[minor].task_list.p = %p", CanWait[minor].task_list.prev));
+	    DBGprint(DBG_DATA,("&CanWait[minor]->task_list.p = %p", (&CanWait[minor])->task_list.prev));
+
+	    DBGprint(DBG_DATA,("wait = %p", wait));
+	    if(wait) {
+	    DBGprint(DBG_DATA,("wait->error = %d", wait->error));
+	    DBGprint(DBG_DATA,("wait->table = %p", wait->table));
+	    } else {
+	    DBGprint(DBG_DATA,("can not dereference wait components"));
+	    }
+#endif
+#ifdef DEBUG
+    CAN_ShowStat(minor);
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+    DBGprint(DBG_BRANCH,("POLL: fifo empty,poll waiting...\n"));
+
+    /* every event queue that could wake up the process
+     * and change the status of the poll operation
+     * can be added to the poll_table structure by
+     * calling the function poll_wait:  
+     */
+                /*     _select para, wait queue, _select para */
+/* X */		poll_wait(file, &CanWait[minor] , wait);
+
+    DBGprint(DBG_BRANCH,("POLL: wait returned \n"));
+    if( RxFifo->head != RxFifo->tail ) {
+	/* fifo has some telegrams */
+	/* Return a bit mask
+	 * describing operations that could be immediately performed
+	 * without blocking.
+	 */
+	DBGout();
+	/*
+	 * POLLIN This bit must be set
+	 *        if the device can be read without blocking. 
+	 * POLLRDNORM This bit must be set
+	 * if "normal'' data is available for reading.
+	 * A readable device returns (POLLIN | POLLRDNORM)
+	 *
+	 *
+	 *
+	 */
+	return POLLIN | POLLRDNORM;
+    }
+    DBGout();return 0;
+
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,3)
+    DBGprint(DBG_BRANCH,("POLL: fifo empty,poll waiting...\n"));
+    poll_wait(file, &CanWait[minor] , wait);
+    DBGprint(DBG_BRANCH,("POLL: wait returned \n"));
+    if( RxFifo->head != RxFifo->tail ) {
+	/* fifo has some telegrams */
+	DBGout();
+	return POLLIN | POLLRDNORM;
+    }
+    DBGout();return 0;
+
+#else
+    switch (sel_type) {
+	case SEL_IN:
+	    DBGprint(DBG_BRANCH,("sel_in \n"));
+	    if( RxFifo->head == RxFifo->tail ) {
+		DBGprint(DBG_BRANCH,("fifo empty \n"));
+		select_wait(&CanWait[minor],wait);
+		DBGout();return 0;
+	    }
+	    break;
+	case SEL_OUT:
+	    DBGprint(DBG_BRANCH,("sel_out \n"));
+	    /* ready for write ? */
+	    select_wait(&CanWait[minor],wait);
+	    DBGout();return 0;
+    }
+    DBGout();return 1;
+#endif
+
+        
+    DBGout();
+    return 0;
+}
diff -urN linux-2.4.29/drivers/char/can4linux/can_sja1000funcs.c linux-2.4.29-uc1/drivers/char/can4linux/can_sja1000funcs.c
--- linux-2.4.29/drivers/char/can4linux/can_sja1000funcs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_sja1000funcs.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,798 @@
+/* can_sja1000funcs
+ *
+ * can4linux -- LINUX CAN device driver source
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * 
+ * Copyright (c) 2002 port GmbH Halle/Saale
+ * (c) 2001 Heinz-Jürgen Oertel (oe@port.de)
+ *------------------------------------------------------------------
+ * $Header: /var/cvs/uClinux-2.4.x/drivers/char/can4linux/can_sja1000funcs.c,v 1.1 2003/07/18 00:11:46 gerg Exp $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: can_sja1000funcs.c,v $
+ * Revision 1.1  2003/07/18 00:11:46  gerg
+ * I followed as much rules as possible (I hope) and generated a patch for the
+ * uClinux distribution. It contains an additional driver, the CAN driver, first
+ * for an SJA1000 CAN controller:
+ *   uClinux-dist/linux-2.4.x/drivers/char/can4linux
+ * In the "user" section two entries
+ *   uClinux-dist/user/can4linux     some very simple test examples
+ *   uClinux-dist/user/horch         more sophisticated CAN analyzer example
+ *
+ * Patch submitted by Heinz-Juergen Oertel <oe@port.de>.
+ *
+ *
+ *
+ */
+#include "can_defs.h"
+#include <asm/delay.h>
+
+
+/* int	CAN_Open = 0; */
+
+/* timing values */
+u8 CanTiming[10][2]={
+	{CAN_TIM0_10K,  CAN_TIM1_10K},
+	{CAN_TIM0_20K,  CAN_TIM1_20K},
+	{CAN_TIM0_40K,  CAN_TIM1_40K},
+	{CAN_TIM0_50K,  CAN_TIM1_50K},
+	{CAN_TIM0_100K, CAN_TIM1_100K},
+	{CAN_TIM0_125K, CAN_TIM1_125K},
+	{CAN_TIM0_250K, CAN_TIM1_250K},
+	{CAN_TIM0_500K, CAN_TIM1_500K},
+	{CAN_TIM0_800K, CAN_TIM1_800K},
+	{CAN_TIM0_1000K,CAN_TIM1_1000K}};
+
+
+
+
+/* Board reset
+   means the following procedure:
+  set Reset Request
+  wait for Rest request is changing - used to see if board is available
+  initialize board (with valuse from /proc/sys/Can)
+    set output control register
+    set timings
+    set acceptance mask
+*/
+
+
+#ifdef DEBUG
+int CAN_ShowStat (int board)
+{
+    if (dbgMask && (dbgMask & DBG_DATA)) {
+    printk(" MODE 0x%x,", CANin(board, canmode));
+    printk(" STAT 0x%x,", CANin(board, canstat));
+    printk(" IRQE 0x%x,", CANin(board, canirq_enable));
+    /* printk(" INT 0x%x\n", CANin(board, canirq)); */
+    printk("\n");
+    }
+    return 0;
+}
+#endif
+
+int can_GetStat(
+	struct inode *inode,
+	CanStatusPar_t *stat
+	)
+{
+unsigned int board = MINOR(inode->i_rdev);	
+msg_fifo_t *Fifo;
+unsigned long flags;
+
+    stat->baud = Baud[board];
+    /* printk(" STAT ST %d\n", CANin(board, canstat)); */
+    stat->status = CANin(board, canstat);
+    /* printk(" STAT EWL %d\n", CANin(board, errorwarninglimit)); */
+    stat->error_warning_limit = CANin(board, errorwarninglimit);
+    stat->rx_errors = CANin(board, rxerror);
+    stat->tx_errors = CANin(board, txerror);
+    stat->error_code= CANin(board, errorcode);
+
+    /* Disable CAN Interrupts */
+    /* !!!!!!!!!!!!!!!!!!!!! */
+    save_flags(flags); cli();
+    Fifo = &Rx_Buf[board];
+    stat->rx_buffer_size = MAX_BUFSIZE;	/**< size of rx buffer  */
+    /* number of messages */
+    stat->rx_buffer_used =
+    	(Fifo->head < Fifo->tail)
+    	? (MAX_BUFSIZE - Fifo->tail + Fifo->head) : (Fifo->head - Fifo->tail);
+    Fifo = &Tx_Buf[board];
+    stat->tx_buffer_size = MAX_BUFSIZE;	/* size of tx buffer  */
+    /* number of messages */
+    stat->tx_buffer_used = 
+    	(Fifo->head < Fifo->tail)
+    	? (MAX_BUFSIZE - Fifo->tail + Fifo->head) : (Fifo->head - Fifo->tail);
+    /* Enable CAN Interrupts */
+    /* !!!!!!!!!!!!!!!!!!!!! */
+    restore_flags(flags);
+    return 0;
+}
+
+int CAN_ChipReset (int board)
+{
+u8 status;
+/* int i; */
+
+    DBGin("CAN_ChipReset");
+    DBGprint(DBG_DATA,(" INT 0x%x\n", CANin(board, canirq)));
+
+    CANout(board, canmode, CAN_RESET_REQUEST);
+
+
+
+    /* for(i = 0; i < 100; i++) SLOW_DOWN_IO; */
+    udelay(10);
+
+    status = CANin(board, canstat);
+
+    DBGprint(DBG_DATA,("status=0x%x mode=0x%x", status,
+	    CANin(board, canmode) ));
+    if( ! (CANin(board, canmode) & CAN_RESET_REQUEST ) ){
+	    printk("ERROR: no board present!");
+	    MOD_DEC_USE_COUNT;
+	    DBGout();return -1;
+    }
+
+#ifndef CAN_PELICANMODE
+# define canmode canctl
+#endif
+
+    DBGprint(DBG_DATA, ("[%d] CAN_mode 0x%x\n", board, CANin(board, canmode)));
+    /* select mode: Basic or PeliCAN */
+    CANout(board, canclk, CAN_MODE_PELICAN + CAN_MODE_CLK);
+    CANout(board, canmode, CAN_RESET_REQUEST + CAN_MODE_DEF);
+    DBGprint(DBG_DATA, ("[%d] CAN_mode 0x%x\n", board, CANin(board, canmode)));
+    
+    /* Board specific output control */
+    if (Outc[board] == 0) {
+	Outc[board] = CAN_OUTC_VAL; 
+    }
+    CANout(board, canoutc, Outc[board]);
+    DBGprint(DBG_DATA, ("[%d] CAN_mode 0x%x\n", board, CANin(board, canmode)));
+
+    CAN_SetTiming(board, Baud[board]    );
+    DBGprint(DBG_DATA, ("[%d] CAN_mode 0x%x\n", board, CANin(board, canmode)));
+    CAN_SetMask  (board, AccCode[board], AccMask[board] );
+    DBGprint(DBG_DATA, ("[%d] CAN_mode 0x%x\n", board, CANin(board, canmode)));
+
+    /* Can_dump(board); */
+    DBGout();
+    return 0;
+}
+
+
+int CAN_SetTiming (int board, int baud)
+{
+int i = 5;
+int custom=0;
+    DBGin("CAN_SetTiming");
+    DBGprint(DBG_DATA, ("baud[%d]=%d", board, baud));
+    switch(baud)
+    {
+	case   10: i = 0; break;
+	case   20: i = 1; break;
+	case   40: i = 2; break;
+	case   50: i = 3; break;
+	case  100: i = 4; break;
+	case  125: i = 5; break;
+	case  250: i = 6; break;
+	case  500: i = 7; break;
+	case  800: i = 8; break;
+	case 1000: i = 9; break;
+	default  : 
+		custom=1;
+    }
+    /* select mode: Basic or PeliCAN */
+    CANout(board, canclk, CAN_MODE_PELICAN + CAN_MODE_CLK);
+    if( custom ) {
+       CANout(board, cantim0, (u8) (baud >> 8) & 0xff);
+       CANout(board, cantim1, (u8) (baud & 0xff ));
+       printk(" custom bit timing BT0=0x%x BT1=0x%x ",
+       		CANin(board, cantim0), CANin(board, cantim1));
+    } else {
+       CANout(board,cantim0, (u8) CanTiming[i][0]);
+       CANout(board,cantim1, (u8) CanTiming[i][1]);
+    }
+    DBGprint(DBG_DATA,("tim0=0x%x tim1=0x%x",
+    		CANin(board, cantim0), CANin(board, cantim1)) );
+
+    DBGout();
+    return 0;
+}
+
+
+int CAN_StartChip (int board)
+{
+/* int i; */
+    RxErr[board] = TxErr[board] = 0L;
+    DBGin("CAN_StartChip");
+    DBGprint(DBG_DATA, ("[%d] CAN_mode 0x%x\n", board, CANin(board, canmode)));
+/*
+    CANout( board,cancmd, (CAN_RELEASE_RECEIVE_BUFFER 
+			  | CAN_CLEAR_OVERRUN_STATUS) ); 
+*/
+    /* for(i=0;i<100;i++) SLOW_DOWN_IO; */
+    udelay(10);
+    /* clear interrupts */
+    CANin(board, canirq);
+
+    /* Interrupts on Rx, TX, any Status change and data overrun */
+    CANset(board, canirq_enable, (
+		  CAN_OVERRUN_INT_ENABLE
+		+ CAN_ERROR_INT_ENABLE
+		+ CAN_TRANSMIT_INT_ENABLE
+		+ CAN_RECEIVE_INT_ENABLE ));
+
+    CANreset( board, canmode, CAN_RESET_REQUEST );
+    DBGprint(DBG_DATA,("start mode=0x%x", CANin(board, canmode)));
+
+    DBGout();
+    return 0;
+}
+
+
+int CAN_StopChip (int board)
+{
+    DBGin("CAN_StopChip");
+    CANset(board, canmode, CAN_RESET_REQUEST );
+    DBGout();
+    return 0;
+}
+
+/* set value of the output control register */
+int CAN_SetOMode (int board, int arg)
+{
+
+    DBGin("CAN_SetOMode");
+	DBGprint(DBG_DATA,("[%d] outc=0x%x", board, arg));
+	CANout(board, canoutc, arg);
+
+    DBGout();
+    return 0;
+}
+
+
+int CAN_SetMask (int board, unsigned int code, unsigned int mask)
+{
+#ifdef CPC_PCI
+# define R_OFF 4 /* offset 4 for the EMS CPC-PCI card */
+#else
+# define R_OFF 1
+#endif
+
+    DBGin("CAN_SetMask");
+    DBGprint(DBG_DATA,("[%d] acc=0x%x mask=0x%x",  board, code, mask));
+    CANout(board, frameinfo,
+			(unsigned char)((unsigned int)(code >> 24) & 0xff));	
+    CANout(board, frame.extframe.canid1,
+			(unsigned char)((unsigned int)(code >> 16) & 0xff));	
+    CANout(board, frame.extframe.canid2,
+			(unsigned char)((unsigned int)(code >>  8) & 0xff));	
+    CANout(board, frame.extframe.canid3,
+    			(unsigned char)((unsigned int)(code >>  0 ) & 0xff));	
+
+    CANout(board, frame.extframe.canid4,
+			(unsigned char)((unsigned int)(mask >> 24) & 0xff));
+    CANout(board, frame.extframe.canxdata[0 * R_OFF],
+			(unsigned char)((unsigned int)(mask >> 16) & 0xff));
+    CANout(board, frame.extframe.canxdata[1 * R_OFF],
+			(unsigned char)((unsigned int)(mask >>  8) & 0xff));
+    CANout(board, frame.extframe.canxdata[2 * R_OFF],
+			(unsigned char)((unsigned int)(mask >>  0) & 0xff));
+
+    DBGout();
+    return 0;
+}
+
+
+int CAN_SendMessage (int board, canmsg_t *tx)
+{
+int i = 0;
+int ext;			/* message format to send */
+u8 tx2reg, stat;
+
+    DBGin("CAN_SendMessage");
+
+    while ( ! (stat=CANin(board, canstat))
+  	& CAN_TRANSMIT_BUFFER_ACCESS ) {
+	    #if LINUX_VERSION_CODE >= 131587
+	    if( current->need_resched ) schedule();
+	    #else
+	    if( need_resched ) schedule();
+	    #endif
+    }
+
+    DBGprint(DBG_DATA,(
+    		"CAN[%d]: tx.flags=%d tx.id=0x%lx tx.length=%d stat=0x%x",
+		board, tx->flags, tx->id, tx->length, stat));
+
+    tx->length %= 9;			/* limit CAN message length to 8 */
+    ext = (tx->flags & MSG_EXT);	/* read message format */
+
+    /* fill the frame info and identifier fields */
+    tx2reg = tx->length;
+    if( tx->flags & MSG_RTR) {
+	    tx2reg |= CAN_RTR;
+    }
+    if(ext) {
+    DBGprint(DBG_DATA, ("---> send ext message \n"));
+	CANout(board, frameinfo, CAN_EFF + tx2reg);
+	CANout(board, frame.extframe.canid1, (u8)(tx->id >> 21));
+	CANout(board, frame.extframe.canid2, (u8)(tx->id >> 13));
+	CANout(board, frame.extframe.canid3, (u8)(tx->id >> 5));
+	CANout(board, frame.extframe.canid4, (u8)(tx->id << 3) & 0xff);
+
+    } else {
+	DBGprint(DBG_DATA, ("---> send std message \n"));
+	CANout(board, frameinfo, CAN_SFF + tx2reg);
+	CANout(board, frame.stdframe.canid1, (u8)((tx->id) >> 3) );
+	CANout(board, frame.stdframe.canid2, (u8)(tx->id << 5 ) & 0xe0);
+    }
+
+    /* - fill data ---------------------------------------------------- */
+    if(ext) {
+	for( i=0; i < tx->length ; i++) {
+	    CANout( board, frame.extframe.canxdata[R_OFF * i], tx->data[i]);
+	    	/* SLOW_DOWN_IO; SLOW_DOWN_IO; */
+	}
+    } else {
+	for( i=0; i < tx->length ; i++) {
+	    CANout( board, frame.stdframe.candata[R_OFF * i], tx->data[i]);
+	    	/* SLOW_DOWN_IO; SLOW_DOWN_IO; */
+	}
+    }
+    /* - /end --------------------------------------------------------- */
+    CANout(board, cancmd, CAN_TRANSMISSION_REQUEST );
+
+  DBGout();return i;
+}
+
+#if 1
+int CAN_GetMessage (int board, canmsg_t *rx )
+{
+u8 dummy = 0, stat;
+int i = 0;
+  
+    DBGin("CAN_GetMessage");
+    stat = CANin(board, canstat);
+#ifdef CAN_PELICANMODE
+#else
+    DBGprint(DBG_DATA,("0x%x:stat=0x%x ctl=0x%x",
+    			Base[board], stat, CANin(board, canctl)));
+#endif
+
+    rx->flags  = 0;
+    rx->length = 0;
+
+    if( stat & CAN_DATA_OVERRUN ) {
+    DBGprint(DBG_DATA,("Rx: overrun!\n"));
+    Overrun[board]++;
+    }
+
+    if( stat & CAN_RECEIVE_BUFFER_STATUS ) {
+#ifdef CAN_PELICANMODE
+#else
+      dummy  = CANin(board, canrxdes2);
+      rx->id = CANin(board, canrxdes1) << 3 | (dummy & 0xe0) >> 5 ;
+#endif
+      dummy  &= 0x0f; /* strip length code */ 
+      rx->length = dummy;
+      DBGprint(DBG_DATA,("rx.id=0x%lx rx.length=0x%x", rx->id, dummy));
+
+      dummy %= 9;
+      for( i = 0; i < dummy; i++) {
+#ifdef CAN_PELICANMODE
+#else
+	rx->data[i] = CANin(board, canrxdata[i]);
+#endif
+	DBGprint(DBG_DATA,("rx[%d]: 0x%x ('%c')",i,rx->data[i],rx->data[i] ));
+      }
+      CANout(board, cancmd, CAN_RELEASE_RECEIVE_BUFFER | CAN_CLEAR_OVERRUN_STATUS );
+    } else {
+      i=0;
+    }
+    DBGout();
+    return i;
+}
+#endif
+
+int CAN_VendorInit (int minor)
+{
+    DBGin("CAN_VendorInit");
+
+/* 1. Vendor specific part ------------------------------------------------ */
+#if defined(IXXAT_PCI03) || defined (PCM3680)
+    can_range[minor] = 0x200; /*stpz board or Advantech Pcm-3680 */
+#else
+    can_range[minor] = CAN_RANGE;
+#endif
+    
+/* End: 1. Vendor specific part ------------------------------------------- */
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,11)
+
+    /* Request the controllers address space */
+#if defined(CAN_PORT_IO) 
+    /* It's port I/O */
+    if(NULL == request_region(Base[minor], can_range[minor], "CAN-IO")) {
+	return -EBUSY;
+    }
+#else
+    /* It's Memory I/O */
+    if(NULL == request_mem_region(Base[minor], can_range[minor], "CAN-IO")) {
+	return -EBUSY;
+    }
+#endif
+
+#if CAN4LINUX_PCI
+	/* PCI scan has already remapped the address */
+	can_base[minor] = (unsigned char *)Base[minor];
+#else
+	can_base[minor] = ioremap(Base[minor], 0x200);
+#endif
+#else 	  /*  LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,11) */
+    
+/* both drivers use high memory area */
+#if !defined(CONFIG_PPC) && !defined(CAN4LINUX_PCI)
+    if( check_region(Base[minor], CAN_RANGE ) ) {
+		     /* MOD_DEC_USE_COUNT; */
+		     DBGout();
+		     return -EBUSY;
+    } else {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,0)
+          request_region(Base[minor], can_range[minor], "CAN-IO" );
+#else
+          request_region(Base[minor], can_range[minor] );
+#endif  /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,0) */
+    }
+#endif /* !defined  ... */
+
+    /* we don't need ioremap in older Kernels */
+    can_base[minor] = Base[minor];
+#endif  /*  LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,11) */
+
+    /* now the virtual address can be used for the register address macros */
+
+
+/* 2. Vendor specific part ------------------------------------------------ */
+
+/* ixxat/stpz board */
+#if defined(IXXAT_PCI03)
+	if( Base[minor] & 0x200 ) {
+		printk("Resetting IXXAT PC I-03 [contr 1]\n");
+		/* perform HW reset 2. contr*/
+		writeb(0xff, can_base[minor] + 0x300);
+	} else {
+		printk("Resetting IXXAT PC I-03 [contr 0]\n");
+		/* perform HW reset 1. contr*/
+		writeb(0xff, can_base[minor] + 0x100);
+	}
+#endif
+/* Advantech Pcm-3680 */
+#if defined (PCM3680)
+	if( Base[minor] & 0x200 ) {
+		printk("Resetting Advantech Pcm-3680 [contr 1]\n");
+		/* perform HW reset 2. contr*/
+		writeb(0xff, can_base[minor] + 0x300);
+	} else {
+		printk("Resetting Advantech Pcm-3680 [contr 0]\n");
+		/* perform HW reset 1. contr*/
+		writeb(0xff, can_base[minor] + 0x100);
+	}
+        mdelay(100);
+#endif
+
+
+/* End: 2. Vendor specific part ------------------------------------------- */
+
+    if( IRQ[minor] > 0 ) {
+        if( Can_RequestIrq( minor, IRQ[minor] , CAN_Interrupt) ) {
+	     printk("Can[%d]: Can't request IRQ %d \n", minor, IRQ[minor]);
+	     DBGout(); return -EBUSY;
+        }
+    }
+
+    DBGout(); return 1;
+}
+
+
+/*
+ * The plain 82c200 interrupt
+ *
+ *				RX ISR           TX ISR
+ *                              8/0 byte
+ *                               _____            _   ___
+ *                         _____|     |____   ___| |_|   |__
+ *---------------------------------------------------------------------------
+ * 1) CPUPentium 75 - 200
+ *  75 MHz, 149.91 bogomips
+ *  AT-CAN-MINI                 42/27µs            50 µs
+ *  CPC-PCI		        35/26µs		   
+ * ---------------------------------------------------------------------------
+ * 2) AMD Athlon(tm) Processor 1M
+ *    2011.95 bogomips
+ *  AT-CAN-MINI  std            24/12µs            ?? µs
+ *               ext id           /14µs
+ *
+ * 
+ * 1) 1Byte = (42-27)/8 = 1.87 µs
+ * 2) 1Byte = (24-12)/8 = 1.5  µs
+ *
+ *
+ *
+ * RX Int with to Receive channels:
+ * 1)                _____   ___
+ *             _____|     |_|   |__
+ *                   30    5  20  µs
+ *   first ISR normal length,
+ *   time between the two ISR -- short
+ *   sec. ISR shorter than first, why? it's the same message
+ */
+
+void CAN_Interrupt ( int irq, void *dev_id, struct pt_regs *ptregs )
+{
+extern void pc104_irqack(void);
+int minor;
+int i;
+unsigned long flags;
+int ext;			/* flag for extended message format */
+int irqsrc, dummy;
+msg_fifo_t   *RxFifo; 
+msg_fifo_t   *TxFifo;
+#if CAN_USE_FILTER
+msg_filter_t *RxPass;
+unsigned int id;
+#endif 
+#if 0
+int first = 0;
+#endif 
+
+#if CONFIG_TIME_MEASURE
+    outb(0xff, 0x378);  
+#endif
+
+    /*  minor = irq2minormap[irq]; */
+    minor = *(int *)dev_id;
+    RxFifo = &Rx_Buf[minor]; 
+    TxFifo = &Tx_Buf[minor];
+#if CAN_USE_FILTER
+    RxPass = &Rx_Filter[minor];
+#endif 
+
+    /* Disable PITA Interrupt */
+    /* writel(0x00000000, Can_pitapci_control[minor] + 0x0); */
+
+    irqsrc = CANin(minor, canirq);
+    if(irqsrc == 0) {
+         /* first call to ISR, it's not for me ! */
+	 goto IRQdone_doneNothing;
+    }
+#if defined(CCPC104)
+	pc104_irqack();
+#endif
+    do {
+    /* loop as long as the CAN controller shows interrupts */
+    DBGprint(DBG_DATA, (" => got IRQ[%d]: 0x%0x\n", minor, irqsrc));
+    /* Can_dump(minor); */
+
+    do_gettimeofday(&(RxFifo->data[RxFifo->head]).timestamp);
+
+#if 0
+    /* how often do we lop through the ISR ? */
+    if(first) printk("n = %d\n", first);
+    first++;
+#endif
+
+    /* preset flags */
+    (RxFifo->data[RxFifo->head]).flags =
+        		(RxFifo->status & BUF_OVERRUN ? MSG_BOVR : 0);
+
+    /*========== receive interrupt */
+    if( irqsrc & CAN_RECEIVE_INT ) {
+        /* fill timestamp as first action */
+
+	dummy  = CANin(minor, frameinfo );
+        if( dummy & CAN_RTR ) {
+	    (RxFifo->data[RxFifo->head]).flags |= MSG_RTR;
+	}
+
+        if( dummy & CAN_EFF ) {
+	    (RxFifo->data[RxFifo->head]).flags |= MSG_EXT;
+	}
+	ext = (dummy & CAN_EFF);
+	if(ext) {
+	    (RxFifo->data[RxFifo->head]).id =
+	          ((unsigned int)(CANin(minor, frame.extframe.canid1)) << 21)
+		+ ((unsigned int)(CANin(minor, frame.extframe.canid2)) << 13)
+		+ ((unsigned int)(CANin(minor, frame.extframe.canid3)) << 5)
+		+ ((unsigned int)(CANin(minor, frame.extframe.canid4)) >> 3);
+	} else {
+	    (RxFifo->data[RxFifo->head]).id =
+        	  ((unsigned int)(CANin(minor, frame.stdframe.canid1 )) << 3) 
+        	+ ((unsigned int)(CANin(minor, frame.stdframe.canid2 )) >> 5);
+	}
+	/* get message length */
+        dummy  &= 0x0f;			/* strip length code */ 
+        (RxFifo->data[RxFifo->head]).length = dummy;
+
+        dummy %= 9;	/* limit count to 8 bytes */
+        for( i = 0; i < dummy; i++) {
+            /* SLOW_DOWN_IO;SLOW_DOWN_IO; */
+	    if(ext) {
+		(RxFifo->data[RxFifo->head]).data[i] =
+			CANin(minor, frame.extframe.canxdata[R_OFF * i]);
+	    } else {
+		(RxFifo->data[RxFifo->head]).data[i] =
+			CANin(minor, frame.stdframe.candata[R_OFF * i]);
+	    }
+	}
+	RxFifo->status = BUF_OK;
+        RxFifo->head = ++(RxFifo->head) % MAX_BUFSIZE;
+
+	if(RxFifo->head == RxFifo->tail) {
+		printk("CAN[%d] RX: FIFO overrun\n", minor);
+		RxFifo->status = BUF_OVERRUN;
+        } 
+        /*---------- kick the select() call  -*/
+        /* __wake_up(struct wait_queue ** p, unsigned int mode); */
+        /* __wake_up(struct wait_queue_head_t *q, unsigned int mode); */
+        /*
+        void wake_up(struct wait_queue**condition)                                                                  
+        */
+        /* This function will wake up all processes
+           that are waiting on this event queue,
+           that are in interruptible sleep
+        */
+        wake_up_interruptible(  &CanWait[minor] ); 
+
+        CANout(minor, cancmd, CAN_RELEASE_RECEIVE_BUFFER );
+        if(CANin(minor, canstat) & CAN_DATA_OVERRUN ) {
+		 printk("CAN[%d] Rx: Overrun Status \n", minor);
+		 CANout(minor, cancmd, CAN_CLEAR_OVERRUN_STATUS );
+	}
+
+   }
+
+    /*========== transmit interrupt */
+    if( irqsrc & CAN_TRANSMIT_INT ) {
+	u8 tx2reg;
+	unsigned int id;
+	if( TxFifo->free[TxFifo->tail] == BUF_EMPTY ) {
+	    /* printk("TXE\n"); */
+	    TxFifo->status = BUF_EMPTY;
+            TxFifo->active = 0;
+            goto Tx_done;
+	} else {
+	    /* printk("TX\n"); */
+	}
+
+        /* enter critical section */
+        save_flags(flags);cli();
+
+	tx2reg = (TxFifo->data[TxFifo->tail]).length;
+	if( (TxFifo->data[TxFifo->tail]).flags & MSG_RTR) {
+		tx2reg |= CAN_RTR;
+	}
+        ext = (TxFifo->data[TxFifo->tail]).flags & MSG_EXT;
+        id = (TxFifo->data[TxFifo->tail]).id;
+        if(ext) {
+	    DBGprint(DBG_DATA, ("---> send ext message \n"));
+	    CANout(minor, frameinfo, CAN_EFF + tx2reg);
+	    CANout(minor, frame.extframe.canid1, (u8)(id >> 21));
+	    CANout(minor, frame.extframe.canid2, (u8)(id >> 13));
+	    CANout(minor, frame.extframe.canid3, (u8)(id >> 5));
+	    CANout(minor, frame.extframe.canid4, (u8)(id << 3) & 0xff);
+        } else {
+	    DBGprint(DBG_DATA, ("---> send std message \n"));
+	    CANout(minor, frameinfo, CAN_SFF + tx2reg);
+	    CANout(minor, frame.stdframe.canid1, (u8)((id) >> 3) );
+	    CANout(minor, frame.stdframe.canid2, (u8)(id << 5 ) & 0xe0);
+        }
+
+
+	tx2reg &= 0x0f;		/* restore length only */
+	if(ext) {
+	    for( i=0; i < tx2reg ; i++) {
+		CANout(minor, frame.extframe.canxdata[R_OFF * i],
+		    (TxFifo->data[TxFifo->tail]).data[i]);
+	    }
+        } else {
+	    for( i=0; i < tx2reg ; i++) {
+		CANout(minor, frame.stdframe.candata[R_OFF * i],
+		    (TxFifo->data[TxFifo->tail]).data[i]);
+	    }
+        }
+
+        CANout(minor, cancmd, CAN_TRANSMISSION_REQUEST );
+
+	TxFifo->free[TxFifo->tail] = BUF_EMPTY; /* now this entry is EMPTY */
+	TxFifo->tail = ++(TxFifo->tail) % MAX_BUFSIZE;
+
+        /* leave critical section */
+	restore_flags(flags);
+   }
+Tx_done:
+   /*========== error status */
+   if( irqsrc & CAN_ERROR_INT ) {
+   int s;
+	printk("CAN[%d]: Tx err!\n", minor);
+        TxErr[minor]++;
+
+        /* insert error */
+        s = CANin(minor,canstat);
+        if(s & CAN_BUS_STATUS )
+	    (RxFifo->data[RxFifo->head]).flags += MSG_BUSOFF; 
+        if(s & CAN_ERROR_STATUS)
+	    (RxFifo->data[RxFifo->head]).flags += MSG_PASSIVE; 
+
+	(RxFifo->data[RxFifo->head]).id = 0xFFFFFFFF;
+        /* (RxFifo->data[RxFifo->head]).length = 0; */
+	/* (RxFifo->data[RxFifo->head]).data[i] = 0; */
+	RxFifo->status = BUF_OK;
+        RxFifo->head = ++(RxFifo->head) % MAX_BUFSIZE;
+	if(RxFifo->head == RxFifo->tail) {
+		printk("CAN[%d] RX: FIFO overrun\n", minor);
+		RxFifo->status = BUF_OVERRUN;
+        } 
+	
+   }
+   if( irqsrc & CAN_OVERRUN_INT ) {
+   int s;
+	printk("CAN[%d]: overrun!\n", minor);
+        Overrun[minor]++;
+
+        /* insert error */
+        s = CANin(minor,canstat);
+        if(s & CAN_DATA_OVERRUN)
+	    (RxFifo->data[RxFifo->head]).flags += MSG_OVR; 
+
+	(RxFifo->data[RxFifo->head]).id = 0xFFFFFFFF;
+        /* (RxFifo->data[RxFifo->head]).length = 0; */
+	/* (RxFifo->data[RxFifo->head]).data[i] = 0; */
+	RxFifo->status = BUF_OK;
+        RxFifo->head = ++(RxFifo->head) % MAX_BUFSIZE;
+	if(RxFifo->head == RxFifo->tail) {
+		printk("CAN[%d] RX: FIFO overrun\n", minor);
+		RxFifo->status = BUF_OVERRUN;
+        } 
+
+        CANout(minor, cancmd, CAN_CLEAR_OVERRUN_STATUS );
+   } 
+   } while( (irqsrc = CANin(minor, canirq)) != 0);
+
+/* IRQdone: */
+    DBGprint(DBG_DATA, (" => leave IRQ[%d]\n", minor));
+#ifdef CAN4LINUX_PCI
+    /* Interrupt_0_Enable (bit 17) + Int_0_Reset (bit 1) */
+    /*  
+     Uttenthaler:
+      nur 
+        writel(0x00020002, Can_pitapci_control[minor] + 0x0);
+      als letzte Anweisung in der ISR
+     Schött:
+      bei Eintritt
+        writel(0x00000000, Can_pitapci_control[minor] + 0x0);
+      am ende
+        writel(0x00020002, Can_pitapci_control[minor] + 0x0);
+    */
+    writel(0x00020002, Can_pitapci_control[minor] + 0x0);
+    writel(0x00020000, Can_pitapci_control[minor] + 0x0);
+#endif
+IRQdone_doneNothing:
+#if CONFIG_TIME_MEASURE
+    outb(0x00, 0x378);  
+#endif
+}
+
+
diff -urN linux-2.4.29/drivers/char/can4linux/can_sja1000.h linux-2.4.29-uc1/drivers/char/can4linux/can_sja1000.h
--- linux-2.4.29/drivers/char/can4linux/can_sja1000.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_sja1000.h	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,405 @@
+/*
+ * can_sja1000.h - can4linux CAN driver module
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001 port GmbH Halle/Saale
+ *------------------------------------------------------------------
+ * $Header: /var/cvs/uClinux-2.4.x/drivers/char/can4linux/can_sja1000.h,v 1.1 2003/07/18 00:11:46 gerg Exp $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: can_sja1000.h,v $
+ * Revision 1.1  2003/07/18 00:11:46  gerg
+ * I followed as much rules as possible (I hope) and generated a patch for the
+ * uClinux distribution. It contains an additional driver, the CAN driver, first
+ * for an SJA1000 CAN controller:
+ *   uClinux-dist/linux-2.4.x/drivers/char/can4linux
+ * In the "user" section two entries
+ *   uClinux-dist/user/can4linux     some very simple test examples
+ *   uClinux-dist/user/horch         more sophisticated CAN analyzer example
+ *
+ * Patch submitted by Heinz-Juergen Oertel <oe@port.de>.
+ *
+ *
+ *
+ *
+ *--------------------------------------------------------------------------
+ */
+
+
+/* typedef unsigned char uint8; */
+
+extern u8 CanTiming[10][2];
+
+/*----------*/
+
+#define CAN_PELICANMODE
+#ifdef  CAN_PELICANMODE
+
+
+#ifdef CAN4LINUX_PCI
+
+/* Definition with offset 4, EMS CPC-PCI */
+union frame {
+	struct {
+	    u8	 canid1;
+	    u8	 			dummy01;
+	    u8	 			dummy02;
+	    u8	 			dummy03;
+	    u8	 canid2;
+	    u8	 			dummy04;
+	    u8	 			dummy05;
+	    u8	 			dummy06;
+	    u8	 canid3;
+	    u8	 			dummy07;
+	    u8	 			dummy08;
+	    u8	 			dummy09;
+	    u8	 canid4;
+	    u8	 			dummy10;
+	    u8	 			dummy11;
+	    u8	 			dummy12;
+	    /* !! use offset 4 !! */
+	    u8    canxdata[8*4];
+
+	} extframe;
+	struct {
+	    u8	 canid1;
+	    u8	 			dummy01;
+	    u8	 			dummy02;
+	    u8	 			dummy03;
+	    u8	 canid2;
+	    u8	 			dummy04;
+	    u8	 			dummy05;
+	    u8	 			dummy06;
+	    /* !! use offset 4 !! */
+	    u8    candata[8*4];
+	} stdframe;
+};
+
+typedef struct canregs {
+	u8    canmode;		/* 0 */
+	u8	 			dummy01;
+	u8	 			dummy02;
+	u8	 			dummy03;
+	u8    cancmd;
+	u8	 			dummy04;
+	u8	 			dummy05;
+	u8	 			dummy06;
+	u8    canstat;
+	u8	 			dummy07;
+	u8	 			dummy08;
+	u8	 			dummy09;
+	u8	 canirq;
+	u8	 			dummy10;
+	u8	 			dummy11;
+	u8	 			dummy12;
+	u8	 canirq_enable;
+	u8	 			dummy13;
+	u8	 			dummy14;
+	u8	 			dummy15;
+	u8	 reserved1;		/* 5 */
+	u8	 			dummy16;
+	u8	 			dummy17;
+	u8	 			dummy18;
+	u8	 cantim0;
+	u8	 			dummy19;
+	u8	 			dummy20;
+	u8	 			dummy21;
+	u8	 cantim1;
+	u8	 			dummy22;
+	u8	 			dummy23;
+	u8	 			dummy24;
+	u8	 canoutc;
+	u8	 			dummy25;
+	u8	 			dummy26;
+	u8	 			dummy27;
+	u8	 cantest;
+	u8	 			dummy28;
+	u8	 			dummy29;
+	u8	 			dummy30;
+	u8	 reserved2;		/* 10 */
+	u8	 			dummy31;
+	u8	 			dummy32;
+	u8	 			dummy33;
+	u8	 arbitrationlost;	/* read only */
+	u8	 			dummy34;
+	u8	 			dummy35;
+	u8	 			dummy36;
+	u8	 errorcode;		/* read only */
+	u8	 			dummy37;
+	u8	 			dummy38;
+	u8	 			dummy39;
+	u8	 errorwarninglimit;
+	u8	 			dummy40;
+	u8	 			dummy41;
+	u8	 			dummy42;
+	u8	 rxerror;
+	u8	 			dummy43;
+	u8	 			dummy44;
+	u8	 			dummy45;
+	u8	 txerror;		/* 15 */
+	u8	 			dummy46;
+	u8	 			dummy47;
+	u8	 			dummy48;
+	u8	 frameinfo;
+	u8	 			dummy49;
+	u8	 			dummy50;
+	u8	 			dummy51;
+	union    frame frame;
+	u8	 reserved3;
+	u8	 			dummy52;
+	u8	 			dummy53;
+	u8	 			dummy54;
+	u8	 canrxbufferadr		/* 30 */;
+	u8	 			dummy55;
+	u8	 			dummy56;
+	u8	 			dummy57;
+	u8	 canclk; 	 
+	u8	 			dummy58;
+	u8	 			dummy59;
+	u8	 			dummy60;
+} canregs_t;
+
+#else
+
+/* Standard definition with offset 1 */
+union frame {
+	struct {
+	    u8	 canid1;
+	    u8	 canid2;
+	    u8	 canid3;
+	    u8	 canid4;
+	    u8    canxdata[8];
+	} extframe;
+	struct {
+	    u8	 canid1;
+	    u8	 canid2;
+	    u8    candata[8];
+	} stdframe;
+};
+
+typedef struct canregs {
+	u8    canmode;		/* 0 */
+	u8    cancmd;
+	u8    canstat;
+	u8	 canirq;
+	u8	 canirq_enable;
+	u8	 reserved1;		/* 5 */
+	u8	 cantim0;
+	u8	 cantim1;
+	u8	 canoutc;
+	u8	 cantest;
+	u8	 reserved2;		/* 10 */
+	u8	 arbitrationlost;	/* read only */
+	u8	 errorcode;		/* read only */
+	u8	 errorwarninglimit;
+	u8	 rxerror;
+	u8	 txerror;		/* 15 */
+	u8	 frameinfo;
+	union    frame frame;
+	u8	 reserved3;
+	u8	 canrxbufferadr		/* 30 */;
+	u8	 canclk; 	 
+} canregs_t;
+#endif
+
+#else
+typedef struct canregs {
+	u8    canctl;
+	u8    cancmd;
+	u8    canstat;
+	u8	 canirq;
+	u8	 canacc;
+	u8	 canmask;
+	u8	 cantim0;
+	u8	 cantim1;
+	u8	 canoutc;
+	u8	 cantest;
+	u8	 cantxdes1;
+	u8	 cantxdes2;
+	u8    cantxdata[8];
+	u8	 canrxdes1;
+	u8    canrxdes2;
+	u8    canrxdata[8];
+	u8    unused;
+	u8	 canclk; 	 
+} canregs_t;
+#endif
+
+#define CAN_RANGE 0x20
+
+#ifdef CAN_PELICANMODE
+/*--- Mode Register -------- PeliCAN -------------------*/
+
+#  define CAN_SLEEP_MODE		0x10    /* Sleep Mode */
+#  define CAN_ACC_FILT_MASK		0x08    /* Acceptance Filter Mask */
+#  define CAN_SELF_TEST_MODE		0x04    /* Self test mode */
+#  define CAN_LISTEN_ONLY_MODE		0x02    /* Listen only mode */
+#  define CAN_RESET_REQUEST		0x01	/* reset mode */
+#  define CAN_MODE_DEF CAN_ACC_FILT_MASK	 /* Default ModeRegister Value*/
+
+   /* bit numbers of mode register */
+#  define CAN_SLEEP_MODE_BIT		4	/* Sleep Mode */
+#  define CAN_ACC_FILT_MASK_BIT		3	/* Acceptance Filter Mask */
+#  define CAN_SELF_TEST_MODE_BIT	2	/* Self test mode */
+#  define CAN_LISTEN_ONLY_MODE_BIT	1	/* Listen only mode */
+#  define CAN_RESET_REQUEST_BIT		0	/* reset mode */
+
+
+/*--- Interrupt enable Reg -----------------------------*/
+#define CAN_ERROR_BUSOFF_INT_ENABLE		(1<<7)
+#define CAN_ARBITR_LOST_INT_ENABLE		(1<<6)
+#define CAN_ERROR_PASSIVE_INT_ENABLE		(1<<5)
+#define CAN_WAKEUP_INT_ENABLE			(1<<4)
+#define CAN_OVERRUN_INT_ENABLE			(1<<3)
+#define CAN_ERROR_INT_ENABLE			(1<<2)
+#define CAN_TRANSMIT_INT_ENABLE			(1<<1)
+#define CAN_RECEIVE_INT_ENABLE			(1<<0)
+
+/*--- Frame information register -----------------------*/
+#define CAN_EFF				0x80	/* extended frame */
+#define CAN_SFF				0x00	/* standard fame format */
+
+
+#else
+/*--- Control Register ----- Basic CAN -----------------*/
+ 
+#define CAN_TEST_MODE				(1<<7)
+#define CAN_SPEED_MODE				(1<<6)
+#define CAN_OVERRUN_INT_ENABLE			(1<<4)
+#define CAN_ERROR_INT_ENABLE			(1<<3)
+#define CAN_TRANSMIT_INT_ENABLE			(1<<2)
+#define CAN_RECEIVE_INT_ENABLE			(1<<1)
+#define CAN_RESET_REQUEST			(1<<0)
+#endif
+
+/*--- Command Register ------------------------------------*/
+ 
+#define CAN_GOTO_SLEEP				(1<<4)
+#define CAN_CLEAR_OVERRUN_STATUS		(1<<3)
+#define CAN_RELEASE_RECEIVE_BUFFER		(1<<2)
+#define CAN_ABORT_TRANSMISSION			(1<<1)
+#define CAN_TRANSMISSION_REQUEST		(1<<0)
+
+/*--- Status Register --------------------------------*/
+ 
+#define CAN_BUS_STATUS 				(1<<7)
+#define CAN_ERROR_STATUS			(1<<6)
+#define CAN_TRANSMIT_STATUS			(1<<5)
+#define CAN_RECEIVE_STATUS			(1<<4)
+#define CAN_TRANSMISSION_COMPLETE_STATUS	(1<<3)
+#define CAN_TRANSMIT_BUFFER_ACCESS		(1<<2)
+#define CAN_DATA_OVERRUN			(1<<1)
+#define CAN_RECEIVE_BUFFER_STATUS		(1<<0)
+
+/*--- Status Register --------------------------------*/
+ 
+#define CAN_BUS_STATUS_BIT 			(1<<7)
+#define CAN_ERROR_STATUS_BIT			(1<<6)
+#define CAN_TRANSMIT_STATUS_BIT			(1<<5)
+#define CAN_RECEIVE_STATUS_BIT			(1<<4)
+#define CAN_TRANSMISSION_COMPLETE_STATUS_BIT	(1<<3)
+#define CAN_TRANSMIT_BUFFER_ACCESS_BIT		(1<<2)
+#define CAN_DATA_OVERRUN_BIT			(1<<1)
+#define CAN_RECEIVE_BUFFER_STATUS_BIT		(1<<0)
+
+/*--- Interrupt Register -----------------------------------*/
+ 
+#define CAN_WAKEUP_INT				(1<<4)
+#define CAN_OVERRUN_INT				(1<<3)
+#define CAN_ERROR_INT				(1<<2)
+#define CAN_TRANSMIT_INT			(1<<1)
+#define CAN_RECEIVE_INT 			(1<<0)
+
+/*--- Output Control Register -----------------------------------------*/
+/*
+ *	7	6	5	4	3	2	1	0
+ * 	OCTP1	OCTN1	OCPOL1	OCTP0	OCTN0	OCPOL0	OCMODE1	OCMODE0
+ *	----------------------  ----------------------  ---------------
+ *	    TX1 Output		    TX0 Output		  programmable
+ *	  Driver Control	  Driver Control	  output functions
+ *
+ *	MODE
+ *	OCMODE1	OCMODE0
+ *	  0	  1	Normal Mode; TX0, TX1 bit sequenze TXData
+ *	  1	  1	Normal Mode; TX0 bit sequenze, TX1 busclock TXCLK
+ *	  0	  0	Biphase Mode
+ *	  1	  0	Test Mode; TX0 bit sequenze, TX1 COMPOUT
+ *
+ *	In normal Mode Voltage Output Levels depend on 
+ *	Driver Characteristic: OCTPx, OCTNx
+ *	and programmed Output Polarity: OCPOLx
+ *
+ *	Driver Characteristic
+ *	OCTPx	OCTNx
+ *	  0	 0	always Floating Outputs,
+ *	  0	 1	Pull Down
+ *	  1	 0	Pull Up
+ *	  1	 1	Push Pull
+ */
+ 
+/*--- Output control register --------------------------------*/
+
+#define CAN_OCTP1			(1<<7)
+#define CAN_OCTN1			(1<<6)
+#define CAN_OCPOL1			(1<<5)
+#define CAN_OCTP0			(1<<4)
+#define CAN_OCTN0			(1<<3)
+#define CAN_OCPOL0			(1<<2)
+#define CAN_OCMODE1			(1<<1)
+#define CAN_OCMODE0			(1<<0)
+
+/*--- Clock Divider register ---------------------------------*/
+
+#define CAN_MODE_BASICCAN		(0x00)
+#define CAN_MODE_PELICAN		(0xC0)
+#define CAN_MODE_CLK			(0x07)		/* CLK-out = Fclk   */
+#define CAN_MODE_CLK2			(0x00)		/* CLK-out = Fclk/2 */
+
+
+/*--- Remote Request ---------------------------------*/
+/*    Notes:
+ *    Basic CAN: RTR is Bit 4 in TXDES1.
+ *    Peli  CAN: RTR is Bit 6 in frameinfo.
+ */
+#ifdef CAN_PELICANMODE
+# define CAN_RTR				(1<<6)
+#else
+# define CAN_RTR				(1<<4)
+#endif
+
+
+/* the base address register array */
+extern unsigned int Base[];
+/*---------- Timing values */
+
+/* the timings are valid for clock 8Mhz */
+#define CAN_TIM0_10K		  49
+#define CAN_TIM1_10K		0x1c
+#define CAN_TIM0_20K		  24	
+#define CAN_TIM1_20K		0x1c
+#define CAN_TIM0_40K		0x89	/* Old Bit Timing Standard of port */
+#define CAN_TIM1_40K		0xEB	/* Old Bit Timing Standard of port */
+#define CAN_TIM0_50K		   9
+#define CAN_TIM1_50K		0x1c
+#define CAN_TIM0_100K              4    /* sp 87%, 16 abtastungen, sjw 1 */
+#define CAN_TIM1_100K           0x1c
+#define CAN_TIM0_125K		   3
+#define CAN_TIM1_125K		0x1c
+#define CAN_TIM0_250K		   1
+#define CAN_TIM1_250K		0x1c
+#define CAN_TIM0_500K		   0
+#define CAN_TIM1_500K		0x1c
+#define CAN_TIM0_800K		   0
+#define CAN_TIM1_800K		0x16
+#define CAN_TIM0_1000K		   0
+#define CAN_TIM1_1000K		0x14
+
+
+
diff -urN linux-2.4.29/drivers/char/can4linux/can_sysctl.c linux-2.4.29-uc1/drivers/char/can4linux/can_sysctl.c
--- linux-2.4.29/drivers/char/can4linux/can_sysctl.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_sysctl.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,396 @@
+/* can_sysctl
+*
+* can4linux -- LINUX CAN device driver source
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * 
+ * Copyright (c) 2001 port GmbH Halle/Saale
+ * (c) 2001 Heinz-Jürgen Oertel (oe@port.de)
+ *          Claus Schroeter (clausi@chemie.fu-berlin.de)
+ *------------------------------------------------------------------
+ * $Header: $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: can_sysctl.c,v $
+ *
+ *
+ */
+/*
+ * This Template implements the SYSCTL basics, and handler/strategy routines
+ * Users may implement own routines and hook them up with the 'handler'		
+ * and 'strategy' methods of sysctl.
+ * 
+ *
+ */
+#include "can_defs.h"
+#include <linux/mm.h>
+#include <linux/sysctl.h>
+#include <linux/ctype.h>
+/* #include <can_sysctl.h> */
+
+
+
+/* #if LINUX_VERSION_CODE >= 131587 */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 3)
+/* on 2.2 kernels replace default functions with the generic ones */
+
+#define Can_dointvec proc_dointvec
+#define Can_dostring proc_dostring
+#define Can_sysctl_string sysctl_string
+
+#endif
+
+
+
+
+
+#define SYSCTL_Can 1
+
+/* ----- Prototypes */
+
+extern int Can_dointvec(ctl_table *table, int write, struct file *filp,
+		  void *buffer, size_t *lenp);
+
+extern int Can_dostring(ctl_table *table, int write, struct file *filp,
+		  void *buffer, size_t *lenp);
+
+
+extern int Can_sysctl_string(ctl_table *table, int *name, int nlen,
+		  void *oldval, size_t *oldlenp,
+		  void *newval, size_t newlen, void **context);
+
+
+/* ----- global variables accessible through /proc/sys/Can */
+
+char version[] = VERSION;
+char IOModel[MAX_CHANNELS];
+char Chipset[] =
+#if defined(ATCANMINI_PELICAN)
+	"SJA1000"
+#elif defined(CPC_PCI)
+	"SJA1000"
+#elif defined(IME_SLIMLINE)
+	"SJA1000"
+#elif defined(PCM3680)
+	"SJA1000"
+#elif defined(IXXAT_PCI03)
+	"SJA1000"
+#elif defined(CCPC104)
+	"SJA1000"
+#elif defined(MCF5282)
+	"FlexCAN"
+#else
+	""
+#endif
+;
+
+int IRQ[MAX_CHANNELS] = { 0x0 };
+/* dont assume a standard address, always configure,
+ * address == 0 means no board available */
+unsigned int Base[MAX_CHANNELS] = { 0x0 };
+unsigned int AccCode[MAX_CHANNELS];
+unsigned int AccMask[MAX_CHANNELS];
+int Baud[MAX_CHANNELS];
+int Timeout[MAX_CHANNELS];
+/* predefined value of the output control register,
+* depends of TARGET set by Makefile */
+int Outc[MAX_CHANNELS]	  = { 0x0 };
+int TxErr[MAX_CHANNELS]   = { 0x0 };
+int RxErr[MAX_CHANNELS]   = { 0x0 };
+int Overrun[MAX_CHANNELS] = { 0x0 };
+
+#ifdef DEBUG_COUNTER
+int Cnt1[MAX_CHANNELS]    = { 0x0 };
+int Cnt2[MAX_CHANNELS]    = { 0x0 };
+#endif /* DEBUG_COUNTER */
+
+/* ----- the sysctl table */
+
+ctl_table Can_sysctl_table[] = {
+ { SYSCTL_VERSION, "version", &version, PROC_VER_LENGTH, 
+		 0444, NULL, &Can_dostring , &Can_sysctl_string },
+ { SYSCTL_CHIPSET, "Chipset", &Chipset, PROC_CHIPSET_LENGTH, 
+		 0444, NULL, &Can_dostring , &Can_sysctl_string },
+ { SYSCTL_IOMODEL, "IOModel", &IOModel, MAX_CHANNELS + 1, 
+		 0444, NULL, &Can_dostring , &Can_sysctl_string },
+ { SYSCTL_IRQ, "IRQ",(void *) IRQ, MAX_CHANNELS*sizeof(int), 
+		 0644, NULL, &Can_dointvec , NULL  },
+ { SYSCTL_BASE, "Base",(void *) Base, MAX_CHANNELS*sizeof(int), 
+		 0644, NULL, &Can_dointvec , NULL  },
+ { SYSCTL_BAUD, "Baud",(void *) Baud, MAX_CHANNELS*sizeof(int), 
+		 0666, NULL, &Can_dointvec , NULL  },
+ { SYSCTL_ACCCODE, "AccCode",(void *) AccCode, MAX_CHANNELS*sizeof(unsigned int), 
+		 0644, NULL, &Can_dointvec , NULL  },
+ { SYSCTL_ACCMASK, "AccMask",(void *) AccMask, MAX_CHANNELS*sizeof(unsigned int), 
+		 0644, NULL, &Can_dointvec , NULL  },
+ { SYSCTL_TIMEOUT, "Timeout",(void *) Timeout, MAX_CHANNELS*sizeof(int), 
+		 0644, NULL, &Can_dointvec , NULL  },
+ { SYSCTL_OUTC, "Outc",(void *) Outc, MAX_CHANNELS*sizeof(int), 
+		 0644, NULL, &Can_dointvec , NULL  },
+ { SYSCTL_TXERR, "TxErr",(void *) TxErr, MAX_CHANNELS*sizeof(int), 
+		 0444, NULL, &Can_dointvec , NULL  },
+ { SYSCTL_RXERR, "RxErr",(void *) RxErr, MAX_CHANNELS*sizeof(int), 
+		 0444, NULL, &Can_dointvec , NULL  },
+ { SYSCTL_OVERRUN, "Overrun",(void *) Overrun, MAX_CHANNELS*sizeof(int), 
+		 0444, NULL, &Can_dointvec , NULL  },
+ { SYSCTL_DBGMASK, "dbgMask",(void *) &dbgMask, 1*sizeof(int), 
+		 0644, NULL, &Can_dointvec , NULL  },
+#ifdef DEBUG_COUNTER
+/* ---------------------------------------------------------------------- */
+ { SYSCTL_CNT1, "cnt1",(void *) Cnt1, MAX_CHANNELS*sizeof(int), 
+		 0444, NULL, &Can_dointvec , NULL  },
+ { SYSCTL_CNT2, "cnt2",(void *) Cnt2, MAX_CHANNELS*sizeof(int), 
+		 0444, NULL, &Can_dointvec , NULL  },
+/* ---------------------------------------------------------------------- */
+#endif /* DEBUG_COUNTER */
+   {0}
+};
+
+/* ----- the main directory entry in /proc/sys */
+
+ctl_table Can_sys_table[] = {
+	    {SYSCTL_Can, "Can", NULL, 0, 0555, 
+                 Can_sysctl_table},	
+	    {0}	
+};
+
+/* ----- register and unregister entrys */
+
+struct ctl_table_header *Can_systable;
+
+void register_systables(void)
+{
+    Can_systable = register_sysctl_table( Can_sys_table, 0 );
+}
+
+void unregister_systables(void)
+{
+    unregister_sysctl_table(Can_systable);
+}
+
+
+
+
+
+
+#if LINUX_VERSION_CODE < 131587
+
+
+/* ----- default proc handlers */
+
+
+int Can_dointvec(ctl_table *table, int write, struct file *filp,
+		  void *buffer, size_t *lenp)
+ {
+int *i, vleft, first=1, len, left, neg, val;
+#define TMPBUFLEN 20
+char buf[TMPBUFLEN], *p;
+	
+    if (!table->data || !table->maxlen || !*lenp ||
+	(filp->f_pos && !write)) {
+	    *lenp = 0;
+	    return 0;
+    }
+    
+    i = (int *) table->data;
+    vleft = table->maxlen / sizeof(int);
+    left = *lenp;
+    
+    for (; left && vleft--; i++, first=0) {
+	if (write) {
+	    while (left && isspace( get_user((char *) buffer))) {
+		left--, ((char *) buffer)++;
+	    }
+	    if (!left) {
+		break;
+	    }
+	    neg = 0;
+	    len = left;
+	    if (len > TMPBUFLEN-1) {
+		len = TMPBUFLEN-1;
+	    }
+
+#if LINUX_VERSION_CODE > 0x20100
+	    memcpy_fromio(buf, buffer, len);
+#else
+	    memcpy_fromfs(buf, buffer, len);
+#endif
+
+	    buf[len] = 0;
+	    p = buf;
+	    if (*p == '-' && left > 1) {
+		neg = 1;
+		left--, p++;
+	    }
+	    if (*p < '0' || *p > '9') {
+		break;
+	    }
+	    val = simple_strtoul(p, &p, 0);
+	    len = p-buf;
+	    if ((len < left) && *p && !isspace(*p)) {
+		break;
+	    }
+	    if (neg) {
+		val = -val;
+	    }
+	    buffer += len;
+	    left -= len;
+	    *i = val;
+	} else {
+	    p = buf;
+	    if (!first) {
+		*p++ = '\t';
+	    }
+	    sprintf(p, "%d", *i);
+	    len = strlen(buf);
+	    if (len > left)
+		    len = left;
+#if LINUX_VERSION_CODE > 0x20100
+	    memcpy_toio(buffer, buf, len);
+#else
+	    memcpy_tofs(buffer, buf, len);
+#endif
+	    left -= len;
+	    buffer += len;
+	}
+    }
+
+    if (!write && !first && left) {
+	put_user('\n', (char *) buffer);
+	left--, buffer++;
+    }
+    if (write) {
+	p = (char *) buffer;
+	while (left && isspace(get_user(p++))) {
+	    left--;
+	}
+    }
+    if (write && first) {
+	return -EINVAL;
+    }
+    *lenp -= left;
+    filp->f_pos += *lenp;
+    return 0;
+}
+
+
+int Can_dostring(ctl_table *table, int write, struct file *filp,
+		  void *buffer, size_t *lenp)
+{
+int len;
+char *p, c;
+    
+    if (!table->data || !table->maxlen || !*lenp ||
+	(filp->f_pos && !write)) {
+	    *lenp = 0;
+	    return 0;
+    }
+    
+    if (write) {
+	    len = 0;
+	    p = buffer;
+	    while (len < *lenp && (c = get_user(p++)) != 0 && c != '\n') {
+		len++;
+	    }
+	    if (len >= table->maxlen) {
+		len = table->maxlen-1;
+	    }
+
+#if LINUX_VERSION_CODE > 0x20100
+	    memcpy_fromio(table->data, buffer, len);
+#else
+	    memcpy_fromfs(table->data, buffer, len);
+#endif
+
+	    ((char *) table->data)[len] = 0;
+	    filp->f_pos += *lenp;
+    } else {
+	    len = strlen(table->data);
+	    if (len > table->maxlen) {
+		len = table->maxlen;
+	    }
+	    if (len > *lenp) {
+		len = *lenp;
+	    }
+	    if (len) {
+#if LINUX_VERSION_CODE > 0x20100
+		memcpy_toio(buffer, table->data, len);
+#else
+		memcpy_tofs(buffer, table->data, len);
+#endif
+	    }
+	    if (len < *lenp) {
+		    put_user('\n', ((char *) buffer) + len);
+		    len++;
+	    }
+	    *lenp = len;
+	    filp->f_pos += len;
+    }
+    return 0;
+}
+
+
+/* ----- strategy handlers */
+
+int Can_sysctl_string(ctl_table *table, int *name, int nlen,
+		  void *oldval, size_t *oldlenp,
+		  void *newval, size_t newlen, void **context)
+{
+int l, len;
+    
+    if (!table->data || !table->maxlen) 
+	    return -ENOTDIR;
+    
+    if (oldval && oldlenp && get_user(oldlenp)) {
+	    len = get_user(oldlenp);
+	    l = strlen(table->data);
+	    if (len > l) len = l;
+	    if (len >= table->maxlen)
+		    len = table->maxlen;
+#if LINUX_VERSION_CODE > 0x20100
+	    memcpy_toio(oldval, table->data, len);
+#else
+	    memcpy_tofs(oldval, table->data, len);
+#endif
+
+
+	    put_user(0, ((char *) oldval) + len);
+	    put_user(len, oldlenp);
+    }
+    if (newval && newlen) {
+	    len = newlen;
+	    if (len > table->maxlen)
+		    len = table->maxlen;
+
+#if LINUX_VERSION_CODE > 0x20100
+	    memcpy_fromio(table->data, newval, len);
+#else
+	    memcpy_fromfs(table->data, newval, len);
+#endif
+
+	    if (len == table->maxlen)
+		    len--;
+	    ((char *) table->data)[len] = 0;
+    }
+    return 0;
+}
+
+#endif /*version*/
+
+
+
+
+
+
+
+
+
+
+
diff -urN linux-2.4.29/drivers/char/can4linux/can_util.c linux-2.4.29-uc1/drivers/char/can4linux/can_util.c
--- linux-2.4.29/drivers/char/can4linux/can_util.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_util.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,761 @@
+/*
+ * can4linux -- LINUX CAN device driver source
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * 
+ * derived from the the LDDK can4linux version
+ *     (c) 1996,1997 Claus Schroeter (clausi@chemie.fu-berlin.de)
+ *
+ *------------------------------------------------------------------
+ * $Header: /var/cvs/uClinux-2.4.x/drivers/char/can4linux/can_util.c,v 1.1 2003/07/18 00:11:46 gerg Exp $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: can_util.c,v $
+ * Revision 1.1  2003/07/18 00:11:46  gerg
+ * I followed as much rules as possible (I hope) and generated a patch for the
+ * uClinux distribution. It contains an additional driver, the CAN driver, first
+ * for an SJA1000 CAN controller:
+ *   uClinux-dist/linux-2.4.x/drivers/char/can4linux
+ * In the "user" section two entries
+ *   uClinux-dist/user/can4linux     some very simple test examples
+ *   uClinux-dist/user/horch         more sophisticated CAN analyzer example
+ *
+ * Patch submitted by Heinz-Juergen Oertel <oe@port.de>.
+ *
+ *
+ *
+ */
+
+
+#include "can_defs.h"
+#include <linux/sched.h> 
+#include <linux/proc_fs.h>
+#include <linux/pci.h>
+
+/*
+ * Refuse to compile under versions older than 1.99.4
+ */
+#define VERSION_CODE(vers,rel,seq) ( ((vers)<<16) | ((rel)<<8) | (seq) )
+#if LINUX_VERSION_CODE < VERSION_CODE(1,99,4)
+#  error "This module needs Linux 1.99.4 or newer"
+#endif
+
+ volatile int irq2minormap[15];
+ volatile int irq2pidmap[15];
+
+ /* each CAN channel has one wait_queue for read() */
+ /* #define wait_queue_head_t     struct wait_queue * */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1)
+ wait_queue_head_t CanWait[MAX_CHANNELS];
+ /* wait_queue_head_t *CanWait[MAX_CHANNELS]; */
+#else
+ struct wait_queue *CanWait[MAX_CHANNELS];
+#endif
+
+
+
+msg_fifo_t   Tx_Buf[MAX_CHANNELS];
+msg_fifo_t   Rx_Buf[MAX_CHANNELS];
+#ifdef CAN_USE_FILTER
+    msg_filter_t Rx_Filter[MAX_CHANNELS]; 
+#endif
+
+unsigned char *can_base[MAX_CHANNELS];		/* ioremapped adresses */
+unsigned int can_range[MAX_CHANNELS];		/* ioremapped adresses */
+
+#if defined(MCF5282)
+	/* Motorola ColdFire Board FlexCAN */
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+/* enabel the interrupts at the interrupt controller
+ used:
+  - receivebuffer 1
+
+*/
+void mcf_irqsetup(void)
+{
+volatile unsigned char *icrp;	/* interrupt control register pointer */
+volatile unsigned long *imrp;	/* interrupt mask register pointer    */
+
+    /* Initialize FlexCAN interrupt handler
+      - Initialize the interrupt configurataion register (CANICR with
+        a specific request level and vector base address
+      - Initialize IARB[3:0] to a non zero value in CANMCR
+        ( This is done in CAN-ChipReset() )
+      - Set the required mask bits in the IMASK register (for all message
+        buffer interrupts) in CANCTRL0 for bus off and error interrupts,
+        and in CANMCR for WAKE interrupt.
+        (happens in CAN-ChipReset() too)
+
+	MCF5282 has two interrupt controllers, FlexCAN interrupts are
+	scheduled to INTC1 (the second one, with lower priority)
+	Int source nr  -- Source --                    vector
+	 8             -- message buffer 0             136
+	   ...
+	23             -- message buffer 15            151
+	24             -- Error Int                    152
+	25             -- Bus-Off Ont                  153
+	26             -- Wake-Up Int                  154
+
+
+       Interrupt Vector number is vector_number = 128 + interrupt source number
+       (for INTC1)                    
+       vector_number = 137 (receive object == MB 1) 
+
+     */
+    icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC1 + 
+	    MCFINTC_ICR0 + MCFINT_CAN_BUF00 );
+    *icrp = 0x33; /* CANx with level 6, priority 3 */
+printk("icrp %p = 0x%08x\n", icrp, *icrp);
+
+    icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC1 + 
+	    MCFINTC_ICR0 + MCFINT_CAN_BUF01 );
+    *icrp = 0x33; /* CANx with level 6, priority 3 */
+printk("icrp %p = 0x%08x\n", icrp, *icrp);
+    
+    icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC1 + 
+	    MCFINTC_ICR0 + MCFINT_CAN_WARN );
+    *icrp = 0x33; /* CANx with level 6, priority 3 */
+printk("icrp %p = 0x%08x\n", icrp, *icrp);
+
+    icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC1 + 
+	    MCFINTC_ICR0 + MCFINT_CAN_BUSOFF );
+    *icrp = 0x33; /* CANx with level 6, priority 3 */
+printk("icrp %p = 0x%08x\n", icrp, *icrp);
+
+    /* Mask register auch setzen
+    The IMRHn and IMRLn registers are each 32 bits in size and provide a
+    bit map for each interrupt to allow the request to be disabled (1 =
+    disable the request, 0 = enable the request).  The IMRn is set to all
+    ones by reset, disabling all interrupt requests. The IMRn can be read
+    and written. A write that sets bit 0 of the IMR forces the other 63
+    bits to be set, disabling all interrupt sources, and providing a global
+    mask-all capability.
+    */
+    imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC1 +
+		MCFINTC_IMRL);
+    *imrp &= ~(   (1 << (MCFINT_CAN_BUF00 ))
+    	        | (1 << (MCFINT_CAN_BUF01 ))
+    	        | (1 << (MCFINT_CAN_WARN ))
+    	        | 1);
+    /*            ^ unmask all */
+
+printk("imrp %p = 0x%08x\n", imrp, *imrp);
+}
+
+void mcf_irqreset(void)
+{
+volatile unsigned long *imrp;	/* interrupt mask register pointer    */
+
+    /* Mask register auch rücksetzen
+    The IMRHn and IMRLn registers are each 32 bits in size and provide a
+    bit map for each interrupt to allow the request to be disabled (1 =
+    disable the request, 0 = enable the request).  The IMRn is set to all
+    ones by reset, disabling all interrupt requests. The IMRn can be read
+    and written. A write that sets bit 0 of the IMR forces the other 63
+    bits to be set, disabling all interrupt sources, and providing a global
+    mask-all capability.
+    */
+    imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC1 +
+		MCFINTC_IMRL);
+    *imrp |= ((1 << (MCFINT_CAN_BUF00 ))
+    	    | (1 << (MCFINT_CAN_BUF01 )) 
+    	    | (1 << (MCFINT_CAN_WARN ))
+            | 1);
+
+}
+#endif
+
+#if defined(CCPC104)
+	/* Motorola ColdFire Board CTRLink */
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+void pc104_irqsetup(void)
+{
+volatile unsigned long	*icrp;
+
+    /* The PC104 device uses external IRQ3 */
+
+    /* reset all PI (pending Interrupts) to 0, mask IPL priority level 
+     * and add 0d to INT3
+     * each ext int 4 bits 
+     *    _  _  _  _
+     *    PI,..IPL..   0d -->  1 1 0 1 --> PI = 1
+     *                                     PL = 5
+     *        
+     */
+    icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+    *icrp = (*icrp & 0x77077777) | 0x00d00000;
+}
+
+void pc104_irqack(int irq)
+{
+	volatile unsigned long	*icrp;
+	/*
+	Writing a 1 to PI enables the value for the corresponding IPL field to be set.
+	Note: for external interrupts only,
+	writing a one to this bit clears the corresponding interrupt latch.
+	The external interrupt must be toggled before another interrupt is latched.
+	*/
+	/* The PC104 device uses external IRQ3 */
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x77777777) | 0x00800000;
+}
+
+#endif
+
+
+
+
+int Can_RequestIrq(int minor, int irq, irqservice_t handler)
+{
+int err=0;
+
+    DBGin("Can_RequestIrq");
+    /*
+
+    int request_irq(unsigned int irq,			// interrupt number  
+              void (*handler)(int, void *, struct pt_regs *), // pointer to ISR
+		              irq, dev_id, registers on stack
+              unsigned long irqflags, const char *devname,
+              void *dev_id);
+
+       dev_id - The device ID of this handler (see below).       
+       This parameter is usually set to NULL,
+       but should be non-null if you wish to do  IRQ  sharing.
+       This  doesn't  matter when hooking the
+       interrupt, but is required so  that,  when  free_irq()  is
+       called,  the  correct driver is unhooked.  Since this is a
+       void *, it can point to anything (such  as  a  device-spe­
+       cific  structure,  or even empty space), but make sure you
+       pass the same pointer to free_irq().
+
+    */
+
+#if defined(CONFIG_PPC)
+    /* LINUX_PPC */
+    err = request_8xxirq( irq, handler, 0, "Can", NULL );
+#elif defined(MCF5282)
+    {
+    int i;
+    	/* 19 Int vectors are used on Interrupt Controller 1 */
+	for( i = 136; i < 155; i++) {
+	    err = request_irq( i, handler, SA_SHIRQ, "Can", &Can_minors[minor]);
+	    if(err) {
+    		DBGout();return err;
+	    }
+	}
+    }
+#else 
+    err = request_irq( irq, handler, SA_SHIRQ, "Can", &Can_minors[minor]);
+#endif
+    if( !err ){
+	/* printk("Requested IRQ[%d]: %d @ 0x%x", minor, irq, handler); */
+
+/* Now the kernel has assigned a service to the Interruptvector,
+   time to enable the hardware to genearte an ISR.
+
+   here should be used a generic function e.g. can_irqsetup(minor)
+   and do whatever needed for the app. hardware
+   to reduce #ifdef clutter
+   */
+#if defined(CCPC104)
+	pc104_irqsetup();
+#endif
+#if defined(MCF5282)
+	mcf_irqsetup();
+#endif
+
+	irq2minormap[irq] = minor;
+
+	irq2pidmap[irq] = current->pid;
+	DBGprint(DBG_BRANCH,("Requested IRQ: %d @ 0x%lx",
+				irq, (unsigned long)handler));
+	IRQ_requested[minor] = 1;
+    }
+    DBGout();return err;
+}
+
+int Can_FreeIrq(int minor, int irq )
+{
+    DBGin("Can_FreeIrq");
+    IRQ_requested[minor] = 0;
+
+#if defined(MCF5282)
+    /* reset interrupt masks */
+    mcf_irqreset();
+#endif
+#if defined(MCF5282)
+    {
+    int i;
+    	/* 19 Int vectors are used on Interrupt Controller 1 */
+	for(i = 136; i < 155; i++) {
+	    free_irq(i, &Can_minors[minor]);
+	}
+    }
+#else 
+    /* release the vector from the kernel */
+    free_irq(irq, &Can_minors[minor]);
+#endif
+
+    DBGout();
+    return 0;
+}
+
+int Can_WaitInit(int minor)
+{
+    DBGin("Can_WaitInit");
+	/* reset the wait_queue pointer */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+/* soll so sein */
+	init_waitqueue_head(&CanWait[minor]);
+/* das geht */
+	/* CanWait[minor] = NULL; */
+#else
+	CanWait[minor] = NULL;
+#endif
+    DBGout();
+    return 0;
+}
+
+/*
+initialize RX and TX Fifo's
+*/
+int Can_FifoInit(int minor)
+{
+int i;
+
+    DBGin("Can_FifoInit");
+       Tx_Buf[minor].head   = Rx_Buf[minor].head = 0;
+       Tx_Buf[minor].tail   = Rx_Buf[minor].tail = 0;
+       Tx_Buf[minor].status = Rx_Buf[minor].status = 0;
+       Tx_Buf[minor].active = Rx_Buf[minor].active = 0;
+       for(i = 0; i < MAX_BUFSIZE; i++) {
+	   Tx_Buf[minor].free[i]  = BUF_EMPTY;
+       }
+    DBGout();
+    return 0;
+}
+
+#ifdef CAN_USE_FILTER
+int Can_FilterInit(int minor)
+{
+int i;
+
+    DBGin("Can_FilterInit");
+       Rx_Filter[minor].use      = 0;
+       Rx_Filter[minor].signo[0] = 0;
+       Rx_Filter[minor].signo[1] = 0;
+       Rx_Filter[minor].signo[2] = 0;
+
+       for(i=0;i<MAX_ID_NUMBER;i++)	
+	  Rx_Filter[minor].filter[i].rtr_response = NULL;
+
+    DBGout();
+    return 0;
+}
+
+int Can_FilterCleanup(int minor)
+{
+int i;
+
+    DBGin("Can_FilterCleanup");
+    for(i=0;i<MAX_ID_NUMBER;i++) {
+	    if( Rx_Filter[minor].filter[i].rtr_response != NULL )	
+	       kfree( Rx_Filter[minor].filter[i].rtr_response);
+	    Rx_Filter[minor].filter[i].rtr_response = NULL;
+    }
+    DBGout();
+    return 0;
+}
+
+
+int Can_FilterOnOff(int minor, unsigned on) {
+    DBGin("Can_FilterOnOff");
+       Rx_Filter[minor].use = (on!=0);
+    DBGout();
+    return 0;
+}
+
+int Can_FilterMessage(int minor, unsigned message, unsigned enable) {
+    DBGin("Can_FilterMessage");
+       Rx_Filter[minor].filter[message].enable = (enable!=0);
+    DBGout();
+    return 0;
+}
+
+int Can_FilterTimestamp(int minor, unsigned message, unsigned stamp) {
+    DBGin("Can_FilterTimestamp");
+       Rx_Filter[minor].filter[message].timestamp = (stamp!=0);
+    DBGout();
+    return 0;
+}
+
+int Can_FilterSignal(int minor, unsigned id, unsigned signal) {
+    DBGin("Can_FilterSignal");
+       if( signal <= 3 )
+       Rx_Filter[minor].filter[id].signal = signal;
+    DBGout();
+    return 0;
+}
+
+int Can_FilterSigNo(int minor, unsigned signo, unsigned signal ) {
+    DBGin("Can_FilterSigNo");
+       if( signal < 3 )
+       Rx_Filter[minor].signo[signal] = signo;
+    DBGout();
+    return 0;
+}
+#endif
+
+#ifdef CAN_RTR_CONFIG
+int Can_ConfigRTR( int minor, unsigned message, canmsg_t *Tx )
+{
+canmsg_t *tmp;
+
+    DBGin("Can_ConfigRTR");
+    if( (tmp = kmalloc ( sizeof(canmsg_t), GFP_ATOMIC )) == NULL ){
+	    DBGprint(DBG_BRANCH,("memory problem"));
+	    DBGout(); return -1;
+    }
+    Rx_Filter[minor].filter[message].rtr_response = tmp;
+    memcpy( Rx_Filter[minor].filter[message].rtr_response , Tx, sizeof(canmsg_t));	
+    DBGout(); return 1;
+    return 0;
+}
+
+int Can_UnConfigRTR( int minor, unsigned message )
+{
+canmsg_t *tmp;
+
+    DBGin("Can_UnConfigRTR");
+    if( Rx_Filter[minor].filter[message].rtr_response != NULL ) {
+	    kfree(Rx_Filter[minor].filter[message].rtr_response);
+	    Rx_Filter[minor].filter[message].rtr_response = NULL;
+    }	
+    DBGout(); return 1;
+    return 0;
+}
+#endif
+
+
+#ifdef DEBUG
+
+/* dump_CAN or CAN_dump() which is better ?? */
+#if CAN4LINUX_PCI
+#else
+#endif
+#include <asm/io.h>
+
+#if 0
+/* simply dump a memory area bytewise for 2*16 addresses */
+void dump_CAN(unsigned long adress, int offset)
+{
+int i, j;
+unsigned long ptr = (unsigned long)ioremap(adress, 256);
+    printk("     CAN at Adress 0x%x\n", adress);
+    for(i = 0; i < 2; i++) {
+	printk("     ");
+	for(j = 0; j < 16; j++) {
+	    /* printk("%02x ", *ptr++); */
+	    printk("%02x ", readb(ptr));
+	    ptr += offset;
+	}
+	printk("\n");
+    }
+}
+
+/*
+ * adress - start address 
+ * n      - number of 16 byte rows, 
+ * offset - print every n-th byte
+ */
+void dump_CAN(unsigned long adress, int n, int offset)
+{
+int i, j;
+    printk("     CAN at Adress 0x%x\n", adress);
+    for(i = 0; i < n; i++) {
+	printk("     ");
+	for(j = 0; j < 16; j++) {
+	    /* printk("%02x ", *ptr++); */
+	    printk("%02x ", readb(adress));
+	    adress += offset;
+	}
+	printk("\n");
+    }
+}
+#endif
+
+#if CAN4LINUX_PCI
+# define REG_OFFSET 4
+#else
+# define REG_OFFSET 1
+#endif
+/**
+*   Dump the CAN controllers register contents,
+*   identified by the device minr number to stdout
+*
+*   Base[minor] should contain the virtual adress
+*/
+void Can_dump(int minor)
+{
+int i, j;
+int index = 0;
+
+	for(i = 0; i < 2; i++) {
+	    for(j = 0; j < 16; j++) {
+		printk("%02x ",
+#ifdef  CAN_PORT_IO
+		inb((int) (Base[minor] + index)) );
+#else
+		readb((u32) (can_base[minor] + index)) );
+#endif
+		index += REG_OFFSET;
+	    }
+	    printk("\n");
+	}
+}
+#endif
+
+#ifdef CAN4LINUX_PCI
+/* reset both can controllers on the EMS-Wünsche CPC-PCI Board */
+/* writing to the control range at BAR1 of the PCI board */
+void reset_CPC_PCI(unsigned long address)
+{
+unsigned long ptr = (unsigned long)ioremap(address, 32);
+    DBGin("reset_CPC_PCI");
+    /* printk("reset_CPC_PCI\n"); */
+    writeb(0x01, ptr);
+    writeb(0x00, ptr);
+}
+
+/* check memory region if there is a CAN controller
+*  assume the controller was resetted before testing 
+*/
+int controller_available(unsigned long address, int offset)
+{
+unsigned long ptr = (unsigned long)ioremap(address, 32 * offset);
+
+    DBGin("controller_available");
+    /* printk("controller_available %ld\n", address); */
+
+
+    /* printk("0x%0x, ", readb(ptr + (2 * offset)) ); */
+    /* printk("0x%0x\n", readb(ptr + (3 * offset)) ); */
+
+    if(   0x0c == readb(ptr + (2 * offset))
+       && 0xe0 == readb(ptr + (3 * offset)) ) {
+	return 1;
+    } else {
+	return 0;
+    }
+}
+#endif
+
+
+
+#ifdef CAN4LINUX_PCI
+static u32 addresses[] = {
+    PCI_BASE_ADDRESS_0,
+    PCI_BASE_ADDRESS_1,
+    PCI_BASE_ADDRESS_2,
+    PCI_BASE_ADDRESS_3,
+    PCI_BASE_ADDRESS_4,
+    PCI_BASE_ADDRESS_5,
+    0
+};
+
+/* used for storing the global pci register address */
+u32 Can_pitapci_control[4];
+
+
+/*
+scan the pci bus
+ look for vendor/device Id == Siemens PITA
+ if found
+    look for  subvendor id
+    if found
+      write to pita register 1c in the first address range the value 0x04000000
+*/
+int pcimod_scan(void)
+{
+    int i, pos = 0;
+    int bus, fun;
+    unsigned char headertype = 0;
+    u32 id;
+    u32 vdid;				/* vendor/device id */
+    int candev = 0;				/* number of found devices */
+
+    if (!pcibios_present()) {
+        printk("CAN: No PCI bios present\n");
+        return ENODEV;
+    }
+    /* printk("CAN: PCI bios present!\n"); */
+
+    /*
+     * This code is derived from "drivers/pci/pci.c". This means that
+     * the GPL applies to this source file and credit is due to the
+     * original authors (Drew Eckhardt, Frederic Potter, David
+     * Mosberger-Tang)
+     */
+    for (bus = 0; !bus; bus++) { /* only bus 0 :-) */
+        for (fun=0; fun < 0x100 && pos < PAGE_SIZE; fun++) {
+            if (!PCI_FUNC(fun)) /* first function */
+                pcibios_read_config_byte(bus,fun,PCI_HEADER_TYPE, &headertype);
+            else if (!(headertype & 0x80))
+                continue;
+            /* the following call gets vendor AND device ID */
+            pcibios_read_config_dword(bus, fun, PCI_VENDOR_ID, &id);
+            if (!id || id == ~0) {
+                headertype = 0; continue;
+            }
+            /* v-endor and d-evice id */
+            vdid = id;
+#if 0
+            printk(" -- found pci device, vendor id = %u/0x%x , device 0x%x\n",
+            	(id & 0xffff), (id & 0xffff), (id >> 16));
+#endif
+            pcibios_read_config_dword(bus, fun, PCI_CLASS_REVISION, &id);
+#if 0
+            printk("    class 0x%x, Revision %d\n",
+            	(id >> 8), (id & 0x0ff));
+#endif
+            if(vdid == (PCI_VENDOR + (PCI_DEVICE << 16))) {
+		unsigned char irq;
+		u16 cmd;
+		u32 svdid;			/* subsystem vendor/device id */
+		    /* found EMS CAN CPC-PCI */
+		    vdid = 0;	/* reset it */
+		    printk("    found Siemens PITA PCI-Chip\n");
+		    pcibios_read_config_byte(bus, fun, PCI_INTERRUPT_LINE, &irq);
+		    printk("        using IRQ %d\n", irq);
+		    pcibios_read_config_word(bus, fun, PCI_COMMAND, &cmd);
+		    /* printk("        cmd: 0x%x\n", cmd); */
+
+                    /* PCI_COMMAND should be at least PCI_COMMAND_MEMORY */
+		    pcibios_write_config_word(bus, fun,
+		    		/* PCI_COMMAND, PCI_COMMAND_MEMORY); */
+		    		PCI_COMMAND, PCI_COMMAND_MEMORY + PCI_COMMAND_MASTER	);
+		    pcibios_read_config_word(bus, fun, PCI_COMMAND, &cmd);
+		    /* printk("        cmd: 0x%x\n", cmd); */
+
+
+
+
+		    pcibios_read_config_dword(bus, fun, PCI_SUBSYSTEM_VENDOR_ID, &svdid);
+		    /* printk("        s_vendor 0x%x, s_device 0x%x\n", */
+					/* (svdid & 0xffff), (svdid >> 16)); */
+
+		/* How can we be sure that that is an EMS CAN card ?? */
+
+
+		for (i = 0; addresses[i]; i++) {
+		    u32 curr, mask;
+		    char *type;
+
+		    pcibios_read_config_dword(bus, fun, addresses[i], &curr);
+		    cli();
+		    pcibios_write_config_dword(bus, fun, addresses[i], ~0);
+		    pcibios_read_config_dword(bus, fun, addresses[i], &mask);
+		    pcibios_write_config_dword(bus, fun, addresses[i], curr);
+		    sti();
+
+		    /* printk("    region %i: mask 0x%08lx, now at 0x%08lx\n", i, */
+				   /* (unsigned long)mask, */
+				   /* (unsigned long)curr); */
+#if 0 /* we don't need this message, so we don't need this code */
+		    if (!mask) {
+			printk("    region %i not existent\n", i);
+			break;
+		    }
+#endif
+		    /* extract the type, and the programmable bits */
+		    if (mask & PCI_BASE_ADDRESS_SPACE) {
+		    type = "I/O"; mask &= PCI_BASE_ADDRESS_IO_MASK;
+		    } else {
+			type = "mem"; mask &= PCI_BASE_ADDRESS_MEM_MASK;
+		    }
+		/* printk("    region %i: type %s, size %i\n", i, */
+			      /* type, ~mask+1); */
+
+		    if(i == 0) {
+		    	/* BAR0 internal PITA registers */
+			unsigned long ptr = (unsigned long)ioremap(curr, 256);
+			/* enable memory access */
+		    	/* printk("write to pita\n"); */
+			writel(0x04000000, ptr + 0x1c);
+			Can_pitapci_control[candev] = ptr;
+
+		    }
+		    if(i == 1) {
+		    	/* BAR1 parallel I/O
+		    	 * at address 0 are some EMS control registers
+		    	 * at address 0x400 the first controller area 
+		    	 * at address 0x600 the second controller area 
+			 * registers are read as 32bit
+			 *
+			 * at adress 0 we can verify the card
+			 * 0x55 0xaa 0x01 0xcb
+			 */
+			/* dump_CAN(curr, 4); */
+
+			reset_CPC_PCI(curr);
+
+			/* enable interrupts Int_0 */
+			/* write to PITAs ICR register */
+    			writel(0x00020000, Can_pitapci_control[candev] + 0x0);
+
+			/* dump_CAN(curr + 0x400, 4); */
+			if(controller_available(curr + 0x400, 4)) {
+			    printk("CAN: at pos 1\n");
+			    if(candev > 4) {
+				printk("CAN: only 4 devices supported\n");
+				break; /* the devices scan loop */
+			    }
+			    Base[candev]
+			    = (unsigned long)ioremap(curr + 0x400, 32*4);
+			    IOModel[candev] = 'm';
+			    IRQ[candev] = irq;
+			    candev++;
+			} else {
+			    printk("CAN: NO at pos 1\n");
+			}
+			/* dump_CAN(curr + 0x600, 4); */
+
+			if(controller_available(curr + 0x600, 4)) {
+			    printk("CAN: at pos 2\n");
+			    if(candev > 4) {
+				printk("CAN: only 4 devices supported\n");
+				break; /* the devices scan loop */
+			    }
+			    /* share the board control register with prev ch */
+    			    Can_pitapci_control[candev] = 
+				Can_pitapci_control[candev - 1];
+			    Base[candev]
+			    = (unsigned long)ioremap(curr + 0x600, 32*4);
+			    IOModel[candev] = 'm';
+			    IRQ[candev] = irq;
+			    candev++;
+			} else {
+			    printk("CAN: NO at pos 2\n");
+			}
+		    }
+
+		}
+            } /* EMS CPC-PCI */
+        } /* for all devices */
+    } /* for all busses */
+    return 0;
+}
+#endif
+
+
diff -urN linux-2.4.29/drivers/char/can4linux/can_write.c linux-2.4.29-uc1/drivers/char/can4linux/can_write.c
--- linux-2.4.29/drivers/char/can4linux/can_write.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/can_write.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,163 @@
+/*
+ * can_write - can4linux CAN driver module
+ *
+ * can4linux -- LINUX CAN device driver source
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * 
+ * Copyright (c) 2001 port GmbH Halle/Saale
+ * (c) 2001 Heinz-Jürgen Oertel (oe@port.de)
+ *          Claus Schroeter (clausi@chemie.fu-berlin.de)
+ *------------------------------------------------------------------
+ * $Header: /var/cvs/uClinux-2.4.x/drivers/char/can4linux/can_write.c,v 1.1 2003/07/18 00:11:46 gerg Exp $
+ *
+ *--------------------------------------------------------------------------
+ *
+ *
+ * modification history
+ * --------------------
+ * $Log: can_write.c,v $
+ * Revision 1.1  2003/07/18 00:11:46  gerg
+ * I followed as much rules as possible (I hope) and generated a patch for the
+ * uClinux distribution. It contains an additional driver, the CAN driver, first
+ * for an SJA1000 CAN controller:
+ *   uClinux-dist/linux-2.4.x/drivers/char/can4linux
+ * In the "user" section two entries
+ *   uClinux-dist/user/can4linux     some very simple test examples
+ *   uClinux-dist/user/horch         more sophisticated CAN analyzer example
+ *
+ * Patch submitted by Heinz-Juergen Oertel <oe@port.de>.
+ *
+ *
+ *
+ *
+ *
+ *--------------------------------------------------------------------------
+ */
+
+
+/**
+* \file can_write.c
+* \author Heinz-Jürgen Oertel, port GmbH
+* $Revision: 1.1 $
+* $Date: 2003/07/18 00:11:46 $
+*
+*/
+
+#include "can_defs.h"
+
+/* \fn size_t can_write( __LDDK_WRITE_PARAM) */
+/***************************************************************************/
+/**
+
+\brief size_t write(int fd, const char *buf, size_t count);
+write CAN messages to the network
+\param fd The descriptor to write to.
+\param buf The data buffer to write (array of CAN canmsg_t).
+\param count The number of bytes to write.
+
+write  writes  up to \a count CAN messages to the CAN controller
+referenced by the file descriptor fd from the buffer
+starting at buf.
+
+
+
+\par Errors
+
+the following errors can occur
+
+\li \c EBADF  fd is not a valid file descriptor or is not open
+              for writing.
+
+\li \c EINVAL fd is attached to an object which is unsuitable for
+              writing.
+
+\li \c EFAULT buf is outside your accessible address space.
+
+\li \c EINTR  The call was interrupted by a signal before any
+              data was written.
+
+
+
+\returns
+On success, the number of CAN messages written are returned
+(zero indicates nothing was written).
+On error, -1 is returned, and errno is set appropriately.
+
+\internal
+*/
+
+__LDDK_WRITE_TYPE can_write( __LDDK_WRITE_PARAM )
+{
+unsigned int minor = __LDDK_MINOR;
+msg_fifo_t *TxFifo = &Tx_Buf[minor];
+canmsg_t *addr;
+canmsg_t tx;
+unsigned long flags;
+int written        = 0;
+
+    DBGin("can_write");
+#ifdef DEBUG_COUNTER
+    Cnt1[minor] = Cnt1[minor] + 1;
+#endif /* DEBUG_COUNTER */
+
+/* DEBUG_TTY(1, "write: %d", count); */
+    DBGprint(DBG_DATA,(" -- write %d msg\n", count));
+    /* printk("w[%d/%d]", minor, TxFifo->active); */
+    addr = (canmsg_t *)buffer;
+
+    if(verify_area(VERIFY_READ, (canmsg_t *)addr, count * sizeof(canmsg_t))) { 
+	    DBGout();return -EINVAL;
+    }
+    while( written < count ) {
+	/* enter critical section */
+	save_flags(flags);cli();
+	/* there are data to write to the network */
+	if(TxFifo->free[TxFifo->head] == BUF_FULL) {
+/* DEBUG_TTY(1, "ret buffer full"); */
+	    /* there is already one message at this place */;
+	    DBGout();
+	    /* return -ENOSPC; */
+	    return written;
+	}
+	if( TxFifo->active ) {
+	    /* more than one data and actual data in queue */
+	    __lddk_copy_from_user(	/* copy one message to FIFO */
+		    (canmsg_t *) &(TxFifo->data[TxFifo->head]), 
+		    (canmsg_t *) &addr[written],
+		    sizeof(canmsg_t) );
+/* DEBUG_TTY(1, " fifo active: id %d/%x; head %d/tail %d", */
+/* TxFifo->data[TxFifo->head].id, */
+/* TxFifo->data[TxFifo->head].id, */
+/* TxFifo->head, */
+/* TxFifo->tail); */
+	    TxFifo->free[TxFifo->head] = BUF_FULL; /* now this entry is FULL */
+	    TxFifo->head = ++(TxFifo->head) % MAX_BUFSIZE;
+	} else {
+	    __lddk_copy_from_user(
+		    (canmsg_t *) &tx, 
+		    (canmsg_t *) &addr[written],
+		    sizeof(canmsg_t) );
+/* DEBUG_TTY(1, " fifo in-active: id %d/%x; head %d/tail %d", */
+		/* tx.id, tx.id, */
+/* TxFifo->head, */
+/* TxFifo->tail ); */
+	  /* f - fast -- use interrupts */
+	  if( count >= 1 ) {
+	    /* !!! CHIP abh. !!! */
+	    TxFifo->active = 1;
+	  }
+	  CAN_SendMessage( minor, &tx);  /* Send, no wait */
+	}
+        written++;
+	/* leave critical section */
+	restore_flags(flags);
+    }
+    /* printk("W[%d/%d]", minor, TxFifo->active); */
+    DBGout();
+    return written;
+}
+
diff -urN linux-2.4.29/drivers/char/can4linux/Makefile linux-2.4.29-uc1/drivers/char/can4linux/Makefile
--- linux-2.4.29/drivers/char/can4linux/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/Makefile	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,84 @@
+#
+# Makefile for the linux CAN drivers.
+#
+# (C) H.-J. Oertel oe@port.de
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+# 
+# 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; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# $Source: /var/cvs/uClinux-2.4.x/drivers/char/can4linux/Makefile,v $
+# $Revision: 1.1 $
+# $Date: 2003/07/18 00:11:46 $
+
+
+
+# Used release tag for this software version
+VERSION=3
+REL=0
+RELEASE=CAN4LINUX-$(VERSION)_$(REL)
+DVERSION=$(VERSION).$(REL)
+
+
+#
+# The CAN driver major device number
+# The new linux/Documentation/devices.txt defines major=91
+CAN_MAJOR=	91
+
+EXTRA_CFLAGS +=  -DVERSION=\"$(DVERSION)_$(TARGET)\" -DCan_MAJOR=$(CAN_MAJOR) \
+	# -DDEBUG=1 -DDEFAULT_DEBUG
+
+O_TARGET := Can.o
+
+obj-y   := can_core.o can_open.o can_select.o can_sysctl.o can_write.o \
+	   can_close.o can_ioctl.o can_read.o can_util.o \
+	   can_debug.o can_error.o
+
+##########################################################################
+ifeq ($(CONFIG_CAN_ATCANMINI),y)
+obj-y += can_sja1000funcs.o
+EXTRA_CFLAGS += -DATCANMINI_PELICAN -DMAX_CHANNELS=2
+TARGET=ATCANMINI_PELICAN
+endif
+##########################################################################
+ifeq ($(CONFIG_CAN_CCPC104),y)
+obj-y += can_sja1000funcs.o
+EXTRA_CFLAGS += -DCCPC104 -DMAX_CHANNELS=2
+TARGET=CTRLink_PC104
+endif
+##########################################################################
+ifeq ($(CONFIG_CAN_MCF5282),y)
+obj-y += can_mcf5282funcs.o
+EXTRA_CFLAGS += -DMCF5282 -DMAX_CHANNELS=1
+TARGET=ColdFire_FlexCAN
+endif
+##########################################################################
+ifeq ($(CONFIG_CAN_MCF5282_MODULE),y)
+obj-y += can_mcf5282funcs.o
+EXTRA_CFLAGS += -DMCF5282 -DMAX_CHANNELS=1
+TARGET=ColdFire_FlexCAN
+endif
+
+obj-y += can_mcf5282funcs.o
+EXTRA_CFLAGS += -DMCF5282 -DMAX_CHANNELS=1
+TARGET=ColdFire_FlexCAN
+
+##########################################################################
+           
+obj-m   := $(O_TARGET)
+
+
+
+include $(TOPDIR)/Rules.make
+
+
diff -urN linux-2.4.29/drivers/char/can4linux/TouCAN.h linux-2.4.29-uc1/drivers/char/can4linux/TouCAN.h
--- linux-2.4.29/drivers/char/can4linux/TouCAN.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/can4linux/TouCAN.h	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,717 @@
+/*
+ * TouCAN - definitions for the Motorola TouCAN module
+ *
+ * Copyright (c) 1998,2000 port GmbH Halle (Saale)
+ *------------------------------------------------------------------
+ * $Header: /z2/cvsroot/common_include/TouCAN.h,v 1.3 2001/04/19 15:06:30 ro Exp $
+ *
+ *--------------------------------------------------------------------------
+ *
+ * 
+ *
+ * modification history
+ * --------------------
+ * $Log: TouCAN.h,v $
+ * Revision 1.3  2001/04/19 15:06:30  ro
+ * adapt to CANopenLIB V4.2
+ * macros for user adaptation moved at the top of the file
+ * Set_Baudrate added
+ *
+ * Revision 1.2  2000/02/10 13:28:34  boe
+ * Vereinbarungen für Motorola TPU CAN-chip
+ *
+ *
+ *
+ *--------------------------------------------------------------------------
+ */
+
+
+/*
+DESCRIPTION
+Version $Revision: 1.3 $
+.sp
+*/
+
+#ifndef __TOU_CAN_H
+#define __TOU_CAN_H
+
+/* Makros to manipulate TouCAN control registers */
+#define CAN_READ(reg)			(reg)
+
+#define CAN_WRITE(reg, source)		((reg) = (source))
+
+#define CAN_SET_BIT(reg, mask)		((reg) |= (mask))
+
+#define CAN_RESET_BIT(reg, mask)	((reg) &= ~(mask))
+
+#define CAN_TEST_BIT(breg, mask)	((breg) & (mask))
+
+
+/*=== Register Layout of the TouCAN module ==============================*/
+typedef struct {
+    volatile unsigned short     canmcr;
+    volatile unsigned short     cantcr;
+    volatile unsigned short     canicr;
+    volatile unsigned char      canctrl0;
+    volatile unsigned char      canctrl1;
+    volatile unsigned char      presdiv;
+    volatile unsigned char      canctrl2;
+    volatile unsigned short     timer;
+    volatile unsigned short     _08C, _08E;
+    volatile unsigned short     rxgmskhi;
+    volatile unsigned short     rxgmsklo;
+    volatile unsigned short     rx14mskhi;
+    volatile unsigned short     rx14msklo;
+    volatile unsigned short     rx15mskhi;
+    volatile unsigned short     rx15msklo;
+    volatile unsigned short     _09C, _09E;
+    volatile unsigned short     estat;
+    volatile unsigned short     imask;
+    volatile unsigned short     iflag;
+    volatile unsigned char      rxectr;
+    volatile unsigned char      txectr;
+} tou_can_t;
+
+/* FlexCAN mcf5282 located at MCF_MBAR + 0x1C'0000 */
+typedef struct {
+    volatile unsigned short     canmcr;		/* module config register */
+    volatile unsigned short     reserved00;
+
+    volatile unsigned short     reserved06;
+    volatile unsigned char      canctrl0;	/* control register 0     */
+    volatile unsigned char      canctrl1;	/* control register 1     */
+    
+    volatile unsigned char      presdiv;	/* prescaler divider      */
+    volatile unsigned char      canctrl2;	/* control register 2     */
+    volatile unsigned short     timer;
+
+    volatile unsigned short     reserved0E;
+    volatile unsigned short     reserved0C;
+
+#if 0
+    volatile unsigned int       rxgmsk;		/* RX global mask         */
+    volatile unsigned int       rx14msk;	/* RX Buffer 14 Mask      */
+    volatile unsigned int       rx15msk;	/* RX Buffer 15 Mask      */
+#else
+/* according errata sheet:
+errata id 8:   FlexCAN
+07/23/03   32-bit accesses to FlexCAN registers do not work properly
+*/
+
+    volatile unsigned short     rxgmskhi;
+    volatile unsigned short     rxgmsklo;
+    volatile unsigned short     rx14mskhi;
+    volatile unsigned short     rx14msklo;
+    volatile unsigned short     rx15mskhi;
+    volatile unsigned short     rx15msklo;
+#endif
+    volatile unsigned int       reserverd1C;
+    
+    volatile unsigned short     estat;		/* Error and status ESTAT */
+    volatile unsigned short     imask;		/* Interrupt masks IMASK  */
+    
+    volatile unsigned short     iflag;		/* Interrupt flags IFLAG  */
+    volatile unsigned char      rxectr;		/* Rx error counter RXECTR*/
+    volatile unsigned char      txectr;		/* Tx error counter TXECTR*/
+} flex_can_t;
+
+
+
+
+/* To have two different CAN structures here, TouCan and FlexCan
+ * to be used with -
+ * - CANopen library without OS we use a global pointer tou_can
+ * - can4linux we use the generic name canregs_t
+ *   /this name is used also in the sja1000 driver)
+ */
+# ifdef CONFIG_MULT_LINES
+#   ifdef MCF5282
+    extern flex_can_t *tou_can_addr[];
+#   else 
+    extern tou_can_t *tou_can_addr[];
+#   endif
+# else 
+#   ifdef MCF5282
+    extern flex_can_t *tou_can;
+    typedef flex_can_t canregs_t;
+#   else 
+    extern tou_can_t *tou_can;
+    typedef tou_can_t canregs_t;
+#   endif
+# endif
+
+
+
+#define CAN_ControlReg0			(tou_can->canctrl0)
+#define CAN_ControlReg1			(tou_can->canctrl1)
+#define CAN_ControlReg2			(tou_can->canctrl2)
+
+#define CAN_TestConfigRegister		(tou_can->cantcr)
+#define CAN_ModulConfigRegister		(tou_can->canmcr)
+#define CAN_InterruptRegister		(tou_can->canicr)
+#define CAN_PrescalerDividerRegister	(tou_can->presdiv)
+#define CAN_TimerRegister		(tou_can->timer)
+#define CAN_ErrorStatusRegister		(tou_can->estat)
+#define CAN_InterruptMasks		(tou_can->imask)
+#define CAN_InterruptFlags		(tou_can->iflag)
+#define CAN_ReceiveErrorCounter		(tou_can->rxectr)
+#define CAN_TransmitErrorCounter	(tou_can->txectr)
+/* or TouCAN with word access */
+#define CAN_ReceiveGlobalMaskHigh	(tou_can->rxgmskhi)
+#define CAN_ReceiveGlobalMaskLow	(tou_can->rxgmsklo)
+#define CAN_ReceiveBuffer14MaskHigh	(tou_can->rx14mskhi)
+#define CAN_ReceiveBuffer14MaskLow	(tou_can->rx14msklo)
+#define CAN_ReceiveBuffer15MaskHigh	(tou_can->rx15mskhi)
+#define CAN_ReceiveBuffer15MaskLow	(tou_can->rx15msklo)
+/* some more for CF FlexCAN with 32bit access */
+#define CAN_ReceiveGlobalMask    	(tou_can->rxgmsk)
+#define CAN_ReceiveBuffer14Mask		(tou_can->rx14msk)
+#define CAN_ReceiveBuffer15Mask		(tou_can->rx15msk)
+
+
+/* Bit values of the TouCAN module configuration register */
+
+#define CAN_MCR_STOP			0x8000
+#define CAN_MCR_FRZ			0x4000
+#define CAN_MCR_HALT			0x1000
+#define CAN_MCR_NOT_RDY			0x0800
+#define CAN_MCR_WAKE_MSK		0x0400
+#define CAN_MCR_SOFT_RST		0x0200
+#define CAN_MCR_FRZ_ACK			0x0100
+#define CAN_MCR_SUPV			0x0080
+#define CAN_MCR_SELF_WAKE		0x0040
+#define CAN_MCR_APS			0x0020
+#define CAN_MCR_STOP_ACK		0x0010
+#define CAN_MCR_IARB_MASK		0x000F
+#define CAN_MCR_IARB3			0x0008
+#define CAN_MCR_IARB2			0x0004
+#define CAN_MCR_IARB1			0x0002
+#define CAN_MCR_IARB0			0x0001
+
+/* Bits of the TouCAN control register 0 */
+
+#define CAN_CTRL0_BOFF_MSK_BIT		7
+#define CAN_CTRL0_ERR_MSK_BIT		6
+#ifdef MCF5282
+/* only one bit for RX configuartion */
+#else
+#define CAN_CTRL0_RXMODE1_BIT		3
+#endif
+#define CAN_CTRL0_RXMODE0_BIT		2
+#define CAN_CTRL0_TXMODE1_BIT		1
+#define CAN_CTRL0_TXMODE0_BIT		0
+
+/* Bit values of the TouCAN control register 0 */
+
+#define CAN_CTRL0_BOFF_MSK		0x80
+#define CAN_CTRL0_ENABLE_BOFF_INT	0x80
+#define CAN_CTRL0_DISABLE_BOFF_INT	0x00
+#define CAN_CTRL0_ERR_MSK		0x40
+#define CAN_CTRL0_ENABLE_ERR_INT	0x40
+#define CAN_CTRL0_DISABLE_ERR_INT	0x00
+#ifdef MCF5282
+/* only one bit for RX configuartion */
+#else
+#define CAN_CTRL0_RXMODE1		0x08
+#endif
+#define CAN_CTRL0_RXMODE0		0x04
+#define CAN_CTRL0_TXMODE1		0x02
+#define CAN_CTRL0_TXMODE0		0x01
+
+
+/* Bits of the TouCAN control register 1 */
+
+#define CAN_CTRL1_SAMP_BIT		7
+#define CAN_CTRL1_LOOP_BIT		6
+#define CAN_CTRL1_TSYNC_BIT		5
+#define CAN_CTRL1_LBUF_BIT		4
+#define CAN_CTRL1_PROPSEG2_BIT		2
+#define CAN_CTRL1_PROPSEG1_BIT		1
+#define CAN_CTRL1_PROPSEG0_BIT		0
+
+/* Bit values of the TouCAN control register 1 */
+
+#define CAN_CTRL1_SAMP			0x80
+#define CAN_CTRL1_LOOP			0x40
+#define CAN_CTRL1_TSYNC			0x20
+#define CAN_CTRL1_LBUF			0x10
+#define CAN_CTRL1_PROPSEG2		0x04
+#define CAN_CTRL1_PROPSEG1		0x02
+#define CAN_CTRL1_PROPSEG0		0x01
+
+
+/* Bits of the TouCAN control register 2 */
+
+#define CAN_CTRL2_RJW1_BIT		7
+#define CAN_CTRL2_RJW0_BIT		6
+#define CAN_CTRL2_PSEG1_2_BIT		5
+#define CAN_CTRL2_PSEG1_1_BIT		4
+#define CAN_CTRL2_PSEG1_0_BIT		3
+#define CAN_CTRL2_PSEG2_2_BIT		2
+#define CAN_CTRL2_PSEG2_1_BIT		1
+#define CAN_CTRL2_PSEG2_0_BIT		0
+
+/* Bit values of the TouCAN control register 2 */
+
+#define CAN_CTRL2_RJW1			0x80
+#define CAN_CTRL2_RJW0			0x40
+#define CAN_CTRL2_PSEG1_2		0x20
+#define CAN_CTRL2_PSEG1_1		0x10
+#define CAN_CTRL2_PSEG1_0		0x08
+#define CAN_CTRL2_PSEG2_2		0x04
+#define CAN_CTRL2_PSEG2_1		0x02
+#define CAN_CTRL2_PSEG2_0		0x01
+
+
+/* Bits of the TouCAN error and status register */
+
+#define CAN_ESTAT_BITERR1_BIT		15
+#define CAN_ESTAT_BITERR0_BIT		14
+#define CAN_ESTAT_ACK_ERR_BIT		13
+#define CAN_ESTAT_CRC_ERR_BIT		12
+#define CAN_ESTAT_FORM_ERR_BIT		11
+#define CAN_ESTAT_STUFF_ERR_BIT		10
+#define CAN_ESTAT_TX_WARN_BIT		9
+#define CAN_ESTAT_RX_WARN_BIT		8
+#define CAN_ESTAT_IDLE_BIT		7
+#define CAN_ESTAT_TX_RX_BIT		6
+#define CAN_ESTAT_FCS1_BIT		5
+#define CAN_ESTAT_FCS0_BIT		4
+#define CAN_ESTAT_BOFF_INT_BIT		2
+#define CAN_ESTAT_ERR_INT_BIT		1
+#define CAN_ESTAT_WAKE_INT_BIT		0
+
+/* Bit values of the TouCAN error and status register */
+
+#define CAN_ESTAT_BITERR1		0x8000
+#define CAN_ESTAT_BITERR0		0x4000
+#define CAN_ESTAT_ACK_ERR		0x2000
+#define CAN_ESTAT_CRC_ERR		0x1000
+#define CAN_ESTAT_FORM_ERR		0x0800
+#define CAN_ESTAT_STUFF_ERR		0x0400
+#define CAN_ESTAT_TX_WARN		0x0200
+#define CAN_ESTAT_RX_WARN		0x0100
+#define CAN_ESTAT_IDLE			0x0080
+#define CAN_ESTAT_TX_RX			0x0040
+#define CAN_ESTAT_FCS 			0x0030
+#define CAN_ESTAT_FCS0			0x0010
+#define CAN_ESTAT_FCS1			0x0020
+#define CAN_ESTAT_FCS0			0x0010
+#define CAN_ESTAT_BOFF_INT		0x0004
+#define CAN_ESTAT_ERR_INT		0x0002
+#define CAN_ESTAT_WAKE_INT		0x0001
+
+/*
+ * Macros to handle CAN objects
+ *
+ * Structure for a single CAN object
+ * A total of 15 such object structures exists (starting at CAN_BASE + 0x80)
+ */
+struct can_obj {
+  unsigned short int ctl_status;/* 8-bit time stamp + code + length	*/
+  union {
+    unsigned short int std_id;	/* Standard Identifier			*/
+    unsigned short int id_high;	/* ID high + SRR + IDE			*/
+    } id_high;
+  union {
+    unsigned short int timeStamp; /* 2 byte time stamp counter		*/
+    unsigned short int id_low;	/* ID low + RTR				*/
+    } id_low;
+  unsigned char msg[8];      	/* Message Data 0 .. 7   		*/
+  unsigned char reserved0;	/* Reserved Byte         		*/
+  unsigned char reserved1;	/* Reserved Byte         		*/
+};
+
+/* The firs data byte ov a message */
+#define MSG0 msg[0]
+
+#define STDID_RTR_BIT		0x10
+#define EXTID_RTR_BIT		0x01
+
+/* CAN object definition */
+#define CAN_OBJ \
+   ((struct can_obj volatile *) (((void *)can_base[board]) + 0x80))
+
+/*
+ * the above definition can be used as follows:
+ * CAN_OBJ[Msg].ctl_status = 0x5595;
+ * val = CAN_OBJ[Msg].ctl_status;
+ * with Msg 0....15
+ */
+
+/* ---------------------------------------------------------------------------
+ * CAN_READ_OID(obj) is a macro to read the CAN-ID of the specified object.
+ * It delivers the value as 16 bit from the standard ID registers.
+ */
+
+#define CAN_READ_OID(bChannel) (CAN_OBJ[bChannel].id_high.std_id >> 5)
+#define CAN_READ_OID_AND_RTR(bChannel) (CAN_OBJ[bChannel].id_high.std_id)
+
+
+/* ---------------------------------------------------------------------------
+ * CAN_WRITE_OID(obj, id) is a macro to write the CAN-ID
+ * of the specified object with identifier id.
+ * CAN_WRITE_XOID(obj, id) is a macro to write the extended CAN-ID
+ */
+#define CAN_WRITE_OID(bChannel, Id) (CAN_OBJ[bChannel].id_high.std_id = (Id) << 5)
+
+#define CAN_WRITE_XOID(bChannel, Id)  \
+	do { (CAN_OBJ[bChannel].id_high.id_high \
+	      = 0x18 + (((Id) & 0x1ffC0000) >> 13) + (((Id)  >> 15) & 0x7)); \
+	CAN_OBJ[bChannel].id_low.id_low = (Id /* & 0x7fff */ << 1); \
+	} while(0);
+
+/* ---------------------------------------------------------------------------
+ * CAN_WRITE_OID_RTR(obj, id) is a macro to write the CAN-ID
+ * of the specified object with identifier id and set the RTR Bit.
+ */
+#define CAN_WRITE_OID_RTR(bChannel, Id) \
+	(CAN_OBJ[bChannel].id_high.std_id = ((Id) << 5) + STDID_RTR_BIT)
+
+#define CAN_WRITE_XOID_RTR(bChannel, Id)  \
+	do { (CAN_OBJ[bChannel].id_high.id_high \
+	      = 0x18 + (((Id) & 0x1ffC0000) >> 13) + (((Id)  >> 15) & 0x7)); \
+	CAN_OBJ[bChannel].id_low.id_low = (Id /* & 0x7fff */ << 1) + EXTID_RTR_BIT; \
+	} while(0);
+
+/* ---------------------------------------------------------------------------
+ * CAN_WRITE_CTRL(obj, code, length) is a macro to write to the 
+ * specified objects control register
+ *
+ * Writes 2 byte, TIME STAMP is overwritten with 0.
+ */
+#define CAN_WRITE_CTRL(bChannel, code, length) \
+	(CAN_OBJ[bChannel].ctl_status = (code << 4) + (length))
+
+/* ---------------------------------------------------------------------------
+ * CAN_READ_CTRL(obj) is a macro to read the CAN-Ctrl register
+ *
+ * Read 2 byte
+ */
+/* #define CAN_READ_CTRL(bChannel) (CAN_OBJ[bChannel].ctl_status >> 4) */
+#define CAN_READ_CTRL(bChannel) (CAN_OBJ[bChannel].ctl_status)
+
+
+/***** receive message object codes *************************************/
+/* Message buffer is not active */
+#define REC_CODE_NOT_ACTIVE	0
+/* Message buffer is active and empty */
+#define REC_CODE_EMPTY		4
+/* Message buffer is full */
+#define REC_CODE_FULL		2
+/* second frame was received into a full buffer before CPU read the first */
+#define REC_CODE_OVERRUN	6
+/* message buffer is now being filled with a new receive frame.
+ * This condition will be cleared within 20 cycles.
+ */
+#define REC_CODE_BUSY		1
+
+/***** transmit message object codes ************************************/
+/* Message buffer not ready for transmit */
+#define TRANS_CODE_NOT_READY		8
+/* Data frame to be transmitted once, unconditionally */
+#define TRANS_CODE_TRANSMIT_ONCE	12
+/* Remote frame to be transmitted once, and message buffer becomes
+ * an RX message buffer for dadat frames;
+ * RTR bit must be set
+ */
+#define TRANS_CODE_TRANSMIT_RTR_ONCE	12
+/* Data frame to be transmitted only as a response to a remote frame, always */
+#define TRANS_CODE_TRANSMIT_ONLY_RTR	10
+/* Data frame to be transmitted once, unconditionally
+ * and then only as a response to remote frame always
+ */
+#define TRANS_CODE_TRANSMIT_ONCE_RTR_ALWAYS	14
+
+
+
+
+/***** message object configuration register ****************************/
+#define CAN_MSG_Dir		    0x08
+#define CAN_MSG_Xtd		    0x04
+
+/* Definitions for Data direction */
+#define CAN_Dir_TRANSMIT 			1
+#define CAN_Dir_RECEIVE 			0
+
+/***** B I T  --  T I M I N G  ******************************************/
+
+/* Bit Timing Register fuer 500 kBit/s   -- 2µs Bit time
+ |       3       |       4       ||       0       |       1       |
+ | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 || 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
+ | 0 |   TSEG2   |     TSEG1     ||  SJW  |          BRP          |
+		BTR1             ||             BTR0
+ 1. possible :
+ CLP = Clock Period ( = 0.1 us at 10 MHz)    82527: CLP == SCLK
+ 1 Tq (Time quantum) = (BRP + 1) * CLP  
+ BRP = Baud Rate Prescaler = 1 (=> Tq = 0.2 us)
+ SJW = Sync Jump Width = 1 (= SJW + 1 = 0 + 1)
+ TSEG1 = Time Segment before Sampling Point = 4
+ TSEG2 = Time Segment after Sampling Point = 3
+ Daraus folgt:
+ Anzahl der Bit Time Segmente (must be  10 )
+    n = 1 + TSEG1+1 + TSEG2+1 = 10
+   --> Sampling Point bei 60 %
+ Baudrate = 10 MHz / ( n * (BRP + 1)) = 500000 Bit/s
+   --> Abweichung 0.0 %
+
+ 2. CANopen DS301 recommends the sampling point at 1.75 µs:
+ CLP = Clock Period ( = 0.1 us at 10 MHz)    82527: CLP == SCLK
+ 1 Tq (Time quantum) = (BRP + 1) * CLP
+ BRP = Baud Rate Prescaler = 0 (=> Tq = 0.1 us)
+ SJW = Sync Jump Width = 1 (= SJW + 1 = 0 + 1)
+ TSEG1 = Time Segment before Sampling Point = 15
+ TSEG2 = Time Segment after Sampling Point = 2
+ Daraus folgt:
+ Anzahl der Bit Time Segmente (must be  20 )
+    n = 1 + TSEG1+1 + TSEG2+1 = 20
+   --> Sampling Point bei 1.7 µs == 85 %
+ Baudrate = 10 MHz / ( n * (BRP + 1)) = 500000 Bit/s
+   --> Abweichung 0.0 %
+
+ With the 82527 additional  divider options must be set in the
+ CPU Interface Register (CAN_CPU_IF_Reg) : Bits DMC and DSC
+ DSC - Divide System Clock 
+     SCKL = XTAL/(1 + DSCbit) ---- SCLK must be <= 10 MHz
+ DMC - Divide Memory Clock 
+*/
+
+/*-- !!! The TouCAN need a special baud rate table with more ----
+ *-- !!! parameters than many other                          ----
+ *-- !!! If you use Set_Baudrate you must cast the table pointer 
+ */
+ 
+typedef struct {
+	UNSIGNED16 rate;
+	UNSIGNED8  presdiv;
+	UNSIGNED8  propseg;
+	UNSIGNED8  pseg1;
+	UNSIGNED8  pseg2;
+} BTR_TAB_TOUCAN_T;
+
+#ifndef CAN_SYSCLK
+#  error Please specify an CAN_SYSCLK value
+#endif
+
+/* generated bit rate table by http://www.port.de/engl/canprod/sv_req_form.html */
+/* bitrate table for 10 MHz */
+#if CAN_SYSCLK == 10
+    #define CAN_SJW			   0
+
+    #define CAN_PRESDIV_10K		0x63
+    #define CAN_PROPSEG_10K		0x07
+    #define CAN_PSEG1_10K		0x07
+    #define CAN_PSEG2_10K		0x02
+
+    #define CAN_PRESDIV_20K		0x31
+    #define CAN_PROPSEG_20K		0x07
+    #define CAN_PSEG1_20K		0x07
+    #define CAN_PSEG2_20K		0x02
+
+    #define CAN_PRESDIV_50K		0x13
+    #define CAN_PROPSEG_50K		0x07
+    #define CAN_PSEG1_50K		0x07
+    #define CAN_PSEG2_50K		0x02
+
+    #define CAN_PRESDIV_100K		0x09
+    #define CAN_PROPSEG_100K		0x07
+    #define CAN_PSEG1_100K		0x07
+    #define CAN_PSEG2_100K		0x02
+
+    #define CAN_PRESDIV_125K		0x07
+    #define CAN_PROPSEG_125K		0x07
+    #define CAN_PSEG1_125K		0x07
+    #define CAN_PSEG2_125K		0x02
+    
+    #define CAN_PRESDIV_250K		0x03
+    #define CAN_PROPSEG_250K		0x07
+    #define CAN_PSEG1_250K		0x07
+    #define CAN_PSEG2_250K		0x02
+
+    #define CAN_PRESDIV_500K		0x01
+    #define CAN_PROPSEG_500K		0x07
+    #define CAN_PSEG1_500K		0x07
+    #define CAN_PSEG2_500K		0x02
+
+    /* bad samplepoint !!! */ 	
+    #define CAN_PRESDIV_800K		0x00
+    #define CAN_PROPSEG_800K		0x07
+    #define CAN_PSEG1_800K		0x07
+    #define CAN_PSEG2_800K		0x07
+    
+    #define CAN_PRESDIV_1000K		0x00
+    #define CAN_PROPSEG_1000K		0x07
+    #define CAN_PSEG1_1000K		0x07
+    #define CAN_PSEG2_1000K		0x02
+    
+    #define CAN_SYSCLK_is_ok		1
+#endif
+
+/* wdh bitrate table for 20 MHz */
+/* using same as for 10 MHz except for PRESDIV */
+#if CAN_SYSCLK == 20
+    #define CAN_SJW			   0
+
+    #define CAN_PRESDIV_10K		(0x63*2+1)
+    #define CAN_PROPSEG_10K		0x07
+    #define CAN_PSEG1_10K		0x07
+    #define CAN_PSEG2_10K		0x02
+
+    #define CAN_PRESDIV_20K		(0x31*2+1)
+    #define CAN_PROPSEG_20K		0x07
+    #define CAN_PSEG1_20K		0x07
+    #define CAN_PSEG2_20K		0x02
+
+    #define CAN_PRESDIV_50K		(0x13*2+1)
+    #define CAN_PROPSEG_50K		0x07
+    #define CAN_PSEG1_50K		0x07
+    #define CAN_PSEG2_50K		0x02
+
+    #define CAN_PRESDIV_100K		(0x09*2+1)
+    #define CAN_PROPSEG_100K		0x07
+    #define CAN_PSEG1_100K		0x07
+    #define CAN_PSEG2_100K		0x02
+
+    #define CAN_PRESDIV_125K		(0x07*2+1)
+    #define CAN_PROPSEG_125K		0x07
+    #define CAN_PSEG1_125K		0x07
+    #define CAN_PSEG2_125K		0x02
+    
+    #define CAN_PRESDIV_250K		(0x03*2+1)
+    #define CAN_PROPSEG_250K		0x07
+    #define CAN_PSEG1_250K		0x07
+    #define CAN_PSEG2_250K		0x02
+
+    #define CAN_PRESDIV_500K		(0x01*2+1)
+    #define CAN_PROPSEG_500K		0x07
+    #define CAN_PSEG1_500K		0x07
+    #define CAN_PSEG2_500K		0x02
+
+    /* bad samplepoint !!! */ 	
+    #define CAN_PRESDIV_800K		(0x00*2+1)
+    #define CAN_PROPSEG_800K		0x07
+    #define CAN_PSEG1_800K		0x07
+    #define CAN_PSEG2_800K		0x07
+    
+    #define CAN_PRESDIV_1000K		(0x00*2+1)
+    #define CAN_PROPSEG_1000K		0x07
+    #define CAN_PSEG1_1000K		0x07
+    #define CAN_PSEG2_1000K		0x02
+    
+    #define CAN_SYSCLK_is_ok		1
+#endif
+
+/*
+ * with Motorola TouCAN, 32 MHz, sample point at 87.5% 
+ * used with ColdFire M5282EVB
+ */ 
+#if CAN_SYSCLK == 32
+    #define CAN_SJW			   0
+
+    #define CAN_PRESDIV_10K		(199)
+    #define CAN_PROPSEG_10K		0x04
+    #define CAN_PSEG1_10K		0x07
+    #define CAN_PSEG2_10K		0x01
+
+    #define CAN_PRESDIV_20K		(99)
+    #define CAN_PROPSEG_20K		0x04
+    #define CAN_PSEG1_20K		0x07
+    #define CAN_PSEG2_20K		0x01
+
+    #define CAN_PRESDIV_50K		(39)
+    #define CAN_PROPSEG_50K		0x04
+    #define CAN_PSEG1_50K		0x07
+    #define CAN_PSEG2_50K		0x01
+
+    #define CAN_PRESDIV_100K		(19)
+    #define CAN_PROPSEG_100K		0x04
+    #define CAN_PSEG1_100K		0x07
+    #define CAN_PSEG2_100K		0x01
+
+    #define CAN_PRESDIV_125K		(15)
+    #define CAN_PROPSEG_125K		0x04
+    #define CAN_PSEG1_125K		0x07
+    #define CAN_PSEG2_125K		0x01
+    
+    #define CAN_PRESDIV_250K		(7)
+    #define CAN_PROPSEG_250K		0x04
+    #define CAN_PSEG1_250K		0x07
+    #define CAN_PSEG2_250K		0x01
+
+    #define CAN_PRESDIV_500K		(3)
+    #define CAN_PROPSEG_500K		0x04
+    #define CAN_PSEG1_500K		0x07
+    #define CAN_PSEG2_500K		0x01
+
+    #define CAN_PRESDIV_800K		(1)
+    #define CAN_PROPSEG_800K		0x07
+    #define CAN_PSEG1_800K		0x07
+    #define CAN_PSEG2_800K		0x02
+    
+    #define CAN_PRESDIV_1000K		(1)
+    #define CAN_PROPSEG_1000K		0x04
+    #define CAN_PSEG1_1000K		0x07
+    #define CAN_PSEG2_1000K		0x01
+    
+    #define CAN_SYSCLK_is_ok		1
+#endif
+
+/* wdh: bitrate table for 40 MHz */
+/* using same as for 10 MHz except for PRESDIV */
+#if CAN_SYSCLK == 40
+    #define CAN_SJW			   0
+
+    #define CAN_PRESDIV_10K		(0x63*4+3)
+    #define CAN_PROPSEG_10K		0x07
+    #define CAN_PSEG1_10K		0x07
+    #define CAN_PSEG2_10K		0x02
+
+    #define CAN_PRESDIV_20K		(0x31*4+3)
+    #define CAN_PROPSEG_20K		0x07
+    #define CAN_PSEG1_20K		0x07
+    #define CAN_PSEG2_20K		0x02
+
+    #define CAN_PRESDIV_50K		(0x13*4+3)
+    #define CAN_PROPSEG_50K		0x07
+    #define CAN_PSEG1_50K		0x07
+    #define CAN_PSEG2_50K		0x02
+
+    #define CAN_PRESDIV_100K		(0x09*4+3)
+    #define CAN_PROPSEG_100K		0x07
+    #define CAN_PSEG1_100K		0x07
+    #define CAN_PSEG2_100K		0x02
+
+    #define CAN_PRESDIV_125K		(0x07*4+3)
+    #define CAN_PROPSEG_125K		0x07
+    #define CAN_PSEG1_125K		0x07
+    #define CAN_PSEG2_125K		0x02
+    
+    #define CAN_PRESDIV_250K		(0x03*4+3)
+    #define CAN_PROPSEG_250K		0x07
+    #define CAN_PSEG1_250K		0x07
+    #define CAN_PSEG2_250K		0x02
+
+    #define CAN_PRESDIV_500K		(0x01*4+3)
+    #define CAN_PROPSEG_500K		0x07
+    #define CAN_PSEG1_500K		0x07
+    #define CAN_PSEG2_500K		0x02
+
+    /* bad samplepoint !!! */ 	
+    #define CAN_PRESDIV_800K		(0x00*4+3)
+    #define CAN_PROPSEG_800K		0x07
+    #define CAN_PSEG1_800K		0x07
+    #define CAN_PSEG2_800K		0x07
+    
+    #define CAN_PRESDIV_1000K		(0x00*4+3)
+    #define CAN_PROPSEG_1000K		0x07
+    #define CAN_PSEG1_1000K		0x07
+    #define CAN_PSEG2_1000K		0x02
+    
+    #define CAN_SYSCLK_is_ok		1
+#endif
+
+#ifndef CAN_SYSCLK_is_ok
+#  error Please specify a valid CAN_SYSCLK value (i.e. 10,20,40) or define new parameters
+#endif
+/*==========================================================================*/
+#endif		/* __TOU_CAN_H  */
diff -urN linux-2.4.29/drivers/char/cnxtserial.c linux-2.4.29-uc1/drivers/char/cnxtserial.c
--- linux-2.4.29/drivers/char/cnxtserial.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/cnxtserial.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,1415 @@
+/****************************************************************************
+*
+*	Name:			cnxtserial.c
+*
+*	Description:	Provides serial port character I/O (16550)
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author: Richarjc $
+*  $Revision: 5 $
+*  $Modtime: 8/19/02 10:51a $
+****************************************************************************/
+
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/config.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/arch/irq.h>
+#include <asm/system.h> 
+#include <asm/segment.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+#include <asm/arch/bspcfg.h>
+#include "cnxtserial.h"
+#include <asm/hardware.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/cnxtbsp.h>
+#include <asm/arch/gpio.h>
+
+static struct cnxt_serial uart_info;
+
+static int console_initialized = 0;
+
+DECLARE_TASK_QUEUE(tq_serial);
+
+struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+static struct tty_struct *serial_table[2];
+static struct termios *serial_termios[2];
+static struct termios *serial_termios_locked[2];
+
+static int baud_table[] = {
+	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
+	9600, 19200, 38400, 57600, 115200, 0 };
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the memcpy_fromfs blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static unsigned char tmp_buf[SERIAL_XMIT_SIZE]; /* This is cheating */
+DECLARE_MUTEX(tmp_buf_sem);
+
+static inline int serial_paranoia_check(struct cnxt_serial *info,
+					dev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%d, %d) in %s\n";
+	static const char *badinfo =
+		"Warning: null m68k_serial for (%d, %d) in %s\n";
+
+	if (!info) {
+		printk(badinfo, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+	if (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+
+
+
+/*
+ * 1. Generic uart stuff
+ */
+
+
+ 
+static void  tx_enable(struct uart_regs *uart){
+	uart->irqe	|= IER_Tx_Holding_Reg;
+}
+
+
+static void tx_start(struct uart_regs *uart, int ints)
+{
+  if(ints)
+    tx_enable(uart);
+}
+
+
+static void start_rx(void)
+{
+	struct uart_regs *uart = uart_info.uart;
+
+#if 0
+	if(uart_info.use_ints)
+#endif
+	{
+		/* enable IRQs */
+		uart->irqe	|= IER_Rx_Holding_Reg;
+	}
+}
+
+
+static void wait_EOT(struct uart_regs *uart)
+{
+  volatile struct uart_regs* puart;
+  unsigned long timeout = 10000;
+  puart = (volatile struct uart_regs*)uart;
+  while(1){
+    if(timeout-- == 0) {
+      printk("eot timeout\n");
+      break;
+    }
+    if(puart->line_status_reg & LSR_Tx_Fifo_Empty)
+      break;
+  }
+}
+
+static void xmit_string(struct cnxt_serial * info, char *p, int len) 
+{
+	struct uart_regs *uart = info->uart;
+	uart->fifo = (char)*p;	
+	tx_start(uart, info->use_ints);
+}
+
+
+static void cnxt_put_char(char ch)
+{
+	int flags = 0;
+
+	if(uart_info.use_ints)
+	{
+		uart_info.uart->fifo=ch;
+	}
+	else
+	{
+		save_flags(flags);
+		cli();
+		wait_EOT(uart_info.uart);
+		uart_info.uart->fifo=ch; 
+		restore_flags(flags);
+	}
+}
+
+
+static void rs_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_put_char"))
+	{
+		return;
+	}
+
+	cnxt_put_char(ch);
+}	
+
+
+static void uart_speed(void)
+{
+  struct uart_regs *uart = uart_info.uart;
+  
+  uart->line_ctrl = LCR_Divisor_Latch;
+  uart->fifo = (char)UART_115200;  /* lower baud rate div */
+  uart->irqe = (char)(UART_115200>>8);  /* upper baud rate div */
+  uart->line_ctrl = 0;
+  uart->line_ctrl =  LCR_8_Bit_Word_1;
+  uart->iir =  (FCR_Fifo_Enable | FCR_Rx_Fifo_Reset | FCR_Tx_Fifo_Reset ); /* fifo ctrl */
+  uart->irqe = IER_Rx_Holding_Reg;  /* enable rx intr */
+  tx_start(uart, uart_info.use_ints);
+  start_rx();
+}
+
+
+/*
+ * 2. Kernel log console
+ */
+ 
+static void cnxt_init_console(void)
+{
+	memset(&uart_info, 0, sizeof(struct cnxt_serial));
+	
+	uart_info.uart          = (struct uart_regs*)UART0_Base_Addr;
+	uart_info.tty	        = 0;
+	uart_info.irqmask	= BIT24;
+	uart_info.irq	        = CNXT_INT_LVL_GPIO;
+	uart_info.port	        = 1;
+	uart_info.use_ints	= 0;
+	uart_info.is_cons	= 1;
+
+	console_initialized = 1;
+}
+
+
+int cnxt_console_setup(struct console *cp, char *arg)
+{
+	if (!cp)
+		return(-1);
+	cnxt_init_console();
+	uart_speed();
+	return(0);
+}
+
+
+static kdev_t cnxt_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+
+/*
+ *	Output a single character, using UART polled mode.
+ *	This is ised for console output.
+ */
+void cnxt_console_write(struct console *cp, const char *p, unsigned len)
+{
+	if (!console_initialized)
+	{
+		cnxt_init_console();
+		uart_speed();
+	}
+	while (len-- > 0)
+	{
+		if (*p == '\n')
+		{
+			cnxt_put_char('\r');
+		}
+		cnxt_put_char(*p++);
+	}
+}
+
+
+struct console  cnxt_console = {
+	name:		"ttyS0",
+	write:		cnxt_console_write,
+	read:	        NULL,
+	device:		cnxt_console_device,
+	unblank:	NULL,
+	setup:		cnxt_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+	cflag:		0,
+	next:		NULL
+};
+
+void serial_cnxt_console_init(void)
+{
+  register_console(&cnxt_console);
+}
+
+/*
+ * 3. serial tty stuff
+ */
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void change_speed(struct cnxt_serial *info)
+{
+	unsigned cflag;
+	int	i;
+
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+
+	/* set the baudrate */
+	i = cflag & CBAUD;
+
+	info->baud = baud_table[i];
+	uart_speed();
+	start_rx();
+	tx_start(info->uart, info->use_ints);
+	return;
+}
+
+
+static void do_serial_hangup(void *private_)
+{
+	struct cnxt_serial	*info = (struct cnxt_serial *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	tty_hangup(tty);
+}
+
+
+static int startup(struct cnxt_serial * info)
+{
+	unsigned long flags;
+	
+	if (info->flags & S_INITIALIZED)
+		return 0;
+
+	if (!info->xmit_buf) {
+		info->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL);
+		if (!info->xmit_buf)
+			return -ENOMEM;
+	}
+
+	save_flags(flags); cli();
+
+#if 0
+	/*
+	 * Clear the FIFO buffers and disable them
+	 * (they will be reenabled in change_speed())
+	 */
+
+	USTCNT = USTCNT_UEN;
+	info->xmit_fifo_size = 1;
+	USTCNT = USTCNT_UEN | USTCNT_RXEN | USTCNT_TXEN;
+	(void)URX;
+
+	/*
+	 * Finally, enable sequencing and interrupts
+	 */
+
+#ifdef USE_INTS
+	USTCNT = USTCNT_UEN | USTCNT_RXEN | 
+                 USTCNT_RX_INTR_MASK | USTCNT_TX_INTR_MASK;
+#else
+	USTCNT = USTCNT_UEN | USTCNT_RXEN | USTCNT_RX_INTR_MASK;
+#endif
+#endif
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+
+	/*
+	 * and set the speed of the serial port
+	 */
+#if 0
+	change_speed(info);
+#endif
+	info->flags |= S_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+}
+
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file * filp,
+			   struct cnxt_serial *info)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int		retval;
+	int		do_clocal = 0;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (info->flags & S_CLOSING) {
+		interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		if (info->flags & S_HUP_NOTIFY)
+			return -EAGAIN;
+		else
+			return -ERESTARTSYS;
+#else
+		return -EAGAIN;
+#endif
+
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & S_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+		    (info->flags & S_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+		    return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+		    (info->flags & S_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+		    return -EBUSY;
+		info->flags |= S_CALLOUT_ACTIVE;
+		return 0;
+	}
+	
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & S_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= S_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & S_CALLOUT_ACTIVE) {
+		if (info->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+	
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, info->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+
+	info->count--;
+	info->blocked_open++;
+	while (1) {
+		cli();
+		if (!(info->flags & S_CALLOUT_ACTIVE))
+		  //m68k_rtsdtr(info, 1);
+		
+		sti();
+		current->state = TASK_INTERRUPTIBLE;
+		if (tty_hung_up_p(filp) ||
+		    !(info->flags & S_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & S_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;	
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & S_CALLOUT_ACTIVE) &&
+		    !(info->flags & S_CLOSING) && do_clocal)
+			break;
+                if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&info->open_wait, &wait);
+	if (!tty_hung_up_p(filp))
+		info->count++;
+	info->blocked_open--;
+
+	if (retval)
+		return retval;
+	info->flags |= S_NORMAL_ACTIVE;
+	return 0;
+}	
+
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its S structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+int rs_open(struct tty_struct *tty, struct file * filp)
+{
+	int 		  retval, line;
+	struct cnxt_serial *info;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+
+	
+	if (line != 0) /* we have exactly one */
+		return -ENODEV;
+
+	info = &uart_info;
+
+	if (serial_paranoia_check(info, tty->device, "rs_open"))
+		return -ENODEV;
+
+	info->count++;
+	tty->driver_data = info;
+	info->tty = tty;
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval)
+		return retval;
+	
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+
+		printk("rs_open returning after block_til_ready with %d\n",
+		       retval);
+		return retval;
+	}
+
+	if ((info->count == 1) && (info->flags & S_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->normal_termios;
+		else 
+			*tty->termios = info->callout_termios;
+		change_speed(info);
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+	// Enable GPIO interrupt line for console uart 
+	SetGPIOIntEnable(GPIOINT_UART1, IRQ_ON);
+	return 0;
+}
+
+
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct cnxt_serial * info)
+{
+	unsigned long	flags;
+
+	
+	if (!(info->flags & S_INITIALIZED))
+	  return;
+	
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Shutting down serial port %d (irq %d)....\n", info->line,
+	       info->irq);
+#endif
+	
+	save_flags(flags); cli(); /* Disable interrupts */
+	
+	if (info->xmit_buf) {
+		free_page((unsigned long) info->xmit_buf);
+		info->xmit_buf = 0;
+	}
+
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+	
+	info->flags &= ~S_INITIALIZED;
+	restore_flags(flags);
+}
+
+
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+	struct cnxt_serial * info = (struct cnxt_serial *)tty->driver_data;
+	unsigned long flags;
+
+	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+		return;
+	
+	save_flags(flags); cli();
+	
+	if (tty_hung_up_p(filp)) {
+		restore_flags(flags);
+		return;
+	}
+	
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  info->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+		       "info->count is %d\n", info->count);
+		info->count = 1;
+	}
+	if (--info->count < 0) {
+		printk("rs_close: bad serial port count for ttyS%d: %d\n",
+		       info->line, info->count);
+		info->count = 0;
+	}
+	if (info->count) {
+		restore_flags(flags);
+		return;
+	}
+	// closing port so disable interrupts
+	//set_ints_mode(0);
+	info->use_ints = 0;
+
+	info->flags |= S_CLOSING;
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & S_NORMAL_ACTIVE)
+		info->normal_termios = *tty->termios;
+	if (info->flags & S_CALLOUT_ACTIVE)
+		info->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != S_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (tty->ldisc.num != tty_ldiscs[N_TTY].num) {
+		if (tty->ldisc.close)
+			(tty->ldisc.close)(tty);
+		tty->ldisc = tty_ldiscs[N_TTY];
+		tty->termios->c_line = N_TTY;
+		if (tty->ldisc.open)
+			(tty->ldisc.open)(tty);
+	}
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(info->close_delay);
+	}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(S_NORMAL_ACTIVE|S_CALLOUT_ACTIVE|
+			 S_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	restore_flags(flags);
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data;		
+	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+	  return;
+	cli();
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+	sti();
+	wake_up_interruptible(&tty->write_wait);
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+void rs_hangup(struct tty_struct *tty)
+{
+  struct cnxt_serial * info = (struct cnxt_serial *)tty->driver_data;
+	
+  if (serial_paranoia_check(info,tty->device, "rs_hangup"))
+		return;
+	
+	rs_flush_buffer(tty);
+	shutdown(info);
+	info->event = 0;
+	info->count = 0;
+	info->flags &= ~(S_NORMAL_ACTIVE|S_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+
+static int rs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	int	c, total = 0;
+	unsigned long flags;
+	struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data;
+  
+	if (serial_paranoia_check(info,tty->device, "rs_write"))
+	  return 0;
+	
+	if (!tty || !info->xmit_buf)
+	  return 0;
+	
+	save_flags(flags);
+	while (1) {
+	  cli();		
+	  c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+			     SERIAL_XMIT_SIZE - info->xmit_head));
+	  if (c <= 0)
+	    break;
+	  
+	  if (from_user) {
+	    down(&tmp_buf_sem);
+	    copy_from_user(tmp_buf, buf, c);
+	    c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+			   SERIAL_XMIT_SIZE - info->xmit_head));
+	    memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
+	    up(&tmp_buf_sem);
+	  } else
+	    memcpy(info->xmit_buf + info->xmit_head, buf, c);
+	  
+	  info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+	  
+	  info->xmit_cnt += c;
+	  restore_flags(flags);
+	  buf += c;
+	  count -= c;
+	  total += c;
+	}
+	
+	if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped ){
+	  /* Enable transmitter */
+	  cli();		
+
+		if(!info->use_ints){	
+			while(info->xmit_cnt) {
+				wait_EOT(info->uart);
+				/* Send char */
+				info->uart->fifo = info->xmit_buf[info->xmit_tail++];
+				info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+				info->xmit_cnt--;
+			}
+		}else{
+			if (info->xmit_cnt){
+				/* Send char */
+				wait_EOT(info->uart);
+				xmit_string(info,&info->xmit_buf[info->xmit_tail], info->xmit_cnt);
+				info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+				info->xmit_cnt=0;
+			}
+		}
+		restore_flags(flags);
+	} 
+
+
+	restore_flags(flags);
+	return total;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	int	ret;
+	struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data;
+	if (serial_paranoia_check(info,tty->device, "rs_write_room"))
+		return 0;
+	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
+	if (ret < 0)
+		ret = 0;
+	return ret;
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+		return 0;
+	return info->xmit_cnt;
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
+		return;
+	if(!info->use_ints){	
+		for(;;) {
+			if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
+				!info->xmit_buf)
+				return;
+
+			/* Enable transmitter */
+			save_flags(flags); cli();
+			tx_start(info->uart,info->use_ints);
+		}
+	}else{
+		if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
+			!info->xmit_buf)
+			return;
+
+			/* Enable transmitter */
+		save_flags(flags); cli();
+		tx_start(info->uart, info->use_ints);
+	}
+
+	if(!info->use_ints)	
+		wait_EOT(info->uart);
+		/* Send char */
+	//xmit_char(info->xmit_buf[info->xmit_tail++]);
+	xmit_string(info,(char *)&info->xmit_buf[info->xmit_tail++],1);
+	info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+	info->xmit_cnt--;
+	
+	restore_flags(flags);
+}
+
+
+
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct cnxt_serial	*info = (struct cnxt_serial *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+#if 0
+	if (clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+	}
+#endif   
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void send_break(	struct cnxt_serial * info, int duration)
+{
+#if 0
+	current->state = TASK_INTERRUPTIBLE;
+	current->timeout = jiffies + duration;
+	cli();
+	sti();
+#else
+	printk("send_break\n");
+#endif
+}
+
+static int get_serial_info(struct cnxt_serial * info,
+			   struct serial_struct * retinfo)
+{
+	struct serial_struct tmp;
+  
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = info->type;
+	tmp.line = info->line;
+	tmp.port = info->port;
+	tmp.irq = info->irq;
+	tmp.flags = info->flags;
+	tmp.baud_base = info->baud_base;
+	tmp.close_delay = info->close_delay;
+	tmp.closing_wait = info->closing_wait;
+	tmp.custom_divisor = info->custom_divisor;
+	copy_to_user(retinfo,&tmp,sizeof(*retinfo));
+	return 0;
+}
+
+
+static int set_serial_info(struct cnxt_serial * info,
+			   struct serial_struct * new_info)
+{
+	struct serial_struct new_serial;
+	struct cnxt_serial old_info;
+	int 			retval = 0;
+
+	if (!new_info)
+		return -EFAULT;
+	copy_from_user(&new_serial,new_info,sizeof(new_serial));
+	old_info = *info;
+
+	if (!suser()) {
+		if ((new_serial.baud_base != info->baud_base) ||
+		    (new_serial.type != info->type) ||
+		    (new_serial.close_delay != info->close_delay) ||
+		    ((new_serial.flags & ~S_USR_MASK) !=
+		     (info->flags & ~S_USR_MASK)))
+			return -EPERM;
+		info->flags = ((info->flags & ~S_USR_MASK) |
+			       (new_serial.flags & S_USR_MASK));
+		info->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	if (info->count > 1)
+		return -EBUSY;
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+	info->baud_base = new_serial.baud_base;
+	info->flags = ((info->flags & ~S_FLAGS) |
+			(new_serial.flags & S_FLAGS));
+	info->type = new_serial.type;
+	info->close_delay = new_serial.close_delay;
+	info->closing_wait = new_serial.closing_wait;
+
+check_and_exit:
+	retval = startup(info);
+	return retval;
+}
+
+
+static int get_lsr_info(struct cnxt_serial * info, unsigned int *value)
+{
+	unsigned char status;
+
+	status = 0;
+	put_user(status,value);
+	return 0;
+}
+
+
+static void rs_throttle(struct tty_struct * tty)
+{
+	struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+		return;
+	
+	if (I_IXOFF(tty))
+		info->x_char = STOP_CHAR(tty);
+
+	/* Turn off RTS line (do this atomic) */
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+	struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+		return;
+#if 0	
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			info->x_char = START_CHAR(tty);
+	}
+#endif
+	/* Assert RTS line (do this atomic) */
+}
+
+static int rs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	int error;
+	struct cnxt_serial * info = (struct cnxt_serial *)tty->driver_data;
+	int retval;
+
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
+	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+	
+	switch (cmd) {
+		case TCSBRK:	/* SVID version: non-zero arg --> no break */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (!arg)
+				send_break(info, HZ/4);	/* 1/4 second */
+			return 0;
+		case TCSBRKP:	/* support for POSIX tcsendbreak() */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+			return 0;
+		case TIOCGSOFTCAR:
+			error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long));
+			if (error)
+				return error;
+			put_user(C_CLOCAL(tty) ? 1 : 0,
+				    (unsigned long *) arg);
+			return 0;
+		case TIOCSSOFTCAR:
+			get_user(arg, (unsigned long *) arg);
+			tty->termios->c_cflag =
+				((tty->termios->c_cflag & ~CLOCAL) |
+				 (arg ? CLOCAL : 0));
+			return 0;
+		case TIOCGSERIAL:
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+						sizeof(struct serial_struct));
+			if (error)
+				return error;
+			return get_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSSERIAL:
+			return set_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSERGETLSR: /* Get line status register */
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+				sizeof(unsigned int));
+			if (error)
+				return error;
+			else
+			    return get_lsr_info(info, (unsigned int *) arg);
+
+		case TIOCSERGSTRUCT:
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+						sizeof(struct cnxt_serial));
+			if (error)
+				return error;
+			copy_to_user((struct cnxt_serial *) arg,
+				    info, sizeof(struct cnxt_serial));
+			return 0;
+			
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+
+static void rs_stop(struct tty_struct *tty)
+{
+	struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_stop"))
+		return;
+#if 0
+	save_flags(flags); cli();
+	tx_stop(info->uart);
+	restore_flags(flags);
+#endif
+
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+	unsigned long flags;
+	struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info,tty->device, "rs_start"))
+		return;
+	
+	save_flags(flags);
+	cli();
+	tx_start(info->uart, info->use_ints);
+	start_rx();
+	restore_flags(flags);
+}
+
+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data;
+
+	if (tty->termios->c_cflag == old_termios->c_cflag)
+		return;
+
+	change_speed(info);
+
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+	
+}
+
+
+static void rs_set_ldisc(struct tty_struct *tty)
+{
+	struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_set_ldisc"))
+		return;
+
+	info->is_cons = (tty->termios->c_line == N_TTY);
+	
+	printk("ttyS%d console mode %s\n", info->line, info->is_cons ? "on" : "off");
+}
+
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static void rs_sched_event(struct cnxt_serial *info, int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_serial);
+	mark_bh(SERIAL_BH);
+}
+
+static inline void receive_chars(struct cnxt_serial *info, unsigned long status)
+{
+	unsigned char ch;
+
+	struct uart_regs *uart = info->uart;
+	
+#if 0
+	// hack to receive chars by polling from anywhere
+	struct tty_struct *tty = info->tty;
+	if (!(info->flags & S_INITIALIZED))
+		return;
+#else
+	struct tty_struct *tty = info->tty;
+	if (!(info->flags & S_INITIALIZED))
+		return;
+#endif	
+	
+	ch = (unsigned char)uart->fifo;
+
+	if(info->is_cons)
+	{
+		
+		if (ch == 0x10)
+		{ 
+			show_state();
+			show_free_areas();
+			show_buffers();
+			//show_net_buffers();
+			return;
+		}
+		else if (ch == 0x12)
+		{ 
+			HARD_RESET_NOW();
+			return;
+		}
+	}
+
+	/* Look for kgdb 'stop' character, consult the gdb documentation
+	 * for remote target debugging and arch/sparc/kernel/sparc-stub.c
+	 * to see how all this works.
+	 */
+
+	
+	if(!tty)
+	{
+	  printk("no tty\n");
+	  goto clear_and_exit;
+	}
+#if 0
+	if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+		queue_task_irq_off(&tty->flip.tqueue, &tq_timer);
+	tty->flip.count++;
+	if(status & US_PARE)
+		*tty->flip.flag_buf_ptr++ = TTY_PARITY;
+	else if(status & US_OVRE)
+		*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+	else if(status & US_FRAME)
+		*tty->flip.flag_buf_ptr++ = TTY_FRAME;
+	else
+		*tty->flip.flag_buf_ptr++ = 0; 
+#endif
+        tty->flip.count++;
+        *tty->flip.flag_buf_ptr++ = 0;
+	*tty->flip.char_buf_ptr++ = ch;
+
+	
+	queue_task(&tty->flip.tqueue, &tq_timer);
+	
+
+clear_and_exit:
+	
+	return;
+}
+
+
+static inline void transmit_chars(struct cnxt_serial *info)
+{
+  struct uart_regs *uart = info->uart;
+
+	if (info->x_char) {
+		/* Send next char */
+	  //xmit_char(info->x_char);
+		uart->fifo=info->x_char;		
+		info->x_char = 0;
+		goto clear_and_return;
+	}
+
+	if((info->xmit_cnt <= 0) || info->tty->stopped) {
+		/* That's peculiar... */
+		goto clear_and_return;
+	}
+
+	/* Send char */
+	//xmit_char(info->xmit_buf[info->xmit_tail++]);
+	info->uart->fifo=info->xmit_buf[info->xmit_tail++];
+	
+	info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+	info->xmit_cnt--;
+
+	if (info->xmit_cnt < 256)
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+	if(info->xmit_cnt <= 0) {
+		goto clear_and_return;
+	}
+
+clear_and_return:
+	/* Clear interrupt (should be auto)*/
+	return;
+}
+
+
+
+void rs_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+{
+	char status;
+
+	struct cnxt_serial * info = &uart_info;
+  	struct uart_regs *uart = uart_info.uart;
+  	
+	status = (uart->iir & 0x0f); /* only concerned w/ lower nibble */
+	
+	if (status == ISR_Tx_Rdy_Source) {
+		transmit_chars(info);
+	}
+	if ((status == ISR_Rx_Rdy_Source) ||
+            (status == ISR_Rx_Rdy_TO_Src )){
+		receive_chars(info,status);
+	}
+	#if 0
+		if(!info->use_ints){
+			serialpoll.data = (void *)&sp_uart_info;		
+			queue_task_irq_off(&serialpoll, &tq_timer);
+		}
+	#endif
+
+
+	return;
+}
+
+
+static int __init
+rs_cnxt_init(void)
+{
+	int flags;
+	struct cnxt_serial *info;
+		
+	/* Setup base handler, and timer table. */
+	init_bh(SERIAL_BH, do_serial_bh);
+	
+	/* Initialize the tty_driver structure */
+	
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+	serial_driver.name = "ttyS";
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64;
+	serial_driver.num = 1;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+	serial_driver.init_termios.c_cflag = 
+			B57600 | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = rs_open;
+	serial_driver.close = rs_close;
+	serial_driver.write = rs_write;
+	serial_driver.put_char = rs_put_char;
+	serial_driver.flush_chars = rs_flush_chars;
+	serial_driver.write_room = rs_write_room;
+	serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	serial_driver.flush_buffer = rs_flush_buffer;
+	serial_driver.ioctl = rs_ioctl;
+	serial_driver.throttle = rs_throttle;
+	serial_driver.unthrottle = rs_unthrottle;
+	serial_driver.set_termios = rs_set_termios;
+	serial_driver.stop = rs_stop;
+	serial_driver.start = rs_start;
+	serial_driver.hangup = rs_hangup;
+	serial_driver.set_ldisc = rs_set_ldisc;
+
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+	callout_driver.name = "cua";
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register serial driver\n");
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+	
+	save_flags(flags); cli();
+
+
+	info = &uart_info;
+	info->magic = SERIAL_MAGIC;
+	info->uart = (struct uart_regs*)UART0_Base_Addr;
+	info->port = UART0_Base_Addr;
+	info->tty = 0;
+	info->irq = CNXT_INT_LVL_GPIO;
+	info->custom_divisor = 16;
+	info->close_delay = 50;
+	info->closing_wait = 3000;
+	info->x_char = 0;
+	info->event = 0;
+	info->count = 0;
+	info->blocked_open = 0;
+	info->tqueue.routine = do_softint;
+	info->tqueue.data = info;
+	info->tqueue_hangup.routine = do_serial_hangup;
+	info->tqueue_hangup.data = info;
+	info->callout_termios =callout_driver.init_termios;
+	info->normal_termios = serial_driver.init_termios;
+	init_waitqueue_head(&info->open_wait);
+	init_waitqueue_head(&info->close_wait);
+	info->line = 0;
+	info->is_cons = 1; /* Means shortcuts work */
+
+	printk("%s%d at 0x%08x (irq = %d)", serial_driver.name, info->line, 
+	       info->port, info->irq);
+       printk(" is a 16c550 UART\n");
+       printk("info = %08x\n",info);
+       
+#if DEBUG_CONSOLE_ON_UART_2
+	SetGPIOIntEnable( GPIO25, IRQ_OFF );
+	SetGPIOInputEnable( GPIO25, GP_INPUTOFF );
+#endif
+
+	SetGPIOIntEnable(GPIOINT_UART1, IRQ_OFF);
+	SetGPIODir( GPIOINT_UART1, GP_INPUT );
+	SetGPIOIntPolarity (GPIOINT_UART1, GP_IRQ_POL_POSITIVE);
+	SetGPIOInputEnable( GPIOINT_UART1, GP_INPUTON );
+
+	GPIO_SetGPIOIRQRoutine(GPIOINT_UART1, GPIOB25_Handler);
+	SetGPIOIntEnable(GPIOINT_UART1, IRQ_ON);
+	
+	restore_flags(flags);
+
+	return 0;
+}
+
+
+
+module_init(rs_cnxt_init);
+
+
+
+
diff -urN linux-2.4.29/drivers/char/cnxtserial.h linux-2.4.29-uc1/drivers/char/cnxtserial.h
--- linux-2.4.29/drivers/char/cnxtserial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/cnxtserial.h	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,309 @@
+/****************************************************************************
+*
+*	Name:			cnxtserial.h
+*
+*	Description:	Provides serial port character I/O (16550) definitions
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author: Richarjc $
+*  $Revision: 4 $
+*  $Modtime: 10/25/02 10:52a $
+****************************************************************************/
+
+#ifndef _CNXTSERIAL_H
+#define _CNXTSERIAL_H
+
+#include <linux/config.h>
+#include <asm/page.h>
+
+
+struct uart_regs
+{
+   volatile unsigned short  fifo;
+   volatile unsigned short  irqe;
+   volatile unsigned short  iir;
+   volatile unsigned short  line_ctrl;
+   volatile unsigned short  modem_ctrl;
+   volatile unsigned short  line_status_reg;
+   volatile unsigned short  msr;
+   volatile unsigned short  scratch;
+};
+
+//#define UART_GPIO_LINE  (1 << 10)
+#define UART_GPIO_LINE  (1 << 9) // gpio25
+
+/*******************************************************************************/
+/* Interrupt Status Register - ISR                                             */
+/*******************************************************************************/
+
+/* ISR b0 indicates that an interrupt is pending when clear. b3 - b1 signal which interrupt as per:- */
+
+#define ISR_LSR_Source      0x06   /* 0 1 1 - Receiver Line Status Register Priority 1 */
+#define ISR_Rx_Rdy_Source   0x04   /* 0 1 0 - Received Data Ready           Priority 2 */
+#define ISR_Rx_Rdy_TO_Src   0x0c   /* 1 1 0 - Received Data Ready Time Out  Priority 2 */
+#define ISR_Tx_Rdy_Source   0x02   /* 0 0 1 - Transmitter Holding Reg Empty Priority 3 */
+#define ISR_MODEM_Source    0x00   /* 0 0 0 - Modem Status Register         Priority 4 */
+
+/* ISR b7 - b4 are not used - in st16c552 b7 - b6 are Set b5 - b4 are Clear   */
+
+/*******************************************************************************/
+/* Interrupt Enable Register - IER                                             */
+/*******************************************************************************/
+#define IER_Rx_Holding_Reg  0x01   /* b0 - Receive Holding Register Interrupt  - Enabled When Set   */
+#define IER_Tx_Holding_Reg  0x02   /* b1 - Transmit Holding Register Interrupt - Enabled When Set   */
+#define IER_Rx_Line_Stat    0x04   /* b2 - Receiver Line Status Interrupt      - Enabled When Set   */
+#define IER_Modem_Status    0x08   /* b3 - Modem Status Register Interrupt     - Enabled When Set   */
+                                   /* b7 - b4 are not used and are set to zero                    */
+
+/*******************************************************************************/
+/* Line Status Register - LSR                                                                              */
+/*******************************************************************************/
+
+#define LSR_Rx_Data_Ready   0x01   /* b0 - Data Received and Saved in Holding Reg - Set when Valid */
+#define LSR_Overrun_Error   0x02   /* b1 - Overrun Error Occured                  - Set When Valid */
+#define LSR_Parity_Error    0x04   /* b2 - Received Data has Incorrect Parity     - Set When Valid */
+#define LSR_Framing_Error   0x08   /* b3 - Framing Error (No Stop Bit)            - Set When Valid */
+#define LSR_Break_Interrupt 0x10   /* b4 - Break Signal Received                  - Set When Valid */
+#define LSR_Tx_Hold_Empty   0x20   /* b5 - Tx Holding Register is empty and ready - Set When Valid */
+#define LSR_Tx_Fifo_Empty   0x40   /* b6 - Tx Shift Registers and FIFO are Empty  - Set When Valid */
+#define LSR_Fifo_Error      0x80   /* b7 - At Least one of b4 - b2 has occurred   - Set When Valid */
+
+/*******************************************************************************/
+/*  Latch Control Register - LCR                                               */
+/*******************************************************************************/
+
+/* LCR b2 defines the stop bits setup b1 - b0 define the Tx - Rx Word Length                        */
+/* The following defines cover all of the available options                                         */
+
+#define LCR_5_Bit_Word_1    0x00   /* 0 0 0  - 5 Bit Word - 1 Stop Bit   */
+#define LCR_6_Bit_Word_1    0x01   /* 0 0 1  - 6 Bit Word - 1 Stop Bit   */ 
+#define LCR_7_Bit_Word_1    0x02   /* 0 1 0  - 7 Bit Word - 1 Stop Bit   */
+#define LCR_8_Bit_Word_1    0x03   /* 0 1 1  - 8 Bit Word - 1 Stop Bit   */
+#define LCR_5_Bit_Word_1p5  0x04   /* 1 0 0  - 5 Bit Word - 1.5 Stop Bit */
+#define LCR_6_Bit_Word_2    0x05   /* 1 0 1  - 6 Bit Word - 2 Stop Bit   */
+#define LCR_7_Bit_Word_2    0x06   /* 1 1 0  - 6 Bit Word - 1 Stop Bit   */
+#define LCR_8_Bit_Word_2    0x07   /* 1 1 1  - 6 Bit Word - 1 Stop Bit   */
+
+#define LCR_Parity_Enable   0x08   /* b3 - Enable Parity Bit Generation and Check - Enabled When Set */
+#define LCR_Parity_Even     0x10   /* b4 - Odd/Even Parity Generation and Check   - Even When Set    */
+#define LCR_Parity_Set      0x20   /* b5 - Toggle Generated Parity Bit 0/1        - 0 When Set       */
+#define LCR_Break_Set       0x40   /* b6 - Force Break Control ( Tx o/p low)      - Forced When Set  */
+#define LCR_Divisor_Latch   0x80   /* b7 - Enable Internal Baud Rate Latch        - Enabled When Set */
+
+
+#if DEBUG_CONSOLE_ON_UART_2
+	#ifdef CONFIG_BD_RUSHMORE
+		#define UART0_Base_Addr    0x002C0010
+	#endif
+	#ifdef CONFIG_BD_HASBANI
+		#define UART0_Base_Addr    0x002C0010
+	#endif
+	#ifdef CONFIG_BD_MACKINAC
+		#define UART0_Base_Addr    0x00290000
+	#endif
+#else
+	#if CONFIG_CHIP_CX82100 && PLD_CS4_UART_v100
+		// Needed to accomodate a programming error in the
+		// current PLD code of the Oakland board that maps
+		// the UART to 0x2C1000.  This error should go away
+		// someday, hopefully.
+		#define UART0_Base_Addr    0x002C1000
+	#else
+		#define UART0_Base_Addr    0x002C0000
+	#endif
+#endif
+
+/*  We use a 1.8432Mhz clk */
+#define UART_CLK    1843200
+#define UART_2400   ((UART_CLK)/(16*2400))
+#define UART_4800   ((UART_CLK)/(16*4800))
+#define UART_9600   ((UART_CLK)/(16*9600))
+#define UART_19200  ((UART_CLK)/(16*19200))
+#define UART_38400  ((UART_CLK)/(16*38400))
+#define UART_57600  ((UART_CLK)/(16*57600))
+#define UART_115200  ((UART_CLK)/(16*115200))
+
+#define UART_CTRL       (UART0_Base_Addr+ )
+#define UART_BRD        (UART0_Base_Addr+ )
+#define UART_DBUF       (UART0_Base_Addr+ )
+#define UART_ISR        (UART0_Base_Addr+ )
+
+/*******************************************************************************/
+/* FIFO Control Register - FCR                                                 */
+/*******************************************************************************/
+#define FCR_Fifo_Enable     0x01   /* b0 - Tx and Rx FIFO Enable               - Enabled When Set   */
+#define FCR_Rx_Fifo_Reset   0x02   /* b1 - Clear Rx FIFO and reset its counter - Clears When Set    */
+#define FCR_Tx_Fifo_Reset   0x04   /* b2 - Clear Tx FIFO and reset its counter - Clears When Set    */
+#define FCR_DMA_Mode_Select 0x08   /* b3 - Change DMA Mode State from m0 to m1 - Mode 1 When Set    */
+
+/* FCR b7 - b6 FIFO Trigger Level  */
+ 
+#define FCR_Rx_Trig_Lvl_01  0x00   /* 0 0 - FIFO Rx Trigger Level 01 */              
+#define FCR_Rx_Trig_Lvl_04  0x40   /* 0 1 - FIFO Rx Trigger Level 04 */          
+#define FCR_Rx_Trig_Lvl_08  0x80   /* 1 0 - FIFO Rx Trigger Level 08 */
+#define FCR_Rx_Trig_Lvl_16  0xc0   /* 1 1 - FIFO Rx Trigger Level 16 */
+
+
+#define BIT24            0x01000000
+#define CNXT_INT_LVL_GPIO  24       /* GPIO interrupts */
+
+struct serial_struct {
+	int	type;
+	int	line;
+	int	port;
+	int	irq;
+	int	flags;
+	int	xmit_fifo_size;
+	int	custom_divisor;
+	int	baud_base;
+	unsigned short	close_delay;
+	char	reserved_char[2];
+	int	hub6;  /* FIXME: We don't have AT&T Hub6 boards! */
+	unsigned short	closing_wait; /* time to wait before closing */
+	unsigned short	closing_wait2; /* no longer used... */
+	int	reserved[4];
+};
+
+/*
+ * For the close wait times, 0 means wait forever for serial port to
+ * flush its output.  65535 means don't wait at all.
+ */
+#define S_CLOSING_WAIT_INF	0
+#define S_CLOSING_WAIT_NONE	65535
+
+/*
+ * Definitions for S_struct (and serial_struct) flags field
+ */
+#define S_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes 
+				   on the callout port */
+#define S_FOURPORT  0x0002	/* Set OU1, OUT2 per AST Fourport settings */
+#define S_SAK	0x0004	/* Secure Attention Key (Orange book) */
+#define S_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
+
+#define S_SPD_MASK	0x0030
+#define S_SPD_HI	0x0010	/* Use 56000 instead of 38400 bps */
+
+#define S_SPD_VHI	0x0020  /* Use 115200 instead of 38400 bps */
+#define S_SPD_CUST	0x0030  /* Use user-specified divisor */
+
+#define S_SKIP_TEST	0x0040 /* Skip UART test during autoconfiguration */
+#define S_AUTO_IRQ  0x0080 /* Do automatic IRQ during autoconfiguration */
+#define S_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
+#define S_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
+#define S_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
+
+#define S_FLAGS	0x0FFF	/* Possible legal S flags */
+#define S_USR_MASK 0x0430	/* Legal flags that non-privileged
+				 * users can set or reset */
+
+/* Internal flags used only by kernel/chr_drv/serial.c */
+#define S_INITIALIZED	0x80000000 /* Serial port was initialized */
+#define S_CALLOUT_ACTIVE	0x40000000 /* Call out device is active */
+#define S_NORMAL_ACTIVE	0x20000000 /* Normal device is active */
+#define S_BOOT_AUTOCONF	0x10000000 /* Autoconfigure port on bootup */
+#define S_CLOSING		0x08000000 /* Serial port is closing */
+#define S_CTS_FLOW		0x04000000 /* Do CTS flow control */
+#define S_CHECK_CD		0x02000000 /* i.e., CLOCAL */
+
+/* Software state per channel */
+
+#ifdef __KERNEL__
+/*
+ * This is our internal structure for each serial port's state.
+ * 
+ * Many fields are paralleled by the structure used by the serial_struct
+ * structure.
+ *
+ * For definitions of the flags field, see tty.h
+ */
+
+struct cnxt_serial {
+	char soft_carrier;  /* Use soft carrier on this channel */
+	char break_abort;   /* Is serial console in, so process brk/abrt */
+	char is_cons;       /* Is this our console. */
+
+	/* We need to know the current clock divisor
+	 * to read the bps rate the chip has currently
+	 * loaded.
+	 */
+	unsigned char clk_divisor;  /* May be 1, 16, 32, or 64 */
+	int baud;
+	int			magic;
+	int			baud_base;
+	int			port;
+	int			irq;
+	int			irqmask;
+	int			flags; 		/* defined in tty.h */
+	int			type; 		/* UART type */
+	int			use_ints;
+	struct uart_regs	*uart;
+	struct tty_struct 	*tty;
+	int			read_status_mask;
+	int			ignore_status_mask;
+	int			timeout;
+	int			xmit_fifo_size;
+	int			custom_divisor;
+	int			x_char;	/* xon/xoff character */
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int			count;	    /* # of fd on device */
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+	unsigned char 		*xmit_buf;
+	unsigned char 		*rx_buf;
+	int			xmit_head;
+	int			xmit_tail;
+	int			xmit_cnt;
+	struct tq_struct	tqueue;
+	struct tq_struct	tqueue_hangup;
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+  //struct wait_queue	*open_wait;
+  //struct wait_queue	*close_wait;
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+};
+
+
+#define SERIAL_MAGIC 0x5301
+
+/*
+ * The size of the serial xmit buffer is 1 page, or 4096 bytes
+ */
+#define SERIAL_XMIT_SIZE	PAGE_SIZE
+#define SERIAL_RX_SIZE		PAGE_SIZE
+
+/*
+ * Events are used to schedule things to happen at timer-interrupt
+ * time, instead of at rs interrupt time.
+ */
+#define RS_EVENT_WRITE_WAKEUP	0
+
+#endif /* __KERNEL__ */
+
+
+
+#endif 
diff -urN linux-2.4.29/drivers/char/Config.in linux-2.4.29-uc1/drivers/char/Config.in
--- linux-2.4.29/drivers/char/Config.in	2004-08-08 00:26:04.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/Config.in	2005-06-14 02:12:17.000000000 +0100
@@ -4,12 +4,284 @@
 mainmenu_option next_comment
 comment 'Character devices'
 
+#############################################################################
+#
+# uClinux options
+#
+
+if [ "$CONFIG_EXCALIBUR" = "y" ]; then
+  bool 'Nios serial support' CONFIG_NIOS_SERIAL
+  bool 'Nios SPI device support' CONFIG_NIOS_SPI
+fi
+
+if [ "$CONFIG_M68328" = "y" ]; then
+  bool '68328 serial support' CONFIG_68328_SERIAL
+  if [ "$CONFIG_68328_SERIAL" = "y" ]; then
+    bool 'Support RTS/CTS on 68328 serial support' CONFIG_68328_SERIAL_RTS_CTS
+  fi
+  if [ "$CONFIG_PILOT" = "y" ]; then
+    bool '68328 digitizer support' CONFIG_68328_DIGI
+  fi
+fi
+
+if [ "$CONFIG_M68EZ328" = "y" ]; then
+  bool '68328 serial support' CONFIG_68328_SERIAL
+  if [ "$CONFIG_68328_SERIAL" = "y" ]; then
+    bool 'Support RTS/CTS on 68328 serial support' CONFIG_68328_SERIAL_RTS_CTS
+  fi
+  if [ "$CONFIG_M68EZ328ADS" = "y" ]; then
+    bool '68681 serial support' CONFIG_68681_SERIAL
+  fi
+  bool '68328 digitizer support' CONFIG_68328_DIGI
+fi
+
+if [ "$CONFIG_M68VZ328" = "y" ]; then
+  bool '68328 serial support' CONFIG_68328_SERIAL
+  if [ "$CONFIG_68328_SERIAL" = "y" ]; then
+    bool 'Enable RTS/CTS support on 1st 68328 serial port' CONFIG_68328_SERIAL_RTS_CTS
+    bool 'Enable second 68328 serial support' CONFIG_68328_SERIAL_UART2
+    if [ "$CONFIG_68328_SERIAL_UART2" = "y" ]; then
+        bool 'Enable RTS/CTS support on 2nd 68328 serial port' CONFIG_68328_SERIAL_UART2_RTS_CTS
+    fi
+  fi
+  if [ "$CONFIG_DRAGONIXVZ" = "y"]; then
+    bool 'Dragonix VZ SPI driver' CONFIG_DRAGONIX_SPI
+  fi
+  if [ "$CONFIG_DRAGEN2" = "y" ]; then
+    tristate 'DragonEngine EEPROM driver' CONFIG_DRAGEN2_EEPROM
+    tristate 'DragonEngine Touchscreen driver' CONFIG_DRAGEN2_TS
+    tristate 'DragonEngine FPGA driver' CONFIG_DRAGEN2_FPGA
+  fi
+fi
+
+if [ "$CONFIG_M68332" = "y" ]; then
+  bool '68332 serial support' CONFIG_68332_SERIAL
+fi
+
+if [ "$CONFIG_M68EN302" = "y" ]; then
+  bool '68302 serial support' CONFIG_68302_SERIAL
+fi
+
+if [ "$CONFIG_360QUICC" = "y" ];then
+  bool 'Support UART on MC68360 SMC' CONFIG_M68360_SMC_UART
+  bool 'Support UART on MC68360 SCC' CONFIG_M68360_SCC_UART
+  if [ "$CONFIG_M68360_SMC_UART" = "y" -o "$CONFIG_M68360_SCC_UART" = "y" ]; then
+      define_bool CONFIG_M68360_UART y
+  fi
+  if [ "$CONFIG_M68360_SMC_UART" = "y" ]; then
+    bool '68360 Serial console' CONFIG_SERIAL_CONSOLE
+    # This is entirely the wrong way to do this :(
+    if [ "$CONFIG_SERIAL_CONSOLE" = "y" ]; then
+      choice 'Initial serial console speed' \
+        "9600   CONFIG_CONSOLE_9600 \
+        19200  CONFIG_CONSOLE_19200 \
+        115200 CONFIG_CONSOLE_115200" 19200
+    fi
+  fi
+fi
+
+if [ "$CONFIG_COLDFIRE" = "y" ]; then
+  bool 'MCF5272 USB support' CONFIG_COLDFIRE_USB
+  bool 'ColdFire serial support' CONFIG_COLDFIRE_SERIAL
+  if [ "$CONFIG_DEVELER_CDB4" = "y" ]; then
+    bool '16C554 serial support for AEP CDB4 board' CONFIG_SERIAL_CDB4
+  fi
+  bool 'ColdFire MBUS Support' CONFIG_MCF_MBUS
+  tristate 'ColdFire QSPI Support' CONFIG_MCF_QSPI
+  bool 'Support for TEXT based LCD driver' CONFIG_LCDTXT
+  bool 'Support for ColdFire DMA driven LCD driver' CONFIG_LCDDMA
+  bool 'Support for ColdFire DMA driven DAC0800 driver' CONFIG_DAC0800
+  bool 'Support for ColdFire 5249 audio' CONFIG_M5249AUDIO
+  bool 'Support for ColdFire 5272 audio' CONFIG_M5272AUDIO
+  bool 'Support for ColdFire DMA driven I2S DAC driver' CONFIG_DACI2S
+  bool 'Support for ColdFire T6963 driver' CONFIG_T6963
+  if [ "$CONFIG_T6963" = "y" ]; then
+    bool '   Use PIO mode' CONFIG_T6963_PIO
+    if [ "$CONFIG_T6963_PIO" != "y" ]; then
+      define_bool CONFIG_T6963_DMA y
+    fi
+  fi
+  bool 'Expansion interface driver' CONFIG_EXP
+  bool 'Reset switch support' CONFIG_RESETSWITCH
+  tristate 'ColdFire Watchdog Timer Support' CONFIG_MCFWATCHDOG
+fi
+
+if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
+   bool 'ARM AMBA serial port support' CONFIG_SERIAL_AMBA
+   if [ "$CONFIG_SERIAL_AMBA" = "y" ]; then
+      define_bool CONFIG_SERIAL_INTEGRATOR y
+      bool '  Support for console on Integrator serial port' CONFIG_SERIAL_AMBA_CONSOLE
+   fi
+fi
+
+if [ "$CONFIG_BOARD_SNDS100" = "y" ]; then
+   bool 'Samsung serial port support' CONFIG_SERIAL_SAMSUNG
+   if [ "$CONFIG_SERIAL_SAMSUNG" = "y" ]; then
+      bool '  Support for console on Samsung serial port' CONFIG_SERIAL_SAMSUNG_CONSOLE
+   fi
+fi
+
+if [ "$CONFIG_CPU_S3C3410" = "y" ]; then
+   bool 'Samsung S3C3410X serial ports support' CONFIG_SERIAL_S3C3410
+   if [ "$CONFIG_SERIAL_S3C3410" = "y" ]; then
+      choice 'Serial console device' \
+        "NULL   CONFIG_CONSOLE_NULL \
+         UART   CONFIG_CONSOLE_UART" UART
+      if [ "$CONFIG_CONSOLE_NULL" = "n" ]; then
+         define_bool CONFIG_SERIAL_S3C3410_CONSOLE y
+         if [ "$CONFIG_UCBOOTSTRAP" = "n" ]; then
+            int '   Initial serial console speed' CONFIG_INIT_CONSOLE_SPEED 9600
+         fi
+      fi
+   fi
+fi
+
+if [ "$CONFIG_CPU_S3C44B0X" = "y" ]; then
+   bool 'Samsung S3C44B0X serial ports support' CONFIG_SERIAL_S3C44B0X
+   if [ "$CONFIG_SERIAL_S3C44B0X" = "y" ]; then
+      choice 'Serial console device' \
+        "NULL   CONFIG_CONSOLE_NULL \
+         UART   CONFIG_CONSOLE_UART" UART
+      if [ "$CONFIG_CONSOLE_NULL" = "n" ]; then
+         define_bool CONFIG_SERIAL_S3C44B0X_CONSOLE y
+         if [ "$CONFIG_UCBOOTSTRAP" = "n" ]; then
+            int '   Initial serial console speed' CONFIG_INIT_CONSOLE_SPEED 9600
+         fi
+      fi
+   fi
+fi
+
+if [ "$CONFIG_CPU_S3C4530" = "y" ]; then
+   bool 'Samsung S3C4530a serial ports support' CONFIG_SERIAL_S3C4530
+   if [ "$CONFIG_SERIAL_S3C4530" = "y" ]; then
+      choice 'Serial console device' \
+        "NULL   CONFIG_CONSOLE_NULL \
+         UARTA  CONFIG_CONSOLE_UARTA \
+         UARTB  CONFIG_CONSOLE_UARTB" UARTA
+      if [ "$CONFIG_CONSOLE_NULL" = "n" ]; then
+         define_bool CONFIG_SERIAL_S3C4530_CONSOLE y
+         if [ "$CONFIG_UCBOOTSTRAP" = "n" ]; then
+            int '   Initial serial console speed' CONFIG_INIT_CONSOLE_SPEED 9600
+         fi
+      fi
+   fi
+fi
+
+if [ "$CONFIG_CPU_S3C2500" = "y" ]; then
+   bool 'Samsung S3C2500 serial port support' CONFIG_SERIAL_S3C2500
+   if [ "$CONFIG_SERIAL_S3C2500" = "y" ]; then
+      choice 'Serial console device' \
+        "NULL    CONFIG_CONSOLE_NULL \
+	 CUART   CONFIG_CONSOLE_CUART \
+     	 HUART0  CONFIG_CONSOLE_HUART0 \
+         HUART1  CONFIG_CONSOLE_HUART1" CUART
+      if [ "$CONFIG_CONSOLE_NULL" = "n" ]; then
+         define_bool CONFIG_SERIAL_S3C2500_CONSOLE y
+         if [ "$CONFIG_UCBOOTSTRAP" = "n" ]; then
+            int 'Initial serial console speed' CONFIG_INIT_CONSOLE_SPEED 9600
+    	 fi
+      fi
+   fi
+fi
+
+if [ "$CONFIG_ARCH_CNXT" = "y" ]; then
+    bool 'CNXT Serial (16550 type)' CONFIG_SERIAL_CNXT
+    bool 'CN9414 SPIPE serial port Support' CONFIG_SERIAL_SPIPE
+    bool 'CNXT self-contained flash driver' CONFIG_CNXT_FLASH
+fi
+
+if [ "$CONFIG_ARCH_DSC21" = "y" ]; then
+   bool 'DSC21 serial port support' CONFIG_SERIAL_DSC21
+   if [ "$CONFIG_SERIAL_DSC21" = "y" ]; then
+      bool 'Console on DSC21 serial port' CONFIG_SERIAL_DSC21_CONSOLE
+#      if [ "$CONFIG_SERIAL_DSC21_CONSOLE" = "y" ]; then
+#         int 'Console UART (0 or 1)' CONFIG_SERIAL_DSC21_CONSOLE_UART
+#      fi
+   fi
+fi
+
+if [ "$CONFIG_ARCH_VC547X" = "y" ]; then
+   bool 'C5471 serial port support' CONFIG_SERIAL_C5471
+   if [ "$CONFIG_SERIAL_C5471" = "y" ]; then
+     bool 'Console on C5471 serial port' CONFIG_SERIAL_C5471_CONSOLE
+   else
+     define_bool CONFIG_SERIAL_C5471_CONSOLE n
+   fi
+   tristate 'C5471 watchdog support' CONFIG_C5471_WDT
+   tristate 'C5471 general purpose IO driver support' CONFIG_C5471_GIO
+fi
+
+if [ "$CONFIG_ARCH_DM270" = "y" ]; then
+   bool 'TI TMS320DM270 serial port support' CONFIG_SERIAL_DM270
+   if [ "$CONFIG_SERIAL_DM270" = "y" ]; then
+      bool 'Console on TI TMS320DM270 serial port' CONFIG_SERIAL_DM270_CONSOLE
+   fi
+fi
+
+if [ "$CONFIG_ARCH_NETARM" = "y" ]; then
+   bool 'NET+ARM serial port support' CONFIG_SERIAL_NETARM
+   if [ "$CONFIG_SERIAL_NETARM" = "y" ]; then
+      bool 'Console on NETARM serial port' CONFIG_SERIAL_NETARM_CONSOLE
+   fi
+fi
+
+if [ "$CONFIG_ARCH_KS8695" = "y" ]; then
+   bool 'Kendin/Micrel KS8695 serial port support' CONFIG_SERIAL_KS8695
+   if [ "$CONFIG_SERIAL_KS8695" = "y" ]; then
+      bool 'Console on KS8695 serial port' CONFIG_SERIAL_CONSOLE
+   fi
+fi
+
+if [ "$CONFIG_CPU_H8300H" = "y" -o "$CONFIG_CPU_H8S" = "y" ]; then
+   bool 'Serial (SCI) support' CONFIG_SH_SCI
+   if [ "$CONFIG_SH_SCI" = "y" ]; then
+      bool '  Support for console on serial port' CONFIG_SERIAL_CONSOLE
+   fi
+fi
+
+if [ "$CONFIG_BLACKFIN" = "y" ]; then
+  if [ "$CONFIG_BLACKFIN_EZKIT" = "y" ]; then
+    bool "ADDS-BF533-EZLITE serial port support" CONFIG_SERIAL_BF533
+  else
+    bool "BlackFin BF535 serial port support" CONFIG_SERIAL_BF535
+  fi
+fi
+
+bool 'LED Manager support' CONFIG_LEDMAN
+bool 'SnapGear Watchdog Support' CONFIG_SNAPDOG
+bool 'Fast Timer Support' CONFIG_FAST_TIMER
+
+if [ "$CONFIG_ARCH_EP93XX" = "y" ]; then
+	tristate 'IDE test driver' CONFIG_IDETEST
+fi
+
+if [ "$CONFIG_ARCH_EP93XX" = "y" ]; then
+	tristate 'IDE test driver' CONFIG_IDETEST
+fi
+
+tristate 'DS1302 Real Time Clock support' CONFIG_DS1302
+tristate 'M41T11M6 Real Time Clock support' CONFIG_M41T11M6
+
+#############################################################################
+
 bool 'Virtual terminal' CONFIG_VT
 if [ "$CONFIG_VT" = "y" ]; then
    bool '  Support for console on virtual terminal' CONFIG_VT_CONSOLE
    if [ "$CONFIG_GSC_LASI" = "y" ]; then
       bool '    Support for Lasi/Dino PS2 port' CONFIG_GSC_PS2
    fi
+   if [ "$CONFIG_ARCH_EDB9312" = "y" ]; then
+      define_bool CONFIG_EP93XX_VT y
+      choice 'EP93xx Keyboard Support' \
+         "SPI-PS2 CONFIG_EP93XX_KBD_SPI \
+          USB CONFIG_EP93XX_KBD_USB" SPI-PS2
+   fi
+   if [ "$CONFIG_ARCH_EDB9315" = "y" ]; then
+      define_bool CONFIG_EP93XX_VT y
+      choice 'EP93xx Keyboard Support' \
+         "SPI-PS2 CONFIG_EP93XX_KBD_SPI \
+          USB CONFIG_EP93XX_KBD_USB" USB
+   fi
 fi
 tristate 'Standard/generic (8250/16550 and compatible UARTs) serial support' CONFIG_SERIAL
 if [ "$CONFIG_SERIAL" = "y" ]; then
@@ -24,6 +296,9 @@
       tristate '   Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL
       tristate '   Dual serial port support' CONFIG_DUALSP_SERIAL
    fi
+   if [ "$CONFIG_ARCH_TA7S" = "y" -o "$CONFIG_ARCH_TA7V" = "y" ]; then
+      define_bool CONFIG_SERIAL_TA7 y
+   fi
 fi
 dep_mbool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED $CONFIG_SERIAL
 if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then
@@ -168,6 +443,15 @@
 if [ "$CONFIG_CPU_VR41XX" = "y" ]; then
    bool 'NEC VR4100 series Keyboard Interface Unit Support ' CONFIG_VR41XX_KIU
 fi
+if [ "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
+  tristate 'AT91RM9200 SPI device interface' CONFIG_AT91_SPIDEV
+fi
+
+source drivers/serial/Config.in
+
+if [ "$CONFIG_ARCH_ANAKIN" = "y" ]; then
+   tristate 'Anakin touchscreen support' CONFIG_TOUCHSCREEN_ANAKIN
+fi
 bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
 if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
    int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
@@ -190,6 +474,10 @@
 
 source drivers/i2c/Config.in
 
+if [ "$CONFIG_I2C" != "n" ]; then
+    dep_tristate '  DS1307 RTC' CONFIG_I2C_DS1307 $CONFIG_I2C
+fi
+
 mainmenu_option next_comment
 comment 'Mice'
 tristate 'Bus Mouse Support' CONFIG_BUSMOUSE
@@ -211,6 +499,16 @@
    tristate '  C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE
    tristate '  PC110 digitizer pad support' CONFIG_PC110_PAD
    tristate '  MK712 touch screen support' CONFIG_MK712_MOUSE
+   if [ "$CONFIG_CPU_S3C44B0X" = "y" ]; then
+      tristate '  Aiji (Samsung) MBA44B0 eval-board touch screen support' CONFIG_MBA44B0_TOUCH
+   fi
+fi
+if [ "$CONFIG_ARCH_EDB7312" != "n" ]; then
+   tristate 'EDB7312 touch screen support' CONFIG_EDB7312_TS
+fi
+if [ "$CONFIG_ARCH_EDB9312" = "y" -o \
+     "$CONFIG_ARCH_EDB9315" = "y" ]; then
+   tristate 'EP93xx touch screen support' CONFIG_EP93XX_TOUCHSCREEN
 fi
 endmenu
 
@@ -235,6 +533,19 @@
 dep_tristate '  IPMI Watchdog Timer' CONFIG_IPMI_WATCHDOG $CONFIG_IPMI_HANDLER
 
 mainmenu_option next_comment
+comment 'Controller Area Network Cards/Chips'
+tristate 'can4linux Support'	CONFIG_CAN4LINUX
+if [ "$CONFIG_CAN4LINUX" != "n" ]; then
+   tristate '  AT-CAN-MINI ISA' CONFIG_CAN_ATCANMINI
+   tristate '  CntrlLink PC104' CONFIG_CAN_CCPC104
+   tristate '  ColdFire Flex CAN' CONFIG_CAN_MCF5282
+   tristate '  CPC-PCI' CONFIG_CAN_CPC_PCI
+   tristate '  I+ME Slimline ISA' CONFIG_CAN_IME_SLIMLINE
+fi
+endmenu
+
+
+mainmenu_option next_comment
 comment 'Watchdog Cards'
 bool 'Watchdog Timer Support'	CONFIG_WATCHDOG
 if [ "$CONFIG_WATCHDOG" != "n" ]; then
@@ -251,6 +562,14 @@
          tristate '  NetWinder WB83C977 watchdog' CONFIG_977_WATCHDOG
       fi
    fi
+   if [ "$CONFIG_ARM" = "y" ]; then
+      dep_tristate '  DC21285 watchdog' CONFIG_21285_WATCHDOG $CONFIG_FOOTBRIDGE
+      dep_tristate '  NetWinder WB83C977 watchdog' CONFIG_977_WATCHDOG $CONFIG_ARCH_NETWINDER
+      dep_tristate '  SA1100 watchdog' CONFIG_SA1100_WATCHDOG $CONFIG_ARCH_SA1100
+      dep_tristate '  EPXA watchdog' CONFIG_EPXA_WATCHDOG $CONFIG_ARCH_CAMELOT
+      dep_tristate '  Omaha watchdog' CONFIG_OMAHA_WATCHDOG $CONFIG_ARCH_OMAHA
+      dep_tristate '  AT91RM9200 watchdog' CONFIG_AT91_WATCHDOG $CONFIG_ARCH_AT91RM9200
+   fi
    tristate '  Eurotech CPU-1220/1410 Watchdog Timer' CONFIG_EUROTECH_WDT
    tristate '  IB700 SBC Watchdog Timer' CONFIG_IB700_WDT
    tristate '  ICP ELectronics Wafer 5823 Watchdog' CONFIG_WAFER_WDT
@@ -273,6 +592,7 @@
    if [ "$CONFIG_SGI_IP22" = "y" ]; then
       dep_tristate '  Indy/I2 Hardware Watchdog' CONFIG_INDYDOG $CONFIG_SGI_IP22
    fi
+   tristate '  Triscend A7 Watchdog' CONFIG_TA7_WDT
    if [ "$CONFIG_8xx" = "y" ]; then
       tristate '  MPC8xx Watchdog Timer' CONFIG_8xx_WDT
    fi
@@ -325,6 +645,18 @@
 if [ "$CONFIG_TOSHIBA_RBTX4927" = "y" -o "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then
    tristate 'Dallas DS1742 RTC support' CONFIG_DS1742
 fi
+if [ "$CONFIG_I2C" != "n" ]; then
+   dep_tristate 'Xicor X1226 Real Time Clock' CONFIG_X1226_RTC $CONFIG_I2C
+fi
+if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
+   tristate 'SA1100 Real Time Clock' CONFIG_SA1100_RTC
+fi
+if [ "$CONFIG_ARCH_OMAHA" = "y" ]; then
+   tristate 'Omaha Real Time Clock' CONFIG_OMAHA_RTC
+fi
+if [ "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
+   tristate 'AT91RM9200 Real Time Clock' CONFIG_AT91_RTC
+fi
 
 tristate 'Double Talk PC internal speech card support' CONFIG_DTLK
 tristate 'Siemens R3964 line discipline' CONFIG_R3964
diff -urN linux-2.4.29/drivers/char/console.c linux-2.4.29-uc1/drivers/char/console.c
--- linux-2.4.29/drivers/char/console.c	2005-01-19 14:09:44.000000000 +0000
+++ linux-2.4.29-uc1/drivers/char/console.c	2005-06-14 02:12:16.000000000 +0100
@@ -67,6 +67,10 @@
  * Resurrected character buffers in videoram plus lots of other trickery
  * by Martin Mares <mj@atrey.karlin.mff.cuni.cz>, July 1998
  *
+ * Split out con_write_ctrl_* functions from do_con_write & changed
+ * vc_state to function pointer
+ * by Russell King <rmk@arm.linux.org.uk>, July 1998
+ *
  * Removed old-style timers, introduced console_timer, made timer
  * deletion SMP-safe.  17Jun00, Andrew Morton <andrewm@uow.edu.au>
  *
@@ -74,6 +78,8 @@
  * 13 March 2001, Andrew Morton
  */
 
+#define CONSOLE_WIP
+
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/tty.h>
@@ -853,7 +859,7 @@
 /* the default colour table, for VGA+ colour systems */
 int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,
     0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};
-int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,
+int default_grn[] = {0x00,0x00,0xaa,0xaa,0x00,0x00,0xaa,0xaa,
     0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};
 int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
     0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
@@ -1399,6 +1405,19 @@
 	need_wrap = 0;
 }
 
+static int con_write_ctrl_ESnormal(int, struct tty_struct *, unsigned int);
+static int con_write_ctrl_ESesc(int, struct tty_struct *, unsigned int);
+static int con_write_ctrl_ESnonstd(int, struct tty_struct *, unsigned int);
+static int con_write_ctrl_ESpalette(int, struct tty_struct *, unsigned int);
+static int con_write_ctrl_ESsquare(int, struct tty_struct *, unsigned int);
+static int con_write_ctrl_ESgetpars(int, struct tty_struct *, unsigned int);
+static int con_write_ctrl_ESgotpars(int, struct tty_struct *, unsigned int);
+static int con_write_ctrl_ESpercent(int, struct tty_struct *, unsigned int);
+static int con_write_ctrl_ESfunckey(int, struct tty_struct *, unsigned int);
+static int con_write_ctrl_EShash(int, struct tty_struct *, unsigned int);
+static int con_write_ctrl_ESsetG0(int, struct tty_struct *, unsigned int);
+static int con_write_ctrl_ESsetG1(int, struct tty_struct *, unsigned int);
+
 enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
 	EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
 	ESpalette };
@@ -1408,7 +1427,7 @@
 {
 	top		= 0;
 	bottom		= video_num_lines;
-	vc_state	= ESnormal;
+	vc_state	= con_write_ctrl_ESnormal;
 	ques		= 0;
 	translate	= set_translate(LAT1_MAP,currcons);
 	G0_charset	= LAT1_MAP;
@@ -1506,87 +1525,146 @@
 		disp_ctrl = 0;
 		return;
 	case 24: case 26:
-		vc_state = ESnormal;
+		vc_state = con_write_ctrl_ESnormal;
 		return;
 	case 27:
-		vc_state = ESesc;
+		vc_state = con_write_ctrl_ESesc;
 		return;
 	case 127:
 		del(currcons);
 		return;
 	case 128+27:
-		vc_state = ESsquare;
+		vc_state = con_write_ctrl_ESsquare;
 		return;
 	}
-	switch(vc_state) {
-	case ESesc:
-		vc_state = ESnormal;
+	vc_state(currcons, tty, c);
+}
+
+static int con_write_utf(int currcons, int c)
+{
+	unsigned int chr;
+
+	/* Combine UTF-8 into Unicode */
+	/* Incomplete characters silently ignored */
+	if (c < 0x80) {
+		utf_count = 0;
+		return c;
+	}
+
+	if (utf_count > 0 && (c & 0xc0) == 0x80) {
+		chr = (utf_char << 6) | (c & 0x3f);
+		utf_count--;
+		if (utf_count == 0)
+			return chr;
+	} else {
+		unsigned int count;
+		if ((c & 0xe0) == 0xc0) {
+			count = 1;
+			chr = (c & 0x1f);
+		} else if ((c & 0xf0) == 0xe0) {
+			count = 2;
+			chr = (c & 0x0f);
+		} else if ((c & 0xf8) == 0xf0) {
+			count = 3;
+			chr = (c & 0x07);
+		} else if ((c & 0xfc) == 0xf8) {
+			count = 4;
+			chr = (c & 0x03);
+		} else if ((c & 0xfe) == 0xfc) {
+			count = 5;
+			chr = (c & 0x01);
+		} else {
+			count = 0;
+			chr = 0;
+		}
+		utf_count = count;
+	}
+
+	utf_char = chr;
+	return -1;
+}
+
+static int con_write_ctrl_ESnormal(int currcons, struct tty_struct *tty, unsigned int c)
+{
+	return 0;
+}
+
+static int con_write_ctrl_ESesc(int currcons, struct tty_struct *tty, unsigned int c)
+{
+	vc_state = con_write_ctrl_ESnormal;
 		switch (c) {
 		case '[':
-			vc_state = ESsquare;
-			return;
+		vc_state = con_write_ctrl_ESsquare;
+		break;
 		case ']':
-			vc_state = ESnonstd;
-			return;
+		vc_state = con_write_ctrl_ESnonstd;
+		break;
 		case '%':
-			vc_state = ESpercent;
-			return;
+		vc_state = con_write_ctrl_ESpercent;
+		break;
 		case 'E':
 			cr(currcons);
 			lf(currcons);
-			return;
+		break;
 		case 'M':
 			ri(currcons);
-			return;
+		break;
 		case 'D':
 			lf(currcons);
-			return;
+		break;
 		case 'H':
 			tab_stop[x >> 5] |= (1 << (x & 31));
-			return;
+		break;
 		case 'Z':
 			respond_ID(tty);
-			return;
+		break;
 		case '7':
 			save_cur(currcons);
-			return;
+		break;
 		case '8':
 			restore_cur(currcons);
-			return;
+		return 1;
 		case '(':
-			vc_state = ESsetG0;
-			return;
+		vc_state = con_write_ctrl_ESsetG0;
+		break;
 		case ')':
-			vc_state = ESsetG1;
-			return;
+		vc_state = con_write_ctrl_ESsetG1;
+		break;
 		case '#':
-			vc_state = EShash;
-			return;
+		vc_state = con_write_ctrl_EShash;
+		break;
 		case 'c':
 			reset_terminal(currcons,1);
-			return;
+		return 1;
 		case '>':  /* Numeric keypad */
 			clr_kbd(kbdapplic);
-			return;
+		break;
 		case '=':  /* Appl. keypad */
 			set_kbd(kbdapplic);
-			return;
+	 	break;
 		}
-		return;
-	case ESnonstd:
-		if (c=='P') {   /* palette escape sequence */
+	return 0;
+}
+
+static int con_write_ctrl_ESnonstd(int currcons, struct tty_struct *tty, unsigned int c)
+{
+	switch (c) {
+	case 'P': /* palette escape sequence */
 			for (npar=0; npar<NPAR; npar++)
 				par[npar] = 0 ;
 			npar = 0 ;
-			vc_state = ESpalette;
-			return;
-		} else if (c=='R') {   /* reset palette */
+		vc_state = con_write_ctrl_ESpalette;
+		break;
+	case 'R': /* reset palette */
 			reset_palette(currcons);
-			vc_state = ESnormal;
-		} else
-			vc_state = ESnormal;
-		return;
-	case ESpalette:
+	default:
+		vc_state = con_write_ctrl_ESnormal;
+	}
+	return 0;
+}
+
+static int con_write_ctrl_ESpalette(int currcons, struct tty_struct *tty, unsigned int c)
+{
 		if ( (c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) {
 			par[npar++] = (c>'9' ? (c&0xDF)-'A'+10 : c-'0') ;
 			if (npar==7) {
@@ -1598,48 +1676,59 @@
 				palette[i] = 16*par[j++];
 				palette[i] += par[j];
 				set_palette(currcons);
-				vc_state = ESnormal;
+			vc_state = con_write_ctrl_ESnormal;
 			}
 		} else
-			vc_state = ESnormal;
-		return;
-	case ESsquare:
+		vc_state = con_write_ctrl_ESnormal;
+	return 0;
+}
+
+static int con_write_ctrl_ESsquare(int currcons, struct tty_struct *tty, unsigned int c)
+{
 		for(npar = 0 ; npar < NPAR ; npar++)
 			par[npar] = 0;
 		npar = 0;
-		vc_state = ESgetpars;
+	vc_state = con_write_ctrl_ESgetpars;
 		if (c == '[') { /* Function key */
-			vc_state=ESfunckey;
-			return;
+		vc_state = con_write_ctrl_ESfunckey;
+		return 0;
 		}
 		ques = (c=='?');
 		if (ques)
-			return;
-	case ESgetpars:
+		return 0;
+	return con_write_ctrl_ESgetpars(currcons, tty, c);
+}
+
+static int con_write_ctrl_ESgetpars(int currcons, struct tty_struct *tty, unsigned int c)
+{
 		if (c==';' && npar<NPAR-1) {
 			npar++;
-			return;
+		return 0;
 		} else if (c>='0' && c<='9') {
 			par[npar] *= 10;
 			par[npar] += c-'0';
-			return;
-		} else vc_state=ESgotpars;
-	case ESgotpars:
-		vc_state = ESnormal;
+		return 0;
+	} else vc_state = con_write_ctrl_ESgotpars;
+	return con_write_ctrl_ESgotpars(currcons, tty, c);
+}
+
+static int con_write_ctrl_ESgotpars(int currcons, struct tty_struct *tty, unsigned int c)
+{
+	vc_state = con_write_ctrl_ESnormal;
 		switch(c) {
 		case 'h':
 			set_mode(currcons,1);
-			return;
+		return 0;
 		case 'l':
 			set_mode(currcons,0);
-			return;
+		return 0;
 		case 'c':
 			if (ques) {
 				if (par[0])
 					cursor_type = par[0] | (par[1]<<8) | (par[2]<<16);
 				else
 					cursor_type = CUR_DEFAULT;
-				return;
+			return 0;
 			}
 			break;
 		case 'm':
@@ -1649,7 +1738,7 @@
 					complement_mask = par[0]<<8 | par[1];
 				else
 					complement_mask = s_complement_mask;
-				return;
+			return 0;
 			}
 			break;
 		case 'n':
@@ -1659,69 +1748,69 @@
 				else if (par[0] == 6)
 					cursor_report(currcons,tty);
 			}
-			return;
+		return 0;
 		}
 		if (ques) {
 			ques = 0;
-			return;
+		return 0;
 		}
 		switch(c) {
 		case 'G': case '`':
 			if (par[0]) par[0]--;
 			gotoxy(currcons,par[0],y);
-			return;
+		break;
 		case 'A':
 			if (!par[0]) par[0]++;
 			gotoxy(currcons,x,y-par[0]);
-			return;
+		break;
 		case 'B': case 'e':
 			if (!par[0]) par[0]++;
 			gotoxy(currcons,x,y+par[0]);
-			return;
+		break;
 		case 'C': case 'a':
 			if (!par[0]) par[0]++;
 			gotoxy(currcons,x+par[0],y);
-			return;
+		break;
 		case 'D':
 			if (!par[0]) par[0]++;
 			gotoxy(currcons,x-par[0],y);
-			return;
+		break;
 		case 'E':
 			if (!par[0]) par[0]++;
 			gotoxy(currcons,0,y+par[0]);
-			return;
+		break;
 		case 'F':
 			if (!par[0]) par[0]++;
 			gotoxy(currcons,0,y-par[0]);
-			return;
+		break;
 		case 'd':
 			if (par[0]) par[0]--;
 			gotoxay(currcons,x,par[0]);
-			return;
+		break;
 		case 'H': case 'f':
 			if (par[0]) par[0]--;
 			if (par[1]) par[1]--;
 			gotoxay(currcons,par[1],par[0]);
-			return;
+		break;
 		case 'J':
 			csi_J(currcons,par[0]);
-			return;
+		break;
 		case 'K':
 			csi_K(currcons,par[0]);
-			return;
+		break;
 		case 'L':
 			csi_L(currcons,par[0]);
-			return;
+		break;
 		case 'M':
 			csi_M(currcons,par[0]);
-			return;
+		break;
 		case 'P':
 			csi_P(currcons,par[0]);
-			return;
+		break;
 		case 'c':
 			if (!par[0])
 				respond_ID(tty);
-			return;
+		break;
 		case 'g':
 			if (!par[0])
 				tab_stop[x >> 5] &= ~(1 << (x & 31));
@@ -1732,16 +1821,16 @@
 					tab_stop[3] =
 					tab_stop[4] = 0;
 			}
-			return;
+		break;
 		case 'm':
 			csi_m(currcons);
-			return;
+		return 1;
 		case 'q': /* DECLL - but only 3 leds */
 			/* map 0,1,2,3 to 0,1,2,4 */
 			if (par[0] < 4)
 				setledstate(kbd_table + currcons,
 					    (par[0] < 3) ? par[0] : 4);
-			return;
+		break;
 		case 'r':
 			if (!par[0])
 				par[0]++;
@@ -1754,41 +1843,50 @@
 				bottom=par[1];
 				gotoxay(currcons,0,0);
 			}
-			return;
+		break;
 		case 's':
 			save_cur(currcons);
-			return;
+		break;
 		case 'u':
 			restore_cur(currcons);
-			return;
+		return 1;
 		case 'X':
 			csi_X(currcons, par[0]);
-			return;
+		break;
 		case '@':
 			csi_at(currcons,par[0]);
-			return;
+		break;
 		case ']': /* setterm functions */
 			setterm_command(currcons);
-			return;
+		break;
 		}
-		return;
-	case ESpercent:
-		vc_state = ESnormal;
+	return 0;
+}
+
+static int con_write_ctrl_ESpercent(int currcons, struct tty_struct *tty, unsigned int c)
+{
+	vc_state = con_write_ctrl_ESnormal;
 		switch (c) {
 		case '@':  /* defined in ISO 2022 */
 			utf = 0;
-			return;
+		break;
 		case 'G':  /* prelim official escape code */
 		case '8':  /* retained for compatibility */
 			utf = 1;
-			return;
+		break;
 		}
-		return;
-	case ESfunckey:
-		vc_state = ESnormal;
-		return;
-	case EShash:
-		vc_state = ESnormal;
+	return 0;
+}
+
+static int con_write_ctrl_ESfunckey(int currcons, struct tty_struct *tty, unsigned int c)
+{
+	vc_state = con_write_ctrl_ESnormal;
+	return 0;
+}
+
+static int con_write_ctrl_EShash(int currcons, struct tty_struct *tty, unsigned int c)
+{
+	vc_state = con_write_ctrl_ESnormal;
 		if (c == '8') {
 			/* DEC screen alignment test. kludge :-) */
 			video_erase_char =
@@ -1798,36 +1896,55 @@
 				(video_erase_char & 0xff00) | ' ';
 			do_update_region(currcons, origin, screenbuf_size/2);
 		}
-		return;
-	case ESsetG0:
-		if (c == '0')
+	return 0;
+}
+
+static int con_write_ctrl_ESsetG0(int currcons, struct tty_struct *tty, unsigned int c)
+{
+	switch (c) {
+	case '0':
 			G0_charset = GRAF_MAP;
-		else if (c == 'B')
+		break;
+	case 'B':
 			G0_charset = LAT1_MAP;
-		else if (c == 'U')
+		break;
+	case 'U':
 			G0_charset = IBMPC_MAP;
-		else if (c == 'K')
+		break;
+	case 'K':
 			G0_charset = USER_MAP;
-		if (charset == 0)
+		break;
+	}
+	if (charset == 0) {
 			translate = set_translate(G0_charset,currcons);
-		vc_state = ESnormal;
-		return;
-	case ESsetG1:
-		if (c == '0')
+		return 1;
+	}
+	vc_state = con_write_ctrl_ESnormal;
+	return 0;
+}
+
+static int con_write_ctrl_ESsetG1(int currcons, struct tty_struct *tty, unsigned int c)
+{
+	switch (c) {
+	case '0':
 			G1_charset = GRAF_MAP;
-		else if (c == 'B')
+		break;
+	case 'B':
 			G1_charset = LAT1_MAP;
-		else if (c == 'U')
+		break;
+	case 'U':
 			G1_charset = IBMPC_MAP;
-		else if (c == 'K')
+		break;
+	case 'K':
 			G1_charset = USER_MAP;
-		if (charset == 1)
+		break;
+	}
+	if (charset == 1) {
 			translate = set_translate(G1_charset,currcons);
-		vc_state = ESnormal;
-		return;
-	default:
-		vc_state = ESnormal;
+		return 1;
 	}
+	vc_state = con_write_ctrl_ESnormal;
+	return 0;
 }
 
 /* This is a temporary buffer used to prepare a tty console write
@@ -1861,7 +1978,7 @@
 	unsigned long draw_from = 0, draw_to = 0;
 	struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
 	u16 himask, charmask;
-	const unsigned char *orig_buf = NULL;
+	const unsigned char *orig_buf;
 	int orig_count;
 
 	if (in_interrupt())
@@ -1919,42 +2036,12 @@
 		count--;
 
 		if (utf) {
-		    /* Combine UTF-8 into Unicode */
-		    /* Incomplete characters silently ignored */
-		    if(c > 0x7f) {
-			if (utf_count > 0 && (c & 0xc0) == 0x80) {
-				utf_char = (utf_char << 6) | (c & 0x3f);
-				utf_count--;
-				if (utf_count == 0)
-				    tc = c = utf_char;
-				else continue;
-			} else {
-				if ((c & 0xe0) == 0xc0) {
-				    utf_count = 1;
-				    utf_char = (c & 0x1f);
-				} else if ((c & 0xf0) == 0xe0) {
-				    utf_count = 2;
-				    utf_char = (c & 0x0f);
-				} else if ((c & 0xf8) == 0xf0) {
-				    utf_count = 3;
-				    utf_char = (c & 0x07);
-				} else if ((c & 0xfc) == 0xf8) {
-				    utf_count = 4;
-				    utf_char = (c & 0x03);
-				} else if ((c & 0xfe) == 0xfc) {
-				    utf_count = 5;
-				    utf_char = (c & 0x01);
-				} else
-				    utf_count = 0;
+			tc = con_write_utf(currcons, c);
+			if (tc < 0)
 				continue;
-			      }
-		    } else {
-		      tc = c;
-		      utf_count = 0;
-		    }
-		} else {	/* no utf */
+			c = tc;
+		} else	/* no utf */
 		  tc = translate[toggle_meta ? (c|0x80) : c];
-		}
 
                 /* If the original code was a control character we
                  * only allow a glyph to be displayed if the code is
@@ -1972,7 +2059,7 @@
                         && (c != 127 || disp_ctrl)
 			&& (c != 128+27);
 
-		if (vc_state == ESnormal && ok) {
+		if (vc_state == con_write_ctrl_ESnormal && ok) {
 			/* Now try to find out how to display it */
 			tc = conv_uni_to_pc(vc_cons[currcons].d, tc);
 			if ( tc == -4 ) {
@@ -2118,7 +2205,7 @@
 	if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
 		currcons = kmsg_redirect - 1;
 
-	/* read `x' only after setting currecons properly (otherwise
+	/* read `x' only after setting currcons properly (otherwise
 	   the `x' macro will read the x of the foreground console). */
 	myx = x;
 
diff -urN linux-2.4.29/drivers/char/de2eeprom.c linux-2.4.29-uc1/drivers/char/de2eeprom.c
--- linux-2.4.29/drivers/char/de2eeprom.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/de2eeprom.c	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,514 @@
+/*
+ *  linux/drivers/misc/de2eeprom.c -- EEPROM driver for the DragonEngine
+ *
+ *	Copyright (C) 2003 Georges Menie
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/miscdevice.h>
+#include <asm/uaccess.h>
+#include <asm/MC68VZ328.h>
+
+#define MODULE_NAME "de2eeprom"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Georges Menie");
+MODULE_DESCRIPTION("EEPROM through SPI driver for the DragonEngine");
+
+/*
+ * Define the EEPROM area managed by the driver
+ * it will be a contiguous area of EEPROMSIZE bytes
+ * starting at EEPROMOFFSET bytes. The driver will
+ * not read or write outside this area.
+ */
+#ifndef EEPROMPAGESIZE
+#define EEPROMPAGESIZE 32
+#endif
+#ifndef EEPROMOFFSET
+#define EEPROMOFFSET 64
+#endif
+#ifndef EEPROMSIZE
+#define EEPROMSIZE (2048-EEPROMOFFSET)
+#endif
+
+/*
+ * Maximum read/write buffer size for the EEPROM
+ *
+ * the sizes can be changed as will, but a lock
+ * is held during read/write, so if the
+ * touchscreen is also used, it is better to
+ * keep the size small
+ */
+#define EEPROMWRMAXSIZE 64
+#define EEPROMRDMAXSIZE 128
+
+#undef PDEBUG
+#ifdef DE2EEPROM_DEBUG
+#ifdef __KERNEL__
+#define PDEBUG(fmt,args...) printk(KERN_ALERT MODULE_NAME ": " fmt, ##args);
+#else
+#define PDEBUG(fmt,args...) fprintf(stderr, MODULE_NAME ": " fmt, ##args);
+#endif
+#else
+#define PDEBUG(fmt,args...)		/* void */
+#endif
+#undef IPDEBUG
+#define IPDEBUG(fmt,args...)	/* void */
+
+typedef struct device_tag {
+	int offs;					/* starting offset in bytes */
+	int size;					/* readable/writable size in bytes */
+	int rc;						/* read count stat */
+	int wc;						/* write count stat */
+	int ec;						/* read/write error count stat */
+	char wbuf[EEPROMWRMAXSIZE];
+	char rbuf[EEPROMRDMAXSIZE];
+} Device;
+
+#include "de2spi.h"
+
+/*
+ * EEPROM management functions and macros
+ */
+
+static void eepromInit(void);
+static int eepromWaitReady(void);
+static int eepromWriteEnable(int enable);
+static int eepromRead(void *buf, unsigned short addr, int len);
+static int eepromWrite(const void *buf, unsigned short addr, int len);
+
+/* commands */
+#define EE_WREN 0x0006
+#define EE_WRDI 0x0004
+#define EE_RDSR 0x0500
+#define EE_WRSR 0x0100
+#define EE_READ 0x0003
+#define EE_WRIT 0x0002
+
+#if 0
+/* write protect arguments */
+#define EE_WPDI 0x00
+#define EE_WPQU 0x84
+#define EE_WPHA 0x88
+#define EE_WPFU 0x8C
+
+static int eepromWriteProtect(int protect);
+#endif
+
+#define eepromEnable PDDATA &= ~(1<<6)
+#define eepromDisable PDDATA |= (1<<6)
+
+static void eepromInit(void)
+{
+	PDSEL |= (1 << 6);			// select PD6 as I/O
+	PDDIR |= (1 << 6);			// select Port D bit 6 as output
+	eepromDisable;				// set eeprom CS high
+}
+
+static int eepromWaitReady(void)
+{
+	int sts, timeout;
+
+	for (timeout = 1000; timeout; --timeout) {
+		eepromEnable;
+		sts = de2spi_exchange(EE_RDSR, 16);
+		eepromDisable;
+		if (sts == -1)
+			timeout = 0;
+		if ((sts & 1) == 0)
+			break;
+	}
+
+	PDEBUG("%d: %s timeout=%d\n", __LINE__, __FUNCTION__, timeout);
+	return timeout == 0;
+}
+
+static int eepromWriteEnable(int e)
+{
+	if (eepromWaitReady())
+		return -1;
+
+	eepromEnable;
+	(void) de2spi_exchange(e ? EE_WREN : EE_WRDI, 8);
+	eepromDisable;
+
+	return 0;
+}
+
+#if 0
+static int eepromWriteProtect(int p)
+{
+	unsigned short cmd = EE_WRSR;
+
+	if (eepromWriteEnable(1))	// inside call to eepromWaitReady
+		return -1;
+
+	switch (p) {
+	case 0:
+		cmd |= (unsigned char) EE_WPDI;
+		break;
+	case 1:
+		cmd |= (unsigned char) EE_WPQU;
+		break;
+	case 2:
+		cmd |= (unsigned char) EE_WPHA;
+		break;
+	case 3:
+		cmd |= (unsigned char) EE_WPFU;
+		break;
+	}
+	eepromEnable;
+	(void) de2spi_exchange(cmd, 16);
+	eepromDisable;
+
+	return 0;
+}
+#endif
+
+static int eepromRead(void *buf, unsigned short addr, int len)
+{
+	register int data, i;
+
+	if (eepromWaitReady())
+		return -1;
+
+	PDEBUG("%d: %s(buf, %d, %d)\n", __LINE__, __FUNCTION__,
+		   (int) addr, len);
+
+	eepromEnable;
+	(void) de2spi_exchange(EE_READ, 8);
+	(void) de2spi_exchange(addr, 16);
+	for (i = 0; i < (len >> 1); ++i) {
+		data = de2spi_exchange(0, 16);
+		*(unsigned char *) buf++ = (unsigned char) (data >> 8);
+		*(unsigned char *) buf++ = (unsigned char) data;
+	}
+	if (len & 1) {
+		*(unsigned char *) buf = (unsigned char) de2spi_exchange(0, 8);
+	}
+	eepromDisable;
+
+	return 0;
+}
+
+static int eepromWrite(const void *buf, unsigned short addr, int len)
+{
+	unsigned char rbuf[EEPROMWRMAXSIZE];
+	register const unsigned char *ptr;
+	register int i, rcnt = 0;
+
+	if (len > EEPROMWRMAXSIZE)
+		return -1;
+
+  retry:
+	if (eepromWriteEnable(1))	// inside call to eepromWaitReady
+		return -2;
+
+	PDEBUG("%d: %s(buf, %d, %d)\n", __LINE__, __FUNCTION__,
+		   (int) addr, len);
+
+	eepromEnable;
+	(void) de2spi_exchange(EE_WRIT, 8);
+	(void) de2spi_exchange(addr, 16);
+	for (i = 0, ptr = buf; i < (len >> 1); ++i, ptr += 2) {
+		(void) de2spi_exchange(((*ptr) << 8) | (*(ptr + 1)), 16);
+	}
+	if (len & 1) {
+		(void) de2spi_exchange(*ptr, 8);
+	}
+	eepromDisable;
+
+	if (eepromRead(rbuf, addr, len))
+		return -3;
+	if (memcmp(buf, rbuf, len)) {
+		if (++rcnt > 4)
+			return -4;
+		goto retry;
+	}
+
+	return 0;
+}
+
+/*
+ * driver functions and macros
+ */
+
+static ssize_t
+de2eeprom_read(struct file *filp, char *buf, size_t count, loff_t * offp)
+{
+	Device *dev;
+	ssize_t ret;
+	register int offi, st;
+
+	PDEBUG("%d: %s(filp, buf, %d, %d)\n", __LINE__,
+		   __FUNCTION__, (int) count, (int) *offp);
+
+	dev = (Device *) filp->private_data;
+	if (!dev)
+		return -ENODEV;
+
+	if (!count)
+		return 0;
+
+	if (*offp >= dev->size) {
+		ret = 0;
+	} else {
+		offi = *offp;
+		if (offi + count > dev->size) {
+			count = dev->size - offi;
+		}
+		if (count > sizeof dev->rbuf)
+			count = sizeof dev->rbuf;
+		if (de2spi_attach(SPICLK_SYSCLK_16)) {
+			return -ERESTARTSYS;
+		}
+		if ((st = eepromRead(dev->rbuf, offi + dev->offs, count)) != 0) {
+			de2spi_detach();
+			++dev->ec;
+			PDEBUG("%d: %s read error %d\n", __LINE__, __FUNCTION__, st);
+			return -EFAULT;
+		}
+		de2spi_detach();
+		if (copy_to_user(buf, dev->rbuf, count)) {
+			PDEBUG("%d: %s copy_to_user error\n", __LINE__, __FUNCTION__);
+			return -EFAULT;
+		}
+		PDEBUG("%d: %s %d bytes red at %d\n", __LINE__,
+			   __FUNCTION__, count, offi + dev->offs);
+		++dev->rc;
+		*offp += count;
+		ret = count;
+	}
+	return ret;
+}
+
+static ssize_t
+de2eeprom_write(struct file *filp, const char *buf, size_t count,
+				loff_t * offp)
+{
+	Device *dev;
+	ssize_t ret;
+	register int offi, wcnt, t;
+	register char *wptr;
+	int st;
+
+	PDEBUG("%d: %s(filp, buf, %d, %d)\n", __LINE__,
+		   __FUNCTION__, (int) count, (int) *offp);
+
+	dev = (Device *) filp->private_data;
+	if (!dev) {
+		return -ENODEV;
+	}
+
+	if (!count)
+		return 0;
+
+	if (*offp >= dev->size)
+		return -ENOSPC;
+
+	offi = *offp;
+
+	if (offi + count > dev->size) {
+		count = dev->size - offi;
+	}
+
+	if (count > EEPROMWRMAXSIZE)
+		count = EEPROMWRMAXSIZE;
+
+	if (copy_from_user(dev->wbuf, buf, count)) {
+		PDEBUG("%d: %s copy_from_user error\n", __LINE__, __FUNCTION__);
+		return -EFAULT;
+	}
+
+	wptr = dev->wbuf;
+	wcnt = count;
+
+	if (de2spi_attach(SPICLK_SYSCLK_16)) {
+		return -ERESTARTSYS;
+	}
+
+	if (eepromWriteEnable(1)) {
+		PDEBUG("%d: %s writeenable error\n", __LINE__, __FUNCTION__);
+		++dev->ec;
+		ret = -EFAULT;
+		goto out2;
+	}
+
+	/* write first partial page */
+	if ((t = (offi + dev->offs) % EEPROMPAGESIZE)) {
+		t = EEPROMPAGESIZE - t;
+		if (t > count)
+			t = count;
+		if ((st = eepromWrite(wptr, offi + dev->offs, t)) != 0) {
+			++dev->ec;
+			PDEBUG("%d: %s write error %d\n", __LINE__, __FUNCTION__, st);
+			ret = -EFAULT;
+			goto out1;
+		}
+		wptr += t;
+		offi += t;
+		wcnt -= t;
+	}
+	/* write full pages */
+	while (wcnt > EEPROMPAGESIZE) {
+		if ((st =
+			 eepromWrite(wptr, offi + dev->offs, EEPROMPAGESIZE)) != 0) {
+			++dev->ec;
+			PDEBUG("%d: %s write error %d\n", __LINE__, __FUNCTION__, st);
+			ret = -EFAULT;
+			goto out1;
+		}
+		wptr += EEPROMPAGESIZE;
+		offi += EEPROMPAGESIZE;
+		wcnt -= EEPROMPAGESIZE;
+	}
+	/* write last partial page */
+	if (wcnt > 0) {
+		if ((st = eepromWrite(wptr, offi + dev->offs, wcnt)) != 0) {
+			++dev->ec;
+			PDEBUG("%d: %s write error %d\n", __LINE__, __FUNCTION__, st);
+			ret = -EFAULT;
+			goto out1;
+		}
+	}
+
+	PDEBUG("%d: %s %d bytes written at %d\n", __LINE__,
+		   __FUNCTION__, count, offi + dev->offs);
+	++dev->wc;
+	*offp += count;
+	ret = count;
+
+  out1:
+	if (eepromWriteEnable(0)) {
+		PDEBUG("%d: %s writeenable error\n", __LINE__, __FUNCTION__);
+	}
+  out2:
+	de2spi_detach();
+	return ret;
+}
+
+static loff_t de2eeprom_llseek(struct file *filp, loff_t off, int whence)
+{
+	Device *dev = filp->private_data;
+	loff_t ret;
+
+	PDEBUG("%d: %s(filp, %d, %d)\n", __LINE__, __FUNCTION__,
+		   (int) off, whence);
+
+	if (!dev) {
+		return -ENODEV;
+	}
+
+	switch (whence) {
+	case 0:					/* SEEK_SET */
+		ret = off;
+		break;
+	case 1:					/* SEEK_CUR */
+		ret = filp->f_pos + off;
+		break;
+	case 2:					/* SEEK_END */
+		ret = dev->size + off;
+		break;
+	default:
+		return -EINVAL;
+	}
+	if (ret < 0)
+		return -EINVAL;
+	filp->f_pos = ret;
+	return ret;
+}
+
+static Device dev;
+
+static int de2eeprom_open(struct inode *inode, struct file *filp)
+{
+	if (!filp->private_data) {
+		filp->private_data = &dev;
+	}
+
+	return 0;
+}
+
+static int de2eeprom_release(struct inode *inode, struct file *filp)
+{
+	return 0;
+}
+
+struct file_operations de2eeprom_fops = {
+	owner:THIS_MODULE,
+	read:de2eeprom_read,
+	write:de2eeprom_write,
+	llseek:de2eeprom_llseek,
+	open:de2eeprom_open,
+	release:de2eeprom_release,
+};
+
+/*
+ * The proc entry displays the managed area and some counters
+ * rd : number of successful read operations
+ * wr : number of successful write operations
+ * err: number of errors during read or write
+ */
+static int
+de2eeprom_proc_read(char *buf, char **start, off_t offset, int count,
+					int *eof, void *data)
+{
+	int len = 0;
+
+	len +=
+		sprintf(buf + len,
+				" offs  size         rd         wr        err\n");
+	len +=
+		sprintf(buf + len, "%5d %5d %10d %10d %10d\n", dev.offs, dev.size,
+				dev.rc, dev.wc, dev.ec);
+
+	*eof = 1;
+	return len;
+}
+
+static struct miscdevice de2eeprom = {
+	NVRAM_MINOR, MODULE_NAME, &de2eeprom_fops
+};
+
+static int __init de2eeprom_init(void)
+{
+	if (misc_register(&de2eeprom) < 0)
+		printk(KERN_ALERT
+			   "%s: error registering eeprom driver.\n", MODULE_NAME);
+
+	create_proc_read_entry(MODULE_NAME, 0, NULL, de2eeprom_proc_read,
+						   NULL);
+
+	memset(&dev, 0, sizeof(Device));
+	dev.offs = EEPROMOFFSET;
+	dev.size = EEPROMSIZE;
+
+	eepromInit();
+
+	printk(KERN_INFO
+		   "%s: eeprom driver installed (c,10,%d).\n", MODULE_NAME,
+		   de2eeprom.minor);
+
+	return 0;
+}
+
+static void __exit de2eeprom_cleanup(void)
+{
+	remove_proc_entry(MODULE_NAME, NULL);
+	misc_deregister(&de2eeprom);
+}
+
+module_init(de2eeprom_init);
+module_exit(de2eeprom_cleanup);
diff -urN linux-2.4.29/drivers/char/de2fpga.c linux-2.4.29-uc1/drivers/char/de2fpga.c
--- linux-2.4.29/drivers/char/de2fpga.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/de2fpga.c	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,476 @@
+/*
+ *  linux/drivers/char/de2fpga.c -- FPGA driver for the DragonEngine
+ *
+ *	Copyright (C) 2003 Georges Menie
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+#include <asm/MC68VZ328.h>
+
+#include <linux/de2fpga.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Georges Menie");
+MODULE_DESCRIPTION("Spartan II FPGA driver for the DragonEngine");
+
+#define MDL_MAJOR 61
+#define MDL_NAME "de2fpga"
+
+#undef PDEBUG
+#ifdef MDL_DEBUG
+#ifdef __KERNEL__
+#define PDEBUG(fmt,args...) printk(KERN_ALERT MDL_NAME ": " fmt, ##args);
+#else
+#define PDEBUG(fmt,args...) fprintf(stderr, MDL_NAME ": " fmt, ##args);
+#endif
+#else
+#define PDEBUG(fmt,args...)		/* void */
+#endif
+
+#undef IPDEBUG
+#define IPDEBUG(fmt,args...)	/* void */
+
+static int major = MDL_MAJOR;
+MODULE_PARM(major, "i");
+
+static struct device_tag {
+	long addr;
+	spinlock_t lock;
+	int readerc;
+	int writerc;
+	int status;
+	int state;
+	int offs;
+	int prog;
+	char *file;
+	char *part;
+	char *date;
+	char *time;
+	char buf[DE2FPGA_MAX_TAGLEN];
+} drvinfo = {
+	0x08000000,					/* fpga registers start address */
+};
+
+static const unsigned char bs_head[] =
+	{ 0, 9, 15, 240, 15, 240, 15, 240, 15, 240, 0, 0, 1 };
+
+#define BIT(x) (1<<(x))
+
+static inline void de2fpga_setup_hw(void)
+{
+	/* program the PROG pin (PB7) as output, and set high */
+	PBSEL |= BIT(7);
+	PBDIR |= BIT(7);
+	PBDATA |= BIT(7);
+
+	/* program the CS/WR pin (PF7) as output, and set high */
+	PFSEL |= BIT(7);
+	PFDIR |= BIT(7);
+	PFDATA |= BIT(7);
+	
+	/* program the DONE pin (PM5) as input */
+	PMSEL |= BIT(5);
+	PMDIR &= ~BIT(5);
+
+	/* Select PF2 pin function as CLKO output pin, disabled */
+	PFSEL &= ~BIT(2);
+	PLLCR |= PLLCR_CLKEN;
+}
+
+static inline void de2fpa_fpga_select(void)
+{
+	/* CS low */
+	PFDATA &= ~BIT(7);
+}
+
+static inline void de2fpa_fpga_deselect(void)
+{
+	/* CS high */
+	PFDATA |= BIT(7);
+}
+
+static inline int de2fpa_start_prog(void)
+{
+	int i, ret;
+
+	de2fpa_fpga_select();
+
+	/* pulse PROG low */
+	PBDATA &= ~BIT(7);
+	for (i = 0; i < 5; ++i);
+	PBDATA |= BIT(7);
+
+	/* Check status */
+	for (i = 0; i < 20; ++i) {
+		ret = PMDATA & BIT(5);
+		if (ret == 0)
+			break;
+	}
+	if (ret) {
+		/* error, CS high */
+		de2fpa_fpga_deselect();
+		return 1;
+	}
+
+	return 0;
+}
+
+static inline void de2fpa_prog(unsigned char byte)
+{
+	/* reverse the bits order */
+	byte = ((byte & 0xAA) >>  1) | ((byte & 0x55) <<  1);
+	byte = ((byte & 0xCC) >>  2) | ((byte & 0x33) <<  2);
+	byte = (byte >> 4) | (byte << 4);
+
+	BYTE_REF(drvinfo.addr+1) = byte;
+}
+
+static inline int de2fpa_end_prog(void)
+{
+	int i, ret;
+
+	/* Check status */
+	for (i = 0; i < 20; ++i) {
+		ret = PMDATA & BIT(5);
+		if (ret != 0)
+			break;
+	}
+
+	de2fpa_fpga_deselect();
+
+	if (ret != 0) {
+		/* Enable the CLKO output buffer */
+		PLLCR &= ~PLLCR_CLKEN;
+		return 0;
+	}
+
+	return 1;
+}
+
+static void de2fpga_reset_prog_data(void)
+{
+	drvinfo.file = drvinfo.part = drvinfo.buf;
+	drvinfo.date = drvinfo.time = drvinfo.buf;
+	drvinfo.buf[0] = '\0';
+	drvinfo.status = DE2FPGA_STS_UNKNOWN;
+}
+
+static void de2fpga_init_state(void)
+{
+	drvinfo.state = 0;
+	drvinfo.offs = 0;
+	drvinfo.prog = 0;
+}
+
+static int de2fpga_load_bitstream(int byte)
+{
+	static int tagsize;
+	static int bitsize;
+	static char *tag;
+
+	switch (drvinfo.state) {
+	case 0:					/* read header */
+		if (drvinfo.offs >= sizeof bs_head
+			|| byte != bs_head[drvinfo.offs])
+			return DE2FPGA_STS_HDR_ERROR;
+		if (drvinfo.offs == sizeof bs_head - 1) {
+			drvinfo.state = 1;
+			tag = drvinfo.buf;
+		}
+		break;
+	case 1:					/* read tag letter */
+		if (byte >= 'a' && byte <= 'd') {
+			drvinfo.state = 2;
+			switch (byte) {
+			case 'a':
+				drvinfo.file = tag;
+				break;
+			case 'b':
+				drvinfo.part = tag;
+				break;
+			case 'c':
+				drvinfo.date = tag;
+				break;
+			case 'd':
+				drvinfo.time = tag;
+				break;
+			}
+		} else if (byte == 'e') {
+			drvinfo.state = 5;
+		} else {
+			return DE2FPGA_STS_TGL_ERROR;
+		}
+		break;
+	case 2:					/* read tag size MSB */
+		drvinfo.state = 3;
+		tagsize = byte << 8;
+		break;
+	case 3:					/* read tag size LSB */
+		drvinfo.state = 4;
+		tagsize += byte;
+		break;
+	case 4:					/* read tag content */
+		if (tag - drvinfo.buf >= DE2FPGA_MAX_TAGLEN)
+			return DE2FPGA_STS_TGC_ERROR;
+		*tag++ = byte;
+		--tagsize;
+		if (tagsize == 0) {
+			drvinfo.state = 1;
+		}
+		break;
+	case 5:					/* read bitstream size MSB */
+		drvinfo.state = 6;
+		bitsize = byte << 24;
+		break;
+	case 6:
+		drvinfo.state = 7;
+		bitsize += byte << 16;
+		break;
+	case 7:
+		drvinfo.state = 8;
+		bitsize += byte << 8;
+		break;
+	case 8:					/* read bitstream size LSB */
+		drvinfo.state = 9;
+		bitsize += byte;
+		if (bitsize == 0)
+			return DE2FPGA_STS_NSZ_ERROR;
+		break;
+	case 9:					/* start program bitstream */
+		drvinfo.state = 10;
+		drvinfo.status = DE2FPGA_STS_UNKNOWN;
+		if (de2fpa_start_prog())
+			return DE2FPGA_STS_PRG_ERROR;
+		drvinfo.prog = 1;
+		/* Fall through */
+	case 10:				/* program bitstream */
+		de2fpa_prog(byte);
+		--bitsize;
+		if (bitsize == 0) {
+			drvinfo.state = -1;
+			if (de2fpa_end_prog())
+				return DE2FPGA_STS_EPR_ERROR;
+			drvinfo.prog = 0;
+			drvinfo.status = DE2FPGA_STS_OK;
+		}
+		break;
+	default:
+		return DE2FPGA_STS_FIL_ERROR;
+	}
+	++drvinfo.offs;
+	return 0;
+}
+
+static ssize_t de2fpga_write(struct file *filp, const char *buf,
+							 size_t count, loff_t * offp)
+{
+	int i, e;
+	unsigned char c;
+
+	/* Can't seek on this device */
+	if (offp != &filp->f_pos)
+		return -ESPIPE;
+
+	for (i = 0; i < count; ++i) {
+		if (get_user(c, buf++)) {
+			PDEBUG("get_user error\n");
+			if (drvinfo.prog) {
+				de2fpga_reset_prog_data();
+				de2fpga_init_state();
+				drvinfo.status = DE2FPGA_STS_DRV_ERROR;
+			}
+			return -EFAULT;
+		}
+		if ((e = de2fpga_load_bitstream(c)) != 0) {
+			PDEBUG("load_bitstream error %d @ %d\n", e, drvinfo.offs);
+			if (drvinfo.prog) {
+				de2fpga_reset_prog_data();
+				de2fpga_init_state();
+			}
+			drvinfo.status = e;
+			return -EFAULT;
+		}
+	}
+
+	*offp += count;
+
+	return count;
+}
+
+static int de2fpga_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	/* this is uClinux (no MMU) specific code */
+	vma->vm_flags |= VM_RESERVED;
+	vma->vm_start = drvinfo.addr;
+
+	return 0;
+}
+
+static int de2fpga_ioctl(struct inode *inode, struct file *filp,
+						 unsigned int cmd, unsigned long arg)
+{
+	int i;
+	char *p_in;
+	char *p_out;
+	struct de2fpga_info param;
+
+	switch (cmd) {
+
+	case DE2FPGA_RESET:
+		de2fpga_setup_hw();
+		de2fpga_reset_prog_data();
+		de2fpga_init_state();
+		/* fall through */
+	case DE2FPGA_PARAMS_GET:
+		if (verify_area(VERIFY_WRITE, (char *) arg,
+						sizeof(struct de2fpga_info)))
+			return -EBADRQC;
+
+		param.status = drvinfo.status;
+		param.file = drvinfo.file - drvinfo.buf;
+		param.part = drvinfo.part - drvinfo.buf;
+		param.date = drvinfo.date - drvinfo.buf;
+		param.time = drvinfo.time - drvinfo.buf;
+		memcpy(param.buf, drvinfo.buf, DE2FPGA_MAX_TAGLEN);
+
+		p_in = (char *) &param;
+		p_out = (char *) arg;
+		for (i = 0; i < sizeof(struct de2fpga_info); i++)
+			put_user(p_in[i], p_out + i);
+
+		return 0;
+
+	default:
+		break;
+	}
+	return -ENOIOCTLCMD;
+}
+
+static int de2fpga_open(struct inode *inode, struct file *filp)
+{
+	/*
+	 * loosy reader/writer protection
+	 *
+	 * unrelated process may open the device RDONLY multiple times
+	 * and RDWR/WRONLY if there is no readers and no writers.
+	 *
+	 * forked process will be able to share an opened device,
+	 * it is supposed the programmer knows what he is doing.
+	 *
+	 * Note: readerc is not decremented, so it is *not* a
+	 * true reader count.
+	 */
+	spin_lock(&drvinfo.lock);
+	if ((filp->f_flags & O_ACCMODE) == O_RDONLY) {
+		if (drvinfo.writerc) {
+			spin_unlock(&drvinfo.lock);
+			return -EBUSY;
+		}
+		++drvinfo.readerc;
+	}
+	else {
+		if (drvinfo.readerc || drvinfo.writerc) {
+			spin_unlock(&drvinfo.lock);
+			return -EBUSY;
+		}
+		++drvinfo.writerc;
+	}
+	spin_unlock(&drvinfo.lock);
+
+	return 0;
+}
+
+static int de2fpga_release(struct inode *inode, struct file *filp)
+{
+	if (drvinfo.prog) {
+		de2fpa_fpga_deselect();
+		de2fpga_reset_prog_data();
+		drvinfo.status = DE2FPGA_STS_REL_ERROR;
+	}
+	de2fpga_init_state();
+	drvinfo.readerc = 0;
+	drvinfo.writerc = 0;
+	
+	return 0;
+}
+
+struct file_operations de2fpga_fops = {
+	owner:THIS_MODULE,
+	write:de2fpga_write,
+	mmap:de2fpga_mmap,
+	ioctl:de2fpga_ioctl,
+	open:de2fpga_open,
+	release:de2fpga_release,
+};
+
+static int de2fpga_proc_read(char *buf, char **start, off_t offset,
+							 int count, int *eof, void *data)
+{
+	int len = 0;
+
+	len += sprintf(buf + len, "FPGA status: ");
+	if (drvinfo.status == DE2FPGA_STS_OK) {
+		len += sprintf(buf + len, "ok\n");
+		len += sprintf(buf + len, "file: %s\n", drvinfo.file);
+		len += sprintf(buf + len, "part: %s\n", drvinfo.part);
+		len += sprintf(buf + len, "date: %s\n", drvinfo.date);
+		len += sprintf(buf + len, "time: %s\n", drvinfo.time);
+	}
+	else if (drvinfo.status == DE2FPGA_STS_UNKNOWN) {
+		len += sprintf(buf + len, "unknown\n");
+	}
+	else {
+		len += sprintf(buf + len, "error %d\n", drvinfo.status);
+	}
+
+	*eof = 1;
+	return len;
+}
+
+static int __init de2fpga_init(void)
+{
+	int result;
+
+	result = register_chrdev(major, MDL_NAME, &de2fpga_fops);
+	if (result < 0) {
+		printk(KERN_WARNING "%s: can't get major %d\n", MDL_NAME, major);
+		return result;
+	}
+	if (major == 0)
+		major = result;
+
+	create_proc_read_entry(MDL_NAME, 0, NULL, de2fpga_proc_read, NULL);
+
+	printk(KERN_INFO "%s: Spartan II fpga driver installed (c,%d,0).\n", MDL_NAME,
+		   major);
+
+	de2fpga_setup_hw();
+	de2fpga_reset_prog_data();
+	de2fpga_init_state();
+	spin_lock_init(&drvinfo.lock);
+
+	return 0;
+}
+
+static void __exit de2fpga_cleanup(void)
+{
+	remove_proc_entry(MDL_NAME, NULL);
+	unregister_chrdev(major, MDL_NAME);
+}
+
+module_init(de2fpga_init);
+module_exit(de2fpga_cleanup);
diff -urN linux-2.4.29/drivers/char/de2spi.c linux-2.4.29-uc1/drivers/char/de2spi.c
--- linux-2.4.29/drivers/char/de2spi.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/de2spi.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,138 @@
+/*
+ *  linux/drivers/misc/de2spi.c -- SPI driver for the DragonEngine
+ *
+ *	Copyright (C) 2003 Georges Menie
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+/*
+ * This driver exports 3 functions:
+ *
+ * int de2spi_attach(int div)
+ *   call this function to check if the spi is free, and
+ *   to lock it until you call detach.
+ *
+ * void de2spi_detach(void)
+ *   to release the spi
+ *
+ * unsigned short de2spi_exchange(unsigned short data, int bitcount)
+ *   call this function to transmit/receive data though the spi
+ *   once it is attached
+ *
+ * This locking mechanism is mandatory on the DragonEngine board,
+ * the touchscreen controller and the EEPROM are connected to SPI2
+ * so a lock should be obtained before reading them
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+#include <asm/MC68VZ328.h>
+
+/* MC68VZ328.h does not define the 'canonical' names
+ * for the SPI2 registers...
+ */
+
+#define SPICONT2 SPIMCONT
+#define SPIDATA2 SPIMDATA
+
+#define MODULE_NAME "de2spi"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Georges Menie");
+MODULE_DESCRIPTION("SPI2 driver for the DragonEngine");
+
+#undef PDEBUG
+#ifdef DE2SPI_DEBUG
+#ifdef __KERNEL__
+#define PDEBUG(fmt,args...) printk(KERN_ALERT MODULE_NAME ": " fmt, ##args);
+#else
+#define PDEBUG(fmt,args...) fprintf(stderr, MODULE_NAME ": " fmt, ##args);
+#endif
+#else
+#define PDEBUG(fmt,args...)		/* void */
+#endif
+#undef IPDEBUG
+#define IPDEBUG(fmt,args...)	/* void */
+
+#include "de2spi.h"
+#define BIT(x) (1<<(x))
+
+static unsigned long spilock;
+static unsigned short cdiv;
+
+/* div is the desired speed (see de2spi.h) */
+int de2spi_attach(int div)
+{
+	if (test_and_set_bit(0, &spilock))
+		return -EBUSY;
+
+	/* store sysclk divisor */
+	cdiv = ((div & 0x7) << 13);
+
+	PDEBUG("de2spi attached\n");
+	return 0;
+}
+
+void de2spi_detach(void)
+{
+	clear_bit(0, &spilock);
+	PDEBUG("de2spi detached\n");
+}
+
+int de2spi_exchange(unsigned short data, int bitcount)
+{
+	int timeout;
+
+	/* setup xfer parameters + enable */
+	SPICONT2 = cdiv | (((bitcount) - 1) & 15) | BIT(9);
+	SPIDATA2 = data;
+
+	/* start xfer */
+	SPICONT2 |= BIT(8);
+
+	/* wait ready */
+	for (timeout = 30; timeout && (SPICONT2 & BIT(7)) == 0; --timeout)
+		/* nothing */ ;
+
+	/* read data received */
+	data = SPIDATA2;
+
+	/* disable spi */
+	SPICONT2 = 0;
+
+	if (timeout == 0)
+		return -1;
+
+	return data;
+}
+
+static int __init de2spi_init(void)
+{
+	/* spilock is used to prevent concurrent access
+	 * for the eeprom or the touchscreen controller
+	 */
+	spilock = 0;
+
+	/* disable spi */
+	SPICONT2 = 0;
+
+	/* dedicated func on PE0-2 */
+	PESEL &= ~(BIT(2) | BIT(1) | BIT(0));
+
+	printk(KERN_INFO "%s: spi2 driver installed.\n", MODULE_NAME);
+	return 0;
+}
+
+module_init(de2spi_init);
diff -urN linux-2.4.29/drivers/char/de2spi.h linux-2.4.29-uc1/drivers/char/de2spi.h
--- linux-2.4.29/drivers/char/de2spi.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/de2spi.h	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,18 @@
+#ifndef _DE2SPI_H_
+#define _DE2SPI_H_
+
+/* Sysclock divider */
+#define SPICLK_SYSCLK_4   (0)
+#define SPICLK_SYSCLK_8   (1)
+#define SPICLK_SYSCLK_16  (2)
+#define SPICLK_SYSCLK_32  (3)
+#define SPICLK_SYSCLK_64  (4)
+#define SPICLK_SYSCLK_128 (5)
+#define SPICLK_SYSCLK_256 (6)
+#define SPICLK_SYSCLK_512 (7)
+
+int de2spi_attach(int div);
+void de2spi_detach(void);
+int de2spi_exchange(unsigned short data, int bitcount);
+
+#endif
diff -urN linux-2.4.29/drivers/char/de2ts.c linux-2.4.29-uc1/drivers/char/de2ts.c
--- linux-2.4.29/drivers/char/de2ts.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/de2ts.c	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,840 @@
+/*
+ *  linux/drivers/char/de2ts.c -- Touchscreen driver for the DragonEngine
+ *
+ *	Copyright (C) 2003 Georges Menie
+ *
+ *  Thanks to Philippe Ney for his m68328digi.c driver
+ *  and to Kurt Stremerch (Exys) for code sample
+ *
+ *  The read method is different from the m68328digi driver :
+ *  we are reading several times the X position until it gets stable,
+ *  then do the same for the Y position, then record the event.
+ *
+ *  The burr-brown controller (ADS7846) is also different and easier to interface
+ *  (PENIRQ has been improved)
+ *
+ *  The BUSY signal is not managed (not connected on my board).
+ *
+ *  DragonEngine board specific feature :
+ *    SPI2 connectivity is shared by the touchscreen and the eeprom so the SPI
+ *    functions are externals (de2spi.c driver) and a lock is held to prevent
+ *    concurrent access.
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/poll.h>
+#include <linux/tqueue.h>
+#include <linux/miscdevice.h>
+#include <linux/timer.h>
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+#include <asm/MC68VZ328.h>
+
+#include <linux/de2ts.h>
+
+#define MODULE_NAME "de2ts"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Georges Menie");
+MODULE_DESCRIPTION("Touchscreen driver for the DragonEngine");
+
+#undef PDEBUG
+#ifdef DE2TS_DEBUG
+#ifdef __KERNEL__
+#define PDEBUG(fmt,args...) printk(KERN_ALERT MODULE_NAME ": " fmt, ##args);
+#else
+#define PDEBUG(fmt,args...) fprintf(stderr, MODULE_NAME ": " fmt, ##args);
+#endif
+#else
+#define PDEBUG(fmt,args...)		/* void */
+#endif
+#undef IPDEBUG
+#define IPDEBUG(fmt,args...)	/* void */
+
+#include "de2spi.h"
+
+#define MAX_EVENT 128
+
+typedef struct {
+	int ri, wi;
+	unsigned long lock;
+	struct de2ts_drv_params drv;
+	struct de2ts_cal_params cal;
+	struct de2ts_event tev[MAX_EVENT];
+	struct timeval start;
+	wait_queue_head_t rdq;
+	struct fasync_struct *asq;
+} Device;
+
+static const struct de2ts_drv_params de2ts_default_drv_params = {
+	DE2TS_VERSION,
+	36,							/* max_samples_x */
+	24,							/* max_samples_y */
+	6,							/* min_equals_x */
+	3,							/* min_equals_y */
+	1,							/* max_error */
+	10,							/* max_speed */
+	0,							/* xy swap */
+};
+
+static const struct de2ts_cal_params de2ts_default_cal_params = {
+	DE2TS_VERSION,
+	0,
+	4096,
+	0,
+	4096,
+	4096,
+	4096,
+};
+
+#define BIT(x) (1<<(x))
+
+/* Connectivity:  Burr-Brown        DragonBall
+ *                PENIRQ     ---->  PF1 (IRQ5)
+ *                BUSY       ---->  NC
+ *                CS         ---->  PE3
+ *                DIN        ---->  PE0
+ *                DOUT       ---->  PE1
+ *                DCLK       ---->  PE2
+ */
+
+/*
+ * ADS7846 fields (BURR-BROWN Touch Screen Controller).
+ */
+#define ADS7846_START_BIT BIT(7)
+#define ADS7846_A2        BIT(6)
+#define ADS7846_A1        BIT(5)
+#define ADS7846_A0        BIT(4)
+#define ADS7846_MODE      BIT(3)	/* HIGH = 8, LOW = 12 bits conversion */
+#define ADS7846_SER_DFR   BIT(2)	/* LOW = differential mode            */
+#define ADS7846_PD1       BIT(1)	/* PD1,PD0 = 11  PENIRQ disable       */
+#define ADS7846_PD0       BIT(0)	/* PD1,PD0 = 00  PENIRQ enable        */
+
+/*
+ * X conversion.
+ */
+#define ADS7846_ASKX    (ADS7846_START_BIT   | \
+                         ADS7846_A2          | \
+						 ADS7846_A1        *0| \
+						 ADS7846_A0          | \
+                         ADS7846_MODE      *0| \
+                         ADS7846_SER_DFR   *0| \
+                         ADS7846_PD1         | \
+                         ADS7846_PD0            )
+/*
+ * Y conversion.
+ */
+#define ADS7846_ASKY    (ADS7846_START_BIT   | \
+                         ADS7846_A2        *0| \
+						 ADS7846_A1        *0| \
+						 ADS7846_A0          | \
+                         ADS7846_MODE      *0| \
+                         ADS7846_SER_DFR   *0| \
+                         ADS7846_PD1         | \
+                         ADS7846_PD0            )
+
+/*
+ * void conversion.
+ */
+#define ADS7846_NOP     (ADS7846_START_BIT   | \
+                         ADS7846_A2        *0| \
+						 ADS7846_A1        *0| \
+						 ADS7846_A0          | \
+                         ADS7846_MODE      *0| \
+                         ADS7846_SER_DFR   *0| \
+                         ADS7846_PD1       *0| \
+                         ADS7846_PD0       *0   )
+
+
+static inline void de2ts_ts_enable(void)
+{
+	PEDATA &= ~BIT(3);
+}
+
+static inline void de2ts_ts_disable(void)
+{
+	PEDATA |= BIT(3);
+}
+
+static inline void de2ts_ts_pen_io(void)
+{
+	// PENIRQ
+	PFSEL |= BIT(1);			// select PF1 as I/O
+	PFDIR &= ~BIT(1);			// select Port F bit 1 as input
+}
+
+static inline void de2ts_ts_pen_irq(void)
+{
+	// PENIRQ
+	PFPUEN |= BIT(1);			// pull up enable
+	ICR &= ~ICR_POL5;			// irq on low level
+	PFSEL &= ~BIT(1);			// select PF1 as IRQ5 pin
+}
+
+static inline int de2ts_ts_pen(void)
+{
+	// PENIRQ status
+	return PFDATA & BIT(1);
+}
+
+static inline void de2ts_setup_hw(void)
+{
+	// CS
+	PESEL |= BIT(3);			// select PE3 as I/O
+	PEDIR |= BIT(3);			// select Port E bit 3 as output
+	de2ts_ts_disable();
+
+	de2ts_ts_pen_irq();
+}
+
+static inline void de2ts_reset_hw(void)
+{
+	de2ts_ts_disable();
+	de2ts_ts_pen_io();
+}
+
+static inline int de2ts_comperr(int m1, int m2)
+{
+	if (m1 > m2)
+		return m2 ? 100 * (m1 - m2) / m2 : 100;
+	else
+		return m1 ? 100 * (m2 - m1) / m1 : 100;
+}
+
+/*
+ * touchscreen main reading function
+ *
+ * read a serie of x positions up to (max_samples_x) 
+ * if (min_equals_x) consecutives read are equals
+ * then continue with y positions.
+ * two conscutive samples are equal if the difference
+ * computed by comperr() is below (min_equal_x)
+ *
+ * same algo for the y position with different
+ * parameters values (max_samples_y, min_equals_y)
+ * because if the x position is stable, the y position
+ * should read faster.
+ *
+ * when x and y are ok, return the average of the
+ * consecutive samples.
+ *
+ * if x or y can not be read, just give up and do not
+ * register an event, the calling function will try
+ * again later.
+ *
+ */
+static int de2ts_readts(int *px, int *py, struct de2ts_drv_params *dprm)
+{
+	int x, xp, xi, y, yp, yi;
+	int n, xtot = 0, ytot = 0;
+
+	xp = x = yp = y = -1;
+	de2ts_ts_enable();
+	(void) de2spi_exchange(ADS7846_ASKX, 8);
+	for (xi = n = yi = 0; xi < dprm->max_samples_x; ++xi) {
+		x = (de2spi_exchange(ADS7846_ASKX, 16) >> 3) & 0xfff;
+		if (!n || de2ts_comperr(x, xp) <= dprm->max_error) {
+			if (!n)
+				xtot = x;
+			else
+				xtot += x;
+			if (++n >= dprm->min_equals_x)
+				break;
+		} else {
+			n = 1;
+			xtot = x;
+		}
+		xp = x;
+	}
+	if (xi < dprm->max_samples_x) {
+		(void) de2spi_exchange(ADS7846_ASKY, 16);
+		for (yi = n = 0; yi < dprm->max_samples_y; ++yi) {
+			y = (de2spi_exchange(ADS7846_ASKY, 16) >> 3) & 0xfff;
+			if (!n || de2ts_comperr(y, yp) <= dprm->max_error) {
+				if (!n)
+					ytot = y;
+				else
+					ytot += y;
+				if (++n >= dprm->min_equals_y)
+					break;
+			} else {
+				n = 1;
+				ytot = y;
+			}
+			yp = y;
+		}
+	}
+
+	(void) de2spi_exchange(ADS7846_NOP, 8);
+	(void) de2spi_exchange(0, 16);
+
+	de2ts_ts_disable();
+
+	if (xi < dprm->max_samples_x && yi < dprm->max_samples_y) {
+		*px = xtot / dprm->min_equals_x;
+		*py = ytot / dprm->min_equals_y;
+	} else
+		return -1;
+
+	return 0;
+}
+
+/* */
+
+#define LIGHT_TIMEOUT (3*60*HZ)
+static struct timer_list light_timer;
+static struct tq_struct event_task;
+static struct de2ts_event ev_prev;
+
+static void light_off(unsigned long data)
+{
+	PBDATA |= 0x20;		/* disable CCFL backlight */
+}
+
+static void light_on(void)
+{
+	PBDATA &= ~0x20;	/* enable CCFL backligh */
+
+	if (light_timer.expires != jiffies + LIGHT_TIMEOUT)
+		mod_timer(&light_timer, jiffies + LIGHT_TIMEOUT);
+}
+
+/* if there is no room in the event queue, then
+ * the event is discarded. The calling process may
+ * check ev_no to see if events have been lost.
+ */
+static void de2ts_addevent(Device * dev, struct de2ts_event *ev)
+{
+	if (((dev->wi + 1) % MAX_EVENT) != dev->ri) {
+		dev->tev[dev->wi] = *ev;
+		dev->wi = (++dev->wi) % MAX_EVENT;
+		wake_up_interruptible(&dev->rdq);
+		if (dev->asq)
+			kill_fasync(&dev->asq, SIGIO, POLL_IN);
+	}
+}
+
+static unsigned long de2ts_settime(struct timeval *start)
+{
+	struct timeval now;
+
+	do_gettimeofday(&now);
+	return (now.tv_sec - start->tv_sec) * 1000 + now.tv_usec / 1000;
+}
+
+/* try to debounce the penirq signal while it is
+ * read as an IO and not in IRQ mode
+ */
+static int de2ts_penstate(void)
+{
+	int i = 0, st, stc;
+
+	goto start_loop;
+
+	for (; i < 200; ++i) {
+		if (de2ts_ts_pen() == st) {
+			if (++stc > 20)
+				return st;
+		} else {
+		  start_loop:
+			stc = 0;
+			st = de2ts_ts_pen();
+		}
+	}
+
+	return 1;
+}
+
+/*
+ * As long as the penirq signal stay low,
+ * a timer task is used to read the touchscreen
+ * this is to make sure we don't generate too
+ * many events. With a 100 Hz timer, we will
+ * have one event each 10 ms maximum.
+ */
+static void timer_handler(void *dev_id)
+{
+	Device *dev;
+	struct de2ts_event ev;
+	static int debounce = 0;
+	int speed, tmpf;
+
+	dev = (Device *) dev_id;
+
+	light_on();
+
+	if (!dev->lock) {
+		/* device not opened */
+		/* re-enable IRQ */
+		de2ts_ts_pen_irq();
+		return;
+	}
+
+	if (de2ts_penstate() == 0) {
+		/* if SPI2 is busy, postpone the read to the next timer tick */
+		if (de2spi_attach(SPICLK_SYSCLK_16) == 0) {
+			tmpf = de2ts_readts(&ev.xraw, &ev.yraw, &dev->drv);
+			de2spi_detach();
+			if (tmpf == 0) {
+	
+				/* timestamp the event */
+				ev.ev_time = de2ts_settime(&dev->start);
+	
+				/* convert the event to the user screen coordinates */
+				ev.x = dev->cal.xrng * (ev.xraw - dev->cal.xoff) / dev->cal.xden;
+				if (ev.x < 0)
+					ev.x = 0;
+				if (ev.x >= dev->cal.xrng)
+					ev.x = dev->cal.xrng - 1;
+	
+				ev.y = dev->cal.yrng * (ev.yraw - dev->cal.yoff) / dev->cal.yden;
+				if (ev.y < 0)
+					ev.y = 0;
+				if (ev.y >= dev->cal.yrng)
+					ev.y = dev->cal.yrng - 1;
+	
+				if (dev->drv.xysw) {
+					int t = ev.x;
+					ev.x = ev.y;
+					ev.y = t;
+				}
+	
+				/* qualify the event */
+				switch (ev_prev.event) {
+				case EV_PEN_DOWN:
+					ev.event = EV_PEN_MOVE;
+					break;
+				case EV_PEN_MOVE:
+					ev.event = EV_PEN_MOVE;
+					break;
+				case EV_PEN_UP:
+					ev.event = EV_PEN_DOWN;
+					break;
+				default:			/* no previous event */
+					ev.event = EV_PEN_DOWN;
+					break;
+				}
+	
+				/* compute the speed from the last position to the current one  */
+				/* if we are in MOVE mode only                                  */
+				if (ev.event == EV_PEN_MOVE) {
+					speed = ((ev.xraw - ev_prev.xraw)>>4) * ((ev.xraw - ev_prev.xraw)>>4);
+					speed += ((ev.yraw - ev_prev.yraw)>>4) * ((ev.yraw - ev_prev.yraw)>>4);
+					if (ev.ev_time != ev_prev.ev_time)
+						speed /= (ev.ev_time - ev_prev.ev_time);
+				} else {
+					speed = 0;
+				}
+	
+				/* ignore the event if:                                    */
+				/*   the speed is higher than the max_speed parameters or  */
+				/*   the event is the same as the previous one             */
+				if (speed <= dev->drv.max_speed && (ev.x != ev_prev.x || ev.y != ev_prev.y
+									|| ev.event != ev_prev.event)) {
+					ev.ev_no = ev_prev.ev_no + 1;
+					de2ts_addevent(dev, &ev);
+					ev_prev = ev;
+				} else {
+					/* update the timestamp of the last good event, to help not to reject */
+					/* too many events once a first one is rejected                       */
+					ev_prev.ev_time = ev.ev_time;
+				}
+			}
+			debounce = 0;
+		}
+		/* penirq was down or SPI2 is busy, so re-enable the timer task */
+		queue_task(&event_task, &tq_timer);
+
+	}
+
+	else {
+
+		/* penirq is up, try to debounce it by re-queuing the task 3 times more */
+		if (++debounce < 4) {
+			queue_task(&event_task, &tq_timer);
+
+		} else {
+			
+			/* penirq is really down, register the last good event as a PEN_UP event */
+			/* if this is not the very first event or if the last good event is not  */
+			/* already a PEN_UP event                                                */
+			if (ev_prev.event && ev_prev.event != EV_PEN_UP) {
+				ev_prev.ev_time = de2ts_settime(&dev->start);
+				++ev_prev.ev_no;
+				ev_prev.event = EV_PEN_UP;
+				de2ts_addevent(dev, &ev_prev);
+			}
+
+			/* re-enable IRQ */
+			de2ts_ts_pen_irq();
+		}
+	}
+}
+
+/* the penirq interrupt handler temporary disable the interrupts
+ * by configuring the signal as a regular IO signal, then it queue
+ * a timer task to do the touchscreen reading on the next timer tick
+ * the timer task will re-queue itself while the penirq signal is down
+ * or re-enable the interrupt
+ */
+static void penirq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	Device *dev;
+
+	dev = (Device *) dev_id;
+
+	/* pause IRQ */
+	de2ts_ts_pen_io();
+
+	event_task.routine = timer_handler;
+	event_task.data = dev;
+	queue_task(&event_task, &tq_timer);
+}
+
+/* */
+
+static ssize_t
+de2ts_read(struct file *filp, char *buf, size_t count, loff_t * offp)
+{
+	Device *dev;
+	ssize_t ret, maxrd;
+
+	dev = (Device *) filp->private_data;
+	if (!dev)
+		return -ENODEV;
+
+	if (offp != &filp->f_pos)
+		return -ESPIPE;
+
+	while (dev->wi == dev->ri) {
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		PDEBUG("de2ts_read going to sleep\n");
+		if (wait_event_interruptible(dev->rdq, (dev->wi != dev->ri)))
+			return -ERESTARTSYS;
+	}
+
+	ret =
+		(count / sizeof(struct de2ts_event)) * sizeof(struct de2ts_event);
+
+	if (ret == 0)
+		return -EFAULT;
+
+	maxrd = dev->wi - dev->ri;
+	while (maxrd < 0)
+		maxrd += MAX_EVENT;
+	maxrd *= sizeof(struct de2ts_event);
+
+	if (ret > maxrd)
+		ret = maxrd;
+
+	if (copy_to_user(buf, &dev->tev[dev->ri], ret))
+		return -EFAULT;
+
+	PDEBUG("de2ts_read returning %ld events\n",
+		   ret / sizeof(struct de2ts_event));
+
+	dev->ri += ret / sizeof(struct de2ts_event);
+	dev->ri %= MAX_EVENT;
+
+	return ret;
+}
+
+static unsigned int de2ts_poll(struct file *filp, poll_table * table)
+{
+	Device *dev;
+
+	dev = (Device *) filp->private_data;
+	if (!dev)
+		return -ENODEV;
+
+	poll_wait(filp, &dev->rdq, table);
+	if (dev->wi != dev->ri)
+		return POLLIN | POLLRDNORM;
+
+	return 0;
+}
+
+static int de2ts_ioctl(struct inode *inode, struct file *filp,
+					   unsigned int cmd, unsigned long arg)
+{
+	int i;
+	Device *dev;
+	char *p_in;
+	char *p_out;
+	struct de2ts_drv_params new_drv_params;
+	struct de2ts_cal_params new_cal_params;
+
+	dev = (Device *) filp->private_data;
+	if (!dev)
+		return -ENODEV;
+
+	switch (cmd) {
+
+	case DE2TS_DRV_PARAMS_GET:
+		if (verify_area(VERIFY_WRITE, (char *) arg,
+						sizeof(struct de2ts_drv_params)))
+			return -EBADRQC;
+		p_in = (char *) &dev->drv;
+		p_out = (char *) arg;
+		for (i = 0; i < sizeof(struct de2ts_drv_params); i++)
+			put_user(p_in[i], p_out + i);
+		return 0;
+
+	case DE2TS_CAL_PARAMS_GET:
+		if (verify_area(VERIFY_WRITE, (char *) arg,
+						sizeof(struct de2ts_cal_params)))
+			return -EBADRQC;
+		p_in = (char *) &dev->cal;
+		p_out = (char *) arg;
+		for (i = 0; i < sizeof(struct de2ts_cal_params); i++)
+			put_user(p_in[i], p_out + i);
+		return 0;
+
+	case DE2TS_DRV_PARAMS_SET:
+		if (verify_area(VERIFY_READ, (char *) arg,
+						sizeof(struct de2ts_drv_params)))
+			return -EBADRQC;
+		p_in = (char *) &new_drv_params;
+		p_out = (char *) arg;
+		for (i = 0; i < sizeof(struct de2ts_drv_params); i++) {
+			get_user(p_in[i], p_out + i);
+		}
+
+		if (new_drv_params.version == 0) {
+			/* reset parameters */
+			memcpy(&dev->drv, &de2ts_default_drv_params,
+				   sizeof(struct de2ts_drv_params));
+		} else {
+			/* check version */
+			if (new_drv_params.version != -1) {
+				if (new_drv_params.version != DE2TS_VERSION) {
+					printk(KERN_ALERT
+						   "%s: error: driver version is %d, requested version is %d\n",
+						   MODULE_NAME, DE2TS_VERSION,
+						   new_drv_params.version);
+					return -EBADRQC;
+				}
+			}
+
+			/* All the params are set with minimal test. */
+			memcpy(&dev->drv, &new_drv_params,
+				   sizeof(struct de2ts_drv_params));
+		}
+		return 0;
+
+	case DE2TS_CAL_PARAMS_SET:
+		if (verify_area(VERIFY_READ, (char *) arg,
+						sizeof(struct de2ts_cal_params)))
+			return -EBADRQC;
+		p_in = (char *) &new_cal_params;
+		p_out = (char *) arg;
+		for (i = 0; i < sizeof(struct de2ts_cal_params); i++) {
+			get_user(p_in[i], p_out + i);
+		}
+
+		if (new_cal_params.version == 0) {
+			/* reset parameters */
+			memcpy(&dev->cal, &de2ts_default_cal_params,
+				   sizeof(struct de2ts_cal_params));
+		} else {
+			/* check version */
+			if (new_cal_params.version != -1) {
+				if (new_cal_params.version != DE2TS_VERSION) {
+					printk(KERN_ALERT
+						   "%s: error: driver version is %d, requested version is %d\n",
+						   MODULE_NAME, DE2TS_VERSION,
+						   new_cal_params.version);
+					return -EBADRQC;
+				}
+			}
+
+			if (new_cal_params.xden == 0 || new_cal_params.yden == 0) {
+				printk(KERN_ALERT
+					   "%s: error: xden or yden should not be set to 0\n",
+					   MODULE_NAME);
+				return -EBADRQC;
+			}
+
+			/* All the params are set with minimal test. */
+			memcpy(&dev->cal, &new_cal_params,
+				   sizeof(struct de2ts_cal_params));
+		}
+		return 0;
+
+	default:
+		break;
+	}
+	return -ENOIOCTLCMD;
+}
+
+static int de2ts_fasync(int inode, struct file *filp, int mode)
+{
+	int retval;
+	Device *dev;
+
+	dev = (Device *) filp->private_data;
+	if (!dev)
+		return -ENODEV;
+
+	retval = fasync_helper(inode, filp, mode, &dev->asq);
+	if (retval < 0)
+		return retval;
+
+	return 0;
+}
+
+/* only one open device allowed */
+static unsigned long de2ts_lock;
+
+static int de2ts_release(struct inode *inode, struct file *filp)
+{
+	Device *dev;
+
+	dev = (Device *) filp->private_data;
+	if (!dev)
+		return -ENODEV;
+
+	de2ts_fasync(-1, filp, 0);
+
+	clear_bit(0, &dev->lock);
+
+	clear_bit(0, &de2ts_lock);
+
+	return 0;
+}
+
+/* only one device managed */
+static Device de2ts_dev;
+
+static int de2ts_open(struct inode *inode, struct file *filp)
+{
+	Device *dev;
+
+	if (test_and_set_bit(0, &de2ts_lock))
+		return -EDEADLK;
+
+	if (!filp->private_data) {
+		filp->private_data = &de2ts_dev;
+	}
+	dev = filp->private_data;
+
+	if (test_and_set_bit(0, &dev->lock))
+		return -EDEADLK;
+
+	init_waitqueue_head(&dev->rdq);
+	do_gettimeofday(&dev->start);
+
+	return 0;
+}
+
+static int
+de2ts_proc_read(char *buf, char **start, off_t offset, int count,
+				int *eof, void *data)
+{
+	int len = 0, evnb;
+
+	evnb = de2ts_dev.wi - de2ts_dev.ri;
+	if (evnb < 0) evnb += MAX_EVENT;
+
+	len += sprintf(buf + len, "\nEvent queue: %d/%d\n", evnb, MAX_EVENT);
+
+	len += sprintf(buf + len, "\nCurrent parameters (v%d):\n", de2ts_dev.drv.version);
+	len += sprintf(buf + len, "max_samples_x: %d\n", de2ts_dev.drv.max_samples_x);
+	len += sprintf(buf + len, "max_samples_y: %d\n", de2ts_dev.drv.max_samples_y);
+	len += sprintf(buf + len, " min_equals_x: %d\n", de2ts_dev.drv.min_equals_x);
+	len += sprintf(buf + len, " min_equals_y: %d\n", de2ts_dev.drv.min_equals_y);
+	len += sprintf(buf + len, "    max_error: %d\n", de2ts_dev.drv.max_error);
+	len += sprintf(buf + len, "    max_speed: %d\n", de2ts_dev.drv.max_speed);
+	len += sprintf(buf + len, "         xysw: %d\n", de2ts_dev.drv.xysw);
+
+	len += sprintf(buf + len, "\nCurrent calibration values (v%d):\n", de2ts_dev.cal.version);
+	len += sprintf(buf + len, "%d %d %d %d %d %d\n",
+		de2ts_dev.cal.xoff,
+		de2ts_dev.cal.xden,
+		de2ts_dev.cal.yoff,
+		de2ts_dev.cal.yden,
+		de2ts_dev.cal.xrng,
+		de2ts_dev.cal.yrng);
+
+	*eof = 1;
+	return len;
+}
+
+static struct file_operations de2ts_fops = {
+	owner:THIS_MODULE,
+	poll:de2ts_poll,
+	read:de2ts_read,
+	ioctl:de2ts_ioctl,
+	fasync:de2ts_fasync,
+	release:de2ts_release,
+	open:de2ts_open,
+};
+
+static struct miscdevice de2ts = {
+	MK712_MINOR, MODULE_NAME, &de2ts_fops
+};
+
+static int __init de2ts_init(void)
+{
+	int err;
+	
+	err = misc_register(&de2ts);
+	if (err < 0) {
+		printk(KERN_ALERT
+			   "%s: error registering touchscreen driver.\n", MODULE_NAME);
+		return err;
+	}
+
+	err = request_irq(IRQ5_IRQ_NUM, penirq_handler,
+					  IRQ_FLG_STD, "touchscreen", &de2ts_dev);
+	if (err) {
+		printk(KERN_ALERT
+			   "%s: Cannot attach IRQ %d\n", MODULE_NAME, IRQ5_IRQ_NUM);
+		return err;
+	}
+
+	memset(&de2ts_dev, 0, sizeof(Device));
+	memcpy(&de2ts_dev.drv, &de2ts_default_drv_params,
+		   sizeof(struct de2ts_drv_params));
+	memcpy(&de2ts_dev.cal, &de2ts_default_cal_params,
+		   sizeof(struct de2ts_cal_params));
+
+	de2ts_setup_hw();
+
+	init_timer(&light_timer);
+	light_timer.function = light_off;
+	light_timer.expires = jiffies + LIGHT_TIMEOUT;
+	add_timer(&light_timer);
+
+	create_proc_read_entry(MODULE_NAME, 0, NULL, de2ts_proc_read, NULL);
+
+	printk(KERN_INFO
+		   "%s: touchscreen driver installed (c,10,%d).\n", MODULE_NAME,
+		   de2ts.minor);
+
+	return 0;
+}
+
+static void __exit de2ts_cleanup(void)
+{
+	de2ts_reset_hw();
+	free_irq(IRQ5_IRQ_NUM, &de2ts_dev);
+	remove_proc_entry(MODULE_NAME, NULL);
+	misc_deregister(&de2ts);
+}
+
+module_init(de2ts_init);
+module_exit(de2ts_cleanup);
diff -urN linux-2.4.29/drivers/char/dragonixspi.c linux-2.4.29-uc1/drivers/char/dragonixspi.c
--- linux-2.4.29/drivers/char/dragonixspi.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/dragonixspi.c	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,223 @@
+/*****************************************************************************/
+
+/*
+ *	ds1302.c -- driver for Dallas Semiconductor DS1302 Real Time Clock.
+ *
+ * 	(C) Copyright 2001, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/*****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/wait.h>
+#include <linux/rtc.h>
+
+/* Defines */
+#define NONE 0
+#define PEN  1
+#define CLK  2
+#define RTC_SIZE 0x80
+
+/* File seek operations */
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+#endif
+
+/* Global data */
+static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t hw_lock = SPIN_LOCK_UNLOCKED;
+
+/* Utility functions */
+int __inline__ bcd2int(int val)
+{
+	return((((val & 0xf0) >> 4) * 10) + (val & 0xf));
+}
+
+/* SPI IO functions */
+static void uwait(unsigned long x)
+{
+ int loop;
+ while(x>0)
+ {
+  for(loop=0;loop<10;loop++);
+  x--;
+ }
+}
+
+static unsigned long SPIIO(unsigned char chip, unsigned long shifts, unsigned long out)
+{
+ int loop;
+ unsigned long in=0;
+
+ *(volatile unsigned  char *)0x4000103=(chip&0x03);
+ uwait(5);
+
+ for(loop=shifts;loop>0;loop--)
+ {
+  *(volatile unsigned  char *)0x4000103= (((out&(1<<(loop-1)))!=0 ? 0x10 : 0x00) | (chip&0x03));        /* data out */
+  uwait(1);
+  *(volatile unsigned  char *)0x4000103= (((out&(1<<(loop-1)))!=0 ? 0x10 : 0x00) | (chip&0x03) | 0x04); /* clk */
+  uwait(5);
+  in=(in<<1) | (((*(volatile unsigned  char *)0x4000103)&0x10)>>4);
+  uwait(5);
+  *(volatile unsigned  char *)0x4000103= (((out&(1<<(loop-1)))!=0 ? 0x10 : 0x00) | (chip&0x03));        /* data out */
+  uwait(5);
+ }
+ *(volatile unsigned  char *)0x4000103=0; /* deselect all */
+ return(in);
+}
+
+
+/* RTC kernel functions */
+/* Called from kernel to get the rtc date */
+void dragonixrtc_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec)
+{
+	/* Ensure exclusive access to hardware */
+	spin_lock_irq(&hw_lock);
+	*sec   =       bcd2int(SPIIO(CLK,16,0x00<<8) & 0xff);
+	*min   =       bcd2int(SPIIO(CLK,16,0x01<<8) & 0xff);
+	*hour  =       bcd2int(SPIIO(CLK,16,0x02<<8) & 0xff);
+	*day   =       bcd2int(SPIIO(CLK,16,0x04<<8) & 0xff);
+	*mon   =       bcd2int(SPIIO(CLK,16,0x05<<8) & 0xff);
+	*year  =       bcd2int(SPIIO(CLK,16,0x06<<8) & 0xff);
+	spin_unlock_irq(&hw_lock);
+
+}
+/* Called from kernel to synchronize the kernel clock to the RTC */
+int dragonixrtc_set_clock_mmss(unsigned long nowtime)
+{
+	unsigned long	m, s;
+
+#if 1
+	printk("ds1302_set_clock_mmss(nowtime=%ld)\n", nowtime);
+#endif
+
+	/* FIXME: not implemented yet... */
+	s = nowtime % 60;
+	m = nowtime / 60;
+	return(0);
+}
+/* End of kernel functions */
+
+/* RTC file operation functions */
+static int rtc_open(struct inode *inode, struct file *file) {
+	//printk("RTC device opened\n");
+	/* Nothing to do here, the lock are made in i/o functions */
+
+	return 0;
+}
+
+static int rtc_release(struct inode *inode, struct file *file) {
+	//printk("Device closed");
+
+	return 0;
+}
+
+static loff_t rtc_lseek(struct file *file, loff_t offset, int orig) {
+	loff_t pos = 0;
+
+	switch(orig) {
+	case SEEK_SET:
+		pos = offset;
+		break;
+	case SEEK_CUR:
+		pos = file->f_pos + offset;
+		break;
+	case SEEK_END:
+		pos = (RTC_SIZE - 1) + offset;
+		break;
+	}
+	if(pos < 0)
+		pos = 0;
+	if(pos >= RTC_SIZE)
+		pos = RTC_SIZE - 1;
+	file->f_pos = pos;
+	return(pos);
+}
+
+static ssize_t rtc_read(struct file *file, char *buffer, size_t length, loff_t *offset) {
+	int	total;
+
+	if (file->f_pos >= RTC_SIZE)
+		return(0);
+	if (length > (RTC_SIZE - file->f_pos))
+		length = RTC_SIZE - file->f_pos;
+
+	spin_lock_irq(&hw_lock);
+	for (total = 0; (total < length); total++) {
+		*buffer = SPIIO(CLK, 16, (file->f_pos + total) << 8) & 0xff;
+		buffer++;
+	}
+	spin_unlock_irq(&hw_lock);
+
+	file->f_pos += total;
+	return(total);
+
+}
+
+static ssize_t rtc_write(struct file *file, const char *buffer, size_t length, loff_t *offset) {
+	int	total;
+
+	if (file->f_pos >= RTC_SIZE)
+		return(0);
+	if (length > (RTC_SIZE - file->f_pos))
+		length = RTC_SIZE - file->f_pos;
+
+	spin_lock_irq(&hw_lock);
+	for (total = 0; (total < length); total++, buffer++)
+		SPIIO(CLK, 16, ((file->f_pos + total) << 8) | 0x8000 | *buffer);
+	spin_lock_irq(&hw_lock);
+
+	file->f_pos += total;
+	return(total);
+}
+/* End of RTC file operations */
+
+/* RTC device definition */
+static struct file_operations dragonixrtc_fops =
+{
+	llseek: rtc_lseek,
+	owner:	THIS_MODULE,
+	read: rtc_read,
+	write: rtc_write,
+	open: rtc_open,
+	release: rtc_release
+};
+
+static struct miscdevice dragonixrtc_dev =
+{
+	RTC_MINOR,
+	"rtc",
+	&dragonixrtc_fops
+};
+
+/*****************************************************************************/
+
+static int __init dragonixspi_init(void)
+{
+	// Register the RTC device
+	misc_register(&dragonixrtc_dev);
+
+	printk ("Dragonix SPI: Copyright (C) 2002, Marcos Lois Bermúdez "
+		"(marcos.lois@securez.org)\n");
+
+	return 0;
+}
+
+static void __exit dragonixspi_exit(void)
+{
+	// not used
+}
+
+/*****************************************************************************/
+module_init(dragonixspi_init);
+module_exit(dragonixspi_exit);
diff -urN linux-2.4.29/drivers/char/ds1302.c linux-2.4.29-uc1/drivers/char/ds1302.c
--- linux-2.4.29/drivers/char/ds1302.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/ds1302.c	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,307 @@
+/*****************************************************************************/
+
+/*
+ *	ds1302.c -- driver for Dallas Semiconductor DS1302 Real Time Clock.
+ *
+ * 	(C) Copyright 2001, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/*****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/module.h> 
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/wait.h>
+#include <asm/param.h>
+#ifdef CONFIG_M68VZ328
+#include <asm/MC68VZ328.h>
+#else
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#endif
+#include <linux/rtc.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h> 
+
+/*****************************************************************************/
+
+/*
+ *	Size of RTC region. 32 bytes of calender and 32 bytes RAM.
+ *	Not all addresses are valid in this range...
+ */
+#define	DS1302_MSIZE	0x3f
+
+/*****************************************************************************/
+
+/*
+ *	DS1302 defines.
+ */
+#define	RTC_CMD_READ	0x81		/* Read command */
+#define	RTC_CMD_WRITE	0x80		/* Write command */
+
+#define	RTC_ADDR_YEAR	0x06		/* Address of year register */
+#define	RTC_ADDR_DAY	0x05		/* Address of day of week register */
+#define	RTC_ADDR_MON	0x04		/* Address of month register */
+#define	RTC_ADDR_DATE	0x03		/* Address of day of month register */
+#define	RTC_ADDR_HOUR	0x02		/* Address of hour register */
+#define	RTC_ADDR_MIN	0x01		/* Address of minute register */
+#define	RTC_ADDR_SEC	0x00		/* Address of second register */
+
+/*****************************************************************************/
+
+/*
+ *	Architecture specific code. Accessing the DS1302 will depend
+ *	on exactly how it is wried up. This section specifically coded
+ *	to match the Gilbarco/NAP board based on a 5272 ColdFire CPU.
+ */
+#ifdef  CONFIG_M68VZ328
+/* 
+ * DS1302 connected to port E[0,1,2]
+ */
+static volatile unsigned char *ds1302_dirp =
+	(volatile unsigned char *) (PEDIR_ADDR);
+static volatile unsigned char *ds1302_dp =
+	(volatile unsigned char *) (PEDATA_ADDR);
+
+#define	RTC_RESET	PE_SPMRXD     /* SPMRXD = PE1 of 68VZ328 */
+#define	RTC_IODATA	PE_SPMTXD     /* SPMTXD = PE0 of 68VZ328 */
+#define	RTC_SCLK        PE_SPMCLK     /* SPMCLK = PE2 of 68VZ328 */
+
+#else
+#ifdef	CONFIG_VIOLA_RTC
+static volatile unsigned short	*ds1302_dirp =
+	(volatile unsigned short *) (MCF_MBAR + MCFSIM_PCDDR);
+static volatile unsigned short	*ds1302_dp =
+	(volatile unsigned short *) (MCF_MBAR + MCFSIM_PCDAT);
+
+#define	RTC_RESET	0x0010		/* PC4 of M5272 */
+#define	RTC_IODATA	0x0008		/* PC3 of M5272 */
+#define	RTC_SCLK	0x0004		/* PC2 of M5272 */
+
+#else
+static volatile unsigned short	*ds1302_dirp =
+	(volatile unsigned short *) (MCF_MBAR + MCFSIM_PADDR);
+static volatile unsigned short	*ds1302_dp =
+	(volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+
+#define	RTC_RESET	0x0020		/* PA5 of M5272 */
+#define	RTC_IODATA	0x0040		/* PA6 of M5272 */
+#define	RTC_SCLK	0x0080		/* PA7 of M5272 */
+#endif
+#endif
+
+void ds1302_sendbits(unsigned int val)
+{
+	int	i;
+
+	for (i = 8; (i); i--, val >>= 1) {
+		*ds1302_dp = (*ds1302_dp & ~RTC_IODATA) |
+			 ((val & 0x1) ? RTC_IODATA : 0);
+		*ds1302_dp |= RTC_SCLK;		// clock high
+		*ds1302_dp &= ~RTC_SCLK;	// clock low
+	}
+}
+
+unsigned int ds1302_recvbits(void)
+{
+	unsigned int	val;
+	int		i;
+
+	for (i = 0, val = 0; (i < 8); i++) {
+		val |= (((unsigned int)((*ds1302_dp & RTC_IODATA) ? 1 : 0)) << i);
+		*ds1302_dp |= RTC_SCLK;		// clock high
+		*ds1302_dp &= ~RTC_SCLK;	// clock low
+	}
+	return(val);
+}
+
+unsigned int ds1302_readbyte(unsigned int addr)
+{
+	unsigned int	val;
+	unsigned long	flags;
+
+#if 0
+	printk("ds1302_readbyte(addr=%x)\n", addr);
+#endif
+
+	save_flags(flags); cli();
+	*ds1302_dirp |= RTC_RESET | RTC_IODATA | RTC_SCLK;
+	*ds1302_dp &= ~(RTC_RESET | RTC_IODATA | RTC_SCLK);
+
+	*ds1302_dp |= RTC_RESET;
+	ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ);
+	*ds1302_dirp &= ~RTC_IODATA;
+	val = ds1302_recvbits();
+	*ds1302_dp &= ~RTC_RESET;
+	restore_flags(flags);
+
+	return(val);
+}
+
+void ds1302_writebyte(unsigned int addr, unsigned int val)
+{
+	unsigned long	flags;
+
+#if 0
+	printk("ds1302_writebyte(addr=%x)\n", addr);
+#endif
+
+	save_flags(flags); cli();
+	*ds1302_dirp |= RTC_RESET | RTC_IODATA | RTC_SCLK;
+	*ds1302_dp &= ~(RTC_RESET | RTC_IODATA | RTC_SCLK);
+
+	*ds1302_dp |= RTC_RESET;
+	ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE);
+	ds1302_sendbits(val);
+	*ds1302_dp &= ~RTC_RESET;
+	restore_flags(flags);
+}
+
+void ds1302_reset(void)
+{
+	/* Hardware dependant reset/init */
+	*ds1302_dirp |= RTC_RESET | RTC_IODATA | RTC_SCLK;
+	*ds1302_dp &= ~(RTC_RESET | RTC_IODATA | RTC_SCLK);
+}
+
+/*****************************************************************************/
+
+int __inline__ bcd2int(int val)
+{
+	return((((val & 0xf0) >> 4) * 10) + (val & 0xf));
+}
+
+/*****************************************************************************/
+
+/*
+ *	This is called direct from the kernel timer handling code.
+ *	It gets the current time from the RTC.
+ */
+
+void ds1302_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec)
+{
+#if 0
+	printk("ds1302_gettod()\n");
+#endif
+
+	*year = bcd2int(ds1302_readbyte(RTC_ADDR_YEAR));
+	*mon = bcd2int(ds1302_readbyte(RTC_ADDR_MON));
+	*day = bcd2int(ds1302_readbyte(RTC_ADDR_DATE));
+	*hour = bcd2int(ds1302_readbyte(RTC_ADDR_HOUR));
+	*min = bcd2int(ds1302_readbyte(RTC_ADDR_MIN));
+	*sec = bcd2int(ds1302_readbyte(RTC_ADDR_SEC));
+}
+
+/*****************************************************************************/
+
+/*
+ *	This is called direct from the kernel timer handling code.
+ *	It is supposed to synchronize the kernel clock to the RTC.
+ */
+
+int ds1302_set_clock_mmss(unsigned long nowtime)
+{
+	unsigned long	m, s;
+
+#if 1
+	printk("ds1302_set_clock_mmss(nowtime=%ld)\n", nowtime);
+#endif
+
+	/* FIXME: not implemented yet... */
+	s = nowtime % 60;
+	m = nowtime / 60;
+	return(0);
+}
+
+/*****************************************************************************/
+
+static ssize_t ds1302_read(struct file *fp, char *buf, size_t count, loff_t *ptr)
+{
+	int	total;
+
+#if 0
+	printk("ds1302_read(buf=%x,count=%d)\n", (int) buf, count);
+#endif
+
+	if (fp->f_pos >= DS1302_MSIZE)
+		return(0);
+	if (count > (DS1302_MSIZE - fp->f_pos))
+		count = DS1302_MSIZE - fp->f_pos;
+
+	for (total = 0; (total < count); total++)
+		put_user(ds1302_readbyte(fp->f_pos + total), buf++);
+
+	fp->f_pos += total;
+	return(total);
+}
+
+/*****************************************************************************/
+
+static ssize_t ds1302_write(struct file *fp, const char *buf, size_t count, loff_t *ptr)
+{
+	int	total;
+	char val;
+
+#if 0
+	printk("ds1302_write(buf=%x,count=%d)\n", (int) buf, count);
+#endif
+
+	if (fp->f_pos >= DS1302_MSIZE)
+		return(0);
+	if (count > (DS1302_MSIZE - fp->f_pos))
+		count = DS1302_MSIZE - fp->f_pos;
+
+	for (total = 0; (total < count); total++, buf++)
+	{
+		get_user(val,buf);
+		ds1302_writebyte((fp->f_pos + total), val);
+	}
+
+	fp->f_pos += total;
+	return(total);
+}
+
+/*****************************************************************************/
+
+/*
+ *	Exported file operations structure for driver...
+ */
+
+static struct file_operations ds1302_fops =
+{
+	owner:	THIS_MODULE, 
+	read:	ds1302_read,
+	write:	ds1302_write,
+};
+
+static struct miscdevice ds1302_dev =
+{
+	RTC_MINOR,
+	"rtc",
+	&ds1302_fops
+};
+
+/*****************************************************************************/
+
+static int __init ds1302_init(void)
+{
+	ds1302_reset();
+	misc_register(&ds1302_dev);
+	printk ("DS1302: Copyright (C) 2001, Greg Ungerer "
+		"(gerg@snapgear.com)\n");
+	return 0;
+}
+
+static void __exit ds1302_exit(void)
+{
+	misc_deregister(&ds1302_dev);
+}
+
+/*****************************************************************************/
+module_init(ds1302_init);
+module_exit(ds1302_exit);
diff -urN linux-2.4.29/drivers/char/ds1307.c linux-2.4.29-uc1/drivers/char/ds1307.c
--- linux-2.4.29/drivers/char/ds1307.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/ds1307.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,604 @@
+/*
+ * ds1307.c
+ *
+ * Device driver for Dallas Semiconductor's Real Time Controller DS1307.
+ *
+ * Copyright (C) 2002 Intrinsyc Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include <linux/kernel.h>
+#include <linux/poll.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/rtc.h>
+#include <linux/string.h>
+#include <linux/miscdevice.h>
+#include <linux/proc_fs.h>
+
+#include "ds1307.h"
+
+#define DEBUG 0
+
+#if DEBUG
+static unsigned int rtc_debug = DEBUG;
+#else
+#define rtc_debug 0	/* gcc will remove all the debug code for us */
+#endif
+
+static unsigned short slave_address = DS1307_I2C_SLAVE_ADDR;
+
+struct i2c_driver ds1307_driver;
+struct i2c_client *ds1307_i2c_client = 0;
+
+static unsigned short ignore[] = { I2C_CLIENT_END };
+static unsigned short normal_addr[] = { DS1307_I2C_SLAVE_ADDR, I2C_CLIENT_END };
+
+static struct i2c_client_address_data addr_data = {
+	normal_i2c:		normal_addr,
+	normal_i2c_range:	ignore,
+	probe:			ignore,
+	probe_range:		ignore,
+	ignore: 		ignore,
+	ignore_range:		ignore,
+	force:			ignore,
+};
+
+static int ds1307_rtc_ioctl( struct inode *, struct file *, unsigned int, unsigned long);
+static int ds1307_rtc_open(struct inode *inode, struct file *file);
+static int ds1307_rtc_release(struct inode *inode, struct file *file);
+
+static struct file_operations rtc_fops = {
+	owner:		THIS_MODULE,
+	ioctl:		ds1307_rtc_ioctl,
+	open:		ds1307_rtc_open,
+	release:	ds1307_rtc_release,
+};
+
+static struct miscdevice ds1307_rtc_miscdev = {
+	RTC_MINOR,
+	"rtc",
+	&rtc_fops
+};
+
+static int ds1307_probe(struct i2c_adapter *adap);
+static int ds1307_detach(struct i2c_client *client);
+static int ds1307_command(struct i2c_client *client, unsigned int cmd, void *arg);
+
+struct i2c_driver ds1307_driver = {
+	name:		"DS1307",
+	id:		I2C_DRIVERID_DS1307,
+	flags:		I2C_DF_NOTIFY,
+	attach_adapter: ds1307_probe,
+	detach_client:	ds1307_detach,
+	command:	ds1307_command
+};
+
+static spinlock_t ds1307_rtc_lock = SPIN_LOCK_UNLOCKED;
+
+#define DAT(x) ((unsigned int)((x)->data)) /* keep the control register info */
+
+static int
+ds1307_readram( char *buf, int len)
+{
+	unsigned long	flags;
+	unsigned char ad[1] = { 0 };
+	int ret;
+	struct i2c_msg msgs[2] = {
+		{ ds1307_i2c_client->addr  , 0,        1, ad  },
+		{ ds1307_i2c_client->addr  , I2C_M_RD, len, buf } };
+
+	spin_lock_irqsave(&ds1307_rtc_lock, flags);
+	ret = i2c_transfer(ds1307_i2c_client->adapter, msgs, 2);
+	spin_unlock_irqrestore(&ds1307_rtc_lock,flags);
+
+	return ret;
+}
+
+static void
+ds1307_dumpram( void)
+{
+	unsigned char buf[DS1307_RAM_SIZE];
+	int ret;
+
+	ret = ds1307_readram( buf, DS1307_RAM_SIZE);
+
+	if( ret > 0)
+	{
+		int i;
+		for( i=0; i<DS1307_RAM_SIZE; i++)
+		{
+			printk ("%02X ", buf[i]);
+			if( (i%8) == 7) printk ("\n");
+		}
+		printk ("\n");
+	}
+}
+
+static void
+ds1307_enable_clock( int enable)
+{
+	unsigned char buf[2], ad[1] = { 0 };
+	struct i2c_msg msgs[2] = {
+		{ ds1307_i2c_client->addr	, 0,	    1, ad  },
+		{ ds1307_i2c_client->addr	, I2C_M_RD, 1, buf }
+	};
+	unsigned char ctrl_info;
+	int ret;
+
+	if( enable)
+		ctrl_info = SQW_ENABLE | RATE_32768HZ;
+	else
+		ctrl_info = SQW_DISABLE;
+	ds1307_command(ds1307_i2c_client, DS1307_SETCTRL, &ctrl_info);
+
+	/* read addr 0 (Clock-Halt bit and second counter */
+	ret = i2c_transfer(ds1307_i2c_client->adapter, msgs, 2);
+
+	if( enable)
+		buf[1] = buf[0] & ~CLOCK_HALT; /* clear Clock-Halt bit */
+	else
+		buf[1] = buf[0] | CLOCK_HALT; /* set Clock-Halt bit */
+	buf[0] = 0;	/* control register address on DS1307 */
+
+	ret = i2c_master_send(ds1307_i2c_client, (char *)buf, 2);
+}
+
+static int
+ds1307_attach(struct i2c_adapter *adap, int addr, unsigned short flags,int kind)
+{
+	struct i2c_client *c;
+	unsigned char buf[1], ad[1] = { 7 };
+	struct i2c_msg msgs[2] = {
+		{ addr	, 0,	    1, ad  },
+		{ addr	, I2C_M_RD, 1, buf }
+	};
+	int ret;
+
+	c = (struct i2c_client *)kmalloc(sizeof(*c), GFP_KERNEL);
+	if (!c)
+		return -ENOMEM;
+
+	strcpy(c->name, "DS1307");
+	c->id		= ds1307_driver.id;
+	c->flags	= 0;
+	c->addr 	= addr;
+	c->adapter	= adap;
+	c->driver	= &ds1307_driver;
+	c->data 	= NULL;
+
+	ret = i2c_transfer(c->adapter, msgs, 2);
+
+	if ( ret == 2 )
+	{
+		DAT(c) = buf[0];
+	}
+	else
+		printk ("ds1307_attach(): i2c_transfer() returned %d.\n",ret);
+
+	ds1307_i2c_client = c;
+	ds1307_enable_clock( 1);
+
+	return i2c_attach_client(c);
+}
+
+static int
+ds1307_probe(struct i2c_adapter *adap)
+{
+	return i2c_probe(adap, &addr_data, ds1307_attach);
+}
+
+static int
+ds1307_detach(struct i2c_client *client)
+{
+	i2c_detach_client(client);
+	ds1307_enable_clock( 0);
+
+	return 0;
+}
+
+static void
+ds1307_convert_to_time( struct rtc_time *dt, char *buf)
+{
+	dt->tm_sec = BCD_TO_BIN(buf[0]);
+	dt->tm_min = BCD_TO_BIN(buf[1]);
+
+	if ( TWELVE_HOUR_MODE(buf[2]) )
+	{
+		dt->tm_hour = HOURS_12(buf[2]);
+		if (HOURS_AP(buf[2])) /* PM */
+		{
+			dt->tm_hour += 12;
+		}
+	}
+	else /* 24-hour-mode */
+	{
+		dt->tm_hour = HOURS_24(buf[2]);
+	}
+
+	dt->tm_mday = BCD_TO_BIN(buf[4]);
+	/* dt->tm_mon is zero-based */
+	dt->tm_mon = BCD_TO_BIN(buf[5]) - 1;
+	/* year is 1900 + dt->tm_year */
+	dt->tm_year = BCD_TO_BIN(buf[6]) + 100;
+
+	if( rtc_debug > 2)
+	{
+		printk("ds1307_get_datetime: year = %d\n", dt->tm_year);
+		printk("ds1307_get_datetime: mon  = %d\n", dt->tm_mon);
+		printk("ds1307_get_datetime: mday = %d\n", dt->tm_mday);
+		printk("ds1307_get_datetime: hour = %d\n", dt->tm_hour);
+		printk("ds1307_get_datetime: min  = %d\n", dt->tm_min);
+		printk("ds1307_get_datetime: sec  = %d\n", dt->tm_sec);
+	}
+}
+
+static int
+ds1307_get_datetime(struct i2c_client *client, struct rtc_time *dt)
+{
+	unsigned char buf[7], addr[1] = { 0 };
+	struct i2c_msg msgs[2] = {
+		{ client->addr, 0,	  1, addr },
+		{ client->addr, I2C_M_RD, 7, buf  }
+	};
+	int ret = -EIO;
+
+	memset(buf, 0, sizeof(buf));
+
+	ret = i2c_transfer(client->adapter, msgs, 2);
+
+	if (ret == 2) {
+		ds1307_convert_to_time( dt, buf);
+		ret = 0;
+	}
+	else
+		printk("ds1307_get_datetime(), i2c_transfer() returned %d\n",ret);
+
+	return ret;
+}
+
+static int
+ds1307_set_datetime(struct i2c_client *client, struct rtc_time *dt, int datetoo)
+{
+	unsigned char buf[8];
+	int ret, len = 4;
+
+	if( rtc_debug > 2)
+	{
+		printk("ds1307_set_datetime: tm_year = %d\n", dt->tm_year);
+		printk("ds1307_set_datetime: tm_mon  = %d\n", dt->tm_mon);
+		printk("ds1307_set_datetime: tm_mday = %d\n", dt->tm_mday);
+		printk("ds1307_set_datetime: tm_hour = %d\n", dt->tm_hour);
+		printk("ds1307_set_datetime: tm_min  = %d\n", dt->tm_min);
+		printk("ds1307_set_datetime: tm_sec  = %d\n", dt->tm_sec);
+	}
+
+	buf[0] = 0;	/* register address on DS1307 */
+	buf[1] = (BIN_TO_BCD(dt->tm_sec));
+	buf[2] = (BIN_TO_BCD(dt->tm_min));
+	buf[3] = (BIN_TO_BCD(dt->tm_hour));
+
+	if (datetoo) {
+		len = 8;
+		/* we skip buf[4] as we don't use day-of-week. */
+		buf[5] = (BIN_TO_BCD(dt->tm_mday));
+		buf[6] = (BIN_TO_BCD(dt->tm_mon + 1));
+		/* The year only ranges from 0-99, we are being passed an offset from 1900,
+		 * and the chip calulates leap years based on 2000, thus we adjust by 100.
+		 */
+		buf[7] = (BIN_TO_BCD(dt->tm_year - 100));
+	}
+	ret = i2c_master_send(client, (char *)buf, len);
+	if (ret == len)
+		ret = 0;
+	else
+		printk("ds1307_set_datetime(), i2c_master_send() returned %d\n",ret);
+
+
+	return ret;
+}
+
+static int
+ds1307_get_ctrl(struct i2c_client *client, unsigned char *ctrl)
+{
+	*ctrl = DAT(client);
+
+	return 0;
+}
+
+static int
+ds1307_set_ctrl(struct i2c_client *client, unsigned char *cinfo)
+{
+	unsigned char buf[2];
+	int ret;
+
+
+	buf[0] = 7;	/* control register address on DS1307 */
+	buf[1] = *cinfo;
+	/* save the control reg info in the client data field so that get_ctrl
+	 * function doesn't have to do an I2C transfer to get it.
+	 */
+	DAT(client) = buf[1];
+
+	ret = i2c_master_send(client, (char *)buf, 2);
+
+	return ret;
+}
+
+static int
+ds1307_read_mem(struct i2c_client *client, struct rtc_mem *mem)
+{
+	unsigned char addr[1];
+	struct i2c_msg msgs[2] = {
+		{ client->addr, 0,	  1, addr },
+		{ client->addr, I2C_M_RD, mem->nr, mem->data }
+	};
+
+	if ( (mem->loc < DS1307_RAM_ADDR_START) ||
+	     ((mem->loc + mem->nr -1) > DS1307_RAM_ADDR_END) )
+		return -EINVAL;
+
+	addr[0] = mem->loc;
+
+	return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
+}
+
+static int
+ds1307_write_mem(struct i2c_client *client, struct rtc_mem *mem)
+{
+	unsigned char addr[1];
+	struct i2c_msg msgs[2] = {
+		{ client->addr, 0, 1, addr },
+		{ client->addr, 0, mem->nr, mem->data }
+	};
+
+	if ( (mem->loc < DS1307_RAM_ADDR_START) ||
+	     ((mem->loc + mem->nr -1) > DS1307_RAM_ADDR_END) )
+		return -EINVAL;
+
+	addr[0] = mem->loc;
+
+	return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
+}
+
+static int
+ds1307_command(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+	switch (cmd) {
+	case DS1307_GETDATETIME:
+		return ds1307_get_datetime(client, arg);
+
+	case DS1307_SETTIME:
+		return ds1307_set_datetime(client, arg, 0);
+
+	case DS1307_SETDATETIME:
+		return ds1307_set_datetime(client, arg, 1);
+
+	case DS1307_GETCTRL:
+		return ds1307_get_ctrl(client, arg);
+
+	case DS1307_SETCTRL:
+		return ds1307_set_ctrl(client, arg);
+
+	case DS1307_MEM_READ:
+		return ds1307_read_mem(client, arg);
+
+	case DS1307_MEM_WRITE:
+		return ds1307_write_mem(client, arg);
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static int
+ds1307_rtc_open(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static int
+ds1307_rtc_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static int
+ds1307_rtc_ioctl( struct inode *inode, struct file *file,
+		unsigned int cmd, unsigned long arg)
+{
+	unsigned long	flags;
+	struct rtc_time wtime;
+	int status = 0;
+
+	switch (cmd) {
+		default:
+		case RTC_UIE_ON:
+		case RTC_UIE_OFF:
+		case RTC_PIE_ON:
+		case RTC_PIE_OFF:
+		case RTC_AIE_ON:
+		case RTC_AIE_OFF:
+		case RTC_ALM_SET:
+		case RTC_ALM_READ:
+		case RTC_IRQP_READ:
+		case RTC_IRQP_SET:
+		case RTC_EPOCH_READ:
+		case RTC_EPOCH_SET:
+		case RTC_WKALM_SET:
+		case RTC_WKALM_RD:
+			status = -EINVAL;
+			break;
+
+		case RTC_RD_TIME:
+			spin_lock_irqsave(&ds1307_rtc_lock, flags);
+			ds1307_command( ds1307_i2c_client, DS1307_GETDATETIME, &wtime);
+			spin_unlock_irqrestore(&ds1307_rtc_lock,flags);
+
+			if( copy_to_user((void *)arg, &wtime, sizeof (struct rtc_time)))
+				status = -EFAULT;
+			break;
+
+		case RTC_SET_TIME:
+			if (!capable(CAP_SYS_TIME))
+			{
+				status = -EACCES;
+				break;
+			}
+
+			if (copy_from_user(&wtime, (struct rtc_time *)arg, sizeof(struct rtc_time)) )
+			{
+				status = -EFAULT;
+				break;
+			}
+
+			spin_lock_irqsave(&ds1307_rtc_lock, flags);
+			ds1307_command( ds1307_i2c_client, DS1307_SETDATETIME, &wtime);
+			spin_unlock_irqrestore(&ds1307_rtc_lock,flags);
+			break;
+	}
+
+	return status;
+}
+
+static char *
+ds1307_mon2str( unsigned int mon)
+{
+	char *mon2str[12] = {
+	  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+	  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+	};
+	if( mon > 11) return "error";
+	else return mon2str[ mon];
+}
+
+static int ds1307_rtc_proc_output( char *buf)
+{
+#define CHECK(ctrl,bit) ((ctrl & bit) ? "yes" : "no")
+	unsigned char ram[DS1307_RAM_SIZE];
+	int ret;
+
+	char *p = buf;
+
+	ret = ds1307_readram( ram, DS1307_RAM_SIZE);
+	if( ret > 0)
+	{
+		int i;
+		struct rtc_time dt;
+		char text[9];
+
+		p += sprintf(p, "DS1307 (64x8 Serial Real Time Clock)\n");
+
+		ds1307_convert_to_time( &dt, ram);
+		p += sprintf(p, "Date/Time	     : %02d-%s-%04d %02d:%02d:%02d\n",
+			dt.tm_mday, ds1307_mon2str(dt.tm_mon), dt.tm_year + 1900,
+			dt.tm_hour, dt.tm_min, dt.tm_sec);
+
+		p += sprintf(p, "Clock halted	     : %s\n", CHECK(ram[0],0x80));
+		p += sprintf(p, "24h mode	     : %s\n", CHECK(ram[2],0x40));
+		p += sprintf(p, "Square wave enabled : %s\n", CHECK(ram[7],0x10));
+		p += sprintf(p, "Freq		     : ");
+
+		switch( ram[7] & 0x03)
+		{
+			case RATE_1HZ:
+				p += sprintf(p, "1Hz\n");
+				break;
+			case RATE_4096HZ:
+				p += sprintf(p, "4.096kHz\n");
+				break;
+			case RATE_8192HZ:
+				p += sprintf(p, "8.192kHz\n");
+				break;
+			case RATE_32768HZ:
+			default:
+				p += sprintf(p, "32.768kHz\n");
+				break;
+
+		}
+
+		p += sprintf(p, "RAM dump:\n");
+		text[8]='\0';
+		for( i=0; i<DS1307_RAM_SIZE; i++)
+		{
+			p += sprintf(p, "%02X ", ram[i]);
+
+			if( (ram[i] < 32) || (ram[i]>126)) ram[i]='.';
+			text[i%8] = ram[i];
+			if( (i%8) == 7) p += sprintf(p, "%s\n",text);
+		}
+		p += sprintf(p, "\n");
+	}
+	else
+	{
+		p += sprintf(p, "Failed to read RTC memory!\n");
+	}
+
+	return	p - buf;
+}
+
+static int ds1307_rtc_read_proc(char *page, char **start, off_t off,
+		int count, int *eof, void *data)
+{
+	int len = ds1307_rtc_proc_output (page);
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+	return len;
+}
+
+static __init int ds1307_init(void)
+{
+	int retval=0;
+
+	if( slave_address != 0xffff)
+	{
+		normal_addr[0] = slave_address;
+	}
+
+	if( normal_addr[0] == 0xffff)
+	{
+		printk(KERN_ERR"I2C: Invalid slave address for DS1307 RTC (%#x)\n",
+			normal_addr[0]);
+		return -EINVAL;
+	}
+
+	retval = i2c_add_driver(&ds1307_driver);
+
+	if (retval==0)
+	{
+		misc_register (&ds1307_rtc_miscdev);
+		create_proc_read_entry (PROC_DS1307_NAME, 0, 0, ds1307_rtc_read_proc, NULL);
+		printk("I2C: DS1307 RTC driver successfully loaded\n");
+
+		if( rtc_debug) ds1307_dumpram();
+	}
+	return retval;
+}
+
+static __exit void ds1307_exit(void)
+{
+	remove_proc_entry (PROC_DS1307_NAME, NULL);
+	misc_deregister(&ds1307_rtc_miscdev);
+	i2c_del_driver(&ds1307_driver);
+}
+
+module_init(ds1307_init);
+module_exit(ds1307_exit);
+
+MODULE_PARM (slave_address, "i");
+MODULE_PARM_DESC (slave_address, "I2C slave address for DS1307 RTC.");
+
+MODULE_AUTHOR ("Intrinsyc Software Inc.");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/drivers/char/ds1307.h linux-2.4.29-uc1/drivers/char/ds1307.h
--- linux-2.4.29/drivers/char/ds1307.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/ds1307.h	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,58 @@
+/*
+ * ds1307.h
+ *
+ * Copyright (C) 2002 Intrinsyc Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef DS1307_H
+#define DS1307_H
+
+#if defined(CONFIG_PXA_EMERSON_SBC) || defined(CONFIG_PXA_CERF_BOARD) || defined(CONFIG_MACH_CSB337)
+	#define DS1307_I2C_SLAVE_ADDR	0x68
+#else
+	#define DS1307_I2C_SLAVE_ADDR	0xffff
+#endif
+
+#define DS1307_RAM_ADDR_START	0x08
+#define DS1307_RAM_ADDR_END	0x3F
+#define DS1307_RAM_SIZE 0x40
+
+#define PROC_DS1307_NAME	"driver/ds1307"
+
+struct rtc_mem {
+	unsigned int	loc;
+	unsigned int	nr;
+	unsigned char	*data;
+};
+
+#define DS1307_GETDATETIME	0
+#define DS1307_SETTIME		1
+#define DS1307_SETDATETIME	2
+#define DS1307_GETCTRL		3
+#define DS1307_SETCTRL		4
+#define DS1307_MEM_READ		5
+#define DS1307_MEM_WRITE	6
+
+#define SQW_ENABLE	0x10	/* Square Wave Enable */
+#define SQW_DISABLE	0x00	/* Square Wave disable */
+
+#define RATE_32768HZ	0x03	/* Rate Select 32.768KHz */
+#define RATE_8192HZ	0x02	/* Rate Select 8.192KHz */
+#define RATE_4096HZ	0x01	/* Rate Select 4.096KHz */
+#define RATE_1HZ	0x00	/* Rate Select 1Hz */
+
+#define CLOCK_HALT	0x80	/* Clock Halt */
+
+#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
+#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
+
+#define TWELVE_HOUR_MODE(n)	(((n)>>6)&1)
+#define HOURS_AP(n)		(((n)>>5)&1)
+#define HOURS_12(n)		BCD_TO_BIN((n)&0x1F)
+#define HOURS_24(n)		BCD_TO_BIN((n)&0x3F)
+
+#endif
diff -urN linux-2.4.29/drivers/char/edb7312_ts.c linux-2.4.29-uc1/drivers/char/edb7312_ts.c
--- linux-2.4.29/drivers/char/edb7312_ts.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/edb7312_ts.c	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,414 @@
+/*
+ *	Copyright (c) 2003 Petko Manolov <petkan@nucleusys.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/interrupt.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/arch/irqs.h>
+#include <asm/hardware/clps7111.h>
+
+
+#define DRV_AUTHOR	"Petko Manolov <petkan@nucleusys.com>"
+#define	DRV_DESC	"touchscreen"
+MODULE_AUTHOR( DRV_AUTHOR );
+MODULE_DESCRIPTION( DRV_DESC );
+MODULE_LICENSE("GPL");
+
+#undef	DEBUG
+#undef	EXTENDED_MODE
+
+#define	TS_MAJOR	16
+#define	TS_IRQ		IRQ_EINT2
+/* must be power of 2 */
+#define	EVT_BUF_SIZE	(1<<6)
+#define	EVT_BUF_MASK	(EVT_BUF_SIZE - 1)
+
+#define	SSIBUSY		(1 << 26)
+#define	ADCCON		(1 << 0)
+#define	ADCCKNSEN	(1 << 4)
+
+/* these assume 18-74Mhz mode */
+#define	SSI_SPD_4K	0
+#define	SSI_SPD_16K	(1 << 16)
+#define	SSI_SPD_64K	(1 << 17)
+#define	SSI_SPD_128K	((1 << 17) | (1 << 16))
+#define	SSI_SPD_MASK	~((1 << 17) | (1 << 16))
+
+#define	TXFRAMEN	(1 << 14)
+
+#ifdef	EXTENDED_MODE
+#define	FLEN		(24 << 7)
+#define	CED(x)		((x) << 24)
+#define	CMD_GET_X	(CED(0xd3) | TXFRAMEN | FLEN | 16)
+#define	CMD_GET_Y	(CED(0x93) | TXFRAMEN | FLEN | 16)
+#define	CMD_GET_Z1	(CED(0xb3) | TXFRAMEN | FLEN | 16)
+#define	CMD_GET_Z2	(CED(0xc3) | TXFRAMEN | FLEN | 16)
+#else
+#define	FLEN		(24 << 8)
+#define	CMD_GET_X	(TXFRAMEN | FLEN | 0xd3)
+#define	CMD_GET_Y	(TXFRAMEN | FLEN | 0x93)
+#define	CMD_GET_Z1	(TXFRAMEN | FLEN | 0xb3)
+#define	CMD_GET_Z2	(TXFRAMEN | FLEN | 0xc3)
+#endif
+/* do sampling every 50ms */
+#define	TS_SR		(HZ/20)
+
+//#define TOUCH_DEBUG
+#ifdef	DEBUG
+#define	dbg(x, arg...)	printk(x, ##arg)
+#else
+#define	dbg(x, ...)
+#endif	/* DEBUG */
+#define	bptr_inc(x)	((x) = ((x + 1) & EVT_BUF_MASK))
+#define	wait_ssibusy()	({ int t;	\
+			do {t = clps_readl(SYSFLG1);} while (t & SSIBUSY);})
+
+typedef struct {
+	unsigned short pressure;
+	unsigned short x;
+	unsigned short y;
+	unsigned short ms;
+} ts_evt_t;
+
+typedef struct {
+	int state;
+	int head, tail;
+	ts_evt_t ev_buf[EVT_BUF_SIZE];
+	int raw_x, raw_y, raw_z1, raw_z2;
+	struct timer_list timer;
+	struct tasklet_struct tl;
+	spinlock_t lock;
+	wait_queue_head_t buff_wait;
+	struct semaphore open_sem;
+} tss_t;
+
+enum {
+	TS_IDLE = 0,
+	TS_GET_X,
+	TS_GET_Y,
+	TS_GET_Z1,
+	TS_GET_Z2
+};
+
+static tss_t ts;
+static struct fasync_struct *fasync;
+
+
+static void edb7312_ts_setup(void)
+{
+	int tmp;
+
+	wait_ssibusy();
+	tmp = clps_readl(SYSCON3);
+#ifdef EXTENDED_MODE	
+	tmp |= ADCCON;
+#endif
+	tmp &= ~ADCCKNSEN;
+	clps_writel(tmp, SYSCON3);
+	/* set SSI clock speed */
+	tmp = clps_readl(SYSCON1) & SSI_SPD_MASK;
+	tmp |= SSI_SPD_128K;
+	clps_writel(tmp, SYSCON1);
+	
+	/*
+	 *  note: EINT2 is used by the IDE interface too, we don't
+	 *  clear this bit on exit since it might be still in use;
+	 */
+	tmp = clps_readl(INTMR1);
+	tmp |= (1 << IRQ_EINT2);
+	clps_writel(tmp, INTMR1);
+	
+	/*
+	 *  init ads7846 here... ?!?
+	 */
+}
+
+/*
+ *  enable the interrupts from SSI, EINT2 should also be enabled
+ */
+static void ssi_enable_irq(void)
+{
+	int tmp;
+	
+	tmp = clps_readl(INTMR1);
+	tmp |= 1 << IRQ_SSEOTI;
+	clps_writel(tmp, INTMR1);
+}
+
+
+static void ssi_disable_irq(void)
+{
+	int tmp;
+	
+	tmp = clps_readl(INTMR1);
+	tmp &= ~(1 << IRQ_SSEOTI);
+	clps_writel(tmp, INTMR1);
+}
+
+/*
+ *  shit-shit-shit is what represents very accurate my feelings at the moment
+ */
+static void ssi_ts_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int res;
+	tss_t *tsp = (tss_t *)dev_id;
+
+//	dbg("%s: state=%d\n", __FUNCTION__, tsp->state);
+
+	/* this read should also be an EOI */
+	res = clps_readl(SYNCIO);
+	
+	switch (tsp->state) {
+	case TS_IDLE:
+		break;
+	case TS_GET_X:
+		tsp->raw_x = res;
+		clps_writel(CMD_GET_Y, SYNCIO);
+		tsp->state = TS_GET_Y;
+		break;
+	case TS_GET_Y:
+		tsp->raw_y = res;
+		clps_writel(CMD_GET_Z1, SYNCIO);
+		tsp->state = TS_GET_Z1;
+		break;
+	case TS_GET_Z1:
+		tsp->raw_z1 = res;
+		clps_writel(CMD_GET_Z2, SYNCIO);
+		tsp->state = TS_GET_Z2;
+		break;
+	case TS_GET_Z2:
+		tsp->raw_z2 = res;
+		tsp->state = TS_IDLE;
+		tasklet_schedule(&tsp->tl);
+		break;
+	default:
+#ifdef TOUCH_DEBUG
+		printk("%s: no such state %d\n", __FUNCTION__, tsp->state);
+#endif
+	}
+//	dbg("res=%08x\n", res);
+}
+
+
+static void ts_timer(unsigned long ptr)
+{
+	tss_t *tsp = (tss_t *)ptr;
+
+#ifdef TOUCH_DEBUG
+	if (tsp->state != TS_IDLE)
+		printk("%s: run while state is not TS_IDLE\n", __FUNCTION__);
+#endif
+	
+	clps_writel(CMD_GET_X, SYNCIO);
+	tsp->state = TS_GET_X;
+	
+	tsp->timer.expires = jiffies + TS_SR;
+	add_timer(&tsp->timer);
+}
+
+
+static void ts_calc(unsigned long ptr)
+{
+	tss_t *tsp = (tss_t *)ptr;
+	int Rt;
+
+#ifdef TOUCH_DEBUG
+	if (tsp->state != TS_IDLE) {
+		printk("%s: in the middle of data acquisition\n", __FUNCTION__);
+	}
+#endif
+	
+	tsp->raw_x = (tsp->raw_x >> 4) & 0xfff;
+	tsp->raw_y = (tsp->raw_y >> 4) & 0xfff;
+	tsp->raw_z1 = (tsp->raw_z1 >> 4) & 0xfff;
+	tsp->raw_z2 = (tsp->raw_z2 >> 4) & 0xfff;
+	/* put the event in buffer only if it's PENDOWN */
+	spin_lock_bh(&tsp->lock);
+	if (!tsp->raw_z1) {
+		goto out;
+	}
+	Rt = (580 * tsp->raw_x * (tsp->raw_z2 - tsp->raw_z1) /
+	         tsp->raw_z1) >> 12;
+	if ((Rt < 0) || (Rt < 200) || (Rt > 4200))
+		goto out;
+	tsp->ev_buf[tsp->head].pressure = Rt;
+	tsp->ev_buf[tsp->head].x = 320 - (tsp->raw_x/6);
+	tsp->ev_buf[tsp->head].y = 240 - (tsp->raw_y/8);
+#ifdef TOUCH_DEBUG
+	printk("%s: Rt is %d, X=%d, Y=%d\n", __FUNCTION__, Rt,
+	       tsp->ev_buf[tsp->head].x, tsp->ev_buf[tsp->head].y);
+#endif
+	bptr_inc(tsp->head);
+	/* event buffer full, drop the last entry */
+	if (tsp->head == tsp->tail)
+		bptr_inc(tsp->tail);
+out:
+	spin_unlock_bh(&tsp->lock);
+	wake_up_interruptible(&tsp->buff_wait);
+}
+
+
+static int edb7312ts_fasync(int fd, struct file *filp, int on)
+{
+	dbg("%s: blah\n", __FUNCTION__);
+	return fasync_helper(fd, filp, on, &fasync);
+}
+
+
+static int edb7312ts_ioctl(struct inode * inode, struct file *filp,
+                           unsigned int cmd, unsigned long arg)
+{
+	dbg("%s: #%d\n", __FUNCTION__, cmd);
+	return 0;
+}
+
+
+static unsigned int edb7312ts_poll(struct file *filp, poll_table *wait)
+{
+	dbg("%s: blah\n", __FUNCTION__);
+	poll_wait(filp, &ts.buff_wait, wait);
+	if (ts.head == ts.tail)
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+
+static ssize_t edb7312ts_read(struct file *filp, char *buf,
+                              size_t count, loff_t *l)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	size_t tmp = count;
+	
+	dbg("%s: requested %d bytes to read\n", __FUNCTION__, count);
+	if (ts.head == ts.tail) {	/* buffer empty*/
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		add_wait_queue(&ts.buff_wait, &wait);
+repeat:
+		set_current_state(TASK_INTERRUPTIBLE);;
+		if (ts.head == ts.tail && !signal_pending(current)) {
+			schedule();
+			goto repeat;
+		}
+		current->state = TASK_RUNNING;
+		remove_wait_queue(&ts.buff_wait, &wait);
+	}
+	while ((ts.tail != ts.head) && (count >= sizeof(ts_evt_t))) {
+		copy_to_user(buf, &ts.ev_buf[ts.tail], sizeof(ts_evt_t));
+		spin_lock_bh(&ts.lock);
+		bptr_inc(ts.tail);
+		spin_unlock_bh(&ts.lock);
+		count -= sizeof(ts_evt_t);
+	}
+	
+	return tmp - count;
+}
+
+
+static int edb7312ts_open(struct inode * inode, struct file * filp)
+{
+	if (down_trylock(&ts.open_sem)) {
+#ifdef TOUCH_DEBUG
+		printk("%s: device is busy\n", __FUNCTION__);
+#endif
+		return -EBUSY;
+	}
+	/* prep the ts structure */
+	ts.head = ts.tail = 0;
+	/*
+	 *  there is no real spin locks on ARM.  this is a bit subtle:
+	 *  spin_lock_bh() resolves as local_bh_disable() which is what
+	 *  we need.  also helps if one day this get ported to a smp arch...
+	 */
+	ts.lock = SPIN_LOCK_UNLOCKED;
+		
+	/* clear any pending interrupt.. */
+	clps_readl(SYNCIO);
+	ssi_enable_irq();
+	
+	init_timer(&ts.timer);
+	ts.timer.function = ts_timer;
+	ts.timer.data = (unsigned long)&ts;
+	ts.timer.expires = jiffies + TS_SR;
+	add_timer(&ts.timer);
+	
+	return 0;
+}
+
+
+static int edb7312ts_release(struct inode * inode, struct file * filp)
+{
+	del_timer_sync(&ts.timer);
+	ssi_disable_irq();
+	edb7312ts_fasync(-1, filp, 0);
+	tasklet_kill(&ts.tl);
+	up(&ts.open_sem);
+
+	return 0;
+}
+
+
+static struct file_operations edb7312ts_fops = {
+	owner:		THIS_MODULE,
+	read:		edb7312ts_read,
+	poll:		edb7312ts_poll,
+	ioctl:		edb7312ts_ioctl,
+	fasync:		edb7312ts_fasync,
+	open:		edb7312ts_open,
+	release:	edb7312ts_release,
+};
+
+
+int __init edb7312ts_init(void)
+{
+	int ret=0;
+
+	/* set up everything here but enable SSEOTI in open() */
+	edb7312_ts_setup();
+	
+	if ((ret = register_chrdev(TS_MAJOR, DRV_DESC, &edb7312ts_fops)) < 0) {
+		printk("can't register char driver, major #%d\n", TS_MAJOR);
+		goto out;
+	}
+	
+	ret = request_irq(IRQ_SSEOTI, ssi_ts_irq, SA_INTERRUPT, DRV_DESC, &ts);
+	if (ret) {
+		printk("can't get irq #%d, ret=%d\n", IRQ_SSEOTI, ret);
+		goto bad_ssi_irq;
+	}
+	
+	memset(&ts, 0, sizeof(tss_t));
+	init_MUTEX(&ts.open_sem);
+	init_waitqueue_head(&ts.buff_wait);
+	tasklet_init(&ts.tl, ts_calc, (unsigned long)&ts);
+	printk("Registered touch-screen driver\n");	
+	goto out;
+	
+bad_ssi_irq:
+	unregister_chrdev(TS_MAJOR, DRV_DESC);
+out:
+	return ret;
+}
+
+
+void __exit edb7312ts_exit(void)
+{
+	free_irq(IRQ_SSEOTI, &ts);
+	unregister_chrdev(TS_MAJOR, DRV_DESC);
+	printk("Deregistered touch-screen driver\n");
+}
+
+
+module_init(edb7312ts_init);
+module_exit(edb7312ts_exit);
diff -urN linux-2.4.29/drivers/char/ep93xx_keymap.map linux-2.4.29-uc1/drivers/char/ep93xx_keymap.map
--- linux-2.4.29/drivers/char/ep93xx_keymap.map	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/ep93xx_keymap.map	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,329 @@
+#  Keymap for Cherry G84-4001QAU keyboard matrix on Cirrus EP93xx
+#
+#		Derived from arm-linux-2.2.12/keymap_psion.map.
+#		Modified by ISDCorp 1999,2001 
+#
+# (c) Copyright 2001 LynuxWorks, Inc., San Jose, CA.  All rights reserved.
+#   
+# Default kernel keymap. This uses 7 modifier combinations.
+keymaps 0-2,4-5,8,12
+# Change the above line into
+#	keymaps 0-2,4-6,8,12
+# in case you want the entries
+#	altgr   control keycode  83 = Boot            
+#	altgr   control keycode 111 = Boot            
+# below.
+#
+# In fact AltGr is used very little, and one more keymap can
+# be saved by mapping AltGr to Alt (and adapting a few entries):
+# keycode 100 = Alt
+#
+keycode   1 = Escape           Escape          
+	alt     keycode   1 = Meta_Escape     
+keycode   2 = one              exclam          
+	alt     keycode   2 = Meta_one        
+keycode   3 = Tab              Tab             
+	alt     keycode  3 = Meta_Tab        
+keycode   4 = Caps_Lock       
+keycode   5 = grave            asciitilde      
+	control keycode  5 = nul             
+	alt     keycode  5 = Meta_grave      
+keycode   6 = space            space           
+	control keycode  6 = nul             
+	alt     keycode  6 = Meta_space      
+keycode   7 = Left            
+	alt     keycode 7 = Decr_Console
+keycode   8 = Up
+keycode   9 = Down            
+keycode  10 = Right           
+	alt     keycode 10 = Incr_Console
+keycode  11 = Shift           
+keycode  12 = Control         
+keycode  13 = 		#AltGr           
+keycode  14 = Alt             
+keycode  15 = AltGr           
+keycode  16 = Shift           
+keycode  17 = F5               F15              Console_17      
+	control keycode  17 = F5              
+	alt     keycode  17 = Console_5       
+	control alt     keycode  17 = Console_5       
+keycode  18 = six              asciicircum     
+	control keycode   18 = Control_asciicircum
+	alt     keycode   18 = Meta_six        
+keycode  19 = t               
+keycode  20 = g               
+keycode  21 = b
+	altgr   keycode  21 = Hex_B
+keycode  22 = slash            question        
+	control keycode  22 = Delete          
+	alt     keycode  22 = Meta_slash      
+keycode  23 = semicolon        colon           
+	alt     keycode  23 = Meta_semicolon  
+keycode  24 = p               
+keycode  25 = minus            underscore       backslash       
+	control	keycode  25 = Control_underscore
+	shift	control	keycode  25 = Control_underscore
+	alt	keycode  25 = Meta_minus      
+keycode  26 = F10              F20              Console_22      
+	control keycode  26 = F10             
+	alt     keycode  26 = Console_10      
+	control alt     keycode  26 = Console_10      
+keycode  27 = 
+keycode  28 = 
+keycode  29 = 
+keycode  30 = 
+keycode  31 = 
+keycode  32 = 
+keycode  33 = F4               F14              Console_16      
+	control keycode  33 = F4              
+	alt     keycode  33 = Console_4       
+	control alt     keycode  33 = Console_4       
+keycode  34 = five             percent         
+	control keycode   34 = Control_bracketright
+	alt     keycode   34 = Meta_five       
+keycode  35 = r               
+keycode  36 = f
+	altgr   keycode  36 = Hex_F               
+keycode  37 = v               
+keycode  38 = Delete           Delete          
+	control keycode  38 = BackSpace
+	alt     keycode  38 = Meta_Delete     
+keycode  39 = apostrophe       quotedbl        
+	control keycode  39 = Control_g       
+	alt     keycode  39 = Meta_apostrophe 
+keycode  40 = bracketleft      braceleft       
+	control keycode  40 = Escape          
+	alt     keycode  40 = Meta_bracketleft
+keycode  41 = equal            plus            
+	alt     keycode  41 = Meta_equal      
+keycode  42 = Num_Lock
+	shift   keycode  42 = Bare_Num_Lock
+keycode  43 = 
+keycode  44 = 
+keycode  45 = 
+keycode  46 = 
+keycode  47 = 
+keycode  48 = 
+keycode  49 = F3               F13              Console_15      
+	control keycode  49 = F3              
+	alt     keycode  49 = Console_3       
+	control alt     keycode  49 = Console_3       
+keycode  50 = four             dollar           dollar          
+	control keycode   50 = Control_backslash
+	alt     keycode   50 = Meta_four       
+keycode  51 = e
+	altgr   keycode  51 = Hex_E   
+keycode  52 = d
+	altgr   keycode  52 = Hex_D   
+keycode  53 = c
+	altgr   keycode  53 = Hex_C   
+keycode  54 = Insert          
+keycode  55 =      
+keycode  56 = bracketright     braceright       asciitilde      
+	control keycode  56 = Control_bracketright
+	alt     keycode  56 = Meta_bracketright
+keycode  57 = BackSpace     
+keycode  58 =      
+keycode  59 =      
+keycode  60 =      
+keycode  61 =      
+keycode  62 =      
+keycode  63 =      
+keycode  64 =      
+keycode  65 = F2               F12              Console_14      
+	control keycode  65 = F2              
+	alt     keycode  65 = Console_2       
+	control alt     keycode  65 = Console_2       
+keycode   66 = three            numbersign      
+	control keycode   66 = Escape          
+	alt     keycode   66 = Meta_three      
+keycode  67 = w               
+keycode  68 = s               
+keycode  69 = x               
+keycode  70 =                
+keycode  71 = Return          
+	alt     keycode  71 = Meta_Control_m  
+keycode  72 = backslash        bar             
+	control keycode  72 = Control_backslash
+	alt     keycode  72 = Meta_backslash  
+keycode  73 =                
+keycode  74 = Scroll_Lock      Show_Memory      Show_Registers  
+	control keycode  74 = Show_State      
+	alt     keycode  74 = Scroll_Lock     
+keycode  75 =                
+keycode  76 =                
+keycode  77 =                
+keycode  78 =                
+keycode  79 =                
+keycode  80 =                
+keycode  81 = F1               F11              Console_13      
+	control keycode  81 = F1              
+	alt     keycode  81 = Console_1       
+	control alt     keycode  81 = Console_1       
+keycode  82 = two              at               at              
+	control	keycode   82 = nul             
+	shift	control	keycode   82 = nul             
+	alt	keycode   82 = Meta_two        
+keycode  83 = q               
+keycode  84 = a
+	altgr   keycode  84 = Hex_A
+keycode  85 = z               
+keycode  86 = Select             # End
+keycode  87 = Next		# Pg Down
+keycode  88 = Prior		# Pg Up              
+keycode  89 = Find               # Home
+keycode  90 = Break           
+keycode  91 =
+keycode  92 =
+keycode  93 =
+keycode  94 =
+keycode  95 =
+keycode  96 = 
+keycode  97 = F6               F16              Console_18      
+	control keycode  97 = F6              
+	alt     keycode  97 = Console_6       
+	control alt     keycode  97 = Console_6       
+keycode  98 = seven            ampersand        braceleft       
+	control keycode   98 = Control_underscore
+	alt     keycode   98 = Meta_seven      
+keycode  99 = y               
+keycode 100 = h               
+keycode 101 = n               
+keycode 102 = period           greater         
+	control keycode  102 = Compose         
+	alt     keycode  102 = Meta_period     
+keycode 103 = l               
+keycode 104 = o               
+keycode 105 = zero             parenright       braceright      
+	alt     keycode  105 = Meta_zero       
+keycode 106 = F9               F19              Console_21      
+	control keycode  106 = F9              
+	alt     keycode  106 = Console_9       
+	control alt     keycode  106 = Console_9       
+keycode 107 = 
+keycode 108 = 
+keycode 109 = 
+keycode 110 = 
+keycode 111 = 
+keycode 112 = 
+keycode 113 = F7               F17              Console_19      
+	control keycode  113 = F7              
+	alt     keycode  113 = Console_7       
+	control alt     keycode  113 = Console_7       
+keycode 114 = eight            asterisk         bracketleft     
+	control keycode   114 = Delete          
+	alt     keycode   114 = Meta_eight      
+keycode 115 = u               
+keycode 116 = j               
+keycode 117 = m               
+keycode 118 = comma            less            
+	alt     keycode  118 = Meta_comma      
+keycode 119 = k               
+keycode 120 = i               
+keycode 121 = nine             parenleft        bracketright    
+	alt     keycode  121 = Meta_nine       
+keycode 122 = F8               F18              Console_20      
+	control keycode  122 = F8              
+	alt     keycode  122 = Console_8       
+	control alt     keycode  122 = Console_8       
+keycode 123 =
+keycode 124 =
+keycode 125 =
+keycode 126 =
+keycode 127 =
+string F1 = "\033[[A"
+string F2 = "\033[[B"
+string F3 = "\033[[C"
+string F4 = "\033[[D"
+string F5 = "\033[[E"
+string F6 = "\033[17~"
+string F7 = "\033[18~"
+string F8 = "\033[19~"
+string F9 = "\033[20~"
+string F10 = "\033[21~"
+string F11 = "\033[23~"
+string F12 = "\033[24~"
+string F13 = "\033[25~"
+string F14 = "\033[26~"
+string F15 = "\033[28~"
+string F16 = "\033[29~"
+string F17 = "\033[31~"
+string F18 = "\033[32~"
+string F19 = "\033[33~"
+string F20 = "\033[34~"
+string Find = "\033[1~"
+string Insert = "\033[2~"
+string Remove = "\033[3~"
+string Select = "\033[4~"
+string Prior = "\033[5~"
+string Next = "\033[6~"
+string Macro = "\033[M"
+string Pause = "\033[P"
+compose '`' 'A' to 'À'
+compose '`' 'a' to 'à'
+compose '\'' 'A' to 'Á'
+compose '\'' 'a' to 'á'
+compose '^' 'A' to 'Â'
+compose '^' 'a' to 'â'
+compose '~' 'A' to 'Ã'
+compose '~' 'a' to 'ã'
+compose '"' 'A' to 'Ä'
+compose '"' 'a' to 'ä'
+compose 'O' 'A' to 'Å'
+compose 'o' 'a' to 'å'
+compose '0' 'A' to 'Å'
+compose '0' 'a' to 'å'
+compose 'A' 'A' to 'Å'
+compose 'a' 'a' to 'å'
+compose 'A' 'E' to 'Æ'
+compose 'a' 'e' to 'æ'
+compose ',' 'C' to 'Ç'
+compose ',' 'c' to 'ç'
+compose '`' 'E' to 'È'
+compose '`' 'e' to 'è'
+compose '\'' 'E' to 'É'
+compose '\'' 'e' to 'é'
+compose '^' 'E' to 'Ê'
+compose '^' 'e' to 'ê'
+compose '"' 'E' to 'Ë'
+compose '"' 'e' to 'ë'
+compose '`' 'I' to 'Ì'
+compose '`' 'i' to 'ì'
+compose '\'' 'I' to 'Í'
+compose '\'' 'i' to 'í'
+compose '^' 'I' to 'Î'
+compose '^' 'i' to 'î'
+compose '"' 'I' to 'Ï'
+compose '"' 'i' to 'ï'
+compose '-' 'D' to 'Ð'
+compose '-' 'd' to 'ð'
+compose '~' 'N' to 'Ñ'
+compose '~' 'n' to 'ñ'
+compose '`' 'O' to 'Ò'
+compose '`' 'o' to 'ò'
+compose '\'' 'O' to 'Ó'
+compose '\'' 'o' to 'ó'
+compose '^' 'O' to 'Ô'
+compose '^' 'o' to 'ô'
+compose '~' 'O' to 'Õ'
+compose '~' 'o' to 'õ'
+compose '"' 'O' to 'Ö'
+compose '"' 'o' to 'ö'
+compose '/' 'O' to 'Ø'
+compose '/' 'o' to 'ø'
+compose '`' 'U' to 'Ù'
+compose '`' 'u' to 'ù'
+compose '\'' 'U' to 'Ú'
+compose '\'' 'u' to 'ú'
+compose '^' 'U' to 'Û'
+compose '^' 'u' to 'û'
+compose '"' 'U' to 'Ü'
+compose '"' 'u' to 'ü'
+compose '\'' 'Y' to 'Ý'
+compose '\'' 'y' to 'ý'
+compose 'T' 'H' to 'Þ'
+compose 't' 'h' to 'þ'
+compose 's' 's' to 'ß'
+compose '"' 'y' to 'ÿ'
+compose 's' 'z' to 'ß'
+compose 'i' 'j' to 'ÿ'
diff -urN linux-2.4.29/drivers/char/ep93xx_scan_keyb.c linux-2.4.29-uc1/drivers/char/ep93xx_scan_keyb.c
--- linux-2.4.29/drivers/char/ep93xx_scan_keyb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/ep93xx_scan_keyb.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,392 @@
+/******************************************************************************
+ * 
+ *  File:	linux/drivers/char/ep93xx_scan_keyb.c
+ *
+ *  Purpose:	Support for Cirrus EP93xx architecture core keyboard scanner.
+ *
+ *  Build:	Define CONFIG_VT.
+ *		Do not define CONFIG_VT_CONSOLE yet.
+ *
+ *  History:	010406	Norman Farquhar at LynuxWorks
+ *
+ *		Initial version
+ *		- Will scan keyboard and feed keyboard.c, which translates
+ *		to input codes and puts them into tty console queue.
+ *		- Raw mode tbd
+ *		- keymaps other than default not supported
+ *		- does not support standby mode yet
+ *
+ *  Limitations:
+ *		1.  The EP93xx is limited to supporting small keyboards
+ *		and cannot handle full PC style keyboards and key usage:
+ *		a)  64 key limit: 8x8 key matrix
+ *		b)  limited to 2 keys down MAXIMUM,
+ *		which makes it impossible to support SHIFT+SHIFT+KEY
+ *		states like shift-control or control-alt keys.
+ *		2.  This means the default keyboard, 83key CherryG84-4001QAU/02,
+ *		will have some dead keys.  
+ *
+ *
+ * (c) Copyright 2001 LynuxWorks, Inc., San Jose, CA.  All rights reserved.
+ *   
+ *=============================================================================
+ *	Overview of EP93xx Scan Keyboard driver
+ *=============================================================================
+ *
+ *	The EP93xx scanned keyboard driver is a low-level hardware driver which
+ *	supports the core logic scanned keyboard controller block of the
+ *	EP93xx.  These machines are embedded systems and this keyboard driver 
+ *	can support small keyboards.
+ *
+ *	The keyboard driver does not have a normal device driver interface
+ *	and instead interfaces to the keyboard.c driver through function calls.
+ *	Note that not all interface function calls are implemented at this time.
+ *	(see /asm/arch/keyboard.h for function definitions):
+ *
+ *	ep93xx_scan_kbd_hw_init
+ *		initializes the scan keyboard hw.
+ *
+ *	handle_scancode
+ *		when scan controller generates interrupt, handler will
+ *		pass scan codes to queue in keyboard.c with this function call.
+ *	
+ *	ep93xx_scan_kbd_translate
+ *		called by keyboard.c to translate scan code stream to
+ *		key code stream.  The keycode stream is then interpreted
+ *		by keyboard.c according to current key shift state
+ *		into a code suitable for Linux. 
+ *
+ *	Note that key scan codes will be delivered by this driver on both
+ *	key down and key up events, using a coding similar to PC XT keyboard.
+ *
+ *	Note however that scan compatibility and key code compatibility
+ *	to PC standard are not required by Linux, and are not guaranteed.
+ *
+ ******************************************************************************/
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kbd_ll.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/keyboard.h>
+#include <asm/hardware.h>
+
+//#define DEBUG
+
+#define KEYREG_KEY1_MASK                        0x0000003F
+#define KEYREG_KEY1_SHIFT                       0
+#define KEYREG_KEY2_MASK                        0x00000Fc0
+#define KEYREG_KEY2_SHIFT                       6
+
+#define KEYREG_KEY1ROW_MASK                     0x00000007
+#define KEYREG_KEY1ROW_SHIFT                    0
+#define KEYREG_KEY1COL_MASK                     0x00000038
+#define KEYREG_KEY1COL_SHIFT                    3
+
+#define KEYREG_KEY2ROW_MASK                     0x000001c0
+#define KEYREG_KEY2ROW_SHIFT                    6
+#define KEYREG_KEY2COL_MASK                     0x00000E00
+#define KEYREG_KEY2COL_SHIFT                    9
+
+#define KEYREG_1KEY                             0x00001000
+#define KEYREG_2KEYS                            0x00002000
+#define KEYREG_INT                              0x00004000
+#define KEYREG_K                                0x00008000
+
+#define SCANINIT_DIS3KY                         0x00008000
+
+//
+//	Prototypes
+//
+int kmi_kbd_init(void)
+{
+    return(0);
+}
+void __init ep93xx_scan_kbd_hw_init( void);
+int ep93xx_scan_kbd_translate( unsigned char scancode, unsigned char *keycode, char rawmode);
+//
+//	Code
+//
+int ep93xx_scan_kbd_translate( unsigned char scancode, unsigned char *keycode, char rawmode)
+{
+	// Translate scan code stream to key code
+	// 
+	// Our scan coding is simple: each key up/down event generates
+	// a single scan code.
+	//
+	// TBD We translate scancode to keycode regardless of up/down status
+
+	*keycode = scancode & ~KBUP;	// Mask off KBUP flag
+	return 1;			// keycode is valid
+}
+
+void kbd_irq_handler( int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int		keystat, key1, key2;
+	static unsigned int	lastkeystat=0, lastkey1=0, lastkey2=0;
+
+	// Note: IRQ_KEY automatically disabled before entry,
+	// and reenabled after exit by Linux interrupt code.
+
+	// Reading status clears keyboard interrupt
+
+	keystat = inl(KEY_REG) &
+		  (KEYREG_KEY1COL_MASK|KEYREG_KEY1ROW_MASK|
+		   KEYREG_KEY2COL_MASK|KEYREG_KEY2ROW_MASK|
+		   KEYREG_1KEY|KEYREG_2KEYS);
+
+#ifdef DEBUG	// DEBUGGING	
+	if (keystat == lastkeystat)
+		printk( "ep93xx_scan_keyb:  spurious interrupt, stat %x\n",
+			 keystat);
+	else
+		printk( "ep93xx_scan_keyb:  interrupt, stat %x\n", keystat);
+#endif
+	if (keystat & KEYREG_1KEY)
+			key1 = KEYCODE( (keystat&KEYREG_KEY1ROW_MASK)>>KEYREG_KEY1ROW_SHIFT,
+				(keystat&KEYREG_KEY1COL_MASK)>>KEYREG_KEY1COL_SHIFT);
+	else
+		key1 = 0;	// invalid
+
+	if (keystat & KEYREG_2KEYS)
+			key2 = KEYCODE( (keystat&KEYREG_KEY2ROW_MASK)>>KEYREG_KEY2ROW_SHIFT,
+				(keystat&KEYREG_KEY2COL_MASK)>>KEYREG_KEY2COL_SHIFT);
+	else
+		key2 = 0;	// invalid
+
+	//
+	// This 'monster' decision tree is used to decide what to report
+	// when last key state has changed to current key state.
+	// This may involve up to 4 keys changing state simultaneously:
+	// lastkey1, lastkey2 going up and key1, key2 going down.
+	//
+	// We use keyboard scanner hardware guarantees to simplify the logic:
+	//	key1 < key2	if both are valid
+	//	key1 is valid 	if key2 is valid
+	//
+	//	handle_scancode called with down and up scancodes
+	//		scancode = keycode when down
+	//		scancode = keycode|KBUP when up
+	//
+	// Note that if more than one keys change state in the same scan period,
+	// then we really do NOT know the order in which the key events occurred.
+	// Our default behavior is to always report key up events before key down
+	// events.  However, multiple key up events or multiple key down events
+	// will be reported in no special order. 
+	//
+	if (!(lastkeystat & (KEYREG_1KEY|KEYREG_2KEYS)))  // No keys down lasttime
+	{
+		if (key1)
+			handle_scancode( key1, 1);
+		if (key2)
+			handle_scancode( key2, 1);
+	}
+	else if (lastkey1 == key1)	   // means key still down
+	{
+		// no change for key1 or lastkey1, both valid
+		if (lastkey2 != key2)
+		{
+			// lastkey2 went up if valid, key2 went down if valid
+			if (lastkey2)
+				handle_scancode( lastkey2|KBUP, 0);
+			if (key2)
+				handle_scancode( key2, 1);
+		}
+		//else no change for all keys
+	}
+	else if	(key1)		// key1 valid and
+				// lastkey1 valid (because NOT no keys lasttime)
+	{
+		if (lastkey1 == key2)
+		{
+			// no change for lastkey1 or key2
+			// lastkey2 went up if valid, key1 went down
+			if (lastkey2)
+				handle_scancode( lastkey2|KBUP, 0);
+			handle_scancode( key1, 1);
+
+		}
+		else
+		{
+			// we know: lastkey1 valid and went up, key1 valid
+			handle_scancode( lastkey1|KBUP, 0);
+			
+			if (lastkey2 == key1)
+			{
+				// no change for lastkey2 or key1
+				// key2 went down if valid
+				if (key2)
+					handle_scancode( key2, 1);
+
+			}
+			else
+			{
+				if (lastkey2 != key2)
+				{
+					// lastkey2 went up if valid
+					// key2 went down if valid
+					if (lastkey2)
+					    	handle_scancode( lastkey2|KBUP, 0);
+					if (key2)
+					    	handle_scancode( key2, 1);
+				}
+				//else no change for lastkey2 or key2
+				
+				// key1 valid and went down
+				handle_scancode( key1, 1);
+			}
+	    	}
+	}
+	else		// key1 not valid and
+			// lastkey1 valid (because NOT no keys lasttime)
+	{
+		// key1 not valid means both key1, key2 not valid
+		// so lastkey1 went up and lastkey2 went up if valid
+		handle_scancode( lastkey1|KBUP, 0);
+		if (lastkey2)
+			handle_scancode( lastkey2|KBUP, 0);
+	}
+	
+	lastkeystat = keystat;
+	lastkey1 = key1;
+	lastkey2 = key2;
+}
+
+
+char 
+ep93xx_unexpected_up(unsigned char xx)
+{
+    return 0x80;
+}
+
+static int
+ep93xx_setkeycode(unsigned int xx, unsigned int yy)
+{
+    return -EINVAL;
+}
+
+static int
+ep93xx_getkeycode(unsigned int xx)
+{
+    return -EINVAL;
+}
+
+static void
+ep93xx_leds(unsigned char xx)
+{
+}
+
+void __init ep93xx_scan_kbd_hw_init( void)
+{
+	int	i=3;
+	unsigned int uiTemp;
+
+	printk( "Entering ep93xx_scan_kbd_hw_init()\n");
+
+	// TBD we initialize the key scanner to start running
+	// TBD instead of putting it into standby and waiting
+	// TBD for any key down interrupt
+
+	cli();		// Atomic access needed
+
+	// Warning: hardware default has already started scanner!
+
+	// Make sure scanner enabled, active and that
+	// Keyboard ROW/COL interface enabled.
+
+	uiTemp = inl(SYSCON_DEVCFG);
+	
+	uiTemp &= ~(SYSCON_DEVCFG_KEYS | SYSCON_DEVCFG_GONK);
+		
+	SysconSetLocked(SYSCON_DEVCFG, uiTemp);
+
+
+	// SYSCON locked automatically now after RSTCR written
+
+	// Enable Keyboard Clock and select clock rate
+	//
+	//	TBD Boot ROM has already inited KTDIV = 0x20018004
+	// 	TBD Measured default 64usec scan period with scope.
+
+	// Assume that GPIO registers do not impact row,col pins since
+	// they are assigned to keyboard scanner.
+	
+	// Setup Keyboard Scanner
+	//
+	// Note that we change the scanner parameters on the fly
+	// while it is running, which is okay.  No need to disable
+	// scanner while tweaking these.
+	// 
+	// TBD Keyboard scan rate will change as master clocks/dividers change
+	//
+	// For now, this gives us measured rate of about 480Hz row scan rate,
+	// which implies 60Hz full kbd scan rate.  Together with debounce
+	// count of 3, means debounce period = 3/60Hz = 50ms>30ms recommended,
+	// so okay.
+	//
+	outl( (0x00FC00FA | SCANINIT_DIS3KY), SCANINIT );
+
+	//TBD If too much capacitance on keyboard
+	//outl( (0x00FC0020 | SCBACK | SCDIS3KEY), SCANINIT );
+
+	uiTemp = inl(SYSCON_KTDIV) | SYSCON_KTDIV_KEN;
+		
+	SysconSetLocked(SYSCON_KTDIV, uiTemp);
+
+
+	if (request_irq( IRQ_KEY, kbd_irq_handler, SA_INTERRUPT,
+			 "ep93xx_scan_keyb", 0))
+	{
+		printk( KERN_ERR "EP93xx scan keyboard driver aborting"
+				 " due to IRQ_KEY unavailable.\n");
+		sti();
+		//return -EBUSY;
+	} 
+	// Note: request_irq has just enabled IRQ_KEY for us.
+
+	// Warning: We have initialized last key status to indicate
+	// all keys up which may not be the current hardware state.
+	//
+	//	TBD If this is important to detect, to alert user
+	//	TBD to a possibly faulty keyboard, then we could
+	//	TBD manually scan the keyboard to verify all keys up.
+	//
+	
+	// Three common cases here:
+	//	1.  All keys up.  This is normal, expected status of keyboard.
+	//	2.  All keys up, although at some time ago during initialization
+	//	a key was momentarily pressed, causing the hardware to latch it.
+	//	3.  Some key is being held down now.
+	//
+	// Reading status clears any pending keyboard interrupt.
+	i = inl(KEY_REG);
+	//
+	// We believe this will have the following impact on common cases:
+	//
+	//	1.  No impact.
+	//	2.  Momentary presses will be cleared out so they do not
+	//	bother us.  Although we get a spurious key up immediately because
+	//	the keyboard hardware will see change from last
+	//	latched status and current status, higher level keyboard driver
+	//	should ignore.
+	//	3.  Key being held will generate a new pending key down
+	//	event which is acceptable.
+
+	sti();
+
+	// Now keyboard is active and will generate interrupts
+	// on key presses.  Driver only needs to handle interrupts.
+	// There are NO driver ioctl or deinit functions in lowlevel.
+	k_unexpected_up = ep93xx_unexpected_up;
+	k_setkeycode    = ep93xx_setkeycode;
+	k_getkeycode    = ep93xx_getkeycode;
+	
+	k_translate     = ep93xx_scan_kbd_translate;
+	k_leds          = ep93xx_leds;
+
+	printk( "Leaving ep93xx_scan_kbd_hw_init()\n");
+}
+
+
+
diff -urN linux-2.4.29/drivers/char/ep93xx_spi_kbd.c linux-2.4.29-uc1/drivers/char/ep93xx_spi_kbd.c
--- linux-2.4.29/drivers/char/ep93xx_spi_kbd.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/ep93xx_spi_kbd.c	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,869 @@
+/******************************************************************************
+ * 
+ *  File:	linux/drivers/char/ep93xx_spi_kbd.c
+ *
+ *  Purpose:	Support for SPI Keyboard for a Cirrus Logic EP93xx
+ *
+ *  History:	
+ *
+ *  Limitations:
+ *  Break and Print Screen keys not handled yet!
+ *
+ *
+ *  Copyright 2003 Cirrus Logic Inc.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/config.h>
+#include <linux/init.h>
+#include <linux/kbd_ll.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/keyboard.h>
+#include <asm/hardware.h>
+#include <asm/arch/ssp.h>
+
+#define EP93XX_MAX_KEY_DOWN_COUNT 6
+
+
+void DataCallback(unsigned int Data);
+static int g_SSP_Handle;
+
+//-----------------------------------------------------------------------------
+//  Debug stuff...
+// For debugging, let's spew messages out serial port 1 or 3 at 57,600 baud.
+//-----------------------------------------------------------------------------
+
+#undef UART_HACK_DEBUG
+// #define UART_HACK_DEBUG 1
+
+#ifdef UART_HACK_DEBUG
+static char szBuf[256];
+void UARTWriteString(char * msg);
+
+#define DPRINTK( x... )   \
+    sprintf( szBuf, ##x ); \
+    UARTWriteString( szBuf );
+#else
+#define DPRINTK( x... )
+#endif
+
+
+#ifdef UART_HACK_DEBUG
+
+// This "array" is a cheap-n-easy way of getting access to the UART registers.
+static unsigned int * const pDebugUART=(unsigned int *)IO_ADDRESS(UART1_BASE);
+//static unsigned int * const pDebugUART=(unsigned int *)IO_ADDRESS(UART3_BASE);
+static int bUartInitialized = 0; 
+
+void SendChar(char value)
+{
+    // wait for Tx fifo full flag to clear.
+    while (pDebugUART[0x18>>2] & 0x20);
+
+    // send a char to the uart               
+    pDebugUART[0] = value;
+}
+
+void UARTWriteString(char * msg) 
+{
+    int index = 0;
+
+    //if((pDebugUART[0x14>>2] & 0x1) == 0)
+    if( bUartInitialized == 0 )
+    {
+        uiTemp = inl(SYSCON_DEVCFG);
+		uiTemp |= SYSCON_DEVCFG_U1EN;
+		//uiTemp |= SYSCON_DEVCFG_U3EN;
+        SysconSetLocked(SYSCON_DEVCFG, uiTemp);  
+        pDebugUART[0x10>>2] = 0xf;
+        pDebugUART[0xc>>2] = 0;
+        pDebugUART[0x8>>2] = 0x70;
+        pDebugUART[0x14>>2] = 0x1;
+        bUartInitialized = 1;
+    }
+    while (msg[index] != 0)
+    {
+        if (msg[index] == '\n')
+        {
+            SendChar('\r');
+            SendChar('\n');
+        }
+        else 
+        {
+            SendChar(msg[index]);
+        }
+        index++;
+    }
+}
+#endif // UART_HACK_DEBUG
+
+
+static unsigned int ExtendedKscanVirtualKey(unsigned char ucExtendedKey);
+static unsigned char SPI2KScan(unsigned int uiSPIValue, int * pValid);
+static void InitSniffer(void);
+static void KeySniffer(unsigned char scancode, int down);
+static void Check4StuckKeys(void);
+
+#define KSCAN_TABLE_SIZE    0x88
+#define KeyStateDownFlag        1
+
+#define KC_NONE         0
+#define KC_ESC          1   // Escape
+#define KC_ONE          2   // 1 !          
+#define KC_TWO          3   // 2 @
+#define KC_THREE        4   // 3 #      
+#define KC_FOUR         5   // 4 $          
+#define KC_FIVE         6   // 5 %         
+#define KC_SIX          7   // 6 ^     
+#define KC_SEVEN        8   // 7 &
+#define KC_EIGHT        9   // 8 *
+#define KC_NINE         10  // 9 (
+#define KC_ZERO         11  // 0 )
+#define KC_MINUS        12  // - _
+#define KC_EQUAL        13  // = +
+#define KC_BACKSPACE    14  // Delete
+#define KC_TAB          15  // Tab
+#define KC_Q            16  // q               
+#define KC_W            17  // w               
+#define KC_E            18  // e
+#define KC_R            19  // r               
+#define KC_T            20 	// t               
+#define KC_Y            21 	// y               
+#define KC_U            22 	// u               
+#define KC_I            23 	// i               
+#define KC_O            24 	// o               
+#define KC_P            25 	// p               
+#define KC_BRACKETLEFT  26  // [ {
+#define KC_BRAKCETRIGHT 27  // ] }
+#define KC_RETURN       28  // Return          
+#define KC_LCONTROL     29  // Control         
+#define KC_A            30  // a
+#define KC_S            31 	// s               
+#define KC_D            32 	// d
+#define KC_F            33 	// f
+#define KC_G            34 	// g               
+#define KC_H            35 	// h               
+#define KC_J            36 	// j               
+#define KC_K            37 	// k               
+#define KC_L            38 	// l               
+#define KC_SEMICOLON    39  // ; :
+#define KC_APOSTROPHE   40  // ' "
+#define KC_GRAVE        41  // ` ~
+#define KC_LEFTSHIFT    42  // Left Shift           
+#define KC_BACKSLASH    43  // \ |
+#define KC_Z            44 	// z               
+#define KC_X            45 	// x               
+#define KC_C            46 	// c
+#define KC_V            47 	// v               
+#define KC_B            48 	// b
+#define KC_N            49  // n               
+#define KC_M            50  // m               
+#define KC_COMMA        51  // , <
+#define KC_PERIOD       52  // . >
+#define KC_SLASH        53  // / ?
+#define KC_RIGHTSHIFT   54  // Right Shift           
+#define KC_KP_MULTIPLY  55  // KP_*
+#define KC_ALT          56  // Alt  
+#define KC_SPACE        57  // Space
+#define KC_CAPSLOCK     58  // CapsLock       
+#define KC_F1           59  // F1
+#define KC_F2           60 	// F12
+#define KC_F3           61 	// F13
+#define KC_F4           62 	// F14
+#define KC_F5           63 	// F15
+#define KC_F6           64 	// F16
+#define KC_F7           65 	// F17
+#define KC_F8           66 	// F18
+#define KC_F9           67 	// F19
+#define KC_F10          68 	// F20
+#define KC_NUMLOCK      69  // NumLock
+#define KC_SCROLLLOCK   70  // Scroll Lock
+#define KC_KP_7         71  // KP 7            
+#define KC_KP_8         72  // KP_8            
+#define KC_KP_9         73  // KP_9            
+#define KC_KP_MINUS     74  // KP_-     
+#define KC_KP_4         75  // KP_4            
+#define KC_KP_5         76 	// KP_5            
+#define KC_KP_6         77 	// KP_6            
+#define KC_KP_ADD       78 	// KP_+
+#define KC_KP_1         79 	// KP_1            
+#define KC_KP_2         80 	// KP_2            
+#define KC_KP_3         81 	// KP_3            
+#define KC_KP_0         82 	// KP_0            
+#define KC_KP_PERIOD    83  // KP_.
+#define KC_LAST_CONSOLE 84  // Last_Console    
+#define KC_F11          87  // F11
+#define KC_F12          88  // F12
+#define KC_KP_ENTER     96  // KP_Enter        
+#define KC_RCONTROL     97  // Control         
+#define KC_KP_DIVIDE    98  // KP_/       
+#define KC_RALT         100 // Right Alt
+#define KC_BREAK        101 // Break           
+#define KC_HOME         102 // Home
+#define KC_UP           103 // Up              
+#define KC_PGUP         104 // Page Up
+#define KC_LEFT         105 // Left            
+#define KC_RIGHT        106 // Right           
+#define KC_END          107 // End
+#define KC_DOWN         108 // Down            
+#define KC_PGDOWN       109 // Page Down            
+#define KC_INSERT       110 // Insert          
+#define KC_DELETE       111 // Delete
+#define KC_13           113 // F13             
+#define KC_14           114 // F14             
+#define KC_PAUSE        119 // Pause
+
+#define EXTENDED_KEY     0x80
+
+//
+// This table is used to map the scan code to the Linux default keymap.
+//
+static unsigned int const KScanCodeToVKeyTable[KSCAN_TABLE_SIZE] =
+{
+    KC_NONE,            // Scan Code 0x0
+    KC_F9,              // Scan Code 0x1
+    KC_NONE,            // Scan Code 0x2
+    KC_F5,              // Scan Code 0x3
+    KC_F3,              // Scan Code 0x4
+    KC_F1,              // Scan Code 0x5
+    KC_F2,              // Scan Code 0x6
+    KC_F12,             // Scan Code 0x7
+    KC_NONE,            // Scan Code 0x8
+    KC_F10,             // Scan Code 0x9
+    KC_F8,              // Scan Code 0xA
+    KC_F6,              // Scan Code 0xB
+    KC_F4,              // Scan Code 0xC
+    KC_TAB,             // Scan Code 0xD Tab
+    KC_GRAVE,           // Scan Code 0xE '
+    KC_NONE,            // Scan Code 0xF
+    KC_NONE,            // Scan Code 0x10
+    KC_ALT,             // Scan Code 0x11 Left Menu
+    KC_LEFTSHIFT,       // Scan Code 0x12 Left Shift
+    KC_NONE,            // Scan Code 0x13
+    KC_LCONTROL,        // Scan Code 0x14
+    KC_Q,               // Scan Code 0x15
+    KC_ONE,             // Scan Code 0x16
+    KC_NONE,            // Scan Code 0x17
+    KC_NONE,            // Scan Code 0x18
+    KC_NONE,            // Scan Code 0x19
+    KC_Z,               // Scan Code 0x1A
+    KC_S,               // Scan Code 0x1B
+    KC_A,               // Scan Code 0x1C
+    KC_W,               // Scan Code 0x1D
+    KC_TWO,             // Scan Code 0x1E
+    KC_NONE,            // Scan Code 0x1F
+    KC_NONE,            // Scan Code 0x20
+    KC_C,               // Scan Code 0x21
+    KC_X,               // Scan Code 0x22
+    KC_D,               // Scan Code 0x23
+    KC_E,               // Scan Code 0x24
+    KC_FOUR,            // Scan Code 0x25
+    KC_THREE,           // Scan Code 0x26
+    KC_NONE,            // Scan Code 0x27
+    KC_NONE,            // Scan Code 0x28
+    KC_SPACE,           // Scan Code 0x29  Space
+    KC_V,               // Scan Code 0x2A
+    KC_F,               // Scan Code 0x2B
+    KC_T,               // Scan Code 0x2C
+    KC_R,               // Scan Code 0x2D
+    KC_FIVE,            // Scan Code 0x2E
+    KC_NONE,            // Scan Code 0x2F
+    KC_NONE,            // Scan Code 0x30
+    KC_N,               // Scan Code 0x31
+    KC_B,               // Scan Code 0x32 B
+    KC_H,               // Scan Code 0x33
+    KC_G,               // Scan Code 0x34
+    KC_Y,               // Scan Code 0x35
+    KC_SIX,             // Scan Code 0x36
+    KC_NONE,            // Scan Code 0x37
+    KC_NONE,            // Scan Code 0x38
+    KC_NONE,            // Scan Code 0x39
+    KC_M,               // Scan Code 0x3A
+    KC_J,               // Scan Code 0x3B
+    KC_U,               // Scan Code 0x3C
+    KC_SEVEN,           // Scan Code 0x3D
+    KC_EIGHT,           // Scan Code 0x3E
+    KC_NONE,            // Scan Code 0x3F
+    KC_NONE,            // Scan Code 0x40
+    KC_COMMA,           // Scan Code 0x41
+    KC_K,               // Scan Code 0x42
+    KC_I,               // Scan Code 0x43	
+    KC_O,               // Scan Code 0x44
+    KC_ZERO,            // Scan Code 0x45
+    KC_NINE,            // Scan Code 0x46
+    KC_NONE,            // Scan Code 0x47
+    KC_NONE,            // Scan Code 0x48
+    KC_PERIOD,          // Scan Code 0x49
+    KC_SLASH,           // Scan Code 0x4A
+    KC_L,               // Scan Code 0x4B
+    KC_SEMICOLON,       // Scan Code 0x4C
+    KC_P,               // Scan Code 0x4D
+    KC_MINUS,           // Scan Code 0x4E
+    KC_NONE,            // Scan Code 0x4F
+    KC_NONE,            // Scan Code 0x50
+    KC_NONE,            // Scan Code 0x51
+    KC_APOSTROPHE,      // Scan Code 0x52
+    KC_NONE,            // Scan Code 0x53
+    KC_BRACKETLEFT,     // Scan Code 0x54
+    KC_EQUAL,           // Scan Code 0x55
+    KC_BACKSPACE,       // Scan Code 0x56
+    KC_NONE,            // Scan Code 0x57
+    KC_CAPSLOCK,        // Scan Code 0x58 Caps Lock
+    KC_RIGHTSHIFT,      // Scan Code 0x59 Right Shift
+    KC_RETURN,          // Scan Code 0x5A
+    KC_BRAKCETRIGHT,    // Scan Code 0x5B
+    KC_NONE,            // Scan Code 0x5C
+    KC_BACKSLASH,       // Scan Code 0x5D
+    KC_NONE,            // Scan Code 0x5E
+    KC_NONE,            // Scan Code 0x5F
+    KC_NONE,            // Scan Code 0x60
+    KC_BACKSLASH,       // Scan Code 0x61 ?? //VK_BSLH,            
+    KC_NONE,            // Scan Code 0x62
+    KC_NONE,            // Scan Code 0x63
+    KC_NONE,            // Scan Code 0x64
+    KC_NONE,            // Scan Code 0x65
+    KC_BACKSPACE,       // Scan Code 0x66 ?? //VK_BKSP,            
+    KC_NONE,            // Scan Code 0x67
+    KC_NONE,            // Scan Code 0x68
+    KC_KP_1,            // Scan Code 0x69
+    KC_NONE,            // Scan Code 0x6A
+    KC_KP_4,            // Scan Code 0x6B
+    KC_KP_7,            // Scan Code 0x6C
+    KC_NONE,            // Scan Code 0x6D
+    KC_NONE,            // Scan Code 0x6E
+    KC_NONE,            // Scan Code 0x6F
+    KC_KP_0,            // Scan Code 0x70
+    KC_KP_PERIOD,       // Scan Code 0x71 DECIMAL??
+    KC_KP_2,            // Scan Code 0x72
+    KC_KP_5,            // Scan Code 0x73
+    KC_KP_6,            // Scan Code 0x74
+    KC_KP_8,            // Scan Code 0x75
+    KC_ESC,             // Scan Code 0x76
+    KC_NUMLOCK,         // Scan Code 0x77
+    KC_F11 ,            // Scan Code 0x78
+    KC_KP_ADD,          // Scan Code 0x79
+    KC_KP_3,            // Scan Code 0x7A
+    KC_KP_MINUS,        // Scan Code 0x7B
+    KC_KP_MULTIPLY,     // Scan Code 0x7C
+    KC_KP_9,            // Scan Code 0x7D
+    KC_SCROLLLOCK,      // Scan Code 0x7E
+    KC_NONE,            // Scan Code 0x7F
+    KC_NONE,            // Scan Code 0x80      
+    KC_NONE,            // Scan Code 0x81
+    KC_NONE,            // Scan Code 0x82
+    KC_F7,              // Scan Code 0x83
+    KC_NONE,            // Scan Code 0x84
+    KC_NONE,            // Scan Code 0x85
+    KC_NONE,            // Scan Code 0x86
+    KC_NONE             // Scan Code 0x87
+};
+
+//=============================================================================
+// KeyboardTranslate
+//=============================================================================
+// Translate the raw scan code to the default keymap for linux keyboards.
+//=============================================================================
+int KeyboardTranslate(unsigned char scancode, unsigned char * keycode, 
+    char rawmode)
+{
+    //
+    // Was this an extended key?
+    //
+    if(scancode & EXTENDED_KEY)
+    {
+        *keycode = ExtendedKscanVirtualKey(scancode & (~EXTENDED_KEY));
+    }
+    else
+    {
+	    *keycode = KScanCodeToVKeyTable[scancode];
+    }
+
+    //
+    // Indicate that this is a valid keycode.
+    //
+	return 1;
+}
+
+typedef struct{
+	unsigned char scancode;
+	unsigned char count;
+} key_down_tracker_t;
+
+//
+// In the interest of efficiency, let's only allow 5 keys to be down
+// at a time, maximum.  So if anybody is having a temper tantrum on
+// their keyboard, they may get stuck keys, but that's to be expected.
+//
+#define MAX_KEYS_DOWN 8
+static key_down_tracker_t KeyTracker[MAX_KEYS_DOWN];
+
+//=============================================================================
+// InitSniffer
+//=============================================================================
+static void InitSniffer(void)
+{
+	int i;
+	
+	//
+	// Clear our struct to indicate that no keys are down now.
+	// If somebody boots this thing while holding down keys, then they'll
+	// get what they deserve.
+	//
+	for( i=0 ; i < MAX_KEYS_DOWN ; i++ )
+	{
+		KeyTracker[i].count = 0;
+		KeyTracker[i].scancode = 0;
+	}
+}
+
+//=============================================================================
+// KeySniffer
+//=============================================================================
+// To prevent stuck keys, keep track of what keys are down.  This information
+// is used by Check4StuckKeys().
+//=============================================================================
+static void KeySniffer(unsigned char scancode, int down)
+{
+	int i;
+
+	//
+	// There are certain keys that will definately get held down
+	// and we can't interfere with that.
+	//
+	switch( scancode )
+	{
+		case 0x12: /* left  shift */
+		case 0x59: /* right shift */
+		case 0x14: /* left  ctrl  */
+		case 0x94: /* right ctrl  */
+		case 0x11: /* left  alt   */
+		case 0x91: /* right alt   */
+		case 0x58: /* caps lock   */
+		case 0x77: /* Num lock    */
+			handle_scancode( scancode, down );
+			return;
+	
+		default:
+			break;
+	}
+
+    //printk("Sniff - %02x, %d\n", scancode, down );
+
+	//
+	// Go thru our array, looking for the key.  If it already
+	// is recorded, update its count.
+	// Also look for empty cells in the array in case we
+	// need one.
+	//
+	for( i=0 ; i < MAX_KEYS_DOWN ; i++ )
+	{
+		//
+		// If this is a key up in our list then we are done.
+		//
+		if (down == 0)
+		{
+			if (KeyTracker[i].scancode == scancode)
+			{
+				KeyTracker[i].count = 0;
+				KeyTracker[i].scancode = 0;
+				handle_scancode( scancode, down );
+				break;
+			}
+		}
+		//
+		// Hey here's an unused cell.  Save its index.
+		//
+		else if(KeyTracker[i].count == 0)
+		{
+			KeyTracker[i].scancode = scancode;
+			KeyTracker[i].count = 1;
+			handle_scancode( scancode, down );
+			break;
+		}
+	}
+}
+
+//=============================================================================
+// Check4StuckKeys
+//=============================================================================
+// When a key is held down longer than 1/2 sec, it start repeating
+// 10 times a second.  What we do is watch how long each key is
+// held down.  If longer than X where X is less than 1/2 second
+// then we assume it is stuck and issue the key up.  If we were
+// wrong and the key really is being held down, no problem because
+// the keyboard is about to start sending it to us repeatedly
+// anyway.
+//=============================================================================
+static void Check4StuckKeys(void)
+{
+	int i;
+
+	for( i=0 ; i < MAX_KEYS_DOWN ; i++ )
+	{
+		if( KeyTracker[i].count )
+		{
+			KeyTracker[i].count++;
+			if( KeyTracker[i].count >= EP93XX_MAX_KEY_DOWN_COUNT )
+			{
+				handle_scancode( KeyTracker[i].scancode, 0 );
+				KeyTracker[i].count = 0;
+				KeyTracker[i].scancode = 0;
+			}
+		}
+	}
+}
+
+//=============================================================================
+// HandleKeyPress
+//=============================================================================
+// Checks if there are any keys in the FIFO and processes them if there are.
+//=============================================================================
+void HandleKeyPress(unsigned int Data)
+{
+    static unsigned char ucKScan[4] = {0,0,0,0};
+    static unsigned int ulNum = 0;
+	int bParityValid;
+	
+	//
+    // No keys to decode, but the timer went off and is calling us
+    // to check for stuck keys.
+    //
+    if (Data == -1)
+	{
+		Check4StuckKeys();
+		return;
+	}
+	
+    //
+    // Read in the value from the SPI controller.
+    //
+    ucKScan[ulNum++] = SPI2KScan( Data, &bParityValid );
+
+	//
+	// Bad parity?	We should read the rest of the fifo and
+	// throw it away, because it will all be bad.  Then the
+	// SSP will be reset when we close the SSP driver and 
+	// all will be good again.
+	//
+	if(!bParityValid)
+	{
+		ulNum = 0;
+	}
+
+    //
+    // If we have one character in the array, do the following.
+    //
+    if(ulNum == 1)
+    {
+        //
+        // If it is a simple key without the extended scan code perform 
+        // following.
+        //
+        if(ucKScan[0] < KSCAN_TABLE_SIZE)
+        {
+            DPRINTK("1:Dn %02x\n", ucKScan[0]);
+            KeySniffer(ucKScan[0], 1);
+            ulNum  = 0;
+        }            
+
+		//
+		// I don't know what type of character this is so erase the 
+		// keys stored in the buffer and continue.
+		//
+		else if((ucKScan[0] !=0xF0) && (ucKScan[0] !=0xE0))
+		{
+           	DPRINTK("1:oops - %02x\n",	ucKScan[0] );
+            ulNum = 0;
+        }
+    }
+	else if(ulNum == 2)
+	{
+		//
+		// 0xF0 means that a key has been released.
+		//
+		if(ucKScan[0] == 0xF0)
+		{
+			//
+			// If it is a simple key without the extended scan code 
+			// perform the following.
+			//
+			if(ucKScan[1] < KSCAN_TABLE_SIZE)
+			{
+				DPRINTK("2:Up %02x %02x\n", ucKScan[0], ucKScan[1]);
+				KeySniffer(ucKScan[1], 0);
+				ulNum = 0;
+			}            
+			//
+			// If it a extended kscan continue to get the next byte.
+			//
+			else if(ucKScan[1] !=0xE0)
+			{
+				DPRINTK("2:oops - %02x %02x\n",	ucKScan[0], ucKScan[1]);
+				ulNum = 0;
+			}
+		}                                    
+		//
+		// Find out what extended code it is.
+		//
+		else if(ucKScan[0] == 0xE0 && ucKScan[1] != 0xF0)
+		{
+			DPRINTK("2:Dn %02x %02x\n", ucKScan[0], ucKScan[1]);
+			KeySniffer(EXTENDED_KEY | ucKScan[1], 1);
+			ulNum = 0;
+		}
+	}
+	//
+	// This means that an extended code key has been released.
+	//
+	else if (ulNum == 3)
+	{
+		//
+		// 0xF0 means that a key has been released.
+		//
+		if(ucKScan[0] == 0xE0 && ucKScan[1] == 0xF0)
+		{
+			DPRINTK("3:Up %02x %02x %02x", 
+				ucKScan[0], ucKScan[1], ucKScan[2] );
+			KeySniffer(EXTENDED_KEY | ucKScan[2], 0);
+		}
+		else
+		{
+			DPRINTK("3:oops - %02x %02x %02x\n",
+					ucKScan[0], ucKScan[1], ucKScan[2]);
+		}
+		ulNum = 0;
+	}
+}
+
+//=============================================================================
+//=============================================================================
+char UnexpectedUp(unsigned char xx)
+{
+	//printk("UnexpectedUp - %02x\n",xx);
+    return 200;
+}
+
+//=============================================================================
+//=============================================================================
+static int SetKeycode(unsigned int xx, unsigned int yy)
+{
+    return -EINVAL;
+}
+
+//=============================================================================
+//=============================================================================
+static int GetKeycode(unsigned int xx)
+{
+    return -EINVAL;
+}
+
+//=============================================================================
+//=============================================================================
+static void SetLEDs(unsigned char xx)
+{
+}
+
+//=============================================================================
+// ExtendedVirtualKey
+//=============================================================================
+// Converts an extended key to its virtual key code.
+// 
+//=============================================================================
+static unsigned int ExtendedKscanVirtualKey(unsigned char ucExtendedKey)
+{
+    unsigned int uiVKey = 0;
+    switch(ucExtendedKey)
+    {
+        case 0x03: // This is really 0x83
+        {
+            uiVKey = KC_F7;
+            break;
+        }
+        case 0x11:
+        {
+            uiVKey = KC_RALT;
+            break;
+        }
+        case 0x14:
+        {
+            uiVKey = KC_RCONTROL;
+            break;
+        }
+        case 0x4a:
+        {
+            uiVKey = KC_KP_DIVIDE;
+            break;
+        }
+        case 0x5a:  
+        {
+            uiVKey = KC_RETURN;
+            break;
+        }
+        case 0x69:
+        {
+            uiVKey = KC_END;
+            break;
+        }
+        case 0x6b:  
+        {
+            uiVKey = KC_LEFT;
+            break;
+        }
+        case 0x6c:  
+        {
+            uiVKey = KC_HOME;
+            break;
+        }
+        case 0x70:
+        {
+            uiVKey = KC_INSERT;
+            break;
+        }
+        case 0x71:  
+        {
+            uiVKey = KC_DELETE;
+            break;
+        }
+        case 0x72:
+        {
+            uiVKey = KC_DOWN;
+            break;
+        }
+        case 0x74:
+        {
+            uiVKey = KC_RIGHT;
+            break;
+        }
+        case 0x75:
+        {
+            uiVKey = KC_UP;
+            break;
+        }
+        case 0x7a:
+        {
+            uiVKey = KC_PGDOWN;
+            break;
+        }
+        case 0x7d:
+        {
+            uiVKey = KC_PGUP;
+            break;
+        }
+        default:
+        {
+            DPRINTK("Unknown Extended Key - XX\n");
+            uiVKey = 0;
+            break;
+        }
+    }
+    return (uiVKey);
+}
+
+//=============================================================================
+// SPI2KScan
+//=============================================================================
+// Get a character from the spi port if it is available.
+// 
+// Below is a picture of the spi signal from the PS2. 
+//
+//CK HHllllHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHllll
+//DA HHHllllll000000111111222222333333444444555555666666777777ppppppssssssLLLLHHH
+//        ^                                                                ^
+//    start bit                                                   important bit
+// 
+//where:  l = 8042 driving the line 
+//        L = KEYBOARD driving the line
+//        1..7 data
+//         = Parity 8042 driving
+//        s = stop   8042 driving
+//         = PARITY KEYBOARD driving the line
+//        S = STOP   KEYBOARD driving the line
+//
+//  In our design the value comes high bit first and is inverted.  So we must
+//  convert it to low byte first and then inverted it back.
+//
+//=============================================================================
+static unsigned char SPI2KScan(unsigned int uiSPIValue, int * pValid)
+{
+    unsigned char ucKScan = 0;
+    unsigned int uiParity = 0;
+    unsigned int uiCount = 0;
+
+    
+    for( uiCount = 1 ; uiCount < 10 ; uiCount++ )
+    {
+        uiParity += (uiSPIValue >> uiCount) & 0x1;
+    }
+    
+
+    if( !(uiParity & 0x1)  && (uiSPIValue & 0x401) == 0x400 )
+    {
+        *pValid = 1;
+    
+	    //
+	    // Invert the pattern.
+	    //
+	    uiSPIValue = ~uiSPIValue;
+	    
+	    //
+	    // Read in the value from the motorola spi file
+	    //
+	    ucKScan =  (unsigned char)((uiSPIValue & 0x004)<< 5);
+	    ucKScan |= (unsigned char)((uiSPIValue & 0x008)<< 3);
+	    ucKScan |= (unsigned char)((uiSPIValue & 0x010)<< 1);
+	    ucKScan |= (unsigned char)((uiSPIValue & 0x020)>> 1);
+	    ucKScan |= (unsigned char)((uiSPIValue & 0x040)>> 3);
+	    ucKScan |= (unsigned char)((uiSPIValue & 0x080)>> 5);
+	    ucKScan |= (unsigned char)((uiSPIValue & 0x100)>> 7);
+	    ucKScan |= (unsigned char)((uiSPIValue & 0x200)>> 9);
+    }
+    else
+    {
+        *pValid = 0;
+    }
+    
+    return (ucKScan);        
+}    
+
+//=============================================================================
+// EP93XXSpiKbdInit
+//=============================================================================
+void __init EP93XXSpiKbdInit(void)
+{
+	//printk( "Entering EP93XXSpiKbdInit()\n");
+
+	//
+	// Open SSP driver for Keyboard input.
+	//
+    g_SSP_Handle = SSPDriver->Open(PS2_KEYBOARD, HandleKeyPress);
+	
+	InitSniffer();
+
+	//
+	// Now keyboard is active and will generate interrupts
+	// on key presses.  Driver only needs to handle interrupts.
+	// There are NO driver ioctl or deinit functions in lowlevel.
+	//
+	k_unexpected_up = UnexpectedUp;
+	k_setkeycode    = SetKeycode;
+	k_getkeycode    = GetKeycode;
+	
+	k_translate     = KeyboardTranslate;
+	k_leds          = SetLEDs;
+
+	DPRINTK( "Leaving EP93XXSpiKbdInit()\n");
+}
diff -urN linux-2.4.29/drivers/char/ep93xx_ts.c linux-2.4.29-uc1/drivers/char/ep93xx_ts.c
--- linux-2.4.29/drivers/char/ep93xx_ts.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/ep93xx_ts.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,998 @@
+/*
+ *  linux/drivers/char/ep93xx_ts.c
+ *
+ *  Copyright (C) 2003-2004 Cirrus Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+ 
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/compiler.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+
+//
+// To customize for a new touchscreen, there are various macros that
+// have to be set.  If you allow UART_HACK_DEBUG to be defined, you
+// will get real time ts data scrolling up your serial terminal
+// screen that will help you empirically determine good values for these.  
+//
+
+//
+// These are used as trigger levels to know when we have pen up/down
+//
+// The rules:
+// 1.  TS_HEAVY_INV_PRESSURE < TS_LIGHT_INV_PRESSURE because these
+//    are Inverse pressure.  
+// 2.  Any touch lighter than TS_LIGHT_INV_PRESSURE is a pen up.
+// 3.  Any touch heavier than TS_HEAVY_INV_PRESSURE is a pen down.
+//
+#define   TS_HEAVY_INV_PRESSURE 0xFE0 //C00
+#define   TS_LIGHT_INV_PRESSURE 0xFFF //e00
+
+//
+// If the x, y, or inverse pressure changes more than these values
+// between two succeeding points, the point is not reported.
+//
+#define   TS_MAX_VALID_XY_CHANGE 0x300
+#define   TS_MAX_VALID_PRESSURE_CHANGE  0x100
+
+//
+// This is the minimum Z1 Value that is valid.
+//
+#define     MIN_Z1_VALUE                    0x50
+
+//
+// Settling delay for taking each ADC measurement.  Increase this
+// if ts is jittery.
+//
+#define EP93XX_TS_ADC_DELAY_USEC 2000
+
+//
+// Delay between TS points.
+//
+#define EP93XX_TS_PER_POINT_DELAY_USEC 10000
+
+//-----------------------------------------------------------------------------
+// Debug messaging thru the UARTs
+//-----------------------------------------------------------------------------
+/*
+ *  Hello there!  Are you trying to get this driver to work with a new
+ *  touschscreen?  Turn this on and you will get useful info coming
+ *  out of your serial port.
+ */
+/* #define PRINT_CALIBRATION_FACTORS */
+#ifdef PRINT_CALIBRATION_FACTORS
+#define UART_HACK_DEBUG 1
+int iMaxX=0, iMaxY=0, iMinX = 0xfff, iMinY = 0xfff;
+#endif
+
+/*
+ * For debugging, let's spew messages out serial port 1 or 3 at 57,600 baud.
+ */
+/* #define UART_HACK_DEBUG 1 */
+#ifdef UART_HACK_DEBUG
+static char szBuf[256];
+void UARTWriteString(char * msg);
+#define DPRINTK( x... )   \
+    sprintf( szBuf, ##x ); \
+    UARTWriteString( szBuf );
+#else
+#define DPRINTK( x... )
+#endif
+
+//-----------------------------------------------------------------------------
+// A few more macros...
+//-----------------------------------------------------------------------------
+#define TSSETUP_DEFAULT  ( TSSETUP_NSMP_32 | TSSETUP_DEV_64 |  \
+                           ((128<<TSSETUP_SDLY_SHIFT) & TSSETUP_SDLY_MASK) | \
+                           ((128<<TSSETUP_DLY_SHIFT)  & TSSETUP_DLY_MASK) )
+
+#define TSSETUP2_DEFAULT (TSSETUP2_NSIGND)
+
+//
+// For now, we use one of the minor numbers from the local/experimental
+// range.
+//
+#define EP93XX_TS_MINOR 240
+
+//-----------------------------------------------------------------------------
+// Static Declarations
+//-----------------------------------------------------------------------------
+static unsigned int   guiLastX, guiLastY;
+static unsigned int   guiLastInvPressure;
+
+
+static int currentX, currentY, currentButton;
+static int bFreshTouchData;
+static int bCurrentPenDown;
+
+
+static DECLARE_WAIT_QUEUE_HEAD(queue);
+static DECLARE_MUTEX(open_sem);
+static spinlock_t event_buffer_lock = SPIN_LOCK_UNLOCKED;
+static struct fasync_struct *fasync;
+
+//-----------------------------------------------------------------------------
+// Typedef Declarations
+//-----------------------------------------------------------------------------
+typedef enum {
+	TS_MODE_UN_INITIALIZED,
+	TS_MODE_HARDWARE_SCAN,
+	TS_MODE_SOFT_SCAN
+} ts_mode_t;
+
+static ts_mode_t      gScanningMode;
+
+typedef enum{
+    TS_STATE_STOPPED = 0,
+    TS_STATE_Z1,
+    TS_STATE_Z2,
+    TS_STATE_Y,
+    TS_STATE_X,
+    TS_STATE_DONE
+} ts_states_t;
+
+typedef struct 
+{
+    unsigned int   uiX;
+    unsigned int   uiY;
+    unsigned int   uiZ1;
+    unsigned int   uiZ2;
+    ts_states_t    state;
+} ts_struct_t;
+
+static ts_struct_t sTouch;
+
+/*
+ * From the spec, here's how to set up the touch screen's switch registers.
+ */
+typedef struct 
+{
+    unsigned int uiDetect;
+    unsigned int uiDischarge;
+    unsigned int uiXSample;
+    unsigned int uiYSample;
+    unsigned int uiSwitchZ1;
+    unsigned int uiSwitchZ2;
+}SwitchStructType;
+
+//
+// Here's the switch settings for a 4-wire touchscreen.  See the spec
+// for how to handle a 4, 7, or 8-wire.
+//
+const static SwitchStructType sSwitchSettings = 
+/*     s28en=0
+ *   TSDetect    TSDischarge  TSXSample  TSYSample    SwitchZ1   SwitchZ2
+ */
+    {0x00403604, 0x0007fe04, 0x00081604, 0x00104601, 0x00101601, 0x00101608};   
+
+
+//-----------------------------------------------------------------------------
+// Function Declarations
+//-----------------------------------------------------------------------------
+static void ep93xx_ts_set_direct( unsigned int uiADCSwitch );
+static void ep93xx_ts_isr(int irq, void *dev_id, struct pt_regs *regs);
+static void ep93xx_timer2_isr(int irq, void *dev_id, struct pt_regs *regs);
+static void ee93xx_ts_evt_add( int buttons, int dX, int dY );
+static ssize_t ep93xx_ts_read(struct file *filp, char *buf, 
+        size_t count, loff_t *l);
+static unsigned int ep93xx_ts_poll(struct file *filp, poll_table *wait);
+static int ep93xx_ts_open(struct inode *inode, struct file *filp);
+static int ep93xx_ts_fasync(int fd, struct file *filp, int on);
+static int ep93xx_ts_release(struct inode *inode, struct file *filp);
+static ssize_t ep93xx_ts_write(struct file *file, const char *buffer, 
+                size_t count, loff_t *ppos);
+static void ep93xx_hw_setup(void);
+static void ep93xx_hw_shutdown(void);
+int __init ep93xx_ts_init(void);
+void __exit ep93xx_ts_exit(void);
+static unsigned int CalculateInvPressure( void );
+static unsigned int ADCGetData( unsigned int uiSamples, unsigned int uiMaxDiff);
+static void TS_Soft_Scan_Mode(void);
+static void TS_Hardware_Scan_Mode(void);
+static void ProcessPointData(void);
+static void Set_Timer2_uSec( unsigned int Delay_mSec );
+static void Stop_Timer2(void);
+
+
+//-----------------------------------------------------------------------------
+//  Debug stuff...
+//-----------------------------------------------------------------------------
+
+#ifdef UART_HACK_DEBUG
+
+// This "array" is a cheap-n-easy way of getting access to the UART registers.
+static unsigned int * const pDebugUART=(unsigned int *)IO_ADDRESS(UART1_BASE);
+//static unsigned int * const pDebugUART=(unsigned int *)IO_ADDRESS(UART3_BASE);
+static int bUartInitialized = 0; 
+
+void SendChar(char value)
+{
+    // wait for Tx fifo full flag to clear.
+    while (pDebugUART[0x18>>2] & 0x20);
+
+    // send a char to the uart               
+    pDebugUART[0] = value;
+}
+
+void UARTWriteString(char * msg) 
+{
+    int index = 0;
+	unsigned int uiTemp;
+
+    //if((pDebugUART[0x14>>2] & 0x1) == 0)
+    if( bUartInitialized == 0 )
+    {
+        uiTemp = inl(SYSCON_DEVCFG);
+		uiTemp |= SYSCON_DEVCFG_U1EN;
+		//uiTemp |= SYSCON_DEVCFG_U3EN;
+        SysconSetLocked(SYSCON_DEVCFG, uiTemp);  
+        pDebugUART[0x10>>2] = 0xf;
+        pDebugUART[0xc>>2] = 0;
+        pDebugUART[0x8>>2] = 0x70;
+        pDebugUART[0x14>>2] = 0x1;
+        bUartInitialized = 1;
+    }
+    while (msg[index] != 0)
+    {
+        if (msg[index] == '\n')
+        {
+            SendChar('\r');
+            SendChar('\n');
+        }
+        else 
+        {
+            SendChar(msg[index]);
+        }
+        index++;
+    }
+}
+#endif // UART_HACK_DEBUG
+
+/*
+ *  ep93xx_ts_isr
+ */
+static void ep93xx_ts_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+    DPRINTK("isr\n");
+
+    // 
+    // Note that we don't clear the interrupt here.  The interrupt
+    // gets cleared in TS_Soft_Scan_Mode when the TS ENABLE
+    // bit is cleared.
+    //
+
+    //
+    // Set the ts to manual polling mode and schedule a callback.
+    // That way we can return from the isr in a reasonable amount of
+    // time and process the touch in the callback after a brief delay.
+    //
+    TS_Soft_Scan_Mode();
+    
+}
+
+/*
+ * Save the current ts 'event' in an atomic fashion.
+ */
+static void ee93xx_ts_evt_add( int buttons, int iX, int iY )
+{
+#ifdef PRINT_CALIBRATION_FACTORS
+    if( iX > iMaxX ) iMaxX = iX;
+    if( iX < iMinX ) iMinX = iX;
+    if( iY > iMaxY ) iMaxY = iY;
+    if( iY < iMinY ) iMinY = iY;
+#endif
+
+    //DPRINTK("cb\n");
+    /*
+     * Note the event, but use spinlocks to keep it from getting
+     * halfway read if we get interrupted.
+     */  
+    spin_lock(&event_buffer_lock);
+
+    currentButton = buttons;
+    currentX = iX;
+    currentY = iY;
+    bFreshTouchData = 1;
+    
+    spin_unlock(&event_buffer_lock);
+
+    kill_fasync(&fasync, SIGIO, POLL_IN);
+    wake_up_interruptible(&queue);
+}
+
+
+static ssize_t ep93xx_ts_read(struct file *filp, char *buf, size_t count, loff_t *l)
+{
+
+    unsigned short data[3];
+
+#ifdef PRINT_CALIBRATION_FACTORS
+    static int lala=0;
+    if( bFreshTouchData && (lala++ > 9) )
+    {
+        DPRINTK("%4d, %4d - range [%4d to %4d],[%4d to %4d]\n",
+            currentX, currentY, iMinX, iMaxX, iMinY, iMaxY );
+        lala = 0;
+    }
+#endif
+
+    if( bFreshTouchData && (count >= sizeof(data)) )
+    {
+        spin_lock_irq(&event_buffer_lock);
+        bFreshTouchData = 0;
+        data[0] = currentX;
+        data[1] = currentY;
+        data[2] = currentButton;
+        spin_unlock_irq(&event_buffer_lock);
+
+        if (copy_to_user(buf, data, sizeof data))
+            return -EFAULT;
+
+        count -= sizeof(data);
+
+        /* return the # of bytes that got read */
+        return( sizeof(data) );
+    }
+
+    return -EINVAL;
+}
+
+static unsigned int	ep93xx_ts_poll(struct file *filp, poll_table *wait)
+{
+    poll_wait(filp, &queue, wait);
+
+    if( bFreshTouchData )
+    {
+        return POLLIN | POLLRDNORM;
+    }
+    
+    return 0;
+}
+
+static int ep93xx_ts_open(struct inode *inode, struct file *filp)
+{
+    if( down_trylock(&open_sem) )
+    {
+        return -EBUSY;
+    }
+
+    ep93xx_hw_setup();
+
+    return 0;
+}
+
+/*
+ * Asynchronous I/O support.
+ */
+static int ep93xx_ts_fasync(int fd, struct file *filp, int on)
+{
+    int retval;
+
+    retval = fasync_helper(fd, filp, on, &fasync);
+    if (retval < 0)
+    {
+        return retval;
+    }
+    
+    return 0;
+}
+
+static int ep93xx_ts_release(struct inode *inode, struct file *filp)
+{
+    Stop_Timer2();
+
+    /*
+     * Call our async I/O support to request that this file 
+     * cease to be used for async I/O.
+     */
+    ep93xx_ts_fasync(-1, filp, 0);
+
+    ep93xx_hw_shutdown();
+    
+    up(&open_sem);
+    
+    return 0;
+}
+
+static ssize_t ep93xx_ts_write(struct file *file, const char *buffer, size_t count,
+               loff_t *ppos)
+{
+    return -EINVAL;
+}
+
+static struct file_operations ep93xx_ts_fops = {
+    owner:      THIS_MODULE,
+    read:       ep93xx_ts_read,
+    write:      ep93xx_ts_write,
+    poll:       ep93xx_ts_poll,
+    open:       ep93xx_ts_open,
+    release:    ep93xx_ts_release,
+    fasync:     ep93xx_ts_fasync,
+};
+
+static struct miscdevice ep93xx_ts_miscdev = 
+{
+        EP93XX_TS_MINOR,
+        "ep93xx_ts",
+        &ep93xx_ts_fops
+};
+
+void ep93xx_hw_setup(void)
+{
+    unsigned int uiKTDIV, uiTSXYMaxMin;
+    
+    /*
+     * Set the TSEN bit in KTDIV so that we are enabling the clock
+     * for the touchscreen.
+     */    
+    uiKTDIV = inl(SYSCON_KTDIV);
+    uiKTDIV |= SYSCON_KTDIV_TSEN;
+    SysconSetLocked( SYSCON_KTDIV, uiKTDIV );    
+
+    //
+    // Program the TSSetup and TSSetup2 registers.
+    //
+	outl( TSSETUP_DEFAULT, TSSetup );
+	outl( TSSETUP2_DEFAULT, TSSetup2 );
+
+    //
+    // Set the the touch settings. 
+    //
+	outl( 0xaa, TSSWLock );
+	outl( sSwitchSettings.uiDischarge, TSDirect );
+
+	outl( 0xaa, TSSWLock );
+	outl( sSwitchSettings.uiDischarge, TSDischarge );
+
+	outl( 0xaa, TSSWLock );
+	outl( sSwitchSettings.uiSwitchZ1, TSXSample );
+
+	outl( 0xaa, TSSWLock );
+	outl( sSwitchSettings.uiSwitchZ2, TSYSample );
+
+	outl( 0xaa, TSSWLock );
+	outl( sSwitchSettings.uiDetect, TSDetect );
+
+    //
+    // X,YMin set to 0x40 = have to drag that many pixels for a new irq.
+    // X,YMax set to 0x40 = 1024 pixels is the maximum movement within the
+    // time scan limit.
+    //
+	uiTSXYMaxMin =  (50   << TSMAXMIN_XMIN_SHIFT) & TSMAXMIN_XMIN_MASK;
+	uiTSXYMaxMin |=	(50   << TSMAXMIN_YMIN_SHIFT) & TSMAXMIN_YMIN_MASK;
+	uiTSXYMaxMin |=	(0xff << TSMAXMIN_XMAX_SHIFT) & TSMAXMIN_XMAX_MASK;
+	uiTSXYMaxMin |=	(0xff << TSMAXMIN_YMAX_SHIFT) & TSMAXMIN_YMAX_MASK;
+	outl( uiTSXYMaxMin, TSXYMaxMin );
+	
+	bCurrentPenDown = 0;
+    bFreshTouchData = 0;
+	guiLastX = 0;
+	guiLastY = 0;
+	guiLastInvPressure = 0xffffff;
+	
+    //
+    // Enable the touch screen scanning engine.
+    //
+    TS_Hardware_Scan_Mode();
+
+}
+
+/*
+ * ep93xx_hw_shutdown
+ *
+ */
+static void
+ep93xx_hw_shutdown(void)
+{
+    unsigned int uiKTDIV;
+    
+    DPRINTK("ep93xx_hw_shutdown\n");
+	
+    sTouch.state = TS_STATE_STOPPED;
+	Stop_Timer2();
+
+    /*
+     * Disable the scanning engine.
+     */
+	outl( 0, TSSetup );
+	outl( 0, TSSetup2 );
+
+    /*
+     * Clear the TSEN bit in KTDIV so that we are disabling the clock
+     * for the touchscreen.
+     */    
+    uiKTDIV = inl(SYSCON_KTDIV);
+    uiKTDIV &= ~SYSCON_KTDIV_TSEN;
+    SysconSetLocked( SYSCON_KTDIV, uiKTDIV );    
+
+} /* ep93xx_hw_shutdown */
+
+static void ep93xx_timer2_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+    DPRINTK("%d", (int)sTouch.state );
+
+    switch( sTouch.state )
+    {
+        case TS_STATE_STOPPED:
+			TS_Hardware_Scan_Mode();
+            break;
+            
+        //
+        // Get the Z1 value for pressure measurement and set up
+		// the switch register for getting the Z2 measurement.
+        //
+        case TS_STATE_Z1:
+		    Set_Timer2_uSec( EP93XX_TS_ADC_DELAY_USEC );
+            sTouch.uiZ1 = ADCGetData( 2, 200 );
+            ep93xx_ts_set_direct( sSwitchSettings.uiSwitchZ2 );
+            sTouch.state = TS_STATE_Z2;
+            break;
+        
+        //
+        // Get the Z2 value for pressure measurement and set up
+		// the switch register for getting the Y measurement.
+        //
+        case TS_STATE_Z2:
+            sTouch.uiZ2 = ADCGetData( 2, 200 );
+            ep93xx_ts_set_direct( sSwitchSettings.uiYSample );
+            sTouch.state = TS_STATE_Y;
+			break;
+		
+		//
+        // Get the Y value and set up the switch register for 
+		// getting the X measurement.
+        //
+        case TS_STATE_Y:
+            sTouch.uiY = ADCGetData( 4, 20 );
+            ep93xx_ts_set_direct( sSwitchSettings.uiXSample );
+            sTouch.state = TS_STATE_X;
+            break;
+        
+        //
+        // Read the X value.  This is the last of the 4 adc values
+        // we need so we continue on to process the data.
+        //
+        case TS_STATE_X:
+            Stop_Timer2();
+            
+            sTouch.uiX = ADCGetData( 4, 20 );
+            
+			outl( 0xaa, TSSWLock );
+			outl( sSwitchSettings.uiDischarge, TSDirect );
+            
+            sTouch.state = TS_STATE_DONE;
+        
+            /*
+             * Process this set of ADC readings.
+             */
+            ProcessPointData();
+            
+            break;
+
+
+        //
+		// Shouldn't get here.  But if we do, we can recover...
+		//
+		case TS_STATE_DONE:
+			TS_Hardware_Scan_Mode();
+            break;
+    } 
+
+    //
+    // Clear the timer2 interrupt.
+    //
+	outl( 1, TIMER2CLEAR );
+
+}
+
+/*---------------------------------------------------------------------
+ * ProcessPointData
+ *
+ * This routine processes the ADC data into usable point data and then
+ * puts the driver into hw or sw scanning mode before returning.
+ *
+ * We calculate inverse pressure (lower number = more pressure) then
+ * do a hystheresis with the two pressure values 'light' and 'heavy'.
+ *
+ * If we are above the light, we have pen up.
+ * If we are below the heavy we have pen down.
+ * As long as the pressure stays below the light, pen stays down.
+ * When we get above the light again, pen goes back up.
+ *
+ */
+static void ProcessPointData(void)
+{
+    int  bValidPoint = 0;
+    unsigned int   uiXDiff, uiYDiff, uiInvPressureDiff;
+    unsigned int   uiInvPressure;
+
+    //
+    // Calculate the current pressure.
+    //
+    uiInvPressure = CalculateInvPressure();
+
+    DPRINTK(" X=0x%x, Y=0x%x, Z1=0x%x, Z2=0x%x, InvPressure=0x%x",
+            sTouch.uiX, sTouch.uiY, sTouch.uiZ1, sTouch.uiZ2, uiInvPressure ); 
+
+
+
+	//
+	// If pen pressure is so light that it is greater than the 'max' setting
+	// then we consider this to be a pen up.
+	//
+    if( uiInvPressure >= TS_LIGHT_INV_PRESSURE )
+	{
+		DPRINTK(" -- up \n");
+		bCurrentPenDown = 0;
+        ee93xx_ts_evt_add( 0, guiLastX, guiLastY );
+		TS_Hardware_Scan_Mode();
+		return;
+	}
+
+    //
+	// Hystheresis:
+    // If the pen pressure is hard enough to be less than the 'min' OR
+	// the pen is already down and is still less than the 'max'...
+	//
+    if( (uiInvPressure < TS_HEAVY_INV_PRESSURE) ||
+        ( bCurrentPenDown && (uiInvPressure < TS_LIGHT_INV_PRESSURE) )  )
+    {
+        if( bCurrentPenDown )
+        {
+            //
+            // If pen was previously down, check the difference between
+            // the last sample and this one... if the difference between 
+            // samples is too great, ignore the sample.
+            //
+            uiXDiff = abs(guiLastX - sTouch.uiX);
+            uiYDiff = abs(guiLastY - sTouch.uiY);
+			uiInvPressureDiff = abs(guiLastInvPressure - uiInvPressure);
+			
+            if( (uiXDiff < TS_MAX_VALID_XY_CHANGE) && 
+			    (uiYDiff < TS_MAX_VALID_XY_CHANGE) &&
+				(uiInvPressureDiff < TS_MAX_VALID_PRESSURE_CHANGE) )
+            {
+				DPRINTK(" -- valid(two) \n");
+                bValidPoint = 1;
+            }
+			else
+			{
+				DPRINTK(" -- INvalid(two) \n");
+			}
+        }
+        else
+        {
+			DPRINTK(" -- valid \n");
+            bValidPoint = 1;
+        }
+        
+        /*
+         * If either the pen was put down or dragged make a note of it.
+         */
+        if( bValidPoint )
+        {
+	        guiLastX = sTouch.uiX;
+	        guiLastY = sTouch.uiY;
+			guiLastInvPressure = uiInvPressure;
+			bCurrentPenDown = 1;
+            ee93xx_ts_evt_add( 1, sTouch.uiX, sTouch.uiY );
+        }
+
+        TS_Soft_Scan_Mode();
+		return;
+    }
+
+	DPRINTK(" -- fallout \n");
+	TS_Hardware_Scan_Mode();
+}
+
+static void ep93xx_ts_set_direct( unsigned int uiADCSwitch )
+{
+    unsigned int uiResult;
+    
+    //
+    // Set the switch settings in the direct register.
+    //
+	outl( 0xaa, TSSWLock );
+	outl( uiADCSwitch, TSDirect );
+
+    //
+    // Read and throw away the first sample.
+    //
+    do {
+        uiResult = inl(TSXYResult);
+    } while( !(uiResult & TSXYRESULT_SDR) );
+    
+}
+
+static unsigned int ADCGetData
+( 
+    unsigned int uiSamples, 
+    unsigned int uiMaxDiff 
+)
+{
+    unsigned int   uiResult, uiValue, uiCount, uiLowest, uiHighest, uiSum, uiAve;
+
+    do
+    {
+        //
+        //Initialize our values.
+        //
+        uiLowest        = 0xfffffff;
+        uiHighest       = 0;
+        uiSum           = 0;
+        
+        for( uiCount = 0 ; uiCount < uiSamples ; uiCount++ )
+        {
+            //
+            // Read the touch screen four more times and average.
+            //
+            do {
+		        uiResult = inl(TSXYResult);
+            } while( !(uiResult & TSXYRESULT_SDR) );
+            
+            uiValue = (uiResult & TSXYRESULT_AD_MASK) >> TSXYRESULT_AD_SHIFT;
+            uiValue = ((uiValue >> 4) + ((1 + TSXYRESULT_X_MASK)>>1))  & TSXYRESULT_X_MASK; 
+
+            //
+            // Add up the values.
+            //
+            uiSum += uiValue;
+
+            //
+            // Get the lowest and highest values.
+            //
+            if( uiValue < uiLowest )
+            {
+                uiLowest = uiValue;
+            }
+            if( uiValue > uiHighest )
+            {
+                uiHighest = uiValue;
+            }
+        }
+
+    } while( (uiHighest - uiLowest) > uiMaxDiff );
+
+    //
+    // Calculate the Average value.
+    //
+    uiAve = uiSum / uiSamples;
+
+    return uiAve;    
+}
+
+//****************************************************************************
+// CalculateInvPressure
+//****************************************************************************
+// Is the Touch Valid.  Touch is not valid if the X or Y value is not 
+// in range and the pressure is not  enough.
+// 
+// Touch resistance can be measured by the following formula:
+//
+//          Rx * X *     Z2
+// Rtouch = --------- * (-- - 1)
+//           4096        Z1
+//
+// This is simplified in the ration of Rtouch to Rx.  The lower the value, the
+// higher the pressure.
+//
+//                     Z2
+// InvPressure =  X * (-- - 1)
+//                     Z1
+//
+static unsigned int CalculateInvPressure(void)
+{
+    unsigned int   uiInvPressure;
+
+    //
+    // Check to see if the point is valid.
+    //
+    if( sTouch.uiZ1 < MIN_Z1_VALUE )
+    {
+        uiInvPressure = 0x10000;
+    }
+
+    //
+    // Can omit the pressure calculation if you need to get rid of the division.
+    //
+    else
+    {
+        uiInvPressure = ((sTouch.uiX * sTouch.uiZ2) / sTouch.uiZ1) - sTouch.uiX;
+    }    
+
+    return uiInvPressure;
+}
+
+
+
+//****************************************************************************
+// TS_Hardware_Scan_Mode
+//****************************************************************************
+// Enables the ep93xx ts scanning engine so that when the pen goes down
+// we will get an interrupt.
+// 
+//
+static void TS_Hardware_Scan_Mode(void)
+{
+    unsigned int   uiDevCfg;
+
+    DPRINTK("S\n");
+
+    //
+	// Disable the soft scanning engine.
+	//
+	sTouch.state = TS_STATE_STOPPED;
+    Stop_Timer2();
+    
+    //
+    // Clear the TIN (Touchscreen INactive) bit so we can go to
+    // automatic scanning mode.
+    //
+    uiDevCfg = inl( SYSCON_DEVCFG );
+    SysconSetLocked( SYSCON_DEVCFG, (uiDevCfg & ~SYSCON_DEVCFG_TIN) );    
+
+    //
+    // Enable the touch screen scanning state machine by setting
+    // the ENABLE bit.
+    //
+	outl( (TSSETUP_DEFAULT | TSSETUP_ENABLE), TSSetup );
+
+    //
+    // Set the flag to show that we are in interrupt mode.
+    //
+    gScanningMode = TS_MODE_HARDWARE_SCAN;
+
+    //
+    // Initialize TSSetup2 register.
+    //
+	outl( TSSETUP2_DEFAULT, TSSetup2 );
+
+}
+
+//****************************************************************************
+// TS_Soft_Scan_Mode
+//****************************************************************************
+// Sets the touch screen to manual polling mode.
+// 
+//
+static void TS_Soft_Scan_Mode(void)
+{
+    unsigned int   uiDevCfg;
+
+    DPRINTK("M\n");
+
+    if( gScanningMode != TS_MODE_SOFT_SCAN )
+    {
+        //
+        // Disable the touch screen scanning state machine by clearing
+        // the ENABLE bit.
+        //
+		outl( TSSETUP_DEFAULT, TSSetup );
+
+        //
+        // Set the TIN bit so we can do manual touchscreen polling.
+        //
+        uiDevCfg = inl( SYSCON_DEVCFG );
+        SysconSetLocked( SYSCON_DEVCFG, (uiDevCfg | SYSCON_DEVCFG_TIN) );    
+    }
+
+    //
+	// Set the switch register up for the first ADC reading
+	//
+	ep93xx_ts_set_direct( sSwitchSettings.uiSwitchZ1 );
+	
+	//
+	// Initialize our software state machine to know which ADC
+	// reading to take
+	//
+    sTouch.state = TS_STATE_Z1;
+	
+	//
+	// Set the timer so after a mSec or two settling delay it will 
+	// take the first ADC reading.
+	// 
+    Set_Timer2_uSec( EP93XX_TS_PER_POINT_DELAY_USEC );
+    
+    //
+    // Note that we are in sw scanning mode not hw scanning mode.
+    //
+    gScanningMode = TS_MODE_SOFT_SCAN;
+
+}
+
+static void Set_Timer2_uSec( unsigned int uiDelay_uSec )
+{
+    unsigned int uiClockTicks;
+
+    /*
+     * Stop timer 2
+     */
+	outl( 0, TIMER2CONTROL );
+
+    uiClockTicks = ((uiDelay_uSec * 508) + 999) / 1000;
+    outl( uiClockTicks, TIMER2LOAD );
+    outl( uiClockTicks, TIMER2VALUE );
+
+    /*
+     * Set up Timer 2 for 508 kHz clock and periodic mode.
+     */ 
+    outl( 0xC8, TIMER2CONTROL );
+
+}
+
+static void Stop_Timer2(void)
+{
+    outl( 0, TIMER2CONTROL );
+}
+
+/*
+ * Initialization and exit routines
+ */
+int __init
+ep93xx_ts_init(void)
+{
+    int retval;
+
+    DPRINTK("ep93xx_ts_init\n");
+
+    retval = request_irq( IRQ_TOUCH, ep93xx_ts_isr,	SA_INTERRUPT, "ep93xx_ts", 0);
+    if( retval )
+    {
+        printk(KERN_WARNING "ep93xx_ts: failed to get touchscreen IRQ\n");
+        return retval;
+    }
+
+    retval = request_irq( IRQ_TIMER2, ep93xx_timer2_isr,
+                        SA_INTERRUPT, "ep93xx_timer2", 0);
+    if( retval )
+    {
+        printk(KERN_WARNING "ep93xx_ts: failed to get timer2 IRQ\n");
+        return retval;
+    }
+
+    misc_register(&ep93xx_ts_miscdev);
+
+    sTouch.state = TS_STATE_STOPPED;
+	gScanningMode = TS_MODE_UN_INITIALIZED;
+    
+    printk(KERN_NOTICE "EP93xx touchscreen driver configured for 4-wire operation\n");
+
+    return 0;
+}
+
+void __exit
+ep93xx_ts_exit(void)
+{
+    DPRINTK("ep93xx_ts_exit\n");
+    
+    Stop_Timer2();
+
+    free_irq(IRQ_TOUCH, 0);
+    free_irq(IRQ_TIMER2, 0);
+    
+    misc_deregister(&ep93xx_ts_miscdev);
+}
+
+module_init(ep93xx_ts_init);
+module_exit(ep93xx_ts_exit);
+
+MODULE_DESCRIPTION("Cirrus EP93xx touchscreen driver");
+MODULE_SUPPORTED_DEVICE("touchscreen/ep93xx");
diff -urN linux-2.4.29/drivers/char/ep93xx_usb_kbd.c linux-2.4.29-uc1/drivers/char/ep93xx_usb_kbd.c
--- linux-2.4.29/drivers/char/ep93xx_usb_kbd.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/ep93xx_usb_kbd.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,314 @@
+/******************************************************************************
+ * 
+ *  File:	linux/drivers/char/ep93xx_usb_kbd.c
+ *
+ *  Purpose: Support for USB Keyboard hack ;) for a Cirrus Logic EP93xx
+ *
+ *  History:	
+ *
+ *  Limitations:
+ *  Break and Print Screen keys not handled yet!
+ *
+ *
+ *  Copyright 2003 Cirrus Logic Inc.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/config.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/keyboard.h>
+
+/* Simple translation table for the SysRq keys */
+
+#ifdef CONFIG_MAGIC_SYSRQ
+unsigned char ep93xx_sysrq_xlate[128] =
+	"\000\0331234567890-=\177\t"			/* 0x00 - 0x0f */
+	"qwertyuiop[]\r\000as"				/* 0x10 - 0x1f */
+	"dfghjkl;'`\000\\zxcv"				/* 0x20 - 0x2f */
+	"bnm,./\000*\000 \000\201\202\203\204\205"	/* 0x30 - 0x3f */
+	"\206\207\210\211\212\000\000789-456+1"		/* 0x40 - 0x4f */
+	"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
+	"\r\000/";					/* 0x60 - 0x6f */
+#endif
+
+/*
+ * Translation of escaped scancodes to keycodes.
+ * This is now user-settable.
+ * The keycodes 1-88,96-111,119 are fairly standard, and
+ * should probably not be changed - changing might confuse X.
+ * X also interprets scancode 0x5d (KEY_Begin).
+ *
+ * For 1-88 keycode equals scancode.
+ */
+
+#define E0_KPENTER 96
+#define E0_RCTRL   97
+#define E0_KPSLASH 98
+#define E0_PRSCR   99
+#define E0_RALT    100
+#define E0_BREAK   101  /* (control-pause) */
+#define E0_HOME    102
+#define E0_UP      103
+#define E0_PGUP    104
+#define E0_LEFT    105
+#define E0_RIGHT   106
+#define E0_END     107
+#define E0_DOWN    108
+#define E0_PGDN    109
+#define E0_INS     110
+#define E0_DEL     111
+
+#define E1_PAUSE   119
+
+/*
+ * The keycodes below are randomly located in 89-95,112-118,120-127.
+ * They could be thrown away (and all occurrences below replaced by 0),
+ * but that would force many users to use the `setkeycodes' utility, where
+ * they needed not before. It does not matter that there are duplicates, as
+ * long as no duplication occurs for any single keyboard.
+ */
+#define SC_LIM 89
+
+#define FOCUS_PF1 85           /* actual code! */
+#define FOCUS_PF2 89
+#define FOCUS_PF3 90
+#define FOCUS_PF4 91
+#define FOCUS_PF5 92
+#define FOCUS_PF6 93
+#define FOCUS_PF7 94
+#define FOCUS_PF8 95
+#define FOCUS_PF9 120
+#define FOCUS_PF10 121
+#define FOCUS_PF11 122
+#define FOCUS_PF12 123
+
+#define JAP_86     124
+/* tfj@olivia.ping.dk:
+ * The four keys are located over the numeric keypad, and are
+ * labelled A1-A4. It's an rc930 keyboard, from
+ * Regnecentralen/RC International, Now ICL.
+ * Scancodes: 59, 5a, 5b, 5c.
+ */
+#define RGN1 124
+#define RGN2 125
+#define RGN3 126
+#define RGN4 127
+
+static unsigned char high_keys[128 - SC_LIM] = {
+  RGN1, RGN2, RGN3, RGN4, 0, 0, 0,                   /* 0x59-0x5f */
+  0, 0, 0, 0, 0, 0, 0, 0,                            /* 0x60-0x67 */
+  0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12,          /* 0x68-0x6f */
+  0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3,    /* 0x70-0x77 */
+  FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7,        /* 0x78-0x7b */
+  FOCUS_PF8, JAP_86, FOCUS_PF10, 0                   /* 0x7c-0x7f */
+};
+
+/* BTC */
+#define E0_MACRO   112
+/* LK450 */
+#define E0_F13     113
+#define E0_F14     114
+#define E0_HELP    115
+#define E0_DO      116
+#define E0_F17     117
+#define E0_KPMINPLUS 118
+/*
+ * My OmniKey generates e0 4c for  the "OMNI" key and the
+ * right alt key does nada. [kkoller@nyx10.cs.du.edu]
+ */
+#define E0_OK	124
+/*
+ * New microsoft keyboard is rumoured to have
+ * e0 5b (left window button), e0 5c (right window button),
+ * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
+ * [or: Windows_L, Windows_R, TaskMan]
+ */
+#define E0_MSLW	125
+#define E0_MSRW	126
+#define E0_MSTM	127
+
+static unsigned char e0_keys[128] = {
+  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x00-0x07 */
+  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x08-0x0f */
+  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x10-0x17 */
+  0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0,	      /* 0x18-0x1f */
+  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x20-0x27 */
+  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x28-0x2f */
+  0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR,	      /* 0x30-0x37 */
+  E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP,	      /* 0x38-0x3f */
+  E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME,	      /* 0x40-0x47 */
+  E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
+  E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0,	      /* 0x50-0x57 */
+  0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0,	      /* 0x58-0x5f */
+  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x60-0x67 */
+  0, 0, 0, 0, 0, 0, 0, E0_MACRO,		      /* 0x68-0x6f */
+  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x70-0x77 */
+  0, 0, 0, 0, 0, 0, 0, 0			      /* 0x78-0x7f */
+};
+
+int ep93xx_translate(unsigned char scancode, unsigned char *keycode, 
+		     char raw_mode)
+{
+	static int prev_scancode;
+
+	/* special prefix scancodes.. */
+	if (scancode == 0xe0 || scancode == 0xe1) {
+		prev_scancode = scancode;
+		return 0;
+	}
+
+	/* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
+	if (scancode == 0x00 || scancode == 0xff) {
+		prev_scancode = 0;
+		return 0;
+	}
+
+	scancode &= 0x7f;
+
+	if (prev_scancode) {
+	  /*
+	   * usually it will be 0xe0, but a Pause key generates
+	   * e1 1d 45 e1 9d c5 when pressed, and nothing when released
+	   */
+	  if (prev_scancode != 0xe0) {
+	      if (prev_scancode == 0xe1 && scancode == 0x1d) {
+		  prev_scancode = 0x100;
+		  return 0;
+	      } else if (prev_scancode == 0x100 && scancode == 0x45) {
+		  *keycode = E1_PAUSE;
+		  prev_scancode = 0;
+	      } else {
+#ifdef KBD_REPORT_UNKN
+		  if (!raw_mode)
+		    printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
+#endif
+		  prev_scancode = 0;
+		  return 0;
+	      }
+	  } else {
+	      prev_scancode = 0;
+	      /*
+	       *  The keyboard maintains its own internal caps lock and
+	       *  num lock statuses. In caps lock mode E0 AA precedes make
+	       *  code and E0 2A follows break code. In num lock mode,
+	       *  E0 2A precedes make code and E0 AA follows break code.
+	       *  We do our own book-keeping, so we will just ignore these.
+	       */
+	      /*
+	       *  For my keyboard there is no caps lock mode, but there are
+	       *  both Shift-L and Shift-R modes. The former mode generates
+	       *  E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
+	       *  So, we should also ignore the latter. - aeb@cwi.nl
+	       */
+	      if (scancode == 0x2a || scancode == 0x36)
+		return 0;
+
+	      if (e0_keys[scancode])
+		*keycode = e0_keys[scancode];
+	      else {
+#ifdef KBD_REPORT_UNKN
+		  if (!raw_mode)
+		    printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
+			   scancode);
+#endif
+		  return 0;
+	      }
+	  }
+	} else if (scancode >= SC_LIM) {
+	    /* This happens with the FOCUS 9000 keyboard
+	       Its keys PF1..PF12 are reported to generate
+	       55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
+	       Moreover, unless repeated, they do not generate
+	       key-down events, so we have to zero up_flag below */
+	    /* Also, Japanese 86/106 keyboards are reported to
+	       generate 0x73 and 0x7d for \ - and \ | respectively. */
+	    /* Also, some Brazilian keyboard is reported to produce
+	       0x73 and 0x7e for \ ? and KP-dot, respectively. */
+
+	  *keycode = high_keys[scancode - SC_LIM];
+
+	  if (!*keycode) {
+	      if (!raw_mode) {
+#ifdef KBD_REPORT_UNKN
+		  printk(KERN_INFO "keyboard: unrecognized scancode (%02x)"
+			 " - ignored\n", scancode);
+#endif
+	      }
+	      return 0;
+	  }
+ 	} else
+	  *keycode = scancode;
+ 	return 1;
+}
+
+//=============================================================================
+//=============================================================================
+char ep93xx_unexpected_up(unsigned char keycode)
+{
+	/* unexpected, but this can happen: maybe this was a key release for a
+	   FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */
+	if (keycode >= SC_LIM || keycode == 85)
+	    return 0;
+	else
+	    return 0200;
+}
+
+//=============================================================================
+//=============================================================================
+static int ep93xx_setkeycode(unsigned int scancode, unsigned int keycode)
+{
+	if (scancode < SC_LIM || scancode > 255 || keycode > 127)
+	  return -EINVAL;
+	if (scancode < 128)
+	  high_keys[scancode - SC_LIM] = keycode;
+	else
+	  e0_keys[scancode - 128] = keycode;
+	return 0;
+}
+
+//=============================================================================
+//=============================================================================
+static int ep93xx_getkeycode(unsigned int scancode)
+{
+	return
+	  (scancode < SC_LIM || scancode > 255) ? -EINVAL :
+	  (scancode < 128) ? high_keys[scancode - SC_LIM] :
+	    e0_keys[scancode - 128];
+}
+
+//=============================================================================
+//=============================================================================
+static void ep93xx_leds(unsigned char leds)
+{
+}
+
+//=============================================================================
+// EP93XXUSBKbdInit
+//=============================================================================
+void __init EP93XXUSBKbdInit(void)
+{
+	k_unexpected_up = ep93xx_unexpected_up;
+	k_setkeycode    = ep93xx_setkeycode;
+	k_getkeycode    = ep93xx_getkeycode;
+	
+	k_translate     = ep93xx_translate;
+	k_leds          = ep93xx_leds;
+#ifdef CONFIG_MAGIC_SYSRQ
+	k_sysrq_key	= 0x63;
+	k_sysrq_xlate	= ep93xx_sysrq_xlate;
+#endif
+}
diff -urN linux-2.4.29/drivers/char/exp.c linux-2.4.29-uc1/drivers/char/exp.c
--- linux-2.4.29/drivers/char/exp.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/exp.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,194 @@
+/*****************************************************************************/
+
+/*
+ *	exp.c -- simple expansion interface driver.
+ *
+ *	(C) Copyright 2001-2003, Greg Ungerer <gerg@snapgear.com>
+ */
+
+/*****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/init.h>
+#include <asm/param.h>
+#include <asm/uaccess.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+/*****************************************************************************/
+
+/*
+ *	Define driver major number.
+ */
+#define	EXP_MAJOR	121
+
+#define	EXP_ADDR	0xe0000000
+#define	EXP_IRQ		67
+#define	EXP_MSIZE	64
+
+/*
+ *	Internal driver state.
+ */
+int	exp_isopen;
+int	exp_blocking;
+
+/*
+ *	Access to the hardware port.
+ */
+volatile unsigned char	*exp_datap;
+
+/*****************************************************************************/
+
+int exp_open(struct inode *inode, struct file *filp)
+{
+#ifdef DEBUG
+	printk("exp_open()\n");
+#endif
+	exp_blocking = (filp->f_flags & O_NONBLOCK) ? 0 : 1;
+	exp_isopen++;
+	return(0);
+}
+
+/*****************************************************************************/
+
+int exp_close(struct inode *inode, struct file *filp)
+{
+#ifdef DEBUG
+	printk("exp_close()\n");
+#endif
+	exp_isopen = 0;
+	return(0);
+}
+
+/*****************************************************************************/
+
+ssize_t exp_read(struct file *fp, char *buf, size_t count, loff_t *ptr)
+{
+	volatile unsigned char	*dp;
+	ssize_t			total;
+
+#ifdef DEBUG
+	printk("exp_read(buf=%x,count=%d)\n", (int) buf, count);
+#endif
+
+	if (fp->f_pos >= EXP_MSIZE)
+		return(0);
+	if (count > (EXP_MSIZE - fp->f_pos))
+		count = EXP_MSIZE - fp->f_pos;
+
+	for (total = 0, dp = &exp_datap[fp->f_pos]; (total < count); total++)
+		put_user(*dp++, buf++);
+
+	fp->f_pos += total;
+	return(total);
+}
+
+/*****************************************************************************/
+
+ssize_t exp_write(struct file *fp, const char *buf, size_t count, loff_t *ptr)
+{
+	volatile unsigned char	*dp;
+	ssize_t			total;
+
+#if 0
+	printk("exp_write(buf=%x,count=%d)\n", (int) buf, count);
+#endif
+
+	if (fp->f_pos >= EXP_MSIZE)
+		return(0);
+	if (count > (EXP_MSIZE - fp->f_pos))
+		count = EXP_MSIZE - fp->f_pos;
+
+	for (total = 0, dp = &exp_datap[fp->f_pos]; (total < count); total++)
+		get_user(*dp++, buf++);
+
+	fp->f_pos += total;
+	return(total);
+}
+
+/*****************************************************************************/
+
+int exp_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	volatile unsigned short	*ap;
+	unsigned int		val;
+	int			rc = 0;
+
+	switch (cmd) {
+	case 0x5501:
+		ap = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+		val = (*ap & 0xc000) >> 14;
+		put_user(val, (unsigned int *) arg);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return(rc);
+}
+
+/*****************************************************************************/
+
+void exp_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	volatile unsigned long	*icrp;
+
+#ifdef DEBUG
+	printk("exp_isr(irq=%d)\n", irq);
+#endif
+
+	/* Acknowledge interrupt */
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x77777777) | 0x00800000;
+}
+
+/*****************************************************************************/
+
+/*
+ *	Exported file operations structure for driver...
+ */
+
+struct file_operations	exp_fops = {
+	open: exp_open,
+	release: exp_close,
+	read: exp_read,
+	write: exp_write,
+	ioctl: exp_ioctl,
+};
+
+/*****************************************************************************/
+
+int __init exp_init(void)
+{
+	volatile unsigned long	*icrp;
+	int			rc;
+
+	if ((rc = register_chrdev(EXP_MAJOR, "exp", &exp_fops)) < 0) {
+		printk(KERN_WARNING "EXP: register_chrdev(major=%d) failed, "
+			"rc=%d\n", EXP_MAJOR, rc);
+		return(-EBUSY);
+	}
+	printk("EXP: Copyright (C) 2001-2003, Greg Ungerer <gerg@snapgear.com>\n");
+
+	/* Port CS6 setup in boot loader */
+	exp_datap = (volatile unsigned char *) EXP_ADDR;
+
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x77077777) | 0x00d00000;
+	if (request_irq(EXP_IRQ, exp_isr, SA_INTERRUPT, "exp", NULL))
+		printk(KERN_WARNING "EXP: request_irq(%d) failed\n", EXP_IRQ);
+	return(0);
+}
+
+/*****************************************************************************/
+
+module_init(exp_init);
+
+/*****************************************************************************/
diff -urN linux-2.4.29/drivers/char/fast_timer.c linux-2.4.29-uc1/drivers/char/fast_timer.c
--- linux-2.4.29/drivers/char/fast_timer.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/fast_timer.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,171 @@
+/*
+ * linux/drivers/char/fast_timer.c
+ *
+ * Fast timer code for general use, primarily polling network chips
+ *
+ * Copyright (c) 2004 SnapGear Inc. <www.snapgear.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/fast_timer.h>
+#ifdef CONFIG_SYSCTL
+#include <linux/sysctl.h>
+#endif
+
+#include <linux/fast_timer.h>
+
+
+struct ftentry {
+	void	(*func)(void *);
+	void	*arg;
+};
+
+#define	FAST_TIMER_MAX	8
+static struct ftentry	fast_timer[FAST_TIMER_MAX];
+static int		fast_timers = 0;
+static spinlock_t	fast_timer_lock;
+static int		fast_timer_rate;
+
+void fast_timer_add(void (*func)(void *arg), void *arg)
+{
+	int i;
+	unsigned long flags;
+
+	spin_lock_irqsave(&fast_timer_lock, flags);
+	for (i = 0; i < fast_timers; i++) {
+		if (fast_timer[i].func == func && fast_timer[i].arg == arg) {
+			spin_unlock_irqrestore(&fast_timer_lock, flags);
+			printk(KERN_ERR
+					"fast_timer: entry already exists (0x%x, 0x%x)\n",
+					(unsigned int) func, (unsigned int) arg);
+			return;
+		}
+	}
+
+	if (fast_timers >= FAST_TIMER_MAX) {
+		spin_unlock_irqrestore(&fast_timer_lock, flags);
+		printk(KERN_ERR "fast timer: no free slots\n");
+		return;
+	}
+
+	fast_timer[fast_timers].func = func;
+	fast_timer[fast_timers].arg = arg;
+	fast_timers++;
+	spin_unlock_irqrestore(&fast_timer_lock, flags);
+}
+
+void fast_timer_remove(void (*func)(void *arg), void *arg)
+{
+	int i;
+	unsigned long flags;
+
+	spin_lock_irqsave(&fast_timer_lock, flags);
+	for (i = 0; i < fast_timers; i++) {
+		if (fast_timer[i].func == func && fast_timer[i].arg == arg) {
+			memmove(&fast_timer[i], &fast_timer[i+1],
+					sizeof(struct ftentry) * (FAST_TIMER_MAX - (i+1)));
+			fast_timers--;
+			spin_unlock_irqrestore(&fast_timer_lock, flags);
+			return;
+		}
+	}
+	spin_unlock_irqrestore(&fast_timer_lock, flags);
+	printk(KERN_ERR "fast timer: entry does not exist (0x%x, 0x%x)\n",
+			(unsigned int) func, (unsigned int) arg);
+}
+
+static void do_fast_timer(void)
+{
+	int i;
+
+	for (i = 0; i < fast_timers; i++)
+		(*fast_timer[i].func)(fast_timer[i].arg);
+}
+
+#include <asm/fast_timer.h>
+
+#ifdef CONFIG_SYSCTL
+int fast_timer_sysctl(ctl_table *ctl, int write,
+        struct file * filp, void *buffer, size_t *lenp)
+{
+        int *valp = ctl->data;
+        int val = *valp;
+        int ret;
+
+        ret = proc_dointvec(ctl, write, filp, buffer, lenp);
+        if (write && (*valp != val))
+		fast_timer_set();
+        return ret;
+
+}
+
+static ctl_table dev_table[] = {
+	{2, "fast_timer",
+	 &fast_timer_rate, sizeof(int), 0644, NULL, &fast_timer_sysctl},
+	{0}
+};
+
+static ctl_table root_table[] = {
+	{CTL_DEV, "dev", NULL, 0, 0555, dev_table},
+	{0}
+};
+
+static struct ctl_table_header *sysctl_header;
+
+static void __init init_sysctl(void)
+{
+	sysctl_header = register_sysctl_table(root_table, 0);
+}
+
+static void __exit cleanup_sysctl(void)
+{
+	unregister_sysctl_table(sysctl_header);
+}
+
+#else
+
+static inline void init_sysctl(void)
+{
+}
+
+static inline void cleanup_sysctl(void)
+{
+}
+
+#endif
+
+static int __init fast_timer_init(void)
+{
+	int ret;
+
+	spin_lock_init(&fast_timer_lock);
+
+	ret = fast_timer_setup();
+	if (ret != 0)
+		return ret;
+
+	init_sysctl();
+	return 0;
+}
+
+static void __exit fast_timer_exit(void)
+{
+	cleanup_sysctl();
+	fast_timer_cleanup();
+}
+
+module_init(fast_timer_init);
+module_exit(fast_timer_exit);
+EXPORT_SYMBOL(fast_timer_add);
+EXPORT_SYMBOL(fast_timer_remove);
+MODULE_AUTHOR("Philip Craig <philipc@snapgear.com>");
+MODULE_DESCRIPTION("Driver for general purpose fast timer");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/drivers/char/gio_c5471.c linux-2.4.29-uc1/drivers/char/gio_c5471.c
--- linux-2.4.29/drivers/char/gio_c5471.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/gio_c5471.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,783 @@
+/************************************************************************
+ * linux/drivers/char/gio_c5471.c
+ *
+ *   Copyright (C) 2003 Cadenux, LLC. All rights reserved.
+ *   todd.fischer@cadenux.com  <www.cadenux.com>
+ *
+ *   Copyright (C) 2001 RidgeRun, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+/* Use versioning if needed */
+
+#include <linux/autoconf.h>
+
+#ifdef CONFIG_MODVERSIONS
+# undef MODVERSIONS
+# define MODVERSIONS
+#endif
+
+#ifdef MODVERSIONS
+#  include <linux/modversions.h>
+#endif
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+
+#include <linux/ioport.h>
+#include <asm/types.h>
+#include <asm/semaphore.h>
+#include <asm/segment.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/gio_ioctl.h>
+#include <asm/arch/sysdep.h>
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/* #undef GIO_DEBUG */
+/* #define GIO_DEBUG */
+
+#ifdef GIO_DEBUG
+# define dbg(format, arg...) \
+  printk(KERN_DEBUG __FUNCTION__ ": " format "\n" , ##arg)
+#else
+# define dbg(x...)
+#endif
+
+#define info(format, arg...) \
+  printk(KERN_INFO __FUNCTION__ ": " format "\n" , ##arg)
+#define err(format, arg...) \
+  printk(KERN_ERR __FUNCTION__ ": " format "\n" , ##arg)
+
+#define NUM_GIO_INTERRUPTS 4
+
+/************************************************************************
+ * Private Type Definitions
+ ************************************************************************/
+
+/* GIO Overlay. This data structure represents each element in the
+ * GIO registers.
+ */
+
+struct gio_s
+{
+  u32 io;
+  u32 cio;
+  u32 irqa;
+  u32 irqb;
+  u32 ddio;
+  u32 en;
+};
+typedef struct gio_s gio_t;
+
+/* Driver static data. */
+
+struct driver_struct
+{
+#ifdef DECLARE_WAITQUEUE
+  wait_queue_head_t  gio_waitq[NUM_GIO_INTERRUPTS];
+#else
+  struct wait_queue *gio_waitq[NUM_GIO_INTERRUPTS];
+#endif
+  char interrupt_occurred[NUM_GIO_INTERRUPTS];
+  char interrupt_requested[NUM_GIO_INTERRUPTS];
+  u64 driver_requested;	
+  u64 direction;
+  u32 interrupt;
+};
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+static int 
+gio_ioctl(struct inode *inode, struct file *filep,
+	  unsigned int cmd, unsigned long arg);
+
+static int
+gio_open(struct inode * inode, struct file * filep);
+
+#ifdef LINUX_20
+static void
+gio_release (struct inode *inode, struct file *filep);
+#else
+static int
+gio_release (struct inode *inode, struct file *filep);
+#endif /* LINUX_20 */
+
+#ifdef LINUX_20
+static int
+gio_read(struct inode *inode, struct file *filep, char *buf, int count);
+#else
+static ssize_t
+gio_read(struct file *filep, char *buf, size_t count, loff_t *f_pos);
+#endif /* LINUX_20 */
+
+static void
+gio_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+/************************************************************************
+ * Private Variable Data
+ ************************************************************************/
+
+static struct driver_struct gio;
+static gio_t *pGIO = (gio_t *)GIO_REGISTER_BASE;
+static gio_t *pKGIO = (gio_t *)KGIO_REGISTER_BASE;
+
+/* Device File Operations */
+
+static struct file_operations gio_fops =
+{
+  ioctl:     gio_ioctl,         /* ioctl */
+  open:      gio_open,          /* open code */
+  release:   gio_release,       /* close code */
+  read:      gio_read,          /* Wait-for-interrupt code */
+};
+
+/* Give other modules access to the GIO ioctl calls without having to
+ * search for the GIO module.
+ */
+
+#ifdef MODULE
+struct file_operations *gio_get_fileops(void);
+#ifdef __USE_OLD_SYMTAB__
+static struct symbol_table gio_symbol_table =
+{
+# include <linux/symtab_begin.h>
+  X(gio_get_fileops),
+# include <linux/symtab_end.h>
+};
+#else
+EXPORT_SYMBOL(gio_get_fileops);
+#endif
+#endif
+
+/************************************************************************
+ * Private Constant Data
+ ************************************************************************/
+
+static const char *int_names[] =
+{
+  "gio0", "gio1", "gio2", "gio3", "gio4", "gio5", "gio6", "gio7"
+};
+
+static const char desc[] = "GIO driver";
+static const char author[] = "Copyright 2003 Cadenux, LLC";
+
+/************************************************************************
+ * Inline Functions
+ ************************************************************************/
+
+static inline int gio_2_irq_num(int val)
+{
+  switch (val)
+    {
+    case 0: return  3; break;
+    case 1: return 12; break;
+    case 2: return 10; break;
+    case 3: return  9; break;
+    default: return -1;
+    }
+}
+
+static inline int irq_2_gio_num(int val)
+{
+  switch (val)
+    {
+    case 3:  return 0; break;
+    case 9:  return 3; break;
+    case 10: return 2; break;
+    case 12: return 1; break;
+    default: return -1;
+    }
+}
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * gio_ioctl
+ ************************************************************************/
+
+static int
+gio_ioctl (struct inode *inode, struct file *filep,
+	   unsigned int cmd, unsigned long arg)
+{
+  u32       *reg;
+  u32        value;
+  int        err     = 0;
+  int        pin = MINOR(inode->i_rdev);
+  signed int size    = _IOC_SIZE(cmd);
+
+  dbg("cmd=0x%x arg=0x%lx", cmd, arg);
+    
+  /* Range check the IOCTL cmd */
+
+  if ((_IOC_TYPE(cmd) != GIO_MAGIC_NUMBER) ||
+      (_IOC_NR(cmd) > GIO_IOC_MAXNR)) 
+    {
+      dbg("Bad ioctl value");
+      return -EINVAL;
+    }
+
+  /* Check address validity */
+
+  if (_IOC_DIR(cmd) & _IOC_READ)
+    {
+      err = verify_area(VERIFY_READ, (void*)arg, size);
+        
+      if (err)
+	dbg("verify_area(VERIFY_READ) error:%d", err);
+    } 
+  else if (_IOC_DIR(cmd) & _IOC_WRITE) 
+    {
+      err = verify_area(VERIFY_WRITE, (void*)arg, size);
+          
+      if (err)
+	dbg("verify_area(VERIFY_WRITE) error:%d", err);
+    }
+
+  if (err) 
+    {
+      return err;
+    }
+
+  /* Command processing */
+
+  switch (cmd) 
+    {
+      /******************************************************************
+       * GIO_DIRECTION: The GIO_DIRECTION can be either input (GIO_INPUT) or
+       * output (GIO_OUTPUT).  If unspecified, the GIO will default to input.
+       */
+
+    case GIO_DIRECTION:
+      {
+        dbg("GIO_DIRECTION: pin=%d arg=%ld", pin, arg);
+
+        /* Pins 0-19 are controlled by bits in GIO; pins 20-35 are
+         * controlled by bits in KGIO.
+         */
+
+	if (pin > 19)
+	  {
+	    reg = &pKGIO->cio;
+	    value = pin - 20;
+	  }
+	else
+	  {
+	    reg = &pGIO->cio;
+	    value = pin;
+	  }
+
+        /* Set or clear the direction bit associated with the pin */
+
+	if (arg)
+	  {
+	    *reg |= (1 << value);
+	    gio.direction |= (1 << pin);
+	  }
+	else
+	  {
+	    *reg &= ~(1 << value);
+	    gio.direction &= ~(1 << pin);
+	  }
+      }
+      break;
+
+      /******************************************************************
+       * GIO_BITSET: If the direction is set to output, this ioctl will
+       * set the output.  If the direction is input, this ioctl will
+       * return the value of the GIO pin (0, 1, or -1 on error).
+       */
+
+    case GIO_BITSET:
+      {
+	dbg("GIO_BITSET: pin=%d arg=%ld", pin, arg);
+
+        /* Check if the pin has been programmed as an interrupt:  We
+         * will not set a bit on an interrupt pin.
+         */
+
+	if (gio.interrupt & (1 << pin))
+	  {
+	    dbg("pin %d is programmed for interrupt", pin);
+	    return -EINVAL;
+	  }
+
+	if (gio.direction & (1 << pin))
+	  {
+            /* Pin is programmed for input */
+
+            /* Input state for pins 0-19 is provided in GIO; pin
+             * 20-35 state is provided in KGIO.
+             */
+
+	    if (pin > 19)
+	      {
+                /* If the pin is set, return "1" otherwise the
+                 * default behavior for this ioctl is to return
+                 * zero.
+                 */
+
+		if (pKGIO->io & (1 << (pin - 20)))
+		  {
+		    return 1;
+		  }
+	      }
+	    else
+	      {
+                /* If the pin is set, return "1" otherwise the
+                 * default behavior for this ioctl is to return
+                 * zero.
+                 */
+
+		if (pGIO->io & (1 << pin)) {
+		  return 1;
+		}
+	      }
+	  }
+	else
+	  {
+            /* Pin is programmed for output */
+
+            /* Output state for pins 0-19 is controlled in GIO; pin
+             * 20-35 state is controlled in KGIO.
+             */
+
+	    if (pin > 19)
+	      {
+		pKGIO->io |= (1 << (pin - 20));
+	      }
+	    else
+	      {
+		pGIO->io |= (1 << pin);
+	      }
+	  }
+      }
+      break;
+
+      /******************************************************************
+       * GIO_BITCLR: If the direction is set to output, this ioctl will
+       * clear the output.  If the direction is input, this ioctl will
+       * return the value of the GIO pin (0, 1, or -1 on error).
+       */
+
+    case GIO_BITCLR:
+      {
+        dbg("GIO_BITCLR: pin=%d arg=%ld", pin, arg);
+
+        /* Check if the pin has been programmed as an interrupt:  We
+         * will not clear a bit on an interrupt pin.
+         */
+
+	if (gio.interrupt & (1 << pin))
+	  {
+            dbg("pin %d is programmed for interrupt", pin);
+	    return -EINVAL;
+	  }
+
+	if (gio.direction & (1 << pin))
+	  {
+            /* Pin is programmed for input */
+
+            /* Input state for pins 0-19 is provided in GIO; pin
+             * 16-31 state is provided in KGIO.
+             */
+
+	    if (pin > 19)
+	      {
+                /* If the pin is set, return "1" otherwise the
+                 * default behavior for this ioctl is to return
+                 * zero.
+                 */
+
+		if (pKGIO->io & (1 << (pin - 20)))
+		  {
+		    return 1;
+		  }
+	      }
+	    else
+	      {
+                /* If the pin is set, return "1" otherwise the
+                 * default behavior for this ioctl is to return
+                 * zero.
+                 */
+
+		if (pGIO->io & (1 << pin))
+		  {
+		    return 1;
+		  }
+	      }
+	  }
+	else
+	  {
+            /* Pin is programmed for output */
+
+            /* Output state for pins 0-19 is controlled in GIO; pin
+             * 16-31 state is controlled in KGIO.
+             */
+
+	    if (pin > 19)
+	      {
+		pKGIO->io &= ~(1 << (pin - 20));
+	      }
+	    else
+	      {
+		pGIO->io &= ~(1 << pin);
+	      }
+	  }
+      }
+      break;
+
+      /******************************************************************
+       * GIO_IRQPORT: Configure a GIO as an interrupt.  Only GIO0-GIO3 can
+       * be configured as an interrupting source.
+       */
+
+    case GIO_IRQPORT:
+      {
+        dbg("GIO_IRQPORT: pin=%d arg=%ld", pin, arg);
+
+        /* Verify that pin corresponds to one of GIO0-GIO3. */
+
+	if (pin >= NUM_GIO_INTERRUPTS)
+	  {
+            dbg("pin=%d will not support interrupts", pin);
+	    return -EINVAL;
+	  }
+
+        /* 0=detach from interrupt; 1=attach to interrupt */
+
+	if (arg)
+	  {
+	    /* Attach to interrupt if it hasn't been done yet. */
+
+	    if ((gio.interrupt & (1 << pin)) == 0)
+	      {
+		/* No, ... then do so now. */
+
+		if (request_irq(gio_2_irq_num(pin), &gio_interrupt, 
+				SA_INTERRUPT, int_names[pin], 
+				&gio_interrupt))
+		  {
+		    err("unable to get IRQ%d for the GIO driver",
+			(int)pin);
+		    return -1;
+		  }
+		else
+		  {
+		    dbg("Attached to IRQ%d", pin);
+		    gio.interrupt |= (1 << pin);
+		  }                    
+	      }
+	    else
+	      {
+		dbg("IRQ%d already attached", pin);
+	      }                    
+	  }
+	else
+	  {
+	    /* Detach from interrupt. */
+
+	    if ((gio.interrupt & (1 << pin)) != 0)
+	      {
+		free_irq(gio_2_irq_num(pin), &gio_interrupt);
+		gio.interrupt &= ~(1 << pin);    
+	      }
+            else
+              {
+                dbg("IRQ%d already detached", pin);
+              }
+	  }
+
+	/* Then make it so */
+
+	pGIO->irqa = pGIO->irqb = gio.interrupt;
+      }
+      break;
+
+    default:
+      dbg("Error, falling through switch");
+      return -EINVAL;
+      break;
+    }
+  return 0;
+}
+
+/************************************************************************
+ * gio_open
+ ************************************************************************/
+
+static int gio_open(struct inode * inode, struct file * filep)
+{
+  int pin = MINOR(inode->i_rdev);
+
+  dbg("pin=%d", pin);
+
+  /* Verify that the GIO pin number is within the range of those supported
+   * by this driver.
+   */
+
+  if (pin > MAX_GIO)
+    {
+      dbg("Bad minor (pin) %d", pin);
+      return -EACCES;
+    }
+
+  /* Initialized the file structure */
+    
+  filep->private_data = 0;
+  filep->f_pos        = 0;
+
+  /* Check if this GIO has already been opened.  Sorry only one per
+   * customer.
+   */
+
+  if (gio.driver_requested & (1 << pin))
+    {
+      err("GIO%d already opened", pin);
+      return -EACCES;
+    }
+
+  /* Mark the driver as open */
+
+  gio.driver_requested |= (1 << pin);
+  MOD_INC_USE_COUNT;
+
+  return 0;
+}
+
+/************************************************************************
+ * gio_read
+ ************************************************************************/
+
+#ifdef LINUX_20
+static void
+gio_release (struct inode *inode, struct file *filep)
+#else
+static int
+gio_release (struct inode *inode, struct file *filep)
+#endif /* LINUX_20 */
+{
+  int pin = MINOR(inode->i_rdev);
+
+  dbg("Closing inode %p, filep %p", inode, filep);
+
+  /* Restore default pin settings */
+
+  (void)gio_ioctl(inode, filep, GIO_DIRECTION, GIO_INPUT);
+  (void)gio_ioctl(inode, filep, GIO_IRQPORT,   GIO_NOINTERRUPT);
+
+  /* And mark the GIO un-opened */
+
+  gio.driver_requested &= ~(1 << pin);
+
+  MOD_DEC_USE_COUNT;
+
+#ifndef LINUX_20
+  return 0;
+#endif /* LINUX_20 */
+}
+
+/************************************************************************
+ * gio_read
+ ************************************************************************/
+
+#ifdef LINUX_20
+static int
+gio_read(struct inode *inode, struct file *filep, char *buf, int count)
+#else
+static ssize_t
+gio_read(struct file *filep, char *buf, size_t count, loff_t *f_pos)
+#endif /* LINUX_20 */
+{
+#ifdef LINUX_20
+  int pin = MINOR(inode->i_rdev);
+#else
+  int pin = MINOR(filep->f_dentry->d_inode->i_rdev);
+#endif /* LINUX_20 */
+  int flags;
+
+  dbg("Reading pin %d", pin);
+
+  /* Make sure that this pin has been programmed for interrupts.
+   * If not, we'll return success immediately.
+   */
+
+  if ((gio.interrupt & (1 << pin)) != 0)
+    {
+      /* If the open flag was noblock and there's no data, return -EAGAIN.
+       * Implementation from Rubini, Blocking I/O, modified with save flags
+       * because we're checking a static that is modified in a ISR, and we're
+       * placing ourselves onto a wait queue that's checked in an ISR.
+       */
+
+      save_flags(flags); cli();
+
+      /* Loop until we receive an interrupt on this pin. */
+
+      while (gio.interrupt_occurred[pin] == 0)
+	{
+          /* If the open flag was O_NONBLOCK and and no interrupt has been
+           * received, return -EAGAIN.
+           */
+
+	  if (filep->f_flags & O_NONBLOCK)
+	    {
+	      restore_flags(flags);
+              dbg("Returing -EAGAIN");
+	      return -EAGAIN;
+	    }
+
+          dbg("%s waiting on timer queue for GIO%d", current->comm, pin);
+	  interruptible_sleep_on(&gio.gio_waitq[pin]);
+          dbg("%s awakened from timer queue for GIO%d", current->comm, pin);
+
+          /* Check signals */
+
+#ifdef LINUX_20
+          if (current->signal & ~current->blocked)
+#else
+          if (signal_pending(current))
+#endif /* LINUX_20 */
+	    {
+              dbg("Returing -EINTR");
+	      return -EINTR;
+	    }
+	  cli();
+	}
+      restore_flags(flags);
+
+      /* Indicate that the interrupt has been received and processed. */
+
+      gio.interrupt_occurred[pin] = 0;
+    }
+  return 0;
+}
+
+/************************************************************************
+ * gio_read
+ ************************************************************************/
+
+static void gio_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+  int pin;
+
+  dbg("irq%d received", irq);
+
+  /* irq_2_gio_num translates the received irq to 0-3 for
+   * both platforms.
+   */
+
+  pin = irq_2_gio_num(irq);
+  if (pin >= 0)
+    {
+      gio.interrupt_occurred[pin] = 1;
+      wake_up_interruptible(&gio.gio_waitq[pin]);
+    }
+}
+
+/************************************************************************
+ * Global Functions
+ ************************************************************************/
+
+struct file_operations *gio_get_fileops(void)
+{
+  return &gio_fops;
+}
+
+#ifdef MODULE
+int init_module(void)
+#else
+int gio_c5471_init(void)
+#endif
+{
+  /* Basic initialization of device nodes. */
+
+  printk("%s module %s\n", desc, author);
+
+  if (register_chrdev(GIO_MAJOR, "gio", &gio_fops) != 0)
+    {
+      info("GIO: can't get major number %d", GIO_MAJOR);
+      return -1;
+    }
+  else
+    {
+      dbg("GIO major number : %d", GIO_MAJOR);
+    }
+
+  request_region((unsigned int)pGIO,sizeof(gio_t),"gio");
+  request_region((unsigned int)pKGIO,sizeof(gio_t),"gio");
+
+  /* Set all pins as input pins */
+
+  pGIO->cio  = 0x000fffff;
+  pKGIO->cio = 0x000fffff;
+
+  /* Non-interrupting */
+
+  pGIO->irqa  = 0;
+  pGIO->irqb  = 0;
+  pKGIO->irqa = 0;
+  pKGIO->irqb = 0;
+
+  /* Set delta detect registers */
+
+  pGIO->ddio  = 0;
+  pKGIO->ddio = 0;
+
+  /* Non-muxed output */
+
+  pGIO->en  = 0x0;
+  pKGIO->en = 0x0;
+
+#ifdef MODULE
+  REGISTER_SYMTAB(&gio_syms);
+#endif
+
+  return 0;
+}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+  unregister_chrdev(GIO_MAJOR, "gio");
+  release_region((unsigned int)pGIO, sizeof(gio_t));
+  release_region((unsigned int)pKGIO, sizeof(gio_t));
+}
+#endif
diff -urN linux-2.4.29/drivers/char/idetest.c linux-2.4.29-uc1/drivers/char/idetest.c
--- linux-2.4.29/drivers/char/idetest.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/idetest.c	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,308 @@
+/*****************************************************************************/
+/*
+ *	idetest.c -- A simple driver to exercise the SnapGear IDE test jig.
+ *
+ * 	(C) Copyright 2004, SnapGear <www.snapgear.com> 
+ *  Code used from EP93xx IDE Linux driver, (C) 2003 Cirrus Logic
+ */
+/*****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DPRINTK( fmt, arg... )  printk( fmt, ##arg )
+#else
+#define DPRINTK( fmt, arg... )
+#endif
+
+#define IDETEST_NAME	"idetest"
+#define IDETEST_MAJOR	122
+#define IDETEST_SIZE	16
+
+/*****************************************************************************/
+
+static int idetest_isopen;
+
+/*****************************************************************************/
+
+static void
+set_pio(void)
+{
+	DPRINTK("set_pio()\n");
+
+	/*
+	 * Clear the MDMA and UDMA operation registers.
+	 */
+	outl(0, IDEMDMAOP);
+	outl(0, IDEUDMAOP);
+
+	/*
+	 * Reset the UDMA state machine.
+	 */
+	outl(IDEUDMADebug_RWOE | IDEUDMADebug_RWPTR | IDEUDMADebug_RWDR |
+	     IDEUDMADebug_RROE | IDEUDMADebug_RRPTR | IDEUDMADebug_RRDR,
+	     IDEUDMADEBUG);
+	outl(0, IDEUDMADEBUG);
+
+	/*
+	 * Enable PIO mode of operation.
+	 */
+	outl(IDECfg_PIO | IDECfg_IDEEN | (4 << IDECfg_MODE_SHIFT) |
+	     (1 << IDECfg_WST_SHIFT), IDECFG);
+}
+
+/*****************************************************************************/
+
+static void
+ide_outb(u8 b, unsigned long addr)
+{
+	unsigned int uiIDECR;
+
+	/*
+	 * Write the address out.
+	 */
+	uiIDECR = IDECtrl_DIORn | IDECtrl_DIOWn |
+		((addr & 7) << 2)/* | (addr >> 10)*/;
+		
+	if (addr & 8)
+		uiIDECR |= IDECtrl_CS0n;
+	else
+		uiIDECR |= IDECtrl_CS1n;
+
+	DPRINTK("%s: addr %lx uiIDECR %lx ", __FUNCTION__, addr, uiIDECR);
+	outl(uiIDECR, IDECR);
+
+	DPRINTK("data %x\n", b);
+
+	/*
+	 * Write the data out.
+	 */
+
+	if (addr & 8)
+		outl(b << 8, IDEDATAOUT);
+	else
+		outl(b, IDEDATAOUT);
+
+	/*
+	 * Toggle the write signal.
+	 */
+	outl(uiIDECR & ~IDECtrl_DIOWn, IDECR);
+	outl(uiIDECR, IDECR);
+}
+
+/*****************************************************************************/
+
+static unsigned char
+ide_inb(unsigned long addr)
+{
+	unsigned int uiIDECR;
+	u8 b;
+
+	/*
+	 * Write the address out.
+	 */
+	uiIDECR = IDECtrl_DIORn | IDECtrl_DIOWn |
+		((addr & 7) << 2)/* | (addr >> 10)*/;
+
+	if (addr & 8)
+		uiIDECR |= IDECtrl_CS0n;
+	else
+		uiIDECR |= IDECtrl_CS1n;
+		
+	DPRINTK("%s: addr %lx uiIDECR %lx ", __FUNCTION__, addr, uiIDECR);
+	outl(uiIDECR, IDECR);
+
+	/*
+	 * Toggle the read signal.
+	 */
+	outl(uiIDECR & ~IDECtrl_DIORn, IDECR);
+	outl(uiIDECR, IDECR);
+
+	/*
+	 * Read the data in.
+	 */
+	if (addr & 8)
+		b = (inl(IDEDATAIN) >> 8) & 0xff;
+	else
+		b = inl(IDEDATAIN) & 0xff;
+
+	DPRINTK("data %x\n", b);
+	return b;
+}
+
+/*****************************************************************************/
+
+static int
+idetest_open(struct inode *inode, struct file *filp)
+{
+	DPRINTK("idetest_open()\n");
+
+	if (idetest_isopen)
+		return -EBUSY;
+
+	idetest_isopen++;
+
+	MOD_INC_USE_COUNT;
+
+	return 0;
+}
+
+/*****************************************************************************/
+
+static int
+idetest_close(struct inode *inode, struct file *filp)
+{
+	DPRINTK("idetest_close()\n");
+
+	idetest_isopen--;
+
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+/*****************************************************************************/
+
+static ssize_t
+idetest_write(struct file *filp, const char *buf, size_t count,loff_t *ppos)
+{
+	char p[IDETEST_SIZE];
+	int i;
+
+	DPRINTK("idetest_write(buf=%x,count=%d)\n",
+		(int) buf, count);
+
+	if (*ppos + count > IDETEST_SIZE)
+		return -ENOSPC;
+	copy_from_user(p, buf, count);
+	for (i=0; i<count; i++)
+		ide_outb(p[i], *ppos+i);
+	*ppos += i;
+
+	return i;
+}
+
+/*****************************************************************************/
+
+static ssize_t
+idetest_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
+{
+	char p[IDETEST_SIZE];
+	int i;
+
+	DPRINTK("idetest_read(buf=%x,count=%d)\n",
+		(int) buf, count);
+
+	if (*ppos + count > IDETEST_SIZE)
+		count = IDETEST_SIZE - *ppos;
+	for (i=0; i<count; i++)
+		p[i] = ide_inb(*ppos+i);
+	copy_to_user(buf, p, i);
+	*ppos += i;
+
+	return i;
+}
+
+/*****************************************************************************/
+
+static loff_t
+idetest_lseek(struct file * file, loff_t offset, int orig)
+{
+	loff_t newpos;
+	
+	switch (orig) {
+	case 0:
+		newpos = offset;
+		break;
+	case 1:
+		newpos = file->f_pos + offset;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (newpos<0 || newpos>=IDETEST_SIZE)
+		return -EINVAL;
+
+	file->f_pos = newpos;
+	return file->f_pos;
+}
+
+/*****************************************************************************/
+
+static int
+idetest_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	int rc = 0;
+
+	DPRINTK("idetest_ioctl(cmd=%x,arg=%x)\n", (int) cmd, (int) arg);
+
+	switch(cmd) {
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+/*****************************************************************************/
+
+static struct file_operations idetest_fops = {
+	llseek: idetest_lseek,
+	read: idetest_read,
+	write: idetest_write,
+	ioctl: idetest_ioctl,
+	open: idetest_open,
+	release: idetest_close
+};
+
+/*****************************************************************************/
+
+static const char banner[] __initdata =
+    KERN_INFO IDETEST_NAME ": Copyright (C) 2004, SnapGear " \
+	"(www.snapgear.com)\n";
+
+static int __init idetest_init(void)
+{
+	DPRINTK("idetest_init()\n");
+
+	set_pio();
+
+	/* Register character device */
+	if (register_chrdev(IDETEST_MAJOR, IDETEST_NAME, &idetest_fops) < 0) {
+		printk(KERN_WARNING IDETEST_NAME": failed to allocate major %d\n",
+			IDETEST_MAJOR);
+		return -1;
+	}
+
+	idetest_isopen = 0;
+	printk(banner);
+
+	return 0;
+}
+
+/*****************************************************************************/
+
+static void __exit idetest_exit(void)
+{
+	unregister_chrdev(IDETEST_MAJOR, IDETEST_NAME);
+}
+
+/*****************************************************************************/
+
+module_init(idetest_init);
+module_exit(idetest_exit);
+MODULE_AUTHOR("Philip Craig <philipc@snapgear.com>, Robert Waldie <robertw@snapgear.com>");
+MODULE_DESCRIPTION("A simple driver to exercise the SnapGear IDE test jig");
+MODULE_LICENSE("GPL");
+
+/*****************************************************************************/
diff -urN linux-2.4.29/drivers/char/lcdtxt.c linux-2.4.29-uc1/drivers/char/lcdtxt.c
--- linux-2.4.29/drivers/char/lcdtxt.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/lcdtxt.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,554 @@
+/*****************************************************************************/
+
+/*
+ *	lcdtxt.c -- driver for a text based LCD displays
+ *
+ *	(C) Copyright 2000-2002, Greg Ungerer (gerg@snapgear.com)
+ *	(C) Copyright 2000-2001, Lineo Inc. (www.lineo.com) 
+ */
+
+/*****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <asm/param.h>
+#include <asm/uaccess.h>
+
+/*****************************************************************************/
+
+/*
+ *	Define driver major number.
+ */
+#define	LCDTXT_MAJOR	120
+
+int		lcdtxt_line;
+int		lcdtxt_pos;
+
+#if LINUX_VERSION_CODE < 0x020100
+#define GET_USER(a,b)   a = get_user(b)
+#else
+#include <asm/uaccess.h>
+#define GET_USER(a,b)   get_user(a,b)
+#endif
+
+/*****************************************************************************/
+
+/*
+ *	Define normal text LCD control commands.
+ */
+#define	LCDTXT_CLEAR		0x01		/* Clear all of LCD display */
+#define	LCDTXT_RETURN		0x02		/* Cursor to start of line */
+
+#define	LCDTXT_MODE		0x04		/* Mode command */
+#define	LCDTXT_MODE_INCR	0x02		/* Increment cursor on data */
+#define	LCDTXT_MODE_DECR	0x00		/* Decrement cursor on data */
+#define	LCDTXT_MODE_SHIFT	0x01		/* Display shift when full */
+#define	LCDTXT_MODE_NOSHIFT	0x00		/* No display shift */
+
+#define	LCDTXT_DISP		0x08		/* Display command */
+#define	LCDTXT_DISP_ON		0x04		/* Turn display on */
+#define	LCDTXT_DISP_OFF		0x00		/* Turn display off */
+#define	LCDTXT_DISP_CUR_ON	0x02		/* Turn cursor on */
+#define	LCDTXT_DISP_CUR_OFF	0x00		/* Turn cursor off */
+#define	LCDTXT_DISP_BLNK_ON	0x01		/* Blinking cursor on */
+#define	LCDTXT_DISP_BLNK_OFF	0x00		/* Blinking cursor off */
+
+#define	LCDTXT_SHIFT		0x10		/* SHift command */
+#define	LCDTXT_SHIFT_CUR	0x00		/* Cursor shift */
+#define	LCDTXT_SHIFT_DISP	0x08		/* Display shift */
+#define	LCDTXT_SHIFT_RIGHT	0x04		/* Right shift */
+#define	LCDTXT_SHIFT_LEFT	0x00		/* Left shift */
+
+#define	LCDTXT_FUNC		0x20		/* Function command */
+#define	LCDTXT_FUNC_4BIT	0x00		/* 4 bit data bus */
+#define	LCDTXT_FUNC_8BIT	0x10		/* 8 bit data bus */
+#define	LCDTXT_FUNC_1LINE	0x00		/* 1 line display */
+#define	LCDTXT_FUNC_2LINE	0x08		/* 2 line display */
+#define	LCDTXT_FUNC_FONT	0x00		/* Standard font */
+
+/*****************************************************************************/
+#if defined(CONFIG_SECUREEDGEMP3)
+/*****************************************************************************/
+
+/*
+ *	Hardware specifics for LCD on the LINEOMP3 board.
+ *	This is a 16 character by 2 line device.
+ */
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+/* LCD display specifics */
+#define	LCDTXT_LINENUM		2
+#define	LCDTXT_LINELENGTH	16
+#define LCDTXT_TABSTOP		8
+
+/* LCD addressing info */
+#define	LCDTXT_ADDR	0x30400000
+static volatile unsigned char	*lcdp = (volatile unsigned char *) LCDTXT_ADDR;
+static volatile unsigned short	*pp = (volatile unsigned short *)
+					(MCF_MBAR + MCFSIM_PADAT);
+
+/*
+ *	LCD initial hardware setup.
+ */
+#define	lcdtxt_hwsetup()
+
+/*
+ *	LCD access functions.
+ */
+static void lcdtxt_writectrl(unsigned char ctrl)
+{
+	*pp &= ~0x0100;
+	lcdp[0] = ctrl;
+	lcdp[1] = 0;	/* Latch data */
+	udelay(40);
+}
+
+static void lcdtxt_writedata(unsigned char val)
+{
+	*pp |= 0x0100;
+	lcdp[0] = val;
+	lcdp[1] = 0;	/* Latch data */
+	udelay(40);
+}
+
+/*****************************************************************************/
+#elif defined(CONFIG_eLIA)
+/*****************************************************************************/
+
+/*
+ *	Hardware specifics for LCD on the eLIA board.
+ *	This is a 2 line by 16 character LCD display device.
+ */
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+/* LCD display specifics */
+#define	LCDTXT_LINENUM		2
+#define	LCDTXT_LINELENGTH	16
+
+/* LCD addressing info */
+#define	LCDTXT_ADDR	0x30800000
+static volatile unsigned char	*lcdp = (volatile unsigned char *) LCDTXT_ADDR;
+
+/*
+ *	LCD initial hardware setup.
+ */
+static void lcdtxt_hwsetiup(void)
+{
+	/* Setup CS4 for our external hardware */
+	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_CSAR4)) = 0x3080;
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_CSMR4)) = 0x000f0001;
+	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_CSCR4)) = 0x3d40;
+	udelay(50000);
+}
+
+/*
+ *	LCD access functions.
+ */
+static void lcdtxt_writectrl(unsigend char ctrl)
+{
+	lcdp[0] = ctrl;
+	udelay(5000);
+}
+
+static unsigned char lcdtxt_readctrl(void)
+{
+	return(lcdp[0]);
+}
+
+static void lcdtxt_writedata(unsigend char val)
+{
+	lcdp[1] = val;
+	udelay(2000);
+}
+
+/*****************************************************************************/
+#else /* UNKNOWN HARDWARE */
+/*****************************************************************************/
+
+#error "LCDTXT: I don't know what hardware address to use?"
+
+#endif
+/*****************************************************************************/
+
+int lcdtxt_open(struct inode *inode, struct file *filp)
+{
+#if LCDTXT_DEBUG
+	printk("lcdtxt_open()\n");
+#endif
+	return(0);
+}
+
+/*****************************************************************************/
+
+int lcdtxt_release(struct inode *inode, struct file *filp)
+{
+#if LCDTXT_DEBUG
+	printk("lcdtxt_close()\n");
+#endif
+	return 0;
+}
+
+/*****************************************************************************/
+
+void lcdtxt_resetposn(void)
+{
+	lcdtxt_writectrl(0x80 | (lcdtxt_line ? 0x40 : 0x00) | lcdtxt_pos);
+}
+
+/*****************************************************************************/
+
+/* 
+ * scroll buffer size
+ */
+#define SCROLL_SIZE	60
+
+static struct timer_list scroll_timer;
+
+/*
+ *	Local copy of command settings of LCD.
+ */
+unsigned char	lcdtxt_disp;
+unsigned char	lcdtxt_mode;
+unsigned char 	scroll_buff[LCDTXT_LINENUM][SCROLL_SIZE];
+
+int scroll_pos = 0;
+int scroll_dir = 1;
+int scroll_buff_line = 1;
+int scrolling = 0;
+
+/*****************************************************************************/
+
+/*
+ *	Magic super scroll function.
+ */
+
+static void scroll_text(void)
+{
+	int i, j;
+	int larger, smaller;
+
+	del_timer(&scroll_timer);
+		
+	i = strlen(scroll_buff[0]);
+	larger = strlen(scroll_buff[1]);
+	if (i > larger) {
+		smaller = larger;
+		larger = i;
+	} else {
+		smaller = i;
+	}
+
+	if (scroll_dir == 1) {
+		if ((scroll_pos + LCDTXT_LINELENGTH) >= larger) {
+			scroll_dir = -1;
+		}
+	} else {
+		if (scroll_pos <= 0) {
+			scroll_dir = 1;
+		}
+	}
+
+	scroll_pos += scroll_dir;
+	if (scroll_pos < 0)
+		scroll_pos = 0;
+
+	for (j = 0; j < LCDTXT_LINENUM ; j++) {
+		if (strlen(scroll_buff[j]+scroll_pos) < LCDTXT_LINELENGTH) {
+				lcdtxt_pos = strlen(scroll_buff[j]);
+				lcdtxt_line = j;
+				lcdtxt_resetposn();
+				continue;
+		} else {
+			lcdtxt_line = j;
+			lcdtxt_pos = 0;
+			lcdtxt_resetposn();
+		}
+		for (i = scroll_pos; i < (scroll_pos + LCDTXT_LINELENGTH); i++) { 
+			if (scroll_buff[j][i] != 0) {
+				lcdtxt_writedata(scroll_buff[j][i]);
+				lcdtxt_pos++;
+			}
+		}
+	}
+	if (larger <= LCDTXT_LINELENGTH) {
+#if LCDTXT_DEBUG
+		printk("lcdtxt: disabling autoscroll\n");
+#endif
+		del_timer(&scroll_timer);
+	} else {
+		scroll_timer.expires = jiffies + HZ;
+		add_timer(&scroll_timer);
+	}
+}
+
+/*****************************************************************************/
+
+void lcdtxt_ceol(void)
+{
+	int		i;
+
+#if LCDTXT_DEBUG
+	printk("lcdtxt_ceol()\n");
+#endif
+
+	for (i = lcdtxt_pos; i < LCDTXT_LINELENGTH; i++)
+		lcdtxt_writedata(' ');
+}
+
+/*****************************************************************************/
+
+ssize_t lcdtxt_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
+{
+	char	*dp, c;
+	int	num;
+
+	static unsigned char	 prog_need;
+	static unsigned char	 setpos;
+
+#if LCDTXT_DEBUG
+	printk("lcdtxt_write(buf=%x,count=%d)\n", (int) buf, count);
+#endif
+
+	del_timer(&scroll_timer);
+	dp = (char *) buf;
+
+	for (num = 0; (num < count); num++) {
+		GET_USER(c, dp++);
+
+		/* If we're programming a character skip normal processing */
+		if (prog_need != 0) {
+			lcdtxt_writedata(c & 0x3f);
+			if (--prog_need == 0)
+				lcdtxt_resetposn();
+			continue;
+		}
+
+		/*
+		 * Now are we setting the cursor position directly.
+		 * This code is a subset of the ioctl(fd, 3, ...) code
+		 * below.  It can be included inline in a character stream
+		 * but addresses a smaller range of rows and columns.
+		 */
+		if (setpos) {
+			lcdtxt_pos = c & 0xf;
+			lcdtxt_line = (c >> 4) & 0xf;
+			setpos = 0;
+			lcdtxt_resetposn();
+			continue;
+		}
+		
+		/* Normal character */
+		switch ((unsigned char)c) {
+		case 0x1:	/* CTRL-A  -- toggle cursor "on/off" */
+			lcdtxt_disp ^= LCDTXT_DISP_CUR_ON;
+			lcdtxt_writectrl(lcdtxt_disp);
+			break;
+		case 0x2:	/* CTRL-B  -- toggle blinking curser */
+			lcdtxt_disp ^= LCDTXT_DISP_BLNK_ON;
+			lcdtxt_writectrl(lcdtxt_disp);
+			break;
+		case 0x3:	/* CTRL-C  -- home cursor no clear */
+			lcdtxt_writectrl(LCDTXT_RETURN);
+			lcdtxt_pos = 0;
+			lcdtxt_line = 0;
+			udelay(1560);		// The rest of the 1600 usec delay
+			break;
+		case 0x5:	/* CTRL-E  -- clear to end of line */
+			lcdtxt_ceol();
+			memset(scroll_buff[lcdtxt_line], '\0', SCROLL_SIZE);
+			lcdtxt_resetposn();
+			break;
+		case 0x6:	/* CTRL-F  -- advance curser 1 position */
+			lcdtxt_pos++;
+			lcdtxt_resetposn();
+			break;
+		case '\b':	/* CTRL-H -- step cursor back 1 position */
+			lcdtxt_pos--;
+			if(lcdtxt_pos < 0)
+				lcdtxt_pos = 0;
+			lcdtxt_resetposn();
+			break;
+		case '\t':	/* CTRL-I  -- tab to tabstop */
+			do {
+				lcdtxt_writedata(' ');
+				lcdtxt_pos++;
+			} while (lcdtxt_pos % LCDTXT_TABSTOP);
+			break;
+
+		case '\n':	/* CTRL-J  -- new line (no scroll) */
+			lcdtxt_ceol();
+			lcdtxt_pos = 0;
+		case '\v':	/* CTRL-K  -- vertical tab (change lines) */
+			lcdtxt_line = lcdtxt_line ? 0 : 1;
+			memset(scroll_buff[lcdtxt_line], '\0', SCROLL_SIZE);
+			lcdtxt_resetposn();
+			break;
+
+		case '\f':	/* CTRL-L  -- clear and home */
+			lcdtxt_writectrl(LCDTXT_CLEAR);
+			memset(scroll_buff[0], '\0', SCROLL_SIZE);
+			memset(scroll_buff[1], '\0', SCROLL_SIZE);
+			lcdtxt_line = 0;
+			lcdtxt_pos = 0;
+			scroll_pos = 0;
+			scroll_dir = 1;
+			udelay(1600);		// The rest of the 1640 usec delay
+			break;
+		case '\r':	/* CTRL-M  -- start of current line */
+			lcdtxt_pos = 0;
+			lcdtxt_resetposn();
+			break;
+		case 0x12:	/* CTRL-R  -- reset cursor: no blink, off */
+			lcdtxt_disp &= ~(LCDTXT_DISP_BLNK_ON | LCDTXT_DISP_CUR_ON);
+			lcdtxt_writectrl(lcdtxt_disp);
+			break;
+		case 0x1f:	/* ??????  -- set cursor x, y position */
+			setpos = 1;
+			break;
+		case 0x80 ... 0x8f:	/* CG RAM character */
+			lcdtxt_writedata(c & 0xf);
+			lcdtxt_pos++;
+			break;
+		case 0x90 ... 0x97:	/* Program CG RAM character */
+			prog_need = 8;
+			lcdtxt_writectrl(0x40 + (c & 7) * 8);
+			break;
+		default:
+			scroll_buff[lcdtxt_line][lcdtxt_pos] = c;
+			if (lcdtxt_pos <= LCDTXT_LINELENGTH)
+				lcdtxt_writedata(c);
+			lcdtxt_pos++;
+			break;
+		}
+	}
+	if ((scroll_buff[0][LCDTXT_LINELENGTH] || scroll_buff[1][LCDTXT_LINELENGTH])
+	    && scrolling == 1) {
+#if LCDTXT_DEBUG
+		printk("lcdtxt: engaging autoscroll\n");
+#endif
+		scroll_timer.expires = jiffies + HZ/2;
+		add_timer(&scroll_timer);
+	}
+
+	return(num);
+}
+
+/*****************************************************************************/
+
+int lcdtxt_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	int	rc = 0;
+
+	switch (cmd) {
+
+	case 1: /* turn scrolling on */
+#if LCDTXT_DEBUG
+		printk(KERN_INFO "lcdtxt:  scrolling enabled\n");
+#endif
+		scrolling = 1;
+		scroll_timer.expires = jiffies + HZ/2;
+		scroll_timer.function = (void *)scroll_text;
+		add_timer(&scroll_timer);
+		break;
+
+	case 2: /* turn scrolling off */
+#if LCDTXT_DEBUG
+		printk(KERN_INFO "lcdtxt:  scrolling disabled\n");
+#endif
+		scrolling = 0;
+		scroll_timer.function = NULL;
+		del_timer(&scroll_timer);
+		break;
+
+	case 3: /* Directly address X/Y cursor position */
+		/*
+		 * This ioctl is essentailly a duplication of the
+		 * 0x1f escape code code in the write routine.
+		 * This version allows a wider range of values to be set
+		 */
+		lcdtxt_pos = arg & 0xff;
+		lcdtxt_line = (arg >> 8) & 0xff;
+		lcdtxt_resetposn();
+		break;
+		
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return(rc);
+}
+
+/*****************************************************************************/
+
+/*
+ *	Exported file operations structure for driver...
+ */
+
+struct file_operations	lcdtxt_fops = {
+	write:		lcdtxt_write,	/* write */
+	ioctl:		lcdtxt_ioctl,	/* ioctl */
+	open:		lcdtxt_open,	/* open */
+	release:	lcdtxt_release,	/* release */
+};
+
+
+/*****************************************************************************/
+
+static int __init lcdtxt_init(void)
+{
+	int	rc;
+
+	/* Register lcdtxt as character device */
+	if ((rc = register_chrdev(LCDTXT_MAJOR, "lcdtxt", &lcdtxt_fops)) < 0) {
+		printk(KERN_WARNING "LCDTXT: can't get major %d\n",
+			LCDTXT_MAJOR);
+		return (-EBUSY);
+	}
+
+	printk("LCDTXT: Copyright (C) 2000-2001, Greg Ungerer "
+		"(gerg@snapgear.com)\n");
+
+	/* Hardware specific initialization */
+	lcdtxt_hwsetup();
+
+	/* Software copy of some commands */
+	lcdtxt_disp = LCDTXT_DISP | LCDTXT_DISP_ON;
+	lcdtxt_mode = LCDTXT_MODE | LCDTXT_MODE_INCR /*| LCDTXT_MODE_SHIFT*/;
+
+	/*
+	 *	Initialize the LCD controller.
+	 *	Some data sheets recommend doing the init write twice...
+	 */
+	lcdtxt_writectrl(LCDTXT_FUNC | LCDTXT_FUNC_8BIT | LCDTXT_FUNC_2LINE);
+	lcdtxt_writectrl(LCDTXT_FUNC | LCDTXT_FUNC_8BIT | LCDTXT_FUNC_2LINE);
+	lcdtxt_writectrl(lcdtxt_disp);
+	lcdtxt_writectrl(lcdtxt_mode);
+
+	/* Set initial character position and clear display */
+	lcdtxt_line = 0;
+	lcdtxt_pos = 0;
+	lcdtxt_writectrl(LCDTXT_CLEAR);
+
+	/* default is scrolling on */
+	scrolling = 1;
+	scroll_timer.expires = jiffies + HZ/2;
+	scroll_timer.function = (void *)scroll_text;
+	add_timer(&scroll_timer);
+
+	return 0;
+}
+
+module_init(lcdtxt_init);
+
+/*****************************************************************************/
diff -urN linux-2.4.29/drivers/char/ledman.c linux-2.4.29-uc1/drivers/char/ledman.c
--- linux-2.4.29/drivers/char/ledman.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/ledman.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,2368 @@
+/****************************************************************************/
+/*	vi:set tabstop=4 cindent shiftwidth=4:
+ *
+ *	ledman.c -- An LED manager,  primarily,  but not limited to SnapGear
+ *              devices manages up to 32 seperate LED at once.
+ *	            Copyright (C) Lineo, 2000-2001.
+ *	            Copyright (C) SnapGear, 2001-2003.
+ *
+ *	This driver currently supports 4 types of LED modes:
+ *
+ *	SET      - transient LED's that show activity,  cleared at next poll
+ *	ON       - always ON
+ *	OFF      - always OFF
+ *  FLASHING - a blinking LED with the frequency determined by the poll func
+ *
+ *	We have two sets of LED's to support non-standard LED usage without
+ *	losing previously/during use set of std values.
+ *
+ *	Hopefully for most cases, adding new HW with new LED patterns will be
+ *	as simple as adding two tables, a small function and an entry in
+ *	led_modes.  The tables being the map and the defaults while the
+ *	function is the XXX_set function.
+ *
+ *	You can, however, add your own functions for XXX_bits, XXX_tick and
+ *	take full control over all aspects of the LED's.
+ */
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/utsname.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/ledman.h>
+
+#if LINUX_VERSION_CODE < 0x020300
+#include <linux/malloc.h>
+#else
+#include <linux/slab.h>
+#endif
+
+#if LINUX_VERSION_CODE < 0x020100
+#define INIT_RET_TYPE	int
+#define Module_init(a)
+#elif LINUX_VERSION_CODE < 0x020300
+#include <linux/init.h>
+#define INIT_RET_TYPE	int
+#define Module_init(a)	module_init(a)
+#else
+#include <linux/init.h>
+#define INIT_RET_TYPE	static int __init
+#define Module_init(a)	module_init(a)
+#endif
+
+#if LINUX_VERSION_CODE < 0x020100
+#define Get_user(a,b)	a = get_user(b)
+#else
+#include <asm/uaccess.h>
+#define Get_user(a,b)	get_user(a,b)
+#endif
+
+#if LINUX_VERSION_CODE < 0x020100
+static struct symbol_table ledman_syms = {
+#include <linux/symtab_begin.h>
+	X(ledman_cmd),
+#include <linux/symtab_end.h>
+};
+#else
+EXPORT_SYMBOL(ledman_cmd);
+#endif
+
+/****************************************************************************/
+
+static void ledman_poll(unsigned long arg);
+static int  ledman_ioctl(struct inode * inode, struct file * file,
+								unsigned int cmd, unsigned long arg);
+#if !defined(CONFIG_SH_KEYWEST) && !defined(CONFIG_SH_BIGSUR)
+static int	ledman_bits(unsigned long cmd, unsigned long bits);
+static void	ledman_tick(void);
+#endif
+
+/****************************************************************************/
+
+static struct timer_list	ledman_timerlist;
+
+/****************************************************************************/
+
+struct file_operations ledman_fops = {
+	ioctl: ledman_ioctl,	/* ledman_ioctl */
+};
+
+/****************************************************************************/
+/*
+ *	some types to make adding new LED modes easier
+ *
+ *	First the elements for def array specifying default LED behaviour
+ */
+
+#define LEDS_SET	0
+#define LEDS_ON		1
+#define LEDS_OFF	2
+#define LEDS_FLASH	3
+#define LEDS_MAX	4
+
+typedef unsigned long leddef_t[LEDS_MAX];
+
+/*
+ *	A LED map is a mapping from numbers in ledman.h to one or more
+ *	physical LED bits.  Currently the typing limits us to 32 LED's
+ *	though this would not be hard to change.
+ */
+
+typedef unsigned long ledmap_t[LEDMAN_MAX];
+
+/*
+ *	A LED mode is a definition of how a set of LED's should behave.
+ *
+ *	name    - a symbolic name for the LED mode,  used for changing modes
+ *	map     - points to a ledmap array,  maps ledman.h defines to real LED bits
+ *	def     - default behaviour for the LED bits (ie, on, flashing ...)
+ *	bits    - perform command on physical bits,  you may use the default or
+ *	          supply your own for more control.
+ *	tick    - time based update of LED status,  used to clear SET LED's and
+ *	          also for flashing LED's
+ *	set     - set the real LED's to match the physical bits
+ *	jiffies - how many clock ticks between runs of the tick routine.
+ */
+
+
+typedef struct {
+	char	name[LEDMAN_MAX_NAME];
+	u_long	*map;
+	u_long	*def;
+	int		(*bits)(unsigned long cmd, unsigned long led);
+	void	(*tick)(void);
+	void	(*set)(unsigned long led);
+	int		jiffies;
+} ledmode_t;
+
+/****************************************************************************/
+
+static int current_mode = 0;				/* the default LED mode */
+static int initted = 0;
+
+/*
+ * We have two sets of LED's for transient operations like DHCP and so on
+ * index 0 is the standard LED's and index 1 is the ALTBIT LED's
+ */
+
+static unsigned long leds_alt, leds_alt_cnt[32];
+#if !defined(CONFIG_SH_KEYWEST) && !defined(CONFIG_SH_BIGSUR)
+static unsigned long leds_set[2];
+#endif
+static unsigned long leds_on[2], leds_off[2], leds_flash[2];
+
+static pid_t ledman_resetpid = -1;
+
+/****************************************************************************/
+
+/*
+ *	Let the system specific defining begin
+ */
+
+#if defined(CONFIG_M586)
+#define CONFIG_X86 1
+#endif
+
+#if defined(CONFIG_X86)
+#if defined(CONFIG_MTD_SNAPGEODE)
+#define	CONFIG_GEODE		1
+#else
+#define	CONFIG_AMDSC520		1
+#endif
+#if defined(CONFIG_SNAPGEAR)
+extern ledmap_t	nettel_old;
+extern leddef_t	nettel_def_old;
+#endif
+extern ledmap_t	nettel_std;
+extern leddef_t	nettel_def;
+static void nettel_set(unsigned long bits);
+static void ledman_initarch(void);
+#endif /* CONFIG_X86 */
+
+#if defined(CONFIG_NETtel) && defined(CONFIG_M5307)
+#ifdef ENTERASYS
+extern ledmap_t enterasys_std;
+extern leddef_t enterasys_def;
+#endif
+extern ledmap_t	nettel_old;
+extern ledmap_t	nettel_new;
+extern leddef_t	nettel_def;
+static void nettel_set(unsigned long bits);
+#endif
+
+#if defined(CONFIG_NETtel) && defined(CONFIG_M5272)
+extern ledmap_t	nt5272_std;
+extern leddef_t	nt5272_def;
+static void nt5272_set(unsigned long bits);
+#endif
+
+#if defined(CONFIG_SE1100)
+extern ledmap_t	se1100_std;
+extern leddef_t	se1100_def;
+static void se1100_set(unsigned long bits);
+#endif
+
+#if defined(CONFIG_GILBARCONAP) && defined(CONFIG_M5272)
+extern ledmap_t	nap5272_std;
+extern leddef_t	nap5272_def;
+static void nap5272_set(unsigned long bits);
+#endif
+
+#if defined(CONFIG_AVNET5282)
+extern ledmap_t	ads5282_std;
+extern leddef_t	ads5282_def;
+static void ads5282_set(unsigned long bits);
+#endif
+
+#if defined(CONFIG_SH_SECUREEDGE5410)
+extern ledmap_t	se5410_std;
+extern leddef_t	se5410_def;
+static void se5410_set(unsigned long bits);
+#endif
+
+#if defined(CONFIG_NETtel) && defined(CONFIG_M5206e)
+extern ledmap_t	nt1500_std;
+extern leddef_t	nt1500_def;
+static void nt1500_set(unsigned long bits);
+#endif
+
+#ifdef CONFIG_eLIA
+extern ledmap_t	elia_std;
+extern leddef_t	elia_def;
+static void elia_set(unsigned long bits);
+#endif
+
+#if defined(CONFIG_SH_KEYWEST) || defined(CONFIG_SH_BIGSUR)
+extern ledmap_t	keywest_std;
+extern leddef_t	keywest_def;
+static void keywest_set(unsigned long bits);
+static void ledman_initkeywest(void);
+static int	keywest_bits(unsigned long cmd, unsigned long bits);
+static void	keywest_tick(void);
+#endif
+
+#if defined(CONFIG_MACH_MONTEJADE) || defined(CONFIG_MACH_SE5100)
+extern ledmap_t	montejade_std;
+extern leddef_t	montejade_def;
+static void ledman_initarch(void);
+static void montejade_set(unsigned long bits);
+#endif
+
+#if defined(CONFIG_ARCH_SE4000) || defined(CONFIG_MACH_ESS710) || \
+    defined(CONFIG_MACH_SG560) || defined(CONFIG_MACH_SG580) || \
+	defined(CONFIG_MACH_SG565) || defined(CONFIG_MACH_SHIVA1100)
+extern ledmap_t	snapgear425_std;
+extern leddef_t	snapgear425_def;
+static void ledman_initarch(void);
+static void snapgear425_set(unsigned long bits);
+#endif
+
+#ifdef CONFIG_MACH_IVPN
+extern ledmap_t	ivpn_std;
+extern leddef_t	ivpn_def;
+static void ledman_initarch(void);
+static void ivpn_set(unsigned long bits);
+#endif
+
+#ifdef CONFIG_MACH_LITE300
+extern ledmap_t	lite3_std;
+extern leddef_t	lite3_def;
+static void ledman_initarch(void);
+static void lite3_set(unsigned long bits);
+#endif
+
+#ifdef CONFIG_MACH_CM4008
+extern ledmap_t	cm4008_std;
+extern leddef_t	cm4008_def;
+static void ledman_initarch(void);
+static void cm4008_set(unsigned long bits);
+#endif
+
+#ifdef CONFIG_MACH_CM41xx
+extern ledmap_t	cm41xx_std;
+extern leddef_t	cm41xx_def;
+static void ledman_initarch(void);
+static void cm41xx_set(unsigned long bits);
+#endif
+
+#ifdef CONFIG_ARCH_EP9312
+extern ledmap_t	ipd_std;
+extern leddef_t	ipd_def;
+static void ledman_initarch(void);
+static void ipd_set(unsigned long bits);
+#endif
+
+#ifdef CONFIG_BD_TIBURON
+extern ledmap_t	tiburon_std;
+extern leddef_t	tiburon_def;
+static void ledman_initarch(void);
+static void tiburon_set(unsigned long bits);
+static struct timer_list	release_tiburon_modemreset_timerlist;
+#endif
+
+/****************************************************************************/
+/****************************************************************************/
+
+#undef LT
+#define LT	(((HZ) + 99) / 100)
+
+/****************************************************************************/
+
+ledmode_t led_mode[] = {
+
+#ifdef ENTERASYS /* first in the list is the default */
+	{ "enterasys", enterasys_std, enterasys_def, ledman_bits, ledman_tick, nettel_set, LT },
+#endif
+
+#if defined(CONFIG_X86)
+	{ "std", nettel_std, nettel_def, ledman_bits, ledman_tick, nettel_set, LT },
+#if defined(CONFIG_SNAPGEAR)
+	{ "old", nettel_old, nettel_def_old, ledman_bits, ledman_tick, nettel_set, LT },
+#endif
+#endif
+
+#if defined(CONFIG_NETtel) && defined(CONFIG_M5307)
+	/*
+	 * by default the first entry is used.  You can select the old-style
+	 * LED patterns for acient boards with the command line parameter:
+	 *
+	 *      ledman=old
+	 */
+	{ "new", nettel_new, nettel_def, ledman_bits, ledman_tick, nettel_set, LT },
+	{ "old", nettel_old, nettel_def, ledman_bits, ledman_tick, nettel_set, LT },
+#endif
+
+#if defined(CONFIG_NETtel) && defined(CONFIG_M5272)
+	{ "std", nt5272_std, nt5272_def, ledman_bits, ledman_tick, nt5272_set, LT },
+#endif
+
+#if defined(CONFIG_NETtel) && defined(CONFIG_M5206e)
+	{ "std", nt1500_std, nt1500_def, ledman_bits, ledman_tick, nt1500_set, LT },
+#endif
+
+#if defined(CONFIG_SE1100)
+	{ "std", se1100_std, se1100_def, ledman_bits, ledman_tick, se1100_set, LT },
+#endif
+
+#if defined(CONFIG_GILBARCONAP) && defined(CONFIG_M5272)
+	{ "std", nap5272_std, nap5272_def, ledman_bits, ledman_tick, nap5272_set, LT },
+#endif
+
+#if defined(CONFIG_SH_SECUREEDGE5410)
+	{ "std", se5410_std, se5410_def, ledman_bits, ledman_tick, se5410_set, LT },
+#endif
+
+#ifdef CONFIG_eLIA
+	{ "std", elia_std, elia_def, ledman_bits, ledman_tick, elia_set, LT },
+#endif
+
+#if defined(CONFIG_SH_KEYWEST) || defined(CONFIG_SH_BIGSUR)
+	{ "std",keywest_std,keywest_def,keywest_bits,keywest_tick,keywest_set,HZ/10},
+#endif
+
+#if defined(CONFIG_MACH_MONTEJADE) || defined(CONFIG_MACH_SE5100)
+	{ "std",montejade_std,montejade_def,ledman_bits,ledman_tick,montejade_set,LT},
+#endif
+
+#if defined(CONFIG_ARCH_SE4000) || defined(CONFIG_MACH_ESS710) || \
+	defined(CONFIG_MACH_SG560) || defined(CONFIG_MACH_SG580) || \
+	defined(CONFIG_MACH_SG565) || defined(CONFIG_MACH_SHIVA1100)
+	{ "std",snapgear425_std,snapgear425_def,ledman_bits,ledman_tick,snapgear425_set,LT},
+#endif
+
+#ifdef CONFIG_MACH_IVPN
+	{ "std",ivpn_std,ivpn_def,ledman_bits,ledman_tick,ivpn_set,LT},
+#endif
+
+#if defined(CONFIG_MACH_LITE300)
+	{ "std",lite3_std,lite3_def,ledman_bits,ledman_tick,lite3_set,LT},
+#endif
+
+#if defined(CONFIG_MACH_CM4008)
+	{ "std",cm4008_std,cm4008_def,ledman_bits,ledman_tick,cm4008_set,LT},
+#endif
+
+#if defined(CONFIG_MACH_CM41xx)
+	{ "std",cm41xx_std,cm41xx_def,ledman_bits,ledman_tick,cm41xx_set,LT},
+#endif
+
+#if defined(CONFIG_ARCH_EP9312)
+	{ "std", ipd_std, ipd_def, ledman_bits, ledman_tick, ipd_set, LT},
+#endif
+
+#if defined(CONFIG_AVNET5282)
+	{ "std", ads5282_std, ads5282_def, ledman_bits, ledman_tick, ads5282_set, LT },
+#endif
+
+#ifdef CONFIG_BD_TIBURON
+	{ "std", tiburon_std, tiburon_def, ledman_bits, ledman_tick, tiburon_set, LT },
+#endif
+
+	{ "",  NULL, NULL, 0 }
+};
+
+/****************************************************************************/
+/*
+ *	boot arg processing ledman=mode
+ */
+
+#if LINUX_VERSION_CODE >= 0x020100
+__setup("ledman=", ledman_setup);
+#endif
+
+int
+ledman_setup(char *arg)
+{
+	ledman_cmd(LEDMAN_CMD_MODE, (unsigned long) arg);
+	return(0);
+}
+
+/****************************************************************************/
+/****************************************************************************/
+
+INIT_RET_TYPE ledman_init(void)
+{
+	printk(KERN_INFO "ledman: Copyright (C) SnapGear, 2000-2003.\n");
+
+	if (register_chrdev(LEDMAN_MAJOR, "nled",  &ledman_fops) < 0) {
+		printk("%s(%d): ledman_init() can't get Major %d\n",
+				__FILE__, __LINE__, LEDMAN_MAJOR);
+		return(-EBUSY);
+	} 
+
+#if defined(CONFIG_SH_KEYWEST) || defined(CONFIG_SH_BIGSUR)
+	ledman_initkeywest();
+#endif
+
+#if defined(CONFIG_X86) || defined(CONFIG_ARM)
+	ledman_initarch();
+#endif
+
+/*
+ *	set the LEDs up correctly at boot
+ */
+	ledman_cmd(LEDMAN_CMD_RESET, LEDMAN_ALL);
+/*
+ *	start the timer
+ */
+	if (led_mode[current_mode].tick)
+		ledman_timerlist.expires = jiffies + led_mode[current_mode].jiffies;
+	else
+		ledman_timerlist.expires = jiffies + HZ;
+	ledman_timerlist.function = ledman_poll;
+	ledman_timerlist.data = 0;
+	add_timer(&ledman_timerlist);
+
+#if LINUX_VERSION_CODE < 0x020100
+	register_symtab(&ledman_syms);
+#endif
+
+	initted = 1;
+	return 0;
+}
+
+Module_init(ledman_init);
+
+/****************************************************************************/
+
+void
+ledman_killtimer(void)
+{
+/*
+ *	stop the timer
+ */
+	del_timer(&ledman_timerlist);
+
+/*
+ *	set the LEDs up correctly at boot
+ */
+	ledman_cmd(LEDMAN_CMD_RESET, LEDMAN_ALL);
+}
+
+/****************************************************************************/
+
+void
+ledman_starttimer(void)
+{
+/*
+ *	stop the timer
+ */
+	add_timer(&ledman_timerlist);
+
+/*
+ *	set the LEDs up correctly at boot
+ */
+	ledman_cmd(LEDMAN_CMD_RESET, LEDMAN_ALL);
+}
+
+/****************************************************************************/
+
+static void
+ledman_poll(unsigned long arg)
+{
+	if (led_mode[current_mode].tick) {
+		(*led_mode[current_mode].tick)();
+		ledman_timerlist.expires = jiffies + led_mode[current_mode].jiffies;
+	} else
+		ledman_timerlist.expires = jiffies + HZ;
+	add_timer(&ledman_timerlist);
+}
+
+/****************************************************************************/
+
+static int
+ledman_ioctl(
+	struct inode * inode,
+	struct file * file,
+	unsigned int cmd,
+	unsigned long arg)
+{
+	char	mode[LEDMAN_MAX_NAME];
+	int		i;
+
+	if (cmd == LEDMAN_CMD_SIGNAL) {
+		ledman_resetpid = current->pid;
+		return(0);
+	}
+
+	if (cmd == LEDMAN_CMD_MODE) {
+		for (i = 0; i < sizeof(mode) - 1; i++) {
+			Get_user(mode[i], (char *) (arg + i));
+			if (!mode[i])
+				break;
+		}
+		mode[i] = '\0';
+		arg = (unsigned long) &mode[0];
+	}
+	return(ledman_cmd(cmd, arg));
+}
+
+/****************************************************************************/
+/*
+ *	cmd - from ledman.h
+ *	led - led code from ledman.h
+ *
+ *	check parameters and then call
+ */
+
+int
+ledman_cmd(int cmd, unsigned long led)
+{
+	ledmode_t	*lmp;
+	int			i;
+
+	switch (cmd & ~LEDMAN_CMD_ALTBIT) {
+	case LEDMAN_CMD_SET:
+	case LEDMAN_CMD_ON:
+	case LEDMAN_CMD_OFF:
+	case LEDMAN_CMD_FLASH:
+	case LEDMAN_CMD_RESET:
+	case LEDMAN_CMD_ALT_ON:
+	case LEDMAN_CMD_ALT_OFF:
+		break;
+	case LEDMAN_CMD_STARTTIMER:
+		ledman_starttimer();
+		return(0);
+	case LEDMAN_CMD_KILLTIMER:
+		ledman_killtimer();
+		return(0);
+	case LEDMAN_CMD_MODE:
+		for (i = 0; led_mode[i].name[0]; i++)
+			if (strcmp((char *) led, led_mode[i].name) == 0) {
+				current_mode = i;
+				if (initted)
+					ledman_cmd(LEDMAN_CMD_RESET, LEDMAN_ALL);
+				return(0);
+			}
+		return(-EINVAL);
+	default:
+		return(-EINVAL);
+	}
+
+	if (led < 0 || led >= LEDMAN_MAX)
+		return(-EINVAL);
+
+	lmp = &led_mode[current_mode];
+	(*lmp->bits)(cmd, lmp->map[led]);
+	return(0);
+}
+
+/****************************************************************************/
+/*
+ * Signal the reset pid, if we have one
+ */
+
+void
+ledman_signalreset()
+{
+	static unsigned long firstjiffies = 0;
+	if (ledman_resetpid == -1)
+		return;
+	if (jiffies > (firstjiffies + (HZ / 4))) {
+		firstjiffies = jiffies;
+		printk("LED: reset switch interrupt! (sending signal to pid=%d)\n",
+					ledman_resetpid);
+		kill_proc(ledman_resetpid, SIGUSR2, 1);
+	}
+}
+
+/****************************************************************************/
+#if !defined(CONFIG_SH_KEYWEST) && !defined(CONFIG_SH_BIGSUR)
+/****************************************************************************/
+
+static int
+ledman_bits(unsigned long cmd, unsigned long bits)
+{
+	ledmode_t		*lmp = &led_mode[current_mode];
+	int				 alt, i;
+	unsigned long	 new_alt;
+
+	alt = (cmd & LEDMAN_CMD_ALTBIT) ? 1 : 0;
+
+	switch (cmd & ~LEDMAN_CMD_ALTBIT) {
+	case LEDMAN_CMD_SET:
+		leds_set[alt]   |= bits;
+		break;
+	case LEDMAN_CMD_ON:
+		leds_on[alt]    |= bits;
+		leds_off[alt]   &= ~bits;
+		leds_flash[alt] &= ~bits;
+		(*lmp->tick)();
+		break;
+	case LEDMAN_CMD_OFF:
+		leds_on[alt]    &= ~bits;
+		leds_off[alt]   |= bits;
+		leds_flash[alt] &= ~bits;
+		(*lmp->tick)();
+		break;
+	case LEDMAN_CMD_FLASH:
+		leds_on[alt]    &= ~bits;
+		leds_off[alt]   &= ~bits;
+		leds_flash[alt] |= bits;
+		break;
+	case LEDMAN_CMD_RESET:
+		leds_set[alt]   = (leds_set[alt]  &~bits) | (bits&lmp->def[LEDS_SET]);
+		leds_on[alt]    = (leds_on[alt]   &~bits) | (bits&lmp->def[LEDS_ON]);
+		leds_off[alt]   = (leds_off[alt]  &~bits) | (bits&lmp->def[LEDS_OFF]);
+		leds_flash[alt] = (leds_flash[alt]&~bits) | (bits&lmp->def[LEDS_FLASH]);
+		break;
+	case LEDMAN_CMD_ALT_ON:
+		new_alt = (bits & ~leds_alt);
+		leds_alt |= bits;
+		/*
+		 * put any newly alt'd bits into a default state
+		 */
+		(*lmp->bits)(LEDMAN_CMD_RESET | LEDMAN_CMD_ALTBIT, new_alt);
+		for (i = 0; i < 32; i++)
+			if (bits & (1 << i))
+				leds_alt_cnt[i]++;
+		break;
+	case LEDMAN_CMD_ALT_OFF:
+		for (i = 0; i < 32; i++)
+			if ((bits & (1 << i)) && leds_alt_cnt[i]) {
+				leds_alt_cnt[i]--;
+				if (leds_alt_cnt[i] == 0)
+					leds_alt &= ~(1 << i);
+			}
+		break;
+	default:
+		return(-EINVAL);
+	}
+	return(0);
+}
+
+/****************************************************************************/
+
+static void
+ledman_tick(void)
+{
+	ledmode_t	*lmp = &led_mode[current_mode];
+	int			new_value;
+	static int	flash_on = 0;
+/*
+ *	work out which LED's should be on
+ */
+	new_value = 0;
+	new_value |= (((leds_set[0] | leds_on[0]) & ~leds_off[0]) & ~leds_alt);
+	new_value |= (((leds_set[1] | leds_on[1]) & ~leds_off[1]) & leds_alt);
+/*
+ *	flashing LED's run on their own devices,  ie,  according to the
+ *	value fo flash_on
+ */
+	if ((flash_on++ % 60) >= 30)
+		new_value |= ((leds_flash[0]&~leds_alt) | (leds_flash[1]&leds_alt));
+	else
+		new_value &= ~((leds_flash[0]&~leds_alt) | (leds_flash[1]&leds_alt));
+/*
+ *	set the HW
+ */
+ 	(*lmp->set)(new_value);
+	leds_set[0] = leds_set[1] = 0;
+}
+
+/****************************************************************************/
+#endif /* !defined(CONFIG_SH_KEYWEST) && !defined(CONFIG_SH_BIGSUR) */
+/****************************************************************************/
+#if defined(CONFIG_NETtel) && defined(CONFIG_M5307)
+/****************************************************************************/
+/*
+ *	Here it the definition of the LED's on the NETtel circuit board
+ *	as per the labels next to them.  The two parallel port LED's steal
+ *	some high bits so we can map it more easily onto the HW
+ *
+ *	LED - D1   D2   D3   D4   D5   D6   D7   D8   D11  D12  
+ *	HEX - 100  200  004  008  010  020  040  080  002  001
+ *
+ */
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/nettel.h>
+
+static ledmap_t	nettel_old = {
+	0x3ff, 0x200, 0x100, 0x008, 0x004, 0x020, 0x010, 0x080, 0x080, 0x080,
+	0x080, 0x040, 0x040, 0x002, 0x002, 0x024, 0x018, 0x001, 0x0ff, 0x0ff,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x100, 0x200, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+
+#if defined(CONFIG_SNAPGEAR)
+
+/*
+ * all snapgear 5307 based boards have a SW link status on the front
+ */
+
+static ledmap_t nettel_new = {
+	0x3ff, 0x200, 0x100, 0x040, 0x040, 0x002, 0x002, 0x008, 0x008, 0x020,
+	0x020, 0x000, 0x000, 0x000, 0x000, 0x024, 0x018, 0x001, 0x0ff, 0x080,
+	0x000, 0x000, 0x080, 0x004, 0x010, 0x000, 0x000, 0x100, 0x200, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+
+#else
+
+static ledmap_t nettel_new = {
+	0x3ff, 0x200, 0x100, 0x040, 0x040, 0x002, 0x002, 0x008, 0x004, 0x020,
+	0x010, 0x000, 0x000, 0x000, 0x000, 0x024, 0x018, 0x001, 0x0ff, 0x080,
+	0x000, 0x000, 0x080, 0x000, 0x000, 0x000, 0x000, 0x100, 0x200, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+
+#endif
+
+static leddef_t	nettel_def = {
+	0x000, 0x200, 0x000, 0x100,
+};
+
+#ifdef ENTERASYS
+static ledmap_t enterasys_std = {
+	0x3ff, 0x200, 0x100, 0x040, 0x040, 0x002, 0x002, 0x008, 0x004, 0x020,
+	0x010, 0x000, 0x000, 0x000, 0x000, 0x024, 0x018, 0x001, 0x00c, 0x030,
+	0x000, 0x000, 0x080, 0x000, 0x000, 0x000, 0x000, 0x100, 0x200, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+  
+static leddef_t enterasys_def = {
+	0x000, 0x200, 0x000, 0x100,
+};
+#endif
+
+static void
+nettel_set(unsigned long bits)
+{
+	unsigned long		flags;
+
+	save_flags(flags); cli();
+	* (volatile char *) NETtel_LEDADDR = (~bits & 0xff);
+	mcf_setppleds(0x60, ~(bits >> 3) & 0x60);
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+#endif /* defined(CONFIG_NETtel) && defined(CONFIG_M5307) */
+/****************************************************************************/
+#if defined(CONFIG_NETtel) && defined(CONFIG_M5272)
+/****************************************************************************/
+
+/*
+ *	For the SecureEdge Firewall (5272), 5 operational LED's.
+ *
+ *	LED -   POWER HEARTBEAT TX     RX     VPN
+ * 	HEX -    001     002    004    008    010
+ */
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/nettel.h>
+
+static ledmap_t nt5272_std = {
+	0x01f, 0x001, 0x002, 0x008, 0x004, 0x008, 0x004, 0x000, 0x000, 0x008,
+	0x004, 0x000, 0x000, 0x000, 0x000, 0x014, 0x008, 0x010, 0x01c, 0x010,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+
+static leddef_t	nt5272_def = {
+	0x000, 0x001, 0x000, 0x002,
+};
+
+static void nt5272_set(unsigned long bits)
+{
+	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT)) = (~bits & 0x1f);
+}
+
+/****************************************************************************/
+#endif /* defined(CONFIG_NETtel) && defined(CONFIG_M5272) */
+/****************************************************************************/
+#if defined(CONFIG_SE1100)
+/****************************************************************************/
+
+/*
+ *	For the SecureEdge SE1100 (5272), 3 operational LED's.
+ *
+ *	LED -   RUNNING INTERNAL1 INTERNAL2
+ * 	HEX -     001     200       002
+ */
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/se1100.h>
+
+static ledmap_t se1100_std = {
+	0x203, 0x000, 0x001, 0x200, 0x200, 0x200, 0x200, 0x000, 0x000, 0x000,
+	0x000, 0x002, 0x002, 0x002, 0x002, 0x200, 0x002, 0x000, 0x202, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+
+static leddef_t	se1100_def = {
+	0x000, 0x000, 0x000, 0x001
+};
+
+static void se1100_set(unsigned long bits)
+{
+	mcf_setpa(0x203, bits & 0x203);
+}
+
+/****************************************************************************/
+#endif /* defined(CONFIG_SE1100) */
+/****************************************************************************/
+#if defined(CONFIG_GILBARCONAP) && defined(CONFIG_M5272)
+/****************************************************************************/
+
+/*
+ *	For the Gilbarco/NAP (5272), 2 operational LED's.
+ *
+ *	LED -   RUNNING DIAG
+ * 	HEX -     001    002
+ */
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/nap.h>
+
+static ledmap_t nap5272_std = {
+	0x003, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x002, 0x001, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+
+static leddef_t	nap5272_def = {
+	0x000, 0x001, 0x000, 0x002,
+};
+
+static void nap5272_set(unsigned long bits)
+{
+	mcf_setpa(0x3, ~bits & 0x3);
+}
+
+/****************************************************************************/
+#endif /* defined(CONFIG_SE1100) */
+/****************************************************************************/
+#if defined(CONFIG_AVNET5282)
+/****************************************************************************/
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+#define GPTASYSCR1  (*(volatile unsigned char *)0x401a0006)
+#define GPTBSYSCR1  (*(volatile unsigned char *)0x401b0006)
+#define GPTADR      (*(volatile unsigned char *)0x401a001d)
+#define GPTBDR      (*(volatile unsigned char *)0x401b001d)
+#define GPTADDR     (*(volatile unsigned char *)0x401a001e)
+#define GPTBDDR     (*(volatile unsigned char *)0x401b001e)
+#define PORT_TC     (*(volatile unsigned char *)0x4010000f)
+#define PORT_TD     (*(volatile unsigned char *)0x40100010)
+#define DDR_TC      (*(volatile unsigned char *)0x40100023)
+#define DDR_TD      (*(volatile unsigned char *)0x40100024)
+#define DR_TC       (*(volatile unsigned char *)0x40100037)
+#define DR_TD       (*(volatile unsigned char *)0x40100038)
+
+
+static ledmap_t ads5282_std = {
+	0x003, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x002, 0x001, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+
+static leddef_t	ads5282_def = {
+	0x000, 0x001, 0x000, 0x002,
+};
+
+static void ads5282_set(unsigned long bits)
+{
+	static int first_call = 1;
+
+	if (first_call) {
+		GPTASYSCR1 = 0x00;
+		GPTBSYSCR1 = 0x00;
+		GPTADDR = 0x00;
+		GPTBDDR = 0x0f;
+		DDR_TC = 0x05;
+		DDR_TD = 0x05;
+		first_call = 0;
+	}
+
+	if (bits & 0x01) PORT_TC &= ~0x01; else PORT_TC |= 0x01;
+	if (bits & 0x02) PORT_TC &= ~0x04; else PORT_TC |= 0x04;
+	if (bits & 0x04) PORT_TD &= ~0x01; else PORT_TD |= 0x01;
+	if (bits & 0x08) PORT_TD &= ~0x04; else PORT_TD |= 0x04;
+	if (bits & 0x10) GPTBDR  &= ~0x01; else GPTBDR  |= 0x01;
+	if (bits & 0x20) GPTBDR  &= ~0x02; else GPTBDR  |= 0x02;
+	if (bits & 0x40) GPTBDR  &= ~0x04; else GPTBDR  |= 0x04;
+	if (bits & 0x80) GPTBDR  &= ~0x08; else GPTBDR  |= 0x08;
+}
+
+/****************************************************************************/
+#endif /* defined(CONFIG_AVNET5282) */
+/****************************************************************************/
+#if defined(CONFIG_SH_SECUREEDGE5410)
+/****************************************************************************/
+
+/*
+ *	For the SecureEdge5410 7 (or 8 for eth2/DMZ port) operational LED's.
+ *
+ *	LED -   POWR  HBEAT  LAN1  LAN2 | LAN3 | COM ONLINE  VPN 
+ *	POS -    D2    D3    D4    D5   |  ??  | D6    D7    D8    DTR
+ * 	HEX -    01    02    04    08   |0x2000| 10    20    40    80 
+ */
+
+#include <asm/io.h>
+#if defined(CONFIG_LEDMAP_TAMS_SOHO)
+/*
+ *	LED -   POWR  HBEAT  LAN1  LAN2    COM   ONLINE VPN      
+ *	POS -    D2    D3    D4    D5      ??    D6     D7    DTR
+ * 	HEX -    01    02    04    08    0x2000  10     20    80
+ */
+static ledmap_t se5410_std = {
+	0x203f,0x0001,0x0002,0x2000,0x2000,0x2000,0x2000,0x0004,0x0004,0x0008,
+	0x0008,0x0000,0x0000,0x0000,0x0000,0x2024,0x0018,0x0020,0x203c,0x0000,
+	0x0000,0x0000,0x0010,0x0000,0x0000,0x0000,0x0000,0x0001,0x0002,0x0000,
+	0x0000,0x0000,0x0000,0x0000
+};
+#else
+static ledmap_t se5410_std = {
+	0x207f,0x0001,0x0002,0x0010,0x0010,0x0010,0x0010,0x0004,0x0004,0x0008,
+	0x0008,0x0000,0x0000,0x0000,0x0000,0x2054,0x0028,0x0040,0x207c,0x0000,
+	0x0000,0x0000,0x0020,0x0000,0x0000,0x0000,0x0000,0x0001,0x0002,0x2000,
+	0x2000,0x0000,0x0000,0x0000
+};
+#endif
+
+static leddef_t	se5410_def = {
+	0x0000, 0x0001, 0x0000, 0x0002,
+};
+
+static void se5410_set(unsigned long bits)
+{
+	int flags;
+
+	save_and_cli(flags);
+	SECUREEDGE_WRITE_IOPORT(~bits, 0x207f);
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+#endif /* defined(CONFIG_GILBARCONAP) && defined(CONFIG_M5272) */
+/****************************************************************************/
+#if defined(CONFIG_NETtel) && defined(CONFIG_M5206e)
+/****************************************************************************/
+/*
+ *	For the WebWhale/NETtel1500,  3 LED's (was 2)
+ *
+ *	LED - HEARTBEAT  DCD    DATA
+ * 	HEX -    001     002    004
+ */
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/nettel.h>
+
+static ledmap_t nt1500_std = {
+	0x007, 0x000, 0x001, 0x004, 0x004, 0x004, 0x004, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x004, 0x002, 0x000, 0x007, 0x000,
+	0x002, 0x002, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+
+static leddef_t	nt1500_def = {
+	0x000, 0x000, 0x000, 0x001,
+};
+
+static void
+nt1500_set(unsigned long bits)
+{
+	* (volatile char *) NETtel_LEDADDR = (~bits & 0x7);
+}
+
+/****************************************************************************/
+#endif /* defined(CONFIG_NETtel) && defined(CONFIG_M5206e) */
+/****************************************************************************/
+#ifdef CONFIG_eLIA
+/****************************************************************************/
+/*
+ *	For the eLIA, only 2 LED's.
+ *
+ *	LED - HEARTBEAT  USER
+ *	HEX -    2        1
+ */
+
+#ifdef CONFIG_COLDFIRE
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#endif
+#include <asm/elia.h>
+
+static ledmap_t elia_std = {
+	0x003, 0x000, 0x002, 0x001, 0x001, 0x001, 0x001, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x002, 0x001, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+
+static leddef_t	elia_def = {
+	0x000, 0x000, 0x000, 0x002,
+};
+
+static void
+elia_set(unsigned long bits)
+{
+	unsigned long		flags;
+
+	save_flags(flags); cli();
+	mcf_setppleds(0x3000, ~(bits << 12) & 0x3000);
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+#endif /* CONFIG_eLIA */
+/****************************************************************************/
+/****************************************************************************/
+#if defined(CONFIG_AMDSC520)
+/****************************************************************************/
+
+#include <linux/smp_lock.h>
+#include <linux/sched.h>
+#include <linux/reboot.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#if defined(CONFIG_CHINOOK)
+/*
+ *	Here is the definition of the LED's on the 6wind Chinook circuit board
+ *	as per the LED order from left to right. These probably don't
+ *  correspond to any known enclosure.
+ *
+ *	LED -  D1    D2    D3    D4    D5    D6    D7    D8    D9    D10
+ *	HEX - 0001  0400  0008  0010  0800  0020  0040  0080  0100  0200
+ *
+ *  Sync LEDs - Activity  Link
+ *  HEX       - 04000000  08000000
+ */
+static ledmap_t	nettel_std = {
+	0x0c000ff9, 0x00000001, 0x00000400, 0x00000040, 0x00000040,
+	0x04000000, 0x04000000, 0x00000010, 0x00000008, 0x00000020,
+	0x00000800, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000028, 0x00000810, 0x00000200, 0x00000bf8, 0x00000820,
+	0x00000000, 0x08000000, 0x00000100, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000
+};
+
+static leddef_t	nettel_def = {
+	0x0000, 0x0001, 0x0000, 0x0400,
+};
+
+#elif defined(CONFIG_SNAPGEAR)
+/*
+ *	Here is the definition of the LED's on the SnapGear x86 circuit board
+ *	as per the labels next to them.
+ *
+ *	LED - D1   D2   D3   D4   D5   D6   D7   D8   D9   D10
+ *	HEX - 001  002  004  008  010  020  040  100  080  200
+ */
+static ledmap_t	nettel_std = {
+	0x3ff, 0x001, 0x002, 0x080, 0x080, 0x040, 0x040, 0x010, 0x010, 0x020,
+	0x020, 0x000, 0x000, 0x000, 0x000, 0x048, 0x030, 0x200, 0x3fc, 0x004,
+	0x000, 0x000, 0x100, 0x008, 0x004, 0x000, 0x000, 0x001, 0x002, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+
+static leddef_t	nettel_def = {
+	0x0000, 0x0001, 0x0000, 0x0002,
+};
+
+/*
+ *	Here is the definition of the LED's on the SnapGear x86 circuit board
+ *	as per the labels next to them.  This is for the old enclosure.
+ *
+ *	LED - D1   D2   D3   D4   D5   D6   D7   D8   D9   D10
+ *	HEX - 001  002  004  008  010  020  040  100  080  200
+ */
+static ledmap_t	nettel_old = {
+	0x3ff, 0x002, 0x001, 0x080, 0x080, 0x040, 0x040, 0x010, 0x010, 0x020,
+	0x020, 0x000, 0x000, 0x000, 0x000, 0x048, 0x030, 0x200, 0x3fc, 0x004,
+	0x000, 0x000, 0x100, 0x008, 0x004, 0x000, 0x000, 0x001, 0x002, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+
+static leddef_t	nettel_def_old = {
+	0x0000, 0x0002, 0x0000, 0x0001,
+};
+
+#elif defined(CONFIG_SITECTRLER)
+/*
+ *	Here it the definition of the LED's on the SiteController circuit board
+ *	as per the labels next to them. (D9 and D10 are not software controlled)
+ *
+ *	LED -  D1   D2   D3   D4   D5   D6   D7   D8 
+ *	HEX - 0001 0002 0004 0008 0010 0020 0040 0080 
+ */
+static ledmap_t	nettel_std = {
+	0x10fd,0x0001,0x1000,0x0004,0x0004,0x0008,0x0008,0x0040,0x0040,0x0080,
+	0x0080,0x0000,0x0000,0x0000,0x0000,0x00cc,0x0030,0x0000,0x0000,0x0000,
+	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,
+	0x0000,0x0000,0x0000,0x0000
+};
+
+static leddef_t	nettel_def = {
+	0x0000, 0x0001, 0x0000, 0x1000,
+};
+
+#elif defined(CONFIG_ADTRAN_ADVANTA)
+/*
+ *	Here is the definition of the LED's on the Adtran Advanta3110 circuit
+ *	board as per the labels next to them.
+ *	The lower 8 bits are for IO port 0x300.
+ *	The upper 4 bits are for PIO31-28.
+ *
+ *	LED - D1   D2   D3   D4   D7   D8   D15green D15red   D16green D16red
+ *	HEX - 01   02   04   08   40   80   10000000 40000000 20000000 80000000
+ */
+static ledmap_t	nettel_std = {
+	0xf00000cf, 0x00000000, 0x20000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000008,
+	0x00000004,	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000009, 0x00000006, 0x10000000, 0x100000cf, 0x0000000c,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000080, 0x00000040, 0x00000001, 0x00000002, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000
+};
+
+static leddef_t	nettel_def = {
+	0, 0, 0, 0x20000000,
+};
+
+#else
+/*
+ *	Here is the definition of the LED's on the x86 NETtel circuit board
+ *	as per the labels next to them.
+ *
+ *	LED - D1   D2   D3   D4   D5   D6   D7   D8   D9   D10
+ *	HEX - 001  002  004  008  010  020  040  100  080  200
+ */
+static ledmap_t	nettel_std = {
+	0x3ff, 0x002, 0x001, 0x100, 0x100, 0x080, 0x080, 0x010, 0x008, 0x040,
+	0x020, 0x000, 0x000, 0x000, 0x000, 0x048, 0x030, 0x200, 0x3fc, 0x004,
+	0x000, 0x000, 0x004, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+
+static leddef_t	nettel_def = {
+	0x0000, 0x0002, 0x0000, 0x0001,
+};
+
+#endif
+
+static volatile unsigned long	*ledman_ledp;
+
+static void nettel_set(unsigned long bits)
+{
+#ifdef CONFIG_ADTRAN_ADVANTA
+	outb(~bits, 0x300);
+	*ledman_ledp = (*ledman_ledp & 0x0fffffff) | (~bits & 0xf0000000);
+#else
+	*ledman_ledp = (*ledman_ledp & ~ nettel_std[LEDMAN_ALL])
+			| (~bits & nettel_std[LEDMAN_ALL]);
+#endif
+}
+
+static void ledman_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	ledman_signalreset();
+}
+
+static void ledman_initarch(void)
+{
+	volatile unsigned char	*mmcrp;
+
+	/* Map the CPU MMCR register for access */
+	mmcrp = (volatile unsigned char *) ioremap(0xfffef000, 4096);
+
+#ifdef CONFIG_ADTRAN_ADVANTA
+	/* Enable the PIO for the PWR and VPN LEDs */
+	*(volatile unsigned short *)(mmcrp + 0xc22) &= 0x0fff;
+	*(volatile unsigned short *)(mmcrp + 0xc2c) |= 0xf000;
+
+	/* Enable GPIRQ2, low-to-high transitions, map to IRQ12 */
+	*(volatile unsigned short *)(mmcrp + 0xc22) |= 0x0020;
+	*(volatile unsigned long *)(mmcrp + 0xd10) |= 0x0004;
+	*(mmcrp + 0xd52) = 0x07;
+#endif
+
+	ledman_ledp = (volatile unsigned long *) (mmcrp + 0xc30);
+
+	/* Setup extern "factory default" switch on IRQ12 */
+	if (request_irq(12, ledman_interrupt, SA_INTERRUPT, "Erase", NULL))
+		printk("LED: failed to register IRQ12 for ERASE witch\n");
+	else
+		printk("LED: registered ERASE switch on IRQ12\n");
+}
+
+/****************************************************************************/
+#endif /* CONFIG_AMDSC520 */
+/****************************************************************************/
+/****************************************************************************/
+#if defined(CONFIG_GEODE)
+/****************************************************************************/
+
+#include <asm/io.h>
+
+/*
+ *	Construct a mapping from virtual LED to gpio bit and bank.
+ */
+struct gpiomap {
+		unsigned int	bank;
+		unsigned long	bit;
+};
+
+#if defined(CONFIG_REEFEDGE) || defined(CONFIG_SE5000)
+/*
+ *	Definition of the LED's on the GEODE SC1100 ReefEdfe circuit board,
+ *	as per the labels next to them.
+ *
+ *	LED      -  D20  D19  D18  D16
+ *	GPIO BIT -   38   18   40   37
+ *  VIRTNUM  -  0x8  0x4  0x2  0x1
+ */
+#define	GPIO0_OFF	0x00040000
+#define	GPIO1_OFF	0x00000160
+
+static ledmap_t	nettel_std = {
+	0x00f, 0x001, 0x002, 0x000, 0x000, 0x000, 0x000, 0x004,
+	0x004, 0x008, 0x008, 0x000, 0x000, 0x000, 0x000, 0x004,
+	0x008, 0x000, 0x00e, 0x000, 0x000, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+	0x000, 0x000
+};
+
+static struct gpiomap iomap[] = {
+	/* VIRT 0x1 */	{ 1, 0x00000020 },
+	/* VIRT 0x2 */	{ 1, 0x00000100 },
+	/* VIRT 0x4 */	{ 0, 0x00040000 },
+	/* VIRT 0x8 */	{ 1, 0x00000040 },
+};
+
+#elif defined(CONFIG_SE2910)
+/*
+ *	Definition of the LED's on the SnapGear SE2910 boards.
+ *
+ *	LED      -   D2   D4   D6  D11  D13  D18  D20  D22   D25   D28
+ *	GPIO BIT -    2    3   17    0   36   47   39   40    18    38
+ *  VIRTNUM  -  0x1  0x2  0x4  0x8 0x10 0x20 0x40 0x80 0x100 0x200
+ */
+#define	GPIO0_OFF	0x0006000d
+#define	GPIO1_OFF	0x000081d0
+
+static ledmap_t	nettel_std = {
+	0x3ff, 0x001, 0x002, 0x080, 0x080, 0x080, 0x080, 0x010,
+	0x008, 0x040, 0x020, 0x200, 0x200, 0x200, 0x200, 0x30c,
+	0x0f0, 0x000, 0x3fc, 0x004, 0x000, 0x000, 0x004, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+   	0x000, 0x000
+};
+
+static struct gpiomap iomap[] = {
+	/* VIRT 0x1 */   { 0, (1 << (02 - 00)) },
+	/* VIRT 0x2 */   { 0, (1 << (03 - 00)) },
+	/* VIRT 0x4 */   { 0, (1 << (17 - 00)) },
+	/* VIRT 0x8 */   { 0, (1 << (00 - 00)) },
+	/* VIRT 0x10 */  { 1, (1 << (36 - 32)) },
+	/* VIRT 0x20 */  { 1, (1 << (47 - 32)) },
+	/* VIRT 0x40 */  { 1, (1 << (39 - 32)) },
+	/* VIRT 0x80 */  { 1, (1 << (40 - 32)) },
+	/* VIRT 0x100 */ { 0, (1 << (18 - 00)) },
+	/* VIRT 0x200 */ { 1, (1 << (38 - 32)) },
+};
+
+#else
+/*
+ *	Definition of the LED's on the SnapGear GEODE board.
+ *
+ *	LED      -  D11  D12  D13  D14  D15  D16  D17  D18   D19   D20
+ *	GPIO BIT -   32   33   34   35   36   37   39   40    18    38
+ *  VIRTNUM  -  0x1  0x2  0x4  0x8 0x10 0x20 0x40 0x80 0x100 0x200
+ */
+#define	GPIO0_OFF	0x00040000
+#define	GPIO1_OFF	0x000001ff
+
+static ledmap_t	nettel_std = {
+	0x3ff, 0x001, 0x002, 0x080, 0x080, 0x080, 0x080, 0x010,
+	0x008, 0x040, 0x020, 0x200, 0x200, 0x200, 0x200, 0x30c,
+	0x0f0, 0x000, 0x3fc, 0x004, 0x000, 0x000, 0x004, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+   	0x000, 0x000
+};
+
+static struct gpiomap iomap[] = {
+	/* VIRT 0x1 */   { 1, 0x00000001 },
+	/* VIRT 0x2 */   { 1, 0x00000002 },
+	/* VIRT 0x4 */   { 1, 0x00000004 },
+	/* VIRT 0x8 */   { 1, 0x00000008 },
+	/* VIRT 0x10 */  { 1, 0x00000010 },
+	/* VIRT 0x20 */  { 1, 0x00000020 },
+	/* VIRT 0x40 */  { 1, 0x00000080 },
+	/* VIRT 0x80 */  { 1, 0x00000100 },
+	/* VIRT 0x100 */ { 0, 0x00040000 },
+	/* VIRT 0x200 */ { 1, 0x00000040 },
+};
+
+#endif /* !CONFIG_REEFEDGE && !CONFIG_SE5000 */
+
+#define	GPIO_SIZE	(sizeof(iomap) / sizeof(*iomap))
+
+static leddef_t	nettel_def = {
+	0x0000, 0x0001, 0x0000, 0x0002,
+};
+
+
+static void nettel_set(unsigned long bits)
+{
+	unsigned int gpio[2];
+	unsigned int i, mask;
+
+	gpio[0] = GPIO0_OFF;
+	gpio[1] = GPIO1_OFF;
+
+	for (i = 0, mask = 0x1; (i < GPIO_SIZE); i++, mask <<= 1) {
+		if (bits & mask)
+			gpio[iomap[i].bank] &= ~iomap[i].bit;
+	}
+
+	outl(gpio[0], 0x6400);
+	outl(gpio[1], 0x6410);
+}
+
+static int ledman_button;
+static struct timer_list ledman_timer;
+
+static void ledman_buttonpoll(unsigned long arg)
+{
+	if (inl(0x6404) & 0x0002) {
+		if (ledman_button == 0) {
+			printk("LEDMAN: reset button pushed!\n");
+			ledman_signalreset();
+		}
+		ledman_button = 1;
+	} else {
+		ledman_button = 0;
+	}
+
+	/* Re-arm timer interrupt. */
+	ledman_timer.expires = jiffies + HZ/25;
+	add_timer(&ledman_timer);
+}
+
+static void ledman_initarch(void)
+{
+	init_timer(&ledman_timer);
+	ledman_timer.function = ledman_buttonpoll;
+	ledman_timer.data = 0;
+	ledman_timer.expires = jiffies + HZ/25;
+	add_timer(&ledman_timer);
+}
+
+/****************************************************************************/
+#endif /* CONFIG_GEODE */
+/****************************************************************************/
+/****************************************************************************/
+#if defined(CONFIG_SH_KEYWEST) || defined(CONFIG_SH_BIGSUR)
+/****************************************************************************/
+/*
+ *	Here it the definition of the how we use the 8 segment LED display on
+ *	the Hitachi Keywest
+ *
+ *	LED - LD0  LD1  LD2  LD3  LD4  LD5  LD6  LD7
+ *	HEX - 001  002  004  008  010  020  040  080
+ *        HB   CNT  L1R  L1T  L2R  L2T  COM  VPN
+ *
+ */
+
+#include <linux/kernel_stat.h>
+
+#define KEYWEST_NUM_LEDS 8
+
+#if defined(CONFIG_SH_BIGSUR)
+#define LED_BASE 0xb1fffe00
+#define LED_ADDR(x) (LED_BASE+((x)<<2))
+#else
+#define LED_BASE 0xb1ffe000
+#define LED_ADDR(x) (LED_BASE+(x))
+#endif
+
+static ledmap_t	keywest_std = {
+	0x0ff, 0x000, 0x001, 0x040, 0x040, 0x040, 0x040, 0x004, 0x008, 0x010,
+	0x020, 0x000, 0x000, 0x000, 0x000, 0x054, 0x02a, 0x080, 0x07e, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x002, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+
+static leddef_t	keywest_def = {
+	0x000, 0x000, 0x000, 0x001,
+};
+
+static struct keywest_led_value {
+	int				count;
+	int				max;
+	int				prev;
+	unsigned char	disp;
+} keywest_led_values[KEYWEST_NUM_LEDS][2];
+
+
+struct keywest_font_s {
+	unsigned char row[7];
+} keywest_font[] = {
+	{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}, /* bar 0 */
+	{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f }}, /* bar 1 */
+	{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f }}, /* bar 2 */
+	{{ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1f }}, /* bar 3 */
+	{{ 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x1f }}, /* bar 4 */
+	{{ 0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f }}, /* bar 5 */
+	{{ 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f }}, /* bar 6 */
+	{{ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f }}, /* bar 7 */
+	{{ 0x00, 0x0a, 0x1f, 0x1f, 0x0e, 0x04, 0x00 }}, /* heart */
+	{{ 0x08, 0x14, 0x14, 0x1c, 0x1c, 0x1c, 0x1c }}, /* vpn locked */
+	{{ 0x02, 0x05, 0x05, 0x1c, 0x1c, 0x1c, 0x1c }}, /* vpn unlocked */
+};
+
+static unsigned int keywest_old_cntx = 0;
+
+/*
+ * program up some display bars
+ */
+
+static void ledman_initkeywest()
+{
+	int i, j;
+
+	for (i = 0; i < sizeof(keywest_font) / sizeof(struct keywest_font_s); i++) {
+		* (unsigned char *)(LED_ADDR(0x20)) = i;
+		for (j = 0; j < 7; j++)
+			* (unsigned char *)(LED_ADDR(0x28+j)) = keywest_font[i].row[j];
+	}
+	keywest_old_cntx = kstat.context_swtch;
+}
+
+/*
+ *	We just rip through and write all LED 'disp' chars each tick.
+ */
+
+static void keywest_set(unsigned long bits)
+{
+	int i, alt;
+	for (i = 0; i < KEYWEST_NUM_LEDS; i++) {
+		alt = (leds_alt & (1 << i)) ? 1 : 0;
+		* (unsigned char *)(LED_ADDR(0x38+i)) = keywest_led_values[i][alt].disp;
+	}
+}
+
+static int
+keywest_bits(unsigned long cmd, unsigned long bits)
+{
+	ledmode_t		*lmp = &led_mode[current_mode];
+	int				 alt, i;
+	unsigned long	 new_alt;
+
+	alt = (cmd & LEDMAN_CMD_ALTBIT) ? 1 : 0;
+
+	switch (cmd & ~LEDMAN_CMD_ALTBIT) {
+	case LEDMAN_CMD_SET:
+		bits   &= ~(leds_flash[alt]|leds_on[alt]|leds_off[alt]);
+		for (i = 0; i < KEYWEST_NUM_LEDS; i++)
+			if (bits & (1 << i))
+				keywest_led_values[i][alt].count++;
+		break;
+	case LEDMAN_CMD_ON:
+		leds_on[alt]    |= bits;
+		leds_off[alt]   &= ~bits;
+		leds_flash[alt] &= ~bits;
+		(*lmp->tick)();
+		break;
+	case LEDMAN_CMD_OFF:
+		leds_on[alt]    &= ~bits;
+		leds_off[alt]   |= bits;
+		leds_flash[alt] &= ~bits;
+		(*lmp->tick)();
+		break;
+	case LEDMAN_CMD_FLASH:
+		leds_on[alt]    &= ~bits;
+		leds_off[alt]   &= ~bits;
+		leds_flash[alt] |= bits;
+		break;
+	case LEDMAN_CMD_RESET:
+		leds_on[alt]    = (leds_on[alt]   &~bits) | (bits&lmp->def[LEDS_ON]);
+		leds_off[alt]   = (leds_off[alt]  &~bits) | (bits&lmp->def[LEDS_OFF]);
+		leds_flash[alt] = (leds_flash[alt]&~bits) | (bits&lmp->def[LEDS_FLASH]);
+		memset(keywest_led_values, 0, sizeof(keywest_led_values));
+		break;
+	case LEDMAN_CMD_ALT_ON:
+		new_alt = (bits & ~leds_alt);
+		leds_alt |= bits;
+		/*
+		 * put any newly alt'd bits into a default state
+		 */
+		(*lmp->bits)(LEDMAN_CMD_RESET | LEDMAN_CMD_ALTBIT, new_alt);
+		for (i = 0; i < 32; i++)
+			if (bits & (1 << i))
+				leds_alt_cnt[i]++;
+		break;
+	case LEDMAN_CMD_ALT_OFF:
+		for (i = 0; i < 32; i++)
+			if ((bits & (1 << i)) && leds_alt_cnt[i]) {
+				leds_alt_cnt[i]--;
+				if (leds_alt_cnt[i] == 0)
+					leds_alt &= ~(1 << i);
+			}
+		break;
+	default:
+		return(-EINVAL);
+	}
+	return(0);
+}
+
+static void
+keywest_tick(void)
+{
+	ledmode_t	*lmp = &led_mode[current_mode];
+	int			alt, i;
+	static int	flash_on = 0;
+	struct keywest_led_value *led_value;
+
+	/*
+	 * we take over the second LED as a context switch indicator
+	 */
+	keywest_led_values[1][0].count = kstat.context_swtch - keywest_old_cntx;
+	keywest_old_cntx = kstat.context_swtch;
+
+	for (i = 0; i < KEYWEST_NUM_LEDS; i++) {
+		alt = (leds_alt >> i) & 1;
+		led_value = &keywest_led_values[i][alt];
+		if (leds_off[alt] & (1 << i)) {
+			if ((1 << i) == 0x080) /* VPN unlock */
+				led_value->disp = 0x8a;
+			else
+				led_value->disp = 0x20;
+		} else if (leds_on[alt] & (1 << i)) {
+			if ((1 << i) == 0x080) /* VPN lock */
+				led_value->disp = 0x89;
+			else
+				led_value->disp = 0x87;
+		} else if (leds_flash[alt] & (1 << i)) {
+			if ((flash_on % 6) >= 3) {
+				if ((1 << i) == 0x001) /* heart beat */
+					led_value->disp = 0x88;
+				else
+					led_value->disp = 0x87;
+			} else
+				led_value->disp = 0x20;
+		} else {
+			int val;
+
+			if (led_value->count > led_value->max)
+				led_value->max = led_value->count;
+			
+			val = (led_value->prev + led_value->count) / 2;
+			led_value->prev = val;
+
+			val = (val * 7) / led_value->max;
+			if (val == 0 && led_value->count)
+				val = 1;
+			led_value->disp = 0x80 + (val & 0x7);
+			led_value->count = 0;
+			/* degrade the maximum over time (except load) */
+			if (i != 1)
+				led_value->max = (led_value->max * 9)/10;
+		}
+	}
+	flash_on++;
+ 	(*lmp->set)(0);
+}
+
+/****************************************************************************/
+#endif /* CONFIG_SH_KEYWEST */
+/****************************************************************************/
+/****************************************************************************/
+#if defined(CONFIG_MACH_MONTEJADE) || defined(CONFIG_MACH_SE5100)
+/****************************************************************************/
+
+#include <linux/interrupt.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+/*
+ *	Here is the definition of the LED's on the Intel/MonteJade platform.
+ *	LED D7 is not visible on the front panel, so not much point using it...
+ *
+ *	LED - D1  D2  D3  D4  D16  D17  D18  D23
+ *	HEX - 80  40  20  10   08   04   02   01
+ */
+static ledmap_t	montejade_std = {
+	0xff, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, 0x20, 0xff, 0x10,
+	0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00
+};
+
+static leddef_t	montejade_def = {
+	0x0000, 0x0000, 0x0000, 0x0001,
+};
+
+
+static volatile unsigned char *ledman_cs2;
+
+static void ledman_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	gpio_line_isr_clear(IXP425_GPIO_PIN_9);
+	ledman_signalreset();
+}
+
+static void montejade_set(unsigned long bits)
+{
+	*ledman_cs2 = ~bits;
+}
+
+static struct timer_list montejade_wdt;
+
+static void montejade_wdtpoll(unsigned long arg)
+{
+	*IXP425_GPIO_GPOUTR ^= 0x400;
+
+	/* Re-arm timer interrupt. */
+	montejade_wdt.expires = jiffies + HZ/10;
+	add_timer(&montejade_wdt);
+}
+
+static void montejade_wdtinit(void)
+{
+	/* Configure GPIO10 as an output to kick watchdog */
+	gpio_line_config(IXP425_GPIO_PIN_10, IXP425_GPIO_OUT);
+
+	/* Setup timer poll, 10 times a second should be good enough */
+	init_timer(&montejade_wdt);
+	montejade_wdt.function = montejade_wdtpoll;
+	montejade_wdt.data = 0;
+	montejade_wdt.expires = jiffies + HZ/10;
+	add_timer(&montejade_wdt);
+}
+
+static void ledman_initarch(void)
+{
+	/* Configure CS2 for operation, 8bit and writable will do */
+	*IXP425_EXP_CS2 = 0xbfff0003;
+
+	/* Map the LED chip select address space */
+	ledman_cs2 = (volatile unsigned char *) ioremap(IXP425_EXP_BUS_CS2_BASE_PHYS, 512);
+	*ledman_cs2 = 0xffffffff;
+
+	/* Configure GPIO9 as interrupt input (ERASE switch) */
+	gpio_line_config(IXP425_GPIO_PIN_9, (IXP425_GPIO_IN | IXP425_GPIO_FALLING_EDGE));
+	gpio_line_isr_clear(IXP425_GPIO_PIN_9);
+
+	if (request_irq(26, ledman_interrupt, SA_INTERRUPT, "Erase", NULL))
+		printk("LED: failed to register IRQ26 for ERASE witch\n");
+	else
+		printk("LED: registered ERASE switch on IRQ26\n");
+
+	montejade_wdtinit();
+}
+
+/****************************************************************************/
+#endif /* CONFIG_MACH_MONTEJADE || CONFIG_MACH_SE5100 */
+/****************************************************************************/
+/****************************************************************************/
+#if defined(CONFIG_ARCH_SE4000) || defined(CONFIG_MACH_ESS710) || \
+    defined(CONFIG_MACH_SG560) || defined(CONFIG_MACH_SG580) || \
+	defined(CONFIG_MACH_SG565) || defined(CONFIG_MACH_SHIVA1100)
+/****************************************************************************/
+
+#include <linux/interrupt.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#if defined(CONFIG_MACH_ESS710)
+/*
+ *	Here is the definition of the LED's on the SnapGear/ESS710 circuit board
+ *	as per the labels next to them.
+ *
+ *	LED - D1   D3   D4   D5 
+ *	HEX - 004  008  010  020 
+ */
+static ledmap_t	snapgear425_std = {
+	0x03c, 0x000, 0x020, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x024, 0x018, 0x000, 0x03c, 0x000,
+	0x000, 0x000, 0x010, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x004
+};
+
+static leddef_t	snapgear425_def = {
+	0x0000, 0x0000, 0x0000, 0x0020,
+};
+
+#define	LEDMASK		0x3c
+
+#elif defined(CONFIG_MACH_SG565) || defined(CONFIG_MACH_SHIVA1100)
+
+/*
+ *	Here is the definition of the LEDs on the CyberGuard/SG565
+ *	and Eicon/Shiva1100, as per the labels next to them.
+ *
+ *	LED -  D2   D3   D4   D5   D6   D7   D8
+ *	HEX - 0004 0008 0010 0020 0040 0080 0400
+ */
+static ledmap_t	snapgear425_std = {
+	0x4fc, 0x000, 0x004, 0x040, 0x040, 0x040, 0x040, 0x008, 0x008, 0x010,
+	0x010, 0x000, 0x000, 0x000, 0x000, 0x48c, 0x070, 0x400, 0x4fc, 0x000,
+	0x000, 0x000, 0x080, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x020,
+	0x020, 0x000, 0x000, 0x000
+};
+
+static leddef_t	snapgear425_def = {
+	0x0000, 0x0000, 0x0000, 0x0004,
+};
+
+#define	LEDMASK		0x04fc
+
+#elif defined(CONFIG_MACH_SG560) || defined(CONFIG_MACH_SG580)
+
+/*
+ *	Here is the definition of the LEDs on the CyberGuard/SG560
+ *	and CyberGuard/SG580, as per the labels next to them.
+ *
+ *	LED -  D2   D3   D4   D5   D6   D7   D8
+ *	HEX - 0004 0008 0010 0400 0040 0020 0080
+ */
+static ledmap_t	snapgear425_std = {
+	0x4fc, 0x000, 0x004, 0x040, 0x040, 0x040, 0x040, 0x008, 0x008, 0x010,
+	0x010, 0x000, 0x000, 0x000, 0x000, 0x0ac, 0x450, 0x080, 0x4fc, 0x000,
+	0x000, 0x000, 0x020, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x400
+};
+
+static leddef_t	snapgear425_def = {
+	0x0000, 0x0000, 0x0000, 0x0004,
+};
+
+#define	LEDMASK		0x04fc
+
+#else
+
+/*
+ *	Here is the definition of the LEDs on the SnapGear/SE4000, as per the
+ *	labels next to them.  LED D7 is not visible on the front panel, so not
+ *	much point using it...
+ *
+ *	LED - D1   D3   D4   D5   D6   D7
+ *	HEX - 004  008  010  020  040  080
+ */
+static ledmap_t	snapgear425_std = {
+	0x0fc, 0x000, 0x004, 0x008, 0x008, 0x008, 0x008, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x028, 0x010, 0x020, 0x0fc, 0x010,
+	0x000, 0x000, 0x010, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+
+static leddef_t	snapgear425_def = {
+	0x0000, 0x0000, 0x0000, 0x0004,
+};
+
+#define	LEDMASK		0xfc
+
+#endif
+
+static void ledman_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	gpio_line_isr_clear(IXP425_GPIO_PIN_9);
+	ledman_signalreset();
+}
+
+static void snapgear425_set(unsigned long bits)
+{
+	*IXP425_GPIO_GPOUTR = (*IXP425_GPIO_GPOUTR & ~LEDMASK) | (~bits & LEDMASK);
+}
+
+static void ledman_initarch(void)
+{
+	/* Enable LED lines as outputs - do them all in one go */
+	*IXP425_GPIO_GPOER &= ~LEDMASK;
+
+	/* Configure GPIO9 as interrupt input (ERASE switch) */
+	gpio_line_config(IXP425_GPIO_PIN_9, (IXP425_GPIO_IN | IXP425_GPIO_FALLING_EDGE));
+	gpio_line_isr_clear(IXP425_GPIO_PIN_9);
+
+	/* De-assert reset for the hub/switch - just in case... */
+	gpio_line_config(IXP425_GPIO_PIN_13, IXP425_GPIO_OUT);
+	gpio_line_set(IXP425_GPIO_PIN_13, 1);
+
+	if (request_irq(26, ledman_interrupt, SA_INTERRUPT, "Erase", NULL))
+		printk("LED: failed to register IRQ26 for ERASE witch\n");
+	else
+		printk("LED: registered ERASE switch on IRQ26\n");
+}
+
+/****************************************************************************/
+#endif /* CONFIG_ARCH_SE4000 || CONFIG_MACH_ESS710 || CONFIG_MACH_SG560 || CONFIG_MACH_SG580 || CONFIG_MACH_SG565 || CONFIG_MACH_SHIVA1100 */
+/****************************************************************************/
+/****************************************************************************/
+#if defined(CONFIG_MACH_IVPN)
+/****************************************************************************/
+
+#include <linux/interrupt.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+/*
+ *	There is 2 LED banks on the iVPN. But really there is 4 LEDs, 2 green
+ *	and 2 red. They are connected to gpio lines, with the mapping:
+ *
+ *	GPIO -   12  13   2  11
+ *	LED  -   G0  R0  G1  R1
+ *
+ *	But...
+ *
+ *	I have virtualized the bits in the ledmap, since the iVPN led
+ *	functionality is a little weird, and cannot be displayed by just
+ *	setting the bits.
+ */
+
+#define	BIT_HEARTBEAT	0x1
+#define	BIT_LANLINK		0x2
+#define	BIT_LANACTIVITY	0x4
+#define	BIT_WANLINK		0x8
+#define	BIT_WANACTIVITY	0x10
+#define	BIT_WIFLINK		0x20
+#define	BIT_WIFACTIVITY	0x40
+#define	BIT_VPNLINK		0x80
+#define	BIT_VPNACTIVITY	0x100
+
+static ledmap_t	ivpn_std = {
+	0x1ff, 0x000, 0x001, 0x000, 0x000, 0x000, 0x000, 0x004, 0x004, 0x010,
+	0x010, 0x000, 0x000, 0x000, 0x000, 0x00a, 0x088, 0x080, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x002, 0x008, 0x100, 0x100, 0x000, 0x000, 0x040,
+	0x040, 0x020, 0x000, 0x000
+};
+
+static leddef_t	ivpn_def = {
+	0x0000, 0x0002, 0x0000, 0x0001,
+};
+
+
+static void ledman_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	gpio_line_isr_clear(IXP425_GPIO_PIN_9);
+	ledman_signalreset();
+}
+
+static void ivpn_set(unsigned long bits)
+{
+	unsigned long flags;
+	unsigned int wanbit, val = 0;
+	static unsigned int lancnt = 0;
+	static unsigned int wancnt = 0;
+
+	if (bits & BIT_LANLINK) {
+		if ((bits & BIT_LANACTIVITY) || lancnt) {
+			if (lancnt++ > 4) {
+				val |= 0x1;
+				if (lancnt > 8)
+					lancnt = 0;
+			}
+		} else {
+			val |= 0x1;
+		}
+	} else {
+		val |= 0x2;
+	}
+	if (bits & (BIT_WANLINK | BIT_WIFLINK)) {
+		wanbit = (bits & BIT_VPNLINK) ? 0x4 : 0x8;
+		if ((bits & (BIT_WANACTIVITY | BIT_WIFACTIVITY)) || wancnt) {
+			if (wancnt++ > 4) {
+				val |= wanbit;
+				if (wancnt > 8)
+					wancnt = 0;
+			}
+		} else {
+			val |= wanbit;
+		}
+	}
+
+	save_flags(flags); cli();
+	gpio_line_set(IXP425_GPIO_PIN_2, val & 0x4 ? 0 : 1);
+	gpio_line_set(IXP425_GPIO_PIN_11, val & 0x8 ? 0 : 1);
+	gpio_line_set(IXP425_GPIO_PIN_12, val & 0x1 ? 0 : 1);
+	gpio_line_set(IXP425_GPIO_PIN_13, val & 0x2 ? 0 : 1);
+	restore_flags(flags);
+}
+
+static void ledman_initarch(void)
+{
+#if 0
+	/* Enabled second ethernet port */
+	gpio_line_config(IXP425_GPIO_PIN_3, IXP425_GPIO_OUT);
+	gpio_line_set(IXP425_GPIO_PIN_3, 0);
+#endif
+	/* Set up GPIO lines to allow access to LEDs. */
+	gpio_line_set(IXP425_GPIO_PIN_2, 1);
+	gpio_line_set(IXP425_GPIO_PIN_11, 1);
+	gpio_line_set(IXP425_GPIO_PIN_12, 1);
+	gpio_line_set(IXP425_GPIO_PIN_13, 1);
+	gpio_line_config(IXP425_GPIO_PIN_2, IXP425_GPIO_OUT);
+	gpio_line_config(IXP425_GPIO_PIN_11, IXP425_GPIO_OUT);
+	gpio_line_config(IXP425_GPIO_PIN_12, IXP425_GPIO_OUT);
+	gpio_line_config(IXP425_GPIO_PIN_13, IXP425_GPIO_OUT);
+	ivpnss_hwsetup();
+	ivpnss_memmap();
+
+	/* Configure GPIO9 as interrupt input (ERASE switch) */
+	gpio_line_config(IXP425_GPIO_PIN_9, (IXP425_GPIO_IN | IXP425_GPIO_FALLING_EDGE));
+	gpio_line_isr_clear(IXP425_GPIO_PIN_9);
+
+	if (request_irq(26, ledman_interrupt, SA_INTERRUPT, "Erase", NULL))
+		printk("LED: failed to register IRQ26 for ERASE witch\n");
+	else
+		printk("LED: registered ERASE switch on IRQ26\n");
+}
+
+/****************************************************************************/
+#endif /* CONFIG_MACH_IVPN */
+/****************************************************************************/
+/****************************************************************************/
+#if defined(CONFIG_MACH_LITE300)
+/****************************************************************************/
+
+#include <linux/interrupt.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+/*
+ *	Virtual IO address of GPIO data register.
+ */
+#define	KS8695_GPIO_ADDR	(IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_DATA)
+
+/*
+ *	Here is the definition of the LED's on the SnapGear/LITE3 circuit board,
+ *	as per the labels next to them. There is only 2 software programmable
+ *	LEDs, so this is pretty easy :-)
+ *
+ *	LED - D1   D2
+ *	HEX - 002  004
+ */
+static ledmap_t	lite3_std = {
+	0x006, 0x004, 0x002, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x002, 0x000, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+
+static leddef_t	lite3_def = {
+	0x0000, 0x0004, 0x0000, 0x0002,
+};
+
+static volatile unsigned int *ledman_gpio;
+
+static void ledman_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	volatile unsigned int *intstatp;
+
+	intstatp = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_INT_STATUS);
+	*intstatp |= 0x4;
+
+	ledman_signalreset();
+}
+
+static void lite3_set(unsigned long bits)
+{
+	*ledman_gpio = (*ledman_gpio & ~0x6) | (~bits & 0x6);
+}
+
+static void ledman_initarch(void)
+{
+	volatile unsigned int *gpiop, *intenp;
+
+	/* Enable LED lines as outputs */
+	gpiop = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_MODE);
+	*gpiop = (*gpiop | 0x6) & ~0x1;
+
+	/* Turn LEDs off */
+	ledman_gpio = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_DATA);
+	*ledman_gpio = (*ledman_gpio & ~0x6);
+
+	/* Configure GPIO0 as interrupt input (ERASE switch) */
+	gpiop = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_CTRL);
+	*gpiop = (*gpiop & ~0x7) | 0xc;
+
+	intenp = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_INT_ENABLE);
+	*intenp |= 0x4;
+
+	if (request_irq(2, ledman_interrupt, SA_INTERRUPT, "Erase", NULL))
+		printk("LED: failed to register IRQ2 for ERASE witch\n");
+	else
+		printk("LED: registered ERASE switch on IRQ2\n");
+}
+
+/****************************************************************************/
+#endif /* CONFIG_MACH_LITE300 */
+/****************************************************************************/
+/****************************************************************************/
+#if defined(CONFIG_MACH_CM4008)
+/****************************************************************************/
+
+#include <linux/interrupt.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+/*
+ *	Virtual IO address of GPIO data register.
+ */
+#define	KS8695_GPIO_ADDR	(IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_DATA)
+
+/*
+ *	Here is the definition of the LED's on the OpenGear/CM4008 circuit board.
+ *	As per the labels on them, there is one power LED, and 8 serial port
+ *	activity LEDs.
+ *
+ *	LED -  D2   D3   D4   D5   D6   D7   D8   D9   D10
+ *	HEX - 0020 0200 0400 0800 1000 2000 4000 8000 0010
+ */
+static ledmap_t	cm4008_std = {
+	0xfe31, 0x0010, 0x0000, 0x0200, 0x0400, 0x0800, 0x1000, 0x0000,
+   	0x0000, 0x0000, 0x0000, 0x2000, 0x4000, 0x8000, 0x0020, 0x0000,
+   	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+   	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+   	0x0000, 0x0000
+};
+
+static leddef_t	cm4008_def = {
+	0x0000, 0x0010, 0x0000, 0x0001,
+};
+
+static unsigned int ledman_oldbits;
+static unsigned int ledman_idlecount, ledman_scanindex;
+static unsigned int ledman_scan[] = {
+		0x0000, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
+	   	0x0020, 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400,
+};
+#define	ledman_scansize	(sizeof(ledman_scan) / sizeof(unsigned int))
+
+static volatile unsigned int *ledman_gpio;
+
+static void ledman_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	volatile unsigned int *intstatp;
+
+	intstatp = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_INT_STATUS);
+	*intstatp |= 0x20;
+
+	ledman_signalreset();
+}
+
+static void cm4008_set(unsigned long bits)
+{
+	if (bits & 0xfe20)
+		ledman_idlecount = ledman_scanindex = 0;
+
+	/* Show _some_ LED activity if idle to show we are still alive */
+	if ((ledman_oldbits & 0x1) != (bits & 0x1)) {
+		if (ledman_idlecount++ > 150)
+			if (++ledman_scanindex >= ledman_scansize)
+				ledman_scanindex = 1;
+	}
+	ledman_oldbits = bits;
+
+	if (ledman_scanindex)
+			bits |= ledman_scan[ledman_scanindex];
+
+	*ledman_gpio = (*ledman_gpio & ~0xfe30) | (~bits & 0xfe30);
+}
+
+static void ledman_initarch(void)
+{
+	volatile unsigned int *gpiop, *intenp;
+
+	/* Enable LED lines as outputs (and GPIO3 as input) */
+	gpiop = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_MODE);
+	*gpiop = (*gpiop | 0xfe30) & ~0x8;
+
+	/* Turn LEDs off */
+	ledman_gpio = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_DATA);
+	*ledman_gpio = (*ledman_gpio & ~0xfe30);
+
+	/* Configure GPIO3 as interrupt input (ERASE switch) */
+	gpiop = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_CTRL);
+	*gpiop = (*gpiop & ~0xf000) | 0xc000;
+
+	intenp = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_INT_ENABLE);
+	*intenp |= 0x20;
+
+	if (request_irq(5, ledman_interrupt, SA_INTERRUPT, "Erase", NULL))
+		printk("LED: failed to register IRQ5 for ERASE witch\n");
+	else
+		printk("LED: registered ERASE switch on IRQ5\n");
+}
+
+/****************************************************************************/
+#endif /* CONFIG_MACH_CM4008 */
+/****************************************************************************/
+/****************************************************************************/
+#if defined(CONFIG_MACH_CM41xx)
+/****************************************************************************/
+
+#include <linux/interrupt.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+/*
+ *	Virtual IO address of GPIO data register.
+ */
+#define	KS8695_GPIO_ADDR	(IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_DATA)
+
+/*
+ *	Here is the definition of the LED's on the OpenGear/CM41xx circuit board.
+ *	As per the labels on them, there is 2 software controlled LEDs.
+ *
+ *	LED -  D1   D2
+ *	HEX - 0200 0400
+ */
+static ledmap_t	cm41xx_std = {
+	0x0600, 0x0400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+   	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+   	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+   	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+   	0x0000, 0x0000
+};
+
+static leddef_t	cm41xx_def = {
+	0x0000, 0x0400, 0x0000, 0x0200,
+};
+
+static volatile unsigned int *ledman_gpio;
+
+static void ledman_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	volatile unsigned int *intstatp;
+
+	intstatp = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_INT_STATUS);
+	*intstatp |= 0x20;
+
+	ledman_signalreset();
+}
+
+static void cm41xx_set(unsigned long bits)
+{
+	*ledman_gpio = (*ledman_gpio & ~0x0600) | (~bits & 0x0600);
+}
+
+static void ledman_initarch(void)
+{
+	volatile unsigned int *gpiop, *intenp;
+
+	/* Enable LED lines as outputs (and GPIO3 as input) */
+	gpiop = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_MODE);
+	*gpiop = (*gpiop | 0x0600) & ~0x8;
+
+	/* Turn LEDs off */
+	ledman_gpio = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_DATA);
+	*ledman_gpio = (*ledman_gpio & ~0x0600);
+
+	/* Configure GPIO3 as interrupt input (ERASE switch) */
+	gpiop = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_CTRL);
+	*gpiop = (*gpiop & ~0xf000) | 0xc000;
+
+	intenp = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_INT_ENABLE);
+	*intenp |= 0x20;
+
+	if (request_irq(5, ledman_interrupt, SA_INTERRUPT, "Erase", NULL))
+		printk("LED: failed to register IRQ5 for ERASE witch\n");
+	else
+		printk("LED: registered ERASE switch on IRQ5\n");
+}
+
+/****************************************************************************/
+#endif /* CONFIG_MACH_CM41xx */
+/****************************************************************************/
+/****************************************************************************/
+#if defined(CONFIG_ARCH_EP9312)
+/****************************************************************************/
+
+#include <linux/interrupt.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+/*
+ *	Here is the definition of the LED's on the Trusonic IPD Board
+ *
+ *	It has no visible LED's, though it has provision for deug LED's,
+ *	however, we need flatfsd support ;-)
+ */
+static ledmap_t	ipd_std;
+static leddef_t	ipd_def;
+
+static void ipd_set(unsigned long bits)
+{
+}
+
+static void ledman_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	while (inl(VIC1RAWINTR) & 0x1)
+		;
+	ledman_signalreset();
+}
+
+static void ledman_initarch(void)
+{
+	if (request_irq(32, ledman_interrupt, SA_INTERRUPT, "Erase", NULL))
+		printk("LED: failed to register IRQ32 for ERASE witch\n");
+	else
+		printk("LED: registered ERASE switch on IRQ32\n");
+}
+
+/****************************************************************************/
+#endif /* CONFIG_ARCH_EP9312 */
+/****************************************************************************/
+#ifdef CONFIG_BD_TIBURON
+/****************************************************************************/
+
+/*
+ *	This is a dummy mapping as the Tiburon board uses one GPIO per LED
+ *
+ *	We simply count the LEDs on the front from the left to the right side,
+ *	i.e. we ignore the defined constants in ledman.h
+ *
+ *	Please note that the board has connections for 7 LEDs, but the shipped
+ *	device only has 4 LEDs connected; we support controlling all 7 LEDs,
+ *	there might be people who want to connect them
+ *
+ *	Also note that LED 1 (power) and LED 3/4 (ethernet 1 and 2) are
+ *	hardware controlled - we do count them but we ignore any request to
+ *	control them
+ *
+ *	LED 8 ist not actually a LED but the reset line for the internal modem;
+ *	if it is set, it will be automatically unset after 100 ms
+ */
+
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/gpio.h>
+
+static ledmap_t tiburon_std = {
+	0x04e, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004, 0x002, 0x001, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+	0x000, 0x000, 0x000, 0x000
+};
+
+static leddef_t	tiburon_def = {
+	0x000, 0x000, 0x04f, 0x000,
+};
+
+static void release_tiburon_modemreset(void)
+{
+	release_tiburon_modemreset_timerlist.expires = 0;
+	ledman_cmd(LEDMAN_CMD_OFF, 8);
+}
+
+static void tiburon_set(unsigned long bits)
+{
+	/* 0x80 = LED 1 = power - hardware controlled! */
+
+	/* 0x40 = LED 2 = modem */
+	if (bits & 0x40) {
+		WriteGPIOData(GPIO19, 0);
+	} else {
+		WriteGPIOData(GPIO19, 1);
+	}
+
+	/* 0x20 = LED 3 = ethernet 1 - hardware controlled! */
+
+	/* 0x10 = LED 4 = ethernet 2 - hardware controlled! */
+
+	/* 0x08 = LED 5 - not connected on the shipped device */
+	if (bits & 0x08) {
+		WriteGPIOData(GPIO7, 0);
+	} else {
+		WriteGPIOData(GPIO7, 1);
+	}
+
+	/* 0x04 = LED 6 - not connected on the shipped device */
+	if (bits & 0x04) {
+		WriteGPIOData(GPIO8, 0);
+	} else {
+		WriteGPIOData(GPIO8, 1);
+	}
+
+	/* 0x02 = LED 7 - not connected on the shipped device */
+	if (bits & 0x02) {
+		WriteGPIOData(GPIO18, 0);
+	} else {
+		WriteGPIOData(GPIO18, 1);
+	}
+
+	/* 0x01 = LED 8 = no actual LED, but modem reset */
+	if (bits & 0x01) {
+		WriteGPIOData(GPIO17, 0);
+		if (release_tiburon_modemreset_timerlist.expires==0) {
+			release_tiburon_modemreset_timerlist.expires = jiffies + HZ/10;
+			add_timer(&release_tiburon_modemreset_timerlist);
+		}
+	} else {
+		WriteGPIOData(GPIO17, 1);
+	}
+}
+
+static void ledman_initarch(void)
+{
+	release_tiburon_modemreset_timerlist.expires = 0;
+	release_tiburon_modemreset_timerlist.function = release_tiburon_modemreset;
+	release_tiburon_modemreset_timerlist.data = 0;
+}
+
+/****************************************************************************/
+#endif /* CONFIG_BD_TIBURON */
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/char/m41t11m6.c linux-2.4.29-uc1/drivers/char/m41t11m6.c
--- linux-2.4.29/drivers/char/m41t11m6.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/m41t11m6.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,528 @@
+/*****************************************************************************/
+
+/*
+ *	m41t11m6.c -- driver for M41T11M6 Real Time Clock.
+ *
+ * 	(C) Copyright 2004-2005, Greg Ungerer <gerg@snapgear.com>
+ */
+
+/*****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/module.h> 
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/rtc.h>
+#include <asm/hardware.h>
+#include <asm/uaccess.h>
+#include <asm/semaphore.h>
+
+/*****************************************************************************/
+
+/*
+ *	Size of RTC region. 64 bytes total, the first 10 are the RTC.
+ */
+#define	M41T11M6_MSIZE	0x3f
+
+/*****************************************************************************/
+
+/*
+ *	M41T11M6 defines.
+ */
+#define	M41T11M6_ADDR	0xd0		/* IIC address of M41T11M6 device */
+#define	M41T11M6_RD	1		/* Read bit command */
+#define	M41T11M6_WR	0		/* Write bit command */
+
+#define	M41T11M6_SEC	0x00		/* Address of second register */
+#define	M41T11M6_MIN	0x01		/* Address of minute register */
+#define	M41T11M6_HOUR	0x02		/* Address of hour register */
+#define	M41T11M6_WDAY	0x03		/* Address of day of week register */
+#define	M41T11M6_MDAY	0x04		/* Address of day of month register */
+#define	M41T11M6_MON	0x05		/* Address of month register */
+#define	M41T11M6_YEAR	0x06		/* Address of year register */
+#define	M41T11M6_FTOUT	0x07		/* Address of control register */
+
+/*****************************************************************************/
+#ifdef CONFIG_MACH_IPD
+/*****************************************************************************/
+
+#include <asm/io.h>
+
+/*
+ * On the EP9312/IPD,  the clock in on EGIO[1] and the data is on EGPIO[3]
+ */
+#define	SDA	0x8
+#define	SCL	0x2
+#define IN	0
+#define OUT	1
+
+static void gpio_line_config(int line, int dir)
+{
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	if (dir == OUT)
+		outl(inl(GPIO_PADDR) | line, GPIO_PADDR); /* data is output */
+	else
+		outl(inl(GPIO_PADDR) & ~line, GPIO_PADDR); /* data is input */
+	restore_flags(flags);
+}
+
+static void gpio_line_set(int line, int val)
+{
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	if (val)
+		outl(inl(GPIO_PADR) | line, GPIO_PADR);
+	else
+		outl(inl(GPIO_PADR) & ~line, GPIO_PADR);
+	restore_flags(flags);
+}
+
+static inline void gpio_line_get(int line, int *val)
+{
+	*val = (inl(GPIO_PADR) & line) ? 1 : 0;
+}
+
+/*****************************************************************************/
+#elif defined(CONFIG_MACH_CM41xx) || defined(CONFIG_MACH_CM4008)
+/*****************************************************************************/
+
+#include <asm/io.h>
+
+/*
+ *	GPIO lines 6, 7 and 8 are used for the RTC.
+ */
+#define	SDAT	6		/* SDA transmit */
+#define	SDAR	7		/* SDA receiver */
+#define	SCL	8		/* SCL - clock */
+#define	SDA	SDAR
+
+#define IN	0
+#define OUT	1
+
+#define	SDAT_B	(1 << SDAT)
+#define	SDAR_B	(1 << SDAR)
+#define	SCL_B	(1 << SCL)
+
+static volatile unsigned int *gpdatap = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_DATA);
+static volatile unsigned int *gpmodep = (volatile unsigned int *) (IO_ADDRESS(KS8695_IO_BASE) + KS8695_GPIO_MODE);
+
+static inline void gpio_line_config(int line, int dir)
+{
+	if (line == SDA) {
+		if (dir == IN)
+			*gpdatap |= SDAT_B;
+	}
+	if (line == SCL) {
+		/* We do normal initialization for all GPIO bits here */
+		*gpmodep |= SCL_B | SDAT_B;
+		*gpmodep &= ~SDAR_B;
+	}
+}
+
+static inline void gpio_line_set(int line, int val)
+{
+	if (line == SCL) {
+		if (val)
+			*gpdatap |= SCL_B;
+		else
+			*gpdatap &= ~SCL_B;
+	} else {
+		if (val)
+			*gpdatap |= SDAT_B;
+		else
+			*gpdatap &= ~SDAT_B;
+	}
+}
+
+static inline void gpio_line_get(int line, int *val)
+{
+	*val = (*gpdatap & SDAR_B) ? 1 : 0;
+}
+
+/*****************************************************************************/
+#else
+/*****************************************************************************/
+
+/*
+ *	The IIC lines to the M41T11M6 are GPIO lines from the IXP425.
+ *	The clock line is on GPIO12, and the data line on GPIO11.
+ */
+#define	SDA	IXP425_GPIO_PIN_11
+#define	SCL	IXP425_GPIO_PIN_12
+#define	IN	IXP425_GPIO_IN
+#define	OUT	IXP425_GPIO_OUT
+
+/*****************************************************************************/
+#endif
+/*****************************************************************************/
+
+static void gpio_line_config_slow(u8 line, u32 style)
+{
+	gpio_line_config(line, style);
+	udelay(10);
+}
+
+static void gpio_line_set_slow(u8 line, int value)
+{
+	gpio_line_set(line, value);
+	udelay(10);
+}
+
+static void gpio_line_get_slow(u8 line, int *value)
+{
+	gpio_line_get(line, value);
+	udelay(10);
+}
+
+/*****************************************************************************/
+
+void m41t11m6_readack(void)
+{
+	unsigned int ack;
+
+	gpio_line_config_slow(SDA, IN);
+	gpio_line_set_slow(SCL, 1);
+	gpio_line_get_slow(SDA, &ack);
+	gpio_line_set_slow(SCL, 0);
+	gpio_line_config_slow(SDA, OUT);
+}
+
+void m41t11m6_writeack(void)
+{
+	gpio_line_set_slow(SDA, 0);
+	gpio_line_set_slow(SCL, 1);
+	gpio_line_set_slow(SCL, 0);
+}
+
+void m41t11m6_sendbits(unsigned int val)
+{
+	int i;
+
+	gpio_line_set_slow(SCL, 0);
+	for (i = 7; (i >= 0); i--) {
+		gpio_line_set_slow(SDA, ((val >> i) & 0x1));
+		gpio_line_set_slow(SCL, 1);
+		gpio_line_set_slow(SCL, 0);
+	}
+}
+
+unsigned int m41t11m6_recvbits(void)
+{
+	unsigned int val, bit;
+	int i;
+
+	gpio_line_set_slow(SCL, 0);
+	gpio_line_config_slow(SDA, IN);
+	for (i = 0, val = 0; (i < 8); i++) {
+		gpio_line_set_slow(SCL, 1);
+		gpio_line_get_slow(SDA, &bit);
+		val = (val << 1) | bit;
+		gpio_line_set_slow(SCL, 0);
+	}
+
+	gpio_line_config_slow(SDA, OUT);
+	return val;
+}
+
+/*****************************************************************************/
+DECLARE_MUTEX(m41t11m6_sem);
+
+/* 
+ *	The read byte sequenece is actually a write sequence followed
+ *	by the read sequenece. The first write is to set the register
+ *	address, and is a complete cycle itself.
+ */
+unsigned int m41t11m6_readbyte(unsigned int addr)
+{
+	unsigned int val;
+
+	down(&m41t11m6_sem);
+#if 0
+	printk("m41t11m6_readbyte(addr=%x)\n", addr);
+#endif
+
+	/* Send start signal */
+	gpio_line_set_slow(SCL, 1);
+	gpio_line_set_slow(SDA, 1);
+	gpio_line_set_slow(SDA, 0);
+
+	/* Send M41T11M6 device address byte, and write command for addr */
+	m41t11m6_sendbits(M41T11M6_ADDR | M41T11M6_WR);
+	m41t11m6_readack();
+	m41t11m6_sendbits(addr);
+	m41t11m6_readack();
+
+	/* Now send sequence to read bytes, starting with start signal */
+	gpio_line_set_slow(SDA, 1);
+	gpio_line_set_slow(SCL, 1);
+	gpio_line_set_slow(SDA, 1);
+	gpio_line_set_slow(SDA, 0);
+
+	/* Send M41T11M6 device address byte, and read command for addr */
+	m41t11m6_sendbits(M41T11M6_ADDR | M41T11M6_RD);
+	m41t11m6_writeack();
+	val = m41t11m6_recvbits();
+
+	/* Send stop signal */
+	gpio_line_set_slow(SDA, 0);
+	gpio_line_set_slow(SCL, 1);
+	gpio_line_set_slow(SDA, 1);
+
+	up(&m41t11m6_sem);
+
+	return val;
+}
+
+void m41t11m6_writebyte(unsigned int addr, unsigned int val)
+{
+	down(&m41t11m6_sem);
+#if 0
+	printk("m41t11m6_writebyte(addr=%x)\n", addr);
+#endif
+
+	/* Send start signal */
+	gpio_line_set_slow(SCL, 1);
+	gpio_line_set_slow(SDA, 1);
+	gpio_line_set_slow(SDA, 0);
+
+	/* Send M41T11M6 device address byte, and write command */
+	m41t11m6_sendbits(M41T11M6_ADDR | M41T11M6_WR);
+	m41t11m6_readack();
+
+	/* Send word address and data to write */
+	m41t11m6_sendbits(addr);
+	m41t11m6_readack();
+	m41t11m6_sendbits(val);
+	m41t11m6_readack();
+
+	/* Send stop signal */
+	gpio_line_set_slow(SDA, 0);
+	gpio_line_set_slow(SCL, 1);
+	gpio_line_set_slow(SDA, 1);
+
+	up(&m41t11m6_sem);
+}
+
+/*****************************************************************************/
+
+void m41t11m6_setup(void)
+{
+	down(&m41t11m6_sem);
+
+	/* Initially set the IIC lines to be outputs from the IXP425 */
+	gpio_line_config(SCL, OUT);
+	gpio_line_config(SDA, OUT);
+
+	/* Set IIC bus into idle mode */
+	gpio_line_set(SCL, 1);
+	gpio_line_set(SDA, 1);
+
+	up(&m41t11m6_sem);
+}
+
+/*****************************************************************************/
+
+int bcd2bin(int val)
+{
+	return ((((val & 0xf0) >> 4) * 10) + (val & 0xf));
+}
+
+int bin2bcd(int val)
+{
+	val &= 0xff;
+	return (((val / 10) << 4) + (val % 10));
+}
+
+/*****************************************************************************/
+
+static ssize_t m41t11m6_read(struct file *fp, char *buf, size_t count, loff_t *ptr)
+{
+	int total;
+
+#if 0
+	printk("m41t11m6_read(buf=%x,count=%d)\n", (int) buf, count);
+#endif
+
+	if (fp->f_pos >= M41T11M6_MSIZE)
+		return 0;
+
+	if (count > (M41T11M6_MSIZE - fp->f_pos))
+		count = M41T11M6_MSIZE - fp->f_pos;
+
+	for (total = 0; (total < count); total++)
+		put_user(m41t11m6_readbyte(fp->f_pos + total), buf++);
+
+	fp->f_pos += total;
+	return total;
+}
+
+/*****************************************************************************/
+
+static ssize_t m41t11m6_write(struct file *fp, const char *buf, size_t count, loff_t *ptr)
+{
+	int total;
+	char val;
+
+#if 0
+	printk("m41t11m6_write(buf=%x,count=%d)\n", (int) buf, count);
+#endif
+
+	if (fp->f_pos >= M41T11M6_MSIZE)
+		return 0;
+
+	if (count > (M41T11M6_MSIZE - fp->f_pos))
+		count = M41T11M6_MSIZE - fp->f_pos;
+
+	for (total = 0; (total < count); total++, buf++) {
+		get_user(val,buf);
+		m41t11m6_writebyte((fp->f_pos + total), val);
+	}
+
+	fp->f_pos += total;
+	return total;
+}
+
+/*****************************************************************************/
+
+/*
+ *	Do some consistency checks on the time. On first power up the
+ *	RTC may contain completely bogus junk, this will clean it up.
+ *	Just for good measure we do this when writing to the RTC as well.
+ */
+
+static void m41t11m6_validatetime(struct rtc_time *rtime)
+{
+	if ((rtime->tm_year < 70) || (rtime->tm_year >= 200))
+		rtime->tm_year = 70;
+	if ((rtime->tm_mon < 0) || (rtime->tm_mon >= 12))
+		rtime->tm_mon = 0;
+	if ((rtime->tm_mday < 1) || (rtime->tm_mday > 31))
+		rtime->tm_mday = 1;
+	if ((rtime->tm_wday < 0) || (rtime->tm_wday >= 7))
+		rtime->tm_wday = 0;
+	if ((rtime->tm_hour < 0) || (rtime->tm_hour >= 24))
+		rtime->tm_hour = 0;
+	if ((rtime->tm_min < 0) || (rtime->tm_min >= 60))
+		rtime->tm_min = 0;
+	if ((rtime->tm_sec < 0) || (rtime->tm_sec >= 60))
+		rtime->tm_sec = 0;
+}
+
+/*****************************************************************************/
+
+static void m41t11m6_readtime(struct rtc_time *rtime)
+{
+	memset(rtime, 0, sizeof(*rtime));
+	rtime->tm_year = bcd2bin(m41t11m6_readbyte(M41T11M6_YEAR)) +
+		((m41t11m6_readbyte(M41T11M6_HOUR) & 0x40) ? 100 : 0);
+	rtime->tm_mon = bcd2bin(m41t11m6_readbyte(M41T11M6_MON & 0x1f)) - 1;
+	rtime->tm_mday = bcd2bin(m41t11m6_readbyte(M41T11M6_MDAY & 0x3f));
+	rtime->tm_wday = bcd2bin(m41t11m6_readbyte(M41T11M6_WDAY) & 0x7) - 1;
+	rtime->tm_hour = bcd2bin(m41t11m6_readbyte(M41T11M6_HOUR) & 0x3f);
+	rtime->tm_min = bcd2bin(m41t11m6_readbyte(M41T11M6_MIN) & 0x7f);
+	rtime->tm_sec = bcd2bin(m41t11m6_readbyte(M41T11M6_SEC) & 0x7f);
+}
+
+/*****************************************************************************/
+
+static void m41t11m6_settime(struct rtc_time *rtime)
+{
+	m41t11m6_writebyte(M41T11M6_YEAR, bin2bcd(rtime->tm_year));
+	m41t11m6_writebyte(M41T11M6_MON, bin2bcd(rtime->tm_mon+1));
+	m41t11m6_writebyte(M41T11M6_MDAY, bin2bcd(rtime->tm_mday));
+	m41t11m6_writebyte(M41T11M6_WDAY, bin2bcd(rtime->tm_wday+1));
+	m41t11m6_writebyte(M41T11M6_HOUR, bin2bcd(rtime->tm_hour) |
+		((rtime->tm_year > 99) ? 0xc0 : 0x80));
+	m41t11m6_writebyte(M41T11M6_MIN, bin2bcd(rtime->tm_min));
+	m41t11m6_writebyte(M41T11M6_SEC, bin2bcd(rtime->tm_sec));
+	m41t11m6_writebyte(M41T11M6_FTOUT, 0x90);
+}
+
+/*****************************************************************************/
+
+static int m41t11m6_ioctl(struct inode *inode, struct file *file, unsigned cmd, unsigned long arg)
+{
+	struct rtc_time rtime;
+
+#if 0
+	printk("m41t11m6_ioctl(cmd=%x,arg=%x)\n", cmd, arg);
+#endif
+
+	switch (cmd) {
+
+	case RTC_RD_TIME:
+		m41t11m6_readtime(&rtime);
+		m41t11m6_validatetime(&rtime);
+		if (copy_to_user((void *) arg, &rtime, sizeof(rtime)))
+			return -EFAULT;
+		break;
+
+	case RTC_SET_TIME:
+		if (!capable(CAP_SYS_TIME))
+			return -EACCES;
+		m41t11m6_validatetime(&rtime);
+		if (copy_from_user(&rtime, (void *) arg, sizeof(rtime)))
+			return -EFAULT;
+		m41t11m6_settime(&rtime);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*****************************************************************************/
+
+/*
+ *	Exported file operations structure for driver...
+ */
+static struct file_operations m41t11m6_fops =
+{
+	.owner = THIS_MODULE, 
+	.read =  m41t11m6_read,
+	.write = m41t11m6_write,
+	.ioctl = m41t11m6_ioctl,
+};
+
+static struct miscdevice m41t11m6_dev =
+{
+	RTC_MINOR,
+	"rtc",
+	&m41t11m6_fops
+};
+
+/*****************************************************************************/
+
+static int __init m41t11m6_init(void)
+{
+	m41t11m6_setup();
+	misc_register(&m41t11m6_dev);
+	printk ("M41T11M6: Real Time Clock driver\n");
+	return 0;
+}
+
+static void __exit m41t11m6_exit(void)
+{
+	misc_deregister(&m41t11m6_dev);
+}
+
+/*****************************************************************************/
+
+module_init(m41t11m6_init);
+module_exit(m41t11m6_exit);
+
+MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>");
+MODULE_LICENSE("GPL");
+
+/*****************************************************************************/
diff -urN linux-2.4.29/drivers/char/m5249audio.c linux-2.4.29-uc1/drivers/char/m5249audio.c
--- linux-2.4.29/drivers/char/m5249audio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/m5249audio.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,677 @@
+/****************************************************************************/
+
+/*
+ *	m5249audio.c -- audio driver for M5249 ColdFire internal audio.
+ *
+ *	(C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/major.h>
+#include <linux/delay.h>
+#include <linux/soundcard.h>
+#include <asm/uaccess.h>
+#include <asm/param.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+#include <asm/m5249audio.h>
+
+/****************************************************************************/
+
+/*
+ *	Hardware configuration.
+ */
+#define	M5249AUDIO_TXIRQ	131	/* Audio TX FIFO IRQ */
+#define	M5249AUDIO_DMAIRQ	120	/* Audio TX DMA IRQ */
+#define	M5249AUDIO_DMA		0	/* Audio TX DMA channel */
+
+/*
+ *	You can choose to use either interrupt or DMA here.
+ *	DMA will give you much better CPU utilitization...
+ */
+//#define CONFIG_AUDIOIRQ	1
+#define CONFIG_AUDIODMA	1
+
+/****************************************************************************/
+
+/*
+ *	Driver configurable settings.
+ */
+#define	BUFSIZE		(256*1024)	/* Audio buffer data size */
+#define	DMASIZE		56000		/* DMA buffer maximum size */
+
+/*
+ *	Driver settings and state.
+ */
+int		m5249audio_isopen;
+int		m5249audio_txbusy;
+int		m5249audio_dmaing;
+unsigned int	m5249audio_speed;
+unsigned int	m5249audio_stereo;
+unsigned int	m5249audio_bits;
+unsigned int	m5249audio_format;
+unsigned long	m5249audio_imrbit;
+
+/*
+ *	Circular buffer for audio data. It is broken up into 2 regions.
+ *	The first is the current portion of the buffer being DMA'ed right
+ *	now. The other is data waiting to be DMA'ed.
+ */
+unsigned char		*m5249audio_buf;
+volatile unsigned int	m5249audio_dmastart;
+volatile unsigned int	m5249audio_dmacount;
+volatile unsigned int	m5249audio_appstart;
+volatile unsigned int	m5249audio_append;
+
+/****************************************************************************/
+
+/*
+ *	Quick and easy access to the audio registers. (This optimizes
+ *	nicely, since it will almost always be a constant pointer).
+ */
+#define	reg32p(r)	((volatile unsigned long *) (MCF_MBAR2 + (r)))
+#define	reg16w(r)	((volatile unsigned short *) (MCF_MBAR2 + (r)))
+#define	reg8p(r)	((volatile unsigned char *) (MCF_MBAR2 + (r)))
+
+/*
+ *	Quick and easy access to the SIM registers.
+ */
+#define	simp(r)	((volatile unsigned char *) (MCF_MBAR + (r)))
+
+/****************************************************************************/
+
+void m5249audio_chipinit(void)
+{
+#if DEBUG
+	printk("m5249audio_chipinit()\n");
+#endif
+
+	*reg32p(MCFA_IIS2CONFIG) = MCFA_IIS_CLK8 | MCFA_IIS_TXSRC_PDOR3 |
+		MCFA_IIS_16BIT | MCFA_IIS_MODE_IIS | MCFA_IIS_LRCK32BIT;
+	*reg32p(MCFA_DATAINCTRL) = 0;
+}
+
+/****************************************************************************/
+
+struct m5249audio_format {
+	unsigned int	format;
+	unsigned int	bits;
+} m5249audio_formattable[] = {
+	{ AFMT_MU_LAW,		8 },
+	{ AFMT_A_LAW,		8 },
+	{ AFMT_IMA_ADPCM,	8 },
+	{ AFMT_U8,		8 },
+	{ AFMT_S16_LE,		16 },
+	{ AFMT_S16_BE,		16 },
+	{ AFMT_S8,		8 },
+	{ AFMT_U16_LE,		16 },
+	{ AFMT_U16_BE,		16 },
+};
+
+#define	FORMATSIZE	(sizeof(m5249audio_formattable) / sizeof(struct m5249audio_format))
+
+
+void m5249audio_setsamplesize(int val)
+{
+	int	i;
+
+	for (i = 0; (i < FORMATSIZE); i++) {
+		if (m5249audio_formattable[i].format == val) {
+			m5249audio_format = m5249audio_formattable[i].format;
+			m5249audio_bits = m5249audio_formattable[i].bits;
+			break;
+		}
+	}
+}
+
+/****************************************************************************/
+
+/*
+ *	Mute the audio signal output.
+ */
+
+void m5249audio_mute(void)
+{
+	*reg32p(MCFSIM2_GPIO1WRITE) &= ~0x00020000;
+}
+
+/****************************************************************************/
+
+/*
+ *	Unmute the audio output (let the sound out :-)
+ */
+
+void m5249audio_unmute(void)
+{
+	*reg32p(MCFSIM2_GPIO1WRITE) |= 0x00020000;
+}
+
+/****************************************************************************/
+
+/*
+ *	I have coded 2 routines for the interrupt driven case. The first
+ *	here is all assembler, and is pretty damn quick. The second is
+ *	C based, slower, not as good, really just for reference.
+ */
+
+#define	CONFIG_AUDIOIRQASM	1
+
+#ifdef CONFIG_AUDIOIRQ
+#ifdef CONFIG_AUDIOIRQASM
+
+extern void m5249audio_isr(int irq, void *dev_id, struct pt_regs *regs);
+
+void m5249audio_irqwrapper(void)
+{
+	__asm__(
+"		.global	m5249audio_isr\n"
+"		m5249audio_isr:\n"
+"			sub.l	#20, %sp\n"
+"			movem.l	%d0-%d2/%a0-%a1, %sp@	/* Save registers */\n"
+"\n"
+"			move.l	m5249audio_buf, %a0	/* Loop setup */\n"
+"			move.l	m5249audio_dmastart, %d0\n"
+"			move.l	#0x80000074, %a1\n"
+"			moveq	#5, %d2\n"
+"\n"
+"		m5249audio_isr_writefifo:\n"
+"			move.l	%a0@(%d0), %d1		/* Get next word */\n"
+"			move.l	%d1, %a1@		/* Write word to FIFO */\n"
+"			add.l	#4, %d0			/* Update buffer */\n"
+"			cmp.l	#(256*1024-4), %d0\n"
+"			blt	m5249audio_isr_nowrap\n"
+"			clr.l	%d0			/* Wrap buffer */\n"
+"		m5249audio_isr_nowrap:\n"
+"			cmp.l	m5249audio_append, %d0\n"
+"			beq	m5249audio_isr_txdisable\n"
+"			sub.l	#1, %d2			/* Loop counter */\n"
+"			bne	m5249audio_isr_writefifo\n"
+"\n"
+"		m5249audio_isr_done:\n"
+"			move.l	%d0, m5249audio_dmastart\n"
+"			movem.l	%sp@, %d0-%d2/%a0-%a1	/* Restore registers */\n"
+"			add.l	#20, %sp\n"
+"			rte\n"
+"\n"
+"		m5249audio_isr_txdisable:\n"
+"			move.l	#0x80000094, %a0	/* Disable interrupt */\n"
+"			move.l	%a0@, %d1\n"
+"			and.l	#0xfffffff7, %d1\n"
+"			move.l	%d1, %a0@\n"
+"			clr.l	m5249audio_txbusy\n"
+"			bra	m5249audio_isr_done\n"
+	);
+}
+
+#else
+
+void m5249audio_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long	*bp;
+
+#if DEBUG
+	printk("m5249audio_isr(irq=%d)", irq);
+#endif
+
+	if (m5249audio_dmastart == m5249audio_append) {
+		*reg32p(MCFA_INTENABLE) &= ~0x00000008;
+		m5249audio_txbusy = 0;
+	} else {
+		bp = (unsigned long *) &m5249audio_buf[m5249audio_dmastart];
+		*reg32p(MCFA_PDOR3) = *bp;
+		m5249audio_dmastart += 4;
+		if (m5249audio_dmastart >= BUFSIZE)
+			m5249audio_dmastart = 0;
+	}
+}
+
+#endif  /* CONFIG_AUDIOIRQASM */
+#endif	/* CONFIG_AUDIOIRQ */
+
+/****************************************************************************/
+
+#ifdef CONFIG_AUDIODMA
+
+/*
+ *	Configure and start DMA engine.
+ */
+void __inline__ m5249audio_dmarun(void)
+{
+#if DEBUG
+	printk("m5249audio_dmarun(): dma=%x count=%d\n",
+		m5249audio_dmastart, m5249audio_dmacount);
+#endif
+
+	set_dma_mode(M5249AUDIO_DMA, DMA_MODE_WRITE|DMA_MODE_LONG_BIT);
+	set_dma_device_addr(M5249AUDIO_DMA, (MCF_MBAR2+MCFA_PDOR3));
+	set_dma_addr(M5249AUDIO_DMA, (int)&m5249audio_buf[m5249audio_dmastart]);
+	set_dma_count(M5249AUDIO_DMA, m5249audio_dmacount);
+	m5249audio_dmaing = 1;
+	m5249audio_txbusy = 1;
+	enable_dma(M5249AUDIO_DMA);
+}
+
+/*
+ *	Start DMA'ing a new buffer of data if any available.
+ */
+void m5249audio_dmabuf(void)
+{
+#if DEBUG
+	printk("m5249audio_dmabuf()\n");
+#endif
+
+	/* If already running then nothing to do... */
+	if (m5249audio_dmaing)
+		return;
+
+	/* Set DMA buffer size */
+	m5249audio_dmacount = (m5249audio_append >= m5249audio_appstart) ?
+		(m5249audio_append - m5249audio_appstart) :
+		(BUFSIZE - m5249audio_appstart);
+	if (m5249audio_dmacount > DMASIZE)
+		m5249audio_dmacount = DMASIZE;
+
+	/* Adjust pointers and counters accordingly */
+	m5249audio_appstart += m5249audio_dmacount;
+	if (m5249audio_appstart >= BUFSIZE)
+		m5249audio_appstart = 0;
+
+	if (m5249audio_dmacount > 0)
+		m5249audio_dmarun();
+	else
+		m5249audio_txbusy = 0;
+}
+
+
+/*
+ *	Interrupt from DMA engine.
+ */
+void m5249audio_dmaisr(int irq, void *dev_id, struct pt_regs *regs)
+{
+#if DEBUG
+	printk("m5249audio_dmaisr(irq=%d)", irq);
+#endif
+
+	/* Clear DMA interrupt */
+	disable_dma(M5249AUDIO_DMA);
+	m5249audio_dmaing = 0;
+
+	/* Update data pointers and counts */
+	m5249audio_dmastart += m5249audio_dmacount;
+	if (m5249audio_dmastart >= BUFSIZE)
+		m5249audio_dmastart = 0;
+	m5249audio_dmacount = 0;
+
+	/* Start new DMA buffer if we can */
+	m5249audio_dmabuf();
+}
+
+#endif	/* CONFIG_AUDIODMA */
+
+/****************************************************************************/
+
+void m5249audio_txdrain(void)
+{
+#ifdef DEBUG
+	printk("m5249audio_txdrain()\n");
+#endif
+
+	while (!signal_pending(current)) {
+		if (m5249audio_txbusy == 0)
+			break;
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(1);
+	}
+}
+
+/****************************************************************************/
+
+int m5249audio_open(struct inode *inode, struct file *filp)
+{
+#if DEBUG
+	printk("m5249audio_open()\n");
+#endif
+
+	if (m5249audio_isopen)
+		return(-EBUSY);
+
+	/* Set initial driver playback defaults. */
+	m5249audio_speed = 44100;
+	m5249audio_format = AFMT_S16_BE;
+	m5249audio_bits = 16;
+	m5249audio_stereo = 1;
+	m5249audio_isopen = 1;
+	m5249audio_unmute();
+
+	return(0);
+}
+
+/****************************************************************************/
+
+int m5249audio_close(struct inode *inode, struct file *filp)
+{
+#if DEBUG
+	printk("m5249audio_close()\n");
+#endif
+
+	m5249audio_txdrain();
+	m5249audio_mute();
+
+#ifdef CONFIG_AUDIOIRQ
+	*reg32p(MCFA_INTENABLE) &= ~0x00000008;
+#endif
+#ifdef CONFIG_AUDIODMA
+	disable_dma(M5249AUDIO_DMA);
+	m5249audio_dmaing = 0;
+#endif
+
+	m5249audio_txbusy = 0;
+	m5249audio_dmastart = 0;
+	m5249audio_dmacount = 0;
+	m5249audio_appstart = 0;
+	m5249audio_append = 0;
+	m5249audio_isopen = 0;
+	return(0);
+}
+
+/****************************************************************************/
+
+ssize_t m5249audio_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
+{
+	unsigned long	*dp, *buflp;
+	unsigned short	*bufwp;
+	unsigned char	*bufbp;
+	unsigned int	slen, bufcnt, i, s, e;
+
+#ifdef DEBUG
+	printk("m5249_write(buf=%x,count=%d)\n", (int) buf, count);
+#endif
+
+	if (count <= 0)
+		return(0);
+
+	buflp = (unsigned long *) buf;
+	bufwp = (unsigned short *) buf;
+	bufbp = (unsigned char *) buf;
+
+	bufcnt = count & ~0x3;
+	if (m5249audio_stereo == 0)
+		bufcnt <<= 1;
+	if (m5249audio_bits == 8)
+		bufcnt <<= 1;
+
+tryagain:
+	/*
+	 *	Get a snapshot of buffer, so we can figure out how
+	 *	much data we can fit in...
+	 */
+	s = m5249audio_dmastart;
+	e = m5249audio_append;
+	dp = (unsigned long *) &m5249audio_buf[e];
+
+	slen = ((s > e) ? (s - e) : (BUFSIZE - (e - s))) - 4;
+	if (slen > bufcnt)
+		slen = bufcnt;
+	if ((BUFSIZE - e) < slen)
+		slen = BUFSIZE - e;
+
+	if (slen == 0) {
+		if (signal_pending(current))
+			return(-ERESTARTSYS);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
+		goto tryagain;
+	}
+
+	if (m5249audio_stereo) {
+		if (m5249audio_bits == 16) {
+			for (i = 0; (i < slen); i += 4)
+				*dp++ = *buflp++;
+		} else {
+			for (i = 0; (i < slen); i += 4) {
+				*dp    = (((unsigned long) *bufbp++) << 24);
+				*dp++ |= (((unsigned long) *bufbp++) << 8);
+			}
+		}
+	} else {
+		if (m5249audio_bits == 16) {
+			for (i = 0; (i < slen); i += 4) {
+				*dp++ = (((unsigned long)*bufwp)<<16) | *bufwp;
+				bufwp++;
+			}
+		} else {
+			for (i = 0; (i < slen); i += 4) {
+				*dp++ = (((unsigned long) *bufbp) << 24) | 
+					(((unsigned long) *bufbp) << 8);
+				bufbp++;
+			}
+		}
+	}
+
+	e += slen;
+	if (e >= BUFSIZE)
+		e = 0;
+	m5249audio_append = e;
+
+#ifdef CONFIG_AUDIOIRQ
+	/* If not outputing audio, then start now */
+	if (m5249audio_txbusy == 0) {
+		m5249audio_txbusy++;
+		*reg32p(MCFA_INTENABLE) |= 0x00000008;
+		/* Dummy write to start output interrupts */
+		*reg32p(MCFA_PDOR3) = 0;
+	}
+#endif
+#ifdef CONFIG_AUDIODMA
+	m5249audio_dmabuf();
+#endif
+
+	bufcnt -= slen;
+	if (bufcnt > 0)
+		goto tryagain;
+
+	return(count);
+}
+
+/****************************************************************************/
+
+int m5249audio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	long	val;
+	int	rc = 0;
+
+#ifdef DEBUG
+        printk("m5249audio_ioctl(cmd=%x,arg=%x)\n", (int) cmd, (int) arg);
+#endif
+
+	switch (cmd) {
+
+	case SNDCTL_DSP_SPEED:
+		rc = verify_area(VERIFY_READ, (void *) arg, sizeof(val));
+		if (rc == 0) {
+			get_user(val, (unsigned long *) arg);
+			m5249audio_txdrain();
+			m5249audio_speed = val;
+			/* FIXME: adjust replay speed?? */
+		}
+		break;
+
+	case SNDCTL_DSP_SAMPLESIZE:
+		rc = verify_area(VERIFY_READ, (void *) arg, sizeof(val));
+		if (rc == 0) {
+			get_user(val, (unsigned long *) arg);
+			m5249audio_txdrain();
+			m5249audio_setsamplesize(val);
+		}
+		break;
+
+	case SNDCTL_DSP_STEREO:
+		rc = verify_area(VERIFY_READ, (void *) arg, sizeof(val));
+		if (rc == 0) {
+			get_user(val, (unsigned long *) arg);
+			m5249audio_txdrain();
+			m5249audio_stereo = val;
+		}
+		break;
+
+	case SNDCTL_DSP_GETBLKSIZE:
+		rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
+		if (rc == 0)
+			put_user(DMASIZE, (long *) arg);
+		break;
+
+	case SNDCTL_DSP_SYNC:
+		m5249audio_txdrain();
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return(rc);
+}
+
+/****************************************************************************/
+
+struct file_operations	m5249audio_fops = {
+	open: m5249audio_open,		/* open */
+	release: m5249audio_close,	/* release */
+	write: m5249audio_write,	/* write */
+	ioctl: m5249audio_ioctl,	/* ioctl */
+};
+
+/****************************************************************************/
+
+#ifdef CONFIG_AUDIOIRQ
+
+void m5249audio_getallintrs(void)
+{
+	int	i, rc;
+
+	for (i = 128; (i < 160); i++) {
+		rc = request_irq(i, m5249audio_isr, SA_INTERRUPT, "audio", NULL);
+		if (rc)
+			printk("M5249AUDIO: IRQ %d already in use?\n", i);
+	}
+
+	/* Enable all audio interrupts... */
+	*((volatile unsigned long *) (MCF_MBAR2 + 0x140)) = 0x33333333;
+	*((volatile unsigned long *) (MCF_MBAR2 + 0x144)) = 0x33333333;
+	*((volatile unsigned long *) (MCF_MBAR2 + 0x148)) = 0x33333333;
+	*((volatile unsigned long *) (MCF_MBAR2 + 0x14c)) = 0x33333333;
+}
+
+#endif
+
+/****************************************************************************/
+
+static int __init m5249audio_init(void)
+{
+	printk("M5249AUDIO: (C) Copyright 2002, "
+		"Greg Ungerer (gerg@snapgear.com)\n");
+
+	if (register_chrdev(SOUND_MAJOR, "sound", &m5249audio_fops) < 0) {
+		printk(KERN_WARNING "SOUND: failed to register major %d\n",
+			SOUND_MAJOR);
+		return(0);
+	}
+
+	m5249audio_buf = kmalloc(BUFSIZE, GFP_KERNEL);
+	if (m5249audio_buf == NULL) {
+		printk("M5249AUDIO: failed to allocate DMA[%d] buffer\n",
+			BUFSIZE);
+	}
+
+#ifdef CONFIG_AUDIOIRQ
+#ifdef CONFIG_AUDIOIRQASM
+	/* Install fast interrupt handler */
+	printk("M5249AUDIO: fast interrupt handler irq=%d\n",
+		M5249AUDIO_TXIRQ);
+	*((unsigned long *) (M5249AUDIO_TXIRQ * 4)) =
+		(unsigned long) m5249audio_isr;
+#else
+	/* Re-direct TX empty FIFO audio interrupt. */
+	printk("M5249AUDIO: standard interrupt handler, irq=%d\n",
+		M5249AUDIO_TXIRQ);
+	if (request_irq(M5249AUDIO_TXIRQ, m5249audio_isr,
+	    (SA_INTERRUPT | IRQ_FLG_FAST), "audio", NULL)) {
+		printk("M5249AUDIO: IRQ %d already in use?\n",
+			M5249AUDIO_TXIRQ);
+	}
+#endif
+	*reg32p(0x140) = 0x00007000;
+#endif
+#ifdef CONFIG_AUDIODMA
+{
+	volatile unsigned char *dmap;
+	unsigned int		icr;
+
+	printk("M5249AUDIO: DMA channel=%d, irq=%d\n",
+		M5249AUDIO_DMA, M5249AUDIO_DMAIRQ);
+	if (request_irq(M5249AUDIO_DMAIRQ, m5249audio_dmaisr,
+	    (SA_INTERRUPT | IRQ_FLG_FAST), "audio(DMA)", NULL)) {
+		printk("M5249AUDIO: DMA IRQ %d already in use?\n", 
+			M5249AUDIO_DMAIRQ);
+	}
+
+	dmap = (volatile unsigned char *) dma_base_addr[M5249AUDIO_DMA];
+	dmap[MCFDMA_DIVR] = M5249AUDIO_DMAIRQ;
+
+	/* Set interrupt level and priority */
+	switch (M5249AUDIO_DMA) {
+	case 1:  icr=MCFSIM_DMA1ICR; m5249audio_imrbit=MCFSIM_IMR_DMA1; break;
+	case 2:  icr=MCFSIM_DMA2ICR; m5249audio_imrbit=MCFSIM_IMR_DMA2; break;
+	case 3:  icr=MCFSIM_DMA3ICR; m5249audio_imrbit=MCFSIM_IMR_DMA3; break;
+	default: icr=MCFSIM_DMA0ICR; m5249audio_imrbit=MCFSIM_IMR_DMA0; break;
+	}
+
+	*simp(icr) = MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3;
+	mcf_setimr(mcf_getimr() & ~m5249audio_imrbit);
+
+	/* Set DMA to use channel 0 for audio */
+	*reg8p(MCFA_DMACONF) = MCFA_DMA_0REQ;
+	*reg32p(MCFSIM2_DMAROUTE) = 0x00000080;
+
+	if (request_dma(M5249AUDIO_DMA, "audio")) {
+		printk("M5249AUDIO: DMA channel %d already in use?\n",
+			M5249AUDIO_DMA);
+	}
+}
+#endif
+
+	/* Unmute the DAC, set GPIO49 */
+	*reg32p(MCFSIM2_GPIO1FUNC) |= 0x00020000;
+	*reg32p(MCFSIM2_GPIO1ENABLE) |= 0x00020000;
+	m5249audio_unmute();
+
+	/* Power up the DAC, set GPIO39 */
+	*reg32p(MCFSIM2_GPIO1FUNC) |= 0x00000080;
+	*reg32p(MCFSIM2_GPIO1ENABLE) |= 0x00000080;
+	*reg32p(MCFSIM2_GPIO1WRITE) |= 0x00000080;
+
+	m5249audio_chipinit();
+
+	/* Dummy write to start outputing */
+	*reg32p(MCFA_PDOR3) = 0;
+
+	return(0);
+}
+
+module_init(m5249audio_init);
+
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/char/m5272audio.c linux-2.4.29-uc1/drivers/char/m5272audio.c
--- linux-2.4.29/drivers/char/m5272audio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/m5272audio.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,494 @@
+/****************************************************************************/
+
+/*
+ *      m5272audio.c (c) 2003 Frieder Ferlemann
+ *
+ *      Derived from:
+ *      m5249audio.c by Greg Ungerer and
+ *      pwm328.c by David Beckemeyer
+ */
+
+/****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/wait.h>
+#include <linux/soundcard.h>
+#include <asm/param.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcftimer.h>
+
+/****************************************************************************/
+
+MODULE_AUTHOR("Frieder Ferlemann <f.ferlemann@identecsolutions.de>");
+MODULE_DESCRIPTION("Driver for 8 bit PWM audio");
+MODULE_SUPPORTED_DEVICE("Motorola MCF5272");
+MODULE_LICENSE("GPL");
+
+EXPORT_NO_SYMBOLS;
+
+/****************************************************************************/
+
+#define NAME "m5272audio"
+
+/* register defines (should have been available from m5272sim.h) */
+#define MCFSIM_PWCR0	(0xc0)
+#define MCFSIM_PWWD0	(0xd0)
+#define MCFSIM_TMR0	(0x200)
+#define MCFSIM_TRR0	(0x204)
+#define MCFSIM_TCN0	(0x20C)
+#define MCFSIM_TER0	(0x210)
+
+/* register defaults */
+#define TMR_RESET	(0)
+#define TMR_DEFAULT	(((125-1)<<8) | 0x0b)
+#define PWCR_DEFAULT	(0x21)
+
+//#define DEBUG_M5272AUDIO_ISR
+//#define DEBUG_M5272AUDIO_ISR2
+//#define DEBUG_M5272AUDIO_OPEN_CLOSE
+//#define DEBUG_M5272AUDIO_TXDRAIN
+//#define DEBUG_M5272AUDIO_WRITE
+//#define DEBUG_M5272AUDIO_BUF
+//#define DEBUG_IOCTL
+
+/****************************************************************************/
+/*
+ * 	Resources used
+ */
+
+#define	M5272AUDIO_BUFSIZE	(0x1000)
+#define PWM_CHANNEL	(1)
+#define TIMER_NUMBER	(0)
+
+#define IRQ		(69+TIMER_NUMBER)
+/* you'll probably need 7 for glitchless audio */
+#define IRQ_PRIORITY	(6)
+
+/****************************************************************************/
+/*
+ *      Quick and easy access to the registers. (This optimizes
+ *      nicely, since it will almost always be a constant pointer).
+ */
+#define reg32p(r)       ((volatile unsigned long *) (MCF_MBAR + (r)))
+#define reg16p(r)       ((volatile unsigned short *) (MCF_MBAR + (r)))
+#define reg8p(r)        ((volatile unsigned char *) (MCF_MBAR + (r)))
+
+/****************************************************************************/
+
+unsigned char		m5272audio_buf[M5272AUDIO_BUFSIZE];
+
+volatile unsigned int	m5272audio_start;
+volatile unsigned int	m5272audio_append;
+volatile unsigned int	m5272audio_txbusy;
+
+unsigned int		m5272audio_isopen;
+unsigned int	  	resource_count;
+
+/****************************************************************************/
+
+DECLARE_WAIT_QUEUE_HEAD( m5272audio_waitchan );
+
+/****************************************************************************/
+
+struct m5272audio_format {
+        unsigned int    format;
+        unsigned int    bits;
+} m5272audio_formattable[] = {
+        { AFMT_U8, 	8 }
+};
+
+#define FORMATSIZE      (sizeof(m5272audio_formattable) / sizeof(struct m5272audio_format))
+
+int m5272audio_setsamplesize(int val)
+{
+        int     i;
+
+        for (i = 0; (i < FORMATSIZE); i++) {
+                if (m5272audio_formattable[i].format == val) {
+                        return 0;
+                }
+        }
+	return -EINVAL;
+}
+
+/****************************************************************************/
+
+void inline timer_init(void)
+{
+	/* Initialize timer */
+        *reg16p( MCFSIM_TRR0 + TIMER_NUMBER * 0x20 ) = 32; 	// 66MHz/(33*125) = 16kHz
+        *reg16p( MCFSIM_TMR0 + TIMER_NUMBER * 0x20 ) = TMR_DEFAULT; 
+}
+
+/****************************************************************************/
+
+void inline timer_interrupt_init(void)
+{
+        int flags;
+      	uint16_t t;
+	
+	save_flags(flags); cli();
+        
+	t= *reg16p( 2 + MCFSIM_ICR1 ); 
+	t = (t & 0x7777 & ~(0xf000>>TIMER_NUMBER*4)) | ( (0x8000 | (IRQ_PRIORITY<<12) )>>TIMER_NUMBER*4);
+	*reg16p( 2 + MCFSIM_ICR1 ) = t; 
+	
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+
+void inline timer_interrupt_exit(void)
+{
+        int flags;
+      	uint16_t t;
+	
+	save_flags(flags); cli();
+        
+	t = *reg16p( 2 + MCFSIM_ICR1 ); 
+	t = (t & 0x7777 & ~(0xf000>>TIMER_NUMBER*4)) | (0x8000>>TIMER_NUMBER*4);
+	*reg16p( 2 + MCFSIM_ICR1 ) = t; 
+	
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+
+void inline timer_interrupt_on(void)
+{	
+#ifdef DEBUG_M5272AUDIO_ISR
+	printk( KERN_DEBUG NAME ": " __FUNCTION__ "\n");
+#endif
+        *reg16p( MCFSIM_TMR0 + TIMER_NUMBER * 0x20 ) =  MCFTIMER_TMR_ENORI | TMR_DEFAULT; 
+}
+
+/****************************************************************************/
+
+short inline timer_interrupt_is_on(void)
+{	
+        return 0 != (*reg16p( MCFSIM_TMR0 + TIMER_NUMBER * 0x20 ) & 0x10); 
+}
+
+/****************************************************************************/
+
+void inline timer_interrupt_off(void)
+{
+        *reg16p( MCFSIM_TMR0 + TIMER_NUMBER * 0x20 ) = TMR_DEFAULT; 
+}
+
+/****************************************************************************/
+
+void inline pwm_on(void)
+{
+        *reg8p( 3 + MCFSIM_PWCR0 + PWM_CHANNEL * 4 ) = PWCR_DEFAULT | 0x80;
+}
+
+/****************************************************************************/
+
+void inline pwm_off(void)
+{
+        *reg8p( 3 + MCFSIM_PWCR0 + PWM_CHANNEL * 4 ) = PWCR_DEFAULT; 
+}
+
+/****************************************************************************/
+
+void inline pwm_set(uint8_t t)
+{
+        *reg8p( 3 + MCFSIM_PWWD0 + PWM_CHANNEL * 4 ) = t;
+}
+
+/****************************************************************************/
+
+void pwm_configure_pin(void)
+{
+        pwm_off();
+	pwm_set( 0xff );
+
+	/* switch pin for use with PWM. (Only the two upper channels share their output pin) */
+	if( PWM_CHANNEL == 1 ){
+		int flags;
+		uint16_t t;
+
+		save_flags(flags); cli();
+
+         	t = *reg16p( 2 + MCFSIM_PDCNT ); 
+		t = (t &  ~0x3000) | 0x1000;
+		*reg16p( 2 + MCFSIM_PDCNT ) = t; 
+
+		restore_flags(flags);
+	}
+	if( PWM_CHANNEL == 2 ){
+		int flags;
+		uint16_t t;
+
+		save_flags(flags); cli();
+
+         	t = *reg16p( 2 + MCFSIM_PDCNT ); 
+		t = (t & ~0xc000) | 0x4000;
+		*reg16p( 2 + MCFSIM_PDCNT ) = t; 
+
+		restore_flags(flags);
+	}
+}
+
+
+/****************************************************************************/
+
+void m5272audio_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned char	*bp;
+	
+#ifdef DEBUG_M5272AUDIO_ISR2
+	int flags;
+	
+ 	save_flags(flags); cli();
+	*reg16p( MCFSIM_PADAT ) |= 1;
+	restore_flags(flags);
+#endif	
+
+	/* clear IRQ */
+        *reg16p( MCFSIM_TER0 + TIMER_NUMBER * 0x20 ) = 0x0003; 
+
+	if (m5272audio_start == m5272audio_append) {
+		m5272audio_txbusy = 0;
+		timer_interrupt_off();
+		pwm_off();	
+#ifdef DEBUG_M5272AUDIO_ISR
+		printk( KERN_DEBUG NAME ": " __FUNCTION__ " done\n");
+#endif
+	} else {
+		bp = &m5272audio_buf[ m5272audio_start++ ];
+		pwm_set( *bp );
+		if (m5272audio_start >= M5272AUDIO_BUFSIZE)
+			m5272audio_start = 0;
+	}
+
+#ifdef DEBUG_M5272AUDIO_ISR2
+ 	save_flags(flags); cli();
+	*reg16p( MCFSIM_PADAT ) &= ~1;
+	restore_flags(flags);
+#endif	
+
+
+}
+
+
+/****************************************************************************/
+
+void m5272audio_txdrain(void)
+{
+#ifdef DEBUG_M5272AUDIO_TXDRAIN
+	printk(KERN_DEBUG NAME ": " __FUNCTION__ "\n");
+#endif
+	while ( m5272audio_txbusy ) {
+	    interruptible_sleep_on_timeout( &m5272audio_waitchan, 1 );
+	}
+}
+
+/****************************************************************************/
+
+int m5272audio_open(struct inode *inode, struct file *filp)
+{
+#ifdef DEBUG_M5272AUDIO_OPEN_CLOSE
+	printk(KERN_DEBUG NAME ": " __FUNCTION__ "\n" );
+#endif
+
+	if (m5272audio_isopen)
+		return -EBUSY;
+	m5272audio_isopen++;
+	return 0;
+}
+
+/****************************************************************************/
+
+int m5272audio_release(struct inode *inode, struct file *filp)
+{
+#ifdef DEBUG_M5272AUDIO_OPEN_CLOSE
+	printk(KERN_DEBUG NAME ": " __FUNCTION__ "\n" );
+#endif
+	m5272audio_txdrain ();
+	m5272audio_isopen = 0;
+	return 0;
+}
+
+/****************************************************************************/
+
+ssize_t m5272audio_write(struct file *filp, const char *buf, size_t count, loff_t *offset )
+{
+	unsigned char *bufp;
+	unsigned int slen, bufcnt, i, s, e;
+
+#ifdef DEBUG_M5272AUDIO_WRITE
+	printk(KERN_DEBUG NAME ": "  __FUNCTION__ " (buf=%x,count=%d)\n", (int) buf, count);
+#endif
+
+	if (count <= 0)
+		return(0);
+
+	bufp = (unsigned char *) buf;
+	bufcnt = count;
+
+tryagain:
+	/*
+	 * Get a snapshot of buffer, so we can figure out how
+	 * much data we can fit in...
+	 */
+	s = m5272audio_start;
+	e = m5272audio_append;
+
+	slen = ((s > e) ? (s - e) : (M5272AUDIO_BUFSIZE - (e - s))) - 4;
+	if (slen > bufcnt)
+		slen = bufcnt;
+	if ((M5272AUDIO_BUFSIZE - e) < slen)
+		slen = M5272AUDIO_BUFSIZE - e;
+
+	if (slen == 0) {
+		if (signal_pending(current))
+			return(-ERESTARTSYS);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
+		goto tryagain;
+	}
+
+#ifdef DEBUG_M5272AUDIO_BUF
+	printk(KERN_DEBUG NAME ": " __FUNCTION__ " filling buf[%d] %d\n", e, slen);
+#endif
+
+	/* Copy the buffer local and start sending it. */
+	copy_from_user( &m5272audio_buf[e], bufp, slen );
+	bufp += slen;
+
+	e += slen;
+	if (e >= M5272AUDIO_BUFSIZE)
+		e = 0;
+	m5272audio_append = e;
+
+	pwm_on();
+	if ( !timer_interrupt_is_on() ){
+		timer_interrupt_on();
+		m5272audio_txbusy++;
+	}
+
+	bufcnt -= slen;
+	if (bufcnt > 0)
+		goto tryagain;
+
+	return(count);
+}
+
+/****************************************************************************/
+
+int m5272audio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+        long    val;
+        int     rc = 0;
+
+#ifdef DEBUG_IOCTL
+        printk(KERN_DEBUG NAME ": " __FUNCTION__ " (cmd=0x%x, arg=0x%x)\n", (int) cmd, (int) arg);
+#endif
+
+        switch (cmd) {
+	
+        case SNDCTL_DSP_SAMPLESIZE:
+                rc = verify_area(VERIFY_READ, (void *) arg, sizeof(val));
+                if (rc == 0) {
+                        get_user(val, (unsigned long *) arg);
+                        m5272audio_txdrain();
+                        rc = m5272audio_setsamplesize(val);
+                }
+                break;
+       
+        case SNDCTL_DSP_GETBLKSIZE:
+                rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
+                if (rc == 0)
+                        put_user(M5272AUDIO_BUFSIZE-16, (long *) arg);
+                break;
+
+        case SNDCTL_DSP_SYNC:
+                m5272audio_txdrain();
+                break;
+
+        default:
+                rc = -EINVAL;
+                break;
+        }
+
+        return(rc);
+}
+
+
+/****************************************************************************/
+/*
+ *	Exported file operations structure for driver...
+ */
+
+struct file_operations	m5272audio_fops = {
+	.write = m5272audio_write,
+	.ioctl = m5272audio_ioctl,
+	.open = m5272audio_open,
+	.release = m5272audio_release
+};
+
+/****************************************************************************/
+
+static int __init m5272audio_init(void)
+{
+	int			result;
+
+	printk (NAME ": MCF5272 audio driver, (C) 2003 F. Ferlemann\n" );
+
+	/* Register pwm as character device */
+	result = register_chrdev(SOUND_MAJOR, NAME, &m5272audio_fops);
+	if (result < 0) {
+		printk(KERN_ERR NAME ": could not register major %d\n", SOUND_MAJOR);
+		return -ENODEV;
+	}
+        resource_count++;
+
+	/* Install ISR (interrupt service routine) */
+	result = request_irq(IRQ, m5272audio_isr, SA_INTERRUPT | IRQ_FLG_FAST, NAME, NULL);
+	if (result) {
+		printk (KERN_ERR NAME ": could not register IRQ %d\n", IRQ);
+		return -ENODEV;
+	}
+
+	printk (NAME ": TMR%d PWM%d IRQ %d IRQ_PRIO %d\n", TIMER_NUMBER, PWM_CHANNEL, IRQ, IRQ_PRIORITY);
+	
+	timer_init();
+	timer_interrupt_init();
+	pwm_configure_pin();
+	resource_count++;
+	
+	return 0;
+}
+
+/****************************************************************************/
+
+static void __exit m5272audio_exit(void)
+{
+	int 	result;
+	
+	printk (NAME ": exiting\n");
+
+        if(!resource_count--) return;
+	timer_interrupt_exit();
+	free_irq(IRQ, NULL);
+
+        if(!resource_count--) return;
+	result = unregister_chrdev(SOUND_MAJOR, NAME);
+	
+}
+
+/****************************************************************************/
+
+module_init(m5272audio_init);
+module_exit(m5272audio_exit);
diff -urN linux-2.4.29/drivers/char/Makefile linux-2.4.29-uc1/drivers/char/Makefile
--- linux-2.4.29/drivers/char/Makefile	2004-08-08 00:26:04.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/Makefile	2005-06-14 02:12:17.000000000 +0100
@@ -23,9 +23,10 @@
 
 export-objs     :=	busmouse.o console.o keyboard.o sysrq.o \
 			misc.o pty.o random.o selection.o serial.o \
+			ledman.o snapdog.o \
 			sonypi.o tty_io.o tty_ioctl.o generic_serial.o \
 			au1000_gpio.o vac-serial.o hp_psaux.o nvram.o \
-			scx200.o fetchop.o
+			scx200.o fetchop.o fast_timer.o	gio_c5471.o
 
 mod-subdirs	:=	joystick ftape drm drm-4.0 pcmcia
 
@@ -71,6 +72,15 @@
    SERIAL   =
 endif
 
+ifeq ($(ARCH),m68knommu)
+   ifdef CONFIG_68328_SERIAL
+       KEYBD  =
+       SERIAL = 68328serial.o
+   else
+       KEYBD =
+   endif
+endif
+
 ifeq ($(ARCH),parisc)
    ifdef CONFIG_GSC_PS2
       KEYBD   = hp_psaux.o hp_keyb.o
@@ -107,10 +117,19 @@
 
 ifeq ($(ARCH),arm)
   ifneq ($(CONFIG_PC_KEYMAP),y)
-    KEYMAP   =
+    KEYMAP   :=
   endif
   ifneq ($(CONFIG_PC_KEYB),y)
-    KEYBD    =
+    KEYBD    :=
+  endif
+  ifeq ($(CONFIG_KMI_KEYB),y)
+    KEYBD    := amba_kmi_keyb.o
+  endif
+endif
+
+ifeq ($(ARCH),armnommu)
+  ifneq ($(CONFIG_PC_KEYB),y)
+    KEYBD    :=
   endif
 endif
 
@@ -140,6 +159,33 @@
   KEYBD    =
   CONSOLE  = console.o
   endif
+  ifeq ($(CONFIG_SH_KEYWEST),y)
+    ifdef CONFIG_DUMMY_CONSOLE
+      ifdef CONFIG_FB
+        KEYMAP  = defkeymap.o
+        CONSOLE  = console.o
+      else
+        KEYMAP  = defkeymap.o
+#       CONSOLE  = console_sci.o
+        CONSOLE  = console.o
+      endif
+    else
+      KEYMAP  = defkeymap.o
+      CONSOLE  = console.o
+    endif
+    ifdef CONFIG_HD64465
+      KEYBD   = pc_keyb_hd64465.o
+    else
+      KEYBD   = pc_keyb.o
+    endif
+  endif
+endif
+
+ifeq ($(ARCH),niosnommu)
+  ifneq ($(CONFIG_PC_KEYB),y)
+    KEYBD    :=
+    KEYMAP   := defkeymap.o
+  endif
 endif
 
 ifeq ($(CONFIG_DECSTATION),y)
@@ -185,6 +231,72 @@
   obj-$(CONFIG_PCI) += keyboard.o $(KEYMAP)
 endif
 
+
+#
+# uClinux drivers
+#
+obj-$(CONFIG_68328_SERIAL) += 68328serial.o
+obj-$(CONFIG_SERIAL_DSC21) += serial_dsc21.o
+obj-$(CONFIG_SERIAL_C5471) += serial_c5471.o
+obj-$(CONFIG_SERIAL_ATMEL) += serial_atmel.o
+obj-$(CONFIG_SERIAL_DM270) += serial_dm270.o
+obj-$(CONFIG_ARCH_POLDHU) += serial_isil.o
+obj-$(CONFIG_ARCH_ISL3893) += serial_isil.o
+obj-$(CONFIG_SERIAL_NETARM) += serial_netarm.o
+obj-$(CONFIG_ARCH_POLDHU) += serial_isil.o
+obj-$(CONFIG_ARCH_ISL3893) += serial_isil.o
+obj-$(CONFIG_SERIAL_SAMSUNG) += serial_samsung.o
+obj-$(CONFIG_SERIAL_S3C2500) += serial_s3c2500.o
+obj-$(CONFIG_SERIAL_S3C3410) += serial_s3c3410.o
+obj-$(CONFIG_SERIAL_S3C44B0X) += serial_s3c44b0x.o
+obj-$(CONFIG_SERIAL_S3C4530) += serial_s3c4530.o
+obj-$(CONFIG_SERIAL_CNXT) += cnxtserial.o
+obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o generic_serial.o
+obj-$(CONFIG_V850E_UART) += v850e_uart.o generic_serial.o
+obj-$(CONFIG_COLDFIRE_SERIAL) += mcfserial.o
+obj-$(CONFIG_COLDFIRE_USB) += mcf_usb.o
+obj-$(CONFIG_MCF_QSPI) += mcf_qspi.o
+obj-$(CONFIG_LEDMAN) += ledman.o
+obj-$(CONFIG_LCDTXT) += lcdtxt.o
+obj-$(CONFIG_IDETEST) += idetest.o
+obj-$(CONFIG_68328_DIGI) += mc68328digi.o
+obj-$(CONFIG_MCFWATCHDOG) += mcfwatchdog.o
+obj-$(CONFIG_M5249AUDIO) += m5249audio.o
+obj-$(CONFIG_M5272AUDIO) += m5272audio.o
+obj-$(CONFIG_DRAGONIX_SPI) += dragonixspi.o
+obj-$(CONFIG_DS1302) += ds1302.o
+obj-$(CONFIG_M41T11M6) += m41t11m6.o
+obj-$(CONFIG_DRAGEN2_EEPROM) += de2spi.o de2eeprom.o
+obj-$(CONFIG_DRAGEN2_TS) += de2spi.o de2ts.o
+obj-$(CONFIG_DRAGEN2_FPGA) += de2fpga.o
+obj-$(CONFIG_NIOS_SERIAL) += NIOSserial.o
+obj-$(CONFIG_NIOS_SPI) += spi.o
+obj-$(CONFIG_XYMEM) += xymem.o
+obj-$(CONFIG_AU1X00_SERIAL_CONSOLE) += au1x00-serial.o
+obj-$(CONFIG_SERIAL_BF535) += bf535_serial.o
+obj-$(CONFIG_SERIAL_BF533) += bf533_serial.o
+mod-subdirs += can4linux
+subdir-$(CONFIG_CAN4LINUX) += can4linux
+obj-$(CONFIG_CAN4LINUX) += can4linux/Can.o
+# Support for Xilinx GPIO driver
+mod-subdirs += xilinx_gpio
+subdir-$(CONFIG_XILINX_GPIO) += xilinx_gpio
+obj-$(CONFIG_XILINX_GPIO) += xilinx_gpio/xilinx_gpio.o
+obj-$(CONFIG_TA7_WDT) += ta7_watchdog.o
+obj-$(CONFIG_C5471_GIO) += gio_c5471.o
+obj-$(CONFIG_C5471_WDT) += wdt_c5471.o
+obj-$(CONFIG_MBA44B0_TOUCH) += mba44b0touch.o
+obj-$(CONFIG_SNAPDOG) += snapdog.o
+obj-$(CONFIG_FAST_TIMER) += fast_timer.o
+obj-$(CONFIG_TA7_WDT) += ta7_watchdog.o
+ifeq ($(CONFIG_EP93XX_VT),y)
+	obj-$(CONFIG_EP93XX_KBD_USB) += defkeymap.o ep93xx_usb_kbd.o
+	obj-$(CONFIG_EP93XX_KBD_SPI) += defkeymap.o ep93xx_spi_kbd.o
+	obj-$(CONFIG_EP93XX_KBD_SCANNED) += ep93xx_keymap.o ep93xx_scan_keyb.o
+	obj-$(CONFIG_EP93XX_TOUCHSCREEN) += ep93xx_ts.o
+endif
+
+
 obj-$(CONFIG_HIL) += hp_keyb.o
 obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o
 obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o
@@ -248,12 +360,14 @@
 obj-$(CONFIG_ADBMOUSE) += adbmouse.o
 obj-$(CONFIG_PC110_PAD) += pc110pad.o
 obj-$(CONFIG_MK712_MOUSE) += mk712.o
+obj-$(CONFIG_EDB7312_TS) += edb7312_ts.o
 obj-$(CONFIG_RTC) += rtc.o
 obj-$(CONFIG_GEN_RTC) += genrtc.o
 obj-$(CONFIG_EFI_RTC) += efirtc.o
 obj-$(CONFIG_SGI_DS1286) += ds1286.o
 obj-$(CONFIG_MIPS_RTC) += mips_rtc.o
 obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o
+obj-$(CONFIG_X1226_RTC) += x1226-rtc.o
 ifeq ($(CONFIG_PPC),)
   obj-$(CONFIG_NVRAM) += nvram.o
 endif
@@ -323,6 +437,7 @@
 obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
 obj-$(CONFIG_INDYDOG) += indydog.o
 obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
+obj-$(CONFIG_C5471_WDT) += wdt_c5471.o
 
 subdir-$(CONFIG_MWAVE) += mwave
 ifeq ($(CONFIG_MWAVE),y)
diff -urN linux-2.4.29/drivers/char/mba44b0touch.c linux-2.4.29-uc1/drivers/char/mba44b0touch.c
--- linux-2.4.29/drivers/char/mba44b0touch.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/mba44b0touch.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,653 @@
+/* -*- c -*- --------------------------------------------------------- *
+ *
+ * Copyright (C) 2003 Stefan Macher <macher@sympat.de>
+ *
+ * This driver is not compatible with the generic linux mouse protocol.
+ * There is a microwindows driver available that supports this touchscreen
+ * driver.
+ * ------------------------------------------------------------------------- */
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/s3c44b0x.h>
+
+#include <linux/mba44b0touch.h>
+
+/* debugging level  */
+/* ---------------- */
+#ifdef MBA44B0_TS_DEBUG_LEVEL
+static int mba44b0_ts_debug_mask = MBA44B0_TS_DEBUG_LEVEL;
+#else
+static int mba44b0_ts_debug_mask = MBA44B0_TS_DEBUG_ERR;
+#endif
+
+/* delay between interrupt and first read out of position  */
+/* ------------------------------------------------------- */
+#ifdef MBA44B0_TS_FIRST_POLL_DELAY
+static int FirstPollDelay = MBA44B0_TS_FIRST_POLL_DELAY;
+#else
+static int FirstPollDelay = 2; /* default value */
+#endif
+
+/* delay between two consecutive position read outs        */
+/* ------------------------------------------------------- */
+#ifdef MBA44B0_TS_POLL_DELAY
+static int PollDelay = MBA44B0_TS_POLL_DELAY;
+#else
+static int PollDelay = 10; /* default value is 100 ms */
+#endif
+
+/* prescaler of the ADC */
+/* -------------------- */
+#ifdef MBA44B0_TS_ADC_PRESCALER
+static int adcpsr = MBA44B0_TS_ADC_PRESCALER
+#else
+static int adcpsr = 0xF; /* default value */
+#endif
+
+/* interrupt of the touchscreen  */
+/* ----------------------------- */
+#ifdef MBA44B0_TS_IRQ
+static int mba44b0_irq = MBA44B0_TS_IRQ;
+#else
+static int mba44b0_irq = S3C44B0X_INTERRUPT_EINT3; /* default value */
+#endif
+
+/* screen informations  */
+/* -------------------- */
+#ifdef MBA44B0_TS_X_RES
+static int xres = MBA44B0_TS_X_RES;
+#else
+static int xres = 320;
+#endif
+
+#ifdef MBA44B0_TS_Y_RES
+static int yres = MBA44B0_TS_X_RES;
+#else
+static int yres = 240;
+#endif
+
+/* calibration settings  */
+/* --------------------- */
+struct mba44b0_cal_settings cal_settings = {
+#ifdef MBA44B0_TS_CAL_X_OFF
+	cal_x_off: MBA44B0_TS_CAL_X_OFF,
+#else
+	cal_x_off: -100,
+#endif
+
+#if ((defined MBA44B0_TS_CAL_X_SCALE_NUM) && (defined MBA44B0_TS_CAL_X_SCALE_DENOM))
+	cal_x_scale_num: MBA44B0_TS_CAL_X_SCALE_NUM,
+	cal_x_scale_denom: MBA44B0_TS_CAL_X_SCALE_DENOM,
+#else
+	cal_x_scale_num: (1<<21),
+	cal_x_scale_denom: 2949120,
+#endif
+
+#ifdef MBA44B0_TS_CAL_Y_OFF
+	cal_y_off: MBA44B0_TS_CAL_Y_OFF,
+#else
+	cal_y_off: -500,
+#endif
+
+#if ((defined MBA44B0_TS_CAL_Y_SCALE_NUM) && (defined MBA44B0_TS_CAL_Y_SCALE_DENOM))
+	cal_y_scale_num:  MBA44B0_TS_CAL_Y_SCALE_NUM,
+	cal_y_scale_denom: MBA44B0_TS_CAL_Y_SCALE_DENOM,
+#else
+	cal_y_scale_num: (1<<21),
+	cal_y_scale_denom: 3407872,
+#endif
+};
+
+/* function declarations           */
+/* ------------------------------- */
+static void           mba44b0_config_pressed(void);
+static void           mba44b0_config_read_x(void);
+static void           mba44b0_config_read_y(void);
+static void           mba44b0_config_adc(unsigned int input_select);
+static unsigned int   mba44b0_read_adc(void);
+static void           mba44b0_interv_poll(unsigned long irq);
+static void           mba44b0_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static int            mba44b0_open(struct inode *inode, struct file *file); 
+static int            mba44b0_close(struct inode * inode, struct file * file);
+static unsigned int   mba44b0_poll(struct file *file, poll_table *wait);
+static int            mba44b0_ioctl(struct inode *inode, struct file * file, unsigned int cmd, unsigned long arg);
+static ssize_t        mba44b0_read(struct file *file, char *buffer, size_t count, loff_t *pos);
+static ssize_t        mba44b0_write(struct file *file, const char *buffer, size_t count, loff_t *ppos);
+static int __init     mba44b0_init(void);
+static void __exit    mba44b0_exit(void);
+static void           mba44b0_map_to_coord(int x, int y, int *newx, int *newy);
+/* -------------------------------- */
+
+struct file_operations mba44b0_ts_fops = {
+	owner: THIS_MODULE,
+	read: mba44b0_read,
+	write: mba44b0_write,
+	poll: mba44b0_poll,
+	ioctl: mba44b0_ioctl,
+	open: mba44b0_open,
+	release: mba44b0_close,
+	fasync: NULL,
+};
+
+static struct miscdevice mba44b0_touchscreen = {
+	MBA44B0_TS_MINOR, "mba44b0_touchscreen", &mba44b0_ts_fops
+};
+
+static struct timer_list mba44b0_timer; /* a kernel timer that is used for polling */
+
+static int mba44b0_users = 0; /* number of connected users; only one is allowed */
+
+static int pos_x=0, pos_y=0; /* indicates the last measured position */
+static int last_pos_x=0, last_pos_y=0; /* the position that was read the last time */
+static unsigned char touch_pressed=0; /* 1 means the touch is currently pressed */
+static int touch_event=0; /* is there an event pending */
+
+DECLARE_WAIT_QUEUE_HEAD(touch_wait);
+static spinlock_t touch_lock = SPIN_LOCK_UNLOCKED;
+
+/*! \brief Maps the measured touch position to pixel values
+ */
+static void mba44b0_map_to_coord(int x, int y, int *newx, int *newy)
+{
+	*newx = (x + cal_settings.cal_x_off) * cal_settings.cal_x_scale_num / cal_settings.cal_x_scale_denom;
+	*newy = (y + cal_settings.cal_y_off) * cal_settings.cal_y_scale_num / cal_settings.cal_y_scale_denom;
+}
+
+/*! \brief Configures the touchscreen ports for testing if
+ *         the touchscreen is pressed or not
+ *
+ *  It configures 
+ *  - TOUCH_XH and TOUCH_XL as input with active pull-up
+ *  - TOUCH_YH and TOUCH_YL as output low
+ *
+ *  If the touch is pressed the low level of the Y plane is connected to
+ *  the X plane and therefore the voltage at AIN0 should also be low
+ *
+ *  This setting is also used to enable the interrupt
+ */
+static void mba44b0_config_pressed()
+{
+	unsigned int val32;
+
+	MBA44B0_TS_DEBUG(MBA44B0_TS_DEBUG_CONFIG, "switch to config pressed\n");
+
+	/*-------------------------*/
+	/* configuration of PCONE  */
+	/*-------------------------*/
+	val32=inl(S3C44B0X_PCONE);
+	outl((val32&0xFFFF00FF)|0x500, S3C44B0X_PCONE); /* config GPE4 - GPE5 output GPE6 and GPE7 input */
+	/*-------------------------*/
+	/* configuration of PUPE   */
+	/*-------------------------*/
+	val32=inl(S3C44B0X_PUPE);
+	outl((val32&0x0F)|0xC0, S3C44B0X_PUPE); /* config GPE6 and GPE7 activate pull up */
+	/*-------------------------*/
+	/* configuration of PDATE  */
+	/*-------------------------*/
+	val32=inl(S3C44B0X_PDATE);
+	outl(val32&0xFFFFFF0F, S3C44B0X_PDATE); /* GPE5 low, GPE4 low */
+
+}
+
+/*! \brief Configures the touchscreen ports for reading out the
+ *         the x position
+ *
+ *  It configures 
+ *  - TOUCH_XH as output high
+ *  - TOUCH_XL as output low
+ *  - TOUCH_YH and TOUCH_YL as input with active pull-up
+ *
+ *  The voltage level at AIN1 then defines the X position
+ */
+static void mba44b0_config_read_x()
+{
+	unsigned int val32;
+
+	MBA44B0_TS_DEBUG(MBA44B0_TS_DEBUG_CONFIG, "switch to config read x\n");
+
+	/*-------------------------*/
+	/* configuration of PCONE  */
+	/*-------------------------*/
+	val32=inl(S3C44B0X_PCONE);
+	outl((val32&0xFFFF00FF)|0x5000, S3C44B0X_PCONE); /* config GPE4 - GPE5 input GPE6 and GPE7 output */
+	/*-------------------------*/
+	/* configuration of PUPE   */
+	/*-------------------------*/
+	val32=inl(S3C44B0X_PUPE);
+	outl((val32&0x0F)|0x00, S3C44B0X_PUPE); /* config GPE4 and GPE5 activate pull up */
+/*	outl((val32&0x0F)|0x30, S3C44B0X_PUPE); ?  config GPE4 and GPE5 activate pull up */
+	/*-------------------------*/
+	/* configuration of PDATE  */
+	/*-------------------------*/
+	val32=inl(S3C44B0X_PDATE);
+	outl((val32&0xFFFFFF0F)|0x80, S3C44B0X_PDATE); /* GPE6 low, GPE7 high */
+
+}
+
+/*! \brief Configures the touchscreen ports for reading out the
+ *         the y position
+ *
+ *  It configures 
+ *  - TOUCH_YH as output high
+ *  - TOUCH_YL as output low
+ *  - TOUCH_XH and TOUCH_XL as input with active pull-up
+ *
+ *  The voltage level at AIN0 then defines the Y position
+ */
+static void mba44b0_config_read_y()
+{
+	unsigned int val32;
+
+	MBA44B0_TS_DEBUG(MBA44B0_TS_DEBUG_CONFIG, "switch to config read y\n");
+
+	/*-------------------------*/
+	/* configuration of PCONE  */
+	/*-------------------------*/
+	val32=inl(S3C44B0X_PCONE);
+	outl((val32&0xFFFF00FF)|0x500, S3C44B0X_PCONE); /* config GPE4 - GPE5 output GPE6 and GPE7 input */
+	/*-------------------------*/
+	/* configuration of PUPE   */
+	/*-------------------------*/
+	val32=inl(S3C44B0X_PUPE);
+	outl((val32&0x0F)|0x00, S3C44B0X_PUPE); /* config GPE6 and GPE7 activate pull up */
+/*	outl((val32&0x0F)|0xC0, S3C44B0X_PUPE);    config GPE6 and GPE7 activate pull up */
+	/*-------------------------*/
+	/* configuration of PDATE  */
+	/*-------------------------*/
+	val32=inl(S3C44B0X_PDATE);
+	outl((val32&0xFFFFFF0F)|0x20, S3C44B0X_PDATE); /* GPE4 low, GPE5 high */
+
+}
+
+/*! \brief Configures the prescaler and the input line
+ *         of the ADC
+ *
+ *  /param input_select Valid values are 0-7 corresponding to AIN0 - AIN7
+ */
+static void mba44b0_config_adc(unsigned int input_select)
+{
+	MBA44B0_TS_DEBUG(MBA44B0_TS_DEBUG_ADC, "set ADC input to %d\n", input_select);
+
+	/*-------------------------*/
+	/* configuration of ADCPSR */
+	/*-------------------------*/
+	outl(adcpsr, S3C44B0X_ADCPSR); //prescaler
+	/*-------------------------*/
+	/* configuration of ADCCON */
+	/*-------------------------*/
+	outl((input_select<<2), S3C44B0X_ADCCON); 
+
+}
+
+/*! \brief Reads out the ADC value
+ *
+ *  According to the S3C44B0X manual the procedure is as follows:
+ *  - Activate conversion by setting bit 0 in ADCCON
+ *  - Wait until the start bit is cleared (after one ADC clock) because
+ *    the ready flag if 1 for one ADC clock after conversion started
+ *  - Wait until the ready bit is 1
+ *  - Wait on further ADC clock because the ready bit is set on ADC clock
+ *    before conversion is finished
+ *
+ *  \return The ADC value
+ */
+static unsigned int mba44b0_read_adc()
+{
+	unsigned int val32, i;
+
+	MBA44B0_TS_DEBUG(MBA44B0_TS_DEBUG_INFO, "Read\n");
+
+       /*--------------------------*/
+	/* activate ADC             */
+	/*--------------------------*/
+	val32=inl(S3C44B0X_ADCCON);
+	outl(val32 |0x1, S3C44B0X_ADCCON);
+	/*----------------------------------------------*/
+	/* wait because of errors in the ADC of the CPU */
+	/*----------------------------------------------*/
+	do
+	{
+		val32 = inl(S3C44B0X_ADCCON);
+	}
+	while(val32 & 0x1);
+	while(!(val32 & 0x40)) 
+	{ 
+		val32 = inl(S3C44B0X_ADCCON); 
+	}
+	for(i=0; i < adcpsr >> 2 ; i++)
+	{
+		val32 = inl(S3C44B0X_ADCDAT);
+	}
+	return val32;
+}
+
+/*! \brief This function is called by the kernel timer and checks the actual
+ *         position
+ *
+ * At first we check if the touch is actually pressed.
+ * If not, we will reenable the interrupt and just return.
+ * If it is pressed, we will check the actually position and
+ * if it changed compared to the previous position we will store it
+ */
+static void mba44b0_interv_poll(unsigned long irq)
+{
+	unsigned int val32=0;
+	unsigned int x, y, map_x, map_y, meas, i;
+
+	MBA44B0_TS_DEBUG(MBA44B0_TS_DEBUG_INFO, "polling\n");
+
+	mba44b0_config_pressed(); /* configure the touchscreen ports for measuring if any key is pressed */
+	mba44b0_config_adc(0); /* measure on AIN0 */
+
+	val32 = mba44b0_read_adc();
+	/*-------------------------------------*/
+	/* check if touch is no longer pressed */
+	/*-------------------------------------*/
+	if(val32 > MBA44B0_TS_PRESS_THRESHOLD)
+	{ /* it is not pressed */
+		if(touch_pressed)
+			touch_event = 1; /* release event */
+		touch_pressed = 0;
+		enable_irq(irq); /* reenable the touchscreen interrupt */
+		return;
+	}
+       /* it is pressed so calculate the new position */
+	/* we start with reading the x position */
+	mba44b0_config_read_x();
+	mba44b0_config_adc(1);
+	meas = 0;
+	for(i=0; i < 40; i++)
+	{
+		x = mba44b0_read_adc();
+		if(i>=8)
+			meas += x;
+	}
+	x = meas >> 5;
+	printk("x=%d ", x);
+	mba44b0_config_read_y();
+	mba44b0_config_adc(0);
+	meas = 0;
+	for(i=0; i < 40; i++)
+	{
+		y = 1023 - mba44b0_read_adc();
+		if(i>=8)
+			meas += y;
+	}
+	y = meas >> 5;
+	printk("y=%d\n",y);
+
+	mba44b0_map_to_coord(x, y, &map_x, &map_y);
+	printk("cal x=%d, y=%d\n", map_x, map_y);
+	spin_lock(&touch_lock);
+	pos_x = map_x;
+	pos_y = map_y;
+	if( (pos_x != last_pos_x) || 
+	    (pos_y != last_pos_y) ||
+	    (!touch_pressed) )
+ /* an event occured if the position changed or if the touch is newly pressed */
+		touch_event=1;
+
+	touch_pressed = 1;
+	spin_unlock(&touch_lock);
+
+
+	init_timer(&mba44b0_timer);
+	mba44b0_timer.function = mba44b0_interv_poll;
+	mba44b0_timer.data = irq;
+	mba44b0_timer.expires = PollDelay;
+	add_timer(&mba44b0_timer);
+
+	MBA44B0_TS_DEBUG(MBA44B0_TS_DEBUG_POS, "x:%d y:%d\n", x, y);
+
+	wake_up_interruptible(&touch_wait);
+}
+
+
+static void mba44b0_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/*-------------------------*/
+	/* disable irq             */
+	/*-------------------------*/
+	disable_irq(irq);
+
+	MBA44B0_TS_DEBUG(MBA44B0_TS_DEBUG_IRQ, "irq\n");
+	
+	/*-------------------------*/
+	/* setup kernel timer      */
+	/*-------------------------*/
+	init_timer(&mba44b0_timer);
+	mba44b0_timer.function = mba44b0_interv_poll;
+	mba44b0_timer.data = irq;
+	mba44b0_timer.expires = FirstPollDelay;
+	add_timer(&mba44b0_timer);
+	/*--------------------------*/
+	/* return from interrupt    */
+	/*--------------------------*/
+	return;
+
+}
+
+static int mba44b0_open(struct inode *inode, struct file *file) 
+{
+	MBA44B0_TS_DEBUG(MBA44B0_TS_DEBUG_INFO, "open\n");
+	if(!mba44b0_users) /* only one user is allowed!! */
+		mba44b0_users++;
+	else
+		return -EBUSY;
+
+	enable_irq(mba44b0_irq);
+	return 0;
+}
+
+static int mba44b0_close(struct inode * inode, struct file * file)
+{
+	MBA44B0_TS_DEBUG(MBA44B0_TS_DEBUG_INFO, "close\n");
+	mba44b0_users--;
+	if(!mba44b0_users) /* must be also true since we allow only one user */
+		disable_irq(mba44b0_irq);
+	return 0;
+}
+
+static unsigned int mba44b0_poll(struct file *file, poll_table *wait)
+{
+	poll_wait(file, &touch_wait, wait);
+	if(touch_event)
+		return (POLLIN | POLLRDNORM);
+
+	return 0;
+}
+
+static int mba44b0_ioctl(struct inode *inode, struct file * file,
+	unsigned int cmd, unsigned long arg)
+{
+	switch(cmd)
+	{
+	case MBA44B0_TS_SET_CAL_PARAMS:
+		if(!arg) {
+			MBA44B0_TS_DEBUG(MBA44B0_TS_DEBUG_ERR, "Set calibration params with zero pointer\n");
+			return -EINVAL;
+		}
+		copy_from_user(&cal_settings, (void*)arg, sizeof(cal_settings));
+		break;
+		
+	case MBA44B0_TS_GET_CAL_PARAMS:
+		if(!arg) {
+			MBA44B0_TS_DEBUG(MBA44B0_TS_DEBUG_ERR, "Get calibration params with zero pointer\n");
+			return -EINVAL;
+		}
+		copy_to_user((void*)arg, &cal_settings, sizeof(cal_settings));
+		break;
+	
+	case MBA44B0_TS_SET_X_RES:
+		copy_from_user(&xres, (void*)arg, sizeof(xres));
+		break;
+
+	case MBA44B0_TS_SET_Y_RES:
+		copy_from_user(&yres, (void*)arg, sizeof(yres));
+		break;
+
+	default:
+		MBA44B0_TS_DEBUG(MBA44B0_TS_DEBUG_ERR, "Received unknown ioctl command\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+static ssize_t mba44b0_read(struct file *file, char *buffer,
+			  size_t count, loff_t *pos)
+{
+	struct ts_event event;
+        unsigned long flags;
+	
+        if(count != sizeof(struct ts_event))
+                return -EINVAL;
+
+	while(!touch_event)
+        {
+                if(file->f_flags&O_NDELAY)
+		{
+			return -EWOULDBLOCK;
+		}
+                if(signal_pending(current))
+		{
+			return -ERESTARTSYS;
+		}
+		if (wait_event_interruptible(touch_wait, touch_event))
+			return -ERESTARTSYS;
+        }
+
+         /* Grab the event */
+
+        spin_lock_irqsave(&touch_lock, flags);
+
+	event.x = pos_x;
+	event.y = pos_y;
+	event.pressure = touch_pressed;
+	touch_event = 0;
+	last_pos_x = pos_x;
+	last_pos_y = pos_y;
+
+        spin_unlock_irqrestore(&touch_lock, flags);
+  
+	event.pad = 0;
+
+/* Restrict to screen resolution */
+	if(event.x < 0)
+		event.x = 0;
+	else if(event.x >= xres)
+		event.x = xres-1;
+	if(event.y < 0)
+		event.y = 0;
+	else if(event.y >= yres)
+		event.y = yres-1;
+
+
+	if(copy_to_user(buffer, &event, sizeof(struct ts_event)))
+		return -EFAULT;
+        return count;	
+}
+
+static ssize_t mba44b0_write(struct file *file, const char *buffer, size_t count,
+			   loff_t *ppos)
+{
+	return -EINVAL;
+}
+
+static int __init mba44b0_init(void)
+{
+	unsigned int val32;
+
+	printk("mba44b0_touch: initializing...\n");
+
+	/* configure touchscreen ports for interrupt */
+	mba44b0_config_pressed();
+	/*-------------------------------*/
+	/* configure interrupt           */
+	/*-------------------------------*/
+	val32=inl(S3C44B0X_INTMOD);
+	outl((val32&0xF7FFFFF), S3C44B0X_INTMOD); /* normal IRQ */
+	val32=inl(S3C44B0X_EXTINT);
+	outl((val32&0xFFFF8FFF)|0x2000, S3C44B0X_EXTINT); /*falling edge */
+	val32=inl(S3C44B0X_PCONG);
+	outl(val32 | 0xC0, S3C44B0X_PCONG); /* use Port G pin 3 as ext int 3 */
+	
+	if(request_irq(mba44b0_irq, mba44b0_interrupt, 0, "mba44b0_touchscreen",NULL))
+	{
+		printk("mba44b0: unable to get IRQ\n");
+		return -EBUSY;
+	}
+
+	disable_irq(mba44b0_irq);
+
+        /* register misc device */
+	if(misc_register(&mba44b0_touchscreen)<0)
+	{
+		free_irq(mba44b0_irq, NULL);
+		return -ENODEV;
+	}
+
+	printk("mba44b0_touch: init ready\n");
+
+	return 0;
+}
+
+static void __exit mba44b0_exit(void)
+{
+	misc_deregister(&mba44b0_touchscreen);
+	free_irq(mba44b0_irq, NULL);
+	printk(KERN_INFO "mba44b0 touchscreen uninstalled\n");
+}
+
+MODULE_AUTHOR("Stefan Macher & Alexander Assel; sympat GmbH Nuremberg");
+MODULE_DESCRIPTION("MBA44B0 touch screen driver");
+
+MODULE_PARM(FirstPollDelay, "i");
+MODULE_PARM_DESC(FirstPollDelay, "Is the delay between the interrupt and the first read out of the touchscreen position in jiffies (normallay 10 ms) (default is 2 -> 20 ms)");
+
+MODULE_PARM(PollDelay, "i");
+MODULE_PARM_DESC(PollDelay, "Is the delay between two consecutive read out of the touchscreen position in jiffies (normallay 10 ms) (default is 10 -> 100 ms)");
+
+MODULE_PARM(irq, "i");
+MODULE_PARM_DESC(irq, "IRQ number of MBA44B0 touch screen controller (default is 22 -> EINT3)");
+
+MODULE_PARM(adcpsr, "i");
+MODULE_PARM_DESC(adcpsr, "Prescaler configuration for the ADC; valid values are 1...255 (default is 15)");
+
+MODULE_PARM(xres, "i");
+MODULE_PARM_DESC(xres, "X resolution of the display (default is 320 pixels)");
+
+MODULE_PARM(yres, "i");
+MODULE_PARM_DESC(yres, "Y resolution of the display (default is 240 pixels)");
+
+MODULE_LICENSE("GPL");
+
+module_init(mba44b0_init);
+module_exit(mba44b0_exit);
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */
diff -urN linux-2.4.29/drivers/char/mc68328digi.c linux-2.4.29-uc1/drivers/char/mc68328digi.c
--- linux-2.4.29/drivers/char/mc68328digi.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/mc68328digi.c	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,1585 @@
+/*----------------------------------------------------------------------------*/
+/* mc68328digi.c,v 1.2 2001/02/12 11:14:10 pney Exp
+ *
+ * linux/drivers/char/mc68328digi.c - Touch screen driver.
+ *
+ * Author: Philippe Ney <philippe.ney@smartdata.ch>
+ * Copyright (C) 2001 SMARTDATA <www.smartdata.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Thanks to:
+ *    Kenneth Albanowski for is first work on a touch screen driver.
+ *    Alessandro Rubini for is "Linux device drivers" book.
+ *    Ori Pomerantz for is "Linux Kernel Module Programming" guide.
+ *
+ * Updates:
+ *   2001-03-07 Pascal bauermeister <pascal.bauermeister@smartdata.ch>
+ *              - Adapted to work ok on xcopilot; yet untested on real Palm.
+ *              - Added check for version in ioctl()
+ *
+ *   2001-03-21 Pascal bauermeister <pascal.bauermeister@smartdata.ch>
+ *              - bypass real hw uninits for xcopilot. Now xcopilot is
+ *                happy. It even no longer generates pen irq while this
+ *                irq is disabled (I'd like to understand why, so that
+ *                I can do the same in mc68328digi_init() !).
+ *
+ *   2001-10-23 Daniel Potts <danielp@cse.unsw.edu.au>
+ *              - support for uCdimm/68VZ328. I use SPI 2 which maps to the
+ *                same addresses as for 68EZ328 and requries less changes to
+ *                the code. For CS I use PF_A22; CSD0/CAS0 is not made 
+ *                available off the uCdimm.
+ *                PF1 (/IRQ5) is already used on uCdimm by the ethernet
+ *                controller. We use /IRQ6 instead (PD7).
+ *              - kill_fasync and request_irq fixes for 2.4.x (only) support.
+ *
+ *
+ * Hardware:      Motorola MC68EZ328 DragonBall-EZ
+ *                Burr-Brown ADS7843 Touch Screen Controller
+ *                Rikei REW-A1 Touch Screen
+ *
+ * OS:            uClinux version 2.0.38.1pre3
+ *
+ * Connectivity:  Burr-Brown        DragonBall
+ *                PENIRQ     ---->  PF1  &  PD4 (with a 100k resistor)
+ *                BUSY       ---->  PF5
+ *                CS         ---->  PB4
+ *                DIN        ---->  PE0
+ *                DOUT       ---->  PE1
+ *                DCLK       ---->  PE2
+ *
+ *     ADS7843: /PENIRQ ----+----[100k resistor]---- EZ328: PD4
+ *                          |
+ *                          +----------------------- EZ328: /IRQ5
+ *
+ * States graph:
+ *
+ *         ELAPSED & PEN_UP
+ *         (re-init)             +------+
+ *     +------------------------>| IDLE |<------+
+ *     |                         +------+       |
+ *     |                           |            | ELAPSED
+ *     |  +------------------------+            | (re-init)
+ *     |  |       PEN_IRQ                       |
+ *     |  |       (disable pen_irq)             | 
+ *     |  |       (enable & set timer)          | 
+ *     |  |                                     |
+ *     | \/                                     |
+ *   +------+                                   |
+ *   | WAIT |                                   |
+ *   +------+                                   |
+ *   /\   |                                     | 
+ *   |    |             +---------------+-------+------+---------------+
+ *   |    |             |               |              |               |
+ *   |    |             |               |              |               |
+ *   |    |        +--------+      +-------+      +--------+      +--------+
+ *   |    +------->| ASK X  |      | ASK Y |      | READ X |      | READ Y |
+ *   |  ELAPSED &  +--------+      +-------+      +--------+      +--------+
+ *   |  PEN_DOWN       |           /\    |         /\    |         /\    |
+ *   |  (init SPIM)    +-----------'     +---------'     +---------'     |
+ *   |  (set timer)    XCH_COMPLETE      XCH_COMPLETE    XCH_COMPLETE    |
+ *   |                                                                   |
+ *   |                                                                   |
+ *   |                                                                   |
+ *   +-------------------------------------------------------------------+
+ *                               XCH_COMPLETE
+ *                               (release SPIM)
+ *                               (set timer)
+ *
+ *
+ * Remarks: I added some stuff for port on 2.2 and 2.4 kernels but currently
+ *          this version works only on 2.0 because not tested on 2.4 yet.
+ *          Someone interested?
+ *
+ */
+/*----------------------------------------------------------------------------*/
+
+#include <linux/kernel.h>     /* We're doing kernel work */
+#include <linux/module.h>     /* Specifically, a module */
+#include <linux/interrupt.h>  /* We want interrupts */
+
+#include <linux/miscdevice.h> /* for misc_register() and misc_deregister() */
+
+#include <linux/fs.h>         /* for struct 'file_operations' */
+
+#include <linux/timer.h>     /* for timeout interrupts */
+#include <linux/param.h>     /* for HZ. HZ = 100 and the timer step is 1/100 */
+#include <linux/sched.h>     /* for jiffies definition. jiffies is incremented
+                              * once for each clock tick; thus it's incremented
+			      * HZ times per secondes.*/
+#include <linux/mm.h>        /* for verify_area */
+#include <linux/malloc.h>    /* for kmalloc */
+#include <linux/init.h>
+
+#include <asm/irq.h>         /* For IRQ_MACHSPEC */
+
+/*----------------------------------------------------------------------------*/
+
+#if defined(CONFIG_M68328)
+/* These are missing in MC68328.h. I took them from MC68EZ328.h temporarily,
+ * but did not dare modifying MC68328.h yet (don't want to break things and
+ * have no time now to do regression testings)
+ *   - Pascal Bauermeister
+ */
+#define ICR_ADDR        0xfffff302
+#define ICR_POL5        0x0080  /* Polarity Control for IRQ5 */
+#define IMR_MIRQ5       (1 << IRQ5_IRQ_NUM)     /* Mask IRQ5 */
+#define IRQ5_IRQ_NUM    20      /* IRQ5 */
+#define PBPUEN          BYTE_REF(PBPUEN_ADDR)
+#define PBPUEN_ADDR     0xfffff40a              /* Port B Pull-Up enable reg */
+#define PB_CSD0_CAS0    0x10    /* Use CSD0/CAS0 as PB[4] */
+#define PDSEL           BYTE_REF(PDSEL_ADDR)
+#define PDSEL_ADDR      0xfffff41b              /* Port D Select Register */
+#define PD_IRQ1         0x10    /* Use IRQ1 as PD[4] */
+#define PF_A22          0x20    /* Use A22       as PF[5] */
+#define PF_IRQ5         0x02    /* Use IRQ5      as PF[1] */
+#define SPIMCONT        WORD_REF(SPIMCONT_ADDR)
+#define SPIMCONT_ADDR   0xfffff802
+#define SPIMCONT_SPIMEN         SPIMCONT_RSPIMEN
+
+#elif defined(CONFIG_M68EZ328)
+# include <asm/MC68EZ328.h>  /* bus, port and irq definition of DragonBall EZ */
+#elif defined(CONFIG_M68VZ328)
+# include <asm/MC68VZ328.h>
+#else
+# error "mc68328digi: a known machine not defined."
+#endif
+
+#include <linux/mc68328digi.h>
+
+/*----------------------------------------------------------------------------*/
+/* Debug */
+
+#if 0
+#if 0
+# define DPRINTK printk("%0: [%03d,%03d] ", __file__, \
+                        current_pos.x, current_pos.y); \
+                        printk
+#else
+# define DPRINTK __dummy__
+  static void __dummy__(const char* fmt, ...) {}
+#endif
+#endif
+/*----------------------------------------------------------------------------*/
+
+static const char* __file__ = __FILE__;
+
+/*----------------------------------------------------------------------------*//*
+ * Kernel compatibility.
+ * Kernel > 2.2.3, include/linux/version.h contain a macro for KERNEL_VERSION
+ */
+#include <linux/version.h>
+#ifndef KERNEL_VERSION
+#define KERNEL_VERSION(a,b,c)  (((a) << 16) + ((b) << 8) + (c))
+#endif
+
+/*
+ * Conditional compilation. LINUX_VERSION_CODE is the code of this version
+ * (as per KERNEL_VERSION)
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0))
+#include <asm/uaccess.h>    /* for put_user     */
+#include <linux/poll.h>     /* for polling fnct */
+#endif
+
+/*
+ * time limit 
+ * Used for a whole conversion (x & y) and to clock the Burr-Brown to fall the
+ * BUSY signal down (otherwise, pen cannot generate irq anymore).
+ * If this limit run out, an error is generated. In the first case, the driver
+ * could recover his normal state. In the second, the BUSY signal cannot be
+ * fallen down and the device have to be reseted.
+ * This limit is defined as approximatively the double of the deglitch one.
+ */
+#define CONV_TIME_LIMIT    50      /* ms */
+
+/* 
+ * Length of the data structure
+ */
+#define DATA_LENGTH       sizeof(struct ts_pen_info)
+
+/*
+ * Size of the buffer for the event queue
+ */
+#define TS_BUF_SIZE        32*DATA_LENGTH
+
+/*
+ * Minor number for the touch screen device. Major is 10 because of the misc 
+ * type of the driver.
+ */
+#define MC68328DIGI_MINOR    9
+
+/*
+ * SPIMCONT fields for this app (not defined in asm/MC68EZ328.h).
+ */
+#define SPIMCONT_DATARATE ( 7 <<SPIMCONT_DATA_RATE_SHIFT)/* SPICLK = CLK / 512 */
+#define SPIMCONT_BITCOUNT (15<< 0)                      /* 16 bits transfert  */
+
+/*
+ * SPIMCONT used values.
+ */
+#define SPIMCONT_INIT (SPIMCONT_DATARATE    | \
+                       SPIMCONT_ENABLE      | \
+                       SPIMCONT_XCH      *0 | \
+                       SPIMCONT_IRQ      *0 | \
+                       SPIMCONT_IRQEN       | \
+                       SPIMCONT_PHA         | \
+                       SPIMCONT_POL         | \
+                       SPIMCONT_BITCOUNT      )
+
+/*
+ * ADS7843 fields (BURR-BROWN Touch Screen Controller).
+ */
+#define ADS7843_START_BIT (1<<7)
+#define ADS7843_A2        (1<<6)
+#define ADS7843_A1        (1<<5)
+#define ADS7843_A0        (1<<4)
+#define ADS7843_MODE      (1<<3)  /* HIGH = 8, LOW = 12 bits conversion */
+#define ADS7843_SER_DFR   (1<<2)  /* LOW = differential mode            */
+#define ADS7843_PD1       (1<<1)  /* PD1,PD0 = 11  PENIRQ disable       */
+#define ADS7843_PD0       (1<<0)  /* PD1,PD0 = 00  PENIRQ enable        */
+
+/*
+ * SPIMDATA used values.
+ */
+/*
+ * Ask for X conversion. Disable PENIRQ.
+ */
+#define SPIMDATA_ASKX   (ADS7843_START_BIT   | \
+                         ADS7843_A2          | \
+			 ADS7843_A1        *0| \
+			 ADS7843_A0          | \
+                         ADS7843_MODE      *0| \
+                         ADS7843_SER_DFR   *0| \
+                         ADS7843_PD1         | \
+                         ADS7843_PD0            )
+/*
+ * Ask for Y conversion. Disable PENIRQ.
+ */
+#define SPIMDATA_ASKY   (ADS7843_START_BIT   | \
+                         ADS7843_A2        *0| \
+ 			 ADS7843_A1        *0| \
+	 	 	 ADS7843_A0          | \
+                         ADS7843_MODE      *0| \
+                         ADS7843_SER_DFR   *0| \
+                         ADS7843_PD1         | \
+                         ADS7843_PD0            )
+/*
+ * Enable PENIRQ.
+ */
+#define SPIMDATA_NOP    (ADS7843_START_BIT   | \
+                         ADS7843_A2        *0| \
+ 			 ADS7843_A1        *0| \
+	 	 	 ADS7843_A0        *0| \
+                         ADS7843_MODE      *0| \
+                         ADS7843_SER_DFR   *0| \
+                         ADS7843_PD1       *0| \
+                         ADS7843_PD0       *0   )
+/*
+ * Generate clock to fall pull BUSY signal.
+ * No start bit to avoid generating a BUSY at end of the transfert.
+ */
+#define SPIMDATA_NULL    0
+
+/*
+ * Useful masks.
+ */
+#if defined (CONFIG_UCDIMM)
+#define PEN_MASK	PD_IRQ6  /* pen irq signal from the Burr-Brown is */
+#define PEN_MASK_2	PD_IRQ1  /* connected to 2 pins of the DragonBall */
+                             /* (bit 2 port F and bit 4 port D)       */
+#define BUSY_MASK	PF_A22
+#define CS_MASK		PF_CSA1
+#define PESEL_MASK	0x07
+#define CONV_MASK	0x0FFF   /* 12 bit conversion */
+
+#define PEN_IRQ_NUM	IRQ6_IRQ_NUM
+
+#define CS_DATA		PFDATA
+#define CS_PUEN		PFPUEN
+#define CS_DIR		PFDIR
+#define CS_SEL		PFSEL
+
+#define PENIRQ_DATA 	PDDATA
+#define PENIRQ_PUEN	PDPUEN
+#define PENIRQ_DIR	PDDIR
+#define PENIRQ_SEL	PDSEL
+#define ICR_PENPOL	ICR_POL6
+#define IMR_MPEN	IMR_MIRQ6
+
+#else
+#error "unexpected"
+#define USE_PENIRQ_PULUP
+#define PEN_MASK	PF_IRQ5  /* pen irq signal from the Burr-Brown is */
+#define PEN_MASK_2	PD_IRQ1  /* connected to 2 pins of the DragonBall */
+                             /* (bit 2 port F and bit 4 port D)       */
+#define BUSY_MASK	PF_A22
+#define CS_MASK		PB_CSD0_CAS0
+#define PESEL_MASK	0x07
+#define CONV_MASK	0x0FFF   /* 12 bit conversion */
+
+#define PEN_IRQ_NUM	IRQ5_IRQ_NUM
+
+/* chip select register offset */
+#define CS_DATA		PBDATA
+#define CS_PUEN		PBPUEN
+#define CS_DIR		PBDIR
+#define CS_SEL		PBSEL
+
+/* pen irq register offsets and data */
+#define PENIRQ_DATA	PFDATA
+#define PENIRQ_PUEN	PFPUEN
+#define PENIRQ_DIR	PFDIR
+#define PENIRQ_SEL	PFSEL
+#define ICR_PENPOL	ICR_POL5
+#define IMR_MPEN	IMR_MIRQ5
+#endif
+
+
+/*
+ * Touch screen driver states.
+ */
+#define TS_DRV_ERROR       -1
+#define TS_DRV_IDLE         0
+#define TS_DRV_WAIT         1
+#define TS_DRV_ASKX         2
+#define TS_DRV_ASKY         3
+#define TS_DRV_READX        4
+#define TS_DRV_READY        5
+
+/*
+ * Conversion status.
+ */
+#define CONV_ERROR      -1   /* error during conversion flow        */    
+#define CONV_END         0   /* conversion ended (= pen is up)      */
+#define CONV_LOOP        1   /* conversion continue (= pen is down) */
+
+/*----------------------------------------------------------------------------*/
+/* macros --------------------------------------------------------------------*/
+
+#define TICKS(nbms)        ((HZ*(nbms))/1000)
+
+/*----------------------------------------------------------------------------*/
+
+/*
+ * Look in the PF register if it is on interrupt state.
+ */
+#ifdef CONFIG_XCOPILOT_BUGS
+# define IS_PEN_DOWN    ((IPR&IPR_PEN)!=0)
+#else
+# define IS_PEN_DOWN	((PENIRQ_DATA & PEN_MASK)==ST_PEN_DOWN)
+#endif
+
+/*
+ * State of the BUSY signal of the SPIM.
+ */
+#define IS_BUSY_ENDED   ((PFDATA & BUSY_MASK)==0)
+
+/*
+ * Write the SPIM (data and control).
+ */
+#define SET_SPIMDATA(x) { SPIMDATA = x; }
+#define SET_SPIMCONT(x) { SPIMCONT = x; }
+
+/*----------------------------------------------------------------------------*/
+
+#define SPIM_ENABLE  { SET_SPIMCONT(SPIMCONT_ENABLE); }  /* enable SPIM       */
+#define SPIM_INIT    { SPIMCONT |= SPIMCONT_INIT; }      /* init SPIM         */
+#define SPIM_DISABLE { SET_SPIMCONT(0x0000); }           /* disable SPIM      */
+
+/*----------------------------------------------------------------------------*/
+#ifdef CONFIG_XCOPILOT_BUGS
+# define CARD_SELECT   
+# define CARD_DESELECT 
+#else
+# define CARD_SELECT   { CS_DATA &= ~CS_MASK; }     /* PB4 active (=low)       */
+# define CARD_DESELECT { CS_DATA |=  CS_MASK; }     /* PB4 inactive (=high)    */
+#endif
+/*----------------------------------------------------------------------------*/
+
+#define ENABLE_PEN_IRQ    { IMR &= ~IMR_MPEN; }
+#define ENABLE_SPIM_IRQ   { IMR &= ~IMR_MSPI; SPIMCONT |= SPIMCONT_IRQEN; }
+
+#define DISABLE_PEN_IRQ   { IMR |= IMR_MPEN; }
+#define DISABLE_SPIM_IRQ  { SPIMCONT &= ~SPIMCONT_IRQEN; IMR |= IMR_MSPI; }
+
+#define CLEAR_SPIM_IRQ    { SPIMCONT &= ~SPIMCONT_IRQ; }
+
+/*----------------------------------------------------------------------------*/
+/* predefinitions ------------------------------------------------------------*/
+
+static void handle_timeout(void);
+static void handle_pen_irq(int irq, void *dev_id, struct pt_regs *regs);
+static void handle_spi_irq(void);
+
+/*----------------------------------------------------------------------------*/
+/* structure -----------------------------------------------------------------*/
+
+struct ts_pen_position { int x,y; };
+
+struct ts_queue {
+  unsigned long head;
+  unsigned long tail;
+  wait_queue_head_t proc_list;
+  struct fasync_struct *fasync;
+  unsigned char buf[TS_BUF_SIZE];
+};
+
+/*----------------------------------------------------------------------------*/
+/* Variables -----------------------------------------------------------------*/
+
+/*
+ * driver state variable.
+ */
+static int ts_drv_state;
+
+/*
+ * first tick initiated at ts_open.
+ */
+static struct timeval   first_tick;
+
+/*
+ * pen state.
+ */
+static int new_pen_state;
+
+/*
+ * event counter.
+ */
+static int ev_counter;
+
+/*
+ * counter to differentiate a click from a move.
+ */
+static int state_counter;
+
+static struct timer_list         ts_wake_time;
+
+/*
+ * drv parameters.
+ */
+static struct ts_drv_params      current_params;
+static int                       sample_ticks;
+/*
+ * pen info variables.
+ */
+static struct ts_pen_info        ts_pen;
+static struct ts_pen_info        ts_pen_prev;
+static struct ts_pen_position    current_pos;
+
+/*
+ * driver management.
+ */
+static struct ts_queue *queue;
+static int    device_open = 0;   /* number of open device to prevent concurrent
+                                  * access to the same device
+				  */
+
+
+/*----------------------------------------------------------------------------*/
+/* Init & release functions --------------------------------------------------*/
+
+static void init_ts_state(void) {
+  DISABLE_SPIM_IRQ;      /* Disable SPIM interrupt */
+
+  ts_drv_state = TS_DRV_IDLE;
+  state_counter = 0;
+
+  ENABLE_PEN_IRQ;        /* Enable interrupt IRQ5  */
+}
+
+static void init_ts_pen_values(void) {
+  ts_pen.x = 0;ts_pen.y = 0;
+  ts_pen.dx = 0;ts_pen.dy = 0;
+  ts_pen.event = EV_PEN_UP;
+  ts_pen.state &= 0;ts_pen.state |= ST_PEN_UP;
+
+  ts_pen_prev.x = 0;ts_pen_prev.y = 0;
+  ts_pen_prev.dx = 0;ts_pen_prev.dy = 0;
+  ts_pen_prev.event = EV_PEN_UP;
+  ts_pen_prev.state &= 0;ts_pen_prev.state |= ST_PEN_UP;
+  
+  new_pen_state = 0;
+  ev_counter = 0;
+  do_gettimeofday(&first_tick);
+}
+
+static void init_ts_timer(struct timer_list *timer) {
+  init_timer(timer);
+  timer->function = (void *)handle_timeout;
+}
+
+static void release_ts_timer(struct timer_list *timer) {
+  del_timer(timer);
+}
+
+/*
+ * Set default values for the params of the driver.
+ */
+static void init_ts_settings(void) {
+  current_params.version = MC68328DIGI_VERSION;
+  current_params.version_req = 0;
+  current_params.x_ratio_num = 1;
+  current_params.x_ratio_den = 1;
+  current_params.y_ratio_num = 1;
+  current_params.y_ratio_den = 1;
+  current_params.x_offset = 0;
+  current_params.y_offset = 0;
+  current_params.xy_swap = 0;
+  current_params.x_min = 0;
+  current_params.x_max = 4095;
+  current_params.y_min = 0;
+  current_params.y_max = 4095;
+  current_params.mv_thrs = 50;
+  current_params.follow_thrs = 5;    /* to eliminate the conversion noise */
+  current_params.sample_ms = 20;
+  current_params.deglitch_on = 1;
+  current_params.event_queue_on = 1;
+  sample_ticks = TICKS(current_params.sample_ms);
+}
+
+static void init_ts_hardware(void) {
+  /* Set bit 2 of port F for interrupt (IRQ5 for pen_irq)                 */
+#if 0
+  PENIRQ_PUEN |= PEN_MASK;     /* Port F as pull-up			*/
+#endif
+  PENIRQ_DIR &= ~PEN_MASK;    /* PF1 as input                                 */
+  PENIRQ_SEL &= ~PEN_MASK;    /* PF1 internal chip function is connected
+			       */
+#if 0
+  /* Set polarity of IRQ5 as low (interrupt occure when signal is low)    */
+  ICR &= ~ICR_PENPOL;
+#endif
+
+  /* Init stuff for port E. The 3 LSB are multiplexed with the SPIM       */
+  PESEL &= ~PESEL_MASK;
+  
+  /* Set bit 4 of port B for the CARD_SELECT signal of ADS7843 as output. */
+#ifndef CONFIG_XCOPILOT_BUGS
+  CS_PUEN |= CS_MASK;       /* Port B as pull-up                           */
+  CS_DIR  |= CS_MASK;       /* PB4 as output                               */
+  CS_DATA |= CS_MASK;       /* PB4 inactive (=high)                        */
+  CS_SEL  |= CS_MASK;       /* PB4 as I/O not dedicated                    */
+#endif
+  
+  /* Set bit 5 of port F for the BUSY signal of ADS7843 as input          */
+  PFPUEN |= BUSY_MASK;     /* Port F as pull-up                           */
+  PFDIR  &= ~BUSY_MASK;    /* PF5 as input                                */
+  PFSEL  |= BUSY_MASK;     /* PF5 I/O port function pin is connected      */
+
+#ifdef USE_PENIRQ_PULLUP
+  /* Set bit 4 of port D for the pen irq pull-up of ADS7843 as output.    */
+  PDDIR  |= PEN_MASK_2;    /* PD4 as output                               */
+  PDDATA |= PEN_MASK_2;    /* PD4 up (pull-up)                            */
+  PDPUEN |= PEN_MASK_2;    /* PD4 as pull-up                              */
+#ifndef CONFIG_XCOPILOT_BUGS
+  PDSEL  |= PEN_MASK_2;    /* PD4 I/O port function pin is connected      */
+#endif
+#endif
+}
+
+
+/*
+ * Reset bits used in each register to their default value.
+ */
+static void release_ts_hardware(void) {
+                          /* Register   default value */
+#ifndef CONFIG_XCOPILOT_BUGS
+  PESEL  |= PESEL_MASK;   /* PESEL      0xFF          */
+  CS_DIR  &= ~CS_MASK;    /* PBDIR      0x00          */
+  CS_DATA &= ~CS_MASK;    /* PBDATA     0x00          */
+  CS_PUEN |= CS_MASK;     /* PBPUEN     0xFF          */
+  CS_SEL  |= CS_MASK;     /* PBSEL      0xFF          */
+#ifdef USE_PENIRQ_PULLUP
+  PDDIR  |= PEN_MASK_2;   /* PDDIR      0xFF          */
+  PDDATA |= PEN_MASK_2;   /* PDDATA     0xF0          */
+  PDPUEN |= PEN_MASK_2;   /* PDPUEN     0xFF          */
+  PDSEL  |= PEN_MASK_2;   /* PDSEL      0xF0          */
+#endif
+  PENIRQ_PUEN |= PEN_MASK;     /* PFPUEN     0xFF          */
+  PENIRQ_DIR  &= ~PEN_MASK;    /* PFDIR      0x00          */
+  PENIRQ_SEL  |= PEN_MASK;     /* PFSEL      0xFF          */
+#endif
+  IMR    |= IMR_MPEN;     /* IMR        0xFFFFFFFF    */
+                          /* I release it anyway!     */ 
+}
+
+static void init_ts_drv(void) {
+  printk("a\n");
+  init_ts_state();
+  printk("b\n");
+  init_ts_pen_values();
+  printk("c\n");
+  init_ts_timer(&ts_wake_time);
+  printk("d\n");
+  init_ts_hardware();
+  printk("e\n");
+}
+
+static void release_ts_drv(void) {
+  release_ts_timer(&ts_wake_time);
+  release_ts_hardware();
+}
+
+
+/*----------------------------------------------------------------------------*/
+/* scaling functions ---------------------------------------------------------*/
+
+static inline void rescale_xpos(int *x) {
+  *x &= CONV_MASK;
+
+  *x *= current_params.x_ratio_num;
+  *x /= current_params.x_ratio_den;
+  *x += current_params.x_offset;
+  *x = (*x > current_params.x_max ? current_params.x_max :
+	(*x < current_params.x_min ? current_params.x_min :
+	 *x));
+}
+
+static inline void rescale_ypos(int *y) {
+  *y &= CONV_MASK;
+
+  *y *= current_params.y_ratio_num;
+  *y /= current_params.y_ratio_den;
+  *y += current_params.y_offset;
+  *y = (*y > current_params.y_max ? current_params.y_max :
+	(*y < current_params.y_min ? current_params.y_min :
+	 *y));
+}
+
+static inline void swap_xy(int *x, int *y)
+{
+  if(current_params.xy_swap) {
+    int t = *x;
+    *x = *y;
+    *y = t;
+  }
+}
+
+/*----------------------------------------------------------------------------*/
+/* xcopilot compatibility hacks ----------------------------------------------*/
+#ifdef CONFIG_XCOPILOT_BUGS
+
+/* xcopilot has the following bugs:
+ *
+ * - Disabling the penirq has no effect; we keep on getting irqs even when
+ *   penirq is disabled; this is not too annoying: we just trash pen irq events
+ *   that come when disabled.
+ *
+ * - SPIM interrupt is not simulated; this is not too annoying: we just read
+ *   SPI data immediately and bypass a couple of states related to SPI irq.
+ *
+ * - We do not get mouse drag events; this is a known xcopilot bug.
+ *   This is annoying: we miss all moves ! You should patch and recompile
+ *   your xcopilot.
+ *
+ *   This has been reported as Debian bug #64367, and there is a patch there:
+ *     http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=64367&repeatmerged=yes
+ *   which is:
+ *   +-----------------------------------------------------------------------+
+ *   | --- display.c   Tue Aug 25 14:56:02 1998
+ *   | +++ display2.c  Fri May 19 16:07:52 2000
+ *   | @@ -439,7 +439,7 @@
+ *   | static void HandleDigitizer(Widget w, XtPointer client_data, XEvent\
+ *   | *event, Boolean *continue_to_dispatch)
+ *   | {
+ *   | -  Time start;
+ *   | +  static Time start;
+ *   | 
+ *   | *continue_to_dispatch = True;
+ *   +-----------------------------------------------------------------------+
+ *   In short, add 'static' to the declaration of 'start' in HandleDigitizer()
+ *   in display.c
+ *
+ *   With this patch, all works perfectly !
+ *
+ * - The pen state can be read only in IPR, not in port D; again, we're doing
+ *   the workaround.
+ *
+ * With all these workarounds in this file, and with the patch on xcopilot,
+ * things go perfectly smoothly.
+ *
+ */
+
+/*
+ * Ugly stuff to read the mouse position on xcopilot
+ *
+ * We get the position of the last mouse up/down only, we get no moves !!! :-(
+ */
+static void xcopilot_read_now(void) {
+    PFDATA &= ~0xf; PFDATA |= 6;
+    SPIMCONT |= SPIMCONT_XCH | SPIMCONT_IRQEN;
+    current_pos.x = SPIMDATA;
+    rescale_xpos(&current_pos.x);
+
+    PFDATA &= ~0xf; PFDATA |= 9;
+    SPIMCONT |= SPIMCONT_XCH | SPIMCONT_IRQEN;
+    current_pos.y = SPIMDATA;
+    rescale_ypos(&current_pos.y);
+
+    swap_xy(&current_pos.x, &current_pos.y);
+}
+
+
+#endif
+/*----------------------------------------------------------------------------*/
+/* flow functions ------------------------------------------------------------*/
+
+/*
+ * Set timer irq to now + delay ticks.
+ */
+static void set_timer_irq(struct timer_list *timer,int delay) {
+  del_timer(timer);
+  timer->expires = jiffies + delay;
+  add_timer(timer);
+}
+
+/*
+ * Set ADS7843 and SPIM parameters for transfer.
+ */
+static void set_SPIM_transfert(void) {
+  /* DragonBall drive I/O 1 and I/O 2 LOW to reverse bias the PENIRQ diode
+   * of the ADS7843
+   */
+#ifdef USE_PENIRQ_PULLUP
+  PDDATA &= ~PEN_MASK_2;        /* Pull down I/0 2 of PENIRQ */
+#endif
+  PENIRQ_DIR  |= PEN_MASK;      /* I/O 1 of PENIRQ as output */
+  PENIRQ_DATA &= ~PEN_MASK;     /* Pull down I/O 2 of PENIRQ */
+
+  /* Initiate selection and parameters for using the Burr-Brown ADS7843
+   * and the DragonBall SPIM.
+   */
+  CARD_SELECT;          /* Select ADS7843.     */
+  SPIM_ENABLE;          /* Enable SPIM         */
+  SPIM_INIT;            /* Set SPIM parameters */
+}
+
+/*
+ * Clock the Burr-Brown to fall the AD_BUSY. 
+ * With a 'start' bit and PD1,PD0 = 00 to enable PENIRQ.
+ * Used for the first pen irq after booting. And when error occures during
+ * conversion that need an initialisation.
+ */
+static void fall_BUSY_enable_PENIRQ(void) {
+  SET_SPIMDATA(SPIMDATA_NOP);
+  SPIMCONT |= SPIMCONT_XCH;     /* initiate exchange */
+}
+
+/*
+ * Release transfer settings.
+ */
+static void release_SPIM_transfert(void) {
+  SPIM_DISABLE;
+  CARD_DESELECT;
+
+#ifdef USE_PENIRQ_PULLUP
+  PDDATA |= PEN_MASK_2;       /* Pull up I/0 2 of PENIRQ   */
+#endif
+  PENIRQ_DIR  &= ~PEN_MASK;   /* I/O 1 of PENIRQ as input  */
+  PENIRQ_DATA |= PEN_MASK;    /* Pull down I/O 2 of PENIRQ */
+}
+
+/*
+ * Ask for an X conversion.
+ */
+static void ask_x_conv(void) {
+  SET_SPIMDATA(SPIMDATA_ASKX);
+  SPIMCONT |= SPIMCONT_XCH;     /* initiate exchange */
+}
+
+/*
+ * Ask for an Y conversion.
+ */
+static void ask_y_conv(void) {
+  SET_SPIMDATA(SPIMDATA_ASKY);
+  SPIMCONT |= SPIMCONT_XCH;     /* initiate exchange */
+}
+
+/*
+ * Get the X conversion. Re-enable the PENIRQ.
+ */
+static void read_x_conv(void) {
+  current_pos.x = (SPIMDATA & 0x7FF8) >> 3;
+  /*
+   * The first clock is used to fall the BUSY line and the following 15 clks
+   * to transfert the 12 bits of the conversion, MSB first.
+   * The result will then be in the SPIM register in the bits 14 to 3.
+   */
+  SET_SPIMDATA(SPIMDATA_NOP);   /* nop with a start bit to re-enable */
+  SPIMCONT |= SPIMCONT_XCH;     /* the pen irq.                      */
+
+  rescale_xpos(&current_pos.x);
+}
+
+/*
+ * Get the Y result. Clock the Burr-Brown to fall the BUSY.
+ */
+static void read_y_conv(void) {
+  current_pos.y = (SPIMDATA & 0x7FF8) >> 3;
+  /* Same remark as upper. */
+  SET_SPIMDATA(SPIMDATA_NULL);  /* No start bit to fall the BUSY without */
+  SPIMCONT |= SPIMCONT_XCH;     /* initiating another BUSY...            */
+
+  rescale_ypos(&current_pos.y);
+}
+
+/*
+ * Get one char from the queue buffer.
+ * AND the head with 'TS_BUF_SIZE -1' to have the loopback
+ */
+static unsigned char get_char_from_queue(void) {
+  unsigned int result;
+
+  result = queue->buf[queue->tail];
+  queue->tail = (queue->tail + 1) & (TS_BUF_SIZE - 1);
+  return result;
+}
+
+/*
+ * Write one event in the queue buffer.
+ * Test if there is place for an event = the head cannot be just one event
+ * length after the queue.
+ */
+static void put_in_queue(char *in, int len) {
+  unsigned long head    = queue->head;
+  unsigned long maxhead = (queue->tail - len) & (TS_BUF_SIZE - 1);
+  int i;
+  
+  if(head != maxhead)              /* There is place for the event */
+    for(i=0;i<len;i++) {
+      queue->buf[head] = in[i];
+      head++;
+      head &= (TS_BUF_SIZE - 1);
+    }
+  //else printk("%0: Queue is full !!!!\n", __file__);
+  queue->head = head;
+}
+
+/*
+ * Test if queue is empty.
+ */
+static inline int queue_empty(void) {
+  return queue->head == queue->tail;
+}
+
+/*
+ * Test if the delta move of the pen is enough big to say that this is a really
+ * move and not due to noise.
+ */
+static int is_moving(void) {
+  int threshold;
+  int dx, dy;
+  
+  threshold=((ts_pen_prev.event & EV_PEN_MOVE) > 0 ?
+             current_params.follow_thrs : current_params.mv_thrs);
+  dx = current_pos.x-ts_pen_prev.x;
+  dy = current_pos.y-ts_pen_prev.y;
+  if(dx < 0) dx = -dx; /* abs() */
+  if(dy < 0) dy = -dy;
+  return (dx > threshold ? 1 :
+	  (dy > threshold ? 1 : 0));
+}
+
+static void copy_info(void) {
+  ts_pen_prev.x = ts_pen.x;
+  ts_pen_prev.y = ts_pen.y;
+  ts_pen_prev.dx = ts_pen.dx;
+  ts_pen_prev.dy = ts_pen.dy;
+  ts_pen_prev.event = ts_pen.event;
+  ts_pen_prev.state = ts_pen.state;
+  ts_pen_prev.ev_no = ts_pen.ev_no;
+  ts_pen_prev.ev_time = ts_pen.ev_time;
+}
+
+unsigned long set_ev_time(void) {
+  struct timeval now;
+
+  do_gettimeofday(&now);
+  return (now.tv_sec -first_tick.tv_sec )*1000 +
+         (now.tv_usec-first_tick.tv_usec)/1000;
+}
+
+static void cause_event(int conv) {
+
+  switch(conv) {
+
+  case CONV_ERROR: /* error occure during conversion */
+    ts_pen.state &= 0;            /* clear */
+    ts_pen.state |= ST_PEN_UP;    /* recover a stable state for the drv.      */
+    ts_pen.state |= ST_PEN_ERROR; /* tell that the state is due to an error   */
+    ts_pen.event = EV_PEN_UP;     /* event = pen go to up */
+    ts_pen.x = ts_pen_prev.x;     /* get previous coord as current to by-pass */
+    ts_pen.y = ts_pen_prev.y;     /* possible errors                          */
+    ts_pen.dx = 0;
+    ts_pen.dy = 0;
+    ts_pen.ev_no = ev_counter++;    /* get no of event   */
+    ts_pen.ev_time = set_ev_time(); /* get time of event */
+    copy_info();                    /* remember info */
+    if(current_params.event_queue_on)
+      put_in_queue((char *)&ts_pen,DATA_LENGTH);  /* queue event */
+
+    /* tell user space progs that a new state occure */
+    new_pen_state = 1;
+    /* signal asynchronous readers that data arrives */
+    if(queue->fasync)
+      kill_fasync(&queue->fasync, SIGIO, POLL_IN);
+    wake_up_interruptible(&queue->proc_list);  /* tell user space progs */
+    break;
+    
+  case CONV_LOOP:  /* pen is down, conversion continue */    
+    ts_pen.state &= 0;          /* clear */
+    ts_pen.state &= ST_PEN_DOWN;
+
+    switch(state_counter) {       /* It could be a move   */
+	    
+    case 1:    /* the pen just went down, it's a new state */
+      ts_pen.x = current_pos.x;
+      ts_pen.y = current_pos.y;
+      ts_pen.dx = 0;
+      ts_pen.dy = 0;
+      ts_pen.event = EV_PEN_DOWN;      /* event = pen go to down */
+      ts_pen.ev_no = ev_counter++;     /* get no of event        */
+      ts_pen.ev_time = set_ev_time();  /* get time of event */
+      copy_info();                     /* remember info */
+      if(current_params.event_queue_on)
+        put_in_queue((char *)&ts_pen,DATA_LENGTH);  /* queue event */
+
+      /* tell user space progs that a new state occure */
+      new_pen_state = 1;
+      /* signal asynchronous readers that data arrives */
+      if(queue->fasync)
+        kill_fasync(&queue->fasync, SIGIO, POLL_IN);
+      wake_up_interruptible(&queue->proc_list);  /* tell user space progs */
+      break;
+
+    case 2:    /* the pen is down for at least 2 loop of the state machine */
+
+      if(is_moving()) {
+        ts_pen.event = EV_PEN_MOVE;
+        ts_pen.x = current_pos.x;
+        ts_pen.y = current_pos.y;
+        ts_pen.dx = ts_pen.x - ts_pen_prev.x;
+        ts_pen.dy = ts_pen.y - ts_pen_prev.y;
+        ts_pen.ev_no = ev_counter++;    /* get no of event   */
+        ts_pen.ev_time = set_ev_time(); /* get time of event */
+        copy_info();                    /* remember info */
+        if(current_params.event_queue_on)
+          put_in_queue((char *)&ts_pen,DATA_LENGTH);  /* queue event */
+
+        /*
+	 * pen is moving, then it's anyway a good reason to tell it to
+	 * user space progs
+	 */
+        new_pen_state = 1;
+        /* signal asynchronous readers that data arrives */
+        if(queue->fasync)
+          kill_fasync(&queue->fasync, SIGIO, POLL_IN);
+        wake_up_interruptible(&queue->proc_list);
+      }
+      else {
+        if(ts_pen_prev.event == EV_PEN_MOVE)  /* if previous state was moving */
+	  ts_pen.event = EV_PEN_MOVE;         /* -> keep it!                  */
+        ts_pen.x = ts_pen_prev.x;       /* No coord passing to     */
+        ts_pen.y = ts_pen_prev.y;       /* avoid Parkinson effects */
+        ts_pen.dx = 0;
+	ts_pen.dy = 0;  /* no wake-up interruptible because nothing new */
+        copy_info();    /* remember info */
+      }
+      break;
+    }
+    break;
+
+  case CONV_END:   /* pen is up, conversion ends */
+    ts_pen.state &= 0;         /* clear */
+    ts_pen.state |= ST_PEN_UP;
+    ts_pen.event = EV_PEN_UP;
+    ts_pen.x = current_pos.x;
+    ts_pen.y = current_pos.y;
+    ts_pen.dx = ts_pen.x - ts_pen_prev.x;
+    ts_pen.dy = ts_pen.y - ts_pen_prev.y;
+    ts_pen.ev_time = set_ev_time();  /* get time of event */
+    ts_pen.ev_no = ev_counter++;     /* get no of event   */
+    copy_info();                     /* remember info */
+    if(current_params.event_queue_on)
+      put_in_queue((char *)&ts_pen,DATA_LENGTH);  /* queue event */
+
+    /* tell user space progs that a new state occure */
+    new_pen_state = 1;
+    /* signal asynchronous readers that data arrives */
+    if(queue->fasync)
+      kill_fasync(&queue->fasync, SIGIO, POLL_IN);
+    wake_up_interruptible(&queue->proc_list);
+    break;
+  }
+}
+
+/*----------------------------------------------------------------------------*/
+/* Interrupt functions -------------------------------------------------------*/
+
+/*
+ * pen irq.
+ */
+static void handle_pen_irq(int irq, void *dev_id, struct pt_regs *regs) {
+  unsigned long flags;
+  int bypass_initial_timer = 0;
+
+  /* if unwanted interrupts come, trash them */ 
+  if(!device_open)
+    return;
+
+  PENIRQ_DATA &= ~PEN_MASK;
+
+#ifdef CONFIG_XCOPILOT_BUGS
+  if(IMR&IMR_MPEN) {
+    return;
+  }
+#endif
+  save_flags(flags);     /* disable interrupts */
+  cli();
+
+  switch(ts_drv_state) {
+
+  case TS_DRV_IDLE:  
+    DISABLE_PEN_IRQ;
+    ts_drv_state++;      /* update driver state */
+    if(current_params.deglitch_on)
+      set_timer_irq(&ts_wake_time,sample_ticks);
+    else
+      bypass_initial_timer = 1;
+    break;
+
+  default: /* Error */
+    /* PENIRQ is enable then just init the driver 
+     * Its not necessary to pull down the busy signal
+     */
+    init_ts_state();
+    break;
+  }    
+  restore_flags(flags);  /* Enable interrupts */
+
+  /* if deglitching is off, we haven't started the deglitching timeout
+   * so we do the inital sampling immediately:
+   */
+  if(bypass_initial_timer)
+    handle_timeout();
+}
+
+/*
+ * timer irq.
+ */
+static void handle_timeout(void) {
+  unsigned long flags;
+
+  /* if unwanted interrupts come, trash them */ 
+  if(!device_open)
+    return;
+  
+  save_flags(flags);     /* disable interrupts */
+  cli();
+  
+  switch(ts_drv_state) {
+
+  case TS_DRV_IDLE:  /* Error in the idle state of the driver */
+    printk("%s: Error in the idle state of the driver\n", __file__);
+    goto treat_error;
+  case TS_DRV_ASKX:  /* Error in release SPIM   */
+    printk("%s: Error in release SPIM\n", __file__);
+    goto treat_error;
+  case TS_DRV_ASKY:  /* Error in ask Y coord    */
+    printk("%s: Error in ask Y coord\n", __file__);
+    goto treat_error;
+  case TS_DRV_READX: /* Error in read X coord   */
+    printk("%s: Error in read X coord\n", __file__);
+    goto treat_error;
+  case TS_DRV_READY: /* Error in read Y coord   */
+    printk("%s: Error in read Y coord\n", __file__);
+    goto treat_error;
+  treat_error:
+    /* Force re-enable of PENIRQ because of an abnormal termination. Limit this
+     * initialization with a timer to define a more FATAL error ...
+     */
+    set_timer_irq(&ts_wake_time,TICKS(CONV_TIME_LIMIT));
+    ts_drv_state = TS_DRV_ERROR;
+    CLEAR_SPIM_IRQ;              /* Consume residual irq from spim */
+    ENABLE_SPIM_IRQ;
+    fall_BUSY_enable_PENIRQ();
+    break;
+    
+  case TS_DRV_WAIT:
+    if(state_counter) {
+      cause_event(CONV_LOOP);  /* only after one loop */
+    }
+    if(IS_PEN_DOWN) {
+      if(state_counter < 2) state_counter++;
+      set_timer_irq(&ts_wake_time,TICKS(CONV_TIME_LIMIT));
+      set_SPIM_transfert();
+      ts_drv_state++;
+      CLEAR_SPIM_IRQ;            /* Consume residual irq from spim */
+      ENABLE_SPIM_IRQ;
+      fall_BUSY_enable_PENIRQ();
+    }
+    else {
+      if(state_counter) {
+#ifdef CONFIG_XCOPILOT_BUGS
+	/* on xcopilot, we read the last mouse position now, because we
+	 * missed the moves, during which the position should have been
+	 * read
+	 */
+	xcopilot_read_now();
+#endif
+	cause_event(CONV_END);
+      }
+      init_ts_state();
+    }
+    break;
+    
+  case TS_DRV_ERROR:  /* Busy doesn't want to fall down -> reboot? */
+    panic(__FILE__": cannot fall pull BUSY signal\n");
+
+  default:
+    init_ts_state();
+  }
+  restore_flags(flags);  /* Enable interrupts */
+
+#ifdef CONFIG_XCOPILOT_BUGS
+  if (ts_drv_state==TS_DRV_ASKX) {
+    handle_spi_irq();
+  }
+  PENIRQ_DATA |= PEN_MASK;
+#endif
+}
+
+/*
+ * spi irq.
+ */
+static void handle_spi_irq(void) {
+  unsigned long flags;
+
+  /* if unwanted interrupts come, trash them */ 
+  if(!device_open)
+    return;
+  
+  save_flags(flags);     /* disable interrupts */
+  cli();
+  
+  CLEAR_SPIM_IRQ;       /* clear source of interrupt */
+
+  switch(ts_drv_state) {
+
+
+  case TS_DRV_ASKX:
+#ifdef CONFIG_XCOPILOT_BUGS
+    /* for xcopilot we bypass all SPI interrupt-related stuff
+     * and read the pos immediately
+     */
+    xcopilot_read_now();
+    ts_drv_state = TS_DRV_WAIT;
+    DISABLE_SPIM_IRQ;
+    release_SPIM_transfert();
+    set_timer_irq(&ts_wake_time,sample_ticks);
+    break;
+#endif
+    if(IS_BUSY_ENDED) {     /* If first BUSY down, then */
+      ask_x_conv();         /* go on with conversion    */
+      ts_drv_state++;
+    }
+    else  fall_BUSY_enable_PENIRQ();  /* else, re-loop  */
+    break;
+
+  case TS_DRV_ASKY:
+    ask_y_conv();
+    ts_drv_state++;
+    break;
+
+  case TS_DRV_READX:
+    read_x_conv();
+    ts_drv_state++;
+    break;
+
+  case TS_DRV_READY:
+    read_y_conv();
+    swap_xy(&current_pos.x, &current_pos.y);
+    ts_drv_state = TS_DRV_WAIT;
+    break;
+
+  case TS_DRV_WAIT:
+    DISABLE_SPIM_IRQ;
+    release_SPIM_transfert();
+    set_timer_irq(&ts_wake_time,sample_ticks);
+    break;
+
+  case TS_DRV_ERROR:
+    if(IS_BUSY_ENDED) {              /* If BUSY down... */
+      release_SPIM_transfert();
+      cause_event(CONV_ERROR);
+      init_ts_state();
+    }
+    else fall_BUSY_enable_PENIRQ();  /* else, re-loop */
+    break;
+
+  default:
+    init_ts_state();
+  }
+  restore_flags(flags);  /* Enable interrupts */
+
+#ifdef CONFIG_XCOPILOT_BUGS
+  PENIRQ_DATA |= PEN_MASK;
+#endif
+}
+
+/*----------------------------------------------------------------------------*/
+/* file_operations functions -------------------------------------------------*/
+
+/*
+ * Called whenever a process attempts to read the device it has already open.
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0))
+static ssize_t ts_read (struct file *file,
+                        char *buff,       /* the buffer to fill with data */
+			size_t len,       /* the length of the buffer.    */
+			loff_t *offset) { /* Our offset in the file       */
+#else
+static int ts_read(struct inode *inode, struct file *file,
+		   char *buff,            /* the buffer to fill with data */
+		   int len) {             /* the length of the buffer.    */
+		                          /* NO WRITE beyond that !!!     */
+#endif
+
+  char *p_buffer;
+  char c;
+  int  i;
+  int  err;
+
+  while(!new_pen_state) {    /* noting to read */
+    if(file->f_flags & O_NONBLOCK)
+      return -EAGAIN;
+    interruptible_sleep_on(&queue->proc_list);
+
+#if (LINUX_VERSION_CODE >= 0x020100)
+    if(signal_pending(current))
+#else
+    if(current->signal & ~current->blocked)  /* a signal arrived */
+#endif
+      return -ERESTARTSYS;    /* tell the fs layer to handle it  */
+    /* otherwise loop */
+  }
+
+  /* Force length to the one available */
+  len = DATA_LENGTH;
+
+  /* verify that the user space address to write is valid */
+  err = verify_area(VERIFY_WRITE,buff,len);
+  if(err) return err;
+
+  /*
+   * The events are anyway put in the queue.
+   * But the read could choose to get the last event or the next in queue.
+   * This decision is controlled through the ioctl function.
+   * When the read doesn't flush the queue, this last is always full.
+   */
+  if(current_params.event_queue_on) {
+    i = len;
+    while((i>0) && !queue_empty()) {
+      c = get_char_from_queue();
+      put_user(c,buff++);
+      i--;
+    }
+  }
+  else {
+    p_buffer = (char *)&ts_pen;
+    for(i=len-1;i>=0;i--)   put_user(p_buffer[i],buff+i);
+/*    for(i=0;i<len;i++)   put_user(p_buffer[i],buff+i);*/
+  }
+
+  if(queue_empty() || !current_params.event_queue_on)
+    new_pen_state = 0;  /* queue events fully consumned */
+  else
+    new_pen_state = 1;  /* queue not empty              */
+
+  if(len-i) {
+      file->f_dentry->d_inode->i_atime = CURRENT_TIME; /* nfi */
+      return len-i;
+  }
+
+  return 0;
+
+}
+
+/*
+ * select file operation seems to become poll since version 2.2 of the kernel
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0))
+static unsigned int ts_poll(struct file *file, poll_table *table) {
+
+  poll_wait(file,&queue->proc_list,table);
+  if (new_pen_state)
+    return POLLIN | POLLRDNORM;
+  return 0;
+
+}
+#else
+static int ts_select(struct inode *inode, struct file *file,
+                     int mode, select_table *table) {
+  if(mode != SEL_IN)
+    return 0;                   /* the device is readable only */
+  if(new_pen_state)
+    return 1;                   /* there is some new stuff to read */
+  select_wait(&queue->proc_list,table);    /* wait for data */
+  return 0;
+}
+#endif
+
+/*
+ * Called whenever a process attempts to do an ioctl to the device it has
+ * already open.
+ */
+static int ts_ioctl(struct inode *inode, struct file *file,
+		    unsigned int cmd,     /* the command to the ioctl */
+		    unsigned long arg) {  /* the parameter to it      */
+
+  struct ts_drv_params  new_params;
+  int  err;
+  int  i;
+  char *p_in;
+  char *p_out;
+
+  switch(cmd) {
+  
+  case TS_PARAMS_GET:  /* Get internal params. First check if user space area
+                        * to write is valid.
+			*/
+    err = verify_area(VERIFY_WRITE,(char *)arg,sizeof(current_params));
+    if(err) return err;
+    p_in  = (char *)&current_params;
+    p_out = (char *)arg;
+    for(i=0;i<sizeof(current_params);i++)
+      put_user(p_in[i],p_out+i);
+    return 0;
+
+  case TS_PARAMS_SET:  /* Set internal params. First check if user space area
+                        * to read is valid.
+			*/
+    err = verify_area(VERIFY_READ,(char *)arg,sizeof(new_params));
+    if(err) {
+      return err;
+    }
+
+    /* ok */
+    p_in  = (char *)&new_params;
+    p_out = (char *)arg;
+    for(i=0;i<sizeof(new_params);i++) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0))
+      get_user(p_in[i],p_out+i);
+#else
+      p_in[i] = get_user(p_out+i);
+#endif
+    }
+    
+    /* All the params are set with minimal test. */
+    memcpy((void*)&current_params, (void*)&new_params, sizeof(current_params));
+    sample_ticks = TICKS(current_params.sample_ms);
+
+    /* check version */
+    if(new_params.version_req!=-1) {
+      if(new_params.version_req!=MC68328DIGI_VERSION) {
+	printk("%s: error: driver version is %d, requested version is %d\n",
+	       __file__, MC68328DIGI_VERSION, new_params.version_req);
+	return -EBADRQC;
+      }
+    }
+
+    return 0;
+
+  default:  /* cmd is not an ioctl command */
+    return -ENOIOCTLCMD;
+  }
+}
+		    
+/*
+ * Called whenever a process attempts to open the device file.
+ */
+static int ts_open(struct inode *inode, struct file *file) {
+  int err;
+  /* To talk to only one device at a time */
+  if(device_open) return -EBUSY;
+
+  /* IRQ registration have to be done before the hardware is instructed to
+   * generate interruptions.
+   */
+  /* IRQ for pen */
+  err = request_irq(PEN_IRQ_NUM, handle_pen_irq,
+		    IRQ_FLG_STD,"touch_screen",NULL);
+  if(err) {
+    printk("%s: Error. Cannot attach IRQ %d to touch screen device\n",
+	   __file__, PEN_IRQ_NUM);
+    return err;
+  }
+  printk("%s: IRQ %d attached to touch screen\n",
+	 __file__, PEN_IRQ_NUM);
+
+  /* IRQ for SPIM */
+  err = request_irq(SPI_IRQ_NUM, handle_spi_irq,
+		    IRQ_FLG_STD,"spi_irq",NULL);
+  if(err) {
+    printk("%s: Error. Cannot attach IRQ %d to SPIM device\n",
+           __file__, SPI_IRQ_NUM);
+    return err;
+  }
+  printk("%s: IRQ %d attached to SPIM\n",
+	 __file__, SPI_IRQ_NUM);
+
+  /* Init hardware */
+  init_ts_drv();
+  
+  printk("digi: init hardware done..\n");
+
+  /* Init the queue */
+  queue = (struct ts_queue *) kmalloc(sizeof(*queue),GFP_KERNEL);
+  memset(queue,0,sizeof(*queue));
+  queue->head = queue->tail = 0;
+  init_waitqueue_head(&queue->proc_list);
+
+  /* Increment the usage count (number of opened references to the module)
+   * to be sure the module couldn't be removed while the file is open.
+   */
+  MOD_INC_USE_COUNT;
+
+  /* And my own counter too */
+  device_open++;
+
+  return 0;  /* open succeed */
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0))
+static int ts_fasync(int inode, struct file *file, int mode) {
+#else
+static int ts_fasync(struct inode *inode, struct file *file, int mode) {
+#endif
+
+  int retval;
+  
+  retval = fasync_helper(inode,file,mode,&queue->fasync);
+  if(retval < 0)
+    return retval;
+  return 0;
+}
+
+/*
+ * Called whenever a process attempts to close the device file.
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0))
+static int ts_release(struct inode *inode, struct file *file) {
+#else
+static void ts_release(struct inode *inode, struct file *file) {
+#endif
+
+  /* Remove this file from the asynchronously notified file's */
+  ts_fasync(inode,file,0);
+
+  /* Release hardware */
+  release_ts_drv();
+
+  /* Free the allocated memory for the queue */
+  kfree(queue);
+
+  /* IRQ have to be freed after the hardware is instructed not to interrupt
+   * the processor any more.
+   */
+  free_irq(SPI_IRQ_NUM,NULL);
+  free_irq(PEN_IRQ_NUM,NULL);
+
+  /* Decrement the usage count, otherwise once the file is open we'll never
+   * get rid of the module.
+   */
+  MOD_DEC_USE_COUNT;
+
+  /* And my own counter too */
+  device_open--;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0))
+  return 0;
+#endif
+}
+
+
+static struct file_operations ts_fops = {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))
+  owner:          THIS_MODULE,
+  read:           ts_read,
+  poll:           ts_poll,
+  ioctl:          ts_ioctl,
+  open:           ts_open,
+  release:        ts_release,
+  fasync:         ts_fasync,
+#else
+
+  NULL,       /* lseek              */
+  ts_read,    /* read               */
+  NULL,       /* write              */
+  NULL,       /* readdir            */
+#  if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0))
+  ts_poll,    /* poll               */
+#  else
+  ts_select,  /* select             */
+#  endif
+  ts_ioctl,   /* ioctl              */
+  NULL,       /* mmap               */
+  ts_open,    /* open               */
+#  if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0))
+  NULL,       /* flush              */
+#  endif
+  ts_release, /* release (close)    */
+  NULL,       /* fsync              */
+  ts_fasync   /* async notification */
+
+#endif
+};
+
+/*
+ * miscdevice structure for misc driver registration.
+ */
+static struct miscdevice mc68328_digi = {
+  MC68328DIGI_MINOR,"mc68328 digitizer",&ts_fops
+};
+
+/*
+ * Initialize the driver.
+ */
+static int __init mc68328digi_init(void) {
+  int err;
+
+  printk("%s: MC68328DIGI touch screen driver\n", __file__);
+
+  /* Register the misc device driver */
+  err = misc_register(&mc68328_digi);
+  if(err<0)
+    printk("%s: Error registering the device\n", __file__);
+  else
+    printk("%s: Device register with name: %s and number: %d %d\n",
+	   __file__, mc68328_digi.name, MC68328DIGI_MAJOR, mc68328_digi.minor);
+
+  /* Init prameters settings at boot time */
+  init_ts_settings();
+
+  return err;     /* A non zero value means that init_module failed */
+}
+
+/*
+ * Cleanup - undid whatever mc68328digi_init did.
+ */
+void mc68328digi_cleanup(void) {
+  /* Unregister device driver */
+  misc_deregister(&mc68328_digi);
+}  
+
+module_init(mc68328digi_init);
+module_exit(mc68328digi_cleanup);
diff -urN linux-2.4.29/drivers/char/mcf5272.h linux-2.4.29-uc1/drivers/char/mcf5272.h
--- linux-2.4.29/drivers/char/mcf5272.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/mcf5272.h	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,1899 @@
+/*********************************************************************
+ *
+ * Copyright:
+ *	MOTOROLA, INC. All Rights Reserved.  
+ *  You are hereby granted a copyright license to use, modify, and
+ *  distribute the SOFTWARE so long as this entire notice is
+ *  retained without alteration in any modified and/or redistributed
+ *  versions, and that such modified versions are clearly identified
+ *  as such. No licenses are granted by implication, estoppel or
+ *  otherwise under any patents or trademarks of Motorola, Inc. This 
+ *  software is provided on an "AS IS" basis and without warranty.
+ *
+ *  To the maximum extent permitted by applicable law, MOTOROLA 
+ *  DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING 
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+ *  PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH REGARD TO THE 
+ *  SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) AND ANY 
+ *  ACCOMPANYING WRITTEN MATERIALS.
+ * 
+ *  To the maximum extent permitted by applicable law, IN NO EVENT
+ *  SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING 
+ *  WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS 
+ *  INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY
+ *  LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.   
+ * 
+ *  Motorola assumes no responsibility for the maintenance and support
+ *  of this software
+ ********************************************************************/
+
+/*
+ * File:		MCF5272.h
+ * Purpose:		MCF5272 definitions
+ *
+ * Notes:
+ */
+
+#ifndef _CPU_MCF5272_H
+#define _CPU_MCF5272_H
+
+/***********************************************************************/
+/*
+ * Misc. Defines
+ */
+
+#ifdef	FALSE
+#undef	FALSE
+#endif
+#define FALSE	(0)
+
+#ifdef	TRUE
+#undef	TRUE
+#endif
+#define	TRUE	(1)
+
+#ifdef	NULL
+#undef	NULL
+#endif
+#define NULL	(0)
+
+/***********************************************************************/
+/*
+ * The basic data types
+ */
+
+typedef unsigned char		uint8;  /*  8 bits */
+typedef unsigned short int	uint16; /* 16 bits */
+typedef unsigned long int	uint32; /* 32 bits */
+
+typedef signed char		int8;   /*  8 bits */
+typedef signed short int	int16;  /* 16 bits */
+typedef signed long int		int32;  /* 32 bits */
+
+/***********************************************************************/
+/*
+ * Common M68K & ColdFire definitions
+ */
+
+#define ADDRESS			uint32
+#define INSTRUCTION		uint16
+#define ILLEGAL			0x4AFC
+#define CPU_WORD_SIZE	16
+
+/********************************************************************
+ * Routines and macros for accessing Input/Output devices
+ *******************************************************************/
+
+#define cpu_iord_8(ADDR)        *((volatile uint8 *)(ADDR))
+#define cpu_iord_16(ADDR)       *((volatile uint16 *)(ADDR))
+#define cpu_iord_32(ADDR)       *((volatile uint32 *)(ADDR))
+
+#define cpu_iowr_8(ADDR,DATA)   *((volatile uint8 *)(ADDR)) = (DATA)
+#define cpu_iowr_16(ADDR,DATA)  *((volatile uint16 *)(ADDR)) = (DATA)
+#define cpu_iowr_32(ADDR,DATA)  *((volatile uint32 *)(ADDR)) = (DATA)
+
+/***********************************************************************/
+
+#define MCF5200_SR_T		(0x8000)
+#define MCF5200_SR_S		(0x2000)
+#define MCF5200_SR_M		(0x1000)
+#define MCF5200_SR_IPL		(0x0700)
+#define MCF5200_SR_IPL_0	(0x0000)
+#define MCF5200_SR_IPL_1	(0x0100)
+#define MCF5200_SR_IPL_2	(0x0200)
+#define MCF5200_SR_IPL_3	(0x0300)
+#define MCF5200_SR_IPL_4	(0x0400)
+#define MCF5200_SR_IPL_5	(0x0500)
+#define MCF5200_SR_IPL_6	(0x0600)
+#define MCF5200_SR_IPL_7	(0x0700)
+#define MCF5200_SR_X		(0x0010)
+#define MCF5200_SR_N		(0x0008)
+#define MCF5200_SR_Z		(0x0004)
+#define MCF5200_SR_V		(0x0002)
+#define MCF5200_SR_C		(0x0001)
+
+/***********************************************************************/
+
+/*
+ * The ColdFire family of processors has a simplified exception stack
+ * frame that looks like the following:
+ *
+ *              3322222222221111 111111
+ *              1098765432109876 5432109876543210
+ *           8 +----------------+----------------+
+ *             |         Program Counter         |
+ *           4 +----------------+----------------+
+ *             |FS/Fmt/Vector/FS|      SR        |
+ *   SP -->  0 +----------------+----------------+
+ *
+ * The stack self-aligns to a 4-byte boundary at an exception, with
+ * the FS/Fmt/Vector/FS field indicating the size of the adjustment
+ * (SP += 0,1,2,3 bytes).
+ */
+
+#define MCF5200_RD_SF_FORMAT(PTR)	\
+	((*((uint16 *)(PTR)) >> 12) & 0x00FF)
+
+#define MCF5200_RD_SF_VECTOR(PTR)	\
+	((*((uint16 *)(PTR)) >>  2) & 0x00FF)
+
+#define MCF5200_RD_SF_FS(PTR)		\
+	( ((*((uint16 *)(PTR)) & 0x0C00) >> 8) | (*((uint16 *)(PTR)) & 0x0003) )
+
+#define MCF5200_SF_SR(PTR)	*((uint16 *)(PTR)+1)
+#define MCF5200_SF_PC(PTR)	*((uint32 *)(PTR)+1)
+
+#if 0
+typedef struct
+{
+	uint16	SR;
+	uint16	FS_FMT_VECTOR_FS;
+	uint32	PC;
+} MCF5200_STACK_FRAME;
+#endif
+
+
+/**********************************************************************
+*
+* Macro for computing address of on-chip peripheral registers
+*
+***********************************************************************/
+
+#define Mcf5272_addr(IMMP,OFFSET)   ((void *)&((uint8 *)IMMP)[OFFSET])
+
+/**********************************************************************
+*
+* Macros for accessing the on-chip I/O resources
+*
+***********************************************************************/
+
+#define Mcf5272_iord(IMMP,OFFSET,SIZE)		\
+    *(volatile uint ## SIZE *)(Mcf5272_addr(IMMP,OFFSET))
+
+#define Mcf5272_iowr(IMMP,OFFSET,SIZE,DATA)  \
+    *(volatile uint ## SIZE *)(Mcf5272_addr(IMMP,OFFSET)) = (DATA)
+
+/**********************************************************************
+*
+* CPU Space Registers
+*
+***********************************************************************/
+
+/* Bit level definitions and macros */
+#define MCF5272_CACR_CENB		(0x80000000)
+#define MCF5272_CACR_CFRZ		(0x08000000)
+#define MCF5272_CACR_CINV		(0x01000000)
+#define MCF5272_CACR_CMOD		(0x00000200)
+#define MCF5272_CACR_CWRP		(0x00000020)
+#define MCF5272_CACR_CLNF_00	(0x00000000)
+#define MCF5272_CACR_CLNF_01	(0x00000001)
+#define MCF5272_CACR_CLNF_10	(0x00000002)
+
+#define MCF5272_ACR_BASE(a)		((a)&0xFF000000)
+#define MCF5272_ACR_MASK(a)		(((a)&0xFF000000) >> 8)
+#define MCF5272_ACR_EN			(0x00008000)
+#define MCF5272_ACR_S_USER		(0x00000000)
+#define MCF5272_ACR_S_SUPER		(0x00002000)
+#define MCF5272_ACR_S_IGNORE	(0x00006000)
+#define MCF5272_ACR_ENIB		(0x00000080)
+#define MCF5272_ACR_CM			(0x00000040)
+#define MCF5272_ACR_WP			(0x00000004)
+
+#define MCF5272_SRAMBAR_BASE(a)	((a)&0xFFFFF000)
+#define MCF5272_SRAMBAR_WP		(0x00000100)
+#define MCF5272_SRAMBAR_CI		(0x00000020)
+#define MCF5272_SRAMBAR_SC		(0x00000010)
+#define MCF5272_SRAMBAR_SD		(0x00000008)
+#define MCF5272_SRAMBAR_UC		(0x00000004)
+#define MCF5272_SRAMBAR_UD		(0x00000002)
+#define MCF5272_SRAMBAR_V		(0x00000001)
+
+#define MCF5272_ROMBAR_BASE(a)	((a)&0xFFFFF000)
+#define MCF5272_ROMBAR_WP		(0x00000100)
+#define MCF5272_ROMBAR_CI		(0x00000080)
+#define MCF5272_ROMBAR_SC		(0x00000040)
+#define MCF5272_ROMBAR_SD		(0x00000020)
+#define MCF5272_ROMBAR_UC		(0x00000004)
+#define MCF5272_ROMBAR_UD		(0x00000002)
+#define MCF5272_ROMBAR_V		(0x00000001)
+
+#define MCF5272_MBAR_BASE(a)	((a)&0xFFFFFC00)
+#define MCF5272_MBAR_SC			(0x00000010)
+#define MCF5272_MBAR_SD			(0x00000008)
+#define MCF5272_MBAR_UC			(0x00000004)
+#define MCF5272_MBAR_UD			(0x00000002)
+#define MCF5272_MBAR_V			(0x00000001)
+
+/**********************************************************************
+*
+* System Configuration Registers
+*
+***********************************************************************/
+
+/* Offsets of the registers from the MBAR */
+#define MCF5272_SIM_MBAR		(0x0000)
+#define MCF5272_SIM_SCR			(0x0004)
+#define MCF5272_SIM_SPR			(0x0006)
+#define MCF5272_SIM_PMR			(0x0008)
+#define MCF5272_SIM_ALPR		(0x000E)
+#define MCF5272_SIM_DIR			(0x0010)
+
+/* Read access macros for general use */
+#define MCF5272_RD_SIM_MBAR(IMMP)	Mcf5272_iord(IMMP,MCF5272_SIM_MBAR,32)
+#define MCF5272_RD_SIM_SCR(IMMP)	Mcf5272_iord(IMMP,MCF5272_SIM_SCR,16)
+#define MCF5272_RD_SIM_SPR(IMMP)	Mcf5272_iord(IMMP,MCF5272_SIM_SPR,16)
+#define MCF5272_RD_SIM_PMR(IMMP)	Mcf5272_iord(IMMP,MCF5272_SIM_PMR,32)
+#define MCF5272_RD_SIM_DIR(IMMP)	Mcf5272_iord(IMMP,MCF5272_SIM_DIR,32)
+
+/* Write access macros for general use */
+#define MCF5272_WR_SIM_SCR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_SIM_SCR,16,DATA)
+#define MCF5272_WR_SIM_SPR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_SIM_SPR,16,DATA)
+#define MCF5272_WR_SIM_PMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_SIM_PMR,32,DATA)
+#define MCF5272_WR_SIM_ALPR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_SIM_ALPR,16,DATA)
+
+/* Bit level definitions and macros */
+#define MCF5272_SIM_SCR_HRST		0x1000
+#define MCF5272_SIM_SCR_DRAMRST		0x3000
+#define MCF5272_SIM_SCR_SWTR		0x2000
+#define MCF5272_SIM_SCR_AR			0x0080
+#define MCF5272_SIM_SCR_SOFT_RES	0x0040
+#define MCF5272_SIM_SCR_HWWD_128	0x0000
+#define MCF5272_SIM_SCR_HWWD_256	0x0001
+#define MCF5272_SIM_SCR_HWWD_512	0x0002
+#define MCF5272_SIM_SCR_HWWD_1024	0x0003
+#define MCF5272_SIM_SCR_HWWD_2048	0x0004
+#define MCF5272_SIM_SCR_HWWD_4096	0x0005
+#define MCF5272_SIM_SCR_HWWD_8192	0x0006
+#define MCF5272_SIM_SCR_HWWD_16384	0x0007
+
+#define MCF5272_SIM_SPR_ADC			0x8000
+#define MCF5272_SIM_SPR_ADCEN		0x0080
+#define MCF5272_SIM_SPR_WPV 		0x4000
+#define MCF5272_SIM_SPR_WPVEN		0x0040
+#define MCF5272_SIM_SPR_SMV			0x2000
+#define MCF5272_SIM_SPR_SMVEN		0x0020
+#define MCF5272_SIM_SPR_SBE			0x1000
+#define MCF5272_SIM_SPR_SBEEN		0x0010
+#define MCF5272_SIM_SPR_HWT			0x0800
+#define MCF5272_SIM_SPR_HWTEN		0x0008
+#define MCF5272_SIM_SPR_RPV 		0x0400
+#define MCF5272_SIM_SPR_RPVEN		0x0004
+#define MCF5272_SIM_SPR_EXT			0x0200
+#define MCF5272_SIM_SPR_EXTEN		0x0002
+#define MCF5272_SIM_SPR_SUV			0x0100
+#define MCF5272_SIM_SPR_SUVEN		0x0001
+
+#define MCF5272_SIM_PMR_BDMPDN      0x80000000
+#define MCF5272_SIM_PMR_ENETPDN     0x04000000
+#define MCF5272_SIM_PMR_PLIPPDN     0x02000000
+#define MCF5272_SIM_PMR_DRAMPDN     0x01000000
+#define MCF5272_SIM_PMR_DMAPDN      0x00800000
+#define MCF5272_SIM_PMR_PWMPDN      0x00400000
+#define MCF5272_SIM_PMR_QSPIPDN     0x00200000
+#define MCF5272_SIM_PMR_TIMERPDN    0x00100000
+#define MCF5272_SIM_PMR_GPIOPDN     0x00080000
+#define MCF5272_SIM_PMR_USBPDN      0x00040000
+#define MCF5272_SIM_PMR_UART1PDN    0x00020000
+#define MCF5272_SIM_PMR_UART0PDN    0x00010000
+#define MCF5272_SIM_PMR_USBWK       0x00000400
+#define MCF5272_SIM_PMR_UART1WK     0x00000200
+#define MCF5272_SIM_PMR_UART0WK     0x00000100
+#define MCF5272_SIM_PMR_MOS         0x00000020
+#define MCF5272_SIM_PMR_SLPEN       0x00000010
+
+/**********************************************************************
+*
+* Interrupt Controller Registers
+*
+***********************************************************************/
+
+/* Offsets of the registers from the MBAR */
+#define MCF5272_SIM_ICR1		(0x0020)
+#define MCF5272_SIM_ICR2		(0x0024)
+#define MCF5272_SIM_ICR3		(0x0028)
+#define MCF5272_SIM_ICR4		(0x002C)
+#define MCF5272_SIM_ISR			(0x0030)
+#define MCF5272_SIM_PITR		(0x0034)
+#define MCF5272_SIM_PIWR		(0x0038)
+#define MCF5272_SIM_PIVR		(0x003F)
+
+/* Read access macros for general use */
+#define MCF5272_RD_SIM_ICR1(IMMP)	Mcf5272_iord(IMMP,MCF5272_SIM_ICR1,32)
+#define MCF5272_RD_SIM_ICR2(IMMP)	Mcf5272_iord(IMMP,MCF5272_SIM_ICR2,32)
+#define MCF5272_RD_SIM_ICR3(IMMP)	Mcf5272_iord(IMMP,MCF5272_SIM_ICR3,32)
+#define MCF5272_RD_SIM_ICR4(IMMP)	Mcf5272_iord(IMMP,MCF5272_SIM_ICR4,32)
+#define MCF5272_RD_SIM_ISR(IMMP)	Mcf5272_iord(IMMP,MCF5272_SIM_ISR,32)
+#define MCF5272_RD_SIM_PITR(IMMP)	Mcf5272_iord(IMMP,MCF5272_SIM_PITR,32)
+#define MCF5272_RD_SIM_PIWR(IMMP)	Mcf5272_iord(IMMP,MCF5272_SIM_PIWR,32)
+#define MCF5272_RD_SIM_PIVR(IMMP)	Mcf5272_iord(IMMP,MCF5272_SIM_PIVR,8)
+
+/* Write access macros for general use */
+#define MCF5272_WR_SIM_ICR1(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_SIM_ICR1,32,DATA)
+#define MCF5272_WR_SIM_ICR2(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_SIM_ICR2,32,DATA)
+#define MCF5272_WR_SIM_ICR3(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_SIM_ICR3,32,DATA)
+#define MCF5272_WR_SIM_ICR4(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_SIM_ICR4,32,DATA)
+#define MCF5272_WR_SIM_PITR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_SIM_PITR,32,DATA)
+#define MCF5272_WR_SIM_PIWR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_SIM_PIWR,32,DATA)
+#define MCF5272_WR_SIM_PIVR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_SIM_PIVR,8,DATA)
+
+/* Bit level definitions and macros */
+#define MCF5272_SIM_ICR_INT1_IL(a)	( 0x80000000 | (((a)&0x07)<<28)	)
+#define MCF5272_SIM_ICR_INT2_IL(a)	( 0x08000000 | (((a)&0x07)<<24)	)
+#define MCF5272_SIM_ICR_INT3_IL(a)	( 0x00800000 | (((a)&0x07)<<20)	)
+#define MCF5272_SIM_ICR_INT4_IL(a)	( 0x00080000 | (((a)&0x07)<<16)	)
+#define MCF5272_SIM_ICR_TMR0_IL(a)	( 0x00008000 | (((a)&0x07)<<12)	)
+#define MCF5272_SIM_ICR_TMR1_IL(a)	( 0x00000800 | (((a)&0x07)<<8) )
+#define MCF5272_SIM_ICR_TMR2_IL(a)	( 0x00000080 | (((a)&0x07)<<4) )
+#define MCF5272_SIM_ICR_TMR3_IL(a)	( 0x00000008 | ((a)&0x07) )
+#define MCF5272_SIM_ICR_TMR_IL(a,x)	( (0x8 | ((a)&0x07)) << ((3-x)*4))
+
+#define MCF5272_SIM_ICR_UART0_IL(a)	( 0x80000000 | (((a)&0x07)<<28)	)
+#define MCF5272_SIM_ICR_UART1_IL(a)	( 0x08000000 | (((a)&0x07)<<24)	)
+#define MCF5272_SIM_ICR_PLIP_IL(a)	( 0x00800000 | (((a)&0x07)<<20)	)
+#define MCF5272_SIM_ICR_PLIA_IL(a)	( 0x00080000 | (((a)&0x07)<<16)	)
+#define MCF5272_SIM_ICR_USB0_IL(a)	( 0x00008000 | (((a)&0x07)<<12)	)
+#define MCF5272_SIM_ICR_USB1_IL(a)	( 0x00000800 | (((a)&0x07)<<8) )
+#define MCF5272_SIM_ICR_USB2_IL(a)	( 0x00000800 | (((a)&0x07)<<4) )
+#define MCF5272_SIM_ICR_USB3_IL(a)	( 0x00000800 | ((a)&0x07) )
+
+#define MCF5272_SIM_ICR_USB4_IL(a)	( 0x80000000 | (((a)&0x07)<<28)	)
+#define MCF5272_SIM_ICR_USB5_IL(a)	( 0x08000000 | (((a)&0x07)<<24)	)
+#define MCF5272_SIM_ICR_USB6_IL(a)	( 0x00800000 | (((a)&0x07)<<20)	)
+#define MCF5272_SIM_ICR_USB7_IL(a)	( 0x00080000 | (((a)&0x07)<<16)	)
+#define MCF5272_SIM_ICR_DMA_IL(a)	( 0x00008000 | (((a)&0x07)<<12)	)
+#define MCF5272_SIM_ICR_ERX_IL(a)	( 0x00000800 | (((a)&0x07)<<8) )
+#define MCF5272_SIM_ICR_ETX_IL(a)	( 0x00000080 | (((a)&0x07)<<4) )
+#define MCF5272_SIM_ICR_ENTC_IL(a)	( 0x00000008 | ((a)&0x07) )
+
+#define MCF5272_SIM_ICR_QSPI_IL(a)	( 0x80000000 | (((a)&0x07)<<28)	)
+#define MCF5272_SIM_ICR_INT5_IL(a)	( 0x08000000 | (((a)&0x07)<<24)	)
+#define MCF5272_SIM_ICR_INT6_IL(a)	( 0x00800000 | (((a)&0x07)<<20)	)
+#define MCF5272_SIM_ICR_SWTO_IL(a)	( 0x00080000 | (((a)&0x07)<<16)	)
+
+#define MCF5272_SIM_PITR_POS_EDGE	(0xF0000060)
+#define MCF5272_SIM_PITR_NEG_EDGE	(0x00000000)
+
+#define MCF5272_SIM_PIWR_INT1			(0x80000000)
+#define MCF5272_SIM_PIWR_INT2			(0x40000000)
+#define MCF5272_SIM_PIWR_INT3			(0x20000000)
+#define MCF5272_SIM_PIWR_INT4			(0x10000000)
+#define MCF5272_SIM_PIWR_TMR0			(0x08000000)
+#define MCF5272_SIM_PIWR_TMR1			(0x04000000)
+#define MCF5272_SIM_PIWR_TMR2			(0x02000000)
+#define MCF5272_SIM_PIWR_TMR3			(0x01000000)
+#define MCF5272_SIM_PIWR_UART0		(0x00800000)
+#define MCF5272_SIM_PIWR_UART1		(0x00400000)
+#define MCF5272_SIM_PIWR_PLIP			(0x00200000)
+#define MCF5272_SIM_PIWR_PLIA			(0x00100000)
+#define MCF5272_SIM_PIWR_USB_0			(0x00080000)
+#define MCF5272_SIM_PIWR_USB_1			(0x00040000)
+#define MCF5272_SIM_PIWR_USB_2			(0x00020000)
+#define MCF5272_SIM_PIWR_USB_3			(0x00010000)
+#define MCF5272_SIM_PIWR_USB_4			(0x00008000)
+#define MCF5272_SIM_PIWR_USB_5			(0x00004000)
+#define MCF5272_SIM_PIWR_USB_6			(0x00002000)
+#define MCF5272_SIM_PIWR_USB_7			(0x00001000)
+#define MCF5272_SIM_PIWR_DMA			(0x00000800)
+#define MCF5272_SIM_PIWR_ERx			(0x00000400)
+#define MCF5272_SIM_PIWR_ETx			(0x00000200)
+#define MCF5272_SIM_PIWR_ENTC			(0x00000100)
+#define MCF5272_SIM_PIWR_QSPI			(0x00000080)
+#define MCF5272_SIM_PIWR_INT5			(0x00000040)
+#define MCF5272_SIM_PIWR_INT6			(0x00000020)
+#define MCF5272_SIM_PIWR_SWTO			(0x00000010)
+
+#define MCF5272_SIM_PIVR_IL(a)		(((a)&0x07)<<5)
+#define MCF5272_SIM_PIVR_NORMAL		(0x40)
+
+/**********************************************************************
+*
+* Chip Select Registers
+*
+***********************************************************************/
+
+/* Offsets of the registers from the MBAR */
+#define MCF5272_CS_CSBR0	(0x0040)
+#define MCF5272_CS_CSOR0	(0x0044)
+#define MCF5272_CS_CSBR1	(0x0048)
+#define MCF5272_CS_CSOR1	(0x004C)
+#define MCF5272_CS_CSBR2	(0x0050)
+#define MCF5272_CS_CSOR2	(0x0054)
+#define MCF5272_CS_CSBR3	(0x0058)
+#define MCF5272_CS_CSOR3	(0x005C)
+#define MCF5272_CS_CSBR4	(0x0060)
+#define MCF5272_CS_CSOR4	(0x0064)
+#define MCF5272_CS_CSBR5	(0x0068)
+#define MCF5272_CS_CSOR5	(0x006C)
+#define MCF5272_CS_CSBR6	(0x0070)
+#define MCF5272_CS_CSOR6	(0x0074)
+#define MCF5272_CS_CSBR7	(0x0078)
+#define MCF5272_CS_CSOR7	(0x007C)
+
+/* Read access macros for general use */
+#define MCF5272_RD_CS_CSBR0(IMMP)	Mcf5272_iord(IMMP,MCF5272_CS_CSBR0,32)
+#define MCF5272_RD_CS_CSOR0(IMMP)	Mcf5272_iord(IMMP,MCF5272_CS_CSOR0,32)
+#define MCF5272_RD_CS_CSBR1(IMMP)	Mcf5272_iord(IMMP,MCF5272_CS_CSBR1,32)
+#define MCF5272_RD_CS_CSOR1(IMMP)	Mcf5272_iord(IMMP,MCF5272_CS_CSOR1,32)
+#define MCF5272_RD_CS_CSBR2(IMMP)	Mcf5272_iord(IMMP,MCF5272_CS_CSBR2,32)
+#define MCF5272_RD_CS_CSOR2(IMMP)	Mcf5272_iord(IMMP,MCF5272_CS_CSOR2,32)
+#define MCF5272_RD_CS_CSBR3(IMMP)	Mcf5272_iord(IMMP,MCF5272_CS_CSBR3,32)
+#define MCF5272_RD_CS_CSOR3(IMMP)	Mcf5272_iord(IMMP,MCF5272_CS_CSOR3,32)
+#define MCF5272_RD_CS_CSBR4(IMMP)	Mcf5272_iord(IMMP,MCF5272_CS_CSBR4,32)
+#define MCF5272_RD_CS_CSOR4(IMMP)	Mcf5272_iord(IMMP,MCF5272_CS_CSOR4,32)
+#define MCF5272_RD_CS_CSBR5(IMMP)	Mcf5272_iord(IMMP,MCF5272_CS_CSBR5,32)
+#define MCF5272_RD_CS_CSOR5(IMMP)	Mcf5272_iord(IMMP,MCF5272_CS_CSOR5,32)
+#define MCF5272_RD_CS_CSBR6(IMMP)	Mcf5272_iord(IMMP,MCF5272_CS_CSBR6,32)
+#define MCF5272_RD_CS_CSOR6(IMMP)	Mcf5272_iord(IMMP,MCF5272_CS_CSOR6,32)
+#define MCF5272_RD_CS_CSBR7(IMMP)	Mcf5272_iord(IMMP,MCF5272_CS_CSBR7,32)
+#define MCF5272_RD_CS_CSOR7(IMMP)	Mcf5272_iord(IMMP,MCF5272_CS_CSOR7,32)
+
+/* Write access macros for general use */
+#define MCF5272_WR_CS_CSBR0(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_CS_CSBR0,32,DATA)
+#define MCF5272_WR_CS_CSOR0(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_CS_CSOR0,32,DATA)
+#define MCF5272_WR_CS_CSBR1(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_CS_CSBR1,32,DATA)
+#define MCF5272_WR_CS_CSOR1(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_CS_CSOR1,32,DATA)
+#define MCF5272_WR_CS_CSBR2(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_CS_CSBR2,32,DATA)
+#define MCF5272_WR_CS_CSOR2(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_CS_CSOR2,32,DATA)
+#define MCF5272_WR_CS_CSBR3(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_CS_CSBR3,32,DATA)
+#define MCF5272_WR_CS_CSOR3(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_CS_CSOR3,32,DATA)
+#define MCF5272_WR_CS_CSBR4(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_CS_CSBR4,32,DATA)
+#define MCF5272_WR_CS_CSOR4(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_CS_CSOR4,32,DATA)
+#define MCF5272_WR_CS_CSBR5(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_CS_CSBR5,32,DATA)
+#define MCF5272_WR_CS_CSOR5(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_CS_CSOR5,32,DATA)
+#define MCF5272_WR_CS_CSBR6(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_CS_CSBR6,32,DATA)
+#define MCF5272_WR_CS_CSOR6(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_CS_CSOR6,32,DATA)
+#define MCF5272_WR_CS_CSBR7(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_CS_CSBR7,32,DATA)
+#define MCF5272_WR_CS_CSOR7(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_CS_CSOR7,32,DATA)
+
+/* Bit level definitions and macros */
+#define MCF5272_CS_BR_BASE(a)			((a)&0xFFFFF000)
+
+#define MCF5272_CS_OR_MASK_32M			(0xFE000000)
+#define MCF5272_CS_OR_MASK_16M			(0xFF000000)
+#define MCF5272_CS_OR_MASK_8M			(0xFF800000)
+#define MCF5272_CS_OR_MASK_4M			(0xFFC00000)
+#define MCF5272_CS_OR_MASK_2M			(0xFFE00000)
+#define MCF5272_CS_OR_MASK_1M			(0xFFF00000)
+#define MCF5272_CS_OR_MASK_512K			(0xFFF80000)
+#define MCF5272_CS_OR_MASK_256K			(0xFFFC0000)
+#define MCF5272_CS_OR_MASK_128K			(0xFFFE0000)
+#define MCF5272_CS_OR_MASK_64K			(0xFFFF0000)
+#define MCF5272_CS_OR_MASK_32K			(0xFFFF8000)
+#define MCF5272_CS_OR_MASK_16K			(0xFFFFC000)
+#define MCF5272_CS_OR_MASK_8K			(0xFFFFE000)
+#define MCF5272_CS_OR_MASK_4K			(0xFFFFF000)
+#define MCF5272_CS_OR_WS_MASK			(0x007C)
+#define MCF5272_CS_OR_WS(a)				(((a)&0x1F)<<2)
+#define MCF5272_CS_OR_BRST				(0x0100)
+#define MCF5272_CS_OR_RD				(0x0003)
+#define MCF5272_CS_OR_WR				(0x0001)
+
+#define MCF5272_CS_BR_PS_8				(0x0100)
+#define MCF5272_CS_BR_PS_16				(0x0200)
+#define MCF5272_CS_BR_PS_32				(0x0000)
+#define MCF5272_CS_BR_PS_LINE			(0x0300)
+#define MCF5272_CS_BR_ROM				(0x0000)
+#define MCF5272_CS_BR_SRAM				(0x0000)
+#define MCF5272_CS_BR_SRAM_8			(0x0C00)
+#define MCF5272_CS_BR_SDRAM				(0x0400)
+#define MCF5272_CS_BR_ISA				(0x0800)
+#define MCF5272_CS_BR_SV				(0x0080)
+#define MCF5272_CS_BR_EN				(0x0001)
+
+/**********************************************************************
+*
+* Ports Registers Description
+*
+***********************************************************************/
+
+/* Offsets of the registers from the MBAR */
+#define MCF5272_GPIO_PACNT		(0x0080)
+#define MCF5272_GPIO_PADDR		(0x0084)
+#define MCF5272_GPIO_PADAT		(0x0086)
+#define MCF5272_GPIO_PBCNT		(0x0088)
+#define MCF5272_GPIO_PBDDR		(0x008C)
+#define MCF5272_GPIO_PBDAT		(0x008E)
+#define MCF5272_GPIO_PCDDR		(0x0094)
+#define MCF5272_GPIO_PCDAT		(0x0096)
+#define MCF5272_GPIO_PDCNT		(0x0098)
+
+/* Read access macros for general use */
+#define MCF5272_RD_GPIO_PACNT(IMMP)	Mcf5272_iord(IMMP,MCF5272_GPIO_PACNT,32)
+#define MCF5272_RD_GPIO_PADDR(IMMP)	Mcf5272_iord(IMMP,MCF5272_GPIO_PADDR,16)
+#define MCF5272_RD_GPIO_PADAT(IMMP)	Mcf5272_iord(IMMP,MCF5272_GPIO_PADAT,16)
+#define MCF5272_RD_GPIO_PBCNT(IMMP)	Mcf5272_iord(IMMP,MCF5272_GPIO_PBCNT,32)
+#define MCF5272_RD_GPIO_PBDDR(IMMP)	Mcf5272_iord(IMMP,MCF5272_GPIO_PBDDR,16)
+#define MCF5272_RD_GPIO_PBDAT(IMMP)	Mcf5272_iord(IMMP,MCF5272_GPIO_PBDAT,16)
+#define MCF5272_RD_GPIO_PCDDR(IMMP)	Mcf5272_iord(IMMP,MCF5272_GPIO_PCDDR,16)
+#define MCF5272_RD_GPIO_PCDAT(IMMP)	Mcf5272_iord(IMMP,MCF5272_GPIO_PCDAT,16)
+#define MCF5272_RD_GPIO_PDCNT(IMMP)	Mcf5272_iord(IMMP,MCF5272_GPIO_PDCNT,32)
+
+/* Write access macros for general use */
+#define MCF5272_WR_GPIO_PACNT(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_GPIO_PACNT,32,DATA)
+#define MCF5272_WR_GPIO_PADDR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_GPIO_PADDR,16,DATA)
+#define MCF5272_WR_GPIO_PADAT(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_GPIO_PADAT,16,DATA)
+#define MCF5272_WR_GPIO_PBCNT(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_GPIO_PBCNT,32,DATA)
+#define MCF5272_WR_GPIO_PBDDR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_GPIO_PBDDR,16,DATA)
+#define MCF5272_WR_GPIO_PBDAT(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_GPIO_PBDAT,16,DATA)
+#define MCF5272_WR_GPIO_PCDDR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_GPIO_PCDDR,16,DATA)
+#define MCF5272_WR_GPIO_PCDAT(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_GPIO_PCDAT,16,DATA)
+#define MCF5272_WR_GPIO_PDCNT(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_GPIO_PDCNT,32,DATA)
+
+/* Bit level definitions and macros */
+#define MCF5272_GPIO_DDR15_INPUT	(~0x80)
+#define MCF5272_GPIO_DDR15_OUTPUT	( 0x80)
+#define MCF5272_GPIO_DDR14_INPUT	(~0x40)
+#define MCF5272_GPIO_DDR14_OUTPUT	( 0x40)
+#define MCF5272_GPIO_DDR13_INPUT	(~0x20)
+#define MCF5272_GPIO_DDR13_OUTPUT	( 0x20)
+#define MCF5272_GPIO_DDR12_INPUT	(~0x10)
+#define MCF5272_GPIO_DDR12_OUTPUT	( 0x10)
+#define MCF5272_GPIO_DDR11_INPUT	(~0x08)
+#define MCF5272_GPIO_DDR11_OUTPUT	( 0x08)
+#define MCF5272_GPIO_DDR10_INPUT	(~0x04)
+#define MCF5272_GPIO_DDR10_OUTPUT	( 0x04)
+#define MCF5272_GPIO_DDR9_INPUT		(~0x02)
+#define MCF5272_GPIO_DDR9_OUTPUT	( 0x02)
+#define MCF5272_GPIO_DDR8_INPUT		(~0x01)
+#define MCF5272_GPIO_DDR8_OUTPUT	( 0x01)
+#define MCF5272_GPIO_DDR7_INPUT		(~0x80)
+#define MCF5272_GPIO_DDR7_OUTPUT	( 0x80)
+#define MCF5272_GPIO_DDR6_INPUT		(~0x40)
+#define MCF5272_GPIO_DDR6_OUTPUT	( 0x40)
+#define MCF5272_GPIO_DDR5_INPUT		(~0x20)
+#define MCF5272_GPIO_DDR5_OUTPUT	( 0x20)
+#define MCF5272_GPIO_DDR4_INPUT		(~0x10)
+#define MCF5272_GPIO_DDR4_OUTPUT	( 0x10)
+#define MCF5272_GPIO_DDR3_INPUT		(~0x08)
+#define MCF5272_GPIO_DDR3_OUTPUT	( 0x08)
+#define MCF5272_GPIO_DDR2_INPUT		(~0x04)
+#define MCF5272_GPIO_DDR2_OUTPUT	( 0x04)
+#define MCF5272_GPIO_DDR1_INPUT		(~0x02)
+#define MCF5272_GPIO_DDR1_OUTPUT	( 0x02)
+#define MCF5272_GPIO_DDR0_INPUT		(~0x01)
+#define MCF5272_GPIO_DDR0_OUTPUT	( 0x01)
+
+#define MCF5272_GPIO_DAT15			( 0x80)
+#define MCF5272_GPIO_DAT14			( 0x40)
+#define MCF5272_GPIO_DAT13			( 0x20)
+#define MCF5272_GPIO_DAT12			( 0x10)
+#define MCF5272_GPIO_DAT11			( 0x08)
+#define MCF5272_GPIO_DAT10			( 0x04)
+#define MCF5272_GPIO_DAT9			( 0x02)
+#define MCF5272_GPIO_DAT8			( 0x01)
+#define MCF5272_GPIO_DAT7			( 0x80)
+#define MCF5272_GPIO_DAT6			( 0x40)
+#define MCF5272_GPIO_DAT5			( 0x20)
+#define MCF5272_GPIO_DAT4			( 0x10)
+#define MCF5272_GPIO_DAT3			( 0x08)
+#define MCF5272_GPIO_DAT2			( 0x04)
+#define MCF5272_GPIO_DAT1			( 0x02)
+#define MCF5272_GPIO_DAT0			( 0x01)
+
+
+/**********************************************************************
+*
+* QSPI Module Registers Description
+*
+***********************************************************************/
+
+/* Offsets of the registers from the MBAR */
+#define MCF5272_QSPI_QMR		(0x00A0)
+#define MCF5272_QSPI_QDLYR	(0x00A4)
+#define MCF5272_QSPI_QWR		(0x00A8)
+#define MCF5272_QSPI_QIR		(0x00AC)
+#define MCF5272_QSPI_QAR		(0x00B0)
+#define MCF5272_QSPI_QDR		(0x00B4)
+
+/* Read access macros for general use */
+#define MCF5272_RD_QSPI_QMR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_QSPI_QMR,16)
+#define MCF5272_RD_QSPI_QDLYR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_QSPI_QDLYR,16)
+#define MCF5272_RD_QSPI_QWR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_QSPI_QWR,16)
+#define MCF5272_RD_QSPI_QIR(IMMP)		\
+	Mcf5272_iord(IMMP,MCF5272_QSPI_QIR,16)
+#define MCF5272_RD_QSPI_QAR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_QSPI_QAR,16)
+#define MCF5272_RD_QSPI_QDR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_QSPI_QDR,16)
+
+/* Write access macros for general use */
+#define MCF5272_WR_QSPI_QMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_QSPI_QMR,16,DATA)
+#define MCF5272_WR_QSPI_QDLYR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_QSPI_QDLYR,16,DATA)
+#define MCF5272_WR_QSPI_QWR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_QSPI_QWR,16,DATA)
+#define MCF5272_WR_QSPI_QIR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_QSPI_QIR,16,DATA)
+#define MCF5272_WR_QSPI_QAR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_QSPI_QAR,16,DATA)
+#define MCF5272_WR_QSPI_QDR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_QSPI_QDR,16,DATA)
+
+
+/**********************************************************************
+*
+* PWM Module Registers Description
+*
+***********************************************************************/
+
+/* Offsets of the registers from the MBAR */
+#define MCF5272_PWM_PWMCR1		(0x00C0)
+#define MCF5272_PWM_PWMCR2		(0x00C4)
+#define MCF5272_PWM_PWMCR3		(0x00C8)
+#define MCF5272_PWM_PWMWD1		(0x00D0)
+#define MCF5272_PWM_PWMWD2		(0x00D4)
+#define MCF5272_PWM_PWMWD3		(0x00D8)
+
+/* Read access macros for general use */
+#define MCF5272_RD_PWM_PWMCR1(IMMP)	Mcf5272_iord(IMMP,MCF5272_PWM_PWMCR1,8)
+#define MCF5272_RD_PWM_PWMCR2(IMMP)	Mcf5272_iord(IMMP,MCF5272_PWM_PWMCR2,8)
+#define MCF5272_RD_PWM_PWMCR3(IMMP)	Mcf5272_iord(IMMP,MCF5272_PWM_PWMCR3,8)
+#define MCF5272_RD_PWM_PWMWD1(IMMP)	Mcf5272_iord(IMMP,MCF5272_PWM_PWMWD1,8)
+#define MCF5272_RD_PWM_PWMWD2(IMMP)	Mcf5272_iord(IMMP,MCF5272_PWM_PWMWD2,8)
+#define MCF5272_RD_PWM_PWMWD3(IMMP)	Mcf5272_iord(IMMP,MCF5272_PWM_PWMWD3,8)
+
+/* Write access macros for general use */
+#define MCF5272_WR_PWM_PWMCR1(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PWM_PWMCR1,8,DATA)
+#define MCF5272_WR_PWM_PWMCR2(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PWM_PWMCR2,8,DATA)
+#define MCF5272_WR_PWM_PWMCR3(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PWM_PWMCR3,8,DATA)
+#define MCF5272_WR_PWM_PWMWD1(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PWM_PWMWD1,8,DATA)
+#define MCF5272_WR_PWM_PWMWD2(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PWM_PWMWD2,8,DATA)
+#define MCF5272_WR_PWM_PWMWD3(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PWM_PWMWD3,8,DATA)
+
+/**********************************************************************
+*
+* DMA Module Registers Description
+*
+***********************************************************************/
+
+/* Offsets of the registers from the MBAR */
+#define MCF5272_DMA_DCMR		(0x00E0)
+#define MCF5272_DMA_DCIR		(0x00E6)
+#define MCF5272_DMA_DBCR		(0x00E8)
+#define MCF5272_DMA_DSAR		(0x00EC)
+#define MCF5272_DMA_DDAR		(0x00F0)
+
+/* Read access macros for general use */
+#define MCF5272_RD_DMA_DCMR(IMMP)	Mcf5272_iord(IMMP,MCF5272_DMA_DCMR,32)
+#define MCF5272_RD_DMA_DCIR(IMMP)	Mcf5272_iord(IMMP,MCF5272_DMA_DCIR,16)
+#define MCF5272_RD_DMA_DBCR(IMMP)	Mcf5272_iord(IMMP,MCF5272_DMA_DBCR,32)
+#define MCF5272_RD_DMA_DSAR(IMMP)	Mcf5272_iord(IMMP,MCF5272_DMA_DSAR,32)
+#define MCF5272_RD_DMA_DDAR(IMMP)	Mcf5272_iord(IMMP,MCF5272_DMA_DDAR,32)
+
+/* Write access macros for general use */
+#define MCF5272_WR_DMA_DCMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_DMA_DCMR,32,DATA)
+#define MCF5272_WR_DMA_DCIR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_DMA_DCIR,16,DATA)
+#define MCF5272_WR_DMA_DBCR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_DMA_DBCR,32,DATA)
+#define MCF5272_WR_DMA_DSAR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_DMA_DSAR,32,DATA)
+#define MCF5272_WR_DMA_DDAR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_DMA_DDAR,32,DATA)
+
+/**********************************************************************
+*
+* USART Module Registers Description
+*
+***********************************************************************/
+
+/* Offsets of the registers from the MBAR */
+#define MCF5272_UART0_UMR		(0x0100)	/* RW */
+#define MCF5272_UART0_USR		(0x0104)	/* USR RO, UCSR WO */
+#define MCF5272_UART0_UCR		(0x0108)	/* WO */
+#define MCF5272_UART0_UBUF		(0x010C)	/* URB RO, UTB WO */
+#define MCF5272_UART0_UCCR		(0x0110)	/* UCCR RO, UACR WO */
+#define MCF5272_UART0_UISR		(0x0114)	/* UISR RO, UIMR WO */
+#define MCF5272_UART0_UBG1		(0x0118)	/* WO */
+#define MCF5272_UART0_UBG2		(0x011C)	/* WO */
+#define MCF5272_UART0_UABR1		(0x0120)	/* RO */
+#define MCF5272_UART0_UABR2		(0x0124)	/* RO */
+#define MCF5272_UART0_UTFCSR	(0x0128)	/* RW */
+#define MCF5272_UART0_URFCSR	(0x012C)	/* RW */
+#define MCF5272_UART0_UIP		(0x0134)	/* RO */
+#define MCF5272_UART0_UOP1		(0x0138)	/* WO */
+#define MCF5272_UART0_UOP0		(0x013C)	/* WO */
+
+#define MCF5272_UART1_UMR		(0x0140)	/* RW */
+#define MCF5272_UART1_USR		(0x0144)	/* USR RO, UCSR WO */
+#define MCF5272_UART1_UCR		(0x0148)	/* WO */
+#define MCF5272_UART1_UBUF		(0x014C)	/* URB RO, UTB WO */
+#define MCF5272_UART1_UCCR		(0x0150)	/* UCCR RO, UACR WO */
+#define MCF5272_UART1_UISR		(0x0154)	/* UISR RO, UIMR WO */
+#define MCF5272_UART1_UBG1		(0x0158)	/* WO */
+#define MCF5272_UART1_UBG2		(0x015C)	/* WO */
+#define MCF5272_UART1_UABR1		(0x0160)	/* RO */
+#define MCF5272_UART1_UABR2		(0x0164)	/* RO */
+#define MCF5272_UART1_UTFCSR	(0x0168)	/* RW */
+#define MCF5272_UART1_URFCSR	(0x016C)	/* RW */
+#define MCF5272_UART1_UIP		(0x0174)	/* RO */
+#define MCF5272_UART1_UOP1		(0x0178)	/* WO */
+#define MCF5272_UART1_UOP0		(0x017C)	/* WO */
+
+/* Read access macros for general use */
+#define MCF5272_RD_UART0_UMR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART0_UMR,8)
+#define MCF5272_RD_UART0_USR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART0_USR,8)
+#define MCF5272_RD_UART0_URB(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART0_UBUF,8)
+#define MCF5272_RD_UART0_UCCR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART0_UCCR,8)
+#define MCF5272_RD_UART0_UISR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART0_UISR,8)
+#define MCF5272_RD_UART0_UABR1(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART0_UABR1,8)
+#define MCF5272_RD_UART0_UABR2(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART1_UABR2,8)
+#define MCF5272_RD_UART0_UTFCSR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART0_UTFCSR,8)
+#define MCF5272_RD_UART0_URFCSR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART0_URFCSR,8)
+#define MCF5272_RD_UART0_UIP(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART0_UIP,8)
+
+#define MCF5272_RD_UART1_UMR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART1_UMR,8)
+#define MCF5272_RD_UART1_USR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART1_USR,8)
+#define MCF5272_RD_UART1_URB(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART1_UBUF,8)
+#define MCF5272_RD_UART1_UCCR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART1_UCCR,8)
+#define MCF5272_RD_UART1_UISR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART1_UISR,8)
+#define MCF5272_RD_UART1_UABR1(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART1_UABR1,8)
+#define MCF5272_RD_UART1_UABR2(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART1_UABR2,8)
+#define MCF5272_RD_UART1_UTFCSR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART1_UTFCSR,8)
+#define MCF5272_RD_UART1_URFCSR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART1_URFCSR,8)
+#define MCF5272_RD_UART1_UIP(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_UART1_UIP,8)
+
+/* Write access macros for general use */
+#define MCF5272_WR_UART0_UMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART0_UMR,8,DATA)
+#define MCF5272_WR_UART0_UCSR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART0_USR,8,DATA)
+#define MCF5272_WR_UART0_UCR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART0_UCR,8,DATA)
+#define MCF5272_WR_UART0_UTB(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART0_UBUF,8,DATA)
+#define MCF5272_WR_UART0_UACR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART0_UCCR,8,DATA)
+#define MCF5272_WR_UART0_UIMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART0_UISR,8,DATA)
+#define MCF5272_WR_UART0_UBG1(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART0_UBG1,8,DATA)
+#define MCF5272_WR_UART0_UBG2(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART0_UBG2,8,DATA)
+#define MCF5272_WR_UART0_UTFCSR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART0_UTFCSR,8,DATA)
+#define MCF5272_WR_UART0_URFCSR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART0_URFCSR,8,DATA)
+#define MCF5272_WR_UART0_UOP1(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART0_UOP1,8,DATA)
+#define MCF5272_WR_UART0_UOP0(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART0_UOP0,8,DATA)
+
+#define MCF5272_WR_UART1_UMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART1_UMR,8,DATA)
+#define MCF5272_WR_UART1_UCSR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART1_USR,8,DATA)
+#define MCF5272_WR_UART1_UCR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART1_UCR,8,DATA)
+#define MCF5272_WR_UART1_UTB(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART1_UBUF,8,DATA)
+#define MCF5272_WR_UART1_UACR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART1_UCCR,8,DATA)
+#define MCF5272_WR_UART1_UIMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART1_UISR,8,DATA)
+#define MCF5272_WR_UART1_UBG1(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART1_UBG1,8,DATA)
+#define MCF5272_WR_UART1_UBG2(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART1_UBG2,8,DATA)
+#define MCF5272_WR_UART1_UTFCSR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART1_UTFCSR,8,DATA)
+#define MCF5272_WR_UART1_URFCSR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART1_URFCSR,8,DATA)
+#define MCF5272_WR_UART1_UOP1(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART1_UOP1,8,DATA)
+#define MCF5272_WR_UART1_UOP0(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_UART1_UOP0,8,DATA)
+
+/* Bit level definitions and macros */
+#define MCF5272_UART_UMR1_RXRTS			(0x80)
+#define MCF5272_UART_UMR1_RXIRQ			(0x40)
+#define MCF5272_UART_UMR1_ERR			(0x20)
+#define MCF5272_UART_UMR1_PM_MULTI_ADDR	(0x1C)
+#define MCF5272_UART_UMR1_PM_MULTI_DATA	(0x18)
+#define MCF5272_UART_UMR1_PM_NONE		(0x10)
+#define MCF5272_UART_UMR1_PM_FORCE_HI	(0x0C)
+#define MCF5272_UART_UMR1_PM_FORCE_LO	(0x08)
+#define MCF5272_UART_UMR1_PM_ODD		(0x04)
+#define MCF5272_UART_UMR1_PM_EVEN		(0x00)
+#define MCF5272_UART_UMR1_BC_5			(0x00)
+#define MCF5272_UART_UMR1_BC_6			(0x01)
+#define MCF5272_UART_UMR1_BC_7			(0x02)
+#define MCF5272_UART_UMR1_BC_8			(0x03)
+
+#define MCF5272_UART_UMR2_CM_NORMAL	  	(0x00)
+#define MCF5272_UART_UMR2_CM_ECHO	  	(0x40)
+#define MCF5272_UART_UMR2_CM_LOCAL_LOOP	(0x80)
+#define MCF5272_UART_UMR2_CM_REMOTE_LOOP	(0xC0)
+#define MCF5272_UART_UMR2_TXRTS		 	(0x20)
+#define MCF5272_UART_UMR2_TXCTS		 	(0x10)
+#define MCF5272_UART_UMR2_STOP_BITS_1 	(0x07)
+#define MCF5272_UART_UMR2_STOP_BITS_15	(0x08)
+#define MCF5272_UART_UMR2_STOP_BITS_2 	(0x0F)
+#define MCF5272_UART_UMR2_STOP_BITS(a)   ((a)&0x0f)	/* Stop Bit Length */
+
+#define MCF5272_UART_USR_RB				(0x80)
+#define MCF5272_UART_USR_FE				(0x40)
+#define MCF5272_UART_USR_PE				(0x20)
+#define MCF5272_UART_USR_OE				(0x10)
+#define MCF5272_UART_USR_TXEMP			(0x08)
+#define MCF5272_UART_USR_TXRDY			(0x04)
+#define MCF5272_UART_USR_FFULL			(0x02)
+#define MCF5272_UART_USR_RXRDY			(0x01)
+
+#define MCF5272_UART_UCSR_RCS(a)	(((a)&0x0f)<<4)	/* Rx Clk Select */
+#define MCF5272_UART_UCSR_TCS(a)		((a)&0x0f)	/* Tx Clk Select */
+
+
+#define MCF5272_UART_UCR_NONE			(0x00)
+#define MCF5272_UART_UCR_STOP_BREAK		(0x70)
+#define MCF5272_UART_UCR_START_BREAK	(0x60)
+#define MCF5272_UART_UCR_RESET_BKCHGINT	(0x50)
+#define MCF5272_UART_UCR_RESET_ERROR	(0x40)
+#define MCF5272_UART_UCR_RESET_TX		(0x30)
+#define MCF5272_UART_UCR_RESET_RX		(0x20)
+#define MCF5272_UART_UCR_RESET_MR		(0x10)
+#define MCF5272_UART_UCR_TX_DISABLED	(0x08)
+#define MCF5272_UART_UCR_TX_ENABLED		(0x04)
+#define MCF5272_UART_UCR_RX_DISABLED	(0x02)
+#define MCF5272_UART_UCR_RX_ENABLED		(0x01)
+
+#define MCF5272_UART_UCCR_COS			(0x10)
+#define MCF5272_UART_UCCR_CTS			(0x01)
+
+#define MCF5272_UART_UACR_BRG			(0x80)
+#define MCF5272_UART_UACR_CTMS_TIMER	(0x60)
+#define MCF5272_UART_UACR_IEC			(0x01)
+
+#define MCF5272_UART_UISR_COS			(0x80)
+#define MCF5272_UART_UISR_DB			(0x04)
+#define MCF5272_UART_UISR_RXRDY			(0x02)
+#define MCF5272_UART_UISR_TXRDY			(0x01)
+
+#define MCF5272_UART_UIMR_COS			(0x80)
+#define MCF5272_UART_UIMR_DB			(0x04)
+#define MCF5272_UART_UIMR_FFULL			(0x02)
+#define MCF5272_UART_UIMR_TXRDY			(0x01)
+
+
+/**********************************************************************
+*
+* SDRAM Controller Module Registers Description
+*
+***********************************************************************/
+
+/* Offsets of the registers from the MBAR */
+#define MCF5272_SDRAMC_SDCCR		(0x0180)
+#define MCF5272_SDRAMC_SDCTR		(0x0184)
+
+/* Read access macros for general use */
+#define MCF5272_RD_SDRAMC_SDCCR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_SDRAMC_SDCCR,32)
+#define MCF5272_RD_SDRAMC_SDCTR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_SDRAMC_SDCTR,32)
+
+/* Write access macros for general use */
+#define MCF5272_WR_SDRAMC_SDCCR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_SDRAMC_SDCCR,32,DATA)
+#define MCF5272_WR_SDRAMC_SDCTR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_SDRAMC_SDCTR,32,DATA)
+
+/* Bit level definitions and macros */
+#define MCF5272_SDRAMC_SDCCR_MCAS_A7	(0x0 << 13)
+#define MCF5272_SDRAMC_SDCCR_MCAS_A8	(0x1 << 13)
+#define MCF5272_SDRAMC_SDCCR_MCAS_A9	(0x2 << 13)
+#define MCF5272_SDRAMC_SDCCR_MCAS_A10	(0x3 << 13)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A19	(0x0 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A20	(0x1 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A21	(0x2 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A22	(0x3 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A23	(0x4 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A24	(0x5 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A25	(0x6 << 8)
+#define MCF5272_SDRAMC_SDCCR_BALOC_A26	(0x7 << 8)
+#define MCF5272_SDRAMC_SDCCR_GSL		(0x00000080)
+#define MCF5272_SDRAMC_SDCCR_REG		(0x00000010)
+#define MCF5272_SDRAMC_SDCCR_INV		(0x00000008)
+#define MCF5272_SDRAMC_SDCCR_SLEEP		(0x00000004)
+#define MCF5272_SDRAMC_SDCCR_ACT		(0x00000002)
+#define MCF5272_SDRAMC_SDCCR_INIT		(0x00000001)
+
+#define MCF5272_SDRAMC_SDCTR_RTP_66MHz	(0x3D << 10)
+#define MCF5272_SDRAMC_SDCTR_RTP_48MHz	(0x2B << 10)
+#define MCF5272_SDRAMC_SDCTR_RTP_33MHz	(0x1D << 10)
+#define MCF5272_SDRAMC_SDCTR_RTP_25MHz	(0x16 << 10)
+#define MCF5272_SDRAMC_SDCTR_RC(x)		((x & 0x3) << 8)
+#define MCF5272_SDRAMC_SDCTR_RP(x)		((x & 0x3) << 4)
+#define MCF5272_SDRAMC_SDCTR_RCD(x)		((x & 0x3) << 2)
+#define MCF5272_SDRAMC_SDCTR_CLT_2		(0x00000001)
+#define MCF5272_SDRAMC_SDCTR_CLT_3		(0x00000002)
+#define MCF5272_SDRAMC_SDCTR_CLT_4		(0x00000003)
+
+/**********************************************************************
+*
+* Timer Module Registers Description
+*
+***********************************************************************/
+
+/* Offsets of the registers from the MBAR */
+#define MCF5272_TIMER0_TMR		(0x0200)
+#define MCF5272_TIMER0_TRR		(0x0204)
+#define MCF5272_TIMER0_TCR		(0x0208)
+#define MCF5272_TIMER0_TCN		(0x020C)
+#define MCF5272_TIMER0_TER		(0x0210)
+#define MCF5272_TIMER1_TMR		(0x0220)
+#define MCF5272_TIMER1_TRR		(0x0224)
+#define MCF5272_TIMER1_TCR		(0x0228)
+#define MCF5272_TIMER1_TCN		(0x022C)
+#define MCF5272_TIMER1_TER		(0x0230)
+#define MCF5272_TIMER2_TMR		(0x0240)
+#define MCF5272_TIMER2_TRR		(0x0244)
+#define MCF5272_TIMER2_TCR		(0x0248)
+#define MCF5272_TIMER2_TCN		(0x024C)
+#define MCF5272_TIMER2_TER		(0x0250)
+#define MCF5272_TIMER3_TMR		(0x0260)
+#define MCF5272_TIMER3_TRR		(0x0264)
+#define MCF5272_TIMER3_TCR		(0x0268)
+#define MCF5272_TIMER3_TCN		(0x026C)
+#define MCF5272_TIMER3_TER		(0x0270)
+#define MCF5272_TIMER_WRRR		(0x0280)
+#define MCF5272_TIMER_WIRR		(0x0284)
+#define MCF5272_TIMER_WCR		(0x0288)
+#define MCF5272_TIMER_WER		(0x028C)
+
+/* Read access macros for general use */
+#define MCF5272_RD_TIMER0_TMR(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER0_TMR,16)
+#define MCF5272_RD_TIMER0_TRR(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER0_TRR,16)
+#define MCF5272_RD_TIMER0_TCR(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER0_TCR,16)
+#define MCF5272_RD_TIMER0_TCN(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER0_TCN,16)
+#define MCF5272_RD_TIMER0_TER(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER0_TER,16)
+
+#define MCF5272_RD_TIMER1_TMR(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER1_TMR,16)
+#define MCF5272_RD_TIMER1_TRR(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER1_TRR,16)
+#define MCF5272_RD_TIMER1_TCR(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER1_TCR,16)
+#define MCF5272_RD_TIMER1_TCN(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER1_TCN,16)
+#define MCF5272_RD_TIMER1_TER(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER1_TER,16)
+
+#define MCF5272_RD_TIMER2_TMR(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER2_TMR,16)
+#define MCF5272_RD_TIMER2_TRR(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER2_TRR,16)
+#define MCF5272_RD_TIMER2_TCR(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER2_TCR,16)
+#define MCF5272_RD_TIMER2_TCN(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER2_TCN,16)
+#define MCF5272_RD_TIMER2_TER(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER2_TER,16)
+
+#define MCF5272_RD_TIMER3_TMR(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER3_TMR,16)
+#define MCF5272_RD_TIMER3_TRR(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER3_TRR,16)
+#define MCF5272_RD_TIMER3_TCR(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER3_TCR,16)
+#define MCF5272_RD_TIMER3_TCN(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER3_TCN,16)
+#define MCF5272_RD_TIMER3_TER(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER3_TER,16)
+
+#define MCF5272_RD_TIMER_TMR(IMMP,NUM)	\
+Mcf5272_iord(IMMP,MCF5272_TIMER0_TMR + (NUM * 0x20),16)
+#define MCF5272_RD_TIMER_TRR(IMMP,NUM)	\
+Mcf5272_iord(IMMP,MCF5272_TIMER0_TRR + (NUM * 0x20),16)
+#define MCF5272_RD_TIMER_TCR(IMMP,NUM)	\
+Mcf5272_iord(IMMP,MCF5272_TIMER0_TCR + (NUM * 0x20),16)
+#define MCF5272_RD_TIMER_TCN(IMMP,NUM)	\
+Mcf5272_iord(IMMP,MCF5272_TIMER0_TCN + (NUM * 0x20),16)
+#define MCF5272_RD_TIMER_TER(IMMP,NUM)	\
+Mcf5272_iord(IMMP,MCF5272_TIMER0_TER + (NUM * 0x20),8)
+
+#define MCF5272_RD_TIMER_WRRR(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER_WRRR,16)
+#define MCF5272_RD_TIMER_WIRR(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER_WIRR,16)
+#define MCF5272_RD_TIMER_WCR(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER_WCR,16)
+#define MCF5272_RD_TIMER_WER(IMMP)	Mcf5272_iord(IMMP,MCF5272_TIMER_WER,16)
+
+/* Write access macros for general use */
+#define MCF5272_WR_TIMER0_TMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER0_TMR,16,DATA)
+#define MCF5272_WR_TIMER0_TRR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER0_TRR,16,DATA)
+#define MCF5272_WR_TIMER0_TCN(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER0_TCN,16,DATA)
+#define MCF5272_WR_TIMER0_TER(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER0_TER,16,DATA)
+#define MCF5272_WR_TIMER1_TMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER1_TMR,16,DATA)
+#define MCF5272_WR_TIMER1_TRR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER1_TRR,16,DATA)
+#define MCF5272_WR_TIMER1_TCN(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER1_TCN,16,DATA)
+#define MCF5272_WR_TIMER1_TER(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER1_TER,16,DATA)
+#define MCF5272_WR_TIMER2_TMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER2_TMR,16,DATA)
+#define MCF5272_WR_TIMER2_TRR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER2_TRR,16,DATA)
+#define MCF5272_WR_TIMER2_TCN(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER2_TCN,16,DATA)
+#define MCF5272_WR_TIMER2_TER(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER2_TER,16,DATA)
+#define MCF5272_WR_TIMER3_TMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER3_TMR,16,DATA)
+#define MCF5272_WR_TIMER3_TRR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER3_TRR,16,DATA)
+#define MCF5272_WR_TIMER3_TCN(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER3_TCN,16,DATA)
+#define MCF5272_WR_TIMER3_TER(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER3_TER,16,DATA)
+#define MCF5272_WR_TIMER_WRRR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER_WRRR,16,DATA)
+#define MCF5272_WR_TIMER_WIRR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER_WIRR,16,DATA)
+#define MCF5272_WR_TIMER_WCR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER_WCR,16,DATA)
+#define MCF5272_WR_TIMER_WER(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER_WER,16,DATA)
+
+#define MCF5272_WR_TIMER_TMR(IMMP,NUM,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER0_TMR + (NUM * 0x20),16,DATA)
+#define MCF5272_WR_TIMER_TRR(IMMP,NUM,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER0_TRR + (NUM * 0x20),16,DATA)
+#define MCF5272_WR_TIMER_TCN(IMMP,NUM,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER0_TCN + (NUM * 0x20),16,DATA)
+#define MCF5272_WR_TIMER_TER(IMMP,NUM,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_TIMER0_TER + (NUM * 0x20),8,DATA)
+
+/* Bit level definitions and macros */
+#define MCF5272_TIMER_TMR_PS(a)		(((a)&0x00FF)<<8)
+#define MCF5272_TIMER_TMR_CE_ANY	(0x00C0)
+#define MCF5272_TIMER_TMR_CE_RISE	(0x0080)
+#define MCF5272_TIMER_TMR_CE_FALL	(0x0040)
+#define MCF5272_TIMER_TMR_CE_NONE	(0x0000)
+#define MCF5272_TIMER_TMR_OM		(0x0020)
+#define MCF5272_TIMER_TMR_ORI		(0x0010)
+#define MCF5272_TIMER_TMR_FRR		(0x0008)
+#define MCF5272_TIMER_TMR_CLK_TIN	(0x0006)
+#define MCF5272_TIMER_TMR_CLK_DIV16	(0x0004)
+#define MCF5272_TIMER_TMR_CLK_MSCLK	(0x0002)
+#define MCF5272_TIMER_TMR_CLK_STOP	(0x0000)
+#define MCF5272_TIMER_TMR_RST		(0x0001)
+
+#define MCF5272_TIMER_TER_REF		(0x02)
+#define MCF5272_TIMER_TER_CAP		(0x01)
+
+/**********************************************************************
+*
+* PLI Module Registers Description
+*
+***********************************************************************/
+
+/* Offsets of the registers from the MBAR */
+#define MCF5272_PLI_P0B1RR			(0x0300)
+#define MCF5272_PLI_P1B1RR			(0x0304)
+#define MCF5272_PLI_P2B1RR			(0x0308)
+#define MCF5272_PLI_P3B1RR			(0x030C)
+#define MCF5272_PLI_P0B2RR			(0x0310)
+#define MCF5272_PLI_P1B2RR			(0x0314)
+#define MCF5272_PLI_P2B2RR			(0x0318)
+#define MCF5272_PLI_P3B2RR			(0x031C)
+#define MCF5272_PLI_P0DRR			(0x0320)
+#define MCF5272_PLI_P1DRR			(0x0321)
+#define MCF5272_PLI_P2DRR			(0x0322)
+#define MCF5272_PLI_P3DRR			(0x0323)
+#define MCF5272_PLI_P0B1TR			(0x0328)
+#define MCF5272_PLI_P1B1TR			(0x032C)
+#define MCF5272_PLI_P2B1TR			(0x0330)
+#define MCF5272_PLI_P3B1TR			(0x0334)
+#define MCF5272_PLI_P0B2TR			(0x0338)
+#define MCF5272_PLI_P1B2TR			(0x033C)
+#define MCF5272_PLI_P2B2TR			(0x0340)
+#define MCF5272_PLI_P3B2TR			(0x0344)
+#define MCF5272_PLI_P0DTR			(0x0348)
+#define MCF5272_PLI_P1DTR			(0x0349)
+#define MCF5272_PLI_P2DTR			(0x034A)
+#define MCF5272_PLI_P3DTR			(0x034B)
+#define MCF5272_PLI_P0CR			(0x0350)
+#define MCF5272_PLI_P1CR			(0x0352)
+#define MCF5272_PLI_P2CR			(0x0354)
+#define MCF5272_PLI_P3CR			(0x0356)
+#define MCF5272_PLI_P0ICR			(0x0358)
+#define MCF5272_PLI_P1ICR			(0x035A)
+#define MCF5272_PLI_P2ICR			(0x035C)
+#define MCF5272_PLI_P3ICR			(0x035E)
+#define MCF5272_PLI_P0GMR			(0x0360)
+#define MCF5272_PLI_P1GMR			(0x0362)
+#define MCF5272_PLI_P2GMR			(0x0364)
+#define MCF5272_PLI_P3GMR			(0x0366)
+#define MCF5272_PLI_P0GMT			(0x0368)
+#define MCF5272_PLI_P1GMT			(0x036A)
+#define MCF5272_PLI_P2GMT			(0x036C)
+#define MCF5272_PLI_P3GMT			(0x036E)
+#define MCF5272_PLI_PGMTS			(0x0371)
+#define MCF5272_PLI_PGMTA			(0x0372)
+#define MCF5272_PLI_P0GCIR			(0x0374)
+#define MCF5272_PLI_P1GCIR			(0x0375)
+#define MCF5272_PLI_P2GCIR			(0x0376)
+#define MCF5272_PLI_P3GCIR			(0x0377)
+#define MCF5272_PLI_P0GCIT			(0x0378)
+#define MCF5272_PLI_P1GCIT			(0x0379)
+#define MCF5272_PLI_P2GCIT			(0x037A)
+#define MCF5272_PLI_P3GCIT			(0x037E)
+#define MCF5272_PLI_PGCITSR			(0x037F)
+#define MCF5272_PLI_PDSUSR			(0x0382)
+#define MCF5272_PLI_PDCSR			(0x0383)
+#define MCF5272_PLI_P0PSR			(0x0384)
+#define MCF5272_PLI_P1PSR			(0x0386)
+#define MCF5272_PLI_P2PSR			(0x0388)
+#define MCF5272_PLI_P3PSR			(0x038A)
+#define MCF5272_PLI_PASR			(0x038C)
+#define MCF5272_PLI_PLCR			(0x038F)
+#define MCF5272_PLI_PDRQR			(0x0392)
+#define MCF5272_PLI_P0SDR			(0x0394)
+#define MCF5272_PLI_P1SDR			(0x0396)
+#define MCF5272_PLI_P2SDR			(0x0398)
+#define MCF5272_PLI_P3SDR			(0x039A)
+#define MCF5272_PLI_PCKSELR			(0x039E)
+
+/* Read access macros for general use */
+#define MCF5272_RD_PLI_P0B1RR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P0B1RR,32)
+#define MCF5272_RD_PLI_P1B1RR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P1B1RR,32)
+#define MCF5272_RD_PLI_P2B1RR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P2B1RR,32)
+#define MCF5272_RD_PLI_P3B1RR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P3B1RR,32)
+#define MCF5272_RD_PLI_P0B2RR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P0B2RR,32)
+#define MCF5272_RD_PLI_P1B2RR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P1B2RR,32)
+#define MCF5272_RD_PLI_P2B2RR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P2B2RR,32)
+#define MCF5272_RD_PLI_P3B2RR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P3B2RR,32)
+#define MCF5272_RD_PLI_P0DRR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P0DRR,8)
+#define MCF5272_RD_PLI_P1DRR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P1DRR,8)
+#define MCF5272_RD_PLI_P2DRR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P2DRR,8)
+#define MCF5272_RD_PLI_P3DRR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P3DRR,8)
+#define MCF5272_RD_PLI_P0B1TR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P0B1TR,32)
+#define MCF5272_RD_PLI_P1B1TR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P1B1TR,32)
+#define MCF5272_RD_PLI_P2B1TR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P2B1TR,32)
+#define MCF5272_RD_PLI_P3B1TR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P3B1TR,32)
+#define MCF5272_RD_PLI_P0B2TR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P0B2TR,32)
+#define MCF5272_RD_PLI_P1B2TR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P1B2TR,32)
+#define MCF5272_RD_PLI_P2B2TR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P2B2TR,32)
+#define MCF5272_RD_PLI_P3B2TR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P3B2TR,32)
+#define MCF5272_RD_PLI_P0DTR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P0DTR,8)
+#define MCF5272_RD_PLI_P1DTR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P1DTR,8)
+#define MCF5272_RD_PLI_P2DTR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P2DTR,8)
+#define MCF5272_RD_PLI_P3DTR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P3DTR,8)
+#define MCF5272_RD_PLI_P0CR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P0CR,16)
+#define MCF5272_RD_PLI_P1CR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P1CR,16)
+#define MCF5272_RD_PLI_P2CR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P2CR,16)
+#define MCF5272_RD_PLI_P3CR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P3CR,16)
+#define MCF5272_RD_PLI_P0ICR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P0ICR,16)
+#define MCF5272_RD_PLI_P1ICR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P1ICR,16)
+#define MCF5272_RD_PLI_P2ICR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P2ICR,16)
+#define MCF5272_RD_PLI_P3ICR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P3ICR,16)
+#define MCF5272_RD_PLI_P0GMR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P0GMR,16)
+#define MCF5272_RD_PLI_P1GMR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P1GMR,16)
+#define MCF5272_RD_PLI_P2GMR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P2GMR,16)
+#define MCF5272_RD_PLI_P3GMR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P3GMR,16)
+#define MCF5272_RD_PLI_P0GMT(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P0GMT,16)
+#define MCF5272_RD_PLI_P1GMT(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P1GMT,16)
+#define MCF5272_RD_PLI_P2GMT(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P2GMT,16)
+#define MCF5272_RD_PLI_P3GMT(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P3GMT,16)
+#define MCF5272_RD_PLI_PGMTS(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_PGMTS,8)
+#define MCF5272_RD_PLI_PGMTA(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_PGMTA,8)
+#define MCF5272_RD_PLI_P0GCIR(IMMP) Mcf5272_iord(IMMP,MCF5272_PLI_P0GCIR,8)
+#define MCF5272_RD_PLI_P1GCIR(IMMP) Mcf5272_iord(IMMP,MCF5272_PLI_P1GCIR,8)
+#define MCF5272_RD_PLI_P2GCIR(IMMP) Mcf5272_iord(IMMP,MCF5272_PLI_P2GCIR,8)
+#define MCF5272_RD_PLI_P3GCIR(IMMP) Mcf5272_iord(IMMP,MCF5272_PLI_P3GCIR,8)
+#define MCF5272_RD_PLI_P0GCIT(IMMP) Mcf5272_iord(IMMP,MCF5272_PLI_P0GCIT,8)
+#define MCF5272_RD_PLI_P1GCIT(IMMP) Mcf5272_iord(IMMP,MCF5272_PLI_P1GCIT,8)
+#define MCF5272_RD_PLI_P2GCIT(IMMP) Mcf5272_iord(IMMP,MCF5272_PLI_P2GCIT,8)
+#define MCF5272_RD_PLI_P3GCIT(IMMP) Mcf5272_iord(IMMP,MCF5272_PLI_P3GCIT,8)
+#define MCF5272_RD_PLI_PGCITSR(IMMP) Mcf5272_iord(IMMP,MCF5272_PLI_PGCITSR,8)
+#define MCF5272_RD_PLI_PDSUSR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_PDSUSR,8)
+#define MCF5272_RD_PLI_PDCSR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_PDCSR,8)
+#define MCF5272_RD_PLI_P0PSR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P0PSR,16)
+#define MCF5272_RD_PLI_P1PSR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P1PSR,16)
+#define MCF5272_RD_PLI_P2PSR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P2PSR,16)
+#define MCF5272_RD_PLI_P3PSR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P3PSR,16)
+#define MCF5272_RD_PLI_PASR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_PASR,16)
+#define MCF5272_RD_PLI_PLCR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_PLCR,8)
+#define MCF5272_RD_PLI_PDRQR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_PDRQR,16)
+#define MCF5272_RD_PLI_P0SDR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P0SDR,16)
+#define MCF5272_RD_PLI_P1SDR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P1SDR,16)
+#define MCF5272_RD_PLI_P2SDR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P2SDR,16)
+#define MCF5272_RD_PLI_P3SDR(IMMP)	Mcf5272_iord(IMMP,MCF5272_PLI_P3SDR,16)
+#define MCF5272_RD_PLI_PCKSELR(IMMP) Mcf5272_iord(IMMP,MCF5272_PLI_PCKSELR,16)
+
+/* Write access macros for general use */
+#define MCF5272_WR_PLI_P0B1TR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P0B1TR,32,DATA)
+#define MCF5272_WR_PLI_P1B1TR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P1B1TR,32,DATA)
+#define MCF5272_WR_PLI_P2B1TR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P2B1TR,32,DATA)
+#define MCF5272_WR_PLI_P3B1TR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P3B1TR,32,DATA)
+#define MCF5272_WR_PLI_P0B2TR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P0B2TR,32,DATA)
+#define MCF5272_WR_PLI_P1B2TR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P1B2TR,32,DATA)
+#define MCF5272_WR_PLI_P2B2TR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P2B2TR,32,DATA)
+#define MCF5272_WR_PLI_P3B2TR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P3B2TR,32,DATA)
+#define MCF5272_WR_PLI_P0DTR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P0DTR,8,DATA)
+#define MCF5272_WR_PLI_P1DTR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P1DTR,8,DATA)
+#define MCF5272_WR_PLI_P2DTR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P2DTR,8,DATA)
+#define MCF5272_WR_PLI_P3DTR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P3DTR,8,DATA)
+#define MCF5272_WR_PLI_P0CR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P0CR,16,DATA)
+#define MCF5272_WR_PLI_P1CR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P1CR,16,DATA)
+#define MCF5272_WR_PLI_P2CR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P2CR,16,DATA)
+#define MCF5272_WR_PLI_P3CR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P3CR,16,DATA)
+#define MCF5272_WR_PLI_P0ICR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P0ICR,16,DATA)
+#define MCF5272_WR_PLI_P1ICR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P1ICR,16,DATA)
+#define MCF5272_WR_PLI_P2ICR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P2ICR,16,DATA)
+#define MCF5272_WR_PLI_P3ICR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P3ICR,16,DATA)
+#define MCF5272_WR_PLI_P0GMT(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P0GMR,16,DATA)
+#define MCF5272_WR_PLI_P1GMT(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P1GMT,16,DATA)
+#define MCF5272_WR_PLI_P2GMT(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P2GMT,16,DATA)
+#define MCF5272_WR_PLI_P3GMT(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P3GMT,16,DATA)
+#define MCF5272_WR_PLI_PGMTA(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_PGMTA,8,DATA)
+#define MCF5272_WR_PLI_P0GCIT(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P0GCIT,8,DATA)
+#define MCF5272_WR_PLI_P1GCIT(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P1GCIT,8,DATA)
+#define MCF5272_WR_PLI_P2GCIT(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P2GCIT,8,DATA)
+#define MCF5272_WR_PLI_P3GCIT(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P3GCIT,8,DATA)
+#define MCF5272_WR_PLI_PLCR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_PLCR,8,DATA)
+#define MCF5272_WR_PLI_PDRQR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_PDRQR,16,DATA)
+#define MCF5272_WR_PLI_P0SDR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P0SDR,16,DATA)
+#define MCF5272_WR_PLI_P1SDR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P1SDR,16,DATA)
+#define MCF5272_WR_PLI_P2SDR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P2SDR,16,DATA)
+#define MCF5272_WR_PLI_P3SDR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_P3SDR,16,DATA)
+#define MCF5272_WR_PLI_PCKSELR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_PLI_PCKSELR,16,DATA)
+
+
+/**********************************************************************
+*
+* Fast Ethernet Controller Module Register Descriptions
+*
+***********************************************************************/
+
+/* Offsets of the registers from the MBAR */
+#define MCF5272_FEC_ECR			(0x0840)
+#define MCF5272_FEC_EIR			(0x0844)
+#define MCF5272_FEC_IMR			(0x0848)
+#define MCF5272_FEC_IVSR		(0x084C)
+#define MCF5272_FEC_RDAR		(0x0850)
+#define MCF5272_FEC_TDAR		(0x0854)
+#define MCF5272_FEC_MMFR		(0x0880)
+#define MCF5272_FEC_MSCR		(0x0884)
+#define MCF5272_FEC_FRBR		(0x08CC)
+#define MCF5272_FEC_FRSR		(0x08D0)
+#define MCF5272_FEC_TFWR		(0x08E4)
+#define MCF5272_FEC_FTSR		(0x08EC)
+#define MCF5272_FEC_RCR			(0x0944)
+#define MCF5272_FEC_MFLR		(0x0948)
+#define MCF5272_FEC_TCR			(0x0984)
+#define MCF5272_FEC_MALR		(0x0C00)
+#define MCF5272_FEC_MAUR		(0x0C04)
+#define MCF5272_FEC_HTUR		(0x0C08)
+#define MCF5272_FEC_HTLR		(0x0C0C)
+#define MCF5272_FEC_ERDSR		(0x0C10)
+#define MCF5272_FEC_ETDSR		(0x0C14)
+#define MCF5272_FEC_EMRBR		(0x0C18)
+#define MCF5272_FEC_EFIFO		(0x0C40)	/* 0x0C40 - 0x0DFF */
+
+/* Read access macros for general use */
+#define MCF5272_RD_FEC_ECR(IMMP)			\
+	Mcf5272_iord(IMMP,MCF5272_FEC_ECR,32)
+#define MCF5272_RD_FEC_EIR(IMMP)			\
+	Mcf5272_iord(IMMP,MCF5272_FEC_EIR,32)
+#define MCF5272_RD_FEC_IMR(IMMP)			\
+	Mcf5272_iord(IMMP,MCF5272_FEC_IMR,32)
+#define MCF5272_RD_FEC_IVSR(IMMP)			\
+	Mcf5272_iord(IMMP,MCF5272_FEC_IVSR,32)
+#define MCF5272_RD_FEC_RDAR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_FEC_RDAR,32)
+#define MCF5272_RD_FEC_TDAR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_FEC_TDAR,32)
+#define MCF5272_RD_FEC_MMFR(IMMP)		\
+	Mcf5272_iord(IMMP,MCF5272_FEC_MMFR,32)
+#define MCF5272_RD_FEC_MSCR(IMMP)		\
+	Mcf5272_iord(IMMP,MCF5272_FEC_MSCR,32)
+#define MCF5272_RD_FEC_FRBR(IMMP)		\
+	Mcf5272_iord(IMMP,MCF5272_FEC_FRBR,32)
+#define MCF5272_RD_FEC_FRSR(IMMP)		\
+	Mcf5272_iord(IMMP,MCF5272_FEC_FRSR,32)
+#define MCF5272_RD_FEC_TFWR(IMMP)			\
+	Mcf5272_iord(IMMP,MCF5272_FEC_TFWR,32)
+#define MCF5272_RD_FEC_FTSR(IMMP)		\
+	Mcf5272_iord(IMMP,MCF5272_FEC_FTSR,32)
+#define MCF5272_RD_FEC_RCR(IMMP)		\
+	Mcf5272_iord(IMMP,MCF5272_FEC_RCR,32)
+#define MCF5272_RD_FEC_MFLR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_FEC_MFLR,32)
+#define MCF5272_RD_FEC_TCR(IMMP)		\
+	Mcf5272_iord(IMMP,MCF5272_FEC_TCR,32)
+#define MCF5272_RD_FEC_MALR(IMMP)		\
+	Mcf5272_iord(IMMP,MCF5272_FEC_MALR,32)
+#define MCF5272_RD_FEC_MAUR(IMMP)		\
+	Mcf5272_iord(IMMP,MCF5272_FEC_MAUR,32)
+#define MCF5272_RD_FEC_HTUR(IMMP)		\
+	Mcf5272_iord(IMMP,MCF5272_FEC_HTUR,32)
+#define MCF5272_RD_FEC_HTLR(IMMP)		\
+	Mcf5272_iord(IMMP,MCF5272_FEC_HTLR,32)
+#define MCF5272_RD_FEC_ERDSR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_FEC_ERDSR,32)
+#define MCF5272_RD_FEC_ETDSR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_FEC_ETDSR,32)
+#define MCF5272_RD_FEC_EMRBR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_FEC_EMRBR,32)
+
+/* Write access macros for general use */
+#define MCF5272_WR_FEC_ECR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_ECR,32,DATA)
+#define MCF5272_WR_FEC_EIR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_EIR,32,DATA)
+#define MCF5272_WR_FEC_IMR(IMMP,DATA)			\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_IMR,32,DATA)
+#define MCF5272_WR_FEC_RDAR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_RDAR,32,DATA)
+#define MCF5272_WR_FEC_TDAR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_TDAR,32,DATA)
+#define MCF5272_WR_FEC_MMFR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_MMFR,32,DATA)
+#define MCF5272_WR_FEC_MSCR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_MSCR,32,DATA)
+#define MCF5272_WR_FEC_FRSR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_FRSR,32,DATA)
+#define MCF5272_WR_FEC_TFWR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_TFWR,32,DATA)
+#define MCF5272_WR_FEC_FTSR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_FTSR,32,DATA)
+#define MCF5272_WR_FEC_RCR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_RCR,32,DATA)
+#define MCF5272_WR_FEC_MFLR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_MFLR,32,DATA)
+#define MCF5272_WR_FEC_TCR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_TCR,32,DATA)
+#define MCF5272_WR_FEC_MALR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_MALR,32,DATA)
+#define MCF5272_WR_FEC_MAUR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_MAUR,32,DATA)
+#define MCF5272_WR_FEC_HTUR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_HTUR,32,DATA)
+#define MCF5272_WR_FEC_HTLR(IMMP,DATA)		\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_HTLR,32,DATA)
+#define MCF5272_WR_FEC_ERDSR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_ERDSR,32,DATA)
+#define MCF5272_WR_FEC_ETDSR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_ETDSR,32,DATA)
+#define MCF5272_WR_FEC_EMRBR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_FEC_EMRBR,32,DATA)
+
+
+/* Bit level definitions and macros */
+#define MCF5272_FEC_ECR_RESET		(0x00000001)
+#define MCF5272_FEC_ECR_ETHER_EN	(0x00000002)
+#define MCF5272_FEC_EIR_GRA			(0x10000000)
+#define MCF5272_FEC_EIR_RXF			(0x02000000)
+#define MCF5272_FEC_EIR_TXF			(0x08000000)
+#define MCF5272_FEC_IMR_HBEEN		(0x80000000)
+#define MCF5272_FEC_IMR_BREN		(0x40000000)
+#define MCF5272_FEC_IMR_BTEN		(0x20000000)
+#define MCF5272_FEC_IMR_GRAEN		(0x10000000)
+#define MCF5272_FEC_IMR_TXFEN		(0x08000000)
+#define MCF5272_FEC_IMR_TXBEN		(0x04000000)
+#define MCF5272_FEC_IMR_RXFEN		(0x02000000)
+#define MCF5272_FEC_IMR_RXBEN		(0x01000000)
+#define MCF5272_FEC_IMR_MIIEN		(0x00800000)
+#define MCF5272_FEC_IMR_EBERREN		(0x00400000)
+#define MCF5272_FEC_RCR_PROM		(0x00000008)
+#define MCF5272_FEC_RCR_MII_MODE	(0x00000004)
+#define MCF5272_FEC_RCR_DRT			(0x00000002)
+#define MCF5272_FEC_RCR_LOOP		(0x00000001)
+#define MCF5272_FEC_TCR_GTS			(0x00000001)
+#define MCF5272_FEC_TCR_HBC			(0x00000002)
+#define MCF5272_FEC_TCR_FDEN		(0x00000004)
+#define MCF5272_MMFR_MODE			(0x00004000)
+#define MCF5272_MMFR_DUPLEX			(0x00000200)
+#define MCF5272_MMFR_LOOP			(0x00004000)
+#define MCF5272_MMFR_NEGOTIATE		(0x00001000)
+#define MCF5272_MMFR_100			(0x00002000)
+
+/**********************************************************************
+*
+* USB_ Module Register Description
+*
+***********************************************************************/
+
+/* Offsets of the registers from the MBAR */
+#define MCF5272_USB_FNR			(0x1002)
+#define MCF5272_USB_FNMR		(0x1006)
+#define MCF5272_USB_RFMR		(0x100A)
+#define MCF5272_USB_RFMMR		(0x100E)
+#define MCF5272_USB_FAR			(0x1013)
+#define MCF5272_USB_ASR			(0x1014)
+#define MCF5272_USB_DRR1		(0x1018)
+#define MCF5272_USB_DRR2		(0x101C)
+#define MCF5272_USB_SPECR		(0x1022)
+#define MCF5272_USB_EP0SR		(0x1026)
+#define MCF5272_USB_IEP0CFG		(0x1028)
+#define MCF5272_USB_OEP0CFG		(0x102C)
+#define MCF5272_USB_EP1CFG		(0x1030)
+#define MCF5272_USB_EP2CFG		(0x1034)
+#define MCF5272_USB_EP3CFG		(0x1038)
+#define MCF5272_USB_EP4CFG		(0x103C)
+#define MCF5272_USB_EP5CFG		(0x1040)
+#define MCF5272_USB_EP6CFG		(0x1044)
+#define MCF5272_USB_EP7CFG		(0x1048)
+#define MCF5272_USB_EP0CTL		(0x104C)
+#define MCF5272_USB_EP1CTL		(0x1052)
+#define MCF5272_USB_EP2CTL		(0x1056)
+#define MCF5272_USB_EP3CTL		(0x105A)
+#define MCF5272_USB_EP4CTL		(0x105E)
+#define MCF5272_USB_EP5CTL		(0x1062)
+#define MCF5272_USB_EP6CTL		(0x1066)
+#define MCF5272_USB_EP7CTL		(0x106A)
+#define MCF5272_USB_EP0ISR		(0x106C)
+#define MCF5272_USB_EP1ISR		(0x1072)
+#define MCF5272_USB_EP2ISR		(0x1076)
+#define MCF5272_USB_EP3ISR		(0x107A)
+#define MCF5272_USB_EP4ISR		(0x107E)
+#define MCF5272_USB_EP5ISR		(0x1082)
+#define MCF5272_USB_EP6ISR		(0x1086)
+#define MCF5272_USB_EP7ISR		(0x108A)
+#define MCF5272_USB_EP0IMR		(0x108C)
+#define MCF5272_USB_EP1IMR		(0x1092)
+#define MCF5272_USB_EP2IMR		(0x1096)
+#define MCF5272_USB_EP3IMR		(0x109A)
+#define MCF5272_USB_EP4IMR		(0x109E)
+#define MCF5272_USB_EP5IMR		(0x10A2)
+#define MCF5272_USB_EP6IMR		(0x10A6)
+#define MCF5272_USB_EP7IMR		(0x10AA)
+#define MCF5272_USB_EP0DR		(0x10AC)
+#define MCF5272_USB_EP1DR		(0x10B0)
+#define MCF5272_USB_EP2DR		(0x10B4)
+#define MCF5272_USB_EP3DR		(0x10B8)
+#define MCF5272_USB_EP4DR		(0x10BC)
+#define MCF5272_USB_EP5DR		(0x10C0)
+#define MCF5272_USB_EP6DR		(0x10C4)
+#define MCF5272_USB_EP7DR		(0x10C8)
+#define MCF5272_USB_EP0DPR		(0x10CE)
+#define MCF5272_USB_EP1DPR		(0x10D2)
+#define MCF5272_USB_EP2DPR		(0x10D6)
+#define MCF5272_USB_EP3DPR		(0x10DA)
+#define MCF5272_USB_EP4DPR		(0x10DE)
+#define MCF5272_USB_EP5DPR		(0x10E2)
+#define MCF5272_USB_EP6DPR		(0x10E6)
+#define MCF5272_USB_EP7DPR		(0x10EA)
+#define MCF5272_USB_CFG_RAM		(0x1400)	/* 0x1400 - 0x17FF */
+
+/* Read access macros for general use */
+#define MCF5272_RD_USB_FNR(IMMP)		\
+	Mcf5272_iord(IMMP,MCF5272_USB_FNR,16)
+#define MCF5272_RD_USB_FNMR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_FNMR,16)
+#define MCF5272_RD_USB_RFMR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_RFMR,16)
+#define MCF5272_RD_USB_RFMMR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_RFMMR,16)
+#define MCF5272_RD_USB_FAR(IMMP)		\
+	Mcf5272_iord(IMMP,MCF5272_USB_FAR,8)
+#define MCF5272_RD_USB_ASR(IMMP)		\
+	Mcf5272_iord(IMMP,MCF5272_USB_ASR,32)
+#define MCF5272_RD_USB_DRR1(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_DRR1,32)
+#define MCF5272_RD_USB_DRR2(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_DRR2,32)
+#define MCF5272_RD_USB_SPECR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_SPECR,16)
+#define MCF5272_RD_USB_EP0SR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP0SR,16)
+#define MCF5272_RD_USB_IEP0CFG(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_IEP0CFG,32)
+#define MCF5272_RD_USB_OEP0CFG(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_OEP0CFG,32)
+#define MCF5272_RD_USB_EPCFG(IMMP,EPN)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP1CFG + 4*(EPN-1),32)
+#define MCF5272_RD_USB_EP1CFG(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP1CFG,32)
+#define MCF5272_RD_USB_EP2CFG(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP2CFG,32)
+#define MCF5272_RD_USB_EP3CFG(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP3CFG,32)
+#define MCF5272_RD_USB_EP4CFG(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP4CFG,32)
+#define MCF5272_RD_USB_EP5CFG(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP5CFG,32)
+#define MCF5272_RD_USB_EP6CFG(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP6CFG,32)
+#define MCF5272_RD_USB_EP7CFG(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP7CFG,32)
+#define MCF5272_RD_USB_EPCTL(IMMP,EPN)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP0CTL + 4*EPN,32)
+#define MCF5272_RD_USB_EP0CTL(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP0CTL,32)
+#define MCF5272_RD_USB_EP1CTL(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP1CTL,16)
+#define MCF5272_RD_USB_EP2CTL(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP2CTL,16)
+#define MCF5272_RD_USB_EP3CTL(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP3CTL,16)
+#define MCF5272_RD_USB_EP4CTL(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP4CTL,16)
+#define MCF5272_RD_USB_EP5CTL(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP5CTL,16)
+#define MCF5272_RD_USB_EP6CTL(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP6CTL,16)
+#define MCF5272_RD_USB_EP7CTL(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP7CTL,16)
+#define MCF5272_RD_USB_EPISR(IMMP,EPN)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP0ISR + 4*EPN,32)
+#define MCF5272_RD_USB_EP0ISR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP0ISR,32)
+#define MCF5272_RD_USB_EP1ISR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP1ISR,16)
+#define MCF5272_RD_USB_EP2ISR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP2ISR,16)
+#define MCF5272_RD_USB_EP3ISR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP3ISR,16)
+#define MCF5272_RD_USB_EP4ISR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP4ISR,16)
+#define MCF5272_RD_USB_EP5ISR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP5ISR,16)
+#define MCF5272_RD_USB_EP6ISR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP6ISR,16)
+#define MCF5272_RD_USB_EP7ISR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP7ISR,16)
+#define MCF5272_RD_USB_EPIMR(IMMP,EPN)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP0IMR + 4*EPN,32)
+#define MCF5272_RD_USB_EP0IMR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP0IMR,32)
+#define MCF5272_RD_USB_EP1IMR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP1IMR,16)
+#define MCF5272_RD_USB_EP2IMR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP2IMR,16)
+#define MCF5272_RD_USB_EP3IMR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP3IMR,16)
+#define MCF5272_RD_USB_EP4IMR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP4IMR,16)
+#define MCF5272_RD_USB_EP5IMR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP5IMR,16)
+#define MCF5272_RD_USB_EP6IMR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP6IMR,16)
+#define MCF5272_RD_USB_EP7IMR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP7IMR,16)
+#define MCF5272_RD_USB_EPDR(IMMP,EPN,SIZE)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP0DR + 4*EPN,SIZE)
+#define MCF5272_RD_USB_EP0DR(IMMP,SIZE)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP0DR,SIZE)
+#define MCF5272_RD_USB_EP1DR(IMMP,SIZE)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP1DR,SIZE)
+#define MCF5272_RD_USB_EP2DR(IMMP,SIZE)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP2DR,SIZE)
+#define MCF5272_RD_USB_EP3DR(IMMP,SIZE)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP3DR,SIZE)
+#define MCF5272_RD_USB_EP4DR(IMMP,SIZE)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP4DR,SIZE)
+#define MCF5272_RD_USB_EP5DR(IMMP,SIZE)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP5DR,SIZE)
+#define MCF5272_RD_USB_EP6DR(IMMP,SIZE)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP6DR,SIZE)
+#define MCF5272_RD_USB_EP7DR(IMMP,SIZE)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP7DR,SIZE)
+#define MCF5272_RD_USB_EPDPR(IMMP,EPN)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP0DPR + 4*EPN,16)
+#define MCF5272_RD_USB_EP0DPR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP0DPR,16)
+#define MCF5272_RD_USB_EP1DPR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP1DPR,16)
+#define MCF5272_RD_USB_EP2DPR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP2DPR,16)
+#define MCF5272_RD_USB_EP3DPR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP3DPR,16)
+#define MCF5272_RD_USB_EP4DPR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP4DPR,16)
+#define MCF5272_RD_USB_EP5DPR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP5DPR,16)
+#define MCF5272_RD_USB_EP6DPR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP6DPR,16)
+#define MCF5272_RD_USB_EP7DPR(IMMP)	\
+	Mcf5272_iord(IMMP,MCF5272_USB_EP7DPR,16)
+
+/* Write access macros for general use */
+#define MCF5272_WR_USB_FNR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_FNR,16,DATA)
+#define MCF5272_WR_USB_FNMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_FNMR,16,DATA)
+#define MCF5272_WR_USB_RFMMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_RFMMR,16,DATA)
+#define MCF5272_WR_USB_EP0SR(IMMP,DATA)\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP0SR,32,DATA)
+#define MCF5272_WR_USB_IEP0CFG(IMMP,DATA)\
+	Mcf5272_iowr(IMMP,MCF5272_USB_IEP0CFG,32,DATA)
+#define MCF5272_WR_USB_OEP0CFG(IMMP,DATA)\
+	Mcf5272_iowr(IMMP,MCF5272_USB_OEP0CFG,32,DATA)
+#define MCF5272_WR_USB_EPCFG(IMMP,EPN,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP1CFG + 4*(EPN-1),32,DATA)
+#define MCF5272_WR_USB_EP1CFG(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP1CFG,32,DATA)
+#define MCF5272_WR_USB_EP2CFG(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP2CFG,32,DATA)
+#define MCF5272_WR_USB_EP3CFG(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP3CFG,32,DATA)
+#define MCF5272_WR_USB_EP4CFG(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP4CFG,32,DATA)
+#define MCF5272_WR_USB_EP5CFG(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP5CFG,32,DATA)
+#define MCF5272_WR_USB_EP6CFG(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP6CFG,32,DATA)
+#define MCF5272_WR_USB_EP7CFG(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP7CFG,32,DATA)
+#define MCF5272_WR_USB_EPCTL(IMMP,EPN,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP0CTL + 4*EPN,32,DATA)
+#define MCF5272_WR_USB_EP0CTL(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP0CTL,32,DATA)
+#define MCF5272_WR_USB_EP1CTL(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP1CTL,16,DATA)
+#define MCF5272_WR_USB_EP2CTL(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP2CTL,16,DATA)
+#define MCF5272_WR_USB_EP3CTL(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP3CTL,16,DATA)
+#define MCF5272_WR_USB_EP4CTL(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP4CTL,16,DATA)
+#define MCF5272_WR_USB_EP5CTL(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP5CTL,16,DATA)
+#define MCF5272_WR_USB_EP6CTL(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP6CTL,16,DATA)
+#define MCF5272_WR_USB_EP7CTL(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP7CTL,16,DATA)
+#define MCF5272_WR_USB_EPISR(IMMP,EPN,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP0ISR + 4*EPN,32,DATA)
+#define MCF5272_WR_USB_EP0ISR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP0ISR,32,DATA)
+#define MCF5272_WR_USB_EP1ISR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP1ISR,16,DATA)
+#define MCF5272_WR_USB_EP2ISR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP2ISR,16,DATA)
+#define MCF5272_WR_USB_EP3ISR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP3ISR,16,DATA)
+#define MCF5272_WR_USB_EP4ISR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP4ISR,16,DATA)
+#define MCF5272_WR_USB_EP5ISR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP5ISR,16,DATA)
+#define MCF5272_WR_USB_EP6ISR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP6ISR,16,DATA)
+#define MCF5272_WR_USB_EP7ISR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP7ISR,16,DATA)
+#define MCF5272_WR_USB_EPIMR(IMMP,EPN,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP0IMR + 4*EPN,32,DATA)
+#define MCF5272_WR_USB_EP0IMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP0IMR,32,DATA)
+#define MCF5272_WR_USB_EP1IMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP1IMR,16,DATA)
+#define MCF5272_WR_USB_EP2IMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP2IMR,16,DATA)
+#define MCF5272_WR_USB_EP3IMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP3IMR,16,DATA)
+#define MCF5272_WR_USB_EP4IMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP4IMR,16,DATA)
+#define MCF5272_WR_USB_EP5IMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP5IMR,16,DATA)
+#define MCF5272_WR_USB_EP6IMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP6IMR,16,DATA)
+#define MCF5272_WR_USB_EP7IMR(IMMP,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP7IMR,16,DATA)
+#define MCF5272_WR_USB_EPDR(IMMP,EPN,SIZE,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP0DR + 4*EPN,SIZE,DATA)
+#define MCF5272_WR_USB_EP0DR(IMMP,SIZE,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP0DR,SIZE,DATA)
+#define MCF5272_WR_USB_EP1DR(IMMP,SIZE,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP1DR,SIZE,DATA)
+#define MCF5272_WR_USB_EP2DR(IMMP,SIZE,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP2DR,SIZE,DATA)
+#define MCF5272_WR_USB_EP3DR(IMMP,SIZE,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP3DR,SIZE,DATA)
+#define MCF5272_WR_USB_EP4DR(IMMP,SIZE,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP4DR,SIZE,DATA)
+#define MCF5272_WR_USB_EP5DR(IMMP,SIZE,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP5DR,SIZE,DATA)
+#define MCF5272_WR_USB_EP6DR(IMMP,SIZE,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP6DR,SIZE,DATA)
+#define MCF5272_WR_USB_EP7DR(IMMP,SIZE,DATA)	\
+	Mcf5272_iowr(IMMP,MCF5272_USB_EP7DR,SIZE,DATA)
+
+/* Macro to return current Alternate Setting for a given Interface */
+#define AltSetting(imm, i)	(int8)((MCF5272_RD_USB_ASR(imm) >> (i << 1)) & 3)
+
+/* Bit level definitions and macros */
+#define MCF5272_USB_EP0SR_WAKE_ST           0x0800
+#define MCF5272_USB_EP0SR_HALT_ST           0x0004
+#define MCF5272_USB_EP0SR_DIR               0x0002
+
+#define MCF5272_USB_EP0CTL_DEBUG			0x00040000
+#define MCF5272_USB_EP0CTL_WOR_LVL			0x00020000
+#define MCF5272_USB_EP0CTL_WOR_EN			0x00010000
+#define MCF5272_USB_EP0CTL_CLK_SEL			0x00008000
+#define MCF5272_USB_EP0CTL_RESUME			0x00004000
+#define MCF5272_USB_EP0CTL_AFE_EN			0x00002000
+#define MCF5272_USB_EP0CTL_BUS_PWR			0x00001000
+#define MCF5272_USB_EP0CTL_USB_EN			0x00000800
+#define MCF5272_USB_EP0CTL_CFG_RAM_VAL		0x00000400
+#define MCF5272_USB_EP0CTL_CMD_ERR			0x00000200
+#define MCF5272_USB_EP0CTL_CMD_OVER			0x00000100
+#define MCF5272_USB_EP0CTL_CRC_ERR			0x00000080
+#define MCF5272_USB_EP0CTL_OUT_LVL(x)		((x & 3) << 4)
+#define MCF5272_USB_EP0CTL_IN_LVL(x)		((x & 3) << 2)
+#define MCF5272_USB_EP0CTL_IN_BUSY			0x00000002
+#define MCF5272_USB_EP0CTL_IN_DONE			0x00000002
+
+#define MCF5272_USB_EPNCTL_CRC_ERR			0x0080
+#define MCF5272_USB_EPNCTL_ISO_MODE			0x0040
+#define MCF5272_USB_EPNCTL_FIFO_LVL(x)		((x & 3) << 2)
+#define MCF5272_USB_EPNCTL_IN_BUSY			0x0002
+#define MCF5272_USB_EPNCTL_IN_DONE			0x0002
+#define MCF5272_USB_EPNCTL_STALL			0x0001
+
+#define MCF5272_USB_EP0ISR_DEV_CFG			0x00010000
+#define MCF5272_USB_EP0ISR_VEND_REQ			0x00008000
+#define MCF5272_USB_EP0ISR_FRM_MAT			0x00004000
+#define MCF5272_USB_EP0ISR_ASOF				0x00002000
+#define MCF5272_USB_EP0ISR_SOF				0x00001000
+#define MCF5272_USB_EP0ISR_WAKE_CHG			0x00000800
+#define MCF5272_USB_EP0ISR_RESUME			0x00000400
+#define MCF5272_USB_EP0ISR_SUSPEND			0x00000200
+#define MCF5272_USB_EP0ISR_RESET			0x00000100
+#define MCF5272_USB_EP0ISR_OUT_EOT			0x00000080
+#define MCF5272_USB_EP0ISR_OUT_EOP			0x00000040
+#define MCF5272_USB_EP0ISR_OUT_LVL			0x00000020
+#define MCF5272_USB_EP0ISR_IN_EOT			0x00000010
+#define MCF5272_USB_EP0ISR_IN_EOP			0x00000008
+#define MCF5272_USB_EP0ISR_UNHALT			0x00000004
+#define MCF5272_USB_EP0ISR_HALT				0x00000002
+#define MCF5272_USB_EP0ISR_IN_LVL			0x00000001
+
+#define MCF5272_USB_EPNISR_HALT_ST			0x8000
+#define MCF5272_USB_EPNISR_DIR				0x4000
+#define MCF5272_USB_EPNISR_PRES				0x2000
+#define MCF5272_USB_EPNISR_EOT				0x0010
+#define MCF5272_USB_EPNISR_EOP				0x0008
+#define MCF5272_USB_EPNISR_UNHALT			0x0004
+#define MCF5272_USB_EPNISR_HALT				0x0002
+#define MCF5272_USB_EPNISR_FIFO_LVL			0x0001
+
+#define MCF5272_USB_EP0IMR_DEV_CFG_EN		0x00010000
+#define MCF5272_USB_EP0IMR_VEND_REQ_EN		0x00008000
+#define MCF5272_USB_EP0IMR_FRM_MAT_EN		0x00004000
+#define MCF5272_USB_EP0IMR_ASOF_EN			0x00002000
+#define MCF5272_USB_EP0IMR_SOF_EN			0x00001000
+#define MCF5272_USB_EP0IMR_WAKE_CHG_EN		0x00000800
+#define MCF5272_USB_EP0IMR_RESUME_EN		0x00000400
+#define MCF5272_USB_EP0IMR_SUSPEND_EN		0x00000200
+#define MCF5272_USB_EP0IMR_RESET_EN			0x00000100
+#define MCF5272_USB_EP0IMR_OUT_EOT_EN		0x00000080
+#define MCF5272_USB_EP0IMR_OUT_EOP_EN		0x00000040
+#define MCF5272_USB_EP0IMR_OUT_LVL_EN		0x00000020
+#define MCF5272_USB_EP0IMR_IN_EOT_EN		0x00000010
+#define MCF5272_USB_EP0IMR_IN_EOP_EN		0x00000008
+#define MCF5272_USB_EP0IMR_UNHALT_EN		0x00000004
+#define MCF5272_USB_EP0IMR_HALT_EN			0x00000002
+#define MCF5272_USB_EP0IMR_IN_LVL_EN		0x00000001
+
+#define MCF5272_USB_EPNIMR_EOT_EN			0x0010
+#define MCF5272_USB_EPNIMR_EOP_EN			0x0008
+#define MCF5272_USB_EPNIMR_UNHALT_EN		0x0004
+#define MCF5272_USB_EPNIMR_HALT_EN			0x0002
+#define MCF5272_USB_EPNIMR_FIFO_LVL_EN		0x0001
+
+/***********************************************************************/
+
+/* 
+ * Define a pointer to the MCF5272 Internal Memory Map 
+ */
+
+typedef uint8	MCF5272_IMM;
+
+/***********************************************************************/
+
+#endif	/* _CPU_MCF5272_H */
diff -urN linux-2.4.29/drivers/char/mcf_descriptors.h linux-2.4.29-uc1/drivers/char/mcf_descriptors.h
--- linux-2.4.29/drivers/char/mcf_descriptors.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/mcf_descriptors.h	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,156 @@
+/*********************************************************************
+ *
+ * Copyright:
+ *	MOTOROLA, INC. All Rights Reserved.  
+ *  You are hereby granted a copyright license to use, modify, and
+ *  distribute the SOFTWARE so long as this entire notice is
+ *  retained without alteration in any modified and/or redistributed
+ *  versions, and that such modified versions are clearly identified
+ *  as such. No licenses are granted by implication, estoppel or
+ *  otherwise under any patents or trademarks of Motorola, Inc. This 
+ *  software is provided on an "AS IS" basis and without warranty.
+ *
+ *  To the maximum extent permitted by applicable law, MOTOROLA 
+ *  DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING 
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+ *  PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH REGARD TO THE 
+ *  SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) AND ANY 
+ *  ACCOMPANYING WRITTEN MATERIALS.
+ * 
+ *  To the maximum extent permitted by applicable law, IN NO EVENT
+ *  SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING 
+ *  WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS 
+ *  INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY
+ *  LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.   
+ * 
+ *  Motorola assumes no responsibility for the maintenance and support
+ *  of this software
+ ********************************************************************/
+
+/*
+ * File:		descriptors.h
+ * Purpose:		USB Descriptors definitions
+ */
+
+#ifndef DESCRIPTOR_H
+#define DESCRIPTOR_H
+
+#include "mcf_usb.h"
+/********************************************************************/
+
+/* USB descriptor types */
+#define DEVICE				1
+#define CONFIGURATION			2
+#define STRING				3
+#define INTERFACE			4
+#define ENDPOINT			5
+
+/* USB Standard Request Types - bRequestType */
+#define IN				0x80
+#define OUT				0x00
+#define STANDARD			0x00
+#define CLASS				0x20
+#define VENDOR				0x40
+#define RQ_DEVICE			0x00
+#define RQ_INTERFACE			0x01
+#define RQ_ENDPOINT			0x02
+
+/* USB Standard Request Codes - bRequest */
+#define GET_STATUS			0
+#define CLEAR_FEATURE			1
+#define SET_FEATURE			3
+#define SET_ADDRESS			5
+#define GET_DESCRIPTOR			6
+#define SET_DESCRIPTOR			7
+#define GET_CONFIGURATION		8
+#define SET_CONFIGURATION		9
+#define GET_INTERFACE			10
+#define SET_INTERFACE			11
+#define SYNCH_FRAME			12
+
+/* Configuration bmAttributes fields */
+#define BUS_POWERED			0x80
+#define SELF_POWERED			0xC0
+#define REMOTE_WAKEUP			0xA0
+
+/* Endpoint bmAttributes fields */
+#define CONTROL				0x00
+#define ISOCHRONOUS			0x01
+#define BULK				0x02
+#define INTERRUPT			0x03
+#define DISABLED			0xFF
+
+/* Standard Feature Selectors */
+#define DEVICE_REMOTE_WAKEUP		1
+#define ENDPOINT_HALT			0
+
+/* Structure for USB Device Descriptors */
+typedef struct {
+	uint8 bLength;
+	uint8 bDescriptorType;
+	uint8 bcdUSBL;
+	uint8 bcdUSBH;
+	uint8 bDeviceClass;
+	uint8 bDeviceSubClass;
+	uint8 bDeviceProtocol;
+	uint8 bMaxPacketSize0;
+	uint8 idVendorL;
+	uint8 idVendorH;
+	uint8 idProductL;
+	uint8 idProductH;
+	uint8 bcdDeviceL;
+	uint8 bcdDeviceH;
+	uint8 iManufacturer;
+	uint8 iProduct;
+	uint8 iSerialNumber;
+	uint8 bNumConfigurations;
+} USB_DEVICE_DESC;
+
+/* Structure for USB Configuration Descriptors */
+typedef struct {
+	uint8 bLength;
+	uint8 bDescriptorType;
+	uint8 wTotalLengthL;
+	uint8 wTotalLengthH;
+	uint8 bNumInterfaces;
+	uint8 bConfigurationValue;
+	uint8 iConfiguration;
+	uint8 bmAttributes;
+	uint8 maxPower;
+} USB_CONFIG_DESC;
+
+/* Structure for USB Interface Descriptors */
+typedef struct {
+	uint8 bLength;
+	uint8 bDescriptorType;
+	uint8 bInterfaceNumber;
+	uint8 bAlternateSetting;
+	uint8 bNumEndpoints;
+	uint8 bInterfaceClass;
+	uint8 bInterfaceSubClass;
+	uint8 bInterfaceProtocol;
+	uint8 iInterface;
+} USB_INTERFACE_DESC;
+
+/* Structure for USB Endpoint Descriptors */
+typedef struct {
+	uint8 bLength;
+	uint8 bDescriptorType;
+	uint8 bEndpointAddress;
+	uint8 bmAttributes;
+	uint8 wMaxPacketSizeL;
+	uint8 wMaxPacketSizeH;
+	uint8 bInterval;
+} USB_ENDPOINT_DESC;
+
+/* Structure for USB String Descriptors */
+typedef struct {
+        uint8 bLength;
+        uint8 bDescriptorType;
+        uint8 bString[256];
+} STR_DESC;
+
+/********************************************************************/
+
+#endif /* DESCRIPTOR_H */
+
diff -urN linux-2.4.29/drivers/char/mcf_qspi.c linux-2.4.29-uc1/drivers/char/mcf_qspi.c
--- linux-2.4.29/drivers/char/mcf_qspi.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/mcf_qspi.c	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,829 @@
+/************************************************************************/
+/*                                                                      */
+/*  mcf_qspi.c - QSPI driver for MCF5272, MCF5235, MCF5282              */
+/*                                                                      */
+/*  (C) Copyright 2001, Wayne Roberts (wroberts1@home.com)              */
+/*                                                                      */
+/*  Driver has an 8bit mode, and a 16bit mode.                          */
+/*  Transfer size QMR[BITS] is set thru QSPIIOCS_BITS.                  */
+/*  When size is 8, driver works normally:                              */
+/*        a char is sent for every transfer                             */
+/*  When size is 9 to 16bits, driver reads & writes the QDRs with       */
+/*  the buffer cast to unsigned shorts.  The QTR & QRR registers can    */
+/*  be filled with up to 16bits.  The length passed to read/write must  */
+/*  be of the number of chars (2x number of shorts). This has been      */
+/*  tested with 10bit a/d and d/a converters.                           */
+/*                                                                      */
+/*  * QSPIIOCS_READDATA:                                                */
+/*    data to send out during read                                      */
+/*  * all other ioctls are global                                       */
+/* -------------------------------------------------------------------- */
+/*  Ported to linux-2.4.x by Ron Fial (ron@fial.com) August 26,2002     */
+/*                                                                      */
+/*   Added new include files                                            */
+/*   Added module_init(),exit(),                                        */
+/*   qspi_read(),qspi_write():  Revised qspi_read & write argument      */
+/*     processing to handle new *filep argument. Changed i_rdev access  */
+/*     to use filep->f_dentry->d_inode->i_rdev  Changed memcpy_fromfs() */
+/*     to memcpy().                                                     */
+/*   Added '__init' to compiled-in init routine for memory recovery     */
+/*   Added '__exit' for loadable-driver module cleanup routine          */
+/*   changed  register_chrdev to  devfs_register_chrdev                 */
+/*   changed  unregister_chrdev to  devfs_unregister_chrdev             */
+/*   Changed various declarations from int to ssize_t or loff_t         */
+/* -------------------------------------------------------------------- */
+/*   Changed interruptible_sleep_on to sleep_on so the driver has       */
+/*           chance to finish the current transfer before application   */
+/*           quits when typing '^C'. Otherwise a write collision will   */
+/*           most likely occur.                                         */
+/*   Added   safe_flags(); cli; and restore_flags() according to        */
+/*           gerg@snapgear.com. Otherwise in some cases (higher clock   */
+/*           rates) the transfer is finished before the current process */
+/*           is put to sleep and therefore never wakes up again.        */
+/*           09/12/2002 richard@opentcp.org                             */
+/* -------------------------------------------------------------------- */
+/*   02/06/2003 josef.baumgartner@telex.de                              */
+/*                                                                      */
+/*   Renamed cleanup_module() to qspi_exit() to be able to              */
+/*     compile as module.                                               */
+/*   Removed init_module() because module_init(qspi_init) does all      */
+/*     we need.                                                         */
+/*   Changed                                                            */
+/*     SPI register settings will be saved for each instance to be able */
+/*     to use different communication settings for different tasks.     */
+/*     An ioctl() does not longer write directly to the SPI registers.  */
+/*     It saves the settings which will be copied into the SPI          */
+/*     registers on every read()/write().                               */
+/*   Added MODULE_LICENSE("GPL") to avoid tainted kernel message.       */
+/*     I think it is GPL?? There's no comment about this??              */
+/*   Added polling mode                                                 */
+/*     Increases performance for small data transfers.                  */
+/*   Added odd mode                                                     */
+/*     If an odd number of bytes is transfered and 16bit transfers are  */
+/*     used, the last byte is transfered in byte mode.                  */
+/*   Added dsp mode                                                     */
+/*     If dsp mode is set, transfers will be limited to 15 bytes        */
+/*     instead of 16. This ensures that DSPs with 24bit words get       */
+/*     whole words within one transfer.                                 */
+/* -------------------------------------------------------------------- */
+/*   16/09/2003 ivan.zanin@bluewin.ch                                   */
+/*                                                                      */
+/*   Changed init and exit code to support the MCF5249                  */
+/* -------------------------------------------------------------------- */
+/*   Oct 19, 2004 jsujjavanich@syntech-fuelmaster.com                   */
+/*                                                                      */
+/*   Adjusted minor number detection to work with one dev per QSPI_CS   */
+/* -------------------------------------------------------------------- */
+/*   17/11/2004 chris_jones_oz@yahoo.com.au                             */
+/*                                                                      */
+/*   Changed init and exit code to support the MCF5282                  */
+/* -------------------------------------------------------------------- */
+/************************************************************************/
+
+/* **********************************************************************
+Chapter 14. (excerpt) Queued Serial Peripheral Interface (QSPI) Module
+   From:  http://e-www.motorola.com/brdata/PDFDB/docs/MCF5272UM.pdf
+
+The following steps are necessary to set up the QSPI 12-bit data transfers
+and a QSPI_CLK of 4.125 MHz. The QSPI RAM is set up for a queue of 16
+transfers. All four QSPI_CS signals are used in this example.
+
+1. Enable all QSPI_CS pins on the MCF5272. Write PACNT with 0x0080_4000 to
+enable QSPI_CS1 and QSPI_CS3.Write PDCNT with 0x0000_0030 to enable QSPI_CS2.
+
+2. Write the QMR with 0xB308 to set up 12-bit data words with the data
+shifted on the falling clock edge, and a clock frequency of 4.125 MHz
+(assuming a 66-MHz CLKIN).
+
+3. Write QDLYR with the desired delays.
+
+4. Write QIR with 0xD00F to enable write collision, abort bus errors, and
+clear any interrupts.
+
+5. Write QAR with 0x0020 to select the first command RAM entry.
+
+6. Write QDR with 0x7E00, 0x7E00, 0x7E00, 0x7E00, 0x7D00, 0x7D00, 0x7D00,
+0x7D00, 0x7B00, 0x7B00, 0x7B00, 0x7B00, 0x7700, 0x7700, 0x7700, and 0x7700
+to set up four transfers for each chip select. The chip selects are active
+low in this example.  NOTE: QDR value auto-increments after each write.
+
+7. Write QAR with 0x0000 to select the first transmit RAM entry.
+
+8. Write QDR with sixteen 12-bit words of data.
+
+9. Write QWR with 0x0F00 to set up a queue beginning at entry 0 and ending
+at entry 15.
+
+10. Set QDLYR[SPE] to enable the transfers.
+
+11.Wait until the transfers are complete. QIR[SPIF] is set when the
+transfers are complete.
+
+12. Write QAR with 0x0010 to select the first receive RAM entry.
+
+13. Read QDR to get the received data for each transfer.  NOTE: QDR
+auto-increments.
+
+14. Repeat steps 5 through 13 to do another transfer.
+
+************************************************************************* */
+#include <asm/coldfire.h>               /* gets us MCF_MBAR value */
+#include <asm/mcfsim.h>                 /* MCFSIM offsets */
+#include <asm/semaphore.h>
+#include <asm/system.h>                 /* cli() and friends */
+#include <asm/uaccess.h>
+#include <linux/config.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/wait.h>
+
+/* Include versioning info, if needed */
+#if (defined(MODULE) && defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS))
+#define MODVERSIONS
+#endif
+
+#if defined(MODVERSIONS)
+#include <linux/modversions.h>
+#endif
+
+#include "mcf_qspi.h"
+
+
+
+
+#define DEVICE_NAME "qspi"
+
+int __init qspi_init(void);
+static int init(void);
+void __exit qspi_exit(void);
+
+
+/* struct wait_queue *wqueue; */
+static DECLARE_WAIT_QUEUE_HEAD(wqueue);   /* use ver 2.4 static declaration - ron */
+/* or should we use   wait_queue_heat_t *wqueue   ?? see page 141  */
+
+static unsigned char dbuf[1024];
+
+/*  static struct semaphore sem = MUTEX;   */
+
+
+#if LINUX_VERSION_CODE < 0x020100
+static struct semaphore sem = MUTEX;
+#else
+static DECLARE_MUTEX(sem);
+#endif
+
+
+static void qspi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+        u16 qir = (QIR & (QIR_WCEF | QIR_ABRT | QIR_SPIF));
+
+        /* Check write collision and transfer abort flags.  Report any
+         * goofiness. */
+        if (qir & QIR_WCEF)
+                printk(KERN_INFO "%s: WCEF\n", __FILE__);
+
+        if (qir & QIR_ABRT)
+                printk(KERN_INFO "%s: ABRT\n", __FILE__);
+
+        /* Check for completed transfer.  Wake any tasks sleeping on our
+         * global wait queue. */
+        if (qir & QIR_SPIF)
+                wake_up(&wqueue);
+
+        /* Clear any set flags. */
+        QIR |= qir;
+}
+
+
+static int qspi_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+                unsigned long arg)
+{
+        int ret = 0;
+        struct qspi_dev *dev = filp->private_data;
+        struct qspi_read_data *read_data;
+        int error;
+
+        down(&sem);
+
+        switch (cmd) {
+                /* Set QMR[DOHIE] (high-z Dout between transfers) */
+                case QSPIIOCS_DOUT_HIZ:
+                        dev->dohie = (arg ? 1 : 0);
+                        break;
+
+                /* Set QMR[BITS] */
+                case QSPIIOCS_BITS:
+                        if (((arg > 0) && (arg < 8)) || (arg > 16)) {
+                                ret = -EINVAL;
+                                break;
+                        }
+
+                        dev->bits = (u8)arg;
+                        break;
+
+                /* Get QMR[BITS] */
+                case QSPIIOCG_BITS:
+                        *((int *)arg) = dev->bits;
+                        break;
+
+                /* Set QMR[CPOL] (QSPI_CLK inactive state) */
+                case QSPIIOCS_CPOL:
+                        dev->cpol = (arg ? 1 : 0);
+                        break;
+
+                /* Set QMR[CPHA] (QSPI_CLK phase, 1 = rising edge) */
+                case QSPIIOCS_CPHA:
+                        dev->cpha = (arg ? 1 : 0);
+                        break;
+
+                /* Set QMR[BAUD] (QSPI_CLK baud rate divisor) */
+                case QSPIIOCS_BAUD:
+                        if (arg > 255) {
+                                ret = -EINVAL;
+                                break;
+                        }
+
+                        dev->baud = (u8)arg;
+                        break;
+
+                /* Set QDR[QCD] (QSPI_CS to QSPI_CLK setup) */
+                case QSPIIOCS_QCD:
+                        if (arg > 127) {
+                                ret = -EINVAL;
+                                break;
+                        }
+
+                        dev->qcd = (u8)arg;
+                        break;
+
+                /* Set QDR[DTL] (QSPI_CLK to QSPI_CS hold) */
+                case QSPIIOCS_DTL:
+                        if (arg > 255) {
+                                ret = -EINVAL;
+                                break;
+                        }
+
+                        dev->dtl = (u8)arg;
+                        break;
+
+                /* Set QCRn[CONT] (QSPI_CS continuous mode, 1 = remain
+                 * asserted after transfer of 16 data words) */
+                case QSPIIOCS_CONT:
+                        dev->qcr_cont = (arg ? 1 : 0);
+                        break;
+
+                /* Set DSP mode, used to limit transfers to 15 bytes for
+                 * 24-bit DSPs */
+                case QSPIIOCS_DSP_MOD:
+                        dev->dsp_mod  = (arg ? 1 : 0);
+                        break;
+
+                /* If an odd count of bytes is transferred, force the transfer
+                 * of the last byte to byte mode, even if word mode is used */
+                case QSPIIOCS_ODD_MOD:
+                        dev->odd_mod = (arg ? 1 : 0);
+                        break;
+
+                /* Set data buffer to be used as "send data" during reads */
+                case QSPIIOCS_READDATA:
+                        read_data = (struct qspi_read_data *)arg;
+                        error = verify_area(VERIFY_READ, read_data,
+                                        sizeof(struct qspi_read_data));
+                        if (error) {
+                                ret = error;
+                                break;
+                        }
+
+                        if (read_data->length > sizeof(read_data->buf)) {
+                                ret = -EINVAL;
+                                break;
+                        }
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+                        memcpy_fromfs(&dev->read_data, read_data,
+                                        sizeof(struct qspi_read_data));
+#else
+                        copy_from_user(&dev->read_data, read_data,
+                                        sizeof(struct qspi_read_data));
+#endif
+                        break;
+
+                /* Set driver to use polling mode, which may increase
+                 * performance for small transfers */
+                case QSPIIOCS_POLL_MOD:
+                        dev->poll_mod = (arg ? 1 : 0);
+                        break;
+
+                default:
+                        ret = -EINVAL;
+                        break;
+        }
+
+        up(&sem);
+        return(ret);
+}
+
+
+static int qspi_open(struct inode *inode, struct file *file)
+{
+        qspi_dev *dev;
+
+/*    #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+        MOD_INC_USE_COUNT;
+   #endif   */
+
+        if ((dev = kmalloc(sizeof(qspi_dev), GFP_KERNEL)) == NULL) {
+  /*  #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+                MOD_DEC_USE_COUNT;
+        #endif  */
+                return(-ENOMEM);
+        }
+
+        /* set default values */
+        dev->read_data.length = 0;
+        dev->read_data.buf[0] = 0;
+        dev->read_data.buf[1] = 0;
+        dev->read_data.loop = 0;
+        dev->poll_mod = 0;              /* interrupt mode */
+        dev->bits = 8;
+        dev->cpol = 0;
+        dev->cpha = 0;
+        dev->qcr_cont = 1;
+        dev->dsp_mod = 0;               /* no DSP mode */
+        dev->odd_mod = 0;               /* no ODD mode */
+        dev->qcd = 17;
+        dev->dtl = 1;
+
+        file->private_data = dev;
+
+        return(0);
+}
+
+
+static int qspi_release(struct inode *inode, struct file *file)
+{
+        kfree(file->private_data);
+
+/*  #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+        MOD_DEC_USE_COUNT;
+        #endif    */
+
+        return(0);
+}
+
+
+//   basic 2.4 kernel function format
+// ssize_t qspi_read(struct file* w12f, char * w12c, size_t w12d, loff_t * w12e) { ; }
+
+
+static ssize_t qspi_read(struct file *filep, char *buffer, size_t length,
+                loff_t *off)
+/******** older 2.0 kernel format **********
+static int qspi_read(
+        struct inode *inode,
+        struct file *filep,
+        char *buffer,
+        int length)
+********************************************/
+{
+        int qcr_cs;
+        int total = 0;
+        int i = 0;
+        int max_trans;
+        unsigned char bits;
+        unsigned char word = 0;
+        unsigned long flag;
+        qspi_dev *dev;
+        int rdi = 0;
+
+        down(&sem);
+
+        dev = filep->private_data;
+
+        /* set the register with default values */
+        QMR = QMR_MSTR |
+                (dev->dohie << 14) |
+                (dev->bits << 10) |
+                (dev->cpol << 9) |
+                (dev->cpha << 8) |
+                (dev->baud);
+
+        QDLYR = (dev->qcd << 8) | dev->dtl;
+
+        if (dev->dsp_mod)
+                max_trans = 15;
+        else
+                max_trans = 16;
+
+	qcr_cs = (~MINOR(filep->f_dentry->d_inode->i_rdev) << 8) & 0xf00;  /* CS for QCR */
+
+        bits = dev->bits % 0x10;
+        if (bits == 0 || bits > 0x08)
+                word = 1; /* 9 to 16bit transfers */
+
+//              printk("\n READ driver -- ioctl xmit data fm dev->read_data.buf array  %x %x %x %x \n",dev->read_data.buf[0],dev->read_data.buf[1],dev->read_data.buf[2],dev->read_data.buf[3]);
+
+        while (i < length) {
+                unsigned short *sp = (unsigned short *)&buffer[i];
+                unsigned char *cp = &buffer[i];
+                unsigned short *rd_sp = (unsigned short *)dev->read_data.buf;
+                int x;
+                int n;
+
+                QAR = TX_RAM_START;             /* address first QTR */
+                for (n = 0; n < max_trans; n++) {
+                        if (rdi != -1) {
+                                if (word) {
+                                        QDR = rd_sp[rdi++];
+                                        if (rdi == dev->read_data.length >> 1)
+                                                rdi = dev->read_data.loop ? 0 : -1;
+                                } else {
+                                        QDR = dev->read_data.buf[rdi++];
+                                        if (rdi == dev->read_data.length)
+                                                rdi = dev->read_data.loop ? 0 : -1;
+                                }
+                        } else
+                                QDR = 0;
+
+                        i++;
+                        if (word)
+                                i++;
+                        if (i > length)
+                                break;
+                }
+
+                QAR = COMMAND_RAM_START;        /* address first QCR */
+                for (x = 0; x < n; x++) {
+                        /* QCR write */
+                        if (dev->qcr_cont) {
+                                if (x == n - 1 && i == length)
+                                        QDR = QCR_SETUP | qcr_cs;       /* last transfer */
+                                else
+                                        QDR = QCR_CONT | QCR_SETUP | qcr_cs;
+                        } else
+                                QDR = QCR_SETUP | qcr_cs;
+                }
+
+                QWR = QWR_CSIV | ((n - 1) << 8);
+
+                /* check if we are using polling mode. Polling increases
+                 * performance for samll data transfers but is dangerous
+                 * if we stay too long here, locking other tasks!!
+                 */
+                if (dev->poll_mod) {
+                        QIR = QIR_SETUP_POLL;
+                        QDLYR |= QDLYR_SPE;
+
+                        while ((QIR & QIR_SPIF) != QIR_SPIF)
+                                ;
+                        QIR = QIR | QIR_SPIF;
+                } else {
+                        QIR = QIR_SETUP;
+                        save_flags(flag); cli();                // like in write function
+
+                        QDLYR |= QDLYR_SPE;
+//                      interruptible_sleep_on(&wqueue);
+                        sleep_on(&wqueue);                      // changed richard@opentcp.org
+                        restore_flags(flag);                    // like in write function
+
+                }
+
+                QAR = RX_RAM_START;     /* address: first QRR */
+                if (word) {
+                        /* 9 to 16bit transfers */
+                        for (x = 0; x < n; x++) {
+                               put_user(*(volatile unsigned short *)(MCF_MBAR + MCFSIM_QDR), sp++);
+                        }
+                } else {
+                        /* 8bit transfers */
+                        for (x = 0; x < n; x++)
+                                put_user(*(volatile unsigned short *)(MCF_MBAR + MCFSIM_QDR), cp++);
+                }
+
+                if (word)
+                        n <<= 1;
+
+                total += n;
+        }
+
+        up(&sem);
+        return(total);
+}
+
+
+
+static ssize_t qspi_write(struct file *filep, const char *buffer, size_t length,
+                loff_t *off)
+{
+        int qcr_cs;
+        int i = 0;
+        int total = 0;
+        int z;
+        int max_trans;
+        unsigned char bits;
+        unsigned char word = 0;
+        unsigned long flag;
+        qspi_dev *dev;
+
+        down(&sem);
+
+        dev = filep->private_data;
+
+        QMR = QMR_MSTR |
+                (dev->dohie << 14) |
+                (dev->bits << 10) |
+                (dev->cpol << 9) |
+                (dev->cpha << 8) |
+                (dev->baud);
+
+        QDLYR = (dev->qcd << 8) | dev->dtl;
+
+        bits = (QMR >> 10) % 0x10;
+        if (bits == 0 || bits > 0x08)
+                word = 1;       /* 9 to 16 bit transfers */
+
+	qcr_cs = (~MINOR(filep->f_dentry->d_inode->i_rdev) << 8) & 0xf00;  /* CS for QCR */
+                                  /* next line was memcpy_fromfs()  */
+        copy_from_user (dbuf, buffer, length);
+
+//      printk("data to write is %x  %x  %x  %X  \n",dbuf[0],dbuf[1],dbuf[2],dbuf[3]);
+
+        if (dev->odd_mod)
+                z = QCR_SETUP8;
+        else
+                z = QCR_SETUP;
+
+        if (dev->dsp_mod)
+                max_trans = 15;
+        else
+                max_trans = 16;
+
+        while (i < length) {
+                int x;
+                int n;
+
+                QAR = TX_RAM_START;             /* address: first QTR */
+                if (word) {
+                        for (n = 0; n < max_trans; ) {
+                                /* in odd mode last byte will be transfered in byte mode */
+                                if (dev->odd_mod && (i + 1 == length)) {
+                                        QDR = dbuf[i];  /* tx data: QDR write */
+                                        // printk("0x%X ", dbuf[i]);
+                                        n++;
+                                        i++;
+                                        break;
+                                }
+                                else {
+                                        QDR = (dbuf[i] << 8) + dbuf[i+1]; /* tx data: QDR write */
+                                        //printk("0x%X 0x%X ", dbuf[i], dbuf[i+1]);
+                                        n++;
+                                        i += 2;
+                                        if (i >= length)
+                                                break;
+                                }
+                        }
+                } else {
+                        /* 8bit transfers */
+                        for (n = 0; n < max_trans; ) {
+                                QDR = dbuf[i];  /* tx data: QTR write */
+                                n++;
+                                i++;
+                                if (i == length)
+                                        break;
+                        }
+                }
+
+                QAR = COMMAND_RAM_START;        /* address: first QCR */
+                for (x = 0; x < n; x++) {
+                        /* QCR write */
+                        if (dev->qcr_cont) {
+                                if (x == n-1 && i == length)
+                                        if ((i % 2)!= 0)
+                                                QDR = z | qcr_cs; /* last transfer and odd number of chars */
+                                        else
+                                                QDR = QCR_SETUP | qcr_cs;       /* last transfer */
+                                else
+                                        QDR = QCR_CONT | QCR_SETUP | qcr_cs;
+                        } else {
+                                if (x == n - 1 && i == length)
+                                        QDR = z | qcr_cs; /* last transfer */
+                                else
+                                        QDR = QCR_SETUP | qcr_cs;
+                        }
+                }
+
+                QWR = QWR_CSIV | ((n - 1) << 8);  /* QWR[ENDQP] = n << 8 */
+
+                /* check if we are using polling mode. Polling increases
+                 * performance for samll data transfers but is dangerous
+                 * if we stay too long here, locking other tasks!!
+                 */
+                if (dev->poll_mod) {
+                        QIR = QIR_SETUP_POLL;
+                        QDLYR |= QDLYR_SPE;
+
+                        while ((QIR & QIR_SPIF) != QIR_SPIF)
+                                ;
+                        QIR = QIR | QIR_SPIF;
+                } else {
+                        QIR = QIR_SETUP;
+                        save_flags(flag); cli();                // added according to gerg@snapgear.com
+                        QDLYR |= QDLYR_SPE;
+
+//                      interruptible_sleep_on(&wqueue);
+                        sleep_on(&wqueue);                      // changed richard@opentcp.org
+
+                        restore_flags(flag);                    // added according to gerg@snapgear.com
+                }
+
+
+                if (word)
+                        n <<= 1;
+
+                total += n;
+        }
+
+        up(&sem);
+        return(total);
+}
+
+
+/*  fixed for 2.4 kernel, owner was ifdef'ed out for 2.0 kernel */
+static struct file_operations Fops = {
+        owner:          THIS_MODULE,
+        read:           qspi_read,
+        write:          qspi_write,
+        ioctl:          qspi_ioctl,
+        open:           qspi_open,
+        release:        qspi_release  /* a.k.a. close */
+};
+
+
+static int init(void)
+{
+        volatile u32 *lp;
+        volatile u8 *cp;
+
+        /* common init: driver or module: */
+
+        if (request_irq(MCFQSPI_IRQ_VECTOR, qspi_interrupt, SA_INTERRUPT, "ColdFire QSPI", NULL)) {
+                printk("QSPI: Unable to attach ColdFire QSPI interrupt "
+                        "vector=%d\n", MCFQSPI_IRQ_VECTOR);
+                return(-EINVAL);
+        }
+
+#if defined(CONFIG_M5249)
+        cp = (volatile u8 *)(MCF_MBAR + MCFSIM_ICR10);
+        *cp = 0x8f;             /* autovector on, il=3, ip=3 */
+
+        lp = (volatile u32 *)(MCF_MBAR2 + 0x180);
+        *lp |= 0x00000800;      /* activate qspi_in and qspi_clk */
+
+        lp = (volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIOFUNC);
+        *lp &= 0xdc9FFFFF;      /* activate qspi_cs0 .. 3, qspi_dout */
+
+        lp = (volatile u32 *)(MCF_MBAR + MCFSIM_IMR);
+        *lp &= 0xFFFbFFFF;      /* enable qspi interrupt */
+#elif defined(CONFIG_M5235)
+	// interrupts mask here
+	{
+	 volatile unsigned char  *icrp;
+	 icrp = (volatile unsigned char *)(MCF_MBAR + MCF5235ICM_INTC0 + MCFINTC0_ICR);
+	 icrp[IRQ_SOURCE] = (( 3/*IL*/ & 0x3 ) << 3 ) | (3 /*IP*/ & 0x3);
+	}
+	{
+	 volatile unsigned int *imrl;
+	 imrl = (volatile unsigned int *)(MCF_MBAR + MCF5235ICM_INTC0 + MCF5235INTC_IMRL);
+	 *imrl &= ~(1 << IRQ_SOURCE);
+	}
+	// GPIO here
+	{
+		volatile unsigned char *parp;
+		parp = (volatile unsigned char *)(MCF_MBAR + 0x10004A);
+		*parp = 0xFF;
+	}
+#elif (defined(CONFIG_M5282) || defined(CONFIG_M5280))
+        cp = (volatile u8 *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 +
+                              MCFINT_QSPI);
+        *cp = (5 << 3) + 3;     /* level 5, priority 3 */
+
+        cp = (volatile u8 *) (MCF_IPSBAR + MCF5282_GPIO_PQSPAR);
+        *cp = 0x7f;             /* activate din, dout, clk and cs[0..3] */
+
+        lp = (volatile u32 *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
+        *lp &= ~(1 + (1 << MCFINT_QSPI));      /* enable qspi interrupt */
+#else
+        /* set our IPL */
+        lp = (volatile u32 *)(MCF_MBAR + MCFSIM_ICR4);
+        *lp = (*lp & 0x07777777) | 0xd0000000;
+
+        /* 1) CS pin setup 17.2.x
+         *      Dout, clk, cs0 always enabled. Din, cs[3:1] must be enabled.
+         *      CS1: PACNT[23:22] = 10
+         *      CS1: PBCNT[23:22] = 10 ?
+         *      CS2: PDCNT[05:04] = 11
+         *      CS3: PACNT[15:14] = 01
+         */
+        lp = (volatile u32 *)(MCF_MBAR + MCFSIM_PACNT);
+        *lp = (*lp & 0xFF3F3FFF) | 0x00804000;  /* 17.2.1 QSPI CS1 & CS3 */
+        lp = (volatile u32 *)(MCF_MBAR + MCFSIM_PDCNT);
+        *lp = (*lp & 0xFFFFFFCF) | 0x00000030;  /* QSPI_CS2 */
+#endif
+
+        /*
+         * These values have to be setup according to the applications
+         * using the qspi driver. Maybe some #defines at the beginning
+         * would be more appropriate. Especially the transfer size
+         * and speed settings
+         */
+        QMR = 0xA1A2; // default mode setup: 8 bits, baud, 160kHz clk.
+//      QMR = 0x81A2; // default mode setup: 16 bits, baud, 160kHz clk.
+        QDLYR = 0x0202; // default start & end delays
+
+        init_waitqueue_head(&wqueue);    /* was init_waitqueue() --Ron */
+
+#if defined(CONFIG_M5249)
+        printk("MCF5249 QSPI driver ok\n");
+#elif defined(CONFIG_M5235)
+	printk("MCF5235 QSPI driver ok\n");
+#elif (defined(CONFIG_M5282) || defined(CONFIG_M5280))
+        printk("MCF5282 QSPI driver ok\n");
+#else
+        printk("MCF5272 QSPI driver ok\n");
+#endif
+
+        return(0);
+}
+
+
+/* init for compiled-in driver: call from mem.c */
+int __init qspi_init(void)                                  /* the __init added by ron  */
+{
+        int ret;
+
+        if ((ret = devfs_register_chrdev(QSPI_MAJOR, DEVICE_NAME, &Fops) < 0)) {
+                printk ("%s device failed with %d\n",
+                        "Sorry, registering the character", ret);
+                return(ret);
+        }
+
+        printk ("QSPI device driver installed OK\n");
+        return(init());
+}
+
+/* Cleanup - undid whatever init_module did */
+void __exit qspi_exit(void)      /* the __exit added by ron  */
+{
+        int ret;
+
+        free_irq(MCFQSPI_IRQ_VECTOR, NULL);
+
+#if defined(CONFIG_M5249)
+        /* autovector on, il=0, ip=0 */
+        *(volatile u8 *)(MCF_MBAR + MCFSIM_ICR10) = 0x80;
+        /* disable qspi interrupt */
+        *(volatile u32 *)(MCF_MBAR + MCFSIM_IMR) |= 0x00040000;
+#elif defined(CONFIG_M5235)
+	{
+	 volatile unsigned char  *icrp;
+	 icrp = (volatile unsigned char *)(MCF_MBAR + MCF5235ICM_INTC0 + MCFINTC0_ICR);
+	 icrp[IRQ_SOURCE] = 0;
+	}
+	// GPIO here
+	{
+		volatile unsigned char *parp;
+		parp = (volatile unsigned char *)(MCF_MBAR + 0x10004A);
+		*parp = 0x00;
+	}
+#elif (defined(CONFIG_M5282) || defined(CONFIG_M5280))
+        /* interrupt level 0, priority 0 */
+        *(volatile u8 *) (MCF_IPSBAR + MCFICM_INTC0 +
+                          MCFINTC_ICR0 + MCFINT_QSPI) = 0;
+        /* disable qspi interrupt */
+        *(volatile u32 *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)
+                                                        |= (1 << MCFINT_QSPI);
+#else
+        /* zero our IPL */
+        *((volatile u32 *)(MCF_MBAR + MCFSIM_ICR4)) = 0x80000000;
+#endif
+
+        /* Unregister the device */
+        if ((ret = devfs_unregister_chrdev(QSPI_MAJOR, DEVICE_NAME)) < 0)
+                printk("Error in unregister_chrdev: %d\n", ret);
+}
+
+
+module_init(qspi_init);      /* added by ron so driver can compile directly into kernel */
+module_exit(qspi_exit);      /* added by ron so driver can compile directly into kernel */
+
+MODULE_LICENSE("GPL");
+
diff -urN linux-2.4.29/drivers/char/mcf_qspi.h linux-2.4.29-uc1/drivers/char/mcf_qspi.h
--- linux-2.4.29/drivers/char/mcf_qspi.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/mcf_qspi.h	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,94 @@
+#if !defined(MCF_QSPI_H)
+#define MCF_QSPI_H
+
+#include <asm/mcfqspi.h>
+#include <linux/types.h>
+
+
+#define QSPI_MAJOR              126
+#if defined(CONFIG_M5249)
+#define MCFQSPI_IRQ_VECTOR      27
+#define QSPIMOD_OFFSET          0x400
+#elif defined(CONFIG_M5235)
+#define MCF5235ICM_INTC0	0xC00
+#define MCFINTC0_ICR		0x40
+#define MCFQSPI_IRQ_VECTOR  82
+#define QSPIMOD_OFFSET      0x340
+#define IRQ_SOURCE			18
+#define MCF5235INTC_IMRL	0x0C
+#elif (defined(CONFIG_M5282) || defined(CONFIG_M5280))
+#define MCFQSPI_IRQ_VECTOR      (64 + 18)
+#define QSPIMOD_OFFSET          0x340
+#else
+#define MCFQSPI_IRQ_VECTOR      89
+#define QSPIMOD_OFFSET          0xa0
+#endif
+
+
+/* QSPI registers */
+#define MCFSIM_QMR              (0x00 + QSPIMOD_OFFSET) /* mode */
+#define MCFSIM_QDLYR            (0x04 + QSPIMOD_OFFSET) /* delay */
+#define MCFSIM_QWR              (0x08 + QSPIMOD_OFFSET) /* wrap */
+#define MCFSIM_QIR              (0x0c + QSPIMOD_OFFSET) /* interrupt */
+#define MCFSIM_QAR              (0x10 + QSPIMOD_OFFSET) /* address */
+#define MCFSIM_QDR              (0x14 + QSPIMOD_OFFSET) /* address */
+
+#define TX_RAM_START            0x00
+#define RX_RAM_START            0x10
+#define COMMAND_RAM_START       0x20
+
+#define QMR                     *(volatile u16 *)(MCF_MBAR + MCFSIM_QMR)
+#define QAR                     *(volatile u16 *)(MCF_MBAR + MCFSIM_QAR)
+#define QDR                     *(volatile u16 *)(MCF_MBAR + MCFSIM_QDR)
+#define QWR                     *(volatile u16 *)(MCF_MBAR + MCFSIM_QWR)
+#define QDLYR                   *(volatile u16 *)(MCF_MBAR + MCFSIM_QDLYR)
+#define QIR                     *(volatile u16 *)(MCF_MBAR + MCFSIM_QIR)
+
+
+/* bits */
+#define QMR_MSTR                0x8000  /* master mode enable: must always be set */
+#define QMR_DOHIE               0x4000  /* shut off (hi-z) Dout between transfers */
+#define QMR_BITS                0x3c00  /* bits per transfer (size) */
+#define QMR_CPOL                0x0200  /* clock state when inactive */
+#define QMR_CPHA                0x0100  /* clock phase: 1 = data taken at rising edge */
+#define QMR_BAUD                0x00ff  /* clock rate divider */
+
+#define QIR_WCEF                0x0008  /* write collison */
+#define QIR_ABRT                0x0004  /* abort */
+#define QIR_SPIF                0x0001  /* finished */
+#define QIR_SETUP               0xdd0f  /* setup QIR for tranfer start */
+#define QIR_SETUP_POLL          0xdc0d  /* setup QIR for tranfer start */
+
+#define QWR_CSIV                0x1000  /* 1 = active low chip selects */
+
+#define QDLYR_SPE               0x8000  /* initiates transfer when set */
+#define QDLYR_QCD               0x7f00  /* start delay between CS and first clock */
+#define QDLYR_DTL               0x00ff  /* delay after CS release */
+
+/* QCR: chip selects return to inactive, bits set in QMR[BITS],
+ * after delay set in QDLYR[DTL], pre-delay set in QDLYR[QCD] */
+#define QCR_SETUP               0x7000
+#define QCR_CONT                0x8000  /* 1=continuous CS after transfer */
+#define QCR_SETUP8              0x3000  /* sets BITSE to 0 => eigth bits per transfer */
+
+
+typedef struct qspi_dev {
+        qspi_read_data read_data;
+        u8 bits;                        /* transfer size, number of bits to transfer for each entry */
+        u8 baud;                        /* baud rate */
+        u8 qcd;                         /* QSPILCK delay */
+        u8 dtl;                         /* delay after transfer */
+        unsigned int qcr_cont   : 1;    /* keep CS active throughout transfer */
+        unsigned int odd_mod    : 1;    /* if length of buffer is a odd number, 16-bit transfers
+                                           are finalized with a 8-bit transfer */
+        unsigned int dsp_mod    : 1;    /* transfers are bounded to 15/30 bytes
+                                           (= a multiple of 3 bytes = 1 word) */
+        unsigned int poll_mod   : 1;    /* mode polling or interrupt */
+        unsigned int cpol       : 1;    /* SPI clock polarity */
+        unsigned int cpha       : 1;    /* SPI clock phase */
+        unsigned int dohie      : 1;    /* data output high impedance enable */
+} qspi_dev;
+
+
+#endif  /* MCF_QSPI_H */
+
diff -urN linux-2.4.29/drivers/char/mcfserial.c linux-2.4.29-uc1/drivers/char/mcfserial.c
--- linux-2.4.29/drivers/char/mcfserial.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/mcfserial.c	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,2271 @@
+/*
+ * mcfserial.c -- serial driver for ColdFire internal UARTS.
+ *
+ * Copyright (c) 1999-2004 Greg Ungerer <gerg@snapgear.com>
+ * Copyright (C) 2001-2003 SnapGear Inc. <www.snapgear.com> 
+ * Copyright (c) 2000-2001 Lineo, Inc. <www.lineo.com> 
+ *
+ * Based on code from 68332serial.c which was:
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1998 TSHG
+ * Copyright (c) 1999 Rt-Control Inc. <jeff@uclinux.org>
+ */
+ 
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/wait.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/config.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#ifdef CONFIG_LEDMAN
+#include <linux/ledman.h>
+#endif
+#include <linux/console.h>
+#include <linux/version.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/semaphore.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfuart.h>
+#include <asm/nettel.h>
+#include <asm/nap.h>
+#include <asm/se1100.h>
+
+#if LINUX_VERSION_CODE < 0x020100
+#define queue_task_irq_off queue_task
+#define copy_from_user(a,b,c) memcpy_fromfs(a,b,c)
+#define copy_to_user(a,b,c) memcpy_tofs(a,b,c)
+#else
+#include <asm/uaccess.h>
+#endif
+
+#include "mcfserial.h"
+
+/*
+ *	the only event we use
+ */
+#undef RS_EVENT_WRITE_WAKEUP
+#define RS_EVENT_WRITE_WAKEUP 0
+#undef RS_EVENT_READ_WAKEUP
+#define RS_EVENT_READ_WAKEUP 1
+
+#if LINUX_VERSION_CODE >= 0x020100
+struct timer_list mcfrs_timer_struct;
+#endif
+
+/*
+ *	Default console baud rate,  we use this as the default
+ *	for all ports so init can just open /dev/console and
+ *	keep going.  Perhaps one day the cflag settings for the
+ *	console can be used instead.
+ */
+#if defined(CONFIG_ARNEWSH) || defined(CONFIG_MOTOROLA) || \
+    defined(CONFIG_COBRA5272) || defined(CONFIG_AVNET) || \
+    defined(CONFIG_COBRA5282) || defined(CONFIG_SNEHA)
+#define	CONSOLE_BAUD_RATE	19200
+#define	DEFAULT_CBAUD		B19200
+#endif
+
+#if defined(CONFIG_GILBARCONAP) || defined(CONFIG_DNP5280) || \
+    defined(CONFIG_SIGNAL_MCP751)
+#define	CONSOLE_BAUD_RATE	115200
+#define	DEFAULT_CBAUD		B115200
+#endif
+
+#if defined(CONFIG_HW_FEITH)
+#define	CONSOLE_BAUD_RATE	38400
+#define	DEFAULT_CBAUD		B38400
+#endif
+
+#ifndef CONSOLE_BAUD_RATE
+#define	CONSOLE_BAUD_RATE	9600
+#define	DEFAULT_CBAUD		B9600
+#endif
+
+int mcfrs_console_inited = 0;
+int mcfrs_console_port = -1;
+int mcfrs_console_baud = CONSOLE_BAUD_RATE;
+int mcfrs_console_cbaud = DEFAULT_CBAUD;
+
+DECLARE_TASK_QUEUE(mcf_tq_serial);
+
+/*
+ *	Driver data structures.
+ */
+struct tty_driver	mcfrs_serial_driver, mcfrs_callout_driver;
+static int		mcfrs_serial_refcount;
+
+/* serial subtype definitions */
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+  
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 128 
+
+/* Debugging...
+ */
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+
+#define _INLINE_ inline
+
+#if defined(CONFIG_M5235) || defined(CONFIG_M527x) || \
+    defined(CONFIG_M5282) || defined(CONFIG_M5280)
+#define	MCFRS_IRQ0	77
+#define	MCFRS_IRQ1	78
+#define	MCFRS_IRQ2	79
+#elif defined(CONFIG_M547x)
+#define	MCFRS_IRQ0	99
+#define	MCFRS_IRQ1	98
+#define	MCFRS_IRQ2	97
+#define	MCFRS_IRQ3	96
+#else
+#define	MCFRS_IRQ0	73
+#define	MCFRS_IRQ1	74
+#endif
+
+/*
+ *	Configuration table, UARTs to look for at startup.
+ */
+static struct mcf_serial mcfrs_table[] = {
+  { 0, (MCF_MBAR+MCFUART_BASE1), MCFRS_IRQ0, ASYNC_BOOT_AUTOCONF },  /* ttyS0 */
+  { 0, (MCF_MBAR+MCFUART_BASE2), MCFRS_IRQ1, ASYNC_BOOT_AUTOCONF },  /* ttyS1 */
+#ifdef MCFUART_BASE3
+  { 0, (MCF_MBAR+MCFUART_BASE3), MCFRS_IRQ2, ASYNC_BOOT_AUTOCONF },  /* ttyS2 */
+#endif
+#ifdef MCFUART_BASE4
+  { 0, (MCF_MBAR+MCFUART_BASE4), MCFRS_IRQ3, ASYNC_BOOT_AUTOCONF },  /* ttyS3 */
+#endif
+};
+
+
+#define	NR_PORTS	(sizeof(mcfrs_table) / sizeof(struct mcf_serial))
+
+static struct tty_struct	*mcfrs_serial_table[NR_PORTS];
+static struct termios		*mcfrs_serial_termios[NR_PORTS];
+static struct termios		*mcfrs_serial_termios_locked[NR_PORTS];
+
+/*
+ * This is used to figure out the divisor speeds and the timeouts.
+ */
+static int mcfrs_baud_table[] = {
+	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
+	9600, 19200, 38400, 57600, 115200, 230400, 460800, 500000, 576000,
+	921600, 1000000, 1152000, 1500000, 2000000, 2500000, 3000000,
+	3500000, 4000000, 0
+};
+#define MCFRS_BAUD_TABLE_SIZE \
+			(sizeof(mcfrs_baud_table)/sizeof(mcfrs_baud_table[0]))
+
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+#ifdef CONFIG_MAGIC_SYSRQ
+/*
+ *	Magic system request keys. Used for debugging...
+ */
+extern int	magic_sysrq_key(int ch);
+#endif
+
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the copy_from_user blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static unsigned char mcfrs_tmp_buf[4096]; /* This is cheating */
+#if LINUX_VERSION_CODE < 0x020100
+static struct semaphore mcfrs_tmp_buf_sem = MUTEX;
+#else
+static DECLARE_MUTEX(mcfrs_tmp_buf_sem);
+#endif
+
+/*
+ *	Forward declarations...
+ */
+static void	mcfrs_change_speed(struct mcf_serial *info);
+static void	mcfrs_wait_until_sent(struct tty_struct *tty, int timeout);
+
+
+static inline int serial_paranoia_check(struct mcf_serial *info,
+					dev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%d, %d) in %s\n";
+	static const char *badinfo =
+		"Warning: null mcf_serial for (%d, %d) in %s\n";
+
+	if (!info) {
+		printk(badinfo, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+	if (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+/*
+ *	Function stubs for boards that do not implement DCD and DTR.
+ */
+#if !defined(MCF_HAVEDCD0) && !defined(MCF_HAVEDCD1)
+static __inline__ unsigned int mcf_getppdcd(unsigned int portnr)
+{
+	return(0);
+}
+#endif
+
+#if !defined(MCF_HAVEDTR0) && !defined(MCF_HAVEDTR1)
+static __inline__ unsigned int mcf_getppdtr(unsigned int portnr)
+{
+	return(0);
+}
+static __inline__ void mcf_setppdtr(unsigned int portnr, unsigned int dtr)
+{
+}
+#endif
+
+/*
+ *	Sets or clears DTR and RTS on the requested line.
+ */
+static void mcfrs_setsignals(struct mcf_serial *info, int dtr, int rts)
+{
+	volatile unsigned char	*uartp;
+	unsigned long		flags;
+	
+#if 0
+	printk("%s(%d): mcfrs_setsignals(info=%x,dtr=%d,rts=%d)\n",
+		__FILE__, __LINE__, (int) info, dtr, rts);
+#endif
+
+	save_flags(flags); cli();
+	if (dtr >= 0)
+		mcf_setppdtr(info->line, dtr);
+	if (rts >= 0) {
+		uartp = (volatile unsigned char *) info->addr;
+		if (rts) {
+			info->sigs |= TIOCM_RTS;
+			uartp[MCFUART_UOP1] = MCFUART_UOP_RTS;
+		} else {
+			info->sigs &= ~TIOCM_RTS;
+			uartp[MCFUART_UOP0] = MCFUART_UOP_RTS;
+		}
+	}
+	restore_flags(flags);
+	return;
+}
+
+/*
+ *	Gets values of serial signals.
+ */
+static int mcfrs_getsignals(struct mcf_serial *info)
+{
+	volatile unsigned char	*uartp;
+	unsigned long		flags;
+	int			sigs;
+
+#if 0
+	printk("%s(%d): mcfrs_getsignals(info=%x)\n", __FILE__, __LINE__);
+#endif
+
+	uartp = (volatile unsigned char *) info->addr;
+	save_flags(flags); cli();
+	sigs = (uartp[MCFUART_UIPR] & MCFUART_UIPR_CTS) ? 0 : TIOCM_CTS;
+	sigs |= (info->sigs & TIOCM_RTS);
+	sigs |= (mcf_getppdcd(info->line) ? TIOCM_CD : 0);
+	sigs |= (mcf_getppdtr(info->line) ? TIOCM_DTR : 0);
+	restore_flags(flags);
+	return(sigs);
+}
+
+/*
+ * ------------------------------------------------------------
+ * mcfrs_stop() and mcfrs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void mcfrs_stop(struct tty_struct *tty)
+{
+	volatile unsigned char	*uartp;
+	struct mcf_serial	*info = (struct mcf_serial *)tty->driver_data;
+	unsigned long		flags;
+
+	if (serial_paranoia_check(info, tty->device, "mcfrs_stop"))
+		return;
+	
+	uartp = (volatile unsigned char *) info->addr;
+	save_flags(flags); cli();
+	info->imr &= ~MCFUART_UIR_TXREADY;
+	uartp[MCFUART_UIMR] = info->imr;
+	restore_flags(flags);
+}
+
+static void mcfrs_start(struct tty_struct *tty)
+{
+	volatile unsigned char	*uartp;
+	struct mcf_serial	*info = (struct mcf_serial *)tty->driver_data;
+	unsigned long		flags;
+	
+	if (serial_paranoia_check(info, tty->device, "mcfrs_start"))
+		return;
+
+	uartp = (volatile unsigned char *) info->addr;
+	save_flags(flags); cli();
+	if (info->xmit_cnt && info->xmit_buf) {
+		info->imr |= MCFUART_UIR_TXREADY;
+		uartp[MCFUART_UIMR] = info->imr;
+	}
+	restore_flags(flags);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * mcfrs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: mcfrs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * mcfrs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ * 
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assemble code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static _INLINE_ void mcfrs_sched_event(struct mcf_serial *info, int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &mcf_tq_serial);
+	mark_bh(CM206_BH);
+}
+
+static _INLINE_ void receive_chars(struct mcf_serial *info, 
+		volatile unsigned char *uartp)
+{
+	struct tty_struct	*tty = info->tty;
+	unsigned char		status, ch;
+
+	if (!tty)
+		return;
+
+#if defined(CONFIG_LEDMAN)
+	ledman_cmd(LEDMAN_CMD_SET, info->line ? LEDMAN_COM2_RX : LEDMAN_COM1_RX);
+#endif
+
+	while ((status = uartp[MCFUART_USR]) & MCFUART_USR_RXREADY) {
+
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			/*
+			 * can't take any more data.  Turn off receiver
+			 * so that the interrupt doesn't continually
+			 * occur.  We have to make sure we turn it
+			 * back on at some point though.
+			 */
+			info->imr &= ~MCFUART_UIR_RXREADY;
+			uartp[MCFUART_UIMR] = info->imr;
+			mcfrs_sched_event(info, RS_EVENT_READ_WAKEUP);
+			break;
+		}
+
+		ch = uartp[MCFUART_URB];
+		info->stats.rx++;
+
+#ifdef CONFIG_MAGIC_SYSRQ
+		if (mcfrs_console_inited && (info->line == mcfrs_console_port)) {
+			if (magic_sysrq_key(ch))
+				continue;
+		}
+#endif
+
+		tty->flip.count++;
+		if (status & MCFUART_USR_RXERR) {
+			uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR;
+			if (status & MCFUART_USR_RXBREAK) {
+				info->stats.rxbreak++;
+				*tty->flip.flag_buf_ptr++ = TTY_BREAK;
+			} else if (status & MCFUART_USR_RXPARITY) {
+				info->stats.rxparity++;
+				*tty->flip.flag_buf_ptr++ = TTY_PARITY;
+			} else if (status & MCFUART_USR_RXOVERRUN) {
+				info->stats.rxoverrun++;
+				*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+			} else if (status & MCFUART_USR_RXFRAMING) {
+				info->stats.rxframing++;
+				*tty->flip.flag_buf_ptr++ = TTY_FRAME;
+			}
+		} else {
+			*tty->flip.flag_buf_ptr++ = 0;
+		}
+		*tty->flip.char_buf_ptr++ = ch;
+	}
+
+	queue_task(&tty->flip.tqueue, &tq_timer);
+	return;
+}
+
+static _INLINE_ void transmit_chars(struct mcf_serial *info,
+		volatile unsigned char *uartp)
+{
+#if defined(CONFIG_LEDMAN)
+	ledman_cmd(LEDMAN_CMD_SET, info->line ? LEDMAN_COM2_TX : LEDMAN_COM1_TX);
+#endif
+
+	if (info->x_char) {
+		/* Send special char - probably flow control */
+		uartp[MCFUART_UTB] = info->x_char;
+		info->x_char = 0;
+		info->stats.tx++;
+	}
+
+	if ((info->xmit_cnt <= 0) || info->tty->stopped) {
+		info->imr &= ~MCFUART_UIR_TXREADY;
+		uartp[MCFUART_UIMR] = info->imr;
+		return;
+	}
+
+	while (uartp[MCFUART_USR] & MCFUART_USR_TXREADY) {
+		uartp[MCFUART_UTB] = info->xmit_buf[info->xmit_tail++];
+		info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+		info->stats.tx++;
+		if (--info->xmit_cnt <= 0)
+			break;
+	}
+
+	if (info->xmit_cnt < WAKEUP_CHARS)
+		mcfrs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+	return;
+}
+
+/*
+ * This is the serial driver's generic interrupt routine
+ */
+void mcfrs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct mcf_serial	*info;
+	unsigned char		isr;
+	volatile unsigned char  *uartp;
+
+ 	info = (struct mcf_serial *)dev_id;
+	uartp = (volatile unsigned char *) info->addr;
+
+	isr = uartp[MCFUART_UISR] & info->imr;
+
+	if (isr & MCFUART_UIR_RXREADY)
+		receive_chars(info, uartp);
+	if (isr & MCFUART_UIR_TXREADY)
+		transmit_chars(info, uartp);
+#if 0
+	if (isr & MCFUART_UIR_DELTABREAK) {
+		printk("%s(%d): delta break!\n", __FILE__, __LINE__);
+		receive_chars(info, regs, isr);
+	}
+#endif
+
+	return;
+}
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * mcfrs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using mcfrs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+	run_task_queue(&mcf_tq_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct mcf_serial	*info = (struct mcf_serial *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+	}
+
+	if (test_and_clear_bit(RS_EVENT_READ_WAKEUP, &info->event)) {
+		if ((info->imr & MCFUART_UIR_RXREADY) == 0) {
+			info->imr |= MCFUART_UIR_RXREADY;
+			((volatile unsigned char *) info->addr)[MCFUART_UIMR] = info->imr;
+		}
+	}
+}
+
+
+/*
+ *	Change of state on a DCD line.
+ */
+void mcfrs_modem_change(struct mcf_serial *info, int dcd)
+{
+	if (info->count == 0)
+		return;
+
+	if (info->flags & ASYNC_CHECK_CD) {
+		if (dcd) {
+			wake_up_interruptible(&info->open_wait);
+		} else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_CALLOUT_NOHUP))) {
+			schedule_task(&info->tqueue_hangup);
+		}
+	}
+}
+
+
+#if defined(MCF_HAVEDCD0) || defined(MCF_HAVEDCD1)
+
+unsigned int	mcfrs_olddcd0;
+unsigned int	mcfrs_olddcd1;
+
+/*
+ * This subroutine is called when the RS_TIMER goes off. It is used
+ * to monitor the state of the DCD lines - since they have no edge
+ * sensors and interrupt generators.
+ */
+#if LINUX_VERSION_CODE < 0x020100
+static void mcfrs_timer(void)
+#else
+static void mcfrs_timer(unsigned long arg)
+#endif
+{
+	unsigned int dcd;
+
+	dcd = mcf_getppdcd(0);
+	if (dcd != mcfrs_olddcd0)
+		mcfrs_modem_change(&mcfrs_table[0], dcd);
+	mcfrs_olddcd0 = dcd;
+
+	dcd = mcf_getppdcd(1);
+	if (dcd != mcfrs_olddcd1)
+		mcfrs_modem_change(&mcfrs_table[1], dcd);
+	mcfrs_olddcd1 = dcd;
+
+	/* Re-arm timer */
+#if LINUX_VERSION_CODE < 0x020100
+	timer_table[RS_TIMER].expires = jiffies + HZ/25;
+	timer_active |= 1 << RS_TIMER;
+#else
+	mcfrs_timer_struct.expires = jiffies + HZ/25;
+	add_timer(&mcfrs_timer_struct);
+#endif
+}
+
+#endif	/* MCF_HAVEDCD0 || MCF_HAVEDCD1 */
+
+
+/*
+ * This routine is called from the scheduler tqueue when the interrupt
+ * routine has signalled that a hangup has occurred.  The path of
+ * hangup processing is:
+ *
+ * 	serial interrupt routine -> (scheduler tqueue) ->
+ * 	do_serial_hangup() -> tty->hangup() -> mcfrs_hangup()
+ * 
+ */
+static void do_serial_hangup(void *private_)
+{
+	struct mcf_serial	*info = (struct mcf_serial *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	tty_hangup(tty);
+}
+
+static int startup(struct mcf_serial * info)
+{
+	volatile unsigned char	*uartp;
+	unsigned long		flags;
+	
+	if (info->flags & ASYNC_INITIALIZED)
+		return 0;
+
+	if (!info->xmit_buf) {
+		info->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL);
+		if (!info->xmit_buf)
+			return -ENOMEM;
+	}
+
+	save_flags(flags); cli();
+
+#if defined(MCF_HAVEDCD0) || defined(MCF_HAVEDCD1)
+#if LINUX_VERSION_CODE < 0x020100
+	/*
+	 * Set up poll timer. It is used to check DCD status.
+	 */
+	if ((timer_active & (1 << RS_TIMER)) == 0) {
+		timer_table[RS_TIMER].expires = jiffies + HZ/25;
+		timer_active |= 1 << RS_TIMER;
+	}
+#endif /* LINUX_VERSION_CODE < 0x020100 */
+#endif /* MCF_HAVEDCD0 || MCF_HAVEDCD1 */
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttyS%d (irq %d)...\n", info->line, info->irq);
+#endif
+
+	/*
+	 *	Reset UART, get it into known state...
+	 */
+	uartp = (volatile unsigned char *) info->addr;
+	uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX;  /* reset RX */
+	uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX;  /* reset TX */
+	mcfrs_setsignals(info, 1, 1);
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+
+	/*
+	 * and set the speed of the serial port
+	 */
+	mcfrs_change_speed(info);
+
+	/*
+	 * Lastly enable the UART transmitter and receiver, and
+	 * interrupt enables.
+	 */
+	info->imr = MCFUART_UIR_RXREADY;
+	uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE;
+	uartp[MCFUART_UIMR] = info->imr;
+
+	info->flags |= ASYNC_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct mcf_serial * info)
+{
+	volatile unsigned char	*uartp;
+	unsigned long		flags;
+
+	if (!(info->flags & ASYNC_INITIALIZED))
+		return;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Shutting down serial port %d (irq %d)....\n", info->line,
+	       info->irq);
+#endif
+	
+	uartp = (volatile unsigned char *) info->addr;
+	save_flags(flags); cli(); /* Disable interrupts */
+
+	uartp[MCFUART_UIMR] = 0;  /* mask all interrupts */
+	uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX;  /* reset RX */
+	uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX;  /* reset TX */
+
+	if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+		mcfrs_setsignals(info, 0, 0);
+
+	if (info->xmit_buf) {
+		free_page((unsigned long) info->xmit_buf);
+		info->xmit_buf = 0;
+	}
+
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+	
+	info->flags &= ~ASYNC_INITIALIZED;
+	restore_flags(flags);
+}
+
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void mcfrs_change_speed(struct mcf_serial *info)
+{
+	volatile unsigned char	*uartp;
+	unsigned int		baudclk, cflag;
+	unsigned long		flags;
+	unsigned char		mr1, mr2;
+	int			i;
+#ifdef	CONFIG_M5272
+	unsigned int		fraction;
+#endif
+
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+	if (info->addr == 0)
+		return;
+
+#if 0
+	printk("%s(%d): mcfrs_change_speed()\n", __FILE__, __LINE__);
+#endif
+
+	i = cflag & CBAUD;
+	if (i & CBAUDEX) {
+		i &= ~CBAUDEX;
+		if (i < 1)
+			info->tty->termios->c_cflag &= ~CBAUDEX;
+		else
+			i += 15;
+	}
+	if (i == 0) {
+		mcfrs_setsignals(info, 0, -1);
+		return;
+	}
+
+	/* compute the baudrate clock */
+#ifdef	CONFIG_M5272
+	/*
+	 * For the MCF5272, also compute the baudrate fraction.
+	 */
+	baudclk = (MCF_BUSCLK / mcfrs_baud_table[i]) / 32;
+	fraction = MCF_BUSCLK - (baudclk * 32 * mcfrs_baud_table[i]);
+	fraction *= 16;
+	fraction /= (32 * mcfrs_baud_table[i]);
+#else
+	baudclk = ((MCF_BUSCLK / mcfrs_baud_table[i]) + 16) / 32;
+#endif
+
+	info->baud = mcfrs_baud_table[i];
+
+	mr1 = MCFUART_MR1_RXIRQRDY | MCFUART_MR1_RXERRCHAR;
+	mr2 = 0;
+
+	switch (cflag & CSIZE) {
+	case CS5:	mr1 |= MCFUART_MR1_CS5; break;
+	case CS6:	mr1 |= MCFUART_MR1_CS6; break;
+	case CS7:	mr1 |= MCFUART_MR1_CS7; break;
+	case CS8:
+	default:	mr1 |= MCFUART_MR1_CS8; break;
+	}
+
+	if (cflag & PARENB) {
+		if (cflag & CMSPAR) {
+			if (cflag & PARODD)
+				mr1 |= MCFUART_MR1_PARITYMARK;
+			else
+				mr1 |= MCFUART_MR1_PARITYSPACE;
+		} else {
+			if (cflag & PARODD)
+				mr1 |= MCFUART_MR1_PARITYODD;
+			else
+				mr1 |= MCFUART_MR1_PARITYEVEN;
+		}
+	} else {
+		mr1 |= MCFUART_MR1_PARITYNONE;
+	}
+
+	if (cflag & CSTOPB)
+		mr2 |= MCFUART_MR2_STOP2;
+	else
+		mr2 |= MCFUART_MR2_STOP1;
+
+	if (cflag & CRTSCTS) {
+		mr1 |= MCFUART_MR1_RXRTS;
+		mr2 |= MCFUART_MR2_TXCTS;
+	}
+
+	if (cflag & CLOCAL)
+		info->flags &= ~ASYNC_CHECK_CD;
+	else
+		info->flags |= ASYNC_CHECK_CD;
+
+	uartp = (volatile unsigned char *) info->addr;
+
+	save_flags(flags); cli();
+#if 0
+	printk("%s(%d): mr1=%x mr2=%x baudclk=%x\n", __FILE__, __LINE__,
+		mr1, mr2, baudclk);
+#endif
+	/*
+	  Note: pg 12-16 of MCF5206e User's Manual states that a
+	  software reset should be performed prior to changing
+	  UMR1,2, UCSR, UACR, bit 7
+	*/
+	uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX;    /* reset RX */
+	uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX;    /* reset TX */
+	uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETMRPTR;	/* reset MR pointer */
+	uartp[MCFUART_UMR] = mr1;
+	uartp[MCFUART_UMR] = mr2;
+	uartp[MCFUART_UBG1] = (baudclk & 0xff00) >> 8;	/* set msb byte */
+	uartp[MCFUART_UBG2] = (baudclk & 0xff);		/* set lsb byte */
+#ifdef	CONFIG_M5272
+	uartp[MCFUART_UFPD] = (fraction & 0xf);		/* set fraction */
+#endif
+	uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER;
+	uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE;
+	mcfrs_setsignals(info, 1, -1);
+	restore_flags(flags);
+	return;
+}
+
+static void mcfrs_flush_chars(struct tty_struct *tty)
+{
+	volatile unsigned char	*uartp;
+	struct mcf_serial	*info = (struct mcf_serial *)tty->driver_data;
+	unsigned long		flags;
+
+	if (serial_paranoia_check(info, tty->device, "mcfrs_flush_chars"))
+		return;
+	/*
+	 * re-enable receiver interrupt
+	 */
+	uartp = (volatile unsigned char *) info->addr;
+	save_flags(flags); cli();
+	if ( (!(info->imr & MCFUART_UIR_RXREADY)) &&
+			(info->flags & ASYNC_INITIALIZED) ) {
+		info->imr |= MCFUART_UIR_RXREADY;
+		uartp[MCFUART_UIMR] = info->imr;
+	}
+	restore_flags(flags);
+	
+	if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
+	    !info->xmit_buf)
+		return;
+
+	/* Enable transmitter */
+	uartp = (volatile unsigned char *) info->addr;
+	save_flags(flags); cli();
+	info->imr |= MCFUART_UIR_TXREADY;
+	uartp[MCFUART_UIMR] = info->imr;
+	restore_flags(flags);
+}
+
+static int mcfrs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	volatile unsigned char	*uartp;
+	struct mcf_serial	*info = (struct mcf_serial *)tty->driver_data;
+	unsigned long		flags;
+	int			c, total = 0;
+
+#if 0
+	printk("%s(%d): mcfrs_write(tty=%x,from_user=%d,buf=%x,count=%d)\n",
+		__FILE__, __LINE__, tty, from_user, buf, count);
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "mcfrs_write"))
+		return 0;
+
+	if (!tty || !info->xmit_buf)
+		return 0;
+	
+	save_flags(flags);
+	while (1) {
+		cli();		
+		c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				   SERIAL_XMIT_SIZE - info->xmit_head));
+
+		if (c <= 0) {
+			restore_flags(flags);
+			break;
+		}
+
+		if (from_user) {
+			down(&mcfrs_tmp_buf_sem);
+			copy_from_user(mcfrs_tmp_buf, buf, c);
+			restore_flags(flags);
+			cli();		
+			c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				       SERIAL_XMIT_SIZE - info->xmit_head));
+			memcpy(info->xmit_buf + info->xmit_head, mcfrs_tmp_buf, c);
+			up(&mcfrs_tmp_buf_sem);
+		} else
+			memcpy(info->xmit_buf + info->xmit_head, buf, c);
+
+		info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+		info->xmit_cnt += c;
+		restore_flags(flags);
+
+		buf += c;
+		count -= c;
+		total += c;
+	}
+
+	if (!tty->stopped) {
+		uartp = (volatile unsigned char *) info->addr;
+		cli();
+		info->imr |= MCFUART_UIR_TXREADY;
+		uartp[MCFUART_UIMR] = info->imr;
+		restore_flags(flags);
+	}
+
+	return total;
+}
+
+static int mcfrs_write_room(struct tty_struct *tty)
+{
+	struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
+	int	ret;
+				
+	if (serial_paranoia_check(info, tty->device, "mcfrs_write_room"))
+		return 0;
+	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
+	if (ret < 0)
+		ret = 0;
+	return ret;
+}
+
+static int mcfrs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
+					
+	if (serial_paranoia_check(info, tty->device, "mcfrs_chars_in_buffer"))
+		return 0;
+
+	return (info->xmit_cnt);
+}
+
+static void mcfrs_flush_buffer(struct tty_struct *tty)
+{
+	struct mcf_serial	*info = (struct mcf_serial *)tty->driver_data;
+	unsigned long		flags;
+				
+	if (serial_paranoia_check(info, tty->device, "mcfrs_flush_buffer"))
+		return;
+
+	save_flags(flags); cli();
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+	restore_flags(flags);
+
+	wake_up_interruptible(&tty->write_wait);
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * ------------------------------------------------------------
+ * mcfrs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void mcfrs_throttle(struct tty_struct * tty)
+{
+	struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
+#ifdef SERIAL_DEBUG_THROTTLE
+	printk("mcfrs_throttle line=%d chars=%d\n", info->line,
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "mcfrs_throttle"))
+		return;
+	
+	if (I_IXOFF(tty)) {
+		/* Force STOP_CHAR (xoff) out */
+		volatile unsigned char	*uartp;
+		unsigned long		flags;
+		info->x_char = STOP_CHAR(tty);
+		uartp = (volatile unsigned char *) info->addr;
+		save_flags(flags); cli();
+		info->imr |= MCFUART_UIR_TXREADY;
+		uartp[MCFUART_UIMR] = info->imr;
+		restore_flags(flags);
+	}
+
+	/* Turn off RTS line */
+	if (tty->termios->c_cflag & CRTSCTS)
+		mcfrs_setsignals(info, -1, 0);
+}
+
+static void mcfrs_unthrottle(struct tty_struct * tty)
+{
+	struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
+#ifdef SERIAL_DEBUG_THROTTLE
+	printk("mcfrs_unthrottle line=%d chars=%d\n", info->line,
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "mcfrs_unthrottle"))
+		return;
+	
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else {
+			/* Force START_CHAR (xon) out */
+			volatile unsigned char	*uartp;
+			unsigned long		flags;
+			info->x_char = START_CHAR(tty);
+			uartp = (volatile unsigned char *) info->addr;
+			save_flags(flags); cli();
+			info->imr |= MCFUART_UIR_TXREADY;
+			uartp[MCFUART_UIMR] = info->imr;
+			restore_flags(flags);
+		}
+	}
+
+	/* Assert RTS line */
+	if (tty->termios->c_cflag & CRTSCTS)
+		mcfrs_setsignals(info, -1, 1);
+}
+
+/*
+ * ------------------------------------------------------------
+ * mcfrs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int get_serial_info(struct mcf_serial * info,
+			   struct serial_struct * retinfo)
+{
+	struct serial_struct tmp;
+  
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = info->type;
+	tmp.line = info->line;
+	tmp.port = info->addr;
+	tmp.irq = info->irq;
+	tmp.flags = info->flags;
+	tmp.baud_base = info->baud_base;
+	tmp.close_delay = info->close_delay;
+	tmp.closing_wait = info->closing_wait;
+	tmp.custom_divisor = info->custom_divisor;
+	copy_to_user(retinfo,&tmp,sizeof(*retinfo));
+	return 0;
+}
+
+static int set_serial_info(struct mcf_serial * info,
+			   struct serial_struct * new_info)
+{
+	struct serial_struct new_serial;
+	struct mcf_serial old_info;
+	int 			retval = 0;
+
+	if (!new_info)
+		return -EFAULT;
+	copy_from_user(&new_serial,new_info,sizeof(new_serial));
+	old_info = *info;
+
+	if (!suser()) {
+		if ((new_serial.baud_base != info->baud_base) ||
+		    (new_serial.type != info->type) ||
+		    (new_serial.close_delay != info->close_delay) ||
+		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
+		     (info->flags & ~ASYNC_USR_MASK)))
+			return -EPERM;
+		info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+			       (new_serial.flags & ASYNC_USR_MASK));
+		info->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	if (info->count > 1)
+		return -EBUSY;
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+	info->baud_base = new_serial.baud_base;
+	info->flags = ((info->flags & ~ASYNC_FLAGS) |
+			(new_serial.flags & ASYNC_FLAGS));
+	info->type = new_serial.type;
+	info->close_delay = new_serial.close_delay;
+	info->closing_wait = new_serial.closing_wait;
+
+check_and_exit:
+	retval = startup(info);
+	return retval;
+}
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space. 
+ */
+static int get_lsr_info(struct mcf_serial * info, unsigned int *value)
+{
+	volatile unsigned char	*uartp;
+	unsigned long		flags;
+	unsigned char		status;
+
+	uartp = (volatile unsigned char *) info->addr;
+	save_flags(flags); cli();
+	status = (uartp[MCFUART_USR] & MCFUART_USR_TXEMPTY) ? TIOCSER_TEMT : 0;
+	restore_flags(flags);
+
+	put_user(status,value);
+	return 0;
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void send_break(	struct mcf_serial * info, int duration)
+{
+	volatile unsigned char	*uartp;
+	unsigned long		flags;
+
+	if (!info->addr)
+		return;
+	current->state = TASK_INTERRUPTIBLE;
+#if LINUX_VERSION_CODE < 0x020100
+	current->timeout = jiffies + duration;
+#endif
+	uartp = (volatile unsigned char *) info->addr;
+
+	save_flags(flags); cli();
+	uartp[MCFUART_UCR] = MCFUART_UCR_CMDBREAKSTART;
+#if LINUX_VERSION_CODE < 0x020100
+	schedule();
+#else
+	schedule_timeout(duration);
+#endif
+	uartp[MCFUART_UCR] = MCFUART_UCR_CMDBREAKSTOP;
+	restore_flags(flags);
+}
+
+static int mcfrs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	struct mcf_serial * info = (struct mcf_serial *)tty->driver_data;
+	unsigned int val;
+	int retval, error;
+	int dtr, rts;
+
+	if (serial_paranoia_check(info, tty->device, "mcfrs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
+	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+	
+	switch (cmd) {
+		case TCSBRK:	/* SVID version: non-zero arg --> no break */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (!arg)
+				send_break(info, HZ/4);	/* 1/4 second */
+			return 0;
+		case TCSBRKP:	/* support for POSIX tcsendbreak() */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+			return 0;
+		case TIOCGSOFTCAR:
+			error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long));
+			if (error)
+				return error;
+			put_user(C_CLOCAL(tty) ? 1 : 0,
+				    (unsigned long *) arg);
+			return 0;
+		case TIOCSSOFTCAR:
+			get_user(arg, (unsigned long *) arg);
+			tty->termios->c_cflag =
+				((tty->termios->c_cflag & ~CLOCAL) |
+				 (arg ? CLOCAL : 0));
+			return 0;
+		case TIOCGSERIAL:
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+						sizeof(struct serial_struct));
+			if (error)
+				return error;
+			return get_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSSERIAL:
+			return set_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSERGETLSR: /* Get line status register */
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+				sizeof(unsigned int));
+			if (error)
+				return error;
+			else
+			    return get_lsr_info(info, (unsigned int *) arg);
+
+		case TIOCSERGSTRUCT:
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+						sizeof(struct mcf_serial));
+			if (error)
+				return error;
+			copy_to_user((struct mcf_serial *) arg,
+				    info, sizeof(struct mcf_serial));
+			return 0;
+			
+		case TIOCMGET:
+			if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+                            sizeof(unsigned int))))
+                                return(error);
+			val = mcfrs_getsignals(info);
+			put_user(val, (unsigned int *) arg);
+			break;
+
+                case TIOCMBIS:
+			if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+                            sizeof(unsigned int))))
+				return(error);
+
+#if LINUX_VERSION_CODE < 0x020100
+			val = get_user((unsigned int *) arg);
+#else
+			get_user(val, (unsigned int *) arg);
+#endif
+			rts = (val & TIOCM_RTS) ? 1 : -1;
+			dtr = (val & TIOCM_DTR) ? 1 : -1;
+			mcfrs_setsignals(info, dtr, rts);
+			break;
+
+                case TIOCMBIC:
+			if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+                            sizeof(unsigned int))))
+				return(error);
+#if LINUX_VERSION_CODE < 0x020100
+			val = get_user((unsigned int *) arg);
+#else
+			get_user(val, (unsigned int *) arg);
+#endif
+			rts = (val & TIOCM_RTS) ? 0 : -1;
+			dtr = (val & TIOCM_DTR) ? 0 : -1;
+			mcfrs_setsignals(info, dtr, rts);
+			break;
+
+                case TIOCMSET:
+			if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+                            sizeof(unsigned int))))
+				return(error);
+#if LINUX_VERSION_CODE < 0x020100
+			val = get_user((unsigned int *) arg);
+#else
+			get_user(val, (unsigned int *) arg);
+#endif
+			rts = (val & TIOCM_RTS) ? 1 : 0;
+			dtr = (val & TIOCM_DTR) ? 1 : 0;
+			mcfrs_setsignals(info, dtr, rts);
+			break;
+
+#ifdef TIOCSET422
+		case TIOCSET422:
+#if LINUX_VERSION_CODE < 0x020100
+			val = get_user((unsigned int *) arg);
+#else
+			get_user(val, (unsigned int *) arg);
+#endif
+			mcf_setpa(MCFPP_PA11, (val ? 0 : MCFPP_PA11));
+			break;
+		case TIOCGET422:
+			val = (mcf_getpa() & MCFPP_PA11) ? 0 : 1;
+			put_user(val, (unsigned int *) arg);
+			break;
+#endif
+
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+static void mcfrs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
+
+	if (tty->termios->c_cflag == old_termios->c_cflag)
+		return;
+
+	mcfrs_change_speed(info);
+
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		mcfrs_setsignals(info, -1, 1);
+#if 0
+		mcfrs_start(tty);
+#endif
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * mcfrs_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * S structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void mcfrs_close(struct tty_struct *tty, struct file * filp)
+{
+	volatile unsigned char	*uartp;
+	struct mcf_serial	*info = (struct mcf_serial *)tty->driver_data;
+	unsigned long		flags;
+
+	if (!info || serial_paranoia_check(info, tty->device, "mcfrs_close"))
+		return;
+	
+	save_flags(flags); cli();
+	
+	if (tty_hung_up_p(filp)) {
+		restore_flags(flags);
+		return;
+	}
+	
+#ifdef SERIAL_DEBUG_OPEN
+	printk("mcfrs_close ttyS%d, count = %d\n", info->line, info->count);
+#endif
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  Info->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("mcfrs_close: bad serial port count; tty->count is 1, "
+		       "info->count is %d\n", info->count);
+		info->count = 1;
+	}
+	if (--info->count < 0) {
+		printk("mcfrs_close: bad serial port count for ttyS%d: %d\n",
+		       info->line, info->count);
+		info->count = 0;
+	}
+	if (info->count) {
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= ASYNC_CLOSING;
+
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & ASYNC_NORMAL_ACTIVE)
+		info->normal_termios = *tty->termios;
+	if (info->flags & ASYNC_CALLOUT_ACTIVE)
+		info->callout_termios = *tty->termios;
+
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+	info->imr &= ~MCFUART_UIR_RXREADY;
+	uartp = (volatile unsigned char *) info->addr;
+	uartp[MCFUART_UIMR] = info->imr;
+
+#if 0
+	/* FIXME: do we need to keep this enabled for console?? */
+	if (mcfrs_console_inited && (mcfrs_console_port == info->line)) {
+		/* Do not disable the UART */ ;
+	} else
+#endif
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	info->imr = 0;
+	if (tty->ldisc.num != tty_ldiscs[N_TTY].num) {
+		if (tty->ldisc.close)
+			(tty->ldisc.close)(tty);
+		tty->ldisc = tty_ldiscs[N_TTY];
+		tty->termios->c_line = N_TTY;
+		if (tty->ldisc.open)
+			(tty->ldisc.open)(tty);
+	}
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+#if LINUX_VERSION_CODE < 0x020100
+			current->timeout = jiffies + info->close_delay;
+			schedule();
+#else
+			schedule_timeout(info->close_delay);
+#endif
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
+			 ASYNC_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	restore_flags(flags);
+}
+
+/*
+ * mcfrs_wait_until_sent() --- wait until the transmitter is empty
+ */
+static void
+mcfrs_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+#ifdef	CONFIG_M5272
+#define	MCF5272_FIFO_SIZE	25		/* fifo size + shift reg */
+
+	struct mcf_serial * info = (struct mcf_serial *)tty->driver_data;
+	volatile unsigned char *uartp;
+	unsigned long orig_jiffies, fifo_time, char_time, fifo_cnt;
+	
+	if (serial_paranoia_check(info, tty->device, "mcfrs_wait_until_sent"))
+		return;
+	
+	orig_jiffies = jiffies;
+
+	/*
+	 * Set the check interval to be 1/5 of the approximate time
+	 * to send the entire fifo, and make it at least 1.  The check
+	 * interval should also be less than the timeout.
+	 *
+	 * Note: we have to use pretty tight timings here to satisfy
+	 * the NIST-PCTS.
+	 */
+	fifo_time = (MCF5272_FIFO_SIZE * HZ * 10) / info->baud;
+	char_time = fifo_time / 5;
+	if (char_time == 0)
+		char_time = 1;
+	if (timeout && timeout < char_time)
+		char_time = timeout;
+
+	/*
+	 * Clamp the timeout period at 2 * the time to empty the
+	 * fifo.  Just to be safe, set the minimum at .5 seconds.
+	 */
+	fifo_time *= 2;
+	if (fifo_time < (HZ/2))
+		fifo_time = HZ/2;
+	if (!timeout || timeout > fifo_time)
+		timeout = fifo_time;
+
+	/*
+	 * Account for the number of bytes in the UART
+	 * transmitter FIFO plus any byte being shifted out.
+	 */
+	uartp = (volatile unsigned char *) info->addr;
+	for (;;) {
+		fifo_cnt = (uartp[MCFUART_UTF] & MCFUART_UTF_TXB);
+		if ((uartp[MCFUART_USR] & (MCFUART_USR_TXREADY|
+				MCFUART_USR_TXEMPTY)) ==
+			MCFUART_USR_TXREADY)
+			fifo_cnt++;
+		if (fifo_cnt == 0)
+			break;
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(char_time);
+		if (signal_pending(current))
+			break;
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			break;
+	}
+#else
+	/*
+	 * For the other coldfire models, assume all data has been sent
+	 */
+#endif
+}
+		
+/*
+ * mcfrs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+void mcfrs_hangup(struct tty_struct *tty)
+{
+	struct mcf_serial * info = (struct mcf_serial *)tty->driver_data;
+	
+	if (serial_paranoia_check(info, tty->device, "mcfrs_hangup"))
+		return;
+	
+	mcfrs_flush_buffer(tty);
+	shutdown(info);
+	info->event = 0;
+	info->count = 0;
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * mcfrs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file * filp,
+			   struct mcf_serial *info)
+{
+#if LINUX_VERSION_CODE < 0x020100
+	struct wait_queue wait = { current, NULL };
+#else
+	DECLARE_WAITQUEUE(wait, current);
+#endif
+	int		retval;
+	int		do_clocal = 0;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (info->flags & ASYNC_CLOSING) {
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		if (info->flags & ASYNC_HUP_NOTIFY)
+			return -EAGAIN;
+		else
+			return -ERESTARTSYS;
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & ASYNC_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+		    return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+		    return -EBUSY;
+		info->flags |= ASYNC_CALLOUT_ACTIVE;
+		return 0;
+	}
+	
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & ASYNC_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= ASYNC_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
+		if (info->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+	
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, info->count is dropped by one, so that
+	 * mcfrs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready before block: ttyS%d, count = %d\n",
+	       info->line, info->count);
+#endif
+	info->count--;
+	info->blocked_open++;
+	while (1) {
+		cli();
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE))
+			mcfrs_setsignals(info, 1, 1);
+		sti();
+		current->state = TASK_INTERRUPTIBLE;
+		if (tty_hung_up_p(filp) ||
+		    !(info->flags & ASYNC_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & ASYNC_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;	
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    !(info->flags & ASYNC_CLOSING) &&
+		    (do_clocal || (mcfrs_getsignals(info) & TIOCM_CD)))
+			break;
+#if LINUX_VERSION_CODE < 0x020100
+		if (current->signal & ~current->blocked) {
+#else
+		if (signal_pending(current)) {
+#endif
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef SERIAL_DEBUG_OPEN
+		printk("block_til_ready blocking: ttyS%d, count = %d\n",
+		       info->line, info->count);
+#endif
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&info->open_wait, &wait);
+	if (!tty_hung_up_p(filp))
+		info->count++;
+	info->blocked_open--;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready after blocking: ttyS%d, count = %d\n",
+	       info->line, info->count);
+#endif
+	if (retval)
+		return retval;
+	info->flags |= ASYNC_NORMAL_ACTIVE;
+	return 0;
+}	
+
+/*
+ * This routine is called whenever a serial port is opened. It
+ * enables interrupts for a serial port, linking in its structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+int mcfrs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct mcf_serial	*info;
+	int 			retval, line;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	if ((line < 0) || (line >= NR_PORTS))
+		return -ENODEV;
+	info = mcfrs_table + line;
+	if (serial_paranoia_check(info, tty->device, "mcfrs_open"))
+		return -ENODEV;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("mcfrs_open %s%d, count = %d\n", tty->driver.name, info->line,
+	       info->count);
+#endif
+	info->count++;
+	tty->driver_data = info;
+	info->tty = tty;
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval)
+		return retval;
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("mcfrs_open returning after block_til_ready with %d\n",
+		       retval);
+#endif
+		return retval;
+	}
+
+	if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->normal_termios;
+		else 
+			*tty->termios = info->callout_termios;
+		mcfrs_change_speed(info);
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("mcfrs_open ttyS%d successful...\n", info->line);
+#endif
+	return 0;
+}
+
+/*
+ *	Based on the line number set up the internal interrupt stuff.
+ */
+static void mcfrs_irqinit(struct mcf_serial *info)
+{
+#if defined(CONFIG_M5272)
+	volatile unsigned long	*icrp;
+	volatile unsigned long	*portp;
+	volatile unsigned char	*uartp;
+
+	uartp = (volatile unsigned char *) info->addr;
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR2);
+
+	switch (info->line) {
+	case 0:
+		*icrp = 0xe0000000;
+		/* Enable the output lines for the serial port 0 */
+		portp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PBCNT);
+		*portp = (*portp & ~0x000000ff) | 0x00000055;
+		break;
+	case 1:
+		*icrp = 0x0e000000;
+		/* Enable the output lines for the serial port 1 */
+		portp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PDCNT);
+		*portp = (*portp & ~0x000003fc) | 0x000002a8;
+		break;
+	default:
+		printk("SERIAL: don't know how to handle UART %d interrupt?\n",
+			info->line);
+		return;
+	}
+
+#ifdef MCF_HAVEDTR0
+	{
+	volatile unsigned short *sportp;
+	/* Set direction bits if we have GPIO based DTR/DCD */
+	sportp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDDR);
+	*sportp = (*sportp & ~0x00f0) | 0x0050;
+	}
+#endif
+
+#elif defined(CONFIG_M5235) || defined(CONFIG_M527x) || \
+      defined(CONFIG_M5282) || defined(CONFIG_M5280)
+	volatile unsigned char *icrp, *uartp;
+	volatile unsigned long *imrp;
+	volatile unsigned char *portp;
+
+	uartp = (volatile unsigned char *) info->addr;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 +
+		MCFINTC_ICR0 + MCFINT_UART0 + info->line);
+ 	/* UART interrupt level and priority */
+	*icrp = 0x30 + (info->line ? 3 : 2);
+
+	imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
+		MCFINTC_IMRL);
+	*imrp &= ~((1 << (info->irq - 64)) | 1);
+
+#if defined(CONFIG_M527x)
+	{
+	/*
+	 * External Pin Mask Setting & Enable External Pin for Interface i 
+	 * mrcbis@aliceposta.it
+         */
+	unsigned short *serpin_enable_mask;
+	serpin_enable_mask = (MCF_IPSBAR + MCF_GPIO_PAR_UART);
+	if (info->line == 0)
+		*serpin_enable_mask |= UART0_ENABLE_MASK;
+	else if (info->line == 1)
+		*serpin_enable_mask |= UART1_ENABLE_MASK;
+	else if (info->line == 2)
+		*serpin_enable_mask |= UART2_ENABLE_MASK;
+	}
+#endif
+
+#if defined(CONFIG_M5280) || defined(CONFIG_M5282)
+	/* Enable the output lines for the serial port */
+	if (info->line < 2) {
+		portp = (volatile unsigned char *) (MCF_MBAR + MCF5282_GPIO_PUAPAR);
+		*portp |= (0x03 << (info->line*2));
+	} else {
+		printk("SERIAL: don't know how to enable outputs "
+			"for UART %d?\n", info->line);
+	}
+#endif
+#elif defined(CONFIG_M547x)
+	volatile unsigned char *icrp, *uartp;
+	volatile unsigned int *imrp;
+	volatile unsigned char *portp;
+
+	uartp = (volatile unsigned char *) info->addr;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR0 +
+		35 - info->line);
+ 	/* UART interrupt level and priority */
+	*icrp = MCFSIM_ICR_LEVEL6 + (info->line & 0x3);
+
+	imrp = (volatile unsigned int *) (MCF_MBAR + MCFSIM_IMRH);
+	*imrp &= ~(1 << (info->irq - (64+32)));
+#else
+	volatile unsigned char	*icrp, *uartp;
+
+	switch (info->line) {
+	case 0:
+		icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_UART1ICR);
+		*icrp = /*MCFSIM_ICR_AUTOVEC |*/ MCFSIM_ICR_LEVEL6 |
+			MCFSIM_ICR_PRI1;
+		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
+		break;
+	case 1:
+		icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_UART2ICR);
+		*icrp = /*MCFSIM_ICR_AUTOVEC |*/ MCFSIM_ICR_LEVEL6 |
+			MCFSIM_ICR_PRI2;
+		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
+		break;
+	default:
+		printk("SERIAL: don't know how to handle UART %d interrupt?\n",
+			info->line);
+		return;
+	}
+
+	uartp = (volatile unsigned char *) info->addr;
+	uartp[MCFUART_UIVR] = info->irq;
+#endif
+
+	/* Clear mask, so no surprise interrupts. */
+	uartp[MCFUART_UIMR] = 0;
+
+	if (request_irq(info->irq, mcfrs_interrupt, SA_INTERRUPT,
+	    "ColdFire UART", info)) {
+		printk("SERIAL: Unable to attach ColdFire UART %d interrupt "
+			"vector=%d\n", info->line, info->irq);
+	}
+
+	return;
+}
+
+
+char *mcfrs_drivername = "ColdFire internal UART serial driver version 1.00\n";
+
+
+/*
+ * Serial stats reporting...
+ */
+int mcfrs_readproc(char *page, char **start, off_t off, int count,
+		         int *eof, void *data)
+{
+	struct mcf_serial	*info;
+	char			str[20];
+	int			len, sigs, i;
+
+	len = sprintf(page, mcfrs_drivername);
+	for (i = 0; (i < NR_PORTS); i++) {
+		info = &mcfrs_table[i];
+		len += sprintf((page + len), "%d: port:%x irq=%d baud:%d ",
+			i, info->addr, info->irq, info->baud);
+		if (info->stats.rx || info->stats.tx)
+			len += sprintf((page + len), "tx:%d rx:%d ",
+			info->stats.tx, info->stats.rx);
+		if (info->stats.rxframing)
+			len += sprintf((page + len), "fe:%d ",
+			info->stats.rxframing);
+		if (info->stats.rxparity)
+			len += sprintf((page + len), "pe:%d ",
+			info->stats.rxparity);
+		if (info->stats.rxbreak)
+			len += sprintf((page + len), "brk:%d ",
+			info->stats.rxbreak);
+		if (info->stats.rxoverrun)
+			len += sprintf((page + len), "oe:%d ",
+			info->stats.rxoverrun);
+
+		str[0] = str[1] = 0;
+		if ((sigs = mcfrs_getsignals(info))) {
+			if (sigs & TIOCM_RTS)
+				strcat(str, "|RTS");
+			if (sigs & TIOCM_CTS)
+				strcat(str, "|CTS");
+			if (sigs & TIOCM_DTR)
+				strcat(str, "|DTR");
+			if (sigs & TIOCM_CD)
+				strcat(str, "|CD");
+		}
+
+		len += sprintf((page + len), "%s\n", &str[1]);
+	}
+
+	return(len);
+}
+
+
+/* Finally, routines used to initialize the serial driver. */
+
+static void show_serial_version(void)
+{
+	printk(mcfrs_drivername);
+}
+
+/* mcfrs_init inits the driver */
+static int __init
+mcfrs_init(void)
+{
+	struct mcf_serial	*info;
+	unsigned long		flags;
+	int			i;
+
+	init_bh(CM206_BH, do_serial_bh);
+
+	/* Setup base handler, and timer table. */
+#if defined(MCF_HAVEDCD0) || defined(MCF_HAVEDCD1)
+#if LINUX_VERSION_CODE < 0x020100
+	timer_table[RS_TIMER].fn = mcfrs_timer;
+	timer_table[RS_TIMER].expires = 0;
+#else
+	init_timer(&mcfrs_timer_struct);
+	mcfrs_timer_struct.function = mcfrs_timer;
+	mcfrs_timer_struct.data = 0;
+	mcfrs_timer_struct.expires = jiffies + HZ/25;
+	add_timer(&mcfrs_timer_struct);
+#endif
+	mcfrs_olddcd0 = mcf_getppdcd(0);
+	mcfrs_olddcd1 = mcf_getppdcd(1);
+#endif /* MCF_HAVEDCD0 || MCF_HAVEDCD1 */
+
+	show_serial_version();
+
+	/* Initialize the tty_driver structure */
+	memset(&mcfrs_serial_driver, 0, sizeof(struct tty_driver));
+	mcfrs_serial_driver.magic = TTY_DRIVER_MAGIC;
+#if defined(CONFIG_DEVFS_FS)
+	mcfrs_serial_driver.name = "tts/%d";
+#else
+	mcfrs_serial_driver.name = "ttyS";
+#endif  /* defined(CONFIG_DEVFS_FS) */
+	mcfrs_serial_driver.major = TTY_MAJOR;
+	mcfrs_serial_driver.minor_start = 64;
+	mcfrs_serial_driver.num = NR_PORTS;
+	mcfrs_serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	mcfrs_serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	mcfrs_serial_driver.init_termios = tty_std_termios;
+
+	mcfrs_serial_driver.init_termios.c_cflag =
+		mcfrs_console_cbaud | CS8 | CREAD | HUPCL | CLOCAL;
+	mcfrs_serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	mcfrs_serial_driver.refcount = &mcfrs_serial_refcount;
+	mcfrs_serial_driver.table = mcfrs_serial_table;
+	mcfrs_serial_driver.termios = mcfrs_serial_termios;
+	mcfrs_serial_driver.termios_locked = mcfrs_serial_termios_locked;
+
+	mcfrs_serial_driver.open = mcfrs_open;
+	mcfrs_serial_driver.close = mcfrs_close;
+	mcfrs_serial_driver.write = mcfrs_write;
+	mcfrs_serial_driver.flush_chars = mcfrs_flush_chars;
+	mcfrs_serial_driver.write_room = mcfrs_write_room;
+	mcfrs_serial_driver.chars_in_buffer = mcfrs_chars_in_buffer;
+	mcfrs_serial_driver.flush_buffer = mcfrs_flush_buffer;
+	mcfrs_serial_driver.ioctl = mcfrs_ioctl;
+	mcfrs_serial_driver.throttle = mcfrs_throttle;
+	mcfrs_serial_driver.unthrottle = mcfrs_unthrottle;
+	mcfrs_serial_driver.set_termios = mcfrs_set_termios;
+	mcfrs_serial_driver.stop = mcfrs_stop;
+	mcfrs_serial_driver.start = mcfrs_start;
+	mcfrs_serial_driver.hangup = mcfrs_hangup;
+	mcfrs_serial_driver.read_proc = mcfrs_readproc;
+	mcfrs_serial_driver.wait_until_sent = mcfrs_wait_until_sent;
+	mcfrs_serial_driver.driver_name = "serial";
+
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	mcfrs_callout_driver = mcfrs_serial_driver;
+#if defined(CONFIG_DEVFS_FS)
+	mcfrs_callout_driver.name = "cua/%d";
+#else
+	mcfrs_callout_driver.name = "cua";
+#endif  /* defined(CONFIG_DEVFS_FS) */
+	mcfrs_callout_driver.major = TTYAUX_MAJOR;
+	mcfrs_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+	mcfrs_callout_driver.read_proc = 0;
+	mcfrs_callout_driver.proc_entry = 0;
+
+	if (tty_register_driver(&mcfrs_serial_driver)) {
+		printk("%s: Couldn't register serial driver\n", __FUNCTION__);
+		return(-EBUSY);
+	}
+	if (tty_register_driver(&mcfrs_callout_driver)) {
+		printk("%s: Couldn't register callout driver\n", __FUNCTION__);
+		return(-EBUSY);
+	}
+	
+	save_flags(flags); cli();
+
+	/*
+	 *	Configure all the attached serial ports.
+	 */
+	for (i = 0, info = mcfrs_table; (i < NR_PORTS); i++, info++) {
+		info->magic = SERIAL_MAGIC;
+		info->line = i;
+		info->tty = 0;
+		info->custom_divisor = 16;
+		info->close_delay = 50;
+		info->closing_wait = 3000;
+		info->x_char = 0;
+		info->event = 0;
+		info->count = 0;
+		info->blocked_open = 0;
+		info->tqueue.routine = do_softint;
+		info->tqueue.data = info;
+		info->tqueue_hangup.routine = do_serial_hangup;
+		info->tqueue_hangup.data = info;
+		info->callout_termios = mcfrs_callout_driver.init_termios;
+		info->normal_termios = mcfrs_serial_driver.init_termios;
+#if LINUX_VERSION_CODE < 0x020100
+		info->open_wait = 0;
+		info->close_wait = 0;
+#else
+		init_waitqueue_head(&info->open_wait);
+		init_waitqueue_head(&info->close_wait);
+#endif
+
+		info->imr = 0;
+		mcfrs_setsignals(info, 0, 0);
+		mcfrs_irqinit(info);
+
+#if defined(CONFIG_DEVFS_FS)
+		printk("%.4s%d at 0x%04x (irq = %d)", mcfrs_serial_driver.name,
+			info->line, info->addr, info->irq);
+#else
+		printk("%s%d at 0x%04x (irq = %d)", mcfrs_serial_driver.name,
+			info->line, info->addr, info->irq);
+#endif  /* defined(CONFIG_DEVFS_FS) */
+		printk(" is a builtin ColdFire UART\n");
+	}
+
+	restore_flags(flags);
+	return 0;
+}
+
+module_init(mcfrs_init);
+/* module_exit(mcfrs_fini); */
+
+/****************************************************************************/
+/*                          Serial Console                                  */
+/****************************************************************************/
+
+/*
+ *	Quick and dirty UART initialization, for console output.
+ */
+
+void mcfrs_init_console(void)
+{
+	volatile unsigned char	*uartp;
+	unsigned int		clk;
+#ifdef	CONFIG_M5272
+	unsigned int		fraction;
+#endif
+
+	/*
+	 *	Reset UART, get it into known state...
+	 */
+	uartp = (volatile unsigned char *) (MCF_MBAR +
+		(mcfrs_console_port ? MCFUART_BASE2 : MCFUART_BASE1));
+
+	uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX;  /* reset RX */
+	uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX;  /* reset TX */
+	uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETMRPTR;  /* reset MR pointer */
+
+	/*
+	 * Set port for defined baud , 8 data bits, 1 stop bit, no parity.
+	 */
+	uartp[MCFUART_UMR] = MCFUART_MR1_PARITYNONE | MCFUART_MR1_CS8;
+	uartp[MCFUART_UMR] = MCFUART_MR2_STOP1;
+
+	/* compute the baudrate clock */
+#ifdef	CONFIG_M5272
+	/*
+	 * For the MCF5272, also compute the baudrate fraction.
+	 */
+	clk = (MCF_BUSCLK / mcfrs_console_baud) / 32;
+	fraction = MCF_BUSCLK - (clk * 32 * mcfrs_console_baud);
+	fraction *= 16;
+	fraction /= (32 * mcfrs_console_baud);
+#else
+	clk = ((MCF_BUSCLK / mcfrs_console_baud) + 16) / 32; /* set baud */
+#endif
+
+	uartp[MCFUART_UBG1] = (clk & 0xff00) >> 8;	/* set msb baud */
+	uartp[MCFUART_UBG2] = (clk & 0xff);		/* set lsb baud */
+#ifdef	CONFIG_M5272
+	uartp[MCFUART_UFPD] = (fraction & 0xf);		/* set fraction */
+#endif	
+	uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER;
+	uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE;
+
+	mcfrs_console_inited++;
+	return;
+}
+
+
+/*
+ *	Setup for console. Argument comes from the boot command line.
+ */
+
+int mcfrs_console_setup(struct console *cp, char *arg)
+{
+	int		i, n = CONSOLE_BAUD_RATE;
+
+	if (!cp)
+		return(-1);
+
+	if (!strncmp(cp->name, "ttyS", 4))
+		mcfrs_console_port = cp->index;
+	else if (!strncmp(cp->name, "cua", 3))
+		mcfrs_console_port = cp->index;
+	else
+		return(-1);
+
+	if (arg)
+		n = simple_strtoul(arg,NULL,0);
+	for (i = 0; i < MCFRS_BAUD_TABLE_SIZE; i++)
+		if (mcfrs_baud_table[i] == n)
+			break;
+	if (i < MCFRS_BAUD_TABLE_SIZE) {
+		mcfrs_console_baud = n;
+		mcfrs_console_cbaud = 0;
+		if (i > 15) {
+			mcfrs_console_cbaud |= CBAUDEX;
+			i -= 15;
+		}
+		mcfrs_console_cbaud |= i;
+	}
+	mcfrs_init_console(); /* make sure baud rate changes */
+	return(0);
+}
+
+
+static kdev_t mcfrs_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+
+/*
+ *	Output a single character, using UART polled mode.
+ *	This is used for console output.
+ */
+
+void mcfrs_put_char(char ch)
+{
+	volatile unsigned char	*uartp;
+	unsigned long		flags;
+	int			i;
+
+	uartp = (volatile unsigned char *) (MCF_MBAR +
+		(mcfrs_console_port ? MCFUART_BASE2 : MCFUART_BASE1));
+
+	save_flags(flags); cli();
+	for (i = 0; (i < 0x10000); i++) {
+		if (uartp[MCFUART_USR] & MCFUART_USR_TXREADY)
+			break;
+	}
+	if (i < 0x10000) {
+		uartp[MCFUART_UTB] = ch;
+		for (i = 0; (i < 0x10000); i++)
+			if (uartp[MCFUART_USR] & MCFUART_USR_TXEMPTY)
+				break;
+	}
+	if (i >= 0x10000)
+		mcfrs_init_console(); /* try and get it back */
+	restore_flags(flags);
+
+	return;
+}
+
+
+/*
+ * rs_console_write is registered for printk output.
+ */
+
+void mcfrs_console_write(struct console *cp, const char *p, unsigned len)
+{
+	if (!mcfrs_console_inited)
+		mcfrs_init_console();
+	while (len-- > 0) {
+		if (*p == '\n')
+			mcfrs_put_char('\r');
+		mcfrs_put_char(*p++);
+	}
+}
+
+/*
+ * declare our consoles
+ */
+
+struct console mcfrs_console = {
+	name:		"ttyS",
+	write:		mcfrs_console_write,
+	read:		NULL,
+	device:		mcfrs_console_device,
+	unblank:	NULL,
+	setup:		mcfrs_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+	cflag:		0,
+	next:		NULL
+};
+
+void __init mcfrs_console_init(void)
+{
+	register_console(&mcfrs_console);
+}
+
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/char/mcfserial.h linux-2.4.29-uc1/drivers/char/mcfserial.h
--- linux-2.4.29/drivers/char/mcfserial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/mcfserial.h	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,84 @@
+/*
+ * mcfserial.c -- serial driver for ColdFire internal UARTS.
+ *
+ * Copyright (c) 1999 Greg Ungerer <gerg@snapgear.com>
+ * Copyright (c) 2000-2001 Lineo, Inc. <www.lineo.com>
+ * Copyright (c) 2002 SnapGear Inc., <www.snapgear.com>
+ *
+ * Based on code from 68332serial.c which was:
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1998 TSHG
+ * Copyright (c) 1999 Rt-Control Inc. <jeff@uclinux.org>
+ */ 
+#ifndef _MCF_SERIAL_H
+#define _MCF_SERIAL_H
+
+#include <linux/config.h>
+#include <linux/serial.h>
+
+#ifdef __KERNEL__
+
+/*
+ *	Define a local serial stats structure.
+ */
+
+struct mcf_stats {
+	unsigned int	rx;
+	unsigned int	tx;
+	unsigned int	rxbreak;
+	unsigned int	rxframing;
+	unsigned int	rxparity;
+	unsigned int	rxoverrun;
+};
+
+
+/*
+ * This is our internal structure for each serial port's state.
+ * Each serial port has one of these structures associated with it.
+ */
+
+struct mcf_serial {
+	int			magic;
+	unsigned int		addr;		/* UART memory address */
+	int			irq;
+	int			flags; 		/* defined in tty.h */
+	int			type; 		/* UART type */
+	struct tty_struct 	*tty;
+	unsigned char		imr;		/* Software imr register */
+	unsigned int		baud;
+	int			sigs;
+	int			custom_divisor;
+	int			x_char;	/* xon/xoff character */
+	int			baud_base;
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	unsigned long		event;
+	int			line;
+	int			count;	    /* # of fd on device */
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+	unsigned char 		*xmit_buf;
+	int			xmit_head;
+	int			xmit_tail;
+	int			xmit_cnt;
+	struct mcf_stats	stats;
+	struct tq_struct	tqueue;
+	struct tq_struct	tqueue_hangup;
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+#if LINUX_VERSION_CODE <= 0x020100
+	struct wait_queue	*open_wait;
+	struct wait_queue	*close_wait;
+#else
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+#endif
+
+};
+
+#endif /* __KERNEL__ */
+
+#endif /* _MCF_SERIAL_H */
diff -urN linux-2.4.29/drivers/char/mcf_usb.c linux-2.4.29-uc1/drivers/char/mcf_usb.c
--- linux-2.4.29/drivers/char/mcf_usb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/mcf_usb.c	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,2273 @@
+/*********************************************************************
+ *
+ * Copyright:
+ *	MOTOROLA, INC. All Rights Reserved.  
+ *  You are hereby granted a copyright license to use, modify, and
+ *  distribute the SOFTWARE so long as this entire notice is
+ *  retained without alteration in any modified and/or redistributed
+ *  versions, and that such modified versions are clearly identified
+ *  as such. No licenses are granted by implication, estoppel or
+ *  otherwise under any patents or trademarks of Motorola, Inc. This 
+ *  software is provided on an "AS IS" basis and without warranty.
+ *
+ *  To the maximum extent permitted by applicable law, MOTOROLA 
+ *  DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING 
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+ *  PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH REGARD TO THE 
+ *  SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) AND ANY 
+ *  ACCOMPANYING WRITTEN MATERIALS.
+ * 
+ *  To the maximum extent permitted by applicable law, IN NO EVENT
+ *  SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING 
+ *  WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS 
+ *  INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY
+ *  LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.   
+ * 
+ *  Motorola assumes no responsibility for the maintenance and support
+ *  of this software
+ ********************************************************************/
+
+/* Purpose:	Device Driver for MCF5272 USB module
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>   /* We're doing kernel work */
+#include <linux/malloc.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <asm/coldfire.h>
+#include <linux/version.h>
+
+#ifdef MODULE
+#include <linux/module.h>   /* We need it if driver acts like a module */
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
+#include "mcf_usb_defs.h"
+#include "mcf5272.h"
+#include "mcf_usb.h"
+#include "mcf_descriptors.h"
+
+//#define DEBUG
+
+/* Deal with CONFIG_MODVERSIONS */
+#if CONFIG_MODVERSIONS==1
+#define MODVERSIONS
+#include <linux/modversions.h>
+#endif
+
+#include <linux/wrapper.h>
+
+/* In 2.2.3 linux/version.h includes
+ * a macro for this, but 2.0.xx doesn't - so I add
+ * it here if necessary. */
+#ifndef KERNEL_VERSION
+#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))
+#endif
+
+#define mcf5272_get_immp()     ((MCF5272_IMM *)(MCF_MBAR))
+
+/***************************************************************/
+/* We need it for compatability with different kernel versions */
+/***************************************************************/
+/* Conditional compilation. LINUX_VERSION_CODE is
+ * the code (as per KERNEL_VERSION) of this version. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+/* Copy data from user address space to kernel. */
+#define GET_RDEV(filp)				((filp)->f_dentry->d_inode->i_rdev)
+#define usb_kill_fasync(async_queue, sig)	(kill_fasync(&async_queue, sig, POLL_IN));
+#else
+#define GET_RDEV(filp)				((filp)->f_inode->i_rdev)
+#define usb_kill_fasync(async_queue, sig)	(kill_fasync(async_queue, sig));
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
+#define DECLARE_WAIT_QUEUE_HEAD(head) struct wait_queue *head = NULL
+typedef struct wait_queue *wait_queue_head_t;
+#endif
+/***************************************************************/
+
+/* Wait queue for fetch_command function */
+DECLARE_WAIT_QUEUE_HEAD(fetch_command_queue);
+/* Wait queue for ep_wait function */
+DECLARE_WAIT_QUEUE_HEAD(ep_wait_queue);
+/* Structure for asynchronous notification */
+struct fasync_struct *usb_async_queue;
+/********************************************************************/
+
+/* Global Endpoint Status Structures */
+USB_EP_STATE ep[NUM_ENDPOINTS];
+USB_ISO_EP_STATE iso_ep[NUM_ENDPOINTS];
+
+/* Pointer to device descriptor */
+uint8 * usb_device_descriptor;
+
+/* Events mask */
+uint32 usb_event=0;
+/* Contains information about current configuration */
+CONFIG_STATUS current_config;
+
+/* Global pointer used to access the command */
+DEVICE_COMMAND * NewC = NULL;
+
+/* Indicates which endpoints are already opened */
+uint8 active_ep_mask = 0;
+
+/* Global pointer to IMM */
+MCF5272_IMM *imm = mcf5272_get_immp();
+
+/*************************USB_INIT******************************/
+void 
+usb_init(DESC_INFO * descriptor_info)
+{
+	uint32 i, DescSize;
+	uint32 *pConfigRam;
+	uint32 *pDevDesc;
+	uint32 reg;
+
+	/* Get device descriptor's address from user space */
+	usb_device_descriptor = descriptor_info -> pDescriptor;
+
+	/* Initialize Descriptor pointers and variables */
+	pConfigRam = (uint32 *)((uint32)imm + MCF5272_USB_CFG_RAM);
+	pDevDesc = (uint32*)usb_device_descriptor;
+	DescSize = descriptor_info -> DescSize + 3;
+
+	/* Initialize Endpoint status structures */
+	ep[0].ttype = CONTROL;
+	ep[0].packet_size = ((USB_DEVICE_DESC *)pDevDesc)->bMaxPacketSize0;
+	ep[0].fifo_length = (uint16)(ep[0].packet_size * FIFO_DEPTH);
+	ep[0].buffer.start = 0;
+	ep[0].buffer.length = 0;
+	ep[0].buffer.position = 0;
+	ep[0].state = USB_CONFIGURED;
+	ep[0].sendZLP = FALSE;
+
+	/* Set the EP0 IN-BUSY bit -- This is only required on
+	   pre-2K75N masks. This bit is set by HW beginning with
+	   the 2K75N silicon. */
+	MCF5272_WR_USB_EP0CTL(imm, MCF5272_RD_USB_EP0CTL(imm)
+		| MCF5272_USB_EP0CTL_IN_BUSY);
+	
+	for (i = 1; i < NUM_ENDPOINTS; i++)
+		ep[i].ttype = DISABLED;
+
+	/* Invalidate Configuration RAM and disable Endpoint 0 */
+	MCF5272_WR_USB_EP0CTL(imm, 0);
+
+	/* Load the Configuration RAM with the descriptors */
+	for (i = 0; i < (DescSize/4); i++)
+		pConfigRam[i] = pDevDesc[i];
+
+	/* Initialize FIFOs */
+	usb_fifo_init();
+
+	/* Initialize the Interrupts */
+	usb_isr_init();
+
+	/* Enable USB controller, Config RAM, EXT AFE */
+#ifdef DEBUG
+	MCF5272_WR_USB_EP0CTL(imm, 0
+		| MCF5272_USB_EP0CTL_DEBUG
+		| MCF5272_USB_EP0CTL_AFE_EN	/*	*/
+		| MCF5272_USB_EP0CTL_USB_EN
+		| MCF5272_USB_EP0CTL_CFG_RAM_VAL);
+#else
+	MCF5272_WR_USB_EP0CTL(imm, 0
+		| MCF5272_USB_EP0CTL_AFE_EN	/*	*/
+		| MCF5272_USB_EP0CTL_USB_EN
+		| MCF5272_USB_EP0CTL_CFG_RAM_VAL);
+#endif
+        /* Enable USB signals */
+	reg = (MCF5272_RD_GPIO_PACNT (imm) & ~0x3fff) | 0x1555;
+        MCF5272_WR_GPIO_PACNT (imm, reg);
+
+        /* Configure all USB pins as inputs */
+	reg = MCF5272_RD_GPIO_PADDR (imm) & ~0x7f;
+        MCF5272_WR_GPIO_PADDR (imm, reg);
+	
+}
+/***********************USB_INIT  end********************************/
+void 
+usb_isr_init(void)
+{
+	/* Clear any pending interrupts in all Endpoints */
+	MCF5272_WR_USB_EP0ISR(imm, 0x0001FFFF);
+	MCF5272_WR_USB_EP1ISR(imm, 0x001F);
+	MCF5272_WR_USB_EP2ISR(imm, 0x001F);
+	MCF5272_WR_USB_EP3ISR(imm, 0x001F);
+	MCF5272_WR_USB_EP4ISR(imm, 0x001F);
+	MCF5272_WR_USB_EP5ISR(imm, 0x001F);
+	MCF5272_WR_USB_EP6ISR(imm, 0x001F);
+	MCF5272_WR_USB_EP7ISR(imm, 0x001F);
+
+	/* Enable all interrupts on all Endpoints */
+	/* These will be altered on configuration/interface changes */
+	/* Enable desired interrupts on EP0 */
+	MCF5272_WR_USB_EP0IMR(imm, 0
+		| MCF5272_USB_EP0IMR_DEV_CFG_EN
+		| MCF5272_USB_EP0IMR_VEND_REQ_EN
+		| MCF5272_USB_EP0IMR_WAKE_CHG_EN
+		| MCF5272_USB_EP0IMR_RESUME_EN
+		| MCF5272_USB_EP0IMR_SUSPEND_EN
+		| MCF5272_USB_EP0IMR_RESET_EN
+		| MCF5272_USB_EP0IMR_OUT_EOT_EN
+		| MCF5272_USB_EP0IMR_OUT_EOP_EN
+		| MCF5272_USB_EP0IMR_IN_EOT_EN
+		| MCF5272_USB_EP0IMR_IN_EOP_EN
+		| MCF5272_USB_EP0IMR_UNHALT_EN
+		| MCF5272_USB_EP0IMR_HALT_EN
+		| MCF5272_USB_EP0IMR_SOF_EN);
+
+	MCF5272_WR_USB_EP1IMR(imm, 0x001F);
+	MCF5272_WR_USB_EP2IMR(imm, 0x001F);
+	MCF5272_WR_USB_EP3IMR(imm, 0x001F);
+	MCF5272_WR_USB_EP4IMR(imm, 0x001F);
+	MCF5272_WR_USB_EP5IMR(imm, 0x001F);
+	MCF5272_WR_USB_EP6IMR(imm, 0x001F);
+	MCF5272_WR_USB_EP7IMR(imm, 0x001F);
+
+	/* Initialize Interrupt Control Registers */
+	MCF5272_WR_SIM_ICR2(imm, 0
+		| (0x00008888)
+		| (USB_EP0_LEVEL << 12) 
+		| (USB_EP1_LEVEL << 8) 
+		| (USB_EP2_LEVEL << 4) 
+		| (USB_EP3_LEVEL << 0));
+	MCF5272_WR_SIM_ICR3(imm, 0
+		| (0x88880000)
+		| (USB_EP4_LEVEL << 28) 
+		| (USB_EP5_LEVEL << 24) 
+		| (USB_EP6_LEVEL << 20) 
+		| (USB_EP7_LEVEL << 16));
+}
+
+/********************************************************************/
+void 
+usb_endpoint0_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+uint32 event;
+
+	event = MCF5272_RD_USB_EP0ISR(imm) & MCF5272_RD_USB_EP0IMR(imm);
+
+	if (event & MCF5272_USB_EP0ISR_SOF)
+	{
+		/* Clear this interrupt bit */
+		MCF5272_WR_USB_EP0ISR(imm, MCF5272_USB_EP0ISR_SOF);
+
+		usb_isochronous_transfer_service();
+		
+	}
+
+	if (event & MCF5272_USB_EP0ISR_DEV_CFG)
+	{
+		usb_devcfg_service();
+		/* Clear this interrupt bit */
+		MCF5272_WR_USB_EP0ISR(imm, MCF5272_USB_EP0ISR_DEV_CFG);
+	}
+	if (event & MCF5272_USB_EP0ISR_VEND_REQ)
+	{
+		/* Clear this interrupt bit */
+		MCF5272_WR_USB_EP0ISR(imm, MCF5272_USB_EP0ISR_VEND_REQ);
+
+		usb_vendreq_service(
+			(uint8)(MCF5272_RD_USB_DRR1(imm) & 0xFF),
+			(uint8)(MCF5272_RD_USB_DRR1(imm) >> 8),
+			(uint16)(MCF5272_RD_USB_DRR1(imm) >> 16),
+			(uint16)(MCF5272_RD_USB_DRR2(imm) & 0xFFFF),
+			(uint16)(MCF5272_RD_USB_DRR2(imm) >> 16));
+
+	}
+		
+	if (event & MCF5272_USB_EP0ISR_FRM_MAT)
+	{
+		/* Clear this interrupt bit */
+		MCF5272_WR_USB_EP0ISR(imm, MCF5272_USB_EP0ISR_FRM_MAT);
+	}
+	if (event & MCF5272_USB_EP0ISR_ASOF)
+	{
+		/* Clear this interrupt bit */
+		MCF5272_WR_USB_EP0ISR(imm, MCF5272_USB_EP0ISR_ASOF);
+	}
+
+	if (event & MCF5272_USB_EP0ISR_WAKE_CHG)
+	{
+        if (MCF5272_RD_USB_EP0SR(imm) & MCF5272_USB_EP0SR_WAKE_ST)
+        {
+            /* Enable Wake-on-Ring */
+            MCF5272_WR_USB_EP0CTL(imm,
+                  MCF5272_RD_USB_EP0CTL(imm)
+                | MCF5272_USB_EP0CTL_WOR_EN);
+            /* Wake-on-Ring function is invoked when /INT1 pin is 0 */
+            MCF5272_WR_USB_EP0CTL(imm, MCF5272_RD_USB_EP0CTL(imm)
+                & ~MCF5272_USB_EP0CTL_WOR_LVL);
+        }
+        else
+        {
+			/* Disable Wake-on-Ring */
+			MCF5272_WR_USB_EP0CTL(imm,
+				   MCF5272_RD_USB_EP0CTL(imm)
+				& ~MCF5272_USB_EP0CTL_WOR_EN);
+        }
+        /* Clear this interrupt bit */
+		MCF5272_WR_USB_EP0ISR(imm, MCF5272_USB_EP0ISR_WAKE_CHG);
+	}
+	if (event & MCF5272_USB_EP0ISR_RESUME)
+	{
+	        usb_bus_state_chg_service(RESUME);
+		/* Clear this interrupt bit */
+		MCF5272_WR_USB_EP0ISR(imm, MCF5272_USB_EP0ISR_RESUME);
+	}
+	if (event & MCF5272_USB_EP0ISR_SUSPEND)
+	{
+	        if (MCF5272_RD_USB_EP0SR(imm) & MCF5272_USB_EP0SR_WAKE_ST)
+	            usb_bus_state_chg_service(SUSPEND | ENABLE_WAKEUP);
+	        else
+	            usb_bus_state_chg_service(SUSPEND);
+		/* Clear this interrupt bit */
+		MCF5272_WR_USB_EP0ISR(imm, MCF5272_USB_EP0ISR_SUSPEND);
+	}
+	if (event & MCF5272_USB_EP0ISR_RESET)
+	{
+	        usb_bus_state_chg_service(RESET);
+		/* Clear this interrupt bit */
+		MCF5272_WR_USB_EP0ISR(imm, MCF5272_USB_EP0ISR_RESET);
+	}
+	if (event & ( MCF5272_USB_EP0ISR_OUT_EOT
+				| MCF5272_USB_EP0ISR_OUT_EOP
+				| MCF5272_USB_EP0ISR_OUT_LVL))
+	{
+		usb_out_service(0, event);
+	}
+	if (event & ( MCF5272_USB_EP0ISR_IN_EOT
+				| MCF5272_USB_EP0ISR_IN_EOP
+				| MCF5272_USB_EP0ISR_IN_LVL))
+	{
+		usb_in_service(0, event);
+	}
+	if (event & MCF5272_USB_EP0ISR_UNHALT)
+	{
+		/* Clear this interrupt bit */
+		MCF5272_WR_USB_EP0ISR(imm, MCF5272_USB_EP0ISR_UNHALT);
+	}
+	if (event & MCF5272_USB_EP0ISR_HALT)
+	{
+		/* Clear this interrupt bit */
+		MCF5272_WR_USB_EP0ISR(imm, MCF5272_USB_EP0ISR_HALT);
+	}
+
+}
+/********************************************************************/
+void 
+usb_endpoint_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int event, epnum;
+	epnum = irq - 77;  /* Obtain endpoint number from interrupt number */
+
+	event = MCF5272_RD_USB_EPISR(imm, epnum) 
+		  & MCF5272_RD_USB_EPIMR(imm, epnum);
+
+	if (event & ( MCF5272_USB_EPNISR_EOT	
+				| MCF5272_USB_EPNISR_EOP
+				| MCF5272_USB_EPNISR_FIFO_LVL))
+	{
+		/* IN Endpoint */
+		if (MCF5272_RD_USB_EPISR(imm, epnum) & MCF5272_USB_EPNISR_DIR)
+			usb_in_service(epnum, event);
+		/* OUT Endpoint */
+		else
+			usb_out_service(epnum,event);
+	}
+	if (event & MCF5272_USB_EPNISR_HALT)
+	{
+		usb_ep_halt(epnum);
+		MCF5272_WR_USB_EPISR(imm, epnum, MCF5272_USB_EPNISR_HALT);
+	}
+	if (event & MCF5272_USB_EPNISR_UNHALT)
+	{
+		usb_ep_unhalt(epnum);
+		MCF5272_WR_USB_EPISR(imm, epnum, MCF5272_USB_EPNISR_UNHALT);
+	}
+
+}
+/********************************************************************/
+inline uint32
+usb_get_request(uint32 epnum)
+{
+	/* Check for requests in requests queue */
+	if (iso_ep[epnum].number_of_requests > 0)
+	{
+	    /* Extract next request from the queue */
+	    iso_ep[epnum].number_of_requests--;
+
+	    /* Set up the iso_ep and buffer structures */
+	    ep[epnum].buffer.length = iso_ep[epnum].requests_queue[iso_ep[epnum].first_io_request].length;
+	    iso_ep[epnum].packet_length = (uint32*) iso_ep[epnum].requests_queue[iso_ep[epnum].first_io_request].start;
+	    ep[epnum].buffer.start = (uint8*)iso_ep[epnum].packet_length + 4 * ep[epnum].buffer.length;
+				    
+	    ep[epnum].buffer.position = 0;
+	    iso_ep[epnum].frame_counter = 0;
+
+	    /* Modify first_io_request index */
+	    if (++iso_ep[epnum].first_io_request >= MAX_IO_REQUESTS)
+		iso_ep[epnum].first_io_request = 0;
+	    
+	    return TRUE;
+
+	} else
+	    return FALSE;
+}
+/********************************************************************/
+void
+usb_in_service(uint32 epnum, uint32 event)
+{
+int32 i;
+int32 free_space = 0;
+uint32 imr_mask;
+uint32 remainder, length;
+
+	/* Save mask register and disable RESET, DEV_CFG, and SOF interrupts on endpoint 0 */
+	imr_mask = MCF5272_RD_USB_EP0IMR(imm);
+	MCF5272_WR_USB_EP0IMR(imm, imr_mask & ~(MCF5272_USB_EP0ISR_RESET
+						| MCF5272_USB_EP0ISR_DEV_CFG
+						| MCF5272_USB_EP0ISR_SOF));
+
+	if (event & MCF5272_USB_EPNISR_EOP)
+	{
+		/* Clear the EOP interrupt bits */
+		MCF5272_WR_USB_EPISR(imm, epnum, MCF5272_USB_EPNISR_EOP);
+		
+		if ((ep[epnum].ttype == ISOCHRONOUS) && (MCF5272_RD_USB_EPDPR(imm, epnum) == 0))
+		{
+			if (iso_ep[epnum].transfer_monitoring == TRUE)
+				/* EOP interrupt occured, so clear sent_packet_watch variable */
+				iso_ep[epnum].sent_packet_watch = 0;
+
+			iso_ep[epnum].frame_counter ++;
+			/* Increase packet_position by the size of next packet */
+			iso_ep[epnum].packet_position += iso_ep[epnum].packet_length[iso_ep[epnum].frame_counter];
+
+			/* Check if sent packet was the last in current buffer */
+			if (iso_ep[epnum].frame_counter >= ep[epnum].buffer.length)
+			{
+				/* Check for requests in requests queue */
+				if (usb_get_request(epnum))
+				    /* Initialize packet_position with the size of first packet in buffer */
+				    iso_ep[epnum].packet_position = iso_ep[epnum].packet_length[0];
+				else
+				{
+				    /* There are no requests in a queue, so we can free buffer structure */
+				    ep[epnum].buffer.start = 0;
+				    ep[epnum].buffer.length = 0;
+				    ep[epnum].buffer.position = 0;
+			
+				    iso_ep[epnum].packet_position = 0;
+				}
+
+				/* Buffer is sent - wake up usb_ep_wait function */
+				wake_up_interruptible(&ep_wait_queue);
+			}
+		}
+	}
+
+	if (event & (MCF5272_USB_EPNISR_EOP | MCF5272_USB_EPNISR_FIFO_LVL))
+	{
+		/* Clear this FIFO_LVL interrupt bit */
+		MCF5272_WR_USB_EPISR(imm, epnum, MCF5272_USB_EPNISR_FIFO_LVL);
+	
+		i = ep[epnum].buffer.position;
+
+		if (ep[epnum].ttype == ISOCHRONOUS)
+			length = iso_ep[epnum].packet_position;
+		else
+			length = ep[epnum].buffer.length;
+
+		if (i < length)
+		{
+			/* USBEPDP0 only monitors the OUT FIFO */
+			if (epnum == 0)
+				free_space = ep[0].packet_size;
+			else
+				free_space = (uint16)(ep[epnum].fifo_length - MCF5272_RD_USB_EPDPR(imm, epnum));
+			/* If the amount of the rest of data to be sent less than free_space, modify free_space */
+			if (free_space > (length - ep[epnum].buffer.position))
+				free_space = (length - ep[epnum].buffer.position);
+				
+			free_space += i;
+			free_space -= 3;
+			
+			/* Write to FIFO by 4 bytes */
+			while (i < free_space)
+			{
+				/* We use here advantages of MMU-less CPU.
+				   Data is copied directly to user's memory space */
+				MCF5272_WR_USB_EPDR(imm, epnum, 32, *(uint32 *)(&ep[epnum].buffer.start[i]));
+				i += 4;
+			}
+			
+			free_space += 3;
+			
+			/* Write to FIFO by 1 byte */
+			while (i < free_space)
+			{
+				MCF5272_WR_USB_EPDR(imm,epnum,8,ep[epnum].buffer.start[i]);
+				i++;
+			}
+		
+			ep[epnum].buffer.position = i;
+		}
+						
+		if (ep[epnum].ttype != ISOCHRONOUS)
+		{
+			/* Is it all data to send ? */
+			if ((ep[epnum].buffer.start) && (i == ep[epnum].buffer.length))
+			{
+				remainder = i % ep[epnum].packet_size;
+			
+				/* Send short packet (if buffer length isn't multiple to packet size) or 
+					zero-length packet, if sendZLP field is set */
+				if ((remainder != 0) || ((remainder == 0) && ep[epnum].sendZLP))
+				{
+					/* All done -> Clear the IN-DONE bit */
+					MCF5272_WR_USB_EPCTL(imm, epnum, 
+							MCF5272_RD_USB_EPCTL(imm, epnum)
+							& ~MCF5272_USB_EPNCTL_IN_DONE);
+				}
+				else
+					if (MCF5272_RD_USB_EPDPR(imm, epnum) == 0)
+					{
+						/* Is it a completion of data IN stage command? */
+						if ((epnum == 0) && (NewC))
+						{
+							usb_vendreq_done(SUCCESS);
+								
+							kfree(NewC);
+							NewC = NULL;
+							
+						}
+
+						ep[epnum].bytes_transferred = i;
+
+						ep[epnum].buffer.start = 0;
+						ep[epnum].buffer.length = 0;
+						ep[epnum].buffer.position = 0;
+
+						/* Wake up usb_ep_wait function if it sleeps */
+						wake_up_interruptible(&ep_wait_queue);
+					}
+
+					ep[epnum].sendZLP = FALSE;
+			}
+		}
+	}
+	
+	if (event & MCF5272_USB_EPNISR_EOT)
+	{
+		MCF5272_WR_USB_EPISR(imm, epnum, 0
+			| MCF5272_USB_EPNISR_EOT);
+			
+		/* Is it a completion of data IN stage command? */
+		if ((epnum == 0) && (NewC))
+		{
+			usb_vendreq_done(SUCCESS);
+			
+			kfree(NewC);
+			NewC = NULL;
+		}
+		ep[epnum].bytes_transferred = ep[epnum].buffer.length;
+
+		ep[epnum].buffer.start = 0;
+		ep[epnum].buffer.length = 0;
+		ep[epnum].buffer.position = 0;
+
+		/* Set the IN-DONE bit
+		   This is only required on pre-2K75N masks. This bit is set by 
+		   HW beginning with the 2K75N silicon. */
+		MCF5272_WR_USB_EPCTL(imm, epnum, MCF5272_RD_USB_EPCTL(imm, epnum) 
+			| MCF5272_USB_EPNCTL_IN_DONE);
+
+		/* Wake up usb_ep_wait function if it sleeps */
+		wake_up_interruptible(&ep_wait_queue);
+	}
+	/* Restore IMR */
+	MCF5272_WR_USB_EP0IMR(imm, imr_mask);
+}
+/********************************************************************/
+void
+usb_out_service(uint32 epnum, uint32 event)
+{
+int32 i, fifo_data;
+int32 bytes_read=0;
+uint32 imr_mask;
+
+	/* Save interrupt mask register */
+	imr_mask = MCF5272_RD_USB_EP0IMR(imm);
+	/* Disable RESET, DEV_CFG, and SOF interrupts */
+	MCF5272_WR_USB_EP0IMR(imm, imr_mask & ~(MCF5272_USB_EP0ISR_RESET
+					| MCF5272_USB_EP0ISR_DEV_CFG
+					| MCF5272_USB_EP0ISR_SOF));
+					
+	if (event & (MCF5272_USB_EP0ISR_OUT_EOP
+				| MCF5272_USB_EPNISR_EOP
+				| MCF5272_USB_EPNISR_FIFO_LVL))
+	{
+		/* Clear the LVL interrupt bits */
+		MCF5272_WR_USB_EPISR(imm, epnum, 0 
+			| MCF5272_USB_EPNISR_FIFO_LVL);
+		/* Clear the EOP interrupt bits */
+		MCF5272_WR_USB_EPISR(imm, epnum, 0 
+			| MCF5272_USB_EP0ISR_OUT_EOP
+			| MCF5272_USB_EPNISR_EOP);
+
+		/* Read the Data Present register */
+		fifo_data = MCF5272_RD_USB_EPDPR(imm, epnum);
+
+		if (ep[epnum].buffer.start)
+		{
+			if (ep[epnum].ttype == ISOCHRONOUS)
+			{
+			    /* Check if there are more data in FIFO than we need */
+			    if (iso_ep[epnum].packet_position + fifo_data >
+				iso_ep[epnum].packet_length[iso_ep[epnum].frame_counter])
+				fifo_data = iso_ep[epnum].packet_length[iso_ep[epnum].frame_counter]
+					    - iso_ep[epnum].packet_position;
+			}
+			else
+			    /* Check if there are more data in FIFO than we need */
+			    if (ep[epnum].buffer.position + fifo_data > ep[epnum].buffer.length)
+				fifo_data = ep[epnum].buffer.length - ep[epnum].buffer.position;
+		}
+
+		/* In isochronous transfer handle the situation when device-side client
+		   application did not allocate buffer in time */
+		if ((ep[epnum].ttype == ISOCHRONOUS) &&
+		    ((ep[epnum].buffer.start == 0) || (iso_ep[epnum].state == MISS_PACKET)))
+		{
+			/* Clear FIFO buffer */
+			MCF5272_WR_USB_EPCFG(imm, epnum, MCF5272_RD_USB_EPCFG(imm, epnum));
+
+			if (event & MCF5272_USB_EPNISR_FIFO_LVL)
+				iso_ep[epnum].state = MISS_PACKET;
+
+			if (event & MCF5272_USB_EPNISR_EOP)
+				iso_ep[epnum].state = DEFAULT;
+			
+			/* It is nothing to read anymore */
+			fifo_data = 0;
+		}
+		
+		bytes_read = fifo_data;
+
+		if (ep[epnum].buffer.start)
+		{
+			/* Read the data from the FIFO into the buffer */
+			i = ep[epnum].buffer.position;
+			
+			fifo_data += i;
+			fifo_data -= 3;
+			
+			/* Read data from FIFO by 4 bytes */
+			while (i < fifo_data)
+			{
+				*((uint32 *)(&ep[epnum].buffer.start[i])) = MCF5272_RD_USB_EPDR(imm, epnum,32);
+				i += 4;
+			}
+			
+			fifo_data += 3;
+			
+			/* Read rest of data from FIFO by 1 byte */
+			while (i < fifo_data)
+			{
+				ep[epnum].buffer.start[i] = MCF5272_RD_USB_EPDR(imm, epnum,8);
+				i++;
+			}
+
+			ep[epnum].buffer.position = i;
+		}
+
+		if (ep[epnum].buffer.start)
+		{
+			if (ep[epnum].ttype == ISOCHRONOUS)
+			{
+				/* packet_position contains the number of bytes read
+				   in current frame */
+				iso_ep[epnum].packet_position += bytes_read;
+
+				if (event & MCF5272_USB_EPNISR_EOP)
+				{
+				    if (iso_ep[epnum].transfer_monitoring == TRUE)
+					    /* Indicate that EOP interrupt occured in this frame */
+					    iso_ep[epnum].sent_packet_watch = 0;
+
+				    /* Save the number of bytes that we have read */
+				    iso_ep[epnum].packet_length[iso_ep[epnum].frame_counter] = iso_ep[epnum].packet_position;
+				    iso_ep[epnum].packet_position = 0;
+
+				    iso_ep[epnum].frame_counter ++;
+
+				    /* Clear FIFO buffer for the case when client asks
+				       to read less then we received */
+				    MCF5272_WR_USB_EPCFG(imm, epnum, MCF5272_RD_USB_EPCFG(imm, epnum));
+
+				    /* Check if it was the last packet in current buffer */
+				    if (iso_ep[epnum].frame_counter == ep[epnum].buffer.length)
+				    {
+					/* Extract next request from the queue */
+					if (!usb_get_request(epnum))
+					{
+						/* There are no requests in a queue, so we can free buffer structure */
+						ep[epnum].buffer.start = 0;
+						ep[epnum].buffer.length = 0;
+						ep[epnum].buffer.position = 0;
+					}
+					/* Buffer is sent - wake up usb_ep_wait function */
+					wake_up_interruptible(&ep_wait_queue);
+				    }
+				}
+			}
+			else
+			/* If given number of bytes is received, complete the transfer */
+			if (ep[epnum].buffer.position == ep[epnum].buffer.length)
+			{
+				if ((epnum == 0) && (NewC))
+				{
+					/* We have got a new command and can wake up fetch_command routine */
+					wake_up_interruptible(&fetch_command_queue);
+					/* and notify client about it */
+					if (usb_async_queue) usb_kill_fasync(usb_async_queue, SIGIO);
+				}
+				else
+				{
+					ep[epnum].bytes_transferred = ep[epnum].buffer.length;
+				}
+				ep[epnum].buffer.start = 0;
+				ep[epnum].buffer.length = 0;
+				ep[epnum].buffer.position = 0;
+				/* Wake up usb_ep_wait function if it sleeps */
+				wake_up_interruptible(&ep_wait_queue);
+			}
+
+		}  /* if (ep[epnum].buffer.start) */
+		
+	} /* if (event &  (EPNISR_EOP | EPNISR_LVL)) */
+	
+	if (event & (MCF5272_USB_EP0ISR_OUT_EOT | MCF5272_USB_EPNISR_EOT))
+	{
+		/* The current transfer is complete */
+		/* Clear the EOT Interrupt bits */
+		MCF5272_WR_USB_EPISR(imm, epnum, 0
+			| MCF5272_USB_EP0ISR_OUT_EOT
+			| MCF5272_USB_EPNISR_EOT);
+	}
+
+	MCF5272_WR_USB_EP0IMR(imm, imr_mask);
+}
+/********************************************************************/
+uint32
+usb_tx_data(uint32 epnum, uint8 *start, uint32 length)
+{
+uint32 imr_mask, imr0_mask=0;
+int32 i = 0;
+int32 free_space;
+
+	/* Exit if device is reset */
+	if ((epnum !=0) && (ep[epnum].state == USB_DEVICE_RESET))
+			return -EIO;
+
+	/* See if non Isochronous EP is currently busy */
+	if ((ep[epnum].ttype != ISOCHRONOUS) && (ep[epnum].buffer.start))
+		return -EBUSY;
+
+	/* Make sure there is data to send */
+	if (!start)
+		return -EFAULT;
+	if (!length)
+		return 0;
+	/* Make sure this is an IN endpoint */
+	if (epnum && !(MCF5272_RD_USB_EPISR(imm, epnum) & MCF5272_USB_EPNISR_DIR))
+		return -EPERM;
+	/* Make sure this EP is not HALTed */
+	if (MCF5272_RD_USB_EPISR(imm, epnum) & MCF5272_USB_EPNISR_HALT)
+		return -EIO;
+
+	/* Save off the current IMR */
+	imr_mask = MCF5272_RD_USB_EPIMR(imm, epnum);
+
+	/* Clear the EOT, EOP, LVL mask bits */
+	if (epnum != 0)
+	{
+		MCF5272_WR_USB_EPIMR(imm, epnum, imr_mask & 
+			~(MCF5272_USB_EPNISR_EOT
+			| MCF5272_USB_EPNISR_EOP
+			| MCF5272_USB_EPNISR_FIFO_LVL));
+
+		imr0_mask = MCF5272_RD_USB_EPIMR(imm, 0);
+
+		MCF5272_WR_USB_EPIMR(imm, 0, imr0_mask & 
+			~(MCF5272_USB_EP0ISR_RESET
+			| MCF5272_USB_EP0ISR_DEV_CFG
+			| MCF5272_USB_EP0ISR_SOF));
+	}
+	else
+		MCF5272_WR_USB_EPIMR(imm, 0, imr_mask &
+			~(MCF5272_USB_EP0ISR_OUT_EOP
+			| MCF5272_USB_EPNISR_EOP
+			| MCF5272_USB_EP0ISR_OUT_EOT
+			| MCF5272_USB_EPNISR_EOT
+			| MCF5272_USB_EP0ISR_RESET
+			| MCF5272_USB_EP0ISR_DEV_CFG));
+
+	if (ep[epnum].buffer.start)
+	{
+	    /* Isochronous EP is currently busy, so enqueue this request */
+	    if (++iso_ep[epnum].number_of_requests >= MAX_IO_REQUESTS)
+	    {
+		iso_ep[epnum].number_of_requests--;
+		return -EBUSY;
+	    }
+	    if (++iso_ep[epnum].last_io_request >= MAX_IO_REQUESTS)
+		    iso_ep[epnum].last_io_request = 0;
+	    iso_ep[epnum].requests_queue[iso_ep[epnum].last_io_request].start = start;
+	    iso_ep[epnum].requests_queue[iso_ep[epnum].last_io_request].length = length;
+
+	    /* Restore saved imr_mask */
+	    MCF5272_WR_USB_EPIMR(imm, 0, imr0_mask);
+	    MCF5272_WR_USB_EPIMR(imm, epnum, imr_mask);
+	    return 0;
+	}
+
+	/* Setup the EP Buffer structure */
+	ep[epnum].buffer.start = start;
+	ep[epnum].buffer.length = length;
+	ep[epnum].buffer.position = 0;
+	
+	if (ep[epnum].ttype == ISOCHRONOUS)
+	{
+		iso_ep[epnum].frame_counter = 0;
+		iso_ep[epnum].packet_length = (uint32*) start;
+		/* Set up packet_position boundary */
+		iso_ep[epnum].packet_position = iso_ep[epnum].packet_length[0];
+		ep[epnum].buffer.start = start + 4 * length;
+
+		/* Check if first packet has to be skipped */
+		if (iso_ep[epnum].state == SKIP_FIRST_PACKET)
+		{
+			/* Indicate that packet was not sent. */
+			iso_ep[epnum].packet_length[0] = 0;
+			
+			/* Does buffer contain more than 1 packet ? */
+			if (ep[epnum].buffer.length > 1)
+			{
+				/* Stepover the first packet */
+				iso_ep[epnum].frame_counter = 1;
+				ep[epnum].buffer.position = iso_ep[epnum].packet_position;
+				iso_ep[epnum].packet_position += iso_ep[epnum].packet_length[1];
+
+				/* Clear state field */
+				iso_ep[epnum].state = DEFAULT;
+			}
+			else
+			{
+				/* It is nothing to send anymore. */
+				ep[epnum].buffer.start = 0;
+				ep[epnum].buffer.position = 0;
+				ep[epnum].buffer.length = 0;
+
+				iso_ep[epnum].packet_position = 0;
+				/* Wake up usb_ep_wait function */
+				wake_up_interruptible(&ep_wait_queue);
+
+				/* Restore saved imr_mask */
+				MCF5272_WR_USB_EPIMR(imm, 0, imr0_mask);
+				MCF5272_WR_USB_EPIMR(imm, epnum, imr_mask);
+				return 0;
+			}
+		}
+	}
+
+	free_space = (uint16)(ep[epnum].fifo_length - MCF5272_RD_USB_EPDPR(imm, epnum));
+
+	/* If the amount of data to be sent less than free_space, modify free_space */
+	if (ep[epnum].ttype == ISOCHRONOUS) 
+	{
+		if (free_space > iso_ep[epnum].packet_position - ep[epnum].buffer.position)
+			free_space = iso_ep[epnum].packet_position - ep[epnum].buffer.position;
+	}
+	else
+		if (free_space > ep[epnum].buffer.length)
+			free_space = ep[epnum].buffer.length;
+
+	i = ep[epnum].buffer.position;
+	free_space += i;
+
+	/* Write data to FIFO by 4 bytes */
+	free_space -= 3;
+	while (i < free_space)
+	{
+		MCF5272_WR_USB_EPDR(imm, epnum, 32, *(uint32 *)(&ep[epnum].buffer.start[i]));
+		i += 4;
+	}
+
+	free_space += 3;
+	/* Write data to FIFO by 1 byte */
+	while (i < free_space)
+	{
+		MCF5272_WR_USB_EPDR(imm, epnum, 8, ep[epnum].buffer.start[i]);
+		i++;
+	}
+	
+	ep[epnum].buffer.position = i;
+
+	if ((i == ep[epnum].buffer.length) && (ep[epnum].ttype != ISOCHRONOUS))
+	{
+		/* This is all of the data to be sent */
+		if ((i % ep[epnum].packet_size) != 0)
+			/*Sent short packet - Clear the IN-DONE bit */
+			MCF5272_WR_USB_EPCTL(imm, epnum, MCF5272_RD_USB_EPCTL(imm, epnum)
+				& ~MCF5272_USB_EPNCTL_IN_DONE);
+	}
+	
+	if (epnum != 0)
+		MCF5272_WR_USB_EPIMR(imm, 0, imr0_mask);
+
+	/* Restore saved imr_mask */
+	MCF5272_WR_USB_EPIMR(imm, epnum, imr_mask);
+
+	return i;
+}
+/********************************************************************/
+uint32
+usb_rx_data(uint32 epnum, uint8 *start, uint32 length)
+{
+uint32 imr_mask, imr0_mask=0;
+int32 i = 0;
+int32 fifo_data;
+
+//printk("rx: %p", start);
+	/* Exit if device is reset */
+	if ((epnum !=0) && (ep[epnum].state == USB_DEVICE_RESET))
+			return -EIO;
+
+	/* Make sure there is data to send */
+	if (!length)
+		return 0;
+	/* See if the EP is currently busy */
+	if (ep[epnum].buffer.start && (ep[epnum].ttype != ISOCHRONOUS))
+		return -EBUSY;
+	/* Make sure the buffer is allocated */
+	if (!start)
+		return -EFAULT;
+	/* Make sure this is an OUT endpoint */
+	if (epnum && (MCF5272_RD_USB_EPISR(imm, epnum) & MCF5272_USB_EPNISR_DIR))
+		return -EPERM;
+	/* Make sure this EP is not HALTed */
+	if (MCF5272_RD_USB_EPISR(imm, epnum) & MCF5272_USB_EPNISR_HALT)
+		return -EIO;
+
+	/* Save off the current IMR */
+	imr_mask = MCF5272_RD_USB_EPIMR(imm, epnum);
+
+	/* Clear the EOT, EOP and FIFO LVL mask bits */
+	if (epnum != 0)
+	{
+		MCF5272_WR_USB_EPIMR(imm, epnum, imr_mask & 
+			~(MCF5272_USB_EPNISR_EOT
+			| MCF5272_USB_EPNISR_EOP
+			| MCF5272_USB_EPNISR_FIFO_LVL));
+
+		imr0_mask = MCF5272_RD_USB_EPIMR(imm, 0);
+
+		MCF5272_WR_USB_EPIMR(imm, 0, imr0_mask & 
+			~(MCF5272_USB_EP0ISR_RESET
+			| MCF5272_USB_EP0ISR_DEV_CFG
+			| MCF5272_USB_EP0ISR_SOF));
+	}
+	else
+		MCF5272_WR_USB_EPIMR(imm, 0, imr_mask & 
+			~(MCF5272_USB_EP0ISR_OUT_EOP
+			| MCF5272_USB_EPNISR_EOP
+			| MCF5272_USB_EP0ISR_OUT_EOT
+			| MCF5272_USB_EPNISR_EOT
+			| MCF5272_USB_EP0ISR_RESET
+			| MCF5272_USB_EP0ISR_DEV_CFG));
+
+	if (ep[epnum].buffer.start)
+	{
+	    /* Isochronous EP is currently busy, so enqueue this request */
+	    if (++iso_ep[epnum].number_of_requests >= MAX_IO_REQUESTS)
+	    {
+		iso_ep[epnum].number_of_requests--;
+		return -EBUSY;
+	    }
+	    if (++iso_ep[epnum].last_io_request >= MAX_IO_REQUESTS)
+		    iso_ep[epnum].last_io_request = 0;
+	    iso_ep[epnum].requests_queue[iso_ep[epnum].last_io_request].start = start;
+	    iso_ep[epnum].requests_queue[iso_ep[epnum].last_io_request].length = length;
+
+	    /* Restore saved imr_mask */
+	    MCF5272_WR_USB_EPIMR(imm, 0, imr0_mask);
+	    MCF5272_WR_USB_EPIMR(imm, epnum, imr_mask);
+	    return 0;
+	}
+
+	/* Setup the EP Buffer structure */
+	ep[epnum].buffer.start = start;
+	ep[epnum].buffer.length = length;
+	ep[epnum].buffer.position = 0;
+	
+	if (ep[epnum].ttype != ISOCHRONOUS)
+	{
+		/* Read the Data Present register */
+		fifo_data = MCF5272_RD_USB_EPDPR(imm, epnum);
+
+		/* If the amount of data to be received less than amount of data in FIFO, modify fifo_data */
+		if (fifo_data > length)
+		{
+			fifo_data = length;
+		}
+
+		/* Read the data from the FIFO into the buffer */
+		fifo_data -= 3;
+		while (i < fifo_data)
+		{
+			*(uint32 *)(&ep[epnum].buffer.start[i]) = MCF5272_RD_USB_EPDR(imm, epnum,32);
+			i += 4;
+		}
+	
+		fifo_data +=3;
+		while (i < fifo_data)
+		{
+			*(uint8 *)(&ep[epnum].buffer.start[i]) = MCF5272_RD_USB_EPDR(imm, epnum,8);
+			i++;
+		}
+		
+		ep[epnum].buffer.position = i;
+
+		/* If it is all the data to receive, complete the transfer */
+		if ( i == ep[epnum].buffer.length )
+		{
+			ep[epnum].bytes_transferred = i;
+		
+			ep[epnum].buffer.start = 0;
+			ep[epnum].buffer.length = 0;
+			ep[epnum].buffer.position = 0;
+
+			wake_up_interruptible(&ep_wait_queue);
+		}
+	}
+	else
+	{
+		/* Setup the iso_ep and buffer structures for ISO transfer */
+		iso_ep[epnum].frame_counter = 0;
+		iso_ep[epnum].packet_length = (uint32*) start;
+		ep[epnum].buffer.start = start + 4 * length;
+		iso_ep[epnum].packet_position = 0;
+	}
+
+	if (epnum != 0)
+		MCF5272_WR_USB_EPIMR(imm, 0, imr0_mask);
+	
+	/* Restore saved imr_mask */
+	MCF5272_WR_USB_EPIMR(imm, epnum, imr_mask);
+
+	return i;
+}
+/********************************************************************/
+void 
+usb_bus_state_chg_service(uint32 event)
+{
+uint32 i;
+    if (event & SUSPEND)
+    {
+	if (event & ENABLE_WAKEUP)
+	{
+		#ifdef DEBUG
+			printk("Remote wakeup enabled.\n");
+		#endif
+        }
+    }
+    if (event & RESUME)
+    {
+		#ifdef DEBUG
+			printk("The bus has been resumed (K state)\n");
+		#endif
+    }
+    if (event & RESET)
+    {
+		#ifdef DEBUG
+			printk("USB reset signal detected\n");
+		#endif
+
+	/* Set "Reset" status to all endpoints */
+	for (i=0; i< NUM_ENDPOINTS; i++)
+	{
+		/* Clear buffers for all endpoints */
+		ep[i].buffer.start = 0;
+		ep[i].buffer.length = 0;
+		ep[i].buffer.position = 0;
+		ep[i].bytes_transferred = 0;
+		
+		/* Assing "Reset" status to all endpoints */
+		ep[i].state = USB_DEVICE_RESET;
+
+		/* Set up default values */
+		if (ep[i].ttype == ISOCHRONOUS)
+		{
+			iso_ep[i].frame_counter = 0;
+			iso_ep[i].packet_position = 0;
+			iso_ep[i].start_frame_number = -1;
+			iso_ep[i].final_frame_number = -1;
+			iso_ep[i].state = DEFAULT;
+			iso_ep[i].transfer_monitoring = FALSE;
+			iso_ep[i].sent_packet_watch = 0;
+			iso_ep[i].last_io_request = MAX_IO_REQUESTS;
+			iso_ep[i].first_io_request = 0;
+			iso_ep[i].number_of_requests = 0;
+		}
+	}
+	/* Permit transfer for ep 0 on unconfigured device */
+	ep[0].state = USB_CONFIGURED;
+
+	/* If NewC points to a command, delete it */
+	if (NewC)
+	{
+		kfree(NewC);
+		NewC = NULL;
+	}
+
+	/* Wake up all waiting functions */
+	usb_event |= USB_DEVICE_RESET;
+	wake_up_interruptible(&ep_wait_queue);
+	wake_up_interruptible(&fetch_command_queue);
+
+	/* Notify client program about reset */
+	if (usb_async_queue) usb_kill_fasync(usb_async_queue, SIGIO);
+    }
+}
+
+/********************************************************************/
+void 
+usb_devcfg_service(void)
+{
+uint8 new_config = 0;
+uint32 i, j, fifo_level;
+uint32 isoep_present = FALSE;
+uint8 epnum;
+USB_CONFIG_DESC *pCfgDesc;
+USB_INTERFACE_DESC *pIfcDesc;
+USB_ENDPOINT_DESC *pEpDesc;
+
+	/* Initialize Endpoint settings for this configuration */
+	new_config = (uint8)(MCF5272_RD_USB_EP0SR(imm) >> 12);
+		
+	/* Start by marking all Endpoints as disabled (except EP0) */
+	for (i = 1; i < NUM_ENDPOINTS; i++)
+		ep[i].ttype = DISABLED;
+
+	/* Get pointer to active Configuration descriptor */
+	pCfgDesc = (USB_CONFIG_DESC *)usb_get_desc(new_config, -1, -1, -1);
+
+	ep[0].state = USB_CONFIGURED;
+
+	ep[0].buffer.start = 0;
+	ep[0].buffer.position = 0;
+	ep[0].buffer.length = 0;
+
+	/* Iterate through all the valid Interfaces in this Configuration */
+	for (i = 0; i < pCfgDesc->bNumInterfaces; i++)
+	{
+		pIfcDesc = (USB_INTERFACE_DESC *)usb_get_desc(new_config, i, AltSetting(imm, i), -1);
+		/* Iterate through all the valid Endpoints in this interface */
+		for (j = 0; j < pIfcDesc->bNumEndpoints; j++)
+		{
+			pEpDesc = (USB_ENDPOINT_DESC *)usb_get_desc(new_config, i, AltSetting(imm, i), j);
+			if (pEpDesc)
+			{
+				epnum = pEpDesc->bEndpointAddress & 0x0F;
+
+				/* See if this Endpoint is actually active */
+				if (!(MCF5272_RD_USB_EPISR(imm, epnum) & 
+					  MCF5272_USB_EPNISR_PRES))
+					return;
+
+				/* Set the new transfer type */
+				ep[epnum].ttype = pEpDesc->bmAttributes;
+
+				/* Set the current direction */
+				if (MCF5272_RD_USB_EPISR(imm, epnum) & 
+					MCF5272_USB_EPNISR_DIR)
+					ep[epnum].dir = IN;
+				else
+					ep[epnum].dir = OUT;
+
+				/* Get the current packet size */
+				ep[epnum].packet_size = (uint16)(pEpDesc->wMaxPacketSizeL + (pEpDesc->wMaxPacketSizeH << 8));
+
+				/* No buffer allocated yet */
+				ep[epnum].buffer.start = 0;
+				ep[epnum].buffer.position = 0;
+				ep[epnum].buffer.length = 0;
+										
+				ep[epnum].sendZLP = FALSE;
+				
+				MCF5272_WR_USB_EPCTL(imm, epnum, 0);
+
+				if (ep[epnum].ttype != ISOCHRONOUS)
+				{
+					/* Set the FIFO length */
+					ep[epnum].fifo_length = (uint16)(ep[epnum].packet_size * FIFO_DEPTH);
+					
+					ep[epnum].bytes_transferred = 0;
+
+					/* Enable EOP and EOT interrupts, disable FIFO_LVL */
+					MCF5272_WR_USB_EPIMR(imm, epnum,
+						((MCF5272_RD_USB_EPIMR(imm, epnum)
+							& ~MCF5272_USB_EPNISR_FIFO_LVL)
+							| (MCF5272_USB_EPNISR_EOP
+							| MCF5272_USB_EPNISR_EOT)));
+
+					if (ep[epnum].dir == IN)
+						/* Set the IN-DONE bit - This is only required
+						   on pre-2K75N masks. This bit is set by HW 
+						   beginning with the 2K75N silicon. */
+						MCF5272_WR_USB_EPCTL(imm, epnum, MCF5272_USB_EPNCTL_IN_DONE);
+				}
+				else
+				{
+					/* Set the FIFO length for isochronous endpoint */
+					ep[epnum].fifo_length = ISOCHRONOUS_FIFO_LENGTH;
+
+					/* Set up default values */
+					iso_ep[epnum].start_frame_number = -1;
+					iso_ep[epnum].final_frame_number = -1;
+					iso_ep[epnum].transfer_monitoring = FALSE;
+					iso_ep[epnum].state = DEFAULT;
+					iso_ep[epnum].frame_counter = 0;
+					iso_ep[epnum].packet_position = 0;
+					iso_ep[epnum].last_io_request = MAX_IO_REQUESTS;
+					iso_ep[epnum].first_io_request = 0;
+					iso_ep[epnum].number_of_requests = 0;
+
+					/* Disable EOT interrupt, enable FIFO_LVL and EOP*/
+					MCF5272_WR_USB_EPIMR(imm, epnum,
+						((MCF5272_RD_USB_EPIMR(imm, epnum)
+							& ~(MCF5272_USB_EPNISR_EOT))
+							| (MCF5272_USB_EPNISR_FIFO_LVL
+							| MCF5272_USB_EPNISR_EOP)));
+						
+					/* Set up appropriate FIFO threshold level */
+					if ((ISOCHRONOUS_FIFO_LENGTH >> 2) >= THRESHOLD_FIFO_FULLNESS)
+						fifo_level =2;
+					else
+					if ((ISOCHRONOUS_FIFO_LENGTH >> 1) >= THRESHOLD_FIFO_FULLNESS)
+						fifo_level = 1;
+					else
+						fifo_level = 0;
+						
+					MCF5272_WR_USB_EPCTL(imm, epnum, MCF5272_USB_EPNCTL_ISO_MODE
+									| MCF5272_USB_EPNCTL_FIFO_LVL(fifo_level));
+					isoep_present = TRUE;
+				}
+				
+				ep[epnum].state = USB_CONFIGURED;
+			}
+		}
+	}
+	
+	/* Initialize FIFO module according the new configuration / interface */
+	usb_fifo_init();
+
+	/* If at least one isochronous endpoint is present in configuration / interface,
+		enable SOF interrupt. Otherwise, disable it. */
+	if (isoep_present)
+		MCF5272_WR_USB_EP0IMR(imm, MCF5272_RD_USB_EP0IMR(imm)
+					| MCF5272_USB_EP0IMR_SOF_EN);
+	else
+		MCF5272_WR_USB_EP0IMR(imm, MCF5272_RD_USB_EP0IMR(imm)
+					& (~MCF5272_USB_EP0IMR_SOF_EN));
+
+	usb_event |= USB_CONFIGURATION_CHG;
+	current_config.cur_config_num = new_config;
+	current_config.altsetting = MCF5272_RD_USB_ASR(imm);
+
+	/* Notify client application about change of configuration */
+	if (usb_async_queue) usb_kill_fasync(usb_async_queue, SIGIO);
+}
+
+
+/********************************************************************/
+void
+usb_vendreq_done(uint32 error)
+{
+	if (error)
+		/* This sends a single STALL as the handshake */
+		MCF5272_WR_USB_EP0CTL(imm,
+			MCF5272_RD_USB_EP0CTL(imm)
+			| MCF5272_USB_EP0CTL_CMD_OVER
+			| MCF5272_USB_EP0CTL_CMD_ERR);
+	else
+		MCF5272_WR_USB_EP0CTL(imm,
+			MCF5272_RD_USB_EP0CTL(imm)
+			| MCF5272_USB_EP0CTL_CMD_OVER);
+	return;
+}
+/********************************************************************/
+void
+usb_ep_halt(uint32 epnum)
+{
+	#ifdef DEBUG
+		printk("Endpoint %d has been HALTed\n", (int)epnum);
+	#endif
+}
+
+/********************************************************************/
+void
+usb_ep_unhalt(uint32 epnum)
+{
+	#ifdef DEBUG
+		printk("Endpoint %d has been UNHALTed\n", (int)epnum);
+	#endif
+}
+
+
+/********************************************************************/
+void
+usb_sort_ep_array(USB_EP_STATE *list[], int n)
+{
+/* Simple bubble sort function called by usb_fifo_init() */
+int i, pass, sorted;
+USB_EP_STATE *temp;
+pass = 1;
+
+	do {
+		sorted = 1;
+		for (i = 0; i < n - pass; ++i)
+		{
+			if (list[i]->fifo_length < list[i+1]->fifo_length )
+			{
+				/* Exchange out-of-order pair */
+				temp = list[i];
+				list[i] = list[i + 1];
+				list[i+1] = temp;
+				sorted = 0;
+			}
+		}
+		++pass;
+	} while(!sorted);
+}
+
+/********************************************************************/
+void
+usb_make_power_of_two(uint32 *size)
+{
+/* Called by usb_fifo_init() */
+int i, not_power_of_two = 0;
+uint32 new_size = *size;
+
+	for (i = 0; new_size != 1; i++)
+	{
+		if (new_size & 0x0001)
+			not_power_of_two = 1;
+		new_size >>= 1;
+	}
+	new_size = 1 << (i + not_power_of_two);
+	if (new_size > 256)
+		new_size = 256;
+	*size = new_size;
+}
+/********************************************************************/
+void
+usb_fifo_init(void)
+{
+USB_EP_STATE *pIN[NUM_ENDPOINTS];
+USB_EP_STATE *pOUT[NUM_ENDPOINTS];
+uint8 nIN, nOUT, i;
+uint16 INpos, OUTpos;
+
+	/* Endpoint 0 is always present and bi-directional */
+	pIN[0] = &ep[0];
+	pOUT[0] = &ep[0];
+	nIN = nOUT = 1;
+
+	/* Sort the active endpoints by direction */
+	for (i = 1; i < NUM_ENDPOINTS; i++)
+	{
+		if (ep[i].ttype != DISABLED)
+		{
+			if (ep[i].dir == IN)
+				pIN[nIN++] = &ep[i];
+			else
+				pOUT[nOUT++] = &ep[i];
+		}
+	}
+
+	/* Make sure FIFO size is a power of 2; if not, make it so */
+	for (i = 0; i < nIN; i++)
+		usb_make_power_of_two( &(pIN[i]->fifo_length) );
+	for (i = 0; i < nOUT; i++)
+		usb_make_power_of_two( &(pOUT[i]->fifo_length) );
+
+	/* Sort the endpoints by FIFO length (decending) */
+	usb_sort_ep_array(pIN, nIN);
+	usb_sort_ep_array(pOUT, nOUT);
+
+	/* Calculate the FIFO address for each endpoint */
+	INpos = 0;
+	OUTpos = 0;
+	for (i = 0; i < nIN; i++)
+	{
+		pIN[i]->in_fifo_start = INpos;
+		INpos += pIN[i]->fifo_length;
+	}
+	for (i = 0; i < nOUT; i++)
+	{
+		pOUT[i]->out_fifo_start = OUTpos;
+		OUTpos += pOUT[i]->fifo_length;
+	}
+
+	/* Save the FIFO settings into the Configuration Registers */
+	
+	/* Initialize Endpoint 0 IN FIFO */
+	MCF5272_WR_USB_IEP0CFG(imm, 0
+		| (ep[0].packet_size << 22)
+		| (ep[0].fifo_length << 11)
+		|  ep[0].in_fifo_start);
+
+	/* Initialize Endpoint 0 OUT FIFO */
+	MCF5272_WR_USB_OEP0CFG(imm, 0
+		| (ep[0].packet_size << 22)
+		| (ep[0].fifo_length << 11)
+		|  ep[0].out_fifo_start);
+
+	for (i = 1; i < NUM_ENDPOINTS; i++)
+	{
+		if (ep[i].ttype != DISABLED)
+		{
+			if (ep[i].dir == IN)
+				/* Initialize Endpoint i FIFO */
+				MCF5272_WR_USB_EPCFG(imm, i, 0
+				| (ep[i].packet_size << 22)
+				| (ep[i].fifo_length << 11)
+				|  ep[i].in_fifo_start);
+			else
+				/* Initialize Endpoint i FIFO */
+				MCF5272_WR_USB_EPCFG(imm, i, 0
+				| (ep[i].packet_size << 22)
+				| (ep[i].fifo_length << 11)
+				|  ep[i].out_fifo_start);
+		}
+	}
+}
+
+/********************************************************************/
+int
+usb_ep_is_busy(uint32 epnum)
+{
+	/* If device is reset, return with error */
+	if (ep[epnum].state == USB_DEVICE_RESET)
+		return -USB_DEVICE_RESET;
+
+	/* See if the EP is currently busy */
+	if (ep[epnum].buffer.start)
+		return -USB_EP_IS_BUSY;
+	
+	return -USB_EP_IS_FREE;
+}
+
+/********************************************************************/
+int
+usb_ep_wait(uint32 epnum, uint32 requests)
+{ 
+int length;
+	/* Sleep until EP becomes free or reset detected */
+	#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+	if (ep[epnum].ttype != ISOCHRONOUS)
+	{
+		if (wait_event_interruptible(ep_wait_queue, ((ep[epnum].state == USB_DEVICE_RESET)
+		    || (ep[epnum].buffer.start == 0))))
+			return(-ERESTARTSYS);
+	}
+	else
+		if (wait_event_interruptible(ep_wait_queue, ( (ep[epnum].state == USB_DEVICE_RESET)
+		    || (!ep[epnum].buffer.start && !iso_ep[epnum].number_of_requests)
+		    || (iso_ep[epnum].number_of_requests < requests) )))
+			return(-ERESTARTSYS);
+	#else
+
+	uint32 flags;
+	save_flags(flags); cli();
+	if (ep[epnum].ttype != ISOCHRONOUS)
+	{
+		while ((ep[epnum].state != USB_DEVICE_RESET) && (ep[epnum].buffer.start != 0))
+		{
+			if (current->signal & ~current->blocked) 
+			{
+				restore_flags(flags);
+				return(-ERESTARTSYS);
+			}
+			interruptible_sleep_on(&ep_wait_queue);
+		}
+	}
+	else
+		while ((ep[epnum].state != USB_DEVICE_RESET)
+		    && !(!ep[epnum].buffer.start && !iso_ep[epnum].number_of_requests)
+		    && !(iso_ep[epnum].number_of_requests < requests) )
+		{
+			if (current->signal & ~current->blocked) 
+			{
+				restore_flags(flags);
+				return(-ERESTARTSYS);
+			}
+			interruptible_sleep_on(&ep_wait_queue);
+		}
+	
+	restore_flags(flags);
+	#endif
+
+	/* See if Reset has occured */
+	if (ep[epnum].state != USB_DEVICE_RESET)
+	{
+		if (ep[epnum].ttype == ISOCHRONOUS)
+			return -USB_EP_IS_FREE;
+		else
+		{
+			length = ep[epnum].bytes_transferred;
+			ep[epnum].bytes_transferred = 0;
+			return length;
+		}
+	}
+
+	return -USB_DEVICE_RESET;
+}
+/********************************************************************/
+uint8*
+usb_get_desc(int8 config, int8 iface, int8 setting, int8 ep)
+{
+	/* Note:
+	 * ep is the offset and not the physical endpoint number
+	 * In order to get the config desc pointer, specify -1 for 
+	 * all other inputs except config
+	 * In order to get the interface/alternate setting desc pointer,
+	 * specify -1 for epNum
+	 */
+	int i;
+	uint8 *pDesc = usb_device_descriptor;
+
+	if (config != -1)
+	{
+		if (config > ((USB_DEVICE_DESC *)pDesc)->bNumConfigurations)
+			return 0;
+		
+		/* Allow for non-standard desc between device and config desc */
+		while (pDesc[1] != CONFIGURATION)
+			pDesc += pDesc[0];	
+
+		/* pDesc now points to Config 1 descriptor */
+		for (i = 1; i < config;)
+		{
+			pDesc += pDesc[0];
+			if (pDesc[1] == CONFIGURATION)
+				i++;
+		}
+
+		/* pDesc now points to the correct Configuration descriptor */
+		if ((iface != -1) && (setting != -1))
+		{
+			if (iface >= ((USB_CONFIG_DESC *)pDesc)->bNumInterfaces)
+				return 0;
+
+			/* Allow for non-standard desc between config and iface desc */
+			while (pDesc[1] != INTERFACE)
+				pDesc += pDesc[0];
+
+			/* pDesc now points to first Interface descriptor */
+			for (i = 0; i < iface;)
+			{
+				pDesc += pDesc[0];
+				if (pDesc[1] == INTERFACE && pDesc[3] == 0)
+					i++;
+			}
+			/* pDesc now points to correct Interface descriptor */
+			for (i = 0; i < setting;)
+			{
+				pDesc += pDesc[0];
+				if (pDesc[1] == INTERFACE)
+				{
+					if (pDesc[2] != iface)
+						return 0;
+					else
+						i++;
+				}
+			}
+
+			/* pDesc now points to correct Alternate Setting descriptor */
+			if (ep != -1)
+			{
+				if (ep >= pDesc[4])
+					return 0;
+
+				/* Allow for non-standard desc between iface and ep desc */
+				while (pDesc[1] != ENDPOINT)
+					pDesc += pDesc[0];
+
+				/* pDesc now points to first Endpoint descriptor */
+				for (i = 0; i < ep;)
+				{
+					pDesc += pDesc[0];
+					if (pDesc[1] == ENDPOINT)
+						i++;
+				}
+				/* pDesc now points to the correct Endpoint descriptor */
+			}
+		}
+	}
+	return (pDesc);
+}
+
+/********************************************************************/
+void 
+usb_vendreq_service(uint8  bmRequestType,
+					uint8  bRequest, 
+					uint16 wValue,
+					uint16 wIndex, 
+					uint16 wLength)
+{
+	if ((bmRequestType < 128) && (wLength > 0))
+	{
+		/* Allocate memory for a new command */
+		/* There is a data stage in this request and direction of data transfer is from Host to Device */
+		NewC = (DEVICE_COMMAND *) kmalloc(sizeof(DEVICE_COMMAND) + wLength, GFP_ATOMIC);
+		
+		/* Store the address where new command will be placed */
+		NewC -> cbuffer = (uint8 *) NewC + sizeof(DEVICE_COMMAND);
+	}
+	else
+		/* Direction of data transfer is from Device to Host, or no data stage */
+		NewC = (DEVICE_COMMAND *) kmalloc(sizeof(DEVICE_COMMAND), GFP_ATOMIC);
+	
+	if (NewC == NULL)
+	{
+		#ifdef DEBUG
+			printk("Could not allocate queue item.\n");
+		#endif
+		
+		if ((wLength != 0) && (bmRequestType > 127))
+			/* The direction of data transfer is from Device to Host,
+			send zero-length packet to indicate no data will be provided */
+			MCF5272_WR_USB_EP0CTL(imm, MCF5272_RD_USB_EP0CTL(imm)
+					& (~ MCF5272_USB_EP0CTL_IN_DONE));
+		
+		usb_vendreq_done(MALLOC_ERROR);
+
+		return;
+	}
+	
+	/* Store request specific values */
+	NewC -> request.bmRequestType = bmRequestType;
+	NewC -> request.bRequest = bRequest;
+	NewC -> request.wValue = wValue;
+	NewC -> request.wIndex = wIndex;
+	NewC -> request.wLength = wLength;
+	
+	if ((bmRequestType < 128) && (wLength > 0))
+	{
+		/* This request has data stage and the direction of command block
+		transfer is from Host to Device */
+	
+		/* Prepare ep[0] structure to accept command (during data stage)*/
+		ep[0].buffer.start = NewC -> cbuffer;
+		ep[0].buffer.length = wLength;
+		ep[0].buffer.position = 0;
+		
+		/* usb_out_service() will receive a command and will call usb_vendreq_done() */
+	}
+	else
+	{
+		/* This request has no data stage or direction of command block transfer
+		is from Device to Host.
+		In any case, client application has to be informed about new request */
+
+		if (usb_async_queue) usb_kill_fasync(usb_async_queue, SIGIO);
+		
+		/* We have got a new command and can wake up fetch_command routine */
+		wake_up_interruptible(&fetch_command_queue);
+	}
+}
+
+/********************************************************************/
+void
+usb_isochronous_transfer_service(void)
+{
+uint32 imr_mask, epnum;
+uint32 free_space, i;
+
+for (epnum = 1; epnum < NUM_ENDPOINTS; epnum++)
+{
+	if (ep[epnum].ttype == ISOCHRONOUS)
+	{
+		/* Save IMR */
+		imr_mask = MCF5272_RD_USB_EP0IMR(imm);
+		/* Disable RESET and DEV_CFG interrupts */
+		MCF5272_WR_USB_EP0IMR(imm, imr_mask & ~(MCF5272_USB_EP0ISR_RESET
+						| MCF5272_USB_EP0ISR_DEV_CFG));
+
+		if ((iso_ep[epnum].transfer_monitoring == TRUE) && (ep[epnum].buffer.start))
+		{
+			if (ep[epnum].dir == IN)
+			{
+				/* Set up sent_packet_watch for the next frame to see, if EOP occurs */
+				iso_ep[epnum].sent_packet_watch ++;
+				/* It must be 1, now */
+				
+				/* If EOP interrupt did not occur in previous frame, handle it */
+				if (iso_ep[epnum].sent_packet_watch > 1)
+				{
+					/* Remove unsent packet from FIFO buffer */
+					MCF5272_WR_USB_EPCFG(imm, epnum, MCF5272_RD_USB_EPCFG(imm, epnum));
+					
+					/* Reset the counter */
+					iso_ep[epnum].sent_packet_watch = 0;
+					iso_ep[epnum].packet_length[iso_ep[epnum].frame_counter] = 0;
+					
+					iso_ep[epnum].frame_counter ++;
+					
+					/* Is it last packet ? */
+					if (iso_ep[epnum].frame_counter == ep[epnum].buffer.length)
+					{
+						/* End of buffer transfer - wake up usb_ep_wait */
+						wake_up_interruptible(&ep_wait_queue);
+
+						/* case 3 */
+						/* The first packet of next buffer must be skipped */
+						if (iso_ep[epnum].number_of_requests > 0)
+						{
+						    iso_ep[epnum].number_of_requests--;
+						    /* Extract next request from the queue */
+						    ep[epnum].buffer.length = iso_ep[epnum].requests_queue[iso_ep[epnum].first_io_request].length;
+						    iso_ep[epnum].packet_length = (uint32*) iso_ep[epnum].requests_queue[iso_ep[epnum].first_io_request].start;
+
+						    ep[epnum].buffer.position = iso_ep[epnum].packet_length[0];
+						    /* Indicate that this packet was not sent. */
+						    iso_ep[epnum].packet_length[0] = 0;
+
+						    if (++iso_ep[epnum].first_io_request >= MAX_IO_REQUESTS)
+							iso_ep[epnum].first_io_request = 0;
+
+						    /* Check if new buffer contains only 1 packet. If true - skip entire buffer,
+						       if false - skip only first packet of buffer */
+						    if (ep[epnum].buffer.length > 1)
+						    {
+							    ep[epnum].buffer.start = (uint8*)iso_ep[epnum].packet_length + 4 * ep[epnum].buffer.length;
+							    iso_ep[epnum].packet_position = ep[epnum].buffer.position + iso_ep[epnum].packet_length[1];
+							    
+							    iso_ep[epnum].frame_counter = 1;
+						    }
+						    else
+						    
+							/* Extract next request from the queue */
+							if (usb_get_request(epnum))
+							    iso_ep[epnum].packet_position = iso_ep[epnum].packet_length[0];
+							    
+						} else /* If there are no requests in a queue */
+						{
+							/* The first packet of next buffer must be skipped by tx_data */
+							iso_ep[epnum].state = SKIP_FIRST_PACKET;
+
+							ep[epnum].buffer.start = 0;
+							ep[epnum].buffer.length = 0;
+							
+							ep[epnum].buffer.position = 0;
+					
+							iso_ep[epnum].frame_counter = 0;
+						}
+					}
+					else
+					/* Is it next to last packet ? */
+					if ((iso_ep[epnum].frame_counter + 1) >= ep[epnum].buffer.length)
+					{
+						/* case 2 */
+						/* The next transfer must be started from first packet */
+						iso_ep[epnum].state = DEFAULT;
+						
+						iso_ep[epnum].packet_length[ep[epnum].buffer.length] = 0;
+
+						/* Extract next request from the queue */
+						if (usb_get_request(epnum))
+						    iso_ep[epnum].packet_position = iso_ep[epnum].packet_length[0];
+						else
+						{
+							ep[epnum].buffer.start = 0;
+							ep[epnum].buffer.length = 0;
+							ep[epnum].buffer.position = 0;
+					
+							iso_ep[epnum].frame_counter = 0;
+						}
+					}
+					else
+					{
+						/* case 1 */
+						/* Step over the next packet in the buffer */
+						ep[epnum].buffer.position = iso_ep[epnum].packet_position + iso_ep[epnum].packet_length[iso_ep[epnum].frame_counter];
+						/* Indicate that this packet was not sent. */
+						iso_ep[epnum].packet_length[iso_ep[epnum].frame_counter] = 0;
+						
+						iso_ep[epnum].frame_counter ++;
+						/* Set up packet_position boundary for the packet */
+						iso_ep[epnum].packet_position = ep[epnum].buffer.position + iso_ep[epnum].packet_length[iso_ep[epnum].frame_counter];
+					}
+
+					if (ep[epnum].buffer.start)
+					{
+						free_space = ep[epnum].fifo_length;
+						if (free_space > iso_ep[epnum].packet_length[iso_ep[epnum].frame_counter])
+							free_space = iso_ep[epnum].packet_length[iso_ep[epnum].frame_counter];
+
+						i = ep[epnum].buffer.position;
+
+						free_space += i;
+						free_space -= 3;
+					
+						/* Write to FIFO by 4 bytes */
+						while (i < free_space)
+						{
+							MCF5272_WR_USB_EPDR(imm, epnum, 32, *(uint32 *)(&ep[epnum].buffer.start[i]));
+							i += 4;
+						}
+				
+						free_space += 3;
+				
+						/* Write to FIFO by 1 byte */
+						while (i < free_space)
+						{
+							MCF5272_WR_USB_EPDR(imm,epnum,8,ep[epnum].buffer.start[i]);
+							i++;
+						}
+
+						ep[epnum].buffer.position = i;
+					}
+				}
+			}  /* if (ep[epnum].dir == IN) */
+			else
+			{
+				/* Set up sent_packet_watch for the next frame to see, if EOP occurs */
+				iso_ep[epnum].sent_packet_watch ++;
+				/* It must be 1, now */
+
+				/* Check if EOP occured in previous frame */
+				if (iso_ep[epnum].sent_packet_watch > 1)
+				{
+					/* Reset the counter */
+					iso_ep[epnum].sent_packet_watch = 1;
+					ep[epnum].buffer.position += iso_ep[epnum].packet_length[iso_ep[epnum].frame_counter];
+					/* Indicate that last packet was not received. */
+					iso_ep[epnum].packet_length[iso_ep[epnum].frame_counter] = 0;
+					iso_ep[epnum].frame_counter ++;
+					iso_ep[epnum].packet_position = 0;
+
+					/* Is it all packets to read ? */
+					if (iso_ep[epnum].frame_counter == ep[epnum].buffer.length)
+					{
+						/* Buffer sent - wake up usb_ep_wait */
+						wake_up_interruptible(&ep_wait_queue);
+
+						/* Extract next request from the queue */
+						if (usb_get_request(epnum))
+						    iso_ep[epnum].packet_position = 0;
+						else
+						{
+						    ep[epnum].buffer.start = 0;
+						    ep[epnum].buffer.length = 0;
+						    ep[epnum].buffer.position = 0;
+						}
+					}
+				}
+			}
+		}
+		else
+			if (iso_ep[epnum].start_frame_number == MCF5272_RD_USB_FNR(imm))
+			{
+				/* Open data stream */
+				iso_ep[epnum].transfer_monitoring = TRUE;
+				iso_ep[epnum].start_frame_number = -1;
+				iso_ep[epnum].sent_packet_watch = 0;
+			}
+		if (iso_ep[epnum].final_frame_number == MCF5272_RD_USB_FNR(imm))
+		{
+			/* Close data stream */
+			iso_ep[epnum].transfer_monitoring = FALSE;
+			iso_ep[epnum].final_frame_number = -1;
+			iso_ep[epnum].state = DEFAULT;
+		}
+
+		MCF5272_WR_USB_EP0IMR(imm, imr_mask);
+
+	}  /* if (ep[epnum].ttype == ISOCHRONOUS) */
+}  /* for (epnum = 1; ... */
+}
+/********************************************************************/
+uint32
+usb_fetch_command(DEVICE_COMMAND * client_item)
+{
+uint32 event;
+
+	/* Sleep until the new command is received */
+	#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+	if (wait_event_interruptible(fetch_command_queue, NewC || usb_event))
+		return(-ERESTARTSYS);
+	#else
+	uint32 flags;
+	while (!NewC && !usb_event) {
+		save_flags(flags); cli();
+		if (current->signal & ~current->blocked) {
+			restore_flags(flags);
+			return(-ERESTARTSYS);
+		}
+		interruptible_sleep_on(&fetch_command_queue);
+		restore_flags(flags);
+	}
+	#endif
+
+	event = usb_event;
+	usb_event = 0;
+	
+	/* Check if device is configured */
+	if (ep[0].state == USB_NOT_CONFIGURED)
+	{
+		return USB_DEVICE_RESET;
+	}
+
+	/* We have to see if command Queue is not empty */
+	if (NewC == NULL)
+	{
+		return event;
+	}
+
+	/* Copy the request to client's structure, pointed by client_item.
+	   In order to save address of client's command buffer in client,
+	   we have start fill structure from client_item -> cbuffer_length,
+	   not from client_item (which means client_item -> cbuffer)  */
+	memcpy((uint8 *) (&(client_item -> request.bmRequestType)), (uint8 *) (&(NewC -> request.bmRequestType)), sizeof(REQUEST));
+
+	/* Now, we can copy the contents of command buffer (the command itself)
+	   to the command buffer of client, pointed by client_item -> cbuffer */
+	if (NewC->request.bmRequestType < 128)
+		memcpy(client_item -> cbuffer, NewC -> cbuffer,  NewC -> request.wLength);
+
+	return (event | USB_NEW_COMMAND);
+}
+
+/****************************END_OF_USB_SECTION******************************/
+void 
+irq64_h(int irq, void *dev_id, struct pt_regs *regs)
+{
+/* for debug purposes */
+}
+
+/* This function is called whenever the FASYNC flag
+   changes for an open file */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+int usb_device_fasync (int ff, struct file *file, int mode)
+{
+    return fasync_helper(ff, file, mode, &usb_async_queue);
+}
+#else
+int usb_device_fasync (struct inode *inode, struct file *file, int mode)
+{
+    return fasync_helper(inode, file, mode, &usb_async_queue);
+}
+#endif
+
+/* This function is called whenever a process
+ * attempts to open the device file */
+static int usb_device_open(struct inode *inode, struct file *file)
+{
+#ifdef DEBUG
+  printk ("usb_device_open(%p,%p)\n", inode, file);
+#endif
+
+  /* See if EP is already opened */
+  if (active_ep_mask & (1 << MINOR(inode->i_rdev))) 
+	return -EBUSY;
+  active_ep_mask |= (1 << MINOR(inode->i_rdev));
+
+  if (MINOR(inode->i_rdev) >= NUM_ENDPOINTS)
+	return -ENODEV;
+
+  /* Increment module usage count */
+  MOD_INC_USE_COUNT;
+  return SUCCESS;
+}
+
+/* This function is called when a process closes the
+ * device file. It doesn't have a return value in
+ * version 2.0.x because it can't fail (you must ALWAYS
+ * be able to close a device). In version 2.2.x it is
+ * allowed to fail - but we won't let it. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+static int usb_device_release(struct inode *inode, struct file *file)
+#else
+static void usb_device_release(struct inode *inode, struct file *file)
+#endif
+{
+#ifdef DEBUG
+  printk ("usb_device_release(%p,%p)\n", inode, file);
+#endif
+
+  /* Reset start, length and position to prevent from copying
+     to/from user memory space from interrupt handler when 
+     application crashed or device file is closed*/
+  ep[MINOR(GET_RDEV(file))].buffer.start = 0;
+  ep[MINOR(GET_RDEV(file))].buffer.position = 0;
+  ep[MINOR(GET_RDEV(file))].buffer.length = 0;
+
+  iso_ep[MINOR(GET_RDEV(file))].transfer_monitoring = FALSE;
+  
+  /* Reset corresponding bit for closed endpoint file */
+  active_ep_mask &= (0xFE << MINOR(inode->i_rdev));
+
+  if (!active_ep_mask)
+  {
+	  /* Remove this file from the asynchronously notified files */
+	  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+	  usb_device_fasync(-1, file, 0);
+	  #else
+	  usb_device_fasync(inode, file, 0);
+	  #endif
+	
+	  /* Disable MCF5272 USB module */
+	  MCF5272_WR_USB_EP0CTL(imm, 0);
+  }
+  
+  /* Decrement the usage count, otherwise once you
+   * opened the file you'll never get rid of the module. */
+  MOD_DEC_USE_COUNT;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+  return 0;
+#endif
+}
+
+/* This function is called whenever a process which
+ * have already opened the device file attempts to
+ * read from it. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+static ssize_t usb_device_read(struct file *file,
+    char *buffer,    /* The buffer to fill with data */
+    size_t length,   /* The length of the buffer */
+    loff_t *offset)  
+#else
+static int usb_device_read(
+    struct inode *inode,
+    struct file *file,
+    char *buffer,   /* The buffer to fill with the data */
+    int length)     /* The length of the buffer */
+#endif
+{
+#ifdef DEBUG
+    printk ("device_read(%d,%d)\n", MINOR(GET_RDEV(file)), length);
+#endif
+return usb_rx_data(MINOR(GET_RDEV(file)), (uint8 *) buffer, (uint32) length);
+}
+
+/* This function is called when somebody tries to
+ * write into our device file. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+static ssize_t usb_device_write(struct file *file, const char *buffer,
+                            size_t length, loff_t *offset)
+#else
+static int usb_device_write(struct inode *inode, struct file *file,
+                        const char *buffer, int length)
+#endif
+{
+#ifdef DEBUG
+  printk ("device_write(%d,%d)\n", MINOR(GET_RDEV(file)), length);
+#endif
+return usb_tx_data(MINOR(GET_RDEV(file)), (uint8 *) buffer, (uint32) length)
+;
+}
+
+/***************************IOCTL section****************************/
+int usb_device_ioctl(struct inode *inode, struct file *file,
+                 unsigned int ioctl_num,/* The number of the ioctl */
+                 unsigned long ioctl_param) /* The parameter to it */
+{
+  /* Switch according to the ioctl called */
+  switch (ioctl_num) {
+    /* Initialization of USB driver */
+    case USB_INIT:
+	/* Initialization allowed only through EP0 */
+	if (MINOR(inode->i_rdev) != 0) 
+	    return -EPERM;
+	usb_init((DESC_INFO *)ioctl_param);
+	break;
+    /* Returns the command */
+    case USB_GET_COMMAND:
+	if (MINOR(inode->i_rdev) != 0) 
+	    return -EPERM;
+	return usb_fetch_command((DEVICE_COMMAND*)ioctl_param);
+    /* Is EP busy ? */
+    case USB_EP_BUSY:
+	return usb_ep_is_busy(MINOR(inode->i_rdev));
+    /* Wait while EP is busy */
+    case USB_EP_WAIT:
+	return usb_ep_wait(MINOR(inode->i_rdev), (uint32)ioctl_param);
+    /* Returns the number of current configuration */
+    case USB_GET_CURRENT_CONFIG:
+	if (MINOR(inode->i_rdev) != 0)
+	    return -EPERM;
+	((CONFIG_STATUS*)(ioctl_param))->altsetting = current_config.altsetting;
+	((CONFIG_STATUS*)(ioctl_param))->cur_config_num = current_config.cur_config_num;
+	return 0;
+    /* Sets send_ZLP flag */
+    case USB_SET_SEND_ZLP:
+	ep[MINOR(inode->i_rdev)].sendZLP = TRUE;
+	break;
+    case USB_COMMAND_ACCEPTED:
+	if (NewC)
+	{
+		/* Send CMD_OVER and free NewC */
+		usb_vendreq_done(SUCCESS);
+
+		kfree(NewC);
+		NewC = NULL;
+		return SUCCESS;
+	}
+	else return -EPERM;
+    case USB_NOT_SUPPORTED_COMMAND:
+	if (NewC)
+	{
+		/* The direction of command block transfer is from Device to Host,
+		but client application does not accept a request (no data is provided) */
+		if ((NewC->request.bmRequestType > 127) && (NewC->request.wLength != 0))
+			MCF5272_WR_USB_EP0CTL(imm, MCF5272_RD_USB_EP0CTL(imm)
+				& (~ MCF5272_USB_EP0CTL_IN_DONE));
+
+		/* Send CMD_OVER and CMD_ERR and free NewC */
+		usb_vendreq_done(NOT_SUPPORTED_COMMAND);
+
+		kfree(NewC);
+		NewC = NULL;
+		return SUCCESS;
+	}
+	else return -EPERM;
+    /* Set start_frame_number to begin ISO transfer monitoring */
+    case USB_SET_START_FRAME:
+	iso_ep[MINOR(inode->i_rdev)].start_frame_number = (uint32)ioctl_param;
+	break;
+    /* Set final_frame_number to stop ISO transfer monitoring */
+    case USB_SET_FINAL_FRAME:
+	iso_ep[MINOR(inode->i_rdev)].final_frame_number = (uint32)ioctl_param;
+	break;
+    /* Returns current frame number */
+    case USB_GET_FRAME_NUMBER:
+	return MCF5272_RD_USB_FNR(imm);
+    /* STALLs given EP */
+    case USB_EP_STALL:
+	if ((MINOR(inode->i_rdev)) && (ep[(MINOR(inode->i_rdev))].ttype != ISOCHRONOUS))
+		MCF5272_WR_USB_EPCTL(imm, (MINOR(inode->i_rdev)),
+		MCF5272_RD_USB_EPCTL(imm, (MINOR(inode->i_rdev)))
+				| MCF5272_USB_EPNCTL_STALL);
+	else
+		return -EPERM;
+	break;
+    default: return -ENOTTY;
+  }
+  return SUCCESS;
+}
+
+/* Module Declarations ************************************* */
+struct file_operations Fops = {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+  NULL,			/* owner */
+#endif
+  NULL,   		/* seek */
+  usb_device_read,	/* read */
+  usb_device_write,	/* write */
+  NULL,   		/* readdir */
+  NULL,   		/* select */
+  usb_device_ioctl,   	/* ioctl */
+  NULL,   		/* mmap */
+  usb_device_open,	/* open */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+  NULL,    		/* flush */
+#endif
+  usb_device_release,  	/* close */
+  NULL,			/* fsync */
+  usb_device_fasync	/* fasync */
+};
+
+/* Initialize the module - Register the character device */
+#ifndef MODULE
+long init_usb(void) {
+#else /* MODULE */
+int init_module() {
+#endif /* MODULE */
+
+  int reg_result;
+
+  /* Register the character device.
+     Negative values signify an error */
+  reg_result = register_chrdev(MAJOR_NUM, DEVICE_NAME, &Fops);
+  if (reg_result < 0) {
+    printk ("%s device failed with %d\n",
+            "Registering the USB", reg_result);
+    return 0;
+  }
+  printk ("%sthe major device number is %d.\n",
+          "MCF5272 USB driver successfully installed:\n", MAJOR_NUM);
+	  
+  /* Setup interrupt handlers */
+  request_irq(77, usb_endpoint0_isr, SA_INTERRUPT, "ColdFire USB (EP0)", NULL);
+  request_irq(78, usb_endpoint_isr, SA_INTERRUPT, "ColdFire USB (EP1)", NULL);
+  request_irq(79, usb_endpoint_isr, SA_INTERRUPT, "ColdFire USB (EP2)", NULL);
+  request_irq(80, usb_endpoint_isr, SA_INTERRUPT, "ColdFire USB (EP3)", NULL);
+  request_irq(81, usb_endpoint_isr, SA_INTERRUPT, "ColdFire USB (EP4)", NULL);
+  request_irq(82, usb_endpoint_isr, SA_INTERRUPT, "ColdFire USB (EP5)", NULL);
+  request_irq(83, usb_endpoint_isr, SA_INTERRUPT, "ColdFire USB (EP6)", NULL);
+  request_irq(84, usb_endpoint_isr, SA_INTERRUPT, "ColdFire USB (EP7)", NULL);
+
+  return 0;
+}
+
+/* Cleanup - unregister the appropriate file if driver acts like a module */
+#ifdef MODULE
+void cleanup_module()
+{
+  int unreg_result;
+
+/* Disable all interrupts */
+  MCF5272_WR_USB_EP0IMR(imm, 0);
+  MCF5272_WR_USB_EP1IMR(imm, 0);
+  MCF5272_WR_USB_EP2IMR(imm, 0);
+  MCF5272_WR_USB_EP3IMR(imm, 0);
+  MCF5272_WR_USB_EP4IMR(imm, 0);
+  MCF5272_WR_USB_EP5IMR(imm, 0);
+  MCF5272_WR_USB_EP6IMR(imm, 0);
+  MCF5272_WR_USB_EP7IMR(imm, 0);
+
+  /* Disable MCF5272 USB module */
+  MCF5272_WR_USB_EP0CTL(imm, 0);
+
+  /* Release interrupt handlers */
+  free_irq(77, NULL);
+  free_irq(78, NULL);
+  free_irq(79, NULL);
+  free_irq(80, NULL);
+  free_irq(81, NULL);
+  free_irq(82, NULL);
+  free_irq(83, NULL);
+  free_irq(84, NULL);
+
+  /* Unregister the device */
+  unreg_result = unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
+
+  /* If there's an error, report it */
+  if (unreg_result < 0) {
+    printk("Error in unregister_chrdev: %d\n", unreg_result);
+    return;
+    }
+  printk("USB driver succesfully uninstalled\n");
+}
+#endif
diff -urN linux-2.4.29/drivers/char/mcf_usb_defs.h linux-2.4.29-uc1/drivers/char/mcf_usb_defs.h
--- linux-2.4.29/drivers/char/mcf_usb_defs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/mcf_usb_defs.h	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,151 @@
+/*********************************************************************
+ *
+ * Copyright:
+ *	MOTOROLA, INC. All Rights Reserved.  
+ *  You are hereby granted a copyright license to use, modify, and
+ *  distribute the SOFTWARE so long as this entire notice is
+ *  retained without alteration in any modified and/or redistributed
+ *  versions, and that such modified versions are clearly identified
+ *  as such. No licenses are granted by implication, estoppel or
+ *  otherwise under any patents or trademarks of Motorola, Inc. This 
+ *  software is provided on an "AS IS" basis and without warranty.
+ *
+ *  To the maximum extent permitted by applicable law, MOTOROLA 
+ *  DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING 
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+ *  PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH REGARD TO THE 
+ *  SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) AND ANY 
+ *  ACCOMPANYING WRITTEN MATERIALS.
+ * 
+ *  To the maximum extent permitted by applicable law, IN NO EVENT
+ *  SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING 
+ *  WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS 
+ *  INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY
+ *  LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.   
+ * 
+ *  Motorola assumes no responsibility for the maintenance and support
+ *  of this software
+ ********************************************************************/
+
+/*
+ * File:		usb_defs.h
+ * Purpose:		USB Header File
+ */
+
+#ifndef USB_DEFS_H
+#define USB_DEFS_H
+
+#include "mcf5272.h"
+#include "mcf_usb.h"
+
+/* Depth of the FIFOs in packet lengths (Must be at */
+/* least 2 for non-isochronous endpoints) */
+#define FIFO_DEPTH		4
+#define ISOCHRONOUS_FIFO_LENGTH	256
+#define THRESHOLD_FIFO_FULLNESS	32	/* At least 32 bytes must be in FIFO when FIFO_LVL is reached */
+#define MAX_IO_REQUESTS		16
+
+/* Definitions for internal isochronous transfer status */
+#define DEFAULT			0
+#define MISS_PACKET		1
+#define SKIP_FIRST_PACKET	2
+
+ /********************************************************************
+ *	Interrupt Controller Definitions
+ ********************************************************************/
+
+#define USB_EP0_LEVEL		6
+#define USB_EP1_LEVEL		5
+#define USB_EP2_LEVEL		5
+#define USB_EP3_LEVEL		5
+#define USB_EP4_LEVEL		5
+#define USB_EP5_LEVEL		5
+#define USB_EP6_LEVEL		5
+#define USB_EP7_LEVEL		5
+
+/* Structure for storing IN and OUT transfer data */
+typedef struct {
+	uint8 *start;				/* Starting address for buffer */
+	uint32 position;			/* Offset pointer within buffer */
+	uint32 length;				/* Length of the buffer in bytes */
+} USB_BUFFER;
+
+/* IO Request to Driver */
+typedef struct {
+	uint8 *start;				/* Stores start of data buffer */
+	uint32 length;				/* Stores length of data buffer */
+} IO_REQUEST;
+
+/* USB Endpoint State Info */
+typedef struct {
+	uint32 fifo_length;			/* Length of FIFO */
+	uint32 in_fifo_start;			/* Starting address of IN-FIFO */
+	uint32 out_fifo_start;			/* Starting address of OUT-FIFO */
+	uint16 packet_size;			/* Maximum Packet Size */
+	uint8 ttype;				/* Transfer Type */
+	uint8 state;				/* State of endpoint */
+	uint8 dir;				/* Direction of transfer */
+	uint8 sendZLP;				/* send zero-length packet (if required) */
+	uint32 bytes_transferred;		/* The amount of successfully transferred bytes */
+	USB_BUFFER buffer;			/* Data Buffer for IN and OUT transfers */
+} USB_EP_STATE;
+
+/* USB Isochronous Endpoint State Info */
+typedef struct {
+	uint32 frame_counter;			/* Number of frames to be read or written */
+	uint32 packet_position;			/* Indicates current position within a packet */
+	uint16 start_frame_number;		/* Number of frame after which data stream will be monitored */
+	uint16 final_frame_number;		/* Number of frame after which data stream monitoring must be stopped */
+	uint16 state;				/* State of last transfer */
+	uint8 transfer_monitoring;
+	uint8 sent_packet_watch;
+	uint32* packet_length;			/* Pointer to the buffer header */
+	uint32 first_io_request;		/* Index of first request in a queue */
+	uint32 last_io_request;			/* Index of last request in a queue */
+	uint32 number_of_requests;		/* The number of requests in a queue */
+	IO_REQUEST requests_queue[MAX_IO_REQUESTS];
+} USB_ISO_EP_STATE;
+/********************************************************************/
+/* USB driver's functions definition */
+
+/* Initialize USB driver */
+void usb_init(DESC_INFO * descriptor_info);
+/* Initialize interrupts */
+void usb_isr_init(void);
+/* Endpoint ISRs */
+void usb_endpoint0_isr(int irq, void *dev_id, struct pt_regs *regs);
+void usb_endpoint_isr(int irq, void *dev_id, struct pt_regs *regs);
+/* EOP, EOT, FIFO_LVL interrupt handlers */
+void usb_in_service(uint32, uint32);
+void usb_out_service(uint32, uint32);
+/* Initialize FIFO buffer */
+void usb_fifo_init(void);
+/* Initiate reading/writing through endpoint */
+uint32 usb_tx(uint32, uint8 *, uint32);
+uint32 usb_rx_data(uint32, uint8 *, uint32);
+/* SOF interrupt handler. Is used for monitoring isochronous transfer */
+void usb_isochronous_transfer_service(void);
+/* Checks if endpoint is busy */
+int usb_ep_is_busy(uint32);
+/* Waits until endpoint becomes free */
+int usb_ep_wait(uint32, uint32);
+/* Returns address of required descriptor */
+uint8* usb_get_desc(int8, int8, int8, int8);
+/* Returns last command to client */
+uint32 usb_fetch_command(DEVICE_COMMAND *);
+/* Vendor specific requests service routine */
+void usb_vendreq_service(uint8,uint8, uint16, uint16, uint16);
+/* Handles DEV_CFG interrupt */
+void usb_devcfg_service(void);
+/* Handles RESUME, SUSPEND and RESET interrupts */
+void usb_bus_state_chg_service(uint32);
+/* Sets EP0CTL[CMD_OVER], EP0CTL[CMD_ERR] bits to appropriate values */
+void usb_vendreq_done(uint32);
+/* Extracts request from the queue */
+uint32 usb_get_request(uint32 epnum);
+
+void usb_ep_unhalt(uint32 epnum);
+void usb_ep_halt(uint32 epnum);
+/********************************************************************/
+
+#endif /* USB_DEFS_H */
diff -urN linux-2.4.29/drivers/char/mcf_usb.h linux-2.4.29-uc1/drivers/char/mcf_usb.h
--- linux-2.4.29/drivers/char/mcf_usb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/mcf_usb.h	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,187 @@
+/*********************************************************************
+ *
+ * Copyright:
+ *	MOTOROLA, INC. All Rights Reserved.  
+ *  You are hereby granted a copyright license to use, modify, and
+ *  distribute the SOFTWARE so long as this entire notice is
+ *  retained without alteration in any modified and/or redistributed
+ *  versions, and that such modified versions are clearly identified
+ *  as such. No licenses are granted by implication, estoppel or
+ *  otherwise under any patents or trademarks of Motorola, Inc. This 
+ *  software is provided on an "AS IS" basis and without warranty.
+ *
+ *  To the maximum extent permitted by applicable law, MOTOROLA 
+ *  DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING 
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+ *  PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH REGARD TO THE 
+ *  SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) AND ANY 
+ *  ACCOMPANYING WRITTEN MATERIALS.
+ * 
+ *  To the maximum extent permitted by applicable law, IN NO EVENT
+ *  SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING 
+ *  WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS 
+ *  INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY
+ *  LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.   
+ * 
+ *  Motorola assumes no responsibility for the maintenance and support
+ *  of this software
+ ********************************************************************/
+
+/*
+ * File:		usb.h
+ * Purpose:		USB Header File
+. Defines the interface of driver.
+ *			
+ */
+
+#ifndef USB_H
+#define USB_H
+
+/***********************************************************************/
+#ifndef _CPU_MCF5272_H
+typedef unsigned char		uint8;  /*  8 bits */
+typedef unsigned short int	uint16; /* 16 bits */
+typedef unsigned long int	uint32; /* 32 bits */
+#endif
+
+#ifdef	FALSE
+#undef	FALSE
+#endif
+#define FALSE	(0)
+
+#ifdef	TRUE
+#undef	TRUE
+#endif
+#define	TRUE	(1)
+
+#ifdef	NULL
+#undef	NULL
+#endif
+#define NULL	(0)
+
+/***********************************************************************/
+/* The major device number. We can't rely on dynamic
+ * registration, because we need to know major number. */
+#define MAJOR_NUM 127
+
+/* We use MAJOR_NUM as magic number */
+/* Initialize USB driver */
+#define USB_INIT _IOW(MAJOR_NUM, 0, char *)
+
+/* Get last command */
+#define USB_GET_COMMAND _IOR(MAJOR_NUM, 1, char *)
+
+/* Check if endpoint is busy */
+#define USB_EP_BUSY _IO(MAJOR_NUM, 2)
+
+/* Wait while endpoint is busy */
+#define USB_EP_WAIT _IOW(MAJOR_NUM, 3, uint32)
+
+/* Get current configuration number */
+#define USB_GET_CURRENT_CONFIG _IOR(MAJOR_NUM, 4, uint32)
+
+/* Accept command (send CMD_OVER to Host) */
+#define USB_COMMAND_ACCEPTED _IO(MAJOR_NUM, 5)
+
+/* Set NOT_SUPPORTED_COMMAND status (send CMD_OVER
+and CMD_ERROR to Host) */
+#define USB_NOT_SUPPORTED_COMMAND _IO(MAJOR_NUM, 6)
+
+/* Set sendZLP flag to TRUE */
+#define USB_SET_SEND_ZLP _IO(MAJOR_NUM, 7)
+
+/* Set start frame number for ISO transfer */
+#define USB_SET_START_FRAME _IOW(MAJOR_NUM, 8, uint32)
+
+/* Set final frame number for ISO transfer */
+#define USB_SET_FINAL_FRAME _IOW(MAJOR_NUM, 9, uint32)
+
+/* Get current frame number */
+#define USB_GET_FRAME_NUMBER _IO(MAJOR_NUM, 10)
+
+/* STALL given endpoint */
+#define USB_EP_STALL _IO(MAJOR_NUM, 12)
+/********************************************************************/
+
+/* The names of the device files */
+#define USB_EP0_FILE_NAME "/dev/usb0"
+#define USB_EP1_FILE_NAME "/dev/usb1"
+#define USB_EP2_FILE_NAME "/dev/usb2"
+#define USB_EP3_FILE_NAME "/dev/usb3"
+#define USB_EP4_FILE_NAME "/dev/usb4"
+#define USB_EP5_FILE_NAME "/dev/usb5"
+#define USB_EP6_FILE_NAME "/dev/usb6"
+#define USB_EP7_FILE_NAME "/dev/usb7"
+
+/* The name of the device */
+#define DEVICE_NAME "usb"
+
+/* Total number of EPs in this USB core */
+#define NUM_ENDPOINTS		8
+
+/* Definitions for Device Config Change events */
+#define USB_NO_NEW_COMMAND	0
+#define USB_CONFIGURATION_CHG	1
+#define USB_INTERFACE_CHG	2
+#define USB_ADDRESS_CHG		4
+#define USB_DEVICE_RESET	8
+#define USB_NEW_COMMAND		16
+
+/* Definitions for Bus State Change events */
+#define SUSPEND             	1 
+#define RESUME              	2
+#define ENABLE_WAKEUP      	4
+#define RESET               	8
+
+/* Definition for Device states */
+#define USB_CONFIGURED          0
+#define USB_NOT_CONFIGURED      2
+
+#define USB_EP_IS_FREE		0
+#define USB_EP_IS_BUSY		1
+
+/* Status definitions. These constants driver uses to report status, raised during a transfer,
+    to client application */
+#define SUCCESS			0
+#define MALLOC_ERROR		2
+#define NOT_SUPPORTED_COMMAND	4
+
+/********************************************************************/
+/* Structure contains current configuration and alt setting number */
+typedef struct {
+	uint32 cur_config_num;
+	uint32 altsetting;
+} CONFIG_STATUS;
+
+/* Structure for Request */
+typedef struct {
+	uint8 bmRequestType;
+	uint8 bRequest;
+	uint16 wValue;
+	uint16 wIndex;
+	uint16 wLength;
+} REQUEST;
+
+/* Structure for Command */
+typedef struct COMMAND_QUEUE_ITEM{
+	uint8 * cbuffer;							/* Pointer to command buffer */
+ 	REQUEST request;			/* Request from Host*/
+	struct COMMAND_QUEUE_ITEM * NextC;	/* Pointer to the next comand in the Queue */
+} QUEUE_ITEM;
+
+/* Structure for Command Buffer for Client*/
+typedef struct {
+	uint8 * cbuffer;							/* Pointer to command buffer */
+ 	REQUEST request;			/* Request from Host*/
+} DEVICE_COMMAND;
+
+/********************************************************************/
+typedef struct{
+        uint8 * pDescriptor;
+        uint32 DescSize;
+        uint8 * pStrDescriptor;
+} DESC_INFO;
+
+/********************************************************************/
+
+#endif /* USB_H */
diff -urN linux-2.4.29/drivers/char/mcfwatchdog.c linux-2.4.29-uc1/drivers/char/mcfwatchdog.c
--- linux-2.4.29/drivers/char/mcfwatchdog.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/mcfwatchdog.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,365 @@
+/***************************************************************************/
+
+/*
+ *	linux/drivers/char/mcfwatchdog.c
+ *
+ *	Copyright (C) 1999-2000, Greg Ungerer (gerg@snapgear.com)
+ * 	Copyright (C) 2000  Lineo Inc. (www.lineo.com)  
+ *
+ *  Added MCF5272 watchdog support, 2/9/2003 richard@uclinux.net
+ *
+ * Changes:
+ * 10/28/2004    Christian Magnusson <mag@mag.cx>
+ *               Bug: MCFSIM_SYPCR can only be written once after reset!
+ *               Reset on overflow. (For 5206e at least)
+ *               Added module support.
+ *               I have noticed that some flash-identification from mtd
+ *                 locks the processor too long, and therefor this watchdog
+ *                 has to be used as a module and started after mtd is done.
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcftimer.h>
+#include <asm/mcfsim.h>
+#include <asm/irq.h>
+#include <asm/delay.h>
+
+/***************************************************************************/
+
+/*
+ *	Define the watchdog vector.
+ */
+#ifdef CONFIG_M5272
+#define	IRQ_WATCHDOG	92
+#define	TIMEPOLL	100
+#else
+#define	IRQ_WATCHDOG	250
+#define	TIMEPOLL	HZ/100
+#endif
+
+#if defined(CONFIG_M5206e)
+#define RESET_ON_SWTR
+#endif
+
+/***************************************************************************/
+
+void	watchdog_alive(unsigned long arg);
+void	watchdog_timeout(int irq, void *dummy, struct pt_regs *fp);
+
+#ifndef MODULE
+extern void	dump(struct pt_regs *fp);
+#endif
+
+/*
+ *	Data for registering the watchdog alive routine with ticker.
+ */
+static struct timer_list	watchdog_timerlist;
+
+static int watchdog_overflows;
+
+#ifdef CONFIG_OLDMASK
+/*
+ *	The old mask 5307 has a broken watchdog timer. It will interrupt
+ *	you regardless of writing to its "alive" register. It can still
+ *	be useful but you have to play some tricks with it. This code
+ *	supports a clock ticker timeout. If the right number of clock
+ *	ticks are not counted then it is assumed that the watchdog saved
+ *	us from a bad bus cycle.
+ */
+#define	SWTREF_COUNT	25
+
+int	swt_inwatchdog = 0;		/* Has watchdog expired */
+int	swt_doit = 0;			/* Start delay before tripping */
+int	swt_lastjiffies = 0;		/* Tick count at last watchdog */
+int	swt_reference = SWTREF_COUNT;	/* Refereence tick count */
+#endif
+
+
+static struct file_operations watchdog_fops = {
+  owner:          THIS_MODULE,
+};
+
+static struct miscdevice watchdog_miscdev = {
+  minor:          WATCHDOG_MINOR,
+  name:           "watchdog",
+  fops:           &watchdog_fops,
+};
+
+/***************************************************************************/
+
+/*
+ *	Software Watchdog Timer enable. Seems to be the same across all
+ *	ColdFire CPU members.
+ */
+void watchdog_enable(void)
+{
+#ifdef CONFIG_M5272
+	*(volatile unsigned short *)(MCF_MBAR + MCFSIM_WRRR) = 0x2001;	// upper watchdog limit
+	*(volatile unsigned short *)(MCF_MBAR + MCFSIM_WIRR) = 0x1000;	// we don't do interrupts, just reset (o;
+	*(volatile unsigned short *)(MCF_MBAR + MCFSIM_WCR) = 0x0000;	// clear counter
+#else  /* CONFIG_M5272 */
+	volatile unsigned char	*mbar = (volatile unsigned char *) MCF_MBAR;
+	*(mbar + MCFSIM_SWSR) = 0x55;
+	*(mbar + MCFSIM_SWSR) = 0xaa; // kick watchdog
+
+	/*
+	  SYPCR Can only be written once after system reset!
+	  0x80 Software Watchdog, 0="Disable" / 1="Enable"
+	  0x40 Software Watchdog, 0="level7 interrupt" / 1="reset"
+	  0x20 Watchdog prescaled (SWP), 0="1" / 1="512" 
+	  0x10 Timing SWT1
+	  0x08 Timing SWT0
+	  	SWT|SWT1|SWT0
+	  	000=2^9  001=2^11 010=2^13 011=2^15 / System Freq.
+		100=2^18 101=2^20 110=2^22 111=2^24 / System Freq.
+	  0x04 Bus Timeout Monitor BMTE 0="Disable" / 1="Enable"
+	  0x02 Bus Monitor Timing BMT1
+	  0x01 Bus Monitor Timing BMT0
+	  	BMT1|BMT0
+	  	00=1024 01=512 10=256 11=128 system clocks
+	*/
+#ifdef CONFIG_OLDMASK
+	*(mbar + MCFSIM_SYPCR) = 0xbe; // level 7 interrupt, 2^22
+#else
+
+#ifdef RESET_ON_SWTR
+	*(mbar + MCFSIM_SYPCR) = 0xfe; // reset, 2^22
+#else
+	*(mbar + MCFSIM_SYPCR) = 0xbe; // level 7 interrupt, 2^22
+#endif /* RESET_ON_SWTR */
+#endif /* CONFIG_OLDMASK */
+#endif /* CONFIG_M5272 */
+}
+
+/***************************************************************************/
+
+void watchdog_disable(void)
+{
+#ifdef CONFIG_M5272
+	*(volatile unsigned short *)(MCF_MBAR + MCFSIM_WRRR) = 0xFFFE;
+	*(volatile unsigned short *)(MCF_MBAR + MCFSIM_WIRR) = 0x0000;
+	*(volatile unsigned short *)(MCF_MBAR + MCFSIM_WCR) = 0x0000;
+#else
+	volatile unsigned char	*mbar = (volatile unsigned char *) MCF_MBAR;
+	/*
+	  If watchdog is set to 'reset', this function is useless...
+	  If timer is disabled, this reset will occour at once.
+	*/
+	*(mbar + MCFSIM_SWSR) = 0x55;
+	*(mbar + MCFSIM_SWSR) = 0xaa;
+#if 0
+	/*
+	  SYPCR Can only be written once after system reset!
+	  This will probably be ignored according to MCF5206E User Manual
+	*/
+	*(mbar + MCFSIM_SYPCR) = 0x00 /*0x3e*/;
+#endif
+	mcf_setimr(mcf_getimr() | MCFSIM_IMR_SWD);
+#endif
+	del_timer(&watchdog_timerlist);
+}
+
+/***************************************************************************/
+
+static int watchdog_notify_sys(struct notifier_block *this, unsigned long code,
+	void *unused)
+{
+	if(code==SYS_DOWN || code==SYS_HALT) {
+		/* Turn the card off */
+		watchdog_disable();
+		/*
+		  If watchdog is set to 'reset', this function is useless...
+		  When timer is disabled, reset will occour during reboot...
+		*/
+	}
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block watchdog_notifier = {
+	.notifier_call = watchdog_notify_sys,
+};
+
+/***************************************************************************/
+
+/*
+ *	Process a watchdog timeout interrupt. For a normal clean watchdog
+ *	we just do a process dump. For old broken 5307 we need to verify
+ *	if this was a real watchdog event or not...
+ */
+void watchdog_timeout(int irq, void *dummy, struct pt_regs *fp)
+{
+#ifdef CONFIG_OLDMASK
+#define	TIMEDELAY	45
+	/*
+	 *	Debuging code for software watchdog. If we get in here
+	 *	and timer interrupt counts don't match we know that a
+	 *	bad external bus cycle must have locked the CPU.
+	 */
+	if ((swt_doit++ > TIMEDELAY) &&
+	    ((swt_lastjiffies + swt_reference) > jiffies)) {
+		if (swt_inwatchdog) {
+			cli();
+			watchdog_disable();
+			mcf_setimr(mcf_getimr() | MCFSIM_IMR_SWD);
+			printk("%s(%d): Double WATCHDOG PANIC!!\n",
+				__FILE__, __LINE__);
+			for (;;)
+				;
+		}
+
+		swt_inwatchdog++;
+		swt_doit = TIMEDELAY - 8;	/* 8 seconds grace */
+		printk("mcfwatchdog: expired last=%d(%d) jiffies=%d!\n",
+			swt_lastjiffies, swt_reference, jiffies);
+#ifndef MODULE
+		dump(fp);
+#endif
+		force_sig(SIGSEGV, current);
+		swt_inwatchdog  = 0;
+	}
+	swt_lastjiffies = jiffies;
+#else
+
+#ifdef RESET_ON_SWTR
+	/* nothing will be done... reset will occour */
+#else  /* RESET_ON_SWTR */
+	// lev7 interrupt is used.
+	if(++watchdog_overflows >= 10) {
+
+	  printk("mcfwatchdog: expired!\n");
+#ifndef MODULE
+	  dump(fp);
+#endif
+	  mcf_setimr(mcf_getimr() | MCFSIM_IMR_SWD);
+	  HARD_RESET_NOW();
+	  for (;;) ;  // hang until reboot
+	} else {
+	  volatile unsigned char *mbar = (volatile unsigned char *) MCF_MBAR;
+	  *(mbar + MCFSIM_SWSR) = 0x55;
+	  *(mbar + MCFSIM_SWSR) = 0xaa; // kick watchdog
+	}
+#endif /* RESET_ON_SWTR */
+#endif /* CONFIG_OLDMASK */
+}
+
+/***************************************************************************/
+
+static int __init watchdog_init(void)
+{
+	printk("mcfwatchdog: initializing at vector=%d\n", IRQ_WATCHDOG);
+
+        if(misc_register(&watchdog_miscdev))
+		return -ENODEV;
+
+	if(register_reboot_notifier(&watchdog_notifier)) {
+		printk("watchdog: cannot register reboot notifier\n");
+		return 1;
+	}
+
+	request_irq(IRQ_WATCHDOG, watchdog_timeout, SA_INTERRUPT,
+		    "Watchdog Timer", &watchdog_miscdev);
+
+	init_timer (&watchdog_timerlist);
+	watchdog_timerlist.function = watchdog_alive;
+ 	watchdog_timerlist.expires = (jiffies + 1);
+	add_timer(&watchdog_timerlist);
+
+#ifdef CONFIG_M5272
+{
+	volatile unsigned long	*icrp;
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR4);
+	*icrp = (*icrp & 0x77707777) | 0x000E0000;
+	watchdog_enable();
+}
+#else  /* CONFIG_M5272 */
+{
+	volatile unsigned char	*mbar = (volatile unsigned char *) MCF_MBAR;
+	unsigned char ch;
+
+	ch = *(mbar + MCFSIM_RSR);
+	printk("mcfwatchdog: Last reset was generated by %s\n",
+	       (ch&0x80 ? "HRST": (ch&0x20 ? "SWTR":"")));
+
+#ifdef RESET_ON_SWTR
+	// high priority just to make sure watchdog won't overflow.
+	*(mbar + MCFSIM_SWDICR) = MCFSIM_ICR_LEVEL1 | MCFSIM_ICR_PRI1;
+#else
+	*(mbar + MCFSIM_SWDICR) = MCFSIM_ICR_LEVEL1 | MCFSIM_ICR_PRI3;
+#endif
+	*(mbar + MCFSIM_SWIVR) = IRQ_WATCHDOG;
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_SWD);
+	watchdog_enable();
+
+	printk("mcfwatchdog: Coldfire watchdog is enabled, \"%s\" is generated on error\n",
+	       ((*(mbar + MCFSIM_SYPCR) & 0x40)?
+		"Reset" : "Level7 interrupt"));
+	
+#ifdef MODULE
+	if(*(mbar + MCFSIM_SYPCR) & 0x40) {
+	  printk("mcfwatchdog: Warning: If module is unloaded, Watchdog will reset card.\n");
+}
+#endif
+}
+#endif /* CONFIG_M5272 */
+	return 0;
+}
+
+/***************************************************************************/
+
+static void __exit watchdog_exit(void)
+{
+#ifdef CONFIG_M5272
+	/* Reset watchdog counter */
+	*(volatile unsigned short *)(MCF_MBAR + MCFSIM_WCR) = 0x0000;
+#else
+	volatile unsigned char	*mbar = (volatile unsigned char *) MCF_MBAR;
+	*(mbar + MCFSIM_RSR) = 0; // clear reset cause
+#endif
+	unregister_reboot_notifier(&watchdog_notifier);
+	misc_deregister(&watchdog_miscdev);
+	watchdog_disable();
+	printk("mcfwatchdog: Coldfire watchdog is disabled and unloaded\n");
+}
+
+/***************************************************************************/
+
+void watchdog_alive(unsigned long arg)
+{
+#ifdef CONFIG_M5272
+	/* Reset watchdog counter */
+	*(volatile unsigned short *)(MCF_MBAR + MCFSIM_WCR) = 0x0000;
+#else
+	volatile unsigned char	*mbar = (volatile unsigned char *) MCF_MBAR;
+	*(mbar + MCFSIM_SWSR) = 0x55;
+	*(mbar + MCFSIM_SWSR) = 0xaa; // kick watchdog
+#endif
+	/* Re-arm the watchdog alive poll */
+	mod_timer(&watchdog_timerlist, jiffies+TIMEPOLL);
+	watchdog_overflows = 0;
+}
+
+/***************************************************************************/
+
+module_init(watchdog_init);
+module_exit(watchdog_exit);
+
+MODULE_AUTHOR("Greg Ungerer");
+MODULE_DESCRIPTION("Coldfire Watchdog Driver");
+MODULE_LICENSE("GPL");
+
+/***************************************************************************/
diff -urN linux-2.4.29/drivers/char/mem.c linux-2.4.29-uc1/drivers/char/mem.c
--- linux-2.4.29/drivers/char/mem.c	2004-08-08 00:26:04.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/mem.c	2005-06-14 02:12:18.000000000 +0100
@@ -6,6 +6,8 @@
  *  Added devfs support. 
  *    Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
  *  Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
+ *  NO_MM changes Dec 2000, David McCullough <davidm@snapgear.com> based on
+ *    work by Kenneth Albanowski <kjahds@kjahds.com>.
  */
 
 #include <linux/config.h>
@@ -49,7 +51,7 @@
 	ssize_t written;
 
 	written = 0;
-#if defined(__sparc__) || defined(__mc68000__)
+#if defined(__sparc__) || defined(__mc68000__) && !defined(NO_MM)
 	/* we don't have page 0 mapped on sparc and m68k.. */
 	if (realp < PAGE_SIZE) {
 		unsigned long sz = PAGE_SIZE-realp;
@@ -86,7 +88,7 @@
 	if (count > end_mem - p)
 		count = end_mem - p;
 	read = 0;
-#if defined(__sparc__) || defined(__mc68000__)
+#if defined(__sparc__) || defined(__mc68000__) && !defined(NO_MM)
 	/* we don't have page 0 mapped on sparc and m68k.. */
 	if (p < PAGE_SIZE) {
 		unsigned long sz = PAGE_SIZE-p;
@@ -140,7 +142,7 @@
 		prot |= _PAGE_PCD | _PAGE_PWT;
 #elif defined(__powerpc__)
 	prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
-#elif defined(__mc68000__)
+#elif defined(__mc68000__) && !defined(NO_MM)
 #ifdef SUN3_PAGE_NOCACHE
 	if (MMU_IS_SUN3)
 		prot |= SUN3_PAGE_NOCACHE;
@@ -185,6 +187,7 @@
 
 static int mmap_mem(struct file * file, struct vm_area_struct * vma)
 {
+#ifndef NO_MM
 	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
 
 	/*
@@ -208,7 +211,22 @@
 			     vma->vm_page_prot))
 		return -EAGAIN;
 	return 0;
+#else /* !NO_MM */
+	/* Return the physical address unmodified if it's possible to do
+	   so given the arguments.  */
+	if (vma->vm_start == file->f_pos + vma->vm_offset)
+		return 0;
+	else
+		return -EINVAL;
+#endif /* !NO_MM */
+}
+
+#ifdef NO_MM
+unsigned long get_unmapped_area_mem (struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	return file->f_pos + (pgoff << PAGE_SHIFT);
 }
+#endif
 
 /*
  * This function reads the *virtual* memory as seen by the kernel.
@@ -226,7 +244,7 @@
 		if (count > (unsigned long) high_memory - p)
 			read = (unsigned long) high_memory - p;
 
-#if defined(__sparc__) || defined(__mc68000__)
+#if defined(__sparc__) || defined(__mc68000__) && !defined(NO_MM)
 		/* we don't have page 0 mapped on sparc and m68k.. */
 		if (p < PAGE_SIZE && read > 0) {
 			size_t tmp = PAGE_SIZE - p;
@@ -376,6 +394,7 @@
 	return count;
 }
 
+#ifndef NO_MM
 /*
  * For fun, we are using the MMU for this.
  */
@@ -430,10 +449,12 @@
 	return size;
 }
 
+#endif /* NO_MM */
+
 static ssize_t read_zero(struct file * file, char * buf, 
 			 size_t count, loff_t *ppos)
 {
-	unsigned long left, unwritten, written = 0;
+	unsigned long left;
 
 	if (!count)
 		return 0;
@@ -443,6 +464,9 @@
 
 	left = count;
 
+#ifndef NO_MM
+{
+	unsigned long unwritten, written = 0;
 	/* do we want to be clever? Arbitrary cut-off */
 	if (count >= PAGE_SIZE*4) {
 		unsigned long partial;
@@ -467,14 +491,28 @@
 out:
 	return written ? written : -EFAULT;
 }
+#else
+    for (left = count; left > 0; left--) {
+        put_user(0,buf);
+        buf++;
+		if (current->need_resched)
+			schedule();
+    }
+	return(count);
+#endif
+}
 
 static int mmap_zero(struct file * file, struct vm_area_struct * vma)
 {
+#ifndef NO_MM
 	if (vma->vm_flags & VM_SHARED)
 		return shmem_zero_setup(vma);
 	if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
 		return -EAGAIN;
 	return 0;
+#else
+	return -ENOSYS;
+#endif
 }
 
 static ssize_t write_full(struct file * file, const char * buf,
@@ -528,6 +566,8 @@
 	return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
 }
 
+#ifndef NO_MM
+
 struct page *kmem_vm_nopage(struct vm_area_struct *vma, unsigned long address, int write)
 {
 	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
@@ -577,8 +617,11 @@
 	nopage:		kmem_vm_nopage,
 };
 
+#endif /* NO_MM */
+
 static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
 {
+#ifndef NO_MM
 	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
 	unsigned long size = vma->vm_end - vma->vm_start;
 
@@ -611,6 +654,10 @@
 	vma->vm_flags |= VM_IO;
 
 	return 0;
+
+#else /* NO_MM */
+	return mmap_mem(file, vma); /* lets see how we go with this */
+#endif /* NO_MM */
 }
 
 #define zero_lseek	null_lseek
@@ -625,6 +672,9 @@
 	read:		read_mem,
 	write:		write_mem,
 	mmap:		mmap_mem,
+#ifdef NO_MM
+	get_unmapped_area: get_unmapped_area_mem,
+#endif
 	open:		open_mem,
 };
 
@@ -766,6 +816,9 @@
 #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
 	tapechar_init();
 #endif
+#ifdef CONFIG_COLDFIRE_USB
+	init_usb();
+#endif
 	return 0;
 }
 
diff -urN linux-2.4.29/drivers/char/misc.c linux-2.4.29-uc1/drivers/char/misc.c
--- linux-2.4.29/drivers/char/misc.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/char/misc.c	2005-06-14 02:12:18.000000000 +0100
@@ -73,6 +73,7 @@
 extern int tosh_init(void);
 extern int i8k_init(void);
 extern int lcd_init(void);
+extern int gio_c5471_init(void);
 
 static int misc_read_proc(char *buf, char **start, off_t offset,
 			  int len, int *eof, void *private)
@@ -272,6 +273,9 @@
 #ifdef CONFIG_I8K
 	i8k_init();
 #endif
+#ifdef CONFIG_C5471_GIO
+	gio_c5471_init();
+#endif
 	if (devfs_register_chrdev(MISC_MAJOR,"misc",&misc_fops)) {
 		printk("unable to get major %d for misc devices\n",
 		       MISC_MAJOR);
diff -urN linux-2.4.29/drivers/char/NIOSserial.c linux-2.4.29-uc1/drivers/char/NIOSserial.c
--- linux-2.4.29/drivers/char/NIOSserial.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/NIOSserial.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,1420 @@
+/* NIOSserial.c: Serial port driver for builtin NIOS UART.
+ *
+ * Copyright (C) 1995       David S. Miller    <davem@caip.rutgers.edu>
+ * Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ * Copyright (C) 1998-2000  D. Jeff Dionne     <jeff@uClinux.org>
+ * Copyright (C) 1999       Vladimir Gurevich  <vgurevic@cisco.com>
+ * Copyright (C) 2001       Vic Phillips       <vic@microtronix.com>
+ * Copyright (C) 2001       Wentao Xu          <wentao@microtronix.com>
+ */
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/config.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/reboot.h>
+#include <linux/keyboard.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+#include <asm/uaccess.h>
+
+#include "NIOSserial.h"
+
+extern void hard_reset_now(void);
+
+//struct tty_struct NIOS_ttys;
+//struct NIOS_serial *NIOS_consinfo = 0;
+
+DECLARE_TASK_QUEUE(tq_serial);
+
+struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+/* serial subtype definitions */
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+/* Debugging... DEBUG_INTR is bad to use when one of the zs
+ * lines is your console ;(
+ */
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+
+#define RS_ISR_PASS_LIMIT 256
+
+#define _INLINE_ inline
+
+static void change_speed(struct NIOS_serial *info);
+
+/*
+ *	Configuration table, UARTs to look for at startup.
+ */
+static struct NIOS_serial nios_soft[] = {
+//	{ 0,0,1,0,0,0,0, (nasys_printf_uart), (nasys_printf_uart_irq) }, /* ttyS0 */
+	{ 0,0,1,0,0,0,0, (int) (na_uart0), (na_uart0_irq) },		/* ttyS0 */
+#ifdef na_uart1
+//	{ 0,0,0,0,0,0,0, (nasys_gdb_uart), (nasys_gdb_uart_irq) },		  /* ttyS1 */
+	{ 0,0,0,0,0,0,0, (int) (na_uart1), (na_uart1_irq) },		/* ttyS1 */
+#endif
+#ifdef na_uart2
+	{ 0,0,0,0,0,0,0, (int) (na_uart2), (na_uart2_irq) },		/* ttyS2 */
+#endif
+#ifdef na_uart3
+	{ 0,0,0,0,0,0,0, (int) (na_uart3), (na_uart3_irq) },		/* ttyS3 */
+#endif
+};
+
+#define	NR_PORTS	(sizeof(nios_soft) / sizeof(struct NIOS_serial))
+
+
+static struct tty_struct *serial_table[NR_PORTS];
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the memcpy_fromfs blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static unsigned char tmp_buf[SERIAL_XMIT_SIZE]; /* This is cheating */
+DECLARE_MUTEX(tmp_buf_sem);
+
+static inline int serial_paranoia_check(struct NIOS_serial *info,
+					dev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%d, %d) in %s\n";
+	static const char *badinfo =
+		"Warning: null NIOS_serial for (%d, %d) in %s\n";
+
+	if (!info) {
+		printk(badinfo, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+	if (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+/*
+ * This is used to figure out the divisor speeds and the timeouts
+ */
+static int baud_table[] = {
+	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
+	9600, 19200, 38400, 57600, 115200, 0 };
+
+/* Sets or clears DTR/RTS on the requested line */
+static inline void NIOS_rtsdtr(struct NIOS_serial *ss, int set)
+{
+	if (set) {
+		/* set the RTS/CTS line */
+	} else {
+		/* clear it */
+	}
+	return;
+}
+
+/* Utility routines */
+static inline int get_baud(struct NIOS_serial *ss)
+{
+	return 0;	/* not implemented yet */
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+	struct NIOS_serial *info = (struct NIOS_serial *)tty->driver_data;
+	np_uart *	uart= (np_uart *)(info->port);
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_stop"))
+		return;
+
+	save_flags(flags); cli();
+	uart->np_uartcontrol &= ~np_uartcontrol_itrdy_mask;
+	restore_flags(flags);
+}
+
+void rs_put_char(char ch, struct NIOS_serial *info)
+{
+	int flags, loops = 0;
+	np_uart *	uart= (np_uart *)(info->port);
+
+	save_flags(flags); cli();
+
+	while (!(uart->np_uartstatus & np_uartstatus_trdy_mask) && (loops < 1000)) {
+		loops++;
+	}
+
+	uart->np_uarttxdata = ch;
+	restore_flags(flags);
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+	struct NIOS_serial *info = (struct NIOS_serial *)tty->driver_data;
+	unsigned long flags;
+	np_uart *	uart= (np_uart *)(info->port);
+
+	if (serial_paranoia_check(info, tty->device, "rs_start"))
+		return;
+
+	save_flags(flags); cli();
+	if (info->xmit_cnt && info->xmit_buf && !(uart->np_uartcontrol & np_uartcontrol_itrdy_mask)) {
+#ifdef USE_INTS
+		uart->np_uartcontrol &= np_uartcontrol_itrdy_mask;
+#endif
+	}
+	restore_flags(flags);
+}
+
+/* Drop into either the boot monitor or gdb upon receiving a break
+ * from keyboard/console input.
+ */
+static void batten_down_hatches(void)
+{
+	/* Drop into the debugger */
+	nios_gdb_breakpoint();
+}
+
+static _INLINE_ void status_handle(struct NIOS_serial *info, unsigned short status)
+{
+	return;
+}
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static _INLINE_ void rs_sched_event(struct NIOS_serial *info,
+				    int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_serial);
+	mark_bh(SERIAL_BH);
+}
+
+static _INLINE_ void receive_chars(struct NIOS_serial *info, struct pt_regs *regs, unsigned short rx)
+{
+	struct tty_struct *tty = info->tty;
+	unsigned char ch;
+	np_uart *	uart= (np_uart *)(info->port);
+
+	/*
+	 * This do { } while() loop will get ALL chars out of Rx FIFO
+         */
+	do {
+		ch = uart->np_uartrxdata;
+
+		if(info->is_cons) {
+#ifdef CONFIG_MAGIC_SYSRQ
+			if(rx & np_uartstatus_brk_mask) {
+				batten_down_hatches();
+				return;
+			} else if (ch == 0x10) { /* ^P */
+				show_state();
+				show_mem();
+				return;
+			} else if (ch == 0x12) { /* ^R */
+				hard_reset_now();
+				return;
+#ifdef DEBUG
+			} else if (ch == 0x02) { /* ^B */
+				batten_down_hatches();
+				return;
+			} else if (ch == 0x01) { /* ^A */
+				asm("trap 0");		/* Back to monitor */
+				return;			/* (won't be coming back) */
+#endif
+			}
+#endif /* CONFIG_MAGIC_SYSRQ */
+		}
+
+		if(!tty)
+			goto clear_and_exit;
+
+		/*
+		 * Make sure that we do not overflow the buffer
+		 */
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			queue_task(&tty->flip.tqueue, &tq_timer);
+			return;
+		}
+
+		if(rx & np_uartstatus_pe_mask) {
+			*tty->flip.flag_buf_ptr++ = TTY_PARITY;
+			status_handle(info, rx);
+		} else if(rx & np_uartstatus_roe_mask) {
+			*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+			status_handle(info, rx);
+		} else if(rx & np_uartstatus_fe_mask) {
+			*tty->flip.flag_buf_ptr++ = TTY_FRAME;
+			status_handle(info, rx);
+		} else if(rx & np_uartstatus_brk_mask) {
+			*tty->flip.flag_buf_ptr++ = TTY_BREAK;
+			status_handle(info, rx);
+		} else {
+			*tty->flip.flag_buf_ptr++ = 0; /* XXX */
+		}
+		*tty->flip.char_buf_ptr++ = ch;
+		tty->flip.count++;
+
+	} while((rx = uart->np_uartstatus) & np_uartstatus_rrdy_mask);
+
+	queue_task(&tty->flip.tqueue, &tq_timer);
+
+clear_and_exit:
+	return;
+}
+
+static _INLINE_ void transmit_chars(struct NIOS_serial *info)
+{
+	np_uart *	uart= (np_uart *)(info->port);
+	if (info->x_char) {
+		/* Send next char */
+		uart->np_uarttxdata = info->x_char;
+		info->x_char = 0;
+		goto clear_and_return;
+	}
+
+	if((info->xmit_cnt <= 0) || info->tty->stopped) {
+		/* That's peculiar... TX ints off */
+		uart->np_uartcontrol &= ~np_uartcontrol_itrdy_mask;
+		goto clear_and_return;
+	}
+
+	/* Send char */
+	uart->np_uarttxdata = info->xmit_buf[info->xmit_tail++];
+	info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+	info->xmit_cnt--;
+
+	if (info->xmit_cnt < WAKEUP_CHARS)
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+	if(info->xmit_cnt <= 0) {
+		/* All done for now... TX ints off */
+		uart->np_uartcontrol &= ~np_uartcontrol_itrdy_mask;
+		goto clear_and_return;
+	}
+
+clear_and_return:
+	/* Clear interrupt (should be auto)*/
+	return;
+}
+
+/*
+ * This is the serial driver's generic interrupt routine
+ */
+void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct NIOS_serial * info = (struct NIOS_serial *) dev_id;
+	np_uart *	uart= (np_uart *)(info->port);
+	unsigned short stat = uart->np_uartstatus;
+	uart->np_uartstatus = 0;		/* clear any error status */
+
+	if (stat & np_uartstatus_rrdy_mask) receive_chars(info, regs, stat);
+	if (stat & np_uartstatus_trdy_mask) transmit_chars(info);
+	return;
+}
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct NIOS_serial	*info = (struct NIOS_serial *) private_;
+	struct tty_struct	*tty;
+
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+	}
+}
+
+/*
+ * This routine is called from the scheduler tqueue when the interrupt
+ * routine has signalled that a hangup has occurred.  The path of
+ * hangup processing is:
+ *
+ * 	serial interrupt routine -> (scheduler tqueue) ->
+ * 	do_serial_hangup() -> tty->hangup() -> rs_hangup()
+ *
+ */
+static void do_serial_hangup(void *private_)
+{
+	struct NIOS_serial	*info = (struct NIOS_serial *) private_;
+	struct tty_struct	*tty;
+
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	tty_hangup(tty);
+}
+
+
+
+static int startup(struct NIOS_serial * info)
+{
+	unsigned long flags;
+	np_uart *	uart= (np_uart *)(info->port);
+
+	if (info->flags & S_INITIALIZED)
+		return 0;
+
+	if (!info->xmit_buf) {
+		info->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL);
+		if (!info->xmit_buf)
+			return -ENOMEM;
+	}
+
+	save_flags(flags); cli();
+
+	/*
+	 * Clear the FIFO buffers and disable them
+	 * (they will be reenabled in change_speed())
+	 */
+
+	change_speed(info);
+
+	info->xmit_fifo_size = 1;
+	uart->np_uartcontrol = np_uartcontrol_itrdy_mask
+												 | np_uartcontrol_irrdy_mask
+												 | np_uartcontrol_ibrk_mask;
+	uart->np_uartrxdata;
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+
+	info->flags |= S_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct NIOS_serial * info)
+{
+	unsigned long	flags;
+	np_uart *	uart= (np_uart *)(info->port);
+
+	uart->np_uartcontrol = 0; /* All off! */
+	if (!(info->flags & S_INITIALIZED))
+		return;
+
+	save_flags(flags); cli(); /* Disable interrupts */
+
+	if (info->xmit_buf) {
+		free_page((unsigned long) info->xmit_buf);
+		info->xmit_buf = 0;
+	}
+
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~S_INITIALIZED;
+	restore_flags(flags);
+}
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void change_speed(struct NIOS_serial *info)
+{
+#if 1		/* NIOS usually has a fixed speed */
+
+//	unsigned long ustcnt;
+	unsigned cflag;
+	unsigned divisor;
+	int	i;
+	np_uart *	uart= (np_uart *)(info->port);
+
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+
+//	ustcnt = uart->np_uartcontrol;
+//	uart->np_uartcontrol = ustcnt & ~UCTRL_TE;
+
+	i = cflag & CBAUD;
+	if (i & CBAUDEX) {
+		i = (i & ~CBAUDEX) + B38400;
+	}
+
+	divisor = (unsigned)(((unsigned)nasys_clock_freq *1.0 / baud_table[i]) + 1) -1;
+	uart->np_uartdivisor = divisor;
+	if (uart->np_uartdivisor == divisor)
+		info->baud = baud_table[i];
+
+//	ustcnt &= ~(UCTRL_PE | UCTRL_PS);
+//	if ((cflag & CSIZE) == CS8)
+//		ustcnt |= USTCNT_8_7;
+//	if (cflag & CSTOPB)
+//		ustcnt |= USTCNT_STOP;
+//	if (cflag & PARENB)
+//		ustcnt |= UCTRL_PE;
+//	if (!(cflag & PARODD))
+//		ustcnt |= UCTRL_PS;
+//	if (cflag & CRTSCTS) {
+//		ustcnt |= UCTRL_FL;
+//	} else {
+//		ustcnt &= ~UCTRL_FL;
+//	}
+//	ustcnt |= UCTRL_TE;
+//	uart->np_uartcontrol = ustcnt;
+
+#endif
+}
+
+/*
+ * Fair output driver allows a process to speak.
+ */
+#if 0
+static void rs_fair_output(void)
+{
+	int left;		/* Output no more than that */
+	unsigned long flags;
+	struct NIOS_serial *info = &nios_soft;
+	char c;
+
+	if (info == 0) return;
+	if (info->xmit_buf == 0) return;
+
+	save_flags(flags);  cli();
+	left = info->xmit_cnt;
+	while (left != 0) {
+		c = info->xmit_buf[info->xmit_tail];
+		info->xmit_tail = (info->xmit_tail+1) & (SERIAL_XMIT_SIZE-1);
+		info->xmit_cnt--;
+		restore_flags(flags);
+
+		rs_put_char(c, info);
+
+		save_flags(flags);  cli();
+		left = MIN(info->xmit_cnt, left-1);
+	}
+
+	/* Last character is being transmitted now (hopefully). */
+	udelay(5);
+
+	restore_flags(flags);
+	return;
+}
+#endif
+
+/*
+ * console_print_NIOS is registered for printk.
+ */
+void console_print_NIOS(const char *p)
+{
+	char c;
+
+	while((c=*(p++)) != 0) {
+		if(c == '\n')
+			rs_put_char('\r', nios_soft);
+		rs_put_char(c, nios_soft);
+	}
+
+	/* Comment this if you want to have a strict interrupt-driven output */
+	/* rs_fair_output(); */
+
+	return;
+}
+
+static void rs_set_ldisc(struct tty_struct *tty)
+{
+	struct NIOS_serial *info = (struct NIOS_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_set_ldisc"))
+		return;
+
+	info->is_cons = (tty->termios->c_line == N_TTY);
+
+	printk("ttyS%d console mode %s\n", info->line, info->is_cons ? "on" : "off");
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct NIOS_serial *info = (struct NIOS_serial *)tty->driver_data;
+	unsigned long flags;
+	np_uart *	uart= (np_uart *)(info->port);
+
+	if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
+		return;
+
+	save_flags(flags); cli();
+
+	if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
+	    !info->xmit_buf)
+		goto flush_exit;
+
+	/* Enable transmitter */
+
+	uart->np_uartcontrol |= np_uartcontrol_itrdy_mask;
+
+	if (uart->np_uartstatus & np_uartstatus_trdy_mask) {
+		/* Send char */
+		uart->np_uarttxdata = info->xmit_buf[info->xmit_tail++];
+		info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+		info->xmit_cnt--;
+	}
+
+flush_exit:
+	restore_flags(flags);
+}
+
+extern void console_printn(const char * b, int count);
+
+static int rs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	int	c, total = 0;
+	struct NIOS_serial *info = (struct NIOS_serial *)tty->driver_data;
+	unsigned long flags;
+	np_uart *	uart= (np_uart *)(info->port);
+
+	if (serial_paranoia_check(info, tty->device, "rs_write"))
+		return 0;
+
+	if (!tty || !info->xmit_buf)
+		return 0;
+
+	save_flags(flags);
+	while (1) {
+		cli();
+		c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				   SERIAL_XMIT_SIZE - info->xmit_head));
+		if (c <= 0)
+			break;
+
+		if (from_user) {
+			down(&tmp_buf_sem);
+			copy_from_user(tmp_buf, buf, c);
+			c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				       SERIAL_XMIT_SIZE - info->xmit_head));
+			memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
+			up(&tmp_buf_sem);
+		} else
+			memcpy(info->xmit_buf + info->xmit_head, buf, c);
+		info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+		info->xmit_cnt += c;
+		restore_flags(flags);
+		buf += c;
+		count -= c;
+		total += c;
+	}
+
+	if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
+		/* Enable transmitter */
+		cli();
+
+		uart->np_uartcontrol |= np_uartcontrol_itrdy_mask;
+
+		if (uart->np_uartstatus & np_uartstatus_trdy_mask) {
+			uart->np_uarttxdata = info->xmit_buf[info->xmit_tail++];
+			info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+			info->xmit_cnt--;
+		}
+
+		restore_flags(flags);
+	}
+	restore_flags(flags);
+	return total;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct NIOS_serial *info = (struct NIOS_serial *)tty->driver_data;
+	int	ret;
+
+	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
+		return 0;
+	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
+	if (ret < 0)
+		ret = 0;
+	return ret;
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct NIOS_serial *info = (struct NIOS_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+		return 0;
+	return info->xmit_cnt;
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	struct NIOS_serial *info = (struct NIOS_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+		return;
+	cli();
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+	sti();
+	wake_up_interruptible(&tty->write_wait);
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ *
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct * tty)
+{
+	struct NIOS_serial *info = (struct NIOS_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+		return;
+
+	if (I_IXOFF(tty))
+		info->x_char = STOP_CHAR(tty);
+
+	/* Turn off RTS line (do this atomic) */
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+	struct NIOS_serial *info = (struct NIOS_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+		return;
+
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			info->x_char = START_CHAR(tty);
+	}
+
+	/* Assert RTS line (do this atomic) */
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int get_serial_info(struct NIOS_serial * info,
+			   struct serial_struct * retinfo)
+{
+	struct serial_struct tmp;
+
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = info->type;
+	tmp.line = info->line;
+	tmp.port = info->port;
+	tmp.irq = info->irq;
+	tmp.flags = info->flags;
+	tmp.baud_base = info->baud_base;
+	tmp.close_delay = info->close_delay;
+	tmp.closing_wait = info->closing_wait;
+	tmp.custom_divisor = info->custom_divisor;
+	copy_to_user(retinfo,&tmp,sizeof(*retinfo));
+	return 0;
+}
+
+static int set_serial_info(struct NIOS_serial * info,
+			   struct serial_struct * new_info)
+{
+	struct serial_struct new_serial;
+	struct NIOS_serial old_info;
+	int 			retval = 0;
+
+	if (!new_info)
+		return -EFAULT;
+	copy_from_user(&new_serial,new_info,sizeof(new_serial));
+	old_info = *info;
+
+	if (!suser()) {
+		if ((new_serial.baud_base != info->baud_base) ||
+		    (new_serial.type != info->type) ||
+		    (new_serial.close_delay != info->close_delay) ||
+		    ((new_serial.flags & ~S_USR_MASK) !=
+		     (info->flags & ~S_USR_MASK)))
+			return -EPERM;
+		info->flags = ((info->flags & ~S_USR_MASK) |
+			       (new_serial.flags & S_USR_MASK));
+		info->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	if (info->count > 1)
+		return -EBUSY;
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+	info->baud_base = new_serial.baud_base;
+	info->flags = ((info->flags & ~S_FLAGS) |
+			(new_serial.flags & S_FLAGS));
+	info->type = new_serial.type;
+	info->close_delay = new_serial.close_delay;
+	info->closing_wait = new_serial.closing_wait;
+
+check_and_exit:
+	retval = startup(info);
+	return retval;
+}
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space.
+ */
+static int get_lsr_info(struct NIOS_serial * info, unsigned int *value)
+{
+	unsigned char status;
+
+	status = 0;
+	put_user(status,value);
+	return 0;
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void send_break(	struct NIOS_serial * info, int duration)
+{
+}
+
+static int rs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	int error;
+	struct NIOS_serial * info = (struct NIOS_serial *)tty->driver_data;
+	int retval;
+
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
+	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+
+	switch (cmd) {
+		case TCSBRK:	/* SVID version: non-zero arg --> no break */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (!arg)
+				send_break(info, HZ/4);	/* 1/4 second */
+			return 0;
+		case TCSBRKP:	/* support for POSIX tcsendbreak() */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+			return 0;
+		case TIOCGSOFTCAR:
+			error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long));
+			if (error)
+				return error;
+			put_user(C_CLOCAL(tty) ? 1 : 0,
+				    (unsigned long *) arg);
+			return 0;
+		case TIOCSSOFTCAR:
+			get_user(arg, (unsigned long *) arg);
+			tty->termios->c_cflag =
+				((tty->termios->c_cflag & ~CLOCAL) |
+				 (arg ? CLOCAL : 0));
+			return 0;
+		case TIOCGSERIAL:
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+						sizeof(struct serial_struct));
+			if (error)
+				return error;
+			return get_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSSERIAL:
+			return set_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSERGETLSR: /* Get line status register */
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+				sizeof(unsigned int));
+			if (error)
+				return error;
+			else
+			    return get_lsr_info(info, (unsigned int *) arg);
+
+		case TIOCSERGSTRUCT:
+			error = verify_area(VERIFY_WRITE, (void *) arg,
+						sizeof(struct NIOS_serial));
+			if (error)
+				return error;
+			copy_to_user((struct NIOS_serial *) arg,
+				    info, sizeof(struct NIOS_serial));
+			return 0;
+
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	struct NIOS_serial *info = (struct NIOS_serial *)tty->driver_data;
+	int	oldbaud = info->baud;
+
+	if (tty->termios->c_cflag == old_termios->c_cflag)
+		return;
+
+	change_speed(info);
+
+	if (info->baud == oldbaud) /* can not change */
+		tty->termios->c_cflag = old_termios->c_cflag;
+	else	/* only speed can be changed */
+		tty->termios->c_cflag = (tty->termios->c_cflag & CBAUD) | CS8 | CREAD | HUPCL | CLOCAL;
+#if 0
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+#endif
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ *
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * S structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+	struct NIOS_serial * info = (struct NIOS_serial *)tty->driver_data;
+	unsigned long flags;
+	np_uart *	uart= (np_uart *)(info->port);
+
+	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+		return;
+
+	save_flags(flags); cli();
+
+	if (tty_hung_up_p(filp)) {
+		restore_flags(flags);
+		return;
+	}
+
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  Info->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+		       "info->count is %d\n", info->count);
+		info->count = 1;
+	}
+	if (--info->count < 0) {
+		printk("rs_close: bad serial port count for ttyS%d: %d\n",
+		       info->line, info->count);
+		info->count = 0;
+	}
+	if (info->count) {
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= S_CLOSING;
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & S_NORMAL_ACTIVE)
+		info->normal_termios = *tty->termios;
+	if (info->flags & S_CALLOUT_ACTIVE)
+		info->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != S_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+
+	uart->np_uartcontrol &= ~(np_uartcontrol_irrdy_mask);
+
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (tty->ldisc.num != tty_ldiscs[N_TTY].num) {
+		if (tty->ldisc.close)
+			(tty->ldisc.close)(tty);
+		tty->ldisc = tty_ldiscs[N_TTY];
+		tty->termios->c_line = N_TTY;
+		if (tty->ldisc.open)
+			(tty->ldisc.open)(tty);
+	}
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(S_NORMAL_ACTIVE|S_CALLOUT_ACTIVE|
+			 S_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	restore_flags(flags);
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+void rs_hangup(struct tty_struct *tty)
+{
+	struct NIOS_serial * info = (struct NIOS_serial *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
+		return;
+
+	rs_flush_buffer(tty);
+	shutdown(info);
+	info->event = 0;
+	info->count = 0;
+	info->flags &= ~(S_NORMAL_ACTIVE|S_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file * filp,
+			   struct NIOS_serial *info)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int		retval;
+	int		do_clocal = 0;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (info->flags & S_CLOSING) {
+		interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		if (info->flags & S_HUP_NOTIFY)
+			return -EAGAIN;
+		else
+			return -ERESTARTSYS;
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & S_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+		    (info->flags & S_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+		    return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+		    (info->flags & S_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+		    return -EBUSY;
+		info->flags |= S_CALLOUT_ACTIVE;
+		return 0;
+	}
+
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & S_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= S_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & S_CALLOUT_ACTIVE) {
+		if (info->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, info->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+
+	info->count--;
+	info->blocked_open++;
+	while (1) {
+		cli();
+		if (!(info->flags & S_CALLOUT_ACTIVE))
+			NIOS_rtsdtr(info, 1);
+		sti();
+		current->state = TASK_INTERRUPTIBLE;
+		if (tty_hung_up_p(filp) ||
+		    !(info->flags & S_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & S_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & S_CALLOUT_ACTIVE) &&
+		    !(info->flags & S_CLOSING) && do_clocal)
+			break;
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&info->open_wait, &wait);
+	if (!tty_hung_up_p(filp))
+		info->count++;
+	info->blocked_open--;
+
+	if (retval)
+		return retval;
+	info->flags |= S_NORMAL_ACTIVE;
+	return 0;
+}
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its S structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+int rs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct NIOS_serial	*info;
+	int 			retval, line;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+
+	if (line >=serial_driver.num) /* too many */
+		return -ENODEV;
+
+	info = &nios_soft[line];
+
+	if (serial_paranoia_check(info, tty->device, "rs_open"))
+		return -ENODEV;
+
+	info->count++;
+	tty->driver_data = info;
+	info->tty = tty;
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval)
+		return retval;
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+		return retval;
+	}
+
+	if ((info->count == 1) && (info->flags & S_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->normal_termios;
+		else
+			*tty->termios = info->callout_termios;
+		change_speed(info);
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+	return 0;
+}
+
+/* Finally, routines used to initialize the serial driver. */
+
+static void show_serial_version(void)
+{
+	printk("NIOS serial driver version 0.0\n");
+}
+
+
+volatile int test_done;
+
+/* rs_init inits the driver */
+static int __init rs_nios_init(void)
+{
+	int flags;
+	struct NIOS_serial *info;
+	int			i;
+
+	/* Setup base handler, and timer table. */
+	init_bh(SERIAL_BH, do_serial_bh);
+
+	show_serial_version();
+
+	/* Initialize the tty_driver structure */
+	/* SPARC: Not all of this is exactly right for us. */
+
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+	serial_driver.name = "ttyS";
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64;
+	serial_driver.num = NR_PORTS;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+
+
+        serial_driver.init_termios.c_cflag =
+		B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+
+	serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = rs_open;
+	serial_driver.close = rs_close;
+	serial_driver.write = rs_write;
+	serial_driver.flush_chars = rs_flush_chars;
+	serial_driver.write_room = rs_write_room;
+	serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	serial_driver.flush_buffer = rs_flush_buffer;
+	serial_driver.ioctl = rs_ioctl;
+	serial_driver.throttle = rs_throttle;
+	serial_driver.unthrottle = rs_unthrottle;
+	serial_driver.set_termios = rs_set_termios;
+	serial_driver.stop = rs_stop;
+	serial_driver.start = rs_start;
+	serial_driver.hangup = rs_hangup;
+	serial_driver.set_ldisc = rs_set_ldisc;
+
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+	callout_driver.name = "cua";
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register serial driver\n");
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+
+	save_flags(flags); cli();
+
+	/*
+	 *	Configure all the attached serial ports.
+	 */
+	for (i = 0, info = nios_soft; (i < NR_PORTS); i++, info++) {
+		info->magic = SERIAL_MAGIC;
+		info->tty = 0;
+		info->custom_divisor = 16;
+		info->close_delay = 50;
+		info->closing_wait = 3000;
+		info->x_char = 0;
+		info->event = 0;
+		info->count = 0;
+		info->blocked_open = 0;
+		info->tqueue.routine = do_softint;
+		info->tqueue.data = info;
+		info->tqueue_hangup.routine = do_serial_hangup;
+		info->tqueue_hangup.data = info;
+		info->callout_termios =callout_driver.init_termios;
+		info->normal_termios = serial_driver.init_termios;
+		init_waitqueue_head(&info->open_wait);
+		init_waitqueue_head(&info->close_wait);
+		info->line = i;
+
+		printk("%s%d (irq = %d) is a builtin NIOS UART\n",
+			serial_driver.name, info->line, info->irq);
+
+//		rs_setsignals(info, 0, 0);
+		if (request_irq(info->irq, rs_interrupt, 0, "NIOS serial", info))
+			panic("Unable to attach NIOS serial interrupt\n");
+	}
+
+	restore_flags(flags);
+	return 0;
+}
+
+/*
+ * register_serial and unregister_serial allows for serial ports to be
+ * configured at run-time, to support PCMCIA modems.
+ */
+/* NIOS: Unused at this time, just here to make things link. */
+int register_serial(struct serial_struct *req)
+{
+	return -1;
+}
+
+void unregister_serial(int line)
+{
+	return;
+}
+
+module_init(rs_nios_init);
+
+int nios_console_setup(struct console *cp, char *arg)
+{
+	return 0;
+}
+
+
+static kdev_t nios_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+
+void nios_console_write (struct console *co, const char *str,
+			   unsigned int count)
+{
+    while (count--) {
+        if (*str == '\n')
+           rs_put_char('\r', nios_soft);
+        rs_put_char( *str++, nios_soft);
+    }
+}
+
+
+static struct console nios_driver = {
+	name:		"ttyS",
+	write:		nios_console_write,
+	read:		NULL,
+	device:		nios_console_device,
+	/*wait_key:	NULL,*/
+	unblank:	NULL,
+	setup:		nios_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+	cflag:		0,
+	next:		NULL
+};
+
+
+void nios_console_init(void)
+{
+	register_console(&nios_driver);
+}
diff -urN linux-2.4.29/drivers/char/NIOSserial.h linux-2.4.29-uc1/drivers/char/NIOSserial.h
--- linux-2.4.29/drivers/char/NIOSserial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/NIOSserial.h	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,148 @@
+/* NIOSserial.h: Definitions for the NIOS serial driver.
+ *
+ * Copyright (C) 1995       David S. Miller    <davem@caip.rutgers.edu>
+ * Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ * Copyright (C) 1998, 1999 D. Jeff Dionne     <jeff@uClinux.org>
+ * Copyright (C) 1999       Vladimir Gurevich  <vgurevic@cisco.com>
+ * Copyright (C) 2001       Vic Phillips       <vic@microtronix.com>
+ *
+ */
+
+#ifndef _NIOS_SERIAL_H
+#define _NIOS_SERIAL_H
+
+#include <linux/config.h>
+#include <asm/nios.h>
+
+struct serial_struct {
+	int	type;
+	int	line;
+	int	port;
+	int	irq;
+	int	flags;
+	int	xmit_fifo_size;
+	int	custom_divisor;
+	int	baud_base;
+	unsigned short	close_delay;
+	char	reserved_char[2];
+	int	hub6;  /* FIXME: We don't have AT&T Hub6 boards! */
+	unsigned short	closing_wait; /* time to wait before closing */
+	unsigned short	closing_wait2; /* no longer used... */
+	int	reserved[4];
+};
+
+/*
+ * For the close wait times, 0 means wait forever for serial port to
+ * flush its output.  65535 means don't wait at all.
+ */
+#define S_CLOSING_WAIT_INF	0
+#define S_CLOSING_WAIT_NONE	65535
+
+/*
+ * Definitions for S_struct (and serial_struct) flags field
+ */
+#define S_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes 
+				   on the callout port */
+#define S_FOURPORT  0x0002	/* Set OU1, OUT2 per AST Fourport settings */
+#define S_SAK	0x0004	/* Secure Attention Key (Orange book) */
+#define S_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
+
+#define S_SPD_MASK	0x0030
+#define S_SPD_HI	0x0010	/* Use 56000 instead of 38400 bps */
+
+#define S_SPD_VHI	0x0020  /* Use 115200 instead of 38400 bps */
+#define S_SPD_CUST	0x0030  /* Use user-specified divisor */
+
+#define S_SKIP_TEST	0x0040 /* Skip UART test during autoconfiguration */
+#define S_AUTO_IRQ  0x0080 /* Do automatic IRQ during autoconfiguration */
+#define S_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
+#define S_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
+#define S_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
+
+#define S_FLAGS	0x0FFF	/* Possible legal S flags */
+#define S_USR_MASK 0x0430	/* Legal flags that non-privileged
+				 * users can set or reset */
+
+/* Internal flags used only by kernel/chr_drv/serial.c */
+#define S_INITIALIZED	0x80000000 /* Serial port was initialized */
+#define S_CALLOUT_ACTIVE	0x40000000 /* Call out device is active */
+#define S_NORMAL_ACTIVE	0x20000000 /* Normal device is active */
+#define S_BOOT_AUTOCONF	0x10000000 /* Autoconfigure port on bootup */
+#define S_CLOSING		0x08000000 /* Serial port is closing */
+#define S_CTS_FLOW		0x04000000 /* Do CTS flow control */
+#define S_CHECK_CD		0x02000000 /* i.e., CLOCAL */
+
+/* Software state per channel */
+
+#ifdef __KERNEL__
+
+/*
+ * This is our internal structure for each serial port's state.
+ * 
+ * Many fields are paralleled by the structure used by the serial_struct
+ * structure.
+ *
+ * For definitions of the flags field, see tty.h
+ */
+
+struct NIOS_serial {
+	char soft_carrier;  /* Use soft carrier on this channel */
+	char break_abort;   /* Is serial console in, so process brk/abrt */
+	char is_cons;       /* Is this our console. */
+
+	/* We need to know the current clock divisor
+	 * to read the bps rate the chip has currently
+	 * loaded.
+	 */
+	unsigned char clk_divisor;  /* May be 1, 16, 32, or 64 */
+	int baud;
+	int			magic;
+	int			baud_base;
+	int			port;
+	int			irq;
+	int			flags; 		/* defined in tty.h */
+	int			type; 		/* UART type */
+	struct tty_struct 	*tty;
+	int			read_status_mask;
+	int			ignore_status_mask;
+	int			timeout;
+	int			xmit_fifo_size;
+	int			custom_divisor;
+	int			x_char;	/* xon/xoff character */
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int			count;	    /* # of fd on device */
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+	unsigned char 		*xmit_buf;
+	int			xmit_head;
+	int			xmit_tail;
+	int			xmit_cnt;
+	struct tq_struct	tqueue;
+	struct tq_struct	tqueue_hangup;
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+};
+
+#define SERIAL_MAGIC 0x5301
+
+/*
+ * The size of the serial xmit buffer is 1 page, or 4096 bytes
+ */
+#define SERIAL_XMIT_SIZE 4096
+
+/*
+ * Events are used to schedule things to happen at timer-interrupt
+ * time, instead of at rs interrupt time.
+ */
+#define RS_EVENT_WRITE_WAKEUP	0
+
+#endif /* __KERNEL__ */
+#endif /* !(_NIOS_SERIAL_H) */
diff -urN linux-2.4.29/drivers/char/pc_keyb.c linux-2.4.29-uc1/drivers/char/pc_keyb.c
--- linux-2.4.29/drivers/char/pc_keyb.c	2002-11-28 23:53:12.000000000 +0000
+++ linux-2.4.29-uc1/drivers/char/pc_keyb.c	2005-06-14 02:12:17.000000000 +0100
@@ -740,7 +740,7 @@
 	spin_unlock_irqrestore(&kbd_controller_lock, flags);
 }
 
-#if defined(__alpha__)
+#if defined(__alpha__) || defined(CONFIG_ARCH_EDB7312)
 /*
  * Some Alphas cannot mask some/all interrupts, so we have to
  * make sure not to allow interrupts AT ALL when polling for
diff -urN linux-2.4.29/drivers/char/pc_keyb_hd64465.c linux-2.4.29-uc1/drivers/char/pc_keyb_hd64465.c
--- linux-2.4.29/drivers/char/pc_keyb_hd64465.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/pc_keyb_hd64465.c	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,1302 @@
+/*
+ * linux/drivers/char/pc_keyb_hd64465.c
+ *
+ * Separation of the PC low-level part by Geert Uytterhoeven, May 1997
+ * See keyboard.c for the whole history.
+ *
+ * Major cleanup by Martin Mares, May 1997
+ *
+ * Combined the keyboard and PS/2 mouse handling into one file,
+ * because they share the same hardware.
+ * Johan Myreen <jem@@iki.fi> 1998-10-08.
+ *
+ * Code fixes to handle mouse ACKs properly.
+ * C. Scott Ananian <cananian@@alumni.princeton.edu> 1999-01-29.
+ *
+ */
+
+#include <linux/config.h>
+
+//#include <asm/spinlock.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/mm.h>
+#include <linux/signal.h>
+#include <linux/init.h>
+#include <linux/kbd_ll.h>
+#include <linux/delay.h>
+#include <linux/random.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+#include <linux/malloc.h>
+
+#include <asm/keyboard_keywest.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include <asm/io.h>
+/* Some configuration switches are present in the include file... */
+
+#include <linux/pc_keyb.h>
+#ifdef CONFIG_SH_KEYWEST
+#include <asm/hitachi_keywest.h>
+#endif
+#include <asm/hd64465.h>
+
+#undef KEYBOARD_IRQ
+#undef AUX_IRQ
+
+#define KEYBOARD_IRQ (HD64465_IRQBASE+15)
+#define AUX_IRQ      (HD64465_IRQBASE+7)
+
+#undef KBD_STATUS_REG
+#undef KBD_CNTL_REG
+#undef KBD_DATA_REG
+#undef AUX_STATUS_REG
+#undef AUX_DATA_REG
+
+#define KBD_STATUS_REG (HD64465_IOBASE+0xDC04)
+#define KBD_CNTL_REG   (HD64465_IOBASE+0xD800)
+#define KBD_DATA_REG   (HD64465_IOBASE+0xDC00)
+#define AUX_STATUS_REG (HD64465_IOBASE+0xDC14)
+#define AUX_DATA_REG   (HD64465_IOBASE+0xDC10)
+
+#undef kbd_read_input
+#undef kbd_read_status
+#undef kbd_write_output
+#undef kbd_write_command
+
+#define kbd_read_input()       inw(KBD_DATA_REG)
+#define kbd_read_status()      inw(KBD_STATUS_REG)
+#define kbd_write_output(val)  outw(val, KBD_DATA_REG)
+#define kbd_write_command(val) do { } while(0)
+
+#define kbd_clear_status()     outw(0x0001, KBD_STATUS_REG)
+#define aux_read_input()       inw(AUX_DATA_REG)
+#define aux_read_status()      inw(AUX_STATUS_REG)
+#define aux_write_output(val)  outw(val, AUX_DATA_REG)
+#define aux_clear_status()     outw(0x0001, AUX_STATUS_REG)
+
+#define KBD_RECEIVE_SEQENCE 0x8000	/* Enable keyboard data receive */
+
+#define DBG(x)
+
+
+/* Simple translation table for the SysRq keys */
+
+#ifdef CONFIG_MAGIC_SYSRQ
+unsigned char pckbd_sysrq_xlate[128] =
+	"\000\0331234567890-=\177\t"			/* 0x00 - 0x0f */
+	"qwertyuiop[]\r\000as"				/* 0x10 - 0x1f */
+	"dfghjkl;'`\000\\zxcv"				/* 0x20 - 0x2f */
+	"bnm,./\000*\000 \000\201\202\203\204\205"	/* 0x30 - 0x3f */
+	"\206\207\210\211\212\000\000789-456+1"		/* 0x40 - 0x4f */
+	"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
+	"\r\000/";					/* 0x60 - 0x6f */
+#endif
+
+static void kbd_write_output_w(int data);
+#ifdef CONFIG_PSMOUSE
+static void aux_write_ack(int val);
+#endif
+
+spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
+
+static unsigned char handle_kbd_event(void);
+#ifdef CONFIG_PSMOUSE
+static unsigned char handle_aux_event(void);
+#endif
+
+/* used only by send_data - set by keyboard_interrupt */
+static volatile unsigned char reply_expected = 0;
+static volatile unsigned char acknowledge = 0;
+static volatile unsigned char resend = 0;
+
+
+#if defined CONFIG_PSMOUSE
+/*
+ *	PS/2 Auxiliary Device
+ */
+
+static int __init psaux_init(void);
+
+#define AUX_RECONNECT    170
+/* #define CHECK_RECONNECT_SCANCODE 1 */
+
+static struct aux_queue *queue;	/* Mouse data buffer. */
+static int aux_count = 0;
+/* used when we send commands to the mouse that expect an ACK. */
+static unsigned char mouse_reply_expected = 0;
+
+#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT)
+#define AUX_INTS_ON  (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
+
+#define MAX_RETRIES	60		/* some aux operations take long time*/
+#endif /* CONFIG_PSMOUSE */
+
+struct {
+  unsigned char KBD;
+  unsigned char KBDP :1;
+  unsigned char KBDS :1;
+  unsigned char KBCS :1;
+  unsigned char KBDD :1;
+  unsigned char KBCD :1;
+  unsigned char KBDOE :1;
+  unsigned char KBCOE :1;
+  unsigned char KBCIE :1;
+} KBCSR;
+
+static volatile char kbd_writing_flag = 0;
+#ifdef CONFIG_PSMOUSE
+static volatile char aux_writing_flag = 0;
+#endif
+
+/*
+ * Wait for keyboard controller input buffer to drain.
+ *
+ * Don't use 'jiffies' so that we don't depend on
+ * interrupts..
+ *
+ * Quote from PS/2 System Reference Manual:
+ *
+ * "Address hex 0060 and address hex 0064 should be written only when
+ * the input-buffer-full bit and output-buffer-full bit in the
+ * Controller Status register are set 0."
+ */
+
+static void kb_wait(void)
+{
+	unsigned long timeout = KBC_TIMEOUT;
+
+	do {
+		/*
+		 * "handle_kbd_event()" will handle any incoming events
+		 * while we wait - keypresses or mouse movement.
+		 */
+		handle_kbd_event();
+		if (!kbd_writing_flag)
+			return;
+		mdelay(1);
+		timeout--;
+	} while (timeout);
+#ifdef KBD_REPORT_TIMEOUTS
+	printk(KERN_WARNING "Keyboard timed out[1]\n");
+#endif
+}
+
+#ifdef CONFIG_PSMOUSE
+static void am_wait(void)
+{
+	unsigned long timeout = KBC_TIMEOUT;
+
+	do {
+		handle_aux_event();
+		if (!aux_writing_flag)
+			return;
+		mdelay(1);
+		timeout--;
+	} while (timeout);
+#ifdef KBD_REPORT_TIMEOUTS
+	printk(KERN_WARNING "Mouse timed out[1]\n");
+#endif
+}
+#endif
+
+/*
+ * Translation of escaped scancodes to keycodes.
+ * This is now user-settable.
+ * The keycodes 1-88,96-111,119 are fairly standard, and
+ * should probably not be changed - changing might confuse X.
+ * X also interprets scancode 0x5d (KEY_Begin).
+ *
+ * For 1-88 keycode equals scancode.
+ */
+
+#define E0_KPENTER 96
+#define E0_RCTRL   97
+#define E0_KPSLASH 98
+#define E0_PRSCR   99
+#define E0_RALT    100
+#define E0_BREAK   101  /* (control-pause) */
+#define E0_HOME    102
+#define E0_UP      103
+#define E0_PGUP    104
+#define E0_LEFT    105
+#define E0_RIGHT   106
+#define E0_END     107
+#define E0_DOWN    108
+#define E0_PGDN    109
+#define E0_INS     110
+#define E0_DEL     111
+
+#define E1_PAUSE   119
+
+/*
+ * The keycodes below are randomly located in 89-95,112-118,120-127.
+ * They could be thrown away (and all occurrences below replaced by 0),
+ * but that would force many users to use the `setkeycodes' utility, where
+ * they needed not before. It does not matter that there are duplicates, as
+ * long as no duplication occurs for any single keyboard.
+ */
+#define SC_LIM 89
+
+#define FOCUS_PF1 85           /* actual code! */
+#define FOCUS_PF2 89
+#define FOCUS_PF3 90
+#define FOCUS_PF4 91
+#define FOCUS_PF5 92
+#define FOCUS_PF6 93
+#define FOCUS_PF7 94
+#define FOCUS_PF8 95
+#define FOCUS_PF9 120
+#define FOCUS_PF10 121
+#define FOCUS_PF11 122
+#define FOCUS_PF12 123
+
+#define JAP_86     124
+/* tfj@@olivia.ping.dk:
+ * The four keys are located over the numeric keypad, and are
+ * labelled A1-A4. It's an rc930 keyboard, from
+ * Regnecentralen/RC International, Now ICL.
+ * Scancodes: 59, 5a, 5b, 5c.
+ */
+#define RGN1 124
+#define RGN2 125
+#define RGN3 126
+#define RGN4 127
+
+static unsigned char high_keys[128 - SC_LIM] = {
+  RGN1, RGN2, RGN3, RGN4, 0, 0, 0,                   /* 0x59-0x5f */
+  0, 0, 0, 0, 0, 0, 0, 0,                            /* 0x60-0x67 */
+  0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12,          /* 0x68-0x6f */
+  0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3,    /* 0x70-0x77 */
+  FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7,        /* 0x78-0x7b */
+  FOCUS_PF8, JAP_86, FOCUS_PF10, 0                   /* 0x7c-0x7f */
+};
+
+/* BTC */
+#define E0_MACRO   112
+/* LK450 */
+#define E0_F13     113
+#define E0_F14     114
+#define E0_HELP    115
+#define E0_DO      116
+#define E0_F17     117
+#define E0_KPMINPLUS 118
+/*
+ * My OmniKey generates e0 4c for  the "OMNI" key and the
+ * right alt key does nada. [kkoller@@nyx10.cs.du.edu]
+ */
+#define E0_OK	124
+/*
+ * New microsoft keyboard is rumoured to have
+ * e0 5b (left window button), e0 5c (right window button),
+ * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
+ * [or: Windows_L, Windows_R, TaskMan]
+ */
+#define E0_MSLW	125
+#define E0_MSRW	126
+#define E0_MSTM	127
+
+static unsigned char e0_keys[128] = {
+  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x00-0x07 */
+  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x08-0x0f */
+  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x10-0x17 */
+  0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0,	      /* 0x18-0x1f */
+  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x20-0x27 */
+  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x28-0x2f */
+  0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR,	      /* 0x30-0x37 */
+  E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP,	      /* 0x38-0x3f */
+  E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME,	      /* 0x40-0x47 */
+  E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
+  E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0,	      /* 0x50-0x57 */
+  0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0,	      /* 0x58-0x5f */
+  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x60-0x67 */
+  0, 0, 0, 0, 0, 0, 0, E0_MACRO,		      /* 0x68-0x6f */
+  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x70-0x77 */
+  0, 0, 0, 0, 0, 0, 0, 0			      /* 0x78-0x7f */
+};
+
+int pckbd_setkeycode(unsigned int scancode, unsigned int keycode)
+{
+	if (scancode < SC_LIM || scancode > 255 || keycode > 127)
+	  return -EINVAL;
+	if (scancode < 128)
+	  high_keys[scancode - SC_LIM] = keycode;
+	else
+	  e0_keys[scancode - 128] = keycode;
+	return 0;
+}
+
+int pckbd_getkeycode(unsigned int scancode)
+{
+	return
+	  (scancode < SC_LIM || scancode > 255) ? -EINVAL :
+	  (scancode < 128) ? high_keys[scancode - SC_LIM] :
+	    e0_keys[scancode - 128];
+}
+
+static int do_acknowledge(unsigned char scancode)
+{
+	if (reply_expected) {
+	  /* Unfortunately, we must recognise these codes only if we know they
+	   * are known to be valid (i.e., after sending a command), because there
+	   * are some brain-damaged keyboards (yes, FOCUS 9000 again) which have
+	   * keys with such codes :(
+	   */
+		if (scancode == KBD_REPLY_ACK) {
+			acknowledge = 1;
+			reply_expected = 0;
+			return 0;
+		} else if (scancode == KBD_REPLY_RESEND) {
+			resend = 1;
+			reply_expected = 0;
+			return 0;
+		}
+		/* Should not happen... */
+#if 0
+		printk(KERN_DEBUG "keyboard reply expected - got %02x\n",
+		       scancode);
+#endif
+	}
+	return 1;
+}
+
+int pckbd_translate(unsigned char scancode, unsigned char *keycode,
+		    char raw_mode)
+{
+	static int prev_scancode = 0;
+
+	/* special prefix scancodes.. */
+	if (scancode == 0xe0 || scancode == 0xe1) {
+		prev_scancode = scancode;
+		return 0;
+	}
+
+	/* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
+	if (scancode == 0x00 || scancode == 0xff) {
+		prev_scancode = 0;
+		return 0;
+	}
+
+	DBG(printk("scancode=0x%02x\n", scancode););
+	scancode &= 0x7f;
+
+	if (prev_scancode) {
+	  /*
+	   * usually it will be 0xe0, but a Pause key generates
+	   * e1 1d 45 e1 9d c5 when pressed, and nothing when released
+	   */
+	  if (prev_scancode != 0xe0) {
+	      if (prev_scancode == 0xe1 && scancode == 0x1d) {
+		  prev_scancode = 0x100;
+		  return 0;
+	      } else if (prev_scancode == 0x100 && scancode == 0x45) {
+		  *keycode = E1_PAUSE;
+		  prev_scancode = 0;
+	      } else {
+#ifdef KBD_REPORT_UNKN
+		  if (!raw_mode)
+		    printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
+#endif
+		  prev_scancode = 0;
+		  return 0;
+	      }
+	  } else {
+	      prev_scancode = 0;
+	      /*
+	       *  The keyboard maintains its own internal caps lock and
+	       *  num lock statuses. In caps lock mode E0 AA precedes make
+	       *  code and E0 2A follows break code. In num lock mode,
+	       *  E0 2A precedes make code and E0 AA follows break code.
+	       *  We do our own book-keeping, so we will just ignore these.
+	       */
+	      /*
+	       *  For my keyboard there is no caps lock mode, but there are
+	       *  both Shift-L and Shift-R modes. The former mode generates
+	       *  E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
+	       *  So, we should also ignore the latter. - aeb@@cwi.nl
+	       */
+	      if (scancode == 0x2a || scancode == 0x36)
+		return 0;
+
+	      if (e0_keys[scancode])
+		*keycode = e0_keys[scancode];
+	      else {
+#ifdef KBD_REPORT_UNKN
+		  if (!raw_mode)
+		    printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
+			   scancode);
+#endif
+		  return 0;
+	      }
+	  }
+	} else if (scancode >= SC_LIM) {
+	    /* This happens with the FOCUS 9000 keyboard
+	       Its keys PF1..PF12 are reported to generate
+	       55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
+	       Moreover, unless repeated, they do not generate
+	       key-down events, so we have to zero up_flag below */
+	    /* Also, Japanese 86/106 keyboards are reported to
+	       generate 0x73 and 0x7d for \ - and \ | respectively. */
+	    /* Also, some Brazilian keyboard is reported to produce
+	       0x73 and 0x7e for \ ? and KP-dot, respectively. */
+
+	  *keycode = high_keys[scancode - SC_LIM];
+
+	  if (!*keycode) {
+	      if (!raw_mode) {
+#ifdef KBD_REPORT_UNKN
+		  printk(KERN_INFO "keyboard: unrecognized scancode (%02x)"
+			 " - ignored\n", scancode);
+#endif
+	      }
+	      return 0;
+	  }
+	} else
+	  *keycode = scancode;
+	return 1;
+}
+
+char pckbd_unexpected_up(unsigned char keycode)
+{
+	/* unexpected, but this can happen: maybe this was a key release for a
+	   FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */
+	if (keycode >= SC_LIM || keycode == 85)
+	    return 0;
+	else
+	    return 0200;
+}
+
+static inline void handle_mouse_event(unsigned char scancode)
+{
+#ifdef CONFIG_PSMOUSE
+	if (mouse_reply_expected) {
+		if (scancode == AUX_ACK) {
+			mouse_reply_expected--;
+			return;
+		}
+		mouse_reply_expected = 0;
+	}
+	else if(scancode == AUX_RECONNECT){
+		queue->head = queue->tail = 0;  /* Flush input queue */
+		aux_write_ack(AUX_ENABLE_DEV);  /* ping the mouse :) */
+		return;
+	}
+
+	add_mouse_randomness(scancode);
+	if (aux_count) {
+		int head = queue->head;
+
+		queue->buf[head] = scancode;
+		head = (head + 1) & (AUX_BUF_SIZE-1);
+		if (head != queue->tail) {
+			queue->head = head;
+			if (queue->fasync)
+				kill_fasync(&queue->fasync, SIGIO, POLL_IN);
+			wake_up_interruptible(&queue->proc_list);
+		}
+	}
+#endif
+}
+
+/*
+ * This reads the keyboard status port, and does the
+ * appropriate action.
+ *
+ * It requires that we hold the keyboard controller
+ * spinlock.
+ */
+static unsigned char handle_kbd_event(void)
+{
+	unsigned short status;
+ 	unsigned int work = 10000;
+ 
+	while (kbd_writing_flag) {
+		udelay(100);
+		if (!work--) {
+			printk(KERN_ERR "sh_hd64465_pc_keyb: controller jammed.\n");
+			return 0;
+		}
+	}
+	kbd_write_output(KBD_RECEIVE_SEQENCE);
+	status = kbd_read_status();
+
+	while (status & KBD_STAT_OBF) {
+		unsigned char scancode;
+
+		scancode = (unsigned char)(kbd_read_input() & 0x00ff);
+ 
+		if (status & KBD_STAT_MOUSE_OBF) {
+			handle_mouse_event(scancode);
+		} else {
+			if (do_acknowledge(scancode))
+				handle_scancode(scancode, !(scancode & 0x80));
+			//mark_bh(KEYBOARD_BH);
+		}
+
+		kbd_clear_status();
+		kbd_write_output(KBD_RECEIVE_SEQENCE);
+
+		status = kbd_read_status();
+		
+		if(!work--)
+		{
+			printk(KERN_ERR "pc_keyb: controller jammed (0x%02X).\n",
+				status);
+			break;
+		}
+	}
+
+	return status;
+}
+
+#ifdef CONFIG_PSMOUSE
+static unsigned char handle_aux_event(void)
+{
+	unsigned short status;
+	unsigned int work = 10000;
+
+	aux_write_output(KBD_RECEIVE_SEQENCE);
+	status = aux_read_status();
+
+	while (status & KBD_STAT_OBF) {
+		unsigned char scancode;
+
+		scancode = (unsigned char)(aux_read_input() & 0x00ff);
+
+		handle_mouse_event(scancode);
+		aux_clear_status();
+		aux_write_output(KBD_RECEIVE_SEQENCE);
+		status = aux_read_status();
+		if (!--work) {
+			printk(KERN_ERR "sh_aspen_keyb: controller jammed (0x%02X).\n",
+				status);
+			break;
+		}
+	}
+
+	return status;
+}
+#endif
+
+static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long flags;
+
+	kbd_pt_regs = regs;
+
+	spin_lock_irqsave(&kbd_controller_lock, flags);
+	handle_kbd_event();
+	spin_unlock_irqrestore(&kbd_controller_lock, flags);
+}
+
+#ifdef CONFIG_PSMOUSE
+static void mouse_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long flags;
+
+	kbd_pt_regs = regs;
+
+	spin_lock_irqsave(&kbd_controller_lock, flags);
+	handle_aux_event();
+	spin_unlock_irqrestore(&kbd_controller_lock, flags);
+}
+#endif
+
+/*
+ * send_data sends a character to the keyboard and waits
+ * for an acknowledge, possibly retrying if asked to. Returns
+ * the success status.
+ *
+ * Don't use 'jiffies', so that we don't depend on interrupts
+ */
+static int send_data(unsigned char data)
+{
+	int retries = 3;
+
+	do {
+		unsigned long timeout = KBD_TIMEOUT;
+
+		acknowledge = 0; /* Set by interrupt routine on receipt of ACK. */
+		resend = 0;
+		reply_expected = 1;
+		kbd_write_output_w(data);
+		for (;;) {
+			if (acknowledge)
+				return 1;
+			if (resend)
+				break;
+			mdelay(1);
+			if (!--timeout) {
+#ifdef KBD_REPORT_TIMEOUTS
+				printk(KERN_WARNING "Keyboard timeout[2]\n");
+#endif
+				return 0;
+			}
+		}
+	} while (retries-- > 0);
+#ifdef KBD_REPORT_TIMEOUTS
+	printk(KERN_WARNING "keyboard: Too many NACKs -- noisy kbd cable?\n");
+#endif
+	return 0;
+}
+
+void pckbd_leds(unsigned char leds)
+{
+	if (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds))
+	    send_data(KBD_CMD_ENABLE);	/* re-enable kbd if any errors */
+}
+
+/*
+ * In case we run on a non-x86 hardware we need to initialize both the
+ * keyboard controller and the keyboard.  On a x86, the BIOS will
+ * already have initialized them.
+ *
+ * Some x86 BIOSes do not correctly initialize the keyboard, so the
+ * "kbd-reset" command line options can be given to force a reset.
+ * [Ranger]
+ */
+#ifdef __i386__
+ int kbd_startup_reset __initdata = 0;
+#else
+ int kbd_startup_reset __initdata = 1;
+#endif
+
+/* for "kbd-reset" cmdline param */
+void __init kbd_reset_setup(char *str, int *ints)
+{
+	kbd_startup_reset = 1;
+}
+
+#define KBD_NO_DATA	(-1)	/* No data */
+#define KBD_BAD_DATA	(-2)	/* Parity or other error */
+
+static int __init kbd_read_data(void)
+{
+	int retval = KBD_NO_DATA;
+	unsigned short status;
+	int i, parity_count = 0;
+
+	kbd_write_output(KBD_RECEIVE_SEQENCE);
+	status = kbd_read_status();
+	if (status & KBD_STAT_OBF) {
+		unsigned short data = kbd_read_input();
+		DBG(printk("%04x\n", (unsigned int)data););
+		
+		retval = (int)(data & 0xff);
+		for (i = 0; i < 8; i++) {
+		  if ((retval >> i) & 0x01)
+		    parity_count++;
+		}
+		if (((data & 0x0100) >> 8) != !(parity_count & 0x01))
+			retval = KBD_BAD_DATA;
+		kbd_write_output(KBD_RECEIVE_SEQENCE);
+		kbd_clear_status();
+		DBG(printk("%02x\n", retval););
+	}
+	return retval;
+}
+
+static void __init kbd_clear_input(void)
+{
+	int maxread = 100;	/* Random number */
+
+	do {
+		if (kbd_read_data() == KBD_NO_DATA)
+			break;
+	} while (--maxread);
+}
+
+static int __init kbd_wait_for_input(void)
+{
+	long timeout = KBD_INIT_TIMEOUT;
+	int i = 0;
+
+	do {
+		int retval = kbd_read_data();
+		if (retval >= 0)
+			return retval;
+		i++;
+		DBG(printk("loop=%d\n", i););
+		mdelay(1);
+	} while (--timeout);
+	return -1;
+}
+
+ 
+static void kbd_write_output_w(int data)
+{
+	unsigned long flags;
+	int i = 0, parity_count = 0;
+	unsigned short kbcsr;
+	long loop_count = 10000, edge_wait = 10000;
+	
+	spin_lock_irqsave(&kbd_controller_lock, flags);
+ 	kb_wait();
+	kbd_writing_flag = 1;
+	kbcsr = kbd_read_input();
+	memcpy(&KBCSR, &kbcsr, sizeof(unsigned short));
+	KBCSR.KBCIE = 1;
+	KBCSR.KBCOE = 1;
+	KBCSR.KBCD = 0;
+	memcpy(&kbcsr, &KBCSR, sizeof(unsigned short));
+	kbd_write_output(kbcsr);
+	
+	kbcsr = kbd_read_input();
+	memcpy(&KBCSR, &kbcsr, sizeof(unsigned short));
+	KBCSR.KBDOE = 1;
+	KBCSR.KBDD = 0; /* start bit set */
+	memcpy(&kbcsr, &KBCSR, sizeof(unsigned short));
+	kbd_write_output(kbcsr);
+	
+	udelay(30);
+	kbcsr = kbd_read_input();
+	memcpy(&KBCSR, &kbcsr, sizeof(unsigned short));
+	KBCSR.KBCOE = 0;
+	memcpy(&kbcsr, &KBCSR, sizeof(unsigned short));
+	kbd_write_output(kbcsr);
+	
+	/* data transfering */
+	while(loop_count-- > 0) {
+		if (i == 8) {
+			break;
+		}
+		kbcsr = kbd_read_input();
+		if (!(kbcsr & 0x400)) {
+			memcpy(&KBCSR, &kbcsr, sizeof(unsigned short));
+			/*KBCSR.KBCIE = 1;*/
+			KBCSR.KBDD = (data >> i) & 0x01;
+			if (KBCSR.KBDD == 1)
+				parity_count++;
+			memcpy(&kbcsr, &KBCSR, sizeof(unsigned short));
+			kbd_write_output(kbcsr);
+			edge_wait = 10000;
+			while(edge_wait-- > 0) {
+				kbcsr = kbd_read_input();
+				if (kbcsr & 0x400)
+					break;
+			}
+			if (edge_wait <= 0)
+				loop_count = 0;
+			else
+				loop_count = 10000;
+			i++;
+		}
+	}
+	/* parity bit and stop bit transfering */
+	i = 0;
+	if (loop_count > 0)
+		loop_count = 10000;
+	while(loop_count-- > 0) {
+		if (i == 2) {
+			break;
+		}
+		kbcsr = kbd_read_input();
+		if (!(kbcsr & 0x400)) {
+			memcpy(&KBCSR, &kbcsr, sizeof(unsigned short));
+			if (i == 0) {
+				KBCSR.KBDD = !(parity_count & 0x1);
+			} else {
+				KBCSR.KBCIE = 0;
+				KBCSR.KBDOE = 0;
+				KBCSR.KBDD = 1; /* stop bit */
+			}
+			memcpy(&kbcsr, &KBCSR, sizeof(unsigned short));
+			kbd_write_output(kbcsr);
+			edge_wait = 10000;
+			while(edge_wait-- > 0) {
+				kbcsr = kbd_read_input();
+				if (kbcsr & 0x400)
+					break;
+			}
+			if (edge_wait <= 0)
+				break;
+			else
+				loop_count = 10000;
+			if (i == 1) {
+				kbd_clear_status();
+				udelay(300);
+				kbcsr = kbd_read_input();
+				memcpy(&KBCSR, &kbcsr, sizeof(unsigned short));
+				KBCSR.KBCOE = 1;
+				KBCSR.KBCD = 0;
+				memcpy(&kbcsr, &KBCSR, sizeof(unsigned short));
+				kbd_write_output(kbcsr);
+				udelay(100);
+			}
+			i++;
+		}
+	}
+	kbd_write_output(KBD_RECEIVE_SEQENCE);
+	kbd_writing_flag = 0;
+	if (loop_count <= 0 || edge_wait <= 0)
+		printk("Keyboard write data fail.\n");
+	spin_unlock_irqrestore(&kbd_controller_lock, flags);
+}
+ 
+#ifdef CONFIG_PSMOUSE
+static void aux_write_output_w(int data)
+{
+	int i = 0, parity_count = 0;
+	unsigned short kbcsr;
+	long loop_count = 10000, edge_wait = 10000;
+	
+	aux_writing_flag = 1;
+	kbcsr = aux_read_input();
+	memcpy(&KBCSR, &kbcsr, sizeof(unsigned short));
+	KBCSR.KBCIE = 1;
+	KBCSR.KBCOE = 1;
+	KBCSR.KBCD = 0;
+	memcpy(&kbcsr, &KBCSR, sizeof(unsigned short));
+	aux_write_output(kbcsr);
+	
+	kbcsr = aux_read_input();
+	memcpy(&KBCSR, &kbcsr, sizeof(unsigned short));
+	KBCSR.KBDOE = 1;
+	KBCSR.KBDD = 0; /* start bit set */
+	memcpy(&kbcsr, &KBCSR, sizeof(unsigned short));
+	aux_write_output(kbcsr);
+	
+	udelay(30);
+	kbcsr = aux_read_input();
+	memcpy(&KBCSR, &kbcsr, sizeof(unsigned short));
+	KBCSR.KBCOE = 0;
+	memcpy(&kbcsr, &KBCSR, sizeof(unsigned short));
+	aux_write_output(kbcsr);
+	
+	/* data transfering */
+	while(loop_count-- > 0) {
+		if (i == 8) {
+			break;
+		}
+		kbcsr = aux_read_input();
+		if (!(kbcsr & 0x400)) {
+			memcpy(&KBCSR, &kbcsr, sizeof(unsigned short));
+			/*KBCSR.KBCIE = 1;*/
+			KBCSR.KBDD = (data >> i) & 0x01;
+			if (KBCSR.KBDD == 1)
+				parity_count++;
+			memcpy(&kbcsr, &KBCSR, sizeof(unsigned short));
+			aux_write_output(kbcsr);
+			edge_wait = 10000;
+			while(edge_wait-- > 0) {
+				kbcsr = aux_read_input();
+				if (kbcsr & 0x400)
+					break;
+			}
+			if (edge_wait <= 0)
+				loop_count = 0;
+			else
+				loop_count = 10000;
+			i++;
+		}
+	}
+	/* parity bit and stop bit transfering */
+	i = 0;
+	if (loop_count > 0)
+		loop_count = 10000;
+	while(loop_count-- > 0) {
+		if (i == 2) {
+			break;
+		}
+		kbcsr = aux_read_input();
+		if (!(kbcsr & 0x400)) {
+			memcpy(&KBCSR, &kbcsr, sizeof(unsigned short));
+			if (i == 0) {
+				KBCSR.KBDD = !(parity_count & 0x1);
+			} else {
+				KBCSR.KBCIE = 0;
+				KBCSR.KBDOE = 0;
+				KBCSR.KBDD = 1; /* stop bit */
+			}
+			memcpy(&kbcsr, &KBCSR, sizeof(unsigned short));
+			aux_write_output(kbcsr);
+			edge_wait = 10000;
+			while(edge_wait-- > 0) {
+				kbcsr = aux_read_input();
+				if (kbcsr & 0x400)
+					break;
+			}
+			if (edge_wait <= 0)
+				break;
+			else
+				loop_count = 10000;
+			if (i == 1) {
+				aux_clear_status();
+				udelay(300);
+				kbcsr = aux_read_input();
+				memcpy(&KBCSR, &kbcsr, sizeof(unsigned short));
+				KBCSR.KBCOE = 1;
+				KBCSR.KBCD = 0;
+				memcpy(&kbcsr, &KBCSR, sizeof(unsigned short));
+				aux_write_output(kbcsr);
+				udelay(100);
+			}
+			i++;
+		}
+	}
+	aux_write_output(KBD_RECEIVE_SEQENCE);
+	aux_writing_flag = 0;
+	if (loop_count <= 0 || edge_wait <= 0)
+		printk("Mouse write data fail.\n");
+}
+#endif /* CONFIG_PSMOUSE */
+
+static char * __init initialize_kbd(void)
+{
+	int status;
+
+	/*
+	 * Reset keyboard. If the read times out
+	 * then the assumption is that no keyboard is
+	 * plugged into the machine.
+	 * This defaults the keyboard to scan-code set 2.
+	 *
+	 * Set up to try again if the keyboard asks for RESEND.
+	 */
+	kbd_write_output(KBD_RECEIVE_SEQENCE);
+	kbd_clear_status();
+	do {
+		kbd_write_output_w(KBD_CMD_RESET);
+		status = kbd_wait_for_input();
+		if (status == KBD_REPLY_ACK)
+			break;
+		if (status != KBD_REPLY_RESEND)
+			return "Keyboard reset failed, no ACK";
+	} while (1);
+
+	if (kbd_wait_for_input() != KBD_REPLY_POR)
+		return "Keyboard reset failed, no POR";
+
+/*
+	 * Set keyboard controller mode. During this, the keyboard should be
+	 * in the disabled state.
+	 *
+	 * Set up to try again if the keyboard asks for RESEND.
+	 */
+	do {
+		kbd_write_output_w(KBD_CMD_DISABLE);
+		status = kbd_wait_for_input();
+		if (status == KBD_REPLY_ACK)
+			break;
+		if (status != KBD_REPLY_RESEND)
+			return "Disable keyboard: no ACK";
+	} while (1);
+
+		/*
+		 * If the controller does not support conversion,
+		 * Set the keyboard to scan-code set 1.
+		 */
+		kbd_write_output_w(0xF0);
+		kbd_wait_for_input();
+		kbd_write_output_w(0x01);
+		kbd_wait_for_input();
+
+	
+	DBG(printk("test0\n"););
+	kbd_write_output_w(KBD_CMD_ENABLE);
+	if (kbd_wait_for_input() != KBD_REPLY_ACK)
+		return "Enable keyboard: no ACK";
+
+	/*
+	 * Finally, set the typematic rate to maximum.
+	 */
+	kbd_write_output_w(KBD_CMD_SET_RATE);
+	if (kbd_wait_for_input() != KBD_REPLY_ACK)
+		return "Set rate: no ACK";
+	kbd_write_output_w(0x00);
+	if (kbd_wait_for_input() != KBD_REPLY_ACK)
+		return "Set rate: no ACK";
+
+	return NULL;
+}
+
+void __init pckbd_init_hw(void)
+{
+
+	kbd_write_output(KBD_RECEIVE_SEQENCE);
+	
+	kbd_request_region();
+	
+	/* Flush any pending input. */
+	kbd_clear_input();
+
+	if (kbd_startup_reset) {
+		char *msg = initialize_kbd();
+		if (msg)
+			printk(KERN_WARNING "initialize_kbd: %s\n", msg);
+	}
+
+#ifdef CONFIG_PSMOUSE
+	psaux_init();
+#endif
+
+	/* Ok, finally allocate the IRQ, and off we go.. */
+	kbd_request_irq(keyboard_interrupt);
+}
+
+#if defined CONFIG_PSMOUSE
+
+/*
+ * Check if this is a dual port controller.
+ */
+static int __init detect_auxiliary_port(void)
+{
+	unsigned long flags;
+	int loops = 10;
+	int retval = 0;
+
+	spin_lock_irqsave(&kbd_controller_lock, flags);
+
+	/* Put the value 0x5A in the output buffer using the "Write
+	 * Auxiliary Device Output Buffer" command (0xD3). Poll the
+	 * Status Register for a while to see if the value really
+	 * turns up in the Data Register. If the KBD_STAT_MOUSE_OBF
+	 * bit is also set to 1 in the Status Register, we assume this
+	 * controller has an Auxiliary Port (a.k.a. Mouse Port).
+	 */
+	kb_wait();
+	kbd_write_command(KBD_CCMD_WRITE_AUX_OBUF);
+
+	kb_wait();
+	kbd_write_output(0x5a); /* 0x5a is a random dummy value. */
+
+	do {
+		unsigned char status = kbd_read_status();
+printk("--+* detect_auxiliary_por %x const %x\n",status,KBD_STAT_OBF);
+		if (status & KBD_STAT_OBF) {
+			(void) kbd_read_input();
+			if (status & KBD_STAT_MOUSE_OBF) {
+				printk(KERN_INFO "Detected PS/2 Mouse Port.\n");
+				retval = 1;
+			}
+			break;
+		}
+		mdelay(1);
+	} while (--loops);
+	spin_unlock_irqrestore(&kbd_controller_lock, flags);
+
+	return retval;
+}
+
+/*
+ * Send a byte to the mouse.
+ */
+static void aux_write_dev(int val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&kbd_controller_lock, flags);
+	am_wait();
+	aux_write_output_w(val);
+	spin_unlock_irqrestore(&kbd_controller_lock, flags);
+}
+
+/*
+ * Send a byte to the mouse & handle returned ack
+ */
+static void aux_write_ack(int val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&kbd_controller_lock, flags);
+	am_wait();
+	aux_write_output_w(val);
+	/* we expect an ACK in response. */
+	mouse_reply_expected++;
+	am_wait();
+	spin_unlock_irqrestore(&kbd_controller_lock, flags);
+}
+
+static unsigned char get_from_queue(void)
+{
+	unsigned char result;
+	unsigned long flags;
+
+	spin_lock_irqsave(&kbd_controller_lock, flags);
+	result = queue->buf[queue->tail];
+	queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
+	spin_unlock_irqrestore(&kbd_controller_lock, flags);
+	return result;
+}
+
+
+static inline int queue_empty(void)
+{
+	return queue->head == queue->tail;
+}
+
+static int fasync_aux(int fd, struct file *filp, int on)
+{
+	int retval;
+
+	retval = fasync_helper(fd, filp, on, &queue->fasync);
+	if (retval < 0)
+		return retval;
+	return 0;
+}
+
+
+/*
+ * Random magic cookie for the aux device
+ */
+#define AUX_DEV ((void *)queue)
+
+static int release_aux(struct inode * inode, struct file * file)
+{
+	fasync_aux(-1, file, 0);
+	if (--aux_count)
+		return 0;
+	aux_write_ack(AUX_INTS_OFF);
+	aux_write_ack(KBD_CCMD_MOUSE_DISABLE);
+	aux_free_irq(AUX_DEV);
+	return 0;
+}
+
+/*
+ * Install interrupt handler.
+ * Enable auxiliary device.
+ */
+
+static int open_aux(struct inode * inode, struct file * file)
+{
+	if (aux_count++) {
+		return 0;
+	}
+	queue->head = queue->tail = 0;		/* Flush input queue */
+	if (aux_request_irq(mouse_interrupt, AUX_DEV)) {
+		aux_count--;
+		return -EBUSY;
+	}
+	aux_write_ack(KBD_CCMD_MOUSE_ENABLE);
+	aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */
+	aux_write_ack(AUX_INTS_ON); /* Enable controller ints */
+	send_data(KBD_CMD_ENABLE);
+
+	return 0;
+}
+
+/*
+ * Put bytes from input queue to buffer.
+ */
+
+static ssize_t read_aux(struct file * file, char * buffer,
+			size_t count, loff_t *ppos)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	ssize_t i = count;
+	unsigned char c;
+
+	if (queue_empty()) {
+		if (file->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		add_wait_queue(&queue->proc_list, &wait);
+repeat:
+		current->state = TASK_INTERRUPTIBLE;
+		if (queue_empty() && !signal_pending(current)) {
+			schedule();
+			goto repeat;
+		}
+		current->state = TASK_RUNNING;
+		remove_wait_queue(&queue->proc_list, &wait);
+	}
+	while (i > 0 && !queue_empty()) {
+		c = get_from_queue();
+		put_user(c, buffer++);
+		i--;
+	}
+	if (count-i) {
+		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
+		return count-i;
+	}
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+	return 0;
+}
+
+/*
+ * Write to the aux device.
+ */
+
+static ssize_t write_aux(struct file * file, const char * buffer,
+			 size_t count, loff_t *ppos)
+{
+	ssize_t retval = 0;
+
+	if (count) {
+		ssize_t written = 0;
+
+		if (count > 32)
+			count = 32; /* Limit to 32 bytes. */
+		do {
+			char c;
+			get_user(c, buffer++);
+			aux_write_dev(c);
+			written++;
+		} while (--count);
+		retval = -EIO;
+		if (written) {
+			retval = written;
+			file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
+		}
+	}
+
+	return retval;
+}
+
+static unsigned int aux_poll(struct file *file, poll_table * wait)
+{
+	poll_wait(file, &queue->proc_list, wait);
+	if (!queue_empty())
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+struct file_operations psaux_fops = {
+        read:           read_aux,
+        write:          write_aux,
+        poll:           aux_poll,
+        open:           open_aux,
+        release:        release_aux,
+        fasync:         fasync_aux,
+};
+/*
+ * Initialize driver.
+ */
+static struct miscdevice psaux_mouse = {
+	PSMOUSE_MINOR, "psaux", &psaux_fops
+};
+
+static int __init psaux_init(void)
+{
+printk("--+* PS2 Mouce init \n");
+	if (!detect_auxiliary_port())
+		return -EIO;
+printk("--+* PS2 Mouce init 2\n");
+
+	misc_register(&psaux_mouse);
+	queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
+	memset(queue, 0, sizeof(*queue));
+	queue->head = queue->tail = 0;
+	init_waitqueue_head(&queue->proc_list);
+#ifdef INITIALIZE_MOUSE
+printk("--+* PS2 Mouce init 3\n");
+	aux_write_ack(KBD_CCMD_MOUSE_ENABLE);
+	aux_write_ack(AUX_SET_SAMPLE);
+	aux_write_ack(100);			/* 100 samples/sec */
+	aux_write_ack(AUX_SET_RES);
+	aux_write_ack(3);			/* 8 counts per mm */
+	aux_write_ack(AUX_SET_SCALE21);		/* 2:1 scaling */
+#endif /* INITIALIZE_MOUSE */
+	aux_write_ack(KBD_CCMD_MOUSE_DISABLE);
+	aux_write_ack(AUX_INTS_OFF);
+
+	return 0;
+}
+
+#endif /* CONFIG_PSMOUSE */
diff -urN linux-2.4.29/drivers/char/random.c linux-2.4.29-uc1/drivers/char/random.c
--- linux-2.4.29/drivers/char/random.c	2005-01-19 14:09:48.000000000 +0000
+++ linux-2.4.29-uc1/drivers/char/random.c	2005-06-14 02:12:18.000000000 +0100
@@ -837,6 +837,7 @@
 	add_timer_randomness(blkdev_timer_state[major], 0x200+major);
 }
 
+
 /******************************************************************
  *
  * Hash function definition
diff -urN linux-2.4.29/drivers/char/rtc.c linux-2.4.29-uc1/drivers/char/rtc.c
--- linux-2.4.29/drivers/char/rtc.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/char/rtc.c	2005-06-14 02:12:17.000000000 +0100
@@ -581,7 +581,7 @@
 		return 0;
 	}
 	default:
-		return -ENOTTY;
+		return -EINVAL;
 	}
 	return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
 }
diff -urN linux-2.4.29/drivers/char/serial_21285.c linux-2.4.29-uc1/drivers/char/serial_21285.c
--- linux-2.4.29/drivers/char/serial_21285.c	2002-08-03 01:39:43.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_21285.c	2005-06-14 02:12:16.000000000 +0100
@@ -5,7 +5,6 @@
  *
  * Based on drivers/char/serial.c
  */
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/errno.h>
@@ -26,7 +25,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
-#include <asm/dec21285.h>
+#include <asm/hardware/dec21285.h>
 #include <asm/hardware.h>
 
 #define BAUD_BASE		(mem_fclk_21285/64)
@@ -39,6 +38,22 @@
 #define SERIAL_21285_AUXMAJOR	205
 #define SERIAL_21285_AUXMINOR	4
 
+#ifdef CONFIG_SERIAL_21285_OLD
+#include <asm/mach-types.h>
+/*
+ * Compatability with a mistake made a long time ago.
+ * Note - the use of "ttyI", "/dev/ttyS0" and major/minor 5,64
+ * is HIGHLY DEPRECIATED, and will be removed in the 2.5
+ * kernel series.
+ *					-- rmk 15/04/2000 
+ */
+#define SERIAL_21285_OLD_NAME	"ttyI"
+#define SERIAL_21285_OLD_MAJOR	TTY_MAJOR
+#define SERIAL_21285_OLD_MINOR	64
+
+static struct tty_driver rs285_old_driver;
+#endif
+
 static struct tty_driver rs285_driver, callout_driver;
 static int rs285_refcount;
 static struct tty_struct *rs285_table[1];
@@ -339,6 +354,18 @@
 	if (request_irq(IRQ_CONTX, rs285_tx_int, 0, "rs285", NULL))
 		panic("Couldn't get tx irq for rs285");
 
+#ifdef CONFIG_SERIAL_21285_OLD
+	if (!machine_is_ebsa285() && !machine_is_netwinder()) {
+		rs285_old_driver = rs285_driver;
+		rs285_old_driver.name = SERIAL_21285_OLD_NAME;
+		rs285_old_driver.major = SERIAL_21285_OLD_MAJOR;
+		rs285_old_driver.minor_start = SERIAL_21285_OLD_MINOR;
+
+		if (tty_register_driver(&rs285_old_driver))
+			printk(KERN_ERR "Couldn't register old 21285 serial driver\n");
+	}
+#endif
+
 	if (tty_register_driver(&rs285_driver))
 		printk(KERN_ERR "Couldn't register 21285 serial driver\n");
 	if (tty_register_driver(&callout_driver))
@@ -362,6 +389,14 @@
 	if (ret)
 		printk(KERN_ERR "Unable to unregister 21285 driver (%d)\n",
 			ret);
+#ifdef CONFIG_SERIAL_21285_OLD
+	if (!machine_is_ebsa285() && !machine_is_netwinder()) {
+		ret = tty_unregister_driver(&rs285_old_driver);
+		if (ret)
+			printk(KERN_ERR "Unable to unregister old 21285 "
+				"driver (%d)\n", ret);
+	}
+#endif
 	free_irq(IRQ_CONTX, NULL);
 	free_irq(IRQ_CONRX, NULL);
 	restore_flags(flags);
@@ -477,6 +512,23 @@
 	return 0;
 }
 
+#ifdef CONFIG_SERIAL_21285_OLD
+static struct console rs285_old_cons =
+{
+	SERIAL_21285_OLD_NAME,
+	rs285_console_write,
+	NULL,
+	rs285_console_device,
+	rs285_console_wait_key,
+	NULL,
+	rs285_console_setup,
+	CON_PRINTBUFFER,
+	-1,
+	0,
+	NULL
+};
+#endif
+
 static struct console rs285_cons =
 {
 	name:		SERIAL_21285_NAME,
@@ -489,6 +541,10 @@
 
 void __init rs285_console_init(void)
 {
+#ifdef CONFIG_SERIAL_21285_OLD
+	if (!machine_is_ebsa285() && !machine_is_netwinder())
+		register_console(&rs285_old_cons);
+#endif
 	register_console(&rs285_cons);
 }
 
diff -urN linux-2.4.29/drivers/char/serial_atmel.c linux-2.4.29-uc1/drivers/char/serial_atmel.c
--- linux-2.4.29/drivers/char/serial_atmel.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_atmel.c	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,2120 @@
+/* serial port driver for the Atmel AT91 series builtin USARTs
+ *
+ * Copyright (C) 2000, 2001  Erik Andersen <andersen@lineo.com>
+ *
+ * Based on:
+ * drivers/char/68302serial.c
+ * and also based on trioserial.c from Aplio, though this driver
+ * has been extensively changed since then.  No author was 
+ * listed in trioserial.c.
+ * 
+ * Phil Wilshire 12/31/2002  Fixed multiple ^@ chars on TCSETA 
+ */
+
+/* Enable this to force this driver to always operate at 57600 */
+#undef FORCE_57600
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/config.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/console.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/arch/irq.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+#include <asm/uaccess.h>
+#include "serial_atmel.h"
+
+#define USE_INTS	1
+#define UART_CLOCK	(ARM_CLK/16)
+
+#define SERIAL_XMIT_SIZE	PAGE_SIZE
+#define RX_SERIAL_SIZE		256
+
+/* serial subtype definitions */
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+/* Debugging... DEBUG_INTR is bad to use when one of the zs
+ * lines is your console ;(
+ */
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+
+#define RS_ISR_PASS_LIMIT 256
+
+#define _INLINE_
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+
+static volatile struct atmel_usart_regs *usarts[AT91_USART_CNT] = {
+	(volatile struct atmel_usart_regs *) AT91_USART0_BASE,
+	(volatile struct atmel_usart_regs *) AT91_USART1_BASE
+};
+static struct atmel_serial atmel_info[AT91_USART_CNT];
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the memcpy_fromfs blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static unsigned char tmp_buf[SERIAL_XMIT_SIZE];	/* This is cheating */
+DECLARE_MUTEX(tmp_buf_sem);
+
+static unsigned char * rx_buf_table[AT91_USART_CNT];
+
+static unsigned char rx_buf1[RX_SERIAL_SIZE];
+static unsigned char rx_buf2[RX_SERIAL_SIZE];
+
+/* Console hooks... */
+struct atmel_serial *atmel_consinfo = 0;
+
+DECLARE_TASK_QUEUE(tq_atmel_serial);
+
+static struct tq_struct serialpoll;
+static struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+static void serpoll(void *data);
+
+static void change_speed(struct atmel_serial *info);
+
+static struct tty_struct *serial_table[AT91_USART_CNT];
+static struct termios *serial_termios[AT91_USART_CNT];
+static struct termios *serial_termios_locked[AT91_USART_CNT];
+
+static char prompt0;
+static void xmit_char(struct atmel_serial *info, char ch);
+static void xmit_string(struct atmel_serial *info, char *p, int len);
+static void start_rx(struct atmel_serial *info);
+static void wait_EOT(volatile struct atmel_usart_regs *);
+static void uart_init(struct atmel_serial *info);
+static void uart_speed(struct atmel_serial *info, unsigned cflag);
+
+static void tx_enable(volatile struct atmel_usart_regs *uart);
+static void rx_enable(volatile struct atmel_usart_regs *uart);
+static void tx_disable(volatile struct atmel_usart_regs *uart);
+static void rx_disable(volatile struct atmel_usart_regs *uart);
+static void tx_stop(volatile struct atmel_usart_regs *uart);
+static void tx_start(volatile struct atmel_usart_regs *uart, int ints);
+static void rx_stop(volatile struct atmel_usart_regs *uart);
+static void rx_start(volatile struct atmel_usart_regs *uart, int ints);
+static void set_ints_mode(int yes, struct atmel_serial *info);
+static void rs_interrupt(struct atmel_serial *info);
+extern void show_net_buffers(void);
+extern void hard_reset_now(void);
+
+static int global;
+
+static void coucou1(void)
+{
+	global = 0;
+}
+
+static void coucou2(void)
+{
+	global = 1;
+}
+static void _INLINE_ tx_enable(volatile struct atmel_usart_regs *uart)
+{
+	uart->ier = US_TXEMPTY;
+}
+static void _INLINE_ rx_enable(volatile struct atmel_usart_regs *uart)
+{
+	uart->ier = US_ENDRX | US_TIMEOUT;
+}
+static void _INLINE_ tx_disable(volatile struct atmel_usart_regs *uart)
+{
+	uart->idr = US_TXEMPTY;
+}
+static void _INLINE_ rx_disable(volatile struct atmel_usart_regs *uart)
+{
+	uart->idr = US_ENDRX | US_TIMEOUT;
+}
+static void _INLINE_ tx_stop(volatile struct atmel_usart_regs *uart)
+{
+	tx_disable(uart);
+	uart->tcr = 0;
+	uart->cr = US_TXDIS;
+}
+static void _INLINE_ tx_start(volatile struct atmel_usart_regs *uart, int ints)
+{
+	if (ints) {
+		tx_enable(uart);
+	}
+	uart->cr = US_TXEN;
+}
+static void _INLINE_ rx_stop(volatile struct atmel_usart_regs *uart)
+{
+	rx_disable(uart);
+	uart->rtor = 0;
+	// PSW fixes slew of ^@ chars on a TCSETA ioctl 
+        //uart->rcr = 0;
+	uart->cr = US_RXDIS;
+}
+static void _INLINE_ rx_start(volatile struct atmel_usart_regs *uart, int ints)
+{
+	uart->cr = US_RXEN | US_STTO;
+	uart->rtor = 20;
+	if (ints) {
+		rx_enable(uart);
+	}
+}
+static void _INLINE_ reset_status(volatile struct atmel_usart_regs *uart)
+{
+	uart->cr = US_RSTSTA;
+}
+static void set_ints_mode(int yes, struct atmel_serial *info)
+{
+	info->use_ints = yes;
+// FIXME: check
+#if 0
+	(yes) ? unmask_irq(info->irq) : mask_irq(info->irq);
+#endif
+}
+
+#ifdef US_RTS
+static void atmel_cts_off(struct atmel_serial *info)
+{
+	volatile struct atmel_usart_regs *uart;
+
+	uart = info->usart;
+	uart->mc &= ~(unsigned long) US_RTS;
+	info->cts_state = 0;
+}
+static void atmel_cts_on(struct atmel_serial *info)
+{
+	volatile struct atmel_usart_regs *uart;
+
+	uart = info->usart;
+	uart->mc |= US_RTS;
+	info->cts_state = 1;
+}
+/* Sets or clears DTR/RTS on the requested line */
+static inline void atmel_rtsdtr(struct atmel_serial *ss, int set)
+{
+        volatile struct atmel_usart_regs *uart;
+
+        uart = ss->usart;
+        if (set) {
+              uart->mc |= US_DTR | US_RTS;
+        } else {
+              uart->mc &= ~(unsigned long) (US_DTR | US_RTS);
+        }
+        return;
+}
+#endif	/* US_RTS */
+
+static inline int serial_paranoia_check(struct atmel_serial *info,
+					dev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%d, %d) in %s\n";
+	static const char *badinfo =
+		"Warning: null atmel_serial struct for (%d, %d) in %s\n";
+
+	if (!info) {
+		printk(badinfo, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+	if (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+	struct atmel_serial *info = (struct atmel_serial *) tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_stop"))
+		return;
+
+	save_flags(flags);
+	cli();
+	tx_stop(info->usart);
+	rx_stop(info->usart);
+	restore_flags(flags);
+}
+
+static void rs_put_char(struct atmel_serial *info, char ch)
+{
+	int flags = 0;
+
+	save_flags(flags);
+	cli();
+	xmit_char(info, ch);
+	wait_EOT(info->usart);
+	restore_flags(flags);
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+	struct atmel_serial *info = (struct atmel_serial *) tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_start"))
+		return;
+
+	save_flags(flags);
+	cli();
+	tx_start(info->usart, info->use_ints);
+	rx_start(info->usart, info->use_ints);
+	/* FIXME */
+//	start_rx(info);
+	restore_flags(flags);
+}
+
+/* Drop into either the boot monitor or kadb upon receiving a break
+ * from keyboard/console input.
+ */
+static void batten_down_hatches(void)
+{
+#if 0
+	/* If we are doing kadb, we call the debugger
+	 * else we just drop into the boot monitor.
+	 * Note that we must flush the user windows
+	 * first before giving up control.
+	 */
+	if ((((unsigned long) linux_dbvec) >= DEBUG_FIRSTVADDR) &&
+		(((unsigned long) linux_dbvec) <= DEBUG_LASTVADDR))
+		sp_enter_debugger();
+	else
+		panic("atmel_serial: batten_down_hatches");
+	return;
+#endif
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ *
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assembly code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static _INLINE_ void rs_sched_event(struct atmel_serial *info, int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_atmel_serial);
+	mark_bh(SERIAL_BH);
+}
+
+extern void breakpoint(void);	/* For the KGDB frame character */
+
+static _INLINE_ void receive_chars(struct atmel_serial *info, unsigned long status)
+{
+//	unsigned char ch; FIXME
+	int count;
+	volatile struct atmel_usart_regs *uart = info->usart;
+
+#if 0
+	// hack to receive chars by polling from anywhere
+	struct atmel_serial *info1 = &atmel_info;
+	struct tty_struct *tty = info1->tty;
+
+	if (!(info->flags & S_INITIALIZED))
+		return;
+#else
+	struct tty_struct *tty = info->tty;
+
+	if (!(info->flags & S_INITIALIZED))
+		return;
+#endif
+	count = RX_SERIAL_SIZE - uart->rcr;
+	// hack to receive chars by polling only BD fields
+	if (!count) {
+		return;
+	}
+#if 0
+	ch = info->rx_buf[0];
+	if (info->is_cons) {
+		if (status & US_RXBRK) {	/* whee, break received */
+			batten_down_hatches();
+			/*rs_recv_clear(info->atmel_channel); */
+			return;
+		} else if (ch == 0x10) {	/* ^P */
+			show_state();
+			show_free_areas();
+			show_buffers();
+			show_net_buffers();
+			return;
+		} else if (ch == 0x12) {	/* ^R */
+			hard_reset_now();
+			return;
+		}
+		/* It is a 'keyboard interrupt' ;-) */
+		wake_up(&keypress_wait);
+	}
+#endif
+
+#if 0
+	/* Look for kgdb 'stop' character, consult the gdb documentation
+	 * for remote target debugging and arch/sparc/kernel/sparc-stub.c
+	 * to see how all this works.
+	 */
+	if((info->kgdb_channel) && (ch =='\003')) {
+	    breakpoint();
+	    goto clear_and_exit;
+	}
+#endif
+
+	if (!tty)
+		goto clear_and_exit;
+
+	if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+		queue_task(&tty->flip.tqueue, &tq_timer);
+
+	if ((count + tty->flip.count) >= TTY_FLIPBUF_SIZE) {
+#ifdef US_RTS
+		atmel_cts_off(info);
+#endif
+		serialpoll.data = (void *) info;
+		queue_task(&serialpoll, &tq_timer);
+	}
+	memset(tty->flip.flag_buf_ptr, 0, count);
+	memcpy(tty->flip.char_buf_ptr, info->rx_buf, count);
+	tty->flip.char_buf_ptr += count;
+
+	if (status & US_PARE)
+		*(tty->flip.flag_buf_ptr - 1) = TTY_PARITY;
+	else if (status & US_OVRE)
+		*(tty->flip.flag_buf_ptr - 1) = TTY_OVERRUN;
+	else if (status & US_FRAME)
+		*(tty->flip.flag_buf_ptr - 1) = TTY_FRAME;
+
+	tty->flip.count += count;
+
+	queue_task(&tty->flip.tqueue, &tq_timer);
+
+  clear_and_exit:
+	start_rx(info);
+	return;
+}
+
+static _INLINE_ void transmit_chars(struct atmel_serial *info)
+{
+	if (info->x_char) {
+		/* Send next char */
+		xmit_char(info, info->x_char);
+		info->x_char = 0;
+		goto clear_and_return;
+	}
+
+	if ((info->xmit_cnt <= 0) || info->tty->stopped) {
+		/* That's peculiar... */
+		tx_stop(info->usart);
+		goto clear_and_return;
+	}
+
+	if (info->xmit_tail + info->xmit_cnt < SERIAL_XMIT_SIZE) {
+		xmit_string(info, info->xmit_buf + info->xmit_tail,
+					info->xmit_cnt);
+		info->xmit_tail =
+			(info->xmit_tail + info->xmit_cnt) & (SERIAL_XMIT_SIZE - 1);
+		info->xmit_cnt = 0;
+	} else {
+		coucou1();
+		xmit_string(info, info->xmit_buf + info->xmit_tail,
+					SERIAL_XMIT_SIZE - info->xmit_tail);
+		//xmit_string(info, info->xmit_buf, info->xmit_tail + info->xmit_cnt - SERIAL_XMIT_SIZE);
+		info->xmit_cnt =
+			info->xmit_cnt - (SERIAL_XMIT_SIZE - info->xmit_tail);
+		info->xmit_tail = 0;
+	}
+
+#if 0
+	/* Send char */
+	xmit_char(info, info->xmit_buf[info->xmit_tail++]);
+	info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+	info->xmit_cnt--;
+#endif
+
+	if (info->xmit_cnt < WAKEUP_CHARS)
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+	if (info->xmit_cnt <= 0) {
+		//tx_stop(info->usart);
+		goto clear_and_return;
+	}
+
+  clear_and_return:
+	/* Clear interrupt (should be auto) */
+	return;
+}
+
+static _INLINE_ void status_handle(struct atmel_serial *info, unsigned long status)
+{
+#if 0
+	if (status & DCD) {
+		if ((info->tty->termios->c_cflag & CRTSCTS) &&
+			((info->curregs[3] & AUTO_ENAB) == 0)) {
+			info->curregs[3] |= AUTO_ENAB;
+			info->pendregs[3] |= AUTO_ENAB;
+			write_zsreg(info->atmel_channel, 3, info->curregs[3]);
+		}
+	} else {
+		if ((info->curregs[3] & AUTO_ENAB)) {
+			info->curregs[3] &= ~AUTO_ENAB;
+			info->pendregs[3] &= ~AUTO_ENAB;
+			write_zsreg(info->atmel_channel, 3, info->curregs[3]);
+		}
+	}
+#endif
+	/* Whee, if this is console input and this is a
+	 * 'break asserted' status change interrupt, call
+	 * the boot prom.
+	 */
+	if ((status & US_RXBRK) && info->break_abort)
+		batten_down_hatches();
+
+	/* XXX Whee, put in a buffer somewhere, the status information
+	 * XXX whee whee whee... Where does the information go...
+	 */
+	reset_status(info->usart);
+	return;
+}
+
+
+/*
+ * This is the serial driver's generic interrupt routine
+ */
+static void rs_interrupta(int irq, void *dev_id, struct pt_regs *regs)
+{
+	rs_interrupt(&atmel_info[0]);
+}
+static void rs_interruptb(int irq, void *dev_id, struct pt_regs *regs)
+{
+	rs_interrupt(&atmel_info[1]);
+}
+static void rs_interrupt(struct atmel_serial *info)
+{
+	unsigned long status;
+
+	status = info->usart->csr;
+	if (status & (US_ENDRX | US_TIMEOUT)) {
+		receive_chars(info, status);
+	}
+	if (status & (US_TXEMPTY)) {
+		transmit_chars(info);
+	}
+	status_handle(info, status);
+
+#ifdef US_RTS
+	if (!info->cts_state) {
+		if (info->tty->flip.count < TTY_FLIPBUF_SIZE - RX_SERIAL_SIZE) {
+			atmel_cts_on(info);
+		}
+	}
+#endif
+	if (!info->use_ints) {
+		serialpoll.data = (void *) info;
+		queue_task(&serialpoll, &tq_timer);
+	}
+	return;
+}
+static void serpoll(void *data)
+{
+	struct atmel_serial *info = data;
+
+	rs_interrupt(info);
+}
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_atmel_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct atmel_serial *info = (struct atmel_serial *) private_;
+	struct tty_struct *tty;
+
+	tty = info->tty;
+	if (!tty)
+		return;
+#if 0 	// FIXME - CHECK
+	if (clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+			tty->ldisc.write_wakeup) (tty->ldisc.write_wakeup) (tty);
+		wake_up_interruptible(&tty->write_wait);
+	}
+#endif
+}
+
+/*
+ * This routine is called from the scheduler tqueue when the interrupt
+ * routine has signalled that a hangup has occurred.  The path of
+ * hangup processing is:
+ *
+ * 	serial interrupt routine -> (scheduler tqueue) ->
+ * 	do_serial_hangup() -> tty->hangup() -> rs_hangup()
+ *
+ */
+static void do_serial_hangup(void *private_)
+{
+	struct atmel_serial *info = (struct atmel_serial *) private_;
+	struct tty_struct *tty;
+
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	tty_hangup(tty);
+}
+
+
+/*
+ * This subroutine is called when the RS_TIMER goes off.  It is used
+ * by the serial driver to handle ports that do not have an interrupt
+ * (irq=0).  This doesn't work at all for 16450's, as a sun has a Z8530.
+ */
+#if 0
+static void rs_timer(void)
+{
+	panic("rs_timer called\n");
+	return;
+}
+#endif
+
+static unsigned long calcCD(unsigned long br)
+{
+	return (UART_CLOCK / br);
+}
+
+static void uart_init(struct atmel_serial *info)
+{
+	volatile struct atmel_usart_regs *uart;
+
+	if (info) {
+		uart = info->usart;
+	} else {
+		uart = usarts[0];
+	}
+
+	/* Reset the USART */
+	uart->cr = US_TXDIS | US_RXDIS | US_RSTTX | US_RSTRX;
+	/* clear Rx receive and Tx sent counters */
+	uart->rcr = 0;
+	uart->tcr = 0;
+
+	/* Disable interrups till we say we want them */
+	tx_disable(info->usart);
+	rx_disable(info->usart);
+	
+	/* Set the serial port into a safe sane state */
+	uart->mr = US_USCLKS(0) | US_CLK0 | US_CHMODE(0) | US_NBSTOP(0) |
+		    US_PAR(4) | US_CHRL(3);
+
+#ifndef FORCE_57600
+	uart->brgr = calcCD(9600);
+#else
+	uart->brgr = calcCD(57600);
+#endif
+
+	uart->rtor = 20;			// timeout = value * 4 *bit period
+	uart->ttgr = 0;				// no guard time
+	uart->rcr = 0;
+	uart->rpr = 0;
+	uart->tcr = 0;
+	uart->tpr = 0;
+#ifdef US_RTS
+	uart->mc = 0; 
+#endif
+}
+
+/* It is the responsibilty of whoever calls this function to be sure
+ * that that have called
+ *	tx_stop(uart); rx_stop(uart);
+ * before calling the function.  Failure to do this will cause messy
+ * things to happen.  You have been warned.   */
+static void uart_speed(struct atmel_serial *info, unsigned cflag)
+{
+	unsigned baud = info->baud;
+	volatile struct atmel_usart_regs *uart = info->usart;
+
+	// disable tx and rx
+	uart->cr = US_TXDIS | US_RXDIS;
+	
+	// disable interrupts
+	tx_disable(uart);
+	rx_disable(uart);
+	
+#ifndef FORCE_57600
+	uart->brgr = calcCD(baud);
+#else
+	uart->brgr = calcCD(57600);
+#endif
+/* FIXME */
+#if 0
+	/* probably not needed */
+	uart->US_RTOR = 20;			// timeout = value * 4 *bit period
+	uart->US_TTGR = 0;				// no guard time
+	uart->US_RPR = 0;
+	uart->US_RCR = 0;
+	uart->US_TPR = 0;
+	uart->US_TCR = 0;
+#endif
+
+
+/* FIXME */
+#if 0
+	uart->mc = 0;
+	if (cflag != 0xffff) {
+		uart->mr = US_USCLKS(0) | US_CLK0 | US_CHMODE(0) | US_NBSTOP(0) |
+		    US_PAR(0);
+
+		if ((cflag & CSIZE) == CS8)
+			uart->mr |= US_CHRL(3);	// 8 bit char
+		else
+			uart->mr |= US_CHRL(2);	// 7 bit char
+
+		if (cflag & CSTOPB)
+			uart->mr |= US_NBSTOP(2);	// 2 stop bits
+
+		if (!(cflag & PARENB))
+			uart->mr |= US_PAR(4);	// parity disabled
+		else if (cflag & PARODD)
+			uart->mr |= US_PAR(1);	// odd parity
+	}
+#endif	
+	
+/* FIXME */
+#if 0
+	// enable tx and rx
+	uart->cr = US_TXEN | US_RXEN;
+	
+	// enable interrupts
+	tx_enable();
+	rx_enable();
+#endif
+	tx_start(uart, info->use_ints);
+	start_rx(info);
+}
+
+static void wait_EOT(volatile struct atmel_usart_regs *uart)
+{
+	// make sure tx is enabled
+	uart->cr = US_TXEN;
+	
+	// wait until all chars sent FIXME - is this sane ?
+	while (1) {
+		if (uart->csr & US_TXEMPTY)
+			break;
+	}
+}
+static int startup(struct atmel_serial *info)
+{
+	unsigned long flags;
+
+	if (info->flags & S_INITIALIZED)
+		return 0;
+
+	if (!info->xmit_buf) {
+		info->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL);
+		if (!info->xmit_buf)
+			return -ENOMEM;
+	}
+	if (!info->rx_buf) {
+	    //info->rx_buf = (unsigned char *) get_free_page(GFP_KERNEL);
+		//info->rx_buf = rx_buf1;
+		if (!info->rx_buf)
+			return -ENOMEM;
+	}
+	save_flags(flags);
+	cli();
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttyS%d (irq %d)...\n", info->line, info->irq);
+#endif
+	/*
+	 * Clear the FIFO buffers and disable them
+	 * (they will be reenabled in change_speed())
+	 */
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+
+	/*
+	 * and set the speed of the serial port
+	 */
+
+	uart_init(info);
+	//set_ints_mode(0, info);
+	change_speed(info);
+	info->flags |= S_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct atmel_serial *info)
+{
+	unsigned long flags;
+
+	tx_disable(info->usart);
+	rx_disable(info->usart);
+	rx_stop(info->usart);		/* All off! */
+	if (!(info->flags & S_INITIALIZED))
+		return;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Shutting down serial port %d (irq %d)....\n", info->line,
+		   info->irq);
+#endif
+
+	save_flags(flags);
+	cli();						/* Disable interrupts */
+
+	if (info->xmit_buf) {
+		free_page((unsigned long) info->xmit_buf);
+		info->xmit_buf = 0;
+	}
+
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~S_INITIALIZED;
+	restore_flags(flags);
+}
+
+/* rate = 1036800 / ((65 - prescale) * (1<<divider)) */
+
+static int baud_table[] = {
+	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
+	9600, 19200, 38400, 57600, 115200, 0
+};
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void change_speed(struct atmel_serial *info)
+{
+	unsigned cflag;
+	int      i;
+
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+
+	// disable tx and rx
+	info->usart->cr = US_TXDIS | US_RXDIS;
+	
+	/* First disable the interrupts */
+	tx_stop(info->usart);
+	rx_stop(info->usart);
+
+	/* set the baudrate */
+	i = cflag & CBAUD;
+
+	info->baud = baud_table[i];
+	uart_speed(info, cflag);
+	tx_start(info->usart, info->use_ints);
+	rx_start(info->usart, info->use_ints);
+
+	// enable tx and rx
+	info->usart->cr = US_TXEN | US_RXEN;
+	
+	return;
+}
+
+static void start_rx(struct atmel_serial *info)
+{
+	volatile struct atmel_usart_regs *uart = info->usart;
+
+	rx_stop(uart);
+/*  FIXME - rehnberg
+	if (info->rx_buf == rx_buf1) {
+		info->rx_buf = rx_buf2;
+	} else {
+		info->rx_buf = rx_buf1;
+	}
+*/
+	uart->rpr = (unsigned long) info->rx_buf;
+	uart->rcr = (unsigned long) RX_SERIAL_SIZE;
+	rx_start(uart, info->use_ints);
+}
+static void xmit_char(struct atmel_serial *info, char ch)
+{
+	prompt0 = ch;
+	xmit_string(info, &prompt0, 1);
+}
+static void xmit_string(struct atmel_serial *info, char *p, int len)
+{
+	info->usart->tcr = 0;
+	info->usart->tpr = (unsigned long) p;
+	info->usart->tcr = (unsigned long) len;
+	tx_start(info->usart, info->use_ints);
+}
+
+/*
+ * atmel_console_print is registered for printk.
+ */
+int atmel_console_initialized;
+
+static void init_console(struct atmel_serial *info)
+{
+	memset(info, 0, sizeof(struct atmel_serial));
+
+#ifdef CONFIG_SWAP_ATMEL_PORTS
+	info->usart = (volatile struct atmel_usart_regs *) AT91_USART1_BASE;
+	info->irqmask = AIC_URT1;
+	info->irq = IRQ_USART1;
+#else
+	info->usart = (volatile struct atmel_usart_regs *) AT91_USART0_BASE;
+	info->irqmask = 1<<IRQ_USART0;
+	info->irq = IRQ_USART0;
+#endif
+	info->tty = 0;
+	info->port = 0;
+	info->use_ints = 0;
+	info->cts_state = 1;
+	info->is_cons = 1;
+	atmel_console_initialized = 1;
+}
+
+
+void console_print_atmel(const char *p)
+{
+	char c;
+	struct atmel_serial *info;
+
+#ifdef CONFIG_SWAP_ATMEL_PORTS
+	info = &atmel_info[1];
+#else
+	info = &atmel_info[0];
+#endif
+
+	if (!atmel_console_initialized) {
+		init_console(info);
+		uart_init(info);
+		info->baud = 9600;
+		tx_stop(info->usart);
+		rx_stop(info->usart);
+		uart_speed(info, 0xffff);
+		tx_start(info->usart, info->use_ints);
+		rx_start(info->usart, info->use_ints);
+	}
+
+	while ((c = *(p++)) != 0) {
+		if (c == '\n')
+			rs_put_char(info, '\r');
+		rs_put_char(info, c);
+	}
+
+	/* Comment this if you want to have a strict interrupt-driven output */
+#if 0
+	if (!info->use_ints)
+	    rs_fair_output(info);
+#endif
+
+	return;
+}
+
+static void rs_set_ldisc(struct tty_struct *tty)
+{
+	struct atmel_serial *info = (struct atmel_serial *) tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_set_ldisc"))
+		return;
+
+	info->is_cons = (tty->termios->c_line == N_TTY);
+
+	printk("ttyS%d console mode %s\n", info->line,
+		   info->is_cons ? "on" : "off");
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct atmel_serial *info = (struct atmel_serial *) tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
+		return;
+	if (!info->use_ints) {
+		for (;;) {
+			if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
+				!info->xmit_buf) return;
+
+			/* Enable transmitter */
+			save_flags(flags);
+			cli();
+			tx_start(info->usart, info->use_ints);
+		}
+	} else {
+		if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
+			!info->xmit_buf) return;
+
+		/* Enable transmitter */
+		save_flags(flags);
+		cli();
+		tx_start(info->usart, info->use_ints);
+	}
+
+	if (!info->use_ints)
+		wait_EOT(info->usart);
+	/* Send char */
+	xmit_char(info, info->xmit_buf[info->xmit_tail++]);
+	info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+	info->xmit_cnt--;
+
+	restore_flags(flags);
+}
+
+extern void console_printn(const char *b, int count);
+
+static int rs_write(struct tty_struct *tty, int from_user,
+					const unsigned char *buf, int count)
+{
+	int c, total = 0;
+	struct atmel_serial *info = (struct atmel_serial *) tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_write"))
+		return 0;
+
+	if (!tty || !info->xmit_buf)
+		return 0;
+
+	save_flags(flags);
+	while (1) {
+		cli();
+		c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+						   SERIAL_XMIT_SIZE - info->xmit_head));
+		if (c <= 0)
+			break;
+
+		if (from_user) {
+			down(&tmp_buf_sem);
+			copy_from_user(tmp_buf, buf, c);
+			memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
+			up(&tmp_buf_sem);
+		} else {
+			memcpy(info->xmit_buf + info->xmit_head, buf, c);
+		}
+		info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1);
+		info->xmit_cnt += c;
+		restore_flags(flags);
+		buf += c;
+		count -= c;
+		total += c;
+	}
+
+	if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
+		/* Enable transmitter */
+
+		cli();
+		/*printk("Enabling transmitter\n"); */
+
+		if (!info->use_ints) {
+			while (info->xmit_cnt) {
+				wait_EOT(info->usart);
+				/* Send char */
+				xmit_char(info, info->xmit_buf[info->xmit_tail++]);
+				wait_EOT(info->usart);
+				info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+				info->xmit_cnt--;
+			}
+		} else {
+			if (info->xmit_cnt) {
+				/* Send char */
+				wait_EOT(info->usart);
+				if (info->xmit_tail + info->xmit_cnt < SERIAL_XMIT_SIZE) {
+					xmit_string(info, info->xmit_buf + info->xmit_tail,
+								info->xmit_cnt);
+					info->xmit_tail =
+						(info->xmit_tail +
+						 info->xmit_cnt) & (SERIAL_XMIT_SIZE - 1);
+					info->xmit_cnt = 0;
+				} else {
+					coucou2();
+					xmit_string(info, info->xmit_buf + info->xmit_tail,
+								SERIAL_XMIT_SIZE - info->xmit_tail);
+					//xmit_string(info, info->xmit_buf, info->xmit_tail + info->xmit_cnt - SERIAL_XMIT_SIZE);
+					info->xmit_cnt =
+						info->xmit_cnt - (SERIAL_XMIT_SIZE - info->xmit_tail);
+					info->xmit_tail = 0;
+				}
+			}
+		}
+	} else {
+		/*printk("Skipping transmit\n"); */
+	}
+
+#if 0
+	printk("Enabling stuff anyhow\n");
+	tx_start(0);
+
+	if (SCC_EOT(0, 0)) {
+		printk("TX FIFO empty.\n");
+		/* Send char */
+		atmel_xmit_char(info->usart, info->xmit_buf[info->xmit_tail++]);
+		info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+		info->xmit_cnt--;
+	}
+#endif
+
+	restore_flags(flags);
+	return total;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct atmel_serial *info = (struct atmel_serial *) tty->driver_data;
+	int ret;
+
+	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
+		return 0;
+	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
+	if (ret < 0)
+		ret = 0;
+	return ret;
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct atmel_serial *info = (struct atmel_serial *) tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+		return 0;
+	return info->xmit_cnt;
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	unsigned long flags;
+	struct atmel_serial *info = (struct atmel_serial *) tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+		return;
+	save_flags(flags);
+	cli();
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+	restore_flags(flags);
+	wake_up_interruptible(&tty->write_wait);
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		tty->ldisc.write_wakeup) (tty->ldisc.write_wakeup) (tty);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ *
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct *tty)
+{
+	struct atmel_serial *info = (struct atmel_serial *) tty->driver_data;
+
+#ifdef SERIAL_DEBUG_THROTTLE
+	char buf[64];
+
+	printk("throttle %s: %d....\n", _tty_name(tty, buf),
+		   tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+		return;
+
+	if (I_IXOFF(tty))
+		info->x_char = STOP_CHAR(tty);
+
+	/* Turn off RTS line (do this atomic) */
+}
+
+static void rs_unthrottle(struct tty_struct *tty)
+{
+	struct atmel_serial *info = (struct atmel_serial *) tty->driver_data;
+
+#ifdef SERIAL_DEBUG_THROTTLE
+	char buf[64];
+
+	printk("unthrottle %s: %d....\n", _tty_name(tty, buf),
+		   tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+		return;
+
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			info->x_char = START_CHAR(tty);
+	}
+
+	/* Assert RTS line (do this atomic) */
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int get_serial_info(struct atmel_serial *info,
+						   struct serial_struct *retinfo)
+{
+	struct serial_struct tmp;
+
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = info->type;
+	tmp.line = info->line;
+	tmp.irq = info->irq;
+	tmp.port = info->port;
+	tmp.flags = info->flags;
+	tmp.baud_base = info->baud_base;
+	tmp.close_delay = info->close_delay;
+	tmp.closing_wait = info->closing_wait;
+	tmp.custom_divisor = info->custom_divisor;
+	copy_to_user(retinfo, &tmp, sizeof(*retinfo));
+	return 0;
+}
+
+static int set_serial_info(struct atmel_serial *info,
+						   struct serial_struct *new_info)
+{
+	struct serial_struct new_serial;
+	struct atmel_serial old_info;
+	int retval = 0;
+
+	if (!new_info)
+		return -EFAULT;
+	copy_from_user(&new_serial, new_info, sizeof(new_serial));
+	old_info = *info;
+
+	if (!suser()) {
+		if ((new_serial.baud_base != info->baud_base) ||
+			(new_serial.type != info->type) ||
+			(new_serial.close_delay != info->close_delay) ||
+			((new_serial.flags & ~S_USR_MASK) !=
+			 (info->flags & ~S_USR_MASK))) return -EPERM;
+		info->flags = ((info->flags & ~S_USR_MASK) |
+					   (new_serial.flags & S_USR_MASK));
+		info->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	if (info->count > 1)
+		return -EBUSY;
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+	info->baud_base = new_serial.baud_base;
+	info->flags = ((info->flags & ~S_FLAGS) |
+				   (new_serial.flags & S_FLAGS));
+	info->type = new_serial.type;
+	info->close_delay = new_serial.close_delay;
+	info->closing_wait = new_serial.closing_wait;
+
+  check_and_exit:
+	//retval = startup(info);
+	change_speed(info);
+	retval = 0;
+	return retval;
+}
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space.
+ */
+static int get_lsr_info(struct atmel_serial *info, unsigned int *value)
+{
+	unsigned char status;
+
+	cli();
+	status = info->usart->csr;
+	status &= US_TXEMPTY;
+	sti();
+	put_user(status, value);
+	return 0;
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void send_break(struct atmel_serial *info, int duration)
+{
+        unsigned long flags;
+        if (!info->port)  return;
+
+	current->state = TASK_INTERRUPTIBLE;
+	save_flags(flags); cli();
+	info->usart->cr = US_STTBRK;
+	if (!info->use_ints) {
+		while (US_TXRDY != (info->usart->csr & US_TXRDY)) {
+			;					// this takes max 2ms at 9600
+		}
+		info->usart->cr = US_STPBRK;
+	}
+	restore_flags(flags);
+}
+
+static int rs_ioctl(struct tty_struct *tty, struct file *file,
+					unsigned int cmd, unsigned long arg)
+{
+	int error;
+	struct atmel_serial *info = (struct atmel_serial *) tty->driver_data;
+	int retval;
+
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+		(cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) &&
+		(cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+			return -EIO;
+	}
+
+	switch (cmd) {
+	case TCSBRK:				/* SVID version: non-zero arg --> no break */
+		retval = tty_check_change(tty);
+		if (retval)
+			return retval;
+		tty_wait_until_sent(tty, 0);
+		if (!arg)
+			send_break(info, HZ / 4);	/* 1/4 second */
+		return 0;
+	case TCSBRKP:				/* support for POSIX tcsendbreak() */
+		retval = tty_check_change(tty);
+		if (retval)
+			return retval;
+		tty_wait_until_sent(tty, 0);
+		send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
+		return 0;
+	case TIOCGSOFTCAR:
+		error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
+
+		if (error)
+			return error;
+		put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
+		return 0;
+	case TIOCSSOFTCAR:
+		arg = get_user(arg,(unsigned long *) arg);
+		tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
+		return 0;
+	case TIOCGSERIAL:
+		error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct serial_struct));
+		if (error)
+			return error;
+		return get_serial_info(info, (struct serial_struct *) arg);
+	case TIOCSSERIAL:
+		return set_serial_info(info, (struct serial_struct *) arg);
+	case TIOCSERGETLSR:		/* Get line status register */
+		error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(unsigned int));
+		if (error)
+			return error;
+		else
+			return get_lsr_info(info, (unsigned int *) arg);
+
+	case TIOCSERGSTRUCT:
+		error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(struct atmel_serial));
+		if (error)
+			return error;
+		copy_to_user((struct atmel_serial *) arg, info,
+			sizeof(struct atmel_serial));
+		return 0;
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static void rs_set_termios(struct tty_struct *tty,
+	struct termios *old_termios)
+{
+	struct atmel_serial *info = (struct atmel_serial *) tty->driver_data;
+
+	if (tty->termios->c_cflag == old_termios->c_cflag)
+		return;
+
+	change_speed(info);
+
+	if ((old_termios->c_cflag & CRTSCTS) &&
+		!(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ *
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * S structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file *filp)
+{
+	struct atmel_serial *info = (struct atmel_serial *) tty->driver_data;
+	unsigned long flags;
+
+	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+		return;
+
+	save_flags(flags);
+	cli();
+
+	if (tty_hung_up_p(filp)) {
+		restore_flags(flags);
+		return;
+	}
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_close ttyS%d, count = %d\n", info->line, info->count);
+#endif
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  Info->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+			   "info->count is %d\n", info->count);
+		info->count = 1;
+	}
+	if (--info->count < 0) {
+		printk("rs_close: bad serial port count for ttyS%d: %d\n",
+			   info->line, info->count);
+		info->count = 0;
+	}
+	if (info->count) {
+		restore_flags(flags);
+		return;
+	}
+	// closing port so disable interrupts
+	set_ints_mode(0, info);
+
+	info->flags |= S_CLOSING;
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & S_NORMAL_ACTIVE)
+		info->normal_termios = *tty->termios;
+	if (info->flags & S_CALLOUT_ACTIVE)
+		info->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != S_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (tty->ldisc.num != tty_ldiscs[N_TTY].num) {
+		if (tty->ldisc.close)
+			(tty->ldisc.close) (tty);
+		tty->ldisc = tty_ldiscs[N_TTY];
+		tty->termios->c_line = N_TTY;
+		if (tty->ldisc.open)
+			(tty->ldisc.open) (tty);
+	}
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(S_NORMAL_ACTIVE | S_CALLOUT_ACTIVE | S_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	restore_flags(flags);
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void rs_hangup(struct tty_struct *tty)
+{
+	struct atmel_serial *info = (struct atmel_serial *) tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
+		return;
+
+	rs_flush_buffer(tty);
+	shutdown(info);
+	info->event = 0;
+	info->count = 0;
+	info->flags &= ~(S_NORMAL_ACTIVE | S_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file *filp,
+						   struct atmel_serial *info)
+{
+	DECLARE_WAITQUEUE(wait, current); 
+	int retval;
+	int do_clocal = 0;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (info->flags & S_CLOSING) {
+		interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		if (info->flags & S_HUP_NOTIFY)
+			return -EAGAIN;
+		else
+			return -ERESTARTSYS;
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & S_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+			(info->flags & S_SESSION_LOCKOUT) &&
+			(info->session != current->session)) return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+			(info->flags & S_PGRP_LOCKOUT) &&
+			(info->pgrp != current->pgrp)) return -EBUSY;
+		info->flags |= S_CALLOUT_ACTIVE;
+		return 0;
+	}
+
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & S_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= S_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & S_CALLOUT_ACTIVE) {
+		if (info->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, info->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready before block: ttyS%d, count = %d\n",
+		   info->line, info->count);
+#endif
+	info->count--;
+	info->blocked_open++;
+	while (1) {
+#ifdef US_RTS
+		save_flags(flags);
+		cli();
+		if (!(info->flags & S_CALLOUT_ACTIVE))
+			atmel_rtsdtr(info, 1);
+		restore_flags(flags);
+#endif
+		current->state = TASK_INTERRUPTIBLE;
+		if (tty_hung_up_p(filp) || !(info->flags & S_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & S_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & S_CALLOUT_ACTIVE) &&
+			!(info->flags & S_CLOSING) && do_clocal)
+			break;
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef SERIAL_DEBUG_OPEN
+		printk("block_til_ready blocking: ttyS%d, count = %d\n",
+			   info->line, info->count);
+#endif
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&info->open_wait, &wait);
+	if (!tty_hung_up_p(filp))
+		info->count++;
+	info->blocked_open--;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready after blocking: ttyS%d, count = %d\n",
+		   info->line, info->count);
+#endif
+	if (retval)
+		return retval;
+	info->flags |= S_NORMAL_ACTIVE;
+	if (!info->use_ints) {
+		serialpoll.data = (void *) info;
+		queue_task(&serialpoll, &tq_timer);
+	}
+	return 0;
+}
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its S structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+int rs_open(struct tty_struct *tty, struct file *filp)
+{
+	struct atmel_serial *info;
+	int retval, line;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+
+	// check if line is sane
+	if (line < 0 || line >= AT91_USART_CNT)
+		return -ENODEV;
+
+	info = &atmel_info[line];
+#if 0
+	/* Is the kgdb running over this line? */
+	if (info->kgdb_channel)
+		return -ENODEV;
+#endif
+	if (serial_paranoia_check(info, tty->device, "rs_open"))
+		return -ENODEV;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+		   info->count);
+#endif
+	info->count++;
+	tty->driver_data = info;
+	info->tty = tty;
+
+	/*
+	 * Start up serial port
+	 */
+	set_ints_mode(1, info);
+	
+	retval = startup(info);
+	if (retval)
+		return retval;
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("rs_open returning after block_til_ready with %d\n",
+			   retval);
+#endif
+		return retval;
+	}
+
+	if ((info->count == 1) && (info->flags & S_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->normal_termios;
+		else
+			*tty->termios = info->callout_termios;
+		change_speed(info);
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open ttyS%d successful...\n", info->line);
+#endif
+	return 0;
+}
+
+
+#if 0
+
+static inline void rs_cons_check(struct atmel_serial *ss, int channel)
+{
+	int i, o, io;
+	static consout_registered = 0;
+	static msg_printed = 0;
+
+	i = o = io = 0;
+
+	/* Is this one of the serial console lines? */
+	if ((atmel_cons_chanout != channel) && (atmel_cons_chanin != channel))
+		return;
+	atmel_conschan = ss->atmel_channel;
+	atmel_consinfo = ss;
+
+	/* Register the console output putchar, if necessary */
+	if ((atmel_cons_chanout == channel)) {
+		o = 1;
+		/* double whee.. */
+		if (!consout_registered) {
+			register_console(atmel_console_print);
+			consout_registered = 1;
+		}
+	}
+
+	/* If this is console input, we handle the break received
+	 * status interrupt on this line to mean prom_halt().
+	 */
+	if (atmel_cons_chanin == channel) {
+		ss->break_abort = 1;
+		i = 1;
+	}
+	if (o && i)
+		io = 1;
+	if (ss->baud != 9600)
+		panic("Console baud rate weirdness");
+
+	/* Set flag variable for this port so that it cannot be
+	 * opened for other uses by accident.
+	 */
+	ss->is_cons = 1;
+
+	if (io) {
+		if (!msg_printed) {
+			printk("zs%d: console I/O\n", ((channel >> 1) & 1));
+			msg_printed = 1;
+		}
+	} else {
+		printk("zs%d: console %s\n", ((channel >> 1) & 1),
+			   (i == 1 ? "input" : (o == 1 ? "output" : "WEIRD")));
+	}
+}
+#endif
+
+static struct irqaction irq_usart0 =
+	{ rs_interrupta, 0, 0, "usart0", NULL, NULL };
+static struct irqaction irq_usart1 =
+	{ rs_interruptb, 0, 0, "usart1", NULL, NULL };
+
+extern int setup_arm_irq(int, struct irqaction *);
+
+static void interrupts_init(void)
+{
+	setup_arm_irq(IRQ_USART0, &irq_usart0);
+	setup_arm_irq(IRQ_USART1, &irq_usart1);
+}
+
+static void show_serial_version(void)
+{
+	printk("Atmel USART driver version 0.99\n");
+}
+
+/* rs_init inits the driver */
+static int  __init rs_atmel_init(void)
+{
+	int flags, i;
+	struct atmel_serial *info;
+
+	/* initialise PIO for serial port */
+	HW_AT91_USART_INIT 
+
+	/* Setup base handler, and timer table. */
+	init_bh(SERIAL_BH, do_serial_bh);
+	//xxx timer_table[RS_TIMER].fn = rs_timer;
+	//xxx timer_table[RS_TIMER].expires = 0;
+
+	// FIXME - do this right
+	rx_buf_table[0] = rx_buf1;
+	rx_buf_table[1] = rx_buf2;
+	
+	show_serial_version();
+
+	/* Initialize the tty_driver structure */
+
+	// set the tty_struct pointers to NULL to let the layer
+	// above allocate the structs.
+	for (i=0; i < AT91_USART_CNT; i++)
+		serial_table[i] = NULL;
+		
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+	serial_driver.name = "ttyS";
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64;
+#ifdef CONFIG_CONSOLE_ON_SC28L91	
+	serial_driver.minor_start += 1;
+#endif
+	serial_driver.num = 2;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+
+	serial_driver.init_termios.c_cflag =
+		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = rs_open;
+	serial_driver.close = rs_close;
+	serial_driver.write = rs_write;
+	serial_driver.flush_chars = rs_flush_chars;
+	serial_driver.write_room = rs_write_room;
+	serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	serial_driver.flush_buffer = rs_flush_buffer;
+	serial_driver.ioctl = rs_ioctl;
+	serial_driver.throttle = rs_throttle;
+	serial_driver.unthrottle = rs_unthrottle;
+	serial_driver.set_termios = rs_set_termios;
+	serial_driver.stop = rs_stop;
+	serial_driver.start = rs_start;
+	serial_driver.hangup = rs_hangup;
+	serial_driver.set_ldisc = rs_set_ldisc;
+
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+	callout_driver.name = "cua";
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register serial driver\n");
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+
+	save_flags(flags);
+	cli();
+	for (i = 0; i < AT91_USART_CNT; i++) {
+		info = &atmel_info[i];
+		info->magic = SERIAL_MAGIC;
+		info->usart = usarts[i];
+		info->tty = 0;
+		info->irqmask = (i) ? (1<<IRQ_USART1) : (1<<IRQ_USART0);
+		info->irq = (i) ? IRQ_USART1 : IRQ_USART0;
+#ifdef CONFIG_SWAP_ATMEL_PORTS
+		info->port = (i) ? 2 : 1;
+		info->line = !i;
+#ifdef CONFIG_CONSOLE_ON_ATMEL
+		info->is_cons = i;
+#else
+		info->is_cons = 0;
+#endif	
+#else
+		info->port = (i) ? 1 : 2;
+		info->line = i;
+#ifdef CONFIG_CONSOLE_ON_ATMEL
+		info->is_cons = !i;
+#else
+		info->is_cons = 0;
+#endif	
+#endif
+#ifdef CONFIG_CONSOLE_ON_SC28L91
+		info->line += 1;
+#endif
+		set_ints_mode(0, info);
+		info->custom_divisor = 16;
+		info->close_delay = 50;
+		info->closing_wait = 3000;
+		info->cts_state = 1;
+		info->x_char = 0;
+		info->event = 0;
+		info->count = 0;
+		info->blocked_open = 0;
+		info->tqueue.routine = do_softint;
+		info->tqueue.data = info;
+		info->tqueue_hangup.routine = do_serial_hangup;
+		info->tqueue_hangup.data = info;
+		info->callout_termios = callout_driver.init_termios;
+		info->normal_termios = serial_driver.init_termios;
+		init_waitqueue_head(&info->open_wait);
+		init_waitqueue_head(&info->close_wait);
+		info->rx_buf = rx_buf_table[i];
+
+		printk("%s%d at 0x%p (irq = %d)", serial_driver.name, info->line,
+			   info->usart, info->irq);
+		printk(" is a builtin Atmel APB USART\n");
+	}
+	
+	// FIXME
+	info->usart->cr = 0x1ac; // reset, disable
+	info->usart->idr = 0xffffffff; // disable all interrupts
+	info->usart->tcr = 0; // stop transmit
+	info->usart->rcr = 0; // stop receive
+	
+	interrupts_init();
+
+	restore_flags(flags);
+	// hack to do polling
+	serialpoll.routine = serpoll;
+	serialpoll.data = 0;
+
+	return 0;
+}
+
+module_init(rs_atmel_init);
+
+#if 0
+/*
+ * register_serial and unregister_serial allows for serial ports to be
+ * configured at run-time, to support PCMCIA modems.
+ */
+/* SPARC: Unused at this time, just here to make things link. */
+static int register_serial(struct serial_struct *req)
+{
+	return -1;
+}
+
+static void unregister_serial(int line)
+{
+	return;
+}
+
+static void dbg_putc(int ch)
+{
+	static char tmp[2];
+#define US_TPR  (0x38) /* Transmit Pointer Register */
+#define US_TCR  (0x3C) /* Transmit Counter Register */
+
+	tmp[0] = ch;
+
+	outl_t((unsigned long) tmp, (USART0_BASE + US_TPR) );
+	outl_t(1, (USART0_BASE + US_TCR) );
+
+	while (inl_t((USART0_BASE + US_TCR) )) {
+	}
+}
+
+static void dbg_print(const char *str)
+{
+	const char *p;
+
+	for (p = str; *p; p++) {
+		if (*p == '\n') {
+			dbg_putc('\r');
+		}
+		dbg_putc(*p);
+	}
+}
+
+static void dbg_printk(const char *fmt, ...)
+{
+	char tmp[256];
+	va_list args;
+
+	va_start(args, fmt);
+	vsprintf(tmp, fmt, args);
+	va_end(args);
+	dbg_print(tmp);
+}
+
+static void rs_atmel_print(const char *str)
+{
+	dbg_printk(str);
+}
+
+static void dump_a(unsigned long a, unsigned int s)
+{
+	unsigned long q;
+
+	for (q = 0; q < s; q++) {
+		if (q % 16 == 0) {
+			dbg_printk("%08X: ", q + a);
+		}
+		if (q % 16 == 7) {
+			dbg_printk("%02X-", *(unsigned char *) (q + a));
+		} else {
+			dbg_printk("%02X ", *(unsigned char *) (q + a));
+		}
+		if (q % 16 == 15) {
+			dbg_printk(" :\n");
+		}
+	}
+	if (q % 16) {
+		dbg_printk(" :\n");
+	}
+}
+#endif
+
+static kdev_t atmel_console_device(struct console *c)
+{
+
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+int atmel_console_setup(void)
+{
+  HW_AT91_USART_INIT
+  return 0;
+}
+
+void atmel_console_write (struct console *co, const char *str,
+			   unsigned int count)
+{
+	char c;
+	struct atmel_serial *info;
+
+#ifdef CONFIG_SWAP_ATMEL_PORTS
+	info = &atmel_info[1];
+#else
+	info = &atmel_info[0];
+#endif
+
+	if (!atmel_console_initialized) {
+		init_console(info);
+		uart_init(info);
+		info->baud = 9600;
+		tx_stop(info->usart);
+		rx_stop(info->usart);
+		uart_speed(info, 0xffff);
+		tx_start(info->usart, info->use_ints);
+		rx_start(info->usart, info->use_ints);
+	}
+
+    	while (count--) {
+        	if (*str == '\n')
+           		rs_put_char(info,'\r');
+        	rs_put_char(info, *str++ );
+    	}
+}
+
+static struct console atmel_driver = {
+	name:		"ttyS",
+	write:		atmel_console_write,
+	read:		NULL,
+	device:		atmel_console_device,
+	unblank:	NULL,
+	setup:		atmel_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+	cflag:		0,
+	next:		NULL
+};
+
+void atmel_console_init(void)
+{
+	register_console(&atmel_driver);
+}
diff -urN linux-2.4.29/drivers/char/serial_atmel.h linux-2.4.29-uc1/drivers/char/serial_atmel.h
--- linux-2.4.29/drivers/char/serial_atmel.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_atmel.h	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,132 @@
+/* serial-atmel.h: Definitions for the Atmel serial driver.
+ *
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     D. Jeff Dionne <jeff@uClinux.org>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ * Based on:
+ *
+ * drivers/char/68328serial.h
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _ATMEL_SERIAL_H
+#define _ATMEL_SERIAL_H
+
+#include <linux/config.h>
+#include <asm/page.h>
+#include <asm/arch/hardware.h>
+
+/*
+ * For the close wait times, 0 means wait forever for serial port to
+ * flush its output.  65535 means don't wait at all.
+ */
+#define S_CLOSING_WAIT_INF	0
+#define S_CLOSING_WAIT_NONE	65535
+
+/*
+ * Definitions for S_struct (and serial_struct) flags field
+ */
+#define S_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes 
+				   on the callout port */
+#define S_FOURPORT  0x0002	/* Set OU1, OUT2 per AST Fourport settings */
+#define S_SAK	0x0004	/* Secure Attention Key (Orange book) */
+#define S_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
+
+#define S_SPD_MASK	0x0030
+#define S_SPD_HI	0x0010	/* Use 56000 instead of 38400 bps */
+
+#define S_SPD_VHI	0x0020  /* Use 115200 instead of 38400 bps */
+#define S_SPD_CUST	0x0030  /* Use user-specified divisor */
+
+#define S_SKIP_TEST	0x0040 /* Skip UART test during autoconfiguration */
+#define S_AUTO_IRQ  0x0080 /* Do automatic IRQ during autoconfiguration */
+#define S_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
+#define S_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
+#define S_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
+
+#define S_FLAGS	0x0FFF	/* Possible legal S flags */
+#define S_USR_MASK 0x0430	/* Legal flags that non-privileged
+				 * users can set or reset */
+
+/* Internal flags used only by kernel/chr_drv/serial.c */
+#define S_INITIALIZED	0x80000000 /* Serial port was initialized */
+#define S_CALLOUT_ACTIVE	0x40000000 /* Call out device is active */
+#define S_NORMAL_ACTIVE	0x20000000 /* Normal device is active */
+#define S_BOOT_AUTOCONF	0x10000000 /* Autoconfigure port on bootup */
+#define S_CLOSING		0x08000000 /* Serial port is closing */
+#define S_CTS_FLOW		0x04000000 /* Do CTS flow control */
+#define S_CHECK_CD		0x02000000 /* i.e., CLOCAL */
+
+#define RS_EVENT_WRITE_WAKEUP   0
+#define SERIAL_MAGIC 0x5301
+
+/* Software state per channel */
+
+/*
+ * This is our internal structure for each serial port's state.
+ * 
+ * Many fields are paralleled by the structure used by the serial_struct
+ * structure.
+ *
+ * For definitions of the flags field, see tty.h
+ */
+
+struct atmel_serial {
+	char soft_carrier;  /* Use soft carrier on this channel */
+	char break_abort;   /* Is serial console in, so process brk/abrt */
+#if 0
+	char cons_keyb;     /* Channel runs the keyboard */
+	char cons_mouse;    /* Channel runs the mouse */
+	char kgdb_channel;  /* Kgdb is running on this channel */
+#endif
+	char is_cons;       /* Is this our console. */
+
+	/* We need to know the current clock divisor
+	 * to read the bps rate the chip has currently
+	 * loaded.
+	 */
+	unsigned char clk_divisor;  /* May be 1, 16, 32, or 64 */
+	int baud;
+	int			magic;
+	int			baud_base;
+	int			port;
+	int			irq;
+	int			irqmask;
+	int			flags; 		/* defined in tty.h */
+	int			type; 		/* UART type */
+	int			use_ints;
+	volatile struct atmel_usart_regs	*usart;
+	int			cts_state;
+	struct tty_struct 	*tty;
+	int			read_status_mask;
+	int			ignore_status_mask;
+	int			timeout;
+	int			xmit_fifo_size;
+	int			custom_divisor;
+	int			x_char;	/* xon/xoff character */
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int			count;	    /* # of fd on device */
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+	unsigned char 		*xmit_buf;
+	unsigned char 		*rx_buf;
+	int			xmit_head;
+	int			xmit_tail;
+	int			xmit_cnt;
+	struct tq_struct	tqueue;
+	struct tq_struct	tqueue_hangup;
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+};
+
+#endif /* !(_MC683XX_SERIAL_H) */
diff -urN linux-2.4.29/drivers/char/serial.c linux-2.4.29-uc1/drivers/char/serial.c
--- linux-2.4.29/drivers/char/serial.c	2005-01-19 14:09:50.000000000 +0000
+++ linux-2.4.29-uc1/drivers/char/serial.c	2005-06-14 02:12:17.000000000 +0100
@@ -62,6 +62,12 @@
  *        Robert Schwebel <robert@schwebel.de>,
  *        Juergen Beisert <jbeisert@eurodsn.de>,
  *        Theodore Ts'o <tytso@mit.edu>
+ *
+ *  9/02: Add support for IXP425 uart chip. Intel Corporation.
+ *	  <support@jungo.com>
+ *
+ * 04/03: Add ColdFire support, based on previous work by Andrea Tarani.
+ *	  Bernardo Innocenti <bernie@develer.com>
  */
 
 static char *serial_version = "5.05c";
@@ -222,6 +228,14 @@
 #ifdef CONFIG_MAGIC_SYSRQ
 #include <linux/sysrq.h>
 #endif
+#ifdef CONFIG_LEDMAN
+#include <linux/ledman.h>
+#endif
+#ifdef CONFIG_COLDFIRE
+#include <asm/coldfire.h>
+#include <asm/mcfpci.h>
+#include <asm/mcfsim.h>
+#endif
 
 /*
  * All of the compatibilty code so we can compile serial.c against
@@ -266,6 +280,13 @@
 /* number of characters left in xmit buffer before we ask for more */
 #define WAKEUP_CHARS 256
 
+#ifdef CONFIG_COLDFIRE
+#undef	TTY_MAJOR
+#define	TTY_MAJOR	24
+#undef	TTYAUX_MAJOR
+#define	TTYAUX_MAJOR	25
+#endif
+
 /*
  * IRQ_timeout		- How long the timeout should be for each IRQ
  * 				should be after the IRQ has been active.
@@ -311,6 +332,7 @@
 	{ "XR16850", 128, UART_CLEAR_FIFO | UART_USE_FIFO |
 		  UART_STARTECH },
 	{ "RSA", 2048, UART_CLEAR_FIFO | UART_USE_FIFO }, 
+	{ "XScale UART", 64, UART_CLEAR_FIFO | UART_USE_FIFO },
 	{ 0, 0}
 };
 
@@ -391,6 +413,59 @@
 static struct semaphore tmp_buf_sem = MUTEX;
 #endif
 
+#if defined(CONFIG_LEDMAN) && defined(CONFIG_MACH_CM4008)
+/*
+ *	We have 8 serial ports on the CM4008 and we want to have each
+ *	represented by 1 front panel LED for its activity. To keep it
+ *	simple I am going to borrow some otherwise unused bits from the
+ *	LEDMAN bit definitions to cover all ports.
+ */
+int ledman_serialmap[8] = {
+	LEDMAN_COM1_RX, LEDMAN_COM1_TX, LEDMAN_COM2_RX, LEDMAN_COM2_TX,
+	LEDMAN_USB1_RX, LEDMAN_USB1_TX, LEDMAN_USB2_RX, LEDMAN_USB2_TX,
+};
+#endif
+
+#if defined(CONFIG_ARCH_SE4000) || defined(CONFIG_MACH_ESS710) || \
+    defined(CONFIG_MACH_SG560) || defined(CONFIG_MACH_SG580) || \
+    defined(CONFIG_MACH_MONTEJADE) || defined(CONFIG_MACH_SG565)
+/*
+ *	The XSCALE/IXP425 does not wire out the DCD and DTR lines.
+ *	We implement them using GPIO lines on the SnapGear boards.
+ */
+#define	CONFIG_IXP425_DTR0	IXP425_GPIO_PIN_0
+#define	CONFIG_IXP425_DCD0	IXP425_GPIO_PIN_1
+#endif /* CONFIG_ARCH_SE4000 || CONFIG_MACH_ESS710 || CONFIG_MACH_MONTEJADE || CONFIG_MACH_SG560 || CONFIG_MACH_SG580 */
+
+#ifdef CONFIG_COLDFIRE
+static inline void mcf_reset_irq(int irq)
+{
+	volatile unsigned long *icrp;
+
+	irq -= 65;
+	if (irq < 0 || irq >= 32)
+		return;
+
+	icrp = (volatile unsigned long *)(MCF_MBAR + MCFSIM_ICR1) + (irq >> 3);
+	*icrp = (*icrp & 0x77777777) | (0x80000000 >> ((irq & 7) << 2));
+}
+static inline void mcf_manage_sim(int irq, int pri)
+{
+	volatile unsigned long *icrp;
+
+	irq -= 65;
+	if(irq < 0 || irq >= 32)
+		return;
+
+	icrp = (volatile unsigned long *)(MCF_MBAR + MCFSIM_ICR1) + irq / 8;
+	irq = (7 - (irq % 8)) * 4;
+
+	*icrp = (*icrp & ((7 << irq) ^ 0x77777777)) | ((8 + pri) << irq);
+}
+#else /* !CONFIG_COLDFIRE */
+# define mcf_reset_irq(irq) do {} while(0)
+# define mcf_manage_sim(irq,pri) do {} while(0)
+#endif /* !CONFIG_COLDFIRE */
 
 static inline int serial_paranoia_check(struct async_struct *info,
 					kdev_t device, const char *routine)
@@ -424,8 +499,16 @@
 	case SERIAL_IO_MEM:
 		return readb((unsigned long) info->iomem_base +
 			     (offset<<info->iomem_reg_shift));
+#ifdef CONFIG_SERIAL_GSC
+	case SERIAL_IO_GSC:
+		return gsc_readb(info->iomem_base + offset);
+#endif
 	default:
+#ifdef CONFIG_SERIAL_TA7
+		return inb(info->port + (offset*4));
+#else
 		return inb(info->port + offset);
+#endif
 	}
 }
 
@@ -443,8 +526,17 @@
 		writeb(value, (unsigned long) info->iomem_base +
 			      (offset<<info->iomem_reg_shift));
 		break;
+#ifdef CONFIG_SERIAL_GSC
+	case SERIAL_IO_GSC:
+		gsc_writeb(value, info->iomem_base + offset);
+		break;
+#endif
 	default:
+#ifdef CONFIG_SERIAL_TA7
+		outb(value, info->port+(offset*4));
+#else
 		outb(value, info->port+offset);
+#endif
 	}
 }
 
@@ -457,6 +549,43 @@
 #define serial_inp(info, offset)		serial_in(info, offset)
 #define serial_outp(info, offset, value)	serial_out(info, offset, value)
 
+/*
+ * Set and get modem control signals.
+ */
+void serial_outMCR(struct async_struct *info, unsigned int mcr)
+{
+	serial_outp(info, UART_MCR, mcr);
+
+#ifdef CONFIG_IXP425_DTR0
+	if (info->port == 0) {
+		if (mcr & UART_MCR_DTR)
+			gpio_line_set(CONFIG_IXP425_DTR0, 0);
+		else
+			gpio_line_set(CONFIG_IXP425_DTR0, 1);
+	}
+#endif
+}
+
+unsigned int serial_inMSR(struct async_struct *info)
+{
+	unsigned int msr;
+
+	msr = serial_in(info, UART_MSR);
+
+#ifdef CONFIG_IXP425_DCD0
+	if (info->port == 0) {
+		int val;
+		gpio_line_get(CONFIG_IXP425_DCD0, &val);
+		if (val)
+			msr &= ~UART_MSR_DCD;
+		else
+			msr |= UART_MSR_DCD;
+		msr &= ~ UART_MSR_RI;
+	}
+#endif
+
+	return msr;
+}
 
 /*
  * For the 16C950
@@ -569,6 +698,15 @@
 	struct	async_icount *icount;
 	int	max_count = 256;
 
+#ifdef CONFIG_LEDMAN
+#ifdef CONFIG_MACH_CM4008
+	ledman_cmd(LEDMAN_CMD_SET, ledman_serialmap[info->line & 0x7]);
+#else
+	ledman_cmd(LEDMAN_CMD_SET,
+		(info->line == 0) ? LEDMAN_COM1_RX : LEDMAN_COM2_RX);
+#endif
+#endif
+
 	icount = &info->state->icount;
 	do {
 		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
@@ -708,8 +846,18 @@
 		serial_out(info, UART_IER, info->IER);
 		return;
 	}
+
+#ifdef CONFIG_LEDMAN
+#ifdef CONFIG_MACH_CM4008
+	ledman_cmd(LEDMAN_CMD_SET, ledman_serialmap[info->line & 0x7]);
+#else
+	ledman_cmd(LEDMAN_CMD_SET,
+		(info->line == 0) ? LEDMAN_COM1_TX : LEDMAN_COM2_TX);
+#endif
+#endif
 	
 	count = info->xmit_fifo_size;
+
 	do {
 		serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]);
 		info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
@@ -740,7 +888,7 @@
 	int	status;
 	struct	async_icount *icount;
 	
-	status = serial_in(info, UART_MSR);
+	status = serial_inMSR(info);
 
 	if (status & UART_MSR_ANY_DELTA) {
 		icount = &info->state->icount;
@@ -876,6 +1024,9 @@
 			continue;
 		}
 	} while (end_mark != info);
+
+	mcf_reset_irq(irq);
+
 #ifdef CONFIG_SERIAL_MULTIPORT	
 	if (multi->port_monitor)
 		printk("rs port monitor (normal) irq %d: 0x%x, 0x%x\n",
@@ -946,6 +1097,9 @@
 #endif
 	} while ((iir & UART_IIR_NO_INT) == 0);
 	info->last_active = jiffies;
+
+	mcf_reset_irq(irq);
+	
 #ifdef CONFIG_SERIAL_MULTIPORT	
 	if (multi->port_monitor)
 		printk("rs port monitor (single) irq %d: 0x%x, 0x%x\n",
@@ -957,6 +1111,58 @@
 #endif
 }
 
+#ifdef CONFIG_IXP425_DCD0
+/*
+ * Interrupt routine for DCD GPIO input.
+ */
+static void rs_interrupt_dcd(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct async_struct *info;
+	struct async_icount *icount;
+	int status;
+
+#ifdef SERIAL_DEBUG_INTR
+	printk("rs_interrupt_dcd(%d)...\n", irq);
+#endif
+
+	info = IRQ_ports[irq];
+	if (!info || !info->tty)
+		return;
+
+	gpio_line_isr_clear(CONFIG_IXP425_DCD0);
+	status = serial_inMSR(info);
+
+	icount = &info->state->icount;
+	/* update input line counters */
+	if (status & UART_MSR_DDCD) {
+		icount->dcd++;
+#ifdef CONFIG_HARD_PPS
+		if ((info->flags & ASYNC_HARDPPS_CD) &&
+		    (status & UART_MSR_DCD))
+			hardpps();
+#endif
+	}
+	wake_up_interruptible(&info->delta_msr_wait);
+
+	if (info->flags & ASYNC_CHECK_CD) {
+#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
+		printk("ttys%d CD now %s...", info->line,
+		       (status & UART_MSR_DCD) ? "on" : "off");
+#endif		
+		if (status & UART_MSR_DCD)
+			wake_up_interruptible(&info->open_wait);
+		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+			   (info->flags & ASYNC_CALLOUT_NOHUP))) {
+#ifdef SERIAL_DEBUG_OPEN
+			printk("doing serial hangup...");
+#endif
+			if (info->tty)
+				tty_hangup(info->tty);
+		}
+	}
+}
+#endif /* CONFIG_IXP425_DCD0 */
+
 #ifdef CONFIG_SERIAL_MULTIPORT	
 /*
  * This is the serial driver's for multiport boards
@@ -1039,6 +1245,9 @@
 			continue;
 		break;
 	} 
+
+	mcf_reset_irq(irq);
+
 #ifdef SERIAL_DEBUG_INTR
 	printk("end.\n");
 #endif
@@ -1333,7 +1542,7 @@
 	(void) serial_inp(info, UART_LSR);
 	(void) serial_inp(info, UART_RX);
 	(void) serial_inp(info, UART_IIR);
-	(void) serial_inp(info, UART_MSR);
+	(void) serial_inMSR(info);
 
 	/*
 	 * At this point there's no way the LSR could still be 0xFF;
@@ -1372,8 +1581,14 @@
 		} else 
 			handler = rs_interrupt_single;
 
+#if defined(CONFIG_HYPERSTONE)
+		retval = request_irq(state->irq, handler, SA_INTERRUPT,
+				     "serial", &IRQ_ports[state->irq]);
+#else
 		retval = request_irq(state->irq, handler, SA_SHIRQ,
 				     "serial", &IRQ_ports[state->irq]);
+#endif
+
 		if (retval) {
 			if (capable(CAP_SYS_ADMIN)) {
 				if (info->tty)
@@ -1383,6 +1598,17 @@
 			}
 			goto errout;
 		}
+#ifdef CONFIG_COLDFIRE
+		else if(handler == rs_interrupt_single)
+			mcf_manage_sim(state->irq, CDB4_COM_IRQPRI);
+#endif /* CONFIG_COLDFIRE */
+#ifdef CONFIG_IXP425_DCD0
+		if (info->port == 0) {
+			IRQ_ports[7] = info;
+			request_irq(7, rs_interrupt_dcd, SA_SHIRQ, 
+				"serial(DCD)", &IRQ_ports[7]);
+		}
+#endif /* CONFIG_IXP425_DCD0 */
 	}
 
 	/*
@@ -1414,12 +1640,14 @@
 			info->MCR |= UART_MCR_OUT2;
 	}
 	info->MCR |= ALPHA_KLUDGE_MCR; 		/* Don't ask */
-	serial_outp(info, UART_MCR, info->MCR);
+	serial_outMCR(info, info->MCR);
 	
 	/*
 	 * Finally, enable interrupts
 	 */
 	info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
+	if (state->type == PORT_XSCALE)
+		info->IER |= UART_IER_UUE | UART_IER_RTOIE;
 	serial_outp(info, UART_IER, info->IER);	/* enable interrupts */
 	
 #ifdef CONFIG_SERIAL_MANY_PORTS
@@ -1437,7 +1665,7 @@
 	(void)serial_inp(info, UART_LSR);
 	(void)serial_inp(info, UART_RX);
 	(void)serial_inp(info, UART_IIR);
-	(void)serial_inp(info, UART_MSR);
+	(void)serial_inMSR(info);
 
 	if (info->tty)
 		clear_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -1524,9 +1752,15 @@
 			  !IRQ_ports[state->irq]->next_port)) {
 		if (IRQ_ports[state->irq]) {
 			free_irq(state->irq, &IRQ_ports[state->irq]);
+#if defined(CONFIG_HYPERSTONE)
+			retval = request_irq(state->irq, rs_interrupt_single,
+					     SA_INTERRUPT, "serial",
+					     &IRQ_ports[state->irq]);
+#else
 			retval = request_irq(state->irq, rs_interrupt_single,
 					     SA_SHIRQ, "serial",
 					     &IRQ_ports[state->irq]);
+#endif
 			
 			if (retval)
 				printk("serial shutdown: request_irq: error %d"
@@ -1534,6 +1768,12 @@
 		} else
 			free_irq(state->irq, &IRQ_ports[state->irq]);
 	}
+#ifdef CONFIG_IXP425_DCD0
+	if (info->port == 0) {
+		free_irq(7, &IRQ_ports[7]);
+		IRQ_ports[7] = NULL;
+	}
+#endif /* CONFIG_IXP425_DCD0 */
 
 	if (info->xmit.buf) {
 		unsigned long pg = (unsigned long) info->xmit.buf;
@@ -1558,7 +1798,7 @@
 	
 	if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
 		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
-	serial_outp(info, UART_MCR, info->MCR);
+	serial_outMCR(info, info->MCR);
 
 	/* disable FIFO's */	
 	serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
@@ -1704,7 +1944,11 @@
 			/* Special case since 134 is really 134.5 */
 			quot = (2*baud_base / 269);
 		else if (baud)
+#ifdef CONFIG_SERIAL_TA7
+			quot =baudrate_div(baud);
+#else
 			quot = baud_base / baud;
+#endif
 	}
 	/* If the quotient is zero refuse the change */
 	if (!quot && old_termios) {
@@ -2028,7 +2272,7 @@
 		info->MCR &= ~UART_MCR_RTS;
 
 	save_flags(flags); cli();
-	serial_out(info, UART_MCR, info->MCR);
+	serial_outMCR(info, info->MCR);
 	restore_flags(flags);
 }
 
@@ -2055,7 +2299,7 @@
 	if (tty->termios->c_cflag & CRTSCTS)
 		info->MCR |= UART_MCR_RTS;
 	save_flags(flags); cli();
-	serial_out(info, UART_MCR, info->MCR);
+	serial_outMCR(info, info->MCR);
 	restore_flags(flags);
 }
 
@@ -2210,7 +2454,11 @@
 				       16, "serial_rsa(set)");
 		else
 #endif
+#ifdef CONFIG_ARCH_TA7
+			request_region(info->port,(8*4),"serial(auto)");
+#else
 			request_region(state->port,8,"serial(set)");
+#endif
 	}
 
 	
@@ -2286,7 +2534,7 @@
 
 	control = info->MCR;
 	save_flags(flags); cli();
-	status = serial_in(info, UART_MSR);
+	status = serial_inMSR(info);
 	restore_flags(flags);
 	result =  ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
 		| ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
@@ -2363,7 +2611,7 @@
 	}
 	save_flags(flags); cli();
 	info->MCR |= ALPHA_KLUDGE_MCR; 		/* Don't ask */
-	serial_out(info, UART_MCR, info->MCR);
+	serial_outMCR(info, info->MCR);
 	restore_flags(flags);
 	return 0;
 }
@@ -2536,9 +2784,14 @@
 			handler = rs_interrupt_multi;
 		else
 			handler = rs_interrupt;
-
+#if defined(CONFIG_HYPERSTONE)
+		retval = request_irq(state->irq, handler, SA_INTERRUPT,
+				     "serial", &IRQ_ports[state->irq]);
+#else
 		retval = request_irq(state->irq, handler, SA_SHIRQ,
 				     "serial", &IRQ_ports[state->irq]);
+#endif
+
 		if (retval) {
 			printk("Couldn't reallocate serial interrupt "
 			       "driver!!\n");
@@ -2732,7 +2985,7 @@
 	    !(cflag & CBAUD)) {
 		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
 		save_flags(flags); cli();
-		serial_out(info, UART_MCR, info->MCR);
+		serial_outMCR(info, info->MCR);
 		restore_flags(flags);
 	}
 	
@@ -2745,7 +2998,7 @@
 			info->MCR |= UART_MCR_RTS;
 		}
 		save_flags(flags); cli();
-		serial_out(info, UART_MCR, info->MCR);
+		serial_outMCR(info, info->MCR);
 		restore_flags(flags);
 	}
 	
@@ -3060,7 +3313,7 @@
 		save_flags(flags); cli();
 		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
 		    (tty->termios->c_cflag & CBAUD))
-			serial_out(info, UART_MCR,
+			serial_outMCR(info,
 				   serial_inp(info, UART_MCR) |
 				   (UART_MCR_DTR | UART_MCR_RTS));
 		restore_flags(flags);
@@ -3079,7 +3332,7 @@
 		}
 		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
 		    !(info->flags & ASYNC_CLOSING) &&
-		    (do_clocal || (serial_in(info, UART_MSR) &
+		    (do_clocal || (serial_inMSR(info) &
 				   UART_MSR_DCD)))
 			break;
 		if (signal_pending(current)) {
@@ -3295,7 +3548,7 @@
 		info->tty = 0;
 	}
 	save_flags(flags); cli();
-	status = serial_in(info, UART_MSR);
+	status = serial_inMSR(info);
 	control = info != &scr_info ? info->MCR : serial_in(info, UART_MCR);
 	restore_flags(flags); 
 
@@ -3467,28 +3720,28 @@
 	probe_irq_off(probe_irq_on());
 	save_mcr = serial_inp(&scr_info, UART_MCR);
 	save_ier = serial_inp(&scr_info, UART_IER);
-	serial_outp(&scr_info, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
+	serial_outMCR(&scr_info, UART_MCR_OUT1 | UART_MCR_OUT2);
 	
 	irqs = probe_irq_on();
-	serial_outp(&scr_info, UART_MCR, 0);
+	serial_outMCR(&scr_info, 0);
 	udelay (10);
 	if (state->flags & ASYNC_FOURPORT)  {
-		serial_outp(&scr_info, UART_MCR,
+		serial_outMCR(&scr_info,
 			    UART_MCR_DTR | UART_MCR_RTS);
 	} else {
-		serial_outp(&scr_info, UART_MCR,
+		serial_outMCR(&scr_info,
 			    UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
 	}
 	serial_outp(&scr_info, UART_IER, 0x0f);	/* enable all intrs */
 	(void)serial_inp(&scr_info, UART_LSR);
 	(void)serial_inp(&scr_info, UART_RX);
 	(void)serial_inp(&scr_info, UART_IIR);
-	(void)serial_inp(&scr_info, UART_MSR);
+	(void)serial_inMSR(&scr_info);
 	serial_outp(&scr_info, UART_TX, 0xFF);
 	udelay (20);
 	irq = probe_irq_off(irqs);
 
-	serial_outp(&scr_info, UART_MCR, save_mcr);
+	serial_outMCR(&scr_info, save_mcr);
 	serial_outp(&scr_info, UART_IER, save_ier);
 #ifdef CONFIG_SERIAL_MANY_PORTS
 	if (state->flags & ASYNC_FOURPORT)
@@ -3510,7 +3763,7 @@
 	old_mcr = serial_inp(info, UART_MCR);
 	serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO |
 		    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
-	serial_outp(info, UART_MCR, UART_MCR_LOOP);
+	serial_outMCR(info, UART_MCR_LOOP);
 	serial_outp(info, UART_LCR, UART_LCR_DLAB);
 	old_dll = serial_inp(info, UART_DLL);
 	old_dlm = serial_inp(info, UART_DLM);
@@ -3524,7 +3777,7 @@
 	     (count < 256); count++)
 		serial_inp(info, UART_RX);
 	serial_outp(info, UART_FCR, old_fcr);
-	serial_outp(info, UART_MCR, old_mcr);
+	serial_outMCR(info, old_mcr);
 	serial_outp(info, UART_LCR, UART_LCR_DLAB);
 	serial_outp(info, UART_DLL, old_dll);
 	serial_outp(info, UART_DLM, old_dlm);
@@ -3716,9 +3969,9 @@
 	 * that conflicts with COM 1-4 --- we hope!
 	 */
 	if (!(state->flags & ASYNC_SKIP_TEST)) {
-		serial_outp(info, UART_MCR, UART_MCR_LOOP | 0x0A);
-		status1 = serial_inp(info, UART_MSR) & 0xF0;
-		serial_outp(info, UART_MCR, save_mcr);
+		serial_outMCR(info, UART_MCR_LOOP | 0x0A);
+		status1 = serial_inMSR(info) & 0xF0;
+		serial_outMCR(info, save_mcr);
 		if (status1 != 0x90) {
 #ifdef SERIAL_DEBUG_AUTOCONF
 			printk("serial: ttyS%d: no UART loopback failed\n",
@@ -3844,7 +4097,7 @@
 	if (state->type == PORT_RSA)
 		serial_outp(info, UART_RSA_FRR, 0);
 #endif
-	serial_outp(info, UART_MCR, save_mcr);
+	serial_outMCR(info, save_mcr);
 	serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
 				     UART_FCR_CLEAR_RCVR |
 				     UART_FCR_CLEAR_XMIT));
@@ -3853,6 +4106,11 @@
 	serial_outp(info, UART_IER, 0);
 	
 	restore_flags(flags);
+
+#ifdef CONFIG_SERIAL_CDB4
+	printk("serial: activating INTM workaround for CDB4 on ttyS%d\n", state->line);
+	serial_outMCR(info, save_mcr | UART_MCR_OUT2);
+#endif /* CONFIG_SERIAL_CDB4 */
 }
 
 int register_serial(struct serial_struct *req);
@@ -4388,6 +4646,8 @@
 	pbn_computone_4,
 	pbn_computone_6,
 	pbn_computone_8,
+
+	pbn_exar_17c158,
 };
 
 static struct pci_board pci_boards[] __devinitdata = {
@@ -4496,6 +4756,9 @@
 		0x40, 2, NULL, 0x200 },
 	{ SPCI_FL_BASE0, 8, 921600, /* IOMEM */		   /* pbn_computone_8 */
 		0x40, 2, NULL, 0x200 },
+
+	{ SPCI_FL_BASE0, 8, 921600,			   /* pbn_exar_17c158 */
+		0x200, 0, NULL, 0 },
 };
 
 /*
@@ -4799,6 +5062,15 @@
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_850,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig10x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_1 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_1 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_1 },
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_550,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig10x_2 },
@@ -4808,6 +5080,15 @@
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_850,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig10x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_2 },
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_550,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig10x_4 },
@@ -4826,6 +5107,24 @@
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_850,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_550,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig20x_2 },
@@ -4835,6 +5134,15 @@
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_850,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig20x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_2 },
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_550,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig20x_4 },
@@ -4939,6 +5247,11 @@
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_dci_pccom8 },
 
+	/* Exar Corp. XR17C158 Octal UART */
+	{	0x13a8, 0x0158,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_exar_17c158 },
+
        { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
 	 PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xffff00, },
        { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -5403,6 +5716,16 @@
 
 #endif /* ENABLE_SERIAL_PNP */
 
+#ifdef CONFIG_IXP425_DTR0
+static void __init rs_ixp425gpio(void)
+{
+	gpio_line_config(CONFIG_IXP425_DTR0, IXP425_GPIO_OUT);
+	gpio_line_config(CONFIG_IXP425_DCD0,
+		(IXP425_GPIO_IN|IXP425_GPIO_TRANSITIONAL));
+	gpio_line_isr_clear(CONFIG_IXP425_DCD0);
+}
+#endif
+
 /*
  * The serial driver boot-time initialization code!
  */
@@ -5438,6 +5761,20 @@
 #endif
 	show_serial_version();
 
+#ifdef CONFIG_SERIAL_CDB4
+	printk("serial: Resetting CDB4 UART\n");
+	*((volatile uint16_t *)(MCF_MBAR + MCFSIM_PADDR)) |= (1<<CDB4_COM_RESET_BIT);
+	*((volatile uint16_t *)(MCF_MBAR + MCFSIM_PADAT)) |= (1<<CDB4_COM_RESET_BIT);
+	udelay(1); /* Hold reset for at least 1000ns */
+	*((volatile uint16_t *)(MCF_MBAR + MCFSIM_PADAT)) &= ~(1<<CDB4_COM_RESET_BIT);
+#endif
+#ifdef CONFIG_IXP425_DTR0
+	rs_ixp425gpio();
+#endif
+#ifdef CONFIG_ARCH_IPOD
+	ipod_serial_init();
+#endif
+
 	/* Initialize the tty_driver structure */
 	
 	memset(&serial_driver, 0, sizeof(struct tty_driver));
@@ -5457,8 +5794,13 @@
 	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
 	serial_driver.subtype = SERIAL_TYPE_NORMAL;
 	serial_driver.init_termios = tty_std_termios;
+#ifdef CONFIG_SERIAL_TA7
+	serial_driver.init_termios.c_cflag =
+		B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+#else
 	serial_driver.init_termios.c_cflag =
 		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+#endif
 	serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
 	serial_driver.refcount = &serial_refcount;
 	serial_driver.table = serial_table;
@@ -5514,7 +5856,6 @@
 	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
 		state->magic = SSTATE_MAGIC;
 		state->line = i;
-		state->type = PORT_UNKNOWN;
 		state->custom_divisor = 0;
 		state->close_delay = 5*HZ/10;
 		state->closing_wait = 30*HZ;
@@ -5528,14 +5869,18 @@
 		state->irq = irq_cannonicalize(state->irq);
 		if (state->hub6)
 			state->io_type = SERIAL_IO_HUB6;
-		if (state->port && check_region(state->port,8))
+		if (state->port && check_region(state->port,8)) {
+			state->type = PORT_UNKNOWN;
 			continue;
+		}
 #ifdef CONFIG_MCA			
 		if ((state->flags & ASYNC_BOOT_ONLYMCA) && !MCA_bus)
 			continue;
 #endif			
-		if (state->flags & ASYNC_BOOT_AUTOCONF)
+		if (state->flags & ASYNC_BOOT_AUTOCONF) {
+			state->type = PORT_UNKNOWN;
 			autoconfig(state);
+		}
 	}
 	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
 		if (state->type == PORT_UNKNOWN)
@@ -5567,8 +5912,9 @@
 	probe_serial_pci();
 #endif
 #ifdef ENABLE_SERIAL_PNP
-       probe_serial_pnp();
+	probe_serial_pnp();
 #endif
+
 	return 0;
 }
 
@@ -5832,7 +6178,7 @@
 	if (info->flags & ASYNC_CONS_FLOW) {
 		tmout = 1000000;
 		while (--tmout &&
-		       ((serial_in(info, UART_MSR) & UART_MSR_CTS) == 0));
+		       ((serial_inMSR(info) & UART_MSR_CTS) == 0));
 	}	
 }
 
@@ -5854,7 +6200,10 @@
 	 *	First save the IER then disable the interrupts
 	 */
 	ier = serial_in(info, UART_IER);
-	serial_out(info, UART_IER, 0x00);
+	if (info->state->type == PORT_XSCALE)
+		serial_out(info, UART_IER, UART_IER_UUE);
+	else
+		serial_out(info, UART_IER, 0);
 
 	/*
 	 *	Now, do each character
@@ -5897,7 +6246,11 @@
 	static struct async_struct *info;
 	struct serial_state *state;
 	unsigned cval;
+#ifdef CONFIG_SERIAL_TA7
+	int	baud = 115200;
+#else
 	int	baud = 9600;
+#endif
 	int	bits = 8;
 	int	parity = 'n';
 	int	doflow = 0;
@@ -5985,7 +6338,11 @@
 	info->io_type = state->io_type;
 	info->iomem_base = state->iomem_base;
 	info->iomem_reg_shift = state->iomem_reg_shift;
+#ifdef CONFIG_SERIAL_TA7
+	quot =baudrate_div(baud);
+#else
 	quot = state->baud_base / baud;
+#endif
 	cval = cflag & (CSIZE | CSTOPB);
 #if defined(__powerpc__) || defined(__alpha__)
 	cval >>= 8;
@@ -6005,8 +6362,11 @@
 	serial_out(info, UART_DLL, quot & 0xff);	/* LS of divisor */
 	serial_out(info, UART_DLM, quot >> 8);		/* MS of divisor */
 	serial_out(info, UART_LCR, cval);		/* reset DLAB */
-	serial_out(info, UART_IER, 0);
-	serial_out(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
+	if (info->state->type == PORT_XSCALE)
+		serial_out(info, UART_IER, UART_IER_UUE);
+	else
+		serial_out(info, UART_IER, 0);
+	serial_outMCR(info, UART_MCR_DTR | UART_MCR_RTS);
 
 	/*
 	 *	If we read 0xff from the LSR, there is no UART here.
diff -urN linux-2.4.29/drivers/char/serial_c5471.c linux-2.4.29-uc1/drivers/char/serial_c5471.c
--- linux-2.4.29/drivers/char/serial_c5471.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_c5471.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,2821 @@
+/***********************************************************************
+ * linux/drivers/char/serial_c5471.c
+ *
+ *   Copyright (C) 2003 Cadenux, LLC. All rights reserved.
+ *   todd.fischer@cadenux.com  <www.cadenux.com>
+ *
+ *   Copyright (C) 2001 RidgeRun, Inc. All rights reserved.
+ *
+ *  This implementation was leveraged from the standard
+ *  serial.c Linux file.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/config.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+/* All of the compatibilty code so we can compile serial.c against
+ * older kernels is hidden in serial_compat.h
+ */
+
+#if defined(LOCAL_HEADERS) || (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */
+#include <linux/compatmac.h>
+#endif
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/segment.h>
+#include <asm/bitops.h>
+#include <asm/serial.h>
+#include <asm/arch/irqs.h>
+
+#define SERIAL_DEV_OFFSET	0
+
+#define SERIAL_TYPE_NORMAL      1
+#define SERIAL_TYPE_CALLOUT     2
+#define WAKEUP_CHARS          256
+#define SERIAL_PARANOIA_CHECK
+#define SERIAL_DO_RESTART
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#define DEFAULT_CONSOLE_BAUD   115200  /* 115,200 buad */
+#define DEFAULT_CONSOLE_BITS   8       /* 8 data bits */
+#define DEFAULT_CONSOLE_PARITY 'n'     /* No parity */
+
+#define USE_HW_FLOW_CONTROL 0
+#define COMPILER_BUG_WORK_AROUND 1
+
+/* #define DEBUG_ENABLED 1 */
+
+#if (defined(CONFIG_DEBUG_LL) && defined(DEBUG_ENABLED))
+
+/* printch and printhex8 are declared in
+ * linux/arch/armnommu/kernel/debug-armv.S\
+ */
+
+extern void printch(unsigned char ch);
+extern void printhex8(unsigned long val);
+
+# define CHECKPOINT(ch) printch(ch)
+# define SHOWVALUE(val) show_value(val)
+
+static void show_value(unsigned long val)
+{
+  printch('['); printhex8(val); printch(']');
+}
+
+#else
+# define CHECKPOINT(ch)
+# define SHOWVALUE(val)
+#endif
+
+/* IRQ_timeout - How long the timeout should be for each IRQ
+ * 		 should be after the IRQ has been active.
+ */
+
+static c5471_async_t *IRQ_ports[NR_IRQS];
+static int IRQ_timeout[NR_IRQS];
+
+DECLARE_TASK_QUEUE(tq_serial);
+struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+/* Serial Console Driver */
+
+#ifdef CONFIG_SERIAL_C5471_CONSOLE
+
+/* This block is enabled when the user has used `make xconfig`
+ * to enable kernel printk() to come out the serial port.
+ * The register_console(serial_console_print) call below
+ * is what hooks in our serial output routine here with the
+ * kernel's printk output.
+ */
+
+#include <linux/console.h>
+
+static c5471_async_t async_sercons;
+
+static void serial_console_write(struct console *co, const char *s,
+				 unsigned count);
+static kdev_t serial_console_device(struct console *co);
+static int serial_console_setup(struct console *co, char *options) __init;
+
+static struct console sercons =
+{
+  name:		"ttyS",
+  write:	serial_console_write,
+  device:	serial_console_device,
+  setup:	serial_console_setup,
+  flags:	CON_PRINTBUFFER,
+  index:	-1,
+};
+
+#endif /* CONFIG_SERIAL_C5471_CONSOLE */
+
+static void autoconfig(c5471_serial_state_t *state);
+static void change_speed(c5471_async_t *info, struct termios *old);
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
+static void serial_io_delay(int milliseconds);
+
+/* tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the memcpy_fromfs blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+
+static unsigned char *tmp_buf = 0;
+#ifdef DECLARE_MUTEX
+static DECLARE_MUTEX(tmp_buf_sem);
+#else
+static struct semaphore tmp_buf_sem = MUTEX;
+#endif
+
+#ifdef CONFIG_ARCH_VC547X
+/*-------------------------------------------------------------------------
+ *       -- Begin; Platform Specifics --
+ *   Note: These definitions and routines will
+ *         surely need to change if porting this
+ *         driver to another platform.
+ *-------------------------------------------------------------------------*/
+
+c5471_serial_state_t rs_table[RS_TABLE_SIZE] =
+{
+  SERIAL_PORT_DFNS        /* Defined in asm/serial.h */
+};
+
+#define NR_PORTS (sizeof(rs_table)/sizeof(c5471_async_t))
+
+static struct tty_struct *serial_table[NR_PORTS];
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
+static struct hw_reg_shadow hw_reg_shadow_table[NR_PORTS];
+
+static inline unsigned long serial_in(c5471_async_t *info,
+				      unsigned long offset)
+{
+  return inl(info->state->iomem_base + offset);
+}
+
+static inline void serial_out(c5471_async_t *info,
+                              unsigned long offset,
+                              unsigned long value)
+{
+  outl(value, info->state->iomem_base + offset);
+}
+
+static inline void serial_reset_chip(c5471_async_t *info)
+{
+  /* Both the IrDA and MODEM UARTs support RESET and UART mode. */
+
+  serial_out(info, UART_MDR_OFFS, MDR_RESET_MODE);
+  serial_io_delay(5);
+  serial_out(info, UART_MDR_OFFS, MDR_UART_MODE);
+  serial_io_delay(5);
+}
+
+static inline void serial_disable_tx_int(c5471_async_t *info)
+{
+  hw_reg_shadow_table[info->port].IER_cached &= ~UART_IER_XmitInt;
+  serial_out(info, UART_IER_OFFS, hw_reg_shadow_table[info->port].IER_cached);
+}
+
+static inline void serial_disable_rx_int(c5471_async_t *info)
+{
+  hw_reg_shadow_table[info->port].IER_cached &= ~UART_IER_RecvInt;
+  serial_out(info, UART_IER_OFFS, hw_reg_shadow_table[info->port].IER_cached);
+}
+
+static inline void serial_enable_tx_int(c5471_async_t *info)
+{
+  hw_reg_shadow_table[info->port].IER_cached |= UART_IER_XmitInt;
+  serial_out(info, UART_IER_OFFS, hw_reg_shadow_table[info->port].IER_cached);
+}
+
+static inline void serial_enable_rx_int(c5471_async_t *info)
+{
+  hw_reg_shadow_table[info->port].IER_cached |= UART_IER_RecvInt;
+  serial_out(info, UART_IER_OFFS, hw_reg_shadow_table[info->port].IER_cached);
+}
+
+static inline void serial_disable_ints(c5471_async_t *info, u16 *msr)
+{
+#ifdef COMPILER_BUG_WORK_AROUND
+  hw_reg_shadow_table[info->port].IER_cached &= ~UART_IER_AllInts;
+  *msr = inl( 0xffff1024 );
+  outl( 0x00000000, 0xffff1024 );
+#else
+  *msr = hw_reg_shadow_table[info->port].IER_cached & UART_IER_AllInts;
+  hw_reg_shadow_table[info->port].IER_cached &= ~UART_IER_AllInts;
+  serial_out(info, UART_IER_OFFS, hw_reg_shadow_table[info->port].IER_cached);
+#endif
+}
+
+static inline void serial_restore_ints(c5471_async_t *info, u16 msr)
+{
+#ifdef COMPILER_BUG_WORK_AROUND
+  hw_reg_shadow_table[info->port].IER_cached = msr;
+  outl( msr, 0xffff1024 );
+#else
+  hw_reg_shadow_table[info->port].IER_cached |= msr & (UART_IER_RecvInt|UART_IER_XmitInt);
+  serial_out(info, UART_IER_OFFS, hw_reg_shadow_table[info->port].IER_cached);
+#endif
+}
+
+static inline void serial_clear_fifos(c5471_async_t *info)
+{
+  serial_out(info, UART_EFR_OFFS,  0x0010);           /* Enable fifo control */
+  serial_out(info, UART_TFCR_OFFS, 0);                /* Reset to 0 */
+  serial_out(info, UART_RFCR_OFFS, UART_FCR_RX_CLR);  /* Clear RX fifo */
+  serial_out(info, UART_TFCR_OFFS, UART_FCR_TX_CLR);  /* Clear TX fifo */
+  serial_out(info, UART_TFCR_OFFS, UART_FCR_FIFO_EN); /* Enable RX/TX fifos */
+}
+
+/*  For the C5471 platform this paticular routine
+ *  failed to work correctly when made "inline".
+ */
+
+#define DONT_INLINE
+static DONT_INLINE void serial_disable_breaks(c5471_async_t *info)
+{
+  hw_reg_shadow_table[info->port].LCR_cached &= ~UART_LCR_BOC;
+  serial_out(info, UART_LCR_OFFS, hw_reg_shadow_table[info->port].LCR_cached);
+}
+
+static inline void serial_enable_breaks(c5471_async_t *info)
+{
+  hw_reg_shadow_table[info->port].LCR_cached |= UART_LCR_BOC;
+  serial_out(info, UART_LCR_OFFS, hw_reg_shadow_table[info->port].LCR_cached);
+}
+
+static inline void serial_set_rate(c5471_async_t *info,
+				   unsigned int rate)
+{
+  unsigned long div_bit_rate;
+
+  SHOWVALUE(rate);
+  SHOWVALUE(serial_in(info, UART_DIV_BIT_RATE_OFFS));
+
+  switch (rate)
+    {
+    case 115200:
+      div_bit_rate = BAUD_115200;
+      break;
+    case 57600:
+      div_bit_rate = BAUD_57600;
+      break;
+    case 38400:
+      div_bit_rate = BAUD_38400;
+      break;
+    case 19200:
+      div_bit_rate = BAUD_19200;
+      break;
+    case 4800:
+      div_bit_rate = BAUD_4800;
+      break;
+    case 2400:
+      div_bit_rate = BAUD_2400;
+      break;
+    case 1200:
+      div_bit_rate = BAUD_1200;
+      break;
+    case 9600:
+    default:
+      div_bit_rate = BAUD_9600;
+      break;
+    }
+  SHOWVALUE(div_bit_rate);
+
+  serial_out(info, UART_DIV_BIT_RATE_OFFS, div_bit_rate);
+}
+
+static inline void serial_set_mode(c5471_async_t *info, u16 mode)
+{
+  hw_reg_shadow_table[info->port].LCR_cached &= 0xffffffe0;          /* clear original field, and... */
+  hw_reg_shadow_table[info->port].LCR_cached |= (unsigned long)mode; /* Set new bits in that field. */
+  serial_out(info, UART_LCR_OFFS, hw_reg_shadow_table[info->port].LCR_cached);
+}
+
+static inline void serial_set_rx_trigger(c5471_async_t *info, u16 val)
+{
+  /* does val need to be shifted to the right spot? */
+  hw_reg_shadow_table[info->port].FCR_cached = (hw_reg_shadow_table[info->port].FCR_cached & 0xffffff3f) | (val & 0xc0);
+  serial_out(info, UART_RFCR_OFFS, hw_reg_shadow_table[info->port].FCR_cached);
+}
+
+static inline void serial_set_tx_trigger(c5471_async_t *info, u16 val)
+{
+  /* does val need to be shifted to the right spot? */
+  hw_reg_shadow_table[info->port].FCR_cached = (hw_reg_shadow_table[info->port].FCR_cached & 0xffffffcf) | (val & 0x30);
+  serial_out(info, UART_RFCR_OFFS, hw_reg_shadow_table[info->port].FCR_cached);
+}
+
+static inline void serial_char_out(c5471_async_t *info, u8 val)
+{
+  serial_out(info, UART_THR_OFFS, val);
+}
+
+static inline unsigned char serial_char_in(c5471_async_t *info,
+                                           unsigned short *status)
+{
+  unsigned long rhr;
+  unsigned long lsr;
+
+  /* Next, construct a 16bit status word that
+   * uses the high byte to hold the status bits
+   * associated with framing,parity,break and
+   * a low byte that holds error bits of LSR for
+   * conditions such as overflow, etc.
+   */
+
+  rhr = serial_in(info, UART_RHR_OFFS);
+  lsr = serial_in(info, UART_LSR_OFFS);
+
+  *status = (unsigned short)((rhr & 0x0000ff00) | (lsr & 0x000000ff));
+
+  return ((unsigned char)(rhr & 0x000000ff));
+}
+
+static inline int serial_some_error_condition_present(unsigned short status)
+{
+  return (status & 0x0782);
+}
+
+static inline int serial_parity_error_condition_present(unsigned short status)
+{
+  return (status & 0x0100);
+}
+
+static inline int serial_framing_error_condition_present(unsigned short status)
+{
+  return (status & 0x0200);
+}
+
+static inline int serial_overrun_error_condition_present(unsigned short status)
+{
+  return (status & 0x0002);
+}
+
+static inline unsigned long Get_INT_Cause_Bits(c5471_async_t *info)
+{
+  /* Note:
+   * This register is an autoclearing one. This means that
+   * if we only want to read the value once and then with
+   * the cached value do the various tests to see which of
+   * the interrupts are asserted. Don't want to re-read the
+   * register for each test since only the first read would
+   * be valid and rest would see the auto-cleared state.
+   */
+
+  return (serial_in(info, UART_ISR_OFFS) & 0x0000003f);
+}
+
+static inline int serial_xmit_INT_asserted(c5471_async_t *info,
+					   unsigned long Cause_Bits)
+{
+    return ((Cause_Bits & 0x00000002) == 0x00000002);
+}
+
+static inline int serial_recv_INT_asserted(c5471_async_t *info,
+					   unsigned long Cause_Bits)
+{
+    return ((Cause_Bits & 0x0000000c) == 0x00000004);
+  /*
+  if ((0x00000004 == Cause_Bits) | (0x00000006 == Cause_Bits))
+  {
+    return 1;
+  }
+  else
+  {
+    return 0;
+  }
+  */
+}
+
+static inline int serial_recvTimeout_INT_asserted(c5471_async_t *info,
+						  unsigned long Cause_Bits)
+{
+    return ((Cause_Bits & 0x0000000c) == 0x0000000c);
+
+  /*
+  if ((0x0000000c == Cause_Bits) | (0x0000000e == Cause_Bits))
+  {
+    return 1;
+  }
+  else
+  {
+    return 0;
+  }
+  */
+}
+
+static inline u8 serial_tx_fifo_is_empty(c5471_async_t *info)
+{
+  return ((serial_in(info, UART_LSR_OFFS) & UART_LSR_TREF) != 0);
+}
+
+static inline u8 serial_room_in_tx_fifo(c5471_async_t *info)
+{
+  /* return ((serial_in(info, UART_LSR_OFFS) & UART_LSR_TREF)); */
+  return ((serial_in(info, UART_SSR_OFFS) & UART_SSR_TXFULL) == 0);
+}
+
+static inline u8 serial_rx_fifo_has_content(c5471_async_t *info)
+{
+  return (serial_in(info, UART_LSR_OFFS) & UART_RX_FIFO_NOEMPTY);
+}
+
+#ifdef USE_HW_FLOW_CONTROL
+static inline void serial_enable_hw_flow_control(c5471_async_t *info)
+{
+  /* Set the FIFO level triggers for flow control
+   * Halt = 48 bytes, resume = 12 bytes
+   */
+
+  hw_reg_shadow_table[info->port].TCR_cached = (hw_reg_shadow_table[info->port].TCR_cached & 0xffffff00) | 0x0000003c;
+  serial_out(info, UART_TCR_OFFS, hw_reg_shadow_table[info->port].TCR_cached);
+
+  /* Enable RTS/CTS flow control */
+
+  hw_reg_shadow_table[info->port].EFR_cached |= 0x000000c0;
+  serial_out(info, UART_EFR_OFFS, hw_reg_shadow_table[info->port].EFR_cached);
+}
+
+static inline void serial_disable_hw_flow_control(c5471_async_t *info)
+{
+  /* Disable RTS/CTS flow control */
+
+  hw_reg_shadow_table[info->port].EFR_cached &= 0xffffff3f;
+  serial_out(info, UART_EFR_OFFS, hw_reg_shadow_table[info->port].EFR_cached);
+}
+#endif // USE_HW_FLOW_CONTROL
+
+static inline void serial_save_registers(c5471_async_t *info)
+{
+  hw_reg_shadow_table[info->port].IER_cached = serial_in(info, UART_IER_OFFS);
+  hw_reg_shadow_table[info->port].LCR_cached = serial_in(info, UART_LCR_OFFS);
+#ifdef USE_HW_FLOW_CONTROL
+  hw_reg_shadow_table[info->port].EFR_cached = serial_in(info, UART_EFR_OFFS);
+  hw_reg_shadow_table[info->port].TCR_cached = serial_in(info, UART_TCR_OFFS);
+#endif // USE_HW_FLOW_CONTROL
+}
+
+/*-------------------------------------------------------------------------
+ *       -- End; Platform Specifics --
+ *-------------------------------------------------------------------------*/
+
+#endif
+
+#define LOOPS_PER_MSEC 1250
+
+/* See io.h for description. */
+static void serial_io_delay(int milliseconds)
+{
+  volatile int i, j;
+  for (i = 0; i < milliseconds; i++) {
+    for (j = 0; j < LOOPS_PER_MSEC; j++) {
+    }
+  }
+}
+
+static inline int serial_paranoia_check(c5471_async_t *info,
+					kdev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+  static const char * const badmagic =
+    "Warning: bad magic number for serial struct (%s) in %s\n";
+  static const char * const badinfo =
+    "Warning: null c5471_async_t for (%s) in %s\n";
+
+  if (!info)
+    {
+      printk(badinfo, kdevname(device), routine);
+      return 1;
+    }
+  if (info->magic != SERIAL_MAGIC)
+    {
+      printk(badmagic, kdevname(device), routine);
+      return 1;
+    }
+#endif
+  return 0;
+}
+
+/* rs_stop() and rs_start()
+ *
+ * These routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ */
+
+static void rs_stop(struct tty_struct *tty)
+{
+  c5471_async_t *info = (c5471_async_t *)tty->driver_data;
+  unsigned long flags;
+
+  if (serial_paranoia_check(info, tty->device, "rs_stop"))
+    {
+      return;
+    }
+	
+  save_flags(flags); cli();
+  serial_disable_tx_int(info);
+  restore_flags(flags);
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+  c5471_async_t *info = (c5471_async_t *)tty->driver_data;
+  unsigned long flags;
+
+  if (serial_paranoia_check(info, tty->device, "rs_start"))
+    {
+      return;
+    }
+        
+  save_flags(flags); cli();
+
+  if ((info->xmit.head != info->xmit.tail) && (info->xmit.buf))
+    {
+      serial_enable_tx_int(info);
+    }
+
+  restore_flags(flags);
+}
+
+/* This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+
+static inline void rs_sched_event(c5471_async_t *info,
+				  int event)
+{
+  info->event |= 1 << event;
+  queue_task(&info->tqueue, &tq_serial);
+  mark_bh(SERIAL_BH);
+}
+
+static inline void receive_chars(c5471_async_t *info)
+{
+  struct tty_struct *tty = info->tty;
+  struct async_icount *icount;
+  unsigned short status;
+  unsigned char ch;
+
+  icount = &info->state->icount;
+
+  do
+    {
+if ((serial_in(info, UART_LSR_OFFS) & UART_RX_FIFO_NOEMPTY) == 0)
+{
+      ch = serial_char_in(info, &status);
+  return;
+}
+      ch = serial_char_in(info, &status);
+
+      if (tty->flip.count >= TTY_FLIPBUF_SIZE) break;
+
+      tty->flip.count++;
+      if (serial_some_error_condition_present(status))
+	{
+	  if (serial_parity_error_condition_present(status))
+	    *tty->flip.flag_buf_ptr++ = TTY_PARITY;
+	  else if (serial_framing_error_condition_present(status))
+	    *tty->flip.flag_buf_ptr++ = TTY_FRAME;
+	  else if (serial_overrun_error_condition_present(status))
+	    *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+	}
+      else
+	*tty->flip.flag_buf_ptr++ = 0;
+
+      *tty->flip.char_buf_ptr++ = ch;
+      icount->rx++;
+    }
+  while (serial_rx_fifo_has_content(info));
+
+#if (LINUX_VERSION_CODE > 131394) /* 2.1.66 */
+  tty_flip_buffer_push(tty);
+#else
+  queue_task(&tty->flip.tqueue, &tq_timer);
+#endif	
+}
+
+static inline void transmit_chars(c5471_async_t *info, int *intr_done)
+{
+  if (info->x_char)
+    {
+      serial_char_out(info, info->x_char);
+      info->state->icount.tx++;
+      info->x_char = 0;
+      if (intr_done)
+	*intr_done = 0;
+      return;
+    }
+
+  if ((info->xmit.head == info->xmit.tail) ||
+      (info->tty->stopped) ||
+      (info->tty->hw_stopped))
+    {
+      serial_disable_tx_int(info);
+      return;
+    }
+
+  /* Send while we still have data & room in the fifo */
+
+  do
+    {
+      serial_char_out(info, info->xmit.buf[info->xmit.tail]);
+      info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
+      info->state->icount.tx++;
+      if (info->xmit.head == info->xmit.tail) goto done;
+    }
+  while(serial_room_in_tx_fifo(info));
+
+ done:
+
+  if (CIRC_CNT(info->xmit.head,
+	       info->xmit.tail,
+	       SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
+    {
+      rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+    }
+
+  if (intr_done)
+    {
+      *intr_done = 0;
+    }
+
+  if (info->xmit.head == info->xmit.tail)
+    {
+      serial_disable_tx_int(info);
+    }
+}
+
+/* This routine is used to handle the "top half" processing for the
+ * serial driver.
+ */
+
+static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+  c5471_async_t         *info;
+  volatile unsigned long cause_bits;
+	volatile unsigned long gpio;
+
+  info = IRQ_ports[irq];
+
+  if (!info || !info->tty)
+    {
+      printk(__FUNCTION__ ": bad port or tty state\n");
+      return;
+    }
+
+
+  cause_bits = Get_INT_Cause_Bits(info);
+
+  if (serial_recvTimeout_INT_asserted(info, cause_bits))
+    {
+      unsigned long ier_val = 0;
+
+      /* Is this an interrupt from the IrDA UART? */
+//      	if (irq == C5471_IRQ_UART_IRDA)
+	{
+	  /* Save the currently enabled IrDA UART interrupts
+	   * so that we can restore the IrDA interrupt state
+	   * below.
+	   */
+
+	  ier_val = serial_in(info, UART_IER_OFFS);
+
+	  /* Then disable all IrDA UART interrupts */
+
+	  serial_out(info, UART_IER_OFFS, 0);
+	}
+
+      /* Receive characters from the RX fifo */
+
+      receive_chars(info);
+
+      /* read UART_RHR to clear int condition
+       * toss = serial_char_in(info,&status);
+       */
+
+		if (serial_in(info, UART_ISR_OFFS)  & 0x0000000c) {
+			gpio = inl(0xffff2814);
+			gpio = gpio | ~(0xfffffbff);
+			outl(gpio, 0xffff2814);
+			serial_io_delay(5);
+			gpio = gpio & 0xfffffbff;
+			outl(gpio, 0xffff2814);
+			serial_io_delay(5);
+	      	receive_chars(info);
+		}
+
+      /* Is this an interrupt from the IrDA UART? */
+//      	if (irq == C5471_IRQ_UART_IRDA)
+	{
+	  /* Restore the IrDA UART interrupt enables */
+
+	  serial_out(info, UART_IER_OFFS, ier_val);
+	}
+    }
+  else
+    {
+      if (serial_recv_INT_asserted(info, cause_bits))
+	{
+	  receive_chars(info);
+	}
+    }
+
+  if (serial_xmit_INT_asserted(info, cause_bits))
+    {
+      transmit_chars(info, 0);
+    }
+
+  info->last_active = jiffies;
+}
+
+/* This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+
+static void do_serial_bh(void)
+{
+  run_task_queue(&tq_serial);
+}
+
+static void do_softint(void *private_)
+{
+  c5471_async_t	    *info = (c5471_async_t *) private_;
+  struct tty_struct *tty;
+	
+  tty = info->tty;
+  if (!tty)
+    return;
+
+  if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event))
+    {
+      if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	  tty->ldisc.write_wakeup)
+	{
+	  (tty->ldisc.write_wakeup)(tty);
+	}
+      wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+      wake_up_interruptible(&tty->poll_wait);
+#endif
+    }
+}
+
+# define rs_start_timer(val)
+# define rs_init_timer()
+# define rs_del_timer()
+
+/* This routine figures out the correct timeout for a particular IRQ.
+ * It uses the smallest timeout of all of the serial ports in a
+ * particular interrupt chain.  Now only used for IRQ 0....
+ */
+
+static void figure_IRQ_timeout(int irq)
+{
+  c5471_async_t	*info;
+  int	         timeout = 60*HZ; /* 60 secs === a long time :-) */
+
+  info = IRQ_ports[irq];
+  if (!info)
+    {
+      IRQ_timeout[irq] = 60*HZ;
+      return;
+    }
+  while (info)
+    {
+      if (info->timeout < timeout)
+	timeout = info->timeout;
+      info = info->next_port;
+    }
+  if (!irq)
+    timeout = timeout / 2;
+  IRQ_timeout[irq] = (timeout > 3) ? timeout-2 : 1;
+}
+
+static int startup(c5471_async_t *info)
+{
+  c5471_serial_state_t *state = info->state;
+  unsigned long         flags;
+  unsigned long         page;
+#ifdef COMPILER_BUG_WORK_AROUND
+  unsigned long         junk;
+#else
+  u16                   junk;
+#endif
+  int	                retval = 0;
+
+  page = get_zeroed_page(GFP_KERNEL);
+  if (!page)
+  {
+     return -ENOMEM;
+  }
+
+  save_flags(flags); cli();
+
+  if (info->flags & ASYNC_INITIALIZED)
+  {
+      free_page(page);
+      goto errout;
+  }
+
+  if (!state->type)
+  {
+      if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+      free_page(page);
+      goto errout;
+  }
+
+  if (info->xmit.buf)
+  {
+      free_page(page);
+  }
+  else
+  {
+      info->xmit.buf = (unsigned char *) page;
+  }
+
+  serial_save_registers(info);
+  serial_disable_ints(info, &junk);
+  serial_clear_fifos(info);
+  serial_disable_breaks(info);	
+
+  /* Allocate the IRQ if necessary */
+
+  if ((state->irq) &&
+      ((!IRQ_ports[state->irq]) ||
+       (!IRQ_ports[state->irq]->next_port)))
+  {
+      if (IRQ_ports[state->irq])
+	{
+	  retval = -EBUSY;
+	  goto errout;
+	}
+
+      retval = request_irq(state->irq, rs_interrupt, SA_SHIRQ, "serial", info);
+      if (retval)
+	{
+	  if (capable(CAP_SYS_ADMIN))
+	    {
+	      if (info->tty)
+		set_bit(TTY_IO_ERROR,
+			&info->tty->flags);
+	      retval = 0;
+	    }
+	  goto errout;
+	}
+  }
+
+
+  /* Insert serial port into IRQ chain.	 */
+
+  info->prev_port = 0;
+  info->next_port = IRQ_ports[state->irq];
+  if (info->next_port)
+    info->next_port->prev_port = info;
+  IRQ_ports[state->irq] = info;
+  figure_IRQ_timeout(state->irq);
+	
+  /* Finally, enable interrupts */
+
+  serial_enable_rx_int(info);
+
+  if (info->tty)
+    clear_bit(TTY_IO_ERROR, &info->tty->flags);
+  info->xmit.head = info->xmit.tail = 0;
+
+  /* Set up serial timers... */
+
+  rs_start_timer(2*HZ/100);
+
+  /* Set up the tty->alt_speed kludge */
+
+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
+  if (info->tty)
+    {
+      if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+	info->tty->alt_speed = 57600;
+      if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+	info->tty->alt_speed = 115200;
+      if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+	info->tty->alt_speed = 230400;
+      if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+	info->tty->alt_speed = 460800;
+    }
+#endif
+	
+  /* And set the speed of the serial port */
+
+  change_speed(info, 0);
+
+  info->flags |= ASYNC_INITIALIZED;
+  restore_flags(flags);
+  return 0;
+	
+errout:
+  restore_flags(flags);
+  return retval;
+}
+
+/* This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+
+static void shutdown(c5471_async_t * info)
+{
+  unsigned long	        flags;
+  c5471_serial_state_t *state;
+  int		        retval;
+#ifdef COMPILER_BUG_WORK_AROUND
+  unsigned long         msr;
+#else
+  u16                   msr;
+#endif
+
+  if (!(info->flags & ASYNC_INITIALIZED))
+    return;
+
+  state = info->state;
+
+  save_flags(flags); cli(); /* Disable interrupts */
+
+  /* clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+   * here so the queue might never be waken up
+   */
+
+  wake_up_interruptible(&info->delta_msr_wait);
+
+  /* First unlink the serial port from the IRQ chain... */
+
+  	if (info->next_port)
+    	info->next_port->prev_port = info->prev_port;
+  	if (info->prev_port)
+    	info->prev_port->next_port = info->next_port;
+  	else {
+    	IRQ_ports[state->irq] = info->next_port;
+	}
+
+  figure_IRQ_timeout(state->irq);
+	
+  /* Free the IRQ, if necessary */
+
+  	if ((state->irq) &&
+      ((!IRQ_ports[state->irq]) ||
+       (!IRQ_ports[state->irq]->next_port)))
+    {
+    	if (IRQ_ports[state->irq])
+		{
+	  		free_irq(state->irq, info);
+	  		retval = request_irq(state->irq, rs_interrupt,
+			       SA_SHIRQ, "serial", 
+				   info);
+	  		if (retval)
+	    	{
+	      		printk("serial shutdown: request_irq: error %d"
+		     		"  Couldn't reacquire IRQ.\n", retval);
+	    	}
+		}
+      	else
+		{
+	  		free_irq(state->irq, info);
+		}
+    }
+
+  if (info->xmit.buf)
+    {
+      unsigned long pg = (unsigned long)info->xmit.buf;
+      info->xmit.buf = 0;
+      free_page(pg);
+    }
+
+  serial_disable_ints(info, &msr);
+
+  if (info->tty)
+    set_bit(TTY_IO_ERROR, &info->tty->flags);
+	
+  info->flags &= ~ASYNC_INITIALIZED;
+  restore_flags(flags);
+}
+
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+
+/* This is used to figure out the divisor speeds and the timeouts */
+
+static int baud_table[] =
+{
+      0,    50,     75,    110,    134,  150,   200, 300,
+    600,  1200,   1800,   2400,   4800, 9600, 19200,
+  38400, 57600, 115200, 230400, 460800,    0
+};
+
+/* This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+
+int tty_get_baud_rate(struct tty_struct *tty)
+{
+  c5471_async_t *info = (c5471_async_t *)tty->driver_data;
+  unsigned int   cflag;
+  unsigned int   i;
+
+  cflag = tty->termios->c_cflag;
+
+  i = cflag & CBAUD;
+  if (i & CBAUDEX)
+    {
+      i &= ~CBAUDEX;
+      if (i < 1 || i > 2) 
+	tty->termios->c_cflag &= ~CBAUDEX;
+      else
+	i += 15;
+    }
+  if (i == 15)
+    {
+      if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+	i += 1;
+      if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+	i += 2;
+    }
+  return baud_table[i];
+}
+#endif
+
+static void change_speed(c5471_async_t *info, 
+			 struct termios *old_termios)
+{
+  unsigned long   flags;
+  unsigned        cflag;
+  unsigned        cval = 0;
+  int             quot = 0;
+  int		  xmit_fifo_size;
+  int             baud_base;
+  int             baud;
+  int             bits;
+#ifdef USE_HW_FLOW_CONTROL
+  int             flowcontrol;
+#endif
+
+  if (!info->tty || !info->tty->termios)
+    {
+      return;
+    }
+
+  cflag = info->tty->termios->c_cflag;
+
+  if (!CONFIGURED_SERIAL_PORT(info))
+    {
+      return;
+    }
+
+  /* Check what we need to do about hw flow control */
+
+#ifdef USE_HW_FLOW_CONTROL
+  if (cflag & CRTSCTS)
+    {
+      flowcontrol = 1;
+    }
+  else
+    {
+      flowcontrol = 0;
+    }
+#endif
+
+  /* Byte size and parity */
+
+  switch (cflag & CSIZE)
+    {
+    case CS7: cval = UART_LCR_7bits; bits = 9; break;
+    case CS8: cval = UART_LCR_8bits; bits = 10; break;
+    default:  cval = UART_LCR_8bits; bits = 7; break;
+    }
+
+  if (cflag & CSTOPB)
+    {
+      cval |= UART_LCR_2stop;
+      bits++;
+    }
+
+  if (cflag & PARENB)
+    {
+      cval |= UART_LCR_ParEn;
+      bits++;
+    }
+
+  if (cflag & PARODD)
+    {
+      cval |= UART_LCR_ParOdd;
+    }
+
+  /* Determine divisor based on baud rate */
+
+  baud = tty_get_baud_rate(info->tty);
+
+  if (!baud)
+    {
+      baud = 9600;    /* B0 transition handled in rs_set_termios */
+    }
+
+  baud_base = info->state->baud_base;
+
+  if (baud == 38400 &&
+      ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+    {
+      quot = info->state->custom_divisor;
+    }
+  else
+    {
+      if (baud == 134)
+	{
+	  /* Special case since 134 is really 134.5 */
+
+	  quot = (2*baud_base / 269);
+	}
+      else if (baud)
+	{
+	  quot = (baud_base / baud) - 1;
+	}
+    }
+
+  /* If the quotient is zero refuse the change */
+
+  if (!quot && old_termios && baud_base != baud)
+    {
+      info->tty->termios->c_cflag &= ~CBAUD;
+      info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD);
+      baud = tty_get_baud_rate(info->tty);
+      if (!baud)
+	{
+	  baud = 9600;
+	}
+      if (baud == 38400 &&
+	  ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+	{
+	  quot = info->state->custom_divisor;
+	}
+      else
+	{
+	  if (baud == 134)
+	    {
+	      /* Special case since 134 is really 134.5 */
+
+	      quot = (2*baud_base / 269);
+	    }
+	  else if (baud)
+	    {
+	      quot = (baud_base / baud) - 1;
+	    }
+	}
+    }
+
+  /* As a last resort, if the quotient is zero, default to 9600 bps */
+
+  if (!quot && baud_base != baud)
+    {
+      quot = (baud_base / 9600) - 1;
+    }
+
+  /* If the quotient is zero refuse the change */
+
+  info->quot     = quot;
+  xmit_fifo_size = info->state->xmit_fifo_size;
+
+  if (!quot && baud_base == baud)
+    {
+      info->timeout  = ((xmit_fifo_size*HZ*bits) / (baud_base * 2));
+    }
+  else
+    {
+      info->timeout  = ((xmit_fifo_size*HZ*bits*quot) / baud_base);
+    }
+ 
+  info->timeout += HZ/50;         /* Add .02 seconds of slop */
+
+  /* Set up parity check flag */
+
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+  save_flags(flags); cli();
+
+  /* serial_set_rate(info, baud_base); */
+//  serial_out(info, UART_DIV_115K_OFFS, BAUD_115200_47_5MHZ);
+  serial_out(info, UART_DIV_115K_OFFS, BAUD_115200_50MHZ);
+
+  serial_set_rate(info, baud);
+  serial_set_mode(info, cval);
+
+#ifdef USE_HW_FLOW_CONTROL
+  if (flowcontrol)
+    {
+      serial_enable_hw_flow_control(info);
+    }
+  else
+    {
+      serial_disable_hw_flow_control(info);
+    }
+#endif
+ 
+  /* We should always set the receive FIFO trigger to the lowest value
+   * because we don't poll.
+   */
+
+  /* Hmmm... Seems to cause problems...
+   * serial_set_rx_trigger(info, UART_FCR_FTL);
+   */
+
+  restore_flags(flags);
+}
+
+static void rs_put_char(struct tty_struct *tty, unsigned char ch)
+{
+  c5471_async_t *info = (c5471_async_t *)tty->driver_data;
+  unsigned long  flags;
+
+  if (serial_paranoia_check(info, tty->device, "rs_put_char"))
+    return;
+
+  if (!tty || !info->xmit.buf)
+    return;
+
+  save_flags(flags); cli();
+  if (CIRC_SPACE(info->xmit.head,
+		 info->xmit.tail,
+		 SERIAL_XMIT_SIZE) == 0)
+    {
+      restore_flags(flags);
+      return;
+    }
+
+  info->xmit.buf[info->xmit.head] = ch;
+  info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
+  restore_flags(flags);
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+  c5471_async_t *info = (c5471_async_t *)tty->driver_data;
+  unsigned long  flags;
+				
+  if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
+    return;
+
+  if ((info->xmit.head == info->xmit.tail) ||
+      (tty->stopped) || (tty->hw_stopped) ||
+      (!info->xmit.buf))
+    return;
+
+  save_flags(flags); cli();
+  serial_enable_tx_int(info);
+  restore_flags(flags);
+}
+
+static int rs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+  c5471_async_t *info = (c5471_async_t *)tty->driver_data;
+  unsigned long  flags;
+  int            c;
+  int            ret = 0;
+
+  if (serial_paranoia_check(info, tty->device, "rs_write"))
+    return 0;
+
+  if (!tty || !info->xmit.buf || !tmp_buf)
+    return 0;
+
+  save_flags(flags);
+  if (from_user)
+    {
+      down(&tmp_buf_sem);
+      while (1)
+	{
+	  int c1;
+	  c = CIRC_SPACE_TO_END(info->xmit.head,
+				info->xmit.tail,
+				SERIAL_XMIT_SIZE);
+	  if (count < c)
+	    c = count;
+	  if (c <= 0)
+	    break;
+
+	  c -= copy_from_user(tmp_buf, buf, c);
+	  if (!c)
+	    {
+	      if (!ret)
+		ret = -EFAULT;
+	      break;
+	    }
+
+	  cli();
+	  c1 = CIRC_SPACE_TO_END(info->xmit.head,
+				 info->xmit.tail,
+				 SERIAL_XMIT_SIZE);
+	  if (c1 < c)
+	    c = c1;
+
+	  memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
+	  info->xmit.head = ((info->xmit.head + c) &
+			     (SERIAL_XMIT_SIZE-1));
+	  restore_flags(flags);
+	  buf += c;
+	  count -= c;
+	  ret += c;
+	}
+      up(&tmp_buf_sem);
+    }
+  else
+    {
+      cli();
+      while (1)
+	{
+	  c = CIRC_SPACE_TO_END(info->xmit.head,
+				info->xmit.tail,
+				SERIAL_XMIT_SIZE);
+	  if (count < c)
+	    c = count;
+	  if (c <= 0)
+	    {
+	      break;
+	    }
+	  memcpy(info->xmit.buf + info->xmit.head, buf, c);
+	  info->xmit.head = ((info->xmit.head + c) &
+			     (SERIAL_XMIT_SIZE-1));
+	  buf += c;
+	  count -= c;
+	  ret += c;
+	}
+      restore_flags(flags);
+    }
+
+  if ((info->xmit.head != info->xmit.tail) &&
+      (!tty->stopped) && (!tty->hw_stopped))
+    {
+      if (serial_room_in_tx_fifo(info))
+	{
+	  transmit_chars(info, 0);
+	}
+      serial_enable_tx_int(info);
+    }
+
+  return ret;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+  c5471_async_t *info = (c5471_async_t *)tty->driver_data;
+
+  if (serial_paranoia_check(info, tty->device, "rs_write_room"))
+    return 0;
+  return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+  c5471_async_t *info = (c5471_async_t *)tty->driver_data;
+				
+  if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+    return 0;
+  return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+  c5471_async_t *info = (c5471_async_t *)tty->driver_data;
+  unsigned long flags;
+	
+  if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+    return;
+
+  save_flags(flags); cli();
+  info->xmit.head = info->xmit.tail = 0;
+  restore_flags(flags);
+  wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+  wake_up_interruptible(&tty->poll_wait);
+#endif
+  if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+      tty->ldisc.write_wakeup)
+    (tty->ldisc.write_wakeup)(tty);
+}
+
+/* This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+
+static void rs_send_xchar(struct tty_struct *tty, char ch)
+{
+  c5471_async_t *info = (c5471_async_t *)tty->driver_data;
+
+  if (serial_paranoia_check(info, tty->device, "rs_send_char"))
+    return;
+
+  info->x_char = ch;
+	if (ch) {
+		serial_enable_tx_int(info);
+	}
+}
+
+/* rs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ */
+
+static void rs_throttle(struct tty_struct * tty)
+{
+  c5471_async_t *info = (c5471_async_t *)tty->driver_data;
+
+  if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+    return;
+	
+  if (I_IXOFF(tty))
+    info->x_char = STOP_CHAR(tty);
+
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+  c5471_async_t *info = (c5471_async_t *)tty->driver_data;
+
+  if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+    return;
+	
+  if (I_IXOFF(tty))
+    {
+      if (info->x_char)
+	info->x_char = 0;
+      else
+	info->x_char = START_CHAR(tty);
+    }
+}
+
+/*-------------------------------------------------------------------------
+ * rs_ioctl() and friends
+ *-------------------------------------------------------------------------*/
+
+static int get_serial_info(c5471_async_t * info,
+			   struct serial_struct * retinfo)
+{
+  struct serial_struct  tmp;
+  c5471_serial_state_t *state = info->state;
+   
+  if (!retinfo)
+    return -EFAULT;
+
+  memset(&tmp, 0, sizeof(tmp));
+  tmp.type           = state->type;
+  tmp.line           = state->line;
+  tmp.port           = state->port;
+  tmp.port_high      = 0;
+  tmp.irq            = state->irq;
+  tmp.flags          = state->flags;
+  tmp.baud_base      = state->baud_base;
+  tmp.close_delay    = state->close_delay;
+  tmp.closing_wait   = state->closing_wait;
+  tmp.custom_divisor = state->custom_divisor;
+  tmp.hub6           = 0;
+  tmp.io_type        = state->io_type;
+
+  if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
+    return -EFAULT;
+  return 0;
+}
+
+static int set_serial_info(c5471_async_t * info,
+			   struct serial_struct * new_info)
+{
+  struct serial_struct new_serial;
+  c5471_serial_state_t old_state, *state;
+  int 		       retval = 0;
+
+  if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
+    return -EFAULT;
+  state = info->state;
+  old_state = *state;
+
+  /* NOTE:  Changes to the serial port address, IRQ, and serial type
+   * are not supported by this driver
+   */
+
+  if (new_serial.irq != state->irq)
+    {
+      printk(KERN_INFO "Changes to serial port IRQ not supported\n");
+    }
+
+  if (new_serial.type != state->type)
+    {
+      printk(KERN_INFO "Changes to serial port type not supported\n");
+    }
+
+  if (!capable(CAP_SYS_ADMIN))
+    {
+      if ((new_serial.baud_base != state->baud_base) ||
+	  (new_serial.close_delay != state->close_delay) ||
+	  (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
+	  ((new_serial.flags & ~ASYNC_USR_MASK) !=
+	   (state->flags & ~ASYNC_USR_MASK)))
+	return -EPERM;
+      state->flags = ((state->flags & ~ASYNC_USR_MASK) |
+		      (new_serial.flags & ASYNC_USR_MASK));
+      info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+		     (new_serial.flags & ASYNC_USR_MASK));
+      state->custom_divisor = new_serial.custom_divisor;
+      goto check_and_exit;
+    }
+
+  if (new_serial.baud_base < 9600)
+    {
+      printk(KERN_INFO "Baud %d not supported\n", new_serial.baud_base);
+      return -EINVAL;
+    }
+
+  if (new_serial.xmit_fifo_size <= 0)
+    {
+      /* For C5471, the only other possibility is 
+       * UART_IRDA_XMIT_FIFO_SIZE
+       */
+
+      new_serial.xmit_fifo_size = UART_XMIT_FIFO_SIZE;
+    }
+
+  /* OK, past this point, all the error checking has been done.
+   * At this point, we start making changes.....
+   */
+
+  state->baud_base       = new_serial.baud_base;
+  state->flags           = ((state->flags & ~ASYNC_FLAGS) |
+			    (new_serial.flags & ASYNC_FLAGS));
+  info->flags            = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
+			    (info->flags & ASYNC_INTERNAL_FLAGS));
+  state->custom_divisor  = new_serial.custom_divisor;
+  state->close_delay     = new_serial.close_delay * HZ/100;
+  state->closing_wait    = new_serial.closing_wait * HZ/100;
+#if (LINUX_VERSION_CODE > 0x20100)
+  info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+#endif
+  state->xmit_fifo_size  =  new_serial.xmit_fifo_size;
+
+ check_and_exit:
+
+  if (info->flags & ASYNC_INITIALIZED)
+    {
+      if (((old_state.flags & ASYNC_SPD_MASK) !=
+	   (state->flags & ASYNC_SPD_MASK)) ||
+	  (old_state.custom_divisor != state->custom_divisor))
+	{
+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
+	  if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+	    info->tty->alt_speed = 57600;
+	  if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+	    info->tty->alt_speed = 115200;
+	  if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+	    info->tty->alt_speed = 230400;
+	  if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+	    info->tty->alt_speed = 460800;
+#endif
+	  change_speed(info, 0);
+	}
+    }
+  else
+    {
+      retval = startup(info);
+    }
+  return retval;
+}
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space. 
+ */
+
+static int get_lsr_info(c5471_async_t *info, unsigned int *value)
+{
+  unsigned char status;
+  unsigned int result;
+  unsigned long flags;
+
+  save_flags(flags); cli();
+  status = serial_in(info, UART_LSR_OFFS);
+  restore_flags(flags);
+  result = ((status & UART_LSR_TREF) ? TIOCSER_TEMT : 0);
+
+  /* If we're about to load something into the transmit
+   * register, we'll pretend the transmitter isn't empty to
+   * avoid a race condition (depending on when the transmit
+   * interrupt happens).
+   */
+
+  if ((info->x_char) || 
+      ((CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) > 0) &&
+       (!info->tty->stopped && !info->tty->hw_stopped)))
+    {
+      result &= ~TIOCSER_TEMT;
+    }
+
+  if (copy_to_user(value, &result, sizeof(int)))
+    return -EFAULT;
+
+  return 0;
+}
+
+static int do_autoconfig(c5471_async_t * info)
+{
+  int retval;
+	
+  if (!capable(CAP_SYS_ADMIN))
+    return -EPERM;
+	
+  if (info->state->count > 1)
+    return -EBUSY;
+	
+  shutdown(info);
+  autoconfig(info->state);
+  retval = startup(info);
+
+  if (retval)
+    return retval;
+
+  return 0;
+}
+
+/* rs_break() --- routine which turns the break handling on or off */
+
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+static void send_break(c5471_async_t *info, int duration)
+{
+  if (!CONFIGURED_SERIAL_PORT(info))
+    return;
+
+  current->state = TASK_INTERRUPTIBLE;
+  current->timeout = jiffies + duration;
+  cli();
+  serial_enable_breaks(info);
+  schedule();
+  serial_disable_breaks(info);
+  sti();
+
+}
+#else
+static void rs_break(struct tty_struct *tty, int break_state)
+{
+  c5471_async_t *info = (c5471_async_t *)tty->driver_data;
+  unsigned long  flags;
+	
+  if (serial_paranoia_check(info, tty->device, "rs_break"))
+    return;
+
+  if (!CONFIGURED_SERIAL_PORT(info))
+    return;
+
+  save_flags(flags); cli();
+
+  if (break_state == -1)
+    serial_enable_breaks(info);
+  else
+    serial_disable_breaks(info);
+
+  restore_flags(flags);
+}
+#endif
+
+static int rs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+  c5471_async_t                *info = (c5471_async_t *)tty->driver_data;
+  struct async_icount           cnow;	/* kernel counter temps */
+  struct serial_icounter_struct icount;
+
+  if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+    return -ENODEV;
+
+  if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+      (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+      (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT))
+    {
+      if (tty->flags & (1 << TTY_IO_ERROR))
+	return -EIO;
+  }
+	
+  switch (cmd)
+    {
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+    case TCSBRK:	/* SVID version: non-zero arg --> no break */
+      {
+	int retval = tty_check_change(tty);
+	if (retval)
+	  return retval;
+	tty_wait_until_sent(tty, 0);
+	if (signal_pending(current))
+	  return -EINTR;
+	if (!arg)
+	  {
+	    send_break(info, HZ/4);	/* 1/4 second */
+	    if (signal_pending(current))
+	      return -EINTR;
+	  }
+      }
+      return 0;
+
+    case TCSBRKP:	/* support for POSIX tcsendbreak() */
+      {
+	int retval = tty_check_change(tty);
+	if (retval)
+	  return retval;
+	tty_wait_until_sent(tty, 0);
+	if (signal_pending(current))
+	  return -EINTR;
+	send_break(info, arg ? arg*(HZ/10) : HZ/4);
+	if (signal_pending(current))
+	  return -EINTR;
+      }
+      return 0;
+
+    case TIOCGSOFTCAR:
+      {
+	int tmp = C_CLOCAL(tty) ? 1 : 0;
+	if (copy_to_user((void *)arg, &tmp, sizeof(int)))
+	  return -EFAULT;
+      }
+      return 0;
+
+    case TIOCSSOFTCAR:
+      {
+	int tmp;
+
+	if (copy_from_user(&tmp, (void *)arg, sizeof(int)))
+	  return -EFAULT;
+
+	tty->termios->c_cflag =
+	  ((tty->termios->c_cflag & ~CLOCAL) |
+	   (tmp ? CLOCAL : 0));
+      }
+      return 0;
+#endif
+
+    case TIOCGSERIAL:
+      return get_serial_info(info, (struct serial_struct *) arg);
+
+    case TIOCSSERIAL:
+      return set_serial_info(info, (struct serial_struct *) arg);
+
+    case TIOCSERCONFIG:
+      return do_autoconfig(info);
+
+    case TIOCSERGETLSR: /* Get line status register */
+      return get_lsr_info(info, (unsigned int *) arg);
+
+    case TIOCSERGSTRUCT:
+      if (copy_to_user((c5471_async_t *) arg, info, sizeof(c5471_async_t)))
+	{
+	  return -EFAULT;
+	}
+      return 0;
+				
+      /* Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+       * Return: write counters to the user passed counter struct
+       * NB: both 1->0 and 0->1 transitions are counted except for
+       *     RI where only 0->1 is counted.
+       */
+
+    case TIOCGICOUNT:
+      {
+	int flags;
+
+	save_flags(flags); cli();
+	cnow = info->state->icount;
+	restore_flags(flags);
+
+	icount.cts         = cnow.cts;
+	icount.dsr         = cnow.dsr;
+	icount.rng         = cnow.rng;
+	icount.dcd         = cnow.dcd;
+	icount.rx          = cnow.rx;
+	icount.tx          = cnow.tx;
+	icount.frame       = cnow.frame;
+	icount.overrun     = cnow.overrun;
+	icount.parity      = cnow.parity;
+	icount.brk         = cnow.brk;
+	icount.buf_overrun = cnow.buf_overrun;
+
+	if (copy_to_user((void *)arg, &icount, sizeof(icount)))
+	  return -EFAULT;
+      }
+      return 0;
+
+    case TIOCSERGWILD:
+    case TIOCSERSWILD:
+      {
+	/* "setserial -W" is called in Debian boot */
+
+	printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
+      }
+      return 0;
+
+    case TIOCSBRK:  /* BSD compatibility: Turn break on, unconditionally */
+      {
+	int retval = tty_check_change(tty);
+	if (retval)
+	  return retval;
+	tty_wait_until_sent(tty, 0);
+	rs_break(tty, -1);
+      }
+      return 0;
+
+    case TIOCCBRK:  /* BSD compatibility: Turn break off, unconditionally */
+      {
+	int retval = tty_check_change(tty);
+	if (retval)
+	  return retval;
+	tty_wait_until_sent(tty, 0);
+	rs_break(tty, 0);
+      }
+      return 0;
+
+    default:
+      return -ENOIOCTLCMD;
+    }
+  return 0;
+}
+
+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+  c5471_async_t *info = (c5471_async_t *)tty->driver_data;
+  unsigned int   cflag = tty->termios->c_cflag;
+	
+  if ((cflag == old_termios->c_cflag) &&
+      (RELEVANT_IFLAG(tty->termios->c_iflag) 
+       == RELEVANT_IFLAG(old_termios->c_iflag)))
+    {
+      return;
+    }
+
+  change_speed(info, old_termios);
+		
+  /* Handle turning off CRTSCTS if RTS/CTS HW flow control is
+   * not supported.
+   */
+
+#ifndef USE_HW_FLOW_CONTROL
+  if ((old_termios->c_cflag & CRTSCTS) &&
+      !(tty->termios->c_cflag & CRTSCTS))
+    {
+      tty->hw_stopped = 0;
+      rs_start(tty);
+    }
+#endif
+}
+
+/*-------------------------------------------------------------------------
+ * rs_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ *-------------------------------------------------------------------------*/
+
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+  c5471_async_t        *info = (c5471_async_t *)tty->driver_data;
+  c5471_serial_state_t *state;
+  unsigned long         flags;
+
+  if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+    return;
+
+  state = info->state;
+	
+  save_flags(flags); cli();
+	
+  if (tty_hung_up_p(filp))
+    {
+      MOD_DEC_USE_COUNT;
+      restore_flags(flags);
+      return;
+    }
+
+  if ((tty->count == 1) && (state->count != 1))
+    {
+      /* Uh, oh.  tty->count is 1, which means that the tty
+       * structure will be freed.  state->count should always
+       * be one in these conditions.  If it's greater than
+       * one, we've got real problems, since it means the
+       * serial port won't be shutdown.
+       */
+
+      printk("rs_close: bad serial port count; tty->count is 1, "
+	     "state->count is %d\n", state->count);
+      state->count = 1;
+    }
+
+  if (--state->count < 0)
+    {
+      printk("rs_close: bad serial port count for ttys%d: %d\n",
+	     info->line, state->count);
+      state->count = 0;
+    }
+
+  if (state->count)
+    {
+      MOD_DEC_USE_COUNT;
+      restore_flags(flags);
+      return;
+    }
+
+  info->flags |= ASYNC_CLOSING;
+  restore_flags(flags);
+
+  /* Save the termios structure, since this port may have
+   * separate termios for callout and dialin.
+   */
+
+  if (info->flags & ASYNC_NORMAL_ACTIVE)
+    info->state->normal_termios = *tty->termios;
+
+  if (info->flags & ASYNC_CALLOUT_ACTIVE)
+    info->state->callout_termios = *tty->termios;
+
+  /* Now we wait for the transmit buffer to clear; and we notify 
+   * the line discipline to only process XON/XOFF characters.
+   */
+
+  tty->closing = 1;
+  if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+    tty_wait_until_sent(tty, info->closing_wait);
+
+  /* At this point we stop accepting input.  To do this, we
+   * disable the receive line status interrupts, and tell the
+   * interrupt driver to stop checking the data ready bit in the
+   * line status register.
+   */
+
+  serial_disable_rx_int(info);	
+
+  if (info->flags & ASYNC_INITIALIZED)
+    {
+      /* Before we drop DTR, make sure the UART transmitter
+       * has completely drained; this is especially
+       * important if there is a transmit FIFO!
+       */
+
+      rs_wait_until_sent(tty, info->timeout);
+    }
+
+  shutdown(info);
+
+  if (tty->driver.flush_buffer)
+    tty->driver.flush_buffer(tty);
+
+  if (tty->ldisc.flush_buffer)
+    tty->ldisc.flush_buffer(tty);
+
+  tty->closing = 0;
+  info->event = 0;
+  info->tty = 0;
+	
+  if (info->blocked_open)
+    {
+      if (info->close_delay)
+	{
+	  set_current_state(TASK_INTERRUPTIBLE);
+	  schedule_timeout(info->close_delay);
+	}
+      wake_up_interruptible(&info->open_wait);
+    }
+
+  info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
+		   ASYNC_CLOSING);
+  wake_up_interruptible(&info->close_wait);
+  MOD_DEC_USE_COUNT;
+}
+
+/* rs_wait_until_sent() --- wait until the transmitter is empty */
+
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+  c5471_async_t *info = (c5471_async_t *)tty->driver_data;
+  unsigned long  orig_jiffies;
+  unsigned long  char_time;
+  int            xmit_fifo_size;
+	
+  if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent"))
+    return;
+
+  if (info->state->type == PORT_UNKNOWN)
+    return;
+
+  xmit_fifo_size = info->state->xmit_fifo_size;
+  if (xmit_fifo_size <= 0)
+    return; /* Just in case.... */
+
+  orig_jiffies = jiffies;
+
+  /* Set the check interval to be 1/5 of the estimated time to
+   * send a single character, and make it at least 1.  The check
+   * interval should also be less than the timeout.
+   * 
+   * Note: we have to use pretty tight timings here to satisfy
+   * the NIST-PCTS.
+   */
+
+  char_time = (info->timeout - HZ/50) / xmit_fifo_size;
+  char_time = char_time / 5;
+
+  if (char_time == 0)
+    char_time = 1;
+
+  if (timeout && timeout < char_time)
+    char_time = timeout;
+
+  /* If the transmitter hasn't cleared in twice the approximate
+   * amount of time to send the entire FIFO, it probably won't
+   * ever clear.  This assumes the UART isn't doing flow
+   * control, which is currently the case.  Hence, if it ever
+   * takes longer than info->timeout, this is probably due to a
+   * UART bug of some kind.  So, we clamp the timeout parameter at
+   * 2*info->timeout.
+   */
+
+  if (!timeout || timeout > 2*info->timeout)
+    timeout = 2*info->timeout;
+
+  while (!serial_tx_fifo_is_empty(info))
+    {
+      set_current_state(TASK_INTERRUPTIBLE);
+      schedule_timeout(char_time);
+      if (signal_pending(current))
+	break;
+      if (timeout && time_after(jiffies, orig_jiffies + timeout))
+	break;
+    }
+  set_current_state(TASK_RUNNING);
+}
+
+/* rs_hangup() --- called by tty_hangup() when a hangup is signaled. */
+
+static void rs_hangup(struct tty_struct *tty)
+{
+  c5471_async_t        *info  = (c5471_async_t *)tty->driver_data;
+  c5471_serial_state_t *state = info->state;
+	
+  if (serial_paranoia_check(info, tty->device, "rs_hangup"))
+    return;
+
+  state = info->state;
+	
+  rs_flush_buffer(tty);
+  if (info->flags & ASYNC_CLOSING)
+    return;
+
+  shutdown(info);
+  info->event = 0;
+  state->count = 0;
+  info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+  info->tty = 0;
+  wake_up_interruptible(&info->open_wait);
+}
+
+/*-------------------------------------------------------------------------
+ * rs_open() and friends
+ *-------------------------------------------------------------------------*/
+
+static int block_til_ready(struct tty_struct *tty, struct file * filp,
+			   c5471_async_t *info)
+{
+  DECLARE_WAITQUEUE(wait, current);
+  c5471_serial_state_t *state = info->state;
+  unsigned long	        flags;
+  int		        retval;
+  int		        do_clocal = 0;
+  int		        extra_count = 0;
+
+  /* If the device is in the middle of being closed, then block
+   * until it's done, and then try again.
+   */
+
+  if (tty_hung_up_p(filp) ||
+      (info->flags & ASYNC_CLOSING))
+    {
+      if (info->flags & ASYNC_CLOSING)
+	interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+      return ((info->flags & ASYNC_HUP_NOTIFY) ?
+	      -EAGAIN : -ERESTARTSYS);
+#else
+      return -EAGAIN;
+#endif
+    }
+
+  /* If this is a callout device, then just make sure the normal
+   * device isn't being used.
+   */
+
+  if (tty->driver.subtype == SERIAL_TYPE_CALLOUT)
+    {
+      if (info->flags & ASYNC_NORMAL_ACTIVE)
+	return -EBUSY;
+
+      if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+	  (info->flags & ASYNC_SESSION_LOCKOUT) &&
+	  (info->session != current->session))
+	return -EBUSY;
+
+      if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+	  (info->flags & ASYNC_PGRP_LOCKOUT) &&
+	  (info->pgrp != current->pgrp))
+	return -EBUSY;
+
+      info->flags |= ASYNC_CALLOUT_ACTIVE;
+      return 0;
+    }
+	
+  /* If non-blocking mode is set, or the port is not enabled,
+   * then make the check up front and then exit.
+   */
+
+  if ((filp->f_flags & O_NONBLOCK) ||
+      (tty->flags & (1 << TTY_IO_ERROR)))
+    {
+      if (info->flags & ASYNC_CALLOUT_ACTIVE)
+	return -EBUSY;
+      info->flags |= ASYNC_NORMAL_ACTIVE;
+      return 0;
+    }
+
+  if (info->flags & ASYNC_CALLOUT_ACTIVE)
+    {
+      if (state->normal_termios.c_cflag & CLOCAL)
+	do_clocal = 1;
+    }
+  else
+    {
+      if (tty->termios->c_cflag & CLOCAL)
+	do_clocal = 1;
+    }
+
+  /* Block waiting for the carrier detect and the line to become
+   * free (i.e., not in use by the callout).  While we are in
+   * this loop, state->count is dropped by one, so that
+   * rs_close() knows when to free things.  We restore it upon
+   * exit, either normal or abnormal.
+   */
+
+  retval = 0;
+  add_wait_queue(&info->open_wait, &wait);
+  save_flags(flags); cli();
+  if (!tty_hung_up_p(filp))
+    {
+      extra_count = 1;
+      state->count--;
+    }
+
+  restore_flags(flags);
+  info->blocked_open++;
+
+  while (1)
+    {
+      set_current_state(TASK_INTERRUPTIBLE);
+
+      if (tty_hung_up_p(filp) ||
+	  !(info->flags & ASYNC_INITIALIZED))
+	{
+#ifdef SERIAL_DO_RESTART
+	  if (info->flags & ASYNC_HUP_NOTIFY)
+	    retval = -EAGAIN;
+	  else
+	    retval = -ERESTARTSYS;	
+#else
+	  retval = -EAGAIN;
+#endif
+	  break;
+	}
+      if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+	  !(info->flags & ASYNC_CLOSING))
+	break;
+      if (signal_pending(current))
+	{
+	  retval = -ERESTARTSYS;
+	  break;
+	}
+      schedule();
+    }
+
+  set_current_state(TASK_RUNNING);
+  remove_wait_queue(&info->open_wait, &wait);
+  if (extra_count)
+    state->count++;
+  info->blocked_open--;
+  if (retval)
+    return retval;
+  info->flags |= ASYNC_NORMAL_ACTIVE;
+  return 0;
+}
+
+static int get_async_struct(int line, c5471_async_t **ret_info)
+{
+  c5471_async_t        *info;
+  c5471_serial_state_t *sstate;
+
+  sstate = rs_table + line;
+  sstate->count++;
+
+  if (sstate->info)
+    {
+      *ret_info = (c5471_async_t*)sstate->info;
+      return 0;
+    }
+
+  info = kmalloc(sizeof(c5471_async_t), GFP_KERNEL);
+  if (!info)
+    {
+      sstate->count--;
+      return -ENOMEM;
+    }
+
+  memset(info, 0, sizeof(c5471_async_t));
+
+  init_waitqueue_head(&info->open_wait);
+  init_waitqueue_head(&info->close_wait);
+  init_waitqueue_head(&info->delta_msr_wait);
+
+  info->magic           = SERIAL_MAGIC;
+  info->port            = sstate->port;
+  info->line            = line;
+  info->tqueue.routine  = do_softint;
+  info->tqueue.data     = info;
+
+  info->state           = sstate;
+  info->flags           = sstate->flags;
+
+  if (sstate->info)
+    {
+      kfree(info);
+      *ret_info = (c5471_async_t*)sstate->info;
+      return 0;
+    }
+
+  sstate->info = info;
+  *ret_info    = info;
+  return 0;
+}
+
+/* This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+
+static int rs_open(struct tty_struct *tty, struct file * filp)
+{
+  c5471_async_t	*info;
+  unsigned long	 page;
+  int 		 retval;
+  int 		 line;
+
+  MOD_INC_USE_COUNT;
+
+  line = MINOR(tty->device) - tty->driver.minor_start;
+  if ((line < 0) || (line >= NR_PORTS))
+  {
+    MOD_DEC_USE_COUNT;
+    return -ENODEV;
+  }
+
+  retval = get_async_struct(line, &info);
+  if (retval)
+    {
+      MOD_DEC_USE_COUNT;
+      return retval;
+    }
+
+  tty->driver_data = info;
+  info->tty = tty;
+  if (serial_paranoia_check(info, tty->device, "rs_open"))
+    {
+      MOD_DEC_USE_COUNT;		
+      return -ENODEV;
+    }
+
+#if (LINUX_VERSION_CODE > 0x20100)
+  info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+#endif
+
+  if (!tmp_buf)
+    {
+      page = get_zeroed_page(GFP_KERNEL);
+      if (tmp_buf)
+	free_page(page);
+      else
+	{
+	  if (!page)
+	    {
+	      MOD_DEC_USE_COUNT;
+	      return -ENOMEM;
+	    }
+	  tmp_buf = (unsigned char*)page;
+	}
+    }
+
+  /* If the port is the middle of closing, bail out now */
+
+  if (tty_hung_up_p(filp) ||
+      (info->flags & ASYNC_CLOSING))
+    {
+      if (info->flags & ASYNC_CLOSING)
+	interruptible_sleep_on(&info->close_wait);
+      MOD_DEC_USE_COUNT;
+#ifdef SERIAL_DO_RESTART
+      return ((info->flags & ASYNC_HUP_NOTIFY) ?
+	      -EAGAIN : -ERESTARTSYS);
+#else
+      return -EAGAIN;
+#endif
+    }
+
+  /* Start up serial port */
+
+  retval = startup(info);
+  if (retval)
+    {
+      MOD_DEC_USE_COUNT;
+      return retval;
+    }
+
+  retval = block_til_ready(tty, filp, info);
+  if (retval)
+    {
+      MOD_DEC_USE_COUNT;
+      return retval;
+    }
+
+  if ((info->state->count == 1) &&
+      (info->flags & ASYNC_SPLIT_TERMIOS))
+    {
+      if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+	*tty->termios = info->state->normal_termios;
+      else 
+	*tty->termios = info->state->callout_termios;
+      change_speed(info, 0);
+    }
+#ifdef CONFIG_SERIAL_C5471_CONSOLE
+  if (sercons.cflag && sercons.index == line)
+    {
+      tty->termios->c_cflag = sercons.cflag;
+      sercons.cflag = 0;
+      change_speed(info, 0);
+    }
+#endif
+  info->session = current->session;
+  info->pgrp = current->pgrp;
+
+  return 0;
+}
+
+/* Basic UART init */
+
+static void autoconfig(c5471_serial_state_t *state)
+{
+  c5471_async_t *info;
+  c5471_async_t  scr_info;
+  unsigned long  flags;
+#ifdef COMPILER_BUG_WORK_AROUND
+  unsigned long  mrs;
+#else
+  u16            mrs;
+#endif
+
+  state->type           = PORT_C5471;
+
+  info                  = &scr_info;
+  info->magic           = SERIAL_MAGIC;
+  info->state           = state;
+  info->flags           = state->flags;
+  info->port            = state->port;
+
+  /* Skip re-configuration of the serial console. This way we won't
+   * clobber the settings established for console printk's during boot.
+   */
+
+#ifdef CONFIG_SERIAL_C5471_CONSOLE
+  if (state == async_sercons.state)
+    {
+      save_flags(flags); cli();
+      serial_save_registers(info);
+      restore_flags(flags);
+    }
+  else
+#endif
+    {
+      save_flags(flags); cli();
+	
+      serial_save_registers(info);
+      serial_disable_ints(info, &mrs);
+      serial_clear_fifos(info);
+      serial_disable_breaks(info);
+      serial_set_tx_trigger(info, UART_FCR_FTL);
+      serial_set_rx_trigger(info, UART_FCR_FTL);
+
+      restore_flags(flags);
+    }
+}
+
+/* The serial driver boot-time initialization code! */
+
+static int __init rs_init(void)
+{
+  c5471_serial_state_t* state;
+  int i;
+
+  init_bh(SERIAL_BH, do_serial_bh);
+  rs_init_timer();
+
+  for (i = 0; i < NR_IRQS; i++)
+    {
+      IRQ_ports[i] = 0;
+      IRQ_timeout[i] = 0;
+    }
+
+  /* Initialize the tty_driver structure */
+	
+  memset(&serial_driver, 0, sizeof(struct tty_driver));
+  serial_driver.magic                = TTY_DRIVER_MAGIC;
+
+#if (LINUX_VERSION_CODE > 0x20100)
+  serial_driver.driver_name          = "serial";
+#endif
+
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+  serial_driver.name                 = "tts/%d";
+#else
+  serial_driver.name                 = "ttyS";
+#endif
+
+  serial_driver.major                = TTY_MAJOR;
+  serial_driver.minor_start          = 64 + SERIAL_DEV_OFFSET;
+  serial_driver.num                  = NR_PORTS;
+  serial_driver.type                 = TTY_DRIVER_TYPE_SERIAL;
+  serial_driver.subtype              = SERIAL_TYPE_NORMAL;
+  serial_driver.init_termios         = tty_std_termios;
+  serial_driver.init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
+  serial_driver.flags                = TTY_DRIVER_REAL_RAW|TTY_DRIVER_NO_DEVFS;
+  serial_driver.refcount             = &serial_refcount;
+  serial_driver.table                = serial_table;
+  serial_driver.termios              = serial_termios;
+  serial_driver.termios_locked       = serial_termios_locked;
+
+  serial_driver.open                 = rs_open;
+  serial_driver.close                = rs_close;
+  serial_driver.write                = rs_write;
+  serial_driver.put_char             = rs_put_char;
+  serial_driver.flush_chars          = rs_flush_chars;
+  serial_driver.write_room           = rs_write_room;
+  serial_driver.chars_in_buffer      = rs_chars_in_buffer;
+  serial_driver.flush_buffer         = rs_flush_buffer;
+  serial_driver.ioctl                = rs_ioctl;
+  serial_driver.throttle             = rs_throttle;
+  serial_driver.unthrottle           = rs_unthrottle;
+  serial_driver.set_termios          = rs_set_termios;
+  serial_driver.stop                 = rs_stop;
+  serial_driver.start                = rs_start;
+  serial_driver.hangup               = rs_hangup;
+
+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
+  serial_driver.break_ctl            = rs_break;
+#endif
+
+#if (LINUX_VERSION_CODE >= 131343)
+  serial_driver.send_xchar           = rs_send_xchar;
+  serial_driver.wait_until_sent      = rs_wait_until_sent;
+#ifdef CONFIG_PROCFS
+  serial_driver.read_proc            = rs_read_proc;
+#else
+  serial_driver.read_proc            = 0;
+#endif
+#endif
+
+  /* The callout device is just like normal device except for
+   * major number and the subtype code.
+   */
+
+  callout_driver                     = serial_driver;
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+  callout_driver.name                = "cua/%d";
+#else
+  callout_driver.name                = "cua";
+#endif
+  callout_driver.major               = TTYAUX_MAJOR;
+  callout_driver.subtype             = SERIAL_TYPE_CALLOUT;
+#if (LINUX_VERSION_CODE >= 131343)
+  callout_driver.read_proc           = 0;
+  callout_driver.proc_entry          = 0;
+#endif
+
+  if (tty_register_driver(&serial_driver))
+    panic("Couldn't register serial driver\n");
+
+  if (tty_register_driver(&callout_driver))
+    panic("Couldn't register callout driver\n");
+	
+  for (i = 0, state = rs_table; i < NR_PORTS; i++,state++)
+    {
+      state->magic                   = SSTATE_MAGIC;
+      state->line                    = i;
+      state->close_delay             = 5*HZ/10;
+      state->closing_wait            = 30*HZ;
+      state->callout_termios         = callout_driver.init_termios;
+      state->normal_termios          = serial_driver.init_termios;
+
+      state->icount.cts              = 0;
+      state->icount.dsr              = 0;
+      state->icount.rng              = 0;
+      state->icount.dcd              = 0;
+      state->icount.rx               = 0;
+      state->icount.tx               = 0;
+      state->icount.frame            = 0; 
+      state->icount.parity           = 0;
+      state->icount.overrun          = 0;
+      state->icount.brk              = 0;
+
+      state->irq                     = irq_cannonicalize(state->irq);
+
+      if (check_region(state->iomem_base, UARTn_IO_RANGE))
+	continue;
+
+      /* Configure the serial port. */
+
+      autoconfig(state);
+
+      /* Next, Be a good citizen and do what it takes to insure
+       * the user gets accurate info if they type "cat /proc/ioports"
+       */
+
+      request_region(state->iomem_base, UARTn_IO_RANGE, "serial");
+
+      printk(KERN_INFO "ttyS%02d at 0x%04lx (irq = %d)\n",
+	     state->line + SERIAL_DEV_OFFSET,
+	     state->iomem_base, 
+	     state->irq);
+
+      tty_register_devfs(&serial_driver, 0,
+			 serial_driver.minor_start + state->line);
+
+      tty_register_devfs(&callout_driver, 0,
+			 callout_driver.minor_start + state->line);
+    }
+	
+  return 0;
+}
+module_init(rs_init);
+
+MODULE_DESCRIPTION("C5471 serial driver");
+MODULE_AUTHOR("Gregory Nutt <spudmonkey@racsa.co.cr>, based on the original by Theodore T'so");
+MODULE_LICENSE("GPL");
+
+/*-------------------------------------------------------------------------
+ * Serial Console Driver
+ *-------------------------------------------------------------------------*/
+
+#ifdef CONFIG_SERIAL_C5471_CONSOLE
+
+/* This block is enabled when the user has used `make xconfig`
+ * to enable kernel printk() to come out the serial port.
+ * The register_console(serial_console_print) call below
+ * is what hooks in our serial output routine here with the
+ * kernel's printk output.
+ */
+
+/* Print a string to the serial port trying not to disturb
+ * any possible real use of the port...
+ *
+ * The console_lock must be held when we get here.
+ */
+
+static inline void wait_for_xmitr(c5471_async_t *info)
+{
+  int tmp;
+  for (tmp = 1000 ; tmp > 0 ; tmp--)
+    if (serial_room_in_tx_fifo(info))
+      break;
+}
+
+static void serial_console_write(struct console *co, const char *s,
+				unsigned count)
+{
+  static c5471_async_t *info = &async_sercons;
+#ifdef COMPILER_BUG_WORK_AROUND
+  unsigned long         ier;
+#else
+  u16                   ier;
+#endif
+  unsigned              i;
+
+  serial_disable_ints(info, &ier);
+
+  /* Somebody seems to be disrupting the LCR register causing
+   * our bytes not to go out. Try this to see if it fixes it.
+   */
+
+  /* serial_disable_breaks(info); */
+
+  for (i = 0; i < count; i++, s++)
+  {
+    wait_for_xmitr(info);
+    serial_char_out(info, *s);
+    if (*s == 10)
+      {
+	/* LF? add CR */
+
+	wait_for_xmitr(info);
+	serial_char_out(info, 13);
+      }
+  }
+
+  wait_for_xmitr(info);
+  serial_restore_ints(info, ier);
+}
+
+static kdev_t serial_console_device(struct console *co)
+{
+  return MKDEV(TTY_MAJOR, 64 + co->index);
+}
+
+static int __init serial_console_setup(struct console *co, char *options)
+{
+  static c5471_async_t *info;
+  c5471_serial_state_t *state;
+
+  unsigned cval   = 0;
+  int      baud   = DEFAULT_CONSOLE_BAUD;
+  int	   bits   = DEFAULT_CONSOLE_BITS;
+  int	   parity = DEFAULT_CONSOLE_PARITY;
+  int	   cflag  = CREAD | HUPCL | CLOCAL;
+  char	  *s;
+#ifdef COMPILER_BUG_WORK_AROUND
+ unsigned long ier;
+#else
+  u16      ier;
+#endif
+
+  if (options)
+    {
+      baud = simple_strtoul(options, NULL, 10);
+      s = options;
+      while(*s >= '0' && *s <= '9')
+	s++;
+      if (*s) parity = *s++;
+      if (*s) bits   = *s - '0';
+    }
+
+  SHOWVALUE(baud);
+
+  switch(baud)
+    {
+    case 1200:
+      cflag |= B1200;
+      break;
+    case 2400:
+      cflag |= B2400;
+      break;
+    case 4800:
+      cflag |= B4800;
+      break;
+    case 19200:
+      cflag |= B19200;
+      break;
+    case 38400:
+      cflag |= B38400;
+      break;
+    case 57600:
+      cflag |= B57600;
+      break;
+    case 115200:
+      cflag |= B115200;
+      break;
+
+    case 9600:
+    default:
+      cflag |= B9600;
+      break;
+    }
+
+  cval = 0;
+
+  SHOWVALUE(bits);
+
+  switch(bits)
+    {
+    case 7:
+      cflag |= CS7;
+      cval  |= UART_LCR_7bits;
+      break;
+
+    default:
+    case 8:
+      cflag |= CS8;
+      cval  |= UART_LCR_8bits;
+      break;
+    }
+
+  SHOWVALUE(parity);
+
+  switch(parity)
+    {
+    case 'o': case 'O':
+      cflag |= (PARODD|PARENB);
+      cval  |= (UART_LCR_ParEn|UART_LCR_ParOdd);
+      break;
+    case 'e': case 'E':
+      cflag |= PARENB;
+      cval  |= (UART_LCR_ParEn|UART_LCR_ParEven);
+      break;
+    }
+
+  SHOWVALUE(cval);
+
+  co->cflag             = cflag;
+
+  /* state              = rs_table + co->index; */
+  state                 = rs_table;
+
+  info                  = &async_sercons;
+  info->magic           = SERIAL_MAGIC;
+  info->state           = state;
+  info->flags           = state->flags;
+  info->port            = state->port;
+  serial_reset_chip(info);
+  serial_save_registers(info);
+  serial_disable_ints(info, &ier);
+  serial_clear_fifos(info);
+//  serial_out(info, UART_DIV_115K_OFFS, BAUD_115200_47_5MHZ);
+  serial_out(info, UART_DIV_115K_OFFS, BAUD_115200_50MHZ);
+  serial_set_rate(info, baud);
+  serial_set_mode(info, cval);
+  serial_io_delay(5);
+
+  return 0;
+}
+
+/* Register console */
+
+void __init c5471_console_init(void)
+{
+  register_console(&sercons);
+}
+
+#endif /* CONFIG_SERIAL_C5471_CONSOLE */
diff -urN linux-2.4.29/drivers/char/serial_dm270.c linux-2.4.29-uc1/drivers/char/serial_dm270.c
--- linux-2.4.29/drivers/char/serial_dm270.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_dm270.c	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,2829 @@
+/***********************************************************************
+ * drivers/char/serial_dm270.c
+ *
+ *   Derived from drivers/char/serial_c5471.c
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ *  This implementation was leveraged from the standard
+ *  serial.c Linux file.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/config.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#ifdef CONFIG_MAGIC_SYSRQ
+#include <linux/sysrq.h>
+#endif
+
+/* All of the compatibilty code so we can compile serial.c against
+ * older kernels is hidden in serial_compat.h
+ */
+
+#if defined(LOCAL_HEADERS) || (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */
+#include <linux/compatmac.h>
+#endif
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/segment.h>
+#include <asm/bitops.h>
+#include <asm/serial.h>
+#include <asm/arch/irqs.h>
+
+/* Set of debugging defines */
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+#undef SERIAL_DEBUG_AUTOCONF
+#undef SERIAL_DEBUG_THROTTLE
+
+#define SERIAL_DEV_OFFSET	0
+
+/* serial subtype definitions */
+#ifndef SERIAL_TYPE_NORMAL
+#define SERIAL_TYPE_NORMAL      1
+#define SERIAL_TYPE_CALLOUT     2
+#endif
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS          256
+
+#define SERIAL_PARANOIA_CHECK
+#define SERIAL_DO_RESTART
+
+#ifdef MODULE
+#undef CONFIG_SERIAL_DM270_CONSOLE
+#endif
+
+#define RS_STROBE_TIME (10*HZ)
+#define RS_ISR_PASS_LIMIT 256
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#define DEFAULT_CONSOLE_BAUD   38400  /* 38,400 buad */
+#define DEFAULT_CONSOLE_BITS   8       /* 8 data bits */
+#define DEFAULT_CONSOLE_PARITY 'n'     /* No parity */
+
+/* #define DEBUG_ENABLED 1 */
+
+#if (defined(CONFIG_DEBUG_LL) && defined(DEBUG_ENABLED))
+
+/* printch and printhex8 are declared in
+ * linux/arch/armnommu/kernel/debug-armv.S\
+ */
+
+extern void printch(unsigned char ch);
+extern void printhex8(unsigned long val);
+
+# define CHECKPOINT(ch) printch(ch)
+# define SHOWVALUE(val) show_value(val)
+
+static void show_value(unsigned long val)
+{
+  printch('['); printhex8(val); printch(']');
+}
+
+#else
+# define CHECKPOINT(ch)
+# define SHOWVALUE(val)
+#endif
+
+/* IRQ_timeout - How long the timeout should be for each IRQ
+ * 		 should be after the IRQ has been active.
+ */
+
+static dm270_async_t *IRQ_ports[NR_IRQS];
+static int IRQ_timeout[NR_IRQS];
+
+static char *serial_name = "TI TMS320DM270 Serial driver";
+static char *serial_version = "0.01";
+
+DECLARE_TASK_QUEUE(tq_serial);
+struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+#if defined(CONFIG_SERIAL_DM270_POLL) || defined(CONFIG_SERIAL_DM270_TIMEOUT_POLL)
+static struct timer_list serial_timer;
+#endif
+
+/* Serial Console Driver */
+
+#ifdef CONFIG_SERIAL_DM270_CONSOLE
+
+/* This block is enabled when the user has used `make xconfig`
+ * to enable kernel printk() to come out the serial port.
+ * The register_console(serial_console_print) call below
+ * is what hooks in our serial output routine here with the
+ * kernel's printk output.
+ */
+
+#include <linux/console.h>
+
+static dm270_async_t async_sercons;
+
+static void serial_console_write(struct console *co, const char *s,
+				 unsigned count);
+static kdev_t serial_console_device(struct console *co);
+static int serial_console_setup(struct console *co, char *options) __init;
+
+static struct console sercons =
+{
+  name:		"ttyS",
+  write:	serial_console_write,
+  device:	serial_console_device,
+  setup:	serial_console_setup,
+  flags:	CON_PRINTBUFFER,
+  index:	-1,
+};
+
+#if defined(CONFIG_MAGIC_SYSRQ)
+static unsigned long break_pressed; /* break, really ... */
+#endif
+#endif /* CONFIG_SERIAL_DM270_CONSOLE */
+
+static void autoconfig(dm270_serial_state_t *state);
+static void change_speed(dm270_async_t *info, struct termios *old);
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
+
+#define SERIAL_DRIVER_NAME "DM270 UART"
+
+/* tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the memcpy_fromfs blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+
+static unsigned char *tmp_buf = 0;
+#ifdef DECLARE_MUTEX
+static DECLARE_MUTEX(tmp_buf_sem);
+#else
+static struct semaphore tmp_buf_sem = MUTEX;
+#endif
+
+#ifdef CONFIG_ARCH_DM270
+/*-------------------------------------------------------------------------
+ *       -- Begin; Platform Specifics --
+ *   Note: These definitions and routines will
+ *         surely need to change if porting this
+ *         driver to another platform.
+ *-------------------------------------------------------------------------*/
+
+static dm270_serial_state_t rs_table[RS_TABLE_SIZE] =
+{
+	SERIAL_PORT_DFNS        /* Defined in asm/serial.h */
+};
+
+#define NR_PORTS (sizeof(rs_table)/sizeof(dm270_serial_state_t))
+
+static struct tty_struct *serial_table[NR_PORTS];
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
+
+static inline unsigned short serial_in(dm270_async_t *info,
+				      unsigned long offset)
+{
+	return inw(info->iomem_base + offset);
+}
+
+static inline void serial_out(dm270_async_t *info,
+                              unsigned long offset,
+                              unsigned short value)
+{
+	outw(value, info->iomem_base + offset);
+}
+
+static inline void serial_reset_chip(dm270_async_t *info)
+{
+	unsigned short reg;
+
+	/* Disable clock to UART. */
+	reg = inw(DM270_CLKC_MOD2);
+	outw((reg & ~(DM270_CLKC_MOD2_CUAT << info->line)), DM270_CLKC_MOD2);
+
+	/* Select CLK_ARM as UART clock source */
+	reg = inw(DM270_CLKC_CLKC);
+	outw((reg & ~(DM270_CLKC_CLKC_CUAS << info->line)), DM270_CLKC_CLKC);
+
+	/* Enable clock to UART. */
+	reg = inw(DM270_CLKC_MOD2);
+	outw((reg | (DM270_CLKC_MOD2_CUAT << info->line)), DM270_CLKC_MOD2);
+
+	if (info->line == 1) {
+		/* Configure GIO23 & GIO24 as RXD1 & TXD1 respectively */
+		reg = inw(DM270_GIO_FSEL0);
+		outw(reg | DM270_GIO_FSEL_RXD1, DM270_GIO_FSEL0);
+		reg = inw(DM270_GIO_FSEL1);
+		outw(reg | DM270_GIO_FSEL_TXD1, DM270_GIO_FSEL1);
+	}
+}
+
+static inline void serial_disable_tx_int(dm270_async_t *info)
+{
+	info->msr &= ~DM270_UART_MSR_TFTIE;
+	serial_out(info, DM270_UART_MSR, info->msr);
+}
+
+static inline void serial_disable_rx_int(dm270_async_t *info)
+{
+	info->msr &= ~(DM270_UART_MSR_TOIC_MASK | DM270_UART_MSR_REIE |
+			DM270_UART_MSR_RFTIE);
+	serial_out(info, DM270_UART_MSR, info->msr);
+}
+
+static inline void serial_enable_tx_int(dm270_async_t *info)
+{
+	info->msr |= DM270_UART_MSR_TFTIE;
+	serial_out(info, DM270_UART_MSR, info->msr);
+}
+
+static inline void serial_enable_rx_int(dm270_async_t *info)
+{
+	info->msr = (info->msr & ~DM270_UART_MSR_TOIC_MASK) |
+			(DM270_UART_MSR_TIMEOUT_7 | DM270_UART_MSR_REIE |
+			 DM270_UART_MSR_RFTIE);
+	serial_out(info, DM270_UART_MSR, info->msr);
+}
+
+static inline void serial_disable_ints(dm270_async_t *info, unsigned short *msr)
+{
+	*msr = info->msr & (DM270_UART_MSR_TOIC_MASK | DM270_UART_MSR_REIE |
+			DM270_UART_MSR_TFTIE | DM270_UART_MSR_RFTIE);
+	info->msr &= ~(DM270_UART_MSR_TOIC_MASK | DM270_UART_MSR_REIE |
+			DM270_UART_MSR_TFTIE | DM270_UART_MSR_RFTIE);
+	serial_out(info, DM270_UART_MSR, info->msr);
+}
+
+static inline void serial_restore_ints(dm270_async_t *info, unsigned short msr)
+{
+	info->msr = (info->msr & ~(DM270_UART_MSR_TOIC_MASK | DM270_UART_MSR_REIE |
+			DM270_UART_MSR_TFTIE | DM270_UART_MSR_RFTIE)) |
+			(msr & (DM270_UART_MSR_TOIC_MASK | DM270_UART_MSR_REIE |
+			DM270_UART_MSR_TFTIE | DM270_UART_MSR_RFTIE));
+	serial_out(info, DM270_UART_MSR, info->msr);
+}
+
+static inline void serial_clear_fifos(dm270_async_t *info)
+{
+	serial_out(info, DM270_UART_TFCR,
+			serial_in(info, DM270_UART_TFCR) | DM270_UART_TFCR_CLEAR);
+	serial_out(info, DM270_UART_RFCR,
+			serial_in(info, DM270_UART_RFCR) |
+			(DM270_UART_RFCR_RESET | DM270_UART_RFCR_CLEAR));
+}
+
+static inline void serial_disable_breaks(dm270_async_t *info)
+{
+	serial_out(info, DM270_UART_LCR,
+			serial_in(info, DM270_UART_LCR) & ~DM270_UART_LCR_BOC);
+}
+
+static inline void serial_enable_breaks(dm270_async_t *info)
+{
+	serial_out(info, DM270_UART_LCR,
+			serial_in(info, DM270_UART_LCR) | DM270_UART_LCR_BOC);
+}
+
+static inline void serial_set_rate(dm270_async_t *info,
+				   unsigned int rate)
+{
+	unsigned short div_bit_rate;
+
+	SHOWVALUE(rate);
+	SHOWVALUE(serial_in(info, DM270_UART_BRSR));
+
+	div_bit_rate = DM270_UART_BRSR_VAL(rate);
+	SHOWVALUE(div_bit_rate);
+
+	serial_out(info, DM270_UART_BRSR, div_bit_rate);
+}
+
+static inline void serial_set_mode(dm270_async_t *info, unsigned short mode)
+{
+	info->msr = (info->msr & ~(DM270_UART_MSR_CLS | DM270_UART_MSR_SBLS |
+			DM270_UART_MSR_PSB | DM270_UART_MSR_PEB)) | mode;
+	serial_out(info, DM270_UART_MSR, info->msr);
+}
+
+static inline void serial_set_rx_trigger(dm270_async_t *info, unsigned short val)
+{
+	serial_out(info, DM270_UART_RFCR, (serial_in(info, DM270_UART_RFCR) &
+			~(DM270_UART_RFCR_RTL_MASK | DM270_UART_RFCR_RESET |
+			DM270_UART_RFCR_CLEAR)) | val);
+}
+
+static inline void serial_set_tx_trigger(dm270_async_t *info, unsigned short val)
+{
+	serial_out(info, DM270_UART_TFCR, (serial_in(info, DM270_UART_TFCR) &
+			~(DM270_UART_TFCR_TTL_MASK | DM270_UART_TFCR_CLEAR)) |
+			val);
+}
+
+static inline void serial_char_out(dm270_async_t *info, u8 val)
+{
+	serial_out(info, DM270_UART_DTRR, val);
+}
+
+static inline unsigned char serial_char_in(dm270_async_t *info,
+                                           unsigned short *status)
+{
+	unsigned short dtrr;
+
+	dtrr = serial_in(info, DM270_UART_DTRR);
+	*status = (dtrr & 0xff00);
+	return ((unsigned char)(dtrr & 0x00ff));
+}
+
+static inline int serial_some_error_condition_present(unsigned short status)
+{
+	return ((status ^ DM270_UART_DTRR_RVF) &
+			(DM270_UART_DTRR_RVF | DM270_UART_DTRR_BF | DM270_UART_DTRR_FE |
+			 DM270_UART_DTRR_ORF | DM270_UART_DTRR_PEF));
+}
+
+static inline int serial_break_condition_present(unsigned short status)
+{
+	return (status & DM270_UART_DTRR_BF);
+}
+
+static inline int serial_parity_error_condition_present(unsigned short status)
+{
+	return (status & DM270_UART_DTRR_PEF);
+}
+
+static inline int serial_framing_error_condition_present(unsigned short status)
+{
+	return (status & DM270_UART_DTRR_FE);
+}
+
+static inline int serial_overrun_error_condition_present(unsigned short status)
+{
+	return (status & DM270_UART_DTRR_ORF);
+}
+
+static inline int serial_received_word_invalid_condition_present(unsigned short status)
+{
+	return (status & DM270_UART_DTRR_RVF);
+}
+
+static inline unsigned short serial_tx_fifo_is_empty(dm270_async_t *info)
+{
+	return (serial_in(info, DM270_UART_SR) & DM270_UART_SR_TREF);
+}
+
+static inline unsigned short serial_room_in_tx_fifo(dm270_async_t *info)
+{
+	return ((serial_in(info, DM270_UART_TFCR) & DM270_UART_TFCR_TWC_MASK) < DM270_UART_TXFIFO_BYTESIZE);
+}
+
+static inline unsigned short serial_rx_fifo_has_content(dm270_async_t *info)
+{
+	return (serial_in(info, DM270_UART_SR) & DM270_UART_SR_RFNEF);
+}
+
+static inline void serial_save_registers(dm270_async_t *info)
+{
+	info->msr = serial_in(info, DM270_UART_MSR);
+}
+
+/*-------------------------------------------------------------------------
+ *       -- End; Platform Specifics --
+ *-------------------------------------------------------------------------*/
+
+#endif
+
+static inline int serial_paranoia_check(dm270_async_t *info,
+					kdev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char * const badmagic =
+		"Warning: bad magic number for serial struct (%s) in %s\n";
+	static const char * const badinfo =
+		"Warning: null dm270_async_t for (%s) in %s\n";
+
+	if (!info) {
+		printk(badinfo, kdevname(device), routine);
+		return 1;
+	}
+	if (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, kdevname(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+/* rs_stop() and rs_start()
+ *
+ * These routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ */
+
+static void rs_stop(struct tty_struct *tty)
+{
+	dm270_async_t *info = (dm270_async_t *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_stop")) {
+		return;
+	}
+	
+	save_flags(flags); cli();
+	if (info->msr & DM270_UART_MSR_TFTIE) {
+		serial_disable_tx_int(info);
+	}
+	restore_flags(flags);
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+	dm270_async_t *info = (dm270_async_t *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_start")) {
+		return;
+	}
+        
+	save_flags(flags); cli();
+
+	if ((info->xmit.head != info->xmit.tail) && (info->xmit.buf) &&
+			!(info->msr & DM270_UART_MSR_TFTIE)) {
+		serial_enable_tx_int(info);
+	}
+
+	restore_flags(flags);
+}
+
+/* ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ * 
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assemble code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/* This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+
+static inline void rs_sched_event(dm270_async_t *info,
+				  int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_serial);
+	mark_bh(SERIAL_BH);
+}
+
+static inline void receive_chars(dm270_async_t *info)
+{
+	struct tty_struct *tty = info->tty;
+	struct async_icount *icount;
+	unsigned short status;
+	unsigned char ch;
+	int max_count = 256;
+
+	icount = &info->state->icount;
+	do {
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			break;
+
+		ch = serial_char_in(info, &status);
+		*tty->flip.char_buf_ptr = ch;
+		icount->rx++;
+
+#ifdef SERIAL_DEBUG_INTR
+		printk("DR%02x:%04x...", ch, status);
+#endif
+		*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		if (serial_some_error_condition_present(status)) {
+			/* For statistics only */
+			if (serial_break_condition_present(status)) {
+				status &= ~(DM270_UART_DTRR_FE | DM270_UART_DTRR_PEF);
+				icount->brk++;
+				/* We do the SysRQ and SAK checking
+				 * here because otherwise the break
+				 * may get masked by ignore_status_mask
+				 * or read_status_mask.
+				 */
+#if defined(CONFIG_SERIAL_DM270_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+				if (info->line == sercons.index) {
+					if (!break_pressed) {
+						break_pressed = jiffies;
+						goto ignore_char;
+					}
+					break_pressed = 0;
+				}
+#endif
+				if (info->flags & ASYNC_SAK)
+					do_SAK(tty);
+			} else if (serial_parity_error_condition_present(status)) {
+				icount->parity++;
+			} else if (serial_framing_error_condition_present(status)) {
+				icount->frame++;
+			}
+			if (serial_overrun_error_condition_present(status))
+				icount->overrun++;
+
+			/* Now check to see if character should be
+			 * ignored, and mask off conditions which
+			 * should be ignored.
+			 */
+			status &= info->read_status_mask;
+
+			if (serial_break_condition_present(status)) {
+#ifdef SERIAL_DEBUG_INTR
+				printk("handling break....");
+#endif
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			} else if (serial_parity_error_condition_present(status)) {
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			} else if (serial_framing_error_condition_present(status)) {
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+			}
+		}
+#if defined(CONFIG_SERIAL_DM270_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+		if (break_pressed && info->line == sercons.index) {
+			if (ch != 0 &&
+					time_before(jiffies, break_pressed + HZ*5)) {
+				handle_sysrq(ch, regs, NULL, NULL);
+				break_pressed = 0;
+				goto ignore_char;
+			}
+			break_pressed = 0;
+		}
+#endif
+		if ((status & info->ignore_status_mask) == 0) {
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+		if (serial_overrun_error_condition_present(status) &&
+				(tty->flip.count < TTY_FLIPBUF_SIZE)) {
+			/* Overrun is special, since it's
+			 * reported immediately, and doesn't
+			 * affect the current character
+			 */
+			*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+			tty->flip.count++;
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+		}
+#if defined(CONFIG_SERIAL_DM270_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+	ignore_char:
+#endif
+	} while (serial_rx_fifo_has_content(info) && (max_count-- > 0));
+
+#if (LINUX_VERSION_CODE > 131394) /* 2.1.66 */
+	tty_flip_buffer_push(tty);
+#else
+	queue_task(&tty->flip.tqueue, &tq_timer);
+#endif	
+}
+
+static inline void transmit_chars(dm270_async_t *info, int *intr_done)
+{
+	int count;
+
+	if (info->x_char) {
+		serial_char_out(info, info->x_char);
+		info->state->icount.tx++;
+		info->x_char = 0;
+		if (intr_done)
+			*intr_done = 0;
+		return;
+	}
+
+	if ((info->xmit.head == info->xmit.tail) ||
+		(info->tty->stopped) ||
+		(info->tty->hw_stopped)) {
+		serial_disable_tx_int(info);
+		return;
+	}
+
+	/* Send while we still have data & room in the fifo */
+
+	count = info->xmit_fifo_size;
+	do {
+		serial_char_out(info, info->xmit.buf[info->xmit.tail++]);
+		info->xmit.tail &= (SERIAL_XMIT_SIZE-1);
+		info->state->icount.tx++;
+		if (info->xmit.head == info->xmit.tail)
+			break;
+	} while (--count > 0);
+
+	if (CIRC_CNT(info->xmit.head,
+				info->xmit.tail,
+				SERIAL_XMIT_SIZE) < WAKEUP_CHARS) {
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+	}
+
+#ifdef SERIAL_DEBUG_INTR
+	printk("THRE...");
+#endif
+	if (intr_done) {
+		*intr_done = 0;
+	}
+
+	if (info->xmit.head == info->xmit.tail) {
+		serial_disable_tx_int(info);
+	}
+}
+
+/* This routine is used to handle the "top half" processing for the
+ * serial driver.
+ */
+
+static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	dm270_async_t     *info;
+	unsigned short    status;
+	int               pass_counter = 0;
+
+#ifdef SERIAL_DEBUG_INTR
+	printk("rs_interrupt(%d)...", irq);
+#endif
+
+	info = IRQ_ports[irq];
+	if (!info || !info->tty)
+		return;
+
+	status = serial_in(info, DM270_UART_SR);
+#ifdef SERIAL_DEBUG_INTR
+	printk("status=%x...", status);
+#endif
+	while (status  & (DM270_UART_SR_RFNEF | DM270_UART_SR_TFEF)) {
+		if (status & DM270_UART_SR_RFNEF)
+			receive_chars(info);
+
+		if (status & DM270_UART_SR_TFEF)
+			transmit_chars(info, 0);
+
+		if (pass_counter++ > RS_ISR_PASS_LIMIT) {
+#ifdef SERIAL_DEBUG_INTR
+			printk("rs_interrupt loop break.\n");
+#endif
+			break;
+		}
+
+		status = serial_in(info, DM270_UART_SR);
+#ifdef SERIAL_DEBUG_INTR
+		printk("status=%x...", status);
+#endif
+	}
+
+	info->last_active = jiffies;
+#ifdef SERIAL_DEBUG_INTR
+	printk("end.\n");
+#endif
+}
+
+/* -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+/* This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+}
+
+static void do_softint(void *private_)
+{
+	dm270_async_t     *info = (dm270_async_t *) private_;
+	struct tty_struct *tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+				tty->ldisc.write_wakeup) {
+			(tty->ldisc.write_wakeup)(tty);
+		}
+		wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+		wake_up_interruptible(&tty->poll_wait);
+#endif
+	}
+}
+
+#if defined(CONFIG_SERIAL_DM270_POLL) || defined(CONFIG_SERIAL_DM270_TIMEOUT_POLL)
+/* This subroutine is called when the RS_TIMER goes off.  It is used
+ * by the serial driver to handle ports that do not have an interrupt
+ * (irq=0).  This doesn't work very well for 16450's, but gives barely
+ * passable results for a 16550A.  (Although at the expense of much
+ * CPU overhead).
+ */
+
+static void rs_timer(unsigned long dummy)
+{
+	dm270_async_t	*info;
+	static unsigned long last_strobe;
+	unsigned int	i;
+	unsigned long flags;
+
+#ifdef CONFIG_SERIAL_DM270_POLL
+	/* assumes RS_STROBE_TIME < IRQ_timeout[0] */
+	if ((jiffies - last_strobe) >= RS_STROBE_TIME)
+	{
+		for (i=0; i < NR_IRQS; i++) {
+			info = IRQ_ports[i];
+			if (!info)
+				continue;
+			save_flags(flags); cli();
+			rs_interrupt(i, NULL, NULL);
+			restore_flags(flags);
+		}
+		last_strobe = jiffies;
+		mod_timer(&serial_timer, jiffies + RS_STROBE_TIME);
+	}
+	else
+#endif
+
+	{
+#ifdef CONFIG_SERIAL_DM270_TIMEOUT_POLL
+		if (IRQ_ports[0]) {
+			save_flags(flags); cli();
+			rs_interrupt(0, NULL, NULL);
+			restore_flags(flags);
+
+			mod_timer(&serial_timer, jiffies + IRQ_timeout[0]);
+		}
+#endif
+	}
+}
+#endif
+
+/* ---------------------------------------------------------------
+ * Low level utility subroutines for the serial driver:  routines to
+ * figure out the appropriate timeout for an interrupt chain, routines
+ * to initialize and startup a serial port, and routines to shutdown a
+ * serial port.  Useful stuff like that.
+ * ---------------------------------------------------------------
+ */
+
+#ifdef CONFIG_SERIAL_DM270_TIMEOUT_POLL
+/* This routine figures out the correct timeout for a particular IRQ.
+ * It uses the smallest timeout of all of the serial ports in a
+ * particular interrupt chain.  Now only used for IRQ 0....
+ */
+
+static void figure_IRQ_timeout(int irq)
+{
+	dm270_async_t	*info;
+	int	         timeout = 60*HZ; /* 60 secs === a long time :-) */
+
+	info = IRQ_ports[irq];
+	if (!info) {
+		IRQ_timeout[irq] = 60*HZ;
+		return;
+	}
+	while (info) {
+		if (info->timeout < timeout)
+			timeout = info->timeout;
+		info = info->next_port;
+	}
+	if (!irq)
+		meout = timeout / 2;
+	IRQ_timeout[irq] = (timeout > 3) ? timeout-2 : 1;
+}
+#endif
+
+static int startup(dm270_async_t *info)
+{
+	dm270_serial_state_t *state = info->state;
+	unsigned long         flags;
+	unsigned long         page;
+	unsigned short        junk;
+	int                   retval = 0;
+
+	page = get_zeroed_page(GFP_KERNEL);
+	if (!page) {
+		return -ENOMEM;
+	}
+
+	save_flags(flags); cli();
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		free_page(page);
+		goto errout;
+	}
+
+	if (!CONFIGURED_SERIAL_PORT(info) || !state->type) {
+		if (info->tty)
+			set_bit(TTY_IO_ERROR, &info->tty->flags);
+		free_page(page);
+		goto errout;
+	}
+
+	if (info->xmit.buf) {
+		free_page(page);
+	} else {
+		info->xmit.buf = (unsigned char *) page;
+	}
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttyS%d (irq %d)...", info->line, state->irq);
+#endif
+	serial_save_registers(info);
+	serial_disable_ints(info, &junk);
+	serial_clear_fifos(info);
+	serial_disable_breaks(info);	
+
+	/* Allocate the IRQ if necessary */
+
+	if ((state->irq) &&
+			((!IRQ_ports[state->irq]) ||
+			 (!IRQ_ports[state->irq]->next_port))) {
+		if (IRQ_ports[state->irq]) {
+			retval = -EBUSY;
+			goto errout;
+		}
+
+		retval = request_irq(state->irq, rs_interrupt, SA_INTERRUPT,
+				"serial", NULL);
+		if (retval) {
+			if (capable(CAP_SYS_ADMIN)) {
+				if (info->tty)
+					set_bit(TTY_IO_ERROR,
+							&info->tty->flags);
+				retval = 0;
+			}
+			goto errout;
+		}
+	}
+
+	/* Insert serial port into IRQ chain. */
+
+	info->prev_port = 0;
+	info->next_port = IRQ_ports[state->irq];
+	if (info->next_port)
+		info->next_port->prev_port = info;
+	IRQ_ports[state->irq] = info;
+#ifdef CONFIG_SERIAL_DM270_TIMEOUT_POLL
+	figure_IRQ_timeout(state->irq);
+#endif
+
+	/* Finally, enable interrupts */
+
+	serial_enable_rx_int(info);
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit.head = info->xmit.tail = 0;
+
+	/* Set up serial timers... */
+
+#if defined(CONFIG_SERIAL_DM270_POLL) || defined(CONFIG_SERIAL_DM270_TIMEOUT_POLL)
+/*	mod_timer(&serial_timer, jiffies + 2*HZ/100);*/
+	mod_timer(&serial_timer, jiffies + RS_STROBE_TIME);
+#endif
+
+	/* Set up the tty->alt_speed kludge */
+
+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
+	if (info->tty) {
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+			info->tty->alt_speed = 57600;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+			info->tty->alt_speed = 115200;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+			info->tty->alt_speed = 230400;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+			info->tty->alt_speed = 460800;
+	}
+#endif
+
+	/* And set the speed of the serial port */
+
+	change_speed(info, 0);
+
+	info->flags |= ASYNC_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+
+errout:
+	restore_flags(flags);
+	return retval;
+}
+
+/* This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+
+static void shutdown(dm270_async_t * info)
+{
+	unsigned long         flags;
+	dm270_serial_state_t *state;
+	int                   retval;
+	unsigned short        junk;
+
+	if (!(info->flags & ASYNC_INITIALIZED))
+		return;
+
+	state = info->state;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Shutting down serial port %d (irq %d)....", info->line,
+			state->irq);
+#endif
+	save_flags(flags); cli(); /* Disable interrupts */
+
+	/* clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+	 * here so the queue might never be waken up
+	 */
+
+	wake_up_interruptible(&info->delta_msr_wait);
+
+	/* First unlink the serial port from the IRQ chain... */
+
+	if (info->next_port)
+		info->next_port->prev_port = info->prev_port;
+	if (info->prev_port)
+		info->prev_port->next_port = info->next_port;
+	else
+		IRQ_ports[state->irq] = info->next_port;
+
+#ifdef CONFIG_SERIAL_DM270_TIMEOUT_POLL
+	figure_IRQ_timeout(state->irq);
+#endif
+	
+	/* Free the IRQ, if necessary */
+
+	if ((state->irq) &&
+			((!IRQ_ports[state->irq]) ||
+			 (!IRQ_ports[state->irq]->next_port))) {
+		if (IRQ_ports[state->irq]) {
+			free_irq(state->irq, NULL);
+			retval = request_irq(state->irq, rs_interrupt,
+			       SA_INTERRUPT, "serial", NULL);
+			if (retval) {
+				printk(KERN_WARNING "serial shutdown: request_irq: error %d"
+						"  Couldn't reacquire IRQ.\n", retval);
+			}
+		} else {
+			free_irq(state->irq, NULL);
+		}
+	}
+
+	if (info->xmit.buf) {
+		unsigned long pg = (unsigned long)info->xmit.buf;
+		info->xmit.buf = 0;
+		free_page(pg);
+	}
+
+	serial_disable_ints(info, &junk);	/* disable all intrs */
+	serial_disable_breaks(info);		/* disable break condition */
+	serial_clear_fifos(info);		/* reset FIFO's */	
+
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+	
+	info->flags &= ~ASYNC_INITIALIZED;
+	restore_flags(flags);
+}
+
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+
+/* This is used to figure out the divisor speeds and the timeouts */
+
+static int baud_table[] =
+{
+      0,    50,     75,    110,    134,  150,   200, 300,
+    600,  1200,   1800,   2400,   4800, 9600, 19200,
+  38400, 57600, 115200, 230400, 460800,    0
+};
+
+/* This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+
+int tty_get_baud_rate(struct tty_struct *tty)
+{
+	dm270_async_t *info = (dm270_async_t *)tty->driver_data;
+	unsigned int   cflag;
+	unsigned int   i;
+
+	cflag = tty->termios->c_cflag;
+
+	i = cflag & CBAUD;
+	if (i & CBAUDEX) {
+		i &= ~CBAUDEX;
+		if (i < 1 || i > 2) 
+			tty->termios->c_cflag &= ~CBAUDEX;
+		else
+			i += 15;
+	}
+	if (i == 15) {
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+			i += 1;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+			i += 2;
+	}
+	return baud_table[i];
+}
+#endif
+
+static void change_speed(dm270_async_t *info, 
+			 struct termios *old_termios)
+{
+	unsigned long   flags;
+	unsigned int    cflag;
+	unsigned short  cval = 0;
+	int             baud;
+	int             bits;
+
+	if (!info->tty || !info->tty->termios) {
+		return;
+	}
+
+	cflag = info->tty->termios->c_cflag;
+
+	if (!CONFIGURED_SERIAL_PORT(info)) {
+		return;
+	}
+
+	/* Byte size and parity */
+
+	switch (cflag & CSIZE) {
+		case CS7:
+			cval = DM270_UART_MSR_7_DBITS;
+			bits = 9;
+			break;
+		case CS8:
+		default:
+			cval = DM270_UART_MSR_8_DBITS;
+			bits = 10;
+			break;
+	}
+
+	if (cflag & CSTOPB) {
+		cval |= DM270_UART_MSR_2_SBITS;
+		bits++;
+	} else {
+		cval |= DM270_UART_MSR_1_SBITS;
+	}
+
+	if (cflag & PARENB) {
+		if (cflag & PARODD) {
+			cval |= DM270_UART_MSR_ODD_PARITY;
+		} else {
+			cval |= DM270_UART_MSR_EVEN_PARITY;
+		}
+		bits++;
+	} else if (cflag & PARODD) {
+		cval |= DM270_UART_MSR_ODD_PARITY;
+		bits++;
+	} else {
+		cval |= DM270_UART_MSR_NO_PARITY;
+	}
+
+	/* Determine divisor based on baud rate */
+
+	baud = tty_get_baud_rate(info->tty);
+	if (!baud) {
+		baud = 9600;    /* B0 transition handled in rs_set_termios */
+	}
+
+	info->baud = baud;
+	info->timeout  = ((info->xmit_fifo_size*HZ*bits) / baud);
+	info->timeout += HZ/50;         /* Add .02 seconds of slop */
+
+	/* Set up parity check flag */
+
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+	info->read_status_mask = (DM270_UART_DTRR_ORF | DM270_UART_DTRR_RVF);
+	if (I_INPCK(info->tty))
+		info->read_status_mask |= (DM270_UART_DTRR_PEF | DM270_UART_DTRR_FE);
+	if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+		info->read_status_mask |= DM270_UART_DTRR_BF;
+
+	/* Characters to ignore */
+	info->ignore_status_mask = 0;
+	if (I_IGNPAR(info->tty))
+		info->ignore_status_mask |= (DM270_UART_DTRR_PEF | DM270_UART_DTRR_FE);
+	if (I_IGNBRK(info->tty)) {
+		info->ignore_status_mask |= DM270_UART_DTRR_BF;
+		/* If we're ignore parity and break indicators, ignore 
+		 * overruns too.  (For real raw support).
+		 */
+		if (I_IGNPAR(info->tty))
+			info->ignore_status_mask |= DM270_UART_DTRR_ORF;
+	}
+	/* !!! ignore all characters if CREAD is not set */
+	if ((cflag & CREAD) == 0)
+		info->ignore_status_mask |= DM270_UART_DTRR_RVF;
+
+	save_flags(flags); cli();
+
+	serial_set_rate(info, baud);
+	serial_set_mode(info, cval);
+
+	/* We should always set the receive FIFO trigger to the lowest value
+	 * because we don't poll.
+	 */
+
+	serial_set_rx_trigger(info, DM270_UART_RFCR_TRG_1);
+
+	restore_flags(flags);
+}
+
+static void rs_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	dm270_async_t *info = (dm270_async_t *)tty->driver_data;
+	unsigned long  flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_put_char"))
+		return;
+
+	if (!tty || !info->xmit.buf)
+		return;
+
+	save_flags(flags); cli();
+	if (CIRC_SPACE(info->xmit.head,
+				info->xmit.tail,
+				SERIAL_XMIT_SIZE) == 0) {
+		restore_flags(flags);
+		return;
+	}
+
+	info->xmit.buf[info->xmit.head++] = ch;
+	info->xmit.head &= (SERIAL_XMIT_SIZE-1);
+	restore_flags(flags);
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	dm270_async_t *info = (dm270_async_t *)tty->driver_data;
+	unsigned long  flags;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
+		return;
+
+	if ((info->xmit.head == info->xmit.tail) ||
+			(tty->stopped) || (tty->hw_stopped) ||
+			(!info->xmit.buf))
+		return;
+
+	save_flags(flags); cli();
+	serial_enable_tx_int(info);
+	restore_flags(flags);
+}
+
+static int rs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	dm270_async_t *info = (dm270_async_t *)tty->driver_data;
+	unsigned long  flags;
+	int            c;
+	int            ret = 0;
+
+	if (serial_paranoia_check(info, tty->device, "rs_write"))
+		return 0;
+
+	if (!tty || !info->xmit.buf || !tmp_buf)
+		return 0;
+
+	save_flags(flags);
+	if (from_user) {
+		  down(&tmp_buf_sem);
+		  while (1) {
+			int c1;
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					info->xmit.tail,
+					SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0)
+				break;
+
+			c -= copy_from_user(tmp_buf, buf, c);
+			if (!c) {
+				if (!ret)
+					ret = -EFAULT;
+				break;
+			}
+
+			cli();
+			c1 = CIRC_SPACE_TO_END(info->xmit.head,
+					info->xmit.tail,
+					SERIAL_XMIT_SIZE);
+			if (c1 < c)
+				c = c1;
+
+			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					(SERIAL_XMIT_SIZE-1));
+			restore_flags(flags);
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		up(&tmp_buf_sem);
+	} else {
+		cli();
+		while (1) {
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+				info->xmit.tail,
+				SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0) {
+				break;
+			}
+			memcpy(info->xmit.buf + info->xmit.head, buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+			     (SERIAL_XMIT_SIZE-1));
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		restore_flags(flags);
+	}
+
+	if ((info->xmit.head != info->xmit.tail) &&
+			(!tty->stopped) && (!tty->hw_stopped) &&
+			!(info->msr & DM270_UART_MSR_TFTIE)) {
+		serial_enable_tx_int(info);
+	}
+
+	return ret;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	dm270_async_t *info = (dm270_async_t *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
+		return 0;
+	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	dm270_async_t *info = (dm270_async_t *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+		return 0;
+	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	dm270_async_t *info = (dm270_async_t *)tty->driver_data;
+	unsigned long flags;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+		return;
+
+	save_flags(flags); cli();
+	info->xmit.head = info->xmit.tail = 0;
+	restore_flags(flags);
+	wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+	wake_up_interruptible(&tty->poll_wait);
+#endif
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+			tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/* This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+
+static void rs_send_xchar(struct tty_struct *tty, char ch)
+{
+	dm270_async_t *info = (dm270_async_t *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_send_char"))
+		return;
+
+	info->x_char = ch;
+	if (ch) {
+		serial_enable_tx_int(info);
+	}
+}
+
+/* rs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ */
+
+static void rs_throttle(struct tty_struct * tty)
+{
+	dm270_async_t *info = (dm270_async_t *)tty->driver_data;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char buf[64];
+
+	printk("throttle %s: %d....\n", tty_name(tty, buf),
+			tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+		return;
+	
+	if (I_IXOFF(tty))
+		rs_send_xchar(tty, STOP_CHAR(tty));
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+	dm270_async_t *info = (dm270_async_t *)tty->driver_data;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char buf[64];
+	
+	printk("unthrottle %s: %d....\n", tty_name(tty, buf),
+			tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+		return;
+	
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			rs_send_xchar(tty, START_CHAR(tty));
+	}
+}
+
+/*-------------------------------------------------------------------------
+ * rs_ioctl() and friends
+ *-------------------------------------------------------------------------*/
+
+static int get_serial_info(dm270_async_t * info,
+			   struct serial_struct * retinfo)
+{
+	struct serial_struct  tmp;
+	dm270_serial_state_t *state = info->state;
+   
+	if (!retinfo)
+		return -EFAULT;
+
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type           = state->type;
+	tmp.line           = state->line;
+	tmp.port           = state->port;
+	tmp.port_high      = 0;
+	tmp.iomem_base     = (unsigned char *)state->iomem_base;
+	tmp.irq            = state->irq;
+	tmp.flags          = state->flags;
+	tmp.xmit_fifo_size = state->xmit_fifo_size;
+	tmp.baud_base      = state->baud_base;
+	tmp.close_delay    = state->close_delay;
+	tmp.closing_wait   = state->closing_wait;
+	tmp.custom_divisor = state->custom_divisor;
+	tmp.hub6           = 0;
+	tmp.io_type        = state->io_type;
+
+	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
+		return -EFAULT;
+	return 0;
+}
+
+static int set_serial_info(dm270_async_t * info,
+			   struct serial_struct * new_info)
+{
+	struct serial_struct new_serial;
+	dm270_serial_state_t old_state, *state;
+	int 		       retval = 0;
+
+	if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
+		return -EFAULT;
+	state = info->state;
+	old_state = *state;
+
+	/* NOTE:  Changes to the serial port address, IRQ, and serial type
+	 * are not supported by this driver
+	 */
+
+	if (new_serial.iomem_base != (unsigned char *)state->iomem_base) {
+		printk(KERN_INFO "Changes to serial port address not supported\n");
+	}
+
+	if (new_serial.irq != state->irq) {
+		printk(KERN_INFO "Changes to serial port address not supported\n");
+	}
+
+	if (new_serial.type != state->type) {
+		printk(KERN_INFO "Changes to serial port type not supported\n");
+	}
+
+	if (!capable(CAP_SYS_ADMIN)) {
+		if ((new_serial.baud_base != state->baud_base) ||
+				(new_serial.close_delay != state->close_delay) ||
+				(new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
+				((new_serial.flags & ~ASYNC_USR_MASK) !=
+				 (state->flags & ~ASYNC_USR_MASK)))
+			return -EPERM;
+		state->flags = ((state->flags & ~ASYNC_USR_MASK) |
+				(new_serial.flags & ASYNC_USR_MASK));
+		info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+				(new_serial.flags & ASYNC_USR_MASK));
+		state->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	if (new_serial.baud_base < 9600) {
+		printk(KERN_INFO "Baud %d not supported\n", new_serial.baud_base);
+		return -EINVAL;
+	}
+
+	if (new_serial.xmit_fifo_size <= 0) {
+		new_serial.xmit_fifo_size = DM270_UART_TXFIFO_BYTESIZE;
+	}
+
+	/* OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+	state->baud_base       = new_serial.baud_base;
+	state->flags           = ((state->flags & ~ASYNC_FLAGS) |
+					(new_serial.flags & ASYNC_FLAGS));
+	info->flags            = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
+					(info->flags & ASYNC_INTERNAL_FLAGS));
+	state->custom_divisor  = new_serial.custom_divisor;
+	state->close_delay     = new_serial.close_delay * HZ/100;
+	state->closing_wait    = new_serial.closing_wait * HZ/100;
+#if (LINUX_VERSION_CODE > 0x20100)
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+#endif
+	info->xmit_fifo_size = state->xmit_fifo_size = new_serial.xmit_fifo_size;
+
+check_and_exit:
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		if (((old_state.flags & ASYNC_SPD_MASK) !=
+				(state->flags & ASYNC_SPD_MASK)) ||
+				(old_state.custom_divisor != state->custom_divisor)) {
+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+				info->tty->alt_speed = 57600;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+				info->tty->alt_speed = 115200;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+				info->tty->alt_speed = 230400;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+				info->tty->alt_speed = 460800;
+#endif
+			change_speed(info, 0);
+		}
+	} else {
+		retval = startup(info);
+	}
+	return retval;
+}
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space. 
+ */
+
+static int get_lsr_info(dm270_async_t *info, unsigned short *value)
+{
+	unsigned char status;
+	unsigned int result;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	status = serial_in(info, DM270_UART_SR);
+	restore_flags(flags);
+	result = ((status & DM270_UART_SR_TREF) ? TIOCSER_TEMT : 0);
+
+	/* If we're about to load something into the transmit
+	 * register, we'll pretend the transmitter isn't empty to
+	 * avoid a race condition (depending on when the transmit
+	 * interrupt happens).
+	 */
+
+	if ((info->x_char) ||
+			((CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) > 0) &&
+			 (!info->tty->stopped && !info->tty->hw_stopped))) {
+		result &= ~TIOCSER_TEMT;
+	}
+
+	if (copy_to_user(value, &result, sizeof(int)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int do_autoconfig(dm270_async_t * info)
+{
+	int retval;
+	
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	
+	if (info->state->count > 1)
+		return -EBUSY;
+	
+	shutdown(info);
+	autoconfig(info->state);
+	retval = startup(info);
+
+	if (retval)
+		return retval;
+
+	return 0;
+}
+
+/* rs_break() --- routine which turns the break handling on or off */
+
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+static void send_break(dm270_async_t *info, int duration)
+{
+	if (!CONFIGURED_SERIAL_PORT(info))
+		return;
+
+	current->state = TASK_INTERRUPTIBLE;
+	current->timeout = jiffies + duration;
+	cli();
+	serial_enable_breaks(info);
+	schedule();
+	serial_disable_breaks(info);
+	sti();
+}
+#else
+static void rs_break(struct tty_struct *tty, int break_state)
+{
+	dm270_async_t *info = (dm270_async_t *)tty->driver_data;
+	unsigned long  flags;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_break"))
+		return;
+
+	if (!CONFIGURED_SERIAL_PORT(info))
+		return;
+
+	save_flags(flags); cli();
+
+	if (break_state == -1)
+		serial_enable_breaks(info);
+	else
+		serial_disable_breaks(info);
+
+	restore_flags(flags);
+}
+#endif
+
+static int rs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	dm270_async_t                *info = (dm270_async_t *)tty->driver_data;
+	struct async_icount           cnow;	/* kernel counter temps */
+	struct serial_icounter_struct icount;
+
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+			(cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+			(cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+			return -EIO;
+	}
+	
+	switch (cmd) {
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+		case TCSBRK:	/* SVID version: non-zero arg --> no break */
+			{
+				int retval = tty_check_change(tty);
+				if (retval)
+					return retval;
+				tty_wait_until_sent(tty, 0);
+				if (signal_pending(current))
+					return -EINTR;
+				if (!arg) {
+					send_break(info, HZ/4);	/* 1/4 second */
+					if (signal_pending(current))
+						return -EINTR;
+				}
+			}
+			return 0;
+
+		case TCSBRKP:	/* support for POSIX tcsendbreak() */
+			{
+				int retval = tty_check_change(tty);
+				if (retval)
+					return retval;
+				tty_wait_until_sent(tty, 0);
+				if (signal_pending(current))
+					return -EINTR;
+				send_break(info, arg ? arg*(HZ/10) : HZ/4);
+				if (signal_pending(current))
+					return -EINTR;
+			}
+			return 0;
+
+		case TIOCGSOFTCAR:
+			{
+				int tmp = C_CLOCAL(tty) ? 1 : 0;
+				if (copy_to_user((void *)arg, &tmp, sizeof(int)))
+					return -EFAULT;
+			}
+			return 0;
+
+		case TIOCSSOFTCAR:
+			{
+				int tmp;
+
+				if (copy_from_user(&tmp, (void *)arg, sizeof(int)))
+					return -EFAULT;
+
+				tty->termios->c_cflag =
+					((tty->termios->c_cflag & ~CLOCAL) |
+					 (tmp ? CLOCAL : 0));
+			}
+			return 0;
+#endif
+
+		case TIOCGSERIAL:
+			return get_serial_info(info, (struct serial_struct *) arg);
+
+		case TIOCSSERIAL:
+			return set_serial_info(info, (struct serial_struct *) arg);
+
+		case TIOCSERCONFIG:
+			return do_autoconfig(info);
+
+		case TIOCSERGETLSR: /* Get line status register */
+			return get_lsr_info(info, (unsigned short *) arg);
+
+		case TIOCSERGSTRUCT:
+			if (copy_to_user((dm270_async_t *) arg, info, sizeof(dm270_async_t))) {
+				return -EFAULT;
+			}
+			return 0;
+				
+		/* Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+		 * Return: write counters to the user passed counter struct
+		 * NB: both 1->0 and 0->1 transitions are counted except for
+		 *     RI where only 0->1 is counted.
+		 */
+
+		case TIOCGICOUNT:
+			{
+				int flags;
+
+				save_flags(flags); cli();
+				cnow = info->state->icount;
+				restore_flags(flags);
+
+				icount.cts         = cnow.cts;
+				icount.dsr         = cnow.dsr;
+				icount.rng         = cnow.rng;
+				icount.dcd         = cnow.dcd;
+				icount.rx          = cnow.rx;
+				icount.tx          = cnow.tx;
+				icount.frame       = cnow.frame;
+				icount.overrun     = cnow.overrun;
+				icount.parity      = cnow.parity;
+				icount.brk         = cnow.brk;
+				icount.buf_overrun = cnow.buf_overrun;
+
+				if (copy_to_user((void *)arg, &icount, sizeof(icount)))
+					return -EFAULT;
+			}
+			return 0;
+
+		case TIOCSERGWILD:
+		case TIOCSERSWILD:
+			{
+				/* "setserial -W" is called in Debian boot */
+
+				printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
+			}
+			return 0;
+
+		default:
+			return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	dm270_async_t *info = (dm270_async_t *)tty->driver_data;
+	unsigned int   cflag = tty->termios->c_cflag;
+
+	if ((cflag == old_termios->c_cflag) &&
+			(RELEVANT_IFLAG(tty->termios->c_iflag)
+			 == RELEVANT_IFLAG(old_termios->c_iflag))) {
+		return;
+	}
+
+	change_speed(info, old_termios);
+}
+
+/*-------------------------------------------------------------------------
+ * rs_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ *-------------------------------------------------------------------------*/
+
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+	dm270_async_t        *info = (dm270_async_t *)tty->driver_data;
+	dm270_serial_state_t *state;
+	unsigned long         flags;
+
+	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+		return;
+
+	state = info->state;
+	
+	save_flags(flags); cli();
+	
+	if (tty_hung_up_p(filp)) {
+		  MOD_DEC_USE_COUNT;
+		  restore_flags(flags);
+		  return;
+	}
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_close ttyS%d, count = %d\n", info->line, state->count);
+#endif
+	if ((tty->count == 1) && (state->count != 1)) {
+		/* Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  state->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+
+		printk(KERN_WARNING "rs_close: bad serial port count; tty->count is 1, "
+				"state->count is %d\n", state->count);
+		state->count = 1;
+	}
+
+	if (--state->count < 0) {
+		printk(KERN_WARNING "rs_close: bad serial port count for ttys%d: %d\n",
+				info->line, state->count);
+		state->count = 0;
+	}
+
+	if (state->count) {
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+
+	info->flags |= ASYNC_CLOSING;
+	restore_flags(flags);
+
+	/* Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+
+	if (info->flags & ASYNC_NORMAL_ACTIVE)
+		info->state->normal_termios = *tty->termios;
+
+	if (info->flags & ASYNC_CALLOUT_ACTIVE)
+		info->state->callout_termios = *tty->termios;
+
+	/* Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+
+	tty->closing = 1;
+	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+
+	/* At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+
+	serial_disable_rx_int(info);	
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		/* Before we drop DTR, make sure the UART transmitter
+		 * has completely drained; this is especially
+		 * important if there is a transmit FIFO!
+		 */
+
+		rs_wait_until_sent(tty, info->timeout);
+	}
+
+	shutdown(info);
+
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	
+	if (info->blocked_open) {
+		if (info->close_delay) {
+				set_current_state(TASK_INTERRUPTIBLE);
+				schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
+			ASYNC_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	MOD_DEC_USE_COUNT;
+}
+
+/* rs_wait_until_sent() --- wait until the transmitter is empty */
+
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	dm270_async_t *info = (dm270_async_t *)tty->driver_data;
+	unsigned long  orig_jiffies;
+	unsigned long  char_time;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent"))
+		return;
+
+	if (info->state->type == PORT_UNKNOWN)
+		return;
+
+	if (info->xmit_fifo_size <= 0)
+		return; /* Just in case.... */
+
+	orig_jiffies = jiffies;
+
+	/* Set the check interval to be 1/5 of the estimated time to
+	 * send a single character, and make it at least 1.  The check
+	 * interval should also be less than the timeout.
+	 * 
+	 * Note: we have to use pretty tight timings here to satisfy
+	 * the NIST-PCTS.
+	 */
+
+	char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
+	char_time = char_time / 5;
+
+	if (char_time == 0)
+		char_time = 1;
+
+	if (timeout && timeout < char_time)
+		char_time = timeout;
+
+	/* If the transmitter hasn't cleared in twice the approximate
+	 * amount of time to send the entire FIFO, it probably won't
+	 * ever clear.  This assumes the UART isn't doing flow
+	 * control, which is currently the case.  Hence, if it ever
+	 * takes longer than info->timeout, this is probably due to a
+	 * UART bug of some kind.  So, we clamp the timeout parameter at
+	 * 2*info->timeout.
+	 */
+
+	if (!timeout || timeout > 2*info->timeout)
+		timeout = 2*info->timeout;
+
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
+	printk("jiff=%lu...", jiffies);
+#endif
+	while (!serial_tx_fifo_is_empty(info)) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(char_time);
+		if (signal_pending(current))
+			break;
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			break;
+	}
+	set_current_state(TASK_RUNNING);
+}
+
+/* rs_hangup() --- called by tty_hangup() when a hangup is signaled. */
+
+static void rs_hangup(struct tty_struct *tty)
+{
+	dm270_async_t        *info  = (dm270_async_t *)tty->driver_data;
+	dm270_serial_state_t *state = info->state;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
+		return;
+
+	state = info->state;
+	
+	rs_flush_buffer(tty);
+	if (info->flags & ASYNC_CLOSING)
+		return;
+
+	shutdown(info);
+	info->event = 0;
+	state->count = 0;
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*-------------------------------------------------------------------------
+ * rs_open() and friends
+ *-------------------------------------------------------------------------*/
+
+static int block_til_ready(struct tty_struct *tty, struct file * filp,
+			   dm270_async_t *info)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	dm270_serial_state_t *state = info->state;
+	unsigned long	        flags;
+	int		        retval;
+	int		        do_clocal = 0;
+	int		        extra_count = 0;
+
+	/* If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+
+	if (tty_hung_up_p(filp) ||
+			(info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
+				-EAGAIN : -ERESTARTSYS);
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/* If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & ASYNC_NORMAL_ACTIVE)
+			return -EBUSY;
+
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+				(info->flags & ASYNC_SESSION_LOCKOUT) &&
+				(info->session != current->session))
+			return -EBUSY;
+
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+				(info->flags & ASYNC_PGRP_LOCKOUT) &&
+				(info->pgrp != current->pgrp))
+			return -EBUSY;
+
+		info->flags |= ASYNC_CALLOUT_ACTIVE;
+		return 0;
+	}
+	
+	/* If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+
+	if ((filp->f_flags & O_NONBLOCK) ||
+			(tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & ASYNC_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= ASYNC_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
+		if (state->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+
+	/* Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, state->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready before block: ttys%d, count = %d\n",
+			state->line, state->count);
+#endif
+	save_flags(flags); cli();
+	if (!tty_hung_up_p(filp)) {
+		extra_count = 1;
+		state->count--;
+	}
+
+	restore_flags(flags);
+	info->blocked_open++;
+
+	while (1) {
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		if (tty_hung_up_p(filp) ||
+				!(info->flags & ASYNC_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & ASYNC_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;	
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+				!(info->flags & ASYNC_CLOSING))
+			break;
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef SERIAL_DEBUG_OPEN
+		printk("block_til_ready blocking: ttys%d, count = %d\n",
+				info->line, state->count);
+#endif
+		schedule();
+	}
+
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&info->open_wait, &wait);
+	if (extra_count)
+		state->count++;
+	info->blocked_open--;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready after blocking: ttys%d, count = %d\n",
+			info->line, state->count);
+#endif
+	if (retval)
+		return retval;
+	info->flags |= ASYNC_NORMAL_ACTIVE;
+	return 0;
+}
+
+static int get_async_struct(int line, dm270_async_t **ret_info)
+{
+	dm270_async_t        *info;
+	dm270_serial_state_t *sstate;
+
+	sstate = rs_table + line;
+	sstate->count++;
+
+	if (sstate->info) {
+		*ret_info = (dm270_async_t*)sstate->info;
+		return 0;
+	}
+
+	info = kmalloc(sizeof(dm270_async_t), GFP_KERNEL);
+	if (!info) {
+		sstate->count--;
+		return -ENOMEM;
+	}
+
+	memset(info, 0, sizeof(dm270_async_t));
+
+	init_waitqueue_head(&info->open_wait);
+	init_waitqueue_head(&info->close_wait);
+	init_waitqueue_head(&info->delta_msr_wait);
+
+	info->magic           = SERIAL_MAGIC;
+	info->port            = sstate->port;
+	info->iomem_base      = sstate->iomem_base;
+	info->line            = line;
+	info->tqueue.routine  = do_softint;
+	info->tqueue.data     = info;
+
+	info->state           = sstate;
+	info->flags           = sstate->flags;
+	info->xmit_fifo_size  = sstate->xmit_fifo_size;
+
+	if (sstate->info) {
+		kfree(info);
+		*ret_info = (dm270_async_t*)sstate->info;
+		return 0;
+	}
+
+	sstate->info = info;
+	*ret_info    = info;
+	return 0;
+}
+
+/* This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+
+static int rs_open(struct tty_struct *tty, struct file * filp)
+{
+	dm270_async_t	*info;
+	unsigned long	 page;
+	int 		 retval;
+	int 		 line;
+
+	MOD_INC_USE_COUNT;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	if ((line < 0) || (line >= NR_PORTS)) {
+		MOD_DEC_USE_COUNT;
+		return -ENODEV;
+	}
+
+	retval = get_async_struct(line, &info);
+	if (retval) {
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+
+	tty->driver_data = info;
+	info->tty = tty;
+	if (serial_paranoia_check(info, tty->device, "rs_open")) {
+		MOD_DEC_USE_COUNT;		
+		return -ENODEV;
+	}
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+			info->state->count);
+#endif
+#if (LINUX_VERSION_CODE > 0x20100)
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+#endif
+
+	if (!tmp_buf) {
+		page = get_zeroed_page(GFP_KERNEL);
+		if (tmp_buf) {
+			free_page(page);
+		} else {
+			if (!page) {
+				MOD_DEC_USE_COUNT;
+				return -ENOMEM;
+			}
+			tmp_buf = (unsigned char*)page;
+		}
+	}
+
+	/* If the port is the middle of closing, bail out now */
+
+	if (tty_hung_up_p(filp) ||
+			(info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+		MOD_DEC_USE_COUNT;
+#ifdef SERIAL_DO_RESTART
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
+				-EAGAIN : -ERESTARTSYS);
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/* Start up serial port */
+
+	retval = startup(info);
+	if (retval) {
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("rs_open returning after block_til_ready with %d\n",
+				retval);
+#endif
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+
+	if ((info->state->count == 1) &&
+			(info->flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->state->normal_termios;
+		else 
+			*tty->termios = info->state->callout_termios;
+		change_speed(info, 0);
+	}
+#ifdef CONFIG_SERIAL_DM270_CONSOLE
+	if (sercons.cflag && sercons.index == line) {
+		tty->termios->c_cflag = sercons.cflag;
+		sercons.cflag = 0;
+		change_speed(info, 0);
+	}
+#endif
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open ttyS%d successful...", info->line);
+#endif
+	return 0;
+}
+
+/* /proc fs routines.... */
+
+static inline int line_info(char *buf, dm270_serial_state_t *state)
+{
+	dm270_async_t *info = state->info;
+	dm270_async_t scr_info;
+	char	stat_buf[30];
+	int	ret;
+
+	ret = sprintf(buf, "%d: uart:%s iomem:%lX irq:%d",
+			state->line, SERIAL_DRIVER_NAME,
+			state->iomem_base, state->irq);
+
+	if (!state->iomem_base) {
+		ret += sprintf(buf+ret, "\n");
+		return ret;
+	}
+
+	/* Figure out the current RS-232 lines */
+	if (!info) {
+		info = &scr_info;	/* This is just for serial_{in,out} */
+
+		info->magic = SERIAL_MAGIC;
+		info->port = state->port;
+		info->flags = state->flags;
+		info->baud = 0;
+		info->tty = 0;
+	}
+
+	stat_buf[0] = 0;
+	stat_buf[1] = 0;
+
+	if (info->baud) {
+		ret += sprintf(buf+ret, " baud:%d",
+				info->baud);
+	}
+
+	ret += sprintf(buf+ret, " tx:%d rx:%d",
+			state->icount.tx, state->icount.rx);
+
+	if (state->icount.frame)
+		ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
+	
+	if (state->icount.parity)
+		ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
+	
+	if (state->icount.brk)
+		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);	
+
+	if (state->icount.overrun)
+		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
+
+	/* Last thing is the RS-232 status lines */
+	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+	return ret;
+}
+
+#ifdef CONFIG_PROC_FS
+static int rs_read_proc(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	off_t begin = 0;
+	int len = 0;
+	int i;
+	int l;
+
+	len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
+	for (i = 0; i < NR_PORTS && len < 4000; i++) {
+		l = line_info(page + len, &rs_table[i]);
+		len += l;
+		if (len+begin > off+count)
+			goto done;
+		if (len+begin < off) {
+			begin += len;
+			len = 0;
+		}
+	}
+	*eof = 1;
+done:
+	if (off >= len+begin)
+		return 0;
+	*start = page + (begin-off);
+	return ((count < begin+len-off) ? count : begin+len-off);
+}
+#endif
+
+/* Basic UART init */
+
+static void autoconfig(dm270_serial_state_t *state)
+{
+	dm270_async_t *info;
+	dm270_async_t  scr_info;
+	unsigned long  flags;
+	unsigned short junk;
+
+#ifdef SERIAL_DEBUG_AUTOCONF
+	printk("Testing ttyS%d (0x%04lx, 0x%04x)...\n", state->line,
+			state->port, (unsigned) state->iomem_base);
+#endif
+	state->type           = PORT_DM270;
+
+	info                  = &scr_info;
+	info->magic           = SERIAL_MAGIC;
+	info->state           = state;
+	info->flags           = state->flags;
+	info->line            = state->line;
+	info->port            = state->port;
+	info->iomem_base      = state->iomem_base;
+
+	/* Skip re-configuration of the serial console. This way we won't
+	 * clobber the settings established for console printk's during boot.
+	 */
+
+#ifdef CONFIG_SERIAL_DM270_CONSOLE
+	if (state != async_sercons.state)
+#endif
+	{
+		save_flags(flags); cli();
+
+		serial_reset_chip(info);
+		serial_disable_ints(info, &junk);
+		serial_clear_fifos(info);
+		serial_disable_breaks(info);
+		serial_set_tx_trigger(info, DM270_UART_TFCR_TRG_1);
+		serial_set_rx_trigger(info, DM270_UART_RFCR_TRG_16);
+
+		restore_flags(flags);
+	}
+}
+
+/*-------------------------------------------------------------------------
+ * rs_init() and friends
+ *-------------------------------------------------------------------------*/
+
+/*
+ * This routine prints out the appropriate serial driver version
+ * number, and identifies which options were configured into this
+ * driver.
+ */
+
+static inline void show_serial_version(void)
+{
+ 	printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
+}
+
+/* The serial driver boot-time initialization code! */
+
+static int __init rs_init(void)
+{
+	dm270_serial_state_t* state;
+	int i;
+
+	init_bh(SERIAL_BH, do_serial_bh);
+#if defined(CONFIG_SERIAL_DM270_POLL) || defined(CONFIG_SERIAL_DM270_TIMEOUT_POLL)
+	init_timer(&serial_timer);
+	serial_timer.function = rs_timer;
+/*	mod_timer(&serial_timer, jiffies + RS_STROBE_TIME);*/
+#endif
+
+	for (i = 0; i < NR_IRQS; i++) {
+		IRQ_ports[i] = 0;
+		IRQ_timeout[i] = 0;
+	}
+
+#ifdef CONFIG_SERIAL_DM270_CONSOLE
+	/* The interrupt of the serial console port
+	 * can't be shared.
+	 */
+	if (sercons.flags & CON_CONSDEV) {
+		for(i = 0; i < NR_PORTS; i++)
+			if (i != sercons.index &&
+					rs_table[i].irq == rs_table[sercons.index].irq)
+				rs_table[i].irq = 0;
+	}
+#endif
+	show_serial_version();
+
+	/* Initialize the tty_driver structure */
+	
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	serial_driver.magic                = TTY_DRIVER_MAGIC;
+
+#if (LINUX_VERSION_CODE > 0x20100)
+	serial_driver.driver_name          = "serial";
+#endif
+
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	serial_driver.name                 = "tts/%d";
+#else
+	serial_driver.name                 = "ttyS";
+#endif
+
+	serial_driver.major                = TTY_MAJOR;
+	serial_driver.minor_start          = 64 + SERIAL_DEV_OFFSET;
+	serial_driver.num                  = NR_PORTS;
+	serial_driver.type                 = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype              = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios         = tty_std_termios;
+	serial_driver.init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
+	serial_driver.flags                = TTY_DRIVER_REAL_RAW|TTY_DRIVER_NO_DEVFS;
+	serial_driver.refcount             = &serial_refcount;
+	serial_driver.table                = serial_table;
+	serial_driver.termios              = serial_termios;
+	serial_driver.termios_locked       = serial_termios_locked;
+
+	serial_driver.open                 = rs_open;
+	serial_driver.close                = rs_close;
+	serial_driver.write                = rs_write;
+	serial_driver.put_char             = rs_put_char;
+	serial_driver.flush_chars          = rs_flush_chars;
+	serial_driver.write_room           = rs_write_room;
+	serial_driver.chars_in_buffer      = rs_chars_in_buffer;
+	serial_driver.flush_buffer         = rs_flush_buffer;
+	serial_driver.ioctl                = rs_ioctl;
+	serial_driver.throttle             = rs_throttle;
+	serial_driver.unthrottle           = rs_unthrottle;
+	serial_driver.set_termios          = rs_set_termios;
+	serial_driver.stop                 = rs_stop;
+	serial_driver.start                = rs_start;
+	serial_driver.hangup               = rs_hangup;
+
+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
+	serial_driver.break_ctl            = rs_break;
+#endif
+
+#if (LINUX_VERSION_CODE >= 131343)
+	serial_driver.send_xchar           = rs_send_xchar;
+	serial_driver.wait_until_sent      = rs_wait_until_sent;
+#ifdef CONFIG_PROC_FS
+	serial_driver.read_proc            = rs_read_proc;
+#else
+	serial_driver.read_proc            = 0;
+#endif
+#endif
+
+	/* The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+
+	callout_driver                     = serial_driver;
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	callout_driver.name                = "cua/%d";
+#else
+	callout_driver.name                = "cua";
+#endif
+	callout_driver.major               = TTYAUX_MAJOR;
+	callout_driver.subtype             = SERIAL_TYPE_CALLOUT;
+#if (LINUX_VERSION_CODE >= 131343)
+	callout_driver.read_proc           = 0;
+	callout_driver.proc_entry          = 0;
+#endif
+
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register serial driver\n");
+
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+	
+	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
+		state->magic                   = SSTATE_MAGIC;
+		state->line                    = i;
+		state->custom_divisor          = 0;
+		state->close_delay             = 5*HZ/10;
+		state->closing_wait            = 30*HZ;
+		state->callout_termios         = callout_driver.init_termios;
+		state->normal_termios          = serial_driver.init_termios;
+
+		state->icount.cts              = 0;
+		state->icount.dsr              = 0;
+		state->icount.rng              = 0;
+		state->icount.dcd              = 0;
+		state->icount.rx               = 0;
+		state->icount.tx               = 0;
+		state->icount.frame            = 0; 
+		state->icount.parity           = 0;
+		state->icount.overrun          = 0;
+		state->icount.brk              = 0;
+
+		state->irq                     = irq_cannonicalize(state->irq);
+		state->xmit_fifo_size          = DM270_UART_TXFIFO_BYTESIZE;
+
+		if (state->type == PORT_UNKNOWN) {
+			/* Configure the serial port. */
+			autoconfig(state);
+		}
+
+		printk(KERN_INFO "ttyS%02d at 0x%04lx (irq = %d)\n",
+				state->line + SERIAL_DEV_OFFSET,
+				state->iomem_base,
+				state->irq);
+
+		tty_register_devfs(&serial_driver, 0,
+				serial_driver.minor_start + state->line);
+
+		tty_register_devfs(&callout_driver, 0,
+				callout_driver.minor_start + state->line);
+	}
+
+	return 0;
+}
+
+static void __exit rs_fini(void) 
+{
+	dm270_async_t *info;
+	unsigned long flags;
+	int e1;
+	int e2;
+	int i;
+
+#if defined(CONFIG_SERIAL_DM270_POLL) || defined(CONFIG_SERIAL_DM270_TIMEOUT_POLL)
+	del_timer_sync(&serial_timer);
+#endif
+	save_flags(flags); cli();
+        remove_bh(SERIAL_BH);
+	if ((e1 = tty_unregister_driver(&serial_driver)))
+		printk(KERN_WARNING "serial: failed to unregister serial driver (%d)\n",
+		       e1);
+	if ((e2 = tty_unregister_driver(&callout_driver)))
+		printk(KERN_WARNING "serial: failed to unregister callout driver (%d)\n", 
+		       e2);
+	restore_flags(flags);
+
+	for (i = 0; i < NR_PORTS; i++) {
+		if ((info = rs_table[i].info)) {
+			rs_table[i].info = NULL;
+			kfree(info);
+		}
+	}
+	if (tmp_buf) {
+		unsigned long pg = (unsigned long) tmp_buf;
+		tmp_buf = NULL;
+		free_page(pg);
+	}
+}
+
+module_init(rs_init);
+module_exit(rs_fini);
+
+MODULE_DESCRIPTION("TI TMS320DM270 serial driver");
+MODULE_AUTHOR("Chee Tim Loh <cheetim_loh@innomedia.com.sg>, based on serial_c5471 by Todd Fischer");
+MODULE_LICENSE("GPL");
+
+/*-------------------------------------------------------------------------
+ * Serial Console Driver
+ *-------------------------------------------------------------------------*/
+
+#ifdef CONFIG_SERIAL_DM270_CONSOLE
+
+/* This block is enabled when the user has used `make xconfig`
+ * to enable kernel printk() to come out the serial port.
+ * The register_console(serial_console_print) call below
+ * is what hooks in our serial output routine here with the
+ * kernel's printk output.
+ */
+
+/* Print a string to the serial port trying not to disturb
+ * any possible real use of the port...
+ *
+ * The console_lock must be held when we get here.
+ */
+
+static inline void wait_for_xmitr(dm270_async_t *info)
+{
+	int tmp;
+	for (tmp = 1000000 ; tmp > 0 ; tmp--)
+		if (serial_room_in_tx_fifo(info))
+			break;
+}
+
+static void serial_console_write(struct console *co, const char *s,
+				unsigned count)
+{
+	static dm270_async_t *info = &async_sercons;
+	unsigned short        msr;
+	unsigned int          i;
+
+	/* First save the MSR then disable the interrupts */
+	serial_disable_ints(info, &msr);
+
+	/* Now, do each character */
+	for (i = 0; i < count; i++, s++) {
+		wait_for_xmitr(info);
+		serial_char_out(info, *s);
+		if (*s == 10) {
+			/* LF? add CR */
+
+			wait_for_xmitr(info);
+			serial_char_out(info, 13);
+		}
+	}
+
+	/* Finally, wait for transmitter & holding register to empty */
+	wait_for_xmitr(info);
+	serial_restore_ints(info, msr);
+}
+
+static kdev_t serial_console_device(struct console *co)
+{
+	return MKDEV(TTY_MAJOR, 64 + co->index);
+}
+
+/* Setup initial baud/bits/parity. We do two things here:
+ * - construct a cflag setting for the first rs_open()
+ * - initialize the serial port
+ * Return non-zero if we didn't find a serial port.
+ */
+
+static int __init serial_console_setup(struct console *co, char *options)
+{
+	static dm270_async_t *info;
+	dm270_serial_state_t *state;
+
+	unsigned short  cval   = 0;
+	int             baud   = DEFAULT_CONSOLE_BAUD;
+	int             bits   = DEFAULT_CONSOLE_BITS;
+	int             parity = DEFAULT_CONSOLE_PARITY;
+	int             cflag  = CREAD | HUPCL | CLOCAL;
+	char           *s;
+	unsigned short  junk;
+
+	if (co->index < 0 || co->index >= NR_PORTS) {
+		return -1;
+	}
+	if (options) {
+		baud = simple_strtoul(options, NULL, 10);
+		s = options;
+		while(*s >= '0' && *s <= '9')
+			s++;
+		if (*s) parity = *s++;
+		if (*s) bits   = *s - '0';
+	}
+
+	SHOWVALUE(baud);
+
+	/*
+	 *	Now construct a cflag setting.
+	 */
+	switch(baud) {
+		case 1200:
+			cflag |= B1200;
+			break;
+		case 2400:
+			cflag |= B2400;
+			break;
+		case 4800:
+			cflag |= B4800;
+			break;
+		case 19200:
+			cflag |= B19200;
+			break;
+		case 38400:
+			cflag |= B38400;
+			break;
+		case 57600:
+			cflag |= B57600;
+			break;
+		case 115200:
+			cflag |= B115200;
+			break;
+		case 9600:
+		default:
+			cflag |= B9600;
+			break;
+	}
+
+	cval = 0;
+
+	SHOWVALUE(bits);
+
+	switch(bits) {
+		case 7:
+			cflag |= CS7;
+			cval  |= DM270_UART_MSR_7_DBITS;
+			break;
+
+		default:
+		case 8:
+			cflag |= CS8;
+			cval  |= DM270_UART_MSR_8_DBITS;
+			break;
+	}
+
+	SHOWVALUE(parity);
+
+	switch(parity) {
+		case 'o': case 'O':
+			cflag |= (PARENB | PARODD);
+			cval  |= DM270_UART_MSR_ODD_PARITY;
+			break;
+		case 'e': case 'E':
+			cflag |= PARENB;
+			cval  |= DM270_UART_MSR_EVEN_PARITY;
+			break;
+	}
+
+	if (cflag & CSTOPB)
+		cval |= DM270_UART_MSR_2_SBITS;
+	else
+		cval |= DM270_UART_MSR_1_SBITS;
+
+	SHOWVALUE(cval);
+
+	co->cflag             = cflag;
+
+	state                 = rs_table + co->index;
+	state->type           = PORT_DM270;
+	info                  = &async_sercons;
+	info->magic           = SERIAL_MAGIC;
+	info->state           = state;
+	info->flags           = state->flags;
+	info->line            = co->index;
+	info->port            = state->port;
+	info->iomem_base      = state->iomem_base;
+	info->xmit_fifo_size  = state->xmit_fifo_size;
+
+	serial_reset_chip(info);
+	serial_save_registers(info);
+	serial_disable_ints(info, &junk);
+	serial_clear_fifos(info);
+	serial_set_rate(info, baud);
+	serial_set_mode(info, cval);
+
+	return 0;
+}
+
+/* Register console */
+
+void __init dm270_console_init(void)
+{
+	register_console(&sercons);
+}
+
+#endif /* CONFIG_SERIAL_DM270_CONSOLE */
diff -urN linux-2.4.29/drivers/char/serial_dsc21.c linux-2.4.29-uc1/drivers/char/serial_dsc21.c
--- linux-2.4.29/drivers/char/serial_dsc21.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_dsc21.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,2380 @@
+/*
+ *  linux/drivers/char/serial_dsc21.c
+ *
+ *  Copyright (C) 2001
+ * Author: RidgeRun, Inc.
+ *          gmcnutt@ridgerun.com
+ *  
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 
+ * 		1998, 1999  Theodore Ts'o
+ *
+ *  Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92.  Now
+ *  much more extensible to support other serial cards based on the
+ *  16450/16550A UART's.  Added support for the AST FourPort and the
+ *  Accent Async board.  
+ *
+ *  set_serial_info fixed to set the flags, custom divisor, and uart
+ * 	type fields.  Fix suggested by Michael K. Johnson 12/12/92.
+ *
+ *  11/95: TIOCMIWAIT, TIOCGICOUNT by Angelo Haritsis <ah@doc.ic.ac.uk>
+ *
+ *  03/96: Modularised by Angelo Haritsis <ah@doc.ic.ac.uk>
+ *
+ *  rs_set_termios fixed to look also for changes of the input
+ *      flags INPCK, BRKINT, PARMRK, IGNPAR and IGNBRK.
+ *                                            Bernd Anhäupl 05/17/96.
+ *
+ *  1/97:  Extended dumb serial ports are a config option now.  
+ *         Saves 4k.   Michael A. Griffith <grif@acm.org>
+ * 
+ *  8/97: Fix bug in rs_set_termios with RTS
+ *        Stanislav V. Voronyi <stas@uanet.kharkov.ua>
+ *
+ *  3/98: Change the IRQ detection, use of probe_irq_o*(),
+ *	  supress TIOCSERGWILD and TIOCSERSWILD
+ *	  Etienne Lorrain <etienne.lorrain@ibm.net>
+ *
+ *  4/98: Added changes to support the ARM architecture proposed by
+ * 	  Russell King
+ *
+ *  5/99: Updated to include support for the XR16C850 and ST16C654
+ *        uarts.  Stuart MacDonald <stuartm@connecttech.com>
+ *
+ *  8/99: Generalized PCI support added.  Theodore Ts'o
+ * 
+ *  3/00: Rid circular buffer of redundant xmit_cnt.  Fix a
+ *	  few races on freeing buffers too.
+ *	  Alan Modra <alan@linuxcare.com>
+ *
+ *  5/00: Support for the RSA-DV II/S card added.
+ *	  Kiyokazu SUTO <suto@ks-and-ks.ne.jp>
+ * 
+ *  6/00: Remove old-style timer, use timer_list
+ *        Andrew Morton <andrewm@uow.edu.au>
+ *
+ *  7/00: Support Timedia/Sunix/Exsys PCI cards
+ *
+ *  7/00: fix some returns on failure not using MOD_DEC_USE_COUNT.
+ *	  Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This module exports the following rs232 io functions:
+ *
+ *	int rs_init(void);
+ */
+
+
+
+
+/*
+ * Serial driver configuration section.  Here are the various options:
+ *
+ * SERIAL_PARANOIA_CHECK
+ * 		Check the magic number for the dsc21_async_structure where
+ * 		ever possible.
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+
+#undef SERIAL_PARANOIA_CHECK
+#define CONFIG_SERIAL_NOPAUSE_IO
+#define SERIAL_DO_RESTART
+
+/* Set of debugging defines */
+
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+#undef SERIAL_DEBUG_PCI
+#undef SERIAL_DEBUG_AUTOCONF
+
+//#define SERIAL_DSC21_INLINE inline
+#define SERIAL_DSC21_INLINE
+
+/* Sanity checks */
+
+
+#ifdef MODULE
+#undef CONFIG_SERIAL_DSC21_CONSOLE
+#endif
+
+#define RS_ISR_PASS_LIMIT 256
+
+
+#ifdef MODVERSIONS
+#include <linux/modversions.h>
+#endif
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+//#include <linux/serial_reg.h>
+#include <asm/serial.h>
+#define LOCAL_VERSTRING ""
+
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/malloc.h>
+#if (LINUX_VERSION_CODE >= 131343)
+#include <linux/init.h>
+#endif
+#if (LINUX_VERSION_CODE >= 131336)
+#include <asm/uaccess.h>
+#endif
+#include <linux/delay.h>
+#ifdef CONFIG_SERIAL_DSC21_CONSOLE
+#include <linux/console.h>
+#endif
+#ifdef CONFIG_MAGIC_SYSRQ
+#include <linux/sysrq.h>
+#endif
+
+/*
+ * All of the compatibilty code so we can compile serial.c against
+ * older kernels is hidden in serial_compat.h
+ */
+#if defined(LOCAL_HEADERS) || (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */
+#include "serial_compat.h"
+#endif
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+
+#define SERIAL_DEV_OFFSET	0
+
+
+
+
+static DECLARE_TASK_QUEUE(tq_serial);
+
+static struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+/* serial subtype definitions */
+#ifndef SERIAL_TYPE_NORMAL
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+#endif
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+/*
+ * IRQ_timeout		- How long the timeout should be for each IRQ
+ * 				should be after the IRQ has been active.
+ */
+
+static struct dsc21_async_struct *IRQ_ports[NR_IRQS];
+static int IRQ_timeout[NR_IRQS];
+#ifdef CONFIG_SERIAL_DSC21_CONSOLE
+static struct console sercons;
+
+#endif
+#if defined(CONFIG_SERIAL_DSC21_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+static unsigned long break_pressed; /* break, really ... */
+#endif
+
+static void autoconfig(struct serial_state * state);
+static void change_speed(struct dsc21_async_struct *info, struct termios *old);
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
+
+/*
+ * Here we define the default xmit fifo size used for each type of
+ * UART
+ */
+static struct serial_uart_config uart_config[] = {
+	{ "unknown", 1, 0 }, 
+	{ "8250", 1, 0 }, 
+	{ "16450", 1, 0 }, 
+	{ "16550", 1, 0 }, 
+	{ "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO }, 
+	{ "cirrus", 1, 0 }, 	/* usurped by cyclades.c */
+	{ "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH }, 
+	{ "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO |
+		  UART_STARTECH }, 
+	{ "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO},
+	{ "Startech", 1, 0},	/* usurped by cyclades.c */
+	{ "16C950/954", 128, UART_CLEAR_FIFO | UART_USE_FIFO},
+	{ "ST16654", 64, UART_CLEAR_FIFO | UART_USE_FIFO |
+		  UART_STARTECH }, 
+	{ "XR16850", 128, UART_CLEAR_FIFO | UART_USE_FIFO |
+		  UART_STARTECH },
+	{ "RSA", 2048, UART_CLEAR_FIFO | UART_USE_FIFO },
+	{ "DSC21", 32, UART_CLEAR_FIFO | UART_USE_FIFO },
+	{ 0, 0}
+};
+
+static struct serial_state rs_table[RS_TABLE_SIZE] = {
+	SERIAL_PORT_DFNS	/* Defined in serial.h */
+};
+
+#define NR_PORTS	(sizeof(rs_table)/sizeof(struct serial_state))
+#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
+
+static struct tty_struct *serial_table[NR_PORTS];
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
+
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the copy_from_user blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static unsigned char *tmp_buf;
+#ifdef DECLARE_MUTEX
+static DECLARE_MUTEX(tmp_buf_sem);
+#else
+static struct semaphore tmp_buf_sem = MUTEX;
+#endif
+
+static SERIAL_DSC21_INLINE unsigned int serial_in(struct dsc21_async_struct *info, 
+					 int offset)
+{
+	return inw(info->iomem_base + (offset<<info->iomem_reg_shift));
+}
+
+static SERIAL_DSC21_INLINE void serial_out(struct dsc21_async_struct *info, int offset,
+				  int value)
+{
+	outw(value, (unsigned long) info->iomem_base +
+	     (offset<<info->iomem_reg_shift));
+}
+
+static SERIAL_DSC21_INLINE void serial_dsc21_disable_tx_int(struct dsc21_async_struct *info)
+{
+	info->MSR &= ~UART_MSR_TFTIE;
+	serial_out(info, UART_MSR, info->MSR);
+}
+
+static SERIAL_DSC21_INLINE void serial_dsc21_disable_rx_int(struct dsc21_async_struct *info)
+{
+	info->MSR &= ~UART_MSR_RFTIE;
+	serial_out(info, UART_MSR, info->MSR);
+}
+
+static SERIAL_DSC21_INLINE void serial_dsc21_enable_tx_int(struct dsc21_async_struct *info)
+{
+	info->MSR |= UART_MSR_TFTIE;
+	serial_out(info, UART_MSR, info->MSR);
+}
+
+static SERIAL_DSC21_INLINE void serial_dsc21_enable_rx_int(struct dsc21_async_struct *info)
+{
+	info->MSR |= UART_MSR_RFTIE;
+	serial_out(info, UART_MSR, info->MSR);
+}
+
+static SERIAL_DSC21_INLINE void serial_dsc21_disable_ints(struct dsc21_async_struct *info,
+					     u16 *msr)
+{
+	*msr = info->MSR & UART_MSR_INTS;
+	info->MSR &= ~UART_MSR_INTS;
+	serial_out(info, UART_MSR, info->MSR);
+}
+
+static SERIAL_DSC21_INLINE void serial_dsc21_restore_ints(struct dsc21_async_struct *info,
+					     u16 msr)
+{
+	info->MSR |= msr & UART_MSR_INTS;
+	serial_out(info, UART_MSR, info->MSR);
+}
+
+static SERIAL_DSC21_INLINE void serial_dsc21_clear_fifos(struct dsc21_async_struct *info)
+{
+	serial_out(info, UART_RFCR, 0x8000);
+	serial_out(info, UART_TFCR, 0x8000);
+}
+
+static SERIAL_DSC21_INLINE void serial_dsc21_disable_breaks(struct dsc21_async_struct *info)
+{
+	info->LCR &= ~UART_LCR_BOC;
+	serial_out(info, UART_LCR, info->LCR);
+}
+static SERIAL_DSC21_INLINE void serial_dsc21_enable_breaks(struct dsc21_async_struct *info)
+{
+	info->LCR |= UART_LCR_BOC;
+	serial_out(info, UART_LCR, info->LCR);
+}
+static SERIAL_DSC21_INLINE void 
+serial_dsc21_set_rate(struct dsc21_async_struct *info, u16 rate)
+{
+	serial_out(info, UART_BRSR, rate);
+}
+static SERIAL_DSC21_INLINE void serial_dsc21_set_mode(struct dsc21_async_struct *info,
+					 u16 mode)
+{
+	info->MSR &= ~UART_MSR_MODE_BITS;
+	info->MSR |= mode;
+	serial_out(info, UART_MSR, info->MSR);
+}
+static SERIAL_DSC21_INLINE void serial_dsc21_set_rx_trigger(struct dsc21_async_struct *info,
+					       u16 val)
+{
+	serial_out(info, UART_RFCR, val);
+}
+static SERIAL_DSC21_INLINE void serial_dsc21_set_tx_trigger(struct dsc21_async_struct *info,
+					       u16 val)
+{
+	serial_out(info, UART_TFCR, val);
+}
+static SERIAL_DSC21_INLINE void serial_dsc21_out(
+	struct dsc21_async_struct *info, u8 val)
+{
+	serial_out(info, UART_DTRR, val);
+}
+static SERIAL_DSC21_INLINE u8 serial_dsc21_in(struct dsc21_async_struct *info)
+{
+	return serial_in(info, UART_DTRR);
+}
+static SERIAL_DSC21_INLINE u16 serial_dsc21_status(struct dsc21_async_struct *info)
+{
+	return serial_in(info, UART_SR);
+}
+static SERIAL_DSC21_INLINE u8 serial_dsc21_data_available(struct dsc21_async_struct *info)
+{
+	return ((serial_in(info, UART_SR) & UART_SR_RFNEF) != 0);
+}
+static SERIAL_DSC21_INLINE u8 serial_dsc21_tx_fifo_empty(struct dsc21_async_struct *info)
+{
+	return ((serial_in(info, UART_SR) & UART_SR_TREF) == 0);
+}
+static SERIAL_DSC21_INLINE u8 serial_dsc21_room_in_tx_fifo(
+	struct dsc21_async_struct *info)
+{
+	return ((serial_in(info, UART_SR) & UART_SR_TFTI) != 0);
+}
+
+static SERIAL_DSC21_INLINE int serial_paranoia_check(struct dsc21_async_struct *info,
+					kdev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%s) in %s\n";
+	static const char *badinfo =
+		"Warning: null dsc21_async_struct for (%s) in %s\n";
+
+	if (!info) {
+		printk(badinfo, kdevname(device), routine);
+		return 1;
+	}
+	if (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, kdevname(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+static void rs_stop(struct tty_struct *tty)
+{
+	struct dsc21_async_struct *info = (struct dsc21_async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_stop"))
+		return;
+
+	save_flags(flags); cli();
+	if (info->MSR & UART_MSR_TFTIE) serial_dsc21_disable_tx_int(info);
+	restore_flags(flags);
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+	struct dsc21_async_struct *info = (struct dsc21_async_struct *)tty->driver_data;
+	unsigned long flags;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_start"))
+		return;
+	
+	save_flags(flags); cli();
+
+	if (info->xmit.head != info->xmit.tail
+	    && info->xmit.buf
+	    && !(info->MSR & UART_MSR_TFTIE))
+		serial_dsc21_enable_tx_int(info);
+
+	restore_flags(flags);
+}
+
+static SERIAL_DSC21_INLINE void rs_sched_event(struct dsc21_async_struct *info,
+				  int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_serial);
+	mark_bh(SERIAL_BH);
+}
+
+static SERIAL_DSC21_INLINE void receive_chars(struct dsc21_async_struct *info,
+				 int *status, struct pt_regs * regs)
+{
+	struct tty_struct *tty = info->tty;
+	unsigned char ch;
+
+	struct	async_icount *icount;
+
+	icount = &info->state->icount;
+
+	do {
+		ch = serial_dsc21_in(info);
+
+		if (tty->flip.count < TTY_FLIPBUF_SIZE) {
+			*tty->flip.char_buf_ptr = ch;
+			*tty->flip.flag_buf_ptr = 0;
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;			
+			icount->rx++;
+		}
+
+		*status = serial_dsc21_status(info);
+
+	} while (*status & UART_SR_RFNEF);
+
+#if (LINUX_VERSION_CODE > 131394) /* 2.1.66 */
+	tty_flip_buffer_push(tty);
+#else
+	queue_task(&tty->flip.tqueue, &tq_timer);
+#endif	
+}
+
+static SERIAL_DSC21_INLINE void transmit_chars(struct dsc21_async_struct *info,
+					       int *intr_done)
+{
+	int count;
+
+	if (info->x_char) {
+		serial_dsc21_out(info, info->x_char);
+		info->state->icount.tx++;
+		info->x_char = 0;
+		if (intr_done)
+			*intr_done = 0;
+		return;
+	}
+	if (info->xmit.head == info->xmit.tail
+	    || info->tty->stopped
+	    || info->tty->hw_stopped) {
+		serial_dsc21_disable_tx_int(info);
+		return;
+	}
+
+	// send while we still have data & room in the fifo
+	count = 32 - (serial_in(info, UART_TFCR) & 0x3f);
+	do {
+		while(count--) {
+			serial_dsc21_out(info, 
+					 info->xmit.buf[info->xmit.tail]);
+			info->xmit.tail = (info->xmit.tail + 1) & 
+				(SERIAL_XMIT_SIZE-1);
+			info->state->icount.tx++;
+			if (info->xmit.head == info->xmit.tail)
+				goto done;
+		}
+
+		count = 32 - (serial_in(info, UART_TFCR) & 0x3f);
+	
+	} while(count);
+	
+ done:
+	if (CIRC_CNT(info->xmit.head,
+		     info->xmit.tail,
+		     SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+	if (intr_done) *intr_done = 0;
+
+	if (info->xmit.head == info->xmit.tail)
+		serial_dsc21_disable_tx_int(info);
+}
+
+static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
+{
+	int status;
+	int pass_counter = 0;
+	struct dsc21_async_struct * info;
+	
+
+	info = IRQ_ports[irq];
+	if (!info || !info->tty)
+		return;
+
+	do {
+		status = serial_dsc21_status(info);
+		if (status & UART_SR_RFTI) receive_chars(info, &status, regs);
+		if (status & UART_SR_TFTI) transmit_chars(info, 0);
+		if (pass_counter++ > RS_ISR_PASS_LIMIT) break;
+
+	} while (serial_dsc21_data_available(info));
+
+	info->last_active = jiffies;
+}
+
+
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct dsc21_async_struct	*info = (struct dsc21_async_struct *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+		wake_up_interruptible(&tty->poll_wait);
+#endif
+	}
+}
+
+#ifdef CONFIG_SERIAL_DSC21_TIMER /*******************************************/
+#define RS_STROBE_TIME (10*HZ)
+static struct timer_list serial_timer;
+static SERIAL_DSC21_INLINE void rs_start_timer(int val)
+{
+	mod_timer(&serial_timer, jiffies + val);
+}
+static SERIAL_DSC21_INLINE void rs_del_timer()
+{
+	del_timer_sync(&serial_timer);
+}
+static void rs_timer(unsigned long dummy)
+{
+	/* Don't need this, and it muddies the waters while debugging.
+	 * --gmcnutt
+	 */
+	static unsigned long last_strobe;
+	struct dsc21_async_struct *info;
+	unsigned int	i;
+	unsigned long flags;
+
+	if ((jiffies - last_strobe) >= RS_STROBE_TIME) {
+		for (i=0; i < NR_IRQS; i++) {
+			info = IRQ_ports[i];
+			if (!info)
+				continue;
+			save_flags(flags); cli();
+				rs_interrupt_single(i, NULL, NULL);
+			restore_flags(flags);
+		}
+	}
+	last_strobe = jiffies;
+	rs_start_timer(RS_STROBE_TIME);
+
+	if (IRQ_ports[0]) {
+		save_flags(flags); cli();
+		rs_interrupt_single(0, NULL, NULL);
+  		restore_flags(flags);
+		rs_start_timer(IRQ_timeout[0]);
+	}
+}
+static SERIAL_DSC21_INLINE void rs_init_timer()
+{
+	init_timer(&serial_timer);
+	serial_timer.function = rs_timer;
+	rs_start_timer(RS_STROBE_TIME);
+}
+#else
+#define rs_start_timer(val)
+#define rs_init_timer()
+#define rs_del_timer()
+#endif/* CONFIG_SERIAL_DSC21_TIMER  *****************************************/
+/*
+ * This routine figures out the correct timeout for a particular IRQ.
+ * It uses the smallest timeout of all of the serial ports in a
+ * particular interrupt chain.  Now only used for IRQ 0....
+ */
+static void figure_IRQ_timeout(int irq)
+{
+	struct	dsc21_async_struct	*info;
+	int	timeout = 60*HZ;	/* 60 seconds === a long time :-) */
+
+	info = IRQ_ports[irq];
+	if (!info) {
+		IRQ_timeout[irq] = 60*HZ;
+		return;
+	}
+	while (info) {
+		if (info->timeout < timeout)
+			timeout = info->timeout;
+		info = info->next_port;
+	}
+	if (!irq)
+		timeout = timeout / 2;
+	IRQ_timeout[irq] = (timeout > 3) ? timeout-2 : 1;
+}
+
+
+static int startup(struct dsc21_async_struct * info)
+{
+	unsigned long flags;
+	int	retval=0;
+	void (*handler)(int, void *, struct pt_regs *);
+	struct serial_state *state= info->state;
+	unsigned long page;
+	u16 junk;
+
+	page = get_zeroed_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	save_flags(flags); cli();
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		free_page(page);
+		goto errout;
+	}
+
+	if (!CONFIGURED_SERIAL_PORT(state) || !state->type) {
+		if (info->tty)
+			set_bit(TTY_IO_ERROR, &info->tty->flags);
+		free_page(page);
+		goto errout;
+	}
+	if (info->xmit.buf)
+		free_page(page);
+	else
+		info->xmit.buf = (unsigned char *) page;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttys%d (irq %d)...", info->line, state->irq);
+#endif
+
+	serial_dsc21_disable_ints(info, &junk);
+	serial_dsc21_clear_fifos(info);
+	serial_dsc21_disable_breaks(info);
+	
+	/*
+	 * Allocate the IRQ if necessary
+	 */
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			retval = -EBUSY;
+			goto errout;
+		} else 
+			handler = rs_interrupt_single;
+
+		retval = request_irq(state->irq, handler, SA_SHIRQ,
+				     "serial", &IRQ_ports[state->irq]);
+		if (retval) {
+			if (capable(CAP_SYS_ADMIN)) {
+				if (info->tty)
+					set_bit(TTY_IO_ERROR,
+						&info->tty->flags);
+				retval = 0;
+			}
+			goto errout;
+		}
+	}
+
+	/*
+	 * Insert serial port into IRQ chain.
+	 */
+	info->prev_port = 0;
+	info->next_port = IRQ_ports[state->irq];
+	if (info->next_port)
+		info->next_port->prev_port = info;
+	IRQ_ports[state->irq] = info;
+	figure_IRQ_timeout(state->irq);
+
+	
+	/*
+	 * Finally, enable interrupts
+	 */
+	serial_dsc21_enable_rx_int(info);
+	
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit.head = info->xmit.tail = 0;
+
+	/*
+	 * Set up serial timers...
+	 */
+	rs_start_timer(2*HZ/100);
+
+	/*
+	 * Set up the tty->alt_speed kludge
+	 */
+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
+	if (info->tty) {
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+			info->tty->alt_speed = 57600;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+			info->tty->alt_speed = 115200;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+			info->tty->alt_speed = 230400;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+			info->tty->alt_speed = 460800;
+	}
+#endif
+	
+	/*
+	 * and set the speed of the serial port
+	 */
+//	info->tty->termios->c_cflag &= ~CBAUD;
+//	info->tty->termios->c_cflag |= B57600;
+	change_speed(info, 0);
+
+	info->flags |= ASYNC_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+	
+errout:
+	restore_flags(flags);
+	return retval;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct dsc21_async_struct * info)
+{
+	unsigned long	flags;
+	struct serial_state *state;
+	int		retval;
+	u16 msr;
+
+	if (!(info->flags & ASYNC_INITIALIZED))
+		return;
+
+	state = info->state;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Shutting down serial port %d (irq %d)....", info->line,
+	       state->irq);
+#endif
+	
+	save_flags(flags); cli(); /* Disable interrupts */
+
+	/*
+	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+	 * here so the queue might never be waken up
+	 */
+	wake_up_interruptible(&info->delta_msr_wait);
+	
+	/*
+	 * First unlink the serial port from the IRQ chain...
+	 */
+	if (info->next_port)
+		info->next_port->prev_port = info->prev_port;
+	if (info->prev_port)
+		info->prev_port->next_port = info->next_port;
+	else
+		IRQ_ports[state->irq] = info->next_port;
+	figure_IRQ_timeout(state->irq);
+	
+	/*
+	 * Free the IRQ, if necessary
+	 */
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			free_irq(state->irq, &IRQ_ports[state->irq]);
+			retval = request_irq(state->irq, rs_interrupt_single,
+					     SA_SHIRQ, "serial",
+					     &IRQ_ports[state->irq]);
+			
+			if (retval)
+				printk("serial shutdown: request_irq: error %d"
+				       "  Couldn't reacquire IRQ.\n", retval);
+		} else
+			free_irq(state->irq, &IRQ_ports[state->irq]);
+	}
+
+	if (info->xmit.buf) {
+		unsigned long pg = (unsigned long) info->xmit.buf;
+		info->xmit.buf = 0;
+		free_page(pg);
+	}
+
+	serial_dsc21_disable_ints(info, &msr);
+
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~ASYNC_INITIALIZED;
+	restore_flags(flags);
+}
+
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+static int baud_table[] = {
+	0, 50, 75, 110, 134, 150, 200, 300,
+	600, 1200, 1800, 2400, 4800, 9600, 19200,
+	38400, 57600, 115200, 230400, 460800, 0 };
+
+static int tty_get_baud_rate(struct tty_struct *tty)
+{
+	struct dsc21_async_struct * info = 
+		(struct dsc21_async_struct *)tty->driver_data;
+	unsigned int cflag, i;
+
+	cflag = tty->termios->c_cflag;
+
+	i = cflag & CBAUD;
+	if (i & CBAUDEX) {
+		i &= ~CBAUDEX;
+		if (i < 1 || i > 2) 
+			tty->termios->c_cflag &= ~CBAUDEX;
+		else
+			i += 15;
+	}
+	if (i == 15) {
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+			i += 1;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+			i += 2;
+	}
+	return baud_table[i];
+}
+#endif
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void change_speed(struct dsc21_async_struct *info,
+			 struct termios *old_termios)
+{
+	int	quot = 0, baud_base, baud;
+	unsigned cflag, cval = 0;
+	int	bits;
+	unsigned long	flags;
+
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+	if (!CONFIGURED_SERIAL_PORT(info))
+		return;
+
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	case CS7: cval = 0x01; bits = 9; break;
+	case CS8: cval = 0x00; bits = 10; break;
+	default:  cval = 0x00; bits = 7; break;
+	}
+
+	if (cflag & CSTOPB) {
+		cval |= 0x04;
+		bits++;
+	}
+	if (cflag & PARENB) {
+		cval |= UART_MSR_PEB;
+		bits++;
+	}
+	if (cflag & PARODD)
+		cval |= UART_MSR_PSB;
+
+	/* Determine divisor based on baud rate */
+	baud = tty_get_baud_rate(info->tty);
+	if (!baud)
+		baud = 9600;	/* B0 transition handled in rs_set_termios */
+	baud_base = info->state->baud_base;
+	if (baud == 38400 &&
+	    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+		quot = info->state->custom_divisor;
+	else {
+		if (baud == 134)
+			/* Special case since 134 is really 134.5 */
+			quot = (2*baud_base / 269);
+		else if (baud)
+			quot = (baud_base / baud) - 1;
+	}
+	/* If the quotient is zero refuse the change */
+	if (!quot && old_termios) {
+		info->tty->termios->c_cflag &= ~CBAUD;
+		info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD);
+		baud = tty_get_baud_rate(info->tty);
+		if (!baud)
+			baud = 9600;
+		if (baud == 38400 &&
+		    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+			quot = info->state->custom_divisor;
+		else {
+			if (baud == 134)
+				/* Special case since 134 is really 134.5 */
+				quot = (2*baud_base / 269);
+			else if (baud)
+				quot = (baud_base / baud) - 1;
+		}
+	}
+	/* As a last resort, if the quotient is zero, default to 9600 bps */
+	if (!quot)
+		quot = (baud_base / 9600) - 1;
+	
+	info->quot = quot;
+	info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base);
+	info->timeout += HZ/50;		/* Add .02 seconds of slop */
+
+	/*
+	 * Set up parity check flag
+	 */
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+
+       	save_flags(flags); cli();
+
+	serial_dsc21_set_rate(info, quot);
+	serial_dsc21_set_mode(info, cval);
+
+	/*
+	 * We should always set the receive FIFO trigger to the lowest value
+	 * because we don't poll.
+	 * --gmcnutt
+	 */
+	serial_dsc21_set_rx_trigger(info, UART_FCR_FTL1);
+
+	restore_flags(flags);
+}
+
+static void rs_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	struct dsc21_async_struct *info = (struct dsc21_async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_put_char"))
+		return;
+
+	if (!tty || !info->xmit.buf)
+		return;
+
+	save_flags(flags); cli();
+	if (CIRC_SPACE(info->xmit.head,
+		       info->xmit.tail,
+		       SERIAL_XMIT_SIZE) == 0) {
+		restore_flags(flags);
+		return;
+	}
+
+	info->xmit.buf[info->xmit.head] = ch;
+	info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
+	restore_flags(flags);
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct dsc21_async_struct *info = (struct dsc21_async_struct *)tty->driver_data;
+	unsigned long flags;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
+		return;
+
+	if (info->xmit.head == info->xmit.tail
+	    || tty->stopped
+	    || tty->hw_stopped
+	    || !info->xmit.buf)
+		return;
+
+	save_flags(flags); cli();
+	serial_dsc21_enable_tx_int(info);
+	restore_flags(flags);
+}
+
+static int rs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	int	c, ret = 0;
+	struct dsc21_async_struct *info = (struct dsc21_async_struct *)tty->driver_data;
+	unsigned long flags;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_write"))
+		return 0;
+
+	if (!tty || !info->xmit.buf || !tmp_buf)
+		return 0;
+
+	save_flags(flags);
+	if (from_user) {
+		down(&tmp_buf_sem);
+		while (1) {
+			int c1;
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					      info->xmit.tail,
+					      SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0)
+				break;
+
+			c -= copy_from_user(tmp_buf, buf, c);
+			if (!c) {
+				if (!ret)
+					ret = -EFAULT;
+				break;
+			}
+			cli();
+			c1 = CIRC_SPACE_TO_END(info->xmit.head,
+					       info->xmit.tail,
+					       SERIAL_XMIT_SIZE);
+			if (c1 < c)
+				c = c1;
+			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			restore_flags(flags);
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		up(&tmp_buf_sem);
+	} else {
+		cli();
+		while (1) {
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					      info->xmit.tail,
+					      SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0) {
+				break;
+			}
+			memcpy(info->xmit.buf + info->xmit.head, buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		restore_flags(flags);
+	}
+	if (info->xmit.head != info->xmit.tail
+	    && !tty->stopped
+	    && !tty->hw_stopped) {
+		if (serial_dsc21_room_in_tx_fifo(info)) {
+			transmit_chars(info, 0);
+		}
+		serial_dsc21_enable_tx_int(info);
+	}
+
+	return ret;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct dsc21_async_struct *info = (struct dsc21_async_struct *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
+		return 0;
+	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct dsc21_async_struct *info = (struct dsc21_async_struct *)tty->driver_data;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+		return 0;
+	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	struct dsc21_async_struct *info = (struct dsc21_async_struct *)tty->driver_data;
+	unsigned long flags;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+		return;
+	save_flags(flags); cli();
+	info->xmit.head = info->xmit.tail = 0;
+	restore_flags(flags);
+	wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+	wake_up_interruptible(&tty->poll_wait);
+#endif
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void rs_send_xchar(struct tty_struct *tty, char ch)
+{
+	struct dsc21_async_struct *info = (struct dsc21_async_struct *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_send_char"))
+		return;
+
+	info->x_char = ch;
+	if (ch) serial_dsc21_enable_tx_int(info);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int get_serial_info(struct dsc21_async_struct * info,
+			   struct serial_struct * retinfo)
+{
+	struct serial_struct tmp;
+	struct serial_state *state = info->state;
+   
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = state->type;
+	tmp.line = state->line;
+	tmp.port = state->port;
+	if (HIGH_BITS_OFFSET)
+		tmp.port_high = state->port >> HIGH_BITS_OFFSET;
+	else
+		tmp.port_high = 0;
+	tmp.irq = state->irq;
+	tmp.flags = state->flags;
+	tmp.xmit_fifo_size = state->xmit_fifo_size;
+	tmp.baud_base = state->baud_base;
+	tmp.close_delay = state->close_delay;
+	tmp.closing_wait = state->closing_wait;
+	tmp.custom_divisor = state->custom_divisor;
+	tmp.hub6 = state->hub6;
+	tmp.io_type = state->io_type;
+	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
+		return -EFAULT;
+	return 0;
+}
+
+static int set_serial_info(struct dsc21_async_struct * info,
+			   struct serial_struct * new_info)
+{
+	struct serial_struct new_serial;
+ 	struct serial_state old_state, *state;
+	unsigned int		i,change_irq,change_port;
+	int 			retval = 0;
+	unsigned long		new_port;
+
+	if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
+		return -EFAULT;
+	state = info->state;
+	old_state = *state;
+
+	new_port = new_serial.port;
+	if (HIGH_BITS_OFFSET)
+		new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
+
+	change_irq = new_serial.irq != state->irq;
+	change_port = (new_port != ((int) state->port)) ||
+		(new_serial.hub6 != state->hub6);
+  
+	if (!capable(CAP_SYS_ADMIN)) {
+		if (change_irq || change_port ||
+		    (new_serial.baud_base != state->baud_base) ||
+		    (new_serial.type != state->type) ||
+		    (new_serial.close_delay != state->close_delay) ||
+		    (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
+		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
+		     (state->flags & ~ASYNC_USR_MASK)))
+			return -EPERM;
+		state->flags = ((state->flags & ~ASYNC_USR_MASK) |
+			       (new_serial.flags & ASYNC_USR_MASK));
+		info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+			       (new_serial.flags & ASYNC_USR_MASK));
+		state->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	new_serial.irq = irq_cannonicalize(new_serial.irq);
+
+	if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || 
+	    (new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) ||
+	    (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) ||
+	    (new_serial.type == PORT_STARTECH)) {
+		return -EINVAL;
+	}
+
+	if ((new_serial.type != state->type) ||
+	    (new_serial.xmit_fifo_size <= 0))
+		new_serial.xmit_fifo_size =
+			uart_config[new_serial.type].dfl_xmit_fifo_size;
+
+	/* Make sure address is not already in use */
+	if (new_serial.type) {
+		for (i = 0 ; i < NR_PORTS; i++)
+			if ((state != &rs_table[i]) &&
+			    (rs_table[i].port == new_port) &&
+			    rs_table[i].type)
+				return -EADDRINUSE;
+	}
+
+	if ((change_port || change_irq) && (state->count > 1))
+		return -EBUSY;
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+	state->baud_base = new_serial.baud_base;
+	state->flags = ((state->flags & ~ASYNC_FLAGS) |
+			(new_serial.flags & ASYNC_FLAGS));
+	info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
+		       (info->flags & ASYNC_INTERNAL_FLAGS));
+	state->custom_divisor = new_serial.custom_divisor;
+	state->close_delay = new_serial.close_delay * HZ/100;
+	state->closing_wait = new_serial.closing_wait * HZ/100;
+#if (LINUX_VERSION_CODE > 0x20100)
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+#endif
+	info->xmit_fifo_size = state->xmit_fifo_size =
+		new_serial.xmit_fifo_size;
+
+	if ((state->type != PORT_UNKNOWN) && state->port) {
+		release_region(state->port,8);
+	}
+	state->type = new_serial.type;
+	if (change_port || change_irq) {
+		/*
+		 * We need to shutdown the serial port at the old
+		 * port/irq combination.
+		 */
+		shutdown(info);
+		state->irq = new_serial.irq;
+		info->port = state->port = new_port;
+	}
+	if ((state->type != PORT_UNKNOWN) && state->port) {
+			request_region(state->port,8,"serial(set)");
+	}
+
+	
+check_and_exit:
+	if (!state->port || !state->type)
+		return 0;
+	if (info->flags & ASYNC_INITIALIZED) {
+		if (((old_state.flags & ASYNC_SPD_MASK) !=
+		     (state->flags & ASYNC_SPD_MASK)) ||
+		    (old_state.custom_divisor != state->custom_divisor)) {
+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+				info->tty->alt_speed = 57600;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+				info->tty->alt_speed = 115200;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+				info->tty->alt_speed = 230400;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+				info->tty->alt_speed = 460800;
+#endif
+			change_speed(info, 0);
+		}
+	} else
+		retval = startup(info);
+	return retval;
+}
+
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space. 
+ */
+static int get_lsr_info(struct dsc21_async_struct * info, unsigned int *value)
+{
+	unsigned char status;
+	unsigned int result;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	status = serial_dsc21_status(info);
+	restore_flags(flags);
+	result = ((status & UART_SR_TREF) ? TIOCSER_TEMT : 0);
+
+	/*
+	 * If we're about to load something into the transmit
+	 * register, we'll pretend the transmitter isn't empty to
+	 * avoid a race condition (depending on when the transmit
+	 * interrupt happens).
+	 */
+	if (info->x_char || 
+	    ((CIRC_CNT(info->xmit.head, info->xmit.tail,
+		       SERIAL_XMIT_SIZE) > 0) &&
+	     !info->tty->stopped && !info->tty->hw_stopped))
+		result &= TIOCSER_TEMT;
+
+	if (copy_to_user(value, &result, sizeof(int)))
+		return -EFAULT;
+	return 0;
+}
+
+
+static int do_autoconfig(struct dsc21_async_struct * info)
+{
+	int retval;
+	
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	
+	if (info->state->count > 1)
+		return -EBUSY;
+	
+	shutdown(info);
+	autoconfig(info->state);
+	retval = startup(info);
+
+	if (retval)
+		return retval;
+	return 0;
+}
+
+/*
+ * rs_break() --- routine which turns the break handling on or off
+ */
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+static void send_break(	struct dsc21_async_struct * info, int duration)
+{
+	if (!CONFIGURED_SERIAL_PORT(info))
+		return;
+	current->state = TASK_INTERRUPTIBLE;
+	current->timeout = jiffies + duration;
+	cli();
+	serial_dsc21_enable_breaks(info);
+	schedule();
+	serial_dsc21_disable_breaks(info);
+	sti();
+}
+#else
+static void rs_break(struct tty_struct *tty, int break_state)
+{
+	struct dsc21_async_struct * info = (struct dsc21_async_struct *)tty->driver_data;
+	unsigned long flags;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_break"))
+		return;
+
+	if (!CONFIGURED_SERIAL_PORT(info))
+		return;
+	save_flags(flags); cli();
+	if (break_state == -1)
+		serial_dsc21_enable_breaks(info);
+	else
+		serial_dsc21_disable_breaks(info);
+	restore_flags(flags);
+}
+#endif
+
+
+static int rs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	struct dsc21_async_struct * info = (struct dsc21_async_struct *)tty->driver_data;
+	struct async_icount cnow;	/* kernel counter temps */
+	struct serial_icounter_struct icount;
+	unsigned long flags;
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+	int retval, tmp;
+#endif
+	
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+	
+	switch (cmd) {
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+		case TCSBRK:	/* SVID version: non-zero arg --> no break */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (signal_pending(current))
+				return -EINTR;
+			if (!arg) {
+				send_break(info, HZ/4);	/* 1/4 second */
+				if (signal_pending(current))
+					return -EINTR;
+			}
+			return 0;
+		case TCSBRKP:	/* support for POSIX tcsendbreak() */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (signal_pending(current))
+				return -EINTR;
+			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+			if (signal_pending(current))
+				return -EINTR;
+			return 0;
+		case TIOCGSOFTCAR:
+			tmp = C_CLOCAL(tty) ? 1 : 0;
+			if (copy_to_user((void *)arg, &tmp, sizeof(int)))
+				return -EFAULT;
+			return 0;
+		case TIOCSSOFTCAR:
+			if (copy_from_user(&tmp, (void *)arg, sizeof(int)))
+				return -EFAULT;
+
+			tty->termios->c_cflag =
+				((tty->termios->c_cflag & ~CLOCAL) |
+				 (tmp ? CLOCAL : 0));
+			return 0;
+#endif
+		case TIOCGSERIAL:
+			return get_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSSERIAL:
+			return set_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSERCONFIG:
+			return do_autoconfig(info);
+
+		case TIOCSERGETLSR: /* Get line status register */
+			return get_lsr_info(info, (unsigned int *) arg);
+
+		case TIOCSERGSTRUCT:
+			if (copy_to_user((struct dsc21_async_struct *) arg,
+					 info, sizeof(struct dsc21_async_struct)))
+				return -EFAULT;
+			return 0;
+				
+		/* 
+		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+		 * Return: write counters to the user passed counter struct
+		 * NB: both 1->0 and 0->1 transitions are counted except for
+		 *     RI where only 0->1 is counted.
+		 */
+		case TIOCGICOUNT:
+			save_flags(flags); cli();
+			cnow = info->state->icount;
+			restore_flags(flags);
+			icount.cts = cnow.cts;
+			icount.dsr = cnow.dsr;
+			icount.rng = cnow.rng;
+			icount.dcd = cnow.dcd;
+			icount.rx = cnow.rx;
+			icount.tx = cnow.tx;
+			icount.frame = cnow.frame;
+			icount.overrun = cnow.overrun;
+			icount.parity = cnow.parity;
+			icount.brk = cnow.brk;
+			icount.buf_overrun = cnow.buf_overrun;
+			
+			if (copy_to_user((void *)arg, &icount, sizeof(icount)))
+				return -EFAULT;
+			return 0;
+		case TIOCSERGWILD:
+		case TIOCSERSWILD:
+			/* "setserial -W" is called in Debian boot */
+			printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
+			return 0;
+
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	struct dsc21_async_struct *info = 
+		(struct dsc21_async_struct *)tty->driver_data;
+
+	unsigned int cflag = tty->termios->c_cflag;
+	
+	if (   (cflag == old_termios->c_cflag)
+	    && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
+		== RELEVANT_IFLAG(old_termios->c_iflag)))
+	  return;
+
+	change_speed(info, old_termios);
+		
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+	struct dsc21_async_struct * info = (struct dsc21_async_struct *)tty->driver_data;
+	struct serial_state *state;
+	unsigned long flags;
+
+	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+		return;
+
+	state = info->state;
+	
+	save_flags(flags); cli();
+	
+	if (tty_hung_up_p(filp)) {
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+	
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
+#endif
+	if ((tty->count == 1) && (state->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  state->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+		       "state->count is %d\n", state->count);
+		state->count = 1;
+	}
+	if (--state->count < 0) {
+		printk("rs_close: bad serial port count for ttys%d: %d\n",
+		       info->line, state->count);
+		state->count = 0;
+	}
+	if (state->count) {
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= ASYNC_CLOSING;
+	restore_flags(flags);
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & ASYNC_NORMAL_ACTIVE)
+		info->state->normal_termios = *tty->termios;
+	if (info->flags & ASYNC_CALLOUT_ACTIVE)
+		info->state->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+	serial_dsc21_disable_rx_int(info);
+
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		/*
+		 * Before we drop DTR, make sure the UART transmitter
+		 * has completely drained; this is especially
+		 * important if there is a transmit FIFO!
+		 */
+		rs_wait_until_sent(tty, info->timeout);
+	}
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
+			 ASYNC_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	MOD_DEC_USE_COUNT;
+}
+
+/*
+ * rs_wait_until_sent() --- wait until the transmitter is empty
+ */
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	struct dsc21_async_struct * info = (struct dsc21_async_struct *)tty->driver_data;
+	unsigned long orig_jiffies, char_time;
+
+	
+	if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent"))
+		return;
+
+	if (info->state->type == PORT_UNKNOWN)
+		return;
+
+	if (info->xmit_fifo_size == 0)
+		return; /* Just in case.... */
+
+	orig_jiffies = jiffies;
+	/*
+	 * Set the check interval to be 1/5 of the estimated time to
+	 * send a single character, and make it at least 1.  The check
+	 * interval should also be less than the timeout.
+	 * 
+	 * Note: we have to use pretty tight timings here to satisfy
+	 * the NIST-PCTS.
+	 */
+	char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
+	char_time = char_time / 5;
+	if (char_time == 0)
+		char_time = 1;
+	if (timeout && timeout < char_time)
+		char_time = timeout;
+	/*
+	 * If the transmitter hasn't cleared in twice the approximate
+	 * amount of time to send the entire FIFO, it probably won't
+	 * ever clear.  This assumes the UART isn't doing flow
+	 * control, which is currently the case.  Hence, if it ever
+	 * takes longer than info->timeout, this is probably due to a
+	 * UART bug of some kind.  So, we clamp the timeout parameter at
+	 * 2*info->timeout.
+	 */
+	if (!timeout || timeout > 2*info->timeout)
+		timeout = 2*info->timeout;
+
+	while (!serial_dsc21_tx_fifo_empty(info)) {
+		
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(char_time);
+		if (signal_pending(current))
+			break;
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			break;
+	}
+	set_current_state(TASK_RUNNING);
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void rs_hangup(struct tty_struct *tty)
+{
+	struct dsc21_async_struct * info = (struct dsc21_async_struct *)tty->driver_data;
+	struct serial_state *state = info->state;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
+		return;
+
+	state = info->state;
+	
+	rs_flush_buffer(tty);
+	if (info->flags & ASYNC_CLOSING)
+		return;
+	shutdown(info);
+	info->event = 0;
+	state->count = 0;
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file * filp,
+			   struct dsc21_async_struct *info)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	struct serial_state *state = info->state;
+	int		retval;
+	int		do_clocal = 0, extra_count = 0;
+	unsigned long	flags;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & ASYNC_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+		    return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+		    return -EBUSY;
+		info->flags |= ASYNC_CALLOUT_ACTIVE;
+		return 0;
+	}
+	
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & ASYNC_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= ASYNC_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
+		if (state->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+	
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, state->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready before block: ttys%d, count = %d\n",
+	       state->line, state->count);
+#endif
+	save_flags(flags); cli();
+	if (!tty_hung_up_p(filp)) {
+		extra_count = 1;
+		state->count--;
+	}
+	restore_flags(flags);
+	info->blocked_open++;
+	while (1) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (tty_hung_up_p(filp) ||
+		    !(info->flags & ASYNC_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & ASYNC_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;	
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    !(info->flags & ASYNC_CLOSING))
+			break;
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef SERIAL_DEBUG_OPEN
+		printk("block_til_ready blocking: ttys%d, count = %d\n",
+		       info->line, state->count);
+#endif
+		schedule();
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&info->open_wait, &wait);
+	if (extra_count)
+		state->count++;
+	info->blocked_open--;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready after blocking: ttys%d, count = %d\n",
+	       info->line, state->count);
+#endif
+	if (retval)
+		return retval;
+	info->flags |= ASYNC_NORMAL_ACTIVE;
+	return 0;
+}
+
+static int get_dsc21_async_struct(int line, 
+				  struct dsc21_async_struct **ret_info)
+{
+	struct dsc21_async_struct *info;
+	struct serial_state *sstate;
+
+	sstate = rs_table + line;
+	sstate->count++;
+	if (sstate->info) {
+		*ret_info = (struct dsc21_async_struct *)sstate->info;
+		return 0;
+	}
+	info = kmalloc(sizeof(struct dsc21_async_struct), GFP_KERNEL);
+	if (!info) {
+		sstate->count--;
+		return -ENOMEM;
+	}
+	memset(info, 0, sizeof(struct dsc21_async_struct));
+	init_waitqueue_head(&info->open_wait);
+	init_waitqueue_head(&info->close_wait);
+	init_waitqueue_head(&info->delta_msr_wait);
+	info->magic = SERIAL_MAGIC;
+	info->port = sstate->port;
+	info->flags = sstate->flags;
+	info->io_type = sstate->io_type;
+	info->iomem_base = sstate->iomem_base;
+	info->iomem_reg_shift = sstate->iomem_reg_shift;
+	info->xmit_fifo_size = sstate->xmit_fifo_size;
+	info->line = line;
+	info->tqueue.routine = do_softint;
+	info->tqueue.data = info;
+	info->state = sstate;
+	if (sstate->info) {
+		kfree(info);
+		*ret_info = (struct dsc21_async_struct *)sstate->info;
+		return 0;
+	}
+	sstate->info = (struct async_struct *)info;
+	*ret_info = info;
+	return 0;
+}
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+static int rs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct dsc21_async_struct	*info;
+	int 			retval, line;
+	unsigned long		page;
+
+	MOD_INC_USE_COUNT;
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	if ((line < 0) || (line >= NR_PORTS)) {
+		MOD_DEC_USE_COUNT;
+		return -ENODEV;
+	}
+	retval = get_dsc21_async_struct(line, &info);
+	if (retval) {
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+	tty->driver_data = info;
+	info->tty = tty;
+	if (serial_paranoia_check(info, tty->device, "rs_open")) {
+		MOD_DEC_USE_COUNT;		
+		return -ENODEV;
+	}
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+	       info->state->count);
+#endif
+#if (LINUX_VERSION_CODE > 0x20100)
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+#endif
+
+	if (!tmp_buf) {
+		page = get_zeroed_page(GFP_KERNEL);
+		if (tmp_buf)
+			free_page(page);
+		else {
+			if (!page) {
+				MOD_DEC_USE_COUNT;
+				return -ENOMEM;
+			}
+			tmp_buf = (unsigned char *) page;
+		}
+	}
+
+	/*
+	 * If the port is the middle of closing, bail out now
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+		MOD_DEC_USE_COUNT;
+#ifdef SERIAL_DO_RESTART
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval) {
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("rs_open returning after block_til_ready with %d\n",
+		       retval);
+#endif
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+
+	if ((info->state->count == 1) &&
+	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->state->normal_termios;
+		else 
+			*tty->termios = info->state->callout_termios;
+		change_speed(info, 0);
+	}
+#ifdef CONFIG_SERIAL_DSC21_CONSOLE
+	if (sercons.cflag && sercons.index == line) {
+		tty->termios->c_cflag = sercons.cflag;
+		sercons.cflag = 0;
+		change_speed(info, 0);
+	}
+#endif
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open ttys%d successful...", info->line);
+#endif
+	return 0;
+}
+
+
+/* basic UART init */
+static void autoconfig(struct serial_state * state)
+{
+	struct dsc21_async_struct *info, scr_info;
+	unsigned long flags;
+	u16 mrs;
+
+	if (!CONFIGURED_SERIAL_PORT(state))
+		return;
+		
+	state->type = PORT_DSC21;
+
+	info = &scr_info;
+
+	info->magic = SERIAL_MAGIC;
+	info->state = state;
+	info->port = state->port;
+	info->flags = state->flags;
+	info->io_type = state->io_type;
+	info->iomem_base = state->iomem_base;
+	info->iomem_reg_shift = state->iomem_reg_shift;
+
+	save_flags(flags); cli();
+	
+	serial_dsc21_disable_ints(info, &mrs);
+	serial_dsc21_clear_fifos(info);
+	serial_dsc21_disable_breaks(info);
+	serial_dsc21_set_tx_trigger(info, UART_FCR_FTL1);
+	serial_dsc21_set_rx_trigger(info, UART_FCR_FTL1);
+
+	restore_flags(flags);
+}
+
+/* bootup module init */
+static int __init rs_init(void)
+{
+	int i;
+	struct serial_state * state;
+
+	init_bh(SERIAL_BH, do_serial_bh);
+	rs_init_timer();
+
+	for (i = 0; i < NR_IRQS; i++) {
+		IRQ_ports[i] = 0;
+		IRQ_timeout[i] = 0;
+	}
+
+	/* Initialize the tty_driver structure */
+	
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+#if (LINUX_VERSION_CODE > 0x20100)
+	serial_driver.driver_name = "serial";
+#endif
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	serial_driver.name = "tts/%d";
+#else
+	serial_driver.name = "ttyS";
+#endif
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64 + SERIAL_DEV_OFFSET;
+	serial_driver.num = NR_PORTS;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+	serial_driver.init_termios.c_cflag =
+		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = rs_open;
+	serial_driver.close = rs_close;
+	serial_driver.write = rs_write;
+	serial_driver.put_char = rs_put_char;
+	serial_driver.flush_chars = rs_flush_chars;
+	serial_driver.write_room = rs_write_room;
+	serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	serial_driver.flush_buffer = rs_flush_buffer;
+	serial_driver.ioctl = rs_ioctl;
+//	serial_driver.throttle = 0;
+//	serial_driver.unthrottle = 0;
+	serial_driver.set_termios = rs_set_termios;
+	serial_driver.stop = rs_stop;
+	serial_driver.start = rs_start;
+	serial_driver.hangup = rs_hangup;
+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
+	serial_driver.break_ctl = rs_break;
+#endif
+#if (LINUX_VERSION_CODE >= 131343)
+	serial_driver.send_xchar = rs_send_xchar;
+	serial_driver.wait_until_sent = rs_wait_until_sent;
+#ifdef CONFIG_PROCFS
+	serial_driver.read_proc = rs_read_proc;
+#else
+	serial_driver.read_proc = 0;
+#endif
+#endif
+	
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	callout_driver.name = "cua/%d";
+#else
+	callout_driver.name = "cua";
+#endif
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+#if (LINUX_VERSION_CODE >= 131343)
+	callout_driver.read_proc = 0;
+	callout_driver.proc_entry = 0;
+#endif
+
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register serial driver\n");
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+	
+	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
+		state->magic = SSTATE_MAGIC;
+		state->line = i;
+		state->custom_divisor = 0;
+		state->close_delay = 5*HZ/10;
+		state->closing_wait = 30*HZ;
+		state->callout_termios = callout_driver.init_termios;
+		state->normal_termios = serial_driver.init_termios;
+		state->icount.cts = state->icount.dsr = 
+			state->icount.rng = state->icount.dcd = 0;
+		state->icount.rx = state->icount.tx = 0;
+		state->icount.frame = state->icount.parity = 0;
+		state->icount.overrun = state->icount.brk = 0;
+		state->irq = irq_cannonicalize(state->irq);
+
+		if (state->port && check_region(state->port, 12))
+			continue;
+
+		autoconfig(state);
+
+		printk(KERN_INFO "ttyS%02d at 0x%04lx (irq = %d)\n",
+		       state->line + SERIAL_DEV_OFFSET, state->iomem_base, 
+		       state->irq);
+
+		tty_register_devfs(&serial_driver, 0,
+				   serial_driver.minor_start + state->line);
+		tty_register_devfs(&callout_driver, 0,
+				   callout_driver.minor_start + state->line);
+	}
+	
+	return 0;
+}
+
+module_init(rs_init);
+
+
+
+
+#ifdef CONFIG_REVISIT
+#error Blow this away?
+static void __exit rs_fini(void) 
+{
+	unsigned long flags;
+	int e1, e2;
+	int i;
+	struct dsc21_async_struct *info;
+
+	/* printk("Unloading %s: version %s\n", serial_name, serial_version); */
+	rs_del_timer();
+	save_flags(flags); cli();
+        remove_bh(SERIAL_BH);
+	if ((e1 = tty_unregister_driver(&serial_driver)))
+		printk("serial: failed to unregister serial driver (%d)\n",
+		       e1);
+	if ((e2 = tty_unregister_driver(&callout_driver)))
+		printk("serial: failed to unregister callout driver (%d)\n", 
+		       e2);
+	restore_flags(flags);
+
+	for (i = 0; i < NR_PORTS; i++) {
+		if ((info = rs_table[i].info)) {
+			rs_table[i].info = NULL;
+			kfree(info);
+		}
+		if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) {
+				release_region(rs_table[i].port, 8);
+		}
+	}
+	if (tmp_buf) {
+		unsigned long pg = (unsigned long) tmp_buf;
+		tmp_buf = NULL;
+		free_page(pg);
+	}
+}
+module_exit(rs_fini);
+MODULE_DESCRIPTION("DSC21 serial driver");
+MODULE_AUTHOR("Gordon McNutt <gmcnutt@ridgerun.com>, based on the original by Theodore T'so");
+#endif
+
+/*
+ * ------------------------------------------------------------
+ * Serial console driver
+ * ------------------------------------------------------------
+ */
+#ifdef CONFIG_SERIAL_DSC21_CONSOLE
+
+static struct dsc21_async_struct async_sercons;
+
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ *
+ *	The console_lock must be held when we get here.
+ */
+static SERIAL_DSC21_INLINE void wait_for_xmitr(struct dsc21_async_struct *info)
+{
+	int tmp = 1000;
+	while(!serial_dsc21_room_in_tx_fifo(info)) if (!--tmp) break;
+}
+
+static void serial_console_write(struct console *co, const char *s,
+				unsigned count)
+{
+	static struct dsc21_async_struct *info = &async_sercons;
+	u16 ier;
+	unsigned i;
+
+	serial_dsc21_disable_ints(info, &ier);
+
+	// HACK!
+	// Somebody seems to be disrupting the LCR register causing
+	// our bytes not to go out. Try this to see if it fixes it.
+	// --gmcnutt
+	serial_dsc21_disable_breaks(info);
+
+	for (i = 0; i < count; i++, s++) {
+		wait_for_xmitr(info);
+		serial_dsc21_out(info, *s);
+		if (*s == 10) { // LF? add CR
+			wait_for_xmitr(info);
+			serial_dsc21_out(info, 13);
+		}
+	}
+
+	wait_for_xmitr(info);
+	serial_dsc21_restore_ints(info, ier);
+}
+
+static kdev_t serial_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static int __init serial_console_setup(struct console *co, char *options)
+{
+	static struct dsc21_async_struct *info;
+	struct serial_state *state;
+	unsigned cval = 0;
+	int     baud = 115200;
+	int	bits = 8;
+	int	parity = 'e';
+	int	cflag = CREAD | HUPCL | CLOCAL;
+	int	quot = 0;
+	char	*s;
+	u16 junk;
+
+	if (options) {
+		baud = simple_strtoul(options, NULL, 10);
+		s = options;
+		while(*s >= '0' && *s <= '9')
+			s++;
+		if (*s) parity = *s++;
+		if (*s) bits   = *s - '0';
+	}
+	switch(baud) {
+		case 1200:
+			cflag |= B1200;
+			break;
+		case 2400:
+			cflag |= B2400;
+			break;
+		case 4800:
+			cflag |= B4800;
+			break;
+		case 19200:
+			cflag |= B19200;
+			break;
+		case 38400:
+			cflag |= B38400;
+			break;
+		case 57600:
+			cflag |= B57600;
+			break;
+		case 115200:
+			cflag |= B115200;
+			break;
+		case 9600:
+		default:
+			cflag |= B9600;
+			break;
+	}
+	switch(bits) {
+		case 7:
+			cflag |= CS7;
+			break;
+		default:
+		case 8:
+			cflag |= CS8;
+			break;
+	}
+	switch(parity) {
+		case 'o': case 'O':
+			cflag |= (PARODD|PARENB);
+			break;
+		case 'e': case 'E':
+			cflag |= PARENB;
+			break;
+	}
+
+	co->cflag = cflag;
+
+	state = rs_table + co->index;
+
+	info = &async_sercons;
+	info->magic = SERIAL_MAGIC;
+	info->state = state;
+	info->port = state->port;
+	info->flags = state->flags;
+	info->io_type = state->io_type;
+	info->iomem_base = state->iomem_base;
+	info->iomem_reg_shift = state->iomem_reg_shift;
+
+	quot = (state->baud_base / baud) - 1;
+
+	if ((cflag & CSIZE) == CS7)
+		cval = UART_MSR_CLS;
+	if (cflag & PARENB)
+		cval |= UART_MSR_PEB;
+	if ((cflag & PARODD))
+		cval |= UART_MSR_PSB;
+
+	serial_dsc21_disable_ints(info, &junk);
+	serial_dsc21_clear_fifos(info);
+	serial_dsc21_disable_breaks(info);
+	serial_dsc21_set_rate(info, quot);
+	serial_dsc21_set_mode(info, cval);
+
+	return 0;
+}
+
+static struct console sercons = {
+	name:		"ttyS",
+	write:		serial_console_write,
+	device:		serial_console_device,
+	setup:		serial_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+/*
+ *	Register console.
+ */
+void __init serial_dsc21_console_init(void)
+{
+	register_console(&sercons);
+}
+#endif
+
+/*
+  Local variables:
+  compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce -march=i586 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h   -DEXPORT_SYMTAB -c serial.c"
+  End:
+*/
diff -urN linux-2.4.29/drivers/char/serial_isil.c linux-2.4.29-uc1/drivers/char/serial_isil.c
--- linux-2.4.29/drivers/char/serial_isil.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_isil.c	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,2457 @@
+/* $Header$
+ *
+ *  linux/drivers/char/serial_isil.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997,
+ * 		1998, 1999  Theodore Ts'o
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  Heavily based on serial.c version 5.05a.
+ */
+
+static char *serial_version = "1.0";
+static char *serial_revdate = "2002-07-11";
+
+
+#include <linux/config.h>
+#include <linux/version.h>
+
+/* Set of debugging defines */
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+#undef SERIAL_DEBUG_PCI
+#undef SERIAL_DEBUG_AUTOCONF
+
+#ifdef MODULE
+#undef CONFIG_SERIAL_CONSOLE
+#endif
+
+#define RS_ISR_PASS_LIMIT 256
+
+/*
+ * End of serial driver configuration section.
+ */
+
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+#include <asm/serial.h>
+#include <asm/hardware.h>
+#define LOCAL_VERSTRING ""
+
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <linux/delay.h>
+#ifdef CONFIG_SERIAL_CONSOLE
+#include <linux/console.h>
+#endif
+#ifdef CONFIG_MAGIC_SYSRQ
+#include <linux/sysrq.h>
+#endif
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+
+#ifdef CONFIG_MAC_SERIAL
+#define SERIAL_DEV_OFFSET	2
+#else
+#define SERIAL_DEV_OFFSET	0
+#endif
+
+#define _INLINE_ inline
+
+static char *serial_name = "ISL3893 UART serial driver";
+
+static DECLARE_TASK_QUEUE(tq_serial);
+
+static struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+/* serial subtype definitions */
+#ifndef SERIAL_TYPE_NORMAL
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+#endif
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+/*
+ * IRQ_timeout		- How long the timeout should be for each IRQ
+ * 				should be after the IRQ has been active.
+ */
+
+static struct async_struct *IRQ_ports[NR_IRQS];
+static int IRQ_timeout[NR_IRQS];
+#ifdef CONFIG_SERIAL_CONSOLE
+static struct console sercons;
+static int lsr_break_flag;
+#endif
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+static unsigned long break_pressed; /* break, really ... */
+#endif
+
+static unsigned detect_uart_irq (struct serial_state * state);
+static void autoconfig(struct serial_state * state);
+static void change_speed(struct async_struct *info, struct termios *old);
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
+
+/*
+ * Here we define the default xmit fifo size used for each type of
+ * UART
+ */
+static struct serial_uart_config uart_config[] = {
+	{ "unknown", 1, 0 },
+#if defined (CONFIG_ARCH_POLDHU)
+	{ "Poldhu UART", 1, 0},
+#elif defined (CONFIG_ARCH_ISL3893)
+	{ "ISL3893 UART", 1, 0},
+#else
+#error "No valid architecture"
+#endif
+	{ 0, 0}
+};
+
+static struct serial_state rs_table[RS_TABLE_SIZE] = {
+	SERIAL_PORT_DFNS	/* Defined in serial.h */
+};
+
+#define NR_PORTS	(sizeof(rs_table)/sizeof(struct serial_state))
+
+#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
+
+static struct tty_struct *serial_table[NR_PORTS];
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
+
+
+#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
+#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
+ kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s)
+#else
+#define DBG_CNT(s)
+#endif
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the copy_from_user blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static unsigned char *tmp_buf;
+#ifdef DECLARE_MUTEX
+static DECLARE_MUTEX(tmp_buf_sem);
+#else
+static struct semaphore tmp_buf_sem = MUTEX;
+#endif
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	info->IER &= ~UART_IER_THRI;
+	uart_interrupt_disable(UART_IER_THRI);
+	restore_flags(flags);
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	if (info->xmit.head != info->xmit.tail
+	    && info->xmit.buf
+	    && !(info->IER & UART_IER_THRI)) {
+		info->IER |= UART_IER_THRI;
+		uart_interrupt_enable(UART_IER_THRI);
+	}
+	restore_flags(flags);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ *
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assemble code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static _INLINE_ void rs_sched_event(struct async_struct *info,
+				  int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_serial);
+	mark_bh(SERIAL_BH);
+}
+
+static _INLINE_ void receive_chars(struct async_struct *info,
+				 int *status, struct pt_regs * regs)
+{
+	struct tty_struct *tty = info->tty;
+	unsigned char ch;
+	struct	async_icount *icount;
+	int	max_count = 256;
+
+	icount = &info->state->icount;
+	do {
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			tty->flip.tqueue.routine((void *) tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+				return;		// if TTY_DONT_FLIP is set
+		}
+		ch = uart_rx();
+		*status = uart_read_lsr();
+		if(*status) {
+			uart_clear_errors();
+		}
+		*tty->flip.char_buf_ptr = ch;
+		icount->rx++;
+
+#ifdef SERIAL_DEBUG_INTR
+		printk("DR%02x:%02x...", ch, *status);
+#endif
+		*tty->flip.flag_buf_ptr = 0;
+		if (*status & (UART_LSR_BI | UART_LSR_PE |
+			       UART_LSR_FE | UART_LSR_OE)) {
+			/*
+			 * For statistics only
+			 */
+			if (*status & UART_LSR_BI) {
+				*status &= ~(UART_LSR_FE | UART_LSR_PE);
+				icount->brk++;
+				/*
+				 * We do the SysRQ and SAK checking
+				 * here because otherwise the break
+				 * may get masked by ignore_status_mask
+				 * or read_status_mask.
+				 */
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+				if (info->line == sercons.index) {
+					if (!break_pressed) {
+						break_pressed = jiffies;
+						goto ignore_char;
+					}
+					break_pressed = 0;
+				}
+#endif
+				if (info->flags & ASYNC_SAK)
+					do_SAK(tty);
+			} else if (*status & UART_LSR_PE)
+				icount->parity++;
+			else if (*status & UART_LSR_FE)
+				icount->frame++;
+			if (*status & UART_LSR_OE)
+				icount->overrun++;
+
+			/*
+			 * Mask off conditions which should be ignored.
+			 */
+			*status &= info->read_status_mask;
+
+#ifdef CONFIG_SERIAL_CONSOLE
+			if (info->line == sercons.index) {
+				/* Recover the break flag from console xmit */
+				*status |= lsr_break_flag;
+				lsr_break_flag = 0;
+			}
+#endif
+			if (*status & (UART_LSR_BI)) {
+#ifdef SERIAL_DEBUG_INTR
+				printk("handling break....");
+#endif
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			} else if (*status & UART_LSR_PE)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (*status & UART_LSR_FE)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+		}
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+		if (break_pressed && info->line == sercons.index) {
+			if (ch != 0 &&
+			    time_before(jiffies, break_pressed + HZ*5)) {
+				handle_sysrq(ch, regs, NULL, NULL);
+				break_pressed = 0;
+				goto ignore_char;
+			}
+			break_pressed = 0;
+		}
+#endif
+		if ((*status & info->ignore_status_mask) == 0) {
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+		if ((*status & UART_LSR_OE) &&
+		    (tty->flip.count < TTY_FLIPBUF_SIZE)) {
+			/*
+			 * Overrun is special, since it's reported
+			 * immediately, and doesn't affect the current
+			 * character
+			 */
+			*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+			tty->flip.count++;
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+		}
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+	ignore_char:
+#endif
+	} while ((*status & UART_LSR_DR) && (max_count-- > 0));
+	tty_flip_buffer_push(tty);
+}
+
+static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
+{
+	if (info->x_char) {
+		uart_tx(info->x_char);
+		info->state->icount.tx++;
+		info->x_char = 0;
+		if (intr_done)
+			*intr_done = 0;
+		return;
+	}
+	if (info->xmit.head == info->xmit.tail
+	    || info->tty->stopped
+	    || info->tty->hw_stopped) {
+		info->IER &= ~UART_IER_THRI;
+		uart_interrupt_disable(UART_IER_THRI);
+		return;
+	}
+
+	do {
+		uart_tx(info->xmit.buf[info->xmit.tail++]);
+		info->xmit.tail = info->xmit.tail & (SERIAL_XMIT_SIZE-1);
+		info->state->icount.tx++;
+                if (info->xmit.head == info->xmit.tail)
+                        break;
+	} while (uart_read_lsr() & UART_LSR_THRE);
+
+	if (CIRC_CNT(info->xmit.head,
+		     info->xmit.tail,
+		     SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+
+#ifdef SERIAL_DEBUG_INTR
+	printk("THRE...");
+#endif
+	if (intr_done)
+		*intr_done = 0;
+
+	if (info->xmit.head == info->xmit.tail) {
+		info->IER &= ~UART_IER_THRI;
+		uart_interrupt_disable(UART_IER_THRI);
+	}
+}
+
+/*
+ * This is the serial driver's interrupt routine for a single port
+ */
+static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
+{
+	int status, iir;
+	int pass_counter = 0;
+	struct async_struct * info;
+
+#ifdef SERIAL_DEBUG_INTR
+	printk("rs_interrupt_single(%d)...", irq);
+#endif
+
+	info = IRQ_ports[irq];
+	if (!info || !info->tty)
+		return;
+
+	do {
+		status = uart_read_lsr();
+
+#ifdef SERIAL_DEBUG_INTR
+		printk("status = %x...", status);
+#endif
+		if (status & UART_LSR_DR)
+			receive_chars(info, &status, regs);
+
+		if (status & UART_LSR_THRE)
+			transmit_chars(info, 0);
+
+		if (pass_counter++ > RS_ISR_PASS_LIMIT) {
+#if 0
+			printk("rs_single loop break.\n");
+#endif
+			break;
+		}
+		iir = uart_read_irqstat();
+#ifdef SERIAL_DEBUG_INTR
+		printk("IIR = %x...", iir);
+#endif
+	} while (UART_IRQSTAT_ANY(iir));
+	info->last_active = jiffies;
+#ifdef SERIAL_DEBUG_INTR
+	printk("end.\n");
+#endif
+}
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct async_struct	*info = (struct async_struct *) private_;
+	struct tty_struct	*tty;
+
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+		wake_up_interruptible(&tty->poll_wait);
+#endif
+	}
+}
+
+/*
+ * ---------------------------------------------------------------
+ * Low level utility subroutines for the serial driver:  routines to
+ * figure out the appropriate timeout for an interrupt chain, routines
+ * to initialize and startup a serial port, and routines to shutdown a
+ * serial port.  Useful stuff like that.
+ * ---------------------------------------------------------------
+ */
+
+/*
+ * This routine figures out the correct timeout for a particular IRQ.
+ * It uses the smallest timeout of all of the serial ports in a
+ * particular interrupt chain.  Now only used for IRQ 0....
+ */
+static void figure_IRQ_timeout(int irq)
+{
+	struct	async_struct	*info;
+	int	timeout = 60*HZ;	/* 60 seconds === a long time :-) */
+
+	info = IRQ_ports[irq];
+	if (!info) {
+		IRQ_timeout[irq] = 60*HZ;
+		return;
+	}
+	while (info) {
+		if (info->timeout < timeout)
+			timeout = info->timeout;
+		info = info->next_port;
+	}
+	if (!irq)
+		timeout = timeout / 2;
+	IRQ_timeout[irq] = (timeout > 3) ? timeout-2 : 1;
+}
+
+static int startup(struct async_struct * info)
+{
+	unsigned long flags;
+	int	retval=0;
+	void (*handler)(int, void *, struct pt_regs *);
+	struct serial_state *state= info->state;
+	unsigned long page;
+
+	page = get_zeroed_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	save_flags(flags); cli();
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		free_page(page);
+		goto errout;
+	}
+
+	if (!CONFIGURED_SERIAL_PORT(state) || !state->type) {
+		if (info->tty)
+			set_bit(TTY_IO_ERROR, &info->tty->flags);
+		free_page(page);
+		goto errout;
+	}
+	if (info->xmit.buf)
+		free_page(page);
+	else
+		info->xmit.buf = (unsigned char *) page;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttys%d (irq %d)...", info->line, state->irq);
+#endif
+
+	uart_initialize();
+
+	/*
+	 * Allocate the IRQ if necessary
+	 */
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			retval = -EBUSY;
+			goto errout;
+		} else {
+			handler = rs_interrupt_single;
+		}
+
+		retval = request_irq(state->irq, handler, SA_INTERRUPT,
+				     "serial", &IRQ_ports[state->irq]);
+		if (retval) {
+			if (capable(CAP_SYS_ADMIN)) {
+				if (info->tty)
+					set_bit(TTY_IO_ERROR,
+						&info->tty->flags);
+				retval = 0;
+			}
+			goto errout;
+		}
+	}
+
+	/*
+	 * Insert serial port into IRQ chain.
+	 */
+	info->prev_port = 0;
+	info->next_port = IRQ_ports[state->irq];
+	if (info->next_port)
+		info->next_port->prev_port = info;
+	IRQ_ports[state->irq] = info;
+	figure_IRQ_timeout(state->irq);
+
+	uart_interrupt_enable(UART_IER_RDI);
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit.head = info->xmit.tail = 0;
+
+	/*
+	 * Set up the tty->alt_speed kludge
+	 */
+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
+	if (info->tty) {
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+			info->tty->alt_speed = 57600;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+			info->tty->alt_speed = 115200;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+			info->tty->alt_speed = 230400;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+			info->tty->alt_speed = 460800;
+	}
+#endif
+
+	/*
+	 * and set the speed of the serial port
+	 */
+	change_speed(info, 0);
+
+	info->flags |= ASYNC_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+
+errout:
+	restore_flags(flags);
+	return retval;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct async_struct * info)
+{
+	unsigned long	flags;
+	struct serial_state *state;
+	int		retval;
+
+	if (!(info->flags & ASYNC_INITIALIZED))
+		return;
+
+	state = info->state;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Shutting down serial port %d (irq %d)....", info->line,
+	       state->irq);
+#endif
+
+	save_flags(flags); cli(); /* Disable interrupts */
+
+	/*
+	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+	 * here so the queue might never be waken up
+	 */
+	wake_up_interruptible(&info->delta_msr_wait);
+
+	/*
+	 * First unlink the serial port from the IRQ chain...
+	 */
+	if (info->next_port)
+		info->next_port->prev_port = info->prev_port;
+	if (info->prev_port)
+		info->prev_port->next_port = info->next_port;
+	else
+		IRQ_ports[state->irq] = info->next_port;
+	figure_IRQ_timeout(state->irq);
+
+	/*
+	 * Free the IRQ, if necessary
+	 */
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			free_irq(state->irq, &IRQ_ports[state->irq]);
+			retval = request_irq(state->irq, rs_interrupt_single,
+					     SA_SHIRQ, "serial",
+					     &IRQ_ports[state->irq]);
+
+			if (retval)
+				printk("serial shutdown: request_irq: error %d"
+				       "  Couldn't reacquire IRQ.\n", retval);
+		} else
+			free_irq(state->irq, &IRQ_ports[state->irq]);
+	}
+
+	if (info->xmit.buf) {
+		unsigned long pg = (unsigned long) info->xmit.buf;
+		info->xmit.buf = 0;
+		free_page(pg);
+	}
+
+	info->IER = 0;
+	uart_interrupt_disable(UART_IER_RDI);
+	uart_interrupt_disable(UART_IER_THRI);
+	info->flags &= ~ASYNC_INITIALIZED;
+	restore_flags(flags);
+}
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void change_speed(struct async_struct *info,
+			 struct termios *old_termios)
+{
+	int	quot = 0, baud_base, baud;
+	unsigned cflag, cval;
+	int	bits;
+
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+	if (!CONFIGURED_SERIAL_PORT(info))
+		return;
+
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	      case CS5: cval = 0x00; bits = 7; break;
+	      case CS6: cval = 0x01; bits = 8; break;
+	      case CS7: cval = 0x02; bits = 9; break;
+	      case CS8: cval = 0x03; bits = 10; break;
+	      /* Never happens, but GCC is too dumb to figure it out */
+	      default:  cval = 0x00; bits = 7; break;
+	      }
+	if (cflag & CSTOPB) {
+		cval |= 0x04;
+		bits++;
+	}
+	if (cflag & PARENB) {
+		cval |= UART_LCR_PARITY;
+		bits++;
+	}
+	if (!(cflag & PARODD))
+		cval |= UART_LCR_EPAR;
+#ifdef CMSPAR
+	if (cflag & CMSPAR)
+		cval |= UART_LCR_SPAR;
+#endif
+
+	/* Determine divisor based on baud rate */
+	baud = tty_get_baud_rate(info->tty);
+	if (!baud)
+		baud = 9600;	/* B0 transition handled in rs_set_termios */
+	baud_base = info->state->baud_base;
+	if (baud == 38400 &&
+	    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+		quot = info->state->custom_divisor;
+	else {
+		if (baud == 134)
+			/* Special case since 134 is really 134.5 */
+			quot = (2*baud_base / 269);
+		else if (baud)
+			quot = baud_base / baud;
+	}
+	/* If the quotient is zero refuse the change */
+	if (!quot && old_termios) {
+		info->tty->termios->c_cflag &= ~CBAUD;
+		info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD);
+		baud = tty_get_baud_rate(info->tty);
+		if (!baud)
+			baud = 9600;
+		if (baud == 38400 &&
+		    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+			quot = info->state->custom_divisor;
+		else {
+			if (baud == 134)
+				/* Special case since 134 is really 134.5 */
+				quot = (2*baud_base / 269);
+			else if (baud)
+				quot = baud_base / baud;
+		}
+	}
+	/* As a last resort, if the quotient is zero, default to 9600 bps */
+	if (!quot)
+		quot = baud_base / 9600;
+	/*
+	 * Work around a bug in the Oxford Semiconductor 952 rev B
+	 * chip which causes it to seriously miscalculate baud rates
+	 * when DLL is 0.
+	 */
+	if (((quot & 0xFF) == 0) && (info->state->type == PORT_16C950) &&
+	    (info->state->revision == 0x5201))
+		quot++;
+
+	info->quot = quot;
+	info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base);
+	info->timeout += HZ/50;		/* Add .02 seconds of slop */
+
+	/* For now, the UART already is configured at the right speed. This may
+	 * change in the future. Then do that HERE!
+	 */
+}
+
+static void rs_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (!tty || !info->xmit.buf)
+		return;
+
+	save_flags(flags); cli();
+	if (CIRC_SPACE(info->xmit.head,
+		       info->xmit.tail,
+		       SERIAL_XMIT_SIZE) == 0) {
+		restore_flags(flags);
+		return;
+	}
+
+	info->xmit.buf[info->xmit.head] = ch;
+	info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
+	restore_flags(flags);
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (info->xmit.head == info->xmit.tail
+	    || tty->stopped
+	    || tty->hw_stopped
+	    || !info->xmit.buf)
+		return;
+
+	save_flags(flags); cli();
+
+	/*
+	 * start xmit interrupt
+	 */
+	uart_interrupt_enable(UART_IER_THRI);
+	restore_flags(flags);
+}
+
+static int rs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	int	c, ret = 0;
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (!tty || !info->xmit.buf || !tmp_buf)
+		return 0;
+
+	save_flags(flags);
+	if (from_user) {
+		down(&tmp_buf_sem);
+		while (1) {
+			int c1;
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					      info->xmit.tail,
+					      SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0)
+				break;
+
+			c -= copy_from_user(tmp_buf, buf, c);
+			if (!c) {
+				if (!ret)
+					ret = -EFAULT;
+				break;
+			}
+			cli();
+			c1 = CIRC_SPACE_TO_END(info->xmit.head,
+					       info->xmit.tail,
+					       SERIAL_XMIT_SIZE);
+			if (c1 < c)
+				c = c1;
+			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			restore_flags(flags);
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		up(&tmp_buf_sem);
+	} else {
+		cli();
+		while (1) {
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					      info->xmit.tail,
+					      SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0) {
+				break;
+			}
+			memcpy(info->xmit.buf + info->xmit.head, buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		restore_flags(flags);
+	}
+	if (info->xmit.head != info->xmit.tail
+	    && !tty->stopped
+	    && !tty->hw_stopped
+	    && !(info->IER & UART_IER_THRI)) {
+		info->IER |= UART_IER_THRI;
+		uart_interrupt_enable(UART_IER_THRI);
+	}
+	return ret;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	info->xmit.head = info->xmit.tail = 0;
+	restore_flags(flags);
+	wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+	wake_up_interruptible(&tty->poll_wait);
+#endif
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void rs_send_xchar(struct tty_struct *tty, char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	info->x_char = ch;
+	if (ch) {
+		/* Make sure transmit interrupts are on */
+		info->IER |= UART_IER_THRI;
+		uart_interrupt_enable(UART_IER_THRI);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ *
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct * tty)
+{
+	/* rs_throttle: Throttling not supported */
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+	/* rs_unthrottle: Throttling not supported */
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int get_serial_info(struct async_struct * info,
+			   struct serial_struct * retinfo)
+{
+	struct serial_struct tmp;
+	struct serial_state *state = info->state;
+
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = state->type;
+	tmp.line = state->line;
+	tmp.port = state->port;
+	if (HIGH_BITS_OFFSET)
+		tmp.port_high = state->port >> HIGH_BITS_OFFSET;
+	else
+		tmp.port_high = 0;
+	tmp.irq = state->irq;
+	tmp.flags = state->flags;
+	tmp.xmit_fifo_size = state->xmit_fifo_size;
+	tmp.baud_base = state->baud_base;
+	tmp.close_delay = state->close_delay;
+	tmp.closing_wait = state->closing_wait;
+	tmp.custom_divisor = state->custom_divisor;
+	tmp.hub6 = state->hub6;
+	tmp.io_type = state->io_type;
+	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
+		return -EFAULT;
+	return 0;
+}
+
+static int set_serial_info(struct async_struct * info,
+			   struct serial_struct * new_info)
+{
+	struct serial_struct new_serial;
+ 	struct serial_state old_state, *state;
+	unsigned int		i,change_irq,change_port;
+	int 			retval = 0;
+	unsigned long		new_port;
+
+	if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
+		return -EFAULT;
+	state = info->state;
+	old_state = *state;
+
+	new_port = new_serial.port;
+	if (HIGH_BITS_OFFSET)
+		new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
+
+	change_irq = new_serial.irq != state->irq;
+	change_port = (new_port != ((int) state->port)) ||
+		(new_serial.hub6 != state->hub6);
+
+	if (!capable(CAP_SYS_ADMIN)) {
+		if (change_irq || change_port ||
+		    (new_serial.baud_base != state->baud_base) ||
+		    (new_serial.type != state->type) ||
+		    (new_serial.close_delay != state->close_delay) ||
+		    (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
+		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
+		     (state->flags & ~ASYNC_USR_MASK)))
+			return -EPERM;
+		state->flags = ((state->flags & ~ASYNC_USR_MASK) |
+			       (new_serial.flags & ASYNC_USR_MASK));
+		info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+			       (new_serial.flags & ASYNC_USR_MASK));
+		state->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	new_serial.irq = irq_cannonicalize(new_serial.irq);
+
+	if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) ||
+	    (new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) ||
+	    (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) ||
+	    (new_serial.type == PORT_STARTECH)) {
+		return -EINVAL;
+	}
+
+	if ((new_serial.type != state->type) ||
+	    (new_serial.xmit_fifo_size <= 0))
+		new_serial.xmit_fifo_size =
+			uart_config[new_serial.type].dfl_xmit_fifo_size;
+
+	/* Make sure address is not already in use */
+	if (new_serial.type) {
+		for (i = 0 ; i < NR_PORTS; i++)
+			if ((state != &rs_table[i]) &&
+			    (rs_table[i].port == new_port) &&
+			    rs_table[i].type)
+				return -EADDRINUSE;
+	}
+
+	if ((change_port || change_irq) && (state->count > 1))
+		return -EBUSY;
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+	state->baud_base = new_serial.baud_base;
+	state->flags = ((state->flags & ~ASYNC_FLAGS) |
+			(new_serial.flags & ASYNC_FLAGS));
+	info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
+		       (info->flags & ASYNC_INTERNAL_FLAGS));
+	state->custom_divisor = new_serial.custom_divisor;
+	state->close_delay = new_serial.close_delay * HZ/100;
+	state->closing_wait = new_serial.closing_wait * HZ/100;
+#if (LINUX_VERSION_CODE > 0x20100)
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+#endif
+	info->xmit_fifo_size = state->xmit_fifo_size =
+		new_serial.xmit_fifo_size;
+
+	if ((state->type != PORT_UNKNOWN) && state->port) {
+		release_region(state->port,8);
+	}
+	state->type = new_serial.type;
+	if (change_port || change_irq) {
+		/*
+		 * We need to shutdown the serial port at the old
+		 * port/irq combination.
+		 */
+		shutdown(info);
+		state->irq = new_serial.irq;
+		info->port = state->port = new_port;
+		info->hub6 = state->hub6 = new_serial.hub6;
+		if (info->hub6)
+			info->io_type = state->io_type = SERIAL_IO_HUB6;
+		else if (info->io_type == SERIAL_IO_HUB6)
+			info->io_type = state->io_type = SERIAL_IO_PORT;
+	}
+	if ((state->type != PORT_UNKNOWN) && state->port) {
+		request_region(state->port,8,"serial(set)");
+	}
+
+
+check_and_exit:
+	if (!state->port || !state->type)
+		return 0;
+	if (info->flags & ASYNC_INITIALIZED) {
+		if (((old_state.flags & ASYNC_SPD_MASK) !=
+		     (state->flags & ASYNC_SPD_MASK)) ||
+		    (old_state.custom_divisor != state->custom_divisor)) {
+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+				info->tty->alt_speed = 57600;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+				info->tty->alt_speed = 115200;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+				info->tty->alt_speed = 230400;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+				info->tty->alt_speed = 460800;
+#endif
+			change_speed(info, 0);
+		}
+	} else
+		retval = startup(info);
+	return retval;
+}
+
+static int do_autoconfig(struct async_struct * info)
+{
+	int irq, retval;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (info->state->count > 1)
+		return -EBUSY;
+
+	shutdown(info);
+
+	autoconfig(info->state);
+	if ((info->state->flags & ASYNC_AUTO_IRQ) &&
+	    (info->state->port != 0) &&
+	    (info->state->type != PORT_UNKNOWN)) {
+		irq = detect_uart_irq(info->state);
+		if (irq > 0)
+			info->state->irq = irq;
+	}
+
+	retval = startup(info);
+	if (retval)
+		return retval;
+	return 0;
+}
+
+/*
+ * rs_break() --- routine which turns the break handling on or off
+ */
+static void rs_break(struct tty_struct *tty, int break_state)
+{
+#if 0
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (!CONFIGURED_SERIAL_PORT(info))
+		return;
+	save_flags(flags); cli();
+	if (break_state == -1)
+		info->LCR |= UART_LCR_SBC;
+	else
+		info->LCR &= ~UART_LCR_SBC;
+	restore_flags(flags);
+#else
+	/* rs_break: not (yet?) supported */
+#endif
+}
+
+static int rs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct async_icount cnow;	/* kernel counter temps */
+	struct serial_icounter_struct icount;
+	unsigned long flags;
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+	int retval, tmp;
+#endif
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+
+	switch (cmd) {
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+		case TCSBRK:	/* SVID version: non-zero arg --> no break */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (signal_pending(current))
+				return -EINTR;
+			if (!arg) {
+				send_break(info, HZ/4);	/* 1/4 second */
+				if (signal_pending(current))
+					return -EINTR;
+			}
+			return 0;
+		case TCSBRKP:	/* support for POSIX tcsendbreak() */
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (signal_pending(current))
+				return -EINTR;
+			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+			if (signal_pending(current))
+				return -EINTR;
+			return 0;
+		case TIOCGSOFTCAR:
+			tmp = C_CLOCAL(tty) ? 1 : 0;
+			if (copy_to_user((void *)arg, &tmp, sizeof(int)))
+				return -EFAULT;
+			return 0;
+		case TIOCSSOFTCAR:
+			if (copy_from_user(&tmp, (void *)arg, sizeof(int)))
+				return -EFAULT;
+
+			tty->termios->c_cflag =
+				((tty->termios->c_cflag & ~CLOCAL) |
+				 (tmp ? CLOCAL : 0));
+			return 0;
+#endif
+		case TIOCGSERIAL:
+			return get_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSSERIAL:
+			return set_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSERCONFIG:
+			return do_autoconfig(info);
+
+		case TIOCSERGSTRUCT:
+			if (copy_to_user((struct async_struct *) arg,
+					 info, sizeof(struct async_struct)))
+				return -EFAULT;
+			return 0;
+
+		/*
+		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+		 * Return: write counters to the user passed counter struct
+		 * NB: both 1->0 and 0->1 transitions are counted except for
+		 *     RI where only 0->1 is counted.
+		 */
+		case TIOCGICOUNT:
+			save_flags(flags); cli();
+			cnow = info->state->icount;
+			restore_flags(flags);
+			icount.cts = cnow.cts;
+			icount.dsr = cnow.dsr;
+			icount.rng = cnow.rng;
+			icount.dcd = cnow.dcd;
+			icount.rx = cnow.rx;
+			icount.tx = cnow.tx;
+			icount.frame = cnow.frame;
+			icount.overrun = cnow.overrun;
+			icount.parity = cnow.parity;
+			icount.brk = cnow.brk;
+			icount.buf_overrun = cnow.buf_overrun;
+
+			if (copy_to_user((void *)arg, &icount, sizeof(icount)))
+				return -EFAULT;
+			return 0;
+		case TIOCSERGWILD:
+		case TIOCSERSWILD:
+			/* "setserial -W" is called in Debian boot */
+			printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
+			return 0;
+
+		case TIOCSERGETLSR: /* Get line status register */
+		case TIOCMGET:
+		case TIOCMBIS:
+		case TIOCMBIC:
+		case TIOCMSET:
+		case TIOCMIWAIT:
+			return -EINVAL;
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	/* Nothing for us here */
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ *
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct serial_state *state;
+	unsigned long flags;
+
+	if (!info)
+		return;
+
+	state = info->state;
+
+	save_flags(flags); cli();
+
+	if (tty_hung_up_p(filp)) {
+		DBG_CNT("before DEC-hung");
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
+#endif
+	if ((tty->count == 1) && (state->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  state->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+		       "state->count is %d\n", state->count);
+		state->count = 1;
+	}
+	if (--state->count < 0) {
+		printk("rs_close: bad serial port count for ttys%d: %d\n",
+		       info->line, state->count);
+		state->count = 0;
+	}
+	if (state->count) {
+		DBG_CNT("before DEC-2");
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= ASYNC_CLOSING;
+	restore_flags(flags);
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & ASYNC_NORMAL_ACTIVE)
+		info->state->normal_termios = *tty->termios;
+	if (info->flags & ASYNC_CALLOUT_ACTIVE)
+		info->state->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+	info->IER &= ~UART_IER_RLSI;
+	info->read_status_mask &= ~UART_LSR_DR;
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
+			 ASYNC_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	MOD_DEC_USE_COUNT;
+}
+
+/*
+ * rs_wait_until_sent() --- wait until the transmitter is empty
+ */
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	unsigned long orig_jiffies, char_time;
+
+	if (info->state->type == PORT_UNKNOWN)
+		return;
+
+	if (info->xmit_fifo_size == 0)
+		return; /* Just in case.... */
+
+	orig_jiffies = jiffies;
+	/*
+	 * Set the check interval to be 1/5 of the estimated time to
+	 * send a single character, and make it at least 1.  The check
+	 * interval should also be less than the timeout.
+	 *
+	 * Note: we have to use pretty tight timings here to satisfy
+	 * the NIST-PCTS.
+	 */
+	char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
+	char_time = char_time / 5;
+	if (char_time == 0)
+		char_time = 1;
+	if (timeout && timeout < char_time)
+		char_time = timeout;
+	/*
+	 * If the transmitter hasn't cleared in twice the approximate
+	 * amount of time to send the entire FIFO, it probably won't
+	 * ever clear.  This assumes the UART isn't doing flow
+	 * control, which is currently the case.  Hence, if it ever
+	 * takes longer than info->timeout, this is probably due to a
+	 * UART bug of some kind.  So, we clamp the timeout parameter at
+	 * 2*info->timeout.
+	 */
+	if (!timeout || timeout > 2*info->timeout)
+		timeout = 2*info->timeout;
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
+	printk("jiff=%lu...", jiffies);
+#endif
+	while (!(uart_read_lsr() & UART_LSR_THRE)) {
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+		printk("waiting for TX ready (jiff=%lu)...", jiffies);
+#endif
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(char_time);
+		if (signal_pending(current))
+			break;
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			break;
+	}
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk("(jiff=%lu)...done\n", jiffies);
+#endif
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void rs_hangup(struct tty_struct *tty)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct serial_state *state = info->state;
+
+	state = info->state;
+
+	rs_flush_buffer(tty);
+	if (info->flags & ASYNC_CLOSING)
+		return;
+	shutdown(info);
+	info->event = 0;
+	state->count = 0;
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file * filp,
+			   struct async_struct *info)
+{
+	struct serial_state *state = info->state;
+	int		do_clocal = 0;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+		return -EAGAIN;
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & ASYNC_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+		    return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+		    return -EBUSY;
+		info->flags |= ASYNC_CALLOUT_ACTIVE;
+		return 0;
+	}
+
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & ASYNC_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= ASYNC_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
+		if (state->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+
+	return 0;
+}
+
+static int get_async_struct(int line, struct async_struct **ret_info)
+{
+	struct async_struct *info;
+	struct serial_state *sstate;
+
+	sstate = rs_table + line;
+	sstate->count++;
+	if (sstate->info) {
+		*ret_info = sstate->info;
+		return 0;
+	}
+	info = kmalloc(sizeof(struct async_struct), GFP_KERNEL);
+	if (!info) {
+		sstate->count--;
+		return -ENOMEM;
+	}
+	memset(info, 0, sizeof(struct async_struct));
+	init_waitqueue_head(&info->open_wait);
+	init_waitqueue_head(&info->close_wait);
+	init_waitqueue_head(&info->delta_msr_wait);
+	info->magic = SERIAL_MAGIC;
+	info->port = sstate->port;
+	info->flags = sstate->flags;
+	info->io_type = sstate->io_type;
+	info->iomem_base = sstate->iomem_base;
+	info->iomem_reg_shift = sstate->iomem_reg_shift;
+	info->xmit_fifo_size = sstate->xmit_fifo_size;
+	info->line = line;
+	info->tqueue.routine = do_softint;
+	info->tqueue.data = info;
+	info->state = sstate;
+	if (sstate->info) {
+		kfree(info);
+		*ret_info = sstate->info;
+		return 0;
+	}
+	*ret_info = sstate->info = info;
+	return 0;
+}
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+static int rs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct async_struct	*info;
+	int 			retval, line;
+	unsigned long		page;
+
+	MOD_INC_USE_COUNT;
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	if ((line < 0) || (line >= NR_PORTS)) {
+		MOD_DEC_USE_COUNT;
+		return -ENODEV;
+	}
+	retval = get_async_struct(line, &info);
+	if (retval) {
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+	tty->driver_data = info;
+	info->tty = tty;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+	       info->state->count);
+#endif
+#if (LINUX_VERSION_CODE > 0x20100)
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+#endif
+
+	if (!tmp_buf) {
+		page = get_zeroed_page(GFP_KERNEL);
+		if (tmp_buf)
+			free_page(page);
+		else {
+		if (!page) {
+			MOD_DEC_USE_COUNT;
+			return -ENOMEM;
+		}
+			tmp_buf = (unsigned char *) page;
+	}
+	}
+
+	/*
+	 * If the port is the middle of closing, bail out now
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+		MOD_DEC_USE_COUNT;
+		return -EAGAIN;
+	}
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval) {
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("rs_open returning after block_til_ready with %d\n",
+		       retval);
+#endif
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+
+	if ((info->state->count == 1) &&
+	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->state->normal_termios;
+		else
+			*tty->termios = info->state->callout_termios;
+		change_speed(info, 0);
+	}
+#ifdef CONFIG_SERIAL_CONSOLE
+	if (sercons.cflag && sercons.index == line) {
+		tty->termios->c_cflag = sercons.cflag;
+		sercons.cflag = 0;
+		change_speed(info, 0);
+	}
+#endif
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open ttys%d successful...", info->line);
+#endif
+	return 0;
+}
+
+/*
+ * /proc fs routines....
+ */
+
+static inline int line_info(char *buf, struct serial_state *state)
+{
+	struct async_struct *info = state->info, scr_info;
+	char	stat_buf[30];
+	int	ret;
+	unsigned long flags;
+
+	ret = sprintf(buf, "%d: uart:%s port:%lX irq:%d",
+		      state->line, uart_config[state->type].name,
+		      state->port, state->irq);
+
+	if (!state->port || (state->type == PORT_UNKNOWN)) {
+		ret += sprintf(buf+ret, "\n");
+		return ret;
+	}
+
+	/*
+	 * Figure out the current RS-232 lines
+	 */
+	if (!info) {
+		info = &scr_info;	/* This is just for serial_{in,out} */
+
+		info->magic = SERIAL_MAGIC;
+		info->port = state->port;
+		info->flags = state->flags;
+		info->hub6 = state->hub6;
+		info->io_type = state->io_type;
+		info->iomem_base = state->iomem_base;
+		info->iomem_reg_shift = state->iomem_reg_shift;
+		info->quot = 0;
+		info->tty = 0;
+	}
+	save_flags(flags); cli();
+
+	if (info->quot) {
+		ret += sprintf(buf+ret, " baud:%d",
+			       state->baud_base / info->quot);
+	}
+
+	ret += sprintf(buf+ret, " tx:%d rx:%d",
+		      state->icount.tx, state->icount.rx);
+
+	if (state->icount.frame)
+		ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
+
+	if (state->icount.parity)
+		ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
+
+	if (state->icount.brk)
+		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);
+
+	if (state->icount.overrun)
+		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
+
+	/*
+	 * Last thing is the RS-232 status lines
+	 */
+	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+	return ret;
+}
+
+int rs_read_proc(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	int i, len = 0, l;
+	off_t	begin = 0;
+
+	len += sprintf(page, "serinfo:1.0 driver:%s%s revision:%s\n",
+		       serial_version, LOCAL_VERSTRING, serial_revdate);
+	for (i = 0; i < NR_PORTS && len < 4000; i++) {
+		l = line_info(page + len, &rs_table[i]);
+		len += l;
+		if (len+begin > off+count)
+			goto done;
+		if (len+begin < off) {
+			begin += len;
+			len = 0;
+		}
+	}
+	*eof = 1;
+done:
+	if (off >= len+begin)
+		return 0;
+	*start = page + (off-begin);
+	return ((count < begin+len-off) ? count : begin+len-off);
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * rs_init() and friends
+ *
+ * rs_init() is called at boot-time to initialize the serial driver.
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * This routine prints out the appropriate serial driver version
+ * number, and identifies which options were configured into this
+ * driver.
+ */
+static char serial_options[] __initdata =
+#ifdef CONFIG_HUB6
+       " HUB-6"
+#define SERIAL_OPT
+#endif
+#ifdef CONFIG_SERIAL_DETECT_IRQ
+       " DETECT_IRQ"
+#define SERIAL_OPT
+#endif
+#ifdef SERIAL_OPT
+       " enabled\n";
+#else
+       " no serial options enabled\n";
+#endif
+#undef SERIAL_OPT
+
+static _INLINE_ void show_serial_version(void)
+{
+ 	printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name,
+	       serial_version, LOCAL_VERSTRING, serial_revdate,
+	       serial_options);
+}
+
+/*
+ * This routine returns the IRQ of the serial port.
+ */
+static unsigned detect_uart_irq (struct serial_state * state)
+{
+	// There's only one IRQ...
+	return IRQ_UART;
+}
+
+
+/*
+ * This routine is called by rs_init() to initialize a specific serial
+ * port
+ */
+static void autoconfig(struct serial_state * state)
+{
+#ifdef SERIAL_DEBUG_AUTOCONF
+	printk("Testing ttyS%d (0x%04lx, 0x%04x)...\n", state->line,
+	       state->port, (unsigned) state->iomem_base);
+#endif
+	state->type = 1; /* 0 is always used for "unknown" */
+	state->xmit_fifo_size =	uart_config[state->type].dfl_xmit_fifo_size;
+}
+
+int register_serial(struct serial_struct *req);
+void unregister_serial(int line);
+
+#if (LINUX_VERSION_CODE > 0x20100)
+EXPORT_SYMBOL(register_serial);
+EXPORT_SYMBOL(unregister_serial);
+#else
+static struct symbol_table serial_syms = {
+#include <linux/symtab_begin.h>
+	X(register_serial),
+	X(unregister_serial),
+#include <linux/symtab_end.h>
+};
+#endif
+
+
+/*
+ * The serial driver boot-time initialization code!
+ */
+static int __init rs_init(void)
+{
+	int i;
+	struct serial_state * state;
+
+	init_bh(SERIAL_BH, do_serial_bh);
+
+	for (i = 0; i < NR_IRQS; i++) {
+		IRQ_ports[i] = 0;
+		IRQ_timeout[i] = 0;
+	}
+#ifdef CONFIG_SERIAL_CONSOLE
+	/*
+	 *	The interrupt of the serial console port
+	 *	can't be shared.
+	 */
+	if (sercons.flags & CON_CONSDEV) {
+		for(i = 0; i < NR_PORTS; i++)
+			if (i != sercons.index &&
+			    rs_table[i].irq == rs_table[sercons.index].irq)
+				rs_table[i].irq = 0;
+	}
+#endif
+	show_serial_version();
+
+	/* Initialize the tty_driver structure */
+
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+#if (LINUX_VERSION_CODE > 0x20100)
+	serial_driver.driver_name = "serial";
+#endif
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	serial_driver.name = "tts/%d";
+#else
+	serial_driver.name = "ttyS";
+#endif
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64 + SERIAL_DEV_OFFSET;
+	serial_driver.num = NR_PORTS;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+	serial_driver.init_termios.c_cflag =
+		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = rs_open;
+	serial_driver.close = rs_close;
+	serial_driver.write = rs_write;
+	serial_driver.put_char = rs_put_char;
+	serial_driver.flush_chars = rs_flush_chars;
+	serial_driver.write_room = rs_write_room;
+	serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	serial_driver.flush_buffer = rs_flush_buffer;
+	serial_driver.ioctl = rs_ioctl;
+	serial_driver.throttle = rs_throttle;
+	serial_driver.unthrottle = rs_unthrottle;
+	serial_driver.set_termios = rs_set_termios;
+	serial_driver.stop = rs_stop;
+	serial_driver.start = rs_start;
+	serial_driver.hangup = rs_hangup;
+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
+	serial_driver.break_ctl = rs_break;
+#endif
+#if (LINUX_VERSION_CODE >= 131343)
+	serial_driver.send_xchar = rs_send_xchar;
+	serial_driver.wait_until_sent = rs_wait_until_sent;
+	serial_driver.read_proc = rs_read_proc;
+#endif
+
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	callout_driver.name = "cua/%d";
+#else
+	callout_driver.name = "cua";
+#endif
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+#if (LINUX_VERSION_CODE >= 131343)
+	callout_driver.read_proc = 0;
+	callout_driver.proc_entry = 0;
+#endif
+
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register serial driver\n");
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+
+	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
+		state->magic = SSTATE_MAGIC;
+		state->line = i;
+		state->type = PORT_UNKNOWN;
+		state->custom_divisor = 0;
+		state->close_delay = 5*HZ/10;
+		state->closing_wait = 30*HZ;
+		state->callout_termios = callout_driver.init_termios;
+		state->normal_termios = serial_driver.init_termios;
+		state->icount.cts = state->icount.dsr =
+			state->icount.rng = state->icount.dcd = 0;
+		state->icount.rx = state->icount.tx = 0;
+		state->icount.frame = state->icount.parity = 0;
+		state->icount.overrun = state->icount.brk = 0;
+		state->irq = irq_cannonicalize(state->irq);
+		if (state->hub6)
+			state->io_type = SERIAL_IO_HUB6;
+		if (state->port && check_region(state->port,8))
+			continue;
+		if (state->flags & ASYNC_BOOT_AUTOCONF)
+			autoconfig(state);
+	}
+	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
+		if (state->type == PORT_UNKNOWN)
+			continue;
+		if (   (state->flags & ASYNC_BOOT_AUTOCONF)
+		    && (state->flags & ASYNC_AUTO_IRQ)
+		    && (state->port != 0))
+			state->irq = detect_uart_irq(state);
+		printk(KERN_INFO "ttyS%02d%s at 0x%04lx (irq = %d) is a %s\n",
+		       state->line + SERIAL_DEV_OFFSET,
+		       (state->flags & ASYNC_FOURPORT) ? " FourPort" : "",
+		       state->port, state->irq,
+		       uart_config[state->type].name);
+		tty_register_devfs(&serial_driver, 0,
+				   serial_driver.minor_start + state->line);
+		tty_register_devfs(&callout_driver, 0,
+				   callout_driver.minor_start + state->line);
+	}
+	return 0;
+}
+
+/*
+ * This is for use by architectures that know their serial console
+ * attributes only at run time. Not to be invoked after rs_init().
+ */
+int __init early_serial_setup(struct serial_struct *req)
+{
+	int i = req->line;
+
+	if (i >= NR_IRQS)
+		return(-ENOENT);
+	rs_table[i].magic = 0;
+	rs_table[i].baud_base = req->baud_base;
+	rs_table[i].port = req->port;
+	if (HIGH_BITS_OFFSET)
+		rs_table[i].port += (unsigned long) req->port_high <<
+							HIGH_BITS_OFFSET;
+	rs_table[i].irq = req->irq;
+	rs_table[i].flags = req->flags;
+	rs_table[i].close_delay = req->close_delay;
+	rs_table[i].io_type = req->io_type;
+	rs_table[i].hub6 = req->hub6;
+	rs_table[i].iomem_base = req->iomem_base;
+	rs_table[i].iomem_reg_shift = req->iomem_reg_shift;
+	rs_table[i].type = req->type;
+	rs_table[i].xmit_fifo_size = req->xmit_fifo_size;
+	rs_table[i].custom_divisor = req->custom_divisor;
+	rs_table[i].closing_wait = req->closing_wait;
+	return(0);
+}
+
+/*
+ * register_serial and unregister_serial allows for 16x50 serial ports to be
+ * configured at run-time, to support PCMCIA modems.
+ */
+
+/**
+ *	register_serial - configure a 16x50 serial port at runtime
+ *	@req: request structure
+ *
+ *	Configure the serial port specified by the request. If the
+ *	port exists and is in use an error is returned. If the port
+ *	is not currently in the table it is added.
+ *
+ *	The port is then probed and if neccessary the IRQ is autodetected
+ *	If this fails an error is returned.
+ *
+ *	On success the port is ready to use and the line number is returned.
+ */
+
+int register_serial(struct serial_struct *req)
+{
+	int i;
+	unsigned long flags;
+	struct serial_state *state;
+	struct async_struct *info;
+	unsigned long port;
+
+	port = req->port;
+	if (HIGH_BITS_OFFSET)
+		port += (unsigned long) req->port_high << HIGH_BITS_OFFSET;
+
+	save_flags(flags); cli();
+	for (i = 0; i < NR_PORTS; i++) {
+		if ((rs_table[i].port == port) &&
+		    (rs_table[i].iomem_base == req->iomem_base))
+			break;
+	}
+#ifdef __i386__
+	if (i == NR_PORTS) {
+		for (i = 4; i < NR_PORTS; i++)
+			if ((rs_table[i].type == PORT_UNKNOWN) &&
+			    (rs_table[i].count == 0))
+				break;
+	}
+#endif
+	if (i == NR_PORTS) {
+		for (i = 0; i < NR_PORTS; i++)
+			if ((rs_table[i].type == PORT_UNKNOWN) &&
+			    (rs_table[i].count == 0))
+				break;
+	}
+	if (i == NR_PORTS) {
+		restore_flags(flags);
+		return -1;
+	}
+	state = &rs_table[i];
+	if (rs_table[i].count) {
+		restore_flags(flags);
+		printk("Couldn't configure serial #%d (port=%ld,irq=%d): "
+		       "device already open\n", i, port, req->irq);
+		return -1;
+	}
+	state->irq = req->irq;
+	state->port = port;
+	state->flags = req->flags;
+	state->io_type = req->io_type;
+	state->iomem_base = req->iomem_base;
+	state->iomem_reg_shift = req->iomem_reg_shift;
+	if (req->baud_base)
+		state->baud_base = req->baud_base;
+	if ((info = state->info) != NULL) {
+		info->port = port;
+		info->flags = req->flags;
+		info->io_type = req->io_type;
+		info->iomem_base = req->iomem_base;
+		info->iomem_reg_shift = req->iomem_reg_shift;
+	}
+	autoconfig(state);
+	if (state->type == PORT_UNKNOWN) {
+		restore_flags(flags);
+		printk("register_serial(): autoconfig failed\n");
+		return -1;
+	}
+	restore_flags(flags);
+
+	if ((state->flags & ASYNC_AUTO_IRQ) && CONFIGURED_SERIAL_PORT(state))
+		state->irq = detect_uart_irq(state);
+
+       printk(KERN_INFO "ttyS%02d at %s 0x%04lx (irq = %d) is a %s\n",
+	      state->line + SERIAL_DEV_OFFSET,
+	      state->iomem_base ? "iomem" : "port",
+	      state->iomem_base ? (unsigned long)state->iomem_base :
+	      state->port, state->irq, uart_config[state->type].name);
+	tty_register_devfs(&serial_driver, 0,
+			   serial_driver.minor_start + state->line);
+	tty_register_devfs(&callout_driver, 0,
+			   callout_driver.minor_start + state->line);
+	return state->line + SERIAL_DEV_OFFSET;
+}
+
+/**
+ *	unregister_serial - deconfigure a 16x50 serial port
+ *	@line: line to deconfigure
+ *
+ *	The port specified is deconfigured and its resources are freed. Any
+ *	user of the port is disconnected as if carrier was dropped. Line is
+ *	the port number returned by register_serial().
+ */
+
+void unregister_serial(int line)
+{
+	unsigned long flags;
+	struct serial_state *state = &rs_table[line];
+
+	save_flags(flags); cli();
+	if (state->info && state->info->tty)
+		tty_hangup(state->info->tty);
+	state->type = PORT_UNKNOWN;
+	printk(KERN_INFO "tty%02d unloaded\n", state->line);
+	/* These will be hidden, because they are devices that will no longer
+	 * be available to the system. (ie, PCMCIA modems, once ejected)
+	 */
+	tty_unregister_devfs(&serial_driver,
+			     serial_driver.minor_start + state->line);
+	tty_unregister_devfs(&callout_driver,
+			     callout_driver.minor_start + state->line);
+	restore_flags(flags);
+}
+
+static void __exit rs_fini(void)
+{
+	unsigned long flags;
+	int e1, e2;
+	int i;
+	struct async_struct *info;
+
+	/* printk("Unloading %s: version %s\n", serial_name, serial_version); */
+	save_flags(flags); cli();
+        remove_bh(SERIAL_BH);
+	if ((e1 = tty_unregister_driver(&serial_driver)))
+		printk("serial: failed to unregister serial driver (%d)\n",
+		       e1);
+	if ((e2 = tty_unregister_driver(&callout_driver)))
+		printk("serial: failed to unregister callout driver (%d)\n",
+		       e2);
+	restore_flags(flags);
+
+	for (i = 0; i < NR_PORTS; i++) {
+		if ((info = rs_table[i].info)) {
+			rs_table[i].info = NULL;
+			kfree(info);
+		}
+		if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) {
+			release_region(rs_table[i].port, 8);
+		}
+	}
+	if (tmp_buf) {
+		unsigned long pg = (unsigned long) tmp_buf;
+		tmp_buf = NULL;
+		free_page(pg);
+	}
+
+}
+
+module_init(rs_init);
+module_exit(rs_fini);
+MODULE_DESCRIPTION("Standard/generic (dumb) serial driver");
+MODULE_AUTHOR("Theodore Ts'o <tytso@mit.edu>");
+
+
+/*
+ * ------------------------------------------------------------
+ * Serial console driver
+ * ------------------------------------------------------------
+ */
+#ifdef CONFIG_SERIAL_CONSOLE
+
+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
+/* #define CONSOLE_INCLUDE_TIMESTAMP */
+
+static struct async_struct async_sercons;
+
+/*
+ *	Wait for transmitter & holding register to empty
+ */
+static inline void wait_for_xmitr(struct async_struct *info)
+{
+	unsigned int status, tmout = 1000000;
+
+	do {
+		status = uart_read_lsr();
+
+		if (status & UART_LSR_BI)
+			lsr_break_flag = UART_LSR_BI;
+
+		if (--tmout == 0)
+			break;
+	} while (!(status & BOTH_EMPTY));
+}
+
+
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ *
+ *	The console_lock must be held when we get here.
+ */
+static void serial_console_write(struct console *co, const char *s,
+				unsigned count)
+{
+	static struct async_struct *info = &async_sercons;
+	unsigned i;
+
+#ifdef ISL3893_SIMSONLY
+	{
+		const char *str = s;
+		for (i = 0; i < count; i++, str++) {
+			uTUBE->Data = *str;
+			if (*str == 10) {
+				uTUBE->Data = 13;
+			}
+		}
+	}
+#else	
+
+#ifdef CONSOLE_INCLUDE_TIMESTAMP
+	{
+		char lead[16];
+		char *lp = &lead[0];
+		struct timespec curtime;
+
+		jiffies_to_timespec(jiffies, &curtime);
+		sprintf(lead, "[%.6ld:%.2ld]", curtime.tv_sec, (curtime.tv_nsec / 10000000L));
+		for (i = 0; i < strlen(lead); i++, lp++) {
+			wait_for_xmitr(info);
+
+			/*
+			 *	Send the character out.
+			 *	If a LF, also do CR...
+			 */
+			uart_tx(*lp);
+			if (*lp == 10) {
+				wait_for_xmitr(info);
+				uart_tx(13);
+			}
+		}
+	}
+#endif /* CONSOLE_INCLUDE_TIMESTAMP */
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++, s++) {
+		wait_for_xmitr(info);
+
+		/*
+		 *	Send the character out.
+		 *	If a LF, also do CR...
+		 */
+		uart_tx(*s);
+		if (*s == 10) {
+			wait_for_xmitr(info);
+			uart_tx(13);
+		}
+	}
+
+	/*
+	 *	Finally, Wait for transmitter & holding register to empty
+	 */
+	wait_for_xmitr(info);
+#endif
+}
+
+static kdev_t serial_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+/*
+ *	Setup initial baud/bits/parity/flow control. We do two things here:
+ *	- construct a cflag setting for the first rs_open()
+ *	- initialize the serial port
+ *	Return non-zero if we didn't find a serial port.
+ */
+static int __init serial_console_setup(struct console *co, char *options)
+{
+	static struct async_struct *info;
+	struct serial_state *state;
+	unsigned cval;
+	int	baud = 9600;
+	int	bits = 8;
+	int	parity = 'n';
+	int	doflow = 0;
+	int	cflag = CREAD | HUPCL | CLOCAL;
+	int	quot = 0;
+	char	*s;
+
+	if (options) {
+		baud = simple_strtoul(options, NULL, 10);
+		s = options;
+		while(*s >= '0' && *s <= '9')
+			s++;
+		if (*s) parity = *s++;
+		if (*s) bits   = *s++ - '0';
+		if (*s) doflow = (*s++ == 'r');
+	}
+
+	/*
+	 *	Now construct a cflag setting.
+	 */
+	switch(baud) {
+		case 1200:
+			cflag |= B1200;
+			break;
+		case 2400:
+			cflag |= B2400;
+			break;
+		case 4800:
+			cflag |= B4800;
+			break;
+		case 19200:
+			cflag |= B19200;
+			break;
+		case 38400:
+			cflag |= B38400;
+			break;
+		case 57600:
+			cflag |= B57600;
+			break;
+		case 115200:
+			cflag |= B115200;
+			break;
+		case 9600:
+		default:
+			cflag |= B9600;
+			/*
+			 * Set this to a sane value to prevent a divide error
+			 */
+			baud  = 9600;
+			break;
+	}
+	switch(bits) {
+		case 7:
+			cflag |= CS7;
+			break;
+		default:
+		case 8:
+			cflag |= CS8;
+			break;
+	}
+	switch(parity) {
+		case 'o': case 'O':
+			cflag |= PARODD;
+			break;
+		case 'e': case 'E':
+			cflag |= PARENB;
+			break;
+	}
+	co->cflag = cflag;
+
+	/*
+	 *	Divisor, bytesize and parity
+	 */
+	state = rs_table + co->index;
+	if (doflow)
+		state->flags |= ASYNC_CONS_FLOW;
+	info = &async_sercons;
+	info->magic = SERIAL_MAGIC;
+	info->state = state;
+	info->port = state->port;
+	info->flags = state->flags;
+#ifdef CONFIG_HUB6
+	info->hub6 = state->hub6;
+#endif
+	info->io_type = state->io_type;
+	info->iomem_base = state->iomem_base;
+	info->iomem_reg_shift = state->iomem_reg_shift;
+	quot = state->baud_base / baud;
+	cval = cflag & (CSIZE | CSTOPB);
+#if defined(__powerpc__) || defined(__alpha__)
+	cval >>= 8;
+#else /* !__powerpc__ && !__alpha__ */
+	cval >>= 4;
+#endif /* !__powerpc__ && !__alpha__ */
+	if (cflag & PARENB)
+		cval |= UART_LCR_PARITY;
+	if (!(cflag & PARODD))
+		cval |= UART_LCR_EPAR;
+
+	/*
+	 *	Enable UART with interrupts disabled.
+	 */
+	uart_initialize();
+
+	return 0;
+}
+
+static struct console sercons = {
+	name:		"ttyS",
+	write:		serial_console_write,
+	device:		serial_console_device,
+	setup:		serial_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+/*
+ *	Register console.
+ */
+void __init serial_console_init(void)
+{
+	register_console(&sercons);
+}
+#endif
+
+/*
+  Local variables:
+  compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce -march=i586 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h   -DEXPORT_SYMTAB -c serial.c"
+  End:
+*/
diff -urN linux-2.4.29/drivers/char/serial_ks8695.c linux-2.4.29-uc1/drivers/char/serial_ks8695.c
--- linux-2.4.29/drivers/char/serial_ks8695.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_ks8695.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,1056 @@
+/****************************************************************************/
+
+/*
+ *	ksserial.c -- basic UART driver for KS8695 UART
+ *
+ *	(C) Copyright 2003, Greg Ungerer <gerg@snapgear.com>
+ *
+ *	This driver is loosely based on the serial_ks8695.c driver
+ *	by Kam Lee/Micrel. But this code is intended to use the old
+ *	serial driver framework.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ * Changes:
+ *
+ *	01/04:	Convert console <LF> to <LF>+<CR>.
+ *		Enable TTY devices support if KS8695_UART_AMBA_DEVICE defined as 0.
+ *		by Oleksandr Zhadan <oleks@arcturusnetworks.com>
+ */
+
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/console.h>
+#include <linux/major.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/tty_driver.h>
+#include <linux/serial.h>
+#include <linux/generic_serial.h>
+#include <linux/interrupt.h>
+#include <asm/hardware.h>
+#include <asm/uaccess.h>
+
+#include "serial_ks8695.h"
+
+//#define DEBUG	1
+
+/* Define KS8695_UART_AMBA_DEVICE to 1 for AMBA devices
+     or   KS8695_UART_AMBA_DEVICE to 0 for TTY devices support
+ */
+
+#define KS8695_UART_AMBA_DEVICE 0 
+
+/****************************************************************************/
+
+#define	KS8695_SERIAL_VERSION	"0.2"
+
+/*
+ *	Base address of the UART (this is a virtual address).
+ *	(Also the interrupt controller, since we need that too).
+ */
+#define	KS8695_UART_ADDR	(IO_ADDRESS(KS8695_IO_BASE) + KS8695_UART_RX_BUFFER)
+#define	KS8695_INTCTRL_ADDR	(IO_ADDRESS(KS8695_IO_BASE) + KS8695_INT_CONTL)
+#define	KS8695_UART_CLK		25000000
+#define	KS8695_UART_FIFOSIZE	16
+
+#define	KS8695_UART_NUM		1
+
+/****************************************************************************/
+
+/*
+ *	Local driver magic number...
+ */
+#define	KS8695_UART_MAGIC	0xbeefcafe
+
+#if KS8695_UART_AMBA_DEVICE
+/*
+ *	Major number to use. We use the AMBA defined number, to be compatible
+ *	with the Micrel driver.
+ */
+#ifndef SERIAL_AMBA_MAJOR
+#define	SERIAL_AMBA_MAJOR	204
+#define	SERIAL_AMBA_MINOR	16
+#define	CALLOUT_AMBA_MAJOR	205
+#define	CALLOUT_AMBA_MINOR	16
+#endif
+
+#else
+#define	SERIAL_TTY_MINOR_START	64
+#endif
+
+#ifndef RS_EVENT_WRITE_WAKEUP
+#define RS_EVENT_WRITE_WAKEUP	1
+#endif
+
+/****************************************************************************/
+
+/*
+ *	Driver data structures.
+ */
+static struct tty_driver ks8695_driver;
+static struct tty_driver ks8695_callout_driver;
+
+static struct tty_struct *ks8695_tty_table[KS8695_UART_NUM];
+static struct termios *ks8695_termios[KS8695_UART_NUM];
+static struct termios *ks8695_termios_locked[KS8695_UART_NUM];
+
+static int ks8695_refcount;
+
+/****************************************************************************/
+
+/*
+ *	The per-port tty structure.
+ */
+
+struct ks8695_uart_tty_port {
+	struct gs_port		gs;
+	struct async_icount	icount;
+	unsigned int		chan;
+	unsigned int		base;
+	void			*uartp;
+	void 			*intp;
+	unsigned int		irq;
+};
+
+static struct ks8695_uart_tty_port ks8695_table[KS8695_UART_NUM];
+
+/****************************************************************************/
+
+static void ks8695_setsignals(void *driver_data, int dtr, int rts)
+{
+	struct ks8695_uart_tty_port *port = driver_data;
+	struct ksuart volatile *uartp;
+	unsigned int mcr;
+
+#if DEBUG
+	printk("ks8695_setsignals(dtr=%d,rts=%d)\n", dtr, rts);
+#endif
+
+	uartp = port->uartp;
+	mcr = uartp->MCR;
+	if (dtr)
+		mcr |= KS8695_UART_MODEMC_DTR;
+	else
+		mcr &= ~KS8695_UART_MODEMC_DTR;
+	if (rts)
+		mcr |= KS8695_UART_MODEMC_RTS;
+	else
+		mcr &= ~KS8695_UART_MODEMC_RTS;
+	uartp->MCR = mcr;
+}
+
+/****************************************************************************/
+
+static int ks8695_getsignals(void *driver_data)
+{
+	struct ks8695_uart_tty_port *port = driver_data;
+	struct ksuart volatile *uartp;
+	unsigned int mcr, msr;
+	int rc;
+
+#if DEBUG
+	printk("ks8695_getsignals()\n");
+#endif
+
+	uartp = port->uartp;
+	mcr = uartp->MCR;
+	msr = uartp->MSR;
+	rc = 0;
+	if (mcr & KS8695_UART_MODEMC_DTR)
+		rc |= TIOCM_DTR;
+	if (mcr & KS8695_UART_MODEMC_RTS)
+		rc |= TIOCM_RTS;
+	if (msr & KS8695_UART_MODEM_DCD)
+		rc |= TIOCM_CD;
+	if (msr & KS8695_UART_MODEM_DSR)
+		rc |= TIOCM_DSR;
+	if (msr & KS8695_UART_MODEM_CTS)
+		rc |= TIOCM_CTS;
+	return rc;
+}
+
+/****************************************************************************/
+
+static void ks8695_enable_tx_interrupts(void *driver_data)
+{
+	struct ks8695_uart_tty_port *port = driver_data;
+	struct ksintctrl volatile *intp;
+	unsigned long flags;
+
+#if DEBUG
+	printk("ks8695_enable_tx_interrupts()\n");
+#endif
+
+	intp = port->intp;
+	save_flags(flags); cli();
+	intp->ENABLE |= KS8695_INT_ENABLE_TX;
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+
+static void ks8695_disable_tx_interrupts(void *driver_data)
+{
+	struct ks8695_uart_tty_port *port = driver_data;
+	struct ksintctrl volatile *intp;
+	unsigned long flags;
+
+#if DEBUG
+	printk("ks8695_disable_tx_interrupts()\n");
+#endif
+
+	intp = port->intp;
+	save_flags(flags); cli();
+	intp->ENABLE &= ~KS8695_INT_ENABLE_TX;
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+
+static void ks8695_enable_rx_interrupts(void *driver_data)
+{
+	struct ks8695_uart_tty_port *port = driver_data;
+	struct ksintctrl volatile *intp;
+	unsigned long flags;
+
+#if DEBUG
+	printk("ks8695_enable_rx_interrupts()\n");
+#endif
+
+	intp = port->intp;
+	save_flags(flags); cli();
+	intp->ENABLE |= KS8695_INT_ENABLE_RX | KS8695_INT_ENABLE_ERR;
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+
+static void ks8695_disable_rx_interrupts(void *driver_data)
+{
+	struct ks8695_uart_tty_port *port = driver_data;
+	struct ksintctrl volatile *intp;
+	unsigned long flags;
+
+#if DEBUG
+	printk("ks8695_disable_rx_interrupts()\n");
+#endif
+
+	intp = port->intp;
+	save_flags(flags); cli();
+	intp->ENABLE &= ~(KS8695_INT_ENABLE_RX | KS8695_INT_ENABLE_ERR);
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+
+static void ks8695_enable_modem_interrupts(void *driver_data)
+{
+	struct ks8695_uart_tty_port *port = driver_data;
+	struct ksintctrl volatile *intp;
+	unsigned long flags;
+
+#if DEBUG
+	printk("ks8695_enable_modem_interrupts()\n");
+#endif
+
+	intp = port->intp;
+	save_flags(flags); cli();
+	intp->ENABLE |= KS8695_INT_ENABLE_MODEM;
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+
+static void ks8695_disable_modem_interrupts(void *driver_data)
+{
+	struct ks8695_uart_tty_port *port = driver_data;
+	struct ksintctrl volatile *intp;
+	unsigned long flags;
+
+#if DEBUG
+	printk("ks8695_disable_modem_interrupts()\n");
+#endif
+
+	intp = port->intp;
+	save_flags(flags); cli();
+	intp->ENABLE &= ~KS8695_INT_ENABLE_MODEM;
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+
+static int ks8695_get_CD(void *driver_data)
+{
+	struct ks8695_uart_tty_port *port = driver_data;
+	struct ksuart volatile *uartp;
+
+#if DEBUG
+	printk("ks8695_get_CD()\n");
+#endif
+
+	uartp = port->uartp;
+	return ((uartp->MSR & KS8695_UART_MODEM_DCD) ? 1 : 0);
+}
+
+/****************************************************************************/
+
+static void ks8695_shutdown_port(void *driver_data)
+{
+	struct ks8695_uart_tty_port *port = driver_data;
+
+#if DEBUG
+	printk("ks8695_shutdown_port()\n");
+#endif
+
+	port->gs.flags &= ~GS_ACTIVE;
+	ks8695_disable_rx_interrupts(port);
+	ks8695_disable_modem_interrupts(port);
+	if (port->gs.tty && (port->gs.tty->termios->c_cflag & HUPCL))
+		ks8695_setsignals(port, 0, 0);
+}
+
+/****************************************************************************/
+
+static int ks8695_set_real_termios(void *driver_data)
+{
+	struct ks8695_uart_tty_port *port = driver_data;
+	struct ksuart volatile *uartp;
+	unsigned long flags;
+	unsigned int cflag;
+	unsigned int lcr = 0, fcr = 0;
+
+#if DEBUG
+	printk("ks8695_set_real_termios()\n");
+#endif
+
+	cflag = port->gs.tty->termios->c_cflag;
+
+	switch (cflag & CSIZE) {
+	case CS5:	lcr |= KS8695_UART_LINEC_WLEN5; break;
+	case CS6:	lcr |= KS8695_UART_LINEC_WLEN6; break;
+	case CS7:	lcr |= KS8695_UART_LINEC_WLEN7; break;
+	default:	lcr |= KS8695_UART_LINEC_WLEN8; break;
+	}
+
+	if (cflag & PARENB) {
+		if (cflag & PARODD)
+			lcr |= KS8695_UART_LINEC_PEN;
+		else
+			lcr |= KS8695_UART_LINEC_PEN | KS8695_UART_LINEC_EPS;
+	}
+
+	if (cflag & CSTOPB)
+		lcr |= KS8695_UART_LINEC_STP2;
+
+	if (cflag & CLOCAL)
+		port->gs.flags &= ~ASYNC_CHECK_CD;
+	else
+		port->gs.flags |= ASYNC_CHECK_CD;
+
+	fcr = KS8695_UART_FIFO_TRIG04 | KS8695_UART_FIFO_TXRST |
+		KS8695_UART_FIFO_RXRST | KS8695_UART_FIFO_FEN;
+
+	uartp = port->uartp;
+
+	save_flags(flags); cli();
+	uartp->BD = port->gs.baud == 0 ?
+		0 : (KS8695_UART_CLK / port->gs.baud);
+	uartp->FCR = fcr;
+	uartp->LCR = lcr;
+	restore_flags(flags);
+	return 0;
+}
+
+/****************************************************************************/
+
+static int ks8695_chars_in_buffer(void *driver_data)
+{
+	struct ks8695_uart_tty_port *port = driver_data;
+	struct ksuart volatile *uartp;
+
+#if DEBUG
+	printk("ks8695_chars_in_buffer()\n");
+#endif
+
+	uartp = port->uartp;
+	return ((uartp->LSR & KS8695_UART_LINES_TXFE) ? 0 : 1);
+}
+
+/****************************************************************************/
+
+static void ks8695_close(void *driver_data)
+{
+#if DEBUG
+	printk("ks8695_close()\n");
+#endif
+}
+
+/****************************************************************************/
+
+static void ks8695_hungup(void *driver_data)
+{
+#if DEBUG
+	printk("ks8695_hungup()\n");
+#endif
+}
+
+/****************************************************************************/
+
+static void ks8695_getserial(void *driver_data, struct serial_struct *s)
+{
+	struct ks8695_uart_tty_port *port = driver_data;
+
+#if DEBUG
+	printk("ks8695_getserial()\n");
+#endif
+
+	s->line = port->chan;
+	s->xmit_fifo_size = KS8695_UART_FIFOSIZE;
+	s->port = (unsigned int) port->uartp;
+	s->irq = port->irq;
+}
+
+/****************************************************************************/
+
+static int ks8695_open(struct tty_struct *tty, struct file *filp)
+{
+	struct ks8695_uart_tty_port *port;
+	unsigned int chan;
+	int rc;
+
+#if DEBUG
+	printk("ks8695_open()\n");
+#endif
+
+#if KS8695_UART_AMBA_DEVICE
+	chan = MINOR(tty->device) - SERIAL_AMBA_MINOR;
+#else
+	chan = MINOR(tty->device) - SERIAL_TTY_MINOR_START;
+#endif
+	
+	if (chan >= KS8695_UART_NUM)
+		return -ENODEV;
+
+	port = &ks8695_table[chan];
+	tty->driver_data = port;
+	port->gs.tty = tty;
+	port->gs.count++;
+
+	rc = gs_init_port(&port->gs);
+	if (rc) {
+		port->gs.count--;
+		return rc;
+	}
+
+	port->gs.flags |= GS_ACTIVE;
+	ks8695_setsignals(port, 1, 1);
+	ks8695_enable_rx_interrupts(port);
+	ks8695_enable_modem_interrupts(port);
+
+	rc = gs_block_til_ready(&port->gs, filp);
+	if (rc) {
+		port->gs.count--;
+		return rc;
+	}
+
+	if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = port->gs.normal_termios;
+		else
+			*tty->termios = port->gs.callout_termios;
+		ks8695_set_real_termios(port);
+	}
+
+	port->gs.session = current->session;
+	port->gs.pgrp = current->pgrp;
+	return 0;
+}
+
+/****************************************************************************/
+
+static int ks8695_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct ks8695_uart_tty_port *port = tty->driver_data;
+	int rc = 0;
+	int ival;
+
+#if DEBUG
+	printk("ks8695_ioctl(cmd=%x,arg=%x)\n", (int)cmd, (int)arg);
+#endif
+
+	switch (cmd) {
+
+	case TIOCGSOFTCAR:
+		rc = put_user((tty->termios->c_cflag & CLOCAL) ? 1 : 0,
+	              (unsigned int *) arg);
+		break;
+
+	case TIOCSSOFTCAR:
+		if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(int))) == 0) {
+			int ival;
+			get_user(ival, (unsigned int *) arg);
+			tty->termios->c_cflag =
+				(tty->termios->c_cflag & ~CLOCAL) |
+				(ival ? CLOCAL : 0);
+		}
+		break;
+
+	case TIOCGSERIAL:
+		if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct serial_struct))) == 0)
+			rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
+		break;
+
+	case TIOCSSERIAL:
+		if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(struct serial_struct))) == 0)
+			rc = gs_setserial(&port->gs, (struct serial_struct *) arg);
+		break;
+
+	case TIOCMGET:
+		ival = ks8695_getsignals(port);
+		rc = put_user(ival, (unsigned int *) arg);
+		break;
+
+	case TIOCMSET:
+		if ((rc = get_user(ival, (unsigned int *) arg)) == 0)
+			ks8695_setsignals(port, ((ival & TIOCM_DTR) ? 1 : 0),
+						((ival & TIOCM_RTS) ? 1 : 0));
+		break;
+
+	default:
+		rc = -ENOIOCTLCMD;
+		break;
+	}
+
+	return rc;
+}
+
+/****************************************************************************/
+
+static int ks8695_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct ks8695_uart_tty_port *port;
+	char str[32];
+	int len = 0;
+	int i, sigs;
+
+	len += sprintf(page, "KS8695 Serial driver (version %s):\n",
+		KS8695_SERIAL_VERSION);
+
+	for (i = 0; (i < KS8695_UART_NUM); i++) {
+		port = &ks8695_table[i];
+		len += sprintf(page+len, "%d: uart:%s port:%x irq:%x",
+			port->chan, "KS8695", (int)port->uartp, port->irq);
+		len += sprintf(page+len, " baud:%d tx:%d rx:%d ",
+			port->gs.baud, port->icount.tx, port->icount.rx);
+
+		if (port->icount.frame)
+			len += sprintf(page+len," fe:%d", port->icount.frame);
+		if (port->icount.parity)
+			len += sprintf(page+len," pe:%d", port->icount.parity);
+		if (port->icount.brk)
+			len += sprintf(page+len," brk:%d", port->icount.brk);
+		if (port->icount.overrun)
+			len += sprintf(page+len," oe:%d", port->icount.overrun);
+
+		str[0] = str[1] = 0;
+		if ((sigs = ks8695_getsignals(port))) {
+			if (sigs & TIOCM_RTS)
+				strcat(str, "|RTS");
+			if (sigs & TIOCM_CTS)
+				strcat(str, "|CTS");
+			if (sigs & TIOCM_DTR)
+				strcat(str, "|DTR");
+			if (sigs & TIOCM_CD)
+				strcat(str, "|CD");
+			if (sigs & TIOCM_DSR)
+				strcat(str, "|DSR");
+		}
+		len += sprintf(page+len, " %s\n", &str[1]);
+	}
+
+	return len;
+}
+
+/****************************************************************************/
+
+static void ks8695_intr_tx(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct ks8695_uart_tty_port *port = dev_id;
+	struct ksuart volatile *uartp;
+	struct ksintctrl volatile *intp;
+	unsigned int ier;
+	int i;
+
+#if DEBUG
+	printk("ks8695_intr_tx(irq=%d)\n", irq);
+#endif
+
+	intp = port->intp;
+	ier = intp->ENABLE;
+	intp->ENABLE &= ~KS8695_INTMASK_UART_TX;
+	uartp = port->uartp;
+
+	if ((port->gs.flags & GS_ACTIVE) == 0) {
+		printk("%s(%d): TX interrupt, not active??\n", __FILE__, __LINE__);
+		ks8695_disable_tx_interrupts(port);
+		return;
+	}
+
+	for (i = 0; (i < KS8695_UART_FIFOSIZE); i++) {
+		if (port->gs.xmit_cnt == 0)
+			break;
+		intp->STATUS = KS8695_INTMASK_UART_TX;
+		uartp->TX = port->gs.xmit_buf[port->gs.xmit_tail];
+		port->gs.xmit_cnt--;
+		port->gs.xmit_tail = (port->gs.xmit_tail + 1) & (SERIAL_XMIT_SIZE-1);
+		port->icount.tx++;
+	}
+
+	if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
+		if ((port->gs.tty->flags & (1<<TTY_DO_WRITE_WAKEUP)) &&
+		    port->gs.tty->ldisc.write_wakeup)
+			(port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
+		wake_up_interruptible(&port->gs.tty->write_wait);
+	}
+
+	if (port->gs.xmit_cnt == 0) {
+		port->gs.flags &= ~GS_TX_INTEN;
+		ier &= ~KS8695_INTMASK_UART_TX;
+#if 1
+	} else {
+		/*
+		 * FIXME: bug in here somehwere. We shouldn't need to keep
+		 * re-enabling the TX interrupt here...
+		 */
+		ier |= KS8695_INTMASK_UART_TX;
+#endif
+	}
+
+	intp->ENABLE = ier;
+}
+
+/****************************************************************************/
+
+static void ks8695_intr_rx(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct ks8695_uart_tty_port *port = dev_id;
+	struct ksuart volatile *uartp;
+	unsigned int lsr;
+	unsigned char status, c;
+
+#if DEBUG
+	printk("ks8695_intr_rx(irq=%d)\n", irq);
+#endif
+
+	uartp = port->uartp;
+
+	if ((port->gs.flags & GS_ACTIVE) == 0) {
+		printk("%s(%d): RX interrupt, not active??\n", __FILE__, __LINE__);
+		ks8695_disable_rx_interrupts(port);
+		while ((lsr = uartp->LSR) & KS8695_UART_LINES_RXFE)
+			c = uartp->RX;
+		return;
+	}
+
+	while ((lsr = uartp->LSR) & KS8695_UART_LINES_RXFE) {
+		c = uartp->RX;
+		if (lsr & KS8695_UART_LINES_OE) {
+			status = TTY_OVERRUN;
+			port->icount.overrun++;
+		} else if (lsr & KS8695_UART_LINES_FE) {
+			status = TTY_FRAME;
+			port->icount.frame++;
+		} else if (lsr & KS8695_UART_LINES_PE) {
+			status = TTY_PARITY;
+			port->icount.parity++;
+		} else if (lsr & KS8695_UART_LINES_BE) {
+			status = TTY_BREAK;
+			port->icount.brk++;
+		} else {
+			status = TTY_NORMAL;
+			port->icount.rx++;
+		}
+
+		tty_insert_flip_char(port->gs.tty, c, status);
+	}
+
+	tty_schedule_flip(port->gs.tty);
+}
+
+/****************************************************************************/
+
+static void ks8695_intr_modem(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct ks8695_uart_tty_port *port = dev_id;
+	struct ksuart volatile *uartp;
+	unsigned int msr;
+
+#if DEBUG
+	printk("ks8695_intr_modem(irq=%d)\n", irq);
+#endif
+
+	/* read this to clear the interrupts */
+	uartp = port->uartp;
+	msr = uartp->MSR;
+
+	if ((port->gs.flags & GS_ACTIVE) == 0) {
+		printk("%s(%d): MODEM interrupt, not active??\n", __FILE__, __LINE__);
+		ks8695_disable_modem_interrupts(port);
+		return;
+	}
+
+	if (msr & KS8695_UART_MODEM_DDCD) {
+		if (port->gs.flags & ASYNC_CHECK_CD) {
+			if (ks8695_get_CD(port)) {
+				if (~(port->gs.flags & ASYNC_NORMAL_ACTIVE) ||
+				    ~(port->gs.flags & ASYNC_CALLOUT_ACTIVE)) 
+					wake_up_interruptible(&port->gs.open_wait);
+			} else {
+				if (!((port->gs.flags & ASYNC_CALLOUT_ACTIVE) &&
+				    (port->gs.flags & ASYNC_CALLOUT_NOHUP)))
+					if (port->gs.tty)
+						tty_hangup(port->gs.tty);
+			}
+		}
+	}
+
+	if (msr & KS8695_UART_MODEM_DDSR)
+		/* FIXME */;
+	if (msr & KS8695_UART_MODEM_DCTS)
+		/* FIXME */;
+}
+
+/****************************************************************************/
+
+static struct real_driver ks8695_uart_driver = {
+	.enable_tx_interrupts = ks8695_enable_tx_interrupts,
+	.disable_tx_interrupts = ks8695_disable_tx_interrupts,
+	.enable_rx_interrupts = ks8695_enable_rx_interrupts,
+	.disable_rx_interrupts = ks8695_disable_rx_interrupts,
+	.get_CD = ks8695_get_CD,
+	.shutdown_port = ks8695_shutdown_port,
+	.set_real_termios = ks8695_set_real_termios,
+	.chars_in_buffer = ks8695_chars_in_buffer,
+	.close = ks8695_close,
+	.hungup = ks8695_hungup,
+	.getserial = ks8695_getserial,
+};
+
+/****************************************************************************/
+
+static void __init ks8695_init_ports(void)
+{
+	struct ks8695_uart_tty_port *port;
+	int i;
+
+	for (i = 0; (i < KS8695_UART_NUM); i++) {
+		port = &ks8695_table[i];
+		port->chan = i;
+		port->base = KS8695_UART_ADDR;
+		port->uartp = (void *) KS8695_UART_ADDR;
+		port->intp = (void *) KS8695_INTCTRL_ADDR;
+		port->irq = KS8695_INT_UART_RX;
+		port->gs.magic = KS8695_UART_MAGIC;
+		port->gs.rd = &ks8695_uart_driver;
+		port->gs.close_delay = HZ / 2;
+		port->gs.closing_wait = 30 * HZ;
+		port->gs.normal_termios = ks8695_driver.init_termios;
+		port->gs.callout_termios = ks8695_callout_driver.init_termios;
+		memset(&port->icount, 0, sizeof(port->icount));
+		init_waitqueue_head(&port->gs.open_wait);
+		init_waitqueue_head(&port->gs.close_wait);
+		printk("ttyS%d at 0x%p is builtin UART\n", i, port->uartp);
+
+		ks8695_disable_rx_interrupts(port);
+		ks8695_disable_tx_interrupts(port);
+		ks8695_disable_modem_interrupts(port);
+
+		if (request_irq(KS8695_INT_UART_TX, ks8695_intr_tx,
+		    SA_SHIRQ, "ks8695 uart TX", port)) {
+			printk("KS8695_SERIAL: fail to get %d interrupt\n",
+				KS8695_INT_UART_TX);
+		}
+		if (request_irq(KS8695_INT_UART_RX, ks8695_intr_rx,
+		    SA_SHIRQ, "ks8695 uart RX", port)) {
+			printk("KS8695_SERIAL: fail to get %d interrupt\n",
+				KS8695_INT_UART_RX);
+		}
+		if (request_irq(KS8695_INT_UART_LINE_ERR, ks8695_intr_rx,
+		    SA_SHIRQ, "ks8695 uart error", port)) {
+			printk("KS8695_SERIAL: fail to get %d interrupt\n",
+				KS8695_INT_UART_LINE_ERR);
+		}
+		if (request_irq(KS8695_INT_UART_MODEMS, ks8695_intr_modem,
+		    SA_SHIRQ, "ks8695 uart modem", port)) {
+			printk("KS8695_SERIAL: fail to get %d interrupt\n",
+				KS8695_INT_UART_MODEMS);
+		}
+	}
+}
+
+/****************************************************************************/
+
+static int __init ks8695_init(void)
+{
+	printk("KS8695_SERIAL: Kendin/Micrel KS8695 serial driver\n");
+
+	memset(&ks8695_driver, 0, sizeof(ks8695_driver));
+	ks8695_driver.magic = TTY_DRIVER_MAGIC;
+	ks8695_driver.driver_name = "serial";
+
+#if KS8695_UART_AMBA_DEVICE
+	ks8695_driver.name = "ttyAM";
+	ks8695_driver.major = SERIAL_AMBA_MAJOR;
+	ks8695_driver.minor_start = SERIAL_AMBA_MINOR;
+#else
+	ks8695_driver.name = "ttyS";
+	ks8695_driver.major = TTY_MAJOR;
+	ks8695_driver.minor_start = SERIAL_TTY_MINOR_START;
+#endif
+
+	ks8695_driver.num = KS8695_UART_NUM;
+	ks8695_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	ks8695_driver.subtype = SERIAL_TYPE_NORMAL;
+	ks8695_driver.init_termios = tty_std_termios;
+	ks8695_driver.init_termios.c_cflag = 
+		B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+	ks8695_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+	ks8695_driver.refcount = &ks8695_refcount;
+	ks8695_driver.table = ks8695_tty_table;
+	ks8695_driver.termios = ks8695_termios;
+	ks8695_driver.termios_locked = ks8695_termios_locked;
+
+	ks8695_driver.open = ks8695_open;
+	ks8695_driver.close = gs_close;
+	ks8695_driver.write = gs_write;
+	ks8695_driver.put_char = gs_put_char;
+	ks8695_driver.flush_chars = gs_flush_chars;
+	ks8695_driver.write_room = gs_write_room;
+	ks8695_driver.chars_in_buffer = gs_chars_in_buffer;
+	ks8695_driver.flush_buffer = gs_flush_buffer;
+	ks8695_driver.ioctl = ks8695_ioctl;
+	//ks8695_driver.throttle = ks8695_throttle;
+	//ks8695_driver.unthrottle = ks8695_unthrottle;
+	ks8695_driver.set_termios = gs_set_termios;
+	ks8695_driver.stop = gs_stop;
+	ks8695_driver.start = gs_start;
+	ks8695_driver.hangup = gs_hangup;
+	//ks8695_driver.break_ctl = ks8695_break;
+	//ks8695_driver.send_xchar = ks8695_send_xchar;
+	//ks8695_driver.wait_until_sent = ks8695_wait_until_sent;
+	ks8695_driver.read_proc = ks8695_read_proc;
+
+	ks8695_callout_driver = ks8695_driver;
+
+#if KS8695_UART_AMBA_DEVICE
+	ks8695_callout_driver.name = "cuaam";
+	ks8695_callout_driver.major = CALLOUT_AMBA_MAJOR;
+#else
+	ks8695_callout_driver.name = "cua";
+	ks8695_callout_driver.major = TTYAUX_MAJOR;
+#endif
+
+	ks8695_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+	ks8695_callout_driver.read_proc = 0;
+
+	ks8695_init_ports();
+
+	if (tty_register_driver(&ks8695_driver))
+		panic("KJS8695_SERIAL: couldn't register serial driver\n");
+	if (tty_register_driver(&ks8695_callout_driver))
+		panic("KJS8695_SERIAL: couldn't register callout driver\n");
+
+	return 0;
+}
+
+/****************************************************************************/
+/*                           SERIAL CONSOLE                                 */
+/****************************************************************************/
+
+static kdev_t ks8695_console_device(struct console *c)
+{
+#if KS8695_UART_AMBA_DEVICE
+	 return MKDEV(SERIAL_AMBA_MAJOR, SERIAL_AMBA_MINOR + c->index);
+#else
+	 return MKDEV(TTY_MAJOR, SERIAL_TTY_MINOR_START + c->index);
+#endif
+}
+
+/****************************************************************************/
+
+static int __init ks8695_console_setup(struct console *co, char *options)
+{
+	struct ksuart volatile *uartp = (void *) KS8695_UART_ADDR;
+	unsigned int cflag = CREAD | HUPCL | CLOCAL;
+	unsigned int lcr = 0;
+	int baud = 115200;
+	int bits = 8;
+	int parity = 'n';
+	int doflow = 0;
+	char *s;
+
+	if (options) {
+		baud = simple_strtoul(options, NULL, 10);
+		for (s = options; ((*s >= '0') && (*s <= '9')); s++)
+			;
+		if (*s)
+			parity = *s++;
+		if (*s)
+			bits = *s++ - '0';
+		if (*s)
+			doflow = (*s++ == 'r');
+	}
+
+	switch (baud) {
+	case 300:
+		cflag |= B300;
+		break;
+	case 1200:
+		cflag |= B1200;
+		break;
+	case 2400:
+		cflag |= B2400;
+		break;
+	case 4800:
+		cflag |= B4800;
+		break;
+	case 9600:
+		cflag |= B9600;
+		break;
+	case 19200:
+		cflag |= B19200;
+		break;
+	case 38400:
+		cflag |= B38400;
+		break;
+	case 57600:
+		cflag |= B57600;
+		break;
+	case 230400:
+		cflag |= B230400;
+		break;
+	default:
+		cflag |= B115200;
+		baud = 115200;
+		break;
+	}
+
+	switch (bits) {
+	case 7:
+		cflag |= CS7;
+		lcr |= KS8695_UART_LINEC_WLEN7;
+		break;
+	default:
+		cflag |= CS8;
+		lcr |= KS8695_UART_LINEC_WLEN8;
+		bits = 8;
+		break;
+	}
+
+	switch (parity) {
+	case 'o':
+		cflag |= PARENB | PARODD;
+		lcr |= KS8695_UART_LINEC_PEN;
+		break;
+	case 'e':
+		cflag |= PARENB;
+		lcr |= KS8695_UART_LINEC_PEN | KS8695_UART_LINEC_EPS;
+		break;
+	}
+
+	co->cflag = cflag;
+	uartp->BD = (KS8695_UART_CLK / baud);
+	uartp->LCR = lcr;
+	return 0;
+}
+
+/****************************************************************************/
+
+static void ks8695_console_writechar(struct console *co, const char c)
+{
+	struct ksuart volatile *uartp = (void *) KS8695_UART_ADDR;
+	int i;
+
+	for (i = 0; (i < 0x10000); i++)
+		if (uartp->LSR & KS8695_UART_LINES_TXFE)
+			break;
+	uartp->TX = c;
+	
+	if  (c == '\n') {
+	    for (i = 0; (i < 0x10000); i++)
+		if (uartp->LSR & KS8695_UART_LINES_TXFE)
+			break;
+	    uartp->TX = '\r';
+	    }	
+
+	for (i = 0; (i < 0x10000); i++)
+		if (uartp->LSR & KS8695_UART_LINES_TXFE)
+			break;
+}
+
+/****************************************************************************/
+
+static void ks8695_console_write(struct console *co, const char *s, unsigned int count)
+{
+	for (; (count > 0); count--)
+		ks8695_console_writechar(co, *s++);
+}
+
+/****************************************************************************/
+
+static struct console ks8695_am_console = {
+	.name = "ttyAM",
+	.write = ks8695_console_write,
+	.device = ks8695_console_device,
+	.setup = ks8695_console_setup,
+	.flags = CON_PRINTBUFFER,
+	.index = -1,
+};
+
+static struct console ks8695_console = {
+	.name = "ttyS",
+	.write = ks8695_console_write,
+	.device = ks8695_console_device,
+	.setup = ks8695_console_setup,
+	.flags = CON_PRINTBUFFER,
+	.index = -1,
+};
+
+
+void __init ks8695_console_init(void)
+{
+	/* We register as both ttyAM? and ttyS? so that both
+	 * are acceptable on the command line */
+	register_console(&ks8695_am_console);
+	register_console(&ks8695_console);
+}
+
+/****************************************************************************/
+
+module_init(ks8695_init);
+MODULE_DESCRIPTION("Kendin/Micrel serial port driver");
+MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>");
+MODULE_LICENSE("GPL");
+
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/char/serial_ks8695.h linux-2.4.29-uc1/drivers/char/serial_ks8695.h
--- linux-2.4.29/drivers/char/serial_ks8695.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_ks8695.h	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,42 @@
+/****************************************************************************/
+
+/*
+ *	serial_ks8695.h -- Kendin/Micrel KS8695 UART support defines.
+ *
+ *	(C) Copyright 2003, Greg Ungerer <gerg@snapgear.com>
+ */
+
+/****************************************************************************/
+#ifndef	serial_ks8695_h
+#define	serial_ks8695_h
+/****************************************************************************/
+
+/*
+ *	The internal UART of the Kendin/Micrel KS8696 is a mutant
+ *	relation of the 8250/16550. Sort of similar and osrt of different.
+ *	Some common defines could be used, but I have not bothered here.
+ */
+
+/*
+ *	Define the UART register access structure.
+ */
+struct ksuart {
+	unsigned int	RX;		/* 0x00	- Receive data (r) */
+	unsigned int	TX;		/* 0x04	- Transmit data (w) */
+	unsigned int	FCR;		/* 0x08	- Fifo Control (r/w) */
+	unsigned int	LCR;		/* 0x0c	- Line Control (r/w) */
+	unsigned int	MCR;		/* 0x10	- Modem Control (r/w) */
+	unsigned int	LSR;		/* 0x14	- Line Status (r/w) */
+	unsigned int	MSR;		/* 0x18	- Modem Status (r/w) */
+	unsigned int	BD;		/* 0x1c	- Baud Rate (r/w) */
+	unsigned int	SR;		/* 0x20	- Status (r/w) */
+};
+
+struct ksintctrl {
+	unsigned int	CONTL;		/* 0x00 - Interrupt control (r/w) */
+	unsigned int	ENABLE;		/* 0x04 - Interrupt enable (r/w) */
+	unsigned int	STATUS;		/* 0x08 - Interrupt status (r/w) */
+};
+
+/****************************************************************************/
+#endif	/* serial_ks8695_h */
diff -urN linux-2.4.29/drivers/char/serial_netarm.c linux-2.4.29-uc1/drivers/char/serial_netarm.c
--- linux-2.4.29/drivers/char/serial_netarm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_netarm.c	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,2590 @@
+/*
+ * linux/drivers/char/serial_netarm.c
+ *
+ * Copyright (C) 2001  IMMS gGmbH
+ *
+ * This software is provided "AS-IS" and without any express or implied 
+ * warranties or conditions.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This particular file is derived from serial.c by Linus Torvalds and
+ * Theodore Ts'o and from Joe deBlaquiere's serial-netarm.c from
+ * the 2.0.38 Net-Lx kernel.
+ * see linux/drivers/char/serial.c for version history and credits
+ *
+ * 06/01: first working adaption to Net+ARM built-in serial interfaces
+ *
+ * author(s) : Rolf Peukert
+ *
+ */
+
+static char *serial_version = "0.2";
+static char *serial_revdate = "2002-02-27";
+
+/*
+ * Serial driver configuration section.  Here are the various options:
+ *
+ * SERIAL_PARANOIA_CHECK
+ * 		Check the magic number for the netarm_async structure
+ * 		where ever possible.
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+
+#undef SERIAL_PARANOIA_CHECK
+#define CONFIG_SERIAL_NOPAUSE_IO
+#define SERIAL_DO_RESTART
+
+/* Set of debugging defines */
+
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+#undef SERIAL_DEBUG_PCI
+#undef SERIAL_DEBUG_AUTOCONF
+
+/* Sanity checks */
+
+#ifdef MODULE
+#undef CONFIG_SERIAL_NETARM_CONSOLE
+#endif
+
+#define RS_STROBE_TIME (10*HZ)
+#define RS_ISR_PASS_LIMIT 256
+
+/*
+ * End of serial driver configuration section.
+ */
+
+#include <linux/module.h>
+
+#include <linux/types.h>
+#ifdef LOCAL_HEADERS
+#include "serial_local.h"
+#else
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+#include <asm/serial.h>
+#define LOCAL_VERSTRING ""
+#endif
+
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <linux/delay.h>
+#ifdef CONFIG_SERIAL_NETARM_CONSOLE
+#include <linux/console.h>
+#endif
+#ifdef CONFIG_MAGIC_SYSRQ
+#include <linux/sysrq.h>
+#endif
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+#endif
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+
+#include <asm/arch/netarm_registers.h>
+
+#ifdef SERIAL_NETARM_INLINE
+#define _INLINE_ inline
+#else
+#define _INLINE_
+#endif
+
+static char *serial_name = "Net+ARM serial driver";
+
+static DECLARE_TASK_QUEUE(tq_serial);
+
+static struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+static struct timer_list serial_timer;
+
+/* serial subtype definitions */
+#ifndef SERIAL_TYPE_NORMAL
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+#endif
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+/* Wait until transmitter is ready for another character */
+#define NAS_TX_WAIT_RDY(registers) while \
+ ((registers->status_a & NETARM_SER_STATA_TX_RDY) == 0){}
+
+/* Device descriptor arrays for our serial ports */
+static struct netarm_async_struct NAS_ports[NR_NAS_PORTS];
+
+static struct serial_state rs_table[NR_NAS_PORTS] = {
+	NETARM_SERIAL_PORT_DFNS	/* Defined in serial.h */
+};
+
+#ifdef CONFIG_SERIAL_NETARM_CONSOLE
+static struct console sercons;
+static int lsr_break_flag;
+#endif
+#if defined(CONFIG_SERIAL_NETARM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+static unsigned long break_pressed; /* break, really ... */
+#endif
+
+static void autoconfig(struct serial_state * state);
+static void change_speed(struct netarm_async_struct *info, struct termios *old);
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
+
+#ifndef PREPARE_FUNC
+#define PREPARE_FUNC(dev)  (dev->prepare)
+#define ACTIVATE_FUNC(dev)  (dev->activate)
+#define DEACTIVATE_FUNC(dev)  (dev->deactivate)
+#endif
+
+#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
+
+static struct tty_struct *serial_table[NR_NAS_PORTS];
+static struct termios *serial_termios[NR_NAS_PORTS];
+static struct termios *serial_termios_locked[NR_NAS_PORTS];
+
+#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
+#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
+ kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s)
+#else
+#define DBG_CNT(s)
+#endif
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the copy_from_user blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static unsigned char *tmp_buf;
+#ifdef DECLARE_MUTEX
+static DECLARE_MUTEX(tmp_buf_sem);
+#else
+static struct semaphore tmp_buf_sem = MUTEX;
+#endif
+
+
+static inline int
+serial_paranoia_check(struct netarm_async_struct *info,
+			kdev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for netarm serial struct (%s) in %s\n";
+	static const char *badinfo =
+		"Warning: null netarm_async_struct for (%s) in %s\n";
+
+	if (!info) {
+		printk(badinfo, kdevname(device), routine);
+		return 1;
+	}
+	if (info->magic != NAS_MAGIC) {
+		printk(badmagic, kdevname(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void
+rs_stop(struct tty_struct *tty)
+{
+	struct netarm_async_struct *info = (struct netarm_async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_stop"))
+		return;
+	
+	save_flags(flags); cli();
+	/* disable all interrupt sources */
+	info->registers->ctrl_a = info->registers->ctrl_a & 0xFFFF0000;
+	restore_flags(flags);
+}
+
+static void
+rs_start(struct tty_struct *tty)
+{
+	struct netarm_async_struct *info = (struct netarm_async_struct *)tty->driver_data;
+	unsigned long flags;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_start"))
+		return;
+	
+	save_flags(flags); cli();
+	/* enable rx interrupts */
+	info->registers->ctrl_a = info->registers->ctrl_a
+	                          | NETARM_SER_CTLA_IE_RX_RDY
+				  | NETARM_SER_CTLA_IE_RX_FULL;
+	restore_flags(flags);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ * Mask&Acknowledge functions, needed by arch/armnommu/mach-netarm/irq.c
+ *
+ * These functions save the current status bits in the netarm_async_struc
+ * structure, because the status is cleared by acknowledging the IRQ.
+ * Each function is used for both RX and TX interrupts.
+ * ----------------------------------------------------------------------
+ */
+void
+nas_mask_ack_serial1_irq( unsigned int irq )
+{
+	volatile unsigned long int *mask = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_INTR_ENABLE_CLR);
+	volatile unsigned long int *stat_a =
+		(volatile unsigned long *)(NETARM_SER_MODULE_BASE +
+		NETARM_SER_CH1_STATUS_A);
+	
+	if ((irq == IRQ_SER1_TX) || (irq == IRQ_SER1_RX))
+	{
+		NAS_ports[0].SCSRA = *stat_a;	/* save current status */
+		*mask  	= (1 << irq);		/* set mask bit */
+		*stat_a	= 0xFFFF;		/* clear all IRQ pending bits */
+	}
+}
+void
+nas_mask_ack_serial2_irq( unsigned int irq )
+{
+	volatile unsigned long int *mask = 
+		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_INTR_ENABLE_CLR);
+	volatile unsigned long int *stat_a =
+		(volatile unsigned long *)(NETARM_SER_MODULE_BASE +
+		NETARM_SER_CH2_STATUS_A);
+
+	if ((irq == IRQ_SER2_TX) || (irq == IRQ_SER2_RX))
+	{
+		NAS_ports[1].SCSRA = *stat_a;	/* save current status */
+		*mask  	= (1 << irq);		/* set mask bit */
+		*stat_a	= 0xFFFF;		/* clear all IRQ pending bits */
+	}
+}
+
+/* Hook interrupts into System */
+
+static int 
+nas_interrupts_init(void)
+{
+  int retval;
+
+  retval = request_irq (IRQ_SER1_RX,
+			nas_rx_interrupt_1,
+			0,
+			"NetARM Serial1 Receive",
+			&NAS_ports[0]);
+  if (retval != 0) {
+    printk("nas_interrupts_init: failed to register serial1 rx interrupt (%d)\n", retval);
+    return retval;
+  }
+  retval = request_irq (IRQ_SER2_RX,
+			nas_rx_interrupt_2,
+			0,
+			"NetARM Serial2 Receive",
+			&NAS_ports[1]);
+  if (retval != 0) {
+    printk("nas_interrupts_init: failed to register serial2 rx interrupt (%d)\n", retval);
+    return retval;
+  }
+  return 0;
+}
+
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here start the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ * 
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assemble code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static _INLINE_ void
+rs_sched_event(struct netarm_async_struct *info, int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_serial);
+	mark_bh(SERIAL_BH);
+}
+
+static _INLINE_ void
+receive_chars(struct netarm_async_struct *info, int *status, struct pt_regs * p_regs)
+{
+	struct tty_struct *tty = info->tty;
+	unsigned int ch_uint;
+	struct	async_icount *icount;
+	int	buf_count = 0;
+	volatile unsigned int *fifo;
+	volatile unsigned char *fifo_char = NULL;
+	volatile netarm_serial_channel_t *regs = info->registers ;
+
+	icount = &info->state->icount;
+	fifo = (volatile unsigned int*)&(regs->fifo) ;
+
+	do
+	{
+	    fifo_char = (unsigned char *)&ch_uint ;
+	    if (*status & NETARM_SER_STATA_RX_RDY)
+    	    {
+      		/* need to read the whole buffer (1 to 4 bytes) */
+      		ch_uint = *fifo;
+		/* check the status word to see how many bytes are pending */
+		buf_count = NETARM_SER_STATA_RXFDB(*status);
+		switch (buf_count)
+      		{
+		    case NETARM_SER_STATA_RXFDB_4BYTES:
+			buf_count = 4;
+			break;	      
+		    case NETARM_SER_STATA_RXFDB_3BYTES:      
+			buf_count = 3;
+			break;
+		    case NETARM_SER_STATA_RXFDB_2BYTES:
+			buf_count = 2;
+			break;
+		    case NETARM_SER_STATA_RXFDB_1BYTES:
+			buf_count = 1;
+			break;
+		    default:
+			printk("receive_chars: AIEE!! GARBAGE!\n");
+		}
+	    }
+	    else
+	    {
+		ch_uint = 0;
+		buf_count = 0;
+	    }
+    
+	    /* read all available characters from FIFO */
+	    while ((buf_count-- > 0) && (tty->flip.count < TTY_FLIPBUF_SIZE))
+	    {
+		*tty->flip.flag_buf_ptr = 0 ;
+
+		/* handle port error conditions */
+		if (*status & NETARM_SER_STATA_RX_BRK)
+	    	{
+		    *tty->flip.flag_buf_ptr = TTY_BREAK ;
+		    icount->brk++;
+		/*
+		 * We do the SysRQ and SAK checking
+		 * here because otherwise the break
+		 * may get masked by ignore_status_mask
+		 * or read_status_mask.
+		 */
+#if defined(CONFIG_SERIAL_NETARM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+		if (info->line == sercons.index) {
+			if (!break_pressed) {
+				break_pressed = jiffies;
+				goto ignore_char;
+			}
+			break_pressed = 0;
+		}
+#endif
+		    if (info->flags & ASYNC_SAK) do_SAK(tty);
+		}
+		else if (*status & NETARM_SER_STATA_RX_PARERR)
+		{
+		    *tty->flip.flag_buf_ptr = TTY_PARITY ;
+		    icount->parity++;
+		}
+		else if (*status & NETARM_SER_STATA_RX_FRMERR)
+		{
+		    *tty->flip.flag_buf_ptr = TTY_FRAME ;
+		    icount->frame++;
+		}
+		else if (*status & NETARM_SER_STATA_RX_OVERRUN)
+		{
+		    *tty->flip.flag_buf_ptr = TTY_OVERRUN ;
+		    icount->overrun++;
+		}
+
+#ifdef CONFIG_SERIAL_NETARM_CONSOLE
+		if (info->line == sercons.index)
+		{
+		    /* Recover the break flag from console xmit */
+		    *status |= lsr_break_flag;
+		    lsr_break_flag = 0;
+		}
+#endif
+		if (*status & (NETARM_SER_STATA_RX_BRK))
+		{
+#ifdef SERIAL_DEBUG_INTR
+		    printk("handling break....");
+#endif
+		    *tty->flip.flag_buf_ptr = TTY_BREAK;
+		}
+
+#if defined(CONFIG_SERIAL_NETARM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+		if (break_pressed && info->line == sercons.index)
+		{
+		    if (ch != 0 &&
+			time_before(jiffies, break_pressed + HZ*5))
+		    {
+			handle_sysrq(ch, p_regs, NULL, NULL);
+			break_pressed = 0;
+			goto ignore_char;
+		    }
+		    break_pressed = 0;
+		}
+#endif
+
+#ifdef SERIAL_DEBUG_INTR
+		printk("receive_chars: %02x (%02x)", *fifo_char, *status);
+#endif
+		*tty->flip.char_buf_ptr = *fifo_char;
+		tty->flip.count++;
+		tty->flip.flag_buf_ptr++;
+		tty->flip.char_buf_ptr++;
+		fifo_char++ ;
+		icount->rx++;
+	    }
+
+#if defined(CONFIG_SERIAL_NETARM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+	ignore_char:
+#endif
+	    /* read status anew */
+	    *status = regs->status_a ;
+	}
+	while ((*status & NETARM_SER_STATA_RX_RDY) 
+	      && (tty->flip.count < TTY_FLIPBUF_SIZE));
+
+	tty_flip_buffer_push(tty);
+}
+
+static _INLINE_ void
+check_modem_status(struct netarm_async_struct *info)
+{
+	int	status;
+	struct	async_icount *icount;
+	
+	status = info->SCSRA;
+
+	if (status & (NETARM_SER_STATA_RI|NETARM_SER_STATA_DSR
+	             |NETARM_SER_STATA_DCD|NETARM_SER_STATA_CTS))
+	{
+		icount = &info->state->icount;
+		/* update input line counters */
+		if (status & NETARM_SER_STATA_RI)
+			icount->rng++;
+		if (status & NETARM_SER_STATA_DSR)
+			icount->dsr++;
+		if (status & NETARM_SER_STATA_DCD)
+			icount->dcd++;
+		if (status & NETARM_SER_STATA_CTS)
+			icount->cts++;
+		wake_up_interruptible(&info->delta_msr_wait);
+	}
+
+	if ((info->flags & ASYNC_CHECK_CD) && (status & NETARM_SER_STATA_DCD)) {
+#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
+		printk("ttys%d CD now %s...", info->line,
+		       (status & NETARM_SER_STATA_DCD) ? "on" : "off");
+#endif		
+		if (status & NETARM_SER_STATA_DCD)
+			wake_up_interruptible(&info->open_wait);
+		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+			   (info->flags & ASYNC_CALLOUT_NOHUP))) {
+#ifdef SERIAL_DEBUG_OPEN
+			printk("doing serial hangup...");
+#endif
+			if (info->tty)
+				tty_hangup(info->tty);
+		}
+	}
+	if (info->flags & ASYNC_CTS_FLOW) {
+		if (info->tty->hw_stopped) {
+			if (status & NETARM_SER_STATA_CTS) {
+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
+				printk("CTS tx start...");
+#endif
+				info->tty->hw_stopped = 0;
+			/* FIXME: do we need rs_sched_event() here?
+				info->IER |= UART_IER_THRI;
+				serial_out(info, UART_IER, info->IER);
+				rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);*/
+				return;
+			}
+		} else {
+			if (!(status & NETARM_SER_STATA_CTS)) {
+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
+				printk("CTS tx stop...");
+#endif
+				info->tty->hw_stopped = 1;
+			/*	info->IER &= ~UART_IER_THRI;
+				serial_out(info, UART_IER, info->IER);*/
+			}
+		}
+	}
+}
+
+
+/*
+ * -------------------------------------------------------------------
+ * This is the serial driver's interrupt routine for a single port
+ * -------------------------------------------------------------------
+ */
+
+static _INLINE_ void
+nas_rx_interrupt(struct netarm_async_struct *info, struct pt_regs *regs)
+{
+ 	int status;
+	int pass_counter = 0;
+	
+	if (!info || !info->tty) return;
+
+	do
+	{
+ 		status = info->SCSRA;
+#ifdef SERIAL_DEBUG_INTR
+		printk("status = %x...", status);
+#endif
+		if (status & (NETARM_SER_STATA_RX_RDY
+		             |NETARM_SER_STATA_RX_HALF
+			     |NETARM_SER_STATA_RX_FULL))
+			receive_chars(info, &status, regs);
+/* FIXME:
+   do we need check_modem_status() if we don't want to transmit anything?
+		check_modem_status(info);
+		if (status & UART_LSR_THRE)
+			transmit_chars(info, 0);
+*/
+		if (pass_counter++ > RS_ISR_PASS_LIMIT)
+		{
+#if 0
+			printk("rs_single loop break.\n");
+#endif
+			break;
+		}
+#ifdef SERIAL_DEBUG_INTR
+		printk("STAT_A = %x...", info->registers->status_a);
+#endif
+	}
+	while (NETARM_SER_STATA_RX_RDY & (info->SCSRA = info->registers->status_a));
+	info->last_active = jiffies;
+#ifdef SERIAL_DEBUG_INTR
+	printk("end.\n");
+#endif
+}
+
+
+static void
+nas_rx_interrupt_1(int irq, void *dev_id, struct pt_regs *regs)
+{
+#if (defined(SERIAL_DEBUG_INTR) && defined(NAS_DEBUG_VERBOSE))
+  printk(" nas_rx_interrupt_1: int!\n");
+#endif
+
+  nas_rx_interrupt(&NAS_ports[0], regs) ;
+}
+
+static void
+nas_rx_interrupt_2(int irq, void *dev_id, struct pt_regs *regs)
+{
+#if (defined(SERIAL_DEBUG_INTR) && defined(NAS_DEBUG_VERBOSE))
+  printk(" nas_rx_interrupt_2: int!\n");
+#endif
+
+  nas_rx_interrupt(&NAS_ports[1], regs) ;
+}
+
+/*
+ * -------------------------------------------------------------------
+ * Here end the serial interrupt routines
+ * -------------------------------------------------------------------
+ */
+
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void
+do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+}
+
+static void
+do_softint(void *private_)
+{
+	struct netarm_async_struct *info = (struct netarm_async_struct *) private_;
+	struct tty_struct          *tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+		wake_up_interruptible(&tty->poll_wait);
+#endif
+	}
+}
+
+
+/*
+ * ---------------------------------------------------------------
+ * Low level utility subroutines for the serial driver:  routines
+ * to initialize and startup a serial port, and routines to shutdown a
+ * serial port.  Useful stuff like that.
+ * ---------------------------------------------------------------
+ */
+
+static int 
+nas_validate_baud(int baud)
+{
+  if (baud >= MIN_BAUD_RATE && baud <= MAX_BAUD_RATE) return 0;
+  return 1;
+}
+
+/*
+ * This is used to figure out the divisor speeds and the timeouts
+ */
+
+static int nas_baud_table[] = {
+	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
+	9600, 19200, 38400, 57600, 115200, 0 };
+
+static int nas_n_baud_table = sizeof(nas_baud_table)/sizeof(int);
+
+/* nas_tty_get_baud_rate is borrowed from 2.2.12 tty_io.c		*/
+/* since the netarm serial driver is based upon the 2.2.x source 	*/
+/* rather than the 2.0.X. The reasons for this are purely historical 	*/
+
+int
+nas_tty_get_baud_rate(struct tty_struct *tty)
+{
+	unsigned int cflag, i;
+
+	cflag = tty->termios->c_cflag;
+
+	i = cflag & CBAUD;
+	if (i & CBAUDEX)
+	{
+		i &= ~CBAUDEX;
+		if (i < 1 || i+15 >= nas_n_baud_table) 
+			tty->termios->c_cflag &= ~CBAUDEX;
+		else
+			i += 15;
+	}
+	return nas_baud_table[i];
+}
+
+static int
+startup(struct netarm_async_struct * info)
+{
+	unsigned long		flags;
+	int			baud, retval=0;
+	struct serial_state 	*state = info->state;
+	unsigned long 		page;
+	volatile netarm_serial_channel_t *regs;
+
+	/* check the baud rate */
+	baud = nas_tty_get_baud_rate(info->tty);
+	if (nas_validate_baud(baud) != 0)
+	{
+	    printk("nas_startup_port: invalid baud rate from tty struct: %d\n", baud);
+	    return -EINVAL;
+	}
+	info->baud = baud;
+
+	page = get_zeroed_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	save_flags(flags); cli();
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		free_page(page);
+		goto errout;
+	}
+
+	if (!CONFIGURED_SERIAL_PORT(state) || !state->type) {
+		if (info->tty)
+			set_bit(TTY_IO_ERROR, &info->tty->flags);
+		free_page(page);
+		goto errout;
+	}
+	if (info->xmit.buf)
+		free_page(page);
+	else
+		info->xmit.buf = (unsigned char *) page;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Starting up ttyS%d (irq %d) at %d baud...\n",
+	        info->line, state->irq, info->baud);
+#endif
+
+	/* Wake up and initialize SER module */
+	regs = info->registers;
+	regs->rx_match = 0;
+	regs->rx_buf_timer = 0;
+	regs->bitrate = NETARM_SER_BR_X16(baud);
+	regs->rx_char_timer = NETARM_SER_RXGAP(baud);
+	regs->ctrl_b = NETARM_SER_CTLB_RCGT_EN | NETARM_SER_CTLB_UART_MODE;
+#ifdef POLLED_SERIAL
+	regs->ctrl_a |= NETARM_SER_CTLA_ENABLE ;
+#else
+	/* enable interrupts */
+	regs->ctrl_a |= NETARM_SER_CTLA_ENABLE | NETARM_SER_CTLA_IE_RX_RDY | 
+	                NETARM_SER_CTLA_IE_RX_FULL ;
+#endif
+	/*
+	 * Set up the tty->alt_speed kludge
+	 */
+	if (info->tty) {
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+			info->tty->alt_speed = 57600;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+			info->tty->alt_speed = 115200;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+			info->tty->alt_speed = 230400;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+			info->tty->alt_speed = 460800;
+	}
+	/*
+	 * and set the speed of the serial port
+	 */
+	change_speed(info, 0);
+
+	info->flags |= ASYNC_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+errout:
+	restore_flags(flags);
+	return retval;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void
+shutdown(struct netarm_async_struct * info)
+{
+	unsigned long flags;
+	struct serial_state *state;
+	volatile netarm_serial_channel_t *regs;
+
+	if (!(info->flags & ASYNC_INITIALIZED))
+		return;
+
+	state = info->state;
+	regs  = info->registers;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Shutting down serial port %d (irq %d)...\n", info->line,
+	       state->irq);
+#endif	
+	save_flags(flags); cli(); /* Disable interrupts */
+
+	/*
+	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+	 * here so the queue might never be waken up
+	 */
+	wake_up_interruptible(&info->delta_msr_wait);
+	
+	if (info->xmit.buf) {
+		unsigned long pg = (unsigned long) info->xmit.buf;
+		info->xmit.buf = 0;
+		free_page(pg);
+	}
+
+	/* turn off the port */
+	regs->ctrl_a &= ~NETARM_SER_CTLA_ENABLE ;	
+	
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~ASYNC_INITIALIZED;
+	restore_flags(flags);
+}
+
+/*
+ * This routine is called to set the specified baud rate for a serial port.
+ */
+static void
+change_speed(struct netarm_async_struct *info, struct termios *old_termios)
+{
+	volatile netarm_serial_channel_t *regs;
+	int	quot = 0, baud_base, baud;
+	unsigned cflag, cval;
+	int	bits;
+	unsigned long flags;
+
+	regs  = info->registers;
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+	if (!CONFIGURED_NAS_PORT(info))
+		return;
+
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	      case CS5: cval = NETARM_SER_CTLA_5BITS; bits = 7; break;
+	      case CS6: cval = NETARM_SER_CTLA_6BITS; bits = 8; break;
+	      case CS7: cval = NETARM_SER_CTLA_7BITS; bits = 9; break;
+	      case CS8: cval = NETARM_SER_CTLA_8BITS; bits = 10; break;
+	      /* Never happens, but GCC is too dumb to figure it out */
+	      default:  cval = NETARM_SER_CTLA_5BITS; bits = 7; break;
+	}
+	if (cflag & CSTOPB) {
+		cval |= NETARM_SER_CTLA_2STOP;
+		bits++;
+	}
+	if (cflag & PARENB) {
+		cval |= NETARM_SER_CTLA_P_ODD;
+		bits++;
+		if (!(cflag & PARODD))
+			cval |= NETARM_SER_CTLA_P_EVEN;
+	}
+	/* Determine divisor based on baud rate */
+	baud = nas_tty_get_baud_rate(info->tty);
+	if (!baud)
+		baud = 9600;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("change_speed: cflag %d, baud rate %d\n", cflag, baud);
+#endif
+
+	baud_base = info->state->baud_base;
+	quot = baud_base / baud;
+	/* As a last resort, if the quotient is zero, default to 9600 bps */
+	if (!quot) quot = baud_base / 9600;
+	
+	info->quot = quot;
+	info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base);
+	info->timeout += HZ/50;		/* Add .02 seconds of slop */
+
+	/* CTS flow control flag and modem status interrupts */
+	if (cflag & CRTSCTS)
+		cval |= NETARM_SER_CTLA_CTSTX | NETARM_SER_CTLA_RTSRX;
+
+	/*
+	 * Set up parity check flag
+	 */
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+	save_flags(flags); cli();
+	regs = info->registers;
+	regs->rx_match = 0;
+	regs->rx_buf_timer = 0;
+	regs->bitrate = NETARM_SER_BR_X16(baud);
+	regs->rx_char_timer = NETARM_SER_RXGAP(baud);
+	regs->ctrl_b = NETARM_SER_CTLB_RCGT_EN | NETARM_SER_CTLB_UART_MODE;
+#ifdef POLLED_SERIAL
+	regs->ctrl_a = NETARM_SER_CTLA_ENABLE | cval;
+#else
+	/* enable interrupts */
+	regs->ctrl_a = NETARM_SER_CTLA_ENABLE | NETARM_SER_CTLA_IE_RX_RDY | 
+	               NETARM_SER_CTLA_IE_RX_FULL | cval;
+#endif
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("change_speed: bitrate %x, rxgap %x\n",
+		regs->bitrate, regs->rx_char_timer );
+#endif
+	restore_flags(flags);
+}
+
+/* Output a single character to the device */
+static void
+rs_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	struct netarm_async_struct *info = (struct netarm_async_struct *)tty->driver_data;
+ 	volatile netarm_serial_channel_t *regs;
+	unsigned char *fifo;
+#ifdef	NAS_DEBUG_VERBOSE
+  printk(" rs_put_char called\n");
+#endif
+	regs = info->registers;
+	fifo = (unsigned char *)&(regs->fifo);
+
+	/* write the character (polled) */
+	NAS_TX_WAIT_RDY(regs);
+        *fifo = ch;
+}
+
+/* not needed in polled output: */
+static void
+rs_flush_chars(struct tty_struct *tty)
+{
+	struct netarm_async_struct *info = (struct netarm_async_struct *)tty->driver_data;
+				
+	serial_paranoia_check(info, tty->device, "rs_flush_chars");
+	return;
+}
+
+/* Write a number of characters (polled) */
+static int
+rs_write(struct tty_struct * tty, int from_user,
+         const unsigned char *buf, int count)
+{
+	struct netarm_async_struct *info = (struct netarm_async_struct *)tty->driver_data;
+	volatile netarm_serial_channel_t *regs;
+	unsigned int *buf32;
+	unsigned int *fifo;
+	unsigned char *bytefifo;
+	int acount;
+	int scount = 0;
+
+#ifdef	NAS_DEBUG_VERBOSE
+	printk(" rs_write: called with %d chars\n", count);
+#endif
+				
+	if (serial_paranoia_check(info, tty->device, "rs_write"))
+		return 0;
+	if (!tty || !info->xmit.buf || !tmp_buf)
+		return 0;
+
+	regs = info->registers;
+	fifo = (unsigned int *)&(regs->fifo);
+	bytefifo = (unsigned char *)&(regs->fifo);
+
+	/* count to align */
+	acount = (4 - (((unsigned int)buf) & 0x3)) & 0x03;
+	if ( acount > count ) acount = count;
+	count -= acount;
+
+	/* word align */
+	if ( acount > 0 )
+	{
+		while ( acount > 0 )
+		{
+			NAS_TX_WAIT_RDY(regs);
+			*bytefifo = *buf;	
+	      		buf++;
+	      		acount--;
+	      		scount++;
+		}
+  	}
+	buf32 = (unsigned int *)buf;
+	while ( count > 3 )
+  	{
+		NAS_TX_WAIT_RDY(regs);
+    		*fifo = *buf32;
+		buf32++;
+		count  -= 4;
+		scount += 4;
+	}
+	if ( count > 0 )
+  	{
+  		buf = (unsigned char *)buf32;
+  		while ( count > 0 )
+		{
+			NAS_TX_WAIT_RDY(regs);
+			*bytefifo = *buf;
+			buf++;
+			count--;
+			scount++;
+		}
+  	}
+	return scount;
+}
+
+static int
+rs_write_room(struct tty_struct *tty)
+{
+	struct netarm_async_struct *info = (struct netarm_async_struct *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
+		return 0;
+	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static int 
+rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct netarm_async_struct *info = (struct netarm_async_struct *)tty->driver_data;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+		return 0;
+	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+/* not needed in polled output: */
+static void 
+rs_flush_buffer(struct tty_struct *tty)
+{
+	struct netarm_async_struct *info = (struct netarm_async_struct *)tty->driver_data;
+	
+	serial_paranoia_check(info, tty->device, "rs_flush_buffer");
+	return;
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void
+rs_send_xchar(struct tty_struct *tty, char ch)
+{
+	rs_put_char( tty, ch );
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void
+rs_throttle(struct tty_struct * tty)
+{
+	struct netarm_async_struct *info = (struct netarm_async_struct *)tty->driver_data;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("throttle %s: %d....\n", tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+		return;
+	
+	if (I_IXOFF(tty))
+		rs_send_xchar(tty, STOP_CHAR(tty));
+
+	if (tty->termios->c_cflag & CRTSCTS)
+		info->registers->ctrl_a &= ~NETARM_SER_CTLA_RTS_EN;
+}
+
+static void
+rs_unthrottle(struct tty_struct * tty)
+{
+	struct netarm_async_struct *info = (struct netarm_async_struct *)tty->driver_data;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("unthrottle %s: %d....\n", tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+		return;
+	
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			rs_send_xchar(tty, START_CHAR(tty));
+	}
+	if (tty->termios->c_cflag & CRTSCTS)
+		info->registers->ctrl_a |= NETARM_SER_CTLA_RTS_EN;
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int
+get_serial_info(struct netarm_async_struct * info, struct serial_struct * retinfo)
+{
+	struct serial_struct tmp;
+	struct serial_state *state = info->state;
+   
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = state->type;
+	tmp.line = state->line;
+	tmp.port = state->port;
+	if (HIGH_BITS_OFFSET)
+		tmp.port_high = state->port >> HIGH_BITS_OFFSET;
+	else
+		tmp.port_high = 0;
+	tmp.irq = state->irq;
+	tmp.flags = state->flags;
+	tmp.xmit_fifo_size = state->xmit_fifo_size;
+	tmp.baud_base = state->baud_base;
+	tmp.close_delay = state->close_delay;
+	tmp.closing_wait = state->closing_wait;
+	tmp.custom_divisor = state->custom_divisor;
+	tmp.hub6 = state->hub6;
+	tmp.io_type = state->io_type;
+	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
+		return -EFAULT;
+	return 0;
+}
+
+static int
+set_serial_info(struct netarm_async_struct * info, struct serial_struct * new_info)
+{
+	struct serial_struct new_serial;
+ 	struct serial_state old_state, *state;
+	unsigned int		i,change_irq,change_port;
+	int 			retval = 0;
+	unsigned long		new_port;
+
+	if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
+		return -EFAULT;
+	state = info->state;
+	old_state = *state;
+
+	new_port = new_serial.port;
+	if (HIGH_BITS_OFFSET)
+		new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
+
+	change_irq = new_serial.irq != state->irq;
+	change_port = (new_port != ((int) state->port)) ||
+		(new_serial.hub6 != state->hub6);
+  
+	if (!capable(CAP_SYS_ADMIN)) {
+		if (change_irq || change_port ||
+		    (new_serial.baud_base != state->baud_base) ||
+		    (new_serial.type != state->type) ||
+		    (new_serial.close_delay != state->close_delay) ||
+		    (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
+		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
+		     (state->flags & ~ASYNC_USR_MASK)))
+			return -EPERM;
+		state->flags = ((state->flags & ~ASYNC_USR_MASK) |
+			       (new_serial.flags & ASYNC_USR_MASK));
+		info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+			       (new_serial.flags & ASYNC_USR_MASK));
+		state->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	new_serial.irq = irq_cannonicalize(new_serial.irq);
+
+	if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || 
+	    (new_serial.baud_base < 9600)|| (new_serial.type != PORT_NETARM))
+	{
+		return -EINVAL;
+	}
+
+	if (new_serial.type == PORT_NETARM)
+		new_serial.xmit_fifo_size = NETARM_SER_FIFO_SIZE;
+
+	/* Make sure address is not already in use */
+	if (new_serial.type) {
+		for (i = 0 ; i < NR_NAS_PORTS; i++)
+			if ((state != &rs_table[i]) &&
+			    (rs_table[i].port == new_port) &&
+			    rs_table[i].type)
+				return -EADDRINUSE;
+	}
+
+	if ((change_port || change_irq) && (state->count > 1))
+		return -EBUSY;
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+	state->baud_base = new_serial.baud_base;
+	state->flags = ((state->flags & ~ASYNC_FLAGS) |
+			(new_serial.flags & ASYNC_FLAGS));
+	info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
+		       (info->flags & ASYNC_INTERNAL_FLAGS));
+	state->custom_divisor = new_serial.custom_divisor;
+	state->close_delay = new_serial.close_delay * HZ/100;
+	state->closing_wait = new_serial.closing_wait * HZ/100;
+#if (LINUX_VERSION_CODE > 0x20100)
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+#endif
+	info->xmit_fifo_size = state->xmit_fifo_size =
+		new_serial.xmit_fifo_size;
+
+	if ((state->type != PORT_UNKNOWN) && state->port) {
+		release_region(state->port,8);
+	}
+	state->type = new_serial.type;
+	if (change_port || change_irq) {
+		/*
+		 * We need to shutdown the serial port at the old
+		 * port/irq combination.
+		 */
+		shutdown(info);
+		state->irq = new_serial.irq;
+		info->port = state->port = new_port;
+	}
+	if ((state->type != PORT_UNKNOWN) && state->port) {
+		request_region(state->port,8,"serial(set)");
+	}
+	
+check_and_exit:
+	if (!state->port || !state->type)
+		return 0;
+	if (info->flags & ASYNC_INITIALIZED) {
+		if (((old_state.flags & ASYNC_SPD_MASK) !=
+		     (state->flags & ASYNC_SPD_MASK)) ||
+		    (old_state.custom_divisor != state->custom_divisor)) {
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+				info->tty->alt_speed = 57600;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+				info->tty->alt_speed = 115200;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+				info->tty->alt_speed = 230400;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+				info->tty->alt_speed = 460800;
+			change_speed(info, 0);
+		}
+	} else
+		retval = startup(info);
+	return retval;
+}
+
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space. 
+ */
+static int
+get_lsr_info(struct netarm_async_struct * info, unsigned int *value)
+{
+	unsigned char status;
+	unsigned int result;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	status = info->registers->status_a;
+	restore_flags(flags);
+	result = ((status & NETARM_SER_STATA_TX_FULL) ? TIOCSER_TEMT : 0);
+
+	/*
+	 * If we're about to load something into the transmit
+	 * register, we'll pretend the transmitter isn't empty to
+	 * avoid a race condition (depending on when the transmit
+	 * interrupt happens).
+	 */
+	if (info->x_char || 
+	    ((CIRC_CNT(info->xmit.head, info->xmit.tail,
+		       SERIAL_XMIT_SIZE) > 0) &&
+	     !info->tty->stopped && !info->tty->hw_stopped))
+		result &= TIOCSER_TEMT;
+
+	if (copy_to_user(value, &result, sizeof(int)))
+		return -EFAULT;
+	return 0;
+}
+
+
+static int
+do_autoconfig(struct netarm_async_struct * info)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	
+	if (info->state->count > 1)
+		return -EBUSY;
+	
+	shutdown(info);
+	autoconfig(info->state);
+
+	return startup(info);
+}
+
+/*
+ * rs_break() --- routine which turns the break handling on or off
+ */
+static void
+rs_break(struct tty_struct *tty, int break_state)
+{
+	struct netarm_async_struct * info = (struct netarm_async_struct *)tty->driver_data;
+	unsigned long flags, control;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_break"))
+		return;
+	if (!CONFIGURED_NAS_PORT(info))
+		return;
+
+	save_flags(flags); cli();
+	control = info->registers->ctrl_a;
+	if (break_state == -1)
+		control |= NETARM_SER_CTLA_BRK;
+	else
+		control &= ~NETARM_SER_CTLA_BRK;
+	info->registers->ctrl_a = control;
+	restore_flags(flags);
+}
+
+static int
+rs_ioctl(struct tty_struct *tty, struct file * file,
+         unsigned int cmd, unsigned long arg)
+{
+	struct netarm_async_struct * info = (struct netarm_async_struct *)tty->driver_data;
+	struct async_icount cprev, cnow;	/* kernel counter temps */
+	struct serial_icounter_struct icount;
+	unsigned long flags, control;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+	
+	switch (cmd) {
+/*		case TIOCMGET:
+			return get_modem_info(info, (unsigned int *) arg);
+		case TIOCMBIS:
+		case TIOCMBIC:
+		case TIOCMSET:
+			return set_modem_info(info, cmd, (unsigned int *) arg);
+*/
+		case TIOCGSERIAL:
+			return get_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSSERIAL:
+			return set_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSERCONFIG:
+			return do_autoconfig(info);
+
+		case TIOCSERGETLSR: /* Get line status register */
+			return get_lsr_info(info, (unsigned int *) arg);
+
+		case TIOCSERGSTRUCT:
+			if (copy_to_user((struct netarm_async_struct *) arg,
+					 info, sizeof(struct netarm_async_struct)))
+				return -EFAULT;
+			return 0;
+							
+		/*
+		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+		 * - mask passed in arg for lines of interest
+ 		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+		 * Caller should use TIOCGICOUNT to see which one it was
+		 */
+		case TIOCMIWAIT:
+			save_flags(flags); cli();
+			/* note the counters on entry */
+			cprev = info->state->icount;
+			restore_flags(flags);
+			/* Force modem status interrupts on */
+			control = info->registers->ctrl_a;
+			control |= NETARM_SER_CTLA_IE_RX_DCD |
+			           NETARM_SER_CTLA_IE_RX_RI |
+				   NETARM_SER_CTLA_IE_RX_DSR |
+				   NETARM_SER_CTLA_IE_TX_CTS;
+			info->registers->ctrl_a = control;
+			while (1)
+			{
+				interruptible_sleep_on(&info->delta_msr_wait);
+				/* see if a signal did it */
+				if (signal_pending(current))
+					return -ERESTARTSYS;
+				save_flags(flags); cli();
+				cnow = info->state->icount; /* atomic copy */
+				restore_flags(flags);
+				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
+				    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+					return -EIO; /* no change => error */
+				if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+				     ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+				     ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
+				     ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
+					return 0;
+				}
+				cprev = cnow;
+			}
+			/* NOTREACHED */
+
+		/* 
+		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+		 * Return: write counters to the user passed counter struct
+		 * NB: both 1->0 and 0->1 transitions are counted except for
+		 *     RI where only 0->1 is counted.
+		 */
+		case TIOCGICOUNT:
+			save_flags(flags); cli();
+			cnow = info->state->icount;
+			restore_flags(flags);
+			icount.cts = cnow.cts;
+			icount.dsr = cnow.dsr;
+			icount.rng = cnow.rng;
+			icount.dcd = cnow.dcd;
+			icount.rx = cnow.rx;
+			icount.tx = cnow.tx;
+			icount.frame = cnow.frame;
+			icount.overrun = cnow.overrun;
+			icount.parity = cnow.parity;
+			icount.brk = cnow.brk;
+			icount.buf_overrun = cnow.buf_overrun;
+			
+			if (copy_to_user((void *)arg, &icount, sizeof(icount)))
+				return -EFAULT;
+			return 0;
+		case TIOCSERGWILD:
+		case TIOCSERSWILD:
+			/* "setserial -W" is called in Debian boot */
+			printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
+			return 0;
+
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+static void
+rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	struct netarm_async_struct *info = (struct netarm_async_struct *)tty->driver_data;
+	unsigned int cflag = tty->termios->c_cflag;
+	
+	if (   (cflag == old_termios->c_cflag)
+	    && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
+		== RELEVANT_IFLAG(old_termios->c_iflag)))
+	  return;
+
+	change_speed(info, old_termios);
+
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void
+rs_close(struct tty_struct *tty, struct file * filp)
+{
+	struct netarm_async_struct * info = (struct netarm_async_struct *)tty->driver_data;
+	struct serial_state *state;
+	unsigned long flags;
+
+	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+		return;
+
+	state = info->state;
+	
+	save_flags(flags); cli();
+	
+	if (tty_hung_up_p(filp)) {
+		DBG_CNT("before DEC-hung");
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+	
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_close ttyS%d, count = %d\n", info->line, state->count);
+#endif
+	if ((tty->count == 1) && (state->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  state->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+		       "state->count is %d\n", state->count);
+		state->count = 1;
+	}
+	if (--state->count < 0) {
+		printk("rs_close: bad serial port count for ttys%d: %d\n",
+		       info->line, state->count);
+		state->count = 0;
+	}
+	if (state->count) {
+		DBG_CNT("before DEC-2");
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= ASYNC_CLOSING;
+	restore_flags(flags);
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & ASYNC_NORMAL_ACTIVE)
+		info->state->normal_termios = *tty->termios;
+	if (info->flags & ASYNC_CALLOUT_ACTIVE)
+		info->state->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+	if (info->flags & ASYNC_INITIALIZED) {
+		info->registers->ctrl_a &= ~NETARM_SER_CTLA_IE_RX_ALL;
+		/*
+		 * Before we drop DTR, make sure the UART transmitter
+		 * has completely drained; this is especially
+		 * important if there is a transmit FIFO!
+		 */
+		rs_wait_until_sent(tty, info->timeout);
+	}
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
+			 ASYNC_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	MOD_DEC_USE_COUNT;
+}
+
+/*
+ * rs_wait_until_sent() --- wait until the transmitter is empty
+ * (only used in rs_close? --rp)
+ */
+static void
+rs_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	struct netarm_async_struct * info = (struct netarm_async_struct *)tty->driver_data;
+	unsigned long orig_jiffies, char_time;
+	int lsr;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent"))
+		return;
+
+	if (info->state->type == PORT_UNKNOWN)
+		return;
+
+	if (info->xmit_fifo_size == 0)
+		return; /* Just in case.... */
+
+	orig_jiffies = jiffies;
+	/*
+	 * Set the check interval to be 1/5 of the estimated time to
+	 * send a single character, and make it at least 1.  The check
+	 * interval should also be less than the timeout.
+	 * 
+	 * Note: we have to use pretty tight timings here to satisfy
+	 * the NIST-PCTS.
+	 */
+	char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
+	char_time = char_time / 5;
+	if (char_time == 0)
+		char_time = 1;
+	if (timeout && timeout < char_time)
+		char_time = timeout;
+	/*
+	 * If the transmitter hasn't cleared in twice the approximate
+	 * amount of time to send the entire FIFO, it probably won't
+	 * ever clear.  This assumes the UART isn't doing flow
+	 * control, which is currently the case.  Hence, if it ever
+	 * takes longer than info->timeout, this is probably due to a
+	 * UART bug of some kind.  So, we clamp the timeout parameter at
+	 * 2*info->timeout.
+	 */
+	if (!timeout || timeout > 2*info->timeout)
+		timeout = 2*info->timeout;
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
+	printk("jiff=%lu...", jiffies);
+#endif
+	while (!((lsr = info->registers->status_a) & NETARM_SER_STATA_TX_FULL))
+	{
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+		printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
+#endif
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(char_time);
+		if (signal_pending(current))
+			break;
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			break;
+	}
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
+#endif
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void
+rs_hangup(struct tty_struct *tty)
+{
+	struct netarm_async_struct * info = (struct netarm_async_struct *)tty->driver_data;
+	struct serial_state *state = info->state;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
+		return;
+
+	state = info->state;
+	
+	rs_flush_buffer(tty);
+	if (info->flags & ASYNC_CLOSING)
+		return;
+	shutdown(info);
+	info->event = 0;
+	state->count = 0;
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int
+block_til_ready(struct tty_struct *tty, struct file * filp,
+		struct netarm_async_struct *info)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	struct serial_state *state = info->state;
+	int		retval;
+	int		do_clocal = 0, extra_count = 0;
+	unsigned long	flags;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+		return -EAGAIN;
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & ASYNC_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+		    return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+		    return -EBUSY;
+		info->flags |= ASYNC_CALLOUT_ACTIVE;
+		return 0;
+	}
+	
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & ASYNC_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= ASYNC_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
+		if (state->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+	
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, state->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready before block: ttys%d, count = %d\n",
+	       state->line, state->count);
+#endif
+	save_flags(flags); cli();
+	if (!tty_hung_up_p(filp)) {
+		extra_count = 1;
+		state->count--;
+	}
+	restore_flags(flags);
+	info->blocked_open++;
+	while (1)
+	{
+		save_flags(flags); cli();
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (tty->termios->c_cflag & CBAUD))
+			info->registers->ctrl_a |= NETARM_SER_CTLA_DTR_EN |
+			                           NETARM_SER_CTLA_RTS_EN;
+		restore_flags(flags);
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (tty_hung_up_p(filp) ||
+		    !(info->flags & ASYNC_INITIALIZED)) {
+			retval = -EAGAIN;
+			break;
+		}
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    !(info->flags & ASYNC_CLOSING) &&
+		    (do_clocal || (info->registers->status_a &
+				   NETARM_SER_STATA_DCD)))
+			break;
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef SERIAL_DEBUG_OPEN
+		printk("block_til_ready blocking: ttys%d, count = %d\n",
+		       info->line, state->count);
+#endif
+		schedule();
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&info->open_wait, &wait);
+	if (extra_count)
+		state->count++;
+	info->blocked_open--;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready after blocking: ttys%d, count = %d\n",
+	       info->line, state->count);
+#endif
+	if (retval)
+		return retval;
+	info->flags |= ASYNC_NORMAL_ACTIVE;
+	return 0;
+}
+
+static int
+get_async_struct(int line, struct netarm_async_struct **ret_info)
+{
+	struct netarm_async_struct *info;
+	struct serial_state *sstate;
+
+	/* only two lines are available */
+	if ((line == 0) || (line == 1))
+	{
+	    sstate = rs_table + line;
+	    sstate->count++;
+	    if (sstate->info) {
+	    		/* this shouldn't happen here */
+		    *ret_info = (struct netarm_async_struct *) sstate->info;
+		    return 0;
+	    }
+	    info = &NAS_ports[line];
+	    memset(info, 0, sizeof(struct netarm_async_struct));
+	    init_waitqueue_head(&info->open_wait);
+	    init_waitqueue_head(&info->close_wait);
+	    init_waitqueue_head(&info->delta_msr_wait);
+	    info->magic = NAS_MAGIC;
+	    info->port = sstate->port;
+	    info->flags = sstate->flags;
+	    info->io_type = sstate->io_type;
+	    info->registers = get_serial_channel( line );
+	    info->xmit_fifo_size = sstate->xmit_fifo_size;
+	    info->line = line;
+	    info->tqueue.routine = do_softint;
+	    info->tqueue.data = info;
+	    info->state = sstate;
+	    sstate->info = (struct async_struct *) info;
+	    *ret_info = info;
+	    return 0;
+	}
+	else
+	    return -ENODEV;
+}
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+static int
+rs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct netarm_async_struct	*info;
+	int 			retval, line;
+	unsigned long		page;
+
+	MOD_INC_USE_COUNT;
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	if ((line < 0) || (line >= NR_NAS_PORTS)) {
+		MOD_DEC_USE_COUNT;
+		return -ENODEV;
+	}
+	retval = get_async_struct(line, &info);
+	if (retval) {
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+	tty->driver_data = info;
+	info->tty = tty;
+	if (serial_paranoia_check(info, tty->device, "rs_open")) {
+		MOD_DEC_USE_COUNT;		
+		return -ENODEV;
+	}
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+	       info->state->count);
+#endif
+#if (LINUX_VERSION_CODE > 0x20100)
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+#endif
+
+	if (!tmp_buf) {
+		page = get_zeroed_page(GFP_KERNEL);
+		if (tmp_buf)
+			free_page(page);
+		else {
+			if (!page) {
+				MOD_DEC_USE_COUNT;
+				return -ENOMEM;
+			}
+			tmp_buf = (unsigned char *) page;
+		}
+	}
+
+	/*
+	 * If the port is the middle of closing, bail out now
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+		MOD_DEC_USE_COUNT;
+		return -EAGAIN;
+	}
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval) {
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("rs_open returning after block_til_ready with %d\n",
+		       retval);
+#endif
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+
+	if ((info->state->count == 1) &&
+	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->state->normal_termios;
+		else 
+			*tty->termios = info->state->callout_termios;
+		change_speed(info, 0);
+	}
+#ifdef CONFIG_SERIAL_NETARM_CONSOLE
+	if (sercons.cflag && sercons.index == line) {
+		tty->termios->c_cflag = sercons.cflag;
+		sercons.cflag = 0;
+		change_speed(info, 0);
+	}
+#endif
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open ttyS%d successful\n", info->line);
+#endif
+	return 0;
+}
+
+/*====================================================================
+  Support for /proc/netarm-serial
+ */
+#ifdef CONFIG_PROC_FS
+
+static struct proc_dir_entry *proc_nas;
+
+static inline int
+line_info(char *buf, struct serial_state *state)
+{
+	char	stat_buf[30];
+	int	ret;
+	unsigned long flags, status, control;
+	netarm_serial_channel_t *regs;
+
+	ret = sprintf(buf, "%d: NetARM SER port:%lX irq:%d",
+		      state->line, state->port, state->irq);
+
+	if (!state->port || (state->type == PORT_UNKNOWN)) {
+		ret += sprintf(buf+ret, "\n");
+		return ret;
+	}
+
+	/*
+	 * Figure out the current RS-232 lines
+	 */
+
+	regs = (netarm_serial_channel_t *) state->iomem_base;
+	save_flags(flags); cli();
+	status = regs->status_a;
+	control = regs->ctrl_a;
+	restore_flags(flags); 
+
+	stat_buf[0] = 0;
+	stat_buf[1] = 0;
+	if (control & NETARM_SER_CTLA_RTS_EN)
+		strcat(stat_buf, "|RTS");
+	if (status & NETARM_SER_STATA_CTS)
+		strcat(stat_buf, "|CTS");
+	if (control & NETARM_SER_CTLA_DTR_EN)
+		strcat(stat_buf, "|DTR");
+	if (status & NETARM_SER_STATA_DSR)
+		strcat(stat_buf, "|DSR");
+	if (status & NETARM_SER_STATA_DCD)
+		strcat(stat_buf, "|CD");
+	if (status & NETARM_SER_STATA_RI)
+		strcat(stat_buf, "|RI");
+
+	ret += sprintf(buf+ret, " tx:%d rx:%d",
+		      state->icount.tx, state->icount.rx);
+
+	if (state->icount.frame)
+		ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
+	
+	if (state->icount.parity)
+		ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
+	
+	if (state->icount.brk)
+		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);	
+
+	if (state->icount.overrun)
+		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
+
+	/*
+	 * Last thing is the RS-232 status lines
+	 */
+	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+	return ret;
+}
+
+int
+nas_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	int i, len = 0, l;
+	off_t	begin = 0;
+
+	len += sprintf(page, "serinfo:1.0 driver:%s%s revision:%s\n",
+		       serial_version, LOCAL_VERSTRING, serial_revdate);
+	for (i = 0; i < NR_NAS_PORTS && len < 4000; i++) {
+		l = line_info(page + len, &rs_table[i]);
+		len += l;
+		if (len+begin > off+count)
+			goto done;
+		if (len+begin < off) {
+			begin += len;
+			len = 0;
+		}
+	}
+	*eof = 1;
+done:
+	if (off >= len+begin)
+		return 0;
+	*start = page + (off-begin);
+	return ((count < begin+len-off) ? count : begin+len-off);
+}
+#endif
+/* end of proc support routines */
+
+/*
+ * ---------------------------------------------------------------------
+ * rs_init() and friends
+ *
+ * rs_init() is called at boot-time to initialize the serial driver.
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * This routine prints out the appropriate serial driver version
+ * number, and identifies which options were configured into this
+ * driver.
+ */
+static char serial_options[] __initdata =
+#ifdef CONFIG_SERIAL_NETARM_CONSOLE
+       " CONSOLE"
+#define SERIAL_OPT
+#endif
+#ifdef SERIAL_OPT
+       " enabled\n";
+#else
+       " no serial options enabled\n";
+#endif
+#undef SERIAL_OPT
+
+static _INLINE_ void
+show_serial_version(void)
+{
+ 	printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name,
+	       serial_version, LOCAL_VERSTRING, serial_revdate,
+	       serial_options);
+}
+
+/*
+ * This routine is called by rs_init() to initialize a specific serial
+ * port.  It determines what type of UART chip this serial port is
+ * using: 8250, 16450, 16550, 16550A.
+ * In the NetARM case, we already know what's there.
+ */
+static void
+autoconfig(struct serial_state * state)
+{
+	struct netarm_async_struct *info, scr_info;
+	unsigned long flags;
+
+	if (!CONFIGURED_SERIAL_PORT(state))
+		return;
+		
+	state->type = PORT_NETARM;
+
+	info = &scr_info;	/* This is just for serial_{in,out} */
+
+	info->magic = SERIAL_MAGIC;
+	info->state = state;
+	info->port = state->port;
+	info->flags = state->flags;
+	info->io_type = state->io_type;
+	info->registers = (netarm_serial_channel_t *) state->iomem_base;
+
+	save_flags(flags); cli();
+	/* Reset FIFO */
+	info->registers->status_a = NETARM_SER_STATA_CLR_ALL;
+	info->SCSRA = 0;
+	restore_flags(flags);
+}
+
+int register_serial(struct serial_struct *req);
+void unregister_serial(int line);
+
+#ifdef MODULE
+#if (LINUX_VERSION_CODE > 0x20100)
+EXPORT_SYMBOL(register_serial);
+EXPORT_SYMBOL(unregister_serial);
+#else
+static struct symbol_table serial_syms = {
+#include <linux/symtab_begin.h>
+	X(register_serial),
+	X(unregister_serial),
+#include <linux/symtab_end.h>
+};
+#endif
+#endif
+
+/*
+ * The serial driver boot-time initialization code
+ */
+static int __init
+rs_init(void)
+{
+	int i;
+	struct serial_state * state;
+
+	init_bh(SERIAL_BH, do_serial_bh);
+	show_serial_version();
+
+	/* Initialize the tty_driver structure */
+	
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+#if (LINUX_VERSION_CODE > 0x20100)
+	serial_driver.driver_name = "NetARM serial";
+#endif
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	serial_driver.name = "tts/%d";
+#else
+	serial_driver.name = "ttyS";
+#endif
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64 + SERIAL_DEV_OFFSET;
+	serial_driver.num = NR_NAS_PORTS;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+	serial_driver.init_termios.c_cflag =
+		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = rs_open;
+	serial_driver.close = rs_close;
+	serial_driver.write = rs_write;
+	serial_driver.put_char = rs_put_char;
+	serial_driver.flush_chars = rs_flush_chars;
+	serial_driver.write_room = rs_write_room;
+	serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	serial_driver.flush_buffer = rs_flush_buffer;
+	serial_driver.ioctl = rs_ioctl;
+	serial_driver.throttle = rs_throttle;
+	serial_driver.unthrottle = rs_unthrottle;
+	serial_driver.set_termios = rs_set_termios;
+	serial_driver.stop = rs_stop;
+	serial_driver.start = rs_start;
+	serial_driver.hangup = rs_hangup;
+	serial_driver.break_ctl = rs_break;
+	serial_driver.send_xchar = rs_send_xchar;
+	serial_driver.wait_until_sent = rs_wait_until_sent;
+	serial_driver.read_proc = nas_read_proc;
+	
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	callout_driver.name = "cua/%d";
+#else
+	callout_driver.name = "cua";
+#endif
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+	callout_driver.read_proc = 0;
+	callout_driver.proc_entry = 0;
+
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register serial driver\n");
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+	
+	for (i = 0, state = rs_table; i < NR_NAS_PORTS; i++,state++)
+	{
+		state->magic = SSTATE_MAGIC;
+		state->line = i;
+		state->type = PORT_NETARM;
+		state->xmit_fifo_size = NETARM_SER_FIFO_SIZE;
+		state->custom_divisor = 0;
+		state->close_delay = 5*HZ/10;
+		state->closing_wait = 30*HZ;
+		state->callout_termios = callout_driver.init_termios;
+		state->normal_termios = serial_driver.init_termios;
+		state->icount.cts = state->icount.dsr = 
+			state->icount.rng = state->icount.dcd = 0;
+		state->icount.rx = state->icount.tx = 0;
+		state->icount.frame = state->icount.parity = 0;
+		state->icount.overrun = state->icount.brk = 0;
+		if (i == 0)
+			state->irq = IRQ_SER1_RX;
+		else
+			state->irq = IRQ_SER2_RX;
+		state->io_type = SERIAL_IO_MEM;
+/* no need to call request_region
+		if (state->port && check_region(state->port,8))
+			continue;
+*/
+		if (state->flags & ASYNC_BOOT_AUTOCONF)
+			autoconfig(state);
+		printk(KERN_INFO "ttyS%02d at 0x%04lx (irq = %d) is a NetARM\n",
+		       state->line + SERIAL_DEV_OFFSET,
+		       state->port, state->irq );
+		tty_register_devfs(&serial_driver, 0,
+				   serial_driver.minor_start + state->line);
+		tty_register_devfs(&callout_driver, 0,
+				   callout_driver.minor_start + state->line);
+	}
+	nas_interrupts_init();
+
+#ifdef CONFIG_PROC_FS
+	if ((proc_nas = create_proc_entry( "netarm-serial", 0, 0 )))
+	  proc_nas->read_proc = nas_read_proc;
+#endif
+
+	return 0;
+}
+
+static void __exit
+rs_fini(void) 
+{
+	unsigned long flags;
+	int e1, e2;
+	int i;
+
+	/* printk("Unloading %s: version %s\n", serial_name, serial_version); */
+	del_timer_sync(&serial_timer);
+	save_flags(flags); cli();
+        remove_bh(SERIAL_BH);
+	if ((e1 = tty_unregister_driver(&serial_driver)))
+		printk("serial: failed to unregister serial driver (%d)\n",
+		       e1);
+	if ((e2 = tty_unregister_driver(&callout_driver)))
+		printk("serial: failed to unregister callout driver (%d)\n", 
+		       e2);
+	restore_flags(flags);
+/*
+	for (i = 0; i < NR_NAS_PORTS; i++) {
+		if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) {
+			release_region(rs_table[i].port, 8);
+		}
+	}
+*/
+	if (tmp_buf) {
+		unsigned long pg = (unsigned long) tmp_buf;
+		tmp_buf = NULL;
+		free_page(pg);
+	}
+}
+
+module_init(rs_init);
+module_exit(rs_fini);
+MODULE_DESCRIPTION("NetARM serial driver");
+MODULE_AUTHOR("Rolf Peukert <peukert@imms.de>");
+
+
+/*
+ * ------------------------------------------------------------
+ * Serial console driver
+ * ------------------------------------------------------------
+ */
+#ifdef CONFIG_SERIAL_NETARM_CONSOLE
+
+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
+static struct netarm_async_struct async_sercons;
+
+/*
+ *	Wait for transmitter & holding register to empty
+ */
+static inline void
+wait_for_xmitr(struct netarm_async_struct *info)
+{
+	unsigned int status, tmout = 1000000;
+
+	do
+	{
+		status = info->registers->status_a;
+
+		if (status & NETARM_SER_STATA_RX_BRK)
+			lsr_break_flag = NETARM_SER_STATA_RX_BRK;
+		if (--tmout == 0)
+			break;
+	} while ((status & NETARM_SER_STATA_TX_DMAEN) == 0);
+	/* This waits until transmitter has finished all characters in fifo.
+	   FIXME: Waiting for the transmit holding register to empty
+	   (checking NETARM_SER_STATA_TX_FULL) doesn't seem to work. */
+
+	/* Wait for flow control if necessary */
+	if (info->flags & ASYNC_CONS_FLOW)
+	{
+		tmout = 1000000;
+		while (--tmout && \
+		       (info->registers->status_a & NETARM_SER_STATA_CTS) == 0)
+		{}
+	}
+}
+
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ *
+ *	The console_lock must be held when we get here.
+ */
+static void
+serial_console_write(struct console *co, const char *s, unsigned count)
+{
+	static struct netarm_async_struct *info = &async_sercons;
+	volatile netarm_serial_channel_t *regs;
+	unsigned long ier;
+	volatile unsigned long *ser_port_fifo;
+	unsigned long *bPtr = (unsigned long *)s;
+	unsigned char *zPtr = (unsigned char *)s;
+	unsigned long ctmp;
+	int scount;
+
+	/*
+	 *	First save the IER then disable the interrupts
+	 */
+	regs = info->registers;
+	ier  = regs->ctrl_a;
+	regs->ctrl_a = ier & ~(NETARM_SER_CTLA_IE_RX_ALL | NETARM_SER_CTLA_IE_TX_ALL);
+
+	/*
+	 *	Now, do all characters, add CR to every LF
+	 */
+	ser_port_fifo = (volatile unsigned long *) &(regs->fifo);
+	zPtr = (unsigned char *)bPtr;
+	while ( count > 0 )
+	{
+		ctmp = 0 ;
+		scount = 0 ;
+  		while ( ( count > 0 ) && ( scount < 4 ) )
+		{
+			ctmp += *zPtr << ( scount << 3 ) ;
+			if (*zPtr == '\n')
+			{
+				if ( scount < 3 )
+				{
+					scount++;
+					ctmp += '\r' << (scount << 3) ; 
+				}
+				else
+				{
+					NAS_TX_WAIT_RDY(regs);
+					*ser_port_fifo = ctmp;
+					scount = 0 ;
+					ctmp = '\r' ;	
+				}
+			}
+			zPtr++;
+			count -- ;
+			scount ++ ;
+		}
+		NAS_TX_WAIT_RDY(regs);
+		*ser_port_fifo = ctmp;	
+	}
+	/*
+	 *	Finally, Wait for transmitter & holding register to empty
+	 * 	and restore the IER
+	 */
+	wait_for_xmitr(info);
+	regs->ctrl_a = ier;
+}
+
+static kdev_t
+serial_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+/*
+ *	Setup initial baud/bits/parity/flow control. We do two things here:
+ *	- construct a cflag setting for the first rs_open()
+ *	- initialize the serial port
+ *	Return non-zero if we didn't find a serial port.
+ */
+static int __init
+serial_console_setup(struct console *co, char *options)
+{
+	static struct netarm_async_struct *info;
+	volatile netarm_serial_channel_t *regs;
+	struct serial_state *state;
+	unsigned cval;
+	int	baud = 9600;
+	int	bits = 8;
+	int	parity = 'n';
+	int	doflow = 0;
+	int	cflag = CREAD | HUPCL | CLOCAL;
+	int	quot = 0;
+	char	*s;
+
+	if (options) {
+		baud = simple_strtoul(options, NULL, 10);
+		s = options;
+		while(*s >= '0' && *s <= '9')
+			s++;
+		if (*s) parity = *s++;
+		if (*s) bits   = *s++ - '0';
+		if (*s) doflow = (*s++ == 'r');
+	}
+
+	/*
+	 *	Now construct a cflag setting.
+	 *      'cval' will be written to the NetARM "Control A" register
+	 */
+	cval = NETARM_SER_CTLA_ENABLE;
+	switch(baud) {
+		case 1200:
+			cflag |= B1200;
+			break;
+		case 2400:
+			cflag |= B2400;
+			break;
+		case 4800:
+			cflag |= B4800;
+			break;
+		case 19200:
+			cflag |= B19200;
+			break;
+		case 38400:
+			cflag |= B38400;
+			break;
+		case 57600:
+			cflag |= B57600;
+			break;
+		case 115200:
+			cflag |= B115200;
+			break;
+		case 9600:
+		default:
+			cflag |= B9600;
+			break;
+	}
+	switch(bits) {
+		case 7:
+			cflag |= CS7;
+			cval  |= NETARM_SER_CTLA_7BITS;
+			break;
+		default:
+		case 8:
+			cflag |= CS8;
+			cval  |= NETARM_SER_CTLA_8BITS;
+			break;
+	}
+	switch(parity) {
+		case 'o': case 'O':
+			cflag |= PARODD;
+			cval  |= NETARM_SER_CTLA_P_ODD;
+			break;
+		case 'e': case 'E':
+			cflag |= PARENB;
+			cval  |= NETARM_SER_CTLA_P_EVEN;
+			break;
+	}
+	co->cflag = cflag;
+
+	/*
+	 *	Divisor, bytesize and parity
+	 */
+	state = rs_table + co->index;
+	if (doflow)
+		state->flags |= ASYNC_CONS_FLOW;
+	info = &async_sercons;
+	info->magic = SERIAL_MAGIC;
+	info->state = state;
+	info->port = state->port;
+	info->flags = state->flags;
+	info->io_type = state->io_type;
+	info->registers = (netarm_serial_channel_t *) state->iomem_base;
+	quot = state->baud_base / baud;
+	cval |= NETARM_SER_CTLA_2STOP;
+	/*
+	 *	Disable UART interrupts, set DTR and RTS high
+	 *	and set speed.
+	 */
+	regs = info->registers;
+	regs->rx_match = 0;
+	regs->rx_buf_timer = 0;
+	regs->bitrate = NETARM_SER_BR_X16(baud);
+	regs->rx_char_timer = NETARM_SER_RXGAP(baud);
+	regs->ctrl_b = NETARM_SER_CTLB_RCGT_EN | NETARM_SER_CTLB_UART_MODE;
+	regs->ctrl_a = cval | NETARM_SER_CTLA_DTR_EN | NETARM_SER_CTLA_RTS_EN;
+	regs->status_a = NETARM_SER_STATA_CLR_ALL;
+	/*
+	 *	If we read 0xff from the status, there is no UART here.
+	 */
+	if (regs->status_a == 0xffffffff)
+		return -1;
+
+	return 0;
+}
+
+static struct console sercons = {
+	name:		"ttyS",
+	write:		serial_console_write,
+	device:		serial_console_device,
+	setup:		serial_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+/*
+ *	Register console.
+ */
+void __init
+serial_netarm_console_init(void)
+{
+	register_console(&sercons);
+}
+#endif /* CONFIG_SERIAL_NETARM_CONSOLE */
+
diff -urN linux-2.4.29/drivers/char/serial_s3c2500.c linux-2.4.29-uc1/drivers/char/serial_s3c2500.c
--- linux-2.4.29/drivers/char/serial_s3c2500.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_s3c2500.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,1970 @@
+/*
+ * linux/drivers/char/serial-s3c2500.c
+ * 
+ * Serial port driver for the Samsung s3c2500A builtin UARTs
+ * Copyright (c) 2002-2003 Arcturus Networks Inc. 
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ * 
+ * Based on: drivers/char/serial-s3c4530.c
+ * Copyright (c) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * Based on: drivers/char/trioserial.c
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *               1998-2003  D. Jeff Dionne <jeff@uClinux.org>
+ * Copyright (c) 1998  The Silver Hammer Group, Ltd.
+ *
+ * Based on: drivers/char/68328serial.c
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/arch/irq.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+
+#define queue_task_irq_off queue_task
+#define copy_from_user(a,b,c) memcpy_fromfs(a,b,c)
+#define copy_to_user(a,b,c) memcpy_tofs(a,b,c)
+
+#include <asm/uaccess.h>
+
+#include "serial_s3c2500.h"
+
+
+#if defined(CONFIG_UCBOOTSTRAP)
+#include <asm/uCbootstrap.h>
+extern  char *getbenv (char *a);
+#endif
+
+#define _INLINE_ inline
+
+/* 
+    As we are using DC signal as GPIO and not using the second
+    HUAR on S3C2500-REF-RGP board, we can reduse the USART_NUMBER.
+*/
+
+#if defined(CONFIG_BOARD_S3C2500REFRGP)
+#define USART_NUMBER		2
+#else
+#define USART_NUMBER		3
+#endif
+
+#define UART_CLOCK		(ARM_CLK/32)
+
+#define RX_FIFO_SIZE		32
+#define TX_FIFO_SIZE		32
+					/* Receive FIFO trigger level	*/
+#define RX_FIFO_LEVEL		18	/* 	1 or 8 0r 18 0r 28	*/
+					/* Transfer FIFO trigger level	*/
+#define TX_FIFO_LEVEL		16	/*	8 or 16 or 24 or 30	*/
+static _INLINE_ void fifo_reset		(struct s3c2500_serial *info);
+static _INLINE_ void fifo_init		(struct s3c2500_serial *info);
+
+
+/* serial subtype definitions */
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+/* Debugging... DEBUG_INTR is bad to use when one of the zs
+ * lines is your console ;(
+ */
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+
+#define RS_ISR_PASS_LIMIT 256
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+#if defined(CONFIG_CONSOLE_CUART)
+    unsigned int console_port = 0;
+
+#elif defined(CONFIG_CONSOLE_HUART0)
+    unsigned int console_port = 1;
+    
+#elif defined(CONFIG_CONSOLE_HUART1)
+    unsigned int console_port = 2;
+    
+#else
+    unsigned int console_port = 3;
+    
+#endif
+
+
+
+static volatile struct s3c2500_usart_regs *usarts[USART_NUMBER] = {
+	  (volatile struct s3c2500_usart_regs *) CUART_BASE
+	, (volatile struct s3c2500_usart_regs *) HUART0_BASE
+	
+#if !defined(CONFIG_BOARD_S3C2500REFRGP)
+	, (volatile struct s3c2500_usart_regs *) HUART1_BASE
+#endif
+	};
+
+static struct s3c2500_serial s3c2500_info[USART_NUMBER];
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the memcpy_fromfs blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+ 
+static unsigned char tmp_buf[SERIAL_XMIT_SIZE];	/* This is cheating */
+static DECLARE_MUTEX (tmp_buf_sem);
+
+/* Console hooks... */
+/* struct s3c2500_serial *s3c2500_consinfo = 0; */
+static s3c_baud_table_t default_console_baud = { 9600, B9600 };
+
+DECLARE_TASK_QUEUE(tq_s3c2500_serial);
+
+static struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+static struct tty_struct 	*serial_table[USART_NUMBER];
+static struct termios 		*serial_termios[USART_NUMBER];
+static struct termios		*serial_termios_locked[USART_NUMBER];
+
+static void change_speed	(struct s3c2500_serial *info);
+
+static _INLINE_ void tx_stop		(struct s3c2500_serial *info);
+static _INLINE_ void tx_start		(struct s3c2500_serial *info);
+static _INLINE_ void rx_stop		(struct s3c2500_serial *info);
+static _INLINE_ void rx_start		(struct s3c2500_serial *info);
+static _INLINE_ void xmit_char		(struct s3c2500_serial *info, char ch);
+static _INLINE_ void rs_sched_event	(struct s3c2500_serial *info, int event);
+static _INLINE_ void uart_speed		(struct s3c2500_serial *info, unsigned int cflag);
+static _INLINE_ void handle_status 	(struct s3c2500_serial *info, unsigned int status);
+
+static void set_ints_mode	(struct s3c2500_serial *info, int yes);
+
+static void batten_down_hatches (void);
+extern void show_net_buffers	(void);
+extern void hard_reset_now	(void);
+static void handle_termios_tcsets(struct termios *ptermios, struct s3c2500_serial *pinfo);
+
+// static _INLINE_ void transmit_CUART_chars(struct s3c2500_serial *);
+// static _INLINE_ void transmit_HUART_chars(struct s3c2500_serial *);
+// static _INLINE_ void receive_CUART_chars (struct s3c2500_serial *, struct pt_regs *);
+// static _INLINE_ void receive_HUART_chars (struct s3c2500_serial *, struct pt_regs *);
+
+
+/******************************************************************************/
+
+static _INLINE_ void tx_start(struct s3c2500_serial *info)
+{
+    if	(info->use_ints)	info->usart->ier |= U_THEIE;
+}
+
+static _INLINE_ void tx_stop(struct s3c2500_serial *info)
+{
+    info->usart->ier &= (~U_THEIE);
+}
+
+static _INLINE_ void rx_start(struct s3c2500_serial *info)
+{
+    if	 ( info->xmit_fifo_size ) {
+	 if 	(info->use_ints)
+    		info->usart->ier |= (U_RFREAIE|U_E_RxTOIE | U_BSDIE|U_FERIE|U_PERIE|U_OERIE|U_CCDIE);
+	 }
+    else 
+	if 	(info->use_ints)
+		info->usart->ier |= (U_RDVIE | U_BSDIE|U_FERIE|U_PERIE|U_OERIE|U_CCDIE);
+}
+
+static _INLINE_ void rx_stop(struct s3c2500_serial *info)
+{
+    if	 ( info->xmit_fifo_size )
+	 info->usart->ier &= (~(U_RFREAIE|U_E_RxTOIE | U_BSDIE|U_FERIE|U_PERIE|U_OERIE|U_CCDIE));
+	 
+    else info->usart->ier &= (~ (U_RDVIE | U_BSDIE|U_FERIE|U_PERIE|U_OERIE|U_CCDIE));
+}
+
+static _INLINE_ void set_ints_mode(struct s3c2500_serial *info, int yes)
+{
+    info->use_ints = yes;
+    if	 ( yes ) {
+	 s3c2500_unmask_irq(  info->irq  );
+	 s3c2500_unmask_irq( (info->irq) - 1 );
+	 }
+    else {	
+	 s3c2500_mask_irq(  info->irq );
+	 s3c2500_mask_irq( (info->irq) - 1 );
+	 }
+}
+
+static _INLINE_ void hw_flow_control (struct s3c2500_serial *info, int cmd)
+{
+    if	 (cmd) {
+	 info->usart->cr |=  U_HFEN;
+	 info->cts_state = 0;
+	 }
+    else {
+	 info->usart->cr &= ~U_HFEN;
+	 info->cts_state = 1;
+	 }
+}
+
+static _INLINE_ void fifo_reset(struct s3c2500_serial *info)
+{
+    if	 ( info->xmit_fifo_size )
+	 info->usart->cr |= ( U_TFRST | U_RFRST );
+}
+
+static _INLINE_ void fifo_init(struct s3c2500_serial *info)
+{
+    if	 ( info->xmit_fifo_size ) {
+	 info->usart->cr |= ( U_TFEN | U_RFEN );
+	 switch ( RX_FIFO_LEVEL ) {
+	    case	 1 :	info->usart->cr |= U_RFTL1;	break;
+	    case	 8 :	info->usart->cr |= U_RFTL8;	break;
+	    case	18 :	info->usart->cr |= U_RFTL18;	break;
+	    case	28 :	info->usart->cr |= U_RFTL28;	break;
+	    }
+	 switch ( TX_FIFO_LEVEL ) {
+	    case	 8 :	info->usart->cr |= U_TFTL8;	break;
+	    case	16 :	info->usart->cr |= U_TFTL16;	break;
+	    case	24 :	info->usart->cr |= U_TFTL24;	break;
+	    case	30 :	info->usart->cr |= U_TFTL30;	break;
+	    }
+	 }
+}
+
+
+/* Sets or clears DTR on the requested line */
+static _INLINE_ void set_dtr(struct s3c2500_serial *info, int set)
+{
+    if (set) info->usart->cr |=  U_DTR;
+    else     info->usart->cr &= ~U_DTR;
+}
+
+/* Sets or clears RTS on the requested line */
+/* Note: rts is only directly controllable if hw flow
+ * control is not enabled */
+ 
+static _INLINE_ void set_rts(struct s3c2500_serial *info, int set)
+{
+    if (set) info->usart->cr |=  U_RTS;
+    else     info->usart->cr &= ~U_RTS;
+}
+
+/* Reads value of serial status signals */
+static unsigned int get_status(struct s3c2500_serial *info)
+{
+    unsigned int bits = 0;
+
+    if (info->usart->csr | U_CTS) bits |= TIOCM_CTS;
+    if (info->usart->cr  | U_RTS) bits |= TIOCM_RTS;
+
+    if (info->usart->cr  | U_DTR) bits |= TIOCM_DTR;
+    if (info->usart->csr | U_DSR) bits |= TIOCM_DSR;
+    if (info->usart->csr | U_DCD) bits |= TIOCM_CD;
+
+    return (bits);
+}
+
+/******************************************************************************/
+
+static inline int serial_paranoia_check(struct s3c2500_serial *info,
+					dev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+    static const char *badmagic =
+		"Warning: bad magic number for serial struct (%d, %d) in %s\n";
+    static const char *badinfo =
+		"Warning: null s3c2500_serial struct for (%d, %d) in %s\n";
+
+    if  (!info) {
+	printk(badinfo, MAJOR(device), MINOR(device), routine);
+	return 1;
+	}
+    if  (info->magic != SERIAL_MAGIC) {
+	printk(badmagic, MAJOR(device), MINOR(device), routine);
+	return 1;
+	}
+#endif
+    return 0;
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+    struct s3c2500_serial *info = (struct s3c2500_serial *) tty->driver_data;
+    unsigned long flags = 0;
+
+    if	(serial_paranoia_check(info, tty->device, "rs_stop"))
+    	return;
+
+    save_flags(flags);
+    cli();
+    tx_stop(info);
+    rx_stop(info);
+    restore_flags(flags);
+}
+
+static void rs_put_char(struct s3c2500_serial *info, char ch)
+{
+    unsigned long flags = 0;
+
+    save_flags(flags);
+    cli();
+    xmit_char(info, ch);
+    restore_flags(flags);
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+    struct s3c2500_serial *info = (struct s3c2500_serial *) tty->driver_data;
+    unsigned long flags = 0;
+
+    if  (serial_paranoia_check(info, tty->device, "rs_start"))
+	return;
+
+    save_flags(flags);
+    cli();
+    rx_start(info);
+    tx_start(info);
+    restore_flags(flags);
+}
+
+/* Drop into either the boot monitor or kadb upon receiving a break
+ * from keyboard/console input.
+ */
+static void batten_down_hatches(void)
+{
+#if 0
+	/* If we are doing kadb, we call the debugger
+	 * else we just drop into the boot monitor.
+	 * Note that we must flush the user windows
+	 * first before giving up control.
+	 */
+	if ((((unsigned long) linux_dbvec) >= DEBUG_FIRSTVADDR) &&
+		(((unsigned long) linux_dbvec) <= DEBUG_LASTVADDR))
+		sp_enter_debugger();
+	else
+		panic("s3c2500_serial: batten_down_hatches");
+	return;
+#endif
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ *
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assembly code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+ 
+static _INLINE_ void rs_sched_event(struct s3c2500_serial *info, int event)
+{
+    info->event |= 1 << event;
+    queue_task_irq_off(&info->tqueue, &tq_s3c2500_serial);
+    mark_bh(SERIAL_BH);
+}
+
+
+static _INLINE_ void handle_status ( struct s3c2500_serial *info, unsigned int status )
+{
+    if	( status & U_TFFUL ) {
+	return;				/* FIXME - do something */
+	}
+    if	( status & U_RFFUL ) {
+	info->usart->cr |= U_SBR;
+	return;
+	}
+    if	( status & U_BSD   ) {
+	batten_down_hatches();
+	}
+    info->usart->csr |= status;
+}
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+    run_task_queue(&tq_s3c2500_serial);
+}
+
+static void do_softint(void *private_)
+{
+    struct s3c2500_serial *info = (struct s3c2500_serial *) private_;
+    struct tty_struct *tty;
+
+    tty = info->tty;
+    if  ( !tty )	return;
+
+    if  (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+	if  ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) 
+	    (tty->ldisc.write_wakeup) (tty);
+	wake_up_interruptible(&tty->write_wait);
+	}
+}
+
+/*
+ * This routine is called from the scheduler tqueue when the interrupt
+ * routine has signalled that a hangup has occurred.  The path of
+ * hangup processing is:
+ *
+ * 	serial interrupt routine -> (scheduler tqueue) ->
+ * 	do_serial_hangup() -> tty->hangup() -> rs_hangup()
+ *
+ */
+static void do_serial_hangup(void *private_)
+{
+    struct s3c2500_serial *info = (struct s3c2500_serial *) private_;
+    struct tty_struct *tty;
+
+    tty = info->tty;
+    if (!tty)	return;
+    tty_hangup(tty);
+}
+
+static unsigned int calcCD(unsigned int br)
+{
+    int divisor;
+
+    /* naive method - also wrong: */
+    /* return (((UART_CLOCK+br/2)/br-1)<<4); */
+    /* return ((UART_CLOCK / br)<<4); */
+
+    /* effectively add 1/2 LSB before dividing */
+    divisor = (ARM_CLK/16)/ br + 1;
+    divisor = (divisor / 2) - 1;
+	
+    return (divisor << 4);
+}
+
+static _INLINE_ void uart_speed(struct s3c2500_serial *info, unsigned int cflag)
+{
+    unsigned baud = info->baud;
+    info->usart->brgr = calcCD(baud);
+}
+
+static int startup(struct s3c2500_serial *info)
+{
+    unsigned long flags;
+
+    if 	(info->flags & S_INITIALIZED)
+	return 0;
+
+    if 	(!info->xmit_buf) {
+	info->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL);
+	if 	(!info->xmit_buf)
+		return -ENOMEM;
+	}
+
+    save_flags(flags);    cli();
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttyS%d (irq %d)...\n", info->line, info->irq);
+#endif
+
+    /*
+     * Now, initialize the UART
+     */
+
+    info->usart->cr = 0;
+    if	( info->tty->termios->c_cflag & CBAUD ) {
+	info->usart->cr = U_IRQ_TMODE | U_IRQ_RMODE;
+	set_dtr (info, 1);
+	set_rts (info, 1);
+	fifo_init(info);
+	}
+    info->usart->ier = 0;		/* disable all interrupts */
+    
+    if 	(info->tty)
+	clear_bit(TTY_IO_ERROR, &info->tty->flags);
+    info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+
+    /*
+     * and set the speed of the serial port
+     */
+
+    change_speed(info);
+    info->flags |= S_INITIALIZED;
+    restore_flags(flags);
+    return 0;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct s3c2500_serial *info)
+{
+    unsigned long flags;
+	
+    tx_stop(info);
+    rx_stop(info);
+    if 	(!(info->flags & S_INITIALIZED))
+	return;
+
+#ifdef SERIAL_DEBUG_OPEN
+    printk("Shutting down serial port %d (irq %d)....\n", info->line,
+		   info->irq);
+#endif
+
+    save_flags(flags);    cli();		/* Disable interrupts */
+
+    if 	(info->xmit_buf) {
+    	free_page((unsigned long) info->xmit_buf);
+	info->xmit_buf = 0;
+	}
+
+    if 	(info->tty)
+	set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+    info->flags &= ~S_INITIALIZED;
+    restore_flags(flags);
+}
+
+static s3c_baud_table_t baud_table[] = {
+	{       0, B0       },
+	{      50, B50      },
+	{      75, B75      },
+	{     110, B110     },
+	{     134, B134     },
+	{     150, B150     },
+	{     200, B200     },
+	{     300, B300     },
+	{     600, B600     },
+	{    1200, B1200    },
+	{    1800, B1800    },
+	{    2400, B2400    },
+	{    4800, B4800    },
+	{    9600, B9600    },
+	{   19200, B19200   },
+	{   38400, B38400   },
+	{   57600, B57600   },
+	{  115200, B115200  },
+	{  230400, B230400  },
+	{  460800, B460800  },
+	{  500000, B500000  },
+	{  576000, B576000  },
+	{  921600, B921600  },
+	{ 1000000, B1000000 },
+	{      -1, -1       }
+};
+
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void change_speed(struct s3c2500_serial *info)
+{
+    unsigned cflag, iflag;
+    int      table_index;
+
+    if 	(!info->tty || !info->tty->termios)
+	return;
+	
+    cflag = info->tty->termios->c_cflag;
+    iflag = info->tty->termios->c_iflag;
+
+    tx_stop(info);
+    rx_stop(info);
+						/* calculate table index */
+    table_index = cflag & CBAUD;
+    if 	(table_index & CBAUDEX)	{
+    	table_index &= ~CBAUDEX; 		/* remove CBAUDEX bit */
+	table_index += CBAUD & ~CBAUDEX;	/* add high rate offset */
+	}
+    info->baud = baud_table[table_index].rate;
+    uart_speed(info, cflag);
+    
+    switch  (cflag & CSIZE) {
+	    case CS5: info->usart->cr &= U_WL5; break;
+	    case CS6: info->usart->cr |= U_WL6; break;
+	    case CS7: info->usart->cr |= U_WL7; break;
+	    case CS8: info->usart->cr |= U_WL8; break;
+	    }
+    if	    (cflag & CSTOPB)
+	    info->usart->cr |= U_STB;
+	    
+    if	    (cflag & PARENB) {
+	    if	    (!(cflag & PARODD))
+		    info->usart->cr |= U_EVEN_PMD;
+	    else    info->usart->cr |= U_ODD_PMD;
+	    }
+	    
+    if	    (cflag & CRTSCTS) {
+	    hw_flow_control (info, 1);
+	    set_dtr (info, 1);
+	    set_rts (info, 1);
+	    if	    ( (unsigned int)info->usart == (unsigned int)HUART0_BASE ) {
+		    REG_WRITE(IO_Ftn_cont1, (REG_READ(IO_Ftn_cont1) | 0xc0000000)); /* DSR0|DTR0 */
+		    REG_WRITE(IO_Ftn_cont2, (REG_READ(IO_Ftn_cont2) | 0x00000003)); /* CTS0|RTS0 */
+		    }
+	    else if ( (unsigned int)info->usart == (unsigned int)HUART1_BASE ) {
+		    REG_WRITE(IO_Ftn_cont2, (REG_READ(IO_Ftn_cont2) | 0x00000180)); /* DSR1|DTR1 */
+		    REG_WRITE(IO_Ftn_cont2, (REG_READ(IO_Ftn_cont2) | 0x00000060)); /* CTS1|RTS1 */
+		    }
+	    }
+	    
+    if	    (iflag & ( IXON | IXOFF)) {
+	    info->usart->cr |= U_SFEN;
+	    info->usart->ucc1 = ( START_CHAR(info->tty)<<24 ) | (START_CHAR(info->tty)<<16) |
+				( STOP_CHAR (info->tty)<<8 )  |  STOP_CHAR (info->tty);
+	    info->usart->ucc2 = ( START_CHAR(info->tty)<<24 ) | (START_CHAR(info->tty)<<16) |
+				( STOP_CHAR (info->tty)<<8 )  |  STOP_CHAR (info->tty);
+	    }
+	
+    tx_start(info);
+    rx_start(info);
+
+    return;
+}
+
+static _INLINE_ void xmit_char(struct s3c2500_serial *info, char ch)
+{
+    if	( info->xmit_fifo_size ) 	while   (info->usart->csr & U_TFFUL);
+    else				while   ( !(info->usart->csr & U_TI));
+    info->usart->thr = ch;
+}
+
+static void rs_set_ldisc(struct tty_struct *tty)
+{
+    struct s3c2500_serial *info = (struct s3c2500_serial *) tty->driver_data;
+
+    if  (serial_paranoia_check(info, tty->device, "rs_set_ldisc"))
+	return;
+
+    info->is_cons = (tty->termios->c_line == N_TTY);
+
+    printk("ttyS%d console mode %s\n", info->line, info->is_cons ? "on" : "off");
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+    struct s3c2500_serial *info = (struct s3c2500_serial *) tty->driver_data;
+    unsigned long flags;
+
+    if  (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
+	return;
+	
+    if  (!info->use_ints) {
+	for (;;) {
+	    if  (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !info->xmit_buf) 
+		return;
+	    save_flags(flags);	    cli();
+	    tx_start(info);
+	    xmit_char(info, info->xmit_buf[info->xmit_tail++]);
+	    info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+	    info->xmit_cnt--;
+	    }
+	} 
+    else {
+	if  (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !info->xmit_buf) 
+	    return;
+	save_flags(flags);	cli();
+	tx_start(info);
+	xmit_char(info, info->xmit_buf[info->xmit_tail++]);
+	info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+	info->xmit_cnt--;
+	}
+    restore_flags(flags);
+}
+
+extern void console_printn(const char *b, int count);
+static int rs_write(struct tty_struct *tty, int from_user,
+					const unsigned char *buf, int count)
+{
+    int c, total = 0;
+    struct s3c2500_serial *info = (struct s3c2500_serial *) tty->driver_data;
+    unsigned long flags;
+    
+    if  (serial_paranoia_check(info, tty->device, "rs_write"))
+	return 0;
+
+    if  (!tty || !info->xmit_buf || !tmp_buf)
+	return 0;
+
+
+    if  (from_user)
+	down(&tmp_buf_sem);
+
+    save_flags(flags);
+    cli();
+    while (1) {
+        c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+	    		   SERIAL_XMIT_SIZE - info->xmit_head));
+        if  (c <= 0)
+    	    break;
+	memcpy(info->xmit_buf + info->xmit_head, buf, c);
+	info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1);
+	info->xmit_cnt += c;
+	buf += c;
+	count -= c;
+	total += c;
+	}
+    restore_flags(flags);
+
+    if  (from_user)
+	up(&tmp_buf_sem);	
+	
+    if  (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
+	if   (!info->use_ints) {
+	     while (info->xmit_cnt) {
+		/* Send char */
+		xmit_char(info, info->xmit_buf[info->xmit_tail++]);
+		info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+		info->xmit_cnt--;
+    		}
+	     } 
+	else {
+/*
+ *	     if	  ( info->xmit_fifo_size )
+ */
+	          tx_start(info);
+#if 0
+	     else 
+     	    	  while (info->xmit_cnt) {
+		    save_flags(flags);
+		    cli();
+		    xmit_char(info, info->xmit_buf[info->xmit_tail++]);
+		    info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+		    info->xmit_cnt--;
+		    restore_flags(flags);
+    		    }
+#endif
+	     }
+	} 
+    return total;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+    struct s3c2500_serial *info = (struct s3c2500_serial *) tty->driver_data;
+    int ret;
+
+    if  (serial_paranoia_check(info, tty->device, "rs_write_room"))
+	return 0;
+    ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
+    if  (ret < 0)
+	ret = 0;
+    return ret;
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+    struct s3c2500_serial *info = (struct s3c2500_serial *) tty->driver_data;
+
+    if  (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+	return 0;
+    return info->xmit_cnt;
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+    unsigned long flags;
+    struct s3c2500_serial *info = (struct s3c2500_serial *) tty->driver_data;
+
+    if  (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+	return;
+    save_flags(flags);    cli();
+    info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+    restore_flags(flags);
+    wake_up_interruptible(&tty->write_wait);
+    if  ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) 
+	(tty->ldisc.write_wakeup) (tty);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ *
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct *tty)
+{
+    struct s3c2500_serial *info = (struct s3c2500_serial *) tty->driver_data;
+    unsigned int flags;
+
+#ifdef SERIAL_DEBUG_THROTTLE
+    char buf[64];
+
+    printk("throttle %s: %d....\n", _tty_name(tty, buf),
+    	    tty->ldisc.chars_in_buffer(tty));
+#endif
+
+    if  (serial_paranoia_check(info, tty->device, "rs_throttle"))
+	return;
+
+    if  (I_IXOFF(tty))
+	info->x_char = STOP_CHAR(tty);
+
+    /* Turn off RTS line (do this atomic) */
+    if	( tty->termios->c_cflag & CRTSCTS ) {	/* Why only RTS? What about DTR? OZH */
+	save_flags(flags); cli();
+	set_rts (info, 0);
+	restore_flags(flags);
+	}
+}
+
+static void rs_unthrottle(struct tty_struct *tty)
+{
+    struct s3c2500_serial *info = (struct s3c2500_serial *) tty->driver_data;
+    unsigned int flags;
+#ifdef SERIAL_DEBUG_THROTTLE
+    char buf[64];
+
+    printk("unthrottle %s: %d....\n", _tty_name(tty, buf),
+    	   tty->ldisc.chars_in_buffer(tty));
+#endif
+
+    if  (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+	return;
+
+    if  (I_IXOFF(tty)) {
+	if  (info->x_char)
+	    info->x_char = 0;
+	else
+	    info->x_char = START_CHAR(tty);
+	}
+
+    /* Assert RTS line (do this atomic) */		/* Why only RTS? What about DTR? OZH */
+    if	( tty->termios->c_cflag & CRTSCTS ) {
+	save_flags(flags); cli();
+	set_rts (info, 1);
+	restore_flags(flags);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int get_serial_info(struct s3c2500_serial *info,
+			   struct serial_struct *retinfo)
+{
+    struct serial_struct tmp;
+
+    if  (!retinfo)
+	return -EFAULT;
+    memset(&tmp, 0, sizeof(tmp));
+    tmp.type = info->type;
+    tmp.line = info->line;
+    tmp.irq = info->irq;
+    tmp.port = info->port;
+    tmp.flags = info->flags;
+    tmp.baud_base = info->baud_base;
+    tmp.close_delay = info->close_delay;
+    tmp.closing_wait = info->closing_wait;
+    tmp.custom_divisor = info->custom_divisor;
+    memcpy_tofs(retinfo, &tmp, sizeof(*retinfo));
+    return 0;
+}
+
+static int set_serial_info(struct s3c2500_serial *info,
+			   struct serial_struct *new_info)
+{
+    struct serial_struct new_serial;
+    struct s3c2500_serial old_info;
+    int retval = 0;
+
+    if  (!new_info)
+    	return -EFAULT;
+    memcpy_fromfs(&new_serial, new_info, sizeof(new_serial));
+    old_info = *info;
+
+    if  (!suser()) {
+	if	((new_serial.baud_base != info->baud_base) 	||
+		 (new_serial.type != info->type) 		||
+	         (new_serial.close_delay != info->close_delay) 	||
+		 ((new_serial.flags & ~S_USR_MASK) 		!=
+		 (info->flags & ~S_USR_MASK))) return -EPERM;
+	info->flags = ((info->flags & ~S_USR_MASK) |
+		      (new_serial.flags & S_USR_MASK));
+	info->custom_divisor = new_serial.custom_divisor;
+	goto check_and_exit;
+	}
+
+    if  (info->count > 1)
+	return -EBUSY;
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+    info->baud_base = new_serial.baud_base;
+    info->flags = ((info->flags & ~S_FLAGS) | (new_serial.flags & S_FLAGS));
+    info->type = new_serial.type;
+    info->close_delay = new_serial.close_delay;
+    info->closing_wait = new_serial.closing_wait;
+
+check_and_exit:
+    retval = startup(info);
+    return retval;
+}
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space.
+ */
+static int get_lsr_info(struct s3c2500_serial *info, unsigned int *value)
+{
+    unsigned char status;
+
+    cli();
+    status = (info->usart->csr & U_CTS) ? 1 : 0;
+    sti();
+    put_user(status, value);
+    return 0;
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void send_break(struct s3c2500_serial *info, int duration)
+{
+    current->state = TASK_INTERRUPTIBLE;
+    cli();
+    info->usart->cr |= U_SBR;
+    schedule_timeout(info->close_delay);
+    info->usart->cr &= (~U_SBR);
+    sti();
+}
+
+static int rs_ioctl(struct tty_struct *tty, struct file *file,
+					unsigned int cmd, unsigned long arg)
+{
+	int error;
+	struct s3c2500_serial *info = (struct s3c2500_serial *) tty->driver_data;
+	int retval;
+	unsigned int val;
+
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+		(cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) &&
+		(cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+			return -EIO;
+	}
+
+	switch (cmd) {
+	case TCSBRK:				/* SVID version: non-zero arg --> no break */
+		retval = tty_check_change(tty);
+		if (retval)
+			return retval;
+		tty_wait_until_sent(tty, 0);
+		if (!arg)
+			send_break(info, HZ / 4);	/* 1/4 second */
+		return 0;
+	case TCSBRKP:				/* support for POSIX tcsendbreak() */
+		retval = tty_check_change(tty);
+		if (retval)
+			return retval;
+		tty_wait_until_sent(tty, 0);
+		send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
+		return 0;
+	case TIOCGSOFTCAR:
+		error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
+
+		if (error)
+			return error;
+		put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
+		return 0;
+	case TIOCSSOFTCAR:
+		arg = get_user(arg, (unsigned long *) arg);
+		tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
+		return 0;
+	case TIOCGSERIAL:
+		error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(struct serial_struct));
+		if (error)
+			return error;
+		return get_serial_info(info, (struct serial_struct *) arg);
+	case TIOCSSERIAL:
+		return set_serial_info(info, (struct serial_struct *) arg);
+	case TIOCSERGETLSR:		/* Get line status register */
+		error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(unsigned int));
+		if (error)
+			return error;
+		else
+			return get_lsr_info(info, (unsigned int *) arg);
+
+	case TIOCSERGSTRUCT:
+		error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(struct s3c2500_serial));
+		if (error)
+			return error;
+		memcpy_tofs((struct s3c2500_serial *) arg, info,
+			sizeof(struct s3c2500_serial));
+		return 0;
+
+
+	case TIOCMGET:	/* get all modem bits */
+		if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(unsigned int))))
+			return(error);
+		val = get_status(info);
+		put_user(val, (unsigned int *) arg);
+		break;
+
+	case TIOCMBIS:	/* modem bits set */
+		if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+								 sizeof(unsigned int))))
+			return(error);
+		
+		get_user(val, (unsigned int *) arg);
+		
+		if (val & TIOCM_RTS) set_rts(info, 1);
+		if (val & TIOCM_DTR) set_dtr(info, 1);
+		break;
+
+	case TIOCMBIC:	/* modem bits clear */
+		if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+								 sizeof(unsigned int))))
+			return(error);
+		get_user(val, (unsigned int *) arg);
+			
+		if (val & TIOCM_RTS) set_rts(info, 0);
+		if (val & TIOCM_DTR) set_dtr(info, 0);
+		break;
+
+	case TIOCMSET:	/* set all modem bits */
+		if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+								 sizeof(unsigned int))))
+			return(error);
+		get_user(val, (unsigned int *) arg);
+
+		set_rts (info, ((val & TIOCM_RTS) ? 1 : 0) );
+		set_dtr (info, ((val & TIOCM_DTR) ? 1 : 0) );
+		break;
+
+	case TCSETS:	
+	  /*
+		* take care if the speed change, leave rest to termios by falling through
+		*/
+	  handle_termios_tcsets((struct termios *)arg, info);
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static void handle_termios_tcsets(  struct termios *ptermios, 
+				    struct s3c2500_serial *pinfo)
+{
+    if  (pinfo->tty->termios->c_cflag != ptermios->c_cflag) {
+	pinfo->tty->termios->c_cflag = ptermios->c_cflag;
+	}
+    change_speed(pinfo);
+}
+	  
+static void rs_set_termios( struct tty_struct *tty,
+			    struct termios *old_termios)
+{
+    struct s3c2500_serial *info = (struct s3c2500_serial *) tty->driver_data;
+
+    if  (tty->termios->c_cflag == old_termios->c_cflag)
+	return;
+    change_speed(info);
+    if  ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) {
+	tty->hw_stopped = 0;
+	rs_start(tty);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ *
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * S structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file *filp)
+{
+    struct s3c2500_serial *info = (struct s3c2500_serial *) tty->driver_data;
+    unsigned long flags;
+
+    if  (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+	return;
+
+    save_flags(flags);  cli();
+
+    if  (tty_hung_up_p(filp)) {
+	restore_flags(flags);
+	return;
+	}
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_close ttyS%d, count = %d\n", info->line, info->count);
+#endif
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  Info->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+			   "info->count is %d\n", info->count);
+		info->count = 1;
+	}
+	if (--info->count < 0) {
+		printk("rs_close: bad serial port count for ttyS%d: %d\n",
+			   info->line, info->count);
+		info->count = 0;
+	}
+	if (info->count) {
+		restore_flags(flags);
+		return;
+	}
+	// closing port so disable interrupts
+	set_ints_mode(info, 0);
+
+	info->flags |= S_CLOSING;
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & S_NORMAL_ACTIVE)
+		info->normal_termios = *tty->termios;
+	if (info->flags & S_CALLOUT_ACTIVE)
+		info->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != S_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (tty->ldisc.num != tty_ldiscs[N_TTY].num) {
+		if (tty->ldisc.close)
+			(tty->ldisc.close) (tty);
+		tty->ldisc = tty_ldiscs[N_TTY];
+		tty->termios->c_line = N_TTY;
+		if (tty->ldisc.open)
+			(tty->ldisc.open) (tty);
+	}
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+/*			current->timeout = jiffies + info->close_delay;  */
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(S_NORMAL_ACTIVE | S_CALLOUT_ACTIVE | S_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	restore_flags(flags);
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void rs_hangup(struct tty_struct *tty)
+{
+    struct s3c2500_serial *info = (struct s3c2500_serial *) tty->driver_data;
+
+    if	(serial_paranoia_check(info, tty->device, "rs_hangup"))
+	return;
+
+    rs_flush_buffer(tty);
+    shutdown(info);
+    info->event = 0;
+    info->count = 0;
+    info->flags &= ~(S_NORMAL_ACTIVE | S_CALLOUT_ACTIVE);
+    info->tty = 0;
+    wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file *filp,
+						   struct s3c2500_serial *info)
+{
+	unsigned long flags;
+/*	struct wait_queue wait = { current, NULL }; */
+	DECLARE_WAITQUEUE(wait, current);
+	int retval;
+	int do_clocal = 0;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (info->flags & S_CLOSING) {
+		interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		if (info->flags & S_HUP_NOTIFY)
+			return -EAGAIN;
+		else
+			return -ERESTARTSYS;
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & S_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+			(info->flags & S_SESSION_LOCKOUT) &&
+			(info->session != current->session)) return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+			(info->flags & S_PGRP_LOCKOUT) &&
+			(info->pgrp != current->pgrp)) return -EBUSY;
+		info->flags |= S_CALLOUT_ACTIVE;
+		return 0;
+	}
+
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & S_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= S_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & S_CALLOUT_ACTIVE) {
+		if (info->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, info->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready before block: ttyS%d, count = %d\n",
+		   info->line, info->count);
+#endif
+	info->count--;
+	info->blocked_open++;
+	while (1) {
+		save_flags(flags);
+		cli();
+		if (!(info->flags & S_CALLOUT_ACTIVE)) {
+			set_rts(info, 1);
+			set_dtr(info, 1);
+			}
+		restore_flags(flags);
+		current->state = TASK_INTERRUPTIBLE;
+		if (tty_hung_up_p(filp) || !(info->flags & S_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & S_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & S_CALLOUT_ACTIVE) &&
+			!(info->flags & S_CLOSING) && do_clocal)
+			break;
+		if (signal_pending(current)) {
+/*		if (current->signal & ~current->blocked) {  */
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef SERIAL_DEBUG_OPEN
+		printk("block_til_ready blocking: ttyS%d, count = %d\n",
+			   info->line, info->count);
+#endif
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&info->open_wait, &wait);
+	if (!tty_hung_up_p(filp))
+		info->count++;
+	info->blocked_open--;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready after blocking: ttyS%d, count = %d\n",
+		   info->line, info->count);
+#endif
+	if (retval)
+		return retval;
+	info->flags |= S_NORMAL_ACTIVE;
+	return 0;
+}
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its S structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+int rs_open(struct tty_struct *tty, struct file *filp)
+{
+	struct s3c2500_serial *info;
+	int retval, line;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+
+	/* check if line is sane */
+	if (line < 0 || line >= USART_NUMBER)
+		return -ENODEV;
+
+	info = &s3c2500_info[line];
+
+	if (serial_paranoia_check(info, tty->device, "rs_open"))
+		return -ENODEV;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+		   info->count);
+#endif
+	info->count++;
+	tty->driver_data = info;
+	info->tty = tty;
+
+	/*
+	 * Start up serial port
+	 */
+	 
+	set_ints_mode(info, 1);
+	
+	retval = startup(info);
+	if (retval)
+		return retval;
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("rs_open returning after block_til_ready with %d\n",
+			   retval);
+#endif
+		return retval;
+	}
+
+	if ((info->count == 1) && (info->flags & S_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->normal_termios;
+		else
+			*tty->termios = info->callout_termios;
+		change_speed(info);
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open ttyS%d successful...\n", info->line);
+#endif
+	return 0;
+}
+
+/************************************************************************/
+/*	This is the serial driver's generic interrupt routine		*/	
+/************************************************************************/
+
+static _INLINE_ void transmit_CUART_chars(struct s3c2500_serial *info)
+{
+    if  (info->x_char) {
+        info->usart->thr = info->x_char;
+        info->x_char = 0;
+        return;
+        }
+
+    if  ((info->xmit_cnt <= 0) || info->tty->stopped || info->tty->hw_stopped ) {
+	tx_stop(info);
+	return;
+	}
+
+    info->usart->thr = info->xmit_buf[info->xmit_tail++];
+    info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+    info->xmit_cnt--;
+	
+    if  (info->xmit_cnt < WAKEUP_CHARS)
+    	rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+    if  ( info->xmit_cnt <= 0 )
+        tx_stop(info);
+    return;
+}
+
+static _INLINE_ void receive_CUART_chars(struct s3c2500_serial *info)
+{
+    struct tty_struct *tty = info->tty;
+    volatile struct s3c2500_usart_regs *uart = info->usart;
+    volatile unsigned int status;
+
+    if  (!info || !tty || (!(info->flags & S_INITIALIZED)))
+	return;
+
+    if  (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+	tty->flip.tqueue.routine((void *) tty);
+	if  (tty->flip.count >= TTY_FLIPBUF_SIZE)
+	    return;
+	}
+
+    status = uart->csr;
+    *tty->flip.char_buf_ptr = uart->rhr & 0xFF;
+    *tty->flip.flag_buf_ptr = TTY_NORMAL;
+
+    if  (status & (U_BSD | U_PER | U_FER | U_CCD | U_OER)) {
+	    handle_status (info, status & (U_BSD | U_PER | U_FER | U_CCD | U_OER));
+	    if	(status & U_BSD)
+		*tty->flip.flag_buf_ptr = TTY_BREAK;
+	    if	(status & U_PER)
+		*tty->flip.flag_buf_ptr = TTY_PARITY;
+	    if	(status & U_FER)
+		*tty->flip.flag_buf_ptr = TTY_FRAME;
+	    }
+	tty->flip.char_buf_ptr++;
+	tty->flip.flag_buf_ptr++;
+	tty->flip.count++;
+
+    tty_flip_buffer_push(tty);
+    return;
+}
+
+static _INLINE_ void transmit_HUART_chars(struct s3c2500_serial *info, struct pt_regs *regs)
+{
+    volatile unsigned int status;
+    register int count;
+
+    if  (info->x_char) {
+        info->usart->thr = info->x_char;
+        info->x_char = 0;
+        return;
+        }
+
+    if  ((info->xmit_cnt <= 0) || info->tty->stopped || info->tty->hw_stopped ) {
+	tx_stop(info);
+	return;
+	}
+
+    count = info->xmit_fifo_size;
+
+    do  {
+	status = info->usart->csr;
+	if  ( status & U_TFFUL ) {
+	    handle_status (info, U_TFFUL);
+	    break;
+	    }
+        else {
+	    info->usart->thr = info->xmit_buf[info->xmit_tail++];
+    	    info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+    	    if  ( --info->xmit_cnt <= 0 ) 
+		break;
+	    }
+    	} while ( --count > 0 );
+	
+    if  (info->xmit_cnt < WAKEUP_CHARS)
+    	rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+    if  ( info->xmit_cnt <= 0 )
+        tx_stop(info);
+    return;
+}
+
+static _INLINE_ void receive_HUART_chars(struct s3c2500_serial *info, struct pt_regs *regs)
+{
+    struct tty_struct *tty = info->tty;
+    volatile struct s3c2500_usart_regs *uart = info->usart;
+    volatile unsigned int ch, status;
+    register int count;
+    
+    if	( !info || !tty || (!(info->flags & S_INITIALIZED)) )
+	return;
+	
+    count  = info->rx_fifo_size;
+    
+    status = uart->csr;
+    
+    do {
+	if  ( status & U_RFEMT )
+	    break;
+
+	if  (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+	    tty->flip.tqueue.routine((void *) tty);
+	    if 	(tty->flip.count >= TTY_FLIPBUF_SIZE)
+		return;
+	    }
+	    
+	ch = uart->rhr & 0xFF;
+	*tty->flip.char_buf_ptr = ch;
+	*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		
+	if	(status & (U_BSD | U_PER | U_FER | U_CCD | U_RFFUL | U_E_CTS)) {
+		if 	( status & U_CCD ) {
+			handle_status ( info, U_CCD );
+			}
+		if 	( status & U_RFFUL ) {
+			handle_status ( info, U_RFFUL );
+			}
+		if 	( status & U_E_CTS ) {
+			handle_status ( info, U_E_CTS );
+			}
+		if	(status & U_BSD) {
+			*tty->flip.flag_buf_ptr = TTY_BREAK;
+			handle_status ( info, U_BSD );
+			}
+		else if (status & U_PER) {
+			*tty->flip.flag_buf_ptr = TTY_PARITY;
+			handle_status ( info, U_PER );
+			}
+		else if (status & U_FER) {
+			*tty->flip.flag_buf_ptr = TTY_FRAME;
+			handle_status ( info, U_FER );
+			}
+		}
+	
+	tty->flip.char_buf_ptr++;
+	tty->flip.flag_buf_ptr++;
+	tty->flip.count++;
+
+	if  ( status & U_OER ) {
+	    handle_status ( info, U_OER );
+	    if  (tty->flip.count < TTY_FLIPBUF_SIZE) {
+	        *tty->flip.flag_buf_ptr = TTY_OVERRUN;
+	        tty->flip.count++;
+	        tty->flip.flag_buf_ptr++;
+	        tty->flip.char_buf_ptr++;
+	        }
+	    }
+		
+	status = uart->csr;
+	
+	} while ((--count > 0) && (status & U_RDV));
+	
+    if ( status & (U_RFOV | U_E_RxTO ) )
+        handle_status (info, (U_RFOV | U_E_RxTO));
+	
+    tty_flip_buffer_push(tty);
+}
+
+/*
+ * This is the serial driver's interrupt routine
+ */
+static void rs_interrupt_CUART(int irq, void *dev_id, struct pt_regs * regs)
+{
+    if	( irq == SRC_IRQ_CUART_TX )	transmit_CUART_chars(&s3c2500_info[0]);
+    else				receive_CUART_chars (&s3c2500_info[0]);
+}
+
+static void rs_interrupt_HUART0(int irq, void *dev_id, struct pt_regs * regs)
+{
+    if	( irq == SRC_IRQ_HUART0_TX )	transmit_HUART_chars(&s3c2500_info[1], regs);
+    else				receive_HUART_chars (&s3c2500_info[1], regs);
+}
+
+static void rs_interrupt_HUART1(int irq, void *dev_id, struct pt_regs * regs)
+{
+    if	( irq == SRC_IRQ_HUART1_TX )	transmit_HUART_chars(&s3c2500_info[2], regs);
+    else				receive_HUART_chars (&s3c2500_info[2], regs);
+}
+
+static struct irqaction irq_cuartTx =
+    { rs_interrupt_CUART, 0, 0, "CUART(Tx)", NULL, NULL };
+static struct irqaction irq_cuartRx =
+    { rs_interrupt_CUART, 0, 0, "CUART(Rx)", NULL, NULL };
+#if USART_NUMBER > 1
+static struct irqaction irq_huart0Tx =
+    { rs_interrupt_HUART0, 0, 0, "HUART0(Tx)", NULL, NULL };
+static struct irqaction irq_huart0Rx =
+    { rs_interrupt_HUART0, 0, 0, "HUART0(Rx)", NULL, NULL };
+#endif
+#if USART_NUMBER > 2
+static struct irqaction irq_huart1Tx =
+    { rs_interrupt_HUART1, 0, 0, "HUART1(Tx)", NULL, NULL };
+static struct irqaction irq_huart1Rx =
+    { rs_interrupt_HUART1, 0, 0, "HUART1(Rx)", NULL, NULL };
+#endif
+
+static void __init uart_interrupts_init(void)
+{
+extern int setup_arm_irq(int, struct irqaction *);
+    setup_arm_irq(SRC_IRQ_CUART_TX,  &irq_cuartTx);
+    setup_arm_irq(SRC_IRQ_CUART_RX,  &irq_cuartRx);
+#if USART_NUMBER > 1
+    setup_arm_irq(SRC_IRQ_HUART0_TX, &irq_huart0Tx);
+    setup_arm_irq(SRC_IRQ_HUART0_RX, &irq_huart0Rx);
+#endif
+#if USART_NUMBER > 2
+    setup_arm_irq(SRC_IRQ_HUART1_TX, &irq_huart1Tx);
+    setup_arm_irq(SRC_IRQ_HUART1_RX, &irq_huart1Rx);
+#endif
+}
+
+static void show_serial_version(void)
+{
+    printk("S3C2500 Serial I/O driver. Version 3.0 <www.ArcturusNetworks.com>\n");
+}
+
+/* rs_init inits the driver */
+static int __init rs_s3c2500_init(void)
+{
+    int flags, i;
+    struct s3c2500_serial *info;
+
+    /* Setup base handler, and timer table. */
+    init_bh(SERIAL_BH, do_serial_bh);
+
+    show_serial_version();
+    
+    /* Initialize the tty_driver structure */
+
+    /* set the tty_struct pointers to NULL to let the layer */
+    /* above allocate the structs. */
+    for	(i=0; i < USART_NUMBER; i++)	serial_table[i] = NULL;
+		
+    memset(&serial_driver, 0, sizeof(struct tty_driver));
+
+    serial_driver.magic = TTY_DRIVER_MAGIC;
+    serial_driver.name = "ttyS";
+    serial_driver.major = TTY_MAJOR;
+    serial_driver.minor_start = 64;
+    serial_driver.num = USART_NUMBER;
+    serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+    serial_driver.subtype = SERIAL_TYPE_NORMAL;
+    serial_driver.init_termios = tty_std_termios;
+    serial_driver.init_termios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
+    serial_driver.init_termios.c_cflag |= default_console_baud.cflag;
+    serial_driver.flags = TTY_DRIVER_REAL_RAW;
+    serial_driver.refcount = &serial_refcount;
+    serial_driver.table = serial_table;
+    serial_driver.termios = serial_termios;
+    serial_driver.termios_locked = serial_termios_locked;
+
+    serial_driver.open = rs_open;
+    serial_driver.close = rs_close;
+    serial_driver.write = rs_write;
+    serial_driver.flush_chars = rs_flush_chars;
+    serial_driver.write_room = rs_write_room;
+    serial_driver.chars_in_buffer = rs_chars_in_buffer;
+    serial_driver.flush_buffer = rs_flush_buffer;
+    serial_driver.ioctl = rs_ioctl;
+    serial_driver.throttle = rs_throttle;
+    serial_driver.unthrottle = rs_unthrottle;
+    serial_driver.set_termios = rs_set_termios;
+    serial_driver.stop = rs_stop;
+    serial_driver.start = rs_start;
+    serial_driver.hangup = rs_hangup;
+    serial_driver.set_ldisc = rs_set_ldisc;
+
+    /*
+     * The callout device is just like normal device except for
+     * major number and the subtype code.
+     */
+    callout_driver = serial_driver;
+    callout_driver.name = "cua";
+    callout_driver.major = TTYAUX_MAJOR;
+    callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+
+    if  (tty_register_driver(&serial_driver))
+	panic("Couldn't register serial driver\n");
+    if  (tty_register_driver(&callout_driver))
+	panic("Couldn't register callout driver\n");
+
+    save_flags(flags);
+    cli();
+    for (i = 0; i < USART_NUMBER; i++) {
+	info = &s3c2500_info[i];
+	info->magic = SERIAL_MAGIC;
+	info->usart = usarts[i];
+	info->tty = 0;
+	info->port = i+1;
+	info->line = i;
+	
+	if    ( console_port == i )	info->is_cons = 1;
+	else				info->is_cons = 0;
+
+	switch (i) {
+	    case 0 :	info->irqmask = MASK_IRQ_CUART_RX;
+			info->irq = SRC_IRQ_CUART_RX;
+			info->xmit_fifo_size = 0;
+	    		info->rx_fifo_size = 0;
+			break;
+			
+	    case 1 :	info->irqmask = MASK_IRQ_HUART0_RX;
+			info->irq = SRC_IRQ_HUART0_RX;
+			info->xmit_fifo_size = TX_FIFO_SIZE;
+			info->rx_fifo_size = RX_FIFO_SIZE;
+			REG_WRITE(IO_Ftn_cont2, (REG_READ(IO_Ftn_cont2) | 0x00000004));	/* DCD0 */
+			break;
+			
+	    case 2 :	info->irqmask = MASK_IRQ_HUART1_RX;
+			info->irq = SRC_IRQ_HUART1_RX;
+			info->xmit_fifo_size = TX_FIFO_SIZE;
+			info->rx_fifo_size = RX_FIFO_SIZE;
+			REG_WRITE(IO_Ftn_cont2, (REG_READ(IO_Ftn_cont2) | 0x00000200)); /* DCD1 */
+			break;
+	    }
+
+	fifo_init(info);
+	
+	set_ints_mode(info, 0);
+/*	info->custom_divisor = 16;  */
+	info->custom_divisor = 0;
+	info->close_delay = 50;
+	info->closing_wait = 3000;
+	info->cts_state = 1;
+	info->x_char = 0;
+	info->event = 0;
+	info->count = 0;
+	info->blocked_open = 0;
+	info->tqueue.routine = do_softint;
+	info->tqueue.data = info;
+	info->tqueue_hangup.routine = do_serial_hangup;
+	info->tqueue_hangup.data = info;
+	info->callout_termios = callout_driver.init_termios;
+	info->normal_termios = serial_driver.init_termios;
+	
+	init_waitqueue_head(&info->open_wait);
+	init_waitqueue_head(&info->close_wait);
+	
+	printk("%s%d: at 0x%p (IRQs: Tx=%2.2d Rx=%2.2d) is a builtin", serial_driver.name, info->line,
+		                           info->usart, info->irq-1, info->irq);
+	if ( !i )	printk(" Console UART\n");
+	else		printk(" High-Speed UART\n");
+	}
+    uart_interrupts_init();
+
+    restore_flags(flags);
+    return 0;
+}
+
+module_init(rs_s3c2500_init);
+
+
+#if defined(CONFIG_SERIAL_S3C2500_CONSOLE)
+/*
+ * ------------------------------------------------------------
+ * Serial console driver
+ * ------------------------------------------------------------
+ */
+static kdev_t s3c2500_console_device(struct console *);
+static int s3c2500_console_setup(struct console *, char *);
+static void s3c2500_console_write (struct console *, const char *, unsigned int );
+static int s3c2500_console_initialized;
+
+static struct console s3c2500_driver = {
+	name:		"ttyS",
+	write:		s3c2500_console_write,
+	device:		s3c2500_console_device,
+	setup:		s3c2500_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+static int s3c2500_console_setup(struct console *c, char *p)
+{
+    int i;
+    int speed = -1;
+    static struct s3c2500_serial *info;
+    
+    switch ( console_port ) {
+	case 0 : info = &s3c2500_info[0];
+		 break;
+	case 1 : info = &s3c2500_info[1];
+		 break;
+	case 2 : info = &s3c2500_info[2];
+		 break;
+	default: return -1;
+	}
+
+    memset(info, 0, sizeof(struct s3c2500_serial));
+
+    switch ( console_port ) {
+	case 0 : info->usart = (volatile struct s3c2500_usart_regs *) CUART_BASE;
+		 break;
+	case 1 : info->usart = (volatile struct s3c2500_usart_regs *) HUART0_BASE;
+		 break;
+	case 2 : info->usart = (volatile struct s3c2500_usart_regs *) HUART1_BASE;
+		 break;
+	}
+    info->is_cons = 1;
+    info->use_ints = 0;
+    info->cts_state = 1;
+    info->usart->cr = 0; 
+    info->usart->cr = (U_IRQ_TMODE | U_IRQ_RMODE | U_WL8);
+    info->xmit_fifo_size = 0;
+    info->rx_fifo_size = 0;
+    fifo_init(info);
+    fifo_reset(info);
+
+#if defined(CONFIG_UCBOOTSTRAP)
+    /* If uCbootloader does not have CONSOLE_SPEED defined, */
+    if (sscanf (getbenv("CONSOLE_SPEED"), "%d", &speed) != 1)
+		speed = -1;
+
+#else /* no uCbootstrap */
+#if defined(CONFIG_INIT_CONSOLE_SPEED)
+    speed = CONFIG_INIT_CONSOLE_SPEED;
+
+#else
+    speed = -1;
+    
+#endif /* defined(CONFIG_INIT_CONSOLE_SPEED) */
+#endif
+
+	/* if console speed has not been overridden from the default: */
+    if  (speed != -1) {
+	for (i=0;baud_table[i].rate != -1;i++)
+	    if  (baud_table[i].rate == speed) {
+		default_console_baud.rate  = speed;
+		default_console_baud.cflag = baud_table[i].cflag;
+		break;
+		}
+	}
+
+    info->baud = default_console_baud.rate;
+    info->usart->brgr = calcCD(info->baud);
+    info->usart->ier = 0;
+
+    s3c2500_console_initialized = 1;
+    return 0;
+}
+
+static kdev_t s3c2500_console_device(struct console *c)
+{
+    return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static void s3c2500_console_write (struct console *co, const char *str,
+			   unsigned int count)
+{
+    static struct s3c2500_serial *info;
+    
+    switch ( console_port ) {
+	case 0 : info = &s3c2500_info[0];
+		 break;
+	case 1 : info = &s3c2500_info[1];
+		 break;
+	case 2 : info = &s3c2500_info[2];
+		 break;
+	}
+
+    if  (!s3c2500_console_initialized)
+	printk ("WARNING: Console used unintialized\n");
+
+    while (count--) {
+	if  (*str == '\n')
+	    rs_put_char(info,'\r');
+        rs_put_char(info, *str++ );
+    	}
+}
+
+void __init s3c2500_console_init(void)
+{
+    register_console ( &s3c2500_driver );
+}
+#endif	/* CONFIG_SERIAL_S3C2500_CONSOLE */
diff -urN linux-2.4.29/drivers/char/serial_s3c2500.h linux-2.4.29-uc1/drivers/char/serial_s3c2500.h
--- linux-2.4.29/drivers/char/serial_s3c2500.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_s3c2500.h	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,150 @@
+/*
+ * drivers/char/serial-s3c2500.h
+ * 
+ * Serial port driver for the Samsung s3c2500A builtin UARTs
+ * Copyright (c) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * Based on: drivers/char/serial-s3c4530.c
+ * Copyright (c) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * Based on: drivers/char/trioserial.c
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *               1998-2003  D. Jeff Dionne <jeff@uClinux.org>
+ * Copyright (c) 1998  The Silver Hammer Group, Ltd.
+ *
+ * Based on: drivers/char/68328serial.h
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _s3c2500_SERIAL_H
+#define _s3c2500_SERIAL_H
+
+#include <linux/config.h>
+#include <asm/page.h>
+#include <asm/arch/hardware.h>
+
+/*
+ * For the close wait times, 0 means wait forever for serial port to
+ * flush its output.  65535 means don't wait at all.
+ */
+#define S_CLOSING_WAIT_INF	0
+#define S_CLOSING_WAIT_NONE	65535
+
+/*
+ * Definitions for S_struct (and serial_struct) flags field
+ */
+#define S_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes 
+				   on the callout port */
+#define S_FOURPORT  0x0002	/* Set OU1, OUT2 per AST Fourport settings */
+#define S_SAK	0x0004	/* Secure Attention Key (Orange book) */
+#define S_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
+
+#define S_SPD_MASK	0x0030
+#define S_SPD_HI	0x0010	/* Use 56000 instead of 38400 bps */
+
+#define S_SPD_VHI	0x0020  /* Use 115200 instead of 38400 bps */
+#define S_SPD_CUST	0x0030  /* Use user-specified divisor */
+
+#define S_SKIP_TEST	0x0040 /* Skip UART test during autoconfiguration */
+#define S_AUTO_IRQ  0x0080 /* Do automatic IRQ during autoconfiguration */
+#define S_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
+#define S_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
+#define S_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
+
+#define S_FLAGS	0x0FFF	/* Possible legal S flags */
+#define S_USR_MASK 0x0430	/* Legal flags that non-privileged
+				 * users can set or reset */
+
+/* Internal flags used only by kernel/chr_drv/serial.c */
+#define S_INITIALIZED	0x80000000 /* Serial port was initialized */
+#define S_CALLOUT_ACTIVE	0x40000000 /* Call out device is active */
+#define S_NORMAL_ACTIVE	0x20000000 /* Normal device is active */
+#define S_BOOT_AUTOCONF	0x10000000 /* Autoconfigure port on bootup */
+#define S_CLOSING		0x08000000 /* Serial port is closing */
+#define S_CTS_FLOW		0x04000000 /* Do CTS flow control */
+#define S_CHECK_CD		0x02000000 /* i.e., CLOCAL */
+
+/* Software state per channel */
+
+/*
+ * This is our internal structure for each serial port's state.
+ * 
+ * Many fields are paralleled by the structure used by the serial_struct
+ * structure.
+ *
+ * For definitions of the flags field, see tty.h
+ */
+
+struct s3c2500_serial {
+	char soft_carrier;  /* Use soft carrier on this channel */
+	char break_abort;   /* Is serial console in, so process brk/abrt */
+#if 0
+	char cons_keyb;     /* Channel runs the keyboard */
+	char cons_mouse;    /* Channel runs the mouse */
+	char kgdb_channel;  /* Kgdb is running on this channel */
+#endif
+	char is_cons;       /* Is this our console. */
+
+	/* We need to know the current clock divisor
+	 * to read the bps rate the chip has currently
+	 * loaded.
+	 */
+	unsigned char clk_divisor;  /* May be 1, 16, 32, or 64 */
+	int baud;
+	int			magic;
+	int			baud_base;
+	int			port;
+	int			irq;
+	int			irqmask;
+	int			flags; 		/* defined in tty.h */
+	int			type; 		/* UART type */
+	int			use_ints;
+	volatile struct s3c2500_usart_regs	*usart;
+	int			cts_state;
+	struct tty_struct 	*tty;
+	int			read_status_mask;
+	int			ignore_status_mask;
+	int			timeout;
+	int			xmit_fifo_size;
+	int			rx_fifo_size;
+	int			custom_divisor;
+	int			x_char;	/* xon/xoff character */
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int			count;	    /* # of fd on device */
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+	unsigned char 		*xmit_buf;
+/*	unsigned char 		*rx_buf;  */
+	int			xmit_head;
+	int			xmit_tail;
+	int			xmit_cnt;
+	struct tq_struct	tqueue;
+	struct tq_struct	tqueue_hangup;
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+};
+
+
+/* typedef to correlate a serial speed with its cflags - type handle: */
+typedef struct
+{
+  int rate;
+  int cflag;
+} s3c_baud_table_t;
+
+
+#define RS_EVENT_WRITE_WAKEUP   0
+#define SERIAL_MAGIC 0x5301
+
+
+#endif /* !(_s3c2500_SERIAL_H) */
diff -urN linux-2.4.29/drivers/char/serial_s3c3410.c linux-2.4.29-uc1/drivers/char/serial_s3c3410.c
--- linux-2.4.29/drivers/char/serial_s3c3410.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_s3c3410.c	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,1739 @@
+/*
+ * serial_s3c3410.c: Serial port driver for the Samsung S3C3410X builtin UART
+ *
+ * Copyright (c) 2003	sympat GmbH
+ *			by Thomas Eschenbacher <thomas.eschenbacher@sympat.de>
+ *
+ * Copyright (c) 2001	Arcturus Networks Inc. 
+ * 			by Oleksandr Zhadan  <www.ArcturusNetworks.com>
+ * Copyright (c) 2002	Arcturus Networks Inc. 
+ * 		       	by Michael Leslie    <www.ArcturusNetworks.com>
+ *
+ * Based on: drivers/char/trioserial.c
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *               1998-2003  D. Jeff Dionne <jeff@uClinux.org>
+ * Copyright (c) 1998  The Silver Hammer Group, Ltd.
+ *
+ * Based on: drivers/char/68328serial.c
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/arch/irq.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+
+#define queue_task_irq_off queue_task
+#define copy_from_user(a,b,c) memcpy_fromfs(a,b,c)
+#define copy_to_user(a,b,c) memcpy_tofs(a,b,c)
+
+#include <asm/uaccess.h>
+
+#include "serial_s3c3410.h"
+
+#if defined(CONFIG_UCBOOTSTRAP)
+#include <asm/uCbootstrap.h>
+extern  char *getbenv (char *a);
+#endif
+
+#define USART_CNT		1
+					/* Receive FIFO trigger level	*/
+#define RX_FIFO_LEVEL		4	/* 	2 or 4 or 6 or 8	*/
+					/* Transfer FIFO trigger level	*/
+#define TX_FIFO_LEVEL		4	/*	0 or 2 or 4 or 6	*/
+
+#define TX_FIFO_DEPTH		(5) 	/* maximum transmit FIFO length */
+#define RX_FIFO_DEPTH		(8) 	/* maximum receive FIFO length  */
+
+/* serial subtype definitions */
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+/* Debugging... DEBUG_INTR is bad to use when one of the zs
+ * lines is your console ;(
+ */
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+#define SERIAL_DEBUG_THROTTLE
+
+#define _INLINE_ inline
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+static struct s3c3410_serial s3c3410_info;
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the memcpy_fromfs blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+ 
+static unsigned char tmp_buf[SERIAL_XMIT_SIZE];	/* This is cheating */
+static DECLARE_MUTEX (tmp_buf_sem);
+
+/* Console hooks... */
+static s3c_baud_table_t default_console_baud = { 115200, B115200 };
+
+#if defined(CONFIG_SERIAL_S3C3410_CONSOLE)
+static int console_number =  0;
+#endif
+	
+DECLARE_TASK_QUEUE(tq_s3c3410_serial);
+
+static struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+static struct tty_struct 	*serial_table[USART_CNT];
+static struct termios 		*serial_termios[USART_CNT];
+static struct termios		*serial_termios_locked[USART_CNT];
+
+static void change_speed	(struct s3c3410_serial *info);
+
+static _INLINE_ void tx_stop	(void);
+static _INLINE_ void tx_start	(int ints);
+static _INLINE_ void rx_stop	(void);
+static _INLINE_ void rx_start	(int ints);
+static _INLINE_ void xmit_char		(struct s3c3410_serial *info, char ch);
+static _INLINE_ void rs_sched_event	(struct s3c3410_serial *info, int event);
+static _INLINE_ void uart_speed		(struct s3c3410_serial *info, unsigned int cflag);
+static _INLINE_ void handle_status 	(struct s3c3410_serial *info, unsigned int status);
+static _INLINE_ void fifo_reset		(void);
+static _INLINE_ void fifo_init		(void);
+
+static void set_ints_mode	(struct s3c3410_serial *info, int yes);
+static void rs_interruptTx	(int irq, void *dev_id, struct pt_regs *regs);
+static void rs_interruptRx	(int irq, void *dev_id, struct pt_regs *regs);
+static void rs_interruptErr	(int irq, void *dev_id, struct pt_regs *regs);
+
+static void batten_down_hatches (void);
+extern void show_net_buffers	(void);
+extern void hard_reset_now	(void);
+static void handle_termios_tcsets(struct termios *ptermios, struct s3c3410_serial *pinfo);
+
+
+/******************************************************************************/
+static _INLINE_ void tx_delay(void)
+{
+	volatile int i;
+	for (i=0; i < 50; i++) {
+		i = i+1;
+		i = i-1;
+	};
+}
+
+static _INLINE_ void tx_start(int ints)
+{
+	if (ints) enable_irq(S3C3410X_INTERRUPT_UTX);
+}
+
+static _INLINE_ void tx_stop(void)
+{
+	disable_irq(S3C3410X_INTERRUPT_UTX);
+}
+
+static _INLINE_ void rx_start(int ints)
+{
+	if (ints) {
+		enable_irq(S3C3410X_INTERRUPT_URX);
+		enable_irq(S3C3410X_INTERRUPT_UERR);
+	}
+}
+
+static _INLINE_ void rx_stop(void)
+{
+	disable_irq(S3C3410X_INTERRUPT_URX);
+	disable_irq(S3C3410X_INTERRUPT_UERR);
+}
+
+static void set_ints_mode(struct s3c3410_serial *info, int yes)
+{
+	info->use_ints = yes;
+	if (yes) {
+		s3c3410_unmask_irq(S3C3410X_INTERRUPT_UTX);
+		s3c3410_unmask_irq(S3C3410X_INTERRUPT_URX);
+		s3c3410_unmask_irq(S3C3410X_INTERRUPT_UERR);
+	} else {	
+		s3c3410_mask_irq(S3C3410X_INTERRUPT_UERR);
+		s3c3410_mask_irq(S3C3410X_INTERRUPT_URX);
+		s3c3410_mask_irq(S3C3410X_INTERRUPT_UTX);
+	}
+}
+
+static void hw_flow_control (int cmd)
+{
+	/* the SMDK40100 board does not have hw flow control */
+}
+
+static _INLINE_ void fifo_reset()
+{
+	u_int8_t ufcon = inb(S3C3410X_UART_BASE+S3C3410X_UFCON);
+	ufcon |= UFCON_RFR | UFCON_TFR;
+	outb(ufcon, S3C3410X_UART_BASE+S3C3410X_UFCON);
+}
+
+static _INLINE_ void fifo_init()
+{
+	u_int8_t ufcon = inb(S3C3410X_UART_BASE+S3C3410X_UFCON);
+
+	if (RX_FIFO_LEVEL + TX_FIFO_LEVEL)
+		ufcon |= UFCON_FE;
+
+	switch (RX_FIFO_LEVEL) {
+		case 2 :	ufcon |= UFCON_RFTL_2; break;
+		case 4 :	ufcon |= UFCON_RFTL_4; break;
+		case 6 :	ufcon |= UFCON_RFTL_6; break;
+		case 8 :	ufcon |= UFCON_RFTL_8; break;
+	}
+	switch (TX_FIFO_LEVEL) {
+		case 0 :	ufcon |= UFCON_TFTL_0; break;
+		case 2 :	ufcon |= UFCON_TFTL_2; break;
+		case 4 :	ufcon |= UFCON_TFTL_4; break;
+		case 6 :	ufcon |= UFCON_TFTL_6; break;
+	}
+	outb(ufcon, S3C3410X_UART_BASE+S3C3410X_UFCON);
+}
+
+static inline int serial_paranoia_check(struct s3c3410_serial *info,
+					dev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%d, %d) in %s\n";
+	static const char *badinfo =
+		"Warning: null s3c3410_serial struct for (%d, %d) in %s\n";
+
+	if  (!info) {
+		printk(badinfo, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+	if  (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+#endif
+    return 0;
+}
+
+/* Sets or clears DTR on the requested line */
+static inline void set_dtr(struct s3c3410_serial *info, int set)
+{
+	/* the SMDK40100 board does not have hw flow control */
+}
+
+/* Sets or clears RTS on the requested line */
+/* Note: rts is only directly controllable if hw flow
+ * control is not enabled */
+static inline void set_rts(struct s3c3410_serial *info, int set)
+{
+	/* the SMDK40100 board does not have hw flow control */
+}
+
+/* Reads value of serial status signals */
+static unsigned int get_status(struct s3c3410_serial *info)
+{
+	/* the SMDK40100 board does not have hw flow control */
+	return 0;
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+    struct s3c3410_serial *info = (struct s3c3410_serial *) tty->driver_data;
+    unsigned long flags = 0;
+
+    if	(serial_paranoia_check(info, tty->device, "rs_stop"))
+    	return;
+
+    save_flags(flags);
+    cli();
+    tx_stop();
+    rx_stop();
+    restore_flags(flags);
+}
+
+static void rs_put_char(struct s3c3410_serial *info, char ch)
+{
+    unsigned long flags = 0;
+
+    save_flags(flags);
+    cli();
+    xmit_char(info, ch);
+    restore_flags(flags);
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+    struct s3c3410_serial *info = (struct s3c3410_serial *) tty->driver_data;
+    unsigned long flags = 0;
+
+    if  (serial_paranoia_check(info, tty->device, "rs_start"))
+	return;
+
+    save_flags(flags);
+    cli();
+    rx_start(info->use_ints);
+    tx_start(info->use_ints);
+    restore_flags(flags);
+}
+
+/* Drop into either the boot monitor or kadb upon receiving a break
+ * from keyboard/console input.
+ */
+static void batten_down_hatches(void)
+{
+#if 0
+	/* If we are doing kadb, we call the debugger
+	 * else we just drop into the boot monitor.
+	 * Note that we must flush the user windows
+	 * first before giving up control.
+	 */
+	if ((((unsigned long) linux_dbvec) >= DEBUG_FIRSTVADDR) &&
+		(((unsigned long) linux_dbvec) <= DEBUG_LASTVADDR))
+		sp_enter_debugger();
+	else
+		panic("s3c3410_serial: batten_down_hatches");
+	return;
+#endif
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ *
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assembly code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+ 
+static _INLINE_ void rs_sched_event(struct s3c3410_serial *info, int event)
+{
+	info->event |= 1 << event;
+	queue_task_irq_off(&info->tqueue, &tq_s3c3410_serial);
+	mark_bh(SERIAL_BH);
+}
+
+/*  
+ *	This is the serial driver's generic interrupt routine
+ */ 
+static void rs_interruptTx(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int count, status;
+	struct s3c3410_serial *info = &s3c3410_info;
+
+	if  (info->x_char) {
+		tx_delay();
+		outb(info->x_char, S3C3410X_UART_BASE+S3C3410X_UTXH_B);
+		info->x_char = 0;
+		return;
+	}
+
+	if  ((info->xmit_cnt <= 0) || info->tty->stopped || info->tty->hw_stopped ) {
+		tx_stop();
+		return;
+	}
+
+	for (count = TX_FIFO_DEPTH; count > 0; --count) {
+		status = inb(S3C3410X_UART_BASE+S3C3410X_UFSTAT);
+		if (status & UFSTAT_TFF) {
+			handle_status (info, UFSTAT_TFF);
+			break;
+		} else {
+			tx_delay();
+			outb(info->xmit_buf[info->xmit_tail++], 
+				S3C3410X_UART_BASE+S3C3410X_UTXH_B);
+			info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+			if (--info->xmit_cnt <= 0) 
+				break;
+		}
+	}
+
+	if (info->xmit_cnt < WAKEUP_CHARS)
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+	if (info->xmit_cnt <= 0)
+		tx_stop();
+	return;
+}
+
+#define USTAT_ERROR  (USTAT_OE | USTAT_PE | USTAT_FE | USTAT_BD)
+#define UFSTAT_ERROR (UFSTAT_RFF)
+
+static void rs_interruptRx(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct s3c3410_serial *info = &s3c3410_info;
+	struct tty_struct *tty = info->tty;
+	unsigned int count;
+	volatile u_int8_t status, fifo_status;
+
+	if (!info || !tty || (!(info->flags & S_INITIALIZED)))
+		return;
+
+	if ((tty->flip.count + RX_FIFO_DEPTH) >= TTY_FLIPBUF_SIZE)
+		queue_task_irq_off(&tty->flip.tqueue, &tq_timer);
+
+	count = RX_FIFO_DEPTH;
+	do {
+		status = inb(S3C3410X_UART_BASE+S3C3410X_USTAT);
+		if (!(status & USTAT_RFDR))
+			break;
+
+		/* check all error flags and accept data if valid */
+		fifo_status = inb(S3C3410X_UART_BASE+S3C3410X_UFSTAT);
+		if (!(status & USTAT_ERROR) && !(fifo_status & UFSTAT_ERROR))
+			*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		else {
+			if (fifo_status & UFSTAT_RFF) {
+				*tty->flip.flag_buf_ptr = TTY_NORMAL;
+				handle_status (info, UFSTAT_RFF);
+			}
+			if (status & USTAT_OE) {
+				*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+				handle_status (info, USTAT_OE);
+			}
+			if 	(status & USTAT_BD) {
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+				handle_status (info, USTAT_BD);
+			}
+			if	(status & USTAT_PE) {
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+				handle_status (info, USTAT_PE);
+			}
+			if 	(status & USTAT_FE) {
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+				handle_status (info, USTAT_FE);
+			}
+		}
+		*tty->flip.char_buf_ptr++ = 
+			inb(S3C3410X_UART_BASE+S3C3410X_URXH_B);
+		tty->flip.flag_buf_ptr++;
+		tty->flip.count++;
+	} while ((--count > 0) && !(status & USTAT_ERROR) && 
+		!(fifo_status & UFSTAT_ERROR) );
+
+//     if (fifo_status & (U_RFOV | U_E_RxTO))
+// 		handle_status (info, (U_RFOV | U_E_RxTO));
+	
+	queue_task_irq_off(&tty->flip.tqueue, &tq_timer);	
+}
+
+static void rs_interruptErr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	rs_interruptRx(irq, dev_id, regs);
+}
+
+static _INLINE_ void handle_status ( struct s3c3410_serial *info, unsigned int status )
+{
+//     if (status & U_TFFUL) {
+// 		return;				/* FIXME - do something */
+// 	}
+//     if (status & U_RFFUL) {
+// 		info->usart->cr |= U_SBR;	
+// 	}
+//     if (status & U_BSD) {
+// 		batten_down_hatches();
+// 	}
+//     info->usart->csr |= status;
+}
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_s3c3410_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct s3c3410_serial *info = (struct s3c3410_serial *) private_;
+	struct tty_struct *tty;
+
+	tty = info->tty;
+	if (!tty ) return;
+
+	if  (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if  ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) 
+		(tty->ldisc.write_wakeup) (tty);
+		wake_up_interruptible(&tty->write_wait);
+	}
+}
+
+/*
+ * This routine is called from the scheduler tqueue when the interrupt
+ * routine has signalled that a hangup has occurred.  The path of
+ * hangup processing is:
+ *
+ * 	serial interrupt routine -> (scheduler tqueue) ->
+ * 	do_serial_hangup() -> tty->hangup() -> rs_hangup()
+ *
+ */
+static void do_serial_hangup(void *private_)
+{
+	struct s3c3410_serial *info = (struct s3c3410_serial *) private_;
+	struct tty_struct *tty;
+	
+	tty = info->tty;
+	if (!tty)	return;
+	tty_hangup(tty);
+}
+
+static u_int16_t calcCD(u_int32_t br)
+{
+	/* effectively add 1/2 LSB before dividing */
+	u_int32_t divisor = (CONFIG_ARM_CLK >> 3) / br - 1;
+	return (divisor >> 1);
+}
+
+static _INLINE_ void uart_speed(struct s3c3410_serial *info, unsigned int cflag)
+{
+	unsigned baud = info->baud;
+	u_int16_t divisor = calcCD(baud);
+// ###	outw(divisor, S3C3410X_UART_BASE+S3C3410X_UBRDIV);
+}
+
+static int startup(struct s3c3410_serial *info)
+{
+	unsigned long flags;
+
+	if (info->flags & S_INITIALIZED)
+		return 0;
+
+	if (!info->xmit_buf) {
+		info->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL);
+		if (!info->xmit_buf) return -ENOMEM;
+	}
+
+	save_flags(flags);    cli();
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttyS%d (irq %d)...\n", info->line, info->irq);
+#endif
+
+	/*
+	 * Clear the FIFO buffers and disable them
+	 * (they will be reenabled in change_speed())
+	 */
+	fifo_reset();
+
+	/*
+	 * Now, initialize the UART 
+	 */ 
+	if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+	
+	/*
+	 * and set the speed of the serial port
+	 */
+	change_speed(info);
+	
+	info->flags |= S_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct s3c3410_serial *info)
+{
+	unsigned long flags;
+	
+	tx_stop();
+	rx_stop();	/* All off! */
+	if (!(info->flags & S_INITIALIZED))
+		return;
+	
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Shutting down serial port %d (irq %d)....\n", info->line,
+			info->irq);
+#endif
+	
+	save_flags(flags);    cli();		/* Disable interrupts */
+	
+	if (info->xmit_buf) {
+		free_page((unsigned long) info->xmit_buf);
+		info->xmit_buf = 0;
+	}
+
+	if  (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~S_INITIALIZED;
+	restore_flags(flags);
+}
+
+static s3c_baud_table_t baud_table[] = {
+	{      0, B0 },
+	{     50, B50 },
+	{     75, B75 },
+	{    110, B110 },
+	{    134, B134 },
+	{    150, B150 },
+	{    200, B200 },
+	{    300, B300 },
+	{    600, B600 },
+	{   1200, B1200 },
+	{   1800, B1800 },
+	{   2400, B2400 },
+	{   4800, B4800 },
+	{   9600, B9600 },
+	{  19200, B19200 },
+	{  38400, B38400 },
+	{  57600, B57600 },
+	{ 115200, B115200 },
+	{ 230400, B230400 },
+	{      -1, -1 }
+};
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void change_speed(struct s3c3410_serial *info)
+{
+	unsigned cflag;
+	int      table_index;
+	u_int8_t ulcon, ucon;
+	
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+	
+	tx_stop();
+	rx_stop();
+	
+	/* UART baudrate setup */
+	table_index = cflag & CBAUD;
+	if (table_index & CBAUDEX)	{
+		table_index &= ~CBAUDEX; 	 /* remove CBAUDEX bit */
+		table_index += CBAUD & ~CBAUDEX; /* add high rate offset */
+	}
+	info->baud = baud_table[table_index].rate;
+	uart_speed(info, cflag);
+
+	/* UART line control register setup */
+	ulcon = 0x00;
+	switch  (cflag & CSIZE) {
+		case CS5: ulcon |= ULCON_WL_5; break;
+		case CS6: ulcon |= ULCON_WL_6; break;
+		case CS7: ulcon |= ULCON_WL_7; break;
+		case CS8: ulcon |= ULCON_WL_8; break;
+	}
+	if (cflag & PARENB)
+		ulcon |= (cflag & PARODD) ? ULCON_PMD_ODD : ULCON_PMD_EVEN;
+	if (cflag & CSTOPB)
+		ulcon |= ULCON_SB;
+	outb(ulcon, S3C3410X_UART_BASE+S3C3410X_ULCON);
+
+	/* UART control register setup */
+	ucon = 0;
+	ucon |= UCON_RM_IRQ_POLL; /* receive mode: IRQ or polling */
+	ucon |= UCON_TM_IRQ_POLL; /* transmit mode: IRQ or polling */
+	ucon |= UCON_RSIE;        /* Rx status interrupt enable */
+	ucon |= UCON_RXTOEL;      /* Rx timeout enable (5 bits) */
+	outb(ucon, S3C3410X_UART_BASE+S3C3410X_UCON);
+	
+	tx_start(info->use_ints);
+	rx_start(info->use_ints);
+
+	return;
+}
+
+/*
+ *	Wait for transmitter & holding register to empty
+ */
+static inline void wait_for_xmitr(void)
+{
+	volatile unsigned int status, tmout = 100000;
+	do {
+		status = inb(S3C3410X_UART_BASE+S3C3410X_USTAT);
+		if (--tmout == 0)
+			break;
+	} while((status & (USTAT_TFE | USTAT_TSE)) != (USTAT_TFE | USTAT_TSE));
+}
+
+static _INLINE_ void xmit_char(struct s3c3410_serial *info, char ch)
+{
+	wait_for_xmitr();	
+	tx_delay();
+	outb(ch, S3C3410X_UART_BASE+S3C3410X_UTXH_B);
+}
+
+static void rs_set_ldisc(struct tty_struct *tty)
+{
+	struct s3c3410_serial *info = (struct s3c3410_serial *) tty->driver_data;
+
+	if  (serial_paranoia_check(info, tty->device, "rs_set_ldisc"))
+		return;
+
+	info->is_cons = (tty->termios->c_line == N_TTY);
+
+	printk("ttyS%d console mode %s\n", info->line, info->is_cons ? "on" : "off");
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct s3c3410_serial *info = (struct s3c3410_serial *) tty->driver_data;
+	unsigned long flags;
+
+	if  (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
+		return;
+
+	if  (!info->use_ints) {
+		for (;;) {
+		if  (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !info->xmit_buf) 
+			return;
+		save_flags(flags);	    cli();
+		tx_start(info->use_ints);
+		xmit_char(info, info->xmit_buf[info->xmit_tail++]);
+		info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+		info->xmit_cnt--;
+		}
+	} else {
+		if  (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !info->xmit_buf) 
+			return;
+		save_flags(flags);	cli();
+		tx_start(info->use_ints);
+		xmit_char(info, info->xmit_buf[info->xmit_tail++]);
+		info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+		info->xmit_cnt--;
+	}
+	restore_flags(flags);
+}
+
+static int rs_write(struct tty_struct *tty, int from_user,
+					const unsigned char *buf, int count)
+{
+	int c, total = 0;
+	struct s3c3410_serial *info = (struct s3c3410_serial *) tty->driver_data;
+	unsigned long flags;
+
+	if  (serial_paranoia_check(info, tty->device, "rs_write"))
+		return 0;
+
+	if  (!tty || !info->xmit_buf || !tmp_buf)
+		return 0;
+
+	save_flags(flags);
+	if (from_user) {
+		down(&tmp_buf_sem);
+		cli();
+		while (1) {
+			c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				SERIAL_XMIT_SIZE - info->xmit_head));
+			if  (c <= 0)
+				break;
+			
+			memcpy(info->xmit_buf + info->xmit_head, buf, c);
+			info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1);
+			info->xmit_cnt += c;
+			restore_flags(flags);
+			buf += c;
+			count -= c;
+			total += c;
+		}
+		restore_flags(flags);
+		up(&tmp_buf_sem);
+
+	} else {
+		cli();
+		while (1) {
+			c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+					SERIAL_XMIT_SIZE - info->xmit_head));
+			if  (c <= 0)
+				break;
+			memcpy(info->xmit_buf + info->xmit_head, buf, c);
+			info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1);
+			info->xmit_cnt += c;
+			buf += c;
+			count -= c;
+			total += c;
+		}
+		restore_flags(flags);
+	}
+
+	if  (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
+		if   (!info->use_ints) {
+			while (info->xmit_cnt) {
+				/* Send char */
+				xmit_char(info, info->xmit_buf[info->xmit_tail++]);
+				info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+				info->xmit_cnt--;
+			}
+		} 
+		else {
+			tx_start(info->use_ints);
+		}
+	} 
+	restore_flags(flags);
+	
+	return total;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct s3c3410_serial *info = (struct s3c3410_serial *) tty->driver_data;
+	int ret;
+
+	if  (serial_paranoia_check(info, tty->device, "rs_write_room"))
+		return 0;
+	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
+	if  (ret < 0)
+		ret = 0;
+	return ret;
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct s3c3410_serial *info = (struct s3c3410_serial *) tty->driver_data;
+
+	if  (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+		return 0;
+	return info->xmit_cnt;
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	unsigned long flags;
+	struct s3c3410_serial *info = (struct s3c3410_serial *) tty->driver_data;
+
+	if  (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+		return;
+	save_flags(flags);    cli();
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+	restore_flags(flags);
+	wake_up_interruptible(&tty->write_wait);
+	if  ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) 
+		(tty->ldisc.write_wakeup) (tty);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ *
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct *tty)
+{
+	struct s3c3410_serial *info = (struct s3c3410_serial *) tty->driver_data;
+	unsigned int flags;
+
+#ifdef SERIAL_DEBUG_THROTTLE
+	char buf[64];
+
+	printk("throttle %s: %d\n", tty_name(tty, buf),
+			tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+		return;
+
+	if (I_IXOFF(tty))
+		info->x_char = STOP_CHAR(tty);
+
+	/* Turn off RTS line (do this atomically) */
+	if (tty->termios->c_cflag & CRTSCTS) {
+			save_flags(flags);
+			cli();
+			set_rts (info, 0);
+			restore_flags(flags);
+	}
+}
+
+static void rs_unthrottle(struct tty_struct *tty)
+{
+	struct s3c3410_serial *info = (struct s3c3410_serial *) tty->driver_data;
+	unsigned int flags;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char buf[64];
+
+	printk("unthrottle %s: %d\n", tty_name(tty, buf),
+		tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+		return;
+
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+		info->x_char = 0;
+		else
+		info->x_char = START_CHAR(tty);
+	}
+
+	/* Assert RTS line (do this atomically) */
+	if (tty->termios->c_cflag & CRTSCTS) {
+		save_flags(flags);
+		cli();
+		set_rts (info, 1);
+		restore_flags(flags);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int get_serial_info(struct s3c3410_serial *info,
+			   struct serial_struct *retinfo)
+{
+	struct serial_struct tmp;
+
+	if  (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = info->type;
+	tmp.line = info->line;
+	tmp.irq = info->irq;
+	tmp.port = info->port;
+	tmp.flags = info->flags;
+	tmp.baud_base = info->baud_base;
+	tmp.close_delay = info->close_delay;
+	tmp.closing_wait = info->closing_wait;
+	tmp.custom_divisor = info->custom_divisor;
+	memcpy_tofs(retinfo, &tmp, sizeof(*retinfo));
+	return 0;
+}
+
+static int set_serial_info(struct s3c3410_serial *info,
+			   struct serial_struct *new_info)
+{
+	struct serial_struct new_serial;
+	struct s3c3410_serial old_info;
+	int retval = 0;
+
+	if  (!new_info)
+		return -EFAULT;
+	memcpy_fromfs(&new_serial, new_info, sizeof(new_serial));
+	old_info = *info;
+
+	if  (!suser()) {
+		if	((new_serial.baud_base != info->baud_base) 	||
+			(new_serial.type != info->type) 		||
+			(new_serial.close_delay != info->close_delay) 	||
+			((new_serial.flags & ~S_USR_MASK) 		!=
+			(info->flags & ~S_USR_MASK))) return -EPERM;
+		info->flags = ((info->flags & ~S_USR_MASK) |
+			(new_serial.flags & S_USR_MASK));
+		info->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	if  (info->count > 1)
+		return -EBUSY;
+
+		/*
+		* OK, past this point, all the error checking has been done.
+		* At this point, we start making changes.....
+		*/
+
+	info->baud_base = new_serial.baud_base;
+	info->flags = ((info->flags & ~S_FLAGS) | (new_serial.flags & S_FLAGS));
+	info->type = new_serial.type;
+	info->close_delay = new_serial.close_delay;
+	info->closing_wait = new_serial.closing_wait;
+
+check_and_exit:
+	retval = startup(info);
+	return retval;
+}
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space.
+ */
+static int get_lsr_info(struct s3c3410_serial *info, unsigned int *value)
+{
+	unsigned char status;
+
+	cli();
+//    status = (info->usart->csr & U_CTS) ? 1 : 0;
+	status = 0x00;
+	sti();
+	put_user(status, value);
+	return 0;
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void send_break(struct s3c3410_serial *info, int duration)
+{
+	u_int8_t ucon;
+	
+	current->state = TASK_INTERRUPTIBLE;
+	cli();
+	
+	ucon = inb(S3C3410X_UART_BASE+S3C3410X_UCON);
+	ucon |= UCON_SBS;
+	outb(ucon, S3C3410X_UART_BASE+S3C3410X_UCON);
+	
+	schedule_timeout(info->close_delay);
+	
+	ucon &= ~UCON_SBS;
+	outb(ucon, S3C3410X_UART_BASE+S3C3410X_UCON);
+	
+	sti();
+}
+
+static int rs_ioctl(struct tty_struct *tty, struct file *file,
+					unsigned int cmd, unsigned long arg)
+{
+	int error;
+	struct s3c3410_serial *info = (struct s3c3410_serial *) tty->driver_data;
+	unsigned int val;
+	int retval;
+
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+		(cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) &&
+		(cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+			return -EIO;
+	}
+
+	switch (cmd) {
+	case TCSBRK:				/* SVID version: non-zero arg --> no break */
+		retval = tty_check_change(tty);
+		if (retval)
+			return retval;
+		tty_wait_until_sent(tty, 0);
+		if (!arg)
+			send_break(info, HZ / 4);	/* 1/4 second */
+		return 0;
+	case TCSBRKP:				/* support for POSIX tcsendbreak() */
+		retval = tty_check_change(tty);
+		if (retval)
+			return retval;
+		tty_wait_until_sent(tty, 0);
+		send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
+		return 0;
+	case TIOCGSOFTCAR:
+		error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
+
+		if (error)
+			return error;
+		put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
+		return 0;
+	case TIOCSSOFTCAR:
+		arg = get_user(arg, (unsigned long *) arg);
+		tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
+		return 0;
+	case TIOCGSERIAL:
+		error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(struct serial_struct));
+		if (error)
+			return error;
+		return get_serial_info(info, (struct serial_struct *) arg);
+	case TIOCSSERIAL:
+		return set_serial_info(info, (struct serial_struct *) arg);
+	case TIOCSERGETLSR:		/* Get line status register */
+		error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(unsigned int));
+		if (error)
+			return error;
+		else
+			return get_lsr_info(info, (unsigned int *) arg);
+
+	case TIOCSERGSTRUCT:
+		error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(struct s3c3410_serial));
+		if (error)
+			return error;
+		memcpy_tofs((struct s3c3410_serial *) arg, info,
+			sizeof(struct s3c3410_serial));
+		return 0;
+
+
+	case TIOCMGET:	/* get all modem bits */
+		if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(unsigned int))))
+			return(error);
+		val = get_status(info);
+		put_user(val, (unsigned int *) arg);
+		break;
+
+	case TIOCMBIS:	/* modem bits set */
+		if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+					 sizeof(unsigned int))))
+			return(error);
+		
+		get_user(val, (unsigned int *) arg);
+		
+		if (val & TIOCM_RTS) set_rts(info, 1);
+		if (val & TIOCM_DTR) set_dtr(info, 1);
+		break;
+
+	case TIOCMBIC:	/* modem bits clear */
+		if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+					 sizeof(unsigned int))))
+			return(error);
+		get_user(val, (unsigned int *) arg);
+			
+		if (val & TIOCM_RTS) set_rts(info, 0);
+		if (val & TIOCM_DTR) set_dtr(info, 0);
+		break;
+
+	case TIOCMSET:	/* set all modem bits */
+		if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+					 sizeof(unsigned int))))
+			return(error);
+		get_user(val, (unsigned int *) arg);
+
+		set_rts (info, ((val & TIOCM_RTS) ? 1 : 0) );
+		set_dtr (info, ((val & TIOCM_DTR) ? 1 : 0) );
+		break;
+
+	case TCSETS:	
+	  /*
+	   * take care if the speed change, leave rest to termios by falling through
+	   */
+	  handle_termios_tcsets((struct termios *)arg, info);
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static void handle_termios_tcsets(  struct termios *ptermios, 
+				    struct s3c3410_serial *pinfo)
+{
+	if  (pinfo->tty->termios->c_cflag != ptermios->c_cflag) {
+		pinfo->tty->termios->c_cflag = ptermios->c_cflag;
+	}
+	change_speed(pinfo);
+}
+	  
+static void rs_set_termios( struct tty_struct *tty,
+			    struct termios *old_termios)
+{
+	struct s3c3410_serial *info = (struct s3c3410_serial *) tty->driver_data;
+
+	if (tty->termios->c_cflag == old_termios->c_cflag)
+		return;
+
+	change_speed(info);
+
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) &&
+		!(tty->termios->c_cflag & CRTSCTS)) 
+	{
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ *
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * S structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file *filp)
+{
+	struct s3c3410_serial *info = (struct s3c3410_serial *) tty->driver_data;
+	unsigned long flags;
+	
+	if  (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+		return;
+	
+	save_flags(flags);  cli();
+	
+	if  (tty_hung_up_p(filp)) {
+		restore_flags(flags);
+		return;
+	}
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_close ttyS%d, count = %d\n", info->line, info->count);
+#endif
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  Info->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+			   "info->count is %d\n", info->count);
+		info->count = 1;
+	}
+	if (--info->count < 0) {
+		printk("rs_close: bad serial port count for ttyS%d: %d\n",
+			   info->line, info->count);
+		info->count = 0;
+	}
+	if (info->count) {
+		restore_flags(flags);
+		return;
+	}
+	// closing port so disable interrupts
+	set_ints_mode(info, 0);
+
+	info->flags |= S_CLOSING;
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & S_NORMAL_ACTIVE)
+		info->normal_termios = *tty->termios;
+	if (info->flags & S_CALLOUT_ACTIVE)
+		info->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != S_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (tty->ldisc.num != tty_ldiscs[N_TTY].num) {
+		if (tty->ldisc.close)
+			(tty->ldisc.close) (tty);
+		tty->ldisc = tty_ldiscs[N_TTY];
+		tty->termios->c_line = N_TTY;
+		if (tty->ldisc.open)
+			(tty->ldisc.open) (tty);
+	}
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+/*			current->timeout = jiffies + info->close_delay;  */
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(S_NORMAL_ACTIVE | S_CALLOUT_ACTIVE | S_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	restore_flags(flags);
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void rs_hangup(struct tty_struct *tty)
+{
+	struct s3c3410_serial *info = (struct s3c3410_serial *) tty->driver_data;
+	
+	if	(serial_paranoia_check(info, tty->device, "rs_hangup"))
+		return;
+	
+	rs_flush_buffer(tty);
+	shutdown(info);
+	info->event = 0;
+	info->count = 0;
+	info->flags &= ~(S_NORMAL_ACTIVE | S_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file *filp,
+			   struct s3c3410_serial *info)
+{
+	unsigned long flags;
+	DECLARE_WAITQUEUE(wait, current);
+	int retval;
+	int do_clocal = 0;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (info->flags & S_CLOSING) {
+		interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		if (info->flags & S_HUP_NOTIFY)
+			return -EAGAIN;
+		else
+			return -ERESTARTSYS;
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & S_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+			(info->flags & S_SESSION_LOCKOUT) &&
+			(info->session != current->session)) return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+			(info->flags & S_PGRP_LOCKOUT) &&
+			(info->pgrp != current->pgrp)) return -EBUSY;
+		info->flags |= S_CALLOUT_ACTIVE;
+		return 0;
+	}
+
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & S_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= S_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & S_CALLOUT_ACTIVE) {
+		if (info->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, info->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready before block: ttyS%d, count = %d\n",
+		   info->line, info->count);
+#endif
+	info->count--;
+	info->blocked_open++;
+	while (1) {
+		save_flags(flags);
+		cli();
+		if (!(info->flags & S_CALLOUT_ACTIVE))
+			set_dtr(info, 1);
+		restore_flags(flags);
+		current->state = TASK_INTERRUPTIBLE;
+		if (tty_hung_up_p(filp) || !(info->flags & S_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & S_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & S_CALLOUT_ACTIVE) &&
+			!(info->flags & S_CLOSING) && do_clocal)
+			break;
+		if (signal_pending(current)) {
+/*		if (current->signal & ~current->blocked) {  */
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef SERIAL_DEBUG_OPEN
+		printk("block_til_ready blocking: ttyS%d, count = %d\n",
+			   info->line, info->count);
+#endif
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&info->open_wait, &wait);
+	if (!tty_hung_up_p(filp))
+		info->count++;
+	info->blocked_open--;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready after blocking: ttyS%d, count = %d\n",
+		   info->line, info->count);
+#endif
+	if (retval)
+		return retval;
+	info->flags |= S_NORMAL_ACTIVE;
+	return 0;
+}
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its S structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+int rs_open(struct tty_struct *tty, struct file *filp)
+{
+	struct s3c3410_serial *info = &s3c3410_info;
+	int retval, line;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+
+	/* check if line is sane */
+	if (line < 0 || line >= USART_CNT)
+		return -ENODEV;
+
+	if (serial_paranoia_check(info, tty->device, "rs_open"))
+		return -ENODEV;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+		info->count);
+#endif
+	info->count++;
+	tty->driver_data = info;
+	info->tty = tty;
+
+	/*
+	 * Start up serial port
+	 */
+	set_ints_mode(info, 1);
+	
+	retval = startup(info);
+	if (retval)
+		return retval;
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("rs_open returning after block_til_ready with %d\n",
+			   retval);
+#endif
+		return retval;
+	}
+
+	if ((info->count == 1) && (info->flags & S_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->normal_termios;
+		else
+			*tty->termios = info->callout_termios;
+		change_speed(info);
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open ttyS%d successful...\n", info->line);
+#endif
+	return 0;
+}
+
+static struct irqaction irq_uartTx =
+	{ rs_interruptTx,  0, 0, "S3C3410_UART_TX",  NULL, NULL };
+static struct irqaction irq_uartRx =
+	{ rs_interruptRx,  0, 0, "S3C3410_UART_RX",  NULL, NULL };
+static struct irqaction irq_uartErr =
+	{ rs_interruptErr, 0, 0, "S3C3410_UART_ERR", NULL, NULL };
+	
+extern int setup_arm_irq(int, struct irqaction *);
+
+static void interrupts_init(void)
+{
+	setup_arm_irq(S3C3410X_INTERRUPT_UTX,  &irq_uartTx);
+	setup_arm_irq(S3C3410X_INTERRUPT_URX,  &irq_uartRx);
+	setup_arm_irq(S3C3410X_INTERRUPT_UERR, &irq_uartErr);
+}
+
+static void show_serial_version(void)
+{
+	printk("Samsung S3C3410X UART driver version 0.1 <thomas.eschenbacher@sympat.de>\n");
+}
+
+/* rs_init inits the driver */
+static int __init rs_s3c3410_init(void)
+{
+	int flags, i;
+	struct s3c3410_serial *info;
+	
+	/* Setup base handler, and timer table. */
+	init_bh(SERIAL_BH, do_serial_bh);
+	
+	show_serial_version();
+	
+	/* Initialize the tty_driver structure */
+	
+	/* set the tty_struct pointers to NULL to let the layer */
+	/* above allocate the structs. */
+	for (i=0; i < USART_CNT; i++)
+		serial_table[i] = NULL;
+	
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+	serial_driver.name = "ttyS";
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64;
+	serial_driver.num = 1;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+	serial_driver.init_termios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver.init_termios.c_cflag |= B115200;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = rs_open;
+	serial_driver.close = rs_close;
+	serial_driver.write = rs_write;
+	serial_driver.flush_chars = rs_flush_chars;
+	serial_driver.write_room = rs_write_room;
+	serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	serial_driver.flush_buffer = rs_flush_buffer;
+	serial_driver.ioctl = rs_ioctl;
+	serial_driver.throttle = rs_throttle;
+	serial_driver.unthrottle = rs_unthrottle;
+	serial_driver.set_termios = rs_set_termios;
+	serial_driver.stop = rs_stop;
+	serial_driver.start = rs_start;
+	serial_driver.hangup = rs_hangup;
+	serial_driver.set_ldisc = rs_set_ldisc;
+	
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+	callout_driver.name = "cua";
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+	
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register serial driver\n");
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+	
+	save_flags(flags);
+	cli();
+	for (i = 0; i < USART_CNT; i++) {
+		info = &s3c3410_info;
+		info->magic = SERIAL_MAGIC;
+		info->tty = 0;
+		info->irqmask = S3C3410X_INTERRUPT_UTX || 
+		                S3C3410X_INTERRUPT_URX || 
+		                S3C3410X_INTERRUPT_UERR;
+		info->irq = S3C3410X_INTERRUPT_UTX;
+		info->port = (i) ? 1 : 2;
+		info->line = i;
+
+#if defined(CONFIG_CONSOLE_NULL)
+		info->is_cons = 0;
+#else
+		if (i == console_number)
+			info->is_cons = 1;
+#endif
+		set_ints_mode(info, 0);
+		/* info->custom_divisor = 16; */ /* unused? */
+		info->custom_divisor = 0;
+		info->close_delay = 50;
+		info->closing_wait = 3000;
+		info->cts_state = 1;
+		info->x_char = 0;
+		info->event = 0;
+		info->count = 0;
+		info->blocked_open = 0;
+		info->tqueue.routine = do_softint;
+		info->tqueue.data = info;
+		info->tqueue_hangup.routine = do_serial_hangup;
+		info->tqueue_hangup.data = info;
+		info->callout_termios = callout_driver.init_termios;
+		info->normal_termios = serial_driver.init_termios;
+		
+		init_waitqueue_head(&info->open_wait);
+		init_waitqueue_head(&info->close_wait);
+		
+		printk("%s%d (irq = %d)", serial_driver.name, info->line,
+			   info->irq);
+		printk(" is a builtin Samsung S3C3410 UART\n");
+	}
+	
+	interrupts_init();
+	
+	restore_flags(flags);
+	return 0;
+}
+
+module_init(rs_s3c3410_init);
+
+/*
+ * ------------------------------------------------------------
+ * Serial console driver
+ * ------------------------------------------------------------
+ */
+
+#ifdef CONFIG_SERIAL_S3C3410_CONSOLE
+
+static kdev_t s3c3410_console_device(struct console *);
+static int    s3c3410_console_setup(struct console *, char *);
+static void   s3c3410_console_write (struct console *, const char *, unsigned int );
+static int    s3c3410_console_initialized = 0;
+
+static struct console s3c3410_driver = {
+	name:		"ttyS",
+	write:		s3c3410_console_write,
+	device:		s3c3410_console_device,
+	setup:		s3c3410_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+/* static void init_console(struct s3c3410_serial *info) */
+static int s3c3410_console_setup(struct console *c, char *p)
+{
+	struct s3c3410_serial *info = &s3c3410_info;
+	
+	memset(info, 0, sizeof(struct s3c3410_serial));
+	info->use_ints = 0;
+	info->cts_state = 1;
+	info->is_cons = 1;
+//	info->usart->cr = 0; 
+//	info->usart->cr = (U_IRQ_TMODE | U_IRQ_RMODE | U_WL8);
+	fifo_init();
+	info->baud = B115200;
+	
+//     info->usart->brgr = calcCD(info->baud);
+//     info->usart->ier = 0;
+	
+	s3c3410_console_initialized = 1;
+	return 0;
+}
+
+static kdev_t s3c3410_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static void s3c3410_console_write (struct console *co, const char *str,
+			   unsigned int count)
+{
+#if defined(CONFIG_CONSOLE_NULL)
+	return;
+#else
+	static struct s3c3410_serial *info = &s3c3410_info;
+	
+	if (!s3c3410_console_initialized)
+		printk ("WARNING: Console used unintialized\n");
+	
+	while (count--) {
+		if  (*str == '\n')
+			rs_put_char(info,'\r');
+        	rs_put_char(info, *str++ );
+	}
+#endif
+}
+
+void __init s3c3410_console_init(void)
+{
+	register_console ( &s3c3410_driver );
+}
+
+#endif /* CONFIG_SERIAL_S3C3410_CONSOLE */
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -urN linux-2.4.29/drivers/char/serial_s3c3410.h linux-2.4.29-uc1/drivers/char/serial_s3c3410.h
--- linux-2.4.29/drivers/char/serial_s3c3410.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_s3c3410.h	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,142 @@
+/*
+ * drivers/char/serial_s3c3410.h
+ * 
+ * Serial port driver for the Samsung S3C3410X builtin UART
+ *
+ * Copyright (c) 2003 sympat GmbH
+ * 	by Thomas Eschenbacher <thomas.eschenbacher@sympat.de>
+ *
+ * Based on: drivers/cahr/serial_s3c4530.h
+ * Copyright (c) 2001-2003  Arcturus Networks Inc.
+ *                          by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * Based on: drivers/char/trioserial.h
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *               1998-2003  D. Jeff Dionne <jeff@uClinux.org>
+ * Copyright (c) 1998  The Silver Hammer Group, Ltd.
+ *
+ * Based on: drivers/char/68328serial.h
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _S3C3410_SERIAL_H
+#define _S3C3410_SERIAL_H
+
+#include <linux/config.h>
+#include <asm/page.h>
+#include <asm/arch/hardware.h>
+
+/*
+ * For the close wait times, 0 means wait forever for serial port to
+ * flush its output.  65535 means don't wait at all.
+ */
+#define S_CLOSING_WAIT_INF	0
+#define S_CLOSING_WAIT_NONE	65535
+
+/*
+ * Definitions for S_struct (and serial_struct) flags field
+ */
+#define S_HUP_NOTIFY 	  0x0001 /* Notify getty on hangups and closes 
+				    on the callout port */
+#define S_FOURPORT  	  0x0002 /* Set OU1, OUT2 per AST Fourport settings */
+#define S_SAK		  0x0004 /* Secure Attention Key (Orange book) */
+#define S_SPLIT_TERMIOS   0x0008 /* Separate termios for dialin/callout */
+
+#define S_SPD_MASK	  0x0030
+#define S_SPD_HI	  0x0010 /* Use 56000 instead of 38400 bps */
+
+#define S_SPD_VHI	  0x0020 /* Use 115200 instead of 38400 bps */
+#define S_SPD_CUST	  0x0030 /* Use user-specified divisor */
+
+#define S_SKIP_TEST	  0x0040 /* Skip UART test during autoconfiguration */
+#define S_AUTO_IRQ  	  0x0080 /* Do automatic IRQ during autoconfiguration */
+#define S_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
+#define S_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
+#define S_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
+
+#define S_FLAGS		  0x0FFF /* Possible legal S flags */
+#define S_USR_MASK 	  0x0430 /* Legal flags that non-privileged
+				    users can set or reset */
+
+/* Internal flags used only by kernel/chr_drv/serial.c */
+#define S_INITIALIZED		0x80000000 /* Serial port was initialized */
+#define S_CALLOUT_ACTIVE	0x40000000 /* Call out device is active */
+#define S_NORMAL_ACTIVE		0x20000000 /* Normal device is active */
+#define S_BOOT_AUTOCONF		0x10000000 /* Autoconfigure port on bootup */
+#define S_CLOSING		0x08000000 /* Serial port is closing */
+#define S_CTS_FLOW		0x04000000 /* Do CTS flow control */
+#define S_CHECK_CD		0x02000000 /* i.e., CLOCAL */
+
+/* Software state per channel */
+
+/*
+ * This is our internal structure for each serial port's state.
+ * 
+ * Many fields are paralleled by the structure used by the serial_struct
+ * structure.
+ *
+ * For definitions of the flags field, see tty.h
+ */
+
+struct s3c3410_serial {
+	char soft_carrier;  /* Use soft carrier on this channel */
+	char break_abort;   /* Is serial console in, so process brk/abrt */
+	char is_cons;       /* Is this our console. */
+
+	/* We need to know the current clock divisor
+	 * to read the bps rate the chip has currently
+	 * loaded.
+	 */
+	unsigned char clk_divisor;  /* May be 1, 16, 32, or 64 */
+	int 			baud;
+	int			magic;
+	int			baud_base;
+	int			port;
+	int			irq;
+	int			irqmask;
+	int			flags; 		/* defined in tty.h */
+	int			type; 		/* UART type */
+	int			use_ints;
+	int			cts_state;
+	struct tty_struct 	*tty;
+	int			read_status_mask;
+	int			ignore_status_mask;
+	int			timeout;
+	int			xmit_fifo_size;
+	int			rx_fifo_size;
+	int			custom_divisor;
+	int			x_char;	/* xon/xoff character */
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int			count;	    /* # of fd on device */
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+	unsigned char 		*xmit_buf;
+	int			xmit_head;
+	int			xmit_tail;
+	int			xmit_cnt;
+	struct tq_struct	tqueue;
+	struct tq_struct	tqueue_hangup;
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+};
+
+
+/* typedef to correlate a serial speed with its cflags - type handle: */
+typedef struct
+{
+  int rate;
+  int cflag;
+} s3c_baud_table_t;
+
+#define RS_EVENT_WRITE_WAKEUP   0
+#define SERIAL_MAGIC 0x5301
+
+#endif /* !(_S3C3410_SERIAL_H) */
diff -urN linux-2.4.29/drivers/char/serial_s3c44b0x.c linux-2.4.29-uc1/drivers/char/serial_s3c44b0x.c
--- linux-2.4.29/drivers/char/serial_s3c44b0x.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_s3c44b0x.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,1753 @@
+/*
+ * serial_s3c44b0x.c: Serial port driver for the Samsung S3C44B0X builtin UART
+ *
+ * Copyright (c) 2003	sympat GmbH
+ *			by Thomas Eschenbacher <thomas.eschenbacher@sympat.de>
+ *
+ * Copyright (c) 2001	Arcturus Networks Inc. 
+ * 			by Oleksandr Zhadan  <oleks@arcturusnetworks.com>
+ * Copyright (c) 2002	Arcturus Networks Inc. 
+ * 		       	by Michael Leslie    <mleslie@arcturusnetworks.com>
+ *
+ * Based on: drivers/char/trioserial.c
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     D. Jeff Dionne <jeff@arcturusnetworks.com>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ * Based on: drivers/char/68328serial.c
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/arch/irq.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+
+#define queue_task_irq_off queue_task
+#define copy_from_user(a,b,c) memcpy_fromfs(a,b,c)
+#define copy_to_user(a,b,c) memcpy_tofs(a,b,c)
+
+#include <asm/uaccess.h>
+
+#include "serial_s3c44b0x.h"
+
+#if defined(CONFIG_UCBOOTSTRAP)
+#include <asm/uCbootstrap.h>
+extern  char *getbenv (char *a);
+#endif
+
+#define USART_CNT		1
+					/* Receive FIFO trigger level	*/
+#define RX_FIFO_LEVEL		4	/*  0 (off) 4 or 8 or 12 or 16	*/
+					/* Transfer FIFO trigger level	*/
+#define TX_FIFO_LEVEL		0	/*	0 or 4 or 8 or 12	*/
+
+#define TX_FIFO_DEPTH		(5) 	/* maximum transmit FIFO length */
+#define RX_FIFO_DEPTH		(8) 	/* maximum receive FIFO length  */
+
+/* serial subtype definitions */
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+/* Debugging... DEBUG_INTR is bad to use when one of the zs
+ * lines is your console ;(
+ */
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+#define SERIAL_DEBUG_THROTTLE
+
+#define _INLINE_ inline
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+static struct s3c44b0x_serial s3c44b0x_info;
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the memcpy_fromfs blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+ 
+static unsigned char tmp_buf[SERIAL_XMIT_SIZE];	/* This is cheating */
+static DECLARE_MUTEX (tmp_buf_sem);
+
+/* Console hooks... */
+static s3c_baud_table_t default_console_baud = { 115200, B115200 };
+
+#if defined(CONFIG_SERIAL_S3C44B0X_CONSOLE)
+static int console_number =  0;
+#endif
+	
+DECLARE_TASK_QUEUE(tq_s3c44b0x_serial);
+
+static struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+static struct tty_struct 	*serial_table[USART_CNT];
+static struct termios 		*serial_termios[USART_CNT];
+static struct termios		*serial_termios_locked[USART_CNT];
+
+static void change_speed	(struct s3c44b0x_serial *info);
+
+static _INLINE_ void tx_stop	(void);
+static _INLINE_ void tx_start	(int ints);
+static _INLINE_ void rx_stop	(void);
+static _INLINE_ void rx_start	(int ints);
+static _INLINE_ void xmit_char		(struct s3c44b0x_serial *info, char ch);
+static _INLINE_ void rs_sched_event	(struct s3c44b0x_serial *info, int event);
+static _INLINE_ void uart_speed		(struct s3c44b0x_serial *info, unsigned int cflag);
+static _INLINE_ void handle_status 	(struct s3c44b0x_serial *info, unsigned int status);
+static _INLINE_ void fifo_reset		(void);
+static _INLINE_ void fifo_init		(void);
+
+static void set_ints_mode	(struct s3c44b0x_serial *info, int yes);
+static void rs_interruptTx	(int irq, void *dev_id, struct pt_regs *regs);
+static void rs_interruptRx	(int irq, void *dev_id, struct pt_regs *regs);
+static void rs_interruptErr	(int irq, void *dev_id, struct pt_regs *regs);
+
+static void batten_down_hatches (void);
+extern void show_net_buffers	(void);
+extern void hard_reset_now	(void);
+static void handle_termios_tcsets(struct termios *ptermios, struct s3c44b0x_serial *pinfo);
+
+
+/******************************************************************************/
+static _INLINE_ void tx_delay(void)
+{
+	volatile int i;
+	for (i=0; i < 50; i++) {
+		i = i+1;
+		i = i-1;
+	};
+}
+
+static _INLINE_ void tx_start(int ints)
+{
+	if (ints) enable_irq(S3C44B0X_INTERRUPT_UTX0);
+}
+
+static _INLINE_ void tx_stop(void)
+{
+	disable_irq(S3C44B0X_INTERRUPT_UTX0);
+}
+
+static _INLINE_ void rx_start(int ints)
+{
+	if (ints) {
+		enable_irq(S3C44B0X_INTERRUPT_URX0);
+		enable_irq(S3C44B0X_INTERRUPT_UERR);
+	}
+}
+
+static _INLINE_ void rx_stop(void)
+{
+	disable_irq(S3C44B0X_INTERRUPT_URX0);
+	disable_irq(S3C44B0X_INTERRUPT_UERR);
+}
+
+static void set_ints_mode(struct s3c44b0x_serial *info, int yes)
+{
+	info->use_ints = yes;
+	if (yes) {
+		s3c44b0x_unmask_irq(S3C44B0X_INTERRUPT_UTX0);
+		s3c44b0x_unmask_irq(S3C44B0X_INTERRUPT_URX0);
+		s3c44b0x_unmask_irq(S3C44B0X_INTERRUPT_UERR);
+	} else {
+		s3c44b0x_mask_irq(S3C44B0X_INTERRUPT_UERR);
+		s3c44b0x_mask_irq(S3C44B0X_INTERRUPT_URX0);
+		s3c44b0x_mask_irq(S3C44B0X_INTERRUPT_UTX0);
+	}
+}
+
+static void hw_flow_control (int cmd)
+{
+	/* the MBA44 board does not have hw flow control */
+}
+
+static _INLINE_ void fifo_reset()
+{
+	u_int8_t ufcon = inb(S3C44B0X_UFCON0);
+	ufcon |= S3C44B0X_UFCON_RX_FIFO_RST | S3C44B0X_UFCON_TX_FIFO_RST;
+	outb(ufcon, S3C44B0X_UFCON0);
+}
+
+static _INLINE_ void fifo_init()
+{
+	u_int8_t ufcon = inb(S3C44B0X_UFCON0);
+
+	if (RX_FIFO_LEVEL + TX_FIFO_LEVEL)
+		ufcon |= S3C44B0X_UFCON_FIFO_EN
+                      | S3C44B0X_UCON_TXINT_LEVEL
+                      | S3C44B0X_UCON_RXINT_LEVEL;
+
+	switch (RX_FIFO_LEVEL) {
+		case 4 :	ufcon |= S3C44B0X_UFCON_RX_FIFO_4; break;
+		case 8 :	ufcon |= S3C44B0X_UFCON_RX_FIFO_8; break;
+		case 12:	ufcon |= S3C44B0X_UFCON_RX_FIFO_12; break;
+		case 16:	ufcon |= S3C44B0X_UFCON_RX_FIFO_16; break;
+	}
+	switch (TX_FIFO_LEVEL) {
+		case 0 :	ufcon |= S3C44B0X_UFCON_TX_FIFO_0; break;
+		case 4 :	ufcon |= S3C44B0X_UFCON_TX_FIFO_4; break;
+		case 8 :	ufcon |= S3C44B0X_UFCON_TX_FIFO_8; break;
+		case 12 :	ufcon |= S3C44B0X_UFCON_TX_FIFO_12; break;
+	}
+	outb(ufcon, S3C44B0X_UFCON0);
+}
+
+static inline int serial_paranoia_check(struct s3c44b0x_serial *info,
+					dev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%d, %d) in %s\n";
+	static const char *badinfo =
+		"Warning: null s3c44b0x_serial struct for (%d, %d) in %s\n";
+
+	if  (!info) {
+		printk(badinfo, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+	if  (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, MAJOR(device), MINOR(device), routine);
+		return 1;
+	}
+#endif
+    return 0;
+}
+
+/* Sets or clears DTR on the requested line */
+static inline void set_dtr(struct s3c44b0x_serial *info, int set)
+{
+	/* we do not need hw flow control */
+}
+
+/* Sets or clears RTS on the requested line */
+/* Note: rts is only directly controllable if hw flow
+ * control is not enabled */
+static inline void set_rts(struct s3c44b0x_serial *info, int set)
+{
+	/* we do not need hw flow control */
+}
+
+/* Reads value of serial status signals */
+static unsigned int get_status(struct s3c44b0x_serial *info)
+{
+	/* we do not need hw flow control */
+	return 0;
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+    struct s3c44b0x_serial *info = (struct s3c44b0x_serial *) tty->driver_data;
+    unsigned long flags = 0;
+
+    if	(serial_paranoia_check(info, tty->device, "rs_stop"))
+    	return;
+
+    save_flags(flags);
+    cli();
+    tx_stop();
+    rx_stop();
+    restore_flags(flags);
+}
+
+static void rs_put_char(struct s3c44b0x_serial *info, char ch)
+{
+    unsigned long flags = 0;
+
+    save_flags(flags);
+    cli();
+    xmit_char(info, ch);
+    restore_flags(flags);
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+    struct s3c44b0x_serial *info = (struct s3c44b0x_serial *) tty->driver_data;
+    unsigned long flags = 0;
+
+    if  (serial_paranoia_check(info, tty->device, "rs_start"))
+	return;
+
+    save_flags(flags);
+    cli();
+    rx_start(info->use_ints);
+    tx_start(info->use_ints);
+    restore_flags(flags);
+}
+
+/* Drop into either the boot monitor or kadb upon receiving a break
+ * from keyboard/console input.
+ */
+static void batten_down_hatches(void)
+{
+#if 0
+	/* If we are doing kadb, we call the debugger
+	 * else we just drop into the boot monitor.
+	 * Note that we must flush the user windows
+	 * first before giving up control.
+	 */
+	if ((((unsigned long) linux_dbvec) >= DEBUG_FIRSTVADDR) &&
+		(((unsigned long) linux_dbvec) <= DEBUG_LASTVADDR))
+		sp_enter_debugger();
+	else
+		panic("s3c44b0x_serial: batten_down_hatches");
+	return;
+#endif
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ *
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assembly code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+ 
+static _INLINE_ void rs_sched_event(struct s3c44b0x_serial *info, int event)
+{
+	info->event |= 1 << event;
+	queue_task_irq_off(&info->tqueue, &tq_s3c44b0x_serial);
+	mark_bh(SERIAL_BH);
+}
+
+/*  
+ *	This is the serial driver's generic interrupt routine
+ */ 
+static void rs_interruptTx(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int count, status;
+	struct s3c44b0x_serial *info = &s3c44b0x_info;
+
+	if  (info->x_char) {
+		tx_delay();
+		outb(info->x_char, S3C44B0X_UTXH0);
+		info->x_char = 0;
+		return;
+	}
+
+	if  ((info->xmit_cnt <= 0) || info->tty->stopped || info->tty->hw_stopped ) {
+		tx_stop();
+		s3c44b0x_mask_irq(S3C44B0X_INTERRUPT_UTX0);
+		return;
+	}
+
+	for (count = TX_FIFO_DEPTH; count > 0; --count) {
+		status = inb(S3C44B0X_UFSTAT0);
+		if (status & S3C44B0X_UFSTAT_TX_FIFO_FULL) {
+			handle_status (info, S3C44B0X_UFSTAT_TX_FIFO_FULL);
+			break;
+		} else {
+			tx_delay();
+			outb(info->xmit_buf[info->xmit_tail++], 
+				S3C44B0X_UTXH0);
+			info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+			if (--info->xmit_cnt <= 0) 
+				break;
+		}
+	}
+
+	if (info->xmit_cnt < WAKEUP_CHARS)
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+	if (info->xmit_cnt <= 0)
+	{
+		tx_stop();
+		s3c44b0x_mask_irq(S3C44B0X_INTERRUPT_UTX0);
+	}
+	return;
+}
+
+#define S3C44B0X_UERSTAT_ERROR  (	S3C44B0X_UERSTAT_OVERRUN_ERROR |\
+					S3C44B0X_UERSTAT_PARITY_ERROR |\
+					S3C44B0X_UERSTAT_FRAME_ERROR |\
+					S3C44B0X_UERSTAT_BREAK_DETECT	)
+
+static void rs_interruptRx(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct s3c44b0x_serial *info = &s3c44b0x_info;
+	struct tty_struct *tty = info->tty;
+	unsigned int count;
+	volatile u_int8_t status, fifo_status;
+
+	// printk("--- Rx INT ---\n"); // ###
+	
+	if (!info || !tty || (!(info->flags & S_INITIALIZED)))
+		return;
+
+	if ((tty->flip.count + RX_FIFO_DEPTH) >= TTY_FLIPBUF_SIZE)
+		queue_task_irq_off(&tty->flip.tqueue, &tq_timer);
+
+	count = RX_FIFO_DEPTH;
+	do {
+		/* check all error flags and accept data if valid */
+		fifo_status = inb(S3C44B0X_UFSTAT0);
+		if (!(fifo_status & S3C44B0X_UFSTAT_RX_FIFO_COUNT))
+			break;  //if 0 bytes exit
+
+		status = inb(S3C44B0X_UERSTAT0);
+		if (!(status & S3C44B0X_UERSTAT_ERROR) )
+			*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		else {
+			if (fifo_status & S3C44B0X_UFSTAT_RX_FIFO_FULL) {
+				*tty->flip.flag_buf_ptr = TTY_NORMAL;
+				handle_status (info, S3C44B0X_UFSTAT_RX_FIFO_FULL);
+			}
+			if (status & S3C44B0X_UERSTAT_OVERRUN_ERROR) {
+				*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+				handle_status (info, S3C44B0X_UERSTAT_OVERRUN_ERROR);
+			}
+			if 	(status & S3C44B0X_UERSTAT_BREAK_DETECT) {
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+				handle_status (info, S3C44B0X_UERSTAT_BREAK_DETECT);
+			}
+			if	(status & S3C44B0X_UERSTAT_PARITY_ERROR) {
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+				handle_status (info, S3C44B0X_UERSTAT_PARITY_ERROR);
+			}
+			if 	(status & S3C44B0X_UERSTAT_FRAME_ERROR) {
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+				handle_status (info, S3C44B0X_UERSTAT_FRAME_ERROR);
+			}
+		}
+		*tty->flip.char_buf_ptr++ = 
+			inb(S3C44B0X_URXH0);
+		tty->flip.flag_buf_ptr++;
+		tty->flip.count++;
+	} while ((--count > 0) && !(status & S3C44B0X_UERSTAT_ERROR) );
+
+//     if (fifo_status & (U_RFOV | U_E_RxTO))
+// 		handle_status (info, (U_RFOV | U_E_RxTO));
+	
+	queue_task_irq_off(&tty->flip.tqueue, &tq_timer);	
+}
+
+static void rs_interruptErr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	rs_interruptRx(irq, dev_id, regs);
+}
+
+static _INLINE_ void handle_status ( struct s3c44b0x_serial *info, unsigned int status )
+{
+//     if (status & U_TFFUL) {
+// 		return;				/* FIXME - do something */
+// 	}
+//     if (status & U_RFFUL) {
+// 		info->usart->cr |= U_SBR;	
+// 	}
+//     if (status & U_BSD) {
+// 		batten_down_hatches();
+// 	}
+//     info->usart->csr |= status;
+}
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_s3c44b0x_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct s3c44b0x_serial *info = (struct s3c44b0x_serial *) private_;
+	struct tty_struct *tty;
+
+	tty = info->tty;
+	if (!tty ) return;
+
+	if  (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if  ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) 
+		(tty->ldisc.write_wakeup) (tty);
+		wake_up_interruptible(&tty->write_wait);
+	}
+}
+
+/*
+ * This routine is called from the scheduler tqueue when the interrupt
+ * routine has signalled that a hangup has occurred.  The path of
+ * hangup processing is:
+ *
+ * 	serial interrupt routine -> (scheduler tqueue) ->
+ * 	do_serial_hangup() -> tty->hangup() -> rs_hangup()
+ *
+ */
+static void do_serial_hangup(void *private_)
+{
+	struct s3c44b0x_serial *info = (struct s3c44b0x_serial *) private_;
+	struct tty_struct *tty;
+	
+	tty = info->tty;
+	if (!tty)	return;
+	tty_hangup(tty);
+}
+
+static u_int16_t calcCD(u_int32_t br)
+{
+	/* effectively add 1/2 LSB before dividing */
+	u_int32_t divisor = (CONFIG_ARM_CLK >> 3) / br - 1;
+	return (divisor >> 1);
+}
+
+static _INLINE_ void uart_speed(struct s3c44b0x_serial *info, unsigned int cflag)
+{
+//	unsigned baud = info->baud;
+//	u_int16_t divisor = calcCD(baud);
+// ###	outw(divisor, S3C44B0X_UBRDIV);
+}
+
+static int startup(struct s3c44b0x_serial *info)
+{
+	unsigned long flags;
+
+	if (info->flags & S_INITIALIZED)
+		return 0;
+
+	if (!info->xmit_buf) {
+		info->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL);
+		if (!info->xmit_buf) return -ENOMEM;
+	}
+
+	save_flags(flags);    cli();
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttyS%d (irq %d)...\n", info->line, info->irq);
+#endif
+
+	/*
+	 * Clear the FIFO buffers and disable them
+	 * (they will be reenabled in change_speed())
+	 */
+	fifo_reset();
+
+	/*
+	 * Now, initialize the UART 
+	 */ 
+	if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+	
+	/*
+	 * and set the speed of the serial port
+	 */
+	change_speed(info);
+	
+	info->flags |= S_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct s3c44b0x_serial *info)
+{
+	unsigned long flags;
+	
+	tx_stop();
+	rx_stop();	/* All off! */
+	if (!(info->flags & S_INITIALIZED))
+		return;
+	
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Shutting down serial port %d (irq %d)....\n", info->line,
+			info->irq);
+#endif
+	
+	save_flags(flags);    cli();		/* Disable interrupts */
+	
+	if (info->xmit_buf) {
+		free_page((unsigned long) info->xmit_buf);
+		info->xmit_buf = 0;
+	}
+
+	if  (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~S_INITIALIZED;
+	restore_flags(flags);
+}
+
+static s3c_baud_table_t baud_table[] = {
+	{      0, B0 },
+	{     50, B50 },
+	{     75, B75 },
+	{    110, B110 },
+	{    134, B134 },
+	{    150, B150 },
+	{    200, B200 },
+	{    300, B300 },
+	{    600, B600 },
+	{   1200, B1200 },
+	{   1800, B1800 },
+	{   2400, B2400 },
+	{   4800, B4800 },
+	{   9600, B9600 },
+	{  19200, B19200 },
+	{  38400, B38400 },
+	{  57600, B57600 },
+	{ 115200, B115200 },
+	{ 230400, B230400 },
+	{      -1, -1 }
+};
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void change_speed(struct s3c44b0x_serial *info)
+{
+	unsigned cflag;
+	int      table_index;
+	u_int8_t ulcon, ucon;
+	
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+	
+	tx_stop();
+	rx_stop();
+	
+	/* UART baudrate setup */
+	table_index = cflag & CBAUD;
+	if (table_index & CBAUDEX)	{
+		table_index &= ~CBAUDEX; 	 /* remove CBAUDEX bit */
+		table_index += CBAUD & ~CBAUDEX; /* add high rate offset */
+	}
+	info->baud = baud_table[table_index].rate;
+	uart_speed(info, cflag);
+
+	/* UART line control register setup */
+	ulcon = 0x00;
+	switch  (cflag & CSIZE) {
+		case CS5: ulcon |= S3C44B0X_ULCON_WORDLN_5; break;
+		case CS6: ulcon |= S3C44B0X_ULCON_WORDLN_6; break;
+		case CS7: ulcon |= S3C44B0X_ULCON_WORDLN_7; break;
+		case CS8: ulcon |= S3C44B0X_ULCON_WORDLN_8; break;
+	}
+	if (cflag & PARENB)
+		ulcon |= (cflag & PARODD) ? 
+			S3C44B0X_ULCON_PAR_ODD : S3C44B0X_ULCON_PAR_EVEN;
+	if (cflag & CSTOPB)
+		ulcon |= S3C44B0X_ULCON_STOPB_2;
+	outb(ulcon, S3C44B0X_ULCON0);
+
+	/* UART control register setup */
+	ucon = 0;
+	ucon |= S3C44B0X_UCON_RX_MODE_INT_POLL;   /* receive mode: IRQ or polling */
+	ucon |= S3C44B0X_UCON_TX_MODE_INT_POLL;   /* transmit mode: IRQ or polling */
+	ucon |= S3C44B0X_UCON_RX_ERR_INT_EN;      /* Rx status interrupt enable */
+	ucon |= S3C44B0X_UCON_RX_TIMEOUT_EN;      /* Rx timeout enable (5 bits) */
+	outb(ucon, S3C44B0X_UCON0);
+	
+	tx_start(info->use_ints);
+	rx_start(info->use_ints);
+
+	return;
+}
+
+/*
+ *	Wait for transmitter & holding register to empty
+ */
+static inline void wait_for_xmitr(void)
+{
+	volatile unsigned int status, tmout = 100000;
+	do {
+		status = inb(S3C44B0X_UTRSTAT0);
+		if (--tmout == 0)
+			break;
+	} while((status & (	S3C44B0X_UTRSTAT_TBE |		\
+				S3C44B0X_UTRSTAT_TSE)) !=	\
+				(S3C44B0X_UTRSTAT_TBE |		\
+				 S3C44B0X_UTRSTAT_TSE)	);
+}
+
+static _INLINE_ void xmit_char(struct s3c44b0x_serial *info, char ch)
+{
+	wait_for_xmitr();	
+	tx_delay();
+	outb(ch, S3C44B0X_UTXH0);
+}
+
+static void rs_set_ldisc(struct tty_struct *tty)
+{
+	struct s3c44b0x_serial *info = (struct s3c44b0x_serial *) tty->driver_data;
+
+	if  (serial_paranoia_check(info, tty->device, "rs_set_ldisc"))
+		return;
+
+	info->is_cons = (tty->termios->c_line == N_TTY);
+
+	printk("ttyS%d console mode %s\n", info->line, info->is_cons ? "on" : "off");
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct s3c44b0x_serial *info = (struct s3c44b0x_serial *) tty->driver_data;
+	unsigned long flags;
+
+	if  (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
+		return;
+
+	if  (!info->use_ints) {
+		for (;;) {
+		if  (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !info->xmit_buf) 
+			return;
+		save_flags(flags);	    cli();
+		tx_start(info->use_ints);
+		xmit_char(info, info->xmit_buf[info->xmit_tail++]);
+		info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+		info->xmit_cnt--;
+		}
+	} else {
+		if  (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !info->xmit_buf) 
+			return;
+		save_flags(flags);	cli();
+		tx_start(info->use_ints);
+		xmit_char(info, info->xmit_buf[info->xmit_tail++]);
+		info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+		info->xmit_cnt--;
+	}
+	restore_flags(flags);
+}
+
+static int rs_write(struct tty_struct *tty, int from_user,
+					const unsigned char *buf, int count)
+{
+	int c, total = 0;
+	struct s3c44b0x_serial *info = (struct s3c44b0x_serial *) tty->driver_data;
+	unsigned long flags;
+
+	if  (serial_paranoia_check(info, tty->device, "rs_write"))
+		return 0;
+
+	if  (!tty || !info->xmit_buf || !tmp_buf)
+		return 0;
+
+	save_flags(flags);
+	if (from_user) {
+		down(&tmp_buf_sem);
+		cli();
+		while (1) {
+			c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				SERIAL_XMIT_SIZE - info->xmit_head));
+			if  (c <= 0)
+				break;
+			
+			memcpy(info->xmit_buf + info->xmit_head, buf, c);
+			info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1);
+			info->xmit_cnt += c;
+			restore_flags(flags);
+			buf += c;
+			count -= c;
+			total += c;
+		}
+		restore_flags(flags);
+		up(&tmp_buf_sem);
+
+	} else {
+		cli();
+		while (1) {
+			c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+					SERIAL_XMIT_SIZE - info->xmit_head));
+			if  (c <= 0)
+				break;
+			memcpy(info->xmit_buf + info->xmit_head, buf, c);
+			info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1);
+			info->xmit_cnt += c;
+			buf += c;
+			count -= c;
+			total += c;
+		}
+		restore_flags(flags);
+	}
+
+	if  (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
+		if   (!info->use_ints) {
+			while (info->xmit_cnt) {
+				/* Send char */
+				xmit_char(info, info->xmit_buf[info->xmit_tail++]);
+				info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+				info->xmit_cnt--;
+			}
+		} 
+		else {
+			tx_start(info->use_ints);
+		}
+	} 
+	restore_flags(flags);
+	
+	return total;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct s3c44b0x_serial *info = (struct s3c44b0x_serial *) tty->driver_data;
+	int ret;
+
+	if  (serial_paranoia_check(info, tty->device, "rs_write_room"))
+		return 0;
+	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
+	if  (ret < 0)
+		ret = 0;
+	return ret;
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct s3c44b0x_serial *info = (struct s3c44b0x_serial *) tty->driver_data;
+
+	if  (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+		return 0;
+	return info->xmit_cnt;
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	unsigned long flags;
+	struct s3c44b0x_serial *info = (struct s3c44b0x_serial *) tty->driver_data;
+
+	if  (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+		return;
+	save_flags(flags);    cli();
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+	restore_flags(flags);
+	wake_up_interruptible(&tty->write_wait);
+	if  ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) 
+		(tty->ldisc.write_wakeup) (tty);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ *
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct *tty)
+{
+	struct s3c44b0x_serial *info = (struct s3c44b0x_serial *) tty->driver_data;
+	unsigned int flags;
+
+#ifdef SERIAL_DEBUG_THROTTLE
+	char buf[64];
+
+	printk("throttle %s: %d\n", tty_name(tty, buf),
+			tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+		return;
+
+	if (I_IXOFF(tty))
+		info->x_char = STOP_CHAR(tty);
+
+	/* Turn off RTS line (do this atomically) */
+	if (tty->termios->c_cflag & CRTSCTS) {
+			save_flags(flags);
+			cli();
+			set_rts (info, 0);
+			restore_flags(flags);
+	}
+}
+
+static void rs_unthrottle(struct tty_struct *tty)
+{
+	struct s3c44b0x_serial *info = (struct s3c44b0x_serial *) tty->driver_data;
+	unsigned int flags;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char buf[64];
+
+	printk("unthrottle %s: %d\n", tty_name(tty, buf),
+		tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+		return;
+
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+		info->x_char = 0;
+		else
+		info->x_char = START_CHAR(tty);
+	}
+
+	/* Assert RTS line (do this atomically) */
+	if (tty->termios->c_cflag & CRTSCTS) {
+		save_flags(flags);
+		cli();
+		set_rts (info, 1);
+		restore_flags(flags);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int get_serial_info(struct s3c44b0x_serial *info,
+			   struct serial_struct *retinfo)
+{
+	struct serial_struct tmp;
+
+	if  (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = info->type;
+	tmp.line = info->line;
+	tmp.irq = info->irq;
+	tmp.port = info->port;
+	tmp.flags = info->flags;
+	tmp.baud_base = info->baud_base;
+	tmp.close_delay = info->close_delay;
+	tmp.closing_wait = info->closing_wait;
+	tmp.custom_divisor = info->custom_divisor;
+	memcpy_tofs(retinfo, &tmp, sizeof(*retinfo));
+	return 0;
+}
+
+static int set_serial_info(struct s3c44b0x_serial *info,
+			   struct serial_struct *new_info)
+{
+	struct serial_struct new_serial;
+	struct s3c44b0x_serial old_info;
+	int retval = 0;
+
+	if  (!new_info)
+		return -EFAULT;
+	memcpy_fromfs(&new_serial, new_info, sizeof(new_serial));
+	old_info = *info;
+
+	if  (!suser()) {
+		if	((new_serial.baud_base != info->baud_base) 	||
+			(new_serial.type != info->type) 		||
+			(new_serial.close_delay != info->close_delay) 	||
+			((new_serial.flags & ~S_USR_MASK) 		!=
+			(info->flags & ~S_USR_MASK))) return -EPERM;
+		info->flags = ((info->flags & ~S_USR_MASK) |
+			(new_serial.flags & S_USR_MASK));
+		info->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	if  (info->count > 1)
+		return -EBUSY;
+
+		/*
+		* OK, past this point, all the error checking has been done.
+		* At this point, we start making changes.....
+		*/
+
+	info->baud_base = new_serial.baud_base;
+	info->flags = ((info->flags & ~S_FLAGS) | (new_serial.flags & S_FLAGS));
+	info->type = new_serial.type;
+	info->close_delay = new_serial.close_delay;
+	info->closing_wait = new_serial.closing_wait;
+
+check_and_exit:
+	retval = startup(info);
+	return retval;
+}
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space.
+ */
+static int get_lsr_info(struct s3c44b0x_serial *info, unsigned int *value)
+{
+	unsigned char status;
+
+	cli();
+//    status = (info->usart->csr & U_CTS) ? 1 : 0;
+	status = 0x00;
+	sti();
+	put_user(status, value);
+	return 0;
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void send_break(struct s3c44b0x_serial *info, int duration)
+{
+	u_int8_t ucon;
+	
+	current->state = TASK_INTERRUPTIBLE;
+	cli();
+	
+	ucon = inb(S3C44B0X_UCON0);
+	ucon |= S3C44B0X_UCON_SEND_BREAK;
+	outb(ucon, S3C44B0X_UCON0);
+	
+	schedule_timeout(info->close_delay);
+	
+	ucon &= ~S3C44B0X_UCON_SEND_BREAK;
+	outb(ucon, S3C44B0X_UCON0);
+	
+	sti();
+}
+
+static int rs_ioctl(struct tty_struct *tty, struct file *file,
+					unsigned int cmd, unsigned long arg)
+{
+	int error;
+	struct s3c44b0x_serial *info = (struct s3c44b0x_serial *) tty->driver_data;
+	unsigned int val;
+	int retval;
+
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+		(cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) &&
+		(cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+			return -EIO;
+	}
+
+	switch (cmd) {
+	case TCSBRK:				/* SVID version: non-zero arg --> no break */
+		retval = tty_check_change(tty);
+		if (retval)
+			return retval;
+		tty_wait_until_sent(tty, 0);
+		if (!arg)
+			send_break(info, HZ / 4);	/* 1/4 second */
+		return 0;
+	case TCSBRKP:				/* support for POSIX tcsendbreak() */
+		retval = tty_check_change(tty);
+		if (retval)
+			return retval;
+		tty_wait_until_sent(tty, 0);
+		send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
+		return 0;
+	case TIOCGSOFTCAR:
+		error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
+
+		if (error)
+			return error;
+		put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
+		return 0;
+	case TIOCSSOFTCAR:
+		arg = get_user(arg, (unsigned long *) arg);
+		tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
+		return 0;
+	case TIOCGSERIAL:
+		error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(struct serial_struct));
+		if (error)
+			return error;
+		return get_serial_info(info, (struct serial_struct *) arg);
+	case TIOCSSERIAL:
+		return set_serial_info(info, (struct serial_struct *) arg);
+	case TIOCSERGETLSR:		/* Get line status register */
+		error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(unsigned int));
+		if (error)
+			return error;
+		else
+			return get_lsr_info(info, (unsigned int *) arg);
+
+	case TIOCSERGSTRUCT:
+		error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(struct s3c44b0x_serial));
+		if (error)
+			return error;
+		memcpy_tofs((struct s3c44b0x_serial *) arg, info,
+			sizeof(struct s3c44b0x_serial));
+		return 0;
+
+
+	case TIOCMGET:	/* get all modem bits */
+		if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(unsigned int))))
+			return(error);
+		val = get_status(info);
+		put_user(val, (unsigned int *) arg);
+		break;
+
+	case TIOCMBIS:	/* modem bits set */
+		if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+					 sizeof(unsigned int))))
+			return(error);
+		
+		get_user(val, (unsigned int *) arg);
+		
+		if (val & TIOCM_RTS) set_rts(info, 1);
+		if (val & TIOCM_DTR) set_dtr(info, 1);
+		break;
+
+	case TIOCMBIC:	/* modem bits clear */
+		if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+					 sizeof(unsigned int))))
+			return(error);
+		get_user(val, (unsigned int *) arg);
+			
+		if (val & TIOCM_RTS) set_rts(info, 0);
+		if (val & TIOCM_DTR) set_dtr(info, 0);
+		break;
+
+	case TIOCMSET:	/* set all modem bits */
+		if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+					 sizeof(unsigned int))))
+			return(error);
+		get_user(val, (unsigned int *) arg);
+
+		set_rts (info, ((val & TIOCM_RTS) ? 1 : 0) );
+		set_dtr (info, ((val & TIOCM_DTR) ? 1 : 0) );
+		break;
+
+	case TCSETS:	
+	  /*
+	   * take care if the speed change, leave rest to termios by falling through
+	   */
+	  handle_termios_tcsets((struct termios *)arg, info);
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static void handle_termios_tcsets(  struct termios *ptermios, 
+				    struct s3c44b0x_serial *pinfo)
+{
+	if  (pinfo->tty->termios->c_cflag != ptermios->c_cflag) {
+		pinfo->tty->termios->c_cflag = ptermios->c_cflag;
+	}
+	change_speed(pinfo);
+}
+	  
+static void rs_set_termios( struct tty_struct *tty,
+			    struct termios *old_termios)
+{
+	struct s3c44b0x_serial *info = (struct s3c44b0x_serial *) tty->driver_data;
+
+	if (tty->termios->c_cflag == old_termios->c_cflag)
+		return;
+
+	change_speed(info);
+
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) &&
+		!(tty->termios->c_cflag & CRTSCTS)) 
+	{
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ *
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * S structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file *filp)
+{
+	struct s3c44b0x_serial *info = (struct s3c44b0x_serial *) tty->driver_data;
+	unsigned long flags;
+	
+	if  (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+		return;
+	
+	save_flags(flags);  cli();
+	
+	if  (tty_hung_up_p(filp)) {
+		restore_flags(flags);
+		return;
+	}
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_close ttyS%d, count = %d\n", info->line, info->count);
+#endif
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  Info->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+			   "info->count is %d\n", info->count);
+		info->count = 1;
+	}
+	if (--info->count < 0) {
+		printk("rs_close: bad serial port count for ttyS%d: %d\n",
+			   info->line, info->count);
+		info->count = 0;
+	}
+	if (info->count) {
+		restore_flags(flags);
+		return;
+	}
+	// closing port so disable interrupts
+	set_ints_mode(info, 0);
+
+	info->flags |= S_CLOSING;
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & S_NORMAL_ACTIVE)
+		info->normal_termios = *tty->termios;
+	if (info->flags & S_CALLOUT_ACTIVE)
+		info->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != S_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (tty->ldisc.num != tty_ldiscs[N_TTY].num) {
+		if (tty->ldisc.close)
+			(tty->ldisc.close) (tty);
+		tty->ldisc = tty_ldiscs[N_TTY];
+		tty->termios->c_line = N_TTY;
+		if (tty->ldisc.open)
+			(tty->ldisc.open) (tty);
+	}
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+/*			current->timeout = jiffies + info->close_delay;  */
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(S_NORMAL_ACTIVE | S_CALLOUT_ACTIVE | S_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	restore_flags(flags);
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void rs_hangup(struct tty_struct *tty)
+{
+	struct s3c44b0x_serial *info = (struct s3c44b0x_serial *) tty->driver_data;
+	
+	if	(serial_paranoia_check(info, tty->device, "rs_hangup"))
+		return;
+	
+	rs_flush_buffer(tty);
+	shutdown(info);
+	info->event = 0;
+	info->count = 0;
+	info->flags &= ~(S_NORMAL_ACTIVE | S_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file *filp,
+			   struct s3c44b0x_serial *info)
+{
+	unsigned long flags;
+	DECLARE_WAITQUEUE(wait, current);
+	int retval;
+	int do_clocal = 0;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (info->flags & S_CLOSING) {
+		interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		if (info->flags & S_HUP_NOTIFY)
+			return -EAGAIN;
+		else
+			return -ERESTARTSYS;
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & S_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+			(info->flags & S_SESSION_LOCKOUT) &&
+			(info->session != current->session)) return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+			(info->flags & S_PGRP_LOCKOUT) &&
+			(info->pgrp != current->pgrp)) return -EBUSY;
+		info->flags |= S_CALLOUT_ACTIVE;
+		return 0;
+	}
+
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & S_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= S_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & S_CALLOUT_ACTIVE) {
+		if (info->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, info->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready before block: ttyS%d, count = %d\n",
+		   info->line, info->count);
+#endif
+	info->count--;
+	info->blocked_open++;
+	while (1) {
+		save_flags(flags);
+		cli();
+		if (!(info->flags & S_CALLOUT_ACTIVE))
+			set_dtr(info, 1);
+		restore_flags(flags);
+		current->state = TASK_INTERRUPTIBLE;
+		if (tty_hung_up_p(filp) || !(info->flags & S_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & S_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & S_CALLOUT_ACTIVE) &&
+			!(info->flags & S_CLOSING) && do_clocal)
+			break;
+		if (signal_pending(current)) {
+/*		if (current->signal & ~current->blocked) {  */
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef SERIAL_DEBUG_OPEN
+		printk("block_til_ready blocking: ttyS%d, count = %d\n",
+			   info->line, info->count);
+#endif
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&info->open_wait, &wait);
+	if (!tty_hung_up_p(filp))
+		info->count++;
+	info->blocked_open--;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready after blocking: ttyS%d, count = %d\n",
+		   info->line, info->count);
+#endif
+	if (retval)
+		return retval;
+	info->flags |= S_NORMAL_ACTIVE;
+	return 0;
+}
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its S structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+int rs_open(struct tty_struct *tty, struct file *filp)
+{
+	struct s3c44b0x_serial *info = &s3c44b0x_info;
+	int retval, line;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+
+	/* check if line is sane */
+	if (line < 0 || line >= USART_CNT)
+		return -ENODEV;
+
+	if (serial_paranoia_check(info, tty->device, "rs_open"))
+		return -ENODEV;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+		info->count);
+#endif
+	info->count++;
+	tty->driver_data = info;
+	info->tty = tty;
+
+	/*
+	 * Start up serial port
+	 */
+	set_ints_mode(info, 1);
+	
+	retval = startup(info);
+	if (retval)
+		return retval;
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("rs_open returning after block_til_ready with %d\n",
+			   retval);
+#endif
+		return retval;
+	}
+
+	if ((info->count == 1) && (info->flags & S_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->normal_termios;
+		else
+			*tty->termios = info->callout_termios;
+		change_speed(info);
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open ttyS%d successful...\n", info->line);
+#endif
+	return 0;
+}
+
+static struct irqaction irq_uartTx =
+	{ rs_interruptTx,  0, 0, "S3C44B0X_UART_TX",  NULL, NULL };
+static struct irqaction irq_uartRx =
+	{ rs_interruptRx,  0, 0, "S3C44B0X_UART_RX",  NULL, NULL };
+static struct irqaction irq_uartErr =
+	{ rs_interruptErr, 0, 0, "S3C44B0X_UART_ERR", NULL, NULL };
+	
+extern int setup_arm_irq(int, struct irqaction *);
+
+static void interrupts_init(void)
+{
+	setup_arm_irq(S3C44B0X_INTERRUPT_UTX0,  &irq_uartTx);
+	setup_arm_irq(S3C44B0X_INTERRUPT_URX0,  &irq_uartRx);
+	setup_arm_irq(S3C44B0X_INTERRUPT_UERR, &irq_uartErr);
+}
+
+static void show_serial_version(void)
+{
+	printk("Samsung S3C44B0X UART driver version 0.1 <thomas.eschenbacher@sympat.de>\n");
+}
+
+/* rs_init inits the driver */
+static int __init rs_s3c44b0x_init(void)
+{
+	int flags, i;
+	struct s3c44b0x_serial *info;
+	
+	/* Setup base handler, and timer table. */
+	init_bh(SERIAL_BH, do_serial_bh);
+	
+	show_serial_version();
+	
+	/* Initialize the tty_driver structure */
+	
+	/* set the tty_struct pointers to NULL to let the layer */
+	/* above allocate the structs. */
+	for (i=0; i < USART_CNT; i++)
+		serial_table[i] = NULL;
+	
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+	serial_driver.name = "ttyS";
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64;
+	serial_driver.num = 1;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+	serial_driver.init_termios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver.init_termios.c_cflag |= B115200;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = rs_open;
+	serial_driver.close = rs_close;
+	serial_driver.write = rs_write;
+	serial_driver.flush_chars = rs_flush_chars;
+	serial_driver.write_room = rs_write_room;
+	serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	serial_driver.flush_buffer = rs_flush_buffer;
+	serial_driver.ioctl = rs_ioctl;
+	serial_driver.throttle = rs_throttle;
+	serial_driver.unthrottle = rs_unthrottle;
+	serial_driver.set_termios = rs_set_termios;
+	serial_driver.stop = rs_stop;
+	serial_driver.start = rs_start;
+	serial_driver.hangup = rs_hangup;
+	serial_driver.set_ldisc = rs_set_ldisc;
+	
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+	callout_driver.name = "cua";
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+	
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register serial driver\n");
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+	
+	save_flags(flags);
+	cli();
+	for (i = 0; i < USART_CNT; i++) {
+		info = &s3c44b0x_info;
+		info->magic = SERIAL_MAGIC;
+		info->tty = 0;
+		info->irqmask = S3C44B0X_INTERRUPT_UTX0 || 
+		                S3C44B0X_INTERRUPT_URX0 || 
+		                S3C44B0X_INTERRUPT_UERR;
+		info->irq = S3C44B0X_INTERRUPT_UTX0;
+		info->port = (i) ? 1 : 2;
+		info->line = i;
+
+#if defined(CONFIG_CONSOLE_NULL)
+		info->is_cons = 0;
+#else
+		if (i == console_number)
+			info->is_cons = 1;
+#endif
+		set_ints_mode(info, 0);
+		/* info->custom_divisor = 16; */ /* unused? */
+		info->custom_divisor = 0;
+		info->close_delay = 50;
+		info->closing_wait = 3000;
+		info->cts_state = 1;
+		info->x_char = 0;
+		info->event = 0;
+		info->count = 0;
+		info->blocked_open = 0;
+		info->tqueue.routine = do_softint;
+		info->tqueue.data = info;
+		info->tqueue_hangup.routine = do_serial_hangup;
+		info->tqueue_hangup.data = info;
+		info->callout_termios = callout_driver.init_termios;
+		info->normal_termios = serial_driver.init_termios;
+		
+		init_waitqueue_head(&info->open_wait);
+		init_waitqueue_head(&info->close_wait);
+		
+		printk("%s%d (irq = %d)", serial_driver.name, info->line,
+			   info->irq);
+		printk(" is a builtin Samsung S3C44B0X UART\n");
+	}
+	
+	interrupts_init();
+	
+	restore_flags(flags);
+	return 0;
+}
+
+module_init(rs_s3c44b0x_init);
+
+/*
+ * ------------------------------------------------------------
+ * Serial console driver
+ * ------------------------------------------------------------
+ */
+
+#ifdef CONFIG_SERIAL_S3C44B0X_CONSOLE
+
+static kdev_t s3c44b0x_console_device(struct console *);
+static int    s3c44b0x_console_setup(struct console *, char *);
+static void   s3c44b0x_console_write (struct console *, const char *, unsigned int );
+static int    s3c44b0x_console_initialized = 0;
+
+static struct console s3c44b0x_driver = {
+	name:		"ttyS",
+	write:		s3c44b0x_console_write,
+	device:		s3c44b0x_console_device,
+	setup:		s3c44b0x_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+/* static void init_console(struct s3c44b0x_serial *info) */
+static int s3c44b0x_console_setup(struct console *c, char *p)
+{
+	struct s3c44b0x_serial *info = &s3c44b0x_info;
+	
+	memset(info, 0, sizeof(struct s3c44b0x_serial));
+	info->use_ints = 0;
+	info->cts_state = 1;
+	info->is_cons = 1;
+//	info->usart->cr = 0; 
+//	info->usart->cr = (U_IRQ_TMODE | U_IRQ_RMODE | U_WL8);
+	fifo_init();
+	info->baud = B115200;
+	
+//     info->usart->brgr = calcCD(info->baud);
+//     info->usart->ier = 0;
+	
+	s3c44b0x_console_initialized = 1;
+	return 0;
+}
+
+static kdev_t s3c44b0x_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static void s3c44b0x_console_write (struct console *co, const char *str,
+			   unsigned int count)
+{
+#if defined(CONFIG_CONSOLE_NULL)
+	return;
+#else
+	static struct s3c44b0x_serial *info = &s3c44b0x_info;
+	
+	if (!s3c44b0x_console_initialized)
+		printk ("WARNING: Console used unintialized\n");
+	
+	while (count--) {
+		if  (*str == '\n')
+			rs_put_char(info,'\r');
+        	rs_put_char(info, *str++ );
+	}
+#endif
+}
+
+void __init s3c44b0x_console_init(void)
+{
+	register_console(&s3c44b0x_driver);
+}
+
+#endif /* CONFIG_SERIAL_S3C44B0X_CONSOLE */
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -urN linux-2.4.29/drivers/char/serial_s3c44b0x.h linux-2.4.29-uc1/drivers/char/serial_s3c44b0x.h
--- linux-2.4.29/drivers/char/serial_s3c44b0x.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_s3c44b0x.h	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,142 @@
+/*
+ * drivers/char/serial_s3c44b0x.h
+ * 
+ * Serial port driver for the Samsung S3C44B0X builtin UART
+ *
+ * Copyright (c) 2003 sympat GmbH
+ * 	by Thomas Eschenbacher <thomas.eschenbacher@sympat.de>
+ *
+ * Based on: drivers/char/serial_s3c3410.h
+ * Copyright (c) 2001, 2002  Arcturus Networks Inc.
+ * 	by Oleksandr Zhadan <oleks@arcturusnetworks.com>
+ *
+ * Based on: drivers/char/trioserial.h
+ * Copyright (c) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     D. Jeff Dionne <jeff@arcturusnetworks.com>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ * Based on: drivers/char/68328serial.h
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _S3C44B0X_SERIAL_H
+#define _S3C44B0X_SERIAL_H
+
+#include <linux/config.h>
+#include <asm/page.h>
+#include <asm/arch/hardware.h>
+
+/*
+ * For the close wait times, 0 means wait forever for serial port to
+ * flush its output.  65535 means don't wait at all.
+ */
+#define S_CLOSING_WAIT_INF	0
+#define S_CLOSING_WAIT_NONE	65535
+
+/*
+ * Definitions for S_struct (and serial_struct) flags field
+ */
+#define S_HUP_NOTIFY 	  0x0001 /* Notify getty on hangups and closes 
+				    on the callout port */
+#define S_FOURPORT  	  0x0002 /* Set OU1, OUT2 per AST Fourport settings */
+#define S_SAK		  0x0004 /* Secure Attention Key (Orange book) */
+#define S_SPLIT_TERMIOS   0x0008 /* Separate termios for dialin/callout */
+
+#define S_SPD_MASK	  0x0030
+#define S_SPD_HI	  0x0010 /* Use 56000 instead of 38400 bps */
+
+#define S_SPD_VHI	  0x0020 /* Use 115200 instead of 38400 bps */
+#define S_SPD_CUST	  0x0030 /* Use user-specified divisor */
+
+#define S_SKIP_TEST	  0x0040 /* Skip UART test during autoconfiguration */
+#define S_AUTO_IRQ  	  0x0080 /* Do automatic IRQ during autoconfiguration */
+#define S_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
+#define S_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
+#define S_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
+
+#define S_FLAGS		  0x0FFF /* Possible legal S flags */
+#define S_USR_MASK 	  0x0430 /* Legal flags that non-privileged
+				    users can set or reset */
+
+/* Internal flags used only by kernel/chr_drv/serial.c */
+#define S_INITIALIZED		0x80000000 /* Serial port was initialized */
+#define S_CALLOUT_ACTIVE	0x40000000 /* Call out device is active */
+#define S_NORMAL_ACTIVE		0x20000000 /* Normal device is active */
+#define S_BOOT_AUTOCONF		0x10000000 /* Autoconfigure port on bootup */
+#define S_CLOSING		0x08000000 /* Serial port is closing */
+#define S_CTS_FLOW		0x04000000 /* Do CTS flow control */
+#define S_CHECK_CD		0x02000000 /* i.e., CLOCAL */
+
+/* Software state per channel */
+
+/*
+ * This is our internal structure for each serial port's state.
+ * 
+ * Many fields are paralleled by the structure used by the serial_struct
+ * structure.
+ *
+ * For definitions of the flags field, see tty.h
+ */
+
+struct s3c44b0x_serial {
+	char soft_carrier;  /* Use soft carrier on this channel */
+	char break_abort;   /* Is serial console in, so process brk/abrt */
+	char is_cons;       /* Is this our console. */
+
+	/* We need to know the current clock divisor
+	 * to read the bps rate the chip has currently
+	 * loaded.
+	 */
+	unsigned char clk_divisor;  /* May be 1, 16, 32, or 64 */
+	int 			baud;
+	int			magic;
+	int			baud_base;
+	int			port;
+	int			irq;
+	int			irqmask;
+	int			flags; 		/* defined in tty.h */
+	int			type; 		/* UART type */
+	int			use_ints;
+	int			cts_state;
+	struct tty_struct 	*tty;
+	int			read_status_mask;
+	int			ignore_status_mask;
+	int			timeout;
+	int			xmit_fifo_size;
+	int			rx_fifo_size;
+	int			custom_divisor;
+	int			x_char;	/* xon/xoff character */
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int			count;	    /* # of fd on device */
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+	unsigned char 		*xmit_buf;
+	int			xmit_head;
+	int			xmit_tail;
+	int			xmit_cnt;
+	struct tq_struct	tqueue;
+	struct tq_struct	tqueue_hangup;
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+};
+
+
+/* typedef to correlate a serial speed with its cflags - type handle: */
+typedef struct
+{
+  int rate;
+  int cflag;
+} s3c_baud_table_t;
+
+#define RS_EVENT_WRITE_WAKEUP   0
+#define SERIAL_MAGIC 0x5301
+
+#endif /* !(_S3C44B0X_SERIAL_H) */
diff -urN linux-2.4.29/drivers/char/serial_s3c4530.c linux-2.4.29-uc1/drivers/char/serial_s3c4530.c
--- linux-2.4.29/drivers/char/serial_s3c4530.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_s3c4530.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,1822 @@
+/*
+ * serial-s3c4530.c: Serial port driver for the Samsung S3C4530A builtin UARTs
+ * Copyright (c) 2001-2003 Arcturus Networks Inc. 
+ *                         by Oleksandr Zhadan  <www.ArcturusNetworks.com>
+ * Copyright (c) 2002	Arcturus Networks Inc. 
+ * 		       	by Michael Leslie    <www.ArcturusNetworks.com>
+ *
+ * Based on: drivers/char/trioserial.c
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *               1998-2003  D. Jeff Dionne <jeff@uClinux.org>
+ * Copyright (c) 1998  The Silver Hammer Group, Ltd.
+ *
+ * Based on: drivers/char/68328serial.c
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/arch/irq.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+
+#define queue_task_irq_off queue_task
+#define copy_from_user(a,b,c) memcpy_fromfs(a,b,c)
+#define copy_to_user(a,b,c) memcpy_tofs(a,b,c)
+
+#include <asm/uaccess.h>
+
+#include "serial_s3c4530.h"
+
+#if defined(CONFIG_UCBOOTSTRAP)
+#include <asm/uCbootstrap.h>
+extern  char *getbenv (char *a);
+#endif
+
+
+#define USART_CNT		2
+#define UART_CLOCK		(ARM_CLK/32)
+
+					/* Receive FIFO trigger level	*/
+#define RX_FIFO_LEVEL		18	/* 	1 or 8 0r 18 0r 28	*/
+					/* Transfer FIFO trigger level	*/
+#define TX_FIFO_LEVEL		16	/*	8 or 16 or 24 or 30	*/
+
+/* serial subtype definitions */
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+/* Debugging... DEBUG_INTR is bad to use when one of the zs
+ * lines is your console ;(
+ */
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+#define SERIAL_DEBUG_THROTTLE
+
+#define RS_ISR_PASS_LIMIT 256
+
+#define _INLINE_ inline
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+
+static volatile struct s3c4530_usart_regs *usarts[USART_CNT] = {
+	(volatile struct s3c4530_usart_regs *) USART0_BASE,
+	(volatile struct s3c4530_usart_regs *) USART1_BASE
+};
+
+static struct s3c4530_serial s3c4530_info[USART_CNT];
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the memcpy_fromfs blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+ 
+static unsigned char tmp_buf[SERIAL_XMIT_SIZE];	/* This is cheating */
+static DECLARE_MUTEX (tmp_buf_sem);
+
+/* Console hooks... */
+/* struct s3c4530_serial *s3c4530_consinfo = 0; */
+static s3c_baud_table_t default_console_baud = { 9600, B9600 };
+
+#if defined(CONFIG_CONSOLE_UARTA)
+static int console_number =  0;
+#elif defined(CONFIG_CONSOLE_UARTB)
+static int console_number =  1;
+#endif
+	
+DECLARE_TASK_QUEUE(tq_s3c4530_serial);
+
+static struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+static struct tty_struct 	*serial_table[USART_CNT];
+static struct termios 		*serial_termios[USART_CNT];
+static struct termios		*serial_termios_locked[USART_CNT];
+
+static void change_speed	(struct s3c4530_serial *info);
+
+static _INLINE_ void tx_stop	(volatile struct s3c4530_usart_regs *uart);
+static _INLINE_ void tx_start	(volatile struct s3c4530_usart_regs *uart, int ints);
+static _INLINE_ void rx_stop	(volatile struct s3c4530_usart_regs *uart);
+static _INLINE_ void rx_start	(volatile struct s3c4530_usart_regs *uart, int ints);
+static _INLINE_ void xmit_char		(struct s3c4530_serial *info, char ch);
+static _INLINE_ void rs_sched_event	(struct s3c4530_serial *info, int event);
+static _INLINE_ void uart_speed		(struct s3c4530_serial *info, unsigned int cflag);
+static _INLINE_ void handle_status 	(struct s3c4530_serial *info, unsigned int status);
+static _INLINE_ void fifo_reset		(struct s3c4530_serial *info);
+static _INLINE_ void fifo_init		(struct s3c4530_serial *info);
+static _INLINE_ void rs_interrupt_Tx	(struct s3c4530_serial *info);
+static _INLINE_ void rs_interrupt_Rx	(struct s3c4530_serial *info);
+
+static void set_ints_mode	(struct s3c4530_serial *info, int yes);
+static void rs_interrupt0Tx	(int irq, void *dev_id, struct pt_regs *regs);
+static void rs_interrupt1Tx	(int irq, void *dev_id, struct pt_regs *regs);
+static void rs_interrupt0Rx	(int irq, void *dev_id, struct pt_regs *regs);
+static void rs_interrupt1Rx	(int irq, void *dev_id, struct pt_regs *regs);
+
+static void batten_down_hatches (void);
+extern void show_net_buffers	(void);
+extern void hard_reset_now	(void);
+static void handle_termios_tcsets(struct termios *ptermios, struct s3c4530_serial *pinfo);
+
+
+/******************************************************************************/
+
+static _INLINE_ void tx_start(volatile struct s3c4530_usart_regs *uart, int ints)
+{
+    if	(ints)	uart->ier |= U_THEIE;
+}
+
+static _INLINE_ void tx_stop(volatile struct s3c4530_usart_regs *uart)
+{
+    uart->ier &= (~U_THEIE);
+}
+
+static _INLINE_ void rx_start(volatile struct s3c4530_usart_regs *uart, int ints)
+{
+    if (ints)
+		uart->ier |= (U_RFREAIE | U_E_RxTOIE);
+}
+
+static _INLINE_ void rx_stop(volatile struct s3c4530_usart_regs *uart)
+{
+    uart->ier &= ~(U_RFREAIE | U_E_RxTOIE);
+}
+
+static void set_ints_mode(struct s3c4530_serial *info, int yes)
+{
+    info->use_ints = yes;
+    if (yes) {
+		s3c4530_unmask_irq (info->irq);
+		s3c4530_unmask_irq (info->irq - 1);
+	} else {	
+		s3c4530_mask_irq (info->irq);
+		s3c4530_mask_irq (info->irq - 1);
+	}
+}
+
+
+static void hw_flow_control (struct s3c4530_serial *info, int cmd)
+{
+    volatile struct s3c4530_usart_regs *uart = info->usart;
+	
+	if (cmd) {
+		uart->cr |=  U_HFEN;
+		info->cts_state = 0;
+	} else {
+		uart->cr &= ~U_HFEN;
+		info->cts_state = 1;
+	}
+}
+
+static _INLINE_ void fifo_reset(struct s3c4530_serial *info)
+{
+    info->usart->cr |= (U_TFRST | U_RFRST);
+}
+
+static _INLINE_ void fifo_init(struct s3c4530_serial *info)
+{
+    info->usart->cr |= (U_TFEN | U_RFEN);
+    switch (RX_FIFO_LEVEL) {
+	    case	 1 :	info->usart->cr |= U_RFTL1;	break;
+	    case	 8 :	info->usart->cr |= U_RFTL8;	break;
+	    case	18 :	info->usart->cr |= U_RFTL18;	break;
+	    case	28 :	info->usart->cr |= U_RFTL28;	break;
+	}
+    switch (TX_FIFO_LEVEL) {
+	    case	 8 :	info->usart->cr |= U_TFTL8;	break;
+	    case	16 :	info->usart->cr |= U_TFTL16;	break;
+	    case	24 :	info->usart->cr |= U_TFTL24;	break;
+	    case	30 :	info->usart->cr |= U_TFTL30;	break;
+	}    
+}
+
+static inline int serial_paranoia_check(struct s3c4530_serial *info,
+					dev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+    static const char *badmagic =
+		"Warning: bad magic number for serial struct (%d, %d) in %s\n";
+    static const char *badinfo =
+		"Warning: null s3c4530_serial struct for (%d, %d) in %s\n";
+
+    if  (!info) {
+	printk(badinfo, MAJOR(device), MINOR(device), routine);
+	return 1;
+	}
+    if  (info->magic != SERIAL_MAGIC) {
+	printk(badmagic, MAJOR(device), MINOR(device), routine);
+	return 1;
+	}
+#endif
+    return 0;
+}
+
+
+/* Sets or clears DTR on the requested line */
+static inline void set_dtr(struct s3c4530_serial *info, int set)
+{
+#if !defined(CONFIG_BOARD_EVS3C4530HEI)
+    volatile struct s3c4530_usart_regs *uart = info->usart;
+
+    if (set) uart->cr |=  U_DTR;
+    else     uart->cr &= ~U_DTR;
+#endif
+}
+
+/* Sets or clears RTS on the requested line */
+/* Note: rts is only directly controllable if hw flow
+ * control is not enabled */
+static inline void set_rts(struct s3c4530_serial *info, int set)
+{
+    volatile struct s3c4530_usart_regs *uart = info->usart;
+
+    if (set) uart->cr |=  U_RTS;
+    else     uart->cr &= ~U_RTS;
+}
+
+/* Reads value of serial status signals */
+static unsigned int get_status(struct s3c4530_serial *info)
+{
+    volatile struct s3c4530_usart_regs *uart = info->usart;
+    unsigned int bits = 0;
+
+    if (uart->csr | U_CTS) bits |= TIOCM_CTS;
+	if (uart->cr  | U_RTS) bits |= TIOCM_RTS;
+
+#if defined(CONFIG_BOARD_EVS3C4530HEI)
+	/* These signals are not connected on the HEI: */
+	bits |= (TIOCM_DTR | TIOCM_DSR | TIOCM_CD);
+#else
+	if (uart->cr  | U_DTR) bits |= TIOCM_DTR;
+    if (uart->csr | U_DSR) bits |= TIOCM_DSR;
+    if (uart->csr | U_DCD) bits |= TIOCM_CD;
+#endif    
+
+	return (bits);
+}
+
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+    struct s3c4530_serial *info = (struct s3c4530_serial *) tty->driver_data;
+    unsigned long flags = 0;
+
+    if	(serial_paranoia_check(info, tty->device, "rs_stop"))
+    	return;
+
+    save_flags(flags);
+    cli();
+    tx_stop(info->usart);
+    rx_stop(info->usart);
+    restore_flags(flags);
+}
+
+static void rs_put_char(struct s3c4530_serial *info, char ch)
+{
+    unsigned long flags = 0;
+
+    save_flags(flags);
+    cli();
+    xmit_char(info, ch);
+    restore_flags(flags);
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+    struct s3c4530_serial *info = (struct s3c4530_serial *) tty->driver_data;
+    unsigned long flags = 0;
+
+    if  (serial_paranoia_check(info, tty->device, "rs_start"))
+	return;
+
+    save_flags(flags);
+    cli();
+    rx_start(info->usart, info->use_ints);
+    tx_start(info->usart, info->use_ints);
+    restore_flags(flags);
+}
+
+/* Drop into either the boot monitor or kadb upon receiving a break
+ * from keyboard/console input.
+ */
+static void batten_down_hatches(void)
+{
+#if 0
+	/* If we are doing kadb, we call the debugger
+	 * else we just drop into the boot monitor.
+	 * Note that we must flush the user windows
+	 * first before giving up control.
+	 */
+	if ((((unsigned long) linux_dbvec) >= DEBUG_FIRSTVADDR) &&
+		(((unsigned long) linux_dbvec) <= DEBUG_LASTVADDR))
+		sp_enter_debugger();
+	else
+		panic("s3c4530_serial: batten_down_hatches");
+	return;
+#endif
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ *
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assembly code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+ 
+static _INLINE_ void rs_sched_event(struct s3c4530_serial *info, int event)
+{
+    info->event |= 1 << event;
+    queue_task_irq_off(&info->tqueue, &tq_s3c4530_serial);
+    mark_bh(SERIAL_BH);
+}
+
+extern void breakpoint(void);	/* For the KGDB frame character */
+
+/*  
+ *	This is the serial driver's generic interrupt routine
+ */ 
+static void rs_interrupt0Tx(int irq, void *dev_id, struct pt_regs *regs)
+{
+    rs_interrupt_Tx(&s3c4530_info[0]);
+}
+
+static void rs_interrupt0Rx(int irq, void *dev_id, struct pt_regs *regs)
+{
+    rs_interrupt_Rx(&s3c4530_info[0]);
+}
+
+static void rs_interrupt1Tx(int irq, void *dev_id, struct pt_regs *regs)
+{
+    rs_interrupt_Tx(&s3c4530_info[1]);
+}
+
+static void rs_interrupt1Rx(int irq, void *dev_id, struct pt_regs *regs)
+{
+    rs_interrupt_Rx(&s3c4530_info[1]);
+}
+
+static void rs_interrupt_Tx(struct s3c4530_serial *info)
+{
+    unsigned int count, status;
+
+    if  (info->x_char) {
+        info->usart->thr = info->x_char;
+        info->x_char = 0;
+        return;
+	}
+
+    if  ((info->xmit_cnt <= 0) || info->tty->stopped || info->tty->hw_stopped ) {
+		tx_stop(info->usart);
+		return;
+	}
+
+    for (count = TX_FIFO_DEPTH; count > 0; --count) {
+		status = info->usart->csr;
+		if (status & U_TFFUL) {
+			handle_status (info, U_TFFUL);
+			break;
+		} else {
+			info->usart->thr = info->xmit_buf[info->xmit_tail++];
+			info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+			if (--info->xmit_cnt <= 0) 
+				break;
+		}
+	}
+	
+    if (info->xmit_cnt < WAKEUP_CHARS)
+    	rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+    if (info->xmit_cnt <= 0)
+        tx_stop(info->usart);
+    return;
+}
+
+static void rs_interrupt_Rx(struct s3c4530_serial *info)
+{
+    struct tty_struct *tty = info->tty;
+    volatile struct s3c4530_usart_regs *usart = info->usart;
+    unsigned int count, status;
+    
+    if	(!info || !tty || (!(info->flags & S_INITIALIZED)))
+		return;
+
+    if	((tty->flip.count + RX_FIFO_DEPTH) >= TTY_FLIPBUF_SIZE)
+		queue_task_irq_off(&tty->flip.tqueue, &tq_timer);
+
+    count = RX_FIFO_DEPTH;
+    do {
+		status = usart->csr;
+		if (status & U_RFEMT)
+			break;
+
+		if (status & U_RDV)
+			*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		else {
+			if (status & U_RFFUL) {
+				*tty->flip.flag_buf_ptr = TTY_NORMAL;
+				handle_status (info, U_RFFUL);
+			}
+			if (status & U_OER) {
+				*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+				handle_status (info, U_OER);
+			}
+			if 	(status & U_BSD) {
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+				handle_status (info, U_BSD);
+			}
+			if	(status & U_PER) {
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+				handle_status (info, U_PER);
+			}
+			if 	(status & U_FER) {
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+				handle_status (info, U_FER);
+			}
+			if 	(status & U_CCD) {
+				*tty->flip.flag_buf_ptr = TTY_NORMAL;
+				handle_status (info, U_CCD);
+			}
+		}
+		*tty->flip.char_buf_ptr++ = usart->rhr & 0xFF;
+		tty->flip.flag_buf_ptr++;
+		tty->flip.count++;
+	} while ((--count > 0) && (status & U_RDV));
+
+    if (status & (U_RFOV | U_E_RxTO))
+		handle_status (info, (U_RFOV | U_E_RxTO));
+	
+    queue_task_irq_off(&tty->flip.tqueue, &tq_timer);	
+}
+
+static _INLINE_ void handle_status ( struct s3c4530_serial *info, unsigned int status )
+{
+    if (status & U_TFFUL) {
+		return;				/* FIXME - do something */
+	}
+    if (status & U_RFFUL) {
+		info->usart->cr |= U_SBR;	
+	}
+    if (status & U_BSD) {
+		batten_down_hatches();
+	}
+    info->usart->csr |= status;
+}
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+    run_task_queue(&tq_s3c4530_serial);
+}
+
+static void do_softint(void *private_)
+{
+    struct s3c4530_serial *info = (struct s3c4530_serial *) private_;
+    struct tty_struct *tty;
+
+    tty = info->tty;
+    if  ( !tty )	return;
+
+    if  (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+	if  ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) 
+	    (tty->ldisc.write_wakeup) (tty);
+	wake_up_interruptible(&tty->write_wait);
+	}
+}
+
+/*
+ * This routine is called from the scheduler tqueue when the interrupt
+ * routine has signalled that a hangup has occurred.  The path of
+ * hangup processing is:
+ *
+ * 	serial interrupt routine -> (scheduler tqueue) ->
+ * 	do_serial_hangup() -> tty->hangup() -> rs_hangup()
+ *
+ */
+static void do_serial_hangup(void *private_)
+{
+    struct s3c4530_serial *info = (struct s3c4530_serial *) private_;
+    struct tty_struct *tty;
+
+    tty = info->tty;
+    if (!tty)	return;
+    tty_hangup(tty);
+}
+
+static u_32 calcCD(u_32 br)
+{
+	int divisor;
+
+	/* naive method - also wrong: */
+    /* return ((UART_CLOCK / br)<<4); */
+
+	/* effectively add 1/2 LSB before dividing */
+	divisor = (ARM_CLK/16)/ br + 1;
+	divisor = (divisor / 2) - 1;
+	
+	return (divisor << 4);
+}
+
+static _INLINE_ void uart_speed(struct s3c4530_serial *info, unsigned int cflag)
+{
+    unsigned baud = info->baud;
+    info->usart->brgr = calcCD(baud);
+}
+
+static int startup(struct s3c4530_serial *info)
+{
+    unsigned long flags;
+
+    if 	(info->flags & S_INITIALIZED)
+	return 0;
+
+    if 	(!info->xmit_buf) {
+	info->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL);
+	if 	(!info->xmit_buf)
+		return -ENOMEM;
+	}
+
+    save_flags(flags);    cli();
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttyS%d (irq %d)...\n", info->line, info->irq);
+#endif
+
+    /*
+     * Clear the FIFO buffers and disable them
+     * (they will be reenabled in change_speed())
+     */
+
+//    fifo_reset(info);    OZH
+
+    /*
+     * Now, initialize the UART 
+     */ 
+         
+    info->usart->cr = 0; 
+    if (info->tty->termios->c_cflag & CBAUD) {
+		info->usart->cr = U_IRQ_TMODE | U_IRQ_RMODE;
+		set_dtr (info, 1);
+		set_rts (info, 1);
+		fifo_init(info);
+	}
+    info->usart->ier = 0;		/* disable all interrupts */
+    
+    if (info->tty)	
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+    info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+
+    /*
+     * and set the speed of the serial port
+     */
+
+    change_speed(info);
+    info->flags |= S_INITIALIZED;
+    restore_flags(flags);
+    return 0;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct s3c4530_serial *info)
+{
+    unsigned long flags;
+	
+    tx_stop(info->usart);
+    rx_stop(info->usart);	/* All off! */
+    if 	(!(info->flags & S_INITIALIZED))
+	return;
+
+#ifdef SERIAL_DEBUG_OPEN
+    printk("Shutting down serial port %d (irq %d)....\n", info->line,
+		   info->irq);
+#endif
+
+    save_flags(flags);    cli();		/* Disable interrupts */
+
+    if 	(info->xmit_buf) {
+    	free_page((unsigned long) info->xmit_buf);
+	info->xmit_buf = 0;
+	}
+
+    if 	(info->tty)
+	set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+    info->flags &= ~S_INITIALIZED;
+    restore_flags(flags);
+}
+
+
+
+static s3c_baud_table_t baud_table[] = {
+	{      0, B0 },
+	{     50, B50 },
+	{     75, B75 },
+	{    110, B110 },
+	{    134, B134 },
+	{    150, B150 },
+	{    200, B200 },
+	{    300, B300 },
+	{    600, B600 },
+	{   1200, B1200 },
+	{   1800, B1800 },
+	{   2400, B2400 },
+	{   4800, B4800 },
+	{   9600, B9600 },
+	{  19200, B19200 },
+	{  38400, B38400 },
+	{  57600, B57600 },
+	{ 115200, B115200 },
+	{ 230400, B230400 },
+	{      -1, -1 }
+};
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void change_speed(struct s3c4530_serial *info)
+{
+    unsigned cflag;
+    int      table_index;
+
+    if 	(!info->tty || !info->tty->termios)
+	return;
+    cflag = info->tty->termios->c_cflag;
+
+    tx_stop(info->usart);
+    rx_stop(info->usart);
+
+	/* calculate table index: */
+    table_index = cflag & CBAUD;
+    if 	(table_index & CBAUDEX)	{
+    	table_index &= ~CBAUDEX; 		 /* remove CBAUDEX bit */
+		table_index += CBAUD & ~CBAUDEX; /* add high rate offset */
+	}
+
+    info->baud = baud_table[table_index].rate;
+    uart_speed(info, cflag);
+    
+    switch  (cflag & CSIZE) {
+	    case CS5: info->usart->cr &= U_WL5; break;
+	    case CS6: info->usart->cr |= U_WL6; break;
+	    case CS7: info->usart->cr |= U_WL7; break;
+	    case CS8: info->usart->cr |= U_WL8; break;
+	    }
+    if (cflag & CSTOPB)
+	    info->usart->cr |= U_STB;
+	    
+    if (cflag & PARENB) {
+	    if	    (!(cflag & PARODD))
+		    info->usart->cr |= U_EVEN_PMD;
+	    else    info->usart->cr |= U_ODD_PMD;
+	    }
+	    
+    if (cflag & CRTSCTS) {
+		hw_flow_control (info, 1);
+
+		/* The 4530 does not pass DTR to the connector */
+		/* info->usart->cr |= (U_HFEN | U_DTR | U_RTS); */
+
+	    if	 ( (unsigned int)info->usart == (unsigned int)USART1_BASE )
+		 *(volatile unsigned int *)IOPCON1 |= 0x18;
+	    else *(volatile unsigned int *)IOPCON1 |= 0xC0;
+	    
+	    }
+	    
+    if (cflag & ( IXON | IXOFF)) {
+	    info->usart->cr |= U_SFEN;
+	    info->usart->ucc1 = ( START_CHAR(info->tty)<<24 ) | (START_CHAR(info->tty)<<16) | 
+				( STOP_CHAR (info->tty)<<8 )  |  STOP_CHAR (info->tty);
+	    info->usart->ucc2 = ( START_CHAR(info->tty)<<24 ) | (START_CHAR(info->tty)<<16) |
+				( STOP_CHAR (info->tty)<<8 )  |  STOP_CHAR (info->tty);
+	    }
+	
+    tx_start(info->usart, info->use_ints);
+    rx_start(info->usart, info->use_ints);
+
+    return;
+}
+
+static _INLINE_ void xmit_char(struct s3c4530_serial *info, char ch)
+{
+    while   (info->usart->csr & U_TFFUL);
+    info->usart->thr = ch;
+}
+
+static void rs_set_ldisc(struct tty_struct *tty)
+{
+    struct s3c4530_serial *info = (struct s3c4530_serial *) tty->driver_data;
+
+    if  (serial_paranoia_check(info, tty->device, "rs_set_ldisc"))
+	return;
+
+    info->is_cons = (tty->termios->c_line == N_TTY);
+
+    printk("ttyS%d console mode %s\n", info->line, info->is_cons ? "on" : "off");
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+    struct s3c4530_serial *info = (struct s3c4530_serial *) tty->driver_data;
+    unsigned long flags;
+
+    if  (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
+	return;
+	
+    if  (!info->use_ints) {
+	for (;;) {
+	    if  (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !info->xmit_buf) 
+		return;
+	    save_flags(flags);	    cli();
+	    tx_start(info->usart, info->use_ints);
+	    xmit_char(info, info->xmit_buf[info->xmit_tail++]);
+	    info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+	    info->xmit_cnt--;
+	    }
+	} 
+    else {
+	if  (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !info->xmit_buf) 
+	    return;
+	save_flags(flags);	cli();
+	tx_start(info->usart, info->use_ints);
+	xmit_char(info, info->xmit_buf[info->xmit_tail++]);
+	info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+	info->xmit_cnt--;
+	}
+    restore_flags(flags);
+}
+
+extern void console_printn(const char *b, int count);
+
+static int rs_write(struct tty_struct *tty, int from_user,
+					const unsigned char *buf, int count)
+{
+    int c, total = 0;
+    struct s3c4530_serial *info = (struct s3c4530_serial *) tty->driver_data;
+    unsigned long flags;
+
+    if  (serial_paranoia_check(info, tty->device, "rs_write"))
+	return 0;
+
+    if  (!tty || !info->xmit_buf || !tmp_buf)
+	return 0;
+
+    save_flags(flags);
+    if (from_user) {
+		down(&tmp_buf_sem);
+		cli();
+		while (1) {
+			c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+							   SERIAL_XMIT_SIZE - info->xmit_head));
+			if  (c <= 0)
+				break;
+
+			memcpy(info->xmit_buf + info->xmit_head, buf, c);
+			info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1);
+			info->xmit_cnt += c;
+			restore_flags(flags);
+			buf += c;
+			count -= c;
+			total += c;
+		}
+		restore_flags(flags);
+ 		up(&tmp_buf_sem);
+
+    } else {
+		cli();
+		while (1) {
+			c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+							   SERIAL_XMIT_SIZE - info->xmit_head));
+			if  (c <= 0)
+				break;
+			memcpy(info->xmit_buf + info->xmit_head, buf, c);
+			info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1);
+			info->xmit_cnt += c;
+			buf += c;
+			count -= c;
+			total += c;
+	    }
+		restore_flags(flags);
+	}
+
+    if  (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
+	if   (!info->use_ints) {
+	     while (info->xmit_cnt) {
+		/* Send char */
+		xmit_char(info, info->xmit_buf[info->xmit_tail++]);
+		info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+		info->xmit_cnt--;
+    		}
+	     } 
+	else {
+	     tx_start(info->usart, info->use_ints);
+	     }
+	} 
+    restore_flags(flags);
+    return total;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+    struct s3c4530_serial *info = (struct s3c4530_serial *) tty->driver_data;
+    int ret;
+
+    if  (serial_paranoia_check(info, tty->device, "rs_write_room"))
+	return 0;
+    ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
+    if  (ret < 0)
+	ret = 0;
+    return ret;
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+    struct s3c4530_serial *info = (struct s3c4530_serial *) tty->driver_data;
+
+    if  (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+	return 0;
+    return info->xmit_cnt;
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+    unsigned long flags;
+    struct s3c4530_serial *info = (struct s3c4530_serial *) tty->driver_data;
+
+    if  (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+	return;
+    save_flags(flags);    cli();
+    info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+    restore_flags(flags);
+    wake_up_interruptible(&tty->write_wait);
+    if  ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) 
+	(tty->ldisc.write_wakeup) (tty);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ *
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct *tty)
+{
+    struct s3c4530_serial *info = (struct s3c4530_serial *) tty->driver_data;
+    unsigned int flags;
+
+#ifdef SERIAL_DEBUG_THROTTLE
+    char buf[64];
+
+    printk("throttle %s: %d\n", tty_name(tty, buf),
+		   tty->ldisc.chars_in_buffer(tty));
+#endif
+
+    if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+		return;
+
+    if (I_IXOFF(tty))
+		info->x_char = STOP_CHAR(tty);
+
+    /* Turn off RTS line (do this atomically) */
+    if (tty->termios->c_cflag & CRTSCTS) {
+		save_flags(flags);
+		cli();
+		set_rts (info, 0);
+		restore_flags(flags);
+	}
+}
+
+static void rs_unthrottle(struct tty_struct *tty)
+{
+    struct s3c4530_serial *info = (struct s3c4530_serial *) tty->driver_data;
+    unsigned int flags;
+#ifdef SERIAL_DEBUG_THROTTLE
+    char buf[64];
+
+    printk("unthrottle %s: %d\n", tty_name(tty, buf),
+    	   tty->ldisc.chars_in_buffer(tty));
+#endif
+
+    if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+		return;
+
+    if (I_IXOFF(tty)) {
+	if (info->x_char)
+	    info->x_char = 0;
+	else
+	    info->x_char = START_CHAR(tty);
+	}
+
+    /* Assert RTS line (do this atomically) */
+    if (tty->termios->c_cflag & CRTSCTS) {
+		save_flags(flags);
+		cli();
+		set_rts (info, 1);
+		restore_flags(flags);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int get_serial_info(struct s3c4530_serial *info,
+			   struct serial_struct *retinfo)
+{
+    struct serial_struct tmp;
+
+    if  (!retinfo)
+	return -EFAULT;
+    memset(&tmp, 0, sizeof(tmp));
+    tmp.type = info->type;
+    tmp.line = info->line;
+    tmp.irq = info->irq;
+    tmp.port = info->port;
+    tmp.flags = info->flags;
+    tmp.baud_base = info->baud_base;
+    tmp.close_delay = info->close_delay;
+    tmp.closing_wait = info->closing_wait;
+    tmp.custom_divisor = info->custom_divisor;
+    memcpy_tofs(retinfo, &tmp, sizeof(*retinfo));
+    return 0;
+}
+
+static int set_serial_info(struct s3c4530_serial *info,
+			   struct serial_struct *new_info)
+{
+    struct serial_struct new_serial;
+    struct s3c4530_serial old_info;
+    int retval = 0;
+
+    if  (!new_info)
+    	return -EFAULT;
+    memcpy_fromfs(&new_serial, new_info, sizeof(new_serial));
+    old_info = *info;
+
+    if  (!suser()) {
+	if	((new_serial.baud_base != info->baud_base) 	||
+		 (new_serial.type != info->type) 		||
+	         (new_serial.close_delay != info->close_delay) 	||
+		 ((new_serial.flags & ~S_USR_MASK) 		!=
+		 (info->flags & ~S_USR_MASK))) return -EPERM;
+	info->flags = ((info->flags & ~S_USR_MASK) |
+		      (new_serial.flags & S_USR_MASK));
+	info->custom_divisor = new_serial.custom_divisor;
+	goto check_and_exit;
+	}
+
+    if  (info->count > 1)
+	return -EBUSY;
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+    info->baud_base = new_serial.baud_base;
+    info->flags = ((info->flags & ~S_FLAGS) | (new_serial.flags & S_FLAGS));
+    info->type = new_serial.type;
+    info->close_delay = new_serial.close_delay;
+    info->closing_wait = new_serial.closing_wait;
+
+check_and_exit:
+    retval = startup(info);
+    return retval;
+}
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space.
+ */
+static int get_lsr_info(struct s3c4530_serial *info, unsigned int *value)
+{
+    unsigned char status;
+
+    cli();
+    status = (info->usart->csr & U_CTS) ? 1 : 0;
+    sti();
+    put_user(status, value);
+    return 0;
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void send_break(struct s3c4530_serial *info, int duration)
+{
+    current->state = TASK_INTERRUPTIBLE;
+    cli();
+    info->usart->cr |= U_SBR;
+    schedule_timeout(info->close_delay);
+    info->usart->cr &= (~U_SBR);
+    sti();
+}
+
+static int rs_ioctl(struct tty_struct *tty, struct file *file,
+					unsigned int cmd, unsigned long arg)
+{
+	int error;
+	struct s3c4530_serial *info = (struct s3c4530_serial *) tty->driver_data;
+	unsigned int val;
+	int retval;
+
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+		(cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) &&
+		(cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+			return -EIO;
+	}
+
+	switch (cmd) {
+	case TCSBRK:				/* SVID version: non-zero arg --> no break */
+		retval = tty_check_change(tty);
+		if (retval)
+			return retval;
+		tty_wait_until_sent(tty, 0);
+		if (!arg)
+			send_break(info, HZ / 4);	/* 1/4 second */
+		return 0;
+	case TCSBRKP:				/* support for POSIX tcsendbreak() */
+		retval = tty_check_change(tty);
+		if (retval)
+			return retval;
+		tty_wait_until_sent(tty, 0);
+		send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
+		return 0;
+	case TIOCGSOFTCAR:
+		error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
+
+		if (error)
+			return error;
+		put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
+		return 0;
+	case TIOCSSOFTCAR:
+		arg = get_user(arg, (unsigned long *) arg);
+		tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
+		return 0;
+	case TIOCGSERIAL:
+		error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(struct serial_struct));
+		if (error)
+			return error;
+		return get_serial_info(info, (struct serial_struct *) arg);
+	case TIOCSSERIAL:
+		return set_serial_info(info, (struct serial_struct *) arg);
+	case TIOCSERGETLSR:		/* Get line status register */
+		error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(unsigned int));
+		if (error)
+			return error;
+		else
+			return get_lsr_info(info, (unsigned int *) arg);
+
+	case TIOCSERGSTRUCT:
+		error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(struct s3c4530_serial));
+		if (error)
+			return error;
+		memcpy_tofs((struct s3c4530_serial *) arg, info,
+			sizeof(struct s3c4530_serial));
+		return 0;
+
+
+	case TIOCMGET:	/* get all modem bits */
+		if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+			sizeof(unsigned int))))
+			return(error);
+		val = get_status(info);
+		put_user(val, (unsigned int *) arg);
+		break;
+
+	case TIOCMBIS:	/* modem bits set */
+		if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+								 sizeof(unsigned int))))
+			return(error);
+		
+		get_user(val, (unsigned int *) arg);
+		
+		if (val & TIOCM_RTS) set_rts(info, 1);
+		if (val & TIOCM_DTR) set_dtr(info, 1);
+		break;
+
+	case TIOCMBIC:	/* modem bits clear */
+		if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+								 sizeof(unsigned int))))
+			return(error);
+		get_user(val, (unsigned int *) arg);
+			
+		if (val & TIOCM_RTS) set_rts(info, 0);
+		if (val & TIOCM_DTR) set_dtr(info, 0);
+		break;
+
+	case TIOCMSET:	/* set all modem bits */
+		if ((error = verify_area(VERIFY_WRITE, (void *) arg,
+								 sizeof(unsigned int))))
+			return(error);
+		get_user(val, (unsigned int *) arg);
+
+		set_rts (info, ((val & TIOCM_RTS) ? 1 : 0) );
+		set_dtr (info, ((val & TIOCM_DTR) ? 1 : 0) );
+		break;
+
+	case TCSETS:	
+	  /*
+		* take care if the speed change, leave rest to termios by falling through
+		*/
+	  handle_termios_tcsets((struct termios *)arg, info);
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static void handle_termios_tcsets(  struct termios *ptermios, 
+				    struct s3c4530_serial *pinfo)
+{
+    if  (pinfo->tty->termios->c_cflag != ptermios->c_cflag) {
+	pinfo->tty->termios->c_cflag = ptermios->c_cflag;
+	}
+    change_speed(pinfo);
+}
+	  
+static void rs_set_termios( struct tty_struct *tty,
+			    struct termios *old_termios)
+{
+    struct s3c4530_serial *info = (struct s3c4530_serial *) tty->driver_data;
+
+    if (tty->termios->c_cflag == old_termios->c_cflag)
+		return;
+
+    change_speed(info);
+
+	/* Handle turning off CRTSCTS */
+    if ((old_termios->c_cflag & CRTSCTS) &&
+		!(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ *
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * S structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file *filp)
+{
+    struct s3c4530_serial *info = (struct s3c4530_serial *) tty->driver_data;
+    unsigned long flags;
+
+    if  (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+	return;
+
+    save_flags(flags);  cli();
+
+    if  (tty_hung_up_p(filp)) {
+	restore_flags(flags);
+	return;
+	}
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_close ttyS%d, count = %d\n", info->line, info->count);
+#endif
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  Info->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+			   "info->count is %d\n", info->count);
+		info->count = 1;
+	}
+	if (--info->count < 0) {
+		printk("rs_close: bad serial port count for ttyS%d: %d\n",
+			   info->line, info->count);
+		info->count = 0;
+	}
+	if (info->count) {
+		restore_flags(flags);
+		return;
+	}
+	// closing port so disable interrupts
+	set_ints_mode(info, 0);
+
+	info->flags |= S_CLOSING;
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & S_NORMAL_ACTIVE)
+		info->normal_termios = *tty->termios;
+	if (info->flags & S_CALLOUT_ACTIVE)
+		info->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != S_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (tty->ldisc.num != tty_ldiscs[N_TTY].num) {
+		if (tty->ldisc.close)
+			(tty->ldisc.close) (tty);
+		tty->ldisc = tty_ldiscs[N_TTY];
+		tty->termios->c_line = N_TTY;
+		if (tty->ldisc.open)
+			(tty->ldisc.open) (tty);
+	}
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+/*			current->timeout = jiffies + info->close_delay;  */
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(S_NORMAL_ACTIVE | S_CALLOUT_ACTIVE | S_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	restore_flags(flags);
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void rs_hangup(struct tty_struct *tty)
+{
+    struct s3c4530_serial *info = (struct s3c4530_serial *) tty->driver_data;
+
+    if	(serial_paranoia_check(info, tty->device, "rs_hangup"))
+	return;
+
+    rs_flush_buffer(tty);
+    shutdown(info);
+    info->event = 0;
+    info->count = 0;
+    info->flags &= ~(S_NORMAL_ACTIVE | S_CALLOUT_ACTIVE);
+    info->tty = 0;
+    wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file *filp,
+						   struct s3c4530_serial *info)
+{
+	unsigned long flags;
+/*	struct wait_queue wait = { current, NULL }; */
+	DECLARE_WAITQUEUE(wait, current);
+	int retval;
+	int do_clocal = 0;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (info->flags & S_CLOSING) {
+		interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		if (info->flags & S_HUP_NOTIFY)
+			return -EAGAIN;
+		else
+			return -ERESTARTSYS;
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & S_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+			(info->flags & S_SESSION_LOCKOUT) &&
+			(info->session != current->session)) return -EBUSY;
+		if ((info->flags & S_CALLOUT_ACTIVE) &&
+			(info->flags & S_PGRP_LOCKOUT) &&
+			(info->pgrp != current->pgrp)) return -EBUSY;
+		info->flags |= S_CALLOUT_ACTIVE;
+		return 0;
+	}
+
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & S_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= S_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & S_CALLOUT_ACTIVE) {
+		if (info->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, info->count is dropped by one, so that
+	 * rs_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready before block: ttyS%d, count = %d\n",
+		   info->line, info->count);
+#endif
+	info->count--;
+	info->blocked_open++;
+	while (1) {
+		save_flags(flags);
+		cli();
+		if (!(info->flags & S_CALLOUT_ACTIVE))
+			set_dtr(info, 1);
+		restore_flags(flags);
+		current->state = TASK_INTERRUPTIBLE;
+		if (tty_hung_up_p(filp) || !(info->flags & S_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & S_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(info->flags & S_CALLOUT_ACTIVE) &&
+			!(info->flags & S_CLOSING) && do_clocal)
+			break;
+		if (signal_pending(current)) {
+/*		if (current->signal & ~current->blocked) {  */
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef SERIAL_DEBUG_OPEN
+		printk("block_til_ready blocking: ttyS%d, count = %d\n",
+			   info->line, info->count);
+#endif
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&info->open_wait, &wait);
+	if (!tty_hung_up_p(filp))
+		info->count++;
+	info->blocked_open--;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready after blocking: ttyS%d, count = %d\n",
+		   info->line, info->count);
+#endif
+	if (retval)
+		return retval;
+	info->flags |= S_NORMAL_ACTIVE;
+	return 0;
+}
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its S structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+int rs_open(struct tty_struct *tty, struct file *filp)
+{
+	struct s3c4530_serial *info;
+	int retval, line;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+
+	/* check if line is sane */
+	if (line < 0 || line >= USART_CNT)
+		return -ENODEV;
+
+	info = &s3c4530_info[line];
+
+	if (serial_paranoia_check(info, tty->device, "rs_open"))
+		return -ENODEV;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+		   info->count);
+#endif
+	info->count++;
+	tty->driver_data = info;
+	info->tty = tty;
+
+	/*
+	 * Start up serial port
+	 */
+	set_ints_mode(info, 1);
+	
+	retval = startup(info);
+	if (retval)
+		return retval;
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("rs_open returning after block_til_ready with %d\n",
+			   retval);
+#endif
+		return retval;
+	}
+
+	if ((info->count == 1) && (info->flags & S_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->normal_termios;
+		else
+			*tty->termios = info->callout_termios;
+		change_speed(info);
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open ttyS%d successful...\n", info->line);
+#endif
+	return 0;
+}
+
+static struct irqaction irq_usart0Tx =
+    { rs_interrupt0Tx, 0, 0, "S3C4530_uart0_Tx", NULL, NULL };
+static struct irqaction irq_usart0Rx =
+    { rs_interrupt0Rx, 0, 0, "S3C4530_uart0_Rx", NULL, NULL };
+	
+static struct irqaction irq_usart1Tx =
+    { rs_interrupt1Tx, 0, 0, "S3C4530_uart1_Tx", NULL, NULL };
+static struct irqaction irq_usart1Rx =
+    { rs_interrupt1Rx, 0, 0, "S3C4530_uart1_Rx", NULL, NULL };
+
+extern int setup_arm_irq(int, struct irqaction *);
+
+static void interrupts_init(void)
+{
+    setup_arm_irq(_URTTx0, &irq_usart0Tx);
+    setup_arm_irq(_URTRx0, &irq_usart0Rx);
+    setup_arm_irq(_URTTx1, &irq_usart1Tx);
+    setup_arm_irq(_URTRx1, &irq_usart1Rx);
+}
+
+static void show_serial_version(void)
+{
+    printk("S3C4530 UART driver Version 3.3 <www.ArcturusNetworks.com>\n");
+}
+
+/* rs_init inits the driver */
+static int __init rs_s3c4530_init(void)
+{
+    int flags, i;
+    struct s3c4530_serial *info;
+
+    /* Setup base handler, and timer table. */
+    init_bh(SERIAL_BH, do_serial_bh);
+
+    show_serial_version();
+
+    /* Initialize the tty_driver structure */
+
+    /* set the tty_struct pointers to NULL to let the layer */
+    /* above allocate the structs. */
+    for	(i=0; i < USART_CNT; i++)
+		serial_table[i] = NULL;
+		
+    memset(&serial_driver, 0, sizeof(struct tty_driver));
+
+    serial_driver.magic = TTY_DRIVER_MAGIC;
+    serial_driver.name = "ttyS";
+    serial_driver.major = TTY_MAJOR;
+    serial_driver.minor_start = 64;
+    serial_driver.num = 2;
+    serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+    serial_driver.subtype = SERIAL_TYPE_NORMAL;
+    serial_driver.init_termios = tty_std_termios;
+    serial_driver.init_termios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
+    serial_driver.init_termios.c_cflag |= default_console_baud.cflag;
+    serial_driver.flags = TTY_DRIVER_REAL_RAW;
+    serial_driver.refcount = &serial_refcount;
+    serial_driver.table = serial_table;
+    serial_driver.termios = serial_termios;
+    serial_driver.termios_locked = serial_termios_locked;
+
+    serial_driver.open = rs_open;
+    serial_driver.close = rs_close;
+    serial_driver.write = rs_write;
+    serial_driver.flush_chars = rs_flush_chars;
+    serial_driver.write_room = rs_write_room;
+    serial_driver.chars_in_buffer = rs_chars_in_buffer;
+    serial_driver.flush_buffer = rs_flush_buffer;
+    serial_driver.ioctl = rs_ioctl;
+    serial_driver.throttle = rs_throttle;
+    serial_driver.unthrottle = rs_unthrottle;
+    serial_driver.set_termios = rs_set_termios;
+    serial_driver.stop = rs_stop;
+    serial_driver.start = rs_start;
+    serial_driver.hangup = rs_hangup;
+    serial_driver.set_ldisc = rs_set_ldisc;
+
+    /*
+     * The callout device is just like normal device except for
+     * major number and the subtype code.
+     */
+    callout_driver = serial_driver;
+    callout_driver.name = "cua";
+    callout_driver.major = TTYAUX_MAJOR;
+    callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+
+    if (tty_register_driver(&serial_driver))
+		panic("Couldn't register serial driver\n");
+    if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+
+    save_flags(flags);
+    cli();
+    for (i = 0; i < USART_CNT; i++) {
+		info = &s3c4530_info[i];
+		info->magic = SERIAL_MAGIC;
+		info->usart = usarts[i];
+		info->tty = 0;
+		info->irqmask = (i) ? IC_UARTRxE1 : IC_UARTRxE0;
+		info->irq = (i) ? _URTRx1 : _URTRx0;
+		info->port = (i) ? 1 : 2;
+		info->line = i;
+
+#if defined(CONFIG_CONSOLE_NULL)
+        info->is_cons = 0;
+#else
+		if (i == console_number)
+			info->is_cons = 1;
+#endif
+		set_ints_mode(info, 0);
+		/* info->custom_divisor = 16; */ /* unused? */
+		info->custom_divisor = 0;
+		info->close_delay = 50;
+		info->closing_wait = 3000;
+		info->cts_state = 1;
+		info->x_char = 0;
+		info->event = 0;
+		info->count = 0;
+		info->blocked_open = 0;
+		info->tqueue.routine = do_softint;
+		info->tqueue.data = info;
+		info->tqueue_hangup.routine = do_serial_hangup;
+		info->tqueue_hangup.data = info;
+		info->callout_termios = callout_driver.init_termios;
+		info->normal_termios = serial_driver.init_termios;
+		
+		init_waitqueue_head(&info->open_wait);
+		init_waitqueue_head(&info->close_wait);
+		
+		printk("%s%d: at 0x%p (irq = %d)", serial_driver.name, info->line,
+			   info->usart, info->irq);
+		printk(" is a builtin Samsung s3c4530 UART\n");
+	}
+
+    interrupts_init();
+
+    restore_flags(flags);
+    return 0;
+}
+
+module_init(rs_s3c4530_init);
+
+
+/*
+ * ------------------------------------------------------------
+ * Serial console driver
+ * ------------------------------------------------------------
+ */
+
+static kdev_t s3c4530_console_device(struct console *);
+static int s3c4530_console_setup(struct console *, char *);
+static void s3c4530_console_write (struct console *, const char *, unsigned int );
+static int s3c4530_console_initialized = 0;
+
+static struct console s3c4530_driver = {
+	name:		"ttyS",
+	write:		s3c4530_console_write,
+	device:		s3c4530_console_device,
+//	wait_key:	NULL,
+	setup:		s3c4530_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+/* static void init_console(struct s3c4530_serial *info) */
+static int s3c4530_console_setup(struct console *c, char *p)
+{
+    struct s3c4530_serial *info;
+	int i;
+	int speed = -1;
+
+    info = &s3c4530_info[console_number];
+
+    memset(info, 0, sizeof(struct s3c4530_serial));
+#if   defined(CONFIG_CONSOLE_UARTA)
+    info->usart = (volatile struct s3c4530_usart_regs *) USART0_BASE;
+#elif defined(CONFIG_CONSOLE_UARTB)
+    info->usart = (volatile struct s3c4530_usart_regs *) USART1_BASE;
+#endif
+    info->use_ints = 0;
+    info->cts_state = 1;
+    info->is_cons = 1;
+    info->usart->cr = 0; 
+    info->usart->cr = (U_IRQ_TMODE | U_IRQ_RMODE | U_WL8);
+    fifo_init(info);
+
+
+#if defined(CONFIG_UCBOOTSTRAP)
+	/* If uCbootloader does not have CONSOLE_SPEED defined, */
+	if (sscanf (getbenv("CONSOLE_SPEED"), "%d", &speed) != 1)
+		speed = -1;
+
+#else /* no uCbootstrap */
+
+#if defined(CONFIG_INIT_CONSOLE_SPEED)
+	speed = CONFIG_INIT_CONSOLE_SPEED;
+#endif /* defined(CONFIG_INIT_CONSOLE_SPEED) */
+
+#endif
+
+	/* if console speed has not been overridden from the default: */
+	if (speed != -1) {
+		for (i=0;baud_table[i].rate != -1;i++)
+			if (baud_table[i].rate == speed) {
+				default_console_baud.rate  = speed;
+				default_console_baud.cflag = baud_table[i].cflag;
+				break;
+			}
+	}
+
+	info->baud = default_console_baud.rate;
+
+    info->usart->brgr = calcCD(info->baud);
+    info->usart->ier = 0;
+
+	s3c4530_console_initialized = 1;
+    return 0;
+}
+
+static kdev_t s3c4530_console_device(struct console *c)
+{
+    return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static void s3c4530_console_write (struct console *co, const char *str,
+			   unsigned int count)
+{
+	static struct s3c4530_serial *info;
+
+#if defined(CONFIG_CONSOLE_NULL)
+    return;
+#else
+    info = &s3c4530_info[console_number];
+#endif
+
+    if (!s3c4530_console_initialized)
+		printk ("WARNING: Console used unintialized\n");
+
+    while (count--) {
+		if  (*str == '\n')
+			rs_put_char(info,'\r');
+        rs_put_char(info, *str++ );
+	}
+}
+
+void __init s3c4530_console_init(void)
+{
+    register_console ( &s3c4530_driver );
+}
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff -urN linux-2.4.29/drivers/char/serial_s3c4530.h linux-2.4.29-uc1/drivers/char/serial_s3c4530.h
--- linux-2.4.29/drivers/char/serial_s3c4530.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_s3c4530.h	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,147 @@
+/*
+ * drivers/char/serial-s3c4530.h
+ * 
+ * Serial port driver for the Samsung S3C4530A builtin UARTs
+ *
+ * Copyright (c) 2001-2003  Arcturus Networks Inc.
+ * 	                    by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * Based on: drivers/char/trioserial.h
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *               1998-2003  D. Jeff Dionne <jeff@uClinux.org>
+ * Copyright (c) 1998  The Silver Hammer Group, Ltd.
+ *
+ * Based on: drivers/char/68328serial.h
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _S3C4530_SERIAL_H
+#define _S3C4530_SERIAL_H
+
+#include <linux/config.h>
+#include <asm/page.h>
+#include <asm/arch/hardware.h>
+
+/*
+ * For the close wait times, 0 means wait forever for serial port to
+ * flush its output.  65535 means don't wait at all.
+ */
+#define S_CLOSING_WAIT_INF	0
+#define S_CLOSING_WAIT_NONE	65535
+
+/*
+ * Definitions for S_struct (and serial_struct) flags field
+ */
+#define S_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes 
+				   on the callout port */
+#define S_FOURPORT  0x0002	/* Set OU1, OUT2 per AST Fourport settings */
+#define S_SAK	0x0004	/* Secure Attention Key (Orange book) */
+#define S_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
+
+#define S_SPD_MASK	0x0030
+#define S_SPD_HI	0x0010	/* Use 56000 instead of 38400 bps */
+
+#define S_SPD_VHI	0x0020  /* Use 115200 instead of 38400 bps */
+#define S_SPD_CUST	0x0030  /* Use user-specified divisor */
+
+#define S_SKIP_TEST	0x0040 /* Skip UART test during autoconfiguration */
+#define S_AUTO_IRQ  0x0080 /* Do automatic IRQ during autoconfiguration */
+#define S_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
+#define S_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
+#define S_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
+
+#define S_FLAGS	0x0FFF	/* Possible legal S flags */
+#define S_USR_MASK 0x0430	/* Legal flags that non-privileged
+				 * users can set or reset */
+
+/* Internal flags used only by kernel/chr_drv/serial.c */
+#define S_INITIALIZED	0x80000000 /* Serial port was initialized */
+#define S_CALLOUT_ACTIVE	0x40000000 /* Call out device is active */
+#define S_NORMAL_ACTIVE	0x20000000 /* Normal device is active */
+#define S_BOOT_AUTOCONF	0x10000000 /* Autoconfigure port on bootup */
+#define S_CLOSING		0x08000000 /* Serial port is closing */
+#define S_CTS_FLOW		0x04000000 /* Do CTS flow control */
+#define S_CHECK_CD		0x02000000 /* i.e., CLOCAL */
+
+/* Software state per channel */
+
+/*
+ * This is our internal structure for each serial port's state.
+ * 
+ * Many fields are paralleled by the structure used by the serial_struct
+ * structure.
+ *
+ * For definitions of the flags field, see tty.h
+ */
+
+struct s3c4530_serial {
+	char soft_carrier;  /* Use soft carrier on this channel */
+	char break_abort;   /* Is serial console in, so process brk/abrt */
+#if 0
+	char cons_keyb;     /* Channel runs the keyboard */
+	char cons_mouse;    /* Channel runs the mouse */
+	char kgdb_channel;  /* Kgdb is running on this channel */
+#endif
+	char is_cons;       /* Is this our console. */
+
+	/* We need to know the current clock divisor
+	 * to read the bps rate the chip has currently
+	 * loaded.
+	 */
+	unsigned char clk_divisor;  /* May be 1, 16, 32, or 64 */
+	int baud;
+	int			magic;
+	int			baud_base;
+	int			port;
+	int			irq;
+	int			irqmask;
+	int			flags; 		/* defined in tty.h */
+	int			type; 		/* UART type */
+	int			use_ints;
+	volatile struct s3c4530_usart_regs	*usart;
+	int			cts_state;
+	struct tty_struct 	*tty;
+	int			read_status_mask;
+	int			ignore_status_mask;
+	int			timeout;
+	int			xmit_fifo_size;
+	int			rx_fifo_size;
+	int			custom_divisor;
+	int			x_char;	/* xon/xoff character */
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int			count;	    /* # of fd on device */
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+	unsigned char 		*xmit_buf;
+/*	unsigned char 		*rx_buf;  */
+	int			xmit_head;
+	int			xmit_tail;
+	int			xmit_cnt;
+	struct tq_struct	tqueue;
+	struct tq_struct	tqueue_hangup;
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+};
+
+
+/* typedef to correlate a serial speed with its cflags - type handle: */
+typedef struct
+{
+  int rate;
+  int cflag;
+} s3c_baud_table_t;
+
+
+#define RS_EVENT_WRITE_WAKEUP   0
+#define SERIAL_MAGIC 0x5301
+
+
+#endif /* !(_S3C4530_SERIAL_H) */
diff -urN linux-2.4.29/drivers/char/serial_samsung.c linux-2.4.29-uc1/drivers/char/serial_samsung.c
--- linux-2.4.29/drivers/char/serial_samsung.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/serial_samsung.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,4618 @@
+/*
+ *  linux/drivers/char/serial.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 
+ * 		1998, 1999  Theodore Ts'o
+ *
+ *  Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92.  Now
+ *  much more extensible to support other serial cards based on the
+ *  16450/16550A UART's.  Added support for the AST FourPort and the
+ *  Accent Async board.  
+ *
+ *  set_serial_info fixed to set the flags, custom divisor, and uart
+ * 	type fields.  Fix suggested by Michael K. Johnson 12/12/92.
+ *
+ *  11/95: TIOCMIWAIT, TIOCGICOUNT by Angelo Haritsis <ah@doc.ic.ac.uk>
+ *
+ *  03/96: Modularised by Angelo Haritsis <ah@doc.ic.ac.uk>
+ *
+ *  rs_set_termios fixed to look also for changes of the input
+ *      flags INPCK, BRKINT, PARMRK, IGNPAR and IGNBRK.
+ *                                            Bernd Anhäupl 05/17/96.
+ *
+ *  1/97:  Extended dumb serial ports are a config option now.  
+ *         Saves 4k.   Michael A. Griffith <grif@acm.org>
+ * 
+ *  8/97: Fix bug in rs_set_termios with RTS
+ *        Stanislav V. Voronyi <stas@uanet.kharkov.ua>
+ *
+ *  3/98: Change the IRQ detection, use of probe_irq_o*(),
+ *	  suppress TIOCSERGWILD and TIOCSERSWILD
+ *	  Etienne Lorrain <etienne.lorrain@ibm.net>
+ *
+ *  4/98: Added changes to support the ARM architecture proposed by
+ * 	  Russell King
+ *
+ *  5/99: Updated to include support for the XR16C850 and ST16C654
+ *        uarts.  Stuart MacDonald <stuartm@connecttech.com>
+ *
+ *  8/99: Generalized PCI support added.  Theodore Ts'o
+ * 
+ *  3/00: Rid circular buffer of redundant xmit_cnt.  Fix a
+ *	  few races on freeing buffers too.
+ *	  Alan Modra <alan@linuxcare.com>
+ *
+ *  5/00: Support for the RSA-DV II/S card added.
+ *	  Kiyokazu SUTO <suto@ks-and-ks.ne.jp>
+ * 
+ *  6/00: Remove old-style timer, use timer_list
+ *        Andrew Morton <andrewm@uow.edu.au>
+ *
+ *  7/00: Support Timedia/Sunix/Exsys PCI cards
+ *
+ *  7/00: fix some returns on failure not using MOD_DEC_USE_COUNT.
+ *	  Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * 10/00: add in optional software flow control for serial console.
+ *	  Kanoj Sarcar <kanoj@sgi.com>  (Modified by Theodore Ts'o)
+ *
+ */
+
+//static char *serial_version = "5.05c";
+static char *serial_version = "0.9";
+static char *serial_revdate = "2001-12-27";
+
+/*
+ * Serial driver configuration section.  Here are the various options:
+ *
+ * CONFIG_HUB6
+ *		Enables support for the venerable Bell Technologies
+ *		HUB6 card.
+ *
+ * CONFIG_SERIAL_MANY_PORTS
+ * 		Enables support for ports beyond the standard, stupid
+ * 		COM 1/2/3/4.
+ *
+ * CONFIG_SERIAL_MULTIPORT
+ * 		Enables support for special multiport board support.
+ *
+ * CONFIG_SERIAL_SHARE_IRQ
+ * 		Enables support for multiple serial ports on one IRQ
+ *
+ * CONFIG_SERIAL_DETECT_IRQ
+ *		Enable the autodetection of IRQ on standart ports
+ *
+ * SERIAL_PARANOIA_CHECK
+ * 		Check the magic number for the async_structure where
+ * 		ever possible.
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+
+#undef SERIAL_PARANOIA_CHECK
+#define CONFIG_SERIAL_NOPAUSE_IO
+#define SERIAL_DO_RESTART
+
+#if 0
+/* These defines are normally controlled by the autoconf.h */
+#define CONFIG_SERIAL_MANY_PORTS
+#define CONFIG_SERIAL_SHARE_IRQ
+#define CONFIG_SERIAL_DETECT_IRQ
+#define CONFIG_SERIAL_MULTIPORT
+#define CONFIG_HUB6
+#endif
+
+#ifdef CONFIG_PCI
+#define ENABLE_SERIAL_PCI
+#ifndef CONFIG_SERIAL_SHARE_IRQ
+#define CONFIG_SERIAL_SHARE_IRQ
+#endif
+#ifndef CONFIG_SERIAL_MANY_PORTS
+#define CONFIG_SERIAL_MANY_PORTS
+#endif
+#endif
+
+#if defined(CONFIG_ISAPNP)|| (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE))
+#ifndef ENABLE_SERIAL_PNP
+#define ENABLE_SERIAL_PNP
+#endif
+#endif
+
+/* Set of debugging defines */
+
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+#undef SERIAL_DEBUG_PCI
+#undef SERIAL_DEBUG_AUTOCONF
+
+/* Sanity checks */
+
+#ifdef CONFIG_SERIAL_MULTIPORT
+#ifndef CONFIG_SERIAL_SHARE_IRQ
+#define CONFIG_SERIAL_SHARE_IRQ
+#endif
+#endif
+
+#ifdef CONFIG_HUB6
+#ifndef CONFIG_SERIAL_MANY_PORTS
+#define CONFIG_SERIAL_MANY_PORTS
+#endif
+#ifndef CONFIG_SERIAL_SHARE_IRQ
+#define CONFIG_SERIAL_SHARE_IRQ
+#endif
+#endif
+
+#ifdef MODULE
+#undef CONFIG_SERIAL_CONSOLE
+#endif
+
+#define CONFIG_SERIAL_RSA
+
+#define RS_STROBE_TIME (10*HZ)
+#define RS_ISR_PASS_LIMIT 256
+
+#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
+#define SERIAL_INLINE
+#endif
+  
+/*
+ * End of serial driver configuration section.
+ */
+
+#include <linux/module.h>
+
+#include <linux/types.h>
+#ifdef LOCAL_HEADERS
+#include "serial_local.h"
+#else
+#include <linux/serial.h>
+#include <linux/serialP.h>
+//#include <linux/serial_reg.h>
+#include <asm/serial.h>
+#define LOCAL_VERSTRING ""
+#endif
+
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#if (LINUX_VERSION_CODE >= 131343)
+#include <linux/init.h>
+#endif
+#if (LINUX_VERSION_CODE >= 131336)
+#include <asm/uaccess.h>
+#endif
+#include <linux/delay.h>
+#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
+#include <linux/console.h>
+#endif
+#ifdef ENABLE_SERIAL_PCI
+#include <linux/pci.h>
+#endif
+#ifdef ENABLE_SERIAL_PNP
+#include <linux/isapnp.h>
+#endif
+#ifdef CONFIG_MAGIC_SYSRQ
+#include <linux/sysrq.h>
+#endif
+#ifdef CONFIG_LEDMAN
+#include <linux/ledman.h>
+#endif
+
+/*
+ * All of the compatibilty code so we can compile serial.c against
+ * older kernels is hidden in serial_compat.h
+ */
+#if defined(LOCAL_HEADERS) || (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */
+#include "serial_compat.h"
+#endif
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+
+#ifdef CONFIG_MAC_SERIAL
+#define SERIAL_DEV_OFFSET	2
+#else
+#define SERIAL_DEV_OFFSET	0
+#endif
+
+#ifdef SERIAL_INLINE
+#define _INLINE_ inline
+#else
+#define _INLINE_
+#endif
+
+static char *serial_name = "Samsung S3C4510 Serial driver";
+
+static DECLARE_TASK_QUEUE(tq_serial);
+
+static struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+static struct timer_list serial_timer;
+
+/* serial subtype definitions */
+#ifndef SERIAL_TYPE_NORMAL
+#define SERIAL_TYPE_NORMAL	1
+#define SERIAL_TYPE_CALLOUT	2
+#endif
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+/*
+ * IRQ_timeout		- How long the timeout should be for each IRQ
+ * 				should be after the IRQ has been active.
+ */
+
+static struct async_struct *IRQ_ports[NR_IRQS];
+#ifdef CONFIG_SERIAL_MULTIPORT
+static struct rs_multiport_struct rs_multiport[NR_IRQS];
+#endif
+static int IRQ_timeout[NR_IRQS];
+#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
+static struct console sercons;
+static int lsr_break_flag;
+#endif
+#if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+static unsigned long break_pressed; /* break, really ... */
+#endif
+
+static unsigned detect_uart_irq (struct serial_state * state);
+static void autoconfig(struct serial_state * state);
+static void change_speed(struct async_struct *info, struct termios *old);
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
+
+/*
+ * Here we define the default xmit fifo size used for each type of
+ * UART
+ */
+static struct serial_uart_config uart_config[] = {
+	{ "unknown", 1, 0 }, 
+	{ "8250", 1, 0 }, 
+	{ "16450", 1, 0 }, 
+	{ "16550", 1, 0 }, 
+	{ "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO }, 
+	{ "cirrus", 1, 0 }, 	// usurped by cyclades.c
+	{ "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH }, 
+	{ "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO |
+		  UART_STARTECH }, 
+	{ "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO},
+	{ "Startech", 1, 0},	// usurped by cyclades.c
+	{ "16C950/954", 128, UART_CLEAR_FIFO | UART_USE_FIFO},
+	{ "ST16654", 64, UART_CLEAR_FIFO | UART_USE_FIFO |
+		  UART_STARTECH }, 
+	{ "XR16850", 128, UART_CLEAR_FIFO | UART_USE_FIFO |
+		  UART_STARTECH },
+	{ "RSA", 2048, UART_CLEAR_FIFO | UART_USE_FIFO }, 
+	{ "S3C4510B", 1, 0},	/* Samsung S3C4510B uart support */
+	{ 0, 0}
+};
+#if defined(CONFIG_SERIAL_RSA) && defined(MODULE)
+
+#define PORT_RSA_MAX 4
+static int probe_rsa[PORT_RSA_MAX];
+static int force_rsa[PORT_RSA_MAX];
+
+MODULE_PARM(probe_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i");
+MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
+MODULE_PARM(force_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i");
+MODULE_PARM_DESC(force_rsa, "Force I/O ports for RSA");
+#endif /* CONFIG_SERIAL_RSA  */
+
+
+static struct serial_state rs_table[RS_TABLE_SIZE] = {
+	SERIAL_PORT_DFNS	// Defined in serial.h
+};
+
+
+#define NR_PORTS	(sizeof(rs_table)/sizeof(struct serial_state))
+
+#if (defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP))
+#define NR_PCI_BOARDS	8
+
+static struct pci_board_inst	serial_pci_board[NR_PCI_BOARDS];
+
+#ifndef IS_PCI_REGION_IOPORT
+#define IS_PCI_REGION_IOPORT(dev, r) (pci_resource_flags((dev), (r)) & \
+				      IORESOURCE_IO)
+#endif
+#ifndef IS_PCI_REGION_IOMEM
+#define IS_PCI_REGION_IOMEM(dev, r) (pci_resource_flags((dev), (r)) & \
+				      IORESOURCE_MEM)
+#endif
+#ifndef PCI_IRQ_RESOURCE
+#define PCI_IRQ_RESOURCE(dev, r) ((dev)->irq_resource[r].start)
+#endif
+#ifndef pci_get_subvendor
+#define pci_get_subvendor(dev) ((dev)->subsystem_vendor)
+#define pci_get_subdevice(dev)  ((dev)->subsystem_device)
+#endif
+#endif	/* ENABLE_SERIAL_PCI || ENABLE_SERIAL_PNP  */
+
+#ifndef PREPARE_FUNC
+#define PREPARE_FUNC(dev)  (dev->prepare)
+#define ACTIVATE_FUNC(dev)  (dev->activate)
+#define DEACTIVATE_FUNC(dev)  (dev->deactivate)
+#endif
+
+#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
+
+static struct tty_struct *serial_table[NR_PORTS];
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
+
+
+#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
+#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
+ kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s)
+#else
+#define DBG_CNT(s)
+#endif
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write.  We need to
+ * lock it in case the copy_from_user blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static unsigned char *tmp_buf;
+#ifdef DECLARE_MUTEX
+static DECLARE_MUTEX(tmp_buf_sem);
+#else
+static struct semaphore tmp_buf_sem = MUTEX;
+#endif
+
+static inline int serial_paranoia_check(struct async_struct *info,
+					kdev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%s) in %s\n";
+	static const char *badinfo =
+		"Warning: null async_struct for (%s) in %s\n";
+
+	if (!info) {
+		printk(badinfo, kdevname(device), routine);
+		return 1;
+	}
+	if (info->magic != SERIAL_MAGIC) {
+		printk(badmagic, kdevname(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset)
+{
+	return CSR_READ(info->port + offset);
+}
+
+static _INLINE_ void serial_out(struct async_struct *info, int offset,
+				int value)
+{
+	CSR_WRITE(info->port+offset, value);
+}
+
+/*
+ * We used to support using pause I/O for certain machines.  We
+ * haven't supported this for a while, but just in case it's badly
+ * needed for certain old 386 machines, I've left these #define's
+ * in....
+ */
+#define serial_inp(info, offset)		serial_in(info, offset)
+#define serial_outp(info, offset, value)	serial_out(info, offset, value)
+
+
+/*
+ * For the 16C950
+ */
+/*
+void serial_icr_write(struct async_struct *info, int offset, int  value)
+{
+	serial_out(info, UART_SCR, offset);
+	serial_out(info, UART_ICR, value);
+}
+
+unsigned int serial_icr_read(struct async_struct *info, int offset)
+{
+	int	value;
+
+	serial_icr_write(info, UART_ACR, info->ACR | UART_ACR_ICRRD);
+	serial_out(info, UART_SCR, offset);
+	value = serial_in(info, UART_ICR);
+	serial_icr_write(info, UART_ACR, info->ACR);
+	return value;
+}
+*/
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_stop"))
+		return;
+	
+	save_flags(flags); cli();
+/*
+	if (info->IER & UART_IER_THRI) {
+		info->IER &= ~UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+	}
+	if (info->state->type == PORT_16C950) {
+		info->ACR |= UART_ACR_TXDIS;
+		serial_icr_write(info, UART_ACR, info->ACR);
+	}
+*/
+	disable_uart_tx_interrupt(info->line);
+	restore_flags(flags);
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_start"))
+		return;
+	
+	save_flags(flags); cli();
+	if (info->xmit.head != info->xmit.tail
+	    && info->xmit.buf) {
+/*
+	    && !(info->IER & UART_IER_THRI)) {
+		info->IER |= UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+*/
+		enable_uart_tx_interrupt(info->line);
+	}
+/*
+	if (info->state->type == PORT_16C950) {
+		info->ACR &= ~UART_ACR_TXDIS;
+		serial_icr_write(info, UART_ACR, info->ACR);
+	}
+*/
+	restore_flags(flags);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ * 
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assemble code in serial.s.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static _INLINE_ void rs_sched_event(struct async_struct *info,
+				  int event)
+{
+	info->event |= 1 << event;
+	queue_task(&info->tqueue, &tq_serial);
+	mark_bh(SERIAL_BH);
+}
+
+static _INLINE_ void receive_chars(struct async_struct *info,
+				 int *status, struct pt_regs * regs)
+{
+	struct tty_struct *tty = info->tty;
+	unsigned char ch;
+	struct	async_icount *icount;
+	int	max_count = 256;
+
+#ifdef CONFIG_LEDMAN
+	ledman_cmd(LEDMAN_CMD_SET,
+		(info->line == 0) ? LEDMAN_COM1_RX : LEDMAN_COM2_RX);
+#endif
+
+	icount = &info->state->icount;
+	do {
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			tty->flip.tqueue.routine((void *) tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+				return;		// if TTY_DONT_FLIP is set
+		}
+		ch = serial_inp(info, UART_RX);
+		*tty->flip.char_buf_ptr = ch;
+		icount->rx++;
+		
+#ifdef SERIAL_DEBUG_INTR
+		printk("DR%02x:%02x...", ch, *status);
+#endif
+		*tty->flip.flag_buf_ptr = 0;
+		if (*status & (UART_LSR_BI | UART_LSR_PE |
+			       UART_LSR_FE | UART_LSR_OE)) {
+			//
+			// For statistics only
+			//
+			if (*status & UART_LSR_BI) {
+				*status &= ~(UART_LSR_FE | UART_LSR_PE);
+				icount->brk++;
+				//
+				// We do the SysRQ and SAK checking
+				// here because otherwise the break
+				// may get masked by ignore_status_mask
+				// or read_status_mask.
+				//
+#if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+				if (info->line == sercons.index) {
+					if (!break_pressed) {
+						break_pressed = jiffies;
+						goto ignore_char;
+					}
+					break_pressed = 0;
+				}
+#endif
+				if (info->flags & ASYNC_SAK)
+					do_SAK(tty);
+			} else if (*status & UART_LSR_PE)
+				icount->parity++;
+			else if (*status & UART_LSR_FE)
+				icount->frame++;
+			if (*status & UART_LSR_OE)
+				icount->overrun++;
+
+			//
+			// Mask off conditions which should be ignored.
+			//
+			*status &= info->read_status_mask;
+
+#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
+			if (info->line == sercons.index) {
+				// Recover the break flag from console xmit
+				*status |= lsr_break_flag;
+				lsr_break_flag = 0;
+			}
+#endif
+			if (*status & (UART_LSR_BI)) {
+#ifdef SERIAL_DEBUG_INTR
+				printk("handling break....");
+#endif
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			} else if (*status & UART_LSR_PE)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (*status & UART_LSR_FE)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+		}
+#if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+		if (break_pressed && info->line == sercons.index) {
+			if (ch != 0 &&
+			    time_before(jiffies, break_pressed + HZ*5)) {
+				handle_sysrq(ch, regs, NULL, NULL);
+				break_pressed = 0;
+				goto ignore_char;
+			}
+			break_pressed = 0;
+		}
+#endif
+		if ((*status & info->ignore_status_mask) == 0) {
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+		if ((*status & UART_LSR_OE) &&
+		    (tty->flip.count < TTY_FLIPBUF_SIZE)) {
+			//
+			// Overrun is special, since it's reported
+			// immediately, and doesn't affect the current
+			// character
+			//
+			*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+			tty->flip.count++;
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+		}
+#if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+	ignore_char:
+#endif
+		*status = serial_inp(info, UART_LSR);
+	} while ((*status & UART_LSR_DR) && (max_count-- > 0));
+#if (LINUX_VERSION_CODE > 131394) // 2.1.66
+	tty_flip_buffer_push(tty);
+#else
+	queue_task_irq_off(&tty->flip.tqueue, &tq_timer);
+#endif	
+}
+
+static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
+{
+	int count;
+
+#ifdef CONFIG_LEDMAN
+	ledman_cmd(LEDMAN_CMD_SET,
+		(info->line == 0) ? LEDMAN_COM1_TX : LEDMAN_COM2_TX);
+#endif
+
+	if (info->x_char) {
+		serial_outp(info, UART_TX, info->x_char);
+		info->state->icount.tx++;
+		info->x_char = 0;
+		if (intr_done)
+			*intr_done = 0;
+		return;
+	}
+	if (info->xmit.head == info->xmit.tail
+	    || info->tty->stopped
+	    || info->tty->hw_stopped) {
+/*
+		info->IER &= ~UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+*/
+		disable_uart_tx_interrupt(info->line);
+		return;
+	}
+	
+	count = info->xmit_fifo_size;
+	do {
+		serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]);
+		info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
+		info->state->icount.tx++;
+		if (info->xmit.head == info->xmit.tail)
+			break;
+	} while (--count > 0);
+	
+	if (CIRC_CNT(info->xmit.head,
+		     info->xmit.tail,
+		     SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+#ifdef SERIAL_DEBUG_INTR
+	printk("THRE...");
+#endif
+	if (intr_done)
+		*intr_done = 0;
+
+	if (info->xmit.head == info->xmit.tail) {
+/*
+		info->IER &= ~UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+*/
+		disable_uart_tx_interrupt(info->line);
+	}
+}
+
+/*
+static _INLINE_ void check_modem_status(struct async_struct *info)
+{
+	int	status;
+	struct	async_icount *icount;
+	
+	status = serial_in(info, UART_MSR);
+
+	if (status & UART_MSR_ANY_DELTA) {
+		icount = &info->state->icount;
+		// update input line counters
+		if (status & UART_MSR_TERI)
+			icount->rng++;
+		if (status & UART_MSR_DDSR)
+			icount->dsr++;
+		if (status & UART_MSR_DDCD) {
+			icount->dcd++;
+#ifdef CONFIG_HARD_PPS
+			if ((info->flags & ASYNC_HARDPPS_CD) &&
+			    (status & UART_MSR_DCD))
+				hardpps();
+#endif
+		}
+		if (status & UART_MSR_DCTS)
+			icount->cts++;
+		wake_up_interruptible(&info->delta_msr_wait);
+	}
+
+	if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
+#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
+		printk("ttys%d CD now %s...", info->line,
+		       (status & UART_MSR_DCD) ? "on" : "off");
+#endif		
+		if (status & UART_MSR_DCD)
+			wake_up_interruptible(&info->open_wait);
+		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+			   (info->flags & ASYNC_CALLOUT_NOHUP))) {
+#ifdef SERIAL_DEBUG_OPEN
+			printk("doing serial hangup...");
+#endif
+			if (info->tty)
+				tty_hangup(info->tty);
+		}
+	}
+	if (info->flags & ASYNC_CTS_FLOW) {
+		if (info->tty->hw_stopped) {
+			if (status & UART_MSR_CTS) {
+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
+				printk("CTS tx start...");
+#endif
+				info->tty->hw_stopped = 0;
+				info->IER |= UART_IER_THRI;
+				serial_out(info, UART_IER, info->IER);
+				rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+				return;
+			}
+		} else {
+			if (!(status & UART_MSR_CTS)) {
+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
+				printk("CTS tx stop...");
+#endif
+				info->tty->hw_stopped = 1;
+				info->IER &= ~UART_IER_THRI;
+				serial_out(info, UART_IER, info->IER);
+			}
+		}
+	}
+}
+*/
+#ifdef CONFIG_SERIAL_SHARE_IRQ
+/*
+ * This is the serial driver's generic interrupt routine
+ */
+/*
+static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	int status;
+	struct async_struct * info;
+	int pass_counter = 0;
+	struct async_struct *end_mark = 0;
+#ifdef CONFIG_SERIAL_MULTIPORT	
+	int first_multi = 0;
+	struct rs_multiport_struct *multi;
+#endif
+
+#ifdef SERIAL_DEBUG_INTR
+	printk("rs_interrupt(%d)...", irq);
+#endif
+
+	info = IRQ_ports[irq];
+	if (!info)
+		return;
+
+#ifdef CONFIG_SERIAL_MULTIPORT	
+	multi = &rs_multiport[irq];
+	if (multi->port_monitor)
+		first_multi = inb(multi->port_monitor);
+#endif
+
+	do {
+		if (!info->tty ||
+		    (serial_in(info, UART_IIR) & UART_IIR_NO_INT)) {
+			if (!end_mark)
+				end_mark = info;
+			goto next;
+		}
+#ifdef SERIAL_DEBUG_INTR
+		printk("IIR = %x...", serial_in(info, UART_IIR));
+#endif
+		end_mark = 0;
+
+		info->last_active = jiffies;
+
+		status = serial_inp(info, UART_LSR);
+#ifdef SERIAL_DEBUG_INTR
+		printk("status = %x...", status);
+#endif
+		if (status & UART_LSR_DR)
+			receive_chars(info, &status, regs);
+		check_modem_status(info);
+		if (status & UART_LSR_THRE)
+			transmit_chars(info, 0);
+
+	next:
+		info = info->next_port;
+		if (!info) {
+			info = IRQ_ports[irq];
+			if (pass_counter++ > RS_ISR_PASS_LIMIT) {
+#if 0
+				printk("rs loop break\n");
+#endif
+				break; 	// Prevent infinite loops
+			}
+			continue;
+		}
+	} while (end_mark != info);
+#ifdef CONFIG_SERIAL_MULTIPORT	
+	if (multi->port_monitor)
+		printk("rs port monitor (normal) irq %d: 0x%x, 0x%x\n",
+		       info->state->irq, first_multi,
+		       inb(multi->port_monitor));
+#endif
+#ifdef SERIAL_DEBUG_INTR
+	printk("end.\n");
+#endif
+}
+*/
+#endif /* #ifdef CONFIG_SERIAL_SHARE_IRQ */
+
+
+/*
+ * This is the serial driver's interrupt routine for a single port
+ */
+static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
+{
+	int status;
+	int pass_counter = 0;
+	struct async_struct * info;
+#ifdef CONFIG_SERIAL_MULTIPORT	
+	int first_multi = 0;
+	struct rs_multiport_struct *multi;
+#endif
+	
+#ifdef SERIAL_DEBUG_INTR
+	printk("rs_interrupt_single(%d)...", irq);
+#endif
+
+	info = IRQ_ports[irq];
+	if (!info || !info->tty)
+		return;
+
+#ifdef CONFIG_SERIAL_MULTIPORT	
+	multi = &rs_multiport[irq];
+	if (multi->port_monitor)
+		first_multi = inb(multi->port_monitor);
+#endif
+
+	do {
+		status = serial_inp(info, UART_LSR);
+#ifdef SERIAL_DEBUG_INTR
+		printk("status = %x...", status);
+#endif
+		if (status & UART_LSR_DR)
+			receive_chars(info, &status, regs);
+// 12/27/2001 Mac Wang Samsung 4510 doesn't have modem relate registers
+//		check_modem_status(info);
+		if (status & UART_LSR_THRE)
+			transmit_chars(info, 0);
+		if (pass_counter++ > RS_ISR_PASS_LIMIT) {
+#if 0
+			printk("rs_single loop break.\n");
+#endif
+			break;
+		}
+#ifdef SERIAL_DEBUG_INTR
+		printk("IIR = %x...", serial_in(info, UART_IIR));
+#endif
+	} while (!(status & (UART_LSR_DR | UART_LSR_THRE)));
+//	} while (!(serial_in(info, UART_IIR) & UART_IIR_NO_INT));
+	info->last_active = jiffies;
+#ifdef CONFIG_SERIAL_MULTIPORT	
+	if (multi->port_monitor)
+		printk("rs port monitor (single) irq %d: 0x%x, 0x%x\n",
+		       info->state->irq, first_multi,
+		       inb(multi->port_monitor));
+#endif
+#ifdef SERIAL_DEBUG_INTR
+	printk("end.\n");
+#endif
+}
+
+#ifdef CONFIG_SERIAL_MULTIPORT	
+/*
+ * This is the serial driver's for multiport boards
+ */
+/*
+static void rs_interrupt_multi(int irq, void *dev_id, struct pt_regs * regs)
+{
+	int status;
+	struct async_struct * info;
+	int pass_counter = 0;
+	int first_multi= 0;
+	struct rs_multiport_struct *multi;
+
+#ifdef SERIAL_DEBUG_INTR
+	printk("rs_interrupt_multi(%d)...", irq);
+#endif
+
+	info = IRQ_ports[irq];
+	if (!info)
+		return;
+	multi = &rs_multiport[irq];
+	if (!multi->port1) {
+		// Should never happen
+		printk("rs_interrupt_multi: NULL port1!\n");
+		return;
+	}
+	if (multi->port_monitor)
+		first_multi = inb(multi->port_monitor);
+	
+	while (1) {
+		if (!info->tty ||
+		    (serial_in(info, UART_IIR) & UART_IIR_NO_INT))
+			goto next;
+
+		info->last_active = jiffies;
+
+		status = serial_inp(info, UART_LSR);
+#ifdef SERIAL_DEBUG_INTR
+		printk("status = %x...", status);
+#endif
+		if (status & UART_LSR_DR)
+			receive_chars(info, &status, regs);
+		check_modem_status(info);
+		if (status & UART_LSR_THRE)
+			transmit_chars(info, 0);
+
+	next:
+		info = info->next_port;
+		if (info)
+			continue;
+
+		info = IRQ_ports[irq];
+		//
+		// The user was a bonehead, and misconfigured their
+		// multiport info.  Rather than lock up the kernel
+		// in an infinite loop, if we loop too many times,
+		// print a message and break out of the loop.
+		//
+		if (pass_counter++ > RS_ISR_PASS_LIMIT) {
+			printk("Misconfigured multiport serial info "
+			       "for irq %d.  Breaking out irq loop\n", irq);
+			break; 
+		}
+		if (multi->port_monitor)
+			printk("rs port monitor irq %d: 0x%x, 0x%x\n",
+			       info->state->irq, first_multi,
+			       inb(multi->port_monitor));
+		if ((inb(multi->port1) & multi->mask1) != multi->match1)
+			continue;
+		if (!multi->port2)
+			break;
+		if ((inb(multi->port2) & multi->mask2) != multi->match2)
+			continue;
+		if (!multi->port3)
+			break;
+		if ((inb(multi->port3) & multi->mask3) != multi->match3)
+			continue;
+		if (!multi->port4)
+			break;
+		if ((inb(multi->port4) & multi->mask4) != multi->match4)
+			continue;
+		break;
+	} 
+#ifdef SERIAL_DEBUG_INTR
+	printk("end.\n");
+#endif
+}
+*/
+#endif
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct async_struct	*info = (struct async_struct *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+		wake_up_interruptible(&tty->poll_wait);
+#endif
+	}
+}
+
+/*
+ * This subroutine is called when the RS_TIMER goes off.  It is used
+ * by the serial driver to handle ports that do not have an interrupt
+ * (irq=0).  This doesn't work very well for 16450's, but gives barely
+ * passable results for a 16550A.  (Although at the expense of much
+ * CPU overhead).
+ */
+static void rs_timer(unsigned long dummy)
+{
+	static unsigned long last_strobe;
+	struct async_struct *info;
+	unsigned int	i;
+	unsigned long flags;
+
+	if ((jiffies - last_strobe) >= RS_STROBE_TIME) {
+		for (i=0; i < NR_IRQS; i++) {
+			info = IRQ_ports[i];
+			if (!info)
+				continue;
+			save_flags(flags); cli();
+#ifdef CONFIG_SERIAL_SHARE_IRQ
+			if (info->next_port) {
+				do {
+					serial_out(info, UART_IER, 0);
+					info->IER |= UART_IER_THRI;
+					serial_out(info, UART_IER, info->IER);
+					info = info->next_port;
+				} while (info);
+#ifdef CONFIG_SERIAL_MULTIPORT
+				if (rs_multiport[i].port1)
+					rs_interrupt_multi(i, NULL, NULL);
+				else
+#endif
+					rs_interrupt(i, NULL, NULL);
+			} else
+#endif // CONFIG_SERIAL_SHARE_IRQ
+				rs_interrupt_single(i, NULL, NULL);
+			restore_flags(flags);
+		}
+	}
+	last_strobe = jiffies;
+	mod_timer(&serial_timer, jiffies + RS_STROBE_TIME);
+
+	if (IRQ_ports[0]) {
+		save_flags(flags); cli();
+#ifdef CONFIG_SERIAL_SHARE_IRQ
+		rs_interrupt(0, NULL, NULL);
+#else
+		rs_interrupt_single(0, NULL, NULL);
+#endif
+		restore_flags(flags);
+
+		mod_timer(&serial_timer, jiffies + IRQ_timeout[0]);
+	}
+}
+/*
+ * ---------------------------------------------------------------
+ * Low level utility subroutines for the serial driver:  routines to
+ * figure out the appropriate timeout for an interrupt chain, routines
+ * to initialize and startup a serial port, and routines to shutdown a
+ * serial port.  Useful stuff like that.
+ * ---------------------------------------------------------------
+ */
+
+/*
+ * This routine figures out the correct timeout for a particular IRQ.
+ * It uses the smallest timeout of all of the serial ports in a
+ * particular interrupt chain.  Now only used for IRQ 0....
+ */
+static void figure_IRQ_timeout(int irq)
+{
+	struct	async_struct	*info;
+	int	timeout = 60*HZ;	// 60 seconds === a long time :-)
+
+	info = IRQ_ports[irq];
+	if (!info) {
+		IRQ_timeout[irq] = 60*HZ;
+		return;
+	}
+	while (info) {
+		if (info->timeout < timeout)
+			timeout = info->timeout;
+		info = info->next_port;
+	}
+	if (!irq)
+		timeout = timeout / 2;
+	IRQ_timeout[irq] = (timeout > 3) ? timeout-2 : 1;
+}
+
+#ifdef CONFIG_SERIAL_RSA
+/* Attempts to turn on the RSA FIFO.  Returns zero on failure */
+/*
+static int enable_rsa(struct async_struct *info)
+{
+	unsigned char mode;
+	int result;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	mode = serial_inp(info, UART_RSA_MSR);
+	result = mode & UART_RSA_MSR_FIFO;
+
+	if (!result) {
+		serial_outp(info, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
+		mode = serial_inp(info, UART_RSA_MSR);
+		result = mode & UART_RSA_MSR_FIFO;
+	}
+
+	restore_flags(flags);
+	return result;
+}
+*/
+/* Attempts to turn off the RSA FIFO.  Returns zero on failure */
+/*
+static int disable_rsa(struct async_struct *info)
+{
+	unsigned char mode;
+	int result;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	mode = serial_inp(info, UART_RSA_MSR);
+	result = !(mode & UART_RSA_MSR_FIFO);
+
+	if (!result) {
+		serial_outp(info, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
+		mode = serial_inp(info, UART_RSA_MSR);
+		result = !(mode & UART_RSA_MSR_FIFO);
+	}
+
+	restore_flags(flags);
+	return result;
+}
+*/
+#endif /* CONFIG_SERIAL_RSA */
+
+static int startup(struct async_struct * info)
+{
+	unsigned long flags;
+	int	retval=0;
+	void (*handler)(int, void *, struct pt_regs *);
+	struct serial_state *state= info->state;
+	unsigned long page;
+#ifdef CONFIG_SERIAL_MANY_PORTS
+	unsigned short ICP;
+#endif
+
+	page = get_zeroed_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	save_flags(flags); cli();
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		free_page(page);
+		goto errout;
+	}
+
+	if (!CONFIGURED_SERIAL_PORT(state) || !state->type) {
+		if (info->tty)
+			set_bit(TTY_IO_ERROR, &info->tty->flags);
+		free_page(page);
+		goto errout;
+	}
+	if (info->xmit.buf)
+		free_page(page);
+	else
+		info->xmit.buf = (unsigned char *) page;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttys%d (irq %d)...", info->line, state->irq);
+#endif
+/*
+	if (uart_config[state->type].flags & UART_STARTECH) {
+		// Wake up UART
+		serial_outp(info, UART_LCR, 0xBF);
+		serial_outp(info, UART_EFR, UART_EFR_ECB);
+		//
+		// Turn off LCR == 0xBF so we actually set the IER
+		// register on the XR16C850
+		//
+		serial_outp(info, UART_LCR, 0);
+		serial_outp(info, UART_IER, 0);
+		//
+		// Now reset LCR so we can turn off the ECB bit
+		//
+		serial_outp(info, UART_LCR, 0xBF);
+		serial_outp(info, UART_EFR, 0);
+		//
+		// For a XR16C850, we need to set the trigger levels
+		//
+		if (state->type == PORT_16850) {
+			serial_outp(info, UART_FCTR, UART_FCTR_TRGD |
+					UART_FCTR_RX);
+			serial_outp(info, UART_TRG, UART_TRG_96);
+			serial_outp(info, UART_FCTR, UART_FCTR_TRGD |
+					UART_FCTR_TX);
+			serial_outp(info, UART_TRG, UART_TRG_96);
+		}
+		serial_outp(info, UART_LCR, 0);
+	}
+
+	if (state->type == PORT_16750) {
+		// Wake up UART
+		serial_outp(info, UART_IER, 0);
+	}
+
+	if (state->type == PORT_16C950) {
+		// Wake up and initialize UART
+		info->ACR = 0;
+		serial_outp(info, UART_LCR, 0xBF);
+		serial_outp(info, UART_EFR, UART_EFR_ECB);
+		serial_outp(info, UART_IER, 0);
+		serial_outp(info, UART_LCR, 0);
+		serial_icr_write(info, UART_CSR, 0); // Reset the UART
+		serial_outp(info, UART_LCR, 0xBF);
+		serial_outp(info, UART_EFR, UART_EFR_ECB);
+		serial_outp(info, UART_LCR, 0);
+	}
+*/
+/*
+#ifdef CONFIG_SERIAL_RSA
+	//
+	// If this is an RSA port, see if we can kick it up to the
+	// higher speed clock.
+	//
+	if (state->type == PORT_RSA) {
+		if (state->baud_base != SERIAL_RSA_BAUD_BASE &&
+		    enable_rsa(info))
+			state->baud_base = SERIAL_RSA_BAUD_BASE;
+		if (state->baud_base == SERIAL_RSA_BAUD_BASE)
+			serial_outp(info, UART_RSA_FRR, 0);
+	}
+#endif
+*/
+/*
+	//
+	// Clear the FIFO buffers and disable them
+	// (they will be reenabled in change_speed())
+	//
+	if (uart_config[state->type].flags & UART_CLEAR_FIFO) {
+		serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
+		serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
+					     UART_FCR_CLEAR_RCVR |
+					     UART_FCR_CLEAR_XMIT));
+		serial_outp(info, UART_FCR, 0);
+	}
+*/
+/*
+	//
+	// Clear the interrupt registers.
+	//
+	(void) serial_inp(info, UART_LSR);
+	(void) serial_inp(info, UART_RX);
+	(void) serial_inp(info, UART_IIR);
+	(void) serial_inp(info, UART_MSR);
+*/
+	CLEAR_PEND_INT(state->irq);   /* clear serial UART rx interrupt */
+	CLEAR_PEND_INT(state->irq-1); /* clear serial UART tx interrupt */
+
+/*
+	//
+	// At this point there's no way the LSR could still be 0xFF;
+	// if it is, then bail out, because there's likely no UART
+	// here.
+	//
+	if (!(info->flags & ASYNC_BUGGY_UART) &&
+	    (serial_inp(info, UART_LSR) == 0xff)) {
+		printk("ttyS%d: LSR safety check engaged!\n", state->line);
+		if (capable(CAP_SYS_ADMIN)) {
+			if (info->tty)
+				set_bit(TTY_IO_ERROR, &info->tty->flags);
+		} else
+			retval = -ENODEV;
+		goto errout;
+	}
+*/	
+	//
+	// Allocate the IRQ if necessary
+	//
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+#ifdef CONFIG_SERIAL_SHARE_IRQ
+			free_irq(state->irq, &IRQ_ports[state->irq]);
+#ifdef CONFIG_SERIAL_MULTIPORT				
+			if (rs_multiport[state->irq].port1)
+				handler = rs_interrupt_multi;
+			else
+#endif
+				handler = rs_interrupt;
+#else
+			retval = -EBUSY;
+			goto errout;
+#endif // CONFIG_SERIAL_SHARE_IRQ
+		} else 
+			handler = rs_interrupt_single;
+
+		// Mac Wang register rx and tx seperatly
+		retval = request_irq(state->irq, handler, SA_SHIRQ,
+				     "serial", &IRQ_ports[state->irq]);
+
+		retval = request_irq(state->irq - 1, handler, SA_SHIRQ,
+				     "serial", &IRQ_ports[state->irq-1]);
+
+		if (retval) {
+			if (capable(CAP_SYS_ADMIN)) {
+				if (info->tty)
+					set_bit(TTY_IO_ERROR,
+						&info->tty->flags);
+				retval = 0;
+			}
+			goto errout;
+		}
+	}
+
+	//
+	// Insert serial port into IRQ chain.
+	//
+	info->prev_port = 0;
+	info->next_port = IRQ_ports[state->irq];
+	if (info->next_port)
+		info->next_port->prev_port = info;
+	IRQ_ports[state->irq] = info;
+	figure_IRQ_timeout(state->irq);
+
+	IRQ_ports[state->irq - 1] = info;
+	figure_IRQ_timeout(state->irq - 1);
+	
+	//
+	// Now, initialize the UART 
+	//
+/*
+	serial_outp(info, UART_LCR, UART_LCR_WLEN8);	// reset DLAB
+
+	info->MCR = 0;
+	if (info->tty->termios->c_cflag & CBAUD)
+		info->MCR = UART_MCR_DTR | UART_MCR_RTS;
+#ifdef CONFIG_SERIAL_MANY_PORTS
+	if (info->flags & ASYNC_FOURPORT) {
+		if (state->irq == 0)
+			info->MCR |= UART_MCR_OUT1;
+	} else
+#endif
+	{
+		if (state->irq != 0)
+			info->MCR |= UART_MCR_OUT2;
+	}
+	info->MCR |= ALPHA_KLUDGE_MCR; 		// Don't ask
+	serial_outp(info, UART_MCR, info->MCR);
+*/
+	serial_outp(info, UART_LCR, UART_LCR_WLEN8);
+	serial_outp(info, UART_GCR, UART_GCR_RX_INT|UART_GCR_TX_INT|UART_GCR_RX_STAT_INT);
+	
+	//
+	// Finally, enable interrupts
+	//
+/*
+	info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
+	serial_outp(info, UART_IER, info->IER);	// enable interrupts
+*/
+	enable_uart_rx_interrupt(info->line) ;
+	
+#ifdef CONFIG_SERIAL_MANY_PORTS
+	if (info->flags & ASYNC_FOURPORT) {
+		// Enable interrupts on the AST Fourport board
+		ICP = (info->port & 0xFE0) | 0x01F;
+		outb_p(0x80, ICP);
+		(void) inb_p(ICP);
+	}
+#endif
+
+	//
+	// And clear the interrupt registers again for luck.
+	//
+/*
+	(void)serial_inp(info, UART_LSR);
+	(void)serial_inp(info, UART_RX);
+	(void)serial_inp(info, UART_IIR);
+	(void)serial_inp(info, UART_MSR);
+*/
+	CLEAR_PEND_INT(state->irq);   /* clear serial UART rx interrupt */
+	CLEAR_PEND_INT(state->irq-1); /* clear serial UART tx interrupt */
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit.head = info->xmit.tail = 0;
+
+	//
+	// Set up serial timers...
+	//
+	mod_timer(&serial_timer, jiffies + 2*HZ/100);
+
+ 	//
+	// Set up the tty->alt_speed kludge
+	//
+#if (LINUX_VERSION_CODE >= 131394) // Linux 2.1.66
+	if (info->tty) {
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+			info->tty->alt_speed = 57600;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+			info->tty->alt_speed = 115200;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+			info->tty->alt_speed = 230400;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+			info->tty->alt_speed = 460800;
+	}
+#endif
+	
+	//
+	// and set the speed of the serial port
+	//
+	change_speed(info, 0);
+
+	info->flags |= ASYNC_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+	
+errout:
+	restore_flags(flags);
+	return retval;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct async_struct * info)
+{
+	unsigned long	flags;
+	struct serial_state *state;
+	int		retval;
+
+	if (!(info->flags & ASYNC_INITIALIZED))
+		return;
+
+	state = info->state;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("Shutting down serial port %d (irq %d)....", info->line,
+	       state->irq);
+#endif
+	
+	save_flags(flags); cli(); // Disable interrupts
+
+	//
+	// clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+	// here so the queue might never be waken up
+	//
+	wake_up_interruptible(&info->delta_msr_wait);
+	
+	//
+	// First unlink the serial port from the IRQ chain...
+	//
+	if (info->next_port)
+		info->next_port->prev_port = info->prev_port;
+	if (info->prev_port)
+		info->prev_port->next_port = info->next_port;
+	else
+		IRQ_ports[state->irq] = info->next_port;
+	figure_IRQ_timeout(state->irq);
+	
+	//
+	// Free the IRQ, if necessary
+	//
+	// rx
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			free_irq(state->irq, &IRQ_ports[state->irq]);
+			retval = request_irq(state->irq, rs_interrupt_single,
+					     SA_SHIRQ, "serial",
+					     &IRQ_ports[state->irq]);
+			
+			if (retval)
+				printk("serial shutdown: request_irq: error %d"
+				       "  Couldn't reacquire IRQ.\n", retval);
+		} else
+			free_irq(state->irq, &IRQ_ports[state->irq]);
+	}
+	// tx
+
+	if (state->irq - 1 && (!IRQ_ports[state->irq - 1] ||
+			  !IRQ_ports[state->irq - 1]->next_port)) {
+		free_irq(state->irq-1, &IRQ_ports[state->irq-1]);
+	}
+/*
+	if (state->irq - 1 && (!IRQ_ports[state->irq - 1] ||
+			  !IRQ_ports[state->irq - 1]->next_port)) {
+		if (IRQ_ports[state->irq - 1]) {
+			free_irq(state->irq - 1, &IRQ_ports[state->irq - 1]);
+			retval = request_irq(state->irq - 1, rs_interrupt_single,
+					     SA_SHIRQ, "serial",
+					     &IRQ_ports[state->irq - 1]);
+			
+			if (retval)
+				printk("serial shutdown: request_irq: error %d"
+				       "  Couldn't reacquire IRQ.\n", retval);
+		} else
+			free_irq(state->irq - 1, &IRQ_ports[state->irq - 1]);
+	}
+*/
+
+	if (info->xmit.buf) {
+		unsigned long pg = (unsigned long) info->xmit.buf;
+		info->xmit.buf = 0;
+		free_page(pg);
+	}
+
+/*
+	info->IER = 0;
+	serial_outp(info, UART_IER, 0x00);	// disable all intrs
+*/
+	disable_uart_rx_interrupt(info->line);
+	disable_uart_tx_interrupt(info->line);
+/*
+#ifdef CONFIG_SERIAL_MANY_PORTS
+	if (info->flags & ASYNC_FOURPORT) {
+		// reset interrupts on the AST Fourport board
+		(void) inb((info->port & 0xFE0) | 0x01F);
+		info->MCR |= UART_MCR_OUT1;
+	} else
+#endif
+		info->MCR &= ~UART_MCR_OUT2;
+	info->MCR |= ALPHA_KLUDGE_MCR; 		// Don't ask
+*/	
+/*
+	// disable break condition
+	serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC);
+	
+	if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
+	serial_outp(info, UART_MCR, info->MCR);
+
+	// disable FIFO's
+	serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
+				     UART_FCR_CLEAR_RCVR |
+				     UART_FCR_CLEAR_XMIT));
+	serial_outp(info, UART_FCR, 0);
+*/
+/*
+#ifdef CONFIG_SERIAL_RSA
+	//
+	// Reset the RSA board back to 115kbps compat mode.
+	//
+	if ((state->type == PORT_RSA) &&
+	    (state->baud_base == SERIAL_RSA_BAUD_BASE &&
+	     disable_rsa(info)))
+		state->baud_base = SERIAL_RSA_BAUD_BASE_LO;
+#endif
+*/	
+
+	(void)serial_in(info, UART_RX);    // read data port to reset things
+	
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+/*
+	if (uart_config[info->state->type].flags & UART_STARTECH) {
+		// Arrange to enter sleep mode
+		serial_outp(info, UART_LCR, 0xBF);
+		serial_outp(info, UART_EFR, UART_EFR_ECB);
+		serial_outp(info, UART_LCR, 0);
+		serial_outp(info, UART_IER, UART_IERX_SLEEP);
+		serial_outp(info, UART_LCR, 0xBF);
+		serial_outp(info, UART_EFR, 0);
+		serial_outp(info, UART_LCR, 0);
+	}
+	if (info->state->type == PORT_16750) {
+		// Arrange to enter sleep mode
+		serial_outp(info, UART_IER, UART_IERX_SLEEP);
+	}
+*/
+	info->flags &= ~ASYNC_INITIALIZED;
+	restore_flags(flags);
+}
+
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+static int baud_table[] = {
+	0, 50, 75, 110, 134, 150, 200, 300,
+	600, 1200, 1800, 2400, 4800, 9600, 19200,
+	38400, 57600, 115200, 230400, 460800, 0 };
+/*
+static int tty_get_baud_rate(struct tty_struct *tty)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	unsigned int cflag, i;
+
+	cflag = tty->termios->c_cflag;
+
+	i = cflag & CBAUD;
+	if (i & CBAUDEX) {
+		i &= ~CBAUDEX;
+		if (i < 1 || i > 2) 
+			tty->termios->c_cflag &= ~CBAUDEX;
+		else
+			i += 15;
+	}
+	if (i == 15) {
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+			i += 1;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+			i += 2;
+	}
+	return baud_table[i];
+}
+*/
+#endif
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void change_speed(struct async_struct *info,
+			 struct termios *old_termios)
+{
+	int	quot = 0, baud_base, baud;
+//	unsigned cflag, cval, fcr = 0;
+	unsigned cflag, cval;
+	int	bits;
+	unsigned long	flags;
+
+	if (!info->tty || !info->tty->termios)
+		return;
+	cflag = info->tty->termios->c_cflag;
+	if (!CONFIGURED_SERIAL_PORT(info))
+		return;
+
+	// byte size and parity
+	switch (cflag & CSIZE) {
+	      case CS5: cval = 0x00; bits = 7; break;
+	      case CS6: cval = 0x01; bits = 8; break;
+	      case CS7: cval = 0x02; bits = 9; break;
+	      case CS8: cval = 0x03; bits = 10; break;
+	      // Never happens, but GCC is too dumb to figure it out
+	      default:  cval = 0x00; bits = 7; break;
+	      }
+	if (cflag & CSTOPB) {
+		cval |= 0x04;
+		bits++;
+	}
+	if (cflag & PARENB) {
+		bits++;
+	}
+	if (cflag & PARODD)
+		cval |= UART_LCR_OPAR;
+	else if (cflag & PARENB)
+		cval |= UART_LCR_EPAR;
+	else
+		cval |= UART_LCR_NPAR;
+/*
+	if (cflag & PARENB) {
+		cval |= UART_LCR_PARITY;
+		bits++;
+	}
+	if (!(cflag & PARODD))
+		cval |= UART_LCR_EPAR;
+#ifdef CMSPAR
+	if (cflag & CMSPAR)
+		cval |= UART_LCR_SPAR;
+#endif
+*/
+	// Determine divisor based on baud rate
+	baud = tty_get_baud_rate(info->tty);
+	if (!baud)
+		baud = 9600;	// B0 transition handled in rs_set_termios
+/*
+#ifdef CONFIG_SERIAL_RSA
+	if ((info->state->type == PORT_RSA) &&
+	    (info->state->baud_base != SERIAL_RSA_BAUD_BASE) &&
+	    enable_rsa(info))
+		info->state->baud_base = SERIAL_RSA_BAUD_BASE;
+#endif
+*/
+	baud_base = info->state->baud_base;
+/*
+	if (info->state->type == PORT_16C950) {
+		if (baud <= baud_base)
+			serial_icr_write(info, UART_TCR, 0);
+		else if (baud <= 2*baud_base) {
+			serial_icr_write(info, UART_TCR, 0x8);
+			baud_base = baud_base * 2;
+		} else if (baud <= 4*baud_base) {
+			serial_icr_write(info, UART_TCR, 0x4);
+			baud_base = baud_base * 4;
+		} else
+			serial_icr_write(info, UART_TCR, 0);
+	}
+*/
+/*
+	if (baud == 38400 &&
+	    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+		quot = info->state->custom_divisor;
+	else {
+		if (baud == 134)
+			// Special case since 134 is really 134.5
+			quot = (2*baud_base / 269);
+		else if (baud)
+			quot = baud_base / baud;
+	}
+*/
+	quot = 1;	//tricky
+
+	// If the quotient is zero refuse the change
+	if (!quot && old_termios) {
+		info->tty->termios->c_cflag &= ~CBAUD;
+		info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD);
+		baud = tty_get_baud_rate(info->tty);
+		if (!baud)
+			baud = 9600;
+/*
+		if (baud == 38400 &&
+		    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+			quot = info->state->custom_divisor;
+		else {
+			if (baud == 134)
+				// Special case since 134 is really 134.5
+				quot = (2*baud_base / 269);
+			else if (baud)
+				quot = baud_base / baud;
+		}
+*/
+	}
+	// As a last resort, if the quotient is zero, default to 9600 bps
+	if (!quot)
+		quot = baud_base / 9600;
+	//
+	// Work around a bug in the Oxford Semiconductor 952 rev B
+	// chip which causes it to seriously miscalculate baud rates
+	// when DLL is 0.
+	//
+/*
+	if (((quot & 0xFF) == 0) && (info->state->type == PORT_16C950) &&
+	    (info->state->revision == 0x5201))
+		quot++;
+*/	
+	info->quot = quot;
+	info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base);
+	info->timeout += HZ/50;		// Add .02 seconds of slop
+
+/*
+	// Set up FIFO's
+	if (uart_config[info->state->type].flags & UART_USE_FIFO) {
+		if ((info->state->baud_base / quot) < 2400)
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
+#ifdef CONFIG_SERIAL_RSA
+		else if (info->state->type == PORT_RSA)
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_14;
+#endif
+		else
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
+	}
+	if (info->state->type == PORT_16750)
+		fcr |= UART_FCR7_64BYTE;
+	
+	// CTS flow control flag and modem status interrupts
+	info->IER &= ~UART_IER_MSI;
+	if (info->flags & ASYNC_HARDPPS_CD)
+		info->IER |= UART_IER_MSI;
+	if (cflag & CRTSCTS) {
+		info->flags |= ASYNC_CTS_FLOW;
+		info->IER |= UART_IER_MSI;
+	} else
+		info->flags &= ~ASYNC_CTS_FLOW;
+	if (cflag & CLOCAL)
+		info->flags &= ~ASYNC_CHECK_CD;
+	else {
+		info->flags |= ASYNC_CHECK_CD;
+		info->IER |= UART_IER_MSI;
+	}
+	serial_out(info, UART_IER, info->IER);
+*/
+
+	//
+	// Set up parity check flag
+	//
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+	info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
+	if (I_INPCK(info->tty))
+		info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
+	if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+		info->read_status_mask |= UART_LSR_BI;
+	
+	//
+	// Characters to ignore
+	//
+	info->ignore_status_mask = 0;
+	if (I_IGNPAR(info->tty))
+		info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
+	if (I_IGNBRK(info->tty)) {
+		info->ignore_status_mask |= UART_LSR_BI;
+		//
+		// If we're ignore parity and break indicators, ignore 
+		// overruns too.  (For real raw support).
+		//
+		if (I_IGNPAR(info->tty))
+			info->ignore_status_mask |= UART_LSR_OE;
+	}
+#if 0 // breaks serial console during boot stage
+	//
+	// !!! ignore all characters if CREAD is not set
+	//
+	if ((cflag & CREAD) == 0)
+		info->ignore_status_mask |= UART_LSR_DR;
+#endif
+	save_flags(flags); cli();
+/*
+	if (uart_config[info->state->type].flags & UART_STARTECH) {
+		serial_outp(info, UART_LCR, 0xBF);
+		serial_outp(info, UART_EFR,
+			    (cflag & CRTSCTS) ? UART_EFR_CTS : 0);
+	}
+*/
+/*
+	serial_outp(info, UART_LCR, cval | UART_LCR_DLAB);	// set DLAB
+	serial_outp(info, UART_DLL, quot & 0xff);	// LS of divisor
+	serial_outp(info, UART_DLM, quot >> 8);		// MS of divisor
+*/
+/*
+	if (info->state->type == PORT_16750)
+		serial_outp(info, UART_FCR, fcr); 	// set fcr
+*/
+//	serial_outp(info, UART_LCR, cval);		// reset DLAB
+	info->LCR = cval;				// Save LCR
+/* 
+	if (info->state->type != PORT_16750) {
+ 		if (fcr & UART_FCR_ENABLE_FIFO) {
+ 			// emulated UARTs (Lucent Venus 167x) need two steps
+ 			serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
+ 		}
+		serial_outp(info, UART_FCR, fcr); 	// set fcr
+	}
+*/
+	serial_outp(info, UART_BDR, baudrate_div(baud));
+	serial_outp(info, UART_LCR, cval);
+	restore_flags(flags);
+}
+
+static void rs_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->device, "rs_put_char"))
+		return;
+
+	if (!tty || !info->xmit.buf)
+		return;
+
+	save_flags(flags); cli();
+	if (CIRC_SPACE(info->xmit.head,
+		       info->xmit.tail,
+		       SERIAL_XMIT_SIZE) == 0) {
+		restore_flags(flags);
+		return;
+	}
+
+	info->xmit.buf[info->xmit.head] = ch;
+	info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
+	restore_flags(flags);
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
+		return;
+
+	if (info->xmit.head == info->xmit.tail
+	    || tty->stopped
+	    || tty->hw_stopped
+	    || !info->xmit.buf)
+		return;
+
+	save_flags(flags); cli();
+/*
+	info->IER |= UART_IER_THRI;
+	serial_out(info, UART_IER, info->IER);
+*/
+	enable_uart_tx_interrupt(info->line);
+	restore_flags(flags);
+}
+
+static int rs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	int	c, ret = 0;
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_write"))
+		return 0;
+
+	if (!tty || !info->xmit.buf || !tmp_buf)
+		return 0;
+
+	save_flags(flags);
+	if (from_user) {
+		down(&tmp_buf_sem);
+		while (1) {
+			int c1;
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					      info->xmit.tail,
+					      SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0)
+				break;
+
+			c -= copy_from_user(tmp_buf, buf, c);
+			if (!c) {
+				if (!ret)
+					ret = -EFAULT;
+				break;
+			}
+			cli();
+			c1 = CIRC_SPACE_TO_END(info->xmit.head,
+					       info->xmit.tail,
+					       SERIAL_XMIT_SIZE);
+			if (c1 < c)
+				c = c1;
+			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			restore_flags(flags);
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		up(&tmp_buf_sem);
+	} else {
+		cli();
+		while (1) {
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					      info->xmit.tail,
+					      SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0) {
+				break;
+			}
+			memcpy(info->xmit.buf + info->xmit.head, buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		restore_flags(flags);
+	}
+	if (info->xmit.head != info->xmit.tail
+	    && !tty->stopped
+	    && !tty->hw_stopped) {
+/*
+	    && !(info->IER & UART_IER_THRI)) {
+		info->IER |= UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+*/
+		enable_uart_tx_interrupt(info->line);
+	}
+	return ret;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
+		return 0;
+	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+				
+	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+		return 0;
+	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+		return;
+	save_flags(flags); cli();
+	info->xmit.head = info->xmit.tail = 0;
+	restore_flags(flags);
+	wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+	wake_up_interruptible(&tty->poll_wait);
+#endif
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void rs_send_xchar(struct tty_struct *tty, char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	if (serial_paranoia_check(info, tty->device, "rs_send_char"))
+		return;
+
+	info->x_char = ch;
+	if (ch) {
+		// Make sure transmit interrupts are on
+/*
+		info->IER |= UART_IER_THRI;
+		serial_out(info, UART_IER, info->IER);
+*/
+		enable_uart_tx_interrupt(info->line);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct * tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("throttle %s: %d....\n", tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+		return;
+	
+	if (I_IXOFF(tty))
+		rs_send_xchar(tty, STOP_CHAR(tty));
+/*
+	if (tty->termios->c_cflag & CRTSCTS)
+		info->MCR &= ~UART_MCR_RTS;
+*/
+	save_flags(flags); cli();
+//	serial_out(info, UART_MCR, info->MCR);
+	restore_flags(flags);
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("unthrottle %s: %d....\n", tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+		return;
+	
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			rs_send_xchar(tty, START_CHAR(tty));
+	}
+/*
+	if (tty->termios->c_cflag & CRTSCTS)
+		info->MCR |= UART_MCR_RTS;
+*/
+	save_flags(flags); cli();
+//	serial_out(info, UART_MCR, info->MCR);
+	restore_flags(flags);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+static int get_serial_info(struct async_struct * info,
+			   struct serial_struct * retinfo)
+{
+	struct serial_struct tmp;
+	struct serial_state *state = info->state;
+   
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = state->type;
+	tmp.line = state->line;
+	tmp.port = state->port;
+	if (HIGH_BITS_OFFSET)
+		tmp.port_high = state->port >> HIGH_BITS_OFFSET;
+	else
+		tmp.port_high = 0;
+	tmp.irq = state->irq;
+	tmp.flags = state->flags;
+	tmp.xmit_fifo_size = state->xmit_fifo_size;
+	tmp.baud_base = state->baud_base;
+	tmp.close_delay = state->close_delay;
+	tmp.closing_wait = state->closing_wait;
+	tmp.custom_divisor = state->custom_divisor;
+	tmp.hub6 = state->hub6;
+	tmp.io_type = state->io_type;
+	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
+		return -EFAULT;
+	return 0;
+}
+
+static int set_serial_info(struct async_struct * info,
+			   struct serial_struct * new_info)
+{
+	struct serial_struct new_serial;
+ 	struct serial_state old_state, *state;
+	unsigned int		i,change_irq,change_port;
+	int 			retval = 0;
+	unsigned long		new_port;
+
+	if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
+		return -EFAULT;
+	state = info->state;
+	old_state = *state;
+
+	new_port = new_serial.port;
+	if (HIGH_BITS_OFFSET)
+		new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
+
+	change_irq = new_serial.irq != state->irq;
+	change_port = (new_port != ((int) state->port)) ||
+		(new_serial.hub6 != state->hub6);
+  
+	if (!capable(CAP_SYS_ADMIN)) {
+		if (change_irq || change_port ||
+		    (new_serial.baud_base != state->baud_base) ||
+		    (new_serial.type != state->type) ||
+		    (new_serial.close_delay != state->close_delay) ||
+		    (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
+		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
+		     (state->flags & ~ASYNC_USR_MASK)))
+			return -EPERM;
+		state->flags = ((state->flags & ~ASYNC_USR_MASK) |
+			       (new_serial.flags & ASYNC_USR_MASK));
+		info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+			       (new_serial.flags & ASYNC_USR_MASK));
+		state->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	new_serial.irq = irq_cannonicalize(new_serial.irq);
+
+	if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || 
+	    (new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) ||
+	    (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) ||
+	    (new_serial.type == PORT_STARTECH)) {
+		return -EINVAL;
+	}
+
+	if ((new_serial.type != state->type) ||
+	    (new_serial.xmit_fifo_size <= 0))
+		new_serial.xmit_fifo_size =
+			uart_config[new_serial.type].dfl_xmit_fifo_size;
+
+	// Make sure address is not already in use
+	if (new_serial.type) {
+		for (i = 0 ; i < NR_PORTS; i++)
+			if ((state != &rs_table[i]) &&
+			    (rs_table[i].port == new_port) &&
+			    rs_table[i].type)
+				return -EADDRINUSE;
+	}
+
+	if ((change_port || change_irq) && (state->count > 1))
+		return -EBUSY;
+
+	//
+	// OK, past this point, all the error checking has been done.
+	// At this point, we start making changes.....
+	//
+
+	state->baud_base = new_serial.baud_base;
+	state->flags = ((state->flags & ~ASYNC_FLAGS) |
+			(new_serial.flags & ASYNC_FLAGS));
+	info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
+		       (info->flags & ASYNC_INTERNAL_FLAGS));
+	state->custom_divisor = new_serial.custom_divisor;
+	state->close_delay = new_serial.close_delay * HZ/100;
+	state->closing_wait = new_serial.closing_wait * HZ/100;
+#if (LINUX_VERSION_CODE > 0x20100)
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+#endif
+	info->xmit_fifo_size = state->xmit_fifo_size =
+		new_serial.xmit_fifo_size;
+
+	if ((state->type != PORT_UNKNOWN) && state->port) {
+/*
+#ifdef CONFIG_SERIAL_RSA
+		if (old_state.type == PORT_RSA)
+			release_region(state->port + UART_RSA_BASE, 16);
+		else
+#endif
+*/
+		release_region(state->port,8);
+	}
+	state->type = new_serial.type;
+	if (change_port || change_irq) {
+		//
+		// We need to shutdown the serial port at the old
+		// port/irq combination.
+		//
+		shutdown(info);
+		state->irq = new_serial.irq;
+		info->port = state->port = new_port;
+		info->hub6 = state->hub6 = new_serial.hub6;
+		if (info->hub6)
+			info->io_type = state->io_type = SERIAL_IO_HUB6;
+		else if (info->io_type == SERIAL_IO_HUB6)
+			info->io_type = state->io_type = SERIAL_IO_PORT;
+	}
+	if ((state->type != PORT_UNKNOWN) && state->port) {
+/*
+#ifdef CONFIG_SERIAL_RSA
+		if (state->type == PORT_RSA)
+			request_region(state->port + UART_RSA_BASE,
+				       16, "serial_rsa(set)");
+		else
+#endif
+*/
+			request_region(state->port,8,"serial(set)");
+	}
+
+	
+check_and_exit:
+	if (!state->port || !state->type)
+		return 0;
+	if (info->flags & ASYNC_INITIALIZED) {
+		if (((old_state.flags & ASYNC_SPD_MASK) !=
+		     (state->flags & ASYNC_SPD_MASK)) ||
+		    (old_state.custom_divisor != state->custom_divisor)) {
+#if (LINUX_VERSION_CODE >= 131394) // Linux 2.1.66
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+				info->tty->alt_speed = 57600;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+				info->tty->alt_speed = 115200;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+				info->tty->alt_speed = 230400;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+				info->tty->alt_speed = 460800;
+#endif
+			change_speed(info, 0);
+		}
+	} else
+		retval = startup(info);
+	return retval;
+}
+
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    release the bus after transmitting. This must be done when
+ * 	    the transmit shift register is empty, not be done when the
+ * 	    transmit holding register is empty.  This functionality
+ * 	    allows an RS485 driver to be written in user space. 
+ */
+static int get_lsr_info(struct async_struct * info, unsigned int *value)
+{
+	unsigned char status;
+	unsigned int result;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	status = serial_in(info, UART_LSR);
+	restore_flags(flags);
+	result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
+
+	//
+	// If we're about to load something into the transmit
+	// register, we'll pretend the transmitter isn't empty to
+	// avoid a race condition (depending on when the transmit
+	// interrupt happens).
+	//
+	if (info->x_char || 
+	    ((CIRC_CNT(info->xmit.head, info->xmit.tail,
+		       SERIAL_XMIT_SIZE) > 0) &&
+	     !info->tty->stopped && !info->tty->hw_stopped))
+		result &= TIOCSER_TEMT;
+
+	if (copy_to_user(value, &result, sizeof(int)))
+		return -EFAULT;
+	return 0;
+}
+
+/*
+static int get_modem_info(struct async_struct * info, unsigned int *value)
+{
+	unsigned char control, status;
+	unsigned int result;
+	unsigned long flags;
+
+	control = info->MCR;
+	save_flags(flags); cli();
+	status = serial_in(info, UART_MSR);
+	restore_flags(flags);
+	result =  ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
+		| ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
+#ifdef TIOCM_OUT1
+		| ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0)
+		| ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0)
+#endif
+		| ((status  & UART_MSR_DCD) ? TIOCM_CAR : 0)
+		| ((status  & UART_MSR_RI) ? TIOCM_RNG : 0)
+		| ((status  & UART_MSR_DSR) ? TIOCM_DSR : 0)
+		| ((status  & UART_MSR_CTS) ? TIOCM_CTS : 0);
+
+	if (copy_to_user(value, &result, sizeof(int)))
+		return -EFAULT;
+	return 0;
+}
+*/
+/*
+static int set_modem_info(struct async_struct * info, unsigned int cmd,
+			  unsigned int *value)
+{
+	unsigned int arg;
+	unsigned long flags;
+
+	if (copy_from_user(&arg, value, sizeof(int)))
+		return -EFAULT;
+
+	switch (cmd) {
+	case TIOCMBIS: 
+		if (arg & TIOCM_RTS)
+			info->MCR |= UART_MCR_RTS;
+		if (arg & TIOCM_DTR)
+			info->MCR |= UART_MCR_DTR;
+#ifdef TIOCM_OUT1
+		if (arg & TIOCM_OUT1)
+			info->MCR |= UART_MCR_OUT1;
+		if (arg & TIOCM_OUT2)
+			info->MCR |= UART_MCR_OUT2;
+#endif
+		if (arg & TIOCM_LOOP)
+			info->MCR |= UART_MCR_LOOP;
+		break;
+	case TIOCMBIC:
+		if (arg & TIOCM_RTS)
+			info->MCR &= ~UART_MCR_RTS;
+		if (arg & TIOCM_DTR)
+			info->MCR &= ~UART_MCR_DTR;
+#ifdef TIOCM_OUT1
+		if (arg & TIOCM_OUT1)
+			info->MCR &= ~UART_MCR_OUT1;
+		if (arg & TIOCM_OUT2)
+			info->MCR &= ~UART_MCR_OUT2;
+#endif
+		if (arg & TIOCM_LOOP)
+			info->MCR &= ~UART_MCR_LOOP;
+		break;
+	case TIOCMSET:
+		info->MCR = ((info->MCR & ~(UART_MCR_RTS |
+#ifdef TIOCM_OUT1
+					    UART_MCR_OUT1 |
+					    UART_MCR_OUT2 |
+#endif
+					    UART_MCR_LOOP |
+					    UART_MCR_DTR))
+			     | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
+#ifdef TIOCM_OUT1
+			     | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0)
+			     | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0)
+#endif
+			     | ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0)
+			     | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0));
+		break;
+	default:
+		return -EINVAL;
+	}
+	save_flags(flags); cli();
+	info->MCR |= ALPHA_KLUDGE_MCR; 		// Don't ask
+	serial_out(info, UART_MCR, info->MCR);
+	restore_flags(flags);
+	return 0;
+}
+*/
+static int do_autoconfig(struct async_struct * info)
+{
+	int irq, retval;
+	
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	
+	if (info->state->count > 1)
+		return -EBUSY;
+	
+	shutdown(info);
+
+	autoconfig(info->state);
+	if ((info->state->flags & ASYNC_AUTO_IRQ) &&
+	    (info->state->port != 0) &&
+	    (info->state->type != PORT_UNKNOWN)) {
+		irq = detect_uart_irq(info->state);
+		if (irq > 0)
+			info->state->irq = irq;
+	}
+
+	retval = startup(info);
+	if (retval)
+		return retval;
+	return 0;
+}
+
+/*
+ * rs_break() --- routine which turns the break handling on or off
+ */
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+/*
+static void send_break(	struct async_struct * info, int duration)
+{
+	if (!CONFIGURED_SERIAL_PORT(info))
+		return;
+	current->state = TASK_INTERRUPTIBLE;
+	current->timeout = jiffies + duration;
+	cli();
+	info->LCR |= UART_LCR_SBC;
+	serial_out(info, UART_LCR, info->LCR);
+	schedule();
+	info->LCR &= ~UART_LCR_SBC;
+	serial_out(info, UART_LCR, info->LCR);
+	sti();
+}
+*/
+#else
+static void rs_break(struct tty_struct *tty, int break_state)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_break"))
+		return;
+
+	if (!CONFIGURED_SERIAL_PORT(info))
+		return;
+	save_flags(flags); cli();
+	if (break_state == -1)
+		info->LCR |= UART_LCR_SBC;
+	else
+		info->LCR &= ~UART_LCR_SBC;
+	serial_out(info, UART_LCR, info->LCR);
+	restore_flags(flags);
+}
+#endif
+
+#ifdef CONFIG_SERIAL_MULTIPORT
+/*
+static int get_multiport_struct(struct async_struct * info,
+				struct serial_multiport_struct *retinfo)
+{
+	struct serial_multiport_struct ret;
+	struct rs_multiport_struct *multi;
+	
+	multi = &rs_multiport[info->state->irq];
+
+	ret.port_monitor = multi->port_monitor;
+	
+	ret.port1 = multi->port1;
+	ret.mask1 = multi->mask1;
+	ret.match1 = multi->match1;
+	
+	ret.port2 = multi->port2;
+	ret.mask2 = multi->mask2;
+	ret.match2 = multi->match2;
+	
+	ret.port3 = multi->port3;
+	ret.mask3 = multi->mask3;
+	ret.match3 = multi->match3;
+	
+	ret.port4 = multi->port4;
+	ret.mask4 = multi->mask4;
+	ret.match4 = multi->match4;
+
+	ret.irq = info->state->irq;
+
+	if (copy_to_user(retinfo,&ret,sizeof(*retinfo)))
+		return -EFAULT;
+	return 0;
+}
+
+static int set_multiport_struct(struct async_struct * info,
+				struct serial_multiport_struct *in_multi)
+{
+	struct serial_multiport_struct new_multi;
+	struct rs_multiport_struct *multi;
+	struct serial_state *state;
+	int	was_multi, now_multi;
+	int	retval;
+	void (*handler)(int, void *, struct pt_regs *);
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	state = info->state;
+	
+	if (copy_from_user(&new_multi, in_multi,
+			   sizeof(struct serial_multiport_struct)))
+		return -EFAULT;
+	
+	if (new_multi.irq != state->irq || state->irq == 0 ||
+	    !IRQ_ports[state->irq])
+		return -EINVAL;
+
+	multi = &rs_multiport[state->irq];
+	was_multi = (multi->port1 != 0);
+	
+	multi->port_monitor = new_multi.port_monitor;
+	
+	if (multi->port1)
+		release_region(multi->port1,1);
+	multi->port1 = new_multi.port1;
+	multi->mask1 = new_multi.mask1;
+	multi->match1 = new_multi.match1;
+	if (multi->port1)
+		request_region(multi->port1,1,"serial(multiport1)");
+
+	if (multi->port2)
+		release_region(multi->port2,1);
+	multi->port2 = new_multi.port2;
+	multi->mask2 = new_multi.mask2;
+	multi->match2 = new_multi.match2;
+	if (multi->port2)
+		request_region(multi->port2,1,"serial(multiport2)");
+
+	if (multi->port3)
+		release_region(multi->port3,1);
+	multi->port3 = new_multi.port3;
+	multi->mask3 = new_multi.mask3;
+	multi->match3 = new_multi.match3;
+	if (multi->port3)
+		request_region(multi->port3,1,"serial(multiport3)");
+
+	if (multi->port4)
+		release_region(multi->port4,1);
+	multi->port4 = new_multi.port4;
+	multi->mask4 = new_multi.mask4;
+	multi->match4 = new_multi.match4;
+	if (multi->port4)
+		request_region(multi->port4,1,"serial(multiport4)");
+
+	now_multi = (multi->port1 != 0);
+	
+	if (IRQ_ports[state->irq]->next_port &&
+	    (was_multi != now_multi)) {
+		free_irq(state->irq, &IRQ_ports[state->irq]);
+		if (now_multi)
+			handler = rs_interrupt_multi;
+		else
+			handler = rs_interrupt;
+
+		retval = request_irq(state->irq, handler, SA_SHIRQ,
+				     "serial", &IRQ_ports[state->irq]);
+		if (retval) {
+			printk("Couldn't reallocate serial interrupt "
+			       "driver!!\n");
+		}
+	}
+	return 0;
+}
+*/
+#endif
+static int rs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct async_icount cprev, cnow;	// kernel counter temps
+	struct serial_icounter_struct icount;
+	unsigned long flags;
+#if (LINUX_VERSION_CODE < 131394) // Linux 2.1.66
+	int retval, tmp;
+#endif
+	
+	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+		return -ENODEV;
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+	
+	switch (cmd) {
+#if (LINUX_VERSION_CODE < 131394) // Linux 2.1.66
+		case TCSBRK:	// SVID version: non-zero arg --> no break
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (signal_pending(current))
+				return -EINTR;
+			if (!arg) {
+				send_break(info, HZ/4);	// 1/4 second
+				if (signal_pending(current))
+					return -EINTR;
+			}
+			return 0;
+		case TCSBRKP:	// support for POSIX tcsendbreak()
+			retval = tty_check_change(tty);
+			if (retval)
+				return retval;
+			tty_wait_until_sent(tty, 0);
+			if (signal_pending(current))
+				return -EINTR;
+			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+			if (signal_pending(current))
+				return -EINTR;
+			return 0;
+		case TIOCGSOFTCAR:
+			tmp = C_CLOCAL(tty) ? 1 : 0;
+			if (copy_to_user((void *)arg, &tmp, sizeof(int)))
+				return -EFAULT;
+			return 0;
+		case TIOCSSOFTCAR:
+			if (copy_from_user(&tmp, (void *)arg, sizeof(int)))
+				return -EFAULT;
+
+			tty->termios->c_cflag =
+				((tty->termios->c_cflag & ~CLOCAL) |
+				 (tmp ? CLOCAL : 0));
+			return 0;
+#endif
+/*
+		case TIOCMGET:
+			return get_modem_info(info, (unsigned int *) arg);
+		case TIOCMBIS:
+		case TIOCMBIC:
+		case TIOCMSET:
+			return set_modem_info(info, cmd, (unsigned int *) arg);
+*/
+		case TIOCGSERIAL:
+			return get_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSSERIAL:
+			return set_serial_info(info,
+					       (struct serial_struct *) arg);
+		case TIOCSERCONFIG:
+			return do_autoconfig(info);
+
+		case TIOCSERGETLSR: // Get line status register
+			return get_lsr_info(info, (unsigned int *) arg);
+
+		case TIOCSERGSTRUCT:
+			if (copy_to_user((struct async_struct *) arg,
+					 info, sizeof(struct async_struct)))
+				return -EFAULT;
+			return 0;
+				
+#ifdef CONFIG_SERIAL_MULTIPORT
+		case TIOCSERGETMULTI:
+			return get_multiport_struct(info,
+				       (struct serial_multiport_struct *) arg);
+		case TIOCSERSETMULTI:
+			return set_multiport_struct(info,
+				       (struct serial_multiport_struct *) arg);
+#endif
+			
+		//
+		// Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+		// - mask passed in arg for lines of interest
+ 		//   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+		// Caller should use TIOCGICOUNT to see which one it was
+		//
+		case TIOCMIWAIT:
+			save_flags(flags); cli();
+			// note the counters on entry
+			cprev = info->state->icount;
+			restore_flags(flags);
+			// Force modem status interrupts on
+/*
+			info->IER |= UART_IER_MSI;
+			serial_out(info, UART_IER, info->IER);
+*/
+			while (1) {
+				interruptible_sleep_on(&info->delta_msr_wait);
+				// see if a signal did it
+				if (signal_pending(current))
+					return -ERESTARTSYS;
+				save_flags(flags); cli();
+				cnow = info->state->icount; // atomic copy
+				restore_flags(flags);
+				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
+				    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+					return -EIO; // no change => error
+				if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+				     ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+				     ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
+				     ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
+					return 0;
+				}
+				cprev = cnow;
+			}
+			// NOTREACHED
+
+		// 
+		// Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+		// Return: write counters to the user passed counter struct
+		// NB: both 1->0 and 0->1 transitions are counted except for
+		//     RI where only 0->1 is counted.
+		//
+		case TIOCGICOUNT:
+			save_flags(flags); cli();
+			cnow = info->state->icount;
+			restore_flags(flags);
+			icount.cts = cnow.cts;
+			icount.dsr = cnow.dsr;
+			icount.rng = cnow.rng;
+			icount.dcd = cnow.dcd;
+			icount.rx = cnow.rx;
+			icount.tx = cnow.tx;
+			icount.frame = cnow.frame;
+			icount.overrun = cnow.overrun;
+			icount.parity = cnow.parity;
+			icount.brk = cnow.brk;
+			icount.buf_overrun = cnow.buf_overrun;
+			
+			if (copy_to_user((void *)arg, &icount, sizeof(icount)))
+				return -EFAULT;
+			return 0;
+		case TIOCSERGWILD:
+		case TIOCSERSWILD:
+			// "setserial -W" is called in Debian boot
+			printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
+			return 0;
+
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+//	unsigned long flags;
+	unsigned int cflag = tty->termios->c_cflag;
+	
+	if (   (cflag == old_termios->c_cflag)
+	    && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
+		== RELEVANT_IFLAG(old_termios->c_iflag)))
+	  return;
+
+	change_speed(info, old_termios);
+
+/*
+	// Handle transition to B0 status
+	if ((old_termios->c_cflag & CBAUD) &&
+	    !(cflag & CBAUD)) {
+		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
+		save_flags(flags); cli();
+		serial_out(info, UART_MCR, info->MCR);
+		restore_flags(flags);
+	}
+	
+	// Handle transition away from B0 status
+	if (!(old_termios->c_cflag & CBAUD) &&
+	    (cflag & CBAUD)) {
+		info->MCR |= UART_MCR_DTR;
+		if (!(tty->termios->c_cflag & CRTSCTS) || 
+		    !test_bit(TTY_THROTTLED, &tty->flags)) {
+			info->MCR |= UART_MCR_RTS;
+		}
+		save_flags(flags); cli();
+		serial_out(info, UART_MCR, info->MCR);
+		restore_flags(flags);
+	}
+*/
+	
+	// Handle turning off CRTSCTS
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+
+#if 0
+	//
+	// No need to wake up processes in open wait, since they
+	// sample the CLOCAL flag once, and don't recheck it.
+	// XXX  It's not clear whether the current behavior is correct
+	// or not.  Hence, this may change.....
+	//
+	if (!(old_termios->c_cflag & CLOCAL) &&
+	    (tty->termios->c_cflag & CLOCAL))
+		wake_up_interruptible(&info->open_wait);
+#endif
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct serial_state *state;
+	unsigned long flags;
+
+	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+		return;
+
+	state = info->state;
+	
+	save_flags(flags); cli();
+	
+	if (tty_hung_up_p(filp)) {
+		DBG_CNT("before DEC-hung");
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+	
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
+#endif
+	if ((tty->count == 1) && (state->count != 1)) {
+		//
+		// Uh, oh.  tty->count is 1, which means that the tty
+		// structure will be freed.  state->count should always
+		// be one in these conditions.  If it's greater than
+		// one, we've got real problems, since it means the
+		// serial port won't be shutdown.
+		//
+		printk("rs_close: bad serial port count; tty->count is 1, "
+		       "state->count is %d\n", state->count);
+		state->count = 1;
+	}
+	if (--state->count < 0) {
+		printk("rs_close: bad serial port count for ttys%d: %d\n",
+		       info->line, state->count);
+		state->count = 0;
+	}
+	if (state->count) {
+		DBG_CNT("before DEC-2");
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= ASYNC_CLOSING;
+	restore_flags(flags);
+	//
+	// Save the termios structure, since this port may have
+	// separate termios for callout and dialin.
+	//
+	if (info->flags & ASYNC_NORMAL_ACTIVE)
+		info->state->normal_termios = *tty->termios;
+	if (info->flags & ASYNC_CALLOUT_ACTIVE)
+		info->state->callout_termios = *tty->termios;
+	//
+	// Now we wait for the transmit buffer to clear; and we notify 
+	// the line discipline to only process XON/XOFF characters.
+	//
+	tty->closing = 1;
+	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	//
+	// At this point we stop accepting input.  To do this, we
+	// disable the receive line status interrupts, and tell the
+	// interrupt driver to stop checking the data ready bit in the
+	// line status register.
+	//
+	//info->IER &= ~UART_IER_RLSI;
+	info->read_status_mask &= ~UART_LSR_DR;
+	if (info->flags & ASYNC_INITIALIZED) {
+		//serial_out(info, UART_IER, info->IER);
+		enable_uart_rx_interrupt(info->line);
+		//
+		// Before we drop DTR, make sure the UART transmitter
+		// has completely drained; this is especially
+		// important if there is a transmit FIFO!
+		//
+		rs_wait_until_sent(tty, info->timeout);
+	}
+	shutdown(info);
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
+			 ASYNC_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	MOD_DEC_USE_COUNT;
+}
+
+/*
+ * rs_wait_until_sent() --- wait until the transmitter is empty
+ */
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	unsigned long orig_jiffies, char_time;
+	int lsr;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent"))
+		return;
+
+	if (info->state->type == PORT_UNKNOWN)
+		return;
+
+	if (info->xmit_fifo_size == 0)
+		return; // Just in case.... 
+
+	orig_jiffies = jiffies;
+	//
+	// Set the check interval to be 1/5 of the estimated time to
+	// send a single character, and make it at least 1.  The check
+	// interval should also be less than the timeout.
+	// 
+	// Note: we have to use pretty tight timings here to satisfy
+	// the NIST-PCTS.
+	//
+	char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
+	char_time = char_time / 5;
+	if (char_time == 0)
+		char_time = 1;
+	if (timeout && timeout < char_time)
+		char_time = timeout;
+	//
+	// If the transmitter hasn't cleared in twice the approximate
+	// amount of time to send the entire FIFO, it probably won't
+	// ever clear.  This assumes the UART isn't doing flow
+	// control, which is currently the case.  Hence, if it ever
+	// takes longer than info->timeout, this is probably due to a
+	// UART bug of some kind.  So, we clamp the timeout parameter at
+	// 2*info->timeout.
+	//
+	if (!timeout || timeout > 2*info->timeout)
+		timeout = 2*info->timeout;
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
+	printk("jiff=%lu...", jiffies);
+#endif
+	while (!((lsr = serial_inp(info, UART_LSR)) & UART_LSR_TEMT)) {
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+		printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
+#endif
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(char_time);
+		if (signal_pending(current))
+			break;
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			break;
+	}
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
+#endif
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void rs_hangup(struct tty_struct *tty)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct serial_state *state = info->state;
+	
+	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
+		return;
+
+	state = info->state;
+	
+	rs_flush_buffer(tty);
+	if (info->flags & ASYNC_CLOSING)
+		return;
+	shutdown(info);
+	info->event = 0;
+	state->count = 0;
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file * filp,
+			   struct async_struct *info)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	struct serial_state *state = info->state;
+	int		retval;
+	int		do_clocal = 0, extra_count = 0;
+	unsigned long	flags;
+
+	//
+	// If the device is in the middle of being closed, then block
+	// until it's done, and then try again.
+	//
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	//
+	// If this is a callout device, then just make sure the normal
+	// device isn't being used.
+	//
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & ASYNC_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+		    return -EBUSY;
+		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+		    return -EBUSY;
+		info->flags |= ASYNC_CALLOUT_ACTIVE;
+		return 0;
+	}
+	
+	//
+	// If non-blocking mode is set, or the port is not enabled,
+	// then make the check up front and then exit.
+	//
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) {
+		if (info->flags & ASYNC_CALLOUT_ACTIVE)
+			return -EBUSY;
+		info->flags |= ASYNC_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
+		if (state->normal_termios.c_cflag & CLOCAL)
+			do_clocal = 1;
+	} else {
+		if (tty->termios->c_cflag & CLOCAL)
+			do_clocal = 1;
+	}
+	
+	//
+	// Block waiting for the carrier detect and the line to become
+	// free (i.e., not in use by the callout).  While we are in
+	// this loop, state->count is dropped by one, so that
+	// rs_close() knows when to free things.  We restore it upon
+	// exit, either normal or abnormal.
+	//
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready before block: ttys%d, count = %d\n",
+	       state->line, state->count);
+#endif
+	save_flags(flags); cli();
+	if (!tty_hung_up_p(filp)) {
+		extra_count = 1;
+		state->count--;
+	}
+	restore_flags(flags);
+	info->blocked_open++;
+	while (1) {
+		save_flags(flags); cli();
+/*
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    (tty->termios->c_cflag & CBAUD))
+			serial_out(info, UART_MCR,
+				   serial_inp(info, UART_MCR) |
+				   (UART_MCR_DTR | UART_MCR_RTS));
+*/
+		restore_flags(flags);
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (tty_hung_up_p(filp) ||
+		    !(info->flags & ASYNC_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+			if (info->flags & ASYNC_HUP_NOTIFY)
+				retval = -EAGAIN;
+			else
+				retval = -ERESTARTSYS;	
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+/*
+		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+		    !(info->flags & ASYNC_CLOSING) &&
+		    (do_clocal || (serial_in(info, UART_MSR) &
+				   UART_MSR_DCD)))
+			break;
+*/
+		break;
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef SERIAL_DEBUG_OPEN
+		printk("block_til_ready blocking: ttys%d, count = %d\n",
+		       info->line, state->count);
+#endif
+		schedule();
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&info->open_wait, &wait);
+	if (extra_count)
+		state->count++;
+	info->blocked_open--;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("block_til_ready after blocking: ttys%d, count = %d\n",
+	       info->line, state->count);
+#endif
+	if (retval)
+		return retval;
+	info->flags |= ASYNC_NORMAL_ACTIVE;
+	return 0;
+}
+
+static int get_async_struct(int line, struct async_struct **ret_info)
+{
+	struct async_struct *info;
+	struct serial_state *sstate;
+
+	sstate = rs_table + line;
+	sstate->count++;
+	if (sstate->info) {
+		*ret_info = sstate->info;
+		return 0;
+	}
+	info = kmalloc(sizeof(struct async_struct), GFP_KERNEL);
+	if (!info) {
+		sstate->count--;
+		return -ENOMEM;
+	}
+	memset(info, 0, sizeof(struct async_struct));
+	init_waitqueue_head(&info->open_wait);
+	init_waitqueue_head(&info->close_wait);
+	init_waitqueue_head(&info->delta_msr_wait);
+	info->magic = SERIAL_MAGIC;
+	info->port = sstate->port;
+	info->flags = sstate->flags;
+	info->io_type = sstate->io_type;
+	info->iomem_base = sstate->iomem_base;
+	info->iomem_reg_shift = sstate->iomem_reg_shift;
+	info->xmit_fifo_size = sstate->xmit_fifo_size;
+	info->line = line;
+	info->tqueue.routine = do_softint;
+	info->tqueue.data = info;
+	info->state = sstate;
+	if (sstate->info) {
+		kfree(info);
+		*ret_info = sstate->info;
+		return 0;
+	}
+	*ret_info = sstate->info = info;
+	return 0;
+}
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+static int rs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct async_struct	*info;
+	int 			retval, line;
+	unsigned long		page;
+
+	MOD_INC_USE_COUNT;
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	if ((line < 0) || (line >= NR_PORTS)) {
+		MOD_DEC_USE_COUNT;
+		return -ENODEV;
+	}
+	retval = get_async_struct(line, &info);
+	if (retval) {
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+	tty->driver_data = info;
+	info->tty = tty;
+	if (serial_paranoia_check(info, tty->device, "rs_open")) {
+		MOD_DEC_USE_COUNT;		
+		return -ENODEV;
+	}
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+	       info->state->count);
+#endif
+#if (LINUX_VERSION_CODE > 0x20100)
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+#endif
+
+	//
+	//	This relies on lock_kernel() stuff so wants tidying for 2.5
+	//
+	if (!tmp_buf) {
+		page = get_zeroed_page(GFP_KERNEL);
+		if (!page) {
+			MOD_DEC_USE_COUNT;
+			return -ENOMEM;
+		}
+		if (tmp_buf)
+			free_page(page);
+		else
+			tmp_buf = (unsigned char *) page;
+	}
+
+	//
+	// If the port is the middle of closing, bail out now
+	//
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+		MOD_DEC_USE_COUNT;
+#ifdef SERIAL_DO_RESTART
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	//
+	// Start up serial port
+	//
+	retval = startup(info);
+	if (retval) {
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("rs_open returning after block_til_ready with %d\n",
+		       retval);
+#endif
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+
+	if ((info->state->count == 1) &&
+	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->state->normal_termios;
+		else 
+			*tty->termios = info->state->callout_termios;
+		change_speed(info, 0);
+	}
+#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
+	if (sercons.cflag && sercons.index == line) {
+		tty->termios->c_cflag = sercons.cflag;
+		sercons.cflag = 0;
+		change_speed(info, 0);
+	}
+#endif
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open ttys%d successful...", info->line);
+#endif
+	return 0;
+}
+
+/*
+ * /proc fs routines....
+ */
+static inline int line_info(char *buf, struct serial_state *state)
+{
+	struct async_struct *info = state->info, scr_info;
+//	char	stat_buf[30], control, status;
+	char	stat_buf[30];
+	int	ret;
+	//unsigned long flags;
+
+	ret = sprintf(buf, "%d: uart:%s port:%lX irq:%d",
+		      state->line, uart_config[state->type].name, 
+		      state->port, state->irq);
+
+	if (!state->port || (state->type == PORT_UNKNOWN)) {
+		ret += sprintf(buf+ret, "\n");
+		return ret;
+	}
+
+	//
+	// Figure out the current RS-232 lines
+	//
+	if (!info) {
+		info = &scr_info;	// This is just for serial_{in,out}
+
+		info->magic = SERIAL_MAGIC;
+		info->port = state->port;
+		info->flags = state->flags;
+		info->hub6 = state->hub6;
+		info->io_type = state->io_type;
+		info->iomem_base = state->iomem_base;
+		info->iomem_reg_shift = state->iomem_reg_shift;
+		info->quot = 0;
+		info->tty = 0;
+	}
+	stat_buf[0] = 0;
+	stat_buf[1] = 0;
+/*
+	save_flags(flags); cli();
+	status = serial_in(info, UART_MSR);
+	control = info != &scr_info ? info->MCR : serial_in(info, UART_MCR);
+	restore_flags(flags); 
+
+	stat_buf[0] = 0;
+	stat_buf[1] = 0;
+	if (control & UART_MCR_RTS)
+		strcat(stat_buf, "|RTS");
+	if (status & UART_MSR_CTS)
+		strcat(stat_buf, "|CTS");
+	if (control & UART_MCR_DTR)
+		strcat(stat_buf, "|DTR");
+	if (status & UART_MSR_DSR)
+		strcat(stat_buf, "|DSR");
+	if (status & UART_MSR_DCD)
+		strcat(stat_buf, "|CD");
+	if (status & UART_MSR_RI)
+		strcat(stat_buf, "|RI");
+*/
+	if (info->quot) {
+		ret += sprintf(buf+ret, " baud:%d",
+			       state->baud_base / info->quot);
+	}
+
+	ret += sprintf(buf+ret, " tx:%d rx:%d",
+		      state->icount.tx, state->icount.rx);
+
+	if (state->icount.frame)
+		ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
+	
+	if (state->icount.parity)
+		ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
+	
+	if (state->icount.brk)
+		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);	
+
+	if (state->icount.overrun)
+		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
+
+	//
+	// Last thing is the RS-232 status lines
+	//
+	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+	return ret;
+}
+
+int rs_read_proc(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	int i, len = 0, l;
+	off_t	begin = 0;
+
+	len += sprintf(page, "serinfo:1.0 driver:%s%s revision:%s\n",
+		       serial_version, LOCAL_VERSTRING, serial_revdate);
+	for (i = 0; i < NR_PORTS && len < 4000; i++) {
+		l = line_info(page + len, &rs_table[i]);
+		len += l;
+		if (len+begin > off+count)
+			goto done;
+		if (len+begin < off) {
+			begin += len;
+			len = 0;
+		}
+	}
+	*eof = 1;
+done:
+	if (off >= len+begin)
+		return 0;
+	*start = page + (off-begin);
+	return ((count < begin+len-off) ? count : begin+len-off);
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * rs_init() and friends
+ *
+ * rs_init() is called at boot-time to initialize the serial driver.
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * This routine prints out the appropriate serial driver version
+ * number, and identifies which options were configured into this
+ * driver.
+ */
+static char serial_options[] __initdata =
+#ifdef CONFIG_HUB6
+       " HUB-6"
+#define SERIAL_OPT
+#endif
+#ifdef CONFIG_SERIAL_MANY_PORTS
+       " MANY_PORTS"
+#define SERIAL_OPT
+#endif
+#ifdef CONFIG_SERIAL_MULTIPORT
+       " MULTIPORT"
+#define SERIAL_OPT
+#endif
+#ifdef CONFIG_SERIAL_SHARE_IRQ
+       " SHARE_IRQ"
+#define SERIAL_OPT
+#endif
+#ifdef CONFIG_SERIAL_DETECT_IRQ
+       " DETECT_IRQ"
+#define SERIAL_OPT
+#endif
+#ifdef ENABLE_SERIAL_PCI
+       " SERIAL_PCI"
+#define SERIAL_OPT
+#endif
+#ifdef ENABLE_SERIAL_PNP
+       " ISAPNP"
+#define SERIAL_OPT
+#endif
+#ifdef SERIAL_OPT
+       " enabled\n";
+#else
+       " no serial options enabled\n";
+#endif
+#undef SERIAL_OPT
+
+static _INLINE_ void show_serial_version(void)
+{
+ 	printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name,
+	       serial_version, LOCAL_VERSTRING, serial_revdate,
+	       serial_options);
+}
+
+/*
+ * This routine detect the IRQ of a serial port by clearing OUT2 when
+ * no UART interrupt are requested (IER = 0) (*GPL*). This seems to work at
+ * each time, as long as no other device permanently request the IRQ.
+ * If no IRQ is detected, or multiple IRQ appear, this function returns 0.
+ * The variable "state" and the field "state->port" should not be null.
+ */
+static unsigned detect_uart_irq (struct serial_state * state)
+{
+/*
+	int irq;
+	unsigned long irqs;
+	unsigned char save_mcr, save_ier;
+	struct async_struct scr_info; // serial_{in,out} because HUB6
+
+#ifdef CONFIG_SERIAL_MANY_PORTS
+	unsigned char save_ICP=0; // no warning
+	unsigned short ICP=0;
+
+	if (state->flags & ASYNC_FOURPORT)  {
+		ICP = (state->port & 0xFE0) | 0x01F;
+		save_ICP = inb_p(ICP);
+		outb_p(0x80, ICP);
+		(void) inb_p(ICP);
+	}
+#endif
+	scr_info.magic = SERIAL_MAGIC;
+	scr_info.state = state;
+	scr_info.port = state->port;
+	scr_info.flags = state->flags;
+#ifdef CONFIG_HUB6
+	scr_info.hub6 = state->hub6;
+#endif
+	scr_info.io_type = state->io_type;
+	scr_info.iomem_base = state->iomem_base;
+	scr_info.iomem_reg_shift = state->iomem_reg_shift;
+
+	// forget possible initially masked and pending IRQ
+	probe_irq_off(probe_irq_on());
+	save_mcr = serial_inp(&scr_info, UART_MCR);
+	save_ier = serial_inp(&scr_info, UART_IER);
+	serial_outp(&scr_info, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
+	
+	irqs = probe_irq_on();
+	serial_outp(&scr_info, UART_MCR, 0);
+	udelay (10);
+	if (state->flags & ASYNC_FOURPORT)  {
+		serial_outp(&scr_info, UART_MCR,
+			    UART_MCR_DTR | UART_MCR_RTS);
+	} else {
+		serial_outp(&scr_info, UART_MCR,
+			    UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
+	}
+	serial_outp(&scr_info, UART_IER, 0x0f);	// enable all intrs
+	(void)serial_inp(&scr_info, UART_LSR);
+	(void)serial_inp(&scr_info, UART_RX);
+	(void)serial_inp(&scr_info, UART_IIR);
+	(void)serial_inp(&scr_info, UART_MSR);
+	serial_outp(&scr_info, UART_TX, 0xFF);
+	udelay (20);
+	irq = probe_irq_off(irqs);
+
+	serial_outp(&scr_info, UART_MCR, save_mcr);
+	serial_outp(&scr_info, UART_IER, save_ier);
+#ifdef CONFIG_SERIAL_MANY_PORTS
+	if (state->flags & ASYNC_FOURPORT)
+		outb_p(save_ICP, ICP);
+#endif
+	return (irq > 0)? irq : 0;
+*/
+	return 0;
+}
+
+/*
+ * This is a quickie test to see how big the FIFO is.
+ * It doesn't work at all the time, more's the pity.
+ */
+/*
+static int size_fifo(struct async_struct *info)
+{
+	unsigned char old_fcr, old_mcr, old_dll, old_dlm;
+	int count;
+
+	old_fcr = serial_inp(info, UART_FCR);
+	old_mcr = serial_inp(info, UART_MCR);
+	serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO |
+		    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+	serial_outp(info, UART_MCR, UART_MCR_LOOP);
+	serial_outp(info, UART_LCR, UART_LCR_DLAB);
+	old_dll = serial_inp(info, UART_DLL);
+	old_dlm = serial_inp(info, UART_DLM);
+	serial_outp(info, UART_DLL, 0x01);
+	serial_outp(info, UART_DLM, 0x00);
+	serial_outp(info, UART_LCR, 0x03);
+	for (count = 0; count < 256; count++)
+		serial_outp(info, UART_TX, count);
+	mdelay(20);
+	for (count = 0; (serial_inp(info, UART_LSR) & UART_LSR_DR) &&
+	     (count < 256); count++)
+		serial_inp(info, UART_RX);
+	serial_outp(info, UART_FCR, old_fcr);
+	serial_outp(info, UART_MCR, old_mcr);
+	serial_outp(info, UART_LCR, UART_LCR_DLAB);
+	serial_outp(info, UART_DLL, old_dll);
+	serial_outp(info, UART_DLM, old_dlm);
+
+	return count;
+}
+*/
+/*
+ * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
+ * When this function is called we know it is at least a StarTech
+ * 16650 V2, but it might be one of several StarTech UARTs, or one of
+ * its clones.  (We treat the broken original StarTech 16650 V1 as a
+ * 16550, and why not?  Startech doesn't seem to even acknowledge its
+ * existence.)
+ * 
+ * What evil have men's minds wrought...
+ */
+/*
+static void autoconfig_startech_uarts(struct async_struct *info,
+				      struct serial_state *state,
+				      unsigned long flags)
+{
+	unsigned char scratch, scratch2, scratch3, scratch4;
+
+	//
+	// First we check to see if it's an Oxford Semiconductor UART.
+	//
+	// If we have to do this here because some non-National
+	// Semiconductor clone chips lock up if you try writing to the
+	// LSR register (which serial_icr_read does)
+	//
+	if (state->type == PORT_16550A) {
+		//
+		// EFR [4] must be set else this test fails
+		//
+		// This shouldn't be necessary, but Mike Hudson
+		// (Exoray@isys.ca) claims that it's needed for 952
+		// dual UART's (which are not recommended for new designs).
+		//
+		info->ACR = 0;
+		serial_out(info, UART_LCR, 0xBF);
+		serial_out(info, UART_EFR, 0x10);
+		serial_out(info, UART_LCR, 0x00);
+		// Check for Oxford Semiconductor 16C950
+		scratch = serial_icr_read(info, UART_ID1);
+		scratch2 = serial_icr_read(info, UART_ID2);
+		scratch3 = serial_icr_read(info, UART_ID3);
+		
+		if (scratch == 0x16 && scratch2 == 0xC9 &&
+		    (scratch3 == 0x50 || scratch3 == 0x52 ||
+		     scratch3 == 0x54)) {
+			state->type = PORT_16C950;
+			state->revision = serial_icr_read(info, UART_REV) |
+				(scratch3 << 8);
+			return;
+		}
+	}
+	
+	//
+	// We check for a XR16C850 by setting DLL and DLM to 0, and
+	// then reading back DLL and DLM.  If DLM reads back 0x10,
+	// then the UART is a XR16C850 and the DLL contains the chip
+	// revision.  If DLM reads back 0x14, then the UART is a
+	// XR16C854.
+	// 
+	//
+
+	// Save the DLL and DLM
+
+	serial_outp(info, UART_LCR, UART_LCR_DLAB);
+	scratch3 = serial_inp(info, UART_DLL);
+	scratch4 = serial_inp(info, UART_DLM);
+
+	serial_outp(info, UART_DLL, 0);
+	serial_outp(info, UART_DLM, 0);
+	scratch2 = serial_inp(info, UART_DLL);
+	scratch = serial_inp(info, UART_DLM);
+	serial_outp(info, UART_LCR, 0);
+
+	if (scratch == 0x10 || scratch == 0x14) {
+		if (scratch == 0x10)
+			state->revision = scratch2;
+		state->type = PORT_16850;
+		return;
+	}
+
+	// Restore the DLL and DLM
+
+	serial_outp(info, UART_LCR, UART_LCR_DLAB);
+	serial_outp(info, UART_DLL, scratch3);
+	serial_outp(info, UART_DLM, scratch4);
+	serial_outp(info, UART_LCR, 0);
+	//
+	// We distinguish between the '654 and the '650 by counting
+	// how many bytes are in the FIFO.  I'm using this for now,
+	// since that's the technique that was sent to me in the
+	// serial driver update, but I'm not convinced this works.
+	// I've had problems doing this in the past.  -TYT
+	//
+	if (size_fifo(info) == 64)
+		state->type = PORT_16654;
+	else
+		state->type = PORT_16650V2;
+}
+*/
+/*
+ * This routine is called by rs_init() to initialize a specific serial
+ * port.  It determines what type of UART chip this serial port is
+ * using: 8250, 16450, 16550, 16550A.  The important question is
+ * whether or not this UART is a 16550A or not, since this will
+ * determine whether or not we can use its FIFO features or not.
+ */
+static void autoconfig(struct serial_state * state)
+{
+//	unsigned char status1, status2, scratch, scratch2, scratch3;
+//	unsigned char save_lcr, save_mcr;
+	struct async_struct *info, scr_info;
+	unsigned long flags;
+
+	state->type = PORT_UNKNOWN;
+
+#ifdef SERIAL_DEBUG_AUTOCONF
+	printk("Testing ttyS%d (0x%04lx, 0x%04x)...\n", state->line,
+	       state->port, (unsigned) state->iomem_base);
+#endif
+	
+	if (!CONFIGURED_SERIAL_PORT(state))
+		return;
+		
+	info = &scr_info;	// This is just for serial_{in,out}
+
+	info->magic = SERIAL_MAGIC;
+	info->state = state;
+	info->port = state->port;
+	info->flags = state->flags;
+#ifdef CONFIG_HUB6
+	info->hub6 = state->hub6;
+#endif
+	info->io_type = state->io_type;
+	info->iomem_base = state->iomem_base;
+	info->iomem_reg_shift = state->iomem_reg_shift;
+
+	save_flags(flags); cli();
+
+/*	
+	if (!(state->flags & ASYNC_BUGGY_UART) &&
+	    !state->iomem_base) {
+		//
+		// Do a simple existence test first; if we fail this,
+		// there's no point trying anything else.
+		// 
+		// 0x80 is used as a nonsense port to prevent against
+		// false positives due to ISA bus float.  The
+		// assumption is that 0x80 is a non-existent port;
+		// which should be safe since include/asm/io.h also
+		// makes this assumption.
+		//
+		scratch = serial_inp(info, UART_IER);
+		serial_outp(info, UART_IER, 0);
+#ifdef __i386__
+		outb(0xff, 0x080);
+#endif
+		scratch2 = serial_inp(info, UART_IER);
+		serial_outp(info, UART_IER, 0x0F);
+#ifdef __i386__
+		outb(0, 0x080);
+#endif
+		scratch3 = serial_inp(info, UART_IER);
+		serial_outp(info, UART_IER, scratch);
+		if (scratch2 || scratch3 != 0x0F) {
+#ifdef SERIAL_DEBUG_AUTOCONF
+			printk("serial: ttyS%d: simple autoconfig failed "
+			       "(%02x, %02x)\n", state->line, 
+			       scratch2, scratch3);
+#endif
+			restore_flags(flags);
+			return;		// We failed; there's nothing here
+		}
+	}
+*/
+/*
+	save_mcr = serial_in(info, UART_MCR);
+	save_lcr = serial_in(info, UART_LCR);
+*/
+	// 
+	// Check to see if a UART is really there.  Certain broken
+	// internal modems based on the Rockwell chipset fail this
+	// test, because they apparently don't implement the loopback
+	// test mode.  So this test is skipped on the COM 1 through
+	// COM 4 ports.  This *should* be safe, since no board
+	// manufacturer would be stupid enough to design a board
+	// that conflicts with COM 1-4 --- we hope!
+	//
+/*
+	if (!(state->flags & ASYNC_SKIP_TEST)) {
+		serial_outp(info, UART_MCR, UART_MCR_LOOP | 0x0A);
+		status1 = serial_inp(info, UART_MSR) & 0xF0;
+		serial_outp(info, UART_MCR, save_mcr);
+		if (status1 != 0x90) {
+#ifdef SERIAL_DEBUG_AUTOCONF
+			printk("serial: ttyS%d: no UART loopback failed\n",
+			       state->line);
+#endif
+			restore_flags(flags);
+			return;
+		}
+	}
+	serial_outp(info, UART_LCR, 0xBF); // set up for StarTech test
+	serial_outp(info, UART_EFR, 0);	// EFR is the same as FCR
+	serial_outp(info, UART_LCR, 0);
+	serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
+	scratch = serial_in(info, UART_IIR) >> 6;
+	switch (scratch) {
+		case 0:
+			state->type = PORT_16450;
+			break;
+		case 1:
+			state->type = PORT_UNKNOWN;
+			break;
+		case 2:
+			state->type = PORT_16550;
+			break;
+		case 3:
+			state->type = PORT_16550A;
+			break;
+	}
+	if (state->type == PORT_16550A) {
+		// Check for Startech UART's
+		serial_outp(info, UART_LCR, UART_LCR_DLAB);
+		if (serial_in(info, UART_EFR) == 0) {
+			state->type = PORT_16650;
+		} else {
+			serial_outp(info, UART_LCR, 0xBF);
+			if (serial_in(info, UART_EFR) == 0)
+				autoconfig_startech_uarts(info, state, flags);
+		}
+	}
+	if (state->type == PORT_16550A) {
+		// Check for TI 16750
+		serial_outp(info, UART_LCR, save_lcr | UART_LCR_DLAB);
+		serial_outp(info, UART_FCR,
+			    UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
+		scratch = serial_in(info, UART_IIR) >> 5;
+		if (scratch == 7) {
+			//
+			// If this is a 16750, and not a cheap UART
+			// clone, then it should only go into 64 byte
+			// mode if the UART_FCR7_64BYTE bit was set
+			// while UART_LCR_DLAB was latched.
+			//
+ 			serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
+			serial_outp(info, UART_LCR, 0);
+			serial_outp(info, UART_FCR,
+				    UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
+			scratch = serial_in(info, UART_IIR) >> 5;
+			if (scratch == 6)
+				state->type = PORT_16750;
+		}
+		serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
+	}
+#if defined(CONFIG_SERIAL_RSA) && defined(MODULE)
+	if (state->type == PORT_16550A) {
+		int i;
+
+		for (i = 0 ; i < PORT_RSA_MAX ; ++i) {
+			if (!probe_rsa[i] && !force_rsa[i])
+				break;
+			if (((probe_rsa[i] != state->port) ||
+			     check_region(state->port + UART_RSA_BASE, 16)) &&
+			    (force_rsa[i] != state->port))
+				continue;
+			if (!enable_rsa(info))
+				continue;
+			state->type = PORT_RSA;
+			state->baud_base = SERIAL_RSA_BAUD_BASE;
+			break;
+		}
+	}
+#endif
+	serial_outp(info, UART_LCR, save_lcr);
+	if (state->type == PORT_16450) {
+		scratch = serial_in(info, UART_SCR);
+		serial_outp(info, UART_SCR, 0xa5);
+		status1 = serial_in(info, UART_SCR);
+		serial_outp(info, UART_SCR, 0x5a);
+		status2 = serial_in(info, UART_SCR);
+		serial_outp(info, UART_SCR, scratch);
+
+		if ((status1 != 0xa5) || (status2 != 0x5a))
+			state->type = PORT_8250;
+	}
+*/
+	state->type = PORT_S3C4510B;
+	state->xmit_fifo_size =	uart_config[state->type].dfl_xmit_fifo_size;
+
+	if (state->type == PORT_UNKNOWN) {
+		restore_flags(flags);
+		return;
+	}
+
+	if (info->port) {
+/*
+#ifdef CONFIG_SERIAL_RSA
+		if (state->type == PORT_RSA)
+			request_region(info->port + UART_RSA_BASE, 16,
+				       "serial_rsa(auto)");
+		else
+#endif
+*/
+			request_region(info->port,8,"serial(auto)");
+	}
+
+	//
+	// Reset the UART.
+	//
+/*
+#ifdef CONFIG_SERIAL_RSA
+	if (state->type == PORT_RSA)
+		serial_outp(info, UART_RSA_FRR, 0);
+#endif
+	serial_outp(info, UART_MCR, save_mcr);
+	serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
+				     UART_FCR_CLEAR_RCVR |
+				     UART_FCR_CLEAR_XMIT));
+	serial_outp(info, UART_FCR, 0);
+*/
+	serial_outp(info, UART_LCR, UART_LCR_WLEN8);
+	serial_outp(info, UART_GCR, UART_GCR_RX_INT|UART_GCR_TX_INT);
+	(void)serial_in(info, UART_RX);
+//	serial_outp(info, UART_IER, 0);
+	
+	restore_flags(flags);
+}
+
+
+int register_serial(struct serial_struct *req);
+void unregister_serial(int line);
+
+#if (LINUX_VERSION_CODE > 0x20100)
+EXPORT_SYMBOL(register_serial);
+EXPORT_SYMBOL(unregister_serial);
+#else
+static struct symbol_table serial_syms = {
+#include <linux/symtab_begin.h>
+	X(register_serial),
+	X(unregister_serial),
+#include <linux/symtab_end.h>
+};
+#endif
+
+/*
+ * The serial driver boot-time initialization code!
+ */
+static int __init rs_init(void)
+{
+	int i;
+	struct serial_state * state;
+
+	init_bh(SERIAL_BH, do_serial_bh);
+	init_timer(&serial_timer);
+	serial_timer.function = rs_timer;
+	mod_timer(&serial_timer, jiffies + RS_STROBE_TIME);
+
+	for (i = 0; i < NR_IRQS; i++) {
+		IRQ_ports[i] = 0;
+		IRQ_timeout[i] = 0;
+#ifdef CONFIG_SERIAL_MULTIPORT
+		memset(&rs_multiport[i], 0,
+		       sizeof(struct rs_multiport_struct));
+#endif
+	}
+#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
+	//
+	//	The interrupt of the serial console port
+	//	can't be shared.
+	//
+	if (sercons.flags & CON_CONSDEV) {
+		for(i = 0; i < NR_PORTS; i++)
+			if (i != sercons.index &&
+			    rs_table[i].irq == rs_table[sercons.index].irq)
+				rs_table[i].irq = 0;
+	}
+#endif
+	show_serial_version();
+
+	// Initialize the tty_driver structure
+	
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+#if (LINUX_VERSION_CODE > 0x20100)
+	serial_driver.driver_name = "serial";
+#endif
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	serial_driver.name = "tts/%d";
+#else
+	serial_driver.name = "ttyS";
+#endif
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64 + SERIAL_DEV_OFFSET;
+	serial_driver.num = NR_PORTS;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+	serial_driver.init_termios.c_cflag =
+		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = rs_open;
+	serial_driver.close = rs_close;
+	serial_driver.write = rs_write;
+	serial_driver.put_char = rs_put_char;
+	serial_driver.flush_chars = rs_flush_chars;
+	serial_driver.write_room = rs_write_room;
+	serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	serial_driver.flush_buffer = rs_flush_buffer;
+	serial_driver.ioctl = rs_ioctl;
+	serial_driver.throttle = rs_throttle;
+	serial_driver.unthrottle = rs_unthrottle;
+	serial_driver.set_termios = rs_set_termios;
+	serial_driver.stop = rs_stop;
+	serial_driver.start = rs_start;
+	serial_driver.hangup = rs_hangup;
+#if (LINUX_VERSION_CODE >= 131394) // Linux 2.1.66
+	serial_driver.break_ctl = rs_break;
+#endif
+#if (LINUX_VERSION_CODE >= 131343)
+	serial_driver.send_xchar = rs_send_xchar;
+	serial_driver.wait_until_sent = rs_wait_until_sent;
+	serial_driver.read_proc = rs_read_proc;
+#endif
+	
+	//
+	// The callout device is just like normal device except for
+	// major number and the subtype code.
+	//
+	callout_driver = serial_driver;
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	callout_driver.name = "cua/%d";
+#else
+	callout_driver.name = "cua";
+#endif
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+#if (LINUX_VERSION_CODE >= 131343)
+	callout_driver.read_proc = 0;
+	callout_driver.proc_entry = 0;
+#endif
+
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register serial driver\n");
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+	
+	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
+		state->magic = SSTATE_MAGIC;
+		state->line = i;
+		state->type = PORT_UNKNOWN;
+		state->custom_divisor = 0;
+		state->close_delay = 5*HZ/10;
+		state->closing_wait = 30*HZ;
+		state->callout_termios = callout_driver.init_termios;
+		state->normal_termios = serial_driver.init_termios;
+		state->icount.cts = state->icount.dsr = 
+			state->icount.rng = state->icount.dcd = 0;
+		state->icount.rx = state->icount.tx = 0;
+		state->icount.frame = state->icount.parity = 0;
+		state->icount.overrun = state->icount.brk = 0;
+		state->irq = irq_cannonicalize(state->irq);
+		if (state->hub6)
+			state->io_type = SERIAL_IO_HUB6;
+		if (state->port && check_region(state->port,8))
+			continue;
+#ifdef CONFIG_MCA			
+		if ((state->flags & ASYNC_BOOT_ONLYMCA) && !MCA_bus)
+			continue;
+#endif			
+		if (state->flags & ASYNC_BOOT_AUTOCONF)
+			autoconfig(state);
+	}
+	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
+		if (state->type == PORT_UNKNOWN)
+			continue;
+		if (   (state->flags & ASYNC_BOOT_AUTOCONF)
+		    && (state->flags & ASYNC_AUTO_IRQ)
+		    && (state->port != 0))
+			state->irq = detect_uart_irq(state);
+		printk(KERN_INFO "ttyS%02d%s at 0x%04lx (irq = %d) is a %s\n",
+		       state->line + SERIAL_DEV_OFFSET,
+		       (state->flags & ASYNC_FOURPORT) ? " FourPort" : "",
+		       state->port, state->irq,
+		       uart_config[state->type].name);
+		tty_register_devfs(&serial_driver, 0,
+				   serial_driver.minor_start + state->line);
+		tty_register_devfs(&callout_driver, 0,
+				   callout_driver.minor_start + state->line);
+	}
+#ifdef ENABLE_SERIAL_PCI
+	probe_serial_pci();
+#endif
+#ifdef ENABLE_SERIAL_PNP
+       probe_serial_pnp();
+#endif
+	return 0;
+}
+/*
+ * This is for use by architectures that know their serial console 
+ * attributes only at run time. Not to be invoked after rs_init().
+ */
+/*
+int __init early_serial_setup(struct serial_struct *req)
+{
+	int i = req->line;
+
+	if (i >= NR_IRQS)
+		return(-ENOENT);
+	rs_table[i].magic = 0;
+	rs_table[i].baud_base = req->baud_base;
+	rs_table[i].port = req->port;
+	if (HIGH_BITS_OFFSET)
+		rs_table[i].port += (unsigned long) req->port_high << 
+							HIGH_BITS_OFFSET;
+	rs_table[i].irq = req->irq;
+	rs_table[i].flags = req->flags;
+	rs_table[i].close_delay = req->close_delay;
+	rs_table[i].io_type = req->io_type;
+	rs_table[i].hub6 = req->hub6;
+	rs_table[i].iomem_base = req->iomem_base;
+	rs_table[i].iomem_reg_shift = req->iomem_reg_shift;
+	rs_table[i].type = req->type;
+	rs_table[i].xmit_fifo_size = req->xmit_fifo_size;
+	rs_table[i].custom_divisor = req->custom_divisor;
+	rs_table[i].closing_wait = req->closing_wait;
+	return(0);
+}
+*/
+/*
+ * register_serial and unregister_serial allows for 16x50 serial ports to be
+ * configured at run-time, to support PCMCIA modems.
+ */
+ 
+/**
+ *	register_serial - configure a 16x50 serial port at runtime
+ *	@req: request structure
+ *
+ *	Configure the serial port specified by the request. If the
+ *	port exists and is in use an error is returned. If the port
+ *	is not currently in the table it is added.
+ *
+ *	The port is then probed and if neccessary the IRQ is autodetected
+ *	If this fails an error is returned.
+ *
+ *	On success the port is ready to use and the line number is returned.
+ */
+/*
+int register_serial(struct serial_struct *req)
+{
+	int i;
+	unsigned long flags;
+	struct serial_state *state;
+	struct async_struct *info;
+	unsigned long port;
+
+	port = req->port;
+	if (HIGH_BITS_OFFSET)
+		port += (unsigned long) req->port_high << HIGH_BITS_OFFSET;
+
+	save_flags(flags); cli();
+	for (i = 0; i < NR_PORTS; i++) {
+		if ((rs_table[i].port == port) &&
+		    (rs_table[i].iomem_base == req->iomem_base))
+			break;
+	}
+#ifdef __i386__
+	if (i == NR_PORTS) {
+		for (i = 4; i < NR_PORTS; i++)
+			if ((rs_table[i].type == PORT_UNKNOWN) &&
+			    (rs_table[i].count == 0))
+				break;
+	}
+#endif
+	if (i == NR_PORTS) {
+		for (i = 0; i < NR_PORTS; i++)
+			if ((rs_table[i].type == PORT_UNKNOWN) &&
+			    (rs_table[i].count == 0))
+				break;
+	}
+	if (i == NR_PORTS) {
+		restore_flags(flags);
+		return -1;
+	}
+	state = &rs_table[i];
+	if (rs_table[i].count) {
+		restore_flags(flags);
+		printk("Couldn't configure serial #%d (port=%ld,irq=%d): "
+		       "device already open\n", i, port, req->irq);
+		return -1;
+	}
+	state->irq = req->irq;
+	state->port = port;
+	state->flags = req->flags;
+	state->io_type = req->io_type;
+	state->iomem_base = req->iomem_base;
+	state->iomem_reg_shift = req->iomem_reg_shift;
+	if (req->baud_base)
+		state->baud_base = req->baud_base;
+	if ((info = state->info) != NULL) {
+		info->port = port;
+		info->flags = req->flags;
+		info->io_type = req->io_type;
+		info->iomem_base = req->iomem_base;
+		info->iomem_reg_shift = req->iomem_reg_shift;
+	}
+	autoconfig(state);
+	if (state->type == PORT_UNKNOWN) {
+		restore_flags(flags);
+		printk("register_serial(): autoconfig failed\n");
+		return -1;
+	}
+	restore_flags(flags);
+
+	if ((state->flags & ASYNC_AUTO_IRQ) && CONFIGURED_SERIAL_PORT(state))
+		state->irq = detect_uart_irq(state);
+
+       printk(KERN_INFO "ttyS%02d at %s 0x%04lx (irq = %d) is a %s\n",
+	      state->line + SERIAL_DEV_OFFSET,
+	      state->iomem_base ? "iomem" : "port",
+	      state->iomem_base ? (unsigned long)state->iomem_base :
+	      state->port, state->irq, uart_config[state->type].name);
+	tty_register_devfs(&serial_driver, 0,
+			   serial_driver.minor_start + state->line); 
+	tty_register_devfs(&callout_driver, 0,
+			   callout_driver.minor_start + state->line);
+	return state->line + SERIAL_DEV_OFFSET;
+}
+*/
+/**
+ *	unregister_serial - deconfigure a 16x50 serial port
+ *	@line: line to deconfigure
+ *
+ *	The port specified is deconfigured and its resources are freed. Any
+ *	user of the port is disconnected as if carrier was dropped. Line is
+ *	the port number returned by register_serial().
+ */
+/*
+void unregister_serial(int line)
+{
+	unsigned long flags;
+	struct serial_state *state = &rs_table[line];
+
+	save_flags(flags); cli();
+	if (state->info && state->info->tty)
+		tty_hangup(state->info->tty);
+	state->type = PORT_UNKNOWN;
+	printk(KERN_INFO "tty%02d unloaded\n", state->line);
+	// These will be hidden, because they are devices that will no longer
+	// be available to the system. (ie, PCMCIA modems, once ejected)
+	//
+	tty_unregister_devfs(&serial_driver,
+			     serial_driver.minor_start + state->line);
+	tty_unregister_devfs(&callout_driver,
+			     callout_driver.minor_start + state->line);
+	restore_flags(flags);
+}
+*/
+static void __exit rs_fini(void) 
+{
+	unsigned long flags;
+	int e1, e2;
+	int i;
+	struct async_struct *info;
+
+	// printk("Unloading %s: version %s\n", serial_name, serial_version);
+	del_timer_sync(&serial_timer);
+	save_flags(flags); cli();
+        remove_bh(SERIAL_BH);
+	if ((e1 = tty_unregister_driver(&serial_driver)))
+		printk("serial: failed to unregister serial driver (%d)\n",
+		       e1);
+	if ((e2 = tty_unregister_driver(&callout_driver)))
+		printk("serial: failed to unregister callout driver (%d)\n", 
+		       e2);
+	restore_flags(flags);
+
+	for (i = 0; i < NR_PORTS; i++) {
+		if ((info = rs_table[i].info)) {
+			rs_table[i].info = NULL;
+			kfree(info);
+		}
+		if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) {
+/*
+#ifdef CONFIG_SERIAL_RSA
+			if (rs_table[i].type == PORT_RSA)
+				release_region(rs_table[i].port +
+					       UART_RSA_BASE, 16);
+			else
+#endif
+*/
+				release_region(rs_table[i].port, 8);
+		}
+/*
+#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP)
+		if (rs_table[i].iomem_base)
+			iounmap(rs_table[i].iomem_base);
+#endif
+*/
+	}
+/*
+#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP)
+	for (i=0; i < NR_PCI_BOARDS; i++) {
+		struct pci_board_inst *brd = &serial_pci_board[i];
+
+		if (serial_pci_board[i].dev == 0)
+			continue;
+		if (brd->board.init_fn)
+			(brd->board.init_fn)(brd->dev, &brd->board, 0);
+		if (DEACTIVATE_FUNC(brd->dev))
+			(DEACTIVATE_FUNC(brd->dev))(brd->dev);
+	}
+#endif
+*/
+	if (tmp_buf) {
+		unsigned long pg = (unsigned long) tmp_buf;
+		tmp_buf = NULL;
+		free_page(pg);
+	}
+/*	
+#ifdef ENABLE_SERIAL_PCI
+	if (serial_pci_driver.name[0])
+		pci_unregister_driver (&serial_pci_driver);
+#endif
+*/
+}
+
+module_init(rs_init);
+module_exit(rs_fini);
+MODULE_DESCRIPTION("Standard/generic (dumb) serial driver");
+MODULE_AUTHOR("Theodore Ts'o <tytso@mit.edu>");
+MODULE_LICENSE("GPL");
+
+/*
+ * ------------------------------------------------------------
+ * Serial console driver
+ * ------------------------------------------------------------
+ */
+#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
+
+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
+static struct async_struct async_sercons;
+
+/*
+ *	Wait for transmitter & holding register to empty
+ */
+static inline void wait_for_xmitr(struct async_struct *info)
+{
+	unsigned int status, tmout = 1000000;
+
+	do {
+		status = serial_in(info, UART_LSR);
+
+		if (status & UART_LSR_BI)
+			lsr_break_flag = UART_LSR_BI;
+		
+		if (--tmout == 0)
+			break;
+	} while((status & BOTH_EMPTY) != BOTH_EMPTY);
+}
+
+
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ *
+ *	The console must be locked when we get here.
+ */
+static void serial_console_write(struct console *co, const char *s,
+				unsigned count)
+{
+	static struct async_struct *info = &async_sercons;
+	unsigned i;
+
+	/*
+	 *	First save the IER then disable the interrupts
+	 */
+	//ier = serial_in(info, UART_IER);
+	//serial_out(info, UART_IER, 0x00);
+//	disable_uart_tx_interrupt(info->line);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++, s++) {
+		wait_for_xmitr(info);
+
+		/*
+		 *	Send the character out.
+		 *	If a LF, also do CR...
+		 */
+		serial_out(info, UART_TX, *s);
+		if (*s == 10) {
+			wait_for_xmitr(info);
+			serial_out(info, UART_TX, 13);
+		}
+	}
+
+	/*
+	 *	Finally, Wait for transmitter & holding register to empty
+	 * 	and restore the IER
+	 */
+	wait_for_xmitr(info);
+	//serial_out(info, UART_IER, ier);
+//	enable_uart_tx_interrupt(info->line);
+}
+
+static kdev_t serial_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+/*
+ *	Setup initial baud/bits/parity/flow control. We do two things here:
+ *	- construct a cflag setting for the first rs_open()
+ *	- initialize the serial port
+ *	Return non-zero if we didn't find a serial port.
+ */
+static int __init serial_console_setup(struct console *co, char *options)
+{
+	static struct async_struct *info;
+	struct serial_state *state;
+	unsigned cval;
+	int	baud = 19200;
+	int	bits = 8;
+	int	parity = 'n';
+	int	doflow = 0;
+	int	cflag = CREAD | HUPCL | CLOCAL;
+	int	quot = 0;
+	char	*s;
+
+	if (options) {
+		baud = simple_strtoul(options, NULL, 10);
+		s = options;
+		while(*s >= '0' && *s <= '9')
+			s++;
+		if (*s) parity = *s++;
+		if (*s) bits   = *s++ - '0';
+		if (*s) doflow = (*s++ == 'r');
+	}
+
+	/*
+	 *	Now construct a cflag setting.
+	 */
+	switch(baud) {
+		case 1200:
+			cflag |= B1200;
+			break;
+		case 2400:
+			cflag |= B2400;
+			break;
+		case 4800:
+			cflag |= B4800;
+			break;
+		case 19200:
+			cflag |= B19200;
+			break;
+		case 38400:
+			cflag |= B38400;
+			break;
+		case 57600:
+			cflag |= B57600;
+			break;
+		case 115200:
+			cflag |= B115200;
+			break;
+		case 9600:
+		default:
+			cflag |= B9600;
+			/*
+			 * Set this to a sane value to prevent a divide error
+			 */
+			baud  = 9600;
+			break;
+	}
+	switch(bits) {
+		case 7:
+			cflag |= CS7;
+			break;
+		default:
+		case 8:
+			cflag |= CS8;
+			break;
+	}
+	switch(parity) {
+		case 'o': case 'O':
+			cflag |= PARODD;
+			break;
+		case 'e': case 'E':
+			cflag |= PARENB;
+			break;
+	}
+	co->cflag = cflag;
+
+	/*
+	 *	Divisor, bytesize and parity
+	 */
+	state = rs_table + co->index;
+	if (doflow)
+		state->flags |= ASYNC_CONS_FLOW;
+	info = &async_sercons;
+	info->magic = SERIAL_MAGIC;
+	info->state = state;
+	info->port = state->port;
+	info->flags = state->flags;
+#ifdef CONFIG_HUB6
+	info->hub6 = state->hub6;
+#endif
+	info->io_type = state->io_type;
+	info->iomem_base = state->iomem_base;
+	info->iomem_reg_shift = state->iomem_reg_shift;
+	quot = state->baud_base / baud;
+	cval = cflag & (CSIZE | CSTOPB);
+#if defined(__powerpc__) || defined(__alpha__)
+	cval >>= 8;
+#else /* !__powerpc__ && !__alpha__ */
+	cval >>= 4;
+#endif /* !__powerpc__ && !__alpha__ */
+	if (cflag & PARENB)
+	{
+		cval |= UART_LCR_PARITY;
+		if (!(cflag & PARODD))
+			cval |= UART_LCR_EPAR;
+	}
+
+	/*
+	 *	Disable UART interrupts, set DTR and RTS high
+	 *	and set speed.
+	 */
+	/*
+	serial_out(info, UART_LCR, cval | UART_LCR_DLAB);	// set DLAB
+	serial_out(info, UART_DLL, quot & 0xff);	// LS of divisor
+	serial_out(info, UART_DLM, quot >> 8);		// MS of divisor
+	serial_out(info, UART_LCR, cval);		// reset DLAB
+	serial_out(info, UART_IER, 0);
+	serial_out(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
+	*/
+	/*
+	 *	If we read 0xff from the LSR, there is no UART here.
+	 */
+	/*
+	if (serial_in(info, UART_LSR) == 0xff)
+		return -1;
+	*/
+	serial_out(info, UART_BDR, baudrate_div(baud));
+	serial_out(info, UART_LCR, cval);
+
+	return 0;
+}
+
+static struct console sercons = {
+	name:		"ttyS",
+	write:		serial_console_write,
+	device:		serial_console_device,
+	setup:		serial_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+/*
+ *	Register console.
+ */
+void __init samsung_console_init(void)
+{
+	register_console(&sercons);
+}
+#endif
+
+/*
+  Local variables:
+  compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce -march=i586 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h   -DEXPORT_SYMTAB -c serial.c"
+  End:
+*/
diff -urN linux-2.4.29/drivers/char/sh-sci.c linux-2.4.29-uc1/drivers/char/sh-sci.c
--- linux-2.4.29/drivers/char/sh-sci.c	2005-01-19 14:09:51.000000000 +0000
+++ linux-2.4.29-uc1/drivers/char/sh-sci.c	2005-06-14 02:12:18.000000000 +0100
@@ -6,6 +6,7 @@
  *  Copyright (C) 1999, 2000  Niibe Yutaka
  *  Copyright (C) 2000  Sugioka Toshinobu
  *  Modified to support multiple serial ports. Stuart Menefy (May 2000).
+ *  Modified to support H8/300H. Yoshinori Sato (2002/09/11) 
  *  Modified to support SecureEdge. David McCullough (2002) 
  *  Modified to support SH7300 SCIF. Takashi Kusuda (Jun 2003).
  *
@@ -38,6 +39,10 @@
 #include <linux/console.h>
 #endif
 
+#ifdef CONFIG_LEDMAN
+#include <linux/ledman.h>
+#endif
+
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -50,6 +55,14 @@
 #include <asm/sh_bios.h>
 #endif
 
+#if defined(__H8300H__)
+#include <asm/regs306x.h>
+#endif
+
+#if defined(__H8300S__)
+#include <asm/regs267x.h>
+#endif
+
 #include "sh-sci.h"
 
 #ifdef CONFIG_SH_KGDB
@@ -88,6 +101,12 @@
 static void sci_init_pins_irda(struct sci_port* port, unsigned int cflag);
 #endif
 #endif
+#if defined(__H8300H__)
+static void sci_init_pins_h8300h(struct sci_port* port, unsigned int cflag);
+#endif
+#if defined(__H8300S__)
+static void sci_init_pins_h8s(struct sci_port* port, unsigned int cflag);
+#endif
 static void sci_disable_tx_interrupts(void *ptr);
 static void sci_enable_tx_interrupts(void *ptr);
 static void sci_disable_rx_interrupts(void *ptr);
@@ -446,7 +465,7 @@
 	if (cflag & CRTSCTS) {
 		fcr_val |= SCFCR_MCE;
 	} else {
-		sci_out(port, SCSPTR, 0x0080); /* Set RTS = 1 */
+		sci_out(port, SCSPTR, 0x0080); /* Set RTS is coutput CTS is input */
 	}
 	sci_out(port, SCFCR, fcr_val);
 }
@@ -454,6 +473,71 @@
 #endif
 #endif /* SCIF_ONLY || SCI_AND_SCIF */
 
+#if defined(__H8300H__)
+static void sci_init_pins_h8300h(struct sci_port* port, unsigned int cflag)
+{
+	int ch = ((port->base & 0xff) - 0xb0) >> 3;
+	switch (ch) {
+	case 0:
+		H8300_GPIO_RESERVE(H8300_GPIO_P9,H8300_GPIO_B2|H8300_GPIO_B0);
+		H8300_GPIO_DDR(H8300_GPIO_P9,H8300_GPIO_B2,H8300_GPIO_INPUT);
+		H8300_GPIO_DDR(H8300_GPIO_P9,H8300_GPIO_B0,H8300_GPIO_OUTPUT);
+		*(volatile char *)P9DR |= 0x01;
+		break;
+	case 1:
+		H8300_GPIO_RESERVE(H8300_GPIO_P9,H8300_GPIO_B3|H8300_GPIO_B1);
+		H8300_GPIO_DDR(H8300_GPIO_P9,H8300_GPIO_B3,H8300_GPIO_INPUT);
+		H8300_GPIO_DDR(H8300_GPIO_P9,H8300_GPIO_B1,H8300_GPIO_OUTPUT);
+		*(volatile char *)P9DR |= 0x02;
+		break;
+	case 2:
+		H8300_GPIO_RESERVE(H8300_GPIO_PB,H8300_GPIO_B7|H8300_GPIO_B6);
+		H8300_GPIO_DDR(H8300_GPIO_PB,H8300_GPIO_B7,H8300_GPIO_INPUT);
+		H8300_GPIO_DDR(H8300_GPIO_PB,H8300_GPIO_B6,H8300_GPIO_OUTPUT);
+		*(volatile char *)PBDR |= 0x40;
+		break;
+	}
+}
+#endif
+
+#if defined(__H8300S__)
+static void sci_init_pins_h8s(struct sci_port* port, unsigned int cflag)
+{
+	int ch = ((port->base & 0xff) - 0x78) >> 3;
+	switch (ch) {
+	case 0:
+		H8300_GPIO_RESERVE(H8300_GPIO_P3,H8300_GPIO_B2|H8300_GPIO_B0);
+		H8300_GPIO_DDR(H8300_GPIO_P3,H8300_GPIO_B2,H8300_GPIO_INPUT);
+		H8300_GPIO_DDR(H8300_GPIO_P3,H8300_GPIO_B0,H8300_GPIO_OUTPUT);
+		*(volatile char *)P3DR |= 0x01;
+		break;
+	case 1:
+		H8300_GPIO_RESERVE(H8300_GPIO_P3,H8300_GPIO_B3|H8300_GPIO_B1);
+		H8300_GPIO_DDR(H8300_GPIO_P3,H8300_GPIO_B3,H8300_GPIO_INPUT);
+		H8300_GPIO_DDR(H8300_GPIO_P3,H8300_GPIO_B1,H8300_GPIO_OUTPUT);
+		*(volatile char *)P3DR |= 0x02;
+		break;
+	case 2:
+		H8300_GPIO_RESERVE(H8300_GPIO_P5,H8300_GPIO_B1|H8300_GPIO_B0);
+		H8300_GPIO_DDR(H8300_GPIO_P5,H8300_GPIO_B1,H8300_GPIO_INPUT);
+		H8300_GPIO_DDR(H8300_GPIO_P5,H8300_GPIO_B0,H8300_GPIO_OUTPUT);
+		*(volatile char *)P5DR |= 0x01;
+		break;
+	}
+}
+
+static void sci_enable(struct sci_port* port, unsigned int pwr)
+{
+	volatile unsigned char *mstpcrl=(volatile unsigned char *)MSTPCRL;
+	int ch = ((port->base & 0xff) - 0x78) >> 3;
+	unsigned char mask = 1 << (ch+1);
+	if (pwr)
+		*mstpcrl &= ~mask;
+	else
+		*mstpcrl |= mask;
+}
+#endif
+
 static void sci_setsignals(struct sci_port *port, int dtr, int rts)
 {
 	/* This routine is used for seting signals of: DTR, DCD, CTS/RTS */
@@ -469,6 +553,12 @@
 			SECUREEDGE_WRITE_IOPORT(0x0080, 0x0080);
 		else if (dtr == 1)
 			SECUREEDGE_WRITE_IOPORT(0x0000, 0x0080);
+		if ((sci_in(port, SCFCR) & SCFCR_MCE) == 0) {
+			if (rts)
+				sci_out(port, SCSPTR, sci_in(port, SCSPTR) & ~0x40);
+			else
+				sci_out(port, SCSPTR, sci_in(port, SCSPTR) | 0x40);
+		}
 	}
 	if (port == &sci_ports[0]) { /* port 0 only */
 		if (dtr == 0)
@@ -494,6 +584,13 @@
 		unsigned short s = SECUREEDGE_READ_IOPORT();
 		int rc = TIOCM_RTS|TIOCM_DSR|TIOCM_CTS;
 
+		if ((sci_in(port, SCFCR) & SCFCR_MCE) == 0) {
+			if (sci_in(port, SCSPTR) & 0x0040)
+				rc &= ~TIOCM_RTS;
+			if (sci_in(port, SCSPTR) & 0x0010)
+				rc &= ~TIOCM_CTS;
+		}
+
 		if ((s & 0x0001) == 0)
 			rc |= TIOCM_CAR;
 		if ((SECUREEDGE_READ_IOPORT() & 0x0080) == 0)
@@ -583,6 +680,7 @@
 
 	sci_out(port, SCSCR, 0x00);	/* TE=0, RE=0, CKE1=0 */
 
+#if !defined(SCI_ONLY)
 	if (port->type == PORT_SCIF) {
 #if defined(CONFIG_CPU_SUBTYPE_SH7300)
 		sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST | SCFCR_TCRST);
@@ -590,6 +688,7 @@
 		sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
 #endif
 	}
+#endif
 
 	smr_val = sci_in(port, SCSMR) & 3;
 	if ((cflag & CSIZE) == CS7)
@@ -649,6 +748,11 @@
 	unsigned short ctrl;
 	unsigned char c;
 
+#ifdef CONFIG_LEDMAN
+	ledman_cmd(LEDMAN_CMD_SET, port == &sci_ports[0] ?
+			LEDMAN_COM1_TX : LEDMAN_COM2_TX);
+#endif
+
 	status = sci_in(port, SCxSR);
 	if (!(status & SCxSR_TDxE(port))) {
 		save_and_cli(flags);
@@ -665,6 +769,7 @@
 
 	while (1) {
 		count = port->gs.xmit_cnt;
+#if !defined(SCI_ONLY)
 		if (port->type == PORT_SCIF) {
 #if defined(CONFIG_CPU_SUBTYPE_SH7300)
 			txroom = 64 - (sci_in(port, SCFDR)>>8);
@@ -674,6 +779,9 @@
 		} else {
 			txroom = (sci_in(port, SCxSR) & SCI_TDRE)?1:0;
 		}
+#else
+		txroom = (sci_in(port, SCxSR) & SCI_TDRE)?1:0;
+#endif
 		if (count > txroom)
 			count = txroom;
 
@@ -710,10 +818,12 @@
 		ctrl &= ~SCI_CTRL_FLAGS_TIE;
 		port->gs.flags &= ~GS_TX_INTEN;
 	} else {
+#if !defined(SCI_ONLY)
 		if (port->type == PORT_SCIF) {
 			sci_in(port, SCxSR); /* Dummy read */
 			sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
 		}
+#endif
 		ctrl |= SCI_CTRL_FLAGS_TIE;
 	}
 	sci_out(port, SCSCR, ctrl);
@@ -737,7 +847,13 @@
 
 	tty = port->gs.tty;
 
+#ifdef CONFIG_LEDMAN
+	ledman_cmd(LEDMAN_CMD_SET,
+		port == &sci_ports[0] ? LEDMAN_COM1_RX :LEDMAN_COM2_RX);
+#endif
+
 	while (1) {
+#if !defined(SCI_ONLY)
 		if (port->type == PORT_SCIF) {
 #if defined(CONFIG_CPU_SUBTYPE_SH7300)
 			count = sci_in(port, SCFDR)&0x007f;
@@ -747,6 +863,9 @@
 		} else {
 			count = (sci_in(port, SCxSR)&SCxSR_RDxF(port))?1:0;
 		}
+#else
+		count = (sci_in(port, SCxSR)&SCxSR_RDxF(port))?1:0;
+#endif		
 
 		/* we must clear RDF or we get stuck in the interrupt for ever */
 		sci_in(port, SCxSR); /* dummy read */
@@ -825,7 +944,8 @@
 		/* drop any remaining chars,  we are full */
 		if (count > 0) {
 			/* force an overrun error on last received char */
-			tty->flip.flag_buf_ptr[TTY_FLIPBUF_SIZE - 1] = TTY_OVERRUN;
+			if (tty->flip.count)
+				*(tty->flip.flag_buf_ptr - 1) = TTY_OVERRUN;
 			while (count-- > 0)
 				(void) sci_in(port, SCxRDR);
 		}
@@ -980,6 +1100,7 @@
 	sci_tx_interrupt(irq, ptr, regs);
 }
 
+#if !defined(SCI_ONLY)
 static void sci_br_interrupt(int irq, void *ptr, struct pt_regs *regs)
 {
 	struct sci_port *port = ptr;
@@ -988,6 +1109,7 @@
 	sci_handle_breaks(port);
 	sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
 }
+#endif
 
 static void sci_mpxed_interrupt(int irq, void *ptr, struct pt_regs *regs)
 {
@@ -1006,9 +1128,11 @@
         if((ssr_status&0x0080) && (scr_status&0x0400)){ /* Error Interrupt */
                 sci_er_interrupt(irq, ptr, regs);
         }
+#if !defined(SCI_ONLY)
         if((ssr_status&0x0010) && (scr_status&0x0200)){ /* Break Interrupt */
                 sci_br_interrupt(irq, ptr, regs);
         }
+#endif
 }
 
 static void do_softint(void *private_)
@@ -1050,7 +1174,9 @@
 
 	disable_irq(port->irqs[SCIx_TXI_IRQ]);
 	sci_transmit_chars(port);
+#if !defined(__H8300H__) && !defined(__H8300S__)
 	enable_irq(port->irqs[SCIx_TXI_IRQ]);
+#endif
 }
 
 static void sci_disable_rx_interrupts(void * ptr)
@@ -1100,11 +1226,15 @@
 {
 	struct sci_port *port = ptr;
 
+#if !defined(SCI_ONLY)
 	if (port->type == PORT_SCIF) {
 		return (sci_in(port, SCFDR) >> 8) + ((sci_in(port, SCxSR) & SCxSR_TEND(port))? 0: 1);
 	} else {
 		return (sci_in(port, SCxSR) & SCxSR_TEND(port))? 0: 1;
 	}
+#else
+	return (sci_in(port, SCxSR) & SCxSR_TEND(port))? 0: 1;
+#endif
 }
 
 static void sci_shutdown_port(void * ptr)
@@ -1115,6 +1245,9 @@
 	if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL)
 		sci_setsignals(port, 0, 0);
 	sci_free_irq(port);
+#if defined(__H8300S__)
+	sci_enable(port,0);
+#endif
 }
 
 /* ********************************************************************** *
@@ -1154,6 +1287,9 @@
 	if (port->gs.count == 1) {
 		MOD_INC_USE_COUNT;
 
+#if defined(__H8300S__)
+		sci_enable(port,1);
+#endif
 		retval = sci_request_irq(port);
 		if (retval) {
 			goto failed_1;
@@ -1223,6 +1359,10 @@
 failed_1:
 	MOD_DEC_USE_COUNT;
 	port->gs.count--;
+#if defined(__H8300S__)
+	if (port->gs.count == 0)
+		sci_enable(port,0);
+#endif
 	return retval;
 }
 
@@ -1445,10 +1585,18 @@
 static int sci_request_irq(struct sci_port *port)
 {
 	int i;
-	void (*handlers[4])(int irq, void *ptr, struct pt_regs *regs) = {
+#if !defined(SCI_ONLY)
+#define IRQs 4
+	void (*handlers[IRQs])(int irq, void *ptr, struct pt_regs *regs) = {
 		sci_er_interrupt, sci_rx_interrupt, sci_tx_interrupt,
 		sci_br_interrupt,
 	};
+#else
+#define IRQs 3
+	void (*handlers[IRQs])(int irq, void *ptr, struct pt_regs *regs) = {
+		sci_er_interrupt, sci_rx_interrupt, sci_tx_interrupt
+	};
+#endif
 
 	if(port->irqs[0] == port->irqs[1]){
 		if (!port->irqs[0]){
@@ -1648,6 +1796,9 @@
 		co->cflag = cflag;
 		sercons_baud = baud;
 
+#if defined(__H8300S__)
+		sci_enable(sercons_port,1);
+#endif
 		sci_set_termios_cflag(sercons_port, cflag, baud);
 		sercons_port->old_cflag = cflag;
 	}
diff -urN linux-2.4.29/drivers/char/sh-sci.h linux-2.4.29-uc1/drivers/char/sh-sci.h
--- linux-2.4.29/drivers/char/sh-sci.h	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-uc1/drivers/char/sh-sci.h	2005-06-14 02:12:17.000000000 +0100
@@ -6,11 +6,16 @@
  *  Copyright (C) 1999, 2000  Niibe Yutaka
  *  Copyright (C) 2000  Greg Banks
  *  Modified to support multiple serial ports. Stuart Menefy (May 2000).
+ *  Modified to support H8/300H. Yoshinori Sato (2002/09/11) 
  *  Modified to support SH7300(SH-Mobile) SCIF. Takashi Kusuda (Jun 2003).
  *
  */
 #include <linux/config.h>
 
+#if defined(CONFIG_CPU_H8300H) || defined(CONFIG_CPU_H8S)
+#include <asm/gpio.h>
+#endif
+
 /* Values for sci_port->type */
 #define PORT_SCI  0
 #define PORT_SCIF 1
@@ -27,6 +32,12 @@
 #define SH3_IRDA_IRQS { 52,  53,  55,  54 }
 #define SH4_SCIF_IRQS { 40,  41,  43,  42 }
 #define STB1_SCIF1_IRQS {23, 24,  26,  25 }
+#define H8300H_SCI_IRQS0 {52, 53, 54,   0 }
+#define H8300H_SCI_IRQS1 {56, 57, 58,   0 }
+#define H8300H_SCI_IRQS2 {60, 61, 62,   0 }
+#define H8S_SCI_IRQS0 {88, 89, 90,   0 }
+#define H8S_SCI_IRQS1 {92, 93, 94,   0 }
+#define H8S_SCI_IRQS2 {96, 97, 98,   0 }
 #define SH5_SCIF_IRQS  { 39, 40, 42 }
 #define SH7300_SCIF0_IRQS {80,  80,  80,  80 }
 
@@ -92,6 +103,24 @@
 # define SCIF_ORER 0x0001   /* overrun error bit */
 # define SCSCR_INIT(port)          0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
 # define SCIF_ONLY
+#elif defined(CONFIG_CPU_H8300H)
+# define SCI_NPORTS 3
+# define SCI_INIT { \
+  { {}, PORT_SCI,  0x00ffffb0, H8300H_SCI_IRQS0, sci_init_pins_h8300h  }, \
+  { {}, PORT_SCI,  0x00ffffb8, H8300H_SCI_IRQS1, sci_init_pins_h8300h  }, \
+  { {}, PORT_SCI,  0x00ffffc0, H8300H_SCI_IRQS2, sci_init_pins_h8300h  }  \
+}
+# define SCSCR_INIT(port)          0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
+# define SCI_ONLY
+#elif defined(CONFIG_CPU_H8S)
+# define SCI_NPORTS 3
+# define SCI_INIT { \
+  { {}, PORT_SCI,  0x00ffff78, H8S_SCI_IRQS0, sci_init_pins_h8s  }, \
+  { {}, PORT_SCI,  0x00ffff80, H8S_SCI_IRQS1, sci_init_pins_h8s  }, \
+  { {}, PORT_SCI,  0x00ffff88, H8S_SCI_IRQS2, sci_init_pins_h8s  }  \
+}
+# define SCSCR_INIT(port)          0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
+# define SCI_ONLY
 
 #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
 # include <asm/hardware.h>
@@ -283,20 +312,44 @@
     SCI_OUT(scif_size, scif_offset, value);				\
   }
 
+#define CPU_SCI_FNS(name, sci_offset, sci_size)				\
+  static inline unsigned int sci_##name##_in(struct sci_port* port)	\
+  {									\
+    SCI_IN(sci_size, sci_offset);		 			\
+  }									\
+  static inline void sci_##name##_out(struct sci_port* port, unsigned int value) \
+  {									\
+    SCI_OUT(sci_size, sci_offset, value);				\
+  }
+
 #ifdef __sh3__
 #if defined(CONFIG_CPU_SUBTYPE_SH7300)
 #define SCIF_FNS(name, scif_offset, scif_size) \
   CPU_SCIF_FNS(name, scif_offset, scif_size)
 #else
 #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
-		 sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
+		 sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \
+                 h8_sci_offset, h8_sci_size) \
   CPU_SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh3_scif_offset, sh3_scif_size)
 #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
   CPU_SCIF_FNS(name, sh3_scif_offset, sh3_scif_size)
 #endif
+#elif __H8300H__
+#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
+		 sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \
+                 h8_sci_offset, h8_sci_size) \
+  CPU_SCI_FNS(name, h8_sci_offset, h8_sci_size)
+#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size)
+#elif __H8300S__
+#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
+		 sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \
+                 h8_sci_offset, h8_sci_size) \
+  CPU_SCI_FNS(name, h8_sci_offset, h8_sci_size)
+#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size)
 #else
 #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
-		 sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
+		 sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \
+		 h8_sci_offset, h8_sci_size) \
   CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size)
 #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
   CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
@@ -314,14 +367,14 @@
 SCIF_FNS(SCxTDR, 0x20,  8)
 SCIF_FNS(SCxRDR, 0x24,  8)
 #else
-/*      reg      SCI/SH3   SCI/SH4  SCIF/SH3   SCIF/SH4  */
-/*      name     off  sz   off  sz   off  sz   off  sz   */
-SCIx_FNS(SCSMR,  0x00,  8, 0x00,  8, 0x00,  8, 0x00, 16)
-SCIx_FNS(SCBRR,  0x02,  8, 0x04,  8, 0x02,  8, 0x04,  8)
-SCIx_FNS(SCSCR,  0x04,  8, 0x08,  8, 0x04,  8, 0x08, 16)
-SCIx_FNS(SCxTDR, 0x06,  8, 0x0c,  8, 0x06,  8, 0x0C,  8)
-SCIx_FNS(SCxSR,  0x08,  8, 0x10,  8, 0x08, 16, 0x10, 16)
-SCIx_FNS(SCxRDR, 0x0a,  8, 0x14,  8, 0x0A,  8, 0x14,  8)
+/*      reg      SCI/SH3   SCI/SH4  SCIF/SH3   SCIF/SH4  SCI/H8*/
+/*      name     off  sz   off  sz   off  sz   off  sz   off  sz*/
+SCIx_FNS(SCSMR,  0x00,  8, 0x00,  8, 0x00,  8, 0x00, 16, 0x00,  8)
+SCIx_FNS(SCBRR,  0x02,  8, 0x04,  8, 0x02,  8, 0x04,  8, 0x01,  8)
+SCIx_FNS(SCSCR,  0x04,  8, 0x08,  8, 0x04,  8, 0x08, 16, 0x02,  8)
+SCIx_FNS(SCxTDR, 0x06,  8, 0x0c,  8, 0x06,  8, 0x0C,  8, 0x03,  8)
+SCIx_FNS(SCxSR,  0x08,  8, 0x10,  8, 0x08, 16, 0x10, 16, 0x04,  8)
+SCIx_FNS(SCxRDR, 0x0a,  8, 0x14,  8, 0x0A,  8, 0x14,  8, 0x05,  8)
 SCIF_FNS(SCFCR,                      0x0c,  8, 0x18, 16)
 SCIF_FNS(SCFDR,                      0x0e, 16, 0x1C, 16)
 SCIF_FNS(SCSPTR,			0,  0, 0x20, 16)
@@ -378,6 +431,30 @@
 		return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */
 
 }
+#elif defined(CONFIG_CPU_H8300H)
+static inline int sci_rxd_in(struct sci_port *port)
+{
+	switch (port->base) {
+	case 0x00ffffb0:
+		return (*(volatile char *)P9DR & H8300_GPIO_B2)?1:0;
+	case 0x00ffffb8:
+		return (*(volatile char *)P9DR & H8300_GPIO_B3)?1:0;
+	case 0x00ffffc0:
+		return (*(volatile char *)PBDR & H8300_GPIO_B7)?1:0;
+	}
+}
+#elif defined(CONFIG_CPU_H8S)
+static inline int sci_rxd_in(struct sci_port *port)
+{
+	switch (port->base) {
+	case 0x00ffff78:
+		return (*(volatile char *)P3DR & H8300_GPIO_B2)?1:0;
+	case 0x00ffff80:
+		return (*(volatile char *)P3DR & H8300_GPIO_B3)?1:0;
+	case 0x00ffffc0:
+		return (*(volatile char *)P5DR & H8300_GPIO_B1)?1:0;
+	}
+}
 #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
 static inline int sci_rxd_in(struct sci_port *port)
 {
@@ -422,6 +499,8 @@
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7300)
 #define SCBRR_VALUE(bps) ((PCLK+16*bps)/(16*bps)-1)
+#elif defined(__H8300H__) || defined(__H8300S__)
+#define SCBRR_VALUE(bps) (((CONFIG_CLK_FREQ*1000/32)/bps)-1)
 #else
 #define SCBRR_VALUE(bps) ((PCLK+16*bps)/(32*bps)-1)
 #endif
diff -urN linux-2.4.29/drivers/char/snapdog.c linux-2.4.29-uc1/drivers/char/snapdog.c
--- linux-2.4.29/drivers/char/snapdog.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/snapdog.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,415 @@
+/****************************************************************************/
+/*
+ *	SnapGear Hardware Watchdog driver (this WD cannot be stopped)
+ *
+ *	Copyright 2004 David McCullough <davidm@snapgear.com>, All Rights Reserved.
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *	
+ *	based on softdog.c by Alan Cox <alan@redhat.com>
+ */
+/****************************************************************************/
+ 
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/reboot.h>
+#include <asm/uaccess.h>
+
+/****************************************************************************/
+/*
+ * here we put the platform specific bits (headers/poke function)
+ */
+
+#ifdef CONFIG_SH_SECUREEDGE5410
+	#include <asm/io.h>
+
+	static inline void enable_dog(void) {}
+
+	static inline void poke_the_dog(void)
+	{
+		volatile char dummy;
+		dummy = * (volatile char *) 0xb8000000;
+	}
+
+	static inline void the_dog_is_dead(void) {}
+
+	#define HAS_HW_SERVICE 1
+#endif
+
+#ifdef CONFIG_MACH_IPD
+	#include <asm/io.h>
+
+	static volatile char *dog_addr = NULL;
+
+	static inline void enable_dog(void)
+	{
+		dog_addr = (char *) ioremap(0x20000000, 32);
+	}
+
+	static inline void poke_the_dog(void)
+	{
+		if (dog_addr) {
+			volatile char dummy = *dog_addr;
+		}
+	}
+
+	static inline void the_dog_is_dead(void) {}
+
+	#define HAS_HW_SERVICE 1
+#endif
+
+#if defined(CONFIG_MACH_ESS710) || defined(CONFIG_MACH_IVPN) || \
+		defined(CONFIG_MACH_SG560) || defined(CONFIG_MACH_SG580)
+	#include <asm/io.h>
+
+	static inline void enable_dog(void)
+	{
+		*IXP425_GPIO_GPCLKR &= 0xffff0000;
+	}
+
+	static inline void poke_the_dog(void)
+	{
+		*IXP425_GPIO_GPOUTR ^= 0x4000;
+	}
+
+	static inline void the_dog_is_dead(void) {}
+
+	#define HAS_HW_SERVICE 1
+#endif
+
+#if defined(CONFIG_MACH_SG565) || defined(CONFIG_MACH_SHIVA1100)
+	#include <asm/io.h>
+
+	static volatile unsigned char *wdtcs2;
+
+	static inline void enable_dog(void)
+	{
+		/* CS7 is watchdog alive. Set it to 8bit and writable */
+		*IXP425_EXP_CS7 = 0xbfff0003;
+		wdtcs2 = (volatile unsigned char *) ioremap(IXP425_EXP_BUS_CS7_BASE_PHYS, 512);
+	}
+
+	static inline void poke_the_dog(void)
+	{
+		if (wdtcs2)
+			*wdtcs2 = 0;
+	}
+
+	static inline void the_dog_is_dead(void) {}
+
+	#define HAS_HW_SERVICE 1
+#endif
+
+#ifdef CONFIG_GEODEWATCHDOG
+	#include <asm/io.h>
+
+	static inline void enable_dog(void) {}
+
+	static inline void poke_the_dog(void)
+	{
+		unsigned int v;
+		v = inl(0x6410);
+		outl((v | 0x200), 0x6410);
+		outl((v & ~0x200), 0x6410);
+	}
+
+	static inline void the_dog_is_dead(void) {}
+
+	#define HAS_HW_SERVICE 1
+#endif
+
+#ifndef HAS_HW_SERVICE
+	static inline void enable_dog(void) {}
+	static inline void poke_the_dog(void) {}
+	static inline void the_dog_is_dead(void)
+	{
+		machine_restart(NULL);
+		printk(KERN_CRIT "snapdog: reboot failed!.\n");
+	}
+#endif
+
+/****************************************************************************/
+
+static unsigned long snapdog_last = 0;
+static unsigned long snapdog_next = 0;
+static int           snapdog_service_required = 0;
+static int           snapdog_busy = 0;
+static int           snapdog_kernel = 0;
+static int           snapdog_timeout = 60;
+static int           snapdog_ltimeout = 300;
+static int           snapdog_use_long_timeout = 0;
+static int           snapdog_warned = 0;
+static int           snapdog_stackdump = 64;
+
+MODULE_PARM(snapdog_kernel, "i");
+MODULE_PARM_DESC(snapdog_kernel,
+		"Watchdog is kernel only (userland servicing not required)");
+
+MODULE_PARM(snapdog_timeout, "i");
+MODULE_PARM_DESC(snapdog_timeout,
+		"Watchdog timeout for user service in seconds");
+
+MODULE_PARM(snapdog_ltimeout, "i");
+MODULE_PARM_DESC(snapdog_ltimeout,
+		"Watchdog 'long' timeout for user service in seconds");
+
+MODULE_PARM(snapdog_stackdump, "i");
+MODULE_PARM_DESC(snapdog_stackdump,
+		"Number of long words to dump from the stack");
+
+/****************************************************************************/
+/*
+ * a really dumb stack dump,  we may need better on some platforms
+ * at least this one is implemented,  unlike dump_stack which is largely
+ * just a stub :-(
+ */
+
+static void show_stack(struct pt_regs *regs)
+{
+	unsigned long i;
+	unsigned long *addr = &i;
+
+	printk("Kernel stack:");
+	for (i = 0; i < snapdog_stackdump; i++) {
+		if (i % 4 == 0)
+			printk("\n%08lx:", (unsigned long) addr);
+		printk(" 0x%08lx", *addr++);
+	}
+	printk("\n");
+}
+
+/****************************************************************************/
+/*
+ *	Because we need to service this guy from deep in other more critical
+ *	code,  we export a function to do this that we can call where
+ *	appropriate.
+ *
+ *	Also the watchdog never stops,  it is always running.  We must service
+ *	it until we are opened,  then we stop servicing it if we are not looked
+ *	after appropriately.
+ *
+ *	I know there are much more clever ways to code the following,  but then
+ *	who would understand it,  let alone know it did the right thing when
+ *	jiffies wraps ;-)
+ */
+
+void
+snapdog_service(struct pt_regs *regs)
+{
+	int the_dog_is_alive = 0;
+
+	if (snapdog_kernel) {
+		the_dog_is_alive = 1;
+	} else if (!snapdog_service_required) {
+		the_dog_is_alive = 1;
+	} else if (snapdog_next < snapdog_last) {
+		if (jiffies < snapdog_next || jiffies > snapdog_last)
+			the_dog_is_alive = 1;
+	} else if (jiffies >= snapdog_last && jiffies < snapdog_next) {
+		the_dog_is_alive = 1;
+	}
+
+	if (the_dog_is_alive)
+		poke_the_dog();
+	else if (!snapdog_warned) {
+		snapdog_warned = 1;
+		printk(KERN_CRIT "snapdog: expired, allowing system reboot.\n");
+		if (regs) {
+			show_regs(regs);
+			show_stack(regs);
+		}
+		the_dog_is_dead();
+	}
+}
+
+EXPORT_SYMBOL(snapdog_service);
+
+/****************************************************************************/
+/*
+ * bump the userland expiry
+ */
+
+static inline void
+snapdog_user_service(void)
+{
+	snapdog_last = jiffies;
+	if (snapdog_use_long_timeout)
+		snapdog_next = snapdog_last + HZ * snapdog_ltimeout;
+	else
+		snapdog_next = snapdog_last + HZ * snapdog_timeout;
+	snapdog_warned = 0;
+}
+
+/****************************************************************************/
+/*
+ *	Allow only one person to hold it open
+ */
+
+static int
+snapdog_open(struct inode *inode, struct file *file)
+{
+	if (test_and_set_bit(0, &snapdog_busy))
+		return -EBUSY;
+
+	/* Activate timer */
+	snapdog_service_required = 1;
+	if (snapdog_use_long_timeout)
+		printk(KERN_INFO "snapdog: now using short timeouts.\n");
+	snapdog_use_long_timeout = 0;
+	snapdog_user_service();
+
+	printk(KERN_INFO "snapdog: user servicing enabled (short=%d,long=%d).\n",
+			snapdog_timeout, snapdog_ltimeout);
+	
+	return 0;
+}
+
+/****************************************************************************/
+
+static int
+snapdog_release(struct inode *inode, struct file *file)
+{
+	lock_kernel();
+	if (!snapdog_service_required) {
+		printk(KERN_INFO
+				"snapdog: disabled user servicing of watchdog timer.\n");
+	} else
+		printk(KERN_CRIT
+				"snapdog: device closed, watchdog will reboot!\n");
+	clear_bit(0, &snapdog_busy);
+	unlock_kernel();
+
+	return 0;
+}
+
+/****************************************************************************/
+
+static ssize_t
+snapdog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+{
+	/*  Can't seek (pwrite) on this device  */
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+
+	/*
+	 *	Refresh the timer.
+	 */
+	if (len) {
+		size_t i;
+
+		for (i = 0; i != len; i++) {
+			char c;
+			if (get_user(c, data + i))
+				return -EFAULT;
+			if (c == 'V')
+				snapdog_service_required = 0;
+			if (c == 'T') {
+				printk(KERN_INFO "snapdog: now using long timeouts.\n");
+				snapdog_use_long_timeout = 1;
+			}
+		}
+		snapdog_user_service();
+		return 1;
+	}
+	return 0;
+}
+
+/****************************************************************************/
+
+static int
+snapdog_ioctl(
+	struct inode *inode,
+	struct file *file,
+	unsigned int cmd,
+	unsigned long arg)
+{
+	static struct watchdog_info ident = {
+		options: WDIOF_MAGICCLOSE,
+		identity: "HW/SW Watchdog for SnapGear",
+	};
+
+	switch (cmd) {
+	default:
+		return(-ENOIOCTLCMD);
+
+	case WDIOC_GETSUPPORT:
+		if (copy_to_user((struct watchdog_info *) arg, &ident, sizeof(ident)))
+			return -EFAULT;
+		return(0);
+
+	case WDIOC_GETSTATUS:
+	case WDIOC_GETBOOTSTATUS:
+		return(put_user(0, (int *) arg));
+
+	case WDIOC_KEEPALIVE:
+		snapdog_user_service();
+		return(0);
+	}
+}
+
+/****************************************************************************/
+
+static struct file_operations snapdog_fops = {
+	owner:		THIS_MODULE,
+	write:		snapdog_write,
+	ioctl:		snapdog_ioctl,
+	open:		snapdog_open,
+	release:	snapdog_release,
+};
+
+
+static struct miscdevice snapdog_miscdev = {
+	minor:		WATCHDOG_MINOR,
+	name:		"snapdog",
+	fops:		&snapdog_fops,
+};
+
+/****************************************************************************/
+
+static const char banner[] __initdata =
+	KERN_INFO "snapdog: HW/SW watchdog timer for SnapGear/Others\n";
+
+static int __init
+watchdog_init(void)
+{
+	int ret;
+
+	enable_dog();
+
+       	ret = misc_register(&snapdog_miscdev);
+	if (ret)
+		return ret;
+
+	printk(banner);
+
+	return 0;
+}
+
+/****************************************************************************/
+
+static void __exit
+watchdog_exit(void)
+{
+	misc_deregister(&snapdog_miscdev);
+}
+
+/****************************************************************************/
+
+module_init(watchdog_init);
+module_exit(watchdog_exit);
+MODULE_AUTHOR("David McCullough <davidm@snapgear.com>");
+MODULE_DESCRIPTION("Driver for SnapGear HW/SW watchdog timer(s)");
+MODULE_LICENSE("GPL");
+
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/char/spi.c linux-2.4.29-uc1/drivers/char/spi.c
--- linux-2.4.29/drivers/char/spi.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/spi.c	2005-06-14 02:12:18.000000000 +0100
@@ -0,0 +1,311 @@
+#ifdef MODULE
+#include <linux/module.h>
+#include <linux/version.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/unistd.h>
+#include <linux/init.h>
+
+
+#include <asm/io.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/spi.h> 
+
+#if !defined(SEEK_SET)
+#define SEEK_SET 0
+#endif
+
+
+static unsigned int   spi_major = 60; /* a local major, can be overwritten */
+static          int   openflag  =  0;
+static np_spi * const spi_ptr   = na_spi;
+
+                    /*******************************/
+                    /* SPI data transfer routines. */
+                    /*******************************/
+
+#define SPI_XMIT_READY np_spistatus_trdy_mask
+#define SPI_RECV_READY np_spistatus_rrdy_mask
+
+#define SPI_BUSYPOLL_TIMEOUT 1000
+
+// returns -1 if there is no data present, otherwise returns
+// the value
+inline int SPI_Recv_Byte(char *pdata )
+{
+	if (spi_ptr->np_spistatus & SPI_RECV_READY){
+		*pdata = spi_ptr->np_spirxdata & 0xff;
+		return 0;
+	}
+	return  -1;
+}
+
+
+// Sends the 16 bit address+data
+inline int SPI_Send_Byte( unsigned char address, char data )
+{
+	u16 value = ((address & 0xFF) << 8) | (data & 0xFF);
+
+	if ( spi_ptr->np_spistatus & SPI_XMIT_READY ) {
+		spi_ptr->np_spitxdata = value;
+		return 0;
+	}
+	
+	return -1;
+}
+
+
+
+                    /*************************/
+                    /* SPI Driver functions. */
+                    /*************************/
+
+int spi_reset( void )
+{
+  // Nothing to do: The Nios does _not_
+  // support burst xfers. Chip Enables
+  // (Selects) are inactive after each xfer.
+  return 0;
+}
+
+
+/***************************************************/
+/* The SPI Write routine. The first 16 bits are     */
+/* the device register, and the rest of the buffer */
+/* is data.                                        */
+/***************************************************/
+
+ssize_t spi_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
+{
+  int            i;
+  unsigned char addr;
+  int timeout;
+  char temp;
+  
+  if ( count < 3 )
+    return -EINVAL;          	       /* Address is 2 bytes: Must have _something_ to send */
+
+  addr = buf[0];          /* chip register address.  */
+  spi_ptr->np_spistatus=0;
+
+  for ( i = sizeof(u16); i<count; i++ ) 
+  {
+  	timeout=SPI_BUSYPOLL_TIMEOUT;
+  	while (SPI_Send_Byte(addr, buf[i])==-1) 
+  	{
+		if (--timeout==0) 
+		{
+		  printk("spi_write time out\n");
+		  return i; /* return the number of bytes sent */
+		}
+  	}
+  	/* read the data */
+  	timeout=SPI_BUSYPOLL_TIMEOUT;
+ 	while (SPI_Recv_Byte(&temp)==-1) 
+ 	{
+		if (--timeout==0) 
+		  break; 
+  	}
+  }
+  return i; 
+//  unsigned char *temp;                 /* Our pointer to the buffer */
+//  int            i;
+//  int            addr;
+//  
+//  if ( count < 3 )
+//    return -EINVAL;          	       /* Address is 2 bytes: Must have _something_ to send */
+//
+//  temp = (char *)buf;
+//  addr = (int)*((u16 *)temp);          /* chip register address.  */
+//  temp += sizeof(u16);
+//
+//  for ( i = count - sizeof(u16); i; i--, temp++ )
+//      *temp = (unsigned char)SPI_Transfer( addr, (int)*temp );
+//    
+//  
+//  return count;                        /* we can always send all data */
+}
+
+//int spi_read( struct inode *inode, struct file *file, char *buf, int count )
+ssize_t spi_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
+{
+  int            i;
+  unsigned char addr;
+  int timeout;
+  char temp;
+  
+  if ( count < 3 )
+    return -EINVAL;          	       /* Address is 2 bytes: Must have _something_ to send */
+
+  addr = buf[0];          /* chip register address.  */
+  spi_ptr->np_spistatus=0;
+  
+  /* empty the np_spirxdata register */
+  SPI_Recv_Byte(&temp);
+  
+  for ( i = sizeof(u16); i<count; i++ ) 
+  {
+  	/* send the address */
+  	timeout=SPI_BUSYPOLL_TIMEOUT;
+  	while (SPI_Send_Byte(addr, 0)==-1) 
+  	{
+		if (--timeout==0) 
+		{
+		  printk("spi_read write address time out\n");
+		  return i; 
+		}
+  	}
+  	
+  	/* read the data */
+  	timeout=SPI_BUSYPOLL_TIMEOUT;
+ 	while (SPI_Recv_Byte(&buf[i])==-1) 
+ 	{
+		if (--timeout==0) 
+		{
+		  printk("spi_read read data time out\n");
+		  return i; 
+		}
+  	}
+#if 0
+  	printk("spi_read time left %d\n", timeout);
+#endif
+  }
+  return i;
+}
+
+loff_t spi_lseek(struct file *filp, loff_t offset, int origin)
+{
+#if 0
+  int     bit_count, i;
+#endif
+
+  if ( origin != SEEK_SET || offset != (offset & 0xFFFF) )
+  {
+      errno = -EINVAL;
+      return -1;
+  }
+
+#if 0
+  /****************************************/
+  /* Nios SPI implementation safeguard:   */
+  /* It is possible to have more than     */
+  /* one CS active at a time. Check that  */
+  /* the given address is a power of two. */
+  /****************************************/
+  bit_count = 0;
+  for ( i = 0; i < sizeof(u16); i++ )
+  {
+      if ( (1 << i) & offset )
+      {
+	  if ( ++bit_count > 1 )
+	  {
+	      errno = -EINVAL;
+	      return -1;
+	  }
+      }
+  }
+#endif
+  spi_ptr->np_spislaveselect = offset;
+  return 0;
+}
+
+int spi_open(struct inode *inode, struct file *filp)
+{
+  if ( openflag )
+    return -EBUSY;
+
+  MOD_INC_USE_COUNT;
+  openflag = 1;
+
+  return 0;
+}
+
+int spi_release(struct inode *inode, struct file *filp)
+{
+  openflag = 0;
+  MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+
+/* static struct file_operations spi_fops  */
+
+static struct file_operations spi_fops = {
+	llseek:		spi_lseek,     /* Set chip-select line. The offset is used as an address. */
+	read:		spi_read,
+	write:		spi_write,
+	open:		spi_open, 
+	release:	spi_release,
+};
+
+
+int register_NIOS_SPI( void )
+{
+  int result = register_chrdev( spi_major, "spi", &spi_fops );
+  if ( result < 0 )
+  {
+    printk( "SPI: unable to get major %d for SPI bus \n", spi_major );
+    return result;
+  }/*end-if*/
+  
+  if ( spi_major == 0 )
+    spi_major = result; /* here we got our major dynamically */
+
+  /* reserve our port, but check first if free */
+  if ( check_region( (unsigned int)na_spi, sizeof(np_spi) ) )
+  {
+    printk( "SPI: port at adr 0x%08x already occupied\n", (unsigned int)na_spi );
+    unregister_chrdev( spi_major, "spi" );
+
+    return result;
+  }/*end-if*/
+
+  return 0;
+}
+
+void unregister_NIOS_SPI( void )
+{
+    if ( spi_major > 0 )
+      unregister_chrdev( spi_major, "spi" );
+
+    release_region( (unsigned int)na_spi, sizeof(np_spi) );
+}
+
+
+#ifdef MODULE
+void cleanup_module( void )
+{
+  unregister_NIOS_SPI();
+}
+
+
+
+int init_module( void )
+{
+  return register_NIOS_SPI();
+}
+#endif
+
+
+static int __init nios_spi_init(void)
+{
+	printk("SPI: Nios SPI bus device version 0.1\n");
+	return register_NIOS_SPI();
+//	if ( register_NIOS_SPI() )
+//		printk("*** Cannot initialize SPI device.\n");
+}
+
+__initcall(nios_spi_init);
diff -urN linux-2.4.29/drivers/char/ta7_watchdog.c linux-2.4.29-uc1/drivers/char/ta7_watchdog.c
--- linux-2.4.29/drivers/char/ta7_watchdog.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/ta7_watchdog.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,242 @@
+/*
+ * drivers/char/ta7_watchdog.c
+ *
+ * by Craig Hackney <craig@triscend.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This driver is for the watchdog device on the Triscend-A7 CSoC
+ * devices.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+#include <linux/random.h>
+#include <linux/init.h>
+#include <linux/smp_lock.h>
+#include <linux/ioport.h>
+#include <linux/watchdog.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/arch/triscend_a7.h>
+
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+static int nowayout = 1;
+#else
+static int nowayout = 0;
+#endif
+
+#ifdef CONFIG_DEVFS_FS
+#undef WATCHDOG_MINOR
+#define WATCHDOG_MINOR	MISC_DYNAMIC_MINOR
+#endif
+
+/*
+ * Default timeout in clock cycles.
+ */
+#define DEFAULT_TIMEOUT 64000000
+
+static unsigned long timeout;
+static int reset = 1;
+static int watchdogStarted;
+static int watchdogFired;
+
+static wait_queue_head_t watchdog_wait;
+
+static void
+watchdog_isr (int irq, void *dev_id, struct pt_regs *regs)
+{
+  SET_BIT(WATCHDOG_CLEAR_REG, WD_INT_CLR_BIT);
+
+  if (reset)
+      while (1);
+
+  watchdogFired = 1;
+  wake_up (&watchdog_wait);
+}
+
+static int
+watchdog_open (struct inode *inode, struct file *file)
+{
+  MOD_INC_USE_COUNT;
+  return (0);
+}
+
+static int
+watchdog_release (struct inode *inode, struct file *file)
+{
+
+  if (!nowayout)
+  {
+    CLR_BIT(WATCHDOG_CONTROL_REG, WD_ENABLE_BIT);
+    watchdogStarted = 0;
+  }
+
+  MOD_DEC_USE_COUNT;
+  return (0);
+}
+
+static int
+watchdog_read (struct file *file, char *buffer, size_t len, loff_t * f_pos)
+{
+  unsigned long wdValue = A7_REG( WATCHDOG_CURRENT_VAL_REG );
+
+  if( len < sizeof( unsigned long ) )
+    return( -EINVAL );
+
+  copy_to_user (buffer, &wdValue, sizeof( unsigned long ) );
+  return ( sizeof( unsigned long ) );
+}
+
+static int
+watchdog_write (struct file *file,
+		const char *data, size_t len, loff_t * ppos)
+{
+  if (!watchdogStarted)
+    {
+      SET_BIT( WATCHDOG_CONTROL_REG, WD_RESET_BIT );
+      A7_REG( WATCHDOG_TIMEOUT_VAL_REG ) = timeout;
+      SET_BIT( WATCHDOG_CONTROL_REG, WD_ENABLE_BIT );
+
+      if (reset)
+      	SET_BIT( WATCHDOG_CONTROL_REG, EN_WD_RST_BIT );
+      else
+	CLR_BIT( WATCHDOG_CONTROL_REG, EN_WD_RST_BIT );
+
+      watchdogStarted = 1;
+    }
+  else
+    SET_BIT( WATCHDOG_CONTROL_REG, WD_RESET_BIT );
+
+  // Return the number of bytes written
+  return (len);
+}
+
+static int
+watchdog_ioctl (struct inode *inode,
+		struct file *file, unsigned int cmd, unsigned long arg)
+{
+  switch (cmd)
+    {
+    case WDIOF_KEEPALIVEPING:
+      SET_BIT( WATCHDOG_CONTROL_REG, WD_RESET_BIT );
+      break;
+    case WDIOF_SETTIMEOUT:
+      // Set the watchdog timeout value
+      timeout = arg;
+      A7_REG(WATCHDOG_TIMEOUT_VAL_REG) = timeout;
+      break;
+    case WDIOS_DISABLECARD:
+      CLR_BIT(WATCHDOG_CONTROL_REG, WD_ENABLE_BIT);
+      watchdogStarted = 0;
+      break;
+    case WDIOS_ENABLECARD:
+      SET_BIT( WATCHDOG_CONTROL_REG, WD_RESET_BIT );
+      A7_REG( WATCHDOG_TIMEOUT_VAL_REG ) = timeout;
+      SET_BIT( WATCHDOG_CONTROL_REG, WD_ENABLE_BIT );
+
+      if (reset)
+      	SET_BIT( WATCHDOG_CONTROL_REG, EN_WD_RST_BIT );
+      else
+	CLR_BIT( WATCHDOG_CONTROL_REG, EN_WD_RST_BIT );
+
+      watchdogStarted = 1;
+      break;
+    default:
+      return (-EINVAL);
+    }
+  return (0);
+}
+
+static unsigned int
+watchdog_poll (struct file *file, poll_table * wait)
+{
+  poll_wait (file, &watchdog_wait, wait);
+
+  if (watchdogFired)
+    {
+      watchdogFired = 0;
+      return (POLLOUT | POLLWRNORM);
+    }
+
+  return (0);
+}
+
+static struct file_operations watchdog_fops = {
+  owner:THIS_MODULE,
+  read:watchdog_read,
+  write:watchdog_write,
+  poll:watchdog_poll,
+  ioctl:watchdog_ioctl,
+  open:watchdog_open,
+  release:watchdog_release,
+};
+
+static struct miscdevice watchdog_miscdev = {
+  WATCHDOG_MINOR,
+  "watchdog",
+  &watchdog_fops
+};
+
+void
+ta7_watchdog_init (void)
+{
+  printk ("Triscend A7 Watchdog Driver: 1.00\n");
+
+  watchdogStarted = 0;
+  watchdogFired = 0;
+  reset = 1;
+  timeout = DEFAULT_TIMEOUT;
+
+  init_waitqueue_head (&watchdog_wait);
+
+  if (!request_region (WD_BASE, 16, "watchdog"))
+    printk (KERN_ERR "watchdog: IO %X is not free.\n", (unsigned int ) WD_BASE);
+
+  if (request_irq (IRQ_WATCHDOG_BIT,
+		   watchdog_isr, SA_INTERRUPT, "watchdog", NULL))
+    printk (KERN_ERR "watchdog: IRQ %d is not free.\n",
+	    IRQ_WATCHDOG_BIT);
+
+  misc_register (&watchdog_miscdev);
+}
+
+int
+watchdog_init (void)
+{
+  ta7_watchdog_init ();
+  return (0);
+}
+
+void
+watchdog_exit (void)
+{
+  CLR_BIT(WATCHDOG_CONTROL_REG, WD_ENABLE_BIT);
+  free_irq (IRQ_WATCHDOG_BIT, NULL);
+  release_region (WD_BASE, 16);
+  misc_deregister (&watchdog_miscdev);
+}
+
+module_init (watchdog_init);
+module_exit (watchdog_exit);
+
+MODULE_PARM(nowayout,"i");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+MODULE_AUTHOR ("Craig Hackney");
+MODULE_DESCRIPTION ("Driver to access the Triscend-A7 watchdog");
+MODULE_LICENSE ("GPL");
+EXPORT_NO_SYMBOLS;
+
diff -urN linux-2.4.29/drivers/char/tty_io.c linux-2.4.29-uc1/drivers/char/tty_io.c
--- linux-2.4.29/drivers/char/tty_io.c	2005-01-19 14:09:53.000000000 +0000
+++ linux-2.4.29-uc1/drivers/char/tty_io.c	2005-06-14 02:12:17.000000000 +0100
@@ -150,11 +150,19 @@
 extern void tty3215_init(void);
 extern void tub3270_con_init(void);
 extern void tub3270_init(void);
+extern void uart_console_init(void);
 extern void rs285_console_init(void);
 extern void sa1100_rs_console_init(void);
 extern void sgi_serial_console_init(void);
 extern void sn_sal_serial_console_init(void);
 extern void sci_console_init(void);
+extern void m68328_console_init(void);
+extern void mcfrs_console_init(void);
+extern void v850e_uart_console_init(void);
+extern void atmel_console_init(void);
+extern void serial_cnxt_console_init(void);
+extern void dm270_console_init(void);
+extern void s3c3410_console_init(void);
 extern void dec_serial_console_init(void);
 extern void tx3912_console_init(void);
 extern void tx3912_rs_init(void);
@@ -162,8 +170,15 @@
 extern void txx9_rs_init(void);
 extern void txx9_serial_console_init(void);
 extern void sb1250_serial_console_init(void);
+extern void s3c3410_console_init(void);
+extern void s3c44b0x_console_init(void);
 extern void arc_console_init(void);
+extern void s3c2500_console_init(void);
+extern void c5471_console_init(void);
+extern void bf535_console_init(void);
+extern void bf533_console_init(void);
 extern int hvc_console_init(void);
+extern int xmbrs_console_init(void);
 
 #ifndef MIN
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
@@ -2679,7 +2694,7 @@
  	mac_scc_console_init();
 #elif defined(CONFIG_PARISC)
 	pdc_console_init();
-#elif defined(CONFIG_SERIAL)
+#elif defined(CONFIG_SERIAL) && !defined(CONFIG_MACH_CM4008) && !defined(CONFIG_MACH_CM41xx)
 	serial_console_init();
 #endif /* CONFIG_8xx */
 #if defined(CONFIG_MVME162_SCC) || defined(CONFIG_BVME6000_SCC) || defined(CONFIG_MVME147_SCC)
@@ -2707,6 +2722,9 @@
 #ifdef CONFIG_STDIO_CONSOLE
 	stdio_console_init();
 #endif
+#ifdef CONFIG_SERIAL_CORE_CONSOLE
+	uart_console_init();
+#endif
 #ifdef CONFIG_SERIAL_21285_CONSOLE
 	rs285_console_init();
 #endif
@@ -2716,9 +2734,54 @@
 #ifdef CONFIG_ARC_CONSOLE
 	arc_console_init();
 #endif
-#ifdef CONFIG_SERIAL_AMBA_CONSOLE
+#if defined(CONFIG_SERIAL_INTEGRATOR) && defined(CONFIG_SERIAL_AMBA_CONSOLE)
 	ambauart_console_init();
 #endif
+#ifdef CONFIG_68328_SERIAL
+	m68328_console_init();
+#endif
+#ifdef CONFIG_COLDFIRE_SERIAL
+	mcfrs_console_init();
+#endif
+#ifdef CONFIG_V850E_UART_CONSOLE
+	v850e_uart_console_init ();
+#endif
+#ifdef CONFIG_SERIAL_DSC21_CONSOLE
+	serial_dsc21_console_init();
+#endif
+#if defined (CONFIG_M68360_SMC_UART) || defined (CONFIG_M68360_SCC_UART)
+    rs_360_init();
+#endif
+#ifdef CONFIG_SERIAL_ATMEL_CONSOLE 
+	atmel_console_init();
+#endif
+#ifdef CONFIG_SERIAL_DM270_CONSOLE
+	dm270_console_init();
+#endif
+#ifdef CONFIG_SERIAL_CNXT
+	serial_cnxt_console_init();
+#endif
+#ifdef CONFIG_SERIAL_NETARM_CONSOLE
+	serial_netarm_console_init();
+#endif
+#ifdef CONFIG_SERIAL_KS8695
+	ks8695_console_init();
+#endif
+#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
+	samsung_console_init();
+#endif
+#ifdef CONFIG_SERIAL_S3C3410_CONSOLE
+	s3c3410_console_init();
+#endif
+#ifdef CONFIG_SERIAL_S3C44B0X_CONSOLE
+	s3c44b0x_console_init();
+#endif
+#ifdef CONFIG_SERIAL_S3C4530_CONSOLE
+	s3c4530_console_init();
+#endif
+#ifdef CONFIG_SERIAL_S3C2500_CONSOLE
+	s3c2500_console_init();
+#endif
 #ifdef CONFIG_SERIAL_TX3912_CONSOLE
 	tx3912_console_init();
 #endif
@@ -2731,9 +2794,24 @@
 #ifdef CONFIG_SIBYTE_SB1250_DUART_CONSOLE
 	sb1250_serial_console_init();
 #endif
+#ifdef CONFIG_NIOS_SERIAL
+ 	nios_console_init();
+#endif
 #ifdef CONFIG_IP22_SERIAL
 	sgi_serial_console_init();
 #endif
+#ifdef CONFIG_SERIAL_C5471_CONSOLE
+	 c5471_console_init();
+#endif
+#ifdef CONFIG_SERIAL_BF535
+	bf535_console_init();
+#endif
+#ifdef CONFIG_SERIAL_BF533
+	bf533_console_init();
+#endif
+#ifdef CONFIG_XILINX_UARTLITE_0_INSTANCE
+	xmbrs_console_init();
+#endif
 }
 
 static struct tty_driver dev_tty_driver, dev_syscons_driver;
diff -urN linux-2.4.29/drivers/char/v850e_uart.c linux-2.4.29-uc1/drivers/char/v850e_uart.c
--- linux-2.4.29/drivers/char/v850e_uart.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/v850e_uart.c	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,568 @@
+/*
+ * drivers/char/v850e_uart.c -- Serial I/O using V850E on-chip UART or UARTB
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+/* This driver supports both the original V850E UART interface (called
+   merely `UART' in the docs) and the newer `UARTB' interface, which is
+   roughly a superset of the first one.  The selection is made at
+   configure time -- if CONFIG_V850E_UARTB is defined, then UARTB is
+   presumed, otherwise the old UART -- as these are on-CPU UARTS, a system
+   can never have both.
+
+   The UARTB interface also has a 16-entry FIFO mode, which is not
+   yet supported by this driver.  */
+
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/tty_driver.h>
+#include <linux/serial.h>
+#include <linux/generic_serial.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/tqueue.h>
+#include <linux/interrupt.h>
+
+#include <asm/v850e_uart.h>
+
+
+/* Initial UART state.  This may be overridden by machine-dependent headers. */
+#ifndef V850E_UART_INIT_BAUD
+#define V850E_UART_INIT_BAUD	115200
+#endif
+#ifndef V850E_UART_INIT_CFLAGS
+#define V850E_UART_INIT_CFLAGS	(B115200 | CS8 | CREAD)
+#endif
+
+/* A string used for prefixing printed descriptions; since the same UART
+   macro is actually used on other chips than the V850E.  This must be a
+   constant string.  */
+#ifndef V850E_UART_CHIP_NAME
+#define V850E_UART_CHIP_NAME	"V850E"
+#endif
+
+
+#define V850E_UART_MAGIC	0xFABCAB22 /* Used in generic_serial header */
+#define V850E_UART_MINOR_BASE	64	   /* First tty minor number */
+
+
+#define RS_EVENT_WRITE_WAKEUP	1 /* from generic_serial.h */
+
+/* For use by modules eventually...  */
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+
+
+/* Low-level UART functions.  */
+
+/* Configure and turn on uart channel CHAN, using the termios `control
+   modes' bits in CFLAGS, and a baud-rate of BAUD.  */
+void v850e_uart_configure (unsigned chan, unsigned cflags, unsigned baud)
+{
+	int flags;
+	v850e_uart_speed_t old_speed;
+	v850e_uart_config_t old_config;
+	v850e_uart_speed_t new_speed = v850e_uart_calc_speed (baud);
+	v850e_uart_config_t new_config = v850e_uart_calc_config (cflags);
+
+	/* Disable interrupts while we're twiddling the hardware.  */
+	save_flags_cli (flags);
+
+#ifdef V850E_UART_PRE_CONFIGURE
+	V850E_UART_PRE_CONFIGURE (chan, cflags, baud);
+#endif
+
+	old_config = V850E_UART_CONFIG (chan);
+	old_speed = v850e_uart_speed (chan);
+
+	if (! v850e_uart_speed_eq (old_speed, new_speed)) {
+		/* The baud rate has changed.  First, disable the UART.  */
+		V850E_UART_CONFIG (chan) = V850E_UART_CONFIG_FINI;
+		old_config = 0;	/* Force the uart to be re-initialized. */
+
+		/* Reprogram the baud-rate generator.  */
+		v850e_uart_set_speed (chan, new_speed);
+	}
+
+	if (! (old_config & V850E_UART_CONFIG_ENABLED)) {
+		/* If we are using the uart for the first time, start by
+		   enabling it, which must be done before turning on any
+		   other bits.  */
+		V850E_UART_CONFIG (chan) = V850E_UART_CONFIG_INIT;
+		/* See the initial state.  */
+		old_config = V850E_UART_CONFIG (chan);
+	}
+
+	if (new_config != old_config) {
+		/* Which of the TXE/RXE bits we'll temporarily turn off
+		   before changing other control bits.  */
+		unsigned temp_disable = 0;
+		/* Which of the TXE/RXE bits will be enabled.  */
+		unsigned enable = 0;
+		unsigned changed_bits = new_config ^ old_config;
+
+		/* Which of RX/TX will be enabled in the new configuration.  */
+		if (new_config & V850E_UART_CONFIG_RX_BITS)
+			enable |= (new_config & V850E_UART_CONFIG_RX_ENABLE);
+		if (new_config & V850E_UART_CONFIG_TX_BITS)
+			enable |= (new_config & V850E_UART_CONFIG_TX_ENABLE);
+
+		/* Figure out which of RX/TX needs to be disabled; note
+		   that this will only happen if they're not already
+		   disabled.  */
+		if (changed_bits & V850E_UART_CONFIG_RX_BITS)
+			temp_disable
+				|= (old_config & V850E_UART_CONFIG_RX_ENABLE);
+		if (changed_bits & V850E_UART_CONFIG_TX_BITS)
+			temp_disable
+				|= (old_config & V850E_UART_CONFIG_TX_ENABLE);
+
+		/* We have to turn off RX and/or TX mode before changing
+		   any associated control bits.  */
+		if (temp_disable)
+			V850E_UART_CONFIG (chan) = old_config & ~temp_disable;
+
+		/* Write the new control bits, while RX/TX are disabled. */ 
+		if (changed_bits & ~enable)
+			V850E_UART_CONFIG (chan) = new_config & ~enable;
+
+		v850e_uart_config_delay (new_config, new_speed);
+
+		/* Write the final version, with enable bits turned on.  */
+		V850E_UART_CONFIG (chan) = new_config;
+	}
+
+	restore_flags (flags);
+}
+
+
+/*  Low-level console. */
+
+static void v850e_uart_cons_write (struct console *co,
+				   const char *s, unsigned count)
+{
+	if (count > 0) {
+		unsigned chan = co->index;
+		unsigned irq = V850E_UART_TX_IRQ (chan);
+		int irq_was_enabled, irq_was_pending, flags;
+
+		/* We don't want to get `transmission completed'
+		   interrupts, since we're busy-waiting, so we disable them
+		   while sending (we don't disable interrupts entirely
+		   because sending over a serial line is really slow).  We
+		   save the status of the tx interrupt and restore it when
+		   we're done so that using printk doesn't interfere with
+		   normal serial transmission (other than interleaving the
+		   output, of course!).  This should work correctly even if
+		   this function is interrupted and the interrupt printks
+		   something.  */
+
+		/* Disable interrupts while fiddling with tx interrupt.  */
+		save_flags_cli (flags);
+		/* Get current tx interrupt status.  */
+		irq_was_enabled = v850e_intc_irq_enabled (irq);
+		irq_was_pending = v850e_intc_irq_pending (irq);
+		/* Disable tx interrupt if necessary.  */
+		if (irq_was_enabled)
+			v850e_intc_disable_irq (irq);
+		/* Turn interrupts back on.  */
+		restore_flags (flags);
+
+		/* Send characters.  */
+		while (count > 0) {
+			int ch = *s++;
+
+			if (ch == '\n') {
+				/* We don't have the benefit of a tty
+				   driver, so translate NL into CR LF.  */
+				v850e_uart_wait_for_xmit_ok (chan);
+				v850e_uart_putc (chan, '\r');
+			}
+
+			v850e_uart_wait_for_xmit_ok (chan);
+			v850e_uart_putc (chan, ch);
+
+			count--;
+		}
+
+		/* Restore saved tx interrupt status.  */
+		if (irq_was_enabled) {
+			/* Wait for the last character we sent to be
+			   completely transmitted (as we'll get an
+			   interrupt interrupt at that point).  */
+			v850e_uart_wait_for_xmit_done (chan);
+			/* Clear pending interrupts received due
+			   to our transmission, unless there was already
+			   one pending, in which case we want the
+			   handler to be called.  */
+			if (! irq_was_pending)
+				v850e_intc_clear_pending_irq (irq);
+			/* ... and then turn back on handling.  */
+			v850e_intc_enable_irq (irq);
+		}
+	}
+}
+
+static kdev_t v850e_uart_cons_device (struct console *c)
+{
+        return MKDEV (TTY_MAJOR, V850E_UART_MINOR_BASE + c->index);
+}
+
+static struct console v850e_uart_cons =
+{
+    name:	"ttyS",
+    write:	v850e_uart_cons_write,
+    device:	v850e_uart_cons_device,
+    flags:	CON_PRINTBUFFER,
+    index:	-1,
+};
+
+void v850e_uart_cons_init (unsigned chan)
+{
+	v850e_uart_configure (chan, V850E_UART_INIT_CFLAGS,
+			      V850E_UART_INIT_BAUD);
+	v850e_uart_cons.index = chan;
+	register_console (&v850e_uart_cons);
+	printk ("Console: %s on-chip UART channel %d\n",
+		V850E_UART_CHIP_NAME, chan);
+}
+
+/* This is what the init code actually calls.  */
+void v850e_uart_console_init (void)
+{
+	v850e_uart_cons_init (V850E_UART_CONSOLE_CHANNEL);
+}
+
+
+/* Interface for generic serial driver layer.  */
+
+struct v850e_uart_tty_port {
+	struct gs_port gs;
+	unsigned chan;
+	struct tq_struct tqueue;
+};
+
+/* Transmit a character, if any are pending.  */
+void v850e_uart_tty_tx (struct v850e_uart_tty_port *port)
+{
+	unsigned chan = port->chan;
+	int flags;
+
+	/* If there are characters to transmit, try to transmit one of them. */
+	if (port->gs.xmit_cnt > 0 && v850e_uart_xmit_ok (port->chan)) {
+		v850e_uart_putc (chan, port->gs.xmit_buf[port->gs.xmit_tail]);
+		port->gs.xmit_tail
+			= (port->gs.xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
+		port->gs.xmit_cnt--;
+
+		if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
+			port->gs.event |= 1 << RS_EVENT_WRITE_WAKEUP;
+			queue_task (&port->tqueue, &tq_immediate);
+			mark_bh (IMMEDIATE_BH);
+		}
+	}
+
+	save_flags_cli (flags);
+	if (port->gs.xmit_cnt == 0)
+		port->gs.flags &= ~GS_TX_INTEN;
+	restore_flags (flags);
+}
+
+static void v850e_uart_tty_disable_tx_interrupts (void *driver_data)
+{
+	struct v850e_uart_tty_port *port = driver_data;
+	v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->chan));
+}
+
+static void v850e_uart_tty_enable_tx_interrupts (void *driver_data)
+{
+	struct v850e_uart_tty_port *port = driver_data;
+	v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->chan));
+	v850e_uart_tty_tx (port);
+	v850e_intc_enable_irq (V850E_UART_TX_IRQ (port->chan));
+}
+
+static void v850e_uart_tty_disable_rx_interrupts (void *driver_data)
+{
+	struct v850e_uart_tty_port *port = driver_data;
+	v850e_intc_disable_irq (V850E_UART_RX_IRQ (port->chan));
+}
+
+static void v850e_uart_tty_enable_rx_interrupts (void *driver_data)
+{
+	struct v850e_uart_tty_port *port = driver_data;
+	v850e_intc_enable_irq (V850E_UART_RX_IRQ (port->chan));
+}
+
+static int v850e_uart_tty_get_CD (void *driver_data)
+{
+	return 1;		/* Can't really detect it, sorry... */
+}
+
+static void v850e_uart_tty_shutdown_port (void *driver_data)
+{
+	struct v850e_uart_tty_port *port = driver_data;
+
+	port->gs.flags &= ~ GS_ACTIVE;
+
+	/* Disable port interrupts.  */
+	free_irq (V850E_UART_TX_IRQ (port->chan), port);
+	free_irq (V850E_UART_RX_IRQ (port->chan), port);
+
+	/* Turn off xmit/recv enable bits.  */
+	V850E_UART_CONFIG (port->chan)
+		&= ~(V850E_UART_CONFIG_RX_ENABLE
+		     | V850E_UART_CONFIG_TX_ENABLE);
+	/* Then reset the channel.  */
+	V850E_UART_CONFIG (port->chan) = V850E_UART_CONFIG_FINI;
+}
+
+static int v850e_uart_tty_set_real_termios (void *driver_data)
+{
+	struct v850e_uart_tty_port *port = driver_data;
+	unsigned cflag = port->gs.tty->termios->c_cflag;
+	v850e_uart_configure (port->chan, cflag, port->gs.baud);
+}
+
+static int v850e_uart_tty_chars_in_buffer (void *driver_data)
+{
+	/* There's only a one-character `buffer', and the only time we
+	   actually know there's a character in it is when we receive a
+	   character-received interrupt -- in which case we immediately
+	   remove it anyway.  */
+	return 0;
+}
+
+static void v850e_uart_tty_close (void *driver_data)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+static void v850e_uart_tty_hungup (void *driver_data)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+static void v850e_uart_tty_getserial (void *driver_data, struct serial_struct *s)
+{
+	struct v850e_uart_tty_port *port = driver_data;
+	s->line = port->chan;
+	s->xmit_fifo_size = 1;
+	s->irq = V850E_UART_RX_IRQ (port->chan); /* actually have TX irq too, but... */
+}
+
+static struct real_driver v850e_uart_tty_gs_driver = {
+	disable_tx_interrupts: 	v850e_uart_tty_disable_tx_interrupts,
+	enable_tx_interrupts:	v850e_uart_tty_enable_tx_interrupts,
+	disable_rx_interrupts:	v850e_uart_tty_disable_rx_interrupts,
+	enable_rx_interrupts:	v850e_uart_tty_enable_rx_interrupts,
+	get_CD:			v850e_uart_tty_get_CD,
+	shutdown_port:		v850e_uart_tty_shutdown_port,
+	set_real_termios:	v850e_uart_tty_set_real_termios,
+	chars_in_buffer:	v850e_uart_tty_chars_in_buffer,
+	close:			v850e_uart_tty_close,
+	hungup:			v850e_uart_tty_hungup,
+	getserial:		v850e_uart_tty_getserial,
+};
+
+static struct v850e_uart_tty_port v850e_uart_tty_ports[V850E_UART_NUM_CHANNELS];
+
+static void init_v850e_uart_tty_ports (void)
+{
+	int chan;
+	for (chan = 0; chan < V850E_UART_NUM_CHANNELS; chan++) {
+		struct v850e_uart_tty_port *port = &v850e_uart_tty_ports[chan];
+
+		port->chan = chan;
+
+		port->gs.magic = V850E_UART_MAGIC;
+		port->gs.rd = &v850e_uart_tty_gs_driver;
+
+		init_waitqueue_head (&port->gs.open_wait);
+		init_waitqueue_head (&port->gs.close_wait);
+
+		port->gs.normal_termios	= tty_std_termios;
+		port->gs.normal_termios.c_cflag = V850E_UART_INIT_CFLAGS;
+
+		port->gs.close_delay = HZ / 2;   /* .5s */
+		port->gs.closing_wait = 30 * HZ; /* 30s */
+	}
+}
+
+
+/* TTY interrupt handlers.  */
+
+void v850e_uart_tty_tx_irq (int irq, void *data, struct pt_regs *regs)
+{
+	struct v850e_uart_tty_port *port = data;
+	if (port->gs.flags & GS_ACTIVE)
+		v850e_uart_tty_tx (port);
+	else
+		v850e_uart_tty_disable_tx_interrupts (data);
+}
+
+void v850e_uart_tty_rx_irq (int irq, void *data, struct pt_regs *regs)
+{
+	struct v850e_uart_tty_port *port = data;
+
+	if (port->gs.flags & GS_ACTIVE) {
+		unsigned ch_stat;
+		unsigned err = v850e_uart_err (port->chan);
+		unsigned ch = v850e_uart_getc (port->chan);
+
+		if (err & V850E_UART_ERR_OVERRUN)
+			ch_stat = TTY_OVERRUN;
+		else if (err & V850E_UART_ERR_FRAME)
+			ch_stat = TTY_FRAME;
+		else if (err & V850E_UART_ERR_PARITY)
+			ch_stat = TTY_PARITY;
+		else
+			ch_stat = TTY_NORMAL;
+
+		tty_insert_flip_char (port->gs.tty, ch, ch_stat);
+		tty_schedule_flip (port->gs.tty);
+	} else
+		v850e_uart_tty_disable_rx_interrupts (port);
+}
+
+
+/* Higher level TTY interface.  */
+
+static struct tty_struct *v850e_uart_ttys[V850E_UART_NUM_CHANNELS] = { 0 };
+static struct termios *v850e_uart_tty_termios[V850E_UART_NUM_CHANNELS] = { 0 };
+static struct termios *v850e_uart_tty_termios_locked[V850E_UART_NUM_CHANNELS] = { 0 };
+static struct tty_driver v850e_uart_tty_driver = { 0 };
+static int v850e_uart_tty_refcount = 0;
+
+int v850e_uart_tty_open (struct tty_struct *tty, struct file *filp)
+{
+	int err;
+	struct v850e_uart_tty_port *port;
+	unsigned chan = MINOR (tty->device) - V850E_UART_MINOR_BASE;
+
+	if (chan >= V850E_UART_NUM_CHANNELS)
+		return -ENODEV;
+
+	port = &v850e_uart_tty_ports[chan];
+
+	tty->driver_data = port;
+	port->gs.tty = tty;
+	port->gs.count++;
+
+	port->tqueue.routine = gs_do_softint;
+	port->tqueue.data = &port->gs;
+
+	/*
+	 * Start up serial port
+	 */
+	err = gs_init_port (&port->gs);
+	if (err)
+		goto failed_1;
+
+	port->gs.flags |= GS_ACTIVE;
+
+	if (port->gs.count == 1) {
+		MOD_INC_USE_COUNT;
+
+		/* Alloc RX irq.  */
+		err = request_irq (V850E_UART_RX_IRQ (chan),
+				   v850e_uart_tty_rx_irq,
+				   SA_INTERRUPT, "v850e_uart", port);
+		if (err)
+			goto failed_2;
+
+		/* Alloc TX irq.  */
+		err = request_irq (V850E_UART_TX_IRQ (chan),
+				   v850e_uart_tty_tx_irq,
+				   SA_INTERRUPT, "v850e_uart", port);
+		if (err) {
+			free_irq (V850E_UART_RX_IRQ (chan), port);
+			goto failed_2;
+		}
+	}
+
+	err = gs_block_til_ready (port, filp);
+	if (err)
+		goto failed_3;
+
+	*tty->termios = port->gs.normal_termios;
+
+	v850e_uart_tty_enable_rx_interrupts (port);
+
+	port->gs.session = current->session;
+	port->gs.pgrp = current->pgrp;
+
+	return 0;
+
+failed_3:
+	free_irq (V850E_UART_TX_IRQ (chan), port);
+	free_irq (V850E_UART_RX_IRQ (chan), port);
+failed_2:
+	MOD_DEC_USE_COUNT;
+failed_1:
+	port->gs.count--;
+
+	return err;
+}
+
+int __init v850e_uart_tty_init (void)
+{
+	struct tty_driver *d = &v850e_uart_tty_driver;
+
+	d->driver_name     = "v850e_uart";
+#ifdef CONFIG_DEVFS_FS
+	d->name            = "tts/%d";
+#else
+	d->name            = "ttyS";
+#endif
+
+	d->major       	   = TTY_MAJOR;
+	d->minor_start 	   = V850E_UART_MINOR_BASE;
+	d->num 	       	   = V850E_UART_NUM_CHANNELS;
+	d->type        	   = TTY_DRIVER_TYPE_SERIAL;
+	d->subtype     	   = SERIAL_TYPE_NORMAL;
+
+	d->refcount 	   = &v850e_uart_tty_refcount;
+
+	d->table 	   = v850e_uart_ttys;
+	d->termios 	   = v850e_uart_tty_termios;
+	d->termios_locked  = v850e_uart_tty_termios_locked;
+
+	d->init_termios    = tty_std_termios;
+	d->init_termios.c_cflag = V850E_UART_INIT_CFLAGS;
+
+	d->open 	   = v850e_uart_tty_open;
+	d->put_char 	   = gs_put_char;
+	d->write 	   = gs_write;
+	d->write_room 	   = gs_write_room;
+	d->start 	   = gs_start;
+	d->stop 	   = gs_stop;
+	d->close 	   = gs_close;
+	d->write 	   = gs_write;
+	d->put_char 	   = gs_put_char;
+	d->flush_chars 	   = gs_flush_chars;
+	d->write_room 	   = gs_write_room;
+	d->chars_in_buffer = gs_chars_in_buffer;
+	d->set_termios 	   = gs_set_termios;
+	d->throttle   	   = 0; /* V850E uarts have no hardware flow control */
+	d->unthrottle 	   = 0;	/* " */
+	d->stop 	   = gs_stop;
+	d->start 	   = gs_start;
+	d->hangup 	   = gs_hangup;
+	d->flush_buffer    = gs_flush_buffer;
+
+	init_v850e_uart_tty_ports ();
+
+	tty_register_driver (&v850e_uart_tty_driver);
+}
+__initcall (v850e_uart_tty_init);
diff -urN linux-2.4.29/drivers/char/wdt_c5471.c linux-2.4.29-uc1/drivers/char/wdt_c5471.c
--- linux-2.4.29/drivers/char/wdt_c5471.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/wdt_c5471.c	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,882 @@
+/**************************************************************************
+ * linux/drivers/char/wdt_c5471.c
+ *
+ * Industrial Computer Source WDT500/501 driver for Linux 2.4.x
+ *
+ * (c) Copyright (C) 2003 Cadenux, LLC. All rights reserved.
+ *     todd.fischer@cadenux.com  <www.cadenux.com>
+ * (c) Copyright 2001 RidgeRun, Inc <www.ridgerun.com>
+ * (c) Copyright 1996-1997 Alan Cox <alan@redhat.com>, All Rights Reserved.
+ *				http://www.redhat.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *	
+ * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide 
+ * warranty for any of this software. This material is provided 
+ * "AS-IS" and at no charge.	
+ *
+ * (c) Copyright 1995    Alan Cox <alan@lxorguk.ukuu.org.uk>
+ *
+ * Release 0.08.
+ *
+ * Fixes
+ *	Dave Gregorich	:	Modularisation and minor bugs
+ *	Alan Cox	:	Added the watchdog ioctl() stuff
+ *	Alan Cox	:	Fixed the reboot problem (as noted by
+ *				Matt Crocker).
+ *	Alan Cox	:	Added wdt= boot option
+ *	Alan Cox	:	Cleaned up copy/user stuff
+ *	Tim Hockin	:	Added insmod parameters, comment cleanup
+ *				Parameterized timeout
+ *	Tigran Aivazian	:	Restructured wdt_init() to handle failures
+ *      Gordon McNutt   :       Leveraged for TI watchdog timers
+ *      Gregory Nutt    :	Leveraged to 2.4.x Linux; Made watchdog
+ *				independent of timer module.
+ **************************************************************************/
+
+/**************************************************************************
+ * Conditional Compilation
+ **************************************************************************/
+
+/* #define WDT_DEBUG 1 */
+
+/**************************************************************************
+ * Included Files
+ **************************************************************************/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+#include <asm/arch/sysdep.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/wdt_ioctl.h>
+
+/* Use versioning if needed */
+
+#if defined(CONFIG_MODVERSIONS)
+# undef MODVERSIONS
+# define MODVERSIONS
+#endif
+
+#if defined(MODVERSIONS)
+# include <linux/modversions.h>
+#endif
+
+/**************************************************************************
+ * Definitions
+ **************************************************************************/
+
+/* Common debug definitions */
+
+#if defined(WDT_DEBUG)
+
+ /* define MY_KERN_DEBUG KERN_DEBUG */
+# define MY_KERN_DEBUG
+
+# define dbg(format, arg...) \
+    printk(MY_KERN_DEBUG __FUNCTION__ ": " format "\n" , ## arg)
+
+# if defined(VERBOSE)
+#  define verbose(format, arg...) \
+    printk(MY_KERN_DEBUG __FUNCTION__ ": " format "\n" , ## arg)
+# else /* VERBOSE */
+#  define verbose(format, arg...) do {} while (0)
+# endif /* VERBOSE */
+
+#else /* WDT_DEBUG */
+
+# undef  VERBOSE
+# define dbg(format, arg...) do {} while (0)
+# define verbose(format, arg...) do {} while (0)
+
+#endif /* WDT_DEBUG */
+
+#define err(format, arg...) \
+  printk(KERN_ERR __FUNCTION__ ": " format "\n" , ## arg)
+#define info(format, arg...) \
+  printk(KERN_INFO __FUNCTION__ ": " format "\n" , ## arg)
+#define warn(format, arg...) \
+  printk(KERN_WARNING __FUNCTION__ ": " format "\n" , ## arg)
+#define critical(format, arg...) \
+  printk(KERN_CRIT __FUNCTION__ ": " format "\n" , ## arg)
+
+/* Major device number (see linux/Documentation/devices.txt) */
+
+#ifdef LINUX_20
+  /* register_chrdev() will not except character device major
+   * numbers greater than 127 in Linux 2.0.  Use the first number
+   * in the range 60-64 of Local/Experimental numbers.
+   */
+
+# define WATCHDOG_MAJOR 60
+#else
+  /* Use the first number in the range 240-254 of Local/Experimental
+   * numbers.
+   */
+
+# define WATCHDOG_MAJOR 240
+#endif /* LINUX_20 */
+
+#define MAX_WDT_USEC            353200
+#define RESET_MODE              0
+#define INTERRUPT_MODE          1
+
+#define WDOG_IRQ               0
+#define MAX_PRESCALER          256
+#define C5471_TIMER_STOP       0
+
+#define C5471_TIMER_PRESCALER  0x07          /* Bits 0-2: Prescale value */
+#define C5471_TIMER_STARTBIT   (1 << 3)      /* Bit 3: Start timer bit */
+#define C5471_TIMER_AUTORELOAD (1 << 4)      /* Bit 4: Auto-reload timer */
+#define C5471_TIMER_LOADTIM    (0xffff << 5) /* Bits 20-5: Load timer value */
+#define C5471_TIMER_MODE       (1 << 21)     /* Bit 21: Timer mode */
+#define C5471_DISABLE_VALUE1   (0xf5 << 22)  /* Bits 29-22: WD disable */
+#define C5471_DISABLE_VALUE2   (0xa0 << 22)
+
+#define CLOCK_KHZ              47500
+#define CLOCK_MHZx2            95
+
+#define RESET_MODE             0
+#define INTERRUPT_MODE         1
+
+/**************************************************************************
+ * Private Types
+ **************************************************************************/
+
+/* This structure represents each register in a block of timer
+ * registers
+ */
+
+struct c5471_timer_s
+{
+  volatile unsigned long cntl_timer;  /* Timer control register */
+  volatile unsigned long read_tim;    /* Current value register */
+};
+typedef struct c5471_timer_s c5471_timer_t;
+
+/* We will use timer 0 for watchdog support */
+
+#define c5471_timer ((c5471_timer_t*)C5471_TIMER0_CTRL)
+
+/**************************************************************************
+ * Global Function Prototypes
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Function Prototypes
+ **************************************************************************/
+
+/* Local implementation of timer interface */
+
+static void
+wdt_unregister_cb(void (*handler)(int, void*, struct pt_regs*));
+
+static int
+wdt_register_cb(void (*handler)(int, void*, struct pt_regs*));
+
+static inline int
+prescale_to_ptv(int in);
+
+static int
+wdt_set_watchdog(int mode);
+
+static int
+wdt_set_usec(unsigned long usec_value);
+
+static void
+wdt_timer_init(void);
+
+static void
+wdt_timer_exit(void);
+
+#if !defined(MODULE)
+static int
+wdt_setup(char *str) __init;
+#endif
+
+static void
+wdt_interrupt(int timer, void *dev_id, struct pt_regs *regs);
+
+static void
+wdt_ping(void);
+
+#if defined(WDT_DEBUG)
+static ssize_t
+wdt_read(struct file *filep, char *buf, size_t count, loff_t *f_pos);
+#endif /* WDT_DEBUG */
+
+static ssize_t
+wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos);
+
+static int
+wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	  unsigned long arg);
+
+static int
+wdt_open(struct inode *inode, struct file *file);
+
+static int
+wdt_release(struct inode *inode, struct file *file);
+
+static int
+wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused);
+
+/**************************************************************************
+ * Private Data
+ **************************************************************************/
+
+static int wdt_is_open;
+
+static const char myname[] = "watchdog";
+
+/* Kernel Interfaces */
+
+static struct file_operations wdt_fops =
+{
+  owner:    THIS_MODULE,
+  llseek:   no_llseek,
+#if defined(WDT_DEBUG)
+  read:     wdt_read,
+#endif /* WDT_DEBUG */
+  write:    wdt_write,
+  ioctl:    wdt_ioctl,
+  open:     wdt_open,
+  release:  wdt_release,
+};
+
+/* The WDT card needs to learn about soft shutdowns in order to
+ * turn the timebomb registers off.
+ */
+
+static struct notifier_block wdt_notifier =
+{
+  wdt_notify_sys,
+  NULL,
+  0
+};
+
+/* ioctl info */
+
+static struct watchdog_info ident =
+{
+  options: 0,
+  firmware_version: 0,
+  identity: "C5471 WDT"
+};
+
+/**************************************************************************
+ * Inline Functions
+ **************************************************************************/
+
+/**************************************************************************
+ * Local Timer Logic
+ **************************************************************************/
+
+static void
+wdt_unregister_cb(void (*handler)(int, void*, struct pt_regs*))
+{
+  /* Stop the timer */
+
+  c5471_timer->cntl_timer = C5471_TIMER_STOP;
+
+  /* And release the IRQ */
+
+  free_irq(WDOG_IRQ, handler);
+}
+
+static int
+wdt_register_cb(void (*handler)(int, void*, struct pt_regs*))
+{
+  dbg("Attaching to Watcdog Timer IRQ(%d)", WDOG_IRQ);
+
+  /* Make sure that the timer is stopped (We had better be the only user!
+   * We had better be successful when we request the IRQ!) */
+
+  c5471_timer->cntl_timer = C5471_TIMER_STOP;
+
+  /* Get the interrupt. */
+
+  if (request_irq(WDOG_IRQ, handler, SA_INTERRUPT, myname, handler)) 
+    {
+      err("Unable to get IRQ for the Watchdog driver\n");
+      return -EPERM;
+    }
+
+  return 0;
+}
+
+static inline int
+prescale_to_ptv(int in)
+{
+  if (in <= 2)
+    return 0;
+  if (in <= 4)
+    return 1;
+  if (in <= 8)
+    return 2;
+  if (in <= 16)
+    return 3;
+  if (in <= 32)
+    return 4;
+  if (in <= 64)
+    return 5;
+  if (in <= 128)
+    return 6;
+  /* > 128 to <= 256 */
+  return 7;
+}
+
+static int
+wdt_set_watchdog(int mode)
+{
+  dbg("Setting watchdog mode");
+
+  if (mode == RESET_MODE)
+    {
+      c5471_timer->cntl_timer = C5471_DISABLE_VALUE1;
+      c5471_timer->cntl_timer = C5471_DISABLE_VALUE2;
+    } 
+  else if (mode == INTERRUPT_MODE)
+    {
+      c5471_timer->cntl_timer = C5471_TIMER_MODE;
+    } 
+  else
+    return -1;
+         
+  return 0;
+}
+
+static int
+wdt_set_usec(unsigned long usec_value)
+{
+  /* prescaler: clock / prescaler = #clock ticks per counter in ptv */
+  /* divisor:   #counts until the interrupt comes. */
+
+  unsigned long prescaler  = 2;     
+  unsigned long divisor    = 1;
+  unsigned long timer_mode;
+
+  prescaler = MAX_PRESCALER;
+
+  dbg("Watchdog timer usec_value=%ld", usec_value);
+     
+  /* Calculate a value of prescaler and divisor that will be able
+   * to count to the usec_value.  It may not be exact or the best
+   * possible set, but it's a quick and simple algorithm.
+   *
+   *    divisor max = 0x10000
+   *    prescaler max = MAX_PRESCALER
+   */
+
+  do
+    {
+      divisor = (CLOCK_MHZx2 * usec_value) / (prescaler * 2);
+      dbg("divisor=0x%lx prescaler=0x%lx", divisor, prescaler);
+      if (divisor >= 0x10000)
+	{
+	  if (prescaler == MAX_PRESCALER)
+	    { 
+	      /* this is the max possible ~2.5 seconds. */
+
+	      dbg("prescaler=0x%lx too big!", prescaler);
+	      return -EINVAL;
+	    }
+	  prescaler *= 2;
+	  if (prescaler > MAX_PRESCALER)
+	    {
+	      prescaler = MAX_PRESCALER;
+	    }
+	}
+    }
+  while (divisor >= 0x10000);
+
+  dbg("prescaler=0x%lx divisor=0x%lx", prescaler, divisor);
+
+  timer_mode = prescale_to_ptv(prescaler);
+  dbg("timer_mode=0x%lx", timer_mode);
+
+  timer_mode &= ~C5471_TIMER_AUTORELOAD; /* One shot mode. */
+  dbg("timer_mode=0x%lx", timer_mode);
+
+  timer_mode |= divisor << 5;
+  dbg("timer_mode=0x%lx", timer_mode);
+
+  /* Program the mode, but don't set the start bit yet. */
+
+  c5471_timer->cntl_timer = timer_mode;
+ 
+  /* Now hit the start bit. */
+
+  c5471_timer->cntl_timer |= C5471_TIMER_STARTBIT;
+  dbg("cntl_timer=0x%lx", c5471_timer->cntl_timer);
+
+  return 0;
+}
+
+static void
+wdt_timer_init(void)
+{
+  /* Disable watdog timer. */
+
+  dbg("&cntl_timer=0x%p", &c5471_timer->cntl_timer);
+
+  c5471_timer->cntl_timer = C5471_TIMER_STOP;
+  request_region((unsigned int)&c5471_timer->cntl_timer,
+		 sizeof(c5471_timer_t),
+		 myname);
+}
+
+static void
+wdt_timer_exit(void)
+{
+  release_region((unsigned int)&c5471_timer->cntl_timer,
+		 sizeof(c5471_timer_t));
+}
+
+/**************************************************************************
+ * Private Functions
+ **************************************************************************/
+
+#if !defined(MODULE)
+
+/**************************************************************************
+ * wdt_setup:
+ * @str: command line string
+ *
+ * Setup options. N/A.
+ **************************************************************************/
+ 
+static int __init
+wdt_setup(char *str)
+{
+  return 1;
+}
+
+__setup("wdt=", wdt_setup);
+
+#endif /* !MODULE */
+
+/**************************************************************************
+ * wdt_interrupt:
+ * @timer:		Timer number
+ * @dev_id:	Unused as we don't allow multiple devices.
+ *
+ * Handle an interrupt from the timer. This only happens when the timer
+ *      is configured in 'interrupt' instead of 'reset' mode (which is never
+ *      by this driver). I include this here as an example of how we could
+ *      do something else besides h/w reset (Dan mentioned some realtime
+ *      applications that might want to shutdown equipment or something 
+ *      instead of just blindly resetting the MPU).
+ **************************************************************************/
+ 
+static void
+wdt_interrupt(int timer, void *dev_id, struct pt_regs *regs)
+{
+  critical("WDT expired!");
+	
+#if defined(SOFTWARE_REBOOT)
+#if defined(ONLY_TESTING)
+  critical("Would Reboot");
+#else		
+  critical("Initiating system reboot");
+  machine_restart(NULL);
+#endif		
+#else
+  critical("But since the WDT is configued in interrupt "\
+	   "mode -- without software reboot -- nothing will happen");
+#endif		
+}
+
+/**************************************************************************
+ * wdt_ping:
+ *
+ * Reset the counter. 
+ **************************************************************************/
+
+static void
+wdt_ping(void)
+{
+  dbg("wdt_ping");
+
+  wdt_set_usec(MAX_WDT_USEC); /* Max usec seconds possible */
+}
+
+/**************************************************************************
+ * wdt_read:
+ * @file: file handle to the watchdog board
+ * @buf: buffer to write 1 byte into
+ * @count: length of buffer
+ * @ptr: offset (no seek allowed)
+ *
+ * Read reports the temperature in degrees Fahrenheit. The API is in
+ * farenheit. It was designed by an imperial measurement luddite.
+ **************************************************************************/
+ 
+#if defined(WDT_DEBUG)
+static ssize_t
+wdt_read(struct file *filep, char *buf, size_t count, loff_t *f_pos)
+{
+  static int not_end = 0;
+  char buffer[256];
+  int len;
+
+  dbg("filep=0x%p size=%d", filep, count);
+
+  /* Have we returned the end of file yet? */
+
+  if (not_end) 
+    {
+      /* No... next time we will. */
+
+      not_end = 0;
+
+      /* Return debug information. */
+
+      dbg("cntl_timer(0x%p)=0x%08lx\nread_tim(0x%p)=0x%08lx",
+	  &c5471_timer->cntl_timer,  c5471_timer->cntl_timer,
+	  &c5471_timer->read_tim, c5471_timer->read_tim);
+
+      sprintf(buffer, "cntl_timer(0x%p)=0x%08lx\nread_tim(0x%p)=0x%08lx\n",
+	  &c5471_timer->cntl_timer,  c5471_timer->cntl_timer,
+	  &c5471_timer->read_tim, c5471_timer->read_tim);
+
+      len = strlen(buffer);
+      if (len > count) len = count;
+
+      copy_to_user(buf, buffer, len);
+    }
+  else
+    {
+      /* Return end of file */
+
+      not_end = 1;
+      len     = 0;
+    }
+  return len;
+}
+#endif /* WDT_DEBUG */
+
+/**************************************************************************
+ * wdt_write:
+ * @file: file handle to the watchdog
+ * @buf: buffer to write (unused as data does not matter here 
+ * @count: count of bytes
+ * @ppos: pointer to the position to write. No seeks allowed
+ *
+ * A write to a watchdog device is defined as a keepalive signal. Any
+ * write of data will do, as we we don't define content meaning.
+ **************************************************************************/
+ 
+static ssize_t
+wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+  /*  Can't seek (pwrite) on this device  */
+
+  if (ppos != &file->f_pos)
+    return -ESPIPE;
+
+  dbg("Write call");
+  if(count)
+    {
+      wdt_ping();
+      return 1;
+    }
+  return 0;
+}
+
+/**************************************************************************
+ * wdt_ioctl:
+ * @inode: inode of the device
+ * @file: file handle to the device
+ * @cmd: watchdog command
+ * @arg: argument pointer
+ *
+ * The watchdog API defines a common set of functions for all watchdogs
+ * according to their available features. We only actually usefully support
+ * querying capabilities and current status. 
+ **************************************************************************/
+ 
+static int
+wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	  unsigned long arg)
+{
+  int retval = 0;
+
+  dbg("ioctl Call: inode=%p file=%p cmd=0x%x arg=0x%lx",
+      inode, file, cmd, arg);
+
+  /* Range check the IOCTL cmd */
+
+  if (_IOC_TYPE(cmd) != WATCHDOG_IOCTL_BASE)
+    {
+      err("Invalid ioctl base value");
+      return -EINVAL;
+    }
+
+  /* Process the the IOCTL command (see include/linux/watchdog.h) */
+
+  switch(cmd)
+    {
+    case WDIOC_GETSUPPORT:
+      {
+	dbg("WDIOC_GETSUPPORT");
+	retval = copy_to_user((struct watchdog_info*)arg, &ident, 
+			      sizeof(ident));
+	if (retval)
+	  retval = -EFAULT;
+      }
+      break;
+                
+    case WDIOC_GETSTATUS:
+      {
+	dbg("WDIOC_GETSTATUS");
+	retval = PUT_USER(0, (int*)arg);
+      }
+      break;
+
+    case WDIOC_GETBOOTSTATUS:
+      {
+	dbg("WDIOC_GETBOOTSTATUS");
+	retval = PUT_USER(0, (int*)arg);
+      }
+      break;
+
+    case WDIOC_KEEPALIVE:
+      {
+	dbg("WDIOC_KEEPALIVE");
+	wdt_ping();
+      }
+      break;
+
+      /* These commands are defined in watchdog.h, but were not
+       * supported in the original implemenation of this
+       * watchdog driver.
+       */
+    case WDIOC_GETTEMP:
+    case WDIOC_SETOPTIONS:
+    case WDIOC_SETTIMEOUT:
+      {
+	err("Unsupported ioctl command");
+	retval = -ENOSYS;
+      }
+      break;
+
+    default:
+      {
+	err("Invalid ioctl command");
+	retval = -ENOIOCTLCMD;
+      }
+      break;
+    }
+  return retval;
+}
+
+/**************************************************************************
+ * wdt_open:
+ * @inode: inode of device
+ * @file: file handle to device
+ *
+ * Our misc device has been opened. It's single open and on open we load
+ *      the counter and start the countdown.
+ **************************************************************************/
+ 
+static int
+wdt_open(struct inode *inode, struct file *file)
+{
+  int ret;
+
+  dbg("Open Module");
+
+  if(wdt_is_open)
+    return -EBUSY;
+
+  /* Activate */
+
+  wdt_is_open=1;
+
+  /* This will automatically load the timer with its max
+   * count and start it running.
+   */
+
+  if ((ret = wdt_set_watchdog(RESET_MODE)))
+    {
+      wdt_is_open = 0;
+      return ret;
+    }
+  return 0;
+}
+
+/**************************************************************************
+ * wdt_release:
+ * @inode: inode to board
+ * @file: file handle to board
+ *
+ * The watchdog has a configurable API. There is a religious dispute 
+ * between people who want their watchdog to be able to shut down and 
+ * those who want to be sure if the watchdog manager dies the machine
+ * reboots. In the former case we disable the counters, in the latter
+ * case you have to open it again very soon.
+ **************************************************************************/
+ 
+static int
+wdt_release(struct inode *inode, struct file *file)
+{
+  dbg("Release Module");
+
+  /* lock_kernel(); */
+
+#if !defined(CONFIG_WATCHDOG_NOWAYOUT)
+  wdt_set_watchdog(INTERRUPT_MODE); /* reset off */
+#endif		
+  wdt_is_open=0;
+
+  /* unlock_kernel(); */
+
+  return 0;
+}
+
+/**************************************************************************
+ *      wdt_notify_sys:
+ *      @this: our notifier block
+ *      @code: the event being reported
+ *      @unused: unused
+ *
+ *      Our notifier is called on system shutdowns. We want to turn the card
+ *      off at reboot otherwise the machine will reboot again during memory
+ *      test or worse yet during the following fsck. This would suck, in fact
+ *      trust me - if it happens it does suck.
+ **************************************************************************/
+
+static int
+wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
+{
+  if(code==SYS_DOWN || code==SYS_HALT)
+    {
+      /* Turn the card off */
+    }
+  return NOTIFY_DONE;
+}
+
+/**************************************************************************
+ * Public Functions
+ **************************************************************************/
+
+/**************************************************************************
+ * wdt_exit
+ *
+ * Unload the watchdog. You cannot do this with any file handles open.
+ * If your watchdog is set to continue ticking on close and you unload
+ * it, well it keeps ticking. We won't get the interrupt but the board
+ * will not touch PC memory so all is fine. You just have to load a new
+ * module in 19 seconds or reboot.
+ **************************************************************************/
+ 
+void __exit wdt_exit(void)
+{
+  dbg("Cleanup Module");
+
+  wdt_timer_exit();
+  unregister_reboot_notifier(&wdt_notifier);
+  unregister_chrdev(WATCHDOG_MAJOR, myname);
+  wdt_unregister_cb(&wdt_interrupt);
+}
+
+/**************************************************************************
+ * wdt_init:
+ *
+ * Set up the WDT watchdog board. All we have to do is grab the
+ * resources we require and bitch if anyone beat us to them.
+ * The open() function will actually kick the board off.
+ **************************************************************************/
+ 
+int __init wdt_init(void)
+{
+  int ret;
+
+  /* Announce that we are installing */
+
+  printk("C5471 Watchdog Driver\n");
+
+  /* Register ourselves as the watchdog device driver */
+
+  ret = register_chrdev(WATCHDOG_MAJOR, myname, &wdt_fops);
+  if (ret)
+    {
+      err("Can't register on major=%d ret=%d\n", 
+	  WATCHDOG_MAJOR, ret);
+      goto out;
+    }
+
+  /* Initialize the watchdog timer */
+
+  wdt_timer_init();
+
+  /* Register for an interrupt level callback through wdt_interrupt */
+
+  ret = wdt_register_cb(wdt_interrupt);
+  if (ret)
+    {
+      err("Watchdog timer is not free");
+      goto outmisc;
+    }
+
+  ret = register_reboot_notifier(&wdt_notifier);
+  if(ret)
+    {
+      err("Can't register reboot notifier (err=%d)", ret);
+      goto outtimer;
+    }
+
+  ret = 0;
+
+ out:
+  return ret;
+
+ outtimer:
+  wdt_unregister_cb(wdt_interrupt);
+
+ outmisc:
+  unregister_chrdev(WATCHDOG_MAJOR, myname);
+  goto out;
+}
+
+module_init(wdt_init);
+module_exit(wdt_exit);
+EXPORT_NO_SYMBOLS;
+
diff -urN linux-2.4.29/drivers/char/x1226-rtc.c linux-2.4.29-uc1/drivers/char/x1226-rtc.c
--- linux-2.4.29/drivers/char/x1226-rtc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/x1226-rtc.c	2005-06-14 02:12:17.000000000 +0100
@@ -0,0 +1,503 @@
+/*
+ *  linux/drivers/char/x1226-rtc.c
+ *
+ *  I2C Real Time Clock Client Driver for Xicor X1226 RTC/Calendar
+ *
+ * Author: Steve Longerbeam <stevel@mvista.com, or source@mvista.com>
+ *
+ * 2002-2003 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/fcntl.h>
+#include <linux/poll.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/rtc.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/time.h>
+
+#undef DEBUG_X1226
+
+#ifdef DEBUG_X1226
+#define	dbg(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__, ## args)
+#else
+#define	dbg(fmt, args...)
+#endif
+
+#define X1226_MODULE_NAME "X1226"
+#define PFX X1226_MODULE_NAME
+
+#define err(format, arg...) printk(KERN_ERR PFX ": " format , ## arg)
+#define info(format, arg...) printk(KERN_INFO PFX ": " format , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING PFX ": " format , ## arg)
+#define emerg(format, arg...) printk(KERN_EMERG PFX ": " format , ## arg)
+
+#define EPOCH 2000
+#define SYS_EPOCH 1900
+
+#undef BCD_TO_BIN
+#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
+
+#undef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
+
+#define X1226_RTC_SR      0x3f
+#define   RTC_SR_WEL  (1<<1)
+#define   RTC_SR_RWEL (1<<2)
+
+#define X1226_RTC_BASE    0x30
+
+/* This is an image of the RTC registers starting at offset 0x30 */
+struct rtc_registers {
+	unsigned char secs;	// 30
+	unsigned char mins;	// 31
+	unsigned char hours;	// 32
+	unsigned char day;	// 33
+	unsigned char mon;	// 34
+	unsigned char year;	// 35
+	unsigned char dayofweek;	// 36
+	unsigned char epoch;	// 37
+};
+
+#define X1226_CONTROL_DTR  0x13
+#define X1226_CONTROL_ATR  0x12
+#define X1226_CONTROL_INT  0x11
+#define X1226_CONTROL_BL   0x10
+
+#define DEVID_RTC          0x6F
+#define DEVID_NVRAM        0x57
+
+#define ABITS           9
+#define EESIZE          (1 << ABITS)	/* size in bytes */
+
+#define NVSIZE          512	/* we use 512 bytes */
+#define NVOFFSET        (EESIZE-NVSIZE)	/* at end of EEROM */
+
+static struct i2c_driver x1226_driver;
+
+static int x1226_use_count = 0;
+
+static struct i2c_client *this_client = NULL;
+
+static int rtc_read_proc(char *page, char **start, off_t off,
+			 int count, int *eof, void *data);
+
+static int
+x1226_read(struct i2c_client *client, u8 reg_offset, u8 * buf, int len)
+{
+	int ret;
+	u8 regbuf[2] = { 0, reg_offset };
+	struct i2c_msg random_addr_read[2] = {
+		{
+		 /* "Set Current Address" */
+		 client->addr,
+		 client->flags,
+		 sizeof (regbuf),
+		 regbuf}
+		,
+		{
+		 /* "Sequential Read" if len>1,
+		    "Current Address Read" if len=1 */
+		 client->addr,
+		 client->flags | I2C_M_RD,
+		 len,
+		 buf}
+	};
+
+	if ((ret = i2c_transfer(client->adapter, random_addr_read, 2)) != 2) {
+		err("i2c_transfer failed, ret=%d\n", ret);
+		ret = -ENXIO;
+	}
+
+	return ret;
+}
+
+static int
+x1226_write(struct i2c_client *client, u8 reg_offset, u8 * buf, int len)
+{
+	int ret;
+	u8 *local_buf;
+	u8 regbuf[2] = { 0, reg_offset };
+	struct i2c_msg page_write = {
+		client->addr,
+		client->flags,
+		len + sizeof (regbuf),
+		NULL
+	};
+
+	if ((local_buf = (u8 *) kmalloc(len + sizeof (regbuf),
+					GFP_KERNEL)) == NULL) {
+		err("buffer alloc failed\n");
+		return -ENOMEM;
+	}
+
+	memcpy(local_buf, regbuf, sizeof (regbuf));
+	memcpy(local_buf + sizeof (regbuf), buf, len);
+	page_write.buf = local_buf;
+
+	if ((ret = i2c_transfer(client->adapter, &page_write, 1)) != 1) {
+		err("i2c_transfer failed, ret=%d\n", ret);
+		ret = -ENXIO;
+	}
+
+	kfree(local_buf);
+	return ret;
+}
+
+static int
+ccr_write_enable(struct i2c_client *client)
+{
+	u8 sr = RTC_SR_WEL;
+	int ret;
+
+	if ((ret = x1226_write(client, X1226_RTC_SR, &sr, 1)) < 0)
+		return ret;
+	sr |= RTC_SR_RWEL;
+	if ((ret = x1226_write(client, X1226_RTC_SR, &sr, 1)) < 0)
+		return ret;
+	sr = 0;
+	if ((ret = x1226_read(client, X1226_RTC_SR, &sr, 1)) < 0)
+		return ret;
+
+	sr &= (RTC_SR_RWEL | RTC_SR_RWEL);
+	if (sr != (RTC_SR_RWEL | RTC_SR_RWEL)) {
+		dbg("verify SR failed\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static int
+ccr_write_disable(struct i2c_client *client)
+{
+	int ret;
+	u8 sr = 0;
+
+	if ((ret = x1226_write(client, X1226_RTC_SR, &sr, 1)) < 0)
+		return ret;
+	if ((ret = x1226_read(client, X1226_RTC_SR, &sr, 1)) < 0)
+		return ret;
+	if (sr != 0) {
+		dbg("verify SR failed\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static int
+x1226_get_time(struct i2c_client *client, struct rtc_time *tm)
+{
+	struct rtc_registers rtc;
+	u32 epoch;
+	int ret;
+
+	/* read RTC registers */
+	if ((ret = x1226_read(client, X1226_RTC_BASE, (u8 *) & rtc,
+			      sizeof (struct rtc_registers))) < 0) {
+		dbg("couldn't read RTC\n");
+		return ret;
+	}
+
+	dbg("IN: epoch=%02x, year=%02x, mon=%02x, day=%02x, hour=%02x, "
+	    "min=%02x, sec=%02x\n",
+	    rtc.epoch, rtc.year, rtc.mon, rtc.day, rtc.hours,
+	    rtc.mins, rtc.secs);
+
+	epoch = 100 * BCD_TO_BIN(rtc.epoch);	// 19 / 20
+	tm->tm_year = BCD_TO_BIN(rtc.year);	// 0 - 99
+	tm->tm_year += (epoch - SYS_EPOCH);
+	tm->tm_mon = BCD_TO_BIN(rtc.mon);	// 1 - 12
+	if (tm->tm_mon)
+		tm->tm_mon--;	/* tm_mon is 0 to 11 */
+	tm->tm_mday = BCD_TO_BIN(rtc.day);	// 1 - 31
+	if (!tm->tm_mday)
+		tm->tm_mday = 1;
+	tm->tm_hour = BCD_TO_BIN(rtc.hours & ~0x80);
+	if (rtc.hours && !(rtc.hours & 0x80)) {
+		// AM/PM 1-12 format, convert to MIL
+		tm->tm_hour--;	// 0 - 11
+		if (rtc.hours & (1 << 5))
+			tm->tm_hour += 12;	// PM
+	}
+
+	tm->tm_min = BCD_TO_BIN(rtc.mins);
+	tm->tm_sec = BCD_TO_BIN(rtc.secs);
+
+	dbg("OUT: year=%d, mon=%d, day=%d, hour=%d, min=%d, sec=%d\n",
+	    tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour,
+	    tm->tm_min, tm->tm_sec);
+
+	return 0;
+}
+
+static int
+x1226_set_time(struct i2c_client *client, const struct rtc_time *tm)
+{
+	struct rtc_registers rtc;
+	int ret;
+
+	dbg("IN: year=%d, mon=%d, day=%d, hour=%d, min=%d, sec=%d\n",
+	    tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour,
+	    tm->tm_min, tm->tm_sec);
+
+	rtc.epoch = BIN_TO_BCD(EPOCH / 100);
+	rtc.year = BIN_TO_BCD(tm->tm_year + SYS_EPOCH - EPOCH);
+	rtc.mon = BIN_TO_BCD(tm->tm_mon + 1);	/* tm_mon is 0 to 11 */
+	rtc.day = BIN_TO_BCD(tm->tm_mday);
+	rtc.dayofweek = 0;	// ignore day of week
+	rtc.hours = BIN_TO_BCD(tm->tm_hour) | 0x80;	/* 24 hour format */
+	rtc.mins = BIN_TO_BCD(tm->tm_min);
+	rtc.secs = BIN_TO_BCD(tm->tm_sec);
+
+	dbg("OUT: epoch=%02x, year=%02x, mon=%02x, day=%02x, hour=%02x, "
+	    "min=%02x, sec=%02x\n",
+	    rtc.epoch, rtc.year, rtc.mon, rtc.day, rtc.hours,
+	    rtc.mins, rtc.secs);
+
+	/* write RTC registers */
+	if ((ret = ccr_write_enable(client)) < 0)
+		return ret;
+	if ((ret = x1226_write(client, X1226_RTC_BASE, (u8 *) & rtc,
+			       sizeof (struct rtc_registers))) < 0) {
+		dbg("couldn't write RTC\n");
+		return ret;
+	}
+	ccr_write_disable(client);
+
+	return 0;
+}
+
+static int
+x1226_probe(struct i2c_adapter *adap)
+{
+	int ret;
+	struct rtc_time dummy_tm;
+
+	if (this_client != NULL)
+		return -EBUSY;
+
+	this_client = kmalloc(sizeof (*this_client), GFP_KERNEL);
+	if (this_client == NULL) {
+		return -ENOMEM;
+	}
+
+	strcpy(this_client->name, X1226_MODULE_NAME);
+	this_client->id = x1226_driver.id;
+	this_client->flags = 0;
+	this_client->addr = DEVID_RTC;
+	this_client->adapter = adap;
+	this_client->driver = &x1226_driver;
+	this_client->data = NULL;
+
+	/*
+	 * use x1226_get_time() to probe for an X1226 on this bus.
+	 */
+	if ((ret = x1226_get_time(this_client, &dummy_tm)) < 0) {
+		kfree(this_client);
+		this_client = NULL;
+		return ret;
+	}
+
+	info("found X1226 on %s\n", adap->name);
+
+	/* attach it. */
+	return i2c_attach_client(this_client);
+}
+
+static int
+x1226_detach(struct i2c_client *client)
+{
+	i2c_detach_client(client);
+
+	if (this_client != NULL) {
+		kfree(this_client);
+		this_client = NULL;
+	}
+
+	return 0;
+}
+
+int
+rtc_open(struct inode *minode, struct file *mfile)
+{
+	/*if(MOD_IN_USE) */
+	if (x1226_use_count > 0) {
+		return -EBUSY;
+	}
+	MOD_INC_USE_COUNT;
+	++x1226_use_count;
+	return 0;
+}
+
+int
+rtc_release(struct inode *minode, struct file *mfile)
+{
+	MOD_DEC_USE_COUNT;
+	--x1226_use_count;
+	return 0;
+}
+
+static loff_t
+rtc_llseek(struct file *mfile, loff_t offset, int origint)
+{
+	return -ESPIPE;
+}
+
+static int
+x1226_command(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+	return -EINVAL;
+}
+
+static int
+rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	  unsigned long arg)
+{
+	struct rtc_time rtc_tm;
+	int ret;
+
+	switch (cmd) {
+	case RTC_RD_TIME:	/* Read the time/date from RTC  */
+		memset(&rtc_tm, 0, sizeof(rtc_tm));
+		if ((ret = x1226_get_time(this_client, &rtc_tm)) < 0)
+			return ret;
+		return copy_to_user((void *) arg, &rtc_tm, sizeof (rtc_tm)) ?
+		    -EFAULT : 0;
+	case RTC_SET_TIME:	/* Set the RTC */
+		if (!capable(CAP_SYS_TIME))
+			return -EACCES;
+
+		if (copy_from_user(&rtc_tm,
+				   (struct rtc_time *) arg,
+				   sizeof (struct rtc_time)))
+			return -EFAULT;
+
+		return x1226_set_time(this_client, &rtc_tm);
+	default:
+		return -EINVAL;
+	}
+}
+
+static struct i2c_driver x1226_driver = {
+	.name = X1226_MODULE_NAME,
+	.id = I2C_DRIVERID_EXP3,
+	.flags = I2C_DF_NOTIFY,
+	.attach_adapter = x1226_probe,
+	.detach_client = x1226_detach,
+	.command = x1226_command
+};
+
+static struct file_operations rtc_fops = {
+	.owner = THIS_MODULE,
+	.llseek = rtc_llseek,
+	.ioctl = rtc_ioctl,
+	.open = rtc_open,
+	.release = rtc_release,
+};
+
+static struct miscdevice x1226rtc_miscdev = {
+	RTC_MINOR,
+	"rtc",
+	&rtc_fops
+};
+
+static __init int
+x1226_init(void)
+{
+	int ret;
+
+	info("I2C based RTC driver.\n");
+	ret = i2c_add_driver(&x1226_driver);
+	if (ret) {
+		err("Register I2C driver failed, errno is %d\n", ret);
+		return ret;
+	}
+	ret = misc_register(&x1226rtc_miscdev);
+	if (ret) {
+		err("Register misc driver failed, errno is %d\n", ret);
+		ret = i2c_del_driver(&x1226_driver);
+		if (ret) {
+			err("Unregister I2C driver failed, errno is %d\n", ret);
+		}
+		return ret;
+	}
+
+	create_proc_read_entry("driver/rtc", 0, 0, rtc_read_proc, NULL);
+
+	return 0;
+}
+
+static void __exit
+x1226_exit(void)
+{
+	remove_proc_entry("driver/rtc", NULL);
+	misc_deregister(&x1226rtc_miscdev);
+	i2c_del_driver(&x1226_driver);
+}
+
+module_init(x1226_init);
+module_exit(x1226_exit);
+
+/*
+ *	Info exported via "/proc/driver/rtc".
+ */
+
+static int
+rtc_proc_output(char *buf)
+{
+	char *p;
+	struct rtc_time tm;
+	int ret;
+
+	if ((ret = x1226_get_time(this_client, &tm)) < 0)
+		return ret;
+
+	p = buf;
+
+	/*
+	 * There is no way to tell if the luser has the RTC set for local
+	 * time or for Universal Standard Time (GMT). Probably local though.
+	 */
+	p += sprintf(p,
+		     "rtc_time\t: %02d:%02d:%02d\n"
+		     "rtc_date\t: %04d-%02d-%02d\n"
+		     "rtc_epoch\t: %04d\n",
+		     tm.tm_hour, tm.tm_min, tm.tm_sec,
+		     tm.tm_year + SYS_EPOCH, tm.tm_mon + 1, tm.tm_mday, EPOCH);
+
+	return p - buf;
+}
+
+static int
+rtc_read_proc(char *page, char **start, off_t off,
+	      int count, int *eof, void *data)
+{
+	int len = rtc_proc_output(page);
+	if (len <= off + count)
+		*eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len > count)
+		len = count;
+	if (len < 0)
+		len = 0;
+	return len;
+}
+
+MODULE_AUTHOR("Steve Longerbeam");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/drivers/char/xilinx_gpio/adapter.c linux-2.4.29-uc1/drivers/char/xilinx_gpio/adapter.c
--- linux-2.4.29/drivers/char/xilinx_gpio/adapter.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/xilinx_gpio/adapter.c	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,349 @@
+/*
+ * adapter.c
+ *
+ * Xilinx GPIO Adapter component to interface GPIO component to Linux
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under the terms
+ * of the GNU General Public License version 2.  This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+/*
+ * This driver is a bit unusual in that it is composed of two logical
+ * parts where one part is the OS independent code and the other part is
+ * the OS dependent code.  Xilinx provides their drivers split in this
+ * fashion.  This file represents the Linux OS dependent part known as
+ * the Linux adapter.  The other files in this directory are the OS
+ * independent files as provided by Xilinx with no changes made to them.
+ * The names exported by those files begin with XGpio_.  All functions
+ * in this file that are called by Linux have names that begin with
+ * xgpio_.  Any other functions are static helper functions.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/miscdevice.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+/* Use the IBM OCP definitions for compatibility. */
+#include <linux/ibm_ocp_gpio.h> 
+
+#include "xbasic_types.h"
+#include <asm/autoconfig.h>  /* Back compat. support */
+#include "xgpio.h"
+#include "xgpio_i.h"
+
+MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
+MODULE_DESCRIPTION("Xilinx GPIO driver");
+MODULE_LICENSE("GPL");
+
+/* Our private per interface data. */
+struct xgpio_instance {
+	struct xgpio_instance *next_inst;	/* The next instance in inst_list */
+	int index;		/* Which interface is this */
+	u32 save_BaseAddress;	/* Saved physical base address */
+	/*
+	 * The underlying OS independent code needs space as well.  A
+	 * pointer to the following XGpio structure will be passed to
+	 * any XGpio_ function that requires it.  However, we treat the
+	 * data as an opaque object in this file (meaning that we never
+	 * reference any of the fields inside of the structure).
+	 */
+	XGpio Gpio;
+};
+/* List of instances we're handling. */
+static struct xgpio_instance *inst_list = NULL;
+
+/* SAATODO: This function will be moved into the Xilinx code. */
+/*****************************************************************************/
+/**
+*
+* Lookup the device configuration based on the GPIO instance.  The table
+* XGpio_ConfigTable contains the configuration info for each device in the system.
+*
+* @param Instance is the index of the interface being looked up.
+*
+* @return
+*
+* A pointer to the configuration table entry corresponding to the given
+* device ID, or NULL if no match is found.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XGpio_Config *XGpio_GetConfig(int Instance)
+{
+	if (Instance < 0 || Instance >= CONFIG_XILINX_GPIO_NUM_INSTANCES)
+	{
+		return NULL;
+	}
+
+	return &XGpio_ConfigTable[Instance];
+}
+
+/* SAATODO: This function will be moved into the Xilinx code. */
+/****************************************************************************/
+/**
+* Get the input/output direction of all discrete signals.
+*
+* @param InstancePtr is a pointer to an XGpio instance to be worked on.
+*
+* @return Current copy of the tristate (direction) register.
+*
+* @note
+*
+* None
+*
+*****************************************************************************/
+u32
+XGpio_GetDataDirection(XGpio * InstancePtr)
+{
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	return XGpio_mReadReg(InstancePtr->BaseAddress, XGPIO_TRI_OFFSET);
+}
+
+static int
+xgpio_open(struct inode *inode, struct file *file)
+{
+	MOD_INC_USE_COUNT;
+
+	return 0;
+}
+
+static int
+xgpio_release(struct inode *inode, struct file *file)
+{
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+static int
+ioctl_setup(unsigned long arg,
+	    struct ibm_gpio_ioctl_data *ioctl_data,
+	    struct xgpio_instance **match)
+{
+	struct xgpio_instance *inst;
+
+	if (copy_from_user(ioctl_data, (void *) arg, sizeof (*ioctl_data)))
+		return -EFAULT;
+
+	inst = inst_list;
+	while (inst && inst->index != ioctl_data->device)
+		inst = inst->next_inst;
+
+	*match = inst;
+	return inst ? 0 : -ENODEV;
+}
+
+static int
+xgpio_ioctl(struct inode *inode, struct file *file,
+	    unsigned int cmd, unsigned long arg)
+{
+	struct ibm_gpio_ioctl_data ioctl_data;
+	struct xgpio_instance *inst;
+	int status;
+	u32 r;
+
+	switch (cmd) {
+	case IBMGPIO_IN:
+		status = ioctl_setup(arg, &ioctl_data, &inst);
+		if (status < 0)
+			return status;
+
+#if 0
+		/* Ensure that the GPIO bits in the mask are tristated. */
+		r = XGpio_GetDataDirection(&inst->Gpio);
+		XGpio_SetDataDirection(&inst->Gpio, r & ioctl_data.mask);
+#endif
+
+		ioctl_data.data = (XGpio_DiscreteRead(&inst->Gpio));
+
+		if (copy_to_user((struct ibm_gpio_ioctl_data *) arg,
+				 &ioctl_data, sizeof (ioctl_data))) {
+			return -EFAULT;
+		}
+		break;
+
+	case IBMGPIO_OUT:
+		status = ioctl_setup(arg, &ioctl_data, &inst);
+		if (status < 0)
+			return status;
+
+#if 0
+		/* Get the prior value. */
+		r = XGpio_DiscreteRead(&inst->Gpio);
+		/* Clear the bits that we're going to put in. */
+		r &= ~ioctl_data.mask;
+		/* Set the bits that were provided. */
+		r |= (ioctl_data.mask & ioctl_data.data);
+#else
+		r=ioctl_data.data;
+#endif
+
+		XGpio_DiscreteWrite(&inst->Gpio, r);
+
+#if 0
+		/* Ensure that the GPIO bits in the mask are not tristated. */
+		r = XGpio_GetDataDirection(&inst->Gpio);
+		XGpio_SetDataDirection(&inst->Gpio, r | ioctl_data.mask);
+#endif
+
+		break;
+
+	case IBMGPIO_TRISTATE:
+		status = ioctl_setup(arg, &ioctl_data, &inst);
+		if (status < 0)
+			return status;
+
+#if 0
+		/* Get the prior value. */
+		r = XGpio_GetDataDirection(&inst->Gpio);
+		/* Clear the bits that we're going to put in. */
+		r &= ~ioctl_data.mask;
+		/* Set the bits that were provided. */
+		r |= (ioctl_data.mask & ioctl_data.data);
+#else
+		r = ioctl_data.mask;
+
+#endif
+		XGpio_SetDataDirection(&inst->Gpio, r);
+		break;
+
+	default:
+		return -ENOIOCTLCMD;
+
+	}
+	return 0;
+}
+
+static void
+remove_head_inst(void)
+{
+	struct xgpio_instance *inst;
+	XGpio_Config *cfg;
+
+	/* Pull the head off of inst_list. */
+	inst = inst_list;
+	inst_list = inst->next_inst;
+
+	cfg = XGpio_GetConfig(inst->index);
+	iounmap((void *) cfg->BaseAddress);
+	cfg->BaseAddress = inst->save_BaseAddress;
+}
+
+static struct file_operations xfops = {
+	owner:THIS_MODULE,
+	ioctl:xgpio_ioctl,
+	open:xgpio_open,
+	release:xgpio_release,
+};
+/*
+ * We get to all of the GPIOs through one minor number.  Here's the
+ * miscdevice that gets registered for that minor number.
+ */
+static struct miscdevice miscdev = {
+	minor:GPIO_MINOR,
+	name:"xgpio",
+	fops:&xfops
+};
+
+static int __init
+probe(int index)
+{
+	static const unsigned long remap_size
+	    = CONFIG_XILINX_GPIO_0_HIGHADDR - CONFIG_XILINX_GPIO_0_BASEADDR + 1;
+	struct xgpio_instance *inst;
+	XGpio_Config *cfg;
+
+	/* Find the config for our instance. */
+	cfg = XGpio_GetConfig(index);
+	if (!cfg)
+		return -ENODEV;
+
+	/* Allocate the inst and zero it out. */
+	inst = (struct xgpio_instance *) kmalloc(sizeof (struct xgpio_instance),
+						 GFP_KERNEL);
+	if (!inst) {
+		printk(KERN_ERR "%s #%d: Could not allocate instance.\n",
+		       miscdev.name, index);
+		return -ENOMEM;
+	}
+	memset(inst, 0, sizeof (struct xgpio_instance));
+	inst->index = index;
+
+	/* Make it the head of inst_list. */
+	inst->next_inst = inst_list;
+	inst_list = inst;
+
+	/* Change the addresses to be virtual; save the old ones to restore. */
+	inst->save_BaseAddress = cfg->BaseAddress;
+	cfg->BaseAddress = (u32) ioremap(inst->save_BaseAddress, remap_size);
+
+	/* Tell the Xilinx code to bring this GPIO interface up. */
+	if (XGpio_Initialize(&inst->Gpio, cfg->DeviceId) != XST_SUCCESS) {
+		printk(KERN_ERR "%s #%d: Could not initialize instance.\n",
+		       miscdev.name, inst->index);
+		remove_head_inst();
+		return -ENODEV;
+	}
+
+	printk(KERN_INFO "%s #%d at 0x%08X mapped to 0x%08X\n",
+	       miscdev.name, inst->index,
+	       inst->save_BaseAddress, cfg->BaseAddress);
+
+	return 0;
+}
+
+static int __init
+xgpio_init(void)
+{
+	int rtn, index = 0;
+
+	while (probe(index++) == 0) ;
+
+	if (index > 1) {
+		/* We found at least one instance. */
+
+		/* Register the driver with misc and report success. */
+		rtn = misc_register(&miscdev);
+		if (rtn) {
+			printk(KERN_ERR "%s: Could not register driver.\n",
+			       miscdev.name);
+			while (inst_list)
+				remove_head_inst();
+			return rtn;
+		}
+
+		/* Report success. */
+		printk("Xilinx GPIO registered\n");
+		return 0;
+	} else {
+		/* No instances found. */
+		return -ENODEV;
+	}
+
+}
+
+static void __exit
+xgpio_cleanup(void)
+{
+	while (inst_list)
+		remove_head_inst();
+
+	misc_deregister(&miscdev);
+}
+
+EXPORT_NO_SYMBOLS;
+
+module_init(xgpio_init);
+module_exit(xgpio_cleanup);
diff -urN linux-2.4.29/drivers/char/xilinx_gpio/Makefile linux-2.4.29-uc1/drivers/char/xilinx_gpio/Makefile
--- linux-2.4.29/drivers/char/xilinx_gpio/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/xilinx_gpio/Makefile	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,20 @@
+#
+# Makefile for the Xilinx GPIO driver
+#
+
+EXTRA_CFLAGS		+= -I$(TOPDIR)/arch/microblaze/xilinx_ocp
+
+list-multi		:= xilinx_gpio.o
+
+# The Linux adapter for the Xilinx driver code.
+xilinx_gpio-objs	+= adapter.o
+
+# The Xilinx OS independent code.
+xilinx_gpio-objs	+= xgpio.o xgpio_g.o
+
+obj-$(CONFIG_XILINX_GPIO) := xilinx_gpio.o
+
+xilinx_gpio.o: $(xilinx_gpio-objs)
+	$(LD) -r -o $@ $(xilinx_gpio-objs)
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/char/xilinx_gpio/xgpio.c linux-2.4.29-uc1/drivers/char/xilinx_gpio/xgpio.c
--- linux-2.4.29/drivers/char/xilinx_gpio/xgpio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/xilinx_gpio/xgpio.c	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,220 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2003 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/**
+* @file xgpio.c
+*
+* The implementation of the XGpio component's basic functionality. See xgpio.h
+* for more information about the component.
+*
+* @note
+*
+* None
+*
+*****************************************************************************/
+
+/***************************** Include Files ********************************/
+#include <asm/autoconfig.h>
+#include "xgpio.h"
+#include "xgpio_i.h"
+#include "xstatus.h"
+
+/************************** Constant Definitions ****************************/
+
+/**************************** Type Definitions ******************************/
+
+/***************** Macros (Inline Functions) Definitions ********************/
+
+/************************** Variable Definitions ****************************/
+
+/************************** Function Prototypes *****************************/
+
+/****************************************************************************/
+/**
+* Initialize the XGpio instance provided by the caller based on the
+* given DeviceID.
+*
+* Nothing is done except to initialize the InstancePtr.
+*
+* @param InstancePtr is a pointer to an XGpio instance. The memory the pointer
+*        references must be pre-allocated by the caller. Further calls to
+*        manipulate the component through the XGpio API must be made with this
+*        pointer.
+*
+* @param DeviceId is the unique id of the device controlled by this XGpio
+*        component.  Passing in a device id associates the generic XGpio
+*        instance to a specific device, as chosen by the caller or application
+*        developer.
+*
+* @return
+*
+* - XST_SUCCESS           Initialization was successfull.
+* - XST_DEVICE_NOT_FOUND  Device configuration data was not found for a device
+*                         with the supplied device ID.
+*
+* NOTES:
+*
+* None
+*
+*****************************************************************************/
+XStatus
+XGpio_Initialize(XGpio * InstancePtr, u16 DeviceId)
+{
+	XGpio_Config *ConfigPtr;
+
+	/*
+	 * Assert arguments
+	 */
+	XASSERT_NONVOID(InstancePtr != NULL);
+
+	/*
+	 * Lookup configuration data in the device configuration table.
+	 * Use this configuration info down below when initializing this component.
+	 */
+	ConfigPtr = XGpio_LookupConfig(DeviceId);
+	if (ConfigPtr == (XGpio_Config *) NULL) {
+		InstancePtr->IsReady = 0;
+		return (XST_DEVICE_NOT_FOUND);
+	}
+
+	/*
+	 * Set some default values.
+	 */
+	InstancePtr->BaseAddress = ConfigPtr->BaseAddress;
+
+	/*
+	 * Indicate the instance is now ready to use, initialized without error
+	 */
+	InstancePtr->IsReady = XCOMPONENT_IS_READY;
+	return (XST_SUCCESS);
+}
+
+/******************************************************************************/
+/**
+* Lookup the device configuration based on the unique device ID.  The table
+* ConfigTable contains the configuration info for each device in the system.
+*
+* @param DeviceID is the device identifier to lookup.
+*
+* @return
+*
+* - XGpio configuration structure pointer if DeviceID is found.
+* - NULL if DeviceID is not found.
+*
+******************************************************************************/
+XGpio_Config *
+XGpio_LookupConfig(u16 DeviceId)
+{
+	XGpio_Config *CfgPtr = NULL;
+
+	int i;
+
+	for (i = 0; i < CONFIG_XILINX_GPIO_NUM_INSTANCES; i++) {
+		if (XGpio_ConfigTable[i].DeviceId == DeviceId) {
+			CfgPtr = &XGpio_ConfigTable[i];
+			break;
+		}
+	}
+
+	return CfgPtr;
+}
+
+/****************************************************************************/
+/**
+* Set the input/output direction of all discrete signals.
+*
+* @param InstancePtr is a pointer to an XGpio instance to be worked on.
+* @param DirectionMask is a bitmask specifying which discretes are input and
+*        which are output. Bits set to 0 are output and bits set to 1 are input.
+*
+* @note
+*
+* None
+*
+*****************************************************************************/
+void
+XGpio_SetDataDirection(XGpio * InstancePtr, u32 DirectionMask)
+{
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	XGpio_mWriteReg(InstancePtr->BaseAddress, XGPIO_TRI_OFFSET,
+			DirectionMask);
+}
+
+/****************************************************************************/
+/**
+* Read state of discretes.
+*
+* @param InstancePtr is a pointer to an XGpio instance to be worked on.
+*
+* @return Current copy of the discretes register.
+*
+* @note
+*
+* None
+*
+*****************************************************************************/
+u32
+XGpio_DiscreteRead(XGpio * InstancePtr)
+{
+	u32 temp;
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	temp = XGpio_mReadReg(InstancePtr->BaseAddress, XGPIO_DATA_OFFSET);
+	return (XGpio_mReadReg(InstancePtr->BaseAddress, XGPIO_DATA_OFFSET));
+}
+
+/****************************************************************************/
+/**
+* Write to discretes register
+*
+* @param InstancePtr is a pointer to an XGpio instance to be worked on.
+* @param Data is the value to be written to the discretes register.
+*
+* @note
+*
+* See also XGpio_DiscreteSet() and XGpio_DiscreteClear().
+*
+*****************************************************************************/
+void
+XGpio_DiscreteWrite(XGpio * InstancePtr, u32 Data)
+{
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	XGpio_mWriteReg(InstancePtr->BaseAddress, XGPIO_DATA_OFFSET, Data);
+}
diff -urN linux-2.4.29/drivers/char/xilinx_gpio/xgpio_g.c linux-2.4.29-uc1/drivers/char/xilinx_gpio/xgpio_g.c
--- linux-2.4.29/drivers/char/xilinx_gpio/xgpio_g.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/xilinx_gpio/xgpio_g.c	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,64 @@
+
+/*******************************************************************
+*
+* CAUTION: This file is automatically generated by libgen.
+* Version: Xilinx EDK 3.2.2 EDK_Cm.22
+* DO NOT EDIT.
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2003 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+* 
+* Description: Driver configuration
+*
+*******************************************************************/
+
+#include <asm/autoconfig.h>
+#include "xgpio.h"
+
+/*
+* The configuration table for devices
+*/
+
+XGpio_Config XGpio_ConfigTable[] = {
+	{
+	 0,
+	 CONFIG_XILINX_GPIO_0_BASEADDR}
+/*
+	,
+	{
+	 1,
+	 CONFIG_XILINX_GPIO_1_BASEADDR}
+*/
+};
diff -urN linux-2.4.29/drivers/char/xilinx_gpio/xgpio.h linux-2.4.29-uc1/drivers/char/xilinx_gpio/xgpio.h
--- linux-2.4.29/drivers/char/xilinx_gpio/xgpio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/xilinx_gpio/xgpio.h	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,121 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2003 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+* @file xgpio.h
+*
+* This file contains the software API definition of the Xilinx General Purpose
+* I/O (XGpio) component.
+*
+* The Xilinx GPIO controller is a soft IP core designed for  Xilinx FPGAs and
+* contains the following general features:
+*   - Support for 8, 16, or 32 I/O discretes
+*   - Each of the discretes can be configured for input or output.
+*
+* @note
+*
+* This API utilizes 32 bit I/O to the GPIO registers. With 16 and 8 bit GPIO
+* components, the unused bits from registers are read as zero and written as
+* don't cares.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rmm  03/13/02 First release
+* </pre>
+*****************************************************************************/
+
+#ifndef XGPIO_H			/* prevent circular inclusions */
+#define XGPIO_H			/* by using protection macros */
+
+/***************************** Include Files ********************************/
+
+#include <xbasic_types.h>
+#include <xstatus.h>
+#include "xgpio_l.h"
+
+/************************** Constant Definitions ****************************/
+
+/**************************** Type Definitions ******************************/
+
+/*
+ * This typedef contains configuration information for the device.
+ */
+typedef struct {
+	u16 DeviceId;		/* Unique ID  of device */
+	u32 BaseAddress;	/* Device base address */
+} XGpio_Config;
+
+/**
+ * The XGpio driver instance data. The user is required to allocate a
+ * variable of this type for every GPIO device in the system. A pointer
+ * to a variable of this type is then passed to the driver API functions.
+ */
+typedef struct {
+	u32 BaseAddress;	/* Device base address */
+	u32 IsReady;		/* Device is initialized and ready */
+} XGpio;
+
+/***************** Macros (Inline Functions) Definitions ********************/
+
+/************************** Function Prototypes *****************************/
+
+/*
+ * API Basic functions implemented in xgpio.c
+ */
+XStatus XGpio_Initialize(XGpio * InstancePtr, u16 DeviceId);
+void XGpio_SetDataDirection(XGpio * InstancePtr, u32 DirectionMask);
+u32 XGpio_DiscreteRead(XGpio * InstancePtr);
+void XGpio_DiscreteWrite(XGpio * InstancePtr, u32 Mask);
+
+XGpio_Config *XGpio_LookupConfig(u16 DeviceId);
+
+/*
+ * API Functions implemented in xgpio_extra.c
+ */
+void XGpio_DiscreteSet(XGpio * InstancePtr, u32 Mask);
+void XGpio_DiscreteClear(XGpio * InstancePtr, u32 Mask);
+
+/*
+ * API Functions implemented in xgpio_selftest.c
+ */
+XStatus XGpio_SelfTest(XGpio * InstancePtr);
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/drivers/char/xilinx_gpio/xgpio_i.h linux-2.4.29-uc1/drivers/char/xilinx_gpio/xgpio_i.h
--- linux-2.4.29/drivers/char/xilinx_gpio/xgpio_i.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/xilinx_gpio/xgpio_i.h	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,78 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2003 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/******************************************************************************/
+/**
+* @file xgpio_i.h
+*
+* This header file contains internal identifiers, which are those shared
+* between the files of the driver. It is intended for internal use only.
+*
+* NOTES:
+*
+* None.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rmm  03/13/02 First release
+* </pre>
+******************************************************************************/
+
+#ifndef XGPIO_I_H		/* prevent circular inclusions */
+#define XGPIO_I_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xgpio.h"
+
+/************************** Constant Definitions ****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+/************************** Variable Definitions ****************************/
+
+extern XGpio_Config XGpio_ConfigTable[];
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/drivers/char/xilinx_gpio/xgpio_l.h linux-2.4.29-uc1/drivers/char/xilinx_gpio/xgpio_l.h
--- linux-2.4.29/drivers/char/xilinx_gpio/xgpio_l.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/xilinx_gpio/xgpio_l.h	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,193 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2003 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xgpio_l.h
+*
+* This header file contains identifiers and low-level driver functions (or
+* macros) that can be used to access the device.  The user should refer to the
+* hardware device specification for more details of the device operation.
+* High-level driver functions are defined in xgpio.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00b jhl  04/24/02 First release
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XGPIO_L_H		/* prevent circular inclusions */
+#define XGPIO_L_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include <xbasic_types.h>
+#include <xio.h>
+
+/************************** Constant Definitions *****************************/
+
+/** @name Registers
+ *
+ * Register offsets for this device. This device does not utilize IPIF registers.
+ * @{
+ */
+/**
+ * - XGPIO_DATA_OFFSET    Data register
+ * - XGPIO_TRI_OFFSET     Three state register (sets input/output direction)
+ *                        0 configures pin for output and 1 for input.
+ */
+#define XGPIO_DATA_OFFSET  0x00000000
+#define XGPIO_TRI_OFFSET   0x00000004
+/* @} */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************
+*
+* Low-level driver macros.  The list below provides signatures to help the
+* user use the macros.
+*
+* u32 XGpio_mReadReg(u32 BaseAddress, int RegOffset, u32 Data)
+* void XGpio_mWriteReg(u32 BaseAddress, int RegOffset, u32 Data)
+*
+* void XGpio_mSetDataDirection(u32 BaseAddress, u32 DirectionMask)
+*
+* u32 XGpio_mGetDataReg(u32 BaseAddress)
+* void XGpio_mSetDataReg(u32 BaseAddress, u32 Mask)
+*
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+ *
+ * Write a value to a GPIO register. A 32 bit write is performed. If the
+ * GPIO component is implemented in a smaller width, only the least
+ * significant data is written.
+ *
+ * @param   BaseAddress is the base address of the GPIO device.
+ * @param   RegOffset is the register offset from the base to write to.
+ * @param   Data is the data written to the register.
+ *
+ * @return  None.
+ *
+ * @note    None.
+ *
+ ****************************************************************************/
+#define XGpio_mWriteReg(BaseAddress, RegOffset, Data) \
+    (XIo_Out32((BaseAddress) + (RegOffset), (u32)(Data)))
+
+/****************************************************************************/
+/**
+ *
+ * Read a value from a GPIO register. A 32 bit read is performed. If the
+ * GPIO component is implemented in a smaller width, only the least
+ * significant data is read from the register. The most significant data
+ * will be read as 0.
+ *
+ * @param   BaseAddress is the base address of the GPIO device.
+ * @param   Register is the register offset from the base to write to.
+ * @param   Data is the data written to the register.
+ *
+ * @return  None.
+ *
+ * @note    None.
+ *
+ ****************************************************************************/
+#define XGpio_mReadReg(BaseAddress, RegOffset) \
+    (XIo_In32((BaseAddress) + (RegOffset)))
+
+/*****************************************************************************
+*
+* Set the input/output direction of all signals.
+*
+* @param    BaseAddress contains the base address of the GPIO device.
+* @param    DirectionMask is a bitmask specifying which discretes are input and
+*           which are output. Bits set to 0 are output and bits set to 1 are
+*           input.
+*
+* @return   None.
+*
+* @note     None.
+*
+******************************************************************************/
+#define XGpio_mSetDataDirection(BaseAddress, DirectionMask) \
+	printk("Setting data direction %08X\n",DirectionMask); \
+    XGpio_mWriteReg((BaseAddress), XGPIO_TRI_OFFSET, (DirectionMask))
+
+/****************************************************************************/
+/**
+* Get the data register.
+*
+* @param    BaseAddress contains the base address of the GPIO device.
+*
+* @return   The contents of the data register.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XGpio_mGetDataReg(BaseAddress) \
+    XGpio_mReadReg(BaseAddress, XGPIO_DATA_OFFSET)
+
+/****************************************************************************/
+/**
+* Set the data register.
+*
+* @param    BaseAddress contains the base address of the GPIO device.
+* @param    Data is the value to be written to the data register.
+*
+* @return   None.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XGpio_mSetDataReg(BaseAddress, Data) \
+	printk("Writing data %08X\n",Data);	\
+    XGpio_mWriteReg((BaseAddress), XGPIO_DATA_OFFSET, (Data));
+
+/************************** Function Prototypes ******************************/
+
+/************************** Variable Definitions *****************************/
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/drivers/char/xymem.c linux-2.4.29-uc1/drivers/char/xymem.c
--- linux-2.4.29/drivers/char/xymem.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/char/xymem.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,192 @@
+/****************************************************************************/
+
+/*
+ *	xymem.c  -- memory driver for DSP X/Y memory.
+ *
+ *	(C) Copyright 2001, Greg Ungerer (gerg@snapgear.com)
+ *	(C) Copyright 2001, Lineo (www.lineo.com)
+ */
+
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+#include <linux/devfs_fs_kernel.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/pgalloc.h>
+
+/****************************************************************************/
+
+static char	*version = "v1.0.0";
+
+MODULE_DESCRIPTION("XYMEM -- X/Y memory driver for SH3-DSP");
+MODULE_AUTHOR("Greg Ungerer (gerg@snapgear.com)");
+
+#ifndef XYMEM_MAJOR
+#define	XYMEM_MAJOR	127
+#endif
+
+/****************************************************************************/
+
+/*
+ *	Physical addresses of xymem regions, and their virtual memory
+ *	mapping addresses. The regions are setup as:
+ *
+ *	[0] = entire xymem region
+ *	[1] = x-memory region
+ *	[2] = y-memory region
+ */
+#define	XYMEM_REGIONS	3
+
+struct xyregion {
+	unsigned long	phys;
+	unsigned int	len;
+	void		*virt;
+};
+
+struct xyregion	xymem_regions[XYMEM_REGIONS] = {
+	{ 0xa5000000, (16*1024*1024), NULL },
+	{ 0xa5007000, (8*1024), NULL },
+	{ 0xa5017000, (8*1024), NULL },
+};
+
+/****************************************************************************/
+
+int xymem_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	unsigned long	size;
+	int		m;
+
+#if 0
+	printk("xymem_mmap(file=%x,vma=%x)\n", (int)file, (int)vma);
+#endif
+
+	m = MINOR(file->f_dentry->d_inode->i_rdev);
+	if ((m < 0) || (m >= XYMEM_REGIONS))
+		return(-EINVAL);
+
+	size = vma->vm_end - vma->vm_start;
+	if (size > xymem_regions[m].len)
+		size = xymem_regions[m].len;
+
+	vma->vm_flags |= VM_RESERVED | VM_IO;
+	vma->vm_page_prot.pgprot &= ~_PAGE_CACHABLE;
+	if (remap_page_range(vma->vm_start, xymem_regions[m].phys,
+	    size, vma->vm_page_prot))
+		return(EAGAIN);
+
+	return(0);
+}
+
+/****************************************************************************/
+
+ssize_t xymem_read(struct file *fp, char *buf, size_t count, loff_t *offp)
+{
+	unsigned long	ppos, len;
+	int		m;
+
+	m = MINOR(fp->f_dentry->d_inode->i_rdev);
+	if ((m < 0) || (m >= XYMEM_REGIONS))
+		return(-ENODEV);
+	if (xymem_regions[m].virt == NULL)
+		return(-ENODEV);
+	ppos = *offp;
+	if (ppos >= xymem_regions[m].len)
+		return(0);
+
+	len = xymem_regions[m].len - ppos;
+	if (count < len)
+		len = count;
+	copy_to_user(buf, (xymem_regions[m].virt + ppos), len);
+	*offp += len;
+
+	return(len);
+}
+
+/****************************************************************************/
+
+ssize_t xymem_write(struct file *fp, const char *buf, size_t count, loff_t *offp)
+{
+	unsigned long	ppos, len;
+	int		m;
+
+	m = MINOR(fp->f_dentry->d_inode->i_rdev);
+	if ((m < 0) || (m >= XYMEM_REGIONS))
+		return(-ENODEV);
+	if (xymem_regions[m].virt == NULL)
+		return(-ENODEV);
+	ppos = *offp;
+	if (ppos >= xymem_regions[m].len)
+		return(0);
+
+	len = xymem_regions[m].len - ppos;
+	if (count < len)
+		len = count;
+	copy_from_user((xymem_regions[m].virt + ppos), buf, len);
+	*offp += len;
+
+	return(len);
+}
+
+/****************************************************************************/
+
+struct file_operations	xymem_ops = {
+	owner:	THIS_MODULE,
+	read:	xymem_read,
+	write:	xymem_write,
+	mmap:	xymem_mmap,
+};
+
+/****************************************************************************/
+
+int __init xymem_init(void)
+{
+	void	*vp;
+	int	i;
+
+	printk("XYMEM driver: version %s\n"
+		"(C) Copyright 2001, Greg Ungerer (gerg@snapgear.com)\n"
+		"(C) Copyright 2001, Lineo (www.lineo.com)\n", version);
+
+	if ((i = devfs_register_chrdev(XYMEM_MAJOR, "xymem", &xymem_ops)))
+		printk("XYMEM: failed to register device, error=%d??\n", i);
+
+	for (i = 0; (i < XYMEM_REGIONS); i++) {
+		vp = ioremap(xymem_regions[i].phys, xymem_regions[i].len);
+		if ((xymem_regions[i].virt = vp) == NULL) {
+			printk("XYMEM: failed to ioremap(%x)\n",
+				(int) xymem_regions[i].phys);
+		}
+	}
+
+	return(0);
+}
+
+/****************************************************************************/
+
+void __exit xymem_fini(void)
+{
+	int	i;
+
+	printk("XYMEM: unloading driver\n");
+	devfs_unregister_chrdev(XYMEM_MAJOR, "xymem");
+	for (i = 0; (i < XYMEM_REGIONS); i++) {
+		if (xymem_regions[i].virt)
+			iounmap(xymem_regions[i].virt);
+	}
+}
+
+/****************************************************************************/
+
+module_init(xymem_init);
+module_exit(xymem_fini);
+
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/i2c/Config.in linux-2.4.29-uc1/drivers/i2c/Config.in
--- linux-2.4.29/drivers/i2c/Config.in	2004-04-14 14:05:29.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/Config.in	2005-06-14 02:12:19.000000000 +0100
@@ -11,16 +11,361 @@
    if [ "$CONFIG_I2C_ALGOBIT" != "n" ]; then
       dep_tristate '  Philips style parallel port adapter' CONFIG_I2C_PHILIPSPAR $CONFIG_I2C_ALGOBIT $CONFIG_PARPORT
       dep_tristate '  ELV adapter' CONFIG_I2C_ELV $CONFIG_I2C_ALGOBIT
+      dep_tristate '  Motorola Coldfire GPIO adapter (EXPERIMENTAL)' CONFIG_I2C_MCF_GPIO $CONFIG_I2C_ALGOBIT $CONFIG_COLDFIRE $CONFIG_EXPERIMENTAL
+      if [ "$CONFIG_I2C_MCF_GPIO" != "n" ]; then
+	 if [ "$CONFIG_M5204" = "y" -o "$CONFIG_M5206" = "y" -o "$CONFIG_M5206e" = "y" ]; then
+	    comment 'M5204, M5206 and M5206e GPIO support'
+	    choice 'SDA GPIO pin' "PP0 CONFIG_I2C_MCF_GPIO_SDA_PP0 \
+				   PP1 CONFIG_I2C_MCF_GPIO_SDA_PP1 \
+				   PP2 CONFIG_I2C_MCF_GPIO_SDA_PP2 \
+				   PP3 CONFIG_I2C_MCF_GPIO_SDA_PP3 \
+				   PP4 CONFIG_I2C_MCF_GPIO_SDA_PP4 \
+				   PP5 CONFIG_I2C_MCF_GPIO_SDA_PP5 \
+				   PP6 CONFIG_I2C_MCF_GPIO_SDA_PP6 \
+				   PP7 CONFIG_I2C_MCF_GPIO_SDA_PP7" PP0
+	    choice 'SCL GPIO pin' "PP0 CONFIG_I2C_MCF_GPIO_SCL_PP0 \
+				   PP1 CONFIG_I2C_MCF_GPIO_SCL_PP1 \
+				   PP2 CONFIG_I2C_MCF_GPIO_SCL_PP2 \
+				   PP3 CONFIG_I2C_MCF_GPIO_SCL_PP3 \
+				   PP4 CONFIG_I2C_MCF_GPIO_SCL_PP4 \
+				   PP5 CONFIG_I2C_MCF_GPIO_SCL_PP5 \
+				   PP6 CONFIG_I2C_MCF_GPIO_SCL_PP6 \
+				   PP7 CONFIG_I2C_MCF_GPIO_SCL_PP7" PP1
+	 fi
+	 if [ "$CONFIG_M5249" = "y" ]; then
+	    comment 'M5249 GPIO support'
+	    choice 'SDA GPIO pin' "GPIO0 CONFIG_I2C_MCF_GPIO_SDA_GPIO0 \
+				   GPIO1 CONFIG_I2C_MCF_GPIO_SDA_GPIO1 \
+				   GPIO2 CONFIG_I2C_MCF_GPIO_SDA_GPIO2 \
+				   GPIO3 CONFIG_I2C_MCF_GPIO_SDA_GPIO3 \
+				   GPIO4 CONFIG_I2C_MCF_GPIO_SDA_GPIO4 \
+				   GPIO5 CONFIG_I2C_MCF_GPIO_SDA_GPIO5 \
+				   GPIO6 CONFIG_I2C_MCF_GPIO_SDA_GPIO6 \
+				   GPIO7 CONFIG_I2C_MCF_GPIO_SDA_GPIO7 \
+				   GPIO9 CONFIG_I2C_MCF_GPIO_SDA_GPIO9 \
+				   GPIO10 CONFIG_I2C_MCF_GPIO_SDA_GPIO10 \
+				   GPIO11 CONFIG_I2C_MCF_GPIO_SDA_GPIO11 \
+				   GPIO12 CONFIG_I2C_MCF_GPIO_SDA_GPIO12 \
+				   GPIO13 CONFIG_I2C_MCF_GPIO_SDA_GPIO13 \
+				   GPIO14 CONFIG_I2C_MCF_GPIO_SDA_GPIO14 \
+				   GPIO15 CONFIG_I2C_MCF_GPIO_SDA_GPIO15 \
+				   GPIO16 CONFIG_I2C_MCF_GPIO_SDA_GPIO16 \
+				   GPIO17 CONFIG_I2C_MCF_GPIO_SDA_GPIO17 \
+				   GPIO18 CONFIG_I2C_MCF_GPIO_SDA_GPIO18 \
+				   GPIO19 CONFIG_I2C_MCF_GPIO_SDA_GPIO19 \
+				   GPIO20 CONFIG_I2C_MCF_GPIO_SDA_GPIO20 \
+				   GPIO21 CONFIG_I2C_MCF_GPIO_SDA_GPIO21 \
+				   GPIO22 CONFIG_I2C_MCF_GPIO_SDA_GPIO22 \
+				   GPIO23 CONFIG_I2C_MCF_GPIO_SDA_GPIO23 \
+				   GPIO24 CONFIG_I2C_MCF_GPIO_SDA_GPIO24 \
+				   GPIO25 CONFIG_I2C_MCF_GPIO_SDA_GPIO25 \
+				   GPIO26 CONFIG_I2C_MCF_GPIO_SDA_GPIO26 \
+				   GPIO29 CONFIG_I2C_MCF_GPIO_SDA_GPIO29 \
+				   GPIO33 CONFIG_I2C_MCF_GPIO_SDA_GPIO33 \
+				   GPIO34 CONFIG_I2C_MCF_GPIO_SDA_GPIO34 \
+				   GPIO44 CONFIG_I2C_MCF_GPIO_SDA_GPIO44 \
+				   GPIO45 CONFIG_I2C_MCF_GPIO_SDA_GPIO45 \
+				   GPIO46 CONFIG_I2C_MCF_GPIO_SDA_GPIO46 \
+				   GPIO48 CONFIG_I2C_MCF_GPIO_SDA_GPIO48 \
+				   GPIO49 CONFIG_I2C_MCF_GPIO_SDA_GPIO49 \
+				   GPIO50 CONFIG_I2C_MCF_GPIO_SDA_GPIO50 \
+				   GPIO51 CONFIG_I2C_MCF_GPIO_SDA_GPIO51 \
+				   GPIO52 CONFIG_I2C_MCF_GPIO_SDA_GPIO52 \
+				   GPIO53 CONFIG_I2C_MCF_GPIO_SDA_GPIO53 \
+				   GPIO54 CONFIG_I2C_MCF_GPIO_SDA_GPIO54 \
+				   GPIO55 CONFIG_I2C_MCF_GPIO_SDA_GPIO55 \
+				   GPIO56 CONFIG_I2C_MCF_GPIO_SDA_GPIO56 \
+				   GPIO57 CONFIG_I2C_MCF_GPIO_SDA_GPIO57 \
+				   GPIO58 CONFIG_I2C_MCF_GPIO_SDA_GPIO58 \
+				   GPIO59 CONFIG_I2C_MCF_GPIO_SDA_GPIO59 \
+				   GPIO60 CONFIG_I2C_MCF_GPIO_SDA_GPIO60 \
+				   GPIO61 CONFIG_I2C_MCF_GPIO_SDA_GPIO61 \
+				   GPIO62 CONFIG_I2C_MCF_GPIO_SDA_GPIO62" \
+				   GPIO0
+	    choice 'SCL GPIO pin' "GPIO0 CONFIG_I2C_MCF_GPIO_SCL_GPIO0 \
+				   GPIO1 CONFIG_I2C_MCF_GPIO_SCL_GPIO1 \
+				   GPIO2 CONFIG_I2C_MCF_GPIO_SCL_GPIO2 \
+				   GPIO3 CONFIG_I2C_MCF_GPIO_SCL_GPIO3 \
+				   GPIO4 CONFIG_I2C_MCF_GPIO_SCL_GPIO4 \
+				   GPIO5 CONFIG_I2C_MCF_GPIO_SCL_GPIO5 \
+				   GPIO6 CONFIG_I2C_MCF_GPIO_SCL_GPIO6 \
+				   GPIO7 CONFIG_I2C_MCF_GPIO_SCL_GPIO7 \
+				   GPIO9 CONFIG_I2C_MCF_GPIO_SCL_GPIO9 \
+				   GPIO10 CONFIG_I2C_MCF_GPIO_SCL_GPIO10 \
+				   GPIO11 CONFIG_I2C_MCF_GPIO_SCL_GPIO11 \
+				   GPIO12 CONFIG_I2C_MCF_GPIO_SCL_GPIO12 \
+				   GPIO13 CONFIG_I2C_MCF_GPIO_SCL_GPIO13 \
+				   GPIO14 CONFIG_I2C_MCF_GPIO_SCL_GPIO14 \
+				   GPIO15 CONFIG_I2C_MCF_GPIO_SCL_GPIO15 \
+				   GPIO16 CONFIG_I2C_MCF_GPIO_SCL_GPIO16 \
+				   GPIO17 CONFIG_I2C_MCF_GPIO_SCL_GPIO17 \
+				   GPIO18 CONFIG_I2C_MCF_GPIO_SCL_GPIO18 \
+				   GPIO19 CONFIG_I2C_MCF_GPIO_SCL_GPIO19 \
+				   GPIO20 CONFIG_I2C_MCF_GPIO_SCL_GPIO20 \
+				   GPIO21 CONFIG_I2C_MCF_GPIO_SCL_GPIO21 \
+				   GPIO22 CONFIG_I2C_MCF_GPIO_SCL_GPIO22 \
+				   GPIO23 CONFIG_I2C_MCF_GPIO_SCL_GPIO23 \
+				   GPIO24 CONFIG_I2C_MCF_GPIO_SCL_GPIO24 \
+				   GPIO25 CONFIG_I2C_MCF_GPIO_SCL_GPIO25 \
+				   GPIO26 CONFIG_I2C_MCF_GPIO_SCL_GPIO26 \
+				   GPIO29 CONFIG_I2C_MCF_GPIO_SCL_GPIO29 \
+				   GPIO33 CONFIG_I2C_MCF_GPIO_SCL_GPIO33 \
+				   GPIO34 CONFIG_I2C_MCF_GPIO_SCL_GPIO34 \
+				   GPIO44 CONFIG_I2C_MCF_GPIO_SCL_GPIO44 \
+				   GPIO45 CONFIG_I2C_MCF_GPIO_SCL_GPIO45 \
+				   GPIO46 CONFIG_I2C_MCF_GPIO_SCL_GPIO46 \
+				   GPIO48 CONFIG_I2C_MCF_GPIO_SCL_GPIO48 \
+				   GPIO49 CONFIG_I2C_MCF_GPIO_SCL_GPIO49 \
+				   GPIO50 CONFIG_I2C_MCF_GPIO_SCL_GPIO50 \
+				   GPIO51 CONFIG_I2C_MCF_GPIO_SCL_GPIO51 \
+				   GPIO52 CONFIG_I2C_MCF_GPIO_SCL_GPIO52 \
+				   GPIO53 CONFIG_I2C_MCF_GPIO_SCL_GPIO53 \
+				   GPIO54 CONFIG_I2C_MCF_GPIO_SCL_GPIO54 \
+				   GPIO55 CONFIG_I2C_MCF_GPIO_SCL_GPIO55 \
+				   GPIO56 CONFIG_I2C_MCF_GPIO_SCL_GPIO56 \
+				   GPIO57 CONFIG_I2C_MCF_GPIO_SCL_GPIO57 \
+				   GPIO58 CONFIG_I2C_MCF_GPIO_SCL_GPIO58 \
+				   GPIO59 CONFIG_I2C_MCF_GPIO_SCL_GPIO59 \
+				   GPIO60 CONFIG_I2C_MCF_GPIO_SCL_GPIO60 \
+				   GPIO61 CONFIG_I2C_MCF_GPIO_SCL_GPIO61 \
+				   GPIO62 CONFIG_I2C_MCF_GPIO_SCL_GPIO62" \
+				   GPIO1
+	 fi
+	 if [ "$CONFIG_M5272" = "y" ]; then
+	    comment 'M5272 GPIO support'
+	    choice 'SDA GPIO pin' "PA0 CONFIG_I2C_MCF_GPIO_SDA_PA0 \
+				   PA1 CONFIG_I2C_MCF_GPIO_SDA_PA1 \
+				   PA2 CONFIG_I2C_MCF_GPIO_SDA_PA2 \
+				   PA3 CONFIG_I2C_MCF_GPIO_SDA_PA3 \
+				   PA4 CONFIG_I2C_MCF_GPIO_SDA_PA4 \
+				   PA5 CONFIG_I2C_MCF_GPIO_SDA_PA5 \
+				   PA6 CONFIG_I2C_MCF_GPIO_SDA_PA6 \
+				   PA7 CONFIG_I2C_MCF_GPIO_SDA_PA7 \
+				   PA8 CONFIG_I2C_MCF_GPIO_SDA_PA8 \
+				   PA9 CONFIG_I2C_MCF_GPIO_SDA_PA9 \
+				   PA10 CONFIG_I2C_MCF_GPIO_SDA_PA10 \
+				   PA11 CONFIG_I2C_MCF_GPIO_SDA_PA11 \
+				   PA12 CONFIG_I2C_MCF_GPIO_SDA_PA12 \
+				   PA13 CONFIG_I2C_MCF_GPIO_SDA_PA13 \
+				   PA14 CONFIG_I2C_MCF_GPIO_SDA_PA14 \
+				   PA15 CONFIG_I2C_MCF_GPIO_SDA_PA15 \
+				   PB0 CONFIG_I2C_MCF_GPIO_SDA_PB0 \
+				   PB1 CONFIG_I2C_MCF_GPIO_SDA_PB1 \
+				   PB2 CONFIG_I2C_MCF_GPIO_SDA_PB2 \
+				   PB3 CONFIG_I2C_MCF_GPIO_SDA_PB3 \
+				   PB4 CONFIG_I2C_MCF_GPIO_SDA_PB4 \
+				   PB5 CONFIG_I2C_MCF_GPIO_SDA_PB5 \
+				   PB6 CONFIG_I2C_MCF_GPIO_SDA_PB6 \
+				   PB7 CONFIG_I2C_MCF_GPIO_SDA_PB7 \
+				   PB8 CONFIG_I2C_MCF_GPIO_SDA_PB8 \
+				   PB9 CONFIG_I2C_MCF_GPIO_SDA_PB9 \
+				   PB10 CONFIG_I2C_MCF_GPIO_SDA_PB10 \
+				   PB11 CONFIG_I2C_MCF_GPIO_SDA_PB11 \
+				   PB12 CONFIG_I2C_MCF_GPIO_SDA_PB12 \
+				   PB13 CONFIG_I2C_MCF_GPIO_SDA_PB13 \
+				   PB14 CONFIG_I2C_MCF_GPIO_SDA_PB14 \
+				   PB15 CONFIG_I2C_MCF_GPIO_SDA_PB15 \
+				   PC0 CONFIG_I2C_MCF_GPIO_SDA_PC0 \
+				   PC1 CONFIG_I2C_MCF_GPIO_SDA_PC1 \
+				   PC2 CONFIG_I2C_MCF_GPIO_SDA_PC2 \
+				   PC3 CONFIG_I2C_MCF_GPIO_SDA_PC3 \
+				   PC4 CONFIG_I2C_MCF_GPIO_SDA_PC4 \
+				   PC5 CONFIG_I2C_MCF_GPIO_SDA_PC5 \
+				   PC6 CONFIG_I2C_MCF_GPIO_SDA_PC6 \
+				   PC7 CONFIG_I2C_MCF_GPIO_SDA_PC7 \
+				   PC8 CONFIG_I2C_MCF_GPIO_SDA_PC8 \
+				   PC9 CONFIG_I2C_MCF_GPIO_SDA_PC9 \
+				   PC10 CONFIG_I2C_MCF_GPIO_SDA_PC10 \
+				   PC11 CONFIG_I2C_MCF_GPIO_SDA_PC11 \
+				   PC12 CONFIG_I2C_MCF_GPIO_SDA_PC12 \
+				   PC13 CONFIG_I2C_MCF_GPIO_SDA_PC13 \
+				   PC14 CONFIG_I2C_MCF_GPIO_SDA_PC14 \
+				   PC15 CONFIG_I2C_MCF_GPIO_SDA_PC15" PA0
+	    choice 'SCL GPIO pin' "PA0 CONFIG_I2C_MCF_GPIO_SCL_PA0 \
+				   PA1 CONFIG_I2C_MCF_GPIO_SCL_PA1 \
+				   PA2 CONFIG_I2C_MCF_GPIO_SCL_PA2 \
+				   PA3 CONFIG_I2C_MCF_GPIO_SCL_PA3 \
+				   PA4 CONFIG_I2C_MCF_GPIO_SCL_PA4 \
+				   PA5 CONFIG_I2C_MCF_GPIO_SCL_PA5 \
+				   PA6 CONFIG_I2C_MCF_GPIO_SCL_PA6 \
+				   PA7 CONFIG_I2C_MCF_GPIO_SCL_PA7 \
+				   PA8 CONFIG_I2C_MCF_GPIO_SCL_PA8 \
+				   PA9 CONFIG_I2C_MCF_GPIO_SCL_PA9 \
+				   PA10 CONFIG_I2C_MCF_GPIO_SCL_PA10 \
+				   PA11 CONFIG_I2C_MCF_GPIO_SCL_PA11 \
+				   PA12 CONFIG_I2C_MCF_GPIO_SCL_PA12 \
+				   PA13 CONFIG_I2C_MCF_GPIO_SCL_PA13 \
+				   PA14 CONFIG_I2C_MCF_GPIO_SCL_PA14 \
+				   PA15 CONFIG_I2C_MCF_GPIO_SCL_PA15 \
+				   PB0 CONFIG_I2C_MCF_GPIO_SCL_PB0 \
+				   PB1 CONFIG_I2C_MCF_GPIO_SCL_PB1 \
+				   PB2 CONFIG_I2C_MCF_GPIO_SCL_PB2 \
+				   PB3 CONFIG_I2C_MCF_GPIO_SCL_PB3 \
+				   PB4 CONFIG_I2C_MCF_GPIO_SCL_PB4 \
+				   PB5 CONFIG_I2C_MCF_GPIO_SCL_PB5 \
+				   PB6 CONFIG_I2C_MCF_GPIO_SCL_PB6 \
+				   PB7 CONFIG_I2C_MCF_GPIO_SCL_PB7 \
+				   PB8 CONFIG_I2C_MCF_GPIO_SCL_PB8 \
+				   PB9 CONFIG_I2C_MCF_GPIO_SCL_PB9 \
+				   PB10 CONFIG_I2C_MCF_GPIO_SCL_PB10 \
+				   PB11 CONFIG_I2C_MCF_GPIO_SCL_PB11 \
+				   PB12 CONFIG_I2C_MCF_GPIO_SCL_PB12 \
+				   PB13 CONFIG_I2C_MCF_GPIO_SCL_PB13 \
+				   PB14 CONFIG_I2C_MCF_GPIO_SCL_PB14 \
+				   PB15 CONFIG_I2C_MCF_GPIO_SCL_PB15 \
+				   PC0 CONFIG_I2C_MCF_GPIO_SCL_PC0 \
+				   PC1 CONFIG_I2C_MCF_GPIO_SCL_PC1 \
+				   PC2 CONFIG_I2C_MCF_GPIO_SCL_PC2 \
+				   PC3 CONFIG_I2C_MCF_GPIO_SCL_PC3 \
+				   PC4 CONFIG_I2C_MCF_GPIO_SCL_PC4 \
+				   PC5 CONFIG_I2C_MCF_GPIO_SCL_PC5 \
+				   PC6 CONFIG_I2C_MCF_GPIO_SCL_PC6 \
+				   PC7 CONFIG_I2C_MCF_GPIO_SCL_PC7 \
+				   PC8 CONFIG_I2C_MCF_GPIO_SCL_PC8 \
+				   PC9 CONFIG_I2C_MCF_GPIO_SCL_PC9 \
+				   PC10 CONFIG_I2C_MCF_GPIO_SCL_PC10 \
+				   PC11 CONFIG_I2C_MCF_GPIO_SCL_PC11 \
+				   PC12 CONFIG_I2C_MCF_GPIO_SCL_PC12 \
+				   PC13 CONFIG_I2C_MCF_GPIO_SCL_PC13 \
+				   PC14 CONFIG_I2C_MCF_GPIO_SCL_PC14 \
+				   PC15 CONFIG_I2C_MCF_GPIO_SCL_PC15" PA1
+	 fi
+	 if [ "$CONFIG_M5307" = "y" -o "$CONFIG_M5407" = "y" ]; then
+	    comment 'M5307 and M5407 GPIO support'
+	    choice 'SDA GPIO pin' "PP0 CONFIG_I2C_MCF_GPIO_SDA_PP0 \
+				   PP1 CONFIG_I2C_MCF_GPIO_SDA_PP1 \
+				   PP2 CONFIG_I2C_MCF_GPIO_SDA_PP2 \
+				   PP3 CONFIG_I2C_MCF_GPIO_SDA_PP3 \
+				   PP4 CONFIG_I2C_MCF_GPIO_SDA_PP4 \
+				   PP5 CONFIG_I2C_MCF_GPIO_SDA_PP5 \
+				   PP6 CONFIG_I2C_MCF_GPIO_SDA_PP6 \
+				   PP7 CONFIG_I2C_MCF_GPIO_SDA_PP7 \
+				   PP8 CONFIG_I2C_MCF_GPIO_SDA_PP8 \
+				   PP9 CONFIG_I2C_MCF_GPIO_SDA_PP9 \
+				   PP10 CONFIG_I2C_MCF_GPIO_SDA_PP10 \
+				   PP11 CONFIG_I2C_MCF_GPIO_SDA_PP11 \
+				   PP12 CONFIG_I2C_MCF_GPIO_SDA_PP12 \
+				   PP13 CONFIG_I2C_MCF_GPIO_SDA_PP13 \
+				   PP14 CONFIG_I2C_MCF_GPIO_SDA_PP14 \
+				   PP15 CONFIG_I2C_MCF_GPIO_SDA_PP15" PP0
+	    choice 'SCL GPIO pin' "PP0 CONFIG_I2C_MCF_GPIO_SCL_PP0 \
+				   PP1 CONFIG_I2C_MCF_GPIO_SCL_PP1 \
+				   PP2 CONFIG_I2C_MCF_GPIO_SCL_PP2 \
+				   PP3 CONFIG_I2C_MCF_GPIO_SCL_PP3 \
+				   PP4 CONFIG_I2C_MCF_GPIO_SCL_PP4 \
+				   PP5 CONFIG_I2C_MCF_GPIO_SCL_PP5 \
+				   PP6 CONFIG_I2C_MCF_GPIO_SCL_PP6 \
+				   PP7 CONFIG_I2C_MCF_GPIO_SCL_PP7 \
+				   PP8 CONFIG_I2C_MCF_GPIO_SCL_PP8 \
+				   PP9 CONFIG_I2C_MCF_GPIO_SCL_PP9 \
+				   PP10 CONFIG_I2C_MCF_GPIO_SCL_PP10 \
+				   PP11 CONFIG_I2C_MCF_GPIO_SCL_PP11 \
+				   PP12 CONFIG_I2C_MCF_GPIO_SCL_PP12 \
+				   PP13 CONFIG_I2C_MCF_GPIO_SCL_PP13 \
+				   PP14 CONFIG_I2C_MCF_GPIO_SCL_PP14 \
+				   PP15 CONFIG_I2C_MCF_GPIO_SCL_PP15" PP1
+	 fi
+         if [ "$CONFIG_M5282" = "y" -o "$CONFIG_M5280" = "y" ]; then
+            comment 'MCF5282/MCF5280 GPIO I2C not currently supported'
+         fi
+      fi
       dep_tristate '  Velleman K8000 adapter' CONFIG_I2C_VELLEMAN $CONFIG_I2C_ALGOBIT
       dep_tristate '  NatSemi SCx200 I2C using GPIO pins' CONFIG_SCx200_I2C $CONFIG_SCx200_GPIO $CONFIG_I2C_ALGOBIT
       if [ "$CONFIG_SCx200_I2C" != "n" ]; then
          int  '    GPIO pin used for SCL' CONFIG_SCx200_I2C_SCL 12
          int  '    GPIO pin used for SDA' CONFIG_SCx200_I2C_SDA 13
       fi
+      dep_tristate '  NatSemi SCx200 ACCESS.bus' CONFIG_SCx200_ACB $CONFIG_I2C
+      dep_tristate '  NetSilicon NetARM GPIO adapter (EXPERIMENTAL)' CONFIG_I2C_NETARM_GPIO $CONFIG_I2C_ALGOBIT $CONFIG_ARCH_NETARM $CONFIG_EXPERIMENTAL
+      if [ "$CONFIG_I2C_NETARM_GPIO" != "n" ]; then
+        if [ "$CONFIG_NETARM_NS7520" = "y" ]; then
+          comment 'NS7520 GPIO support'
+          choice 'SDA GPIO pin' "PORTA0 CONFIG_I2C_NETARM_GPIO_SDA_PORTA0 \
+				   PORTA1 CONFIG_I2C_NETARM_GPIO_SDA_PORTA1 \
+				   PORTA2 CONFIG_I2C_NETARM_GPIO_SDA_PORTA2 \
+				   PORTA3 CONFIG_I2C_NETARM_GPIO_SDA_PORTA3 \
+				   PORTA4 CONFIG_I2C_NETARM_GPIO_SDA_PORTA4 \
+				   PORTA5 CONFIG_I2C_NETARM_GPIO_SDA_PORTA5 \
+				   PORTA6 CONFIG_I2C_NETARM_GPIO_SDA_PORTA6 \
+				   PORTA7 CONFIG_I2C_NETARM_GPIO_SDA_PORTA7 \
+				   PORTC0 CONFIG_I2C_NETARM_GPIO_SDA_PORTC0 \
+				   PORTC1 CONFIG_I2C_NETARM_GPIO_SDA_PORTC1 \
+				   PORTC2 CONFIG_I2C_NETARM_GPIO_SDA_PORTC2 \
+				   PORTC3 CONFIG_I2C_NETARM_GPIO_SDA_PORTC3 \
+				   PORTC4 CONFIG_I2C_NETARM_GPIO_SDA_PORTC4 \
+				   PORTC5 CONFIG_I2C_NETARM_GPIO_SDA_PORTC5 \
+				   PORTC6 CONFIG_I2C_NETARM_GPIO_SDA_PORTC6 \
+				   PORTC7 CONFIG_I2C_NETARM_GPIO_SDA_PORTC7" PORTA0
+   	    choice 'SCL GPIO pin' "PORTA0 CONFIG_I2C_NETARM_GPIO_SCL_PORTA0 \
+				   PORTA1 CONFIG_I2C_NETARM_GPIO_SCL_PORTA1 \
+				   PORTA2 CONFIG_I2C_NETARM_GPIO_SCL_PORTA2 \
+				   PORTA3 CONFIG_I2C_NETARM_GPIO_SCL_PORTA3 \
+				   PORTA4 CONFIG_I2C_NETARM_GPIO_SCL_PORTA4 \
+				   PORTA5 CONFIG_I2C_NETARM_GPIO_SCL_PORTA5 \
+				   PORTA6 CONFIG_I2C_NETARM_GPIO_SCL_PORTA6 \
+				   PORTA7 CONFIG_I2C_NETARM_GPIO_SCL_PORTA7 \
+				   PORTC0 CONFIG_I2C_NETARM_GPIO_SCL_PORTC0 \
+				   PORTC1 CONFIG_I2C_NETARM_GPIO_SCL_PORTC1 \
+				   PORTC2 CONFIG_I2C_NETARM_GPIO_SCL_PORTC2 \
+				   PORTC3 CONFIG_I2C_NETARM_GPIO_SCL_PORTC3 \
+				   PORTC4 CONFIG_I2C_NETARM_GPIO_SCL_PORTC4 \
+				   PORTC5 CONFIG_I2C_NETARM_GPIO_SCL_PORTC5 \
+				   PORTC6 CONFIG_I2C_NETARM_GPIO_SCL_PORTC6 \
+				   PORTC7 CONFIG_I2C_NETARM_GPIO_SCL_PORTC7" PORTA1
+         else
+          comment 'NET+ARM 15, 20, 40, 50 GPIO support'
+          choice 'SDA GPIO pin' "PORTA0 CONFIG_I2C_NETARM_GPIO_SDA_PORTA0 \
+				   PORTA1 CONFIG_I2C_NETARM_GPIO_SDA_PORTA1 \
+				   PORTA2 CONFIG_I2C_NETARM_GPIO_SDA_PORTA2 \
+				   PORTA3 CONFIG_I2C_NETARM_GPIO_SDA_PORTA3 \
+				   PORTA4 CONFIG_I2C_NETARM_GPIO_SDA_PORTA4 \
+				   PORTA5 CONFIG_I2C_NETARM_GPIO_SDA_PORTA5 \
+				   PORTA6 CONFIG_I2C_NETARM_GPIO_SDA_PORTA6 \
+				   PORTA7 CONFIG_I2C_NETARM_GPIO_SDA_PORTA7 \
+				   PORTB0 CONFIG_I2C_NETARM_GPIO_SDA_PORTB0 \
+				   PORTB1 CONFIG_I2C_NETARM_GPIO_SDA_PORTB1 \
+				   PORTB2 CONFIG_I2C_NETARM_GPIO_SDA_PORTB2 \
+				   PORTB3 CONFIG_I2C_NETARM_GPIO_SDA_PORTB3 \
+				   PORTB4 CONFIG_I2C_NETARM_GPIO_SDA_PORTB4 \
+				   PORTB5 CONFIG_I2C_NETARM_GPIO_SDA_PORTB5 \
+				   PORTB6 CONFIG_I2C_NETARM_GPIO_SDA_PORTB6 \
+				   PORTB7 CONFIG_I2C_NETARM_GPIO_SDA_PORTB7 \
+				   PORTC0 CONFIG_I2C_NETARM_GPIO_SDA_PORTC0 \
+				   PORTC1 CONFIG_I2C_NETARM_GPIO_SDA_PORTC1 \
+				   PORTC2 CONFIG_I2C_NETARM_GPIO_SDA_PORTC2 \
+				   PORTC3 CONFIG_I2C_NETARM_GPIO_SDA_PORTC3 \
+				   PORTC4 CONFIG_I2C_NETARM_GPIO_SDA_PORTC4 \
+				   PORTC5 CONFIG_I2C_NETARM_GPIO_SDA_PORTC5 \
+				   PORTC6 CONFIG_I2C_NETARM_GPIO_SDA_PORTC6 \
+				   PORTC7 CONFIG_I2C_NETARM_GPIO_SDA_PORTC7" PORTA0
+   	    choice 'SCL GPIO pin' "PORTA0 CONFIG_I2C_NETARM_GPIO_SCL_PORTA0 \
+				   PORTA1 CONFIG_I2C_NETARM_GPIO_SCL_PORTA1 \
+				   PORTA2 CONFIG_I2C_NETARM_GPIO_SCL_PORTA2 \
+				   PORTA3 CONFIG_I2C_NETARM_GPIO_SCL_PORTA3 \
+				   PORTA4 CONFIG_I2C_NETARM_GPIO_SCL_PORTA4 \
+				   PORTA5 CONFIG_I2C_NETARM_GPIO_SCL_PORTA5 \
+				   PORTA6 CONFIG_I2C_NETARM_GPIO_SCL_PORTA6 \
+				   PORTA7 CONFIG_I2C_NETARM_GPIO_SCL_PORTA7 \
+				   PORTB0 CONFIG_I2C_NETARM_GPIO_SCL_PORTB0 \
+				   PORTB1 CONFIG_I2C_NETARM_GPIO_SCL_PORTB1 \
+				   PORTB2 CONFIG_I2C_NETARM_GPIO_SCL_PORTB2 \
+				   PORTB3 CONFIG_I2C_NETARM_GPIO_SCL_PORTB3 \
+				   PORTB4 CONFIG_I2C_NETARM_GPIO_SCL_PORTB4 \
+				   PORTB5 CONFIG_I2C_NETARM_GPIO_SCL_PORTB5 \
+				   PORTB6 CONFIG_I2C_NETARM_GPIO_SCL_PORTB6 \
+				   PORTB7 CONFIG_I2C_NETARM_GPIO_SCL_PORTB7 \
+				   PORTC0 CONFIG_I2C_NETARM_GPIO_SCL_PORTC0 \
+				   PORTC1 CONFIG_I2C_NETARM_GPIO_SCL_PORTC1 \
+				   PORTC2 CONFIG_I2C_NETARM_GPIO_SCL_PORTC2 \
+				   PORTC3 CONFIG_I2C_NETARM_GPIO_SCL_PORTC3 \
+				   PORTC4 CONFIG_I2C_NETARM_GPIO_SCL_PORTC4 \
+				   PORTC5 CONFIG_I2C_NETARM_GPIO_SCL_PORTC5 \
+				   PORTC6 CONFIG_I2C_NETARM_GPIO_SCL_PORTC6 \
+				   PORTC7 CONFIG_I2C_NETARM_GPIO_SCL_PORTC7" PORTA1
+         fi
+      fi
    fi
 
-   dep_tristate 'NatSemi SCx200 ACCESS.bus' CONFIG_SCx200_ACB $CONFIG_I2C
-
    dep_tristate 'I2C PCF 8584 interfaces' CONFIG_I2C_ALGOPCF $CONFIG_I2C
    if [ "$CONFIG_I2C_ALGOPCF" != "n" ]; then
       dep_tristate '  Elektor ISA card' CONFIG_I2C_ELEKTOR $CONFIG_I2C_ALGOPCF
@@ -45,10 +390,16 @@
       fi
    fi
 
+   dep_tristate 'Xilinx on-chip I2C' CONFIG_I2C_XILINX $CONFIG_I2C
+
    if [ "$CONFIG_ALL_PPC" = "y" ] ; then
       dep_tristate 'Keywest I2C interface in Apple Core99 machines' CONFIG_I2C_KEYWEST $CONFIG_I2C
    fi
 
+   if [ "$CONFIG_ARCH_AT91RM9200" = "y" ] ; then
+      dep_tristate 'Atmel AT91RM9200 I2C Two-Wire interface (TWI)' CONFIG_I2C_AT91 $CONFIG_I2C
+   fi
+
    if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then
       dep_tristate 'SiByte SMBus interface' CONFIG_I2C_ALGO_SIBYTE $CONFIG_I2C
       dep_tristate '  MAX1617 Temperature Sensor' CONFIG_I2C_MAX1617 $CONFIG_I2C_ALGO_SIBYTE
diff -urN linux-2.4.29/drivers/i2c/i2c-adap-ixdp2400.c linux-2.4.29-uc1/drivers/i2c/i2c-adap-ixdp2400.c
--- linux-2.4.29/drivers/i2c/i2c-adap-ixdp2400.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/i2c-adap-ixdp2400.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,183 @@
+/*
+ * drivers/i2c/i2c-ixdp2400.c
+ *
+ * I2C adapter for IXP2000 systems with IXDP2400 style I2C bus
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ * Based on code by: Naeem M. Afzal <naeem.m.afzal@intel.com>
+ *
+ * Copyright 2003 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ * I2C adapter driver for IXDP2400 reference platform. This could
+ * be a generic IXP2000 driver, but the IXDP2400 uses the HW GPIO
+ * in a very board specific manner to create an I2C bus. If you copy
+ * the exact same setup, you can use this driver for your board.
+ *
+ * GPIO2 is pulled high and connected to both I2C lines.
+ *
+ * GPIO6 and GPIO7 are used for SDA and SCL respectively and
+ * are both set to 0.
+ *
+ * To drive a line high on the bus, that that GPIO is set to an output.
+ * This causes the GPIO pin to float and so the bus sees a logic 1.
+ *
+ * To drive a line low on the bus, that GPIO is set to an input
+ * and we pull down the line.
+ *
+ * (This is my understanding of it.  I'm not a HW person and don't have
+ *  the schematics in front of me, but this seems to make sense from
+ *  the original Intel driver).
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <asm/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/init.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+/*
+ * In case other boards use the same setup, this will make it
+ * easier to support multiple boards without tons of 
+ * #ifdef's or machine_is_xxx() calls. Just fill in the ixdp2400_gpio
+ * with the appropriate GPIO information.
+ */
+static struct ixdp2400_data {
+	unsigned short sda_gpio;
+	unsigned short scl_gpio;
+} ixdp2400_gpio;
+
+static void ixdp2400_bit_setscl(void *data, int val)
+{
+	struct ixdp2400_data *gpio = (struct ixdp2400_data*)data; 
+	int i = 5000;
+
+	if(val) {
+		gpio_line_config(gpio->scl_gpio, GPIO_IN);
+		while(!gpio_line_get(gpio->scl_gpio) && i--);
+	} else {
+		gpio_line_config(gpio->scl_gpio, GPIO_OUT);
+	}
+}
+
+static void ixdp2400_bit_setsda(void *data, int val)
+{
+	struct ixdp2400_data *gpio = (struct ixdp2400_data*)data;
+
+	if(val) {
+		gpio_line_config(gpio->sda_gpio, GPIO_IN);
+	} else {
+		gpio_line_config(gpio->sda_gpio, GPIO_OUT);
+	}
+
+//	printk("SDA %d PDPR = %#010x\n", val, *IXP2000_GPIO_PDPR);
+}
+
+static int ixdp2400_bit_getscl(void *data)
+{
+	struct ixdp2400_data *gpio = (struct ixdp2400_data*)data;
+	int ret;
+
+	ret = gpio_line_get(gpio->scl_gpio);
+
+	return ret;
+}
+
+static int ixdp2400_bit_getsda(void *data)
+{
+	struct ixdp2400_data *gpio = (struct ixdp2400_data*)data;
+	int ret;
+
+	ret = gpio_line_get(gpio->sda_gpio);
+
+	return ret;
+}
+
+void ixdp2400_i2c_inc(struct i2c_adapter *adapter)
+{
+	MOD_INC_USE_COUNT;
+}
+
+void ixdp2400_i2c_dec(struct i2c_adapter *adapter)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+/*
+ * If you board provides multiple I2C channels, just
+ * make copies of this and change the gpio information.
+ */
+static struct i2c_algo_bit_data ixdp2400_bit_data = {
+	.data =		&ixdp2400_gpio,
+	.setsda =	ixdp2400_bit_setsda,
+	.setscl =	ixdp2400_bit_setscl,
+	.getsda =	ixdp2400_bit_getsda,
+	.getscl =	ixdp2400_bit_getscl,
+	.udelay = 	6,
+	.mdelay =	6,
+	.timeout = 	100
+};
+
+static struct i2c_adapter ixdp2400_i2c_adapter = {
+	.name =		"IXDP2400-style GPIO I2C Adapter",
+	.id =		I2C_HW_B_IXDP2400,
+	.algo =		NULL,
+	.algo_data =	&ixdp2400_bit_data,
+	.inc_use =	ixdp2400_i2c_inc,
+	.dec_use = 	ixdp2400_i2c_dec
+};
+
+static int __init ixdp2400_i2c_init(void)
+{
+	if(machine_is_ixdp2400()) {
+		int i = 0;
+
+		/*
+		 * GPIO2 needs to be high for SDA to work on this board
+		 */
+		gpio_line_set(IXDP2400_GPIO_HIGH, 1);
+		gpio_line_config(IXDP2400_GPIO_HIGH, GPIO_OUT);
+
+		ixdp2400_gpio.sda_gpio = IXDP2400_GPIO_SCL;
+		ixdp2400_gpio.scl_gpio = IXDP2400_GPIO_SDA;
+
+		gpio_line_config(ixdp2400_gpio.sda_gpio, GPIO_OUT);
+		gpio_line_config(ixdp2400_gpio.scl_gpio, GPIO_OUT);
+
+		gpio_line_set(ixdp2400_gpio.scl_gpio, 0);
+		gpio_line_set(ixdp2400_gpio.sda_gpio, 0);
+
+		gpio_line_config(ixdp2400_gpio.scl_gpio, GPIO_IN);
+
+		for(i = 0; i < 10; i++);
+
+		gpio_line_config(ixdp2400_gpio.sda_gpio, GPIO_IN);
+	}
+
+	if (i2c_bit_add_bus(&ixdp2400_i2c_adapter)) {
+		printk("i2c-ixdp2400: I2C adapter registration failed\n");
+		return -EIO;
+	} else printk("i2c-ixdp2400: I2C bus initialized\n");
+
+	return 0;
+}
+
+static void __exit ixdp2400_i2c_exit(void)
+{
+	i2c_bit_del_bus(&ixdp2400_i2c_adapter);
+}
+
+EXPORT_NO_SYMBOLS;
+MODULE_AUTHOR ("Deepak Saxena <dsaxena@mvista.com>");
+MODULE_DESCRIPTION("IXDP2400 I2C bus driver");
+MODULE_LICENSE("GPL");
+
+module_init(ixdp2400_i2c_init);
+module_exit(ixdp2400_i2c_exit);
diff -urN linux-2.4.29/drivers/i2c/i2c-adap-ixp2000.c linux-2.4.29-uc1/drivers/i2c/i2c-adap-ixp2000.c
--- linux-2.4.29/drivers/i2c/i2c-adap-ixp2000.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/i2c-adap-ixp2000.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,179 @@
+/*
+ * drivers/i2c/i2c-adap-ixp2000.c
+ *
+ * I2C adapter for IXP2000 systems using GPIOs for I2C bus
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ * Based on code by: Naeem M. Afzal <naeem.m.afzal@intel.com>
+ * Made generic by: Jeff Daly <jeffrey.daly@intel.com>
+ *
+ * Copyright (c) 2003 MontaVista Software Inc.
+ *
+ * This file is licensed under  the terms of the GNU General Public 
+ * License version 2. This program is licensed "as is" without any 
+ * warranty of any kind, whether express or implied.
+ *
+ * I2C adapter driver for IXP2000 platform. This should 
+ * be a generic IXP2000 driver, if you use the HW GPIO in the same manner.
+ * Basically, SDA and SCL GPIOs have external pullups.  Setting the respective
+ * GPIO to an input will make the signal a '1' via the pullup.  Setting them
+ * to outputs will pull them down.
+ *
+ * The GPIOs are open drain signals and are used as configuration strap inputs
+ * during power-up so there's generally a buffer on the board that needs to be 
+ * 'enabled' to drive the GPIOs.
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <asm/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/init.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+
+/*
+ * Init code fills this in at run time with board-specific data.
+ */
+static struct ixp2000_data {
+	unsigned short sda_gpio;
+	unsigned short scl_gpio;
+} ixp2000_gpio;
+
+static void ixp2000_bit_setscl(void *data, int val)
+{
+	struct ixp2000_data *gpio = (struct ixp2000_data*)data; 
+	int i = 5000;
+
+	if(val) {
+		gpio_line_config(gpio->scl_gpio, GPIO_IN);
+		while(!gpio_line_get(gpio->scl_gpio) && i--);
+	} else {
+		gpio_line_config(gpio->scl_gpio, GPIO_OUT);
+	}
+}
+
+static void ixp2000_bit_setsda(void *data, int val)
+{
+	struct ixp2000_data *gpio = (struct ixp2000_data*)data;
+
+	if(val) {
+		gpio_line_config(gpio->sda_gpio, GPIO_IN);
+	} else {
+		gpio_line_config(gpio->sda_gpio, GPIO_OUT);
+	}
+}
+
+static int ixp2000_bit_getscl(void *data)
+{
+	struct ixp2000_data *gpio = (struct ixp2000_data*)data;
+	int ret;
+
+	ret = gpio_line_get(gpio->scl_gpio);
+
+	return ret;
+}
+
+static int ixp2000_bit_getsda(void *data)
+{
+	struct ixp2000_data *gpio = (struct ixp2000_data*)data;
+	int ret;
+
+	ret = gpio_line_get(gpio->sda_gpio);
+
+	return ret;
+}
+
+void ixp2000_i2c_inc(struct i2c_adapter *adapter)
+{
+	MOD_INC_USE_COUNT;
+}
+
+void ixp2000_i2c_dec(struct i2c_adapter *adapter)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+/*
+ * If you board provides multiple I2C channels, just
+ * make copies of this and change the gpio information.
+ */
+static struct i2c_algo_bit_data ixp2000_bit_data = {
+	.data =		&ixp2000_gpio,
+	.setsda =	ixp2000_bit_setsda,
+	.setscl =	ixp2000_bit_setscl,
+	.getsda =	ixp2000_bit_getsda,
+	.getscl =	ixp2000_bit_getscl,
+	.udelay = 	6,
+	.mdelay =	6,
+	.timeout = 	100
+};
+
+static struct i2c_adapter ixp2000_i2c_adapter = {
+	.name =		"IXP2000-style GPIO I2C Adapter",
+	.id =		I2C_HW_B_IXP2000,
+	.algo =		NULL,
+	.algo_data =	&ixp2000_bit_data,
+	.inc_use =	ixp2000_i2c_inc,
+	.dec_use = 	ixp2000_i2c_dec
+};
+
+static int __init ixp2000_i2c_init(void)
+{
+	int i = 0;
+
+#ifdef CONFIG_ARCH_IXDP2400
+	if(machine_is_ixdp2400()) {
+
+		gpio_line_set(IXDP2400_GPIO_I2C_ENABLE, 1);
+		gpio_line_config(IXDP2400_GPIO_I2C_ENABLE, GPIO_OUT);
+
+		ixp2000_gpio.sda_gpio = IXDP2400_GPIO_SDA;
+		ixp2000_gpio.scl_gpio = IXDP2400_GPIO_SCL;
+	}
+#endif
+#ifdef CONFIG_ARCH_IXDP2800
+	if(machine_is_ixdp2800()) {
+
+		gpio_line_set(IXDP2800_GPIO_I2C_ENABLE, 1);
+		gpio_line_config(IXDP2800_GPIO_I2C_ENABLE, GPIO_OUT);
+
+		ixp2000_gpio.sda_gpio = IXDP2800_GPIO_SDA;
+		ixp2000_gpio.scl_gpio = IXDP2800_GPIO_SCL;
+	}
+#endif
+
+	gpio_line_config(ixp2000_gpio.sda_gpio, GPIO_OUT);
+	gpio_line_config(ixp2000_gpio.scl_gpio, GPIO_OUT);
+
+	gpio_line_set(ixp2000_gpio.scl_gpio, 0);
+	gpio_line_set(ixp2000_gpio.sda_gpio, 0);
+
+	gpio_line_config(ixp2000_gpio.scl_gpio, GPIO_IN);
+
+	for(i = 0; i < 10; i++);
+
+	gpio_line_config(ixp2000_gpio.sda_gpio, GPIO_IN);
+
+	if (i2c_bit_add_bus(&ixp2000_i2c_adapter)) {
+		printk("i2c-adap-ixp2000: I2C adapter registration failed\n");
+		return -EIO;
+	} else printk("i2c-adap-ixp2000: I2C bus initialized\n");
+
+	return 0;
+}
+
+static void __exit ixp2000_i2c_exit(void)
+{
+	i2c_bit_del_bus(&ixp2000_i2c_adapter);
+}
+
+EXPORT_NO_SYMBOLS;
+MODULE_AUTHOR ("Deepak Saxena <dsaxena@mvista.com>");
+MODULE_DESCRIPTION("IXP2000 GPIO-based I2C bus driver");
+MODULE_LICENSE("GPL");
+
+module_init(ixp2000_i2c_init);
+module_exit(ixp2000_i2c_exit);
diff -urN linux-2.4.29/drivers/i2c/i2c-adap-ixp425.c linux-2.4.29-uc1/drivers/i2c/i2c-adap-ixp425.c
--- linux-2.4.29/drivers/i2c/i2c-adap-ixp425.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/i2c-adap-ixp425.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,146 @@
+/*
+ * drivers/i2c/i2c-adap-ixp425.c
+ *
+ * Driver for gpio-based i2c adapter on IXP425 systems.
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Based on original Intel driver by Teodor Mihai <teodor.mihai@intel.com>
+ *
+ * TODO: fix GPIO interface so that _get just returns value instead
+ *       of taking ptr
+ *
+ * Copyright 2003 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/i2c-id.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+static struct ixp425_i2c_data {
+	unsigned int sda_line;
+	unsigned int scl_line;
+} gpio_data;
+
+static inline int ixp425_scl_line(void *data)
+{
+	return ((struct ixp425_i2c_data*)data)->scl_line;
+}
+
+static inline int ixp425_sda_line(void *data)
+{
+	return ((struct ixp425_i2c_data*)data)->sda_line;
+}
+
+static void ixdp425_bit_setscl(void *data, int val)
+{
+	gpio_line_set(ixp425_scl_line(data), 0);
+	gpio_line_config(ixp425_scl_line(data),
+		val ? IXP425_GPIO_IN : IXP425_GPIO_OUT );
+}
+
+static void ixdp425_bit_setsda(void *data, int val)
+{
+	gpio_line_set(ixp425_sda_line(data), 0);
+	gpio_line_config(ixp425_sda_line(data),
+		val ? IXP425_GPIO_IN : IXP425_GPIO_OUT );
+}
+
+static int ixdp425_bit_getscl(void *data)
+{
+	int scl;
+
+	gpio_line_config(ixp425_scl_line(data), IXP425_GPIO_IN );
+	gpio_line_get(ixp425_scl_line(data), &scl);
+
+	return scl;
+}	
+
+static int ixdp425_bit_getsda(void *data)
+{
+	int sda;
+
+	gpio_line_config(ixp425_sda_line(data), IXP425_GPIO_IN );
+	gpio_line_get(ixp425_sda_line(data), &sda);
+
+	return sda;
+}	
+
+static void ixp425_i2c_inc_use(struct i2c_adapter *adap)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void ixp425_i2c_dec_use(struct i2c_adapter *adap)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+struct i2c_algo_bit_data ixdp425_bit_data = {
+	.data		= &gpio_data,
+	.setsda		= ixdp425_bit_setsda,
+	.setscl		= ixdp425_bit_setscl,
+	.getsda		= ixdp425_bit_getsda,
+	.getscl		= ixdp425_bit_getscl,
+	.udelay		= 10,
+	.mdelay		= 10,
+	.timeout	= 100
+};
+
+struct i2c_adapter ixp425_i2c_adapter = {
+	.name 		= "IXP425 I2C Adapter",
+	.id		= I2C_HW_B_IXP425,
+	.algo_data	= &ixdp425_bit_data,
+	.inc_use	= ixp425_i2c_inc_use,
+	.dec_use	= ixp425_i2c_dec_use,
+};
+
+int __init ixp425_i2c_init(void)
+{
+	int res;
+
+	if(machine_is_ixdp425()) {
+		gpio_data.scl_line = IXP425_GPIO_PIN_6;
+		gpio_data.sda_line = IXP425_GPIO_PIN_7;
+	} else {
+		printk(KERN_WARNING 
+			"Unknown IXP425 platform: No I2C support available\n");
+		return -EIO;
+	}
+
+	gpio_line_config(gpio_data.scl_line, IXP425_GPIO_IN);
+	gpio_line_config(gpio_data.sda_line, IXP425_GPIO_IN);
+	gpio_line_set(gpio_data.scl_line, 0);
+	gpio_line_set(gpio_data.sda_line, 0);
+
+	if ((res = i2c_bit_add_bus(&ixp425_i2c_adapter) != 0)) {
+		printk(KERN_ERR "ERROR: Could not install IXP425 I2C adapter\n");
+		return res;
+	}
+
+	return 0;
+}
+
+void __exit ixp425_i2c_exit(void)
+{
+	i2c_bit_del_bus(&ixp425_i2c_adapter);
+}
+
+module_init(ixp425_i2c_init);
+module_exit(ixp425_i2c_exit);
+
+MODULE_DESCRIPTION("GPIO-based I2C adapter for IXP425 systems");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Deepak Saxena<dsaxena@mvista.com>");
+
diff -urN linux-2.4.29/drivers/i2c/i2c-adap-mcf_gpio.c linux-2.4.29-uc1/drivers/i2c/i2c-adap-mcf_gpio.c
--- linux-2.4.29/drivers/i2c/i2c-adap-mcf_gpio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/i2c-adap-mcf_gpio.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,1258 @@
+/* vim:set ts=8 sw=8 et: */
+/* ----------------------------------------------------------------------------
+ * i2c-adap-mcf_gpio.c i2c-hw access using Motorola Coldfire GPIO
+ *
+ * ----------------------------------------------------------------------------
+ * Cory T. Tusar, Videon Central, Inc.
+ * <ctusar@videon-central.com>
+ *
+ * Copyright (C) 2003, 2004 Videon Central, Inc.
+ *
+ * ----------------------------------------------------------------------------
+ * This driver supports using a pair of GPIO pins on the Motorola Coldfire
+ * series of microcontrollers as an I2C adapter.
+ *
+ * Currently, this driver supports the MCF5204, MCF5206, MCF5206e, MCF5249,
+ * MCF5272, MCF5307, and MCF5407 processors.  The MCF5282 is not currently
+ * supported.
+ *
+ * This driver has only undergone basic testing on MCF5272 hardware.  Please be
+ * aware that issues may be present when attempting to use this driver with
+ * untested processors.
+ *
+ * ----------------------------------------------------------------------------
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* $Id: i2c-adap-mcf_gpio.c,v 1.1 2003/08/28 01:16:03 gerg Exp $ */
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+/*
+ * Coldfire register offsets, etc.
+ * I see no asm/m5204sim.h in the current uClinux tree, but asm/m5206sim.h
+ * should work fine for the few registers we need to access.
+ */
+#include <asm/coldfire.h>
+#if defined(CONFIG_M5204)
+#include <asm/m5206sim.h>
+#elif (defined(CONFIG_M5206) || defined(CONFIG_M5206e))
+#include <asm/m5206sim.h>
+#elif defined(CONFIG_M5249)
+#include <asm/m5249sim.h>
+#elif defined(CONFIG_M5272)
+#include <asm/m5272sim.h>
+#elif (defined(CONFIG_M5282) || defined(CONFIG_M5280))
+#include <asm/m5282sim.h>
+#elif defined(CONFIG_M5307)
+#include <asm/m5307sim.h>
+#elif defined(CONFIG_M5407)
+#include <asm/m5407sim.h>
+#endif  /* CONFIG_M5* */
+
+/* Legacy includes */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0))
+#include <linux/string.h>               /* Provides NULL for 2.0 kernels */
+#include <asm/errno.h>                  /* Provides ENODEV for 2.0 kernels */
+#endif  /* LINUX_VERSION_CODE */
+
+
+/* ----------------------------------------------------------------------------
+ * Compile-time dummy checks to keep things relatively sane
+ */
+#if !defined(CONFIG_COLDFIRE)
+#error "Can't build Coldfire I2C-Bus adapter driver for non-Coldfire processor"
+#endif  /* !defined(CONFIG_COLDFIRE) */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0))
+#warning "This driver has not been tested with kernel versions < 2.4.0"
+#endif  /* LINUX_VERSION_CODE */
+
+
+/* ----------------------------------------------------------------------------
+ * Dig through the myriad of #define's created during configuration to
+ * determine the registers used for controlling SDA and SCL, as well as the
+ * bitmasks needed for pin function setup, data direction toggling, and general
+ * bit-banging of the bus.
+ *
+ * This is kinda kludgey due to the way the configuration 'choice' operator
+ * works.  I'm open to suggestions for improvement.
+ */
+
+/* ----------------------------------------------------------------------------
+ * MCF5204, MCF5206, and MCF5206e driver ports and bitmasks
+ */
+#if (defined(CONFIG_M5204) || defined(CONFIG_M5206) || defined(MCF5206e))
+
+/* Determine SCL line settings based on CONFIG_I2C_MCF_GPIO_SCL_* */
+#define I2C_PORT_SCL_STRING     "PP"
+#define I2C_PORT_SCL_READ       *(volatile u8 *)(MCF_MBAR + MCFSIM_PADAT)
+#define I2C_PORT_SCL_WRITE      *(volatile u8 *)(MCF_MBAR + MCFSIM_PADAT)
+#define I2C_DDR_SCL             *(volatile u8 *)(MCF_MBAR + MCFSIM_PADDR)
+
+#if (defined(CONFIG_M5204) || defined(CONFIG_M5206))
+#define I2C_CNT_SCL             *(volatile u8 *)(MCF_MBAR + MCFSIM_PAR)
+
+#elif defined(CONFIG_M5206e)
+#define I2C_CNT_SCL             *(volatile u16 *)(MCF_MBAR + MCFSIM_PAR)
+#endif  /* CONFIG_M520* */
+
+#if defined(CONFIG_I2C_MCF_GPIO_SCL_PP0)
+#define I2C_BIT_SCL             0
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP1)
+#define I2C_BIT_SCL             1
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP2)
+#define I2C_BIT_SCL             2
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP3)
+#define I2C_BIT_SCL             3
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP4)
+#define I2C_BIT_SCL             4
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP5)
+#define I2C_BIT_SCL             5
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP6)
+#define I2C_BIT_SCL             6
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP7)
+#define I2C_BIT_SCL             7
+
+#else
+#error "CONFIG_I2C_MCF_GPIO_SCL_* is not correctly #define'd!"
+#endif  /* CONFIG_I2C_MCF_GPIO_SCL_* */
+
+
+/* Determine SDA line settings based on CONFIG_I2C_MCF_GPIO_SDA_* */
+#define I2C_PORT_SDA_STRING     "PP"
+#define I2C_PORT_SDA_READ       *(volatile u8 *)(MCF_MBAR + MCFSIM_PADAT)
+#define I2C_PORT_SDA_WRITE      *(volatile u8 *)(MCF_MBAR + MCFSIM_PADAT)
+#define I2C_DDR_SDA             *(volatile u8 *)(MCF_MBAR + MCFSIM_PADDR)
+
+#if (defined(CONFIG_M5204) || defined(CONFIG_M5206))
+#define I2C_CNT_SDA             *(volatile u8 *)(MCF_MBAR + MCFSIM_PAR)
+
+#elif defined(CONFIG_M5206e)
+#define I2C_CNT_SDA             *(volatile u16 *)(MCF_MBAR + MCFSIM_PAR)
+#endif  /* CONFIG_M520* */
+
+#if defined(CONFIG_I2C_MCF_GPIO_SDA_PP0)
+#define I2C_BIT_SDA             0
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP1)
+#define I2C_BIT_SDA             1
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP2)
+#define I2C_BIT_SDA             2
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP3)
+#define I2C_BIT_SDA             3
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP4)
+#define I2C_BIT_SDA             4
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP5)
+#define I2C_BIT_SDA             5
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP6)
+#define I2C_BIT_SDA             6
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP7)
+#define I2C_BIT_SDA             7
+
+#else
+#error "CONFIG_I2C_MCF_GPIO_SDA_* is not correctly #define'd!"
+#endif  /* CONFIG_I2C_MCF_GPIO_SDA_* */
+
+
+/* Bitmasks for SCL and SDA lines */
+#define I2C_MASK_SCL            (1 << I2C_BIT_SCL)
+#define I2C_MASK_SDA            (1 << I2C_BIT_SDA)
+
+#if defined(CONFIG_M5204)
+#define I2C_MASK_CNT_SCL_AND    (~0)
+#define I2C_MASK_CNT_SDA_AND    (~0)
+#define I2C_MASK_CNT_SCL_OR     (1 << I2C_BIT_SCL)
+#define I2C_MASK_CNT_SDA_OR     (1 << I2C_BIT_SDA)
+
+#elif (defined(CONFIG_M5206) || defined(CONFIG_M5206e)
+#define I2C_MASK_CNT_SCL_AND    (~(1 << ((I2C_BIT_SCL > 3) ? 5 : 4)))
+#define I2C_MASK_CNT_SDA_AND    (~(1 << ((I2C_BIT_SDA > 3) ? 5 : 4)))
+#define I2C_MASK_CNT_SCL_OR     (0)
+#define I2C_MASK_CNT_SDA_OR     (0)
+#endif  /* MCF520* */
+
+
+/* ----------------------------------------------------------------------------
+ * MCF5249 driver ports and bitmasks
+ */
+#elif defined(CONFIG_M5249)
+
+/* Determine SCL line settings based on CONFIG_I2C_MCF_GPIO_SCL_* */
+#if (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO0) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO1) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO2) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO3) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO4) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO5) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO6) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO7) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO9) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO10) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO11) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO12) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO13) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO14) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO15) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO16) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO17) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO18) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO19) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO20) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO21) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO22) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO23) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO24) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO25) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO26) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO29))
+#define I2C_PORT_SCL_STRING     "GPIO"
+#define I2C_PORT_SCL_READ       *(volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIOREAD)
+#define I2C_PORT_SCL_WRITE      *(volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIOWRITE)
+#define I2C_DDR_SCL             *(volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIOENABLE)
+#define I2C_CNT_SCL             *(volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIOFUNC)
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO33) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO34) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO44) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO45) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO46) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO48) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO49) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO50) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO51) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO52) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO53) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO54) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO55) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO56) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO57) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO58) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO59) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO60) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO61) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO62))
+#define I2C_PORT_SCL_STRING     "GPIO"
+#define I2C_PORT_SCL_READ       *(volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIO1READ)
+#define I2C_PORT_SCL_WRITE      *(volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIO1WRITE)
+#define I2C_DDR_SCL             *(volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIO1ENABLE)
+#define I2C_CNT_SCL             *(volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIO1FUNC)
+
+#else
+#error "CONFIG_I2C_MCF_GPIO_SCL_* is not correctly #define'd!"
+#endif  /* CONFIG_I2C_MCF_GPIO_SCL_* */
+
+
+#if (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO0) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO32))
+#define I2C_BIT_SCL             0
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO1) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO33))
+#define I2C_BIT_SCL             1
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO2) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO34))
+#define I2C_BIT_SCL             2
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO3) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO35))
+#define I2C_BIT_SCL             3
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO4) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO36))
+#define I2C_BIT_SCL             4
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO5) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO37))
+#define I2C_BIT_SCL             5
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO6) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO38))
+#define I2C_BIT_SCL             6
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO7) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO39))
+#define I2C_BIT_SCL             7
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO8) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO40))
+#define I2C_BIT_SCL             8
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO9) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO41))
+#define I2C_BIT_SCL             9
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO10) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO42))
+#define I2C_BIT_SCL             10
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO11) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO43))
+#define I2C_BIT_SCL             11
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO12) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO44))
+#define I2C_BIT_SCL             12
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO13) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO45))
+#define I2C_BIT_SCL             13
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO14) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO46))
+#define I2C_BIT_SCL             14
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO15) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO47))
+#define I2C_BIT_SCL             15
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO16) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO48))
+#define I2C_BIT_SCL             16
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO17) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO49))
+#define I2C_BIT_SCL             17
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO18) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO50))
+#define I2C_BIT_SCL             18
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO19) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO51))
+#define I2C_BIT_SCL             19
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO20) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO52))
+#define I2C_BIT_SCL             20
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO21) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO53))
+#define I2C_BIT_SCL             21
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO22) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO54))
+#define I2C_BIT_SCL             22
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO23) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO55))
+#define I2C_BIT_SCL             23
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO24) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO56))
+#define I2C_BIT_SCL             24
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO25) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO57))
+#define I2C_BIT_SCL             25
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO26) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO58))
+#define I2C_BIT_SCL             26
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO27) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO59))
+#define I2C_BIT_SCL             27
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO28) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO60))
+#define I2C_BIT_SCL             28
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO29) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO61))
+#define I2C_BIT_SCL             29
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO30) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO62))
+#define I2C_BIT_SCL             30
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO31) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_GPIO63))
+#define I2C_BIT_SCL             31
+
+#else
+#error "CONFIG_I2C_MCF_GPIO_SCL_* is not correctly #define'd!"
+#endif  /* CONFIG_I2C_MCF_GPIO_SCL_* */
+
+
+/* Determine SDA line settings based on CONFIG_I2C_MCF_GPIO_SDA_* */
+#if (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO0) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO1) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO2) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO3) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO4) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO5) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO6) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO7) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO9) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO10) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO11) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO12) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO13) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO14) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO15) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO16) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO17) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO18) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO19) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO20) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO21) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO22) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO23) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO24) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO25) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO26) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO29))
+#define I2C_PORT_SDA_STRING     "GPIO"
+#define I2C_PORT_SDA_READ       *(volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIOREAD)
+#define I2C_PORT_SDA_WRITE      *(volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIOWRITE)
+#define I2C_DDR_SDA             *(volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIOENABLE)
+#define I2C_CNT_SDA             *(volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIOFUNC)
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO33) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO34) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO44) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO45) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO46) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO48) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO49) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO50) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO51) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO52) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO53) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO54) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO55) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO56) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO57) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO58) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO59) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO60) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO61) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO62))
+#define I2C_PORT_SDA_STRING     "GPIO"
+#define I2C_PORT_SDA_READ       *(volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIO1READ)
+#define I2C_PORT_SDA_WRITE      *(volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIO1WRITE)
+#define I2C_DDR_SDA             *(volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIO1ENABLE)
+#define I2C_CNT_SDA             *(volatile u32 *)(MCF_MBAR2 + MCFSIM2_GPIO1FUNC)
+
+#else
+#error "CONFIG_I2C_MCF_GPIO_SDA_* is not correctly #define'd!"
+#endif  /* CONFIG_I2C_MCF_GPIO_SDA_* */
+
+
+#if (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO0) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO32))
+#define I2C_BIT_SDA             0
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO1) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO33))
+#define I2C_BIT_SDA             1
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO2) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO34))
+#define I2C_BIT_SDA             2
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO3) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO35))
+#define I2C_BIT_SDA             3
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO4) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO36))
+#define I2C_BIT_SDA             4
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO5) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO37))
+#define I2C_BIT_SDA             5
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO6) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO38))
+#define I2C_BIT_SDA             6
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO7) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO39))
+#define I2C_BIT_SDA             7
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO8) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO40))
+#define I2C_BIT_SDA             8
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO9) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO41))
+#define I2C_BIT_SDA             9
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO10) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO42))
+#define I2C_BIT_SDA             10
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO11) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO43))
+#define I2C_BIT_SDA             11
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO12) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO44))
+#define I2C_BIT_SDA             12
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO13) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO45))
+#define I2C_BIT_SDA             13
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO14) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO46))
+#define I2C_BIT_SDA             14
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO15) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO47))
+#define I2C_BIT_SDA             15
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO16) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO48))
+#define I2C_BIT_SDA             16
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO17) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO49))
+#define I2C_BIT_SDA             17
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO18) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO50))
+#define I2C_BIT_SDA             18
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO19) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO51))
+#define I2C_BIT_SDA             19
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO20) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO52))
+#define I2C_BIT_SDA             20
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO21) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO53))
+#define I2C_BIT_SDA             21
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO22) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO54))
+#define I2C_BIT_SDA             22
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO23) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO55))
+#define I2C_BIT_SDA             23
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO24) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO56))
+#define I2C_BIT_SDA             24
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO25) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO57))
+#define I2C_BIT_SDA             25
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO26) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO58))
+#define I2C_BIT_SDA             26
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO27) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO59))
+#define I2C_BIT_SDA             27
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO28) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO60))
+#define I2C_BIT_SDA             28
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO29) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO61))
+#define I2C_BIT_SDA             29
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO30) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO62))
+#define I2C_BIT_SDA             30
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO31) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_GPIO63))
+#define I2C_BIT_SDA             31
+
+#else
+#error "CONFIG_I2C_MCF_GPIO_SDA_* is not correctly #define'd!"
+#endif  /* CONFIG_I2C_MCF_GPIO_SDA_* */
+
+
+/* Bitmasks for SCL and SDA lines */
+#define I2C_MASK_SCL            (1 << I2C_BIT_SCL)
+#define I2C_MASK_SDA            (1 << I2C_BIT_SDA)
+
+#define I2C_MASK_CNT_SCL_AND    (~0)
+#define I2C_MASK_CNT_SDA_AND    (~0)
+#define I2C_MASK_CNT_SCL_OR     (1 << I2C_BIT_SCL)
+#define I2C_MASK_CNT_SDA_OR     (1 << I2C_BIT_SDA)
+
+
+/* ----------------------------------------------------------------------------
+ * MCF5272 driver ports and bitmasks
+ */
+#elif defined(CONFIG_M5272)
+
+/* Determine SCL line settings based on CONFIG_I2C_MCF_GPIO_SCL_* */
+#if (defined(CONFIG_I2C_MCF_GPIO_SCL_PA0) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PA1) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PA2) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PA3) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PA4) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PA5) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PA6) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PA7) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PA8) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PA9) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PA10) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PA11) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PA12) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PA13) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PA14) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PA15))
+#define I2C_PORT_SCL_STRING     "PA"
+#define I2C_PORT_SCL_READ       *(volatile u16 *)(MCF_MBAR + MCFSIM_PADAT)
+#define I2C_PORT_SCL_WRITE      *(volatile u16 *)(MCF_MBAR + MCFSIM_PADAT)
+#define I2C_DDR_SCL             *(volatile u16 *)(MCF_MBAR + MCFSIM_PADDR)
+#define I2C_CNT_SCL             *(volatile u32 *)(MCF_MBAR + MCFSIM_PACNT)
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PB0) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB1) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB2) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB3) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB4) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB5) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB6) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB7) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB8) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB9) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB10) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB11) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB12) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB13) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB14) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB15))
+#define I2C_PORT_SCL_STRING     "PB"
+#define I2C_PORT_SCL_READ       *(volatile u16 *)(MCF_MBAR + MCFSIM_PBDAT)
+#define I2C_PORT_SCL_WRITE      *(volatile u16 *)(MCF_MBAR + MCFSIM_PBDAT)
+#define I2C_DDR_SCL             *(volatile u16 *)(MCF_MBAR + MCFSIM_PBDDR)
+#define I2C_CNT_SCL             *(volatile u32 *)(MCF_MBAR + MCFSIM_PBCNT)
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PC0) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC1) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC2) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC3) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC4) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC5) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC6) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC7) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC8) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC9) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC10) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC11) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC12) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC13) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC14) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC15))
+#define I2C_PORT_SCL_STRING     "PC"
+#define I2C_PORT_SCL_READ       *(volatile u16 *)(MCF_MBAR + MCFSIM_PCDAT)
+#define I2C_PORT_SCL_WRITE      *(volatile u16 *)(MCF_MBAR + MCFSIM_PCDAT)
+#define I2C_DDR_SCL             *(volatile u16 *)(MCF_MBAR + MCFSIM_PCDDR)
+#undef  I2C_CNT_SCL             /* Port C has no control register */
+
+#else
+#error "CONFIG_I2C_MCF_GPIO_SCL_* is not correctly #define'd!"
+#endif  /* CONFIG_I2C_MCF_GPIO_SCL_* */
+
+
+#if (defined(CONFIG_I2C_MCF_GPIO_SCL_PA0) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB0) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC0))
+#define I2C_BIT_SCL             0
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PA1) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB1) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC1))
+#define I2C_BIT_SCL             1
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PA2) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB2) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC2))
+#define I2C_BIT_SCL             2
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PA3) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB3) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC3))
+#define I2C_BIT_SCL             3
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PA4) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB4) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC4))
+#define I2C_BIT_SCL             4
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PA5) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB5) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC5))
+#define I2C_BIT_SCL             5
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PA6) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB6) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC6))
+#define I2C_BIT_SCL             6
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PA7) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB7) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC7))
+#define I2C_BIT_SCL             7
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PA8) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB8) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC8))
+#define I2C_BIT_SCL             8
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PA9) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB9) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC9))
+#define I2C_BIT_SCL             9
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PA10) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB10) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC10))
+#define I2C_BIT_SCL             10
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PA11) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB11) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC11))
+#define I2C_BIT_SCL             11
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PA12) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB12) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC12))
+#define I2C_BIT_SCL             12
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PA13) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB13) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC13))
+#define I2C_BIT_SCL             13
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PA14) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB14) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC14))
+#define I2C_BIT_SCL             14
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SCL_PA15) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PB15) || \
+        defined(CONFIG_I2C_MCF_GPIO_SCL_PC15))
+#define I2C_BIT_SCL             15
+
+#else
+#error "CONFIG_I2C_MCF_GPIO_SCL_* is not correctly #define'd!"
+#endif  /* CONFIG_I2C_MCF_GPIO_SCL_* */
+
+
+/* Determine SDA line settings based on CONFIG_I2C_MCF_GPIO_SDA_* */
+#if (defined(CONFIG_I2C_MCF_GPIO_SDA_PA0) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PA1) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PA2) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PA3) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PA4) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PA5) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PA6) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PA7) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PA8) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PA9) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PA10) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PA11) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PA12) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PA13) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PA14) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PA15))
+#define I2C_PORT_SDA_STRING     "PA"
+#define I2C_PORT_SDA_READ       *(volatile u16 *)(MCF_MBAR + MCFSIM_PADAT)
+#define I2C_PORT_SDA_WRITE      *(volatile u16 *)(MCF_MBAR + MCFSIM_PADAT)
+#define I2C_DDR_SDA             *(volatile u16 *)(MCF_MBAR + MCFSIM_PADDR)
+#define I2C_CNT_SDA             *(volatile u32 *)(MCF_MBAR + MCFSIM_PACNT)
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PB0) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB1) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB2) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB3) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB4) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB5) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB6) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB7) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB8) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB9) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB10) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB11) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB12) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB13) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB14) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB15))
+#define I2C_PORT_SDA_STRING     "PB"
+#define I2C_PORT_SDA_READ       *(volatile u16 *)(MCF_MBAR + MCFSIM_PBDAT)
+#define I2C_PORT_SDA_WRITE      *(volatile u16 *)(MCF_MBAR + MCFSIM_PBDAT)
+#define I2C_DDR_SDA             *(volatile u16 *)(MCF_MBAR + MCFSIM_PBDDR)
+#define I2C_CNT_SDA             *(volatile u32 *)(MCF_MBAR + MCFSIM_PBCNT)
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PC0) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC1) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC2) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC3) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC4) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC5) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC6) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC7) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC8) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC9) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC10) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC11) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC12) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC13) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC14) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC15))
+#define I2C_PORT_SDA_STRING     "PC"
+#define I2C_PORT_SDA_READ       *(volatile u16 *)(MCF_MBAR + MCFSIM_PCDAT)
+#define I2C_PORT_SDA_WRITE      *(volatile u16 *)(MCF_MBAR + MCFSIM_PCDAT)
+#define I2C_DDR_SDA             *(volatile u16 *)(MCF_MBAR + MCFSIM_PCDDR)
+#undef  I2C_CNT_SDA             /* Port C has no control register */
+
+#else
+#error "CONFIG_I2C_MCF_GPIO_SDA_* is not correctly #define'd!"
+#endif  /* CONFIG_I2C_MCF_GPIO_SDA_* */
+
+
+#if (defined(CONFIG_I2C_MCF_GPIO_SDA_PA0) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB0) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC0))
+#define I2C_BIT_SDA             0
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PA1) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB1) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC1))
+#define I2C_BIT_SDA             1
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PA2) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB2) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC2))
+#define I2C_BIT_SDA             2
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PA3) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB3) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC3))
+#define I2C_BIT_SDA             3
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PA4) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB4) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC4))
+#define I2C_BIT_SDA             4
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PA5) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB5) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC5))
+#define I2C_BIT_SDA             5
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PA6) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB6) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC6))
+#define I2C_BIT_SDA             6
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PA7) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB7) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC7))
+#define I2C_BIT_SDA             7
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PA8) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB8) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC8))
+#define I2C_BIT_SDA             8
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PA9) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB9) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC9))
+#define I2C_BIT_SDA             9
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PA10) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB10) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC10))
+#define I2C_BIT_SDA             10
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PA11) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB11) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC11))
+#define I2C_BIT_SDA             11
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PA12) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB12) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC12))
+#define I2C_BIT_SDA             12
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PA13) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB13) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC13))
+#define I2C_BIT_SDA             13
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PA14) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB14) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC14))
+#define I2C_BIT_SDA             14
+
+#elif (defined(CONFIG_I2C_MCF_GPIO_SDA_PA15) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PB15) || \
+        defined(CONFIG_I2C_MCF_GPIO_SDA_PC15))
+#define I2C_BIT_SDA             15
+
+#else
+#error "CONFIG_I2C_MCF_GPIO_SDA_* is not correctly #define'd!"
+#endif  /* CONFIG_I2C_MCF_GPIO_SDA_* */
+
+
+/* Bitmasks for SCL and SDA lines */
+#define I2C_MASK_SCL            (1 << I2C_BIT_SCL)
+#define I2C_MASK_SDA            (1 << I2C_BIT_SDA)
+
+#define I2C_MASK_CNT_SCL_AND    (~(3 << (I2C_BIT_SCL << 1)))
+#define I2C_MASK_CNT_SDA_AND    (~(3 << (I2C_BIT_SDA << 1)))
+#define I2C_MASK_CNT_SCL_OR     (0)
+#define I2C_MASK_CNT_SDA_OR     (0)
+
+
+/* ----------------------------------------------------------------------------
+ * MCF5307 and MCF5407 driver ports and bitmasks
+ */
+#elif (defined(CONFIG_M5307) || defined(MCF5407))
+
+/* Determine SCL line settings based on CONFIG_I2C_MCF_GPIO_SCL_* */
+#define I2C_PORT_SCL_STRING     "PP"
+#define I2C_PORT_SCL_READ       *(volatile u16 *)(MCF_MBAR + MCFSIM_PADAT)
+#define I2C_PORT_SCL_WRITE      *(volatile u16 *)(MCF_MBAR + MCFSIM_PADAT)
+#define I2C_DDR_SCL             *(volatile u16 *)(MCF_MBAR + MCFSIM_PADDR)
+#define I2C_CNT_SCL             *(volatile u16 *)(MCF_MBAR + MCFSIM_PAR)
+
+#if defined(CONFIG_I2C_MCF_GPIO_SCL_PP0)
+#define I2C_BIT_SCL             0
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP1)
+#define I2C_BIT_SCL             1
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP2)
+#define I2C_BIT_SCL             2
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP3)
+#define I2C_BIT_SCL             3
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP4)
+#define I2C_BIT_SCL             4
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP5)
+#define I2C_BIT_SCL             5
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP6)
+#define I2C_BIT_SCL             6
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP7)
+#define I2C_BIT_SCL             7
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP8)
+#define I2C_BIT_SCL             8
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP9)
+#define I2C_BIT_SCL             9
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP10)
+#define I2C_BIT_SCL             10
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP11)
+#define I2C_BIT_SCL             11
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP12)
+#define I2C_BIT_SCL             12
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP13)
+#define I2C_BIT_SCL             13
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP14)
+#define I2C_BIT_SCL             14
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SCL_PP15)
+#define I2C_BIT_SCL             15
+
+#else
+#error "CONFIG_I2C_MCF_GPIO_SCL_* is not correctly #define'd!"
+#endif  /* CONFIG_I2C_MCF_GPIO_SCL_* */
+
+
+/* Determine SDA line settings based on CONFIG_I2C_MCF_GPIO_SDA_* */
+#define I2C_PORT_SDA_STRING     "PP"
+#define I2C_PORT_SDA_READ       *(volatile u16 *)(MCF_MBAR + MCFSIM_PADAT)
+#define I2C_PORT_SDA_WRITE      *(volatile u16 *)(MCF_MBAR + MCFSIM_PADAT)
+#define I2C_DDR_SDA             *(volatile u16 *)(MCF_MBAR + MCFSIM_PADDR)
+#define I2C_CNT_SDA             *(volatile u16 *)(MCF_MBAR + MCFSIM_PAR)
+
+#if defined(CONFIG_I2C_MCF_GPIO_SDA_PP0)
+#define I2C_BIT_SDA             0
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP1)
+#define I2C_BIT_SDA             1
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP2)
+#define I2C_BIT_SDA             2
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP3)
+#define I2C_BIT_SDA             3
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP4)
+#define I2C_BIT_SDA             4
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP5)
+#define I2C_BIT_SDA             5
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP6)
+#define I2C_BIT_SDA             6
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP7)
+#define I2C_BIT_SDA             7
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP8)
+#define I2C_BIT_SDA             8
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP9)
+#define I2C_BIT_SDA             9
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP10)
+#define I2C_BIT_SDA             10
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP11)
+#define I2C_BIT_SDA             11
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP12)
+#define I2C_BIT_SDA             12
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP13)
+#define I2C_BIT_SDA             13
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP14)
+#define I2C_BIT_SDA             14
+
+#elif defined(CONFIG_I2C_MCF_GPIO_SDA_PP15)
+#define I2C_BIT_SDA             15
+
+#else
+#error "CONFIG_I2C_MCF_GPIO_SDA_* is not correctly #define'd!"
+#endif  /* CONFIG_I2C_MCF_GPIO_SDA_* */
+
+
+/* Bitmasks for SCL and SDA lines */
+#define I2C_MASK_SCL            (1 << I2C_BIT_SCL)
+#define I2C_MASK_SDA            (1 << I2C_BIT_SDA)
+
+#define I2C_MASK_CNT_SCL_AND    (~(1 << I2C_BIT_SCL))
+#define I2C_MASK_CNT_SDA_AND    (~(1 << I2C_BIT_SDA))
+#define I2C_MASK_CNT_SCL_OR     (0)
+#define I2C_MASK_CNT_SDA_OR     (0)
+
+
+#else
+#error "CONFIG_M5* is not correctly #define'd!  What processor is this?"
+#endif  /* CONFIG_M5* */
+
+
+/* ----------------------------------------------------------------------------
+ * Local prototypes
+ */
+static void bit_mcf_gpio_inc_use(struct i2c_adapter *adap);
+static void bit_mcf_gpio_dec_use(struct i2c_adapter *adap);
+static int bit_mcf_gpio_reg(struct i2c_client *client);
+static int bit_mcf_gpio_unreg(struct i2c_client *client);
+static void bit_mcf_gpio_init(void);
+static void bit_mcf_gpio_setscl(void *data, int state);
+static void bit_mcf_gpio_setsda(void *data, int state);
+static int bit_mcf_gpio_getscl(void *data);
+static int bit_mcf_gpio_getsda(void *data);
+
+
+/* ----------------------------------------------------------------------------
+ * Data structures
+ */
+static struct i2c_algo_bit_data bit_mcf_gpio_data = {
+        NULL,
+        bit_mcf_gpio_setsda,
+        bit_mcf_gpio_setscl,
+        bit_mcf_gpio_getsda,
+        bit_mcf_gpio_getscl,
+        10,
+        10,
+        100
+};
+
+static struct i2c_adapter bit_mcf_gpio_ops = {
+        "Motorola Coldfire GPIO",
+        I2C_HW_B_COLDF,
+        NULL,
+        &bit_mcf_gpio_data,
+        bit_mcf_gpio_inc_use,
+        bit_mcf_gpio_dec_use,
+        bit_mcf_gpio_reg,
+        bit_mcf_gpio_unreg,
+};
+
+
+/* ----------------------------------------------------------------------------
+ * Public methods
+ */
+#if defined(MODULE)
+int __init init_module(void)
+{
+        return(i2c_bit_mcf_gpio_init());
+}
+
+
+void __exit cleanup_module(void)
+{
+        i2c_bit_del_bus(&bit_mcf_gpio_ops);
+}
+#endif  /* MODULE */
+
+
+int __init i2c_bit_mcf_gpio_init(void)
+{
+        printk(KERN_INFO "%s: Motorola Coldfire GPIO I2C adapter\n", __FILE__);
+        printk(KERN_INFO "%s: SCL on %s%d, SDA on %s%d\n", __FILE__, 
+                        I2C_PORT_SCL_STRING, I2C_BIT_SCL,
+                        I2C_PORT_SDA_STRING, I2C_BIT_SDA);
+
+        /* Set SCL and SDA lines for use as GPIO */
+        bit_mcf_gpio_init();
+
+        /* Set SDA and SCL as output initially */
+        bit_mcf_gpio_setsda(NULL, 1);
+        bit_mcf_gpio_setscl(NULL, 1);
+
+        if (i2c_bit_add_bus(&bit_mcf_gpio_ops) < 0) {
+                printk(KERN_ERR "%s: i2c_bit_add_bus() failed - adapter not "
+                                "installed!\n", __FILE__);
+                return(-ENODEV);
+        }
+
+        return(0);
+}
+
+
+/* ----------------------------------------------------------------------------
+ * Private methods and helper functions
+ */
+static void bit_mcf_gpio_inc_use(struct i2c_adapter *adap)
+{
+#if defined(MODULE)
+        MOD_INC_USE_COUNT;
+#endif  /* MODULE */
+}
+
+
+static void bit_mcf_gpio_dec_use(struct i2c_adapter *adap)
+{
+#if defined(MODULE)
+        MOD_DEC_USE_COUNT;
+#endif  /* MODULE */
+}
+
+
+static int bit_mcf_gpio_reg(struct i2c_client *client)
+{
+        return(0);
+}
+
+
+static int bit_mcf_gpio_unreg(struct i2c_client *client)
+{
+        return(0);
+}
+
+
+static void bit_mcf_gpio_init(void)
+{
+        /* I2C_CNT_* will not be defined for MCF5272 Port C */
+#if defined(I2C_CNT_SCL)
+        I2C_CNT_SCL &= I2C_MASK_CNT_SCL_AND;
+        I2C_CNT_SCL |= I2C_MASK_CNT_SCL_OR;
+#endif  /* I2C_CNT_SCL */
+
+#if defined(I2C_CNT_SDA)
+        I2C_CNT_SDA &= I2C_MASK_CNT_SDA_AND;
+        I2C_CNT_SDA |= I2C_MASK_CNT_SDA_OR;
+#endif  /* I2C_CNT_SDA */
+}
+
+
+static void bit_mcf_gpio_setscl(void *data, int state)
+{
+        I2C_DDR_SCL |= I2C_MASK_SCL;
+
+        if (state)
+                I2C_PORT_SCL_WRITE |= I2C_MASK_SCL;
+        else
+                I2C_PORT_SCL_WRITE &= ~I2C_MASK_SCL;
+}
+
+
+static void bit_mcf_gpio_setsda(void *data, int state)
+{
+        I2C_DDR_SDA |= I2C_MASK_SDA;
+
+        if (state)
+                I2C_PORT_SDA_WRITE |= I2C_MASK_SDA;
+        else
+                I2C_PORT_SDA_WRITE &= ~I2C_MASK_SDA;
+}
+
+
+static int bit_mcf_gpio_getscl(void *data)
+{
+        I2C_DDR_SCL &= ~I2C_MASK_SCL;
+        return((I2C_PORT_SCL_READ & I2C_MASK_SCL) != 0);
+}
+
+
+static int bit_mcf_gpio_getsda(void *data)
+{
+        I2C_DDR_SDA &= ~I2C_MASK_SDA;
+        return((I2C_PORT_SDA_READ & I2C_MASK_SDA) != 0);
+}
+
+
+/* ----------------------------------------------------------------------------
+ * Driver public symbols
+ */
+EXPORT_NO_SYMBOLS;
+
+#if defined(MODULE)
+MODULE_AUTHOR("Cory T. Tusar <ctusar@videon-central.com>");
+MODULE_DESCRIPTION("I2C-Bus GPIO driver for Motorola Coldfire processors");
+MODULE_LICENSE("GPL");
+#endif  /* MODULE */
+
diff -urN linux-2.4.29/drivers/i2c/i2c-adap-netarm_gpio.c linux-2.4.29-uc1/drivers/i2c/i2c-adap-netarm_gpio.c
--- linux-2.4.29/drivers/i2c/i2c-adap-netarm_gpio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/i2c-adap-netarm_gpio.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,436 @@
+/* vim:set ts=8 sw=8 et: */
+/* ----------------------------------------------------------------------------
+ * i2c-adap-netarm_gpio.c i2c-hw access using Netsilicon NetARM GPIO
+ *
+ * ----------------------------------------------------------------------------
+ * Arthur E. Shipkowski, Videon Central, Inc.
+ * <art@videon-central.com>
+ *
+ * Copyright (C) 2004 Videon Central, Inc.
+ *
+ * ----------------------------------------------------------------------------
+ * This driver supports using a pair of GPIO pins on the NetSilicon NetARM
+ * series of microcontrollers as an I2C adapter.
+ *
+ * This driver has only undergone basic testing on NS7520 hardware.  Please be
+ * aware that issues may be present when attempting to use this driver with
+ * untested processors.
+ *
+ * This driver was based upon Cory Tusar's GPIO I2C driver for ColdFire chips.
+ *
+ * ----------------------------------------------------------------------------
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+/*
+ * NetSilicon register offsets, etc.
+ */
+#include <asm/arch/netarm_gen_module.h>
+
+/* Legacy includes */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0))
+#include <linux/string.h>               /* Provides NULL for 2.0 kernels */
+#include <asm/errno.h>                  /* Provides ENODEV for 2.0 kernels */
+#endif  /* LINUX_VERSION_CODE */
+
+
+/* ----------------------------------------------------------------------------
+ * Compile-time dummy checks to keep things relatively sane
+ */
+#if !defined(CONFIG_ARCH_NETARM)
+#error "Can't build NetSilicon I2C-Bus adapter driver for non-NetARM processor"
+#endif  /* !defined(CONFIG_ARCH_NETARM) */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0))
+#warning "This driver has not been tested with kernel versions < 2.4.0"
+#endif  /* LINUX_VERSION_CODE */
+
+/* Determine SCL port values */
+#if (defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTA0) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTA1) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTA2) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTA3) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTA4) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTA5) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTA6) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTA7))
+#define I2C_PORT_SCL_STRING     "PA"
+#define I2C_PORT_SCL            *(get_gen_reg_addr(NETARM_GEN_PORTA))
+#define I2C_SCL_PORTA
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTB0) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTB1) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTB2) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTB3) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTB4) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTB5) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTB6) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTB7))
+        
+#if defined(CONFIG_NETARM_NS7520)        
+#error "Nonexistent PORTB somehow selected for NS7520 processor SCL line!"
+#endif  
+        
+#define I2C_PORT_SCL_STRING     "PB"
+#define I2C_PORT_SCL            *(get_gen_reg_addr(NETARM_GEN_PORTB))
+#define I2C_SCL_PORTB
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTC0) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTC1) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTC2) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTC3) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTC4) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTC5) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTC6) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTC7))
+#define I2C_PORT_SCL_STRING     "PC"
+#define I2C_PORT_SCL            *(get_gen_reg_addr(NETARM_GEN_PORTC))
+#define I2C_SCL_PORTC
+
+#else
+#error "CONFIG_I2C_NETARM_GPIO_SCL_* is not properly configured."
+#endif /* CONFIG_I2C_NETARM_GPIO_SCL_*/
+
+#if (defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTA0) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTB0) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTC0))
+#define I2C_BIT_SCL             0
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTA1) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTB1) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTC1))
+#define I2C_BIT_SCL             1
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTA2) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTB2) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTC2))
+#define I2C_BIT_SCL             2
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTA3) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTB3) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTC3))
+#define I2C_BIT_SCL             3
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTA4) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTB4) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTC4))
+#define I2C_BIT_SCL             4
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTA5) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTB5) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTC5))
+#define I2C_BIT_SCL             5
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTA6) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTB6) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTC6))
+#define I2C_BIT_SCL             6
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTA7) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTB7) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SCL_PORTC7))
+#define I2C_BIT_SCL             7
+
+#else
+#error "CONFIG_I2C_NETARM_GPIO_SCL_* is not correctly #define'd!"
+#endif  /* CONFIG_I2C_NETARM_GPIO_SCL_* */
+
+/* Set up SCL port mode for GPIO */
+#if (defined(CONFIG_NETARM_NS7520) && defined(I2C_SCL_PORTC))
+#define I2C_SCL_PORT_SETUP(x)       (~(NETARM_GEN_PORT_MODE(x) | NETARM_GEN_PORT_CSF(x))) /* Handle NS7520 PORTC properly */
+#else
+#define I2C_SCL_PORT_SETUP(x)       (~(NETARM_GEN_PORT_MODE(x)))
+#endif                        
+
+
+/* Determine SDA port values */
+#if (defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTA0) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTA1) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTA2) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTA3) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTA4) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTA5) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTA6) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTA7))
+#define I2C_PORT_SDA_STRING     "PA"
+#define I2C_PORT_SDA            *(get_gen_reg_addr(NETARM_GEN_PORTA))
+#define I2C_SDA_PORTA
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTB0) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTB1) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTB2) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTB3) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTB4) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTB5) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTB6) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTB7))
+        
+#if defined(CONFIG_NETARM_NS7520)        
+#error "Nonexistent PORTB somehow selected for NS7520 processor SDA line!"
+#endif  
+        
+#define I2C_PORT_SDA_STRING     "PB"
+#define I2C_PORT_SDA            *(get_gen_reg_addr(NETARM_GEN_PORTB))
+#define I2C_SDA_PORTB
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTC0) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTC1) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTC2) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTC3) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTC4) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTC5) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTC6) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTC7))
+#define I2C_PORT_SDA_STRING     "PC"
+#define I2C_PORT_SDA            *(get_gen_reg_addr(NETARM_GEN_PORTC))
+#define I2C_SDA_PORTC
+
+#else
+#error "CONFIG_I2C_NETARM_GPIO_SDA_* is not properly configured."
+#endif /* CONFIG_I2C_NETARM_GPIO_SDA_*/
+
+#if (defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTA0) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTB0) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTC0))
+#define I2C_BIT_SDA             0
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTA1) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTB1) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTC1))
+#define I2C_BIT_SDA             1
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTA2) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTB2) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTC2))
+#define I2C_BIT_SDA             2
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTA3) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTB3) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTC3))
+#define I2C_BIT_SDA             3
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTA4) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTB4) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTC4))
+#define I2C_BIT_SDA             4
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTA5) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTB5) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTC5))
+#define I2C_BIT_SDA             5
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTA6) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTB6) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTC6))
+#define I2C_BIT_SDA             6
+
+#elif (defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTA7) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTB7) || \
+        defined(CONFIG_I2C_NETARM_GPIO_SDA_PORTC7))
+#define I2C_BIT_SDA             7
+
+#else
+#error "CONFIG_I2C_NETARM_GPIO_SDA_* is not correctly #define'd!"
+#endif  /* CONFIG_I2C_NETARM_GPIO_SDA_* */
+
+/* Set up SDA port mode for GPIO */
+#if (defined(CONFIG_NETARM_NS7520) && defined(I2C_SDA_PORTC))
+#define I2C_SDA_PORT_SETUP(x)       (~(NETARM_GEN_PORT_MODE(x) | NETARM_GEN_PORT_CSF(x))) /* Handle NS7520 PORTC properly */
+#else
+#define I2C_SDA_PORT_SETUP(x)       (~(NETARM_GEN_PORT_MODE(x)))
+#endif                        
+
+/* Bitmasks for SCL and SDA lines */
+#define I2C_MASK_SCL            (1 << I2C_BIT_SCL)
+#define I2C_MASK_SDA            (1 << I2C_BIT_SDA)
+
+
+
+
+/* ----------------------------------------------------------------------------
+ * Local prototypes
+ */
+static void bit_netarm_gpio_inc_use(struct i2c_adapter *adap);
+static void bit_netarm_gpio_dec_use(struct i2c_adapter *adap);
+static int bit_netarm_gpio_reg(struct i2c_client *client);
+static int bit_netarm_gpio_unreg(struct i2c_client *client);
+static void bit_netarm_gpio_init(void);
+static void bit_netarm_gpio_setscl(void *data, int state);
+static void bit_netarm_gpio_setsda(void *data, int state);
+static int bit_netarm_gpio_getscl(void *data);
+static int bit_netarm_gpio_getsda(void *data);
+
+
+/* ----------------------------------------------------------------------------
+ * Data structures
+ */
+static struct i2c_algo_bit_data bit_netarm_gpio_data = {
+        NULL,
+        bit_netarm_gpio_setsda,
+        bit_netarm_gpio_setscl,
+        bit_netarm_gpio_getsda,
+        bit_netarm_gpio_getscl,
+        10,
+        10,
+        100
+};
+
+static struct i2c_adapter bit_netarm_gpio_ops = {
+        "NetSilicon NetARM GPIO",
+        I2C_HW_B_NETARM,
+        NULL,
+        &bit_netarm_gpio_data,
+        bit_netarm_gpio_inc_use,
+        bit_netarm_gpio_dec_use,
+        bit_netarm_gpio_reg,
+        bit_netarm_gpio_unreg,
+};
+
+
+/* ----------------------------------------------------------------------------
+ * Public methods
+ */
+#if defined(MODULE)
+int __init init_module(void)
+{
+        return(i2c_bit_netarm_gpio_init());
+}
+
+
+void __exit cleanup_module(void)
+{
+        i2c_bit_del_bus(&bit_netarm_gpio_ops);
+}
+#endif  /* MODULE */
+
+
+int __init i2c_bit_netarm_gpio_init(void)
+{
+        printk(KERN_INFO "%s: NetSilicon NetARM GPIO I2C adapter\n",
+                        __FILE__);
+        printk(KERN_INFO "%s: SCL on %s%d, SDA on %s%d\n",
+                        __FILE__,
+                        I2C_PORT_SCL_STRING, I2C_BIT_SCL,
+                        I2C_PORT_SDA_STRING, I2C_BIT_SDA);
+
+        /* Set SCL and SDA lines for use as GPIO */
+        bit_netarm_gpio_init();
+
+        /* Set SDA and SCL as output initially */
+        bit_netarm_gpio_setsda(NULL, 1);
+        bit_netarm_gpio_setscl(NULL, 1);
+
+        if (i2c_bit_add_bus(&bit_netarm_gpio_ops) < 0) {
+                printk(KERN_ERR "%s: i2c_bit_add_bus() failed - adapter not "
+                                "installed!\n", __FILE__);
+                return(-ENODEV);
+        }
+
+        return(0);
+}
+
+
+/* ----------------------------------------------------------------------------
+ * Private methods and helper functions
+ */
+static void bit_netarm_gpio_inc_use(struct i2c_adapter *adap)
+{
+#if defined(MODULE)
+        MOD_INC_USE_COUNT;
+#endif  /* MODULE */
+}
+
+
+static void bit_netarm_gpio_dec_use(struct i2c_adapter *adap)
+{
+#if defined(MODULE)
+        MOD_DEC_USE_COUNT;
+#endif  /* MODULE */
+}
+
+
+static int bit_netarm_gpio_reg(struct i2c_client *client)
+{
+        return(0);
+}
+
+
+static int bit_netarm_gpio_unreg(struct i2c_client *client)
+{
+        return(0);
+}
+
+
+static void bit_netarm_gpio_init(void)
+{
+        I2C_PORT_SCL &= I2C_SCL_PORT_SETUP(I2C_MASK_SCL);
+        I2C_PORT_SDA &= I2C_SDA_PORT_SETUP(I2C_MASK_SDA);
+}
+
+
+static void bit_netarm_gpio_setscl(void *data, int state)
+{
+        I2C_PORT_SCL |= NETARM_GEN_PORT_DIR(I2C_MASK_SCL);
+
+        if (state)
+                I2C_PORT_SCL |= I2C_MASK_SCL;
+        else
+                I2C_PORT_SCL &= ~I2C_MASK_SCL;
+}
+
+
+static void bit_netarm_gpio_setsda(void *data, int state)
+{
+        I2C_PORT_SDA |= NETARM_GEN_PORT_DIR(I2C_MASK_SDA);
+
+
+        if (state)
+                I2C_PORT_SDA |= I2C_MASK_SDA;
+        else
+                I2C_PORT_SDA &= ~I2C_MASK_SDA;
+}
+
+
+static int bit_netarm_gpio_getscl(void *data)
+{
+        I2C_PORT_SCL &= ~NETARM_GEN_PORT_DIR(I2C_MASK_SCL);
+        return((I2C_PORT_SCL & I2C_MASK_SCL) != 0);
+}
+
+
+static int bit_netarm_gpio_getsda(void *data)
+{
+        I2C_PORT_SDA &= ~NETARM_GEN_PORT_DIR(I2C_MASK_SDA);
+        return((I2C_PORT_SDA & I2C_MASK_SDA) != 0);
+}
+
+
+/* ----------------------------------------------------------------------------
+ * Driver public symbols
+ */
+EXPORT_NO_SYMBOLS;
+
+#if defined(MODULE)
+MODULE_AUTHOR("Arthur E. Shipkowski <art@videon-central.com>");
+MODULE_DESCRIPTION("I2C-Bus GPIO driver for NetSilicon NetARM processors");
+MODULE_LICENSE("GPL");
+#endif  /* MODULE */
+
diff -urN linux-2.4.29/drivers/i2c/i2c-core.c linux-2.4.29-uc1/drivers/i2c/i2c-core.c
--- linux-2.4.29/drivers/i2c/i2c-core.c	2005-01-19 14:09:54.000000000 +0000
+++ linux-2.4.29-uc1/drivers/i2c/i2c-core.c	2005-06-14 02:12:19.000000000 +0100
@@ -1258,6 +1258,12 @@
 #ifdef CONFIG_I2C_BITVIA
 	extern int i2c_bitvia_init(void);
 #endif
+#ifdef CONFIG_I2C_MCF_GPIO
+	extern int i2c_bit_mcf_gpio_init(void);
+#endif
+#ifdef CONFIG_I2C_NETARM_GPIO
+	extern int i2c_bit_netarm_gpio_init(void);
+#endif
 
 #ifdef CONFIG_I2C_ALGOPCF
 	extern int i2c_algo_pcf_init(void);	
@@ -1309,6 +1315,12 @@
 #ifdef CONFIG_I2C_VELLEMAN
 	i2c_bitvelle_init();
 #endif
+#ifdef CONFIG_I2C_MCF_GPIO
+	i2c_bit_mcf_gpio_init();
+#endif
+#ifdef CONFIG_I2C_NETARM_GPIO
+	i2c_bit_netarm_gpio_init();
+#endif
 
 	/* --------------------- pcf -------- */
 #ifdef CONFIG_I2C_ALGOPCF
diff -urN linux-2.4.29/drivers/i2c/i2c-frodo.c linux-2.4.29-uc1/drivers/i2c/i2c-frodo.c
--- linux-2.4.29/drivers/i2c/i2c-frodo.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/i2c-frodo.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,114 @@
+
+/*
+ * linux/drivers/i2c/i2c-frodo.c
+ *
+ * Author: Abraham van der Merwe <abraham@2d3d.co.za>
+ *
+ * An I2C adapter driver for the 2d3D, Inc. StrongARM SA-1110
+ * Development board (Frodo).
+ *
+ * This source code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <asm/hardware.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+static void frodo_setsda (void *data,int state)
+{
+	if (state)
+		frodo_cpld_set (FRODO_CPLD_I2C,FRODO_I2C_SDA_OUT);
+	else
+		frodo_cpld_clear (FRODO_CPLD_I2C,FRODO_I2C_SDA_OUT);
+}
+
+static void frodo_setscl (void *data,int state)
+{
+	if (state)
+		frodo_cpld_set (FRODO_CPLD_I2C,FRODO_I2C_SCL_OUT);
+	else
+		frodo_cpld_clear (FRODO_CPLD_I2C,FRODO_I2C_SCL_OUT);
+}
+
+static int frodo_getsda (void *data)
+{
+	return ((frodo_cpld_read (FRODO_CPLD_I2C) & FRODO_I2C_SDA_IN) != 0);
+}
+
+static int frodo_getscl (void *data)
+{
+	return ((frodo_cpld_read (FRODO_CPLD_I2C) & FRODO_I2C_SCL_IN) != 0);
+}
+
+static struct i2c_algo_bit_data bit_frodo_data = {
+	setsda:		frodo_setsda,
+	setscl:		frodo_setscl,
+	getsda:		frodo_getsda,
+	getscl:		frodo_getscl,
+	udelay:		80,
+	mdelay:		80,
+	timeout:	100
+};
+
+static int frodo_client_register (struct i2c_client *client)
+{
+	return (0);
+}
+
+static int frodo_client_unregister (struct i2c_client *client)
+{
+	return (0);
+}
+
+static void frodo_inc_use (struct i2c_adapter *adapter)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void frodo_dec_use (struct i2c_adapter *adapter)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+static struct i2c_adapter frodo_ops = {
+	name:				"Frodo adapter driver",
+	id:					I2C_HW_B_FRODO,
+	algo:				NULL,
+	algo_data:			&bit_frodo_data,
+	inc_use:			frodo_inc_use,
+	dec_use:			frodo_dec_use,
+	client_register:	frodo_client_register,
+	client_unregister:	frodo_client_unregister
+};
+
+static int __init i2c_frodo_init (void)
+{
+	return (i2c_bit_add_bus (&frodo_ops));
+}
+
+EXPORT_NO_SYMBOLS;
+
+static void __exit i2c_frodo_exit (void)
+{
+	i2c_bit_del_bus (&frodo_ops);
+}
+
+MODULE_AUTHOR ("Abraham van der Merwe <abraham@2d3d.co.za>");
+MODULE_DESCRIPTION ("I2C-Bus adapter routines for Frodo");
+MODULE_LICENSE ("GPL");
+EXPORT_NO_SYMBOLS;
+
+module_init (i2c_frodo_init);
+module_exit (i2c_frodo_exit);
+
diff -urN linux-2.4.29/drivers/i2c/i2c-guide.c linux-2.4.29-uc1/drivers/i2c/i2c-guide.c
--- linux-2.4.29/drivers/i2c/i2c-guide.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/i2c-guide.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,199 @@
+/************************************************************************************\
+Copyright	: Copyright (C) 1995-2000 Simon G. Vogl
+		  Copyright 2002 IDERs Incorporated
+File Name	: i2c-guide.c
+Description	: this i2c driver uses the GPIO port B pin 0 and pin 1 on the cs89712.
+Notes		: To change the bit rate, change the structure i2c_algo_bit_data
+                : to 10 10 100
+Contact		: tsong@iders.ca
+License		: This source code is free software; you can redistribute it and/or
+		  modify it under the terms of the GNU General Public License
+		  version 2 as published by the Free Software Foundation.
+\************************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>  /* for 2.0 kernels to get NULL   */
+#include <asm/errno.h>     /* for 2.0 kernels to get ENODEV */
+#include <asm/io.h>
+
+#include <asm/hardware/cs89712.h>   // io operation ep_writel()
+#include <asm/hardware/clps7111.h>   // io operation clps_writel()
+#include <asm/arch-clps711x/hardware.h>   // io operation clps_writel()
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+/* ----- global defines -----------------------------------------------	*/
+
+#define DEB(x)		/* should be reasonable open, close &c. 	*/
+#define DEB2(x) 	/* low level debugging - very slow 		*/
+#define DEBE(x)	x	/* error messages 				*/
+					/*  Pin Port  Inverted	name	*/
+#define I2C_SDA		0x08		/*  port B ctrl pin 3  	(inv)	*/
+#define I2C_SCL		0x04		/*  port B ctrl pin 2 	(inv)	*/
+
+#define I2C_SDAIN	0x08		/*  use the same pin with output	*/
+#define I2C_SCLIN	0x04		/*  use the same pin with output        */
+
+#define I2C_DMASK	0xf7            /* inverse of I2C_SDA  */
+#define I2C_CMASK	0xfb            /* inverse of I2c_SCL  */
+
+#define PORTB_PIN0_SDA_OUTPUT 0x08               /* pin 3 direction  of port B output */
+#define PORTB_PIN0_SDA_INPUT  0xf7               /* pin 3 direction of port B input  */
+
+#define PORTB_PIN1_SCL_OUTPUT 0x04               /* pin 2 direction of port B output  */
+#define PORTB_PIN1_SCL_INPUT  0xfb               /* pin 2 direction of port B input  */
+
+int base = 0;
+#define DEFAULT_BASE PBDR
+
+/* ----- local functions --------------------------------------------------- */
+
+static void bit_guide_setscl(void* data, int state)
+{
+	if (state) {
+		// set port B pin2 input
+		clps_writeb((clps_readb(PBDDR)) & PORTB_PIN1_SCL_INPUT, PBDDR);
+	}
+	else {
+		// clear
+		clps_writeb((clps_readb(PBDR)) & I2C_CMASK,  PBDR);
+		// set port B pin2 output
+		clps_writeb((clps_readb(PBDDR)) | PORTB_PIN1_SCL_OUTPUT, PBDDR);
+	}
+}
+
+static void bit_guide_setsda(void* data, int state)
+{
+	if (state) {
+		clps_writeb((clps_readb(PBDDR)) & PORTB_PIN0_SDA_INPUT, PBDDR);
+		// float pin 0 (actually  drive high by pull up resistor)
+		// clps_writeb((clps_readb(PBDR)) | I2C_SDA, PBDR);   // set Jan4 ori: eff
+		// printk("set sda high, state=%i\n",state);
+	}
+	else {
+		// clear
+		clps_writeb((clps_readb(PBDR)) & I2C_DMASK,  PBDR);
+		// set port B pin 0 output
+		clps_writeb((clps_readb(PBDDR)) | PORTB_PIN0_SDA_OUTPUT, PBDDR);
+	}
+}
+
+static int bit_guide_getscl(void *data)
+{
+	return ( 0 != ( (clps_readb(PBDR)) & I2C_SCLIN  ) );
+}
+
+static int bit_guide_getsda(void *data)
+{
+	// set port B pin 0 input Jan4 ori eff
+	clps_writeb((clps_readb(PBDDR)) & PORTB_PIN0_SDA_INPUT, PBDDR);
+	return ( 0 != ( (clps_readb(PBDR) ) & I2C_SDAIN ) );
+}
+
+static int bit_guide_init(void)
+{
+	bit_guide_setsda((void*)base,1);
+	bit_guide_setscl((void*)base,1);
+	return 0;
+}
+
+static int bit_guide_reg(struct i2c_client *client)
+{
+	return 0;
+}
+
+static int bit_guide_unreg(struct i2c_client *client)
+{
+	return 0;
+}
+
+static void bit_guide_inc_use(struct i2c_adapter *adap)
+{
+#ifdef MODULE
+	MOD_INC_USE_COUNT;
+#endif
+}
+
+static void bit_guide_dec_use(struct i2c_adapter *adap)
+{
+#ifdef MODULE
+	MOD_DEC_USE_COUNT;
+#endif
+}
+
+/* ------------------------------------------------------------------------
+ * Encapsulate the above functions in the correct operations structure.
+ * This is only done when more than one hardware adapter is supported.
+ */
+
+/* last line (us, ms, timout)
+ * us dominates the bit rate: 10us  means: 100Kbit/sec(25 means 40kbps)
+ *                            10ms  not known
+ *                            100ms timeout
+ */
+static struct i2c_algo_bit_data bit_guide_data = {
+	NULL,
+	bit_guide_setsda,
+	bit_guide_setscl,
+	bit_guide_getsda,
+	bit_guide_getscl,
+	50, 10, 100,	/* orginal (non-guide) value 10, 10, 100  */
+};
+
+static struct i2c_adapter bit_guide_ops = {
+	"Guide Port B: PIN2-SCL/PIN3-SDA",
+	I2C_HW_B_GUIDE,
+	NULL,
+	&bit_guide_data,
+	bit_guide_inc_use,
+	bit_guide_dec_use,
+	bit_guide_reg,
+	bit_guide_unreg,
+};
+
+static int __init  i2c_bitguide_init(void)
+{
+	printk("i2c-guide.o: Guide i2c port B adapter module.\n");
+	clps_writeb((clps_readb(PBDDR)) & 0xfd, PBDDR);  //  set service reuest pb1 as input
+	if (base==0) {
+		/* probe some values */
+		base=DEFAULT_BASE;
+		bit_guide_data.data=(void*)DEFAULT_BASE;
+		if (bit_guide_init()==0) {
+			if(i2c_bit_add_bus(&bit_guide_ops) < 0)
+				return -ENODEV;
+		} else {
+			return -ENODEV;
+		}
+	} else {
+		bit_guide_data.data=(void*)base;
+		if (bit_guide_init()==0) {
+			if(i2c_bit_add_bus(&bit_guide_ops) < 0)
+				return -ENODEV;
+		} else {
+			return -ENODEV;
+		}
+	}
+	printk("i2c-guide.o: found device at %#x.\n",base);
+	return 0;
+}
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("T. C. Song  <tsong@iders.ca>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for Guide (cs89712) GPIO port B");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(base, "i");
+
+module_init(i2c_bitguide_init);
+/* for completeness, we should have a module_exit() function, but the
+   GUIDE requires this to always be loaded.  If it is unloaded, the
+   operation of the GUIDE is undefined.
+   Nobody has written the i2c_bitguide_exit() routine yet, so it is not included.
+module_exit(i2c_bitguide_exit);
+*/
diff -urN linux-2.4.29/drivers/i2c/i2c-iop3xx.c linux-2.4.29-uc1/drivers/i2c/i2c-iop3xx.c
--- linux-2.4.29/drivers/i2c/i2c-iop3xx.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/i2c-iop3xx.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,545 @@
+/* ------------------------------------------------------------------------- */
+/* i2c-iop3xx.c i2c driver algorithms for Intel XScale IOP3xx                */
+/* ------------------------------------------------------------------------- */
+/*   Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd
+ *                      <Peter dot Milne at D hyphen TACQ dot com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, version 2.
+
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.                */
+/* ------------------------------------------------------------------------- */
+/*
+   With acknowledgements to i2c-algo-ibm_ocp.c by 
+   Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com
+
+   And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund:
+
+     Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund
+   
+   And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>,
+   Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com>
+
+  ---------------------------------------------------------------------------*/
+
+
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/ioport.h>
+#include <linux/i2c.h>
+
+
+#include <asm/arch-iop3xx/iop321.h>
+#include <asm/arch-iop3xx/iop321-irqs.h>
+#include "i2c-iop3xx.h"
+
+
+/* ----- global defines ----------------------------------------------- */
+#define PASSERT(x) do { if (!(x) ) \
+		printk(KERN_CRIT "PASSERT %s in %s:%d\n", #x, __FILE__, __LINE__ );\
+	} while (0)
+
+
+/* ----- global variables ---------------------------------------------	*/
+
+
+static inline unsigned char iic_cook_addr(struct i2c_msg *msg) 
+{
+	unsigned char addr;
+
+	addr = (msg->addr << 1);
+
+	if (msg->flags & I2C_M_RD)
+		addr |= 1;
+
+	/* PGM: what is M_REV_DIR_ADDR - do we need it ?? */
+	if (msg->flags & I2C_M_REV_DIR_ADDR)
+		addr ^= 1;
+
+	return addr;   
+}
+
+
+static inline void iop3xx_adap_reset(struct i2c_algo_iop3xx_data *iop3xx_adap)
+{
+	/* Follows devman 9.3 */
+	*iop3xx_adap->biu->CR = IOP321_ICR_UNIT_RESET;
+	*iop3xx_adap->biu->SR = IOP321_ISR_CLEARBITS;
+	*iop3xx_adap->biu->CR = 0;
+} 
+
+static inline void iop3xx_adap_set_slave_addr(struct i2c_algo_iop3xx_data *iop3xx_adap)
+{
+	*iop3xx_adap->biu->SAR = MYSAR;
+}
+
+static inline void iop3xx_adap_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
+{
+	u32 cr = IOP321_ICR_GCD|IOP321_ICR_SCLEN|IOP321_ICR_UE;
+
+	/* NB SR bits not same position as CR IE bits :-( */
+	iop3xx_adap->biu->SR_enabled = 
+		IOP321_ISR_ALD | IOP321_ISR_BERRD |
+		IOP321_ISR_RXFULL | IOP321_ISR_TXEMPTY;
+
+	cr |= IOP321_ICR_ALDIE | IOP321_ICR_BERRIE |
+		IOP321_ICR_RXFULLIE | IOP321_ICR_TXEMPTYIE;
+
+	*iop3xx_adap->biu->CR = cr;
+}
+
+static void iop3xx_adap_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
+{
+	unsigned cr = *iop3xx_adap->biu->CR;
+	
+	cr &= ~(IOP321_ICR_MSTART | IOP321_ICR_TBYTE | 
+		IOP321_ICR_MSTOP | IOP321_ICR_SCLEN);
+	*iop3xx_adap->biu->CR = cr;
+}
+
+static void iop3xx_adap_final_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
+{
+	unsigned cr = *iop3xx_adap->biu->CR;
+	
+	cr &= ~(IOP321_ICR_ALDIE | IOP321_ICR_BERRIE |
+		IOP321_ICR_RXFULLIE | IOP321_ICR_TXEMPTYIE);
+	iop3xx_adap->biu->SR_enabled = 0;
+	*iop3xx_adap->biu->CR = cr;
+}
+
+/* 
+ * NB: the handler has to clear the source of the interrupt! 
+ * Then it passes the SR flags of interest to BH via adap data
+ */
+static void iop3xx_i2c_handler(int this_irq, 
+				void *dev_id, 
+				struct pt_regs *regs) 
+{
+	struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id;
+
+	u32 sr = *iop3xx_adap->biu->SR;
+
+	if ((sr &= iop3xx_adap->biu->SR_enabled)) {
+		*iop3xx_adap->biu->SR = sr;
+		iop3xx_adap->biu->SR_received |= sr;
+		wake_up_interruptible(&iop3xx_adap->waitq);
+	}
+}
+
+/* check all error conditions, clear them , report most important */
+static int iop3xx_adap_error(u32 sr)
+{
+	int rc = 0;
+
+	if ((sr&IOP321_ISR_BERRD)) {
+		if ( !rc ) rc = -I2C_ERR_BERR;
+	}
+	if ((sr&IOP321_ISR_ALD)) {
+		if ( !rc ) rc = -I2C_ERR_ALD;		
+	}
+	return rc;	
+}
+
+static inline u32 get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap)
+{
+	unsigned long flags;
+	u32 sr;
+
+	spin_lock_irqsave(&iop3xx_adap->lock, flags);
+	sr = iop3xx_adap->biu->SR_received;
+	iop3xx_adap->biu->SR_received = 0;
+	spin_unlock_irqrestore(&iop3xx_adap->lock, flags);
+
+	return sr;
+}
+
+/*
+ * sleep until interrupted, then recover and analyse the SR
+ * saved by handler
+ */
+typedef int (* compare_func)(unsigned test, unsigned mask);
+/* returns 1 on correct comparison */
+
+static int iop3xx_adap_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, 
+				  unsigned flags, unsigned* status,
+				  compare_func compare)
+{
+	unsigned sr = 0;
+	int interrupted;
+	int done;
+	int rc = 0;
+
+	do {
+		interrupted = wait_event_interruptible_timeout (
+			iop3xx_adap->waitq,
+			(done = compare( sr = get_srstat(iop3xx_adap),flags )),
+			iop3xx_adap->timeout
+			);
+		if ((rc = iop3xx_adap_error(sr)) < 0) {
+			*status = sr;
+			return rc;
+		}else if (!interrupted) {
+			*status = sr;
+			return -ETIMEDOUT;
+		}
+	} while(!done);
+
+	*status = sr;
+
+	return 0;
+}
+
+/*
+ * Concrete compare_funcs 
+ */
+static int all_bits_clear(unsigned test, unsigned mask)
+{
+	return (test & mask) == 0;
+}
+static int any_bits_set(unsigned test, unsigned mask)
+{
+	return (test & mask) != 0;
+}
+
+static int iop3xx_adap_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
+{
+	return iop3xx_adap_wait_event( 
+		iop3xx_adap, 
+	        IOP321_ISR_TXEMPTY|IOP321_ISR_ALD|IOP321_ISR_BERRD,
+		status, any_bits_set);
+}
+
+static int iop3xx_adap_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
+{
+	return iop3xx_adap_wait_event( 
+		iop3xx_adap, 
+		IOP321_ISR_RXFULL|IOP321_ISR_ALD|IOP321_ISR_BERRD,
+		status,	any_bits_set);
+}
+
+static int iop3xx_adap_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
+{
+	return iop3xx_adap_wait_event( 
+		iop3xx_adap, IOP321_ISR_UNITBUSY, status, all_bits_clear);
+}
+
+/*
+ * Description: This performs the IOP3xx initialization sequence
+ * Valid for IOP321. Maybe valid for IOP310?.
+ */
+static int iop3xx_adap_init (struct i2c_algo_iop3xx_data *iop3xx_adap)
+{
+	*IOP321_GPOD &= ~(iop3xx_adap->channel==0 ?
+			  IOP321_GPOD_I2C0:
+			  IOP321_GPOD_I2C1);
+
+	iop3xx_adap_reset(iop3xx_adap);
+	iop3xx_adap_set_slave_addr(iop3xx_adap);
+	iop3xx_adap_enable(iop3xx_adap);
+	
+        return 0;
+}
+
+static int iop3xx_adap_send_target_slave_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
+					      struct i2c_msg* msg)
+{
+	unsigned cr = *iop3xx_adap->biu->CR;
+	int status;
+	int rc;
+
+	*iop3xx_adap->biu->DBR = iic_cook_addr(msg);
+	
+	cr &= ~(IOP321_ICR_MSTOP | IOP321_ICR_NACK);
+	cr |= IOP321_ICR_MSTART | IOP321_ICR_TBYTE;
+
+	*iop3xx_adap->biu->CR = cr;
+	rc = iop3xx_adap_wait_tx_done(iop3xx_adap, &status);
+	/* this assert fires every time, contrary to IOP manual	
+	PASSERT((status&IOP321_ISR_UNITBUSY)!=0);
+	*/
+	PASSERT((status&IOP321_ISR_RXREAD)==0);
+	     
+	return rc;
+}
+
+static int iop3xx_adap_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte, int stop)
+{
+	unsigned cr = *iop3xx_adap->biu->CR;
+	int status;
+	int rc = 0;
+
+	*iop3xx_adap->biu->DBR = byte;
+	cr &= ~IOP321_ICR_MSTART;
+	if (stop) {
+		cr |= IOP321_ICR_MSTOP;
+	} else {
+		cr &= ~IOP321_ICR_MSTOP;
+	}
+	*iop3xx_adap->biu->CR = cr |= IOP321_ICR_TBYTE;
+	rc = iop3xx_adap_wait_tx_done(iop3xx_adap, &status);
+
+	return rc;
+} 
+
+static int iop3xx_adap_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap,
+				 char* byte, int stop)
+{
+	unsigned cr = *iop3xx_adap->biu->CR;
+	int status;
+	int rc = 0;
+
+	cr &= ~IOP321_ICR_MSTART;
+
+	if (stop) {
+		cr |= IOP321_ICR_MSTOP|IOP321_ICR_NACK;
+	} else {
+		cr &= ~(IOP321_ICR_MSTOP|IOP321_ICR_NACK);
+	}
+	*iop3xx_adap->biu->CR = cr |= IOP321_ICR_TBYTE;
+
+	rc = iop3xx_adap_wait_rx_done(iop3xx_adap, &status);
+
+	*byte = *iop3xx_adap->biu->DBR;
+
+    
+	return rc;
+}
+
+static int iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, 
+				 const char *buf, int count)
+{
+	struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
+	int ii;
+	int rc = 0;
+    	int ret = 0;
+
+	for (ii = 0; rc == 0 && ii != count; ++ii) {
+		rc = iop3xx_adap_write_byte(iop3xx_adap, buf[ii], ii==count-1);
+	}
+	return rc;
+}
+
+static int iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, 
+				char *buf, int count)
+{
+	struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
+	int ii;
+	int rc = 0;
+	int ret = 0;
+
+	for (ii = 0; rc == 0 && ii != count; ++ii) {
+		rc = iop3xx_adap_read_byte(iop3xx_adap, &buf[ii], ii==count-1);
+	}
+	return rc;
+}
+
+/*
+ * Description:  This function implements combined transactions.  Combined
+ * transactions consist of combinations of reading and writing blocks of data.
+ * FROM THE SAME ADDRESS
+ * Each transfer (i.e. a read or a write) is separated by a repeated start
+ * condition.
+ */
+static int iop3xx_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg) 
+{
+	struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
+	int rc;
+
+	rc = iop3xx_adap_send_target_slave_addr(iop3xx_adap, pmsg);
+	if (rc < 0) {
+		return rc;
+	}
+
+	if ((pmsg->flags&I2C_M_RD)) {
+		return iop3xx_i2c_readbytes(i2c_adap, pmsg->buf, pmsg->len);
+	} else {
+		return iop3xx_i2c_writebytes(i2c_adap, pmsg->buf, pmsg->len);
+	}
+}
+
+/*
+ * master_xfer() - main read/write entry
+ */
+static int iop3xx_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
+{
+	struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
+	int im = 0;
+	int ret = 0;
+	int status;
+
+	iop3xx_adap_wait_idle(iop3xx_adap, &status);
+	iop3xx_adap_reset(iop3xx_adap);
+	iop3xx_adap_enable(iop3xx_adap);
+
+	for (im = 0; ret == 0 && im != num; im++) {
+		ret = iop3xx_handle_msg(i2c_adap, &msgs[im]);
+	}
+
+	iop3xx_adap_transaction_cleanup(iop3xx_adap);
+
+	if(ret)
+		return ret;
+
+	return im;   
+}
+
+static int algo_control(struct i2c_adapter *adapter, unsigned int cmd,
+			unsigned long arg)
+{
+	return 0;
+}
+
+static u32 iic_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+
+/* -----exported algorithm data: -------------------------------------	*/
+
+static struct i2c_algorithm iic_algo = {
+	.name		= "IOP3xx I2C algorithm",
+	.id		= I2C_ALGO_OCP_IOP3XX,
+	.master_xfer	= iop3xx_master_xfer,
+	.algo_control	= algo_control,
+	.functionality	= iic_func,
+};
+
+/* 
+ * registering functions to load algorithms at runtime 
+ */
+static int i2c_iop3xx_add_bus(struct i2c_adapter *iic_adap)
+{
+	struct i2c_algo_iop3xx_data *iop3xx_adap = iic_adap->algo_data;
+
+	if (!request_region( REGION_START(iop3xx_adap), 
+			      REGION_LENGTH(iop3xx_adap),
+			      iic_adap->name)) {
+		return -ENODEV;
+	}
+
+	init_waitqueue_head(&iop3xx_adap->waitq);
+	spin_lock_init(&iop3xx_adap->lock);
+
+	if (request_irq( 
+		     iop3xx_adap->biu->irq,
+		     iop3xx_i2c_handler,
+		     /* SA_SAMPLE_RANDOM */ 0,
+		     iic_adap->name,
+		     iop3xx_adap)) {
+		return -ENODEV;
+	}			  
+
+	/* register new iic_adapter to i2c module... */
+	iic_adap->id |= iic_algo.id;
+	iic_adap->algo = &iic_algo;
+
+	iic_adap->timeout = 100;	/* default values, should */
+	iic_adap->retries = 3;		/* be replaced by defines */
+
+	iop3xx_adap_init(iic_adap->algo_data);
+	i2c_add_adapter(iic_adap);
+	return 0;
+}
+
+static int i2c_iop3xx_del_bus(struct i2c_adapter *iic_adap)
+{
+	struct i2c_algo_iop3xx_data *iop3xx_adap = iic_adap->algo_data;
+
+	iop3xx_adap_final_cleanup(iop3xx_adap);
+	free_irq(iop3xx_adap->biu->irq, iop3xx_adap);
+
+	release_region(REGION_START(iop3xx_adap), REGION_LENGTH(iop3xx_adap));
+
+	return i2c_del_adapter(iic_adap);
+}
+
+#ifdef CONFIG_ARCH_IOP321
+
+static struct iop3xx_biu biu0 = {
+	.CR	= IOP321_I2C_ICR0,
+	.SR	= IOP321_I2C_ISR0,
+	.SAR	= IOP321_I2C_ISAR0,
+	.DBR	= IOP321_I2C_IDBR0,
+	.BMR	= IOP321_I2C_IBMR0,
+	.irq	= IRQ_IOP321_I2C_0,
+};
+
+static struct iop3xx_biu biu1 = {
+	.CR	= IOP321_I2C_ICR1,
+	.SR	= IOP321_I2C_ISR1,
+	.SAR	= IOP321_I2C_ISAR1,
+	.DBR	= IOP321_I2C_IDBR1,
+	.BMR	= IOP321_I2C_IBMR1,
+	.irq	= IRQ_IOP321_I2C_1,
+};
+
+#define ADAPTER_NAME_ROOT "IOP321 i2c biu adapter "
+#else
+#error Please define the BIU struct iop3xx_biu for your processor arch
+#endif
+
+static struct i2c_algo_iop3xx_data algo_iop3xx_data0 = {
+	.channel		= 0,
+	.biu			= &biu0,
+	.timeout		= 1*HZ,
+};
+static struct i2c_algo_iop3xx_data algo_iop3xx_data1 = {
+	.channel		= 1,
+	.biu			= &biu1,
+	.timeout		= 1*HZ,
+};
+
+static struct i2c_adapter iop3xx_ops0 = {
+	.name			= ADAPTER_NAME_ROOT "0",
+	.id			= I2C_HW_IOP321,
+	.algo			= NULL,
+	.algo_data		= &algo_iop3xx_data0,
+};
+static struct i2c_adapter iop3xx_ops1 = {
+	.name			= ADAPTER_NAME_ROOT "1",
+	.id			= I2C_HW_IOP321,
+	.algo			= NULL,
+	.algo_data		= &algo_iop3xx_data1,
+};
+
+static int __init i2c_iop3xx_init (void)
+{
+	return i2c_iop3xx_add_bus(&iop3xx_ops0) ||
+		i2c_iop3xx_add_bus(&iop3xx_ops1);
+}
+
+static void __exit i2c_iop3xx_exit (void)
+{
+	i2c_iop3xx_del_bus(&iop3xx_ops0);
+	i2c_iop3xx_del_bus(&iop3xx_ops1);
+}
+
+module_init (i2c_iop3xx_init);
+module_exit (i2c_iop3xx_exit);
+
+MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>");
+MODULE_DESCRIPTION("IOP3xx iic algorithm and driver");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(i2c_debug,"i");
+
+MODULE_PARM_DESC(i2c_debug, "debug level - 0 off; 1 normal; 2,3 more verbose; 9 iic-protocol");
+
diff -urN linux-2.4.29/drivers/i2c/i2c-iop3xx.h linux-2.4.29-uc1/drivers/i2c/i2c-iop3xx.h
--- linux-2.4.29/drivers/i2c/i2c-iop3xx.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/i2c-iop3xx.h	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,118 @@
+/* ------------------------------------------------------------------------- */
+/* i2c-iop3xx.h algorithm driver definitions private to i2c-iop3xx.c         */
+/* ------------------------------------------------------------------------- */
+/*   Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd
+ *                      <Peter dot Milne at D hyphen TACQ dot com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, version 2.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.                */
+/* ------------------------------------------------------------------------- */
+
+
+#ifndef I2C_IOP3XX_H
+#define I2C_IOP3XX_H 1
+
+/*
+ * iop321 hardware bit definitions
+ */
+#define IOP321_ICR_FAST_MODE	0x8000	/* 1=400kBps, 0=100kBps */
+#define IOP321_ICR_UNIT_RESET	0x4000	/* 1=RESET */
+#define IOP321_ICR_SADIE	0x2000	/* 1=Slave Detect Interrupt Enable */
+#define IOP321_ICR_ALDIE	0x1000	/* 1=Arb Loss Detect Interrupt Enable */
+#define IOP321_ICR_SSDIE	0x0800	/* 1=Slave STOP Detect Interrupt Enable */
+#define IOP321_ICR_BERRIE	0x0400	/* 1=Bus Error Interrupt Enable */
+#define IOP321_ICR_RXFULLIE	0x0200	/* 1=Receive Full Interrupt Enable */
+#define IOP321_ICR_TXEMPTYIE	0x0100	/* 1=Transmit Empty Interrupt Enable */
+#define IOP321_ICR_GCD		0x0080	/* 1=General Call Disable */
+/*
+ * IOP321_ICR_GCD: 1 disables response as slave. "This bit must be set
+ * when sending a master mode general call message from the I2C unit"
+ */
+#define IOP321_ICR_UE		0x0040	/* 1=Unit Enable */
+/*
+ * "NOTE: To avoid I2C bus integrity problems, 
+ * the user needs to ensure that the GPIO Output Data Register - 
+ * GPOD bits associated with an I2C port are cleared prior to setting 
+ * the enable bit for that I2C serial port. 
+ * The user prepares to enable I2C port 0 and 
+ * I2C port 1 by clearing GPOD bits 7:6 and GPOD bits 5:4, respectively.
+ */
+#define IOP321_ICR_SCLEN	0x0020	/* 1=SCL enable for master mode */
+#define IOP321_ICR_MABORT	0x0010	/* 1=Send a STOP with no data 
+					 * NB TBYTE must be clear */
+#define IOP321_ICR_TBYTE	0x0008	/* 1=Send/Receive a byte. i2c clears */
+#define IOP321_ICR_NACK		0x0004	/* 1=reply with NACK */
+#define IOP321_ICR_MSTOP	0x0002	/* 1=send a STOP after next data byte */
+#define IOP321_ICR_MSTART	0x0001	/* 1=initiate a START */
+
+
+#define IOP321_ISR_BERRD	0x0400	/* 1=BUS ERROR Detected */
+#define IOP321_ISR_SAD		0x0200	/* 1=Slave ADdress Detected */
+#define IOP321_ISR_GCAD		0x0100	/* 1=General Call Address Detected */
+#define IOP321_ISR_RXFULL	0x0080	/* 1=Receive Full */
+#define IOP321_ISR_TXEMPTY	0x0040	/* 1=Transmit Empty */
+#define IOP321_ISR_ALD		0x0020	/* 1=Arbitration Loss Detected */
+#define IOP321_ISR_SSD		0x0010	/* 1=Slave STOP Detected */
+#define IOP321_ISR_BBUSY	0x0008	/* 1=Bus BUSY */
+#define IOP321_ISR_UNITBUSY	0x0004	/* 1=Unit Busy */
+#define IOP321_ISR_NACK		0x0002	/* 1=Unit Rx or Tx a NACK */
+#define IOP321_ISR_RXREAD	0x0001	/* 1=READ 0=WRITE (R/W bit of slave addr */
+
+#define IOP321_ISR_CLEARBITS	0x07f0
+
+#define IOP321_ISAR_SAMASK	0x007f
+
+#define IOP321_IDBR_MASK	0x00ff
+
+#define IOP321_IBMR_SCL		0x0002
+#define IOP321_IBMR_SDA		0x0001
+
+#define IOP321_GPOD_I2C0	0x00c0	/* clear these bits to enable ch0 */
+#define IOP321_GPOD_I2C1	0x0030	/* clear these bits to enable ch1 */
+
+#define MYSAR			0x02	/* SWAG a suitable slave address */
+
+#define I2C_ERR			321
+#define I2C_ERR_BERR		(I2C_ERR+0)
+#define I2C_ERR_ALD		(I2C_ERR+1)
+
+
+struct iop3xx_biu {                /* Bus Interface Unit - the hardware */
+/* physical hardware defs - regs*/
+	u32 *CR;
+	u32 *SR;
+	u32 *SAR;
+	u32 *DBR;
+	u32 *BMR;
+/* irq bit vector */
+	u32 irq;
+/* stored flags */
+	u32 SR_enabled, SR_received;
+};
+
+struct i2c_algo_iop3xx_data {
+	int channel;
+
+	wait_queue_head_t waitq;
+	spinlock_t lock;
+	int timeout;
+	struct iop3xx_biu* biu;
+};
+
+#define REGION_START(adap)	((u32)((adap)->biu->CR))
+#define REGION_END(adap)	((u32)((adap)->biu->BMR+1))
+#define REGION_LENGTH(adap)	(REGION_END(adap)-REGION_START(adap))
+
+#define IRQ_STATUS_MASK(adap)	(1<<adap->biu->irq)
+
+#endif /* I2C_IOP3XX_H */
diff -urN linux-2.4.29/drivers/i2c/i2c-omaha.c linux-2.4.29-uc1/drivers/i2c/i2c-omaha.c
--- linux-2.4.29/drivers/i2c/i2c-omaha.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/i2c-omaha.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,276 @@
+/* ------------------------------------------------------------------------- *
+    Copyright ARM Limited 2002. All rights reserved.
+ 
+    i2c driver for Omaha					     
+ 
+    Notes:Based on i2c-elv.c
+ 
+    The S3C2400X01 has better support for I2C, but bit oriented operations 
+    are directly supported by the other I2C layers, so we use that method
+    of performing I2C operations.
+
+    Copyright (C) 1995-2000 Simon G. Vogl
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.		     */
+/* ------------------------------------------------------------------------- */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+/* ----- global defines ----------------------------------------------- */
+#define DEB(x) if (i2c_debug>=1) x;
+#define DEB2(x) if (i2c_debug>=2) x;
+#define DEB3(x) if (i2c_debug>=3) x
+#define DEBE(x)	x	// error messages
+#define DEBSTAT(x) if (i2c_debug>=3) x; /* print several statistical values*/
+#define DEBPROTO(x) if (i2c_debug>=9) { x; }
+ 	/* debug the protocol by showing transferred bits */
+
+/* Register and bitdefs for Omaha */
+
+// Port G control registers
+static volatile unsigned int pgcon = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_PGCON);
+static volatile unsigned int pgdat = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_PGDAT);
+
+static volatile unsigned int opencr = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_OPENCR);
+
+static int base = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_PGCON);
+
+// Open drain control registers
+#define OPC_CMD		BIT2
+#define OPC_DAT		BIT3
+
+// data bits in GPIO Port G data register
+#define OMAHA_SDA	BIT5
+#define OMAHA_SCL	BIT6
+#define IIC_WP		BIT3	// Write Protect for EEPROM
+
+// input/out select bits in GPIO G control register
+#define IIC_BITS	(BIT12|BIT10|BIT6);
+
+
+/* ----- local functions ----------------------------------------------	*/
+
+
+static void bit_omaha_setscl(void *data, int state)
+{
+	unsigned int tmp;
+	
+	if (state)
+	{
+		tmp = __raw_readl(pgdat);
+		tmp |= OMAHA_SCL;
+		__raw_writel(tmp,pgdat);
+	}
+	else
+	{
+		tmp = __raw_readl(pgdat);
+		tmp &= ~OMAHA_SCL;
+		__raw_writel(tmp,pgdat);
+	}
+}
+
+static void bit_omaha_setsda(void *data, int state)
+{
+	unsigned int tmp;
+	
+	// ensure that sda is an output at the moment
+	tmp = __raw_readl(pgcon);
+	tmp = tmp | BIT10;
+	__raw_writel(tmp,pgcon);
+		
+	if (state)
+	{
+		tmp = __raw_readl(pgdat);
+		tmp |= OMAHA_SDA;
+		__raw_writel(tmp,pgdat);
+	}
+	else
+	{
+		tmp = __raw_readl(pgdat);
+		tmp &= ~OMAHA_SDA;
+		__raw_writel(tmp,pgdat);
+	}
+} 
+
+static int bit_omaha_getscl(void *data)
+{
+	if (__raw_readl(pgdat) & OMAHA_SCL)
+		return 1;
+	else
+		return 0;
+}
+
+static int bit_omaha_getsda(void *data)
+{
+	unsigned int tmp;
+	
+	// ensure that sda is an output at the moment
+	tmp = __raw_readl(pgcon);
+	tmp = tmp & ~BIT10;
+	__raw_writel(tmp,pgcon);
+	
+	if (__raw_readl(pgdat) & OMAHA_SDA)
+		return 1;
+	else
+		return 0;
+}
+
+static int bit_omaha_init(void)
+{
+	// Have we got some mmapped space?
+	if (request_region(base, 0x100, "i2c (omaha bus adapter)") < 0 )
+	{
+		printk("i2c-omaha.o: requested I/O region (0x%08x) is in use.\n", base);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+
+static int bit_omaha_reg(struct i2c_client *client)
+{
+	return 0;
+}
+
+
+static int bit_omaha_unreg(struct i2c_client *client)
+{
+	return 0;
+}
+
+static void bit_omaha_inc_use(struct i2c_adapter *adap)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void bit_omaha_dec_use(struct i2c_adapter *adap)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+
+
+/* ------------------------------------------------------------------------
+ * Encapsulate the above functions in the correct operations structure.
+ * This is only done when more than one hardware adapter is supported.
+ */
+static struct i2c_algo_bit_data bit_omaha_data = {
+	NULL,
+	bit_omaha_setsda,
+	bit_omaha_setscl,
+	bit_omaha_getsda,
+	bit_omaha_getscl,
+	10, 10, 20,		/*	waits, timeout */
+};
+
+static struct i2c_adapter bit_omaha_ops = {
+	"BIT-Type Omaha I2C adapter",
+	I2C_HW_B_OMAHA,
+	NULL,
+	&bit_omaha_data,
+	bit_omaha_inc_use,
+	bit_omaha_dec_use,
+	bit_omaha_reg,
+	bit_omaha_unreg,
+};     
+
+static int __init i2c_omaha_init (void)
+{
+	unsigned int tmp;
+
+	printk("i2c-omaha.o: i2c omaha adapter module\n");
+	
+	if (bit_omaha_init() == 0) {
+		if(i2c_bit_add_bus(&bit_omaha_ops) < 0)
+		{
+			printk("Could not add bus!\n");
+			return -ENODEV;
+		}
+	} else {
+		printk("Could not pcf_omaha_init\n");
+		return -ENODEV;
+	}	
+	
+	// Program Port G bits to output function
+	tmp = __raw_readl(pgcon);
+	tmp |= IIC_BITS;	   	
+	__raw_writel(tmp,pgcon);
+	
+	// Ensure SDA and SCL are open-drain
+	tmp = __raw_readl(opencr);
+	tmp = tmp | OPC_CMD | OPC_DAT;
+	__raw_writel(tmp,opencr);
+
+	bit_omaha_setsda((void*)base,1);
+	bit_omaha_setscl((void*)base,1);
+
+	// Disable WP
+	tmp = __raw_readl(pgdat);
+	tmp = tmp & ~IIC_WP;
+	__raw_writel(tmp,pgdat);
+			       		
+	return 0;
+}
+
+static void bit_omaha_exit(void)
+{
+	release_region(base , 2);
+}
+
+static void i2c_omaha_exit(void)
+{
+
+	i2c_bit_del_bus(&bit_omaha_ops);
+
+	bit_omaha_exit();
+
+}
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("ARM Limited <support@arm.com>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for Omaha");
+MODULE_LICENSE("GPL");
+			
+MODULE_PARM(base, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(clock, "i");
+MODULE_PARM(own, "i");
+MODULE_PARM(mmapped, "i");
+MODULE_PARM(i2c_debug, "i");
+
+
+module_init(i2c_omaha_init);
+module_exit(i2c_omaha_exit);
+
+
diff -urN linux-2.4.29/drivers/i2c/Makefile linux-2.4.29-uc1/drivers/i2c/Makefile
--- linux-2.4.29/drivers/i2c/Makefile	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/i2c/Makefile	2005-06-14 02:12:19.000000000 +0100
@@ -7,13 +7,26 @@
 export-objs	:= i2c-core.o i2c-algo-bit.o i2c-algo-pcf.o \
 		   i2c-algo-ite.o i2c-algo-sibyte.o i2c-algo-sgi.o \
 		   i2c-proc.o
+mod-subdirs	:= xilinx_iic
 
 obj-$(CONFIG_I2C)		+= i2c-core.o
 obj-$(CONFIG_I2C_CHARDEV)	+= i2c-dev.o
+
+# Bit adapters
 obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
 obj-$(CONFIG_I2C_PHILIPSPAR)	+= i2c-philips-par.o
 obj-$(CONFIG_I2C_ELV)		+= i2c-elv.o
 obj-$(CONFIG_I2C_VELLEMAN)	+= i2c-velleman.o
+obj-$(CONFIG_I2C_GUIDE)		+= i2c-guide.o
+obj-$(CONFIG_I2C_FRODO)		+= i2c-frodo.o
+obj-$(CONFIG_I2C_OMAHA)		+= i2c-omaha.o
+obj-$(CONFIG_I2C_IXP2000)	+= i2c-adap-ixp2000.o
+obj-$(CONFIG_I2C_IXP425) 	+= i2c-adap-ixp425.o 
+obj-$(CONFIG_I2C_MCF_GPIO)	+= i2c-adap-mcf_gpio.o
+obj-$(CONFIG_I2C_NETARM_GPIO)	+= i2c-adap-netarm_gpio.o
+obj-$(CONFIG_I2C_MAX1617)	+= i2c-max1617.o
+
+# PCF adapters
 obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
 obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
 obj-$(CONFIG_ITE_I2C_ALGO)	+= i2c-algo-ite.o
@@ -22,10 +35,14 @@
 obj-$(CONFIG_SCx200_I2C)	+= scx200_i2c.o
 obj-$(CONFIG_SCx200_ACB)	+= scx200_acb.o
 obj-$(CONFIG_I2C_KEYWEST)	+= i2c-keywest.o
+obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
 obj-$(CONFIG_I2C_ALGO_SIBYTE)	+= i2c-algo-sibyte.o i2c-sibyte.o
 obj-$(CONFIG_I2C_MAX1617)	+= i2c-max1617.o
 obj-$(CONFIG_I2C_ALGO_SGI)	+= i2c-algo-sgi.o
 
+subdir-$(CONFIG_I2C_XILINX)	+= xilinx_iic
+obj-$(CONFIG_I2C_XILINX)	+= xilinx_iic/xilinx_iic.o
+
 # This is needed for automatic patch generation: sensors code starts here
 # This is needed for automatic patch generation: sensors code ends here
 
diff -urN linux-2.4.29/drivers/i2c/xilinx_iic/i2c-algo-xilinx.c linux-2.4.29-uc1/drivers/i2c/xilinx_iic/i2c-algo-xilinx.c
--- linux-2.4.29/drivers/i2c/xilinx_iic/i2c-algo-xilinx.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/xilinx_iic/i2c-algo-xilinx.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,546 @@
+/*
+ * i2c-algo-xilinx.c
+ *
+ * Xilinx IIC Adapter component to interface IIC component to Linux
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under the terms
+ * of the GNU General Public License version 2.  This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+/*
+ * I2C drivers are split into two pieces: the adapter and the algorithm.
+ * The adapter is responsible for actually manipulating the hardware and
+ * the algorithm is the layer above that that handles the higher level
+ * tasks such as transmitting or receiving a buffer.  The best example
+ * (in my opinion) of this is the bit banging algorithm has a number of
+ * different adapters that can plug in under it to actually wiggle the
+ * SDA and SCL.
+ *
+ * The interesting part is that the drivers Xilinx provides with their
+ * IP are also split into two pieces where one part is the OS
+ * independent code and the other part is the OS dependent code.  All of
+ * the other sources in this directory are the OS independent files as
+ * provided by Xilinx with no changes made to them.
+ *
+ * As it turns out, this maps quite well into the I2C driver philosophy.
+ * This file is the I2C algorithm that communicates with the Xilinx OS
+ * independent function that will serve as our I2C adapter.  The
+ * unfortunate part is that the term "adapter" is overloaded in our
+ * context.  Xilinx refers to the OS dependent part of a driver as an
+ * adapter.  So from an I2C driver perspective, this file is not an
+ * adapter; that role is filled by the Xilinx OS independent files.
+ * From a Xilinx perspective, this file is an adapter; it adapts their
+ * OS independent code to Linux.
+ *
+ * Another thing to consider is that the Xilinx OS dependent code knows
+ * nothing about Linux I2C adapters, so even though this file is billed
+ * as the I2C algorithm, it takes care of the i2c_adapter structure.
+ *
+ * Fortunately, naming conventions will give you a clue as to what comes
+ * from where.  Functions beginning with XIic_ are provided by the
+ * Xilinx OS independent files.  Functions beginning with i2c_ are
+ * provided by the I2C Linux core.  All functions in this file that are
+ * called by Linux have names that begin with xiic_.  The functions in
+ * this file that have Handler in their name are registered as callbacks
+ * with the underlying Xilinx OS independent layer.  Any other functions
+ * are static helper functions.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/i2c.h>
+
+#include <xbasic_types.h>
+#include "xiic.h"
+#include "xiic_i.h"
+
+MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
+MODULE_DESCRIPTION("Xilinx IIC driver");
+MODULE_LICENSE("GPL");
+MODULE_PARM(scan, "i");
+MODULE_PARM_DESC(scan, "Scan for active chips on the bus");
+static int scan = 0;		/* have a look at what's hanging 'round */
+
+/* SAATODO: actually use these? */
+#define XIIC_TIMEOUT		100
+#define XIIC_RETRY		3
+
+/* Our private per device data. */
+struct xiic_dev {
+	struct i2c_adapter adap;	/* The Linux I2C core data  */
+	struct xiic_dev *next_dev;	/* The next device in dev_list */
+	struct completion complete;	/* for waiting for interrupts */
+	int index;		/* Which interface is this */
+	u32 save_BaseAddress;	/* Saved physical base address */
+	unsigned int irq;	/* device IRQ number    */
+	/*
+	 * The underlying OS independent code needs space as well.  A
+	 * pointer to the following XIic structure will be passed to
+	 * any XIic_ function that requires it.  However, we treat the
+	 * data as an opaque object in this file (meaning that we never
+	 * reference any of the fields inside of the structure).
+	 */
+	XIic Iic;
+	XStatus interrupt_status;
+	/*
+	 * The following bit fields are used to keep track of what
+	 * all has been done to initialize the xiic_dev to make
+	 * error handling out of probe() easier.
+	 */
+	unsigned int reqirq:1;	/* Has request_irq() been called? */
+	unsigned int remapped:1;	/* Has ioremap() been called? */
+	unsigned int started:1;	/* Has XIic_Start() been called? */
+	unsigned int added:1;	/* Has i2c_add_adapter() been called? */
+};
+
+/* List of devices we're handling and a lock to give us atomic access. */
+static struct xiic_dev *dev_list = NULL;
+static spinlock_t dev_lock = SPIN_LOCK_UNLOCKED;
+
+/* SAATODO: This function will be moved into the Xilinx code. */
+/*****************************************************************************/
+/**
+*
+* Lookup the device configuration based on the iic instance.  The table
+* XIic_ConfigTable contains the configuration info for each device in the system.
+*
+* @param Instance is the index of the interface being looked up.
+*
+* @return
+*
+* A pointer to the configuration table entry corresponding to the given
+* device ID, or NULL if no match is found.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XIic_Config *XIic_GetConfig(int Instance)
+{
+	if (Instance < 0 || Instance >= CONFIG_XILINX_IIC_NUM_INSTANCES)
+	{
+		return NULL;
+	}
+
+	return &XIic_ConfigTable[Instance];
+}
+
+static int
+xiic_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
+{
+	struct xiic_dev *dev = (struct xiic_dev *) i2c_adap;
+	struct i2c_msg *pmsg;
+	u32 options;
+	int i, retries;
+	XStatus Status;
+
+	for (i = 0; i < num; i++) {
+		pmsg = &msgs[i];
+
+		if (!pmsg->len)	/* If length is zero */
+		     continue;	/* on to the next request. */
+
+		options = 0;
+		if (pmsg->flags & I2C_M_TEN)
+			options |= XII_SEND_10_BIT_OPTION;
+		if (i != num-1)
+			options |= XII_REPEATED_START_OPTION;
+		XIic_SetOptions(&dev->Iic, options);
+
+		if (XIic_SetAddress(&dev->Iic, XII_ADDR_TO_SEND_TYPE,
+				    pmsg->addr) != XST_SUCCESS) {
+			printk(KERN_WARNING
+			       "%s #%d: Could not set address to 0x%2x.\n",
+			       dev->adap.name, dev->index, pmsg->addr);
+			return -EIO;
+		}
+		dev->interrupt_status = ~(XStatus) 0;
+		/*
+		 * The Xilinx layer does not handle bus busy conditions yet
+		 * so this code retries a request up to 16 times if it
+		 * receives a bus busy condition.  If and when the underlying
+		 * code is enhanced, the retry code can be removed.
+		 */
+		retries = 16;
+		if (pmsg->flags & I2C_M_RD) {
+			while ((Status = XIic_MasterRecv(&dev->Iic,
+							 pmsg->buf, pmsg->len))
+			       == XST_IIC_BUS_BUSY && retries--) {
+				set_current_state(TASK_INTERRUPTIBLE);
+				schedule_timeout(HZ/10);
+			}
+		} else {
+			while ((Status = XIic_MasterSend(&dev->Iic,
+							 pmsg->buf, pmsg->len))
+			       == XST_IIC_BUS_BUSY && retries--) {
+				set_current_state(TASK_INTERRUPTIBLE);
+				schedule_timeout(HZ/10);
+			}
+		}
+		if (Status != XST_SUCCESS) {
+			printk(KERN_WARNING
+			       "%s #%d: Unexpected error %d.\n",
+			       dev->adap.name, dev->index, Status);
+			return -EIO;
+		}
+		printk("calling wait_for_completion\n");
+		wait_for_completion(&dev->complete);
+		if (dev->interrupt_status != XST_SUCCESS) {
+			printk(KERN_WARNING
+			       "%s #%d: Could not talk to device 0x%2x (%d).\n",
+			       dev->adap.name, dev->index, pmsg->addr,
+			       dev->interrupt_status);
+			return -EIO;
+		}
+	}
+	return num;
+}
+
+static int
+xiic_algo_control(struct i2c_adapter *adapter,
+		  unsigned int cmd, unsigned long arg)
+{
+	return 0;
+}
+
+static u32
+xiic_bit_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
+	    I2C_FUNC_PROTOCOL_MANGLING;
+}
+
+static struct i2c_algorithm xiic_algo = {
+	"Xilinx IIC algorithm",	/* name                 */
+	/*
+	 * SAATODO: Get a real ID (perhaps I2C_ALGO_XILINX) after
+	 * initial release.  Will need to email lm78@stimpy.netroedge.com
+	 * per http://www2.lm-sensors.nu/~lm78/support.html
+	 */
+	I2C_ALGO_EXP,		/* id                   */
+	xiic_xfer,		/* master_xfer          */
+	NULL,			/* smbus_xfer           */
+	NULL,			/* slave_send           */
+	NULL,			/* slave_recv           */
+	xiic_algo_control,	/* algo_control         */
+	xiic_bit_func,		/* functionality        */
+};
+
+/*
+ * This routine is registered with the OS as the function to call when
+ * the IIC interrupts.  It in turn, calls the Xilinx OS independent
+ * interrupt function.  The Xilinx OS independent interrupt function
+ * will in turn call any callbacks that we have registered for various
+ * conditions.
+ */
+static void
+xiic_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct xiic_dev *dev = dev_id;
+	printk("+");
+	XIic_InterruptHandler(&dev->Iic);
+}
+
+static void
+RecvHandler(void *CallbackRef, int ByteCount)
+{
+	struct xiic_dev *dev = (struct xiic_dev *) CallbackRef;
+
+	printk("r");
+	if (ByteCount == 0) {
+		dev->interrupt_status = XST_SUCCESS;
+		printk("R");
+		complete(&dev->complete);
+	}
+}
+static void
+SendHandler(void *CallbackRef, int ByteCount)
+{
+	struct xiic_dev *dev = (struct xiic_dev *) CallbackRef;
+
+	printk("s");
+	if (ByteCount == 0) {
+		dev->interrupt_status = XST_SUCCESS;
+		printk("S");
+		complete(&dev->complete);
+	}
+}
+static void
+StatusHandler(void *CallbackRef, XStatus Status)
+{
+	struct xiic_dev *dev = (struct xiic_dev *) CallbackRef;
+
+	printk("H");
+	dev->interrupt_status = Status;
+	complete(&dev->complete);
+}
+
+static void
+xiic_inc_use(struct i2c_adapter *adap)
+{
+#ifdef MODULE
+	MOD_INC_USE_COUNT;
+#endif
+}
+static void
+xiic_dec_use(struct i2c_adapter *adap)
+{
+#ifdef MODULE
+	MOD_DEC_USE_COUNT;
+#endif
+}
+
+static void
+remove_head_dev(void)
+{
+	struct xiic_dev *dev;
+	XIic_Config *cfg;
+
+	/* Pull the head off of dev_list. */
+	spin_lock(&dev_lock);
+	dev = dev_list;
+	dev_list = dev->next_dev;
+	spin_unlock(&dev_lock);
+
+	/*
+	 * If we've told the core I2C code about this dev, tell
+	 * the core I2C code to forget the dev.
+	 */
+	if (dev->added) {
+		/*
+		 * If an error is returned, there's not a whole lot we can
+		 * do.  An error has already been printed out so we'll
+		 * just keep trundling along.
+		 */
+		(void) i2c_del_adapter(&dev->adap);
+	}
+
+	/* Tell the Xilinx code to take this IIC interface down. */
+	if (dev->started) {
+		while (XIic_Stop(&dev->Iic) != XST_SUCCESS) {
+			/* The bus was busy.  Retry. */
+			printk(KERN_WARNING
+			       "%s #%d: Could not stop device.  Will retry.\n",
+			       dev->adap.name, dev->index);
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(HZ / 2);
+		}
+	}
+
+	/*
+	 * Now that the Xilinx code isn't using the IRQ or registers,
+	 * unmap the registers and free the IRQ.
+	 */
+	if (dev->remapped) {
+		cfg = XIic_GetConfig(dev->index);
+		iounmap((void *) cfg->BaseAddress);
+		cfg->BaseAddress = dev->save_BaseAddress;
+	};
+	if (dev->reqirq) {
+		disable_irq(dev->irq);
+		free_irq(dev->irq, dev);
+	}
+
+	kfree(dev);
+}
+
+static int __init
+probe(int index)
+{
+	static const unsigned long remap_size
+	    = CONFIG_XILINX_IIC_0_HIGHADDR - CONFIG_XILINX_IIC_0_BASEADDR + 1;
+	struct xiic_dev *dev;
+	XIic_Config *cfg;
+	unsigned int irq;
+	int retval;
+
+	switch (index) {
+#if defined(CONFIG_XILINX_IIC_0_INSTANCE)
+	case 0:
+		irq = CONFIG_XILINX_IIC_0_IRQ;
+		break;
+#endif
+#if defined(CONFIG_XILINX_IIC_1_INSTANCE)
+	case 1:
+		irq = CONFIG_XILINX_IIC_1_IRQ;
+		break;
+#endif
+#if defined(CONFIG_XILINX_IIC_2_INSTANCE)
+	case 2:
+		irq = CONFIG_XILINX_IIC_2_IRQ;
+		break;
+#endif
+#if defined(CONFIG_XILINX_IIC_3_INSTANCE)
+	case 3:
+		irq = CONFIG_XILINX_IIC_3_IRQ;
+		break;
+#endif
+	default:
+		return -ENODEV;
+	}
+
+	/* Find the config for our device. */
+	cfg = XIic_GetConfig(index);
+	if (!cfg)
+		return -ENODEV;
+
+	/* Allocate the dev and zero it out. */
+	dev = (struct xiic_dev *) kmalloc(sizeof (struct xiic_dev), GFP_KERNEL);
+	if (!dev) {
+		printk(KERN_ERR "%s #%d: Could not allocate device.\n",
+		       "Xilinx IIC adapter", index);
+		return -ENOMEM;
+	}
+	memset(dev, 0, sizeof (struct xiic_dev));
+	strcpy(dev->adap.name, "Xilinx IIC adapter");
+	dev->index = index;
+
+	/* Make it the head of dev_list. */
+	spin_lock(&dev_lock);
+	dev->next_dev = dev_list;
+	dev_list = dev;
+	spin_unlock(&dev_lock);
+
+	init_completion(&dev->complete);
+
+	/* Change the addresses to be virtual; save the old ones to restore. */
+	dev->save_BaseAddress = cfg->BaseAddress;
+	cfg->BaseAddress = (u32) ioremap(dev->save_BaseAddress, remap_size);
+	dev->remapped = 1;
+
+	/* Tell the Xilinx code to bring this IIC interface up. */
+	if (XIic_Initialize(&dev->Iic, cfg->DeviceId) != XST_SUCCESS) {
+		printk(KERN_ERR "%s #%d: Could not initialize device.\n",
+		       dev->adap.name, dev->index);
+		remove_head_dev();
+		return -ENODEV;
+	}
+	XIic_SetRecvHandler(&dev->Iic, (void *) dev, RecvHandler);
+	XIic_SetSendHandler(&dev->Iic, (void *) dev, SendHandler);
+	XIic_SetStatusHandler(&dev->Iic, (void *) dev, StatusHandler);
+
+	/* Grab the IRQ */
+	dev->irq = irq;
+	retval = request_irq(dev->irq, xiic_interrupt, 0, dev->adap.name, dev);
+	if (retval) {
+		printk(KERN_ERR "%s #%d: Could not allocate interrupt %d.\n",
+		       dev->adap.name, dev->index, dev->irq);
+		remove_head_dev();
+		return retval;
+	}
+	dev->reqirq = 1;
+
+	if (XIic_Start(&dev->Iic) != XST_SUCCESS) {
+		printk(KERN_ERR "%s #%d: Could not start device.\n",
+		       dev->adap.name, dev->index);
+		remove_head_dev();
+		return -ENODEV;
+	}
+	dev->started = 1;
+
+	/* Now tell the core I2C code about our new device. */
+	/*
+	 * SAATODO: Get a real ID (perhaps I2C_HW_XILINX) after
+	 * initial release.  Will need to email lm78@stimpy.netroedge.com
+	 * per http://www2.lm-sensors.nu/~lm78/support.html
+	 */
+	dev->adap.id = xiic_algo.id | I2C_DRIVERID_EXP0;
+	dev->adap.algo = &xiic_algo;
+	dev->adap.algo_data = NULL;
+	dev->adap.inc_use = xiic_inc_use;
+	dev->adap.dec_use = xiic_dec_use;
+	dev->adap.timeout = XIIC_TIMEOUT;
+	dev->adap.retries = XIIC_RETRY;
+	retval = i2c_add_adapter(&dev->adap);
+	if (retval) {
+		printk(KERN_ERR "%s #%d: Could not add I2C adapter.\n",
+		       dev->adap.name, dev->index);
+		remove_head_dev();
+		return retval;
+	}
+	dev->added = 1;
+
+	printk(KERN_INFO "%s #%d at 0x%08X mapped to 0x%08X, irq=%d\n",
+	       dev->adap.name, dev->index,
+	       dev->save_BaseAddress, cfg->BaseAddress, dev->irq);
+
+	/* scan bus */
+	if (scan) {
+		int i, anyfound;
+
+		printk(KERN_INFO "%s #%d Bus scan:",
+		       dev->adap.name, dev->index);
+		/*
+		 * The Philips I2C-bus specification defines special addresses:
+		 *      0x00       General Call
+		 *      0x01       CBUS Address
+		 *      0x02       Reserved for different bus format
+		 *      0x03       Reserved for future purposes
+		 *   0x04 to 0x07  Hs-mode master code
+		 *   0x78 to 0x7B  10-bit slave addressing
+		 *   0x7C to 0x7F  Reserved for future purposes
+		 *
+		 * We don't bother scanning any of these addresses.
+		 */
+		anyfound = 0;
+		for (i = 0x08; i < 0x78; i++) {
+			u8 data;
+			XStatus Status;
+
+			if (XIic_SetAddress(&dev->Iic, XII_ADDR_TO_SEND_TYPE,
+					    i) != XST_SUCCESS) {
+				printk(KERN_WARNING
+				       "%s #%d: Could not set address to %2x.\n",
+				       dev->adap.name, dev->index, i);
+				continue;
+			}
+			dev->interrupt_status = ~(XStatus) 0;
+			Status = XIic_MasterRecv(&dev->Iic, &data, 1);
+			if (Status != XST_SUCCESS) {
+				printk(KERN_WARNING
+				       "%s #%d: Unexpected error %d.\n",
+				       dev->adap.name, dev->index, Status);
+				continue;
+			}
+			printk("calling wait for completion\n");
+			wait_for_completion(&dev->complete);
+			if (dev->interrupt_status == XST_SUCCESS) {
+				printk(" 0x%02x", i);
+				anyfound = 1;
+			}
+		}
+		printk(anyfound ? " responded.\n" : " Nothing responded.\n");
+	}
+
+	return 0;
+}
+static int __init
+xiic_init(void)
+{
+	int index = 0;
+
+	while (probe(index++) == 0) ;
+	/* If we found at least one, report success. */
+	return (index > 1) ? 0 : -ENODEV;
+}
+
+static void __exit
+xiic_cleanup(void)
+{
+	while (dev_list)
+		remove_head_dev();
+}
+
+EXPORT_NO_SYMBOLS;
+
+module_init(xiic_init);
+module_exit(xiic_cleanup);
diff -urN linux-2.4.29/drivers/i2c/xilinx_iic/Makefile linux-2.4.29-uc1/drivers/i2c/xilinx_iic/Makefile
--- linux-2.4.29/drivers/i2c/xilinx_iic/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/xilinx_iic/Makefile	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,21 @@
+#
+# Makefile for the Xilinx I2C driver
+#
+
+EXTRA_CFLAGS		+= -I$(TOPDIR)/arch/microblaze/xilinx_ocp
+
+list-multi		:= xilinx_iic.o
+
+# The Linux adapter for the Xilinx driver code.
+xilinx_iic-objs		+= i2c-algo-xilinx.o
+
+# The Xilinx OS independent code.
+xilinx_iic-objs		+= xiic.o xiic_g.o xiic_intr.o \
+			   xiic_master.o xiic_options.o
+
+obj-$(CONFIG_I2C_XILINX) := xilinx_iic.o
+
+xilinx_iic.o: $(xilinx_iic-objs)
+	$(LD) -r -o $@ $(xilinx_iic-objs)
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/i2c/xilinx_iic/xiic.c linux-2.4.29-uc1/drivers/i2c/xilinx_iic/xiic.c
--- linux-2.4.29/drivers/i2c/xilinx_iic/xiic.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/xilinx_iic/xiic.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,702 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xiic.c
+*
+* Contains required functions for the XIic component. See xiic.h for more
+* information on the driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- --- ------- -----------------------------------------------
+* 1.01a rfp  10/19/01 release
+* 1.01c ecm  12/05/02 new rev
+* 1.01c rmm  05/14/03 Fixed diab compiler warnings relating to asserts.
+* </pre>
+*
+****************************************************************************/
+
+/***************************** Include Files *******************************/
+
+#include "xiic.h"
+#include "xiic_i.h"
+#include "xio.h"
+//#include "xparameters.h"
+
+/************************** Constant Definitions ***************************/
+
+/**************************** Type Definitions *****************************/
+
+/***************** Macros (Inline Functions) Definitions *******************/
+
+/************************** Function Prototypes ****************************/
+
+static void XIic_StubStatusHandler(void *CallBackRef, XStatus ErrorCode);
+
+static void XIic_StubHandler(void *CallBackRef, int ByteCount);
+
+/************************** Variable Definitions **************************/
+
+/*****************************************************************************/
+/**
+*
+* Initializes a specific XIic instance.  The initialization entails:
+*
+* - Check the device has an entry in the configuration table.
+* - Initialize the driver to allow access to the device registers and
+*   initialize other subcomponents necessary for the operation of the device.
+* - Default options to:
+*     - 7-bit slave addressing
+*     - Send messages as a slave device
+*     - Repeated start off
+*     - General call recognition disabled
+* - Clear messageing and error statistics
+*
+* The XIic_Start() function must be called after this function before the device
+* is ready to send and receive data on the IIC bus.
+*
+* Before XIic_Start() is called, the interrupt control must connect the ISR
+* routine to the interrupt handler. This is done by the user, and not
+* XIic_Start() to allow the user to use an interrupt controller of their choice.
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+* @param    DeviceId is the unique id of the device controlled by this XIic
+*           instance.  Passing in a device id associates the generic XIic
+*           instance to a specific device, as chosen by the caller or
+*           application developer.
+*
+* @return
+*
+* - XST_SUCCESS when successful
+* - XST_DEVICE_IS_STARTED indicates the device is started (i.e. interrupts
+*   enabled and messaging is possible). Must stop before re-initialization
+*   is allowed.
+*
+* @note
+*
+* None.
+*
+****************************************************************************/
+XStatus
+XIic_Initialize(XIic * InstancePtr, u16 DeviceId)
+{
+	XIic_Config *IicConfigPtr;	/* Pointer to configuration data */
+
+	/*
+	 * Asserts test the validity of selected input arguments.
+	 */
+	XASSERT_NONVOID(InstancePtr != NULL);
+
+	InstancePtr->IsReady = 0;
+
+	/*
+	 * If the device is started, disallow the initialize and return a Status
+	 * indicating it is started.  This allows the user to stop the device
+	 * and reinitialize, but prevents a user from inadvertently initializing
+	 */
+	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+		return XST_DEVICE_IS_STARTED;
+	}
+
+	/*
+	 * Lookup the device configuration in the temporary CROM table. Use this
+	 * configuration info down below when initializing this component.
+	 */
+	IicConfigPtr = XIic_LookupConfig(DeviceId);
+	if (IicConfigPtr == NULL) {
+		return XST_DEVICE_NOT_FOUND;
+	}
+	/*
+	 * Set default values, including setting the callback
+	 * handlers to stubs so the system will not crash should the
+	 * application not assign its own callbacks.
+	 */
+	InstancePtr->IsStarted = 0;
+	InstancePtr->BaseAddress = IicConfigPtr->BaseAddress;
+	InstancePtr->RecvHandler = XIic_StubHandler;
+	InstancePtr->SendHandler = XIic_StubHandler;
+	InstancePtr->StatusHandler = XIic_StubStatusHandler;
+	InstancePtr->Has10BitAddr = IicConfigPtr->Has10BitAddr;
+	InstancePtr->IsReady = XCOMPONENT_IS_READY;
+	InstancePtr->Options = 0;
+	InstancePtr->BNBOnly = FALSE;
+
+	/*
+	 * Reset the device so it's in the reset state, this must be after the
+	 * IPIF is initialized since it resets thru the IPIF and clear the stats
+	 */
+	XIic_Reset(InstancePtr);
+
+	XIIC_CLEAR_STATS(InstancePtr);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function starts the IIC device and driver by enabling the proper
+* interrupts such that data may be sent and received on the IIC bus.
+* This function must be called before the functions to send and receive data.
+*
+* Before XIic_Start() is called, the interrupt control must connect the ISR
+* routine to the interrupt handler. This is done by the user, and not
+* XIic_Start() to allow the user to use an interrupt controller of their choice.
+*
+* Start enables:
+*  - IIC device
+*  - Interrupts:
+*     - Addressed as slave to allow messages from another master
+*     - Arbitration Lost to detect Tx arbitration errors
+*     - Global IIC interrupt within the IPIF interface
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+*
+* @return
+*
+* XST_SUCCESS always
+*
+* @note
+*
+* The device interrupt is connected to the interrupt controller, but no
+* "messaging" interrupts are enabled. Addressed as Slave is enabled to
+* reception of messages when this devices address is written to the bus.
+* The correct messaging interrupts are enabled when sending or receiving
+* via the IicSend() and IicRecv() functions. No action is required
+* by the user to control any IIC interrupts as the driver completely
+* manages all 8 interrupts. Start and Stop control the ability
+* to use the device. Stopping the device completely stops all device
+* interrupts from the processor.
+*
+****************************************************************************/
+XStatus
+XIic_Start(XIic * InstancePtr)
+{
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/*
+	 * Mask off all interrupts, each is enabled when needed.
+	 */
+	XIIF_V123B_WRITE_IIER(InstancePtr->BaseAddress, 0);
+
+	/*
+	 * Clear all interrupts by reading and rewriting exact value back.
+	 * Only those bits set will get written as 1 (writing 1 clears intr)
+	 */
+	XIic_mClearIntr(InstancePtr->BaseAddress, 0xFFFFFFFF);
+
+	/*
+	 * Enable the device
+	 */
+	XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
+		 XIIC_CR_ENABLE_DEVICE_MASK);
+	/*
+	 * Set Rx FIFO Occupancy depth to throttle at first byte(after reset = 0)
+	 */
+	XIo_Out8(InstancePtr->BaseAddress + XIIC_RFD_REG_OFFSET, 0);
+
+	/*
+	 * Clear and enable the interrupts needed
+	 */
+	XIic_mClearEnableIntr(InstancePtr->BaseAddress,
+			      XIIC_INTR_AAS_MASK | XIIC_INTR_ARB_LOST_MASK);
+
+	InstancePtr->IsStarted = XCOMPONENT_IS_STARTED;
+
+	/* Enable all interrupts by the global enable in the IPIF */
+
+	XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function stops the IIC device and driver such that data is no longer
+* sent or received on the IIC bus. This function stops the device by
+* disabling interrupts. This function only disables interrupts within the
+* device such that the caller is responsible for disconnecting the interrupt
+* handler of the device from the interrupt source and disabling interrupts
+* at other levels.
+*
+* Due to bus throttling that could hold the bus between messages when using
+* repeated start option, stop will not occur when the device is actively
+* sending or receiving data from the IIC bus or the bus is being throttled
+* by this device, but instead return XST_IIC_BUS_BUSY.
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+*
+* @return
+*
+* - XST_SUCCESS indicates all IIC interrupts are disabled. No messages can
+*   be received or transmitted until XIic_Start() is called.
+* - XST_IIC_BUS_BUSY indicates this device is currently engaged in message
+*   traffic and cannot be stopped.
+*
+* @note
+*
+* None.
+*
+****************************************************************************/
+XStatus
+XIic_Stop(XIic * InstancePtr)
+{
+	u8 Status;
+	u8 CntlReg;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+
+	/*
+	 * Disable all interrupts globally using the IPIF
+	 */
+	XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
+
+	CntlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
+	Status = XIo_In8(InstancePtr->BaseAddress + XIIC_SR_REG_OFFSET);
+
+	if ((CntlReg & XIIC_CR_MSMS_MASK)
+	    || (Status & XIIC_SR_ADDR_AS_SLAVE_MASK)) {
+		/* when this device is using the bus
+		 * - re-enable interrupts to finish current messaging
+		 * - return bus busy
+		 */
+		XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+
+		return XST_IIC_BUS_BUSY;
+	}
+
+	InstancePtr->IsStarted = 0;
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Resets the IIC device. Reset must only be called after the driver has been
+* initialized. The configuration after this reset is as follows:
+*   - Repeated start is disabled
+*   - General call is disabled
+*
+* The upper layer software is responsible for initializing and re-configuring
+* (if necessary) and restarting the IIC device after the reset.
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+* @internal
+*
+* The reset is accomplished by setting the IPIF reset register.  This takes
+* care of resetting all IPIF hardware blocks, including the IIC device.
+*
+****************************************************************************/
+void
+XIic_Reset(XIic * InstancePtr)
+{
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	XIIF_V123B_RESET(InstancePtr->BaseAddress);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sets the bus addresses. The addresses include the device
+* address that the device responds to as a slave, or the slave address
+* to communicate with on the bus.  The IIC device hardware is built to
+* allow either 7 or 10 bit slave addressing only at build time rather
+* than at run time. When this device is a master, slave addressing can
+* be selected at run time to match addressing modes for other bus devices.
+*
+* Addresses are represented as hex values with no adjustment for the data
+* direction bit as the software manages address bit placement.
+* Example: For a 7 address written to the device of 1010 011X where X is
+* the transfer direction (send/recv), the address parameter for this function
+* needs to be 01010011 or 0x53 where the correct bit alllignment will be
+* handled for 7 as well as 10 bit devices. This is especially important as
+* the bit placement is not handled the same depending on which options are
+* used such as repeated start.
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+* @param    AddressType indicates which address is being modified; the address
+*           which this device responds to on the IIC bus as a slave, or the
+*           slave address to communicate with when this device is a master. One
+*           of the following values must be contained in this argument.
+* <pre>
+*   XII_ADDRESS_TO_SEND         Slave being addressed by a this master
+*   XII_ADDRESS_TO_RESPOND      Address to respond to as a slave device
+* </pre>
+* @param    Address contains the address to be set; 7 bit or 10 bit address.
+*           A ten bit address must be within the range: 0 - 1023 and a 7 bit
+*           address must be within the range 0 - 127.
+*
+* @return
+*
+* XST_SUCCESS is returned if the address was successfully set, otherwise one
+* of the following errors is returned.
+* - XST_IIC_NO_10_BIT_ADDRESSING indicates only 7 bit addressing supported.
+* - XST_INVALID_PARAM indicates an invalid parameter was specified.
+*
+* @note
+*
+* Upper bits of 10-bit address is written only when current device is built
+* as a ten bit device.
+*
+****************************************************************************/
+XStatus
+XIic_SetAddress(XIic * InstancePtr, int AddressType, int Address)
+{
+	u8 SendAddr;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(Address < 1023);
+
+	/* Set address to respond to for this device into address registers */
+
+	if (AddressType == XII_ADDR_TO_RESPOND_TYPE) {
+		SendAddr = (u8) ((Address & 0x007F) << 1);	/* Addr in upper 7 bits */
+		XIo_Out8(InstancePtr->BaseAddress + XIIC_ADR_REG_OFFSET,
+			 SendAddr);
+
+		if (InstancePtr->Has10BitAddr == TRUE) {
+			/* Write upper 3 bits of addr to DTR only when 10 bit option
+			 * included in design i.e. register exists
+			 */
+			SendAddr = (u8) ((Address & 0x0380) >> 7);
+			XIo_Out8(InstancePtr->BaseAddress + XIIC_TBA_REG_OFFSET,
+				 SendAddr);
+		}
+
+		return XST_SUCCESS;
+	}
+
+	/* Store address of slave device being read from */
+
+	if (AddressType == XII_ADDR_TO_SEND_TYPE) {
+		InstancePtr->AddrOfSlave = Address;
+		return XST_SUCCESS;
+	}
+
+	return XST_INVALID_PARAM;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function gets the addresses for the IIC device driver. The addresses
+* include the device address that the device responds to as a slave, or the
+* slave address to communicate with on the bus. The address returned has the
+* same format whether 7 or 10 bits.
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+* @param    AddressType indicates which address, the address which this
+*           responds to on the IIC bus as a slave, or the slave address to
+*           communicate with when this device is a master. One of the following
+*           values must be contained in this argument.
+* <pre>
+*   XII_ADDRESS_TO_SEND_TYPE         slave being addressed as a master
+*   XII_ADDRESS_TO_RESPOND_TYPE      slave address to respond to as a slave
+* </pre>
+*  If neither of the two valid arguments are used, the function returns
+*  the address of the slave device
+*
+* @return
+*
+* The address retrieved.
+*
+* @note
+*
+* None.
+*
+****************************************************************************/
+u16
+XIic_GetAddress(XIic * InstancePtr, int AddressType)
+{
+	u8 LowAddr;
+	u16 HighAddr = 0;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+
+	/* return this devices address */
+
+	if (AddressType == XII_ADDR_TO_RESPOND_TYPE) {
+
+		LowAddr =
+		    XIo_In8(InstancePtr->BaseAddress + XIIC_ADR_REG_OFFSET);
+
+		if (InstancePtr->Has10BitAddr == TRUE) {
+			HighAddr = (u16) XIo_In8(InstancePtr->BaseAddress +
+						 XIIC_TBA_REG_OFFSET);
+		}
+		return ((HighAddr << 8) & (u16) LowAddr);
+	}
+
+	/* Otherwise return address of slave device on the IIC bus */
+
+	return InstancePtr->AddrOfSlave;
+}
+
+/*****************************************************************************/
+/**
+*
+* A function to determine if the device is currently addressed as a slave
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+*
+* @return
+*
+* TRUE if the device is addressed as slave, and FALSE otherwise.
+*
+* @note
+*
+* None.
+*
+****************************************************************************/
+u32
+XIic_IsSlave(XIic * InstancePtr)
+{
+	XASSERT_NONVOID(InstancePtr != NULL);
+
+	if ((XIo_In8(InstancePtr->BaseAddress + XIIC_SR_REG_OFFSET) &
+	     XIIC_SR_ADDR_AS_SLAVE_MASK) == 0) {
+		return FALSE;
+	}
+	return TRUE;
+}
+
+/*****************************************************************************/
+/**
+*
+* Sets the receive callback function, the receive handler, which the driver
+* calls when it finishes receiving data. The number of bytes used to signal
+* when the receive is complete is the number of bytes set in the XIic_Recv
+* function.
+*
+* The handler executes in an interrupt context such that it must minimize
+* the amount of processing performed such as transferring data to a thread
+* context.
+*
+* The number of bytes received is passed to the handler as an argument.
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+* @param    CallBackRef is the upper layer callback reference passed back when
+*           the callback function is invoked.
+* @param    FuncPtr is the pointer to the callback function.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* The handler is called within interrupt context ...
+*
+****************************************************************************/
+void
+XIic_SetRecvHandler(XIic * InstancePtr, void *CallBackRef, XIic_Handler FuncPtr)
+{
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(FuncPtr != NULL);
+
+	InstancePtr->RecvHandler = FuncPtr;
+	InstancePtr->RecvCallBackRef = CallBackRef;
+}
+
+/*****************************************************************************/
+/**
+*
+* Sets the send callback function, the send handler, which the driver calls when
+* it receives confirmation of sent data. The handler executes in an interrupt
+* context such that it must minimize the amount of processing performed such
+* as transferring data to a thread context.
+*
+* @param    InstancePtr the pointer to the XIic instance to be worked on.
+* @param    CallBackRef the upper layer callback reference passed back when
+*           the callback function is invoked.
+* @param    FuncPtr the pointer to the callback function.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* The handler is called within interrupt context ...
+*
+****************************************************************************/
+void
+XIic_SetSendHandler(XIic * InstancePtr, void *CallBackRef, XIic_Handler FuncPtr)
+{
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	XASSERT_VOID(FuncPtr != NULL);
+
+	InstancePtr->SendHandler = FuncPtr;
+	InstancePtr->SendCallBackRef = CallBackRef;
+}
+
+/*****************************************************************************/
+/**
+*
+* Sets the status callback function, the status handler, which the driver calls
+* when it encounters conditions which are not data related. The handler
+* executes in an interrupt context such that it must minimize the amount of
+* processing performed such as transferring data to a thread context. The
+* status events that can be returned are described in xiic.h.
+*
+* @param    InstancePtr points to the XIic instance to be worked on.
+* @param    CallBackRef is the upper layer callback reference passed back when
+*           the callback function is invoked.
+* @param    FuncPtr is the pointer to the callback function.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* The handler is called within interrupt context ...
+*
+****************************************************************************/
+void
+XIic_SetStatusHandler(XIic * InstancePtr, void *CallBackRef,
+		      XIic_StatusHandler FuncPtr)
+{
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+	XASSERT_VOID(FuncPtr != NULL);
+
+	InstancePtr->StatusHandler = FuncPtr;
+	InstancePtr->StatusCallBackRef = CallBackRef;
+}
+
+/*****************************************************************************/
+/**
+*
+* Looks up the device configuration based on the unique device ID. The table
+* IicConfigTable contains the configuration info for each device in the system.
+*
+* @param DeviceId is the unique device ID to look for
+*
+* @return
+*
+* A pointer to the configuration data of the device, or NULL if no match is
+* found.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XIic_Config *
+XIic_LookupConfig(u16 DeviceId)
+{
+	XIic_Config *CfgPtr = NULL;
+	int i;
+
+	for (i = 0; i < CONFIG_XILINX_IIC_NUM_INSTANCES; i++) {
+		if (XIic_ConfigTable[i].DeviceId == DeviceId) {
+			CfgPtr = &XIic_ConfigTable[i];
+			break;
+		}
+	}
+
+	return CfgPtr;
+}
+
+/*****************************************************************************
+*
+* This is a stub for the send and recv callbacks. The stub is here in case the
+* upper layers forget to set the handlers.
+*
+* @param    CallBackRef is a pointer to the upper layer callback reference
+* @param    ByteCount is the number of bytes sent or received
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+XIic_StubHandler(void *CallBackRef, int ByteCount)
+{
+	XASSERT_VOID_ALWAYS();
+}
+
+/*****************************************************************************
+*
+* This is a stub for the asynchronous error callback. The stub is here in case
+* the upper layers forget to set the handler.
+*
+* @param    CallBackRef is a pointer to the upper layer callback reference
+* @param    ErrorCode is the Xilinx error code, indicating the cause of the error
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+XIic_StubStatusHandler(void *CallBackRef, XStatus ErrorCode)
+{
+	XASSERT_VOID_ALWAYS();
+}
diff -urN linux-2.4.29/drivers/i2c/xilinx_iic/xiic_g.c linux-2.4.29-uc1/drivers/i2c/xilinx_iic/xiic_g.c
--- linux-2.4.29/drivers/i2c/xilinx_iic/xiic_g.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/xilinx_iic/xiic_g.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,54 @@
+/*******************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+* 
+* Description: Driver configuration
+*
+*******************************************************************/
+
+#include <linux/autoconf.h>
+#include "xiic.h"
+
+/*
+* The configuration table for devices
+*/
+
+XIic_Config XIic_ConfigTable[] = {
+	{
+	 0,
+	 CONFIG_XILINX_IIC_0_BASEADDR,
+	 CONFIG_XILINX_IIC_0_TEN_BIT_ADR}
+};
diff -urN linux-2.4.29/drivers/i2c/xilinx_iic/xiic.h linux-2.4.29-uc1/drivers/i2c/xilinx_iic/xiic.h
--- linux-2.4.29/drivers/i2c/xilinx_iic/xiic.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/xilinx_iic/xiic.h	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,423 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xiic.h
+*
+* XIic is the driver for an IIC master or slave device.
+
+* In order to reduce the memory requirements of the driver it is partitioned
+* such that there are optional parts of the driver.  Slave, master, and
+* multimaster features are optional such that these files are not required.
+* In order to use the slave and multimaster features of the driver, the user
+* must call functions (XIic_SlaveInclude and XIic_MultiMasterInclude)
+* to dynamically include the code .  These functions may be called at any time.
+*
+* <b>Bus Throttling</b>
+*
+* The IIC hardware provides bus throttling which allows either the device, as
+* either a master or a slave, to stop the clock on the IIC bus. This feature
+* allows the software to perform the appropriate processing for each interrupt
+* without an unreasonable response restriction.  With this design, it is
+* important for the user to understand the implications of bus throttling.
+*
+* <b>Repeated Start</b>
+*
+* An application can send multiple messages, as a master, to a slave device
+* and re-acquire the IIC bus each time a message is sent. The repeated start
+* option allows the application to send multiple messages without re-acquiring
+* the IIC bus for each message. This feature also could cause the application
+* to lock up, or monopolize the IIC bus, should repeated start option be
+* enabled and sequences of messages never end (periodic data collection).
+* Also when repeated start is not disable before the last master message is
+* sent or received, will leave the bus captive to the master, but unused.
+*
+* <b>Addressing</b>
+*
+* The IIC hardware is parameterized such that it can be built for 7 or 10
+* bit addresses. The driver provides the ability to control which address
+* size is sent in messages as a master to a slave device.  The address size
+* which the hardware responds to as a slave is parameterized as 7 or 10 bits
+* but fixed by the hardware build.
+*
+* Addresses are represented as hex values with no adjustment for the data
+* direction bit as the software manages address bit placement. This is
+* especially important as the bit placement is not handled the same depending
+* on which options are used such as repeated start and 7 vs 10 bit addessing.
+*
+* <b>Data Rates</b>
+*
+* The IIC hardware is parameterized such that it can be built to support
+* data rates from DC to 400KBit. The frequency of the interrupts which
+* occur is proportional to the data rate.
+*
+* <b>Polled Mode Operation</b>
+*
+* This driver does not provide a polled mode of operation primarily because
+* polled mode which is non-blocking is difficult with the amount of
+* interaction with the hardware that is necessary.
+*
+* <b>Interrupts</b>
+*
+* The device has many interrupts which allow IIC data transactions as well
+* as bus status processing to occur.
+*
+* The interrupts are divided into two types, data and status. Data interrupts
+* indicate data has been received or transmitted while the status interrupts
+* indicate the status of the IIC bus. Some of the interrupts, such as Not
+* Addressed As Slave and Bus Not Busy, are only used when these specific
+* events must be recognized as opposed to being enabled at all times.
+*
+* Many of the interrupts are not a single event in that they are continuously
+* present such that they must be disabled after recognition or when undesired.
+* Some of these interrupts, which are data related, may be acknowledged by the
+* software by reading or writing data to the appropriate register, or must
+* be disabled. The following interrupts can be continuous rather than single
+* events.
+*   - Data Transmit Register Empty/Transmit FIFO Empty
+*   - Data Receive Register Full/Receive FIFO
+*   - Transmit FIFO Half Empty
+*   - Bus Not Busy
+*   - Addressed As Slave
+*   - Not Addressed As Slave
+*
+* The following interrupts are not passed directly to the application thru the
+* status callback.  These are only used internally for the driver processing
+* and may result in the receive and send handlers being called to indicate
+* completion of an operation.  The following interrupts are data related
+* rather than status.
+*   - Data Transmit Register Empty/Transmit FIFO Empty
+*   - Data Receive Register Full/Receive FIFO
+*   - Transmit FIFO Half Empty
+*   - Slave Transmit Complete
+*
+* <b>Interrupt To Event Mapping</b>
+*
+* The following table provides a mapping of the interrupts to the events which
+* are passed to the status handler and the intended role (master or slave) for
+* the event.  Some interrupts can cause multiple events which are combined
+* together into a single status event such as XII_MASTER_WRITE_EVENT and
+* XII_GENERAL_CALL_EVENT
+* <pre>
+* Interrupt                         Event(s)                     Role
+*
+* Arbitration Lost Interrupt        XII_ARB_LOST_EVENT            Master
+* Transmit Error                    XII_SLAVE_NO_ACK_EVENT        Master
+* IIC Bus Not Busy                  XII_BUS_NOT_BUSY_EVENT        Master
+* Addressed As Slave                XII_MASTER_READ_EVENT,        Slave
+*                                   XII_MASTER_WRITE_EVENT,       Slave
+*                                   XII_GENERAL_CALL_EVENT        Slave
+* </pre>
+* <b>Not Addressed As Slave Interrupt</b>
+*
+* The Not Addressed As Slave interrupt is not passed directly to the
+* application thru the status callback.  It is used to determine the end of
+* a message being received by a slave when there was no stop condition
+* (repeated start).  It will cause the receive handler to be called to
+* indicate completion of the operation.
+*
+* <b>RTOS Independence</b>
+*
+* This driver is intended to be RTOS and processor independent.  It works
+* with physical addresses only.  Any needs for dynamic memory management,
+* threads or thread mutual exclusion, virtual memory, or cache control must
+* be satisfied by the layer above this driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.01a rfp  10/19/01 release
+* 1.01c ecm  12/05/02 new rev
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XIIC_H			/* prevent circular inclusions */
+#define XIIC_H			/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xipif_v1_23_b.h"
+#include "xiic_l.h"
+
+/************************** Constant Definitions *****************************/
+
+/** @name Configuration options
+ *
+ * The following options may be specified or retrieved for the device and
+ * enable/disable additional features of the IIC bus.  Each of the options
+ * are bit fields such that more than one may be specified.
+ * @{
+ */
+/**
+ * <pre>
+ * XII_GENERAL_CALL_OPTION      The general call option allows an IIC slave to
+ *                              recognized the general call address. The status
+ *                              handler is called as usual indicating the device
+ *                              has been addressed as a slave with a general
+ *                              call. It is the application's responsibility to
+ *                              perform any special processing for the general
+ *                              call.
+ *
+ * XII_REPEATED_START_OPTION    The repeated start option allows multiple
+ *                              messages to be sent/received on the IIC bus
+ *                              without rearbitrating for the bus.  The messages
+ *                              are sent as a series of messages such that the
+ *                              option must be enabled before the 1st message of
+ *                              the series, to prevent an stop condition from
+ *                              being generated on the bus, and disabled before
+ *                              the last message of the series, to allow the
+ *                              stop condition to be generated.
+ *
+ * XII_SEND_10_BIT_OPTION       The send 10 bit option allows 10 bit addresses
+ *                              to be sent on the bus when the device is a
+ *                              master. The device can be configured to respond
+ *                              as to 7 bit addresses even though it may be
+ *                              communicating with other devices that support 10
+ *                              bit addresses.  When this option is not enabled,
+ *                              only 7 bit addresses are sent on the bus.
+ *
+ * </pre>
+ */
+#define XII_GENERAL_CALL_OPTION    0x00000001
+#define XII_REPEATED_START_OPTION  0x00000002
+#define XII_SEND_10_BIT_OPTION     0x00000004
+
+/*@}*/
+
+/** @name Status events
+ *
+ * The following status events occur during IIC bus processing and are passed
+ * to the status callback. Each event is only valid during the appropriate
+ * processing of the IIC bus. Each of these events are bit fields such that
+ * more than one may be specified.
+ * @{
+ */
+/**
+ * <pre>
+ *   XII_BUS_NOT_BUSY_EVENT      bus transitioned to not busy
+ *   XII_ARB_LOST_EVENT          arbitration was lost
+ *   XII_SLAVE_NO_ACK_EVENT      slave did not acknowledge data (had error)
+ *   XII_MASTER_READ_EVENT       master reading from slave
+ *   XII_MASTER_WRITE_EVENT      master writing to slave
+ *   XII_GENERAL_CALL_EVENT      general call to all slaves
+ * </pre>
+ */
+#define XII_BUS_NOT_BUSY_EVENT   0x00000001
+#define XII_ARB_LOST_EVENT       0x00000002
+#define XII_SLAVE_NO_ACK_EVENT   0x00000004
+#define XII_MASTER_READ_EVENT    0x00000008
+#define XII_MASTER_WRITE_EVENT   0x00000010
+#define XII_GENERAL_CALL_EVENT   0x00000020
+/*@}*/
+
+/* The following address types are used when setting and getting the addresses
+ * of the driver. These are mutually exclusive such that only one or the other
+ * may be specified.
+ */
+/** bus address of slave device */
+#define XII_ADDR_TO_SEND_TYPE       1
+/** this device's bus address when slave */
+#define XII_ADDR_TO_RESPOND_TYPE    2
+
+/**************************** Type Definitions *******************************/
+
+/**
+ * This typedef contains configuration information for the device.
+ */
+typedef struct {
+	u16 DeviceId;	/**< Unique ID  of device */
+	u32 BaseAddress;/**< Device base address */
+	u32 Has10BitAddr;
+		       /**< does device have 10 bit address decoding */
+} XIic_Config;
+
+/**
+ * This callback function data type is defined to handle the asynchronous
+ * processing of sent and received data of the IIC driver.  The application
+ * using this driver is expected to define a handler of this type to support
+ * interrupt driven mode. The handlers are called in an interrupt context such
+ * that minimal processing should be performed. The handler data type is
+ * utilized for both send and receive handlers.
+ *
+ * @param CallBackRef is a callback reference passed in by the upper layer when
+ *        setting the callback functions, and passed back to the upper layer
+ *        when the callback is invoked. Its type is unimportant to the driver
+ *        component, so it is a void pointer.
+ *
+ * @param ByteCount indicates the number of bytes remaining to be sent or
+ *        received.  A value of zero indicates that the requested number of
+ *        bytes were sent or received.
+ */
+typedef void (*XIic_Handler) (void *CallBackRef, int ByteCount);
+
+/**
+ * This callback function data type is defined to handle the asynchronous
+ * processing of status events of the IIC driver.  The application using
+ * this driver is expected to define a handler of this type to support
+ * interrupt driven mode. The handler is called in an interrupt context such
+ * that minimal processing should be performed.
+ *
+ * @param CallBackRef is a callback reference passed in by the upper layer when
+ *        setting the callback functions, and passed back to the upper layer
+ *        when the callback is invoked. Its type is unimportant to the driver
+ *        component, so it is a void pointer.
+ *
+ * @param StatusEvent indicates one or more status events that occurred.  See
+ *        the definition of the status events above.
+ */
+typedef void (*XIic_StatusHandler) (void *CallBackRef, XStatus StatusEvent);
+
+/**
+ * XIic statistics
+ */
+typedef struct {
+	u8 ArbitrationLost;/**< Number of times arbitration was lost */
+	u8 RepeatedStarts; /**< Number of repeated starts */
+	u8 BusBusy;	   /**< Number of times bus busy status returned */
+	u8 RecvBytes;	   /**< Number of bytes received */
+	u8 RecvInterrupts; /**< Number of receive interrupts */
+	u8 SendBytes;	   /**< Number of transmit bytes received */
+	u8 SendInterrupts; /**< Number of transmit interrupts */
+	u8 TxErrors;	   /**< Number of transmit errors (no ack) */
+	u8 IicInterrupts;  /**< Number of IIC (device) interrupts */
+} XIicStats;
+
+/**
+ * The XIic driver instance data. The user is required to allocate a
+ * variable of this type for every IIC device in the system. A pointer
+ * to a variable of this type is then passed to the driver API functions.
+ */
+typedef struct {
+	XIicStats Stats;	/* Statistics                              */
+	u32 BaseAddress;	/* Device base address                     */
+	u32 Has10BitAddr;	/* TRUE when 10 bit addressing in design  */
+	u32 IsReady;		/* Device is initialized and ready         */
+	u32 IsStarted;		/* Device has been started                 */
+	int AddrOfSlave;	/* Slave addr writing to                   */
+
+	u32 Options;		/* current operating options               */
+	u8 *SendBufferPtr;	/* Buffer to send (state)                  */
+	u8 *RecvBufferPtr;	/* Buffer to receive (state)               */
+	u8 TxAddrMode;		/* State of Tx Address transmission        */
+	int SendByteCount;	/* Number of data bytes in buffer (state)  */
+	int RecvByteCount;	/* Number of empty bytes in buffer (state) */
+
+	u32 BNBOnly;		/* TRUE when BNB interrupt needs to   */
+	/* call callback  */
+
+	XIic_StatusHandler StatusHandler;
+	void *StatusCallBackRef;	/* Callback reference for status handler */
+	XIic_Handler RecvHandler;
+	void *RecvCallBackRef;	/* Callback reference for recv handler */
+	XIic_Handler SendHandler;
+	void *SendCallBackRef;	/* Callback reference for send handler */
+
+} XIic;
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+/*
+ * Required functions in xiic.c
+ */
+XStatus XIic_Initialize(XIic * InstancePtr, u16 DeviceId);
+
+XStatus XIic_Start(XIic * InstancePtr);
+XStatus XIic_Stop(XIic * InstancePtr);
+
+void XIic_Reset(XIic * InstancePtr);
+
+XStatus XIic_SetAddress(XIic * InstancePtr, int AddressType, int Address);
+u16 XIic_GetAddress(XIic * InstancePtr, int AddressType);
+
+XIic_Config *XIic_LookupConfig(u16 DeviceId);
+
+/*
+ * Interrupt (currently required) functions in xiic_intr.c
+ */
+void XIic_InterruptHandler(void *InstancePtr);
+void XIic_SetRecvHandler(XIic * InstancePtr, void *CallBackRef,
+			 XIic_Handler FuncPtr);
+void XIic_SetSendHandler(XIic * InstancePtr, void *CallBackRef,
+			 XIic_Handler FuncPtr);
+void XIic_SetStatusHandler(XIic * InstancePtr, void *CallBackRef,
+			   XIic_StatusHandler FuncPtr);
+/*
+ * Master send and receive functions in xiic_master.c
+ */
+XStatus XIic_MasterRecv(XIic * InstancePtr, u8 * RxMsgPtr, int ByteCount);
+XStatus XIic_MasterSend(XIic * InstancePtr, u8 * TxMsgPtr, int ByteCount);
+
+/*
+ * Slave send and receive functions in xiic_slave.c
+ */
+void XIic_SlaveInclude(void);
+XStatus XIic_SlaveRecv(XIic * InstancePtr, u8 * RxMsgPtr, int ByteCount);
+XStatus XIic_SlaveSend(XIic * InstancePtr, u8 * TxMsgPtr, int ByteCount);
+
+/*
+ * Statistics functions in xiic_stats.c
+ */
+void XIic_GetStats(XIic * InstancePtr, XIicStats * StatsPtr);
+void XIic_ClearStats(XIic * InstancePtr);
+
+/*
+ * Self test functions in xiic_selftest.c
+ */
+XStatus XIic_SelfTest(XIic * InstancePtr);
+
+/*
+ * Options functions in xiic_options.c
+ */
+void XIic_SetOptions(XIic * InstancePtr, u32 Options);
+u32 XIic_GetOptions(XIic * InstancePtr);
+
+/*
+ * Multi-master functions in xiic_multi_master.c
+ */
+void XIic_MultiMasterInclude(void);
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/drivers/i2c/xilinx_iic/xiic_i.h linux-2.4.29-uc1/drivers/i2c/xilinx_iic/xiic_i.h
--- linux-2.4.29/drivers/i2c/xilinx_iic/xiic_i.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/xilinx_iic/xiic_i.h	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,479 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xiic_i.h
+*
+* This header file contains internal identifiers, which are those shared
+* between XIic components.  The identifiers in this file are not intended for
+* use external to the driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.01a rfp  10/19/01 release
+* 1.01c ecm  12/05/02 new rev
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XIIC_I_H		/* prevent circular inclusions */
+#define XIIC_I_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/******************************************************************************
+*
+* This macro sends the first byte of the address for a 10 bit address during
+* both read and write operations. It takes care of the details to format the
+* address correctly.
+*
+* address = 1111_0xxD   xx = address MSBits
+*                        D = Tx direction = 0 = write
+*
+* @param    SlaveAddress contains the address of the slave to send to.
+*
+* @param    Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIic_mSend10BitAddrByte1(u16 SlaveAddress, u8 Operation);
+*
+******************************************************************************/
+#define XIic_mSend10BitAddrByte1(SlaveAddress, Operation)                  \
+{                                                                            \
+    u8 LocalAddr = (u8)((SlaveAddress) >> 7);                        \
+    LocalAddr = (LocalAddr & 0xF6) | 0xF0 | (Operation);                     \
+    XIo_Out8(InstancePtr->BaseAddress + XIIC_DTR_REG_OFFSET, LocalAddr);  \
+}
+
+/******************************************************************************
+*
+* This macro sends the second byte of the address for a 10 bit address during
+* both read and write operations. It takes care of the details to format the
+* address correctly.
+*
+* @param    SlaveAddress contains the address of the slave to send to.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIic_mSend10BitAddrByte2(u16 SlaveAddress,
+*                                            u8 Operation);
+*
+******************************************************************************/
+#define XIic_mSend10BitAddrByte2(SlaveAddress)                        \
+    XIo_Out8(InstancePtr->BaseAddress + XIIC_DTR_REG_OFFSET,         \
+             (u8)(SlaveAddress));
+
+/******************************************************************************
+*
+* This macro sends the address for a 7 bit address during both read and write
+* operations. It takes care of the details to format the address correctly.
+*
+* @param    SlaveAddress contains the address of the slave to send to.
+*
+* @param    Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIic_mSend7BitAddr(u16 SlaveAddress, u8 Operation);
+*
+******************************************************************************/
+#define XIic_mSend7BitAddr(SlaveAddress, Operation)                          \
+{                                                                            \
+    u8 LocalAddr = (u8)(SlaveAddress << 1);                          \
+    LocalAddr = (LocalAddr & 0xFE) | (Operation);                            \
+    XIo_Out8(InstancePtr->BaseAddress + XIIC_DTR_REG_OFFSET, LocalAddr);  \
+}
+
+/******************************************************************************
+*
+* This macro disables the specified interrupts in the IPIF interrupt enable
+* register.  It is non-destructive in that the register is read and only the
+* interrupts specified is changed.
+*
+* @param    BaseAddress contains the IPIF registers base address.
+*
+* @param    InterruptMask contains the interrupts to be disabled
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIic_mDisableIntr(u32 BaseAddress,
+*                                        u32 InterruptMask);
+*
+******************************************************************************/
+#define XIic_mDisableIntr(BaseAddress, InterruptMask)           \
+    XIIF_V123B_WRITE_IIER((BaseAddress),                        \
+        XIIF_V123B_READ_IIER(BaseAddress) & ~(InterruptMask))
+
+/******************************************************************************
+*
+* This macro enables the specified interrupts in the IPIF interrupt enable
+* register.  It is non-destructive in that the register is read and only the
+* interrupts specified is changed.
+*
+* @param    BaseAddress contains the IPIF registers base address.
+*
+* @param    InterruptMask contains the interrupts to be disabled
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIic_mEnableIntr(u32 BaseAddress,
+*                                  u32 InterruptMask);
+*
+******************************************************************************/
+#define XIic_mEnableIntr(BaseAddress, InterruptMask)           \
+    XIIF_V123B_WRITE_IIER((BaseAddress),                       \
+        XIIF_V123B_READ_IIER(BaseAddress) | (InterruptMask))
+
+/******************************************************************************
+*
+* This macro clears the specified interrupt in the IPIF interrupt status
+* register.  It is non-destructive in that the register is read and only the
+* interrupt specified is cleared.  Clearing an interrupt acknowledges it.
+*
+* @param    BaseAddress contains the IPIF registers base address.
+*
+* @param    InterruptMask contains the interrupts to be disabled
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIic_mClearIntr(u32 BaseAddress,
+*                                 u32 InterruptMask);
+*
+******************************************************************************/
+#define XIic_mClearIntr(BaseAddress, InterruptMask)                 \
+    XIIF_V123B_WRITE_IISR((BaseAddress),                            \
+        XIIF_V123B_READ_IISR(BaseAddress) & (InterruptMask))
+
+/******************************************************************************
+*
+* This macro clears and enables the specified interrupt in the IPIF interrupt
+* status and enable registers.  It is non-destructive in that the registers are
+* read and only the interrupt specified is modified.
+* Clearing an interrupt acknowledges it.
+*
+* @param    BaseAddress contains the IPIF registers base address.
+*
+* @param    InterruptMask contains the interrupts to be cleared and enabled
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIic_mClearEnableIntr(u32 BaseAddress,
+*                                             u32 InterruptMask);
+*
+******************************************************************************/
+#define XIic_mClearEnableIntr(BaseAddress, InterruptMask)          \
+{                                                                       \
+    XIIF_V123B_WRITE_IISR(BaseAddress,                              \
+        (XIIF_V123B_READ_IISR(BaseAddress) & (InterruptMask)));     \
+                                                                        \
+    XIIF_V123B_WRITE_IIER(BaseAddress,                              \
+        (XIIF_V123B_READ_IIER(BaseAddress) | (InterruptMask)));     \
+}
+
+/******************************************************************************
+*
+* This macro flushes the receive FIFO such that all bytes contained within it
+* are discarded.
+*
+* @param    InstancePtr is a pointer to the IIC instance containing the FIFO
+*           to be flushed.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIic_mFlushRxFifo(XIic *InstancePtr);
+*
+******************************************************************************/
+#define XIic_mFlushRxFifo(InstancePtr)                                     \
+{                                                                           \
+    int LoopCnt;                                                            \
+    u8 Temp;                                                            \
+    u8 BytesToRead = XIo_In8(InstancePtr->BaseAddress +              \
+                                 XIIC_RFO_REG_OFFSET) + 1;                  \
+    for(LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++)                      \
+    {                                                                       \
+        Temp = XIo_In8(InstancePtr->BaseAddress + XIIC_DRR_REG_OFFSET);  \
+    }                                                                       \
+}
+
+/******************************************************************************
+*
+* This macro flushes the transmit FIFO such that all bytes contained within it
+* are discarded.
+*
+* @param    InstancePtr is a pointer to the IIC instance containing the FIFO
+*           to be flushed.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIic_mFlushTxFifo(XIic *InstancePtr);
+*
+******************************************************************************/
+#define XIic_mFlushTxFifo(InstancePtr);                                    \
+{                                                                           \
+    u8 CntlReg = XIo_In8(InstancePtr->BaseAddress +                  \
+                             XIIC_CR_REG_OFFSET);                           \
+    XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,              \
+             CntlReg | XIIC_CR_TX_FIFO_RESET_MASK);                         \
+    XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET, CntlReg);    \
+}
+
+/******************************************************************************
+*
+* This macro reads the next available received byte from the receive FIFO
+* and updates all the data structures to reflect it.
+*
+* @param    InstancePtr is a pointer to the IIC instance to be operated on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIic_mReadRecvByte(XIic *InstancePtr);
+*
+******************************************************************************/
+#define XIic_mReadRecvByte(InstancePtr)                                    \
+{                                                                           \
+    *InstancePtr->RecvBufferPtr++ =                                         \
+        XIo_In8(InstancePtr->BaseAddress + XIIC_DRR_REG_OFFSET);         \
+    InstancePtr->RecvByteCount--;                                           \
+    InstancePtr->Stats.RecvBytes++;                                         \
+}
+
+/******************************************************************************
+*
+* This macro writes the next byte to be sent to the transmit FIFO
+* and updates all the data structures to reflect it.
+*
+* @param    InstancePtr is a pointer to the IIC instance to be operated on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIic_mWriteSendByte(XIic *InstancePtr);
+*
+******************************************************************************/
+#define XIic_mWriteSendByte(InstancePtr)                                   \
+{                                                                           \
+    XIo_Out8(InstancePtr->BaseAddress + XIIC_DTR_REG_OFFSET,             \
+        *InstancePtr->SendBufferPtr++);                                     \
+    InstancePtr->SendByteCount--;                                           \
+    InstancePtr->Stats.SendBytes++;                                         \
+}
+
+/******************************************************************************
+*
+* This macro sets up the control register for a master receive operation.
+* A write is necessary if a 10 bit operation is being performed.
+*
+* @param    InstancePtr is a pointer to the IIC instance to be operated on.
+*
+* @param    ControlRegister contains the contents of the IIC device control
+*           register
+*
+* @param    ByteCount contains the number of bytes to be received for the
+*           master receive operation
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIic_mSetControlRegister(XIic *InstancePtr,
+*                                           u8 ControlRegister,
+*                                           int ByteCount);
+*
+******************************************************************************/
+#define XIic_mSetControlRegister(InstancePtr, ControlRegister, ByteCount)  \
+{                                                                           \
+    (ControlRegister) &= ~(XIIC_CR_NO_ACK_MASK | XIIC_CR_DIR_IS_TX_MASK);   \
+    if (InstancePtr->Options & XII_SEND_10_BIT_OPTION)                      \
+    {                                                                       \
+        (ControlRegister) |= XIIC_CR_DIR_IS_TX_MASK;                        \
+    }                                                                       \
+    else                                                                    \
+    {                                                                       \
+        if ((ByteCount) == 1)                                               \
+        {                                                                   \
+            (ControlRegister) |= XIIC_CR_NO_ACK_MASK;                       \
+        }                                                                   \
+    }                                                                       \
+}
+
+/******************************************************************************
+*
+* This macro enters a critical region by disabling the global interrupt bit
+* in the IPIF.
+*
+* @param    BaseAddress contains the IPIF registers base address.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIic_mEnterCriticalRegion(u32 BaseAddress)
+*
+******************************************************************************/
+#define XIic_mEnterCriticalRegion(BaseAddress)  \
+    XIIF_V123B_GINTR_DISABLE(BaseAddress)
+
+/******************************************************************************
+*
+* This macro exits a critical region by enabling the global interrupt bit
+* in the IPIF.
+*
+* @param    BaseAddress contains the IPIF registers base address.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIic_mExitCriticalRegion(u32 BaseAddress)
+*
+******************************************************************************/
+#define XIic_mExitCriticalRegion(BaseAddress)  \
+    XIIF_V123B_GINTR_ENABLE(BaseAddress)
+
+/******************************************************************************
+*
+* This macro clears the statistics of an instance such that it can be common
+* such that some parts of the driver may be optional.
+*
+* @param    InstancePtr is a pointer to the IIC instance to be operated on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XIIC_CLEAR_STATS(XIic *InstancePtr)
+*
+******************************************************************************/
+#define XIIC_CLEAR_STATS(InstancePtr)                                   \
+{                                                                       \
+    u8 NumBytes;                                                    \
+    u8 *DestPtr;                                                    \
+                                                                        \
+    DestPtr = (u8 *)&InstancePtr->Stats;                            \
+    for (NumBytes = 0; NumBytes < sizeof(XIicStats); NumBytes++)        \
+    {                                                                   \
+        *DestPtr++ = 0;                                                 \
+    }                                                                   \
+}
+
+/************************** Function Prototypes ******************************/
+
+extern XIic_Config XIic_ConfigTable[];
+
+/* The following variables are shared across files of the driver and
+ * are function pointers that are necessary to break dependencies allowing
+ * optional parts of the driver to be used without condition compilation
+ */
+extern void (*XIic_AddrAsSlaveFuncPtr) (XIic * InstancePtr);
+extern void (*XIic_NotAddrAsSlaveFuncPtr) (XIic * InstancePtr);
+extern void (*XIic_RecvSlaveFuncPtr) (XIic * InstancePtr);
+extern void (*XIic_SendSlaveFuncPtr) (XIic * InstancePtr);
+extern void (*XIic_RecvMasterFuncPtr) (XIic * InstancePtr);
+extern void (*XIic_SendMasterFuncPtr) (XIic * InstancePtr);
+extern void (*XIic_ArbLostFuncPtr) (XIic * InstancePtr);
+extern void (*XIic_BusNotBusyFuncPtr) (XIic * InstancePtr);
+
+void XIic_TransmitFifoFill(XIic * InstancePtr, int Role);
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/drivers/i2c/xilinx_iic/xiic_intr.c linux-2.4.29-uc1/drivers/i2c/xilinx_iic/xiic_intr.c
--- linux-2.4.29/drivers/i2c/xilinx_iic/xiic_intr.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/xilinx_iic/xiic_intr.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,448 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xiic_intr.c
+*
+* Contains interrupt functions of the XIic driver.  This file is required
+* for the driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.01a rfp  10/19/01 release
+* 1.01c ecm  12/05/02 new rev
+* 1.01c rmm  05/14/03 Fixed diab compiler warnings relating to asserts.
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xiic.h"
+#include "xiic_i.h"
+#include "xio.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions ******************/
+
+/*************** Macros (Inline Functions) Definitions ********************/
+
+/************************** Function Prototypes ****************************/
+
+static void StubFunction(XIic * InstancePtr);
+static void TxErrorHandler(XIic * InstancePtr);
+
+/*****************************************************************************
+ * This is a temporary workaround for the single master mode to work correctly.
+ * Until the platform independent IIC driver code is updated by Xilinx
+ * XIic_BusNotBusyFuncPtr must be initialized to BusNotBusyStub instead of
+ * StubFunction.
+ ****************************************************************************/
+static void
+BusNotBusyStub(XIic * InstancePtr)
+{
+	return;
+}
+
+/************************** Variable Definitions *****************************/
+
+/* The following function pointers are used to help allow finer partitioning
+ * of the driver such that some parts of it are optional. These pointers are
+ * setup by functions in the optional parts of the driver.
+ */
+void (*XIic_AddrAsSlaveFuncPtr) (XIic * InstancePtr) = StubFunction;
+void (*XIic_NotAddrAsSlaveFuncPtr) (XIic * InstancePtr) = StubFunction;
+void (*XIic_RecvSlaveFuncPtr) (XIic * InstancePtr) = StubFunction;
+void (*XIic_SendSlaveFuncPtr) (XIic * InstancePtr) = StubFunction;
+void (*XIic_RecvMasterFuncPtr) (XIic * InstancePtr) = StubFunction;
+void (*XIic_SendMasterFuncPtr) (XIic * InstancePtr) = StubFunction;
+void (*XIic_ArbLostFuncPtr) (XIic * InstancePtr) = StubFunction;
+void (*XIic_BusNotBusyFuncPtr) (XIic * InstancePtr) = BusNotBusyStub;
+
+/*****************************************************************************/
+/**
+*
+* This function is the interrupt handler for the XIic driver. This function
+* should be connected to the interrupt system.
+*
+* Only one interrupt source is handled for each interrupt allowing
+* higher priority system interrupts quicker response time.
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+*
+* @return
+*
+* None.
+*
+* @internal
+*
+* The XIIC_INTR_ARB_LOST_MASK and XIIC_INTR_TX_ERROR_MASK interrupts must have
+* higher priority than the other device interrupts so that the IIC device does
+* not get into a potentially confused state. The remaining interrupts may be
+* rearranged with no harm.
+*
+* All XIic device interrupts are ORed into one device interrupt. This routine
+* reads the pending interrupts via the IpIf interface and masks that with the
+* interrupt mask to evaluate only the interrupts enabled.
+*
+******************************************************************************/
+void
+XIic_InterruptHandler(void *InstancePtr)
+{
+	u8 Status;
+	u32 IntrStatus;
+	u32 IntrPending;
+	u32 IntrEnable;
+	XIic *IicPtr = NULL;
+	u32 Clear = 0;
+
+	/*
+	 * Verify that each of the inputs are valid.
+	 */
+	XASSERT_VOID(InstancePtr != NULL);
+
+	/*
+	 * Convert the non-typed pointer to an IIC instance pointer
+	 */
+	IicPtr = (XIic *) InstancePtr;
+
+	/* Get the interrupt Status from the IPIF. There is no clearing of
+	 * interrupts in the IPIF. Interrupts must be cleared at the source.
+	 * To find which interrupts are pending; AND interrupts pending with
+	 * interrupts masked.
+	 */
+	IntrPending = XIIF_V123B_READ_IISR(IicPtr->BaseAddress);
+	IntrEnable = XIIF_V123B_READ_IIER(IicPtr->BaseAddress);
+	IntrStatus = IntrPending & IntrEnable;
+
+	/* Do not processes a devices interrupts if the device has no
+	 * interrupts pending or the global interrupts have been disabled
+	 */
+
+	if ((IntrStatus == 0) |
+	    (XIIF_V123B_IS_GINTR_ENABLED(IicPtr->BaseAddress) == FALSE)) {
+		return;
+	}
+
+	/* Update interrupt stats and get the contents of the status register
+	 */
+	IicPtr->Stats.IicInterrupts++;
+	Status = XIo_In8(IicPtr->BaseAddress + XIIC_SR_REG_OFFSET);
+
+	/* Service requesting interrupt
+	 */
+	if (IntrStatus & XIIC_INTR_ARB_LOST_MASK) {
+		/* Bus Arbritration Lost */
+
+		IicPtr->Stats.ArbitrationLost++;
+		XIic_ArbLostFuncPtr(IicPtr);
+
+		Clear = XIIC_INTR_ARB_LOST_MASK;
+	}
+
+	else if (IntrStatus & XIIC_INTR_TX_ERROR_MASK) {
+		/* Transmit errors (no acknowledge) received */
+
+		IicPtr->Stats.TxErrors++;
+		TxErrorHandler(IicPtr);
+
+		Clear = XIIC_INTR_TX_ERROR_MASK;
+	}
+
+	else if (IntrStatus & XIIC_INTR_NAAS_MASK) {
+		/* Not Addressed As Slave */
+
+		XIic_NotAddrAsSlaveFuncPtr(IicPtr);
+		Clear = XIIC_INTR_NAAS_MASK;
+	}
+
+	else if (IntrStatus & XIIC_INTR_RX_FULL_MASK) {
+		/* Receive register/FIFO is full */
+
+		IicPtr->Stats.RecvInterrupts++;
+
+		if (Status & XIIC_SR_ADDR_AS_SLAVE_MASK) {
+			XIic_RecvSlaveFuncPtr(InstancePtr);
+		} else {
+			XIic_RecvMasterFuncPtr(InstancePtr);
+		}
+
+		Clear = XIIC_INTR_RX_FULL_MASK;
+	}
+
+	else if (IntrStatus & XIIC_INTR_AAS_MASK) {
+		/* Addressed As Slave */
+
+		XIic_AddrAsSlaveFuncPtr(IicPtr);
+		Clear = XIIC_INTR_AAS_MASK;
+	}
+
+	else if (IntrStatus & XIIC_INTR_BNB_MASK) {
+		/* IIC bus has transitioned to not busy */
+
+		/* check if send callback needs to run */
+		if (IicPtr->BNBOnly == TRUE) {
+			XIic_BusNotBusyFuncPtr(IicPtr);
+			IicPtr->BNBOnly = FALSE;
+		} else {
+			IicPtr->SendHandler(IicPtr->SendCallBackRef, 0);
+		}
+
+		Clear = XIIC_INTR_BNB_MASK;
+
+		/* The bus is not busy, disable BusNotBusy interrupt */
+		XIic_mDisableIntr(IicPtr->BaseAddress, XIIC_INTR_BNB_MASK);
+
+	}
+
+	else if ((IntrStatus & XIIC_INTR_TX_EMPTY_MASK) ||
+		 (IntrStatus & XIIC_INTR_TX_HALF_MASK)) {
+		/* Transmit register/FIFO is empty or ½ empty *
+		 */
+		IicPtr->Stats.SendInterrupts++;
+
+		if (Status & XIIC_SR_ADDR_AS_SLAVE_MASK) {
+			XIic_SendSlaveFuncPtr(InstancePtr);
+		} else {
+			XIic_SendMasterFuncPtr(InstancePtr);
+		}
+
+		/* Clear Interrupts
+		 */
+		IntrStatus = XIIF_V123B_READ_IISR(IicPtr->BaseAddress);
+		Clear = IntrStatus & (XIIC_INTR_TX_EMPTY_MASK |
+				      XIIC_INTR_TX_HALF_MASK);
+	}
+
+	XIIF_V123B_WRITE_IISR(IicPtr->BaseAddress, Clear);
+}
+
+/******************************************************************************
+*
+* This function fills the FIFO using the occupancy register to determine the
+* available space to be filled. When the repeated start option is on, the last
+* byte is withheld to allow the control register to be properly set on the last
+* byte.
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+*
+* @param    Role indicates the role of this IIC device, a slave or a master, on
+*           the IIC bus (XIIC_SLAVE_ROLE or XIIC_MASTER_ROLE)
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XIic_TransmitFifoFill(XIic * InstancePtr, int Role)
+{
+	u8 AvailBytes;
+	s32 LoopCnt;
+	s32 NumBytesToSend;
+
+	/* Determine number of bytes to write to FIFO. Number of bytes that can be
+	 * put into the FIFO is (FIFO depth) - (current occupancy + 1)
+	 * When more room in FIFO than msg bytes put all of message in the FIFO.
+	 */
+	AvailBytes = IIC_TX_FIFO_DEPTH -
+	    (XIo_In8(InstancePtr->BaseAddress + XIIC_TFO_REG_OFFSET) + 1);
+
+	if (InstancePtr->SendByteCount > AvailBytes) {
+		NumBytesToSend = AvailBytes;
+	} else {
+		/* More space in FIFO than bytes in message
+		 */
+		if ((InstancePtr->Options & XII_REPEATED_START_OPTION) ||
+		    (Role == XIIC_SLAVE_ROLE)) {
+			NumBytesToSend = InstancePtr->SendByteCount;
+		} else {
+			NumBytesToSend = InstancePtr->SendByteCount - 1;
+		}
+	}
+
+	/* fill FIFO with amount determined above */
+
+	for (LoopCnt = 0; LoopCnt < NumBytesToSend; LoopCnt++) {
+		XIic_mWriteSendByte(InstancePtr);
+	}
+}
+
+/*****************************************************************************/
+/**
+*
+* This interrupt occurs four different ways: Two as master and two as slave.
+* Master:
+* <pre>
+*  (1) Transmitter (IMPLIES AN ERROR)
+*      The slave receiver did not acknowledge properly.
+*  (2) Receiver (Implies tx complete)
+*      Interrupt caused by setting TxAck high in the IIC to indicate to the
+*      the last byte has been transmitted.
+* </pre>
+*
+* Slave:
+* <pre>
+*  (3) Transmitter (Implies tx complete)
+*      Interrupt caused by master device indicating last byte of the message
+*      has been transmitted.
+*  (4) Receiver (IMPLIES AN ERROR)
+*      Interrupt caused by setting TxAck high in the IIC to indicate Rx
+*      IIC had a problem - set by this device and condition already known
+*      and interrupt is not enabled.
+* </pre>
+*
+* This interrupt is enabled during Master send and receive and disabled
+* when this device knows it is going to send a negative acknowledge (Ack = No).
+*
+* Signals user of Tx error via status callback sending: XII_TX_ERROR_EVENT
+*
+* When MasterRecv has no message to send and only receives one byte of data
+* from the salve device, the TxError must be enabled to catch addressing
+* errors, yet there is not opportunity to disable TxError when there is no
+* data to send allowing disabling on last byte. When the slave sends the
+* only byte the NOAck causes a Tx Error. To disregard this as no real error,
+* when there is data in the Receive FIFO/register then the error was not
+* a device address write error, but a NOACK read error - to be ignored.
+* To work with or without FIFO's, the Rx Data interrupt is used to indicate
+* data is in the rx register.
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* No action is required to clear this interrupt in the device as it is a
+* pulse. The interrupt need only be cleared in the IpIf interface.
+*
+******************************************************************************/
+static void
+TxErrorHandler(XIic * InstancePtr)
+{
+	u32 IntrStatus;
+	u8 CntlReg;
+
+	/* When Sending as a slave, Tx error signals end of msg. Not Addressed As
+	 * Slave will handle the callbacks. this is used to only flush the Tx fifo.
+	 * The addressed as slave bit is gone as soon as the bus has been released
+	 * such that the buffer pointers are used to determine the direction of
+	 * transfer (send or receive).
+	 */
+	if (InstancePtr->RecvBufferPtr == NULL) {
+		/* Master Receiver finished reading message. Flush Tx fifo to remove an
+		 * 0xFF that was written to prevent bus throttling, and disable all
+		 * transmit and receive interrupts
+		 */
+		XIic_mFlushTxFifo(InstancePtr);
+		XIic_mDisableIntr(InstancePtr->BaseAddress,
+				  XIIC_TX_RX_INTERRUPTS);
+
+		return;
+	}
+
+	/* Data in the receive register from either master or slave receive
+	 * When:slave, indicates master sent last byte, message completed.
+	 * When:master, indicates a master Receive with one byte received. When a
+	 * byte is in Rx reg then the Tx error indicates the Rx data was recovered
+	 * normally Tx errors are not enabled such that this should not occur.
+	 */
+	IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
+	if (IntrStatus & XIIC_INTR_RX_FULL_MASK) {
+		/* Rx Reg/FIFO has data,  Disable tx error interrupts */
+
+		XIic_mDisableIntr(InstancePtr->BaseAddress,
+				  XIIC_INTR_TX_ERROR_MASK);
+		return;
+	}
+
+	XIic_mFlushTxFifo(InstancePtr);
+
+	/* Disable and clear tx empty, ½ empty, Rx Full or tx error interrupts
+	 */
+	XIic_mDisableIntr(InstancePtr->BaseAddress, XIIC_TX_RX_INTERRUPTS);
+	XIic_mClearIntr(InstancePtr->BaseAddress, XIIC_TX_RX_INTERRUPTS);
+
+	/* Clear MSMS as on TX error when Rxing, the bus will be
+	 * stopped but MSMS bit is still set. Reset to proper state
+	 */
+	CntlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
+	CntlReg &= ~XIIC_CR_MSMS_MASK;
+	XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET, CntlReg);
+
+	/* set FIFO occupancy depth = 1 so that the first byte will throttle
+	 * next recieve msg
+	 */
+	XIo_Out8(InstancePtr->BaseAddress + XIIC_RFD_REG_OFFSET, 0);
+
+	/* make event callback */
+
+	InstancePtr->StatusHandler(InstancePtr->StatusCallBackRef,
+				   XII_SLAVE_NO_ACK_EVENT);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function is a stub function that is used for the default function for
+* events that are handled optionally only when the appropriate modules are
+* linked in.  Function pointers are used to handle some events to allow
+* some events to be optionally handled.
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+*
+******************************************************************************/
+static void
+StubFunction(XIic * InstancePtr)
+{
+	XASSERT_VOID_ALWAYS();
+}
diff -urN linux-2.4.29/drivers/i2c/xilinx_iic/xiic_l.h linux-2.4.29-uc1/drivers/i2c/xilinx_iic/xiic_l.h
--- linux-2.4.29/drivers/i2c/xilinx_iic/xiic_l.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/xilinx_iic/xiic_l.h	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,165 @@
+/*****************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*****************************************************************************/
+/****************************************************************************/
+/**
+*
+* @file xiic_l.h
+*
+* This header file contains identifiers and low-level driver functions (or
+* macros) that can be used to access the device.  High-level driver functions
+* are defined in xiic.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00b jhl  05/07/02 First release
+* 1.01c ecm  12/05/02 new rev
+* </pre>
+*
+*****************************************************************************/
+
+#ifndef XIIC_L_H		/* prevent circular inclusions */
+#define XIIC_L_H		/* by using protection macros */
+
+/***************************** Include Files ********************************/
+
+#include "xbasic_types.h"
+
+/************************** Constant Definitions ****************************/
+
+#define XIIC_MSB_OFFSET                3
+
+#define XIIC_REG_OFFSET 0x100 + XIIC_MSB_OFFSET
+
+/*
+ * Register offsets in bytes from RegisterBase. Three is added to the
+ * base offset to access LSB (IBM style) of the word
+ */
+#define XIIC_CR_REG_OFFSET   0x00+XIIC_REG_OFFSET	/* Control Register   */
+#define XIIC_SR_REG_OFFSET   0x04+XIIC_REG_OFFSET	/* Status Register    */
+#define XIIC_DTR_REG_OFFSET  0x08+XIIC_REG_OFFSET	/* Data Tx Register   */
+#define XIIC_DRR_REG_OFFSET  0x0C+XIIC_REG_OFFSET	/* Data Rx Register   */
+#define XIIC_ADR_REG_OFFSET  0x10+XIIC_REG_OFFSET	/* Address Register   */
+#define XIIC_TFO_REG_OFFSET  0x14+XIIC_REG_OFFSET	/* Tx FIFO Occupancy  */
+#define XIIC_RFO_REG_OFFSET  0x18+XIIC_REG_OFFSET	/* Rx FIFO Occupancy  */
+#define XIIC_TBA_REG_OFFSET  0x1C+XIIC_REG_OFFSET	/* 10 Bit Address reg */
+#define XIIC_RFD_REG_OFFSET  0x20+XIIC_REG_OFFSET	/* Rx FIFO Depth reg  */
+
+/* Control Register masks */
+
+#define XIIC_CR_ENABLE_DEVICE_MASK        0x01	/* Device enable = 1      */
+#define XIIC_CR_TX_FIFO_RESET_MASK        0x02	/* Transmit FIFO reset=1  */
+#define XIIC_CR_MSMS_MASK                 0x04	/* Master starts Txing=1  */
+#define XIIC_CR_DIR_IS_TX_MASK            0x08	/* Dir of tx. Txing=1     */
+#define XIIC_CR_NO_ACK_MASK               0x10	/* Tx Ack. NO ack = 1     */
+#define XIIC_CR_REPEATED_START_MASK       0x20	/* Repeated start = 1     */
+#define XIIC_CR_GENERAL_CALL_MASK         0x40	/* Gen Call enabled = 1   */
+
+/* Status Register masks */
+
+#define XIIC_SR_GEN_CALL_MASK             0x01	/* 1=a mstr issued a GC   */
+#define XIIC_SR_ADDR_AS_SLAVE_MASK        0x02	/* 1=when addr as slave   */
+#define XIIC_SR_BUS_BUSY_MASK             0x04	/* 1 = bus is busy        */
+#define XIIC_SR_MSTR_RDING_SLAVE_MASK     0x08	/* 1=Dir: mstr <-- slave  */
+#define XIIC_SR_TX_FIFO_FULL_MASK         0x10	/* 1 = Tx FIFO full       */
+#define XIIC_SR_RX_FIFO_FULL_MASK         0x20	/* 1 = Rx FIFO full       */
+#define XIIC_SR_RX_FIFO_EMPTY_MASK        0x40	/* 1 = Rx FIFO empty      */
+
+/* IPIF Interrupt Status Register masks    Interrupt occurs when...       */
+
+#define XIIC_INTR_ARB_LOST_MASK           0x01	/* 1 = arbitration lost   */
+#define XIIC_INTR_TX_ERROR_MASK           0x02	/* 1=Tx error/msg complete */
+#define XIIC_INTR_TX_EMPTY_MASK           0x04	/* 1 = Tx FIFO/reg empty  */
+#define XIIC_INTR_RX_FULL_MASK            0x08	/* 1=Rx FIFO/reg=OCY level */
+#define XIIC_INTR_BNB_MASK                0x10	/* 1 = Bus not busy       */
+#define XIIC_INTR_AAS_MASK                0x20	/* 1 = when addr as slave */
+#define XIIC_INTR_NAAS_MASK               0x40	/* 1 = not addr as slave  */
+#define XIIC_INTR_TX_HALF_MASK            0x80	/* 1 = TX FIFO half empty */
+
+/* IPIF Device Interrupt Register masks */
+
+#define XIIC_IPIF_IIC_MASK          0x00000004UL	/* 1=inter enabled */
+#define XIIC_IPIF_ERROR_MASK        0x00000001UL	/* 1=inter enabled */
+#define XIIC_IPIF_INTER_ENABLE_MASK  (XIIC_IPIF_IIC_MASK |  \
+                                      XIIC_IPIF_ERROR_MASK)
+
+#define XIIC_TX_ADDR_SENT             0x00
+#define XIIC_TX_ADDR_MSTR_RECV_MASK   0x02
+
+/* The following constants specify the depth of the FIFOs */
+
+#define IIC_RX_FIFO_DEPTH         16	/* Rx fifo capacity               */
+#define IIC_TX_FIFO_DEPTH         16	/* Tx fifo capacity               */
+
+/* The following constants specify groups of interrupts that are typically
+ * enabled or disables at the same time
+ */
+#define XIIC_TX_INTERRUPTS                                          \
+            (XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_TX_EMPTY_MASK |    \
+             XIIC_INTR_TX_HALF_MASK)
+
+#define XIIC_TX_RX_INTERRUPTS (XIIC_INTR_RX_FULL_MASK | XIIC_TX_INTERRUPTS)
+
+/* The following constants are used with the following macros to specify the
+ * operation, a read or write operation.
+ */
+#define XIIC_READ_OPERATION  1
+#define XIIC_WRITE_OPERATION 0
+
+/* The following constants are used with the transmit FIFO fill function to
+ * specify the role which the IIC device is acting as, a master or a slave.
+ */
+#define XIIC_MASTER_ROLE     1
+#define XIIC_SLAVE_ROLE      0
+
+/**************************** Type Definitions ******************************/
+
+/***************** Macros (Inline Functions) Definitions ********************/
+
+/************************** Function Prototypes *****************************/
+
+unsigned XIic_Recv(u32 BaseAddress, u8 Address,
+		   u8 * BufferPtr, unsigned ByteCount);
+
+unsigned XIic_Send(u32 BaseAddress, u8 Address,
+		   u8 * BufferPtr, unsigned ByteCount);
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/drivers/i2c/xilinx_iic/xiic_master.c linux-2.4.29-uc1/drivers/i2c/xilinx_iic/xiic_master.c
--- linux-2.4.29/drivers/i2c/xilinx_iic/xiic_master.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/xilinx_iic/xiic_master.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,713 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xiic_master.c
+*
+* Contains master functions for the XIic component. This file is necessary to
+* send or receive as a master on the IIC bus.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- --- ------- -----------------------------------------------
+* 1.01b jhl 3/27/02 Reparitioned the driver
+* 1.01c ecm 12/05/02 new rev
+* </pre>
+*
+****************************************************************************/
+
+/***************************** Include Files *******************************/
+
+#include "xiic.h"
+#include "xiic_i.h"
+#include "xio.h"
+
+/************************** Constant Definitions ***************************/
+
+/**************************** Type Definitions *****************************/
+
+/***************** Macros (Inline Functions) Definitions *******************/
+
+/*****************************************************************************
+*
+* This macro includes master code such that master operations, sending
+* and receiving data, may be used.  This function hooks the master processing
+* to the driver such that events are handled properly and allows master
+* processing to be optional.  It must be called before any functions which
+* are contained in this file are called, such as after the driver is
+* initialized.
+*
+* @note
+*
+* None
+*
+******************************************************************************/
+#define XIIC_MASTER_INCLUDE                                             \
+{                                                                       \
+    XIic_RecvMasterFuncPtr = RecvMasterData;                            \
+    XIic_SendMasterFuncPtr = SendMasterData;                            \
+}
+
+/************************** Function Prototypes ****************************/
+
+static void SendSlaveAddr(XIic * InstancePtr);
+static void RecvMasterData(XIic * InstancePtr);
+static void SendMasterData(XIic * InstancePtr);
+static u32 IsBusBusy(XIic * InstancePtr);
+
+/************************** Variable Definitions **************************/
+
+/****************************************************************************/
+/**
+* This function sends data as a master on the IIC bus. If the bus is busy, it
+* will indicate so and then enable an interrupt such that the status handler
+* will be called when the bus is no longer busy.  The slave address which has
+* been set with the XIic_SetAddress() function is the address to which the
+* specific data is sent.  Sending data on the bus performs a write operation.
+*
+* @param    InstancePtr points to the Iic instance to be worked on.
+* @param    TxMsgPtr points to the data to be transmitted
+* @param    ByteCount is the number of message bytes to be sent
+*
+* @return
+*
+* - XST_SUCCESS indicates the message transmission has been initiated.
+* - XST_IIC_BUS_BUSY indicates the bus was in use and that the BusNotBusy
+*   interrupt is enabled which will update the EventStatus when the bus is no
+*   longer busy.
+*
+* @note
+*
+* None
+*
+******************************************************************************/
+XStatus
+XIic_MasterSend(XIic * InstancePtr, u8 * TxMsgPtr, int ByteCount)
+{
+	u8 CntlReg;
+
+	XIic_mEnterCriticalRegion(InstancePtr->BaseAddress);
+
+	/* Ensure that the master processing has been included such that events
+	 * will be properly handled
+	 */
+	XIIC_MASTER_INCLUDE;
+
+	/*
+	 * If the busy is busy, then exit the critical region and wait for the
+	 * bus to not be busy, the function enables the bus not busy interrupt
+	 */
+	if (IsBusBusy(InstancePtr)) {
+		XIic_mExitCriticalRegion(InstancePtr->BaseAddress);
+
+		return XST_IIC_BUS_BUSY;
+	}
+
+	/* If it is already a master on the bus (repeated start), the direction was
+	 * set to tx which is throttling bus.  The control register needs to be set
+	 * before putting data into the FIFO
+	 */
+	CntlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
+
+	if (CntlReg & XIIC_CR_MSMS_MASK) {
+		CntlReg &= ~XIIC_CR_NO_ACK_MASK;
+		CntlReg |=
+		    (XIIC_CR_DIR_IS_TX_MASK | XIIC_CR_REPEATED_START_MASK);
+
+		XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
+			 CntlReg);
+		InstancePtr->Stats.RepeatedStarts++;
+	}
+
+	/* Save message state
+	 */
+	InstancePtr->SendByteCount = ByteCount;
+	InstancePtr->SendBufferPtr = TxMsgPtr;
+
+	/* Put the address into the FIFO to be sent and indicate that the operation
+	 * to be performed on the bus is a write operation, a general call address
+	 * handled the same as a 7 bit address even if 10 bit address is selected
+	 * Set the transmit address state to indicate the address has been sent
+	 */
+	if ((InstancePtr->Options & XII_SEND_10_BIT_OPTION) &&
+	    (InstancePtr->AddrOfSlave != 0)) {
+		XIic_mSend10BitAddrByte1(InstancePtr->AddrOfSlave,
+					 XIIC_WRITE_OPERATION);
+		XIic_mSend10BitAddrByte2(InstancePtr->AddrOfSlave);
+	} else {
+		XIic_mSend7BitAddr(InstancePtr->AddrOfSlave,
+				   XIIC_WRITE_OPERATION);
+	}
+	/* Set the transmit address state to indicate the address has been sent
+	 * for communication with event driven processing
+	 */
+	InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
+
+	/* Fill remaining available FIFO with message data
+	 */
+	if (InstancePtr->SendByteCount > 1) {
+		XIic_TransmitFifoFill(InstancePtr, XIIC_MASTER_ROLE);
+	}
+
+	/* After filling fifo, if data yet to send > 1, enable Tx ½ empty interrupt
+	 */
+	if (InstancePtr->SendByteCount > 1) {
+		XIic_mClearEnableIntr(InstancePtr->BaseAddress,
+				      XIIC_INTR_TX_HALF_MASK);
+	}
+
+	/* Clear any pending Tx empty, Tx Error and then enable them.
+	 */
+	XIic_mClearEnableIntr(InstancePtr->BaseAddress,
+			      XIIC_INTR_TX_ERROR_MASK |
+			      XIIC_INTR_TX_EMPTY_MASK);
+
+	/* When repeated start not used, MSMS must be set after putting data into
+	 * transmit FIFO, start the transmitter
+	 */
+
+	CntlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
+	if ((CntlReg & XIIC_CR_MSMS_MASK) == 0) {
+		CntlReg &= ~XIIC_CR_NO_ACK_MASK;
+		CntlReg |= XIIC_CR_MSMS_MASK | XIIC_CR_DIR_IS_TX_MASK;
+		XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
+			 CntlReg);
+	}
+
+	XIic_mExitCriticalRegion(InstancePtr->BaseAddress);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+* This function receives data as a master from a slave device on the IIC bus.
+* If the bus is busy, it will indicate so and then enable an interrupt such
+* that the status handler will be called when the bus is no longer busy.  The
+* slave address which has been set with the XIic_SetAddress() function is the
+* address from which data is received. Receiving data on the bus performs a
+* read operation.
+*
+* @param    InstancePtr is a pointer to the Iic instance to be worked on.
+* @param    RxMsgPtr is a pointer to the data to be transmitted
+* @param    ByteCount is the number of message bytes to be sent
+*
+* @return
+*
+* - XST_SUCCESS indicates the message reception processes has been initiated.
+* - XST_IIC_BUS_BUSY indicates the bus was in use and that the BusNotBusy
+*   interrupt is enabled which will update the EventStatus when the bus is no
+*   longer busy.
+* - XST_IIC_GENERAL_CALL_ADDRESS indicates the slave address is set to the
+*   the general call address. This is not allowed for Master receive mode.
+*
+* @internal
+*
+* The receive FIFO threshold is a zero based count such that 1 must be
+* subtracted from the desired count to get the correct value. When receiving
+* data it is also necessary to not receive the last byte with the prior bytes
+* because the acknowledge must be setup before the last byte is received.
+*
+******************************************************************************/
+XStatus
+XIic_MasterRecv(XIic * InstancePtr, u8 * RxMsgPtr, int ByteCount)
+{
+	u8 CntlReg;
+	u8 Temp;
+
+	/* If the slave address is zero (general call) the master can't perform
+	 * receive operations, indicate an error
+	 */
+	if (InstancePtr->AddrOfSlave == 0) {
+		return XST_IIC_GENERAL_CALL_ADDRESS;
+	}
+
+	XIic_mEnterCriticalRegion(InstancePtr->BaseAddress);
+
+	/* Ensure that the master processing has been included such that events
+	 * will be properly handled
+	 */
+	XIIC_MASTER_INCLUDE;
+	/*
+	 * If the busy is busy, then exit the critical region and wait for the
+	 * bus to not be busy, the function enables the bus not busy interrupt
+	 */
+	if (IsBusBusy(InstancePtr)) {
+		XIic_mExitCriticalRegion(InstancePtr->BaseAddress);
+
+		return XST_IIC_BUS_BUSY;
+	}
+
+	/* Save message state for event driven processing
+	 */
+	InstancePtr->RecvByteCount = ByteCount;
+	InstancePtr->RecvBufferPtr = RxMsgPtr;
+
+	/* Clear and enable Rx full interrupt if using 7 bit, If 10 bit, wait until
+	 * last address byte sent incase arbitration gets lost while sending out
+	 * address.
+	 */
+	if ((InstancePtr->Options & XII_SEND_10_BIT_OPTION) == 0) {
+		XIic_mClearEnableIntr(InstancePtr->BaseAddress,
+				      XIIC_INTR_RX_FULL_MASK);
+	}
+
+	/* If already a master on the bus, the direction was set by Rx Interrupt
+	 * routine to tx which is throttling bus because during Rxing, Tx reg is
+	 * empty = throttle. CR needs setting before putting data or the address
+	 * written will go out as Tx instead of receive. Start Master Rx by setting
+	 * CR Bits MSMS to Master and msg direction.
+	 */
+	CntlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
+
+	if (CntlReg & XIIC_CR_MSMS_MASK) {
+		CntlReg |= XIIC_CR_REPEATED_START_MASK;
+		XIic_mSetControlRegister(InstancePtr, CntlReg, ByteCount);
+
+		InstancePtr->Stats.RepeatedStarts++;	/* increment stats counts */
+		XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
+			 CntlReg);
+
+	}
+
+	/* Set receive FIFO occupancy depth which must be done prior to writing the
+	 * address in the FIFO because the transmitter will immediatedly start when
+	 * in repeated start mode followed by the receiver such that the number of
+	 * bytes to receive should be set 1st.
+	 */
+	if (ByteCount == 1) {
+		Temp = 0;
+	} else {
+		if (ByteCount < IIC_RX_FIFO_DEPTH) {
+			Temp = ByteCount - 2;
+		} else {
+			Temp = IIC_RX_FIFO_DEPTH - 1;
+		}
+	}
+	XIo_Out8(InstancePtr->BaseAddress + XIIC_RFD_REG_OFFSET, Temp);
+
+	if (InstancePtr->Options & XII_SEND_10_BIT_OPTION) {
+		/* Send the 1st and 2nd byte of the 10 bit address of a write
+		 * operation, write because it's a 10 bit address
+		 */
+		XIic_mSend10BitAddrByte1(InstancePtr->AddrOfSlave,
+					 XIIC_WRITE_OPERATION);
+		XIic_mSend10BitAddrByte2(InstancePtr->AddrOfSlave);
+
+		/* Set flag to indicate the next byte of the address needs to be
+		 * send, clear and enable tx empty interrupt
+		 */
+		InstancePtr->TxAddrMode = XIIC_TX_ADDR_MSTR_RECV_MASK;
+		XIic_mClearEnableIntr(InstancePtr->BaseAddress,
+				      XIIC_INTR_TX_EMPTY_MASK);
+	} else {
+		/* 7 bit slave address, send the address for a read operation
+		 * and set the state to indicate the address has been sent
+		 */
+		XIic_mSend7BitAddr(InstancePtr->AddrOfSlave,
+				   XIIC_READ_OPERATION);
+		InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
+	}
+
+	/* Tx error is enabled incase the address (7 or 10) has no device to answer
+	 * with Ack. When only one byte of data, must set NO ACK before address goes
+	 * out therefore Tx error must not be enabled as it will go off immediately
+	 * and the Rx full interrupt will be checked.  If full, then the one byte
+	 * was received and the Tx error will be disabled without sending an error
+	 * callback msg.
+	 */
+	XIic_mClearEnableIntr(InstancePtr->BaseAddress,
+			      XIIC_INTR_TX_ERROR_MASK);
+
+	/*  When repeated start not used, MSMS gets set after putting data
+	 *  in Tx reg. Start Master Rx by setting CR Bits MSMS to Master and
+	 *  msg direction.
+	 */
+	CntlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
+	if ((CntlReg & XIIC_CR_MSMS_MASK) == 0) {
+		CntlReg |= XIIC_CR_MSMS_MASK;
+		XIic_mSetControlRegister(InstancePtr, CntlReg, ByteCount);
+		XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
+			 CntlReg);
+	}
+
+	XIic_mExitCriticalRegion(InstancePtr->BaseAddress);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************
+*
+* This function checks to see if the IIC bus is busy.  If so, it will enable
+* the bus not busy interrupt such that the driver is notified when the bus
+* is no longer busy.
+*
+* @param    InstancePtr points to the Iic instance to be worked on.
+*
+* @return
+*
+* - FALSE indicates the IIC bus is not busy.
+* - TRUE indicates the bus was in use and that the BusNotBusy
+*   interrupt is enabled which will update the EventStatus when the bus is no
+*   longer busy.
+*
+* @note
+*
+* None
+*
+******************************************************************************/
+static u32
+IsBusBusy(XIic * InstancePtr)
+{
+	u8 ControlReg;
+	u8 StatusReg;
+
+	ControlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
+	StatusReg = XIo_In8(InstancePtr->BaseAddress + XIIC_SR_REG_OFFSET);
+
+	/* If this device is already master of the bus as when using the repeated
+	 * start and the bus is busy setup to wait for it to not be busy
+	 */
+	if (((ControlReg & XIIC_CR_MSMS_MASK) == 0) &&	/* not master */
+	    (StatusReg & XIIC_SR_BUS_BUSY_MASK)) {	/* is busy    */
+		/* The bus is busy, clear pending BNB interrupt incase previously set
+		 * and then enable BusNotBusy interrupt
+		 */
+		InstancePtr->BNBOnly = TRUE;
+		XIic_mClearEnableIntr(InstancePtr->BaseAddress,
+				      XIIC_INTR_BNB_MASK);
+		InstancePtr->Stats.BusBusy++;
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+/******************************************************************************
+*
+* This function sends the proper byte of the address as well as generate the
+* proper address bit fields depending on the address byte required and the
+* direction of the data (write or read).
+*
+* A master receiving has the restriction that the direction must be switched
+* from write to read when the third address byte is transmitted.
+* For the last byte of the 10 bit address, repeated start must be set prior
+* to writing the address. If repeated start options is enabled, the
+* control register is written before the address is written to the tx reg.
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* This function does read/modify/write to the device control register. Calling
+* functions must ensure critical sections are used.
+*
+******************************************************************************/
+static void
+SendSlaveAddr(XIic * InstancePtr)
+{
+	u8 CRreg;
+
+	/* Set the control register for Master Receive, repeated start must be set
+	 * before writing the address, MSMS should be already set, don't set here
+	 * so if arbitration is lost or some other reason we don't want MSMS set
+	 * incase of error
+	 */
+	CRreg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
+
+	CRreg |= XIIC_CR_REPEATED_START_MASK;
+	CRreg &= ~XIIC_CR_DIR_IS_TX_MASK;
+
+	XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET, CRreg);
+
+	/* Send the 1st byte of the 10 bit address as a read operation, enable the
+	 * receive interrupt to know when data is received, assuming that the
+	 * receive FIFO threshold has been previously set
+	 */
+	XIic_mSend10BitAddrByte1(InstancePtr->AddrOfSlave, XIIC_READ_OPERATION);
+
+	XIic_mClearEnableIntr(InstancePtr->BaseAddress, XIIC_INTR_RX_FULL_MASK);
+}
+
+/******************************************************************************
+*
+* When the IIC Tx FIFO/register goes empty, this routine is called by the
+* interrupt service routine to fill the transmit FIFO with data to be sent.
+*
+* This function also is called by the Tx ½ empty interrupt as the data handling
+* is identical when you don't assume the FIFO is empty but use the Tx_FIFO_OCY
+* register to indicate the available free FIFO bytes.
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+SendMasterData(XIic * InstancePtr)
+{
+	u8 CntlReg;
+
+	/* The device is a master on the bus.  If there is still more address bytes
+	 * to send when in master receive operation and the slave device is 10 bit
+	 * addressed. This requires the lower 7 bits of address to be resent when
+	 * the mode switches to Read instead of write (while sending addresses).
+	 */
+	if (InstancePtr->TxAddrMode & XIIC_TX_ADDR_MSTR_RECV_MASK) {
+		/* Send the 1st byte of the slave address in the read operation
+		 * and change the state to indicate this has been done
+		 */
+		SendSlaveAddr(InstancePtr);
+		InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
+	}
+
+	/* In between 1st and last byte of message, fill the FIFO with more data
+	 * to send, disable the 1/2 empty interrupt based upon data left to send
+	 */
+	else if (InstancePtr->SendByteCount > 1) {
+		XIic_TransmitFifoFill(InstancePtr, XIIC_MASTER_ROLE);
+
+		if (InstancePtr->SendByteCount < 2) {
+			XIic_mDisableIntr(InstancePtr->BaseAddress,
+					  XIIC_INTR_TX_HALF_MASK);
+		}
+	}
+	/*
+	 * If there is only one byte left to send, processing differs between
+	 * repeated start and normal messages
+	 */
+	else if (InstancePtr->SendByteCount == 1) {
+		/* When using repeated start, another interrupt is expected after the
+		 * last byte has been sent, so the message is not done yet
+		 */
+		if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
+			XIic_mWriteSendByte(InstancePtr);
+		}
+
+		/* When not using repeated start, the stop condition must be generated
+		 * after the last byte is written. The bus is throttled waiting for the last
+		 * byte.
+		 */
+		else {
+			/* Set the stop condition before sending the last byte of data so that
+			 * the stop condition will be generated immediately following the data
+			 * another transmit interrupt is not expected so the message is done
+			 */
+
+			CntlReg =
+			    XIo_In8(InstancePtr->BaseAddress +
+				    XIIC_CR_REG_OFFSET);
+			CntlReg &= ~XIIC_CR_MSMS_MASK;
+			XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
+				 CntlReg);
+
+			XIic_mWriteSendByte(InstancePtr);
+
+			/* Wait for bus to not be busy before declaring message has
+			 * been sent for the no repeated start operation. The callback
+			 * will be called from the BusNotBusy part of the Interrupt
+			 * handler to ensure that the message is completely sent.
+			 * Disable the TX interrupts and enable the BNB interrupt
+			 */
+
+			InstancePtr->BNBOnly = FALSE;
+			XIic_mDisableIntr(InstancePtr->BaseAddress,
+					  XIIC_TX_INTERRUPTS);
+			XIic_mEnableIntr(InstancePtr->BaseAddress,
+					 XIIC_INTR_BNB_MASK);
+
+		}
+	} else {
+		if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
+			/* The message being sent has completed. When using repeated start
+			 * with no more bytes to send repeated start needs to be set in
+			 * the control register so that the bus will still be held by this
+			 * master
+			 */
+
+			CntlReg =
+			    XIo_In8(InstancePtr->BaseAddress +
+				    XIIC_CR_REG_OFFSET);
+			CntlReg |= XIIC_CR_REPEATED_START_MASK;
+			XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
+				 CntlReg);
+
+			/* If the message that was being sent has finished, disable all
+			 *transmit interrupts and call the callback that was setup to
+			 * indicate the message was sent, with 0 bytes remaining
+			 */
+
+			XIic_mDisableIntr(InstancePtr->BaseAddress,
+					  XIIC_TX_INTERRUPTS);
+			InstancePtr->SendHandler(InstancePtr->SendCallBackRef,
+						 0);
+		}
+	}
+
+	return;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function is called when the receive register is full. The number
+* of bytes received to cause the interrupt is adjustable using the Receive FIFO
+* Depth register. The number of bytes in the register is read in the Receive
+* FIFO occupancy register. Both these registers are zero based values (0-15)
+* such that a value of zero indicates 1 byte.
+*
+* For a Master Receiver to properly signal the end of a message, the data must
+* be read in up to the message length - 1, where control register bits will be
+* set for bus controls to occur on reading of the last byte.
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+RecvMasterData(XIic * InstancePtr)
+{
+	u8 LoopCnt;
+	int BytesInFifo;
+	int BytesToRead;
+	u8 CntlReg;
+
+	/* Device is a master receiving, get the contents of the control register
+	 * and determine the number of bytes in fifo to be read out
+	 */
+	CntlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
+	BytesInFifo = XIo_In8(InstancePtr->BaseAddress + XIIC_RFO_REG_OFFSET)
+	    + 1;
+
+	/* If data in FIFO holds all data to be retrieved - 1, set NOACK and
+	 * disable the tx error
+	 */
+	if ((InstancePtr->RecvByteCount - BytesInFifo) == 1) {
+		/* Disable tx error interrupt to prevent interrupt
+		 * as this device will cause it when it set NO ACK next
+		 */
+		XIic_mDisableIntr(InstancePtr->BaseAddress,
+				  XIIC_INTR_TX_ERROR_MASK);
+		XIic_mClearIntr(InstancePtr->BaseAddress,
+				XIIC_INTR_TX_ERROR_MASK);
+
+		/* Write control reg with NO ACK allowing last byte to
+		 * have the No ack set to indicate to slave last byte read.
+		 */
+		XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
+			 (CntlReg | XIIC_CR_NO_ACK_MASK));
+
+		/* Read one byte to clear a place for the last byte to be read
+		 * which will set the NO ACK
+		 */
+		XIic_mReadRecvByte(InstancePtr);
+	}
+
+	/* If data in FIFO is all the data to be received then get the data
+	 * and also leave the device in a good state for the next transaction
+	 */
+	else if ((InstancePtr->RecvByteCount - BytesInFifo) == 0) {
+		/* If repeated start option is off then the master should stop
+		 * using the bus, otherwise hold the bus, setting repeated start
+		 * stops the slave from transmitting data when the FIFO is read
+		 */
+		if ((InstancePtr->Options & XII_REPEATED_START_OPTION) == 0) {
+			CntlReg &= ~XIIC_CR_MSMS_MASK;
+		} else {
+			CntlReg |= XIIC_CR_REPEATED_START_MASK;
+		}
+		XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
+			 CntlReg);
+
+		/* Read data from the FIFO then set zero based FIFO read depth for a byte
+		 */
+		for (LoopCnt = 0; LoopCnt < BytesInFifo; LoopCnt++) {
+			XIic_mReadRecvByte(InstancePtr);
+		}
+		XIo_Out8(InstancePtr->BaseAddress + XIIC_RFD_REG_OFFSET, 0);
+
+		/* Disable Rx full interrupt and write the control reg with ACK allowing
+		 * next byte sent to be acknowledged automatically
+		 */
+		XIic_mDisableIntr(InstancePtr->BaseAddress,
+				  XIIC_INTR_RX_FULL_MASK);
+
+		XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
+			 (CntlReg & ~XIIC_CR_NO_ACK_MASK));
+
+		/* Send notification of msg Rx complete in RecvHandler callback
+		 */
+		InstancePtr->RecvHandler(InstancePtr->RecvCallBackRef, 0);
+	} else {
+		/* Fifo data not at n-1, read all but the last byte of data from the
+		 * slave, if more than a FIFO full yet to receive read a FIFO full
+		 */
+		BytesToRead = InstancePtr->RecvByteCount - BytesInFifo - 1;
+		if (BytesToRead > IIC_RX_FIFO_DEPTH) {
+			BytesToRead = IIC_RX_FIFO_DEPTH;
+		}
+
+		/* Read in data from the FIFO */
+
+		for (LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++) {
+			XIic_mReadRecvByte(InstancePtr);
+		}
+	}
+}
diff -urN linux-2.4.29/drivers/i2c/xilinx_iic/xiic_options.c linux-2.4.29-uc1/drivers/i2c/xilinx_iic/xiic_options.c
--- linux-2.4.29/drivers/i2c/xilinx_iic/xiic_options.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/i2c/xilinx_iic/xiic_options.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,176 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xiic_options.c
+*
+* Contains options functions for the XIic component. This file is not required
+* unless the functions in this file are called.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- --- ------- -----------------------------------------------
+* 1.01b jhl 3/26/02 repartioned the driver
+* 1.01c ecm 12/05/02 new rev
+* </pre>
+*
+****************************************************************************/
+
+/***************************** Include Files *******************************/
+
+#include "xiic.h"
+#include "xiic_i.h"
+#include "xio.h"
+
+/************************** Constant Definitions ***************************/
+
+/**************************** Type Definitions *****************************/
+
+/***************** Macros (Inline Functions) Definitions *******************/
+
+/************************** Function Prototypes ****************************/
+
+/************************** Variable Definitions **************************/
+
+/*****************************************************************************/
+/**
+*
+* This function sets the options for the IIC device driver. The options control
+* how the device behaves relative to the IIC bus. If an option applies to
+* how messages are sent or received on the IIC bus, it must be set prior to
+* calling functions which send or receive data.
+*
+* To set multiple options, the values must be ORed together. To not change
+* existing options, read/modify/write with the current options using
+* XIic_GetOptions().
+*
+* <b>USAGE EXAMPLE:</b>
+*
+* Read/modify/write to enable repeated start:
+* <pre>
+*   u8 Options;
+*   Options = XIic_GetOptions(&Iic);
+*   XIic_SetOptions(&Iic, Options | XII_REPEATED_START_OPTION);
+* </pre>
+*
+* Disabling General Call:
+* <pre>
+*   Options = XIic_GetOptions(&Iic);
+*   XIic_SetOptions(&Iic, Options &= ~XII_GENERAL_CALL_OPTION);
+* </pre>
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+*
+* @param    NewOptions are the options to be set.  See xiic.h for a list of
+*           the available options.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Sending or receiving messages with repeated start enabled, and then
+* disabling repeated start, will not take effect until another master
+* transaction is completed. i.e. After using repeated start, the bus will
+* continue to be throttled after repeated start is disabled until a master
+* transaction occurs allowing the IIC to release the bus.
+* <br><br>
+* Options enabled will have a 1 in its appropriate bit position.
+*
+****************************************************************************/
+void
+XIic_SetOptions(XIic * InstancePtr, u32 NewOptions)
+{
+	u8 CntlReg;
+
+	XASSERT_VOID(InstancePtr != NULL);
+
+	XIic_mEnterCriticalRegion(InstancePtr->BaseAddress);
+
+	/* Update the options in the instance and get the contents of the control
+	 * register such that the general call option can be modified
+	 */
+	InstancePtr->Options = NewOptions;
+	CntlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
+
+	/* The general call option is the only option that maps directly to
+	 * a hardware register feature
+	 */
+	if (NewOptions & XII_GENERAL_CALL_OPTION) {
+		CntlReg |= XIIC_CR_GENERAL_CALL_MASK;
+	} else {
+		CntlReg &= ~XIIC_CR_GENERAL_CALL_MASK;
+	}
+
+	/* Write the new control register value to the register */
+
+	XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET, CntlReg);
+
+	XIic_mExitCriticalRegion(InstancePtr->BaseAddress);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function gets the current options for the IIC device. Options control
+* the how the device behaves on the IIC bus. See SetOptions for more information
+* on options.
+*
+* @param    InstancePtr is a pointer to the XIic instance to be worked on.
+*
+* @return
+*
+* The options of the IIC device. See xiic.h for a list of available options.
+*
+* @note
+*
+* Options enabled will have a 1 in its appropriate bit position.
+*
+****************************************************************************/
+u32
+XIic_GetOptions(XIic * InstancePtr)
+{
+	XASSERT_NONVOID(InstancePtr != NULL);
+
+	return InstancePtr->Options;
+}
diff -urN linux-2.4.29/drivers/ide/arm/ess710ide.c linux-2.4.29-uc1/drivers/ide/arm/ess710ide.c
--- linux-2.4.29/drivers/ide/arm/ess710ide.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ide/arm/ess710ide.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,181 @@
+/****************************************************************************/
+
+/*
+ *	ess710ide.c -- IDE driver for the CF slot on the ESS710.
+ *
+ *	(C) Copyright 2004, Greg Ungerer <gerg@snapgear.com>
+ */
+
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/ide.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+
+/****************************************************************************/
+
+/*
+ *	Regiser offsets for the ESS710 CF/IDE port. It is mapped onto
+ *	CS3 of the IXP425. The IDE CS0 and CS1 liens are driven based
+ *	on A$ from the CS3/IXP425 address range.
+ */
+#define	ESS710IDE_IRQ	27
+#define	ESS710IDE_INT	IXP425_GPIO_PIN_10
+
+#define	ESS710IDE_BASE	0x53000000
+#define	ESS710IDE_CTRL	0x1e
+
+static unsigned char *ess710ide_basep;
+
+/****************************************************************************/
+
+/*
+ *	Define the CS3 mapping value. No real header file define support
+ *	for the appropriate fields or flags, so this is just the number,
+ */
+#define	ESS710IDE_CS3	0xbfff3c03
+#define	IXP425_CS_BEN	0x00000001
+
+/****************************************************************************/
+
+static void ess710ide_enable16(void)
+{
+	*IXP425_EXP_CS3 &= ~IXP425_CS_BEN;
+}
+
+/****************************************************************************/
+
+static void ess710ide_disable16(void)
+{
+	*IXP425_EXP_CS3 |= IXP425_CS_BEN;
+}
+
+/****************************************************************************/
+
+static u8 ess710ide_inb(unsigned long addr)
+{
+	return readb(addr);
+}
+
+/****************************************************************************/
+
+static u16 ess710ide_inw(unsigned long addr)
+{
+	u16 val;
+
+	ess710ide_enable16();
+	val = swab16(readw(addr));
+	ess710ide_disable16();
+
+	return val;
+}
+
+/****************************************************************************/
+
+static void ess710ide_insw(unsigned long addr, void *buf, u32 len)
+{
+	u16 *buf16p;
+
+	ess710ide_enable16();
+	for (buf16p = (u16 *) buf; (len > 0); len--)
+		*buf16p++ = swab16(readw(addr));
+	ess710ide_disable16();
+}
+
+/****************************************************************************/
+
+static void ess710ide_outb(u8 val, unsigned long addr)
+{
+	writeb(val, addr);
+}
+
+/****************************************************************************/
+
+static void ess710ide_outbsync(ide_drive_t *drive, u8 val, unsigned long addr)
+{
+	writeb(val, addr);
+}
+/****************************************************************************/
+
+static void ess710ide_outw(u16 val, unsigned long addr)
+{
+	ess710ide_enable16();
+	writew(swab16(val), addr);
+	ess710ide_disable16();
+}
+
+/****************************************************************************/
+
+static void ess710ide_outsw(unsigned long addr, void *buf, u32 len)
+{
+	u16 *buf16p;
+
+	ess710ide_enable16();
+	for (buf16p = (u16 *) buf; (len > 0); len--)
+		writew(swab16(*buf16p++), addr);
+	ess710ide_disable16();
+}
+
+/****************************************************************************/
+
+static int ess710ide_iack(ide_hwif_t *hwif)
+{
+	gpio_line_isr_clear(ESS710IDE_INT);
+	return 1;
+}
+
+/****************************************************************************/
+
+static int __init ess710_iomap(void)
+{
+	/* Enable GPIO line 10 as interrupt source */
+	gpio_line_config(ESS710IDE_INT, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
+	//gpio_line_config(ESS710IDE_INT, IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_HIGH);
+	gpio_line_isr_clear(ESS710IDE_INT);
+
+	/* Program chip selects to decode for IDE region */
+	*IXP425_EXP_CS3 |= 0xbfff3c03;
+
+	ess710ide_basep = ioremap(ESS710IDE_BASE, 0x1000);
+	if (ess710ide_basep == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+
+/****************************************************************************/
+
+void __init ess710ide_init(void)
+{
+	hw_regs_t hw;
+	ide_hwif_t *hwif;
+	int i;
+
+	if (ess710_iomap() < 0)
+		return;
+
+	memset(&hw, 0, sizeof(hw));
+	hw.irq = ESS710IDE_IRQ;
+	hw.dma = NO_DMA;
+	hw.ack_intr = ess710ide_iack;
+	for (i = 0; (i <= IDE_STATUS_OFFSET); i++)
+		hw.io_ports[i] = ess710ide_basep + i;
+	hw.io_ports[IDE_CONTROL_OFFSET] = ess710ide_basep + ESS710IDE_CTRL;
+
+	if (ide_register_hw(&hw, &hwif) != -1) {
+		hwif->mmio = 1;
+		hwif->OUTB = ess710ide_outb;
+		hwif->OUTBSYNC = ess710ide_outbsync;
+		hwif->OUTW = ess710ide_outw;
+		hwif->OUTSW = ess710ide_outsw;
+		hwif->INB = ess710ide_inb;
+		hwif->INW = ess710ide_inw;
+		hwif->INSW = ess710ide_insw;
+	}
+}
+
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/ide/arm/ide-ep93xx.c linux-2.4.29-uc1/drivers/ide/arm/ide-ep93xx.c
--- linux-2.4.29/drivers/ide/arm/ide-ep93xx.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ide/arm/ide-ep93xx.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,2043 @@
+/*****************************************************************************
+ *
+ * drivers/ide/ide-ep93xx.c
+ *
+ *  Copyright (c) 2003 Cirrus Logic, Inc.
+ *
+ * Some code based in whole or in part on:
+ *
+ *      linux/drivers/ide/ide-dma.c		Version 4.13	May 21, 2003
+ *
+ *      Copyright (c) 1999-2000	Andre Hedrick <andre@linux-ide.org>
+ *      May be copied or modified under the terms of the GNU General Public License
+ *
+ *      Portions Copyright Red Hat 2003
+ *
+ *      Special Thanks to Mark for his Six years of work.
+ *
+ *      Copyright (c) 1995-1998  Mark Lord
+ *      May be copied or modified under the terms of the GNU General Public License
+ *
+ *
+ * Some code taken from the PowerMac implentation
+ *
+ *      Copyright (C) 1998-2001 Paul Mackerras & Ben. Herrenschmidt
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ * ***************************************************************************
+ *
+ * Cirrus Logic's EP93XX architecture specific ide driver. This driver
+ * supports the following ide transfer modes:
+ *
+ *     PIO mode 4
+ *     UDMA modes 0 - 2
+ *
+ * This driver provides workarounds for the following hardware bugs:
+ *
+ * Write bug #1: If DDMARDYn is deasserted at the appropriate time (which is
+ *               within the ATA spec. and is therefore valid), 32-bits of data
+ *               to be written to the device is lost.  Since the upper 16-bits
+ *               of that word is written to the IDE data bus, but never strobed
+ *               to the device, this will also result in a CRC error (the
+ *               EP93xx CRC generator will see the 16-bit value, but the device
+ *               CRC generator will not).
+ *
+ *               This can be detected in two ways.  The first is the fact that
+ *               the DMA controller will complete the transfer while the device
+ *               is still requesting data.  This is not guaranteed to occur due
+ *               to the second write bug; the data from one incident of this
+ *               write bug will be offset by the data from two incidents of the
+ *               second write bug (see below).  The other is to look for CRC
+ *               errors.  If the device wants more data, the DMA controller is
+ *               given more data 32-bits at a time until the device is happy.
+ *
+ * Write bug #2: If a data out burst is terminated after an odd number of
+ *               16-bit words have been written to the device, the last 16-bit
+ *               word of the burst is repeated as the first 16-bit word of the
+ *               subsequent burst.  This also results in the last 16-bit word
+ *               of data being "lost" since it is never written to the device.
+ *               No CRC error occurs since the same data is seen by both the
+ *               EP93xx CRC generator and the device CRC generator.  If this
+ *               bug occurs only once during a single request, and the first
+ *               write bug does not occur during that request, then this is an
+ *               undetectable situation since the final "extra" 16-bit word is
+ *               transferred to the device, which simply ignores it.
+ *
+ *               This can be detected by seeing that the device no longs wants
+ *               data (it has deasserted DMARQ and has asserted INTRQ) but the
+ *               DMA controller has more data to transfer.
+ *
+ *               A single instance of this bug in a request can be detected by
+ *               reading back the data from the drive after each write.  This
+ *               is obviously not acceptable from a performance point of view.
+ *               Fortunately, this bug only appears to be triggered by old,
+ *               small drives.
+ *
+ * Read bug #1:  If a data in burst is terminated after an odd number of
+ *               16-bit words have been read from the device, the last 16-bit
+ *               word of the burst is lost.  Like write bug #2, no CRC error
+ *               occurs.  Note that this bug always occurs in pairs.  If it
+ *               actually happens one time, there will always be an odd number
+ *               of 16-bit words left to be read from the device.  Therefore,
+ *               it will happen again either in the middle of the remaining
+ *               data (leaving an even number of words remaining), or at the
+ *               end of the request.
+ *
+ *               This can be detected by seeing that the device has no more
+ *               data (it has deasserted DMARQ and has asserted INTRQ) but the
+ *               DMA controller still expects more data to transfer.
+ *
+ * Once any of these bugs is detected, the request is retried.  If the request
+ * can not be satisfied after RETRIES_PER_TRANSFER attempts, it is done in PIO
+ * mode.  If FAILURES_BEFORE_BACKOFF requests in a row can not be completed
+ * successfully (including retries), the transfer mode is backed down (i.e.
+ * moving to UDMA1 instead of UDMA2).  Lower transfer modes are less likely
+ * to be affected by these bugs, so a slower data transfer rate with less
+ * retries will be better than a higher data transfer rate with more retries.
+ *
+ * The transfer mode and retries are managed independently for the two devices
+ * on the IDE bus.  So, if the master device doesn't excite these bugs, but the
+ * slave device does, the transfer rate of the master device isn't affected by
+ * the slow down/retries on the slave device.
+ *
+ ****************************************************************************/
+#include <linux/ide.h>
+#include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <asm/io.h>
+#include <asm/ide.h>
+#include <asm/irq.h>
+#include <asm/arch/ide.h>
+#include <asm/arch/dma.h>
+#include <asm/hardware.h>
+
+/*****************************************************************************
+ *
+ * Debugging macros
+ *
+ ****************************************************************************/
+#undef DEBUG
+//#define DEBUG 1
+#ifdef DEBUG
+#define DPRINTK( fmt, arg... )  printk( fmt, ##arg )
+#else
+#define DPRINTK( fmt, arg... )
+#endif
+
+/*****************************************************************************
+ *
+ * Functions and macros for handling dma transfers.
+ *
+ ****************************************************************************/
+#define RETRIES_PER_TRANSFER			5
+#define FAILURES_BEFORE_BACKOFF			50
+
+/*****************************************************************************
+ *
+ * Global to keep track of the number of entries in the dma buffer
+ * table for each transfer.
+ *
+ ****************************************************************************/
+static int g_prd_count;
+static unsigned int g_prd_total;
+static unsigned int g_prd_returned;
+static unsigned int *g_dma_table_base;
+
+/*****************************************************************************
+ *
+ * Global to set during the DMA callback function to indicate that a DMA
+ * error occurred (i.e. the DMA completed while the device was still
+ * requesting).
+ *
+ ****************************************************************************/
+static unsigned int g_bad = 0;
+
+/*****************************************************************************
+ *
+ * A garbage word that is used to satify additional DMA requests from the
+ * device.
+ *
+ ****************************************************************************/
+static unsigned long g_garbage;
+
+/*****************************************************************************
+ *
+ * The particulars of the most recent command that was executed.
+ *
+ ****************************************************************************/
+static unsigned long g_cmd = 0;
+static ide_drive_t *g_drive = NULL;
+static unsigned long g_sector = 0;
+static unsigned long g_nr_sectors = 0;
+static unsigned long g_cur_retries = 0;
+
+/*****************************************************************************
+ *
+ * The count of consective DMA request errors.  For each array, the first
+ * entry is for hda reads, the second for hda writes, the third for hdb reads,
+ * and the forth for hdb writes.
+ *
+ ****************************************************************************/
+static unsigned long g_errors[4] = { 0, 0, 0, 0 };
+
+/*****************************************************************************
+ *
+ * Some statistics that are gathered about the transfers.  For each array, the
+ * first entry is for hda reads, the second for hda writes, the third for hdb
+ * reads, and the fourth for hdb writes.
+ *
+ ****************************************************************************/
+static unsigned long g_sectors[4] = { 0, 0, 0, 0 };
+static unsigned long g_xfers[4] = { 0, 0, 0, 0 };
+static unsigned long g_retries[4] = { 0, 0, 0, 0 };
+static unsigned long g_max_retries[4] = { 0, 0, 0, 0 };
+
+/*****************************************************************************
+ *
+ * Forward declarations.
+ *
+ ****************************************************************************/
+static int ep93xx_ide_dma_on(ide_drive_t *drive);
+static int ep93xx_ide_dma_off(ide_drive_t *drive);
+static int ep93xx_ide_dma_begin(ide_drive_t *drive);
+static int ep93xx_ide_dma_end(ide_drive_t *drive);
+static int ep93xx_ide_dma_host_on(ide_drive_t *drive);
+
+/*****************************************************************************
+ *
+ * The following is directly from ide-dma.c.
+ *
+ ****************************************************************************/
+struct drive_list_entry
+{
+	const char * id_model;
+	const char * id_firmware;
+};
+
+static const struct
+drive_list_entry drive_blacklist [] =
+{
+	{ "WDC AC11000H",			"ALL"		},
+	{ "WDC AC22100H",			"ALL"		},
+	{ "WDC AC32500H",			"ALL"		},
+	{ "WDC AC33100H",			"ALL"		},
+	{ "WDC AC31600H",			"ALL"		},
+	{ "WDC AC32100H",			"24.09P07"	},
+	{ "WDC AC23200L",			"21.10N21"	},
+	{ "Compaq CRD-8241B",			"ALL"		},
+	{ "CRD-8400B",				"ALL"		},
+	{ "CRD-8480B",				"ALL"		},
+	{ "CRD-8480C",				"ALL"		},
+	{ "CRD-8482B",				"ALL"		},
+	{ "CRD-84",				"ALL"		},
+	{ "SanDisk SDP3B",			"ALL"		},
+	{ "SanDisk SDP3B-64",			"ALL"		},
+	{ "SANYO CD-ROM CRD",			"ALL"		},
+	{ "HITACHI CDR-8",			"ALL"		},
+	{ "HITACHI CDR-8335",			"ALL"		},
+	{ "HITACHI CDR-8435",			"ALL"		},
+	{ "Toshiba CD-ROM XM-6202B",		"ALL"		},
+	{ "CD-532E-A",				"ALL"		},
+	{ "E-IDE CD-ROM CR-840",		"ALL"		},
+	{ "CD-ROM Drive/F5A",			"ALL"		},
+	{ "RICOH CD-R/RW MP7083A",		"ALL"		},
+	{ "WPI CDD-820",			"ALL"		},
+	{ "SAMSUNG CD-ROM SC-148C",		"ALL"		},
+	{ "SAMSUNG CD-ROM SC-148F",		"ALL"		},
+	{ "SAMSUNG CD-ROM SC",			"ALL"		},
+	{ "SanDisk SDP3B-64",			"ALL"		},
+	{ "SAMSUNG CD-ROM SN-124",		"ALL"		},
+	{ "PLEXTOR CD-R PX-W8432T",		"ALL"		},
+	{ "ATAPI CD-ROM DRIVE 40X MAXIMUM",	"ALL"		},
+	{ "_NEC DV5800A",			"ALL"		},
+	{ NULL,					NULL		}
+};
+
+/*****************************************************************************
+ *
+ *	This is directly from ide-dma.c
+ *
+ *  in_drive_list	-	look for drive in black/white list
+ *	@id: drive identifier
+ *	@drive_table: list to inspect
+ *
+ *	Look for a drive in the blacklist and the whitelist tables
+ *	Returns 1 if the drive is found in the table.
+ *
+ ****************************************************************************/
+static int
+in_drive_list(struct hd_driveid *id,
+              const struct drive_list_entry *drive_table)
+{
+	for ( ; drive_table->id_model ; drive_table++)
+		if ((!strcmp(drive_table->id_model, id->model)) &&
+		    ((!strstr(drive_table->id_firmware, id->fw_rev)) ||
+		     (!strcmp(drive_table->id_firmware, "ALL"))))
+			return 1;
+	return 0;
+}
+
+/*****************************************************************************
+ *
+ * Return some statistics that are gathered about the operation of the IDE
+ * driver.
+ *
+ ****************************************************************************/
+#ifdef CONFIG_PROC_FS
+static int
+ep93xx_get_info(char *buffer, char **addr, off_t offset, int count)
+{
+	char *p = buffer;
+
+	p += sprintf(p, "               sectors    requests     retries"
+			                 "         max\n");
+	p += sprintf(p, "hda read :  %10ld  %10ld  %10ld  %10ld\n",
+		     g_sectors[0], g_xfers[0], g_retries[0], g_max_retries[0]);
+	p += sprintf(p, "hda write:  %10ld  %10ld  %10ld  %10ld\n",
+		     g_sectors[1], g_xfers[1], g_retries[1], g_max_retries[1]);
+	p += sprintf(p, "hdb read :  %10ld  %10ld  %10ld  %10ld\n",
+		     g_sectors[2], g_xfers[2], g_retries[2], g_max_retries[2]);
+	p += sprintf(p, "hdb write:  %10ld  %10ld  %10ld  %10ld\n",
+		     g_sectors[3], g_xfers[3], g_retries[3], g_max_retries[3]);
+
+	return p - buffer;
+}
+#endif
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_intr() is the handler for disk read/write DMA interrupts
+ *
+ ****************************************************************************/
+static ide_startstop_t
+ep93xx_ide_dma_intr (ide_drive_t *drive)
+{
+	struct request *rq = HWGROUP(drive)->rq;
+	byte stat, dma_stat;
+	int i;
+
+	DPRINTK("%s: ep93xx_ide_dma_intr\n", drive->name);
+
+	/*
+	 * Disable the DMA for this transfer and cleanup.
+	 */
+	dma_stat = HWIF(drive)->ide_dma_end(drive);
+
+	/*
+	 * Get status from the ide device.
+	 */
+	stat = HWIF(drive)->INB(IDE_STATUS_REG);
+
+	/*
+	 * Retry the transfer if a DMA error occurred.
+	 */
+	if(dma_stat)
+		return ide_stopped;
+
+	/*
+	 * See if the drive returned an error.
+	 */
+	if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
+		/*
+		 * Complete the request.
+		 */
+		for (i = rq->nr_sectors; i > 0;) {
+			i -= rq->current_nr_sectors;
+			DRIVER(drive)->end_request(drive, 1);
+		}
+
+		/*
+		 * The transfer has been completed.
+		 */
+		return ide_stopped;
+	}
+
+	/*
+	 * Print out an error.
+	 */
+	return DRIVER(drive)->error(drive, __FUNCTION__, stat);
+}
+
+/****************************************************************************
+ *
+ * Map a set of buffers described by scatterlist in streaming
+ * mode for DMA.  This is the scather-gather version of the
+ * above pci_map_single interface.  Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length.  They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ *       DMA address/length pairs than there are SG table elements.
+ *       (for example via virtual mapping capabilities)
+ *       The routine returns the number of addr/length pairs actually
+ *       used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ *
+ ****************************************************************************/
+static inline int
+ep93xx_map_sg(struct scatterlist *sg, unsigned int entries,
+              unsigned int direction)
+{
+	unsigned int loop;
+
+	for (loop = 0; loop < entries; loop++, sg++) {
+		consistent_sync(sg->address, sg->length, direction);
+		sg->dma_address = virt_to_bus(sg->address);
+	}
+
+	return entries;
+}
+
+/*****************************************************************************
+ *
+ * ide_build_sglist()
+ *
+ * Builds a table of buffers to be used by the dma.  Each buffer consists
+ * of a region of memory which is contiguous in virtual memory.
+ *
+ ****************************************************************************/
+static int
+ide_build_sglist(ide_hwif_t *hwif, struct request *rq)
+{
+	struct buffer_head *buf_head;
+	struct scatterlist *sg = hwif->sg_table;
+	int nents = 0;
+
+	DPRINTK("%s: ide_build_sglist: sg_table 0x%08lx\n", hwif->name,
+		(unsigned long)hwif->sg_table);
+
+	if (hwif->sg_dma_active)
+		BUG();
+
+	/*
+	 * Set up the direction of the command
+	 */
+	if (rq->cmd == READ)
+		hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
+	else
+		hwif->sg_dma_direction = PCI_DMA_TODEVICE;
+
+	/*
+	 * Get a pointer to the buffer head.
+	 */
+	buf_head = rq->bh;
+
+	do {
+		unsigned char *virt_addr = buf_head->b_data;
+		unsigned int size = buf_head->b_size;
+
+		if (nents >= PRD_ENTRIES)
+			return 0;
+
+		while ((buf_head = buf_head->b_reqnext) != NULL) {
+			if ((virt_addr + size) !=
+			    (unsigned char *)buf_head->b_data)
+				break;
+
+			size += buf_head->b_size;
+		}
+		memset(&sg[nents], 0, sizeof(*sg));
+		sg[nents].address = virt_addr;
+		sg[nents].length = size;
+		nents++;
+	} while (buf_head != NULL);
+
+	/*
+	 * This call to map_sg will return the number of entries
+	 * for which DMAable memory could be mapped.
+	 */
+	return ep93xx_map_sg(sg, nents, hwif->sg_dma_direction);
+}
+
+/*****************************************************************************
+ *
+ * ide_build_dmatable() prepares a dma request.
+ * Returns 0 if all went okay, returns 1 otherwise.
+ *
+ ****************************************************************************/
+static int
+ide_build_dmatable(ide_drive_t *drive)
+{
+	unsigned int *table = HWIF(drive)->dmatable_cpu = g_dma_table_base;
+	unsigned int count = 0;
+	int i;
+	struct scatterlist *sg;
+
+	DPRINTK("%s: ide_build_dmatable\n", drive->name);
+
+	HWIF(drive)->sg_nents = i = ide_build_sglist(HWIF(drive),
+						     HWGROUP(drive)->rq);
+
+	if (!i)
+		return 0;
+
+	sg = HWIF(drive)->sg_table;
+
+	while (i && sg_dma_len(sg)) {
+		u32 cur_addr;
+		u32 cur_len;
+
+		cur_addr = sg_dma_address(sg);
+		cur_len = sg_dma_len(sg);
+
+		/*
+		 * Fill in the dma table, without crossing any 64kB boundaries.
+		 * Most hardware requires 16-bit alignment of all blocks,
+		 * but the trm290 requires 32-bit alignment.
+		 */
+		while (cur_len) {
+			if (count++ >= PRD_ENTRIES) {
+				printk("%s: DMA table too small\n", drive->name);
+				goto use_pio_instead;
+			} else {
+				u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff);
+
+				if (bcount > cur_len)
+					bcount = cur_len;
+				*table++ = cur_addr;
+				xcount = bcount & 0xffff;
+				if (xcount == 0x0000) {
+					/*
+					 * Most chipsets correctly interpret a
+					 * length of 0x0000 as 64KB, but at
+					 * least one (e.g. CS5530)
+					 * misinterprets it as zero (!).  So
+					 * here we break the 64KB entry into
+					 * two 32KB entries instead.
+					 */
+					if (count++ >= PRD_ENTRIES) {
+						printk("%s: DMA table too small\n",
+						       drive->name);
+						goto use_pio_instead;
+					}
+					*table++ = 0x8000;
+					*table++ = cur_addr + 0x8000;
+					xcount = 0x8000;
+				}
+				*table++ = xcount;
+				cur_addr += bcount;
+				cur_len -= bcount;
+			}
+		}
+		sg++;
+		i--;
+	}
+
+	if (count) {
+		*--table |= 0x80000000;
+		return count;
+	}
+	printk("%s: empty DMA table?\n", drive->name);
+
+use_pio_instead:
+	/*
+	 * Revert to PIO for this request.
+	 */
+	HWIF(drive)->sg_dma_active = 0;
+	return 0;
+}
+
+/*****************************************************************************
+ *
+ * ide_release_dma()
+ *
+ * This function releases the memory allocated for the scatter gather list
+ * and for the dma table, and frees the dma channel.
+ *
+ ****************************************************************************/
+static void
+ep93xx_ide_release_dma(ide_hwif_t *hwif)
+{
+	DPRINTK("%s: ep93xx_ide_release_dma\n", hwif->name);
+
+	/*
+	 * Check if we have a valid dma handle.
+	 */
+	if (hwif->hw.dma != 0) {
+		/*
+		 * Pause the DMA channel.
+		 */
+		ep93xx_dma_pause(hwif->hw.dma, 1, 0);
+
+		/*
+		 * Flush the DMA channel
+		 */
+		ep93xx_dma_flush(hwif->hw.dma);
+	}
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_callback()
+ *
+ * Registered with the ep93xx dma driver and called at the end of the dma
+ * interrupt handler, this function should process the dma buffers.
+ *
+ ****************************************************************************/
+static void
+ep93xx_ide_callback(ep93xx_dma_int_t dma_int, ep93xx_dma_dev_t device,
+                    unsigned int user_data)
+{
+	ide_drive_t *drive = (ide_drive_t *)user_data;
+	ide_hwif_t *hwif = HWIF(drive);
+	unsigned int temp;
+
+	DPRINTK("ep93xx_ide_callback %d\n", dma_int);
+
+	/*
+	 * Retrieve from the dma interface as many used buffers as are
+	 * available.
+	 */
+	while (ep93xx_dma_remove_buffer(hwif->hw.dma, &temp) == 0)
+		g_prd_returned++;
+
+	/*
+	 * Add new buffers if we have any available.
+	 */
+	while (g_prd_count) {
+		/*
+		 * Check if this is a read or write operation.
+		 */
+		if (hwif->sg_dma_direction == PCI_DMA_FROMDEVICE)
+			/*
+			 * Set up buffers for a read op.
+			 */
+			temp = ep93xx_dma_add_buffer(hwif->hw.dma,
+						     hwif->dma_base,
+						     hwif->dmatable_cpu[0],
+						     hwif->dmatable_cpu[1], 0,
+						     g_prd_count);
+		else
+			/*
+			 * Set up buffers for a write op.
+			 */
+			temp = ep93xx_dma_add_buffer(hwif->hw.dma,
+						     hwif->dmatable_cpu[0],
+						     hwif->dma_base,
+						     hwif->dmatable_cpu[1], 0,
+						     g_prd_count);
+
+		/*
+		 * Add a buffer to the dma interface.
+		 */
+		if (temp != 0)
+			break;
+		hwif->dmatable_cpu += 2;
+
+		/*
+		 * Decrement the count of dmatable entries
+		 */
+		g_prd_count--;
+	}
+
+	/*
+	 * See if all of the buffers have been returned.
+	 */
+	if (g_prd_returned >= g_prd_total) {
+		/*
+		 * See if the IDE device is still requesting data.
+		 */
+		if (inl(IDECR) & IDECtrl_DMARQ) {
+			/*
+			 * Indicate that an error has occurred during this
+			 * transfer.
+			 */
+			g_bad = 1;
+
+			/*
+			 * Add another word to the DMA to try and satisfy the
+			 * device's request.
+			 */
+			if (hwif->sg_dma_direction == PCI_DMA_FROMDEVICE)
+				ep93xx_dma_add_buffer(hwif->hw.dma,
+						      hwif->dma_base,
+						      virt_to_bus(&g_garbage),
+						      4, 0, 0);
+			else
+				ep93xx_dma_add_buffer(hwif->hw.dma,
+						      virt_to_bus(&g_garbage),
+						      hwif->dma_base,
+						      4, 0, 0);
+		}
+	}
+}
+
+/*****************************************************************************
+ *
+ *  ep93xx_dma_timer_expiry()
+ *
+ *
+ *	dma_timer_expiry	-	handle a DMA timeout
+ *	@drive: Drive that timed out
+ *
+ *	An IDE DMA transfer timed out. In the event of an error we ask
+ *	the driver to resolve the problem, if a DMA transfer is still
+ *	in progress we continue to wait (arguably we need to add a
+ *	secondary 'I dont care what the drive thinks' timeout here)
+ *	Finally if we have an interrupt we let it complete the I/O.
+ *	But only one time - we clear expiry and if it's still not
+ *	completed after WAIT_CMD, we error and retry in PIO.
+ *	This can occur if an interrupt is lost or due to hang or bugs.
+ *
+ *
+ ****************************************************************************/
+static int
+ep93xx_idedma_timer_expiry(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+	u8 dev_stat	 = hwif->INB(IDE_ALTSTATUS_REG);
+	u8 irq_stat	 = inl(IDECR) & IDECtrl_INTRQ;
+
+	DPRINTK(KERN_WARNING "%s: dma_timer_expiry: dev status == 0x%02x,irq= %d\n",
+		drive->name, dev_stat, irq_stat);
+
+	/*
+	 * Clear the expiry handler in case we decide to wait more,
+	 * next time timer expires it is an error
+	 */
+	HWGROUP(drive)->expiry = NULL;
+
+	/*
+	 * If the interrupt is asserted, call the handler.
+	 */
+	if (irq_stat)
+		HWGROUP(drive)->handler(drive);
+
+	/*
+	 * Check if the busy bit or the drq bit is set, indicating that
+	 * a dma transfer is still active, or the IDE interrupt is asserted.
+	 */
+	if ( (dev_stat & 0x80) || (dev_stat & 0x08) || irq_stat)
+		return WAIT_CMD;
+
+	/*
+	 * the device is not busy and the interrupt is not asserted, so check
+	 * if there's an error.
+	 */
+	if (dev_stat & 0x01)	/* ERROR */
+		return -1;
+
+	return 0;	/* Unknown status -- reset the bus */
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_config_ide_device()
+ *
+ * This function sets up the ep93xx ide device for a dma transfer by first
+ * probing to find the best dma mode supported by the device.
+ *
+ * Returns a 0 for success, and a 1 otherwise.
+ *
+ ****************************************************************************/
+static unsigned int
+ep93xx_config_ide_device(ide_drive_t *drive)
+{
+	byte transfer = 0;
+
+	DPRINTK("%s: ep93xx_config_ide_device\n", drive->name);
+
+	/*
+	 * Determine the best transfer speed supported.
+	 */
+	transfer = ide_dma_speed(drive, 2);
+
+	/*
+	 * Do not use MW DMA modes above 0 on ATAPI devices since they excite a
+	 * chip bug.
+	 */
+	if ((drive->media != ide_disk) &&
+	    ((transfer == XFER_MW_DMA_2) || (transfer == XFER_MW_DMA_1)))
+		transfer = XFER_MW_DMA_0;
+
+	/*
+	 * Do nothing if a DMA mode is not supported.
+	 */
+	if (transfer == 0)
+		return HWIF(drive)->ide_dma_off(drive);
+
+	/*
+	 * Configure the drive.
+	 */
+	if (ide_config_drive_speed(drive, transfer) == 0) {
+		/*
+		 * Hold on to this value for use later.
+		 */
+		drive->current_speed = transfer;
+
+		/*
+		 * Success, so turn on DMA.
+		 */
+		return HWIF(drive)->ide_dma_on(drive);
+	} else
+		return HWIF(drive)->ide_dma_off(drive);
+}
+
+/*****************************************************************************
+ *
+ *  ep93xx_set_pio()
+ *
+ *  Configures the ep93xx controller for a PIO mode transfer.
+ *
+ ****************************************************************************/
+static void
+ep93xx_set_pio(void)
+{
+	DPRINTK("ep93xx_set_pio\n");
+
+	/*
+	 * Clear the MDMA and UDMA operation registers.
+	 */
+	outl(0, IDEMDMAOP);
+	outl(0, IDEUDMAOP);
+
+	/*
+	 * Reset the UDMA state machine.
+	 */
+	outl(IDEUDMADebug_RWOE | IDEUDMADebug_RWPTR | IDEUDMADebug_RWDR |
+	     IDEUDMADebug_RROE | IDEUDMADebug_RRPTR | IDEUDMADebug_RRDR,
+	     IDEUDMADEBUG);
+	outl(0, IDEUDMADEBUG);
+
+	/*
+	 * Enable PIO mode of operation.
+	 */
+	outl(IDECfg_PIO | IDECfg_IDEEN | (4 << IDECfg_MODE_SHIFT) |
+	     (1 << IDECfg_WST_SHIFT), IDECFG);
+}
+
+/*****************************************************************************
+ *
+ *  ep93xx_rwproc()
+ *
+ *  Initializes the ep93xx IDE controller interface with the transfer type,
+ *  transfer mode, and transfer direction.
+ *
+ ****************************************************************************/
+static void
+ep93xx_rwproc(ide_drive_t *drive, int action)
+{
+	DPRINTK("%s: ep93xx_rwproc\n", drive->name);
+
+	/*
+	 * Configure the IDE controller for the specified transfer mode.
+	 */
+	switch (drive->current_speed)
+	{
+		/*
+		 * Configure for an MDMA operation.
+		 */
+		case XFER_MW_DMA_0:
+		case XFER_MW_DMA_1:
+		case XFER_MW_DMA_2:
+			outl(((drive->current_speed & 3) << IDECfg_MODE_SHIFT) |
+			     IDECfg_MDMA | IDECfg_IDEEN, IDECFG);
+			outl(action ? IDEMDMAOp_RWOP : 0, IDEMDMAOP);
+			outl(inl(IDEMDMAOP) | IDEMDMAOp_MEN, IDEMDMAOP);
+			break;
+
+		/*
+		 * Configure for a UDMA operation.
+		 */
+		case XFER_UDMA_0:
+		case XFER_UDMA_1:
+		case XFER_UDMA_2:
+		case XFER_UDMA_3:
+		case XFER_UDMA_4:
+			outl(((drive->current_speed & 7) << IDECfg_MODE_SHIFT) |
+			     IDECfg_UDMA | IDECfg_IDEEN, IDECFG);
+			outl(action ? IDEUDMAOp_RWOP : 0, IDEUDMAOP);
+			outl(inl(IDEUDMAOP) | IDEUDMAOp_UEN, IDEUDMAOP);
+			break;
+
+		default:
+			break;
+	}
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_check()
+ *
+ * This function determines if the device supports dma transfers, and if it
+ * does, then enables dma.
+ *
+ ****************************************************************************/
+static int
+ep93xx_ide_dma_check(ide_drive_t *drive)
+{
+	ide_hwif_t * hwif = HWIF(drive);
+	struct hd_driveid *id = drive->id;
+
+	DPRINTK("%s: ep93xx_ide_dma_check\n", drive->name);
+
+	if (!id || !(id->capability & 1) || !hwif->autodma) {
+		/*
+		 * Disable dma for this drive.
+		 */
+		hwif->ide_dma_off_quietly(drive);
+		return 1;
+	}
+
+	/*
+	 * Consult the list of known "bad" drives
+	 */
+	if (in_drive_list(id, drive_blacklist)) {
+		printk("%s: Disabling DMA for %s (blacklisted)\n",
+			   drive->name, id->model);
+
+		/*
+		 * Disable dma for this drive.
+		 */
+		hwif->ide_dma_off_quietly(drive);
+		return 1;
+	}
+
+	/*
+	 * Check if the drive supports multiword dma or udma modes.
+	 * If it does, then set the device up for that
+	 * type of dma transfer, and call ep93xx_ide_dma_on.
+	 */
+	return ep93xx_config_ide_device(drive);
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_host_off()
+ *
+ * This function disables dma for the host.
+ *
+ ****************************************************************************/
+static int
+ep93xx_ide_dma_host_off(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+
+	/*
+	 * TODO: what's to be done here?
+	 */
+	DPRINTK("%s: ep93xx_ide_dma_host_off\n", drive->name);
+
+	/*
+	 * Release the dma channel and all memory allocated for dma
+	 * purposes.
+	 */
+	ep93xx_ide_release_dma(hwif);
+
+	/*
+	 * Success.
+	 */
+	return 0;
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_off_quietly()
+ *
+ * This function, without announcing it,  disables dma for the device.
+ *
+ ****************************************************************************/
+static int
+ep93xx_ide_dma_off_quietly(ide_drive_t *drive)
+{
+	DPRINTK("%s: ep93xx_ide_dma_off_quietly\n", drive->name);
+
+	/*
+	 * Clear the using_dma field to indicate that dma is disabled
+	 * for this drive.
+	 */
+	drive->using_dma = 0;
+
+	/*
+	 * Disable dma on the host side.
+	 */
+	return HWIF(drive)->ide_dma_host_off(drive);
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_off()
+ *
+ * This function disables dma for the device.
+ *
+ ****************************************************************************/
+static int
+ep93xx_ide_dma_off(ide_drive_t *drive)
+{
+	DPRINTK("%s: ep93xx_ide_dma_off\n", drive->name);
+
+	return HWIF(drive)->ide_dma_off_quietly(drive);
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_on()
+ *
+ * This function enables dma for the device.
+ *
+ ****************************************************************************/
+static int
+ep93xx_ide_dma_on(ide_drive_t *drive)
+{
+	DPRINTK("%s: ep93xx_ide_dma_on\n", drive->name);
+
+	/*
+	 * Set the using_dma field to indicate that dma is enabled.
+	 */
+	drive->using_dma = 1;
+
+	/*
+	 * Enable DMA on the host side.
+	 */
+	return HWIF(drive)->ide_dma_host_on(drive);
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_host_on()
+ *
+ * This function enables dma for the device.
+ *
+ ****************************************************************************/
+static int
+ep93xx_ide_dma_host_on(ide_drive_t *drive)
+{
+	DPRINTK("%s: ep93xx_ide_dma_host_on\n", drive->name);
+
+	if (drive->using_dma)
+		return 0;
+	return 1;
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_read()
+ *
+ * This function sets up a dma read operation.
+ *
+ ****************************************************************************/
+static int
+ep93xx_ide_dma_read(ide_drive_t *drive)
+{
+	u8 lba48 = (drive->addressing == 1) ? 1 : 0;
+	struct request *rq = HWGROUP(drive)->rq;
+	unsigned int flags, i;
+	ide_hwif_t *hwif = HWIF(drive);
+	task_ioreg_t command = WIN_NOP;
+
+	DPRINTK("%s: ep93xx_ide_dma_read\n", drive->name);
+	DPRINTK("    %ld, %ld\n", HWGROUP(drive)->rq->sector,
+		HWGROUP(drive)->rq->nr_sectors);
+
+	/*
+	 * Check if we are already transferring on this dma channel.
+	 */
+	if (hwif->sg_dma_active || drive->waiting_for_dma) {
+		DPRINTK("%s: dma_read: dma already active \n", drive->name);
+		return 1;
+	}
+
+	/*
+	 * Compute the array index used for this request.
+	 */
+	i = drive->name[2] == 'a' ? 0 : 2;
+
+	/*
+	 * See if this request matches the most recent request, and that the
+	 * most recent request ended in error.
+	 */
+	if (g_bad && (g_cmd == READ) && (g_drive == drive) &&
+	    (g_sector == HWGROUP(drive)->rq->sector) &&
+	    (g_nr_sectors == HWGROUP(drive)->rq->nr_sectors)) {
+		g_cur_retries++;
+		if (g_cur_retries > g_max_retries[i])
+			g_max_retries[i]++;
+		if (g_cur_retries == RETRIES_PER_TRANSFER) {
+			g_bad = 0;
+			return 1;
+		}
+	} else {
+		g_cur_retries = 0;
+		g_cmd = READ;
+		g_drive = drive;
+		g_sector = HWGROUP(drive)->rq->sector;
+		g_nr_sectors = HWGROUP(drive)->rq->nr_sectors;
+	}
+
+	/*
+	 * Save information about this transfer.
+	 */
+	g_xfers[i]++;
+	g_sectors[i] += HWGROUP(drive)->rq->nr_sectors;
+
+	/*
+	 * Indicate that we're waiting for dma.
+	 */
+	drive->waiting_for_dma = 1;
+
+	/*
+	 * Configure DMA M2M channel flags for a source address hold, h/w
+	 * initiated P2M transfer.
+	 */
+	flags = (SOURCE_HOLD | TRANSFER_MODE_HW_P2M);
+
+	if (drive->current_speed & 0x20) {
+		flags |= (WS_IDE_MDMA_READ << WAIT_STATES_SHIFT);
+
+		/*
+		 * MDMA data register address.
+		 */
+		hwif->dma_base = IDEMDMADATAIN - IO_BASE_VIRT + IO_BASE_PHYS;
+	} else {
+		flags |= (WS_IDE_UDMA_READ << WAIT_STATES_SHIFT);
+		/*
+		 * UDMA data register address.
+		 */
+		hwif->dma_base = IDEUDMADATAIN - IO_BASE_VIRT + IO_BASE_PHYS;
+	}
+
+	/*
+	 * Configure the dma interface for this IDE operation.
+	 */
+	if (ep93xx_dma_config(hwif->hw.dma, 0, flags, ep93xx_ide_callback,
+			      (unsigned int)drive) != 0) {
+		DPRINTK("%s: ep93xx_ide_dma_read: ERROR- dma config failed",
+				drive->name);
+		drive->waiting_for_dma = 0;
+		/*
+		 * Fail.
+		 */
+		return 1;
+	}
+
+	/*
+	 * Build the table of dma-able buffers.
+	 */
+	if (!(g_prd_count = ide_build_dmatable(drive))) {
+		DPRINTK("%s: ep93xx_ide_dma_read: ERROR- failed to build dma table",
+			drive->name);
+		drive->waiting_for_dma = 0;
+		/*
+		 * Fail, try PIO instead of DMA
+		 */
+		return 1;
+	}
+
+	/*
+	 * Indicate that the scatter gather is active.
+	 */
+	hwif->sg_dma_active = 1;
+
+	/*
+	 * test stuff
+	 */
+	g_prd_total = g_prd_count;
+	g_prd_returned = 0;
+
+	DPRINTK("%d buffers\n", g_prd_total);
+
+	/*
+	 * Prepare the dma interface with some buffers from the
+	 * dma_table.
+	 */
+	do {
+		/*
+		 * Add a buffer to the dma interface.
+		 */
+		if (ep93xx_dma_add_buffer(hwif->hw.dma, hwif->dma_base,
+					  hwif->dmatable_cpu[0],
+					  hwif->dmatable_cpu[1], 0,
+					  g_prd_count) != 0)
+			break;
+		hwif->dmatable_cpu += 2;
+
+		/*
+		 * Decrement the count of dmatable entries
+		 */
+		g_prd_count--;
+	} while (g_prd_count);
+
+	/*
+	 * Nothing further is required if this is not a ide_disk (i.e. an ATAPI
+	 * device).
+	 */
+	if (drive->media != ide_disk)
+		return 0;
+
+	/*
+	 * Determine the command to be sent to the device.
+	 */
+	command = (lba48) ? WIN_READDMA_EXT : WIN_READDMA;
+	if (rq->cmd == IDE_DRIVE_TASKFILE) {
+		ide_task_t *args = rq->special;
+		command = args->tfRegister[IDE_COMMAND_OFFSET];
+	}
+
+	/*
+	 * Send the read command to the device.
+	 */
+	ide_execute_command(drive, command, &ep93xx_ide_dma_intr, 2*WAIT_CMD,
+			    &ep93xx_idedma_timer_expiry);
+
+	/*
+	 * initiate the dma transfer.
+	 */
+	return hwif->ide_dma_begin(drive);
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_first_read()
+ *
+ * This function handles the very first dma read operation.
+ *
+ ****************************************************************************/
+static int
+ep93xx_ide_dma_first_read(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+
+	/*
+	 * Switch the hwif to the real read routine.
+	 */
+	hwif->ide_dma_read = ep93xx_ide_dma_read;
+
+	/*
+	 * Register a proc entry for the statistics that we gather.
+	 */
+#ifdef CONFIG_PROC_FS
+	create_proc_info_entry("ide/ep93xx", 0, 0, ep93xx_get_info);
+#endif
+
+	/*
+	 * Do the actual read.
+	 */
+	return hwif->ide_dma_read(drive);
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_write()
+ *
+ * This function sets up a dma write operation.
+ *
+ ****************************************************************************/
+static int
+ep93xx_ide_dma_write(ide_drive_t *drive)
+{
+	u8 lba48 = (drive->addressing == 1) ? 1 : 0;
+	struct request *rq = HWGROUP(drive)->rq;
+	unsigned int flags, i;
+	ide_hwif_t *hwif = HWIF(drive);
+	task_ioreg_t command = WIN_NOP;
+
+	DPRINTK("%s: ep93xx_ide_dma_write\n", drive->name);
+
+	/*
+	 * Check if we are already transferring on this dma channel.
+	 */
+	if (hwif->sg_dma_active || drive->waiting_for_dma) {
+		DPRINTK("%s: dma_write - dma is already active \n",
+			drive->name);
+		return 1;
+	}
+
+	/*
+	 * Compute the array index used for this request.
+	 */
+	i = drive->name[2] == 'a' ? 1 : 3;
+
+	/*
+	 * See if this request matches the most recent request, and that the
+	 * most recent request ended in error.
+	 */
+	if (g_bad && (g_cmd == WRITE) && (g_drive == drive) &&
+	    (g_sector == HWGROUP(drive)->rq->sector) &&
+	    (g_nr_sectors == HWGROUP(drive)->rq->nr_sectors)) {
+		g_cur_retries++;
+		if (g_cur_retries > g_max_retries[i])
+			g_max_retries[i]++;
+		if (g_cur_retries == RETRIES_PER_TRANSFER) {
+			g_bad = 0;
+			return 1;
+		}
+	} else {
+		g_cur_retries = 0;
+		g_cmd = WRITE;
+		g_drive = drive;
+		g_sector = HWGROUP(drive)->rq->sector;
+		g_nr_sectors = HWGROUP(drive)->rq->nr_sectors;
+	}
+
+	/*
+	 * Save information about this transfer.
+	 */
+	g_xfers[i]++;
+	g_sectors[i] += HWGROUP(drive)->rq->nr_sectors;
+
+	/*
+	 * Indicate that we're waiting for dma.
+	 */
+	drive->waiting_for_dma = 1;
+
+	/*
+	 * Configure DMA M2M channel flags for a destination address
+	 * hold, h/w initiated M2P transfer.
+	 */
+	flags = (DESTINATION_HOLD | TRANSFER_MODE_HW_M2P);
+
+	/*
+	 * Determine if we need the MDMA or UDMA data register.
+	 */
+	if (drive->current_speed & 0x20) {
+		flags |= (WS_IDE_MDMA_WRITE << WAIT_STATES_SHIFT);
+
+		/*
+		 * MDMA data register address.
+		 */
+		hwif->dma_base = IDEMDMADATAOUT - IO_BASE_VIRT + IO_BASE_PHYS;
+	} else {
+		flags |= (WS_IDE_UDMA_WRITE << WAIT_STATES_SHIFT);
+
+		/*
+		 * UDMA data register address.
+		 */
+		hwif->dma_base = IDEUDMADATAOUT - IO_BASE_VIRT + IO_BASE_PHYS;
+	}
+
+	/*
+	 * Configure the dma interface for this IDE operation.
+	 */
+	if (ep93xx_dma_config(hwif->hw.dma, 0, flags, ep93xx_ide_callback,
+			      (unsigned int)drive) != 0) {
+		drive->waiting_for_dma = 0;
+		return 1;
+	}
+
+	/*
+	 * Build the table of dma-able buffers.
+	 */
+	if (!(g_prd_count = ide_build_dmatable(drive))) {
+		drive->waiting_for_dma = 0;
+		/*
+		 * Fail, try PIO instead of DMA
+		 */
+		return 1;
+	}
+
+	/*
+	 * Indicate that we're waiting for dma.
+	 */
+	hwif->sg_dma_active = 1;
+
+	/*
+	 * test stuff
+	 */
+	g_prd_total = g_prd_count;
+	g_prd_returned = 0;
+
+	/*
+	 * Prepare the dma interface with some buffers from the
+	 * dma_table.
+	 */
+	do {
+		/*
+		 * Add a buffer to the dma interface.
+		 */
+		if (ep93xx_dma_add_buffer(hwif->hw.dma,
+					  hwif->dmatable_cpu[0],
+					  hwif->dma_base,
+					  hwif->dmatable_cpu[1], 0,
+					  g_prd_count) != 0)
+			break;
+		hwif->dmatable_cpu += 2;
+
+		/*
+		 * Decrement the count of dmatable entries
+		 */
+		g_prd_count--;
+	} while (g_prd_count);
+
+	/*
+	 * Nothing further is required if this is not a ide_disk (i.e. an ATAPI
+	 * device).
+	 */
+	if (drive->media != ide_disk)
+		return 0;
+
+	/*
+	 * Determine the command to be sent to the device.
+	 */
+	command = (lba48) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
+	if (rq->cmd == IDE_DRIVE_TASKFILE) {
+		ide_task_t *args = rq->special;
+		command = args->tfRegister[IDE_COMMAND_OFFSET];
+	}
+
+	/*
+	 * Send the write dma command to the device.
+	 */
+	ide_execute_command(drive, command, &ep93xx_ide_dma_intr, 2*WAIT_CMD,
+			    &ep93xx_idedma_timer_expiry);
+
+	/*
+	 * initiate the dma transfer.
+	 */
+	return hwif->ide_dma_begin(drive);
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_begin()
+ *
+ * This function initiates a dma transfer.
+ *
+ ****************************************************************************/
+static int
+ep93xx_ide_dma_begin(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+
+	DPRINTK("%s: ep93xx_ide_dma_begin\n", drive->name);
+
+	/*
+	 * The transfer is not bad yet.
+	 */
+	g_bad = 0;
+
+	/*
+	 * Configure the ep93xx ide controller for a dma operation.
+	 */
+	if (HWGROUP(drive)->rq->cmd == READ)
+		ep93xx_rwproc(drive, 0);
+	else
+		ep93xx_rwproc(drive, 1);
+
+	/*
+	 * Start the dma transfer.
+	 */
+	ep93xx_dma_start(hwif->hw.dma, 1, NULL);
+
+	return 0;
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_end()
+ *
+ * This function performs any tasks needed to cleanup after a dma transfer.
+ * Returns 1 if an error occured, and 0 otherwise.
+ *
+ ****************************************************************************/
+static int
+ep93xx_ide_dma_end(ide_drive_t *drive)
+{
+	ide_hwif_t * hwif = HWIF(drive);
+	int i, stat;
+
+	DPRINTK("%s: ep93xx_ide_dma_end\n", drive->name);
+
+	/*
+	 * See if there is any data left in UDMA FIFOs.  For a read, first wait
+	 * until either the DMA is done or the FIFO is empty.  If there is any
+	 * residual data in the FIFO, there was an error in the transfer.
+	 */
+	if (HWGROUP(drive)->rq->cmd == READ) {
+		do {
+			i = inl(IDEUDMARFST);
+		} while (!ep93xx_dma_is_done(hwif->hw.dma) &&
+			 ((i & 15) != ((i >> 4) & 15)));
+		udelay(1);
+	}
+	else
+		i = inl(IDEUDMAWFST);
+	if ((i & 15) != ((i >> 4) & 15))
+		g_bad = 1;
+            
+	/*
+	 * See if all of the buffers were returned by the DMA driver.  If not,
+	 * then a transfer error has occurred.
+	 */
+	if (!ep93xx_dma_is_done(hwif->hw.dma))
+		g_bad = 1;
+
+	/*
+	 * Put the dma interface into pause mode.
+	 */
+	ep93xx_dma_pause(hwif->hw.dma, 1, 0);
+	ep93xx_dma_flush(hwif->hw.dma);
+
+	/*
+	 * Enable PIO mode on the IDE interface.
+	 */
+	ep93xx_set_pio();
+
+	/*
+	 * Indicate there's no dma transfer currently in progress.
+	 */
+	hwif->sg_dma_active = 0;
+	drive->waiting_for_dma = 0;
+
+	/*
+	 * Get status from the ide device.
+	 */
+	stat = HWIF(drive)->INB(IDE_STATUS_REG);
+
+	/*
+	 * If this is an ATAPI device and it reported an error, then simply
+	 * return a DMA success.
+	 */
+	if ((drive->media != ide_disk) && (stat & ERR_STAT))
+		return 0;
+
+	/*
+	 * See if a CRC error occurred.  If so, then a transfer error has
+	 * occurred.
+	 */
+	if ((stat & ERR_STAT) && (HWIF(drive)->INB(IDE_ERROR_REG) & ICRC_ERR))
+		g_bad = 1;
+
+	/*
+	 * Compute the array index used for this request.
+	 */
+	i = HWGROUP(drive)->rq->cmd == READ ? 0 : 1;
+	i += drive->name[2] == 'a' ? 0 : 2;
+
+	/*
+	 * Fail if an error occurred during the DMA.
+	 */
+	if (g_bad) {
+		/*
+		 * Increment the number of retries for this request, along with
+		 * the number of consecutive errors for this drive.
+		 */
+		g_retries[i]++;
+		g_errors[i]++;
+
+		/*
+		 * See if the maximum number of consective errors has occurred.
+		 */
+		if (g_errors[i] == FAILURES_BEFORE_BACKOFF) {
+			/*
+			 * Drop down to the next lowest transfer rate, or PIO
+			 * if already at the bottom.
+			 */
+			switch (drive->current_speed) {
+			case XFER_UDMA_4:
+				ide_config_drive_speed(drive, XFER_UDMA_3);
+				break;
+			case XFER_UDMA_3:
+				ide_config_drive_speed(drive, XFER_UDMA_2);
+				break;
+			case XFER_UDMA_2:
+				ide_config_drive_speed(drive, XFER_UDMA_1);
+				break;
+			case XFER_UDMA_1:
+				ide_config_drive_speed(drive, XFER_UDMA_0);
+				break;
+			case XFER_UDMA_0:
+				HWIF(drive)->ide_dma_off(drive);
+				break;
+			case XFER_MW_DMA_2:
+				ide_config_drive_speed(drive, XFER_MW_DMA_1);
+				break;
+			case XFER_MW_DMA_1:
+				ide_config_drive_speed(drive, XFER_MW_DMA_0);
+				break;
+			case XFER_MW_DMA_0:
+				HWIF(drive)->ide_dma_off(drive);
+				break;
+			}
+
+			/*
+			 * Reset the consecutive error counters for this drive.
+			 */
+			g_errors[i] = 0;
+			g_errors[i ^ 1] = 0;
+		}
+
+		/*
+		 * Fail the transfer.
+		 */
+		return 1;
+	} else
+		/*
+		 * Success, so reset the consecutive error counter.
+		 */
+		g_errors[i] = 0;
+
+	/*
+	 * Success.
+	 */
+	return 0;
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_test_irq()
+ *
+ * This function checks if the IDE interrupt is asserted and returns a
+ * 1 if it is, and 0 otherwise..
+ *
+ ****************************************************************************/
+static int
+ep93xx_ide_dma_test_irq(ide_drive_t *drive)
+{
+	DPRINTK("%s: ep93xx_ide_dma_test_irq\n", drive->name);
+
+	if (!drive->waiting_for_dma)
+		printk(KERN_WARNING "%s: %s called while not waiting\n",
+		       drive->name, __FUNCTION__);
+
+	/*
+	 * Return the value of the IDE interrupt bit.
+	 */
+	return inl(IDECR) & IDECtrl_INTRQ;
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_count()
+ *
+ ****************************************************************************/
+static int
+ep93xx_ide_dma_count(ide_drive_t *drive)
+{
+	DPRINTK("%s: ep93xx_ide_dma_count\n", drive->name);
+
+	return 0;
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_verbose()
+ *
+ ****************************************************************************/
+static int
+ep93xx_ide_dma_verbose(ide_drive_t *drive)
+{
+	DPRINTK("%s: ep93xx_ide_dma_verbose\n", drive->name);
+
+	printk(", %s ", ide_xfer_verbose(drive->current_speed));
+
+	return 1;
+
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_bad_timeout()
+ *
+ ****************************************************************************/
+static int
+ep93xx_ide_dma_timeout(ide_drive_t *drive)
+{
+	DPRINTK("%s: ep93xx_ide_dma_timeout\n", drive->name);
+
+	if (HWIF(drive)->ide_dma_test_irq(drive))
+		return 0;
+	return HWIF(drive)->ide_dma_end(drive);
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_dma_lostirq()
+ *
+ ****************************************************************************/
+static int
+ep93xx_ide_dma_lostirq(ide_drive_t *drive)
+{
+	DPRINTK("%s: ep93xx_ide_dma_lostirq\n", drive->name);
+	printk("%s: DMA interrupt recovery\n", drive->name);
+	return 1;
+}
+
+/*****************************************************************************
+ *
+ *  functions to set up the IDE control register and data register to read
+ *  or write a byte of data to/from the specified IDE device register.
+ *
+ ****************************************************************************/
+static void
+ep93xx_ide_outb(u8 b, unsigned long addr)
+{
+	unsigned int uiIDECR;
+
+	/*
+	 * Write the address out.
+	 */
+	uiIDECR = IDECtrl_DIORn | IDECtrl_DIOWn | ((addr & 7) << 2) |
+		  (addr >> 10);
+	outl(uiIDECR, IDECR);
+
+	/*
+	 * Write the data out.
+	 */
+	outl(b, IDEDATAOUT);
+
+	/*
+	 * Toggle the write signal.
+	 */
+	outl(uiIDECR & ~IDECtrl_DIOWn, IDECR);
+	outl(uiIDECR, IDECR);
+}
+
+static void
+ep93xx_ide_outbsync(ide_drive_t *drive, u8 b, unsigned long addr)
+{
+	unsigned int uiIDECR;
+
+	/*
+	 * Write the address out.
+	 */
+	uiIDECR = IDECtrl_DIORn | IDECtrl_DIOWn | ((addr & 7) << 2) |
+		  (addr >> 10);
+	outl(uiIDECR, IDECR);
+
+	/*
+	 * Write the data out.
+	 */
+	outl(b, IDEDATAOUT);
+
+	/*
+	 * Toggle the write signal.
+	 */
+	outl(uiIDECR & ~IDECtrl_DIOWn, IDECR);
+	outl(uiIDECR, IDECR);
+}
+
+static unsigned char
+ep93xx_ide_inb(unsigned long addr)
+{
+	unsigned int uiIDECR;
+
+	/*
+	 * Write the address out.
+	 */
+	uiIDECR = IDECtrl_DIORn | IDECtrl_DIOWn | ((addr & 7) << 2) |
+		  (addr >> 10);
+	outl(uiIDECR, IDECR);
+
+	/*
+	 * Toggle the read signal.
+	 */
+	outl(uiIDECR & ~IDECtrl_DIORn, IDECR);
+	outl(uiIDECR, IDECR);
+
+	/*
+	 * Read the data in.
+	 */
+	return(inl(IDEDATAIN) & 0xff);
+}
+
+/*****************************************************************************
+ *
+ *  functions to set up the IDE control register and data restister to read
+ *  or write 16 bits of data to/from the specified IDE device register.
+ *  These functions should only be used when reading/writing data to/from
+ *  the data register.
+ *
+ ****************************************************************************/
+static void
+ep93xx_ide_outw(u16 w, unsigned long addr)
+{
+	unsigned int uiIDECR;
+
+	/*
+	 * Write the address out.
+	 */
+	uiIDECR = IDECtrl_DIORn | IDECtrl_DIOWn | ((addr & 7) << 2) |
+		  (addr >> 10);
+	outl(uiIDECR, IDECR);
+
+	/*
+	 * Write the data out.
+	 */
+	outl(w, IDEDATAOUT);
+
+	/*
+	 * Toggle the write signal.
+	 */
+	outl(uiIDECR & ~IDECtrl_DIOWn, IDECR);
+	outl(uiIDECR, IDECR);
+}
+
+static u16
+ep93xx_ide_inw(unsigned long addr)
+{
+	unsigned int uiIDECR;
+
+	/*
+	 * Write the address out.
+	 */
+	uiIDECR = IDECtrl_DIORn | IDECtrl_DIOWn | ((addr & 7) << 2) |
+		  (addr >> 10);
+	outl(uiIDECR, IDECR);
+
+	/*
+	 * Toggle the read signal.
+	 */
+	outl(uiIDECR & ~IDECtrl_DIORn, IDECR);
+	outl(uiIDECR, IDECR);
+
+	/*
+	 * Read the data in.
+	 */
+	return(inl(IDEDATAIN) & 0xffff);
+}
+
+/*****************************************************************************
+ *
+ *  functions to read/write a block of data to/from the ide device using
+ *  PIO mode.
+ *
+ ****************************************************************************/
+static void
+ep93xx_ide_insw(unsigned long addr, void *buf, u32 count)
+{
+	unsigned short *data = (unsigned short *)buf;
+
+	/*
+	 * Read in data from the data register 16 bits at a time.
+	 */
+	for (; count; count--)
+		*data++ = ep93xx_ide_inw(addr);
+}
+
+static void
+ep93xx_ide_outsw(unsigned long addr, void *buf, u32 count)
+{
+	unsigned short *data = (unsigned short *)buf;
+
+	/*
+	 * Write out data to the data register 16 bits at a time.
+	 */
+	for (; count; count--)
+		ep93xx_ide_outw(*data++, addr);
+}
+
+static void
+ep93xx_ata_input_data(ide_drive_t *drive, void *buffer, u32 count)
+{
+	/*
+	 * Read in the specified number of half words from the ide interface.
+	 */
+	ep93xx_ide_insw(IDE_DATA_REG, buffer, count << 1);
+}
+
+static void
+ep93xx_ata_output_data(ide_drive_t *drive, void *buffer, u32 count)
+{
+	/*
+	 * write the specified number of half words from the ide interface
+	 * to the ide device.
+	 */
+	ep93xx_ide_outsw(IDE_DATA_REG, buffer, count << 1);
+}
+
+static void
+ep93xx_atapi_input_bytes(ide_drive_t *drive, void *buffer, u32 count)
+{
+	/*
+	 * read in the specified number of bytes from the ide interface.
+	 */
+	ep93xx_ide_insw(IDE_DATA_REG, buffer, (count >> 1) + (count & 1));
+}
+
+static void
+ep93xx_atapi_output_bytes(ide_drive_t *drive, void *buffer, u32 count)
+{
+	/*
+	 * Write the specified number of bytes from the ide interface
+	 * to the ide device.
+	 */
+	ep93xx_ide_outsw(IDE_DATA_REG, buffer, (count >> 1) + (count & 1));
+}
+
+/*****************************************************************************
+ *
+ * ep93xx_ide_init()
+ *
+ * This function sets up a pointer to the ep93xx specific ideproc funciton.
+ *
+ ****************************************************************************/
+void
+ep93xx_ide_init(void)
+{
+	DPRINTK("ep93xx_ide_init\n");
+	hw_regs_t hw;
+	struct hwif_s *hwif;
+	unsigned int uiTemp;
+
+	/*
+	 * Make sure the GPIO on IDE bits in the DEVCFG register are not set.
+	 */
+	uiTemp = inl(SYSCON_DEVCFG) & ~(SYSCON_DEVCFG_EonIDE |
+					SYSCON_DEVCFG_GonIDE |
+					SYSCON_DEVCFG_HonIDE);
+	SysconSetLocked( SYSCON_DEVCFG, uiTemp );
+
+	/*
+	 * Make sure that MWDMA and UDMA are disabled.
+	 */
+	outl(0, IDEMDMAOP);
+	outl(0, IDEUDMAOP);
+
+	/*
+	 * Set up the IDE interface for PIO transfers, using the default PIO
+	 * mode.
+	 */
+	outl(IDECfg_IDEEN | IDECfg_PIO | (4 << IDECfg_MODE_SHIFT) |
+	     (1 << IDECfg_WST_SHIFT), IDECFG);
+
+	/*
+	 * Setup the ports.
+	 */
+	ide_init_hwif_ports(&hw, 0x800, 0x406, NULL);
+
+	/*
+	 * Get the interrupt.
+	 */
+	hw.irq = IRQ_EIDE;
+
+	/*
+	 * This is the dma channel number assigned to this IDE interface. Until
+	 * dma is enabled for this interface, we set it to NO_DMA.
+	 */
+	hw.dma = NO_DMA;
+
+	/*
+	 * Register the IDE interface, an ide_hwif_t pointer is passed in,
+	 * which will get filled in with the hwif pointer for this interface.
+	 */
+	ide_register_hw(&hw, &hwif);
+
+	/*
+	 *  Set up the HW interface function pointers with the ep93xx specific
+	 *  function.
+	 */
+	hwif->ata_input_data = ep93xx_ata_input_data;
+	hwif->ata_output_data = ep93xx_ata_output_data;
+	hwif->atapi_input_bytes = ep93xx_atapi_input_bytes;
+	hwif->atapi_output_bytes = ep93xx_atapi_output_bytes;
+
+	hwif->OUTB = ep93xx_ide_outb;
+	hwif->OUTBSYNC = ep93xx_ide_outbsync;
+	hwif->OUTW = ep93xx_ide_outw;
+	hwif->OUTSW = ep93xx_ide_outsw;
+
+	hwif->INB = ep93xx_ide_inb;
+	hwif->INW = ep93xx_ide_inw;
+	hwif->INSW = ep93xx_ide_insw;
+
+	/*
+	 * Only enable IDE DMA on rev D1 and later chips.
+	 */
+	if ((inl(SYSCON_CHIPID) >> 28) > 3) {
+		DPRINTK("ep93xx_ide_init- dma enabled \n");
+
+		/*
+		 * Allocate memory for the DMA table.
+		 */
+		g_dma_table_base = kmalloc(PRD_ENTRIES * PRD_BYTES,
+					   GFP_KERNEL);
+
+		/*
+		 * Check if we allocated memory for dma
+		 */
+		if (g_dma_table_base == NULL) {
+			printk("%s: SG-DMA disabled, UNABLE TO ALLOCATE DMA TABLES\n",
+			       hwif->name);
+			return;
+		}
+
+		/*
+		 * Allocate memory for the scatterlist structures.
+		 */
+		hwif->sg_table = kmalloc(sizeof(struct scatterlist) *
+					 PRD_ENTRIES, GFP_KERNEL);
+
+		/*
+		 * Check if we allocated the memory we expected to.
+		 */
+		if (hwif->sg_table == NULL) {
+			/*
+			 *  Fail, so clean up.
+			 */
+			kfree(g_dma_table_base);
+			printk("%s: SG-DMA disabled, UNABLE TO ALLOCATE DMA TABLES\n",
+			       hwif->name);
+			return;
+		}
+
+		/*
+		 * Init the dma handle to 0.  This field is used to hold a
+		 * handle to the dma instance.
+		 */
+		hwif->hw.dma = 0;
+
+		/*
+		 * Open an instance of the ep93xx dma interface.
+		 */
+		if (ep93xx_dma_request(&hwif->hw.dma, hwif->name, DMA_IDE) !=
+		    0) {
+			/*
+			 * Fail, so clean up.
+			 */
+			kfree(g_dma_table_base);
+			kfree(hwif->sg_table);
+			printk("%s: SG-DMA disabled, unable to allocate DMA channel.\n",
+			       hwif->name);
+			return;
+		}
+
+		/*
+		 * Now that we've got a dma channel allocated, set up the rest
+		 * of the dma specific stuff.
+		 */
+		DPRINTK("\n ide init- dma channel allocated: %d \n", hwif->hw.dma);
+
+		/*
+		 * Enable dma support for atapi devices.
+		 */
+		hwif->atapi_dma			= 1;
+
+		hwif->ultra_mask		= 0x07;
+		hwif->mwdma_mask		= 0x00;
+		hwif->swdma_mask		= 0x00;
+
+		hwif->speedproc			= NULL;
+		hwif->autodma			= 1;
+
+		hwif->ide_dma_check		= ep93xx_ide_dma_check;
+		hwif->ide_dma_host_off		= ep93xx_ide_dma_host_off;
+		hwif->ide_dma_off_quietly	= ep93xx_ide_dma_off_quietly;
+		hwif->ide_dma_off		= ep93xx_ide_dma_off;
+		hwif->ide_dma_host_on		= ep93xx_ide_dma_host_on;
+		hwif->ide_dma_on		= ep93xx_ide_dma_on;
+		hwif->ide_dma_read		= ep93xx_ide_dma_first_read;
+		hwif->ide_dma_write		= ep93xx_ide_dma_write;
+		hwif->ide_dma_count		= ep93xx_ide_dma_count;
+		hwif->ide_dma_begin		= ep93xx_ide_dma_begin;
+		hwif->ide_dma_end		= ep93xx_ide_dma_end;
+		hwif->ide_dma_test_irq		= ep93xx_ide_dma_test_irq;
+		hwif->ide_dma_verbose		= ep93xx_ide_dma_verbose;
+		hwif->ide_dma_timeout		= ep93xx_ide_dma_timeout;
+		hwif->ide_dma_lostirq		= ep93xx_ide_dma_lostirq;
+	}
+}
diff -urN linux-2.4.29/drivers/ide/arm/Makefile linux-2.4.29-uc1/drivers/ide/arm/Makefile
--- linux-2.4.29/drivers/ide/arm/Makefile	2003-06-13 15:51:33.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ide/arm/Makefile	2005-06-14 02:12:19.000000000 +0100
@@ -6,6 +6,8 @@
 
 obj-$(CONFIG_BLK_DEV_IDE_ICSIDE)	+= icside.o
 obj-$(CONFIG_BLK_DEV_IDE_RAPIDE)	+= rapide.o
+obj-$(CONFIG_BLK_DEV_IDE_EP93XX)	+= ide-ep93xx.o
+obj-$(CONFIG_BLK_DEV_IDE_ESS710)	+= ess710ide.o
 
 EXTRA_CFLAGS	:= -I../
 
diff -urN linux-2.4.29/drivers/ide/Config.in linux-2.4.29-uc1/drivers/ide/Config.in
--- linux-2.4.29/drivers/ide/Config.in	2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.29-uc1/drivers/ide/Config.in	2005-06-14 02:12:19.000000000 +0100
@@ -109,6 +109,13 @@
 	 define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_ICS
 	 dep_bool '    RapIDE interface support' CONFIG_BLK_DEV_IDE_RAPIDE $CONFIG_ARCH_ACORN
       fi
+      if [ "$CONFIG_ARCH_EP9312" = "y" -o \
+           "$CONFIG_ARCH_EP9315" = "y" ]; then
+         bool '  EP93xx IDE Support' CONFIG_BLK_DEV_IDE_EP93XX
+         define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDE_EP93XX
+      else
+         define_bool CONFIG_BLK_DEV_IDE_EP93XX n
+      fi
       if [ "$CONFIG_AMIGA" = "y" ]; then
 	 dep_bool '  Amiga Gayle IDE interface support' CONFIG_BLK_DEV_GAYLE $CONFIG_AMIGA
 	 dep_mbool '    Amiga IDE Doubler support (EXPERIMENTAL)' CONFIG_BLK_DEV_IDEDOUBLER $CONFIG_BLK_DEV_GAYLE $CONFIG_EXPERIMENTAL
@@ -131,6 +138,8 @@
       if [ "$CONFIG_8xx" = "y" ]; then
          dep_bool '  MPC8xx IDE support' CONFIG_BLK_DEV_MPC8xx_IDE $CONFIG_8xx
       fi
+      dep_bool '  uClinux IDE interface support' CONFIG_BLK_DEV_UCLINUX_IDE $CONFIG_UCLINUX
+      dep_bool '  IDE interface on the CyberGuard/SnapGear ESS710' CONFIG_BLK_DEV_IDE_ESS710 $CONFIG_MACH_ESS710
 
       if [ "$CONFIG_BLK_DEV_MPC8xx_IDE" = "y" ]; then
          choice 'Type of MPC8xx IDE interface'		\
@@ -147,6 +156,7 @@
 	 dep_tristate '    ALI M14xx support' CONFIG_BLK_DEV_ALI14XX $CONFIG_BLK_DEV_IDE
 	 dep_tristate '    DTC-2278 support' CONFIG_BLK_DEV_DTC2278 $CONFIG_BLK_DEV_IDE
 	 dep_tristate '    Holtek HT6560B support' CONFIG_BLK_DEV_HT6560B $CONFIG_BLK_DEV_IDE
+	 dep_bool     '    OCIDEC-3 support' CONFIG_BLK_DEV_OCIDEC $CONFIG_BLK_DEV_IDE $CONFIG_EXCALIBUR
 	 dep_tristate '    PROMISE DC4030 support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC4030 $CONFIG_BLK_DEV_IDEDISK $CONFIG_EXPERIMENTAL
 	 dep_tristate '    QDI QD65xx support' CONFIG_BLK_DEV_QD65XX $CONFIG_BLK_DEV_IDE
 	 dep_tristate '    UMC-8672 support' CONFIG_BLK_DEV_UMC8672 $CONFIG_BLK_DEV_IDE
diff -urN linux-2.4.29/drivers/ide/h8300/aki3068_ide.c linux-2.4.29-uc1/drivers/ide/h8300/aki3068_ide.c
--- linux-2.4.29/drivers/ide/h8300/aki3068_ide.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ide/h8300/aki3068_ide.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,139 @@
+/****************************************************************************/
+/*
+ *  linux/drivers/ide/h8300/aki3068_ide.c
+ *  aki3068net IDE I/F support
+ *  reference schematic is http://www.linet.gr.jp/mituiwa/h8/h8osv3/hddprog/hdd.png
+ *
+ *  Copyright (C) 2003 Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ *
+ */
+/****************************************************************************/
+
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+#include <asm/irq.h>
+#include <asm/regs306x.h>
+
+/* IDE I/F configuration */
+#define IDE_BASE CONFIG_H8300_IDE_BASE
+#define IDE_CTRL CONFIG_H8300_IDE_ALT
+#define IDE_IRQ  (EXT_IRQ0 + CONFIG_H8300_IDE_IRQNO)
+
+#define IDE_DATA	0x00
+#define IDE_ERROR	0x02
+#define IDE_NSECTOR	0x04
+#define IDE_SECTOR	0x06
+#define IDE_LCYL	0x08
+#define IDE_HCYL	0x0A
+#define IDE_SELECT	0x0C
+#define IDE_STATUS	0x0E
+
+const static int offsets[IDE_NR_PORTS] = {
+    IDE_DATA, IDE_ERROR,  IDE_NSECTOR, IDE_SECTOR, IDE_LCYL,
+    IDE_HCYL, IDE_SELECT, IDE_STATUS,          -1,       -1
+};
+
+static void _outb(u8 d, unsigned long a)
+{
+	*(unsigned short *)a = (d & 0xff);
+}
+
+static void _outbsync(ide_drive_t *drive, u8 d, unsigned long a)
+{
+	*(unsigned short *)a = (d & 0xff);
+}
+
+static u8 _inb(unsigned long a)
+{
+	return *(unsigned short *)a;
+}
+
+static void _outw(u16 d, unsigned long a)
+{
+	*(unsigned short *)a = (d << 8) | (d >> 8);
+}
+
+static u16 _inw(unsigned long a)
+{
+	unsigned short d;
+	d = *(unsigned short *)a;
+	return (d << 8) | (d >> 8);
+}
+
+static void _outl(u32 d, unsigned long a)
+{
+}
+
+static u32 _inl(unsigned long a)
+{
+	return 0xffffffffUL;
+}
+
+static void _outsw(unsigned long addr, void *buf, u32 len)
+{
+	unsigned volatile short *ap = (unsigned volatile short *)addr;
+	unsigned short *bp = (unsigned short *)buf;
+	unsigned short d;
+	while(len--) {
+		d = *bp++;
+		*ap = (d << 8) | (d >> 8);
+	}
+}
+
+static void _insw(unsigned long addr, void *buf, u32 len)
+{
+	unsigned volatile short *ap = (unsigned volatile short *)addr;
+	unsigned short *bp = (unsigned short *)buf;
+	unsigned short d;
+	while(len--) {
+		d = *ap;
+		*bp++ = (d << 8) | (d >> 8);
+	}
+}
+
+void __init h8300_ide_init(void)
+{
+	hw_regs_t hw;
+	ide_hwif_t *hwif;
+	volatile unsigned char *abwcr = (volatile unsigned char *)ABWCR;
+	volatile unsigned char *cscr = (volatile unsigned char *)CSCR;
+	*abwcr &= ~((1 << ((IDE_BASE >> 21) & 7)) | (1 << ((IDE_CTRL >> 21) & 7)));
+	*cscr  |= (1 << ((IDE_BASE >> 21) & 7)) | (1 << ((IDE_CTRL >> 21) & 7)) | 0x0f;
+	memset(&hw,0,sizeof(hw));
+	ide_setup_ports(&hw, IDE_BASE, (int *)offsets,
+                             IDE_CTRL, 0, NULL,IDE_IRQ);
+	if (ide_register_hw(&hw, &hwif) != -1) {
+		hwif->mmio  = 0;
+		hwif->OUTB  = _outb;
+		hwif->OUTBSYNC = _outbsync;
+		hwif->OUTW  = _outw;
+		hwif->OUTL  = _outl;
+		hwif->OUTSW = _outsw;
+		hwif->OUTSL = NULL;
+		hwif->INB   = _inb;
+		hwif->INW   = _inw;
+		hwif->INL   = _inl;
+		hwif->INSW  = _insw;
+		hwif->INSL  = NULL;
+	}
+}
+
+void __init ide_print_resource(char *name, hw_regs_t *hw)
+{
+	printk("%s at 0x%08x-0x%08x,0x%08x on irq %d", name,
+		(unsigned int)hw->io_ports[IDE_DATA_OFFSET],
+		(unsigned int)hw->io_ports[IDE_DATA_OFFSET]+15,
+		(unsigned int)hw->io_ports[IDE_CONTROL_OFFSET],
+		hw->irq);
+}
diff -urN linux-2.4.29/drivers/ide/h8300/h8max_ide.c linux-2.4.29-uc1/drivers/ide/h8300/h8max_ide.c
--- linux-2.4.29/drivers/ide/h8300/h8max_ide.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ide/h8300/h8max_ide.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,163 @@
+/****************************************************************************/
+/*
+ *  linux/drivers/ide/h8300/h8max_ide.c
+ *  H8MAX IDE Interface support
+ *
+ *  Copyright (C) 2003 Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ *
+ */
+/****************************************************************************/
+
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+#include <asm/irq.h>
+#include <asm/delay.h>
+
+/* IDE I/F configuration */
+#define IDE_BASE 0x200000
+#define IDE_CTRL 0x60000c
+#define IDE_IRQ  EXT_IRQ5
+
+#define IDE_DATA	0x00
+#define IDE_ERROR	0x02
+#define IDE_NSECTOR	0x04
+#define IDE_SECTOR	0x06
+#define IDE_LCYL	0x08
+#define IDE_HCYL	0x0A
+#define IDE_SELECT	0x0C
+#define IDE_STATUS	0x0E
+
+#define IDE_INIT_WAIT 100
+
+const static int offsets[IDE_NR_PORTS] = {
+    IDE_DATA, IDE_ERROR,  IDE_NSECTOR, IDE_SECTOR, IDE_LCYL,
+    IDE_HCYL, IDE_SELECT, IDE_STATUS,          -1,       -1
+};
+
+static void h8max_outb(u8 d, unsigned long a)
+{
+	*(volatile unsigned short *)a = (d & 0xff);
+}
+
+static void h8max_outbsync(ide_drive_t *drive, u8 d, unsigned long a)
+{
+	*(volatile unsigned short *)a = (d & 0xff);
+}
+
+static u8 h8max_inb(unsigned long a)
+{
+	u8 r;
+	__asm__("mov.w @%1,r1\n\t"
+		"mov.b r1l,%w0"
+	    :"=r"(r):"r"(a):"er1");
+	return r;
+}
+
+static void h8max_outw(u16 d, unsigned long a)
+{
+	*(volatile unsigned short *)a = ((d << 8) & 0xff00) | ((d >> 8) & 0x00ff);
+}
+
+static u16 h8max_inw(unsigned long a)
+{
+	unsigned short d;
+	d = *(volatile unsigned short *)a;
+	return ((d << 8) & 0xff00) | ((d >> 8) & 0x00ff);
+}
+
+static void h8max_outl(u32 d, unsigned long a)
+{
+}
+
+static u32 h8max_inl(unsigned long a)
+{
+	return 0xffffffffUL;
+}
+
+static void h8max_outsw(unsigned long addr, void *buf, u32 len)
+{
+	unsigned volatile short *ap = (unsigned volatile short *)addr;
+	unsigned short *bp = (unsigned short *)buf;
+	unsigned short d;
+	while(len--) {
+		d = *bp++;
+		*ap = (d >> 8) | (d << 8);
+	}
+}
+
+static void h8max_insw(unsigned long addr, void *buf, u32 len)
+{
+	unsigned volatile short *ap = (unsigned volatile short *)addr;
+	unsigned short *bp = (unsigned short *)buf;
+	unsigned short d;
+	while(len--) {
+		d = *ap;
+		*bp++ = (d >> 8) | (d << 8);
+	}
+}
+
+void __init h8300_ide_init(void)
+{
+	hw_regs_t hw;
+	ide_hwif_t *hwif;
+	int w;
+	u8 st;
+
+	memset(&hw,0,sizeof(hw));
+
+	/* probe device */
+	h8max_outb(0x06, IDE_CTRL);
+	ide_delay_50ms();
+	h8max_outb(0x02, IDE_CTRL);
+	ide_delay_50ms();
+	for (w = IDE_INIT_WAIT; w > 0; w--) {
+		udelay(1000);
+		st = h8max_inb(IDE_BASE + IDE_STATUS);
+		if ((st & 0xc0) == 0xc0) {
+			/* failed */
+			return ;
+		}
+		if ((st & 0x80) == 0x00)
+			break ;
+	}
+
+	/* probe ok */
+	if (w != 0) {
+		ide_setup_ports(&hw, IDE_BASE, (int *)offsets,
+				IDE_CTRL, 0, NULL,IDE_IRQ);
+		if (ide_register_hw(&hw, &hwif) != -1) {
+			hwif->mmio  = 0;
+			hwif->OUTB  = h8max_outb;
+			hwif->OUTBSYNC = h8max_outbsync;
+			hwif->OUTW  = h8max_outw;
+			hwif->OUTL  = h8max_outl;
+			hwif->OUTSW = h8max_outsw;
+			hwif->OUTSL = NULL;
+			hwif->INB   = h8max_inb;
+			hwif->INW   = h8max_inw;
+			hwif->INL   = h8max_inl;
+			hwif->INSW  = h8max_insw;
+			hwif->INSL  = NULL;
+		}
+	}
+}
+
+void __init ide_print_resource(char *name, hw_regs_t *hw)
+{
+	printk("%s at 0x%08x-0x%08x,0x%08x on irq %d", name,
+		(unsigned int)hw->io_ports[IDE_DATA_OFFSET],
+		(unsigned int)hw->io_ports[IDE_DATA_OFFSET]+15,
+		(unsigned int)hw->io_ports[IDE_CONTROL_OFFSET],
+		hw->irq);
+}
diff -urN linux-2.4.29/drivers/ide/h8300/Makefile linux-2.4.29-uc1/drivers/ide/h8300/Makefile
--- linux-2.4.29/drivers/ide/h8300/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ide/h8300/Makefile	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,7 @@
+O_TARGET := idedriver-h8300.o
+
+obj-$(CONFIG_BOARD_H8MAX) := h8max_ide.o
+obj-$(CONFIG_BOARD_AKI3068NET) := aki3068_ide.o
+obj-m		:=
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/ide/ide.c linux-2.4.29-uc1/drivers/ide/ide.c
--- linux-2.4.29/drivers/ide/ide.c	2004-08-08 00:26:04.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ide/ide.c	2005-06-14 02:12:19.000000000 +0100
@@ -230,7 +230,7 @@
 	ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, &hwif->irq);
 	memcpy(&hwif->hw, &hw, sizeof(hw));
 	memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports));
-	hwif->noprobe	= !hwif->io_ports[IDE_DATA_OFFSET];
+	hwif->noprobe   = !hwif->io_ports[IDE_DATA_OFFSET];
 #ifdef CONFIG_BLK_DEV_HD
 	if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA)
 		hwif->noprobe = 1; /* may be overridden by ide_setup() */
@@ -1102,7 +1102,7 @@
  * may set up the hw structure yourself OR use this routine to
  * do it for you.
  */
-void ide_setup_ports (	hw_regs_t *hw,
+void ide_setup_ports ( hw_regs_t *hw,
 			ide_ioreg_t base, int *offsets,
 			ide_ioreg_t ctrl, ide_ioreg_t intr,
 			ide_ack_intr_t *ack_intr,
@@ -1177,6 +1177,7 @@
 	memcpy(&hwif->hw, hw, sizeof(*hw));
 	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
 	hwif->irq = hw->irq;
+
 	hwif->noprobe = 0;
 	hwif->chipset = hw->chipset;
 
@@ -1203,8 +1204,10 @@
 int ide_register (int arg1, int arg2, int irq)
 {
 	hw_regs_t hw;
+
 	ide_init_hwif_ports(&hw, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2, NULL);
 	hw.irq = irq;
+
 	return ide_register_hw(&hw, NULL);
 }
 
@@ -2425,7 +2428,7 @@
 				hwif->hw.irq = vals[2];
 				ide_init_hwif_ports(&hwif->hw, (ide_ioreg_t) vals[0], (ide_ioreg_t) vals[1], &hwif->irq);
 				memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
-				hwif->irq      = vals[2];
+				hwif->irq = vals[2];
 				hwif->noprobe  = 0;
 				hwif->chipset  = ide_generic;
 				goto done;
@@ -2530,6 +2533,12 @@
 		rapide_init();
 	}
 #endif /* CONFIG_BLK_DEV_IDE_RAPIDE */
+#ifdef CONFIG_BLK_DEV_IDE_ESS710
+	{
+		extern void ess710ide_init(void);
+		ess710ide_init();
+	}
+#endif /* CONFIG_BLK_DEV_UIDE_ESS710 */
 #ifdef CONFIG_BLK_DEV_GAYLE
 	{
 		extern void gayle_init(void);
@@ -2548,6 +2557,12 @@
 		macide_init();
 	}
 #endif /* CONFIG_BLK_DEV_MAC_IDE */
+#ifdef CONFIG_BLK_DEV_UCLINUX_IDE
+	{
+		extern void uclinux_ide_init(void);
+		uclinux_ide_init();
+	}
+#endif /* CONFIG_BLK_DEV_UCLINUX_IDE */
 #ifdef CONFIG_BLK_DEV_CPCI405_IDE
 	{
 		extern void cpci405ide_init(void);
@@ -2566,6 +2581,18 @@
 		buddha_init();
 	}
 #endif /* CONFIG_BLK_DEV_BUDDHA */
+#ifdef CONFIG_BLK_DEV_OCIDEC
+	{
+		extern void ocidec_init(void);
+		ocidec_init();
+	}
+#endif /* CONFIG_BLK_DEV_OCIDEC */
+#if defined(__H8300H__) || defined(__H8300S__)
+        {
+		extern void h8300_ide_init(void);
+		h8300_ide_init();
+	}
+#endif
 }
 
 void __init ide_init_builtin_subdrivers (void)
diff -urN linux-2.4.29/drivers/ide/ide-cd.c linux-2.4.29-uc1/drivers/ide/ide-cd.c
--- linux-2.4.29/drivers/ide/ide-cd.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-uc1/drivers/ide/ide-cd.c	2005-06-14 02:12:19.000000000 +0100
@@ -1048,8 +1048,12 @@
 	/* Check for errors. */
 	if (dma) {
 		info->dma = 0;
+#ifdef CONFIG_ARCH_EP93XX
+		dma_error = HWIF(drive)->ide_dma_end(drive);
+#else
 		if ((dma_error = HWIF(drive)->ide_dma_end(drive)))
 			HWIF(drive)->ide_dma_off(drive);
+#endif
 	}
 
 	if (cdrom_decode_status (&startstop, drive, 0, &stat))
@@ -1063,7 +1067,11 @@
 			}
 			return ide_stopped;
 		} else
+#ifdef CONFIG_ARCH_EP93XX
+			return ide_stopped;
+#else
 			return DRIVER(drive)->error(drive, "dma error", stat);
+#endif
 	}
 
 	/* Read the interrupt reason and the transfer length. */
diff -urN linux-2.4.29/drivers/ide/ide-disk.c linux-2.4.29-uc1/drivers/ide/ide-disk.c
--- linux-2.4.29/drivers/ide/ide-disk.c	2004-08-08 00:26:04.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ide/ide-disk.c	2005-06-14 02:12:19.000000000 +0100
@@ -1593,7 +1593,7 @@
 	ide_add_setting(drive,	"nowerr",		SETTING_RW,					HDIO_GET_NOWERR,	HDIO_SET_NOWERR,	TYPE_BYTE,	0,	1,				1,	1,	&drive->nowerr,			set_nowerr);
 	ide_add_setting(drive,	"breada_readahead",	SETTING_RW,					BLKRAGET,		BLKRASET,		TYPE_INT,	0,	255,				1,	1,	&read_ahead[major],		NULL);
 	ide_add_setting(drive,	"file_readahead",	SETTING_RW,					BLKFRAGET,		BLKFRASET,		TYPE_INTA,	0,	4096,			PAGE_SIZE,	1024,	&max_readahead[major][minor],	NULL);
-	ide_add_setting(drive,	"max_kb_per_request",	SETTING_RW,					BLKSECTGET,		BLKSECTSET,		TYPE_INTA,	1,	255,				1,	1,	&max_sectors[major][minor],	NULL);
+	ide_add_setting(drive,	"max_kb_per_request",	SETTING_RW,					BLKSECTGET,		BLKSECTSET,		TYPE_INTA,	1,	255,				1,	2,	&max_sectors[major][minor],	NULL);
 	ide_add_setting(drive,	"lun",			SETTING_RW,					-1,			-1,			TYPE_INT,	0,	7,				1,	1,	&drive->lun,			NULL);
 	ide_add_setting(drive,	"wcache",		SETTING_RW,					HDIO_GET_WCACHE,	HDIO_SET_WCACHE,	TYPE_BYTE,	0,	1,				1,	1,	&drive->wcache,			write_cache);
 	ide_add_setting(drive,	"acoustic",		SETTING_RW,					HDIO_GET_ACOUSTIC,	HDIO_SET_ACOUSTIC,	TYPE_BYTE,	0,	254,				1,	1,	&drive->acoustic,		set_acoustic);
diff -urN linux-2.4.29/drivers/ide/ide-io.c linux-2.4.29-uc1/drivers/ide/ide-io.c
--- linux-2.4.29/drivers/ide/ide-io.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-uc1/drivers/ide/ide-io.c	2005-06-14 02:12:19.000000000 +0100
@@ -879,8 +879,8 @@
 		ret = DRIVER(drive)->error(drive, "dma timeout retry",
 				hwif->INB(IDE_STATUS_REG));
 	} else {
-		printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
-		(void) hwif->ide_dma_timeout(drive);
+	printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
+	(void) hwif->ide_dma_timeout(drive);
 	}
 
 	/*
diff -urN linux-2.4.29/drivers/ide/ide-iops.c linux-2.4.29-uc1/drivers/ide/ide-iops.c
--- linux-2.4.29/drivers/ide/ide-iops.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/ide/ide-iops.c	2005-06-14 02:12:19.000000000 +0100
@@ -107,17 +107,31 @@
 
 static u8 ide_inb (unsigned long port)
 {
+#if defined( CONFIG_ARCH_EDB7312 )
+	return IN_BYTE(port);
+#elif defined( CONFIG_ARCH_EP93XX )
+	return (u8) ep93xx_pcmcia_ide_inb(port);
+#else
 	return (u8) inb(port);
+#endif
 }
 
 static u16 ide_inw (unsigned long port)
 {
+#ifdef CONFIG_ARCH_EP93XX
+	return (u16) ep93xx_pcmcia_ide_inw(port);
+#else
 	return (u16) inw(port);
+#endif
 }
 
 static void ide_insw (unsigned long port, void *addr, u32 count)
 {
+#ifdef CONFIG_ARCH_EP93XX
+	return ep93xx_pcmcia_ide_insw(port, addr, count);
+#else
 	return insw(port, addr, count);
+#endif
 }
 
 static u32 ide_inl (unsigned long port)
@@ -132,22 +146,40 @@
 
 static void ide_outb (u8 addr, unsigned long port)
 {
+#if defined( CONFIG_ARCH_EDB7312 )
+	OUT_BYTE(addr, port);
+#elif defined( CONFIG_ARCH_EP93XX )
+	ep93xx_pcmcia_ide_outb(addr, port);
+#else
 	outb(addr, port);
+#endif
 }
 
 static void ide_outbsync (ide_drive_t *drive, u8 addr, unsigned long port)
 {
+#ifdef CONFIG_ARCH_EP93XX
+	ep93xx_pcmcia_ide_outb(addr, port);
+#else
 	outb(addr, port);
+#endif
 }
 
 static void ide_outw (u16 addr, unsigned long port)
 {
+#ifdef CONFIG_ARCH_EP93XX
+	ep93xx_pcmcia_ide_outw(addr, port);
+#else
 	outw(addr, port);
+#endif
 }
 
 static void ide_outsw (unsigned long port, void *addr, u32 count)
 {
+#ifdef CONFIG_ARCH_EP93XX
+	ep93xx_pcmcia_ide_outsw(port, addr, count);
+#else
 	outsw(port, addr, count);
+#endif
 }
 
 static void ide_outl (u32 addr, unsigned long port)
@@ -431,8 +463,10 @@
 	u16 *stringcast;
 
 #ifdef __mc68000__
+#ifndef NO_MM
 	if (!MACH_IS_AMIGA && !MACH_IS_MAC && !MACH_IS_Q40 && !MACH_IS_ATARI)
 		return;
+#endif
 
 #ifdef M68K_IDE_SWAPW
 	if (M68K_IDE_SWAPW) {	/* fix bus byteorder first */
diff -urN linux-2.4.29/drivers/ide/ide-lib.c linux-2.4.29-uc1/drivers/ide/ide-lib.c
--- linux-2.4.29/drivers/ide/ide-lib.c	2003-06-13 15:51:33.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ide/ide-lib.c	2005-06-14 02:12:19.000000000 +0100
@@ -94,47 +94,47 @@
 	switch(mode) {
 		case 0x04:
 			if ((id->dma_ultra & 0x0040) &&
-			    (id->dma_ultra & hwif->ultra_mask))
+			    (id->dma_ultra & hwif->ultra_mask & 0x0040))
 				{ speed = XFER_UDMA_6; break; }
 		case 0x03:
 			if ((id->dma_ultra & 0x0020) &&
-			    (id->dma_ultra & hwif->ultra_mask))
+			    (id->dma_ultra & hwif->ultra_mask & 0x0020))
 				{ speed = XFER_UDMA_5; break; }
 		case 0x02:
 			if ((id->dma_ultra & 0x0010) &&
-			    (id->dma_ultra & hwif->ultra_mask))
+			    (id->dma_ultra & hwif->ultra_mask & 0x0010))
 				{ speed = XFER_UDMA_4; break; }
 			if ((id->dma_ultra & 0x0008) &&
-			    (id->dma_ultra & hwif->ultra_mask))
+			    (id->dma_ultra & hwif->ultra_mask & 0x0008))
 				{ speed = XFER_UDMA_3; break; }
 		case 0x01:
 			if ((id->dma_ultra & 0x0004) &&
-			    (id->dma_ultra & hwif->ultra_mask))
+			    (id->dma_ultra & hwif->ultra_mask & 0x0004))
 				{ speed = XFER_UDMA_2; break; }
 			if ((id->dma_ultra & 0x0002) &&
-			    (id->dma_ultra & hwif->ultra_mask))
+			    (id->dma_ultra & hwif->ultra_mask & 0x0002))
 				{ speed = XFER_UDMA_1; break; }
 			if ((id->dma_ultra & 0x0001) &&
-			    (id->dma_ultra & hwif->ultra_mask))
+			    (id->dma_ultra & hwif->ultra_mask & 0x0001))
 				{ speed = XFER_UDMA_0; break; }
 		case 0x00:
 			if ((id->dma_mword & 0x0004) &&
-			    (id->dma_mword & hwif->mwdma_mask))
+			    (id->dma_mword & hwif->mwdma_mask & 0x0004))
 				{ speed = XFER_MW_DMA_2; break; }
 			if ((id->dma_mword & 0x0002) &&
-			    (id->dma_mword & hwif->mwdma_mask))
+			    (id->dma_mword & hwif->mwdma_mask & 0x0002))
 				{ speed = XFER_MW_DMA_1; break; }
 			if ((id->dma_mword & 0x0001) &&
-			    (id->dma_mword & hwif->mwdma_mask))
+			    (id->dma_mword & hwif->mwdma_mask & 0x0001))
 				{ speed = XFER_MW_DMA_0; break; }
 			if ((id->dma_1word & 0x0004) &&
-			    (id->dma_1word & hwif->swdma_mask))
+			    (id->dma_1word & hwif->swdma_mask & 0x0004))
 				{ speed = XFER_SW_DMA_2; break; }
 			if ((id->dma_1word & 0x0002) &&
-			    (id->dma_1word & hwif->swdma_mask))
+			    (id->dma_1word & hwif->swdma_mask & 0x0002))
 				{ speed = XFER_SW_DMA_1; break; }
 			if ((id->dma_1word & 0x0001) &&
-			    (id->dma_1word & hwif->swdma_mask))
+			    (id->dma_1word & hwif->swdma_mask & 0x0001))
 				{ speed = XFER_SW_DMA_0; break; }
 	}
 
diff -urN linux-2.4.29/drivers/ide/ide-probe.c linux-2.4.29-uc1/drivers/ide/ide-probe.c
--- linux-2.4.29/drivers/ide/ide-probe.c	2004-04-14 14:05:29.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ide/ide-probe.c	2005-06-14 02:12:19.000000000 +0100
@@ -52,6 +52,7 @@
 #include <linux/kmod.h>
 
 #include <asm/byteorder.h>
+#include <asm/dma.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -460,6 +461,25 @@
 	ide_delay_50ms();
 	SELECT_DRIVE(drive);
 	ide_delay_50ms();
+
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_MACH_IPD)
+	/*
+	 *  ColdFire platforms boot up so quick that most hard drives
+	 *  have not completed there own self tests. Pause here for
+	 *  a couple of seconds if it looks like there is a drive
+	 *  present...
+	 */
+	if (hwif->INB(IDE_SELECT_REG) != drive->select.all) {
+		printk("IDE: waiting for drives to settle...\n");
+		for (rc = 0; (rc < 400); rc++) {
+			SELECT_DRIVE(drive);
+			ide_delay_50ms();
+			if (hwif->INB(IDE_SELECT_REG) == drive->select.all)
+				break;
+		}
+	}
+#endif
+
 	if (hwif->INB(IDE_SELECT_REG) != drive->select.all && !drive->present) {
 		if (drive->select.b.unit != 0) {
 			/* exit with drive0 selected */
@@ -824,7 +844,7 @@
 	if (hwif->noprobe)
 		return;
 #ifdef CONFIG_BLK_DEV_IDE
-	if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA) {
+	if (hwif->io_ports[IDE_DATA_OFFSET] == (ide_ioreg_t)HD_DATA) {
 		extern void probe_cmos_for_drives(ide_hwif_t *);
 		probe_cmos_for_drives(hwif);
 	}
@@ -1105,6 +1125,13 @@
 		}
 	}
 
+#ifdef CONFIG_BLK_DEV_UCLINUX_IDE
+{
+	extern void uclinux_irq_fixup();
+	uclinux_irq_fixup();
+}
+#endif
+
 	/*
 	 * Everything is okay, so link us into the hwgroup
 	 */
@@ -1136,7 +1163,8 @@
 	spin_unlock_irqrestore(&io_request_lock, flags);
 #endif
 
-#if !defined(__mc68000__) && !defined(CONFIG_APUS) && !defined(__sparc__)
+#if !defined(__mc68000__) && !defined(CONFIG_APUS) && !defined(__sparc__) && \
+    !defined(__H8300H__) && !defined(__H8300S__)
 	printk("%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name,
 		hwif->io_ports[IDE_DATA_OFFSET],
 		hwif->io_ports[IDE_DATA_OFFSET]+7,
@@ -1146,6 +1174,8 @@
 		hwif->io_ports[IDE_DATA_OFFSET],
 		hwif->io_ports[IDE_DATA_OFFSET]+7,
 		hwif->io_ports[IDE_CONTROL_OFFSET], __irq_itoa(hwif->irq));
+#elif defined(__H8300H__) || defined(__H8300S__)
+	ide_print_resource(hwif->name,&(hwif->hw));
 #else
 	printk("%s at 0x%08lx on irq %d", hwif->name,
 		hwif->io_ports[IDE_DATA_OFFSET], hwif->irq);
diff -urN linux-2.4.29/drivers/ide/ide-proc.c linux-2.4.29-uc1/drivers/ide/ide-proc.c
--- linux-2.4.29/drivers/ide/ide-proc.c	2004-04-14 14:05:29.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ide/ide-proc.c	2005-06-14 02:12:19.000000000 +0100
@@ -424,6 +424,7 @@
 		case ide_cmd646:	name = "cmd646";	break;
 		case ide_cy82c693:	name = "cy82c693";	break;
 		case ide_4drives:	name = "4drives";	break;
+		case ide_acorn:		name = "acorn";		break;
 		case ide_pmac:		name = "pmac";		break;
 		default:		name = "(unknown)";	break;
 	}
diff -urN linux-2.4.29/drivers/ide/legacy/Makefile linux-2.4.29-uc1/drivers/ide/legacy/Makefile
--- linux-2.4.29/drivers/ide/legacy/Makefile	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-uc1/drivers/ide/legacy/Makefile	2005-06-14 02:12:19.000000000 +0100
@@ -16,6 +16,7 @@
 obj-$(CONFIG_BLK_DEV_GAYLE)		+= gayle.o
 obj-$(CONFIG_BLK_DEV_MAC_IDE)		+= macide.o
 obj-$(CONFIG_BLK_DEV_Q40IDE)		+= q40ide.o
+obj-$(CONFIG_BLK_DEV_UCLINUX_IDE)	+= uclinux.o
 
 obj-$(CONFIG_BLK_DEV_IDE_SIBYTE)	+= sibyte.o
 
diff -urN linux-2.4.29/drivers/ide/legacy/uclinux.c linux-2.4.29-uc1/drivers/ide/legacy/uclinux.c
--- linux-2.4.29/drivers/ide/legacy/uclinux.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ide/legacy/uclinux.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,515 @@
+/****************************************************************************/
+/*
+ *  linux/drivers/ide/legacy/uclinux.c
+ *
+ *  A simple driver that is easy to adjust for a large number of
+ *  embedded targets,  not just coldfire.
+ *
+ *     Copyright (C) 2001-2004 by David McCullough <davidm@snapgear.com>
+ *     Copyright (C) 2002 by Greg Ungerer <gerg@snapgear.com>
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ *
+ *  ex: set ts=4 sw=4
+ */
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+
+/****************************************************************************/
+
+#ifdef CONFIG_COLDFIRE
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#endif
+
+/****************************************************************************/
+/*
+ *	Our list of ports/irq's for different boards.
+ */
+
+static struct ide_defaults {
+	ide_ioreg_t	base;
+	int			irq;
+} ide_defaults[] = {
+#if defined(CONFIG_SECUREEDGEMP3)
+	{ ((ide_ioreg_t) 0x30800000), 29 },
+#elif defined(CONFIG_eLIA) || defined(CONFIG_DISKtel)
+	{ ((ide_ioreg_t) 0x30c00000), 29 },
+#elif defined(CONFIG_M5249C3)
+	{ ((ide_ioreg_t) 0x50000020), 165 },
+#elif defined(CONFIG_SIGNAL_MCP751)
+	{ ((ide_ioreg_t) 0x42000000), 65 },	// INT1
+#else
+	#error "No IDE setup defined"
+#endif
+	{ ((ide_ioreg_t) -1), -1 }
+};
+
+/****************************************************************************/
+/*
+ * the register offsets from the base address
+ */
+
+#define IDE_DATA	0x00
+#define IDE_ERROR	0x01
+#define IDE_NSECTOR	0x02
+#define IDE_SECTOR	0x03
+#define IDE_LCYL	0x04
+#define IDE_HCYL	0x05
+#define IDE_SELECT	0x06
+#define IDE_STATUS	0x07
+
+/* The control register often changes */
+#define IDE_CONTROL	0x0e
+
+#define IDE_IRQ		-1 /* not used */
+
+static int ide_offsets[IDE_NR_PORTS] = {
+    IDE_DATA, IDE_ERROR,  IDE_NSECTOR, IDE_SECTOR, IDE_LCYL,
+    IDE_HCYL, IDE_SELECT, IDE_STATUS,  IDE_CONTROL, IDE_IRQ
+};
+
+#define	DBGIDE(fmt,a...)
+//#define	DBGIDE(fmt,a...) printk(fmt, a)
+
+/****************************************************************************/
+
+static void	OUTB(u8 addr, unsigned long port);
+static void	OUTBSYNC(ide_drive_t *drive, u8 addr, unsigned long port);
+static void	OUTW(u16 addr, unsigned long port);
+static void	OUTL(u32 addr, unsigned long port);
+static void	OUTSW(unsigned long port, void *addr, u32 count);
+static void	OUTSL(unsigned long port, void *addr, u32 count);
+static u8	INB(unsigned long port);
+static u16	INW(unsigned long port);
+static u32	INL(unsigned long port);
+static void	INSW(unsigned long port, void *addr, u32 count);
+static void	INSL(unsigned long port, void *addr, u32 count);
+
+static void	uclinux_irq_remove();
+/****************************************************************************/
+/*
+ * if needed, this function returns 1 if an interrupt was acked
+ */
+
+#if defined(CONFIG_M5249C3)
+static int ack_intr(ide_hwif_t* hwif)
+{
+	/* Clear interrupts for GPIO5 */
+	*((volatile unsigned long *) 0x800000c0) = 0x00002020;
+	return 1;
+}
+#elif defined(CONFIG_SIGNAL_MCP751)
+
+static void mcf_autovector(unsigned int vec)
+{
+	/* Everything is auto-vectored on the 5272 */
+}
+
+static int ack_intr(ide_hwif_t* hwif)
+{
+	volatile unsigned long	*icrp;
+	/* Acknowledge interrupt */
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x77777777) | 0x80000000; // INT1
+}
+#else
+#define ack_intr NULL
+#endif
+
+/****************************************************************************/
+
+void uclinux_ide_init(void)
+{
+	hw_regs_t hw;
+	ide_ioreg_t base;
+	int index, i;
+	ide_hwif_t* hwif;
+
+	for (i = 0; ide_defaults[i].base != (ide_ioreg_t) -1; i++) {
+		base = ide_defaults[i].base;
+		memset(&hw, 0, sizeof(hw));
+#ifdef CONFIG_COLDFIRE
+		mcf_autovector(hw.irq);
+#endif
+		hw.irq = ide_defaults[i].irq;
+		ide_setup_ports(&hw, base, ide_offsets, 0, 0, ack_intr,
+				/* ide_iops, */
+				ide_defaults[i].irq);
+		index = ide_register_hw(&hw, &hwif);
+		if (index != -1) {
+			hwif->mmio  = 1; /* not io(0) or mmio(1) */
+#ifdef CONFIG_COLDFIRE
+			hwif->OUTB  = OUTB;
+			hwif->OUTBSYNC = OUTBSYNC;
+			hwif->OUTW  = OUTW;
+			hwif->OUTL  = OUTL;
+			hwif->OUTSW = OUTSW;
+			hwif->OUTSL = OUTSL;
+			hwif->INB   = INB;
+			hwif->INW   = INW;
+			hwif->INL   = INL;
+			hwif->INSW  = INSW;
+			hwif->INSL  = INSL;
+
+			DRIVER(&hwif->drives[0])->cleanup = uclinux_irq_remove;
+
+#endif
+		}
+		disable_irq(ide_defaults[i].irq);
+	}
+}
+
+/****************************************************************************/
+/*
+ * this is called after the irq handler has been installed,  so if you need
+ * to fix something do it here
+ */
+
+void
+uclinux_irq_fixup()
+{
+#ifdef CONFIG_M5249C3
+	/* Enable interrupts for GPIO5 */
+	*((volatile unsigned long *) 0x800000c4) |= 0x00000020;
+
+	/* Enable interrupt level for GPIO5 - VEC37 */
+	*((volatile unsigned long *) 0x80000150) |= 0x00200000;
+#elif defined(CONFIG_SIGNAL_MCP751)
+	// ICR1 enable INT1
+	{
+	volatile unsigned long	*icrp;
+
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x07777777) | 0xd0000000; // INT1
+	}
+	DBGIDE("IDE enable irq %s %s\n", __DATE__, __TIME__);
+
+	// PITR trig L->H
+	*((volatile unsigned long *) (MCF_MBAR+MCFSIM_PITR)) |= 0x80000000; // INT1
+#endif
+}
+
+static void
+uclinux_irq_remove()
+{
+#ifdef CONFIG_M5249C3
+#elif defined(CONFIG_SIGNAL_MCP751)
+	DBGIDE("IDE free irq %s %s\n", __DATE__, __TIME__);
+	// ICR1 disable INT1
+	{
+	volatile unsigned long	*icrp;
+
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x07777777) | 0x80000000;
+	}
+#endif
+}
+
+/****************************************************************************/
+/*
+ * the custom IDE IO access for platforms that need it
+ */
+
+#ifdef CONFIG_COLDFIRE
+
+#if defined(CONFIG_eLIA) || defined(CONFIG_DISKtel)
+ /* 8/16 bit acesses are controlled by flicking bits in the CS register */
+ #define	MODE_16BIT()	\
+	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_CSCR6)) = 0x0080
+ #define	MODE_8BIT()	\
+	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_CSCR6)) = 0x0040
+
+ #define	ENABLE16()		MODE_16BIT()
+ #define	ENABLE32()		MODE_16BIT()
+ #define	DISABLE16()		MODE_8BIT()
+ #define	DISABLE32()		MODE_8BIT()
+#endif /* defined(CONFIG_eLIA) || defined(CONFIG_DISKtel) */
+
+#ifdef CONFIG_SECUREEDGEMP3
+ #define	ADDR8(addr)		(((addr) & 0x1) ? (0x8000+(addr)-1) : (addr))
+ #define	ADDR16(addr)	(addr)
+ #define	ADDR32(addr)	(addr)
+ #define	SWAP8(w)		((((w) & 0xffff) << 8) | (((w) & 0xffff) >> 8))
+ #define	SWAP16(w)		(w)
+ #define	SWAP32(w)		(w)
+
+ #define	io8_t	unsigned short
+#endif CONFIG_SECUREEDGEMP3
+
+#if defined(CONFIG_M5249C3)
+ #define	ADDR(a)			(((a) & 0xfffffff0) + (((a) & 0xf) << 1))
+ #define	ADDR8(addr)		ADDR(addr)
+ #define	ADDR16(addr)	ADDR(addr)
+ #define	ADDR32(addr)	ADDR(addr)
+
+ #define	SWAP8(w)		(w)
+ #define	SWAP16(w)		((((w)&0xffff) << 8)   | (((w)&0xffff) >> 8))
+ #define	SWAP32(w)		((((w)&0xff) << 24)    | (((w)&0xff00) << 8) | \
+							 (((w)&0xff0000) >> 8) | (((w)&0xff000000) >> 24))
+
+ #define io8_t	unsigned short
+#endif
+
+#if defined(CONFIG_SIGNAL_MCP751)
+ #define	ADDR(a)			(((a) & 0xfffffff0) + (((a) & 0xf) << 1))
+ #define	ADDR8(addr)		ADDR(addr)
+ #define	ADDR16(addr)	ADDR(addr)
+ #define	ADDR32(addr)	ADDR(addr)
+
+ #define	SWAP8(w)		(w&0xff)
+ #define	SWAP16(w)		((((w)&0xffff) << 8)   | (((w)&0xffff) >> 8))
+ #define	SWAP32(w)		((((w)&0xff) << 24)    | (((w)&0xff00) << 8) | \
+							 (((w)&0xff0000) >> 8) | (((w)&0xff000000) >> 24))
+
+ #define io8_t	unsigned short
+#endif
+
+
+/****************************************************************************/
+/*
+ * default anything that wasn't set
+ */
+
+#ifndef io8_t
+#define io8_t	unsigned char
+#endif
+
+#ifndef io16_t
+#define io16_t	unsigned short
+#endif
+
+#ifndef io32_t
+#define io32_t	unsigned long
+#endif
+
+#ifndef ENABLE8
+#define ENABLE8()
+#endif
+
+#ifndef ENABLE16
+#define ENABLE16()
+#endif
+
+#ifndef ENABLE32
+#define ENABLE32()
+#endif
+
+#ifndef DISABLE8
+#define DISABLE8()
+#endif
+
+#ifndef DISABLE16
+#define DISABLE16()
+#endif
+
+#ifndef DISABLE32
+#define DISABLE32()
+#endif
+
+#ifndef SWAP8
+#define SWAP8(x) (x)
+#endif
+
+#ifndef SWAP16
+#define SWAP16(x) (x)
+#endif
+
+#ifndef SWAP16
+#define SWAP16(x) (x)
+#endif
+
+#ifndef ADDR8
+#define ADDR8(x) (x)
+#endif
+
+#ifndef ADDR16
+#define ADDR16(x) (x)
+#endif
+
+#ifndef ADDR32
+#define ADDR32(x) (x)
+#endif
+
+#ifndef SWAP8
+#define SWAP8(x) (x)
+#endif
+
+#ifndef SWAP16
+#define SWAP16(x) (x)
+#endif
+
+#ifndef SWAP32
+#define SWAP32(x) (x)
+#endif
+
+/****************************************************************************/
+
+static void
+OUTB(u8 val, unsigned long addr)
+{
+	volatile io8_t	*rp;
+
+	DBGIDE("%s(val=%x,addr=%lx)\n", __FUNCTION__, val, addr);
+	rp = (volatile unsigned short *) ADDR(addr);
+	ENABLE8();
+	*rp = SWAP8(val);
+	DISABLE8();
+}
+
+static void
+OUTBSYNC(ide_drive_t *drive, u8 val, unsigned long addr)
+{
+	volatile io8_t	*rp;
+
+	DBGIDE("%s(val=%x,addr=%lx)\n", __FUNCTION__, val, addr);
+	rp = (volatile unsigned short *) ADDR(addr);
+	ENABLE8();
+	*rp = SWAP8(val);
+	DISABLE8();
+}
+
+static u8
+INB(unsigned long addr)
+{
+	volatile io8_t	*rp, val;
+
+	rp = (volatile unsigned short *) ADDR(addr);
+	ENABLE8();
+	val = *rp;
+	DISABLE8();
+	DBGIDE("%s(addr=%lx) = 0x%x\n", __FUNCTION__, addr, SWAP8(val));
+	return(SWAP8(val));
+}
+
+static void
+OUTW(u16 val, unsigned long addr)
+{
+	volatile io16_t	*rp;
+
+	DBGIDE("%s(val=%x,addr=%lx)\n", __FUNCTION__, val, addr);
+	rp = (volatile io16_t *) ADDR(addr);
+	ENABLE16();
+	*rp = SWAP16(val);
+	DISABLE16();
+}
+
+static void
+OUTSW(unsigned long addr, void *vbuf, u32 len)
+{
+	volatile io16_t	*rp, val;
+	unsigned short   	*buf;
+
+	DBGIDE("%s(addr=%lx,vbuf=%p,len=%lx)\n", __FUNCTION__, addr, vbuf, len);
+	buf = (unsigned short *) vbuf;
+	rp = (volatile io16_t *) ADDR(addr);
+	ENABLE16();
+	for (; (len > 0); len--) {
+		val = *buf++;
+		*rp = SWAP16(val);
+	}
+	DISABLE16();
+}
+
+static u16
+INW(unsigned long addr)
+{
+	volatile io16_t *rp, val;
+
+	rp = (volatile io16_t *) ADDR(addr);
+	ENABLE16();
+	val = *rp;
+	DISABLE16();
+	DBGIDE("%s(addr=%lx) = 0x%x\n", __FUNCTION__, addr, SWAP16(val));
+	return(SWAP16(val));
+}
+
+static void
+INSW(unsigned long addr, void *vbuf, u32 len)
+{
+	volatile io16_t *rp;
+	unsigned short          w, *buf;
+
+	DBGIDE("%s(addr=%lx,vbuf=%p,len=%lx)\n", __FUNCTION__, addr, vbuf, len);
+	buf = (unsigned short *) vbuf;
+	rp = (volatile io16_t *) ADDR(addr);
+	ENABLE16();
+	for (; (len > 0); len--) {
+		w = *rp;
+		*buf++ = SWAP16(w);
+	}
+	DISABLE16();
+}
+
+static u32
+INL(unsigned long addr)
+{
+	volatile io32_t *rp, val;
+
+	rp = (volatile io32_t *) ADDR(addr);
+	ENABLE32();
+	val = *rp;
+	DISABLE32();
+	DBGIDE("%s(addr=%lx) = 0x%lx\n", __FUNCTION__, addr, SWAP32(val));
+	return(SWAP32(val));
+}
+
+static void
+INSL(unsigned long addr, void *vbuf, u32 len)
+{
+	volatile io32_t *rp;
+	unsigned long          w, *buf;
+
+	DBGIDE("%s(addr=%lx,vbuf=%p,len=%lx)\n", __FUNCTION__, addr, vbuf, len);
+	buf = (unsigned long *) vbuf;
+	rp = (volatile io32_t *) ADDR(addr);
+	ENABLE32();
+	for (; (len > 0); len--) {
+		w = *rp;
+		*buf++ = SWAP32(w);
+	}
+	DISABLE32();
+}
+
+static void
+OUTL(u32 val, unsigned long addr)
+{
+	volatile io32_t	*rp;
+
+	DBGIDE("%s(val=%lx,addr=%lx)\n", __FUNCTION__, val, addr);
+	rp = (volatile io32_t *) ADDR(addr);
+	ENABLE32();
+	*rp = SWAP32(val);
+	DISABLE32();
+}
+
+static void
+OUTSL(unsigned long addr, void *vbuf, u32 len)
+{
+	volatile io32_t	*rp, val;
+	unsigned long   	*buf;
+
+	DBGIDE("%s(addr=%lx,vbuf=%p,len=%lx)\n", __FUNCTION__, addr, vbuf, len);
+	buf = (unsigned long *) vbuf;
+	rp = (volatile io32_t *) ADDR(addr);
+	ENABLE32();
+	for (; (len > 0); len--) {
+		val = *buf++;
+		*rp = SWAP32(val);
+	}
+	DISABLE32();
+}
+
+#endif /* CONFIG_COLDFIRE */
+
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/ide/Makefile linux-2.4.29-uc1/drivers/ide/Makefile
--- linux-2.4.29/drivers/ide/Makefile	2004-04-14 14:05:29.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ide/Makefile	2005-06-14 02:12:19.000000000 +0100
@@ -11,14 +11,14 @@
 
 export-objs := ide-iops.o ide-taskfile.o ide-proc.o ide.o ide-probe.o ide-probe-mini.o ide-dma.o ide-lib.o setup-pci.o ide-io.o ide-disk.o
 
-all-subdirs	:= arm legacy pci ppc raid
-mod-subdirs	:= arm legacy pci ppc raid
+all-subdirs	:= arm legacy pci ppc raid h8300
+mod-subdirs	:= arm legacy pci ppc raid h8300
 
 obj-y		:=
 obj-m		:=
 ide-obj-y	:=
 
-subdir-$(CONFIG_BLK_DEV_IDE) += legacy ppc arm raid pci
+subdir-$(CONFIG_BLK_DEV_IDE) += legacy ppc arm raid pci h8300
 
 # First come modules that register themselves with the core
 
@@ -55,6 +55,7 @@
   obj-y		+= legacy/idedriver-legacy.o
   obj-y		+= ppc/idedriver-ppc.o
   obj-y		+= arm/idedriver-arm.o
+  obj-y		+= h8300/idedriver-h8300.o
 else
   ifeq ($(CONFIG_BLK_DEV_HD_ONLY),y)
 	subdir-$(CONFIG_BLK_DEV_HD_ONLY) += legacy
@@ -82,8 +83,8 @@
 include $(TOPDIR)/Rules.make
 
 ide-core.o:	$(ide-core-objs)
-	$(LD) -r -o $@ $(ide-core-objs)
+	$(LD) $(LDFLAGS) -r -o $@ $(ide-core-objs)
 
 ide-detect.o:	$(ide-detect-objs)
-	$(LD) -r -o $@ $(ide-detect-objs)
+	$(LD) $(LDFLAGS) -r -o $@ $(ide-detect-objs)
 
diff -urN linux-2.4.29/drivers/ide/ocidec.c linux-2.4.29-uc1/drivers/ide/ocidec.c
--- linux-2.4.29/drivers/ide/ocidec.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ide/ocidec.c	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,220 @@
+/*
+ *  linux/drivers/ide/ocidec.c		Version 0.06	Aug 3, 2000
+ *
+ */
+
+/*
+ * Open Core IDE Controller (OCIDEC) support
+ *
+ */
+
+#undef REALLY_SLOW_IO		/* most systems can safely undef this */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/nios.h>
+
+#include "ide_modes.h"
+#include "ocidec.h"
+
+
+
+#define WAIT_LOOP_COUNT  6
+
+unsigned long ATA_reset( np_OCIDEC* np_ptr )
+{
+    int i;
+    unsigned long val;
+
+//vic FIXME - maybe wait a bit longer to make sure the devices see the reset
+    np_ptr->np_ctrl = ATA_RESET;
+	udelay (25);		/* Assert RESET for at least 25us */
+
+    for ( i = WAIT_LOOP_COUNT; i; i-- )
+    {
+        val = np_ptr->np_ctrl;
+        if ( val == ATA_RESET )
+            break;
+    }
+
+    if ( !i )
+        return 1;      // timed out
+
+    np_ptr->np_ctrl = 0;  // Clear reset op
+	udelay (2000);		/* Negate RESET for at least 2ms */
+
+    for ( i = WAIT_LOOP_COUNT; i; i-- )
+    {
+        val = np_ptr->np_ctrl;
+        if ( !val )
+            break;
+    }
+    return val;
+}
+
+
+unsigned long ATA_initialize_control( np_OCIDEC* np_ptr )
+{
+    unsigned int stat;
+    unsigned int ctrlVal = IDE_ENABLE | COMPATIBLE_TIMING_IORDY_ENABLE | (IS_PP_ENABLED ? WRITE_PING_PONG_ENABLE : 0);
+
+    if ( ATA_reset( np_ptr ) )
+        return 1;
+
+    if ( (stat = np_ptr->np_stat) != VERSION3_REV1 )
+    {
+        printk( "OCIDEC status = 0x%08lX, should be 0x%08lX\n", VERSION3_REV1, stat );
+        return 1;
+    }
+    else
+    {
+        stat >>= 24;
+        printk( "OCIDEC V%d.%d\n", stat >> 4, stat & 0x0F );
+    }
+
+    np_ptr->np_ctrl = ctrlVal;
+    if ( np_ptr->np_ctrl != ctrlVal )
+        return 1;
+
+    np_ptr->np_pctr  = MODE0_TIMING;
+    np_ptr->np_pftr0 = MODE0_DTIMING;
+    np_ptr->np_pftr1 = MODE0_DTIMING;
+
+    np_ptr->np_stat = 0;		/* clear pending interrupt */
+
+    return 0;
+}
+
+
+int Reset( np_OCIDEC* ideptr )
+{
+    if ( ATA_initialize_control( ideptr ) )
+        return -1;
+    return 0;
+}
+
+
+/* FIXME - the use of IORDY and fast timing for modes 0, 1, and 2 needs tbd */
+void ocidec_set_mode(  np_OCIDEC *ideptr, int mode, int device )
+{
+    if ( mode < 0 || mode > 4 )
+        mode = 0;
+
+	if ( device ) {
+		/* device = 1; */
+		switch ( mode )
+		{
+			case 0:
+				ideptr->np_pftr1 = MODE0_DTIMING;
+				ideptr->np_ctrl &= ~(FAST_TIMING_DEV1_ENABLE | FAST_TIMING_DEV1_IORDY_ENABLE);
+				break;
+
+			case 1:
+				ideptr->np_pftr1 = MODE1_DTIMING;
+				ideptr->np_ctrl |= (FAST_TIMING_DEV1_ENABLE | FAST_TIMING_DEV1_IORDY_ENABLE);
+				break;
+
+			case 2:
+				ideptr->np_pftr1 = MODE2_DTIMING;
+				ideptr->np_ctrl &= ~(FAST_TIMING_DEV1_ENABLE | FAST_TIMING_DEV1_IORDY_ENABLE);
+				break;
+
+			case 3:
+				ideptr->np_pftr1 = MODE3_DTIMING;
+				ideptr->np_ctrl |= (FAST_TIMING_DEV1_ENABLE | FAST_TIMING_DEV1_IORDY_ENABLE);
+				break;
+
+			case 4:
+				ideptr->np_pftr1 = MODE4_DTIMING;
+				ideptr->np_ctrl |= (FAST_TIMING_DEV1_ENABLE | FAST_TIMING_DEV1_IORDY_ENABLE);
+				break;
+
+			default:
+				break;
+		}
+	} else /* device = 0 */ {
+		switch ( mode )
+		{
+			case 0:
+				ideptr->np_pftr0 = MODE0_DTIMING;
+				ideptr->np_ctrl &= ~(FAST_TIMING_DEV0_ENABLE | FAST_TIMING_DEV0_IORDY_ENABLE);
+				break;
+
+			case 1:
+				ideptr->np_pftr0 = MODE1_DTIMING;
+				ideptr->np_ctrl |= (FAST_TIMING_DEV0_ENABLE | FAST_TIMING_DEV0_IORDY_ENABLE);
+				break;
+
+			case 2:
+				ideptr->np_pftr0 = MODE2_DTIMING;
+				ideptr->np_ctrl &= ~(FAST_TIMING_DEV0_ENABLE | FAST_TIMING_DEV0_IORDY_ENABLE);
+				break;
+
+			case 3:
+				ideptr->np_pftr0 = MODE3_DTIMING;
+				ideptr->np_ctrl |= (FAST_TIMING_DEV0_ENABLE | FAST_TIMING_DEV0_IORDY_ENABLE);
+				break;
+
+			case 4:
+				ideptr->np_pftr0 = MODE4_DTIMING;
+				ideptr->np_ctrl |= (FAST_TIMING_DEV0_ENABLE | FAST_TIMING_DEV0_IORDY_ENABLE);
+				break;
+
+	        default:
+				break;
+		}
+	}
+}
+
+
+static void ocidec_tune_drive(ide_drive_t *drive, byte pio)
+{
+    np_OCIDEC *ideptr = (np_OCIDEC *)na_ide_interface;
+	ide_pio_data_t d;
+
+	pio = ide_get_best_pio_mode(drive, pio, OCIDEC_MAX_PIO, &d);
+	printk ("%s: selected PIO mode%d (%dns) %s/IORDY%s%s\n",
+		drive->name,
+		d.pio_mode,
+		d.cycle_time,
+		d.use_iordy ? "w" : "wo",
+		d.overridden ? " (overriding vendor mode)" : "",
+		d.blacklisted ? " (blacklisted)" : "");
+
+    ocidec_set_mode( ideptr, pio, drive->select.b.unit );
+}
+
+
+static void delay_2s (void)
+{
+	unsigned long timer = jiffies + (HZ*2);
+	while (timer > jiffies);
+}
+
+void __init ocidec_init(void)		/* called from ide.c */
+{
+    np_OCIDEC *ideptr = (np_OCIDEC *)na_ide_interface;
+    int i;
+
+    if ( Reset( ideptr ) == -1 )
+    {
+        printk( "Error in resetting OCIDEC.\n");
+        return;
+    }
+
+	delay_2s();		/* give drives time to spinup and settle */
+
+    ide_hwifs[0].chipset  = ide_ocidec;
+    ide_hwifs[0].tuneproc = &ocidec_tune_drive;
+	ide_hwifs[0].drives[0].autotune = 1;
+	ide_hwifs[0].drives[1].autotune = 1;
+}
diff -urN linux-2.4.29/drivers/ide/ocidec.h linux-2.4.29-uc1/drivers/ide/ocidec.h
--- linux-2.4.29/drivers/ide/ocidec.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ide/ocidec.h	2005-06-14 02:12:19.000000000 +0100
@@ -0,0 +1,104 @@
+#ifndef _OCIDEC_
+#define _OCIDEC_
+
+typedef struct OCIDEC_Status_s
+{
+    unsigned long IDE_interruptStatus : 1; // bit   0
+    unsigned long reserved1           : 5; // bits  5:1
+    unsigned long writePingPongFull   : 1; // bit   6
+    unsigned long PIO_inProgress      : 1; // bit   7
+    unsigned long DMA_reqStatus       : 1; // bit   8
+    unsigned long DMA_xmitFull        : 1; // bit   9
+    unsigned long DMA_recvEmpty       : 1; // bit  10
+    unsigned long reserved2           : 4; // bits 14:11
+    unsigned long DMA_inProgress      : 1; // bit  15
+    unsigned long reserved3           : 7; // bits 23:16
+    unsigned long revisionNr          : 4; // bits 27:24
+    unsigned long deviceID            : 4; // bits 31:28
+} OCIDEC_Status_t;
+
+// OCIDEC status register bit masks
+#define IDE_INTERRUPT_STATUS  0x00000001
+#define WRITE_PING_PONG_FULL  0x00000040
+#define PIO_IN_PROGRESS       0x00000080
+#define DMA_REQ_STATUS        0x00000100
+#define DMA_XMIT_FULL         0x00000200
+#define DMA_RECV_EMPTY        0x00000400
+#define DMA_IN_PROGRESS       0x00008000
+#define REVISION_NR           0x0F000000
+#define DEVICE_ID             0xF0000000
+#define RESERVED_STATUS_BITS  0x00FF713E
+
+
+typedef struct OCIDEC_Control_s
+{
+  unsigned long ATA_Reset                     : 1; // bit   0
+  unsigned long compatibleTiming_IORDY_enable : 1; // bit   1
+  unsigned long fastTimingDev0_IORDY_enable   : 1; // bit   2
+  unsigned long fastTimingDev1_IORDY_enable   : 1; // bit   3
+  unsigned long writePingPongEnable           : 1; // bit   4
+  unsigned long fastTimingDev0Enable          : 1; // bit   5
+  unsigned long fastTimingDev1Enable          : 1; // bit   6
+  unsigned long IDE_enable                    : 1; // bit   7
+  unsigned long endianFlipDev0                : 1; // bit   8
+  unsigned long endianFlipDev1                : 1; // bit   9
+  unsigned long reserved1                     : 3; // bits 12:10
+  unsigned long DMA_dir                       : 1; // bit  13
+  unsigned long reserved2                     : 1; // bit  14
+  unsigned long DMA_enable                    : 1; // bit  15
+  unsigned long reserved3                     : 16;// bits 31:16
+} OCIDEC_Control_t;
+
+
+// OCIDEC Control register bit masks
+#define ATA_RESET                       0x00000001
+#define COMPATIBLE_TIMING_IORDY_ENABLE  0x00000002
+#define FAST_TIMING_DEV0_IORDY_ENABLE   0x00000004
+#define FAST_TIMING_DEV1_IORDY_ENABLE   0x00000008
+#define WRITE_PING_PONG_ENABLE          0x00000010
+#define FAST_TIMING_DEV0_ENABLE         0x00000020
+#define FAST_TIMING_DEV1_ENABLE         0x00000040
+#define IDE_ENABLE                      0x00000080
+#define ENDIAN_FLIP_DEV0                0x00000100
+#define ENDIAN_FLIP_DEV1                0x00000200
+#define DMA_DIR                         0x00002000
+#define DMA_ENABLE                      0x00008000
+#define RESERVED_CONTROL_BITS           0xFFFF1C00
+
+
+typedef volatile struct
+{
+    unsigned long np_ctrl;  // control register
+    unsigned long np_stat;  // status register
+    unsigned long np_pctr;  // PIO compatible timing register
+    unsigned long np_pftr0; // pio fast timing register device 0
+    unsigned long np_pftr1; // pio fast timing register device 1
+    unsigned long np_dtr0;  // DMA timing register device 0
+    unsigned long np_dtr1;  // DMA timing register device 1
+    unsigned long np_dtxdb; // DMA transmit data buffer
+} np_OCIDEC;
+#define	np_drxdb  np_dtxdb  // DMA receive data buffer
+
+
+#define DEFAULT_TIMING 0x17021C06
+
+#define MODE0_TIMING   0x07010901
+#define MODE1_TIMING   0x01010901
+#define MODE2_TIMING   0x01010901
+#define MODE3_TIMING   0x01010201
+#define MODE4_TIMING   0x01010101
+
+#define MODE0_DTIMING  0x0B010401
+#define MODE1_DTIMING  0x06010301
+#define MODE2_DTIMING  0x03010201
+#define MODE3_DTIMING  0x01010201
+#define MODE4_DTIMING  0x01010101
+
+
+#define VERSION3_REV1  0x31000000
+#define OCIDEC_MAX_PIO 4
+#define IS_PP_ENABLED  1         /* Using write ping-pong facility, or not. */
+
+
+#endif
+
diff -urN linux-2.4.29/drivers/ieee1394/Config.in linux-2.4.29-uc1/drivers/ieee1394/Config.in
--- linux-2.4.29/drivers/ieee1394/Config.in	2003-08-25 12:44:41.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ieee1394/Config.in	2005-06-14 02:11:55.000000000 +0100
@@ -1,10 +1,10 @@
 # -*- shell-script -*-
 
-if [ "$CONFIG_PCI" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
     mainmenu_option next_comment
     comment 'IEEE 1394 (FireWire) support (EXPERIMENTAL)'
 
-    dep_tristate 'IEEE 1394 (FireWire) support (EXPERIMENTAL)' CONFIG_IEEE1394 $CONFIG_PCI
+    tristate 'IEEE 1394 (FireWire) support (EXPERIMENTAL)' CONFIG_IEEE1394
 
     if [ "$CONFIG_IEEE1394" != "n" ]; then
 
@@ -13,7 +13,7 @@
 	if [ "$CONFIG_I2C" = "n" -o "$CONFIG_I2C_ALGOBIT" = "n" ]; then
 	    comment '  Texas Instruments PCILynx requires I2C bit-banging'
 	else
-	    dep_tristate '  Texas Instruments PCILynx support' CONFIG_IEEE1394_PCILYNX $CONFIG_IEEE1394 $CONFIG_I2C $CONFIG_I2C_ALGOBIT
+	    dep_tristate '  Texas Instruments PCILynx support' CONFIG_IEEE1394_PCILYNX $CONFIG_IEEE1394 $CONFIG_I2C $CONFIG_I2C_ALGOBIT $CONFIG_PCI
 	fi
 
 	# Non-maintained pcilynx options
@@ -22,7 +22,8 @@
 	#     bool '    Support for non-IEEE1394 local ports' CONFIG_IEEE1394_PCILYNX_PORTS
 	# fi
 
-	dep_tristate '  OHCI-1394 support' CONFIG_IEEE1394_OHCI1394 $CONFIG_IEEE1394
+	dep_tristate '  OHCI-1394 support' CONFIG_IEEE1394_OHCI1394 $CONFIG_IEEE1394 $CONFIG_PCI
+	dep_tristate '  iPod IEEE1394 support (TI TSB43AA82)' CONFIG_IEEE1394_IPOD $CONFIG_IEEE1394
 
 	comment "Protocol Drivers"
 	dep_tristate '  OHCI-1394 Video support' CONFIG_IEEE1394_VIDEO1394 $CONFIG_IEEE1394_OHCI1394
diff -urN linux-2.4.29/drivers/ieee1394/dma.c linux-2.4.29-uc1/drivers/ieee1394/dma.c
--- linux-2.4.29/drivers/ieee1394/dma.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ieee1394/dma.c	2005-06-14 02:11:56.000000000 +0100
@@ -184,6 +184,8 @@
 	pci_dma_sync_sg(dma->dev, &dma->sglist[first], last - first + 1, dma->direction);
 }
 
+#ifndef CONFIG_ARCH_IPOD
+
 /* nopage() handler for mmap access */
 
 static struct page*
@@ -237,3 +239,5 @@
 
 	return 0;
 }
+
+#endif /* CONFIG_ARCH_IPOD */
diff -urN linux-2.4.29/drivers/ieee1394/ieee1394_core.c linux-2.4.29-uc1/drivers/ieee1394/ieee1394_core.c
--- linux-2.4.29/drivers/ieee1394/ieee1394_core.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-uc1/drivers/ieee1394/ieee1394_core.c	2005-06-14 02:11:55.000000000 +0100
@@ -1235,7 +1235,9 @@
 	/* it's ok to pass a NULL devfs_handle to devfs_unregister */
 	devfs_unregister(ieee1394_devfs_handle);
 	
+#ifdef CONFIG_PROC_FS
 	remove_proc_entry("ieee1394", proc_bus);
+#endif
 }
 
 module_init(ieee1394_init);
@@ -1331,7 +1333,9 @@
 EXPORT_SYMBOL(dma_region_alloc);
 EXPORT_SYMBOL(dma_region_free);
 EXPORT_SYMBOL(dma_region_sync);
+#ifndef CONFIG_ARCH_IPOD
 EXPORT_SYMBOL(dma_region_mmap);
+#endif
 EXPORT_SYMBOL(dma_region_offset_to_bus);
 
 /** iso.c **/
diff -urN linux-2.4.29/drivers/ieee1394/ieee1394_transactions.c linux-2.4.29-uc1/drivers/ieee1394/ieee1394_transactions.c
--- linux-2.4.29/drivers/ieee1394/ieee1394_transactions.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-uc1/drivers/ieee1394/ieee1394_transactions.c	2005-06-14 02:11:55.000000000 +0100
@@ -143,11 +143,18 @@
 	}
 
 	spin_lock_irqsave(&tp->lock, flags);
-	
+
+#ifndef CONFIG_ARCH_IPOD
 	packet->tlabel = find_next_zero_bit(tp->pool, 64, tp->next);
 	if (packet->tlabel > 63)
 		packet->tlabel = find_first_zero_bit(tp->pool, 64);
 	tp->next = (packet->tlabel + 1) % 64;
+#else
+	packet->tlabel = find_next_zero_bit(tp->pool, 0xe, tp->next);
+	if (packet->tlabel > 0xe)
+		packet->tlabel = find_first_zero_bit(tp->pool, 0xe);
+	tp->next = (packet->tlabel + 1) % 0xe;
+#endif
 	/* Should _never_ happen */
 	BUG_ON(test_and_set_bit(packet->tlabel, tp->pool));
 	tp->allocations++;
diff -urN linux-2.4.29/drivers/ieee1394/nodemgr.c linux-2.4.29-uc1/drivers/ieee1394/nodemgr.c
--- linux-2.4.29/drivers/ieee1394/nodemgr.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/ieee1394/nodemgr.c	2005-06-14 02:11:55.000000000 +0100
@@ -1260,7 +1260,8 @@
 	quadlet_t bc;
 	int status;
 
-	if (host->is_irm)
+	/* if irm_id == -1 then there is no IRM on this bus */
+	if (host->is_irm  || host->irm_id == (nodeid_t)-1)
 		return 1;
 
 	status = hpsb_read(host, LOCAL_BUS | (host->irm_id),
diff -urN linux-2.4.29/drivers/ieee1394/sbp2.c linux-2.4.29-uc1/drivers/ieee1394/sbp2.c
--- linux-2.4.29/drivers/ieee1394/sbp2.c	2004-08-08 00:26:04.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ieee1394/sbp2.c	2005-06-14 02:11:56.000000000 +0100
@@ -231,7 +231,9 @@
  * enable this define to make use of it. This provides better hotplug
  * support. The mentioned patch is not part of the kernel proper though,
  * because it is considered somewhat of a hack. */
-//#define SBP2_USE_SCSI_ADDREM_HACK
+#ifdef CONFIG_ARCH_IPOD
+#define SBP2_USE_SCSI_ADDREM_HACK
+#endif
 
 
 /*
diff -urN linux-2.4.29/drivers/Makefile linux-2.4.29-uc1/drivers/Makefile
--- linux-2.4.29/drivers/Makefile	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-uc1/drivers/Makefile	2005-06-14 02:12:05.000000000 +0100
@@ -8,9 +8,9 @@
 
 mod-subdirs :=	dio hil mtd sbus video macintosh usb input telephony ide \
 		message/i2o message/fusion scsi md ieee1394 pnp isdn atm \
-		fc4 net/hamradio i2c acpi bluetooth usb/gadget
+		fc4 net/hamradio i2c acpi bluetooth usb/gadget pcmcia
 
-subdir-y :=	parport char block net sound misc media cdrom hotplug
+subdir-y :=	parport serial char block net sound misc media cdrom hotplug 
 subdir-m :=	$(subdir-y)
 
 
@@ -49,4 +49,6 @@
 
 subdir-$(CONFIG_BLUEZ)		+= bluetooth
 
+subdir-$(CONFIG_ARCH_AT91RM9200)+= at91
+
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/media/video/Config.in linux-2.4.29-uc1/drivers/media/video/Config.in
--- linux-2.4.29/drivers/media/video/Config.in	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/media/video/Config.in	2005-06-14 02:12:03.000000000 +0100
@@ -49,6 +49,13 @@
 dep_tristate '  Miro DC10(+) support' CONFIG_VIDEO_ZORAN_DC10 $CONFIG_VIDEO_ZORAN $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C
 dep_tristate '  Linux Media Labs LML33 support' CONFIG_VIDEO_ZORAN_LML33 $CONFIG_VIDEO_ZORAN $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C
 dep_tristate '  Zoran ZR36120/36125 Video For Linux' CONFIG_VIDEO_ZR36120 $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   # unfortunately, this depends on having CONFIG_FB_CYBER2000
+   # set as well - we hook off of the VGA driver
+   if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then
+      dep_tristate '  NetWinder Video for Linux (EXPERIMENTAL)' CONFIG_VIDEO_CYBERPRO $CONFIG_VIDEO_DEV
+   fi
+fi
 if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_HIGHMEM64G" != "y" ]; then
   dep_tristate '  Sony Vaio Picturebook Motion Eye Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_MEYE $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_SONYPI
 fi
diff -urN linux-2.4.29/drivers/media/video/i2c-old.c linux-2.4.29-uc1/drivers/media/video/i2c-old.c
--- linux-2.4.29/drivers/media/video/i2c-old.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/media/video/i2c-old.c	2005-06-14 02:12:03.000000000 +0100
@@ -36,11 +36,26 @@
 static struct i2c_driver *drivers[I2C_DRIVER_MAX];
 static int bus_count = 0, driver_count = 0;
 
+extern int saa7111_init(void);
+extern int saa7185_init(void);
+extern int bt819_init(void);
+extern int bt856_init(void);
+
 int i2c_init(void)
 {
 	printk(KERN_INFO "i2c: initialized%s\n",
 		scan ? " (i2c bus scan enabled)" : "");
 
+#if defined(CONFIG_VIDEO_BUZ) || defined(CONFIG_VIDEO_CYBERPRO)
+	saa7111_init();
+#endif
+#ifdef CONFIG_VIDEO_BUZ
+	saa7185_init();
+#endif
+#ifdef CONFIG_VIDEO_LML33
+	bt819_init();
+	bt856_init();
+#endif
 	return 0;
 }
 
diff -urN linux-2.4.29/drivers/media/video/Makefile linux-2.4.29-uc1/drivers/media/video/Makefile
--- linux-2.4.29/drivers/media/video/Makefile	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/media/video/Makefile	2005-06-14 02:12:03.000000000 +0100
@@ -43,6 +43,8 @@
 obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
 obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
 obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
+obj-$(CONFIG_VIDEO_ZORAN) += buz.o i2c-old.o saa7110.o saa7111.o saa7185.o 
+obj-$(CONFIG_VIDEO_CYBERPRO) += cyberpro.o i2c-old.o saa7111.o
 obj-$(CONFIG_VIDEO_W9966) += w9966.o
 obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o i2c-old.o
 obj-$(CONFIG_VIDEO_ZORAN_BUZ) += saa7111.o saa7185.o
diff -urN linux-2.4.29/drivers/media/video/saa7111.c linux-2.4.29-uc1/drivers/media/video/saa7111.c
--- linux-2.4.29/drivers/media/video/saa7111.c	2001-09-30 20:26:06.000000000 +0100
+++ linux-2.4.29-uc1/drivers/media/video/saa7111.c	2005-06-14 02:12:03.000000000 +0100
@@ -149,9 +149,17 @@
 		0x0d, 0x00,	/* 0d - HUE=0 */
 		0x0e, 0x01,	/* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
 		0x0f, 0x00,	/* 0f - reserved */
+#ifndef CONFIG_ARCH_NETWINDER
 		0x10, 0x48,	/* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
+#else
+		0x10, 0xc8,	/* 10 - YUV CCIR 656, 8 bits */
+#endif
 		0x11, 0x1c,	/* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
+#ifndef CONFIG_ARCH_NETWINDER
 		0x12, 0x00,	/* 12 - output control 2 */
+#else
+		0x12, 0x80,	/* 12 -	Horizontal Locked on pin 39 */
+#endif
 		0x13, 0x00,	/* 13 - output control 3 */
 		0x14, 0x00,	/* 14 - reserved */
 		0x15, 0x00,	/* 15 - VBI */
diff -urN linux-2.4.29/drivers/misc/Config.in linux-2.4.29-uc1/drivers/misc/Config.in
--- linux-2.4.29/drivers/misc/Config.in	1999-12-25 23:04:56.000000000 +0000
+++ linux-2.4.29-uc1/drivers/misc/Config.in	2005-06-14 02:12:16.000000000 +0100
@@ -4,4 +4,21 @@
 mainmenu_option next_comment
 comment 'Misc devices'
 
+if [ "$CONFIG_MICROBLAZE" = "y" ]; then
+  tristate 'FSL FIFO driver' CONFIG_MICROBLAZE_FSLFIFO 
+
+  if [ "$CONFIG_MICROBLAZE_FSLFIFO" = "y" -o \
+	"$CONFIG_MICROBLAZE_FSLFIFO" = "m" ]; then
+    bool '  FIFO on FSL0' CONFIG_MICROBLAZE_FSLFIFO0
+    bool '  FIFO on FSL1' CONFIG_MICROBLAZE_FSLFIFO1
+    bool '  FIFO on FSL2' CONFIG_MICROBLAZE_FSLFIFO2
+    bool '  FIFO on FSL3' CONFIG_MICROBLAZE_FSLFIFO3
+    bool '  FIFO on FSL4' CONFIG_MICROBLAZE_FSLFIFO4
+    bool '  FIFO on FSL5' CONFIG_MICROBLAZE_FSLFIFO5
+    bool '  FIFO on FSL6' CONFIG_MICROBLAZE_FSLFIFO6
+    bool '  FIFO on FSL7' CONFIG_MICROBLAZE_FSLFIFO7
+  fi
+
+fi
+
 endmenu
diff -urN linux-2.4.29/drivers/misc/fslfifo/fslfifo.c linux-2.4.29-uc1/drivers/misc/fslfifo/fslfifo.c
--- linux-2.4.29/drivers/misc/fslfifo/fslfifo.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/misc/fslfifo/fslfifo.c	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,571 @@
+/*
+ * fslfifo.c -- FSL FIFO driver for Microblaze
+ *
+ * Copyright (C) 2004 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *       
+ */
+
+/*
+ * Simple driver to provide Linux-style FIFO interface to custom hardware
+ * peripherals connected to Microblaze FSL ports.  See Microblaze user manual
+ * for details of FSL architecture.
+ *
+ * read() and write() operate on software buffers, with a tasklet scheduled
+ * to actually stuff data into / out of FSL ports.  This might be better 
+ * served by interrupts, however the hardware doesn't support it yet.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/miscdevice.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <asm/fsl.h>
+#include <asm/fslfifo_ioctl.h>
+
+MODULE_AUTHOR("John Williams <jwilliams@itee.uq.edu.au>");
+MODULE_LICENSE("GPL");
+
+#if 0
+#define DBPRINTK(...) printk(__VA_ARGS__)
+#else
+#define DBPRINTK(...)
+#endif
+
+#ifndef MIN
+#define MIN(a,b)	((a)<(b) ? (a) : (b))
+#endif
+
+#include "fslfifo.h"
+
+DECLARE_WAIT_QUEUE_HEAD(fsl_read_queue);
+DECLARE_WAIT_QUEUE_HEAD(fsl_write_queue);
+
+/* Declarations of the various files ops */
+static loff_t fsl_llseek(struct file *f, loff_t off, int whence);
+static ssize_t fsl_read(struct file *f, char *buf, size_t count, loff_t *pos);
+static ssize_t fsl_write(struct file *f, const char *buf, size_t count, loff_t *pos);
+static int fsl_ioctl(struct inode *inode, struct file *f,
+			unsigned int cmd, unsigned long arg);
+static int fsl_open(struct inode *inode, struct file *f);
+static int fsl_release(struct inode *inode, struct file *f);
+
+void write_tasklet_func(unsigned long data);
+void read_tasklet_func(unsigned long data);
+	
+static struct file_operations fsl_fops = {
+	llseek:		fsl_llseek,
+	read:		fsl_read,
+	write:		fsl_write,
+	ioctl:		fsl_ioctl,
+	open:		fsl_open,
+	release:	fsl_release};
+
+/* Statically allocate descriptors - this is klunky but too bad */
+static struct miscdevice fsl_miscdev[MAX_FSLFIFO_COUNT];
+static struct fsl_fifo_t fsl_fifo_table[MAX_FSLFIFO_COUNT];
+
+/* The tasklet data is the address of the first fsl_fifo in the array
+   We do this so a single tasklet can process all fsl fifos
+   hopefully saves us some time in doing multiple tasklet executions
+*/
+DECLARE_TASKLET(fsl_write_tasklet, write_tasklet_func, 
+			(unsigned long)fsl_fifo_table);
+DECLARE_TASKLET(fsl_read_tasklet, read_tasklet_func, 
+			(unsigned long)fsl_fifo_table);
+
+/* The fsl fifo writing tasklet.  It loops through *all* FIFOs
+   see if any are waiting to write, and does so until it blocks.
+   if *any* FIFO blocks on writing, the tasklet is rescheduled.
+
+   We could alternatively have one tasklet per FIFO , not sure which would
+   be more efficient... */
+void write_tasklet_func(unsigned long data)
+{
+	struct fsl_fifo_t *fsl_fifo=(struct fsl_fifo_t *)data;
+	int id;
+	int do_reschedule=0;
+
+	/* Loop through each fsl fifo*/
+	for(id=0;id<MAX_FSLFIFO_COUNT;id++, fsl_fifo++)
+	{
+		unsigned flags;
+
+		if(!fsl_fifo->exists)
+			continue;
+
+		save_flags_cli(flags);
+
+		/* There must be at least "width" bytes in the buffer */
+		if(fsl_fifo->tx_cnt < fsl_fifo->width)
+		{
+			restore_flags(flags);
+			continue;
+		}
+
+		while(fsl_fifo->tx_cnt >= fsl_fifo->width)
+		{
+			unsigned fsl_status;
+			unsigned int value;
+			void *ptr = &(fsl_fifo->tx_buf[fsl_fifo->tx_tail]);
+
+			switch(fsl_fifo->width)
+			{
+			case 1: value = (u32) *((u8 *)ptr);
+				break;
+			case 2: value = (u32) *((u16 *)ptr);
+				break;
+			case 4: value = (u32) *((u32 *)ptr);
+				break;
+			default:
+				/* errors in a tasklet?  yuck! */
+			}
+
+			fsl_nput(fsl_fifo->id, value, fsl_status);
+
+			if(fsl_nodata(fsl_status))
+			{
+				do_reschedule++;
+				break;
+			}
+			else
+			{
+				/* Update the buffer data structure */
+				fsl_fifo->tx_cnt-=fsl_fifo->width;
+				fsl_fifo->tx_tail+= fsl_fifo->width;
+				fsl_fifo->tx_tail &= FSLFIFO_BUF_SIZE-1;
+			}
+		}
+		restore_flags(flags);
+	}
+
+	if(do_reschedule)
+		tasklet_schedule(&fsl_write_tasklet);
+
+	/* Wake any processes blocked on FIFO write() operations */
+	wake_up(&fsl_write_queue);
+}
+
+
+void read_tasklet_func(unsigned long data)
+{
+	struct fsl_fifo_t *fsl_fifo=(struct fsl_fifo_t *)data;
+	int id;
+	int do_reschedule=0;
+
+	/* Loop through each fsl fifo*/
+	for(id=0;id<MAX_FSLFIFO_COUNT;id++, fsl_fifo++)
+	{
+		unsigned flags;
+
+		if(!fsl_fifo->exists)
+			continue;
+	
+		/* If rx_buf is full, don't even try */
+		save_flags_cli(flags);
+		if((fsl_fifo->rx_cnt + fsl_fifo->width) >= FSLFIFO_BUF_SIZE)
+		{
+			restore_flags(flags);
+			continue;
+		}
+		restore_flags(flags);
+
+		while(1)
+		{
+			unsigned val;
+			unsigned fsl_status;
+
+			void *ptr=&(fsl_fifo->rx_buf[fsl_fifo->rx_head]);
+
+			fsl_nget(fsl_fifo->id, val, fsl_status);
+			if(fsl_nodata(fsl_status))
+			{
+				break;
+			}
+
+			save_flags_cli(flags);
+
+			switch(fsl_fifo->width) {
+			case 1:
+				*((u8*)ptr) = val & 0xFF;
+				break;
+			case 2:
+				*((u16*)ptr) = val & 0xFFFF;
+				break;
+			case 4:
+				*((u32*)ptr) = val;
+				break;
+			default:
+				/* bleugh, error in tasklet */
+			}
+			
+			fsl_fifo->rx_head += fsl_fifo->width;
+			fsl_fifo->rx_head &= FSLFIFO_BUF_SIZE-1;
+			fsl_fifo->rx_cnt += fsl_fifo->width;
+			if(fsl_fifo->rx_cnt<FSLFIFO_BUF_SIZE)
+			{
+				restore_flags(flags);
+				do_reschedule++;
+				break;
+			}
+			restore_flags(flags);
+		}
+	}
+
+	if(do_reschedule)
+	{
+		tasklet_schedule(&fsl_read_tasklet);
+	}
+
+	wake_up(&fsl_read_queue);
+}
+
+
+/* Seek doesn't make a lot of sense! */
+static loff_t fsl_llseek(struct file *f, loff_t off, int whence)
+{
+	return 0;
+}
+
+/* Put data into the tx_buffer and schedule write_tasklet */
+static ssize_t fsl_write(struct file *f, const char *buf, 
+				size_t count, loff_t *pos)
+{
+	struct fsl_fifo_t *fsl_fifo;
+	int do_sched_tasklet=0;
+	unsigned flags;
+	int total=0;
+
+	fsl_fifo = (struct fsl_fifo_t *)f->private_data;
+	if(!fsl_fifo->exists)
+		return -ENODEV;
+
+	save_flags_cli(flags);
+
+	/* Is the tx buffer full, and we block */
+	while(fsl_fifo->tx_cnt==FSLFIFO_BUF_SIZE)
+	{
+		restore_flags(flags);
+		tasklet_schedule(&fsl_write_tasklet);
+		interruptible_sleep_on(&fsl_write_queue);
+		if(current->sigpending)
+			return -EINTR;
+		save_flags_cli(flags);
+	}
+
+	/* The following logic stolen from mcfserial.c */
+	save_flags(flags);
+	while(1)
+	{
+		int c;
+
+		cli();
+
+		/* How much can we write into the buffer? */
+		c=MIN(count, MIN(FSLFIFO_BUF_SIZE - fsl_fifo->tx_cnt-1,
+				 FSLFIFO_BUF_SIZE - fsl_fifo->tx_head));
+		if(c<=0)
+		{
+			restore_flags(flags);
+			break;
+		}
+
+		copy_from_user(fsl_fifo->tx_buf+fsl_fifo->tx_head, 
+				buf, c);
+
+		fsl_fifo->tx_head=(fsl_fifo->tx_head+c) & (FSLFIFO_BUF_SIZE-1);
+		fsl_fifo->tx_cnt += c;
+
+		restore_flags(flags);
+
+		do_sched_tasklet++;
+
+		buf+=c;
+		count-=c;
+		total+=c;
+	}
+
+	if(do_sched_tasklet)
+		tasklet_schedule(&fsl_write_tasklet);
+
+	return total;
+}
+
+static ssize_t fsl_read(struct file *f, char *buf, 
+				size_t count, loff_t *pos)
+{
+	struct fsl_fifo_t *fsl_fifo=(struct fsl_fifo_t *)f->private_data;
+	unsigned flags;
+	int total=0;
+
+	if(!fsl_fifo->exists)
+		return -ENODEV;
+
+	save_flags_cli(flags);
+
+	/* Block until there's some data in the buffer */
+	while(!fsl_fifo->rx_cnt)
+	{
+		restore_flags(flags);
+		tasklet_schedule(&fsl_read_tasklet);
+		interruptible_sleep_on(&fsl_read_queue);
+		if(current->sigpending)
+		{
+			return -EINTR;
+		}
+		save_flags_cli(flags);
+	}
+		
+	while(1)
+	{
+		int c; 
+
+		cli();
+		c = MIN(count, MIN(fsl_fifo->rx_cnt,
+				   FSLFIFO_BUF_SIZE - fsl_fifo->rx_tail));
+
+		if(c<=0)
+		{
+			restore_flags(flags);
+			break;
+		}
+
+		copy_to_user(buf, fsl_fifo->rx_buf+fsl_fifo->rx_tail,c);
+
+		/* Update the buffer data structure */
+		fsl_fifo->rx_cnt-=c;
+		fsl_fifo->rx_tail+=c;
+		fsl_fifo->rx_tail &= FSLFIFO_BUF_SIZE-1;
+
+		restore_flags(flags);
+
+		buf += c;
+		count -= c;
+		total += c;
+	}
+
+	if(count)
+		tasklet_schedule(&fsl_read_tasklet);
+
+	return total;
+}
+
+int fsl_flush_buffers(int id)
+{
+	unsigned flags;
+
+	struct fsl_fifo_t *fsl_fifo=&fsl_fifo_table[id];
+
+	if(!fsl_fifo->exists)
+		return 0;
+
+	save_flags_cli(flags);
+	fsl_fifo->rx_cnt=fsl_fifo->rx_head=fsl_fifo->rx_tail=0;
+	fsl_fifo->tx_cnt=fsl_fifo->tx_head=fsl_fifo->tx_tail=0;
+	restore_flags(flags);
+
+	return 0;
+}
+
+static int fsl_ioctl(struct inode *inode, struct file *f,
+			unsigned int cmd, unsigned long arg)
+{
+	int fsl_id;
+	struct fsl_fifo_t *fsl_fifo;
+	unsigned flags, fsl_status;
+
+	fsl_id=FSLFIFO_ID(inode->i_rdev);
+
+	if(fsl_id >= MAX_FSLFIFO_COUNT)
+		return -ENODEV;
+
+	fsl_fifo=&fsl_fifo_table[fsl_id];
+
+	if(!fsl_fifo->exists)
+		return -ENODEV;
+
+	switch(cmd)
+	{
+	case FSLFIFO_IOCRESET:		/* Reset */
+		save_flags_cli(flags);
+		fsl_flush_buffers(fsl_id);
+		restore_flags(flags);
+		return 0;
+
+	case FSLFIFO_IOCTCONTROL:	/* Write control value */
+	/* Note this jumps the queue, and is blatted directly to the FSL
+	   port.  It does not get queued in the main SW buffer */
+		save_flags_cli(flags);
+		fsl_ncput(fsl_id, arg, fsl_status);
+		restore_flags(flags);
+		if(fsl_error(fsl_status))
+			return -EIO;
+		else if(fsl_nodata(fsl_status))
+			return -EBUSY;
+		return 0;
+
+	case FSLFIFO_IOCQCONTROL:	/* Read control value */
+	/* This bypasses the normal software buffers.  It is very unlikely
+	   to work unless those buffers are empty, and the tasklets are
+ 	   idling */
+		save_flags_cli(flags);
+		fsl_ncget(fsl_id, arg, fsl_status);
+		restore_flags(flags);
+		if(fsl_error(fsl_status))	/* Non-control value from FSL */
+			return -EIO;	
+		else if(fsl_nodata(fsl_status))	/* Nothing from FSL */
+			return -EBUSY;	
+		return arg;
+		
+	case FSLFIFO_IOCTWIDTH:		/* set data width */
+		if(arg==1 || arg==2 || arg==4)
+		{
+			save_flags_cli(flags);
+			fsl_flush_buffers(fsl_id);
+			fsl_fifo->width=arg;
+			return 0;
+		}
+		else
+			return -EINVAL;
+
+	case FSLFIFO_IOCQWIDTH:		/* get data width */
+		return fsl_fifo->width;
+
+	default:			/* bleugh */
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int fsl_open(struct inode *inode, struct file *f)
+{
+	int fsl_id;
+	struct fsl_fifo_t *fsl_fifo;
+
+	fsl_id=FSLFIFO_ID(inode->i_rdev);
+
+	if(fsl_id >= MAX_FSLFIFO_COUNT)
+		return -ENODEV;
+
+	fsl_fifo=&fsl_fifo_table[fsl_id];
+
+	if(!fsl_fifo->exists)
+		return -ENODEV;
+
+	MOD_INC_USE_COUNT;
+	
+	/* Set the file's private data to be the fsl_fifo descriptor*/
+	if(!f->private_data)
+		f->private_data=(void *)fsl_fifo;
+
+	return 0;
+}
+
+static int fsl_release(struct inode *inode, struct file *f)
+{
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static int __init init_fsl_fifo_devices(void)
+{
+	int i;
+	int rtn;
+
+/* This is horrible.  In fact, the whole static table thing is horrible. */
+#ifdef CONFIG_MICROBLAZE_FSLFIFO0
+	fsl_fifo_table[0].exists=1;
+#endif
+#ifdef CONFIG_MICROBLAZE_FSLFIFO1
+	fsl_fifo_table[1].exists=1;
+#endif
+#ifdef CONFIG_MICROBLAZE_FSLFIFO2
+	fsl_fifo_table[2].exists=1;
+#endif
+#ifdef CONFIG_MICROBLAZE_FSLFIFO3
+	fsl_fifo_table[3].exists=1;
+#endif
+#ifdef CONFIG_MICROBLAZE_FSLFIFO4
+	fsl_fifo_table[4].exists=1;
+#endif
+#ifdef CONFIG_MICROBLAZE_FSLFIFO5
+	fsl_fifo_table[5].exists=1;
+#endif
+#ifdef CONFIG_MICROBLAZE_FSLFIFO6
+	fsl_fifo_table[6].exists=1;
+#endif
+#ifdef CONFIG_MICROBLAZE_FSLFIFO7
+	fsl_fifo_table[7].exists=1;
+#endif
+
+	printk("Microblaze FSL FIFO Driver. ");
+	printk("John Williams <jwilliams@itee.uq.edu.au>\n");
+	for(i=0;i<MAX_FSLFIFO_COUNT;i++)
+	{
+		struct fsl_fifo_t *fsl_fifo=&fsl_fifo_table[i];
+		if(!fsl_fifo->exists)
+			continue;
+
+		fsl_miscdev[i].minor=FSLFIFO_MINOR(i);
+		fsl_miscdev[i].name="data";
+		fsl_miscdev[i].fops=&fsl_fops;
+
+		if((rtn=misc_register(&fsl_miscdev[i])))
+		{
+			printk("Error registering fslfifo[%i]\n",i);
+			continue;
+			/* return rtn; */
+		}
+
+		fsl_fifo->id=i;
+		fsl_fifo->width=4;	/* Assume word-wide FSL channel */
+		fsl_fifo->tx_cnt=0;
+		fsl_fifo->tx_head=0;
+		fsl_fifo->tx_tail=0;
+	
+		fsl_fifo->rx_cnt=0;
+		fsl_fifo->rx_head=0;
+		fsl_fifo->rx_tail=0;
+	
+		printk(KERN_INFO "FSL FIFO[%i] initialised\n",i);
+	}
+
+	return 0;
+}
+
+static int __init fsl_fifo_init(void)
+{
+	int rtn = init_fsl_fifo_devices();
+
+	if(!rtn)
+		return 0;
+	else
+	{
+		printk(KERN_INFO "Error registering PicoFIFO devices\n");
+		return -ENODEV;
+	}
+}
+
+static void __exit fsl_fifo_cleanup(void)
+{
+	int i;
+
+	for(i=0;i<MAX_FSLFIFO_COUNT;i++)
+		if(fsl_fifo_table[i].exists)
+			misc_deregister(&fsl_miscdev[i]);
+}
+
+EXPORT_NO_SYMBOLS;
+
+module_init(fsl_fifo_init);
+module_exit(fsl_fifo_cleanup);
+
diff -urN linux-2.4.29/drivers/misc/fslfifo/fslfifo.h linux-2.4.29-uc1/drivers/misc/fslfifo/fslfifo.h
--- linux-2.4.29/drivers/misc/fslfifo/fslfifo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/misc/fslfifo/fslfifo.h	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ * fslfifo.h -- FSL FIFO driver for Microblaze
+ *
+ * Copyright (C) 2004 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *       
+ */
+
+#ifndef _FSLFIFO_H
+#define _FSLFIFO_H
+
+#include <linux/miscdevice.h>
+#include <linux/major.h>
+
+/* Maximum number of FSL FIFOs */
+#define MAX_FSLFIFO_COUNT 8
+
+/* FSL fifo data channels are misc devices (major-10)
+   minor channel is base+fsl_num (eg 192--199) */
+#define FSLFIFO_MINOR_BASE 192
+
+#define FSLFIFO_MINOR(id) (FSLFIFO_MINOR_BASE | ((id)&0x7))
+
+/* Return a dev->device code for a given fsl channel*/
+#define FSLFIFO(id) MKDEV(MISC_MAJOR, FSLFIFO_MINOR(id))
+
+/* Compute an fsl fifo ID from a device number */
+#define FSLFIFO_ID(dev) (MINOR(dev) & ~FSLFIFO_MINOR_BASE)
+
+#define FSLFIFO_BUF_SIZE 2048
+
+struct fsl_fifo_t {
+	int id;				/* Which FSL port */
+	int exists;			/* Is there something on the end? */
+	int width;			/* Data width in bytes (1,2,4) */
+	char tx_buf[FSLFIFO_BUF_SIZE]; /* TX buffer */
+	int tx_head, tx_tail;		/* TX buffer accounting */
+	int tx_cnt;
+
+	char rx_buf[FSLFIFO_BUF_SIZE];	/* RX buffer */
+	int rx_head, rx_tail;		/* RX buffer accounting */
+	int rx_cnt;
+};
+
+#endif
+
diff -urN linux-2.4.29/drivers/misc/fslfifo/Makefile linux-2.4.29-uc1/drivers/misc/fslfifo/Makefile
--- linux-2.4.29/drivers/misc/fslfifo/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/misc/fslfifo/Makefile	2005-06-14 02:12:16.000000000 +0100
@@ -0,0 +1,13 @@
+#
+# Makefile for JWs FSL FIFO device
+#
+
+EXTRA_CFLAGS		+= 
+
+# the kernel interface 
+fslfifo-objs 		+= fslfifo.o
+
+obj-$(CONFIG_MICROBLAZE_FSLFIFO) := fslfifo.o
+
+include $(TOPDIR)/Rules.make
+
diff -urN linux-2.4.29/drivers/misc/Makefile linux-2.4.29-uc1/drivers/misc/Makefile
--- linux-2.4.29/drivers/misc/Makefile	2000-12-29 22:07:22.000000000 +0000
+++ linux-2.4.29-uc1/drivers/misc/Makefile	2005-06-14 02:12:16.000000000 +0100
@@ -11,6 +11,11 @@
 
 O_TARGET := misc.o
 
+
+mod-subdirs	+=	fslfifo
+subdir-$(CONFIG_MICROBLAZE_FSLFIFO) += fslfifo
+obj-$(CONFIG_MICROBLAZE_FSLFIFO) += fslfifo/fslfifo.o
+
 include $(TOPDIR)/Rules.make
 
 fastdep:
diff -urN linux-2.4.29/drivers/mtd/chips/amd_flash.c linux-2.4.29-uc1/drivers/mtd/chips/amd_flash.c
--- linux-2.4.29/drivers/mtd/chips/amd_flash.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/chips/amd_flash.c	2005-06-14 02:12:08.000000000 +0100
@@ -67,6 +67,8 @@
 #define AM29LV160DB	0x2249
 #define AM29BDS323D     0x22D1
 #define AM29BDS643D	0x227E
+#define AM29LV004T	0x00B5
+#define AM29LV004B	0x00B6
 
 /* Atmel */
 #define AT49xV16x	0x00C0
@@ -430,6 +432,30 @@
 	const struct amd_flash_info table[] = {
 	{
 		mfr_id: MANUFACTURER_AMD,
+                dev_id: AM29LV004T,
+                name: "AMD AM29LV004T",
+                size: 0x00080000,
+                numeraseregions: 4,
+                regions: {
+                        { offset: 0x000000, erasesize: 0x10000, numblocks:  7 },
+                        { offset: 0x070000, erasesize: 0x08000, numblocks:  1 },
+                        { offset: 0x078000, erasesize: 0x02000, numblocks:  2 },
+                        { offset: 0x07C000, erasesize: 0x04000, numblocks:  1 }
+                }
+        }, {
+                mfr_id: MANUFACTURER_AMD,
+                dev_id: AM29LV004B,
+                name: "AMD AM29LV004B",
+                size: 0x00080000,
+                numeraseregions: 4,
+                regions: {
+                        { offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
+                        { offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
+                        { offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
+                        { offset: 0x010000, erasesize: 0x10000, numblocks:  7 }
+                }
+        }, {
+		mfr_id: MANUFACTURER_AMD,
 		dev_id: AM29LV160DT,
 		name: "AMD AM29LV160DT",
 		size: 0x00200000,
diff -urN linux-2.4.29/drivers/mtd/chips/cfi_cmdset_0002.c linux-2.4.29-uc1/drivers/mtd/chips/cfi_cmdset_0002.c
--- linux-2.4.29/drivers/mtd/chips/cfi_cmdset_0002.c	2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.29-uc1/drivers/mtd/chips/cfi_cmdset_0002.c	2005-06-14 02:12:08.000000000 +0100
@@ -18,6 +18,7 @@
 #include <linux/sched.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
+#include <asm/unaligned.h>
 
 #include <linux/errno.h>
 #include <linux/slab.h>
@@ -510,13 +511,18 @@
 	   or tells us why it failed. */        
 	dq6 = CMD(1<<6);
 	dq5 = CMD(1<<5);
-	timeo = jiffies + (HZ/1000); /* setting timeout to 1ms for now */
+	timeo = jiffies + HZ; /* setting timeout to 1s for safety */
 		
 	oldstatus = cfi_read(map, adr);
 	status = cfi_read(map, adr);
 
-	while( (status & dq6) != (oldstatus & dq6) && 
-	       (status & dq5) != dq5 &&
+	/*
+	 * some toshiba flash acts weird with the toggle bits, so
+	 * we check the datum as well
+	 */
+	while( (status != datum ||
+	           ((status & dq6) != (oldstatus & dq6) && 
+	           (status & dq5) != dq5)) &&
 	       !time_after(jiffies, timeo) ) {
 
 		if (need_resched()) {
@@ -540,7 +546,9 @@
 			status = cfi_read(map, adr);
 		    
 			if ( (oldstatus & 0x00FF) == (status & 0x00FF) ) {
+#ifndef CONFIG_MTD_SNAPGEODE
 				printk(KERN_WARNING "Warning: DQ5 raised while program operation was in progress, however operation completed OK\n" );
+#endif
 			} else { 
 				/* DQ5 is active so we can do a reset and stop the erase */
 				cfi_write(map, CMD(0xF0), chip->start);
@@ -632,9 +640,9 @@
 		if (cfi_buswidth_is_1()) {
 			datum = *(__u8*)buf;
 		} else if (cfi_buswidth_is_2()) {
-			datum = *(__u16*)buf;
+			datum = get_unaligned((__u16*)buf);
 		} else if (cfi_buswidth_is_4()) {
-			datum = *(__u32*)buf;
+			datum = get_unaligned((__u32*)buf);
 		} else {
 			return -EINVAL;
 		}
diff -urN linux-2.4.29/drivers/mtd/chips/cfi_probe.c linux-2.4.29-uc1/drivers/mtd/chips/cfi_probe.c
--- linux-2.4.29/drivers/mtd/chips/cfi_probe.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/chips/cfi_probe.c	2005-06-14 02:12:08.000000000 +0100
@@ -43,10 +43,11 @@
 	    cfi_read(map,base+osf*0x11)==cfi_build_cmd('R',map,cfi) &&
 	    cfi_read(map,base+osf*0x12)==cfi_build_cmd('Y',map,cfi))
 		return 1;	// ok !
-
+	
 	return 0; 	// nothing found
 }
 
+
 static int cfi_probe_chip(struct map_info *map, __u32 base,
 			  struct flchip *chips, struct cfi_private *cfi)
 {
diff -urN linux-2.4.29/drivers/mtd/chips/Config.in linux-2.4.29-uc1/drivers/mtd/chips/Config.in
--- linux-2.4.29/drivers/mtd/chips/Config.in	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/chips/Config.in	2005-06-14 02:12:08.000000000 +0100
@@ -1,6 +1,6 @@
 # drivers/mtd/chips/Config.in
 
-# $Id: Config.in,v 1.16 2002/09/03 13:30:43 joern Exp $
+# $Id: Config.in,v 1.1.1.1 2003/10/24 09:52:18 bas Exp $
 
 mainmenu_option next_comment
 
@@ -54,6 +54,7 @@
 dep_tristate '  AMD compatible flash chip support (non-CFI)' CONFIG_MTD_AMDSTD $CONFIG_MTD $CONFIG_MTD_OBSOLETE_CHIPS
 dep_tristate '  pre-CFI Sharp chip support' CONFIG_MTD_SHARP $CONFIG_MTD $CONFIG_MTD_OBSOLETE_CHIPS
 dep_tristate '  JEDEC device support' CONFIG_MTD_JEDEC $CONFIG_MTD $CONFIG_MTD_OBSOLETE_CHIPS
+dep_tristate '  ST PSD4256G compatible flash chip support' CONFIG_MTD_PSD4256G $CONFIG_MTD $CONFIG_MTD_OBSOLETE_CHIPS
 
 
 endmenu
diff -urN linux-2.4.29/drivers/mtd/chips/jedec_probe.c linux-2.4.29-uc1/drivers/mtd/chips/jedec_probe.c
--- linux-2.4.29/drivers/mtd/chips/jedec_probe.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/chips/jedec_probe.c	2005-06-14 02:12:08.000000000 +0100
@@ -44,6 +44,10 @@
 #define AM29F040	0x00A4
 #define AM29LV040B	0x004F
 #define AM29F032B	0x0041
+#define AM29LV004T	0x00B5
+#define AM29LV004B	0x00B6
+#define AM29LV320DT	0x22F6
+#define AM29LV320DB	0x22F9
 
 /* Atmel */
 #define AT49BV512	0x0003
@@ -110,6 +114,7 @@
 #define SST39LF040	0x00D7
 #define SST39SF010A	0x00B5
 #define SST39SF020A	0x00B6
+#define SST49LF020A	0x0061
 #define SST49LF030A	0x001C
 #define SST49LF040A	0x0051
 #define SST49LF080A	0x005B
@@ -126,6 +131,7 @@
 struct amd_flash_info {
 	const __u16 mfr_id;
 	const __u16 dev_id;
+	const __u16 extra_id;
 	const char *name;
 	const int DevSize;
 	const int InterfaceDesc;
@@ -148,6 +154,30 @@
 static const struct amd_flash_info jedec_table[] = {
 	{
 		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV004T,
+		name: "AMD AM29LV004T",
+		DevSize: SIZE_512KiB,
+		CmdSet:	P_ID_AMD_STD,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,7),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV004B,
+		name: "AMD AM29LV004B",
+		DevSize: SIZE_512KiB,
+		CmdSet:	P_ID_AMD_STD,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x04000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x10000,7)
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
 		dev_id: AM29F032B,
 		name: "AMD AM29F032B",
 		DevSize: SIZE_4MiB,
@@ -157,6 +187,26 @@
 		}
 	}, {
 		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV320DT,
+		name: "AMD AM29LV320DT",
+		DevSize: SIZE_4MiB,
+		CmdSet:	P_ID_AMD_STD,
+		NumEraseRegions: 2,
+		regions: {ERASEINFO(0x02000,8),
+			  ERASEINFO(0x10000,63)
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV320DB,
+		name: "AMD AM29LV320DB",
+		DevSize: SIZE_4MiB,
+		CmdSet:	P_ID_AMD_STD,
+		NumEraseRegions: 2,
+		regions: {ERASEINFO(0x10000,63),
+			  ERASEINFO(0x02000,8)
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
 		dev_id: AM29LV160DT,
 		name: "AMD AM29LV160DT",
 		DevSize: SIZE_2MiB,
@@ -671,6 +721,7 @@
 	}, {
 		mfr_id: MANUFACTURER_ATMEL,
 		dev_id: AT49BV16X,
+		extra_id: 8,			/* always place before devices with undefined extra_id !! */
 		name: "Atmel AT49BV16X",
 		DevSize: SIZE_2MiB,
 		CmdSet: P_ID_AMD_STD,
@@ -681,6 +732,7 @@
 	}, {
 		mfr_id: MANUFACTURER_ATMEL,
 		dev_id: AT49BV16XT,
+		extra_id: 8,			/* always place before devices with undefined extra_id !! */
 		name: "Atmel AT49BV16XT",
 		DevSize: SIZE_2MiB,
 		CmdSet: P_ID_AMD_STD,
@@ -688,6 +740,50 @@
 		regions: {ERASEINFO(0x10000,31),
 			  ERASEINFO(0x02000,8)
 		}
+        }, {
+                mfr_id: MANUFACTURER_ATMEL,
+                dev_id: AT49BV16X,
+                extra_id: 0xc8,                 /* always place before devices with undefined extra_id !! */
+                name: "Atmel AT49BV16X4A",
+                DevSize: SIZE_2MiB,
+                CmdSet: P_ID_AMD_STD,
+                NumEraseRegions: 2,
+                regions: {ERASEINFO(0x02000,8),
+                          ERASEINFO(0x10000,31)
+                }
+        }, {
+                mfr_id: MANUFACTURER_ATMEL,
+                dev_id: AT49BV16XT,
+                extra_id: 0xc8,                 /* always place before devices with undefined extra_id !! */
+                name: "Atmel AT49BV16X4AT",
+                DevSize: SIZE_2MiB,
+                CmdSet: P_ID_AMD_STD,
+                NumEraseRegions: 2,
+                regions: {ERASEINFO(0x10000,31),
+                          ERASEINFO(0x02000,8)
+                }
+	}, {
+		mfr_id: MANUFACTURER_ATMEL,
+		dev_id: AT49BV16X,
+		name: "Atmel AT49BV16X4",
+		DevSize: SIZE_2MiB,
+		CmdSet: P_ID_AMD_STD,
+		NumEraseRegions: 3,
+		regions: {ERASEINFO(0x02000,8),
+			  ERASEINFO(0x08000,2),
+			  ERASEINFO(0x10000,30)
+		}
+	}, {
+                mfr_id: MANUFACTURER_ATMEL,
+                dev_id: AT49BV16XT,
+                name: "Atmel AT49BV16X4T",
+                DevSize: SIZE_2MiB,
+		CmdSet: P_ID_AMD_STD,
+                NumEraseRegions: 3,
+                regions: {ERASEINFO(0x10000,30),
+                          ERASEINFO(0x08000,2),
+			  ERASEINFO(0x02000,8)
+                }
 	}, {
 		mfr_id: MANUFACTURER_ATMEL,
 		dev_id: AT49BV32X,
@@ -875,6 +971,15 @@
 		}
 	}, {
 		mfr_id: MANUFACTURER_SST,
+		dev_id: SST49LF020A,
+		name: "SST 49LF020A",
+		DevSize: SIZE_256KiB,
+		CmdSet: P_ID_AMD_STD,
+		NumEraseRegions: 1,
+		regions: {ERASEINFO(0x01000,64),
+		}
+	}, {
+		mfr_id: MANUFACTURER_SST,
 		dev_id: SST49LF030A,
 		name: "SST 49LF030A",
 		DevSize: SIZE_512KiB,
@@ -900,7 +1005,18 @@
 		NumEraseRegions: 1,
 		regions: {ERASEINFO(0x01000,256),
 		}
-	} 
+	}, {
+		mfr_id: MANUFACTURER_SST,
+		dev_id: SST39LF160,
+		name: "SST 39LF/VF160",
+		DevSize: SIZE_2MiB,
+		CmdSet: P_ID_AMD_STD,
+		NumEraseRegions: 2,
+    /* Split into two regions to get around the 256-region restriction */
+		regions: {ERASEINFO(0x01000,256),
+			  ERASEINFO(0x01000,256),
+		}
+ }
 };
 
 
@@ -911,22 +1027,16 @@
 
 struct mtd_info *jedec_probe(struct map_info *map);
 
-static inline u32 jedec_read_mfr(struct map_info *map, __u32 base, 
-	struct cfi_private *cfi)
-{
-	u32 result, mask;
-	mask = (1 << (cfi->device_type * 8)) -1;
-	result = cfi_read(map, base);
-	result &= mask;
-	return result;
-}
+#define MFR_ID 0
+#define DEV_ID 1
+#define EXTRA_ID 3
 
 static inline u32 jedec_read_id(struct map_info *map, __u32 base, 
-	struct cfi_private *cfi)
+	struct cfi_private *cfi,int addr)
 {
 	int osf;
 	u32 result, mask;
-	osf = cfi->interleave *cfi->device_type;
+	osf = cfi->interleave *cfi->device_type * addr;
 	mask = (1 << (cfi->device_type * 8)) -1;
 	result = cfi_read(map, base + osf);
 	result &= mask;
@@ -978,8 +1088,16 @@
 			      struct flchip *chips, struct cfi_private *cfi)
 {
 	int i;
+	int busmask;
 	int unlockpass = 0;
 
+	switch(map->buswidth) {
+	case 1:  busmask = 0xff; break;
+	case 2:  busmask = 0xffff; break;
+	case 4:  busmask = 0xffffffff; break;
+	default: printk("Unknown buswidth in jedec_probe_chip\n"); return(0);
+	}
+
 	if (!cfi->numchips) {
 		switch (cfi->device_type) {
 		case CFI_DEVICETYPE_X8:
@@ -1043,13 +1161,22 @@
 		/* This is the first time we're called. Set up the CFI 
 		   stuff accordingly and return */
 		
-		cfi->mfr = jedec_read_mfr(map, base, cfi);
-		cfi->id = jedec_read_id(map, base, cfi);
+		cfi->mfr = jedec_read_id(map, base, cfi, MFR_ID);
+		cfi->id = jedec_read_id(map, base, cfi, DEV_ID);
+		/* this is the third id that is available in some
+   		 * devices. If it is not used, it is set to 0 later. 
+		 */
+		cfi->extra=jedec_read_id(map, base, cfi, EXTRA_ID);
+
 		printk(KERN_INFO "Search for id:(%02x %02x) interleave(%d) type(%d)\n", 
 			cfi->mfr, cfi->id, cfi->interleave, cfi->device_type);
 		for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) {
-			if (cfi->mfr == jedec_table[i].mfr_id &&
-			    cfi->id == jedec_table[i].dev_id) {
+			if (cfi->mfr == (jedec_table[i].mfr_id&busmask) &&
+			    cfi->id == (jedec_table[i].dev_id&busmask) &&
+			    (!jedec_table[i].extra_id || cfi->extra == (jedec_table[i].extra_id&busmask))) {
+				
+				if (!jedec_table[i].extra_id) cfi->extra=0; /*don't check*/ 
+
 				if (!cfi_jedec_setup(cfi, i))
 					return 0;
 				goto ok_out;
@@ -1068,12 +1195,17 @@
 	} else {
 		__u16 mfr;
 		__u16 id;
+		__u16 extra;
+
+
 
 		/* Make sure it is a chip of the same manufacturer and id */
-		mfr = jedec_read_mfr(map, base, cfi);
-		id = jedec_read_id(map, base, cfi);
+		mfr = jedec_read_id(map, base, cfi,MFR_ID);
+		id = jedec_read_id(map, base, cfi,DEV_ID);
+		extra = jedec_read_id(map, base, cfi,EXTRA_ID);
 
-		if ((mfr != cfi->mfr) || (id != cfi->id)) {
+		if ((mfr != cfi->mfr) || (id != cfi->id) ||
+			 (cfi->extra && extra != cfi->extra)) {
 			printk(KERN_DEBUG "%s: Found different chip or no chip at all (mfr 0x%x, id 0x%x) at 0x%x\n",
 			       map->name, mfr, id, base);
 			jedec_reset(base, map, cfi);
@@ -1085,15 +1217,17 @@
 	for (i=0; i<cfi->numchips; i++) {
 		/* This chip should be in read mode if it's one
 		   we've already touched. */
-		if (jedec_read_mfr(map, chips[i].start, cfi) == cfi->mfr &&
-		    jedec_read_id(map, chips[i].start, cfi) == cfi->id) {
+		if (jedec_read_id(map, chips[i].start, cfi,MFR_ID) == cfi->mfr &&
+		    jedec_read_id(map, chips[i].start, cfi,DEV_ID) == cfi->id &&
+		    (!cfi->extra || jedec_read_id(map, chips[i].start, cfi,EXTRA_ID)==cfi->extra)) {
 			/* Eep. This chip also looks like it's in autoselect mode.
 			   Is it an alias for the new one? */
 			jedec_reset(chips[i].start, map, cfi);
 
 			/* If the device IDs go away, it's an alias */
-			if (jedec_read_mfr(map, base, cfi) != cfi->mfr ||
-			    jedec_read_id(map, base, cfi) != cfi->id) {
+			if (jedec_read_id(map, base, cfi,MFR_ID) != cfi->mfr ||
+			    jedec_read_id(map, base, cfi,DEV_ID) != cfi->id ||
+			    (cfi->extra && jedec_read_id(map, base, cfi,EXTRA_ID) != cfi->extra)) {
 				printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
 				       map->name, base, chips[i].start);
 				return 0;
@@ -1104,8 +1238,9 @@
 			 * too and if it's the same, assume it's an alias. */
 			/* FIXME: Use other modes to do a proper check */
 			jedec_reset(base, map, cfi);
-			if (jedec_read_mfr(map, base, cfi) == cfi->mfr &&
-			    jedec_read_id(map, base, cfi) == cfi->id) {
+			if (jedec_read_id(map, base, cfi,MFR_ID) == cfi->mfr &&
+			    jedec_read_id(map, base, cfi,DEV_ID) == cfi->id&&
+		    	   (!cfi->extra || jedec_read_id(map, base, cfi,EXTRA_ID)==cfi->extra)) {
 				printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
 				       map->name, base, chips[i].start);
 				return 0;
diff -urN linux-2.4.29/drivers/mtd/chips/Makefile linux-2.4.29-uc1/drivers/mtd/chips/Makefile
--- linux-2.4.29/drivers/mtd/chips/Makefile	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/chips/Makefile	2005-06-14 02:12:08.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # linux/drivers/chips/Makefile
 #
-# $Id: Makefile,v 1.8 2002/01/10 20:27:40 eric Exp $
+# $Id: Makefile,v 1.1.1.1 2003/10/24 09:52:18 bas Exp $
 
 O_TARGET	:= chipslink.o
 
@@ -16,6 +16,7 @@
 
 obj-$(CONFIG_MTD)		+= chipreg.o
 obj-$(CONFIG_MTD_AMDSTD)	+= amd_flash.o 
+obj-$(CONFIG_MTD_PSD4256G)	+= stm_flash.o
 obj-$(CONFIG_MTD_CFI)		+= cfi_probe.o
 obj-$(CONFIG_MTD_CFI_STAA)	+= cfi_cmdset_0020.o
 obj-$(CONFIG_MTD_CFI_AMDSTD)	+= cfi_cmdset_0002.o
diff -urN linux-2.4.29/drivers/mtd/chips/map_ram.c linux-2.4.29-uc1/drivers/mtd/chips/map_ram.c
--- linux-2.4.29/drivers/mtd/chips/map_ram.c	2001-10-04 23:14:59.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/chips/map_ram.c	2005-06-14 02:12:08.000000000 +0100
@@ -34,6 +34,11 @@
 
 	/* Check the first byte is RAM */
 #if 0
+	/*
+	 * enabling this code will corrupt the first and last byte of memory
+	 * in the area.  This is particularly bad if you have pre-loaded
+	 * something useful into the area (like a rom filesystem)
+	 */
 	map->write8(map, 0x55, 0);
 	if (map->read8(map, 0) != 0x55)
 		return NULL;
diff -urN linux-2.4.29/drivers/mtd/chips/stm_flash.c linux-2.4.29-uc1/drivers/mtd/chips/stm_flash.c
--- linux-2.4.29/drivers/mtd/chips/stm_flash.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/chips/stm_flash.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,930 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/flashchip.h>
+
+#define MAX_SMT_CHIPS 8
+
+#define DEVICE_TYPE_X8  (8 / 8)
+#define DEVICE_TYPE_X16 (16 / 8)
+#define DEVICE_TYPE_X32 (32 / 8)
+
+/* Addresses */
+#define ADDR_MANUFACTURER		0x0000
+#define ADDR_DEVICE_ID			0x0002
+#define ADDR_UNLOCK_1			0x0AAA
+#define ADDR_UNLOCK_2			0x0554
+
+/* Commands */
+#define CMD_UNLOCK_DATA_1		0x00aa
+#define CMD_UNLOCK_DATA_2		0x0055
+#define CMD_MANUFACTURER_UNLOCK_DATA	0x0090
+#define CMD_PROGRAM_UNLOCK_DATA		0x00A0
+#define CMD_RESET_DATA			0x00F0
+#define CMD_SECTOR_ERASE_UNLOCK_DATA	0x0080
+#define CMD_SECTOR_ERASE_UNLOCK_DATA_2	0x0030
+
+#define D6_MASK 0x40
+
+struct stm_flash_private {
+	int device_type;
+	int interleave;
+	int numchips;
+	unsigned long chipshift;
+	struct flchip chips[0];
+};
+
+struct stm_flash_info {
+	const __u16 mfr_id;
+	const __u16 dev_id;
+	const char *name;
+	const u_long size;
+	const int numeraseregions;
+	const struct mtd_erase_region_info regions[4];
+};
+
+static int stm_flash_read(struct mtd_info *, loff_t, size_t, size_t *, unsigned char *);
+static int stm_flash_write(struct mtd_info *, loff_t, size_t, size_t *, const unsigned char *);
+static void stm_flash_sync(struct mtd_info *);
+static int stm_flash_erase(struct mtd_info *, struct erase_info *);
+static void stm_flash_destroy(struct mtd_info*);
+static struct mtd_info* stm_flash_probe(struct map_info *);
+static int stm_flash_suspend(struct mtd_info *mtd);
+static void stm_flash_resume(struct mtd_info *mtd);
+
+static struct mtd_chip_driver stm_flash_chipdrv = {
+	probe:		stm_flash_probe,
+	destroy:	stm_flash_destroy,
+	name:		"stm_flash",
+	module:		THIS_MODULE
+};
+
+static const char im_name[] = "stm_flash";
+
+static void send_unlock(struct map_info *map, unsigned long base)
+{
+	map->write16(map, CMD_UNLOCK_DATA_1, base + ADDR_UNLOCK_1);
+	map->write16(map, CMD_UNLOCK_DATA_2, base + ADDR_UNLOCK_2);
+}
+
+static void send_cmd(struct map_info *map, unsigned long base, 
+		     unsigned long cmd)
+{
+	send_unlock(map, base);
+	map->write16(map, cmd, base + ADDR_UNLOCK_1);
+}
+
+static void send_cmd_to_addr(struct map_info *map, unsigned long base, 
+			     unsigned long cmd, unsigned long addr)
+{
+	send_unlock(map, base);
+	map->write16(map, cmd, addr);
+}
+
+static int probe_new_chip(struct mtd_info *mtd, __u32 base, 
+			  struct flchip *chips,
+			  struct stm_flash_private *private,
+			  const struct stm_flash_info *table,
+			  int table_size)
+{
+	__u32 mfr_id, dev_id;
+	struct map_info *map = mtd->priv;
+	struct stm_flash_private temp;
+	int i;
+
+	temp.device_type = DEVICE_TYPE_X16;
+	temp.interleave = 1;
+	map->fldrv_priv = &temp;
+
+	/* Enter autoselect mode. */
+	send_cmd(map, base, CMD_RESET_DATA);
+	send_cmd(map, base, CMD_MANUFACTURER_UNLOCK_DATA);
+
+	mfr_id = map->read16(map, base + ADDR_MANUFACTURER) & 0x00FF;
+	dev_id = map->read16(map, base + ADDR_DEVICE_ID) & 0x00FF;
+
+	for (i = 0; i < table_size; i++)
+	{
+		if ((mfr_id == table[i].mfr_id) &&
+		    (dev_id == table[i].dev_id))
+		{
+			if (chips)
+			{
+				int j;
+
+				for (j = 0; j < private->numchips; j++)
+				{
+					if ((map->read16(map, chips[j].start +
+							ADDR_MANUFACTURER)
+						== mfr_id) &&
+					    (map->read16(map, chips[j].start +
+							 ADDR_DEVICE_ID)
+						== dev_id))
+					{
+						/* Exit autoselect mode */
+						send_cmd(map, base, CMD_RESET_DATA);
+						return -1;
+					}
+				}
+
+				if (private->numchips == MAX_SMT_CHIPS)
+				{
+					printk(KERN_WARNING "%s: Too many "
+						"flash chips detected. "
+						"Increase MAX_SMT_CHIPS "
+						"from %d.\n", map->name,
+						MAX_SMT_CHIPS);
+					return -1;
+				}
+
+				chips[private->numchips].start = base;
+				chips[private->numchips].state = FL_READY;
+				chips[private->numchips].mutex =
+					&chips[private->numchips]._spinlock;
+				private->numchips++;
+			}
+			printk("%s: Found %d x %ldMiB %s at 0x%08x\n",
+				map->name, temp.interleave, 
+				(table[i].size)/(1024*1024),
+				table[i].name, base);
+			
+			mtd->size += table[i].size * temp.interleave;
+			mtd->numeraseregions += table[i].numeraseregions;
+
+			break;
+		}
+	}
+
+	/* Exit autoselect mode. */
+	send_cmd(map, base, CMD_RESET_DATA);
+
+	if (i == table_size)
+	{
+		printk(KERN_DEBUG "%s: unknown flash device at 0x%08x, "
+			"mfr id 0x%02x, dev_id 0x%02x\n", map->name,
+			base, mfr_id, dev_id);
+		map->fldrv_priv = NULL;
+
+		return -1;
+	}
+
+	private->device_type = temp.device_type;
+	private->interleave = temp.interleave;
+
+	return i;
+}
+
+static struct mtd_info* stm_flash_probe(struct map_info *map)
+{
+	const struct stm_flash_info table[] = {
+	{
+		mfr_id: 0x20,
+		dev_id: 0xe9,
+		name: "ST PSD4256G",
+		size: 0x00100000,
+		numeraseregions: 1,
+		regions: {
+		  { offset: 0x000000, erasesize: 0x10000, numblocks: 16 }, 
+		}
+	}
+	};
+	struct mtd_info *mtd;
+	struct flchip chips[MAX_SMT_CHIPS];
+	int table_pos[MAX_SMT_CHIPS];
+	struct stm_flash_private temp;
+	struct stm_flash_private *private;
+	unsigned long base;
+	unsigned long size;
+	int i;
+	int offset, reg_idx;
+
+	mtd = (struct mtd_info*)kmalloc(sizeof(*mtd), GFP_KERNEL);
+	if (!mtd)
+	{
+		printk(KERN_WARNING "%s: kmalloc failed for info structure\n",
+			map->name);
+		return NULL;
+	}
+	memset(mtd, 0, sizeof(*mtd));
+	mtd->priv = map;
+
+	memset(&temp, 0, sizeof(temp));
+	
+	printk("%s: Probing for SMT PSD4256G compatible flash...\n", map->name);
+	
+	if ((table_pos[0] = probe_new_chip(mtd, 0, NULL, &temp, table,
+					sizeof(table)/sizeof(table[0]))) == -1)
+	{
+		printk(KERN_WARNING 
+			"%s: Found no SMT PSD4256G compatible device at "
+			"location zero\n", map->name);
+		kfree(mtd);
+
+		return NULL;
+	}
+
+	chips[0].start = 0;
+	chips[0].state = FL_READY;
+	chips[0].mutex = &chips[0]._spinlock;
+	temp.numchips = 1;
+	for (size = mtd->size; size > 1; size >>= 1)
+		temp.chipshift++;
+
+	/* Find out if there are any more chips in the map. */
+	for (base = (1 << temp.chipshift); base < map->size;
+			base += (1 << temp.chipshift))
+	{
+		int numchips = temp.numchips;
+		table_pos[numchips] = 
+			probe_new_chip(mtd, base, chips, &temp, 
+				table, sizeof(table)/sizeof(table[0]));
+	}
+
+	mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) *
+					mtd->numeraseregions, GFP_KERNEL);
+
+	if (!mtd->eraseregions)
+	{
+		printk(KERN_WARNING "%s: Failed to allocate memory for "
+			"MTD erase region info\n", map->name);
+		kfree(mtd);
+		map->fldrv_priv = NULL;
+		return NULL;
+	}
+
+	reg_idx = 0;
+	offset = 0;
+	for (i = 0; i < temp.numchips; i++)
+	{
+		int dev_size;
+		int j;
+
+		dev_size = 0;
+		for (j = 0; j < table[table_pos[i]].numeraseregions; j++)
+		{
+			mtd->eraseregions[reg_idx].offset = offset + 
+				(table[table_pos[i]].regions[j].offset *
+				 temp.interleave);
+			mtd->eraseregions[reg_idx].erasesize =
+				table[table_pos[i]].regions[j].erasesize *
+				temp.interleave;
+			mtd->eraseregions[reg_idx].numblocks =
+				table[table_pos[i]].regions[j].numblocks;
+			if (mtd->erasesize < 
+					mtd->eraseregions[reg_idx].erasesize)
+				mtd->erasesize = 
+					mtd->eraseregions[reg_idx].erasesize;
+
+			dev_size += mtd->eraseregions[reg_idx].erasesize *
+				mtd->eraseregions[reg_idx].numblocks;
+			reg_idx++;
+		}
+		offset += dev_size;
+	}
+
+	mtd->type = MTD_NORFLASH;
+	mtd->flags = MTD_CAP_NORFLASH;
+	mtd->name = map->name;
+	mtd->erase = stm_flash_erase;
+	mtd->read = stm_flash_read;
+	mtd->write = stm_flash_write;
+	mtd->sync = stm_flash_sync;
+	mtd->suspend = stm_flash_suspend;
+	mtd->resume = stm_flash_resume;
+
+	private = kmalloc(sizeof(*private) + 
+			(sizeof(struct flchip) * temp.numchips), GFP_KERNEL);
+	if (!private) {
+		printk(KERN_WARNING
+		       "%s: kmalloc failed for private structure\n", map->name);
+		kfree(mtd);
+		map->fldrv_priv = NULL;
+		return NULL;
+	}
+	memcpy(private, &temp, sizeof(temp));
+	memcpy(private->chips, chips, 
+		sizeof(struct flchip) * private->numchips);
+	for (i = 0; i < private->numchips; i++)
+	{
+		init_waitqueue_head(&private->chips[i].wq);
+		spin_lock_init(&private->chips[i]._spinlock);
+	}
+
+	map->fldrv_priv = private;
+
+	map->fldrv = &stm_flash_chipdrv;
+	MOD_INC_USE_COUNT;
+	
+	return mtd;
+}
+
+static void stm_flash_destroy(struct mtd_info *mtd)
+{
+	struct map_info *map = mtd->priv;
+	struct stm_flash_private *private = map->fldrv_priv;
+	kfree(private);
+}
+
+static void stm_flash_sync(struct mtd_info *mtd)
+{
+	struct map_info *map = mtd->priv;
+	struct stm_flash_private *private = map->fldrv_priv;
+	int i;
+	struct flchip *chip;
+	int ret = 0;
+	DECLARE_WAITQUEUE(wait, current);
+
+	for (i = 0; !ret && (i < private->numchips); i++)
+	{
+		chip = &private->chips[i];
+
+	retry:
+		spin_lock_bh(chip->mutex);
+
+		switch (chip->state)
+		{
+		case FL_READY:
+		case FL_STATUS:
+		case FL_CFI_QUERY:
+		case FL_JEDEC_QUERY:
+			chip->oldstate = chip->state;
+			chip->state = FL_SYNCING;
+		case FL_SYNCING:
+			spin_unlock_bh(chip->mutex);
+			break;
+		default:
+			/* Not an idle state */
+			add_wait_queue(&chip->wq, &wait);
+
+			spin_unlock_bh(chip->mutex);
+
+			schedule();
+
+			remove_wait_queue(&chip->wq, &wait);
+
+			goto retry;
+		}
+	}
+
+	/* Unlock the chips again */
+	for (i--; i >= 0; i--)
+	{
+		chip = &private->chips[i];
+
+		spin_lock_bh(chip->mutex);
+
+		if (chip->state == FL_SYNCING) 
+		{
+			chip->state = chip->oldstate;
+			wake_up(&chip->wq);
+		}
+		spin_unlock_bh(chip->mutex);
+	}
+}
+
+static int read_one_chip(struct map_info *map, struct flchip *chip, 
+			loff_t addr, size_t len, unsigned char *buf)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	unsigned long timeo = jiffies + HZ;
+
+retry:
+	spin_lock_bh(chip->mutex);
+
+	if (chip->state != FL_READY)
+	{
+		printk(KERN_INFO "%s: waiting for chip to read, state = %d\n",
+			map->name, chip->state);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+
+		spin_unlock_bh(chip->mutex);
+
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+
+		if (signal_pending(current))
+			return -EINTR;
+
+		timeo = jiffies + HZ;
+
+		goto retry;
+	}
+
+	addr += chip->start;
+
+	chip->state = FL_READY;
+
+	map->copy_from(map, buf, addr, len);
+
+	wake_up(&chip->wq);
+	spin_unlock_bh(chip->mutex);
+
+	return 0;
+}
+
+static int stm_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
+			  size_t *retlen, unsigned char *buf)
+{
+	struct map_info *map = mtd->priv;
+	struct stm_flash_private *private = map->fldrv_priv;
+	unsigned long offset;
+	int chipnum;
+	int ret = 0;
+
+	if ((from + len) > mtd->size)
+	{
+		printk(KERN_WARNING "%s: read request past end of device "
+			"(0x%lx)\n", map->name, (unsigned long)from + len);
+		return -EINVAL;
+	}
+
+	/* Offset within the first chip that the first read should start. */
+	chipnum = (from >> private->chipshift);
+	offset = from - (chipnum << private->chipshift);
+
+	*retlen = 0;
+
+	while (len)
+	{
+		unsigned long this_len;
+
+		if (chipnum >= private->numchips)
+			break;
+
+		if ((len + offset -1) >> private->chipshift)
+			this_len = (1 << private->chipshift) - offset;
+		else
+			this_len = len;
+
+		ret = read_one_chip(map, &private->chips[chipnum], offset,
+				this_len, buf);
+
+		if (ret)
+			break;
+
+		*retlen += this_len;
+		len -= this_len;
+		buf += this_len;
+
+		offset = 0;
+		chipnum++;
+	}
+
+	return ret;
+}
+
+static int flash_is_busy(struct map_info *map, unsigned long addr)
+{
+	unsigned short read1, read2, toggled;
+	
+	read1 = map->read16(map, addr);
+	read2 = map->read16(map, addr);
+	toggled = read1 ^ read2;
+	toggled &= (((unsigned short)1) << 6);
+	return toggled;
+}
+
+static int write_one_word(struct map_info *map, struct flchip *chip,
+		unsigned long addr, unsigned long datum)
+{
+	unsigned long timeo = jiffies + HZ;
+	struct stm_flash_private *private = map->fldrv_priv;
+	DECLARE_WAITQUEUE(wait, current);
+	int ret = 0;
+	int times_left;
+
+retry:
+	spin_lock_bh(chip->mutex);
+
+	if (chip->state != FL_READY)
+	{
+		printk("%s: waiting for chip to write, state = %d\n",
+				map->name, chip->state);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+
+		spin_unlock_bh(chip->mutex);
+
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+		printk(KERN_INFO "%s: woke up to write\n", map->name);
+		if (signal_pending(current))
+			return -EINTR;
+
+		timeo = jiffies + HZ;
+
+		goto retry;
+	}
+
+	chip->state = FL_WRITING;
+
+	addr += chip->start;
+
+	send_cmd(map, chip->start, CMD_PROGRAM_UNLOCK_DATA);
+	map->write16(map, datum, addr);
+
+	times_left = 50000;
+	while (times_left-- && flash_is_busy(map, addr))
+	{
+		if (current->need_resched) 
+		{
+			spin_unlock_bh(chip->mutex);
+			schedule();
+			spin_lock_bh(chip->mutex);
+		}
+	}
+
+	if (!times_left)
+	{
+		printk(KERN_WARNING "%s: write to 0x%lx timed out!\n",
+				map->name, addr);
+		ret = -EIO;
+	} else {
+		unsigned long verify;
+		if ((verify = map->read16(map, addr)) != datum) 
+		{
+			printk(KERN_WARNING "%s: write to 0x%lx failed. "
+				"datum = %lx, verify = %lx\n", map->name,
+				addr, datum, verify);
+			ret = -EIO;
+		}
+	}
+	chip->state = FL_READY;
+	wake_up(&chip->wq);
+	spin_unlock_bh(chip->mutex);
+
+	return ret;
+}
+
+static int stm_flash_write(struct mtd_info *mtd, loff_t to, size_t len,
+			   size_t *retlen, const unsigned char *buf)
+{
+	struct map_info *map = mtd->priv;
+	struct stm_flash_private *private = map->fldrv_priv;
+	int ret = 0;
+	int chipnum;
+	unsigned long offset;
+	unsigned long chipstart;
+
+	*retlen = 0;
+	if (!len)
+		return 0;
+
+	chipnum = to >> private->chipshift;
+	offset = to - (chipnum << private->chipshift);
+	chipstart = private->chips[chipnum].start;
+
+	/* If it's not bus-aligned, do the first byte write. */
+	if (offset & (map->buswidth -1))
+	{
+		unsigned long bus_offset = offset & ~(map->buswidth - 1);
+		int i = offset - bus_offset;
+		int n = 0;
+		unsigned char tmp_buf[4];
+		unsigned long datum;
+
+		map->copy_from(map, tmp_buf, 
+			       bus_offset + private->chips[chipnum].start,
+			       map->buswidth);
+		while (len && i < map->buswidth)
+			tmp_buf[i++] = buf[n++], len--;
+
+		if (map->buswidth == 2)
+			datum = *(__u16*)tmp_buf;
+		else if (map->buswidth == 4)
+			datum = *(__u32*)tmp_buf;
+		else
+			return -EINVAL;
+
+		ret = write_one_word(map, &private->chips[chipnum], bus_offset,
+				datum);
+
+		if (ret)
+			return ret;
+
+		offset += n;
+		buf += n;
+		(*retlen) += n;
+
+		if (offset >> private->chipshift)
+		{
+			chipnum++;
+			offset = 0;
+			if (chipnum == private->numchips)
+				return 0;
+		}
+	}
+
+	/* We are now aligned, write as much as possible. */
+	while (len >= map->buswidth)
+	{
+		unsigned long datum;
+
+		if (map->buswidth == 1)
+			datum = *(unsigned char*)buf;
+		else if (map->buswidth == 2)
+			datum = *(unsigned short*)buf;
+		else if (map->buswidth == 4)
+			datum = *(unsigned long*)buf;
+		else
+			return -EINVAL;
+
+		ret = write_one_word(map, &private->chips[chipnum], offset, 
+				datum);
+
+		if (ret)
+			return ret;
+
+		offset += map->buswidth;
+		buf += map->buswidth;
+		(*retlen) += map->buswidth;
+		len -= map->buswidth;
+
+		if (offset >> private->chipshift)
+		{
+			chipnum++;
+			offset = 0;
+			if (chipnum == private->numchips)
+				return 0;
+			chipstart = private->chips[chipnum].start;
+		}
+	}
+
+	if (len & (map->buswidth - 1))
+	{
+		int i = 0, n = 0;
+		unsigned char tmp_buf[2];
+		unsigned long datum;
+
+		map->copy_from(map, tmp_buf, 
+				offset + private->chips[chipnum].start,
+				map->buswidth);
+
+		while (len--)
+			tmp_buf[i++] = buf[n++];
+
+		if (map->buswidth == 2)
+			datum = *(unsigned short*)tmp_buf;
+		else if (map->buswidth == 4)
+			datum = *(unsigned long*)tmp_buf;
+		else
+			return -EINVAL;
+
+		ret = write_one_word(map, &private->chips[chipnum], offset, 
+				datum);
+
+		if (ret)
+			return ret;
+
+		(*retlen) += n;
+	}
+
+	return 0;
+}
+
+static int erase_one_block(struct map_info *map, struct flchip *chip,
+			   unsigned long addr, unsigned long size)
+{
+	unsigned long timeo = jiffies + HZ;
+	struct stm_flash_private *private = map->fldrv_priv;
+	DECLARE_WAITQUEUE(wait, current);
+
+retry:
+	spin_lock_bh(chip->mutex);
+
+	if (chip->state != FL_READY)
+	{
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+
+		spin_unlock_bh(chip->mutex);
+
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+
+		if (signal_pending(current))
+			return -EINTR;
+
+		timeo = jiffies + HZ;
+
+		goto retry;
+	}
+
+	chip->state = FL_ERASING;
+
+	addr += chip->start;
+
+	send_cmd(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA);
+	send_cmd_to_addr(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA_2, addr);
+
+	timeo = jiffies + (HZ * 20);
+
+	spin_unlock_bh(chip->mutex);
+	schedule_timeout(HZ);
+	spin_lock_bh(chip->mutex);
+
+	while (flash_is_busy(map, chip->start))
+	{
+		if (chip->state != FL_ERASING)
+		{
+			/* Someone's suspended the erase. Sleep. */
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			add_wait_queue(&chip->wq, &wait);
+
+			spin_unlock_bh(chip->mutex);
+			printk(KERN_INFO "%s: erase suspended. Sleeping.\n",
+				map->name);
+			schedule();
+			remove_wait_queue(&chip->wq, &wait);
+
+			if (signal_pending(current))
+				return -EINTR;
+
+			timeo = jiffies + (HZ*2);
+			spin_lock_bh(chip->mutex);
+			continue;
+		}
+
+		/* OK Still waiting */
+		if (time_after(jiffies, timeo))
+		{
+			chip->state = FL_READY;
+			spin_unlock_bh(chip->mutex);
+			printk(KERN_WARNING "%s: waiting for erase to complete "
+				"timed out.\n", map->name);
+
+			return -EIO;
+		}
+
+		/* Latency issues. Drop the lock, wait a while, and retry. */
+		spin_unlock_bh(chip->mutex);
+
+		if (current->need_resched)
+			schedule();
+		else
+			udelay(1);
+
+		spin_lock_bh(chip->mutex);
+	}
+
+	{
+		/* Verify every single word */
+		int address;
+		int error = 0;
+		int verify;
+		
+		for (address = addr; address < (addr + size); address += 2)
+			if ((verify = map->read16(map, address)) != 0xFFFF)
+			{
+				error = 1;
+				break;
+			}
+
+		if (error)
+		{
+			chip->state = FL_READY;
+			spin_unlock_bh(chip->mutex);
+			printk(KERN_WARNING "%s: verify error at 0x%x, size "
+				"%ld.\n", map->name, address, size);
+			return -EIO;
+		}
+	}
+
+	chip->state = FL_READY;
+	wake_up(&chip->wq);
+	spin_unlock_bh(chip->mutex);
+
+	return 0;
+}
+
+static int stm_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	struct map_info *map = mtd->priv;
+	struct stm_flash_private *private = map->fldrv_priv;
+	unsigned long addr, len;
+	int chipnum;
+	int ret = 0;
+	int i, first;
+	struct mtd_erase_region_info *regions = mtd->eraseregions;
+
+	if (instr->addr > mtd->size)
+		return -EINVAL;
+
+	if ((instr->len + instr->addr) > mtd->size)
+		return -EINVAL;
+
+	/*
+	 * Check that both start and end of the requested erase are aligned
+	 * with the erasesize at the appropriate addresses.
+	 */
+	i = 0;
+
+	/*
+	 * Skip all erase regions which are ended before the start of the
+	 * requested erase. Actually, to save on the calculations, we skip
+	 * to the first erase region which starts after the start of the 
+	 * requested erase, and then go back one.
+	 */
+	while ((i < mtd->numeraseregions) &&
+	       (instr->addr >= regions[i].offset))
+		i++;
+	i--;
+
+	/*
+	 * OK. Now i is pointing at the erase region in which this erase 
+	 * request starts. Check the start of the requested erase range
+	 * is aligned with the erase size which is in effect here.
+	 */
+	if (instr->addr & (regions[i].erasesize -1))
+		return -EINVAL;
+
+	/*
+	 * Remember the erase region we start on.
+	 */
+	first = i;
+
+	/*
+	 * Next, theck that the end of the requested erase is aligned with
+	 * the erase region at that address.
+	 */
+	while ((i < mtd->numeraseregions) &&
+	       ((instr->addr + instr->len) >= regions[i].offset))
+		i++;
+	i--;
+
+	if ((instr->addr + instr->len) & (regions[i].erasesize-1))
+		return -EINVAL;
+
+	chipnum = instr->addr >> private->chipshift;
+	addr = instr->addr - (chipnum << private->chipshift);
+	len = instr->len;
+
+	i = first;
+
+	while (len)
+	{
+		ret = erase_one_block(map, &private->chips[chipnum], addr,
+				regions[i].erasesize);
+
+		if (ret)
+			return ret;
+
+		addr += regions[i].erasesize;
+		len -= regions[i].erasesize;
+
+		if ((addr % (1 << private->chipshift)) ==
+		    ((regions[i].offset + (regions[i].erasesize *
+					   regions[i].numblocks))
+		     % (1 << private->chipshift)))
+			i++;
+
+		if (addr >> private->chipshift)
+		{
+			addr = 0;
+			chipnum++;
+
+			if (chipnum >= private->numchips)
+				break;
+		}
+	}
+
+	instr->state = MTD_ERASE_DONE;
+	if (instr->callback)
+		instr->callback(instr);
+
+	return 0;
+}
+
+static int stm_flash_suspend(struct mtd_info *mtd)
+{
+	printk("stm_flash_suspend(): not implemented!\n");
+	        return -EINVAL;
+}
+
+
+
+static void stm_flash_resume(struct mtd_info *mtd)
+{
+	printk("stm_flash_resume(): not implemented!\n");
+}
+
+int __init stm_flash_init(void)
+{
+	register_mtd_chip_driver(&stm_flash_chipdrv);
+	return 0;
+}
+
+void __exit stm_flash_exit(void)
+{
+	unregister_mtd_chip_driver(&stm_flash_chipdrv);
+}
+
+module_init(stm_flash_init);
+module_exit(stm_flash_exit);
diff -urN linux-2.4.29/drivers/mtd/cmdlinepart.c linux-2.4.29-uc1/drivers/mtd/cmdlinepart.c
--- linux-2.4.29/drivers/mtd/cmdlinepart.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/cmdlinepart.c	2005-06-14 02:12:08.000000000 +0100
@@ -1,6 +1,4 @@
 /*
- * $Id: cmdlinepart.c,v 1.6 2002/11/16 01:37:39 dneuer Exp $
- *
  * Read flash partition table from command line
  *
  * Copyright 2002 SYSGO Real-Time Solutions GmbH
@@ -35,7 +33,7 @@
 #define ERRP "mtd: "
 
 /* debug macro */
-#if 0
+#if 1
 #define dbg(x) do { printk("DEBUG-CMDLINE-PART: "); printk x; } while(0)
 #else
 #define dbg(x)
@@ -79,7 +77,7 @@
 	unsigned long offset = 0;
 	char *name;
 	int name_len;
-	unsigned char *extra_mem;
+	unsigned char *extra_mem,*pName;
 	char delim;
 	unsigned int mask_flags;
 
@@ -134,7 +132,7 @@
 	}
    
 	/* record name length for memory allocation later */
-	extra_mem_size += name_len + 1;
+	//xxxx extra_mem_size += name_len + 1;
 
         /* test for options */
         if (strncmp(s, "ro", 2) == 0) 
@@ -153,7 +151,7 @@
 		}
 		/* more partitions follow, parse them */
 		if ((parts = newpart(s + 1, &s, num_parts, 
-		                     this_part + 1, &extra_mem, extra_mem_size)) == 0)
+		                     this_part + 1, &extra_mem, extra_mem_size+name_len+1)) == 0)
 		  return 0;
 	}
 	else
@@ -162,13 +160,15 @@
 
 		*num_parts = this_part + 1;
 		alloc_size = *num_parts * sizeof(struct mtd_partition) +
-			     extra_mem_size;
+			     extra_mem_size+name_len+1;
 		parts = kmalloc(alloc_size, GFP_KERNEL);
 		if (!parts)
 		{
 			printk(KERN_ERR ERRP "out of memory\n");
 			return 0;
 		}
+		dbg(("parts=0x%lx *num_parts=0x%lx\n",parts,*num_parts));
+
 		memset(parts, 0, alloc_size);
 		extra_mem = (unsigned char *)(parts + *num_parts);
 	}
@@ -176,17 +176,20 @@
 	parts[this_part].size = size;
 	parts[this_part].offset = offset;
 	parts[this_part].mask_flags = mask_flags;
+	pName = extra_mem+extra_mem_size;
 	if (name)
 	{
-		strncpy(extra_mem, name, name_len);
-		extra_mem[name_len] = 0;
+		strncpy(pName, name, name_len);
+		pName[name_len] = 0;
+		dbg(("ext. name\n"));
 	}
 	else
 	{
-		sprintf(extra_mem, "Partition_%03d", this_part);
+		dbg(("def. name\n"));
+		sprintf(pName, "Partition_%03d", this_part);
 	}
-	parts[this_part].name = extra_mem;
-	extra_mem += name_len + 1;
+	parts[this_part].name = pName;
+	//extra_mem += name_len + 1;
 
 	dbg(("partition %d: name <%s>, offset %x, size %x, mask flags %x\n",
 	     this_part, 
@@ -230,8 +233,6 @@
 		}
 		mtd_id_len = p - mtd_id;
 
-		dbg(("parsing <%s>\n", p+1));
-
 		/* 
 		 * parse one mtd. have it reserve memory for the
 		 * struct cmdline_mtd_partition and the mtd-id string.
@@ -241,7 +242,7 @@
 				&num_parts,	/* out: number of parts */
 				0,		/* first partition */
 				(unsigned char**)&this_mtd, /* out: extra mem */
-				mtd_id_len + 1 + sizeof(*this_mtd));
+				((mtd_id_len + 4) & ~3) + sizeof(*this_mtd));
 		if(!parts)
 		{
 			/*
@@ -254,6 +255,7 @@
 			 return 0;
 		 }
 
+
 		/* enter results */	    
 		this_mtd->parts = parts;
 		this_mtd->num_parts = num_parts;
@@ -299,7 +301,7 @@
 	int i;
 	struct cmdline_mtd_partition *part;
 
-	if(!cmdline)
+	if (!cmdline)
 		return -EINVAL;
 
 	/* parse command line */
diff -urN linux-2.4.29/drivers/mtd/Config.in linux-2.4.29-uc1/drivers/mtd/Config.in
--- linux-2.4.29/drivers/mtd/Config.in	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/Config.in	2005-06-14 02:12:08.000000000 +0100
@@ -14,6 +14,10 @@
    dep_tristate '  MTD partitioning support' CONFIG_MTD_PARTITIONS $CONFIG_MTD
    dep_tristate '  MTD concatenating support' CONFIG_MTD_CONCAT $CONFIG_MTD
    dep_tristate '  RedBoot partition table parsing' CONFIG_MTD_REDBOOT_PARTS $CONFIG_MTD_PARTITIONS
+   if [ "$CONFIG_MTD_REDBOOT_PARTS" = "y" ]; then
+      dep_bool '  Include unallocated flash space' CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED $CONFIG_MTD_REDBOOT_PARTS
+      dep_bool '  Force read-only for RedBoot system images' CONFIG_MTD_REDBOOT_PARTS_READONLY $CONFIG_MTD_REDBOOT_PARTS
+   fi
    dep_tristate '  Command line partition table parsing' CONFIG_MTD_CMDLINE_PARTS $CONFIG_MTD_PARTITIONS
    if [ "$CONFIG_ARM" = "y" ]; then
       dep_tristate '  ARM Firmware Suite partition parsing' CONFIG_MTD_AFS_PARTS $CONFIG_MTD_PARTITIONS
@@ -27,6 +31,7 @@
    fi
    dep_tristate '  FTL (Flash Translation Layer) support' CONFIG_FTL $CONFIG_MTD
    dep_tristate '  NFTL (NAND Flash Translation Layer) support' CONFIG_NFTL $CONFIG_MTD
+   dep_tristate '  INFTL (Inverse NAND Flash Translation Layer) support' CONFIG_INFTL $CONFIG_MTD
    if [ "$CONFIG_NFTL" = "y" -o "$CONFIG_NFTL" = "m" ]; then
       bool '    Write support for NFTL (BETA)' CONFIG_NFTL_RW
    fi
diff -urN linux-2.4.29/drivers/mtd/devices/cfm.c linux-2.4.29-uc1/drivers/mtd/devices/cfm.c
--- linux-2.4.29/drivers/mtd/devices/cfm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/devices/cfm.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,552 @@
+/*
+ * MTD driver for the ColdFire Flash Module on MCF5282.
+ *
+ * $Id:$
+ *
+ * Author: Mathias Küster
+ *
+ * Copyright (c) 2004, Mathias Küster
+ *
+ * Some parts are based on lart.c by Abraham vd Merwe
+ *
+ * This code is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/* debugging */
+//#define CFM_DEBUG
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/errno.h>
+#include <linux/mtd/mtd.h>
+#include <linux/autoconf.h>
+#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/partitions.h>
+#endif
+
+#ifndef CONFIG_M5282
+#error This is for MCF5282 architecture only
+#endif
+
+static char module_name[] = "CFM";
+
+/*
+ * Flash memory blocksize, blockcount and offset.
+ */
+#define FLASH_BLOCKSIZE		(1024*2)
+#define FLASH_NUMBLOCKS		256
+#define FLASH_OFFSET		0x00000000
+
+/*
+ * General settings, FLASH_OFFSET based on FLASHBAR chip select
+ */
+#define BUSWIDTH		4
+#ifdef CONFIG_MTD_CFM_OFFSET
+#define CFM_OFFSET		CONFIG_MTD_CFM_OFFSET
+#else
+#define CFM_OFFSET		0xF0000000
+#endif
+#define CFM_BACKDOOR_OFFSET	(MCF_IPSBAR+0x04000000)
+
+/*
+ * CFM User Mode Commands
+ */
+#define CFMCMD_RDARY1	0x05	/* erase verify */
+#define CFMCMD_PGM	0x20	/* longword program */
+#define CFMCMD_PGERS	0x40	/* page erase */
+#define CFMCMD_MASERS	0x41	/* mass erase */
+#define CFMCMD_PGERSVER	0x06	/* page erase verify */
+
+/*
+ * CFM Status Bits
+ */
+#define CFMUSTAT_CBEIF	0x80
+#define CFMUSTAT_CCIF	0x40
+#define CFMUSTAT_PVIOL	0x20
+#define CFMUSTAT_ACCERR	0x10
+#define CFMUSTAT_BLANK	0x04
+
+/*
+ * CFM configuration fields (sector 0)
+ */
+#define CFMCFG_BDKEY	0x0400	/* back door comparison key (8 byte) */
+#define CFMCFG_PROT	0x0408	/* flash program/erase sector protection (4 byte) */
+#define CFMCFG_SACC	0x040C	/* flash supervisor/user space restrictions (4 byte) */
+#define CFMCFG_DACC	0x0410	/* flash program/data space restrictions (4 byte) */
+#define CFMCFG_MSEC	0x0414	/* flash security longword (4 byte) */
+
+/***************************************************************************************************/
+
+/*
+ * Reset CFM state register error bits
+ */
+void reset_state (void)
+{
+   if ( *(volatile unsigned char*) (MCF_IPSBAR+MCF5282_CFM_USTAT) & CFMUSTAT_PVIOL )
+		*(volatile unsigned char*) (MCF_IPSBAR+MCF5282_CFM_USTAT) |= CFMUSTAT_PVIOL;
+   if ( *(volatile unsigned char*) (MCF_IPSBAR+MCF5282_CFM_USTAT) & CFMUSTAT_ACCERR )
+		*(volatile unsigned char*) (MCF_IPSBAR+MCF5282_CFM_USTAT) |= CFMUSTAT_ACCERR;
+   if ( *(volatile unsigned char*) (MCF_IPSBAR+MCF5282_CFM_USTAT) & CFMUSTAT_BLANK )
+		*(volatile unsigned char*) (MCF_IPSBAR+MCF5282_CFM_USTAT) |= CFMUSTAT_BLANK;
+}
+
+/*
+ * Erase one block of flash memory at offset ``offset'' which is any
+ * address within the block which should be erased.
+ *
+ * Returns 1 if successful, 0 otherwise.
+ */
+static inline int erase_block (__u32 offset)
+{
+   __u32 status = 1;
+
+#ifdef CFM_DEBUG
+   printk (KERN_DEBUG "%s(): 0x%.8x\n",__FUNCTION__,offset);
+#endif
+
+   /* start sector erase sequence */
+   *(volatile __u32*) (CFM_BACKDOOR_OFFSET+offset) = 0;
+   *(volatile __u8*) (MCF_IPSBAR+MCF5282_CFM_CMD) = CFMCMD_PGERS;
+   *(volatile __u8*) (MCF_IPSBAR+MCF5282_CFM_USTAT) = CFMUSTAT_CBEIF;
+   
+   /* wait for ready */
+   while ( ! (*(volatile __u8*) (MCF_IPSBAR+MCF5282_CFM_USTAT) & CFMUSTAT_CCIF ) );
+   
+   /* error handling */
+   if ( *(volatile __u8*) (MCF_IPSBAR+MCF5282_CFM_USTAT) & CFMUSTAT_ACCERR )
+   	{
+   		printk( KERN_INFO "%s(): ACCERR\n",__FUNCTION__);
+		status = 0;
+   	}
+   if ( *(volatile __u8*) (MCF_IPSBAR+MCF5282_CFM_USTAT) & CFMUSTAT_PVIOL )
+   	{
+   		printk( KERN_INFO "%s(): PVIOL\n",__FUNCTION__);
+		status = 0;
+   	}
+
+   /* reset status flags */
+   reset_state();
+
+   return (status);
+}
+
+/*
+ * Erase flash.
+ *
+ * Returns 1 if successful, 0 otherwise.
+ */
+static inline int erase_flash (int page)
+{
+   __u32 status = 1;
+
+#ifdef CFM_DEBUG
+   printk (KERN_DEBUG "%s(): page %d\n",__FUNCTION__,page);
+#endif
+
+   if ( (page < 0) || (page > 1) )
+   	 return (0);
+
+   /* start sector erase sequence */
+   *(volatile __u32*) (CFM_BACKDOOR_OFFSET+(page*256*1024)) = 0x00000000;
+   *(volatile __u8*) (MCF_IPSBAR+MCF5282_CFM_CMD) = CFMCMD_MASERS;
+   *(volatile __u8*) (MCF_IPSBAR+MCF5282_CFM_USTAT) = CFMUSTAT_CBEIF;
+   
+   /* wait for ready */
+   while ( ! (*(volatile __u8*) (MCF_IPSBAR+MCF5282_CFM_USTAT) & CFMUSTAT_CCIF ) );
+   
+   /* error handling */
+   if ( *(volatile __u8*) (MCF_IPSBAR+MCF5282_CFM_USTAT) & CFMUSTAT_ACCERR )
+   	{
+   		printk( KERN_INFO "%s(): ACCERR\n",__FUNCTION__);
+		status = 0;
+   	}
+   if ( *(volatile __u8*) (MCF_IPSBAR+MCF5282_CFM_USTAT) & CFMUSTAT_PVIOL )
+   	{
+   		printk( KERN_INFO "%s(): PVIOL\n",__FUNCTION__);
+		status = 0;
+   	}
+
+   /* reset status flags */
+   reset_state();
+
+   return (status);
+}
+
+static int flash_erase (struct mtd_info *mtd,struct erase_info *instr)
+{
+   __u32 addr,len;
+   int i,first;
+
+#ifdef CFM_DEBUG
+   printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n",__FUNCTION__,instr->addr,instr->len);
+#endif
+
+   /* sanity checks */
+   if (instr->addr + instr->len > mtd->size) return (-EINVAL);
+
+   /*
+	* check that both start and end of the requested erase are
+	* aligned with the erasesize at the appropriate addresses.
+	*
+	* skip all erase regions which are ended before the start of
+	* the requested erase. Actually, to save on the calculations,
+	* we skip to the first erase region which starts after the
+	* start of the requested erase, and then go back one.
+	*/
+   for (i = 0; i < mtd->numeraseregions && instr->addr >= mtd->eraseregions[i].offset; i++) ;
+   i--;
+
+   /*
+	* ok, now i is pointing at the erase region in which this
+	* erase request starts. Check the start of the requested
+	* erase range is aligned with the erase size which is in
+	* effect here.
+	*/
+   if (instr->addr & (mtd->eraseregions[i].erasesize - 1)) return (-EINVAL);
+
+   /* Remember the erase region we start on */
+   first = i;
+
+   /*
+	* next, check that the end of the requested erase is aligned
+	* with the erase region at that address.
+	*
+	* as before, drop back one to point at the region in which
+	* the address actually falls
+	*/
+   for (; i < mtd->numeraseregions && instr->addr + instr->len >= mtd->eraseregions[i].offset; i++) ;
+   i--;
+
+   /* is the end aligned on a block boundary? */
+   if ((instr->addr + instr->len) & (mtd->eraseregions[i].erasesize - 1)) return (-EINVAL);
+
+   addr = instr->addr;
+   len = instr->len;
+
+   i = first;
+
+   /* if sector 0 erased, we erase the complete flash */
+   if ( addr == FLASH_OFFSET )
+	 {
+	 	 if (!erase_flash(0))
+		   {
+			 instr->state = MTD_ERASE_FAILED;
+			 return (-EIO);
+		   }
+	 
+	 	 if (!erase_flash(1))
+		   {
+			 instr->state = MTD_ERASE_FAILED;
+			 return (-EIO);
+		   }
+	 	 
+		 len = 0;
+	 }
+   
+   /* now erase those blocks */
+   while (len)
+	 {
+		if (!erase_block (addr))
+		  {
+			 instr->state = MTD_ERASE_FAILED;
+			 return (-EIO);
+		  }
+
+		addr += mtd->eraseregions[i].erasesize;
+		len -= mtd->eraseregions[i].erasesize;
+
+		if (addr == mtd->eraseregions[i].offset + (mtd->eraseregions[i].erasesize * mtd->eraseregions[i].numblocks)) i++;
+	 }
+
+   instr->state = MTD_ERASE_DONE;
+   if (instr->callback) instr->callback (instr);
+
+   return (0);
+}
+
+static int flash_read (struct mtd_info *mtd,loff_t from,size_t len,size_t *retlen,u_char *buf)
+{
+#ifdef CFM_DEBUG
+   printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) from,len);
+#endif
+
+   /* sanity checks */
+   if (!len) return (0);
+   if (from + len > mtd->size) return (-EINVAL);
+
+   /* we always read len bytes */
+   *retlen = len;
+
+   memcpy(buf,((u_char*)(CFM_OFFSET))+from,len);
+   
+   return 0;
+}
+
+/*
+ * Write one dword ``x'' to flash memory at offset ``offset''. ``offset''
+ * must be 32 bits, i.e. it must be on a dword boundary.
+ *
+ * Returns 1 if successful, 0 otherwise.
+ */
+static inline int write_dword (__u32 offset,__u32 x)
+{
+   __u32 status = 1;
+
+#ifdef CFM_DEBUG
+   printk (KERN_DEBUG "%s(): 0x%.8x <- 0x%.8x\n",__FUNCTION__,offset,x);
+#endif
+
+   /* start program sequence */
+   *(volatile __u32*) (CFM_BACKDOOR_OFFSET+offset) = x;
+   *(volatile __u8*) (MCF_IPSBAR+MCF5282_CFM_CMD) = CFMCMD_PGM;
+   *(volatile __u8*) (MCF_IPSBAR+MCF5282_CFM_USTAT) = CFMUSTAT_CBEIF;
+
+   /* wait for ready */
+   while ( ! (*(volatile __u8*) (MCF_IPSBAR+MCF5282_CFM_USTAT) & CFMUSTAT_CCIF ) );
+   
+   /* error handling */
+   if ( *(volatile __u8*) (MCF_IPSBAR+MCF5282_CFM_USTAT) & CFMUSTAT_ACCERR )
+   	{
+   		printk( KERN_INFO "%s(): ACCERR\n",__FUNCTION__);
+		status = 0;
+   	}
+   if ( *(volatile __u8*) (MCF_IPSBAR+MCF5282_CFM_USTAT) & CFMUSTAT_PVIOL )
+   	{
+   		printk( KERN_INFO "%s(): PVIOL\n",__FUNCTION__);
+		status = 0;
+   	}
+
+   /* reset status flags */
+   reset_state();
+   
+   return status;
+}
+
+static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen,const u_char *buf)
+{
+   __u8 tmp[4];
+   int i,n;
+
+#ifdef CFM_DEBUG
+   printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) to,len);
+#endif
+
+   *retlen = 0;
+
+   /* sanity checks */
+   if (!len) return (0);
+   if (to + len > mtd->size) return (-EINVAL);
+
+   /* first, we write a 0xFF.... padded byte until we reach a dword boundary */
+   if (to & (BUSWIDTH - 1))
+	 {
+		__u32 aligned = to & ~(BUSWIDTH - 1);
+		int gap = to - aligned;
+
+		i = n = 0;
+
+		while (gap--) tmp[i++] = 0xFF;
+		while (len && i < BUSWIDTH) tmp[i++] = buf[n++], len--;
+		while (i < BUSWIDTH) tmp[i++] = 0xFF;
+
+		if (!write_dword (aligned,*((__u32 *) tmp))) return (-EIO);
+
+		to += n;
+		buf += n;
+		*retlen += n;
+	 }
+
+   /* now we write dwords until we reach a non-dword boundary */
+   while (len >= BUSWIDTH)
+	 {
+		if (!write_dword (to,*((__u32 *) buf))) return (-EIO);
+
+		to += BUSWIDTH;
+		buf += BUSWIDTH;
+		*retlen += BUSWIDTH;
+		len -= BUSWIDTH;
+	 }
+
+   /* top up the last unaligned bytes, padded with 0xFF.... */
+   if (len & (BUSWIDTH - 1))
+	 {
+		i = n = 0;
+
+		while (len--) tmp[i++] = buf[n++];
+		while (i < BUSWIDTH) tmp[i++] = 0xFF;
+
+		if (!write_dword (to,*((__u32 *) tmp))) return (-EIO);
+
+		*retlen += n;
+	 }
+
+   return (0);
+}
+
+/***************************************************************************************************/
+
+#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
+
+static struct mtd_info mtd;
+
+static struct mtd_erase_region_info erase_regions[] =
+{
+   /* parameter blocks cfmsec */
+   {
+	     offset: FLASH_OFFSET,
+	  erasesize: FLASH_BLOCKSIZE,
+	  numblocks: 1
+   },
+   /* parameter blocks cfm */
+   {
+	     offset: FLASH_OFFSET+FLASH_BLOCKSIZE,
+	  erasesize: FLASH_BLOCKSIZE,
+	  numblocks: (FLASH_NUMBLOCKS-1)
+   }
+};
+
+#ifdef CONFIG_MTD_PARTITIONS
+static struct mtd_partition cfm_partitions[] =
+{
+   /* cfmsec */
+   {
+	       name: "cfmsec",
+	     offset: FLASH_OFFSET,
+	       size: FLASH_BLOCKSIZE,
+	 mask_flags: 0
+   },
+   /* cfm */
+   {
+	       name: "cfm",
+	     offset: FLASH_OFFSET+FLASH_BLOCKSIZE,
+	       size: FLASH_BLOCKSIZE * (FLASH_NUMBLOCKS-1),
+	 mask_flags: 0
+   }
+};
+#endif
+
+void flash_init (void)
+{
+   reset_state();
+
+   *(volatile unsigned short*)(MCF_IPSBAR+MCF5282_CFM_MCR)  = 0;
+   /* 200KHz @ 64MHz sysclk */
+   *(volatile unsigned char*) (MCF_IPSBAR+MCF5282_CFM_CLKD) = (1<<6) | 20;
+   /* disable protection */
+   *(volatile unsigned long*) (MCF_IPSBAR+MCF5282_CFM_PROT) = 0;
+   /* disable supervisor mode */
+   *(volatile unsigned long*) (MCF_IPSBAR+MCF5282_CFM_SACC) = 0;
+   /* data and program address space */
+   *(volatile unsigned long*) (MCF_IPSBAR+MCF5282_CFM_DACC) = 0;
+}
+
+int __init cfm_flash_init (void)
+{
+   int result;
+   uint32_t keyhi,keylo;
+   memset (&mtd,0,sizeof (mtd));
+   printk ("MTD driver for ColdFire Flash Module. Written by Mathias Küster\n");
+   flash_init();
+
+   if ( (*(volatile unsigned long*) (MCF_IPSBAR+MCF5282_CFM_SEC) & 0x80000000) )
+	 {
+		printk ("CFM: Warning, backdoor mode enabled. (%x)\n",*(volatile unsigned long*) (MCF_IPSBAR+MCF5282_CFM_SEC));
+	
+		keyhi = *(volatile unsigned long*) (CFM_OFFSET + CFMCFG_BDKEY);
+		keylo = *(volatile unsigned long*) (CFM_OFFSET + CFMCFG_BDKEY+4);
+
+		*(volatile unsigned short*)(MCF_IPSBAR+MCF5282_CFM_MCR) |= (1<<5);
+		*(volatile unsigned long*) (CFM_BACKDOOR_OFFSET + CFMCFG_BDKEY) = keyhi;
+		*(volatile unsigned long*) (CFM_BACKDOOR_OFFSET + CFMCFG_BDKEY+4) = keylo;
+		*(volatile unsigned short*)(MCF_IPSBAR+MCF5282_CFM_MCR) &= ~(1<<5);
+	 }
+   
+   if ( (*(volatile unsigned long*) (MCF_IPSBAR+MCF5282_CFM_SEC) & 0x40000000) )
+   	printk ("CFM: Warning, security mode enabled. %x\n",*(volatile unsigned long*) (MCF_IPSBAR+MCF5282_CFM_SEC));
+
+#ifdef CFM_DEBUG
+   printk("MCR : %04X\n",*(volatile unsigned short*)(MCF_IPSBAR+MCF5282_CFM_MCR));
+   printk("PROT: %08X\n",*(volatile unsigned long*) (MCF_IPSBAR+MCF5282_CFM_PROT));
+   printk("SEC : %08X\n",*(volatile unsigned long*) (MCF_IPSBAR+MCF5282_CFM_SEC));
+   printk("SACC: %08X\n",*(volatile unsigned long*) (MCF_IPSBAR+MCF5282_CFM_SACC));
+   printk("DACC: %08X\n",*(volatile unsigned long*) (MCF_IPSBAR+MCF5282_CFM_DACC));
+#endif
+
+   mtd.name = module_name;
+   mtd.type = MTD_NORFLASH;
+   mtd.flags = MTD_CAP_NORFLASH;
+   mtd.size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS;
+   mtd.erasesize = FLASH_BLOCKSIZE;
+   mtd.numeraseregions = NB_OF (erase_regions);
+   mtd.eraseregions = erase_regions;
+   mtd.module = THIS_MODULE;
+   mtd.erase = flash_erase;
+   mtd.read = flash_read;
+   mtd.write = flash_write;
+
+#ifdef CFM_DEBUG
+   printk (KERN_DEBUG
+		   "mtd.name = %s\n"
+		   "mtd.size = 0x%.8x (%uM)\n"
+		   "mtd.erasesize = 0x%.8x (%uK)\n"
+		   "mtd.numeraseregions = %d\n",
+		   mtd.name,
+		   mtd.size,mtd.size / (1024*1024),
+		   mtd.erasesize,mtd.erasesize / 1024,
+		   mtd.numeraseregions);
+
+   if (mtd.numeraseregions)
+	 for (result = 0; result < mtd.numeraseregions; result++)
+	   printk (KERN_DEBUG
+			   "\n\n"
+			   "mtd.eraseregions[%d].offset = 0x%.8x\n"
+			   "mtd.eraseregions[%d].erasesize = 0x%.8x (%uK)\n"
+			   "mtd.eraseregions[%d].numblocks = %d\n",
+			   result,mtd.eraseregions[result].offset,
+			   result,mtd.eraseregions[result].erasesize,mtd.eraseregions[result].erasesize / 1024,
+			   result,mtd.eraseregions[result].numblocks);
+
+#ifdef CONFIG_MTD_PARTITIONS
+   printk ("\npartitions = %d\n",NB_OF (cfm_partitions));
+
+   for (result = 0; result < NB_OF (cfm_partitions); result++)
+	 printk (KERN_DEBUG
+			 "\n\n"
+			 "cfm_partitions[%d].name = %s\n"
+			 "cfm_partitions[%d].offset = 0x%.8x\n"
+			 "cfm_partitions[%d].size = 0x%.8x (%uK)\n",
+			 result,cfm_partitions[result].name,
+			 result,cfm_partitions[result].offset,
+			 result,cfm_partitions[result].size,cfm_partitions[result].size / 1024);
+#endif
+#endif
+
+#ifndef CONFIG_MTD_PARTITIONS
+   result = add_mtd_device (&mtd);
+#else
+   result = add_mtd_partitions (&mtd,cfm_partitions,NB_OF (cfm_partitions));
+#endif
+
+   return (result);
+}
+
+void __exit cfm_flash_exit (void)
+{
+#ifndef CONFIG_MTD_PARTITIONS
+   del_mtd_device (&mtd);
+#else
+   del_mtd_partitions (&mtd);
+#endif
+}
+
+module_init (cfm_flash_init);
+module_exit (cfm_flash_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathias Küster");
+MODULE_DESCRIPTION("MTD driver for ColdFire Flash Module");
diff -urN linux-2.4.29/drivers/mtd/devices/Config.in linux-2.4.29-uc1/drivers/mtd/devices/Config.in
--- linux-2.4.29/drivers/mtd/devices/Config.in	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/devices/Config.in	2005-06-14 02:12:08.000000000 +0100
@@ -17,6 +17,22 @@
 if [ "$CONFIG_SA1100_LART" = "y" ]; then
    dep_tristate '  28F160xx flash driver for LART' CONFIG_MTD_LART $CONFIG_MTD
 fi
+if [ "$CONFIG_ARCH_MX1ADS" = "y" ]; then
+   dep_tristate '  SyncFlash driver for MX1ADS' CONFIG_MTD_SYNCFLASH $CONFIG_MTD
+fi
+if [ "$CONFIG_M5282" = "y" ]; then
+   bool '  ColdFire Flash Module' CONFIG_MTD_CFM $CONFIG_MTD
+   if [ "$CONFIG_MTD_CFM" = "y" ]; then
+      hex  '    Physical address of ColdFire Flash Module' CONFIG_MTD_CFM_OFFSET 0xF0000000
+   fi
+fi
+if [ "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
+   dep_tristate '  AT91RM9200 DataFlash support' CONFIG_MTD_AT91_DATAFLASH $CONFIG_MTD
+   if [ "$CONFIG_MTD_AT91_DATAFLASH" = "y" -o "$CONFIG_MTD_AT91_DATAFLASH" = "m" ]; then
+      bool '     Enable DataFlash card?   ' CONFIG_MTD_AT91_DATAFLASH_CARD
+   fi
+fi
+
 dep_tristate '  Test driver using RAM' CONFIG_MTD_MTDRAM $CONFIG_MTD
 if [ "$CONFIG_MTD_MTDRAM" = "y" -o "$CONFIG_MTD_MTDRAM" = "m" ]; then
    int 'MTDRAM device size in KiB' CONFIG_MTDRAM_TOTAL_SIZE 4096
@@ -25,16 +41,20 @@
       hex 'SRAM Hexadecimal Absolute position or 0' CONFIG_MTDRAM_ABS_POS 0
    fi
 fi
+
+dep_tristate '  Conexant flash MTD support hack' CONFIG_MTD_MTDCNXT $CONFIG_MTD $CONFIG_CNXT_FLASH
+
 dep_tristate '  MTD emulation using block device' CONFIG_MTD_BLKMTD $CONFIG_MTD
 
 comment 'Disk-On-Chip Device Drivers'
    dep_tristate '  M-Systems Disk-On-Chip 1000' CONFIG_MTD_DOC1000 $CONFIG_MTD
    dep_tristate '  M-Systems Disk-On-Chip 2000 and Millennium' CONFIG_MTD_DOC2000 $CONFIG_MTD
    dep_tristate '  M-Systems Disk-On-Chip Millennium-only alternative driver (see help)' CONFIG_MTD_DOC2001 $CONFIG_MTD
-   if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then
+   dep_tristate '  M-Systems Disk-On-Chip Millennium Plus driver (see help)' CONFIG_MTD_DOC2001PLUS $CONFIG_MTD
+   if [ "$CONFIG_MTD_DOC2001PLUS" = "y" -o "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then
       define_bool CONFIG_MTD_DOCPROBE y
    else
-      if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then
+      if [ "$CONFIG_MTD_DOC2001PLUS" = "m" -o "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then
 	 define_bool CONFIG_MTD_DOCPROBE m
       else
 	 define_bool CONFIG_MTD_DOCPROBE n
diff -urN linux-2.4.29/drivers/mtd/devices/doc2001.c linux-2.4.29-uc1/drivers/mtd/devices/doc2001.c
--- linux-2.4.29/drivers/mtd/devices/doc2001.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/devices/doc2001.c	2005-06-14 02:12:08.000000000 +0100
@@ -227,6 +227,7 @@
 			doc->mfr = mfr;
 			doc->id = id;
 			doc->chipshift = nand_flash_ids[i].chipshift;
+			doc->erasesize = nand_flash_ids[i].erasesize;
 			break;
 		}
 	}
@@ -361,9 +362,7 @@
 	mtd->flags = MTD_CAP_NANDFLASH;
 	mtd->size = 0;
 
-	/* FIXME: erase size is not always 8kB */
-	mtd->erasesize = 0x2000;
-
+	mtd->erasesize = 0;
 	mtd->oobblock = 512;
 	mtd->oobsize = 16;
 	mtd->module = THIS_MODULE;
@@ -393,6 +392,7 @@
 		this->nextdoc = docmillist;
 		docmillist = mtd;
 		mtd->size  = this->totlen;
+		mtd->erasesize = this->erasesize;
 		add_mtd_device(mtd);
 		return;
 	}
diff -urN linux-2.4.29/drivers/mtd/devices/doc2001plus.c linux-2.4.29-uc1/drivers/mtd/devices/doc2001plus.c
--- linux-2.4.29/drivers/mtd/devices/doc2001plus.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/devices/doc2001plus.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,1116 @@
+/*
+ * Linux driver for Disk-On-Chip Millennium Plus
+ *
+ * (c) 2002-2003 Greg Ungerer <gerg@snapgear.com>
+ * (c) 2002-2003 SnapGear Inc
+ * (c) 1999 Machine Vision Holdings, Inc.
+ * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
+ *
+ * $Id: doc2001plus.c,v 1.7 2003/08/22 14:16:18 davidm Exp $
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/doc2000.h>
+
+/* #define ECC_DEBUG */
+
+/* I have no idea why some DoC chips can not use memcop_form|to_io().
+ * This may be due to the different revisions of the ASIC controller built-in or
+ * simplily a QA/Bug issue. Who knows ?? If you have trouble, please uncomment
+ * this:*/
+#undef USE_MEMCPY
+
+static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, u_char *buf);
+static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
+		size_t *retlen, const u_char *buf);
+static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel);
+static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
+		size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel);
+static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+		size_t *retlen, u_char *buf);
+static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+		size_t *retlen, const u_char *buf);
+static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
+
+static struct mtd_info *docmilpluslist = NULL;
+
+
+/* Perform the required delay cycles by writing to the NOP register */
+static void DoC_Delay(unsigned long docptr, int cycles)
+{
+	int i;
+
+	for (i = 0; (i < cycles); i++)
+		WriteDOC(0, docptr, Mplus_NOP);
+}
+
+#define	CDSN_CTRL_FR_B_MASK	(CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1)
+
+/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
+static int _DoC_WaitReady(unsigned long docptr)
+{
+	unsigned int c = 0xffff;
+
+	DEBUG(MTD_DEBUG_LEVEL3,
+	      "_DoC_WaitReady called for out-of-line wait\n");
+
+	/* Out-of-line routine to wait for chip response */
+	while (((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) && --c)
+		;
+
+	if (c == 0)
+		DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
+
+	return (c == 0);
+}
+
+static inline int DoC_WaitReady(unsigned long docptr)
+{
+	/* This is inline, to optimise the common case, where it's ready instantly */
+	int ret = 0;
+
+	/* read form NOP register should be issued prior to the read from CDSNControl
+	   see Software Requirement 11.4 item 2. */
+	DoC_Delay(docptr, 4);
+
+	if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK)
+		/* Call the out-of-line routine to wait */
+		ret = _DoC_WaitReady(docptr);
+
+	return ret;
+}
+
+/* For some reason the Millennium Plus seems to occassionally put itself
+ * into reset mode. For me this happens randomly, with no pattern that I
+ * can detect. M-systems suggest always check this on any block level
+ * operation and setting to normal mode if in reset mode.
+ */
+static inline void DoC_CheckASIC(unsigned long docptr)
+{
+	/* Make sure the DoC is in normal mode */
+	if ((ReadDOC(docptr, Mplus_DOCControl) & DOC_MODE_NORMAL) == 0) {
+		WriteDOC((DOC_MODE_NORMAL | DOC_MODE_MDWREN), docptr, Mplus_DOCControl);
+		WriteDOC(~(DOC_MODE_NORMAL | DOC_MODE_MDWREN), docptr, Mplus_CtrlConfirm);
+	}
+}
+
+/* DoC_Command: Send a flash command to the flash chip through the Flash
+ * command register. Need 2 Write Pipeline Terminates to complete send.
+ */
+static inline void DoC_Command(unsigned long docptr, unsigned char command,
+			       unsigned char xtraflags)
+{
+	WriteDOC(command, docptr, Mplus_FlashCmd);
+	WriteDOC(command, docptr, Mplus_WritePipeTerm);
+	WriteDOC(command, docptr, Mplus_WritePipeTerm);
+}
+
+/* DoC_Address: Set the current address for the flash chip through the Flash
+ * Address register. Need 2 Write Pipeline Terminates to complete send.
+ */
+static inline void DoC_Address(struct DiskOnChip *doc, int numbytes,
+			       unsigned long ofs, unsigned char xtraflags1,
+			       unsigned char xtraflags2)
+{
+	unsigned long docptr = doc->virtadr;
+
+	/* Allow for possible Mill Plus internal flash interleaving */
+	ofs >>= doc->interleave;
+
+	switch (numbytes) {
+	case 1:
+		/* Send single byte, bits 0-7. */
+		WriteDOC(ofs & 0xff, docptr, Mplus_FlashAddress);
+		break;
+	case 2:
+		/* Send bits 9-16 followed by 17-23 */
+		WriteDOC((ofs >> 9)  & 0xff, docptr, Mplus_FlashAddress);
+		WriteDOC((ofs >> 17) & 0xff, docptr, Mplus_FlashAddress);
+		break;
+	case 3:
+		/* Send 0-7, 9-16, then 17-23 */
+		WriteDOC(ofs & 0xff, docptr, Mplus_FlashAddress);
+		WriteDOC((ofs >> 9)  & 0xff, docptr, Mplus_FlashAddress);
+		WriteDOC((ofs >> 17) & 0xff, docptr, Mplus_FlashAddress);
+		break;
+	default:
+		return;
+	}
+
+	WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
+	WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
+}
+
+/* DoC_SelectChip: Select a given flash chip within the current floor */
+static int DoC_SelectChip(unsigned long docptr, int chip)
+{
+	/* No choice for flash chip on Millennium Plus */
+	return 0;
+}
+
+/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
+static int DoC_SelectFloor(unsigned long docptr, int floor)
+{
+	WriteDOC((floor & 0x3), docptr, Mplus_DeviceSelect);
+	return 0;
+}
+
+/*
+ * Translate the given offset into the appropriate command and offset.
+ * This does the mapping using the 16bit interleave layout defined by
+ * M-Systems, and looks like this for a sector pair:
+ *  +-----------+-------+-------+-------+--------------+---------+-----------+
+ *  | 0 --- 511 |512-517|518-519|520-521| 522 --- 1033 |1034-1039|1040 - 1055|
+ *  +-----------+-------+-------+-------+--------------+---------+-----------+
+ *  | Data 0    | ECC 0 |Flags0 |Flags1 | Data 1       |ECC 1    | OOB 1 + 2 |
+ *  +-----------+-------+-------+-------+--------------+---------+-----------+
+ */
+static unsigned int DoC_GetDataOffset(struct mtd_info *mtd, loff_t *from)
+{
+	unsigned int ofs = *from & 0x3ff;
+	unsigned int cmd;
+
+	if (ofs < 512) {
+		cmd = NAND_CMD_READ0;
+		ofs &= 0x1ff;
+	} else if (ofs < 1014) {
+		cmd = NAND_CMD_READ1;
+		ofs = (ofs & 0x1ff) + 10;
+	} else {
+		cmd = NAND_CMD_READOOB;
+		ofs = ofs - 1014;
+	}
+
+	*from = (*from & ~0x3ff) | ofs;
+	return cmd;
+}
+
+static unsigned int DoC_GetECCOffset(struct mtd_info *mtd, loff_t *from)
+{
+	unsigned int ofs, cmd;
+
+	if (*from & 0x200) {
+		cmd = NAND_CMD_READOOB;
+		ofs = 10 + (*from & 0xf);
+	} else {
+		cmd = NAND_CMD_READ1;
+		ofs = (*from & 0xf);
+	}
+
+	*from = (*from & ~0x3ff) | ofs;
+	return cmd;
+}
+
+static unsigned int DoC_GetFlagsOffset(struct mtd_info *mtd, loff_t *from)
+{
+	unsigned int ofs, cmd;
+
+	cmd = NAND_CMD_READ1;
+	ofs = (*from & 0x200) ? 8 : 6;
+	*from = (*from & ~0x3ff) | ofs;
+	return cmd;
+}
+
+static unsigned int DoC_GetHdrOffset(struct mtd_info *mtd, loff_t *from)
+{
+	unsigned int ofs, cmd;
+
+	cmd = NAND_CMD_READOOB;
+	ofs = (*from & 0x200) ? 24 : 16;
+	*from = (*from & ~0x3ff) | ofs;
+	return cmd;
+}
+
+static inline void MemReadDOC(unsigned long docptr, unsigned char *buf, int len)
+{
+#ifndef USE_MEMCPY
+	int i;
+	for (i = 0; i < len; i++)
+		buf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
+#else
+	memcpy_fromio(buf, docptr + DoC_Mil_CDSN_IO, len);
+#endif
+}
+
+static inline void MemWriteDOC(unsigned long docptr, unsigned char *buf, int len)
+{
+#ifndef USE_MEMCPY
+	int i;
+	for (i = 0; i < len; i++)
+		WriteDOC(buf[i], docptr, Mil_CDSN_IO + i);
+#else
+	memcpy_toio(docptr + DoC_Mil_CDSN_IO, buf, len);
+#endif
+}
+
+/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
+static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
+{
+	int mfr, id, i, j;
+	volatile char dummy;
+	unsigned long docptr = doc->virtadr;
+
+	/* Page in the required floor/chip */
+	DoC_SelectFloor(docptr, floor);
+	DoC_SelectChip(docptr, chip);
+
+	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
+	WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);
+
+	/* Reset the chip, see Software Requirement 11.4 item 1. */
+	DoC_Command(docptr, NAND_CMD_RESET, 0);
+	DoC_WaitReady(docptr);
+
+	/* Read the NAND chip ID: 1. Send ReadID command */ 
+	DoC_Command(docptr, NAND_CMD_READID, 0);
+
+	/* Read the NAND chip ID: 2. Send address byte zero */ 
+	DoC_Address(doc, 1, 0x00, 0, 0x00);
+
+	WriteDOC(0, docptr, Mplus_FlashControl);
+	DoC_WaitReady(docptr);
+
+	/* Read the manufacturer and device id codes of the flash device through
+	   CDSN IO register see Software Requirement 11.4 item 5.*/
+	dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
+	dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
+
+	mfr = ReadDOC(docptr, Mil_CDSN_IO);
+	dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */
+
+	id  = ReadDOC(docptr, Mil_CDSN_IO);
+	dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */
+
+	dummy = ReadDOC(docptr, Mplus_LastDataRead);
+	dummy = ReadDOC(docptr, Mplus_LastDataRead);
+
+	/* Disable flash internally */
+	WriteDOC(0, docptr, Mplus_FlashSelect);
+
+	/* No response - return failure */
+	if (mfr == 0xff || mfr == 0)
+		return 0;
+
+	for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+		if (id == nand_flash_ids[i].id) {
+			/* Try to identify manufacturer */
+			for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
+				if (nand_manuf_ids[j].id == mfr)
+					break;
+			}
+			printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, "
+			       "Chip ID: %2.2X (%s:%s)\n", mfr, id,
+			       nand_manuf_ids[j].name, nand_flash_ids[i].name);
+			doc->mfr = mfr;
+			doc->id = id;
+			doc->interleave = 0;
+			if (doc->ChipID == DOC_ChipID_DocMilPlus32)
+				doc->interleave = 1;
+			doc->chipshift = nand_flash_ids[i].chipshift;
+			doc->erasesize = nand_flash_ids[i].erasesize << doc->interleave;
+			break;
+		}
+	}
+
+	if (nand_flash_ids[i].name == NULL)
+		return 0;
+	return 1;
+}
+
+/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
+static void DoC_ScanChips(struct DiskOnChip *this)
+{
+	int floor, chip;
+	int numchips[MAX_FLOORS_MPLUS];
+	int ret;
+
+	this->numchips = 0;
+	this->mfr = 0;
+	this->id = 0;
+
+	/* For each floor, find the number of valid chips it contains */
+	for (floor = 0,ret = 1; floor < MAX_FLOORS_MPLUS; floor++) {
+		numchips[floor] = 0;
+		for (chip = 0; chip < MAX_CHIPS_MPLUS && ret != 0; chip++) {
+			ret = DoC_IdentChip(this, floor, chip);
+			if (ret) {
+				numchips[floor]++;
+				this->numchips++;
+			}
+		}
+	}
+	/* If there are none at all that we recognise, bail */
+	if (!this->numchips) {
+		printk("No flash chips recognised.\n");
+		return;
+	}
+
+	/* Allocate an array to hold the information for each chip */
+	this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL);
+	if (!this->chips){
+		printk("MTD: No memory for allocating chip info structures\n");
+		return;
+	}
+
+	/* Fill out the chip array with {floor, chipno} for each 
+	 * detected chip in the device. */
+	for (floor = 0, ret = 0; floor < MAX_FLOORS_MPLUS; floor++) {
+		for (chip = 0 ; chip < numchips[floor] ; chip++) {
+			this->chips[ret].floor = floor;
+			this->chips[ret].chip = chip;
+			this->chips[ret].curadr = 0;
+			this->chips[ret].curmode = 0x50;
+			ret++;
+		}
+	}
+
+	/* Calculate and print the total size of the device */
+	this->totlen = this->numchips * (1 << this->chipshift);
+	printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld MiB\n",
+	       this->numchips ,this->totlen >> 20);
+}
+
+static int DoCMilPlus_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
+{
+	int tmp1, tmp2, retval;
+
+	if (doc1->physadr == doc2->physadr)
+		return 1;
+
+	/* Use the alias resolution register which was set aside for this
+	 * purpose. If it's value is the same on both chips, they might
+	 * be the same chip, and we write to one and check for a change in
+	 * the other. It's unclear if this register is usuable in the
+	 * DoC 2000 (it's in the Millennium docs), but it seems to work. */
+	tmp1 = ReadDOC(doc1->virtadr, Mplus_AliasResolution);
+	tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
+	if (tmp1 != tmp2)
+		return 0;
+	
+	WriteDOC((tmp1+1) % 0xff, doc1->virtadr, Mplus_AliasResolution);
+	tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
+	if (tmp2 == (tmp1+1) % 0xff)
+		retval = 1;
+	else
+		retval = 0;
+
+	/* Restore register contents.  May not be necessary, but do it just to
+	 * be safe. */
+	WriteDOC(tmp1, doc1->virtadr, Mplus_AliasResolution);
+
+	return retval;
+}
+
+static const char im_name[] = "DoCMilPlus_init";
+
+/* This routine is made available to other mtd code via
+ * inter_module_register.  It must only be accessed through
+ * inter_module_get which will bump the use count of this module.  The
+ * addresses passed back in mtd are valid as long as the use count of
+ * this module is non-zero, i.e. between inter_module_get and
+ * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
+ */
+static void DoCMilPlus_init(struct mtd_info *mtd)
+{
+	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	struct DiskOnChip *old = NULL;
+
+	/* We must avoid being called twice for the same device. */
+	if (docmilpluslist)
+		old = (struct DiskOnChip *)docmilpluslist->priv;
+
+	while (old) {
+		if (DoCMilPlus_is_alias(this, old)) {
+			printk(KERN_NOTICE "Ignoring DiskOnChip Millennium "
+				"Plus at 0x%lX - already configured\n",
+				this->physadr);
+			iounmap((void *)this->virtadr);
+			kfree(mtd);
+			return;
+		}
+		if (old->nextdoc)
+			old = (struct DiskOnChip *)old->nextdoc->priv;
+		else
+			old = NULL;
+	}
+
+	mtd->name = "DiskOnChip Millennium Plus";
+	printk(KERN_NOTICE "DiskOnChip Millennium Plus found at "
+		"address 0x%lX\n", this->physadr);
+
+	mtd->type = MTD_NANDFLASH;
+	mtd->flags = MTD_CAP_NANDFLASH;
+	mtd->size = 0;
+
+	mtd->erasesize = 0;
+	mtd->oobblock = 512;
+	mtd->oobsize = 16;
+	mtd->module = THIS_MODULE;
+	mtd->erase = doc_erase;
+	mtd->point = NULL;
+	mtd->unpoint = NULL;
+	mtd->read = doc_read;
+	mtd->write = doc_write;
+	mtd->read_ecc = doc_read_ecc;
+	mtd->write_ecc = doc_write_ecc;
+	mtd->read_oob = doc_read_oob;
+	mtd->write_oob = doc_write_oob;
+	mtd->sync = NULL;
+
+	this->totlen = 0;
+	this->numchips = 0;
+	this->curfloor = -1;
+	this->curchip = -1;
+
+	/* Ident all the chips present. */
+	DoC_ScanChips(this);
+
+	if (!this->totlen) {
+		kfree(mtd);
+		iounmap((void *)this->virtadr);
+	} else {
+		this->nextdoc = docmilpluslist;
+		docmilpluslist = mtd;
+		mtd->size  = this->totlen;
+		mtd->erasesize = this->erasesize;
+		add_mtd_device(mtd);
+		return;
+	}
+}
+
+#if 0
+static int doc_dumpblk(struct mtd_info *mtd, loff_t from)
+{
+	int i;
+	loff_t fofs;
+	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	unsigned long docptr = this->virtadr;
+	struct Nand *mychip = &this->chips[from >> (this->chipshift)];
+	unsigned char *bp, buf[1056];
+	char c[32];
+
+	from &= ~0x3ff;
+
+	/* Don't allow read past end of device */
+	if (from >= this->totlen)
+		return -EINVAL;
+
+	DoC_CheckASIC(docptr);
+
+	/* Find the chip which is to be used and select it */
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(docptr, mychip->floor);
+		DoC_SelectChip(docptr, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(docptr, mychip->chip);
+	}
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
+	WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);
+
+	/* Reset the chip, see Software Requirement 11.4 item 1. */
+	DoC_Command(docptr, NAND_CMD_RESET, 0);
+	DoC_WaitReady(docptr);
+
+	fofs = from;
+	DoC_Command(docptr, DoC_GetDataOffset(mtd, &fofs), 0);
+	DoC_Address(this, 3, fofs, 0, 0x00);
+	WriteDOC(0, docptr, Mplus_FlashControl);
+	DoC_WaitReady(docptr);
+
+	/* disable the ECC engine */
+	WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
+
+	ReadDOC(docptr, Mplus_ReadPipeInit);
+	ReadDOC(docptr, Mplus_ReadPipeInit);
+
+	/* Read the data via the internal pipeline through CDSN IO
+	   register, see Pipelined Read Operations 11.3 */
+	MemReadDOC(docptr, buf, 1054);
+	buf[1054] = ReadDOC(docptr, Mplus_LastDataRead);
+	buf[1055] = ReadDOC(docptr, Mplus_LastDataRead);
+
+	memset(&c[0], 0, sizeof(c));
+	printk("DUMP OFFSET=%x:\n", (int)from);
+
+        for (i = 0, bp = &buf[0]; (i < 1056); i++) {
+                if ((i % 16) == 0)
+                        printk("%08x: ", i);
+                printk(" %02x", *bp);
+                c[(i & 0xf)] = ((*bp >= 0x20) && (*bp <= 0x7f)) ? *bp : '.';
+                bp++;
+                if (((i + 1) % 16) == 0)
+                        printk("    %s\n", c);
+        }
+	printk("\n");
+
+	/* Disable flash internally */
+	WriteDOC(0, docptr, Mplus_FlashSelect);
+
+	return 0;
+}
+#endif
+
+static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
+		    size_t *retlen, u_char *buf)
+{
+	/* Just a special case of doc_read_ecc */
+	return doc_read_ecc(mtd, from, len, retlen, buf, NULL, 0);
+}
+
+static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
+			size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel)
+{
+	int ret, i;
+	volatile char dummy;
+	loff_t fofs;
+	unsigned char syndrome[6];
+	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	unsigned long docptr = this->virtadr;
+	struct Nand *mychip = &this->chips[from >> (this->chipshift)];
+
+	/* Don't allow read past end of device */
+	if (from >= this->totlen)
+		return -EINVAL;
+
+	/* Don't allow a single read to cross a 512-byte block boundary */
+	if (from + len > ((from | 0x1ff) + 1)) 
+		len = ((from | 0x1ff) + 1) - from;
+
+	DoC_CheckASIC(docptr);
+
+	/* Find the chip which is to be used and select it */
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(docptr, mychip->floor);
+		DoC_SelectChip(docptr, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(docptr, mychip->chip);
+	}
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
+	WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);
+
+	/* Reset the chip, see Software Requirement 11.4 item 1. */
+	DoC_Command(docptr, NAND_CMD_RESET, 0);
+	DoC_WaitReady(docptr);
+
+	fofs = from;
+	DoC_Command(docptr, DoC_GetDataOffset(mtd, &fofs), 0);
+	DoC_Address(this, 3, fofs, 0, 0x00);
+	WriteDOC(0, docptr, Mplus_FlashControl);
+	DoC_WaitReady(docptr);
+
+	if (eccbuf) {
+		/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
+		WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
+		WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);
+	} else {
+		/* disable the ECC engine */
+		WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
+	}
+
+	/* Let the caller know we completed it */
+	*retlen = len;
+        ret = 0;
+
+	ReadDOC(docptr, Mplus_ReadPipeInit);
+	ReadDOC(docptr, Mplus_ReadPipeInit);
+
+	if (eccbuf) {
+		/* Read the data via the internal pipeline through CDSN IO
+		   register, see Pipelined Read Operations 11.3 */
+		MemReadDOC(docptr, buf, len);
+
+		/* Read the ECC data following raw data */
+		MemReadDOC(docptr, eccbuf, 4);
+		eccbuf[4] = ReadDOC(docptr, Mplus_LastDataRead);
+		eccbuf[5] = ReadDOC(docptr, Mplus_LastDataRead);
+
+		/* Flush the pipeline */
+		dummy = ReadDOC(docptr, Mplus_ECCConf);
+		dummy = ReadDOC(docptr, Mplus_ECCConf);
+
+		/* Check the ECC Status */
+		if (ReadDOC(docptr, Mplus_ECCConf) & 0x80) {
+                        int nb_errors;
+			/* There was an ECC error */
+#ifdef ECC_DEBUG
+			printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
+#endif
+			/* Read the ECC syndrom through the DiskOnChip ECC logic.
+			   These syndrome will be all ZERO when there is no error */
+			for (i = 0; i < 6; i++)
+				syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
+
+                        nb_errors = doc_decode_ecc(buf, syndrome);
+#ifdef ECC_DEBUG
+			printk("ECC Errors corrected: %x\n", nb_errors);
+#endif
+                        if (nb_errors < 0) {
+				/* We return error, but have actually done the read. Not that
+				   this can be told to user-space, via sys_read(), but at least
+				   MTD-aware stuff can know about it by checking *retlen */
+#ifdef ECC_DEBUG
+			printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n",
+				__FILE__, __LINE__, (int)from);
+			printk("        syndrome= %02x:%02x:%02x:%02x:%02x:"
+				"%02x\n",
+				syndrome[0], syndrome[1], syndrome[2],
+				syndrome[3], syndrome[4], syndrome[5]);
+			printk("          eccbuf= %02x:%02x:%02x:%02x:%02x:"
+				"%02x\n",
+				eccbuf[0], eccbuf[1], eccbuf[2],
+				eccbuf[3], eccbuf[4], eccbuf[5]);
+#endif
+				ret = -EIO;
+                        }
+		}
+
+#ifdef PSYCHO_DEBUG
+		printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
+		       (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
+		       eccbuf[4], eccbuf[5]);
+#endif
+
+		/* disable the ECC engine */
+		WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf);
+	} else {
+		/* Read the data via the internal pipeline through CDSN IO
+		   register, see Pipelined Read Operations 11.3 */
+		MemReadDOC(docptr, buf, len-2);
+		buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead);
+		buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead);
+	}
+
+	/* Disable flash internally */
+	WriteDOC(0, docptr, Mplus_FlashSelect);
+
+	return ret;
+}
+
+static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
+		     size_t *retlen, const u_char *buf)
+{
+	char eccbuf[6];
+	return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, 0);
+}
+
+static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
+			 size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel)
+{
+	int i, before, ret = 0;
+	loff_t fto;
+	volatile char dummy;
+	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	unsigned long docptr = this->virtadr;
+	struct Nand *mychip = &this->chips[to >> (this->chipshift)];
+
+	/* Don't allow write past end of device */
+	if (to >= this->totlen)
+		return -EINVAL;
+
+	/* Don't allow writes which aren't exactly one block (512 bytes) */
+	if ((to & 0x1ff) || (len != 0x200))
+		return -EINVAL;
+
+	/* Determine position of OOB flags, before or after data */
+	before = to & 0x200;
+
+	DoC_CheckASIC(docptr);
+
+	/* Find the chip which is to be used and select it */
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(docptr, mychip->floor);
+		DoC_SelectChip(docptr, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(docptr, mychip->chip);
+	}
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
+	WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);
+
+	/* Reset the chip, see Software Requirement 11.4 item 1. */
+	DoC_Command(docptr, NAND_CMD_RESET, 0);
+	DoC_WaitReady(docptr);
+
+	/* Set device to appropriate plane of flash */
+	fto = to;
+	WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd);
+
+	/* On interleaved devices the flags for 2nd half 512 are before data */
+	if (eccbuf && before)
+		fto -= 2;
+
+	/* issue the Serial Data In command to initial the Page Program process */
+	DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
+	DoC_Address(this, 3, fto, 0x00, 0x00);
+
+	/* Disable the ECC engine */
+	WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
+
+	if (eccbuf) {
+		if (before) {
+			/* Write the block status BLOCK_USED (0x5555) */
+			WriteDOC(0x55, docptr, Mil_CDSN_IO);
+			WriteDOC(0x55, docptr, Mil_CDSN_IO);
+		}
+
+		/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
+		WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);
+	}
+
+	MemWriteDOC(docptr, (unsigned char *) buf, len);
+
+	if (eccbuf) {
+		/* Write ECC data to flash, the ECC info is generated by
+		   the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */
+		DoC_Delay(docptr, 3);
+
+		/* Read the ECC data through the DiskOnChip ECC logic */
+		for (i = 0; i < 6; i++)
+			eccbuf[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
+
+		/* disable the ECC engine */
+		WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
+
+		/* Write the ECC data to flash */
+		MemWriteDOC(docptr, eccbuf, 6);
+
+		if (!before) {
+			/* Write the block status BLOCK_USED (0x5555) */
+			WriteDOC(0x55, docptr, Mil_CDSN_IO+6);
+			WriteDOC(0x55, docptr, Mil_CDSN_IO+7);
+		}
+
+#ifdef PSYCHO_DEBUG
+		printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
+		       (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
+		       eccbuf[4], eccbuf[5]);
+#endif
+	}
+
+	WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
+	WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
+
+	/* Commit the Page Program command and wait for ready
+	   see Software Requirement 11.4 item 1.*/
+	DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
+	DoC_WaitReady(docptr);
+
+	/* Read the status of the flash device through CDSN IO register
+	   see Software Requirement 11.4 item 5.*/
+	DoC_Command(docptr, NAND_CMD_STATUS, 0);
+	dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
+	dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
+	DoC_Delay(docptr, 2);
+	if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
+		printk("MTD: Error 0x%x programming at 0x%x\n", dummy, (int)to);
+		/* Error in programming
+		   FIXME: implement Bad Block Replacement (in nftl.c ??) */
+		*retlen = 0;
+		ret = -EIO;
+	}
+	dummy = ReadDOC(docptr, Mplus_LastDataRead);
+
+	/* Disable flash internally */
+	WriteDOC(0, docptr, Mplus_FlashSelect);
+
+	/* Let the caller know we completed it */
+	*retlen = len;
+
+	return ret;
+}
+
+static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+			size_t *retlen, u_char *buf)
+{
+	loff_t fofs, base;
+	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	unsigned long docptr = this->virtadr;
+	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
+	size_t i, size, got, want;
+
+	DoC_CheckASIC(docptr);
+
+	/* Find the chip which is to be used and select it */
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(docptr, mychip->floor);
+		DoC_SelectChip(docptr, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(docptr, mychip->chip);
+	}
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
+	WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);
+
+	/* disable the ECC engine */
+	WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
+	DoC_WaitReady(docptr);
+
+	/* Maximum of 16 bytes in the OOB region, so limit read to that */
+	if (len > 16)
+		len = 16;
+	got = 0;
+	want = len;
+
+	for (i = 0; ((i < 3) && (want > 0)); i++) {
+		/* Figure out which region we are accessing... */
+		fofs = ofs;
+		base = ofs & 0xf;
+		if (base < 6) {
+			DoC_Command(docptr, DoC_GetECCOffset(mtd, &fofs), 0);
+			size = 6 - base;
+		} else if (base < 8) {
+			DoC_Command(docptr, DoC_GetFlagsOffset(mtd, &fofs), 0);
+			size = 8 - base;
+		} else {
+			DoC_Command(docptr, DoC_GetHdrOffset(mtd, &fofs), 0);
+			size = 16 - base;
+		}
+		if (size > want)
+			size = want;
+
+		/* Issue read command */
+		DoC_Address(this, 3, fofs, 0, 0x00);
+		WriteDOC(0, docptr, Mplus_FlashControl);
+		DoC_WaitReady(docptr);
+
+		ReadDOC(docptr, Mplus_ReadPipeInit);
+		ReadDOC(docptr, Mplus_ReadPipeInit);
+		MemReadDOC(docptr, &buf[got], size - 2);
+		buf[got + size - 2] = ReadDOC(docptr, Mplus_LastDataRead);
+		buf[got + size - 1] = ReadDOC(docptr, Mplus_LastDataRead);
+
+		ofs += size;
+		got += size;
+		want -= size;
+	}
+
+	/* Disable flash internally */
+	WriteDOC(0, docptr, Mplus_FlashSelect);
+
+	*retlen = len;
+	return 0;
+}
+
+static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+			 size_t *retlen, const u_char *buf)
+{
+	volatile char dummy;
+	loff_t fofs, base;
+	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	unsigned long docptr = this->virtadr;
+	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
+	size_t i, size, got, want;
+	int ret = 0;
+
+	DoC_CheckASIC(docptr);
+
+	/* Find the chip which is to be used and select it */
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(docptr, mychip->floor);
+		DoC_SelectChip(docptr, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(docptr, mychip->chip);
+	}
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
+	WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);
+
+
+	/* Maximum of 16 bytes in the OOB region, so limit write to that */
+	if (len > 16)
+		len = 16;
+	got = 0;
+	want = len;
+
+	for (i = 0; ((i < 3) && (want > 0)); i++) {
+		/* Reset the chip, see Software Requirement 11.4 item 1. */
+		DoC_Command(docptr, NAND_CMD_RESET, 0);
+		DoC_WaitReady(docptr);
+
+		/* Figure out which region we are accessing... */
+		fofs = ofs;
+		base = ofs & 0x0f;
+		if (base < 6) {
+			WriteDOC(DoC_GetECCOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
+			size = 6 - base;
+		} else if (base < 8) {
+			WriteDOC(DoC_GetFlagsOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
+			size = 8 - base;
+		} else {
+			WriteDOC(DoC_GetHdrOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
+			size = 16 - base;
+		}
+		if (size > want)
+			size = want;
+
+		/* Issue the Serial Data In command to initial the Page Program process */
+		DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
+		DoC_Address(this, 3, fofs, 0, 0x00);
+
+		/* Disable the ECC engine */
+		WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
+
+		/* Write the data via the internal pipeline through CDSN IO
+		   register, see Pipelined Write Operations 11.2 */
+		MemWriteDOC(docptr, (unsigned char *) &buf[got], size);
+		WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
+		WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
+
+		/* Commit the Page Program command and wait for ready
+	 	   see Software Requirement 11.4 item 1.*/
+		DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
+		DoC_WaitReady(docptr);
+
+		/* Read the status of the flash device through CDSN IO register
+		   see Software Requirement 11.4 item 5.*/
+		DoC_Command(docptr, NAND_CMD_STATUS, 0x00);
+		dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
+		dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
+		DoC_Delay(docptr, 2);
+		if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
+			printk("MTD: Error 0x%x programming oob at 0x%x\n",
+				dummy, (int)ofs);
+			/* FIXME: implement Bad Block Replacement */
+			*retlen = 0;
+			ret = -EIO;
+		}
+		dummy = ReadDOC(docptr, Mplus_LastDataRead);
+
+		ofs += size;
+		got += size;
+		want -= size;
+	}
+
+	/* Disable flash internally */
+	WriteDOC(0, docptr, Mplus_FlashSelect);
+
+	*retlen = len;
+	return ret;
+}
+
+int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	volatile char dummy;
+	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	__u32 ofs = instr->addr;
+	__u32 len = instr->len;
+	unsigned long docptr = this->virtadr;
+	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
+
+	DoC_CheckASIC(docptr);
+
+	if (len != mtd->erasesize) 
+		printk(KERN_WARNING "MTD: Erase not right size (%x != %x)n",
+		       len, mtd->erasesize);
+
+	/* Find the chip which is to be used and select it */
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(docptr, mychip->floor);
+		DoC_SelectChip(docptr, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(docptr, mychip->chip);
+	}
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	instr->state = MTD_ERASE_PENDING;
+
+	/* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
+	WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);
+
+	DoC_Command(docptr, NAND_CMD_RESET, 0x00);
+	DoC_WaitReady(docptr);
+
+	DoC_Command(docptr, NAND_CMD_ERASE1, 0);
+	DoC_Address(this, 2, ofs, 0, 0x00);
+	DoC_Command(docptr, NAND_CMD_ERASE2, 0);
+	DoC_WaitReady(docptr);
+	instr->state = MTD_ERASING;
+
+	/* Read the status of the flash device through CDSN IO register
+	   see Software Requirement 11.4 item 5. */
+	DoC_Command(docptr, NAND_CMD_STATUS, 0);
+	dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
+	dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
+	if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
+		printk("MTD: Error 0x%x erasing at 0x%x\n", dummy, ofs);
+		/* FIXME: implement Bad Block Replacement (in nftl.c ??) */
+		instr->state = MTD_ERASE_FAILED;
+	} else {
+		instr->state = MTD_ERASE_DONE;
+	}
+	dummy = ReadDOC(docptr, Mplus_LastDataRead);
+
+	/* Disable flash internally */
+	WriteDOC(0, docptr, Mplus_FlashSelect);
+
+	if (instr->callback) 
+		instr->callback(instr);
+
+	return 0;
+}
+
+/****************************************************************************
+ *
+ * Module stuff
+ *
+ ****************************************************************************/
+
+int __init init_doc2001plus(void)
+{
+	inter_module_register(im_name, THIS_MODULE, &DoCMilPlus_init);
+	return 0;
+}
+
+static void __exit cleanup_doc2001plus(void)
+{
+	struct mtd_info *mtd;
+	struct DiskOnChip *this;
+
+	while ((mtd=docmilpluslist)) {
+		this = (struct DiskOnChip *)mtd->priv;
+		docmilpluslist = this->nextdoc;
+			
+		del_mtd_device(mtd);
+			
+		iounmap((void *)this->virtadr);
+		kfree(this->chips);
+		kfree(mtd);
+	}
+	inter_module_unregister(im_name);
+}
+
+module_exit(cleanup_doc2001plus);
+module_init(init_doc2001plus);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com> et al.");
+MODULE_DESCRIPTION("Driver for DiskOnChip Millennium Plus");
diff -urN linux-2.4.29/drivers/mtd/devices/docprobe.c linux-2.4.29-uc1/drivers/mtd/devices/docprobe.c
--- linux-2.4.29/drivers/mtd/devices/docprobe.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/devices/docprobe.c	2005-06-14 02:12:08.000000000 +0100
@@ -40,7 +40,10 @@
    a Millennium enough that they go through and work out what the 
    difference is :)
 */
+#include <linux/config.h>
+#ifndef CONFIG_SH_SECUREEDGE5410
 #define DOC_SINGLE_DRIVER
+#endif
 
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -92,17 +95,26 @@
         0xff000000,
 #elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C)
         0xff000000,
-##else
+#elif defined(CONFIG_SH_SECUREEDGE5410)
+	0x00000000,
+	0x04000000,
+#elif defined(CONFIG_SECUREEDGEMP3)
+	0xe0000000,
+#elif defined(CONFIG_NETtel)
+	0x30c00000,
+#elif defined(CONFIG_MACH_ESS710) || defined(CONFIG_MACH_SE5100)
+	0x50000000,
+#else
 #warning Unknown architecture for DiskOnChip. No default probe locations defined
 #endif
-	0 };
+	0xffffffff };
 
 /* doccheck: Probe a given memory window to see if there's a DiskOnChip present */
 
 static inline int __init doccheck(unsigned long potential, unsigned long physadr)
 {
 	unsigned long window=potential;
-	unsigned char tmp, ChipID;
+	unsigned char tmp, tmpb, tmpc, ChipID;
 #ifndef DOC_PASSIVE_PROBE
 	unsigned char tmp2;
 #endif
@@ -145,19 +157,65 @@
 	switch (ChipID) {
 	case DOC_ChipID_Doc2k:
 		/* Check the TOGGLE bit in the ECC register */
-		tmp = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
-		if ((ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT) != tmp)
+		tmp  = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
+		tmpb = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
+		tmpc = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
+		if (tmp != tmpb && tmp == tmpc)
 				return ChipID;
 		break;
 		
 	case DOC_ChipID_DocMil:
 		/* Check the TOGGLE bit in the ECC register */
-		tmp = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
-		if ((ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT) != tmp)
+		tmp  = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
+		tmpb = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
+		tmpc = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
+		if (tmp != tmpb && tmp == tmpc)
 				return ChipID;
 		break;
 		
+	case DOC_ChipID_DocMilPlus16:
+	case DOC_ChipID_DocMilPlus32:
+	case 0:
+		/* Possible Millennium+, need to do more checks */
+#ifndef DOC_PASSIVE_PROBE
+		/* Possibly release from power down mode */
+		for (tmp = 0; (tmp < 4); tmp++)
+			ReadDOC(window, Mplus_Power);
+
+		/* Reset the DiskOnChip ASIC */
+		tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
+			DOC_MODE_BDECT;
+		WriteDOC(tmp, window, Mplus_DOCControl);
+		WriteDOC(~tmp, window, Mplus_CtrlConfirm);
+	
+		mdelay(1);
+		/* Enable the DiskOnChip ASIC */
+		tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
+			DOC_MODE_BDECT;
+		WriteDOC(tmp, window, Mplus_DOCControl);
+		WriteDOC(~tmp, window, Mplus_CtrlConfirm);
+		mdelay(1);
+#endif /* !DOC_PASSIVE_PROBE */	
+
+		ChipID = ReadDOC(window, ChipID);
+
+		switch (ChipID) {
+		case DOC_ChipID_DocMilPlus16:
+		case DOC_ChipID_DocMilPlus32:
+			/* Check the TOGGLE bit in the toggle register */
+			tmp  = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT;
+			tmpb = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT;
+			tmpc = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT;
+			if (tmp != tmpb && tmp == tmpc)
+					return ChipID;
+			break;
+		default:
+			break;
+		}
+		/* FALL TRHU */
+
 	default:
+
 #ifndef CONFIG_MTD_DOCPROBE_55AA
 		printk(KERN_WARNING "Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n",
 		       ChipID, physadr);
@@ -237,6 +295,13 @@
 			im_modname = "doc2001";
 #endif /* DOC_SINGLE_DRIVER */
 			break;
+
+		case DOC_ChipID_DocMilPlus16:
+		case DOC_ChipID_DocMilPlus32:
+			name="MillenniumPlus";
+			im_funcname = "DoCMilPlus_init";
+			im_modname = "doc2001plus";
+			break;
 		}
 
 		if (im_funcname)
@@ -267,7 +332,7 @@
 		printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location);
 		DoC_Probe(doc_config_location);
 	} else {
-		for (i=0; doc_locations[i]; i++) {
+		for (i=0; (doc_locations[i] != 0xffffffff); i++) {
 			DoC_Probe(doc_locations[i]);
 		}
 	}
diff -urN linux-2.4.29/drivers/mtd/devices/Makefile linux-2.4.29-uc1/drivers/mtd/devices/Makefile
--- linux-2.4.29/drivers/mtd/devices/Makefile	2002-11-28 23:53:13.000000000 +0000
+++ linux-2.4.29-uc1/drivers/mtd/devices/Makefile	2005-06-14 02:12:08.000000000 +0100
@@ -15,12 +15,15 @@
 obj-$(CONFIG_MTD_DOC1000)	+= doc1000.o
 obj-$(CONFIG_MTD_DOC2000)	+= doc2000.o
 obj-$(CONFIG_MTD_DOC2001)	+= doc2001.o
+obj-$(CONFIG_MTD_DOC2001PLUS)	+= doc2001plus.o
 obj-$(CONFIG_MTD_DOCPROBE)	+= docprobe.o docecc.o
 obj-$(CONFIG_MTD_SLRAM)		+= slram.o
 obj-$(CONFIG_MTD_PMC551)	+= pmc551.o
 obj-$(CONFIG_MTD_MS02NV)	+= ms02-nv.o
 obj-$(CONFIG_MTD_MTDRAM)	+= mtdram.o
+obj-$(CONFIG_MTD_MTDCNXT)	+= mtdcnxt.o
 obj-$(CONFIG_MTD_LART)		+= lart.o
 obj-$(CONFIG_MTD_BLKMTD)	+= blkmtd.o
+obj-$(CONFIG_MTD_CFM)		+= cfm.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/mtd/devices/mtdcnxt.c linux-2.4.29-uc1/drivers/mtd/devices/mtdcnxt.c
--- linux-2.4.29/drivers/mtd/devices/mtdcnxt.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/devices/mtdcnxt.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,356 @@
+/*
+ * mtdcnxt - a hack for read/write-access to a small chunk of
+ * flash space via the conexant flash routines CnxtFlashOpen(),
+ * CnxtFlashReadRequest() and CnxtFlashWriteRequest()
+ *
+ * Please note that whenever you read or write to the device 
+ * (/dev/mtdc0), the flash is not directly accessed, but a copy
+ * of the data in RAM is modified
+ * To actually write the content to flash you have to write the string
+ * "SaveToFlash" to /dev/mtdc0 (e.g. by executing
+ * "echo SaveToFlash >/dev/mtdc0" at the shell prompt)
+ * Likewise to read the flash and copy it into the RAM buffer,
+ * write "ReadFrFlash" to /dev/mtdc0; also note that this is NOT
+ * automatically done at device startup, so before you make changes
+ * to the data, issue the read command
+ * As this method of flash rw-access mixes up data and commands,
+ * i regard it as an HACK
+ *
+ * In addition to the flash access, also the modem LED and the modem
+ * reset is controlled via this device:
+ * echo "ResetModem***" >/dev/mtdc0 -- will reset the modem
+ * echo "LedOn***" >/dev/mtdc0      -- will turn the modem LED on
+ * echo "LedOff***" >/dev/mtdc0     -- will turn the modem LED off
+ *
+ * This code is heavily based on mtdram.c and has been extended
+ * by Actiontec (http://www.actiontec.com/) for their Dual PC Modem
+ *
+ * It's noteworthy that Actiontec never officially released this
+ * code (it's NOT part of their DPCM GPL release); the file has
+ * been posted by Bruce D. Lightner <lightner@lightner.net> to
+ * the ActionHack Mailing List (ActionHack@express.org, archive
+ * at http://www.express.org/mailman/listinfo/actionhack) as part
+ * of his DualPcModemGplPatch; he declared the source of the file
+ * as unspecified and he also noted that the "This code is GPL"
+ * notice in the file has been deleted (probably be Actiontec); but
+ * as the code is clearly derived from GPL code it's of course
+ * still GPL
+ *
+ * Author: Alexander Larsson <alex@cendio.se>
+ * Conexant flash hack by: Actiontec (http://www.actiontec.com/)
+ * Code origin notice and cleanups by: Johann Hanne <jhml@gmx.net>
+ *
+ * Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
+ * Copyright (c) 2003 Actiontec (http://www.actiontec.com/)
+ * Copyright (c) 2005 Johann Hanne <jhml@gmx.net>
+ *
+ * This code is GPL
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/mtd/compatmac.h>
+#include <linux/mtd/mtd.h>
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/cnxtflash.h>
+#include <asm/arch/gpio.h>
+
+#define SUPPORT_SST_FLASH
+
+#include <asm/io.h>
+
+#define MTDCNXT_TOTAL_SIZE 2048
+#define MTDCNXT_ERASE_SIZE 1024
+
+/* We could store these in the mtd structure, but we only support 1 device */
+static struct mtd_info *mtd_info;
+
+static int ram_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+  DEBUG(MTD_DEBUG_LEVEL2, "ram_erase(pos:%ld, len:%ld)\n", (long)instr->addr, (long)instr->len);
+  if (instr->addr + instr->len > mtd->size) {
+    DEBUG(MTD_DEBUG_LEVEL1, "ram_erase() out of bounds (%ld > %ld)\n", (long)(instr->addr + instr->len), (long)mtd->size);
+    return -EINVAL;
+  }
+	
+  memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
+	
+  instr->state = MTD_ERASE_DONE;
+
+  if (instr->callback)
+    (*(instr->callback))(instr);
+  return 0;
+}
+
+static int ram_point(struct mtd_info *mtd, loff_t from, size_t len,
+                     size_t *retlen, u_char **mtdbuf)
+{
+  if (from + len > mtd->size)
+    return -EINVAL;
+	
+  *mtdbuf = mtd->priv + from;
+  *retlen = len;
+  return 0;
+}
+
+static void ram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from,
+                        size_t len)
+{
+  DEBUG(MTD_DEBUG_LEVEL2, "ram_unpoint\n");
+}
+
+static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
+                    size_t *retlen, u_char *buf)
+{
+  DEBUG(MTD_DEBUG_LEVEL2, "ram_read(pos:%ld, len:%ld)\n", (long)from, (long)len);
+  if (from + len > mtd->size) {
+    DEBUG(MTD_DEBUG_LEVEL1, "ram_read() out of bounds (%ld > %ld)\n", (long)(from + len), (long)mtd->size);
+    return -EINVAL;
+  }
+
+  memcpy(buf, mtd->priv + from, len);
+
+  *retlen=len;
+  return 0;
+}
+
+/*
+ * ACTIONTEC IMPORTANT NOTICE:
+ *
+ * Don't expect you can read full 2 * 1024 bytes, because you will lose 
+ * sizeof(CNXT_FLASH_SEGMENT_T) == about 128 bytes
+ *
+ * But we don't give any failed to read msg.
+ * So the maximum size is about
+ *      2 * 1024 - 128 bytes
+ */
+static char savetoflash[]="SaveToFlash";
+static char readfrflash[]="ReadFrFlash";
+static char resetmodem[]="ResetModem***";
+static char ledon[]="LedOn***";
+static char ledoff[]="LedOff***";
+static int ram_write(struct mtd_info *mtd, loff_t to, size_t len,
+                     size_t *retlen, const u_char *buf)
+{
+  CNXT_FLASH_STATUS_E flashStatus;
+  CNXT_FLASH_SEGMENT_E segment = CNXT_FLASH_SEGMENT_3;
+
+  DEBUG(MTD_DEBUG_LEVEL2, "ram_write(pos:%ld, len:%ld)\n", (long)to, (long)len);
+  if (to + len > mtd->size) {
+    DEBUG(MTD_DEBUG_LEVEL1, "ram_write() out of bounds (%ld > %ld)\n", (long)(to + len), (long)mtd->size);
+    return -EINVAL;
+  }
+
+  DEBUG(MTD_DEBUG_LEVEL2, "mtdcnxt write: '%s'\n", buf);
+
+  if (strstr(buf, ledon)) {
+    WriteGPIOData(GPIO19, 0);
+    DEBUG(MTD_DEBUG_LEVEL2, "Modem LED ON\n");
+    memset(buf,'\0',len);
+    *retlen=len;
+    return 0;
+  }
+
+  if (strstr(buf, ledoff)) {
+    WriteGPIOData(GPIO19, 1);
+    DEBUG(MTD_DEBUG_LEVEL2, "Modem LED OFF\n");
+    memset(buf,'\0',len);
+    *retlen=len;
+    return 0;
+  }
+
+#define LED_DELAY_PERIOD 30 /* should be 15/25 mapping reset / ready */
+
+  if (strstr(buf, resetmodem)) {
+    /* GPIO17 is used for modem reset for TIBURON */
+    WriteGPIOData(GPIO17, 0);
+    TaskDelayMsec(LED_DELAY_PERIOD);
+    DEBUG(MTD_DEBUG_LEVEL2, "Modem reset\n");
+    WriteGPIOData(GPIO17, 1);
+    TaskDelayMsec(LED_DELAY_PERIOD);
+    memset(buf,'\0',len);
+    *retlen=len;
+    return 0;
+  }
+
+  if (strstr(buf, savetoflash)) {
+
+try_avoid_CRC_error:
+
+    flashStatus = CnxtFlashOpen(segment);
+
+    switch (flashStatus) {
+    case CNXT_FLASH_DATA_ERROR:
+      printk("Open to Flash Data Error (Open in mtdc for write): "
+             "CNXT_FLASH_SEGMENT_%d\n", segment+1);
+      break;
+
+    case CNXT_FLASH_DATA_CRC_ERROR:
+      printk("Open to Flash Data CRC Error (Open in mtdc for write): "
+             "CNXT_FLASH_SEGMENT_%d\n", segment+1);
+      flashStatus = CnxtFlashWriteRequest(
+                                          segment, 
+                                          (UINT16 *)mtd->priv,
+                                          (MTDCNXT_TOTAL_SIZE)
+                                         );
+      goto try_avoid_CRC_error;
+      break;
+
+    case CNXT_FLASH_DATA_SIZE_ERROR:
+      printk("Open to Flash Data SIZE Error (Open in mtdc for write): "
+             "CNXT_FLASH_SEGMENT_%d\n", segment+1);
+      break;
+
+    case CNXT_FLASH_OWNER_ERROR:
+      printk("Open to Wrong owner for requested Flash Segment!\n");
+      break;
+
+    default:
+      DEBUG(MTD_DEBUG_LEVEL2, "Open to Flash Data Success: "
+            "CNXT_FLASH_SEGMENT_%d\n", segment+1);
+    }
+
+    while (CnxtFlashWriteRequest(segment, (UINT16 *)mtd->priv,
+                                 MTDCNXT_TOTAL_SIZE)==FALSE) {
+      printk("Error writing to flash, trying again\n");
+    }
+    memset(buf, '\0', len);
+    /* We must return here, otherwise we will overwrite the data with
+       the write command */
+    *retlen=len;
+    return 0;
+  }
+
+  if (strstr(buf, readfrflash)) {
+
+    flashStatus = CnxtFlashOpen(segment);
+
+    switch (flashStatus) {
+    case CNXT_FLASH_DATA_CRC_ERROR:
+      printk("Open to Flash Data CRC Error (Open in mtdc for read): "
+             "CNXT_FLASH_SEGMENT_%d\n", segment+1);
+      break;
+
+    case CNXT_FLASH_DATA_SIZE_ERROR:
+      printk("Open to Flash Data SIZE Error (Open in mtdc for read): "
+             "CNXT_FLASH_SEGMENT_%d\n", segment+1);
+      break;
+
+    case CNXT_FLASH_DATA_ERROR:
+      printk("Open to Flash Data Error (Open in mtdc for read): "
+             "CNXT_FLASH_SEGMENT_%d\n", segment+1);
+      break;
+
+    case CNXT_FLASH_OWNER_ERROR:
+      printk("Open to Wrong owner for requested Flash Segment!\n");
+      break;
+
+    default:
+      DEBUG(MTD_DEBUG_LEVEL2, "Open to Flash Data Success: "
+            "CNXT_FLASH_SEGMENT_%d\n", segment+1);
+    }
+
+    while (CnxtFlashReadRequest(segment, (UINT16 *)mtd->priv,
+                                MTDCNXT_TOTAL_SIZE)==FALSE) {
+      printk("Error reading from flash, trying again\n");
+    }
+    memset(buf, '\0', len);
+    /* We must return here, otherwise we will overwrite the data with
+       the read command */
+    *retlen=len;
+    return 0;
+  }
+
+  memcpy ((char *)mtd->priv + to, buf, len);
+
+  *retlen=len;
+  return 0;
+}
+
+static void __exit cleanup_mtdcnxt(void)
+{
+  if (mtd_info) {
+    del_mtd_device(mtd_info);
+    if (mtd_info->priv)
+      vfree(mtd_info->priv);
+    kfree(mtd_info);
+  }
+}
+
+int mtdcnxt_init_device(struct mtd_info *mtd, void *mapped_address, 
+                       unsigned long size, char *name)
+{
+   memset(mtd, 0, sizeof(*mtd));
+
+   /* Setup the MTD structure */
+   mtd->name = name;
+   mtd->type = MTD_RAM;
+   mtd->flags = MTD_CAP_RAM;
+   mtd->size = size;
+   mtd->erasesize = MTDCNXT_ERASE_SIZE;
+   mtd->priv = mapped_address;
+
+   mtd->module = THIS_MODULE;
+   mtd->erase = ram_erase;
+   mtd->point = ram_point;
+   mtd->unpoint = ram_unpoint;
+   mtd->read = ram_read;
+   mtd->write = ram_write;
+
+   if (add_mtd_device(mtd)) {
+     return -EIO;
+   }
+   
+   return 0;
+}
+
+int __init init_mtdcnxt(void)
+{
+  void *addr;
+  int err;
+
+  /* Just for init flash */
+  CNXT_FLASH_STATUS_E flashStatus;
+  CNXT_FLASH_SEGMENT_E segment = CNXT_FLASH_SEGMENT_3;
+
+#ifdef SUPPORT_SST_FLASH
+  setBootsectorBlocksize();
+#endif /* SUPPORT_SST_FLASH */
+  flashStatus = CnxtFlashOpen(segment);
+
+  /* Allocate some memory */
+  mtd_info = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
+  if (!mtd_info)
+    return -ENOMEM;
+
+  addr = vmalloc(MTDCNXT_TOTAL_SIZE);
+  if (!addr) {
+    DEBUG(MTD_DEBUG_LEVEL1, 
+          "Failed to vmalloc memory region of size %ld\n", 
+          (long)MTDCNXT_TOTAL_SIZE);
+    kfree(mtd_info);
+    mtd_info = NULL;
+    return -ENOMEM;
+  }
+  err = mtdcnxt_init_device(mtd_info, addr, 
+                           MTDCNXT_TOTAL_SIZE, "mtdcnxt device");
+  if (err) 
+  {
+    vfree(addr);
+    kfree(mtd_info);
+    mtd_info = NULL;
+    return err;
+  }
+  memset(mtd_info->priv, 0xff, MTDCNXT_TOTAL_SIZE);
+  return err;
+}
+
+module_init(init_mtdcnxt);
+module_exit(cleanup_mtdcnxt);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexander Larsson <alexl@redhat.com>");
+MODULE_DESCRIPTION("Read/write-access to conexant controlled flash");
diff -urN linux-2.4.29/drivers/mtd/inftlcore.c linux-2.4.29-uc1/drivers/mtd/inftlcore.c
--- linux-2.4.29/drivers/mtd/inftlcore.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/inftlcore.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,1255 @@
+/* 
+ * inftlcore.c -- Linux driver for Inverse Flash Translation Layer (INFTL)
+ *
+ * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
+ *
+ * Based heavily on the inftlcore.c code which is:
+ * (c) 1999 Machine Vision Holdings, Inc.
+ * Author: David Woodhouse <dwmw2@infradead.org>
+ *
+ * $Id: inftlcore.c,v 1.13 2003/10/07 07:04:16 gerg Exp $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/kmod.h>
+#include <linux/hdreg.h>
+#include <linux/blkpg.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nftl.h>
+#include <linux/mtd/inftl.h>
+#include <asm/uaccess.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+
+/*
+ * Maximum number of loops while examining next block, to have a
+ * chance to detect consistency problems (they should never happen
+ * because of the checks done in the mounting.
+ */
+#define MAX_LOOPS 10000
+
+/* INFTL block device stuff */
+#define MAJOR_NR INFTL_MAJOR
+#define DEVICE_OFF(device)
+
+#include <linux/blk.h>
+#include <linux/hdreg.h>
+
+/*
+ * There is some confusion as to what major inftl actually can use.
+ */
+#undef DEVICE_REQUEST
+#undef DEVICE_NR
+#define DEVICE_REQUEST inftl_request
+#define	DEVICE_NR(device) (MINOR(device) >> PARTN_BITS)
+
+
+extern void INFTL_dumptables(struct INFTLrecord *inftl);
+extern void INFTL_dumpVUchains(struct INFTLrecord *inftl);
+
+
+/* Linux-specific block device functions */
+
+/* I _HATE_ the Linux block device setup more than anything else I've ever
+ *  encountered, except ...
+ */
+
+static int inftl_sizes[256];
+static int inftl_blocksizes[256];
+
+/* .. for the Linux partition table handling. */
+static struct hd_struct part_table[256];
+
+static struct gendisk inftl_gendisk = {
+	.major =	MAJOR_NR,
+	.major_name =	"inftl",
+	.minor_shift =	INFTL_PARTN_BITS, /* Bits to shift to get real from partition */
+	.max_p =	(1<<INFTL_PARTN_BITS)-1, /* Number of partitions per real */
+	.part =		part_table,     /* hd struct */
+	.sizes =	inftl_sizes,     /* block sizes */
+};
+
+struct INFTLrecord *INFTLs[MAX_INFTLS];
+
+static void INFTL_setup(struct mtd_info *mtd)
+{
+	int i;
+	struct INFTLrecord *inftl;
+	unsigned long temp;
+	int firstfree = -1;
+
+	DEBUG(MTD_DEBUG_LEVEL1, "INFTL: INFTL_setup()\n");
+
+	for (i = 0; i < MAX_INFTLS; i++) {
+		if (!INFTLs[i] && firstfree == -1)
+			firstfree = i;
+		else if (INFTLs[i] && INFTLs[i]->mtd == mtd) {
+			/*
+			 * This is a Spare Media Header for an INFTL we've
+			 * already found.
+			 */
+			DEBUG(MTD_DEBUG_LEVEL1, "INFTL: MTD already mounted "
+				"as INFTL\n");
+			return;
+		}
+	}
+        if (firstfree == -1) {
+		printk(KERN_WARNING "INFTL: No more INFTL slots available\n");
+		return;
+        }
+
+	inftl = kmalloc(sizeof(struct INFTLrecord), GFP_KERNEL);
+	if (!inftl) {
+		printk(KERN_WARNING "INFTL: out of memory for INFTL data "
+			"structures\n");
+		return;
+	}
+
+	init_MUTEX(&inftl->mutex);
+	inftl->mtd = mtd;
+
+        if (INFTL_mount(inftl) < 0) {
+		printk(KERN_WARNING "INFTL:cCould not mount INFTL device\n");
+		kfree(inftl);
+		return;
+        }
+
+	/* OK, it's a new one. Set up all the data structures. */
+#ifdef PSYCHO_DEBUG
+	printk("INFTL: found new INFTL inftl%c\n", firstfree + 'a');
+#endif
+
+        /* linux stuff */
+	inftl->usecount = 0;
+	inftl->cylinders = 1024;
+	inftl->heads = 16;
+
+	temp = inftl->cylinders * inftl->heads;
+	inftl->sectors = inftl->nr_sects / temp;
+	if (inftl->nr_sects % temp) {
+		inftl->sectors++;
+		temp = inftl->cylinders * inftl->sectors;
+		inftl->heads = inftl->nr_sects / temp;
+
+		if (inftl->nr_sects % temp) {
+			inftl->heads++;
+			temp = inftl->heads * inftl->sectors;
+			inftl->cylinders = inftl->nr_sects / temp;
+		}
+	}
+
+	if (inftl->nr_sects != inftl->heads*inftl->cylinders*inftl->sectors) {
+		printk(KERN_WARNING "INFTL: cannot calculate an INFTL "
+			"geometry to match size of 0x%x.\n",
+			(int)inftl->nr_sects);
+		printk(KERN_WARNING "INFTL: Using C:%d H:%d S:%d (== 0x%lx "
+			"sects)\n", inftl->cylinders, inftl->heads,
+			inftl->sectors, (long)inftl->cylinders *
+			(long)inftl->heads * (long)inftl->sectors );
+
+		/*
+		 * Oh no we don't have inftl->nr_sects = inftl->heads *
+		 * inftl->cylinders * inftl->sectors;
+		 */
+	}
+	INFTLs[firstfree] = inftl;
+	/* Finally, set up the block device sizes */
+	inftl_sizes[firstfree * 16] = inftl->nr_sects;
+	//nftl_blocksizes[firstfree*16] = 512;
+	part_table[firstfree * 16].nr_sects = inftl->nr_sects;
+
+	inftl_gendisk.nr_real++;
+
+	/* partition check ... */
+	grok_partitions(&inftl_gendisk, firstfree, 1 << INFTL_PARTN_BITS,
+		inftl->nr_sects);
+}
+
+static void INFTL_unsetup(int i)
+{
+	struct INFTLrecord *inftl = INFTLs[i];
+
+	DEBUG(MTD_DEBUG_LEVEL1, "INFTL: INFTL_unsetup(%d)\n", i);
+	
+	INFTLs[i] = NULL;
+	
+	if (inftl->PUtable)
+		kfree(inftl->PUtable);
+	if (inftl->VUtable)
+		kfree(inftl->VUtable);
+		      
+	inftl_gendisk.nr_real--;
+	kfree(inftl);
+}
+
+/*
+ * Search the MTD device for INFTL partitions
+ */
+static void INFTL_notify_add(struct mtd_info *mtd)
+{
+	DEBUG(MTD_DEBUG_LEVEL1, "INFTL: INFTL_notify_add(%s)\n", mtd->name);
+
+	if (mtd) {
+		if (!mtd->read_oob) {
+			/*
+			 * If this MTD doesn't have out-of-band data,
+			 * then there's no point continuing.
+			 */
+			DEBUG(MTD_DEBUG_LEVEL1, "INFTL: no OOB data, quitting\n");
+			return;
+		}
+		DEBUG(MTD_DEBUG_LEVEL3, "INFTL: mtd->read = %p, size = %d, "
+			"erasesize = %d\n", mtd->read, mtd->size,
+			mtd->erasesize);
+
+                INFTL_setup(mtd);
+	}
+}
+
+static void INFTL_notify_remove(struct mtd_info *mtd)
+{
+	int i;
+
+	for (i = 0; i < MAX_INFTLS; i++) {
+		if (INFTLs[i] && INFTLs[i]->mtd == mtd)
+			INFTL_unsetup(i);
+	}
+}
+
+/*
+ * Actual INFTL access routines.
+ */
+
+/*
+ * INFTL_findfreeblock: Find a free Erase Unit on the INFTL partition.
+ *	This function is used when the give Virtual Unit Chain.
+ */
+static u16 INFTL_findfreeblock(struct INFTLrecord *inftl, int desperate)
+{
+	u16 pot = inftl->LastFreeEUN;
+	int silly = inftl->nb_blocks;
+
+	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_findfreeblock(inftl=0x%x,"
+		"desperate=%d)\n", (int)inftl, desperate);
+
+	/*
+	 * Normally, we force a fold to happen before we run out of free
+	 * blocks completely.
+	 */
+	if (!desperate && inftl->numfreeEUNs < 2) {
+		DEBUG(MTD_DEBUG_LEVEL1, "INFTL: there are too few free "
+			"EUNs (%d)\n", inftl->numfreeEUNs);
+		return 0xffff;
+	}
+
+	/* Scan for a free block */
+	do {
+		if (inftl->PUtable[pot] == BLOCK_FREE) {
+			inftl->LastFreeEUN = pot;
+			return pot;
+		}
+
+		if (++pot > inftl->lastEUN)
+			pot = 0;
+
+		if (!silly--) {
+			printk(KERN_WARNING "INFTL: no free blocks found!  "
+				"EUN range = %d - %d\n", 0, inftl->LastFreeEUN);
+			return BLOCK_NIL;
+		}
+	} while (pot != inftl->LastFreeEUN);
+
+	return BLOCK_NIL;
+}
+
+static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned pendingblock)
+{
+	u16 BlockMap[MAX_SECTORS_PER_UNIT];
+	unsigned char BlockDeleted[MAX_SECTORS_PER_UNIT];
+	unsigned int thisEUN, prevEUN, status;
+	int block, silly;
+	unsigned int targetEUN;
+	struct inftl_oob oob;
+        size_t retlen;
+
+	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_foldchain(inftl=0x%x,thisVUC=%d,"
+		"pending=%d)\n", (int)inftl, thisVUC, pendingblock);
+
+	memset(BlockMap, 0xff, sizeof(BlockMap));
+	memset(BlockDeleted, 0, sizeof(BlockDeleted));
+
+	thisEUN = targetEUN = inftl->VUtable[thisVUC];
+
+	if (thisEUN == BLOCK_NIL) {
+		printk(KERN_WARNING "INFTL: trying to fold non-existent "
+		       "Virtual Unit Chain %d!\n", thisVUC);
+		return BLOCK_NIL;
+	}
+	
+	/*
+	 * Scan to find the Erase Unit which holds the actual data for each
+	 * 512-byte block within the Chain.
+	 */
+        silly = MAX_LOOPS;
+	while (thisEUN < inftl->nb_blocks) {
+		for (block = 0; block < inftl->EraseSize/SECTORSIZE; block ++) {
+			if ((BlockMap[block] != 0xffff) || BlockDeleted[block])
+				continue;
+
+			if (MTD_READOOB(inftl->mtd, (thisEUN * inftl->EraseSize)
+			     + (block * SECTORSIZE), 16 , &retlen,
+			     (char *)&oob) < 0)
+				status = SECTOR_IGNORE;
+			else
+                        	status = oob.b.Status | oob.b.Status1;
+
+			switch(status) {
+			case SECTOR_FREE:
+			case SECTOR_IGNORE:
+				break;
+			case SECTOR_USED:
+				BlockMap[block] = thisEUN;
+				continue;
+			case SECTOR_DELETED:
+				BlockDeleted[block] = 1;
+				continue;
+			default:
+				printk(KERN_WARNING "INFTL: unknown status "
+					"for block %d in EUN %d: %x\n",
+					block, thisEUN, status);
+				break;
+			}
+		}
+
+		if (!silly--) {
+			printk(KERN_WARNING "INFTL: infinite loop in Virtual "
+				"Unit Chain 0x%x\n", thisVUC);
+			return BLOCK_NIL;
+		}
+		
+		thisEUN = inftl->PUtable[thisEUN];
+	}
+
+	/*
+	 * OK. We now know the location of every block in the Virtual Unit
+	 * Chain, and the Erase Unit into which we are supposed to be copying.
+	 * Go for it.
+	 */
+	DEBUG(MTD_DEBUG_LEVEL1, "INFTL: folding chain %d into unit %d\n",
+		thisVUC, targetEUN);
+
+	for (block = 0; block < inftl->EraseSize/SECTORSIZE ; block++) {
+		unsigned char movebuf[SECTORSIZE];
+		int ret;
+
+		/*
+		 * If it's in the target EUN already, or if it's pending write,
+		 * do nothing.
+		 */
+		if (BlockMap[block] == targetEUN || (pendingblock ==
+		    (thisVUC * (inftl->EraseSize / SECTORSIZE) + block))) {
+			continue;
+		}
+
+                /*
+		 * Copy only in non free block (free blocks can only
+                 * happen in case of media errors or deleted blocks).
+		 */
+                if (BlockMap[block] == BLOCK_NIL)
+                        continue;
+                
+                ret = MTD_READECC(inftl->mtd, (inftl->EraseSize *
+			BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE,
+			&retlen, movebuf, (char *)&oob, NAND_ECC_DISKONCHIP); 
+                if (ret < 0) {
+			ret = MTD_READECC(inftl->mtd, (inftl->EraseSize *
+				BlockMap[block]) + (block * SECTORSIZE),
+				SECTORSIZE, &retlen, movebuf, (char *)&oob,
+				NAND_ECC_DISKONCHIP); 
+			if (ret != -EIO) 
+                        	DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went "
+					"away on retry?\n");
+                }
+                MTD_WRITEECC(inftl->mtd, (inftl->EraseSize * targetEUN) +
+			(block * SECTORSIZE), SECTORSIZE, &retlen,
+			movebuf, (char *)&oob, NAND_ECC_DISKONCHIP);
+	}
+
+	/*
+	 * Newest unit in chain now contains data from _all_ older units.
+	 * So go through and erase each unit in chain, oldest first. (This
+	 * is important, by doing oldest first if we crash/reboot then it
+	 * it is relatively simple to clean up the mess).
+	 */
+	DEBUG(MTD_DEBUG_LEVEL1, "INFTL: want to erase virtual chain %d\n",
+		thisVUC);
+
+	for (;;) {
+		/* Find oldest unit in chain. */
+		thisEUN = inftl->VUtable[thisVUC];
+		prevEUN = BLOCK_NIL;
+		while (inftl->PUtable[thisEUN] != BLOCK_NIL) {
+			prevEUN = thisEUN;
+			thisEUN = inftl->PUtable[thisEUN];
+		}
+
+		/* Check if we are all done */
+		if (thisEUN == targetEUN)
+			break;
+
+                if (INFTL_formatblock(inftl, thisEUN) < 0) {
+			/*
+			 * Could not erase : mark block as reserved.
+			 * FixMe: Update Bad Unit Table on disk.
+			 */
+			inftl->PUtable[thisEUN] = BLOCK_RESERVED;
+                } else {
+			/* Correctly erased : mark it as free */
+			inftl->PUtable[thisEUN] = BLOCK_FREE;
+			inftl->PUtable[prevEUN] = BLOCK_NIL;
+			inftl->numfreeEUNs++;
+                }
+	}
+
+	return targetEUN;
+}
+
+u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock)
+{
+	/*
+	 * This is the part that needs some cleverness applied. 
+	 * For now, I'm doing the minimum applicable to actually
+	 * get the thing to work.
+	 * Wear-levelling and other clever stuff needs to be implemented
+	 * and we also need to do some assessment of the results when
+	 * the system loses power half-way through the routine.
+	 */
+	u16 LongestChain = 0;
+	u16 ChainLength = 0, thislen;
+	u16 chain, EUN;
+
+	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_makefreeblock(inftl=0x%x,"
+		"pending=%d)\n", (int)inftl, pendingblock);
+
+	for (chain = 0; chain < inftl->nb_blocks; chain++) {
+		EUN = inftl->VUtable[chain];
+		thislen = 0;
+
+		while (EUN <= inftl->lastEUN) {
+			thislen++;
+			EUN = inftl->PUtable[EUN];
+			if (thislen > 0xff00) {
+				printk(KERN_WARNING "INFTL: endless loop in "
+					"Virtual Chain %d: Unit %x\n",
+					chain, EUN);
+				/*
+				 * Actually, don't return failure.
+				 * Just ignore this chain and get on with it.
+				 */
+				thislen = 0;
+				break;
+			}
+		}
+
+		if (thislen > ChainLength) {
+			ChainLength = thislen;
+			LongestChain = chain;
+		}
+	}
+
+	if (ChainLength < 2) {
+		printk(KERN_WARNING "INFTL: no Virtual Unit Chains available "
+			"for folding. Failing request\n");
+		return BLOCK_NIL;
+	}
+
+	return INFTL_foldchain(inftl, LongestChain, pendingblock);
+}
+
+static int nrbits(unsigned int val, int bitcount)
+{
+	int i, total = 0;
+
+	for (i = 0; (i < bitcount); i++)
+		total += (((0x1 << i) & val) ? 1 : 0);
+	return total;
+}
+
+/*
+ * INFTL_findwriteunit: Return the unit number into which we can write 
+ *                      for this block. Make it available if it isn't already.
+ */
+static /*inline*/ u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned int block)
+{
+	unsigned int thisVUC = block / (inftl->EraseSize / SECTORSIZE);
+	unsigned int thisEUN, writeEUN, prev_block, status;
+	unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize -1);
+	struct inftl_oob oob;
+	struct inftl_bci bci;
+	size_t retlen;
+	int silly, silly2 = 3;
+	unsigned char anac, nacs, parity;
+
+	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_findwriteunit(inftl=0x%x,"
+		"block=%d)\n", (int)inftl, block);
+
+	do {
+		/*
+		 * Scan the media to find a unit in the VUC which has
+		 * a free space for the block in question.
+		 */
+		writeEUN = BLOCK_NIL;
+		thisEUN = inftl->VUtable[thisVUC];
+		silly = MAX_LOOPS;
+
+		while (thisEUN <= inftl->lastEUN) {
+			MTD_READOOB(inftl->mtd, (thisEUN * inftl->EraseSize) +
+				blockofs, 8, &retlen, (char *)&bci);
+
+                        status = bci.Status | bci.Status1;
+			DEBUG(MTD_DEBUG_LEVEL3, "INFTL: status of block %d in "
+				"EUN %d is %x\n", block , writeEUN, status);
+
+			switch(status) {
+			case SECTOR_FREE:
+				writeEUN = thisEUN;
+				break;
+			case SECTOR_DELETED:
+			case SECTOR_USED:
+				/* Can't go any further */
+				goto hitused;
+			case SECTOR_IGNORE:
+				break;
+			default:
+				/*
+				 * Invalid block. Don't use it any more.
+				 * Must implement.
+				 */
+				break;			
+			}
+			
+			if (!silly--) { 
+				printk(KERN_WARNING "INFTL: infinite loop in "
+					"Virtual Unit Chain 0x%x\n", thisVUC);
+				return 0xffff;
+			}
+
+			/* Skip to next block in chain */
+			thisEUN = inftl->PUtable[thisEUN];
+		}
+
+hitused:
+		if (writeEUN != BLOCK_NIL)
+			return writeEUN;
+
+
+		/*
+		 * OK. We didn't find one in the existing chain, or there 
+		 * is no existing chain. Allocate a new one.
+		 */
+		writeEUN = INFTL_findfreeblock(inftl, 0);
+
+		if (writeEUN == BLOCK_NIL) {
+			/*
+			 * That didn't work - there were no free blocks just
+			 * waiting to be picked up. We're going to have to fold
+			 * a chain to make room.
+			 */
+			thisEUN = INFTL_makefreeblock(inftl, 0xffff);
+
+			/*
+			 * Hopefully we free something, lets try again.
+			 * This time we are desperate...
+			 */
+			DEBUG(MTD_DEBUG_LEVEL1, "INFTL: using desperate==1 "
+				"to find free EUN to accommodate write to "
+				"VUC %d\n", thisVUC);
+			writeEUN = INFTL_findfreeblock(inftl, 1);
+			if (writeEUN == BLOCK_NIL) {
+				/*
+				 * Ouch. This should never happen - we should
+				 * always be able to make some room somehow. 
+				 * If we get here, we've allocated more storage 
+				 * space than actual media, or our makefreeblock
+				 * routine is missing something.
+				 */
+				printk(KERN_WARNING "INFTL: cannot make free "
+					"space.\n");
+#ifdef DEBUG
+				INFTL_dumptables(inftl);
+				INFTL_dumpVUchains(inftl);
+#endif
+				return BLOCK_NIL;
+			}			
+		}
+
+		/*
+		 * Insert new block into virtual chain. Firstly update the
+		 * block headers in flash...
+		 */
+		anac = 0;
+		nacs = 0;
+		thisEUN = inftl->VUtable[thisVUC];
+
+		if (thisEUN != BLOCK_NIL) {
+			MTD_READOOB(inftl->mtd, thisEUN * inftl->EraseSize
+				+ 8, 8, &retlen, (char *)&oob.u);
+			anac = oob.u.a.ANAC + 1;
+			nacs = oob.u.a.NACs + 1;
+		}
+
+		prev_block = inftl->VUtable[thisVUC];
+		if (prev_block < inftl->nb_blocks)
+			prev_block -= inftl->firstEUN;
+
+		parity = (nrbits(thisVUC, 16) & 0x1) ? 0x1 : 0;
+		parity |= (nrbits(prev_block, 16) & 0x1) ? 0x2 : 0;
+		parity |= (nrbits(anac, 8) & 0x1) ? 0x4 : 0;
+		parity |= (nrbits(nacs, 8) & 0x1) ? 0x8 : 0;
+ 
+		oob.u.a.virtualUnitNo = cpu_to_le16(thisVUC);
+		oob.u.a.prevUnitNo = cpu_to_le16(prev_block);
+		oob.u.a.ANAC = anac;
+		oob.u.a.NACs = nacs;
+		oob.u.a.parityPerField = parity;
+		oob.u.a.discarded = 0xaa;
+
+		MTD_WRITEOOB(inftl->mtd, writeEUN * inftl->EraseSize + 8, 8,
+			&retlen, (char *)&oob.u);
+
+		/* Also back up header... */
+		oob.u.b.virtualUnitNo = cpu_to_le16(thisVUC);
+		oob.u.b.prevUnitNo = cpu_to_le16(prev_block);
+		oob.u.b.ANAC = anac;
+		oob.u.b.NACs = nacs;
+		oob.u.b.parityPerField = parity;
+		oob.u.b.discarded = 0xaa;
+
+		MTD_WRITEOOB(inftl->mtd, writeEUN * inftl->EraseSize + 
+			SECTORSIZE * 4 + 8, 8, &retlen, (char *)&oob.u);
+
+		inftl->PUtable[writeEUN] = inftl->VUtable[thisVUC];
+		inftl->VUtable[thisVUC] = writeEUN;
+
+		inftl->numfreeEUNs--;
+		return writeEUN;
+
+	} while (silly2--);
+
+	printk(KERN_WARNING "INFTL: error folding to make room for Virtual "
+		"Unit Chain 0x%x\n", thisVUC);
+	return 0xffff;
+}
+
+/*
+ * Given a Virtual Unit Chain, see if it can be deleted, and if so do it.
+ */
+static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
+{
+	unsigned char BlockUsed[MAX_SECTORS_PER_UNIT];
+	unsigned char BlockDeleted[MAX_SECTORS_PER_UNIT];
+	unsigned int thisEUN, status;
+	int block, silly;
+	struct inftl_bci bci;
+	size_t retlen;
+
+	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_trydeletechain(inftl=0x%x,"
+		"thisVUC=%d)\n", (int)inftl, thisVUC);
+
+	memset(BlockUsed, 0, sizeof(BlockUsed));
+	memset(BlockDeleted, 0, sizeof(BlockDeleted));
+
+	thisEUN = inftl->VUtable[thisVUC];
+	if (thisEUN == BLOCK_NIL) {
+		printk(KERN_WARNING "INFTL: trying to delete non-existent "
+		       "Virtual Unit Chain %d!\n", thisVUC);
+		return;
+	}
+	
+	/*
+	 * Scan through the Erase Units to determine whether any data is in
+	 * each of the 512-byte blocks within the Chain.
+	 */
+	silly = MAX_LOOPS;
+	while (thisEUN < inftl->nb_blocks) {
+		for (block = 0; block < inftl->EraseSize/SECTORSIZE; block++) {
+			if (BlockUsed[block] || BlockDeleted[block])
+				continue;
+
+			if (MTD_READOOB(inftl->mtd, (thisEUN * inftl->EraseSize)
+			    + (block * SECTORSIZE), 8 , &retlen,
+			    (char *)&bci) < 0)
+				status = SECTOR_IGNORE;
+			else
+				status = bci.Status | bci.Status1;
+
+			switch(status) {
+			case SECTOR_FREE:
+			case SECTOR_IGNORE:
+				break;
+			case SECTOR_USED:
+				BlockUsed[block] = 1;
+				continue;
+			case SECTOR_DELETED:
+				BlockDeleted[block] = 1;
+				continue;
+			default:
+				printk(KERN_WARNING "INFTL: unknown status "
+					"for block %d in EUN %d: 0x%x\n",
+					block, thisEUN, status);
+			}
+		}
+
+		if (!silly--) {
+			printk(KERN_WARNING "INFTL: infinite loop in Virtual "
+				"Unit Chain 0x%x\n", thisVUC);
+			return;
+		}
+		
+		thisEUN = inftl->PUtable[thisEUN];
+	}
+
+	for (block = 0; block < inftl->EraseSize/SECTORSIZE; block++)
+		if (BlockUsed[block])
+			return;
+
+	/*
+	 * For each block in the chain free it and make it available
+	 * for future use. Erase from the oldest unit first.
+	 */
+	DEBUG(MTD_DEBUG_LEVEL1, "INFTL: deleting empty VUC %d\n", thisVUC);
+
+	for (;;) {
+		u16 *prevEUN = &inftl->VUtable[thisVUC];
+		thisEUN = *prevEUN;
+
+		/* If the chain is all gone already, we're done */
+		if (thisEUN == BLOCK_NIL) {
+			DEBUG(MTD_DEBUG_LEVEL2, "INFTL: Empty VUC %d for deletion was already absent\n", thisEUN);
+			return;
+		}
+
+		/* Find oldest unit in chain. */
+		while (inftl->PUtable[thisEUN] != BLOCK_NIL) {
+			BUG_ON(thisEUN >= inftl->nb_blocks);
+
+			prevEUN = &inftl->PUtable[thisEUN];
+			thisEUN = *prevEUN;
+		}
+
+		DEBUG(MTD_DEBUG_LEVEL3, "Deleting EUN %d from VUC %d\n",
+		      thisEUN, thisVUC);
+
+                if (INFTL_formatblock(inftl, thisEUN) < 0) {
+			/*
+			 * Could not erase : mark block as reserved.
+			 * FixMe: Update Bad Unit Table on medium.
+			 */
+			inftl->PUtable[thisEUN] = BLOCK_RESERVED;
+                } else {
+			/* Correctly erased : mark it as free */
+			inftl->PUtable[thisEUN] = BLOCK_FREE;
+			inftl->numfreeEUNs++;
+		}
+
+		/* Now sort out whatever was pointing to it... */
+		*prevEUN = BLOCK_NIL;
+
+		/* Ideally we'd actually be responsive to new
+		   requests while we're doing this -- if there's
+		   free space why should others be made to wait? */
+		cond_resched();
+	}
+
+	inftl->VUtable[thisVUC] = BLOCK_NIL;
+}
+
+static int INFTL_deleteblock(struct INFTLrecord *inftl, unsigned block)
+{
+	unsigned int thisEUN = inftl->VUtable[block / (inftl->EraseSize / SECTORSIZE)];
+	unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1);
+	unsigned int status;
+	int silly = MAX_LOOPS;
+	size_t retlen;
+	struct inftl_bci bci;
+
+	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_deleteblock(inftl=0x%x,"
+		"block=%d)\n", (int)inftl, block);
+
+	while (thisEUN < inftl->nb_blocks) {
+		if (MTD_READOOB(inftl->mtd, (thisEUN * inftl->EraseSize) +
+		    blockofs, 8, &retlen, (char *)&bci) < 0)
+			status = SECTOR_IGNORE;
+		else
+			status = bci.Status | bci.Status1;
+
+		switch (status) {
+		case SECTOR_FREE:
+		case SECTOR_IGNORE:
+			break;
+		case SECTOR_DELETED:
+			thisEUN = BLOCK_NIL;
+			goto foundit;
+		case SECTOR_USED:
+			goto foundit;
+		default:
+			printk(KERN_WARNING "INFTL: unknown status for "
+				"block %d in EUN %d: 0x%x\n",
+				block, thisEUN, status);
+			break;
+		}
+
+		if (!silly--) {
+			printk(KERN_WARNING "INFTL: infinite loop in Virtual "
+				"Unit Chain 0x%x\n",
+				block / (inftl->EraseSize / SECTORSIZE));
+			return 1;
+		}
+		thisEUN = inftl->PUtable[thisEUN];
+	}
+
+foundit:
+	if (thisEUN != BLOCK_NIL) {
+		loff_t ptr = (thisEUN * inftl->EraseSize) + blockofs;
+
+		if (MTD_READOOB(inftl->mtd, ptr, 8, &retlen, (char *)&bci) < 0)
+			return -EIO;
+		bci.Status = bci.Status1 = SECTOR_DELETED;
+		if (MTD_WRITEOOB(inftl->mtd, ptr, 8, &retlen, (char *)&bci) < 0)
+			return -EIO;
+		INFTL_trydeletechain(inftl, block / (inftl->EraseSize / SECTORSIZE));
+	}
+	return 0;
+}
+
+static int INFTL_writeblock(struct INFTLrecord *inftl, unsigned block, char *buffer)
+{
+	u16 writeEUN;
+	unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1);
+	size_t retlen;
+	u8 eccbuf[6];
+	char *p, *pend;
+
+	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_writeblock(inftl=0x%x,block=%d,"
+		"buffer=0x%x)\n", (int)inftl, block, (int)buffer);
+
+	/* Is block all zero? */
+	pend = buffer + SECTORSIZE;
+	for (p = buffer; p < pend && !*p; p++);
+
+	if (p < pend) {
+		writeEUN = INFTL_findwriteunit(inftl, block);
+
+		if (writeEUN == BLOCK_NIL) {
+			printk(KERN_WARNING "INFTL__writeblock(): cannot find "
+				"block to write to\n");
+			/*
+			 * If we _still_ haven't got a block to use,
+			 * we're screwed.
+			 */
+			return 1;
+		}
+
+		MTD_WRITEECC(inftl->mtd, (writeEUN * inftl->EraseSize) +
+			blockofs, SECTORSIZE, &retlen, (char *)buffer,
+			(char *)eccbuf, NAND_ECC_DISKONCHIP);
+		/*
+		 * no need to write SECTOR_USED flags since they are
+		 * written in mtd_writeecc.
+		 */
+	} else {
+		INFTL_deleteblock(inftl, block);
+	}
+
+	return 0;
+}
+
+static int INFTL_readblock(struct INFTLrecord *inftl, unsigned block, char *buffer)
+{
+	u16 thisEUN = inftl->VUtable[block / (inftl->EraseSize / SECTORSIZE)];
+	unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1);
+        unsigned int status;
+	int silly = MAX_LOOPS;
+        struct inftl_bci bci;
+        size_t retlen;
+
+	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_readblock(inftl=0x%x,block=%d,"
+		"buffer=0x%x)\n", (int)inftl, block, (int)buffer);
+
+	while (thisEUN < inftl->nb_blocks) {
+		if (MTD_READOOB(inftl->mtd, (thisEUN * inftl->EraseSize) +
+		     blockofs, 8, &retlen, (char *)&bci) < 0)
+			status = SECTOR_IGNORE;
+		else
+			status = bci.Status | bci.Status1;
+
+		switch (status) {
+		case SECTOR_DELETED:
+			thisEUN = BLOCK_NIL;
+			goto foundit;
+		case SECTOR_USED:
+			goto foundit;
+		case SECTOR_FREE:
+		case SECTOR_IGNORE:
+			break;
+		default:
+			printk(KERN_WARNING "INFTL: unknown status for "
+				"block %d in EUN %d: 0x%04x\n",
+				block, thisEUN, status);
+			break;
+		}
+
+		if (!silly--) {
+			printk(KERN_WARNING "INFTL: infinite loop in "
+				"Virtual Unit Chain 0x%x\n",
+				block / (inftl->EraseSize / SECTORSIZE));
+			return 1;
+		}
+
+		thisEUN = inftl->PUtable[thisEUN];
+	}
+
+foundit:
+	if (thisEUN == BLOCK_NIL) {
+		/* The requested block is not on the media, return all 0x00 */
+		memset(buffer, 0, SECTORSIZE);
+	} else {
+        	size_t retlen;
+		loff_t ptr = (thisEUN * inftl->EraseSize) + blockofs;
+		u_char eccbuf[6];
+		if (MTD_READECC(inftl->mtd, ptr, SECTORSIZE, &retlen,
+		    buffer, eccbuf, NAND_ECC_DISKONCHIP))
+			return -EIO;
+	}
+	return 0;
+}
+
+static int inftl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct INFTLrecord *inftl;
+	int p;
+
+	inftl = INFTLs[MINOR(inode->i_rdev) >> INFTL_PARTN_BITS];
+
+	if (!inftl)
+		return -EINVAL;
+
+	switch (cmd) {
+#if 0
+	case INFTL_IOCTL_DELETE_SECTOR: {
+		unsigned int dev;
+		int res;
+
+		if (arg >= part_table[dev].nr_sects)
+			return -EINVAL;
+		arg += part_table[MINOR(inode->i_rdev)].start_sect;
+		DEBUG(MTD_DEBUG_LEVEL3, "Waiting for mutex\n");
+		down(&inftl->mutex);
+		DEBUG(MTD_DEBUG_LEVEL3, "Got mutex\n");
+		res = INFTL_deleteblock(inftl, arg);
+		up(&inftl->mutex);
+		return res;
+	}
+#endif
+	case HDIO_GETGEO: {
+		struct hd_geometry g;
+
+		g.heads = inftl->heads;
+		g.sectors = inftl->sectors;
+		g.cylinders = inftl->cylinders;
+		g.start = part_table[MINOR(inode->i_rdev)].start_sect;
+		return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0;
+	}
+	case BLKGETSIZE:   /* Return device size */
+		return put_user(part_table[MINOR(inode->i_rdev)].nr_sects,
+			(unsigned long *) arg);
+
+#ifdef BLKGETSIZE64
+	case BLKGETSIZE64:
+		return put_user((u64)part_table[MINOR(inode->i_rdev)].nr_sects << 9,
+			(u64 *)arg);
+#endif
+
+	case BLKFLSBUF:
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
+		fsync_dev(inode->i_rdev);
+		invalidate_buffers(inode->i_rdev);
+		if (inftl->mtd->sync)
+			inftl->mtd->sync(inftl->mtd);
+		return 0;
+
+	case BLKRRPART:
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
+		if (inftl->usecount > 1)
+			return -EBUSY;
+		/* 
+		 * We have to flush all buffers and invalidate caches,
+		 * or we won't be able to re-use the partitions,
+		 * if there was a change and we don't want to reboot
+		 */
+		p = (1 << INFTL_PARTN_BITS) - 1;
+		while (p-- > 0) {
+			kdev_t devp = MKDEV(MAJOR(inode->i_dev),
+				MINOR(inode->i_dev)+p);
+			if (part_table[p].nr_sects > 0)
+				invalidate_device (devp, 1);
+
+			part_table[MINOR(inode->i_dev)+p].start_sect = 0;
+			part_table[MINOR(inode->i_dev)+p].nr_sects = 0;
+		}
+		
+#if LINUX_VERSION_CODE < 0x20328
+		resetup_one_dev(&inftl_gendisk,
+			MINOR(inode->i_rdev) >> INFTL_PARTN_BITS);
+#else
+		grok_partitions(&inftl_gendisk,
+			MINOR(inode->i_rdev) >> INFTL_PARTN_BITS,
+			1 << INFTL_PARTN_BITS, inftl->nr_sects);
+#endif
+		return 0;
+
+	case BLKROSET:
+	case BLKROGET:
+	case BLKSSZGET:
+		return blk_ioctl(inode->i_rdev, cmd, arg);
+
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+void inftl_request(RQFUNC_ARG)
+{
+	unsigned int dev, block, nsect;
+	struct INFTLrecord *inftl;
+	char *buffer;
+	struct request *req;
+	int res;
+
+	while (1) {
+		INIT_REQUEST;	/* blk.h */
+		req = CURRENT;
+		
+		/* We can do this because the generic code knows not to
+		   touch the request at the head of the queue */
+		spin_unlock_irq(&io_request_lock);
+
+		DEBUG(MTD_DEBUG_LEVEL2, "INFTL_request\n");
+		DEBUG(MTD_DEBUG_LEVEL3, "INFTL %s request, from sector 0x%04lx"
+			" for 0x%04lx sectors\n",
+			(req->cmd == READ) ? "Read " : "Write",
+			req->sector, req->current_nr_sectors);
+
+		dev = MINOR(req->rq_dev);
+		block = req->sector;
+		nsect = req->current_nr_sectors;
+		buffer = req->buffer;
+		res = 1; /* succeed */
+
+		if (dev >= MAX_INFTLS * (1 << INFTL_PARTN_BITS)) {
+			/* there is no such partition */
+			printk("INFTL: bad minor number: device = %s\n",
+			       kdevname(req->rq_dev));
+			res = 0; /* fail */
+			goto repeat;
+		}
+		
+		inftl = INFTLs[dev / (1 << INFTL_PARTN_BITS)];
+		DEBUG(MTD_DEBUG_LEVEL3, "Waiting for mutex\n");
+		down(&inftl->mutex);
+		DEBUG(MTD_DEBUG_LEVEL3, "Got mutex\n");
+
+		if (block + nsect > part_table[dev].nr_sects) {
+			/* access past the end of device */
+			printk("inftl%c%d: bad access: block = %d, "
+				"count = %d\n",
+				(MINOR(req->rq_dev) >> 6) + 'a', dev & 0xf,
+				block, nsect);
+			up(&inftl->mutex);
+			res = 0; /* fail */
+			goto repeat;
+		}
+		
+		block += part_table[dev].start_sect;
+		
+		if (req->cmd == READ) {
+			DEBUG(MTD_DEBUG_LEVEL2, "INFTL: read request of 0x%x"
+				"  sectors @ %x (req->nr_sectors == %lx)\n",
+				nsect, block, req->nr_sectors);
+	
+			for ( ; nsect > 0; nsect-- , block++, buffer += SECTORSIZE) {
+				/* Read a single sector to req->buffer + (512 * i) */
+				if (INFTL_readblock(inftl, block, buffer)) {
+					DEBUG(MTD_DEBUG_LEVEL2, "INFTL: "
+						"read request failed\n");
+					up(&inftl->mutex);
+					res = 0;
+					goto repeat;
+				}
+			}
+
+			DEBUG(MTD_DEBUG_LEVEL2, "INFTL: read request "
+				"completed OK\n");
+			up(&inftl->mutex);
+			goto repeat;
+		} else if (req->cmd == WRITE) {
+			DEBUG(MTD_DEBUG_LEVEL2, "INFTL: write request of 0x%x"
+				" sectors @ %x (req->nr_sectors == %lx)\n",
+				nsect, block, req->nr_sectors);
+			for ( ; nsect > 0; nsect-- , block++, buffer += 512) {
+				/* Read a single sector to req->buffer + (512 * i) */
+				if (INFTL_writeblock(inftl, block, buffer)) {
+					DEBUG(MTD_DEBUG_LEVEL1, "INFTL: "
+						"write request failed\n");
+					up(&inftl->mutex);
+					res = 0;
+					goto repeat;
+				}
+			}
+			DEBUG(MTD_DEBUG_LEVEL2, "INFTL write request "
+				"completed OK\n");
+			up(&inftl->mutex);
+			goto repeat;
+		} else {
+			DEBUG(MTD_DEBUG_LEVEL0, "INFTL: unknown request\n");
+			up(&inftl->mutex);
+			res = 0;
+			goto repeat;
+		}
+	repeat: 
+		DEBUG(MTD_DEBUG_LEVEL3, "INFTL: end_request(%d)\n", res);
+		spin_lock_irq(&io_request_lock);
+		end_request(res);
+	}
+}
+
+static int inftl_open(struct inode *ip, struct file *fp)
+{
+	int inftlnum = MINOR(ip->i_rdev) >> INFTL_PARTN_BITS;
+	struct INFTLrecord *thisINFTL;
+	thisINFTL = INFTLs[inftlnum];
+
+	DEBUG(MTD_DEBUG_LEVEL2, "INFTL: INFTL_open()\n");
+
+#ifdef CONFIG_KMOD
+	if (!thisINFTL && inftlnum == 0) {
+		request_module("docprobe");
+		thisINFTL = INFTLs[inftlnum];
+	}
+#endif
+	if (!thisINFTL) {
+		DEBUG(MTD_DEBUG_LEVEL2, "INFTL: ENODEV, thisINFTL = %d, "
+			"minor = %d, ip = %p, fp = %p\n", 
+			inftlnum, ip->i_rdev, ip, fp);
+		return -ENODEV;
+	}
+
+	thisINFTL->usecount++;
+	if (!get_mtd_device(thisINFTL->mtd, -1))
+		return -ENXIO;
+
+	return 0;
+}
+
+static int inftl_release(struct inode *inode, struct file *fp)
+{
+	struct INFTLrecord *thisINFTL;
+
+	thisINFTL = INFTLs[MINOR(inode->i_rdev) / 16];
+
+	DEBUG(MTD_DEBUG_LEVEL2, "INFTL: INFTL_release()\n");
+
+	if (thisINFTL->mtd->sync)
+		thisINFTL->mtd->sync(thisINFTL->mtd);
+	thisINFTL->usecount--;
+
+	put_mtd_device(thisINFTL->mtd);
+
+	return 0;
+}
+
+static struct block_device_operations inftl_fops = 
+{
+	.owner =	THIS_MODULE,
+	.open =		inftl_open,
+	.release =	inftl_release,
+	.ioctl = 	inftl_ioctl
+};
+
+/****************************************************************************
+ *
+ * Module stuff
+ *
+ ****************************************************************************/
+                                                                                
+static struct mtd_notifier inftl_notifier = {
+	.add = INFTL_notify_add,
+	.remove = INFTL_notify_remove
+};
+                                                                                
+extern char inftlmountrev[];
+
+static int __init init_inftl(void)
+{
+	int i;
+
+	printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.13 $, "
+		"inftlmount.c %s\n", inftlmountrev);
+
+	if (register_blkdev(MAJOR_NR, "inftl", &inftl_fops)) {
+		printk(KERN_WARNING "INFTL: unable to register INFTL block "
+			"device on major %d\n", MAJOR_NR);
+		return -EBUSY;
+	}
+
+	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &inftl_request);
+
+	/* set block size to 1kb each */
+	for (i = 0; i < 256; i++)
+		inftl_blocksizes[i] = 1024;
+	blksize_size[MAJOR_NR] = inftl_blocksizes;
+
+	add_gendisk(&inftl_gendisk);
+	register_mtd_user(&inftl_notifier);
+	return 0;
+}
+
+static void __exit cleanup_inftl(void)
+{
+	unregister_mtd_user(&inftl_notifier);
+	unregister_blkdev(MAJOR_NR, "inftl");
+	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+	del_gendisk(&inftl_gendisk);
+}
+
+module_init(init_inftl);
+module_exit(cleanup_inftl);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>, David Woodhouse <dwmw2@infradead.org>, Fabrice Bellard <fabrice.bellard@netgem.com> et al.");
+MODULE_DESCRIPTION("Support code for Inverse Flash Translation Layer, used on M-Systems DiskOnChip 2000, Millennium and Millennium Plus");
diff -urN linux-2.4.29/drivers/mtd/inftlmount.c linux-2.4.29-uc1/drivers/mtd/inftlmount.c
--- linux-2.4.29/drivers/mtd/inftlmount.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/inftlmount.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,814 @@
+/* 
+ * inftlmount.c -- INFTL mount code with extensive checks.
+ *
+ * Author: Greg Ungerer (gerg@snapgear.com)
+ * (C) Copyright 2002-2003, Greg Ungerer (gerg@snapgear.com)
+ *
+ * Based heavily on the nftlmount.c code which is:
+ * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 
+ * Copyright (C) 2000 Netgem S.A.
+ *
+ * $Id: inftlmount.c,v 1.13 2003/10/07 07:04:16 gerg Exp $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nftl.h>
+#include <linux/mtd/inftl.h>
+#include <linux/mtd/compatmac.h>
+
+char inftlmountrev[]="$Revision: 1.13 $";
+
+/*
+ * find_boot_record: Find the INFTL Media Header and its Spare copy which
+ *	contains the various device information of the INFTL partition and
+ *	Bad Unit Table. Update the PUtable[] table according to the Bad
+ *	Unit Table. PUtable[] is used for management of Erase Unit in
+ *	other routines in inftlcore.c and inftlmount.c.
+ */
+static int find_boot_record(struct INFTLrecord *inftl)
+{
+	struct inftl_unittail h1;
+	//struct inftl_oob oob;
+	unsigned int i, block, boot_record_count = 0;
+	u8 buf[SECTORSIZE];
+	struct INFTLMediaHeader *mh = &inftl->MediaHdr;
+	struct INFTLPartition *ip;
+	int retlen;
+
+	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: find_boot_record(inftl=0x%x)\n",
+		(int)inftl);
+
+        /*
+	 * Assume logical EraseSize == physical erasesize for starting the
+	 * scan. We'll sort it out later if we find a MediaHeader which says
+	 * otherwise.
+	 */
+	inftl->EraseSize = inftl->mtd->erasesize;
+        inftl->nb_blocks = inftl->mtd->size / inftl->EraseSize;
+
+	inftl->MediaUnit = BLOCK_NIL;
+	inftl->SpareMediaUnit = BLOCK_NIL;
+
+	/* Search for a valid boot record */
+	for (block = 0; block < inftl->nb_blocks; block++) {
+		int ret;
+
+		/*
+		 * Check for BNAND header first. Then whinge if it's found
+		 * but later checks fail.
+		 */
+		if ((ret = MTD_READ(inftl->mtd, block * inftl->EraseSize,
+		    SECTORSIZE, &retlen, buf))) {
+			static int warncount = 5;
+
+			if (warncount) {
+				printk(KERN_WARNING "INFTL: block read at 0x%x "
+					"of mtd%d failed: %d\n",
+					block * inftl->EraseSize,
+					inftl->mtd->index, ret);
+				if (!--warncount)
+					printk(KERN_WARNING "INFTL: further "
+						"failures for this block will "
+						"not be printed\n");
+			}
+			continue;
+		}
+
+		if (retlen < 6 || memcmp(buf, "BNAND", 6)) {
+			/* BNAND\0 not found. Continue */
+			continue;
+		}
+
+		/* To be safer with BIOS, also use erase mark as discriminant */
+		if ((ret = MTD_READOOB(inftl->mtd, block * inftl->EraseSize +
+		    SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0)) {
+			printk(KERN_WARNING "INFTL: ANAND header found at "
+				"0x%x in mtd%d, but OOB data read failed "
+				"(err %d)\n", block * inftl->EraseSize,
+				inftl->mtd->index, ret);
+			continue;
+		}
+
+		if (boot_record_count) {
+			/*
+			 * We've already processed one. So we just check if
+			 * this one is the same as the first one we found.
+			 */
+			if (memcmp(mh, buf, sizeof(struct INFTLMediaHeader))) {
+				printk(KERN_WARNING "INFTL: Media Headers at "
+					"0x%x and 0x%x disagree.\n",
+					inftl->MediaUnit * inftl->EraseSize,
+					block * inftl->EraseSize);
+				return -1;
+			}
+			if (boot_record_count == 1)
+				inftl->SpareMediaUnit = block;
+
+			/*
+			 * Mark this boot record (INFTL MediaHeader) block as
+			 * reserved.
+			 */
+			inftl->PUtable[block] = BLOCK_RESERVED;
+
+			boot_record_count++;
+			continue;
+		}
+
+		/*
+		 * This is the first we've seen.
+		 * Copy the media header structure into place.
+		 */
+		memcpy(mh, buf, sizeof(struct INFTLMediaHeader));
+		mh->NoOfBootImageBlocks = le32_to_cpu(mh->NoOfBootImageBlocks);
+		mh->NoOfBinaryPartitions = le32_to_cpu(mh->NoOfBinaryPartitions);
+		mh->NoOfBDTLPartitions = le32_to_cpu(mh->NoOfBDTLPartitions);
+		mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits);
+		mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
+		mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
+
+#ifdef CONFIG_MTD_DEBUG_VERBOSE
+		if (CONFIG_MTD_DEBUG_VERBOSE >= 2) {
+			printk("INFTL: Media Header ->\n"
+				"    bootRecordID          = %s\n"
+				"    NoOfBootImageBlocks   = %d\n"
+				"    NoOfBinaryPartitions  = %d\n"
+				"    NoOfBDTLPartitions    = %d\n"
+				"    BlockMultiplerBits    = %d\n"
+				"    FormatFlgs            = %d\n"
+				"    OsakVersion           = 0x%x\n"
+				"    PercentUsed           = %d\n",
+				mh->bootRecordID, mh->NoOfBootImageBlocks,
+				mh->NoOfBinaryPartitions,
+				mh->NoOfBDTLPartitions,
+				mh->BlockMultiplierBits, mh->FormatFlags,
+				mh->OsakVersion, mh->PercentUsed);
+		}
+#endif
+
+		if (mh->NoOfBDTLPartitions == 0) {
+			printk(KERN_WARNING "INFTL: Media Header sanity check "
+				"failed: NoOfBDTLPartitions (%d) == 0, "
+				"must be at least 1\n", mh->NoOfBDTLPartitions);
+			return -1;
+		}
+
+		if ((mh->NoOfBDTLPartitions + mh->NoOfBinaryPartitions) > 4) {
+			printk(KERN_WARNING "INFTL: Media Header sanity check "
+				"failed: Total Partitions (%d) > 4, "
+				"BDTL=%d Binary=%d\n", mh->NoOfBDTLPartitions +
+				mh->NoOfBinaryPartitions,
+				mh->NoOfBDTLPartitions,
+				mh->NoOfBinaryPartitions);
+			return -1;
+		}
+
+		if (mh->BlockMultiplierBits > 1) {
+			printk(KERN_WARNING "INFTL: sorry, we don't support "
+				"UnitSizeFactor 0x%02x\n",
+				mh->BlockMultiplierBits);
+			return -1;
+		} else if (mh->BlockMultiplierBits == 1) {
+			printk(KERN_WARNING "INFTL: support for INFTL with "
+				"UnitSizeFactor 0x%02x is experimental\n",
+				mh->BlockMultiplierBits);
+			inftl->EraseSize = inftl->mtd->erasesize <<
+				(0xff - mh->BlockMultiplierBits);
+			inftl->nb_blocks = inftl->mtd->size / inftl->EraseSize;
+		}
+
+		/* Scan the partitions */
+		for (i = 0; (i < 4); i++) {
+			ip = &mh->Partitions[i];
+			ip->virtualUnits = le32_to_cpu(ip->virtualUnits);
+			ip->firstUnit = le32_to_cpu(ip->firstUnit);
+			ip->lastUnit = le32_to_cpu(ip->lastUnit);
+			ip->flags = le32_to_cpu(ip->flags);
+			ip->spareUnits = le32_to_cpu(ip->spareUnits);
+			ip->Reserved0 = le32_to_cpu(ip->Reserved0);
+
+#ifdef CONFIG_MTD_DEBUG_VERBOSE
+			if (CONFIG_MTD_DEBUG_VERBOSE >= 2) {
+				printk("    PARTITION[%d] ->\n"
+					"        virtualUnits    = %d\n"
+					"        firstUnit       = %d\n"
+					"        lastUnit        = %d\n"
+					"        flags           = 0x%x\n"
+					"        spareUnits      = %d\n",
+					i, ip->virtualUnits, ip->firstUnit,
+					ip->lastUnit, ip->flags,
+					ip->spareUnits);
+			}
+#endif
+
+			if (ip->Reserved0 != ip->firstUnit) {
+				struct erase_info *instr = &inftl->instr;
+
+				/*
+				 * 	Most likely this is using the
+				 * 	undocumented qiuck mount feature.
+				 * 	We don't support that, we will need
+				 * 	to erase the hidden block for full
+				 * 	compatibility.
+				 */
+				instr->addr = ip->Reserved0 * inftl->EraseSize;
+				instr->len = inftl->EraseSize;
+				MTD_ERASE(inftl->mtd, instr);
+			}
+			if ((ip->lastUnit - ip->firstUnit + 1) < ip->virtualUnits) {
+				printk(KERN_WARNING "INFTL: Media Header "
+					"Partition %d sanity check failed\n"
+					"    firstUnit %d : lastUnit %d  >  "
+					"virtualUnits %d\n", i, ip->lastUnit,
+					ip->firstUnit, ip->Reserved0);
+				return -1;
+			}
+			if (ip->Reserved1 != 0) {
+				printk(KERN_WARNING "INFTL: Media Header "
+					"Partition %d sanity check failed: "
+					"Reserved1 %d != 0\n",
+					i, ip->Reserved1);
+				return -1;
+			}
+
+			if (ip->flags & INFTL_BDTL)
+				break;
+		}
+
+		if (i >= 4) {
+			printk(KERN_WARNING "INFTL: Media Header Partition "
+				"sanity check failed:\n       No partition "
+				"marked as Disk Partition\n");
+			return -1;
+		}
+
+		inftl->nb_boot_blocks = ip->firstUnit;
+		inftl->numvunits = ip->virtualUnits;
+		if (inftl->numvunits > (inftl->nb_blocks -
+		    inftl->nb_boot_blocks - 2)) {
+			printk(KERN_WARNING "INFTL: Media Header sanity check "
+				"failed:\n        numvunits (%d) > nb_blocks "
+				"(%d) - nb_boot_blocks(%d) - 2\n",
+				inftl->numvunits, inftl->nb_blocks,
+				inftl->nb_boot_blocks);
+			return -1;
+		}
+		
+		inftl->nr_sects  = inftl->numvunits *
+			(inftl->EraseSize / SECTORSIZE);
+
+		/*
+		 * Block count is set to last used EUN (we won't need to keep
+		 * any meta-data past that point).
+		 */
+		inftl->firstEUN = ip->firstUnit;
+		inftl->lastEUN = ip->lastUnit;
+		inftl->nb_blocks = ip->lastUnit + 1;
+
+		/* Memory alloc */
+		inftl->PUtable = kmalloc(inftl->nb_blocks * sizeof(u16), GFP_KERNEL);
+		if (!inftl->PUtable) {
+			printk(KERN_WARNING "INFTL: allocation of PUtable "
+				"failed (%d bytes)\n",
+				inftl->nb_blocks * sizeof(u16));
+			return -ENOMEM;
+		}
+
+		inftl->VUtable = kmalloc(inftl->nb_blocks * sizeof(u16), GFP_KERNEL);
+		if (!inftl->VUtable) {
+			kfree(inftl->PUtable);
+			printk(KERN_WARNING "INFTL: allocation of VUtable "
+				"failed (%d bytes)\n",
+				inftl->nb_blocks * sizeof(u16));
+			return -ENOMEM;
+		}
+		
+		/* Mark the blocks before INFTL MediaHeader as reserved */
+		for (i = 0; i < inftl->nb_boot_blocks; i++)
+			inftl->PUtable[i] = BLOCK_RESERVED;
+		/* Mark all remaining blocks as potentially containing data */
+		for (; i < inftl->nb_blocks; i++)
+			inftl->PUtable[i] = BLOCK_NOTEXPLORED;
+
+		/* Mark this boot record (NFTL MediaHeader) block as reserved */
+		inftl->PUtable[block] = BLOCK_RESERVED;
+
+#if 0
+		/* Read Bad Erase Unit Table and modify PUtable[] accordingly */
+		for (i = 0; i < inftl->nb_blocks; i++) {
+			if ((i & (SECTORSIZE - 1)) == 0) {
+				/* read one sector for every SECTORSIZE of blocks */
+				if ((ret = MTD_READECC(inftl->mtd,
+				    block * inftl->EraseSize + i + SECTORSIZE,
+				    SECTORSIZE, &retlen, buf,
+				    (char *)&oob, NULL)) < 0) {
+					printk(KERN_WARNING "INFTL: read of "
+						"bad sector table failed "
+						"(err %d)\n", ret);
+					kfree(inftl->VUtable);
+					kfree(inftl->PUtable);
+					return -1;
+				}
+			}
+			/* Mark the Bad Erase Unit as RESERVED in PUtable */
+			if (buf[i & (SECTORSIZE - 1)] != 0xff)
+				inftl->PUtable[i] = BLOCK_RESERVED;
+		}
+#endif
+
+		inftl->MediaUnit = block;
+		boot_record_count++;
+	}
+		
+	return boot_record_count ? 0 : -1;
+}
+
+static int memcmpb(void *a, int c, int n)
+{
+	int i;
+	for (i = 0; i < n; i++) {
+		if (c != ((unsigned char *)a)[i])
+			return 1;
+	}
+	return 0;
+}
+
+/*
+ * check_free_sector: check if a free sector is actually FREE,
+ *	i.e. All 0xff in data and oob area.
+ */
+static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address,
+	int len, int check_oob)
+{
+	int i, retlen;
+	u8 buf[SECTORSIZE];
+
+	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: check_free_sectors(inftl=0x%x,"
+		"address=0x%x,len=%d,check_oob=%d)\n", (int)inftl,
+		address, len, check_oob);
+
+	for (i = 0; i < len; i += SECTORSIZE) {
+		/*
+		 * We want to read the sector without ECC check here since a
+		 * free sector does not have ECC syndrome on it yet.
+		 */
+		if (MTD_READ(inftl->mtd, address, SECTORSIZE, &retlen, buf) < 0)
+			return -1;
+		if (memcmpb(buf, 0xff, SECTORSIZE) != 0)
+			return -1;
+
+		if (check_oob) {
+			if (MTD_READOOB(inftl->mtd, address,
+			    inftl->mtd->oobsize, &retlen, buf) < 0)
+				return -1;
+			if (memcmpb(buf, 0xff, inftl->mtd->oobsize) != 0)
+				return -1;
+		}
+		address += SECTORSIZE;
+	}
+
+	return 0;
+}
+
+/*
+ * INFTL_format: format a Erase Unit by erasing ALL Erase Zones in the Erase
+ *		 Unit and Update INFTL metadata. Each erase operation is
+ *		 checked with check_free_sectors.
+ *
+ * Return: 0 when succeed, -1 on error.
+ *
+ * ToDo: 1. Is it neceressary to check_free_sector after erasing ?? 
+ *       2. UnitSizeFactor != 0xFF
+ */
+int INFTL_formatblock(struct INFTLrecord *inftl, int block)
+{
+	int retlen;
+	struct inftl_unittail uci;
+	struct erase_info *instr = &inftl->instr;
+
+	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_formatblock(inftl=0x%x,"
+		"block=%d)\n", (int)inftl, block);
+
+	memset(instr, 0, sizeof(struct erase_info));
+
+	/* Use async erase interface, test return code */
+	instr->addr = block * inftl->EraseSize;
+	instr->len = inftl->EraseSize;
+	MTD_ERASE(inftl->mtd, instr);
+
+	if (instr->state == MTD_ERASE_FAILED) {
+		/*
+		 * Could not format, FixMe: We should update the BadUnitTable 
+		 * both in memory and on disk.
+		 */
+		printk(KERN_WARNING "INFTL: error while formatting block %d\n",
+			block);
+		return -1;
+	}
+
+	/*
+	 * Check the "freeness" of Erase Unit before updating metadata.
+	 * FixMe: is this check really necessary? Since we have check the
+	 *        return code after the erase operation.
+	 */
+	if (check_free_sectors(inftl, instr->addr, inftl->EraseSize, 1) != 0)
+		return -1;
+
+	uci.EraseMark = cpu_to_le16(ERASE_MARK);
+	uci.EraseMark1 = cpu_to_le16(ERASE_MARK);
+	uci.Reserved[0] = 0;
+	uci.Reserved[1] = 0;
+	uci.Reserved[2] = 0;
+	uci.Reserved[3] = 0;
+	if (MTD_WRITEOOB(inftl->mtd, block * inftl->EraseSize + SECTORSIZE * 2 +
+	    8, 8, &retlen, (char *)&uci) < 0)
+		return -1;
+	return 0;
+}
+
+/*
+ * format_chain: Format an invalid Virtual Unit chain. It frees all the Erase
+ *	Units in a Virtual Unit Chain, i.e. all the units are disconnected.
+ *
+ *	Since the chain is invalid then we will have to erase it from its
+ *	head (normally for INFTL we go from the oldest). But if it has a
+ *	loop then there is no oldest...
+ */
+static void format_chain(struct INFTLrecord *inftl, unsigned int first_block)
+{
+	unsigned int block = first_block, block1;
+
+	printk(KERN_WARNING "INFTL: formatting chain at block %d\n",
+		first_block);
+
+	for (;;) {
+		block1 = inftl->PUtable[block];
+
+		printk(KERN_WARNING "INFTL: formatting block %d\n", block);
+		if (INFTL_formatblock(inftl, block) < 0) {
+			/*
+			 * Cannot format !!!! Mark it as Bad Unit,
+			 * FixMe: update the BadUnitTable on disk.
+			 */
+			inftl->PUtable[block] = BLOCK_RESERVED;
+		} else {
+			inftl->PUtable[block] = BLOCK_FREE;
+		}
+
+		/* Goto next block on the chain */
+		block = block1;
+
+		if (block == BLOCK_NIL || block >= inftl->lastEUN)
+			break;
+	}
+}
+
+void INFTL_dumptables(struct INFTLrecord *s)
+{
+	int i;
+
+	printk("-------------------------------------------"
+		"----------------------------------\n");
+
+	printk("VUtable[%d] ->", s->nb_blocks);
+	for (i = 0; i < s->nb_blocks; i++) {
+		if ((i % 8) == 0)
+			printk("\n%04x: ", i);
+		printk("%04x ", s->VUtable[i]);
+	}
+
+	printk("\n-------------------------------------------"
+		"----------------------------------\n");
+
+	printk("PUtable[%d-%d=%d] ->", s->firstEUN, s->lastEUN, s->nb_blocks);
+	for (i = 0; i <= s->lastEUN; i++) {
+		if ((i % 8) == 0)
+			printk("\n%04x: ", i);
+		printk("%04x ", s->PUtable[i]);
+	}
+
+	printk("\n-------------------------------------------"
+		"----------------------------------\n");
+
+	printk("INFTL ->\n"
+		"  EraseSize       = %d\n"
+		"  h/s/c           = %d/%d/%d\n"
+		"  numvunits       = %d\n"
+		"  firstEUN        = %d\n"
+		"  lastEUN         = %d\n"
+		"  numfreeEUNs     = %d\n"
+		"  LastFreeEUN     = %d\n"
+		"  nb_blocks       = %d\n"
+		"  nb_boot_blocks  = %d",
+		s->EraseSize, s->heads, s->sectors, s->cylinders,
+		s->numvunits, s->firstEUN, s->lastEUN, s->numfreeEUNs,
+		s->LastFreeEUN, s->nb_blocks, s->nb_boot_blocks);
+
+	printk("\n-------------------------------------------"
+		"----------------------------------\n");
+}
+
+void INFTL_dumpVUchains(struct INFTLrecord *s)
+{
+	int logical, block, i;
+
+	printk("-------------------------------------------"
+		"----------------------------------\n");
+
+	printk("INFTL Virtual Unit Chains:\n");
+	for (logical = 0; logical < s->nb_blocks; logical++) {
+		block = s->VUtable[logical];
+		if (block > s->nb_blocks)
+			continue;
+		printk("  LOGICAL %d --> %d ", logical, block);
+		for (i = 0; i < s->nb_blocks; i++) {
+			if (s->PUtable[block] == BLOCK_NIL)
+				break;
+			block = s->PUtable[block];
+			printk("%d ", block);
+		}
+		printk("\n");
+	}
+
+	printk("-------------------------------------------"
+		"----------------------------------\n");
+}
+
+int INFTL_mount(struct INFTLrecord *s)
+{
+	unsigned int block, first_block, prev_block, last_block;
+	unsigned int first_logical_block, logical_block, erase_mark;
+	int chain_length, do_format_chain;
+	struct inftl_unithead1 h0;
+	struct inftl_unittail h1;
+	int i, retlen;
+	u8 *ANACtable, ANAC;
+
+	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_mount(inftl=0x%x)\n", (int)s);
+
+	/* Search for INFTL MediaHeader and Spare INFTL Media Header */
+	if (find_boot_record(s) < 0) {
+		printk(KERN_WARNING "INFTL: could not find valid boot record?\n");
+		return -1;
+	}
+
+	/* Init the logical to physical table */
+	for (i = 0; i < s->nb_blocks; i++)
+		s->VUtable[i] = BLOCK_NIL;
+
+	logical_block = block = BLOCK_NIL;
+
+	/* Temporary buffer to store ANAC numbers. */
+	ANACtable = kmalloc(s->nb_blocks * sizeof(u8), GFP_KERNEL);
+	memset(ANACtable, 0, s->nb_blocks);
+
+	/*
+	 * First pass is to explore each physical unit, and construct the
+	 * virtual chains that exist (newest physical unit goes into VUtable).
+	 * Any block that is in any way invalid will be left in the
+	 * NOTEXPLORED state. Then at the end we will try to format it and
+	 * mark it as free.
+	 */
+	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 1, explore each unit\n");
+	for (first_block = s->firstEUN; first_block <= s->lastEUN; first_block++) {
+		if (s->PUtable[first_block] != BLOCK_NOTEXPLORED)
+			continue;
+
+		do_format_chain = 0;
+		first_logical_block = BLOCK_NIL;
+		last_block = BLOCK_NIL;
+		block = first_block;
+
+		for (chain_length = 0; ; chain_length++) {
+
+			if ((chain_length == 0) && 
+			    (s->PUtable[block] != BLOCK_NOTEXPLORED)) {
+				/* Nothing to do here, onto next block */
+				break;
+			}
+
+			if (MTD_READOOB(s->mtd, block * s->EraseSize + 8,
+			    8, &retlen, (char *)&h0) < 0 ||
+			    MTD_READOOB(s->mtd, block * s->EraseSize +
+			    2 * SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0) {
+				/* Should never happen? */
+				do_format_chain++;
+				break;
+			}
+
+			logical_block = le16_to_cpu(h0.virtualUnitNo);
+			prev_block = le16_to_cpu(h0.prevUnitNo);
+			erase_mark = le16_to_cpu((h1.EraseMark | h1.EraseMark1));
+			ANACtable[block] = h0.ANAC;
+
+			/* Previous block is relative to start of Partition */
+			if (prev_block < s->nb_blocks)
+				prev_block += s->firstEUN;
+
+			/* Already explored partial chain? */
+			if (s->PUtable[block] != BLOCK_NOTEXPLORED) {
+				/* Check if chain for this logical */
+				if (logical_block == first_logical_block) {
+					if (last_block != BLOCK_NIL)
+						s->PUtable[last_block] = block;
+				}
+				break;
+			}
+
+			/* Check for invalid block */
+			if (erase_mark != ERASE_MARK) {
+				printk(KERN_WARNING "INFTL: corrupt block %d "
+					"in chain %d, chain length %d, erase "
+					"mark 0x%x?\n", block, first_block,
+					chain_length, erase_mark);
+				/*
+				 * Assume end of chain, probably incomplete
+				 * fold/erase...
+				 */
+				if (chain_length == 0)
+					do_format_chain++;
+				break;
+			}
+
+			/* Check for it being free already then... */
+			if ((logical_block == BLOCK_FREE) ||
+			    (logical_block == BLOCK_NIL)) {
+				s->PUtable[block] = BLOCK_FREE;
+				break;
+			}
+
+			/* Sanity checks on block numbers */
+			if ((logical_block >= s->nb_blocks) ||
+			    ((prev_block >= s->nb_blocks) &&
+			     (prev_block != BLOCK_NIL))) {
+				if (chain_length > 0) {
+					printk(KERN_WARNING "INFTL: corrupt "
+						"block %d in chain %d?\n",
+						block, first_block);
+					do_format_chain++;
+				}
+				break;
+			}
+
+			if (first_logical_block == BLOCK_NIL) {
+				first_logical_block = logical_block;
+			} else {
+				if (first_logical_block != logical_block) {
+					/* Normal for folded chain... */
+					break;
+				}
+			}
+
+			/*
+			 * Current block is valid, so if we followed a virtual
+			 * chain to get here then we can set the previous
+			 * block pointer in our PUtable now. Then move onto
+			 * the previous block in the chain.
+			 */
+			s->PUtable[block] = BLOCK_NIL;
+			if (last_block != BLOCK_NIL)
+				s->PUtable[last_block] = block;
+			last_block = block;
+			block = prev_block;
+
+			/* Check for end of chain */
+			if (block == BLOCK_NIL)
+				break;
+
+			/* Validate next block before following it... */
+			if (block > s->lastEUN) {
+				printk(KERN_WARNING "INFTL: invalid previous "
+					"block %d in chain %d?\n", block,
+					first_block);
+				do_format_chain++;
+				break;
+			}
+		}
+
+		if (do_format_chain) {
+			format_chain(s, first_block);
+			continue;
+		}
+
+		/*
+		 * Looks like a valid chain then. It may not really be the
+		 * newest block in the chain, but it is the newest we have
+		 * found so far. We might update it in later iterations of
+		 * this loop if we find something newer.
+		 */
+		s->VUtable[first_logical_block] = first_block;
+		logical_block = BLOCK_NIL;
+	}
+
+#ifdef CONFIG_MTD_DEBUG_VERBOSE
+	if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
+		INFTL_dumptables(s);
+#endif
+
+	/*
+	 * Second pass, check for infinite loops in chains. These are
+	 * possible because we don't update the previous pointers when
+	 * we fold chains. No big deal, just fix them up in PUtable.
+	 */
+	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 2, validate virtual chains\n");
+	for (logical_block = 0; logical_block < s->numvunits; logical_block++) {
+		block = s->VUtable[logical_block];
+		last_block = BLOCK_NIL;
+
+		/* Check for free/reserved/nil */
+		if (block >= BLOCK_RESERVED)
+			continue;
+
+		ANAC = ANACtable[block];
+		for (i = 0; i < s->numvunits; i++) {
+			if (s->PUtable[block] == BLOCK_NIL)
+				break;
+			if (s->PUtable[block] > s->lastEUN) {
+				printk(KERN_WARNING "INFTL: invalid prev %d, "
+					"in virtual chain %d\n",
+					s->PUtable[block], logical_block);
+				s->PUtable[block] = BLOCK_NIL;
+					
+			}
+			if (ANACtable[block] != ANAC) {
+				/*
+				 * Chain must point back to itself. This is ok,
+				 * but we will need adjust the tables with this
+				 * newest block and oldest block.
+				 */
+				s->VUtable[logical_block] = block;
+				s->PUtable[last_block] = BLOCK_NIL;
+				break;
+			}
+
+			ANAC--;
+			last_block = block;
+			block = s->PUtable[block];
+		}
+
+		if (i >= s->nb_blocks) {
+			/*
+			 * Uhoo, infinite chain with valid ANACS!
+			 * Format whole chain...
+			 */
+			format_chain(s, first_block);
+		}
+	}
+
+#ifdef CONFIG_MTD_DEBUG_VERBOSE
+	if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
+		INFTL_dumptables(s);
+	if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
+		INFTL_dumpVUchains(s);
+#endif
+
+	/*
+	 * Third pass, format unreferenced blocks and init free block count.
+	 */
+	s->numfreeEUNs = 0;
+	s->LastFreeEUN = BLOCK_NIL;
+
+	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 3, format unused blocks\n");
+	for (block = s->firstEUN; block <= s->lastEUN; block++) {
+		if (s->PUtable[block] == BLOCK_NOTEXPLORED) {
+			printk("INFTL: unreferenced block %d, formatting it\n",
+				block);
+			if (INFTL_formatblock(s, block) < 0)
+				s->PUtable[block] = BLOCK_RESERVED;
+			else
+				s->PUtable[block] = BLOCK_FREE;
+		}
+		if (s->PUtable[block] == BLOCK_FREE) {
+			s->numfreeEUNs++;
+			if (s->LastFreeEUN == BLOCK_NIL)
+				s->LastFreeEUN = block;
+		}
+	}
+
+	kfree(ANACtable);
+	return 0;
+}
diff -urN linux-2.4.29/drivers/mtd/Makefile linux-2.4.29-uc1/drivers/mtd/Makefile
--- linux-2.4.29/drivers/mtd/Makefile	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/Makefile	2005-06-14 02:12:08.000000000 +0100
@@ -20,7 +20,7 @@
 O_TARGET	:= mtdlink.o
 
 export-objs	:= mtdcore.o mtdpart.o redboot.o cmdlinepart.o afs.o mtdconcat.o
-list-multi	:= nftl.o
+list-multi	:= nftl.o inftl.o
 
 mod-subdirs	:= 
 subdir-y	:= chips maps devices nand
@@ -49,6 +49,7 @@
 obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
 obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
 obj-$(CONFIG_MTD_AFS_PARTS)	+= afs.o
+obj-$(CONFIG_MTD_CMDLINE_PARTS)	+= cmdlinepart.o
 
 # 'Users' - code which presents functionality to userspace.
 obj-$(CONFIG_MTD_CHAR)		+= mtdchar.o
@@ -56,11 +57,16 @@
 obj-$(CONFIG_MTD_BLOCK_RO)	+= mtdblock_ro.o
 obj-$(CONFIG_FTL)		+= ftl.o
 obj-$(CONFIG_NFTL)		+= nftl.o
+obj-$(CONFIG_INFTL)		+= inftl.o
 
 nftl-objs	:= nftlcore.o nftlmount.o
+inftl-objs	:= inftlcore.o inftlmount.o
 
 include $(TOPDIR)/Rules.make
 
 nftl.o: $(nftl-objs)
 	$(LD) -r -o $@ $(nftl-objs)
 
+inftl.o: $(inftl-objs)
+	$(LD) -r -o $@ $(inftl-objs)
+
diff -urN linux-2.4.29/drivers/mtd/maps/advanta.c linux-2.4.29-uc1/drivers/mtd/maps/advanta.c
--- linux-2.4.29/drivers/mtd/maps/advanta.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/advanta.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,191 @@
+/****************************************************************************/
+
+/*
+ *      advanta.c -- mappings for Adtran Advanta 3110 board.
+ *
+ *      (C) Copyright 2002, SnapGear Inc (www.snapgear.com)
+ */
+
+/****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/cfi.h>
+#include <linux/reboot.h>
+#include <asm/io.h>
+
+/****************************************************************************/
+
+#define ADVANTA_WINDOW_MAXSIZE	0x00200000
+#define ADVANTA_BUSWIDTH		1
+
+/*
+ *	PAR masks and shifts, assuming 64K pages.
+ */
+#define SC520_PAR_ADDR_MASK	0x00003fff
+#define SC520_PAR_ADDR_SHIFT	16
+#define SC520_PAR_TO_ADDR(par) \
+	(((par)&SC520_PAR_ADDR_MASK) << SC520_PAR_ADDR_SHIFT)
+
+#define SC520_PAR_SIZE_MASK	0x01ffc000
+#define SC520_PAR_SIZE_SHIFT	2
+#define SC520_PAR_TO_SIZE(par) \
+	((((par)&SC520_PAR_SIZE_MASK) << SC520_PAR_SIZE_SHIFT) + (64*1024))
+
+#define SC520_PAR(cs, addr, size) \
+	((cs) | \
+	((((size)-(64*1024)) >> SC520_PAR_SIZE_SHIFT) & SC520_PAR_SIZE_MASK) | \
+	(((addr) >> SC520_PAR_ADDR_SHIFT) & SC520_PAR_ADDR_MASK))
+
+#define SC520_PAR_BOOTCS	0x8a000000
+#define	SC520_PAR_ROMCS1	0xaa000000
+#define SC520_PAR_ROMCS2	0xca000000	/* Cache disabled, 64K page */
+
+static struct mtd_info *advanta_mtd;
+
+/****************************************************************************/
+
+static __u8 advanta_read8(struct map_info *map, unsigned long ofs)
+{
+	return(readb(map->map_priv_1 + ofs));
+}
+
+static __u16 advanta_read16(struct map_info *map, unsigned long ofs)
+{
+	return(readw(map->map_priv_1 + ofs));
+}
+
+static __u32 advanta_read32(struct map_info *map, unsigned long ofs)
+{
+	return(readl(map->map_priv_1 + ofs));
+}
+
+static void advanta_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+static void advanta_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	writeb(d, map->map_priv_1 + adr);
+}
+
+static void advanta_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	writew(d, map->map_priv_1 + adr);
+}
+
+static void advanta_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	writel(d, map->map_priv_1 + adr);
+}
+
+static void advanta_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+/****************************************************************************/
+
+static struct map_info advanta_map = {
+	name: "Adtran Advanta",
+	size: 256*1024,
+	buswidth: ADVANTA_BUSWIDTH,
+	read8: advanta_read8,
+	read16: advanta_read16,
+	read32: advanta_read32,
+	copy_from: advanta_copy_from,
+	write8: advanta_write8,
+	write16: advanta_write16,
+	write32: advanta_write32,
+	copy_to: advanta_copy_to
+};
+
+static struct mtd_partition advanta_partitions[] = {
+	{
+		name: "All",
+		offset: 0
+	},
+};
+
+#define NUM_PARTITIONS \
+	(sizeof(advanta_partitions)/sizeof(advanta_partitions[0]))
+
+/****************************************************************************/
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_nettel init_module
+#define cleanup_nettel cleanup_module
+#endif
+
+mod_init_t init_advanta(void)
+{
+	static void *mmcrp = NULL;
+	volatile unsigned long *par;
+	unsigned long addr, maxsize;
+	int rc;
+
+	mmcrp = (void *) ioremap_nocache(0xfffef000, 4096);
+	if (mmcrp == NULL) {
+		printk("Advanta: failed to disable MMCR cache??\n");
+		return(-EIO);
+	}
+
+	/* Set up DoC CS */
+	*(unsigned long *)(mmcrp + 0xa8) = 0x440400d0;
+
+	/* Set up OTP EPROM CS */
+	par = (volatile unsigned long *)(mmcrp + 0xc0);
+	addr = 0x20000000;
+	maxsize = ADVANTA_WINDOW_MAXSIZE;
+
+	*par = SC520_PAR(SC520_PAR_BOOTCS, addr, maxsize);
+	__asm__ ("wbinvd");
+
+	advanta_map.map_priv_1 = (unsigned long)ioremap_nocache(addr, maxsize);
+	if (!advanta_map.map_priv_1) {
+		printk("Advanta: failed to ioremap() BOOTCS\n");
+		return(-EIO);
+	}
+
+	advanta_mtd = do_map_probe("map_rom", &advanta_map);
+	if (!advanta_mtd) {
+		iounmap((void *)advanta_map.map_priv_1);
+		return(-ENXIO);
+	}
+
+	rc = add_mtd_partitions(advanta_mtd, advanta_partitions,
+		NUM_PARTITIONS);
+
+	return rc;
+}
+
+/****************************************************************************/
+
+mod_exit_t cleanup_advanta(void)
+{
+	if (advanta_mtd) {
+		del_mtd_partitions(advanta_mtd);
+		map_destroy(advanta_mtd);
+	}
+	if (advanta_map.map_priv_1) {
+		iounmap((void *)advanta_map.map_priv_1);
+		advanta_map.map_priv_1 = 0;
+	}
+}
+
+/****************************************************************************/
+
+module_init(init_advanta);
+module_exit(cleanup_advanta);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Philip Craig <philipc@snapgear.com>");
+MODULE_DESCRIPTION("Adtran Advanta 3110 OTP EPROM support");
+
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/mtd/maps/bf533-flash.c linux-2.4.29-uc1/drivers/mtd/maps/bf533-flash.c
--- linux-2.4.29/drivers/mtd/maps/bf533-flash.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/bf533-flash.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,168 @@
+/*
+ * Flash memory access on BlackFin BF533 based devices
+ * 
+ * (C) 2000 Nicolas Pitre <nico@cam.org>
+ * 
+ * $Id: bf533-flash.c,v 1.1 2003/10/16 10:45:47 bas Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#ifndef CONFIG_BLACKFIN_EZKIT
+#error This is for BlackFin ADDS-BF533-EZLITE boards only
+#endif
+
+
+#define WINDOW_ADDR 0x20000000
+
+#ifndef lo
+# define lo(addr)	(addr & 0xFFFF)
+#endif
+#ifndef hi
+# define hi(addr)	(addr >> 16)
+#endif
+
+static __u16 bf533_read16(struct map_info *map, unsigned long ofs)
+{
+	int nValue = 0x0;
+	__asm__ __volatile__ (
+		"p2.l = 0x0000; \n\t"
+		"p2.h = 0x2000; \n\t"
+		"r3 = %1; \n\t"
+		"r2 = p2; \n\t"
+		"r2 = r2 + r3; \n\t"
+		"p2 = r2; \n\t"
+		/* The actual thing */
+		"ssync; \n\t"
+		"%0 = w[p2] (z); \n\t"
+		"ssync; \n\t"
+		: "=d" (nValue)
+		: "d" (ofs));
+	return (__u16)nValue;
+}
+
+static void bf533_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	unsigned long i;
+
+	for (i = 0; i < len; i += 2)
+		*((u16*)(to + i)) = bf533_read16(map, from + i);
+	if (len & 0x01)
+		*((u8*)(to + (i-1))) = (u8)(bf533_read16(map, from + i) >> 8);
+}
+
+static void bf533_write16(struct map_info *map, __u16 d, unsigned long ofs)
+{
+	__asm__ __volatile__ (
+		"p2.l = 0x0000; \n\t"
+		"p2.h = 0x2000; \n\t"
+		"r3 = %1; \n\t"
+		"r2 = p2; \n\t"
+		"r2 = r2 + r3; \n\t"
+		"p2 = r2; \n\t"
+		/* The actual thing */
+		"ssync; \n\t"
+		"w[p2] = %0; \n\t"
+		"ssync; \n\t"
+		: 
+		: "d" (d), "d" (ofs));
+}
+
+static void bf533_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy((void *)(WINDOW_ADDR + to), from, len);
+}
+
+static struct map_info bf533_map = {
+	name:		"BF533 flash",
+	read8:		NULL,
+	read16:		bf533_read16,
+	read32:		NULL,
+	copy_from:	bf533_copy_from,
+	write8:		NULL,
+	write16:	bf533_write16,
+	write32:	NULL,
+	copy_to:	bf533_copy_to
+};
+
+
+/*
+ * Here are partition information for all known BlackFin-based devices.
+ * See include/linux/mtd/partitions.h for definition of the mtd_partition
+ * structure.
+ * 
+ * The *_max_flash_size is the maximum possible mapped flash size which
+ * is not necessarily the actual flash size.  It must correspond to the 
+ * value specified in the mapping definition defined by the
+ * "struct map_desc *_io_desc" for the corresponding machine.
+ */
+
+static unsigned long bf533_max_flash_size = 0x00200000;
+static struct mtd_partition bf533_partitions[] = {
+	{
+		name: "bootloader",
+		size: 0x00010000,
+		offset: 0,
+		mask_flags: MTD_CAP_ROM
+	},{
+		name: "kernel image",
+		size: MTDPART_SIZ_FULL,
+		offset: MTDPART_OFS_APPEND
+	}
+};
+
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+static struct mtd_info *mymtd;
+
+int __init bf533_mtd_init(void)
+{
+	struct mtd_partition *parts;
+	int nb_parts = 0;
+	char *part_type;
+	
+	bf533_map.buswidth = 2;
+	bf533_map.size = bf533_max_flash_size;
+
+	printk(KERN_NOTICE "BF533 flash: probing %d-bit flash bus\n", bf533_map.buswidth*8);
+	mymtd = do_map_probe("stm_flash", &bf533_map);
+	if (!mymtd)
+		return -ENXIO;
+	mymtd->module = THIS_MODULE;
+
+	/*
+	 * Static partition definition selection
+	 */
+	part_type = "static";
+#ifdef CONFIG_BLACKFIN_EZKIT
+	parts = bf533_partitions;
+	nb_parts = NB_OF(bf533_partitions);
+#endif
+
+	if (nb_parts == 0) {
+		printk(KERN_NOTICE "BF533 flash: no partition info available, registering whole flash at once\n");
+		add_mtd_device(mymtd);
+	} else {
+		printk(KERN_NOTICE "Using %s partition definition\n", part_type);
+		add_mtd_partitions(mymtd, parts, nb_parts);
+	}
+	return 0;
+}
+
+static void __exit bf533_mtd_cleanup(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+}
+
+module_init(bf533_mtd_init);
+module_exit(bf533_mtd_cleanup);
diff -urN linux-2.4.29/drivers/mtd/maps/ceiva.c linux-2.4.29-uc1/drivers/mtd/maps/ceiva.c
--- linux-2.4.29/drivers/mtd/maps/ceiva.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/ceiva.c	2005-06-14 02:12:08.000000000 +0100
@@ -318,7 +318,7 @@
 	return nr;
 }
 
-extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts, unsigned long fis_origin);
 extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, char *);
 
 static struct mtd_partition *parsed_parts;
@@ -339,7 +339,7 @@
 		}
 #endif
 #ifdef CONFIG_MTD_REDBOOT_PARTS
-		nr_parts = parse_redboot_partitions(mtd, &parsed_parts);
+		nr_parts = parse_redboot_partitions(mtd, &parsed_parts, 0);
 		if (nr_parts > 0) {
 			part_type = "RedBoot";
 			break;
diff -urN linux-2.4.29/drivers/mtd/maps/clps7500.c linux-2.4.29-uc1/drivers/mtd/maps/clps7500.c
--- linux-2.4.29/drivers/mtd/maps/clps7500.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/clps7500.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,171 @@
+/*
+ * $Id: clps7500.c,v 1.2 2002/09/05 05:11:24 acurtis Exp $
+ *
+ * Handle mapping of the NOR flash on CL-PS7500FE boards
+ *
+ * Copyright 2002 SYSGO Real-Time Solutions GmbH
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/config.h>
+
+#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/partitions.h>
+#endif
+
+#define WINDOW_ADDR 0x00000000      /* physical properties of flash */
+#define WINDOW_SIZE 0x00800000
+#define BUSWIDTH    4
+/* can be "cfi_probe", "jedec_probe", "map_rom", 0 }; */
+#define PROBETYPES { "cfi_probe", 0 }
+
+#define MSG_PREFIX "CLPS7500FE-NOR:"   /* prefix for our printk()'s */
+#define MTDID      "clps7500fe-nor"    /* for mtdparts= partitioning */
+
+static struct mtd_info *mymtd;
+
+__u8 clps7500nor_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u32 clps7500nor_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void clps7500nor_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void clps7500nor_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void clps7500nor_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void clps7500nor_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info clps7500nor_map = {
+	name: "NOR flash on CL-PS7500FE",
+	size: WINDOW_SIZE,
+	buswidth: BUSWIDTH,
+	read8: clps7500nor_read8,
+	read32: clps7500nor_read32,
+	copy_from: clps7500nor_copy_from,
+	write8: clps7500nor_write8,
+	write32: clps7500nor_write32,
+	copy_to: clps7500nor_copy_to
+};
+
+#ifdef CONFIG_MTD_PARTITIONS
+
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+int parse_cmdline_partitions(struct mtd_info *master, 
+			     struct mtd_partition **pparts,
+			     const char *mtd_id);
+#endif
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+int parse_redboot_partitions(struct mtd_info *master,
+			     struct mtd_partition **pparts);
+#endif
+
+#endif
+
+static int                   mtd_parts_nb = 0;
+static struct mtd_partition *mtd_parts    = 0;
+
+int __init init_clps7500nor(void)
+{
+	static const char *rom_probe_types[] = PROBETYPES;
+	const char **type;
+	const char *part_type = 0;
+
+       	printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n", 
+	       WINDOW_SIZE, WINDOW_ADDR);
+	clps7500nor_map.map_priv_1 = (unsigned long)
+	  ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+	if (!clps7500nor_map.map_priv_1) {
+		printk(MSG_PREFIX "failed to ioremap\n");
+		return -EIO;
+	}
+
+	mymtd = 0;
+	type = rom_probe_types;
+	for(; !mymtd && *type; type++) {
+		mymtd = do_map_probe(*type, &clps7500nor_map);
+	}
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+		mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts, MTDID);
+		if (mtd_parts_nb > 0)
+		  part_type = "command line";
+		else if (mtd_parts_nb < 0)
+		  mtd_parts_nb = 0;
+#endif
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+		if (mtd_parts_nb <= 0)
+		{
+			mtd_parts_nb = parse_redboot_partitions(mymtd, &mtd_parts);
+			if (mtd_parts_nb > 0)
+				part_type = "redboot";
+		}
+#endif
+#endif
+		add_mtd_device(mymtd);
+		if (mtd_parts_nb <= 0)
+		  printk(KERN_NOTICE MSG_PREFIX "no partition info available\n");
+		else
+		{
+			printk(KERN_NOTICE MSG_PREFIX
+			       "using %s partition definition\n", part_type);
+			add_mtd_partitions(mymtd, mtd_parts, mtd_parts_nb);
+		}
+		return 0;
+	}
+
+	iounmap((void *)clps7500nor_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_clps7500nor(void)
+{
+	if (mymtd) {
+		del_mtd_device(mymtd);
+		map_destroy(mymtd);
+	}
+	if (clps7500nor_map.map_priv_1) {
+		iounmap((void *)clps7500nor_map.map_priv_1);
+		clps7500nor_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_clps7500nor);
+module_exit(cleanup_clps7500nor);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marius Groeger <mag@sysgo.de>");
+MODULE_DESCRIPTION("Generic configurable MTD map driver");
diff -urN linux-2.4.29/drivers/mtd/maps/cobra5272.c linux-2.4.29-uc1/drivers/mtd/maps/cobra5272.c
--- linux-2.4.29/drivers/mtd/maps/cobra5272.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/cobra5272.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,220 @@
+/*
+ * This file is "heavily based" ;) on physmap.c, which I copied
+ * and changed to suit my needs! But to show who is responsible
+ * for the file I included the new copyright. I don't know if that
+ * is the correct way, so if this should be a problem, please
+ * email me! 
+ * 
+ * (C) 2002 senTec Elektronik GmbH, Heiko Degenhardt
+ * <linux@sentec-elektronik.de>
+ * 
+ * ----------------------------------------------------------------------
+ * File:       cobra5272.c
+ * Place:      uClinux-dist/linux-2.4.x/drivers/mtd/maps/
+ * Author:     Heiko Degenhardt (linux@sentec-elektronik.de)
+ * Contents:   Flash layout of the COBRA5272 board.
+ * Version:    v01.00
+ * Date:       Mon Mar 25 09:01:01 CET 2002
+ * ______________________________________________________________________
+ *
+ * CHANGES
+ * 020325   v01.00 Creation from physmap.c
+ *          (hede)
+ * ______________________________________________________________________
+ *
+ *  This program is free software; you can redistribute  it and/or
+ *  modify it under  the terms of  the GNU General  Public License as
+ *  published by the Free Software Foundation;  either version 2 of
+ *  the  License, or (at your option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR
+ *  IMPLIED WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED.  IN NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE
+ *  FOR ANY   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED   TO,
+ *  PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ *  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ *  SUCH DAMAGE.
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Mappings of chips in memory of the senTec COBRA5272 board.
+ * 
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/config.h>
+
+
+#define WINDOW_ADDR 0xffe00000
+#define WINDOW_SIZE 0x200000
+#define BUSWIDTH 2
+
+static struct mtd_info *mymtd;
+
+__u8 cb5272map_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 cb5272map_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 cb5272map_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void cb5272map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void cb5272map_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void cb5272map_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void cb5272map_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void cb5272map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info cb5272map_map = {
+	name: "Physically mapped flash of COBRA5272",
+	size: WINDOW_SIZE,
+	buswidth: BUSWIDTH,
+	read8: cb5272map_read8,
+	read16: cb5272map_read16,
+	read32: cb5272map_read32,
+	copy_from: cb5272map_copy_from,
+	write8: cb5272map_write8,
+	write16: cb5272map_write16,
+	write32: cb5272map_write32,
+	copy_to: cb5272map_copy_to
+};
+
+/*
+ * MTD 'PARTITIONING' STUFF 
+ */
+#define NUM_PARTITIONS 10
+static struct mtd_partition nettel_partitions[NUM_PARTITIONS] = {
+        {
+                name: "boot (16K)",
+                size: 0x4000,
+                offset: 0
+        },
+        {
+                name: "kernel (512K)",
+                size: 0x80000,
+                offset: 0x80000
+        },
+        {
+                name: "rootfs (1024K)",
+                size: 0x100000,
+                offset: 0x100000
+        },
+	{
+                name: "spare (8K)",
+                size: 0x2000,
+                offset: 0x4000
+        },
+        {
+                name: "spare (8K)",
+                size: 0x2000,
+                offset: 0x6000
+        },
+        {
+                name: "spare (256K)",
+                size: 0x40000,
+                offset: 0x40000
+        },
+        {
+                name: "complete (2048K)",
+                size: 0x200000,
+                offset: 0x0
+        },
+        {
+                name: "boot J13 (256K)",
+                size: 0x40000,
+                offset: 0x100000
+        },
+        {
+                name: "kernel J13 (512K)",
+                size: 0x80000,
+                offset: 0x140000
+        },
+        {
+                name: "rootfs J13 (256K)",
+                size: 0x40000,
+                offset: 0x1c0000
+        }
+};
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_cb5272map init_module
+#define cleanup_cb5272map cleanup_module
+#endif
+
+int __init init_cb5272map(void)
+{
+  	printk(KERN_NOTICE "cb5272map flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
+	cb5272map_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+	if (!cb5272map_map.map_priv_1) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}
+	mymtd = do_map_probe("cfi_probe", &cb5272map_map);
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+
+		return add_mtd_partitions(mymtd, nettel_partitions, NUM_PARTITIONS);
+	}
+
+	iounmap((void *)cb5272map_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_cb5272map(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+	if (cb5272map_map.map_priv_1) {
+		iounmap((void *)cb5272map_map.map_priv_1);
+		cb5272map_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_cb5272map);
+module_exit(cleanup_cb5272map);
+
diff -urN linux-2.4.29/drivers/mtd/maps/cobra5282.c linux-2.4.29-uc1/drivers/mtd/maps/cobra5282.c
--- linux-2.4.29/drivers/mtd/maps/cobra5282.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/cobra5282.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,221 @@
+/*
+ * This file is "heavily based" ;) on physmap.c, which I copied
+ * and changed to suit my needs! But to show who is responsible
+ * for the file I included the new copyright. I don't know if that
+ * is the correct way, so if this should be a problem, please
+ * email me! 
+ * 
+ * (C) 2004 senTec Elektronik GmbH, Heiko Degenhardt
+ * <linux@sentec-elektronik.de>
+ * 
+ * ----------------------------------------------------------------------
+ * File:       cobra5282.c
+ * Place:      uClinux-dist/linux-2.4.x/drivers/mtd/maps/
+ * Author:     Heiko Degenhardt (linux@sentec-elektronik.de)
+ *             Wolfgang Elsner (linux@sentec-elektronik.de)
+ * Contents:   Flash layout of the COBRA5282 board.
+ * Version:    v01.00
+ * Date:       
+ * ______________________________________________________________________
+ *
+ * CHANGES
+ * 040324   v01.00 Creation from cobra5272.c
+ *          (woel)
+ * ______________________________________________________________________
+ *
+ *  This program is free software; you can redistribute  it and/or
+ *  modify it under  the terms of  the GNU General  Public License as
+ *  published by the Free Software Foundation;  either version 2 of
+ *  the  License, or (at your option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR
+ *  IMPLIED WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED.  IN NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE
+ *  FOR ANY   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED   TO,
+ *  PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ *  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ *  SUCH DAMAGE.
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Mappings of chips in memory of the senTec COBRA5282 board.
+ * 
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/config.h>
+
+
+#define WINDOW_ADDR 0xffc00000
+#define WINDOW_SIZE 0x400000
+#define BUSWIDTH 2
+
+static struct mtd_info *mymtd;
+
+__u8 cb5282map_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 cb5282map_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 cb5282map_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void cb5282map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void cb5282map_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void cb5282map_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void cb5282map_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void cb5282map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info cb5282map_map = {
+	name: "Physically mapped flash of COBRA5282",
+	size: WINDOW_SIZE,
+	buswidth: BUSWIDTH,
+	read8: cb5282map_read8,
+	read16: cb5282map_read16,
+	read32: cb5282map_read32,
+	copy_from: cb5282map_copy_from,
+	write8: cb5282map_write8,
+	write16: cb5282map_write16,
+	write32: cb5282map_write32,
+	copy_to: cb5282map_copy_to
+};
+
+/*
+ * MTD 'PARTITIONING' STUFF 
+ */
+#define NUM_PARTITIONS 10
+static struct mtd_partition nettel_partitions[NUM_PARTITIONS] = {
+        {
+                name: "boot (16K)",
+                size: 0x4000,
+                offset: 0
+        },
+        {
+                name: "kernel (512K)",
+                size: 0x80000,
+                offset: 0x80000
+        },
+        {
+                name: "rootfs (1024K)",
+                size: 0x100000,
+                offset: 0x100000
+        },
+	{
+                name: "spare (8K)",
+                size: 0x2000,
+                offset: 0x4000
+        },
+        {
+                name: "spare (8K)",
+                size: 0x2000,
+                offset: 0x6000
+        },
+        {
+                name: "spare (256K)",
+                size: 0x40000,
+                offset: 0x40000
+        },
+        {
+                name: "complete (2048K)",
+                size: 0x200000,
+                offset: 0x0
+        },
+        {
+                name: "boot J13 (256K)",
+                size: 0x40000,
+                offset: 0x100000
+        },
+        {
+                name: "kernel J13 (512K)",
+                size: 0x80000,
+                offset: 0x140000
+        },
+        {
+                name: "rootfs J13 (256K)",
+                size: 0x40000,
+                offset: 0x1c0000
+        }
+};
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_cb5282map init_module
+#define cleanup_cb5282map cleanup_module
+#endif
+
+int __init init_cb5282map(void)
+{
+  	printk(KERN_NOTICE "cb5282map flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
+	cb5282map_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+	if (!cb5282map_map.map_priv_1) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}
+	mymtd = do_map_probe("cfi_probe", &cb5282map_map);
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+
+		return add_mtd_partitions(mymtd, nettel_partitions, NUM_PARTITIONS);
+	}
+
+	iounmap((void *)cb5282map_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_cb5282map(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+	if (cb5282map_map.map_priv_1) {
+		iounmap((void *)cb5282map_map.map_priv_1);
+		cb5282map_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_cb5282map);
+module_exit(cleanup_cb5282map);
+
diff -urN linux-2.4.29/drivers/mtd/maps/Config.in linux-2.4.29-uc1/drivers/mtd/maps/Config.in
--- linux-2.4.29/drivers/mtd/maps/Config.in	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/Config.in	2005-06-14 02:12:08.000000000 +0100
@@ -1,6 +1,6 @@
 # drivers/mtd/maps/Config.in
 
-# $Id: Config.in,v 1.43 2003/01/24 14:26:38 dwmw2 Exp $
+# $Id: Config.in,v 1.2 2003/10/24 11:00:57 bas Exp $
 
 mainmenu_option next_comment
 
@@ -13,6 +13,49 @@
    int '    Bus width in octets' CONFIG_MTD_PHYSMAP_BUSWIDTH 2
 fi
 
+dep_tristate '  CFI Flash device mapped on Dragonix VZ' CONFIG_MTD_DRAGONIX $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_PARTITIONS
+dep_tristate '  CFI Flash device mapped on SnapGear/SecureEdge' CONFIG_MTD_NETtel $CONFIG_MTD_PARTITIONS
+dep_tristate '  CFI Flash device mapped on SnapGear/GEODE boards' CONFIG_MTD_SNAPGEODE $CONFIG_MTD_PARTITIONS
+dep_tristate '  CFI Flash device mapped on SnapGear/SecureEdge (uClinux)' CONFIG_MTD_NETteluC $CONFIG_UCLINUX $CONFIG_MTD_PARTITIONS
+if [ "$CONFIG_MTD_NETteluC" = "y" ]; then
+   choice '  FLASH size' \
+           " AUTO  CONFIG_FLASHAUTO \
+            128KB  CONFIG_FLASH128KB \
+              1MB  CONFIG_FLASH1MB \
+              2MB  CONFIG_FLASH2MB \
+              4MB  CONFIG_FLASH4MB \
+              6MB  CONFIG_FLASH6MB \
+              8MB  CONFIG_FLASH8MB \
+             16MB  CONFIG_FLASH16MB" AUTO
+fi
+dep_tristate '  CFI Flash device mapped on Microblaze/mbvanilla (uClinux)' CONFIG_MTD_MBVANILLA $CONFIG_UCLINUX $CONFIG_MTD_PARTITIONS
+if [ "$CONFIG_MTD_MBVANILLA" = "y" ]; then
+   choice '  FLASH size' \
+           " AUTO  CONFIG_FLASHAUTO \
+            128KB  CONFIG_FLASH128KB \
+              1MB  CONFIG_FLASH1MB \
+              2MB  CONFIG_FLASH2MB \
+              4MB  CONFIG_FLASH4MB \
+              6MB  CONFIG_FLASH6MB \
+              8MB  CONFIG_FLASH8MB " AUTO
+fi
+
+dep_tristate '  CFI Flash device mapped on Microblaze/ML401 (uClinux)' CONFIG_MTD_ML401 $CONFIG_MICROBLAZE $CONFIG_UCLINUX $CONFIG_ML401 $CONFIG_MTD_PARTITIONS
+if [ "$CONFIG_MTD_ML401" = "y" ]; then
+   choice '  FLASH size' \
+           " AUTO  CONFIG_FLASHAUTO \
+            128KB  CONFIG_FLASH128KB \
+              1MB  CONFIG_FLASH1MB \
+              2MB  CONFIG_FLASH2MB \
+              4MB  CONFIG_FLASH4MB \
+              6MB  CONFIG_FLASH6MB \
+              8MB  CONFIG_FLASH8MB " 8MB
+fi
+
+dep_tristate '  CFI Flash device mapped on Microblaze/SUZAKU (uClinux)' CONFIG_MTD_SUZAKU $CONFIG_MICROBLAZE $CONFIG_SUZAKU $CONFIG_MTD_PARTITIONS
+
+dep_tristate '  CFI Flash device mapped on Key Technology devices' CONFIG_MTD_KeyTechnology $CONFIG_UCLINUX $CONFIG_MTD_PARTITIONS
+dep_tristate '  CFI Flash device mapped on SED SIOS III Core' CONFIG_MTD_SED_SIOSIII $CONFIG_MTD_PARTITIONS
 if [ "$CONFIG_SPARC" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
    dep_tristate '  Sun Microsystems userflash support' CONFIG_MTD_SUN_UFLASH $CONFIG_MTD_CFI
 fi
@@ -30,11 +73,11 @@
    dep_tristate '  JEDEC Flash device mapped on Mixcom piggyback card' CONFIG_MTD_MIXMEM $CONFIG_MTD_JEDEC
    dep_tristate '  JEDEC Flash device mapped on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC
    dep_tristate '  JEDEC Flash device mapped on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC
+   dep_tristate '  OTP EPROM device mapped on Adtran Advanta 3110' CONFIG_MTD_ADVANTA $CONFIG_MTD_ROM
    dep_tristate '  Flash device mapped with DOCCS on NatSemi SCx200' CONFIG_MTD_SCx200_DOCFLASH $CONFIG_MTD_CFI
    dep_tristate '  BIOS flash chip on Intel L440GX boards' CONFIG_MTD_L440GX $CONFIG_MTD_JEDECPROBE
    dep_tristate '  ROM connected to AMD76X southbridge' CONFIG_MTD_AMD76XROM $CONFIG_MTD_GEN_PROBE   
    dep_tristate '  ROM connected to Intel Hub Controller 2' CONFIG_MTD_ICH2ROM $CONFIG_MTD_JEDECPROBE
-   dep_tristate '  CFI Flash device mapped on SnapGear/SecureEdge' CONFIG_MTD_NETtel $CONFIG_MTD_PARTITIONS
    dep_tristate '  BIOS flash chip on Intel SCB2 boards' CONFIG_MTD_SCB2_FLASH $CONFIG_MTD_GEN_PROBE
 fi
 
@@ -74,6 +117,10 @@
    fi
 fi
 
+if [ "$CONFIG_SUPERH" = "y" ]; then
+   tristate '  Hitachi SH KeyWest Intel flash device' CONFIG_MTD_KEYWEST
+fi
+
 if [ "$CONFIG_ARM" = "y" ]; then
    dep_tristate '  CFI Flash device mapped on Nora' CONFIG_MTD_NORA $CONFIG_MTD_CFI
    dep_tristate '  CFI Flash device mapped on ARM Integrator/P720T' CONFIG_MTD_ARM_INTEGRATOR $CONFIG_MTD_CFI
@@ -84,18 +131,66 @@
    dep_tristate '  CFI Flash device mapped on Epxa10db' CONFIG_MTD_EPXA10DB $CONFIG_MTD_CFI  $CONFIG_MTD_PARTITIONS $CONFIG_ARCH_CAMELOT
    dep_tristate '  CFI Flash device mapped on the FortuNet board' CONFIG_MTD_FORTUNET $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS $CONFIG_SA1100_FORTUNET
    dep_tristate '  NV-RAM mapping AUTCPU12 board' CONFIG_MTD_AUTCPU12 $CONFIG_ARCH_AUTCPU12
-   dep_tristate '  CFI Flash device mapped on EDB7312' CONFIG_MTD_EDB7312 $CONFIG_MTD_CFI
+   dep_tristate '  CFI Flash device mapped on IXP425' CONFIG_MTD_IXP425 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS
+   dep_tristate '  CFI Flash device mapped on SnapGear SE4000 board' CONFIG_MTD_SE4000 $CONFIG_MTD_CFI $CONFIG_ARCH_SE4000
+   dep_tristate '  CFI Flash device mapped on SnapGear ARM based boards' CONFIG_MTD_SNAPARM $CONFIG_MTD_CFI
+   dep_tristate '  CFI Flash device mapped on TI TMS320DM270' CONFIG_MTD_DM270 $CONFIG_MTD_CFI $CONFIG_ARCH_DM270 $CONFIG_MTD_PARTITIONS
+   dep_tristate '  CFI Flash device mapped on CL-PS7500FE' CONFIG_MTD_CLPS7500 $CONFIG_ARCH_CLPS7500 $CONFIG_MTD_CFI
+   dep_tristate '  CFI Flash device mapped on EDB7312' CONFIG_MTD_EDB7312 $CONFIG_ARCH_EDB7312 $CONFIG_MTD_CFI
+   dep_tristate '  CFI Flash device mapped on EDB9301' CONFIG_MTD_EDB9301 $CONFIG_ARCH_EDB9301 $CONFIG_MTD_CFI
+   dep_tristate '  CFI Flash device mapped on EDB9302' CONFIG_MTD_EDB9302 $CONFIG_ARCH_EDB9302 $CONFIG_MTD_CFI
+   dep_tristate '  CFI Flash device mapped on EDB9312' CONFIG_MTD_EDB9312 $CONFIG_ARCH_EDB9312 $CONFIG_MTD_CFI
+   dep_tristate '  CFI Flash device mapped on EDB9315' CONFIG_MTD_EDB9315 $CONFIG_ARCH_EDB9315 $CONFIG_MTD_CFI
    dep_tristate '  JEDEC Flash device mapped on impA7' CONFIG_MTD_IMPA7 $CONFIG_MTD_JEDECPROBE
    dep_tristate '  JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame' CONFIG_MTD_CEIVA $CONFIG_MTD_JEDECPROBE  $CONFIG_ARCH_CEIVA
+   dep_tristate '  JEDEC Flash device mapped on TI TMS320VC547X' CONFIG_MTD_VC547X $CONFIG_MTD_JEDECPROBE
+   dep_tristate '  JEDEC Flash device mapped on Tiburon (Actiontec DPCM)' CONFIG_MTD_TIBURON $CONFIG_MTD_JEDECPROBE
+fi
+
+if [ "$CONFIG_COBRA5272" = "y" ]; then
+	dep_tristate '  CFI Flash device mapped on COBRA5272' CONFIG_MTD_COBRA5272 $CONFIG_MTD_CFI
+fi
+
+if [ "$CONFIG_M5272C3" ]; then
+   dep_tristate '  CFI Flash device mapped on Motorola M5272C3' CONFIG_MTD_M5272C3 $CONFIG_MTD_CFI
+fi
+
+if [ "$CONFIG_SNEHA" ]; then
+   dep_tristate '  CFI Flash device mapped on SNEHA CPU16B' CONFIG_MTD_CPU16B $CONFIG_MTD_CFI
 fi
+
 if [ "$CONFIG_ALPHA" = "y" ]; then
    dep_tristate '  Flash chip mapping on TSUNAMI' CONFIG_MTD_TSUNAMI $CONFIG_MTD_GENPROBE
 fi
 
+if [ "$CONFIG_DNP5280" = "y" ]; then
+	dep_tristate '  CFI Flash device mapped on DNP5280' CONFIG_MTD_DNP5280 $CONFIG_MTD_CFI
+fi
+
+if [ "$CONFIG_COBRA5282" = "y" ]; then
+	dep_tristate '  CFI Flash device mapped on COBRA5282' CONFIG_MTD_COBRA5282 $CONFIG_MTD_CFI
+fi
+
+if [ "$CONFIG_BLACKFIN" = "y" ]; then
+   dep_tristate '  ADDS-BF533-EZLITE Flash support' CONFIG_MTD_BLACKFIN_533 $CONFIG_MTD_PARTITIONS $CONFIG_BLACKFIN_EZKIT
+fi
+
 if [ "$CONFIG_UCLINUX" = "y" ]; then
    dep_tristate '  Generic uClinux RAM/ROM filesystem support' CONFIG_MTD_UCLINUX $CONFIG_MTD_PARTITIONS
 fi
 
+if [ "$CONFIG_HW_FEITH" = "y" ]; then
+	dep_tristate '  CFI Flash device mapped on Feith boards' CONFIG_MTD_FEITH $CONFIG_MTD_CFI
+fi
+if [ "$CONFIG_MTD_FEITH" = "y" ]; then
+   choice '  FLASH size' \
+           " AUTO  CONFIG_FLASHAUTO \
+              2MB  CONFIG_FLASH2MB \
+              4MB  CONFIG_FLASH4MB \
+              6MB  CONFIG_FLASH6MB \
+             16MB  CONFIG_FLASH8MB" AUTO
+fi
+
 # This needs CFI or JEDEC, depending on the cards found.
 dep_tristate '  PCI MTD driver' CONFIG_MTD_PCI $CONFIG_MTD $CONFIG_PCI
 dep_tristate '  PCMCIA MTD driver' CONFIG_MTD_PCMCIA $CONFIG_MTD $CONFIG_PCMCIA
diff -urN linux-2.4.29/drivers/mtd/maps/coyote.c linux-2.4.29-uc1/drivers/mtd/maps/coyote.c
--- linux-2.4.29/drivers/mtd/maps/coyote.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/coyote.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,222 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/cfi.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+
+#include <linux/notifier.h>
+
+#define WINDOW_ADDR 	0x50000000
+#define BUSWIDTH 	2
+#define WINDOW_SIZE	0x01000000
+
+#ifndef __ARMEB__
+#define	B_0(h)	((h) & 0xFF)
+#define	B_1(h)	(((h) >> 8) & 0xFF)
+#else
+#define	B_0(h)	(((h) >> 8) & 0xFF)
+#define	B_1(h)	((h) & 0xFF)
+#endif
+
+static __u16 coyote_read16(struct map_info *map, unsigned long ofs)
+{
+    return *(__u16 *)(map->map_priv_1 + ofs);
+}
+
+/*
+ * The IXP425 expansion bus only allows 16-bit wide acceses
+ * when attached to a 16-bit wide device (such as the 28F128J3A),
+ * so we can't use a memcpy_fromio as it does byte acceses.
+ */
+static void coyote_copy_from(struct map_info *map, void *to,
+    unsigned long from, ssize_t len)
+{
+	int i;
+	u8 *dest = (u8*)to;
+	u16 *src = (u16 *)(map->map_priv_1 + from);
+	u16 data;
+
+	for(i = 0; i < (len / 2); i++) {
+		data = src[i];
+		dest[i * 2] = B_0(data);
+		dest[i * 2 + 1] = B_1(data);
+	}
+
+	if(len & 1)
+		dest[len - 1] = B_0(src[i]);
+}
+
+static void coyote_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+    *(__u16 *)(map->map_priv_1 + adr) = d;
+}
+
+static struct map_info coyote_map = {
+	name: 		"IXP425 Residential Gateway Demo Platform Flash",
+	buswidth: 	BUSWIDTH,
+	read16:		coyote_read16,
+	copy_from:	coyote_copy_from,
+	write16:	coyote_write16,
+};
+
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+static struct mtd_partition *parsed_parts;
+#endif
+
+#ifdef CONFIG_MTD_CFI_INTELEXT
+/*
+ *	Set the Intel flash back to read mode as MTD may leave it in command mode
+ */
+
+static int coyote_reboot_notifier(
+	struct notifier_block *nb,
+	unsigned long val,
+	void *v)
+{
+	struct cfi_private *cfi = coyote_map.fldrv_priv;
+	int i;
+	
+	for (i = 0; cfi && i < cfi->numchips; i++)
+		cfi_send_gen_cmd(0xff, 0x55, cfi->chips[i].start, &coyote_map,
+				cfi, cfi->device_type, NULL);
+
+	return(NOTIFY_OK);
+}
+
+static struct notifier_block coyote_notifier_block = {
+	coyote_reboot_notifier, NULL, 0
+};
+
+#endif
+
+
+static struct mtd_partition coyote_partitions[] = {
+    {
+	name:	"image",
+	offset:	0x00040000,
+	size:	0x00400000, /* 4M for linux kernel + cramfs + initrd image */
+    },
+    {
+	name:	"user",
+	offset:	0x00440000,
+	size:	0x00B80000, /* Rest of flash space minus redboot configuration
+	                     * sectors (-256k) at the end of flash
+			     */
+    },
+};
+
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+static struct mtd_info *coyote_mtd;
+static struct resource *mtd_resource;
+
+static void coyote_exit(void)
+{
+    if (coyote_mtd)
+    {
+	del_mtd_partitions(coyote_mtd);
+	map_destroy(coyote_mtd);
+    }
+    if (coyote_map.map_priv_1)
+	iounmap((void *)coyote_map.map_priv_1);
+    if (mtd_resource)
+	release_mem_region(WINDOW_ADDR, WINDOW_SIZE);
+    
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+    if (parsed_parts)
+	kfree(parsed_parts);
+#endif
+
+    /* Disable flash write */
+    *IXP425_EXP_CS0 &= ~IXP425_FLASH_WRITABLE;
+}
+
+static int __init coyote_init(void)
+{
+    int res, npart;
+
+    /* Enable flash write */
+    *IXP425_EXP_CS0 |= IXP425_FLASH_WRITABLE;
+
+    coyote_map.map_priv_1 = 0;
+    mtd_resource = 
+	request_mem_region(WINDOW_ADDR, WINDOW_SIZE, "IXP425 Residential Gateway Demo Platform Flash");
+    if (!mtd_resource)
+    {
+	printk(KERN_ERR "IXP425 Residential Gateway Demo Platform Flash: Could not request mem region.\n" );
+	res = -ENOMEM;
+	goto Error;
+    }
+
+    coyote_map.map_priv_1 =
+	(unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+    if (!coyote_map.map_priv_1)
+    {
+	printk("IXP425 Residential Gateway Demo Platform Flash: Failed to map IO region. (ioremap)\n");
+	res = -EIO;
+	goto Error;
+    }
+    coyote_map.size = WINDOW_SIZE;
+
+
+    /* 
+     * Probe for the CFI complaint chip
+     * suposed to be 28F128J3A
+     */
+    coyote_mtd = do_map_probe("cfi_probe", &coyote_map);
+    if (!coyote_mtd)
+    {
+	res = -ENXIO;
+	goto Error;
+    }
+    coyote_mtd->module = THIS_MODULE;
+   
+    /* Initialize flash partiotions 
+     * Note: Redeboot partition info table can be parsed by MTD, and used
+     *       instead of hard-coded partions. TBD
+     */
+
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+    /* Try to parse RedBoot partitions */
+    npart = parse_redboot_partitions(coyote_mtd, &parsed_parts, 0);
+    if (npart > 0)
+    {
+	/* found "npart" RedBoot partitions */
+	
+	res = add_mtd_partitions(coyote_mtd, parsed_parts, npart);
+    }
+    else   
+	res = -EIO;
+
+    if (res)
+#endif
+    {
+	printk("Using predefined MTD partitions.\n");
+	/* RedBoot partitions not found - use hardcoded partition table */
+	res = add_mtd_partitions(coyote_mtd, coyote_partitions,
+	    NB_OF(coyote_partitions));
+    }
+
+    if (res)
+	goto Error;
+
+#ifdef CONFIG_MTD_CFI_INTELEXT
+	register_reboot_notifier(&coyote_notifier_block);
+#endif
+
+    return res;
+Error:
+    coyote_exit();
+    return res;
+}
+
+module_init(coyote_init);
+module_exit(coyote_exit);
+
+MODULE_DESCRIPTION("MTD map driver for IXP425 Residential Gateway Demo Platform");
+
diff -urN linux-2.4.29/drivers/mtd/maps/dc21285.c linux-2.4.29-uc1/drivers/mtd/maps/dc21285.c
--- linux-2.4.29/drivers/mtd/maps/dc21285.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/dc21285.c	2005-06-14 02:12:08.000000000 +0100
@@ -108,7 +108,7 @@
 /* Partition stuff */
 static struct mtd_partition *dc21285_parts;
 		      
-extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **);
+extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **, unsigned long fis_origin);
 
 int __init init_dc21285(void)
 {
@@ -146,7 +146,7 @@
 		/* partition fixup */
 
 #ifdef CONFIG_MTD_REDBOOT_PARTS
-		nrparts = parse_redboot_partitions(mymtd, &dc21285_parts);
+		nrparts = parse_redboot_partitions(mymtd, &dc21285_parts, 0);
 #endif
 		if (nrparts > 0) {
 			add_mtd_partitions(mymtd, dc21285_parts, nrparts);
diff -urN linux-2.4.29/drivers/mtd/maps/dm270-flash.c linux-2.4.29-uc1/drivers/mtd/maps/dm270-flash.c
--- linux-2.4.29/drivers/mtd/maps/dm270-flash.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/dm270-flash.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,280 @@
+/***********************************************************************
+ * drivers/mtd/maps/dm270-flash.c
+ *
+ *   Flash memory access on TI TMS320DM270 based devices
+ *
+ *   Derived from drivers/mtd/maps/sa1100-flash.c
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#ifndef CONFIG_ARCH_DM270
+#error This is for DM270 architecture only
+#endif
+
+#define BUSWIDTH 	2
+
+static __u8 dm270_read8(struct map_info *map, unsigned long ofs)
+{
+	return(*((__u8 *) (map->map_priv_1 + ofs)));
+}
+
+static __u16 dm270_read16(struct map_info *map, unsigned long ofs)
+{
+	return(*((__u16 *) (map->map_priv_1 + ofs)));
+}
+
+static __u32 dm270_read32(struct map_info *map, unsigned long ofs)
+{
+	return(*((__u32 *) (map->map_priv_1 + ofs)));
+}
+
+static void dm270_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *)(map->map_priv_1 + from), len);
+}
+
+static void dm270_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*((__u8 *) (map->map_priv_1 + adr)) = d;
+}
+
+static void dm270_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*((__u16 *) (map->map_priv_1 + adr)) = d;
+}
+
+static void dm270_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*((__u32 *) (map->map_priv_1 + adr)) = d;
+}
+
+static void dm270_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy((void *)(map->map_priv_1 + to), from, len);
+}
+
+static struct map_info dm270_map = {
+	name:		"DM270 flash",
+	read8:		dm270_read8,
+	read16:		dm270_read16,
+	read32:		dm270_read32,
+	copy_from:	dm270_copy_from,
+	write8:		dm270_write8,
+	write16:	dm270_write16,
+	write32:	dm270_write32,
+	copy_to:	dm270_copy_to,
+
+	map_priv_1:	FLASH_MEM_BASE,
+	map_priv_2:	-1,
+};
+
+
+/*
+ * Here are partition information for all known DM270-based devices.
+ * See include/linux/mtd/partitions.h for definition of the mtd_partition
+ * structure.
+ *
+ * The *_max_flash_size is the maximum possible mapped flash size which
+ * is not necessarily the actual flash size.  It must be no more than
+ * the value specified in the "struct map_desc *_io_desc" mapping
+ * definition for the corresponding machine.
+ *
+ * Please keep these in alphabetical order, and formatted as per existing
+ * entries.  Thanks.
+ */
+
+#ifdef CONFIG_ARCH_DM270
+/*
+ * 1 x Toshiba TC58FVB160AFT-70 16-MBIT (2M x 8 bits / 1M x 16 bits) CMOS FLASH MEMORY
+ *   Block erase architecture:
+ *   1 X 16 Kbytes / 2 x 8 Kbytes / 1 x 32 Kbytes / 31 x 64 Kbytes
+ */
+static struct mtd_partition dm270_partitions[] = {
+	{
+		name:		"bootloader",
+		size:		0x20000,
+		offset:		0,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"kernel",
+		size:		0xc0000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"rootfs",
+		size:		0x110000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	0,              /* read-write */
+	}, {
+		name:		"bootloader params",
+		size:		0x10000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}
+};
+#endif
+
+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts, unsigned long fis_origin);
+extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, char *);
+
+static struct mtd_partition *parsed_parts;
+static struct mtd_info *mymtd;
+
+int __init dm270_mtd_init(void)
+{
+	struct mtd_partition *parts;
+	int nb_parts = 0, ret;
+	int parsed_nr_parts = 0;
+	const char *part_type;
+	unsigned long base = -1UL;
+
+	/* Default flash buswidth */
+	dm270_map.buswidth = BUSWIDTH;
+
+	/*
+	 * Static partition definition selection
+	 */
+	part_type = "static";
+
+#ifdef CONFIG_ARCH_DM270
+	if (machine_is_dm270()) {
+		parts = dm270_partitions;
+		nb_parts = ARRAY_SIZE(dm270_partitions);
+		dm270_map.size = FLASH_SIZE;
+		dm270_map.buswidth = BUSWIDTH;
+		base = FLASH_MEM_BASE;
+	}
+#endif
+
+	/*
+	 * For simple flash devices, use ioremap to map the flash.
+	 */
+	if (base != (unsigned long)-1) {
+		if (!request_mem_region(base, dm270_map.size, "flash")) {
+			printk(KERN_ERR "dm270 flash: Could not request mem region %lx at %lx.\n",
+					dm270_map.size, base);
+			return -ENOMEM;
+		}
+		dm270_map.map_priv_2 = base;
+		dm270_map.map_priv_1 = (unsigned long)
+				ioremap(base, dm270_map.size);
+		if (!dm270_map.map_priv_1) {
+			printk(KERN_ERR "dm270 Flash: Failed to map IO region %lx at %lx.\n",
+					dm270_map.size, base);
+			ret = -EIO;
+			goto out_err;
+		}
+	}
+
+	/*
+	 * Now let's probe for the actual flash.  Do it here since
+	 * specific machine settings might have been set above.
+	 */
+	printk(KERN_NOTICE "DM270 flash: probing %d-bit flash bus\n", dm270_map.buswidth*8);
+	mymtd = do_map_probe("cfi_probe", &dm270_map);
+	ret = -ENXIO;
+	if (!mymtd)
+		goto out_err;
+	mymtd->module = THIS_MODULE;
+
+	/*
+	 * Dynamic partition selection stuff (might override the static ones)
+	 */
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+	if (parsed_nr_parts == 0) {
+		int ret = parse_redboot_partitions(mymtd, &parsed_parts, FLASH_MEM_BASE);
+
+		if (ret > 0) {
+			part_type = "RedBoot";
+			parsed_nr_parts = ret;
+		}
+	}
+#endif
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+	if (parsed_nr_parts == 0) {
+		int ret = parse_cmdline_partitions(mymtd, &parsed_parts, "dm270");
+		if (ret > 0) {
+			part_type = "Command Line";
+			parsed_nr_parts = ret;
+		}
+	}
+#endif
+
+	if (parsed_nr_parts > 0) {
+		parts = parsed_parts;
+		nb_parts = parsed_nr_parts;
+	}
+
+	if (nb_parts == 0) {
+		printk(KERN_NOTICE "DM270 flash: no partition info available, registering whole flash at once\n");
+		add_mtd_device(mymtd);
+	} else {
+		printk(KERN_NOTICE "Using %s partition definition\n", part_type);
+		add_mtd_partitions(mymtd, parts, nb_parts);
+	}
+	return 0;
+
+ out_err:
+	if (dm270_map.map_priv_2 != -1) {
+		iounmap((void *)dm270_map.map_priv_1);
+		release_mem_region(dm270_map.map_priv_2, dm270_map.size);
+	}
+	return ret;
+}
+
+static void __exit dm270_mtd_cleanup(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+		if (parsed_parts)
+			kfree(parsed_parts);
+	}
+	if (dm270_map.map_priv_2 != -1) {
+		iounmap((void *)dm270_map.map_priv_1);
+		release_mem_region(dm270_map.map_priv_2, dm270_map.size);
+	}
+}
+
+module_init(dm270_mtd_init);
+module_exit(dm270_mtd_cleanup);
+
+MODULE_AUTHOR("Chee Tim Loh");
+MODULE_DESCRIPTION("DM270 CFI map driver");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/drivers/mtd/maps/dnp5280.c linux-2.4.29-uc1/drivers/mtd/maps/dnp5280.c
--- linux-2.4.29/drivers/mtd/maps/dnp5280.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/dnp5280.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,189 @@
+/*
+ * This file is "heavily based" ;) on physmap.c, which I copied
+ * and changed to suit my needs! But to show who is responsible
+ * for the file I included the new copyright. I don't know if that
+ * is the correct way, so if this should be a problem, please
+ * email me! 
+ * 
+ * (C) 2003 SSV Embedded Systems <support@ist1.de>
+ * 
+ * ----------------------------------------------------------------------
+ * File:       dnp5280.c
+ * Place:      uClinux-dist/linux-2.4.x/drivers/mtd/maps/
+ * Author:     Heiko Degenhardt. For support please contact
+ *             M. Hasewinkel" <support@ist1.de>
+ * Contents:   Flash layout of the DNP5280 board.
+ * Version:    v01.00
+ * Date:       Thu Sep  4 13:52:19 CEST 2003
+ * ______________________________________________________________________
+ *
+ * CHANGES
+ * 030904   v01.00 Creation from physmap.c
+ *          (hede)
+ * ______________________________________________________________________
+ *
+ *  This program is free software; you can redistribute  it and/or
+ *  modify it under  the terms of  the GNU General  Public License as
+ *  published by the Free Software Foundation;  either version 2 of
+ *  the  License, or (at your option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR
+ *  IMPLIED WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED.  IN NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE
+ *  FOR ANY   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED   TO,
+ *  PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ *  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ *  SUCH DAMAGE.
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Mappings of chips in memory of the senTec COBRA5272 board.
+ * 
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/config.h>
+
+
+#define WINDOW_ADDR 0xff800000
+#define WINDOW_SIZE 0x800000
+#define BUSWIDTH 2
+
+static struct mtd_info *mymtd;
+
+__u8 dnp5280map_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 dnp5280map_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 dnp5280map_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void dnp5280map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void dnp5280map_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void dnp5280map_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void dnp5280map_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void dnp5280map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info dnp5280map_map = {
+	name: "Physically mapped flash of DNP5280",
+	size: WINDOW_SIZE,
+	buswidth: BUSWIDTH,
+	read8: dnp5280map_read8,
+	read16: dnp5280map_read16,
+	read32: dnp5280map_read32,
+	copy_from: dnp5280map_copy_from,
+	write8: dnp5280map_write8,
+	write16: dnp5280map_write16,
+	write32: dnp5280map_write32,
+	copy_to: dnp5280map_copy_to
+};
+
+/*
+ * MTD 'PARTITIONING' STUFF 
+ *
+ * ATTENTION! This is just an example!
+ * 
+ */
+#define NUM_PARTITIONS 3
+
+static struct mtd_partition dnp5280_partitions[NUM_PARTITIONS] = {
+        {
+                name: "dBUG",
+                size: 0x50000,
+                offset: 0
+        },
+        {
+                name: "uClinux",
+                size: 0x2B0000,
+                offset: 0x50000
+        },
+        {
+                name: "flash space",
+                size: 0x500000,
+                offset: 0x300000
+        }
+};
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_dnp5280map init_module
+#define cleanup_dnp5280map cleanup_module
+#endif
+
+int __init init_dnp5280map(void)
+{
+  	printk(KERN_NOTICE "dnp5280map flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
+	dnp5280map_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+	if (!dnp5280map_map.map_priv_1) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}
+	mymtd = do_map_probe("cfi_probe", &dnp5280map_map);
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+
+		return add_mtd_partitions(mymtd, dnp5280_partitions, NUM_PARTITIONS);
+	}
+
+	iounmap((void *)dnp5280map_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_dnp5280map(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+	if (dnp5280map_map.map_priv_1) {
+		iounmap((void *)dnp5280map_map.map_priv_1);
+		dnp5280map_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_dnp5280map);
+module_exit(cleanup_dnp5280map);
+
diff -urN linux-2.4.29/drivers/mtd/maps/dnp5282.c linux-2.4.29-uc1/drivers/mtd/maps/dnp5282.c
--- linux-2.4.29/drivers/mtd/maps/dnp5282.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/dnp5282.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,189 @@
+/*
+ * This file is "heavily based" ;) on physmap.c, which I copied
+ * and changed to suit my needs! But to show who is responsible
+ * for the file I included the new copyright. I don't know if that
+ * is the correct way, so if this should be a problem, please
+ * email me! 
+ * 
+ * (C) 2003 SSV Embedded Systems <support@ist1.de>
+ * 
+ * ----------------------------------------------------------------------
+ * File:       dnp5282.c
+ * Place:      uClinux-dist/linux-2.4.x/drivers/mtd/maps/
+ * Author:     Heiko Degenhardt. For support please contact
+ * 				M. Hasewinkel" <support@ist1.de>
+ * Contents:   Flash layout of the DNP5282 board.
+ * Version:    v01.00
+ * Date:       Thu Sep  4 13:52:19 CEST 2003
+ * ______________________________________________________________________
+ *
+ * CHANGES
+ * 030904   v01.00 Creation from physmap.c
+ *          (hede)
+ * ______________________________________________________________________
+ *
+ *  This program is free software; you can redistribute  it and/or
+ *  modify it under  the terms of  the GNU General  Public License as
+ *  published by the Free Software Foundation;  either version 2 of
+ *  the  License, or (at your option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR
+ *  IMPLIED WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ *  ARE DISCLAIMED.  IN NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE
+ *  FOR ANY   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED   TO,
+ *  PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ *  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ *  SUCH DAMAGE.
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Mappings of chips in memory of the senTec COBRA5272 board.
+ * 
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/config.h>
+
+
+#define WINDOW_ADDR 0xff800000
+#define WINDOW_SIZE 0x800000
+#define BUSWIDTH 2
+
+static struct mtd_info *mymtd;
+
+__u8 dnp5282map_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 dnp5282map_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 dnp5282map_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void dnp5282map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void dnp5282map_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void dnp5282map_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void dnp5282map_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void dnp5282map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info dnp5282map_map = {
+	name: "Physically mapped flash of DNP5282",
+	size: WINDOW_SIZE,
+	buswidth: BUSWIDTH,
+	read8: dnp5282map_read8,
+	read16: dnp5282map_read16,
+	read32: dnp5282map_read32,
+	copy_from: dnp5282map_copy_from,
+	write8: dnp5282map_write8,
+	write16: dnp5282map_write16,
+	write32: dnp5282map_write32,
+	copy_to: dnp5282map_copy_to
+};
+
+/*
+ * MTD 'PARTITIONING' STUFF 
+ *
+ * ATTENTION! This is just an example!
+ * 
+ */
+#define NUM_PARTITIONS 3
+
+static struct mtd_partition dnp5282_partitions[NUM_PARTITIONS] = {
+        {
+                name: "vectors (64K)",
+                size: 0x10000,
+                offset: 0
+        },
+        {
+                name: "kernel (2MB)",
+                size: 0x200000,
+                offset: 0x50000
+        },
+        {
+                name: "spare (4MB)",
+                size: 0x400000,
+                offset: 0x40000
+        }
+};
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_dnp5282map init_module
+#define cleanup_dnp5282map cleanup_module
+#endif
+
+int __init init_dnp5282map(void)
+{
+  	printk(KERN_NOTICE "dnp5282map flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
+	dnp5282map_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+	if (!dnp5282map_map.map_priv_1) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}
+	mymtd = do_map_probe("cfi_probe", &dnp5282map_map);
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+
+		return add_mtd_partitions(mymtd, dnp5282_partitions, NUM_PARTITIONS);
+	}
+
+	iounmap((void *)dnp5282map_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_dnp5282map(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+	if (dnp5282map_map.map_priv_1) {
+		iounmap((void *)dnp5282map_map.map_priv_1);
+		dnp5282map_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_dnp5282map);
+module_exit(cleanup_dnp5282map);
+
diff -urN linux-2.4.29/drivers/mtd/maps/dragonix_map.c linux-2.4.29-uc1/drivers/mtd/maps/dragonix_map.c
--- linux-2.4.29/drivers/mtd/maps/dragonix_map.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/dragonix_map.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,147 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+
+#define WINDOW_ADDR 0x02200000
+#define WINDOW_SIZE 0x00200000
+#define BUSWIDTH 2
+
+#define __raw_readb readb
+#define __raw_readl readl
+#define __raw_readw readw
+
+static struct mtd_info *mymtd;
+
+
+static __u8 dragonix_read8(struct map_info *map,unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+static __u16 dragonix_read16(struct map_info *map,unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+static __u32 dragonix_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+static void dragonix_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *)(map->map_priv_1 + from), len);
+}
+
+static void dragonix_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*(__u8 *)(map->map_priv_1 + adr) = d;
+}
+
+static void dragonix_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*(__u16 *)(map->map_priv_1 + adr) = d;
+}
+
+static void dragonix_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*(__u32 *)(map->map_priv_1 + adr) = d;
+}
+
+static void dragonix_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy((void *)(map->map_priv_1 + to), from, len);
+}
+
+/*
+static struct mtd_partition dragonix_partition[]={
+    { 
+	    name: "Dragonix Bootloader", 
+	    offset: 0, 
+	    size:   0x20000,
+    },
+    {
+	   name:"Dragonix Kernel",
+	   offset:0x20000,
+	   size:0x7e0000,
+    },
+    { 
+	    name: "dragonix RamDisk", /////
+	    offset: 0x800000,
+	    size:0x800000, 
+    }
+};
+*/
+
+// Test partition
+static struct mtd_partition dragonix_partition[]={
+    { 
+	    name: "Dragonix Bootloader", 
+	    offset: 0, 
+	    size:   0x200000,
+    }
+};
+
+#define NUM_PARTITIONS (sizeof(dragonix_partition)/sizeof(dragonix_partition[0]))
+
+
+struct map_info dragonix_map = {
+	name: "Dragonix VZ Flash map",
+	size: WINDOW_SIZE,
+	buswidth: BUSWIDTH,
+	read8: dragonix_read8,
+	read16: dragonix_read16,
+	read32: dragonix_read32,
+	copy_from: dragonix_copy_from,
+	write8: dragonix_write8,
+	write16: dragonix_write16,
+	write32: dragonix_write32,
+	copy_to: dragonix_copy_to,
+};
+
+
+static  int __init init_dragonix(void)
+{
+	printk(KERN_NOTICE "Dragonix VZ mapping:size %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
+	dragonix_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+	printk("ZEUS:dragonix_map.map_priv_1=%x\n",dragonix_map.map_priv_1);
+	if (!dragonix_map.map_priv_1) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}
+	
+	mymtd = do_map_probe("cfi_probe", &dragonix_map);
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+		add_mtd_partitions( mymtd, dragonix_partition, NUM_PARTITIONS );
+
+		add_mtd_device(mymtd);
+		printk("ZEUS:right end of init_dragonix(I mean flash)\n");
+		return 0;
+	}
+	
+	iounmap((void *)dragonix_map.map_priv_1);
+	printk("ZEUS:so its the wrong end of init_dragonix(flash)\n");
+	return -ENXIO;
+
+}
+
+mod_exit_t cleanup_dragonix(void)
+{
+	if (mymtd) {
+		del_mtd_device(mymtd);
+		map_destroy(mymtd);
+	}
+	if (dragonix_map.map_priv_1) {
+		iounmap((void *)dragonix_map.map_priv_1);
+		dragonix_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_dragonix);
+module_exit(cleanup_dragonix);
diff -urN linux-2.4.29/drivers/mtd/maps/edb7312.c linux-2.4.29-uc1/drivers/mtd/maps/edb7312.c
--- linux-2.4.29/drivers/mtd/maps/edb7312.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/edb7312.c	2005-06-14 02:12:08.000000000 +0100
@@ -93,37 +93,15 @@
 };
 
 #ifdef CONFIG_MTD_PARTITIONS
-
-/*
- * MTD partitioning stuff 
- */
-static struct mtd_partition static_partitions[3] =
-{
-    {
-	name: "ARMboot",
-	  size: 0x40000,
-	  offset: 0
-    },
-    {
-	name: "Kernel",
-	  size: 0x200000,
-	  offset: 0x40000
-    },
-    {
-	name: "RootFS",
-	  size: 0xDC0000,
-	  offset: 0x240000
-    },
-};
-
-#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
-
 #ifdef CONFIG_MTD_CMDLINE_PARTS
 int parse_cmdline_partitions(struct mtd_info *master, 
 			     struct mtd_partition **pparts,
 			     const char *mtd_id);
 #endif
-
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+int parse_redboot_partitions(struct mtd_info *master,
+			     struct mtd_partition **pparts);
+#endif
 #endif
 
 static int                   mtd_parts_nb = 0;
@@ -154,20 +132,22 @@
 		mymtd->module = THIS_MODULE;
 
 #ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+		mtd_parts_nb = parse_redboot_partitions(mymtd, &mtd_parts);
+		if (mtd_parts_nb > 0)
+			part_type = "redboot";
+#endif
 #ifdef CONFIG_MTD_CMDLINE_PARTS
+		if (mtd_parts_nb <= 0)
+		{
 		mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts, MTDID);
 		if (mtd_parts_nb > 0)
 		  part_type = "command line";
-#endif
-		if (mtd_parts_nb == 0)
-		{
-			mtd_parts = static_partitions;
-			mtd_parts_nb = NB_OF(static_partitions);
-			part_type = "static";
 		}
 #endif
+#endif
 		add_mtd_device(mymtd);
-		if (mtd_parts_nb == 0)
+		if (mtd_parts_nb <= 0)
 		  printk(KERN_NOTICE MSG_PREFIX "no partition info available\n");
 		else
 		{
diff -urN linux-2.4.29/drivers/mtd/maps/edb9301.c linux-2.4.29-uc1/drivers/mtd/maps/edb9301.c
--- linux-2.4.29/drivers/mtd/maps/edb9301.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/edb9301.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,179 @@
+/*
+ *
+ * Handle mapping of the NOR flash on Cirrus Logic EDB9301 boards
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/config.h>
+
+#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/partitions.h>
+#endif
+
+#define WINDOW_ADDR 0x60000000      /* physical properties of flash */
+#define WINDOW_SIZE 0x01000000
+#define BUSWIDTH    2
+#define FLASH_BLOCKSIZE_MAIN	0x20000
+#define FLASH_NUMBLOCKS_MAIN	128
+/* can be "cfi_probe", "jedec_probe", "map_rom", 0 */
+#define PROBETYPES { "cfi_probe", 0 }
+
+#define MSG_PREFIX "EDB9301-NOR:"   /* prefix for our printk()'s */
+#define MTDID      "edb9301-nor"    /* for mtdparts= partitioning */
+
+static struct mtd_info *mymtd;
+
+__u8 edb9301nor_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 edb9301nor_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 edb9301nor_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void edb9301nor_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void edb9301nor_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void edb9301nor_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void edb9301nor_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void edb9301nor_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info edb9301nor_map = {
+	name: "NOR flash on EDB9301",
+	size: WINDOW_SIZE,
+	buswidth: BUSWIDTH,
+	read8: edb9301nor_read8,
+	read16: edb9301nor_read16,
+	read32: edb9301nor_read32,
+	copy_from: edb9301nor_copy_from,
+	write8: edb9301nor_write8,
+	write16: edb9301nor_write16,
+	write32: edb9301nor_write32,
+	copy_to: edb9301nor_copy_to
+};
+
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+int parse_cmdline_partitions(struct mtd_info *master, 
+			     struct mtd_partition **pparts,
+			     const char *mtd_id);
+#endif
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+extern int parse_redboot_partitions(struct mtd_info *master,
+	struct mtd_partition **pparts);
+#endif
+#endif
+
+static int                   mtd_parts_nb = 0;
+static struct mtd_partition *mtd_parts    = 0;
+
+int __init init_edb9301nor(void)
+{
+	static const char *rom_probe_types[] = PROBETYPES;
+	const char **type;
+	const char *part_type = 0;
+
+       	printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n", 
+	       WINDOW_SIZE, WINDOW_ADDR);
+	edb9301nor_map.map_priv_1 = (unsigned long)
+	  ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+	if (!edb9301nor_map.map_priv_1) {
+		printk(MSG_PREFIX "failed to ioremap\n");
+		return -EIO;
+	}
+	mymtd = 0;
+	type = rom_probe_types;
+	for(; !mymtd && *type; type++) {
+		mymtd = do_map_probe(*type, &edb9301nor_map);
+	}
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+		mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts, MTDID);
+		if (mtd_parts_nb > 0)
+		  part_type = "command line";
+#endif
+		
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+		if (mtd_parts_nb <= 0) {
+			mtd_parts_nb = parse_redboot_partitions(mymtd, &mtd_parts);
+			if (mtd_parts_nb > 0) {
+				part_type = "RedBoot";
+			}
+		}
+#endif
+#endif
+		add_mtd_device(mymtd);
+		if (mtd_parts_nb <= 0)
+		  printk(KERN_NOTICE MSG_PREFIX "no partition info available\n");
+		else
+		{
+			printk(KERN_NOTICE MSG_PREFIX
+			       "using %s partition definition\n", part_type);
+			add_mtd_partitions(mymtd, mtd_parts, mtd_parts_nb);
+		}
+		return 0;
+	}
+
+	iounmap((void *)edb9301nor_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_edb9301nor(void)
+{
+	if (mymtd) {
+		del_mtd_device(mymtd);
+		map_destroy(mymtd);
+	}
+	if (edb9301nor_map.map_priv_1) {
+		iounmap((void *)edb9301nor_map.map_priv_1);
+		edb9301nor_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_edb9301nor);
+module_exit(cleanup_edb9301nor);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marius Groeger <mag@sysgo.de>");
+MODULE_DESCRIPTION("Generic configurable MTD map driver");
diff -urN linux-2.4.29/drivers/mtd/maps/edb9302.c linux-2.4.29-uc1/drivers/mtd/maps/edb9302.c
--- linux-2.4.29/drivers/mtd/maps/edb9302.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/edb9302.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,179 @@
+/*
+ *
+ * Handle mapping of the NOR flash on Cirrus Logic EDB9302 boards
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/config.h>
+
+#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/partitions.h>
+#endif
+
+#define WINDOW_ADDR 0x60000000      /* physical properties of flash */
+#define WINDOW_SIZE 0x01000000
+#define BUSWIDTH    2
+#define FLASH_BLOCKSIZE_MAIN	0x20000
+#define FLASH_NUMBLOCKS_MAIN	128
+/* can be "cfi_probe", "jedec_probe", "map_rom", 0 */
+#define PROBETYPES { "cfi_probe", 0 }
+
+#define MSG_PREFIX "EDB9302-NOR:"   /* prefix for our printk()'s */
+#define MTDID      "edb9302-nor"    /* for mtdparts= partitioning */
+
+static struct mtd_info *mymtd;
+
+__u8 edb9302nor_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 edb9302nor_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 edb9302nor_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void edb9302nor_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void edb9302nor_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void edb9302nor_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void edb9302nor_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void edb9302nor_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info edb9302nor_map = {
+	name: "NOR flash on EDB9302",
+	size: WINDOW_SIZE,
+	buswidth: BUSWIDTH,
+	read8: edb9302nor_read8,
+	read16: edb9302nor_read16,
+	read32: edb9302nor_read32,
+	copy_from: edb9302nor_copy_from,
+	write8: edb9302nor_write8,
+	write16: edb9302nor_write16,
+	write32: edb9302nor_write32,
+	copy_to: edb9302nor_copy_to
+};
+
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+int parse_cmdline_partitions(struct mtd_info *master, 
+			     struct mtd_partition **pparts,
+			     const char *mtd_id);
+#endif
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+extern int parse_redboot_partitions(struct mtd_info *master,
+	struct mtd_partition **pparts);
+#endif
+#endif
+
+static int                   mtd_parts_nb = 0;
+static struct mtd_partition *mtd_parts    = 0;
+
+int __init init_edb9302nor(void)
+{
+	static const char *rom_probe_types[] = PROBETYPES;
+	const char **type;
+	const char *part_type = 0;
+
+       	printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n", 
+	       WINDOW_SIZE, WINDOW_ADDR);
+	edb9302nor_map.map_priv_1 = (unsigned long)
+	  ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+	if (!edb9302nor_map.map_priv_1) {
+		printk(MSG_PREFIX "failed to ioremap\n");
+		return -EIO;
+	}
+	mymtd = 0;
+	type = rom_probe_types;
+	for(; !mymtd && *type; type++) {
+		mymtd = do_map_probe(*type, &edb9302nor_map);
+	}
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+		mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts, MTDID);
+		if (mtd_parts_nb > 0)
+		  part_type = "command line";
+#endif
+		
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+		if (mtd_parts_nb <= 0) {
+			mtd_parts_nb = parse_redboot_partitions(mymtd, &mtd_parts);
+			if (mtd_parts_nb > 0) {
+				part_type = "RedBoot";
+			}
+		}
+#endif
+#endif
+		add_mtd_device(mymtd);
+		if (mtd_parts_nb <= 0)
+		  printk(KERN_NOTICE MSG_PREFIX "no partition info available\n");
+		else
+		{
+			printk(KERN_NOTICE MSG_PREFIX
+			       "using %s partition definition\n", part_type);
+			add_mtd_partitions(mymtd, mtd_parts, mtd_parts_nb);
+		}
+		return 0;
+	}
+
+	iounmap((void *)edb9302nor_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_edb9302nor(void)
+{
+	if (mymtd) {
+		del_mtd_device(mymtd);
+		map_destroy(mymtd);
+	}
+	if (edb9302nor_map.map_priv_1) {
+		iounmap((void *)edb9302nor_map.map_priv_1);
+		edb9302nor_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_edb9302nor);
+module_exit(cleanup_edb9302nor);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marius Groeger <mag@sysgo.de>");
+MODULE_DESCRIPTION("Generic configurable MTD map driver");
diff -urN linux-2.4.29/drivers/mtd/maps/edb9312.c linux-2.4.29-uc1/drivers/mtd/maps/edb9312.c
--- linux-2.4.29/drivers/mtd/maps/edb9312.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/edb9312.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,179 @@
+/*
+ *
+ * Handle mapping of the NOR flash on Cirrus Logic EDB9312 boards
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/config.h>
+
+#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/partitions.h>
+#endif
+
+#define WINDOW_ADDR 0x60000000      /* physical properties of flash */
+#define WINDOW_SIZE 0x02000000
+#define BUSWIDTH    4
+#define FLASH_BLOCKSIZE_MAIN	0x20000
+#define FLASH_NUMBLOCKS_MAIN	128
+/* can be "cfi_probe", "jedec_probe", "map_rom", 0 }; */
+#define PROBETYPES { "cfi_probe", 0 }
+
+#define MSG_PREFIX "EDB9312-NOR:"   /* prefix for our printk()'s */
+#define MTDID      "edb9312-nor"    /* for mtdparts= partitioning */
+
+static struct mtd_info *mymtd;
+
+__u8 edb9312nor_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 edb9312nor_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 edb9312nor_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void edb9312nor_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void edb9312nor_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void edb9312nor_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void edb9312nor_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void edb9312nor_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info edb9312nor_map = {
+	name: "NOR flash on EDB9312",
+	size: WINDOW_SIZE,
+	buswidth: BUSWIDTH,
+	read8: edb9312nor_read8,
+	read16: edb9312nor_read16,
+	read32: edb9312nor_read32,
+	copy_from: edb9312nor_copy_from,
+	write8: edb9312nor_write8,
+	write16: edb9312nor_write16,
+	write32: edb9312nor_write32,
+	copy_to: edb9312nor_copy_to
+};
+
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+int parse_cmdline_partitions(struct mtd_info *master, 
+			     struct mtd_partition **pparts,
+			     const char *mtd_id);
+#endif
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+extern int parse_redboot_partitions(struct mtd_info *master,
+	struct mtd_partition **pparts);
+#endif
+#endif
+
+static int                   mtd_parts_nb = 0;
+static struct mtd_partition *mtd_parts    = 0;
+
+int __init init_edb9312nor(void)
+{
+	static const char *rom_probe_types[] = PROBETYPES;
+	const char **type;
+	const char *part_type = 0;
+
+       	printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n", 
+	       WINDOW_SIZE, WINDOW_ADDR);
+	edb9312nor_map.map_priv_1 = (unsigned long)
+	  ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+	if (!edb9312nor_map.map_priv_1) {
+		printk(MSG_PREFIX "failed to ioremap\n");
+		return -EIO;
+	}
+	mymtd = 0;
+	type = rom_probe_types;
+	for(; !mymtd && *type; type++) {
+		mymtd = do_map_probe(*type, &edb9312nor_map);
+	}
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+		mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts, MTDID);
+		if (mtd_parts_nb > 0)
+		  part_type = "command line";
+#endif
+		
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+		if (mtd_parts_nb <= 0) {
+			mtd_parts_nb = parse_redboot_partitions(mymtd, &mtd_parts);
+			if (mtd_parts_nb > 0) {
+				part_type = "RedBoot";
+			}
+		}
+#endif
+#endif
+		add_mtd_device(mymtd);
+		if (mtd_parts_nb <= 0)
+		  printk(KERN_NOTICE MSG_PREFIX "no partition info available\n");
+		else
+		{
+			printk(KERN_NOTICE MSG_PREFIX
+			       "using %s partition definition\n", part_type);
+			add_mtd_partitions(mymtd, mtd_parts, mtd_parts_nb);
+		}
+		return 0;
+	}
+
+	iounmap((void *)edb9312nor_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_edb9312nor(void)
+{
+	if (mymtd) {
+		del_mtd_device(mymtd);
+		map_destroy(mymtd);
+	}
+	if (edb9312nor_map.map_priv_1) {
+		iounmap((void *)edb9312nor_map.map_priv_1);
+		edb9312nor_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_edb9312nor);
+module_exit(cleanup_edb9312nor);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marius Groeger <mag@sysgo.de>");
+MODULE_DESCRIPTION("Generic configurable MTD map driver");
diff -urN linux-2.4.29/drivers/mtd/maps/edb9315.c linux-2.4.29-uc1/drivers/mtd/maps/edb9315.c
--- linux-2.4.29/drivers/mtd/maps/edb9315.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/edb9315.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,179 @@
+/*
+ *
+ * Handle mapping of the NOR flash on Cirrus Logic EDB9315 boards
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/config.h>
+
+#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/partitions.h>
+#endif
+
+#define WINDOW_ADDR 0x60000000      /* physical properties of flash */
+#define WINDOW_SIZE 0x02000000
+#define BUSWIDTH    4
+#define FLASH_BLOCKSIZE_MAIN	0x20000
+#define FLASH_NUMBLOCKS_MAIN	128
+/* can be "cfi_probe", "jedec_probe", "map_rom", 0 }; */
+#define PROBETYPES { "cfi_probe", 0 }
+
+#define MSG_PREFIX "EDB9315-NOR:"   /* prefix for our printk()'s */
+#define MTDID      "edb9315-nor"    /* for mtdparts= partitioning */
+
+static struct mtd_info *mymtd;
+
+__u8 edb9315nor_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 edb9315nor_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 edb9315nor_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void edb9315nor_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void edb9315nor_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void edb9315nor_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void edb9315nor_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void edb9315nor_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info edb9315nor_map = {
+	name: "NOR flash on EDB9315",
+	size: WINDOW_SIZE,
+	buswidth: BUSWIDTH,
+	read8: edb9315nor_read8,
+	read16: edb9315nor_read16,
+	read32: edb9315nor_read32,
+	copy_from: edb9315nor_copy_from,
+	write8: edb9315nor_write8,
+	write16: edb9315nor_write16,
+	write32: edb9315nor_write32,
+	copy_to: edb9315nor_copy_to
+};
+
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+int parse_cmdline_partitions(struct mtd_info *master, 
+			     struct mtd_partition **pparts,
+			     const char *mtd_id);
+#endif
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+extern int parse_redboot_partitions(struct mtd_info *master,
+	struct mtd_partition **pparts);
+#endif
+#endif
+
+static int                   mtd_parts_nb = 0;
+static struct mtd_partition *mtd_parts    = 0;
+
+int __init init_edb9315nor(void)
+{
+	static const char *rom_probe_types[] = PROBETYPES;
+	const char **type;
+	const char *part_type = 0;
+
+       	printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n", 
+	       WINDOW_SIZE, WINDOW_ADDR);
+	edb9315nor_map.map_priv_1 = (unsigned long)
+	  ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+	if (!edb9315nor_map.map_priv_1) {
+		printk(MSG_PREFIX "failed to ioremap\n");
+		return -EIO;
+	}
+	mymtd = 0;
+	type = rom_probe_types;
+	for(; !mymtd && *type; type++) {
+		mymtd = do_map_probe(*type, &edb9315nor_map);
+	}
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+		mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts, MTDID);
+		if (mtd_parts_nb > 0)
+		  part_type = "command line";
+#endif
+		
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+		if (mtd_parts_nb <= 0) {
+			mtd_parts_nb = parse_redboot_partitions(mymtd, &mtd_parts);
+			if (mtd_parts_nb > 0) {
+				part_type = "RedBoot";
+			}
+		}
+#endif
+#endif
+		add_mtd_device(mymtd);
+		if (mtd_parts_nb <= 0)
+		  printk(KERN_NOTICE MSG_PREFIX "no partition info available\n");
+		else
+		{
+			printk(KERN_NOTICE MSG_PREFIX
+			       "using %s partition definition\n", part_type);
+			add_mtd_partitions(mymtd, mtd_parts, mtd_parts_nb);
+		}
+		return 0;
+	}
+
+	iounmap((void *)edb9315nor_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_edb9315nor(void)
+{
+	if (mymtd) {
+		del_mtd_device(mymtd);
+		map_destroy(mymtd);
+	}
+	if (edb9315nor_map.map_priv_1) {
+		iounmap((void *)edb9315nor_map.map_priv_1);
+		edb9315nor_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_edb9315nor);
+module_exit(cleanup_edb9315nor);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marius Groeger <mag@sysgo.de>");
+MODULE_DESCRIPTION("Generic configurable MTD map driver");
diff -urN linux-2.4.29/drivers/mtd/maps/epxa10db-flash.c linux-2.4.29-uc1/drivers/mtd/maps/epxa10db-flash.c
--- linux-2.4.29/drivers/mtd/maps/epxa10db-flash.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/epxa10db-flash.c	2005-06-14 02:12:08.000000000 +0100
@@ -43,7 +43,7 @@
 
 static struct mtd_info *mymtd;
 
-extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **);
+extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **, unsigned long fis_origin);
 static int epxa_default_partitions(struct mtd_info *master, struct mtd_partition **pparts);
 
 static __u8 epxa_read8(struct map_info *map, unsigned long ofs)
@@ -136,7 +136,7 @@
 	}
 
 #ifdef CONFIG_MTD_REDBOOT_PARTS
-	nr_parts = parse_redboot_partitions(mymtd, &parts);
+	nr_parts = parse_redboot_partitions(mymtd, &parts, 0);
 
 	if (nr_parts > 0) {
 		add_mtd_partitions(mymtd, parts, nr_parts);
diff -urN linux-2.4.29/drivers/mtd/maps/feith.c linux-2.4.29-uc1/drivers/mtd/maps/feith.c
--- linux-2.4.29/drivers/mtd/maps/feith.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/feith.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,394 @@
+/****************************************************************************/
+/*
+ * Flash memory access on Feith Sensor to Image GmbH devices
+ * Copyright (C) Feith Sensor to Image GmbH, Roman Wagner <rw@feith.de>
+ *
+ * Mostly hijacked from nettel-uc.c
+ * Copyright (C) Lineo, <davidm@moreton.com.au>
+ */
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <linux/fs.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+
+/****************************************************************************/
+
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+#define SIZE_2MB	(2 * 1024 * 1024)
+#define SIZE_4MB	(4 * 1024 * 1024)
+#define SIZE_6MB	(6 * 1024 * 1024)
+#define SIZE_8MB	(8 * 1024 * 1024)
+
+#define FLASH_BASE	0xf0000000
+#define	BUS_WIDTH	2
+
+/*
+ *	If you set AUTO_PROBE,  then we will just use the biggest device
+ *	we can find
+ */
+#undef AUTO_PROBE
+
+/****************************************************************************/
+
+static __u8 Feith_read8(struct map_info *map, unsigned long ofs)
+{
+	return *(__u8 *)(map->map_priv_1 + ofs);
+}
+
+static __u16 Feith_read16(struct map_info *map, unsigned long ofs)
+{
+	return *(__u16 *)(map->map_priv_1 + ofs);
+}
+
+static __u32 Feith_read32(struct map_info *map, unsigned long ofs)
+{
+	return *(__u32 *)(map->map_priv_1 + ofs);
+}
+
+static void Feith_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *)(map->map_priv_1 + from), len);
+}
+
+static void Feith_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*(__u8 *)(map->map_priv_1 + adr) = d;
+}
+
+static void Feith_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*(__u16 *)(map->map_priv_1 + adr) = d;
+}
+
+static void Feith_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*(__u32 *)(map->map_priv_1 + adr) = d;
+}
+
+static void Feith_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy((void *)(map->map_priv_1 + to), from, len);
+}
+
+/****************************************************************************/
+
+static struct map_info Feith_flash_map = {
+	name:		"Flash",
+	read8:		Feith_read8,
+	read16:		Feith_read16,
+	read32:		Feith_read32,
+	copy_from:	Feith_copy_from,
+	write8:		Feith_write8,
+	write16:	Feith_write16,
+	write32:	Feith_write32,
+	copy_to:	Feith_copy_to,
+};
+
+static struct map_info Feith_ram_map = {
+	name:		"RAM",
+	read8:		Feith_read8,
+	read16:		Feith_read16,
+	read32:		Feith_read32,
+	copy_from:	Feith_copy_from,
+	write8:		Feith_write8,
+	write16:	Feith_write16,
+	write32:	Feith_write32,
+	copy_to:	Feith_copy_to,
+};
+
+static struct mtd_info *ram_mtdinfo;
+static struct mtd_info *flash_mtdinfo;
+
+/****************************************************************************/
+
+static struct mtd_partition Feith_romfs[] = {
+	{ name: "romfs", offset: 0 }
+};
+
+/****************************************************************************/
+/*
+ *	The layout of our flash,  note the order of the names,  this
+ *	means we use the same major/minor for the same purpose on all
+ *	layouts (when possible)
+ */
+
+#if defined(CONFIG_CLEOPATRA) || defined(CONFIG_SCALES)
+static struct mtd_partition Feith_2mb[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },
+	{ name: "Bootargs",   offset: 0x00004000, size:   0x00002000 },
+	{ name: "MAC",        offset: 0x00006000, size:   0x00002000 },
+	{ name: "Image",      offset: 0x00020000, size:   0x001c0000 },
+	{ name: "Config",     offset: 0x00010000, size:   0x00010000 },
+	{ name: "Flash",      offset: 0x00000000, size:   0x00200000 },
+	{ name: "Spare",      offset: 0x00008000, size:   0x00008000 },
+	{ name: "Config User",offset: 0x001e0000, size:   0x00020000 }
+};
+
+static struct mtd_partition Feith_4mb[] = {
+	{ name: "Bootloader",  offset: 0x00000000, size:   0x00004000 },
+	{ name: "Bootargs",    offset: 0x00004000, size:   0x00002000 },
+	{ name: "MAC",         offset: 0x00006000, size:   0x00002000 },
+	{ name: "Image",       offset: 0x00020000, size:   0x001c0000 },
+	{ name: "Config",      offset: 0x00010000, size:   0x00010000 },
+	{ name: "Flash",       offset: 0x00000000, size:   0x00200000 },
+	{ name: "Spare",       offset: 0x00008000, size:   0x00008000 },
+	{ name: "Config User", offset: 0x001e0000, size:   0x00020000 },
+	{ name: "User Block 1",offset: 0x00200000, size:   0x00180000 },
+	{ name: "User Block 2",offset: 0x00380000, size:   0x00080000 }
+};
+
+static struct mtd_partition Feith_6mb[] = {
+	{ name: "Bootloader",  offset: 0x00000000, size:   0x00004000 },
+	{ name: "Bootargs",    offset: 0x00004000, size:   0x00002000 },
+	{ name: "MAC",         offset: 0x00006000, size:   0x00002000 },
+	{ name: "Image",       offset: 0x00020000, size:   0x001c0000 },
+	{ name: "Config",      offset: 0x00010000, size:   0x00010000 },
+	{ name: "Flash",       offset: 0x00000000, size:   0x00200000 },
+	{ name: "Spare",       offset: 0x00008000, size:   0x00008000 },
+	{ name: "Config User", offset: 0x001e0000, size:   0x00020000 },
+	{ name: "User Block 1",offset: 0x00200000, size:   0x00180000 },
+	{ name: "User Block 2",offset: 0x00380000, size:   0x00080000 },
+	{ name: "User Block 3",offset: 0x00400000, size:   0x00200000 }
+};
+#endif
+
+#if defined(CONFIG_CANCAM)
+static struct mtd_partition Feith_8mb[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00010000 },
+	{ name: "Bootargs",   offset: 0x00010000, size:   0x00010000 },
+	{ name: "MAC",        offset: 0x00020000, size:   0x00010000 },
+	{ name: "Image",      offset: 0x00050000, size:   0x001b0000 },
+	{ name: "Config",     offset: 0x00040000, size:   0x00010000 },
+	{ name: "Flash",      offset: 0x00000000, size:   0x00800000 },
+	{ name: "Spare",      offset: 0x00030000, size:   0x00010000 },
+	{ name: "Config User",offset: 0x00200000, size:   0x00600000 }
+};
+#endif
+
+
+/****************************************************************************/
+/*
+ * Find the MTD device with the given name
+ */
+
+static struct mtd_info *get_mtd_named(char *name)
+{
+	int i;
+	struct mtd_info *mtd;
+
+	for (i = 0; i < MAX_MTD_DEVICES; i++) {
+		mtd = get_mtd_device(NULL, i);
+		if (mtd) {
+			if (strcmp(mtd->name, name) == 0)
+				return(mtd);
+			put_mtd_device(mtd);
+		}
+	}
+	return(NULL);
+}
+
+/****************************************************************************/
+
+static int
+Feith_point(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, u_char **mtdbuf)
+{
+	struct map_info *map = (struct map_ptr *) mtd->priv;
+	*mtdbuf = map->map_priv_1 + from;
+	*retlen = len;
+	return(0);
+}
+
+/****************************************************************************/
+
+static int __init
+Feith_probe(int ram, unsigned long addr, int size, int buswidth)
+{
+	struct mtd_info *mymtd;
+	struct map_info *map_ptr;
+
+	if (ram)
+		map_ptr = &Feith_ram_map;
+	else
+		map_ptr = &Feith_flash_map;
+
+	map_ptr->buswidth = buswidth;
+	map_ptr->map_priv_2 = addr;
+	map_ptr->size = size;
+
+	printk(KERN_NOTICE "Feith MTD %s probe(0x%lx,%d,%d): %lx at %lx\n",
+			ram ? "ram" : "flash",
+			addr, size, buswidth, map_ptr->size, map_ptr->map_priv_2);
+
+	map_ptr->map_priv_1 = (unsigned long)
+			ioremap_nocache(map_ptr->map_priv_2, map_ptr->size);
+
+	if (!map_ptr->map_priv_1) {
+		printk("Failed to ioremap_nocache\n");
+		return -EIO;
+	}
+
+	if (!ram) {
+		mymtd = do_map_probe("cfi_probe", map_ptr);
+	} else {
+		mymtd = do_map_probe("map_ram", map_ptr);
+	}
+
+	if (!mymtd) {
+		iounmap((void *)map_ptr->map_priv_1);
+		return -ENXIO;
+	}
+
+	mymtd->module = THIS_MODULE;
+	mymtd->point = Feith_point;
+	mymtd->priv = map_ptr;
+
+	if (ram) {
+		ram_mtdinfo = mymtd;
+		add_mtd_partitions(mymtd, Feith_romfs, NB_OF(Feith_romfs));
+		return(0);
+	}
+
+	flash_mtdinfo = mymtd;
+	switch (size) {
+	case SIZE_2MB:
+		add_mtd_partitions(mymtd, Feith_2mb, NB_OF(Feith_2mb));
+		break;
+	case SIZE_4MB:
+		add_mtd_partitions(mymtd, Feith_4mb, NB_OF(Feith_4mb));
+		break;
+	case SIZE_6MB:
+		add_mtd_partitions(mymtd, Feith_6mb, NB_OF(Feith_6mb));
+		break;
+#if defined(CONFIG_CANCAM)
+	case SIZE_8MB:
+		add_mtd_partitions(mymtd, Feith_8mb, NB_OF(Feith_8mb));
+		break;
+#endif
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
+
+int __init Feith_mtd_init(void)
+{
+	int rc = -1;
+	struct mtd_info *mtd;
+	extern char _ebss;
+
+	/*
+	 * I hate this ifdef stuff,  but our HW doesn't always have
+	 * the same chipsize as the map that we use
+	 */
+#if defined(CONFIG_CANCAM)
+#if defined(CONFIG_FLASH8MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = Feith_probe(0, FLASH_BASE, SIZE_8MB, BUS_WIDTH);
+#endif
+#endif
+
+#if defined(CONFIG_FLASH6MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = Feith_probe(0, FLASH_BASE, SIZE_6MB, BUS_WIDTH);
+#endif
+
+#if defined(CONFIG_FLASH4MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = Feith_probe(0, FLASH_BASE, SIZE_4MB, BUS_WIDTH);
+#endif
+
+#if defined(CONFIG_FLASH2MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = Feith_probe(0, FLASH_BASE, SIZE_2MB, BUS_WIDTH);
+#endif
+
+	/*
+	 * Map in the filesystem from RAM last so that,  if the filesystem
+	 * is not in RAM for some reason we do not change the minor/major
+	 * for the flash devices
+	 */
+#ifndef CONFIG_ROMFS_FROM_ROM
+	if (0 != Feith_probe(1, (unsigned long) &_ebss,
+			PAGE_ALIGN(* (unsigned long *)((&_ebss) + 8)), 4))
+		printk("Failed to probe RAM filesystem 1\n");
+#else
+	{
+		unsigned long start_area;
+		unsigned char *sp, *ep;
+		size_t len;
+
+		start_area = (unsigned long) &_ebss;
+
+		if (strncmp((char *) start_area, "-rom1fs-", 8) != 0) {
+			mtd = get_mtd_named("Image");
+			if (mtd && mtd->point) {
+				if ((*mtd->point)(mtd, 0, mtd->size, &len, &sp) == 0) {
+					ep = sp + len;
+					while (sp < ep && strncmp(sp, "-rom1fs-", 8) != 0)
+						sp++;
+					if (sp < ep)
+						start_area = (unsigned long) sp;
+				}
+			}
+			if (mtd)
+				put_mtd_device(mtd);
+		}
+		if (0 != Feith_probe(1, start_area,
+				PAGE_ALIGN(* (unsigned long *)(start_area + 8)), 4))
+			printk("Failed to probe RAM filesystem 2\n");
+	}
+#endif
+	
+	mtd = get_mtd_named("romfs");
+	if (mtd) {
+		ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+		put_mtd_device(mtd);
+	}
+
+	return(rc);
+}
+
+/****************************************************************************/
+
+static void __exit Feith_mtd_cleanup(void)
+{
+	if (flash_mtdinfo) {
+		del_mtd_partitions(flash_mtdinfo);
+		map_destroy(flash_mtdinfo);
+		flash_mtdinfo = NULL;
+	}
+	if (ram_mtdinfo) {
+		del_mtd_partitions(ram_mtdinfo);
+		map_destroy(ram_mtdinfo);
+		ram_mtdinfo = NULL;
+	}
+	if (Feith_ram_map.map_priv_1) {
+		iounmap((void *)Feith_ram_map.map_priv_1);
+		Feith_ram_map.map_priv_1 = 0;
+	}
+	if (Feith_flash_map.map_priv_1) {
+		iounmap((void *)Feith_flash_map.map_priv_1);
+		Feith_flash_map.map_priv_1 = 0;
+	}
+}
+
+/****************************************************************************/
+
+module_init(Feith_mtd_init);
+module_exit(Feith_mtd_cleanup);
+
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/mtd/maps/iq80310.c linux-2.4.29-uc1/drivers/mtd/maps/iq80310.c
--- linux-2.4.29/drivers/mtd/maps/iq80310.c	2002-08-03 01:39:44.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/iq80310.c	2005-06-14 02:12:08.000000000 +0100
@@ -107,7 +107,7 @@
 static struct mtd_info *mymtd;
 static struct mtd_partition *parsed_parts;
 
-extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts, unsigned long fis_origin);
 
 static int __init init_iq80310(void)
 {
@@ -130,7 +130,7 @@
 
 #ifdef CONFIG_MTD_REDBOOT_PARTS
 	if (parsed_nr_parts == 0) {
-		int ret = parse_redboot_partitions(mymtd, &parsed_parts);
+		int ret = parse_redboot_partitions(mymtd, &parsed_parts, 0);
 
 		if (ret > 0) {
 			part_type = "RedBoot";
diff -urN linux-2.4.29/drivers/mtd/maps/ixp425.c linux-2.4.29-uc1/drivers/mtd/maps/ixp425.c
--- linux-2.4.29/drivers/mtd/maps/ixp425.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/ixp425.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,334 @@
+/*
+ * drivers/mtd/maps
+ *
+ * MTD Map file for IXP425 based systems
+ *
+ * Original Author: Intel Corporation
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2002 Intel Corporation
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/ioport.h>
+#include <linux/reboot.h>
+#include <asm/io.h>
+
+#define WINDOW_ADDR 	0x50000000
+#define WINDOW_ADDR2 	0x51000000
+#define BUSWIDTH 	2
+#define WINDOW_SIZE	0x01000000
+
+#ifndef __ARMEB__
+#define	BYTE0(h)	((h) & 0xFF)
+#define	BYTE1(h)	(((h) >> 8) & 0xFF)
+#else
+#define	BYTE0(h)	(((h) >> 8) & 0xFF)
+#define	BYTE1(h)	((h) & 0xFF)
+#endif
+
+static __u16 ixp425_read16(struct map_info *map, unsigned long ofs)
+{
+	return *(__u16 *)(map->map_priv_1 + ofs);
+}
+
+/*
+ * The IXP425 expansion bus only allows 16-bit wide acceses
+ * when attached to a 16-bit wide device (such as the 28F128J3A),
+ * so we can't use a memcpy_fromio as it does byte acceses.
+ */
+static void ixp425_copy_from(struct map_info *map, void *to,
+    unsigned long from, ssize_t len)
+{
+	int i;
+	u8 *dest = (u8*)to;
+	u16 *src = (u16 *)(map->map_priv_1 + from);
+	u16 data;
+
+	for(i = 0; i < (len / 2); i++) {
+		data = src[i];
+		dest[i * 2] = BYTE0(data);
+		dest[i * 2 + 1] = BYTE1(data);
+	}
+
+	if(len & 1)
+		dest[len - 1] = BYTE0(src[i]);
+}
+
+static void ixp425_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*(__u16 *)(map->map_priv_1 + adr) = d;
+}
+
+static struct map_info ixp425_map = {
+	name: 		"IXP425 Flash",
+	buswidth: 	BUSWIDTH,
+	read16:		ixp425_read16,
+	copy_from:	ixp425_copy_from,
+	write16:	ixp425_write16,
+};
+
+
+#ifdef CONFIG_MACH_MONTEJADE
+/*
+ *	The Intel Monte Jade has a second optional flash device on CS1.
+ */
+static struct map_info ixp425_map1 = {
+	name: 		"IXP425 Flash",
+	buswidth: 	BUSWIDTH,
+	read16:		ixp425_read16,
+	copy_from:	ixp425_copy_from,
+	write16:	ixp425_write16,
+};
+static struct mtd_info *ixp425_mtd1;
+static struct resource *mtd_resource1;
+static struct mtd_partition ixp425_partitions1[] = {
+	{
+		name:	"spare",
+		offset:	0x00000000
+    	},
+};
+#endif /* CONFIG_MACH_MONTEJADE */
+
+/*
+ * Put flash back in read mode so RedBoot can boot properly.
+ */
+int ixp425_mtd_reboot(struct notifier_block *n, unsigned long code, void *p)
+{
+	if (code != SYS_RESTART)
+		return NOTIFY_DONE;
+
+	ixp425_write16(&ixp425_map, 0xff, 0x55 * 0x2);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block ixp425_mtd_notifier = {
+	notifier_call:ixp425_mtd_reboot,
+	next:NULL,
+	priority:0
+};
+
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+static struct mtd_partition *parsed_parts;
+#endif
+
+#ifdef CONFIG_MACH_MONTEJADE
+static struct mtd_partition ixp425_partitions[] = {
+	{
+		name:	"RedBoot",
+		offset:	0x00000000,
+		size:	0x00040000
+	},
+	{
+		name:	"config",
+		offset:	0x00040000,
+		size:	0x00040000
+	},
+	{
+		name:	"image",
+		offset:	0x00080000,
+		size:	0x00f40000
+	},
+	{
+		name:	"zImage",
+		offset:	0x00080000,
+		size:	0x00100000
+	},
+	{
+		name:	"ramdisk",
+		offset:	0x00180000,
+		size:	0x00e40000
+	},
+	{
+		name:	"RedBoot config",
+		offset:	0x00fc0000,
+		size:	0x00020000
+	},
+	{
+		name:	"FIS directory",
+		offset:	0x00fe0000,
+		size:	0x00020000
+	},
+	{
+		name:	"all",
+		offset:	0
+	},
+};
+#else
+static struct mtd_partition ixp425_partitions[] = {
+	{
+		name:	"image",
+		offset:	0x00040000,
+		size:	0x00400000, 
+    	},
+	{
+		name:	"user",
+		offset:	0x00440000,
+		size:	0x00B80000, /* Rest of flash space minus redboot 
+				     * configuration sectors (-256k)    
+				     */
+	},
+};
+#endif
+
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+static struct mtd_info *ixp425_mtd;
+static struct resource *mtd_resource;
+
+static void ixp425_exit(void)
+{
+    if(ixp425_mtd){
+	del_mtd_partitions(ixp425_mtd);
+	map_destroy(ixp425_mtd);
+    }
+    if (ixp425_map.map_priv_1)
+	iounmap((void *)ixp425_map.map_priv_1);
+    if (mtd_resource)
+	release_mem_region(WINDOW_ADDR, WINDOW_SIZE);
+    
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+    if (parsed_parts)
+	kfree(parsed_parts);
+#endif
+
+    unregister_reboot_notifier(&ixp425_mtd_notifier);
+
+    /* Disable flash write */
+    *IXP425_EXP_CS0 &= ~IXP425_FLASH_WRITABLE;
+
+#ifdef CONFIG_MACH_MONTEJADE
+    if(ixp425_mtd1){
+	del_mtd_partitions(ixp425_mtd1);
+	map_destroy(ixp425_mtd1);
+    }
+    if (ixp425_map1.map_priv_1)
+	iounmap((void *)ixp425_map1.map_priv_1);
+    if (mtd_resource1)
+	release_mem_region(WINDOW_ADDR2, WINDOW_SIZE);
+    
+    /* Disable flash write */
+    *IXP425_EXP_CS1 &= ~IXP425_FLASH_WRITABLE;
+#endif /* CONFIG_MACH_MONTEJADE */
+}
+
+static int __init ixp425_init(void)
+{
+    int res = -1, npart;
+
+    /* Enable flash write */
+    *IXP425_EXP_CS0 |= IXP425_FLASH_WRITABLE;
+
+    ixp425_map.map_priv_1 = 0;
+    mtd_resource = 
+	request_mem_region(WINDOW_ADDR, WINDOW_SIZE, "ixp425 Flash");
+    if(!mtd_resource) {
+	printk(KERN_ERR "ixp425 flash: Could not request mem region.\n" );
+	res = -ENOMEM;
+	goto Error;
+    }
+
+    ixp425_map.map_priv_1 =
+	(unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+    if (!ixp425_map.map_priv_1) {
+	printk("ixp425 Flash: Failed to map IO region. (ioremap)\n");
+	res = -EIO;
+	goto Error;
+    }
+    ixp425_map.size = WINDOW_SIZE;
+
+
+    /* 
+     * Probe for the CFI complaint chip
+     * suposed to be 28F128J3A
+     */
+    ixp425_mtd = do_map_probe("cfi_probe", &ixp425_map);
+    if (!ixp425_mtd) {
+	res = -ENXIO;
+	goto Error;
+    }
+    ixp425_mtd->module = THIS_MODULE;
+   
+    /* Initialize flash partiotions 
+     * Note: Redeboot partition info table can be parsed by MTD, and used
+     *       instead of hard-coded partions. TBD
+     */
+
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+    /* Try to parse RedBoot partitions */
+    npart = parse_redboot_partitions(ixp425_mtd, &parsed_parts, 0);
+    if (npart > 0) 
+	res = add_mtd_partitions(ixp425_mtd, parsed_parts, npart);
+    else   
+#endif
+	res = -EIO;
+
+    if (res) {
+	printk("Using static MTD partitions.\n");
+	/* RedBoot partitions not found - use hardcoded partition table */
+	res = add_mtd_partitions(ixp425_mtd, ixp425_partitions,
+	    NB_OF(ixp425_partitions));
+    }
+
+    if (res)
+	goto Error;
+
+    register_reboot_notifier(&ixp425_mtd_notifier);
+
+#ifdef CONFIG_MACH_MONTEJADE
+    /*
+     *	Possible second flash device on CS1...
+     */
+    *IXP425_EXP_CS1 = *IXP425_EXP_CS0;
+
+    ixp425_map1.map_priv_1 = 0;
+    mtd_resource1 = 
+	request_mem_region(WINDOW_ADDR2, WINDOW_SIZE, "ixp425 Flash2");
+    if(!mtd_resource1) {
+	printk(KERN_ERR "ixp425 flash2: Could not request mem region.\n" );
+	goto Done;
+    }
+
+    ixp425_map1.map_priv_1 =
+	(unsigned long)ioremap(WINDOW_ADDR2, WINDOW_SIZE);
+    if (!ixp425_map1.map_priv_1) {
+	printk("ixp425 Flash2: Failed to map IO region. (ioremap)\n");
+	goto Done;
+    }
+    ixp425_map1.size = WINDOW_SIZE;
+
+    /* 
+     * Probe for the CFI complaint chip
+     * suposed to be 28F128J3A
+     */
+    ixp425_mtd1 = do_map_probe("cfi_probe", &ixp425_map1);
+    if (!ixp425_mtd1)
+	goto Done;
+
+    ixp425_mtd1->module = THIS_MODULE;
+
+     printk("Using static MTD partitions (on spare flash).\n");
+     add_mtd_partitions(ixp425_mtd1, ixp425_partitions1, NB_OF(ixp425_partitions1));
+#endif /* CONFIG_MACH_MONTEJADE */
+
+Done:
+    return res;
+Error:
+    ixp425_exit();
+    return res;
+}
+
+module_init(ixp425_init);
+module_exit(ixp425_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MTD map driver for ixp425 evaluation board");
+
diff -urN linux-2.4.29/drivers/mtd/maps/keyTechnology.c linux-2.4.29-uc1/drivers/mtd/maps/keyTechnology.c
--- linux-2.4.29/drivers/mtd/maps/keyTechnology.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/keyTechnology.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,311 @@
+/****************************************************************************/
+/*
+ * Flash memory access on Key Technology devices
+ * Copyright (C) Key Technology, Inc. <ktreis@keyww.com>
+ *
+ * Mostly hijacked from nettel-uc.c
+ * Copyright (C) Lineo, <davidm@moreton.com.au>
+ */
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <linux/fs.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+
+/****************************************************************************/
+
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+#define SIZE_2MB	(2 * 1024 * 1024)
+#define SIZE_8MB	(8 * 1024 * 1024)
+
+/*
+ *	If you set AUTO_PROBE,  then we will just use the biggest device
+ *	we can find
+ */
+#undef AUTO_PROBE
+
+/****************************************************************************/
+
+static __u8 keyTechnology_read8(struct map_info *map, unsigned long ofs)
+{
+	return *(__u8 *)(map->map_priv_1 + ofs);
+}
+
+static __u16 keyTechnology_read16(struct map_info *map, unsigned long ofs)
+{
+	return *(__u16 *)(map->map_priv_1 + ofs);
+}
+
+static __u32 keyTechnology_read32(struct map_info *map, unsigned long ofs)
+{
+	return *(__u32 *)(map->map_priv_1 + ofs);
+}
+
+static void keyTechnology_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *)(map->map_priv_1 + from), len);
+}
+
+static void keyTechnology_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*(__u8 *)(map->map_priv_1 + adr) = d;
+}
+
+static void keyTechnology_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*(__u16 *)(map->map_priv_1 + adr) = d;
+}
+
+static void keyTechnology_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*(__u32 *)(map->map_priv_1 + adr) = d;
+}
+
+static void keyTechnology_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy((void *)(map->map_priv_1 + to), from, len);
+}
+
+/****************************************************************************/
+
+static struct map_info keyTechnology_flash_map = {
+	name:		"Flash",
+	read8:		keyTechnology_read8,
+	read16:		keyTechnology_read16,
+	read32:		keyTechnology_read32,
+	copy_from:	keyTechnology_copy_from,
+	write8:		keyTechnology_write8,
+	write16:	keyTechnology_write16,
+	write32:	keyTechnology_write32,
+	copy_to:	keyTechnology_copy_to,
+};
+
+static struct map_info keyTechnology_ram_map = {
+	name:		"RAM",
+	read8:		keyTechnology_read8,
+	read16:		keyTechnology_read16,
+	read32:		keyTechnology_read32,
+	copy_from:	keyTechnology_copy_from,
+	write8:		keyTechnology_write8,
+	write16:	keyTechnology_write16,
+	write32:	keyTechnology_write32,
+	copy_to:	keyTechnology_copy_to,
+};
+
+static struct mtd_info *ram_mtdinfo;
+static struct mtd_info *flash_mtdinfo;
+
+/****************************************************************************/
+
+static struct mtd_partition keyTechnology_romfs[] = {
+	{ name: "romfs", offset: 0 }
+};
+
+/****************************************************************************/
+/*
+ *	The layout of our flash,  note the order of the names,  this
+ *	means we use the same major/minor for the same purpose on all
+ *	layouts (when possible)
+ */
+
+static struct mtd_partition keyTechnology_2mb[] = {
+	{ name: "bootloader",	offset: 0x00000000, size: 0x00004000 },
+	{ name: "ethernet",		offset: 0x00004000, size: 0x00002000 },
+	{ name: "cmdline",		offset: 0x00006000, size: 0x00002000 },
+	{ name: "kernel+romfs",	offset: 0x00040000, size: 0x000c0000 },
+	{ name: "config",		offset: 0x00100000, size: 0x00100000 }
+};
+
+/****************************************************************************/
+/*
+ * Find the MTD device with the given name
+ */
+
+static struct mtd_info *get_mtd_named(char *name)
+{
+	int i;
+	struct mtd_info *mtd;
+
+	for (i = 0; i < MAX_MTD_DEVICES; i++) {
+		mtd = get_mtd_device(NULL, i);
+		if (mtd) {
+			if (strcmp(mtd->name, name) == 0)
+				return(mtd);
+			put_mtd_device(mtd);
+		}
+	}
+	return(NULL);
+}
+
+/****************************************************************************/
+
+static int
+keyTechnology_point(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, u_char **mtdbuf)
+{
+	struct map_info *map = (struct map_ptr *) mtd->priv;
+	*mtdbuf = map->map_priv_1 + from;
+	*retlen = len;
+	return(0);
+}
+
+/****************************************************************************/
+
+static int __init
+keyTechnology_probe(int ram, unsigned long addr, int size, int buswidth)
+{
+	struct mtd_info *mymtd;
+	struct map_info *map_ptr;
+
+	if (ram)
+		map_ptr = &keyTechnology_ram_map;
+	else
+		map_ptr = &keyTechnology_flash_map;
+
+	map_ptr->buswidth = buswidth;
+	map_ptr->map_priv_2 = addr;
+	map_ptr->size = size;
+
+	printk(KERN_NOTICE "Key MTD %s probe(0x%lx,%d,%d): %lx at %lx\n",
+			ram ? "ram" : "flash",
+			addr, size, buswidth, map_ptr->size, map_ptr->map_priv_2);
+
+	map_ptr->map_priv_1 = (unsigned long)
+			ioremap_nocache(map_ptr->map_priv_2, map_ptr->size);
+
+	if (!map_ptr->map_priv_1) {
+		printk("Failed to ioremap_nocache\n");
+		return -EIO;
+	}
+
+	if (!ram) {
+		mymtd = do_map_probe("cfi_probe", map_ptr);
+	} else {
+		mymtd = do_map_probe("map_ram", map_ptr);
+	}
+
+	if (!mymtd) {
+		iounmap((void *)map_ptr->map_priv_1);
+		return -ENXIO;
+	}
+		
+	mymtd->module = THIS_MODULE;
+	mymtd->point = keyTechnology_point;
+	mymtd->priv = map_ptr;
+
+	if (ram) {
+		ram_mtdinfo = mymtd;
+		add_mtd_partitions(mymtd, keyTechnology_romfs, NB_OF(keyTechnology_romfs));
+		return(0);
+	}
+
+	flash_mtdinfo = mymtd;
+	switch (size) {
+	case SIZE_2MB:
+		add_mtd_partitions(mymtd, keyTechnology_2mb, NB_OF(keyTechnology_2mb));
+		break;
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
+
+int __init keyTechnology_mtd_init(void)
+{
+	int rc = -1;
+	struct mtd_info *mtd;
+	extern char _ebss;
+
+#if defined(CONFIG_FLASH2MB) || defined(AUTO_PROBE)
+	if (rc != 0)
+		rc = keyTechnology_probe(0, 0xffe00000, SIZE_2MB, 2);
+#endif
+
+	/*
+	 * Map in the filesystem from RAM last so that,  if the filesystem
+	 * is not in RAM for some reason we do not change the minor/major
+	 * for the flash devices
+	 */
+#ifndef CONFIG_ROMFS_FROM_ROM
+	if (0 != keyTechnology_probe(1, (unsigned long) &_ebss,
+			PAGE_ALIGN(* (unsigned long *)((&_ebss) + 8)), 4))
+		printk("Failed to probe RAM filesystem\n");
+#else
+	{
+		unsigned long start_area;
+		unsigned char *sp, *ep;
+		size_t len;
+
+		start_area = (unsigned long) &_ebss;
+
+		if (strncmp((char *) start_area, "-rom1fs-", 8) != 0) {
+			mtd = get_mtd_named("Image");
+			if (mtd && mtd->point) {
+				if ((*mtd->point)(mtd, 0, mtd->size, &len, &sp) == 0) {
+					ep = sp + len;
+					while (sp < ep && strncmp(sp, "-rom1fs-", 8) != 0)
+						sp++;
+					if (sp < ep)
+						start_area = (unsigned long) sp;
+				}
+			}
+			if (mtd)
+				put_mtd_device(mtd);
+		}
+		if (0 != keyTechnology_probe(1, start_area,
+				PAGE_ALIGN(* (unsigned long *)(start_area + 8)), 4))
+			printk("Failed to probe RAM filesystem\n");
+	}
+#endif
+	
+	mtd = get_mtd_named("romfs");
+	if (mtd) {
+		ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+		put_mtd_device(mtd);
+	}
+
+	return(rc);
+}
+
+/****************************************************************************/
+
+static void __exit keyTechnology_mtd_cleanup(void)
+{
+	if (flash_mtdinfo) {
+		del_mtd_partitions(flash_mtdinfo);
+		map_destroy(flash_mtdinfo);
+		flash_mtdinfo = NULL;
+	}
+	if (ram_mtdinfo) {
+		del_mtd_partitions(ram_mtdinfo);
+		map_destroy(ram_mtdinfo);
+		ram_mtdinfo = NULL;
+	}
+	if (keyTechnology_ram_map.map_priv_1) {
+		iounmap((void *)keyTechnology_ram_map.map_priv_1);
+		keyTechnology_ram_map.map_priv_1 = 0;
+	}
+	if (keyTechnology_flash_map.map_priv_1) {
+		iounmap((void *)keyTechnology_flash_map.map_priv_1);
+		keyTechnology_flash_map.map_priv_1 = 0;
+	}
+}
+
+/****************************************************************************/
+
+module_init(keyTechnology_mtd_init);
+module_exit(keyTechnology_mtd_cleanup);
+
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/mtd/maps/keywest.c linux-2.4.29-uc1/drivers/mtd/maps/keywest.c
--- linux-2.4.29/drivers/mtd/maps/keywest.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/keywest.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,184 @@
+/*
+ * Flash memory access on SH/KeyWest based devices
+ * (C) 2001 Lineo
+ * (C) 2002,2003 SnapGear, davidm@snapgear.com
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+
+#ifndef CONFIG_SUPERH
+#error This is for SH architecture only
+#endif
+
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+static __u8 keywest_read8(struct map_info *map, unsigned long ofs)
+{
+	return *(__u8 *)(map->map_priv_1 + ofs);
+}
+
+static __u16 keywest_read16(struct map_info *map, unsigned long ofs)
+{
+	return *(__u16 *)(map->map_priv_1 + ofs);
+}
+
+static __u32 keywest_read32(struct map_info *map, unsigned long ofs)
+{
+	return *(__u32 *)(map->map_priv_1 + ofs);
+}
+
+static void keywest_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *)(map->map_priv_1 + from), len);
+}
+
+static void keywest_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*(__u8 *)(map->map_priv_1 + adr) = d;
+}
+
+static void keywest_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*(__u16 *)(map->map_priv_1 + adr) = d;
+}
+
+static void keywest_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*(__u32 *)(map->map_priv_1 + adr) = d;
+}
+
+static void keywest_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy((void *)(map->map_priv_1 + to), from, len);
+}
+
+static struct map_info keywest_map = {
+	name:		"KeyWest/BigSur flash",
+	read8:		keywest_read8,
+	read16:		keywest_read16,
+	read32:		keywest_read32,
+	copy_from:	keywest_copy_from,
+	write8:		keywest_write8,
+	write16:	keywest_write16,
+	write32:	keywest_write32,
+	copy_to:	keywest_copy_to,
+	size:       0x00400000,			/* 32 Mbytes */
+};
+
+static struct mtd_partition keywest_partitions[] = {
+	{
+		name: "Bootloader",
+		offset: 0x00000000,
+		size:   0x00080000
+	},
+	{
+		name: "Bootargs",
+		offset: 0x00080000,
+		size:   0x00080000
+	},
+	{
+		name: "Config",
+		offset: 0x00180000,
+		size:   0x00080000
+	},
+	{
+		name: "Spare",
+		offset: 0x00100000,
+		size:   0x00080000
+	},
+	{
+		name: "kernel/root",
+		offset: 0x00200000,
+		size:   0x00e00000
+	},
+	{
+		name: "Full flash",
+		offset: 0
+	}
+};
+
+static struct mtd_partition *parsed_parts;
+static struct mtd_info *mymtd;
+
+static int __init keywest_probe(unsigned long addr, int buswidth)
+{
+	keywest_map.buswidth = buswidth;
+	keywest_map.map_priv_2 = addr;
+
+	printk(KERN_NOTICE "KeyWest flash probe(0x%x,%d): %lx at %lx\n",
+			addr, buswidth, keywest_map.size, keywest_map.map_priv_2);
+
+	keywest_map.map_priv_1 = (unsigned long)
+			ioremap_nocache(keywest_map.map_priv_2, keywest_map.size);
+
+	if (!keywest_map.map_priv_1) {
+		printk("Failed to ioremap_nocache\n");
+		return -EIO;
+	}
+	mymtd = do_map_probe("cfi_probe", &keywest_map);
+	if(!mymtd)
+		mymtd = do_map_probe("jedec_probe", &keywest_map);
+
+	if (!mymtd) {
+		printk("No flash/rom found !\n");
+		iounmap((void *)keywest_map.map_priv_1);
+		return -ENXIO;
+	}
+		
+	mymtd->module = THIS_MODULE;
+	add_mtd_partitions(mymtd, keywest_partitions, NB_OF(keywest_partitions));
+	return 0;
+}
+
+int __init keywest_mtd_init(void)
+{
+	unsigned short r;
+	int rc;
+
+#if defined(CONFIG_SH_KEYWEST)
+	/*
+	 *	Need to enable flash writes to ID chips etc
+	 *	Port D(2) is our target,  set it to '1'
+	 */
+	r = * (unsigned short *) 0xa4000106;
+	r &= ~0x0030;
+	r |=  0x0010;
+	* (unsigned short *) 0xa4000106 = r;
+	* (unsigned char *) 0xa4000126 |= 0x04;
+#elif defined(CONFIG_SH_BIGSUR)
+	/*
+	 *	Need to enable flash writes to ID chips etc
+	 */
+	* (unsigned char *) 0xb1fffb00 = 0x08;
+#endif
+
+	rc = keywest_probe(0x0000000, 4); /* boot from FLASH */
+	if (rc != 0)
+		rc = keywest_probe(0x8000000, 4); /* otherwise boot from ROM */
+	return(rc);
+}
+
+static void __exit keywest_mtd_cleanup(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+	if (keywest_map.map_priv_1) {
+		iounmap((void *)keywest_map.map_priv_1);
+		keywest_map.map_priv_1 = 0;
+	}
+}
+
+module_init(keywest_mtd_init);
+module_exit(keywest_mtd_cleanup);
diff -urN linux-2.4.29/drivers/mtd/maps/m5272c3.c linux-2.4.29-uc1/drivers/mtd/maps/m5272c3.c
--- linux-2.4.29/drivers/mtd/maps/m5272c3.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/m5272c3.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,273 @@
+/*
+ *
+ * Normal mappings of chips in physical memory
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/config.h>
+
+#ifdef CONFIG_SIGNAL_MCP751
+#define WINDOW_ADDR 0xff000000
+#define WINDOW_SIZE 0x400000
+#else
+#define WINDOW_ADDR 0xffe00000
+#define WINDOW_SIZE 0x200000
+#endif
+#define BUSWIDTH 2
+
+extern char* ppcboot_getenv(char* v);
+
+static struct mtd_info *mymtd;
+
+__u8 m5272c3_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 m5272c3_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 m5272c3_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void m5272c3_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void m5272c3_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void m5272c3_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void m5272c3_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void m5272c3_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info m5272c3_map = {
+	name: "MCF5272C3 flash device",
+	size: WINDOW_SIZE,
+	buswidth: BUSWIDTH,
+	read8: m5272c3_read8,
+	read16: m5272c3_read16,
+	read32: m5272c3_read32,
+	copy_from: m5272c3_copy_from,
+	write8: m5272c3_write8,
+	write16: m5272c3_write16,
+	write32: m5272c3_write32,
+	copy_to: m5272c3_copy_to
+};
+
+/*
+ * MTD 'PARTITIONING' STUFF 
+ */
+
+#ifndef CONFIG_PPCBOOT
+
+static struct mtd_partition m5272c3_partitions[] = {
+
+#ifdef CONFIG_SIGNAL_MCP751
+	{
+		name:		"colilo_0",
+		size:		0x2000,
+		offset:		0,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"config_0",
+		size:		0x2000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"config_1",
+		size:		0x2000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"config_2",
+		size:		0x2000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"colilo_1",
+		size:		0x8000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"colilo_2",
+		size:		0x10000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"fpga",
+		size:		0x20000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"kernel",
+		size:		0x180000,
+		offset:		MTDPART_OFS_APPEND,
+		mask_flags:	MTD_WRITEABLE,  /* force read-only */
+	}, {
+		name:		"user0",
+		size:		0x100000,
+		offset:		MTDPART_OFS_APPEND,
+	}, {
+		name:		"user",
+		size:		MTDPART_SIZ_FULL,
+		offset:		MTDPART_OFS_APPEND,
+	}
+};
+#else
+        {
+                name: "kernel (768K)",
+                size: 0xc0000,
+                offset: 0x40000
+        },
+        {
+                name: "rootfs (1024K)",
+                size: 0x100000,
+                offset: 0x100000
+        },
+	{
+                name: "environment (8K)",
+                size: 0x2000,
+                offset: 0x4000
+        }
+};
+#endif
+
+#else
+
+#define M5272C3_MAX_PARTITIONS 8
+#define M5272C3_MAX_PARTARGENTRIES 3
+#define M5272C3_PTABLE_BUFSIZE 256
+static struct mtd_partition m5272c3_partitions[M5272C3_MAX_PARTITIONS];
+static int m5272c3_partitions_cnt=0;
+static char* m5272c3_emptyentry = "";
+
+static void read_m5272c3_partitiontable(void) {
+  char* envptable=ppcboot_getenv("ptable");
+  if(envptable) {
+    char ptable[M5272C3_PTABLE_BUFSIZE],*p,*pt;
+    int pcnt,acnt,i;
+    char *ptableargentry[M5272C3_MAX_PARTITIONS][M5272C3_MAX_PARTARGENTRIES];
+    
+    strncpy(ptable,envptable,M5272C3_PTABLE_BUFSIZE-1);
+    ptable[M5272C3_PTABLE_BUFSIZE-1]=0;
+
+    for(pcnt=0;pcnt<M5272C3_MAX_PARTITIONS;pcnt++) {
+      for(acnt=0;acnt<M5272C3_MAX_PARTARGENTRIES;acnt++) {
+	ptableargentry[pcnt][acnt]=m5272c3_emptyentry;
+      };
+    };
+
+    pcnt=acnt=0;
+    p=pt=ptable;
+    while(1) {
+      if((*p == ',') || (*p == ':') || (*p == 0)) {
+	if(pcnt<M5272C3_MAX_PARTITIONS) {      
+	  if(acnt<M5272C3_MAX_PARTARGENTRIES)
+	    ptableargentry[pcnt][acnt++]=pt;
+	  if((*p == ':') || ( *p == 0 ))
+	    { acnt=0; pcnt++; };
+	  if( *p == 0 )
+	    break;
+	  pt=p+1;
+	};
+	*p=0;
+      };
+      p++;
+    };
+
+    for(i=0;i<pcnt;i++) {
+      m5272c3_partitions[i].name=
+	(char*)kmalloc(strlen(ptableargentry[i][0])+1,GFP_KERNEL);
+      strcpy(m5272c3_partitions[i].name,ptableargentry[i][0]);
+      m5272c3_partitions[i].size=
+	simple_strtoul(ptableargentry[i][1],0,16)*0x1000;
+      m5272c3_partitions[i].offset=
+	simple_strtoul(ptableargentry[i][2],0,16)*0x1000;
+    };
+    
+    m5272c3_partitions_cnt=pcnt;
+  };
+};
+
+#endif
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_m5272c3 init_module
+#define cleanup_m5272c3 cleanup_module
+#endif
+
+int __init init_m5272c3(void)
+{
+       	printk(KERN_NOTICE "m5272c3 flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
+	m5272c3_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+	if (!m5272c3_map.map_priv_1) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}
+	mymtd = do_map_probe("cfi_probe", &m5272c3_map);
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+
+#ifdef CONFIG_PPCBOOT
+                read_m5272c3_partitiontable();
+		if(m5272c3_partitions_cnt) {
+		  return add_mtd_partitions(mymtd, m5272c3_partitions, m5272c3_partitions_cnt);
+		}
+		else {
+		  return  -ENXIO;
+		};
+#else
+		return add_mtd_partitions(mymtd, m5272c3_partitions,
+					  sizeof(m5272c3_partitions) /
+					  sizeof(struct mtd_partition));
+#endif
+	}
+
+	iounmap((void *)m5272c3_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_m5272c3(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+	if (m5272c3_map.map_priv_1) {
+		iounmap((void *)m5272c3_map.map_priv_1);
+		m5272c3_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_m5272c3);
+module_exit(cleanup_m5272c3);
+
diff -urN linux-2.4.29/drivers/mtd/maps/Makefile linux-2.4.29-uc1/drivers/mtd/maps/Makefile
--- linux-2.4.29/drivers/mtd/maps/Makefile	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/Makefile	2005-06-14 02:12:08.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # linux/drivers/maps/Makefile
 #
-# $Id: Makefile,v 1.37 2003/01/24 14:26:38 dwmw2 Exp $
+# $Id: Makefile,v 1.2 2003/10/24 11:00:57 bas Exp $
 
 BELOW25		:= $(shell echo $(PATCHLEVEL) | sed s/[1234]/y/)
 
@@ -10,6 +10,7 @@
 endif
 
 # Chip mappings
+obj-$(CONFIG_MTD_DRAGONIX)      += dragonix_map.o
 obj-$(CONFIG_MTD_CDB89712)	+= cdb89712.o
 obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o
 obj-$(CONFIG_MTD_CFI_FLAGADM)	+= cfi_flagadm.o
@@ -47,19 +48,47 @@
 obj-$(CONFIG_MTD_SCx200_DOCFLASH)+= scx200_docflash.o
 obj-$(CONFIG_MTD_DBOX2)		+= dbox2-flash.o
 obj-$(CONFIG_MTD_OCELOT)	+= ocelot.o
+obj-$(CONFIG_MTD_KEYWEST)	+= keywest.o
+obj-$(CONFIG_MTD_SNAPGEODE)	+= snapgeode.o
+obj-$(CONFIG_MTD_SNAPARM)	+= snaparm.o
 obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
+obj-$(CONFIG_MTD_ADVANTA)	+= advanta.o
+obj-$(CONFIG_MTD_KeyTechnology)	+= keyTechnology.o
+obj-$(CONFIG_MTD_COBRA5272)     += cobra5272.o
+obj-$(CONFIG_MTD_DNP5280)	+= dnp5280.o
+obj-$(CONFIG_MTD_M5272C3)	+= m5272c3.o
 obj-$(CONFIG_MTD_PCI)		+= pci.o
 obj-$(CONFIG_MTD_PB1000)	+= pb1xxx-flash.o
 obj-$(CONFIG_MTD_PB1100)	+= pb1xxx-flash.o
 obj-$(CONFIG_MTD_PB1500)	+= pb1xxx-flash.o
 obj-$(CONFIG_MTD_LASAT)		+= lasat.o
 obj-$(CONFIG_MTD_AUTCPU12)	+= autcpu12-nvram.o
+obj-$(CONFIG_MTD_IXP425)	+= ixp425.o
+obj-$(CONFIG_MTD_SE4000)	+= se4000.o
+obj-$(CONFIG_MTD_CLPS7500)	+= clps7500.o
 obj-$(CONFIG_MTD_EDB7312)	+= edb7312.o
+obj-$(CONFIG_MTD_EDB9301)	+= edb9301.o
+obj-$(CONFIG_MTD_EDB9302)	+= edb9302.o
+obj-$(CONFIG_MTD_EDB9312)	+= edb9312.o
+obj-$(CONFIG_MTD_EDB9315)	+= edb9315.o
 obj-$(CONFIG_MTD_IMPA7)		+= impa7.o
 obj-$(CONFIG_MTD_FORTUNET)	+= fortunet.o
 obj-$(CONFIG_MTD_REDWOOD)	+= redwood.o
+obj-$(CONFIG_MTD_SUZAKU)	+= suzaku.o
 obj-$(CONFIG_MTD_UCLINUX)	+= uclinux.o
+obj-$(CONFIG_MTD_DM270)		+= dm270-flash.o
 obj-$(CONFIG_MTD_NETtel)	+= nettel.o
+obj-$(CONFIG_MTD_NETteluC)	+= nettel-uc.o
 obj-$(CONFIG_MTD_SCB2_FLASH)	+= scb2_flash.o
+obj-$(CONFIG_MTD_MBVANILLA)	+= mbvanilla-flash.o
+obj-$(CONFIG_MTD_ML401)		+= ml401.o
+obj-$(CONFIG_MTD_SED_SIOSIII)       += sedsios.o
+obj-$(CONFIG_MTD_BLACKFIN_533)	+= bf533-flash.o
+obj-$(CONFIG_MTD_COBRA5282)	+= cobra5282.o
+obj-$(CONFIG_MTD_FEITH)		+= feith.o
+obj-$(CONFIG_MTD_CPU16B)        += mtdcpu16b.o
+obj-$(CONFIG_MTD_VC547X) += vc547x-flash.o
+obj-$(CONFIG_MTD_TIBURON)	+= tiburon.o
 
 include $(TOPDIR)/Rules.make
+
diff -urN linux-2.4.29/drivers/mtd/maps/mbvanilla-flash.c linux-2.4.29-uc1/drivers/mtd/maps/mbvanilla-flash.c
--- linux-2.4.29/drivers/mtd/maps/mbvanilla-flash.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/mbvanilla-flash.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,436 @@
+/****************************************************************************/
+/*
+ * Flash memory access on uClinux mbvanilla Microblaze systems
+ * Copyright (C) 2003,      John Williams <jwilliams@itee.uq.edu.au>
+ *  based upon NETTEL_uc support, which is 
+ * Copyright (C) 2001-2002, David McCullough <davidm@snapgear.com>
+ */
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nftl.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/cfi.h>
+
+#include <linux/fs.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+
+/****************************************************************************/
+
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+#define SIZE_128K	(128 * 1024)
+#define SIZE_1MB	(1024 * 1024)
+#define SIZE_2MB	(2 * 1024 * 1024)
+#define SIZE_4MB	(4 * 1024 * 1024)
+#define SIZE_8MB	(8 * 1024 * 1024)
+
+#ifdef CONFIG_MBVANILLA
+#define FLASH_BASE	0xff000000
+#define	BUS_WIDTH	4
+#elif defined(CONFIG_UCLINUX_AUTO)
+#define FLASH_BASE	0xff000000
+#define BUS_WIDTH	4
+#endif
+
+/****************************************************************************/
+
+static __u8 mbvanilla_read8(struct map_info *map, unsigned long ofs)
+{
+	return *(__u8 *)(map->map_priv_1 + ofs);
+}
+
+static __u16 mbvanilla_read16(struct map_info *map, unsigned long ofs)
+{
+	return *(__u16 *)(map->map_priv_1 + ofs);
+}
+
+static __u32 mbvanilla_read32(struct map_info *map, unsigned long ofs)
+{
+	return *(__u32 *)(map->map_priv_1 + ofs);
+}
+
+static void mbvanilla_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *)(map->map_priv_1 + from), len);
+}
+
+static void mbvanilla_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*(__u8 *)(map->map_priv_1 + adr) = d;
+}
+
+static void mbvanilla_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*(__u16 *)(map->map_priv_1 + adr) = d;
+}
+
+static void mbvanilla_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*(__u32 *)(map->map_priv_1 + adr) = d;
+}
+
+static void mbvanilla_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy((void *)(map->map_priv_1 + to), from, len);
+}
+
+/****************************************************************************/
+
+static struct map_info mbvanilla_flash_map = {
+	name:		"Flash",
+	read8:		mbvanilla_read8,
+	read16:		mbvanilla_read16,
+	read32:		mbvanilla_read32,
+	copy_from:	mbvanilla_copy_from,
+	write8:		mbvanilla_write8,
+	write16:	mbvanilla_write16,
+	write32:	mbvanilla_write32,
+	copy_to:	mbvanilla_copy_to,
+};
+
+static struct map_info mbvanilla_ram_map = {
+	name:		"RAM",
+	read8:		mbvanilla_read8,
+	read16:		mbvanilla_read16,
+	read32:		mbvanilla_read32,
+	copy_from:	mbvanilla_copy_from,
+	write8:		mbvanilla_write8,
+	write16:	mbvanilla_write16,
+	write32:	mbvanilla_write32,
+	copy_to:	mbvanilla_copy_to,
+};
+
+static struct mtd_info *ram_mtdinfo;
+static struct mtd_info *flash_mtdinfo;
+
+/****************************************************************************/
+
+static struct mtd_partition mbvanilla_romfs[] = {
+	{ name: "Romfs", offset: 0 }
+};
+
+/****************************************************************************/
+/*
+ *	The layout of our flash,  note the order of the names,  this
+ *	means we use the same major/minor for the same purpose on all
+ *	layouts (when possible)
+ */
+
+static struct mtd_partition mbvanilla_128k[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },
+	{ name: "Bootargs",   offset: 0x00004000, size:   0x00004000 },
+	{ name: "MAC",        offset: 0x00008000, size:   0x00004000 },
+	{ name: "Config",     offset: 0x00010000, size:   0x00010000 },
+	{ name: "Spare",      offset: 0x0000c000, size:   0x00004000 },
+	{ name: "Flash",      offset: 0 }
+};
+
+static struct mtd_partition mbvanilla_1mb[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },
+	{ name: "Bootargs",   offset: 0x00004000, size:   0x00002000 },
+	{ name: "MAC",        offset: 0x00006000, size:   0x00002000 },
+	{ name: "Config",     offset: 0x000f0000, size:   0x00010000 },
+	{ name: "Spare",      offset: 0x00008000, size:   0x00008000 },
+	{ name: "Image",      offset: 0x00010000, size:   0x000e0000 },
+	{ name: "Flash",      offset: 0 }
+};
+
+static struct mtd_partition mbvanilla_2mb[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },
+	{ name: "Bootargs",   offset: 0x00004000, size:   0x00002000 },
+	{ name: "MAC",        offset: 0x00006000, size:   0x00002000 },
+	{ name: "Config",     offset: 0x00010000, size:   0x00010000 },
+	{ name: "Spare",      offset: 0x00008000, size:   0x00008000 },
+	{ name: "Image",      offset: 0x00020000, size:   0x001e0000 },
+	{ name: "Flash",      offset: 0 }
+};
+
+static struct mtd_partition mbvanilla_4mb[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },
+	{ name: "Bootargs",   offset: 0x00004000, size:   0x00004000 },
+	{ name: "MAC",        offset: 0x00008000, size:   0x00004000 },
+	{ name: "Config",     offset: 0x00010000, size:   0x00010000 },
+	{ name: "Spare",      offset: 0x0000C000, size:   0x00004000 },
+	{ name: "Image",      offset: 0x00100000, size:   0x00280000 },
+	{ name: "JFFS2",      offset: 0x00380000, size:   0x00080000 },
+	{ name: "Flash",     offset: 0 }
+};
+
+static struct mtd_partition mbvanilla_8mb[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00020000 },
+	{ name: "Bootargs",   offset: 0x00020000, size:   0x00020000 },
+	{ name: "MAC",        offset: 0x00040000, size:   0x00020000 },
+	{ name: "Config",     offset: 0x00080000, size:   0x00080000 },
+	{ name: "Spare",      offset: 0x00060000, size:   0x00020000 },
+	{ name: "Image",      offset: 0x00100000, size:   0x00200000 },
+	{ name: "JFFS2",      offset: 0x00300000, size:   0x00500000 },
+	{ name: "Flash",      offset: 0 }
+};
+
+/****************************************************************************/
+/*
+ * Find the MTD device with the given name
+ */
+
+static struct mtd_info *get_mtd_named(char *name)
+{
+	int i;
+	struct mtd_info *mtd;
+
+	for (i = 0; i < MAX_MTD_DEVICES; i++) {
+		mtd = get_mtd_device(NULL, i);
+		if (mtd) {
+			if (strcmp(mtd->name, name) == 0)
+				return(mtd);
+			put_mtd_device(mtd);
+		}
+	}
+	return(NULL);
+}
+
+/****************************************************************************/
+#ifdef CONFIG_MTD_CFI_INTELEXT
+/*
+ *	Set the Intel flash back to read mode as MTD may leave it in command mode
+ */
+
+static int mbvanilla_reboot_notifier(
+	struct notifier_block *nb,
+	unsigned long val,
+	void *v)
+{
+	struct cfi_private *cfi = mbvanilla_flash_map.fldrv_priv;
+	int i;
+	
+	for (i = 0; cfi && i < cfi->numchips; i++)
+		cfi_send_gen_cmd(0xff, 0x55, cfi->chips[i].start, &mbvanilla_flash_map,
+				cfi, cfi->device_type, NULL);
+
+	return(NOTIFY_OK);
+}
+
+static struct notifier_block mbvanilla_notifier_block = {
+	mbvanilla_reboot_notifier, NULL, 0
+};
+
+#endif
+
+/****************************************************************************/
+
+static int
+mbvanilla_point(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, u_char **mtdbuf)
+{
+	struct map_info *map = (struct map_info *) mtd->priv;
+	*mtdbuf = (u_char *) (map->map_priv_1 + (int)from);
+	*retlen = len;
+	return(0);
+}
+
+static void
+mbvanilla_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
+{
+}
+
+/****************************************************************************/
+
+static int __init
+mbvanilla_probe(int ram, unsigned long addr, int size, int buswidth)
+{
+	struct mtd_info *mymtd;
+	struct map_info *map_ptr;
+
+	if (ram)
+		map_ptr = &mbvanilla_ram_map;
+	else
+		map_ptr = &mbvanilla_flash_map;
+
+	map_ptr->buswidth = buswidth;
+	map_ptr->map_priv_2 = addr;
+	map_ptr->size = size;
+
+	printk(KERN_NOTICE "MBVanilla %s probe(0x%lx,%d,%d): %lx at %lx\n",
+			ram ? "ram" : "flash",
+			addr, size, buswidth, map_ptr->size, map_ptr->map_priv_2);
+
+	map_ptr->map_priv_1 = (unsigned long)
+			ioremap_nocache(map_ptr->map_priv_2, map_ptr->size);
+
+	if (!map_ptr->map_priv_1) {
+		printk("Failed to ioremap_nocache\n");
+		return -EIO;
+	}
+
+	if (!ram) {
+		mymtd = do_map_probe("cfi_probe", map_ptr);
+		if (!mymtd)
+			mymtd = do_map_probe("jedec_probe", map_ptr);
+	} else
+		mymtd = do_map_probe("map_ram", map_ptr);
+
+	if (!mymtd) {
+		iounmap((void *)map_ptr->map_priv_1);
+		return -ENXIO;
+	}
+		
+	mymtd->module = THIS_MODULE;
+	mymtd->point = mbvanilla_point;
+	mymtd->unpoint = mbvanilla_unpoint;
+	mymtd->priv = map_ptr;
+
+	if (ram) {
+		ram_mtdinfo = mymtd;
+		add_mtd_partitions(mymtd, mbvanilla_romfs, NB_OF(mbvanilla_romfs));
+		return(0);
+	}
+
+	flash_mtdinfo = mymtd;
+	switch (size) {
+	case SIZE_128K:
+		add_mtd_partitions(mymtd, mbvanilla_128k, NB_OF(mbvanilla_128k));
+		break;
+	case SIZE_1MB:
+		add_mtd_partitions(mymtd, mbvanilla_1mb, NB_OF(mbvanilla_1mb));
+		break;
+	case SIZE_2MB:
+		add_mtd_partitions(mymtd, mbvanilla_2mb, NB_OF(mbvanilla_2mb));
+		break;
+	case SIZE_4MB:
+		add_mtd_partitions(mymtd, mbvanilla_4mb, NB_OF(mbvanilla_4mb));
+		break;
+	case SIZE_8MB:
+		add_mtd_partitions(mymtd, mbvanilla_8mb, NB_OF(mbvanilla_8mb));
+		break;
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
+
+int __init mbvanilla_mtd_init(void)
+{
+	int rc = -1;
+	struct mtd_info *mtd;
+	extern char _ebss;
+
+	/*
+	 * I hate this ifdef stuff,  but our HW doesn't always have
+	 * the same chipsize as the map that we use
+	 */
+#if defined(CONFIG_FLASH8MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = mbvanilla_probe(0, FLASH_BASE, SIZE_8MB, BUS_WIDTH);
+#endif
+
+#if defined(CONFIG_FLASH4MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = mbvanilla_probe(0, FLASH_BASE, SIZE_4MB, BUS_WIDTH);
+#endif
+
+#if defined(CONFIG_FLASH2MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = mbvanilla_probe(0, FLASH_BASE, SIZE_2MB, BUS_WIDTH);
+#endif
+
+#if defined(CONFIG_FLASH1MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = mbvanilla_probe(0, FLASH_BASE, SIZE_1MB, BUS_WIDTH);
+#endif
+
+#if defined(CONFIG_FLASH128K) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = mbvanilla_probe(0, FLASH_BASE, SIZE_128K, BUS_WIDTH);
+#endif
+
+	/*
+	 * Map in the filesystem from RAM last so that,  if the filesystem
+	 * is not in RAM for some reason we do not change the minor/major
+	 * for the flash devices
+	 */
+#ifndef CONFIG_SEARCH_ROMFS
+	if (0 != mbvanilla_probe(1, (unsigned long) &_ebss,
+			PAGE_ALIGN(* (unsigned long *)((&_ebss) + 8)),4))
+		printk("Failed to probe RAM filesystem\n");
+#else
+	{
+		unsigned long start_area;
+		unsigned char *sp, *ep;
+		size_t len;
+
+		printk("Probing for ROMFS...\n");
+		start_area = (unsigned long) &_ebss;
+
+		if (strncmp((char *) start_area, "-rom1fs-", 8) != 0) {
+			mtd = get_mtd_named("Image");
+			if (mtd && mtd->point) {
+				if ((*mtd->point)(mtd, 0, mtd->size, &len, &sp) == 0) {
+					ep = sp + len;
+					while (sp < ep && strncmp(sp, "-rom1fs-", 8) != 0)
+						sp++;
+					if (sp < ep)
+						start_area = (unsigned long) sp;
+				}
+			}
+			if (mtd)
+				put_mtd_device(mtd);
+		}
+		if (0 != mbvanilla_probe(1, start_area,
+				PAGE_ALIGN(* (unsigned long *)(start_area + 8)), 4))
+			printk("Failed to probe RAM filesystem\n");
+	}
+#endif
+	
+	mtd = get_mtd_named("Romfs");
+	if (mtd) {
+		ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+		put_mtd_device(mtd);
+	}
+
+	return(rc);
+}
+
+/****************************************************************************/
+
+static void __exit mbvanilla_mtd_cleanup(void)
+{
+	if (flash_mtdinfo) {
+		del_mtd_partitions(flash_mtdinfo);
+		map_destroy(flash_mtdinfo);
+		flash_mtdinfo = NULL;
+	}
+	if (ram_mtdinfo) {
+		del_mtd_partitions(ram_mtdinfo);
+		map_destroy(ram_mtdinfo);
+		ram_mtdinfo = NULL;
+	}
+	if (mbvanilla_ram_map.map_priv_1) {
+		iounmap((void *)mbvanilla_ram_map.map_priv_1);
+		mbvanilla_ram_map.map_priv_1 = 0;
+	}
+	if (mbvanilla_flash_map.map_priv_1) {
+		iounmap((void *)mbvanilla_flash_map.map_priv_1);
+		mbvanilla_flash_map.map_priv_1 = 0;
+	}
+}
+
+/****************************************************************************/
+
+module_init(mbvanilla_mtd_init);
+module_exit(mbvanilla_mtd_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Williams <jwilliams@itee.uq.edu.au>");
+MODULE_DESCRIPTION("Microblaze/MBVanilla FLASH support for uClinux");
+
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/mtd/maps/ml401.c linux-2.4.29-uc1/drivers/mtd/maps/ml401.c
--- linux-2.4.29/drivers/mtd/maps/ml401.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/ml401.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,431 @@
+/****************************************************************************/
+/*
+ * Flash memory access on uClinux Microblaze systems on Xilinx ML401 board
+ * Copyright (C) 2003-2005  John Williams <jwilliams@itee.uq.edu.au>
+ *  based upon NETTEL_uc support, which is 
+ * Copyright (C) 2001-2002, David McCullough <davidm@snapgear.com>
+ */
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nftl.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/cfi.h>
+
+#include <linux/fs.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+
+/****************************************************************************/
+
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+#define SIZE_128K	(128 * 1024)
+#define SIZE_1MB	(1024 * 1024)
+#define SIZE_2MB	(2 * 1024 * 1024)
+#define SIZE_4MB	(4 * 1024 * 1024)
+#define SIZE_8MB	(8 * 1024 * 1024)
+
+#define FLASH_BASE	CONFIG_XILINX_FLASH_START
+#define BUS_WIDTH	4
+
+/****************************************************************************/
+
+static __u8 ml401_read8(struct map_info *map, unsigned long ofs)
+{
+	return *(__u8 *)(map->map_priv_1 + ofs);
+}
+
+static __u16 ml401_read16(struct map_info *map, unsigned long ofs)
+{
+	return *(__u16 *)(map->map_priv_1 + ofs);
+}
+
+static __u32 ml401_read32(struct map_info *map, unsigned long ofs)
+{
+	return *(__u32 *)(map->map_priv_1 + ofs);
+}
+
+static void ml401_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *)(map->map_priv_1 + from), len);
+}
+
+static void ml401_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*(__u8 *)(map->map_priv_1 + adr) = d;
+}
+
+static void ml401_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*(__u16 *)(map->map_priv_1 + adr) = d;
+}
+
+static void ml401_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*(__u32 *)(map->map_priv_1 + adr) = d;
+}
+
+static void ml401_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy((void *)(map->map_priv_1 + to), from, len);
+}
+
+/****************************************************************************/
+
+static struct map_info ml401_flash_map = {
+	name:		"Flash",
+	read8:		ml401_read8,
+	read16:		ml401_read16,
+	read32:		ml401_read32,
+	copy_from:	ml401_copy_from,
+	write8:		ml401_write8,
+	write16:	ml401_write16,
+	write32:	ml401_write32,
+	copy_to:	ml401_copy_to,
+};
+
+static struct map_info ml401_ram_map = {
+	name:		"RAM",
+	read8:		ml401_read8,
+	read16:		ml401_read16,
+	read32:		ml401_read32,
+	copy_from:	ml401_copy_from,
+	write8:		ml401_write8,
+	write16:	ml401_write16,
+	write32:	ml401_write32,
+	copy_to:	ml401_copy_to,
+};
+
+static struct mtd_info *ram_mtdinfo;
+static struct mtd_info *flash_mtdinfo;
+
+/****************************************************************************/
+
+static struct mtd_partition ml401_romfs[] = {
+	{ name: "Romfs", offset: 0 }
+};
+
+/****************************************************************************/
+/*
+ *	The layout of our flash,  note the order of the names,  this
+ *	means we use the same major/minor for the same purpose on all
+ *	layouts (when possible)
+ */
+
+static struct mtd_partition ml401_128k[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },
+	{ name: "Bootargs",   offset: 0x00004000, size:   0x00004000 },
+	{ name: "MAC",        offset: 0x00008000, size:   0x00004000 },
+	{ name: "Config",     offset: 0x00010000, size:   0x00010000 },
+	{ name: "Spare",      offset: 0x0000c000, size:   0x00004000 },
+	{ name: "Flash",      offset: 0 }
+};
+
+static struct mtd_partition ml401_1mb[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },
+	{ name: "Bootargs",   offset: 0x00004000, size:   0x00002000 },
+	{ name: "MAC",        offset: 0x00006000, size:   0x00002000 },
+	{ name: "Config",     offset: 0x000f0000, size:   0x00010000 },
+	{ name: "Spare",      offset: 0x00008000, size:   0x00008000 },
+	{ name: "Image",      offset: 0x00010000, size:   0x000e0000 },
+	{ name: "Flash",      offset: 0 }
+};
+
+static struct mtd_partition ml401_2mb[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },
+	{ name: "Bootargs",   offset: 0x00004000, size:   0x00002000 },
+	{ name: "MAC",        offset: 0x00006000, size:   0x00002000 },
+	{ name: "Config",     offset: 0x00010000, size:   0x00010000 },
+	{ name: "Spare",      offset: 0x00008000, size:   0x00008000 },
+	{ name: "Image",      offset: 0x00020000, size:   0x001e0000 },
+	{ name: "Flash",      offset: 0 }
+};
+
+static struct mtd_partition ml401_4mb[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },
+	{ name: "Bootargs",   offset: 0x00004000, size:   0x00004000 },
+	{ name: "MAC",        offset: 0x00008000, size:   0x00004000 },
+	{ name: "Config",     offset: 0x00010000, size:   0x00010000 },
+	{ name: "Spare",      offset: 0x0000C000, size:   0x00004000 },
+	{ name: "Image",      offset: 0x00100000, size:   0x00300000 },
+	{ name: "JFFS2",      offset: 0x00400000, size:   0x00000000 },
+	{ name: "Flash",     offset: 0 }
+};
+
+static struct mtd_partition ml401_8mb[] = {
+	{ name: "fpga0",      offset: 0x00000000, size:   0x00100000 },
+	{ name: "fpga1",      offset: 0x00100000, size:   0x00100000 },
+	{ name: "Bootloader", offset: 0x00200000, size:   0x00040000 },
+	{ name: "Bootargs",   offset: 0x00240000, size:   0x00040000 },
+	{ name: "MAC",        offset: 0x00280000, size:   0x00040000 },
+	{ name: "Config",     offset: 0x002C0000, size:   0x00080000 },
+	{ name: "Spare",      offset: 0x00340000, size:   0x000C0000 },
+	{ name: "Image",      offset: 0x00400000, size:   0x00300000 },
+	{ name: "JFFS2",      offset: 0x00700000, size:   0x00100000 },
+	{ name: "Flash",      offset: 0 }
+};
+
+/****************************************************************************/
+/*
+ * Find the MTD device with the given name
+ */
+
+static struct mtd_info *get_mtd_named(char *name)
+{
+	int i;
+	struct mtd_info *mtd;
+
+	for (i = 0; i < MAX_MTD_DEVICES; i++) {
+		mtd = get_mtd_device(NULL, i);
+		if (mtd) {
+			if (strcmp(mtd->name, name) == 0)
+				return(mtd);
+			put_mtd_device(mtd);
+		}
+	}
+	return(NULL);
+}
+
+/****************************************************************************/
+#ifdef CONFIG_MTD_CFI_INTELEXT
+/*
+ *	Set the Intel flash back to read mode as MTD may leave it in command mode
+ */
+
+static int ml401_reboot_notifier(
+	struct notifier_block *nb,
+	unsigned long val,
+	void *v)
+{
+	struct cfi_private *cfi = ml401_flash_map.fldrv_priv;
+	int i;
+	
+	for (i = 0; cfi && i < cfi->numchips; i++)
+		cfi_send_gen_cmd(0xff, 0x55, cfi->chips[i].start, &ml401_flash_map,
+				cfi, cfi->device_type, NULL);
+
+	return(NOTIFY_OK);
+}
+
+static struct notifier_block ml401_notifier_block = {
+	ml401_reboot_notifier, NULL, 0
+};
+
+#endif
+
+/****************************************************************************/
+
+static int
+ml401_point(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, u_char **mtdbuf)
+{
+	struct map_info *map = (struct map_info *) mtd->priv;
+	*mtdbuf = (u_char *) (map->map_priv_1 + (int)from);
+	*retlen = len;
+	return(0);
+}
+
+static void
+ml401_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
+{
+}
+
+/****************************************************************************/
+
+static int __init
+ml401_probe(int ram, unsigned long addr, int size, int buswidth)
+{
+	struct mtd_info *mymtd;
+	struct map_info *map_ptr;
+
+	if (ram)
+		map_ptr = &ml401_ram_map;
+	else
+		map_ptr = &ml401_flash_map;
+
+	map_ptr->buswidth = buswidth;
+	map_ptr->map_priv_2 = addr;
+	map_ptr->size = size;
+
+	printk(KERN_NOTICE "MBVanilla %s probe(0x%lx,%d,%d): %lx at %lx\n",
+			ram ? "ram" : "flash",
+			addr, size, buswidth, map_ptr->size, map_ptr->map_priv_2);
+
+	map_ptr->map_priv_1 = (unsigned long)
+			ioremap_nocache(map_ptr->map_priv_2, map_ptr->size);
+
+	if (!map_ptr->map_priv_1) {
+		printk("Failed to ioremap_nocache\n");
+		return -EIO;
+	}
+
+	if (!ram) {
+		mymtd = do_map_probe("cfi_probe", map_ptr);
+		if (!mymtd)
+			mymtd = do_map_probe("jedec_probe", map_ptr);
+	} else
+		mymtd = do_map_probe("map_ram", map_ptr);
+
+	if (!mymtd) {
+		iounmap((void *)map_ptr->map_priv_1);
+		return -ENXIO;
+	}
+		
+	mymtd->module = THIS_MODULE;
+	mymtd->point = ml401_point;
+	mymtd->unpoint = ml401_unpoint;
+	mymtd->priv = map_ptr;
+
+	if (ram) {
+		ram_mtdinfo = mymtd;
+		add_mtd_partitions(mymtd, ml401_romfs, NB_OF(ml401_romfs));
+		return(0);
+	}
+
+	flash_mtdinfo = mymtd;
+	switch (size) {
+	case SIZE_128K:
+		add_mtd_partitions(mymtd, ml401_128k, NB_OF(ml401_128k));
+		break;
+	case SIZE_1MB:
+		add_mtd_partitions(mymtd, ml401_1mb, NB_OF(ml401_1mb));
+		break;
+	case SIZE_2MB:
+		add_mtd_partitions(mymtd, ml401_2mb, NB_OF(ml401_2mb));
+		break;
+	case SIZE_4MB:
+		add_mtd_partitions(mymtd, ml401_4mb, NB_OF(ml401_4mb));
+		break;
+	case SIZE_8MB:
+		add_mtd_partitions(mymtd, ml401_8mb, NB_OF(ml401_8mb));
+		break;
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
+
+int __init ml401_mtd_init(void)
+{
+	int rc = -1;
+	struct mtd_info *mtd;
+	extern char _ebss;
+
+	/*
+	 * I hate this ifdef stuff,  but our HW doesn't always have
+	 * the same chipsize as the map that we use
+	 */
+#if defined(CONFIG_FLASH8MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = ml401_probe(0, FLASH_BASE, SIZE_8MB, BUS_WIDTH);
+#endif
+
+#if defined(CONFIG_FLASH4MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = ml401_probe(0, FLASH_BASE, SIZE_4MB, BUS_WIDTH);
+#endif
+
+#if defined(CONFIG_FLASH2MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = ml401_probe(0, FLASH_BASE, SIZE_2MB, BUS_WIDTH);
+#endif
+
+#if defined(CONFIG_FLASH1MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = ml401_probe(0, FLASH_BASE, SIZE_1MB, BUS_WIDTH);
+#endif
+
+#if defined(CONFIG_FLASH128K) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = ml401_probe(0, FLASH_BASE, SIZE_128K, BUS_WIDTH);
+#endif
+
+	/*
+	 * Map in the filesystem from RAM last so that,  if the filesystem
+	 * is not in RAM for some reason we do not change the minor/major
+	 * for the flash devices
+	 */
+#ifndef CONFIG_SEARCH_ROMFS
+	if (0 != ml401_probe(1, (unsigned long) &_ebss,
+			PAGE_ALIGN(* (unsigned long *)((&_ebss) + 8)),4))
+		printk("Failed to probe RAM filesystem\n");
+#else
+	{
+		unsigned long start_area;
+		unsigned char *sp, *ep;
+		size_t len;
+
+		printk("Probing for ROMFS...\n");
+		start_area = (unsigned long) &_ebss;
+
+		if (strncmp((char *) start_area, "-rom1fs-", 8) != 0) {
+			mtd = get_mtd_named("Image");
+			if (mtd && mtd->point) {
+				if ((*mtd->point)(mtd, 0, mtd->size, &len, &sp) == 0) {
+					ep = sp + len;
+					while (sp < ep && strncmp(sp, "-rom1fs-", 8) != 0)
+						sp++;
+					if (sp < ep)
+						start_area = (unsigned long) sp;
+				}
+			}
+			if (mtd)
+				put_mtd_device(mtd);
+		}
+		if (0 != ml401_probe(1, start_area,
+				PAGE_ALIGN(* (unsigned long *)(start_area + 8)), 4))
+			printk("Failed to probe RAM filesystem\n");
+	}
+#endif	
+	mtd = get_mtd_named("Romfs");
+	if (mtd) {
+		ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+		put_mtd_device(mtd);
+	}
+	return(rc);
+}
+
+/****************************************************************************/
+
+static void __exit ml401_mtd_cleanup(void)
+{
+	if (flash_mtdinfo) {
+		del_mtd_partitions(flash_mtdinfo);
+		map_destroy(flash_mtdinfo);
+		flash_mtdinfo = NULL;
+	}
+	if (ram_mtdinfo) {
+		del_mtd_partitions(ram_mtdinfo);
+		map_destroy(ram_mtdinfo);
+		ram_mtdinfo = NULL;
+	}
+	if (ml401_ram_map.map_priv_1) {
+		iounmap((void *)ml401_ram_map.map_priv_1);
+		ml401_ram_map.map_priv_1 = 0;
+	}
+	if (ml401_flash_map.map_priv_1) {
+		iounmap((void *)ml401_flash_map.map_priv_1);
+		ml401_flash_map.map_priv_1 = 0;
+	}
+}
+
+/****************************************************************************/
+
+module_init(ml401_mtd_init);
+module_exit(ml401_mtd_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Williams <jwilliams@itee.uq.edu.au>");
+MODULE_DESCRIPTION("Microblaze/ML401 Flash support for uClinux");
+
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/mtd/maps/mtdcpu16b.c linux-2.4.29-uc1/drivers/mtd/maps/mtdcpu16b.c
--- linux-2.4.29/drivers/mtd/maps/mtdcpu16b.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/mtdcpu16b.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,156 @@
+/*
+ *
+ * Normal mappings of chips in physical memory
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/config.h>
+
+
+#define WINDOW_ADDR 0xffe00000
+#define WINDOW_SIZE 0x200000
+#define BUSWIDTH 2
+
+extern char* ppcboot_getenv(char* v);
+
+static struct mtd_info *mymtd;
+
+__u8 cpu16b_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 cpu16b_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 cpu16b_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void cpu16b_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void cpu16b_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void cpu16b_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void cpu16b_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void cpu16b_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info cpu16b_map = {
+	name: "SNEHA CPU 16B flash device",
+	size: WINDOW_SIZE,
+	buswidth: BUSWIDTH,
+	read8: cpu16b_read8,
+	read16: cpu16b_read16,
+	read32: cpu16b_read32,
+	copy_from: cpu16b_copy_from,
+	write8: cpu16b_write8,
+	write16: cpu16b_write16,
+	write32: cpu16b_write32,
+	copy_to: cpu16b_copy_to
+};
+
+/*
+ * MTD 'PARTITIONING' STUFF 
+ */
+
+
+static struct mtd_partition cpu16b_partitions[] = {
+        {
+                name: "boot (128K)",
+                size: 0x20000,
+                offset: 0x00000
+        },
+        {
+                name: "kernel (896K)",
+                size: 0xE0000,
+                offset: 0x20000
+        },
+	{
+                name: "jffs2 (1024K)",
+                size: 0x100000,
+                offset: 0x100000
+        }
+};
+
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_cpu16b init_module
+#define cleanup_cpu16b cleanup_module
+#endif
+
+int __init init_cpu16b(void)
+{
+       	printk(KERN_NOTICE "SNEHA CPU 16B flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
+	cpu16b_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+	if (!cpu16b_map.map_priv_1) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}
+	mymtd = do_map_probe("cfi_probe", &cpu16b_map);
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+
+#ifdef CONFIG_PPCBOOT
+                read_cpu16b_partitiontable();
+		if(cpu16b_partitions_cnt) {
+		  return add_mtd_partitions(mymtd, cpu16b_partitions, cpu16b_partitions_cnt);
+		}
+		else {
+		  return  -ENXIO;
+		};
+#else
+		return add_mtd_partitions(mymtd, cpu16b_partitions,
+					  sizeof(cpu16b_partitions) /
+					  sizeof(struct mtd_partition));
+#endif
+	}
+
+	iounmap((void *)cpu16b_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_cpu16b(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+	if (cpu16b_map.map_priv_1) {
+		iounmap((void *)cpu16b_map.map_priv_1);
+		cpu16b_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_cpu16b);
+module_exit(cleanup_cpu16b);
+
diff -urN linux-2.4.29/drivers/mtd/maps/nettel.c linux-2.4.29-uc1/drivers/mtd/maps/nettel.c
--- linux-2.4.29/drivers/mtd/maps/nettel.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/nettel.c	2005-06-14 02:12:08.000000000 +0100
@@ -5,8 +5,6 @@
  *
  *      (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
  *      (C) Copyright 2001-2002, SnapGear (www.snapgear.com)
- *
- *	$Id: nettel.c,v 1.1 2002/08/08 06:30:13 gerg Exp $
  */
 
 /****************************************************************************/
@@ -212,67 +210,16 @@
 	nettel_reboot_notifier, NULL, 0
 };
 
-/*
- *	Erase the configuration file system.
- *	Used to support the software reset button.
- */
-static void nettel_erasecallback(struct erase_info *done)
-{
-	wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
-	wake_up(wait_q);
-}
-
-static struct erase_info nettel_erase;
-
-int nettel_eraseconfig(void)
-{
-	struct mtd_info *mtd;
-	DECLARE_WAITQUEUE(wait, current);
-	wait_queue_head_t wait_q;
-	int ret;
-
-	init_waitqueue_head(&wait_q);
-	mtd = get_mtd_device(NULL, 2);
-	if (mtd) {
-		nettel_erase.mtd = mtd;
-		nettel_erase.callback = nettel_erasecallback;
-		nettel_erase.callback = 0;
-		nettel_erase.addr = 0;
-		nettel_erase.len = mtd->size;
-		nettel_erase.priv = (u_long) &wait_q;
-		nettel_erase.priv = 0;
-
-		set_current_state(TASK_INTERRUPTIBLE);
-		add_wait_queue(&wait_q, &wait);
-
-		ret = MTD_ERASE(mtd, &nettel_erase);
-		if (ret) {
-			set_current_state(TASK_RUNNING);
-			remove_wait_queue(&wait_q, &wait);
-			put_mtd_device(mtd);
-			return(ret);
-		}
-
-		schedule();  /* Wait for erase to finish. */
-		remove_wait_queue(&wait_q, &wait);
-		
-		put_mtd_device(mtd);
-	}
-
-	return(0);
-}
-
-#else
-
-int nettel_eraseconfig(void)
-{
-	return(0);
-}
 
 #endif
 
 /****************************************************************************/
 
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define nettel_init init_module
+#define nettel_cleanup cleanup_module
+#endif
+
 int __init nettel_init(void)
 {
 	volatile unsigned long *amdpar;
diff -urN linux-2.4.29/drivers/mtd/maps/nettel-uc.c linux-2.4.29-uc1/drivers/mtd/maps/nettel-uc.c
--- linux-2.4.29/drivers/mtd/maps/nettel-uc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/nettel-uc.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,583 @@
+/****************************************************************************/
+/*
+ * Flash memory access on uClinux SnapGear like devices
+ * Copyright (C) 2001-2002, David McCullough <davidm@snapgear.com>
+ */
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nftl.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/cfi.h>
+
+#include <linux/fs.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+
+/****************************************************************************/
+
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+#define SIZE_128K	(1  *  128 * 1024)
+#define SIZE_1MB	(1  * 1024 * 1024)
+#define SIZE_2MB	(2  * 1024 * 1024)
+#define SIZE_4MB	(4  * 1024 * 1024)
+#define SIZE_8MB	(8  * 1024 * 1024)
+#define SIZE_16MB	(16 * 1024 * 1024)
+
+#ifdef CONFIG_UCDIMM
+#define FLASH_BASE	0x10c00000
+#define	BUS_WIDTH	2
+#ifdef CONFIG_RAMKERNEL
+#define ROMFS_LOC	((&__rom_start) + ((&_edata) - (&__ram_start)))
+extern char __rom_start, _edata, __ram_start;
+#else
+#define ROMFS_LOC	(&_edata)
+extern char _edata;
+#endif
+#endif
+
+#ifdef CONFIG_COLDFIRE
+#define FLASH_BASE	0xf0000000
+#define	BUS_WIDTH	2
+#endif
+
+#ifdef CONFIG_SUPERH
+#define FLASH_BASE	0x00000000
+#define	BUS_WIDTH	1
+#endif
+
+#ifdef CONFIG_MIPS32
+#define FLASH_BASE	0x1f000000
+#define	BUS_WIDTH	4
+#endif
+
+#ifdef CONFIG_ARCH_IXP425
+#define	FLASH_BASE	0x50000000
+#define	BUS_WIDTH	1
+#endif
+
+#ifndef ROMFS_LOC
+extern char _ebss;
+#define ROMFS_LOC	(&_ebss)
+#endif
+
+/****************************************************************************/
+
+static __u8 nettel_read8(struct map_info *map, unsigned long ofs)
+{
+	return *(__u8 *)(map->map_priv_1 + ofs);
+}
+
+static __u16 nettel_read16(struct map_info *map, unsigned long ofs)
+{
+	return *(__u16 *)(map->map_priv_1 + ofs);
+}
+
+static __u32 nettel_read32(struct map_info *map, unsigned long ofs)
+{
+	return *(__u32 *)(map->map_priv_1 + ofs);
+}
+
+static void nettel_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *)(map->map_priv_1 + from), len);
+}
+
+static void nettel_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*(__u8 *)(map->map_priv_1 + adr) = d;
+}
+
+static void nettel_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*(__u16 *)(map->map_priv_1 + adr) = d;
+}
+
+static void nettel_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*(__u32 *)(map->map_priv_1 + adr) = d;
+}
+
+static void nettel_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy((void *)(map->map_priv_1 + to), from, len);
+}
+
+/****************************************************************************/
+
+static struct map_info nettel_flash_map = {
+	name:		"Flash",
+	read8:		nettel_read8,
+	read16:		nettel_read16,
+	read32:		nettel_read32,
+	copy_from:	nettel_copy_from,
+	write8:		nettel_write8,
+	write16:	nettel_write16,
+	write32:	nettel_write32,
+	copy_to:	nettel_copy_to,
+};
+
+static struct map_info nettel_ram_map = {
+	name:		"RAM",
+	read8:		nettel_read8,
+	read16:		nettel_read16,
+	read32:		nettel_read32,
+	copy_from:	nettel_copy_from,
+	write8:		nettel_write8,
+	write16:	nettel_write16,
+	write32:	nettel_write32,
+	copy_to:	nettel_copy_to,
+};
+
+static struct mtd_info *ram_mtdinfo;
+static struct mtd_info *flash_mtdinfo;
+
+/****************************************************************************/
+
+static struct mtd_partition nettel_romfs[] = {
+	{ name: "Romfs", offset: 0 }
+};
+
+/****************************************************************************/
+/*
+ *	The layout of our flash,  note the order of the names,  this
+ *	means we use the same major/minor for the same purpose on all
+ *	layouts (when possible)
+ */
+
+static struct mtd_partition nettel_128k[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },
+	{ name: "Bootargs",   offset: 0x00004000, size:   0x00004000 },
+	{ name: "MAC",        offset: 0x00008000, size:   0x00004000 },
+	{ name: "Config",     offset: 0x00010000, size:   0x00010000 },
+	{ name: "Spare",      offset: 0x0000c000, size:   0x00004000 },
+	{ name: "Flash",      offset: 0 }
+};
+
+static struct mtd_partition nettel_1mb[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },
+	{ name: "Bootargs",   offset: 0x00004000, size:   0x00002000 },
+	{ name: "MAC",        offset: 0x00006000, size:   0x00002000 },
+	{ name: "Config",     offset: 0x000f0000, size:   0x00010000 },
+	{ name: "Spare",      offset: 0x00008000, size:   0x00008000 },
+	{ name: "Image",      offset: 0x00010000, size:   0x000e0000 },
+	{ name: "Flash",      offset: 0 }
+};
+
+#ifndef CONFIG_UCDIMM
+
+static struct mtd_partition nettel_2mb[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },
+	{ name: "Bootargs",   offset: 0x00004000, size:   0x00002000 },
+	{ name: "MAC",        offset: 0x00006000, size:   0x00002000 },
+	{ name: "Config",     offset: 0x00010000, size:   0x00010000 },
+	{ name: "Spare",      offset: 0x00008000, size:   0x00008000 },
+	{ name: "Image",      offset: 0x00020000, size:   0x001e0000 },
+	{ name: "Flash",      offset: 0 }
+};
+
+#ifdef CONFIG_SH_SECUREEDGE5410
+
+static struct mtd_partition nettel_4mb[] = {
+	{ name: "Boot data",  offset: 0x00000000, size:   0x00020000 },
+	{ name: "Config",     offset: 0x00020000, size:   0x00040000 },
+	{ name: "Image",      offset: 0x00060000, size:   0x00000000 },
+	{ name: "Flash",      offset: 0 }
+};
+
+static struct mtd_partition nettel_8mb[] = {
+	{ name: "Boot data",  offset: 0x00000000, size:   0x00020000 },
+	{ name: "Config",     offset: 0x00020000, size:   0x00080000 },
+	{ name: "Image",      offset: 0x000a0000, size:   0x00000000 },
+	{ name: "Flash",      offset: 0 }
+};
+
+#else
+
+static struct mtd_partition nettel_4mb[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00004000 },
+	{ name: "Bootargs",   offset: 0x00004000, size:   0x00002000 },
+	{ name: "MAC",        offset: 0x00006000, size:   0x00002000 },
+	{ name: "Config",     offset: 0x00010000, size:   0x00010000 },
+	{ name: "Spare",      offset: 0x00008000, size:   0x00008000 },
+	{ name: "Image",      offset: 0x00020000, size:   0x001e0000 },
+	{ name: "Flash",      offset: 0x00000000, size:   0x00200000 },
+	{ name: "Image2",     offset: 0x00220000, size:   0x001e0000 },
+	{ name: "Flash2",     offset: 0 }
+};
+
+static struct mtd_partition nettel_8mb[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00020000 },
+	{ name: "Bootargs",   offset: 0x00020000, size:   0x00020000 },
+	{ name: "MAC",        offset: 0x00040000, size:   0x00020000 },
+	{ name: "Config",     offset: 0x00080000, size:   0x00080000 },
+	{ name: "Spare",      offset: 0x00060000, size:   0x00020000 },
+	{ name: "Image",      offset: 0x00100000, size:   0x00700000 },
+	{ name: "Flash",      offset: 0 }
+};
+
+#endif
+
+#else /* CONFIG_UCDIMM */
+
+static struct mtd_partition nettel_2mb[] = {
+	{ name: "Bootloader", offset: 0x00000000, size:   0x00010000,
+	                                          mask_flags: MTD_WRITEABLE },
+	{ name: "Image",      offset: 0x00010000, size:   0x00190000 },
+	{ name: "Spare",      offset: 0x001a0000, size:   0x00060000 },
+	{ name: "Flash",      offset: 0 }
+};
+
+#define nettel_4mb nettel_2mb
+#define nettel_8mb nettel_2mb
+
+#endif
+
+#ifdef CONFIG_MIPS_VEGAS
+static struct mtd_partition nettel_16mb[] = {
+	{ name: "Bootloader",  offset: 0x00c00000, size:   0x00020000 },
+	{ name: "Bootargs",    offset: 0x00c20000, size:   0x00020000 },
+	{ name: "MAC",         offset: 0x00c40000, size:   0x00020000 },
+	{ name: "Config",      offset: 0x00c60000, size:   0x003a0000 },
+	{ name: "Image",       offset: 0x00000000, size:   0x00c00000 },
+	{ name: "Flash",       offset: 0 }
+};
+#else
+static struct mtd_partition nettel_16mb[] = {
+	{ name: "Boot data",  offset: 0x00000000, size:   0x00020000 },
+	{ name: "Config",     offset: 0x00020000, size:   0x00100000 },
+	{ name: "Image",      offset: 0x00120000, size:   0x00000000 },
+	{ name: "Flash",      offset: 0 }
+};
+#endif
+
+/****************************************************************************/
+/*
+ * Find the MTD device with the given name
+ */
+
+static struct mtd_info *get_mtd_named(char *name)
+{
+	int i;
+	struct mtd_info *mtd;
+
+	for (i = 0; i < MAX_MTD_DEVICES; i++) {
+		mtd = get_mtd_device(NULL, i);
+		if (mtd) {
+			if (strcmp(mtd->name, name) == 0)
+				return(mtd);
+			put_mtd_device(mtd);
+		}
+	}
+	return(NULL);
+}
+
+/****************************************************************************/
+#ifdef CONFIG_MTD_CFI_INTELEXT
+/*
+ *	Set the Intel flash back to read mode as MTD may leave it in command mode
+ */
+
+static int nettel_reboot_notifier(
+	struct notifier_block *nb,
+	unsigned long val,
+	void *v)
+{
+	struct cfi_private *cfi = nettel_flash_map.fldrv_priv;
+	int i;
+	
+	for (i = 0; cfi && i < cfi->numchips; i++)
+		cfi_send_gen_cmd(0xff, 0x55, cfi->chips[i].start, &nettel_flash_map,
+				cfi, cfi->device_type, NULL);
+
+	return(NOTIFY_OK);
+}
+
+static struct notifier_block nettel_notifier_block = {
+	nettel_reboot_notifier, NULL, 0
+};
+
+#endif
+
+/****************************************************************************/
+
+static int
+nettel_point(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, u_char **mtdbuf)
+{
+	struct map_info *map = (struct map_info *) mtd->priv;
+	*mtdbuf = (u_char *) (map->map_priv_1 + (int)from);
+	*retlen = len;
+	return(0);
+}
+
+static void
+nettel_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
+{
+}
+
+/****************************************************************************/
+
+static int __init
+nettel_probe(int ram, unsigned long addr, int size, int buswidth)
+{
+	struct mtd_info *mymtd;
+	struct map_info *map_ptr;
+
+	if (ram)
+		map_ptr = &nettel_ram_map;
+	else
+		map_ptr = &nettel_flash_map;
+
+	map_ptr->buswidth = buswidth;
+	map_ptr->map_priv_2 = addr;
+	map_ptr->size = size;
+
+	printk(KERN_NOTICE "SnapGear %s probe(0x%lx,%d,%d): %lx at %lx\n",
+			ram ? "ram" : "flash",
+			addr, size, buswidth, map_ptr->size, map_ptr->map_priv_2);
+
+	if (ram)
+		map_ptr->map_priv_1 = addr;
+	else
+		map_ptr->map_priv_1 = (unsigned long) ioremap_nocache(map_ptr->map_priv_2, map_ptr->size);
+
+	if (!map_ptr->map_priv_1) {
+		printk("Failed to ioremap_nocache\n");
+		return -EIO;
+	}
+
+	if (!ram) {
+		mymtd = do_map_probe("cfi_probe", map_ptr);
+		if (!mymtd)
+			mymtd = do_map_probe("jedec_probe", map_ptr);
+		if (mymtd == NULL || mymtd->size < size)
+			return -ENODEV;
+	} else
+		mymtd = do_map_probe("map_ram", map_ptr);
+
+	if (!mymtd) {
+		iounmap((void *)map_ptr->map_priv_1);
+		return -ENXIO;
+	}
+		
+	mymtd->module  = THIS_MODULE;
+	mymtd->point   = nettel_point;
+	mymtd->unpoint = nettel_unpoint;
+	mymtd->priv    = map_ptr;
+
+	if (ram) {
+		ram_mtdinfo = mymtd;
+		add_mtd_partitions(mymtd, nettel_romfs, NB_OF(nettel_romfs));
+		return(0);
+	}
+
+	flash_mtdinfo = mymtd;
+	switch (size) {
+	case SIZE_128K:
+		add_mtd_partitions(mymtd, nettel_128k, NB_OF(nettel_128k));
+		break;
+	case SIZE_1MB:
+		add_mtd_partitions(mymtd, nettel_1mb, NB_OF(nettel_1mb));
+		break;
+	case SIZE_2MB:
+		add_mtd_partitions(mymtd, nettel_2mb, NB_OF(nettel_2mb));
+		break;
+	case SIZE_4MB:
+		add_mtd_partitions(mymtd, nettel_4mb, NB_OF(nettel_4mb));
+		break;
+	case SIZE_8MB:
+		add_mtd_partitions(mymtd, nettel_8mb, NB_OF(nettel_8mb));
+		break;
+	case SIZE_16MB:
+		add_mtd_partitions(mymtd, nettel_16mb, NB_OF(nettel_16mb));
+		break;
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
+
+int __init nettel_mtd_init(void)
+{
+	int rc = -1;
+	struct mtd_info *mtd;
+
+	/*
+	 * I hate this ifdef stuff,  but our HW doesn't always have
+	 * the same chipsize as the map that we use
+	 */
+#if defined(CONFIG_FLASH16MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = nettel_probe(0, FLASH_BASE, SIZE_16MB, BUS_WIDTH);
+#endif
+
+#if defined(CONFIG_FLASH8MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = nettel_probe(0, FLASH_BASE, SIZE_8MB, BUS_WIDTH);
+#endif
+
+#if defined(CONFIG_FLASH4MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = nettel_probe(0, FLASH_BASE, SIZE_4MB, BUS_WIDTH);
+#endif
+
+#if defined(CONFIG_FLASH2MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = nettel_probe(0, FLASH_BASE, SIZE_2MB, BUS_WIDTH);
+#endif
+
+#if defined(CONFIG_FLASH1MB) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = nettel_probe(0, FLASH_BASE, SIZE_1MB, BUS_WIDTH);
+#endif
+
+#if defined(CONFIG_FLASH128K) || defined(CONFIG_FLASHAUTO)
+	if (rc != 0)
+		rc = nettel_probe(0, FLASH_BASE, SIZE_128K, BUS_WIDTH);
+#endif
+
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_UCDIMM)
+	/*
+	 * Map in the filesystem from RAM last so that,  if the filesystem
+	 * is not in RAM for some reason we do not change the minor/major
+	 * for the flash devices
+	 */
+#ifndef CONFIG_ROMFS_FROM_ROM
+	if (0 != nettel_probe(1, (unsigned long) ROMFS_LOC,
+			PAGE_ALIGN(* (unsigned long *)(ROMFS_LOC + 8)), 4))
+		printk("Failed to probe RAM filesystem\n");
+#else
+	{
+		unsigned long start_area;
+		unsigned char *sp, *ep;
+
+		size_t len;
+
+		start_area = (unsigned long) ROMFS_LOC;
+
+		if (strncmp((char *) start_area, "-rom1fs-", 8) != 0) {
+			mtd = get_mtd_named("Image");
+			if (mtd && mtd->point) {
+				if ((*mtd->point)(mtd, 0, mtd->size, &len, &sp) == 0) {
+					ep = sp + len;
+					while (sp < ep && strncmp(sp, "-rom1fs-", 8) != 0)
+						sp++;
+					if (sp < ep)
+						start_area = (unsigned long) sp;
+				}
+			}
+			if (mtd)
+				put_mtd_device(mtd);
+		}
+		if (0 != nettel_probe(1, start_area,
+				PAGE_ALIGN(* (unsigned long *)(start_area + 8)), 4))
+			printk("Failed to probe RAM filesystem\n");
+	}
+#endif
+	
+	mtd = get_mtd_named("Romfs");
+	if (mtd) {
+		ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+		put_mtd_device(mtd);
+	}
+#endif
+
+#if defined(CONFIG_SH_SECUREEDGE5410) || defined(CONFIG_MIPS_VEGAS) || defined(CONFIG_MACH_ESS710)
+{
+	extern int _end;
+	unsigned long magic;
+	unsigned char *cp = (char *) &_end;
+
+	memcpy(&magic, cp, sizeof(magic));
+	if (memcmp(cp, "-rom1fs-", 8) == 0) {
+#ifndef CONFIG_BLK_DEV_INITRD
+		/* romfs */ ;
+		nettel_probe(1, (unsigned long) cp,
+				PAGE_ALIGN(* (unsigned long *)(cp + 8)), 4);
+		mtd = get_mtd_named("Romfs");
+		if (mtd) {
+			ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+			put_mtd_device(mtd);
+		} else
+			printk("%s: Failed to find & make romfs root filesystem\n",
+					__FUNCTION__);
+#endif
+	} else if (magic == 0x28cd3d45) {
+#ifndef CONFIG_BLK_DEV_INITRD
+		/* cramfs */ ;
+		nettel_probe(1, (unsigned long) cp,
+				PAGE_ALIGN(* (unsigned long *)(cp + 4)), 4);
+		mtd = get_mtd_named("Romfs");
+		if (mtd) {
+			ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+			put_mtd_device(mtd);
+		} else
+			printk("%s: Failed to find & make cramfs root filesystem\n",
+					__FUNCTION__);
+#endif
+	} else {
+		mtd = get_mtd_named("Image");
+		if (mtd) {
+			ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+			put_mtd_device(mtd);
+		}
+#if defined(CONFIG_NFTL) || defined(CONFIG_INFTL)
+		else
+			ROOT_DEV = MKDEV(NFTL_MAJOR, 1);
+#endif
+	}
+}
+#endif
+
+#ifdef CONFIG_MTD_CFI_INTELEXT
+	register_reboot_notifier(&nettel_notifier_block);
+#endif
+
+	return(rc);
+}
+
+/****************************************************************************/
+
+static void __exit nettel_mtd_cleanup(void)
+{
+	if (flash_mtdinfo) {
+		del_mtd_partitions(flash_mtdinfo);
+		map_destroy(flash_mtdinfo);
+		flash_mtdinfo = NULL;
+	}
+	if (ram_mtdinfo) {
+		del_mtd_partitions(ram_mtdinfo);
+		map_destroy(ram_mtdinfo);
+		ram_mtdinfo = NULL;
+	}
+	if (nettel_ram_map.map_priv_1) {
+		iounmap((void *)nettel_ram_map.map_priv_1);
+		nettel_ram_map.map_priv_1 = 0;
+	}
+	if (nettel_flash_map.map_priv_1) {
+		iounmap((void *)nettel_flash_map.map_priv_1);
+		nettel_flash_map.map_priv_1 = 0;
+	}
+}
+
+/****************************************************************************/
+
+module_init(nettel_mtd_init);
+module_exit(nettel_mtd_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David McCullough <davidm@snapgear.com>");
+MODULE_DESCRIPTION("SnapGear/SecureEdge FLASH support for uClinux");
+
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/mtd/maps/ocelot.c linux-2.4.29-uc1/drivers/mtd/maps/ocelot.c
--- linux-2.4.29/drivers/mtd/maps/ocelot.c	2001-10-04 23:14:59.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/ocelot.c	2005-06-14 02:12:08.000000000 +0100
@@ -20,7 +20,7 @@
 #define NVRAM_WINDOW_SIZE 0x00007FF0
 #define NVRAM_BUSWIDTH 1
 
-extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts, unsigned long fis_origin);
 
 static unsigned int cacheflush = 0;
 
@@ -156,7 +156,7 @@
 	add_mtd_device(nvram_mtd);
 
 	flash_mtd->module = THIS_MODULE;
-	nr_parts = parse_redboot_partitions(flash_mtd, &parsed_parts);
+	nr_parts = parse_redboot_partitions(flash_mtd, &parsed_parts, 0);
 
 	if (nr_parts)
 		add_mtd_partitions(flash_mtd, parsed_parts, nr_parts);
diff -urN linux-2.4.29/drivers/mtd/maps/physmap.c linux-2.4.29-uc1/drivers/mtd/maps/physmap.c
--- linux-2.4.29/drivers/mtd/maps/physmap.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/physmap.c	2005-06-14 02:12:08.000000000 +0100
@@ -119,6 +119,12 @@
 {
 	static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", 0 };
 	const char **type;
+#ifdef CONFIG_MTD_PARTITIONS
+	int nb_parts = 0, parsed_nr_parts = 0;
+	struct mtd_partition *parts;
+	const char *part_type;
+	static struct mtd_partition *parsed_parts;
+#endif
 
        	printk(KERN_NOTICE "physmap flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
 	physmap_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
@@ -147,6 +153,14 @@
 			       "Using command line partition definition\n");
 			add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb);
 		}
+
+		if (parsed_nr_parts == 0) {
+			int ret = parse_cmdline_partitions(mymtd, &parsed_parts, "physmap");
+			if (ret > 0) {
+				part_type = "Command Line";
+				parsed_nr_parts = ret;
+			}
+		}
 #else
 		if (NUM_PARTITIONS != 0) 
 		{
@@ -154,9 +168,24 @@
 			       "Using physmap partition definition\n");
 			add_mtd_partitions (mymtd, physmap_partitions, NUM_PARTITIONS);
 		}
+#endif /* CONFIG_MTD_CMDLINE_PARTS */
+
+		if (parsed_nr_parts > 0) {
+			parts = parsed_parts;
+			nb_parts = parsed_nr_parts;
+		}
+
+		if (nb_parts == 0) {
+			printk(KERN_NOTICE "physmap: no partition info available, "
+					"registering whole flash at once\n");
+			add_mtd_device(mymtd);
+		} else {
+			printk(KERN_NOTICE "physmap: Using %s partition definition\n",
+					part_type);
+			add_mtd_partitions(mymtd, parts, nb_parts);
+		}
+#endif /* CONFIG_MTD_PARTITIONS */
 
-#endif
-#endif
 		return 0;
 	}
 
diff -urN linux-2.4.29/drivers/mtd/maps/sa1100-flash.c linux-2.4.29-uc1/drivers/mtd/maps/sa1100-flash.c
--- linux-2.4.29/drivers/mtd/maps/sa1100-flash.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/sa1100-flash.c	2005-06-14 02:12:08.000000000 +0100
@@ -765,8 +765,8 @@
 };
 #endif
 
-extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
-extern int parse_bootldr_partitions(struct mtd_info *master, struct mtd_partition **pparts);
+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts, unsigned long fis_origin);
+extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts);
 
 static struct mtd_partition *parsed_parts;
 static struct mtd_info *mymtd;
@@ -964,7 +964,7 @@
 	 */
 #ifdef CONFIG_MTD_REDBOOT_PARTS
 	if (parsed_nr_parts == 0) {
-		int ret = parse_redboot_partitions(mymtd, &parsed_parts);
+		int ret = parse_redboot_partitions(mymtd, &parsed_parts, 0);
 
 		if (ret > 0) {
 			part_type = "RedBoot";
diff -urN linux-2.4.29/drivers/mtd/maps/se4000.c linux-2.4.29-uc1/drivers/mtd/maps/se4000.c
--- linux-2.4.29/drivers/mtd/maps/se4000.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/se4000.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,176 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/notifier.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/cfi.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+
+#define WINDOW_ADDR 	0x50000000
+#define BUSWIDTH 	2
+#define WINDOW_SIZE	0x01000000
+
+#ifndef __ARMEB__
+#define	B0(h)	((h) & 0xFF)
+#define	B1(h)	(((h) >> 8) & 0xFF)
+#else
+#define	B0(h)	(((h) >> 8) & 0xFF)
+#define	B1(h)	((h) & 0xFF)
+#endif
+
+static __u16 se4000_read16(struct map_info *map, unsigned long ofs)
+{
+    return *(__u16 *)(map->map_priv_1 + ofs);
+}
+
+/*
+ * The IXP425 expansion bus only allows 16-bit wide acceses
+ * when attached to a 16-bit wide device (such as the 28F128J3A),
+ * so we can't use a memcpy_fromio as it does byte acceses.
+ */
+static void se4000_copy_from(struct map_info *map, void *to,
+    unsigned long from, ssize_t len)
+{
+	int i;
+	u8 *dest = (u8*)to;
+	u16 *src = (u16 *)(map->map_priv_1 + from);
+	u16 data;
+
+	for (i = 0; i < (len / 2); i++) {
+		data = src[i];
+		dest[i * 2] = B0(data);
+		dest[i * 2 + 1] = B1(data);
+	}
+
+	if (len & 1)
+		dest[len - 1] = B0(src[i]);
+}
+
+static void se4000_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+    *(__u16 *)(map->map_priv_1 + adr) = d;
+}
+
+static struct map_info se4000_map = {
+	name: 		"SnapGear SE4000 Flash",
+	buswidth: 	BUSWIDTH,
+	read16:		se4000_read16,
+	copy_from:	se4000_copy_from,
+	write16:	se4000_write16,
+};
+
+static struct mtd_partition *parsed_parts;
+
+#ifdef CONFIG_MTD_CFI_INTELEXT
+/*
+ * Set the Intel flash back to read mode as MTD may leave it in command mode
+ */
+
+static int se4000_reboot_notifier(
+	struct notifier_block *nb,
+	unsigned long val,
+	void *v)
+{
+	struct cfi_private *cfi = se4000_map.fldrv_priv;
+	int i;
+	
+	for (i = 0; cfi && i < cfi->numchips; i++)
+		cfi_send_gen_cmd(0xff, 0x55, cfi->chips[i].start, &se4000_map,
+			cfi, cfi->device_type, NULL);
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block se4000_notifier_block = {
+	se4000_reboot_notifier, NULL, 0
+};
+
+#endif
+
+
+static struct mtd_info *se4000_mtd;
+static struct resource *mtd_resource;
+
+static void se4000_exit(void)
+{
+    if (se4000_mtd) {
+	del_mtd_partitions(se4000_mtd);
+	map_destroy(se4000_mtd);
+    }
+    if (se4000_map.map_priv_1)
+	iounmap((void *)se4000_map.map_priv_1);
+    if (mtd_resource)
+	release_mem_region(WINDOW_ADDR, WINDOW_SIZE);
+  
+    if (parsed_parts)
+	kfree(parsed_parts);
+
+    /* Disable flash write */
+    *IXP425_EXP_CS0 &= ~IXP425_FLASH_WRITABLE;
+}
+
+static int __init se4000_init(void)
+{
+    int res, npart;
+
+    /* Enable flash write */
+    *IXP425_EXP_CS0 |= IXP425_FLASH_WRITABLE;
+
+    se4000_map.map_priv_1 = 0;
+    mtd_resource = request_mem_region(WINDOW_ADDR, WINDOW_SIZE, "SnapGear SE4000");
+    if (!mtd_resource) {
+	printk(KERN_ERR "SE4000: request_mem_region() failed\n" );
+	res = -ENOMEM;
+	goto Error;
+    }
+
+    se4000_map.map_priv_1 = (unsigned long) ioremap(WINDOW_ADDR, WINDOW_SIZE);
+    if (!se4000_map.map_priv_1) {
+	printk(KERN_ERR "SE4000: ioremap() failed\n");
+	res = -EIO;
+	goto Error;
+    }
+    se4000_map.size = WINDOW_SIZE;
+
+    /* 
+     * Probe for the CFI complaint chip
+     * suposed to be 28F128J3A
+     */
+    se4000_mtd = do_map_probe("cfi_probe", &se4000_map);
+    if (!se4000_mtd) {
+	res = -ENXIO;
+	goto Error;
+    }
+    se4000_mtd->module = THIS_MODULE;
+   
+    /* Try to parse RedBoot partitions */
+    npart = parse_redboot_partitions(se4000_mtd, &parsed_parts, 0);
+    if (npart > 0) {
+	/* found "npart" RedBoot partitions */
+	res = add_mtd_partitions(se4000_mtd, parsed_parts, npart);
+    } else {
+	res = -EIO;
+    }
+
+    if (res)
+	goto Error;
+
+#ifdef CONFIG_MTD_CFI_INTELEXT
+	register_reboot_notifier(&se4000_notifier_block);
+#endif
+
+    return res;
+Error:
+    se4000_exit();
+    return res;
+}
+
+module_init(se4000_init);
+module_exit(se4000_exit);
+
+MODULE_DESCRIPTION("MTD map driver for SnapGear SE4000");
+
diff -urN linux-2.4.29/drivers/mtd/maps/sedsios.c linux-2.4.29-uc1/drivers/mtd/maps/sedsios.c
--- linux-2.4.29/drivers/mtd/maps/sedsios.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/sedsios.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,257 @@
+/****************************************************************************/
+/*
+ * Flash memory access on uClinux SIOS III like devices
+ * Copyright (C) 2001-2002, David McCullough <davidm@snapgear.com>
+ * Copyright (C) 2004, SED Systems <hamilton@sedsystems.ca>
+ */
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nftl.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/cfi.h>
+
+#include <linux/fs.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+/****************************************************************************/
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+#define SIZE_128K	(1  *  128 * 1024)
+#define SIZE_1MB	(1  * 1024 * 1024)
+#define SIZE_2MB	(2  * 1024 * 1024)
+#define SIZE_4MB	(4  * 1024 * 1024)
+#define SIZE_8MB	(8  * 1024 * 1024)
+#define SIZE_16MB	(16 * 1024 * 1024)
+
+#define FLASH_BASE	0x7fc00000
+#define	BUS_WIDTH	2
+/****************************************************************************/
+
+static __u8 sedcfc_read8(struct map_info *map, unsigned long ofs)
+{
+	return *(__u8 *)(map->map_priv_1 + ofs);
+}
+
+static __u16 sedcfc_read16(struct map_info *map, unsigned long ofs)
+{
+	return *(__u16 *)(map->map_priv_1 + ofs);
+}
+
+static __u32 sedcfc_read32(struct map_info *map, unsigned long ofs)
+{
+	return *(__u32 *)(map->map_priv_1 + ofs);
+}
+
+static void sedcfc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *)(map->map_priv_1 + from), len);
+}
+
+static void sedcfc_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*(__u8 *)(map->map_priv_1 + adr) = d;
+}
+
+static void sedcfc_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*(__u16 *)(map->map_priv_1 + adr) = d;
+}
+
+static void sedcfc_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*(__u32 *)(map->map_priv_1 + adr) = d;
+}
+
+static void sedcfc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy((void *)(map->map_priv_1 + to), from, len);
+}
+
+/****************************************************************************/
+
+static struct map_info sedcfc_flash_map =
+{
+	name:		"Flash",
+	read8:		sedcfc_read8,
+	read16:		sedcfc_read16,
+	read32:		sedcfc_read32,
+	copy_from:	sedcfc_copy_from,
+	write8:		sedcfc_write8,
+	write16:	sedcfc_write16,
+	write32:	sedcfc_write32,
+	copy_to:	sedcfc_copy_to,
+};
+
+static struct mtd_info *flash_mtdinfo;
+
+/****************************************************************************/
+/*
+ *	The layout of our flash,  note the order of the names,  this
+ *	means we use the same major/minor for the same purpose on all
+ *	layouts (when possible)
+ */
+static struct mtd_partition sedcfc_4mb[] =
+{
+	{ name: "Colilo",     offset: 0x00000000, size:   0x00010000 },
+	{ name: "Kernel",     offset: 0x00010000, size:   0x00070000 },
+	{ name: "RootFS",     offset: 0x00080000, size:   0x00180000 },
+	{ name: "SEDFS",      offset: 0x00200000, size:   0x00200000 }
+};
+
+/****************************************************************************/
+/*
+ * Find the MTD device with the given name
+ */
+
+static struct mtd_info *get_mtd_named(char *name)
+{
+	int i;
+	struct mtd_info *mtd;
+
+	for (i = 0; i < MAX_MTD_DEVICES; i++)
+	{
+		mtd = get_mtd_device(NULL, i);
+		if (mtd)
+		{
+			if (strcmp(mtd->name, name) == 0)
+				return(mtd);
+			put_mtd_device(mtd);
+		}
+	}
+	return(NULL);
+}
+
+/****************************************************************************/
+static int sedcfc_point(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, u_char **mtdbuf)
+{
+	struct map_info *map = (struct map_info *) mtd->priv;
+	*mtdbuf = (u_char *) (map->map_priv_1 + (int)from);
+	*retlen = len;
+	return(0);
+}
+/****************************************************************************/
+static void
+sedcfc_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
+{
+}
+/****************************************************************************/
+static int __init
+sedcfc_probe(int ram, unsigned long addr, int size, int buswidth)
+{
+	struct mtd_info *mymtd;
+	struct map_info *map_ptr;
+	struct mtd_info *mtd;
+
+	map_ptr = &sedcfc_flash_map;
+
+	map_ptr->buswidth = buswidth;
+	map_ptr->map_priv_2 = addr;
+	map_ptr->size = size;
+
+	printk(KERN_NOTICE "SED SIOS III Core flash probe(0x%lx,%d,%d): %lx at %lx\n",
+			addr, size, buswidth, map_ptr->size,
+			map_ptr->map_priv_2);
+
+	map_ptr->map_priv_1 = (unsigned long)
+		ioremap_nocache(map_ptr->map_priv_2, map_ptr->size);
+
+	if (!map_ptr->map_priv_1)
+	{
+		printk("Failed to ioremap_nocache\n");
+		return -EIO;
+	}
+
+	mymtd = do_map_probe("amd_flash", map_ptr);
+
+	if(!mymtd)
+	{
+		printk("Failed to find device doing amd_flash,"
+				" trying cfi_probe\n");
+		mymtd = do_map_probe("cfi_probe", map_ptr);
+	}
+
+	if (!mymtd)
+	{
+		printk("Failed to find device doing cfi_probe\n");
+		iounmap((void *)map_ptr->map_priv_1);
+		return -ENXIO;
+	}
+
+	mymtd->module  = THIS_MODULE;
+	mymtd->point   = sedcfc_point;
+	mymtd->unpoint = sedcfc_unpoint;
+	mymtd->priv    = map_ptr;
+
+	flash_mtdinfo = mymtd;
+	switch (size)
+	{
+		case SIZE_4MB:
+			add_mtd_partitions(mymtd, sedcfc_4mb,
+					NB_OF(sedcfc_4mb));
+			break;
+	}
+	mtd = get_mtd_named("RootFS");
+	if (mtd)
+	{
+		ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+		put_mtd_device(mtd);
+	}
+	else
+	{
+		printk("Root device not set\n");
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
+
+int __init sedcfc_mtd_init(void)
+{
+	int rc = -1;
+	struct mtd_info *mtd;
+
+	printk(KERN_NOTICE "Initializing flash devices for filesystems\n");
+
+	rc = sedcfc_probe(0, FLASH_BASE, SIZE_4MB, BUS_WIDTH);
+	
+	mtd = get_mtd_named("RootFS");
+	if (mtd)
+	{
+		ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+		put_mtd_device(mtd);
+	}
+	return(rc);
+}
+/****************************************************************************/
+static void __exit sedcfc_mtd_cleanup(void)
+{
+	if (flash_mtdinfo)
+	{
+		del_mtd_partitions(flash_mtdinfo);
+		map_destroy(flash_mtdinfo);
+		flash_mtdinfo = NULL;
+	}
+	if (sedcfc_flash_map.map_priv_1)
+	{
+		iounmap((void *)sedcfc_flash_map.map_priv_1);
+		sedcfc_flash_map.map_priv_1 = 0;
+	}
+}
+/****************************************************************************/
+module_init(sedcfc_mtd_init);
+module_exit(sedcfc_mtd_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David McCullough <davidm@snapgear.com>");
+MODULE_DESCRIPTION("SED SIOS III Flash support for uClinux");
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/mtd/maps/snaparm.c linux-2.4.29-uc1/drivers/mtd/maps/snaparm.c
--- linux-2.4.29/drivers/mtd/maps/snaparm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/snaparm.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,552 @@
+/****************************************************************************/
+
+/*
+ *      snaparm.c -- mappings for SnapGear ARM based boards
+ *
+ *      (C) Copyright 2000-2005, Greg Ungerer (gerg@snapgear.com)
+ *      (C) Copyright 2001-2005, SnapGear (www.snapgear.com)
+ *
+ *	I expect most SnapGear ARM based boards will have similar
+ *	flash arrangements. So this map driver can handle them all.
+ */
+
+/****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/blk.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/cfi.h>
+#include <linux/reboot.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+
+/****************************************************************************/
+
+static struct mtd_info *sg_mtd;
+static struct resource *sg_res;
+
+/****************************************************************************/
+
+/*
+ *	Define physical addresss flash is mapped at. Will be different on
+ *	different boards.
+ */
+#if defined(CONFIG_ARCH_SE4000) || defined(CONFIG_MACH_IVPN) || \
+    defined(CONFIG_MACH_SG560) || defined(CONFIG_MACH_SG580)
+#define	FLASH_ADDR	0x50000000		/* Physical flash address */
+#define	FLASH_SIZE	0x01000000		/* Maximum flash size */
+#define	FLASH_WIDTH	2			/* Flash bus width */
+
+#if defined(CONFIG_MACH_SG560)
+#define CONFIG_SIZE	0x80000
+#elif defined(CONFIG_MACH_SG580)
+#define CONFIG_SIZE	0x100000
+#else
+#define CONFIG_SIZE	0x20000
+#endif
+
+#endif
+
+#if defined(CONFIG_MACH_SG565) || defined(CONFIG_MACH_SHIVA1100)
+#define	FLASH_ADDR	0x50000000		/* Physical flash address */
+#define	FLASH_SIZE	0x01000000		/* Maximum flash size */
+#define	FLASH_WIDTH	1			/* Flash bus width */
+
+#if defined(CONFIG_MACH_SG565)
+#define CONFIG_SIZE	0x100000
+#else
+#define CONFIG_SIZE	0x20000
+#endif
+
+#endif
+
+#if defined(CONFIG_MACH_LITE300)
+#define	FLASH_ADDR	0x02000000		/* Physical flash address */
+#define	FLASH_SIZE	0x00800000		/* Maximum flash size */
+#define	FLASH_WIDTH	1			/* Flash bus width */
+#define CONFIG_SIZE	0x20000
+#endif
+
+#if defined(CONFIG_MACH_CM4008)
+#define	FLASH_ADDR	0x02000000		/* Physical flash address */
+#define	FLASH_SIZE	0x00800000		/* Maximum flash size */
+#define	FLASH_WIDTH	1			/* Flash bus width */
+#endif
+
+#if defined(CONFIG_MACH_CM41xx)
+#define	FLASH_ADDR	0x02000000		/* Physical flash address */
+#define	FLASH_SIZE	0x01000000		/* Maximum flash size */
+#define	FLASH_WIDTH	1			/* Flash bus width */
+#endif
+
+#if defined(CONFIG_MACH_EP9312)
+#define	FLASH_ADDR	0x60000000		/* Physical flash address */
+#define	FLASH_SIZE	0x00800000		/* Maximum flash size */
+#define	FLASH_WIDTH	2			/* Flash bus width */
+#define CONFIG_SIZE	0x20000
+#endif
+
+#if defined(CONFIG_MACH_IPD)
+#define	FLASH_ADDR	0x00000000		/* Physical flash address */
+#define	FLASH_SIZE	0x01000000		/* Maximum flash size */
+#define	FLASH_WIDTH	2			/* Flash bus width */
+#endif
+
+/****************************************************************************/
+
+//#define SNAPARM_DEBUG 1
+#if SNAPARM_DEBUG
+#define DPRINTK printk
+#else
+#define DPRINTK(...)
+#endif
+
+/****************************************************************************/
+
+/*
+ *	Define some access helper macros. On different architectures
+ *	we have to deal with multi-byte quanitites, read/write buffers,
+ *	and other architectural details a little differently. These
+ *	macros try to abstract that as much as possible to keep the
+ *	code clean.
+ */
+
+#if CONFIG_ARCH_KS8695
+/*
+ *	The bus read and write buffers can potenitially coalesce read and
+ *	write bus cycles to the same address, thus dropping real cycles
+ *	when talking to IO type devices. We need to flush those	buffers 
+ *	when doing flash reading/writing.
+ *
+ *	Walk through a small section of memory avoiding the cache so that we
+ *	can keep the flash running smoothly. Using the write buffer enable
+ *	disable seems tocause nasty bus junk, sodon't use them.
+ */
+static void invalidate_buffer(void)
+{
+	static int z = 0;
+	*((volatile unsigned int *) (0xc0010000 + (z++ & 0xffff)));
+}
+#define	readpreflush(x)		invalidate_buffer()
+#define	writepreflush(x)	invalidate_buffer()
+
+#define	CONFIG_LOCK_MULTIBYTE
+#define	initlock()		unsigned long flags
+#define	getlock()		save_flags(flags); cli()
+#define	releaselock()		restore_flags(flags)
+#endif	/* CONFIG_ARCH_KS8695 */
+
+
+/*
+ *	We are not entirely sure why, but on the iVPN the timing _between_
+ *	access to the flash causes problems with other bus activity on the
+ *	expansion bus. Namely the CompactFlash WiFi card. Delaying 1us
+ *	is enough to clean up the cycles.
+ */
+#if CONFIG_MACH_IVPN
+#define	readpreflush(x)		udelay(1)
+#define	readpostflush(x)	udelay(1)
+#define	writepreflush(x)	udelay(1)
+#define	writepostflush(x)	udelay(1)
+
+#define	CONFIG_LOCK_MULTIBYTE
+#define	initlock()		unsigned long flags
+#define	getlock()		save_flags(flags); cli()
+#define	releaselock()		restore_flags(flags)
+#endif	/* CONFIG_MACH_IVPN */
+
+
+/*
+ *	Now default any macros that are not used.
+ */
+#ifndef readpreflush
+#define	readpreflush(x)
+#endif
+#ifndef readpostflush
+#define	readpostflush(x)
+#endif
+#ifndef writepreflush
+#define	writepreflush(x)
+#endif
+#ifndef writepostflush
+#define	writepostflush(x)
+#endif
+#ifndef initlock()
+#define	initlock()
+#endif
+#ifndef getlock()
+#define	getlock()
+#endif
+#ifndef releaselock()
+#define	releaselock()
+#endif
+
+/****************************************************************************/
+
+static __u8 sg_read8(struct map_info *map, unsigned long ofs)
+{
+	__u8 res;
+	readpreflush(map->map_priv_1 + ofs);
+	res = readb(map->map_priv_1 + ofs);
+	readpostflush(map->map_priv_1 + ofs);
+	DPRINTK("%s(0x%x) = 0x%x\n", __FUNCTION__, (__u32)ofs, (__u32)res);
+	return(res);
+}
+
+static __u16 sg_read16(struct map_info *map, unsigned long ofs)
+{
+	__u16 res;
+	readpreflush(map->map_priv_1 + ofs);
+	res = readw(map->map_priv_1 + ofs);
+	readpostflush(map->map_priv_1 + ofs);
+	DPRINTK("%s(0x%x) = 0x%x\n", __FUNCTION__, (__u32)ofs, (__u32)res);
+	return(res);
+}
+
+static __u32 sg_read32(struct map_info *map, unsigned long ofs)
+{
+	__u32 res;
+	initlock();
+
+	readpreflush(map->map_priv_1 + ofs);
+	getlock();
+	res = readl(map->map_priv_1 + ofs);
+	releaselock();
+	readpostflush(map->map_priv_1 + ofs);
+	DPRINTK("%s(0x%x) = 0x%x\n", __FUNCTION__, (__u32)ofs, (__u32)res);
+	return(res);
+}
+
+static void sg_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	DPRINTK("%s(to=0x%x, from=0x%x, len=%d)\n", __FUNCTION__,
+		(__u32)to, (__u32)from, (__u32)len);
+
+#ifdef CONFIG_LOCK_MULTIBYTE
+{
+	unsigned short *dst;
+	unsigned int i;
+	initlock();
+
+	getlock();
+	for (dst = to, i = 0; (i < len); i += 2) {
+		readpreflush(map->map_priv_1 + from + i);
+		*dst++ = readw(map->map_priv_1 + from + i);
+		readpostflush(map->map_priv_1 + from + i);
+	}
+	releaselock();
+}
+#else
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+#endif
+}
+
+static void sg_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	DPRINTK("%s(0x%x,0x%x)\n", __FUNCTION__, (__u32)d, (__u32)adr);
+	writepreflush(map->map_priv_1 + adr);
+	writeb(d, map->map_priv_1 + adr);
+	writepostflush(map->map_priv_1 + adr);
+}
+
+static void sg_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	DPRINTK("%s(0x%x,0x%x)\n", __FUNCTION__, (__u32)d, (__u32)adr);
+	writepreflush(map->map_priv_1 + adr);
+	writew(d, map->map_priv_1 + adr);
+	writepostflush(map->map_priv_1 + adr);
+}
+
+static void sg_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	initlock();
+
+	DPRINTK("%s(0x%x,0x%x)\n", __FUNCTION__, (__u32)d, (__u32)adr);
+	writepreflush(map->map_priv_1 + adr);
+	getlock();
+	writel(d, map->map_priv_1 + adr);
+	releaselock();
+	writepostflush(map->map_priv_1 + adr);
+}
+
+static void sg_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	DPRINTK("%s(to=0x%x,from=0x%x,len=%d)\n", __FUNCTION__,
+		(__u32)to, (__u32)from, (__u32)len);
+
+#ifdef CONFIG_LOCK_MULTIBYTE
+{
+	unsigned short *src;
+	unsigned int i;
+	initlock();
+
+	getlock();
+	for (src = from, i = 0; (i < len); i += 2) {
+		writepreflush(map->map_priv_1 + from + i);
+		writew(*src++, map->map_priv_1 + from + i);
+		writepostflush(map->map_priv_1 + from + i);
+	}
+	releaselock();
+}
+#else
+	memcpy_toio(map->map_priv_1 + to, from, len);
+#endif
+}
+
+/****************************************************************************/
+/*                           OPENGEAR FLASH                                 */
+/****************************************************************************/
+#if defined(CONFIG_MACH_CM4008) || defined(CONFIG_MACH_CM41xx)
+
+#define	VENDOR	"OpenGear"
+
+/*
+ *	Intel FLASH setup. This is the only flash device, it is the entire
+ *	non-volatile storage (no IDE CF or hard drive or anything else).
+ */
+static struct map_info sg_map = {
+	name: "OpenGear Intel/StrataFlash",
+	size: FLASH_SIZE,
+	buswidth: FLASH_WIDTH,
+	read8: sg_read8,
+	read16: sg_read16,
+	read32: sg_read32,
+	copy_from: sg_copy_from,
+	write8: sg_write8,
+	write16: sg_write16,
+	write32: sg_write32,
+	copy_to: sg_copy_to
+};
+
+static struct mtd_partition sg_partitions[] = {
+	{
+		name: "U-Boot Loader",
+		offset: 0,
+		size: 0x00020000
+	},
+	{
+		name: "OpenGear non-volatile configuration",
+		offset: 0x00020000,
+		size: 0x001e0000
+	},
+	{
+		name: "OpenGear image",
+		offset: 0x200000,
+	},
+	{
+		name: "OpenGear Intel/StrataFlash",
+		offset: 0
+	},
+};
+
+#else
+/****************************************************************************/
+/*                           SNAPGEAR FLASH                                 */
+/****************************************************************************/
+
+#define	VENDOR	"SnapGear"
+
+/*
+ *	Intel FLASH setup. This is the only flash device, it is the entire
+ *	non-volatile storage (no IDE CF or hard drive or anything else).
+ */
+static struct map_info sg_map = {
+	name: "SnapGear Intel/StrataFlash",
+	size: 0x800000,
+	buswidth: FLASH_WIDTH,
+	read8: sg_read8,
+	read16: sg_read16,
+	read32: sg_read32,
+	copy_from: sg_copy_from,
+	write8: sg_write8,
+	write16: sg_write16,
+	write32: sg_write32,
+	copy_to: sg_copy_to
+};
+
+static struct mtd_partition sg_partitions[] = {
+	{
+		name: "SnapGear Boot Loader",
+		offset: 0,
+		size: 0x00020000
+	},
+#if defined(CONFIG_MACH_IPD)
+	{
+		name: "SnapGear System Data",
+		offset: 0x00020000,
+		size: 0x00020000
+	},
+	{
+		name: "SnapGear non-volatile configuration",
+		offset: 0x00040000,
+		size: 0x00020000
+	},
+	{
+		name: "SnapGear image",
+		offset: 0x00060000,
+	},
+#else
+	{
+		name: "SnapGear non-volatile configuration",
+		offset: 0x00020000,
+		size: CONFIG_SIZE
+	},
+	{
+		name: "SnapGear image",
+		offset: 0x00020000+CONFIG_SIZE,
+	},
+#endif
+	{
+		name: "SnapGear Intel/StrataFlash",
+		offset: 0
+	},
+};
+
+/****************************************************************************/
+#endif
+/****************************************************************************/
+
+#define NUM_PARTITIONS	(sizeof(sg_partitions)/sizeof(sg_partitions[0]))
+
+/****************************************************************************/
+
+/*
+ *	Set the Intel flash back to read mode. Sometimes MTD leaves the
+ *	flash in status mode, and if you reboot there is no code to
+ *	execute (the flash devices do not get a RESET) :-(
+ */
+static int sg_reboot_notifier(struct notifier_block *nb, unsigned long val, void *v)
+{
+	struct cfi_private *cfi = sg_map.fldrv_priv;
+	int i;
+
+	/* Make sure all FLASH chips are put back into read mode */
+	for (i = 0; cfi && i < cfi->numchips; i++) {
+		cfi_send_gen_cmd(0xff, 0x55, cfi->chips[i].start, &sg_map,
+			cfi, cfi->device_type, NULL);
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block sg_notifier_block = {
+	sg_reboot_notifier, NULL, 0
+};
+
+/****************************************************************************/
+
+/*
+ *	Find the MTD device with the given name.
+ */
+
+static int sg_getmtdindex(char *name)
+{
+	struct mtd_info *mtd;
+	int i, index;
+
+	index = -1;
+	for (i = 0; (i < MAX_MTD_DEVICES); i++) {
+		mtd = get_mtd_device(NULL, i);
+		if (mtd) {
+			if (strcmp(mtd->name, name) == 0)
+				index = mtd->index;
+			put_mtd_device(mtd);
+			if (index >= 0)
+				break;
+		}
+	}
+	return index;
+}
+
+/****************************************************************************/
+
+int __init sg_init(void)
+{
+	int index, rc;
+
+	printk(VENDOR ": MTD flash setup\n");
+
+#if defined(CONFIG_ARCH_IXP425)
+	/* Enable flash writes */
+	*IXP425_EXP_CS0 |= IXP425_FLASH_WRITABLE;
+#endif
+
+	sg_res = request_mem_region(FLASH_ADDR, FLASH_SIZE, VENDOR " FLASH");
+	if (sg_res == NULL) {
+		printk(VENDOR ": failed memory resource request?\n");
+		return -EIO;
+	}
+
+	/*
+	 *	Map flash into our virtual address space.
+	 */
+	sg_map.map_priv_1 = (unsigned long) ioremap(FLASH_ADDR, FLASH_SIZE);
+	if (!sg_map.map_priv_1) {
+		release_mem_region(FLASH_ADDR, FLASH_SIZE);
+		sg_res = NULL;
+		printk(VENDOR ": failed to ioremap() flash\n");
+		return -EIO;
+	}
+
+	if ((sg_mtd = do_map_probe("cfi_probe", &sg_map)) == NULL) {
+		iounmap((void *)sg_map.map_priv_1);
+		release_mem_region(FLASH_ADDR, FLASH_SIZE);
+		sg_res = NULL;
+		sg_map.map_priv_1 = 0;
+		printk(VENDOR ":probe failed\n");
+		return -ENXIO;
+	}
+
+	printk(KERN_NOTICE VENDOR ": %s device size = %dK\n",
+		sg_mtd->name, sg_mtd->size>>10);
+
+	sg_mtd->module = THIS_MODULE;
+	register_reboot_notifier(&sg_notifier_block);
+	rc = add_mtd_partitions(sg_mtd, sg_partitions, NUM_PARTITIONS);
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (initrd_start == 0)
+#endif
+	{
+		/* Mark mtd partition as root device */
+		index = sg_getmtdindex(VENDOR " image");
+		if (index >= 0)
+			ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, index);
+	}
+
+	return rc;
+}
+
+/****************************************************************************/
+
+void __exit sg_cleanup(void)
+{
+	unregister_reboot_notifier(&sg_notifier_block);
+	if (sg_mtd) {
+		del_mtd_partitions(sg_mtd);
+		map_destroy(sg_mtd);
+	}
+	if (sg_map.map_priv_1) {
+		iounmap((void *)sg_map.map_priv_1);
+		sg_map.map_priv_1 = 0;
+	}
+	if (sg_res) {
+		release_mem_region(FLASH_ADDR, FLASH_SIZE);
+		sg_res = NULL;
+	}
+}
+
+/****************************************************************************/
+
+module_init(sg_init);
+module_exit(sg_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>");
+MODULE_DESCRIPTION("SnapGear/ARM flash support");
+
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/mtd/maps/snapgeode.c linux-2.4.29-uc1/drivers/mtd/maps/snapgeode.c
--- linux-2.4.29/drivers/mtd/maps/snapgeode.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/snapgeode.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,289 @@
+/****************************************************************************/
+
+/*
+ *      snapgeode.c -- mappings for SnapGear GEODE based boards
+ *
+ *      (C) Copyright 2000-2003, Greg Ungerer (gerg@snapgear.com)
+ *      (C) Copyright 2001-2003, SnapGear (www.snapgear.com)
+ */
+
+/****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/cfi.h>
+#include <linux/reboot.h>
+#include <asm/io.h>
+
+/****************************************************************************/
+
+static struct mtd_info *sg_mtd;
+
+/****************************************************************************/
+
+static __u8 sg_read8(struct map_info *map, unsigned long ofs)
+{
+	return(readb(map->map_priv_1 + ofs));
+}
+
+static __u16 sg_read16(struct map_info *map, unsigned long ofs)
+{
+	return(readw(map->map_priv_1 + ofs));
+}
+
+static __u32 sg_read32(struct map_info *map, unsigned long ofs)
+{
+	return(readl(map->map_priv_1 + ofs));
+}
+
+static void sg_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+static void sg_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	writeb(d, map->map_priv_1 + adr);
+}
+
+static void sg_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	writew(d, map->map_priv_1 + adr);
+}
+
+static void sg_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	writel(d, map->map_priv_1 + adr);
+}
+
+static void sg_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+/****************************************************************************/
+#ifdef CONFIG_MTD_CFI_INTELEXT
+/****************************************************************************/
+
+/*
+ *	Intel FLASH setup. This is the only flash device, it is the entire
+ *	non-volatile storage (no IDE CF or hard drive).
+ */
+
+static struct map_info sg_map = {
+	name: "SnapGear Intel/StrataFlash",
+	size: 0x800000,
+	buswidth: 1,
+	read8: sg_read8,
+	read16: sg_read16,
+	read32: sg_read32,
+	copy_from: sg_copy_from,
+	write8: sg_write8,
+	write16: sg_write16,
+	write32: sg_write32,
+	copy_to: sg_copy_to
+};
+
+static struct mtd_partition sg_partitions[] = {
+	{
+		name: "SnapGear kernel",
+		offset: 0,
+		size: 0x00100000
+	},
+	{
+		name: "SnapGear filesystem",
+		offset: 0x00100000,
+	},
+	{
+		name: "SnapGear config",
+		offset: 0x007c0000,
+		size: 0x00020000
+	},
+	{
+		name: "SnapGear Intel/StrataFlash",
+		offset: 0
+	},
+	{
+		name: "SnapGear BIOS Config",
+		offset: 0x007e0000,
+		size: 0x00020000
+	},
+	{
+		name: "SnapGear BIOS",
+		offset: 0x007e0000,
+		size: 0x00020000
+	},
+};
+
+#define	PROBE	"cfi_probe"
+
+/****************************************************************************/
+#else
+/****************************************************************************/
+
+/*
+ *	If only an AMD flash is fitted then it is the BIOS/boot loader.
+ *	Primary non-volatile storage must be via some ither IDE mechanism
+ *	(either compact flash [CF] or real hard drive).
+ */
+
+static struct map_info sg_map = {
+	name: "SnapGear AMD/Flash",
+	size: 0x800000,
+	buswidth: 1,
+	read8: sg_read8,
+	read16: sg_read16,
+	read32: sg_read32,
+	copy_from: sg_copy_from,
+	write8: sg_write8,
+	write16: sg_write16,
+	write32: sg_write32,
+	copy_to: sg_copy_to
+};
+
+static struct mtd_partition sg_partitions[] = {
+	{
+		name: "SnapGear BIOS config",
+		offset: 0x00000000,
+		size: 0x00010000
+	},
+	{
+		name: "SnapGear BIOS",
+		offset: 0x00010000,
+		size: 0x00010000
+	},
+	{
+		name: "SnapGear AMD/Flash",
+		offset: 0
+	},
+};
+
+#define	PROBE	"jedec_probe"
+
+/****************************************************************************/
+#endif
+/****************************************************************************/
+
+#define NUM_PARTITIONS	(sizeof(sg_partitions)/sizeof(sg_partitions[0]))
+
+/****************************************************************************/
+
+#ifdef CONFIG_MTD_CFI_INTELEXT
+
+/*
+ *	Set the Intel flash back to read mode. Sometimes MTD leaves the
+ *	flash in status mode, and if you reboot there is no code to
+ *	execute (the flash devices do not get a RESET) :-(
+ */
+static int sg_reboot_notifier(struct notifier_block *nb, unsigned long val, void *v)
+{
+	struct cfi_private *cfi = sg_map.fldrv_priv;
+	unsigned long b;
+
+	/* Make sure all FLASH chips are put back into read mode */
+	for (b = 0; (b < sg_partitions[3].size); b += 0x100000) {
+		cfi_send_gen_cmd(0xff, 0x55, b, &sg_map, cfi,
+			cfi->device_type, NULL);
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block sg_notifier_block = {
+	sg_reboot_notifier, NULL, 0
+};
+
+#endif /* CONFIG_MTD_CFI_INTELEXT */
+
+/****************************************************************************/
+
+int __init sg_init(void)
+{
+	printk("SNAPGEAR: MTD BIOS setup\n");
+
+#if 0 && defined(CONFIG_MTD_CFI_INTELEXT)
+	/*
+	 *	Disable the LPC ROM. On a true Intel Strata flash only
+	 *	unit this has no real effect. But on a Unit fitted with
+	 *	both LPC boot ROMS and Intel Flash it will make the 
+	 *	Intel flash accessible.
+	 */
+	printk("SNAPGEODE: disabling LPC ROM, enabling Intel strata flash\n");
+	outl((inl(0x6610) & ~0x8000), 0x6610);
+#endif
+
+	/*
+	 *	On the GEODE the ROM CS stays mapped into high memory.
+	 *	So we look for it at the top of the 32bit address space.
+	 */
+	sg_map.map_priv_1 = (unsigned long)
+		ioremap_nocache(0xff800000, 0x800000);
+	if (!sg_map.map_priv_1) {
+		printk("SNAPGEAR: failed to ioremap() ROMCS\n");
+		return -EIO;
+	}
+
+	if ((sg_mtd = do_map_probe(PROBE, &sg_map)) == NULL)
+		return -ENXIO;
+
+	printk(KERN_NOTICE "SNAPGEAR: %s device size = %dK\n",
+		sg_mtd->name, sg_mtd->size>>10);
+
+	sg_mtd->module = THIS_MODULE;
+
+#ifdef CONFIG_MTD_CFI_INTELEXT
+	sg_partitions[1].size = sg_mtd->size -
+		(sg_partitions[1].offset + sg_mtd->erasesize * 2);
+	if (sg_mtd->size > 0x800000) {
+		sg_partitions[2].offset += sg_mtd->size - 0x800000;
+		sg_partitions[4].offset += sg_mtd->size - 0x800000;
+		sg_partitions[5].offset += sg_mtd->size - 0x800000;
+	}
+	register_reboot_notifier(&sg_notifier_block);
+#ifndef CONFIG_BLK_DEV_INITRD
+	ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 1);
+#endif
+#else
+	/*
+	 * Setup the partitions, second from top 64KiB and top 64KiB
+	 */
+	if (sg_mtd->size > 0x20000) {
+		sg_partitions[0].offset += sg_mtd->size - 0x20000;
+		sg_partitions[1].offset += sg_mtd->size - 0x20000;
+	}
+#endif /* !CONFIG_MTD_CFI_INTELEXT */
+
+	return add_mtd_partitions(sg_mtd, sg_partitions, NUM_PARTITIONS);
+}
+
+/****************************************************************************/
+
+void __exit sg_cleanup(void)
+{
+#ifdef CONFIG_MTD_CFI_INTELEXT
+	unregister_reboot_notifier(&sg_notifier_block);
+#endif
+	if (sg_mtd) {
+		del_mtd_partitions(sg_mtd);
+		map_destroy(sg_mtd);
+	}
+	if (sg_map.map_priv_1) {
+		iounmap((void *)sg_map.map_priv_1);
+		sg_map.map_priv_1 = 0;
+	}
+}
+
+/****************************************************************************/
+
+module_init(sg_init);
+module_exit(sg_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>");
+MODULE_DESCRIPTION("SnapGear/GEODE flash support");
+
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/mtd/maps/solutionengine.c linux-2.4.29-uc1/drivers/mtd/maps/solutionengine.c
--- linux-2.4.29/drivers/mtd/maps/solutionengine.c	2002-08-03 01:39:44.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/solutionengine.c	2005-06-14 02:12:08.000000000 +0100
@@ -18,7 +18,7 @@
 #include <linux/config.h>
 
 
-extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts, unsigned long fis_origin);
 
 __u32 soleng_read32(struct map_info *map, unsigned long ofs)
 {
@@ -110,7 +110,7 @@
 	}
 
 #ifdef CONFIG_MTD_REDBOOT_PARTS
-	nr_parts = parse_redboot_partitions(flash_mtd, &parsed_parts);
+	nr_parts = parse_redboot_partitions(flash_mtd, &parsed_parts, 0);
 	if (nr_parts > 0)
 		printk(KERN_NOTICE "Found RedBoot partition table.\n");
 	else if (nr_parts < 0)
diff -urN linux-2.4.29/drivers/mtd/maps/suzaku.c linux-2.4.29-uc1/drivers/mtd/maps/suzaku.c
--- linux-2.4.29/drivers/mtd/maps/suzaku.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/suzaku.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,202 @@
+/*
+ * drivers/mtd/maps/suzaku.c
+ *
+ * Copyright (C) 2003, 2004 Atmark Techno, Inc.
+ *
+ * Yasushi SHOJI <yashi@atmark-techno.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <linux/types.h>
+#include <linux/ioport.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+
+MODULE_AUTHOR("Atmark Techno, Inc.");
+MODULE_DESCRIPTION("Suzaku Flash map driver");
+MODULE_LICENSE("GPL v2");
+
+#define FLASH_START 0xff000000
+#define FLASH_SIZE  0x00400000
+#define FLASH_WIDTH 2
+
+__u16 suzaku_read16(struct map_info *map, unsigned long ofs)
+{
+        return readw(map->map_priv_1 + ofs);
+}
+
+void suzaku_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+        writew(d, map->map_priv_1 + adr);
+}
+
+void suzaku_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+        memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void suzaku_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+        memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+static struct mtd_info *flash_mtd;
+
+struct map_info suzaku_flash_map = {
+        .name      = "flash",
+        .size      = FLASH_SIZE,
+        .buswidth  = FLASH_WIDTH,
+
+        .read16    = suzaku_read16,
+        .copy_from = suzaku_copy_from,
+
+        .write16   = suzaku_write16,
+        .copy_to   = suzaku_copy_to,
+};
+
+/*
+ *      0x0 +-------------+
+ *          |    FPGA     |
+ *  0x80000 +-------------+
+ *          |    Boot     |
+ *  0xa0000 +------+------+
+ *          |      | Kern |
+ * 0x210000 | IMG  +------+
+ *          |      | User |
+ * 0x3f0000 +------+------+
+ *          |   Config    |
+ *          +-------------+
+ */
+/*
+ * Do _NOT_ change the order of first four entries. These entries are
+ * fixed and assinged to fixed minor numbers.
+ */
+#define CONFIG_SUZAKU_FLASH_TOP
+#if defined(CONFIG_SUZAKU_FLASH_TOP)
+struct mtd_partition suzaku_partitions[] = {
+        { .name = "Flash/All",        .size = 0x00400000, .offset = 0, },
+        { .name = "Flash/FPGA",       .size = 0x00080000, .offset = 0, },
+        { .name = "Flash/Bootloader", .size = 0x00020000, .offset = 0x00080000, },
+        { .name = "Flash/Config",     .size = 0x00010000, .offset = 0x003F0000, },
+        { .name = "Flash/Image",      .size = 0x00350000, .offset = 0x000A0000, },
+        { .name = "Flash/Kernel",     .size = 0x00170000, .offset = 0x000A0000, },
+        { .name = "Flash/User",       .size = 0x001E0000, .offset = 0x00210000, },
+};
+#else
+struct mtd_partition suzaku_partitions[] = {
+        { .name = "Flash/Bootloader", .size = 0x00008000, .offset = 0,},
+        { .name = "Flash/Reserved",   .size = 0x00008000, .offset = MTDPART_OFS_APPEND, },
+        { .name = "Flash/User",       .size = 0x00370000, .offset = MTDPART_OFS_APPEND, },
+        { .name = "Flash/FPGA",       .size = 0x00080000, .offset = MTDPART_OFS_APPEND, },
+};
+#endif
+
+struct resource suzaku_flash_resource = {
+        .name  = "flash",
+        .start = FLASH_START,
+        .end   = FLASH_START + FLASH_SIZE - 1,
+        .flags = IORESOURCE_IO | IORESOURCE_BUSY,
+};
+
+static int __init init_suzaku_flash (void)
+{
+        struct mtd_partition *parts;
+        int nb_parts = 0;
+        int err;
+        
+        parts = suzaku_partitions;
+        nb_parts = NB_OF(suzaku_partitions);
+        
+        if (request_resource (&ioport_resource, &suzaku_flash_resource)) {
+                printk(KERN_NOTICE "Failed to reserve Suzaku Flash space\n");
+                err = -EBUSY;
+                goto out;
+        }
+        
+        suzaku_flash_map.map_priv_1 = (unsigned long)ioremap(FLASH_START, FLASH_SIZE);
+        if (!suzaku_flash_map.map_priv_1) {
+                printk(KERN_NOTICE "Failed to ioremap Suzaku Flash space\n");
+                err = -EIO;
+                goto out_resource;
+        }
+
+        flash_mtd = do_map_probe("cfi_probe", &suzaku_flash_map);
+        if (!flash_mtd) {
+                flash_mtd = do_map_probe("map_rom", &suzaku_flash_map);
+        }
+        if (!flash_mtd) {
+                printk("FLASH probe failed\n");
+                err = -ENXIO;
+                goto out_ioremap;
+        }
+
+        flash_mtd->module = THIS_MODULE;
+        
+        if (add_mtd_partitions(flash_mtd, parts, nb_parts)) {
+                printk("FLASH partitions addition failed\n");
+                err = -ENOMEM;
+                goto out_probe;
+        }
+                
+        return 0;
+
+out_probe:
+        map_destroy(flash_mtd);
+        flash_mtd = 0;
+out_ioremap:
+        iounmap((void *)suzaku_flash_map.map_priv_1);
+out_resource:
+        release_resource (&suzaku_flash_resource);
+out:
+        return err;
+}
+
+static int __init init_suzaku_maps(void)
+{
+        printk(KERN_INFO "Suzaku MTD mappings:\n  Flash 0x%x at 0x%x\n", 
+               FLASH_SIZE, FLASH_START);
+
+        init_suzaku_flash();
+        
+        return 0;
+}
+
+static void __exit cleanup_suzaku_maps(void)
+{
+        if (flash_mtd) {
+                del_mtd_partitions(flash_mtd);
+                map_destroy(flash_mtd);
+                iounmap((void *)suzaku_flash_map.map_priv_1);
+                release_resource (&suzaku_flash_resource);
+        }
+}
+
+module_init(init_suzaku_maps);
+module_exit(cleanup_suzaku_maps);
diff -urN linux-2.4.29/drivers/mtd/maps/tiburon.c linux-2.4.29-uc1/drivers/mtd/maps/tiburon.c
--- linux-2.4.29/drivers/mtd/maps/tiburon.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/tiburon.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,158 @@
+/*
+ * (C) Johann Hanne, 2005, GPL
+ *
+ * Tiburon (Actiontec Dual PC Modem) flash driver
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/config.h>
+
+/* partition_info gives details on the logical partitions that the split the
+ * single flash device into. If the size if zero we use up to the end of the
+ * device. */
+static struct mtd_partition partition_info[]= {
+
+	{
+		name: "bootloader",
+		size: 64 * 1024,
+		offset: 0,
+		mask_flags: MTD_WRITEABLE
+	},
+	{
+		name: "kernel",
+		size: 640 * 1024,
+		offset: MTDPART_OFS_APPEND,
+		mask_flags: MTD_WRITEABLE
+	},
+	{
+		name: "filesystem",
+		size: 1344 * 1024,
+		offset: MTDPART_OFS_APPEND,
+		mask_flags: MTD_WRITEABLE
+	},
+	{
+		name: "config",
+		size: 16 * 1024,
+		offset: 0x4000
+	},
+	{
+		name: "complete flash",
+		size: 2048 * 1024,
+		offset: 0
+	}
+};
+
+#define NUM_PARTITIONS (sizeof(partition_info) / sizeof(partition_info[0]))
+
+#define WINDOW_ADDR 0x400000
+#define WINDOW_SIZE 0x200000
+
+static struct mtd_info *mymtd;
+
+__u8 tiburon_flash_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 tiburon_flash_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 tiburon_flash_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void tiburon_flash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *)(map->map_priv_1 + from), len);
+}
+
+void tiburon_flash_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void tiburon_flash_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void tiburon_flash_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void tiburon_flash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy((void *)(map->map_priv_1 + to), from, len);
+}
+
+struct map_info tiburon_flash_map = {
+	name: "Tiburon (Actiontec DPCM) flash memory",
+	size: WINDOW_SIZE,
+	buswidth: 2,
+	read8: tiburon_flash_read8,
+	read16: tiburon_flash_read16,
+	read32: tiburon_flash_read32,
+	copy_from: tiburon_flash_copy_from,
+	write8: tiburon_flash_write8,
+	write16: tiburon_flash_write16,
+	write32: tiburon_flash_write32,
+	copy_to: tiburon_flash_copy_to
+};
+
+int __init init_tiburon_flash(void)
+{
+       	printk(KERN_NOTICE "Tiburon (Actiontec DPCM) flash driver\n");
+	tiburon_flash_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+	if (!tiburon_flash_map.map_priv_1) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}
+
+	mymtd = do_map_probe("jedec_probe", &tiburon_flash_map);
+
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+
+                /* Create MTD devices for each partition. */
+	        add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
+		
+		return 0;
+	}
+
+	iounmap((void *)tiburon_flash_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_tiburon_flash(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+	if (tiburon_flash_map.map_priv_1) {
+		iounmap((void *)tiburon_flash_map.map_priv_1);
+		tiburon_flash_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_tiburon_flash);
+module_exit(cleanup_tiburon_flash);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Johann Hanne");
+MODULE_DESCRIPTION("MTD map driver for Actiontec Dual PC Modem");
diff -urN linux-2.4.29/drivers/mtd/maps/uclinux.c linux-2.4.29-uc1/drivers/mtd/maps/uclinux.c
--- linux-2.4.29/drivers/mtd/maps/uclinux.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/uclinux.c	2005-06-14 02:12:08.000000000 +0100
@@ -4,8 +4,6 @@
  *	uclinux.c -- generic memory mapped MTD driver for uclinux
  *
  *	(C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
- *
- * 	$Id: uclinux.c,v 1.2 2002/08/07 00:43:45 gerg Exp $
  */
 
 /****************************************************************************/
@@ -82,14 +80,6 @@
 
 /****************************************************************************/
 
-struct mtd_partition uclinux_romfs[] = {
-	{ name: "ROMfs", offset: 0 }
-};
-
-#define	NUM_PARTITIONS	(sizeof(uclinux_romfs) / sizeof(uclinux_romfs[0]))
-
-/****************************************************************************/
-
 int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len,
 	size_t *retlen, u_char **mtdbuf)
 {
@@ -99,6 +89,11 @@
 	return(0);
 }
 
+static void uclinux_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from,
+	size_t len)
+{
+}
+
 /****************************************************************************/
 
 int __init uclinux_mtd_init(void)
@@ -109,7 +104,7 @@
 
 	mapp = &uclinux_ram_map;
 	mapp->map_priv_2 = (unsigned long) &_ebss;
-	mapp->size = PAGE_ALIGN(*((unsigned long *)((&_ebss) + 8)));
+	mapp->size = PAGE_ALIGN(ntohl(*((unsigned long *)((&_ebss) + 8))));
 	mapp->buswidth = 4;
 
 	printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n",
@@ -132,14 +127,15 @@
 		
 	mtd->module = THIS_MODULE;
 	mtd->point = uclinux_point;
+	mtd->unpoint = uclinux_unpoint;
 	mtd->priv = mapp;
 
 	uclinux_ram_mtdinfo = mtd;
-	add_mtd_partitions(mtd, uclinux_romfs, NUM_PARTITIONS);
+	add_mtd_device(mtd);
+
+	printk("uclinux[mtd]: root filesystem index=%d\n", mtd->index);
 
-	printk("uclinux[mtd]: set %s to be root filesystem\n",
-	     	uclinux_romfs[0].name);
-	ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 0);
+	ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
 	put_mtd_device(mtd);
 
 	return(0);
diff -urN linux-2.4.29/drivers/mtd/maps/vc547x-flash.c linux-2.4.29-uc1/drivers/mtd/maps/vc547x-flash.c
--- linux-2.4.29/drivers/mtd/maps/vc547x-flash.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/maps/vc547x-flash.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,146 @@
+/*
+ * $Id: vc547x-flash.c,v 1.1 2005/03/02 05:30:25 gerg Exp $
+ *
+ * Nokia / Sagem D-Box 2 flash driver
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/config.h>
+
+#define WINDOW_ADDR 0x00000000
+#define WINDOW_SIZE 0x00800000
+
+/* partition_info gives details on the logical partitions that the split the
+ * single flash device into. If the size if zero we use up to the end of the
+ * device. */
+static struct mtd_partition partition_info[]= {
+							{name: "uboot bootloader",		// raw
+						     size: 128 * 1024, 
+						     offset: 0,                  
+						     mask_flags: MTD_WRITEABLE},
+                            {name: "System (JFFS2)",		// jffs
+						     size: MTDPART_SIZ_FULL, 
+						     offset: MTDPART_OFS_APPEND, 
+						     mask_flags: 0}
+};
+
+#define NUM_PARTITIONS (sizeof(partition_info) / sizeof(partition_info[0]))
+
+
+static struct mtd_info *mymtd;
+
+__u8 vc547x_flash_read8(struct map_info *map, unsigned long ofs)
+{
+	return(*((__u8 *) (map->map_priv_1 + ofs)));
+}
+
+__u16 vc547x_flash_read16(struct map_info *map, unsigned long ofs)
+{
+	return(*((__u16 *) (map->map_priv_1 + ofs)));
+}
+
+__u32 vc547x_flash_read32(struct map_info *map, unsigned long ofs)
+{
+	return(*((__u32 *) (map->map_priv_1 + ofs)));
+}
+
+void vc547x_flash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+//printk("flash_copy_from(%x, %x, %x\n", to, (void *)(map->map_priv_1 + from), len);
+	memcpy(to, (void *)(map->map_priv_1 + from), len);
+}
+
+void vc547x_flash_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*((__u8 *) (map->map_priv_1 + adr)) = d;
+}
+
+void vc547x_flash_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*((__u16 *) (map->map_priv_1 + adr)) = d;
+}
+
+void vc547x_flash_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*((__u32 *) (map->map_priv_1 + adr)) = d;
+}
+
+void vc547x_flash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+//printk("flash_copy_to(%x, %x, %x\n", to, (void *)(map->map_priv_1 + to), from, len);
+	memcpy((void *)(map->map_priv_1 + to), from, len);
+}
+
+struct map_info vc547x_flash_map = {
+	name: "audio_oip flash memory",
+	size: WINDOW_SIZE,
+	buswidth: 4,
+	read8: vc547x_flash_read8,
+	read16: vc547x_flash_read16,
+	read32: vc547x_flash_read32,
+	copy_from: vc547x_flash_copy_from,
+	write8: vc547x_flash_write8,
+	write16: vc547x_flash_write16,
+	write32: vc547x_flash_write32,
+	copy_to: vc547x_flash_copy_to
+};
+
+int __init init_vc547x_flash(void)
+{
+   	printk(KERN_NOTICE "vc547x flash driver (size->0x%X mem->0x%X)\n", WINDOW_SIZE, WINDOW_ADDR);
+	vc547x_flash_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+	// since our flash is at 0 no problem - but don't check
+	/*
+	if (!vc547x_flash_map.map_priv_1) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}*/
+
+	// Probe for dual Intel 28F320 or dual AMD
+	/* can be { "cfi_probe", "jedec_probe", "map_rom", 0 }; */
+	mymtd = do_map_probe("jedec_probe", &vc547x_flash_map);
+	if (!mymtd) {
+	    // Probe for single Intel 28F640
+	    vc547x_flash_map.buswidth = 2;
+	
+	    mymtd = do_map_probe("cfi_probe", &vc547x_flash_map);
+	}
+	    
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+
+                /* Create MTD devices for each partition. */
+	        add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
+		
+		return 0;
+	}
+
+	iounmap((void *)vc547x_flash_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_vc547x_flash(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+	if (vc547x_flash_map.map_priv_1) {
+		iounmap((void *)vc547x_flash_map.map_priv_1);
+		vc547x_flash_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_vc547x_flash);
+module_exit(cleanup_vc547x_flash);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>");
+MODULE_DESCRIPTION("MTD map driver for Nokia/Sagem D-Box 2 board, used for vc547x");
diff -urN linux-2.4.29/drivers/mtd/mtdblock.c linux-2.4.29-uc1/drivers/mtd/mtdblock.c
--- linux-2.4.29/drivers/mtd/mtdblock.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/mtdblock.c	2005-06-14 02:12:08.000000000 +0100
@@ -566,6 +566,30 @@
 	}
 }
 
+
+#ifdef MAGIC_ROM_PTR
+static int
+mtdblock_romptr(kdev_t dev, struct vm_area_struct * vma)
+{
+	struct mtd_info *mtd;
+	u_char *ptr;
+	size_t len;
+
+	mtd = __get_mtd_device(NULL, MINOR(dev));
+
+	if (!mtd->point)
+		return -ENOSYS; /* Can't do it, No function to point to correct addr */
+
+	if ((*mtd->point)(mtd,vma->vm_offset,vma->vm_end-vma->vm_start,&len,&ptr) != 0)
+		return -ENOSYS;
+
+	vma->vm_start = (unsigned long) ptr;
+	vma->vm_end = vma->vm_start + len;
+	return 0;
+}
+#endif
+
+
 #if LINUX_VERSION_CODE < 0x20326
 static struct file_operations mtd_fops =
 {
@@ -573,6 +597,9 @@
 	ioctl: mtdblock_ioctl,
 	release: mtdblock_release,
 	read: block_read,
+#ifdef MAGIC_ROM_PTR
+	romptr: mtdblock_romptr,
+#endif
 	write: block_write
 };
 #else
@@ -583,6 +610,9 @@
 #endif
 	open: mtdblock_open,
 	release: mtdblock_release,
+#ifdef MAGIC_ROM_PTR
+	romptr: mtdblock_romptr,
+#endif
 	ioctl: mtdblock_ioctl
 };
 #endif
@@ -636,6 +666,8 @@
 		return -EAGAIN;
 	}
 #endif
+	DEBUG(MTD_DEBUG_LEVEL3,
+		"init_mtdblock: allocated major number %d.\n", MTD_BLOCK_MAJOR);
 	
 	/* We fill it in at open() time. */
 	for (i=0; i< MAX_MTD_DEVICES; i++) {
diff -urN linux-2.4.29/drivers/mtd/mtdblock_ro.c linux-2.4.29-uc1/drivers/mtd/mtdblock_ro.c
--- linux-2.4.29/drivers/mtd/mtdblock_ro.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/mtdblock_ro.c	2005-06-14 02:12:08.000000000 +0100
@@ -241,6 +241,30 @@
 	}
 }
 
+
+#ifdef MAGIC_ROM_PTR
+static int
+mtdblock_romptr(kdev_t dev, struct vm_area_struct * vma)
+{
+	struct mtd_info *mtd;
+	u_char *ptr;
+	size_t len;
+
+	mtd = __get_mtd_device(NULL, MINOR(dev));
+
+	if (!mtd->point)
+		return -ENOSYS; /* Can't do it, No function to point to correct addr */
+
+	if ((*mtd->point)(mtd,vma->vm_offset,vma->vm_end-vma->vm_start,&len,&ptr) != 0)
+		return -ENOSYS;
+
+	vma->vm_start = (unsigned long) ptr;
+	vma->vm_end = vma->vm_start + len;
+	return 0;
+}
+#endif
+
+
 #if LINUX_VERSION_CODE < 0x20326
 static struct file_operations mtd_fops =
 {
@@ -248,6 +272,9 @@
 	ioctl: mtdblock_ioctl,
 	release: mtdblock_release,
 	read: block_read,
+#ifdef MAGIC_ROM_PTR
+	romptr: mtdblock_romptr,
+#endif
 	write: block_write
 };
 #else
@@ -258,6 +285,9 @@
 #endif
 	open: mtdblock_open,
 	release: mtdblock_release,
+#ifdef MAGIC_ROM_PTR
+	romptr: mtdblock_romptr,
+#endif
 	ioctl: mtdblock_ioctl
 };
 #endif
@@ -271,6 +301,9 @@
 		       MTD_BLOCK_MAJOR);
 		return -EAGAIN;
 	}
+	DEBUG(MTD_DEBUG_LEVEL3,
+		"init_mtdblock: allocated major number %d (read only).\n", 
+		MTD_BLOCK_MAJOR);
 	
 	/* We fill it in at open() time. */
 	for (i=0; i< MAX_MTD_DEVICES; i++) {
diff -urN linux-2.4.29/drivers/mtd/mtdchar.c linux-2.4.29-uc1/drivers/mtd/mtdchar.c
--- linux-2.4.29/drivers/mtd/mtdchar.c	2004-08-08 00:26:04.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/mtdchar.c	2005-06-14 02:12:08.000000000 +0100
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/mtd/mtd.h>
 #include <linux/slab.h>
+#include <asm/semaphore.h>
 
 #ifdef CONFIG_DEVFS_FS
 #include <linux/devfs_fs_kernel.h>
@@ -115,7 +116,8 @@
 /* FIXME: This _really_ needs to die. In 2.5, we should lock the
    userspace buffer down and use it directly with readv/writev.
 */
-#define MAX_KMALLOC_SIZE 0x20000
+#define MAX_KMALLOC_SIZE 0x2000
+
 
 static ssize_t mtd_read(struct file *file, char *buf, size_t count,loff_t *ppos)
 {
@@ -176,10 +178,13 @@
 	return total_retlen;
 } /* mtd_read */
 
+static char *write_kbuf;
+static int write_kbuf_len;
+static struct semaphore write_kbuf_sem;
+
 static ssize_t mtd_write(struct file *file, const char *buf, size_t count,loff_t *ppos)
 {
 	struct mtd_info *mtd = (struct mtd_info *)file->private_data;
-	char *kbuf;
 	size_t retlen;
 	size_t total_retlen=0;
 	loff_t pos = *ppos;
@@ -197,24 +202,30 @@
 	if (!count)
 		return 0;
 
-	while (count) {
-		if (count > MAX_KMALLOC_SIZE) 
-			len = MAX_KMALLOC_SIZE;
-		else
-			len = count;
+	down(&write_kbuf_sem);
 
-		kbuf=kmalloc(len,GFP_KERNEL);
-		if (!kbuf) {
-			printk("kmalloc is null\n");
+	if (!write_kbuf_len) {
+		write_kbuf_len = MAX_KMALLOC_SIZE;
+		write_kbuf = kmalloc(write_kbuf_len, GFP_KERNEL);
+		if (!write_kbuf) {
+			write_kbuf_len = 0x0;
+			up(&write_kbuf_sem);
 			return -ENOMEM;
 		}
+	}
 
-		if (copy_from_user(kbuf, buf, len)) {
-			kfree(kbuf);
+	while (count) {
+		if (count < write_kbuf_len)
+			len = count;
+		else
+			len = write_kbuf_len;
+
+		if (copy_from_user(write_kbuf, buf, len)) {
+			up(&write_kbuf_sem);
 			return -EFAULT;
 		}
 		
-	        ret = (*(mtd->write))(mtd, pos, len, &retlen, kbuf);
+	        ret = (*(mtd->write))(mtd, pos, len, &retlen, write_kbuf);
 		if (!ret) {
 			pos += retlen;
 			total_retlen += retlen;
@@ -222,14 +233,13 @@
 			buf += retlen;
 		}
 		else {
-			kfree(kbuf);
+			up(&write_kbuf_sem);
 			return ret;
 		}
-		
-		kfree(kbuf);
 	}
 	*ppos = pos;
 
+	up(&write_kbuf_sem);
 	return total_retlen;
 } /* mtd_write */
 
@@ -526,7 +536,7 @@
 
 		
 	default:
-		DEBUG(MTD_DEBUG_LEVEL0, "Invalid ioctl %x (MEMGETINFO = %x)\n", cmd, MEMGETINFO);
+		DEBUG(MTD_DEBUG_LEVEL0, "Invalid ioctl %x (MEMGETINFO = %lx)\n", cmd, MEMGETINFO);
 		ret = -ENOTTY;
 	}
 
@@ -600,6 +610,24 @@
 	}
 #endif
 
+	/* XXX
+	 * Allocate and buffer and init spinlock.
+	 */
+	sema_init(&write_kbuf_sem, 1);
+
+	down(&write_kbuf_sem);
+	write_kbuf_len = 0x2000;
+	write_kbuf = kmalloc(write_kbuf_len, GFP_KERNEL);
+	if (!write_kbuf) {
+		write_kbuf_len = 0x0;
+		up(&write_kbuf_sem);
+		return -ENOMEM;
+	}
+	up(&write_kbuf_sem);
+	
+	DEBUG(MTD_DEBUG_LEVEL3,
+		"init_mtdchar: allocated major number %d.\n", MTD_CHAR_MAJOR);
+
 	return 0;
 }
 
diff -urN linux-2.4.29/drivers/mtd/nand/Config.in linux-2.4.29-uc1/drivers/mtd/nand/Config.in
--- linux-2.4.29/drivers/mtd/nand/Config.in	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/nand/Config.in	2005-06-14 02:12:08.000000000 +0100
@@ -20,17 +20,21 @@
 fi
 
 if [ "$CONFIG_ARCH_EDB7312" = "y" ]; then
-   dep_tristate '  NAND Flash device on EDP7312 board' CONFIG_MTD_NAND_EDB7312 $CONFIG_MTD_NAND
+   dep_tristate '  NAND Flash device on EDB7312 board' CONFIG_MTD_NAND_EDB7312 $CONFIG_MTD_NAND
 fi
 
-if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" -o "$CONFIG_MTD_NAND" = "y" ]; then
+if [ "$CONFIG_MTD_DOC2001PLUS" = "y" -o "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" -o "$CONFIG_MTD_NAND" = "y" ]; then
    define_bool CONFIG_MTD_NAND_IDS y
 fi
 
 if [ "$CONFIG_MTD_NAND_IDS" != "y" ]; then
-if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" -o "$CONFIG_MTD_NAND" = "m" ]; then
+if [ "$CONFIG_MTD_DOC2001PLUS" = "m" -o "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" -o "$CONFIG_MTD_NAND" = "m" ]; then
    define_bool CONFIG_MTD_NAND_IDS m
 fi
 fi
 
+if [ "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
+   dep_tristate '  SmartMedia Card on Atmel AT91RM9200' CONFIG_MTD_AT91_SMARTMEDIA $CONFIG_MTD_NAND
+fi
+  
 endmenu
diff -urN linux-2.4.29/drivers/mtd/nftlcore.c linux-2.4.29-uc1/drivers/mtd/nftlcore.c
--- linux-2.4.29/drivers/mtd/nftlcore.c	2003-06-13 15:51:34.000000000 +0100
+++ linux-2.4.29-uc1/drivers/mtd/nftlcore.c	2005-06-14 02:12:08.000000000 +0100
@@ -704,25 +704,192 @@
 	return 0xffff;
 }
 
+/* Given a Virtual Unit Chain, see if it can be deleted, and if so do it. */
+static void NFTL_trydeletechain(struct NFTLrecord *nftl, unsigned thisVUC)
+{
+	unsigned char BlockUsed[MAX_SECTORS_PER_UNIT];
+	unsigned char BlockFreeFound[MAX_SECTORS_PER_UNIT];
+	unsigned int thisEUN;
+	int block;
+	unsigned int status;
+	int silly;
+	struct nftl_bci bci;
+	size_t retlen;
+
+	memset(BlockUsed, 0, sizeof(BlockUsed));
+	memset(BlockFreeFound, 0, sizeof(BlockFreeFound));
+
+	thisEUN = nftl->EUNtable[thisVUC];
+	if (thisEUN == BLOCK_NIL) {
+		printk(KERN_WARNING "Trying to delete non-existent "
+		       "Virtual Unit Chain %d!\n", thisVUC);
+		return;
+	}
+	
+	/* Scan through the Erase Units to determine whether any data is in
+	   each of the 512-byte blocks within the Chain.
+	*/
+	silly = MAX_LOOPS;
+	while (thisEUN < nftl->nb_blocks) {
+		for (block = 0; block < nftl->EraseSize/512; block++) {
+			if (BlockFreeFound[block])
+				continue;
+
+			if (MTD_READOOB(nftl->mtd,
+					(thisEUN * nftl->EraseSize) + (block * 512),
+					8 , &retlen, (char *)&bci) < 0)
+				status = SECTOR_IGNORE;
+			else
+				status = bci.Status | bci.Status1;
+
+			switch(status) {
+			case SECTOR_FREE:
+				BlockFreeFound[block] = 1;
+				break;
+			case SECTOR_USED:
+				BlockUsed[block] = 1;
+				break;
+			case SECTOR_DELETED:
+				BlockUsed[block] = 0;
+				break;
+			case SECTOR_IGNORE:
+				break;
+			default:
+				printk("Unknown status for block %d in EUN %d: %x\n",
+				       block, thisEUN, status);
+			}
+		}
+
+		if (!silly--) {
+			printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%x\n",
+			       thisVUC);
+			return;
+		}
+		
+		thisEUN = nftl->ReplUnitTable[thisEUN];
+	}
+
+	for (block = 0; block < nftl->EraseSize/512; block++)
+		if (BlockUsed[block])
+			return;
+
+	/* For each block in the chain free it and make it available
+	 * for future use
+	 */
+	DEBUG(MTD_DEBUG_LEVEL1, "Deleting empty VUC %d\n", thisVUC);
+	thisEUN = nftl->EUNtable[thisVUC];
+	while (thisEUN < nftl->nb_blocks) {
+		unsigned int EUNtmp;
+
+		EUNtmp = nftl->ReplUnitTable[thisEUN];
+
+		if (NFTL_formatblock(nftl, thisEUN) < 0) {
+			/* could not erase : mark block as reserved
+			 * FixMe: Update Bad Unit Table on disk
+			 */
+			nftl->ReplUnitTable[thisEUN] = BLOCK_RESERVED;
+		} else {
+			/* correctly erased : mark it as free */
+			nftl->ReplUnitTable[thisEUN] = BLOCK_FREE;
+			nftl->numfreeEUNs++;
+		}
+		thisEUN = EUNtmp;
+	}
+	
+	nftl->EUNtable[thisVUC] = BLOCK_NIL;
+}
+
+static int NFTL_deleteblock(struct NFTLrecord *nftl, unsigned block)
+{
+	u16 lastgoodEUN;
+	u16 thisEUN = nftl->EUNtable[block / (nftl->EraseSize / 512)];
+	unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1);
+	unsigned int status;
+	int silly = MAX_LOOPS;
+	size_t retlen;
+	struct nftl_bci bci;
+
+	lastgoodEUN = BLOCK_NIL;
+
+	if (thisEUN != BLOCK_NIL) {
+		while (thisEUN < nftl->nb_blocks) {
+			if (MTD_READOOB(nftl->mtd, (thisEUN * nftl->EraseSize) + blockofs,
+					8, &retlen, (char *)&bci) < 0)
+				status = SECTOR_IGNORE;
+			else
+				status = bci.Status | bci.Status1;
+
+			switch (status) {
+			case SECTOR_FREE:
+				/* no modification of a sector should follow a free sector */
+				goto the_end;
+			case SECTOR_DELETED:
+				lastgoodEUN = BLOCK_NIL;
+				break;
+			case SECTOR_USED:
+				lastgoodEUN = thisEUN;
+				break;
+			case SECTOR_IGNORE:
+				break;
+			default:
+				printk("Unknown status for block %d in EUN %d: %x\n",
+				       block, thisEUN, status);
+				break;
+			}
+
+			if (!silly--) {
+				printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%x\n",
+				       block / (nftl->EraseSize / 512));
+				return 1;
+			}
+			thisEUN = nftl->ReplUnitTable[thisEUN];
+		}
+	}
+
+ the_end:
+	if (lastgoodEUN != BLOCK_NIL) {
+		loff_t ptr = (lastgoodEUN * nftl->EraseSize) + blockofs;
+		size_t retlen;
+
+		if (MTD_READOOB(nftl->mtd, ptr, 8, &retlen, (char *)&bci) < 0)
+			return -EIO;
+		bci.Status = bci.Status1 = SECTOR_DELETED;
+		if (MTD_WRITEOOB(nftl->mtd, ptr, 8, &retlen, (char *)&bci) < 0)
+			return -EIO;
+		NFTL_trydeletechain(nftl, block / (nftl->EraseSize / 512));
+	}
+	return 0;
+}
+
 static int NFTL_writeblock(struct NFTLrecord *nftl, unsigned block, char *buffer)
 {
 	u16 writeEUN;
 	unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1);
 	size_t retlen;
 	u8 eccbuf[6];
+	char *p, *pend;
 
-	writeEUN = NFTL_findwriteunit(nftl, block);
+	/* Is block all zero? */
+	pend = buffer+512;
+	for (p=buffer; p<pend && !*p; p++);
+
+	if (p<pend) {
+		writeEUN = NFTL_findwriteunit(nftl, block);
+
+		if (writeEUN == BLOCK_NIL) {
+			printk(KERN_WARNING
+					"NFTL_writeblock(): Cannot find block to write to\n");
+			/* If we _still_ haven't got a block to use, we're screwed */
+			return 1;
+		}
 
-	if (writeEUN == BLOCK_NIL) {
-		printk(KERN_WARNING
-		       "NFTL_writeblock(): Cannot find block to write to\n");
-		/* If we _still_ haven't got a block to use, we're screwed */
-		return 1;
+		MTD_WRITEECC(nftl->mtd, (writeEUN * nftl->EraseSize) + blockofs,
+				512, &retlen, (char *)buffer, (char *)eccbuf,
+				NAND_ECC_DISKONCHIP);
+		/* no need to write SECTOR_USED flags since they are written in mtd_writeecc */
 	}
-
-	MTD_WRITEECC(nftl->mtd, (writeEUN * nftl->EraseSize) + blockofs,
-		     512, &retlen, (char *)buffer, (char *)eccbuf, NAND_ECC_DISKONCHIP);
-        /* no need to write SECTOR_USED flags since they are written in mtd_writeecc */
+	else
+		NFTL_deleteblock(nftl, block);
 
 	return 0;
 }
@@ -799,6 +966,22 @@
 	if (!nftl) return -EINVAL;
 
 	switch (cmd) {
+#if 0
+	case NFTL_IOCTL_DELETE_SECTOR: {
+		unsigned int dev;
+		int res;
+
+		if (arg >= part_table[dev].nr_sects)
+			return -EINVAL;
+		arg += part_table[MINOR(inode->i_rdev)].start_sect;
+		DEBUG(MTD_DEBUG_LEVEL3, "Waiting for mutex\n");
+		down(&nftl->mutex);
+		DEBUG(MTD_DEBUG_LEVEL3, "Got mutex\n");
+		res = NFTL_deleteblock(nftl, arg);
+		up(&nftl->mutex);
+		return res;
+	}
+#endif
 	case HDIO_GETGEO: {
 		struct hd_geometry g;
 
diff -urN linux-2.4.29/drivers/mtd/redboot.c linux-2.4.29-uc1/drivers/mtd/redboot.c
--- linux-2.4.29/drivers/mtd/redboot.c	2001-11-09 22:01:22.000000000 +0000
+++ linux-2.4.29-uc1/drivers/mtd/redboot.c	2005-06-14 02:12:08.000000000 +0100
@@ -34,7 +34,7 @@
 	return 1;
 }
 
-int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts)
+int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts, unsigned long fis_origin)
 {
 	int nrparts = 0;
 	struct fis_image_desc *buf;
@@ -44,20 +44,25 @@
 	size_t retlen;
 	char *names;
 	int namelen = 0;
+	char *nullname;
+	int nulllen = 0;
+#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
+	static char nullstring[] = "unallocated";
+#endif
 
-	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	buf = kmalloc(master->erasesize, GFP_KERNEL);
 
 	if (!buf)
 		return -ENOMEM;
 
 	/* Read the start of the last erase block */
 	ret = master->read(master, master->size - master->erasesize,
-			   PAGE_SIZE, &retlen, (void *)buf);
+			   master->erasesize, &retlen, (void *)buf);
 
 	if (ret)
 		goto out;
 
-	if (retlen != PAGE_SIZE) {
+	if (retlen != master->erasesize) {
 		ret = -EIO;
 		goto out;
 	}
@@ -75,7 +80,7 @@
 		goto out;
 	}
 
-	for (i = 0; i < PAGE_SIZE / sizeof(struct fis_image_desc); i++) {
+	for (i = 0; i < master->erasesize / sizeof(struct fis_image_desc); i++) {
 		struct fis_list *new_fl, **prev;
 
 		if (buf[i].name[0] == 0xff)
@@ -90,7 +95,11 @@
 			goto out;
 		}
 		new_fl->img = &buf[i];
-		buf[i].flash_base &= master->size-1;
+		if (fis_origin) {
+			buf[i].flash_base -= fis_origin;
+		} else {
+			buf[i].flash_base &= master->size-1;
+		}
 
 		/* I'm sure the JFFS2 code has done me permanent damage.
 		 * I now think the following is _normal_
@@ -103,42 +112,69 @@
 
 		nrparts++;
 	}
-	if (fl->img->flash_base)
+#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
+	if (fl->img->flash_base) {
 		nrparts++;
+		nulllen = sizeof(nullstring);
+	}
 
 	for (tmp_fl = fl; tmp_fl->next; tmp_fl = tmp_fl->next) {
-		if (tmp_fl->img->flash_base + tmp_fl->img->size + master->erasesize < tmp_fl->next->img->flash_base)
+		if (tmp_fl->img->flash_base + tmp_fl->img->size + master->erasesize <= tmp_fl->next->img->flash_base) {
 			nrparts++;
+			nulllen = sizeof(nullstring);
+		}
 	}
-	parts = kmalloc(sizeof(*parts)*nrparts + namelen, GFP_KERNEL);
+#endif
+	parts = kmalloc(sizeof(*parts)*nrparts + nulllen + namelen, GFP_KERNEL);
 
 	if (!parts) {
 		ret = -ENOMEM;
 		goto out;
 	}
-	names = (char *)&parts[nrparts];
-	memset(parts, 0, sizeof(*parts)*nrparts + namelen);
+
+	memset(parts, 0, sizeof(*parts)*nrparts + nulllen + namelen);
+
+	nullname = (char *)&parts[nrparts];
+#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
+	if (nulllen > 0) {
+		strcpy(nullname, nullstring);
+	}
+#endif
+	names = nullname + nulllen;
+
 	i=0;
 
+#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
 	if (fl->img->flash_base) {
-	       parts[0].name = "unallocated space";
-	       parts[0].size = fl->img->flash_base;
-	       parts[0].offset = 0;
+		parts[0].name = nullname;
+		parts[0].size = fl->img->flash_base;
+		parts[0].offset = 0;
+		i++;
 	}
+#endif
 	for ( ; i<nrparts; i++) {
 		parts[i].size = fl->img->size;
 		parts[i].offset = fl->img->flash_base;
 		parts[i].name = names;
 
 		strcpy(names, fl->img->name);
+#ifdef CONFIG_MTD_REDBOOT_PARTS_READONLY
+		if (!memcmp(names, "RedBoot", 8) ||
+				!memcmp(names, "RedBoot config", 15) ||
+				!memcmp(names, "FIS directory", 14)) {
+			parts[i].mask_flags = MTD_WRITEABLE;
+		}
+#endif
 		names += strlen(names)+1;
 
-		if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize < fl->next->img->flash_base) {
+#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
+		if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) {
 			i++;
 			parts[i].offset = parts[i-1].size + parts[i-1].offset;
 			parts[i].size = fl->next->img->flash_base - parts[i].offset;
-			parts[i].name = "unallocated space";
+			parts[i].name = nullname;
 		}
+#endif
 		tmp_fl = fl;
 		fl = fl->next;
 		kfree(tmp_fl);
diff -urN linux-2.4.29/drivers/net/8139cp.c linux-2.4.29-uc1/drivers/net/8139cp.c
--- linux-2.4.29/drivers/net/8139cp.c	2005-01-19 14:09:56.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/8139cp.c	2005-06-14 02:12:14.000000000 +0100
@@ -69,18 +69,30 @@
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
+#ifdef CONFIG_LEDMAN
+#include <linux/ledman.h>
+#endif
 #include <linux/cache.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
+static int dev_get_info(char *buffer, char **start, off_t offset, int length);
+
+/* do we want fast poll operation instead of interrupts */
+#ifdef CONFIG_FAST_TIMER
+#define FAST_POLL 1
+#include <linux/fast_timer.h>
+#endif
+
 /* VLAN tagging feature enable/disable */
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) 
 #define CP_VLAN_TAG_USED 1
-#define CP_VLAN_TX_TAG(tx_desc,vlan_tag_value) \
-	do { (tx_desc)->opts2 = (vlan_tag_value); } while (0)
+#define CP_VLAN_TX_TAG(tx_desc,vlan_tag_value, do_vlan) \
+	do { (tx_desc)->opts2 = do_vlan?cpu_to_le16(TxVlanTag):0; \
+		tx_desc->vtag = cpu_to_be16(vlan_tag_value); } while (0)
 #else
 #define CP_VLAN_TAG_USED 0
-#define CP_VLAN_TX_TAG(tx_desc,vlan_tag_value) \
+#define CP_VLAN_TX_TAG(tx_desc,vlan_tag_value, do_vlan) \
 	do { (tx_desc)->opts2 = 0; } while (0)
 #endif
 
@@ -129,7 +141,6 @@
 	  (CP)->tx_tail + (CP_TX_RING_SIZE - 1) - (CP)->tx_head :	\
 	  (CP)->tx_tail - (CP)->tx_head - 1)
 
-#define PKT_BUF_SZ		1536	/* Size of each temporary Rx buffer.*/
 #define RX_OFFSET		2
 #define CP_INTERNAL_PHY		32
 
@@ -146,6 +157,10 @@
 #define CP_MIN_MTU		60	/* TODO: allow lower, but pad */
 #define CP_MAX_MTU		4096
 
+/* Used to calculate the size of the temporary rx buffer */
+#define CP_RX_FIFO_SZ		2048
+#define CP_RX_DMA_MARGIN	500
+
 enum {
 	/* NIC register offsets */
 	MAC0		= 0x00,	/* Ethernet hardware address. */
@@ -179,6 +194,7 @@
 	TxThresh	= 0xEC, /* Early Tx threshold */
 	OldRxBufAddr	= 0x30, /* DMA address of Rx ring buffer (C mode) */
 	OldTSD0		= 0x10, /* DMA address of first Tx desc (C mode) */
+	MIIRegister	= 0xFC, /*The mii register */
 
 	/* Tx and Rx status descriptors */
 	DescOwn		= (1 << 31), /* Descriptor is owned by NIC */
@@ -190,8 +206,8 @@
 	IPCS		= (1 << 18), /* Calculate IP checksum */
 	UDPCS		= (1 << 17), /* Calculate UDP/IP checksum */
 	TCPCS		= (1 << 16), /* Calculate TCP/IP checksum */
-	TxVlanTag	= (1 << 17), /* Add VLAN tag */
-	RxVlanTagged	= (1 << 16), /* Rx VLAN tag available */
+	TxVlanTag	= (1 << 1), /* Add VLAN tag */
+	RxVlanTagged	= (1), /* Rx VLAN tag available */
 	IPFail		= (1 << 15), /* IP checksum failed */
 	UDPFail		= (1 << 14), /* UDP/IP checksum failed */
 	TCPFail		= (1 << 13), /* TCP/IP checksum failed */
@@ -293,6 +309,12 @@
 	LANWake         = (1 << 1),  /* Enable LANWake signal */
 	PMEStatus	= (1 << 0),  /* PME status can be reset by PCI RST# */
 
+	/* mii register */
+	MDO				= (1 << 26),  /* The mdio pin output */
+	MDI				= (1 << 25),  /* the mdio pin input */
+	MDC				= (1 << 24),  /* the mdio pin clock pin */
+	MDM				= (1 << 27),
+
 	cp_norx_intr_mask = PciErr | LinkChg | TxOK | TxErr | TxEmpty,
 	cp_rx_intr_mask = RxOK | RxErr | RxEmpty | RxFIFOOvr,
 	cp_intr_mask = cp_rx_intr_mask | cp_norx_intr_mask,
@@ -304,7 +326,11 @@
 
 struct cp_desc {
 	u32		opts1;
-	u32		opts2;
+/*
+ * We break this filed into 2 16 bit fields to get around endiannes issues
+ */
+	u16		vtag;
+	u16		opts2;
 	u64		addr;
 };
 
@@ -398,6 +424,10 @@
 static struct pci_device_id cp_pci_tbl[] = {
 	{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+#if defined(CONFIG_MTD_NETtel) || defined(CONFIG_SH_SECUREEDGE5410)
+	{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8129,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+#endif
 	{ PCI_VENDOR_ID_TTTECH, PCI_DEVICE_ID_TTTECH_MC322,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
 	{ },
@@ -423,6 +453,14 @@
 	{ "rx_frags" },
 };
 
+#ifdef FAST_POLL
+static void
+fast_poll_8139cp(void *arg)
+{
+	static void cp_interrupt (int irq,void *dev_instance,struct pt_regs *regs);
+	cp_interrupt (-1, arg, NULL);
+}
+#endif
 
 #if CP_VLAN_TAG_USED
 static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
@@ -454,15 +492,25 @@
 static inline void cp_set_rxbufsize (struct cp_private *cp)
 {
 	unsigned int mtu = cp->dev->mtu;
-	
-	if (mtu > ETH_DATA_LEN)
+
+	/* 
+	We need to ensure that the DMA buffers are bigger
+	than the rx fifo of the 8139C+, otherwise the DMA engine on
+	the chip can get confused and we cease to be able to receive
+	packets :-(.
+
+	It seems to get confused if the size of the packet we are receiving
+	is the same size of as the DMA buffer.
+	*/
+	if (mtu > (CP_RX_FIFO_SZ + CP_RX_DMA_MARGIN)) {
 		/* MTU + ethernet header + FCS + optional VLAN tag */
 		cp->rx_buf_sz = mtu + ETH_HLEN + 8;
-	else
-		cp->rx_buf_sz = PKT_BUF_SZ;
+	} else {
+		cp->rx_buf_sz = (CP_RX_FIFO_SZ + CP_RX_DMA_MARGIN);
+	}
 }
 
-static inline void cp_rx_skb (struct cp_private *cp, struct sk_buff *skb,
+static inline int cp_rx_skb (struct cp_private *cp, struct sk_buff *skb,
 			      struct cp_desc *desc)
 {
 	skb->protocol = eth_type_trans (skb, cp->dev);
@@ -471,13 +519,26 @@
 	cp->net_stats.rx_bytes += skb->len;
 	cp->dev->last_rx = jiffies;
 
+#ifdef FAST_POLL
+
+#if CP_VLAN_TAG_USED
+	if (cp->vlgrp && (le16_to_cpu(desc->opts2) & RxVlanTagged)) {
+		return vlan_hwaccel_rx(skb, cp->vlgrp,
+					 be16_to_cpu(desc->vtag));
+
+	} else
+#endif
+		return netif_rx(skb);
+#else
 #if CP_VLAN_TAG_USED
-	if (cp->vlgrp && (desc->opts2 & RxVlanTagged)) {
-		vlan_hwaccel_receive_skb(skb, cp->vlgrp,
-					 be16_to_cpu(desc->opts2 & 0xffff));
+	if (cp->vlgrp && (le16_to_cpu(desc->opts2) & RxVlanTagged)) {
+		return vlan_hwaccel_receive_skb(skb, cp->vlgrp,
+					 be16_to_cpu(desc->vtag));
+
 	} else
 #endif
-		netif_receive_skb(skb);
+		return netif_receive_skb(skb);
+#endif
 }
 
 static void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail,
@@ -513,16 +574,32 @@
 	return 0;
 }
 
+#ifdef FAST_POLL
+static void cp_rx (struct cp_private *cp)
+#else
 static int cp_rx_poll (struct net_device *dev, int *budget)
+#endif
 {
+#ifdef FAST_POLL
+	unsigned rx_work = 16;
+#else
 	struct cp_private *cp = netdev_priv(dev);
-	unsigned rx_tail = cp->rx_tail;
 	unsigned rx_work = dev->quota;
 	unsigned rx;
+#endif
+	unsigned rx_tail = cp->rx_tail;
+	int cng_level;
+
+#ifdef CONFIG_LEDMAN
+	ledman_cmd(LEDMAN_CMD_SET, (cp->dev->name[3] == '0') ?  LEDMAN_LAN1_RX :
+			((cp->dev->name[3] == '1') ?  LEDMAN_LAN2_RX : LEDMAN_LAN3_RX));
+#endif
 
+#ifndef FAST_POLL
 rx_status_loop:
 	rx = 0;
 	cpw16(IntrStatus, cp_rx_intr_mask);
+#endif
 
 	while (1) {
 		u32 status, len;
@@ -537,8 +614,19 @@
 
 		desc = &cp->rx_ring[rx_tail];
 		status = le32_to_cpu(desc->opts1);
-		if (status & DescOwn)
+		if (status & DescOwn) {
+#if 0
+			/* Sometimes we get an interrupt, but the descriptor
+			 * doesnt have DescOwn cleared yet, so wait a bit and
+			 * try again. */
+			if (rx_work == 99) {
+				cp->net_stats.rx_fifo_errors++;
+				udelay(20);
+				continue;
+			}
+#endif
 			break;
+		}
 
 		len = (status & 0x1fff) - 4;
 		mapping = cp->rx_skb[rx_tail].mapping;
@@ -552,11 +640,13 @@
 			cp_rx_err_acct(cp, rx_tail, status, len);
 			cp->net_stats.rx_dropped++;
 			cp->cp_stats.rx_frags++;
+			cng_level = NET_RX_SUCCESS;
 			goto rx_next;
 		}
 
 		if (status & (RxError | RxErrFIFO)) {
 			cp_rx_err_acct(cp, rx_tail, status, len);
+			cng_level = NET_RX_SUCCESS;
 			goto rx_next;
 		}
 
@@ -568,6 +658,7 @@
 		new_skb = dev_alloc_skb (buflen);
 		if (!new_skb) {
 			cp->net_stats.rx_dropped++;
+			cng_level = NET_RX_DROP;
 			goto rx_next;
 		}
 
@@ -591,11 +682,13 @@
 				       buflen, PCI_DMA_FROMDEVICE);
 		cp->rx_skb[rx_tail].skb = new_skb;
 
-		cp_rx_skb(cp, skb, desc);
+		cng_level = cp_rx_skb(cp, skb, desc);
+#ifndef FAST_POLL
 		rx++;
-
+#endif
 rx_next:
 		cp->rx_ring[rx_tail].opts2 = 0;
+		cp->rx_ring[rx_tail].vtag = 0;
 		cp->rx_ring[rx_tail].addr = cpu_to_le64(mapping);
 		if (rx_tail == (CP_RX_RING_SIZE - 1))
 			desc->opts1 = cpu_to_le32(DescOwn | RingEnd |
@@ -604,19 +697,26 @@
 			desc->opts1 = cpu_to_le32(DescOwn | cp->rx_buf_sz);
 		rx_tail = NEXT_RX(rx_tail);
 
+		if (cng_level == NET_RX_DROP || cng_level == NET_RX_CN_HIGH
+				|| cng_level == NET_RX_CN_MOD) {
+			rx_work = 0;
+			break;
+		}
+
 		if (!rx_work--)
 			break;
 	}
 
 	cp->rx_tail = rx_tail;
 
+#ifndef FAST_POLL
 	dev->quota -= rx;
 	*budget -= rx;
 
 	/* if we did not reach work limit, then we're done with
 	 * this round of polling
 	 */
-	if (rx_work) {
+	if (rx_work > 0) {
 		if (cpr16(IntrStatus) & cp_rx_intr_mask)
 			goto rx_status_loop;
 
@@ -629,6 +729,7 @@
 	}
 
 	return 1;		/* not done */
+#endif
 }
 
 static irqreturn_t
@@ -650,7 +751,11 @@
 		printk(KERN_DEBUG "%s: intr, status %04x cmd %02x cpcmd %04x\n",
 		        dev->name, status, cpr8(Cmd), cpr16(CpCmd));
 
+#ifdef FAST_POLL
+	cpw16_f(IntrStatus, status);
+#else
 	cpw16(IntrStatus, status & ~cp_rx_intr_mask);
+#endif
 
 	spin_lock(&cp->lock);
 
@@ -662,10 +767,14 @@
 	}
 
 	if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
+#ifdef FAST_POLL
+		cp_rx(cp);
+#else
 		if (netif_rx_schedule_prep(dev)) {
 			cpw16_f(IntrMask, cp_norx_intr_mask);
 			__netif_rx_schedule(dev);
 		}
+#endif
 
 	if (status & (TxOK | TxErr | TxEmpty | SWInt))
 		cp_tx(cp);
@@ -693,6 +802,11 @@
 	unsigned tx_head = cp->tx_head;
 	unsigned tx_tail = cp->tx_tail;
 
+#ifdef CONFIG_LEDMAN
+	ledman_cmd(LEDMAN_CMD_SET, (cp->dev->name[3] == '0') ?  LEDMAN_LAN1_TX :
+			((cp->dev->name[3] == '1') ?  LEDMAN_LAN2_TX : LEDMAN_LAN3_TX));
+#endif
+
 	while (tx_tail != tx_head) {
 		struct sk_buff *skb;
 		u32 status;
@@ -751,6 +865,7 @@
 	unsigned entry;
 	u32 eor;
 #if CP_VLAN_TAG_USED
+	int do_vlan = 0;
 	u32 vlan_tag = 0;
 #endif
 
@@ -766,8 +881,10 @@
 	}
 
 #if CP_VLAN_TAG_USED
-	if (cp->vlgrp && vlan_tx_tag_present(skb))
-		vlan_tag = TxVlanTag | cpu_to_be16(vlan_tx_tag_get(skb));
+	if (cp->vlgrp && vlan_tx_tag_present(skb)) {
+		vlan_tag = vlan_tx_tag_get(skb);
+		do_vlan = 1;
+	}
 #endif
 
 	entry = cp->tx_head;
@@ -779,7 +896,7 @@
 
 		len = skb->len;
 		mapping = pci_map_single(cp->pdev, skb->data, len, PCI_DMA_TODEVICE);
-		CP_VLAN_TX_TAG(txd, vlan_tag);
+		CP_VLAN_TX_TAG(txd, vlan_tag, do_vlan);
 		txd->addr = cpu_to_le64(mapping);
 		wmb();
 
@@ -851,7 +968,7 @@
 				ctrl |= LastFrag;
 
 			txd = &cp->tx_ring[entry];
-			CP_VLAN_TX_TAG(txd, vlan_tag);
+			CP_VLAN_TX_TAG(txd, vlan_tag, do_vlan);
 			txd->addr = cpu_to_le64(mapping);
 			wmb();
 
@@ -865,7 +982,7 @@
 		}
 
 		txd = &cp->tx_ring[first_entry];
-		CP_VLAN_TX_TAG(txd, vlan_tag);
+		CP_VLAN_TX_TAG(txd, vlan_tag, do_vlan);
 		txd->addr = cpu_to_le64(first_mapping);
 		wmb();
 
@@ -1052,7 +1169,9 @@
 
 	cpw16(MultiIntr, 0);
 
+#ifndef FAST_POLL
 	cpw16_f(IntrMask, cp_intr_mask);
+#endif
 
 	cpw8_f(Cfg9346, Cfg9346_Lock);
 }
@@ -1077,6 +1196,7 @@
 		cp->rx_skb[i].frag = 0;
 
 		cp->rx_ring[i].opts2 = 0;
+		cp->rx_ring[i].vtag = 0;
 		cp->rx_ring[i].addr = cpu_to_le64(cp->rx_skb[i].mapping);
 		if (i == (CP_RX_RING_SIZE - 1))
 			cp->rx_ring[i].opts1 =
@@ -1174,9 +1294,13 @@
 
 	cp_init_hw(cp);
 
+#ifndef FAST_POLL
 	rc = request_irq(dev->irq, cp_interrupt, SA_SHIRQ, dev->name, dev);
 	if (rc)
 		goto err_out_hw;
+#else
+	fast_timer_add(fast_poll_8139cp, dev);
+#endif
 
 	netif_carrier_off(dev);
 	mii_check_media(&cp->mii_if, netif_msg_link(cp), TRUE);
@@ -1184,7 +1308,9 @@
 
 	return 0;
 
+#ifndef FAST_POLL
 err_out_hw:
+#endif
 	cp_stop_hw(cp);
 	cp_free_rings(cp);
 	return rc;
@@ -1207,8 +1333,12 @@
 
 	spin_unlock_irqrestore(&cp->lock, flags);
 
+#ifndef FAST_POLL
 	synchronize_irq();
 	free_irq(dev->irq, dev);
+#else
+	fast_timer_remove(fast_poll_8139cp, dev);
+#endif
 
 	cp_free_rings(cp);
 	return 0;
@@ -1260,12 +1390,73 @@
 	0
 };
 
+
+#ifdef CONFIG_8139CP_EXTERNAL_PHY
+
+/* MII serial management: mostly bogus for now. */
+/* Read and write the MII management registers using software-generated
+   serial MDIO protocol.
+   The maximum data clock rate is 25 Mhz.  The minimum timing is usually
+   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
+   "overclocking" issues. */
+#define mdio_delay()	cpr32(MIIRegister)
+
+#define MAX_PHYID (31)
+
+/* Syncronize the MII management interface by shifting 32 one bits out. */
+static void mdio_cp_sync (struct cp_private *cp) {
+	int i;
+
+	for (i = 32; i >= 0; i--) {
+		cpw32 (MIIRegister, MDO|MDM);
+		mdio_delay ();
+		cpw32 (MIIRegister, MDO | MDC | MDM);
+		mdio_delay ();
+	}
+}
+#endif
+
+
 static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
 	struct cp_private *cp = netdev_priv(dev);
 
+#ifdef CONFIG_8139CP_EXTERNAL_PHY
+	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
+	int i;
+	int retval = 0;
+
+	/* The CP can only use 32 external PHYs so try the internal */
+	if (phy_id <= MAX_PHYID) {
+		mdio_cp_sync (cp);
+		/* Shift the read command bits out. */
+		for (i = 15; i >= 0; i--) {
+			int dataval = (mii_cmd & (1 << i)) ? MDO : 0;
+
+			cpw32 (MIIRegister, dataval | MDM);
+			mdio_delay ();
+			cpw32 (MIIRegister, dataval | MDC | MDM);
+			mdio_delay ();
+		}
+
+		/* Read the two transition, 16 data, and wire-idle bits. */
+		for (i = 19; i > 0; i--) {
+			cpw32 (MIIRegister, 0);
+			mdio_delay ();
+			retval = (retval << 1) | ((cpr32 (MIIRegister) & MDI) ? 1 : 0);
+			cpw32 (MIIRegister, MDC);
+			mdio_delay ();
+		}
+		return (retval >> 1) & 0xffff;
+	} else {
+#endif
+
 	return location < 8 && mii_2_8139_map[location] ?
 	       readw(cp->regs + mii_2_8139_map[location]) : 0;
+#ifdef CONFIG_8139CP_EXTERNAL_PHY
+	}
+#endif
+
 }
 
 
@@ -1273,13 +1464,42 @@
 		       int value)
 {
 	struct cp_private *cp = netdev_priv(dev);
+#ifdef CONFIG_8139CP_EXTERNAL_PHY
+	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
+	int i;
+
+	/* If we select a valid internal phy */
+	if (phy_id <= MAX_PHYID) {
+		mdio_cp_sync (cp);
 
+
+		/* Shift the command bits out. */
+		for (i = 31; i >= 0; i--) {
+			int dataval =
+				(mii_cmd & (1 << i)) ? MDO : 0;
+			cpw32 (MIIRegister, dataval | MDM);
+			mdio_delay ();
+			cpw32 (MIIRegister, dataval | MDC | MDM);
+			mdio_delay ();
+		}
+		/* Clear out extra bits. */
+		for (i = 2; i > 0; i--) {
+			cpw32 (MIIRegister, 0|MDM);
+			mdio_delay ();
+			cpw32 (MIIRegister, MDC|MDM);
+			mdio_delay ();
+		}
+	} else {
+#endif
 	if (location == 0) {
 		cpw8(Cfg9346, Cfg9346_Unlock);
 		cpw16(BasicModeCtrl, value);
 		cpw8(Cfg9346, Cfg9346_Lock);
 	} else if (location < 8 && mii_2_8139_map[location])
 		cpw16(mii_2_8139_map[location], value);
+#ifdef CONFIG_8139CP_EXTERNAL_PHY
+	}
+#endif
 }
 
 /* Set the ethtool Wake-on-LAN settings */
@@ -1648,7 +1868,9 @@
 	pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
 
 	if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
-	    pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pci_rev < 0x20) {
+	    	(pdev->device == PCI_DEVICE_ID_REALTEK_8139 ||
+			 	pdev->device == PCI_DEVICE_ID_REALTEK_8129)
+			 && pci_rev < 0x20) {
 		printk(KERN_ERR PFX "pci dev %s (id %04x:%04x rev %02x) is not an 8139C+ compatible chip\n",
 		       pci_name(pdev), pdev->vendor, pdev->device, pci_rev);
 		printk(KERN_ERR PFX "Try the \"8139too\" driver instead.\n");
@@ -1670,7 +1892,7 @@
 	cp->mii_if.mdio_read = mdio_read;
 	cp->mii_if.mdio_write = mdio_write;
 	cp->mii_if.phy_id = CP_INTERNAL_PHY;
-	cp->mii_if.phy_id_mask = 0x1f;
+	cp->mii_if.phy_id_mask = 0x3f;
 	cp->mii_if.reg_num_mask = 0x1f;
 	cp_set_rxbufsize(cp);
 
@@ -1730,11 +1952,17 @@
 
 	cp_stop_hw(cp);
 
+#if defined(CONFIG_MTD_NETtel) || defined(CONFIG_SH_SECUREEDGE5410) || defined(CONFIG_MTD_SNAPGEODE)
+	/* Don't rely on the eeprom, get MAC from chip. */
+	for (i = 0; (i < 6); i++)
+		dev->dev_addr[i] = readb(regs + MAC0 + i);
+#else
 	/* read MAC address from EEPROM */
 	addr_len = read_eeprom (regs, 0, 8) == 0x8129 ? 8 : 6;
 	for (i = 0; i < 3; i++)
 		((u16 *) (dev->dev_addr))[i] =
 		    le16_to_cpu (read_eeprom (regs, i + 7, addr_len));
+#endif
 
 	dev->open = cp_open;
 	dev->stop = cp_close;
@@ -1742,8 +1970,10 @@
 	dev->hard_start_xmit = cp_start_xmit;
 	dev->get_stats = cp_get_stats;
 	dev->do_ioctl = cp_ioctl;
+#ifndef FAST_POLL
 	dev->poll = cp_rx_poll;
 	dev->weight = 16;	/* arbitrary? from NAPI_HOWTO.txt. */
+#endif
 #ifdef BROKEN
 	dev->change_mtu = cp_change_mtu;
 #endif
@@ -1783,6 +2013,15 @@
 	/* enable busmastering and memory-write-invalidate */
 	pci_set_master(pdev);
 
+#ifdef CONFIG_8139CP_EXTERNAL_PHY
+	{
+		/* Check if external phy exists. */
+		int mii_status = mdio_read(dev, CONFIG_8139CP_PHY_NUM, 1);
+		if (mii_status != 0xffff  &&  mii_status != 0x0000)
+			cp->mii_if.phy_id = CONFIG_8139CP_PHY_NUM;
+	}
+#endif
+
 	if (cp->wol_enabled) cp_set_d3_state (cp);
 
 	return 0;
@@ -1886,6 +2125,8 @@
 #ifdef MODULE
 	printk("%s", version);
 #endif
+	printk("%s", version);
+	proc_net_create("8139cp", 0, dev_get_info);
 	return pci_module_init (&cp_driver);
 }
 
@@ -1894,5 +2135,154 @@
 	pci_unregister_driver (&cp_driver);
 }
 
+
+#ifdef CONFIG_PROC_FS
+
+/*
+ * Called from the PROCfs module
+ *
+ */
+static int dev_get_info(char *buffer, char **start, off_t offset, int length)
+{
+	int len = 0;
+	struct net_device *dev;
+
+	/*
+	 * Lock the interface
+	 */
+	read_lock(&dev_base_lock);
+
+	len = sprintf(buffer, "%s\n", version);
+
+	for (dev = dev_base; dev != NULL; dev = dev->next) {
+		struct cp_private *cp;
+		int i;
+		if (dev->stop != cp_close) {
+			continue;
+		}
+		if (!(dev->flags & IFF_UP))
+			continue;
+
+
+		/* It's one of ours - check it out */
+		cp = dev->priv;
+		len += sprintf(buffer+len, "%s %s\n", dev->name,
+			dev->flags & IFF_UP?"UP":"DOWN");
+
+		len += sprintf(buffer + len, "Some interesting registers:\n");
+
+		len += sprintf(buffer + len, "IMR -       %04x\n",
+			cpr16(IntrMask)
+			);
+		len += sprintf(buffer + len, "ISR -       %04x\n",
+			cpr16(IntrStatus)
+			);
+
+		len += sprintf(buffer + len, "TCR -       %08x\n",
+			cpr32(TxConfig)
+			);
+
+		len += sprintf(buffer + len, "RCR -       %08x\n",
+			cpr32(RxConfig)
+			);
+
+		len += sprintf(buffer + len, "RxMissed -  %06x\n",
+			cpr32(RxMissed)&0xffffff
+			);
+
+		len += sprintf(buffer + len, "ANLPAR -    %04x\n",
+			cpr16(NWayLPAR)
+			);
+
+		len += sprintf(buffer + len, "FCSC -      %04x\n",
+			cpr16(0x6E)
+			);
+
+		len += sprintf(buffer + len, "DIS -       %04x\n",
+			cpr16(0x6C)
+			);
+
+		len += sprintf(buffer + len, "RXErr -     %04x\n",
+			cpr16(0x72)
+			);
+
+		len += sprintf(buffer + len, "RX Descriptor ring:\n");
+		len += sprintf(buffer + len, "opts1    vtag  opts2 addr[0]   addr[1]\n");
+
+		/* Output all of the rx descriptors */
+		for (i = 0;cp && cp->rx_ring && i < CP_RX_RING_SIZE;i++) {
+			len += sprintf(buffer + len, "%8x %4x %4x %8x %8x\n",
+				cp->rx_ring[i].opts1,
+				cp->rx_ring[i].vtag,
+				cp->rx_ring[i].opts2,
+				cp->rx_ring[i].addr & (0xffffffff),
+				cp->rx_ring[i].addr >> 32
+			);
+		}
+
+		len += sprintf(buffer + len, "RX Errors:\n");
+
+		len += sprintf(buffer + len, "Dropped - %d\n",
+			cp->net_stats.rx_dropped
+			);
+
+		len += sprintf(buffer + len, "Error -   %d\n",
+			cp->net_stats.rx_errors
+			);
+		
+		len += sprintf(buffer + len, "length -  %d\n",
+			cp->net_stats.rx_length_errors
+			);
+
+		len += sprintf(buffer + len, "over -    %d\n",
+			cp->net_stats.rx_over_errors
+			);
+
+		len += sprintf(buffer + len, "crc -     %d\n",
+			cp->net_stats.rx_crc_errors
+			);
+
+		len += sprintf(buffer + len, "frame -   %d\n",
+			cp->net_stats.rx_frame_errors
+			);
+
+		len += sprintf(buffer + len, "fifo -    %d\n",
+			cp->net_stats.rx_fifo_errors
+			);
+
+		len += sprintf(buffer + len, "missed -  %d\n",
+			cp->net_stats.rx_missed_errors
+			);
+
+		len += sprintf(buffer + len, "Frags -   %d\n",
+			cp->cp_stats.rx_frags
+			);
+
+		len += sprintf(buffer + len, "\n");
+	}
+
+	goto leave;
+
+leave:
+	/*
+	 * free the lock
+	 */
+	read_unlock(&dev_base_lock);
+
+	if (offset >= len) {
+		*start = buffer;
+		return 0;
+	}
+	*start = buffer + offset;
+	len -= offset;
+
+	if (len > length)
+		len = length;
+	if (len < 0)
+		len = 0;
+	return len;
+}
+#endif
+
 module_init(cp_init);
 module_exit(cp_exit);
diff -urN linux-2.4.29/drivers/net/8139too.c linux-2.4.29-uc1/drivers/net/8139too.c
--- linux-2.4.29/drivers/net/8139too.c	2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/8139too.c	2005-06-14 02:12:12.000000000 +0100
@@ -113,6 +113,16 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
+#ifdef CONFIG_LEDMAN
+#include <linux/ledman.h>
+#endif
+
+#ifdef CONFIG_FAST_TIMER
+#define FAST_POLL 1
+#include <linux/fast_timer.h>
+static void fast_poll_8139too(void *arg);
+#endif
+
 #define RTL8139_DRIVER_NAME   DRV_NAME " Fast Ethernet driver " DRV_VERSION
 #define PFX DRV_NAME ": "
 
@@ -223,6 +233,10 @@
 #define RTL8129_CAPS	HAS_MII_XCVR
 #define RTL8139_CAPS	HAS_CHIP_XCVR|HAS_LNK_CHNG
 
+#ifdef CONFIG_8139TOO_8129
+#define CONFIG_8139TOO_EXTERNAL_PHY
+#endif
+
 typedef enum {
 	RTL8139 = 0,
 	RTL8129,
@@ -260,7 +274,7 @@
 	{0x1743, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
 	{0x021b, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
 
-#ifdef CONFIG_SH_SECUREEDGE5410
+#if defined(CONFIG_MTD_NETtel) || defined(CONFIG_SH_SECUREEDGE5410)
 	/* Bogus 8139 silicon reports 8129 without external PROM :-( */
 	{0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
 #endif
@@ -327,6 +341,7 @@
 	CSCR = 0x74,		/* Chip Status and Configuration Register. */
 	PARA78 = 0x78,
 	PARA7c = 0x7c,		/* Magic transceiver parameter register. */
+	PARA80 = 0x80,
 	Config5 = 0xD8,		/* absent on RTL-8139A */
 };
 
@@ -592,6 +607,9 @@
 	int time_to_die;
 	struct mii_if_info mii;
 	unsigned int regs_len;
+#ifdef FAST_POLL
+	unsigned int rx_poll_incomplete;
+#endif
 };
 
 MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>");
@@ -609,7 +627,16 @@
 MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
 MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
 
+#if !defined(CONFIG_MTD_NETtel) && !defined(CONFIG_SH_SECUREEDGE5410)
 static int read_eeprom (void *ioaddr, int location, int addr_len);
+#endif
+#if 0
+static int  read_eeprom (void *ioaddr, int location, int addr_len);
+
+void serial_eeprom_write(char *ioaddr, int location, int addr_len,
+		int data);
+#endif
+
 static int rtl8139_open (struct net_device *dev);
 static int mdio_read (struct net_device *dev, int phy_id, int location);
 static void mdio_write (struct net_device *dev, int phy_id, int location,
@@ -746,6 +773,10 @@
 			break;
 		udelay (10);
 	}
+#if 1
+	if (i <= 0)
+		printk("%s(%d): chip reset timeout??\n", __FILE__, __LINE__);
+#endif
 }
 
 
@@ -923,10 +954,13 @@
 {
 	struct net_device *dev = NULL;
 	struct rtl8139_private *tp;
-	int i, addr_len, option;
+	int i, option;
 	void *ioaddr;
 	static int board_idx = -1;
 	u8 pci_rev;
+#if !defined(CONFIG_MTD_NETtel) && !defined(CONFIG_SH_SECUREEDGE5410)
+	int addr_len;
+#endif
 
 	assert (pdev != NULL);
 	assert (ent != NULL);
@@ -963,10 +997,29 @@
 	ioaddr = tp->mmio_addr;
 	assert (ioaddr != NULL);
 
+#if defined(CONFIG_MTD_NETtel) || defined(CONFIG_SH_SECUREEDGE5410)
+	/* Don't rely on the eeprom, get MAC from chip. */
+	for (i = 0; (i < 6); i++)
+		dev->dev_addr[i] = readb(ioaddr + MAC0 + i);
+#else
 	addr_len = read_eeprom (ioaddr, 0, 8) == 0x8129 ? 8 : 6;
 	for (i = 0; i < 3; i++)
 		((u16 *) (dev->dev_addr))[i] =
 		    le16_to_cpu (read_eeprom (ioaddr, i + 7, addr_len));
+#endif
+
+#if 0
+
+	printk(KERN_INFO "****Setting eeprom to 8139 - %x\n", 
+			read_eeprom(ioaddr, 2, 6));
+	if (read_eeprom(ioaddr, 2, 16) != cpu_to_le16(0x8139)) {
+		printk(KERN_INFO "****Setting eeprom to 8129\n");
+		serial_eeprom_write(ioaddr, 2, 6, cpu_to_le16(0x8139));
+		printk(KERN_INFO "new eeprom - 0x%x\n", read_eeprom(ioaddr, 2, 16));
+	} else {
+		printk(KERN_INFO "\neeprom already 8129\n");
+	}
+#endif
 
 	/* The Rtl8139-specific entries in the device structure. */
 	dev->open = rtl8139_open;
@@ -1028,6 +1081,7 @@
 	/* Find the connected MII xcvrs.
 	   Doing this in open() would allow detecting external xcvrs later, but
 	   takes too much time. */
+	tp->phys[0] = 32;
 #ifdef CONFIG_8139TOO_8129
 	if (tp->drv_flags & HAS_MII_XCVR) {
 		int phy, phy_idx = 0;
@@ -1047,9 +1101,21 @@
 				   dev->name);
 			tp->phys[0] = 32;
 		}
-	} else
+	}
+#elif defined(CONFIG_8139TOO_EXTERNAL_PHY)
+	{
+		/* Check if external phy exists. */
+		int mii_status = mdio_read(dev, CONFIG_8139TOO_PHY_NUM, 1);
+		if (mii_status != 0xffff  &&  mii_status != 0x0000) {
+			tp->phys[0] = CONFIG_8139TOO_PHY_NUM;
+			printk(KERN_INFO "%s: Using external PHY %d\n",
+					dev->name, tp->phys[0]);
+		} else {
+			printk(KERN_INFO "%s: External PHY not found\n",
+					dev->name);
+		}
+	}
 #endif
-		tp->phys[0] = 32;
 	tp->mii.phy_id = tp->phys[0];
 
 	/* The lower four bits are the media type. */
@@ -1104,6 +1170,7 @@
 }
 
 
+#if !defined(CONFIG_MTD_NETtel) && !defined(CONFIG_SH_SECUREEDGE5410)
 /* Serial EEPROM section. */
 
 /*  EEPROM_Ctrl bits. */
@@ -1115,6 +1182,10 @@
 #define EE_DATA_READ	0x01	/* EEPROM chip data out. */
 #define EE_ENB			(0x80 | EE_CS)
 
+
+#define EE_TWP_MAX	(15000)
+
+
 /* Delay between EEPROM clock transitions.
    No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
  */
@@ -1125,6 +1196,8 @@
 #define EE_WRITE_CMD	(5)
 #define EE_READ_CMD		(6)
 #define EE_ERASE_CMD	(7)
+#define EE_WEN_CMD	(4)
+#define EE_WDS_CMD	(4)
 
 static int __devinit read_eeprom (void *ioaddr, int location, int addr_len)
 {
@@ -1164,6 +1237,7 @@
 
 	return retval;
 }
+#endif
 
 /* MII serial management: mostly bogus for now. */
 /* Read and write the MII management registers using software-generated
@@ -1171,6 +1245,10 @@
    The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
    met by back-to-back PCI I/O cycles, but we insert a delay to avoid
    "overclocking" issues. */
+
+#ifdef CONFIG_8139TOO_8129
+
+#define MDIO_REG		Config4
 #define MDIO_DIR		0x80
 #define MDIO_DATA_OUT	0x04
 #define MDIO_DATA_IN	0x02
@@ -1178,7 +1256,26 @@
 #define MDIO_WRITE0 (MDIO_DIR)
 #define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT)
 
-#define mdio_delay(mdio_addr)	readb(mdio_addr)
+#define mdio_delay(mdio_addr)		readb(mdio_addr)
+#define mdio_out(val, mdio_addr)	writeb((val), (mdio_addr))
+#define mdio_in(mdio_addr)		readb(mdio_addr)
+
+#elif defined(CONFIG_8139TOO_EXTERNAL_PHY)
+
+/* Hack in the MII support for C+ chips. */
+#define MDIO_REG		0xFC
+#define MDIO_DIR		(1 << 27)
+#define MDIO_DATA_OUT		(1 << 26)
+#define MDIO_DATA_IN		(1 << 25)
+#define MDIO_CLK		(1 << 24)
+#define MDIO_WRITE0 (MDIO_DIR)
+#define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT)
+
+#define mdio_delay(mdio_addr)		readl(mdio_addr)
+#define mdio_out(val, mdio_addr)	writel((val), (mdio_addr))
+#define mdio_in(mdio_addr)		readl(mdio_addr)
+
+#endif
 
 
 static char mii_2_8139_map[8] = {
@@ -1193,16 +1290,16 @@
 };
 
 
-#ifdef CONFIG_8139TOO_8129
+#ifdef CONFIG_8139TOO_EXTERNAL_PHY
 /* Syncronize the MII management interface by shifting 32 one bits out. */
 static void mdio_sync (void *mdio_addr)
 {
 	int i;
 
 	for (i = 32; i >= 0; i--) {
-		writeb (MDIO_WRITE1, mdio_addr);
+		mdio_out (MDIO_WRITE1, mdio_addr);
 		mdio_delay (mdio_addr);
-		writeb (MDIO_WRITE1 | MDIO_CLK, mdio_addr);
+		mdio_out (MDIO_WRITE1 | MDIO_CLK, mdio_addr);
 		mdio_delay (mdio_addr);
 	}
 }
@@ -1212,8 +1309,8 @@
 {
 	struct rtl8139_private *tp = dev->priv;
 	int retval = 0;
-#ifdef CONFIG_8139TOO_8129
-	void *mdio_addr = tp->mmio_addr + Config4;
+#ifdef CONFIG_8139TOO_EXTERNAL_PHY
+	void *mdio_addr = tp->mmio_addr + MDIO_REG;
 	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
 	int i;
 #endif
@@ -1223,24 +1320,24 @@
 		    readw (tp->mmio_addr + mii_2_8139_map[location]) : 0;
 	}
 
-#ifdef CONFIG_8139TOO_8129
+#ifdef CONFIG_8139TOO_EXTERNAL_PHY
 	mdio_sync (mdio_addr);
 	/* Shift the read command bits out. */
 	for (i = 15; i >= 0; i--) {
 		int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;
 
-		writeb (MDIO_DIR | dataval, mdio_addr);
+		mdio_out (MDIO_DIR | dataval, mdio_addr);
 		mdio_delay (mdio_addr);
-		writeb (MDIO_DIR | dataval | MDIO_CLK, mdio_addr);
+		mdio_out (MDIO_DIR | dataval | MDIO_CLK, mdio_addr);
 		mdio_delay (mdio_addr);
 	}
 
 	/* Read the two transition, 16 data, and wire-idle bits. */
 	for (i = 19; i > 0; i--) {
-		writeb (0, mdio_addr);
+		mdio_out (0, mdio_addr);
 		mdio_delay (mdio_addr);
-		retval = (retval << 1) | ((readb (mdio_addr) & MDIO_DATA_IN) ? 1 : 0);
-		writeb (MDIO_CLK, mdio_addr);
+		retval = (retval << 1) | ((mdio_in (mdio_addr) & MDIO_DATA_IN) ? 1 : 0);
+		mdio_out (MDIO_CLK, mdio_addr);
 		mdio_delay (mdio_addr);
 	}
 #endif
@@ -1253,8 +1350,8 @@
 			int value)
 {
 	struct rtl8139_private *tp = dev->priv;
-#ifdef CONFIG_8139TOO_8129
-	void *mdio_addr = tp->mmio_addr + Config4;
+#ifdef CONFIG_8139TOO_EXTERNAL_PHY
+	void *mdio_addr = tp->mmio_addr + MDIO_REG;
 	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
 	int i;
 #endif
@@ -1270,23 +1367,23 @@
 		return;
 	}
 
-#ifdef CONFIG_8139TOO_8129
+#ifdef CONFIG_8139TOO_EXTERNAL_PHY
 	mdio_sync (mdio_addr);
 
 	/* Shift the command bits out. */
 	for (i = 31; i >= 0; i--) {
 		int dataval =
 		    (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
-		writeb (dataval, mdio_addr);
+		mdio_out (dataval, mdio_addr);
 		mdio_delay (mdio_addr);
-		writeb (dataval | MDIO_CLK, mdio_addr);
+		mdio_out (dataval | MDIO_CLK, mdio_addr);
 		mdio_delay (mdio_addr);
 	}
 	/* Clear out extra bits. */
 	for (i = 2; i > 0; i--) {
-		writeb (0, mdio_addr);
+		mdio_out (0, mdio_addr);
 		mdio_delay (mdio_addr);
-		writeb (MDIO_CLK, mdio_addr);
+		mdio_out (MDIO_CLK, mdio_addr);
 		mdio_delay (mdio_addr);
 	}
 #endif
@@ -1296,19 +1393,24 @@
 static int rtl8139_open (struct net_device *dev)
 {
 	struct rtl8139_private *tp = dev->priv;
-	int retval;
 	void *ioaddr = tp->mmio_addr;
+	
+#ifndef FAST_POLL
+	int retval;
 
 	retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev);
 	if (retval)
 		return retval;
+#endif
 
 	tp->tx_bufs = pci_alloc_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
 					   &tp->tx_bufs_dma);
 	tp->rx_ring = pci_alloc_consistent(tp->pci_dev, RX_BUF_TOT_LEN,
 					   &tp->rx_ring_dma);
 	if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
+#ifndef FAST_POLL
 		free_irq(dev->irq, dev);
+#endif
 
 		if (tp->tx_bufs)
 			pci_free_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
@@ -1336,6 +1438,16 @@
 
 	rtl8139_start_thread(dev);
 
+#ifdef CONFIG_LEDMAN
+	ledman_cmd((RTL_R16 (CSCR) & CSCR_LinkOKBit) ?
+		LEDMAN_CMD_ON : LEDMAN_CMD_OFF,
+		(dev->name[3] == '0') ? LEDMAN_LAN1_LINK : LEDMAN_LAN2_LINK);
+#endif
+
+#ifdef FAST_POLL
+	fast_timer_add(fast_poll_8139too, dev);
+#endif /* FAST_POLL */
+
 	return 0;
 }
 
@@ -1365,9 +1477,12 @@
 
 	/* unlock Config[01234] and BMCR register writes */
 	RTL_W8_F (Cfg9346, Cfg9346_Unlock);
+
+#if !defined(CONFIG_MTD_NETtel) && !defined(CONFIG_SH_SECUREEDGE5410)
 	/* Restore our idea of the MAC address. */
 	RTL_W32_F (MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
 	RTL_W32_F (MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
+#endif
 
 	/* Must enable Tx/Rx before setting transfer thresholds! */
 	RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
@@ -1413,8 +1528,10 @@
 	if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb)))
 		RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
 
+#ifndef FAST_POLL
 	/* Enable all known interrupts by setting the interrupt mask. */
 	RTL_W16 (IntrMask, rtl8139_intr_mask);
+#endif
 
 	netif_start_queue (dev);
 }
@@ -1706,13 +1823,22 @@
 	unsigned int entry;
 	unsigned int len = skb->len;
 
+#ifdef CONFIG_LEDMAN
+	ledman_cmd(LEDMAN_CMD_SET,
+		(dev->name[3] == '0') ? LEDMAN_LAN1_TX : LEDMAN_LAN2_TX);
+#endif
+
 	/* Calculate the next Tx descriptor entry. */
 	entry = tp->cur_tx % NUM_TX_DESC;
 
 	if (likely(len < TX_BUF_SIZE)) {
 		if (len < ETH_ZLEN)
 			memset(tp->tx_buf[entry], 0, ETH_ZLEN);
+#if 0
 		skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
+#else
+		memcpy(tp->tx_buf[entry], skb->data, len);
+#endif
 		dev_kfree_skb(skb);
 	} else {
 		dev_kfree_skb(skb);
@@ -1898,15 +2024,22 @@
 }
 
 static void rtl8139_rx_interrupt (struct net_device *dev,
-				  struct rtl8139_private *tp, void *ioaddr)
+				  struct rtl8139_private *tp, void *ioaddr,
+				  int *boguscnt)
 {
 	unsigned char *rx_ring;
 	u16 cur_rx;
+	int cng_level;
 
 	assert (dev != NULL);
 	assert (tp != NULL);
 	assert (ioaddr != NULL);
 
+#ifdef CONFIG_LEDMAN
+	ledman_cmd(LEDMAN_CMD_SET,
+		(dev->name[3] == '0') ? LEDMAN_LAN1_RX : LEDMAN_LAN2_RX);
+#endif
+
 	rx_ring = tp->rx_ring;
 	cur_rx = tp->cur_rx;
 
@@ -1979,11 +2112,15 @@
 			skb->dev = dev;
 			skb_reserve (skb, 2);	/* 16 byte align the IP fields. */
 
+#if 0
 			eth_copy_and_sum (skb, &rx_ring[ring_offset + 4], pkt_size, 0);
+#else
+			memcpy(skb->data, &rx_ring[ring_offset + 4], pkt_size);
+#endif
 			skb_put (skb, pkt_size);
 
 			skb->protocol = eth_type_trans (skb, dev);
-			netif_rx (skb);
+			cng_level = netif_rx(skb);
 			dev->last_rx = jiffies;
 			tp->stats.rx_bytes += pkt_size;
 			tp->stats.rx_packets++;
@@ -1992,6 +2129,7 @@
 				"%s: Memory squeeze, dropping packet.\n",
 				dev->name);
 			tp->stats.rx_dropped++;
+			cng_level = NET_RX_DROP;
 		}
 
 		cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
@@ -1999,8 +2137,20 @@
 
 		if (RTL_R16 (IntrStatus) & RxAckBits)
 			RTL_W16_F (IntrStatus, RxAckBits);
+
+		if (cng_level == NET_RX_DROP || cng_level == NET_RX_CN_HIGH
+				|| cng_level == NET_RX_CN_MOD)
+			(*boguscnt) = 0;
+		else
+			(*boguscnt)--;
+		if (*boguscnt <= 0)
+			break;
 	}
 
+#ifdef FAST_POLL
+	tp->rx_poll_incomplete = ((RTL_R8 (ChipCmd) & RxBufEmpty) == 0);
+#endif
+
 	DPRINTK ("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
 		 " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
 		 RTL_R16 (RxBufAddr),
@@ -2030,6 +2180,12 @@
 	    (tp->drv_flags & HAS_LNK_CHNG)) {
 		rtl_check_media(dev, 0);
 		status &= ~RxUnderrun;
+#ifdef CONFIG_LEDMAN
+		ledman_cmd((RTL_R16 (CSCR) & CSCR_LinkOKBit) ?
+			LEDMAN_CMD_ON : LEDMAN_CMD_OFF,
+			(dev->name[3] == '0') ?
+					LEDMAN_LAN1_LINK : LEDMAN_LAN2_LINK);
+#endif
 	}
 
 	/* XXX along with rtl8139_rx_err, are we double-counting errors? */
@@ -2042,16 +2198,32 @@
 	if (status & (RxUnderrun | RxFIFOOver))
 		tp->stats.rx_fifo_errors++;
 	if (status & PCIErr) {
-		u16 pci_cmd_status;
+		u16 pci_cmd_status, s;
 		pci_read_config_word (tp->pci_dev, PCI_STATUS, &pci_cmd_status);
 		pci_write_config_word (tp->pci_dev, PCI_STATUS, pci_cmd_status);
+		pci_read_config_word (tp->pci_dev, PCI_STATUS, &s);
 
-		printk (KERN_ERR "%s: PCI Bus error %4.4x.\n",
-			dev->name, pci_cmd_status);
+		printk (KERN_ERR "%s: PCI Bus error %4.4x (%04x).\n",
+			dev->name, pci_cmd_status, s);
+
+		printk (KERN_ERR "%s: reseting interface...\n", dev->name);
+		rtl8139_hw_start (dev);
 	}
 }
 
 
+#ifdef FAST_POLL
+/*
+ *	Fast poll interrupt simulator.
+ */
+static void
+fast_poll_8139too(void *arg)
+{
+	rtl8139_interrupt(0, arg, NULL);
+}
+#endif /* FAST_POLL */
+
+
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
 static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
@@ -2097,13 +2269,20 @@
 				dev->name, status, ackstat, RTL_R16 (IntrStatus));
 
 		if (netif_running (dev) && (status & RxAckBits))
-			rtl8139_rx_interrupt (dev, tp, ioaddr);
+			rtl8139_rx_interrupt (dev, tp, ioaddr, &boguscnt);
+#ifdef FAST_POLL
+		else if (netif_running (dev) && tp->rx_poll_incomplete)
+			rtl8139_rx_interrupt (dev, tp, ioaddr, &boguscnt);
+#endif
 
 		/* Check uncommon events with one test. */
 		if (status & (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
-		  	      RxFIFOOver | RxErr))
+		  	      RxFIFOOver | RxErr)) {
 			rtl8139_weird_interrupt (dev, tp, ioaddr,
 						 status, link_changed);
+			if (status & (RxOverflow | RxFIFOOver))
+				RTL_W16 (IntrStatus, RxOverflow | RxFIFOOver);
+		}
 
 		if (netif_running (dev) && (status & (TxOK | TxErr))) {
 			rtl8139_tx_interrupt (dev, tp, ioaddr);
@@ -2114,13 +2293,19 @@
 		boguscnt--;
 	} while (boguscnt > 0);
 
+	/* Don't clear interrupts for polled mode so that we
+	 * can immediately continue reading on the next poll,
+	 * even if no more packets have been received. */
+#ifndef FAST_POLL
 	if (boguscnt <= 0) {
-		printk (KERN_WARNING "%s: Too much work at interrupt, "
-			"IntrStatus=0x%4.4x.\n", dev->name, status);
+		if (net_ratelimit())
+			printk (KERN_WARNING "%s: Too much work at interrupt, "
+				"IntrStatus=0x%4.4x.\n", dev->name, status);
 
 		/* Clear all interrupt sources. */
 		RTL_W16 (IntrStatus, 0xffff);
 	}
+#endif
 
 	spin_unlock (&tp->lock);
 
@@ -2169,7 +2354,11 @@
 	spin_unlock_irqrestore (&tp->lock, flags);
 
 	synchronize_irq ();		/* racy, but that's ok here */
+#ifndef FAST_POLL
 	free_irq (dev->irq, dev);
+#else
+	fast_timer_remove(fast_poll_8139too, dev);
+#endif
 
 	rtl8139_tx_clear (tp);
 
@@ -2186,6 +2375,11 @@
 	if (rtl_chip_info[tp->chipset].flags & HasHltClk)
 		RTL_W8 (HltClk, 'H');	/* 'R' would leave the clock running. */
 
+#ifdef CONFIG_LEDMAN
+	ledman_cmd(LEDMAN_CMD_OFF,
+		(dev->name[3] == '0') ? LEDMAN_LAN1_LINK : LEDMAN_LAN2_LINK);
+#endif
+
 	return 0;
 }
 
@@ -2554,6 +2748,144 @@
 	pci_unregister_driver (&rtl8139_pci_driver);
 }
 
+#if 0
+void serial_eeprom_write(char *ioaddr, int location, int addr_len,
+		int data)
+/*
+ * ioaddr - the base address of the ethernet device.
+ * location - the location in the serial eeprom to be over written.
+ * addr_len - the length of the address that this eeprom accepts.
+ * data - the data to write to the eeprom.
+ *
+ */
+{
+	int i;
+	char *ee_addr = ioaddr + Cfg9346;
+	int write_cmd = location | (EE_WRITE_CMD << addr_len);
+	int write_en_cmd = 0 | (EE_WEN_CMD << addr_len) | 
+		(0x3 << (addr_len - 2));
+	int write_dis_cmd = 0 | (EE_WDS_CMD << addr_len) |
+		(0x0 << (addr_len - 2));
+
+	/* Allow access to eeprom bits */
+	writeb (EE_ENB & ~EE_CS, ee_addr);
+	eeprom_delay(); 
+
+	/*********
+	 * WRITE ENABLE
+	 */
+ 
+#if DEBUG
+	printf("\nWEN\n");
+#endif
+	/* Initiate WEN command by raising CS */
+	writeb (EE_ENB, ee_addr);
+	eeprom_delay ();
+
+	/* shift out the write enable command */
+	for (i = 4 + addr_len; i >= 0;i --) {
+		int dataval = (write_en_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+#if DEBUG
+		printf("%d", (write_en_cmd & (1 << i)) ? 1 : 0);
+#endif
+		writeb (EE_ENB | dataval, ee_addr);
+		eeprom_delay ();
+		writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+		eeprom_delay ();
+	}
+
+	/* CS low to complete the command. */
+	writeb(EE_ENB & ~EE_CS, ee_addr);
+	eeprom_delay();
+
+	/********
+	 * WRITE COMMAND
+	 */
+
+#if DEBUG
+	printf("\nwrite command\n");
+#endif
+	/* Initiate write by raising CS */
+	writeb(EE_ENB , ee_addr);
+	eeprom_delay();
+
+	/* Shift the write command bits out. */
+	/*
+	 * DEBUG: i >= 0 correct spot wrong val for odds
+	 */
+	for (i = 3 + addr_len; i >= 0; i--) {
+		int dataval = (write_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+#if DEBUG
+		printf("%d", (write_cmd & (1<< i)) ? 1 : 0);
+#endif
+		writeb (EE_ENB | dataval, ee_addr);
+		eeprom_delay ();
+		writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+		eeprom_delay ();
+	}
+
+#if DEBUG
+	printf("\ndata\n");
+#endif
+	/* shift out the actual data. */
+	for (i = 15; i >= 0; i--) {
+		int dataval = (data & (1 << i)) ? EE_DATA_WRITE : 0;
+#if DEBUG
+		printf("%d", (data & (1<< i)) ? 1 : 0);
+#endif
+		writeb(EE_ENB | dataval, ee_addr);
+		eeprom_delay ();
+		writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+		eeprom_delay ();
+	}
+
+	/* 
+	 * Complete the command and then Poll to determine when the write cycle 
+	 * finishes. 
+	 */
+	writeb(EE_ENB & ~EE_CS, ee_addr);
+	eeprom_delay();
+	udelay(EE_TWP_MAX);
+
+	/* Complete command by dropping CS */
+	writeb(EE_ENB & ~EE_CS, ee_addr);
+	eeprom_delay();
+
+	/*******
+	 * WRITE DISABLE
+	 */
+#if DEBUG
+	printf("\nWDS\n");
+#endif
+
+	/* Start write disable command  */
+	writeb (EE_ENB, ee_addr);
+	eeprom_delay ();
+
+	/*
+	 * shift out the write disable command.
+	 */
+	for (i = 4 + addr_len; i >= 0;i --) {
+		int dataval = (write_dis_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+#if DEBUG
+		printf("%d", (write_dis_cmd & (1<< i)) ? 1 : 0);
+#endif
+		writeb (EE_ENB | dataval, ee_addr);
+		eeprom_delay ();
+		writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+		eeprom_delay ();
+	}
+
+	/* Terminate the EEPROM cmd */
+	writeb (~EE_CS, ee_addr);
+	eeprom_delay();
+
+	/* and access. */
+	writeb (~EE_CS, ee_addr);
+	eeprom_delay ();
+}
+#endif
+
 
 module_init(rtl8139_init_module);
 module_exit(rtl8139_cleanup_module);
diff -urN linux-2.4.29/drivers/net/8139toocp.c linux-2.4.29-uc1/drivers/net/8139toocp.c
--- linux-2.4.29/drivers/net/8139toocp.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/8139toocp.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,3178 @@
+/*
+
+	8139too.c: A RealTek RTL-8139 Fast Ethernet driver for Linux.
+
+	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
+	Copyright 2000,2001 Jeff Garzik
+
+	Much code comes from Donald Becker's rtl8139.c driver,
+	versions 1.13 and older.  This driver was originally based
+	on rtl8139.c version 1.07.  Header of rtl8139.c version 1.13:
+
+	-----<snip>-----
+
+        	Written 1997-2001 by Donald Becker.
+		This software may be used and distributed according to the
+		terms of the GNU General Public License (GPL), incorporated
+		herein by reference.  Drivers based on or derived from this
+		code fall under the GPL and must retain the authorship,
+		copyright and license notice.  This file is not a complete
+		program and may only be used when the entire operating
+		system is licensed under the GPL.
+
+		This driver is for boards based on the RTL8129 and RTL8139
+		PCI ethernet chips.
+
+		The author may be reached as becker@scyld.com, or C/O Scyld
+		Computing Corporation 410 Severn Ave., Suite 210 Annapolis
+		MD 21403
+
+		Support and updates available at
+		http://www.scyld.com/network/rtl8139.html
+
+		Twister-tuning table provided by Kinston
+		<shangh@realtek.com.tw>.
+
+	-----<snip>-----
+
+	This software may be used and distributed according to the terms
+	of the GNU General Public License, incorporated herein by reference.
+
+	Contributors:
+
+		Donald Becker - he wrote the original driver, kudos to him!
+		(but please don't e-mail him for support, this isn't his driver)
+
+		Tigran Aivazian - bug fixes, skbuff free cleanup
+
+		Martin Mares - suggestions for PCI cleanup
+
+		David S. Miller - PCI DMA and softnet updates
+
+		Ernst Gill - fixes ported from BSD driver
+
+		Daniel Kobras - identified specific locations of
+			posted MMIO write bugginess
+
+		Gerard Sharp - bug fix, testing and feedback
+
+		David Ford - Rx ring wrap fix
+
+		Dan DeMaggio - swapped RTL8139 cards with me, and allowed me
+		to find and fix a crucial bug on older chipsets.
+
+		Donald Becker/Chris Butterworth/Marcus Westergren -
+		Noticed various Rx packet size-related buglets.
+
+		Santiago Garcia Mantinan - testing and feedback
+
+		Jens David - 2.2.x kernel backports
+
+		Martin Dennett - incredibly helpful insight on undocumented
+		features of the 8139 chips
+
+		Jean-Jacques Michel - bug fix
+		
+		Tobias Ringström - Rx interrupt status checking suggestion
+
+		Andrew Morton - Clear blocked signals, avoid
+		buffer overrun setting current->comm.
+
+	Submitting bug reports:
+
+		"rtl8139-diag -mmmaaavvveefN" output
+		enable RTL8139_DEBUG below, and look at 'dmesg' or kernel log
+
+		See 8139too.txt for more details.
+
+-----------------------------------------------------------------------------
+2001/09/21
+Comments by ShuChen Shao
+
+1.This driver is originally based on 8139too.c version "0.9.15".
+
+2.It has been enhanced to support RTL8139C+ PCI ethernet chips and tested in 2.4.2 kernel.
+
+3.RTL8139C+ PCI ethernet chips is set to support C+ mode by default.
+  If FORCE_C_Mode below is enable, the RTL8139C+ chip will be forced to support C mode
+  after reboot.
+
+4.This program can be compiled at /usr/src/linux-2.4.2/drivers/net/ using the attached Makefile.
+  And the object file named 8139too.o should be moved to the directory 
+  /lib/modules/2.4.2-2/kernel/drivers/net/
+
+*/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/delay.h>
+#include <linux/ethtool.h>
+#include <linux/version.h>
+#include <linux/proc_fs.h>
+#include <linux/wireless.h>
+#ifdef CONFIG_LEDMAN
+#include <linux/ledman.h>
+#endif
+#include <asm/uaccess.h>	//for copy_from_user
+#include <asm/io.h>
+
+#if LINUX_VERSION_CODE < 0x20407
+#else
+#include <linux/mii.h>
+#include <linux/completion.h>
+#endif
+
+#define RTL8139CP_VERSION "1.5.0"
+#define MODNAME "8139too"
+#define RTL8139_DRIVER_NAME   MODNAME " Fast Ethernet driver " RTL8139CP_VERSION
+#define PFX MODNAME ": "
+
+#undef RTL8139_PROC_DEBUG
+
+#undef FORCE_CPlus_Mode
+#undef FORCE_C_Mode
+
+/* enable PIO instead of MMIO, if CONFIG_8139TOO_PIO is selected */
+#ifdef CONFIG_8139TOO_PIO
+#define USE_IO_OPS 1
+#endif
+
+/* define to 1 to enable copious debugging info */
+#undef RTL8139_DEBUG
+
+/* define to 1 to disable lightweight runtime debugging checks */
+#undef RTL8139_NDEBUG
+
+
+#ifdef RTL8139_DEBUG
+/* note: prints function name for you */
+#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#  define DPRINTK(fmt, args...)
+#endif
+
+#ifdef RTL8139_NDEBUG
+#  define assert(expr) do {} while (0)
+#else
+#  define assert(expr) \
+        if(!(expr)) {					\
+        printk( "Assertion failed! %s,%s,%s,line=%d\n",	\
+        #expr,__FILE__,__FUNCTION__,__LINE__);		\
+        }
+#endif
+
+
+/* A few user-configurable values. */
+/* media options */
+#define MAX_UNITS 8
+static int media[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
+static int max_interrupt_work = 20;
+
+/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
+   The RTL chips use a 64 element hash table based on the Ethernet CRC.  */
+static int multicast_filter_limit = 32;
+
+/* Size of the in-memory receive ring. */
+#define RX_BUF_LEN_IDX	2	/* 0==8K, 1==16K, 2==32K, 3==64K */
+#define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX)
+#define RX_BUF_PAD 16
+#define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */
+#define RX_BUF_TOT_LEN (RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD)
+
+/* Number of Tx descriptor registers. */
+#define NUM_TX_DESC	4
+
+/* max supported ethernet frame size -- must be at least (dev->mtu+14+4).*/
+#define MIN_ETH_FRAME_SIZE	60
+#define MAX_ETH_FRAME_SIZE	1536
+
+/* Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). */
+#define TX_BUF_SIZE	MAX_ETH_FRAME_SIZE
+#define TX_BUF_TOT_LEN	(TX_BUF_SIZE * NUM_TX_DESC)
+
+/* PCI Tuning Parameters
+   Threshold is bytes transferred to chip before transmission starts. */
+#define TX_FIFO_THRESH 256	/* In bytes, rounded down to 32 byte units. */
+
+/* The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024, 7==end of packet. */
+#define RX_FIFO_THRESH	0	/* Rx buffer level before first PCI xfer.  */
+#define RX_DMA_BURST	7 	/* Maximum PCI burst, '6' is 1024 */
+#define TX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
+
+/* Operational parameters that usually are not changed. */
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT  (6*HZ)
+
+////////////////////////////////////////////////////////////////////
+//for 8139C+ only
+#define NUM_CP_TX_DESC	64			/* Number of Tx descriptor registers for C+*/
+#define NUM_CP_RX_DESC	64			/* Number of Rx descriptor registers for C+*/
+#define CP_RX_BUF_SIZE	2000
+#define CPlusEarlyTxThld 0x06
+#define CPlusChecksumOffload 0x00070000
+////////////////////////////////////////////////////////////////////
+
+enum {
+	HAS_MII_XCVR = 0x010000,
+	HAS_CHIP_XCVR = 0x020000,
+	HAS_LNK_CHNG = 0x040000,
+};
+
+#define RTL_MIN_IO_SIZE 0x80
+#define RTL8139B_IO_SIZE 256
+
+#define RTL8129_CAPS	HAS_MII_XCVR
+#define RTL8139_CAPS	HAS_CHIP_XCVR|HAS_LNK_CHNG
+
+typedef enum {
+	RTL8139 = 0,
+	RTL8139_CB,
+	SMC1211TX,
+	/*MPX5030,*/
+	DELTA8139,
+	ADDTRON8139,
+	DFE538TX,
+	RTL8129,
+} board_t;
+
+
+/* indexed by board_t, above */
+static struct {
+	const char *name;
+	u32 hw_flags;
+} board_info[] __devinitdata = {
+	{ "RealTek RTL8139CP Fast Ethernet", RTL8139_CAPS },
+	{ "RealTek RTL8139B PCI/CardBus", RTL8139_CAPS },
+	{ "SMC1211TX EZCard 10/100 (RealTek RTL8139)", RTL8139_CAPS },
+/*	{ MPX5030, "Accton MPX5030 (RealTek RTL8139)", RTL8139_CAPS },*/
+	{ "Delta Electronics 8139 10/100BaseTX", RTL8139_CAPS },
+	{ "Addtron Technolgy 8139 10/100BaseTX", RTL8139_CAPS },
+	{ "D-Link DFE-538TX (RealTek RTL8139)", RTL8139_CAPS },
+	{ "RealTek RTL8129", RTL8129_CAPS },
+};
+
+
+static struct pci_device_id rtl8139_pci_tbl[] __devinitdata = {
+	{0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+	{0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139_CB },
+	{0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SMC1211TX },
+/*	{0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MPX5030 },*/
+	{0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DELTA8139 },
+	{0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ADDTRON8139 },
+	{0x1186, 0x1300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DFE538TX },
+#if defined(CONFIG_MTD_NETtel) || defined(CONFIG_SH_SECUREEDGE5410)
+	{0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+#else
+	{0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8129 },
+#endif
+
+	/* some crazy cards report invalid vendor ids like
+	 * 0x0001 here.  The other ids are valid and constant,
+	 * so we simply don't match on the main vendor id.
+	 */
+	{PCI_ANY_ID, 0x8139, 0x10ec, 0x8139, 0, 0, RTL8139 },
+
+	{0,}
+};
+MODULE_DEVICE_TABLE (pci, rtl8139_pci_tbl);
+
+
+/* The rest of these values should never change. */
+
+/* Symbolic offsets to registers. */
+enum RTL8139_registers {
+	MAC0 = 0,		/* Ethernet hardware address. */
+	MAR0 = 8,		/* Multicast filter. */
+	TxStatus0 = 0x10,	/* Transmit status (Four 32bit registers). */
+	TxAddr0 = 0x20,		/* Tx descriptors (also four 32bit). */
+	RxBuf = 0x30,
+	RxEarlyCnt = 0x34,
+	RxEarlyStatus = 0x36,
+	ChipCmd = 0x37,
+	RxBufPtr = 0x38,
+	RxBufAddr = 0x3A,
+	IntrMask = 0x3C,
+	IntrStatus = 0x3E,
+	TxConfig = 0x40,
+	ChipVersion = 0x43,
+	RxConfig = 0x44,
+	Timer = 0x48,		/* A general-purpose counter. */
+	RxMissed = 0x4C,	/* 24 bits valid, write clears. */
+	Cfg9346 = 0x50,
+	Config0 = 0x51,
+	Config1 = 0x52,
+	FlashReg = 0x54,
+	MediaStatus = 0x58,
+	Config3 = 0x59,
+	Config4 = 0x5A,		/* absent on RTL-8139A */
+	HltClk = 0x5B,
+	MultiIntr = 0x5C,
+	TxSummary = 0x60,
+	BasicModeCtrl = 0x62,
+	BasicModeStatus = 0x64,
+	NWayAdvert = 0x66,
+	NWayLPAR = 0x68,
+	NWayExpansion = 0x6A,
+	/* Undocumented registers, but required for proper operation. */
+	FIFOTMS = 0x70,		/* FIFO Control and test. */
+	CSCR = 0x74,		/* Chip Status and Configuration Register. */
+	PARA78 = 0x78,
+	PARA7c = 0x7c,		/* Magic transceiver parameter register. */
+	Config5 = 0xD8,		/* absent on RTL-8139A */
+//  For C+ Registers
+	CPlusTxPoll=0xD9, CPlusCmd=0xE0, CPlusRxStartAddr=0xE4,
+	CPlusTxStartAddr=0x20, CPlusEarlyTxThldReg=0xEC,
+};
+
+enum ClearBitMasks {
+	MultiIntrClear = 0xF000,
+	ChipCmdClear = 0xE2,
+	Config1Clear = (1<<7)|(1<<6)|(1<<3)|(1<<2)|(1<<1),
+};
+
+enum ChipCmdBits {
+	CmdReset = 0x10,
+	CmdRxEnb = 0x08,
+	CmdTxEnb = 0x04,
+	RxBufEmpty = 0x01,
+};
+
+enum CPlusCmdBits {
+	CPlusTxEnb = 0x01,
+	CPlusRxEnb = 0x02,
+	CPlusCheckSumEnb = 0x20,
+};
+
+enum CPlusRxStatusDesc {
+	CPlusRxRES = 0x00100000,
+	CPlusRxCRC = 0x00040000,
+	CPlusRxRUNT= 0x00080000,
+	CPlusRxRWT = 0x00200000,
+	CPlusRxFAE = 0x08000000,
+	CPlusRxIPchecksumBIT  = 0x00008000,
+	CPlusRxUDPIPchecksumBIT = 0x0000C000,
+	CPlusRxTCPIPchecksumBIT = 0x0000A000,
+	ProtocolType_NonIP	  = 0,
+	ProtocolType_TCPIP	  = 1,
+	ProtocolType_UDPIP	  = 2,
+	ProtocolType_IP	  	  = 3,
+};
+
+enum CPlusTxChecksumOffload {
+	CPlusTxIPchecksumOffload  = 0x00040000,
+	CPlusTxUDPchecksumOffload = 0x00020000,
+	CPlusTxTCPchecksumOffload = 0x00010000,
+};
+
+/* Interrupt register bits, using my own meaningful names. */
+enum IntrStatusBits {
+	PCIErr = 0x8000,
+	PCSTimeout = 0x4000,
+	RxFIFOOver = 0x40,
+	RxUnderrun = 0x20,
+	RxOverflow = 0x10,
+	TxErr = 0x08,
+	TxOK = 0x04,
+	RxErr = 0x02,
+	RxOK = 0x01,
+};
+enum TxStatusBits {
+	TxHostOwns = 0x2000,
+	TxUnderrun = 0x4000,
+	TxStatOK = 0x8000,
+	TxOutOfWindow = 0x20000000,
+	TxAborted = 0x40000000,
+	TxCarrierLost = 0x80000000,
+};
+enum RxStatusBits {
+	RxMulticast = 0x8000,
+	RxPhysical = 0x4000,
+	RxBroadcast = 0x2000,
+	RxBadSymbol = 0x0020,
+	RxRunt = 0x0010,
+	RxTooLong = 0x0008,
+	RxCRCErr = 0x0004,
+	RxBadAlign = 0x0002,
+	RxStatusOK = 0x0001,
+};
+
+/* Bits in RxConfig. */
+enum rx_mode_bits {
+	AcceptErr = 0x20,
+	AcceptRunt = 0x10,
+	AcceptBroadcast = 0x08,
+	AcceptMulticast = 0x04,
+	AcceptMyPhys = 0x02,
+	AcceptAllPhys = 0x01,
+};
+
+/* Bits in TxConfig. */
+enum tx_config_bits {
+	TxIFG1 = (1 << 25),	/* Interframe Gap Time */
+	TxIFG0 = (1 << 24),	/* Enabling these bits violates IEEE 802.3 */
+	TxLoopBack = (1 << 18) | (1 << 17), /* enable loopback test mode */
+	TxCRC = (1 << 16),	/* DISABLE appending CRC to end of Tx packets */
+	TxClearAbt = (1 << 0),	/* Clear abort (WO) */
+	TxDMAShift = 8,		/* DMA burst value (0-7) is shift this many bits */
+
+	TxVersionMask = 0x7C800000, /* mask out version bits 30-26, 23 */
+};
+
+/* Bits in Config1 */
+enum Config1Bits {
+	Cfg1_PM_Enable = 0x01,
+	Cfg1_VPD_Enable = 0x02,
+	Cfg1_PIO = 0x04,
+	Cfg1_MMIO = 0x08,
+	Cfg1_LWAKE = 0x10,
+	Cfg1_Driver_Load = 0x20,
+	Cfg1_LED0 = 0x40,
+	Cfg1_LED1 = 0x80,
+};
+
+enum RxConfigBits {
+	/* Early Rx threshold, none or X/16 */
+	RxCfgEarlyRxNone = 0,
+	RxCfgEarlyRxShift = 24,
+
+	/* rx fifo threshold */
+	RxCfgFIFOShift = 13,
+	RxCfgFIFONone = (7 << RxCfgFIFOShift),
+
+	/* Max DMA burst */
+	RxCfgDMAShift = 8,
+	RxCfgDMAUnlimited = (7 << RxCfgDMAShift),
+
+	/* rx ring buffer length */
+	RxCfgRcv8K = 0,
+	RxCfgRcv16K = (1 << 11),
+	RxCfgRcv32K = (1 << 12),
+	RxCfgRcv64K = (1 << 11) | (1 << 12),
+
+	/* Disable packet wrap at end of Rx buffer */
+	RxNoWrap = (1 << 7),
+};
+
+
+/* Twister tuning parameters from RealTek.
+   Completely undocumented, but required to tune bad links. */
+enum CSCRBits {
+	CSCR_LinkOKBit = 0x0400,
+	CSCR_LinkChangeBit = 0x0800,
+	CSCR_LinkStatusBits = 0x0f000,
+	CSCR_LinkDownOffCmd = 0x003c0,
+	CSCR_LinkDownCmd = 0x0f3c0,
+};
+
+
+enum Cfg9346Bits {
+	Cfg9346_Lock = 0x00,
+	Cfg9346_Unlock = 0xC0,
+};
+
+enum NegotiationBits {
+	AutoNegotiationEnable  = 0x1000,
+	AutoNegotiationRestart = 0x0200,
+	AutoNegoAbility10half  = 0x21,
+	AutoNegoAbility10full  = 0x41,
+	AutoNegoAbility100half  = 0x81,
+	AutoNegoAbility100full  = 0x101,
+};
+
+enum MediaStatusBits {
+	DuplexMode = 0x0100,	//in BasicModeControlRegister
+	Speed_10 = 0x08,		//in Media Status Register
+};
+
+#define PARA78_default	0x78fa8388
+#define PARA7c_default	0xcb38de43	/* param[0][3] */
+#define PARA7c_xxx		0xcb38de43
+static const unsigned long param[4][4] = {
+	{0xcb39de43, 0xcb39ce43, 0xfb38de03, 0xcb38de43},
+	{0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83},
+	{0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83},
+	{0xbb39de43, 0xbb39ce43, 0xbb39ce83, 0xbb39ce83}
+};
+
+struct ring_info {
+	struct sk_buff *skb;
+	dma_addr_t mapping;
+};
+
+
+typedef enum {
+	CH_8139 = 0,
+	CH_8139_K,
+	CH_8139A,
+	CH_8139B,
+	CH_8130,
+	CH_8139C,
+	CH_8139CP,
+} chip_t;
+
+
+/* directly indexed by chip_t, above */
+const static struct {
+	const char *name;
+	u8 version; /* from RTL8139C docs */
+	u32 RxConfigMask; /* should clear the bits supported by this chip */
+} rtl_chip_info[] = {
+	{ "RTL-8139",
+	  0x40,
+	  0xf0fe0040, /* XXX copied from RTL8139A, verify */
+	},
+
+	{ "RTL-8139 rev K",
+	  0x60,
+	  0xf0fe0040,
+	},
+
+	{ "RTL-8139A",
+	  0x70,
+	  0xf0fe0040,
+	},
+
+	{ "RTL-8139B",
+	  0x78,
+	  0xf0fc0040
+	},
+
+	{ "RTL-8130",
+	  0x7C,
+	  0xf0fe0040, /* XXX copied from RTL8139A, verify */
+	},
+
+	{ "RTL-8139C",
+	  0x74,
+	  0xf0fc0040, /* XXX copied from RTL8139B, verify */
+	},
+
+	{ "RTL-8139CP",
+	  0x76,
+	  0xf0fc0040, /* XXX copied from RTL8139B, verify */
+	},
+};
+
+struct CPlusTxDesc {
+	u32		status;
+	u32		vlan_tag;
+	u64		buf_addr;
+};
+
+struct CPlusRxDesc {
+	u32		status;
+	u32		vlan_tag;
+	u64		buf_addr;
+};
+/********************************************************************** */
+#define IP_PROTOCOL            0x0008   /* Network Byte order */
+#define TCP_PROTOCOL    6
+#define UDP_PROTOCOL    17
+#define ADDRESS_LEN             6
+
+struct ethernet_ii_header {
+    uint8_t DestAddr[ADDRESS_LEN];
+    uint8_t SourceAddr[ADDRESS_LEN];
+    uint16_t TypeLength;
+};
+/********************************************************************** */
+/* Internet Protocol Version 4 (IPV4) Header Definition */
+/********************************************************************** */
+
+typedef struct _ip_v4_header_ {
+    uint32_t HdrLength:4,           /* Network Byte order */
+        HdrVersion:4,              /* Network Byte order */
+        TOS:8,                       /* Network Byte order */
+        Length:16;                 /* Network Byte order */
+
+    union {
+        uint32_t IdThruOffset;
+
+        struct {
+            uint32_t DatagramId:16, FragOffset1:5,   /* Network Byte order */
+                MoreFragments:1, NoFragment:1, Reserved2:1, FragOffset:8;
+        } Bits;
+
+        struct {
+            uint32_t DatagramId:16, FragsNFlags:16;   /* Network Byte order */
+        } Fields;
+
+    } FragmentArea;
+
+    uint8_t TimeToLive;
+    uint8_t ProtocolCarried;
+    uint16_t Checksum;
+
+    union {
+        uint32_t SourceIPAddress;
+
+        struct {
+            uint32_t SrcAddrLo:16,     /* Network Byte order */
+	             SrcAddrHi:16;
+        } Fields;
+
+        struct {
+            uint32_t OctA:8, OctB:8, OctC:8, OctD:8;
+        } SFields;
+
+    } SrcAddr;
+
+    union {
+        uint32_t TargetIPAddress;
+
+        struct {
+            uint32_t DestAddrLo:16,     /* Network Byte order */
+                DestAddrHi:16;
+        } Fields;
+
+        struct {
+            uint32_t OctA:8, OctB:8, OctC:8, OctD:8;
+        } DFields;
+
+    } DestAddr;
+
+    uint16_t IpOptions[20];   /* Maximum of 40 bytes (20 words) of IP options  */
+
+} ip_v4_header;
+/********************************************************************** */
+
+struct rtl8139_private {
+	void *mmio_addr;
+	int drv_flags;
+	struct pci_dev *pci_dev;
+	struct net_device_stats stats;
+	unsigned char *rx_ring;
+	unsigned int cur_rx;	/* Index into the Rx buffer of next Rx pkt. */
+	unsigned int tx_flag;
+	unsigned long cur_tx;
+	unsigned long dirty_tx;
+	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
+	struct ring_info tx_info[NUM_TX_DESC];
+	unsigned char *tx_buf[NUM_TX_DESC];	/* Tx bounce buffers */
+	unsigned char *tx_bufs;	/* Tx bounce buffer region. */
+	dma_addr_t rx_ring_dma;
+	dma_addr_t tx_bufs_dma;
+	signed char phys[4];		/* MII device addresses. */
+	u16 advertising;		/* NWay media advertisement */
+	char twistie, twist_row, twist_col;	/* Twister tune state. */
+	unsigned int full_duplex:1;	/* Full-duplex operation requested. */
+	unsigned int duplex_lock:1;
+	unsigned int default_port:4;	/* Last dev->if_port value. */
+	unsigned int media2:4;	/* Secondary monitored media port. */
+	unsigned int medialock:1;	/* Don't sense media type. */
+	unsigned int mediasense:1;	/* Media sensing in progress. */
+	spinlock_t lock;
+	chip_t chipset;
+	pid_t thr_pid;
+	wait_queue_head_t thr_wait;
+
+#if LINUX_VERSION_CODE < 0x20407
+	struct semaphore thr_exited;
+#else
+	struct completion thr_exited;
+#endif
+
+
+  // For 8139C+
+	int AutoNegoAbility;
+	unsigned long CP_cur_tx;
+	unsigned long CP_dirty_tx;
+	unsigned long CP_cur_rx;
+	unsigned char *TxDescArrays;
+	dma_addr_t TxDescArraysDMA;
+	unsigned char *RxDescArrays;
+	dma_addr_t RxDescArraysDMA;
+	struct CPlusTxDesc *TxDescArray;
+	struct CPlusRxDesc *RxDescArray;
+	unsigned char *RxBufferRings;
+	dma_addr_t RxBufferRingsDMA;
+	unsigned char *RxBufferRing[NUM_CP_RX_DESC];
+	struct ring_info TxRingInfo[NUM_CP_TX_DESC];
+
+	atomic_t CRC32DoubleCheck_ERR;
+};
+
+MODULE_AUTHOR ("Jeff Garzik <jgarzik@mandrakesoft.com>");
+MODULE_DESCRIPTION ("RealTek RTL-8139CP Fast Ethernet driver");
+MODULE_LICENSE("GPL");
+MODULE_PARM (multicast_filter_limit, "i");
+MODULE_PARM (max_interrupt_work, "i");
+MODULE_PARM (media, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM (full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+
+static int read_eeprom (void *ioaddr, int location, int addr_len);
+
+static int rtl8139CP_open (struct net_device *dev);
+static int rtl8139CP_start_xmit (struct sk_buff *skb, struct net_device *dev);
+static void rtl8139CP_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+static void rtl8139CP_init_ring (struct net_device *dev);
+static void rtl8139CP_hw_start (struct net_device *dev);
+static int rtl8139CP_close (struct net_device *dev);	       
+static void rtl8139CP_tx_timeout (struct net_device *dev);
+
+static int rtl8139_open (struct net_device *dev);
+static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev);
+static void rtl8139_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+static void rtl8139_init_ring (struct net_device *dev);
+static void rtl8139_hw_start (struct net_device *dev);
+static int rtl8139_close (struct net_device *dev);
+static void rtl8139_tx_timeout (struct net_device *dev);
+
+static int mdio_read (struct net_device *dev, int phy_id, int location);
+static void mdio_write (struct net_device *dev, int phy_id, int location, int val);
+static int mii_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
+
+static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
+static inline u32 ether_crc (int length, unsigned char *data);
+static void rtl8139_set_rx_mode (struct net_device *dev);
+
+#ifdef USE_IO_OPS
+
+#define RTL_R8(reg)		inb (((unsigned long)ioaddr) + (reg))
+#define RTL_R16(reg)		inw (((unsigned long)ioaddr) + (reg))
+#define RTL_R32(reg)		((unsigned long) inl (((unsigned long)ioaddr) + (reg)))
+#define RTL_W8(reg, val8)	outb ((val8), ((unsigned long)ioaddr) + (reg))
+#define RTL_W16(reg, val16)	outw ((val16), ((unsigned long)ioaddr) + (reg))
+#define RTL_W32(reg, val32)	outl ((val32), ((unsigned long)ioaddr) + (reg))
+#define RTL_W8_F		RTL_W8
+#define RTL_W16_F		RTL_W16
+#define RTL_W32_F		RTL_W32
+#undef readb
+#undef readw
+#undef readl
+#undef writeb
+#undef writew
+#undef writel
+#define readb(addr) inb((unsigned long)(addr))
+#define readw(addr) inw((unsigned long)(addr))
+#define readl(addr) inl((unsigned long)(addr))
+#define writeb(val,addr) outb((val),(unsigned long)(addr))
+#define writew(val,addr) outw((val),(unsigned long)(addr))
+#define writel(val,addr) outl((val),(unsigned long)(addr))
+
+#else
+
+/* write MMIO register, with flush */
+/* Flush avoids rtl8139 bug w/ posted MMIO writes */
+#define RTL_W8_F(reg, val8)	do { writeb ((val8), ioaddr + (reg)); readb (ioaddr + (reg)); } while (0)
+#define RTL_W16_F(reg, val16)	do { writew ((val16), ioaddr + (reg)); readw (ioaddr + (reg)); } while (0)
+#define RTL_W32_F(reg, val32)	do { writel ((val32), ioaddr + (reg)); readl (ioaddr + (reg)); } while (0)
+
+
+#if MMIO_FLUSH_AUDIT_COMPLETE
+
+/* write MMIO register */
+#define RTL_W8(reg, val8)	writeb ((val8), ioaddr + (reg))
+#define RTL_W16(reg, val16)	writew ((val16), ioaddr + (reg))
+#define RTL_W32(reg, val32)	writel ((val32), ioaddr + (reg))
+
+#else
+
+/* write MMIO register, then flush */
+#define RTL_W8		RTL_W8_F
+#define RTL_W16		RTL_W16_F
+#define RTL_W32		RTL_W32_F
+
+#endif /* MMIO_FLUSH_AUDIT_COMPLETE */
+
+/* read MMIO register */
+#define RTL_R8(reg)		readb (ioaddr + (reg))
+#define RTL_R16(reg)		readw (ioaddr + (reg))
+#define RTL_R32(reg)		((unsigned long) readl (ioaddr + (reg)))
+
+#endif /* USE_IO_OPS */
+
+
+static const u16 rtl8139_intr_mask =
+	PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver |
+	TxErr | TxOK | RxErr | RxOK;
+
+static const unsigned int rtl8139_rx_config =
+	  RxCfgEarlyRxNone | RxCfgRcv32K | RxNoWrap |
+	  (RX_FIFO_THRESH << RxCfgFIFOShift) |
+	  (RX_DMA_BURST << RxCfgDMAShift);
+
+
+
+//==========================================================================================
+unsigned long crc32_table[256];
+#define CRC32_POLY 0x04c11db7
+#define ReverseBit(data) ( ((data<<7)&0x80) | ((data<<5)&0x40) | ((data<<3)&0x20) | ((data<<1)&0x10) |\
+                	   ((data>>1)&0x08) | ((data>>3)&0x04) | ((data>>5)&0x02) | ((data>>7)&0x01)	)
+//==========================================================================================
+void init_crc32( struct net_device *dev )
+{
+        int i, j;
+        unsigned long c;
+        unsigned char *p=(unsigned char *)&c, *p1;
+        unsigned char k;
+	struct rtl8139_private *tp = dev->priv;
+
+	;
+	atomic_set( &tp->CRC32DoubleCheck_ERR, 0 );
+
+        c = 0x12340000;
+
+        for (i = 0; i < 256; ++i) 
+        {
+			k = ReverseBit((unsigned char)i);
+			for (c = ((unsigned long)k) << 24, j = 8; j > 0; --j)
+				c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1);
+			p1 = (unsigned char *)(&crc32_table[i]);
+
+			p1[0] = ReverseBit(p[3]);
+			p1[1] = ReverseBit(p[2]);
+			p1[2] = ReverseBit(p[1]);
+			p1[3] = ReverseBit(p[0]);
+        }
+}
+
+unsigned long crc32(unsigned char *buf, int len)
+{
+        unsigned char *p;
+        unsigned long  crc;
+
+        crc = 0xffffffff;       /* preload shift register, per CRC-32 spec */
+
+        for (p = buf; len > 0; ++p, --len)
+        {
+			crc = crc32_table[ (crc ^ *p) & 0xff] ^ (crc >> 8);
+        }
+        return ~crc;    /* transmit complement, per CRC-32 spec */
+}
+
+
+//int DoubleCheck( &rx_ring[ring_offset + 4], pkt_size )
+//----------------------------------------------------------------------
+// rx_data_ptr	:	the start pointer of the received data
+// pkt_size	:	the received data length excluding 4-bytes CRC
+//----------------------------------------------------------------------
+static inline int CRC32DoubleCheck( unsigned char *rx_data_ptr, unsigned int pkt_size )
+{
+	unsigned short	EtherType = *( (unsigned short *)(rx_data_ptr + 12) );
+	unsigned char	IPType = *(rx_data_ptr + 23);
+	unsigned long	SWCRC = 0xffffffff;
+	unsigned long	HWCRC;
+
+	//----------------------------------------------------------------------
+	// If this is the packet of type TCP/IP, skip CRC32 double-check.
+	//----------------------------------------------------------------------
+	if( (EtherType == 0x0008) && (IPType == 0x06) ){
+		return 0;
+	}
+
+	HWCRC = *( (unsigned long *)(rx_data_ptr + pkt_size) );
+
+	SWCRC = crc32( rx_data_ptr, pkt_size );
+
+//	printk(KERN_INFO "RTL8139: %s( pkt_size = %d, EtherType = 0x%4.4x, IPType = 0x%2.2x). HWCRC = 0x%8.8lx, SWCRC = 0x%8.8lx\n",
+//				__FUNCTION__, pkt_size, EtherType, IPType, HWCRC, SWCRC );
+
+	return ( (SWCRC == HWCRC) ? 0 : -1 );
+}
+
+
+
+
+#ifdef RTL8139_PROC_DEBUG
+//==========================================================================================
+struct proc_dir_entry *rtl8139_Proc_root;
+struct proc_dir_entry *rtl8139_Proc;
+
+
+static int rtl8139_proc_status(char *buffer,
+		  	char **buffer_location,
+		  	off_t offset,
+		  	int buffer_length,
+		  	int *eof,
+		  	void *data)
+{
+	char *buf = buffer;
+	struct net_device *dev = (struct net_device *)data;
+
+	buf += sprintf( buf, " ************ Current driver status ************\n\n\n" );
+	buf += sprintf( buf, " MAC address = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
+				dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
+
+	buf += sprintf( buf, " ioaddr = 0x%8.8lx\n",  (unsigned long)dev->base_addr );
+	buf += sprintf( buf, " irq = %d\n",  dev->irq );
+
+	return (buf - buffer);
+}
+
+
+static void rtl8139_init_proc(struct net_device *dev)
+{
+	if(rtl8139_Proc_root == NULL)
+		rtl8139_Proc_root = proc_mkdir("rtl8139", NULL);
+	if(rtl8139_Proc_root != NULL){
+		rtl8139_Proc = create_proc_read_entry(
+				"status",0644, rtl8139_Proc_root, rtl8139_proc_status, (void *)dev);
+	}
+}
+
+static void rtl8139_remove_proc(struct net_device *dev)
+{
+	if(rtl8139_Proc_root != NULL){
+		remove_proc_entry("status", rtl8139_Proc_root );
+		remove_proc_entry("rtl8139", NULL );
+	}
+}
+//==========================================================================================
+#endif	//#ifdef RTL8139_PROC_DEBUG
+
+
+
+
+
+//------------------------------------------------------------------------------------------------------------
+//------------------------------------------------------------------------------------------------------------
+static int __devinit rtl8139_init_board (struct pci_dev *pdev, struct net_device **dev_out, void **ioaddr_out)
+{
+	void *ioaddr = NULL;
+	struct net_device *dev;
+	struct rtl8139_private *tp;
+	u8 tmp8;
+	int rc, i;
+	u32 pio_start, pio_end, pio_flags, pio_len;
+	unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
+	u32 tmp;
+
+
+	DPRINTK ("ENTER\n");
+
+	assert (pdev != NULL);
+	assert (ioaddr_out != NULL);
+
+	*ioaddr_out = NULL;
+	*dev_out = NULL;
+
+	/* dev zeroed in init_etherdev */
+	dev = init_etherdev (NULL, sizeof (*tp));
+	if (dev == NULL) {
+		printk (KERN_ERR PFX "unable to alloc new ethernet\n");
+		DPRINTK ("EXIT, returning -ENOMEM\n");
+		return -ENOMEM;
+	}
+	SET_MODULE_OWNER(dev);
+	tp = dev->priv;
+
+	/* enable device (incl. PCI PM wakeup and hotplug setup) */
+	rc = pci_enable_device (pdev);
+	if (rc)
+		goto err_out;
+
+	pio_start = pci_resource_start (pdev, 0);
+	pio_end = pci_resource_end (pdev, 0);
+	pio_flags = pci_resource_flags (pdev, 0);
+	pio_len = pci_resource_len (pdev, 0);
+
+	mmio_start = pci_resource_start (pdev, 1);
+	mmio_end = pci_resource_end (pdev, 1);
+	mmio_flags = pci_resource_flags (pdev, 1);
+	mmio_len = pci_resource_len (pdev, 1);
+
+	/* set this immediately, we need to know before
+	 * we talk to the chip directly */
+	DPRINTK("PIO region size == 0x%02X\n", pio_len);
+	DPRINTK("MMIO region size == 0x%02lX\n", mmio_len);
+	if (pio_len == RTL8139B_IO_SIZE)
+		tp->chipset = CH_8139B;
+
+	/* make sure PCI base addr 0 is PIO */
+	if (!(pio_flags & IORESOURCE_IO)) {
+		printk (KERN_ERR PFX "region #0 not a PIO resource, aborting\n");
+		rc = -ENODEV;
+		goto err_out;
+	}
+
+	/* make sure PCI base addr 1 is MMIO */
+	if (!(mmio_flags & IORESOURCE_MEM)) {
+		printk (KERN_ERR PFX "region #1 not an MMIO resource, aborting\n");
+		rc = -ENODEV;
+		goto err_out;
+	}
+
+	/* check for weird/broken PCI region reporting */
+	if ((pio_len < RTL_MIN_IO_SIZE) ||
+	    (mmio_len < RTL_MIN_IO_SIZE)) {
+		printk (KERN_ERR PFX "Invalid PCI region size(s), aborting\n");
+		rc = -ENODEV;
+		goto err_out;
+	}
+
+
+#ifndef USE_IO_OPS
+	rc = pci_request_regions (pdev, dev->name);
+	if (rc)
+		goto err_out;
+#endif /* !USE_IO_OPS */
+
+
+
+	/* enable PCI bus-mastering */
+	pci_set_master (pdev);
+
+#ifdef USE_IO_OPS
+	ioaddr = (void *) pio_start;
+	printk ("%s: use pci IO map. ioaddr=0x%08lx\n", dev->name, (unsigned long)ioaddr);
+#else
+	/* ioremap MMIO region */
+	ioaddr = ioremap (mmio_start, mmio_len);
+	if (ioaddr == NULL) {
+		printk (KERN_ERR PFX "cannot remap MMIO, aborting\n");
+		rc = -EIO;
+		goto err_out_free_res;
+	}
+	printk ("%s: use memory map. ioaddr=0x%08lx\n", dev->name, (unsigned long)ioaddr);
+#endif /* USE_IO_OPS */
+
+	/* Soft reset the chip. */
+	RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) | CmdReset);
+
+	/* Check that the chip has finished the reset. */
+	for (i = 1000; i > 0; i--)
+		if ((RTL_R8 (ChipCmd) & CmdReset) == 0)
+			break;
+		else
+			udelay (10);
+
+	/* Bring the chip out of low-power mode. */
+	if (tp->chipset == CH_8139B) {
+		RTL_W8 (Config1, RTL_R8 (Config1) & ~(1<<4));
+		RTL_W8 (Config4, RTL_R8 (Config4) & ~(1<<2));
+	} else {
+		/* handle RTL8139A and RTL8139 cases */
+		/* XXX from becker driver. is this right?? */
+		RTL_W8 (Config1, 0);
+	}
+
+	/* make sure chip thinks PIO and MMIO are enabled */
+	tmp8 = RTL_R8 (Config1);
+	if ((tmp8 & Cfg1_PIO) == 0) {
+		printk (KERN_ERR PFX "PIO not enabled, Cfg1=%02X, aborting\n", tmp8);
+		rc = -EIO;
+		goto err_out_iounmap;
+	}
+	if ((tmp8 & Cfg1_MMIO) == 0) {
+		printk (KERN_ERR PFX "MMIO not enabled, Cfg1=%02X, aborting\n", tmp8);
+		rc = -EIO;
+		goto err_out_iounmap;
+	}
+
+	/* identify chip attached to board */
+//	tmp = RTL_R8 (ChipVersion);
+	tmp = RTL_R32 (TxConfig);
+	tmp = ( (tmp&0x7c000000) + ( (tmp&0x00800000)<<2 ) )>>24;
+
+	for (i = ARRAY_SIZE (rtl_chip_info) - 1; i >= 0; i--)
+		if (tmp == rtl_chip_info[i].version) {
+			tp->chipset = i;
+			goto match;
+		}
+
+	/* if unknown chip, assume array element #0, original RTL-8139 in this case */
+	printk (KERN_DEBUG PFX "PCI device %s: unknown chip version, assuming RTL-8139\n",
+		pdev->slot_name);
+	printk (KERN_DEBUG PFX "PCI device %s: TxConfig = 0x%lx\n", pdev->slot_name, RTL_R32 (TxConfig));
+	tp->chipset = 0;
+
+match:
+#ifdef FORCE_CPlus_Mode
+	if(tp->chipset >= (ARRAY_SIZE (rtl_chip_info) - 2))	
+		tp->chipset = ARRAY_SIZE (rtl_chip_info) - 1;
+#endif
+#ifdef FORCE_C_Mode
+	if(tp->chipset > (ARRAY_SIZE (rtl_chip_info) - 2))
+		tp->chipset = ARRAY_SIZE (rtl_chip_info) - 2;
+#endif
+
+	DPRINTK ("chipset id (%d) == index %d, '%s'\n",
+		tmp,
+		tp->chipset,
+		rtl_chip_info[tp->chipset].name);
+
+	DPRINTK ("EXIT, returning 0\n");
+	*ioaddr_out = ioaddr;
+	*dev_out = dev;
+	return 0;
+
+err_out_iounmap:
+	assert (ioaddr > 0);
+#ifndef USE_IO_OPS
+	iounmap (ioaddr);
+err_out_free_res:
+	pci_release_regions (pdev);
+#endif /* !USE_IO_OPS */
+err_out:
+	unregister_netdev (dev);
+	kfree (dev);
+	DPRINTK ("EXIT, returning %d\n", rc);
+	return rc;
+}
+
+
+static int __devinit rtl8139_init_one (struct pci_dev *pdev,
+				       const struct pci_device_id *ent)
+{
+	struct net_device *dev = NULL;
+	struct rtl8139_private *tp;
+	int i, addr_len, option;
+	void *ioaddr = NULL;
+	static int board_idx = -1;
+	static int printed_version;
+	u8 tmp;
+
+	
+	DPRINTK ("ENTER\n");
+
+	assert (pdev != NULL);
+	assert (ent != NULL);
+
+	board_idx++;
+
+	if (!printed_version) {
+		printk (KERN_INFO RTL8139_DRIVER_NAME " loaded\n");
+		printed_version = 1;
+	}
+
+	i = rtl8139_init_board (pdev, &dev, &ioaddr);
+	if (i < 0) {
+		DPRINTK ("EXIT, returning %d\n", i);
+		return i;
+	}
+
+	tp = dev->priv;
+
+	assert (ioaddr != NULL);
+	assert (dev != NULL);
+	assert (tp != NULL);
+
+	init_crc32( dev );
+
+#if defined(CONFIG_MTD_NETtel) || defined(CONFIG_SH_SECUREEDGE5410)
+	/* Don't rely on the eeprom, get MAC from chip. */
+	for (i = 0; (i < 6); i++)
+		dev->dev_addr[i] = readb(ioaddr + MAC0 + i);
+#else
+	addr_len = read_eeprom (ioaddr, 0, 8) == 0x8129 ? 8 : 6;
+	for (i = 0; i < 3; i++)
+		((u16 *) (dev->dev_addr))[i] =
+		    le16_to_cpu (read_eeprom (ioaddr, i + 7, addr_len));
+#endif
+
+	/* The Rtl8139-specific entries in the device structure. */
+	if( rtl_chip_info[tp->chipset].name == "RTL-8139CP" ){
+		dev->open = rtl8139CP_open;
+		dev->hard_start_xmit = rtl8139CP_start_xmit;
+		dev->stop = rtl8139CP_close;
+		dev->tx_timeout = rtl8139CP_tx_timeout;
+		dev->features |= NETIF_F_IP_CSUM;	/* Can checksum only TCP/UDP over IPv4. */
+		printk (KERN_DEBUG "%s: Identified 8139CP chip type '%s'. Support TCP/UDP checksumOffload\n",dev->name,rtl_chip_info[tp->chipset].name);
+
+	}
+	else{
+		dev->open = rtl8139_open;
+		dev->hard_start_xmit = rtl8139_start_xmit;
+		dev->stop = rtl8139_close;
+		dev->tx_timeout = rtl8139_tx_timeout;
+		printk (KERN_DEBUG "%s:  Identified 8139CP chip type '%s'\n", dev->name, rtl_chip_info[tp->chipset].name);
+	}
+
+
+	dev->get_stats = rtl8139_get_stats;
+	dev->set_multicast_list = rtl8139_set_rx_mode;
+	dev->do_ioctl = mii_ioctl;
+
+	dev->watchdog_timeo = TX_TIMEOUT;
+	dev->irq = pdev->irq;
+	dev->base_addr = (unsigned long) ioaddr;
+	/* dev->priv/tp zeroed and aligned in init_etherdev */
+	tp = dev->priv;
+	/* note: tp->chipset set in rtl8139_init_board */
+	tp->drv_flags = board_info[ent->driver_data].hw_flags;
+	tp->pci_dev = pdev;
+	tp->mmio_addr = ioaddr;
+	spin_lock_init (&tp->lock);
+	init_waitqueue_head (&tp->thr_wait);
+
+#if LINUX_VERSION_CODE < 0x20407
+	init_MUTEX_LOCKED (&tp->thr_exited);
+#else
+	init_completion (&tp->thr_exited);
+#endif
+
+	pdev->driver_data = dev;
+
+	printk (KERN_INFO "%s: %s at 0x%lx, "
+		"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
+		"IRQ %d\n",
+		dev->name,
+		board_info[ent->driver_data].name,
+		dev->base_addr,
+		dev->dev_addr[0], dev->dev_addr[1],
+		dev->dev_addr[2], dev->dev_addr[3],
+		dev->dev_addr[4], dev->dev_addr[5],
+		dev->irq);
+
+//	dev->tx_queue_len=500;
+
+	/* Find the connected MII xcvrs.
+	   Doing this in open() would allow detecting external xcvrs later, but
+	   takes too much time. */
+	if (tp->drv_flags & HAS_MII_XCVR) {
+		int phy, phy_idx = 0;
+		for (phy = 0; phy < 32 && phy_idx < sizeof(tp->phys); phy++) {
+			int mii_status = mdio_read(dev, phy, 1);
+			if (mii_status != 0xffff  &&  mii_status != 0x0000) {
+				tp->phys[phy_idx++] = phy;
+				tp->advertising = mdio_read(dev, phy, 4);
+				printk(KERN_INFO "%s: MII transceiver %d status 0x%4.4x "
+					   "advertising %4.4x.\n",
+					   dev->name, phy, mii_status, tp->advertising);
+			}
+		}
+		if (phy_idx == 0) {
+			printk(KERN_INFO "%s: No MII transceivers found!  Assuming SYM "
+				   "transceiver.\n",
+				   dev->name);
+			tp->phys[0] = 32;
+		}
+	} else
+		tp->phys[0] = 32;
+
+	/* Put the chip into low-power mode. */
+	RTL_W8_F (Cfg9346, Cfg9346_Unlock);
+
+	tmp = RTL_R8 (Config1) & Config1Clear;
+	tmp |= (tp->chipset == CH_8139B) ? 3 : 1; /* Enable PM/VPD */
+	RTL_W8_F (Config1, tmp);
+
+	RTL_W8_F (HltClk, 'H');	/* 'R' would leave the clock running. */
+
+	/* The lower four bits are the media type. */
+	option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx];
+	tp->AutoNegoAbility = option&0xF;
+
+	if (option > 0) {
+		tp->full_duplex = (option & 0x210) ? 1 : 0;
+		tp->default_port = option & 0xFF;
+		if (tp->default_port)
+			tp->medialock = 1;
+	}
+	if (board_idx < MAX_UNITS  &&  full_duplex[board_idx] > 0)
+		tp->full_duplex = full_duplex[board_idx];
+	if (tp->full_duplex) {
+		printk(KERN_INFO "%s: Media type forced to Full Duplex.\n", dev->name);
+		/* Changing the MII-advertised media because might prevent
+		   re-connection. */
+		tp->duplex_lock = 1;
+	}
+
+	if (tp->default_port) {
+		printk(KERN_INFO "%s: Forcing %dMbs %s-duplex operation.\n", dev->name,
+			   (option & 0x0C ? 100 : 10),
+			   (option & 0x0A ? "full" : "half"));
+		mdio_write(dev, tp->phys[0], 0,
+				   ((option & 0x20) ? 0x2000 : 0) | 	/* 100mbps? */
+				   ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */
+	}
+
+
+#ifdef RTL8139_PROC_DEBUG
+	//-----------------------------------------------------------------------------
+	// Add proc file system
+	//-----------------------------------------------------------------------------
+	rtl8139_init_proc(dev);
+#endif	//#ifdef RTL8139_PROC_DEBUG
+
+
+	DPRINTK ("EXIT - returning 0\n");
+	return 0;
+}
+
+
+static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
+{
+	struct net_device *dev = pdev->driver_data;
+	struct rtl8139_private *np;
+
+
+	DPRINTK ("ENTER\n");
+
+	assert (dev != NULL);
+
+	np = (struct rtl8139_private *) (dev->priv);
+	assert (np != NULL);
+
+
+#ifndef USE_IO_OPS
+	iounmap (np->mmio_addr);
+	pci_release_regions (pdev);
+#endif /* !USE_IO_OPS */
+
+#ifdef RTL8139_PROC_DEBUG
+	//-----------------------------------------------------------------------------
+	// Remove proc file system
+	//-----------------------------------------------------------------------------
+	rtl8139_remove_proc(dev);
+#endif	//#ifdef RTL8139_PROC_DEBUG
+
+
+	unregister_netdev (dev);
+
+	pdev->driver_data = NULL;
+
+	pci_disable_device (pdev);
+
+	DPRINTK ("EXIT\n");
+}
+
+
+/* Serial EEPROM section. */
+
+/*  EEPROM_Ctrl bits. */
+#define EE_SHIFT_CLK	0x04	/* EEPROM shift clock. */
+#define EE_CS			0x08	/* EEPROM chip select. */
+#define EE_DATA_WRITE	0x02	/* EEPROM chip data in. */
+#define EE_WRITE_0		0x00
+#define EE_WRITE_1		0x02
+#define EE_DATA_READ	0x01	/* EEPROM chip data out. */
+#define EE_ENB			(0x80 | EE_CS)
+
+/* Delay between EEPROM clock transitions.
+   No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
+ */
+
+#define eeprom_delay()	readl(ee_addr)
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define EE_WRITE_CMD	(5)
+#define EE_READ_CMD		(6)
+#define EE_ERASE_CMD	(7)
+
+static int __devinit read_eeprom (void *ioaddr, int location, int addr_len)
+{
+	int i;
+	unsigned retval = 0;
+	void *ee_addr = ioaddr + Cfg9346;
+	int read_cmd = location | (EE_READ_CMD << addr_len);
+
+	DPRINTK ("ENTER\n");
+
+	writeb (EE_ENB & ~EE_CS, ee_addr);
+	writeb (EE_ENB, ee_addr);
+	eeprom_delay ();
+
+	/* Shift the read command bits out. */
+	for (i = 4 + addr_len; i >= 0; i--) {
+		int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+		writeb (EE_ENB | dataval, ee_addr);
+		eeprom_delay ();
+		writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+		eeprom_delay ();
+	}
+	writeb (EE_ENB, ee_addr);
+	eeprom_delay ();
+
+	for (i = 16; i > 0; i--) {
+		writeb (EE_ENB | EE_SHIFT_CLK, ee_addr);
+		eeprom_delay ();
+		retval =
+		    (retval << 1) | ((readb (ee_addr) & EE_DATA_READ) ? 1 :
+				     0);
+		writeb (EE_ENB, ee_addr);
+		eeprom_delay ();
+	}
+
+	/* Terminate the EEPROM access. */
+	writeb (~EE_CS, ee_addr);
+	eeprom_delay ();
+
+	DPRINTK ("EXIT - returning %d\n", retval);
+	return retval;
+}
+
+/* MII serial management: mostly bogus for now. */
+/* Read and write the MII management registers using software-generated
+   serial MDIO protocol.
+   The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
+   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
+   "overclocking" issues. */
+#define MDIO_DIR		0x80
+#define MDIO_DATA_OUT	0x04
+#define MDIO_DATA_IN	0x02
+#define MDIO_CLK		0x01
+#define MDIO_WRITE0 (MDIO_DIR)
+#define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT)
+
+#define mdio_delay(mdio_addr)	readb(mdio_addr)
+
+
+static char mii_2_8139_map[8] = {
+	BasicModeCtrl,
+	BasicModeStatus,
+	0,
+	0,
+	NWayAdvert,
+	NWayLPAR,
+	NWayExpansion,
+	0
+};
+
+
+/* Syncronize the MII management interface by shifting 32 one bits out. */
+static void mdio_sync (void *mdio_addr)
+{
+	int i;
+
+	DPRINTK ("ENTER\n");
+
+	for (i = 32; i >= 0; i--) {
+		writeb (MDIO_WRITE1, mdio_addr);
+		mdio_delay (mdio_addr);
+		writeb (MDIO_WRITE1 | MDIO_CLK, mdio_addr);
+		mdio_delay (mdio_addr);
+	}
+
+	DPRINTK ("EXIT\n");
+}
+
+
+static int mdio_read (struct net_device *dev, int phy_id, int location)
+{
+	struct rtl8139_private *tp = dev->priv;
+	void *mdio_addr = tp->mmio_addr + Config4;
+	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
+	int retval = 0;
+	int i;
+
+	DPRINTK ("ENTER\n");
+
+	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
+		DPRINTK ("EXIT after directly using 8139 internal regs\n");
+		return location < 8 && mii_2_8139_map[location] ?
+		    readw (tp->mmio_addr + mii_2_8139_map[location]) : 0;
+	}
+	mdio_sync (mdio_addr);
+	/* Shift the read command bits out. */
+	for (i = 15; i >= 0; i--) {
+		int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;
+
+		writeb (MDIO_DIR | dataval, mdio_addr);
+		mdio_delay (mdio_addr);
+		writeb (MDIO_DIR | dataval | MDIO_CLK, mdio_addr);
+		mdio_delay (mdio_addr);
+	}
+
+	/* Read the two transition, 16 data, and wire-idle bits. */
+	for (i = 19; i > 0; i--) {
+		writeb (0, mdio_addr);
+		mdio_delay (mdio_addr);
+		retval = (retval << 1) | ((readb (mdio_addr) & MDIO_DATA_IN) ? 1 : 0);
+		writeb (MDIO_CLK, mdio_addr);
+		mdio_delay (mdio_addr);
+	}
+
+	DPRINTK ("EXIT, returning %d\n", (retval >> 1) & 0xffff);
+	return (retval >> 1) & 0xffff;
+}
+
+
+static void mdio_write (struct net_device *dev, int phy_id, int location,
+			int value)
+{
+	struct rtl8139_private *tp = dev->priv;
+	void *mdio_addr = tp->mmio_addr + Config4;
+	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
+	int i;
+
+	DPRINTK ("ENTER\n");
+
+	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
+		void *ioaddr = tp->mmio_addr;
+		if (location == 0) {
+			RTL_W8_F (Cfg9346, Cfg9346_Unlock);
+			//////////////////////////////////////////////////////////////
+			switch(tp->AutoNegoAbility){
+			case 1: RTL_W16 (NWayAdvert, AutoNegoAbility10half); break;
+			case 2: RTL_W16 (NWayAdvert, AutoNegoAbility10full); break;
+			case 4: RTL_W16 (NWayAdvert, AutoNegoAbility100half); break;
+			case 8: RTL_W16 (NWayAdvert, AutoNegoAbility100full); break;
+			default: break;
+			}
+			RTL_W16_F (BasicModeCtrl, AutoNegotiationEnable|AutoNegotiationRestart);
+			//////////////////////////////////////////////////////////////
+//			RTL_W16_F (BasicModeCtrl, value);
+			RTL_W8_F (Cfg9346, Cfg9346_Lock);
+		} else if (location < 8 && mii_2_8139_map[location])
+			RTL_W16_F (mii_2_8139_map[location], value);
+
+		return;
+	}
+	mdio_sync (mdio_addr);
+
+	/* Shift the command bits out. */
+	for (i = 31; i >= 0; i--) {
+		int dataval =
+		    (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
+		writeb (dataval, mdio_addr);
+		mdio_delay (mdio_addr);
+		writeb (dataval | MDIO_CLK, mdio_addr);
+		mdio_delay (mdio_addr);
+	}
+	/* Clear out extra bits. */
+	for (i = 2; i > 0; i--) {
+		writeb (0, mdio_addr);
+		mdio_delay (mdio_addr);
+		writeb (MDIO_CLK, mdio_addr);
+		mdio_delay (mdio_addr);
+	}
+	return;
+}
+
+static int rtl8139_open (struct net_device *dev)
+{
+	struct rtl8139_private *tp = dev->priv;
+	int retval;
+#ifdef RTL8139_DEBUG
+	void *ioaddr = tp->mmio_addr;
+#endif
+
+	DPRINTK ("ENTER\n");
+
+	retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev);
+	if (retval) {
+		DPRINTK ("EXIT, returning %d\n", retval);
+		return retval;
+	}
+
+	tp->tx_bufs = pci_alloc_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
+					   &tp->tx_bufs_dma);
+	tp->rx_ring = pci_alloc_consistent(tp->pci_dev, RX_BUF_TOT_LEN,
+					   &tp->rx_ring_dma);
+	if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
+		free_irq(dev->irq, dev);
+
+		if (tp->tx_bufs)
+			pci_free_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
+					    tp->tx_bufs, tp->tx_bufs_dma);
+		if (tp->rx_ring)
+			pci_free_consistent(tp->pci_dev, RX_BUF_TOT_LEN,
+					    tp->rx_ring, tp->rx_ring_dma);
+
+		DPRINTK ("EXIT, returning -ENOMEM\n");
+		return -ENOMEM;
+
+	}
+
+	tp->full_duplex = tp->duplex_lock;
+	tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000;
+	tp->twistie = 1;
+
+	rtl8139_init_ring (dev);
+	rtl8139_hw_start (dev);
+
+	DPRINTK ("%s: rtl8139_open() ioaddr %#lx IRQ %d"
+			" GP Pins %2.2x %s-duplex.\n",
+			dev->name, pci_resource_start (tp->pci_dev, 1),
+			dev->irq, RTL_R8 (MediaStatus),
+			tp->full_duplex ? "full" : "half");
+
+
+	DPRINTK ("EXIT, returning 0\n");
+	return 0;
+}
+
+
+/* Start the hardware at open or resume. */
+static void rtl8139_hw_start (struct net_device *dev)
+{
+	struct rtl8139_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+	u32 i;
+	u8 tmp;
+
+	DPRINTK ("ENTER\n");
+
+	/* Soft reset the chip. */
+	RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) | CmdReset);
+	udelay (100);
+
+	/* Check that the chip has finished the reset. */
+	for (i = 1000; i > 0; i--)
+		if ((RTL_R8 (ChipCmd) & CmdReset) == 0)
+			break;
+
+	/* unlock Config[01234] and BMCR register writes */
+	RTL_W8_F (Cfg9346, Cfg9346_Unlock);
+	/* Restore our idea of the MAC address. */
+	RTL_W32_F (MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
+	RTL_W32_F (MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
+
+	/* Must enable Tx/Rx before setting transfer thresholds! */
+	RTL_W8_F (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) |
+			   CmdRxEnb | CmdTxEnb);
+
+	i = rtl8139_rx_config |
+	    (RTL_R32 (RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
+	RTL_W32_F (RxConfig, i);
+
+	/* Check this value: the documentation for IFG contradicts ifself. */
+	RTL_W32 (TxConfig, (TX_DMA_BURST << TxDMAShift));
+
+	tp->cur_rx = 0;
+
+	/* This is check_duplex() */
+	if (tp->phys[0] >= 0  ||  (tp->drv_flags & HAS_MII_XCVR)) {
+		u16 mii_reg5 = mdio_read(dev, tp->phys[0], 5);
+		if (mii_reg5 == 0xffff)
+			;					/* Not there */
+		else if ((mii_reg5 & 0x0100) == 0x0100
+				 || (mii_reg5 & 0x00C0) == 0x0040)
+			tp->full_duplex = 1;
+		printk(KERN_INFO"%s: Setting %s%s-duplex based on"
+			   " auto-negotiated partner ability %4.4x.\n", dev->name,
+			   mii_reg5 == 0 ? "" :
+			   (mii_reg5 & 0x0180) ? "100mbps " : "10mbps ",
+			   tp->full_duplex ? "full" : "half", mii_reg5);
+	}
+
+	if (tp->chipset >= CH_8139A) {
+		tmp = RTL_R8 (Config1) & Config1Clear;
+		tmp |= Cfg1_Driver_Load;
+		tmp |= (tp->chipset == CH_8139B) ? 3 : 1; /* Enable PM/VPD */
+		RTL_W8_F (Config1, tmp);
+	} else {
+		u8 foo = RTL_R8 (Config1) & Config1Clear;
+		RTL_W8 (Config1, tp->full_duplex ? (foo|0x60) : (foo|0x20));
+	}
+
+	if (tp->chipset >= CH_8139B) {
+		tmp = RTL_R8 (Config4) & ~(1<<2);
+		/* chip will clear Rx FIFO overflow automatically */
+		tmp |= (1<<7);
+		RTL_W8 (Config4, tmp);
+
+		/* disable magic packet scanning, which is enabled
+		 * when PM is enabled above (Config1) */
+		RTL_W8 (Config3, RTL_R8 (Config3) & ~(1<<5));
+	}
+
+	/* Lock Config[01234] and BMCR register writes */
+	RTL_W8_F (Cfg9346, Cfg9346_Lock);
+	udelay (10);
+
+	/* init Rx ring buffer DMA address */
+	RTL_W32_F (RxBuf, tp->rx_ring_dma);
+
+	/* init Tx buffer DMA addresses */
+	for (i = 0; i < NUM_TX_DESC; i++)
+		RTL_W32_F (TxAddr0 + (i * 4), tp->tx_bufs_dma + (tp->tx_buf[i] - tp->tx_bufs));
+
+	RTL_W32_F (RxMissed, 0);
+
+	rtl8139_set_rx_mode (dev);
+
+	/* no early-rx interrupts */
+	RTL_W16 (MultiIntr, RTL_R16 (MultiIntr) & MultiIntrClear);
+
+	/* make sure RxTx has started */
+	RTL_W8_F (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) |
+			   CmdRxEnb | CmdTxEnb);
+
+	/* Enable all known interrupts by setting the interrupt mask. */
+	RTL_W16_F (IntrMask, rtl8139_intr_mask);
+
+	netif_start_queue (dev);
+
+	DPRINTK ("EXIT\n");
+}
+
+
+/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
+static void rtl8139_init_ring (struct net_device *dev)
+{
+	struct rtl8139_private *tp = dev->priv;
+	int i;
+
+	DPRINTK ("ENTER\n");
+
+	tp->cur_rx = 0;
+	tp->cur_tx = 0;
+	tp->dirty_tx = 0;
+
+	for (i = 0; i < NUM_TX_DESC; i++) {
+		tp->tx_info[i].skb = NULL;
+		tp->tx_info[i].mapping = 0;
+		tp->tx_buf[i] = &tp->tx_bufs[i * TX_BUF_SIZE];
+	}
+
+	DPRINTK ("EXIT\n");
+}
+
+
+static int rtl8139CP_open (struct net_device *dev)
+{
+	struct rtl8139_private *tp = dev->priv;
+	int retval;
+	u8 diff;			//for 8139C+
+	u32 txPhyAddr, rxPhyAddr;	//for 8139C+
+
+#ifdef RTL8139_DEBUG
+	void *ioaddr = tp->mmio_addr;
+#endif
+
+	DPRINTK ("ENTER\n");
+
+	retval = request_irq (dev->irq, rtl8139CP_interrupt, SA_SHIRQ, dev->name, dev);
+	if (retval) {
+		DPRINTK ("EXIT, returning %d\n", retval);
+		return retval;
+	}
+
+	//////////////////////////////////////////////////////////////////////////////
+	tp->TxDescArrays = pci_alloc_consistent(tp->pci_dev, NUM_CP_TX_DESC*sizeof(struct CPlusTxDesc)+256 ,
+					   &tp->TxDescArraysDMA);
+	// Tx Desscriptor needs 256 bytes alignment;
+	txPhyAddr=tp->TxDescArraysDMA;
+	diff=txPhyAddr-((txPhyAddr >> 8)<< 8);
+	diff=256-diff;
+	txPhyAddr +=diff;
+	tp->TxDescArray = (struct CPlusTxDesc *)(tp->TxDescArrays + diff);
+
+	tp->RxDescArrays = pci_alloc_consistent(tp->pci_dev, NUM_CP_RX_DESC*sizeof(struct CPlusRxDesc)+256 ,
+					   &tp->RxDescArraysDMA);
+	// Rx Desscriptor needs 256 bytes alignment;
+	rxPhyAddr=tp->RxDescArraysDMA;
+	diff=rxPhyAddr-((rxPhyAddr >> 8)<< 8);
+	diff=256-diff;
+	rxPhyAddr +=diff;
+	tp->RxDescArray = (struct CPlusRxDesc *)(tp->RxDescArrays + diff);
+	
+	if (tp->TxDescArrays == NULL || tp->RxDescArrays == NULL) {
+		printk(KERN_INFO"Allocate RxDescArray or TxDescArray failed\n");
+		free_irq(dev->irq, dev);
+		if (tp->TxDescArrays)
+			pci_free_consistent(tp->pci_dev, NUM_CP_TX_DESC*sizeof(struct CPlusTxDesc)+256,
+					   tp->TxDescArrays, tp->TxDescArraysDMA);
+		if (tp->RxDescArrays)
+			pci_free_consistent(tp->pci_dev, NUM_CP_RX_DESC*sizeof(struct CPlusRxDesc)+256,
+					   tp->RxDescArrays, tp->RxDescArraysDMA);
+		DPRINTK ("EXIT, returning -ENOMEM\n");
+		return -ENOMEM;
+	}
+	tp->RxBufferRings=pci_alloc_consistent(tp->pci_dev, CP_RX_BUF_SIZE*NUM_CP_RX_DESC, &tp->RxBufferRingsDMA);
+	if(tp->RxBufferRings==NULL){
+		printk(KERN_INFO"Allocate RxBufferRing failed\n");
+	}
+	//////////////////////////////////////////////////////////////////////////////
+	tp->full_duplex = tp->duplex_lock;
+	tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000;
+	tp->twistie = 1;
+
+	rtl8139CP_init_ring (dev);
+	rtl8139CP_hw_start (dev);
+
+	DPRINTK ("%s: rtl8139_open() ioaddr %#lx IRQ %d"
+			" GP Pins %2.2x %s-duplex.\n",
+			dev->name, pci_resource_start (tp->pci_dev, 1),
+			dev->irq, RTL_R8 (MediaStatus),
+			tp->full_duplex ? "full" : "half");
+
+
+	DPRINTK ("EXIT, returning 0\n");
+	return 0;
+}
+
+
+/* Start the hardware at open or resume. */
+static void rtl8139CP_hw_start (struct net_device *dev)
+{
+	struct rtl8139_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+	u32 i;
+	u8 tmp;
+	u16 BasicModeCtrlReg;
+	u8 MediaStatusReg;
+
+	DPRINTK ("ENTER\n");
+
+	/* Soft reset the chip. */
+	RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) | CmdReset);
+	udelay (100);
+
+	/* Check that the chip has finished the reset. */
+	for (i = 1000; i > 0; i--)
+		if ((RTL_R8 (ChipCmd) & CmdReset) == 0)
+			break;
+
+	/* unlock Config[01234] and BMCR register writes */
+	RTL_W8_F (Cfg9346, Cfg9346_Unlock);
+
+	RTL_W16 (CPlusCmd, CPlusTxEnb | CPlusRxEnb | CPlusCheckSumEnb);	//C+ mode only
+
+	/* Restore our idea of the MAC address. */
+	RTL_W32_F (MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
+	RTL_W32_F (MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
+
+	/* Must enable Tx/Rx before setting transfer thresholds! */
+	RTL_W8 (ChipCmd,CmdRxEnb | CmdTxEnb);					//C+ mode only
+	RTL_W8 (CPlusEarlyTxThldReg, CPlusEarlyTxThld);			//C+ mode only
+
+
+	i = rtl8139_rx_config | (RTL_R32 (RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
+	RTL_W32_F (RxConfig, i);
+
+	/* Check this value: the documentation for IFG contradicts ifself. */
+	RTL_W32 (TxConfig, (TX_DMA_BURST << TxDMAShift)|0x03000000);
+
+	tp->CP_cur_rx = 0;
+
+/*
+	//////////////////////////////////////////////////////////////
+	RTL_W8_F (Cfg9346, Cfg9346_Unlock);
+	RTL_W16 (NWayAdvert, AutoNegoAbility10half | AutoNegoAbility10full | AutoNegoAbility100half | AutoNegoAbility100full);
+	RTL_W16_F (BasicModeCtrl, AutoNegotiationEnable|AutoNegotiationRestart);
+	RTL_W8_F (Cfg9346, Cfg9346_Lock);
+	//////////////////////////////////////////////////////////////
+*/
+	MediaStatusReg = RTL_R8(MediaStatus);
+	BasicModeCtrlReg = RTL_R16(BasicModeCtrl);
+
+	/* This is check_duplex() */
+	if (tp->phys[0] >= 0  ||  (tp->drv_flags & HAS_MII_XCVR)) {
+		u16 mii_reg5 = mdio_read(dev, tp->phys[0], 5);
+		if (mii_reg5 == 0xffff)
+			;					/* Not there */
+		else if ((mii_reg5 & 0x0100) == 0x0100
+				 || (mii_reg5 & 0x00C0) == 0x0040)
+			tp->full_duplex = 1;
+/*
+		printk(KERN_INFO"%s: Setting %s%s-duplex based on"
+			   " auto-negotiated partner ability %4.4x.\n", dev->name,
+			   mii_reg5 == 0 ? "" :
+			   (mii_reg5 & 0x0180) ? "100mbps " : "10mbps ",
+			   tp->full_duplex ? "full" : "half", mii_reg5);
+*/
+		printk(KERN_INFO"%s: Setting %s%s-duplex based on"
+			   " auto-negotiated partner ability %4.4x.\n", dev->name,
+			   (MediaStatusReg & Speed_10) ? "10mbps " : "100mbps ",
+			   (BasicModeCtrlReg & DuplexMode) ? "full" : "half", mii_reg5);
+	}
+
+	if (tp->chipset >= CH_8139A) {
+		tmp = RTL_R8 (Config1) & Config1Clear;
+		tmp |= Cfg1_Driver_Load;
+		tmp |= (tp->chipset == CH_8139B) ? 3 : 1; /* Enable PM/VPD */
+		RTL_W8_F (Config1, tmp);
+	} else {
+		u8 foo = RTL_R8 (Config1) & Config1Clear;
+		RTL_W8 (Config1, tp->full_duplex ? (foo|0x60) : (foo|0x20));
+	}
+
+	if (tp->chipset >= CH_8139B) {
+		tmp = RTL_R8 (Config4) & ~(1<<2);
+		/* chip will clear Rx FIFO overflow automatically */
+		tmp |= (1<<7);
+		RTL_W8 (Config4, tmp);
+
+		/* disable magic packet scanning, which is enabled
+		 * when PM is enabled above (Config1) */
+		RTL_W8 (Config3, RTL_R8 (Config3) & ~(1<<5));
+	}
+
+	RTL_W32 ( CPlusTxStartAddr, (unsigned char *)tp->TxDescArray - tp->TxDescArrays + tp->TxDescArraysDMA);	//C+ mode only
+	RTL_W32 ( CPlusRxStartAddr, (unsigned char *)tp->RxDescArray - tp->RxDescArrays + tp->RxDescArraysDMA);	//C+ mode only	
+
+	/* Lock Config[01234] and BMCR register writes */
+	RTL_W8_F (Cfg9346, Cfg9346_Lock);
+	udelay (10);
+
+	RTL_W32_F (RxMissed, 0);
+
+	rtl8139_set_rx_mode (dev);
+
+	/* no early-rx interrupts */
+	RTL_W16 (MultiIntr, RTL_R16 (MultiIntr) & MultiIntrClear);
+
+	/* Enable all known interrupts by setting the interrupt mask. */
+	RTL_W16_F (IntrMask, rtl8139_intr_mask);
+
+	netif_start_queue (dev);
+
+	DPRINTK ("EXIT\n");
+}
+
+
+/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
+static void rtl8139CP_init_ring (struct net_device *dev)
+{
+	struct rtl8139_private *tp = dev->priv;
+	int i;
+
+
+	DPRINTK ("ENTER\n");
+
+	//////////////////////////////////////////////////////////////////////////////
+	tp->CP_cur_rx = 0;
+	tp->CP_cur_tx = 0;
+	tp->CP_dirty_tx = 0;
+	memset(tp->TxDescArray, 0x0, NUM_CP_TX_DESC*sizeof(struct CPlusTxDesc));
+	memset(tp->RxDescArray, 0x0, NUM_CP_RX_DESC*sizeof(struct CPlusRxDesc));
+
+	for (i=0 ; i<NUM_CP_TX_DESC ; i++){
+		tp->TxRingInfo[i].skb=NULL;
+		tp->TxRingInfo[i].mapping = 0;
+	}
+	for (i=0; i <NUM_CP_RX_DESC; i++) {
+		if(i==(NUM_CP_RX_DESC-1))
+			tp->RxDescArray[i].status = cpu_to_le32(0xC0000000+CP_RX_BUF_SIZE);
+		else
+			tp->RxDescArray[i].status = cpu_to_le32(0x80000000+CP_RX_BUF_SIZE);
+
+		tp->RxBufferRing[i]= &(tp->RxBufferRings[i*CP_RX_BUF_SIZE]);
+		tp->RxDescArray[i].buf_addr=cpu_to_le64(tp->RxBufferRing[i] - tp->RxBufferRings + tp->RxBufferRingsDMA);
+	}
+	//////////////////////////////////////////////////////////////////////////////
+	DPRINTK ("EXIT\n");
+}
+
+
+
+
+
+static void rtl8139_tx_clear (struct rtl8139_private *tp)
+{
+	int i;
+
+	tp->cur_tx = 0;
+	tp->dirty_tx = 0;
+
+	/* Dump the unsent Tx packets. */
+	for (i = 0; i < NUM_TX_DESC; i++) {
+		struct ring_info *rp = &tp->tx_info[i];
+		if (rp->mapping != 0) {
+			pci_unmap_single (tp->pci_dev, rp->mapping,
+					  rp->skb->len, PCI_DMA_TODEVICE);
+			rp->mapping = 0;
+		}
+		if (rp->skb) {
+			dev_kfree_skb (rp->skb);
+			rp->skb = NULL;
+			tp->stats.tx_dropped++;
+		}
+	}
+}
+
+
+static void rtl8139CP_tx_clear (struct rtl8139_private *tp)
+{
+	int i;
+
+	tp->CP_cur_tx=0;
+	for (i=0 ; i<NUM_CP_TX_DESC ; i++){
+		struct ring_info *rp = &tp->TxRingInfo[i];
+		if (rp->mapping != 0) {
+			pci_unmap_single (tp->pci_dev, rp->mapping,
+					  rp->skb->len, PCI_DMA_TODEVICE);
+			rp->mapping = 0;
+		}
+		if (rp->skb) {
+			dev_kfree_skb (rp->skb);
+			rp->skb = NULL;
+			tp->stats.tx_dropped++;
+		}
+	}
+}
+
+
+static void rtl8139_tx_timeout (struct net_device *dev)
+{
+	struct rtl8139_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+	u8 tmp8;
+
+	DPRINTK ("%s: Transmit timeout, status %2.2x %4.4x "
+		 "media %2.2x.\n", dev->name,
+		 RTL_R8 (ChipCmd),
+		 RTL_R16 (IntrStatus),
+		 RTL_R8 (MediaStatus));
+
+	/* disable Tx ASAP, if not already */
+	tmp8 = RTL_R8 (ChipCmd);
+	if (tmp8 & CmdTxEnb)
+		RTL_W8 (ChipCmd, tmp8 & ~CmdTxEnb);
+
+	/* Disable interrupts by clearing the interrupt mask. */
+	RTL_W16 (IntrMask, 0x0000);
+
+	/* Stop a shared interrupt from scavenging while we are. */
+	spin_lock_irq (&tp->lock);
+
+	rtl8139_tx_clear (tp);
+
+	spin_unlock_irq (&tp->lock);
+
+	/* ...and finally, reset everything */
+	rtl8139_hw_start (dev);	
+
+	netif_wake_queue (dev);
+}
+
+static void rtl8139CP_tx_timeout (struct net_device *dev)
+{
+	struct rtl8139_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+	u8 tmp8;
+
+	printk ("%s: %s - Transmit timeout, status %2.2x %4.4x "
+		 "media %2.2x.\n", dev->name, __FUNCTION__,
+		 RTL_R8 (ChipCmd),
+		 RTL_R16 (IntrStatus),
+		 RTL_R8 (MediaStatus));
+
+	/* disable Tx ASAP, if not already */
+	tmp8 = RTL_R8 (ChipCmd);
+	if (tmp8 & CmdTxEnb)
+		RTL_W8 (ChipCmd, tmp8 & ~CmdTxEnb);
+
+	/* Disable interrupts by clearing the interrupt mask. */
+	RTL_W16 (IntrMask, 0x0000);
+
+	/* Stop a shared interrupt from scavenging while we are. */
+	spin_lock_irq (&tp->lock);
+
+	rtl8139CP_tx_clear (tp);
+
+	spin_unlock_irq (&tp->lock);
+
+	/* ...and finally, reset everything */
+	rtl8139CP_hw_start (dev);
+
+	netif_wake_queue (dev);
+}
+
+
+static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
+{
+	struct rtl8139_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+	int entry;
+
+	/* Calculate the next Tx descriptor entry. */
+	entry = tp->cur_tx % NUM_TX_DESC;
+
+	assert (tp->tx_info[entry].skb == NULL);
+	assert (tp->tx_info[entry].mapping == 0);
+
+
+	// ----------------------------------------------
+	// For skb->len < 60, padding payload with 0x20.
+	// ----------------------------------------------
+	if( skb->len < ETH_ZLEN ){							//if data_len < 60
+		if( (skb->data + ETH_ZLEN) <= skb->end ){				//	if data_buf is greater than 60 bytes
+			//printk("%s:memset( skb->data + %d, 0x20, %d )\n", __FUNCTION__, skb->len, ETH_ZLEN - skb->len);
+			memset( skb->data + skb->len, 0x20, (ETH_ZLEN - skb->len) );	//		padding data payload with 0x20
+			skb->len = (skb->len >= ETH_ZLEN) ? skb->len : ETH_ZLEN;	//		data_len = 60
+		}
+		else{
+			printk("%s:(skb->data+ETH_ZLEN) > skb->end\n",__FUNCTION__);	//	data_buf is less than or equal to 60 bytes
+		}																//		do nothing
+	}
+
+
+	tp->tx_info[entry].skb = skb;
+	if ((long) skb->data & 3) {	/* Must use alignment buffer. */
+		/* tp->tx_info[entry].mapping = 0; */
+		memcpy (tp->tx_buf[entry], skb->data, skb->len);
+		RTL_W32 (TxAddr0 + (entry * 4),
+			 tp->tx_bufs_dma + (tp->tx_buf[entry] - tp->tx_bufs));
+	} else {
+		tp->tx_info[entry].mapping =
+		    pci_map_single (tp->pci_dev, skb->data, skb->len,
+				    PCI_DMA_TODEVICE);
+		RTL_W32 (TxAddr0 + (entry * 4), tp->tx_info[entry].mapping);
+	}
+
+	/* Note: the chip doesn't have auto-pad! */
+	RTL_W32 (TxStatus0 + (entry * sizeof (u32)),
+		 tp->tx_flag | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN));
+
+	dev->trans_start = jiffies;
+
+	spin_lock_irq (&tp->lock);
+
+	tp->cur_tx++;
+	if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
+		netif_stop_queue (dev);
+
+	spin_unlock_irq (&tp->lock);
+
+	DPRINTK ("%s: Queued Tx packet at %p size %u to slot %d.\n",
+		 dev->name, skb->data, skb->len, entry);
+
+	return 0;
+}
+
+
+static int rtl8139CP_start_xmit (struct sk_buff *skb, struct net_device *dev)
+{
+	struct rtl8139_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+	int CP_entry;
+	struct ethernet_ii_header *eIIHeader;
+	ip_v4_header   *IPPacket = NULL;
+	u32 tx_status;
+
+	mb();
+
+	DPRINTK("%s: %s!!!\n", dev->name, __FUNCTION__ );
+
+
+	CP_entry = tp->CP_cur_tx % NUM_CP_TX_DESC;			//C+ mode only
+
+	spin_lock_irq (&tp->lock);
+
+	tx_status = le32_to_cpu(tp->TxDescArray[CP_entry].status);
+	if( (tx_status & 0x80000000)==0 ){
+
+		tp->TxRingInfo[CP_entry].skb = skb;
+		tp->TxRingInfo[CP_entry].mapping =
+		    pci_map_single (tp->pci_dev, skb->data, skb->len,
+				    PCI_DMA_TODEVICE);
+		tp->TxDescArray[CP_entry].buf_addr=cpu_to_le64(tp->TxRingInfo[CP_entry].mapping);	//C+ mode only
+		if( CP_entry != (NUM_CP_TX_DESC-1) )
+		  tp->TxDescArray[CP_entry].status= cpu_to_le32(0xB0000000 |( (skb->len > ETH_ZLEN) ? skb->len : ETH_ZLEN));
+	        else
+		  tp->TxDescArray[CP_entry].status= cpu_to_le32(0xF0000000 |( (skb->len > ETH_ZLEN) ? skb->len : ETH_ZLEN));
+	
+		//////////////////////////////////////////////////////////////////////////////
+		if( skb->ip_summed == CHECKSUM_HW ){
+			eIIHeader = (struct ethernet_ii_header *) skb->data;
+    			// Check for Ethernet_II IP encapsulation //
+    			if (eIIHeader->TypeLength == IP_PROTOCOL) {
+        			// We need to point the IPPacket past the Ethernet_II header. //
+        			IPPacket = (ip_v4_header *) ((uint8_t *) eIIHeader + sizeof(struct ethernet_ii_header));
+		
+        			if (IPPacket->ProtocolCarried == TCP_PROTOCOL) {
+					tp->TxDescArray[CP_entry].status |= cpu_to_le32(CPlusTxIPchecksumOffload | CPlusTxTCPchecksumOffload);
+        			}
+        			else if (IPPacket->ProtocolCarried == UDP_PROTOCOL) {
+					tp->TxDescArray[CP_entry].status |= cpu_to_le32(CPlusTxIPchecksumOffload | CPlusTxUDPchecksumOffload);
+        			}
+    			}
+		}//end of if( skb->ip_summed == CHECKSUM_HW )
+		//////////////////////////////////////////////////////////////////////////////
+
+		RTL_W8 (CPlusTxPoll, 0x40);		//set polling bit
+
+		dev->trans_start = jiffies;
+
+		tp->CP_cur_tx++;						//C+ mode only
+		if ( (tp->CP_cur_tx - NUM_CP_TX_DESC) == tp->CP_dirty_tx )
+			netif_stop_queue (dev);
+	}//end of if( (tp->TxDescArray[CP_entry].status & 0x80000000)==0 )
+
+	spin_unlock_irq (&tp->lock);
+
+	mb();
+
+//	if ( (tp->CP_cur_tx - NUM_CP_TX_DESC) == tp->CP_dirty_tx )
+//		netif_stop_queue (dev);
+
+	return 0;
+}
+
+
+static void rtl8139_tx_interrupt (struct net_device *dev,
+				  struct rtl8139_private *tp,
+				  void *ioaddr)
+{
+	unsigned long dirty_tx, tx_left;
+
+	assert (dev != NULL);
+	assert (tp != NULL);
+	assert (ioaddr != NULL);
+
+	dirty_tx = tp->dirty_tx;
+	tx_left = tp->cur_tx - dirty_tx;
+	while (tx_left > 0) {
+		int entry = dirty_tx % NUM_TX_DESC;
+		int txstatus;
+
+		txstatus = RTL_R32 (TxStatus0 + (entry * sizeof (u32)));
+
+		if (!(txstatus & (TxStatOK | TxUnderrun | TxAborted)))
+			break;	/* It still hasn't been Txed */
+
+		/* Note: TxCarrierLost is always asserted at 100mbps. */
+		if (txstatus & (TxOutOfWindow | TxAborted)) {
+			/* There was an major error, log it. */
+			DPRINTK ("%s: Transmit error, Tx status %8.8x.\n",
+				 dev->name, txstatus);
+			tp->stats.tx_errors++;
+			if (txstatus & TxAborted) {
+				tp->stats.tx_aborted_errors++;
+				RTL_W32 (TxConfig, TxClearAbt | (TX_DMA_BURST << TxDMAShift));
+			}
+			if (txstatus & TxCarrierLost)
+				tp->stats.tx_carrier_errors++;
+			if (txstatus & TxOutOfWindow)
+				tp->stats.tx_window_errors++;
+#ifdef ETHER_STATS
+			if ((txstatus & 0x0f000000) == 0x0f000000)
+				tp->stats.collisions16++;
+#endif
+		} else {
+			if (txstatus & TxUnderrun) {
+				/* Add 64 to the Tx FIFO threshold. */
+				if (tp->tx_flag < 0x00300000)
+					tp->tx_flag += 0x00020000;
+				tp->stats.tx_fifo_errors++;
+			}
+			tp->stats.collisions += (txstatus >> 24) & 15;
+			tp->stats.tx_bytes += txstatus & 0x7ff;
+			tp->stats.tx_packets++;
+		}
+
+		/* Free the original skb. */
+		if (tp->tx_info[entry].mapping != 0) {
+			pci_unmap_single(tp->pci_dev,
+					 tp->tx_info[entry].mapping,
+					 tp->tx_info[entry].skb->len,
+					 PCI_DMA_TODEVICE);
+			tp->tx_info[entry].mapping = 0;
+		}
+		dev_kfree_skb_irq (tp->tx_info[entry].skb);
+		tp->tx_info[entry].skb = NULL;
+
+		dirty_tx++;
+		tx_left--;
+	}
+
+#ifndef RTL8139_NDEBUG
+	if (tp->cur_tx - dirty_tx > NUM_TX_DESC) {
+		printk (KERN_ERR "%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
+		        dev->name, dirty_tx, tp->cur_tx);
+		dirty_tx += NUM_TX_DESC;
+	}
+#endif /* RTL8139_NDEBUG */
+
+	/* only wake the queue if we did work, and the queue is stopped */
+	if (tp->dirty_tx != dirty_tx) {
+		tp->dirty_tx = dirty_tx;
+		if (netif_queue_stopped (dev))
+			netif_wake_queue (dev);
+	}
+}
+
+
+/* TODO: clean this up!  Rx reset need not be this intensive */
+static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
+			    struct rtl8139_private *tp, void *ioaddr)
+{
+	u8 tmp8;
+	int tmp_work = 1000;
+
+	DPRINTK ("%s: Ethernet frame had errors, status %8.8x.\n",
+	         dev->name, rx_status);
+	if (rx_status & RxTooLong) {
+		DPRINTK ("%s: Oversized Ethernet frame, status %4.4x!\n",
+			 dev->name, rx_status);
+		/* A.C.: The chip hangs here. */
+	}
+	tp->stats.rx_errors++;
+	if (rx_status & (RxBadSymbol | RxBadAlign))
+		tp->stats.rx_frame_errors++;
+	if (rx_status & (RxRunt | RxTooLong))
+		tp->stats.rx_length_errors++;
+	if (rx_status & RxCRCErr)
+		tp->stats.rx_crc_errors++;
+	/* Reset the receiver, based on RealTek recommendation. (Bug?) */
+	tp->cur_rx = 0;
+
+	/* disable receive */
+	tmp8 = RTL_R8 (ChipCmd) & ChipCmdClear;
+	RTL_W8_F (ChipCmd, tmp8 | CmdTxEnb);
+
+	/* A.C.: Reset the multicast list. */
+	rtl8139_set_rx_mode (dev);
+
+	/* XXX potentially temporary hack to
+	 * restart hung receiver */
+	while (--tmp_work > 0) {
+		tmp8 = RTL_R8 (ChipCmd);
+		if ((tmp8 & CmdRxEnb) && (tmp8 & CmdTxEnb))
+			break;
+		RTL_W8_F (ChipCmd,
+			  (tmp8 & ChipCmdClear) | CmdRxEnb | CmdTxEnb);
+	}
+
+	/* G.S.: Re-enable receiver */
+	/* XXX temporary hack to work around receiver hang */
+	rtl8139_set_rx_mode (dev);
+
+	if (tmp_work <= 0)
+		printk (KERN_WARNING PFX "tx/rx enable wait too long\n");
+}
+
+
+/* The data sheet doesn't describe the Rx ring at all, so I'm guessing at the
+   field alignments and semantics. */
+static void rtl8139_rx_interrupt (struct net_device *dev,
+				  struct rtl8139_private *tp, void *ioaddr)
+{
+	unsigned char *rx_ring;
+	u16 cur_rx;
+
+	assert (dev != NULL);
+	assert (tp != NULL);
+	assert (ioaddr != NULL);
+
+	rx_ring = tp->rx_ring;
+	cur_rx = tp->cur_rx;
+
+	DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x,"
+		 " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
+		 RTL_R16 (RxBufAddr),
+		 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
+
+	while ((RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
+		int ring_offset = cur_rx % RX_BUF_LEN;
+		u32 rx_status;
+		unsigned int rx_size;
+		unsigned int pkt_size;
+		struct sk_buff *skb;
+
+		/* read size+status of next frame from DMA ring buffer */
+		rx_status = le32_to_cpu (*(u32 *) (rx_ring + ring_offset));
+		rx_size = rx_status >> 16;
+		pkt_size = rx_size - 4;
+
+		DPRINTK ("%s:  rtl8139_rx() status %4.4x, size %4.4x,"
+			 " cur %4.4x.\n", dev->name, rx_status,
+			 rx_size, cur_rx);
+#if RTL8139_DEBUG > 2
+		{
+			int i;
+			DPRINTK ("%s: Frame contents ", dev->name);
+			for (i = 0; i < 70; i++)
+				printk (" %2.2x",
+					rx_ring[ring_offset + i]);
+			printk (".\n");
+		}
+#endif
+
+		/* E. Gill */
+		/* Note from BSD driver:
+		 * Here's a totally undocumented fact for you. When the
+		 * RealTek chip is in the process of copying a packet into
+		 * RAM for you, the length will be 0xfff0. If you spot a
+		 * packet header with this value, you need to stop. The
+		 * datasheet makes absolutely no mention of this and
+		 * RealTek should be shot for this.
+		 */
+		if (rx_size == 0xfff0)
+			break;
+
+		/* If Rx err or invalid rx_size/rx_status received
+		 * (which happens if we get lost in the ring),
+		 * Rx process gets reset, so we abort any further
+		 * Rx processing.
+		 */
+		if ((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
+		    (!(rx_status & RxStatusOK))) {
+			rtl8139_rx_err (rx_status, dev, tp, ioaddr);
+			return;
+		}
+
+		/* Malloc up new buffer, compatible with net-2e. */
+		/* Omit the four octet CRC from the length. */
+
+		/* TODO: consider allocating skb's outside of
+		 * interrupt context, both to speed interrupt processing,
+		 * and also to reduce the chances of having to
+		 * drop packets here under memory pressure.
+		 */
+		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+		if( CRC32DoubleCheck( &rx_ring[ring_offset + 4], pkt_size ) >= 0 )
+		{
+			skb = dev_alloc_skb (pkt_size + 2);
+			if (skb) {
+				skb->dev = dev;
+				skb_reserve (skb, 2);	/* 16 byte align the IP fields. */
+
+				eth_copy_and_sum (skb, &rx_ring[ring_offset + 4], pkt_size, 0);
+				skb_put (skb, pkt_size);
+				skb->protocol = eth_type_trans (skb, dev);
+				netif_rx (skb);
+
+				dev->last_rx = jiffies;
+				tp->stats.rx_bytes += pkt_size;
+				tp->stats.rx_packets++;
+			} else {
+				printk (KERN_WARNING
+					"%s: Memory squeeze, dropping packet.\n",
+					dev->name);
+				tp->stats.rx_dropped++;
+			}
+		}
+		else{
+			atomic_inc( &tp->CRC32DoubleCheck_ERR );
+			printk("%s: CRC double check failed.\n", dev->name);
+		}
+		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+		cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
+		RTL_W16_F (RxBufPtr, cur_rx - 16);
+	}
+
+	DPRINTK ("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
+		 " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
+		 RTL_R16 (RxBufAddr),
+		 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
+
+	tp->cur_rx = cur_rx;
+}
+
+
+static void rtl8139_weird_interrupt (struct net_device *dev,
+				     struct rtl8139_private *tp,
+				     void *ioaddr,
+				     int status, int link_changed)
+{
+	printk (KERN_DEBUG "%s: Abnormal interrupt, status %8.8x.\n",
+		dev->name, status);
+
+	assert (dev != NULL);
+	assert (tp != NULL);
+	assert (ioaddr != NULL);
+
+	/* Update the error count. */
+	tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+	RTL_W32 (RxMissed, 0);
+
+	if ((status & RxUnderrun) && link_changed &&
+	    (tp->drv_flags & HAS_LNK_CHNG)) {
+		/* Really link-change on new chips. */
+		int lpar = RTL_R16 (NWayLPAR);
+		int duplex = (lpar & 0x0100) || (lpar & 0x01C0) == 0x0040
+				|| tp->duplex_lock;
+		if (tp->full_duplex != duplex) {
+			tp->full_duplex = duplex;
+			RTL_W8 (Cfg9346, Cfg9346_Unlock);
+			RTL_W8 (Config1, tp->full_duplex ? 0x60 : 0x20);
+			RTL_W8 (Cfg9346, Cfg9346_Lock);
+		}
+		status &= ~RxUnderrun;
+	}
+
+	/* XXX along with rtl8139_rx_err, are we double-counting errors? */
+	if (status &
+	    (RxUnderrun | RxOverflow | RxErr | RxFIFOOver))
+		tp->stats.rx_errors++;
+
+	if (status & (PCSTimeout))
+		tp->stats.rx_length_errors++;
+	if (status & (RxUnderrun | RxFIFOOver))
+		tp->stats.rx_fifo_errors++;
+	if (status & RxOverflow) {
+		tp->stats.rx_over_errors++;
+		tp->cur_rx = RTL_R16 (RxBufAddr) % RX_BUF_LEN;
+		RTL_W16_F (RxBufPtr, tp->cur_rx - 16);
+	}
+	if (status & PCIErr) {
+		u16 pci_cmd_status;
+		pci_read_config_word (tp->pci_dev, PCI_STATUS, &pci_cmd_status);
+
+		printk (KERN_ERR "%s: PCI Bus error %4.4x.\n",
+			dev->name, pci_cmd_status);
+	}
+}
+
+
+/* The interrupt handler does all of the Rx thread work and cleans up
+   after the Tx thread. */
+static void rtl8139_interrupt (int irq, void *dev_instance,
+			       struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *) dev_instance;
+	struct rtl8139_private *tp = dev->priv;
+	int boguscnt = max_interrupt_work;
+	void *ioaddr = tp->mmio_addr;
+	int status = 0, link_changed = 0; /* avoid bogus "uninit" warning */
+
+	do {
+		status = RTL_R16 (IntrStatus);
+
+		/* h/w no longer present (hotplug?) or major error, bail */
+		if (status == 0xFFFF)
+			break;
+
+		/* Acknowledge all of the current interrupt sources ASAP, but
+		   an first get an additional status bit from CSCR. */
+		if (status & RxUnderrun){
+			link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit;
+			printk("TEST Link change!\n");
+		}
+
+		/* E. Gill */
+		/* In case of an RxFIFOOver we must also clear the RxOverflow
+		   bit to avoid dropping frames for ever. Believe me, I got a
+		   lot of troubles copying huge data (approximately 2 RxFIFOOver
+		   errors per 1GB data transfer).
+		   The following is written in the 'p-guide.pdf' file (RTL8139(A/B)
+		   Programming guide V0.1, from 1999/1/15) on page 9 from REALTEC.
+		   -----------------------------------------------------------
+		   2. RxFIFOOvw handling:
+		     When RxFIFOOvw occurs, all incoming packets are discarded.
+		     Clear ISR(RxFIFOOvw) doesn't dismiss RxFIFOOvw event. To
+		     dismiss RxFIFOOvw event, the ISR(RxBufOvw) must be written
+		     with a '1'.
+		   -----------------------------------------------------------
+		   Unfortunately I was not able to find any reason for the
+		   RxFIFOOver error (I got the feeling this depends on the
+		   CPU speed, lower CPU speed --> more errors).
+		   After clearing the RxOverflow bit the transfer of the
+		   packet was repeated and all data are error free transferred */
+		RTL_W16_F (IntrStatus, (status & RxFIFOOver) ? (status | RxOverflow) : status);
+
+		DPRINTK ("%s: interrupt  status=%#4.4x new intstat=%#4.4x.\n",
+				dev->name, status,
+				RTL_R16 (IntrStatus));
+
+		if ((status &
+		     (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
+		      RxFIFOOver | TxErr | TxOK | RxErr | RxOK)) == 0)
+			break;
+
+		/* Check uncommon events with one test. */
+		if (status & (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
+		  	      RxFIFOOver | TxErr | RxErr))
+			rtl8139_weird_interrupt (dev, tp, ioaddr,
+						 status, link_changed);
+
+		if (status & (RxOK | RxUnderrun | RxOverflow | RxFIFOOver))	/* Rx interrupt */
+			rtl8139_rx_interrupt (dev, tp, ioaddr);
+
+		if (status & (TxOK | TxErr)) {
+			spin_lock (&tp->lock);
+			rtl8139_tx_interrupt (dev, tp, ioaddr);
+			spin_unlock (&tp->lock);
+		}
+
+		boguscnt--;
+	} while (boguscnt > 0);
+
+	if (boguscnt <= 0) {
+		printk (KERN_WARNING
+			"%s: Too much work at interrupt, "
+			"IntrStatus=0x%4.4x.\n", dev->name,
+			status);
+
+		/* Clear all interrupt sources. */
+		RTL_W16 (IntrStatus, 0xffff);
+	}
+
+	DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
+		 dev->name, RTL_R16 (IntrStatus));
+}
+
+
+static void rtl8139CP_tx_interrupt (struct net_device *dev,
+				  struct rtl8139_private *tp,
+				  void *ioaddr)
+{
+	unsigned long CP_dirty_tx, CP_tx_left;			
+
+
+	assert (dev != NULL);
+	assert (tp != NULL);
+	assert (ioaddr != NULL);
+
+#ifdef CONFIG_LEDMAN
+	ledman_cmd(LEDMAN_CMD_SET, (dev->name[3] == '0') ?  LEDMAN_LAN1_TX :
+			((dev->name[3] == '1') ?  LEDMAN_LAN2_TX : LEDMAN_LAN3_TX));
+#endif
+
+	CP_dirty_tx = tp->CP_dirty_tx;
+	CP_tx_left = tp->CP_cur_tx - CP_dirty_tx;
+	while (CP_tx_left > 0) {					
+		unsigned long entry = CP_dirty_tx % NUM_CP_TX_DESC;
+	
+		if (tp->TxRingInfo[entry].mapping != 0) {
+			pci_unmap_single(tp->pci_dev,
+					 tp->TxRingInfo[entry].mapping,
+					 tp->TxRingInfo[entry].skb->len,
+					 PCI_DMA_TODEVICE);
+			tp->TxRingInfo[entry].mapping = 0;
+		}
+		dev_kfree_skb_irq (tp->TxRingInfo[entry].skb);
+		tp->TxRingInfo[entry].skb = NULL;
+		tp->stats.tx_packets++;			
+		CP_dirty_tx++;				
+		CP_tx_left--;				
+	}						
+
+	if (tp->CP_dirty_tx != CP_dirty_tx) {			
+		tp->CP_dirty_tx = CP_dirty_tx;			
+		if (netif_queue_stopped (dev))			
+			netif_wake_queue (dev);			
+	}							
+}
+
+
+/* The data sheet doesn't describe the Rx ring at all, so I'm guessing at the
+   field alignments and semantics. */
+static void rtl8139CP_rx_interrupt (struct net_device *dev,
+				  struct rtl8139_private *tp, void *ioaddr)
+{
+	int CP_cur_rx;						
+	struct sk_buff *skb; 					
+	int pkt_size=0 ;					
+	int boguscnt = max_interrupt_work;
+	u32 rx_status;
+
+
+	assert (dev != NULL);
+	assert (tp != NULL);
+	assert (ioaddr != NULL);
+
+#ifdef CONFIG_LEDMAN
+	ledman_cmd(LEDMAN_CMD_SET, (dev->name[3] == '0') ?  LEDMAN_LAN1_RX :
+			((dev->name[3] == '1') ?  LEDMAN_LAN2_RX : LEDMAN_LAN3_RX));
+#endif
+
+	CP_cur_rx = tp->CP_cur_rx;					
+
+	while (boguscnt--) {
+		rx_status = le32_to_cpu(tp->RxDescArray[CP_cur_rx].status);
+		if (rx_status & 0x80000000) {
+			if (boguscnt == max_interrupt_work-1)
+				printk("no rx\n");
+			break;
+		}
+		
+	    if (rx_status & CPlusRxRES){
+		printk(KERN_INFO"RTL8139: Rx ERROR!!!\n");
+		tp->stats.rx_errors++;
+		if (rx_status & CPlusRxFAE)
+			tp->stats.rx_frame_errors++;
+		if (rx_status & (CPlusRxRWT|CPlusRxRUNT) )
+			tp->stats.rx_length_errors++;
+		if (rx_status & CPlusRxCRC)
+			tp->stats.rx_crc_errors++;
+	    }
+	    else{
+	   	pkt_size=(int)(rx_status & 0x00001FFF)-4;
+		skb = dev_alloc_skb(pkt_size + 2);
+		if (skb != NULL) {
+		  	skb->dev = dev;
+			skb_reserve (skb, 2);	// 16 byte align the IP fields. //
+			eth_copy_and_sum(skb, tp->RxBufferRing[CP_cur_rx], pkt_size, 0);
+
+			////////For Checksum Offload///////////////////////////////////////
+			switch( (rx_status>>16)&0x3 ){
+				case ProtocolType_IP:
+							//if the protocol type is IP and IP checksum is correct//
+							if( (rx_status & CPlusRxIPchecksumBIT) == 0 )
+									skb->ip_summed=CHECKSUM_UNNECESSARY;
+							break;
+				case ProtocolType_TCPIP:
+							//if the protocol type is TCP/IP and TCP/IP checksum is correct//
+							if( (rx_status & CPlusRxTCPIPchecksumBIT) == 0 )
+									skb->ip_summed=CHECKSUM_UNNECESSARY;
+							break;
+				case ProtocolType_UDPIP:
+							//if the protocol type is UDP/IP and UDP/IP checksum is correct//
+							if( (rx_status & CPlusRxUDPIPchecksumBIT) == 0 )
+									skb->ip_summed=CHECKSUM_UNNECESSARY;
+							break;
+				default:
+							break;
+			}
+
+			///////////////////////////////////////////////////////////////////
+
+			skb_put(skb, pkt_size);
+			skb->protocol = eth_type_trans(skb, dev);
+
+			netif_rx (skb);
+
+			dev->last_rx = jiffies;
+	    		tp->stats.rx_bytes += pkt_size;
+	    		tp->stats.rx_packets++;
+		}
+		else{
+			printk(KERN_WARNING"%s: Memory squeeze, deferring packet.\n",dev->name);
+			/* We should check that some rx space is free.
+		   	If not, free one and mark stats->rx_dropped++. */
+			tp->stats.rx_dropped++;
+              	}
+	    }
+
+	    if( CP_cur_rx== (NUM_CP_RX_DESC-1) )
+		tp->RxDescArray[CP_cur_rx].status  = cpu_to_le32(0xC0000000 + CP_RX_BUF_SIZE);
+	    else
+		tp->RxDescArray[CP_cur_rx].status  = cpu_to_le32(0x80000000 + CP_RX_BUF_SIZE);
+
+	    tp->RxDescArray[CP_cur_rx].buf_addr  = cpu_to_le64(tp->RxBufferRing[CP_cur_rx] - tp->RxBufferRings + tp->RxBufferRingsDMA);
+
+	    CP_cur_rx = (CP_cur_rx +1) % NUM_CP_RX_DESC;
+	}// end of while ( (tp->RxDescArray[CP_cur_rx].status & 0x80000000)== 0)
+
+	tp->CP_cur_rx = CP_cur_rx;
+}
+
+/* The interrupt handler does all of the Rx thread work and cleans up
+   after the Tx thread. */
+static void rtl8139CP_interrupt (int irq, void *dev_instance,
+			       struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *) dev_instance;
+	struct rtl8139_private *tp = dev->priv;
+	int boguscnt = max_interrupt_work;
+	void *ioaddr = tp->mmio_addr;
+	int status = 0, link_changed = 0; /* avoid bogus "uninit" warning */
+
+	do {
+		status = RTL_R16 (IntrStatus);
+
+		/* h/w no longer present (hotplug?) or major error, bail */
+		if (status == 0xFFFF)
+			break;
+
+		/* Acknowledge all of the current interrupt sources ASAP, but
+		   an first get an additional status bit from CSCR. */
+		if (status & RxUnderrun){
+			printk("%s: %s RxUnderrun/Linkchange!\n", dev->name, __FUNCTION__);
+			rtl8139CP_init_ring (dev);
+			rtl8139CP_hw_start (dev);
+			link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit;
+		}
+
+		/* E. Gill */
+		/* In case of an RxFIFOOver we must also clear the RxOverflow
+		   bit to avoid dropping frames for ever. Believe me, I got a
+		   lot of troubles copying huge data (approximately 2 RxFIFOOver
+		   errors per 1GB data transfer).
+		   The following is written in the 'p-guide.pdf' file (RTL8139(A/B)
+		   Programming guide V0.1, from 1999/1/15) on page 9 from REALTEC.
+		   -----------------------------------------------------------
+		   2. RxFIFOOvw handling:
+		     When RxFIFOOvw occurs, all incoming packets are discarded.
+		     Clear ISR(RxFIFOOvw) doesn't dismiss RxFIFOOvw event. To
+		     dismiss RxFIFOOvw event, the ISR(RxBufOvw) must be written
+		     with a '1'.
+		   -----------------------------------------------------------
+		   Unfortunately I was not able to find any reason for the
+		   RxFIFOOver error (I got the feeling this depends on the
+		   CPU speed, lower CPU speed --> more errors).
+		   After clearing the RxOverflow bit the transfer of the
+		   packet was repeated and all data are error free transferred */
+		RTL_W16_F (IntrStatus, (status & RxFIFOOver) ? (status | RxOverflow) : status);
+
+		DPRINTK ("%s: interrupt  status=%#4.4x new intstat=%#4.4x.\n",
+				dev->name, status,
+				RTL_R16 (IntrStatus));
+
+		if ((status & (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
+		      RxFIFOOver | TxErr | TxOK | RxErr | RxOK)) == 0)
+			break;
+
+		if (status & (RxOK | RxUnderrun | RxOverflow | RxFIFOOver))	/* Rx interrupt */
+			rtl8139CP_rx_interrupt (dev, tp, ioaddr);
+
+		if (status & (TxOK | TxErr)) {
+			spin_lock (&tp->lock);
+			rtl8139CP_tx_interrupt (dev, tp, ioaddr);
+			spin_unlock (&tp->lock);
+		}
+
+		boguscnt--;
+	} while (boguscnt > 0);
+
+	if (boguscnt <= 0) {
+		printk (KERN_WARNING "%s: Too much work at interrupt, "	"IntrStatus=0x%4.4x.\n", dev->name,	status);
+
+		/* Clear all interrupt sources. */
+		RTL_W16 (IntrStatus, 0xffff);
+	}
+
+	DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n", dev->name, RTL_R16 (IntrStatus));
+}
+
+
+static int rtl8139_close (struct net_device *dev)
+{
+	struct rtl8139_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+	int ret = 0;
+
+	DPRINTK ("ENTER\n");
+
+	netif_stop_queue (dev);
+
+	if (tp->thr_pid >= 0) {
+		ret = kill_proc (tp->thr_pid, SIGTERM, 1);
+		if (ret) {
+			printk (KERN_ERR "%s: unable to signal thread\n", dev->name);
+			return ret;
+		}
+#if LINUX_VERSION_CODE < 0x20407
+		down (&tp->thr_exited);
+#else
+		wait_for_completion (&tp->thr_exited);
+#endif
+	}
+
+	DPRINTK ("%s: Shutting down ethercard, status was 0x%4.4x.\n", dev->name, RTL_R16 (IntrStatus));
+
+	spin_lock_irq (&tp->lock);
+
+	/* Stop the chip's Tx and Rx DMA processes. */
+	RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear));
+
+	/* Disable interrupts by clearing the interrupt mask. */
+	RTL_W16 (IntrMask, 0x0000);
+
+	/* Update the error counts. */
+	tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+	RTL_W32 (RxMissed, 0);
+
+	spin_unlock_irq (&tp->lock);
+
+	synchronize_irq ();
+	free_irq (dev->irq, dev);
+
+	rtl8139_tx_clear (tp);
+	pci_free_consistent(tp->pci_dev, RX_BUF_TOT_LEN,tp->rx_ring, tp->rx_ring_dma);
+	pci_free_consistent(tp->pci_dev, TX_BUF_TOT_LEN,tp->tx_bufs, tp->tx_bufs_dma);
+	tp->rx_ring = NULL;
+	tp->tx_bufs = NULL;
+	
+	/* Green! Put the chip in low-power mode. */
+	RTL_W8 (Cfg9346, Cfg9346_Unlock);
+	RTL_W8 (Config1, 0x03);
+	RTL_W8 (HltClk, 'H');	/* 'R' would leave the clock running. */
+
+	DPRINTK ("EXIT\n");
+	return 0;
+}
+
+static int rtl8139CP_close (struct net_device *dev)
+{
+	struct rtl8139_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+	int ret = 0;
+	int i;
+
+	DPRINTK ("ENTER\n");
+
+	netif_stop_queue (dev);
+
+	if (tp->thr_pid >= 0) {
+		ret = kill_proc (tp->thr_pid, SIGTERM, 1);
+		if (ret) {
+			printk (KERN_ERR "%s: unable to signal thread\n", dev->name);
+			return ret;
+		}
+
+#if LINUX_VERSION_CODE < 0x20407
+		down (&tp->thr_exited);
+#else
+		wait_for_completion (&tp->thr_exited);
+#endif
+	}
+
+	DPRINTK ("%s: Shutting down ethercard, status was 0x%4.4x.\n", dev->name, RTL_R16 (IntrStatus));
+
+	spin_lock_irq (&tp->lock);
+
+	/* Stop the chip's Tx and Rx DMA processes. */
+	RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear));
+
+	/* Disable interrupts by clearing the interrupt mask. */
+	RTL_W16 (IntrMask, 0x0000);
+
+	/* Update the error counts. */
+	tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+	RTL_W32 (RxMissed, 0);
+
+	spin_unlock_irq (&tp->lock);
+
+	synchronize_irq ();
+	free_irq (dev->irq, dev);
+
+	rtl8139CP_tx_clear (tp);
+	if (tp->TxDescArrays)
+		pci_free_consistent(tp->pci_dev, NUM_CP_TX_DESC*sizeof(struct CPlusTxDesc)+256,
+				   tp->TxDescArrays, tp->TxDescArraysDMA);
+	if (tp->RxDescArrays)
+		pci_free_consistent(tp->pci_dev, NUM_CP_RX_DESC*sizeof(struct CPlusRxDesc)+256,
+				   tp->RxDescArrays, tp->RxDescArraysDMA);
+	tp->TxDescArrays = NULL;
+	tp->RxDescArrays = NULL;
+	tp->TxDescArray = NULL;
+	tp->RxDescArray = NULL;
+	for (i=0; i <NUM_CP_RX_DESC; i++)tp->RxBufferRing[i]=NULL;
+	pci_free_consistent(tp->pci_dev, CP_RX_BUF_SIZE*NUM_CP_RX_DESC,
+			tp->RxBufferRings, tp->RxBufferRingsDMA);
+
+	/* Green! Put the chip in low-power mode. */
+	RTL_W8 (Cfg9346, Cfg9346_Unlock);
+	RTL_W8 (Config1, 0x03);
+	RTL_W8 (HltClk, 'H');	/* 'R' would leave the clock running. */
+
+	DPRINTK ("EXIT\n");
+	return 0;
+}
+
+
+
+
+
+
+
+
+static int mii_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct rtl8139_private *tp = dev->priv;
+	u16 *data = (u16 *) & rq->ifr_data;
+	int rc = 0;
+
+	DPRINTK ("ENTER\n");
+
+	switch (cmd) {
+	case SIOCDEVPRIVATE:	/* Get the address of the PHY in use. */
+		data[0] = tp->phys[0] & 0x3f;
+		/* Fall Through */
+
+	case SIOCDEVPRIVATE + 1:	/* Read the specified MII register. */
+		data[3] = mdio_read (dev, data[0], data[1] & 0x1f);
+		break;
+
+	case SIOCDEVPRIVATE + 2:	/* Write the specified MII register */
+		if (!capable (CAP_NET_ADMIN)) {
+			rc = -EPERM;
+			break;
+		}
+
+		if (data[0] == tp->phys[0]) {
+			u16 value = data[2];
+			switch (data[1]) {
+			case 0:
+				/* Check for autonegotiation on or reset. */
+				tp->medialock = (value & 0x9000) ? 0 : 1;
+				if (tp->medialock)
+					tp->full_duplex = (value & 0x0100) ? 1 : 0;
+				break;
+			case 4: tp->advertising = value; break;
+			}
+		}
+		mdio_write(dev, data[0], data[1] & 0x1f, data[2]);
+		break;
+
+	default:
+		rc = -EOPNOTSUPP;
+		break;
+	}
+
+	DPRINTK ("EXIT, returning %d\n", rc);
+	return rc;
+}
+
+
+static struct net_device_stats *rtl8139_get_stats (struct net_device *dev)
+{
+	struct rtl8139_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+
+	DPRINTK ("ENTER\n");
+
+	if (netif_running(dev)) {
+		spin_lock_irq (&tp->lock);
+		tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+		RTL_W32 (RxMissed, 0);
+		spin_unlock_irq (&tp->lock);
+	}
+
+	DPRINTK ("EXIT\n");
+	return &tp->stats;
+}
+
+/* Set or clear the multicast filter for this adaptor.
+   This routine is not state sensitive and need not be SMP locked. */
+
+static unsigned const ethernet_polynomial = 0x04c11db7U;
+static inline u32 ether_crc (int length, unsigned char *data)
+{
+	int crc = -1;
+
+	DPRINTK ("ENTER\n");
+
+	while (--length >= 0) {
+		unsigned char current_octet = *data++;
+		int bit;
+		for (bit = 0; bit < 8; bit++, current_octet >>= 1)
+			crc = (crc << 1) ^ ((crc < 0) ^ (current_octet & 1) ?
+			     ethernet_polynomial : 0);
+	}
+
+	DPRINTK ("EXIT, returning %u\n", crc);
+	return crc;
+}
+
+
+static void rtl8139_set_rx_mode (struct net_device *dev)
+{
+	struct rtl8139_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+	unsigned long flags;
+	u32 mc_filter[2];	/* Multicast hash filter */
+	int i, rx_mode;
+	u32 tmp;
+
+	DPRINTK ("ENTER\n");
+
+	DPRINTK ("%s:   rtl8139_set_rx_mode(%4.4x) done -- Rx config %8.8lx.\n",
+			dev->name, dev->flags, RTL_R32 (RxConfig));
+
+	/* Note: do not reorder, GCC is clever about common statements. */
+	if (dev->flags & IFF_PROMISC) {
+		/* Unconditionally log net taps. */
+		printk (KERN_NOTICE "%s: Promiscuous mode enabled.\n",
+			dev->name);
+		rx_mode =
+		    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
+		    AcceptAllPhys;
+		mc_filter[1] = mc_filter[0] = 0xffffffff;
+	} else if ((dev->mc_count > multicast_filter_limit)
+		   || (dev->flags & IFF_ALLMULTI)) {
+		/* Too many to filter perfectly -- accept all multicasts. */
+		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+		mc_filter[1] = mc_filter[0] = 0xffffffff;
+	} else {
+		struct dev_mc_list *mclist;
+		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+		mc_filter[1] = mc_filter[0] = 0;
+		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+		     i++, mclist = mclist->next)
+			set_bit (ether_crc (ETH_ALEN, mclist->dmi_addr) >> 26,
+				 mc_filter);
+	}
+
+	spin_lock_irqsave (&tp->lock, flags);
+
+	/* We can safely update without stopping the chip. */
+	tmp = rtl8139_rx_config | rx_mode |
+		(RTL_R32 (RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
+	RTL_W32_F (RxConfig, tmp);
+	RTL_W32_F (MAR0 + 0, mc_filter[0]);
+	RTL_W32_F (MAR0 + 4, mc_filter[1]);
+
+	spin_unlock_irqrestore (&tp->lock, flags);
+
+	DPRINTK ("EXIT\n");
+}
+
+#ifdef CONFIG_PM
+
+#if LINUX_VERSION_CODE < 0x20407
+static void rtl8139_suspend (struct pci_dev *pdev)
+#else
+static int rtl8139_suspend (struct pci_dev *pdev, u32 state)
+#endif
+{
+	struct net_device *dev = pdev->driver_data;
+	struct rtl8139_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+	unsigned long flags;
+
+	netif_device_detach (dev);
+
+	spin_lock_irqsave (&tp->lock, flags);
+
+	/* Disable interrupts, stop Tx and Rx. */
+	RTL_W16 (IntrMask, 0x0000);
+	RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear));
+
+	/* Update the error counts. */
+	tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+	RTL_W32 (RxMissed, 0);
+
+	spin_unlock_irqrestore (&tp->lock, flags);
+
+#if LINUX_VERSION_CODE < 0x20407
+#else
+	return 0;
+#endif
+}
+
+
+#if LINUX_VERSION_CODE < 0x20407
+static void rtl8139_resume (struct pci_dev *pdev)
+#else
+static int rtl8139_resume (struct pci_dev *pdev)
+#endif
+{
+	struct net_device *dev = pdev->driver_data;
+	struct rtl8139_private *tp = dev->priv;
+
+	netif_device_attach (dev);
+	if( rtl_chip_info[tp->chipset].name == "RTL-8139CP" )
+		rtl8139CP_hw_start (dev);
+	else
+		rtl8139_hw_start (dev);
+
+#if LINUX_VERSION_CODE < 0x20407
+#else
+	return 0;
+#endif
+}
+
+#endif	//end of #ifdef CONFIG_PM
+
+static struct pci_driver rtl8139_pci_driver = {
+	name:		MODNAME,
+	id_table:	rtl8139_pci_tbl,
+	probe:		rtl8139_init_one,
+	remove:		__devexit_p(rtl8139_remove_one),
+#ifdef CONFIG_PM
+	suspend:	rtl8139_suspend,
+	resume:		rtl8139_resume,
+#endif	//end of #ifdef CONFIG_PM	
+};
+
+
+static int __init rtl8139_init_module (void)
+{
+	return pci_module_init (&rtl8139_pci_driver);
+}
+
+
+static void __exit rtl8139_cleanup_module (void)
+{
+	pci_unregister_driver (&rtl8139_pci_driver);
+}
+
+
+module_init(rtl8139_init_module);
+module_exit(rtl8139_cleanup_module);
diff -urN linux-2.4.29/drivers/net/8390.c linux-2.4.29-uc1/drivers/net/8390.c
--- linux-2.4.29/drivers/net/8390.c	2005-01-19 14:09:56.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/8390.c	2005-06-14 02:12:15.000000000 +0100
@@ -41,6 +41,10 @@
 			  module by all drivers that require it.
   Alan Cox		: Spinlocking work, added 'BUG_83C690'
   Paul Gortmaker	: Separate out Tx timeout code from Tx path.
+ 
+  Greg Ungerer		: added some coldfire addressing code.
+
+  Yoshinori Sato    : added H8/300H support.
 
   Sources:
   The National Semiconductor LAN Databook, and the 3Com 3c503 databook.
@@ -76,6 +80,22 @@
 #define NS8390_CORE
 #include "8390.h"
 
+#ifdef CONFIG_COLDFIRE
+#ifdef CONFIG_NE2K_PCI
+#include <asm/mcfpci.h>
+#else
+#include <asm/mcfne.h>
+#endif /* CONFIG_NE2K_PCI */
+#endif /* CONFIG_COLDFIRE */
+
+#if defined(CONFIG_CPU_H8300H)
+#include <asm/h8300_ne.h>
+#endif
+
+#ifdef CONFIG_LEDMAN
+#include <linux/ledman.h>
+#endif
+
 #define BUG_83C690
 
 /* These are the operational function interfaces to board-specific
@@ -436,6 +456,10 @@
 		printk ("net_interrupt(): irq %d for unknown device.\n", irq);
 		return;
 	}
+
+#ifdef CONFIG_M5272
+    ne2000_irqack(irq);
+#endif
     
 	e8390_base = dev->base_addr;
 	ei_local = (struct ei_device *) dev->priv;
@@ -477,6 +501,17 @@
 			interrupts = 0;
 			break;
 		}
+#ifdef CONFIG_LEDMAN
+        if (interrupts & (ENISR_TX|ENISR_TX_ERR)) {
+            ledman_cmd(LEDMAN_CMD_SET,
+                    strcmp(dev->name, "eth0") == 0 ? LEDMAN_LAN1_TX :
+							LEDMAN_LAN2_TX);
+        } else {
+            ledman_cmd(LEDMAN_CMD_SET,
+                    strcmp(dev->name, "eth0") == 0 ? LEDMAN_LAN1_RX :
+							LEDMAN_LAN2_RX);
+        }
+#endif
 		if (interrupts & ENISR_OVER) 
 			ei_rx_overrun(dev);
 		else if (interrupts & (ENISR_RX+ENISR_RX_ERR)) 
diff -urN linux-2.4.29/drivers/net/au1000_eth.c linux-2.4.29-uc1/drivers/net/au1000_eth.c
--- linux-2.4.29/drivers/net/au1000_eth.c	2005-01-19 14:09:56.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/au1000_eth.c	2005-06-14 02:12:13.000000000 +0100
@@ -1206,6 +1206,18 @@
 	if (ioaddr == iflist[0].base_addr)
 	{
 		/* check env variables first */
+#if CONFIG_MIPS_VEGAS
+		{
+			unsigned long 	*reg;
+		
+			reg = (unsigned long *) 0xbfc40000;
+			if ((*reg == 0xffffffff && (*(reg+1) & 0xffff0000) == 0xffff0000) ||
+					(*reg == 0x0 && (*(reg+1) & 0xffff0000) == 0x0))
+				reg = (unsigned long *) au1000_mac_addr;
+			memcpy(au1000_mac_addr, reg, 
+						sizeof(dev->dev_addr));
+		}
+#else
 		if (!get_ethernet_addr(ethaddr)) { 
 			memcpy(au1000_mac_addr, ethaddr, sizeof(dev->dev_addr));
 		} else {
@@ -1221,6 +1233,8 @@
 						sizeof(dev->dev_addr));
 			}
 		}
+#endif
+		if (ioaddr == AU1000_ETH0_BASE)
 			aup->enable = (volatile u32 *) 
 				((unsigned long)iflist[0].macen_addr);
 		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
@@ -1380,7 +1394,9 @@
 	}
 	au_sync();
 
+#ifdef CLEANUP
 	aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed);
+#endif
 	control = MAC_DISABLE_RX_OWN | MAC_RX_ENABLE | MAC_TX_ENABLE;
 #ifndef CONFIG_CPU_LITTLE_ENDIAN
 	control |= MAC_BIG_ENDIAN;
@@ -1410,6 +1426,8 @@
 	}
 
 	if_port = dev->if_port;
+
+#ifdef CLEANUP	
 	if (aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed) == 0) {
 		if (link) {
 			if (!(dev->flags & IFF_RUNNING)) {
@@ -1427,6 +1445,7 @@
 			}
 		}
 	}
+#endif
 
 	if (link && (dev->if_port != if_port) && 
 			(dev->if_port != IF_PORT_UNKNOWN)) {
@@ -1869,6 +1888,7 @@
 				dev->name, dev->if_port, map->port);
 	}
 
+#if 0
 	switch(map->port){
 		case IF_PORT_UNKNOWN: /* use auto here */   
 			printk(KERN_INFO "%s: config phy for aneg\n", 
@@ -1950,6 +1970,7 @@
 					dev->name);
 			return -EINVAL;
 	}
+#endif	
 	return 0;
 }
 
diff -urN linux-2.4.29/drivers/net/cnxt_emac/cnxtEmac.c linux-2.4.29-uc1/drivers/net/cnxt_emac/cnxtEmac.c
--- linux-2.4.29/drivers/net/cnxt_emac/cnxtEmac.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/cnxtEmac.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,3300 @@
+/****************************************************************************
+*
+*	Name:			cnxtEmac.c
+*
+*	Description:	Emac driver for CX821xx products
+*
+*	Copyright:		(c) 2001,2002 Conexant Systems Inc.
+*					Personal Computing Division
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+*****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.2 $
+*  $Modtime:   Aug 08 2003 08:13:00  $
+****************************************************************************/
+
+static char *version =
+"EMAC Network Driver Cnxt 2003/07/16";
+
+/* Always include 'config.h' first in case the user wants to turn on
+   or override something. */
+#define __KERNEL_SYSCALLS__
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/unistd.h>
+#include <linux/config.h>
+
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <linux/errno.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <asm/arch/bspcfg.h>
+#include <asm/hardware.h>
+#include "osutil.h"
+#include <asm/arch/irq.h>
+#include <asm/arch/sysmem.h>
+#include "cnxtEmac.h"
+#include <asm/delay.h>
+
+#if HOMEPLUGPHY
+#include "tesla.h"
+#endif
+
+#define SDRAM_TX_MEM			1
+#define HW_RESET_EVENT			1
+#define EMAC_TX_WD_TIMER		1
+#define EMAC_MUTUALLY_EX_OPR	1
+#define EMAC_CHK_HW_4_MUTEX_OPR	0
+#define	TX_FULL_DUPLEX			1
+#define RX_SKB_DEBUG			0
+#define SETUP_FRAME_VERIFY		0
+#define RX_TASKLET				1
+#ifdef CONFIG_BD_TIBURON
+#define TX_TASKLET				1
+#define	TX_DMA_INT				1
+#else
+#define TX_TASKLET				0
+#define	TX_DMA_INT				0
+#endif
+#define	RX_DMA_INT				1
+#define USE_TU_INTERRUPT		1
+#define USE_HASHTABLE			0
+#define	EMAC_ISR_ERR_MSG_PRINT	1
+#define EMAC_DISABLE_CHK		1
+#define EMAC_TX_UDELAY			1
+
+#define RX_COPY_MEMORY( pDest, pSrc, size ) memcpy( pDest, pSrc, size )
+#define TX_COPY_MEMORY( pDest, pSrc, size ) memcpy( pDest, pSrc, size )
+
+#if CONFIG_CPU_ARM940_D_CACHE_ON
+#define EMAC_KMALLOC(s,flg)     emac_AllocNonCachedMem((s),(flg))
+#define	EMAC_KFREE(p)			
+#else
+#define EMAC_KMALLOC(s,flg)     kmalloc((s),(flg))
+#define	EMAC_KFREE(p)			kfree(p)
+#endif
+
+#define	DWORD_ALIGN_IP_HDR	2
+#define TX_TIMEOUT_DELAY	15		// 150 ms delay
+//#define TX_TIMEOUT_DELAY	10		// 100 ms delay
+#define	TX_MSG_Q_THRESHOLD			4
+#define	TX_MSG_Q_AWAKE_THRESHOLD	TX_MSG_Q_THRESHOLD + 0
+//#define	TX_MSG_Q_THRESHOLD	TX_RING_SIZE
+#define LOW_QWORD_MASK		0xFFFFFFF0
+
+#define SLAVE_ADDRESS		0xA0	// bit 1 is page block number
+#define CLOSED				FALSE
+#define	OPEN				TRUE
+#define	DRAM_8M_SIZE		0x800000
+#define	ENABLED				1
+
+#if CONFIG_NUM_ETHERNET_IS_1
+	#define MAX_ETH_PORTS	1
+#endif
+
+#if CONFIG_NUM_ETHERNET_IS_2
+	#define MAX_ETH_PORTS	2
+#endif
+
+#if CONFIG_NUM_ETHERNET_IS_3
+	#define MAX_ETH_PORTS	3
+#endif
+
+#if CONFIG_NUM_ETHERNET_IS_4
+	#define MAX_ETH_PORTS	4
+#endif
+
+// NOTE: EMAC_tx_pkt_q2 will be the common tx queue for
+// mutually exclusive transmitter operation.
+DATA_QUEUE_T	*EMAC_tx_pkt_q1;
+DATA_QUEUE_T	*EMAC_tx_pkt_q2;	
+
+DWORD			EMAC_num_in_operation = NONE;
+DWORD			EMAC_hdw_cntr = 0;
+DWORD			unhandled_emac_tx_error = 0;
+DWORD			emac_rx_proc_no_skb;
+struct net_device	*emac_dev[MAX_ETH_PORTS];
+BOOLEAN			emac_mutually_ex_opr;
+
+#define RX_LOOKBACK_THRESHOLD	20
+WORD	rx_lookback_idx[RX_RING_SIZE];
+
+#if SETUP_FRAME_VERIFY
+BOOLEAN		sf_verify;
+#endif
+
+// Emac 1 registers
+volatile unsigned long* DMAC_1_Ptr1 = (unsigned long*)0x00300000;
+volatile unsigned long* DMAC_1_Ptr2 = (unsigned long*)0x00300030;
+volatile unsigned long* DMAC_2_Ptr2 = (unsigned long*)0x00300034;
+volatile unsigned long* DMAC_1_Cnt1 = (unsigned long*)0x00300060;
+volatile unsigned long* DMAC_2_Cnt1 = (unsigned long*)0x00300064;
+volatile unsigned long* DMAC_2_Cnt2 = (unsigned long*)0x00300094;
+
+// Emac 2 registers
+volatile unsigned long* DMAC_3_Ptr1 = (unsigned long*)0x00300008;
+volatile unsigned long* DMAC_3_Ptr2 = (unsigned long*)0x00300038;
+volatile unsigned long* DMAC_4_Ptr2 = (unsigned long*)0x0030003C;
+volatile unsigned long* DMAC_3_Cnt1 = (unsigned long*)0x00300068;
+volatile unsigned long* DMAC_4_Cnt1 = (unsigned long*)0x0030006C;
+volatile unsigned long* DMAC_4_Cnt2 = (unsigned long*)0x0030009C;
+
+volatile unsigned long* INT_Stat = (unsigned long*)0x00350044;
+volatile unsigned long* INT_Msk = (unsigned long*)0x0035004c;
+volatile unsigned long* INT_MStat = (unsigned long*)0x00350090;
+
+volatile unsigned long* E_STAT_1_reg	= (volatile unsigned long*)0x00310008;
+volatile unsigned long* E_NA_1_reg  	= (volatile unsigned long*)0x00310004;
+volatile unsigned long* E_IE_1_reg	 	= (volatile unsigned long*)0x0031000C;
+volatile unsigned long* E_LP_1_reg	 	= (volatile unsigned long*)0x00310010;
+
+volatile unsigned long* E_STAT_2_reg	= (volatile unsigned long*)0x00320008;
+volatile unsigned long* E_NA_2_reg  	= (volatile unsigned long*)0x00320004;
+volatile unsigned long* E_IE_2_reg		= (volatile unsigned long*)0x0032000C;
+volatile unsigned long* E_LP_2_reg		= (volatile unsigned long*)0x00320010;
+
+volatile unsigned long* M2M_Cnt   = (volatile unsigned long* ) 0x00350004;
+volatile unsigned long* DMA7_Ptr1 = (volatile unsigned long* ) 0x00300018;
+volatile unsigned long* DMA8_Ptr1 = (volatile unsigned long* ) 0x0030001C;
+
+#define NUM_EMACS		2
+#define	MAC_ADDR_OFFSET_SIZE	1
+#define ADDRESS_FILTER_SIZE   192
+
+extern void CnxtBsp_Get_Mac_Address( int emac_num, char *mac_addr_array );
+extern int cnxt_irq_mask_state_chk( unsigned int irq_num );
+extern PHY_STATUS PhyConnectSet(PHY *phy, DWORD connect);
+extern void TaskDelayMsec(UINT32 TimeDuration);
+extern BOOLEAN CnxtBsp_Mac_MutEx_Chk( void );
+
+static int EMAC_restart_hw( struct net_device *dev, BOOLEAN flush_txq, BOOLEAN flush_rxq );
+static int EMAC_restart_rx( struct net_device *dev, BOOLEAN flush_rxq );
+
+/* Index to functions, as function prototypes. */
+int emac_probe(struct net_device *dev);
+#if USE_HASHTABLE
+	static void SetupHashTable(struct net_device *dev);
+#endif
+void ResetChip( EMAC_DRV_CTRL *thisadapter );
+
+static int emac_open(struct net_device *dev);
+static int emac_send_packet(struct sk_buff *skb, struct net_device *dev);
+static int emac_close(struct net_device *dev);
+static struct net_device_stats *emac_get_stats(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
+
+void EMAC_Linkcheck(EMAC_DRV_CTRL *thisadapter, BOOLEAN force_update );
+BOOLEAN emac_SetupFrame ( struct net_device *dev );
+
+#if RX_SKB_DEBUG
+	static void skb_debug(const struct sk_buff *skb)
+	{
+	#define NUM2PRINT 80
+		char buf[NUM2PRINT * 3 + 1];	/* 3 chars per byte */
+		int i = 0;
+		for (i = 0; i < skb->len && i < NUM2PRINT; i++) {
+			sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
+		}
+		printk("skb->data: %s\n", buf);
+	}
+#endif
+
+#if CONFIG_CPU_ARM940_D_CACHE_ON
+
+/******************************************************************************
+|
+|  Function:    emacAllocNonCachedMem
+|
+|  Description: This function emulate the calloc () call to allocate a block
+|               of memory space from the non-cached memory space.  When DATA
+|               Cache is turned on, EMAC must use the non-cached memory space
+|               for its Tx descriptors, Rx descriptors, and data buffers which
+|               will be accessed by DMA.
+|
+|  Parameters:  size_t  n       number of memory elements
+|               size_t  size    number of bytes for each memory elements
+|
+|  Returns:     void    *pMem   pointer to the start of the memory allocated
+|               NULL            don't have enough room for the requested space
+|
+*******************************************************************************/
+
+void *emac_AllocNonCachedMem ( size_t size, int flags )
+{
+	// Request non-cached SDRAM memory
+	return SYSMEM_Allocate_BlockMemory( 0, (int) size, 16);
+}
+#endif
+
+DWORD	emac1_tx_reset = 0;
+DWORD	emac2_tx_reset = 0;
+DWORD	emac1_rx_reset = 0;
+DWORD	emac2_rx_reset = 0;
+
+void EMAC_Disabled_Check( struct net_device *dev )
+{
+	EMAC_DRV_CTRL *thisadapter = ( EMAC_DRV_CTRL *)dev->priv; 
+
+	if
+	(		
+		//	thisadapter->phyState.duplexMode == PHY_STAT_DUPLEX_HALF
+		//&&	thisadapter->emac_state == OPEN
+			thisadapter->emac_state == OPEN
+		&&	thisadapter->hw_reset_required == TRUE
+	)
+	{
+		thisadapter->hw_reset_required = FALSE;
+		switch( thisadapter->emac_num )
+		{
+			// emac1
+			case 1:
+				emac1_tx_reset++;
+				break;
+
+			case 2:
+				emac2_tx_reset++;
+				break;
+		}
+
+		// Tell the OS we are closed
+		netif_stop_queue(dev);
+
+		// Restart the hardware to bring it into a known state
+		EMAC_restart_hw( dev, TRUE, TRUE );
+	}
+}
+
+
+/*
+	 Parameters :
+		BOOLEAN Port_Mii: 
+			TRUE: configure MAC MII interface
+			FALSE: configure MAC 7WS interface 
+		BOOLEAN Speed100m: 
+			TRUE: configure MAC device speed 100M
+			FALSE: configure MAC device speed 1/10M
+		BOOLEAN Full_Duplex:
+			TRUE: configure MAC full duplex
+			FALSE: configure MAC half duplex
+*/
+void EMACHW_Configure_Mac
+(
+	EMAC_DRV_CTRL	*thisadapter,
+	int 			Port_Mii,
+	int 			Speed100m,
+	int 			Full_Duplex
+)
+{
+	unsigned long E_NA_settings ;
+
+	// don't care Port_Mii, CX82100 do not support 7WS mode
+	E_NA_settings = *thisadapter->emac_na_reg;
+
+	// Set default conditions
+	E_NA_settings &= ~(E_NA_NS|E_NA_FD);
+
+	if( !Speed100m)
+	{ 
+		E_NA_settings |= E_NA_NS;	// 10m
+	}
+
+	if( Full_Duplex )
+	{
+		E_NA_settings |= E_NA_FD;   // Full Duplex 
+	}
+
+	*thisadapter->emac_na_reg = E_NA_settings;
+	thisadapter->E_NA_settings = E_NA_settings;
+
+// related to ADI DSLAM/>6 Mbps/Win XP/FTP issue.  During FTP transfer, session dies but
+// it will work if we force 10 HDX
+	if ( thisadapter->phyState.linkStatus == PHY_STAT_LINK_UP )
+	{
+		if( !Speed100m && !Full_Duplex )
+		{
+			PhyConnectSet( thisadapter->pPhy, PHY_CONN_10BASE_T );
+		}
+	}
+	else
+	{
+		PhyConnectSet( thisadapter->pPhy, PHY_CONN_AUTONEG_ALL_MEDIA );
+	}
+
+#if 0
+	if( thisadapter->emac_num == 1)
+	{
+		printk("\neth0 hw update: ");
+		if( !Speed100m)
+		{ 
+			printk(" 10M");
+		}
+		else
+		{
+			printk(" 100M");
+		}
+		if( Full_Duplex )
+		{ 
+			printk(" FULL\n");
+		}
+		else
+		{
+			printk(" HALF\n");
+		}
+		if( emac_mutually_ex_opr == FALSE )
+		{
+			printk("emac_mutually_ex_opr = FALSE\n");
+		}
+		else
+		{
+			printk("emac_mutually_ex_opr = TRUE\n");
+		}
+		if(thisadapter->phyState.linkStatus == PHY_STAT_LINK_UP)
+		{
+			printk("PHY_LINK_UP\n");
+		}
+		else
+		{
+			printk("PHY_LINK_DOWN\n");
+		}
+	}
+#endif
+}
+
+
+BOOL EMAC_GetPortConfig( int dev_num,  EMAC_DRV_CTRL *pthisadapter )
+{
+    pthisadapter->MacFilteringMode = 2; 		// Not sure if we need this
+    pthisadapter->phyState.autoNegotiate = 1;	// 0: disable,  1: enable
+    pthisadapter->phyState.networkSpeed = 1; 	// 0: 10M,  1: 100M
+    pthisadapter->phyState.duplexMode = 1;		// 0: HDX,  1: FDX
+
+    return TRUE;
+}
+
+
+/******************************************************************************
+|
+|  Function:    EMAC_MapToPhyConn
+|
+|  Description: Convert PHY settings to PHY_CONN_XXXX as defined in phy.h
+|               established link rate
+|
+|  Parameters:  *pPhySettings - pointer to PHY_SETTING structure containing
+|                               speed/duplex configurations
+|
+|  Returns:     The PHY_CONN_XXXX corresponds to the specified PHY configurations
+|
+*******************************************************************************/
+
+UINT32 EMAC_MapToPhyConn ( PHY_SETTING *pPhySettings )
+{
+    UINT32  conn;
+
+    if ( pPhySettings->autoNegotiate == PHY_AUTONEGOTIATE )
+	{
+        conn = PHY_CONN_AUTONEG_ALL_MEDIA;
+	}
+    else
+    {
+        if ( pPhySettings->networkSpeed == PHY_STAT_SPEED_100 )
+        {
+            if ( pPhySettings->duplexMode == PHY_STAT_DUPLEX_FULL )
+			{
+                conn = PHY_CONN_100BASE_TXFD | PHY_CONN_AUTONEG;
+			}
+            else
+			{
+                conn = PHY_CONN_100BASE_TX;
+			}
+        }
+        else
+        {
+            if ( pPhySettings->duplexMode == PHY_STAT_DUPLEX_FULL )
+			{
+                conn = PHY_CONN_10BASE_TFD | PHY_CONN_AUTONEG;
+            }
+            else
+            {
+                conn = PHY_CONN_10BASE_T;
+			}
+        }
+    }
+    return ( conn );
+}
+
+	
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_Queue_Data
+		
+ABSTRACT:
+		Places data on the queue of the data queue context
+		Returns TRUE if successful.  FALSE if not.
+
+  		This function is intended to be called from within an interrupt handler
+		therefor it does not wrap the checking of the queue status with IRQ protection.
+		
+DETAILS:
+		Returns TRUE if the data queueing operation was successful.
+
+*******************************************************************************/
+
+static BOOLEAN EMAC_Queue_Data
+(
+	DATA_QUEUE_T	*QueueCtx,	// Data queue context
+	DWORD			Data1,		// Data1 value to be queued
+	DWORD			Data2		// Data2 value to be queued
+)
+{
+
+	DATA_REG_T *data_q_entry;
+	
+	// Is there room for the data on the queue?
+	if ( QueueCtx->entry_cnt < SIZE_OF_DATA_QUEUES )
+	{
+		// Put the data on the queue context given to us
+		data_q_entry = &QueueCtx->queue[ QueueCtx->put_idx++ ];
+		data_q_entry->Data2 = Data2;
+		data_q_entry->Data1 = Data1;
+
+		// Process the put index to account for queue wrapping
+		QueueCtx->put_idx %= SIZE_OF_DATA_QUEUES;
+
+		// Indicate an entry was placed on the queue
+		QueueCtx->entry_cnt++;
+
+		// Response successfully put on queue
+		return TRUE;
+
+	}
+	else
+	{
+		// Response was not put on queue because it was full.
+		return FALSE;
+	}
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_Dequeue_Data
+		
+ABSTRACT:
+		Removes data from the queue of the data queue context
+		Returns TRUE if successful.  FALSE if not.
+
+  		This function is intended to be called from within an interrupt handler
+		therefor it does not wrap the checking of the queue status with IRQ protection.
+		
+DETAILS:
+		Returns TRUE if the data dequeueing operation was successful.
+
+*******************************************************************************/
+
+static BOOLEAN EMAC_Dequeue_Data
+(
+	DATA_QUEUE_T	*QueueCtx,	// Data queue context
+	DWORD           *Data1,		// Pointer to variable to be filled with dequeued Data1 value
+	DWORD 			*Data2		// Pointer to variable to be filled with dequeued Data2 value
+)
+{
+	DATA_REG_T *data_q_entry;
+	
+	// Is there data on the queue?
+	if ( QueueCtx->entry_cnt > 0 )
+	{
+		// Get data entries from the queue context given to us
+		data_q_entry = &QueueCtx->queue[ QueueCtx->get_idx++ ];
+		*Data2 = data_q_entry->Data2;
+		*Data1 = data_q_entry->Data1;
+
+		// Process the get index to account for queue wrapping
+		QueueCtx->get_idx %= SIZE_OF_DATA_QUEUES;
+
+		// Indicate an entry was removed from the queue
+		QueueCtx->entry_cnt--;
+
+		// Response successfully dequeued
+		return TRUE;
+
+	}
+	else
+	{
+		// No response to remove from the queue.
+		return FALSE;
+	}
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_Queue_Count
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+static DWORD EMAC_Queue_Count( DATA_QUEUE_T *QueueCtx )
+{
+	return	QueueCtx->entry_cnt;	
+}
+	
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_Queue_Tx_Pkt
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+static void EMAC_Queue_Tx_Pkt
+(
+	struct net_device	*dev,
+	DWORD				tx_entry
+)
+{
+	EMAC_DRV_CTRL	*thisadapter=(EMAC_DRV_CTRL*)dev->priv;
+
+	// Always queue the ethernet tx packet to be sent
+	if( EMAC_Queue_Data( thisadapter->emac_tx_q, (DWORD)dev, tx_entry ) == FALSE )
+	{
+		// Queuing of data failed!!
+		printk( KERN_DEBUG "%s transmit queue full!\n", dev->name );
+	}
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_Tx_Pkt_Transmit
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+static void EMAC_Tx_Pkt_Transmit( struct net_device *pdevice )
+{
+	EMAC_DRV_CTRL	*pthisadapter;
+	DWORD			tx_entry_num;
+	DWORD			buf_ptr;
+	DWORD			buf_len;
+    ULONG			*pL;
+    unsigned int	idx;
+	unsigned long	flags;
+
+	pthisadapter = ( EMAC_DRV_CTRL *)pdevice->priv;
+
+#if EMAC_MUTUALLY_EX_OPR
+	// Check for transmission of an ethernet packet already in progress.
+	// The value contained in EMAC_num_in_operation represents the emac
+	// device that currently is in operation in mutually exclusive operation.
+	
+	if
+	(
+			( emac_mutually_ex_opr == FALSE && pthisadapter->tx_pkt_in_progress == FALSE )
+		||	( emac_mutually_ex_opr == TRUE && EMAC_num_in_operation == NONE )
+	)
+	{
+		// Get the next tx ethernet packet to be sent
+		if( EMAC_Dequeue_Data( pthisadapter->emac_tx_q, (DWORD *)&pdevice, &tx_entry_num ) == FALSE )
+		{
+			// No more ethernet tx data to send on either emac
+			return;
+		}
+		
+		pthisadapter = (EMAC_DRV_CTRL*)pdevice->priv;
+		
+		// Indicate which EMAC is currently in operation 
+		//  AND
+		// that it has a transmit packet in progress.
+		EMAC_num_in_operation = pthisadapter->emac_num;
+		pthisadapter->tx_pkt_in_progress = TRUE;
+		
+		buf_ptr = (DWORD)(pthisadapter->tx_msg_q[ tx_entry_num ]).Data;
+		buf_len = (DWORD)(pthisadapter->tx_msg_q[ tx_entry_num ]).ulLength;
+		
+		// Program the DMA registers to transfer the ethernet packet into the TMAC.
+		*pthisadapter->emac_tx_dma_ptr = (ULONG) buf_ptr;
+		*pthisadapter->emac_tx_dma_cnt = (ULONG) buf_len;		// # of QWORDs to transfer
+
+		if(	emac_mutually_ex_opr == TRUE )
+		{
+			*pthisadapter->emac_tx_dma_ptrx = (ULONG) buf_ptr;
+		}
+
+		// Compute dword (UINT32) offset to the end of the data in the txd buffer.
+		// Since ulLength is in QWORDS, the number of DWORDS is 2 times ulLength.
+		idx = (unsigned int)( buf_len << 1 );
+
+		// Add the END TMAC TRANSMIT DESCRIPTOR pointer and qword count
+		// to the end of the txd message buffer.
+
+		// Get the txd buffer starting address.
+		pL          = (ULONG*)buf_ptr;
+		
+		// Write the pointer to the END transmit frame structure.
+	    pL[idx]		= (ULONG)(pthisadapter->TxD_end);
+
+		// Initialize the QWORD count used by the DMA to xfer
+		// the END transmit frame structure to the TMAC.
+		pL[idx + 1]	= (ULONG) 3;
+
+		// Indicate which tx_msg we are currently sending
+		pthisadapter->tx_msg_q_current = tx_entry_num;
+		
+		// Indicate there is one less message in the tx queue
+		if( pthisadapter->tx_msg_q_size > 0 )
+		{
+			pthisadapter->tx_msg_q_size--;
+		}
+		
+		// Put a time stamp on the message
+		pdevice->trans_start = jiffies;
+
+		// Begin the DMA transfer of the START transmit descriptor into the TMAC.
+		*pthisadapter->emac_na_reg = (pthisadapter->E_NA_settings | E_NA_STRT);
+	#if EMAC_TX_WD_TIMER
+		#if 1
+		// Disable interrupts
+		local_irq_save(flags);
+
+		#endif
+		// Start the timer that will check for missed emac tx dma interrupts
+		mod_timer(&pthisadapter->wd_timer, jiffies + TX_TIMEOUT_DELAY );
+		#if 1
+
+		// Reenable interrupts
+		local_irq_restore(flags);
+		#endif
+	#endif
+	}
+#else
+
+	if( pthisadapter->tx_pkt_in_progress == FALSE )
+	{
+		// Get the next tx ethernet packet to be sent
+		if( EMAC_Dequeue_Data( pthisadapter->emac_tx_q, (DWORD *)&pdevice, &tx_entry_num ) == FALSE )
+		{
+			// No more ethernet tx data to send on either emac
+			return;
+		}
+		
+		pthisadapter = (EMAC_DRV_CTRL*)pdevice->priv;
+		
+		// Indicate which EMAC is currently in operation 
+		//  AND
+		// that it has a transmit packet in progress.
+		EMAC_num_in_operation = pthisadapter->emac_num;
+		pthisadapter->tx_pkt_in_progress = TRUE;
+		
+		buf_ptr = (DWORD)(pthisadapter->tx_msg_q[ tx_entry_num ]).Data;
+		buf_len = (DWORD)(pthisadapter->tx_msg_q[ tx_entry_num ]).ulLength;
+		
+		// Program the DMA registers to transfer the ethernet packet into the TMAC.
+		*pthisadapter->emac_tx_dma_ptr = (ULONG) buf_ptr;
+		*pthisadapter->emac_tx_dma_cnt = (ULONG) buf_len;		// # of QWORDs to transfer
+
+		// Compute dword (UINT32) offset to the end of the data in the txd buffer.
+		// Since ulLength is in QWORDS, the number of DWORDS is 2 times ulLength.
+		idx = (unsigned int)( buf_len << 1 );
+
+		// Add the END TMAC TRANSMIT DESCRIPTOR pointer and qword count
+		// to the end of the txd message buffer.
+
+		// Get the txd buffer starting address.
+		pL          = (ULONG*)buf_ptr;
+		
+		// Write the pointer to the END transmit frame structure.
+	    pL[idx]		= (ULONG)(pthisadapter->TxD_end);
+
+		// Initialize the QWORD count used by the DMA to xfer
+		// the END transmit frame structure to the TMAC.
+		pL[idx + 1]	= (ULONG) 3;
+
+		// Indicate which tx_msg we are currently sending
+		pthisadapter->tx_msg_q_current = tx_entry_num;
+		
+		// Indicate there is one less message in the tx queue
+		if( pthisadapter->tx_msg_q_size > 0 )
+		{
+			pthisadapter->tx_msg_q_size--;
+		}
+
+		// Begin the DMA transfer of the START transmit descriptor into the TMAC.
+		*pthisadapter->emac_na_reg = (pthisadapter->E_NA_settings | E_NA_STRT);
+
+		// Put a time stamp on the message
+		pdevice->trans_start = jiffies;
+	}
+#endif
+}	
+
+void EMAC_Tx_Err_Cnt( EMAC_DRV_CTRL *thisadapter )
+{
+    register unsigned long 	estatus;
+    	
+	estatus = *thisadapter->emac_stat_reg;
+	*thisadapter->emac_stat_reg = estatus;
+
+    if ( estatus & E_S_TOF )	
+    {
+		#if EMAC_ISR_ERR_MSG_PRINT
+		printk( KERN_DEBUG "ETH%d: TX FIFO overflow\n", thisadapter->unit);  
+		#endif
+		thisadapter->stats.tx_fifo_errors++;
+		thisadapter->stats.tx_errors++;
+    }
+    if ( estatus & E_S_TUF )	
+    {
+		#if EMAC_ISR_ERR_MSG_PRINT
+		printk( KERN_DEBUG "ETH%d: TX FIFO underflow\n", thisadapter->unit);  
+		#endif
+		thisadapter->stats.tx_fifo_errors++;
+		thisadapter->stats.tx_errors++;
+    }
+
+	if ( estatus & E_S_RLD )
+	{
+		thisadapter->stats.collisions += (estatus & TSTAT_CC);	
+	}
+    if ( estatus & E_S_ED )	
+    {
+    }
+    if ( estatus & E_S_DF )	
+    {
+    }
+    if ( estatus & E_S_TF )	
+    {
+    }
+    if ( estatus & E_S_TJT )	
+    {
+    }
+}
+
+/******************************************************************************
+|
+|  Function:  EMAC_Tx_Pkt_Done
+|
+|  Description:  
+
+|  Parameters:  
+|
+|  Returns:
+*******************************************************************************/
+
+static BOOLEAN	EMAC_Tx_Pkt_Done(struct net_device *dev )
+{
+    TX_MSG_QUEUE	tx_msg;
+	unsigned long	flags;
+	BOOLEAN			status = FALSE;
+
+	EMAC_DRV_CTRL 	*thisadapter=( EMAC_DRV_CTRL *)dev->priv; 
+
+#if EMAC_MUTUALLY_EX_OPR
+	// Disable interrupts
+	local_irq_save(flags);
+
+	// Did this EMAC really have a tx packet transmission in progress?
+	if( emac_mutually_ex_opr == FALSE || EMAC_num_in_operation == thisadapter->emac_num )
+	{
+		EMAC_num_in_operation = NONE;
+		thisadapter->tx_pkt_in_progress = FALSE;
+				
+		if( netif_queue_stopped(dev))
+		{
+			if ( (TX_RING_SIZE - thisadapter->tx_msg_q_size) > TX_MSG_Q_AWAKE_THRESHOLD )
+			{
+				netif_wake_queue( dev );
+			}
+		}
+
+		tx_msg = thisadapter->tx_msg_q[ thisadapter->tx_msg_q_current ];
+
+		// Reenable interrupts
+		local_irq_restore(flags);
+
+		if( ((EMAC_TXD *)tx_msg.Data)->status & (TSTAT_TDN | TSTAT_CD) )
+		{
+			status = TRUE;
+			thisadapter->stats.tx_packets++;
+			thisadapter->stats.tx_bytes += (DWORD)tx_msg.ulLength;
+		#if 1
+		// DOES THIS NEED TO BE MOVED OUTSIDE OF THE IF-ELSE STATEMENT
+		// TO THE END OF THE FUNCTION ????
+			// Disable interrupts
+			local_irq_save(flags);
+
+			EMAC_Tx_Pkt_Transmit( dev );
+
+			// Reenable interrupts
+			local_irq_restore(flags);
+		#endif
+		}
+		else
+		{
+			EMAC_Tx_Err_Cnt( thisadapter );
+		}
+	}
+	else
+	{
+		// Reenable interrupts
+		local_irq_restore(flags);
+	}
+#else
+	thisadapter->tx_pkt_in_progress = FALSE;
+			
+	tx_msg = thisadapter->tx_msg_q[ thisadapter->tx_msg_q_current ];
+
+	if( netif_queue_stopped(dev))
+	{
+		netif_wake_queue( dev );
+	}
+
+	if( ((EMAC_TXD *)tx_msg.Data)->status & (TSTAT_TDN | TSTAT_CD) )
+	{
+		status = TRUE;
+		thisadapter->stats.tx_packets++;
+		thisadapter->stats.tx_bytes += (DWORD)tx_msg.ulLength;
+		// Disable interrupts
+		local_irq_save(flags);
+
+		EMAC_Tx_Pkt_Transmit( dev );
+
+		// Reenable interrupts
+		local_irq_restore(flags);
+	}
+	else
+	{
+		EMAC_Tx_Err_Cnt( thisadapter );
+	}
+
+#endif
+	return status;
+}
+
+
+#if (TX_FULL_DUPLEX && EMAC_MUTUALLY_EX_OPR)
+
+/******************************************************************************
+|
+|  Function:  EMAC_Mutually_Ex_Op_Chk
+|
+|  Description:
+|			   
+|  Parameters:  
+|
+|  Returns:
+*******************************************************************************/
+
+static void EMAC_Mutually_Ex_Op_Chk( struct net_device *dev )
+{
+	unsigned int		idx;
+	DWORD				tx_entry_num;
+	struct net_device	*pdevice;	
+	unsigned long		flags;
+	
+
+	EMAC_DRV_CTRL	*thisadapter= (EMAC_DRV_CTRL *)dev->priv;
+
+	// Check for emac mutually exclusive transmitter operation
+	if(	thisadapter->emac_num == 1 )
+	{
+		// Disable interrupts
+		local_irq_save(flags);
+
+		// Half Duplex
+		if(		(thisadapter->phyState.duplexMode == PHY_STAT_DUPLEX_HALF)
+#if EMAC_CHK_HW_4_MUTEX_OPR
+			&&	(thisadapter->tx_mutex_part)
+#endif
+			&&	(emac_mutually_ex_opr == FALSE) )
+		{
+			printk( KERN_DEBUG "eth0 changing to half duplex mutually exclusive operation.\n");
+			emac_mutually_ex_opr = TRUE;
+			thisadapter->emac_tx_q = EMAC_tx_pkt_q2;
+			
+			// Clear out the emac 1 transmit packet queue of 
+			// any queued transmit packets and put them	on
+			// the common emac transmit queue.
+			idx = EMAC_Queue_Count( EMAC_tx_pkt_q1 );
+			if( idx != 0 )
+			{
+				do
+				{
+					// Get an entry from the emac 1 tx pkt q
+					EMAC_Dequeue_Data( EMAC_tx_pkt_q1, (DWORD *)&pdevice, &tx_entry_num );
+
+					// Now put it on the common transmit queue
+					if( EMAC_Queue_Data( EMAC_tx_pkt_q2, (DWORD)pdevice, tx_entry_num ) == FALSE )
+					{
+						// Queuing of data failed!!
+						printk("EMAC2 transmit queue full!\n");
+						break;
+					}
+					idx--;		
+				} while( idx != 0 );	
+			}
+		}
+		
+		// Full Duplex
+		if( (thisadapter->phyState.duplexMode == PHY_STAT_DUPLEX_FULL) && emac_mutually_ex_opr == TRUE )
+		{
+			printk( KERN_DEBUG "eth0 changing to full duplex simultaneous operation.\n");
+			// When leaving mutually exclusive transmitter operation
+			// flush the common emac transmitter queue of any
+			// tx packets for emac 1 and put them on the emac 1 queue.
+			emac_mutually_ex_opr = FALSE;
+			thisadapter->emac_tx_q = EMAC_tx_pkt_q1;
+			
+			idx = EMAC_Queue_Count( EMAC_tx_pkt_q2 );
+			if( idx != 0 )
+			{
+				do
+				{
+					// Get an entry from the common tx pkt q
+					EMAC_Dequeue_Data( EMAC_tx_pkt_q2, (DWORD *)&pdevice, &tx_entry_num );
+
+					// If it is not emac 1 then return it to the common tx pkt q 
+					if( pdevice != dev )
+					{
+						if( EMAC_Queue_Data( EMAC_tx_pkt_q2, (DWORD)pdevice, tx_entry_num ) == FALSE )
+						{
+							// Queuing of data failed!!
+							printk("EMAC2 transmit queue full!\n");
+							break;
+						}
+					}
+					else
+					{
+						if( EMAC_Queue_Data( EMAC_tx_pkt_q1, (DWORD)pdevice, tx_entry_num ) == FALSE )
+						{
+							// Queuing of data failed!!
+							printk("EMAC1 transmit queue full!\n");
+							break;
+						}
+					}
+					idx--;		
+				} while( idx != 0 );	
+			}
+		}
+		
+		// Reenable interrupts
+		local_irq_restore(flags);
+	}
+}	
+#endif
+
+
+/******************************************************************************
+|
+|  Function:  EMAC_stop_hw
+|
+|  Description:  restarts the hardware and attempts to retransmit the
+|				last ethernet packet
+|  Parameters:  
+|
+|  Returns:    OK on success, ERROR otherwise.
+*******************************************************************************/
+
+void EMAC_stop_hw( struct net_device *dev)
+{
+
+ 	EMAC_DRV_CTRL	*thisadapter= (EMAC_DRV_CTRL *)dev->priv;
+
+    cnxt_mask_irq( dev->irq );
+
+#if TX_DMA_INT
+    cnxt_mask_irq( thisadapter->tx_dma_int );	
+#endif
+#if RX_DMA_INT
+    cnxt_mask_irq( thisadapter->rx_dma_int );	
+#endif
+	
+	netif_stop_queue(dev);
+
+	/* Clear the status registers  */
+	*INT_Stat = thisadapter->int_stat_clr_dev_irq;
+
+#if TX_DMA_INT
+	/* Clear the INT1_Stat register of pending TX interrupts */
+	*INT_Stat = thisadapter->int_stat_clr_tx;
+#endif
+#if RX_DMA_INT
+	/* Clear the INT1_Stat register of pending RX interrupts */
+	*INT_Stat = thisadapter->int_stat_clr_rx;
+#endif
+
+	// Stop the transmitter and receiver
+
+	// NOTE: The transmitter does not stop immediately when the stop
+	// bit is set.  Depending upon where the dma engine may be in
+	// the tranferring of a TX frame to the emac, it may take up to a maximum
+	// time interval that is equal to the value of a 1514 MTU in bits times the
+	// period of the networkspeed clock period.  Since there is no hardware
+	// indication of when the dma has stopped, all you can do is delay
+	// for this maximum time interval and hope for the best. 
+
+    thisadapter->E_NA_settings = 0;
+	*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+}
+
+
+/******************************************************************************
+|
+|  Function:  EMAC_restart_hw
+|
+|  Description:  restarts the hardware and attempts to retransmit the
+|				last ethernet packet
+|  Parameters:  
+|
+|  Returns:    OK on success, ERROR otherwise.
+*******************************************************************************/
+
+static int EMAC_restart_hw( struct net_device *dev, BOOLEAN flush_txq, BOOLEAN flush_rxq )
+{
+	EMAC_RXD_HW_QTYPE	*rxd_hw;
+	BYTE				*rxd_buf;
+	unsigned int		idx;
+    unsigned long 		estatus;	/* contains the status of the ethernet hardware */
+    unsigned long 		lstatus;	/* contains the status of the last packet register */
+	DWORD				tx_entry_num;
+	struct net_device	*pdevice;	
+	
+	EMAC_DRV_CTRL	*thisadapter= (EMAC_DRV_CTRL *)dev->priv;
+
+    cnxt_mask_irq( dev->irq );
+
+#if TX_DMA_INT
+    cnxt_mask_irq( thisadapter->tx_dma_int );	
+#endif
+#if RX_DMA_INT
+    cnxt_mask_irq( thisadapter->rx_dma_int );	
+#endif
+	
+	netif_stop_queue(dev);
+
+	/* Clear the status registers  */
+	*INT_Stat = thisadapter->int_stat_clr_dev_irq;
+
+#if TX_DMA_INT
+	/* Clear the INT1_Stat register of pending TX interrupts */
+	*INT_Stat = thisadapter->int_stat_clr_tx;
+#endif
+#if RX_DMA_INT
+	/* Clear the INT1_Stat register of pending RX interrupts */
+	*INT_Stat = thisadapter->int_stat_clr_rx;
+#endif
+
+	// Clear the EMAC exception condition registers
+	estatus = *thisadapter->emac_stat_reg;
+	*thisadapter->emac_stat_reg = estatus;
+
+    lstatus = *thisadapter->emac_lp_reg;
+    *thisadapter->emac_lp_reg = lstatus;
+
+	// Stop the transmitter and receiver
+
+	// NOTE: The transmitter does not stop immediately when the stop
+	// bit is set.  Depending upon where the dma engine may be in
+	// the tranferring of a TX frame to the emac, it may take up to a maximum
+	// time interval that is equal to the value of a 1514 MTU in bits times the
+	// period of the networkspeed clock period.  Since there is no hardware
+	// indication of when the dma has stopped, all you can do is delay
+	// for this maximum time interval and hope for the best. 
+
+    thisadapter->E_NA_settings = 0;
+//	*thisadapter->emac_na_reg = (thisadapter->E_NA_settings | E_NA_STOP);
+	*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+	if( thisadapter->phyState.networkSpeed == PHY_STAT_SPEED_100 )
+	{
+		TaskDelayMsec(10);
+	}
+	else
+	{
+		TaskDelayMsec(10);
+	}
+	*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+    
+    ResetChip( thisadapter ); 
+    
+	rxd_hw = thisadapter->rxd_hw;
+
+	if( flush_rxq == TRUE )
+	{
+		// Reset the entire receive packet mess
+		rxd_buf = thisadapter->rxd_buf;
+	    QWORD_ALIGN_PTR(rxd_buf);
+
+		for( idx = 0; idx < RXD_NUM; idx++ ) 
+		{
+			rxd_hw->q[idx].mData = rxd_buf + (ETH_PKT_BUF_SZ * idx);
+			rxd_hw->q[idx].reserved = 0;
+			rxd_hw->q[idx].status = 0;
+			rxd_hw->q[idx].mib = 0;
+		}
+		rxd_hw->qndx = 0;	
+
+	}
+
+	*thisadapter->emac_rx_dma_ptr2 = (unsigned long)(&rxd_hw->q[0]); /* address of descriptor list */
+	*thisadapter->emac_rx_dma_cnt1 = (unsigned long)((CL_SIZ/8)-4);/* size of cluster in qwords */
+	*thisadapter->emac_rx_dma_cnt2 = (unsigned long)(2 * RXD_NUM);   /* number of descriptors * 2 */
+  	
+	if( flush_txq == TRUE )
+	{
+		// Clear out the emac transmit packet queue of 
+		// any queued transmit packets for this emac.
+		idx = EMAC_Queue_Count( thisadapter->emac_tx_q );
+		if( idx != 0 )
+		{
+			do
+			{
+				// Get an entry from the tx pkt q
+				EMAC_Dequeue_Data( thisadapter->emac_tx_q, (DWORD *)&pdevice, &tx_entry_num );
+
+				// If it is not this device then return it to the tx pkt q 
+				if( pdevice != dev )
+				{
+					if( EMAC_Queue_Data( thisadapter->emac_tx_q, (DWORD)pdevice, tx_entry_num ) == FALSE )
+					{
+						// Queuing of data failed!!
+						printk("EMAC transmit queue full!\n");
+						break;
+					}
+				}
+				idx--;		
+			} while( idx != 0 );	
+		}
+		
+	    //	Initialize the tx msg queue.
+	    thisadapter->tx_msg_q_next = 0;
+	    thisadapter->tx_msg_q_current = 0;
+	    thisadapter->tx_msg_q_size = 0;
+	}
+
+	*thisadapter->emac_tx_dma_ptr = 0;
+	*thisadapter->emac_tx_dma_cnt = 0;
+	thisadapter->tx_pkt_in_progress = FALSE;
+
+#if EMAC_MUTUALLY_EX_OPR
+	// Release the EMAC operation lock if we had it
+	// and allow the other EMAC to run if it needs to.
+	if(	emac_mutually_ex_opr == FALSE || EMAC_num_in_operation == thisadapter->emac_num  )
+	{
+		EMAC_num_in_operation = NONE;		
+	}		
+#endif
+	if( thisadapter->emac_state == OPEN )
+	{
+		// Get the current emac line state
+		thisadapter->E_NA_settings = 0;
+		EMAC_Linkcheck( thisadapter, TRUE );
+
+		// Set up the emac hardware filtering for perfect address filtering 
+		thisadapter->E_NA_settings |= E_NA_FILTER_MC1PERFECT;	
+		*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+		// Configure the emac hardware filtering 
+		emac_SetupFrame ( dev );
+
+#if 0
+	#if HOMEPLUGPHY
+	    if( PhyActiveHOMEPLUG( thisadapter->pPhy) )
+	    {
+		    TeslaControl_Str TeslaControl ;
+
+	        Emac_TeslaConfigRead( &TeslaControl ) ;
+	        Emac_TeslaSetup( (PVOID)thisadapter, &TeslaControl) ;
+	    }
+	#endif
+#endif	
+		*thisadapter->emac_ie_reg = thisadapter->E_IE_settings;
+	    
+		// Start the receiver operating now
+	    thisadapter->E_NA_settings |= (E_NA_SR|E_NA_SB);
+		*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+	    cnxt_unmask_irq( dev->irq );
+	#if TX_DMA_INT
+	    cnxt_unmask_irq( thisadapter->tx_dma_int );	
+	#endif
+	#if RX_DMA_INT
+	    cnxt_unmask_irq( thisadapter->rx_dma_int );	
+	#endif
+
+	}
+
+	if( netif_queue_stopped(dev))
+	{
+		netif_wake_queue( dev );
+	}
+
+    return 0;
+}
+
+
+static int EMAC_restart_rx( struct net_device *dev, BOOLEAN flush_rxq )
+{
+	EMAC_RXD_HW_QTYPE	*rxd_hw;
+	BYTE				*rxd_buf;
+	unsigned int		idx;
+	
+	EMAC_DRV_CTRL	*thisadapter= (EMAC_DRV_CTRL *)dev->priv;
+
+    cnxt_mask_irq( dev->irq );
+
+#if RX_DMA_INT
+    cnxt_mask_irq( thisadapter->rx_dma_int );	
+#endif
+	
+	netif_stop_queue(dev);
+
+	/* Clear the status registers  */
+	*INT_Stat = thisadapter->int_stat_clr_dev_irq;
+
+#if RX_DMA_INT
+	/* Clear the INT1_Stat register of pending RX interrupts */
+	*INT_Stat = thisadapter->int_stat_clr_rx;
+#endif
+
+	// Stop the receiver
+
+    thisadapter->E_NA_settings &= ~E_NA_SR;
+	*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+	if( thisadapter->phyState.networkSpeed == PHY_STAT_SPEED_100 )
+	{
+		TaskDelayMsec(10);
+	}
+	else
+	{
+		TaskDelayMsec(10);
+	}
+    
+    EMAC_REG_WRITE( E_NA, E_NA_RRX, thisadapter->emac_hdw_num );
+	udelay( 100 );
+	udelay( 100 );
+	udelay( 50 );
+    EMAC_REG_WRITE( E_NA, 0, thisadapter->emac_hdw_num );
+	udelay( 100 );
+	udelay( 100 );
+	udelay( 50 );
+    EMAC_REG_WRITE( E_NA, 0, thisadapter->emac_hdw_num );
+	udelay( 100 );
+	udelay( 100 );
+	udelay( 50 );
+    
+	rxd_hw = thisadapter->rxd_hw;
+
+	if( flush_rxq == TRUE )
+	{
+		// Reset the entire receive packet mess
+		rxd_buf = thisadapter->rxd_buf;
+	    QWORD_ALIGN_PTR(rxd_buf);
+
+		for( idx = 0; idx < RXD_NUM; idx++ ) 
+		{
+			rxd_hw->q[idx].mData = rxd_buf + (ETH_PKT_BUF_SZ * idx);
+			rxd_hw->q[idx].reserved = 0;
+			rxd_hw->q[idx].status = 0;
+			rxd_hw->q[idx].mib = 0;
+		}
+		rxd_hw->qndx = 0;	
+	}
+
+	*thisadapter->emac_rx_dma_ptr2 = (unsigned long)(&rxd_hw->q[0]); /* address of descriptor list */
+	*thisadapter->emac_rx_dma_cnt1 = (unsigned long)((CL_SIZ/8)-4);/* size of cluster in qwords */
+	*thisadapter->emac_rx_dma_cnt2 = (unsigned long)(2 * RXD_NUM);   /* number of descriptors * 2 */
+  	
+	// Start the receiver operating now
+    thisadapter->E_NA_settings |= E_NA_SR;
+	*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+    cnxt_unmask_irq( dev->irq );
+#if RX_DMA_INT
+    cnxt_unmask_irq( thisadapter->rx_dma_int );	
+#endif
+
+	if( netif_queue_stopped(dev))
+	{
+		netif_wake_queue( dev );
+	}
+
+    return 0;
+}
+
+
+/******************************************************************************
+|
+|  Function:  EMAC_Linux_tx_timeout
+|
+|  Description:  
+
+|  Parameters:  
+|
+|  Returns:
+*******************************************************************************/
+
+static void EMAC_Linux_tx_timeout(struct net_device *dev)
+{
+
+	EMAC_DRV_CTRL *thisadapter = ( EMAC_DRV_CTRL *)dev->priv; 
+
+	thisadapter->stats.tx_errors++;
+	thisadapter->stats.tx_aborted_errors++;
+	if( netif_queue_stopped(dev))
+	{
+		netif_wake_queue( dev );
+	}
+	printk( KERN_DEBUG "%s tx timeout\n", dev->name);
+
+	thisadapter->hw_reset_required = TRUE;
+}
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_tx_timeout
+		
+ABSTRACT:
+		
+DETAILS:
+
+RETURNS:
+		
+NOTES:
+*******************************************************************************/
+
+static void EMAC_tx_timeout(struct net_device *dev)
+{
+	unsigned long		flags;
+	EMAC_DRV_CTRL *thisadapter = ( EMAC_DRV_CTRL *)dev->priv; 
+
+	// Check to see if this was a case of us failing to detect
+	// the completion of a valid transmit frame or that there
+	// was an emac lockup or something else.
+#if 0
+	if( EMAC_Tx_Pkt_Done( dev ) == FALSE )
+#endif
+	{
+		printk( KERN_DEBUG "%s tx_timeout\n", dev->name );		
+#if 1
+		// Disable interrupts
+		local_irq_save(flags);
+
+		netif_stop_queue( dev );
+#endif
+		EMAC_Tx_Err_Cnt( thisadapter );
+		thisadapter->stats.tx_errors++;
+		thisadapter->stats.tx_aborted_errors++;
+		thisadapter->hw_reset_required = TRUE;
+#if 1
+
+		// Reenable interrupts
+		local_irq_restore(flags);
+#endif
+	#if HW_RESET_EVENT
+		SET_EVENT( thisadapter->hw_reset_event );
+	#endif
+	}
+}
+
+	 
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_Tx_Pkt_Process
+		
+ABSTRACT:
+		
+DETAILS:
+
+RETURNS:
+		
+NOTES:
+To transmit an ethernet packet, three items are necessary.  Two TMAC
+TRANSMIT DESCRIPTORS and a transmit message buffer.   In this particular
+implementation the START transmit descriptor is not prepended to the
+buffer to be transmitted so the first DWORD of the buffer must be copied
+into this transmit descriptor. 
+
+See section 7.7 of the CX82100 HNP data sheet for more details on how the 
+ethernet TMAC function operates.	In particular see figures 7.5 EMAC Transmit
+Frame Structure and 7.6 TMAC DMA Operation for Channel {x} = 1 or 3.
+
+Also see section 4.6.3 Linked List Mode for an explanation of the Embedded Tail
+Linked List mode of DMA operation.
+
+The START ethernet TMAC TRANSMIT DESCRIPTOR consists of the following
+DWORD (32 bit) sized variables:
+
+	Relative 		Variable
+	Byte Address	Name			Notes
+	--------------	------------	----------------------------------------------
+	0x00			STATUS			Status of transmitted message. Updated by TMAC
+	0x04			STATUS_ZERO		Always all zeros
+	0x08			DESCRIPTOR		Contains bit fields that indicate readiness of
+									the frame, frame size and other items.  Set by
+									ARM CPU.
+	0x0C			DATA			First DWORD of data from the transmit message buffer.
+	 	.
+		.
+		.
+	0x0C + n		DATA			Last DWORD of data in transmit message buffer.
+	0x0C + n + 4	PAD				Optional padding to QWORD align POINTER and COUNT
+	0x0C + n + 4(8)	POINTER			Pointer to the END transmit descriptor structure.
+									The END transmit descriptor is used to terminate
+									the transmission of this transmit message buffer.
+	0x0C + n + 8(12)	COUNT		Size in QWORDS of the END transmit descriptor structure.
+
+The END ethernet TMAC TRANSMIT DESCRIPTOR consists of the following
+DWORD (32 bit) sized variables:
+
+	Relative 		Variable
+	Byte Address	Name			Notes
+	--------------	------------	----------------------------------------------
+	0x00			STATUS			Set to zero.
+	0x04			STATUS_ZERO		Set to zero.
+	0x08			DESCRIPTOR		Set to zero.
+	0x0C			DATA			Set to zero.
+	0x10			POINTER			Set to zero.
+	0x14			COUNT			Set to zero.
+
+*******************************************************************************/
+
+static int	EMAC_Tx_Pkt_Process
+(
+	EMAC_DRV_CTRL	*thisadapter,
+	TX_PKT_INFO		*tx_pkt_info,
+	DWORD			*entry
+)
+{
+    TX_MSG_QUEUE	tx_msg;
+	BYTE            *txd_buf;
+
+	// Determine if the transmitter has any buffers left
+	if( thisadapter->tx_msg_q_size < TX_RING_SIZE )
+	{
+		// Get a buffer from the transmitter message queue to copy the data into.
+		*entry = thisadapter->tx_msg_q_next++ % TX_RING_SIZE;
+		thisadapter->tx_msg_q_next %= TX_RING_SIZE;
+		txd_buf = thisadapter->txd_buf[*entry];
+			
+		// Copy the transmit data into our own buffer so that we can
+		// prepend the START transmit descriptor to the data.
+		TX_COPY_MEMORY
+		(
+		 	txd_buf + EMAC_TXD_SIZE,
+	        tx_pkt_info->tx_pkt_data,
+	        tx_pkt_info->tx_pkt_len
+		);
+
+		tx_msg.Data = txd_buf;
+
+		tx_msg.ulControl = TX_FRM_LEN_SET(tx_pkt_info->tx_pkt_len) | (TCTRL_RDY);
+
+		// Determine the length of the tx message in QWORDS
+		// NOTE: This length must also include the START TMAC
+		// TRANSMIT DESCRIPTOR fields.
+		tx_msg.ulLength =  ((tx_pkt_info->tx_pkt_len + EMAC_TXD_SIZE + QWORD_ROUND_UP_FACTOR ) / SIZEOF_QWORD );
+
+		// Initialize START TMAC TRANSMIT DESCRIPTOR
+		((EMAC_TXD *)tx_msg.Data)->status = 0;
+		((EMAC_TXD *)tx_msg.Data)->status_zero = 0;
+		((EMAC_TXD *)tx_msg.Data)->control = tx_msg.ulControl;
+
+		/* insert tx_msg into queue  */
+		thisadapter->tx_msg_q[ *entry ] = tx_msg; /* this is a copy*/
+		thisadapter->tx_msg_q_size++;
+	}
+
+	// Return number of empty buffers left in our ring
+	return (TX_RING_SIZE - thisadapter->tx_msg_q_size);
+}	
+
+
+/******************************************************************************
+|
+|  Function:    emac_SetupFrame
+|
+|  Description: This routine sets up the EMAC Setup Frame based on the 
+|               filtering mode configuration.  This is to configure the 
+|               hardware assisted address filtering.  
+|
+|               Currently it only supports All Multicast plus One Perfect mode.
+|               No setting is needed for promiscuous mode.
+|
+|  Returns:     OK/ERROR
+*******************************************************************************/
+
+BOOLEAN emac_SetupFrame ( struct net_device *dev )
+{
+    UINT8       		index;
+    char        		*macaddr;
+    EMAC_SETUP_FRAME  	*cam;
+    ULONG				*pL;
+    unsigned int		idx;
+    TX_MSG_QUEUE		tx_msg;
+
+	EMAC_DRV_CTRL	*thisadapter = (EMAC_DRV_CTRL*)dev->priv;
+	
+#if SETUP_FRAME_VERIFY
+	if(	sf_verify == FALSE )
+	{
+		return FALSE;
+	}
+#endif
+
+	// Check to see if we are configured for something 
+	// other than perfect MAC address filtering.
+    if 
+	(
+			( thisadapter->E_NA_settings & E_NA_FILTER_MODE ) != E_NA_FILTER_MC1PERFECT
+		||	( dev->flags & IFF_PROMISC )
+	)
+    {
+        return FALSE;
+    }
+        
+    /*
+		Prepare the setup frame with the unicast addresses.  CX821xx specifies that each entry 
+		occupies 3 double words (12 bytes) and the address data go into the low word of each 
+		double words.  CX821xx also requires the empty entries in the setup frame be filled with 
+		the last valid entry.
+    */
+		
+	memset( &thisadapter->setup_frame_buf[0], 0, sizeof ( thisadapter->setup_frame_buf ));
+
+    cam = ( EMAC_SETUP_FRAME * )((BYTE *) &thisadapter->setup_frame_buf[0] + EMAC_TXD_SIZE);
+    
+    macaddr = ( char * ) &thisadapter->PortNetAddress[0];
+
+    for (index = 0; index < EMAC_SETUP_PERFECT_ENTRIES; index++)
+    {
+        *(UINT16 *) & cam->Perfect.PhysicalAddress[index][0] = (UINT16)((macaddr[0] & 0xff) + ((macaddr[1] & 0xff) <<8));
+        *(UINT16 *) & cam->Perfect.PhysicalAddress[index][1] = (UINT16)((macaddr[2] & 0xff) + ((macaddr[3] & 0xff) <<8));
+        *(UINT16 *) & cam->Perfect.PhysicalAddress[index][2] = (UINT16)((macaddr[4] & 0xff) + ((macaddr[5] & 0xff) <<8));
+    }
+    
+	tx_msg.Data = &thisadapter->setup_frame_buf[0];
+	tx_msg.ulControl = TX_FRM_LEN_SET(ADDRESS_FILTER_SIZE) | (TCTRL_RDY | TCTRL_SET );
+
+	// Determine the length of the tx message in QWORDS
+	// NOTE: This length must also include the START TMAC
+	// TRANSMIT DESCRIPTOR fields.
+	tx_msg.ulLength =  ((ADDRESS_FILTER_SIZE + EMAC_TXD_SIZE + QWORD_ROUND_UP_FACTOR ) / SIZEOF_QWORD );
+
+	// Initialize START TMAC TRANSMIT DESCRIPTOR
+	((EMAC_TXD *)tx_msg.Data)->status = 0;
+	((EMAC_TXD *)tx_msg.Data)->status_zero = 0;
+	((EMAC_TXD *)tx_msg.Data)->control = tx_msg.ulControl;
+
+	// Compute dword (UINT32) offset to the end of the data in the txd buffer.
+	// Since ulLength is in QWORDS, the number of DWORDS is 2 times ulLength.
+	idx = (unsigned int)(tx_msg.ulLength << 1 );
+
+	// Add the END TMAC TRANSMIT DESCRIPTOR pointer and qword count
+	// to the end of the setup frame buffer.
+
+	// Get the setup frame buffer starting address.
+	pL          = (ULONG*)tx_msg.Data;
+	
+	// Write the pointer to the END transmit frame structure.
+    pL[idx]		= (ULONG)(thisadapter->TxD_end);
+
+	// Initialize the QWORD count used by the DMA to xfer
+	// the END transmit frame structure to the TMAC.
+	pL[idx + 1]	= (ULONG)TD_DMA_SIZ;
+
+	// Initialize END TMAC TRANSMIT DESCRIPTOR
+	thisadapter->TxD_end->status		= 0;
+	thisadapter->TxD_end->status_zero	= 0;
+	thisadapter->TxD_end->control		= 0;
+	thisadapter->TxD_end->data			= 0;             
+	thisadapter->TxD_end->joint.pNext	= (BYTE *)&thisadapter->TxD_end;
+	thisadapter->TxD_end->joint.cNext	= 0;          
+
+	// Program the DMA registers to transfer the ethernet packet into the TMAC.
+	*thisadapter->emac_tx_dma_ptr = (ULONG) tx_msg.Data;
+	*thisadapter->emac_tx_dma_cnt = (ULONG) tx_msg.ulLength;
+
+	// Begin the DMA transfer of the START transmit descriptor into the TMAC.
+	*thisadapter->emac_na_reg |= E_NA_STRT;
+
+	return TRUE;
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		emac_send_packet
+		
+ABSTRACT:
+		
+DETAILS:
+
+RETURNS:
+
+*******************************************************************************/
+
+static int	emac_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+	TX_PKT_INFO		tx_pkt_info;
+	unsigned long	flags;
+	DWORD			entry;
+	int				num_buf;
+
+	EMAC_DRV_CTRL	*thisadapter=(EMAC_DRV_CTRL*)dev->priv;
+
+#if 0
+	if(	thisadapter->phyState.linkStatus != PHY_STAT_LINK_UP )
+	{
+		dev_kfree_skb_any (skb);
+		return 0;
+	}
+#endif
+		
+	// Generalize the data about the transmit packet
+	tx_pkt_info.tx_pkt_data = skb->data;
+	tx_pkt_info.tx_pkt_len = skb->len;
+
+	// Disable interrupts
+	spin_lock_irqsave(&thisadapter->lock, flags);
+	 
+	// Preprocess the transmit packet data for the emac driver
+	num_buf = EMAC_Tx_Pkt_Process( thisadapter, &tx_pkt_info, &entry );
+
+	// If the number of remaining tx buffers is less than
+	// some amount then tell the OS to stop giving us more.
+	if( num_buf < TX_MSG_Q_THRESHOLD )
+	{
+		netif_stop_queue( dev );
+	}
+
+	EMAC_Queue_Tx_Pkt( dev, entry );
+	
+	// Transmit a packet now
+	EMAC_Tx_Pkt_Transmit( dev );
+
+	// Reenable interrupts
+	spin_unlock_irqrestore(&thisadapter->lock, flags);
+
+	// Return the skb back to the pool now that
+	// we have copied the data from it.
+	dev_kfree_skb_any (skb);
+	return 0;
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_task
+		
+ABSTRACT:
+		
+DETAILS:
+
+RETURNS:
+		
+NOTES:
+*******************************************************************************/
+
+BOOLEAN print_debug_msg = FALSE;
+DWORD	disabled_irq_cnt = 0;
+DWORD	enabled_irq_cnt = 0;
+
+static void EMAC_task(struct net_device *dev)
+{
+	EMAC_DRV_CTRL *thisadapter = ( EMAC_DRV_CTRL *)dev->priv; 
+
+	// Check to see if the emac has been put into
+	// promiscuious mode by the operating system.
+	
+	// NOTE: The EMAC_Linkcheck function will update
+	// the emac NA register with the promiscuity settings.
+	if( dev->flags & IFF_PROMISC )
+	{
+		thisadapter->E_NA_settings &= ~E_NA_FILTER_MODE;
+		thisadapter->E_NA_settings |= E_NA_FILTER_PROMIS;	
+	}
+	else
+	{
+		thisadapter->E_NA_settings &= ~E_NA_FILTER_MODE;
+		thisadapter->E_NA_settings |= E_NA_FILTER_MC1PERFECT;	
+	}
+	
+	// Get the current emac line state
+	EMAC_Linkcheck( thisadapter, FALSE );
+
+#if 0
+	// If the physical link is not up then blow off any transmit packets
+	if(	thisadapter->phyState.linkStatus == PHY_STAT_LINK_UP )
+	{
+		netif_carrier_on( dev );
+	}
+	else
+	{
+		netif_carrier_off( dev );
+	}
+#endif
+
+	if( thisadapter->emac_state == OPEN )
+	{
+#if 1
+		// If the physical link is not up then blow off any transmit packets
+		if(	thisadapter->phyState.linkStatus == PHY_STAT_LINK_UP )
+		{
+			netif_carrier_on( dev );
+		}
+		else
+		{
+			netif_carrier_off( dev );
+		}
+
+#endif
+		#if EMAC_DISABLE_CHK
+		EMAC_Disabled_Check( dev );
+		#endif
+
+	#if (TX_FULL_DUPLEX && EMAC_MUTUALLY_EX_OPR)
+		// Check for and configure emacs for mutally
+		// exclusive transmitter operation.
+		EMAC_Mutually_Ex_Op_Chk( dev );
+	#endif
+		
+		if( netif_queue_stopped(dev) )
+		{
+			// Inform the OS that we can accept packets now
+			netif_wake_queue(dev);
+		}
+	}
+}
+
+typedef struct
+{
+	EVENT_HNDL	taskevent;
+	
+} EMAC_EVENT_T;
+
+EMAC_EVENT_T emac1_event;
+EMAC_EVENT_T emac2_event;
+
+void EMAC1_Task( struct net_device *dev )
+{
+	EMAC_DRV_CTRL *thisadapter = ( EMAC_DRV_CTRL *)dev->priv;
+	EMAC_EVENT_T *pemac_event = &emac1_event;
+
+	// Initialize task event
+	INIT_EVENT( &pemac_event->taskevent );
+	thisadapter->hw_reset_event = &pemac_event->taskevent;
+
+	while(1)
+	{
+	#if HW_RESET_EVENT
+		RESET_EVENT( thisadapter->hw_reset_event );
+		WAIT_EVENT ( thisadapter->hw_reset_event, 1070 );
+	#else
+		TaskDelayMsec(1070);
+	#endif
+		EMAC_task( dev );
+	}
+}
+
+void EMAC2_Task( struct net_device *dev )
+{
+
+	EMAC_DRV_CTRL *thisadapter = ( EMAC_DRV_CTRL *)dev->priv;
+	EMAC_EVENT_T *pemac_event = &emac2_event;
+
+	// Initialize task event
+	INIT_EVENT( &pemac_event->taskevent );
+	thisadapter->hw_reset_event = &pemac_event->taskevent;
+
+	while(1)
+	{
+	#if HW_RESET_EVENT
+		RESET_EVENT( thisadapter->hw_reset_event );
+		WAIT_EVENT ( thisadapter->hw_reset_event, 1070 );
+	#else
+		TaskDelayMsec(1070);
+	#endif
+		EMAC_task( dev );
+	}
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		sp_emac_close
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+static int emac_close(struct net_device *dev)
+{
+
+	unsigned long	flags;
+	EMAC_DRV_CTRL *thisadapter=(EMAC_DRV_CTRL*)dev->priv;
+
+#if 1
+	// Disable interrupts
+	local_irq_save(flags);
+
+#endif
+	// Effectively disable the tx watchdog timer by setting
+	// it to a very long timeout.
+	del_timer(&thisadapter->periodic_task);
+	
+	// Tell the OS we are closed
+	netif_stop_queue(dev);
+
+	// Indicate the emac is closed
+	thisadapter->emac_state = CLOSED;
+	
+#if 0
+	// Disable interrupts
+	local_irq_save(flags);
+
+#endif
+	// Restart the hardware to bring it into a known state
+	EMAC_restart_hw( dev, TRUE, TRUE );
+
+#if 0
+	// Reenable interrupts
+	local_irq_restore(flags);
+
+#endif
+	// Zero out the statistics to start out clean when we open.
+	memset( &thisadapter->stats, 0, sizeof ( struct net_device_stats ));
+
+#if 1
+	// Reenable interrupts
+	local_irq_restore(flags);
+
+#endif
+	return 0;
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		sp_emac_get_stats
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+static struct net_device_stats *emac_get_stats(struct net_device *dev)
+{
+	EMAC_DRV_CTRL *thisadapter=(EMAC_DRV_CTRL*)dev->priv;
+
+	return &(thisadapter->stats);
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		set_multicast_list
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+static void set_multicast_list(struct net_device *dev)
+{}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_Rx_Process
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+#if 0
+void EMAC_Rx_Process( unsigned long data )
+{
+	// Exists so CodeWright will so this function in its list
+}	
+#endif
+#if RX_TASKLET
+static void EMAC_Rx_Process( unsigned long data )
+#else
+static void EMAC_Rx_Process( struct net_device	*dev )
+#endif
+{
+
+	register EMAC_DRV_CTRL		*thisadapter;
+	register int				i;
+	register int				idx;
+	int							lookback_idx;
+	unsigned long	    		status;
+	unsigned long				pktlen;
+	DWORD						cdt_ptr;
+	DWORD						dma_ptr2;
+	struct sk_buff				*skb;
+	volatile EMAC_RXD_HW_QTYPE	*rxd_hw;
+	BOOLEAN						rx_drop_pkts;	
+	BOOLEAN						rx_disabled;
+#if RX_TASKLET
+	struct net_device	*dev;
+	dev	= (struct net_device *)*((unsigned long *)data);
+#endif
+	thisadapter = ( EMAC_DRV_CTRL *)dev->priv;
+
+	rx_drop_pkts = FALSE;
+	rx_disabled = FALSE;
+		
+	rxd_hw = thisadapter->rxd_hw;
+	
+	i = 0;
+	while( i < (RX_RING_SIZE / 1))
+	{
+		// The 'i' variable determines the maximum entries we will check.
+		// The 'idx' variable determines where in the receive buffer CDT
+		// 	that we will begin.  When the loop finishes 'idx' points to 
+		// 	the last receive buffer that we looked at.
+    	idx = rxd_hw->qndx;
+
+		// Check to see if the DMA engine is catching up to us
+		// and if so disable the receiver so that we do not overrun
+		lookback_idx = rx_lookback_idx[ idx ];
+		if(( rxd_hw->q[lookback_idx].status != 0 ) && (	rx_disabled == FALSE ))
+		{
+		    thisadapter->E_NA_settings &= ~E_NA_SR;
+			*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+			rx_disabled = TRUE;
+		#if 0
+			printk(KERN_DEBUG "%s rx lookback threshold limit\n", dev->name );
+		#else
+			thisadapter->stats.rx_over_errors++;
+		#endif
+		}
+
+		i++;
+
+		// Check to see if we have reached the CDT entry that
+		// the dma hardware is currently working on.
+		cdt_ptr = ((DWORD)(&rxd_hw->q[idx].mData)) & LOW_QWORD_MASK;
+		dma_ptr2 = ((DWORD)(*thisadapter->emac_rx_dma_ptr2)) & LOW_QWORD_MASK;
+		
+		if(	cdt_ptr != dma_ptr2 )
+		{
+			rxd_hw->qndx = ( rxd_hw->qndx + 1 ) % RX_RING_SIZE;
+	
+			// Do we process or drop the packet?
+			if( rx_drop_pkts == FALSE )
+			{
+				status = rxd_hw->q[idx].status;
+		
+				// Check the magic status bit
+				// Always 1 for good frame?
+				if( ( status & ( RX_A1 )) != 0 ) 
+				{
+					// Get the packet length
+					pktlen = RX_FRM_LEN_GET( status );
+
+					// Make sure the frame is neither too short or too long
+					// AND that it did not have a CRC error
+					if
+					(
+							( pktlen >= MIN_ETHERNET_SIZE )
+						&&	( pktlen <= MAX_ETHERNET_SIZE )
+						&&	!( status & (RSTAT_TS | RSTAT_TL | RSTAT_CE ))
+					)
+					{
+						// Get a kernel buffer to put the data in
+						skb = dev_alloc_skb( pktlen + DWORD_ALIGN_IP_HDR );
+						if (skb != NULL)
+						{
+							skb->dev = dev;
+							skb_reserve(skb, DWORD_ALIGN_IP_HDR );	/* Align IP on 16 byte boundaries */
+
+							// Adjust the packet len pointer to remove the ethernet CRC from it
+							pktlen -= ETHERNET_CRC_SIZE;
+
+					        // NOTE: In the following memcpy the first QWORD is used by
+							// the RMAC hardware - it means nothing to us except that we
+							// must account for it in our data pointer calculations and
+							// cluster allocations.
+
+							RX_COPY_MEMORY
+							(
+							 	skb_put(skb,pktlen),
+						        (void*)rxd_hw->q[idx].mData + SIZEOF_QWORD,
+						        pktlen
+							);
+
+					  		dev->last_rx = jiffies;
+
+						#if RX_SKB_DEBUG
+							skb_debug(skb);
+						#endif
+							// Indicate to Linux that it is an ethernet packet
+							skb->protocol = eth_type_trans(skb,dev);
+
+							thisadapter->stats.rx_packets++;
+							thisadapter->stats.rx_bytes+=pktlen;
+
+							// Deliver the received packet to the protocol stack
+							switch ( netif_rx(skb) )
+							{
+								case NET_RX_SUCCESS:
+								case NET_RX_CN_LOW:
+								case NET_RX_CN_MOD:
+									break;
+									
+								case NET_RX_CN_HIGH:
+									printk( KERN_DEBUG "%s NET_RX_CN_HIGH\n", dev->name);
+									break;
+									
+								case NET_RX_DROP:
+									printk( KERN_DEBUG "%s NET_RX_DROP\n", dev->name);
+									rx_drop_pkts = TRUE;
+									break;
+									
+								default:
+									printk( KERN_DEBUG "unknown feedback return code\n");
+									break;
+							}
+						}
+						else
+						{
+							// No skbuffer to put the data into!
+							emac_rx_proc_no_skb++;
+						}
+					}
+					rxd_hw->q[idx].status = 0;
+				}
+				else
+				{
+					// Exit the loop because we have reached a receive
+					// buffer that has not had any data put into it.
+					break;
+				}
+ 			}
+			else
+			{
+				// Drop rx packets here
+ 				rxd_hw->q[idx].status = 0;
+				thisadapter->stats.rx_dropped++;
+			}
+		}
+		else
+		{
+			// Exit the loop because we are now up to the receive
+			// buffer that the dma hardware is currently working in.
+			break;
+		}
+	}
+
+    thisadapter->E_NA_settings |= E_NA_SR;
+	*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+	// Set the receive frame interrupt mask bit so
+	// that receive frame interrupts will start
+	// occurring again.
+#if RX_DMA_INT
+    cnxt_unmask_irq( thisadapter->rx_dma_int );	
+#else
+	thisadapter->E_IE_settings |= E_IE_RI;
+	*thisadapter->emac_ie_reg = thisadapter->E_IE_settings;
+#endif
+}
+
+
+#if RX_TASKLET
+DECLARE_TASKLET( emac1_rx_tasklet, EMAC_Rx_Process, (unsigned long) &emac_dev[0]);
+DECLARE_TASKLET( emac2_rx_tasklet, EMAC_Rx_Process, (unsigned long) &emac_dev[1]);
+#endif
+
+
+#if RX_DMA_INT
+/******************************************************************************
+|
+|  Function:  EMAC_RxISR
+|
+|  Description:  handle device RX interrupts
+|				 This interrupt service routine, reads device interrupt status, acknowledges
+|				 the interrupting events, and schedules transmit when required.
+|				
+|  Parameters:  *pDrvCtrl - Pointer Driver Cntrl
+|
+|  Returns:   NONE
+*******************************************************************************/
+
+static void EMAC_RxISR(int irq, void *dev_id, struct pt_regs * regs)
+{
+	register EMAC_DRV_CTRL *thisadapter=( EMAC_DRV_CTRL *)((struct net_device *)dev_id)->priv; 
+
+	/* Clear the INT1_Stat register of pending TX interrupts */
+	*INT_Stat = thisadapter->int_stat_clr_rx;
+
+#if RX_TASKLET		
+	// Process the received frames(s) via a tasklet
+	// Clear out the receive frame interrupt mask after
+	// getting the interrupt.  The tasklet will set the
+	// mask bit again after it processes the received
+	// frames.  This keeps the system from getting more
+	// receive frame interrupts while it is already 
+	// scheduled to run the tasklet or is already running
+	// the tasklet.
+    cnxt_mask_irq( thisadapter->rx_dma_int );	
+	 
+	switch( thisadapter->emac_num )
+	{
+		case 1:
+			tasklet_schedule(&emac1_rx_tasklet);
+			break;
+
+		case 2:
+			tasklet_schedule(&emac2_rx_tasklet);
+			break;
+	}
+#else
+	EMAC_Rx_Process( dev );
+#endif
+}
+#endif
+
+#if TX_TASKLET
+static void EMAC_Tx_Process( unsigned long data )
+{
+#if EMAC_TX_UDELAY
+	udelay( 2 );
+#endif
+	EMAC_Tx_Pkt_Done((struct net_device *)*((unsigned long *)data) );
+}
+
+DECLARE_TASKLET( emac1_tx_tasklet, EMAC_Tx_Process, (unsigned long) &emac_dev[0]);
+DECLARE_TASKLET( emac2_tx_tasklet, EMAC_Tx_Process, (unsigned long) &emac_dev[1]);
+#endif
+
+#if TX_DMA_INT
+/******************************************************************************
+|
+|  Function:  EMAC_TxISR
+|
+|  Description:  handle device TX interrupts
+|				 This interrupt service routine, reads device interrupt status, acknowledges
+|				 the interrupting events, and schedules transmit when required.
+|				
+|  Parameters:  *pDrvCtrl - Pointer Driver Cntrl
+|
+|  Returns:   NONE
+*******************************************************************************/
+
+static void EMAC_TxISR(int irq, void *dev_id, struct pt_regs * regs)
+{
+	register EMAC_DRV_CTRL *thisadapter=( EMAC_DRV_CTRL *)((struct net_device *)dev_id)->priv; 
+
+	/* Clear the INT1_Stat register of pending TX interrupts */
+	*INT_Stat = thisadapter->int_stat_clr_tx;
+
+#if EMAC_TX_WD_TIMER
+	// Effectively disable the tx watchdog timer by setting
+	// it to a very long timeout.
+	del_timer(&thisadapter->wd_timer );
+#endif
+#if TX_TASKLET		
+	switch( thisadapter->emac_num )
+	{
+		case 1:
+			tasklet_schedule(&emac1_tx_tasklet);
+			break;
+
+		case 2:
+			tasklet_schedule(&emac2_tx_tasklet);
+			break;
+	}
+#else
+	// TRANSMIT FRAMES
+	// Check to see if an EMAC frame transmitted OK
+	// Perform housekeeping on the just transmitted frame
+#if EMAC_TX_UDELAY
+	udelay( 1 );
+#endif
+	EMAC_Tx_Pkt_Done( dev_id );
+#endif
+}
+#endif
+
+
+/******************************************************************************
+|
+|  Function:  EMAC_Exception_ISR
+|
+|  Description:   handle ethernet DMA device errors
+|				
+|  Returns:   None
+*******************************************************************************/
+
+static void EMAC_Exception_ISR(int irq, void *dev_id, struct pt_regs * regs)
+{
+    register unsigned long 	estatus;	/* contains the status of the ethernet hardware */
+#if (!RX_DMA_INT || !TX_DMA_INT)
+    register unsigned long 	lstatus;	/* contains the status of the last packet register */
+#endif
+	register EMAC_DRV_CTRL *thisadapter=( EMAC_DRV_CTRL *)((struct net_device *)dev_id)->priv; 
+
+	// Get the EMAC exception condition registers
+	estatus = *thisadapter->emac_stat_reg;
+#if (!RX_DMA_INT || !TX_DMA_INT)
+    lstatus = *thisadapter->emac_lp_reg;
+#endif
+
+	// Now clear out the ARM INT_Stat register interrupt that got us here
+	*thisadapter->emac_stat_reg = estatus;
+
+#if (!RX_DMA_INT || !TX_DMA_INT)
+    *thisadapter->emac_lp_reg = lstatus;
+#endif
+	*INT_Stat = thisadapter->int_stat_clr_dev_irq;
+
+#if !RX_DMA_INT
+	// RECEIVE FRAMES
+	// Check to see if an EMAC frame was received properly
+	if( lstatus & ( E_LP_RI ))
+	{
+	#if RX_TASKLET		
+		// Process the received frames(s) via a tasklet
+		// Clear out the receive frame interrupt mask after
+		// getting the interrupt.  The tasklet will set the
+		// mask bit again after it processes the received
+		// frames.  This keeps the system from getting more
+		// receive frame interrupts while it is already 
+		// scheduled to run the tasklet or is already running
+		// the tasklet.
+		thisadapter->E_IE_settings &= ~E_IE_RI;
+		*thisadapter->emac_ie_reg = thisadapter->E_IE_settings;
+		 
+		switch( thisadapter->emac_num )
+		{
+			case 1:
+				tasklet_schedule(&emac1_rx_tasklet);
+				break;
+
+			case 2:
+				tasklet_schedule(&emac2_rx_tasklet);
+				break;
+		}
+	#else
+		EMAC_Rx_Process( dev );
+	#endif
+	}
+#endif
+#if !TX_DMA_INT
+	#if USE_TU_INTERRUPT
+	// TRANSMIT FRAMES
+	// Check to see if the EMAC transmitter has stopped
+    if( estatus & (E_S_TU) )
+	{
+		#if EMAC_TX_WD_TIMER
+		del_timer(&thisadapter->wd_timer );
+		#endif
+		#if TX_TASKLET		
+		switch( thisadapter->emac_num )
+		{
+			case 1:
+				tasklet_schedule(&emac1_tx_tasklet);
+				break;
+
+			case 2:
+				tasklet_schedule(&emac2_tx_tasklet);
+				break;
+		}
+		#else
+		// TRANSMIT FRAMES
+		// Check to see if an EMAC frame transmitted OK
+		// Perform housekeeping on the just transmitted frame
+			#if EMAC_TX_UDELAY
+		udelay( 1 );
+			#endif
+		EMAC_Tx_Pkt_Done( dev_id );
+		#endif
+	}
+	#else
+	// TRANSMIT FRAMES
+	// Check to see if an EMAC frame transmitted OK
+    if
+    ( 
+    		( lstatus & ( E_LP_TI ) )
+		#if HOMEPLUGPHY
+			// The CX11656 HomePlug device uses the mii CRS bit
+			// to indicate when it has a free tx buffer.
+    	||	( PhyActiveHOMEPLUG( thisadapter->pPhy) & ( estatus & ( E_S_LCRS) ) )
+		#endif
+    )
+	{
+		// Perform housekeeping on the just transmitted frame
+		EMAC_Tx_Pkt_Done( dev ); 
+	}
+	#endif
+#endif
+
+	// Check for tx/rx frame errors
+	if(	estatus & ( E_S_LC | E_S_16 ))
+	{
+		// FATAL ERROR CONDITIONS
+		// NOTE: These error conditions must fall through to
+		// the EMAC_restart_hw at the end of the list.
+		if ( estatus & E_S_LC )
+		{
+			#if EMAC_ISR_ERR_MSG_PRINT
+			printk( KERN_DEBUG "ETH%d: TX Late Collision\n", thisadapter->unit);  
+			#endif
+		}
+
+		if( estatus &  E_S_16 )
+	    {
+			#if EMAC_ISR_ERR_MSG_PRINT
+			printk( KERN_DEBUG "ETH%d: TX Excessive Collisions\n", thisadapter->unit);  
+			#endif
+		}
+		thisadapter->stats.collisions += (estatus & TSTAT_CC);	
+
+		EMAC_stop_hw( dev_id );
+		
+		// FATAL error in mutually exclusive tx parts
+		thisadapter->hw_reset_required = TRUE;
+		
+	#if HW_RESET_EVENT
+		SET_EVENT( thisadapter->hw_reset_event );
+	#endif
+	}
+}
+
+
+/******************************************************************************
+|
+|  Function:  EMAC_Linkcheck
+|
+|  Description: Read the PHY link status and set the MAC according to the 
+|				established link rate
+|
+|  Returns:   NONE
+|
+*******************************************************************************/
+
+void EMAC_Linkcheck(EMAC_DRV_CTRL *thisadapter, BOOLEAN force_update )
+{
+    
+	unsigned long phy_settings;
+    
+	// If TRUE then clear out the adapter phySettings variable so
+	// that the logical flow of this function will cause the
+	// adapter E_NA_settings and the E_NA_x hardware register for
+	// this adapter to be updated.
+	if( force_update == TRUE )
+	{
+		thisadapter->phyState.phySettings = 0;
+	}
+
+	/*************************************************
+	* 	Read the current link settings from the PHY. *
+	*************************************************/
+    phy_settings = PhyCheck(thisadapter->pPhy);
+
+    /* Check settings and record the link state.
+	   If we are in FORCEDMODE, skip speed and duplex check.
+       If we are in auto-negotiation mode, deduce what the link speed and duplex
+       should be.  If the link is down, default it to 10 HDX.
+    */
+    if ( phy_settings != thisadapter->phyState.phySettings )
+    {
+        thisadapter->phyState.phySettings = phy_settings;
+
+        if ( phy_settings & PHY_LINK_UP )
+        {
+            if ( thisadapter->phyState.linkStatus != PHY_STAT_LINK_UP )
+            {
+                thisadapter->phyState.linkStatus = PHY_STAT_LINK_UP;
+            }
+
+        	if ( thisadapter->phyState.autoNegotiate == PHY_AUTONEGOTIATE )
+			{
+	            if ( phy_settings & PHY_LINK_100 )
+                {
+	                thisadapter->phyState.networkSpeed = PHY_STAT_SPEED_100;
+                }
+	            else
+                {
+	                thisadapter->phyState.networkSpeed = PHY_STAT_SPEED_10;
+                }
+
+	            if ( phy_settings & PHY_LINK_FDX )
+				{
+	                thisadapter->phyState.duplexMode = PHY_STAT_DUPLEX_FULL;
+	            }
+	            else
+	            {
+	                thisadapter->phyState.duplexMode = PHY_STAT_DUPLEX_HALF;
+				}
+			}
+        }
+        else
+        {
+            if ( thisadapter->phyState.linkStatus != PHY_STAT_LINK_DOWN )
+            {
+                thisadapter->phyState.linkStatus = PHY_STAT_LINK_DOWN;
+            }
+
+        	if ( thisadapter->phyState.autoNegotiate == PHY_AUTONEGOTIATE )
+			{
+	            thisadapter->phyState.networkSpeed = PHY_STAT_SPEED_100;
+	            thisadapter->phyState.duplexMode = PHY_STAT_DUPLEX_FULL;
+			}
+        }
+
+		// Update the E_NA_settings and E_NA_x hardware register
+        EMACHW_Configure_Mac
+        (
+        	thisadapter,
+        	TRUE,
+			(thisadapter->phyState.networkSpeed == PHY_STAT_SPEED_100 ),
+			(thisadapter->phyState.duplexMode == PHY_STAT_DUPLEX_FULL )
+		);
+	}
+}
+
+
+/******************************************************************************
+|
+|  Function:  EMAC_init_tx
+|
+|  Description: initializes all queues and registers necessary to begin receiving
+| 				data from the RMAC.
+|
+|  Returns:   OK on success; otherwise ERROR.
+|
+*******************************************************************************/
+
+static signed int EMAC_init_tx( EMAC_DRV_CTRL *	thisadapter )
+{
+	BYTE				*txd_buf;
+	BYTE				*txd_end;
+	unsigned int		i;
+
+#if SDRAM_TX_MEM
+    txd_end = (BYTE *)EMAC_KMALLOC(sizeof(EMAC_TD)+16, GFP_KERNEL);
+#else
+	txd_end = SYSMEM_Allocate_BlockMemory( 1, sizeof(EMAC_TD)+16, 16 );
+#endif
+    if (txd_end == NULL)
+    {
+    	printk("EMAC:TxD_end alloc() FAIL!\n");
+    }
+
+    QWORD_ALIGN_PTR( txd_end );
+	thisadapter->TxD_end = (EMAC_TD *)txd_end;
+
+	// Zero out thisadapter->TxD_end structure
+	// so that everything is at a known state
+	memset( thisadapter->TxD_end, 0, sizeof(EMAC_TD) + 16 );
+
+	// Obtain memory for the txd buffers
+#if SDRAM_TX_MEM
+	if(( txd_buf = (BYTE *) EMAC_KMALLOC((TX_RING_SIZE * ETH_PKT_BUF_SZ) + QWORD_ALIGN_PAD, GFP_KERNEL)) == NULL ) 
+#else
+	if(( txd_buf = SYSMEM_Allocate_BlockMemory( 1, (TX_RING_SIZE * ETH_PKT_BUF_SZ) + QWORD_ALIGN_PAD, 16 )) == NULL ) 
+#endif
+    {
+    	printk("EMAC:txd_buf alloc() FAIL!\n");
+    }
+
+	// Save the unaligned txd buffer pointer originally obtained
+	// from kmalloc to subsequent use in freeing the memory.
+	thisadapter->txd_buf_mem = txd_buf;
+    QWORD_ALIGN_PTR(txd_buf);
+
+	// Initialize the txd buffer array with pointers to the buffers
+	for( i = 0; i < TX_RING_SIZE; i++ ) 
+	{
+		thisadapter->txd_buf[i] = (txd_buf + (ETH_PKT_BUF_SZ * i));
+	}
+
+    //	Initialize the tx msg queue.
+    thisadapter->tx_msg_q_next = 0;
+    thisadapter->tx_msg_q_current = 0;
+    thisadapter->tx_msg_q_size = 0;
+    memset((char*)thisadapter->tx_msg_q, 0, sizeof(thisadapter->tx_msg_q));
+	
+    return 0;
+}
+
+
+/******************************************************************************
+|
+|  Function:  init_RX_EMAC
+|
+|  Description: initializes all queues and registers necessary to begin receiving
+| 				data from the RMAC.
+|
+|  Returns:   OK on success; otherwise ERROR.
+|
+*******************************************************************************/
+
+static signed int EMAC_init_rx( EMAC_DRV_CTRL	*thisadapter )
+{
+	EMAC_RXD_HW_QTYPE	*rxd_hw;
+	BYTE				*rxd_buf;
+	unsigned int		i;
+
+	/****************************************************************
+    	Obtain and clear memory for the RxD table and management 
+        information list.
+    ****************************************************************/
+    if (( rxd_hw = (EMAC_RXD_HW_QTYPE *)EMAC_KMALLOC(sizeof(EMAC_RXD_HW_QTYPE)+16,GFP_KERNEL)) == NULL )
+    {
+    	printk("EMAC:rxd_hw alloc() FAIL!\n");
+    }
+
+    QWORD_ALIGN_PTR(rxd_hw);
+	thisadapter->rxd_hw = rxd_hw;
+	
+	// Zero out thisadapter->rxd_hw structure
+	// so that everything is at a known state
+	memset( thisadapter->rxd_hw, 0, sizeof(EMAC_RXD_HW_QTYPE) + 16 );
+	
+	// Obtain memory for the rxd buffers
+	if(( rxd_buf = (BYTE *) EMAC_KMALLOC((RX_RING_SIZE * ETH_PKT_BUF_SZ) + QWORD_ALIGN_PAD, GFP_KERNEL)) == NULL ) 
+    {
+    	printk("EMAC:rxd_buf alloc() FAIL!\n");
+    }
+
+	// Save the unaligned rxd buffer pointer originally obtained
+	// from kmalloc to subsequent use in freeing the memory.
+	thisadapter->rxd_buf = rxd_buf;
+    QWORD_ALIGN_PTR(rxd_buf);
+
+	// Initialize the rxd hardware q buffer pointers with buffers
+	for( i = 0; i < RXD_NUM; i++ ) 
+	{
+		rxd_hw->q[i].mData = rxd_buf + (ETH_PKT_BUF_SZ * i);
+		rxd_hw->q[i].reserved = 0;
+		rxd_hw->q[i].status = 0;
+		rxd_hw->q[i].mib = 0;
+	}
+
+	/****************************************************************
+    	Initialize the hardware RxD Q index.
+    ****************************************************************/
+    rxd_hw->qndx = 0;
+
+	/****************************************************************
+		Initialize DMA4 to generate an interrupt at the end of 
+        receiving a packet.  Leave some space for padding at the
+        beginning and ending of the cluster.  At least seven bytes
+        are needed for cluster alignment, eight bytes are used by
+        the RMAC DMA channel, and two bytes may be used by the 
+        IP alignment copy if an in-cluster copy is performed.
+    ****************************************************************/
+	*thisadapter->emac_rx_dma_ptr2 = (unsigned long)(&rxd_hw->q[0]); /* address of descriptor list */
+    *thisadapter->emac_rx_dma_cnt1 = (unsigned long)((CL_SIZ/8)-4); /* size of cluster in qwords */
+	*thisadapter->emac_rx_dma_cnt2 = (unsigned long)(2 * RXD_NUM);  /* number of descriptors * 2 */
+
+    return 0;
+}
+
+
+static int emac_set_mac_address(struct net_device *dev, void *addr)
+{
+	int i;
+
+	if(netif_running(dev))
+	{
+    	return -EBUSY;
+	}
+
+	printk("%s : CNXT set mac address\n",dev->name);
+
+	for( i = 0; i < MAC_ADDR_LEN; i++)
+	{
+	    printk(" %2.2x",dev->dev_addr[i]=((unsigned char *)addr)[i]);
+	}
+	printk(".\n");
+	return 0;
+}
+
+
+/******************************************************************************
+|
+|  Function:  sp_emac_open
+|
+|  Returns:   OK on success; otherwise ERROR.
+|
+*******************************************************************************/
+
+static int emac_open(struct net_device *dev)
+{
+
+	EMAC_DRV_CTRL *thisadapter=(EMAC_DRV_CTRL*)dev->priv;
+
+	// Get the current emac line state
+	EMAC_Linkcheck( thisadapter, TRUE );
+
+	// If the physical link is not up then blow off any transmit packets
+	if(	thisadapter->phyState.linkStatus == PHY_STAT_LINK_UP )
+	{
+		netif_carrier_on( dev );
+	}
+	else
+	{
+		netif_carrier_off( dev );
+	}
+
+#if (TX_FULL_DUPLEX && EMAC_MUTUALLY_EX_OPR)
+	// Check for and configure emacs for mutally
+	// exclusive transmitter operation.
+	EMAC_Mutually_Ex_Op_Chk( dev );
+#endif
+	
+#if HOMEPLUGPHY
+    if( PhyActiveHOMEPLUG( thisadapter->pPhy) )
+    {
+	    TeslaControl_Str TeslaControl ;
+
+		// Pointer back to dev needed for homeplug functions
+		thisadapter->dev = dev;
+		
+        Emac_TeslaConfigRead( &TeslaControl ) ;
+        Emac_TeslaSetup( (PVOID)thisadapter, &TeslaControl) ;
+    }
+#endif
+	
+	// Set up the emac hardware filtering for perfect address filtering 
+	thisadapter->E_NA_settings |= E_NA_FILTER_MC1PERFECT;	
+	*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+	*thisadapter->emac_stat_reg = 0;
+
+	// Configure the emac hardware filtering 
+	emac_SetupFrame ( dev );
+
+	/********************************************
+	    Set the operating modes for the EMAC
+        receiver and transmitter.
+	********************************************/
+
+	thisadapter->E_IE_settings =
+	(
+#if !RX_DMA_INT
+		E_IE_RI		|	/* Receive OK interrupt enable (masks E_LP_RI) */
+#endif	
+#if !TX_DMA_INT
+	#if USE_TU_INTERRUPT
+		E_IE_TU		|	/* Transmit process stopped interrupt enable (masks E_S_TU) */
+	#endif
+#endif	
+		E_IE_LC		|	/* Late collision interrupt enable (masks E_S_LC) */
+		E_IE_16			/* 16 collisions interrupt enable (masks E_S_16) */
+	);
+
+#if HOMEPLUGPHY
+	if( PhyActiveHOMEPLUG( thisadapter->pPhy) )
+	{
+		// The CX11656 device uses the mii CRS signal
+		//  to indicate when it has a free tx buffer
+		thisadapter->E_IE_settings |= E_IE_LCRS;
+	}
+	else
+	{
+	#if !TX_DMA_INT
+		thisadapter->E_IE_settings |= E_IE_TI;
+	#endif
+	}
+#endif
+
+	*thisadapter->emac_ie_reg = thisadapter->E_IE_settings;
+    
+	// Start the receiver operating now
+    thisadapter->E_NA_settings |= (E_NA_SR|E_NA_SB);
+	*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+	// Indicate the emac is open
+	thisadapter->emac_state = OPEN;
+	
+	// Enable the device irq
+    cnxt_unmask_irq( dev->irq );
+	
+#if TX_DMA_INT
+    cnxt_unmask_irq( thisadapter->tx_dma_int );	
+#endif
+#if RX_DMA_INT
+    cnxt_unmask_irq( thisadapter->rx_dma_int );	
+#endif
+
+	// Inform the OS that we can accept packets now
+	netif_start_queue(dev);
+
+	printk("%s: (CX821xx EMAC) started!\n",dev->name);
+	return 0;
+}
+
+
+/******************************************************************************
+|
+|  Function:  ResetChip
+|
+|  Description:   Reset the chip and setup E_NA register
+|				  This routine stops the transmitter and receiver, masks all interrupts, then
+|				  resets the ethernet chip. Once the device comes out of the reset state, it
+|				  initializes E_NA register.
+|
+|  Parameters:  
+|
+|  Returns:   
+*******************************************************************************/
+
+void ResetChip( EMAC_DRV_CTRL *thisadapter )	/* pointer to device control structure */
+{
+    
+	/* Delay between applying the reset condition and clearing it 
+		and then delay again after releasing the condition. Sometimes not all
+		aspects of the chip have reached their new state with a back to back
+		bit set and clear. */
+
+	// NOTE: The following delays between the register writes were empirically
+	// derived because there is no value specified in the hardware document
+	// as to how long it actually takes.
+	// Do the delays as a series of usec delays so that if an interrupt is
+	// pending it can occur between them.
+    EMAC_REG_WRITE( E_NA, E_NA_RTX, thisadapter->emac_hdw_num );
+	udelay( 100 );
+	udelay( 100 );
+	udelay( 50 );
+    EMAC_REG_WRITE( E_NA, 0, thisadapter->emac_hdw_num );
+	udelay( 100 );
+	udelay( 100 );
+	udelay( 50 );
+    EMAC_REG_WRITE( E_NA, 0, thisadapter->emac_hdw_num );
+	udelay( 100 );
+	udelay( 100 );
+	udelay( 50 );
+}
+
+
+#if USE_HASHTABLE
+HI HashIndex(unsigned char* eAddr)
+{
+    HI hi;/* hash index - return value */
+    hi  = eAddr[0];
+    hi ^= eAddr[1];
+    hi ^= eAddr[2];
+    return hi; 
+}
+
+/******************************************************************************
+|
+|  Function:  SetupHashTable
+|
+|  Description:  sets up the hash table for multicast addresses.
+|				 This routine should be called whenever there is an addition
+|				 or a deletion of multicast address. And also in endStart.
+|				 While the first call to this routine during chip 
+|				 initialization requires that the receiver be turned off, 
+|				 subsequent calls do not.
+|
+|  Returns:    OK/ERROR
+*******************************************************************************/
+static void SetupHashTable(struct net_device *dev)
+{
+    EMAC_DRV_CTRL *thisadapter = (EMAC_DRV_CTRL *)dev->priv;
+	struct dev_mc_list *dmi = dev->mc_list;
+	HI hi;
+	int i;
+
+
+#ifdef SUPPORT_BROADCAST_FILTER
+    UINT8	ethBcastAdrs[]={ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+#endif /* SUPPORT_BROADCAST_FILTER */
+
+    /* 
+     * Initialize the hash table to zeroes so that the "wrong" 
+     * multicast address don't get reflected in the table this time.
+     * Here the "wrong" are the ones added/deleted between the last two
+     * consecutive calls of this function.
+     */
+    memset( (signed char*)thisadapter->hashTable,0, HASH_TABLE_SIZE );
+    
+	if (!(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) 
+	{
+		for (i = 0; i < dev->mc_count; i++)
+		{
+			hi = (HI)HASH_INDEX ((unsigned char*)dmi->dmi_addr );
+			ADD_TO_HASHTBL(thisadapter, hi);
+			dmi = dmi->next;
+		}
+	}
+	
+#ifdef SUPPORT_BROADCAST_FILTER
+    /* Install the ethernet broadcast address */
+    hi = HASH_INDEX ((unsigned char*)ethBcastAdrs);
+    ADD_TO_HASHTBL(pDrvCtrl, hi);       /* Add index to table */
+#endif /* SUPPORT_BROADCAST_FILTER */
+
+
+}
+#endif
+
+/******************************************************************************
+|
+|  Function:  sp_emac_probe
+|
+|  Description: 
+|  Parameters:  struct net_device *dev
+|
+|
+*******************************************************************************/
+
+int __init emac_probe(struct net_device *dev)
+{
+	EMAC_DRV_CTRL	*thisadapter;
+	EMAC_DRV_CTRL	*temp;
+	
+	DATA_QUEUE_T	*tx_pkt_q;
+	int				i;
+	int				j;
+	unsigned long	flags;
+	DWORD			dev_num;
+	DWORD			hdw_idx;
+	ULONG			*txd_end;
+
+	// Determine what ethernet device number we are
+	if (dev->name && (strncmp(dev->name, "eth", 3) == 0))
+	{
+		dev_num = simple_strtoul(dev->name + 3, NULL, 0);
+
+		// Do this stuff only when the first device is probed
+		if( dev_num == 0 )
+		{
+			EMAC_hdw_cntr = 0;
+
+		#if (TX_FULL_DUPLEX && EMAC_MUTUALLY_EX_OPR)
+			// Initially assume that we do not
+			// need mutually exclusive operation.
+			emac_mutually_ex_opr = FALSE;
+		#else
+			emac_mutually_ex_opr = TRUE;
+		#endif
+					
+		#if SETUP_FRAME_VERIFY
+			sf_verify = FALSE;
+		#endif
+			for( i = 0; i < RX_RING_SIZE; i++ )
+			{
+				j = ( i + (	RX_RING_SIZE - RX_LOOKBACK_THRESHOLD )) % RX_RING_SIZE;
+				rx_lookback_idx[ i ] = j;
+			}
+			
+			// Allocate space for the transmit frame queues
+			EMAC_tx_pkt_q1 = ( DATA_QUEUE_T *)(EMAC_KMALLOC( sizeof(DATA_QUEUE_T), GFP_KERNEL));
+			EMAC_tx_pkt_q2 = ( DATA_QUEUE_T *)(EMAC_KMALLOC( sizeof(DATA_QUEUE_T), GFP_KERNEL));
+		}
+
+		// NOTE: dev_num is zero relative
+		if( dev_num > ( MAX_ETH_PORTS - 1 ) || EMAC_hdw_cntr > (MAX_ETH_PORTS - 1))
+		{
+			#if 0
+			printk("emac_probe: %s is not supported by CX821xx Family BSP\n",dev->name);
+			#endif
+			return -ENODEV;
+		}
+	}
+	else
+	{
+		// Device name was not an ethernet device
+		return -ENODEV;
+	}
+
+	thisadapter=( EMAC_DRV_CTRL *)(EMAC_KMALLOC(sizeof(EMAC_DRV_CTRL)+QWORD_ALIGN_PAD, GFP_KERNEL));
+
+	if(thisadapter == NULL)
+	{
+		printk("emac_probe: Out Of Memory %s\n",dev->name);
+		return -ENODEV;
+	}
+
+	// Zero out the emac drive control structure
+	// so that everything is at a known state
+	memset( thisadapter, 0, sizeof(EMAC_DRV_CTRL)+QWORD_ALIGN_PAD);
+	
+	// Save a copy of the original adapter pointer
+	// in case we have to free the memory.
+	temp = thisadapter;
+
+	QWORD_ALIGN_PTR(thisadapter);
+	dev->priv = thisadapter;
+
+    if( !(thisadapter->pPhy = PhyAllocateMemory()) )	// PORT
+    {
+		printk("Fatal Error -- PHY OBJ Memory allocation Failure\n");
+		return -ENODEV;
+    }
+
+	// Get the configuration parameters for the emac from the flash
+    if ( EMAC_GetPortConfig( dev_num, thisadapter) == FALSE )
+    {
+        /* Error!*/
+
+        return -ENODEV;
+    }
+
+	// Probe for emac hardware now
+	for( hdw_idx = EMAC_hdw_cntr; hdw_idx <= MAX_ETH_PORTS; hdw_idx++)
+	{
+
+		EMAC_hdw_cntr = hdw_idx;
+		
+		// Fill in the emac hardware number field of the first
+		// emac hardware that we will try for use by the Phy code.
+		// NOTE: This field is zero relative.
+
+		thisadapter->emac_hdw_num = hdw_idx;
+		// Check to see if we reached the end of the list
+		// potential emac hardware ports.
+		if ( hdw_idx >= MAX_ETH_PORTS )
+		{
+			// Free up the emac adapter context memory
+			EMAC_KFREE(temp);				
+			EMAC_KFREE( thisadapter->pPhy );
+			printk("emac_probe:  PHY INIT failed.\n");
+			return -ENODEV;
+		}
+					
+		// Reset the emac hardware 
+		ResetChip( thisadapter );
+		
+		// Probe for the presence of and if found, reset
+		// and initialize the PHY and MAC layers.
+	    if( PhyInit(
+	    				(unsigned long) EMAC_REG_ADDR(E_DMA, thisadapter->emac_hdw_num ),
+						thisadapter->pPhy, 
+						EMAC_MapToPhyConn ( &thisadapter->phyState ), 
+						PHY_HWOPTS_PORT_HOPPING,
+						thisadapter->pHpna
+
+					) == PHY_STATUS_OK )
+	    {
+
+			// We found an emac device
+			hdw_idx++;
+			EMAC_hdw_cntr = hdw_idx;
+			break;
+		}
+	}
+
+	thisadapter->flags = 0;
+
+#if EMAC_TX_WD_TIMER
+	#if 1
+	// Disable interrupts
+	local_irq_save(flags);
+
+	#endif
+	init_timer(&thisadapter->wd_timer);
+	thisadapter->wd_timer.data = (unsigned long)dev;
+	thisadapter->wd_timer.function = (void *)&EMAC_tx_timeout;
+	#if 1
+
+	// Reenable interrupts
+	local_irq_restore(flags);
+	#endif
+
+#endif
+	spin_lock_init(&thisadapter->lock);
+	
+	// This is the Linux ethx number
+	thisadapter->unit = dev_num;
+
+#if EMAC_MUTUALLY_EX_OPR
+	// See if this is a mutually exclusive tx emac part
+	thisadapter->tx_mutex_part = CnxtBsp_Mac_MutEx_Chk();
+#endif
+
+	//!!! test code !!!
+	printk("emac_probe: %s found.\n",dev->name);
+	//!!! test code !!!
+
+	// Initialize the device specific stuff
+	switch( thisadapter->emac_hdw_num )
+	{
+		// emac1
+		case 0:
+			emac_dev[0] = dev;
+			thisadapter->emac_num = 1;
+
+			dev->irq = CNXT_INT_LVL_E1_ERR;
+			dev->base_addr = (ULONG)(EMAC_BASE_ADDR + ( dev_num * 0x00010000));
+			thisadapter->emac_tx_dma_ptr =	DMAC_1_Ptr1;
+		#if EMAC_MUTUALLY_EX_OPR
+			// CX82100-41 parts and above do not need this nonsense
+			if( thisadapter->tx_mutex_part == FALSE )
+			{
+				// CX82100-41
+				thisadapter->emac_tx_dma_ptrx =	DMAC_1_Ptr1;
+			}
+			else
+			{
+				thisadapter->emac_tx_dma_ptrx =	DMAC_3_Ptr1;
+			}
+		#endif
+			thisadapter->emac_rx_dma_ptr2 = DMAC_2_Ptr2;
+			thisadapter->emac_tx_dma_cnt =	DMAC_1_Cnt1;
+			thisadapter->emac_rx_dma_cnt1 = DMAC_2_Cnt1;
+			thisadapter->emac_rx_dma_cnt2 = DMAC_2_Cnt2;
+			thisadapter->emac_na_reg = E_NA_1_reg;
+			thisadapter->emac_stat_reg = E_STAT_1_reg;
+			thisadapter->emac_lp_reg = E_LP_1_reg;
+			thisadapter->emac_ie_reg = E_IE_1_reg;
+			thisadapter->tx_dma_int = CNXT_INT_LVL_DMA1;
+			thisadapter->rx_dma_int = CNXT_INT_LVL_DMA2;
+			thisadapter->int_stat_clr_dev_irq = CNXT_INT_MASK_E1_ERR;
+			thisadapter->int_stat_clr_tx = INT_DMA_EMAC_1_TX;
+			thisadapter->int_stat_clr_rx = INT_DMA_EMAC_1_RX;
+			thisadapter->tx_pkt_in_progress = FALSE;
+
+		#if TX_FULL_DUPLEX
+			thisadapter->emac_tx_q = EMAC_tx_pkt_q1;
+		#else
+			thisadapter->emac_tx_q = EMAC_tx_pkt_q2;
+		#endif
+			tx_pkt_q = thisadapter->emac_tx_q;
+			tx_pkt_q->entry_cnt = 0;
+			tx_pkt_q->get_idx = 0;
+			tx_pkt_q->put_idx = 0;
+
+			kernel_thread( (void *)EMAC1_Task, dev , CLONE_FS | CLONE_FILES  );
+			break;
+			
+		// emac2
+		case 1:
+			emac_dev[1] = dev;
+			thisadapter->emac_num = 2;
+
+			dev->irq = CNXT_INT_LVL_E2_ERR;
+			dev->base_addr = (ULONG)(EMAC_BASE_ADDR + ( dev_num * 0x00010000));
+			thisadapter->emac_tx_dma_ptr =	DMAC_3_Ptr1;
+		#if EMAC_MUTUALLY_EX_OPR
+			thisadapter->emac_tx_dma_ptrx =	DMAC_3_Ptr1;
+		#endif
+			thisadapter->emac_rx_dma_ptr2 = DMAC_4_Ptr2;
+			thisadapter->emac_tx_dma_cnt =	DMAC_3_Cnt1;
+			thisadapter->emac_rx_dma_cnt1 = DMAC_4_Cnt1;
+			thisadapter->emac_rx_dma_cnt2 = DMAC_4_Cnt2;
+			thisadapter->emac_na_reg = E_NA_2_reg;
+			thisadapter->emac_stat_reg = E_STAT_2_reg;
+			thisadapter->emac_lp_reg = E_LP_2_reg;
+			thisadapter->emac_ie_reg = E_IE_2_reg;
+			thisadapter->tx_dma_int = CNXT_INT_LVL_DMA3;
+			thisadapter->rx_dma_int = CNXT_INT_LVL_DMA4;
+			thisadapter->int_stat_clr_dev_irq = CNXT_INT_MASK_E2_ERR;
+			thisadapter->int_stat_clr_tx = INT_DMA_EMAC_2_TX;
+			thisadapter->int_stat_clr_rx = INT_DMA_EMAC_2_RX;
+			thisadapter->tx_pkt_in_progress = FALSE;
+			thisadapter->emac_tx_q = EMAC_tx_pkt_q2;
+
+		#if TX_FULL_DUPLEX
+			tx_pkt_q = thisadapter->emac_tx_q;
+			tx_pkt_q->entry_cnt = 0;
+			tx_pkt_q->get_idx = 0;
+			tx_pkt_q->put_idx = 0;
+		#endif
+
+			kernel_thread( (void *)EMAC2_Task, dev, CLONE_FS | CLONE_FILES  );
+			break;
+	}
+
+	// Retrieve the mac address for the device
+	CnxtBsp_Get_Mac_Address( dev_num, &thisadapter->PortNetAddress[0] );
+
+    /* memory Initializations.
+     * Allocation & Initialization of all the memory required by an 
+     * instance of the driver is done in the following function.
+     */
+
+	// Initialize the memory used by the transmitter
+    EMAC_init_tx( thisadapter );
+	printk("Tx DMA Ring %lx \n",(DWORD)thisadapter->txd_buf[0]);
+
+	// Initialize END TMAC TRANSMIT DESCRIPTOR
+	// NOTE: This must be done after the EMAC_init_tx function call
+	thisadapter->TxD_end->status = 0;     
+	thisadapter->TxD_end->status_zero =0;   
+	thisadapter->TxD_end->control = 0;
+
+	txd_end = (ULONG *) thisadapter->TxD_end;
+	txd_end[6] = (ULONG) txd_end;
+	txd_end[7] = 3;				/* avoids prefetch of next ptr and ctr */
+
+	// Initialize the memory used by the receiver
+    EMAC_init_rx( thisadapter );
+	printk("Rx DMA Ring %lx \n",(DWORD)thisadapter->rxd_buf);
+	
+	SET_MODULE_OWNER(dev);
+
+	dev->open				= emac_open;
+	dev->stop				= emac_close;
+	dev->hard_start_xmit	= emac_send_packet;
+	dev->get_stats			= emac_get_stats;
+	dev->set_multicast_list = &set_multicast_list;
+	dev->set_mac_address	= emac_set_mac_address;
+#if 0
+	dev->tx_timeout			= EMAC_Linux_tx_timeout;
+	dev->watchdog_timeo		= TX_TIMEOUT_DELAY + 10;
+#endif
+	
+	/* Fill in the fields of the device structure with ethernet values. */
+	ether_setup(dev);
+
+	printk("%s irq=%d ",version,dev->irq);
+	
+	for( i = 0; i < MAC_ADDR_LEN ; i++)
+	{
+		printk("%2.2x:", dev->dev_addr[i] = thisadapter->PortNetAddress[i]);
+	}
+	printk("\n");
+
+	// Connect the device irq to the OS interrupt handler
+	if (request_irq( dev->irq, &EMAC_Exception_ISR, 0, "Cnxt Ethernet Media Access Ctrl", dev))
+	{
+		return -EAGAIN;		
+	}
+
+	// Disable the device irq
+    cnxt_mask_irq( dev->irq );
+
+#if TX_DMA_INT
+	if (request_irq( thisadapter->tx_dma_int, &EMAC_TxISR, 0, "emac Tx Isr", dev))
+	{
+		return -EAGAIN;		
+	}
+	
+    cnxt_mask_irq( thisadapter->tx_dma_int );	
+#endif
+#if RX_DMA_INT
+	if (request_irq( thisadapter->rx_dma_int, &EMAC_RxISR, 0, "emac Rx Isr", dev))
+	{
+		return -EAGAIN;		
+	}
+	
+    cnxt_mask_irq( thisadapter->rx_dma_int );	
+#endif
+
+	return 0;
+}
+
+#if HOMEPLUGPHY
+
+struct sk_buff	homeplug_skb;
+BYTE			homeplug_msg_data[128];
+
+ADDR_TBL * Get_Free_Tx_Buffer( EMAC_DRV_CTRL *MACAdapter )
+{
+	homeplug_skb.data = &homeplug_msg_data[0];		
+	return &homeplug_skb;
+}
+
+void MAC_Assign_MacAddress( EMAC_DRV_CTRL *MACAdapter, UINT8 *S_Addr )
+{
+	MOVE_MEMORY( S_Addr, &MACAdapter->PortNetAddress[0], 6 ) ;
+}
+
+
+void MAC_Send_A_Frame( EMAC_DRV_CTRL *MACAdapter, UINT32 PacketSize, ADDR_TBL *PtrTxBuffer, BOOLEAN Control_Frame )
+{
+	TX_PKT_INFO		tx_pkt_info;
+	unsigned long	flags;
+	DWORD				entry;
+
+	// Generalize the data about the transmit packet
+	PtrTxBuffer->len = PacketSize;
+
+	tx_pkt_info.tx_pkt_data = PtrTxBuffer->data;
+	tx_pkt_info.tx_pkt_len = PtrTxBuffer->len;
+	tx_pkt_info.pkt_type = NORMAL;
+	
+	// Preprocess the transmit packet data for the emac driver
+	if( EMAC_Tx_Pkt_Process( MACAdapter, &tx_pkt_info, &entry ) == TRUE )
+	{
+		// Disable interrupts
+		spin_lock_irqsave(&MACAdapter->lock, flags); 
+
+		EMAC_Queue_Tx_Pkt( MACAdapter->dev, (DWORD)entry );
+		
+		// Transmit the successfully processed packet now
+		EMAC_Tx_Pkt_Transmit( MACAdapter->dev );
+		
+		// Reenable interrupts
+		spin_unlock_irqrestore(&MACAdapter->lock, flags);
+	}
+	else
+	{
+	}
+}
+#endif
+
diff -urN linux-2.4.29/drivers/net/cnxt_emac/cnxtEmac.h linux-2.4.29-uc1/drivers/net/cnxt_emac/cnxtEmac.h
--- linux-2.4.29/drivers/net/cnxt_emac/cnxtEmac.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/cnxtEmac.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,612 @@
+/****************************************************************************
+*
+*	Name:			cnxtEmac.h
+*
+*	Description:	Header file for cnxtEmac.c
+*
+*	Copyright:		(c) 2001,2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+*
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Jul 11 2003 07:36:44  $
+****************************************************************************/
+
+#ifndef __EMAC_END_H
+#define __EMAC_END_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+ * 
+ * includes 
+ *
+ */
+
+#include  <linux/skbuff.h>
+
+/* emac */
+#define INC_PHY
+#include "cnxtEmac_hw.h"      /* HW regs & related defines. */
+#include "filters.h"       /* Hashing, Address filtering & setup frame. */
+//#include "emac_type.h"
+#include <linux/if_ether.h>
+
+#include "phy.h"           /* Physical Layer Driver: types */
+#include <asm/arch/OsTools.h>
+
+
+/* PHY link status data structure and related #defines. */
+typedef struct phy_setting
+{
+    unsigned long   autoNegotiate;      // 0: disable,  1: enable
+    unsigned long   networkSpeed;       // 0: 10M,  1: 100M
+    unsigned long   duplexMode;         // 0: HDX,  1: FDX
+    unsigned long   linkStatus;         // 0: down, 1: up
+    unsigned long   phySettings;        // returned by PhyCheck ()
+} PHY_SETTING;
+
+#define PHY_FORCEDMODE          0
+#define PHY_AUTONEGOTIATE       1
+#define PHY_STAT_SPEED_10       0
+#define PHY_STAT_SPEED_100      1
+#define PHY_STAT_DUPLEX_HALF    0
+#define PHY_STAT_DUPLEX_FULL    1
+#define PHY_STAT_LINK_DOWN      0
+#define PHY_STAT_LINK_UP        1
+
+
+
+#if 0
+	#define	RX_RING_SIZE		64
+#else
+	#define	RX_RING_SIZE		80
+#endif
+#if 0
+	#define	TX_RING_SIZE		64
+#else
+	#define	TX_RING_SIZE		80
+#endif
+#if 1
+	#define ETH_PKT_BUF_SZ		1536
+#else
+	#define ETH_PKT_BUF_SZ		1600
+#endif
+
+
+/* Assign the appropriate number of RXD's based on the link speed. */
+#define RXD_NUM  RX_RING_SIZE
+/* Assign the mask number to allow wrap around in the RXD table. */
+#define RXD_NUM_WRAP  (RXD_NUM-1)
+
+#define SIZE_OF_DATA_QUEUES	(TX_RING_SIZE * 2)
+
+typedef struct
+{
+	DWORD	Data1;
+	DWORD	Data2;
+	DWORD	Data3;
+
+} DATA_REG_T;
+
+typedef struct
+{
+	
+	BYTE		get_idx;
+	BYTE		put_idx;
+	BYTE		entry_cnt;
+	BYTE		fill;		// Dword align the structure
+	DATA_REG_T	queue[SIZE_OF_DATA_QUEUES];
+	
+} DATA_QUEUE_T;
+
+
+#define DRV_NAME		"mac"
+#define DRV_NAME_LEN    5
+#define EDRV_DESC		"Conexant CX82100 EMAC Enhanced Network Driver"
+
+#define	NONE			0
+
+/*******************************************************************************
+ * Ethernet Standards:
+ *
+ * 1. Ethernet Frame fields - order left to right - are:
+ *    preamble[7],sfd[1],da[6],sa[6],type(or len)[2],data[var],pad[var],fcs[4].
+ *    Where, [x] = length in bytes. [var] = variable length.
+ *
+ *    da, sa & type(or len) put together is called ethernet header.
+ *
+ *    ISO802.3 has length field instead of Type field.
+ *    But in both cases ethernet & ISO802.3, the length of the 3rd field
+ *    remains 2 bytes. 
+ *
+ *    Ethernet address, Physical address & MAC address are synonymous.
+ *
+ *    ENET_HDR_REAL_SIZ: len of destination & source addr & type = 14 bytes.
+ *    ETHERMTU: max length of data & pad fields = 1500 bytes.
+ *    ETHERMIN: min length of data & pad fields (60-14) = 46 bytes.
+ *
+ * 2. MAC HW:
+ *    Preamble & sfd are removed/added by Rx/Tx MAC HW before the frame
+ *    is sent up/down to the protocols/cable. So as far as MAC SW (driver) goes, 
+ *    the frame starts from DA and ends with FCS.
+ */
+
+
+#define MAC_ADDR_LEN          ( 6 ) 
+           
+/* return value for MAC_cmp */
+#define MAC_GREATER           ( 1 )    
+#define MAC_EQUAL             ( 0 )
+#define MAC_LESS              ( -1 )
+
+/* size of multicast address and hash tables */
+#define MULTI_TABLE_SIZE      ( 256 )
+#define HASH_TABLE_SIZE       ( 32 )
+
+/* bit which defines whether a MAC Address is multi or uni cast */
+#define MULTICAST_MSK         ( 0x01 )
+
+/* hash table initialization values */
+#define FILTER_ALL            ( 0x00 )
+#define PASS_ALL              ( 0xFF )
+
+typedef enum
+{
+	NORMAL = 0,
+	SETUP
+
+} TX_PKT_TYPE;
+
+
+/****************************************************************************
+ * Structures
+ ****************************************************************************/
+
+#define EMAC_SETUP_PERFECT_ENTRIES     16
+typedef union _EMAC_SETUP_FRAME 
+{
+    struct 
+    {
+        unsigned long PhysicalAddress[EMAC_SETUP_PERFECT_ENTRIES][3];
+    } Perfect;
+} EMAC_SETUP_FRAME, *PEMAC_SETUP_FRAME;
+
+#define ADDRESS_FILTER_SIZE     192
+
+/* MAC Address */
+typedef UINT8 MAC_ADDR[MAC_ADDR_LEN];
+
+/* aligned MAC address */
+typedef struct aligned_mac_addr
+{
+   UINT16      usLSW;      /* least significant word */
+   UINT16      usCSW;      /* middle word */
+   UINT16      usMSW;      /* most significant word */
+} ALIGNED_MAC_ADDR;
+
+
+
+
+#define EMAC_CLUSTER_SZ  2048
+
+#define EADDR_LEN	        6       /* ethernet address length */
+
+#define NET_SPEED_10	10000000             /* 10 Mbps		*/
+#define NET_SPEED_100	100000000            /* 100 Mbps	*/
+
+/* Setup Frame Type */
+
+#define	MT_SETUP_FRAME	   ( NUM_MBLK_TYPES )   /* setup frame emac tx identifier */
+
+/* Call these in endMCastAddrAdd[Del] funcs. */
+#define DRV_END_DECR_MULTI(pDrvCtrl) ((pDrvCtrl)->endObj.nMulti--)
+#define DRV_END_INCR_MULTI(pDrvCtrl) ((pDrvCtrl)->endObj.nMulti++)
+
+/* 
+ * Mem alignment macros 
+ */
+
+#define QWORD_ALIGN_PTR(x) \
+	{  \
+		register unsigned int* p; \
+		p = (unsigned int*)(void*)&(x); \
+		*p=((*p)&0x7)?(((*p)|7)+1):(*p); \
+	}
+
+#define	QWORD_ALIGN_PAD		8
+#define QWORD_ALIGN_CHK		7
+#define SIZEOF_QWORD		8
+#define QWORD_ROUND_UP_FACTOR	7
+
+/* alignment sizes: always power of 2*/
+#define W_AL  2				   /* WORD alignment? */
+#define DW_AL (sizeof (DWORD))    /* DWORD alignment */
+#define QW_AL (2*sizeof (DWORD))  /* QWORD alignment */
+
+/* Align qty to forward(next) al-boundry.*/
+#define ALIGN_FW(qty,al)       (((int)(qty) + ((al)-1)) & ~((al)-1))
+
+/*******************************************************************************
+ * DMA Chain elements joining.
+ */
+
+/* Joins two dma chains. */
+typedef struct _DMA_Chain_joint
+{
+	volatile BYTE* pNext; /* Pointer to next contiguous location */
+	volatile ULONG cNext; /* # of QWORDS in next contiguous location */
+} JOINT;
+
+#define JOINT_SIZ	sizeof(JOINT)
+
+/*******************************************************************************
+ * Descriptors: definitions & defines.
+ *
+ * Note:
+ * 1 The order in which the fields are listed is important.
+ * 2 Both descriptors have status, a 64 bit qword, represented as two ULONGs.
+ *   The order in which the two ULONGs are listed in the structure definition, 
+ *   depends on the endianism: in our case little endian.
+ */
+
+/* Transmit Descriptor - hardware defined. */
+typedef struct _emac_txd
+{
+    volatile ULONG   status;         /* status - see TSTAT_XXX in emac_desc.h                    */
+    volatile ULONG   status_zero;    /* zeroes                                                   */
+    volatile ULONG   control;        /* TDES -see TCTRL_XXX in emac_desc.h (incl. len in bytes)  */
+} EMAC_TXD;
+
+#define EMAC_TXD_SIZE	sizeof( EMAC_TXD )
+
+/* Transmit Message Descriptor Entry. */
+typedef struct tDesc
+{
+    volatile ULONG	status;	     /* status				*/
+    volatile ULONG	status_zero; /* zeroes				*/
+    volatile ULONG	control;     /* control parameters	*/
+    ULONG   data;        		/* first ulong in the cluster */
+    JOINT   joint;
+} EMAC_TD;
+
+#define TD_SIZ	        ( sizeof(EMAC_TD)/ SIZEOF_QWORD ) /* 3 qwords */
+#define TD_DMA_SIZ	    (( TD_SIZ - JOINT_SIZ ) / SIZEOF_QWORD )
+
+
+typedef struct
+{
+	BYTE			*tx_pkt_data;
+	unsigned int	tx_pkt_len;
+	TX_PKT_TYPE		pkt_type;
+
+} TX_PKT_INFO;
+
+/*
+ * Tx Msg Queue 
+ */
+
+typedef struct tx_msg_queue
+{
+	char *      Data;
+    ULONG		ulControl;
+	ULONG		ulLength;
+
+} TX_MSG_QUEUE;
+
+/*********************************************************************
+	This is a hardware structure found in the CX82100
+	Design Specification. 
+*********************************************************************/
+typedef struct 
+{
+	volatile unsigned char*	mData;
+    volatile unsigned long	reserved;
+    volatile unsigned long	status;
+    volatile unsigned long	mib;
+
+}EMAC_RXD;
+
+
+/*********************************************************************
+	This structure contains the main Q information for tracking the 
+    hardware packet information and which clusters are to be
+    transferred to the MUX.  The ordering of the elements is 
+    important because the DMA channel is expecting the first
+    Q element of the EMAC_RXD to be qword aligned!
+*********************************************************************/
+typedef struct
+{
+	EMAC_RXD        q[RXD_NUM];				/* pointer to the beginning of the descriptor list */
+	struct sk_buff*	skb[RXD_NUM];
+	unsigned long   qndx;   				/* index to next available element when queue size is non-zero  */
+
+} EMAC_RXD_HW_QTYPE;
+
+typedef struct EMAC_drv_ctrl
+{
+	BYTE			*txd_buf_mem;			// Pointer to the original non-qword aligned
+											// memory block obtained from kmalloc
+
+	BYTE			*txd_buf[TX_RING_SIZE];	// Array of pointers to ethernet sized blocks
+											// of memory from the memory pointed to by
+											// txd_buf_mem
+	TX_MSG_QUEUE   	tx_msg_q [TX_RING_SIZE];
+	DATA_QUEUE_T	*emac_tx_q;
+
+   	EMAC_TD*		TxD_end;
+
+	UINT32   		tx_msg_q_next;   /* index to next available element when queue is not full */
+	UINT32   		tx_msg_q_current;  /* current transmitting TxD                               */
+	UINT32   		tx_msg_q_size;    /* if size is zero, then queue is empty                   */
+	BOOLEAN			tx_pkt_in_progress;
+	BOOLEAN			tx_mutex_part;
+	BOOLEAN			hw_reset_required;
+	EVENT_HNDL		*hw_reset_event;
+
+	BYTE			setup_frame_buf[256];
+
+	/* Tx control lock.  This protects the transmit buffer ring
+	 * state along with the "tx full" state of the driver.  This
+	 * means all netif_queue flow control actions are protected
+	 * by this lock as well.
+	 */
+	spinlock_t		lock;
+
+	struct net_device_stats	stats;
+	struct net_device_stats	prev_stats;
+
+	// Receiver hardware queue
+	EMAC_RXD_HW_QTYPE	*rxd_hw;
+	BYTE				*rxd_buf;
+	DATA_QUEUE_T		EMAC_rx_buf_q;
+
+	struct timer_list	wd_timer;
+	struct timer_list	periodic_task;
+
+   	/* Multicast Address Table is array */
+    int         multiCount;                     /* Number of multicast address in Table */
+    MAC_ADDR    multiTable[MULTI_TABLE_SIZE];   /* Multicast address table */
+    UINT8       hashTable[HASH_TABLE_SIZE];     /* Multicast hash table */
+
+    int			flags;               /* driver flags					*/
+
+	BOOLEAN		emac_dev_q_state;	// TRUE = STARTED,  FALSE = STOPPED
+	BOOLEAN		emac_state;			// TRUE = OPEN,  FALSE = CLOSED
+	DWORD		emac_num;			// emac_num = unit + 1 -> emac1 = eth0 and emac2 = eth1
+	DWORD		emac_hdw_num;		// emac_hdw_num = 0 -> emac1 and 1 -> emac2
+    int			unit;                /* unit number	*/
+
+	UINT8		PortNetAddress[MAC_ADDR_LEN];
+	   
+	volatile unsigned int	E_NA_settings;
+	volatile unsigned int	E_IE_settings;
+
+	int						tx_dma_int;
+	int						rx_dma_int;
+
+	volatile unsigned long	int_stat_clr_dev_irq;
+	volatile unsigned long	int_stat_clr_tx;
+	volatile unsigned long	int_stat_clr_rx;
+
+	volatile unsigned long*	emac_tx_dma_ptr;
+	volatile unsigned long*	emac_tx_dma_ptrx;
+	volatile unsigned long* emac_rx_dma_ptr2;
+	volatile unsigned long* emac_tx_dma_cnt;
+	volatile unsigned long* emac_rx_dma_cnt1;
+	volatile unsigned long* emac_rx_dma_cnt2;
+	volatile unsigned long* emac_na_reg;
+	volatile unsigned long* emac_stat_reg;
+	volatile unsigned long* emac_lp_reg;
+	volatile unsigned long* emac_ie_reg;
+
+	ULONG	MacFilteringMode;
+
+#ifdef INC_PHY
+
+/*
+ *  Physical Layer Driver struct-type.
+ */
+
+    PHY_SETTING     phyState;
+	
+/* # of Phys connected to the MAC via the MII bus.*/
+#ifndef MAX_SUPPORTED_PHYS
+#define MAX_SUPPORTED_PHYS	2 /* Must be < 31 */
+#endif
+
+    PHY		*pPhy;
+#endif /* INC_PHY */
+	void	*pHpna ;	//PHPNALLOBJ pHpna ;
+
+#if HOMEPLUGPHY
+	struct net_device *dev;
+		
+	#ifdef HOMEPLUG_PHYMAC_OVERFLOW_WORKAROUND
+	struct semaphore	tx_delay_sem_id;
+	int		Current_packet_Collision_cnt ;
+	#endif
+#endif
+
+
+} EMAC_DRV_CTRL;
+
+#define DRV_CTRL_SIZ	sizeof(DRV_CTRL)
+#define	DRV_CTRL	EMAC_DRV_CTRL
+
+/*******************************************************************************
+ * EMAC specific ethernet frame size & cluster size requirements.
+ */
+
+#define MIN_ETHERNET_SIZE 18        /* used in end send */
+#define MAX_ETHERNET_SIZE 1518
+#define ETHERNET_CRC_SIZE	  4
+#define CL_SIZ             2048
+
+#define	NET_SPEED_DEF	NET_SPEED_10
+
+
+/*
+ * END specific defines
+ */
+
+#define END_FLAGS_ISSET(pEnd, setBits)                                  \
+        ((pEnd)->flags & (setBits))
+
+#define END_HADDR(pEnd)                                                 \
+		((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)
+
+#define END_HADDR_LEN(pEnd)                                             \
+		((pEnd)->mib2Tbl.ifPhysAddress.addrLength)
+
+#define	END_MIB_SPEED_SET(pEndObj, speed)                               \
+	    ((pEndObj)->mib2Tbl.ifSpeed=speed)
+
+
+/*
+ * DRV_CTRL flags & access macros 
+ */
+
+#define DRV_MEMOWN		0x0001	/* TDs and RDs allocated by driver	*/
+#define EMAC_POLLING	0x0004	/* Poll mode, io mode				*/
+#define FLT_PROMISC		0x0008	/* Promiscuous, rx mode				*/
+#define FLT_MCAST		0x0010	/* Multicast, rx mode				*/
+
+#define DRV_FLAGS_SET(setBits)                                          \
+	    (pDrvCtrl->flags |= (setBits))
+
+#define DRV_FLAGS_ISSET(setBits)                                        \
+	    (pDrvCtrl->flags & (setBits))
+
+#define DRV_FLAGS_CLR(clrBits)                                          \
+	    (pDrvCtrl->flags &= ~(clrBits))
+
+#define DRV_FLAGS_GET()                                                 \
+        (pDrvCtrl->flags)
+
+        
+/* 
+ * Network Access 
+ */
+
+#define E_NA_RTX	((ULONG)((ULONG)1<<31)) /* Tx Software Reset	        [31]        */
+#define E_NA_STOP	((ULONG)((ULONG)1<<30)) /* Stop transmit		        [30]        */
+#define E_NA_HP		((ULONG)((ULONG)1<<27)) /* Hash/perfect addr filter     [27]        */
+#define E_NA_HO		((ULONG)((ULONG)1<<26)) /* Hash only			        [26]        */
+#define E_NA_IF		((ULONG)((ULONG)1<<25)) /* Inverse Filter		        [25]        */
+#define E_NA_PR		((ULONG)((ULONG)1<<24)) /* Promiscuous mode	            [24]        */
+#define E_NA_PM     ((ULONG)((ULONG)1<<23)) /* Pass all Multicast           [23]        */
+#define E_NA_PB		((ULONG)((ULONG)1<<22)) /* Pass bad packet	            [22]        */
+#define E_NA_RRX	((ULONG)((ULONG)1<<21)) /* Rx s/w reset		            [21]        */
+#define E_NA_THU	((ULONG)((ULONG)1<<20)) /* Tx test HUJ counter          [20]        */
+#define E_NA_DIS	((ULONG)((ULONG)1<<19)) /* Tx Disable backoff counter   [19]        */
+#define E_NA_RUT	((ULONG)((ULONG)1<<18)) /* Tx reset unit timer          [18]        */
+#define E_NA_IFG	((ULONG)((ULONG)3<<16)) /* Inter-frame gap	            [17:16]		*/
+#define E_NA_JBD	((ULONG)((ULONG)1<<15)) /* Jabber disable		        [15]        */
+#define E_NA_HUJ	((ULONG)((ULONG)1<<14)) /* Host Un-Jabber		        [14]        */
+#define E_NA_JCLK	((ULONG)((ULONG)1<<13)) /* Jabber clock		            [13]        */
+#define E_NA_SB		((ULONG)((ULONG)1<<12)) /* Start/Stop Backoff Counter   [12]        */
+#define E_NA_FD		((ULONG)((ULONG)1<<11)) /* Full duplex		            [11]        */
+#define E_NA_OM 	((ULONG)((ULONG)3<<9 )) /* Operating mode               [10:9]	   	*/
+#define E_NA_OM_R	((ULONG)((ULONG)3<<9 )) /* Operating mode: Reserved	    [10:9]	-GL	*/
+#define E_NA_OM_E   ((ULONG)((ULONG)2<<9 )) /* Operating mode: External LB	[10:9]  -GL	*/ 
+#define E_NA_OM_I   ((ULONG)((ULONG)1<<9 )) /* Operating mode: Internal LB	[10:9]	-GL	*/
+#define E_NA_FC		((ULONG)((ULONG)1<<8 )) /* Force Collisions	            [8]         */
+#define E_NA_HLAN	((ULONG)((ULONG)1<<7 )) /* Home LAN Enablee	            [7] 	    */
+#define E_NA_SR		((ULONG)((ULONG)1<<6 )) /* Start/Stop receive	        [6] 	    */
+#define E_NA_NS		((ULONG)((ULONG)1<<5 )) /* Network speed		        [5] 	    */
+#define E_NA_RWR	((ULONG)((ULONG)1<<4 )) /* Receive WD release	        [4]			*/
+#define E_NA_RWD	((ULONG)((ULONG)1<<3 )) /* Receive WD disable	        [3] 	    */
+#define E_NA_STRT	((ULONG)((ULONG)1    )) /* Start transmit		        [0] 	    */
+
+#define E_NA_FILTER_MODE        ( E_NA_PM | E_NA_PR | E_NA_IF | E_NA_HO | E_NA_HP )
+#define E_NA_FILTER_PROMIS      ( E_NA_PM | E_NA_PR )
+#define E_NA_FILTER_MC1PERFECT  ( E_NA_PM | E_NA_HP )
+#define E_NA_FILTER_INVERSE	    ( E_NA_IF )
+
+/*
+ * END Specific interfaces. 
+ */
+
+#define INT_DMA_EMAC_1_TX   ((unsigned long)1<<15)
+#define INT_DMA_EMAC_1_RX   ((unsigned long)1<<14)
+#define INT_DMA_EMAC_2_TX   ((unsigned long)1<<13)
+#define INT_DMA_EMAC_2_RX   ((unsigned long)1<<12)
+
+/**********************************************************/    
+/* Global shadow register for the E_NA register           */
+/**********************************************************/    
+
+
+#define E_S_TU    ((unsigned long)1<<31)
+#define E_S_RO    ((unsigned long)1<<26)
+#define E_S_RWT   ((unsigned long)1<<25)
+#define E_S_TOF   ((unsigned long)1<<16)
+#define E_S_TUF   ((unsigned long)1<<15)
+#define E_S_ED    ((unsigned long)1<<14)
+#define E_S_DF    ((unsigned long)1<<13)
+#define E_S_CD    ((unsigned long)1<<12)
+#define E_S_ES    ((unsigned long)1<<11)
+#define E_S_RLD   ((unsigned long)1<<10)
+#define E_S_TF    ((unsigned long)1<<9)
+#define E_S_TJT   ((unsigned long)1<<8)
+#define E_S_NCRS  ((unsigned long)1<<7)
+#define E_S_LCRS  ((unsigned long)1<<6)
+#define E_S_16    ((unsigned long)1<<5)
+#define E_S_LC    ((unsigned long)1<<4)
+#define E_S_CC    ((unsigned long)0xf<<0)
+
+#define BF_CRC 	   0x0ff00000
+#define BF_ALN     0x000f0000
+#define BF_LONG    0x0000f000
+#define BF_RUNT    0x00000ff0 
+#define BF_OFLW    0x0000000f
+#define BF_MASK    (BF_CRC+BF_ALN+BF_LONG+BF_RUNT+BF_OFLW)
+
+#define GF_TS      0x00000800
+#define GF_MF      0x00000400
+#define GF_TL      0x00000080
+#define GF_LC      0x00000040
+#define GF_OFT     0x00000020
+#define GF_RW      0x00000010
+#define GF_DB      0x00000004
+#define GF_CE      0x00000002
+#define GF_OF      0x00000001
+#define GF_MASK    (GF_TS+GF_MF+GF_TL+GF_LC+GF_OFT+GF_RW+GF_DB+GF_CE+GF_OF)
+#define RX_ES		0x00008000
+#define RX_A1		0x00000008
+
+
+#if HOMEPLUGPHY
+typedef	struct sk_buff ADDR_TBL ;
+
+#define Packet_Buffer_Virtual_Adr( _pBuffer )	((ADDR_TBL *)(_pBuffer))->data
+ADDR_TBL * Get_Free_Tx_Buffer( EMAC_DRV_CTRL *MACAdapter );
+
+void MAC_Assign_MacAddress( EMAC_DRV_CTRL *MACAdapter, BYTE *S_Addr );
+void MAC_Send_A_Frame( EMAC_DRV_CTRL *MACAdapter, DWORD PacketSize, ADDR_TBL *PtrTxBuffer, BOOLEAN Control_Frame );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __EMAC_END_H */
diff -urN linux-2.4.29/drivers/net/cnxt_emac/cnxtEmac_hw.h linux-2.4.29-uc1/drivers/net/cnxt_emac/cnxtEmac_hw.h
--- linux-2.4.29/drivers/net/cnxt_emac/cnxtEmac_hw.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/cnxtEmac_hw.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,89 @@
+/****************************************************************************
+*
+*	Name:			cnxtEmac_hw.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2001,2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+*
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __CNXT_EMAC_HW_H
+#define __CNXT_EMAC_HW_H
+
+/*******************************************************************************
+ *
+ * This file simply INCLUDES files. 
+ * Each included file:
+ * 1) corresponds to a sub-device of the CX821xx device. 
+ * 2) It defines registers, bit masks & reg-access macros for that sub-device.
+ *
+ */
+
+/*******************************************************************************
+ * Emac: Reg base addr & Reg offset.
+ * The reg offset is same for all the sub-devices (like DMAC, EMAC & 
+ * Interrupt controller).
+ */
+
+
+#ifndef REG_BASE_ADDR
+#define REG_BASE_ADDR	 ((BYTE*)(0x00300000)) /* double word aligned */
+#endif
+
+#ifndef BE_OFST
+#define BE_OFST		 0   /* 0 for little endian, 7 for big  */
+#endif
+
+#ifndef REG_OFFSET
+#define REG_OFFSET	 (BE_OFST + 0x04) /* double word aligned */
+#endif
+
+
+/*
+ * Reg Access Macros, using Register-ADDRESS ( and not the reg number)
+ */
+
+#ifndef REG_WRITE
+#define REG_WRITE(regAddr,val)  ( (*(volatile ULONG*)(regAddr)) = (val) )
+#endif /* REG_WRITE */
+
+/*******************************************************************************
+ * Emac sub-devices: registers, bitmasks & reg access macros.
+ */
+
+
+/* M2M registers & access-macros*/
+#include "m2m_regs.h"
+
+/* Interrupt controller registers (eg int msk, intr stat) & access-macros */
+#include "intr_regs.h"
+
+/* EMAC registers & access-macros */
+#include "emac_regs.h"
+
+/* EMAC descriptors, status & access-macros */
+#include "emac_desc.h"
+
+
+#endif /* __CNXT_EMAC_HW_H */
diff -urN linux-2.4.29/drivers/net/cnxt_emac/dma_regs.h linux-2.4.29-uc1/drivers/net/cnxt_emac/dma_regs.h
--- linux-2.4.29/drivers/net/cnxt_emac/dma_regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/dma_regs.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,211 @@
+/****************************************************************************
+*
+*	Name:			dma_regs.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*					Personal Computing Division
+*					All Rights Reserved
+*
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __DMA_REGS_H
+#define __DMA_REGS_H
+
+
+/*******************************************************************************
+ * CX821xx: Reg base addr & Reg offset.
+ * The reg offset is same for all the sub-devices (like DMAC, EMAC & 
+ * Interrupt controller).
+ */
+
+
+#ifndef REG_BASE_ADDR
+#define REG_BASE_ADDR	 ((BYTE*)(0x00300000)) /*  */
+#endif
+
+#ifndef BE_OFST
+#define BE_OFST		 0   /* 0 for little endian, 7 for big  */
+#endif
+
+#ifndef REG_OFFSET
+#define REG_OFFSET	 (BE_OFST + 0x04) /* double word aligned */
+#endif
+
+/*******************************************************************************
+ *
+ * Define DMAC REGs and macros to access them.
+ * To optimize REG accesses, redefine DMA_*_REG_READ and
+ * DMA_*_REG_WRITE macros in a wrapper file.
+ */
+
+/*
+ * Current pointers ( DMA{x}_Ptr1 )
+ */
+
+#define DMA_PTR1_BASE_ADDR	    REG_BASE_ADDR
+#define DMA_PTR1_REG_OFFSET	    REG_OFFSET	
+
+/* Reg numbering w.r.t base */
+
+#define DMA1_PTR1	0
+#define DMA2_PTR1	1
+#define DMA3_PTR1	2 /* EMAC Tx channel */
+#define DMA4_PTR1	3 /* EMAC Rx channel */
+#define DMA5_PTR1	4
+#define DMA6_PTR1	5
+#define DMA7_PTR1	6
+#define DMA8_PTR1	7
+#define DMA9_PTR1	8
+#define DMA10_PTR1	9
+
+/* Reg access macros */
+
+#define DMA_PTR1_REG_ADDR(regNum)   (DMA_PTR1_BASE_ADDR + \
+                                     (regNum) * DMA_PTR1_REG_OFFSET)
+
+#ifndef DMA_PTR1_REG_READ
+#define DMA_PTR1_REG_READ(regNum)   (*((volatile ULONG*)DMA_PTR1_REG_ADDR((regNum))))
+#endif /* DMA_PTR1_REG_READ */
+
+#ifndef DMA_PTR1_REG_WRITE
+#define DMA_PTR1_REG_WRITE(regNum,val)  (*((volatile ULONG*)DMA_PTR1_REG_ADDR((regNum))) = (val))
+#endif /* DMA_PTR1_REG_WRITE */
+
+
+#define DMA4_PTR1_BASE_ADDR	   	0x30000c 
+#define DMA4_PTR1_REG_ADDR(regNum)   ((volatile ULONG *)(DMA4_PTR1_BASE_ADDR + \
+                                    ((regNum) * (DMA_PTR1_REG_OFFSET))))
+
+#undef DMA4_PTR1_REG_WRITE
+#define DMA4_PTR1_REG_WRITE(regNum,val) \
+	 (*(DMA4_PTR1_REG_ADDR(regNum)) = (val))
+
+
+
+#ifndef DMA_PTR1_REG_UPDATE
+#define DMA_PTR1_REG_UPDATE(regNum,val) DMA_PTR1_REG_WRITE((regNum), \
+                                        DMA_PTR1_REG_READ((regNum)) | (val))
+#endif /* DMA_PTR1_REG_UPDATE */
+    
+#ifndef DMA_PTR1_REG_RESET
+#define DMA_PTR1_REG_RESET(regNum,val)  DMA_PTR1_REG_WRITE((regNum), \
+                                        DMA_PTR1_REG_READ((regNum)) & ~(val))
+#endif /* DMA_PTR1_REG_RESET */
+
+/*
+ * Indirect/Return pointers ( DMA{x}_Ptr2 ). 
+ */
+
+#define DMA_PTR2_BASE_ADDR	((BYTE*)0x00300030) /* Base Address */
+#define DMA_PTR2_REG_OFFSET	    REG_OFFSET	
+
+/* Reg numbering w.r.t base */
+
+#define DMA1_PTR2	0
+#define DMA2_PTR2	1
+#define DMA3_PTR2	2 /* EMAC Tx channel */
+#define DMA4_PTR2	3 /* EMAC Rx channel */
+#define DMA5_PTR2	4
+#define DMA6_PTR2	5
+#define DMA7_PTR2	6
+#define DMA8_PTR2	7
+#define DMA9_PTR2	8
+#define DMA10_PTR2	9
+
+/* Reg access macros */
+
+#define DMA_PTR2_REG_ADDR(regNum)   (DMA_PTR2_BASE_ADDR + \
+                                     (regNum) * DMA_PTR2_REG_OFFSET)
+
+#ifndef DMA_PTR2_REG_READ
+#define DMA_PTR2_REG_READ(regNum)       (*((volatile ULONG*)DMA_PTR2_REG_ADDR((regNum))))
+#endif /* DMA_PTR2_REG_READ */
+
+#ifndef DMA_PTR2_REG_WRITE
+#define DMA_PTR2_REG_WRITE(regNum,val)  (*((volatile ULONG*)DMA_PTR2_REG_ADDR((regNum))) = (val))
+#endif /* DMA_PTR2_REG_WRITE */
+
+#ifndef DMA_PTR2_REG_UPDATE
+#define DMA_PTR2_REG_UPDATE(regNum,val) DMA_PTR2_REG_WRITE((regNum), \
+                                        DMA_PTR2_REG_READ((regNum)) | (val))
+#endif /* DMA_PTR2_REG_UPDATE */
+    
+#ifndef DMA_PTR2_REG_RESET
+#define DMA_PTR2_REG_RESET(regNum,val)  DMA_PTR2_REG_WRITE((regNum), \
+                                        DMA_PTR2_REG_READ((regNum)) & ~(val))
+#endif /* DMA_PTR2_REG_RESET */
+
+/*
+ * Buffer size/Pointer mode ( DMA{x}_Cnt1 )
+ */
+
+#define DMA_CNT1_BASE_ADDR	((BYTE*)0x00300040) /* Base Address */
+#define DMA_CNT1_REG_OFFSET	REG_OFFSET	
+
+/* Reg numbering w.r.t base */
+
+#define DMA1_CNT1	0
+#define DMA2_CNT1	1
+#define DMA3_CNT1	2 /* EMAC Tx channel */
+#define DMA4_CNT1	3 /* EMAC Rx channel */
+
+/* Reg access macros */
+
+#define DMA_CNT1_REG_ADDR(regNum)   (DMA_CNT1_BASE_ADDR + \
+                                     (regNum) * DMA_CNT1_REG_OFFSET)
+
+#ifndef DMA_CNT1_REG_READ
+#define DMA_CNT1_REG_READ(regNum)       (*((volatile ULONG*)DMA_CNT1_REG_ADDR((regNum))))
+#endif /* DMA_CNT1_REG_READ */
+
+#ifndef DMA_CNT1_REG_WRITE
+#define DMA_CNT1_REG_WRITE(regNum,val)  (*((volatile ULONG*)DMA_CNT1_REG_ADDR((regNum))) = (val))
+#endif /* DMA_CNT1_REG_WRITE */
+
+#ifndef DMA_CNT1_REG_UPDATE
+#define DMA_CNT1_REG_UPDATE(regNum,val) DMA_CNT1_REG_WRITE((regNum), \
+                                        DMA_CNT1_REG_READ((regNum)) | (val))
+#endif /* DMA_CNT1_REG_UPDATE */
+    
+#ifndef DMA_CNT1_REG_RESET
+#define DMA_CNT1_REG_RESET(regNum,val)  DMA_CNT1_REG_WRITE((regNum), \
+                                        DMA_CNT1_REG_READ((regNum)) & ~(val))
+#endif /* DMA_CNT1_REG_RESET */
+
+
+
+/* 
+ * DMA addr & count reg macros
+ */
+
+/* Get dma addr from physical addr */
+#define DMA_ADDR_MASK ((ULONG)0x00ffffff)   /* [23:0] bit dma addr */
+#define DMA_ADDR(addr)\
+        (DMA_ADDR_MASK & (addr))
+
+/* Get dma cnt from byte cnt */
+#if     (MAC_HW_VER < REV_C)
+/* AD use for RevA or higher */
+#define DMA_CNT_MASK    ((ULONG)0x000007ff) /* [10:0] bit dma cnt */
+#else
+/* AD use for RevC and higher */
+#define DMA_CNT_MASK    ((ULONG)0x00001fff) /* [12:0] bit dma cnt */ 
+#endif
+
+/* Specify linked list modes used by dma */
+#define DMA_LMODE_MASK  ((ULONG)0x03000000) /* [25:24] bit dma link list mode */
+#define DMA_LMODE_TAIL  ((ULONG)0x00000000) /* ptr/cnt at buf-tail */
+#define DMA_LMODE_TBL   ((ULONG)0x01000000) /* ptr/cnt at Ptr2(table) */
+#define DMA_LMODE_RETN  ((ULONG)0x02000000) /* ptr/cnt at Ptr2(return ptr) */
+
+/* Form dma cnt reg from LMode & count - qwords - */
+#define DMA_CNT(lmode,cnt)\
+        ((DMA_LMODE_MASK & (lmode)) | (DMA_CNT_MASK & (cnt)))
+
+#endif /* __DMA_REGS_H */
diff -urN linux-2.4.29/drivers/net/cnxt_emac/emac_desc.h linux-2.4.29-uc1/drivers/net/cnxt_emac/emac_desc.h
--- linux-2.4.29/drivers/net/cnxt_emac/emac_desc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/emac_desc.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,207 @@
+/****************************************************************************
+*
+*	Name:			emac_desc.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 1999-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+*
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef _EMAC_DESC_H
+#define _EMAC_DESC_H
+
+
+
+/* 
+ * receive descriptor 
+ */
+
+
+/* 
+ * Recieve status (RSTAT) - QWORD 
+ */
+
+#define RSTAT_FL	((ULONG)(0xffff0000)) /* Frame len including CRC.
+													 [31-16]			*/
+#define RSTAT_ES	((ULONG)(0x00008000)) /* Error Summary.			 
+													 [15]				*/
+/* The following Receive status defines are unused */
+#define RSTAT_OM	((ULONG)(0x00003000)) /* Operating mode.		 
+													 [13-12]			*/
+#define RSTAT_TS	((ULONG)(0x00000800)) /* Too short=1, Pkt<64 bytes.
+													 [11]				*/
+#define RSTAT_MF	((ULONG)(0x00000400)) /* Multicast frame=1.		 
+													 [10]				*/
+#define RSTAT_TL	((ULONG)(0x00000080)) /* Too long=1, Packet>1518.
+													 [7]				*/
+#define RSTAT_LC	((ULONG)(0x00000040)) /* Late collision=1.		 
+													 [6]				*/
+#define RSTAT_OFT	((ULONG)(0x00000020)) /* Frame type.			 
+													 [5]				*/
+#define RSTAT_RW	((ULONG)(0x00000010)) /* Receive watchdog=1.	 
+													 [4]				*/
+#define RSTAT_DB	((ULONG)(0x00000004)) /* Dribble bit=1.			 
+													 [2]				*/
+#define RSTAT_CE	((ULONG)(0x00000002)) /* CRC error.				 
+													 [1]				*/
+#define RSTAT_OF	((ULONG)(0x00000001)) /* RMAC Fifo overflow=1.	 
+													 [0]				*/
+/* 
+ * receive descriptor describing control information
+ */
+
+/* Ownership bit of the descriptor indicates:
+ * if reset: the packet received not yet processed.
+ * if set  : The pkt processed and now the desc is available.
+ *
+ * Note: The "processing" here is done by a function runing in tNetTask
+ * context. The netJobAdd adds the addr of this func in the tNetTask-queue.
+ * After processing a packet, the func sets it.
+ */
+#define RCTRL_OWN		0x80000000	
+#define RCTRL_RER		0x02000000	/* recv end of ring */
+
+
+/*
+ * Length of Received frame related defines.
+ */
+
+#define RX_FRM_LEN_MSK		RSTAT_FL	/* Frame length mask */
+#define RX_FRM_LEN_SHF		16			/* bit-shift required to obtain
+										   the Frame length  */
+#define RX_FRM_LEN_GET(x)	(((x) & RX_FRM_LEN_MSK) >> RX_FRM_LEN_SHF)
+#define RX_FRM_LEN_SET(x)	(((x) << RX_FRM_LEN_SHF) & RX_FRM_LEN_MSK)
+
+/*
+ * transmit descriptor 
+ */
+
+/*
+ * Transmit Descriptor describes control information.
+ */
+
+#define TCTRL_RDY		((ULONG)(0x00010000)) /* Frame ready to be transmitted
+												 when this bit is 1.
+												 [16]		*/
+#define TCTRL_TLEN		((ULONG)(0x0000fff0)) /* Transmit frame length in bytes.
+												 [15:4]		*/
+#define TCTRL_SET		((ULONG)(0x00000004)) /* Current frame is a setup frame
+												 when this bit is 1.
+												 [2]		*/
+#define TCTRL_DPD		((ULONG)(0x00000002)) /* Disable Tx padding	
+												 [1]		*/
+#define TCTRL_AC		((ULONG)(0x00000001)) /* Disable CRC append 
+												 [0]		*/
+
+#define TX_FRM_LEN_MSK		TCTRL_TLEN	/* Frame length mask */
+#define TX_FRM_LEN_SHF		4			/* bit-shift required to obtain
+										   the Frame length  */
+#define TX_FRM_LEN_SET(x)	(((x) << TX_FRM_LEN_SHF) & TX_FRM_LEN_MSK)
+
+/*
+ * Transmit Status (TSTAT) - QWORD 
+ */
+
+#define TSTAT_TDN		((ULONG)(0x80000000)) /* When set indicates transmit
+												 completed successfully
+												 (from the buffer manager)
+														[31]		*/
+#define TSTAT_TU		((ULONG)(0x40000000)) /* Transmit stopped 
+												 (descriptor not ready)
+														[30]		*/
+#define TSTAT_TOF		((ULONG)(0x00010000)) /* Transmit buffer manager
+												 FIFO Overflow when 1.
+														[16]		*/
+#define TSTAT_TUF		((ULONG)(0x00008000)) /* Transmit buffer manager
+												 FIFO underflow when 1.(MIB11)
+														[15]		*/
+#define TSTAT_ED		((ULONG)(0x00004000)) /* Excessive Tx deferral
+												 (Tx deffered longer then
+												  8192 x 400 ns.
+														[14]		*/
+#define TSTAT_DF		((ULONG)(0x00002000)) /* Frame has been defered
+												 atlease once (MIB8)
+														[13]		*/
+#define TSTAT_CD		((ULONG)(0x00001000)) /* Frame transmit completed
+												 successfully (from MII).
+														[12]		*/
+#define TSTAT_ES		((ULONG)(0x00000800)) /* Transmit Error Summary. 
+												 TF|C16|LC|NCRS|LCRS|TJT
+														[11]			*/
+#define TSTAT_RLD		((ULONG)(0x00000400)) /* Tx FIFO reload/abort during
+												 frame (includes collision)
+														[10]			*/
+#define TSTAT_TF		((ULONG)(0x00000200)) /* Tx fault (or unexpected 
+												 transmit data request during
+												 frame (from MII).
+														[9]			*/
+#define TSTAT_TJT		((ULONG)(0x00000100)) /* Transmit jabber timeout: set
+												 when the jabber timer expires.
+												 E_NA_HUJ must be configured 
+												 for this bit to function.
+														[8]			*/
+#define TSTAT_NCRS		((ULONG)(0x00000080)) /* No carrier (ECRS pin never 
+												 gone high) during the transmit
+												 of the frame.
+														[7]			*/
+#define TSTAT_LCRS		((ULONG)(0x00000040)) /* Carrier was lost (ECRS pin 
+												 gone low) at least once during
+												 the transmit of the frame. 
+												 (MIB18).
+														[6]			*/
+#define TSTAT_C16		((ULONG)(0x00000020)) /* 16 or more collisions have 
+												 occured during the frame 
+												 transmit.
+														[5]			*/
+#define TSTAT_LC		((ULONG)(0x00000010)) /* Late collision (after 64th 
+												 byte) has occured during the
+												 frame transmit (MIB16)
+														[4]			*/
+#define TSTAT_CC		((ULONG)(0x0000000F)) /* Transmit collision count of
+												 the frame. Resets after the
+												 frame is transmitted 
+												 successfully (MIB9). Increments
+												 with every collision of the 
+												 current frame.
+														[3:0]			*/
+
+
+#define TD_STAT_CC_MSK		TSTAT_CC
+#define	TD_STAT_CC_VAL(X)	(((X) & TD_STAT_CC_MSK) >> 3)    
+
+
+/* 
+ * This macro assumes that the status was 0 before Tx started for this TxD.
+ * This macro returns true if Tx was done successfully or unsuccessfully.
+ * Note in the current version, EMAC HW doesn't clear this bit.
+ */
+#ifdef HW_CLRS_TXD_RDY
+#define IS_TXD_OWNED_BY_HW(pTxD) ((pTxD)->control & (TCTRL_RDY))
+#else
+#define IS_TXD_OWNED_BY_HW(pTxD) ( ((pTxD)->status == 0) && \
+                                   ((pTxD)->control & (TCTRL_RDY)))
+#endif
+
+
+#endif  /* _EMAC_DESC_H */
diff -urN linux-2.4.29/drivers/net/cnxt_emac/emac_regs.h linux-2.4.29-uc1/drivers/net/cnxt_emac/emac_regs.h
--- linux-2.4.29/drivers/net/cnxt_emac/emac_regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/emac_regs.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,423 @@
+/****************************************************************************
+*
+*	Name:			emac_regs.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 1999-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+*
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __EMAC_REGS_H
+#define __EMAC_REGS_H
+
+
+/*******************************************************************************
+ * Reg base addr & Reg offset.
+ * The reg offset is same for all the sub-devices (like DMAC, EMAC & 
+ * Interrupt controller).
+ */
+
+
+#ifndef REG_BASE_ADDR
+#define REG_BASE_ADDR	 ((BYTE*)(0x00300000)) /* double word aligned */
+#endif
+
+#ifndef BE_OFST
+#define BE_OFST		 0   /* 0 for little endian, 7 for big  */
+#endif
+
+#ifndef REG_OFFSET
+#define REG_OFFSET	 (BE_OFST + 0x04) /* double word aligned */
+#endif
+
+/*******************************************************************************
+ *
+ * Define EMAC REGs and macros to access them.
+ * To optimize REG accesses, redefine EMAC_REG_READ and
+ * EMAC_REG_WRITE macros in a wrapper file.
+ */
+
+#define EMAC_BASE_ADDR      ((UCHAR *)0x00310000)
+
+#define EMAC_REG_OFFSET		(REG_OFFSET)	/* double word aligned */
+
+/* Reg numbering w.r.t base */
+
+#define E_DMA	0		/* EMAC TxD / Rx DMA port [63:0]. NOT USED BY DRIVER */
+#define E_NA	1		/* network access [32:0]*/
+#define E_STAT	2		/* status */
+#define E_IE	3		/* enable interrupts */
+#define E_LP	4		/* Receiver Last Packet. */
+#define E_MII	6		/* MII Management Interface */
+#define E_TDMA	8		/* TxD status DMA port. NOT USED BY DRIVER */
+
+/* Reg access macros */
+
+#define EMAC_REG_ADDR(regNum,unit)  (EMAC_BASE_ADDR + (unit * 0x00010000) \
+									+ ((regNum) * EMAC_REG_OFFSET))
+
+#define EMAC_INTR_BASE_ADDR      ((volatile ULONG*)0x0031000c)
+
+#define EMAC_INTR_REG_WRITE(val,unit)  (*(EMAC_INTR_BASE_ADDR + (unit * 0x00010000)) \
+											 = (val))
+
+#define E_INTR	0	
+#define EMAC_INTR_REG_ADDR(regNum)   ((ULONG *)(EMAC_INTR_BASE_ADDR + (unit * 0x00010000)\
+                                 + ((regNum) * EMAC_REG_OFFSET)))
+
+#ifndef EMAC_INTR_REG_READ
+#define EMAC_INTR_REG_READ(unit)       (*(EMAC_INTR_BASE_ADDR + (unit * 0x00010000)))
+#endif /* EMAC_REG_READ */
+
+#ifndef EMAC_REG_READ
+#define EMAC_REG_READ(regNum,unit)       (*((volatile ULONG*)EMAC_REG_ADDR((regNum),unit)))
+#endif /* EMAC_REG_READ */
+
+#ifndef EMAC_REG_WRITE
+#define EMAC_REG_WRITE(regNum,val,unit)  (*((volatile ULONG*)EMAC_REG_ADDR((regNum),unit)) = (val))
+#endif /* EMAC_REG_WRITE */
+
+#ifndef EMAC_REG_UPDATE
+#define EMAC_REG_UPDATE(regNum,val,unit)  EMAC_REG_WRITE((regNum), \
+                                     EMAC_REG_READ((regNum),unit) | (val), unit)
+#endif /* EMAC_REG_UPDATE */
+    
+#ifndef EMAC_REG_RESET
+#define EMAC_REG_RESET(regNum,val,unit)   EMAC_REG_WRITE((regNum), \
+                                     EMAC_REG_READ((regNum),unit) & ~(val),unit)
+#endif /* EMAC_REG_RESET */
+    
+#ifndef EMAC_REG_RESET_SET
+#define EMAC_REG_RESET_SET(regNum,resetVal, setVal,unit)\
+            EMAC_REG_WRITE((regNum), \
+            (EMAC_REG_READ((regNum),unit) & ~(resetVal))|(setVal),unit)
+#endif /* EMAC_REG_RESET_SET */
+
+/*******************************************************************************
+ *
+ * Define EMAC bit masks.
+ */
+
+
+/*
+ * EMAC Register masks. 
+ */
+
+#define E_NA_MSK	((ULONG)(0xcffffff9)) /* [31:0]RW  */
+#define E_STAT_MSK	((ULONG)(0xffffffff)) /* [31:0]RW* */
+#define E_IE_MSK	((ULONG)(0x0001ffff)) /* [16:0]RW  */
+#define E_LP_MSK	((ULONG)(0x000003ff)) /* [9:0] RW  */
+#define E_MII_MSK	((ULONG)(0x0000001f)) /* [4:0]     */
+
+
+/* 
+ * EMAC Register bit masks.
+ */
+
+
+/* 
+ * Network Access 
+ */
+
+#define E_NA_RTX	((ULONG)((ULONG)1<<31)) /* Tx Software Reset	        [31]        */
+#define E_NA_STOP	((ULONG)((ULONG)1<<30)) /* Stop transmit		        [30]        */
+#define E_NA_HP		((ULONG)((ULONG)1<<27)) /* Hash/perfect addr filter     [27]        */
+#define E_NA_HO		((ULONG)((ULONG)1<<26)) /* Hash only			        [26]        */
+#define E_NA_IF		((ULONG)((ULONG)1<<25)) /* Inverse Filter		        [25]        */
+#define E_NA_PR		((ULONG)((ULONG)1<<24)) /* Promiscuous mode	            [24]        */
+#define E_NA_PM     ((ULONG)((ULONG)1<<23)) /* Pass all Multicast           [23]        */
+#define E_NA_PB		((ULONG)((ULONG)1<<22)) /* Pass bad packet	            [22]        */
+#define E_NA_RRX	((ULONG)((ULONG)1<<21)) /* Rx s/w reset		            [21]        */
+#define E_NA_THU	((ULONG)((ULONG)1<<20)) /* Tx test HUJ counter          [20]        */
+#define E_NA_DIS	((ULONG)((ULONG)1<<19)) /* Tx Disable backoff counter   [19]        */
+#define E_NA_RUT	((ULONG)((ULONG)1<<18)) /* Tx reset unit timer          [18]        */
+#define E_NA_IFG	((ULONG)((ULONG)3<<16)) /* Inter-frame gap	            [17:16]		*/
+#define E_NA_JBD	((ULONG)((ULONG)1<<15)) /* Jabber disable		        [15]        */
+#define E_NA_HUJ	((ULONG)((ULONG)1<<14)) /* Host Un-Jabber		        [14]        */
+#define E_NA_JCLK	((ULONG)((ULONG)1<<13)) /* Jabber clock		            [13]        */
+#define E_NA_SB		((ULONG)((ULONG)1<<12)) /* Start/Stop Backoff Counter   [12]        */
+#define E_NA_FD		((ULONG)((ULONG)1<<11)) /* Full duplex		            [11]        */
+#define E_NA_OM 	((ULONG)((ULONG)3<<9 )) /* Operating mode               [10:9]	   	*/
+#define E_NA_OM_R	((ULONG)((ULONG)3<<9 )) /* Operating mode: Reserved	    [10:9]	-GL	*/
+#define E_NA_OM_E   ((ULONG)((ULONG)2<<9 )) /* Operating mode: External LB	[10:9]  -GL	*/ 
+#define E_NA_OM_I   ((ULONG)((ULONG)1<<9 )) /* Operating mode: Internal LB	[10:9]	-GL	*/
+#define E_NA_FC		((ULONG)((ULONG)1<<8 )) /* Force Collisions	            [8]         */
+#define E_NA_HLAN	((ULONG)((ULONG)1<<7 )) /* Home LAN Enablee	            [7] 	    */
+#define E_NA_SR		((ULONG)((ULONG)1<<6 )) /* Start/Stop receive	        [6] 	    */
+#define E_NA_NS		((ULONG)((ULONG)1<<5 )) /* Network speed		        [5] 	    */
+#define E_NA_RWR	((ULONG)((ULONG)1<<4 )) /* Receive WD release	        [4]			*/
+#define E_NA_RWD	((ULONG)((ULONG)1<<3 )) /* Receive WD disable	        [3] 	    */
+#define E_NA_STRT	((ULONG)((ULONG)1    )) /* Start transmit		        [0] 	    */
+
+/* 
+ * Status 
+ */
+
+#define E_STAT_TU	((ULONG)(0x80000000)) /* Transmit descriptor not ready	
+                                             [31] */
+#define E_STAT_RS	((ULONG)(0x78000000)) /* Receive state					
+                                             [30:27] */
+#define E_STAT_RO	((ULONG)(0x04000000)) /* Receive FIFO overflow			
+                                             [26] */
+#define E_STAT_RWT	((ULONG)(0x02000000)) /* Receive WD timeout				
+                                             [25] */
+#define E_STAT_TDS	((ULONG)(0x01e00000)) /* Transmit buffer manager state	
+                                             [24:21] */
+#define E_STAT_TS	((ULONG)(0x001e0000)) /* Transmit state					
+                                             [20:17] */
+#define E_STAT_TOF	((ULONG)(0x00010000)) /* Transmit FIFO overflow			
+                                             [16] */
+#define E_STAT_TUF	((ULONG)(0x00008000)) /* Transmit FIFO underflow		
+                                             [15] */
+#define E_STAT_ED	((ULONG)(0x00004000)) /* Excessive Transmit deferrals	
+                                             [14] */
+#define E_STAT_DF	((ULONG)(0x00002000)) /* Tx frame differed				
+                                             [13] */
+#define E_STAT_CD	((ULONG)(0x00001000)) /* Frame transmit done from MII	
+                                             [12] */
+#define E_STAT_ES	((ULONG)(0x00000800)) /* Transmitter error summary		
+                                             [11] */
+#define E_STAT_RLD	((ULONG)(0x00000400)) /* Transmit FIFO reload/abort		
+                                             [10] */
+#define E_STAT_TF	((ULONG)(0x00000200)) /* Transmit fault					
+                                             [9] */
+#define E_STAT_TJT	((ULONG)(0x00000100)) /* Transmit Jabber Time-Out		
+                                             [8] */
+#define E_STAT_NCRS	((ULONG)(0x00000080)) /* No Carrier						
+                                             [7] */
+#define E_STAT_LCRS	((ULONG)(0x00000040)) /* Carrier was lost				
+                                             [6] */
+#define E_STAT_16	((ULONG)(0x00000020)) /* 16 or more collisions			
+                                             [5] */
+#define E_STAT_LC	((ULONG)(0x00000010)) /* Late collision					
+                                             [4] */
+#define E_STAT_CC	((ULONG)(0x0000000f)) /* Transmit collision count		
+                                             [3:0] */
+/* 
+ * Interrupt enable 
+ */
+
+#define E_IE_AU		((ULONG)(0x00020000)) /* Transmit FIFO almost underflow interrupt enable
+                                             [17] */
+#define E_IE_NI		((ULONG)(0x00010000)) /* Normal interrupt summary enable
+                                             [16] */
+#define E_IE_RW		((ULONG)(0x00008000)) /* Receive WD Timer				
+                                             [15] */
+#define E_IE_RI		((ULONG)(0x00004000)) /* Receive OK interrupt enable	
+                                             [14] */
+#define E_IE_AI		((ULONG)(0x00002000)) /* Abnormal interrupt summary 	
+                                             [13] */
+#define E_IE_LC		((ULONG)(0x00001000)) /* Late collision enable			
+                                             [12] */
+#define E_IE_16		((ULONG)(0x00000800)) /* 16 collisions interrupt enable	
+                                             [11] */
+#define E_IE_LCRS	((ULONG)(0x00000400)) /* Lost carrier interrupt enable	
+                                             [10] */
+#define E_IE_NCRS	((ULONG)(0x00000200)) /* No carrier interrupt enable	
+                                             [9] */
+#define E_IE_TF		((ULONG)(0x00000100)) /* Transmit fault enable			
+                                             [8] */
+#define E_IE_RLD	((ULONG)(0x00000080)) /* Transmit reload/abort enable	
+                                             [7] */
+#define E_IE_ED		((ULONG)(0x00000040)) /* Excessive deferral enable		
+                                             [6] */
+#define E_IE_DF		((ULONG)(0x00000020)) /* Transmit deferred enable		
+                                             [5] */
+#define E_IE_TOF	((ULONG)(0x00000010)) /* Transmit overflow enable		
+                                             [4] */
+#define E_IE_TUF	((ULONG)(0x00000008)) /* Transmit underflow enable		
+                                             [3] */
+#define E_IE_TJT	((ULONG)(0x00000004)) /* Transmit Jabber time-out enable
+                                             [2] */
+#define E_IE_TU		((ULONG)(0x00000002)) /* Transmit process stopped enable
+                                             [1] */
+#define E_IE_TI		((ULONG)(0x00000001)) /* Transmit OK interrupt			
+                                             [0] */
+
+/* 
+ * Reciever Last Packet 
+ */
+
+#define E_LP_RDMA	((ULONG)(0xf<<6)) 	/* [9:6] NOT USED by the driver */
+#define E_LP_RFIFO	((ULONG)(0xf<<2)) 	/* [5:2] NOT USED by the driver */
+#define E_LP_AU		((ULONG)(1<<10))    /* Rx Done OK from Rx buff-mgr[1] */
+#define E_LP_RI		((ULONG)(1<<1))     /* Rx Done OK from Rx buff-mgr[1] */
+#define E_LP_TI		((ULONG)(1<<0))     /* Tx Done OK from Tx buff-mgr[0] */
+
+/* 
+ * Media Independent Interface 
+ */
+
+#define E_MII_MDIP	((ULONG)(0x00000010))
+#define E_MII_MM	((ULONG)(0x00000008))
+#define E_MII_MDO	((ULONG)(0x00000004))
+#define E_MII_MDI	((ULONG)(0x00000002))
+#define E_MII_MDC	((ULONG)(0x00000001))
+
+/*
+ * Derived bit masks
+ */
+
+/* 
+ * When system error occurs, HW must be reset & driver should
+ * be restarted. Now the hw needs to be reset whenever 
+ * Tx/Rx under/over flow occurs.So these are also included in
+ * the system error.
+ *
+ * Note: 
+ * 1) Rx Overflow is sys err but there is no separate bit
+ * in the interrupt enable reg. It is absorbed in the abnormal
+ * interrupt summary bit.
+ * 2) Rx underflow is not captured in both status and intr-enable regs.
+ */
+#define E_SYS_ERR    (E_STAT_TOF|E_STAT_TUF|E_STAT_TF|E_STAT_RO)
+#define E_IE_SYS_ERR (E_IE_TOF  |E_IE_TUF  |E_IE_TF)
+
+#define IS_RX_STOPED 0x0 /* the Rx process is not stopped*/
+
+
+
+/******************************************************************************
+ * EMAC's Media Independent Interface (MII) register defines, bit masks &
+ * access macros.
+ */
+
+/*
+ * EMAC MII's Management Interface register & bit-masks.
+ */
+
+#define E_MMI_OFFSET       ((ULONG)0x18) /*offset from EMAC base addr. */
+
+/* 
+ * Active edge is the edge of the Clk - EMDC -. The sampling of the EMDIO
+ * is done, in input mode, using this edge 
+ */
+#define E_MDIP             ((ULONG)0x10) /* Active edge Mask.Bit[4].*/
+#define E_MDIP_RISING      ((ULONG)0x10) /* Active edge = rising edge  */
+#define E_MDIP_FALING      ((ULONG)0x00) /* Active edge = falling edge */
+#define E_MDIP_DEF         E_MDIP_FALING /* HW default active edge     */
+
+#define E_MM               ((ULONG)0x08) /* MDIO pin dire' mask.Bit[3] */
+#define E_MM_INPUT         ((ULONG)0x08) /* direction = input          */
+#define E_MM_OUTPUT        ((ULONG)0x00) /* direction = output         */
+#define E_MM_DEF           E_MM_INPUT    /* HW default direction       */
+
+#define E_MDO              ((ULONG)0x04) /* "Value to output" mask.Bit[2] */
+#define E_MDO_VAL1         ((ULONG)0x04) /* Value=1 to output.            */
+#define E_MDO_VAL0         ((ULONG)0x00) /* Value=0 to output.            */
+#define E_MDO_DEF          E_MDO_VAL0    /* HW default value to output.   */
+
+#define E_MDI              ((ULONG)0x02) /* "Value read" mask.Bit[1] */
+#define E_MDI_DEF          ((ULONG)0x02) /* HW default value read.   */
+
+
+#define E_MDC              ((ULONG)0x01) /* "Val to write to clk" mask.Bit[0]*/
+#define E_MDC_VAL1         ((ULONG)0x01) /* Val=1 to write to the clk, MDC   */
+#define E_MDC_VAL0         ((ULONG)0x00) /* Val=0 to write to the clk, MDC   */
+#define E_MDC_DEF          E_MDC_VAL0    /* HW default-value to write to clk.*/
+
+/*
+ * Map the bit masks as per "functional" interpretation.
+ * This mapping is used by the Phy driver.
+ * 
+ * PHY Modes:
+ * ----------
+ * Read : PHY is in read mode when it's reading data from the network cable.
+ * Write: PHY is in write mode when it's writing data to the network cable.
+ * 
+ * MAC Modes:
+ * ----------
+ * Output: MAC should output data to PHY after setting PHY in write mode.
+ * Input : MAC should input data from PHY after setting PHY in read mode.
+ *
+ * MAC & PHY Data Exchange:
+ * ------------------------
+ * 1. Data exchange between MAC & PHY is a bit (value = 0 or 1) at a time.
+ * 2. MAC controlls the PHY's mode.
+ * 3. MAC's modes are "exclusive" either input or output.
+ * 4. PHY's modes are "exclusive" either read or write.
+ */
+
+
+/* First undefined all if defined ... */
+
+#ifdef MAC_ADAPTER_ADDR
+#undef MAC_ADAPTER_ADDR
+#endif /* MAC_ADAPTER_ADDR */
+
+#ifdef MAC_MDIO_REG
+#undef MAC_MDIO_REG
+#endif /* MAC_MDIO_REG */
+
+#ifdef MDIO_CLK_MDIP
+#undef MDIO_CLK_MDIP
+#endif /* MDIO_CLK_MDIP */
+
+#ifdef MDIO_RD_ENABLE
+#undef MDIO_RD_ENABLE
+#endif /* MDIO_RD_ENABLE */
+
+#ifdef MDIO_WR_ENABLE
+#undef MDIO_WR_ENABLE
+#endif /* MDIO_WR_ENABLE */
+
+#ifdef MDIO_RD_DATA
+#undef MDIO_RD_DATA
+#endif /* MDIO_RD_DATA */
+
+#ifdef MDIO_WR_DATA_1
+#undef MDIO_WR_DATA_1
+#endif /* MDIO_WR_DATA_1 */
+
+#ifdef MDIO_WR_DATA_0
+#undef MDIO_WR_DATA_0
+#endif /* MDIO_WR_DATA_0 */
+
+#ifdef MDIO_CLK
+#undef MDIO_CLK
+#endif /* MDIO_CLK */           
+
+/* ... Now define them for Super Pipe */
+
+#define MAC_ADAPTER_ADDR  EMAC_BASE_ADDR
+#define MAC_MDIO_REG      E_MMI_OFFSET
+#define MDIO_CLK_MDIP     E_MDIP_DEF	
+#define MDIO_RD_ENABLE    (E_MM_INPUT | MDIO_CLK_MDIP) /* Set PHY in read mode.*/
+#define MDIO_WR_ENABLE    E_MM_OUTPUT /* Set PHY in write mode.*/
+#define MDIO_RD_DATA      E_MDI  /* Data read by MAC.*/
+#define MDIO_WR_DATA_1    E_MDO_VAL1  /* MAC writes 1. */
+#define MDIO_WR_DATA_0    E_MDO_VAL0  /* MAC writes 0. */
+#define MDIO_CLK          E_MDC_VAL1  /* MAC sends clock, MDC pulse.*/
+                          /* Why not E_MDC_VAL0? 
+                             While writting data to MII, the Phy driver
+                             either needs to send clk=0 or clk=1 ORed with
+                             the other flags - eg RD_ENABLE|CLK|.
+                             So clk=0 case is automatically taken care of
+                             if driver doesn't "OR" the flags with the CLK.
+                             eg. RD_ENABLE   - no "OR"ing with CLK.
+                           */
+
+
+
+#endif /* __EMAC_REGS_H */
diff -urN linux-2.4.29/drivers/net/cnxt_emac/emac_type.h linux-2.4.29-uc1/drivers/net/cnxt_emac/emac_type.h
--- linux-2.4.29/drivers/net/cnxt_emac/emac_type.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/emac_type.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,42 @@
+/****************************************************************************
+*
+*	Name:			emac_type.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2001,2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+*
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __EMAC_TYPE_H
+#define __EMAC_TYPE_H
+
+typedef unsigned char       UINT8;
+typedef unsigned short int  UINT16;
+typedef unsigned int        UINT32;
+
+typedef unsigned int	BOOL;
+typedef unsigned int	ULONG;
+typedef unsigned char	UCHAR;
+
+#endif /* __EMAC_TYPE_H */
diff -urN linux-2.4.29/drivers/net/cnxt_emac/filters.h linux-2.4.29-uc1/drivers/net/cnxt_emac/filters.h
--- linux-2.4.29/drivers/net/cnxt_emac/filters.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/filters.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,167 @@
+/****************************************************************************
+*
+*	Name:			filters.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 1999-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+*
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __FILTERS_H
+#define __FILTERS_H
+
+
+/* 
+ * Hashing & Address filtering.
+ */
+
+#include "hashIndex.h"
+
+/*
+ * Ethernet Address Filters supported by MAC HW...
+ */
+
+/* Basic filters */
+/* 16 */
+#define HW_FLT_16PER    0x0001/* 16 uni or multi perfect  */
+#define HW_FLT_16INV    0x0002/* 16 uni or multi inverse  */
+#define HW_FLT_16PER_PM 0x0004/* Pass all multi & 16 uni perfect */
+#define HW_FLT_16RES    0x0008/* reserved */
+
+/* hash */
+#define HW_FLT_1PER_HASH      0x0010/* 1 uni perfect & unlimited multi hash */
+#define HW_FLT_HASH           0x0020/* unlimited uni and/or multi hash */
+#define HW_FLT_1PER_PM        0x0040/* reserved */
+#define HW_FLT_HASH_RES2      0x0080/* reserved */
+
+/* others */
+#define HW_FLT_PM       0x0100/* Pass all multicast addrs */
+#define HW_FLT_PR       0x0200/* Promiscuous: all good pkts pass */
+#define HW_FLT_PB       0x0400/* Pass all bad pkts */
+
+/* Derived filters */
+#define HW_FLT_16ANY          (HW_FLT_16PER|HW_FLT_16INV|HW_FLT_16PER_PM|\
+                              HW_FLT_16RES)
+#define HW_FLT_HASHANY        (HW_FLT_1PER_HASH|HW_FLT_HASH|HW_FLT_1PER_PM|\
+                              HW_FLT_HASH_RES2)
+#define HW_FLT_OTHERANY       (HW_FLT_1PER_PM|HW_FLT_PM|HW_FLT_PR|\
+                              HW_FLT_PB)
+
+/* Default filter */
+#define HW_FLT_DEF            HW_FLT_16ANY/* our default */
+
+/* Default filter */
+#define HW_FLT                HW_FLT_DEF
+
+/* 
+ * Setup Frame Filtering Modes: 
+ *
+ * There are two ways of storing an ethernet address in the setup frame.
+ * 1) Directly: copying the addr, byte by byte.
+ * 2) hashing : set 1bit -per addr- of the hash table contained within setup frame.
+ *
+ * Hence, eventhough there are multiple modes available for address filtering, 
+ * as far as preparation of the setup frame goes there are only two. 
+ * 1) "Perfect": 16 addrs stored "directly".
+ * 2) "1Perfect-Hash": 1 addr stored directly & unlimited addrs stored using hashing.
+ */
+
+#define SF_FM_NONE       0x0/* No setup frame filter needed */
+#define SF_FM_PER        0x1/* 16 addrs perfect & no hash table*/
+#define SF_FM_1PER_HASH  0x2/* 1 addr perfect & a hash table */
+
+#ifdef SF_FM
+#undef SF_FM
+#endif /* SF_FM */
+
+#if (HW_FLT & HW_FLT_16ANY)
+#define SF_FM   SF_FM_PER
+#endif /* HW_FLT & HW_FLT_16ANY */
+
+#if (HW_FLT & HW_FLT_HASHANY)
+#ifdef SF_FM
+#error Setup frame filter can not support mixing of hash & 16* filters.
+#else
+#define SF_FM   SF_FM_1PER_HASH
+#endif /* SF_FM */
+#endif /* HW_FLT & HW_FLT_HASHANY */
+
+#if (HW_FLT & HW_FLT_OTHERANY)
+#ifndef SF_FM
+#define SF_FM       SF_FM_NONE
+#endif /* SF_FM */
+#endif /* HW_FLT & HW_FLT_OTHERANY */
+
+/*
+ *
+ */
+
+#if 0
+#define E_NA_HP		((ULONG)(0x08000000)) /* Hash/perfect addr filter [27]	*/
+#define E_NA_HO		((ULONG)(0x04000000)) /* Hash only			[26]		*/
+#define E_NA_IF		((ULONG)(0x02000000)) /* Inverse Filter		[25]		*/
+#define E_NA_PR		((ULONG)(0x01000000)) /* Promiscuous mode	[24]		*/
+#define E_NA_PM		((ULONG)(0x00800000)) /* Pass all Multicast [23]		*/
+#define E_NA_PB		((ULONG)(0x00400000)) /* Pass bad packet	[22]		*/
+
+#define E_NA_FM     (E_NA_IF|E_NA_PM)
+#endif
+
+#if 0
+typedef struct _FLT_FRM_EADDR_BYTE_INDEX
+{
+#if  (SF_FM==SF_FM_PER)
+int index;
+int indexOfst;
+
+#elif(SF_FM==SF_FM_1PER_HASH)
+HI hi;
+
+#elif(SF_FM==SF_FM_NONE)
+
+#else
+#error Wrong HW filter mode set.
+
+#endif /* SF_FM */
+}FLT_FRM_EADDR_BYTE_INDEX;
+#endif
+
+#define HASH_TBL_SIZ HT1_0_SIZE 
+#define IS_FILTERED_HI(pDrvCtrl, hi) HT1_0_PASS_HI((pDrvCtrl)->hashTable,hi)
+#define ADD_TO_HASHTBL(pDrvCtrl, hi) HT1_0_SET_HI((pDrvCtrl)->hashTable,hi)
+
+#define FLT_INDEX               HT_OPTY_2_2
+#define FLTR_FRM_PHY_ADRS_OFF	156   /* = FILT_INDEX(13 * 6):14th addr */
+#define FLTR_FRM_SIZE		    0xC0  /* filter frm size 192 bytes	*/
+#define FLTR_FRM_NUM_ADRS       16
+
+/* 
+ * If the LSB bit - 0th - of the first byte - byte #0 - of the
+ * ethernet address, is set - 1- then the address is a multicast one
+ * else it is unicast.
+ */
+//#define IS_MULTICAST(addrPtr) ( (*((UCHAR *)(addrPtr))) & (UCHAR *)0x01 )
+
+
+#endif /* __FILTERS_H */
diff -urN linux-2.4.29/drivers/net/cnxt_emac/hashIndex.h linux-2.4.29-uc1/drivers/net/cnxt_emac/hashIndex.h
--- linux-2.4.29/drivers/net/cnxt_emac/hashIndex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/hashIndex.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,124 @@
+/****************************************************************************
+*
+*	Name:			hashIndex.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 1999-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+*
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __HASH_INDEX_H
+#define __HASH_INDEX_H
+/*
+ * 
+ *
+ *
+ */
+
+#define EADDR_LEN 6 /* Lenth of ethernet address, in bytes. */
+
+/*
+ * Hash Index (HI) methods & types.
+ */
+
+/* List of available HI methods. */
+#define HI_METHOD_CRC32        0  /* CRC32 method. */
+#define HI_METHOD_RSSCM        1  /* RSS Cable Modem (CM) HI method. */
+#define HI_METHOD_NEW          2  /* Example. */
+
+/* The default HI method. */
+#define HI_METHOD_DEF HI_METHOD_RSSCM
+
+/* No HI method specified? Choose the default one. */
+#ifndef HI_METHOD
+#define HI_METHOD HI_METHOD_DEF
+#endif
+
+
+
+#define NUM_HI_SUPPORTED 256
+typedef unsigned char HI;
+#define HT_Y(hi) ((hi)>>3)            /* byte# in the Hash Table  */
+#define HT_X(hi) (1 << ((hi) & 0x07)) /* bit position in the byte */
+
+
+/*
+ * In next two macros the interpretation of the location is as follows:
+ * L(x,y) means: nth bit in yth byte of HT. Where n is the bit # of the
+ * only bit set in x. Depending upon various HT organisation the y co-ordinate
+ * may change from plain HT_Y(hi), but x remains unchanged.
+ *
+ * HT options for Y co-ord modifications: These options decide which bytes
+ * (pattern) to be used for y co-ordinate. Commonly used options are listed
+ * below.
+ *
+ * HT_OPTY_i_j: First i bytes [0...i-1] are used for y. Next j bytes [i...i+j-1]
+ *              are not used. Then again bytes [i+j...i+j+i-1] are used & so on.
+ *
+ * HT_OPTY_1_0: All the bytes of HT are used for y co-ordinate.
+ *              Here y = HT_Y(hi);
+ *
+ * HT_OPTY_1_1: Byte# 0,2,4,6,8,...are used & 1,3,5,7... not used.
+ *              Here y = HT_OPTY_1_1(HT_Y(hi));
+ * 
+ * HT_OPTY_2_2: Byte# 0,1,4,5,8,9,...are used & 2,3,6,7,...not used.
+ *              Here y = HT_OPTY_1_1(HT_Y(hi));
+ *              This is the commonly used option when the HT is to be formed
+ *              in the Setup frame.
+ */
+
+/* Set the location (x,y), in the HT. */
+#define HT_SET_HI(ht, x, y)    (ht[(y)] |= (x))
+
+/* Check the location (x,y), in the HT.(i.e. xth bit in yth byte of HT) */
+#define HT_PASS_HI(ht, x, y)   ((ht[(y)] & (x)) ? 1:0)
+
+#define HT_OPTY_1_0(y) (y)
+#define HT_OPTY_1_1(y) TBD /* To Be Defined */
+#define HT_OPTY_2_2(y) ((((y) & ~0x1) * 2) + ((y) & 0x1))
+
+#define HT1_0_SET_HI(ht,hi) HT_SET_HI(ht,HT_X(hi),HT_OPTY_1_0(HT_Y(hi)))
+#define HT1_1_SET_HI(ht,hi) HT_SET_HI(ht,HT_X(hi),HT_OPTY_1_1(HT_Y(hi)))
+#define HT2_2_SET_HI(ht,hi) HT_SET_HI(ht,HT_X(hi),HT_OPTY_2_2(HT_Y(hi)))
+
+#define HT1_0_PASS_HI(ht,hi) HT_PASS_HI(ht,HT_X(hi),HT_OPTY_1_0(HT_Y(hi)))
+#define HT1_1_PASS_HI(ht,hi) HT_PASS_HI(ht,HT_X(hi),HT_OPTY_1_1(HT_Y(hi)))
+#define HT2_2_PASS_HI(ht,hi) HT_PASS_HI(ht,HT_X(hi),HT_OPTY_2_2(HT_Y(hi)))
+
+/* 
+ * Hash Table size: Depending on the HT_OPTY_*_*, table size required to hold
+ * HIs varies. This size is #ofbytes required to hold Hash Values (HV) for all 
+ * of the Hash Indices. Each HV is a bit: HV = value of HIth bit.
+ */
+#define HT1_0_SIZE   (NUM_HI_SUPPORTED/8) 
+#define HT1_1_SIZE   (2*HT1_0_SIZE) 
+#define HT2_2_SIZE   HT1_1_SIZE 
+
+/* Externals. */
+extern HI HashIndex(unsigned char* eAddr);
+
+/* Macros for a user of this module. */
+#define HASH_INDEX(eAddr) HashIndex((eAddr))
+
+#endif __HASH_INDEX_H
diff -urN linux-2.4.29/drivers/net/cnxt_emac/intr_regs.h linux-2.4.29-uc1/drivers/net/cnxt_emac/intr_regs.h
--- linux-2.4.29/drivers/net/cnxt_emac/intr_regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/intr_regs.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,143 @@
+/****************************************************************************
+*
+*	Name:			intr_regs.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 1999-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+*
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __INTR_REGS_H
+#define __INTR_REGS_H
+
+/*******************************************************************************
+ * CX821xx: Reg base addr & Reg offset.
+ * The reg offset is same for all the sub-devices (like DMAC, EMAC & 
+ * Interrupt controller).
+ */
+
+
+#ifndef REG_BASE_ADDR
+#define REG_BASE_ADDR	 ((BYTE*)(0x00300000)) /* double word aligned */
+#endif
+
+#ifndef BE_OFST
+#define BE_OFST		 0   /* 0 for little endian, 7 for big  */
+#endif
+
+#ifndef REG_OFFSET
+#define REG_OFFSET	 (BE_OFST + 0x04) /* double word aligned */
+#endif
+
+/*******************************************************************************
+ *
+ * Define Interrupt REGs and macros to access them.
+ * To optimize REG accesses, redefine INTR_REG_READ and
+ * INTR_REG_WRITE macros in a wrapper file.
+ */
+
+/*
+ * ARM 1 interrupts ( indicated by INT1).
+ */
+
+#define INTR1_BASE_ADDR	    ((BYTE*)0x00350040)
+#define INTR1_REG_OFFSET	REG_OFFSET	
+
+/* Reg numbering w.r.t base */
+
+#define INT1_MSK	    0
+#define INT1_STAT	    1
+#define INT1_MSTAT	    2 
+#define INT1_SETSTAT	3 
+
+/* Reg access macros */
+
+#define INTR1_REG_ADDR(regNum)   (INTR1_BASE_ADDR + \
+                                 ((regNum) * INTR1_REG_OFFSET))
+
+#ifndef INTR1_REG_READ
+#define INTR1_REG_READ(regNum)       (*((volatile ULONG*)INTR1_REG_ADDR((regNum))))
+#endif /* INTR1_REG_READ */
+
+#ifndef INTR1_REG_WRITE
+#define INTR1_REG_WRITE(regNum,val)  (*((volatile ULONG*)INTR1_REG_ADDR((regNum))) = (val))
+#endif /* INTR1_REG_WRITE */
+
+#ifndef INTR1_REG_UPDATE
+#define INTR1_REG_UPDATE(regNum,val) INTR1_REG_WRITE((regNum), \
+                                     INTR1_REG_READ((regNum)) | (val))
+#endif /* INTR1_REG_UPDATE */
+    
+#ifndef INTR1_REG_RESET /* writing 1 resets, 0 no effect */
+#define INTR1_REG_RESET(regNum,val)  INTR1_REG_WRITE((regNum), \
+                                     INTR1_REG_READ((regNum)) | (val))
+#endif /* INTR1_REG_RESET */
+
+/* INT1_STAT Bit masks */
+
+#ifdef INT_ER_ERR
+#undef  INT_ER_ERR
+#endif
+#ifdef INT_ET_ERR
+#undef  INT_ET_ERR
+#endif
+#ifdef INT_DMA_ERR
+#undef  INT_DMA_ERR
+#endif
+#ifdef INT_DMAn_MASK
+#undef  INT_DMAn_MASK
+#endif
+#ifdef INT_DMA3
+#undef  INT_DMA3
+#endif
+#ifdef INT_DMA4
+#undef  INT_DMA4
+#endif
+
+/*#define INT_ER_ERR    ((ULONG)0x00040000)
+#define INT_ET_ERR    ((ULONG)0x00020000)
+#define INT_DMA_ERR   ((ULONG)0x00010000)
+#define INT_DMAn_MASK ((ULONG)0x000ff000)  Int_DMA{n} 
+#define INT_DMA3 ((ULONG)0x00002000)  Ethernet Tx 
+#define INT_DMA4 ((ULONG)0x00001000)  Ethernet Rx */
+
+#define INT_EMAC_TX     (INT_ET_ERR|INT_DMA3)
+#define INT_EMAC_RX     (INT_ER_ERR|INT_DMA4)
+#define INT_EMAC        (INT_EMAC_TX|INT_EMAC_RX)
+#define INT_DMA_M2M 	((ULONG)0x00000100)      
+
+/*#define MAX(x,y) ((x)>(y)?(x):(y))*/
+
+#define INT_EMAC_LVL MAX(\
+        MAX(INT_LVL_ET_ERR,INT_LVL_DMA3),\
+        MAX(INT_LVL_ER_ERR,INT_LVL_DMA4))
+/*
+ * ARM 2 interrupts ( indicated by INT2).
+ * Not listed here as they are not used by the driver.
+ */
+
+#define INTR2_BASE_ADDR	    ((BYTE*)0x00350080)
+
+
+#endif /* __INTR_REGS_H */
diff -urN linux-2.4.29/drivers/net/cnxt_emac/m2m_regs.h linux-2.4.29-uc1/drivers/net/cnxt_emac/m2m_regs.h
--- linux-2.4.29/drivers/net/cnxt_emac/m2m_regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/m2m_regs.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,101 @@
+/****************************************************************************
+*
+*	Name:			m2m_regs.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 1999-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+*
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __M2M_REGS_H
+#define __M2M_REGS_H
+
+
+/*******************************************************************************
+ * CX821xx: Reg base addr & Reg offset.
+ * The reg offset is same for all the sub-devices (like DMAC, EMAC & 
+ * Interrupt controller).
+ */
+
+
+#ifndef REG_BASE_ADDR
+#define REG_BASE_ADDR	 ((BYTE*)(0x00300000)) /* double word aligned */
+#endif
+
+#ifndef BE_OFST
+#define BE_OFST		 0   /* 0 for little endian, 7 for big  */
+#endif
+
+#ifndef REG_OFFSET
+#define REG_OFFSET	 (BE_OFST + 0x04) /* double word aligned */
+#endif
+
+/**************************************************************
+ * M2M regs, bit masks & reg-access macros
+ */
+
+/* 
+ * Reg addresses
+ */
+
+/* M2M DMA port reg. It's 64 bit reg. Lower 32 are software writable */
+#define M2M_DMA_64BITS	  ((volatile BYTE*)0x00350000) 
+
+#if (BE_OFST==0) /* Little endian */
+#define M2M_DMA	           M2M_DMA_64BITS /* lower 32bits start here */
+#else /* big endian */
+#define M2M_DMA	          (M2M_DMA_64BITS + sizeof(DWORD)) /* Next ULONG */
+#endif /* BE_OFST == 0 */
+
+/* M2M CNT reg*/
+#define M2M_CNT	      ((volatile BYTE*)0x00350004)
+
+/* 
+ * M2M_CNT masks 
+ */
+
+#define M2M_BS_MASK       ((ULONG)(0x00600000)) /* [22:21] RW */
+
+#define M2M_BS0_MASK      ((ULONG)(0x00000000)) /* bs=0 */
+#define M2M_BS1_MASK      ((ULONG)(0x00200000)) /* bs=1 */
+#define M2M_BS2_MASK      ((ULONG)(0x00400000)) /* bs=2 */
+#define M2M_BS3_MASK      ((ULONG)(0x00600000)) /* bs=3 */
+
+#define M2M_DO_MASK       ((ULONG)(0x00100000)) /* Dst only. [20] RW */
+#define M2M_SD_MASK       ((ULONG)(0x00000000)) /* src & dst */
+
+#define M2M_COUNT_MASK    ((ULONG)(0x000fffff)) /* [19:0] RW */
+
+/* 
+ * M2M macros that form the val that may be written to M2M_CNT reg. 
+ */
+
+#define M2M_BS0_DO_CNT(num_of_qwords) \
+        (M2M_BS0_MASK|M2M_DO_MASK|(M2M_COUNT_MASK & (ULONG)(num_of_qwords)))
+
+#define M2M_BS0_SD_CNT(num_of_qwords) \
+        (M2M_BS0_MASK|M2M_SD_MASK|(M2M_COUNT_MASK & (ULONG)(num_of_qwords)))
+
+
+#endif /*__M2M_REGS_H */
diff -urN linux-2.4.29/drivers/net/cnxt_emac/mac.h linux-2.4.29-uc1/drivers/net/cnxt_emac/mac.h
--- linux-2.4.29/drivers/net/cnxt_emac/mac.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/mac.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,90 @@
+/****************************************************************************
+*
+*	Name:			mac.h
+*
+*	Description:	Header file for unicast, multicast and broadcast MAC 
+*					address handling.
+*
+*	Copyright:		(c) 1999-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+*
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __MAC_H
+#define __MAC_H
+/****************************************************************************
+ * Include Files
+ ****************************************************************************/
+
+#include <vxWorks.h>
+#include <string.h>
+
+
+/****************************************************************************
+ * Defines
+ ****************************************************************************/
+
+/* length of MAC address (in bytes) */
+#define MAC_ADDR_LEN          ( 6 ) 
+           
+/* return value for MAC_cmp */
+#define MAC_GREATER           ( 1 )    
+#define MAC_EQUAL             ( 0 )
+#define MAC_LESS              ( -1 )
+
+/* size of multicast address and hash tables */
+#define MULTI_TABLE_SIZE      ( 256 )
+#define HASH_TABLE_SIZE       ( 32 )
+
+/* bit which defines whether a MAC Address is multi or uni cast */
+#define MULTICAST_MSK         ( 0x01 )
+
+/* hash table initialization values */
+#define FILTER_ALL            ( 0x00 )
+#define PASS_ALL              ( 0xFF )
+
+
+/****************************************************************************
+ * Structures
+ ****************************************************************************/
+
+/* MAC Address */
+typedef UINT8 MAC_ADDR[MAC_ADDR_LEN];
+
+/* aligned MAC address */
+typedef struct aligned_mac_addr
+{
+   UINT16      usLSW;      /* least significant word */
+   UINT16      usCSW;      /* middle word */
+   UINT16      usMSW;      /* most significant word */
+} ALIGNED_MAC_ADDR;
+
+
+/****************************************************************************
+ * Prototypes
+ ****************************************************************************/
+
+int   MAC_cmp(const void *, const void *);
+void  MAC_SetupHashTable(MAC_ADDR *, UINT16 , UINT8 *);
+#endif /*  End of __MAC_H  */
+/*###################################################*/
+
diff -urN linux-2.4.29/drivers/net/cnxt_emac/Makefile linux-2.4.29-uc1/drivers/net/cnxt_emac/Makefile
--- linux-2.4.29/drivers/net/cnxt_emac/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/Makefile	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,17 @@
+# File: drivers/net/cnxt_emac/Makefile
+#
+# Makefile for the Linux Conexant emac driver.
+#
+
+O_TARGET := emac_drv.o
+
+EXTRA_CFLAGS += -DOS_LINUX -DLINUX_EMBEDDED	-DLINUX_DRIVER
+
+obj-y += cnxtEmac.o \
+	 phy.o \
+	 mii.o
+# JH: does not compile, disabled:	 tesla.o
+
+obj-m := $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/net/cnxt_emac/mii.c linux-2.4.29-uc1/drivers/net/cnxt_emac/mii.c
--- linux-2.4.29/drivers/net/cnxt_emac/mii.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/mii.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,953 @@
+/****************************************************************************
+*
+*	Name:			mii.c
+*
+*	Description:	MII driver for CX821xx products
+*
+*	Copyright:		(c) 1997-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+*
+*****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+/*
+ *  Module Name: mii.c  
+ *  Author: Joe Bonaker
+ *
+ *  MII.C : OS_DEPENDENT, MAC_DEPENDENT 
+ *  100Base-T Media Independent Interface (MII)
+ *  module, which contains adapter and OS-specific support routines for
+ *  the "phy.c" PHY driver module.  This file must be tailored for each
+ *  unique adapter/operating system environment pair.
+ *
+ *  Conditional Compilation Switches:
+ *
+ *     The following conditional compilation switches apply, and may
+ *     be overridden by the user at compile-time.
+ *
+ *     DRV_OS - default DOS.  Establishes the OS-specific controller
+ *     (MAC or repeater) device I/O (or memory-mapped) access to the
+ *     PHY's serial MII plus microsecond and/or millisecond timer
+ *     support as detailed in [Step 1] of the Porting Guide below and
+ *     within this module.  DRV_OS types are defined in "phytypes.h."
+ *
+ *  Porting Guide:
+ *
+ *  There are two steps which must be performed to tailor this module
+ *  for a specific adapter (NIC) or repeater configuration.
+ *
+ *  [Step 1] entails mapping the OS_MICROSECOND_WAIT() and/or
+ *  OS_MILLISECOND_WAIT(), IO_WRITE(), IO_READ(), plus optional
+ *  OS_NANOSECOND_WAIT() macros into the PHY driver's operating system,
+ *  as defined by DRV_OS.
+ *
+ *  [Step 2] alters the adapter-specific register configuration.  At
+ *  present, only a MAC (NIC) controller interface, the RSS1161x 10/100
+ *  Mbit Fast Ethernet series, is supported.  [Step 2a] contains
+ *  MAC general purpose I/O (GPIO) settings which may vary among
+ *  different adapter configurations.  [Step 2b] contains an optional
+ *  PHY hardware reset sequence, which is dependent upon the [Step 2a]
+ *  interconnection between the MAC and PHY devices/modules.
+ *
+ *  Search this module for occurances of [Step 1] and [Step 2], editing
+ *  accordingly.
+ *
+ **********************************************************************/
+#if 0
+	#if defined(LINUX_DRIVER)
+	#include "linuxinc.h"
+	#endif
+#endif
+#define P52
+#include "phytypes.h"
+#include "mii.h"
+
+
+ /*--------------------------------------------------------------------*
+ * [Step 1] Enter DRV_OS-dependent support for OS_MICROSECOND_WAIT(),
+ *          and/or OS_MILLISECOND_WAIT(), optional OS_NANOSECOND_WAIT(),
+ *          plus 32-bit IO_WRITE()/IO_READ() services.  Edit one or
+ *          more of [Step 1a] through [Step 1h] as necessary.
+ *
+ *          Either one or both of OS_MICROSECOND_WAIT() and
+ *          OS_MILLISECOND_WAIT() must be #defined, depending on DRV_OS
+ *          environment support.  If the DRV_OS supports microsecond
+ *          granularity delays (preferred), then #define the
+ *          OS_MICROSECOND_WAIT() macro accordingly.  Otherwise,
+ *          #define OS_MILLISECOND_WAIT().  If the DRV_OS supports both
+ *          microsecond and millisecond delays, and advocates a scheme
+ *          for relinquishing the CPU during longer delays, then
+ *          OS_MILLISECOND_WAIT() may also be #defined using the more
+ *          system-friendly long delay service.  As long as at least
+ *          one of these two macros is #defined, code outside this
+ *          [Step 1] DRV_OS-specific block will ensure that the other
+ *          macro is properly derived.
+ *
+ *          Unless the DRV_OS supports nanosecond granularity (highly
+ *          unlikely), OS_NANOSECOND_WAIT() should NOT be #defined,
+ *          and will be derived from OS_MICROSECOND_WAIT() outside this
+ *          code block.  There is one exception.  Since the nanosecond
+ *          delay is only used to ensure that MiiRead() and MiiWrite()
+ *          clock timing doesn't exceed the 802.3u minimum hold time
+ *          of 200-300 nanoseconds, OS_NANOSECOND_WAIT() can be
+ *          disabled in a DRV_OS environment where IO_READ() and
+ *          IO_WRITE() take a considerable length of time to complete.
+ *          This is accomplished as follows:
+ *
+ *              #define OS_NANOSECOND_WAIT(n)           // No delay
+ *
+ *          For example, the DRV_OS=WIN32_DIAG relies on driver ioctls
+ *          to perform IO_READ() and IO_WRITE().  This, in conjunction
+ *          with a 10-millisecond delay granularity, results in
+ *          MiiRead() and MiiWrite() times approaching one second per
+ *          register!  Therein, OS_NANONSECOND_WAIT() was disabled.
+ *
+ *          Though their names imply I/O device access, the IO_READ()
+ *          and IO_WRITE() macros may also be crafted to support a
+ *          memory-mapped controller -- MAC or repeater -- device
+ *          interface.  Regardless, they also support the notion of an
+ *          <adapter> reference for DRV_OS environments requiring
+ *          abstraction to touch hardware, e.g., NDIS, WIN32_DIAG,
+ *          NOVELL_CHSM.  Other environments can ignore the <adapter>
+ *          or use it as a device base address parameter.
+ *--------------------------------------------------------------------*/
+
+#if (DRV_OS == NDIS)            /*------------------------------------*
+                                 * [Step 1a] Win95/WinNT NDIS
+                                 *
+                                 * Assumes <adapter> is the starting
+                                 * I/O port address of the MAC device
+                                 *------------------------------------*/
+#define OS_MICROSECOND_WAIT(u)          NdisStallWrapper(u)
+#ifdef P51
+ULONG P51_GlobalReadVariable;
+#define IO_WRITE(adapter, port, val) {                                         \
+    NdisWriteRegisterUlong((PULONG) ((adapter) + (port)), (ULONG) (val));      \
+    NdisReadRegisterUlong((PULONG) ((adapter) + (port)), (PULONG) &P51_GlobalReadVariable); \
+}
+#else
+#define IO_WRITE(adapter, port, val)    \
+    NdisRawWritePortUlong((PULONG) ((adapter) + (port)), (ULONG) (val))
+#endif
+#define IO_READ(adapter, port)          \
+    NdisIoReadWrapper((adapter) + (port))
+
+/***********************************************************************
+ * NdisStallWrapper() - "OS-friendly" wait in 100 uSec chunks
+ **********************************************************************/
+static void
+NdisStallWrapper(DWORD num_microseconds)
+{
+    /*
+     * Semi-hog:  relinquish the CPU every 100 microseconds to prevent
+     * other drivers (e.g., tty character devices) from starving
+     */
+    while (num_microseconds > 25) {
+        NdisStallExecution(25);
+        num_microseconds -= 25;
+    }
+//	if( num_microseconds == 1)
+//		num_microseconds = 10;
+    NdisStallExecution(num_microseconds);
+}
+
+/***********************************************************************
+ * NdisIoReadWrapper() - expected NdisRawReadPortUlong() interface
+ **********************************************************************/
+static DWORD
+NdisIoReadWrapper(DWORD port)
+{
+    ULONG       val;
+
+#ifdef P51
+    NdisReadRegisterUlong((PULONG) port, &val);
+#else
+    NdisRawReadPortUlong((PULONG) port, &val);
+#endif
+    return ((DWORD) val);
+}
+
+#elif (DRV_OS == NOVELL_CHSM)   /*------------------------------------*
+                                 * [Step 1b] Novell 32-bit ODI
+                                 *
+                                 * Assumes <adapter> has been cast as
+                                 * pointer to a PHY_ADAPTER structure
+                                 *------------------------------------*/
+
+#define OS_MICROSECOND_WAIT(u)          Odi32MicroWait(u)
+#define OS_NANOSECOND_WAIT(n)           Slow()  /* 0.5 uSec NOP */
+#ifndef IO_MAPPED               /* default:  memory-mapped device */
+#define IO_WRITE(adapter, port, val)                            \
+    Wrt32(((PHY_ADAPTER *) (adapter))->bus_tag, NULL,           \
+          (void *) (((port) + (UINT8 *)                         \
+                     ((PHY_ADAPTER *) (adapter))->dev_addr)),   \
+          (UINT32) (val))
+#define IO_READ(adapter, port)          (DWORD)                 \
+    Rd32(((PHY_ADAPTER *) (adapter))->bus_tag, NULL,            \
+         (void *) (((port) + (UINT8 *)                          \
+                   ((PHY_ADAPTER *) (adapter))->dev_addr)))
+#else                           /* non-default:  I/O-mapped device */
+#define IO_WRITE(adapter, port, val)                            \
+    Out32(((PHY_ADAPTER *) (adapter))->bus_tag,                 \
+          (void *) (((port) + (UINT8 *)                         \
+                     ((PHY_ADAPTER *) (adapter))->dev_addr)),   \
+          (UINT32) (val))
+#define IO_READ(adapter, port)          (DWORD)                 \
+    In32(((PHY_ADAPTER *) (adapter))->bus_tag,                  \
+         (void *) (((port) + (UINT8 *)                          \
+                   ((PHY_ADAPTER *) (adapter))->dev_addr)))
+#endif
+
+/***********************************************************************
+ * Odi32MicroWait() - Microsecond delay under 32-bit Novell ODI OS
+ **********************************************************************/
+static void
+Odi32MicroWait(DWORD num_microseconds)
+{
+    /*
+     * CMSMGetMicroTimer() support is suspect under some client
+     * operating systems as only 16 bits of returned 32-bit timer value
+     * may be valid.  Instead, use the (hopefully) more trustworthy
+     * Slow() service.
+     */
+    while (num_microseconds-- > 0) {
+        Slow();         /* 0.5 uSec NOP per CHSM ODI spec v1.11 */
+        Slow();
+    }
+}
+
+#elif (DRV_OS == SCO_MDI)       /*------------------------------------*
+                                 * [Step 1c] SCO Unix drivers: MDI,
+                                 * LLI, DLPI, and Gemini.
+                                 *
+                                 * Assumes <adapter> is the starting
+                                 * I/O port address of the MAC device
+                                 *------------------------------------*/
+#define OS_MICROSECOND_WAIT(u)          suspend(u)
+#define IO_WRITE(adapter, port, val)    outd((adapter) + (port), (val))
+#define IO_READ(adapter, port)          ind((adapter) + (port))
+
+#elif (DRV_OS == SCO_LLI)
+#define OS_MICROSECOND_WAIT(u)          TBD
+#define IO_WRITE(adapter, port, val)    TBD
+#define IO_READ(adapter, port)          TBD
+
+#elif (DRV_OS == SCO_DLPI)
+#define OS_MICROSECOND_WAIT(u)          TBD
+#define IO_WRITE(adapter, port, val)    TBD
+#define IO_READ(adapter, port)          TBD
+
+#elif (DRV_OS == SCO_GEMINI)
+#define OS_MICROSECOND_WAIT(u)          TBD
+#define IO_WRITE(adapter, port, val)    TBD
+#define IO_READ(adapter, port)          TBD
+
+#elif (DRV_OS == SOLARIS)       /*------------------------------------*
+                                 * [Step 1d] Sun Solaris driver
+                                 *
+                                 * Assumes <adapter> is the starting
+                                 * I/O port address of the MAC device
+                                 *------------------------------------*/
+#define OS_MICROSECOND_WAIT(u)          drv_usecwait(u)
+#define IO_WRITE(adapter, port, val)    outl((adapter) + (port), (val))
+#define IO_READ(adapter, port)          inl((adapter) + (port))
+
+#elif (DRV_OS == LINUX)         /*------------------------------------*
+                                 * [Step 1e] Linux driver support
+                                 *
+                                 * Assumes <adapter> is the starting
+                                 * I/O port address of the MAC device
+                                 *------------------------------------*/
+/*
+ * Caution:  per the outb(9) man page, the outl() arguments are the
+ * opposite of most DOS-based output routines:  outl(value, portAddr)
+ * instead of outl(portAddr, value).
+ */
+#ifdef __KERNEL__
+
+#define OS_MICROSECOND_WAIT(u)          udelay(u)
+#else
+	/* #include <unistd.h> */
+	/* #define OS_MICROSECOND_WAIT(u)          usleep(u) */
+	#define OS_MICROSECOND_WAIT(u)          LinuxMicroWait(u)
+	void LinuxMicroWait(int microseconds)
+	{
+	    do {
+	    } while (--microseconds > 0);
+	}
+#endif
+
+// Turn the requested nanosecond delay into a 20 times longer usec delay
+#define OS_NANOSECOND_WAIT(u) udelay(u/50)
+
+#ifdef P51
+	#define IO_WRITE(adapter, port, val)  { \
+		writel((val), (adapter) + (port)) ; \
+		readl( (adapter) + (port) );		\
+	}
+	#define IO_READ(adapter, port)          readl((adapter) + (port))
+#else
+	#define IO_WRITE(adapter, port, val)    outl((val), (adapter) + (port))
+	#define IO_READ(adapter, port)          inl((adapter) + (port))
+#endif
+
+#elif (DRV_OS == PKTDRV)        /*------------------------------------*
+                                 * [Step 1f] DOS/PCTCP packet driver
+                                 *
+                                 * Assumes <adapter> is the starting
+                                 * I/O port address of the MAC device
+                                 *------------------------------------*/
+#include <???.h>
+
+#define OS_MICROSECOND_WAIT(u)          TBD
+#define IO_WRITE(adapter, port, val)    TBD
+#define IO_READ(adapter, port)          TBD
+
+#elif (DRV_OS == WIN32_DIAG)    /*------------------------------------*
+                                 * [Step 1g] RSS' Win95/WinNT Diagnostic
+                                 *
+                                 * Assumes <adapter> is the adapter
+                                 * handle used by the diagnostic.  Also,
+                                 * nullifies OS_NANOSECOND_WAIT(), as
+                                 * IO_READ() and IO_WRITE() driver
+                                 * ioctl's provide sufficient clock
+                                 * spacing, i.e., >> one uSec.
+                                 *------------------------------------*/
+
+#define Unknown_OS      0
+#define Windows95_OS    1
+#define Windows98_OS    2
+#define WindowsNT4_OS   3
+
+#define OS_MILLISECOND_WAIT(m)                  SleepEx((m), FALSE)
+#define OS_NANOSECOND_WAIT(n)                   /* No delay */
+
+#define IO_WRITE(adapter, port, val)            \
+    (void) _PutCSRRegisterWrapper((ULONG) adapter, (ULONG) (port), (ULONG) (val))
+
+#define IO_READ(adapter, port)          \
+    _GetCSRRegisterWrapper((ULONG) (adapter), (ULONG) (port))
+
+/***********************************************************************
+ * _PutCSRRegisterWrapper() - expected _PutCSRRegister() interface
+ **********************************************************************/
+static DWORD
+_PutCSRRegisterWrapper(ULONG adapter, ULONG port, ULONG val)
+{
+
+    HANDLE      drvhandle;
+    DWORD       RunningOS;
+
+    RunningOS = CheckOS();
+
+    if (RunningOS != WindowsNT4_OS) {
+        _getdriverhandle(&drvhandle);   /* get handle to driver */
+        
+        if (!drvhandle)                 /* if fail, return -1 */
+            return (-1);
+    }
+
+    (void) _putcsrregister(drvhandle,adapter, port, val);
+
+    return ((DWORD) val);
+}
+
+/***********************************************************************
+ * _GetCSRRegisterWrapper() - expected _GetCSRRegister() interface
+ **********************************************************************/
+static DWORD
+_GetCSRRegisterWrapper(ULONG adapter, ULONG port)
+{
+    ULONG       val = -1;
+    HANDLE      drvhandle;
+    DWORD       RunningOS;
+
+    RunningOS = CheckOS();
+
+    if (RunningOS != WindowsNT4_OS) {
+        _getdriverhandle(&drvhandle);   /* get handle to driver */
+        
+        if (!drvhandle)                 /* if fail, return -1 */
+            return (-1);
+    }
+    
+    (void) _getcsrregister(drvhandle,adapter, port, &val);
+
+    return ((DWORD) val);
+}
+
+#elif (DRV_OS == VXWORKS)       /*------------------------------------*
+                                 * [Step 1g.1] VxWorks
+                                 *------------------------------------*/
+
+#define OS_MICROSECOND_WAIT(u)          VxWorksMicroWait(u)
+#define OS_NANOSECOND_WAIT(n)           VxWorksSlow() /* 0.5 uSec NOP */
+
+/* default:  memory-mapped device */
+#define IO_WRITE(adapter, port, val)                            \
+	* ((BYTE *) adapter + port) = val
+#define IO_READ(adapter, port)          (DWORD)                 \
+	* ((BYTE *) adapter + port)
+
+static void VxWorksSlow();
+/***********************************************************************
+ * VxWorksMicroWait() - Microsecond delay under VxWorks OS
+ **********************************************************************/
+static void
+VxWorksMicroWait(DWORD num_microseconds)
+{
+    /*
+     * Use the VxWorksSlow() function which busywaits for 0.5 microsec.
+     */
+    while (num_microseconds-- > 0) {
+        VxWorksSlow();         /* 0.5 uSec NOP loop */
+        VxWorksSlow();
+    }
+}
+
+/***********************************************************************
+ * VxWorksSlow() - Microsecond delay under VxWorks OS
+ **********************************************************************/
+static void
+VxWorksSlow()
+{
+	volatile int	iLoopCount;
+    /*
+     * Loop for 25 times to pass 0.5 micro.
+     */
+	for (iLoopCount=25; iLoopCount; iLoopCount--)
+		;
+	for (iLoopCount=25; iLoopCount; iLoopCount--)
+		;
+}
+
+
+#elif (DRV_OS == NO_OS)         /*------------------------------------*
+                                 * [Step 1g.2] No OS Services
+                                 *------------------------------------*/
+
+#define OS_MICROSECOND_WAIT(u)          NoOSMicroWait(u)
+#define OS_NANOSECOND_WAIT(n)           NoOSSlow() /* 0.5 uSec NOP */
+
+/* default:  memory-mapped device */
+#define IO_WRITE(adapter, port, val)                            \
+	* ((BYTE *) adapter + port) = val
+#define IO_READ(adapter, port)          (DWORD)                 \
+	* ((BYTE *) adapter + port)
+
+/***********************************************************************
+ * VxWorksMicroWait() - Microsecond delay under No OS Services
+ **********************************************************************/
+static void
+NoOSMicroWait(DWORD num_microseconds)
+{
+    /*
+     * Use the NoOSSlow() function which busywaits for 0.5 microsec.
+     */
+    while (num_microseconds-- > 0) {
+        NoOSSlow();         /* 0.5 uSec NOP loop */
+        NoOSSlow();
+    }
+}
+
+/***********************************************************************
+ * NoOSSlow() - Microsecond delay under VxWorks OS
+ **********************************************************************/
+static void
+NoOSSlow()
+{
+	volatile int	iLoopCount;
+    /*
+     * Loop for 25 times to pass 0.5 micro.
+     */
+	for (iLoopCount=25; iLoopCount; iLoopCount++)
+		;
+}
+
+
+#else                           /*------------------------------------*
+                                 * [Step 1h] Miscellaneous (DOS, etc.)
+                                 *
+                                 * Assumes <adapter> is the starting
+                                 * I/O port address of the MAC device
+                                 *------------------------------------*/
+#include <conio.h>
+
+#if   defined(__WATCOMC__)
+#elif defined(__BORLANDC__)
+#elif defined(_MSVC_VER)
+#endif
+
+#ifdef _MAPTEST_
+BYTE    phy_data[0x10] = {0};   /* DATA - initialized */
+BYTE    phy_bss[0x10];          /* BSS  - uninitialized */
+#endif
+
+extern DWORD    inpd(int port);
+extern DWORD    outpd(int port, DWORD val);
+#define OS_MICROSECOND_WAIT(u)          DosMicroWait(u)
+#define IO_WRITE(adapter, port, val)    \
+    (void) outpd((int) (adapter) + (port), (val))
+#define IO_READ(adapter, port)          \
+    inpd((int) (adapter) + (port))
+
+/*
+ * Convert microseconds to PC system ticks.  The 16-bit Timer0, in
+ * Mode 3 (square wave), decrements two counts per 1.1932 MHz input
+ * clock on most systems.  We round this 2.3864 ticks/uSec to integer
+ * (239 / 100) here, yielding a 32-bit unsigned range of 17.971 seconds.
+ * Warning:  Some AMI BIOSes have a bug, configuring Timer0 into Mode 2
+ * (rate generator), which only decrements one count per clock.  On
+ * such systems, we'll suffer a delay that is twice as long as
+ * expected.  This could be a problem for longer, millisecond-to-second
+ * duration delays, however, most MII related delays are microsecond
+ * or less.
+ */
+#define PC_TIMER0_TICKS(usec)           \
+    (1 + (((DWORD) (usec) * 239) / 100))
+
+/***********************************************************************
+ * DosMicroWait() - Microsecond delay under 16-bit DOS environment
+ **********************************************************************/
+static void
+DosMicroWait(DWORD count)
+{
+    DWORD       t0;
+    DWORD       t1;
+    DWORD       delta_t;
+    BYTE        timer0_lsb;
+
+    /*
+     * Writing a command value of 0x00 to Port 0x43 transfers
+     * the Timer 0 counter into the output latch register.  The value
+     * is held until read from port 0x40 (two successive byte reads,
+     * LSB followed by the MSB).  A truly bullet-proof implementation
+     * would lock interrupts prior to latching and reading the counter.
+     */
+    outp(0x43, 0x00);
+    timer0_lsb = inp(0x40);
+    t1 = ((DWORD) inp(0x40) << 8) + timer0_lsb;
+    delta_t = 0;
+    count = PC_TIMER0_TICKS(count);     /* uSec to Timer0 ticks */
+
+    do {
+        count -= delta_t;
+        t0 = t1;
+        outp(0x43, 0x00);
+        timer0_lsb = inp(0x40);
+        t1 = ((DWORD) inp(0x40) << 8) + timer0_lsb;
+        if (t1 > t0) {
+            t0 += 0x10000UL;            /* handle 16-bit rollover */
+        }
+        delta_t = t0 - t1;
+    } while (count > delta_t);
+}
+
+#ifdef UNSUPPORTED      /* Most C/C++ only support 16-bit in-line ASM */
+DWORD
+outpd(int port, DWORD val)
+{
+    __asm {
+        mov     dx, port;
+        mov     eax, val;
+        out     dx, eax;
+    }
+    return (val);
+}
+
+DWORD
+inpd(int port)
+{
+    DWORD       val;
+
+    __asm {
+        mov     dx, port;
+        in      eax, dx;
+        mov     val, eax;
+    }
+    return (val);
+}
+#endif  /* UNSUPPORTED, as most C/C++ only support 16-bit in-line ASM */
+
+#endif                          /*------------------------------------*
+                                 * [Step 1] End of first porting step
+                                 *------------------------------------*/
+
+/*
+ * Post- [Step 1] timer derivation.  OS_MICROSECOND_WAIT() and/or
+ * OS_MILLISECOND_WAIT() must be #defined for this to work....
+ */
+
+#ifndef OS_MICROSECOND_WAIT
+#define OS_MICROSECOND_WAIT(u)                  \
+    OS_MILLISECOND_WAIT((DWORD) ((u) + 999) / 1000)
+#endif
+
+#ifndef OS_MILLISECOND_WAIT
+#define OS_MILLISECOND_WAIT(m)  MICROSECOND_WAIT((DWORD) (m) * 1000)
+#endif
+
+//#if (DRV_OS == NDIS)
+//#define OS_NANOSECOND_WAIT(n)           // NO_DELAY
+//#endif
+#ifndef OS_NANOSECOND_WAIT
+#define OS_NANOSECOND_WAIT(n)   \
+    MICROSECOND_WAIT((DWORD) ((n) + 999) / 1000)
+#endif
+#define NANOSECOND_WAIT         OS_NANOSECOND_WAIT
+
+/*--------------------------------------------------------------------*
+ * [Step 2] Enter (NIC or repeater) adapter's MAC controller-specific
+ *          register information.  The MII (MDIO) and any optional
+ *          adapter-unique general purpose I/O (GPIO) settings must be
+ *          captured here.  In particular, the gpio[] table should be
+ *          modified per adapter configuration of the MAC's GPIO
+ *          interface [Step 2a].  If additional, custom configuration
+ *          is required, the low-level MiiPhyHwReset() routine may be
+ *          modifified [Step 2b].
+ *
+ *          Warning:  at present, only RSS and DEC-compatible fast
+ *          ethernet MACs are supported.  Common repeater interfaces
+ *          will be added as development (COMET?) progresses at RSS.
+ *--------------------------------------------------------------------*/
+#ifdef DEVICE_YELLOWSTONE
+
+	#define MAC_MDIO_REG            0x0c
+	#define MDIO_RD_DATA            0x8L
+	#define MDIO_RD_ENABLE          0x2L
+	#define MDIO_WR_ENABLE          0x00000L
+	#define MDIO_WR_DATA_1          0x4L
+	#define MDIO_WR_DATA_0          0x00000L        
+	#define MDIO_CLK                0x1L
+	#define MDIO_MASK               0xFL
+
+#elif defined(P51) 
+
+	#define JEDI_MII_ID			0x0032cc10		
+	#define JEDI_MII_ID_REVC	0x0032cc13
+	// bit 3:0 - revision
+
+	#define JediPhy(mii_id) (BOOLEAN)( (mii_id & 0xfffffff0) == JEDI_MII_ID)
+
+	/* P51- YUKON or ATHENS , ELAN or HLAN MII (MDIO) register offset and values */
+	// the following definition is not 100% correct but it work for all our current boards
+	#define MAC_MDIO_REG            0x30
+	#define MDIO_RD_DATA            (0x8L<< ((phy->P51_HLAN) ? 2 : 0))
+	#define MDIO_RD_ENABLE          (0x2L<< ((phy->P51_HLAN) ? 2 : 0))
+	#define MDIO_WR_ENABLE          0x00000L
+	#define MDIO_WR_DATA_1          (0x4L<< ((phy->P51_HLAN) ? 2 : 0))
+	#define MDIO_WR_DATA_0          0x00000L        
+	#define MDIO_CLK                (0x1L<<((phy->P51_HLAN) ? 2 : 0))
+	#define MDIO_MASK               (0xFL<<((phy->P51_HLAN) ? 2 : 0))
+
+#elif defined(P52) 
+	// P52- CX82100,
+	#define MAC_MDIO_REG            0x18
+	#define MDIO_RD_DATA            0x0002L
+	#define MDIO_RD_ENABLE          0x0008L
+	#define MDIO_WR_ENABLE          0x0000L
+	#define MDIO_WR_DATA_1          0x0004L        
+	#define MDIO_WR_DATA_0          0x0000L        
+	#define MDIO_CLK                0x0001L
+	#ifdef JEDIPHY		// Bright 6/8/01 test
+		#define MDIO_CLK_MDIP           0x0010L	/* bit 4 - default 0 */
+												/*		0=falling endge sample */
+												/*      1=rising endge sample */
+
+		#define MDIO_MASK               0x001FL
+	#else
+		#define MDIO_CLK_MDIP           0x0010L	/* bit 4 - default 0 */
+												/*		0=falling endge sample */
+												/*      1=rising endge sample */
+
+		#define MDIO_MASK               0x000FL
+	#endif
+
+
+#else
+
+	/* RSS 1161x MACs' CSR9 (MDIO) register offset and values */
+	#define MAC_MDIO_REG            0x48
+	#define MDIO_RD_DATA            0x80000L
+	#define MDIO_RD_ENABLE          0x40000L
+	#define MDIO_WR_ENABLE          0x00000L
+	#define MDIO_WR_DATA_1          0x20000L        
+	#define MDIO_WR_DATA_0          0x00000L        
+	#define MDIO_CLK                0x10000L
+	#define MDIO_MASK               0xF0000L
+#endif
+
+/* MII frame fields */
+#define MII_READ_ST_OP          0x6     /* MII READ start, opcode */
+#define MII_WRITE_ST_OP         0x5     /* MII WRITE start, opcode */
+#define MII_WRITE_TA            0x2     /* MII WRITE turnaround bits */
+#define MII_WRITE_FRAME         \
+    (((DWORD) MII_WRITE_ST_OP << 28) | ((DWORD) MII_WRITE_TA << 16))
+
+/* Local (static) function prototypes */
+static void     MiiPreamble(MIIOBJ *phy);
+static void     MiiIdle(MIIOBJ *phy, int num_clocks);
+
+/***********************************************************************
+ * MiiRead() - read serial data from MII register
+ **********************************************************************/
+
+WORD MiiRead(MIIOBJ *phy, BYTE reg_addr)
+{
+    DWORD 	io_data;
+    WORD	mii_data;
+    int		n;
+
+    /* Output 32-bit preamble (all ones) to re-sync the PHY */
+    MiiPreamble(phy);
+
+    /* Preserve non-MDIO bits in shared MAC_MDIO_REG (SPR) */
+    io_data = IO_READ(phy->adapter, MAC_MDIO_REG) & ~MDIO_MASK;
+
+    /* Write the first 14 <mii_data> frame bits in MSB-first order */
+    mii_data = (MII_READ_ST_OP << 10) | (phy->mii_addr << 5) | (reg_addr & 0x1F);
+    for (n = 0x2000; n > 0; n >>= 1)
+    {
+        io_data &= ~MDIO_MASK;          /* Preserve non-MDIO bits */
+        if (mii_data & n)
+        {
+            io_data |= (MDIO_WR_ENABLE | MDIO_WR_DATA_1);
+        }
+        else
+        {
+            io_data |= (MDIO_WR_ENABLE | MDIO_WR_DATA_0);
+        }
+
+		// Change output data to phy on falling edge of MDIO_CLK
+        IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data);
+        NANOSECOND_WAIT(200);
+
+		// Input data sampled by phy on rising edge of MDIO_CLK
+        IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data | MDIO_CLK);
+        NANOSECOND_WAIT(200);
+    }
+
+    mii_data = 0;
+    io_data &= ~MDIO_MASK;          /* Preserve non-MDIO bits */
+    io_data |= (MDIO_RD_ENABLE | MDIO_CLK_MDIP);
+
+    /*
+     * Read the next 18 bits [17:0] in MSB-first order.  The first two
+     * bits, turnaround (TA) high-Z and zero, are effectively ignored.
+     */
+    for (n = 0; n < 18; n++)
+    {
+		// NOTE: When MDIO_CLK_MDIP bit is a zero the data from 
+		// the phy is sampled on the falling edge of the MDIO_CLK.
+		// When MDIO_CLK_MDIP bit is a one the data from the phy
+		// is sampled on the rising edge of the MDIO_CLK.
+
+        // MDIO_CLK falling edge
+		IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data);	
+        NANOSECOND_WAIT(200);
+
+		// MDIO_CLK rising edge
+        IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data | MDIO_CLK); 
+        /*
+         * ??? Shouldn't IO_READ() occur *after* MDC_CLK rising edge?
+         * The IEEE 802.3u specification -- Clause 22.3.4, "MDIO timing
+         * relationship to MDC" and Figure 22-17, "MDIO sourced by
+         * PHY" -- doesn't imply that data is latched on the falling
+         * edge of MDC.  In any case, that is what works with a National
+         * Semiconductor DP83840 PHY, but may be a source of problems
+         * with other PHY devices....
+		 *
+         * IT IS! Data must be sampled on the rising edge for the CX11656
+		 * Home Plug device.
+         */
+        mii_data <<= 1;
+        if (IO_READ(phy->adapter, MAC_MDIO_REG) & MDIO_RD_DATA) {
+            mii_data |= 0x0001;
+        }
+
+        NANOSECOND_WAIT(300);        /* [sic] 300 nSec PHY hold */
+
+    }
+
+    /* Output a single, idle (high-Z, tri-stated) clock transition */
+    MiiIdle(phy, 1);
+
+    return (mii_data & 0xFFFF);
+}
+
+/***********************************************************************
+ * MiiWrite() - write serial data to MII register
+ **********************************************************************/
+void MiiWrite(MIIOBJ *phy, BYTE reg_addr, WORD reg_value)
+{
+    DWORD       io_data;
+    DWORD       mii_frame;
+    DWORD       mask;
+
+    /* Output 32-bit preamble (ones) sequence to re-sync the PHY */
+    MiiPreamble(phy);
+
+    /* Preserve non-MDIO bits in shared MAC_MDIO_REG (SPR) */
+    io_data = IO_READ(phy->adapter, MAC_MDIO_REG) & ~MDIO_MASK;
+
+    /* Form and write 32-bit [31:0] <mii_frame> in MSB-first order */
+    mii_frame = MII_WRITE_FRAME | ((DWORD) phy->mii_addr << 23) |
+        ((DWORD) (reg_addr & 0x1F) << 18) | (DWORD) reg_value;
+    for (mask = 0x80000000UL; mask > 0; mask >>= 1) {
+        io_data &= ~MDIO_MASK;          /* Preserve non-MDIO bits */
+        if (mii_frame & mask) {
+            io_data |= (MDIO_WR_ENABLE | MDIO_WR_DATA_1);
+        } else {
+            io_data |= (MDIO_WR_ENABLE | MDIO_WR_DATA_0);
+        }
+        IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data);
+        NANOSECOND_WAIT(200);
+        IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data | MDIO_CLK);
+        NANOSECOND_WAIT(200);
+    }
+
+    /* Output a single, idle (high-Z, tri-stated) clock transition */
+    MiiIdle(phy, 1);
+}
+
+
+void MiiWriteMask(MIIOBJ *phy, WORD reg_addr, WORD reg_value, WORD mask_value)
+{
+
+	if( mask_value != 0xffff )
+	{
+		reg_value = (MiiRead( phy, (BYTE)reg_addr) & ~mask_value) | (reg_value & mask_value) ;
+	}
+	MiiWrite(phy, (BYTE)reg_addr, reg_value) ;
+}
+/***********************************************************************
+ * MiiPreamble() - Generate 32-bit MII preamble sequence (all ones)
+ **********************************************************************/
+static void
+MiiPreamble(MIIOBJ *phy)
+{
+    DWORD       io_data;
+    int         n;
+
+    /* Preserve non-MDIO bits in shared MAC_MDIO_REG (SPR) */
+    io_data = IO_READ(phy->adapter, MAC_MDIO_REG) & ~MDIO_MASK;
+
+    if (!phy->preamble_suppression) 
+    {
+        io_data |= (MDIO_WR_ENABLE | MDIO_WR_DATA_1);
+#if defined(JEDIPHY) && defined(P52)
+        for (n = 0; n < 64; n++)
+        {
+#else
+        for (n = 0; n < 32; n++)
+        {
+#endif
+            IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data);
+            NANOSECOND_WAIT(200);
+            IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data | MDIO_CLK);
+            NANOSECOND_WAIT(200);
+        }
+    }
+}
+
+/***********************************************************************
+ * MiiIdle() - Generate one or more bits of MII idle sequence (high-Z)
+ **********************************************************************/
+static void MiiIdle(MIIOBJ *phy, int num_clocks)
+{
+    DWORD       io_data;
+
+    /* Preserve non-MDIO bits in shared MAC_MDIO_REG (SPR) */
+    io_data = IO_READ(phy->adapter, MAC_MDIO_REG) & ~MDIO_MASK;
+#if defined(JEDIPHY) && defined(P52)
+    io_data |= (MDIO_RD_ENABLE | MDIO_CLK_MDIP);
+#else
+    io_data |= MDIO_RD_ENABLE;
+#endif
+
+	// need more delay for JEDI phy, tested under Win2K , need 5ms to make 
+	// MiiRead, Write work for JEDI, (Win98 have longer delay for the same API call)
+    do {
+        IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data);
+//        NANOSECOND_WAIT(200);
+        MICROSECOND_WAIT(5);
+        IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data | MDIO_CLK);
+//        NANOSECOND_WAIT(200);
+        MICROSECOND_WAIT(5);
+    } while (--num_clocks > 0);
+}
+
+/***********************************************************************
+ * MiiMillisecondWait() - OS-dependent busy-wait/process sleep wrapper
+ **********************************************************************/
+void
+MiiMillisecondWait(DWORD num_milliseconds)
+{
+    OS_MILLISECOND_WAIT(num_milliseconds);
+}
+
+/***********************************************************************
+ * MiiMicrosecondWait() - OS-dependent busy-wait/process sleep wrapper
+ **********************************************************************/
+void
+MiiMicrosecondWait(DWORD num_microseconds)
+{
+    OS_MICROSECOND_WAIT(num_microseconds);
+}
+
+/***********************************************************************
+ * MiiIoRead() - Export wrapper for the IO_READ() macro
+ **********************************************************************/
+DWORD MiiIoRead( DWORD mac_addr, WORD io_offset)
+{
+    return (IO_READ( mac_addr, io_offset));
+}
+
+/***********************************************************************
+ * MiiIoRead() - Export wrapper for the IO_WRITE() macro
+ **********************************************************************/
+void
+MiiIoWrite( DWORD mac_addr, WORD io_offset, DWORD io_value)
+{
+    IO_WRITE(mac_addr, io_offset, io_value);
+}
+
+#if (DRV_OS == DOS)     /* ########################################## */
+
+/***********************************************************************
+ * MiiSetBits() - Set (logical-OR) one or more bits in MII register
+ **********************************************************************/
+void
+MiiSetBits(MIIOBJ *phy, BYTE reg_addr, WORD bits)
+{
+    MiiWrite(phy, reg_addr, MiiRead(phy, reg_addr) | bits);
+}
+
+/***********************************************************************
+ * MiiClrBits() - Clear (logical-NAND) one or more bits in MII register
+ **********************************************************************/
+void
+MiiClrBits(MIIOBJ *phy, BYTE reg_addr, WORD bits)
+{
+    MiiWrite(phy, reg_addr, MiiRead(phy, reg_addr) & ~bits);
+}
+
+#endif                  /* ########################################## */
diff -urN linux-2.4.29/drivers/net/cnxt_emac/mii.h linux-2.4.29-uc1/drivers/net/cnxt_emac/mii.h
--- linux-2.4.29/drivers/net/cnxt_emac/mii.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/mii.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,140 @@
+/****************************************************************************
+*
+*	Name:			mii.h
+*
+*	Description:	The 100Base-T serial Media Independent Interface (MII),
+*					which defines OS- and adapter-dependent functions imported by
+*  					the PHY driver.  The accompanying "mii.c" module must be
+*					tailored to	adhere to the implementation-dependent environment.
+*
+*	Copyright:		(c) 1997-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+*
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef _MII_H_
+#define _MII_H_
+
+#include "phytypes.h"
+
+
+typedef struct def_MIIOBJ
+{
+	DWORD	 adapter;	// beginning of MAC IO address
+   DWORD  mii_id;		// not use now 
+	WORD   mii_addr;   // Nominal value/usage here 
+	BOOLEAN   preamble_suppression;
+#ifdef P51
+	BOOLEAN P51_HLAN;	// the current mac is P51 HLAN
+#endif
+} MIIOBJ ;
+
+
+/*
+ * Special "adapter" handle for 32-bit Novell ODI drivers.  Most
+ * other drivers assume that the phy->adapter value is simply the
+ * starting I/O port (or memory-mapped) address of the MAC (or repeater)
+ * controller device.
+ */
+typedef struct {
+    void       *dev_addr;       /* MAC's I/O or memory base address */
+    void       *bus_tag;        /* CMSMSearchAdapter() busTag value */
+} PHY_ADAPTER;
+
+
+/*
+ * MII_SET_BIT, MII_SET_MASK(), MII_CLR_BIT(), MII_CLR_MASK()
+ *
+ * Macros which set or clear one or more MII register bits.  In DOS
+ * mode, a few hundred bytes can be saved by calling MiiSetBits()
+ * and MiiClearBits() instead of the in-line MiiRead() and MiiWrite()
+ * calls, as these macros are used extensively.
+ */
+#if (DRV_OS == DOS)     /* ########################################## */
+
+void             MiiSetBits(MIIOBJ *phy, BYTE reg_addr, WORD bits);
+void             MiiClrBits(MIIOBJ *phy, BYTE reg_addr, WORD bits);
+#define MII_SET_MASK    MiiSetBits
+#define MII_CLR_MASK    MiiClrBits
+
+#else                   /* ########################################## */
+
+#define MII_SET_MASK(phy, regaddr, mask)        \
+    MiiWrite((phy),                             \
+             (BYTE) (regaddr),                  \
+             (WORD) (MiiRead((phy), (BYTE) (regaddr)) | (mask)))
+#define MII_CLR_MASK(phy, regaddr, mask)        \
+    MiiWrite((phy),                             \
+             (BYTE) (regaddr),                  \
+             (WORD) (MiiRead((phy), (BYTE) (regaddr)) & ~(mask)))
+#endif                  /* ########################################## */
+
+#define MII_SET_BIT     MII_SET_MASK
+#define MII_CLR_BIT     MII_CLR_MASK
+
+/*
+ * MiiRead(), MiiWrite()
+ *
+ * (MAC or repeater) User-supplied MII read and write functions.  The
+ * PHY's serial MII registers cannot be directly addressed via the
+ * (PCI) bus, as the PHY does not implement a 16-bit parallel register
+ * interface.  Instead, the PHY's serial Media Independent Interface
+ * (MII) must be accessed and accumulated into an external, general
+ * general purpose port, e.g., an MII port on a LAN adapter MAC or
+ * or a repeater controller device.  See the "mii.c" porting file for
+ * implementation-dependent MiiRead() and MiiWrite() example code.
+ */
+WORD     MiiRead(MIIOBJ *phy, BYTE reg_addr);
+void     MiiWrite(MIIOBJ *phy, BYTE reg_addr, WORD reg_value);
+void MiiWriteMask(MIIOBJ *phy, WORD reg_addr, WORD reg_value, WORD mask_value) ;
+
+/*
+ * MILLISECOND_WAIT() and MICROSECOND_WAIT() - hook for implementation
+ * and OS-dependent delay routines defined by the user.  See "mii.c"
+ * MiiMillisecondWait() and MiiMicrosecondWait() functions for
+ * OS-specific example code.  Two functions are declared to allow the
+ * designer to deploy different wait mechanisms.  Short, microsecond
+ * delays may be implemented via a non-blocking, busy-wait mechanism
+ * whereas longer, millisecond delays might relinquish the CPU via
+ * a process or thread sleep mechanism.  Alternately, the millisecond
+ * wait function might just call the microsecond wait function.
+ */
+#ifndef MICROSECOND_WAIT
+#define MICROSECOND_WAIT        MiiMicrosecondWait
+void     MiiMicrosecondWait(DWORD num_microseconds);
+#endif
+#ifndef MILLISECOND_WAIT
+#define MILLISECOND_WAIT        MiiMillisecondWait
+void     MiiMillisecondWait(DWORD num_milliseconds);
+#endif
+
+/*
+ * MiiIoRead() and MiiIoWrite() - export IO_READ() and IO_WRITE()
+ * routines for usage by related functions, 
+ * The <io_offset> is relative to the base address of the associated
+ * MAC or repeater controller device.  The <io_value> read or
+ * written is the 32-bit DWORD I/O register value.
+ */
+DWORD    MiiIoRead( DWORD mac_address, WORD io_offset);
+void     MiiIoWrite(DWORD mac_address, WORD io_offset, DWORD io_value);
+
+#endif /* _MII_H_ */
diff -urN linux-2.4.29/drivers/net/cnxt_emac/osutil.h linux-2.4.29-uc1/drivers/net/cnxt_emac/osutil.h
--- linux-2.4.29/drivers/net/cnxt_emac/osutil.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/osutil.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,133 @@
+/****************************************************************************
+*
+*	Name:			osutil.h
+*
+*	Description:	This header file define all the OS dependent services
+*					required by HPNALL and PHY
+*
+*	Copyright:		(c) 2000-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+*
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef OSUTIL_H_
+#define	OSUTIL_H_
+
+#if defined(NDIS_MINIPORT_DRIVER)
+
+#include <ndis.h>
+//---------------------------------------------------------------
+// NIDS Data Type
+//---------------------------------------------------------------
+
+// #define HANDLE		NDIS_HANDLE			// NDIS handle 
+#define STATUS		NDIS_STATUS
+#define SUCCESS		NT_SUCCESS		// ((NT_STATUS)(Status) >= 0)
+#define FAILURE		NDIS_STATUS_FAILURE
+
+#define H20_ALLOC_MEM(_pbuffer, _length) NdisAllocateMemoryWithTag( \
+    (void *)(_pbuffer), \
+    (_length), \
+    'TXNC')
+
+#define H20_FREE_MEM(_buffer,_length) NdisFreeMemory((_buffer), (_length), 0)
+#define H20_ZERO_MEM(_buffer,_length) NdisZeroMemory((_buffer), (_length))
+
+#ifndef  MOVE_MEMORY
+#define MOVE_MEMORY(Destination,Source,Length)   \
+                         \
+    NdisMoveMemory((PVOID)(Destination),     \
+               (PVOID)(Source),      \
+               (ULONG)(Length)       \
+              )              
+
+#endif
+
+#ifndef  ZERO_MEMORY
+#define ZERO_MEMORY(_buffer,_length) NdisZeroMemory((_buffer), (_length))
+#endif
+
+#elif defined(LINUX_DRIVER)
+#include <linux/slab.h>
+#include <asm/arch/bspcfg.h>
+#include <asm/arch/bsptypes.h>
+
+
+// PORT
+#define AcquireSpinLock( pLock, flags) spin_lock_irqsave( pLock, flags) 
+#define ReleaseSpinLock( pLock, flags) spin_unlock_irqrestore( pLock, flags )
+
+// #define HANDLE		NDIS_HANDLE			// NDIS handle 
+//typedef int STATUS;
+#define SUCCESS(Status)		((STATUS)(Status) != 0)
+#define FAILURE		0
+
+#define H20_ALLOC_MEM(_pbuffer, _length) *(_pbuffer) = (void *)kmalloc( \
+    (_length), \
+    GFP_KERNEL )
+
+#define H20_FREE_MEM(_buffer,_length) kfree( _buffer ) 
+#define H20_ZERO_MEM(_buffer,_length) memset((_buffer), 0, (_length))
+
+#ifndef  MOVE_MEMORY
+#define MOVE_MEMORY(Destination,Source,Length)   \
+                         \
+    memcpy((void *)(Destination),     \
+               (void *)(Source),      \
+               (ULONG)(Length)       \
+              )              \
+
+#endif
+
+#ifndef  ZERO_MEMORY
+#define ZERO_MEMORY(_buffer,_length) memset((_buffer), 0, (_length))
+#endif
+
+#elif defined(VXWORKS_DRIVER)
+#include "vxwinc.h"
+
+// #define HANDLE		NDIS_HANDLE			// NDIS handle 
+// typedef int STATUS ;
+#define SUCCESS(Status)		((STATUS)(Status) != 0)
+#define FAILURE		0
+
+#define H20_ALLOC_MEM(_pbuffer, _length) *(_pbuffer) = (void *)malloc((_length))
+
+#define H20_FREE_MEM(_buffer,_length) free( (_buffer) ) 
+#define H20_ZERO_MEM(_buffer,_length) memset((_buffer), 0, (_length))
+
+#ifndef  MOVE_MEMORY
+#define MOVE_MEMORY(Destination,Source,Length)   \
+                         \
+    memcpy((PVOID)(Destination),     \
+               (PVOID)(Source),      \
+               (ULONG)(Length)       \
+              )              \
+
+#endif
+
+#ifndef  ZERO_MEMORY
+#define ZERO_MEMORY(_buffer,_length) memset((_buffer), 0, (_length))
+#endif
+#endif	
+
+#endif
diff -urN linux-2.4.29/drivers/net/cnxt_emac/phy.c linux-2.4.29-uc1/drivers/net/cnxt_emac/phy.c
--- linux-2.4.29/drivers/net/cnxt_emac/phy.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/phy.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,1770 @@
+/****************************************************************************
+*
+*	Name:			phy.c
+*
+*	Copyright:		(c) 1997-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+*
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 27 2003 13:14:40  $
+****************************************************************************/
+
+/*
+ *  Module Name: phy.c
+ *  Author: Joe Bonaker
+ *
+ *  Copyright © Conexant Systems 1999.
+ *  Copyright © Rockwell Semiconductor Systems 1997-1998.
+ *
+ *  Module Description: 100Base-T PHY driver module.  Consists of PHY
+ *  primitives supported by underlying "mii.c" MII and adapter/OS
+ *  services.  The primary services used are PhyInit() and a periodic
+ *  PhyCheck(), the latter of which can be periodically invoked and/or
+ *  dispatched upon PHY-to-MAC generated interrupt, depending on
+ *  adapter configuration.
+ *
+ *  Conditional Compilation Switches:
+ *
+ *     The following conditional compilation switches apply, and may
+ *     be overridden by the user at compile-time.
+ *
+ *     LINK_DOWN_HOP_COUNT - default 5.  When a multiple-device (i.e.,
+ *     both HomePNA and MII PHY devices populated) PHY experiences
+ *     link down for 5 consecutive calls of PhyCheck(), this routine
+ *     may switch or "hop" ports based on the following logic:
+ *
+ *     select current, "active" port;
+ *     if (++link_down_count > LINK_DOWN_HOP_COUNT) {
+ *         clear link_down_count;
+ *         if (PHY_HWOPTS_PORT_HOPPING) {
+ *             select the other, "inactive" port;
+ *         } else if (PHY_HWOPTS_MII_PORT_PRIORITY) {
+ *             select the MII port;
+ *         } else if (PHY_HWOPTS_HPNA_PORT_PRIORITY) {
+ *             select the HomePNA port;
+ *         } else {
+ *             // retain the current, "active" port;
+ *         }
+ *     }
+ *
+ *     The PHY_HWOPTS_PORT_HOPPING option gives devices which
+ *     cannot function when isolated a chance to achieve a media link.
+ *     Some examples are the 1st generation HomePNA PHY devices plus
+ *     National, Enable and Level One MII PHY devices.  The
+ *     PHY_HWOPTS_HPNA_PORT_PRIORITY option is a good idea when using
+ *     MII PHY devices which can function isolated, such as the TDK,
+ *     QSI, GEC-Plessey, and ICS devices.  This allows the PHY
+ *     Driver to emit MAC-level link test frames on the foreground
+ *     "active" HomePNA PHY to determine a soft link indication while
+ *     the background "inactive" MII PHY attempts to establish its
+ *     hardware link indication.  The PHY_HWOPTS_MII_PORT_PRIORITY
+ *     will effectively preclude HomePNA operation unless used in
+ *     conjunction with PHY_HWOPTS_PORT_HOPPING as a way of
+ *     establishing an initial MII port state, e.g., subsequent to
+ *     DriverReset() where the initial state will be the last known
+ *     link state.
+ *
+ *     PORTABILITY_CHECK - default #undefined.  This should only be
+ *     #defined when initially porting this module to a new compiler/OS
+ *     environment.  This switch enables some simple PhyInit() sizeof()
+ *     tests of BYTE, WORD and DWORD types to ensure proper compiler
+ *     sizing of register-based fields.  Typically, most compilers
+ *     will generate "Unreachable Code" warnings which actually
+ *     indicates proper sizing.  Relaxed warnings or older compilers
+ *     may warrant a run-time check, for which the PhyInit() function
+ *     will return a PHY_STATUS_PORTABILITY_ERROR result.
+ **********************************************************************/
+
+#define PHYOBJECT_MODULE	// this is one of the PHY object module
+#define PHY_MODULE
+
+#include "osutil.h"
+
+#include "phyobj.h"
+#include "phyregs.h"
+
+#ifdef JEDIPHY	// Bright
+#include "ramse.h"
+#include "jediphy.h"
+#endif
+
+
+#define PHYID_KENDIN_KS8737(p)  (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x00221720L)
+
+/* For Kendin KS8993, KS8995 and Marvell 88E6050 which do not support MDIO interface
+ required for MII management channel. */
+#define SUPPORT_NO_MDIO_PHY 1
+
+#ifdef SUPPORT_NO_MDIO_PHY
+#define	NO_MDIO_PHY				0xA0A05050
+#define PHYID_NO_MDIO(p)		(((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == NO_MDIO_PHY)
+#else
+#define PHYID_NO_MDIO(p)		(FALSE)
+#endif
+
+#ifndef LINK_DOWN_HOP_COUNT
+#define LINK_DOWN_HOP_COUNT     5       /* 10 seconds @ 0.5 Hz */
+#endif
+
+PHY_STATUS 	 PhyReset( MIIOBJ *pMiiObj ) ;	// internal interface for jediphy
+
+static PHY_STATUS   PhyDisable(PHY *phy, PHY_PORT port);
+static PHY_STATUS   PhyEnable(PHY  *phy, PHY_PORT port);
+static DWORD        PhyConnectGet(PHY *phy);
+PHY_STATUS   PhyConnectSet(PHY *phy, DWORD connect);
+static PHY_STATUS   PhyConfigurePort(PHY *phy, DWORD link_state);
+static DWORD PhyCapabilityGet(PHY *phy);
+static DWORD PhyLastLinkUp(PHY *phy) ;
+
+#if 0
+/*
+ * PHY test and diagnostic support functions
+ *
+ * PhyLoopback() - Start/stop one of four modes of PHY loopback
+ * PhyColTest()  - Start/stop collision test via register.bit 0.7
+ * PhyIdGet()    - Read PHY Identifier registers 2-3
+ */
+static PHY_STATUS   PhyLoopback(PHY *phy, PHY_LOOPBACK mode);
+static PHY_STATUS   PhyColTest(PHY *phy, BOOLEAN enable);
+#endif
+
+
+/* Local (static) function prototypes */
+static void     ETHParsePhyHwConfig(PHY *phy);
+static void     ETHSetPhyHwOptions(PHY *phy);
+
+PHY * PhyAllocateMemory( void)
+{
+	PHY *pPhy ;
+
+	if( !SUCCESS(H20_ALLOC_MEM( &pPhy, sizeof(PHY) )) )
+		return NULL ;	// allocate fail
+	H20_ZERO_MEM( pPhy, sizeof(PHY) ) ;
+	return (void *)pPhy ;
+}
+
+void PhyFreeMemory( PHY *pPhy )
+{
+	H20_FREE_MEM( pPhy, sizeof(PHY) ) ;
+}
+
+static void Set_Active_Port( PHY *phy, PHY_PORT port )
+{
+	if( port & PHY_PORT_HPNA_DEVICES)
+	{
+		phy->active_port = phy->hpna_port ;
+		phy->inactive_port = phy->mii_port ;
+		phy->pActive_miiphy = &phy->mii_phy[JEDI_MII_PHY];
+#ifdef NON_BYPASSMODE	// test
+		phy->frame_ctl_length = 0 ;
+#else
+		phy->frame_ctl_length = 4 ;
+#endif
+	}
+	else
+	{
+		phy->inactive_port = phy->hpna_port ;
+		phy->active_port = phy->mii_port ;
+		phy->pActive_miiphy = &phy->mii_phy[ETH_MII_PHY];
+		phy->frame_ctl_length = 0 ;
+	}
+}
+
+/* 
+ * Local an_lookup[] table maps BMSR and ANAR hardware to internal,
+ * soft PHY_LINK_* (or associated PHY_CONN_* alias) bit assignments.
+ * The table is ordered in decreasing Auto-Negotiation priority per
+ * IEEE 802.3u and 802.3y, and is terminated by a null (zero) record.
+ * Searches may be keyed on any of the fields, however, <phy_link>
+ * keys should mask out non-PHY_LINK_TECHNOLOGY bits, otherwise the
+ * search may fail to achieve a match.
+ *
+ * This table may have to be extended to include an SNMP MIB field,
+ * which contains yet another enumeration of the PHY technology types.
+ */
+typedef struct {
+    WORD            bmsr;       /* BMSR HW capability bit */
+    WORD            anar;       /* ANAR/ANLPAR HW bit */
+    DWORD           phy_link;   /* internal PHY_LINK_* state */
+}                AN_LOOKUP;
+static AN_LOOKUP an_lookup[] = {
+    {BMSR_100BASE_T2FD, ANAR_100BASE_T2FD,
+     PHY_LINK_100BASE_T2FD | PHY_LINK_100 | PHY_LINK_FDX},
+
+    {BMSR_100BASE_TXFD, ANAR_100BASE_TXFD,
+     PHY_LINK_100BASE_TXFD | PHY_LINK_100 | PHY_LINK_FDX},
+
+    {BMSR_100BASE_T2,   ANAR_100BASE_T2,
+     PHY_LINK_100BASE_T2   | PHY_LINK_100},
+
+    {BMSR_100BASE_T4,   ANAR_100BASE_T4,
+     PHY_LINK_100BASE_T4   | PHY_LINK_100},
+
+    {BMSR_100BASE_TX,   ANAR_100BASE_TX,
+     PHY_LINK_100BASE_TX   | PHY_LINK_100},
+
+    {BMSR_10BASE_TFD,   ANAR_10BASE_TFD,
+     PHY_LINK_10BASE_TFD   | PHY_LINK_10  | PHY_LINK_FDX},
+
+    {BMSR_10BASE_T,     ANAR_10BASE_T,
+     PHY_LINK_10BASE_T     | PHY_LINK_10},
+
+    /* null-terminating record */
+    {0, 0, 0}
+};
+
+
+static PHY_STATUS ETHPhy_SetUp( PHY *phy )
+{
+	if(phy->hw_options & PHY_HWOPTS_NO_ETH_SEARCH)
+		return PHY_STATUS_OK ;
+
+	if (!(phy->hw_options & PHY_HWOPTS_DONT_SWRESET)) 
+		if( PhyReset( &phy->mii_phy[ETH_MII_PHY]) != PHY_STATUS_OK)
+			return PHY_STATUS_RESET_ERROR;
+
+	/* Terminate upon successful reset(s) or excess restarts */
+	phy->devices |= PHY_PORT_MII_DEVICE;
+	phy->mii_port = PHY_PORT_MII;
+
+	ETHParsePhyHwConfig( phy );
+	ETHSetPhyHwOptions( phy );
+
+	MII_CLR_MASK( &phy->mii_phy[ETH_MII_PHY], MII_BMCR, (BMCR_RESTART_AUTONEG |
+		BMCR_POWERDOWN  |
+		BMCR_LOOPBACK   |
+		BMCR_COLLISION_TEST) );
+
+	return PHY_STATUS_OK ;
+}
+
+#define MAX_PHY_NUM	2		// assume at most 1 ETH and 1 JEDI
+#define SINGLE_PHY	1			// Bright, 4/27/01, only one PHY on one EMAC (MII BUS)
+// currently this is ture
+
+#if HOMEPLUGPHY
+
+// TBD , need improvement	
+#define HOMEPLUGID 0xffffffff
+#endif
+
+PHY_STATUS
+MiiDetectPorts( PHY   *phy,             /* allocated PHY data structure space */
+        BYTE   phy_addr ) 
+{
+	BYTE        last_addr;
+	WORD        bmsr;
+	int	num_phy = 0 ;
+	int	num_of_eth_phy = 0 ;
+	DWORD  hw_options = phy->hw_options ;
+	MIIOBJ TmpMii ;
+
+    /*
+     * MII search, reset and optionally disable (isolate) PHY.  The
+     * search logic simply reads the BMSR, for which a responding PHY
+     * should return a value that is non-zero and not all one's.
+     * Otherwise, assume there isn't an MII-capable PHY at <phy_addr>.
+     * The ANAR probe is repeated after post-HW and/or software reset to
+     * guard against the PHY losing its identity (address) upon reset.
+     *
+     * If the caller specified PHY_ADDR_ANY or PHY_ADDR_NEXT(phy#), 
+     * we'll walk the list of valid PHY addresses until the first/next
+     * responding PHY is detected.  Some PHY devices have side-effects
+     * associated with PHY_ADDR_MIN (zero) -- this address is often
+     * (erroneously) treated as a broadcast by some PHYs, others
+     * won't display vendor-specific registers when reading from
+     * address-0, etc.  As such, we'll initiate a PHY_ADDR_ANY search
+     * from (PHY_ADDR_MIN + 1) on up to PHY_ADDR_MAX, concluding the
+     * search using PHY_ADDR_MIN only if no other addresses are found.
+     * This can be overriden by the PHY_HWOPTS_MII_SEARCH_0 <hw_options>
+     * switch, which initiates a search from address 0..31, rather
+     * than the default 1..31 followed by 0.
+     */
+
+#ifdef P51
+	// the driver can run on ELAN or HLAN under Yukon or Athens
+	if(hw_options & PHY_HWOPTS_P51_HLAN) 
+		TmpMii.P51_HLAN = TRUE ;
+	else
+		TmpMii.P51_HLAN = FALSE ;
+#endif
+	TmpMii.adapter = phy->mii_phy[JEDI_MII_PHY].adapter ;
+	TmpMii.preamble_suppression = FALSE ;
+	phy->pActive_miiphy = &phy->mii_phy[JEDI_MII_PHY];	// set default
+
+	if (phy_addr == PHY_ADDR_ANY) 
+	{
+		last_addr = PHY_ADDR_MAX;
+		phy_addr  = PHY_ADDR_MIN + 1;    /* start search at address-1 */
+		if (hw_options & PHY_HWOPTS_MII_SEARCH_0) 
+			--phy_addr;                 /* start search at address-0 */
+	} 
+	else if( phy_addr <= PHY_ADDR_MAX ) 
+	{
+		last_addr = phy_addr;          /* single MII search, below */
+	} 
+	else 
+	{
+		phy_addr = -phy_addr;         /* partial? MII search per */
+		last_addr  = PHY_ADDR_MAX;      /* phy.h PHY_ADDR_NEXT() */
+	}
+
+Search_Mii :
+	while (phy_addr <= last_addr) 
+	{
+		TmpMii.mii_addr = phy_addr++;
+		if (((bmsr = MiiRead(&TmpMii, MII_BMSR)) != 0x0000) &&
+			(bmsr != 0xFFFF)) 
+		{	/* Assume PHY found, so nominally perform post-SW reset */
+			num_phy++ ;
+
+			TmpMii.mii_id = (((DWORD) MiiRead(&TmpMii, MII_PHYIDR1) << 16) |
+			((DWORD) MiiRead(&TmpMii, MII_PHYIDR2)));
+
+			printk("PHY #%x = %lx\n", phy_addr,TmpMii.mii_id );
+
+#ifdef JEDIPHY	// Bright
+			if( JediPhy(TmpMii.mii_id) )
+			{	// this is Jedi Phy (HPNA2)
+				phy->mii_phy[JEDI_MII_PHY] = TmpMii ;
+				JediPhy_SetUp( phy) ;
+#ifndef SINGLE_PHY
+				if(hw_options & PHY_HWOPTS_NO_ETH_SEARCH)
+#endif
+					return PHY_STATUS_OK ;
+			}
+			else
+#endif
+			{	// assume this is Ether Phy
+				if( num_of_eth_phy == 0 )
+				{
+					phy->mii_phy[ETH_MII_PHY] = TmpMii ;
+					phy->pActive_miiphy = &phy->mii_phy[ETH_MII_PHY];
+					ETHPhy_SetUp( phy ) ;	
+
+#ifndef SINGLE_PHY
+					if(hw_options & PHY_HWOPTS_NO_HPNA_SEARCH)
+#endif
+						return PHY_STATUS_OK ;
+				}
+				num_of_eth_phy++ ;
+			}
+		}
+		if( num_phy == MAX_PHY_NUM )
+			return PHY_STATUS_OK ;
+	}
+
+	/* Go back to addr-0 once full MII search 1..31 fails */
+	if ((phy_addr == (PHY_ADDR_MAX+1)) &&
+		!(hw_options & PHY_HWOPTS_MII_SEARCH_0)) 
+	{
+		phy_addr = last_addr = PHY_ADDR_MIN ;
+		goto Search_Mii ;
+	}
+	
+	if( num_phy != 0 )
+		return PHY_STATUS_OK ;
+	else
+		return PHY_STATUS_NOT_FOUND ;
+}
+/***********************************************************************
+ * PhyInit() - Initialize PHY and attach to media (w/optional override)
+		PhyInit do not	perform hardware reset of the PHYs. 
+		Hardware reset is MAC operation, should be called before PhyInit(if required).
+ **********************************************************************/
+PHY_STATUS
+PhyInit(DWORD  adapter,         /* MAC device I/O base address */
+        PHY   *phy,             /* allocated PHY data structure space */
+        DWORD  connect,         /* PhyConnectSet() directive */
+        DWORD  hw_options,      /* zero or more PHY_HWOPTS_* values */
+        void  *LinkLayerAdapter )	// for HPNA 2.0 LL compliance
+{
+    PHY_STATUS  status;
+
+#ifdef PORTABILITY_CHECK        /* ################################## */
+    /* Not a bad idea during initial PHY driver porting effort */
+    if ((sizeof(BYTE) != 1) ||
+            (sizeof(WORD) != 2) || (sizeof(DWORD) != 4)) {
+        return (PHY_STATUS_PORTABILITY_ERROR);
+    }
+#endif  /* PORTABILITY_CHECK */ /* ################################## */
+
+
+	if( IS_PHY_INITIALIZED(phy) )
+	{	// not first time PHY Init
+		if( !(PhyCapabilityGet(phy) & PHY_LINK_MII_TECHNOLOGY ) )
+		{
+			/* No MII PHY, so don't waste time searching henceforth */
+			hw_options |= PHY_HWOPTS_NO_ETH_SEARCH;
+		}
+		else
+		{
+			if( phy->mii_phy[ETH_MII_PHY].mii_addr == PHY_ADDR_0) 
+			{
+					/*
+					 * Reduce subsequent PhyInit() MII search times by
+					 * starting at MII address zero.  The default sequence
+					 * is 1..31 then zero due to some funky side-effects
+					 * on some MII PHY devices.  This option re-orders the
+					 * search sequence to 0..31, thereby reducing
+					 * subsequent PhyInit() times by a few hundred milliseconds!
+					 */
+				hw_options |= PHY_HWOPTS_MII_SEARCH_0;
+			}
+		}
+
+		if (!(PhyCapabilityGet(phy) & PHY_LINK_HPNA_TECHNOLOGY)) 
+			/* No HomePNA PHY, so don't waste time searching henceforth */
+			hw_options |= PHY_HWOPTS_NO_HPNA_SEARCH;
+		else
+		{
+			if( phy->mii_phy[JEDI_MII_PHY].mii_addr == PHY_ADDR_0) 
+			{
+					/*
+					 * Reduce subsequent PhyInit() MII search times by
+					 * starting at MII address zero.  The default sequence
+					 * is 1..31 then zero due to some funky side-effects
+					 * on some MII PHY devices.  This option re-orders the
+					 * search sequence to 0..31, thereby reducing
+					 * subsequent PhyInit() times by a few hundred milliseconds!
+					 */
+				hw_options |= PHY_HWOPTS_MII_SEARCH_0;
+			}
+		}
+
+		if (PhyLastLinkUp(phy) & PHY_LINK_MII_TECHNOLOGY)
+		{
+			/* Last known link was MII, so pre-hop default to MII port */
+			hw_options |= (PHY_HWOPTS_MII_PORT_PRIORITY |
+						   PHY_HWOPTS_PORT_HOPPING);
+		} 
+		else if (PhyLastLinkUp(phy) & PHY_LINK_HPNA_TECHNOLOGY) 
+		{
+			/* Last known link was HLAN, so don't pre-hop default to MII port */
+			hw_options &= ~PHY_HWOPTS_MII_PORT_PRIORITY;
+		}
+	} 
+
+
+    /*
+     * Set-up <phy> data and perform optional pre-MII search HW reset,
+     * which may be required only in the case of unusual adapter design.
+     * This case has been included to satisfy the RSS11606 test adapter
+     * board, wherein a MAC general purpose I/O (GPIO) pin holds the PHY
+     * in hardware reset.  Unless programmed to release the PHY prior to
+     * searching the MII bus, the subsequent MII search will fail, as
+     * the PHY obviously cannot respond when held in hardware reset.
+     *
+     * Bug warning:  unless there's a crafty HW design, this could
+     * cause unexpected failures in a multiple-PHY environment if
+     * PHY_ADDR_ANY or PHY_ADDR_NEXT() is specified to search for a
+     * responding PHY.  For now, we'll simply do as we're told.  This
+     * should probably be moved into the search loop below, and rely
+     * upon a PHY_HWRESET() routine that parses the phy_addr argument...
+     */
+#ifdef JEDIPHY	// Bright
+	H20_ZERO_MEM( phy, sizeof(PHY)-sizeof(OSFILEOBJ) ) ;
+#else
+	H20_ZERO_MEM( phy, sizeof(PHY) ) ;
+#endif
+
+//    if (hw_options & PHY_HWOPTS_READ_ONLY) {
+//        phy->read_only = TRUE;
+//    }
+    phy->mii_phy[JEDI_MII_PHY].adapter = adapter ;
+    phy->mii_phy[ETH_MII_PHY].adapter = adapter ;
+
+    phy->LinkLayerAdapter = LinkLayerAdapter ;
+
+
+//    if ( (hw_options & PHY_HWOPTS_HWRESET_MASK) &&
+//		 (hw_options & PHY_HWOPTS_GP0_SPI_DOUT) ) 
+//        PHY_HWRESET( adapter );
+
+	phy->hw_options = hw_options;
+
+	status = MiiDetectPorts( phy, PHY_ADDR_ANY) ;
+
+	if( status != PHY_STATUS_OK )
+	{
+#ifdef SUPPORT_NO_MDIO_PHY
+		// TBD : not tested yet
+		phy->mii_phy[ETH_MII_PHY].mii_id = NO_MDIO_PHY;
+        phy->initialized = PHY_INIT_CODE;
+		phy->media.capability = PHY_LINK_100BASE_TXFD |
+								PHY_LINK_100BASE_T2FD | 
+								PHY_LINK_100 | 
+								PHY_LINK_FDX;
+		phy->media.connect = PHY_CONN_MII_TECHNOLOGY;
+		phy->devices |= PHY_PORT_MII_DEVICE;
+		phy->mii_port = PHY_PORT_MII;
+
+		Set_Active_Port( phy, phy->mii_port ) ;		
+	    status = PHY_STATUS_OK;
+#endif
+		return status ;
+	}
+
+#if HOMEPLUGPHY
+	if( phy->pActive_miiphy->mii_id == HOMEPLUGID )
+	{
+		connect = PHY_CONN_100BASE_TX ;		// HomePlug as 100 half
+	}	
+#endif
+
+	if( hw_options & PHY_HWOPTS_ISOLATE )
+		PhyDisable(phy, phy->devices);
+
+	if (phy->mii_port == PHY_PORT_NONE) 
+	{
+		/* Coerce soft non-MII Auto-Negotiation capability */
+		phy->media.capability |= PHY_LINK_AUTONEG;
+		phy->media.connect    |= PHY_CONN_AUTONEG;
+	}
+
+	if ((status = PhyConnectSet(phy, connect)) == PHY_STATUS_OK) 
+	{
+		phy->initialized = PHY_INIT_CODE;
+		phy->hw_options &= ~PHY_HWOPTS_ISOLATE;
+	}
+	return (status);
+}
+
+/***********************************************************************
+ * ParsePhyHwConfig() - Process PHY HW configuration options
+ **********************************************************************/
+static void
+ETHParsePhyHwConfig(PHY *phy)
+{
+    WORD        bmcr;
+    WORD        bmsr;
+    WORD        anar;
+    DWORD       mode;
+    AN_LOOKUP  *lookup;
+
+// no need
+//    phy->media.capability = 0;
+//    phy->media.connect = 0;
+
+    /* Determine media capabilities based on BMSR */
+    bmsr = MiiRead( &phy->mii_phy[ETH_MII_PHY], MII_BMSR);
+    if (bmsr & BMSR_AUTONEG_ABILITY) {
+        phy->media.capability |= PHY_LINK_AUTONEG;
+    }
+    for (lookup = &an_lookup[0]; lookup->bmsr != 0; lookup++) {
+        if (bmsr & lookup->bmsr)
+        {
+            phy->media.capability |= (lookup->phy_link & PHY_LINK_TECHNOLOGY);
+        }
+    }
+
+    /*
+     * Determine adapter (NIC) unique HW configuration strap
+     * settings based on BMCR (and ANAR if Auto-Negotiation is enabled).
+     */
+    bmcr = MiiRead( &phy->mii_phy[ETH_MII_PHY], MII_BMCR);
+    if (bmcr & BMCR_AUTONEG_ENABLE) {
+        /* Read default Auto-Negotiation configuration per ANAR */
+        phy->media.connect |= PHY_CONN_AUTONEG;
+        anar = MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_ANAR);
+        for (lookup = &an_lookup[0]; lookup->anar != 0; lookup++) {
+            if (anar & lookup->anar) {
+                phy->media.connect |=
+                    (lookup->phy_link & PHY_LINK_TECHNOLOGY);
+            }
+        }
+    } else {
+        /* Infer default forced mode configuration per BMCR */
+        mode = 0;
+        if (bmcr & BMCR_SPEED_100) {
+            mode |= PHY_LINK_100;
+        } else {
+            mode |= PHY_LINK_10;
+        }
+        if (bmcr & BMCR_DUPLEX_MODE) {
+            mode |= PHY_LINK_FDX;
+        }
+        for (lookup = &an_lookup[0]; lookup->phy_link != 0; lookup++) {
+            if ((phy->media.capability & lookup->phy_link) &&
+                    (mode == (lookup->phy_link &
+                              (PHY_LINK_SPEED | PHY_LINK_FDX)))) {
+                phy->media.connect |= lookup->phy_link;
+                break;
+            }
+        }
+    }
+
+    /* Check for isolated (tri-stated) MII PHY */
+    if (bmcr & BMCR_ISOLATE) {
+        phy->mii_isolated = TRUE;
+    }
+
+    /* 
+     * Finally, set <preamble_suppression> if suported by the device.
+     * This can subsequently be overriden by SetPhyHwOptions()
+     * via the PHY_HWOPTS_MII_PREAMBLE directive, which may be used
+     * in a multi-PHY environment or in case a device's BMSR register
+     * falsely indicates preamble suppression capability.
+     */
+    if (bmsr & BMSR_PREAMBLE_SUPPRESS) {
+        phy->mii_phy[ETH_MII_PHY].preamble_suppression = TRUE;
+    }
+}
+
+/***********************************************************************
+ * SetPhyHwOptions() - Configure non-default MII PHY hardware features
+ **********************************************************************/
+// ETH only
+static void
+ETHSetPhyHwOptions(PHY *phy)
+{
+    DWORD hw_opts = phy->hw_options ;
+
+    /* Force MDIO preamble, i.e., explicitly disable suppression */
+    if (hw_opts & PHY_HWOPTS_MII_PREAMBLE) {
+        phy->mii_phy[ETH_MII_PHY].preamble_suppression = FALSE;
+    }
+
+    if (PHYID_NSC_DP83840(phy)) {
+        /* Force node or repeater mode, which affects CRS signal */
+        if (hw_opts & PHY_HWOPTS_REPEATER) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_PCR, PCR_REPEATER_MODE);
+        } else {
+            MII_CLR_BIT(&phy->mii_phy[ETH_MII_PHY], MII_PCR, PCR_REPEATER_MODE);
+        }
+
+        /* Disable CLK25 output line, reducing noise when unused */
+        if (hw_opts & PHY_HWOPTS_CK25DIS) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_PCR, PCR_CLK25DIS);
+        }
+
+        /* Bypass portions of the transmitter and receiver coding */
+        if (hw_opts & PHY_HWOPTS_TX_BPALIGN) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_LBREMR, LBREMR_BP_ALIGN);
+        }
+        if (hw_opts & PHY_HWOPTS_TX_BPSCR) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_LBREMR, LBREMR_BP_SCR);
+        }
+        if (hw_opts & PHY_HWOPTS_TX_BP4B5B) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_LBREMR, LBREMR_BP_4B5B);
+        }
+
+        /* Assert FDX CRS during transmit, not receive (default) */
+        if (hw_opts & PHY_HWOPTS_FDX_CRS) {
+            if (PHYID_REV(phy) >= 1) {
+                /* New NSC DP83840 Rev A (revision code 1) feature */
+                MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_LBREMR, LBREMR_ALT_CRS);
+            }
+        }
+
+    } else if (PHYID_QSI_6612(phy)) {
+        /* Bypass portions of the transmitter and receiver coding */
+        if (hw_opts & PHY_HWOPTS_TX_BPALIGN) {
+            /* No QSI support for bypassing the alignment function */
+        }
+        if (hw_opts & PHY_HWOPTS_TX_BPSCR) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R31, QSI_R31_SCR_DISABLE);
+        }
+        if (hw_opts & PHY_HWOPTS_TX_BP4B5B) {
+            MII_CLR_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R31, QSI_R31_4B5BEN);
+        }
+
+    } else if (PHYID_LXT_970(phy)) {
+        /* Bypass portions of the transmitter and receiver coding */
+        if (hw_opts & PHY_HWOPTS_TX_BPALIGN) {
+            /* No Level One support for bypassing alignment function */
+        }
+        if (hw_opts & PHY_HWOPTS_TX_BPSCR) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R19, LXT_R19_SCR_BYPASS);
+        }
+        if (hw_opts & PHY_HWOPTS_TX_BP4B5B) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R19, LXT_R19_4B5B_BYPASS);
+        }
+
+    } else if (PHYID_GEC_NWK936(phy)) {
+        /* Bypass portions of the transmitter and receiver coding */
+        if (hw_opts & PHY_HWOPTS_TX_BPALIGN) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R24, GEC_R24_BPALIGN);
+        }
+        if (hw_opts & PHY_HWOPTS_TX_BPSCR) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R24, GEC_R24_BPSCR);
+        }
+        if (hw_opts & PHY_HWOPTS_TX_BP4B5B) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R24, GEC_R24_BPENC);
+        }
+
+        /* Assert FDX CRS during transmit, not receive (default) */
+        if (!(hw_opts & PHY_HWOPTS_FDX_CRS)) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], 24, 0x0800);
+        }
+
+    } else if (PHYID_TDK_2120(phy)) {
+        /* Force node or repeater mode, which affects CRS signal */
+        if (hw_opts & PHY_HWOPTS_REPEATER) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R16, TDK_R16_RPTR);
+        } else {
+            MII_CLR_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R16, TDK_R16_RPTR);
+        }
+
+        /*
+         * Disable CLK25 output line, reducing noise when unused.  Due
+         * to Auto-Negotiation side-effects, the TDK RXCC option is
+         * now performed by PhyCheck() on link up and down transitions.
+         *
+         * if (hw_opts & PHY_HWOPTS_CK25DIS) {
+         *     MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R16, TDK_R16_RXCC);
+         * }
+         */
+
+        /* Bypass portions of the transmitter and receiver coding */
+        if (hw_opts & (PHY_HWOPTS_TX_BPSCR | PHY_HWOPTS_TX_BP4B5B)) {
+            /* TDK PHY doesn't have separate PCS, scrambler bypass */
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R16, TDK_R16_PCSBP);
+        }
+    }
+}
+
+/***********************************************************************
+ * PhyReset() - Issue PHY software reset, waiting 500 mSec to complete
+ **********************************************************************/
+PHY_STATUS 	 PhyReset( MIIOBJ *pMiiObj ) 
+{
+    PHY_STATUS  phy_status = PHY_STATUS_RESET_ERROR;
+    int         n;
+
+    /*
+     * Set BMCR Reset bit, expected to auto-clear in 500 milliseconds
+     * Some devices may require a 500-microsecond guard against serial
+     * MII access, so we'll delay after setting the reset bit and after
+     * detecting auto-clear, just to be safe.
+     */
+    MII_SET_BIT(pMiiObj, MII_BMCR, BMCR_RESET);
+    MICROSECOND_WAIT(500);
+    for (n = 0; n < 50; n++) {
+        if (!(MiiRead( pMiiObj, MII_BMCR) & BMCR_RESET)) {
+            phy_status = PHY_STATUS_OK;
+            break;
+        }
+        MILLISECOND_WAIT(10);
+    }
+    MICROSECOND_WAIT(500);
+    return (phy_status);
+}
+
+
+/***********************************************************************
+ * PhyDisable() - Disable PHY by asserting BMCR isolate command
+ **********************************************************************/
+PHY_STATUS
+PhyDisable(PHY *phy, PHY_PORT port)
+{
+
+    /* (1) Validate the selected port(s) */
+    port &= phy->devices;
+
+    /* (2) MII PMD isolation (TP tri-state) */
+    if (port & PHY_PORT_MII_PMD) {
+        if (PHYID_QSI_6612(phy)) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R31, QSI_R31_TX_ISOLATE);
+        } else if (PHYID_LXT_970(phy)) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R19, LXT_R19_TX_DISCONNECT);
+        }
+    }
+
+    /* (3) MII data isolation (tri-state) */
+    if ((port & PHY_PORT_MII) && !phy->mii_isolated) {
+        phy->mii_isolated = TRUE;
+        MII_SET_BIT( &phy->mii_phy[ETH_MII_PHY], MII_BMCR, BMCR_ISOLATE);
+    }
+
+#ifdef JEDIPHY	// Bright
+	 JediPhyDisable( phy, port) ;
+#endif
+
+    return (PHY_STATUS_OK);
+}
+
+/***********************************************************************
+ * PhyEnable() - (Re)Enable PHY by deasserting BMCR isolate command
+ **********************************************************************/
+PHY_STATUS
+PhyEnable(PHY *phy, PHY_PORT port)
+{
+    WORD        bmcr;
+
+    /* (1) Validate the selected port(s) */
+    port &= phy->devices;
+
+    /* (2) MII PMD de-isolation (TP non tri-state) */
+    if (port & PHY_PORT_MII_PMD) {
+        if (PHYID_QSI_6612(phy)) {
+            MII_CLR_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R31, QSI_R31_TX_ISOLATE);
+        } else if (PHYID_LXT_970(phy)) {
+            MII_CLR_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R19, LXT_R19_TX_DISCONNECT);
+        }
+    }
+
+    /* (3) MII data de-isolation (no longer tri-stated) */
+    if ((port & PHY_PORT_MII) && phy->mii_isolated) {
+        phy->mii_isolated = FALSE;
+			// Bright fixed 7/18/02
+        bmcr = MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_BMCR) & 
+			~(BMCR_ISOLATE |BMCR_POWERDOWN) ;
+        if (phy->media.connect & PHY_CONN_AUTONEG) {
+            bmcr |= (BMCR_AUTONEG_ENABLE | BMCR_RESTART_AUTONEG);
+            /*
+             * Side-effect:  some PHYs (well, at least one vendor's)
+             * require the BMCR_AUTONEG_ENABLE bit (reg 0.12) be cleared
+             * then set in the case where the device is coming up out
+             * of reset or isolated state, otherwise, Auto-Negotiation
+             * won't be initiated.  We'll temporarily clear A-N bits,
+             * which will then be immediately be set, below.
+             */
+            if (PHYID_NSC_DP83840(phy) ||
+                    (phy->hw_options & PHY_HWOPTS_ACTIVE_AN_RESTART)) {
+                MiiWrite(&phy->mii_phy[ETH_MII_PHY], MII_BMCR,
+                         (WORD) (bmcr & ~(BMCR_AUTONEG_ENABLE |
+                                          BMCR_RESTART_AUTONEG)));
+            }
+        }
+        MiiWrite(&phy->mii_phy[ETH_MII_PHY], MII_BMCR, bmcr);
+    }
+
+#ifdef JEDIPHY	// Bright
+	JediPhyEnable(phy, port) ;
+#endif
+    return (PHY_STATUS_OK);
+}
+
+/***********************************************************************
+ * PhyConnectGet() - Get PHY connect setting(s)
+ **********************************************************************/
+DWORD
+PhyConnectGet(PHY *phy)
+{
+    return (phy->media.connect);
+}
+
+/***********************************************************************
+ * PhyConnectSet() - Execute PHY connect settings
+ **********************************************************************/
+PHY_STATUS
+PhyConnectSet(PHY *phy, DWORD connect)
+{
+    WORD        bmcr;
+    WORD        anar;
+    AN_LOOKUP  *lookup;
+
+    /* (1) Establish/adjust the <connect> directive */
+    switch (connect & (PHY_CONN_AUTONEG | PHY_CONN_TECHNOLOGY)) {
+        default:
+            /* Use non-zero <connect> directive as-is */
+            break;
+
+        case PHY_CONN_CURRENT:
+            /* Zero: use HW default or previous setting */
+            connect = phy->media.connect; break;
+
+        case PHY_CONN_AUTONEG:
+            /* A-N bit only: Auto-Negotiate HW default or previous */
+            connect = phy->media.connect | PHY_CONN_AUTONEG; break;
+    }
+
+    if (phy->hw_options & PHY_HWOPTS_STRICT_PARM_CHECKING) {
+        /* Strict checking:  A-N and full media agreement required */
+        if ((connect & (PHY_CONN_AUTONEG | PHY_CONN_TECHNOLOGY)) !=
+                (connect & phy->media.capability)) {
+            return (PHY_STATUS_UNSUPPORTED_MEDIA);
+        }
+
+    } else {
+        /* Relaxed checking:  A-N and partial media agreement needed */
+        if (((connect & PHY_CONN_AUTONEG)
+             && !(phy->media.capability & PHY_CONN_AUTONEG)) ||
+            ((connect & PHY_CONN_TECHNOLOGY) &&
+             !(connect & phy->media.capability &
+               PHY_CONN_TECHNOLOGY))) {
+            return (PHY_STATUS_UNSUPPORTED_MEDIA);
+        }
+        /* Truth in advertising:  shave unsupported media settings */
+        connect &= (phy->media.capability | ~PHY_CONN_TECHNOLOGY);
+    }
+
+#ifdef JEDIPHY	// Bright
+    /* (2) HomePNA device: force highest-priority setting */
+	connect = JediPhyConnectSet(phy, connect) ;
+#endif
+
+    /* (3) MII device: Auto-Negotiate or force highest capability */
+    if (connect & PHY_CONN_MII_TECHNOLOGY) {
+
+        /* Read BMCR, momentarily clearing speed and duplex bits */
+        bmcr = MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_BMCR) &
+            ~(BMCR_SPEED_100 | BMCR_DUPLEX_MODE);
+
+        if (connect & PHY_CONN_AUTONEG) {
+            /*
+             * Auto-Negotiation connection mode.  Walk the entire
+             * an_lookup[] table, latching all matching <phy_link> types
+             * into the PHY's Auto-Negotiation Advertisement Register
+             * (ANAR).  Set ANAR and BMCR when the table is exhausted.
+             */
+            bmcr |= (BMCR_AUTONEG_ENABLE | BMCR_RESTART_AUTONEG);
+            anar = MiiRead( &phy->mii_phy[ETH_MII_PHY], MII_ANAR) &
+                (ANAR_NEXT_PAGE | /* ANAR_ACKNOWLEDGE | */
+                 ANAR_PROTOCOL_SELECTOR);
+            if (connect & PHY_CONN_AUTONEG_REMOTE_FAULT)
+                anar |= ANAR_REMOTE_FAULT;
+            if (connect & PHY_CONN_AUTONEG_FDX_PAUSE)
+                anar |= ANAR_FDX_PAUSE;
+            for (lookup = &an_lookup[0]; lookup->phy_link != 0; lookup++) {
+                if (connect & lookup->phy_link & PHY_CONN_TECHNOLOGY)
+                    anar |= lookup->anar;
+            }
+            MiiWrite( &phy->mii_phy[ETH_MII_PHY], MII_ANAR, anar);
+            phy->anar = anar;       /* cached for PhyCheck() */
+            /*
+             * Side-effect:  some PHYs (well, at least one vendor's)
+             * require the BMCR_AUTONEG_ENABLE bit (reg 0.12) be cleared
+             * and then set in the case where the device is coming up out
+             * of reset or isolated state, otherwise, Auto-Negotiation
+             * won't be initiated.  We'll temporarily clear the A-N bits,
+             * which will then be immediately be set, below.
+             */
+            MiiWrite( &phy->mii_phy[ETH_MII_PHY], MII_BMCR,
+                     (WORD) (bmcr & ~(BMCR_AUTONEG_ENABLE |
+                                      BMCR_RESTART_AUTONEG)));
+
+        } else {
+            /*
+             * Forced connect mode.  Walk the an_lookup[] table until a
+             * matching <phy_link> type is found.  Set BMCR accordingly
+             * and terminate the loop.  Doesn't yet support a dual -T2/-TX
+             * device (R7145 is TBD), which likely requires an additional
+             * control to select the desired 100Base-T PMA technology.
+             */
+            bmcr &= ~(BMCR_AUTONEG_ENABLE | BMCR_RESTART_AUTONEG);
+            for (lookup = &an_lookup[0]; lookup->phy_link != 0; lookup++) {
+                if (connect & lookup->phy_link & PHY_CONN_TECHNOLOGY) {
+                    connect = lookup->phy_link & PHY_CONN_TECHNOLOGY;
+                    if (lookup->phy_link & PHY_LINK_FDX)
+                        bmcr |= BMCR_DUPLEX_MODE;
+                    if (lookup->phy_link & PHY_LINK_100)
+                        bmcr |= BMCR_SPEED_100;
+                    break;
+                }
+            }
+        }
+
+        /* Issue the MII BMCR hardware command */
+        MiiWrite(&phy->mii_phy[ETH_MII_PHY], MII_BMCR, bmcr);
+
+        /* National PHY bug:  kick (read) PHY to restart A-N (?) */
+        if ((connect & PHY_CONN_AUTONEG) && PHYID_NSC_DP83840(phy)) {
+            (void) MiiRead( &phy->mii_phy[ETH_MII_PHY], MII_BMCR);
+        }
+    }
+
+    /*
+     * (4) Select default MII/HPNA ports to activate/enable and
+     *     deactivate/disable.  If Auto-Negotiating both HomePNA
+     *     and MII ports, activate the HomePNA port unless MII
+     *     priority is specified.  If forcing or Auto-Negotiating
+     *     a single port, then activate that port.
+     */
+	 Set_Active_Port( phy, phy->hpna_port ) ;
+
+    if ((connect & PHY_CONN_MII_TECHNOLOGY) &&
+            (connect & PHY_CONN_HPNA_TECHNOLOGY)) {
+        /* Both ports active */
+        if (connect & PHY_CONN_AUTONEG) {
+            if (phy->hw_options & PHY_HWOPTS_MII_PORT_PRIORITY) {
+                /* Auto-Negotiating and MII priority option */
+                Set_Active_Port( phy, phy->mii_port ) ;
+            }
+
+        } else {
+            /* Forced connections: disable lower priority port */
+            if (phy->hw_options & PHY_HWOPTS_HPNA_PORT_PRIORITY) {
+                connect &= ~PHY_CONN_MII_TECHNOLOGY;
+            } else {
+                connect &= ~PHY_CONN_HPNA_TECHNOLOGY;
+                Set_Active_Port( phy, phy->mii_port ) ;
+            }
+        }
+
+    } else if (connect & PHY_CONN_MII_TECHNOLOGY) {
+        Set_Active_Port( phy, phy->mii_port ) ;
+    }
+
+    /* (5) Shave unused, residual <connect> settings and save */
+    connect &= (PHY_CONN_AUTONEG              |
+                PHY_CONN_AUTONEG_REMOTE_FAULT |
+                PHY_CONN_AUTONEG_FDX_PAUSE    |
+                PHY_CONN_TECHNOLOGY);
+    if (!(connect & PHY_CONN_AUTONEG) ||
+            !(connect & PHY_CONN_MII_TECHNOLOGY)) {
+        connect &= ~(PHY_CONN_AUTONEG_REMOTE_FAULT |
+                     PHY_CONN_AUTONEG_FDX_PAUSE);
+    }
+    phy->media.connect = connect;
+    phy->media.cum_link_state      =
+        phy->media.hpna_link_state =
+        phy->media.mii_link_state  = 0;
+
+    /*
+     * (6) Activate/deactivate selected ports whenever called from
+     *     PhyInit().  
+     */
+    if(!(phy->hw_options & PHY_HWOPTS_ISOLATE)) {
+        PhyConfigurePort(phy, phy->media.cum_link_state);
+    }
+    
+    return (PHY_STATUS_OK);
+}
+
+/***********************************************************************
+ * PhyConfigurePort() - Configure PHY (and optional MAC) port settings
+ **********************************************************************/
+#if 0
+	#include "macphy.h"
+#endif
+
+PHY_STATUS
+PhyConfigurePort(PHY *phy, DWORD link_state)
+{
+	BOOLEAN 			Port_Mii, Speed100m, Full_Duplex ;
+
+	if ((link_state & PHY_LINK_NEW_MEDIA) ||
+		(phy->active_port != phy->enabled_port)) 
+	{
+		/*
+		 * Upon new media and/or port change ...
+		 *
+		 * (1) Optionally stop MAC Tx/Rx, delay up to 5 maximum packet
+		 *     times (5 x 1518 bytes = 60,720 bits, yielding respective
+		 *     100/10/1 Mbit/s delays of 607.2uS/6.072mS/60.72mS)
+		 *     for the current transmit and/or receive processing to
+		 *     complete, and then disable the soon-to-be-active PHY if
+		 *     we're changing (MAC and PHY) ports.
+		 */
+#ifndef SINGLE_PHY
+		MacPhy_Stop_And_Wait_TXRX_Complete( phy->mii_phy[JEDI_MII_PHY].adapter ) ;
+#endif
+		/*
+		* Temporarily tri-state the active, soon-to-be-enabled port
+		* only upon initial or subsequent port changes.
+		*/
+		if (phy->active_port != phy->enabled_port )
+			PhyDisable(phy, phy->active_port);
+
+		/* (2) Disable the inactive PHY */
+		PhyDisable(phy, phy->inactive_port);
+
+		/* (3) reconfigure the MAC's */
+		Full_Duplex = FALSE ;
+		Port_Mii = TRUE ;
+		if (phy->active_port & PHY_PORT_HPNA_MII ) 
+		{
+			Speed100m = TRUE ;
+		}
+		else if (phy->active_port & PHY_PORT_HPNA_7WS)
+		{
+			Port_Mii = FALSE ;
+			Speed100m = FALSE ;
+		}
+		else 
+		{	// 10/100
+			Speed100m = TRUE ;
+
+			if ((link_state & PHY_LINK_UP) ||
+               ((link_state = phy->media.mii_link_state) != 0)) 
+			{
+				/* Go with current or previous MII link settings */
+				if (link_state & PHY_LINK_10) 
+					Speed100m = FALSE ;	// 10M
+
+				if (link_state & PHY_LINK_FDX) 
+					Full_Duplex = TRUE ;
+			} 
+			else 
+			{
+				/* MII link never established: go with connect */
+				link_state = phy->media.connect;
+				if (link_state & (PHY_LINK_100BASE_T2FD |
+					PHY_LINK_100BASE_TXFD)) 
+				{
+					if (!(link_state & PHY_LINK_AUTONEG))
+						/* A-N @ half-duplex, forced @ full-duplex */
+						Full_Duplex = TRUE ;
+
+				} else if (link_state & (PHY_LINK_100BASE_T2 |
+                                     PHY_LINK_100BASE_TX |
+                                     PHY_LINK_100BASE_T4)) 
+				{
+                ;       /* nada */
+
+				} 
+				else if (link_state & PHY_LINK_10BASE_TFD) 
+				{
+					Speed100m = FALSE ;
+					if (!(link_state & PHY_LINK_AUTONEG))
+					/* A-N @ half-duplex, forced @ full-duplex */
+						Full_Duplex = TRUE ;
+				} else {
+					Speed100m = FALSE ;
+				}
+			}
+		}
+#if !defined(DEVICE_YELLOWSTONE)
+	#if 0
+		MacPhy_Configure_Mac( phy->mii_phy[JEDI_MII_PHY].adapter, Port_Mii, Speed100m, Full_Duplex ) ;
+	#endif
+#endif
+
+		/* (4) Enable the active PHY */
+		PhyEnable(phy, phy->active_port) ;
+		phy->enabled_port = phy->active_port;
+	}
+	return (PHY_STATUS_OK);
+}
+
+/***********************************************************************
+ * PhyCapabilityGet() - Get PHY technology capabilities
+ **********************************************************************/
+DWORD
+PhyCapabilityGet(PHY *phy)
+{
+    return (phy->media.capability);
+}
+
+/***********************************************************************
+ * PhyCheck() - Assess link status, speed and duplex mode
+ **********************************************************************/
+static DWORD ETHPhyCheck(PHY *phy)
+{ 
+	DWORD mii_link_state  = phy->media.mii_link_state;
+	DWORD connect = phy->media.connect;
+	WORD            bmsr;
+	WORD            aner;
+	WORD            negotiation;
+	AN_LOOKUP      *table;
+	DWORD mii_link_error = 0 ;	// no checking now
+
+   if( (connect & PHY_CONN_MII_TECHNOLOGY) && (phy->mii_isolated == FALSE)){
+
+	/* For no-MDIO PHYs assume link is up, 100 Mbps, full duplex. What else?
+	 * We have no way to verify that anyway */
+        if( PHYID_NO_MDIO(phy) )
+		{
+			mii_link_state = PHY_LINK_UP | PHY_LINK_AUTONEG | PHY_LINK_100 | PHY_LINK_100BASE_TX | PHY_LINK_FDX;
+	        phy->media.mii_link_state = mii_link_state;
+	        phy->media.connect = PHY_CONN_AUTONEG | PHY_LINK_UP;
+			return mii_link_state ;
+		}	
+
+        /*
+         * Important note:  must double-clutch BMSR when link status
+         * is down, since the BMSR_LINK_STATUS bit is latched LOW until
+         * read.  A second BMSR read ensures current link state.
+         */
+        bmsr = MiiRead( &phy->mii_phy[ETH_MII_PHY], MII_BMSR);
+        if (!(bmsr & BMSR_LINK_STATUS)) {
+            bmsr |= MiiRead( &phy->mii_phy[ETH_MII_PHY], MII_BMSR); /* |= retains error latches */
+
+            /*
+             * Upon "long-term" link down transition, disable power-saving
+             * TDK RXCC option (RX_CLK is held low when no data is
+             * received), as it adversely impacts Auto-Negotiation.  We'll
+             * restart Auto-Negotiation as a precautionary measure.
+             */
+            if ((phy->hw_options & PHY_HWOPTS_CK25DIS) &&
+                    PHYID_TDK_2120(phy) &&
+                    (mii_link_state & PHY_LINK_UP) &&
+                    !(bmsr & BMSR_LINK_STATUS)) {
+                MII_CLR_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R16, TDK_R16_RXCC);
+                if (connect & PHY_CONN_AUTONEG) {
+                    MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_BMCR, BMCR_RESTART_AUTONEG);
+                }
+            }
+
+            /* Link down: report current connect state */
+            phy->media.mii_link_state &= ~PHY_LINK_UP;
+            mii_link_state = connect & (PHY_CONN_MII_TECHNOLOGY       |
+                                        PHY_CONN_AUTONEG_REMOTE_FAULT |
+                                        PHY_CONN_AUTONEG_FDX_PAUSE);
+
+        }
+
+        /*
+         * Re-evaluate link configuration for down-to-up transitions,
+         * otherwise report present (connecting or operational) link state.
+         */
+        if ((bmsr & BMSR_LINK_STATUS) && !(mii_link_state & PHY_LINK_UP)) {
+            mii_link_state = 0;
+            if (!(connect & PHY_CONN_AUTONEG)) {
+                /*
+                 * Forced connection mode:  assume the forced state,
+                 * walking the an_lookup[] table to pick up associated
+                 * PHY_LINK_FDX and PHY_LINK_100/10 status bits.
+                 */
+                for (table = &an_lookup[0]; table->phy_link != 0; table++) {
+                    if (connect & table->phy_link & PHY_LINK_TECHNOLOGY) {
+                        mii_link_state = table->phy_link | PHY_LINK_UP;
+                        break;
+                    }
+                }
+
+            } else {
+                /*
+                 * Auto-Negotiation mode:  infer link speed/mode based
+                 * on Link Control Words (LCWs) advertised and received
+                 * from our link partner.  Simply walk the negotiated
+                 * settings against the an_lookup[] table, ordered from
+                 * highest to lowest Auto-Negotiation priority, reporting
+                 * first (highest) matching capability.  Special case:
+                 * the Davicom PHY doesn't cleanse (zero) the ANLPAR link
+                 * partner register when transitioning from an A-N partner
+                 * to a non A-N partner, so check its ANER expansion
+                 * register for a new link page notification.  Not all PHYs
+                 * indicate new page in all modes, e.g., the QSI 970 and
+                 * Level One (LXT 901) PHYs' "ANLPAR spoofing" won't
+                 * indicate ANER new page when linked to a non A-N partner,
+                 * and the pre-RevA NSC 83840 apparently doesn't indicate
+                 * next page even when linked with an A-N partner.
+                 */
+                if ((bmsr & BMSR_AUTONEG_COMPLETE) &&
+                        (((aner = MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_ANER)) &
+                           ANER_PAGE_RECEIVED) ||
+                         !PHYID_DAVICOM_9101(phy))) {
+                    negotiation = (phy->anar & MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_ANLPAR));
+                    for (table = &an_lookup[0]; table->anar != 0; table++) {
+                        if (negotiation & table->anar) {
+                            mii_link_state = (PHY_LINK_UP      |
+                                              PHY_LINK_AUTONEG |
+                                              table->phy_link);
+                            break;
+                        }
+                    }
+                    if (aner & ANER_PARALLEL_DETECTION_FAULT) {
+                        mii_link_error |= PHY_LINK_PARALLEL_ERROR;
+                    }
+                }
+
+				// Bright new 9/26/01
+                if (PHYID_KENDIN_KS8737(phy)) {
+                /*
+                 * Though the Kendin PHY supports "ANLPAR spoofing,"
+                 * subsequent to link with Auto-Negotiating peer,
+                 * it fails to update its ANLPAR register, resulting
+                 * in false mode selection.  We'll correct via
+                 * vendor-specific register 31.
+                 */
+                   WORD    r31 = MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_R31);
+                   if (!(r31 & MII_BIT4)) 
+                   {
+                    /*
+                     * Not full-duplex, which can only result from
+                     * a true Auto-Negotiation handshake.
+                     */
+                    mii_link_state = (PHY_LINK_UP | PHY_LINK_AUTONEG);
+                    if (r31 & MII_BIT2) {
+                        mii_link_state |= PHY_LINK_10BASE_T;
+                    } else {
+                        mii_link_state |=
+                            (PHY_LINK_100 | PHY_LINK_100BASE_TX);
+                    }
+                   }
+                } else if (mii_link_state == 0) {
+                    /*
+                     * Parallel Detection: link but no Auto-Negotiation
+                     * match, which implies our link partner is not A-N
+                     * capable.  Determine link technology via PHY
+                     * vendor-specific status registers.
+                     */
+                    if (PHYID_NSC_DP83840(phy)) {
+                        mii_link_state = PHY_LINK_UP | PHY_LINK_AUTONEG;
+                        if (MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_PAR) & PAR_SPEED_10) {
+                            mii_link_state |=
+                                (PHY_LINK_10  | PHY_LINK_10BASE_T);
+                        } else {
+                            mii_link_state |=
+                                (PHY_LINK_100 | PHY_LINK_100BASE_TX);
+                        }
+
+                    } else if (PHYID_GEC_NWK936(phy)) {
+                        /*
+                         * The GEC PHY apparently sets BMCR speed/duplex
+                         * bits based on the A-N outcome.  Though their spec
+                         * says to use extended register 25 for current
+                         * speed and duplex state, we'll stick to the
+                         * standard BMCR register, although most PHYs
+                         * don't reflect current speed/duplex state in
+                         * the BMCR when Auto-Negotiating....
+                         */
+                        mii_link_state = PHY_LINK_UP | PHY_LINK_AUTONEG;
+                        if (MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_BMCR) & BMCR_SPEED_100) {
+                            mii_link_state |=
+                                (PHY_LINK_100 | PHY_LINK_100BASE_TX);
+                        } else {
+                            mii_link_state |=
+                                (PHY_LINK_10  | PHY_LINK_10BASE_T);
+                        }
+
+                    } else if (PHYID_TDK_2120(phy)) {
+                        /*
+                         * The TDK PHY's diagnostic register 18 (decimal)
+                         * MR18.RATE, bit-10 (0x400) indicates the result of
+                         * Auto-Negotiation data rate arbitration.  However,
+                         * when using their pre-production Rev 3 device,
+                         * our testing apparently revealed bit-9 (0x200) as
+                         * the RATE indicator when connecting to dumb,
+                         * non Auto-Negotiating hubs at 10 or 100 Mbit/sec,
+                         * half-duplex.  TDK support confirms that bit-10
+                         * RATE is a new feature in the Rev 7 device.  As
+                         * such, we'll go with this apparent bit-9 heuristic
+                         * on the earlier, Rev-3 device.
+                         */
+                        mii_link_state = PHY_LINK_UP | PHY_LINK_AUTONEG;
+                        if (MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_R18) &
+                                ((PHYID_REV(phy) >= 7) ? TDK_R18_RATE_100
+                                                       : MII_BIT9)) {
+                            mii_link_state |=
+                                (PHY_LINK_100 | PHY_LINK_100BASE_TX);
+                        } else {
+                            mii_link_state |=
+                               (PHY_LINK_10   | PHY_LINK_10BASE_T);
+                        }
+
+                    } else if (PHYID_DAVICOM_9101(phy)) {
+                        /*
+                         * The Davicom PHY apparently (as of 21Jan98 we
+                         * have no data sheet) identifies auto-negotiation
+                         * results in bits 12-15 of register 17 (decimal).
+                         * 8nnn = 100-FDX, 4nnn = 100-HDX, 2nnn = 10-FDX,
+                         * and 1nnn = 10-HDX.  Since an A-N partner's
+                         * advertisement should be correctly reflected in
+                         * the ANLPAR (register 5), we'll only troll for
+                         * dumb, non A-N partners' half-duplex results here.
+                         */
+                        mii_link_state = PHY_LINK_UP | PHY_LINK_AUTONEG;
+                        switch (MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_R17) & 0xF000) {
+                            default:
+                                mii_link_state = 0;
+                                break;
+                            case 0x4000:
+                                mii_link_state |=
+                                    (PHY_LINK_100 | PHY_LINK_100BASE_TX);
+                                break;
+                            case 0x1000:
+                                mii_link_state |=
+                                    (PHY_LINK_10  | PHY_LINK_10BASE_T);
+                                break;
+                        }
+                    } else if (PHYID_LXT_971(phy)) {
+
+                        // Unspecified, based on lab test observation 03Dec99                        */
+                        mii_link_state = PHY_LINK_UP | PHY_LINK_AUTONEG;
+                        if(MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_R17) & 0x4000) {
+							mii_link_state |= (PHY_LINK_100 | PHY_LINK_100BASE_TX);
+						}
+						else {
+							mii_link_state |= (PHY_LINK_10  | PHY_LINK_10BASE_T);
+                        }
+                    }
+                } /* end if - SW parallel detection logic */
+            } /* end if - Auto-Negotiating */
+
+            /* Latch 1st and subsequent PHY_LINK_NEW_MEDIA changes */
+            if (mii_link_state == 0) {
+                /* ??? Couldn't resolve link; need PHY_LINK_UNKNOWN err */
+                mii_link_state = connect & (PHY_CONN_MII_TECHNOLOGY       |
+                                            PHY_CONN_AUTONEG_REMOTE_FAULT |
+                                            PHY_CONN_AUTONEG_FDX_PAUSE);
+            } else if ((mii_link_state ^ phy->media.mii_link_state) &
+                     (PHY_LINK_SPEED | PHY_LINK_FDX |
+                      PHY_LINK_MII_TECHNOLOGY)) {
+                phy->media.mii_link_state = mii_link_state;
+                mii_link_state |= PHY_LINK_NEW_MEDIA;
+            } else {
+                phy->media.mii_link_state = mii_link_state;
+            }
+
+            /* Enable TDK RXCC option only on link down-to-up @ 100 Mbit */
+            if ((phy->hw_options & PHY_HWOPTS_CK25DIS) &&
+                    PHYID_TDK_2120(phy)) {
+                if (mii_link_state & PHY_LINK_100) {
+                    MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R16, TDK_R16_RXCC);
+                } else {
+                    MII_CLR_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R16, TDK_R16_RXCC);
+                }
+            }
+        } /* endif - MII link down-to-up transition */
+
+        /* Affix newly detected errors latched by PHY hardware */
+        if ((bmsr & BMSR_JABBER_DETECT) &&
+                (mii_link_state & (PHY_LINK_10BASE_TFD |
+                                   PHY_LINK_10BASE_T))) {
+            mii_link_error |= PHY_LINK_JABBER;
+        }
+        if (bmsr & BMSR_REMOTE_FAULT) {
+            mii_link_error |= PHY_LINK_REMOTE_FAULT;
+        }
+    }
+	return mii_link_state ;
+}
+
+DWORD PhyCheck(PHY *phy)
+{
+    DWORD           connect          = phy->media.connect;
+    DWORD           hpna_link_state = 0 ;
+    DWORD           cum_link_state   = phy->media.cum_link_state;
+    DWORD           mii_link_state ;
+    PHY_PORT        port_select;
+
+    if (!IS_PHY_INITIALIZED(phy)) {
+        return (PHY_LINK_INIT_ERROR);
+    }
+
+#if HOMEPLUGPHY
+	if( PhyActiveHOMEPLUG( phy) )
+	{
+		mii_link_state = PHY_LINK_UP | PHY_LINK_AUTONEG | PHY_LINK_100 | PHY_LINK_100BASE_TX ;
+		phy->media.mii_link_state = mii_link_state;
+		phy->media.connect = PHY_CONN_AUTONEG | PHY_LINK_UP;
+		return mii_link_state ;
+	}	
+#endif
+
+    /*----------------------------------------------------------------*
+     * (1) Examine HomePNA PHY
+     *----------------------------------------------------------------*/
+#ifdef JEDIPHY	// Bright
+    hpna_link_state = JediPhyCheck(phy) ;
+#endif
+
+    /*----------------------------------------------------------------*
+     * (2) Examine MII PHY
+     *----------------------------------------------------------------*/
+    mii_link_state = ETHPhyCheck(phy) ;
+
+    /*----------------------------------------------------------------*
+     * (3) Form cumulative link state based on HomePNA and MII states
+     *----------------------------------------------------------------*/
+
+    /* Initial state indicates Auto-Negotiation directive */
+    cum_link_state = (connect & PHY_LINK_AUTONEG);
+
+    if (!(connect & PHY_CONN_HPNA_TECHNOLOGY)) {
+        /*
+         * (3a) No HomePNA connect, so infer MII-only operation
+         */
+        cum_link_state |= mii_link_state;
+        port_select = phy->mii_port;
+
+    } else if (!(connect & PHY_CONN_MII_TECHNOLOGY)) {
+        /*
+         * (3b) No MII connect, so infer HomePNA-only operation
+         */
+        cum_link_state |= hpna_link_state;
+        port_select = phy->hpna_port;
+
+        /*
+         * (3c) Simultaneous HomePNA and MII operation ...
+         */
+    } else if (!((hpna_link_state | mii_link_state) & PHY_LINK_UP)) {
+
+        /*
+         * (3c-1) Neither device reporting link: choose a port.
+         *
+         * By default, retain the current, active port.  After
+         * LINK_DOWN_HOP_COUNT (nominally 5) successive cycles of
+         * link down, we can optionally switch (hop) to the other,
+         * inactive port or lock-in on the MII or HomePNA port if
+         * the respective PHY_HWOPTS_PORT_HOPPING, PHY_HWOPTS_MII_ 
+         * PORT_PRIORITY or PHY_HWOPTS_HPNA_PORT_PRIORITY options
+         * are in effect.  Special port-hopping note:  certain
+         * tested MII PHYs such as the TDK, QSI and GEC don't require
+         * hopping to achieve link, thus we won't hop thereupon
+         * to improve our odds of achieving link on the HomePNA
+         * device.
+         */
+        cum_link_state |= (hpna_link_state | mii_link_state);
+        port_select = phy->active_port;
+        if (++phy->link_down_count >= LINK_DOWN_HOP_COUNT) {
+            phy->link_down_count = 0;
+            if ((phy->hw_options & PHY_HWOPTS_PORT_HOPPING) &&
+                    (phy->inactive_port != PHY_PORT_NONE)) {
+                port_select = phy->inactive_port;   /* (hop) */
+            } else if (phy->hw_options & PHY_HWOPTS_MII_PORT_PRIORITY) {
+                port_select = phy->mii_port;
+            } else if (phy->hw_options & PHY_HWOPTS_HPNA_PORT_PRIORITY) {
+                port_select = phy->hpna_port;
+            }
+        }
+
+    } else {
+        /*
+         * (3c-2) One or both devices reporting link: choose a port.
+         *
+         * If both devices report link, retain the active port if
+         * previously linked.  Otherwise, default to the MII link
+         * status and select the MII port, since 10/100 Mbit/s is
+         * considered a greater capability than 1 Mbit/s HomePNA.
+         * This can be overriden via the PHY_HWOPTS_HPNA_PORT_PRIORITY
+         * option.
+         *
+         * If only one device is reporting link, select that device's
+         * port and use its associated link status.
+         */
+        phy->link_down_count = 0;
+        if (hpna_link_state & mii_link_state & PHY_LINK_UP) {
+            /* Both devices reporting link: choose a winner */
+            if (phy->media.cum_link_state & PHY_LINK_UP) {
+                port_select = phy->active_port;
+                if (port_select == phy->hpna_port) {
+                    cum_link_state |= hpna_link_state;
+                } else {
+                    cum_link_state |= mii_link_state;
+                }
+
+            } else if (phy->hw_options &
+                       PHY_HWOPTS_HPNA_PORT_PRIORITY) {
+                cum_link_state |= hpna_link_state;
+                port_select = phy->hpna_port;
+
+            } else {
+                /* 10/100 Mbit/s MII > 1-Mit/s HomePNA */
+                cum_link_state |= mii_link_state;
+                port_select = phy->mii_port;
+            }
+
+        } else if (mii_link_state & PHY_LINK_UP) {
+            /* MII-only link up */
+            cum_link_state |= mii_link_state;
+            port_select = phy->mii_port;
+
+        } else {
+            /* HomePNA-only link up */
+            cum_link_state |= hpna_link_state;
+            port_select = phy->hpna_port;
+        }
+    }
+
+    /*----------------------------------------------------------------*
+     * (4) Select port and merge into cumulative link state
+     *----------------------------------------------------------------*/
+
+    switch (port_select) {
+        case PHY_PORT_HPNA_7WS:  
+           cum_link_state |= PHY_LINK_PORT_7WS;  break;
+        case PHY_PORT_HPNA_MII:  
+           cum_link_state |= PHY_LINK_PORT_MII;  break;
+        case PHY_PORT_MII:       
+           cum_link_state |= PHY_LINK_PORT_MII;  break;
+        default:                 /* ??? */                             break;
+    }
+    if (!(cum_link_state & PHY_LINK_UP)) {
+        phy->media.cum_link_state &= ~PHY_LINK_UP;
+    } else {
+        if ((cum_link_state ^ phy->media.cum_link_state) &
+                (PHY_LINK_PORT | PHY_LINK_FDX | PHY_LINK_SPEED |
+                 PHY_LINK_TECHNOLOGY)) {
+            cum_link_state |= PHY_LINK_NEW_MEDIA;
+        }
+        phy->media.cum_link_state = cum_link_state & ~PHY_LINK_NEW_MEDIA;
+    }
+
+    /*----------------------------------------------------------------*
+     * (5) Optionally reconfigure upon new-media and/or port switch
+     *----------------------------------------------------------------*/
+    if ((cum_link_state & PHY_LINK_NEW_MEDIA) ||
+            ((port_select != phy->active_port) &&
+             (port_select != PHY_PORT_NONE))) {
+        if ((port_select != phy->active_port) &&
+                (port_select != PHY_PORT_NONE)) {
+#if OLD
+            phy->inactive_port = phy->active_port;
+            phy->active_port = port_select;
+#else
+            Set_Active_Port( phy, port_select ) ;
+#endif
+        }
+        if( !(phy->hw_options & PHY_HWOPTS_ISOLATE)) 
+            PhyConfigurePort(phy, cum_link_state);
+    }
+
+    return (cum_link_state);
+}
+
+/***********************************************************************
+ * PhyLastLinkUp() - Return current or last known, valid link state
+ **********************************************************************/
+DWORD
+PhyLastLinkUp(PHY *phy)
+{
+    if (phy->media.cum_link_state != 0) {
+        return (phy->media.cum_link_state | PHY_LINK_UP);
+    }
+    return (0);         /* valid link never established */
+}
+
+/***********************************************************************
+ * PhyShutdown() - Disable (isolate) and power-down the PHY
+ **********************************************************************/
+void PhyShutdown(PHY *phy)
+{
+    (void) PhyDisable(phy, PHY_PORT_MII_DEVICE);
+    MII_SET_MASK(phy->pActive_miiphy, MII_BMCR, BMCR_POWERDOWN);
+}
+
+#if 0
+/***********************************************************************
+ * PhyLoopback() - Enable/disable PHY loopback (one of four modes)
+ **********************************************************************/
+PHY_STATUS
+PhyLoopback(PHY *phy, PHY_LOOPBACK mode)
+{
+    WORD        lbremr;
+
+    if (!IS_PHY_INITIALIZED(phy)) {
+        return (PHY_STATUS_UNINITIALIZED);
+    }
+
+    switch (mode) {
+        default:
+            mode = PHY_LOOPBACK_OFF;
+            /* fall through ... */
+        case PHY_LOOPBACK_MII:       /* MAC loopback at MII Tx/Rx */
+            lbremr = LBREMR_LB_OFF;
+            break;
+
+        case PHY_LOOPBACK_PMD:       /* Loopback at the PMD Tx/Rx */
+            lbremr = LBREMR_LB_XCVR;
+            break;
+
+        case PHY_LOOPBACK_REMOTE:    /* Media Rx Data looped onto Tx at
+                                      * MII (e.g., link BER testing) */
+            lbremr = LBREMR_LB_REMOTE;
+            break;
+
+        case PHY_LOOPBACK_10BASE_T:
+            lbremr = LBREMR_LB_10BT;
+            break;
+    }
+
+    /* Configure BMCR and LBREMR registers' loopback control bits */
+    phy->loopback = mode;
+    if (mode == PHY_LOOPBACK_MII) {
+        MII_SET_BIT(phy->pActive_miiphy, MII_BMCR, BMCR_LOOPBACK);
+    } else {
+        MII_CLR_BIT(phy->pActive_miiphy, MII_BMCR, BMCR_LOOPBACK);
+    }
+    MII_CLR_MASK(phy->pActive_miiphy, MII_LBREMR, LBREMR_LB_MASK);
+    MII_SET_MASK(phy->pActive_miiphy, MII_LBREMR, lbremr);
+
+    return (PHY_STATUS_OK);
+}
+
+/***********************************************************************
+ * PhyColTest() - Enable/disable collision test (diagnostic)
+ **********************************************************************/
+PHY_STATUS
+PhyColTest(PHY *phy, BOOLEAN enable)
+{
+    phy = phy;
+    return ((enable) ? PHY_STATUS_UNSUPPORTED_FUNCTION : PHY_STATUS_OK);
+}
+#endif
+
+/***********************************************************************
+ * PhyIdGet() - Read HW ID from registers 2 and 3
+ **********************************************************************/
+DWORD PhyIdGet(PHY *phy)
+{
+	return phy->pActive_miiphy->mii_id ;
+}
+
+BOOLEAN PhyActiveHPNA(PHY *phy)
+{
+#ifndef NON_BYPASSMODE	// test
+	if ( phy->active_port & PHY_PORT_HPNA_DEVICES )
+		return TRUE ;
+#endif
+	return FALSE ;
+}
+
+#if HOMEPLUGPHY
+
+// TBD , need improvement	
+BOOLEAN PhyActiveHOMEPLUG(PHY *phy)
+{
+
+	if ( phy->active_port & PHY_PORT_MII_DEVICE &&
+	phy->mii_phy[ETH_MII_PHY].mii_id == HOMEPLUGID )
+//	if ( phy->active_port & PHY_PORT_MII_DEVICE &&
+//	phy->mii_phy[ETH_MII_PHY].mii_id != 0x221720 )
+		return TRUE ;
+
+	return FALSE ;
+}
+#endif
+
+
+// Check if Any Phy attached to EMAC port
+// input : 
+//		Mac_Addr : beginnig of the emac mac address
+//		mii_addr : if 0xff : search 0 to 31
+//					  else search specified mii_addr (faster)
+BOOLEAN Phy_EmacPortAttached(DWORD Mac_Addr, BYTE mii_addr) 
+{
+	BYTE	last_addr;
+	WORD	bmsr;
+	MIIOBJ TmpMii ;
+
+	TmpMii.adapter = Mac_Addr ;
+	TmpMii.preamble_suppression = FALSE ;
+
+	if( mii_addr == 0xff )
+	{
+		last_addr = PHY_ADDR_MAX;
+		mii_addr  = PHY_ADDR_MIN + 1;    
+	}
+	else
+		last_addr = mii_addr ;
+
+Search_Mii_1 :
+	while(mii_addr <= last_addr) 
+	{
+		TmpMii.mii_addr = mii_addr++;
+		if (((bmsr = MiiRead(&TmpMii, MII_BMSR)) != 0x0000) &&
+			(bmsr != 0xFFFF)) 
+			return TRUE ;
+	}
+
+	/* Go back to addr-0 once full MII search 1..31 fails */
+	if( mii_addr == (PHY_ADDR_MAX+1) ) 
+	{
+		mii_addr = last_addr = PHY_ADDR_MIN ;
+		goto Search_Mii_1 ;
+	}
+	
+	return FALSE ;
+}
diff -urN linux-2.4.29/drivers/net/cnxt_emac/phy.h linux-2.4.29-uc1/drivers/net/cnxt_emac/phy.h
--- linux-2.4.29/drivers/net/cnxt_emac/phy.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/phy.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,392 @@
+/****************************************************************************
+*
+*	Name:			phy.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 1997-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+*
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 27 2003 08:01:52  $
+****************************************************************************/
+
+#ifndef _PHY_H_
+#define _PHY_H_
+
+#include "phytypes.h"
+// PHY object interfaces for other objects
+// #define NON_BYPASSMODE	1	// test
+
+#ifndef _PHYOBJ_H_
+// these definition are required for interfaces
+// the superset defined inside phyobj.h
+
+typedef enum _phy_status_ {
+    PHY_STATUS_OK = 0,
+    PHY_STATUS_NOT_FOUND,               /* PhyInit() errors ... */
+    PHY_STATUS_UNSUPPORTED_FUNCTION,
+    PHY_STATUS_PORTABILITY_ERROR,
+    PHY_STATUS_RESET_ERROR,             /* PhyReset() bit stuck */
+    PHY_STATUS_UNSUPPORTED_MEDIA,       /* PhyConnSet() error */
+    PHY_STATUS_UNINITIALIZED,
+    PHY_STATUS_ERROR_MISC 
+    /* etc. */
+} PHY_STATUS;
+
+#define PHY_LINK_UP             0x80000000L
+#define PHY_LINK_NEW_MEDIA      0x40000000L
+#define PHY_LINK_FDX            0x20000000L
+#define PHY_LINK_AUTONEG        0x10000000L
+#define PHY_LINK_100            0x04000000L
+#define PHY_LINK_10             0x02000000L
+#define PHY_LINK_HPNA_10        0x01000000L
+
+#define PHY_LINK_HPNA20         0x00000800L /* (3) PHY_LINK_TECHNOLOGY ... */
+
+#define PHY_LINK_100BASE_T2FD   0x00000080L
+#define PHY_LINK_100BASE_T2     0x00000040L
+#define PHY_LINK_FDX_PAUSE      0x00000020L
+#define PHY_LINK_100BASE_T4     0x00000010L
+#define PHY_LINK_100BASE_TXFD   0x00000008L
+#define PHY_LINK_100BASE_TX     0x00000004L
+#define PHY_LINK_10BASE_TFD     0x00000002L
+#define PHY_LINK_10BASE_T       0x00000001L
+
+
+#define PHY_LINK_SPEED          \
+    (PHY_LINK_100  | PHY_LINK_10   | PHY_LINK_HPNA_10)
+
+
+
+#define PHY_CONN_CURRENT                0
+#define PHY_CONN_AUTONEG                PHY_LINK_AUTONEG
+#define PHY_CONN_HPNA20                 PHY_LINK_HPNA20
+#define PHY_CONN_100BASE_T2FD           PHY_LINK_100BASE_T2FD
+#define PHY_CONN_100BASE_T2             PHY_LINK_100BASE_T2
+#define PHY_CONN_AUTONEG_FDX_PAUSE      PHY_LINK_FDX_PAUSE
+#define PHY_CONN_100BASE_T4             PHY_LINK_100BASE_T4
+#define PHY_CONN_100BASE_TXFD           PHY_LINK_100BASE_TXFD
+#define PHY_CONN_100BASE_TX             PHY_LINK_100BASE_TX
+#define PHY_CONN_10BASE_TFD             PHY_LINK_10BASE_TFD
+#define PHY_CONN_10BASE_T               PHY_LINK_10BASE_T
+
+/* Any (defaults to highest capability) HomePNA settting */
+#define PHY_CONN_ANY_HPNA20                                     \
+     PHY_CONN_HPNA20
+
+/* Any 10Base-T half-duplex setting */
+#define PHY_CONN_ANY_10BASE_T           PHY_CONN_10BASE_T
+
+/* Any 10Base-T full-duplex setting */
+#define PHY_CONN_ANY_10BASE_TFD         PHY_CONN_10BASE_TFD
+
+/* Any available 100Base-T half-duplex capability */
+#define PHY_CONN_ANY_100BASE_T          \
+    (PHY_CONN_100BASE_T2 | PHY_CONN_100BASE_T4 | PHY_CONN_100BASE_TX)
+
+/* Any available 100Base-T full-duplex capability */
+#define PHY_CONN_ANY_100BASE_TFD        \
+    (PHY_CONN_100BASE_T2FD | PHY_CONN_100BASE_TXFD)
+
+/* Force highest available HomePNA or 10/100 MII capability */
+#define PHY_CONN_FORCE_ANY_MEDIA        \
+    (PHY_CONN_ANY_HPNA20     |          \
+     PHY_CONN_ANY_10BASE_T   |          \
+     PHY_CONN_ANY_10BASE_TFD |          \
+     PHY_CONN_ANY_100BASE_T  |          \
+     PHY_CONN_ANY_100BASE_TFD)
+
+/* Auto-Negotiate all available HomePNA and/or 10/100 MII capabilities */
+#define PHY_CONN_AUTONEG_ALL_MEDIA      \
+    (PHY_CONN_AUTONEG | PHY_CONN_FORCE_ANY_MEDIA)
+
+/* Only Auto-Negotiate 10/100 MII capabilities: exclude HomePNA */
+#define PHY_CONN_AUTONEG_ALL_MII_MEDIA  \
+    (PHY_CONN_AUTONEG_ALL_MEDIA & ~PHY_CONN_ANY_HPNA20)
+
+/* Only Auto-Negotiate HomePNA capabilities: exclude 10/100 MII */
+#define PHY_CONN_AUTONEG_ALL_HPNA_MEDIA  \
+    (PHY_CONN_AUTONEG | PHY_CONN_ANY_HPNA20)
+
+/* Supported Options */
+#define PHY_HWOPTS_NONE                 0x00000000L
+#define PHY_HWOPTS_ISOLATE              0x00000400L
+#define PHY_HWOPTS_DONT_SWRESET         0x00002000L
+#define PHY_HWOPTS_MII_PREAMBLE         0x00008000L
+#define PHY_HWOPTS_NO_ETH_SEARCH        0x00010000L
+#define PHY_HWOPTS_NO_HPNA_SEARCH       0x00020000L
+#define PHY_HWOPTS_HPNA_PORT_PRIORITY   0x00080000L
+#define PHY_HWOPTS_MII_PORT_PRIORITY    0x00100000L
+#define PHY_HWOPTS_PORT_HOPPING         0x00200000L
+#define PHY_HWOPTS_HPNA7WS              0x20000000L
+#ifdef P51
+#define PHY_HWOPTS_P51_HLAN             0x40000000L
+#endif
+
+#define PHY void
+#endif
+
+
+PHY * PhyAllocateMemory( void) ;
+void PhyFreeMemory( PHY *pPhy ) ;
+
+PHY_STATUS   PhyInit(
+						DWORD	mac_address,
+						PHY		*phy,
+                        DWORD	connect,
+                        DWORD	hw_options, 
+						void	*pHpnaObj
+					);	// for HPNA 2.0 LL compliance
+
+DWORD PhyCheck(PHY *phy);
+BOOLEAN PhyActiveHPNA(PHY *phy) ;
+
+#if HOMEPLUGPHY
+BOOLEAN PhyActiveHOMEPLUG(PHY *phy) ;
+#endif
+
+DWORD PhyIdGet(PHY *phy) ;
+void PhyShutdown(PHY *phy) ;
+
+// Check if Any Phy attached to EMAC port
+// input : 
+//		Mac_Addr : beginnig of the emac mac address
+//		mii_addr : if 0xff : search 0 to 31
+//					  else search specified mii_addr (faster)
+BOOLEAN Phy_EmacPortAttached(DWORD Mac_Addr, BYTE mii_addr) ;
+
+/*
+	PHY * PhyAllocateMemory( void) ;
+		Allocte memory for PHY object
+	 Parameters :
+	 Return Value :
+		NULL if fail, else return a pointer to the PHY object
+	 Comment :
+		. the caller should save the returned value for other services provided 
+		by this module.
+*/
+
+/*
+	void PhyFreeMemory( PHY *pPhy ) ;
+		Free memory for PHY object
+	 Parameters :
+		PHY *pPhy: pointer to the PHY object
+	 Return Value :
+	 Comment :
+*/
+
+
+/*
+	PHY_STATUS   PhyInit(DWORD  mac_address, PHY   *phy, DWORD  connect,
+	DWORD  hw_options, PVOID pHpnaObj );	
+		Initialize PHY and attach to media (w/optional override), PhyInit do not
+		perform hardware reset of the PHYs. Hardware reset is MAC operation, should
+		be called before PhyInit(if required).
+	 Parameters :
+		DWORD  mac_address: MAC device I/O base address
+		PHY   *phy: allocated PHY data structure space 
+		DWORD  connect: used either to (a) force a selected line speed (10 or 100 Mbps)
+			) and mode (full- or half-duplex), or (b) to set a list of Auto-Negotiation
+			(A-N) options when the PHY_CONN_AUTONEG bit is set.  It can be a OR value of 
+			PHY_CONN-xxx bits defined above. The default value is PHY_CONN_AUTONEG_ALL_MEDIA.
+		DWORD  hw_options: one or more PHY_HWOPTS_* bits as follows.
+			ISOLATE - Disable (tri-state) the active HomePNA or MII device's
+				data interface and underlying PMD interface.  The
+				associated 7WS or MDC/MDIO Serial Management Interface
+				remains enabled for subsequent management commands.
+				This is equivalent to calling PhyDisable().
+			DONT_SWRESET - Don't issue (otherwise) mandatory software reset
+			MII_PREAMBLE - If this option is activated, the PHY driver will
+				always send a 32-bit MDIO preamble during MII reads
+				and writes.  Otherwise, the PHY driver will attempt
+				to suppress the 32-bit preamble, provided the device
+				hardware supports this feature as indicated by the
+				MII register 1.6 status bit.
+			PHY_HWOPTS_NO_ETH_SEARCH - do not search Ethernet PHY
+			PHY_HWOPTS_NO_HPNA_SEARCH - do not search HPNA(JEDI) PHY
+			HPNA_PORT_PRIORITY - If this option is selected, a link indication 
+				from a HPNA device will take precedence over a
+				simultaneous link indication from a ethernet 10/100 MII
+				device.  Otherwise the default case is for the higher
+				speed 10/100 MII device precedence.  This affects
+				the PhyCheck() link indication in the unlikely case
+				that both devices report link, as only the highest
+				priority capability will be reported.  It also has a
+				side-effect in that the PhyCheck() routine will switch
+				from an MII to HomePNA PHY device whenever the MII
+				link goes down (i.e., cable removed from 10/100 Ether
+				hub).
+
+			MII_PORT_PRIORITY  - Similar to HPNA_PORT_PRIORITY.  Since by default,
+				MII > HPNA, this doesn't affect the simultaneous link status. 
+				However, it does determine the default port selected (MII) 
+				at PhyInit() time and subsequent to link down.
+
+			PORT_HOPPING - If this option is selected and multi-port PHY devices
+				are present, i.e., both HomePNA and 10/100 MII
+				devices found, then the PhyCheck() routine will
+				force a port hop every LINK_DOWN_HOP_COUNT calls
+				when the link is down.  The default value of the
+				"phy.c" LINK_DOWN_HOP_COUNT is 5, which allows
+				ten seconds per port for a 2-second check period.
+				This option should not be enabled when the app/driver
+				polls PhyCheck() repeatedly in an initialization loop.
+
+				This option is recommended for broken PHY devices which
+				cannot achieve link while configured in the MII isolate
+				mode.  To date, we've found that the National
+				Semiconductor DP83840 won't work at all when isolated
+				(it also disables its twisted pair PMD interface), and
+				the Level One LXT 970 and Enable Semiconductor PHYs
+				curiously can achieve link when connected to 10 but
+				not 100 Mbit hubs and switches.
+
+				------------------------------------------------------
+
+				Note: the following truth table depicts the complex
+				interaction among the PHY_HWOPTS_PORT_HOPPING (HOP),
+				PHY_HWOPTS_HPNA_PORT_PRIORITY (HPNA) and the
+				PHY_HWOPTS_MII_PORT_PRIORITY (MII) options.  This
+				table is only applicable when BOTH devices (HomePNA and
+				MII) are present.  As can be seen, MII priority
+				primarily affects the PhyInit() default port select,
+				HPNA priority primarily affects PhyCheck() in the
+				rare (unlikely?) case that both links are up, and
+				HOP determines whether a port switch is made when
+				both links are down.  As a secondary effect when
+				HOP is disabled, MII supercedes HPNA priority when
+				both links are down, otherwise HPNA supercedes the
+				the current, active port which is retained in the
+				default case where no options are in effect.  Whew!
+
+				What's not depicted is the simple case where only one
+				port is reporting link: that port is always selected,
+				regardless of multi-port options.
+ 
+                          Multi-Port Selection Truth Table           
+ 
+                 +==================++=================+===========+
+                 |                  ||    PhyCheck()   |           |
+                 |  PHY HW option   |+---------+-------+           |
+                 |                  || Both    | Both  | PhyInit() |
+                 +=====+======+=====+| Links   | Links | Default   |
+                 | HOP | HPNA | MII || Down**  | Up    | Port      |
+                 +=====+======+=====++=========+=======+===========+
+      (default)  |  0  |   0  |  0  || current |  MII  |   HPNA    |
+                 +-----+------+-----++---------+-------+-----------+
+                 |  0  |   0  |  1  ||   MII*  |  MII  |    MII*   |
+                 +-----+------+-----++---------+-------+-----------+
+                 |  0  |   1  |  0  ||  HPNA*  | HPNA* |   HPNA    |
+                 +-----+------+-----++---------+-------+-----------+
+                 |  0  |   1  |  1  ||   MII*  | HPNA* |    MII*   |
+                 +=====+======+=====++=========+=======+===========+
+                 |  1  |   0  |  0  ||  other* |  MII  |   HPNA    |
+                 +-----+------+-----++---------+-------+-----------+
+                 |  1  |   0  |  1  ||  other* |  MII  |    MII*   |
+                 +-----+------+-----++---------+-------+-----------+
+                 |  1  |   1  |  0  ||  other* | HPNA* |   HPNA    |
+                 +-----+------+-----++---------+-------+-----------+
+                 |  1  |   1  |  1  ||  other* | HPNA* |    MII*   |
+                 +-----+------+-----++---------+-------+-----------+
+ 
+                 *  - Indicates behavior change with respect to the
+                      default action.
+ 
+                 ** - With both links down, "current" denotes the
+                      currently active port (default or last link),
+                      whereas "other" denotes a swap to the other,
+                      presently inactive port.  All port switching is
+                      governed by the nominal LINK_DOWN_HOP_COUNT
+                      value of 5, which yields a 10-second rate
+                      assuming a periodic, 2-second PhyCheck() cycle.
+                      As such, a link-down port switch won't occur
+                      for ten seconds, though a single- or dual-port
+                      link-up event will instanly effect a port switch.
+			HPNA7WS - If this option is activated, the PHY driver will support
+				HPNA(JEDI) with 7 wire istead of MII mode
+
+
+		PVOID pHpnaObj : a pointer of HPNALLOBJ
+	 Return Value
+*/
+
+/*
+	DWORD PhyCheck(PHY *phy)
+		To get the current PHY states. The driver can call this function at a timer 
+		routine to know the current PHY states from the return value to update the
+		the driver states. Beware that, if return value indicate PHY_LINK_NEW_MEDIA,
+		the PhyCheck would already reconfigure the PHY and MAC to the correct states,
+		but the current TX and RX of MAC stopped. Under this scenario, driver need to 
+		restart TX and RX of MAC if required.
+
+	 Parameters :
+		PHY *phy :
+	 Return Value : return a OR value of the following bits, please iqnore the
+		other bits not describes in this document.
+ 		PHY_LINK_SPEED - Set with PHY_LINK_UP to indicate 1/10/100
+                       Mbit/s line speed, as follows.  One and only
+                       one of the following PHY_LINK_SPEED bits will
+                       be set when PHY_LINK_UP is set.  If PHY_LINK_UP
+                       is not set, then none of the PHY_LINK_SPEED
+                       bits will be set.
+ 
+			PHY_LINK_100 - if PHY_LINK_UP && ETHERNET 100 Mbit/s
+			PHY_LINK_10  - if PHY_LINK_UP &&  ETHERNET 10 Mbit/s
+			PHY_LINK_HPNA_10  - if PHY_LINK_UP &&   HPNA 10 Mbit/s
+
+		PHY_LINK_UP        - Set when the link is operational
+		PHY_LINK_NEW_MEDIA - Set upon initial PHY_LINK_UP, and whenever
+                       PHY_LINK_UP is true and a media state change
+                       (speed and/or duplex mode) has been detected
+                       since the last PhyCheck().  This status
+                       can be used as a signal to reconfigure a MAC's
+                       speed, duplex and port select settings.
+*/
+
+/*
+	BOOLEAN PhyActiveHPNA(PHY *phy)
+		check if current active PHY is HPNA (JEDI)
+	 Parameters :
+		PHY *phy :
+	 Return Value :
+		TRUE : the current active PHY is HPNA (JEDI)
+		FLASE : the current active PHY is ETHERNET(10/100) or none
+*/
+
+/*
+	BOOLEAN PhyActiveHOMEPLUG(PHY *phy)
+		check if current active PHY is HOMEPLUG (TESLA)
+	 Parameters :
+		PHY *phy :
+	 Return Value :
+		TRUE : the current active PHY is HOMEPLUG
+		FLASE : the current active PHY is not HOMEPLUG
+*/
+
+/*
+	DWORD PhyIdGet(PHY *phy)
+		get MII ID
+	 Parameters :
+		PHY *phy :
+	 Return Value :
+		DWORD mii id from register 2 and 3
+*/
+#endif
diff -urN linux-2.4.29/drivers/net/cnxt_emac/phyobj.h linux-2.4.29-uc1/drivers/net/cnxt_emac/phyobj.h
--- linux-2.4.29/drivers/net/cnxt_emac/phyobj.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/phyobj.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,1021 @@
+/****************************************************************************
+*
+*	Name:			phyobj.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 1997-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef _PHYOBJ_H_
+#define _PHYOBJ_H_
+
+//#include "typdef.h"
+#include "phytypes.h"
+#include "mii.h"
+#ifdef JEDIPHY	// Bright
+#include "osfile.h"
+#endif
+
+/*
+ * PHY_LINK_* -- link state information returned by PhyCheck()
+ *
+ * (1) Link summary (PHY_LINK_SUMMARY)
+ *
+ * PHY_LINK_UP        - Set when the link is operational
+ *
+ * PHY_LINK_NEW_MEDIA - Set upon initial PHY_LINK_UP, and whenever
+ *                      PHY_LINK_UP is true and a media state change
+ *                      (speed and/or duplex mode) has been detected
+ *                      since the last PhyCheck().  This status
+ *                      can be used as a signal to reconfigure a MAC's
+ *                      speed, duplex and port select settings.
+ *
+ * PHY_LINK_FDX       - Set when PHY_LINK_UP && operating Full-Duplex
+ *
+ * PHY_LINK_AUTONEG   - Set when Auto-Negotiating:  if PHY_LINK_UP,
+ *                      this indicates Auto-Negotiation complete,
+ *                      otherwise negotiation is still in progress
+ *
+ * PHY_LINK_SPEED     - Set with PHY_LINK_UP to indicate 1/10/100
+ *                      Mbit/s line speed, as follows.  One and only
+ *                      one of the following PHY_LINK_SPEED bits will
+ *                      be set when PHY_LINK_UP is set.  If PHY_LINK_UP
+ *                      is not set, then none of the PHY_LINK_SPEED
+ *                      bits will be set.
+ *
+ *                      PHY_LINK_100 - if PHY_LINK_UP && 100 Mbit/s
+ *                      PHY_LINK_10  - if PHY_LINK_UP &&  10 Mbit/s
+ *                      PHY_LINK_HPNA_10  - if PHY_LINK_UP &&   HPNA 10 Mbit/s
+ *
+ * PHY_LINK_PORT      - Set to indicate the current, active PHY port
+ *                      specific to an RSS 11617 or 11623 series
+ *                      Ethernet MAC device.  The caller should
+ *                      (carefully) reconfigure the MAC R6 Network
+ *                      Access Register (NAR, I/O offset 0x30)
+ *                      accordingly, carefully switching upon changes
+ *                      in state.  Exactly one of the following
+ *                      bits will always be set, regardless of the
+ *                      state of PHY_LINK_UP:
+ *
+ *                      PHY_LINK_PORT_MII  - Use external MII port
+ *                      PHY_LINK_PORT_7WS  - Use external 7-wire
+ *                                           serial port
+ *                      PHY_LINK_PORT_HPNA - Use internal HomePNA 
+ *                                           PHY port (not use for JEDI, RSS 11623
+ *                                           and newer devices only)
+ *                       
+ *
+ * (2) Error status (PHY_LINK_ERRORS)
+ *
+ * One or more of the following error bits are latched when ...
+ *
+ * PHY_LINK_JABBER         - Jabber condition detected (10Base-T only)
+ * PHY_LINK_PARALLEL_ERROR - Auto-Negotiation/parallel detection failure
+ * PHY_LINK_REMOTE_FAULT   - Auto-Negotiation Remote Fault received
+ *                           from the link partner
+ * PHY_LINK_INIT_ERROR     - Device not initialized
+ *
+ * (3) Media specifics (PHY_LINK_TECHNOLOGY)
+ *
+ * The PhyCheck() return code will contain exactly one of the following
+ * PHY_LINK_TECHNOLOGY bits if (PHY_LINK_UP || !PHY_LINK_AUTONEG), i.e.,
+ * whenever the link is up or if the link is down and we're trying to
+ * force a single media technology.  Otherwise, in the case that
+ * (!PHY_LINK_UP && PHY_LINK_AUTONEG), i.e., the link is down but
+ * we're advertising multiple media types, then one or more of the
+ * following bits will be set to indicate the current capability
+ * advertisement.  Depending on device capabilities, this may be a
+ * reduced subset of the <connect> argument passed via the PhyInit() or
+ * PhyConnectSet() APIs.
+ *
+ * PHY_LINK_HPNA20             - HomePNA mode 
+ *
+ * PHY_LINK_100BASE_T2FD       - 100Base-T2 Full-Duplex mode
+ * PHY_LINK_100BASE_T2         - 100Base-T2 (Half-Duplex mode)
+ * PHY_LINK_100BASE_T4         - 100Base-T4 (Half-Duplex mode)
+ * PHY_LINK_100BASE_TXFD       - 100Base-TX Full-Duplex mode
+ * PHY_LINK_100BASE_TX         - 100Base-TX (Half-Duplex mode)
+ * PHY_LINK_10BASE_TFD         - 10Base-T   Full-Duplex mode
+ * PHY_LINK_10BASE_T           - 10Base-T   (Half-Duplex mode)
+ *
+ * (4) PhyCheck()'s PHY_LINK_* Return Code Pseudo-Code
+ *
+ * The aggregate PHY_LINK_* status returned by PhyCheck() is
+ * contructed as follows:
+ *
+ * if (PHY_LINK_UP) {
+ *     One and only one PHY_LINK_1* PHY_LINK_TECHNOLOGY status bit is
+ *     set to indicate the selected link technology/speed/mode which
+ *     are currently active (PHY_LINK_TECHNOLOGY defines the
+ *     aggregation of specific technologies and maps to the 802.3u
+ *     aAutoNegLocalTechnologyAbility MIB attribute) plus some HomePNA
+ *     PHY extensions;
+ *     if (first-time PHY_LINK_UP or change in PHY_LINK_TECHNOLOGY) {
+ *         report PHY_LINK_NEW_MEDIA;
+ *     }
+ * } else { // the following should probably be ignored ... too complex
+ *     if (!PHY_LINK_AUTONEG) {
+ *         One and only one PHY_LINK_1* status bit is set to
+ *         indicate the forced mode connection attempt pending link
+ *         activation;
+ *     } else {
+ *         One or more PHY_LINK_1* status bits are set to indicate
+ *         the Auto-Negotiation advertisement pending link activation;
+ *     }
+ * }
+ *
+ * (5) PHY_LINK_DEFAULT - assume a conservative, default PHY link
+ *     state of 10 Mbit/s, half-duplex, until configured or detected
+ *     otherwise.
+ */
+#define PHY_LINK_UP             0x80000000L /* (1) PHY_LINK_SUMMARY ... */
+#define PHY_LINK_NEW_MEDIA      0x40000000L
+#define PHY_LINK_FDX            0x20000000L
+#define PHY_LINK_AUTONEG        0x10000000L
+#define PHY_LINK_SPARE1         0x08000000L
+#define PHY_LINK_100            0x04000000L // PHY_LINK_SPEED ...       
+#define PHY_LINK_10             0x02000000L
+#define PHY_LINK_HPNA_10        0x01000000L
+#define PHY_LINK_PORT_MII       0x00800000L // PHY_LINK_PORT ...
+#define PHY_LINK_PORT_7WS       0x00400000L
+//#define PHY_LINK_PORT_HPNA      0x00200000L	
+#define PHY_LINK_SPARE2         0x00100000L
+#define PHY_LINK_JABBER         0x00080000L /* (2) PHY_LINK_ERRORS ... */
+#define PHY_LINK_PARALLEL_ERROR 0x00040000L
+#define PHY_LINK_REMOTE_FAULT   0x00020000L
+#define PHY_LINK_INIT_ERROR     0x00010000L
+#define PHY_LINK_SPARE3         0x0000F000L
+#define PHY_LINK_HPNA20         0x00000800L /* (3) PHY_LINK_TECHNOLOGY ... */
+//#define PHY_LINK_1HPNA_HIPWR    0x00000400L
+//#define PHY_LINK_1HPNA_LOSPD    0x00000200L
+//#define PHY_LINK_1HPNA_HIPWR_LOSPD   0x00000100L
+#define PHY_LINK_100BASE_T2FD   0x00000080L
+#define PHY_LINK_100BASE_T2     0x00000040L
+#define PHY_LINK_FDX_PAUSE      0x00000020L
+#define PHY_LINK_100BASE_T4     0x00000010L
+#define PHY_LINK_100BASE_TXFD   0x00000008L
+#define PHY_LINK_100BASE_TX     0x00000004L
+#define PHY_LINK_10BASE_TFD     0x00000002L
+#define PHY_LINK_10BASE_T       0x00000001L
+
+#define PHY_LINK_SPEED          \
+    (PHY_LINK_100  | PHY_LINK_10   | PHY_LINK_HPNA_10)
+
+#define PHY_LINK_PORT           \
+    (PHY_LINK_PORT_MII | PHY_LINK_PORT_7WS)
+//    (PHY_LINK_PORT_MII | PHY_LINK_PORT_7WS | PHY_LINK_PORT_HPNA)
+
+#define PHY_LINK_SUMMARY        \
+    (PHY_LINK_UP       | PHY_LINK_NEW_MEDIA | PHY_LINK_FDX |    \
+     PHY_LINK_AUTONEG  | PHY_LINK_PORT      | PHY_LINK_SPEED)
+
+#define PHY_LINK_ERRORS                                 \
+    (PHY_LINK_JABBER       | PHY_LINK_PARALLEL_ERROR |  \
+     PHY_LINK_REMOTE_FAULT | PHY_LINK_INIT_ERROR)
+
+#define PHY_LINK_HPNA_TECHNOLOGY                            \
+    PHY_LINK_HPNA20
+
+#define PHY_LINK_MII_TECHNOLOGY                             \
+    (PHY_LINK_100BASE_T2FD | PHY_LINK_100BASE_T2    |       \
+     PHY_LINK_100BASE_T4   |                                \
+     PHY_LINK_100BASE_TXFD | PHY_LINK_100BASE_TX    |       \
+     PHY_LINK_10BASE_TFD   | PHY_LINK_10BASE_T)
+
+#define PHY_LINK_TECHNOLOGY                                 \
+    (PHY_LINK_MII_TECHNOLOGY | PHY_LINK_HPNA_TECHNOLOGY)
+
+#define PHY_LINK_DEFAULT        PHY_LINK_10
+
+/*
+ * PhyInit(), PhyConnectGet() and PhyConnectSet() <connect> parameters,
+ * used either to (a) force a selected line speed (10 or 100 Mbps) and
+ * mode (full- or half-duplex), or (b) to set a list of Auto-Negotiation
+ * (A-N) options when the PHY_CONN_AUTONEG bit is set.  These represent
+ * a subset of the PHY_LINK_* codes returned by PhyCheck().
+ *
+ * PHY_CONN_CURRENT - indicates that the current connection settings
+ *     are to be retained; these settings were set by a previous
+ *     PhyInit()/PhyConnSet(), otherwise they were established by the
+ *     default hardware strapping of the device's AN[2:0] pins.
+ *
+ * PHY_CONN_AUTONEG - when set, indicates that one or more
+ *     Auto-Negotiation settings are to advertised, otherwise a single
+ *     configuration mode is to be forced.  Warning:  Set by itself,
+ *     this flag directs the PHY to advertise *NO* capabilities,
+ *     which may not be the desired result.  This flag must be or-ed
+ *     with one or more of the PHY_CONN_TECHNOLOGY bits.  Optionally,
+ *     the caller can use PHY_CONN_AUTONEG_ALL_MEDIA to utilize any
+ *     available media.
+ *
+ * PHY_CONN_PORT_* - when one of [MII|7WS|HPNA] is set, indicates a
+ *     current port selection specified by the caller of PhyInit() or
+ *     PhyConnectSet().  When not set, the caller isn't indicating
+ *     the current PHY device port selection.
+ *
+ * PHY_CONN_AUTONEG_REMOTE_FAULT - a Remote Fault indication should
+ *     be advertised during Auto-Negotiation, applicable only when
+ *     accompanied by PHY_CONN_AUTONEG.
+ *
+ * PHY_CONN_AUTONEG_FDX_PAUSE - adveritise Full-Duplex Pause mode (?),
+ *     applicable only when accompanied by PHY_CONN_AUTONEG.
+ *
+ * PHY_CONN_1* - various link speeds and duplex modes whose aggregation
+ *     is defined by PHY_CONN_TECHNOLOGY.
+ *
+ * PHY_CONN_ANY_* - used to request any available 1-, 10- or 100-Mbps
+ *     technology supported by the PHY device.  Use these settings when
+ *     uncertain of the precise technology (100Base-TX, 100Base-T2, or
+ *     even the presently unsupported 100Base-T4) to be deployed.
+ *     The "FD" suffix denotes full-duplex, otherwise half-duplex applies.
+ *     PHY_CONN_FORCE_ANY_MEDIA and PHY_CONN_AUTONEG_ALL_MEDIA are
+ *     all-technology wildcards which respectively force the highest
+ *     priority technology or advertise all capabilities supported by the
+ *     device, in the following order of precedence:  100Base-T2FD,
+ *     100Base-TXFD, 100Base-T2, 100Base-T4, 100Base-TX, 10Base-TFD,
+ *     10Base-T).  Warning:  These PHY_CONN_ANY_* selections will fail if
+ *     the "phy.c" module is compiled with the non-default,
+ *     STRICT_PARAMETER_CHECKING switch #defined.
+ *
+ * PHY_CONN_DEFAULT - default connection values, dependent upon
+ *     conditional *_PHY compilation switch.
+ */
+#define PHY_CONN_CURRENT                0
+#define PHY_CONN_AUTONEG                PHY_LINK_AUTONEG
+
+#define PHY_CONN_AUTONEG_REMOTE_FAULT   PHY_LINK_REMOTE_FAULT
+
+#define PHY_CONN_HPNA20                 PHY_LINK_HPNA20
+#define PHY_CONN_100BASE_T2FD           PHY_LINK_100BASE_T2FD
+#define PHY_CONN_100BASE_T2             PHY_LINK_100BASE_T2
+#define PHY_CONN_AUTONEG_FDX_PAUSE      PHY_LINK_FDX_PAUSE
+#define PHY_CONN_100BASE_T4             PHY_LINK_100BASE_T4
+#define PHY_CONN_100BASE_TXFD           PHY_LINK_100BASE_TXFD
+#define PHY_CONN_100BASE_TX             PHY_LINK_100BASE_TX
+#define PHY_CONN_10BASE_TFD             PHY_LINK_10BASE_TFD
+#define PHY_CONN_10BASE_T               PHY_LINK_10BASE_T
+#define PHY_CONN_HPNA_TECHNOLOGY        PHY_LINK_HPNA_TECHNOLOGY
+#define PHY_CONN_MII_TECHNOLOGY         PHY_LINK_MII_TECHNOLOGY
+#define PHY_CONN_TECHNOLOGY             PHY_LINK_TECHNOLOGY
+
+/* Any (defaults to highest capability) HomePNA settting */
+#define PHY_CONN_ANY_HPNA20                                     \
+     PHY_CONN_HPNA20
+
+/* Any 10Base-T half-duplex setting */
+#define PHY_CONN_ANY_10BASE_T           PHY_CONN_10BASE_T
+
+/* Any 10Base-T full-duplex setting */
+#define PHY_CONN_ANY_10BASE_TFD         PHY_CONN_10BASE_TFD
+
+/* Any available 100Base-T half-duplex capability */
+#define PHY_CONN_ANY_100BASE_T          \
+    (PHY_CONN_100BASE_T2 | PHY_CONN_100BASE_T4 | PHY_CONN_100BASE_TX)
+
+/* Any available 100Base-T full-duplex capability */
+#define PHY_CONN_ANY_100BASE_TFD        \
+    (PHY_CONN_100BASE_T2FD | PHY_CONN_100BASE_TXFD)
+
+/* Force highest available HomePNA or 10/100 MII capability */
+#define PHY_CONN_FORCE_ANY_MEDIA        \
+    (PHY_CONN_ANY_HPNA20     |          \
+     PHY_CONN_ANY_10BASE_T   |          \
+     PHY_CONN_ANY_10BASE_TFD |          \
+     PHY_CONN_ANY_100BASE_T  |          \
+     PHY_CONN_ANY_100BASE_TFD)
+
+/* Auto-Negotiate all available HomePNA and/or 10/100 MII capabilities */
+#define PHY_CONN_AUTONEG_ALL_MEDIA      \
+    (PHY_CONN_AUTONEG | PHY_CONN_FORCE_ANY_MEDIA)
+
+/* Only Auto-Negotiate 10/100 MII capabilities: exclude HomePNA */
+#define PHY_CONN_AUTONEG_ALL_MII_MEDIA  \
+    (PHY_CONN_AUTONEG_ALL_MEDIA & ~PHY_CONN_ANY_HPNA20)
+
+/* Only Auto-Negotiate HomePNA capabilities: exclude 10/100 MII */
+#define PHY_CONN_AUTONEG_ALL_HPNA_MEDIA  \
+    (PHY_CONN_AUTONEG | PHY_CONN_ANY_HPNA20)
+
+/* Default: Auto-Negotiate HomePNA, 10Base-T and 100Base-TX */
+#define PHY_CONN_DEFAULT                           \
+    (PHY_CONN_AUTONEG    |                         \
+     PHY_CONN_ANY_HPNA20 |                         \
+     PHY_CONN_10BASE_T   | PHY_CONN_10BASE_TFD   | \
+     PHY_CONN_100BASE_TX | PHY_CONN_100BASE_TXFD   \
+    )
+
+/*
+ * The PhyInit() <phy_addr> parameter conveys either an explicit PHY
+ * address value in the range of PHY_ADDR_MIN to PHY_ADDR_MAX, or
+ * specifies PHY_ADDR_ANY which directs PhyInit() to search for
+ * the first responding PHY in the range PHY_ADDR_MIN..PHY_ADDR_MAX.
+ * Moreover, in a multiple PHY environment, the caller can use the
+ * PHY_ADDR_NEXT() macro to search for the next responding PHY
+ * starting at an address above the specified value.
+ *
+ * The following examples demonstrate search and initialization of
+ * (a) a single PHY at MII address 5, (b) the first -- and perhaps
+ * only -- PHY found on the MII bus, (c) the first PHY found on the
+ * MII bus excluding PHY 0, which may be reserved for a special
+ * purpose such as hub management.
+ * 
+ *     static PHY       phy_space[MAX_SUPPORTED_PHYS];
+ *     PHY             *phy = &phy_space[0];
+ *     DWORD            my_adapter;     // e.g., MAC register address
+ *
+ *     (a) PhyInit(my_adapter, phy, 5, ...)
+ *     (b) PhyInit(my_adapter, phy, PHY_ADDR_ANY, ...)
+ *     (c) PhyInit(my_adapter, phy, PHY_ADDR_NEXT(PHY_ADDR_MGMT), ...)
+ * 
+ * A multiple PHY (e.g., intelligent hub) search might look something
+ * like this:
+ *
+ *     static PHY       phy_space[MAX_SUPPORTED_PHYS];
+ *     PHY             *phy = &phy_space[0];
+ *     DWORD            my_adapter;     // e.g., MAC register address
+ *     BYTE             phy_addr = PHY_ADDR_ANY;
+ *     PHY_STATUS       status;
+ *
+ *     // Search (and isolate) multiple MII PHYs
+ *     do {
+ *         status = PhyInit(my_adapter, phy, phy_addr,
+ *                          PHY_CONN_CURRENT,
+ *                          PHY_HWOPTS_DONT_CONNECT);
+ *         if (status == PHY_STATUS_NOT_FOUND) {
+ *             break;
+ *         } else if (status != PHY_STATUS_OK) {
+ *             // process other PhyInit() failures ...
+ *         }
+ *         phy_addr = PHY_ADDR_NEXT(phy->addr);
+ *     } while (++phy < &phy_space[MAX_SUPPORTED_PHYS]);
+ */
+#define PHY_ADDR_MIN            ((BYTE) 0)
+#define PHY_ADDR_MAX            ((BYTE) 31)
+#define PHY_ADDR_NEXT(addr)     ((BYTE) -((addr) + 1))
+#define PHY_ADDR_ANY            PHY_ADDR_NEXT(PHY_ADDR_MAX)
+#define PHY_ADDR_MGMT           PHY_ADDR_MIN
+#define PHY_ADDR_0              ((BYTE) 0)
+
+#ifdef _H2INC_                  /* MASM H2INC.exe utility workaround */
+#undef PHY_ADDR_MIN
+#undef PHY_ADDR_MAX
+#undef PHY_ADDR_ANY
+#undef PHY_ADDR_MGMT
+#define PHY_ADDR_MIN            0       /* can't handle type cast?!! */
+#define PHY_ADDR_MAX            31
+#define PHY_ADDR_ANY            -32     /* can't handle macro func */
+#define PHY_ADDR_MGMT           PHY_ADDR_MIN
+#define PHY_ADDR_0              0
+#endif
+
+/*
+ * PhyInit() <hw_options> -- one or more PHY_HWOPTS_* bits as follows.
+ * Many HWOPTS are PHY- or adapter-dependent, and will be silently
+ * ignored if not supported.
+ *
+ * PHY_HWOPTS_* Supported Options:
+ *
+ * NONE         - Don't override any HW defaults
+ *
+ * REPEATER     - Force PHY Repeater mode such that CRS is only asserted
+ *                due to Rx activity.  The default is to force PHY Node
+ *                mode which asserts CRS due to Rx or Tx in half-duplex
+ *                mode only (802.3u CRS behavior is undefined in full-
+ *                duplex mode)
+ *
+ * READ_ONLY    - Read, but don't write to PHY devices.  Useful as a
+ *                diagnostic tool, e.g., the phyck.exe utility to query
+ *                MII and SPI registers without disturbing the
+ *                configuration maintained by a background NDIS driver.
+ *
+ * CK25DIS      - PHY dependent, use with caution.  On the NSC,
+ *                disables CLK25 pin (Hi-Z) if external clock unused.
+ *                This breaks some NICs (SMC 9332, DEC DE500) which
+ *                apparently rely on this output.  On the TDK, invokes
+ *                their R16.RXCC option, which may have adverse side
+ *                effects upon Auto-Negotiation, so the PhyCheck()
+ *                routine trys to compensate by enabling upon link up
+ *                and disabling upon link down.
+ *
+ * TX_BP4B5B    - 100Base-TX bypass 4B/5B endec (repeater applications)
+ * TX_BPSCR     - 100Base-TX bypass scrambler (100Base-FX applications)
+ * TX_BPALIGN   - 100Base-TX bypass all Tx/Rx conditioning
+ *
+ * HWRESET_MASK - Enumerated set of 15 GPIO hardware reset options:
+ *                    HWRESET_GPn     - Active-high reset using GPn
+ *                    HWRESET_GPn_NOT - Active-low  reset using GPn
+ *                    HWRESET_GPn_R12 - Active-high reset using GPn
+ *                                      via obsolete RSS 1161x MAC R12
+ *                    HWRESET_ALL     - Active-high reset using GP[3:0]
+ *                    HWRESET_ALL_NOT - Active-low  reset using GP[3:0]
+ *                    HWRESET_ALL_R12 - Active-high reset using GP[3:0]
+ *                                      via obsolete RSS 1161x MAC R12
+ *                Where GPn is LAN General Purpose I/O GP0, GP1, GP2
+ *                or GP3. The resultant hardware reset pulse is an
+ *                active-high signal, unless the _NOT suffix is
+ *                specified to generate an active-low hardware reset
+ *                pulse.  The _R12 suffix provides a backwards-
+ *                compatible option for use with pre-production devices
+ *                (RSS 11606, 11610 and 11611 and compatibles).
+ *
+ *                The _ALL suffix provides a shotgun, wildcard reset
+ *                against all GPIO signals, GP[3:0].  This is useful in
+ *                cases where none of the GPIO signals are dedicated
+ *                as inputs, and a driver is supporting multiple adapter
+ *                GPIO configurations and there's no adverse affect
+ *                from driving unused GPIO lines.  The _ALL_NOT suffix
+ *                provides an active-low signal on all GP[3:0], and the
+ *                _ALL_R12 provides an active-high signal on all GP[3:0]
+ *                using the antiquated RSS 11611 R12 register interface.
+ *
+ * ISOLATE      - Disable (tri-state) the active HomePNA or MII device's
+ *                data interface and underlying PMD interface.  The
+ *                associated SPI or MDC/MDIO Serial Management Interface
+ *                remains enabled for subsequent management commands.
+ *                This is equivalent to calling PhyDisable().
+ *
+ * HPNA_        - Allow a remote HomePNA master device to reconfigure
+ * CMD_ENABLE     the local HomePNA PHY device's speed and power mode
+ *                settings.  This is normally disabled, as the v1.0
+ *                device implementations have a bug in which noise
+ *                can be mistaken for a remote command, causing
+ *                inadvertant reconfiguration.
+ *
+ * FDX_CRS      - Set PHY-specific CRS option which alters
+ *                the CRS behavior in full-duplex mode to assert CRS
+ *                during transmission rather than during reception
+ *                (its default).  This is an RSS61x MAC SAR-26
+ *                workaround which may (?) alleviate Tx-hangs (SAR-23)
+ *                in full-duplex mode.
+ *
+ * DONT_SWRESET - Don't issue (otherwise) mandatory software reset
+ *
+ * MII_SEARCH_0 - Begin a <PHY_ADDR_ANY> MII search with address-0,
+ *                which was the pre-v1.50 PHY Driver default.
+ *                Otherwise, perform an MII search from addresses 1..31,
+ *                attempting address-0 only if no other MII PHY is
+ *                found.  (Some MII PHYs erroneously treat address-0 as
+ *                a broadcast address, others have side-effects.)
+ *                Unless this option is specified, we try 1..31 followed
+ *                by zero.  If the option is specified, we try 0..31.
+ *
+ * MII_PREAMBLE - If this option is activated, the PHY driver will
+ *                always send a 32-bit MDIO preamble during MII reads
+ *                and writes.  Otherwise, the PHY driver will attempt
+ *                to suppress the 32-bit preamble, provided the device
+ *                hardware supports this feature as indicated by the
+ *                MII register 1.6 status bit.
+ *
+ * NO_MII_      - HomePNA-only NICs can save time by eliminating a
+ * SEARCH         PhyInit() MII device search.
+ *
+ * NO_HPNA      - MII-only NICs can save time by eliminating a
+ * SEARCH         PhyInit() search for both internal (RSS 11623) and
+ *                external HomePNA devices.
+ *
+ * NO_HPNA_     - RSS 11623 NICs can save time by eliminating a
+ * EXT_SEARCH     PhyInit() search for external HomePNA devices.
+ *
+ * HPNA_PORT_   - If this option is selected, a link indication from
+ * PRIORITY       a HPNA device will take precedence over a
+ *                simultaneous link indication from a ethernet 10/100 MII
+ *                device.  Otherwise the default case is for the higher
+ *                speed 10/100 MII device precedence.  This affects
+ *                the PhyCheck() link indication in the unlikely case
+ *                that both devices report link, as only the highest
+ *                priority capability will be reported.  It also has a
+ *                side-effect in that the PhyCheck() routine will switch
+ *                from an MII to HomePNA PHY device whenever the MII
+ *                link goes down (i.e., cable removed from 10/100 Ether
+ *                hub).
+ *
+ * MII_PORT_    - Similar to HPNA_PORT_PRIORITY.  Since by default,
+ * PRIORITY       MII > HPNA, this doesn't affect the simultaneous
+ *                link status.  However, it does determine the default
+ *                port selected (MII) at PhyInit() time and subsequent
+ *                to link down.
+ *
+ * PORT_HOPPING - If this option is selected and multi-port PHY devices
+ *                are present, i.e., both 1M8 HomePNA and 10/100 MII
+ *                devices found, then the PhyCheck() routine will
+ *                force a port hop every LINK_DOWN_HOP_COUNT calls
+ *                when the link is down.  The default value of the
+ *                "phy.c" LINK_DOWN_HOP_COUNT is 5, which allows
+ *                ten seconds per port for a 2-second check period.
+ *                This option should not be enabled when the app/driver
+ *                polls PhyCheck() repeatedly in an initialization loop.
+ *
+ *                This option is recommended for broken PHY devices which
+ *                cannot achieve link while configured in the MII isolate
+ *                mode.  To date, we've found that the National
+ *                Semiconductor DP83840 won't work at all when isolated
+ *                (it also disables its twisted pair PMD interface), and
+ *                the Level One LXT 970 and Enable Semiconductor PHYs
+ *                curiously can achieve link when connected to 10 but
+ *                not 100 Mbit hubs and switches.
+ *
+ *                ------------------------------------------------------
+ *
+ *                Note: the following truth table depicts the complex
+ *                interaction among the PHY_HWOPTS_PORT_HOPPING (HOP),
+ *                PHY_HWOPTS_HPNA_PORT_PRIORITY (HPNA) and the
+ *                PHY_HWOPTS_MII_PORT_PRIORITY (MII) options.  This
+ *                table is only applicable when BOTH devices (HomePNA and
+ *                MII) are present.  As can be seen, MII priority
+ *                primarily affects the PhyInit() default port select,
+ *                HPNA priority primarily affects PhyCheck() in the
+ *                rare (unlikely?) case that both links are up, and
+ *                HOP determines whether a port switch is made when
+ *                both links are down.  As a secondary effect when
+ *                HOP is disabled, MII supercedes HPNA priority when
+ *                both links are down, otherwise HPNA supercedes the
+ *                the current, active port which is retained in the
+ *                default case where no options are in effect.  Whew!
+ *
+ *                What's not depicted is the simple case where only one
+ *                port is reporting link: that port is always selected,
+ *                regardless of multi-port options.
+ *
+ *                         Multi-Port Selection Truth Table           
+ *
+ *                +==================++=================+===========+
+ *                |                  ||    PhyCheck()   |           |
+ *                |  PHY HW option   |+---------+-------+           |
+ *                |                  || Both    | Both  | PhyInit() |
+ *                +=====+======+=====+| Links   | Links | Default   |
+ *                | HOP | HPNA | MII || Down**  | Up    | Port      |
+ *                +=====+======+=====++=========+=======+===========+
+ *     (default)  |  0  |   0  |  0  || current |  MII  |   HPNA    |
+ *                +-----+------+-----++---------+-------+-----------+
+ *                |  0  |   0  |  1  ||   MII*  |  MII  |    MII*   |
+ *                +-----+------+-----++---------+-------+-----------+
+ *                |  0  |   1  |  0  ||  HPNA*  | HPNA* |   HPNA    |
+ *                +-----+------+-----++---------+-------+-----------+
+ *                |  0  |   1  |  1  ||   MII*  | HPNA* |    MII*   |
+ *                +=====+======+=====++=========+=======+===========+
+ *                |  1  |   0  |  0  ||  other* |  MII  |   HPNA    |
+ *                +-----+------+-----++---------+-------+-----------+
+ *                |  1  |   0  |  1  ||  other* |  MII  |    MII*   |
+ *                +-----+------+-----++---------+-------+-----------+
+ *                |  1  |   1  |  0  ||  other* | HPNA* |   HPNA    |
+ *                +-----+------+-----++---------+-------+-----------+
+ *                |  1  |   1  |  1  ||  other* | HPNA* |    MII*   |
+ *                +-----+------+-----++---------+-------+-----------+
+ *
+ *                *  - Indicates behavior change with respect to the
+ *                     default action.
+ *
+ *                ** - With both links down, "current" denotes the
+ *                     currently active port (default or last link),
+ *                     whereas "other" denotes a swap to the other,
+ *                     presently inactive port.  All port switching is
+ *                     governed by the nominal LINK_DOWN_HOP_COUNT
+ *                     value of 5, which yields a 10-second rate
+ *                     assuming a periodic, 2-second PhyCheck() cycle.
+ *                     As such, a link-down port switch won't occur
+ *                     for ten seconds, though a single- or dual-port
+ *                     link-up event will instanly effect a port switch.
+ *
+ *                ------------------------------------------------------
+ *
+ * MAC_         - RSS 11617 and 11623 feature: If this option is selected,
+ * PORT_MGMT      the PHY Driver's PhyInit() and PhyCheck() routines will
+ *                assume management of the MAC Network Access Register
+ *                (NAR, R6 offset 0x30) configuration of PHY port select
+ *                bits [18:17], full-duplex mode select bit [09], and
+ *                the 10/100 speed select bit [22].  All other NAR register
+ *                bits will be retained intact, with the exception that
+ *                if the MAC's transmitter and/or receiver are currently
+ *                running, they may be temporarily stopped (this can take
+ *                up to 5-10 milliseconds) while all MII and HomePNA PHY
+ *                devices are tri-stated, the MAC port is switched, an
+ *                active MII or HomePNA PHY is enabled and then the prior
+ *                receiver and transmitter states are restored.
+ *
+ *                In addition, if a non-null <soft_nar> is passed to the
+ *                PhyInit() routine, the caller can specify the address of
+ *                its 32-bit "soft NAR" register value field which
+ *                presumably contains a driver's local, shadow copy of
+ *                the NAR register contents.  This is HIGHLY recommended
+ *                in conjunction with PHY_HWOPTS_MAC_PORT_MGMT to avoid
+ *                coherency mismatches between the hardware and shadow
+ *                software copies of the NAR register.  In this manner,
+ *                both the MAC device driver and the PhyCheck() routine
+ *                can safely manipulate the NAR register in a single-
+ *                threaded (or blocked deserialized) driver.
+ *
+ * FAST_INIT    - Avoids time consuming MII and SPI searches and device
+ *                parsing PHY devices previously initialized via
+ *                PhyInit().  Effectively re-uses the values discovered
+ *                during the initial PhyInit() call.
+ *
+ *                (Not yet supported)
+ *
+ * STRICT_      - Default unspecified provides "loose" checking by the
+ * PARM_          PhyConnectSet() routine, which is called by PhyInit().
+ * CHECKING       When specified, PhyConnectSet() will reject a
+ *                connection, reporting PHY_STATUS_UNSUPPORTED_MEDIA,
+ *                if *any* <connect> parameter media setting is not
+ *                supported by the device.  In contrast, when
+ *                unspecified, PhyConnectSet() will accept the
+ *                directive if *at least one* <connect> media setting
+ *                is supported by the device(s).  For example, assume
+ *                a 100Base-TX device supporting both full- and
+ *                half-duplex 100Base-TX and 10Base-T operation.  By
+ *                default (#undefined), a <connect> request to
+ *                Auto-Negotiate for these capabilities plus an
+ *                unsupported 100Base-T2 mode is accepted.  In contrast,
+ *                the same <connect> request is rejected due to
+ *                unsupported -T2 service, even though the other
+ *                services are available.
+ *
+ *                It's likely that NIC drivers (NDIS) won't specify
+ *                this option in order to wildcard the connect
+ *                directive to "whatever's possible" whereas diagnostic
+ *                or test utilities may use the option to verify that
+ *                expected devices are present.
+ *
+ * ACTIVE_AN_   - Restarts Auto-negotiation whenever the MII port
+ * RESTART        becomes newly active, i.e., transitions from disabled
+ *                (isolated) to enabled (de-isolated) state.  The
+ *                NSC PHY automatically gets this setting; other PHYs
+ *                may also need to be kicked when coming out of
+ *                isolation.
+ *
+ * ALT_1HZ_     - Use alternate, 1-Hz Conexant link detection algorithm
+ * HPNA_LINK      instead of the standard 0.5 Hz HomePNA algorithm.
+ *                This version only transmits a heartbeat packet if
+ *                neither a PHY-level transmit or receive indication
+ *                occurred during the previous 1-second sample interval.
+ *                This is the preferred option for the 1161x chipset
+ *                family to avoid excessive or late collision
+ *                problems.
+ *
+ * X3_DEVICE    - Force CN7221 (11625) "Ramses" X3 device version
+ *                settings.
+ *
+ * GP0_SPI_DOUT - Use alternate Ramses SPI DOUT interface such that
+ *                LAN_GPIO[0] is read in lieu of EEDO and ROM_CS#
+ *                is used in lieu of LAN_GPIO[0] for Ramses RESET#.
+ *
+ * --------------
+ *
+ * NIC_DEFAULT  - Recommended default (your implementation may vary)
+ * NIC_*        - Various adapter-specific options
+ *
+ * --------------
+ * Discontinued PHY_HWOPTS_* Options (No Longer Supported):
+ *
+ * DEFAULTS     - Replaced by PHY_HWOPTS_NONE to avoid confusion
+ * NODE         - !REPEATER implies NODE, no need for separate control
+ * LED_COL      - Obscure NSC-only option to change COL LED definition
+ * PRE_HWRESET  - Superceded by HWRESET_GP2..5* settings
+ * POST_HWRESET - No compelling need for a hardware reset subsequent
+ *                to the MII search phase of PhyInit().  The updated
+ *                HWRESET_GP2..5* options present ample flexibility for
+ *                NICs whose GPIO are tied to a PHY Reset.
+ * DONT_CONNECT - Replaced by ISOLATE
+ * ISR          - Enable PHY interrupts upon change in link state
+ */
+
+/* Supported Options */
+#define PHY_HWOPTS_NONE                 0x00000000L
+#define PHY_HWOPTS_REPEATER             0x00000001L
+#define PHY_HWOPTS_READ_ONLY            0x00000002L
+#define PHY_HWOPTS_CK25DIS              0x00000004L
+#define PHY_HWOPTS_TX_BP4B5B            0x00000008L
+#define PHY_HWOPTS_TX_BPSCR             0x00000010L
+#define PHY_HWOPTS_TX_BPALIGN           0x00000020L
+#define PHY_HWOPTS_HWRESET_MASK         0x000003C0L /* listed below */
+#define PHY_HWOPTS_ISOLATE              0x00000400L
+#define PHY_HWOPTS_HPNA_CMD_ENABLE      0x00000800L
+#define PHY_HWOPTS_FDX_CRS              0x00001000L
+#define PHY_HWOPTS_DONT_SWRESET         0x00002000L
+#define PHY_HWOPTS_MII_SEARCH_0         0x00004000L
+#define PHY_HWOPTS_MII_PREAMBLE         0x00008000L
+#define PHY_HWOPTS_NO_ETH_SEARCH        0x00010000L
+#define PHY_HWOPTS_NO_HPNA_SEARCH       0x00020000L
+#define PHY_HWOPTS_NO_HPNA_EXT_SEARCH   0x00040000L
+#define PHY_HWOPTS_HPNA_PORT_PRIORITY   0x00080000L
+#define PHY_HWOPTS_MII_PORT_PRIORITY    0x00100000L
+#define PHY_HWOPTS_PORT_HOPPING         0x00200000L
+#define PHY_HWOPTS_MAC_PORT_MGMT        0x00400000L
+#define PHY_HWOPTS_FAST_INIT            0x00800000L
+#define PHY_HWOPTS_STRICT_PARM_CHECKING 0x01000000L
+#define PHY_HWOPTS_ACTIVE_AN_RESTART    0x02000000L
+#define PHY_HWOPTS_ALT_1HZ_HPNA_LINK    0x04000000L // obsolete for JEDI
+#define PHY_HWOPTS_X3_DEVICE            0x08000000L
+#define PHY_HWOPTS_GP0_SPI_DOUT         0x10000000L
+#define PHY_HWOPTS_HPNA7WS              0x20000000L
+#ifdef P51
+#define PHY_HWOPTS_P51_HLAN             0x40000000L
+#endif
+
+/*
+ * PHY HW Reset enumerations via GPIO.  A _GP0.._GP3 suffix identifies
+ * the general purpose I/O output port used to generate a nominal
+ * one microsecond, active-high hardware reset pulse.  An additional
+ * _NOT suffix specifies an active-low reset pulse.  The QSI PHY is an
+ * example of a device requiring an active-low reset.
+ *
+ * Beginning with the production RSS 11617 devices, a.k.a. 11611
+ * version 5 (v5), the GPIO register migrated from MAC register R12 to
+ * R15.  As such, use of pre-production RSS 11611 (v3 and v4), 11610,
+ * 11606 and compatible devices is facilitated via the _R12 suffix
+ * which directs the PHY driver to access GPIO via the antiquated R12
+ * device interface.  Note that the _NOT active-low reset capability
+ * is not supported using these older, obsoleted pre-production devices.
+ * This is strictly a PHY Driver software constraint, and not a hardware
+ * restriction of the earlier devices.
+ *
+ * The _ALL suffixes provide wildcard (shotgun) resets using all four
+ * GPIO[3:0] signal lines.  _ALL and _ALL_NOT provide respective
+ * active-high and active-low reset pulses via the MAC's R15 register,
+ * whereas _ALL_R12 provides an active-high reset pulse using the
+ * antiquated MAC R12 register for older device support.
+ *
+ *      PHY_HWOPTS_HWRESET_MASK         0x03C0L
+ */
+#define PHY_HWOPTS_HWRESET_GP0          0x0040L /* Active-high resets */
+#define PHY_HWOPTS_HWRESET_GP1          0x0080L
+#define PHY_HWOPTS_HWRESET_GP2          0x00C0L
+#define PHY_HWOPTS_HWRESET_GP3          0x0100L
+#define PHY_HWOPTS_HWRESET_GP0_NOT      0x0140L /* Active-low resets */
+#define PHY_HWOPTS_HWRESET_GP1_NOT      0x0180L
+#define PHY_HWOPTS_HWRESET_GP2_NOT      0x01C0L
+#define PHY_HWOPTS_HWRESET_GP3_NOT      0x0200L
+#define PHY_HWOPTS_HWRESET_GP0_R12      0x0240L /* Obsoleted R12 GPIO */
+#define PHY_HWOPTS_HWRESET_GP1_R12      0x0280L
+#define PHY_HWOPTS_HWRESET_GP2_R12      0x02C0L
+#define PHY_HWOPTS_HWRESET_GP3_R12      0x0300L
+#define PHY_HWOPTS_HWRESET_ALL          0x0340L /* Wildcard, all GPIO */
+#define PHY_HWOPTS_HWRESET_ALL_NOT      0x0380L
+#define PHY_HWOPTS_HWRESET_ALL_R12      0x03C0L
+
+/*
+ * PHY_HWOPTS_NIC_* NIC-specific Hardware Options
+ *
+ * Usage is primarily intended for RSS test boards.  OEMs should use
+ * PHY_HWOPTS_NIC_DEFAULT or may #define their own NIC-specific set of
+ * options as necessary.  PHY_HWOPTS_NIC_EN5032 is an example of such
+ * an option.
+ * 
+ * The RSS 11617 (a.k.a. 11611 v5) is the first production LANfinity
+ * MAC device to use the newer, R15 GPIO register.  All others are
+ * pre-production or compatible devices which use the older R12 GPIO
+ * register, hence must use the _R12 suffix to direct the PHY driver
+ * to access GPIO via R12.
+ *
+ * The 11623 (RS7112) with integrated HomePNA PHY, uses GP0 as an
+ * external 10/100 PHY link LED to support the optional PC 98/99
+ * wake-on-link capability.
+ *
+ * The 11617 (RS7111A) reference board, plus pre-production 11611 and
+ * 11610 test boards have GP0 tied to PHY hardware reset.  The original
+ * 11606 test board uses GP3 as PHY hardware reset.
+ */
+#define PHY_HWOPTS_NIC_DEFAULT          PHY_HWOPTS_NONE
+/* Changed PHY_HWOPTS_NIC_RSS11623 define to support 11623/Ramses board.*/
+#define PHY_HWOPTS_NIC_RSS11623         \
+    (PHY_HWOPTS_ALT_1HZ_HPNA_LINK | PHY_HWOPTS_HWRESET_GP0_NOT)     
+#define PHY_HWOPTS_NIC_RSS11611         PHY_HWOPTS_HWRESET_GP0_R12
+#define PHY_HWOPTS_NIC_RSS11610         PHY_HWOPTS_HWRESET_GP0_R12
+#define PHY_HWOPTS_NIC_RSS11606         PHY_HWOPTS_HWRESET_GP3_R12
+#define PHY_HWOPTS_NIC_EN1207           PHY_HWOPTS_NIC_DEFAULT
+#define PHY_HWOPTS_NIC_EN5032           PHY_HWOPTS_NIC_DEFAULT
+#define PHY_HWOPTS_NIC_OEM_GP0          PHY_HWOPTS_HWRESET_GP0
+#define PHY_HWOPTS_NIC_OEM_GP0_NOT      PHY_HWOPTS_HWRESET_GP0_NOT
+
+/* Discontinued Options (no longer supported) */
+#undef PHY_HWOPTS_DEFAULTS      /* was 0x0000 */
+#undef PHY_HWOPTS_NODE          /* was 0x0002 */
+#undef PHY_HWOPTS_LED_COL       /* was 0x0008 */
+#undef PHY_HWOPTS_PRE_HWRESET   /* was 0x0080 */
+#undef PHY_HWOPTS_POST_HWRESET  /* was 0x0100 */
+#undef PHY_HWOPTS_DONT_CONNECT  /* was 0x0400 */
+#undef PHY_HWOPTS_ISR           /* was 0x0800 */
+
+/*
+ * Result codes for many PHY Driver APIs, e.g., PhyInit(), software
+ * PhyReset(), PhyDisable(), PhyEnable(), PhyConnectSet(), etc.
+ */
+typedef enum _phy_status_ {
+    PHY_STATUS_OK = 0,
+    PHY_STATUS_NOT_FOUND,               /* PhyInit() errors ... */
+    PHY_STATUS_UNSUPPORTED_FUNCTION,
+    PHY_STATUS_PORTABILITY_ERROR,
+    PHY_STATUS_RESET_ERROR,             /* PhyReset() bit stuck */
+    PHY_STATUS_UNSUPPORTED_MEDIA,       /* PhyConnSet() error */
+    PHY_STATUS_UNINITIALIZED,
+    PHY_STATUS_ERROR_MISC 
+    /* etc. */
+} PHY_STATUS;
+
+/* PhyEnable() and PhyDisable() <port_select> argument values */
+typedef enum _phy_port_ {
+    /* physical ports */
+    PHY_PORT_NONE     = 0x00,
+    PHY_PORT_MII      = 0x01,   /* 10/100 MII data signals ... */
+    PHY_PORT_MII_PMD  = 0x02,   /* and associated MDI twisted pair */
+    PHY_PORT_HPNA_7WS = 0x04,   /* HPNA 7-wire serial data */
+    PHY_PORT_HPNA_MII = 0x08   /* HPNA Mii */
+} PHY_PORT;
+#define PHY_PORT_MII_DEVICE      (PHY_PORT_MII | PHY_PORT_MII_PMD)
+#define PHY_PORT_HPNA_DEVICES    (PHY_PORT_HPNA_7WS | PHY_PORT_HPNA_MII)
+#define PHY_PORT_ALL             \
+    (PHY_PORT_MII_DEVICE | PHY_PORT_HPNA_DEVICES)
+
+/* PhyLoopback() <mode> options */
+typedef enum _phy_loopback_ {
+    PHY_LOOPBACK_OFF = 0,       /* default  - loopback disabled */
+    PHY_LOOPBACK_MII,           /* short    - MAC/PHY @ MII */
+    PHY_LOOPBACK_PMD,           /* long     - MAC/PHY @ PMD Tx/Rx */
+    PHY_LOOPBACK_REMOTE,        /* external - PMD Rx to Tx (BER test) */
+    PHY_LOOPBACK_10BASE_T       /* ???      - NSC compatibility mode */
+} PHY_LOOPBACK;
+
+
+/* PHY device descriptor */
+
+/* PHY device descriptor */
+#define MAX_MII_PHY		2
+#define JEDI_MII_PHY		0
+#define ETH_MII_PHY		1
+
+
+typedef struct _phy_ {
+#ifndef _H2INC_
+    struct _phy_       *next;   /* Nominal value/usage here */
+#else
+    DWORD              *next;   /* MASM H2INC.exe utility workaroud */
+#endif
+    void				*LinkLayerAdapter;	// HPNALLOBJ
+    int					frame_ctl_length ; // 4 bytes prefix control for JEDI phy, 0: for ethernet phy
+    PHY_PORT            devices;			// indicate what PHYS on the board
+	// set by ??Phy_SetUp can be PHY_PORT_HPNA_DEVICES [|] PHY_PORT_MII_DEVICE
+    PHY_PORT            active_port;
+    PHY_PORT            inactive_port;
+    PHY_PORT            enabled_port;   /* nominally == active_port */
+    DWORD               link_down_count;
+
+	MIIOBJ *pActive_miiphy ;		// point to active mii_phy
+	MIIOBJ mii_phy[MAX_MII_PHY] ;
+
+//	{	// for Ethernet Phy
+	PHY_PORT            mii_port;
+	BOOLEAN             mii_isolated;
+
+	PHY_LOOPBACK        loopback;		// not work for JEDI 
+	WORD                anar;			// ETHERNET only, not for JEDI
+//	}
+
+//	{	// for Jedi HPNA Phy
+	PHY_PORT            hpna_port;
+   BOOLEAN             hpna_link_pending;
+	BOOLEAN             hpna_isolated;
+
+	WORD                ramse_ctrl_reg; /* For ramses only. Shadow of control register */
+
+	int	V1_Detect_Count ;
+#ifdef H2_TX_WORKAROUND
+	DWORD JediPhy_Tx_Buffer_Len ;		
+	DWORD JediPhy_Tx_Buffer_Left ;
+#endif
+//	}
+    struct {
+        DWORD               capability;
+        DWORD               connect;
+        DWORD               mii_link_state;
+        DWORD               hpna_link_state;
+        DWORD               cum_link_state;     /* PhyCheck() report */
+    }                   media;
+    DWORD               initialized;
+
+    DWORD               hw_options;
+
+#ifdef JEDIPHY	// Bright
+    OSFILEOBJ	osfile ;	
+#endif
+} PHY;
+
+
+/* Device initialization code used by the PHY Driver */
+#define PHY_INIT_CODE           0x29FD7A64L  /* magic number */
+#define IS_PHY_INITIALIZED(p)   ((p)->initialized == PHY_INIT_CODE)
+
+/* PHY ID checks, exclusive of 4-bit vendor revision code */
+#define PHYID_RSS_20417(p)      (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x01825010L)
+#define PHYID_NSC_DP83840(p)    (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x20005C00L)
+#define PHYID_QSI_6612(p)       (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x01814400L)
+#define PHYID_LXT_970(p)        (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x78100000L)
+#define PHYID_LXT_971(p)        (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x001378E0L)
+#define PHYID_GEC_NWK936(p)     (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x02821C20L)
+#define PHYID_TDK_2120(p)       (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x0300E540L)
+#define PHYID_DAVICOM_9101(p)   (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x0181B800L)
+#define PHYID_ICS_1890(p)       (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x0015F420L)
+#define PHYID_ENABLE_5V(p)      (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x00437410L)
+#define PHYID_ENABLE_3V(p)      (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x00437420L)
+
+/* PHY ID revision codes */
+#define PHYID_REV(p)            ((p)->mii_phy[ETH_MII_PHY].mii_id & 0xFL)
+
+/*
+ * PHY operational mode functions
+ *
+ * The three most commonly used PHY Driver functions are PhyInit(),
+ * PhyCheck(), and PhyWakeOnLink().  PhyInit() is called
+ * upon DriverInit() and subsequent DriverReset() routines.  PhyCheck()
+ * may be repetitively called
+ * at DriverInit() or DriverReset() time to determine an intial
+ * link status, and then periodically invoked, e.g., upon a two-second
+ * DriverCheck() interval.  PhyWakeOnLink() simply enables or disables
+ * the MII and/or HomePNA device's wake-up signals.  The caller is
+ * responsible for other set-ups (e.g., OS and 11623 dependent).
+ *
+ *
+ * PhyInit()           - Find, reset, initialize and attach PHY to
+ *                       media, PhyInit() is the first function which
+ *                       must be called before accessing a PHY device.
+ *                       Returns PHY_STATUS_OK upon successful search
+ *                       and initialization of single or combination
+ *                       10/100 MII and 1M8 HomePNA PHY devices.  The
+ *                       Parameter list is as follows:
+ *
+ *                         DWORD  adapter    - MAC device I/O base addr
+ *                         PHY   *phy        - allocated data struct space
+ *                         BYTE   phy_addr   - MII PHY address or wildcard
+ *                         DWORD  connect    - PhyConnectSet() directive
+ *                         DWORD  hw_options - zero or more PHY_HWOPTS_*
+ *                         DWORD *soft_nar   - null, or used with
+ *                                             PHY_HWOPTS_MAC_PORT_MGMT
+ *
+ * PhyReset()          - Issue PHY software reset
+ *
+ * PhyConnectGet()     - Get PHY connection parameters (Auto-Negotiation
+ *                       on/off, 10/100 Mbps speed, Full-Duplex on/off),
+ *                       plus PHY_CONN_TECHNOLOGY specific settings
+ *
+ * PhyConnectSet()     - Set PHY connection parameters
+ *
+ * PhyDisable()        - Disable/isolate MII (or SPI) and/or PMD ports
+ *
+ * PhyEnable()         - Attach (previously isolated) PHY(s) to media
+ *
+ * PhyCapbilityGet()   - Get device-dependent PHY_CONNECT_ABILITY mask
+ *
+ * PhyCheck ()         - Report operational link state (link down/up,
+ *                       1/10/100 Mbps speed, half/full-duplex mode)
+ *                       plus any error indications
+ *
+ * PhyLastLinkUp()     - Report last known link state reported by
+ *                       PhyCheck().  A zero return value indicates link
+ *                       has never been established.  Note that the link
+ *                       state is zeroed (cleared) whenever PhyInit() or
+ *                       PhyConnectSet() is invoked.
+ *
+ * PhyShutdown()       - Disables PHY and places in power-down mode
+ *
+ * PhyConfigurePort()  - Manually switches a multi-port PHY device per
+ *                       PhyCheck() <link_state>.  If the PhyInit() option
+ *                       PHY_HWOPTS_MAC_PORT_MGMT is selected, this
+ *                       function is automatically called by PhyCheck()
+ *                       upon port change, and will additionally manage
+ *                       the RSS 116xx Network Access Register (NAR)
+ *                       port/speed/duplex/heartbeat settings.  Otherwise,
+ *                       the caller must manually manage the NAR and
+ *                       call this function whenever a PHY port change
+ *                       or PHY_LINK_NEW_MEDIA is detected.  Note that a
+ *                       PHY port change can occur even when the link
+ *                       is down!
+ *
+ * PhyWakeOnLink()     - When enabled, enables the HomePNA interrupt
+ *                       (IMASK) based on receive activity and/or
+ *                       sets external, MII-based GPIO for input to
+ *                       receive a device LINK LED transition.
+ */
+#include "phy.h"
+                             
+#endif /* _PHY_H_ */
diff -urN linux-2.4.29/drivers/net/cnxt_emac/phyregs.h linux-2.4.29-uc1/drivers/net/cnxt_emac/phyregs.h
--- linux-2.4.29/drivers/net/cnxt_emac/phyregs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/phyregs.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,574 @@
+/****************************************************************************
+*
+*	Name:			phyregs.h
+
+*  Module Description: PHY device register definitions.
+
+*  Copyright © Conexant Systems 1999-2002.
+*  Copyright © Rockwell Semiconductor Systems 1997-1998.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef _PHYREGS_H_
+#define _PHYREGS_H_
+
+#include "phytypes.h"
+
+/*----------------------------------------------------------------------
+ * (1) Register Map
+ *
+ * 100Base-X PHY and repeater port Media Independent Interface (MII)
+ * register offsets.  The first sixteen registers are defined by
+ * IEEE 802.3u (100Base-X) and 802.3y (100Base-T2); the next sixteen
+ * registers are reserved for vendor-specific extensions.
+ *--------------------------------------------------------------------*/
+
+/* IEEE-defined standard register set */
+#define MII_BMCR        0x00    /* Basic Mode Control Register */
+#define MII_BMSR        0x01    /* Basic Mode Status Reg */
+
+/* IEEE-defined extended register set */
+#define MII_PHYIDR1     0x02    /* PHY Identifier Register #1 */
+#define MII_PHYIDR2     0x03    /* PHY Identifier Register #2 */
+#define MII_ANAR        0x04    /* Auto-Negotiation Advertisement Reg */
+#define MII_ANLPAR      0x05    /* A-N Link Partner Availability Reg */
+#define MII_ANER        0x06    /* Auto-Negotiation Expansion Reg */
+
+/* Generic vendor extension registers (decimal) */
+#define MII_R16         16
+#define MII_R17         17
+#define MII_R18         18
+#define MII_R19         19
+#define MII_R20         20
+#define MII_R21         21
+#define MII_R22         22
+#define MII_R23         23
+#define MII_R24         24
+#define MII_R25         25
+#define MII_R26         26
+#define MII_R27         27
+#define MII_R28         28
+#define MII_R29         29
+#define MII_R30         30
+#define MII_R31         31
+
+/*----------------------------------------------------------------------
+ * (2) IEEE-defined register set
+ *--------------------------------------------------------------------*/
+
+/* Generic bit-value definitions */
+#define MII_BIT0        0x0001
+#define MII_BIT1        0x0002
+#define MII_BIT2        0x0004
+#define MII_BIT3        0x0008
+#define MII_BIT4        0x0010
+#define MII_BIT5        0x0020
+#define MII_BIT6        0x0040
+#define MII_BIT7        0x0080
+#define MII_BIT8        0x0100
+#define MII_BIT9        0x0200
+#define MII_BIT10       0x0400
+#define MII_BIT11       0x0800
+#define MII_BIT12       0x1000
+#define MII_BIT13       0x2000
+#define MII_BIT14       0x4000
+#define MII_BIT15       0x8000
+
+/* Register 0, Basic Mode Control Register (BMCR) */
+#define BMCR_RESET              0x8000
+#define BMCR_LOOPBACK           0x4000
+#define BMCR_SPEED_100          0x2000
+#define BMCR_AUTONEG_ENABLE     0x1000
+#define BMCR_POWERDOWN          0x0800
+#define BMCR_ISOLATE            0x0400
+#define BMCR_RESTART_AUTONEG    0x0200
+#define BMCR_DUPLEX_MODE        0x0100
+#define BMCR_COLLISION_TEST     0x0080
+#define BMCR_RESERVED           0x007F
+#define BMCR_HW_DEFAULT         \
+    (BMCR_SPEED_100 | BMCR_AUTONEG_ENABLE | BMCR_DUPLEX_MODE)
+
+/* Register 1, Basic Mode Status Register (BMSR) */
+#define BMSR_100BASE_T4         0x8000
+#define BMSR_100BASE_TXFD       0x4000
+#define BMSR_100BASE_TX         0x2000
+#define BMSR_10BASE_TFD         0x1000
+#define BMSR_10BASE_T           0x0800
+#define BMSR_100BASE_T2FD       0x0400
+#define BMSR_100BASE_T2         0x0200
+#define BMSR_RESERVED           0x0180
+#define BMSR_PREAMBLE_SUPPRESS  0x0040
+#define BMSR_AUTONEG_COMPLETE   0x0020
+#define BMSR_REMOTE_FAULT       0x0010
+#define BMSR_AUTONEG_ABILITY    0x0008
+#define BMSR_LINK_STATUS        0x0004
+#define BMSR_JABBER_DETECT      0x0002
+#define BMSR_EXTENDED_CAPABLE   0x0001
+#define BMSR_HW_DEFAULT                 \
+    (BMSR_100BASE_TXFD | BMSR_100BASE_TX |      \
+     BMSR_10BASE_TFD   | BMSR_10BASE_T   |      \
+     BMSR_AUTONEG_ABILITY | BMSR_EXTENDED_CAPABLE)
+
+/* Register 2-3, PHY Identifier Register 1-2 (PHYIDR1-2) */
+#define GET_OUI_OF(phyidr1, phyidr2)                            \
+    ((DWORD) ((phyidr1) << 6) | ((phyidr2) >> 10) & 0x003F))
+#define GET_CANONICAL_OUI_OF(phyidr1, phyidr2)                  \
+    ((BitSwap(((phyidr1) >> 10) & 0x003F) << 16) |              \
+     (BitSwap(((phyidr1) >> 2)  & 0x00FF) <<  8) |              \
+     (BitSwap(((phyidr1) << 6)  & 0x00C0) | (phyidr2 >> 10) & 0x003F)) 
+
+/*
+ * Register 4, Auto-Negotiation Advertisement Register (ANAR).
+ *
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * Warning!  Need to verify that the newer 802.3x and 802.3y bits
+ * match the HW register definitions, as the PHY hardware design
+ * may predate the IEEE specifications.
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+#define ANAR_NEXT_PAGE                  0x8000
+#define ANAR_ACKNOWLEDGE                0x4000
+#define ANAR_REMOTE_FAULT               0x2000
+#define ANAR_100BASE_T2FD               0x1000  /* per 802.3y -T2 */
+#define ANAR_100BASE_T2                 0x0800  /* per 802.3y -T2 */
+#define ANAR_FDX_PAUSE                  0x0400  /* per 802.3x FDX */
+#define ANAR_100BASE_T4                 0x0200
+#define ANAR_100BASE_TXFD               0x0100
+#define ANAR_100BASE_TX                 0x0080
+#define ANAR_10BASE_TFD                 0x0040
+#define ANAR_10BASE_T                   0x0020
+#define ANAR_PROTOCOL_SELECTOR          0x001F
+#define IS_ANAR_PROTOCOL_IEEE_802_3(anar)       \
+    ((anar) & ANAR_PROTOCOL_SELECTOR) == 0x0001
+
+/*
+ * Register 5, Auto-Negotiation Link Partner Ability Register (ANLPAR),
+ * which is the same format as the ANAR (Register 4)
+ */
+#define ANLPAR_NEXT_PAGE                ANAR_NEXT_PAGE
+#define ANLPAR_ACKNOWLEDGE              ANAR_ACKNOWLEDGE
+#define ANLPAR_REMOTE_FAULT             ANAR_REMOTE_FAULT
+#define ANLPAR_100BASE_T2FD             ANAR_100BASE_T2FD
+#define ANLPAR_100BASE_T2               ANAR_100BASE_T2
+#define ANLPAR_FDX_PAUSE                ANAR_FDX_PAUSE
+#define ANLPAR_100BASE_T4               ANAR_100BASE_T4
+#define ANLPAR_100BASE_TXFD             ANAR_100BASE_TXFD
+#define ANLPAR_100BASE_TX               ANAR_100BASE_TX
+#define ANLPAR_10BASE_TFD               ANAR_10BASE_TFD
+#define ANLPAR_10BASE_T                 ANAR_10BASE_T
+#define ANLPAR_PROTOCOL_SELECTOR        ANAR_PROTOCOL_SELECTOR
+#define IS_ANLPAR_PROTOCOL_IEEE_802_3   IS_ANPAR_PROTOCOL_IEEE_802_3
+
+/* Register 6, Auto-Negotiation Expansion Register (ANER) */
+#define ANER_RESERVED                           0xFFE0
+#define ANER_PARALLEL_DETECTION_FAULT           0x0010
+#define ANER_LINK_PARTNER_NEXT_PAGE_ABLE        0x0008
+#define ANER_NEXT_PAGE_ABLE                     0x0004
+#define ANER_PAGE_RECEIVED                      0x0002
+#define ANER_LINK_PARNTER_AUTONEG_ABLE          0x0001
+
+/*----------------------------------------------------------------------
+ * (3a) RSS 20417 100Base-T2 extended register set
+ *--------------------------------------------------------------------*/
+
+/* RSS vendor extension registers */
+#define MII_RSS_TBD     MII_R16
+
+/* Register TBD, TBD */
+#define RSS_RXX_BIT0    MII_BIT0
+
+/*----------------------------------------------------------------------
+ * (3b) NSC DP83840 10/100Base-TX extended register set
+ *--------------------------------------------------------------------*/
+
+/* NSC vendor extension registers */
+#define MII_DCR         0x12    /* Disconnect Counter Reg */
+#define MII_FCSCR       0x13    /* False Carrier Sense Counter Reg */
+#define MII_RECR        0x15    /* Receive Error Counter Reg */
+#define MII_SRR         0x16    /* Silicon Revision Reg */
+#define MII_PCR         0x17    /* PCS Sub-Layer Configuration Reg */
+#define MII_LBREMR      0x18    /* Loopback, Bypass & Rcvr Error Mask */
+#define MII_PAR         0x19    /* PHY Address Reg */
+#define MII_10BTSR      0x1B    /* 10Base-T Status Reg */
+#define MII_10BTCR      0x1C    /* 10Base-T Configuration Reg */
+
+/* Register 23, PCS sublayer Configuration Register (PCR) */
+#define PCR_NRZI_ENABLE         0x8000
+#define PCR_RESERVED            0x4F0B
+#define PCR_TO_DIS              0x2000
+#define PCR_REPEATER_MODE       0x1000
+#define PCR_CLK25DIS            0x0080
+#define PCR_FORCE_LINK_100      0x0040
+#define PCR_FORCE_CONNECT       0x0020
+#define PCR_TX_OFF              0x0010
+#define PCR_LED_COLLISION       0x0004
+
+/* Register 24, Loopback, Bypass & Rx Error Mask Register (LBREMR) */
+#define LBREMR_RESERVED         0x84E1
+#define LBREMR_BP_4B5B          0x4000
+#define LBREMR_BP_SCR           0x2000
+#define LBREMR_BP_ALIGN         0x1000
+#define LBREMR_LB_MASK          0x0B00
+#define LBREMR_LB_OFF           0x0000
+#define LBREMR_LB_10BT          0x0800
+#define LBREMR_LB_XCVR          0x0100
+#define LBREMR_LB_REMOTE        0x0200
+#define LBREMR_LB_UNDEFINED     0x0300
+#define LBREMR_ALT_CRS          0x0040  /* 83840 RevA device feature */
+#define LBREMR_XMT_DS           0x0020  /* 83840 RevA device feature */
+#define LBREMR_CODE_ERR         0x0010
+#define LBREMR_PE_ERR           0x0008
+#define LBREMR_LINK_ERR         0x0004
+#define LBREMR_PKT_ERR          0x0002
+
+/* Register 25, PHY Address Register (PAR) */
+#define PAR_RESERVED            0xFF80
+#define PAR_SPEED_10            0x0040
+#define PAR_CONNECT_STATUS      0x0020
+#define PAR_ADDR_MASK           0x001F
+
+/*----------------------------------------------------------------------
+ * (3c) QSI 6612 10/100Base-TX extended register set
+ *--------------------------------------------------------------------*/
+
+/* Register 17, Mode Control */
+#define QSI_R17_RESERVED_0_1   (MII_BIT0 | MII_BIT1)
+#define QSI_R17_TEST            MII_BIT2
+#define QSI_R17_PHY_ADDR       (MII_BIT3 | MII_BIT4 |           \
+                                MII_BIT5 | MII_BIT6 | MII_BIT7)
+#define QSI_R17_AN_TEST_MODE    MII_BIT8
+#define QSI_R17_RESERVED_9_10  (MII_BIT9 | MII_BIT10)
+#define QSI_R17_BTEXT           MII_BIT11
+#define QSI_R17_T4_PRESENT      MII_BIT12
+#define QSI_R17_RESERVED_13_15 (MII_BIT13 | MII_BIT14 | MII_BIT15)
+
+/* Register 29, Interrupt Source */
+#define QSI_R29_RXERR_CTR_FULL  MII_BIT0
+#define QSI_R29_AN_PAGE_RCVD    MII_BIT1
+#define QSI_R29_PARALLEL_FAULT  MII_BIT2
+#define QSI_R29_AN_LP_ACK       MII_BIT3
+#define QSI_R29_LINK_DOWN       MII_BIT4
+#define QSI_R29_REMOTE_FAULT    MII_BIT5
+#define QSI_R29_AN_COMPLETE     MII_BIT6
+#define QSI_R29_RESERVED_7_15   0xFF80
+
+/* Register 30, Interrupt Mask */
+#define QSI_R30_ENABLE_RXERR_CTR_FULL   QSI_R29_RXERR_CTR_FULL
+#define QSI_R30_ENABLE_AN_PAGE_RCVD     QSI_R29_AN_PAGE_RCVD
+#define QSI_R30_ENABLE_PARALLEL_FAULT   QSI_R29_PARALLEL_FAULT
+#define QSI_R30_ENABLE_AN_LP_ACK        QSI_R29_AN_LP_ACK
+#define QSI_R30_ENABLE_LINK_DOWN        QSI_R29_LINK_DOWN
+#define QSI_R30_ENABLE_REMOTE_FAULT     QSI_R29_REMOTE_FAULT
+#define QSI_R30_ENABLE_AN_COMPLETE      QSI_R29_AN_COMPLETE
+#define QSI_R30_RESERVED_7_14           0x7F80
+#define QSI_R30_INTERRUPT_MODE          MII_BIT15
+
+/* Register 31, BASE-TX PHY Control */
+#define QSI_R31_SCR_DISABLE     MII_BIT0
+#define QSI_R31_MLT3_DISABLE    MII_BIT1
+#define QSI_R31_OPMODE         (MII_BIT2 | MII_BIT3 | MII_BIT4)
+#define QSI_R31_TX_ISOLATE      MII_BIT5
+#define QSI_R31_4B5BEN          MII_BIT6
+#define QSI_R31_RESERVED_7      MII_BIT7
+#define QSI_R31_DCREN           MII_BIT8
+#define QSI_R31_RLBEN           MII_BIT9
+#define QSI_R31_RESERVED_10_11 (MII_BIT10 | MII_BIT11)
+#define QSI_R31_AN_COMPLETE     MII_BIT12
+#define QSI_R31_DISABLE_RXERRCT MII_BIT13
+#define QSI_R31_RESERVED_14_15 (MII_BIT14 | MII_BIT15)
+
+/*----------------------------------------------------------------------
+ * (3d) Level One LXT970 10/100Base-TX extended register set
+ *--------------------------------------------------------------------*/
+
+/* Register 17, Interrupt Enable Register */
+#define LXT_R17_TINT            MII_BIT0
+#define LXT_R17_INTEN           MII_BIT1
+
+/* Register 18, Interrupt Status Register */
+#define LXT_R18_XTALOK          MII_BIT14
+#define LXT_R18_MINT            MII_BIT15
+
+/* Register 19, Configuration Register */
+#define LXT_R19_TX_DISCONNECT   MII_BIT0
+#define LXT_R19_RESERVED_1      MII_BIT1
+#define LXT_R19_100BASE_FX      MII_BIT2
+#define LXT_R19_SCR_BYPASS      MII_BIT3
+#define LXT_R19_4B5B_BYPASS     MII_BIT4
+#define LXT_R19_ADVANCE_TXCLK   MII_BIT5
+#define LXT_R19_LEDC_BITS      (MII_BIT6 | MII_BIT7)
+#define LXT_R19_LEDC_COLLISION  0
+#define LXT_R19_LEDC_OFF        MII_BIT6
+#define LXT_R19_LEDC_ACTIVITY   MII_BIT7
+#define LXT_R19_LEDC_ON        (MII_BIT6 | MII_BIT7)
+#define LXT_R19_LINK_TEST       MII_BIT8
+#define LXT_R19_JABBER_DISABLE  MII_BIT9
+#define LXT_R19_SQE             MII_BIT10
+#define LXT_R19_TP_LPBK_DISABLE MII_BIT11
+#define LXT_R19_MDIO_INT        MII_BIT12
+#define LXT_R19_REPEATER_MODE   MII_BIT13
+#define LXT_R19_TXTEST_100      MII_BIT14
+#define LXT_R19_RESERVED_15     MII_BIT15
+
+/* Register 20, Chip Status Register */
+#define LXT_R20_PLL_LOCK        MII_BIT0
+#define LXT_R20_RESERVED_1      MII_BIT1
+#define LXT_R20_LOW_VOLTAGE     MII_BIT2
+#define LXT_R20_RESERVED_3      MII_BIT3
+#define LXT_R20_MLT3_ERROR      MII_BIT4
+#define LXT_R20_SYMBOL_ERROR    MII_BIT5
+#define LXT_R20_SCR_LOCK        MII_BIT6
+#define LXT_R20_RESERVED_7      MII_BIT7
+#define LXT_R20_PAGE_RECEIVED   MII_BIT8
+#define LXT_R20_AN_COMPLETE     MII_BIT9
+#define LXT_R20_RESERVED_10     MII_BIT10
+#define LXT_R20_SPEED_100       MII_BIT11
+#define LXT_R20_DUPLEX          MII_BIT12
+#define LXT_R20_LINK_UP         MII_BIT13
+#define LXT_R20_RESERVED_14_15 (MII_BIT14 | MII_BIT15)
+
+/*----------------------------------------------------------------------
+ * (3e) GEC Plessey NWK936 10/100Base-TX extended register set
+ *--------------------------------------------------------------------*/
+
+/* "GPS (GEC) Defined" Register 24 */
+#define GEC_R24_ERROR_CODE_0101 MII_BIT0        /* 0 = 0110, 1 = 0101 */
+#define GEC_R24_BPSCR           MII_BIT1
+#define GEC_R24_BPENC           MII_BIT2
+#define GEC_R24_BPALIGN         MII_BIT3
+#define GEC_R24_MF              MII_BIT4
+#define GEC_R24_TEST_MODES     (MII_BIT5 | MII_BIT6)
+#define GEC_R24_LEDCTL          MII_BIT7
+#define GEC_R24_LB10CTL         MII_BIT8
+#define GEC_R24_FRC_TX          MII_BIT9
+#define GEC_R24_FRC_RX          MII_BIT10
+#define GEC_R24_CRS_CTL_FDX_RX  MII_BIT11
+#define GEC_R24_JAB_DIS         MII_BIT12
+#define GEC_R24_SQE_DIS         MII_BIT13
+#define GEC_R24_UNDEF_14_15    (MII_BIT14 | MII_BIT15)
+
+/* "GPS (GEC) Defined" Register 25 */
+#define GEC_R25_AN_STATE       (MII_BIT0 | MII_BIT1 |   \
+                                MII_BIT2 | MII_BIT3)
+#define GEC_R25_AN_ABIL_MATCH   MII_BIT4
+#define GEC_R25_SPEED_100       MII_BIT5
+#define GEC_R25_DUPLEX          MII_BIT6
+#define GEC_R25_AN_COMPLETE     MII_BIT7
+#define GEC_R25_PHY_ADDR       (MII_BIT8  | MII_BIT9  | \
+                                MII_BIT10 | MII_BIT11 | MII_BIT12)
+#define GEC_R25_UNDEF_13_15    (MII_BIT13 | MII_BIT14 | MII_BIT15)
+
+/*----------------------------------------------------------------------
+ * (3f) TDK 78Q2120 10/100Base-TX extended register set
+ *--------------------------------------------------------------------*/
+
+/* Register 16, Vendor Specific Register */
+#define TDK_R16_RXCC            MII_BIT0
+#define TDK_R16_PCSBP           MII_BIT1
+#define TDK_R16_RSVD_2_3       (MII_BIT2 | MII_BIT3)
+#define TDK_R16_RVSPOL          MII_BIT4
+#define TDK_R16_APOL_DISABLE    MII_BIT5
+#define TDK_R16_GPIO0_INPUT     MII_BIT6
+#define TDK_R16_GPIO0_DAT       MII_BIT7
+#define TDK_R16_GPIO1_INPUT     MII_BIT8
+#define TDK_R16_GPIO1_DAT       MII_BIT9
+#define TDK_R16_10BT_NAT_LPBK   MII_BIT10
+#define TDK_R16_SQETEST_INHIBIT MII_BIT11
+#define TDK_R16_RSVD_12_13     (MII_BIT12 | MII_BIT13)
+#define TDK_R16_INTR_HIGH       MII_BIT14
+#define TDK_R16_RPTR            MII_BIT15
+
+/* Register 17, Interrupt Control/Status Register */
+#define TDK_R17_ANEG_COMP_INT   MII_BIT0
+#define TDK_R17_RFAULT_INT      MII_BIT1
+#define TDK_R17_LS_CHG_INT      MII_BIT2
+#define TDK_R17_LP_ACK_INT      MII_BIT3
+#define TDK_R17_PDF_INT         MII_BIT4
+#define TDK_R17_PRX_INT         MII_BIT5
+#define TDK_R17_RXER_INT        MII_BIT6
+#define TDK_R17_JABBER_INT      MII_BIT7
+#define TDK_R17_ANEG_COMP_IE    MII_BIT8
+#define TDK_R17_RFAULT_IE       MII_BIT9
+#define TDK_R17_LS_CHG_IE       MII_BIT10
+#define TDK_R17_LP_ACK_IE       MII_BIT11
+#define TDK_R17_PDF_IE          MII_BIT12
+#define TDK_R17_PRX_IE          MII_BIT13
+#define TDK_R17_RXER_IE         MII_BIT14
+#define TDK_R17_JABBER_IE       MII_BIT15
+
+/* Register 18, Diagnostic Register */
+#define TDK_R18_RSVD_0_7        0x00FF
+#define TDK_R18_RX_LOCK         MII_BIT8
+#define TDK_R18_RX_PASS         MII_BIT9
+#define TDK_R18_RATE_100        MII_BIT10
+#define TDK_R18_DPLX            MII_BIT11
+#define TDK_R18_ANEG_FAIL       MII_BIT12
+#define TDK_R18_RSVD_13_15     (MII_BIT13 | MII_BIT14 | MII_BIT15)
+
+/*----------------------------------------------------------------------
+ * (3g) Davicom 9101 10/100Base-TX extended register set
+ *--------------------------------------------------------------------*/
+
+/* No data sheet as of 04Feb98 ... */
+#define DAV_RXX_BIT0            MII_BIT0
+
+/*----------------------------------------------------------------------
+ * (3h) ICS 1890 10/100Base-TX extended register set per "ICS1890
+ *      10Base-T/100Base-TX Integrated PHYceiver(tm)" data sheet,
+ *      ICS890RevG, dated 21Oct97.
+ *--------------------------------------------------------------------*/
+
+/* Register 16, Extended Control Register */
+#define ICS_R16_CIPHER_DISABLE  MII_BIT0
+#define ICS_R16_RESERVED_1      MII_BIT1
+#define ICS_R16_INVLD_ERR_TEST  MII_BIT2
+#define ICS_R16_NRZI_ENCODING   MII_BIT3
+#define ICS_R16_RESERVED_4      MII_BIT4
+#define ICS_R16_CIPHER_TEST     MII_BIT5
+#define ICS_R16_PHY_ADDR       (MII_BIT6  | MII_BIT7  |         \
+                                MII_BIT8  | MII_BIT9  | MII_BIT10)
+#define ICS_R16_RESERVED_11_14 (MII_BIT11 | MII_BIT12 |         \
+                                MII_BIT13 | MII_BIT14)
+#define ICS_R16_CMDREG_OVERRIDE MII_BIT15
+
+/* Register 17, QuickPoll Detailed Status Register */
+#define ICS_R17_LINK_VALID      MII_BIT0
+#define ICS_R17_REMOTE_FAULT    MII_BIT1
+#define ICS_R17_JABBER_DETECT   MII_BIT2
+#define ICS_R17_SD_100BASE_TX   MII_BIT3
+#define ICS_R17_AN_COMPLETE     MII_BIT4
+#define ICS_R17_PREMATURE_END   MII_BIT5
+#define ICS_R17_HALT_SYMBOL     MII_BIT6
+#define ICS_R17_INVALID_SYMBOL  MII_BIT7
+#define ICS_R17_FALSE_CARRIER   MII_BIT8
+#define ICS_R17_PLL_LOCK_ERROR  MII_BIT9
+#define ICS_R17_RX_SIGNAL_ERROR MII_BIT10
+#define ICS_R17_AN_PROGRESS    (MII_BIT11 | MII_BIT12 | MII_BIT13)
+#define ICS_R17_DUPLEX          MII_BIT14
+#define ICS_R17_DATA_RATE_100   MII_BIT15
+
+/*----------------------------------------------------------------------
+ * (3i) <Your 10/100 MII PHY Device here>
+ *--------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------
+ * (4) HomePNA 1M8 SPI register definitions.  Registers are 8-bits
+ *     except where noted.
+ *--------------------------------------------------------------------*/
+
+/* (4a) HomePNA SPI register map */
+#define HPNA_CONTROL            0x00    /* 16-bit */
+#define HPNA_STATUS             0x02    /* 16-bit */
+#define HPNA_IMASK              0x04    /* 16-bit */
+#define HPNA_ISTAT              0x06    /* 16-bit */
+#define HPNA_TX_PCOM            0x08    /* 32-bit */
+#define HPNA_RX_PCOM            0x0C    /* 32-bit */
+#define HPNA_NOISE              0x10
+#define HPNA_PEAK               0x11
+#define HPNA_NSE_FLOOR          0x12
+#define HPNA_NSE_CEILING        0x13
+#define HPNA_NSE_ATTACK         0x14
+#define HPNA_NSE_EVENTS         0x15
+#define HPNA_AFE_CONTROL        0x16    /* 16-bit CN7221 Ramses dev */
+#define HPNA_SPARE_2            0x17
+#define HPNA_SLC_PEAK_MID       0x18	/* For Ramses only */
+#define HPNA_AID_ADDRESS        0x19
+#define HPNA_AID_INTERVAL       0x1A
+#define HPNA_AID_ISBI           0x1B
+#define HPNA_ISBI_SLOW          0x1C
+#define HPNA_ISBI_FAST          0x1D
+#define HPNA_TX_PULSE_WIDTH     0x1E
+#define HPNA_TX_PULSE_CYCLES    0x1F
+
+/* HomePNA SPI register 0x00, 16-bit HPNA_CONTROL */
+#define HPNA_CONTROL_RESERVED           0x7009
+#define HPNA_CONTROL_HIGH_POWER         0x0002
+#define HPNA_CONTROL_HIGH_SPEED         0x0004
+#define HPNA_CONTROL_POWERDOWN          0x0010
+#define HPNA_CONTROL_STOP_SLICE_ADAPT   0x0020
+#define HPNA_CONTROL_CLEAR_NSE_EVENTS   0x0040
+#define HPNA_CONTROL_STOP_AID_AUTO_ADDR 0x0080
+#define HPNA_CONTROL_CMD_HIGH_SPEED     0x0100
+#define HPNA_CONTROL_CMD_LOW_SPEED      0x0200
+#define HPNA_CONTROL_CMD_HIGH_POWER     0x0400
+#define HPNA_CONTROL_CMD_LOW_POWER      0x0800
+#define HPNA_CONTROL_IGNORE_REMOTE_CMD  0x8000
+
+/* HomePNA SPI register 0x02, 16-bit HPNA_STATUS */
+#define HPNA_STATUS_RESERVED            0x0F8F
+#define HPNA_STATUS_RX_VERSION          0x0010
+#define HPNA_STATUS_RX_SPEED            0x0020
+#define HPNA_STATUS_RX_POWER            0x0040
+#define HPNA_STATUS_INVERT_RXCLK        0x1000
+#define HPNA_STATUS_INVERT_TXCLK        0x2000
+#define HPNA_STATUS_INVERT_CLSN         0x4000
+#define HPNA_STATUS_INVERT_RXCRS        0x8000
+
+/* HomePNA SPI register 0x04, 16-bit HPNA_IMASK */
+#define HPNA_IMASK_RESERVED             0x00F0
+#define HPNA_IMASK_REMOTE_CMD_SENT      0x0001
+#define HPNA_IMASK_REMOTE_CMD_RCVD      0x0002
+#define HPNA_IMASK_PACKET_TRANSMITTED   0x0004
+#define HPNA_IMASK_PACKET_RECEIVED      0x0008
+#define HPNA_IMASK_TXPCOM_READY         0x0100
+#define HPNA_IMASK_RXPCOM_VALID         0x0200
+#define HPNA_IMASK_SW_INTERRUPTS        0xFC00
+
+/* HomePNA SPI register 0x06, 16-bit HPNA_ISTAT */
+#define HPNA_ISTAT_RESERVED             HPNA_IMASK_RESERVED
+#define HPNA_ISTAT_REMOTE_CMD_SENT      HPNA_IMASK_REMOTE_CMD_SENT
+#define HPNA_ISTAT_REMOTE_CMD_RCVD      HPNA_IMASK_REMOTE_CMD_RCVD
+#define HPNA_ISTAT_PACKET_TRANSMITTED   HPNA_IMASK_PACKET_TRANSMITTED
+#define HPNA_ISTAT_PACKET_RECEIVED      HPNA_IMASK_PACKET_RECEIVED
+#define HPNA_ISTAT_TXPCOM_READY         HPNA_IMASK_TXPCOM_READY
+#define HPNA_ISTAT_RXPCOM_VALID         HPNA_IMASK_RXPCOM_VALID         
+#define HPNA_ISTAT_SW_INTERRUPTS        HPNA_IMASK_SW_INTERRUPTS
+
+/* HomePNA SPI NSE_FLOOR register   0x12 @ 13 mV granularity */
+#define HPNA_NSE_FLOOR_HWDEFAULT        0x04
+#define HPNA_NSE_FLOOR_SWOVERRIDE       0x07
+
+/* HomePNA SPI NSE_CEILING register 0x13 @ 13 mV granularity */
+#define HPNA_NSE_CEILING_HWDEFAULT      0xD0    /* 7-bit 0x50? */
+#define HPNA_NSE_CEILING_SWOVERRIDE     0x7F
+
+/* HomePNA SPI NSE_ATTACK  register 0x14 @ 13 mV granularity */
+#define HPNA_NSE_ATTACK_HWDEFAULT       0xF4
+#define HPNA_NSE_ATTACK_SWOVERRIDE      0xF4
+
+/* 11625 Ramses (CN7221) 16-bit AFE_CONTROL test register 0x16 */
+#define HPNA_AFE_CONTROL_PD_TX          0x0001  /* powerdown Tx */
+#define HPNA_AFE_CONTROL_HPCTR          0x0002  /* Shadows reg 0.1 */
+#define HPNA_AFE_CONTROL_PD_RXIFAMP     0x0004  /* powerdown Rx amp */
+#define HPNA_AFE_CONTROL_RXGAIN         0x0008  /* 1=50, 0=30 */
+#define HPNA_AFE_CONTROL_PD_VC          0x0010  /* mid-rail current */
+#define HPNA_AFE_CONTROL_PD_RECTI       0x0020  /* Rx rectifier block */
+#define HPNA_AFE_CONTROL_PD_ENV         0x0040  /* Rx envelope amp */
+#define HPNA_AFE_CONTROL_TRI_REF        0x0080  /* tristate slice ref */
+#define HPNA_AFE_CONTROL_PD_COMP        0x0100  /* Rx slice comparatr */
+#define HPNA_AFE_CONTROL_PEAK_DELAY     0x0E00  /* Noise-to-Peak wait */
+#define HPNA_AFE_CONTROL_NOISE_SLICE    0x3000  /* Noise slice increase */
+#define HPNA_AFE_CONTROL_RESERVED       0xC000
+
+
+#endif /* _PHYREGS_H_ */
diff -urN linux-2.4.29/drivers/net/cnxt_emac/phytypes.h linux-2.4.29-uc1/drivers/net/cnxt_emac/phytypes.h
--- linux-2.4.29/drivers/net/cnxt_emac/phytypes.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/phytypes.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,173 @@
+/****************************************************************************
+*
+*	Name:			phytypes.h
+*
+*	Description:	PHY driver OS/compiler mapping of simple
+*					BYTE/WORD/DWORD types.
+*
+*	Copyright:		(c) 1997-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:22  $
+****************************************************************************/
+
+#ifndef _PHYTYPES_H_
+#define _PHYTYPES_H_
+
+/*----------------------------------------------------------------------
+ * OS and compiler-specific types here, based on DRV_OS complier switch
+ *--------------------------------------------------------------------*/
+#define NDIS            1
+#define NOVELL_CHSM     2
+#define DRV_OS_UNUSED   3       /* was "SCO" ... see SCO_*, below */
+#define SOLARIS         4
+#define LINUX           5
+#define PKTDRV          6
+#define DOS             7
+#define WIN32_DIAG      8       /* RSS' Win95/NT diagnostic tool */
+#define SCO_MDI         9
+#define SCO_LLI        10
+#define SCO_DLPI       11
+#define SCO_GEMINI     12
+#define VXWORKS        13		/* VxWorks Tornado RTOS */
+#define NO_OS          14		/* No OS Services */
+
+#define DRV_OS	LINUX
+
+#ifndef DRV_OS
+#define DRV_OS  DOS     /* THE lowest common denominator :-/ */
+#endif
+
+#if (DRV_OS == NDIS)
+#include <ndis.h>
+#if !defined(_TYPDEF_H_)
+typedef ULONG DWORD;
+typedef USHORT WORD;
+typedef UCHAR BYTE;
+#endif
+
+#elif (DRV_OS == NOVELL_CHSM)
+#include <odi.h>
+#include <odi_nbi.h>
+#include <cmsm.h>
+
+#ifndef BYTE
+typedef UINT8           BYTE;
+#endif
+
+#ifndef WORD
+typedef UINT16          WORD;
+#endif
+
+#ifndef DWORD
+/* Warning:  <odi.h> UINT32 == unsigned int, not unsigned long */
+typedef unsigned long   DWORD;
+#endif
+
+#elif (DRV_OS == SCO_MDI)
+typedef int             BOOLEAN;
+typedef unsigned char   BYTE;
+typedef unsigned short  WORD;
+typedef unsigned long   DWORD;
+
+#elif (DRV_OS == SCO_LLI)
+typedef int             BOOLEAN;
+typedef unsigned char   BYTE;
+typedef unsigned short  WORD;
+typedef unsigned long   DWORD;
+
+#elif (DRV_OS == SCO_DLPI)
+typedef int             BOOLEAN;
+typedef unsigned char   BYTE;
+typedef unsigned short  WORD;
+typedef unsigned long   DWORD;
+
+#elif (DRV_OS == SCO_GEMINI)
+typedef int             BOOLEAN;
+typedef unsigned char   BYTE;
+typedef unsigned short  WORD;
+typedef unsigned long   DWORD;
+
+#elif (DRV_OS == SOLARIS)
+#include <sys/types.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+typedef int             BOOLEAN;
+typedef unsigned char   BYTE;
+typedef unsigned short  WORD;
+typedef unsigned long   DWORD;
+
+#elif (DRV_OS == LINUX)
+#include <linux/delay.h>
+/* #include <asm/delay.h> */
+#include <asm/io.h>
+#include <asm/arch/bsptypes.h>
+
+#if !defined(_TYPDEF_H_) 
+	#if 0
+		typedef int             BOOLEAN;
+		typedef unsigned char   BYTE;
+		typedef unsigned short  WORD;
+		typedef unsigned long   DWORD;
+	#endif
+#endif
+
+#elif (DRV_OS == VXWORKS)	/* VxWorks Tornado RTOS */
+#if !defined(_TYPDEF_H_) && !defined(BSPTYPES_H)
+typedef int             BOOLEAN;
+typedef unsigned char   BYTE;
+typedef unsigned short  WORD;
+typedef unsigned long   DWORD;
+#endif
+
+#elif (DRV_OS == PKTDRV)
+#include <pktdrv???.h>
+
+#elif (DRV_OS == WIN32_DIAG)
+#include <windows.h>
+#include "RockDLL.h"    /* NIC diagnostics DLL */
+
+#else                   /* DOS -- Roll our own basic types */
+#if !defined(_TYPDEF_H_)
+	#if 0
+		typedef int             BOOLEAN;
+		typedef unsigned char   BYTE;
+		typedef unsigned short  WORD;
+		typedef unsigned long   DWORD;
+	#endif
+#endif
+
+#endif
+/*--------------------------------------------------------------------*/
+
+/* Be sure the essentials are in place */
+#ifndef TRUE
+#define TRUE            1
+#endif
+#ifndef FALSE
+#define FALSE           0
+#endif
+#ifndef NULL
+#define NULL            ((void *) 0)
+#endif
+
+#endif /* _PHYTYPES_H_ */
diff -urN linux-2.4.29/drivers/net/cnxt_emac/tesla.c linux-2.4.29-uc1/drivers/net/cnxt_emac/tesla.c
--- linux-2.4.29/drivers/net/cnxt_emac/tesla.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/tesla.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,1100 @@
+/****************************************************************************
+*
+*	Name:			tesla.c
+*
+*	Description:	HomePlug support for Emac driver for CX821xx products
+*
+*	Copyright:		(c) 2001,2002 Conexant Systems Inc.
+*					Personal Computing Division
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+*****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:22  $
+****************************************************************************/
+
+#define TESLA_MODULE
+
+#if defined(VXWORKS_DRIVER) 
+#include "protoutils.h"
+#include "JxRegSrv.h"
+#endif
+
+#include "osutil.h"
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include "cnxtEmac.h"
+#include <asm/arch/gpio.h>
+#include <asm/arch/cnxtflash.h>
+
+#include "tesla.h"
+
+#define TESLA_DEBUG	1
+
+// Tesla setupframe
+/****************************************************************************
+* int5130SendConfigPacket
+*
+* Get a transmit buffer, fill it in with configuration data and
+* send it to the card
+*
+****************************************************************************/
+#define SIZE_ETHER_ADDRESS       6              // Ethernet/IEEE addresses always 6 bytes long
+#define MIN_ETHER_PACKET_SIZE    60             // Minimum size Ethernet packet we can send (including header)
+#define MAX_ETHER_PACKET_SIZE    1514           // Maximum size Ethernet packet we can send (including header)
+#define INT5130_ENCRYPTION_KEY_LENGTH 8
+
+// Intellon Ethertype
+#define INT5130_FRAME_TYPE_OCTET_1 (0x88)
+#define INT5130_FRAME_TYPE_OCTET_2 (0x7B)
+
+#define INT5130_INIT_FRAME_ENTRY_COUNT (0x05) //Note - change to 4 if not using LCON
+#define INT5130_SET_LOCAL_PARAMETERS                     (0x19)
+#define INT5130_SET_NETWORK_ENCRYPTION_KEY (0x04)
+#define INT5130_REQUEST_PARAMETERS_AND_STATISTICS 	(0x07)
+#define INT5130_SET_TRANSMIT_CHARACTERISTICS (0x1F)
+#define INT5130_LOCAL_PARAMETER_LENGTH                   (6)
+#define INT5130_SET_TRANSMIT_CHARACTERISTICS_LENGTH (3)
+
+/* Here are the bit masks for the first transmit characteristics octet. */
+#define INT5130_LCO_MASK (0x80)
+#define INT5130_LCO_ON (0x80)
+
+#define INT5130_ENCF_MASK (0x40)
+#define INT5130_ENCF_ON (0x40)
+
+#define INT5130_TXPRIO_MASK (0x30)
+#define INT5130_CAP0 (0x00)
+#define INT5130_CAP1 (0x10)
+#define INT5130_CAP2 (0x20)
+#define INT5130_CAP3 (0x30)
+
+#define INT5130_RESPEXP_MASK           (0x08)
+#define INT5130_RESPEXP_ON             (0x08)
+
+#define INT5130_TX_CONT_FREE_MASK      (0x04)
+#define INT5130_TX_CONT_FREE_ON        (0x04)
+
+#define INT5130_CONT_FREE_TOKEN_MASK   (0x02)
+#define INT5130_CONT_FREE_TOKEN_ON		(0x02)
+
+#define INT5130_TX_WITH_TOKEN_MASK     (0x01)
+#define INT5130_TX_WITH_TOKEN_ON       (0x01)
+
+/* Here are the bit masks for the second transmit characteristics octet. */
+#define INT5130_RETRY_CTL_MASK (0xC0)
+#define INT5130_RETRY_CTL_NONE (0x00)
+
+#define INT5130_RETRY_CTL_ONE (0x40)
+#define INT5130_RETRY_CTL_ALL (0x80)
+
+#define INT5130_BUFFER_PUT(nValue) *pSendBuf++ = nValue; nSendSize +=1;
+
+#define INT5130_BUFFER_PUT_ADDR(pAddr) MOVE_MEMORY(pSendBuf, pAddr, SIZE_ETHER_ADDRESS); \
+	pSendBuf += SIZE_ETHER_ADDRESS; nSendSize += SIZE_ETHER_ADDRESS;
+
+#define INT5130_BUFFER_PUT_KEY(pKey) MOVE_MEMORY( pSendBuf, pKey, INT5130_ENCRYPTION_KEY_LENGTH); \
+	pSendBuf += INT5130_ENCRYPTION_KEY_LENGTH; nSendSize += INT5130_ENCRYPTION_KEY_LENGTH;
+
+// This is Tesla Control struct with default values, do not modify it
+TeslaControl_Str Default_TeslaControl =
+{
+	TRUE ,
+	{0x4C,0x76,0x4A,0xF8,0xE0,0x12,0xD6,0x47},
+	CA1 ,
+	TRUE ,
+	TX_NORMAL_RETRY ,
+	{"HomePlug"} ,
+	FALSE ,
+	{0,0,0,0,0,0,0,0},
+	1 ,
+	AFE_ADI ,
+	ALG_NONE ,
+	120 ,
+	{0x00,0x05,0x04,0x0c,0x06,0x80,0x12,0x69,0x13,0x69,0x14,0x69,0x00,0x00,0x00,0x00},
+	19
+} ;
+
+#if 0
+TeslaControl_Str Current_TeslaControl =
+{
+	FALSE ,
+	{0x01,0xf2,0xe3,0xd4,0xc5,0xb6,0xa7,0x98},
+	CA1 ,
+	TRUE ,
+	TX_NORMAL_RETRY ,
+	FALSE ,
+	{0,0,0,0,0,0,0,0},
+	1 ,
+	AFE_ADI ,
+	ALG_NONE ,
+	120 ,
+	{0x00,0x05,0x04,0x0c,0x06,0x80,0x12,0x69,0x13,0x69,0x14,0x69,0x00,0x00,0x00,0x00},
+	19
+} ;
+#else
+TeslaControl_Str Current_TeslaControl = {0};
+#endif
+
+
+#define MAX_BUF				256
+
+BYTE teslaflashParams[MAX_BUF];
+
+
+/*******************************************************************************
+FUNCTION NAME:
+	teslaflashGetParams
+
+ABSTRACT:	
+	Get the home plug parameters from the Tesla flash storage segment.
+
+RETURN:
+	Status
+
+DETAILS:
+*******************************************************************************/
+
+static void teslaflashGetParams( void )
+{
+
+	CNXT_FLASH_STATUS_E flashStatus;
+	CNXT_FLASH_SEGMENT_E segment = CNXT_TESLA_FLASH_SEGMENT;
+	int		i;
+	BYTE	*pteslaParams;
+
+	flashStatus = CnxtFlashOpen( segment );
+
+	switch( flashStatus )
+	{
+		case CNXT_FLASH_DATA_ERROR:
+			printk("Flash Data Error: CNXT_FLASH_SEGMENT_%d\n", segment+1 );
+
+			// Get the default home plug device parameters
+			pteslaParams = (BYTE *)&Default_TeslaControl;
+	
+			for( i = 0; i < sizeof(TeslaControl_Str); i++ )
+			{
+				teslaflashParams[i] = *pteslaParams;
+				pteslaParams++;
+			}
+
+			// Update the flash device with the default home plug parameters
+			flashStatus = CnxtFlashWriteRequest( 
+				segment, 
+				(UINT16 *)&teslaflashParams[0],
+				sizeof(TeslaControl_Str)
+			);
+			break;
+
+		case CNXT_FLASH_OWNER_ERROR:
+			printk("Wrong owner for requested Flash Segment!\n");
+			break;
+
+		default:
+
+			CnxtFlashReadRequest( 
+				segment, 
+				(UINT16 *)&teslaflashParams,
+				sizeof(TeslaControl_Str)
+			);
+
+			pteslaParams = (BYTE *)&Current_TeslaControl;
+
+			// Update the home plug device parameter structure
+			// with the values saved in the flash device.
+			for( i = 0; i < sizeof(TeslaControl_Str); i++ )
+			{
+				*pteslaParams = teslaflashParams[i];
+				pteslaParams++;
+			}
+			printk("Flash Data Success: CNXT_FLASH_SEGMENT_%d\n", segment+1 );
+			break;
+	}
+}
+
+
+static const UCHAR BroadcastAddress[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+/****************************************************************************
+* TransmitPriorities
+*
+* These bit masks are indexed by the Configured Transmit Priority setting.
+*
+****************************************************************************/
+
+static const UCHAR TransmitPriorities[] = {INT5130_CAP0, INT5130_CAP1, INT5130_CAP2, INT5130_CAP3 };
+
+/****************************************************************************
+* RetryControls
+*
+* These bit masks are indexed by the Configured Retry Control setting.
+*
+****************************************************************************/
+static UCHAR const RetryControls[]      = {INT5130_RETRY_CTL_NONE, INT5130_RETRY_CTL_ONE, INT5130_RETRY_CTL_ALL};
+
+/****************************************************************************
+* int5130SendCharacteristicsInit
+*
+* Construct the send characteristics from the supplied parameters.
+*
+* SendCharacteristics0 Bits
+*        7     (LC0)                Local Consumption only flag (not configurable)
+*        6     (ENCF)               Encryption enable flag
+*        5-4   (TxPriority)         Transmit Priority (CAP0=00b CAP1=01b CAP2=10b CAP3=11b)
+*        3     (RESP_EXP)           Response Expected Flag
+*        2     (TX_CONT_FREE)       Transmit contention free period (not configurable)
+*        1     (CONT_FREE_TOKEN)    Contention Token (not configurable)
+*        0     (TX_WITH_TOKEN)      Transmit with token (not configurable)
+*
+* SendCharacteristics1 Bits
+*        7-6   (RETRY_CTRL)         Retry Control
+*        5-0   (RESERVED)           Reserved Bits
+*
+* SendCharacteristics1 Bits
+*        7-0   (ENCRYPT_KEY_SELECT) Which Encryption Key o use (if SendChar0 Bit 7 is set)
+*                                   00000000b - Use Default Key
+*                                   00000001b - Use Network Key
+*
+****************************************************************************/
+static EMAC_DRV_CTRL *MACAdapter = NULL ;	// TBD
+
+void Emac_TeslaSetup( TESLA_HANDLE Tesla_Adapter, TeslaControl_Str *pTeslaControl )
+{
+
+	ADDR_TBL *FreeTxBuffer;
+
+	PUCHAR  pSendBuf ;
+	ULONG   nSendSize   = 0;
+	UCHAR    cfgSendCharacteristics0 ;    // 0x18,   LCO, EncryptFlag, TxPriority, ResponseExpected, TxToken Stuff
+	UCHAR    cfgSendCharacteristics1 ;    // 0x80,   Retry Control 00=NoRetry 01=OneRetry 10=All Retry?
+	short	i;
+
+	if( Tesla_Adapter )
+	{
+		MACAdapter = (EMAC_DRV_CTRL *)Tesla_Adapter ;
+	}
+
+	if (pTeslaControl->ChipSelectGpio != -1)
+	{
+		WriteGPIOData(pTeslaControl->ChipSelectGpio, 1);		// set high for Homeplug MAC select
+	}
+
+   // Setup send characteristic 0
+	cfgSendCharacteristics0 = TransmitPriorities[pTeslaControl->TransmitPriority] ;
+	if ( pTeslaControl->EncryptEnableFlag )
+	{
+		cfgSendCharacteristics0 |= INT5130_ENCF_MASK;
+	}
+	if ( pTeslaControl->ResponseExpected )
+	{
+		cfgSendCharacteristics0 |= INT5130_RESPEXP_ON;
+	}
+
+   // Setup send characteristic 1
+	cfgSendCharacteristics1 = RetryControls[pTeslaControl->RetryControl] ;
+
+	FreeTxBuffer = Get_Free_Tx_Buffer( MACAdapter) ;
+	pSendBuf = (UINT8 *)Packet_Buffer_Virtual_Adr(FreeTxBuffer) ;
+
+//     NdisStallExecution(50);
+//     NdisStallExecution(50);
+
+   // Put standard Ethernet header into buffer (dest source type)
+   INT5130_BUFFER_PUT_ADDR(BroadcastAddress);
+
+	MAC_Assign_MacAddress( MACAdapter, pSendBuf ) ;
+	pSendBuf += SIZE_ETHER_ADDRESS;
+	nSendSize += SIZE_ETHER_ADDRESS;
+
+//   INT5130_BUFFER_PUT_ADDR(MACAdapter->node_address);
+   
+   INT5130_BUFFER_PUT(INT5130_FRAME_TYPE_OCTET_1);
+   INT5130_BUFFER_PUT(INT5130_FRAME_TYPE_OCTET_2);
+                 
+   /* Indicate the number of data entries to follow. */
+   INT5130_BUFFER_PUT(INT5130_INIT_FRAME_ENTRY_COUNT);
+
+   /* Construct local parameters frame. */
+   INT5130_BUFFER_PUT(INT5130_SET_LOCAL_PARAMETERS);
+   INT5130_BUFFER_PUT(INT5130_LOCAL_PARAMETER_LENGTH);
+
+   /* Insert another copy of the MAC address. */
+	MAC_Assign_MacAddress( MACAdapter, pSendBuf ) ;
+	pSendBuf += SIZE_ETHER_ADDRESS; nSendSize += SIZE_ETHER_ADDRESS;
+
+   /* Construct xmit characteristics frame for local consumption only. */
+   INT5130_BUFFER_PUT(INT5130_SET_TRANSMIT_CHARACTERISTICS);
+   INT5130_BUFFER_PUT(INT5130_SET_TRANSMIT_CHARACTERISTICS_LENGTH);
+
+   //Tesla - need to construct cfgSendCharacteristics0 from 
+   //		RetrievedRegistryValues->EncryptFlag, TxPriority, ResponseExpected, TxToken Stuff
+   INT5130_BUFFER_PUT(INT5130_LCO_ON | cfgSendCharacteristics0);
+   INT5130_BUFFER_PUT(cfgSendCharacteristics1);
+   INT5130_BUFFER_PUT( (UCHAR)pTeslaControl->NetworkKeySelect ) ;
+
+   /* Construct two encryption key frames. */
+   /* First, put in the default key. */
+   INT5130_BUFFER_PUT(INT5130_SET_NETWORK_ENCRYPTION_KEY);
+   INT5130_BUFFER_PUT(INT5130_ENCRYPTION_KEY_LENGTH+1);
+   INT5130_BUFFER_PUT(0);  /* Default Key */
+
+	INT5130_BUFFER_PUT_KEY( pTeslaControl->DefaultKeyOverride );
+#if 0
+	MAC_Assign_MacAddress( MACAdapter, pSendBuf+2 ) ;
+	// make DefaultEncryptionKey
+	pSendBuf[0] = pSendBuf[6];
+	pSendBuf[1] = pSendBuf[7];
+	pSendBuf += INT5130_ENCRYPTION_KEY_LENGTH; nSendSize += INT5130_ENCRYPTION_KEY_LENGTH;
+#endif
+
+   /* Now the network key. */
+   INT5130_BUFFER_PUT(INT5130_SET_NETWORK_ENCRYPTION_KEY);
+   INT5130_BUFFER_PUT(INT5130_ENCRYPTION_KEY_LENGTH+1);
+   INT5130_BUFFER_PUT( (UCHAR)pTeslaControl->NetworkKeySelect ) ;
+	INT5130_BUFFER_PUT_KEY(pTeslaControl->NetworkEncryptionKey);
+
+   /* Construct xmit characteristics frame NOT for local consumption. */
+   INT5130_BUFFER_PUT(INT5130_SET_TRANSMIT_CHARACTERISTICS);
+   INT5130_BUFFER_PUT(INT5130_SET_TRANSMIT_CHARACTERISTICS_LENGTH);
+   INT5130_BUFFER_PUT(cfgSendCharacteristics0);
+   INT5130_BUFFER_PUT(cfgSendCharacteristics1);
+   INT5130_BUFFER_PUT( (UCHAR)pTeslaControl->NetworkKeySelect ) ;
+
+   // Pad out to minimum packet size
+   if (nSendSize < MIN_ETHER_PACKET_SIZE)
+   {
+      ZERO_MEMORY(pSendBuf, MIN_ETHER_PACKET_SIZE-nSendSize); /* Zero out the padded memory */
+      nSendSize = MIN_ETHER_PACKET_SIZE;
+	}
+
+	MAC_Send_A_Frame( MACAdapter, nSendSize, FreeTxBuffer, TRUE ) ;
+
+	// Set up AFE if type is defined as ADI in config.reg
+
+	if (pTeslaControl->AfeType == AFE_ADI)
+	{
+		// configure settings
+		for (i = 0; i < pTeslaControl->RegisterConfig[1]; i++)
+			Write_ADI_AFE(
+				pTeslaControl->RegisterConfig[2*(i+1)],		// reg address
+				pTeslaControl->RegisterConfig[2*(i+1)+1],	// value to program
+				pTeslaControl->ChipSelectGpio);
+	}
+}
+
+/****************************************************************************
+* End Of Tesla int5130SendConfigPacket
+****************************************************************************/
+
+#if 0	// TBD , collect code in this module
+
+//Tesla - Initialize Encryption Keys
+
+	UCHAR bNullKey[INT5130_ENCRYPTION_KEY_LENGTH] = {0};
+	UCHAR bNetworkKeyDefault[INT5130_ENCRYPTION_KEY_LENGTH] = {0x01, 0xf2, 0xe3, 0xd4, 0xc5, 0xb6, 0xa7, 0x98};
+	#define KEY_IS_NULL(key)  NdisEqualMemory(key, bNullKey, INT5130_ENCRYPTION_KEY_LENGTH)
+
+
+/****************************************************************************
+* int5130EncryptKeysInit
+*
+* Complete the initialization of our encryption keys, based on what was
+* originally read from the registry.
+*
+* This routine assumes that our network address has already been setup.
+*
+****************************************************************************/
+VOID
+EncryptKeysInit(
+	IN PULONG SourceValue, //RetrievedRegistryValues[OVERRIDE_DEFAULT_KEY_KEY]
+	IN UCHAR DefaultKey[INT5130_ENCRYPTION_KEY_LENGTH], //Adapter->DefaultEncryptionKey
+	IN UCHAR NetworkKey[INT5130_ENCRYPTION_KEY_LENGTH], //Adapter->NetworkEncryptionKey
+	IN PUCHAR RegistryNetworkAddress
+	)
+{
+	// Check to see if we need to initialize our default key
+   if (!SourceValue || KEY_IS_NULL(DefaultKey)) //pCard->cfg.cfgDefaultEncryptKey
+		{
+		//Do the hash for the default encryption key. We use the lower 16 bits of the MAC addr
+		//for the upper 16 bits of 64 and then the entire 48 bits of the MAC addr for the rest.
+		NdisMoveMemory(DefaultKey, &RegistryNetworkAddress[4], 2);
+		NdisMoveMemory(&DefaultKey[2], RegistryNetworkAddress, 6);
+		}
+DbgPrint("DefaultKey %x \n", DefaultKey);
+DbgPrint("RegistryNetAddr %x \n", RegistryNetworkAddress);
+   
+	// Check to see if we need to initialize our network key
+	if (KEY_IS_NULL(NetworkKey))
+		{
+		NdisMoveMemory(NetworkKey, bNetworkKeyDefault, INT5130_ENCRYPTION_KEY_LENGTH);
+		}
+}
+
+
+//Tesla read encryption key from registry-used in following function
+/****************************************************************************
+* UniCharToNibble
+*
+* Convert a unicode character  to a hex nibble.  Return 0xFF if its not a legal
+* hex nibble.
+*
+****************************************************************************/
+UCHAR UniCharToNibble(SHORT wNibble)
+{
+   UCHAR nNibble;
+
+   // We only care about the lower byte
+   wNibble &= 0xff;
+   
+   if (wNibble >= '0' && wNibble <= '9')
+      nNibble = wNibble - '0';
+   else if (wNibble >= 'A' && wNibble <= 'F')
+      nNibble = (wNibble - 'A') + 10;
+   else if (wNibble >= 'a' && wNibble <= 'f')
+      nNibble = (wNibble - 'a') + 10;
+   else
+      nNibble = 0xff;
+
+   return nNibble;
+}
+
+// Tesla read encryption key from registry
+/****************************************************************************
+* CfgReadEncryptKey
+*
+* Read an encryption key from the registery (as a unicode string), and
+* convert it to an 8 byte binary array.
+*
+* NOTE: NOTE: For Win 95 Gold and Win 95 OSR-1, Registry Strings are ASCII (not Unicode)
+* If you really want to support these, check if nKeyLength == INT5130_ENCRYPTION_KEY_LENGTH.
+* If it is assume its ASCII and proceed accordingly.
+*
+* All other Windows versions starting with Win 95 OSR-2 store registery strings
+* as unicode.
+*
+* This routine is good for Win 95 OSR-2 and newer versions of Windows O/S.
+*
+****************************************************************************/
+VOID
+ReadEncryptKey(
+	IN PUNICODE_STRING SourceString,
+	IN UCHAR EncryptKey[INT5130_ENCRYPTION_KEY_LENGTH]
+	)
+{
+//   PNDIS_CONFIGURATION_PARAMETER pCfgParam;
+	UCHAR	key[INT5130_ENCRYPTION_KEY_LENGTH];
+	PUSHORT	pHexString;
+	PUCHAR	pHexByte    = key;
+	BOOLEAN	bGoodHex    = TRUE;
+	UCHAR	nNibbleHi;
+	UCHAR	nNibbleLo;
+	int		nKeyUniLen;
+	int		nKeySize;
+	int		i;
+
+	{
+
+   
+	nKeyUniLen	= SourceString->Length;
+	pHexString	= (PUSHORT)(&(SourceString->Buffer[0]));
+
+	// Don't overflow our key buffer.
+	nKeySize = nKeyUniLen / 2;
+	if (nKeySize > INT5130_ENCRYPTION_KEY_LENGTH)
+		nKeySize = INT5130_ENCRYPTION_KEY_LENGTH;
+      
+		for (i=0; i<nKeySize; i++)
+		{
+			nNibbleHi = UniCharToNibble(*pHexString++);
+			nNibbleLo = UniCharToNibble(*pHexString++);
+
+			if (nNibbleHi == 0xff || nNibbleLo == 0xff)
+			{
+				bGoodHex = FALSE;
+				break;
+			}
+
+			*pHexByte++ = (nNibbleHi << 4) + nNibbleLo;
+		}
+
+	if (bGoodHex == TRUE)
+		{
+			NdisMoveMemory(EncryptKey, key, INT5130_ENCRYPTION_KEY_LENGTH);
+		}
+	}  
+	return;
+}
+
+
+{
+   if (RetrievedRegistryValues[ENCRYPT_ENABLE_FLAG_KEY])  //(Adapter->cfgEncryptEnableFlag)
+      Adapter->cfgSendCharacteristics0 |= INT5130_ENCF_MASK;
+   if (RetrievedRegistryValues[RESPONSE_EXPECTED_KEY])  //(Adapter->cfgResponseExpected)
+      Adapter->cfgSendCharacteristics0 |= INT5130_RESPEXP_ON;
+
+   // Setup send characteristic 1
+   Adapter->cfgSendCharacteristics1    = RetryControls[RetrievedRegistryValues[RETRY_CONTROL_KEY]]; //RetryControls[Adapter->cfgRetryControl];
+}
+#endif
+
+
+// return FALSE if failed (ex: Emac not started)
+
+// TBD : not worked as specified, Kludge for HomePlug only
+// TBD : need to move to emac instead of tesla
+BOOLEAN Emac_Phy_Attached( Emac_DevType *pPort1, Emac_DevType *pPort2 )
+{
+
+	if( MACAdapter )
+		*pPort1 = Emac_HomePlug_Phy ;
+	else
+		*pPort1 = Emac_Ethernet_Phy ;
+
+	*pPort2 = Emac_Ethernet_Phy ;
+	return TRUE ;
+}
+
+
+// Save Tesla control specified by TeslaControl into config.reg
+// return FALSE : if fail to write
+BOOLEAN Emac_TeslaConfigSave( TeslaControl_Str *TeslaControl ) 
+{
+	Current_TeslaControl = *TeslaControl ;
+	Emac_TeslaCurrentConfigSave( NULL) ;
+
+	return TRUE ;
+}
+
+// Read the current Tesla control into TeslaControl
+// Return TRUE :  If Emac read these settings from config.reg successfully else
+// Return FALSE : Emac would still load the default settings into TeslaControl
+BOOLEAN Emac_TeslaConfigRead( TeslaControl_Str *TeslaControl ) 
+{
+	BOOLEAN    bResult = FALSE;
+
+#if OS_FILE_SYSTEM_SUPPORTED
+	JX_REG_VAL_DESC PortConfigDesc[] =
+	{
+		{
+			"EncryptEnableFlag",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->EncryptEnableFlag),
+			&TeslaControl->EncryptEnableFlag
+		},
+		{
+			"NetworkEncryptionKey",
+			JX_REG_VAL_BINARY,
+			sizeof(TeslaControl->NetworkEncryptionKey),
+			&TeslaControl->NetworkEncryptionKey
+		},
+		{
+			"TransmitPriority",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->TransmitPriority),
+			&TeslaControl->TransmitPriority
+		},
+		{
+			"ResponseExpected",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->ResponseExpected),
+			&TeslaControl->ResponseExpected
+		},
+		{
+			"RetryControl",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->RetryControl),
+			&TeslaControl->RetryControl
+		},
+		{
+			"OverrideDefaultKey",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->OverrideDefaultKey),
+			&TeslaControl->OverrideDefaultKey
+		},
+		{
+			"DefaultKeyOverride",
+			JX_REG_VAL_BINARY,
+			sizeof(TeslaControl->DefaultKeyOverride),
+			&TeslaControl->DefaultKeyOverride
+		},
+		{
+			"NetworkKeySelect",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->NetworkKeySelect),
+			&TeslaControl->NetworkKeySelect
+		},
+		{
+			"AfeType",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->AfeType),
+			&TeslaControl->AfeType
+		},
+		{
+			"OptSettingAlgorithm",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->OptSettingAlgorithm),
+			&TeslaControl->OptSettingAlgorithm
+		},
+		{
+			"AlgorithmTime",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->AlgorithmTime),
+			&TeslaControl->AlgorithmTime
+		},
+		{
+			"RegisterConfig",
+			JX_REG_VAL_BINARY,
+			sizeof(TeslaControl->RegisterConfig),
+			&TeslaControl->RegisterConfig
+		},
+		{
+			"ChipSelectGpio",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->ChipSelectGpio),
+			&TeslaControl->ChipSelectGpio
+		}
+	};
+
+	JX_REG_KEY_HANDLE   hKey    = NULL;
+
+	*TeslaControl = Default_TeslaControl ;	// set default 
+
+	if((hKey = JxRegOpenKey(NULL, HOMEPLUG_ROOT_KEY)) != NULL)
+	{
+		bResult = JxRegQueryStruct
+		(
+			hKey,
+			NUMBER_OF_ELEMENTS(PortConfigDesc),
+			PortConfigDesc
+		);
+
+		JxRegCloseKey(hKey);
+	}
+
+	Current_TeslaControl = *TeslaControl ;
+#else
+	
+	teslaflashGetParams();
+
+	// Parameters in the Current_TeslaControl structure were
+	// loaded from the data stored in the flash device.
+	*TeslaControl = Current_TeslaControl;
+	bResult = TRUE;
+#endif
+	return bResult;
+}
+
+BOOLEAN static Emac_TeslaConfigSaveToFile( TeslaControl_Str *TeslaControl )
+{
+	BOOLEAN    bResult = FALSE;
+
+#if OS_FILE_SYSTEM_SUPPORTED
+	struct JX_REG_VAL_DESC PortConfigDesc[] =
+	{
+		{
+			"EncryptEnableFlag",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->EncryptEnableFlag),
+			&TeslaControl->EncryptEnableFlag
+		},
+		{
+			"NetworkEncryptionKey",
+			JX_REG_VAL_BINARY,
+			sizeof(TeslaControl->NetworkEncryptionKey),
+			&TeslaControl->NetworkEncryptionKey
+		},
+		{
+			"TransmitPriority",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->TransmitPriority),
+			&TeslaControl->TransmitPriority
+		},
+		{
+			"ResponseExpected",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->ResponseExpected),
+			&TeslaControl->ResponseExpected
+		},
+		{
+			"RetryControl",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->RetryControl),
+			&TeslaControl->RetryControl
+		},
+		{
+			"OverrideDefaultKey",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->OverrideDefaultKey),
+			&TeslaControl->OverrideDefaultKey
+		},
+		{
+			"DefaultKeyOverride",
+			JX_REG_VAL_BINARY,
+			sizeof(TeslaControl->DefaultKeyOverride),
+			&TeslaControl->DefaultKeyOverride
+		},
+		{
+			"NetworkKeySelect",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->NetworkKeySelect),
+			&TeslaControl->NetworkKeySelect
+		},
+		{
+			"AfeType",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->AfeType),
+			&TeslaControl->AfeType
+		},
+		{
+			"OptSettingAlgorithm",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->OptSettingAlgorithm),
+			&TeslaControl->OptSettingAlgorithm
+		},
+		{
+			"AlgorithmTime",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->AlgorithmTime),
+			&TeslaControl->AlgorithmTime
+		},
+		{
+			"RegisterConfig",
+			JX_REG_VAL_BINARY,
+			sizeof(TeslaControl->RegisterConfig),
+			&TeslaControl->RegisterConfig
+		},
+		{
+			"ChipSelectGpio",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->ChipSelectGpio),
+			&TeslaControl->ChipSelectGpio
+		}
+	};
+
+	JX_REG_KEY_HANDLE   hKey    = NULL;
+
+	if((hKey = JxRegCreateKey(NULL, HOMEPLUG_ROOT_KEY)) != NULL)
+	{
+		bResult = JxRegSetStruct
+		(
+			hKey,
+			NUMBER_OF_ELEMENTS(PortConfigDesc),
+			PortConfigDesc
+		);
+
+		JxRegCloseKey(hKey);
+	}
+#endif
+	return bResult;
+}
+
+// Emac to save the current Tesla Controls into config.reg
+// 12/03/01, the function currently called by CfgMgr at Appy time to write 
+// trigger : Windweb Savesetting ... ????
+// if input Tesla_Adapter is NULL, Emac will setup whatever Homeplug Phy it detect 
+void Emac_TeslaCurrentConfigSave( TESLA_HANDLE Tesla_Adapter)
+{
+
+	// Tesla_Adapter : only one now so no need to check
+	Emac_TeslaConfigSaveToFile( &Current_TeslaControl );
+}
+
+#ifdef HOMEPLUG_PHYMAC_OVERFLOW_WORKAROUND
+
+// TBD , allow one HOMEPLUG instance only
+// TBD , how about reset 
+
+#define MAC_ADDRESSES_IDENTICAL(a1,a2) (memcmp((UCHAR *)a1,(UCHAR *)a2, 6 ) == 0)   
+
+static ULONG SendStatsRequests = 0 ;
+static ULONG StatsRequests = 0 ;
+static ULONG StatsRequestsReqDelay = 0 ;
+
+static BOOLEAN TeslaRequireTxDelay = FALSE ;
+static ULONG LastTxAck = 0;
+static ULONG LastTxCont = 0;
+
+void Emac_TeslaSendStatsRequest(
+	TESLA_HANDLE Tesla_Adapter
+)
+{
+	ADDR_TBL *FreeTxBuffer ;
+	PUCHAR  pSendBuf ;
+	ULONG   nSendSize   = 0;
+
+#if TESLA_DEBUG
+	if( MACAdapter != (PMACAPI)Tesla_Adapter )
+	{
+		printf( "TBD : support only one HOMEPLUG instance\n" ) ;
+	}
+#endif
+
+#if 0
+	if( SendStatsRequests != StatsRequests )
+	{
+		TeslaRequireTxDelay  = TRUE ;
+		SendStatsRequests = StatsRequests ;
+#if TESLA_DEBUG
+		StatsRequestsReqDelay++ ;
+#endif
+		return ;
+	}
+#endif
+
+	FreeTxBuffer = Get_Free_Tx_Buffer( MACAdapter) ;
+
+	if( !FreeTxBuffer)
+		return ;
+
+	SendStatsRequests++ ;
+
+	pSendBuf = (U8 *)Packet_Buffer_Virtual_Adr(FreeTxBuffer) ;
+
+	MAC_Assign_MacAddress( MACAdapter, pSendBuf ) ;
+
+	pSendBuf += SIZE_ETHER_ADDRESS; nSendSize += SIZE_ETHER_ADDRESS;
+
+	MAC_Assign_MacAddress( MACAdapter, pSendBuf ) ;
+
+	pSendBuf += SIZE_ETHER_ADDRESS; nSendSize += SIZE_ETHER_ADDRESS;
+
+   INT5130_BUFFER_PUT(INT5130_FRAME_TYPE_OCTET_1);
+   INT5130_BUFFER_PUT(INT5130_FRAME_TYPE_OCTET_2);
+                 
+   /* Indicate the number of data entries to follow. */
+   INT5130_BUFFER_PUT(1);
+
+   /* Construct local parameters frame. */
+   INT5130_BUFFER_PUT(INT5130_REQUEST_PARAMETERS_AND_STATISTICS) ;
+	// length 0
+   INT5130_BUFFER_PUT(0) ;
+
+	MAC_Send_A_Frame( MACAdapter, MIN_ETHER_PACKET_SIZE, FreeTxBuffer, TRUE ) ;
+}
+
+BOOLEAN Emac_TeslaRequireTxDelay( TESLA_HANDLE Tesla_Adapter )
+{
+
+#if TESLA_DEBUG
+	if( MACAdapter != (PMACAPI)Tesla_Adapter )
+	{
+		printf( "TBD : support only one HOMEPLUG instance\n" ) ;
+	}
+#endif
+
+	return TeslaRequireTxDelay  ;
+}
+
+
+BOOLEAN  Emac_TeslaIsStatsPacket
+(
+	TESLA_HANDLE	Tesla_Adapter,
+	PUCHAR 			DataPacket
+) 
+{
+	ULONG Index;
+	ULONG TxAck;
+	ULONG TxCont;
+
+#if TESLA_DEBUG
+	if( MACAdapter != (PMACAPI)Tesla_Adapter )
+	{
+		printf( "TBD : support only one HOMEPLUG instance\n" ) ;
+	}
+#endif
+
+	if ((DataPacket[12] == INT5130_FRAME_TYPE_OCTET_1) && 
+	(DataPacket[13] == INT5130_FRAME_TYPE_OCTET_2) &&
+	DataPacket[15] == 0x08 ) 	// PARAMETERS_AND_STATISTICS Response
+	{
+	char SMacAddr[SIZE_ETHER_ADDRESS] ;
+
+		MAC_Assign_MacAddress( MACAdapter, SMacAddr ) ;
+
+		if( MAC_ADDRESSES_IDENTICAL (DataPacket+6, SMacAddr )) 
+		{
+
+			StatsRequests++ ;
+			TxAck  = (DataPacket[17] << 8) + DataPacket[18];
+			TxCont = (DataPacket[23] << 8) + DataPacket[24];
+			TxAck  -= LastTxAck; 
+			TxCont -= LastTxCont;
+			TxAck  -= (TxAck >> 3); 
+			if (TxCont > TxAck) {
+				TeslaRequireTxDelay = TRUE ;
+#if 0	// TESLA_DEBUG
+				StatsRequestsReqDelay++ ;
+
+				printf( "SendStatsRequests=%ld, StatsRequests= %ld, StatsRequestsReqDelay =%ld \n",
+				SendStatsRequests, StatsRequests, StatsRequestsReqDelay ) ;
+#endif
+			}
+			else {
+				TeslaRequireTxDelay = FALSE ;
+			}
+			LastTxAck =  (DataPacket[17] << 8) + DataPacket[18];
+			LastTxCont = (DataPacket[23] << 8) + DataPacket[24];
+			return (TRUE);
+		}
+	}
+
+	// allow all other HOMEPLUG frames to upper for installation or diagnosis application
+	return (FALSE);
+}
+
+#endif	// HOMEPLUG_PHYMAC_OVERFLOW_WORKAROUND
+
+/******************************************************************************
+|
+|  Function:    TeslaState
+|
+|  Description: Sets and Gets whether Tesla exists
+|
+|  Parameters:  SetState: 1 = turns Tesla state on, 0 = do nothing
+|				Tesla state off by default
+|
+|  Returns:     TRUE (Tesla exists), FALSE (otherwise)
+*******************************************************************************/
+
+BOOLEAN TeslaState(short SetState)
+{
+	static BOOLEAN state = FALSE;
+
+	if (SetState == 1)
+	{
+		state = TRUE;
+	}
+
+	return state;
+}
+
+unsigned int *EMAC1_MDIO_REG = (unsigned int *)0x310018;
+
+#define	MDIO_MASK		0x1FL
+#define	MDIO_DEFAULT	0x08
+#define MDIO_CLK_LO		0x00
+#define MDIO_CLK_HI		0x01
+#define MDIO_READ_MODE	0x18		// rising edge for ADI + input mode
+#define MDIO_READ_BIT	0x02
+
+void Write_ADI_Byte(char RegByte)
+{
+	short	i;
+	DWORD	io_data;
+	char	data;
+	volatile int	j;
+
+	// Preserve non-MDIO bits in shared MAC_MDIO_REG
+	io_data = *EMAC1_MDIO_REG & ~MDIO_MASK;
+
+	for (i = 7; i >= 0; i--)		// sweep across byte (MSB first)
+	{
+		data = (((RegByte>>i)&1)<<2);
+		*EMAC1_MDIO_REG = io_data | MDIO_CLK_LO | data;
+		for (j = 10; j; j--);
+		*EMAC1_MDIO_REG = io_data | MDIO_CLK_HI | data;
+		for (j = 10; j; j--);
+		// These 2 for loops generate a 500 kHz clk on MDC with the processor running at 144 MHz
+	}
+}
+
+char Read_ADI_Byte(void)
+{
+	short	i;
+	DWORD	io_data;
+	char	read_data = 0;
+	volatile int	j;
+
+	// Preserve non-MDIO bits in shared MAC_MDIO_REG
+	io_data = *EMAC1_MDIO_REG & ~MDIO_MASK;
+
+	// Set for read mode
+	io_data |= MDIO_READ_MODE;
+	*EMAC1_MDIO_REG = io_data;
+
+	for (i = 7; i >= 0; i--)		// sweep across byte (MSB first)
+	{
+		*EMAC1_MDIO_REG = io_data | MDIO_CLK_LO;
+		for (j = 10; j; j--);
+		*EMAC1_MDIO_REG = io_data | MDIO_CLK_HI;
+		read_data |= ((*EMAC1_MDIO_REG & MDIO_READ_BIT) >> 1) << i;
+		for (j = 10; j; j--);
+		// These 2 for loops generate a 500 kHz clk on MDC with the processor running at 144 MHz
+	}
+
+	return read_data;
+}
+
+/******************************************************************************
+|
+|  Function:    Read_ADI_AFE
+|
+|  Description: Reads from the ADI AFE control register
+|
+|  Parameters:  RegisterAddress - register control address
+|
+|  Returns:     contents of register control at requested address
+*******************************************************************************/
+
+char Read_ADI_AFE(char RegisterAddress, short GpioEnable)
+{
+	char	returnByte;
+
+	if (GpioEnable != -1)
+		WriteGPIOData(GpioEnable, 0);
+
+	Write_ADI_Byte(RegisterAddress | 0x80);		// need bit 7 hi to let AFE know this is a read request
+	returnByte = Read_ADI_Byte();
+
+	if (GpioEnable != -1)
+		WriteGPIOData(GpioEnable, 1);
+
+	*EMAC1_MDIO_REG = (*EMAC1_MDIO_REG & ~MDIO_MASK)|MDIO_DEFAULT;
+
+	return returnByte;
+}
+
+/******************************************************************************
+|
+|  Function:    Write_ADI_AFE
+|
+|  Description: Writes to the ADI AFE control register
+|
+|  Parameters:  RegisterAddress - register control address
+|				RegisterData - register data
+|
+|  Returns:     void
+*******************************************************************************/
+
+void Write_ADI_AFE(char RegisterAddress, char RegisterData, short GpioEnable)
+{
+	if (GpioEnable != -1)
+		WriteGPIOData(GpioEnable, 0);
+
+	Write_ADI_Byte(RegisterAddress);
+	Write_ADI_Byte(RegisterData);
+
+	if (GpioEnable != -1)
+		WriteGPIOData(GpioEnable, 1);
+
+	*EMAC1_MDIO_REG = (*EMAC1_MDIO_REG & ~MDIO_MASK)|MDIO_DEFAULT;
+}
diff -urN linux-2.4.29/drivers/net/cnxt_emac/tesla.h linux-2.4.29-uc1/drivers/net/cnxt_emac/tesla.h
--- linux-2.4.29/drivers/net/cnxt_emac/tesla.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/tesla.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,138 @@
+/****************************************************************************
+* $Header: /cvs/sw/linux-2.4.x/drivers/net/cnxt_emac/tesla.h,v 1.1 2005/02/18 04:53:51 gerg Exp $
+*
+*  Copyright(c)2001  Conexant Systems
+*
+*****************************************************************************/
+
+// Bright Shih, 11/12/2001
+#if !defined(TESLA_H_)
+#define	TESLA_H_
+
+//#define HOMEPLUG_PHYMAC_OVERFLOW_WORKAROUND 1
+
+//#define HOMEPLUG_GPIO8		1
+//#define GPIO8_DEBUG			1
+
+typedef enum def_ACCESS_PRIORITY
+{
+	CA0 = 0,
+	CA1,
+	CA2,
+	CA3,
+} ACCESS_PRIORITY ;
+
+typedef enum def_TX_RETRY_CONTROL
+{
+	TX_NO_RETRY = 0,
+	TX_ONE_RETRY ,
+	TX_NORMAL_RETRY ,
+} TX_RETRY_CONTROL ;
+
+typedef enum def_AFE_TYPE
+{
+	AFE_ADI = 0,
+	AFE_INTELLON ,
+	AFE_UNKNOWN ,
+} AFE_TYPE ;
+
+typedef enum def_SETTING_ALGORITHM		// optimum setting algorithm
+{
+	ALG_NONE = 0,
+	ALG_HUNT ,
+} SETTING_ALGORITHM ;
+
+typedef struct def_TeslaControl_Str
+{
+BOOLEAN				EncryptEnableFlag ;		// default FALSE
+UCHAR				NetworkEncryptionKey[8];// default  0x01,0xf2,0xe3,0xd4,0xc5, 0xb6, 0xa7,0x98 
+
+ACCESS_PRIORITY		TransmitPriority ;		// default CA1
+BOOLEAN				ResponseExpected ;		// default TRUE
+TX_RETRY_CONTROL	RetryControl;			// default TX_NORMAL_RETRY
+
+UCHAR				PasswordPlainText[32];
+
+// below hidden from end users
+BOOLEAN				OverrideDefaultKey	;	// default FALSE ;
+UCHAR				DefaultKeyOverride[8] ;	//	default get from device driver - expose to user only if OverrideDefaultKey is TRUE
+DWORD				NetworkKeySelect ;		// 1-255, default NETWORK_KEY 1 ( 0 - use DEFAULT_KEY)
+
+AFE_TYPE			AfeType ;				// default AFE_ADI
+SETTING_ALGORITHM	OptSettingAlgorithm ;	// default ALG_HUNT
+DWORD				AlgorithmTime ;			// default 120 (seconds)
+
+UCHAR				RegisterConfig[16] ;	// default:
+											//		in pairs except for 0 and 1
+											//		pairs denote register and value to set
+											//		0: 0x00, 0x03 - denotes 3 reg to program
+											//		2: 0x04, 0x0c (Reg 0x04 = 0x0c)
+											//		4: 0x05, 0xff (Reg 0x05 = 0xff)
+											//		6: 0x06, 0x80 (Reg 0x06 = 0x80)
+											//      0x00 for the rest since only 3 reg set by default
+
+DWORD				ChipSelectGpio ;		// default 19
+} TeslaControl_Str ;
+
+#define TESLA_HANDLE void*
+
+// call Emac to get the HomePlug Handle, 
+// return NULL if no HOMEPLUG phy detected
+// TESLA_HANDLE Emac_HomePlugHandle(void) ;
+
+typedef enum def_Emac_DevType
+{
+	Emac_No_Phy = 0,
+	Emac_Ethernet_Phy ,
+	Emac_HomePlug_Phy ,
+	Emac_Hpna_Phy ,
+	// future Phy support
+} Emac_DevType ;
+
+// return FALSE if failed (ex: Emac not started)
+BOOLEAN Emac_Phy_Attached( Emac_DevType *pPort1, Emac_DevType *pPort2 ) ;
+
+
+// Save Tesla control specified by TeslaControl into config.reg
+// return FALSE : if fail to write
+BOOLEAN Emac_TeslaConfigSave( TeslaControl_Str *TeslaControl ) ;
+
+
+// Read the current Tesla control into TeslaControl
+// Return TRUE :  If Emac read these settings from config.reg successfully else
+// Return FALSE : Emac would still load the default settings into TeslaControl
+BOOLEAN Emac_TeslaConfigRead( TeslaControl_Str *TeslaControl ) ;
+
+
+// Ask Emac to setup Homeplug phy with pTeslaControl
+// if input Tesla_Adapter is NULL, Emac will setup whatever Homeplug Phy it detect
+void Emac_TeslaSetup( TESLA_HANDLE Tesla_Adapter, TeslaControl_Str *pTeslaControl ) ;
+
+
+// Emac to save the current Tesla Controls into config.reg
+// 12/03/01, the function currently called by CfgMgr at Appy time to write 
+// trigger : Windweb Savesetting ... ????
+// if input Tesla_Adapter is NULL, Emac will setup whatever Homeplug Phy it detect 
+void Emac_TeslaCurrentConfigSave( TESLA_HANDLE Tesla_Adapter) ;
+
+
+void Write_ADI_AFE(char RegisterAddress, char RegisterData, short GpioEnable);
+char Read_ADI_AFE(char RegisterAddress, short GpioEnable);
+
+#if 1		// HOMEPLUG_PHYMAC_OVERFLOW_WORKAROUND
+void Emac_TeslaSendStatsRequest(
+	TESLA_HANDLE Tesla_Adapter
+) ;
+
+BOOLEAN Emac_TeslaRequireTxDelay( TESLA_HANDLE Tesla_Adapter ) ;
+
+BOOLEAN  Emac_TeslaIsStatsPacket (
+	TESLA_HANDLE Tesla_Adapter,
+	unsigned char * DataPacket ) ;
+
+
+#define HomePlug_TX_Delay	2	// suggest 2 milli second
+
+#endif
+
+#endif
diff -urN linux-2.4.29/drivers/net/cnxt_emac/verFeatures.h linux-2.4.29-uc1/drivers/net/cnxt_emac/verFeatures.h
--- linux-2.4.29/drivers/net/cnxt_emac/verFeatures.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cnxt_emac/verFeatures.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,168 @@
+/****************************************************************************
+*
+*	Name:			verFeatures.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*					Personal Computing Division
+*					All Rights Reserved
+*
+****************************************************************************
+*  $Author: gerg $
+*  $Revision: 1.1 $
+*  $Modtime:   Mar 19 2003 12:25:22  $
+****************************************************************************/
+
+#ifndef _VER_H
+#define _VER_H
+
+/*
+ * Version numbers
+ */
+
+/* EMAC HW versions */
+#define REV_A   1
+#define REV_B	2
+#define REV_C   3
+#define REV_D   4
+
+/* EMAC SW versions */
+#define VER_01   1
+#define VER_02   2
+#define VER_03   3
+#define VER_04   4
+#define VER_05   5
+#define VER_06   6
+#define VER_07   7
+#define VER_08   8
+#define VER_09   9
+#define VER_10   10
+#define VER_11   11
+#define VER_12   12
+#define VER_13   13
+#define VER_14   14
+#define VER_15   15
+#define VER_16   16
+#define VER_17   17
+#define VER_18   18
+#define VER_19   19
+#define VER_20   20
+
+/* EMAC versions */
+#define MAC_HW_VER      REV_C		
+#define MAC_SW_VER      VER_06     
+
+/*
+ * Version Features.
+ */
+
+/* Defines to control code generation depending on features available. */
+
+#define INC_SNMP  0 /* AD Aug18 SNMP API support: include SNMP. */
+
+#define NETPOOL_USE_DEF_FUNCTBL
+#define REMEMBER_MClBlks_CL_STARTADDR
+#define UCAST_IN_IOCTL		/* Unicast addr manipulation using IOCTL */
+/*#define USE_BSP_ENET_RTN*/	/* Use the BSP fn to get the mac addr 1st time */
+#define USE_BSP_SRAM_RTN
+/*#define USE_BSP_DMA_M2M_OBJ*/
+/*#define SUPPORT_MACADDR_FILTER*/
+#define INC_PHY
+
+
+#define USE_DMA_M2M_COPY_OP1
+#define BUG_MUX_PATCH
+
+
+/* Do rxHandling - netJobAdd - as late as possible. */
+#define RXHANDLING_AS_SOON_AS_POSSIBLE				1
+#define RXHANDLING_AS_LATE_AS_POSSIBLE				2
+#define RXHANDLING_NO_RXHANDLING					3
+#define RXHANDLING RXHANDLING_AS_LATE_AS_POSSIBLE
+
+#if     (MAC_HW_VER == REV_A)
+
+#define EMAC_TX_DMA_LMODE DMA_LMODE_TAIL
+#define BUG_HW_EMAC_RX_1   /* This bug is in REV_A & will not be in REV_B/C...*/
+#define BUG_HW_EMAC_RX_2   /* This bug is in REV_A & will not be in REV_B/C...*/
+#define ZERO_MEM_USING_DMA /* zero memory using DMA */
+
+#else   /* not MAC_HW_VER_A*/
+
+#undef  BUG_HW_EMAC_RX_1 
+#define EMAC_TX_DMA_LMODE DMA_LMODE_TAIL
+
+#endif  /*MAC_HW_VER_A*/
+
+#define TEST_PLATFORM_MODEL     1
+#define TEST_PLATFORM_HW        2
+#define TEST_PLATFORM           TEST_PLATFORM_HW
+
+
+/*
+ * Version strings.
+ */
+
+/* EMAC HW version strings */
+#if     (MAC_HW_VER == REV_A)
+#define MAC_HW_VER_STR  "A"
+#elif   (MAC_HW_VER == REV_B)
+#define MAC_HW_VER_STR  "B"
+#elif   (MAC_HW_VER == REV_C)
+#define MAC_HW_VER_STR  "C"
+#elif   (MAC_HW_VER == REV_D)
+#define MAC_HW_VER_STR  "D"
+#else
+#error Invalid EMAC HW version.
+#endif
+
+/* EMAC SW version strings */
+#if     (MAC_SW_VER == VER_01)
+#define MAC_SW_VER_STR  "0.1"
+#elif   (MAC_SW_VER == VER_02)
+#define MAC_SW_VER_STR  "0.2"
+#elif   (MAC_SW_VER == VER_03)
+#define MAC_SW_VER_STR  "0.3"
+#elif   (MAC_SW_VER == VER_04)
+#define MAC_SW_VER_STR  "0.4"
+#elif   (MAC_SW_VER == VER_05)
+#define MAC_SW_VER_STR  "0.5"
+#elif   (MAC_SW_VER == VER_06)
+#define MAC_SW_VER_STR  "0.6"
+#elif   (MAC_SW_VER == VER_07)
+#define MAC_SW_VER_STR  "0.7"
+#elif   (MAC_SW_VER == VER_08)
+#define MAC_SW_VER_STR  "0.8"
+#elif   (MAC_SW_VER == VER_09)
+#define MAC_SW_VER_STR  "0.9"
+#elif   (MAC_SW_VER == VER_10)
+#define MAC_SW_VER_STR  "1.0"
+#elif   (MAC_SW_VER == VER_11)
+#define MAC_SW_VER_STR  "1.1"
+#elif   (MAC_SW_VER == VER_12)
+#define MAC_SW_VER_STR  "1.2"
+#elif   (MAC_SW_VER == VER_13)
+#define MAC_SW_VER_STR  "1.3"
+#elif   (MAC_SW_VER == VER_14)
+#define MAC_SW_VER_STR  "1.4"
+#elif   (MAC_SW_VER == VER_15)
+#define MAC_SW_VER_STR  "1.5"
+#elif   (MAC_SW_VER == VER_16)
+#define MAC_SW_VER_STR  "1.6"
+#elif   (MAC_SW_VER == VER_17)
+#define MAC_SW_VER_STR  "1.7"
+#elif   (MAC_SW_VER == VER_18)
+#define MAC_SW_VER_STR  "1.8"
+#elif   (MAC_SW_VER == VER_19)
+#define MAC_SW_VER_STR  "1.9"
+#elif   (MAC_SW_VER == VER_20)
+#define MAC_SW_VER_STR  "2.0"
+#else
+#error Invalid EMAC SW version.
+#endif
+
+/* EMAC versions */
+#define MAC_VER_STR "v:" MAC_HW_VER_STR "," MAC_SW_VER_STR
+
+#endif _VER_H
diff -urN linux-2.4.29/drivers/net/Config.in linux-2.4.29-uc1/drivers/net/Config.in
--- linux-2.4.29/drivers/net/Config.in	2005-01-19 14:09:56.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/Config.in	2005-06-14 02:12:09.000000000 +0100
@@ -1,3 +1,4 @@
+# $USAGI: Config.in,v 1.23 2003/11/12 05:11:25 yoshfuji Exp $
 #
 # Network device configuration
 #
@@ -7,6 +8,11 @@
 tristate 'Dummy net driver support' CONFIG_DUMMY
 tristate 'Bonding driver support' CONFIG_BONDING
 tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
+if [ "$CONFIG_NETFILTER" = "y" ]; then
+  tristate 'IMQ (intermediate queueing device) support' CONFIG_IMQ
+else
+  comment 'IMQ needs CONFIG_NETFILTER enabled'
+fi
 tristate 'Universal TUN/TAP device driver support' CONFIG_TUN
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
    tristate 'Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP
@@ -24,12 +30,55 @@
 comment 'Ethernet (10 or 100Mbit)'
 bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET
 if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
+
+   if [ "$CONFIG_CPU_S3C2500" = "y" ]; then
+      bool '  Samsung S3C2500 Embedded Ethernet support' CONFIG_ETH_S3C2500
+      if [ "$CONFIG_UCBOOTSTRAP" != "y" ]; then
+         string 'S3C2500 MAC Address' S3C2500_HWADDR 00:00:00:00:00:00
+      fi
+   fi
+   if [ "$CONFIG_CPU_S3C4510" = "y" ]; then
+      tristate '  Samsung 4510B ethernet support' CONFIG_ETH_S3C4510
+   fi
+   if [ "$CONFIG_CPU_S3C4530" = "y" ]; then
+      bool '  Samsung S3C4530A Embedded Ethernet support' CONFIG_ETH_S3C4530
+      if [ "$CONFIG_UCBOOTSTRAP" != "y" ]; then
+         string 'S3C4530 MAC Address' S3C4530_HWADDR 00:00:00:00:00:00
+      fi
+   fi
    if [ "$CONFIG_ARM" = "y" ]; then  
+      if [ "$CONFIG_ARCH_KS8695" = "y" ]; then
+         tristate '  KS8695 internal ethernet support' CONFIG_KS8695
+         if [ "$CONFIG_KS8695" = "y" -o "$CONFIG_KS8695" = "m" ]; then
+            bool '    Hardware IP/TCP/UDP checksum' CONFIG_CSUM_UNNECESSARY
+         fi
+      fi
       dep_bool '  ARM EBSA110 AM79C961A support' CONFIG_ARM_AM79C961A $CONFIG_ARCH_EBSA110
       tristate '  Cirrus Logic CS8900A support' CONFIG_ARM_CIRRUS
+      if [ "$CONFIG_ARCH_EP93XX" = "y" ]; then
+         tristate '  EP93xx Ethernet support' CONFIG_EP93XX_ETHERNET
+      fi
       if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
          source drivers/acorn/net/Config.in
       fi
+      if [ "$CONFIG_ARCH_VC547X" = "y" ]; then
+         tristate 'C5471 LAN ethernet' CONFIG_C5471_NET
+         if [ "$CONFIG_C5471_NET" = "y" ]; then
+           int 'C5471 LAN rate (0=Auto,10,100)' C5471_LAN_RATE 0
+         else
+           define_hex C5471_LAN_RATE 0x00000000
+         fi
+      fi
+      if [ "$CONFIG_ARCH_INL" = "y" ]; then
+         dep_bool '  Intersil MVC driver support' CONFIG_ISIL_MVCDRIVER $CONFIG_ARCH_INL
+         dep_bool '  ISL3893 Standalone ethernet support' CONFIG_ISL3893_ETHERNET $CONFIG_ARCH_ISL3893
+      fi
+   fi
+   if [ "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
+      tristate '  AT91RM9200 Ethernet support' CONFIG_AT91_ETHER
+      if [ "$CONFIG_AT91_ETHER" = "y" -o "$CONFIG_AT91_ETHER" = "m" ]; then
+         bool '      RMII interface?   ' CONFIG_AT91_ETHER_RMII
+      fi
    fi
    if [ "$CONFIG_ARCH_CAMELOT" = "y" ]; then
 	tristate ' Altera Ether00 support' CONFIG_ETHER00
@@ -116,6 +165,7 @@
       dep_tristate '    SMC Ultra support' CONFIG_ULTRA $CONFIG_ISA
       dep_tristate '    SMC Ultra32 EISA support' CONFIG_ULTRA32 $CONFIG_EISA
       dep_tristate '    SMC 9194 support' CONFIG_SMC9194 $CONFIG_ISA
+      tristate     '    SMC 91111 support' CONFIG_SMC91111
    fi
    bool '  Racal-Interlan (Micom) NI cards' CONFIG_NET_VENDOR_RACAL
    if [ "$CONFIG_NET_VENDOR_RACAL" = "y" ]; then
@@ -165,6 +215,7 @@
    fi
    if [ "$CONFIG_NET_PCI" = "y" ]; then
       dep_tristate '    AMD PCnet32 PCI support' CONFIG_PCNET32 $CONFIG_PCI
+      dep_mbool    '        Use VMware support with AMD PCnet32(EXPERIMENTAL)' CONFIG_PCNET32_VMWARE $CONFIG_PCNET32 $CONFIG_EXPERIMENTAL
       dep_tristate '    AMD 8111 (new PCI lance) support' CONFIG_AMD8111_ETH $CONFIG_PCI
       dep_tristate '    Adaptec Starfire/DuraLAN support' CONFIG_ADAPTEC_STARFIRE $CONFIG_PCI
       if [ "$CONFIG_ISA" = "y" -o "$CONFIG_EISA" = "y" ]; then
@@ -199,11 +250,24 @@
       dep_tristate '    Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL
       dep_tristate '    Racal-Interlan EISA ES3210 support (EXPERIMENTAL)' CONFIG_ES3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL
       dep_tristate '    RealTek RTL-8139 C+ PCI Fast Ethernet Adapter support (EXPERIMENTAL)' CONFIG_8139CP $CONFIG_PCI $CONFIG_EXPERIMENTAL
+      if [ "$CONFIG_8139CP" != "n" ]; then
+	  dep_mbool '      Support for External PHY' CONFIG_8139CP_EXTERNAL_PHY $CONFIG_8139CP $CONFIG_EXPERIMENTAL
+	  if [ "$CONFIG_8139CP_EXTERNAL_PHY" = "y" ]; then
+        int '        The CP uses this Phy' CONFIG_8139CP_PHY_NUM 32
+	  else
+		define_int CONFIG_8139CP_PHY_NUM 32
+	  fi
+      fi
       dep_tristate '    RealTek RTL-8139 PCI Fast Ethernet Adapter support' CONFIG_8139TOO $CONFIG_PCI
       dep_mbool '      Use PIO instead of MMIO' CONFIG_8139TOO_PIO $CONFIG_8139TOO
       dep_mbool '      Support for uncommon RTL-8139 rev. K (automatic channel equalization)' CONFIG_8139TOO_TUNE_TWISTER $CONFIG_8139TOO
       dep_mbool '      Support for older RTL-8129/8130 boards' CONFIG_8139TOO_8129 $CONFIG_8139TOO
       dep_mbool '      Use older RX-reset method' CONFIG_8139_OLD_RX_RESET $CONFIG_8139TOO
+      dep_mbool '      Support for External PHY' CONFIG_8139TOO_EXTERNAL_PHY $CONFIG_8139TOO $CONFIG_EXPERIMENTAL
+      if [ "$CONFIG_8139TOO_EXTERNAL_PHY" = "y" ]; then
+         int '        External PHY number' CONFIG_8139TOO_PHY_NUM 32
+      fi
+      dep_tristate '    ORIGINAL RealTek RTL-8139 PCI Fast Ethernet Adapter support' CONFIG_RTL8139 $CONFIG_PCI
       dep_tristate '    SiS 900/7016 PCI Fast Ethernet Adapter support' CONFIG_SIS900 $CONFIG_PCI
       dep_tristate '    SMC EtherPower II' CONFIG_EPIC100 $CONFIG_PCI
       dep_tristate '    Sundance Alta support' CONFIG_SUNDANCE $CONFIG_PCI
@@ -215,6 +279,7 @@
 	 dep_tristate '    TOSHIBA TC35815 Ethernet support' CONFIG_TC35815 $CONFIG_PCI
       fi
       dep_tristate '    VIA Rhine support' CONFIG_VIA_RHINE $CONFIG_PCI
+      dep_tristate '    VIA Rhine FET support' CONFIG_VIA_RHINE_FET $CONFIG_PCI
       dep_mbool '      Use MMIO instead of PIO (EXPERIMENTAL)' CONFIG_VIA_RHINE_MMIO $CONFIG_VIA_RHINE $CONFIG_EXPERIMENTAL
       dep_tristate '    Winbond W89c840 Ethernet support' CONFIG_WINBOND_840 $CONFIG_PCI
       if [ "$CONFIG_OBSOLETE" = "y" ]; then
@@ -232,6 +297,51 @@
       dep_tristate '    D-Link DE600 pocket adapter support' CONFIG_DE600 $CONFIG_ISA
       dep_tristate '    D-Link DE620 pocket adapter support' CONFIG_DE620 $CONFIG_ISA
    fi
+   tristate '  CNXT Emac support' CONFIG_CNXT_EMAC
+   if [ "$CONFIG_CNXT_EMAC" != "n" ]; then
+      if [ "$CONFIG_ARCH_CX821XX" = "y" ]; then
+         define_bool CONFIG_CNXT_EMAC_82 y
+      fi
+      choice '    Number of Ethernet Ports'  " \
+         1   CONFIG_NUM_ETHERNET_IS_1 \
+         2   CONFIG_NUM_ETHERNET_IS_2 \
+         3   CONFIG_NUM_ETHERNET_IS_3 \
+         4   CONFIG_NUM_ETHERNET_IS_4 \
+         "  1
+   fi
+   bool '  FEC ethernet controller (of ColdFire 5272/5282/5280)' CONFIG_FEC
+   if [ "$CONFIG_FEC" = "y" ]; then
+	dep_mbool '   enable second FEC port (5274/5275)' CONFIG_FEC2 $CONFIG_M527x
+	dep_mbool '   enable IOCTL (EXPERIMENTAL)'  CONFIG_FEC_IOCTL $CONFIG_EXPERIMENTAL
+	dep_mbool '   uCdimm PHY interrupt support (uC5272 v1.3 +) '  CONFIG_UC5272_PHY_INT $CONFIG_BOARD_UC5272 
+	bool      '   Micrel KS8995M switch chip support' CONFIG_FEC_KS8995M
+	if [ "$CONFIG_FEC_KS8995M" = "y" ]; then
+		choice 'KS8995M MII Mode' \
+		"MII-P5 CONFIG_FEC_KS8995M_P5 \
+		MII-SW CONFIG_FEC_KS8995M_SW" MII-P5
+	fi
+   fi
+   tristate '  CS89x0 support' CONFIG_CS89x0
+   bool '  uCcs8900 support' CONFIG_UCCS8900
+   if [ "$CONFIG_CS89x0" = "y" -o "$CONFIG_UCCS8900" = "y" ]; then
+      bool '    Hardware byte-swapping support for CS89x0 Ethernet' CONFIG_UCCS89x0_HW_SWAP
+   fi
+   if [ "$CONFIG_UCCS8900" = "y" -a "$CONFIG_UCBOOTSTRAP" != "y" ]; then
+      string 'CS8900A MAC Address' CS8900A_HWADDR 00:00:00:00:00:00
+   fi
+   if [ "$CONFIG_ARCH_ATMEL" = "y" ]; then
+      tristate '  SkyEye ne2k ethernet support (for ARMulator)' CONFIG_SKYEYENE2k
+   fi
+
+   if [ "$CONFIG_ARCH_NETARM" = "y" ]; then
+      tristate 'NET+ARM built-in Ethernet controller' CONFIG_ETHER_NETARM
+      if [ "$CONFIG_ETHER_NETARM" = "y" ]; then
+         hex 'hexadecimal MAC OUI' NETARM_OUI 0040AF
+      fi
+   fi
+   if [ "$CONFIG_NETARM_NS7520" = "y" ]; then
+      tristate 'NS7520 built-in Ethernet controller' CONFIG_ETHER_NS7520
+   fi
    if [ "$CONFIG_SGI_IP22" = "y" ]; then
       tristate '  SGI Seeq ethernet controller support' CONFIG_SGISEEQ
    fi
@@ -273,6 +383,9 @@
    tristate 'SB1250 Ethernet support' CONFIG_NET_SB1250_MAC
 fi
 dep_tristate 'Marvell Yukon Chipset / SysKonnect SK-98xx Support' CONFIG_SK98LIN $CONFIG_PCI
+if [ "$CONFIG_SK98LIN" != "n" ]; then
+	bool '    Use Rx polling (NAPI)' CONFIG_SK98LIN_NAPI
+fi
 dep_tristate 'Broadcom Tigon3 support' CONFIG_TIGON3 $CONFIG_PCI
 
 if [ "$CONFIG_MOMENCO_OCELOT_C" = "y" -o "$CONFIG_MOMENCO_JAGUAR_ATX" = "y" ]; then
diff -urN linux-2.4.29/drivers/net/cs89x0.c linux-2.4.29-uc1/drivers/net/cs89x0.c
--- linux-2.4.29/drivers/net/cs89x0.c	2003-08-25 12:44:42.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/cs89x0.c	2005-06-14 02:12:09.000000000 +0100
@@ -81,9 +81,24 @@
                     : Make `version[]' __initdata
                     : Uninlined the read/write reg/word functions.
 
+  Craig Peacock     : Apr 2001 - Craig.Peacock@senet.com.au
+  Tom Walsh         : May 2001 - tom@openhardware.net
+  David McCullough  : Jun 2001 - davidm@snapgear.com
+                    : Customized for use on uClinux & MC68EZ328 platforms.
+ 
+  Evan Stawnyczy    : Customized for use on MC68VZ328 platform.
+
+  Daniel Potts      : uClinux sleep support, ucDimm
+  Mark McChrystal   : uClinux sleep support, ucSimm
+
   Oskar Schirmer    : oskar@scara.com
                     : HiCO.SH4 (superh) support added (irq#1, cs89x0_media=)
 
+  Craig Hackney     : Added support for Triscend A7S.
+
+  Chee Tim Loh      : cheetim_loh@innomedia.com.sg
+                    : Added support for TI TMS320DM270.
+
 */
 
 /* Always include 'config.h' first in case the user wants to turn on
@@ -98,7 +113,12 @@
  * Note that even if DMA is turned off we still support the 'dma' and  'use_dma'
  * module options so we don't break any startup scripts.
  */
+#ifdef CONFIG_UCLINUX
+#define ALLOW_DMA	0
+#define NO_EPROM
+#else
 #define ALLOW_DMA	1
+#endif
 
 /*
  * Set this to zero to remove all the debug statements via
@@ -106,6 +126,11 @@
  */
 #define DEBUGGING	1
 
+#if defined(CONFIG_DRAGEN2) || defined(CONFIG_ARCH_TA7S)
+#undef DEBUGGING
+#define DEBUGGING	0
+#endif
+
 /*
   Sources:
 
@@ -128,7 +153,11 @@
 #include <linux/init.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
+#ifndef CONFIG_UCCS89x0_HW_SWAP
 #include <asm/io.h>
+#else
+#include <asm/io_hw_swap.h>
+#endif
 #if ALLOW_DMA
 #include <asm/dma.h>
 #endif
@@ -138,9 +167,44 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/pm.h>
 
 #include "cs89x0.h"
 
+
+#ifdef CONFIG_M68328
+#include <asm/irq.h>
+#include <asm/MC68328.h>
+#endif
+
+#ifdef CONFIG_M68EZ328
+#include <asm/irq.h>
+#include <asm/MC68EZ328.h>
+#endif
+
+#ifdef CONFIG_M68VZ328
+#include <asm/irq.h>
+#include <asm/MC68VZ328.h>
+#endif
+
+#ifdef CONFIG_EXCALIBUR
+#include <asm/nios.h>
+#endif
+
+#ifdef CONFIG_ARCH_TA7S
+#include <asm/arch/arch.h>
+#include <asm/arch/irqs.h>
+#endif
+
+#ifdef CONFIG_ARCH_DM270
+#include <asm/irq.h>
+#endif
+
+#ifdef CONFIG_HYPERSTONE 
+#include <asm/irq.h>
+#include <asm/io.h>
+#endif
+
 static char version[] __initdata =
 "cs89x0.c: v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>\n";
 
@@ -155,14 +219,34 @@
 /* The cs8900 has 4 IRQ pins, software selectable. cs8900_irq_map maps 
    them to system IRQ numbers. This mapping is card specific and is set to
    the configuration of the Cirrus Eval board for this chip. */
-#ifdef CONFIG_ARCH_CLPS7500
+#if defined(CONFIG_ALMA_ANS)
+static unsigned int netcard_portlist[] __initdata = { 0x10200300, 0 };
+#elif defined(CONFIG_UCSIMM) || defined(CONFIG_UCDIMM)
+static unsigned int netcard_portlist[] __initdata = { 0x10000300, 0 };
+#elif defined(CONFIG_EZ328LCD) || defined(CONFIG_VZ328LCD)
+static unsigned int netcard_portlist[] __initdata = { 0x2000300, 0 };
+#elif defined(CONFIG_ARCH_TA7S)
+static unsigned int netcard_portlist[] __initdata = { 0x10000000, 0 };
+#elif defined(CONFIG_ARCH_DM270)
+static unsigned int netcard_portlist[] __initdata = { 0x07c00300, 0 };
+#elif defined(CONFIG_DRAGONIXVZ) || defined(CONFIG_CWVZ328)
+static unsigned int netcard_portlist[] __initdata = { 0x4000000, 0 };
+#elif defined(CONFIG_ARCH_CLPS7500)
 static unsigned int netcard_portlist[] __initdata =
    { 0x80090303, 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
 static unsigned int cs8900_irq_map[] = {12,0,0,0};
+#elif defined(CONFIG_EXCALIBUR)
+static unsigned int netcard_portlist[] __initdata = { ((int) (na_enet)), 0 };
 #elif defined(CONFIG_SH_HICOSH4)
 static unsigned int netcard_portlist[] __initdata =
    { 0x0300, 0};
 static unsigned int cs8900_irq_map[] = {1,0,0,0};
+#elif defined(CONFIG_HYPERSTONE_CS89X0)
+static unsigned int netcard_portlist[] __initdata = { 0x01000300, 0 };
+#elif defined(CONFIG_ARCH_EDB7312)
+static unsigned int netcard_portlist[] __initdata =
+   { 0xfc000003, 0 };
+static unsigned int cs8900_irq_map[] = {7,0,0,0};
 #else
 static unsigned int netcard_portlist[] __initdata =
    { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
@@ -235,6 +319,9 @@
 static void get_dma_channel(struct net_device *dev);
 static void release_dma_buff(struct net_local *lp);
 #endif
+#ifdef CONFIG_UCLINUX
+static void get_dev_addr(struct net_device *dev);
+#endif
 
 /* Example routines you must write ;->. */
 #define tx_done(dev) 1
@@ -254,6 +341,11 @@
 __setup("cs89x0_dma=", dma_fn);
 #endif	/* !defined(MODULE) && (ALLOW_DMA != 0) */
 
+
+#ifdef CONFIG_PM
+static int cs89x0_in_use = 0;
+#endif
+
 #ifndef MODULE
 static int g_cs89x0_media__force;
 
@@ -279,12 +371,23 @@
 
 int __init cs89x0_probe(struct net_device *dev)
 {
-	int i;
-	int base_addr = dev ? dev->base_addr : 0;
+#ifdef CONFIG_UCLINUX
+	static int i = 0; /* don't probe twice */
+#else
+	int i = 0;
+#endif
+	int base_addr = (dev && dev->base_addr != 0xffe0) ? dev->base_addr : 0;
 
 	SET_MODULE_OWNER(dev);
 
-	if (net_debug)
+#if defined(CONFIG_DRAGEN2)
+	if (dev) {
+		extern int dragen2_cs8900_setup(struct net_device *dev);
+		base_addr = dragen2_cs8900_setup(dev);
+	}
+#endif
+
+	if (net_debug > 1)
 		printk("cs89x0:cs89x0_probe(0x%x)\n", base_addr);
 
 	if (base_addr > 0x1ff)		/* Check a single specified location. */
@@ -292,11 +395,20 @@
 	else if (base_addr != 0)	/* Don't probe at all. */
 		return -ENXIO;
 
-	for (i = 0; netcard_portlist[i]; i++) {
-		if (cs89x0_probe1(dev, netcard_portlist[i]) == 0)
+	for (; netcard_portlist[i]; i++) {
+		if (cs89x0_probe1(dev, netcard_portlist[i]) == 0) {
+			i++;
 			return 0;
+		}
+#ifdef CONFIG_UCLINUX
+		printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected at 0x%x\n",
+				netcard_portlist[i]);
+#endif
 	}
-	printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected.  Be sure to disable PnP with SETUP\n");
+#ifndef CONFIG_UCLINUX
+	if (net_debug)
+		printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected.  Be sure to disable PnP with SETUP\n");
+#endif
 	return -ENODEV;
 }
 
@@ -326,6 +438,52 @@
 	outw(value, dev->base_addr + portno);
 }
 
+#if 0 
+static int
+readreg(struct net_device *dev, int portno)
+{
+	long lala;
+	
+	printk("Sthn readreg diabazei apo  0x%x, 0x%8x \n",portno, dev->base_addr);
+	//__udelay(5000);
+
+	outw(portno, dev->base_addr + ADD_PORT);
+	lala= inw(dev->base_addr + DATA_PORT);
+	printk("Apo thn readreg epistrefei 0x%x\n",lala);
+	return lala;
+}
+
+static void
+writereg(struct net_device *dev, int portno, int value)
+{
+	printk("Sthn writereg grafei %x, 0x%x\n",portno, value);
+	//__udelay(5000);
+
+	outw(portno, dev->base_addr + ADD_PORT);
+	outw(value, dev->base_addr + DATA_PORT);
+}
+
+static int
+readword(struct net_device *dev, int portno)
+{
+	long lala;
+	printk("Sthn readword diabazei apo  0x%x,\n",portno);
+	//__udelay(5000);
+
+	lala= inw(dev->base_addr + portno);
+	printk("Apo thn readword epistrefei 0x%x\n",lala);
+	return lala;
+}
+
+static void
+writeword(struct net_device *dev, int portno, int value)
+{
+	printk("Sthn writereg grafei %x, 0x%x\n",portno, value);
+	outw(value, dev->base_addr + portno);
+}
+#endif
+#ifndef NO_EPROM
+
 static int __init
 wait_eeprom_ready(struct net_device *dev)
 {
@@ -371,6 +529,56 @@
 	return -1;
 }
 
+#endif /* NO_EPROM */
+
+
+#if defined(CONFIG_PM)
+
+static struct pm_dev *cs89x0_pm;
+
+/* cs89x0_pm_callback():
+ *
+ *  We don't actually suspend or resume here - that is left to the
+ *  net_open/close functions.
+ *  On PM_SUSPEND: we check that the connection is closed down. If it is, we
+ *  return success. PM_RESUME does nothing.
+ *  It is required that the user brings the connection down (perhaps via
+ *  a pm helper daemon)
+ */
+static int cs89x0_pm_callback(struct pm_dev *dev, pm_request_t request, void *data)
+{
+	struct net_device *cs_dev = (struct net_device *)dev->data;
+
+	switch (request) {
+	case PM_SUSPEND:
+		if (cs89x0_in_use) {
+			printk("cs89x00 connection still open, not sleeping\n");
+			return -EBUSY;
+		}
+
+#if defined(CONFIG_UCSIMM)
+		/* set sleep pin low */
+		*(volatile unsigned char *)0xfffff429 &= ~(0x01);
+		writereg(cs_dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) & ~(AUTO_WAKEUP));
+#elif defined(CONFIG_UCDIMM)
+		*(volatile unsigned char *)0xfffff431 &= ~(0x08);
+#endif
+		writereg(cs_dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | SLEEP_ON);
+		break;
+	case PM_RESUME:
+#if defined (CONFIG_UCSIMM)
+		*(volatile unsigned short *)0xfffff429 |= 0x01; /* not sleeping */
+#elif defined(CONFIG_UCDIMM)
+		*(volatile unsigned char *)0xfffff431 |= (0x08);
+#endif
+		break;
+	}
+
+	return 0;
+}
+
+#endif
+
 /* This is the real probe routine.  Linux has a history of friendly device
    probes on the ISA bus.  A good device probes avoids doing writes, and
    verifies that the correct device exists and functions.
@@ -387,6 +595,84 @@
 	int eeprom_buff[CHKSUM_LEN];
 	int retval;
 
+#ifdef CONFIG_DRAGONIXVZ
+	printk("cs89x0: Setting up DragonixVZ CS8900 Chip Select & IRQ ioaddr = 0x%X\n",ioaddr);
+	/* set up the chip select */
+	*(volatile unsigned  char *)0xfffff41b &= ~0x80; /* input irq6 */
+        *(volatile unsigned  char *)0x04000105= 0x01; /* nSleep=1 */
+#endif
+
+#ifdef CONFIG_CWVZ328
+	printk("cs89x0: Setting up CWVZ328 CS8900 Chip Select & IRQ ioaddr = 0x%X\n",ioaddr);
+	*(volatile unsigned  char *)0xfffff42b |= 0x01; /* output /sleep */
+	*(volatile unsigned short *)0xfffff428 |= 0x0101; /* not sleeping */
+
+	*(volatile unsigned  char *)0xfffff42b &= ~0x02; /* input irq5 */
+	*(volatile unsigned short *)0xfffff428 &= ~0x0202; /* irq5 fcn on */
+
+	*(volatile unsigned short *)0xfffff102 = 0x2000; /* 0x4000000 */
+	*(volatile unsigned short *)0xfffff112 = 0x01e1; /* 128k, 2ws, FLASH, en */
+#endif
+
+#if defined( CONFIG_UCSIMM ) || defined(CONFIG_UCDIMM)
+#ifdef CONFIG_UCSIMM
+	printk("cs89x0: Setting up uCsimm CS8900 Chip Select & IRQ ioaddr = 0x%X\n",ioaddr);
+
+	/* set up the chip select */
+	*(volatile unsigned  char *)0xfffff42b |= 0x01; /* output /sleep */
+	*(volatile unsigned short *)0xfffff428 |= 0x0101; /* not sleeping */
+
+#else   /* UCDIMM */
+	printk("cs89x0: Setting up uCcs8900 Chip Select & IRQ ioaddr = 0x%X\n",ioaddr);
+
+	/* set up the chip select */
+	*(volatile unsigned char *)0xfffff430 |= 0x08;
+	*(volatile unsigned char *)0xfffff433 |= 0x08;
+	*(volatile unsigned char *)0xfffff431 |= (0x08); /* sleep */
+#endif
+	*(volatile unsigned  char *)0xfffff42b &= ~0x02; /* input irq5 */
+	*(volatile unsigned short *)0xfffff428 &= ~0x0202; /* irq5 fcn on */
+
+	*(volatile unsigned short *)0xfffff102 = 0x8000; /* 0x04000000 */
+	*(volatile unsigned short *)0xfffff112 = 0x01e1; /* 128k, 2ws, FLASH, en */
+#endif
+
+#ifdef CONFIG_EXCALIBUR
+	*(char *)ioaddr = 0;			/* Reset the chip to a usable state. */
+	dev->base_addr = ioaddr;
+	if (readreg(dev, PP_ChipID) != CHIP_EISA_ID_SIG) {
+		retval = -ENODEV;
+		goto out;
+	}
+#ifdef na_enet_reset_n
+	*(volatile unsigned char*)na_enet_reset_n=3;
+#endif	
+	printk("cs89x0: Setting up uCcs8900 Chip Select & IRQ ioaddr = 0x%X\n",ioaddr);
+#endif
+
+#ifdef CONFIG_ARCH_DM270
+	printk("cs89x0: Setting up TI TMS320DM270 CS8900A IRQ ioaddr = 0x%X\n",ioaddr);
+	/* Set GIO port to input */
+	outw(inw(DM270_GIO_DIR(DM270_INTERRUPT_EXT4)) | (1<<DM270_GIO_DIR_SHIFT(DM270_INTERRUPT_EXT4)),
+			DM270_GIO_DIR(DM270_INTERRUPT_EXT4));
+
+	/* Set GIO as interrupt port */
+	outw(inw(DM270_GIO_IRQPORT) | (1<<DM270_GIO_IRQPORT_SHIFT(DM270_INTERRUPT_EXT4)),
+			DM270_GIO_IRQPORT);
+
+	/*
+	 * CS8900A INTRQ goes high when an enabled interrupt is triggered
+	 * and goes low after ISQ is read as all 0's
+	 */
+
+	/* Trigger on rising edge */
+	outw(inw(DM270_GIO_INV(DM270_INTERRUPT_EXT4)) | (1<<DM270_GIO_INV_SHIFT(DM270_INTERRUPT_EXT4)),
+			DM270_GIO_INV(DM270_INTERRUPT_EXT4));
+
+	/* Use single-sided edge interrupts */
+	outw(inw(DM270_GIO_IRQEDGE) & ~(1<<DM270_GIO_IRQEDGE_SHIFT(DM270_INTERRUPT_EXT4)), DM270_GIO_IRQEDGE);
+#endif
+
 	/* Initialize the device structure. */
 	if (dev->priv == NULL) {
 		dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
@@ -410,6 +696,7 @@
         }
 	lp = (struct net_local *)dev->priv;
 
+#ifndef CONFIG_UCLINUX
 	/* Grab the region so we can find another board if autoIRQ fails. */
 	if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, dev->name)) {
 		printk(KERN_ERR "%s: request_region(0x%x, 0x%x) failed\n",
@@ -417,6 +704,9 @@
 		retval = -EBUSY;
 		goto out1;
 	}
+#endif /* CONFIG_UCLINUX */
+
+#if !defined(CONFIG_UCLINUX) || defined(CONFIG_DRAGEN2)
 
 #ifdef CONFIG_SH_HICOSH4
 	/* truely reset the chip */
@@ -441,7 +731,7 @@
 		ioaddr &= ~3;
 		outw(PP_ChipID, ioaddr + ADD_PORT);
 	}
-printk("PP_addr=0x%x\n", inw(ioaddr + ADD_PORT));
+	if (net_debug) printk("PP_addr=0x%x\n", inw(ioaddr + ADD_PORT));
 
 	if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG) {
 		printk(KERN_ERR "%s: incorrect signature 0x%x\n",
@@ -449,10 +739,36 @@
   		retval = -ENODEV;
   		goto out2;
 	}
+#endif /* !CONFIG_UCLINUX || CONFIG_DRAGEN2 */
 
 	/* Fill in the 'dev' fields. */
 	dev->base_addr = ioaddr;
 
+#if defined CONFIG_DRAGONIXVZ
+	dev->irq = IRQ6_IRQ_NUM;
+#endif
+
+#if defined( CONFIG_UCSIMM ) || defined( CONFIG_EZ328LCD ) || defined( CONFIG_UCDIMM ) || defined( CONFIG_CWVZ328)
+	dev->irq = IRQ5_IRQ_NUM;
+#endif
+
+#ifdef CONFIG_EXCALIBUR
+	dev->irq = na_enet_irq;
+#endif
+
+#ifdef CONFIG_ARCH_TA7S
+	dev->irq = IRQ_CSL_USER_0;
+#endif
+
+#ifdef CONFIG_ARCH_DM270
+	dev->irq = DM270_INTERRUPT_EXT4;
+#endif
+
+#if defined CONFIG_E132XS_BOARD 
+	dev->irq = CONFIG_HYPERSTONE_CS89X0_IRQ-1;
+	memcpy(dev->dev_addr, "\x48\x79\x4c\x6e\x78\x30", 6); /* FIXME */
+#endif
+
 	/* get the chip type */
 	rev_type = readreg(dev, PRODUCT_ID_ADD);
 	lp->chip_type = rev_type &~ REVISON_BITS;
@@ -460,11 +776,16 @@
 
 	/* Check the chip type and revision in order to set the correct send command
 	CS8920 revision C and CS8900 revision F can use the faster send. */
+#if !defined( CONFIG_UCSIMM ) && !defined(CONFIG_UCDIMM) && !defined(CONFIG_DRAGEN2) && !defined(CONFIG_DRAGONIXVZ) && !defined(CONFIG_CWVZ328)
 	lp->send_cmd = TX_AFTER_381;
 	if (lp->chip_type == CS8900 && lp->chip_revision >= 'F')
 		lp->send_cmd = TX_NOW;
 	if (lp->chip_type != CS8900 && lp->chip_revision >= 'C')
 		lp->send_cmd = TX_NOW;
+#else
+	/* uCsimm has trouble keeping up */
+	lp->send_cmd = TX_AFTER_ALL;
+#endif
 
 	if (net_debug  &&  version_printed++ == 0)
 		printk(version);
@@ -477,7 +798,8 @@
 	       dev->base_addr);
 
 	reset_chip(dev);
-   
+
+#ifndef NO_EPROM
         /* Here we read the current configuration of the chip. If there
 	   is no Extended EEPROM then the idea is to not disturb the chip
 	   configuration, it should have been correctly setup by automatic
@@ -517,8 +839,12 @@
 	} else
 #endif
 
+#if defined(CONFIG_ARCH_EDB7312)
+	if (1) { /* boot rom set up chip correctly */
+#else
         if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) == 
 	      (EEPROM_OK|EEPROM_PRESENT)) {
+#endif
 	        /* Load the MAC. */
 		for (i=0; i < ETH_ALEN/2; i++) {
 	                unsigned int Addr;
@@ -564,7 +890,12 @@
 		if (lp->chip_type == CS8900) 
 			lp->isa_config = readreg(dev, PP_CS8900_ISAINT) & INT_NO_MASK;
 	   
+#if defined(CONFIG_ARCH_EDB7312)
+		lp->isa_config = 0;
+		printk( "[bootrom] ");
+#else
 		printk( "[Cirrus EEPROM] ");
+#endif
 	}
 
         printk("\n");
@@ -608,6 +939,13 @@
 			printk(KERN_DEBUG "%s: new adapter_cnf: 0x%x\n",
 				dev->name, lp->adapter_cnf);
         }
+#else
+	get_dev_addr(dev);
+	printk("\n");
+    /* Fill this in, we don't have an EEPROM */
+    lp->adapter_cnf = A_CNF_10B_T | A_CNF_MEDIA_10B_T;
+    lp->auto_neg_cnf = EE_AUTO_NEG_ENABLE | IMM_BIT;
+#endif /* NO_EPROM */
 
         /* allow them to force multiple transceivers.  If they force multiple, autosense */
         {
@@ -639,6 +977,7 @@
 
 	lp->irq_map = 0xffff;
 
+#ifndef CONFIG_UCLINUX
 	/* If this is a CS8900 then no pnp soft */
 	if (lp->chip_type != CS8900 &&
 	    /* Check if the ISA IRQ has been set  */
@@ -669,6 +1008,7 @@
 		if (!dev->irq)
 			dev->irq = i;
 	}
+#endif /* CONFIG_UCLINUX */
 
 	printk(" IRQ %d", dev->irq);
 
@@ -705,6 +1045,11 @@
 	printk("\n");
 	if (net_debug)
 		printk("cs89x0_probe1() successful\n");
+#if defined (CONFIG_PM)
+	cs89x0_pm = pm_register(PM_SYS_DEV, PM_SYS_COM, cs89x0_pm_callback);
+	if (cs89x0_pm)
+		cs89x0_pm->data = dev;
+#endif
 	return 0;
 out2:
 	release_region(ioaddr & ~3, NETCARD_IO_EXTENT);
@@ -880,6 +1225,9 @@
 
 	writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET);
 
+#ifdef CONFIG_ARCH_TA7S
+	a7hal_lancs8900_reset( 0 );
+#endif
 	/* wait 30 ms */
 	current->state = TASK_INTERRUPTIBLE;
 	schedule_timeout(30*HZ/1000);
@@ -894,6 +1242,12 @@
 		outb((dev->mem_start >> 16) & 0xff, ioaddr + DATA_PORT);
 		outb((dev->mem_start >> 8) & 0xff,   ioaddr + DATA_PORT + 1);
 	}
+#ifdef CONFIG_EXCALIBUR
+/* This is a hack that seems to be necessary for the 2.0 nios core
+ * that must be done after power up resets.
+ */
+	*(char *)dev->base_addr = 0;
+#endif
 	/* Wait until the chip is reset */
 	reset_start_time = jiffies;
 	while( (readreg(dev, PP_SelfST) & INIT_DONE) == 0 && jiffies - reset_start_time < 2)
@@ -907,7 +1261,7 @@
 	struct net_local *lp = (struct net_local *)dev->priv;
 	unsigned int selfcontrol;
 	int timenow = jiffies;
-	/* control the DC to DC convertor in the SelfControl register.  
+	/* control the DC to DC convertor in the SelfControl register.
 	   Note: This is hooked up to a general purpose pin, might not
 	   always be a DC to DC convertor. */
 
@@ -1080,6 +1434,7 @@
 static void
 write_irq(struct net_device *dev, int chip_type, int irq)
 {
+#ifndef CONFIG_UCLINUX
 	int i;
 
 	if (chip_type == CS8900) {
@@ -1094,6 +1449,9 @@
 	} else {
 		writereg(dev, PP_CS8920_ISAINT, irq);
 	}
+#else
+	writereg(dev, PP_CS8900_ISAINT, 0);
+#endif
 }
 
 /* Open/initialize the board.  This is called (in the current kernel)
@@ -1114,6 +1472,7 @@
 	int i;
 	int ret;
 
+#if !defined(CONFIG_UCLINUX)
 #ifndef CONFIG_SH_HICOSH4 /* uses irq#1, so this wont work */
 	if (dev->irq < 2) {
 		/* Allow interrupts to be generated by the chip */
@@ -1166,6 +1525,34 @@
 		}
 	}
 
+#else /* CONFIG_UCLINUX */
+
+	writereg(dev, PP_BusCTL, 0);    /* Disable Interrupts. */
+	write_irq(dev, lp->chip_type, dev->irq);
+#if defined( CONFIG_M68EZ328 ) || defined (CONFIG_M68VZ328)
+  #if  defined (CONFIG_DRAGONIXVZ)
+    *(volatile unsigned short *)0xfffff302 &= ~0x1100; /* -ve pol, level sensitive irq */
+    ret = request_irq(dev->irq, &net_interrupt, IRQ_FLG_STD, dev->name, dev);
+  #else
+
+    #if !defined(CONFIG_DRAGEN2)
+	*(volatile unsigned short *)0xfffff302 |= 0x0080; /* +ve pol irq */
+    #endif
+	ret = request_irq(dev->irq, &net_interrupt, IRQ_FLG_STD, dev->name, dev);
+  #endif
+
+#else
+	ret = request_irq(dev->irq, &net_interrupt, SA_INTERRUPT, dev->name, dev);
+#endif
+
+	if (ret) {
+		if (net_debug)
+			printk(KERN_DEBUG "cs89x0: request_irq(%d) failed\n", dev->irq);
+		goto bad_out;
+	}
+	writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ );
+#endif /* CONFIG_UCLINUX */
+
 #if ALLOW_DMA
 	if (lp->use_dma) {
 		if (lp->isa_config & ANY_ISA_DMA) {
@@ -1333,6 +1720,9 @@
         netif_start_queue(dev);
 	if (net_debug > 1)
 		printk("cs89x0: net_open() succeeded\n");
+#ifdef CONFIG_PM
+	cs89x0_in_use = 1;
+#endif
 	return 0;
 bad_out:
 	return ret;
@@ -1384,6 +1774,13 @@
 	outsw(dev->base_addr + TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
 	spin_unlock_irq(&lp->lock);
 	dev->trans_start = jiffies;
+	/*
+	 * This is the estimate of how many bytes have been sent,
+	 * we don't realy know if the packet was sent 'till we get
+	 * the TX interrupt with a status of OK. However the interrupt
+	 * routine does not know the length of the packet that was sent.
+	 */
+	lp->stats.tx_bytes += skb->len;
 	dev_kfree_skb (skb);
 
 	/*
@@ -1402,13 +1799,13 @@
 
 /* The typical workload of the driver:
    Handle the network interface interrupts. */
-   
 static void net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
+		
 	struct net_device *dev = dev_id;
 	struct net_local *lp;
 	int ioaddr, status;
- 
+
 	ioaddr = dev->base_addr;
 	lp = (struct net_local *)dev->priv;
 
@@ -1453,8 +1850,14 @@
 			if (status & TX_UNDERRUN) {
 				if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
                                 lp->send_underrun++;
+#if !defined( CONFIG_UCSIMM ) && !defined(CONFIG_UCDIMM) && !defined(CONFIG_DRAGEN2) && !defined(DRAGONIXVZ) && !defined(CWVZ328)
+//vic - FIXME - is this ok for excalibur ?
                                 if (lp->send_underrun == 3) lp->send_cmd = TX_AFTER_381;
                                 else if (lp->send_underrun == 6) lp->send_cmd = TX_AFTER_ALL;
+#else
+								/* uCsimm has trouble keeping up */
+                                lp->send_cmd = TX_AFTER_ALL;
+#endif
 				/* transmit cycle is done, although
 				   frame wasn't transmitted - this
 				   avoids having to wait for the upper
@@ -1580,6 +1983,10 @@
 	}
 #endif
 
+#if defined(CONFIG_PM)
+	cs89x0_in_use = 0;
+#endif
+
 	/* Update the statistics here. */
 	return 0;
 }
@@ -1653,6 +2060,41 @@
 	return 0;
 }
 
+
+
+#ifdef CONFIG_UCLINUX
+static void get_dev_addr(struct net_device *dev)
+{
+#if defined( CONFIG_UCSIMM ) || defined(CONFIG_UCDIMM) || defined(CONFIG_EXCALIBUR)
+	extern unsigned char *cs8900a_hwaddr;
+	memcpy(dev->dev_addr, cs8900a_hwaddr, 6);
+#endif
+#ifdef CONFIG_ARCH_DM270
+	dev->dev_addr[0] = 0x00;
+	dev->dev_addr[1] = 0x10;
+	dev->dev_addr[2] = 0x8b;
+	dev->dev_addr[3] = 0xf1;
+	dev->dev_addr[4] = 0xda;
+	dev->dev_addr[5] = 0x01;
+#endif
+#if defined CONFIG_EZ328LCD  || defined CONFIG_CWVZ328
+	dev->dev_addr[0] = 0x00;
+	dev->dev_addr[1] = 0x10;
+	dev->dev_addr[2] = 0x8b;
+	dev->dev_addr[3] = 0xf1;
+	dev->dev_addr[4] = 0xda;
+	dev->dev_addr[5] = 0x01;
+#endif
+#ifdef CONFIG_DRAGONIXVZ
+	extern unsigned char cs8900a_hwaddr1[6];
+	memcpy(dev->dev_addr, cs8900a_hwaddr1, 6);
+        /* FIXME add second controller support here */
+#endif
+}
+#endif
+
+
+
 #ifdef MODULE
 
 static struct net_device dev_cs89x0 = {
diff -urN linux-2.4.29/drivers/net/cs89x0.h linux-2.4.29-uc1/drivers/net/cs89x0.h
--- linux-2.4.29/drivers/net/cs89x0.h	2002-11-28 23:53:13.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/cs89x0.h	2005-06-14 02:12:14.000000000 +0100
@@ -326,14 +326,35 @@
 
 #define RX_FRAME_PORT	0x0000
 #define TX_FRAME_PORT RX_FRAME_PORT
+
+#ifdef CONFIG_EXCALIBUR
+#define TX_CMD_PORT	0x0008
+#elif defined(CONFIG_ARCH_TA7S)
+#define TX_CMD_PORT	(0x0004*2)
+#else
 #define TX_CMD_PORT	0x0004
+#endif
+
 #define TX_NOW		0x0000       /*  Tx packet after   5 bytes copied */
 #define TX_AFTER_381	0x0040       /*  Tx packet after 381 bytes copied */
 #define TX_AFTER_ALL	0x00c0       /*  Tx packet after all bytes copied */
+
+#ifdef CONFIG_EXCALIBUR
+#define TX_LEN_PORT	0x000C
+#define ISQ_PORT	0x0010
+#define ADD_PORT	0x0014
+#define DATA_PORT	0x0018
+#elif defined(CONFIG_ARCH_TA7S)
+#define ADD_PORT	(0x000A*2)
+#define DATA_PORT	(0x000C*2)
+#define TX_LEN_PORT	(0x0006*2)
+#define ISQ_PORT	(0x0008*2)
+#else
 #define TX_LEN_PORT	0x0006
 #define ISQ_PORT	0x0008
 #define ADD_PORT	0x000A
 #define DATA_PORT	0x000C
+#endif
 
 #define EEPROM_WRITE_EN		0x00F0
 #define EEPROM_WRITE_DIS	0x0000
@@ -437,8 +458,10 @@
 #define IRQ_MAP_EEPROM_DATA 0x0046 /*  Offset into eeprom for the IRQ map */
 #define IRQ_MAP_LEN 0x0004 /*  No of bytes to read for the IRQ map */
 #define PNP_IRQ_FRMT 0x0022 /*  PNP small item IRQ format */
-#ifdef CONFIG_SH_HICOSH4
+#if defined(CONFIG_SH_HICOSH4)
 #define CS8900_IRQ_MAP 0x0002 /* HiCO-SH4 board has its IRQ on #1 */
+#elif defined(CONFIG_ARCH_EDB7312)
+#define CS8900_IRQ_MAP 0x0080 /*  EDB7312 board has it's IRQ on */
 #else
 #define CS8900_IRQ_MAP 0x1c20 /*  This IRQ map is fixed */
 #endif
diff -urN linux-2.4.29/drivers/net/ep93xx_eth.c linux-2.4.29-uc1/drivers/net/ep93xx_eth.c
--- linux-2.4.29/drivers/net/ep93xx_eth.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/ep93xx_eth.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,1840 @@
+/*----------------------------------------------------------------------------
+ * ep93xx_eth.c
+ *  Ethernet Device Driver for Cirrus Logic EP93xx.
+ *
+ * Copyright (C) 2003 by Cirrus Logic www.cirrus.com 
+ * This software may be used and distributed according to the terms
+ * of the GNU Public License.
+ *
+ *   This driver was written based on skeleton.c by Donald Becker and
+ * smc9194.c by Erik Stahlman.  
+ *
+ * Theory of Operation
+ * Driver Configuration
+ *  - Getting MAC address from system
+ *     To setup identical MAC address for each target board, driver need
+ *      to get a MAC address from system.  Normally, system has a Serial 
+ *      EEPROM or other media to store individual MAC address when 
+ *      manufacturing.
+ *      The macro GET_MAC_ADDR is prepared to get the MAC address from 
+ *      system and one should supply a routine for this purpose.
+ * Driver Initialization
+ * DMA Operation
+ * Cache Coherence
+ *
+ * History:
+ * 07/19/01 0.1  Sungwook Kim  initial release
+ * 10/16/01 0.2  Sungwook Kim  add workaround for ignorance of Tx request while sending frame
+ *                             add some error stuations handling
+ *
+ * 03/25/03 Melody Lee Modified for EP93xx
+ *--------------------------------------------------------------------------*/
+
+static const char  *version=
+    "ep93xx_eth.c: V1.0 09/04/2003 Cirrus Logic\n";
+
+
+#include <linux/module.h>
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/ssp.h>
+
+#include "ep93xx_eth.h"
+
+
+/*----------------------------------------------------------------------------
+ * The name of the card.
+ * It is used for messages and in the requests for io regions, irqs and ...
+ * This device is not in a card but I used same name in skeleton.c file.
+ *--------------------------------------------------------------------------*/
+#define  cardname  "ep93xx_ethernet"
+
+
+/*----------------------------------------------------------------------------
+ * Macro to get MAC address from system
+ *
+ * Parameters:
+ *  - pD  : a pointer to the net device information, struct net_device.
+ *          one can get base address of device from pD->base_addr,
+ *          device instance ID (0 for 1st and so on) from *((int*)pD->priv).
+ *  - pMac: a pointer to a 6 bytes length buffer to return device MAC address.
+ *          this buffer will be initialized with default_mac[] value before 
+ *          calling.
+ * Return: none
+ *--------------------------------------------------------------------------*/
+#define GET_MAC_ADDR(pD, pMac)						\
+	{								\
+		unsigned int uiTemp;					\
+		int SSP_Handle;						\
+									\
+		SSP_Handle = SSPDriver->Open( SERIAL_FLASH, 0 );	\
+		if (SSP_Handle != -1) {					\
+			SSPDriver->Read( SSP_Handle, 0x1000, &uiTemp );	\
+			if (uiTemp == 0x43414d45) {			\
+				SSPDriver->Read( SSP_Handle, 0x1004,	\
+						 &uiTemp );		\
+				pMac[0] = uiTemp & 255;			\
+				pMac[1] = (uiTemp >> 8) & 255;		\
+				pMac[2] = (uiTemp >> 16) & 255;		\
+				pMac[3] = uiTemp >> 24;			\
+				SSPDriver->Read( SSP_Handle, 0x1008,	\
+						 &uiTemp );		\
+				pMac[4] = uiTemp & 255;			\
+				pMac[5] = (uiTemp >> 8) & 255;		\
+			}						\
+			SSPDriver->Close( SSP_Handle );			\
+		}							\
+	}
+
+
+
+/****  default MAC address if GET_MAC_ADDR does not override  *************/
+static const U8  default_mac[6] = {0x00, 0xba, 0xd0, 0x0b, 0xad, 0x00};
+
+
+/*----------------------------------------------------------------------------
+ * A List of default device port configuration for auto probing.
+ * At this time, the CPU has only one Ethernet device,
+ * but better to support multiple device configuration.
+ * Keep in mind that the array must end in zero.
+ *--------------------------------------------------------------------------*/
+
+/* We get the MAC_BASE from include/asm-arm/arch-ep93xx/regmap.h */
+static struct {
+    unsigned int  baseAddr;   /*base address, (0:end mark)*/
+    int           irq;        /*IRQ number, (0:auto detect)*/
+}  portList[] __initdata = { 
+    {MAC_BASE, 39},
+    {0/*end mark*/, 0}
+};
+
+
+
+/*----------------------------------------------------------------------------
+ * Some definitions belong to the operation of this driver.
+ * You should understand how it affect to driver before any modification.
+ *--------------------------------------------------------------------------*/
+
+/****  Interrupt Sources in Use  *******************************************/
+/*#define  Default_IntSrc  (IntEn_RxMIE|IntEn_RxSQIE|IntEn_TxLEIE|IntEn_TIE|IntEn_TxSQIE|IntEn_RxEOFIE|IntEn_RxEOBIE|IntEn_RxHDRIE)
+*/
+#define  Default_IntSrc  (IntEn_TxSQIE|IntEn_RxEOFIE|IntEn_RxEOBIE|IntEn_RxHDRIE)
+
+/****  Length of Device Queue in number of entries
+       (must be less than or equal to 255)  ********************************/
+#define  LEN_QueRxDesc  64             /*length of Rx Descriptor Queue (4 or bigger) Must be power of 2.*/
+#define  LEN_QueRxSts   LEN_QueRxDesc  /*length of Rx Status Queue*/
+#define  LEN_QueTxDesc  8              /*length of Tx Descriptor Queue (4 or bigger) Must be power of 2.*/
+#define  LEN_QueTxSts   LEN_QueTxDesc  /*length of Tx Status Queue*/
+
+/****  Tx Queue fill-up level control  *************************************/
+#define  LVL_TxStop    LEN_QueTxDesc - 2    /*level to ask the stack to stop Tx*/
+#define  LVL_TxResume  2   /*level to ask the stack to resume Tx*/
+
+/****  Rx Buffer length in bytes  ******************************************/
+#define  LEN_RxBuf  (1518+2+16)  /*length of Rx buffer, must be 4-byte aligned*/
+#define  LEN_TxBuf   LEN_RxBuf
+
+
+/*----------------------------------------------------------------------------
+ * MACRO for ease
+ *--------------------------------------------------------------------------*/
+
+#define  Align32(a)  (((unsigned int)(a)+3)&~0x03)  /*32bit address alignment*/
+#define  IdxNext(idxCur,len)  (((idxCur)+1)%(len))  /*calc next array index number*/
+
+
+
+/****  malloc/free routine for DMA buffer  **********************************/
+ /*use non-cached DMA buffer*/
+#define  MALLOC_DMA(size, pPhyAddr)  consistent_alloc(GFP_KERNEL|GFP_DMA, (size), (dma_addr_t*)(pPhyAddr))
+#define  FREE_DMA(vaddr)            consistent_free(vaddr)
+extern void  cpu_arm920_dcache_clean_range(U32 va_bgn,U32 va_end);
+#define  dma_cache_wback(vaddr,size)  cpu_arm920_dcache_clean_range((U32)(vaddr),(U32)(vaddr)+(size)-1)
+
+
+/*----------------------------------------------------------------------------
+ * DEBUGGING LEVELS
+ *
+ * 0 for normal operation
+ * 1 for slightly more details
+ * >2 for various levels of increasingly useless information
+ *    2 for interrupt tracking, status flags
+ *    3 for packet dumps, etc.
+ *--------------------------------------------------------------------------*/
+//#define  _DBG  3
+
+#if (_DBG > 2 )
+#define PRINTK3(x) printk x
+#else
+#define PRINTK3(x)
+#endif
+
+#if _DBG > 1
+#define PRINTK2(x) printk x
+#else
+#define PRINTK2(x)
+#endif
+
+#if _DBG > 0
+#define PRINTK1(x) printk x
+#else
+#define PRINTK1(x)
+#endif
+
+#ifdef _DBG
+#define PRINTK(x) printk x
+#else
+#define PRINTK(x)
+#endif
+
+#define  _PRTK_ENTRY      PRINTK2   /*to trace function entries*/
+#define  _PRTK_SWERR      PRINTK    /*logical S/W error*/
+#define  _PRTK_SYSFAIL    PRINTK    /*system service failure*/
+#define  _PRTK_HWFAIL     PRINTK    /*H/W operation failure message*/
+#define  _PRTK_WARN       PRINTK1   /*warning information*/
+#define  _PRTK_INFO       PRINTK2   /*general information*/
+#define  _PRTK_ENTRY_ISR  PRINTK3   /*to trace function entries belong to ISR*/
+#define  _PRTK_WARN_ISR   PRINTK1   /*warning informations from ISR*/
+#define  _PRTK_INFO_ISR   PRINTK3   /*general informations from ISR*/
+#define  _PRTK_           PRINTK    /*for temporary print out*/
+
+#if 0
+# define  _PRTK_DUMP       PRINTK1   /*to dump large amount of debug info*/
+#endif
+
+
+
+/*----------------------------------------------------------------------------
+ * Custom Data Structures
+ *--------------------------------------------------------------------------*/
+
+/****  the information about the buffer passed to device.
+       there are matching bufferDescriptor informations 
+       for each Tx/Rx Descriptor Queue entry to trace 
+       the buffer within those queues.  ************************************/
+typedef  struct bufferDescriptor  {
+    void  *vaddr;                /*virtual address representing the buffer passed to device*/
+    int(*pFreeRtn)(void *pBuf);  /*free routine*/
+}  bufferDescriptor;
+
+
+/****  device privite informations
+       pointed by struct net_device::priv  *********************************/
+typedef  struct ep9213Eth_info  {
+    /****  static device informations  **********************************/
+    struct {
+        int                 id;            /*device instance ID (0 for 1st and so on)
+                                             must be first element of this structure*/
+        receiveDescriptor   *pQueRxDesc;   /*pointer to Rx Descriptor Queue*/
+        receiveStatus       *pQueRxSts;    /*pointer to Rx Status Queue*/
+        transmitDescriptor  *pQueTxDesc;   /*pointer to Tx Descriptor Queue*/
+        transmitStatus      *pQueTxSts;    /*pointer to Tx Status Queue*/
+        unsigned char       *pRxBuf;       /*base of Rx Buffer pool*/
+        unsigned char       *pTxBuf;       /*base of Tx Buffer pool*/
+        unsigned long       phyQueueBase;  /*physical address of device queues*/
+        unsigned long       phyQueRxDesc,  /*physical address of Rx Descriptor Queue*/
+                            phyQueRxSts,   /*physical address of Rx Status Queue*/
+                            phyQueTxDesc,  /*physical address of Tx Descriptor Queue*/
+                            phyQueTxSts,   /*physical address of Tx Status Queue*/
+                            phyRxBuf,      /*physical address of Rx Buffer pool*/
+                            phyTxBuf;      /*physical address of Tx Buffer pool*/
+        bufferDescriptor    *pRxBufDesc,   /*info of Rx Buffers*/
+                            *pTxBufDesc;   /*info of Tx Buffers*/
+        int                 miiIdPhy;      /*MII Bus ID of Ethernet PHY*/
+    }  s;
+    /****  dynamic information, subject to clear when device open  ******/
+    struct {
+        struct net_device_stats  stats;  /*statistic data*/
+        int  idxQueRxDesc,       /*next processing index of device queues*/
+             idxQueRxSts,
+             idxQueTxDescHead,
+             idxQueTxDescTail,
+             idxQueTxSts;
+        int  txStopped;          /*flag for Tx condition*/
+    }  d;
+}  ep9213Eth_info;
+
+
+
+/*----------------------------------------------------------------------------
+ * Global Variables
+ *--------------------------------------------------------------------------*/
+static int  numOfInstance = 0;  /*total number of device instance, 0 means the 1st instance.*/
+
+//static struct sk_buff gTxSkb;
+//static char gTxBuff[LEN_TxBuf];
+
+static char gTxDataBuff[LEN_QueTxDesc][LEN_TxBuf];
+
+// To know if PHY auto-negotiation has done?
+static int gPhyAutoNegoDone=0;
+
+/*----------------------------------------------------------------------------
+ * Function Proto-types
+ *--------------------------------------------------------------------------*/
+int __init  ep93xxEth_probe(struct net_device *pD);
+static int  ep9213Eth_open(struct net_device *pD);
+static int  ep9213Eth_close(struct net_device *pD);
+static int  ep9213Eth_hardStartXmit(struct sk_buff *pSkb, struct net_device *pD);
+static void  ep9213Eth_txTimeout(struct net_device *pD);
+static void  ep9213Eth_setMulticastList(struct net_device *pD);
+static struct net_device_stats*  ep9213Eth_getStats(struct net_device *pD);
+
+static void  ep9213Eth_isr(int irq, void *pDev, struct pt_regs *pRegs);
+
+
+
+/*============================================================================
+ *
+ * Internal Routines
+ *
+ *==========================================================================*/
+
+/*****************************************************************************
+* free_skb()
+*****************************************************************************/
+static int  free_skb(void *pSkb)
+{
+    dev_kfree_skb_irq((struct sk_buff*)pSkb);
+    return 0;
+}/*free_skb()*/
+
+
+
+/*****************************************************************************
+* waitOnReg32()
+*****************************************************************************/
+static int  waitOnReg32(struct net_device *pD, int reg,
+                        unsigned long mask, unsigned long expect, int tout)
+{
+    int  i;
+    int  dt;
+
+/*    _PRTK_ENTRY(("waitOnReg32(pD:0x%x,reg:0x%x,mask:0x%x,expect:0x%x,tout:%d)\n",
+                 pD,reg,mask,expect,tout));
+*/
+
+    for(i=0;i<10000;) {
+        dt=RegRd32(reg);
+        dt=(dt^expect)&mask;
+        if(0==dt)  break;
+        if(tout)  i++;
+    }/*for*/
+    return dt;
+}/*waitOnReg32()*/
+
+
+
+#define  phy_wr(reg,dt)  _phy_write(pD, ((ep9213Eth_info*)pD->priv)->s.miiIdPhy, (reg), (dt))
+#define  phy_rd(reg)     _phy_read(pD, ((ep9213Eth_info*)pD->priv)->s.miiIdPhy, (reg))
+#define  phy_waitRdy()  waitOnReg32(pD, REG_MIISts,MIISts_Busy, ~MIISts_Busy, 1)
+
+/*****************************************************************************
+* _phy_write()
+*****************************************************************************/
+static void  _phy_write(struct net_device *pD,int idPhy,int reg,U16 dt) {
+
+/*    _PRTK_ENTRY(("_phy_write(pD:0x%p,idPhy:%d,reg:0x%x,dt:0x%x)\n",pD,idPhy,reg,dt));*/
+
+    phy_waitRdy();
+    RegWr32(REG_MIIData,dt);
+    RegWr32(REG_MIICmd,MIICmd_OP_WR|((idPhy&0x1f)<<5)|((reg&0x1f)<<0));
+}/*_phy_write()*/
+
+
+
+/*****************************************************************************
+* _phy_read()
+*****************************************************************************/
+static U16  _phy_read(struct net_device *pD,int idPhy,int reg) {
+    U16  dt;
+
+/*    _PRTK_ENTRY(("_phy_read(pD:0x%p,idPhy:%d,reg:0x%x)\n",pD,idPhy,reg)); */
+
+    phy_waitRdy();
+    RegWr32(REG_MIICmd,MIICmd_OP_RD|((idPhy&0x1f)<<5)|((reg&0x1f)<<0));
+    phy_waitRdy();
+    dt=(unsigned short)RegRd32(REG_MIIData);
+
+/*    _PRTK_INFO(("_phy_read(): read 0x%x\n",dt));*/
+
+    return dt;
+}/*_phy_read()*/
+
+
+
+#ifndef _PRTK_DUMP
+#define _dbg_phy_dumpReg(pD)
+#else
+/*****************************************************************************
+* _dbg_phy_dumpReg()
+*****************************************************************************/
+static void  _dbg_phy_dumpReg(struct net_device *pD) {
+    _PRTK_DUMP(("Dumping registers of Ethernet PHY\n"));
+    _PRTK_DUMP((" pD:0x%p, Eth Base Address:0x%x\n", pD, (unsigned int)pD->base_addr));
+
+    _PRTK_DUMP((" 0-3:0x%04x 0x%04x  0x%04x 0x%04x\n",
+                phy_rd(0),phy_rd(1),phy_rd(2),phy_rd(3)));
+    _PRTK_DUMP((" 4-6:0x%04x 0x%04x  0x%04x\n",
+                phy_rd(4),phy_rd(5),phy_rd(6)));
+    _PRTK_DUMP((" 16-19:0x%04x 0x%04x  0x%04x  0x%04x\n",
+                phy_rd(16),phy_rd(17),phy_rd(18),phy_rd(19)));
+    _PRTK_DUMP((" 20:0x%04x\n",phy_rd(20)));
+}/*_dbg_phy_dumpReg()*/
+#endif/*ifndef _PRTK_DUMP else*/
+
+
+/*****************************************************************************
+* phy_autoNegotiation()
+*****************************************************************************/
+static int  phy_autoNegotiation(struct net_device *pD) {
+   U16 val;
+   U16 oldVal;
+   U16 count=0;
+
+   phy_wr(4, 0x01e1);  /*Set 802.3, 100M/10M Full/Half ability*/
+   phy_wr(0,(1<<12)|(1<<9)); /* enable auto negotiation*/
+   while (1) {
+     val = phy_rd(1); /* read BM status Reg*/
+     if ( val&0x0020) /* if Auto_Neg_complete?*/
+     {
+       break;
+     }
+     else {
+       if (count >= 3)
+       {
+         return -1;
+       }
+       mdelay(1000);//delay 1 second.
+       count++;
+     }
+   }
+
+   //CS8952 PHY needs the delay.  Otherwise it won't send the 1st frame.
+   mdelay(1000);//delay 1 second.
+
+   val = phy_rd(5); /* read ANLPAR Reg*/
+   if ( val&0x0140) /* if 100M_FDX or 10M_FDX?*/
+   {
+     oldVal=RegRd16(REG_TestCTL);
+     /*Enable MAC's Full Duplex mode.*/
+     RegWr16(REG_TestCTL, oldVal|TestCTL_MFDX); 
+     //printk("ep93xx_eth(): set MAC to Full Duplex mode\n");
+   } else {
+     //printk("ep93xx_eth(): set MAC to Half Duplex mode\n");
+   }
+   // TODO PJJ-added to get rid of _dbg_phy_dumpReg be sure returning zero is ok.
+    gPhyAutoNegoDone=1;
+
+   return(0);
+}
+
+/*****************************************************************************
+* phy_init()
+*****************************************************************************/
+static int  phy_init(struct net_device *pD) {
+    U32 oldVal;
+    int status = -1;
+    U16 val;
+
+    _PRTK_ENTRY(("phy_init(pD:0x%x)\n", (unsigned int)pD));
+
+    oldVal = RegRd32(REG_SelfCTL);
+    RegWr32(REG_SelfCTL,0x0e00);/*Set MDC clock to be divided by 8
+                               and disable PreambleSuppress bit*/
+
+    val = phy_rd(1); /* read BM status Reg; Link Status Bit remains cleared
+                        until the Reg is read. */
+    val = phy_rd(1); /* read BMStaReg again to get the current link status */
+    if ( val&0x0004) /* if Link Status == established? */
+    {
+      status = phy_autoNegotiation(pD);
+    }
+
+    RegWr32(REG_SelfCTL, oldVal);/*restore the old value */
+
+    return status;
+}/*phy_init()*/
+
+/*****************************************************************************
+* phy_reset()
+*****************************************************************************/
+#if 0
+static int  phy_reset(struct net_device *pD) {
+    int  i;
+
+    _PRTK_ENTRY(("phy_reset(pD:0x%p)\n",pD));
+
+    phy_wr(0,1<<15);  /*reset PHY*/
+    for(i=0;i<1000;i++)  if(0==((1<<15)&phy_rd(0)))  break;
+    if(0!=((1<<15)&phy_rd(0))) {
+        _PRTK_HWFAIL(("phy_reset(): PHY reset does not self-clear\n"));
+        return -1;
+    }/*if*/
+
+    phy_wr(19,0x00);  /*@ override default value from H/W pin that is not correct*/
+    phy_wr(4,(1<<8)|(1<<7)|(1<<6)|(1<<5)|(0x01<<0));  /*advertise 100/10M full/half*/
+    phy_wr(0,(1<<12)|(1<<9));  /*enable auto negotiation*/
+
+    return 0;
+}/*phy_reset()*/
+#endif
+
+
+#ifndef _PRTK_DUMP
+# define _dbg_ep9312Eth_dumpQueues(pD)
+#else
+/*****************************************************************************
+* _dbg_ep9312Eth_dumpQueues()
+*****************************************************************************/
+static void  _dbg_ep9312Eth_dumpQueues(struct net_device *pD) {
+//    struct ep9213Eth_info  *pP=pD->priv;
+    int  i;
+
+    _PRTK_DUMP(("Dumping Descriptor/Status Queues\n"));
+    _PRTK_DUMP((" pD:0x%p, Base Address:0x%x\n",pD,(unsigned int)pD->base_addr));
+
+    _PRTK_DUMP((" o Rx Status Queue: at 0x%p, %d entries\n",pP->s.pQueRxSts,LEN_QueRxSts));
+    for(i=0;i<LEN_QueRxSts;i++)
+        _PRTK_DUMP(("  - %2d: 0x%08x 0x%08x \n",
+                    i,(unsigned int)pP->s.pQueRxSts[i].w.e0, (unsigned int)pP->s.pQueRxSts[i].w.e1));
+
+    _PRTK_DUMP((" o Rx Descriptor Queue: at 0x%p, %d entries\n",pP->s.pQueRxDesc,LEN_QueRxDesc));
+    for(i=0;i<LEN_QueRxDesc;i++)
+        _PRTK_DUMP(("  - %2d: 0x%08x 0x%08x \n",
+                    i, (unsigned int)pP->s.pQueRxDesc[i].w.e0, (unsigned int)pP->s.pQueRxDesc[i].w.e1));
+
+    _PRTK_DUMP((" o Tx Status Queue: at 0x%p, %d entries\n",pP->s.pQueTxSts,LEN_QueTxSts));
+    for(i=0;i<LEN_QueTxSts;i++)
+        _PRTK_DUMP(("  - %2d: 0x%08x \n",i,(unsigned int)pP->s.pQueTxSts[i].w.e0));
+
+    _PRTK_DUMP((" o Tx Descriptor Queue: at 0x%p, %d entries\n",pP->s.pQueTxDesc,LEN_QueTxDesc));
+    for(i=0;i<LEN_QueTxDesc;i++)
+        _PRTK_DUMP(("  - %2d: 0x%08x 0x%08x \n",
+                    i, (unsigned int)pP->s.pQueTxDesc[i].w.e0, (unsigned int)pP->s.pQueTxDesc[i].w.e1));
+}/*_dbg_ep9312Eth_dumpQueues()*/
+#endif/*ifndef _PRTK_DUMP else*/
+
+
+/*****************************************************************************
+* devQue_start()
+*
+  make descriptor queues active
+  allocate queue entries if needed
+  and set device registers up to make it operational
+  assume device has been initialized
+* 
+*****************************************************************************/
+static int  devQue_start(struct net_device *pD) {
+    int  err;
+    struct ep9213Eth_info  *pP=pD->priv;
+    int  i;
+    void  *pBuf;
+    U32  phyA;
+
+    _PRTK_ENTRY(("devQue_start(pD:0x%p)\n",pD));
+
+    /*turn off device bus mastering*/
+    RegWr32(REG_BMCtl,BMCtl_RxDis|BMCtl_TxDis|RegRd32(REG_BMCtl));
+    err=waitOnReg32(pD,REG_BMSts,BMSts_TxAct,~BMSts_TxAct,1);
+    err|=waitOnReg32(pD,REG_BMSts,BMSts_RxAct,~BMSts_RxAct,1);
+    if(err) {
+        _PRTK_HWFAIL(("devQue_start(): BM does not stop\n"));
+    }/*if*/
+
+    /*Tx Status Queue*/
+    memset(pP->s.pQueTxSts, 0, sizeof(pP->s.pQueTxSts[0])*LEN_QueTxSts);  /*clear status*/
+    pP->d.idxQueTxSts=0;  /*init index*/
+    RegWr32(REG_TxSBA,pP->s.phyQueTxSts);  /*base addr*/
+    RegWr32(REG_TxSCA,pP->s.phyQueTxSts);  /*current addr*/
+    RegWr16(REG_TxSBL,sizeof(pP->s.pQueTxSts[0])*LEN_QueTxSts);  /*base len*/
+    RegWr16(REG_TxSCL,sizeof(pP->s.pQueTxSts[0])*LEN_QueTxSts);  /*current len*/
+
+    /*Tx Descriptor Queue*/
+    memset(pP->s.pQueTxDesc, 0, sizeof(pP->s.pQueTxDesc[0])*LEN_QueTxDesc); /*clear descriptor*/
+    pP->d.idxQueTxDescHead=pP->d.idxQueTxDescTail=0;  /*init index*/
+    RegWr32(REG_TxDBA, pP->s.phyQueTxDesc);  /*base addr*/
+    RegWr32(REG_TxDCA, pP->s.phyQueTxDesc);  /*current addr*/
+    RegWr16(REG_TxDBL, sizeof(pP->s.pQueTxDesc[0])*LEN_QueTxDesc);  /*base len*/
+    RegWr16(REG_TxDCL, sizeof(pP->s.pQueTxDesc[0])*LEN_QueTxDesc);  /*current len*/
+
+    /*Rx Status Queue*/
+    memset(pP->s.pQueRxSts, 0, sizeof(pP->s.pQueRxSts[0])*LEN_QueRxSts);  /*clear status*/
+    pP->d.idxQueRxSts=0;  /*init index*/
+    RegWr32(REG_RxSBA, pP->s.phyQueRxSts);  /*base addr*/
+    RegWr32(REG_RxSCA, pP->s.phyQueRxSts);  /*current addr*/
+    RegWr16(REG_RxSBL, sizeof(pP->s.pQueRxSts[0])*LEN_QueRxSts);  /*base len*/
+    RegWr16(REG_RxSCL, sizeof(pP->s.pQueRxSts[0])*LEN_QueRxSts);  /*current len*/
+
+    /*Rx Descriptor Queue*/
+    memset(pP->s.pQueRxDesc, 0, sizeof(pP->s.pQueRxDesc[0])*LEN_QueRxDesc);  /*clear descriptor*/
+    phyA=pP->s.phyRxBuf;
+    for(i=0;i<LEN_QueRxDesc;i++) {
+        pP->s.pQueRxDesc[i].f.bi=i;  /*Rx Buffer Index*/
+        pP->s.pQueRxDesc[i].f.ba=phyA;  /*physical address of Rx Buf*/
+        pP->s.pQueRxDesc[i].f.bl=LEN_RxBuf;  /*Rx Buffer Length*/
+        phyA+=(LEN_RxBuf+3)&~0x03;
+    }/*for*/
+    pP->d.idxQueRxDesc=0;  /*init index*/
+    RegWr32(REG_RxDBA, pP->s.phyQueRxDesc);  /*base addr*/
+    RegWr32(REG_RxDCA, pP->s.phyQueRxDesc);  /*current addr*/
+    RegWr16(REG_RxDBL, sizeof(pP->s.pQueRxDesc[0])*LEN_QueRxDesc);  /*base len*/
+    RegWr16(REG_RxDCL, sizeof(pP->s.pQueRxDesc[0])*LEN_QueRxDesc);  /*current len*/
+
+    /*init Rx Buffer Descriptors*/
+    pBuf=pP->s.pRxBuf;
+    for(i=0;i<LEN_QueRxDesc;i++) {
+        pP->s.pRxBufDesc[i].vaddr=pBuf;  /*system address of buffer*/
+        pP->s.pRxBufDesc[i].pFreeRtn=0;  /*no freeing after use*/
+        pBuf+=(LEN_RxBuf+3)&~0x03;
+    }/*for*/
+
+    /*init Tx Buffer Descriptors*/
+    memset(pP->s.pTxBufDesc, 0x0, sizeof(*pP->s.pTxBufDesc)*LEN_QueTxDesc);
+	pP->s.pTxBuf = &gTxDataBuff[0][0];
+    for(i=0;i<LEN_QueTxDesc;i++) {
+        pP->s.pTxBufDesc[i].vaddr=&gTxDataBuff[i][0];  /*system address of buffer*/
+        pP->s.pTxBufDesc[i].pFreeRtn=0;  /*no freeing after use*/
+    }/*for*/
+
+    /*turn on device bus mastering*/
+    RegWr32(REG_BMCtl, BMCtl_TxEn|BMCtl_RxEn|RegRd32(REG_BMCtl));
+    err=waitOnReg32(pD, REG_BMSts,BMSts_TxAct|BMSts_TxAct,BMSts_TxAct|BMSts_TxAct,1);
+    if(err) {
+        _PRTK_HWFAIL(("devQue_start(): BM does not start\n"));
+    }/*if*/
+
+    /*Enqueue whole entries; this must be done after BM activation*/
+    RegWr32(REG_RxSEQ, LEN_QueRxSts);  /*Rx Status Queue*/
+    RegWr32(REG_RxDEQ, LEN_QueRxDesc);  /*Rx Descriptor queue*/
+
+    return 0;
+}/*devQue_start()*/
+
+
+
+/*****************************************************************************
+* devQue_init()
+  init device descriptor queues at system level
+  device access is not recommended at this point
+* 
+*****************************************************************************/
+static int  devQue_init(struct net_device *pD) {
+    struct ep9213Eth_info  *pP=pD->priv;
+    void  *pBuf;
+    int   size;
+
+    _PRTK_ENTRY(("devQue_init(pD:0x%x)\n", (unsigned int)pD));
+
+    /*verify device Tx/Rx Descriptor/Status Queue data size*/
+    if(8 != sizeof(receiveDescriptor)) {
+        _PRTK_SWERR(("devQue_init(): size of receiveDescriptor is not 8 bytes!!!\n"));
+        return -1;
+    }else if(8 != sizeof(receiveStatus)) {
+        _PRTK_SWERR(("devQue_init(): size of receiveStatus is not 8 bytes!!!\n"));
+        return -1;
+    }else if(8 != sizeof(transmitDescriptor)) {
+        _PRTK_SWERR(("devQue_init(): size of transmitDescriptor is not 8 bytes!!!\n"));
+        return -1;
+    }else if(4 != sizeof(transmitStatus)) {
+        _PRTK_SWERR(("devQue_init(): size of transmitStatus is not 4 bytes!!!\n"));
+        return -1;
+    }/*else*/
+
+    /*
+      allocate kernel memory for whole queues
+      best if non-cached memory block due to DMA access by the device
+      if CPU doesn't have bus snooping
+    */
+    size=sizeof(receiveDescriptor)*(LEN_QueRxDesc+1)+
+         sizeof(receiveStatus)*(LEN_QueRxSts+1)+
+         sizeof(transmitDescriptor)*(LEN_QueTxDesc+1)+
+         sizeof(transmitStatus)*(LEN_QueTxSts+1)+
+         sizeof(unsigned long)*4;
+
+    pBuf=MALLOC_DMA(size, &pP->s.phyQueueBase);  /*request memory allocation*/
+    if(!pBuf) {
+        _PRTK_SYSFAIL(("devQue_initAll(): fail to allocate memory for queues\n"));
+        return -1;
+    }/*if*/
+
+    /*
+      assign memory to each queue
+    */
+    pP->s.pQueRxDesc = (void*)Align32(pBuf);
+    pBuf = (char*)pBuf + sizeof(receiveDescriptor)*(LEN_QueRxDesc+1);
+    pP->s.pQueRxSts = (void*)Align32(pBuf);
+    pBuf = (char*)pBuf + sizeof(receiveStatus)*(LEN_QueRxSts+1);
+    pP->s.pQueTxDesc = (void*)Align32(pBuf);
+    pBuf = (char*)pBuf + sizeof(transmitDescriptor)*(LEN_QueTxDesc+1);
+    pP->s.pQueTxSts = (void*)Align32(pBuf);
+    pBuf = (char*)pBuf + sizeof(transmitStatus)*(LEN_QueTxSts+1);
+
+    /*
+      store physical address of each queue
+    */
+    pP->s.phyQueRxDesc = Align32(pP->s.phyQueueBase);
+    pP->s.phyQueRxSts = pP->s.phyQueRxDesc + ((U32)pP->s.pQueRxSts-(U32)pP->s.pQueRxDesc);
+    pP->s.phyQueTxDesc = pP->s.phyQueRxDesc + ((U32)pP->s.pQueTxDesc-(U32)pP->s.pQueRxDesc);
+    pP->s.phyQueTxSts = pP->s.phyQueRxDesc + ((U32)pP->s.pQueTxSts-(U32)pP->s.pQueRxDesc);
+
+    _PRTK_INFO(("devQue_init(): Rx Descriptor Queue at 0x%p(Phy0x%x), %d entries\n",
+                pP->s.pQueRxDesc, (unsigned int)pP->s.phyQueRxDesc,LEN_QueRxDesc));
+    _PRTK_INFO(("devQue_init(): Rx Status Queue at 0x%p(Phy0x%x), %d entries\n",
+                pP->s.pQueRxSts, (unsigned int)pP->s.phyQueRxSts,LEN_QueRxSts));
+    _PRTK_INFO(("devQue_init(): Tx Descriptor Queue at 0x%p(Phy0x%x), %d entries\n",
+                pP->s.pQueTxDesc, (unsigned int)pP->s.phyQueTxDesc,LEN_QueTxDesc));
+    _PRTK_INFO(("devQue_init(): Tx Status Queue at 0x%p(Phy0x%x), %d entries\n",
+                pP->s.pQueTxSts, (unsigned int)pP->s.phyQueTxSts,LEN_QueTxSts));
+
+    /*
+      init queue entries
+    */
+    memset(pP->s.pQueRxDesc, 0, sizeof(receiveDescriptor)*LEN_QueRxDesc);
+    memset(pP->s.pQueRxSts, 0, sizeof(receiveStatus)*LEN_QueRxSts);
+    memset(pP->s.pQueTxDesc, 0, sizeof(transmitDescriptor)*LEN_QueTxDesc);
+    memset(pP->s.pQueTxSts, 0, sizeof(transmitStatus)*LEN_QueTxSts);
+
+    /*Allocate Rx Buffer
+      (We might need to copy from Rx buf to skbuff in whatever case,
+       because device bus master requires 32bit aligned Rx buffer address 
+       but Linux network stack requires odd 16bit aligned Rx buf address)*/
+    pP->s.pRxBuf = MALLOC_DMA(((LEN_RxBuf+3)&~0x03)*LEN_QueRxDesc, &pP->s.phyRxBuf);
+    if(!pP->s.pRxBuf) { 
+        /*@*/
+        pP->s.pRxBuf=0;
+        _PRTK_SYSFAIL(("devQue_init(): fail to allocate memory for RxBuf\n"));
+        return -1;
+    }/*if*/
+
+
+    /*
+      allocate kernel memory for buffer descriptors
+    */
+    size = sizeof(bufferDescriptor)*(LEN_QueRxDesc+LEN_QueTxDesc);
+    pBuf = kmalloc(size, GFP_KERNEL);
+    if(!pBuf) {
+        _PRTK_SYSFAIL(("devQue_initAll(): fail to allocate memory for buf desc\n"));
+        return -1;
+    }/*if*/
+    memset(pBuf,0x0,size);  /*clear with 0*/
+    pP->s.pRxBufDesc=pBuf;
+    pP->s.pTxBufDesc=pBuf+sizeof(bufferDescriptor)*LEN_QueRxDesc;
+
+    return 0;
+}/*devQue_init()*/
+
+
+
+#ifndef _PRTK_DUMP
+# define _dbg_ep9312eth_dumpReg(pD)
+#else
+/*****************************************************************************
+* _dbg_ep9312eth_dumpReg()
+*****************************************************************************/
+static void  _dbg_ep9312eth_dumpReg(struct net_device *pD) {
+//    struct ep9213Eth_info  *pP = pD->priv;
+
+    _PRTK_DUMP(("Dumping registers of Ethernet Module Embedded within EP9312\n"));
+    _PRTK_DUMP((" pD:0x%p, Base Address:0x%x\n",pD,(unsigned int)pD->base_addr));
+
+    _PRTK_DUMP((" RxCTL:0x%08x  TxCTL:0x%08x  TestCTL:0x%08x\n",
+                (unsigned int)RegRd32(REG_RxCTL), (unsigned int)RegRd32(REG_TxCTL), (unsigned int)RegRd32(REG_TestCTL)));
+    _PRTK_DUMP((" SelfCTL:0x%08x  IntEn:0x%08x  IntStsP:0x%08x\n",
+                (unsigned int)RegRd32(REG_SelfCTL), (unsigned int)RegRd32(REG_IntEn), (unsigned int)RegRd32(REG_IntStsP)));
+    _PRTK_DUMP((" GT:0x%08x  FCT:0x%08x  FCF:0x%08x\n",
+                (unsigned int)RegRd32(REG_GT), (unsigned int)RegRd32(REG_FCT), (unsigned int)RegRd32(REG_FCF)));
+    _PRTK_DUMP((" AFP:0x%08x\n", (unsigned int)RegRd32(REG_AFP)));
+    _PRTK_DUMP((" TxCollCnt:0x%08x  RxMissCnt:0x%08x  RxRntCnt:0x%08x\n",
+                (unsigned int)RegRd32(REG_TxCollCnt), (unsigned int)RegRd32(REG_RxMissCnt), (unsigned int)RegRd32(REG_RxRntCnt)));
+    _PRTK_DUMP((" BMCtl:0x%08x  BMSts:0x%08x\n",
+                (unsigned int)RegRd32(REG_BMCtl), (unsigned int)RegRd32(REG_BMSts)));
+    _PRTK_DUMP((" RBCA:0x%08x  TBCA:0x%08x\n",
+                (unsigned int)RegRd32(REG_RBCA), (unsigned int)RegRd32(REG_TBCA)));
+    _PRTK_DUMP((" RxDBA:0x%08x  RxDBL/CL:0x%08x  RxDCA:0x%08x\n",
+                (unsigned int)RegRd32(REG_RxDBA), (unsigned int)RegRd32(REG_RxDBL), (unsigned int)RegRd32(REG_RxDCA)));
+    _PRTK_DUMP((" RxSBA:0x%08x  RxSBL/CL:0x%08x  RxSCA:0x%08x\n",
+                (unsigned int)RegRd32(REG_RxSBA), (unsigned int)RegRd32(REG_RxSBL), (unsigned int)RegRd32(REG_RxSCA)));
+    _PRTK_DUMP((" RxDEQ:0x%08x  RxSEQ:0x%08x\n",
+                (unsigned int)RegRd32(REG_RxDEQ), (unsigned int)RegRd32(REG_RxSEQ)));
+    _PRTK_DUMP((" TxDBA:0x%08x  TxDBL/CL:0x%08x  TxDCA:0x%08x\n",
+                (unsigned int)RegRd32(REG_TxDBA), (unsigned int)RegRd32(REG_TxDBL), (unsigned int)RegRd32(REG_TxDCA)));
+    _PRTK_DUMP((" TxSBA:0x%08x  TxSBL/CL:0x%08x  TxSCA:0x%08x\n",
+                (unsigned int)RegRd32(REG_TxSBA), (unsigned int)RegRd32(REG_TxSBL), (unsigned int)RegRd32(REG_TxSCA)));
+    _PRTK_DUMP((" TxDEQ:0x%08x\n",(unsigned int)RegRd32(REG_TxDEQ)));
+    _PRTK_DUMP((" RxBTH:0x%08x  TxBTH:0x%08x  RxSTH:0x%08x\n",
+                (unsigned int)RegRd32(REG_RxBTH), (unsigned int)RegRd32(REG_TxBTH), (unsigned int)RegRd32(REG_RxSTH)));
+    _PRTK_DUMP((" TxSTH:0x%08x  RxDTH:0x%08x  TxDTH:0x%08x\n",
+                (unsigned int)RegRd32(REG_TxSTH), (unsigned int)RegRd32(REG_RxDTH), (unsigned int)RegRd32(REG_TxDTH)));
+    _PRTK_DUMP((" MaxFL:0x%08x  RxHL:0x%08x\n",
+                (unsigned int)RegRd32(REG_MaxFL), (unsigned int)RegRd32(REG_RxHL)));
+    _PRTK_DUMP((" MACCFG0-3:0x%08x 0x%08x 0x%08x 0x%08x\n",
+                (unsigned int)RegRd32(REG_MACCFG0), (unsigned int)RegRd32(REG_MACCFG1), (unsigned int)RegRd32(REG_MACCFG2), (unsigned int)RegRd32(REG_MACCFG3)));
+/*
+    _PRTK_DUMP((" ---INT Controller Reg---\n"));
+    _PRTK_DUMP((" RawIrqSts :0x%08x 0x%08x\n",_RegRd(U32,0x80800004),_RegRd(U32,0x80800018)));
+    _PRTK_DUMP((" IrqMask   :0x%08x 0x%08x\n",_RegRd(U32,0x80800008),_RegRd(U32,0x8080001c)));
+    _PRTK_DUMP((" MaskIrqSts:0x%08x 0x%08x\n",_RegRd(U32,0x80800000),_RegRd(U32,0x80800014)));
+*/
+
+    _PRTK_DUMP(("Dumping private data:\n"));
+    _PRTK_DUMP((" d.txStopped:%d  d.idxQueTxSts:%d  d.idxQueTxDescHead:%d  d.idxQueTxDescTail:%d\n",
+                pP->d.txStopped,pP->d.idxQueTxSts,pP->d.idxQueTxDescHead,pP->d.idxQueTxDescTail));
+    _PRTK_DUMP((" d.idxQueRxDesc:%d  d.idxQueRxSts:%d\n",pP->d.idxQueRxDesc,pP->d.idxQueRxSts));
+}/*_dbg_ep9312eth_dumpReg()*/
+#endif/*ifndef _PRTK_DUMP else*/
+
+
+
+#define CRC_PRIME 0xFFFFFFFF
+#define CRC_POLYNOMIAL 0x04C11DB6
+/*****************************************************************************
+* calculate_hash_index()
+*****************************************************************************/
+static unsigned char  calculate_hash_index(char *pMulticastAddr) {
+   unsigned long CRC;
+   unsigned char  HashIndex;
+   unsigned char  AddrByte;
+   unsigned char *pC;
+   unsigned long HighBit;
+   int   Byte;
+   int   Bit;
+
+   /* Prime the CRC */
+   CRC = CRC_PRIME;
+   pC=pMulticastAddr;
+
+   /* For each of the six bytes of the multicast address */
+   for ( Byte=0; Byte<6; Byte++ )
+   {
+      AddrByte = *pC;
+      pC++;
+      /* For each bit of the byte */
+      for ( Bit=8; Bit>0; Bit-- )
+      {
+         HighBit = CRC >> 31;
+         CRC <<= 1;
+
+         if ( HighBit ^ (AddrByte & 1) )
+         {
+            CRC ^= CRC_POLYNOMIAL;
+            CRC |= 1;
+         }
+
+         AddrByte >>= 1;
+      }
+   }
+
+   /* Take the least significant six bits of the CRC and copy them */
+   /* to the HashIndex in reverse order.                           */
+   for( Bit=0,HashIndex=0; Bit<6; Bit++ )
+   {
+      HashIndex <<= 1;
+      HashIndex |= (unsigned char)(CRC & 1);
+      CRC >>= 1;
+   }
+
+   return HashIndex;
+}/*calculate_hash_index()*/
+
+/*****************************************************************************
+* eth_setMulticastTbl()
+*****************************************************************************/
+static void  eth_setMulticastTbl(struct net_device *pD,U8 *pBuf) {
+    int  i;
+    unsigned char position;
+    struct dev_mc_list  *cur_addr;
+
+    memset(pBuf,0x00,8);
+
+    cur_addr = pD->mc_list;
+    for(i=0;i<pD->mc_count;i++,cur_addr=cur_addr->next) {
+
+        if(!cur_addr)  break;
+        if(!(*cur_addr->dmi_addr&1))  continue;  /*make sure multicast addr*/
+        position=calculate_hash_index(cur_addr->dmi_addr);
+        pBuf[position>>3]|=1<<(position&0x07);
+
+    }/*for*/
+}/*eth_setMulticastTbl()*/
+
+
+/*****************************************************************************
+* eth_indAddrWr()
+*****************************************************************************/
+static int  eth_indAddrWr(struct net_device *pD,int afp,char *pBuf) {
+    U32  rxctl;
+    int  i,  len;
+
+    _PRTK_ENTRY(("eth_indAddrWr(pD:0x%x,afp:0x%x,pBuf:0x%x)\n",(unsigned int)pD,afp, (unsigned int)pBuf));
+
+    afp&=0x07;
+    if(4==afp || 5==afp) {
+        _PRTK_SWERR(("eth_indAddrWr(): invalid afp value\n"));
+        return -1;
+    }/*if*/
+    len=(AFP_AFP_HASH==afp)?8:6;
+
+    _PRTK_INFO(("eth_indAddrWr(): %02x:%02x:%02x:%02x:%02x:%02x%s",
+                pBuf[0],pBuf[1],pBuf[2],pBuf[3],pBuf[4],pBuf[5],(6==len)?"\n":":"));
+    if(6!=len) {
+        _PRTK_INFO(("%02x:%02x\n",pBuf[6],pBuf[7]));
+    }/*if*/
+
+    rxctl=RegRd32(REG_RxCTL);    /*turn Rx off*/
+    RegWr32(REG_RxCTL,~RxCTL_SRxON&rxctl);
+    RegWr32(REG_AFP,afp);  /*load new address pattern*/
+    for(i=0;i<len;i++)  RegWr8(REG_IndAD+i,pBuf[i]);
+    RegWr32(REG_RxCTL,rxctl);  /*turn Rx back*/
+
+    return 0;
+}/*eth_indAddrWr()*/
+
+
+
+/*****************************************************************************
+* eth_indAddrRd()
+*****************************************************************************/
+#if 0
+static int  eth_indAddrRd(struct net_device *pD,int afp,char *pBuf) {
+    int  i,  len;
+
+    _PRTK_ENTRY(("eth_indAddrRd(pD:0x%x,afp:0x%x,pBuf:0x%x)\n", (unsigned int)pD, afp, (unsigned int)pBuf));
+
+    afp&=0x07;
+    if(4==afp||5==afp) {
+        _PRTK_SWERR(("eth_indAddrRd(): invalid afp value\n"));
+        return -1;
+    }/*if*/
+
+    RegWr32(REG_AFP,afp);
+    len=(AFP_AFP_HASH==afp)?8:6;
+    for(i=0;i<len;i++)  pBuf[i]=RegRd8(REG_IndAD+i);
+
+    return 0;
+}/*eth_indAddrRd()*/
+#endif // 0
+
+/*****************************************************************************
+* eth_rxCtl()
+*****************************************************************************/
+static int  eth_rxCtl(struct net_device *pD,int sw) {
+
+    _PRTK_ENTRY(("eth_rxCtl(pD:0x%p,sw:%d)\n",pD,sw));
+
+/* Workaround for MAC lost 60-byte-long frames:  must enable Runt_CRC_Accept bit */
+    RegWr32(REG_RxCTL, sw?RegRd32(REG_RxCTL)| RxCTL_SRxON | RxCTL_RCRCA:
+                         RegRd32(REG_RxCTL)&~RxCTL_SRxON);
+
+    return 0;
+}/*eth_rxCtl()*/
+
+
+
+/*****************************************************************************
+* eth_chkTxLvl()
+*****************************************************************************/
+static void  eth_chkTxLvl(struct net_device *pD) {
+    struct ep9213Eth_info  *pP = pD->priv;
+    int  idxQTxDescHd;
+    int  filled;
+
+    _PRTK_ENTRY_ISR(("eth_chkTxLvl(pD:0x%x)\n", (unsigned int) pD));
+
+    idxQTxDescHd=pP->d.idxQueTxDescHead;
+
+    /*check Tx Descriptor Queue fill-up level*/
+    filled=idxQTxDescHd-pP->d.idxQueTxDescTail;
+    if(filled<0)  filled += LEN_QueTxDesc;
+
+    if(pP->d.txStopped && filled <= (LVL_TxResume+1)) {
+        pP->d.txStopped=0;
+        pD->trans_start = jiffies;
+        netif_wake_queue(pD);
+        _PRTK_INFO_ISR(("eth_chkTxLvl(): Tx Resumed, filled:%d\n",filled));
+    }/*if*/
+}/*eth_chkTxLvl()*/
+
+
+
+/*****************************************************************************
+* eth_cleanUpTx()
+*****************************************************************************/
+static int  eth_cleanUpTx(struct net_device *pD) {
+    struct ep9213Eth_info  *pP = pD->priv;
+    transmitStatus  *pQTxSts;
+    int  idxSts,  bi;
+
+    _PRTK_ENTRY(("eth_cleanUpTx(pD:0x%x)\n", (unsigned int)pD));
+
+    /*process Tx Status Queue (no need to limit processing of TxStatus Queue because
+      each queue entry consist of 1 dword)*/
+    while(pP->s.pQueTxSts[pP->d.idxQueTxSts].f.txfp) {
+
+        idxSts = pP->d.idxQueTxSts;
+
+        /*ahead Tx Status Queue index*/
+        pP->d.idxQueTxSts = IdxNext(pP->d.idxQueTxSts,LEN_QueTxSts);
+        pQTxSts = &pP->s.pQueTxSts[idxSts];
+        _PRTK_INFO(("eth_cleanUpTx(): QTxSts[%d]:0x%x\n",idxSts,(unsigned int)pQTxSts->w.e0));
+        if(!pQTxSts->f.txfp) {  /*empty?*/
+            _PRTK_HWFAIL(("eth_cleanUpTx(): QueTxSts[%d]:x%08x is empty\n",idxSts,(int)pQTxSts->w.e0));
+            /*@ do recover*/
+            return -1;
+        }/*if*/
+        pQTxSts->f.txfp=0;  /*mark processed*/
+
+        bi=pQTxSts->f.bi;  /*buffer index*/
+#if 0
+        if(pP->d.idxQueTxDescTail!=bi) {  /*verify BI*/
+            _PRTK_HWFAIL(("eth_cleanUpTx(): unmatching QTxSts[%d].BI:%d idxQTxDTail:%d\n",
+                          idxSts,bi,pP->d.idxQueTxDescTail));
+            /*@ recover*/
+        }/*if*/
+#endif
+
+        /*free Tx buffer*/
+        if(pP->s.pTxBufDesc[bi].pFreeRtn) {
+            (*pP->s.pTxBufDesc[bi].pFreeRtn)(pP->s.pTxBufDesc[bi].vaddr);
+            pP->s.pTxBufDesc[bi].pFreeRtn=0;
+        }/*if*/
+
+        /*statistics collection*/
+        if(pQTxSts->f.txwe) {  /*Sent without error*/
+            pP->d.stats.tx_packets++;
+        }else {  /*Tx failed due to error*/
+            _PRTK_INFO(("eth_cleanUpTx(): Tx failed due to error QTxSts[%d]:0x%x\n",
+                            idxSts, (unsigned int)pQTxSts->w.e0));
+            pP->d.stats.tx_errors++;
+            if(pQTxSts->f.lcrs)   pP->d.stats.tx_carrier_errors++;  /*loss of CRS*/
+            if(pQTxSts->f.txu) {
+                pP->d.stats.tx_fifo_errors++;     /*underrun*/
+            }/*if*/
+            if(pQTxSts->f.ecoll)  pP->d.stats.collisions++;  /*excessive collision*/
+        }/*else*/
+
+        /*ahead Tx Descriptor Queue tail index*/
+        pP->d.idxQueTxDescTail=IdxNext(pP->d.idxQueTxDescTail,LEN_QueTxDesc);
+    }/*while*/
+
+    return 0;
+}/*eth_cleanUpTx()*/
+
+
+
+/*****************************************************************************
+* eth_restartTx()
+*****************************************************************************/
+static int  eth_restartTx(struct net_device *pD)
+{
+    struct ep9213Eth_info  *pP = pD->priv;
+    int  i;
+
+    _PRTK_ENTRY(("eth_restartTx(pD:0x%p)\n",pD));
+
+    /*disable int*/
+    RegWr32(REG_GIntMsk, RegRd32(REG_GIntMsk)&~GIntMsk_IntEn);  /*turn off master INT control*/
+
+    /*stop Tx and Tx DMA*/
+    RegWr32(REG_TxCTL, RegRd32(REG_TxCTL)&~TxCTL_STxON);  /*Tx off*/
+    RegWr32(REG_BMCtl, RegRd32(REG_BMCtl)|BMCtl_TxDis);  /*disable Tx DMA*/
+
+    /*reset Tx DMA*/
+    RegWr32(REG_BMCtl,BMCtl_TxChR|RegRd32(REG_BMCtl));  /*reset Tx DMA*/
+
+    /*release Tx buffers*/
+    for(i=0;i<LEN_QueTxDesc;i++) {
+        if(pP->s.pTxBufDesc[i].pFreeRtn) {
+            pP->s.pTxBufDesc[i].pFreeRtn(pP->s.pTxBufDesc[i].vaddr);
+            pP->s.pTxBufDesc[i].pFreeRtn=0;
+        }/*if*/
+        pP->d.stats.tx_dropped++;
+    }/*for*/
+
+    /*init Tx Queues and flush cache*/
+    memset(pP->s.pQueTxSts, 0, sizeof(pP->s.pQueTxSts[0])*LEN_QueTxSts);  /*clear FP flag*/
+
+    /*init variables*/
+    pP->d.txStopped=0;
+    pP->d.idxQueTxSts=pP->d.idxQueTxDescHead=pP->d.idxQueTxDescTail=0;
+
+    /*init registers*/
+    waitOnReg32(pD,REG_BMSts,BMCtl_TxChR,~BMCtl_TxChR,1);  /*wait to finish Tx DMA reset*/
+    RegWr32(REG_TxSBA,pP->s.phyQueTxSts);  /*base addr of Tx Status Queue*/
+    RegWr32(REG_TxSCA,pP->s.phyQueTxSts);  /*current addr*/
+    RegWr16(REG_TxSBL,sizeof(pP->s.pQueTxSts[0])*LEN_QueTxSts);  /*base len*/
+    RegWr16(REG_TxSCL,sizeof(pP->s.pQueTxSts[0])*LEN_QueTxSts);  /*current len*/
+    RegWr32(REG_TxDBA,pP->s.phyQueTxDesc);  /*base addr of Tx Descriptor Queue*/
+    RegWr32(REG_TxDCA,pP->s.phyQueTxDesc);  /*current addr*/
+    RegWr16(REG_TxDBL,sizeof(pP->s.pQueTxDesc[0])*LEN_QueTxDesc);  /*base len*/
+    RegWr16(REG_TxDCL,sizeof(pP->s.pQueTxDesc[0])*LEN_QueTxDesc);  /*current len*/
+
+    /*start Tx and Tx DMA*/
+    RegWr32(REG_TxCTL,RegRd32(REG_TxCTL)|TxCTL_STxON);  /*Tx on*/
+    RegWr32(REG_BMCtl,RegRd32(REG_BMCtl)|BMCtl_TxEn);  /*enable Tx DMA*/
+
+    /*enable int again*/
+    RegWr32(REG_GIntMsk,RegRd32(REG_GIntMsk)|GIntMsk_IntEn);  /*turn on master INT control*/
+
+    return 0;
+}/*eth_restartTx()*/
+
+
+
+/*****************************************************************************
+* eth_reset()
+*****************************************************************************/
+static int  eth_reset(struct net_device *pD) {
+    int  err;
+
+    _PRTK_ENTRY(("eth_reset(pD:0x%p)\n",pD));
+
+    RegWr8(REG_SelfCTL,SelfCTL_RESET);  /*soft reset command*/
+    err=waitOnReg32(pD,REG_SelfCTL,SelfCTL_RESET,~SelfCTL_RESET,1);
+    if(err) {
+        _PRTK_WARN(("eth_reset(): Soft Reset does not self-clear\n"));
+    }/*if*/
+
+    /*reset PHY*/
+    //phy_reset(pD);
+
+    return 0;
+}/*eth_reset()*/
+
+
+
+/*****************************************************************************
+ . Function: eth_shutDown()
+ . Purpose:  closes down the Ethernet module
+ . Make sure to:
+ .	1. disable all interrupt mask
+ .	2. disable Rx
+ .	3. disable Tx
+ .
+ . TODO:
+ .   (1) maybe utilize power down mode.
+ .	Why not yet?  Because while the chip will go into power down mode,
+ .	the manual says that it will wake up in response to any I/O requests
+ .	in the register space.   Empirical results do not show this working.
+* 
+*****************************************************************************/
+static int  eth_shutDown(struct net_device *pD) {
+
+    _PRTK_ENTRY(("eth_shutDown(pD:0x%p)\n",pD));
+
+    eth_reset(pD);
+    /*@ power down the Ethernet module*/
+
+    return 0;
+}/*eth_shutDown()*/
+
+
+
+/*****************************************************************************
+*  eth_enable()
+ 
+  Purpose:
+        Turn on device interrupt for interrupt driven operation.
+        Also turn on Rx but no Tx.
+* 
+*****************************************************************************/
+static int  eth_enable(struct net_device *pD) {
+
+    _PRTK_ENTRY(("eth_enable(pD:0x%p)\n",pD));
+
+    RegWr32(REG_IntEn,Default_IntSrc);  /*setup Interrupt sources*/
+    RegWr32(REG_GIntMsk,GIntMsk_IntEn);  /*turn on INT*/
+    eth_rxCtl(pD,1);  /*turn on Rx*/
+
+    return 0;
+}/*eth_enable()*/
+
+
+
+/*****************************************************************************
+*  eth_init()
+ 
+  Purpose:
+        Reset and initialize the device.
+        Device should be initialized enough to function in polling mode.
+        Tx and Rx must be disabled and no INT generation.
+* 
+*****************************************************************************/
+static int  eth_init(struct net_device *pD) {
+     int status;
+
+    _PRTK_ENTRY(("eth_init(pD:0x%p)\n",pD));
+
+    /*reset device*/
+    eth_reset(pD);
+
+    /*init PHY*/
+    gPhyAutoNegoDone=0;
+    status = phy_init(pD);
+    if (status != 0)
+    {
+      printk(KERN_WARNING "%s: No network cable detected!\n", pD->name);
+    }
+
+    /*init MAC*/
+    RegWr32(REG_SelfCTL,0x0f00);/*Set MDC clock to be divided by 8
+                               and enable PreambleSuppress bit*/
+    RegWr32(REG_GIntMsk,0x00);  /*mask Interrupt*/
+    RegWr32(REG_RxCTL,RxCTL_BA|RxCTL_IA0);  /*no Rx on at this point*/
+    RegWr32(REG_TxCTL,0x00);
+    RegWr32(REG_GT,0x00);
+    RegWr32(REG_BMCtl,0x00);
+    RegWr32(REG_RxBTH,(0x80<<16)|(0x40<<0));  /*Buffer Threshold*/
+    RegWr32(REG_TxBTH,(0x80<<16)|(0x40<<0) );
+    RegWr32(REG_RxSTH,(4<<16)|(2<<0) );        /*Status Threshold*/
+    RegWr32(REG_TxSTH,(4<<16)|(2<<0) );
+    RegWr32(REG_RxDTH,(4<<16)|(2<<0) );        /*Descriptor Threshold*/
+    RegWr32(REG_TxDTH,(4<<16)|(2<<0) );
+    RegWr32(REG_MaxFL,((1518+1)<<16)|(944<<0));  /*Max Frame Length & Tx Start Threshold*/
+    
+    RegRd32(REG_TxCollCnt);  /*clear Tx Collision Counter*/
+    RegRd32(REG_RxMissCnt);  /*clear Rx Miss Counter*/
+    RegRd32(REG_RxRntCnt);   /*clear Rx Runt Counter*/
+
+    RegRd32(REG_IntStsC);  /*clear Pending INT*/
+
+    RegWr32(REG_TxCTL,TxCTL_STxON|RegRd32(REG_TxCTL));  /*Tx on*/
+
+    /*Set MAC address*/
+    eth_indAddrWr(pD,AFP_AFP_IA0,&pD->dev_addr[0]);
+
+    /*init queue*/
+    devQue_start(pD);
+
+    return 0;
+}/*eth_init()*/
+
+
+
+/*****************************************************************************
+*  eth_probe()
+ 
+  Purpose:
+        Tests to see if a given base address points to an valid device
+        Returns 0 on success
+ 
+  Algorithm:
+        No method available now
+        Alway returns success
+* 
+*****************************************************************************/
+#if 0
+static int  eth_probe(U32 baseA) {
+
+    _PRTK_ENTRY(("eth_probe(baseA:0x%x)\n",(unsigned int)baseA));
+
+    return (portList[0].baseAddr==baseA)?0:-1;  /*no probe method available now except base addr*/
+}/*eth_probe()*/
+#endif // 0
+
+
+
+/*****************************************************************************
+*  driver_init()
+*
+*  Purpose:
+*        Logical driver initialization for an individual device
+*        Minimum device H/W access at this point
+*
+*  Task:
+*        Initialize the structure if needed
+*        print out my vanity message if not done so already
+*        print out what type of hardware is detected
+*        print out the ethernet address
+*        find the IRQ
+*        set up my private data
+*        configure the dev structure with my subroutines
+*        actually GRAB the irq.
+*        GRAB the region
+* 
+*****************************************************************************/
+static int __init  driver_init(struct net_device *pD,U32 baseA,int irq) {
+    struct ep9213Eth_info  *pP;
+    int  err;
+    int  i;
+
+
+    _PRTK_ENTRY(("driver_init(pD:0x%p,baseA:0x%x,irq:%d)\n",pD, (unsigned int)baseA,irq));
+
+    /*print out driver version*/
+    if(0==numOfInstance)  printk("ep93xx_eth() version: %s",version);
+
+    /*allocate the private structure*/
+    if(0==pD->priv) {
+        pD->priv = kmalloc(sizeof(struct ep9213Eth_info),GFP_KERNEL);
+        if(0==pD->priv) {
+            _PRTK_SYSFAIL((cardname " initDriver(): fail to allocate pD->priv\n"));
+            return -ENOMEM;
+	}/*if*/
+    }/*if*/
+    memset(pD->priv,0x00,sizeof(struct ep9213Eth_info));  /*init to 0*/
+
+    /*privite info*/
+    pP=pD->priv;
+    pP->s.id=numOfInstance;  /*device instance ID*/
+    pP->s.miiIdPhy=1;        /*MII Bus ID of PHY device*/
+
+    /*device access info*/
+    pD->base_addr  = baseA;     /*base address*/
+    pD->irq        = irq;       /*IRQ number*/
+
+    /*Get the Ethernet MAC address from system
+      but, do NOT set to the device at this point*/
+    for(i=0;i<6;i++)  pD->dev_addr[i]=default_mac[i];
+    GET_MAC_ADDR(pD, pD->dev_addr);
+
+    /*Grab the region so that no one else tries to probe this device*/
+    err=(int)request_mem_region(baseA,DEV_REG_SPACE,cardname);
+    if(!err) {
+        _PRTK_SYSFAIL((cardname " initDriver(): unable to get region 0x%x-0x%x (err=%d)\n",
+                       (int)baseA,(int)(baseA+DEV_REG_SPACE-1),err));
+        return -EAGAIN;
+    }/*if*/
+
+    /*Grab the IRQ (support no auto-probing)*/
+    _PRTK_INFO(("initDriver(): grabbing IRQ %d\n",pD->irq));
+    err = (int)request_irq(pD->irq, &ep9213Eth_isr, 0, cardname, pD);
+    if(err) {
+        _PRTK_SYSFAIL((cardname " initDriver(): unable to get IRQ %d (err=%d)\n",pD->irq,err));
+        return -EAGAIN;
+    }/*if*/
+
+    /*init device handler functions*/
+    pD->open               = &ep9213Eth_open;
+    pD->stop               = &ep9213Eth_close;
+    pD->hard_start_xmit    = &ep9213Eth_hardStartXmit;
+    pD->tx_timeout         = &ep9213Eth_txTimeout;
+    pD->watchdog_timeo     = /*@ HZ/2 */ HZ*5 ;
+    pD->get_stats          = &ep9213Eth_getStats;
+    pD->set_multicast_list = &ep9213Eth_setMulticastList;
+
+    /*Fill in the fields of the device structure with ethernet values*/
+    ether_setup(pD);
+
+    /*init device descriptor/status queues*/
+    devQue_init(pD);
+    /*reset the device, and put it into a known state*/
+    eth_reset(pD);
+
+    /*print out the device info*/
+    PRINTK((cardname " #%d at 0x%x IRQ:%d MAC",pP->s.id,(int)pD->base_addr,pD->irq));
+    for(i=0;i<6;i++)  PRINTK((":%02x",pD->dev_addr[i]));
+    PRINTK(("\n"));
+
+    numOfInstance++;  /*inc Number Of Instance under this device driver*/
+
+    return 0;
+}/*driver_init()*/
+
+
+
+/*****************************************************************************
+* eth_isrRx()
+*
+*  Interrupt Service Routines
+* 
+*****************************************************************************/
+static int  eth_isrRx(struct net_device *pD)
+{
+    ep9213Eth_info  *pP = pD->priv;
+    receiveStatus   *pQRxSts;
+    int  idxQRxStsHead;  /*index of Rx Status Queue Head from device (next put point)*/
+    int  idxSts;
+    int  cntStsProcessed,  cntDescProcessed;
+    char  *pDest;
+    struct sk_buff  *pSkb;
+    int  len;
+    UINT  dt;
+
+
+    _PRTK_ENTRY_ISR(("eth_isrRx(pD:0x%x)\n", (unsigned int)pD));
+
+    /*get Current Rx Status Queue pointer*/
+    dt=RegRd32(REG_RxSCA);
+    idxQRxStsHead=(dt-pP->s.phyQueRxSts)/sizeof(pP->s.pQueRxSts[0]);  /*convert to array index*/
+    _PRTK_INFO_ISR(("eth_isrRx(): RxSCA:0x%x -> idx:%d\n",dt,idxQRxStsHead));
+    if(!(0<=idxQRxStsHead&&idxQRxStsHead<LEN_QueRxSts)) {
+        _PRTK_HWFAIL(("eth_isrRx(): invalid REG_RxSCA:0x%x idx:%d (phyQueRxSts:0x%x Len:%x)\n",
+                      dt,idxQRxStsHead,(int)pP->s.phyQueRxSts,LEN_QueRxSts));
+        /*@ do recover*/
+        return -1;
+    }/*if*/
+
+    /*process Rx (limit to idxQRxStsHead due to cache)*/
+    cntStsProcessed=cntDescProcessed=0;
+    while(idxQRxStsHead!=pP->d.idxQueRxSts) {
+        idxSts=pP->d.idxQueRxSts;
+        pP->d.idxQueRxSts=IdxNext(pP->d.idxQueRxSts,LEN_QueRxSts);
+        pQRxSts=&pP->s.pQueRxSts[idxSts];
+        _PRTK_INFO_ISR(("eth_isrRx(): QRxSts[%d]:0x%x 0x%x\n",idxSts,(unsigned int)pQRxSts->w.e0, (unsigned int)pQRxSts->w.e1));
+        if(!pQRxSts->f.rfp) {  /*empty?*/
+            _PRTK_HWFAIL(("eth_isrRx(): QueRxSts[%d] is empty; Hd:%d\n",
+                          idxSts,idxQRxStsHead));
+            /*@ do recover*/
+            return -1;
+        }/*if*/
+        pQRxSts->f.rfp=0;  /*mark processed*/
+
+        if(pQRxSts->f.eob) {  /*buffer has data*/
+            if(pQRxSts->f.bi==pP->d.idxQueRxDesc) {  /*check BI*/
+                pP->d.idxQueRxDesc=IdxNext(pP->d.idxQueRxDesc,LEN_QueRxDesc);  /*inc Desc index*/
+                cntDescProcessed++;
+                if(pQRxSts->f.eof&&pQRxSts->f.rwe) {  /*received a frame without error*/
+                    len=pQRxSts->f.fl;
+                    _PRTK_INFO_ISR(("eth_isrRx(): Rx Len:%d\n",len));
+                    pSkb=dev_alloc_skb(len+5);  /*alloc buffer for protocal stack*/
+                    if(NULL!=pSkb) {
+                        skb_reserve(pSkb, 2);   /*odd 16 bit alignment to make protocal stack happy*/
+                        pSkb->dev=pD;
+                        pDest=skb_put(pSkb, len);
+
+                        memcpy( pDest, pP->s.pRxBufDesc[pQRxSts->f.bi].vaddr, len);
+                        pSkb->protocol=eth_type_trans(pSkb, pD);
+                        netif_rx(pSkb);  /*pass Rx packet to system*/
+                        pP->d.stats.rx_packets++;  /*inc Rx stat counter*/
+                        if(3==pQRxSts->f.am)  pP->d.stats.multicast++;  /*multicast*/
+                    }else {
+                        _PRTK_SYSFAIL(("eth_isrRx(): Low Memory, Rx dropped\n"));
+                        pP->d.stats.rx_dropped++;
+                    }/*else*/
+                }else {  /*errored Rx*/
+                    _PRTK_INFO_ISR(("eth_isrRx(): errored Rx, QueRxSts[%d]:0x%x/0x%x\n",
+                                    idxSts, (unsigned int)pP->s.pQueRxSts[idxSts].w.e0, (unsigned int)pP->s.pQueRxSts[idxSts].w.e1));
+                    pP->d.stats.rx_errors++;
+                    if(pQRxSts->f.oe)  pP->d.stats.rx_fifo_errors++;  /*overrun*/
+                    if(pQRxSts->f.fe)  pP->d.stats.rx_frame_errors++;  /*frame error*/
+                    if(pQRxSts->f.runt||pQRxSts->f.edata)  pP->d.stats.rx_length_errors++;  /*inv length*/
+                    if(pQRxSts->f.crce)  pP->d.stats.rx_crc_errors++;  /*crc error*/
+                }/*else*/
+            }else {
+                _PRTK_HWFAIL(("eth_isrRx(): unmatching QueRxSts[%d].BI:0x%x; idxQueRxDesc:0x%x\n",
+                              idxSts,pQRxSts->f.bi,pP->d.idxQueRxDesc));
+            }/*else*/
+        }/*if*/
+
+        cntStsProcessed++;
+    }/*while*/
+
+    /*enqueue*/
+    _PRTK_INFO_ISR(("eth_isrRx(): enqueue QueRxSts:%d QueRxDesc:%d\n",
+                    cntStsProcessed,cntDescProcessed));
+    RegWr32(REG_RxSEQ, cntStsProcessed);
+    RegWr32(REG_RxDEQ, cntDescProcessed);
+    
+    return 0;    
+}/*eth_isrRx()*/
+
+
+
+/*****************************************************************************
+* eth_isrTx()
+*****************************************************************************/
+static int  eth_isrTx(struct net_device *pD)
+{
+    _PRTK_ENTRY_ISR(("eth_isrTx(pD:0x%x)\n",(unsigned int)pD));
+
+    eth_cleanUpTx(pD);
+    eth_chkTxLvl(pD);  /*resume Tx if it was stopped*/
+    return 0;    
+}/*eth_isrTx()*/
+
+
+
+
+/*****************************************************************************
+* ep9213Eth_isr()
+*****************************************************************************/
+static void ep9213Eth_isr(int irq,void *pDev,struct pt_regs *pRegs) {
+    struct net_device  *pD = pDev;
+    int  lpCnt;
+    U32  intS;
+
+    _PRTK_ENTRY_ISR(("ep9213Eth_isr(irq:%d,pDev:0x%x,pRegs:0x%x)\n",
+                     irq, (unsigned int)pDev, (unsigned int)pRegs));
+
+    lpCnt=0;
+    do {
+        intS=RegRd32(REG_IntStsC);  /*get INT status and then clear*/
+
+        /*
+        intE=RegRd32(REG_IntEn);  //get INT Source Enable
+        intS&=(intE&~0x07)|(IntSts_AHBE|IntSts_OTHER|IntSts_SWI)|
+              ((intE&0x07)?IntSts_RxSQ:0x00);
+        _PRTK_INFO_ISR(("ep9213Eth_isr(): intS:0x%x intE:0x%x\n",intS,intE));
+       */
+
+        if(!intS)  break;  /*no INT*/
+        if(IntSts_RxSQ&intS)  eth_isrRx(pD);  /*Rx INT*/
+        if(IntSts_TxSQ&intS)  eth_isrTx(pD);  /*Tx INT*/
+    }while(lpCnt++ < 64);  /*limit loop to serve other interrupts too*/
+}/*ep9213Eth_isr()*/
+
+
+
+
+/*=========================================================
+ *  Exposed Driver Routines to the Outside World
+ *=======================================================*/
+
+/*****************************************************************************
+* ep9213Eth_getStats()
+*****************************************************************************/
+static struct net_device_stats*  ep9213Eth_getStats(struct net_device *pD)
+{
+    _PRTK_ENTRY(("ep9213Eth_getStats(pD:0x%x)\n", (unsigned int)pD));
+
+#ifdef _PRTK_DUMP  /*@ for debug*/
+    {
+        static int  tog=0;
+        tog=tog?0:1;
+        if(tog) {
+            _dbg_ep9312Eth_dumpQueues(pD);
+            /*_dbg_phy_dumpReg(pD);*/
+            _dbg_ep9312eth_dumpReg(pD);
+        }/*if*/
+    }
+#endif/*ifdef _PRTK_DUMP*/
+
+    return &((struct ep9213Eth_info*)pD->priv)->d.stats;
+}/*ep9213Eth_getStats()*/
+
+
+
+/*****************************************************************************
+* ep9213Eth_setMulticastList()
+*****************************************************************************/
+static void ep9213Eth_setMulticastList(struct net_device *pD)
+{
+    U8  tblMulti[8+1];
+
+    _PRTK_ENTRY(("ep9213Eth_setMulticastList(pD:0x%x)\n", (unsigned int)pD));
+
+    if(IFF_PROMISC&pD->flags) {  /*set promiscuous mode*/
+        _PRTK_INFO(("ep9213Eth_setMulticastList(): set Promiscuous mode\n"));
+        RegWr32(REG_RxCTL,RxCTL_PA|RegRd32(REG_RxCTL));
+
+    }else if(IFF_ALLMULTI&pD->flags) {  /*set to receive all multicast addr*/
+        _PRTK_INFO(("ep9213Eth_setMulticastList(): set All-Multicast mode\n"));
+        RegWr32(REG_RxCTL,RxCTL_MA|(~RxCTL_PA&RegRd32(REG_RxCTL)));
+        eth_indAddrWr(pD,AFP_AFP_HASH,"\xff\xff\xff\xff\xff\xff\xff\xff");
+
+    }else if(pD->mc_count) {  /*set H/W multicasting filter*/
+        _PRTK_INFO(("ep9213Eth_setMulticastList(): set Multicast mode\n"));
+        RegWr32(REG_RxCTL,RxCTL_MA|(~RxCTL_PA&RegRd32(REG_RxCTL)));
+        eth_setMulticastTbl(pD,&tblMulti[0]);
+        eth_indAddrWr(pD,AFP_AFP_HASH,&tblMulti[0]);
+
+    }else {  /*no multicasting*/
+        _PRTK_INFO(("ep9213Eth_setMulticastList(): no Promiscuous/Multicast\n"));
+        RegWr32(REG_RxCTL,~(RxCTL_PA|RxCTL_MA)&RegRd32(REG_RxCTL));
+    }/*else*/
+}/*ep9213Eth_setMulticastList()*/
+
+
+
+/*****************************************************************************
+* ep9213Eth_txTimeout()
+*****************************************************************************/
+static void  ep9213Eth_txTimeout(struct net_device *pD)
+{
+    int status;
+
+    _PRTK_ENTRY(("ep9213Eth_txTimeout(pD:0x%p)\n",pD));
+
+    /* If we get here, some higher level has decided we are broken.
+       There should really be a "kick me" function call instead. */
+    _PRTK_WARN(("ep9213Eth_txTimeout(): transmit timed out\n"));
+
+    // Check if PHY Auto negotiation has done?
+    // If not, we need to check the Link status.
+    // If no network cable is present, just print a error message
+    if (gPhyAutoNegoDone == 0) {
+       status = phy_init(pD);
+       if (status != 0)
+       {
+         printk(KERN_WARNING "%s: No network cable detected!\n", pD->name);
+         return ;
+       }
+    }
+
+    /*kick Tx engine*/
+    eth_restartTx(pD);
+
+    /*ask the Network Stack to resume Tx*/
+    pD->trans_start = jiffies;
+    netif_wake_queue(pD);
+}/*ep9213Eth_txTimeout()*/
+
+
+
+/*****************************************************************************
+* ep9213Eth_hardStartXmit()
+*****************************************************************************/
+static int  ep9213Eth_hardStartXmit(struct sk_buff *pSkb,struct net_device *pD) {
+
+/*@swk  to check H/W defect of Tx Underrun Error caused by certain frame length*/
+
+    struct ep9213Eth_info  *pP = pD->priv;
+    transmitDescriptor  *pQTxDesc;
+    int  idxQTxDescHd;
+    int  filled;
+    int status;
+//	unsigned int *pTemp;
+
+    _PRTK_ENTRY(("ep9213Eth_hardStartXmit(pSkb:0x%x,pD:0x%x)\n",(unsigned int)pSkb, (unsigned int)pD));
+
+    _PRTK_INFO(("ep9213Eth_hardStartXmit(): pSkb->len:0x%x\n",pSkb->len));
+
+    // Check if PHY Auto negotiation has done?
+    // If not, we need to check the Link status
+    // and have PHY do auto-negotiation.
+    // If no network cable is present, just drop the packet.
+    if (gPhyAutoNegoDone == 0) {
+       status = phy_init(pD);
+       if (status != 0)
+       {
+         return 1;
+       }
+    }
+
+    idxQTxDescHd = pP->d.idxQueTxDescHead;
+    pQTxDesc = &pP->s.pQueTxDesc[idxQTxDescHd];
+
+    /*check Tx Descriptor Queue fill-up level*/
+    filled=idxQTxDescHd-pP->d.idxQueTxDescTail;
+    if(filled<0)  filled+=LEN_QueTxDesc;
+    filled += 1;
+
+    if(/*!pP->d.txStopped&&*/LVL_TxStop <= filled) {  /*check Queue level*/
+        netif_stop_queue(pD);  /*no more Tx allowed*/
+        pP->d.txStopped=1;
+        _PRTK_INFO(("ep9213Eth_hardStartXmit(): Tx STOP requested, filled:%d\n",filled));
+        if(LVL_TxStop<filled) {
+            /*this situation can not be happen*/
+            _PRTK_SYSFAIL(("ep9213Eth_hardStartXmit(): a Tx Request while stop\n"));
+            return 1;
+        }/*if*/
+    }/*if*/
+
+    /*fill up Tx Descriptor Queue entry*/
+    if ( pSkb->len < 60 )
+    {
+       pQTxDesc->f.bl = 60;
+	   memset(pP->s.pTxBufDesc[idxQTxDescHd].vaddr, 0, 60);
+    }
+    else
+    {
+       pQTxDesc->f.bl = pSkb->len;
+    }
+    pQTxDesc->f.ba = virt_to_bus(pP->s.pTxBufDesc[idxQTxDescHd].vaddr); 
+    pQTxDesc->f.bi = idxQTxDescHd;
+    pQTxDesc->f.af = 0;
+    pQTxDesc->f.eof = 1;
+    _PRTK_INFO(("ep9213Eth_hardStartXmit(): Tx buf:x%08x len:%d QTxD[%d]:x%08x x%08x\n",
+                (unsigned int)pSkb->data, pSkb->len, (unsigned int)idxQTxDescHd,(unsigned int)pQTxDesc->w.e0, (unsigned int)pQTxDesc->w.e1));
+
+	//copy data to Tx buffer
+    memcpy(pP->s.pTxBufDesc[idxQTxDescHd].vaddr, pSkb->data, pSkb->len);  
+    pP->s.pTxBufDesc[idxQTxDescHd].pFreeRtn = 0;
+
+	//Don't need this. Flush Tx buffer into memory
+    //dma_cache_wback(pP->s.pTxBufDesc[idxQTxDescHd].vaddr, pQTxDesc->f.bl);
+
+	//Free the data buffer passed by upper layer
+	free_skb(pSkb);
+
+    pP->d.idxQueTxDescHead=IdxNext(pP->d.idxQueTxDescHead,LEN_QueTxDesc);  /*ahead Tx Desc Queue*/
+    RegWr32(REG_TxDEQ,1);  /*Enqueue a Tx Descriptor to the device*/
+
+    return 0;
+}/*ep9213Eth_hardStartXmit()*/
+
+
+
+/*****************************************************************************
+ . ep9213Eth_close()
+ .
+ . this makes the board clean up everything that it can
+ . and not talk to the outside world.   Caused by
+ . an 'ifconfig ethX down'
+ * 
+*****************************************************************************/
+
+static int  ep9213Eth_close(struct net_device *pD) {
+
+    _PRTK_ENTRY(("ep9213Eth_close(pD:0x%x)\n", (unsigned int)pD));
+
+    netif_stop_queue(pD);
+    eth_shutDown(pD);  /*shut device down*/
+
+    MOD_DEC_USE_COUNT;
+    return 0;
+}/*ep9213Eth_close()*/
+
+
+
+/*******************************************************
+ * ep9213Eth_open()
+ *
+ * Open and Initialize the board
+ *
+ * Set up everything, reset the card, etc ..
+ *
+ ******************************************************/
+static int  ep9213Eth_open(struct net_device *pD) {
+    int status;
+    struct ep9213Eth_info  *pP = pD->priv;
+
+
+    _PRTK_ENTRY(("ep9213Eth_open(pD:0x%x)\n",(unsigned int)pD));
+
+    /*clear dynamic device info*/
+    memset(&pP->d, 0, sizeof(pP->d));
+
+    MOD_INC_USE_COUNT;
+
+    /*reset/init device*/
+    status = eth_init(pD);
+    if (status != 0 )
+    {
+      return -EAGAIN;
+    }
+
+    /*turn on INT, turn on Rx*/
+    eth_enable(pD);
+
+#if 0  /*@*/
+    _dbg_phy_dumpReg(pD);
+    _dbg_ep9312eth_dumpReg(pD);
+    _dbg_ep9312Eth_dumpQueues(pD);
+#endif
+
+    /*link to upper layer*/
+    netif_start_queue(pD);
+
+    return 0;
+}/*ep9213Eth_open()*/
+
+
+
+/*****************************************************************************
+ .
+ . ep93xxEth_probe( struct net_device * dev )
+ .   This is the first routine called to probe device existance
+ .   and initialize the driver if the device found.
+ .
+ .   Input parameters:
+ .	dev->base_addr == 0, try to find all possible locations
+ .	dev->base_addr == 1, return failure code
+ .	dev->base_addr == 2, always allocate space,  and return success
+ .	dev->base_addr == <anything else>   this is the address to check
+ .
+ .   Output:
+ .	0 --> there is a device
+ .	anything else, error
+
+*****************************************************************************/
+
+int __init  ep93xxEth_probe(struct net_device *pD) {
+//    int  err;
+//    UINT  baseA;
+
+    
+    /*check input arguments*/
+    if(0==pD) {
+        _PRTK_SWERR(("ep93xxEth_probe(): pD equal 0\n"));
+        return -ENXIO;
+    }/*if*/
+
+    pD->base_addr=portList[0].baseAddr;
+    pD->irq=portList[0].irq;
+
+    _PRTK_ENTRY(("ep93xxEth_probe(pD:0x%x) base_addr=0x%x irq=%d \n", (unsigned int)pD, (unsigned int)pD->base_addr, pD->irq));
+
+    return driver_init(pD, pD->base_addr, pD->irq);
+
+}/*ep93xxEth_probe()*/
+
+
+
+
+#ifdef MODULE
+
+static struct net_device dev_ep9312Eth = { init: ep93xxEth_probe };
+
+static int io;
+static int irq;
+static int ifport;
+
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(ifport, "i");
+
+/*****************************************************************************
+* init_module()
+*****************************************************************************/
+int init_module(void)
+{
+	int result;
+
+	if (io == 0)
+		printk( "ep93xx_eth: You shouldn't use auto-probing with insmod!\n" );
+
+	/* copy the parameters from insmod into the device structure */
+	dev_ep9312Eth.base_addr = io;
+	dev_ep9312Eth.irq       = irq;
+	dev_ep9312Eth.if_port	= ifport;
+	if ((result = register_netdev(&dev_ep9312Eth)) != 0)
+		return result;
+
+	return 0;
+}
+
+/*****************************************************************************
+* cleanup_module()
+*****************************************************************************/
+void cleanup_module(void)
+{
+	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+	unregister_netdev(&dev_ep9312Eth);
+
+	free_irq(dev_ep9312Eth.irq, &dev_ep9312Eth);
+	release_mem_region(dev_ep9312Eth.base_addr, DEV_REG_SPACE);
+        
+
+	if (dev_ep9312Eth.priv)
+		kfree(dev_ep9312Eth.priv);
+}
+
+
+#endif /* MODULE */
diff -urN linux-2.4.29/drivers/net/ep93xx_eth.h linux-2.4.29-uc1/drivers/net/ep93xx_eth.h
--- linux-2.4.29/drivers/net/ep93xx_eth.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/ep93xx_eth.h	2005-06-14 02:12:10.000000000 +0100
@@ -0,0 +1,402 @@
+/*------------------------------------------------------------------------
+ * ep93xx_eth.h
+ * : header file of Ethernet Device Driver for Cirrus Logic EP93xx.
+ *
+ * Copyright (C) 2003 by Cirrus Logic www.cirrus.com 
+ * This software may be used and distributed according to the terms
+ * of the GNU Public License.
+ *
+ * This file contains device related information like register info
+ * and register access method macros for the Ethernet device 
+ * embedded within Cirrus Logic's EP93xx SOC chip.  
+ *
+ * Information contained in this file was obtained from 
+ * the EP9312 Manual Revision 0.12 and 0.14 from Cirrus Logic.
+ *
+ * History
+ * 05/18/01  Sungwook Kim  Initial release
+ * 03/25/2003  Melody Modified for EP92xx
+ *--------------------------------------------------------------------------*/
+
+
+#ifndef _EP9213_ETH_H_
+#define _EP9213_ETH_H_
+
+
+/*---------------------------------------------------------------
+ *  Definition of H/W Defects and Their Workarounds
+ *-------------------------------------------------------------*/
+
+
+
+/*---------------------------------------------------------------
+ *  Data types used in this driver
+ *-------------------------------------------------------------*/
+typedef  unsigned char   U8;
+typedef  unsigned short  U16;
+typedef  unsigned long   U32;
+typedef  unsigned int    UINT;
+
+
+
+/*---------------------------------------------------------------
+ * Definition of the registers.
+ * For details, refer to the datasheet  .
+ * 
+ * Basically, most registers are 32 bits width register.
+ * But some are 16 bits and some are 6 or 8 bytes long.
+ *-------------------------------------------------------------*/
+
+#define  REG_RxCTL  0x0000  /*offset to Receiver Control Reg*/
+#define  RxCTL_PauseA  (1<<20)
+#define  RxCTL_RxFCE1  (1<<19)
+#define  RxCTL_RxFCE0  (1<<18)
+#define  RxCTL_BCRC    (1<<17)
+#define  RxCTL_SRxON   (1<<16)
+#define  RxCTL_RCRCA   (1<<13)
+#define  RxCTL_RA      (1<<12)
+#define  RxCTL_PA      (1<<11)
+#define  RxCTL_BA      (1<<10)
+#define  RxCTL_MA      (1<<9)
+#define  RxCTL_IAHA    (1<<8)
+#define  RxCTL_IA3     (1<<3)
+#define  RxCTL_IA2     (1<<2)
+#define  RxCTL_IA1     (1<<1)
+#define  RxCTL_IA0     (1<<0)
+
+#define  REG_TxCTL  0x0004  /*offset to Transmit Control Reg*/
+#define  TxCTL_DefDis  (1<<7)
+#define  TxCTL_MBE     (1<<6)
+#define  TxCTL_ICRC    (1<<5)
+#define  TxCTL_TxPD    (1<<5)
+#define  TxCTL_OColl   (1<<3)
+#define  TxCTL_SP      (1<<2)
+#define  TxCTL_PB      (1<<1)
+#define  TxCTL_STxON   (1<<0)
+
+#define  REG_TestCTL   0x0008  /*Test Control Reg, R/W*/
+#define  TestCTL_MACF  (1<<7)
+#define  TestCTL_MFDX  (1<<6)
+#define  TestCTL_DB    (1<<5)
+#define  TestCTL_MIIF  (1<<4)
+
+#define  REG_MIICmd  0x0010  /*offset to MII Command Reg, R/W*/
+#define  MIICmd_OP     (0x03<<14)
+#define  MIICmd_OP_RD  (2<<14)
+#define  MIICmd_OP_WR  (1<<14)
+#define  MIICmd_PHYAD  (0x1f<<5)
+#define  MIICmd_REGAD  (0x1f<<0)
+
+#define  REG_MIIData  0x0014  /*offset to MII Data Reg, R/W*/
+#define  MIIData_MIIData  (0xffff<<0)
+
+#define  REG_MIISts  0x0018  /*offset to MII Status Reg, R*/
+#define  MIISts_Busy  (1<<0)
+
+#define  REG_SelfCTL  0x0020  /*offset to Self Control Reg*/
+#define  SelfCTL_RWP    (1<<7)    /*Remote Wake Pin*/
+#define  SelfCTL_GPO0   (1<<5)
+#define  SelfCTL_PUWE   (1<<4)
+#define  SelfCTL_PDWE   (1<<3)
+#define  SelfCTL_MIIL   (1<<2)
+#define  SelfCTL_RESET  (1<<0)
+
+#define  REG_IntEn   0x0024  /*Interrupt Enable Reg, R/W*/
+#define  IntEn_RWIE    (1<<30)
+#define  IntEn_RxMIE   (1<<29)
+#define  IntEn_RxBIE   (1<<28)
+#define  IntEn_RxSQIE  (1<<27)
+#define  IntEn_TxLEIE  (1<<26)
+#define  IntEn_ECIE    (1<<25)
+#define  IntEn_TxUHIE  (1<<24)
+#define  IntEn_MOIE    (1<<18)
+#define  IntEn_TxCOIE  (1<<17)
+#define  IntEn_RxROIE  (1<<16)
+#define  IntEn_MIIIE   (1<<12)
+#define  IntEn_PHYSIE  (1<<11)
+#define  IntEn_TIE     (1<<10)
+#define  IntEn_SWIE    (1<<8)
+#define  IntEn_TxSQIE   (1<<3)
+#define  IntEn_RxEOFIE  (1<<2)
+#define  IntEn_RxEOBIE  (1<<1)
+#define  IntEn_RxHDRIE  (1<<0)
+
+#define  REG_IntStsP  0x0028  /*offset to Interrupt Status Preserve Reg, R/W*/
+#define  REG_IntStsC  0x002c  /*offset to Interrupt Status Clear Reg, R*/
+#define  IntSts_RWI    (1<<30)
+#define  IntSts_RxMI   (1<<29)
+#define  IntSts_RxBI   (1<<28)
+#define  IntSts_RxSQI  (1<<27)
+#define  IntSts_TxLEI  (1<<26)
+#define  IntSts_ECI    (1<<25)
+#define  IntSts_TxUHI  (1<<24)
+#define  IntSts_MOI    (1<<18)
+#define  IntSts_TxCOI  (1<<17)
+#define  IntSts_RxROI  (1<<16)
+#define  IntSts_MIII   (1<<12)
+#define  IntSts_PHYSI  (1<<11)
+#define  IntSts_TI     (1<<10)
+#define  IntSts_AHBE   (1<<9)
+#define  IntSts_SWI    (1<<8)
+#define  IntSts_OTHER  (1<<4)
+#define  IntSts_TxSQ   (1<<3)
+#define  IntSts_RxSQ   (1<<2)
+
+#define  REG_GT  0x0040  /*offset to General Timer Reg*/
+#define  GT_GTC  (0xffff<<16)
+#define  GT_GTP  (0xffff<<0)
+
+#define  REG_FCT  0x0044  /*offset to Flow Control Timer Reg*/
+#define  FCT_FCT  (0x00ffffff<<0)
+
+#define  REG_FCF  0x0048  /*offset to Flow Control Format Reg*/
+#define  FCF_MACCT  (0xffff<<16)
+#define  FCF_TPT    (0xffff<<0)
+
+#define  REG_AFP  0x004c  /*offset to Address Filter Pointer Reg*/
+#define  AFP_AFP  (0x07<<0)  /*Address Filter Pointer (bank control for REG_IndAD)*/
+#define  AFP_AFP_IA0   0       /*Primary Individual Address (MAC Addr)*/
+#define  AFP_AFP_IA1   1       /*Individual Address 1*/
+#define  AFP_AFP_IA2   2       /*Individual Address 2*/
+#define  AFP_AFP_IA3   3       /*Individual Address 3*/
+#define  AFP_AFP_DTxP  6       /*Destination Address of Tx Pause Frame*/
+#define  AFP_AFP_HASH  7       /*Hash Table*/
+
+#define  REG_IndAD      0x0050  /*offset to Individual Address Reg, n bytes, R/W*/
+
+#define  REG_GIntSts    0x0060  /*offset to Global Interrupt Status Reg (writing 1 will clear)*/
+#define  REG_GIntROS    0x0068  /*offset to Global Interrupt Status Read Only Reg*/
+#define  GIntSts_INT  (1<<15)     /*Global Interrupt Request Status*/
+
+#define  REG_GIntMsk    0x0064  /*offset to Global Interrupt Mask Reg*/
+#define  GIntMsk_IntEn  (1<<15)   /*Global Interrupt Enable*/
+
+#define  REG_GIntFrc    0x006c  /*offset to Global Interrupt Force Reg*/
+#define  GIntFrc_INT  (1<<15)     /*Force to set GIntSts*/
+
+#define  REG_TxCollCnt  0x0070  /*Transmit Collision Count Reg, R*/
+#define  REG_RxMissCnt  0x0074  /*Receive Miss Count Reg, R*/
+#define  REG_RxRntCnt   0x0078  /*Receive Runt Count Reg, R*/
+
+#define  REG_BMCtl  0x0080  /*offset to Bus Master Control Reg, R/W*/
+#define  BMCtl_MT     (1<<13)
+#define  BMCtl_TT     (1<<12)
+#define  BMCtl_UnH    (1<<11)
+#define  BMCtl_TxChR  (1<<10)
+#define  BMCtl_TxDis  (1<<9)
+#define  BMCtl_TxEn   (1<<8)
+#define  BMCtl_EH2    (1<<6)
+#define  BMCtl_EH1    (1<<5)
+#define  BMCtl_EEOB   (1<<4)
+#define  BMCtl_RxChR  (1<<2)
+#define  BMCtl_RxDis  (1<<1)
+#define  BMCtl_RxEn   (1<<0)
+
+#define  REG_BMSts  0x0084  /*offset to Bus Master Status Reg, R*/
+#define  BMSts_TxAct  (1<<7)
+#define  BMSts_TP     (1<<4)
+#define  BMSts_RxAct  (1<<3)
+#define  BMSts_QID    (0x07<<0)
+#define  BMSts_QID_RxDt   (0<<0)
+#define  BMSts_QID_TxDt   (1<<0)
+#define  BMSts_QID_RxSts  (2<<0)
+#define  BMSts_QID_TxSts  (3<<0)
+#define  BMSts_QID_RxDesc (4<<0)
+#define  BMSts_QID_TxDesc (5<<0)
+
+#define  REG_RBCA   0x0088  /*offset to Receive Buffer Current Address Reg, R*/
+#define  REG_TBCA   0x008c  /*offset to Transmit Buffer Current Address Reg, R*/
+
+#define  REG_RxDBA  0x0090  /*offset to Receive Descriptor Queue Base Address Reg, R/W*/
+#define  REG_RxDBL  0x0094  /*offset to Receive Descriptor Queue Base Length Reg, R/W, 16bits*/
+#define  REG_RxDCL  0x0096  /*offset to Receive Descriptor Queue Current Length Reg, R/W, 16bits*/
+#define  REG_RxDCA  0x0098  /*offset to Receive Descriptor Queue Current Address Reg, R/W*/
+
+#define  REG_RxDEQ  0x009c  /*offset to Receive Descriptor Enqueue Reg, R/W*/
+#define  RxDEQ_RDV  (0xffff<<16)  /*R 16bit; Receive Descriptor Value*/
+#define  RxDEQ_RDI  (0xff<<0)     /*W 8bit; Receive Descriptor Increment*/
+
+#define  REG_RxSBA  0x00a0  /*offset to Receive Status Queue Base Address Reg, R/W*/
+#define  REG_RxSBL  0x00a4  /*offset to Receive Status Queue Base Length Reg, R/W, 16bits*/
+#define  REG_RxSCL  0x00a6  /*offset to Receive Status Queue Current Length Reg, R/W, 16bits*/
+#define  REG_RxSCA  0x00a8  /*offset to Receive Status Queue Current Address Reg, R/W*/
+
+#define  REG_RxSEQ  0x00ac  /*offset to Receive Status Queue Current Address Reg, R/W*/
+#define  RxSEQ_RSV  (0xffff<<16)
+#define  RxSEQ_RSI  (0xff<<0)
+
+#define  REG_TxDBA  0x00b0  /*offset to Transmit Descriptor Queue Base Address Reg, R/W*/
+#define  REG_TxDBL  0x00b4  /*offset to Transmit Descriptor Queue Base Length Reg, R/W, 16bits*/
+#define  REG_TxDCL  0x00b6  /*offset to Transmit Descriptor Queue Current Length Reg, R/W, 16bits*/
+#define  REG_TxDCA  0x00b8  /*offset to Transmit Descriptor Queue Current Address Reg, R/W*/
+
+#define  REG_TxDEQ  0x00bc  /*offset to Transmit Descriptor Queue Current Address Reg, R/W*/
+#define  TxDEQ_TDV  (0xffff<<16)
+#define  TxDEQ_TDI  (0xff<<0)
+
+#define  REG_TxSBA  0x00c0  /*offset to Transmit Status Queue Base Address Reg, R/W*/
+#define  REG_TxSBL  0x00c4  /*offset to Transmit Status Queue Base Length Reg, R/W, 16bits*/
+#define  REG_TxSCL  0x00c6  /*offset to Transmit Status Queue Current Length Reg, R/W, 16bits*/
+#define  REG_TxSCA  0x00c8  /*offset to Transmit Status Queue Current Address Reg, R/W*/
+
+#define  REG_RxBTH  0x00d0  /*offset to Receive Buffer Threshold Reg, R/W*/
+#define  RxBTH_RDHT  (0x03ff<<16)
+#define  RxBTH_RDST  (0x03ff<<0)
+
+#define  REG_TxBTH  0x00d4  /*offset to Transmit Buffer Threshold Reg, R/W*/
+#define  TxBTH_TDHT  (0x03ff<<16)
+#define  TxBTH_TDST  (0x03ff<<0)
+
+#define  REG_RxSTH  0x00d8  /*offset to Receive Status Threshold Reg, R/W*/
+#define  RxSTH_RSHT  (0x003f<<16)
+#define  RxSTH_RSST  (0x003f<<0)
+
+#define  REG_TxSTH  0x00dc  /*offset to Transmit Status Threshold Reg, R/W*/
+#define  TxSTH_TSHT  (0x003f<<16)
+#define  TxSTH_TSST  (0x003f<<0)
+
+#define  REG_RxDTH  0x00e0  /*offset to Receive Descriptor Threshold Reg, R/W*/
+#define  RxDTH_RDHT  (0x003f<<16)
+#define  RxDTH_RDST  (0x003f<<0)
+
+#define  REG_TxDTH  0x00e4  /*offset to Transmit Descriptor Threshold Reg, R/W*/
+#define  TxDTH_TDHT  (0x003f<<16)
+#define  TxDTH_TDST  (0x003f<<0)
+
+#define  REG_MaxFL  0x00e8  /*offset to Max Frame Length Reg, R/W*/
+#define  MaxFL_MFL  (0x07ff<<16)
+#define  MaxFL_TST  (0x07ff<<0)
+
+#define  REG_RxHL  0x00ec  /*offset to Receive Header Length Reg, R/W*/
+#define  RxHL_RHL2  (0x07ff<<16)
+#define  RxHL_RHL1  (0x03ff<<0)
+
+#define  REG_MACCFG0  0x0100  /*offset to Test Reg #0, R/W*/
+#define  MACCFG0_DbgSel  (1<<7)
+#define  MACCFG0_LCKEN   (1<<6)
+#define  MACCFG0_LRATE   (1<<5)
+#define  MACCFG0_RXERR   (1<<4)
+#define  MACCFG0_BIT33   (1<<2)
+#define  MACCFG0_PMEEN   (1<<1)
+#define  MACCFG0_PMEST   (1<<0)
+
+#define  REG_MACCFG1  0x0104  /*offset to Test Reg #1, R/W*/
+#define  REG_MACCFG2  0x0108  /*offset to Test Reg #2, R*/
+#define  REG_MACCFG3  0x010c  /*offset to Test Reg #3, R*/
+
+
+
+/*---------------------------------------------------------------
+ * Definition of Descriptor/Status Queue Entry
+ *-------------------------------------------------------------*/
+
+typedef  union receiveDescriptor  {  /*data structure of Receive Descriptor Queue Entry*/
+    struct {        /*whole value*/
+        U32  e0,      /*1st dword entry*/
+             e1;      /*2nd dword entry*/
+    }  w;
+    struct {        /*bit field definitions*/
+        U32  ba:32,   /*Buffer Address (keep in mind this is physical address)*/
+             bl:16,   /*b15-0; Buffer Length*/
+             bi:15,   /*b30-16; Buffer Index*/
+             nsof:1;  /*b31; Not Start Of Frame*/
+    }  f;
+}  receiveDescriptor;
+
+
+typedef  union receiveStatus  {  /*data structure of Receive Status Queue Entry*/
+    struct {         /*whole word*/
+        U32  e0,       /*1st dword entry*/
+             e1;       /*2nd dword entry*/
+    }  w;
+    struct {         /*bit field*/
+        U32  rsrv1:8,  /*b7-0: reserved*/
+             hti:6,    /*b13-8: Hash Table Index*/
+             rsrv2:1,  /*b14: reserved*/
+             crci:1,   /*b15: CRC Included*/
+             crce:1,   /*b16: CRC Error*/
+             edata:1,  /*b17: Extra Data*/
+             runt:1,   /*b18: Runt Frame*/
+             fe:1,     /*b19: Framing Error*/
+             oe:1,     /*b20: Overrun Error*/
+             rxerr:1,  /*b21: Rx Error*/
+             am:2,     /*b23-22: Address Match*/
+             rsrv3:4,  /*b27-24: reserved*/
+             eob:1,    /*b28: End Of Buffer*/
+             eof:1,    /*b29: End Of Frame*/
+             rwe:1,    /*b30: Received Without Error*/
+             rfp:1,    /*b31: Receive Frame Processed*/
+             fl:16,    /*b15-0: frame length*/
+             bi:15,    /*b30-16: Buffer Index*/
+             rfp2:1;   /*b31: Receive Frame Processed at 2nd word*/
+    }  f;
+}  receiveStatus;
+
+
+typedef  union transmitDescriptor  {  /*data structure of Transmit Descriptor Queue Entry*/
+    struct {         /*whole value*/
+        U32  e0,       /*1st dword entry*/
+             e1;       /*2nd dword entry*/
+    }  w;
+    struct {         /*bit field*/
+        U32  ba:32,    /*b31-0: Buffer Address (keep in mind this is physical address)*/
+             bl:12,    /*b11-0: Buffer Length*/
+             rsrv1:3,  /*b14-12: reserved*/
+             af:1,     /*b15: Abort Frame*/
+             bi:15,    /*b30-16: Buffer Index*/
+             eof:1;    /*b31: End Of Frame*/
+
+    }  f;
+}  transmitDescriptor;
+
+
+typedef  union transmitStatus  {  /*data structure of Transmit Status Queue Entry*/
+    struct {         /*whole word*/
+        U32  e0;       /*1st dword entry*/
+    }  w;
+    struct {         /*bit field*/
+        U32  bi:15,    /*b14-0: Buffer Index*/
+             rsrv3:1,  /*b15: reserved*/
+             ncoll:5,  /*b20-16: Number of Collisions*/
+             rsrv2:3,  /*b23-21: reserved*/
+             ecoll:1,  /*b24: Excess Collisions*/
+             txu:1,    /*b25: Tx Underrun*/
+             ow:1,     /*b26: Out of Window*/
+             rsrv1:1,  /*b27: reserved*/
+             lcrs:1,   /*b28: Loss of CRS*/
+             fa:1,     /*b29: Frame Abort*/
+             txwe:1,   /*b30: Transmitted Without Error*/
+             txfp:1;   /*b31: Transmit Frame Processed*/
+    }  f;
+}  transmitStatus;
+
+
+
+/*---------------------------------------------------------------
+ *  Size of device registers occupied in memory/IO address map
+ *-------------------------------------------------------------*/
+#define  DEV_REG_SPACE  0x00010000
+
+/*
+#define U8 unsigned char
+#define U16 unsigned short
+#define U32 unsigned long
+*/
+
+/*---------------------------------------------------------------
+ * A definition of register access macros
+ *-------------------------------------------------------------*/
+#define  _RegRd(type,ofs)     (*(volatile type*)(ofs))
+#define  _RegWr(type,ofs,dt)  *(volatile type*)(ofs)=((type)(dt))
+
+#define  RegRd8(ofs)   _RegRd(U8,(char*)pD->base_addr+(ofs))
+#define  RegRd16(ofs)  _RegRd(U16,(char*)pD->base_addr+(ofs))
+#define  RegRd32(ofs)  _RegRd(U32,(char*)pD->base_addr+(ofs))
+#define  RegWr8(ofs,dt)   _RegWr(U8,(char*)pD->base_addr+(ofs),(dt))
+#define  RegWr16(ofs,dt)  _RegWr(U16,(char*)pD->base_addr+(ofs),(dt))
+#define  RegWr32(ofs,dt)  _RegWr(U32,(char*)pD->base_addr+(ofs),(dt))
+
+
+
+#endif  /* _EP9213_ETH_H_ */
+
diff -urN linux-2.4.29/drivers/net/eth_c5471.c linux-2.4.29-uc1/drivers/net/eth_c5471.c
--- linux-2.4.29/drivers/net/eth_c5471.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/eth_c5471.c	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,1103 @@
+/***********************************************************************
+ * linux/drivers/net/eth_c5471.c
+ *
+ * Based on linux/drivers/net/isa-skeleton.c from the linux-2.4.17
+ * and on the linux/drivers/net/skeleton.c from the linux 2.0.38
+ * distribution:
+ *
+ *   Copyright (C) 2003 Cadenux, LLC. All rights reserved.
+ *   todd.fischer@cadenux.com  <www.cadenux.com>
+ *
+ *   Copyright (C) 2001 RidgeRun, Inc. All rights reserved.
+ *
+ *   A network driver outline for linux written 1993-94 by Donald Becker.
+ *
+ *   Copyright 1993 United States Government as represented by the
+ *   Director, National Security Agency.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+/***********************************************************************
+ * Included Files
+ ***********************************************************************/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/crc32.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <asm/arch/sysdep.h> /* LINUX_20 */
+
+#ifdef LINUX_20
+#undef dev_kfree_skb
+#include <linux/malloc.h>    /* Deprecated */
+#else
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#endif
+
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
+#include "eth_c5471.h"
+
+/***********************************************************************
+ * Definitions
+ ***********************************************************************/
+
+#ifndef C5471_LAN_RATE /* Should be provided by config.in script */
+# define C5471_LAN_RATE 0
+#endif
+
+/***********************************************************************
+ * Private Type Declarations
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Variables
+ ***********************************************************************/
+
+/* This is a parameter that can be overriden at the time this module
+ * is loaded. It is used to control whether the board is set for
+ * 10BaseT (10) 100BaseT (100), or autonegotiation (0) operation.
+ * e.g. insmod LAN_Rate=10
+ */
+
+int LAN_Rate = C5471_LAN_RATE;
+
+/***********************************************************************
+ * Private Variables
+ ***********************************************************************/
+
+static const char cardname[] = "ethernet";
+
+/* Information that needs to be kept for each each port. */
+
+struct net_local
+{
+  struct NET_DEVICE_STATS stats;
+  long open_time;                 /* Useless example local info. */
+
+#ifndef LINUX_20
+  /* Tx control lock.  This protects the transmit buffer ring
+   * state along with the "tx full" state of the driver.  This
+   * means all netif_queue flow control actions are protected
+   * by this lock as well.
+   */
+
+  spinlock_t lock;
+#endif /* LINUX_20 */
+};
+
+#ifndef LINUX_20
+static int (*eth_set_mac_address)(struct NET_DEVICE *dev, void *addr) = NULL;
+#endif /* LINUX_20 */
+
+/***********************************************************************
+ * Private Function Prototypes
+ ***********************************************************************/
+
+#ifdef MODULE
+static int  c5471_net_probe(struct NET_DEVICE *dev);
+#else /* MODULE */
+extern int  c5471_net_probe(struct NET_DEVICE *dev);
+#endif /* MODULE */
+static int  net_open(struct NET_DEVICE *dev);
+static int  net_send_packet(struct sk_buff *skb, struct NET_DEVICE *dev);
+static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void net_rx(struct NET_DEVICE *dev);
+#if TX_EVENT
+static void net_tx(struct NET_DEVICE *dev);
+#endif /* TX_EVENT */
+static int  net_close(struct NET_DEVICE *dev);
+static struct NET_DEVICE_STATS *net_get_stats(struct NET_DEVICE *dev);
+static void set_multicast_list(struct NET_DEVICE *dev);
+#ifndef LINUX_20
+static void net_tx_timeout(struct NET_DEVICE *dev);
+#endif /* LINUX_20 */
+
+static void net_get_mac_address(struct NET_DEVICE *dev);
+static int  net_set_mac_address(struct NET_DEVICE *dev, void *addr);
+static int  net_reset_mac_address(struct NET_DEVICE *dev);
+
+/***********************************************************************
+ * c5471_net_probe
+ *
+ * This function is called during the kernel initialization
+ * for cases when this driver is linked with the kernel or
+ * from within this driver module when loaded by insmod.
+ *
+ * Check for a network adaptor of this type, and return '0' iff one
+ * exists.
+ *
+ * There is only one valid value for the base_address.  Normally,
+ * the following apply:
+ *
+ * dev->base_addr == 0, probe all likely locations.
+ * dev->base_addr == 1, always return failure.
+ * dev->base_addr == 2, allocate space for the device and return
+ *                      success (detachable devices only).
+ *
+ * However, we ignore these and slam-dunk the known C5471 base_addr.
+ *
+ * Similarly, we use the known C5471 IRQ.  We ignore the following
+ * possbilities:
+ *
+ * dev->irq == -1, a user-level program will set the IRQ.
+ * dev->irq <   2, do auto IRQ setupt
+ * dev->irq >=  2, use this IRQ.
+ *
+ ***********************************************************************/
+
+#ifdef MODULE
+static
+#endif /* MODULE */
+int
+#ifndef LINUX_20
+__init
+#endif
+c5471_net_probe(struct NET_DEVICE *dev)
+{
+  SET_MODULE_OWNER(dev);
+
+  if (strcmp(dev->name, "eth0") != 0) return -ENODEV;
+
+  dbg("%s/%s found at 0x%x, ", dev->name, cardname, ETHER_BASE);
+
+  /* Allocate a new 'dev' if needed. */
+
+#ifndef MODULE
+#ifdef LINUX_20
+  if (dev == NULL)
+    {
+      dev = init_etherdev(0, 0);
+      if (dev == NULL)
+	return -ENOMEM;
+    }
+#endif /* LINUX_20 */
+
+  /* Fill in the 'dev' fields that will not be provided if we
+   * are not a module.
+   */
+
+  dev->base_addr = ETHER_BASE;
+  dev->irq       = ETHER_IRQ;
+  dev->dma       = 0; /* no dma  */
+#endif /* MODULE */
+
+  /* Since C5471 has hard "jumpered" interrupts, allocate the interrupt
+   * vector now. There is no point in waiting since no other device
+   * can use the interrupt, and this marks the irq as busy.
+   */
+
+#if 0 /* Nah... We'll do this in net_open() */
+  {
+    int irqval;
+    irqval = request_irq(dev->irq, net_interrupt, 0, cardname, dev);
+    if (irqval)
+      {
+	warn("%s: unable to get IRQ %d (irqval=%d)",
+	     dev->name, dev->irq, irqval);
+	return -EAGAIN;
+      }
+  }
+#endif /* Nah */
+
+  /* Allocate private device data */
+
+  if (dev->priv == NULL)
+    {
+      dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+      if (dev->priv == NULL)
+	return -ENOMEM;
+    }
+
+  memset(dev->priv, 0, sizeof(struct net_local));
+
+#ifndef LINUX_20
+  {
+    struct net_local *np;
+    np = (struct net_local *)dev->priv;
+    spin_lock_init(&np->lock);
+  }
+#endif
+
+  /* Grab the region so that no one else tries to probe our ioports. */
+
+  request_region(dev->base_addr, NETCARD_IO_EXTENT, cardname);
+
+  /* Configure our driver routines to the kernel's INET subsystem. */
+
+  dev->open               = net_open;
+  dev->stop               = net_close;
+  dev->hard_start_xmit    = net_send_packet;
+  dev->get_stats          = net_get_stats;
+  dev->set_multicast_list = set_multicast_list;
+#ifdef LINUX_20
+  dev->set_mac_address    = net_set_mac_address;
+#else
+  dev->tx_timeout         = net_tx_timeout;
+  dev->watchdog_timeo     = MY_TX_TIMEOUT;
+#endif
+
+  /* Get the default MAC address */
+
+  net_get_mac_address(dev);
+
+  /* Fill in the fields of the device structure with ethernet values.
+   * (see net_init.c).  */
+
+  ether_setup(dev);
+
+  /* Capture the attempts to set the MAC address */
+
+#ifndef LINUX_20
+  eth_set_mac_address  = dev->set_mac_address;
+  dev->set_mac_address = net_set_mac_address;
+#endif
+
+  dbg("%s driver registered with kernel", cardname);
+  return 0;
+}
+
+/***********************************************************************
+ * net_open
+ *
+ * Open/initialize the board. This is called (in the current kernel)
+ * sometime after booting when the 'ifconfig' program is run.
+ *
+ * This routine should set everything up anew at each open, even
+ * registers that "should" only need to be set once at boot, so that
+ * there is non-reboot way to recover if something goes wrong.
+ *
+ ***********************************************************************/
+
+static int
+net_open(struct NET_DEVICE *dev)
+{
+  struct net_local *np = (struct net_local *)dev->priv;
+  int irqval;
+
+  dbg("request_irq(%d, 0x%08lx, 0, %s, 0x%08lx)",
+      (int)dev->irq, (long)net_interrupt, cardname, (long)dev);
+
+  /* This is used if the interrupt line can turned off (shared).
+   * See 3c503.c for an example of selecting the IRQ at config-time.
+   */
+
+#ifdef LINUX_20
+  dev->tbusy     = 0;
+  dev->start     = 1;
+  dev->interrupt = 0;
+#endif /* LINUX_20 */
+
+  irqval = request_irq(dev->irq, net_interrupt, 0, cardname, dev);
+  if (irqval)
+    {
+      warn("%s: unable to get IRQ %d (irqval=%d)",
+	   dev->name, dev->irq, irqval);
+      return -EAGAIN;
+    }
+
+  /* Always allocate the DMA channel after the IRQ,
+   * and clean up on failure.
+   * -- We have no DMA.
+   */
+
+  net_reset_mac_address(dev);
+
+  /* Reset the hardware here. Don't forget to set the station address. */
+
+  eth_turn_on_ethernet();
+  np->open_time  = jiffies;
+
+#ifdef LINUX_20
+  dev->tbusy     = 0;
+  dev->interrupt = 0;
+  dev->start     = 1;
+
+  MOD_INC_USE_COUNT;
+#else
+  /* We are now ready to accept transmit requeusts from
+   * the queueing layer of the networking.
+   */
+
+  netif_start_queue(dev);
+#endif
+
+  return 0;
+}
+
+/***********************************************************************
+ * net_send_packet
+ *
+ * LINUX_24:
+ * This will only be invoked if your driver is _not_ in XOFF state.
+ * What this means is that you need not check it, and that this
+ * invariant will hold if you make sure that the netif_*_queue()
+ * calls are done at the proper times.
+ *
+ ***********************************************************************/
+
+static int
+net_send_packet(struct sk_buff *skb, struct NET_DEVICE *dev)
+{
+  struct net_local *np;
+  short             length;
+
+  dbg("skb=0x%08lx, dev=0x%08lx", (long)skb, (long)dev);
+
+  /* If some error occurs while trying to transmit this
+   * packet, you should return '1' from this function.
+   * In such a case you _may not_ do anything to the
+   * SKB, it is still owned by the network queueing
+   * layer when an error is returned.  This means you
+   * may not modify any SKB fields, you may not free
+   * the SKB, etc.
+   */
+
+#ifdef LINUX_20
+  if (dev->tbusy)
+    {
+      /* If we get here, some higher level has decided we are broken.
+       * They had been waiting for an indication that the prior xmit had
+       * finished but never received it. Do what we can here to get the
+       * h/w running again.
+       */
+
+      int tickssofar = jiffies - dev->trans_start;
+      if (tickssofar < 5) return 1;
+
+      warn("%s: suspect transmit timed out", dev->name);
+
+      eth_turn_on_ethernet();
+
+      dev->tbusy       = 0;
+      dev->trans_start = jiffies;
+    }
+#endif
+
+  if (!skb)
+    {
+      warn("%s: unexpected null skb", dev->name);
+      return 1;
+    }
+  if (!dev)
+    {
+      warn("unexpected null device");
+      return 1;
+    }
+
+  np     = (struct net_local *)dev->priv;
+  length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+
+  dbg("np=0x%08lx, length=%d", (long)np, length);
+
+#if TX_RING
+
+  /* This is the most common case for modern hardware.
+   * The spinlock protects this code from the TX complete
+   * hardware interrupt handler.  Queue flow control is
+   * thus managed under this lock as well.
+   */
+
+  spin_lock_irq(&np->lock);
+
+  add_to_tx_ring(np, skb, length);
+  dev->trans_start = jiffies;
+
+  /* If we just used up the very last entry in the
+   * TX ring on this device, tell the queueing
+   * layer to send no more.
+   */
+
+  if (tx_full(dev))
+    {
+      netif_stop_queue(dev);
+    }
+
+  /* When the TX completion hw interrupt arrives, this
+   * is when the transmit statistics are updated.
+   */
+
+  spin_unlock_irq(&np->lock);
+
+#else
+
+  /* This is the case for older hardware which takes
+   * a single transmit buffer at a time, and it is
+   * just written to the device via PIO.
+   *
+   * No spin locking is needed since there is no TX complete
+   * event.  If by chance your card does have a TX complete
+   * hardware IRQ then you may need to utilize np->lock here.
+   */
+
+#ifdef LINUX_20
+  /* Block a timer-based transmit from overlapping. This could better be
+   * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
+   */
+
+  if (set_bit(0, (void*)&dev->tbusy) != 0)
+    {
+      warn("%s: Transmitter access conflict", dev->name);
+    }
+  else
+    {
+      eth_send_packet(skb->data, length);
+      dev->trans_start = jiffies;
+    }
+  dev_kfree_skb(skb,FREE_WRITE);
+#else /* LINUX_20 */
+  eth_send_packet(skb->data, length);
+  np->stats.tx_bytes += skb->len;
+
+  dev->trans_start = jiffies;
+
+  dev_kfree_skb(skb);
+#endif /* LINUX_20 */
+#endif
+
+  return 0;
+}
+
+/***********************************************************************
+ * net_interrupt.  Interrupt handler that is invoked whenever a
+ * packet is received or transmitted to the network.
+ ***********************************************************************/
+
+static void
+net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+  struct NET_DEVICE *dev = (struct NET_DEVICE *)dev_id;
+  struct net_local  *np;
+
+  verbose("");
+
+  if (dev == NULL)
+    {
+      warn("%s: irq %d for unknown device", cardname, irq);
+      return;
+    }
+#ifdef LINUX_20
+  dev->interrupt = 1;
+#endif /* LINUX_20 */
+
+  np = (struct net_local *)dev->priv;
+
+  if (eth_recv_int_active())
+    {
+      /* Got packet(s) */
+
+      net_rx(dev);
+    }
+
+#if TX_EVENT
+  if (eth_xmit_int_active())
+    {
+      /* Transmit complete. */
+
+      net_tx(dev);
+
+#if TX_RING
+      np->stats.tx_packets++;
+      netif_wake_queue(dev);
+#endif /* TX_RING */
+
+    }
+#endif /* TX_EVENT */
+
+#ifdef LINUX_20
+  dev->interrupt = 0;
+#endif /* LINUX_20 */
+}
+
+/***********************************************************************
+ * net_rx.
+ *
+ * We have a good packet(s), get it/them out of the buffers.
+ *
+ ***********************************************************************/
+
+static void
+net_rx(struct NET_DEVICE *dev)
+{
+  struct net_local *lp = (struct net_local *)dev->priv;
+  struct sk_buff *skb;
+  int packet_len;
+
+  /* Get the number of bytes in the first packet of the frame. */
+
+  eth_get_received_packet_len(&packet_len);
+
+  /* Loop until a zero-length packet is reported. */
+
+  while (packet_len)
+    {
+      verbose("packet_len=%d", packet_len);
+
+      /* Allocate memory for the packet data. */
+
+#ifdef LINUX_20
+      skb = alloc_skb(packet_len + 2, GFP_ATOMIC);
+#else
+      skb = dev_alloc_skb(packet_len + 2);
+#endif /* LINUX_20 */
+      if (skb == NULL)
+	{
+	  warn("%s: Memory squeeze, dropping packet", dev->name);
+	  lp->stats.rx_dropped++;
+	  dbg("rx_dropped=%ld", lp->stats.rx_dropped);
+	  return;
+	}
+
+      skb_reserve(skb, 2);  /* align the buffer */
+      skb->len = packet_len;
+      skb->dev = dev;
+
+      /* 'skb->data' points to the start of sk_buff data area. */
+
+      eth_get_received_packet_data(skb->data,(int *)(&(skb->len)));
+
+      if (eth_rx_errors())
+	{
+	  lp->stats.rx_errors++;
+	  dbg("rx_errors=%ld", lp->stats.rx_errors);
+	}
+      if (eth_rx_length_errors())
+	{
+	  lp->stats.rx_length_errors++;
+	  dbg("rx_length_errors=%ld", lp->stats.rx_length_errors);
+	}
+      if (eth_rx_over_errors())
+	{
+	  lp->stats.rx_over_errors++;
+	  dbg("rx_over_errors=%ld", lp->stats.rx_over_errors);
+	}
+      if (eth_rx_crc_errors())
+	{
+	  lp->stats.rx_crc_errors++;
+	  dbg("rx_crc_errors=%ld", lp->stats.rx_crc_errors);
+	}
+      if (eth_rx_frame_errors())
+	{
+	  lp->stats.rx_frame_errors++;
+	  dbg("rx_frame_errors=%ld", lp->stats.rx_frame_errors);
+	}
+      if (eth_rx_fifo_errors())
+	{
+	  lp->stats.rx_fifo_errors++;
+	  dbg("rx_fifo_errors=%ld", lp->stats.rx_fifo_errors);
+	}
+      if (eth_rx_missed_errors())
+	{
+	  lp->stats.rx_missed_errors++;
+	  dbg("rx_missed_errors=%ld", lp->stats.rx_missed_errors);
+	}
+
+      /* This INET call also modifies skb->pkt_type, skb->mac.raw, etc */
+
+      skb->protocol = eth_type_trans(skb, dev); 
+
+      /* Inform Linux INET subsystem. */
+#ifdef LINUX_20
+      lp->stats.rx_packets++;
+      netif_rx(skb);
+#else /* LINUX_20 */
+      netif_rx(skb); 
+
+      dev->last_rx  = jiffies;
+      lp->stats.rx_packets++;
+      lp->stats.rx_bytes += packet_len;
+#endif /* LINUX_20 */
+
+      /* Get the length of the next packet. */
+
+      eth_get_received_packet_len(&packet_len);
+    }  
+  return;
+}
+
+/***********************************************************************
+ * net_tx
+ ***********************************************************************/
+
+#if TX_EVENT
+static void
+net_tx(struct NET_DEVICE *dev)
+{
+#if TX_RING
+  struct net_local *np = (struct net_local *)dev->priv;
+  int entry;
+
+  verbose("");
+
+  /* This protects us from concurrent execution of
+   * our dev->hard_start_xmit function above.
+   */
+  spin_lock(&np->lock);
+
+  entry = np->tx_old;
+  while (tx_entry_is_sent(np, entry))
+    {
+      struct sk_buff *skb = np->skbs[entry];
+
+      np->stats.tx_bytes += skb->len;
+      dev_kfree_skb_irq (skb);
+
+      entry = next_tx_entry(np, entry);
+    }
+  np->tx_old = entry;
+
+  /* If we had stopped the queue due to a "tx full"
+   * condition, and space has now been made available,
+   * wake up the queue.
+   */
+  if (netif_queue_stopped(dev) && ! tx_full(dev))
+    {
+      netif_wake_queue(dev);
+    }
+
+  spin_unlock(&np->lock);
+#else
+
+  struct net_local *np = (struct net_local *)dev->priv;
+
+#ifdef LINUX_20
+  dev->tbusy = 0;
+#endif /* LINUX_20 */
+
+  /* Update statistics */
+
+  np->stats.tx_packets++;
+  verbose("tx_packets=%ld", np->stats.rx_errors);
+
+  if (eth_tx_errors())
+    {
+      np->stats.tx_errors++;
+      dbg("tx_errors=%ld", np->stats.tx_errors);
+    }
+  if (eth_tx_aborted_errors())
+    {
+      np->stats.tx_aborted_errors++;
+      dbg("tx_aborted_errors=%ld", np->stats.tx_aborted_errors);
+    }
+  if (eth_tx_carrier_errors())
+    {
+      np->stats.tx_carrier_errors++;
+      dbg("tx_carrier_errors=%ld", np->stats.tx_carrier_errors);
+    }
+  if (eth_tx_fifo_errors())
+    {
+      np->stats.tx_fifo_errors++;
+      dbg("tx_fifo_errors=%ld", np->stats.tx_fifo_errors);
+    }
+  if (eth_tx_heartbeat_errors())
+    {
+      np->stats.tx_heartbeat_errors++;
+      dbg("tx_heartbeat_errors=%ld", np->stats.tx_heartbeat_errors);
+    }
+  if (eth_tx_window_errors())
+    {
+      np->stats.tx_window_errors++;
+      dbg("tx_window_errors=%ld", np->stats.tx_window_errors);
+    }
+#endif /* TX_RING */
+
+#ifdef LINUX_20
+  /* Driver now informs Linux INET subsystem. */
+
+  mark_bh(NET_BH);
+#endif /* LINUX_20 */
+}
+#endif /* TX_EVENT */
+
+/***********************************************************************
+ * net_close
+ ***********************************************************************/
+
+static int
+net_close(struct NET_DEVICE *dev)
+{
+  struct net_local *np = (struct net_local *)dev->priv;
+
+  dbg("");
+
+#ifdef LINUX_20
+  eth_turn_off_ethernet();
+  free_irq(dev->irq, dev);
+
+  np->open_time = 0;
+
+  dev->tbusy    = 1;
+  dev->start    = 0;
+
+  MOD_DEC_USE_COUNT;
+#else
+  np->open_time = 0;
+
+  netif_stop_queue(dev);
+
+  eth_turn_off_ethernet();
+  free_irq(dev->irq, dev);  
+#endif
+
+  /* Update statistics here */
+
+  return 0;
+}
+
+/***********************************************************************
+ * net_get_status
+ ***********************************************************************/
+
+static struct NET_DEVICE_STATS *net_get_stats(struct NET_DEVICE *dev)
+{
+  struct net_local *np = (struct net_local *)dev->priv;
+
+  dbg("");
+
+  /* Update statistics here -- with interrupts disabled */
+
+  return &np->stats;
+}
+
+/***********************************************************************
+ * set_multicast_list
+ ***********************************************************************/
+
+static void set_multicast_list(struct NET_DEVICE *dev)
+{
+  int eim_addr_mode;              /* ENET_ADR_ defines */
+  int cpu_fltr_mode;              /* EIM_FILTER_ defines */
+
+	if(dev->flags&IFF_PROMISC)
+	{
+    eim_addr_mode = ENET_ADR_PROMISCUOUS;
+    cpu_fltr_mode = EIM_FILTER_MULTICAST | 
+                    EIM_FILTER_BROADCAST | 
+                    EIM_FILTER_UNICAST;
+    eth_multicast_promiscuous();
+	}
+	else if(dev->flags&IFF_ALLMULTI)
+	{
+    eim_addr_mode = ENET_ADR_PROMISCUOUS;
+    cpu_fltr_mode = EIM_FILTER_MULTICAST | 
+                    EIM_FILTER_BROADCAST | 
+                    EIM_FILTER_UNICAST;
+    eth_multicast_accept_multicast();
+	} 
+	else if(dev->mc_count > 0)
+	{
+		/* Accept all multicast packets and
+		   rely on higher-level filtering */
+    eim_addr_mode = ENET_ADR_PROMISCUOUS;
+    cpu_fltr_mode = EIM_FILTER_MULTICAST | 
+                    EIM_FILTER_BROADCAST | 
+                    EIM_FILTER_UNICAST;
+    eth_multicast_accept_multicast();
+	} 
+	else {
+    /* just accept broadcast packets and packets
+       sent to this device */     
+    eim_addr_mode = ENET_ADR_PROMISCUOUS;
+    cpu_fltr_mode = EIM_FILTER_BROADCAST | 
+                    EIM_FILTER_UNICAST;
+  }
+
+  eth_set_addressing(eim_addr_mode);
+  eth_set_filter(cpu_fltr_mode);
+}
+
+/***********************************************************************
+ * net_tx_timeout
+ ***********************************************************************/
+
+#ifndef LINUX_20
+static void net_tx_timeout(struct NET_DEVICE *dev)
+{
+  struct net_local *np = (struct net_local *)dev->priv;
+
+  warn("%s: transmit timed out", dev->name);
+
+  /* Try to restart the adaptor. */
+
+  eth_turn_on_ethernet();
+
+  np->stats.tx_errors++;
+  dbg("tx_errors=%ld", np->stats.tx_errors);
+
+  /* If we have space available to accept new transmit
+   * requests, wake up the queueing layer.  This would
+   * be the case if the eth_turn_on_ethernet() call above just
+   * flushes out the tx queue and empties it.
+   *
+   * If instead, the tx queue is retained then the
+   * netif_wake_queue() call should be placed in the
+   * TX completion interrupt handler of the driver instead
+   * of here.
+   */
+
+  if (!tx_full(dev))
+    {
+      netif_wake_queue(dev);
+    }
+}
+#endif /* LINUX_20 */
+
+/***********************************************************************
+ * net_get_mac_address
+ ***********************************************************************/
+
+static void net_get_mac_address(struct NET_DEVICE *dev)
+{
+  eth_get_default_MAC(dev->dev_addr);
+
+  dbg("Default ether MAC address = %02x:%02x:%02x:%02x:%02x:%02x",
+      dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], 
+      dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+}
+
+/***********************************************************************
+ * net_set_mac_address
+ ***********************************************************************/
+
+static int net_set_mac_address(struct NET_DEVICE *dev, void *addr)
+#ifndef LINUX_20
+{
+  int retval = 0;
+
+  dbg("");
+
+  /* Get the MAC address.  Do we have a pointer to the MAC
+   * address getting function?  Did it successfully get the
+   * MAC address? */
+
+  if (eth_set_mac_address)
+    {
+      if (eth_set_mac_address(dev,addr) == 0)
+	{
+	  /* Yes, set the HW MAC address. */
+
+	  retval = net_reset_mac_address(dev);
+	}
+    }
+  else
+    {
+      /* No pointer, set the hardware MAC address. */
+
+      retval = net_reset_mac_address(dev);
+    }
+  return retval;
+}
+#else /* LINUX_20 */
+{
+  /* Copy the address */
+
+  memcpy(dev->dev_addr, addr, 6);
+
+  /* Set the hardware MAC address. */
+
+  return net_reset_mac_address(dev);
+}
+#endif /* LINUX_20 */
+
+/***********************************************************************
+ * net_reset_mac_address
+ ***********************************************************************/
+
+static int net_reset_mac_address(struct NET_DEVICE *dev)
+{
+  eth_set_MAC(dev->dev_addr);
+
+  dbg("Set ether MAC address = %02x:%02x:%02x:%02x:%02x:%02x",
+      dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], 
+      dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+
+  return 0;
+}
+
+/***********************************************************************
+ * MODULE LOGIC
+ ***********************************************************************/
+
+#ifdef MODULE
+
+/* The NET_DEVICE structure for this device. */
+
+#ifdef LINUX_20
+static char devicename[9] = { 0, };
+static struct NET_DEVICE this_device =
+{
+  devicename,     /* will be inserted by linux/drivers/net/net_init.c */
+  0,              /* rmem_end:   shmem "recv" end */
+  0,              /* rmem_start: shmem "recv" start */
+  0,              /* mem_end:    shared mem end */
+  0,              /* mem_start:  shared mem start */
+  ETHER_BASE,     /* base_addr:  device I/O address */
+  ETHER_IRQ,      /* irq:        device IRQ number */
+  0,              /* start:      start an operation */
+  0,              /* interrupt:  interrupt arrived */
+  0,              /* tbusy:      transmitter busy */
+  NULL,           /* next:       list implementation */
+  c5471_net_probe /* init:       initialization function */
+                  /* (Rest implicitly initialized to zero) */
+};
+#else /* LINUX_20 */
+static struct NET_DEVICE this_device;
+#endif /* LINUX_20 */
+
+/* Set some defaults which the insmod command line can override
+ * (which, of course, is kind of silly because these are not optional
+ * values). */
+
+static int io  = ETHER_BASE;   /* Base address of registers */
+static int irq = ETHER_IRQ;    /* IRQ of ethernet device */
+static int dma = 0;            /* We don't support DMA. */
+static int mem = 0;            /* We don't use this */
+
+MODULE_PARM(io,  "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(dma, "i");
+MODULE_PARM(mem, "i");
+MODULE_PARM(LAN_Rate, "i");
+
+MODULE_PARM_DESC(io,       "C5471 Ethernet I/O base address");
+MODULE_PARM_DESC(irq,      "C5471 Ethernet IRQ number");
+MODULE_PARM_DESC(LAN_Rate, "0=Autonegotiate, 10=10BaseT, 100=100BaseT");
+
+MODULE_LICENSE("GPL");
+
+EXPORT_NO_SYMBOLS;
+
+/***********************************************************************
+ * net_init
+ ***********************************************************************/
+
+#ifdef LINUX_20
+static int net_init(void)
+#else
+static int __init net_init(void)
+#endif
+{
+  int result;
+
+  printk("C5471 C5471 Ethernet Driver, LAN_Rate=%d\n", LAN_Rate);
+
+  if (io == 0)
+    {
+      warn("%s: You shouldn't use auto-probing with insmod!", cardname);
+    }
+
+  /* Copy the parameters from insmod into the device structure. */
+
+  this_device.name[0]   = '\0';            /* System will provide name */
+  this_device.base_addr = io;              /* Base address of registers */
+  this_device.irq       = irq;             /* IRQ of ethernet device */
+  this_device.dma       = dma;             /* We don't support DMA. */
+  this_device.mem_start = mem;             /* We don't use this */
+#ifndef LINUX_20
+  this_device.init      = c5471_net_probe; /* Address of init function */
+#endif
+	
+  result = register_netdev(&this_device);
+  if (result != 0)
+    {
+      err("Failed to register ethernet driver, result=%d", result);
+      return result;
+    }
+
+  dbg("Successfully registered net device");
+  return 0;
+}
+
+/***********************************************************************
+ * net_cleanup
+ ***********************************************************************/
+
+#ifdef LINUX_20
+static void net_cleanup(void)
+#else
+static void __exit net_cleanup(void)
+#endif
+{
+  dbg("");
+
+  /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+
+  unregister_netdev(&this_device);
+
+  /* If we don't do this, we can't re-insmod it later.
+   * Release irq/dma here, when you have jumpered versions and
+   * allocate them in c5471_net_probe().
+   */
+
+  if (this_device.irq)
+    {
+      free_irq(this_device.irq, &this_device);
+    }
+
+  if (this_device.dma)
+    {
+      free_dma(this_device.dma);
+    }
+
+  if (this_device.base_addr)
+    {
+      release_region(this_device.base_addr, NETCARD_IO_EXTENT);
+    }
+
+  if (this_device.priv)
+    {
+#ifdef LINUX_20
+      kfree_s(this_device.priv, sizeof(struct net_local));
+#else
+      kfree(this_device.priv);
+#endif
+    }
+}
+
+module_init(net_init);
+module_exit(net_cleanup);
+
+#endif /* MODULE */
+/*
+ * Local variables:
+ *  c-indent-level: 2
+ *  tab-width: 2
+ * End:
+ */
diff -urN linux-2.4.29/drivers/net/eth_c5471.h linux-2.4.29-uc1/drivers/net/eth_c5471.h
--- linux-2.4.29/drivers/net/eth_c5471.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/eth_c5471.h	2005-06-14 02:12:15.000000000 +0100
@@ -0,0 +1,429 @@
+/***********************************************************************
+ * linux/drivers/net/eth_c5471.h
+ *
+ *   Copyright (C) 2003 Cadenux, LLC. All rights reserved.
+ *   todd.fischer@cadenux.com  <www.cadenux.com>
+ *
+ *   Copyright (C) 2001 RidgeRun, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#ifndef _ETH_C5471_H_
+#define _ETH_C5471_H_
+
+/***********************************************************************
+ *Included Files
+ ***********************************************************************/
+
+#include <asm/arch/sysdep.h> /* LINUX_20 */
+
+/***********************************************************************
+ * Compilation Switches
+ ***********************************************************************/
+
+/* #define ETHER_DEBUG 1 */
+/* #define VERBOSE     1 */
+
+/* This is the most common case for modern hardware. */
+
+#ifdef LINUX_20
+# undef TX_RING
+# define TX_RING    0
+#else
+# ifndef TX_RING
+#  define TX_RING   0
+# endif
+#endif
+
+#ifndef TX_EVENT
+# define TX_EVENT   1
+#endif
+
+/* gives all descriptors which belong to a TX packet to HW at the same time
+   not descriptor after desriptor which causes TX problems (lost TX packets) 
+   because of TX underruns when running via nfs */
+#define ETH_C5471_ALL_DESC_AT_ONCE 	1
+//#undef ETH_C5471_ALL_DESC_AT_ONCE
+
+/* define if you want to use the ESM otherwise use directly ENET0 */
+//#define ETH_C5471_USE_ESM 			1
+#undef ETH_C5471_USE_ESM
+
+/***********************************************************************
+ * Definitions
+ ***********************************************************************/
+
+/* Common debug definitions */
+
+#ifdef ETHER_DEBUG
+
+ /* Debug is enabled. */
+
+/* define MY_KERN_DEBUG KERN_DEBUG */
+
+# define MY_KERN_DEBUG
+# define dbg(format, arg...) \
+    printk(MY_KERN_DEBUG __FUNCTION__ ": " format "\n" , ## arg)
+
+ /* Check if verbose debug output is enabled. */
+
+# ifdef VERBOSE
+
+#   define verbose(format, arg...) \
+      printk(MY_KERN_DEBUG __FUNCTION__ ": " format "\n" , ## arg)
+
+# else /* VERBOSE */
+
+#   define verbose(format, arg...) do {} while (0)
+
+# endif /* VERBOSE */
+
+#else /* ETHER_DEBUG */
+
+ /* Can't have VERBOSE debug without ETHER_DEBUG */
+
+# undef  VERBOSE
+# define dbg(format, arg...) do {} while (0)
+# define verbose(format, arg...) do {} while (0)
+
+#endif /* ETHER_DEBUG */
+
+#define err(format, arg...) \
+  printk(KERN_ERR __FUNCTION__ ": " format "\n" , ## arg)
+#define info(format, arg...) \
+  printk(KERN_INFO __FUNCTION__ ": " format "\n" , ## arg)
+#define warn(format, arg...) \
+  printk(KERN_WARNING __FUNCTION__ ": " format "\n" , ## arg)
+
+#ifndef nop
+#define nop() asm("    nop");
+#endif /* nop */
+
+/* Byte management macros */
+
+#define __swap_16(x)       \
+  ((((x) & 0xff00) >> 8) | \
+   (((x) & 0x00ff) << 8))
+
+#define __swap_32(x)            \
+  ((((x) & 0xff000000) >> 24) | \
+   (((x) & 0x00ff0000) >>  8) | \
+   (((x) & 0x0000ff00) <<  8) | \
+   (((x) & 0x000000ff) << 24))
+
+#define EIM_RAM_START        ((void *)0xffd00000)
+
+/* Register definitions */
+
+#define ETHER_BASE           0xffff0000 
+#define EIM_CTRL_REG         ((volatile unsigned long *)0xffff0000)
+#define EIM_STATUS_REG       ((volatile unsigned long *)0xffff0004)
+#define EIM_CPU_TXBA_REG     ((volatile unsigned long *)0xffff0008)
+#define EIM_CPU_RXBA_REG     ((volatile unsigned long *)0xffff000c)
+#define EIM_BUFSIZE_REG      ((volatile unsigned long *)0xffff0010)
+#define EIM_CPU_FILTER_REG   ((volatile unsigned long *)0xffff0014)
+#define EIM_CPU_DAHI_REG     ((volatile unsigned long *)0xffff0018)
+#define EIM_CPU_DALO_REG     ((volatile unsigned long *)0xffff001c)
+#define EIM_MFVHI_REG        ((volatile unsigned long *)0xffff0020)
+#define EIM_MFVLO_REG        ((volatile unsigned long *)0xffff0024)
+#define EIM_MFMHI_REG        ((volatile unsigned long *)0xffff0028)
+#define EIM_MFMLO_REG        ((volatile unsigned long *)0xffff002c)
+#define EIM_RXTH_REG         ((volatile unsigned long *)0xffff0030)
+#define EIM_CPU_RXRDY_REG    ((volatile unsigned long *)0xffff0034)
+#define EIM_INT_EN_REG       ((volatile unsigned long *)0xffff0038)
+
+#define ENET0_MODE_REG       ((volatile unsigned long *)0xffff0100)
+#define ENET0_BOFFSEED_REG   ((volatile unsigned long *)0xffff0104)
+#define ENET0_FLWPAUSE_REG   ((volatile unsigned long *)0xffff010c)
+#define ENET0_FLWCONTROL_REG ((volatile unsigned long *)0xffff0110)
+#define ENET0_VTYPE_REG      ((volatile unsigned long *)0xffff0114)
+#define ENET0_SYS_ERR_REG    ((volatile unsigned long *)0xffff0118)
+#define ENET0_TXBUF_RDY_REG  ((volatile unsigned long *)0xffff011c)
+#define ENET0_TDBA_REG       ((volatile unsigned long *)0xffff0120)
+#define ENET0_RDBA_REG       ((volatile unsigned long *)0xffff0124)
+#define ENET0_PARHI_REG      ((volatile unsigned long *)0xffff0128)
+#define ENET0_PARLO_REG      ((volatile unsigned long *)0xffff012c)
+#define ENET0_LARHI_REG      ((volatile unsigned long *)0xffff0130)
+#define ENET0_LARLO_REG      ((volatile unsigned long *)0xffff0134)
+#define ENET0_ADRMODE_EN_REG ((volatile unsigned long *)0xffff0138)
+#define ENET0_DRP_REG        ((volatile unsigned long *)0xffff013c)
+
+#define GPIO_IO_REG          ((volatile unsigned long *)0xffff2800)
+#define GPIO_CIO_REG         ((volatile unsigned long *)0xffff2804)
+#define GPIO_EN_REG          ((volatile unsigned long *)0xffff2814)
+
+#define CLKM_REG             ((volatile unsigned long *)0xffff2f00)
+#define CLKM_CTL_RST_REG     ((volatile unsigned long *)0xffff2f10)
+#define CLKM_RESET_REG       ((volatile unsigned long *)0xffff2f18)
+
+/* Bit definitions */
+
+#define EIM_FILTER_UNICAST     	0x00000001  
+#define EIM_FILTER_BROADCAST   	0x00000002
+#define EIM_FILTER_MULTICAST   	0x00000004
+#define EIM_FILTER_HASH_MCAST  	0x00000008
+
+/* EIM ESM Control Register */
+#define EIM_CTRL_ESM_EN		   	0x00008000
+#define EIM_CTRL_ENET0_EN      	0x00000100
+//#define EIM_CTRL_ENET1_DIS     	0x00000100
+#define EIM_CTRL_ENET0_FLW     	0x00000040
+#define EIM_CTRL_ENET0_RXEN    	0x00000020  
+#define EIM_CTRL_ENET0_TXEN    	0x00000010
+#define EIM_CTRL_ENET1_RXEN    	0x00000008
+#define EIM_CTRL_ENET1_TXEN    	0x00000004
+#define EIM_CTRL_CPU_RXEN      	0x00000002
+#define EIM_CTRL_CPU_TXEN      	0x00000001
+
+/* EIM ESM Status Register */
+#define EIM_CPU_TX_LIF_INT     	0x00000200
+#define EIM_CPU_RX_LIF_INT     	0x00000100
+#define EIM_CPU_TX_INT         	0x00000080
+#define EIM_CPU_RX_INT         	0x00000040
+#define EIM_ENET0_ERR_INT      	0x00000004
+#define EIM_ENET0_TX_INT       	0x00000002
+#define EIM_ENET0_RX_INT       	0x00000001
+
+/* EIM CPU Filtering Control Register */
+// tbd
+
+/* ENET0 Mode Register */
+#define ENET0_MODE_FIFO_EN     	0x00008000
+#define ENET0_MODE_RJCT_SFE     0x00000080
+#define ENET0_MODE_DPNET     	0x00000040
+#define ENET0_MODE_MWIDTH       0x00000020
+#define ENET0_MODE_WRAP       	0x00000010
+#define ENET0_MODE_FDWRAP       0x00000008
+#define ENET0_MODE_HALFDUPLEX   0x00000000
+#define ENET0_MODE_FULLDUPLEX   0x00000004
+#define ENET0_MODE_ENABLE       0x00000001
+
+/* ENET0 System Error Interrupt Status Register */
+#define ENET0_SE_SR_TX_FE      	0x00000010
+#define ENET0_SE_SR_RX_BCE     	0x00000008
+#define ENET0_SE_SR_FIFE      	0x00000004
+#define ENET0_SE_SR_OFLW      	0x00000002
+#define ENET0_SE_SR_UFLW      	0x00000001
+
+/* ENET0 Address Mode Enable Register */
+#define ENET_ADR_PROMISCUOUS   	0x00000008
+#define ENET_ADR_BROADCAST     	0x00000004
+#define ENET_ADR_HAST_FLTR     	0x00000002
+#define ENET_ADR_DEST_ADDR     	0x00000001
+
+/* CPU/ENET RX/TX Descriptor Word #0/#1 (32bits) */
+#define EIM_DESC_OWNER_HOST    	0x80000000
+#define EIM_DESC_OWNER_ENET0   	0x00000000
+#define	EIM_DESC_OWNER_DEVICE	0x80000000
+#define EIM_DESC_OWNER_ESM		0x00000000
+
+#define EIM_DESC_WRAP        	0x40000000
+#define EIM_DESC_FIF        	0x20000000
+#define EIM_DESC_LIF         	0x10000000
+#define EIM_DESC_RETRY_MASK    	0x0f000000
+#define EIM_DESC_INTEN         	0x00800000
+#define EIM_DESC_PADCRC       	0x00004000  
+// number of data bytes of one descriptor
+#define EIM_DESC_PACKET_BYTES  	0x00000040
+
+/* This mask is used to clean the packet size in the RX descriptor */
+#define EIM_DESC_BYTES_MASK     0xfffff800
+
+/* Status bit positions for RX Descriptor Word #0/#1 (32bits) */
+#define RXSTATUS_MISS_BIT      0x00400000
+#define RXSTATUS_VLAN_BIT      0x00200000
+#define RXSTATUS_LONG_BIT      0x00100000
+#define RXSTATUS_SHORT_BIT     0x00080000
+#define RXSTATUS_CRC_BIT       0x00040000
+#define RXSTATUS_OVER_BIT      0x00020000
+#define RXSTATUS_ALIGN_BIT     0x00010000
+
+/* Status bit positions for TX Descriptor Word #0/#1 (32bits) */
+#define TXSTATUS_RETRY_BIT     0x00400000
+#define TXSTATUS_HEART_BIT     0x00200000
+#define TXSTATUS_LATE_COL_BIT  0x00100000
+#define TXSTATUS_COLLISION_BIT 0x00080000
+#define TXSTATUS_CRC_BIT       0x00040000
+#define TXSTATUS_UNDER_BIT     0x00020000
+#define TXSTATUS_LOSS_BIT      0x00010000
+
+/* EIM Reset */
+#define CLKM_RESET_EIM          0x00000008
+#define CLKM_EIM_CLK_STOP       0x00000010
+#define CLKM_CTL_RST_LEAD_RESET 0x00000000
+#define CLKM_CTL_RST_EXT_RESET  0x00000002
+
+/* Number of TX/RX descriptors */
+#define NUM_DESC_TX             32
+#define NUM_DESC_RX             64
+
+
+/* IRQ for the c5471 ethernet hardware */
+
+#define ETHER_IRQ               0x04
+
+/* The number of I/O ports used by the ethercard. */
+
+#define NETCARD_IO_EXTENT       0x140
+
+/* The C5471 EVM board (C5472) uses a Lucent LU3X31T-T64 transeiver
+ * device to handle the physical layer (PHY). It's a HW block that
+ * on the one end offers a Media Independent Interface (MII) which is
+ * connected to the Ethernet Interface Module (EIM) internal to the
+ * C5472 and on the other end offers either the 10baseT or 100baseT
+ * electrical interface connecting to an RJ45 onboard network connector.
+ * The PHY transeiver has several internal registers allowing host
+ * configuration and status access. These internal registers are
+ * accessable by clocking serial data in/out of the MDIO pin of the
+ * LU3X31T-T64 chip. For C5471, the MDC and the MDIO pins are
+ * connected to the C5472 GPIO15 and GPIO14 pins respectivley. Host
+ * software twidles the GPIO pins appropriately to get data serially
+ * into and out of the chip. This is typically a one time operation at
+ * boot and normal operation of the transeiver involves EIM/Transeiver
+ * interaction at the other pins of the transeiver chip and doesn't
+ * require host intervention at the MDC and MDIO pins.
+ */
+
+#define LU3X31_T64_IDval       0x00437421
+#define MD_PHY_MSB_REG         0x02
+#define MD_PHY_LSB_REG         0x03
+#define MD_PHY_CONTROL_REG     0x00
+#define MD_PHY_CTRL_STAT_REG   0x17
+#define MODE_AUTONEG           0x1000
+#define MODE_10MBIT_HALFDUP    0x0000
+#define MODE_10MBIT_FULLDUP    0x0100
+#define MODE_100MBIT_FULLDUP   0x2100
+#define MODE_100MBIT_HALFDUP   0x2000
+
+/* You'll notice a few places that reference ROUNDUP. The idea here is
+ * that we want to xfer bytes out of packet memory into the client's
+ * buffer in the most efficient way possible. This may involve xfering
+ * the data 16bits at a time or even 32bits at a time if possible.
+ * What this means is that if the packet actually isn't evenly
+ * divisible by the xfer size of 16bits or 32bits then we have to
+ * round *up* to insure that we xfer all the bytes of the packet
+ * recognizing that we may actually get a bit more data beyond 
+ * the last byte of the actual packet as the algorithm proceeds to the
+ * nearest whole 16bit or 32bit boundary.  This is harmless *if* the
+ * client buffer actually has the extra bytes allocated to allow us to
+ * overshoot slightly during the packet transfer -- in the end 
+ * we'll report an actual byte length of the packet and the client
+ * will not even know that a byte or two of bogus data actually follows
+ * the real packet. So this definition will help us manage this
+ * mechanism.
+ */
+
+#define ROUNDUP 1
+
+#ifndef LINUX_20
+# define MY_TX_TIMEOUT  ((400*HZ)/1000)
+#endif
+
+/* For now */
+
+#if !TX_RING
+# define tx_full(dev) 0
+#endif
+
+  /* These two address locations are special in that they are used
+   * by the bootloader to communicate a default device MAC to the kernel.
+   */
+
+#if 1
+  /* Ether MAC string deposited by bootloader to IRAM.  */
+
+#define __EtherMACMagicStr (unsigned char *)0xffc00100
+#define __EtherMAC         (unsigned char *)0xffc0010C
+
+#else  
+  /* Ether MAC string deposited by bootloader to SDRAM
+   * Careful! if you enable this then you are essentially declaring
+   * this area of SDRAM "reserved" and need to make sure that your
+   * kernel's CADENUX_DRAM_BASE setting (see asm/arch/memconfig.h) is a
+   * value larger than the space we are reserving here. Plan on this
+   * group of strings representing the kernel command line string and
+   * MAC string taking 0x100 bytes. That is your reserved amount of SDRAM.
+   */
+
+#define __EtherMACMagicStr (unsigned char *)0x10000100
+#define __EtherMAC         (unsigned char *)0x1000010C
+
+#endif  
+  
+#ifdef LINUX_20
+# define NET_DEVICE       device
+# define NET_DEVICE_STATS enet_statistics
+#else
+# define NET_DEVICE       net_device
+# define NET_DEVICE_STATS net_device_stats
+#endif
+
+/***********************************************************************
+ * Public Type Declarations
+ ***********************************************************************/
+
+/***********************************************************************
+ * Public Variables
+ ***********************************************************************/
+
+extern int LAN_Rate;
+
+/***********************************************************************
+ * Public Functions
+ ***********************************************************************/
+
+extern int  eth_tx_errors(void);
+extern int  eth_tx_window_errors(void);
+extern int  eth_tx_heartbeat_errors(void);
+extern int  eth_tx_fifo_errors(void);
+extern int  eth_tx_carrier_errors(void);
+extern int  eth_tx_aborted_errors(void);
+
+extern int  eth_rx_missed_errors(void);
+extern int  eth_rx_fifo_errors(void);
+extern int  eth_rx_frame_errors(void);
+extern int  eth_rx_crc_errors(void);
+extern int  eth_rx_over_errors(void);
+extern int  eth_rx_length_errors(void);
+extern int  eth_rx_errors(void);
+
+extern int  eth_recv_int_active(void);
+extern int  eth_xmit_int_active(void);
+
+extern void eth_get_default_MAC(unsigned char *mac_array);
+extern void eth_set_MAC(unsigned char *mac_array);
+
+extern void eth_multicast_accept_multicast(void);
+extern void eth_multicast_promiscuous(void);
+extern void eth_set_hast_multicast(long hash_table);
+extern void eth_set_addressing(int eim_addr);
+extern void eth_set_filter(int cpu_fltr);
+
+extern void eth_turn_on_ethernet(void);
+extern void eth_turn_off_ethernet(void);
+
+extern void eth_get_received_packet_len(int *numbytes);
+extern void eth_get_received_packet_data(unsigned char *buf, int *numbytes);
+extern void eth_send_packet(unsigned char *buf, int numbytes);
+
+#endif /* _ETH_C5471_H_ */
diff -urN linux-2.4.29/drivers/net/eth_c5471hw.c linux-2.4.29-uc1/drivers/net/eth_c5471hw.c
--- linux-2.4.29/drivers/net/eth_c5471hw.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/eth_c5471hw.c	2005-06-14 02:12:15.000000000 +0100
@@ -0,0 +1,2126 @@
+/***********************************************************************
+ * linux/drivers/net/eth_c5471hw.c
+ *
+ *   Copyright (C) 2003 Cadenux, LLC. All rights reserved.
+ *   todd.fischer@cadenux.com  <www.cadenux.com>
+ *
+ *   Copyright (C) 2001 RidgeRun, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+/***********************************************************************
+ * Included Files
+ ***********************************************************************/
+
+#include <linux/kernel.h>
+#include <asm/string.h>
+#include "eth_c5471.h"
+
+/***********************************************************************
+ * Definitions
+ ***********************************************************************/
+
+#ifdef MODULE
+static int   eth_strlen(const char *str);
+static char *eth_strcpy(char *dst, const char *src);
+static int   eth_strcmp(const char *s1, const char *s2);
+#else
+# define eth_strlen(str)      strlen(str)
+# define eth_strcpy(dst,src)  strcpy(dst,src)
+# define eth_strcmp(s1,s2)    strcmp(s1,s2)
+#endif
+
+/***********************************************************************
+ * Public Variables
+ ***********************************************************************/
+
+/***********************************************************************
+ * Private Variables
+ ***********************************************************************/
+
+static unsigned char d_MAC[6] = {0,0,0,0,0,0};
+
+/* According to the C5471 documentation: "The software has
+ * to maintain two pointers to the current RX-CPU and TX-CPU
+ * descriptors. At init time, they have to be set to the first
+ * descriptors of each queue, and they have to be incremented
+ * each time a descriptor ownership is give to the SWITCH".
+ */
+
+#ifdef ETH_C5471_USE_ESM
+static long         *current_tx_cpu_desc;
+static long         *current_rx_cpu_desc;
+#else
+static long         *current_tx_enet0_desc;
+static long         *current_rx_enet0_desc;
+#endif
+static long         *last_packet_desc_start;
+static long         *last_packet_desc_end;
+static unsigned long eim_status_shadow;
+static unsigned long cached_rx_status;
+static unsigned long cached_tx_status;
+
+/***********************************************************************
+ * eth_strlen, eth_strcpy, eth_strcmp
+ ***********************************************************************/
+
+#ifdef MODULE
+static int eth_strlen(const char *str)
+{
+  const char *ptr;
+  for (ptr = str; *ptr ; ptr++);
+  return (int)(ptr-str);
+}
+static char *eth_strcpy(char *dst, const char *src)
+{
+  char *ptr;
+  for (ptr = dst; *src; )
+    *ptr++ = *src++;
+  *ptr = '\0';
+  return dst;
+}
+
+static int eth_strcmp(const char *s1, const char *s2)
+{
+  unsigned char c1, c2;
+
+  do
+    {
+      c1 = (unsigned char) *s1++;
+      c2 = (unsigned char) *s2++;
+      if (c1 == '\0')
+	{
+	  return c1 - c2;
+	}
+    }
+  while (c1 == c2);
+
+  return c1 - c2;
+}
+#endif
+
+/***********************************************************************
+ * do_delay
+ ***********************************************************************/
+
+static void do_delay(int c)
+{
+  volatile int i;
+  for (i = 0; i <= c; i++){}
+}
+
+/***********************************************************************
+ * eth_out32.  Write to 32-bit HW registers
+ ***********************************************************************/
+
+static __inline__ void eth_out32(volatile unsigned long *addr,
+				unsigned long val)
+{
+#undef ADJUST_ENDIANNESS
+#ifdef ADJUST_ENDIANNESS
+  *addr = __swap_32(val);
+#else
+  *addr = val;
+#endif  
+}
+  
+/***********************************************************************
+ * eth_in32. Read from 32-bit HW registers
+ ***********************************************************************/
+
+static __inline__ unsigned long eth_in32(volatile unsigned long *addr)
+{
+#undef ADJUST_ENDIANNESS
+#ifdef ADJUST_ENDIANNESS
+  unsigned long val;
+  val = *addr;
+  return __swap_32(val);
+#else
+  return *addr;
+#endif
+}
+
+/***********************************************************************
+ * eth_md_tx_bit
+ ***********************************************************************/
+
+/* This is a  helper routine used when serially communicating
+ * with the C5471's external ethernet transeiver device.
+ * GPIO pins are connected to the transeiver's MDCLK and
+ * MDIO pins and are used to accomplish the serial comm.
+ *
+ * protocol:
+ *                     ___________
+ *    MDCLK   ________/           \_
+ *             ________:____
+ *    MDIO    <________:____>--------
+ *                     :
+ *                     ^
+ *             Pin state internalized
+ */
+
+#define MDIO_bit  0x00004000
+#define MDCLK_bit 0x00008000
+
+static void eth_md_tx_bit (int bit_state)
+{
+  	/* config MDIO as output pin. */
+  	eth_out32(GPIO_CIO_REG, (eth_in32(GPIO_CIO_REG)&~MDIO_bit)); 
+
+  	if (bit_state)
+    {
+    	/* set MDIO state high. */
+      	eth_out32(GPIO_IO_REG, (eth_in32(GPIO_IO_REG)|MDIO_bit));
+    }
+  	else
+    {
+    	/* set MDIO state low. */
+      	eth_out32(GPIO_IO_REG, (eth_in32(GPIO_IO_REG)&~MDIO_bit));
+    }
+
+  	nop();                    
+	nop();
+	nop();
+	nop();
+
+  	/* MDCLK rising edge */
+  	eth_out32(GPIO_IO_REG, (eth_in32(GPIO_IO_REG)|MDCLK_bit));
+  	nop();
+  	nop();
+
+  	/* release MDIO */
+  	eth_out32(GPIO_CIO_REG, (eth_in32(GPIO_CIO_REG)|MDIO_bit));
+  	nop();
+  	nop();
+
+  	/* MDCLK falling edge. */
+  	eth_out32(GPIO_IO_REG, (eth_in32(GPIO_IO_REG)&~MDCLK_bit));
+}
+
+/***********************************************************************
+ * eth_md_rx_bit()
+ ***********************************************************************/
+
+/* This is a helper routine used when serially communicating
+ * with the C5471's external ethernet transeiver device.
+ * GPIO pins are connected to the transeiver's MDCLK and
+ * MDIO pins and are used to accomplish the serial comm.
+ * 
+ * protocol:
+ *                    ___________
+ *    MDCLK  ________/           \_
+ *           _______:_____
+ *    MDIO   _______:_____>--------
+ *                  :
+ *                  ^
+ *         pin state sample point
+ */
+
+#define MDIO_bit  0x00004000
+#define MDCLK_bit 0x00008000
+
+static unsigned long eth_md_rx_bit (void)
+{
+	register unsigned long bit_state;
+
+	/* sanity; insure MDIO configured as input pin. */
+	eth_out32(GPIO_CIO_REG, (eth_in32(GPIO_CIO_REG)|MDIO_bit));
+
+	/* sanity; insure MDCLK low. */
+	eth_out32(GPIO_IO_REG, (eth_in32(GPIO_IO_REG)&~MDCLK_bit));
+	nop();
+	nop();
+	nop();
+	nop();
+
+	/* sample MDIO */
+	bit_state = eth_in32(GPIO_IO_REG) & MDIO_bit;
+
+	/* MDCLK rising edge */
+	eth_out32(GPIO_IO_REG, (eth_in32(GPIO_IO_REG)|MDCLK_bit));
+	nop();
+	nop();
+	nop();
+	nop();
+
+	/* MDCLK falling edge. */
+	eth_out32(GPIO_IO_REG, (eth_in32(GPIO_IO_REG)&~MDCLK_bit));
+	if (bit_state)
+  	{
+    	return 1;
+  	}
+	else
+  	{
+    	return 0;
+  	}
+}
+
+/***********************************************************************
+ * eth_md_write_reg
+ ***********************************************************************/
+
+/* This function is a helper routine used when serially communicating
+ * with the C5471's external ethernet transeiver device.
+ * GPIO pins are connected to the transeiver's MDCLK and
+ * MDIO pins and are used to accomplish the serial comm.
+ */
+
+static void eth_md_write_reg (int adr, int reg, int data)
+{
+  	int i;
+
+  	/* preamble: 11111111111111111111111111111111 */
+  	for (i = 0; i < 32; i++)
+    {
+      	eth_md_tx_bit(1);
+    }
+
+  	/* start of frame: 01 */
+  	eth_md_tx_bit(0);
+  	eth_md_tx_bit(1);
+
+  	/* operation code: 01 - write */
+  	eth_md_tx_bit(0);
+  	eth_md_tx_bit(1);
+
+  	/* PHY device address: AAAAA, msb first */
+  	for (i = 0; i < 5; i++)
+    {
+      	eth_md_tx_bit(adr & 0x10);
+      	adr = adr << 1;
+    }
+
+  	/* MII register address: RRRRR, msb first */
+  	for (i = 0; i < 5; i++)
+    {
+      	eth_md_tx_bit(reg & 0x10);
+      	reg = reg << 1;
+    }
+
+  	/* turnaround time: ZZ */
+  	eth_md_tx_bit(1);
+  	eth_md_tx_bit(0);
+
+  	/* data: DDDDDDDDDDDDDDDD, msb first */
+  	for (i = 0; i < 16; i++)
+    {
+      	eth_md_tx_bit(data & 0x8000);
+    	data = data << 1;
+    }
+}
+
+/***********************************************************************
+ * eth_md_read_reg
+ ***********************************************************************/
+
+/* This is a helper routine used when serially communicating
+ * with the C5471's external ethernet transeiver device.
+ * GPIO pins are connected to the transeiver's MDCLK and
+ * MDIO pins and are used to accomplish the serial comm.
+ */
+
+static int eth_md_read_reg (int adr, int reg)
+{
+  	int i;
+  	int data = 0;
+
+  	/* preamble: 11111111111111111111111111111111 */
+  	for (i = 0; i < 32; i++)
+    {
+      	eth_md_tx_bit(1);
+    }
+
+  	/* start of frame: 01 */
+  	eth_md_tx_bit(0);
+  	eth_md_tx_bit(1);
+
+  	/* operation code: 10 - read */
+  	eth_md_tx_bit(1);
+  	eth_md_tx_bit(0);
+
+  	/* PHY device address: AAAAA, msb first */
+  	for (i = 0; i < 5; i++)
+    {
+      	eth_md_tx_bit(adr & 0x10);
+      	adr = adr << 1;
+    }
+
+  	/* MII register address: RRRRR, msb first */
+  	for (i = 0; i < 5; i++)
+    {
+      	eth_md_tx_bit(reg & 0x10);
+      	reg = reg << 1;
+    }
+
+  	/* turnaround time: ZZ */
+  	eth_md_rx_bit();
+ 	eth_md_rx_bit(); /* PHY should drive a 0 */
+
+  	/* data: DDDDDDDDDDDDDDDD, msb first */
+  	for (i = 0; i < 16; i++)
+    {
+      	data = data << 1;
+     	 data |= eth_md_rx_bit();
+    }
+
+ 	return data;
+}
+
+/***********************************************************************
+ * eth_phy_init
+ ***********************************************************************/
+
+/* The C5471 EVM board (C5472) uses a Lucent LU3X31T-T64 transeiver
+ * device to handle the physical layer (PHY). It's a HW block that
+ * on the one end offers a Media Independent Interface (MII) which is
+ * connected to the Ethernet Interface Module (EIM) internal to the
+ * C5472 and on the other end offers either the 10baseT or 100baseT
+ * electrical interface connecting to an RJ45 onboard network connector.
+ * The PHY transeiver has several internal registers allowing host
+ * configuration and status access. These internal registers are
+ * accessable by clocking serial data in/out of the MDIO pin of the
+ * LU3X31T-T64 chip. For C5471, the MDC and the MDIO pins are
+ * connected to the C5472 GPIO15 and GPIO14 pins respectivley. Host
+ * software twidles the GPIO pins appropriately to get data serially
+ * into and out of the chip. This is typically a one time operation at
+ * boot and normal operation of the transeiver involves EIM/Transeiver
+ * interaction at the other pins of the transeiver chip and doesn't
+ * require host intervention at the MDC and MDIO pins.
+ */
+
+#if (CADENUX_ETHERNET_PHY == ETHERNET_PHY_LU3X31T_T64)
+static int eth_phy_init (void)
+{
+  int phy_id;
+  int status;
+  
+  /* Next, Setup GPIO pins to talk serially to the
+   * Lucent transeiver chip.
+   */
+
+  dbg("Setup GPIO connection to PHY.");
+
+  /* enable gpio bits 15,14 */
+
+  eth_out32(GPIO_EN_REG, (eth_in32(GPIO_EN_REG)|0x0000C000));
+
+  /* config gpio(15); out -> MDCLK */
+
+  eth_out32(GPIO_CIO_REG, (eth_in32(GPIO_CIO_REG)&~0x00008000));
+
+  /* config gpio(14); in <- MDIO */
+
+  eth_out32(GPIO_CIO_REG, (eth_in32(GPIO_CIO_REG)|0x00004000));
+
+  /* initial pin state; MDCLK = 0 */
+
+  eth_out32(GPIO_IO_REG, (eth_in32(GPIO_IO_REG)&0x000F3FFF));
+
+  /* Next, request a chip reset */
+
+  eth_md_write_reg(0, MD_PHY_CONTROL_REG, 0x8000);
+
+  dbg("PHY reset");
+
+  while (eth_md_read_reg(0, MD_PHY_CONTROL_REG) & 0x8000)
+    {
+      /* wait for chip reset to complete. */
+    }
+
+  /* Next, Read out the chip ID */
+ 
+  dbg("PHY chip ID read");
+
+  phy_id = (eth_md_read_reg(0, MD_PHY_MSB_REG) << 16) |
+    eth_md_read_reg(0, MD_PHY_LSB_REG);
+  if (phy_id != LU3X31_T64_IDval)
+    {
+      err("Unexpected PHY chip ID 0x%X", phy_id);
+      return -1;
+    }
+
+  /* Next, Set desired operation mode. */
+
+  switch (LAN_Rate)
+    {
+    case 100: /* 100BaseT */
+      dbg("Setting PHY Transceiver for 100BaseT FullDuplex");
+      eth_md_write_reg(0, MD_PHY_CONTROL_REG, MODE_100MBIT_FULLDUP);
+      break;
+
+    case 50: /* 100BaseT */
+      dbg("Setting PHY Transceiver for 100BaseT HalfDuplex");
+      eth_md_write_reg(0, MD_PHY_CONTROL_REG, MODE_100MBIT_HALFDUP);
+      break;
+
+    case 10: /* 10BaseT */
+      dbg("Setting PHY Transceiver for 10BaseT FullDuplex");
+      eth_md_write_reg(0, MD_PHY_CONTROL_REG, MODE_10MBIT_FULLDUP);
+      break;
+
+    case 5: /* 10BaseT */
+      dbg("Setting PHY Transceiver for 10BaseT HalfDuplex");
+      eth_md_write_reg(0, MD_PHY_CONTROL_REG, MODE_10MBIT_HALFDUP);
+      break;
+
+    case 0: /* Auto negotiation */
+      dbg("Setting PHY Transceiver for Autonegotiation");
+      eth_md_write_reg(0, MD_PHY_CONTROL_REG, MODE_AUTONEG);
+      break;
+    }
+
+  status = eth_md_read_reg(0, MD_PHY_CTRL_STAT_REG);
+  return status;
+}
+#else
+# define eth_phy_init()
+# if !defined(CADENUX_ETHERNET_PHY)
+#  warning "CADENUX_ETHERNET_PHY not defined -- assumed NONE"
+# endif
+#endif
+
+/***********************************************************************
+ * eth_eim_reset
+ ***********************************************************************/
+
+/* The C5472 docs states that a module should generally be reset
+ * according to the following algorithm:
+ *
+ *  1. Put the module in reset.
+ *  2. Switch on the module clock.
+ *  3. Wait for eight clock cycles.
+ *  4. Release the reset.
+ */
+
+static void eth_eim_reset (void)
+{
+  /* Stop the EIM module clock. */
+
+  eth_out32(CLKM_REG, (eth_in32(CLKM_REG)|CLKM_EIM_CLK_STOP));
+
+  /* put EIM module in reset. */
+
+  eth_out32(CLKM_RESET_REG, (eth_in32(CLKM_RESET_REG)&~CLKM_RESET_EIM));
+
+  /* Start the EIM module clock. */
+
+  eth_out32(CLKM_REG, (eth_in32(CLKM_REG)&~CLKM_EIM_CLK_STOP));
+  
+  /* Assert nRESET to reset the board's PHY0/1 chips 
+   * (i.e the external LU3X31T-T64 transeiver parts).
+  */
+
+  eth_out32(CLKM_CTL_RST_REG, (CLKM_CTL_RST_EXT_RESET | CLKM_CTL_RST_LEAD_RESET));
+
+  do_delay(2000);
+
+  /* Release the peripheral nRESET signal. */
+
+  eth_out32(CLKM_CTL_RST_REG, CLKM_CTL_RST_LEAD_RESET);
+  
+  /* Release EIM module reset. */
+
+  eth_out32(CLKM_RESET_REG, (eth_in32(CLKM_RESET_REG) | CLKM_RESET_EIM));
+
+  last_packet_desc_start = (void *)0;
+  last_packet_desc_end = (void *)0;
+  cached_tx_status = 0;
+  cached_rx_status = 0;
+
+  /* All EIM register should now be in their
+   * power-up default states. 
+   */
+}
+
+/***********************************************************************
+ * eth_eim_specific_config
+ ***********************************************************************/
+
+/* This function sssumes that all registers are currently in the
+ * power-up reset state. This routine then modifies that state to
+ * provide our  specific ethernet configuration.
+ */
+
+static void eth_eim_specific_config(void)
+{
+  char *p_buf;
+  unsigned long *p_desc, val;
+  int i;
+  
+  p_desc = EIM_RAM_START;
+  p_buf  = (unsigned char *)EIM_RAM_START + 0x6C0;
+
+  /* TX ENET 0 */
+  /* 16bit offset address. */
+
+#ifndef ETH_C5471_USE_ESM
+  current_tx_enet0_desc = p_desc;
+#endif
+  eth_out32(ENET0_TDBA_REG, (unsigned long)((unsigned long)(p_desc)&0x0000ffff)); 
+  for (i = NUM_DESC_TX-1; i >= 0; i--)
+    {
+      if (i == 0)
+	val = EIM_DESC_WRAP;
+      else
+	val = 0x0000;
+      val |= EIM_DESC_OWNER_HOST | EIM_DESC_INTEN | EIM_DESC_PADCRC | EIM_DESC_PACKET_BYTES;
+      eth_out32(p_desc, val);
+      p_desc++;
+      eth_out32(p_desc, (unsigned long)p_buf);
+      p_desc++;
+      *((unsigned long *)p_buf) = 0x00000000;
+      p_buf += EIM_DESC_PACKET_BYTES;
+      *((unsigned long *)p_buf) = 0x00000000;
+
+      /* As per C5471 doc; this space for Ether Module's
+       * "Buffer Usage Word". */
+
+      p_buf += 4;
+    }
+
+  /* RX ENET 0 */
+
+  /* 16bit offset address. */
+
+#ifndef ETH_C5471_USE_ESM
+  current_rx_enet0_desc = p_desc;
+#endif
+  eth_out32(ENET0_RDBA_REG, (unsigned long)((unsigned long)(p_desc)&0x0000ffff));
+  for (i=NUM_DESC_RX-1; i>=0; i--)
+    {
+      if (i == 0)
+	val = EIM_DESC_WRAP;
+      else
+	val = 0x0000;
+      val |= EIM_DESC_OWNER_ENET0 | EIM_DESC_INTEN | EIM_DESC_PADCRC | EIM_DESC_PACKET_BYTES;
+      eth_out32(p_desc, val);
+      p_desc++;
+      eth_out32(p_desc, (unsigned long)p_buf);
+      p_desc++;
+      *((unsigned long *)p_buf) = 0x00000000;
+      p_buf += EIM_DESC_PACKET_BYTES;
+      *((unsigned long *)p_buf) = 0x00000000;
+
+      /* As per C5471 doc; this space for Ether Module's "Buffer Usage Word". */
+
+      p_buf += 4;
+    }
+
+#ifdef ETH_C5471_USE_ESM
+  /* TX CPU */
+
+  current_tx_cpu_desc = p_desc;
+
+  /* 16bit offset address. */
+
+  eth_out32(EIM_CPU_TXBA_REG, (unsigned long)((unsigned long)(p_desc)&0x0000ffff));
+  for (i = NUM_DESC_TX-1; i >= 0; i--)
+    {
+      if (i == 0)
+	val = EIM_DESC_WRAP;
+      else
+	val = 0x0000;
+      val |= EIM_DESC_OWNER_HOST | EIM_DESC_INTEN | EIM_DESC_PADCRC | EIM_DESC_PACKET_BYTES;
+      eth_out32(p_desc, val);
+      p_desc++;
+      eth_out32(p_desc, (unsigned long)p_buf);
+      p_desc++;
+      *((unsigned long *)p_buf) = 0x00000000;
+      p_buf += EIM_DESC_PACKET_BYTES;
+      *((unsigned long *)p_buf) = 0x00000000;
+
+      /* As per C5471 doc; this space for Ether Module's "Buffer Usage Word". */
+
+      p_buf += 4;
+    }
+  
+  /* RX CPU */
+
+  current_rx_cpu_desc = p_desc;
+
+  /* 16bit offset address. */
+
+  eth_out32(EIM_CPU_RXBA_REG, (unsigned long)((unsigned long)(p_desc)&0x0000ffff));
+  for (i=NUM_DESC_RX-1; i>=0; i--)
+    {
+      if (i == 0)
+	val = EIM_DESC_WRAP;
+      else
+	val = 0x0000;
+      val |= EIM_DESC_OWNER_ESM | EIM_DESC_INTEN | EIM_DESC_PADCRC | EIM_DESC_PACKET_BYTES;
+      eth_out32(p_desc, val);
+      p_desc++;
+      eth_out32(p_desc, (unsigned long)p_buf);
+      p_desc++;
+      *((unsigned long *)p_buf) = 0x0000;
+      p_buf += EIM_DESC_PACKET_BYTES;
+      *((unsigned long *)p_buf) = 0x0000;
+
+      /* As per C5471 doc; this space for Ether Module's "Buffer Usage Word". */
+
+      p_buf += 4;
+    }
+#endif
+  
+  eth_out32(EIM_BUFSIZE_REG      , EIM_DESC_PACKET_BYTES);
+#if 0
+  eth_out32(EIM_CPU_FILTER_REG   , EIM_FILTER_UNICAST);
+#else
+
+  /* eth_out32(EIM_CPU_FILTER_REG   ,0x08 | EIM_FILTER_UNICAST | EIM_FILTER_MULTICAST | EIM_FILTER_BROADCAST); */
+
+  eth_out32(EIM_CPU_FILTER_REG   , EIM_FILTER_MULTICAST | EIM_FILTER_BROADCAST | EIM_FILTER_UNICAST);
+#endif
+
+  /* 0 == all ethernet interrupts disabled. */
+
+  eth_out32(EIM_INT_EN_REG       , 0x00000000);
+#if 1  
+#ifdef ETH_C5471_USE_ESM
+  eth_out32(EIM_CTRL_REG         , EIM_CTRL_ENET0_EN  |
+	   EIM_CTRL_ENET0_RXEN | EIM_CTRL_ENET0_TXEN |
+	   EIM_CTRL_CPU_RXEN   | EIM_CTRL_CPU_TXEN);
+#else
+  eth_out32(EIM_CTRL_REG         , EIM_CTRL_ENET0_EN  |
+	   EIM_CTRL_ENET0_RXEN | EIM_CTRL_ENET0_TXEN);
+#endif
+#else  
+  eth_out32(EIM_CTRL_REG         , EIM_CTRL_ENET1_DIS  | EIM_CTRL_ENET0_FLW  |
+	   EIM_CTRL_ENET0_RXEN | EIM_CTRL_ENET0_TXEN |
+	   EIM_CTRL_CPU_RXEN   | EIM_CTRL_CPU_TXEN);
+#endif
+#if 1  
+  eth_out32(EIM_MFVHI_REG        , 0x00000000);
+#else
+  eth_out32(EIM_MFVHI_REG        , 0x0000ff00);
+#endif  
+  eth_out32(EIM_MFVLO_REG        , 0x00000000);
+  eth_out32(EIM_MFMHI_REG        , 0x00000000);
+  eth_out32(EIM_MFMLO_REG        , 0x00000000);
+  eth_out32(EIM_RXTH_REG         , 0x00000018);
+  eth_out32(EIM_CPU_RXRDY_REG    , 0x00000000);
+#if 1
+  eth_out32(ENET0_MODE_REG       , ENET0_MODE_RJCT_SFE | ENET0_MODE_MWIDTH |
+	   ENET0_MODE_FULLDUPLEX);
+#else
+  eth_out32(ENET0_MODE_REG       , ENET0_MODE_RJCT_SFE | ENET0_MODE_MWIDTH |
+	   ENET0_MODE_HALFDUPLEX);
+#endif  
+  eth_out32(ENET0_BOFFSEED_REG   , 0x00000000);
+  eth_out32(ENET0_FLWPAUSE_REG   , 0x00000000);
+  eth_out32(ENET0_FLWCONTROL_REG , 0x00000000);
+  eth_out32(ENET0_VTYPE_REG      , 0x00000000);
+#if 0  
+  eth_out32(ENET0_ADRMODE_EN_REG , ENET_ADR_BROADCAST | ENET_ADR_PROMISCUOUS);
+#else
+
+  /* The CPU port is not PROMISCUOUS, it wants a no-promiscuous address
+   * match yet the the SWITCH receives packets from the PROMISCUOUS ENET0
+   * which routes all packets for filter matching at the CPU port which
+   * then allows the s/w to see the new incoming packetes that passed
+   * the filter. Here we are setting the main SWITCH closest the ether
+   * wire.
+   */
+
+  eth_out32(ENET0_ADRMODE_EN_REG , ENET_ADR_PROMISCUOUS);
+#endif  
+  eth_out32(ENET0_DRP_REG        , 0x00000000);
+
+#if 1  
+  {
+    int i;
+    for (i = 0; i < 2000000; i++);
+  }
+#endif  
+}
+
+static const unsigned char hextable[256] = {
+  255, 255, 255, 255, 255, 255, 255, 255, 
+  255, 255, 255, 255, 255, 255, 255, 255,
+
+  255, 255, 255, 255, 255, 255, 255, 255, 
+  255, 255, 255, 255, 255, 255, 255, 255,
+
+  255, 255, 255, 255, 255, 255, 255, 255, 
+  255, 255, 255, 255, 255, 255, 255, 255,
+
+  0,   1,   2,   3,   4,   5,   6,   7,   
+  8,   9, 255, 255, 255, 255, 255, 255,
+
+  255,  10,  11,  12,  13,  14,  15, 255, 
+  255, 255, 255, 255, 255, 255, 255, 255,
+
+  255, 255, 255, 255, 255, 255, 255, 255, 
+  255, 255, 255, 255, 255, 255, 255, 255,
+
+  255,  10,  11,  12,  13,  14,  15, 255, 
+  255, 255, 255, 255, 255, 255, 255, 255,
+
+  255, 255, 255, 255, 255, 255, 255, 255, 
+  255, 255, 255, 255, 255, 255, 255, 255,
+
+  255, 255, 255, 255, 255, 255, 255, 255, 
+  255, 255, 255, 255, 255, 255, 255, 255,
+
+  255, 255, 255, 255, 255, 255, 255, 255, 
+  255, 255, 255, 255, 255, 255, 255, 255,
+
+  255, 255, 255, 255, 255, 255, 255, 255, 
+  255, 255, 255, 255, 255, 255, 255, 255,
+
+  255, 255, 255, 255, 255, 255, 255, 255, 
+  255, 255, 255, 255, 255, 255, 255, 255,
+
+  255, 255, 255, 255, 255, 255, 255, 255, 
+  255, 255, 255, 255, 255, 255, 255, 255,
+
+  255, 255, 255, 255, 255, 255, 255, 255, 
+  255, 255, 255, 255, 255, 255, 255, 255,
+
+  255, 255, 255, 255, 255, 255, 255, 255, 
+  255, 255, 255, 255, 255, 255, 255, 255,
+
+  255, 255, 255, 255, 255, 255, 255, 255, 
+  255, 255, 255, 255, 255, 255, 255, 255,
+};
+
+/***********************************************************************
+ * eth_ascii_to_bin
+ ***********************************************************************/
+
+static unsigned char eth_ascii_to_bin(unsigned char c)
+{
+  return hextable[c];
+}
+
+/***********************************************************************
+ * eth_hexstrtobyte
+ ***********************************************************************/
+
+/* Incoming string is assumed to be a hex numeric string
+ * (without the 0x prefix) whos converted value will fit within
+ * a single byte.  example "1", "ff", "7d", "22", etc.
+ */
+
+static unsigned char eth_hexstrtobyte(char *str)
+{
+  unsigned short retval;
+  int len;
+  retval = 0;
+  len = eth_strlen(str);
+  if (2 == len)
+    {
+      retval += (unsigned short)(eth_ascii_to_bin(str[0])*0x10);
+      retval += (unsigned short)(eth_ascii_to_bin(str[1]));
+    }
+  else if (1 == len)
+    {
+      retval += (unsigned short)(eth_ascii_to_bin(str[0]));
+    }
+  else
+    {
+      panic("Logic Error");
+    }
+  if (retval > 0x00FF)
+    {
+      panic("Logic Error");
+    }
+  return (unsigned char)retval;
+}
+
+/***********************************************************************
+ * eth_fill_mac
+ ***********************************************************************/
+
+/* Input string is expected to be in standard MAC format;
+ * x:x:x:x:x:x, where x can be up to two numeric hex characters.
+ * example. "ff:0:e0:10:c:22" This call will convert the incoming
+ * string into a series of numeric values which are loaded into
+ * the callers supplied array; mac_array[0] through mac_array[5].
+ */
+
+#define MIN_MAC 11
+#define MAX_MAC 17
+
+static void eth_fill_mac(unsigned char *mac_array, char *MAC_str)
+{
+  /* example MAC: 1:2:3:4:5:6 (11 chars).
+   * example MAC: 10:20:30:40:50:60 (17 chars).
+  */
+
+  char str[MAX_MAC+1];
+  int i;
+  unsigned char bval;
+  unsigned char *start;
+  unsigned char *end;
+  bval = 0;
+  if (eth_strlen(MAC_str) < MIN_MAC) return;
+  if (eth_strlen(MAC_str) > MAX_MAC) return;
+
+ /* get a local writable copy. */
+
+  eth_strcpy(str,MAC_str);
+  end = str;
+  start = end;
+  for (i = 0; i < 6; i++)
+    {
+      if (i < 5)
+	{
+	  while (*end != ':') end++;
+
+	  /* replace the ':' with a 0 to terminate the string. */
+
+	  *end = 0;
+	}
+      bval = eth_hexstrtobyte(start);
+      mac_array[i] = bval;
+      end++;
+      start = end;
+    }
+}
+
+/***********************************************************************
+ * eth_mac_is_null
+ ***********************************************************************/
+
+static int eth_mac_is_null(unsigned char *mac_array)
+{
+  int i, ret_val;
+  ret_val = 1;
+  for (i=0; i<6; i++)
+    {
+      if (mac_array[i] != 0x00)
+	{
+	  ret_val = 0;
+	  break;
+	}
+    }
+  return ret_val;
+}
+
+/***********************************************************************
+ * eth_mac_assign
+ ***********************************************************************/
+
+/* Set the mac address of our CPU ether port so that when
+ * the SWITCH receives packets from the PROMISCUOUS ENET0
+ * it will switch them to the CPU port and cause a packet
+ * arrival event on the Switch's CPU TX queue when an address
+ * match occurs. The CPU port is not PROMISCUOUS and wants to
+ * see only packets specifically addressed to this device.
+ */
+
+static void eth_mac_assign(unsigned char *mac_array)
+{
+  /* Set CPU port mac address. s/w will only see
+   * incoming packets that match this destination address.
+  */
+
+  eth_out32(EIM_CPU_DAHI_REG, ((mac_array[0] << 8)  |
+			     (mac_array[1])));
+  eth_out32(EIM_CPU_DALO_REG, ((mac_array[2] << 24) |
+			     (mac_array[3] << 16) |
+			     (mac_array[4] << 8)  |
+			     (mac_array[5])));
+  
+  /* Set ENET port mac address.
+   * incoming packets that match this destination address.
+   * Except for multicast, ENET runs in PROMISCUOUS mode,
+   * so these are only used to filter packets when in multicast
+   * hast table mode (which is different than multicast
+   * accept all mode which runs the ENET in PROMISCUOUS
+     mode).
+   */
+
+  eth_out32(ENET0_PARHI_REG, ((mac_array[0] << 8)  |
+			     (mac_array[1])));
+  eth_out32(ENET0_PARLO_REG, ((mac_array[2] << 24) |
+			     (mac_array[3] << 16) |
+			     (mac_array[4] << 8)  |
+			     (mac_array[5])));
+}
+
+#ifdef ETH_C5471_USE_ESM
+/***********************************************************************
+ * eth_incr_tx_cpu_desc
+ ***********************************************************************/
+
+static void eth_incr_tx_cpu_desc(void)
+{
+  if (EIM_DESC_WRAP & eth_in32(current_tx_cpu_desc))
+    {
+      /* Loop back around to base of descriptor queue. */
+
+      current_tx_cpu_desc = (unsigned long *)(eth_in32(EIM_CPU_TXBA_REG)
+					      + EIM_RAM_START);
+    }
+  else
+    {
+      current_tx_cpu_desc+=2;
+    }
+}
+  
+/***********************************************************************
+ * incr_rx_cpu_desc
+ ***********************************************************************/
+
+static void incr_rx_cpu_desc(void)
+{
+  if (EIM_DESC_WRAP & eth_in32(current_rx_cpu_desc))
+    {
+      /* Loop back around to base of descriptor queue. */
+
+      current_rx_cpu_desc = (unsigned long *)(eth_in32(EIM_CPU_RXBA_REG)
+					      + EIM_RAM_START);
+    }
+  else
+    {
+      current_rx_cpu_desc+=2;
+    }
+}
+
+#else
+
+/***********************************************************************
+ * eth_incr_tx_cpu_desc
+ ***********************************************************************/
+
+static void eth_incr_tx_enet0_desc(void)
+{
+  if (EIM_DESC_WRAP & eth_in32(current_tx_enet0_desc))
+    {
+      /* Loop back around to base of descriptor queue. */
+
+      current_tx_enet0_desc = (unsigned long *)(eth_in32(ENET0_TDBA_REG)
+					      + EIM_RAM_START);
+    }
+  else
+    {
+      current_tx_enet0_desc+=2;
+    }
+}
+  
+/***********************************************************************
+ * incr_rx_cpu_desc
+ ***********************************************************************/
+
+static void incr_rx_enet0_desc(void)
+{
+  if (EIM_DESC_WRAP & eth_in32(current_rx_enet0_desc))
+    {
+      /* Loop back around to base of descriptor queue. */
+
+      current_rx_enet0_desc = (unsigned long *)(eth_in32(ENET0_RDBA_REG)
+					      + EIM_RAM_START);
+    }
+  else
+    {
+      current_rx_enet0_desc+=2;
+    }
+}
+#endif
+  
+/***********************************************************************
+ * eth_tx_errors
+ ***********************************************************************/
+
+int eth_tx_errors(void)
+{
+  int more;
+  long *Descriptor_p = last_packet_desc_start;
+
+  /* Note:
+   * We walk that last packet we just sent to collect up
+   * xmit status bits.
+   */
+
+  if (last_packet_desc_start && last_packet_desc_end)
+    {
+      more = 1;
+      cached_tx_status = 0;
+      while (more)
+	{
+	  cached_tx_status |= (eth_in32(Descriptor_p)&0x007f0000);
+	  if (Descriptor_p == last_packet_desc_end)
+	    {
+	      more = 0;
+	    }
+
+	  /* This packet is made up of several descriptors;
+	   * Find next one in chain. */
+
+	  if (EIM_DESC_WRAP & eth_in32(Descriptor_p))
+	    {
+
+	      /* Loop back around to base of descriptor queue. */
+
+	      Descriptor_p = (unsigned long *)(eth_in32(EIM_CPU_RXBA_REG)+EIM_RAM_START);
+	    }
+	  else
+	    {
+	      Descriptor_p+=2;
+	    }
+	}
+    }
+  
+  if (cached_tx_status)
+    {
+      return 1;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+/***********************************************************************
+ * eth_tx_window_errors
+ ***********************************************************************/
+
+int eth_tx_window_errors(void)
+{
+  if ((TXSTATUS_RETRY_BIT     & cached_tx_status) ||
+      (TXSTATUS_UNDER_BIT     & cached_tx_status) ||
+      (TXSTATUS_CRC_BIT       & cached_tx_status) ||
+      (TXSTATUS_COLLISION_BIT & cached_tx_status) ||
+      (TXSTATUS_LATE_COL_BIT  & cached_tx_status))
+    {
+      return 1;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+/***********************************************************************
+ * eth_tx_heartbeat_errors
+ ***********************************************************************/
+
+int eth_tx_heartbeat_errors(void)
+{
+  if (TXSTATUS_HEART_BIT & cached_tx_status)
+    {
+      return 1;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+/***********************************************************************
+ * eth_tx_fifo_errors
+ ***********************************************************************/
+
+int eth_tx_fifo_errors(void)
+{
+  return 0;
+}
+
+/***********************************************************************
+ * eth_tx_carrier_errors
+ ***********************************************************************/
+
+int eth_tx_carrier_errors(void)
+{
+  if (TXSTATUS_LOSS_BIT & cached_tx_status)
+    {
+      return 1;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+/***********************************************************************
+ * eth_tx_aborted_errors
+ ***********************************************************************/
+
+int eth_tx_aborted_errors(void)
+{
+  return 0;
+}
+
+/***********************************************************************
+ * eth_rx_missed_errors
+ ***********************************************************************/
+
+int eth_rx_missed_errors(void)
+{
+  if (RXSTATUS_MISS_BIT & cached_rx_status)
+    {
+      return 1;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+/***********************************************************************
+ * eth_rx_fifo_errors
+ ***********************************************************************/
+
+int eth_rx_fifo_errors(void)
+{
+  return 0;
+}
+
+/***********************************************************************
+ * eth_rx_frame_errors
+ ***********************************************************************/
+
+int eth_rx_frame_errors(void)
+{
+  if ((RXSTATUS_LONG_BIT & cached_rx_status) ||
+      (RXSTATUS_SHORT_BIT & cached_rx_status))
+    {
+      return 1;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+/***********************************************************************
+ * eth_rx_crc_errors
+ ***********************************************************************/
+
+int eth_rx_crc_errors(void)
+{
+  if (RXSTATUS_CRC_BIT & cached_rx_status)
+    {
+      return 1;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+/***********************************************************************
+ * eth_rx_over_errors
+ ***********************************************************************/
+
+int eth_rx_over_errors(void)
+{
+  if (RXSTATUS_OVER_BIT & cached_rx_status)
+    {
+      return 1;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+/***********************************************************************
+ * eth_rx_length_errors
+ ***********************************************************************/
+
+int eth_rx_length_errors(void)
+{
+  if ((RXSTATUS_VLAN_BIT & cached_rx_status) ||
+      (RXSTATUS_ALIGN_BIT & cached_rx_status))
+    {
+      return 1;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+/***********************************************************************
+ * eth_rx_errors
+ ***********************************************************************/
+
+int eth_rx_errors(void)
+{
+  if (cached_rx_status)
+    {
+      return 1;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+/***********************************************************************
+ * eth_recv_int_active
+ ***********************************************************************/
+
+int eth_recv_int_active(void)
+{
+	eim_status_shadow = eth_in32(EIM_STATUS_REG);
+
+  	if ((EIM_CPU_TX_INT | EIM_ENET0_RX_INT) & eim_status_shadow)
+    {
+      /* An in coming packet has been received by
+       * the EIM from the network and the interrupt
+       * associated with EIM's CPU TX que has been
+       * asserted. Rememeber that it is the EIM's CPU
+       * TX que that we need to read from to get those
+       * packets *into* the linux system.
+       * This may seem a bit backwards to you but we
+       * are keeping this terminology to stay consistent
+       * with the C5471 documentation.
+       */
+
+      	return 1;
+    }
+  	else
+    {
+      	return 0;
+    }
+}
+
+/***********************************************************************
+ * eth_xmit_int_active
+ ***********************************************************************/
+
+int eth_xmit_int_active(void)
+{
+  /* Unfortunately with this platform the HW status
+   * we need is implemented in a clear-on-read register.
+   * We'll refrain from referencing the HW register
+   * here since we happen to *know* that the client
+   * will always ask about the recv_int *prior* to the
+   * xmit_int and hence our shadow value here has the
+   * current bits we need to test. Yes, this impl is
+   * dependent on the *particular* usage model we know
+   * our client (generic_ether.c) is using. I really 
+   * dislike clear-on-read HW registers.
+   */
+
+  	if ((EIM_CPU_RX_INT | EIM_ENET0_TX_INT) & eim_status_shadow)
+    {
+      /* An outgoing packet has been processed by
+       * the EIM and the interrupt associated with
+       * EIM's CPU RX que has been asserted. Rememeber
+       * that it is the EIM's CPU RX que that we put
+       * packets on to send them *out*. This may seem a
+       * bit backwards to you but we are keeping this
+       * terminology to stay consistent with the C5471
+       * documentation.
+       */
+
+      	return 1;
+    }
+  	else
+    {
+      	return 0;
+    }
+}
+
+/***********************************************************************
+ * eth_get_default_MAC
+ ***********************************************************************/
+
+void eth_get_default_MAC(unsigned char *mac_array)
+{
+  int got_mac = 0;
+
+  /* Ether MAC string deposited by bootloader to IRAM.  */
+
+  if (0 == *(__EtherMACMagicStr+eth_strlen("etherMAC-->")))
+    {
+      /* okay, looks reasonable so far, do final comparison. */
+
+      if (0 == eth_strcmp(__EtherMACMagicStr,"etherMAC-->"))
+	{
+	  /* okay, the magic string is there so we can assume that
+	   * the invoker of the linux kernel has deposited a MAC
+	   * string next -- even if only a NULL string.
+	   */
+
+	  if (0 != *(__EtherMAC))
+	    {
+	      /* the MAC string is not NULL so we'll use it
+	       * as our default MAC address.
+	       */
+
+	      eth_fill_mac(mac_array,__EtherMAC);
+	      got_mac = 1;
+	    }
+	}
+    }
+  if (!got_mac)
+    {
+      /* We didn't get a MAC from the bootloader so
+       * use the default hardcoded value as a last resort.
+       */
+
+      warn("Mac address normally deposited by bootloader was not found");
+#if 1  
+      warn("Resorting to internally coded default");
+      mac_array[0] = 0x00;
+      mac_array[1] = 0x60;
+      mac_array[2] = 0x54;
+      mac_array[3] = 0xbe;
+      mac_array[4] = 0xfa;
+      mac_array[5] = 0xce;
+#endif
+    }
+}
+
+/***********************************************************************
+ * eth_set_MAC
+ ***********************************************************************/
+
+void eth_set_MAC(unsigned char *mac_array)
+{
+  int i;
+  for (i = 0; i < 6; i++)
+    {
+      d_MAC[i] = mac_array[i];
+    }
+}
+
+/***********************************************************************
+ * eth_multicast_accept_multicast
+ ***********************************************************************/
+
+void eth_multicast_accept_multicast(void)
+{
+  /* valid Ethernet MAC multicast address range
+     01:00:00:00:00:00 - 01:FF:FF:FF:FF:FF
+
+     based on MFV0/MFV1 description on pg 12-39 and
+              MFM0/MFM1 description on pg 12-40
+
+     I believe the hardware "ands" the destination address (DA)
+     of the incoming packet with MFM0/MFM1 and then compares the
+     result with MFV0/MFV1.  If the compare is an exact match, 
+     then the packet is accepted as a multicast packet.
+
+     set MFM to 01:00:00:00:00:00
+     set MFV to 01:00:00:00:00:00
+    
+     this should accept all DAs with the low order bit in the 
+     high-order octet - bit 40.
+  */
+
+  eth_out32(EIM_MFVHI_REG        ,0x00000100);
+  eth_out32(EIM_MFVLO_REG        ,0x00000000);
+
+  eth_out32(EIM_MFMHI_REG        ,0x00000100);
+  eth_out32(EIM_MFMLO_REG        ,0x00000000);
+}
+
+/***********************************************************************
+ * eth_multicast_promiscuous
+ ***********************************************************************/
+
+void eth_multicast_promiscuous(void)
+{
+  /* Note: TF 08/21/03
+     This probably won't work because the earlier version of the
+     driver was configured with the MFM and MFV registers set to
+     zero and multicast enabled in the CPU filter register.  See
+     the eth_eim_specific_config() routine above.
+
+     Use multicast filter to filter all packets to go though at the
+     CPU level.  This is done because I don't know how else to
+     enable promiscuous at the CPU level.
+
+     I believe the hardware "ands" the destination address (DA)
+     of the incoming packet with MFM0/MFM1 and then compares the
+     result with MFV0/MFV1.  If the compare is an exact match, 
+     then the packet is accepted.
+
+     set MFM to 00:00:00:00:00:00
+     set MFV to 00:00:00:00:00:00
+    
+     this should accept all DAs.
+  */
+
+  eth_out32(EIM_MFVHI_REG        ,0x00000000);
+  eth_out32(EIM_MFVLO_REG        ,0x00000000);
+
+  eth_out32(EIM_MFMHI_REG        ,0x00000000);
+  eth_out32(EIM_MFMLO_REG        ,0x00000000);
+}
+
+/***********************************************************************
+ * eth_set_hast_multicast
+ ***********************************************************************/
+
+void eth_set_hast_multicast(long hash_table)
+{
+  int i;
+  i = (hash_table & 0xFFFF0000) >> 16;
+  eth_out32(ENET0_LARHI_REG, i);
+  i = (hash_table & 0xFFFF);
+  eth_out32(ENET0_LARLO_REG, i);
+}
+
+/***********************************************************************
+ * eth_set_addressing
+ ***********************************************************************/
+
+void eth_set_addressing(int eim_addr)
+{
+  eth_out32(ENET0_ADRMODE_EN_REG, eim_addr);
+}
+
+/***********************************************************************
+ * eth_set_filter
+ ***********************************************************************/
+
+void eth_set_filter(int cpu_fltr)
+{
+  eth_out32(EIM_CPU_FILTER_REG, cpu_fltr);
+}
+
+/***********************************************************************
+ * eth_turn_on_ethernet
+ ***********************************************************************/
+
+void eth_turn_on_ethernet(void)
+{
+  volatile unsigned long clearbits;
+
+  dbg("Begin Ethernet HW setup");
+  dbg("EIM reset");
+
+  eth_eim_reset();
+
+  dbg("PHY init");
+
+  eth_phy_init();
+
+  dbg("EIM config");
+
+  eth_eim_specific_config();
+
+  dbg("MAC assign");
+
+  if (eth_mac_is_null(d_MAC))
+    {
+      /* load d_MAC with either the default MAC */
+
+      eth_get_default_MAC(d_MAC);
+
+      /* passed to us from the bootloader or
+       * possibly uses a special on-board serial 
+       * eeprom to located the board's MAC.
+       */
+    }
+  eth_mac_assign(d_MAC);
+
+  /* Next, enable interrupts going from EIM Module to Interrupt Module. */
+
+  /* dummy read of clear-on-read register. */
+
+  clearbits = eth_in32(EIM_STATUS_REG);
+#ifdef ETH_C5471_USE_ESM
+  eth_out32(EIM_INT_EN_REG, (eth_in32(EIM_INT_EN_REG) | EIM_CPU_TX_INT | EIM_CPU_RX_INT));
+#else
+  eth_out32(EIM_INT_EN_REG, (eth_in32(EIM_INT_EN_REG) | EIM_ENET0_TX_INT | EIM_ENET0_RX_INT | EIM_ENET0_ERR_INT));
+#endif
+
+  /* Next, go on-line.
+   * According to the C5471 documentation the enables have to occur
+   * in this order to insure proper operation; SWITCH first then the
+   * ENET.
+   */
+
+  dbg("EIM on-line");
+
+  /* enable SWITCH */
+
+#ifdef ETH_C5471_USE_ESM
+  eth_out32(EIM_CTRL_REG, (eth_in32(EIM_CTRL_REG) | EIM_CTRL_ESM_EN));
+#endif
+
+  /* enable ENET */
+
+  eth_out32(ENET0_MODE_REG, (eth_in32(ENET0_MODE_REG) | ENET0_MODE_ENABLE));
+  dbg("Ethernet HW setup complete");
+  return;
+}
+
+/***********************************************************************
+ * eth_turn_off_ethernet
+ ***********************************************************************/
+
+void eth_turn_off_ethernet(void)
+{
+  /* Next, disable interrupts going from EIM Module to Interrupt Module. */
+
+#ifdef ETH_C5471_USE_ESM
+  eth_out32(EIM_INT_EN_REG, (eth_in32(EIM_INT_EN_REG) & ~EIM_CPU_TX_INT & ~EIM_CPU_RX_INT));
+#else
+  eth_out32(EIM_INT_EN_REG, (eth_in32(EIM_INT_EN_REG) & ~(EIM_ENET0_TX_INT | EIM_ENET0_RX_INT | EIM_ENET0_ERR_INT)));
+#endif
+
+  /* Next, go off-line. */
+  /* disable ENET */
+  eth_out32(ENET0_MODE_REG, (eth_in32(ENET0_MODE_REG) & ~ENET0_MODE_ENABLE));
+
+  /* disable SWITCH */
+  eth_out32(EIM_CTRL_REG, (eth_in32(EIM_CTRL_REG) & ~EIM_CTRL_ESM_EN));
+  return;
+}
+
+
+#ifdef ETH_C5471_USE_ESM
+
+/***********************************************************************
+ * eth_get_received_packet_len
+ ***********************************************************************/
+
+void eth_get_received_packet_len(int *numbytes)
+{
+  int more, bytelen;
+  unsigned int packetlen = 0;
+  long *Descriptor_p = current_tx_cpu_desc;
+
+  /* We walk the packet contained within the EIM
+   * to add up the number of bytes contained
+   * in the packet. We don't actually pull the
+   * packet out of HW at this point. We're just
+   * looking in to see how long the packet is.
+   */
+
+  cached_rx_status = 0;
+  more = 1;
+  while (more)
+    {
+      if (EIM_DESC_OWNER_DEVICE & eth_in32(Descriptor_p))
+	{
+	  /* words #0 and #1 of descriptor
+	   * The incoming packe queue is empty. There are no more
+	   * packets for the INET subsystem to process. Indicate this
+	   * with a packet len of zero.
+	   */
+
+	  *numbytes = 0;
+	  return;
+	}
+
+      cached_rx_status |= (eth_in32(Descriptor_p)&0x007f0000);
+      bytelen = (eth_in32(Descriptor_p)&0x000007ff);
+      packetlen += bytelen;
+
+      if (eth_in32(Descriptor_p) & EIM_DESC_LIF)
+	{
+	  more = 0;
+	}
+
+      /* This packet is made up of several descriptors;
+       * Find next one in chain.
+       */
+
+      if (EIM_DESC_WRAP & eth_in32(Descriptor_p))
+	{
+	  /* Loop back around to base of descriptor queue. */
+
+	  Descriptor_p = (unsigned long *)(eth_in32(EIM_CPU_TXBA_REG)+EIM_RAM_START);
+	}
+      else
+	{
+	  Descriptor_p+=2;
+	}
+    }
+
+  /* Next, We know that this routine is used by the client to 
+   * allocate memory for the actual packet and we know that
+   * our packet transfer algorithm in eth_get_received_packet_data()
+   * may overshoot by "ROUNDUP" amount of bytes so adjust the
+   * length here to insure that the client allocates a buffer
+   * big enough to allow us to perform the packet xfer with its
+   * potential overshoot.
+   */
+
+  *numbytes = packetlen+ROUNDUP;
+  return;
+}
+
+/***********************************************************************
+ * eth_get_received_packet_data
+ ***********************************************************************/
+
+void eth_get_received_packet_data(unsigned char *buf, int *numbytes)
+{
+  unsigned short bytelen, numshorts, more, i, j;
+  unsigned int packetlen;
+  unsigned short *packetmem;
+
+  j = bytelen = packetlen = 0;
+
+  /* We walk the newly received packet contained within 
+   * the EIM and transfer its contents to the client supplied
+   * buffer. This frees up the memory contained within
+   * the EIM for additional packets that might be received
+   * later from the network.
+   */
+
+  more = 1;
+  while (more)
+    {
+      if (EIM_DESC_OWNER_DEVICE & eth_in32(current_tx_cpu_desc))
+	{
+	  /* words #0 and #1 of descriptor
+	   *
+	   * We don't ever expect to get here. If we do it means that
+	   * the client thought we had an incoming packet to process
+	   * and yet we see now that there isn't one. So, construct
+	   * a default answer and let the upper layers of the system sort
+	   * out the confusion.
+	   */
+
+	  err("LOGIC Error! eth_get_received_packet_data()");
+
+	  /* return a null packet. */
+
+	  memset(buf,0,*numbytes);
+	  return;
+	}
+      bytelen = (eth_in32(current_tx_cpu_desc)&0x000007ff);
+      packetlen += bytelen;
+
+      /* words #2 and #3 of descriptor */
+
+      packetmem = (unsigned short *)eth_in32(current_tx_cpu_desc+1);
+
+      /* divide by 2 with round up. */
+
+      numshorts = (bytelen+ROUNDUP)>>1;
+      for (i=0; i<numshorts; i++, j++)
+	{
+	  /* 16bits at a time. */
+
+	  ((unsigned short *)buf)[j] = __swap_16(packetmem[i]);
+	}
+      if (eth_in32(current_tx_cpu_desc) & EIM_DESC_LIF)
+	{
+	  more = 0;
+	}
+
+      /* Next, Clear all bits of words0/1 of the emptied descriptor
+       * except preserve the settings of a select few. Can
+       * leave descriptor words 2/3 alone.
+       */
+
+      eth_out32(current_tx_cpu_desc, (eth_in32(current_tx_cpu_desc) & (EIM_DESC_WRAP | EIM_DESC_INTEN)));
+
+      /* Next, Give ownership of now emptied descriptor
+       * back to the Ether Module's SWITCH.
+       */
+
+      eth_out32(current_tx_cpu_desc, (eth_in32(current_tx_cpu_desc) | EIM_DESC_OWNER_DEVICE));
+      eth_incr_tx_cpu_desc(); /* advance; to find our next data buffer. */
+    }
+
+  /* Next, adjust the length to remove the crc bytes that we know the
+   * client doesn't care about. I suspect the crc bytes would be ignored
+   * anyway by the Kernel's INET subsystem but I notice that some eth
+   * drivers for other platforms (DSC21) don't deliver the crc bytes
+   * so for consistency I'll remove them here too.
+   */
+
+  *numbytes = packetlen - 4;
+  return;
+}
+
+/***********************************************************************
+ * eth_send_packet
+ ***********************************************************************/
+
+/* Use the HW to send the supplied Ether buffer out the board's network
+ * cable. We'll rely on the HW to supply the CRC of the packet as well as
+ * any necessary retrys required due to normal network collisions, etc.
+ */
+
+void eth_send_packet(unsigned char *buf, int numbytes)
+{
+  	unsigned int i, j, FirstFrame;
+  	unsigned short bytelen, numshorts;
+  	unsigned short *packetmem;
+	unsigned long cached_desc;
+
+  	j = 0;
+  	FirstFrame = 1;
+	last_packet_desc_start = current_rx_cpu_desc;
+
+	while (numbytes)
+  	{
+      	while (EIM_DESC_OWNER_DEVICE & eth_in32(current_rx_cpu_desc))
+		{
+	  		/* words #0 and #1 of descriptor
+	  		 * loop until the SWITCH lets go of the descriptor
+	  		 * giving us access rights to submit our new ether
+	  		 * frame to it.
+	  		 * do_delay(1000);
+	  		 */
+		}
+
+	    if (numbytes >= EIM_DESC_PACKET_BYTES)
+		{
+			bytelen = EIM_DESC_PACKET_BYTES;
+		}
+	    else
+		{
+			bytelen = numbytes;
+		}
+
+	    /* Next, submit ether frame bytes to the C5472 Ether Module packet
+	     * memory space.
+	     */
+
+	    /* divide by 2 with round up. */
+	    numshorts = (bytelen+1)>>1;
+
+    	/* words #2 and #3 of descriptor */
+	    packetmem = (unsigned short *)eth_in32(current_rx_cpu_desc+1);
+    	for (i=0; i<numshorts; i++, j++)
+		{
+			/* 16bits at a time. */
+			packetmem[i] = __swap_16(((unsigned short *)buf)[j]);
+		}
+
+		cached_desc = (eth_in32(current_rx_cpu_desc) & EIM_DESC_BYTES_MASK) | bytelen | EIM_DESC_INTEN;
+
+	    numbytes -= bytelen;
+	    if (0 == numbytes)
+		{
+			cached_desc |= (EIM_DESC_LIF | EIM_DESC_INTEN);
+		}
+	    else
+		{
+			cached_desc &= (~(EIM_DESC_LIF /*| EIM_DESC_INTEN*/));
+		}
+
+	    if (FirstFrame)
+		{
+			cached_desc |= (EIM_DESC_FIF | EIM_DESC_PADCRC);
+		}
+	    else
+		{
+			cached_desc &= (~(EIM_DESC_FIF | EIM_DESC_PADCRC));
+		}
+
+	    eth_out32(current_rx_cpu_desc, cached_desc);
+
+		/* Next, We're done with that descriptor;
+    	 * give access rights back to HW. */
+	    eth_out32(current_rx_cpu_desc,
+		     (eth_in32(current_rx_cpu_desc) | EIM_DESC_OWNER_DEVICE));
+
+	    last_packet_desc_end = current_rx_cpu_desc;
+    	incr_rx_cpu_desc(); /* advance to next free descriptor. */
+
+    	/* Next, tell Ether Module that those submitted bytes are ready
+	     * for the wire. */
+	   	eth_out32(EIM_CPU_RXRDY_REG, 0x00000001);
+    	FirstFrame = 0;
+	}
+
+  	return;
+}
+#else
+
+/***********************************************************************
+ * eth_get_received_packet_len
+ ***********************************************************************/
+
+void eth_get_received_packet_len(int *numbytes)
+{
+	int more, bytelen;
+	unsigned int packetlen = 0;
+	long *Descriptor_p = current_rx_enet0_desc;
+
+	/* We walk the packet contained within the EIM
+	 * to add up the number of bytes contained
+	 * in the packet. We don't actually pull the
+	 * packet out of HW at this point. We're just
+	 * looking in to see how long the packet is.
+	 */
+	cached_rx_status = 0;
+	more = 1;
+	while (more)
+  	{
+    	if ((EIM_DESC_OWNER_HOST & eth_in32(Descriptor_p)) == 0)
+		{
+		/* words #0 and #1 of descriptor
+		 * The incoming packe queue is empty. There are no more
+		 * packets for the INET subsystem to process. Indicate this
+		 * with a packet len of zero.
+		 */
+			*numbytes = 0;
+			return;
+		}
+
+	    cached_rx_status |= (eth_in32(Descriptor_p)&0x007f0000);
+    	bytelen = (eth_in32(Descriptor_p)&0x000007ff);
+	    packetlen += bytelen;
+
+    	if (eth_in32(Descriptor_p) & EIM_DESC_LIF)
+		{
+  			more = 0;
+		}
+
+	    /* This packet is made up of several descriptors;
+    	 * Find next one in chain.
+	     */	
+	    if (EIM_DESC_WRAP & eth_in32(Descriptor_p))
+		{
+		  	/* Loop back around to base of descriptor queue. */
+	  		Descriptor_p = (unsigned long *)(eth_in32(ENET0_RDBA_REG)+EIM_RAM_START);
+		}
+    	else
+		{
+  			Descriptor_p+=2;
+		}
+	}
+
+	/* Next, We know that this routine is used by the client to 
+	 * allocate memory for the actual packet and we know that
+	 * our packet transfer algorithm in eth_get_received_packet_data()
+	 * may overshoot by "ROUNDUP" amount of bytes so adjust the
+	 * length here to insure that the client allocates a buffer
+	 * big enough to allow us to perform the packet xfer with its
+	 * potential overshoot.
+	 */
+	*numbytes = packetlen+ROUNDUP;
+	return;
+}
+
+/***********************************************************************
+ * eth_get_received_packet_data
+ ***********************************************************************/
+
+void eth_get_received_packet_data(unsigned char *buf, int *numbytes)
+{
+	unsigned short bytelen, numshorts, more, i, j;
+	unsigned int packetlen;
+	unsigned short *packetmem;
+
+	j = bytelen = packetlen = 0;
+
+	/* We walk the newly received packet contained within 
+	 * the EIM and transfer its contents to the client supplied
+	 * buffer. This frees up the memory contained within
+	 * the EIM for additional packets that might be received
+	 * later from the network.
+	 */
+	more = 1;
+	while (more)
+  	{
+    	if ((EIM_DESC_OWNER_HOST & eth_in32(current_rx_enet0_desc)) == 0)
+		{
+		  /* words #0 and #1 of descriptor
+		   *
+		   * We don't ever expect to get here. If we do it means that
+		   * the client thought we had an incoming packet to process
+		   * and yet we see now that there isn't one. So, construct
+		   * a default answer and let the upper layers of the system sort
+		   * out the confusion.
+		   */
+
+			err("LOGIC Error! eth_get_received_packet_data()");
+
+		  /* return a null packet. */
+		  	memset(buf,0,*numbytes);
+		  	return;
+		}
+	    bytelen = (eth_in32(current_rx_enet0_desc)&0x000007ff);
+    	packetlen += bytelen;
+
+	    /* words #2 and #3 of descriptor */
+    	packetmem = (unsigned short *)eth_in32(current_rx_enet0_desc+1);
+
+	    /* divide by 2 with round up. */
+    	numshorts = (bytelen+ROUNDUP)>>1;
+	    for (i=0; i<numshorts; i++, j++)
+		{
+			/* 16bits at a time. */
+  			((unsigned short *)buf)[j] = __swap_16(packetmem[i]);
+		}
+
+	    if (eth_in32(current_rx_enet0_desc) & EIM_DESC_LIF)
+		{
+			more = 0;
+		}
+
+	    /* Next, Clear all bits of words0/1 of the emptied descriptor
+    	 * except preserve the settings of a select few. Can
+	     * leave descriptor words 2/3 alone.
+    	 */
+    	eth_out32(current_rx_enet0_desc, (EIM_DESC_PACKET_BYTES | (eth_in32(current_rx_enet0_desc) & (EIM_DESC_WRAP | EIM_DESC_INTEN))));
+
+    	/* Next, Give ownership of now emptied descriptor
+    	 * back to the Ether Module's ENET0.
+    	 */
+    	eth_out32(current_rx_enet0_desc, (eth_in32(current_rx_enet0_desc) & ~(EIM_DESC_OWNER_HOST)));
+    	incr_rx_enet0_desc(); /* advance; to find our next data buffer. */
+  	}
+
+	/* Next, adjust the length to remove the crc bytes that we know the
+	 * client doesn't care about. I suspect the crc bytes would be ignored
+	 * anyway by the Kernel's INET subsystem but I notice that some eth
+	 * drivers for other platforms (DSC21) don't deliver the crc bytes
+	 * so for consistency I'll remove them here too.
+	 */
+	*numbytes = packetlen - 4;
+	return;
+}
+
+
+/***********************************************************************
+ * eth_send_packet
+ ***********************************************************************/
+
+/* Use the HW to send the supplied Ether buffer out the board's network
+ * cable. We'll rely on the HW to supply the CRC of the packet as well as
+ * any necessary retrys required due to normal network collisions, etc.
+ */
+
+void eth_send_packet(unsigned char *buf, int numbytes)
+{
+	unsigned int i, j, FirstFrame;
+	unsigned short bytelen, numshorts;
+	unsigned short *packetmem;
+	unsigned long cached_desc;
+#ifdef ETH_C5471_ALL_DESC_AT_ONCE
+	long *tmp_packet_desc;
+#endif
+
+	j = 0;
+	FirstFrame = 1;
+#ifdef ETH_C5471_ALL_DESC_AT_ONCE
+	tmp_packet_desc = 
+#endif
+	last_packet_desc_start = current_tx_enet0_desc;
+
+	if (numbytes == 0) return;
+
+	while (numbytes)
+  	{
+    	while ((EIM_DESC_OWNER_HOST & eth_in32(current_tx_enet0_desc)) == 0)
+		{
+	  	/* words #0 and #1 of descriptor
+	   	 * loop until the ENET0 goes off the descriptor
+	  	 * giving us access rights to submit our new ether
+	  	 * frame to it.
+	  	 * do_delay(1000);
+	  	 */
+		}
+
+	    if (numbytes >= EIM_DESC_PACKET_BYTES)
+		{
+			bytelen = EIM_DESC_PACKET_BYTES;
+		}
+	    else
+		{
+			bytelen = numbytes;
+		}
+
+	    /* Next, submit ether frame bytes to the C5472 Ether Module packet
+	     * memory space.
+	     */
+
+	    /* divide by 2 with round up. */
+	    numshorts = (bytelen+1)>>1;
+
+    	/* words #2 and #3 of descriptor */
+	    packetmem = (unsigned short *)eth_in32(current_tx_enet0_desc+1);
+    	for (i=0; i<numshorts; i++, j++)
+		{
+			/* 16bits at a time. */
+			packetmem[i] = __swap_16(((unsigned short *)buf)[j]);
+		}
+
+		cached_desc = (eth_in32(current_tx_enet0_desc) & EIM_DESC_BYTES_MASK) | bytelen;
+
+	    numbytes -= bytelen;
+	    if (0 == numbytes)
+		{
+			cached_desc |= (EIM_DESC_LIF | EIM_DESC_INTEN);
+		}
+	    else
+		{
+			cached_desc &= (~(EIM_DESC_LIF | EIM_DESC_INTEN));
+		}
+
+	    if (FirstFrame)
+		{
+			cached_desc |= (EIM_DESC_FIF | EIM_DESC_PADCRC);
+		}
+	    else
+		{
+			cached_desc &= (~(EIM_DESC_FIF | EIM_DESC_PADCRC));
+		}
+
+	    eth_out32(current_tx_enet0_desc, cached_desc);
+
+#ifndef ETH_C5471_ALL_DESC_AT_ONCE
+		/* Next, We're done with that descriptor;
+    	 * give access rights back to HW. */
+	    eth_out32(current_tx_enet0_desc,
+	       (eth_in32(current_tx_enet0_desc) & ~(EIM_DESC_OWNER_HOST)));
+#endif
+    	last_packet_desc_end = current_tx_enet0_desc;
+	    eth_incr_tx_enet0_desc(); /* advance to next free descriptor. */
+    	/* Next, tell Ether Module that those submitted bytes are ready
+	     * for the wire. */
+#ifndef ETH_C5471_ALL_DESC_AT_ONCE
+	    eth_out32(ENET0_TXBUF_RDY_REG, 0x00000001);
+#endif
+    	FirstFrame = 0;
+	}
+
+#ifdef ETH_C5471_ALL_DESC_AT_ONCE
+	do {
+		/* Next, We're done with those descriptors;
+    	 * give access rights back to HW. */
+	    eth_out32(tmp_packet_desc,
+	       (eth_in32(tmp_packet_desc) & ~(EIM_DESC_OWNER_HOST)));
+
+	  	if (EIM_DESC_WRAP & eth_in32(tmp_packet_desc))
+    	{
+      		/* Loop back around to base of descriptor queue. */
+	    	tmp_packet_desc = (unsigned long *)(eth_in32(ENET0_TDBA_REG)
+						      + EIM_RAM_START);
+	    }
+  		else
+	    {
+    		tmp_packet_desc+=2;
+	    }
+
+	} while(tmp_packet_desc != current_tx_enet0_desc);
+
+   	/* Next, tell Ether Module that those submitted bytes are ready
+     * for the wire. */
+	eth_out32(ENET0_TXBUF_RDY_REG, 0x00000001);
+#endif
+	return;
+}
+
+#endif
diff -urN linux-2.4.29/drivers/net/fec.c linux-2.4.29-uc1/drivers/net/fec.c
--- linux-2.4.29/drivers/net/fec.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/fec.c	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,3069 @@
+/*
+ * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx.
+ * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
+ *
+ * This version of the driver is specific to the FADS implementation,
+ * since the board contains control registers external to the processor
+ * for the control of the LevelOne LXT970 transceiver.  The MPC860T manual
+ * describes connections using the internal parallel port I/O, which
+ * is basically all of Port D.
+ *
+ * Right now, I am very watseful with the buffers.  I allocate memory
+ * pages and then divide them into 2K frame buffers.  This way I know I
+ * have buffers large enough to hold one frame within one buffer descriptor.
+ * Once I get this working, I will use 64 or 128 byte CPM buffers, which
+ * will be much more memory efficient and will easily handle lots of
+ * small packets.
+ *
+ * Much better multiple PHY support by Magnus Damm.
+ * Copyright (c) 2000 Ericsson Radio Systems AB.
+ *
+ * Support for FEC controller of ColdFire 5235/5270/5271/5272/5280/5282.
+ * Copyright (c) 2001-2003 Greg Ungerer (gerg@snapgear.com)
+ *
+ * Added first level of IOCTL interface
+ * Copyright (c) 2002 Arcturus Networks Inc. 
+ *               by MaTed (Ted Ma - mated@ArcutrusNetworks.com)
+ *
+ * CHANGES
+ *   2003/06/18 ...MaTed
+ * - Fixed scanning of PHYS to scan ALL
+ * - Generalized interrupt vector. Was Magic numbers - now defines
+ *   near beginning of this file
+ * - replaced magic numbers by defines
+ * - fixed open / close pair. ifconfig up/down now builds / tears
+ *   down the descriptors. skb's allocated and released. Some of
+ *   the code previously in init() has migrated to open()
+ * - Added support for uC5272 v1.3 board with PHY interrupt enabled
+ * - Added support for uC5282 v1.0 board with LXT971
+ * - shut down queue when link is down (and wake it later when
+ *   queue comes back up
+ *   2003/08/01  .. Phil Wilshire (PSW)
+ *      moved the fec enable to later in the init sequence
+ *      stops hangs on the 5282EVB board with some bootloaders
+ *   2003/09/03  -  Heiko Degenhardt
+ *      - Added support for the RTL8201BL.
+ *      - changed fecp->fec_mii_speed and fep->phy_speed to 0x1a
+ *        (orig: 0x0e), because that seems to be more correct at
+ *        64MHz.
+ *        ATTENTION! I currently don't know if that breaks other
+ *        stuff!
+ *      - Omitted the " && phytype != 0" in the if clause in
+ *        the if clause in mii_discover_phy.
+ *        ATTENTION! I currently don't know if that breaks other
+ *        stuff!
+ *   2003/09/23  - Michael Durrant 
+ *      - Added back the " && phytype != 0" so that we ensure we are 
+ *        using valid phytypes not 0x0000 or 0xffff.
+ *        patch from (patch from Ted Ma)
+ *      - The fecp->fec_mii_speed and fep->phy_speed needs to be a
+ *        caluclation specific to the MCF5272FEC, MCF5282FEC 
+ *        and system clocks.  (patch from Michael Leslie) 
+ *   2003/10/21  - Heiko Degenhardt
+ *      - Correction/redo of support for the RTL8201BL (of DNP/5280)
+ *        (backed out by Gerg because of "collisions" with other
+ *        changes in cvs)
+ *   2003-10-11  - jens at familie-heilig.net
+ *      - Added support National 8384 (Future/NetBurner "Badge" board)
+ *   2004/10/01  - Paul Mecklenburg (paulm@vxitech.com)
+ *      - Added support for Broadcom 5221 PHY
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+
+#if defined(CONFIG_COLDFIRE)
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/virtconvert.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include "fec.h"
+#define __clear_user(a,l)       memset(a, 0, l)
+#else
+#include <asm/8xx_immap.h>
+#include <asm/pgtable.h>
+#include <asm/mpc8xx.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include "commproc.h"
+#endif
+
+#if defined(CONFIG_FEC_IOCTL)
+#include <linux/fec_ioctl.h>		// only for IOCTL code
+#endif
+
+#ifdef CONFIG_AVNET5282
+#define BIT_BANG_THE_MII
+#endif
+
+/* List of PHYs we wish to support.
+*/
+#define CONFIG_FEC_LXT970
+#define CONFIG_FEC_LXT971
+#define CONFIG_FEC_QS6612
+#define CONFIG_FEC_AM79C874
+#define CONFIG_FEC_LXT972
+#define CONFIG_FEC_DP83847
+#define CONFIG_FEC_BCM5221
+#define CONFIG_FEC_KS8721BL
+
+/* 
+ * We ifdef our changes to our board to not affect other plattforms
+ */
+#if defined(CONFIG_DNP5280)
+#define CONFIG_FEC_RTL8201BL
+#endif
+
+/*
+ * Defines for the PHY Interrupt Status Change
+ */
+#if defined(CONFIG_M5272)
+#define M5272_PHY_STAT_INT
+# if defined(CONFIG_BOARD_UC5272)
+extern unsigned char fec_hwaddr[6];
+#define PHY_INT			MCF_INT_INT6
+#define PHY_START_ADDR	1
+#define ICR_PHY_REG		(MCF_MBAR + MCFSIM_ICR4)
+#define ICR_PHY_MASK_IPL	0x77777777
+#  if defined(CONFIG_UC5272_PHY_INT)
+ #define ICR_PHY_MASK	0xFF0FFFFF
+ #define ICR_PHY_SETUP	0x00d00000
+ #define ICR_MASK_IP	0x00800000
+#  else /* CONFIG_UC5272_PHY_INT */
+ #undef  M5272_PHY_STAT_INT
+ #define ICR_PHY_MASK	0xFFFFFFFF
+ #define ICR_PHY_SETUP	0x00000000
+ #define ICR_MASK_IP	0x00000000
+#  endif /* CONFIG_UC5272_PHY_INT */
+# else /* CONFIG_BOARD_UC5272 */
+#  if defined(CONFIG_FEC_KS8995M)
+  #undef  M5272_PHY_STAT_INT
+  #define PHY_START_ADDR	5
+  #define ICR_PHY_MASK	0xFFFFFFFF
+  #define ICR_PHY_SETUP	0x00000000
+  #define ICR_MASK_IP	0x00000000
+#  else /*CONFIG_FEC_KS8995M */
+// These are values for ColdFire 5272 SIM
+#define PHY_INT			MCF_INT_INT2
+  #define PHY_START_ADDR	0
+  #define ICR_PHY_REG		(MCF_MBAR + MCFSIM_ICR1)
+  #define ICR_PHY_MASK_IPL	0x77777777
+  #define ICR_PHY_MASK	0x70777777
+  #define ICR_MASK_IP	0x08000000
+  #define ICR_PHY_SETUP	0x0d000000
+#  endif /* CONFIG_FEC_KS8995M */
+# endif /* CONFIG_BOARD_UC5272 */
+#endif /* CONFIG_M5272 */
+
+
+/**********
+ * Debug
+ * - Currently only added for IOCTL Functions
+ *   But feel free to add more ...MaTed---
+ **********/
+#define FEC_DEBUG 1
+	// higher numbers give more debug 7 is highest so far ...MaTed---
+
+/*
+ *	Set maximum numbers of FEC devices.
+ */
+#if defined(CONFIG_FEC2)
+#define	FEC_MAX	2
+#else
+#define	FEC_MAX	1
+#endif
+
+/*
+ * Define the fixed address of the FEC hardware.
+ */
+#if defined(CONFIG_M5272)
+static unsigned int fec_hw[] = { (MCF_MBAR+0x840) };
+#elif defined(CONFIG_M5235) || defined(CONFIG_M5282) || defined(CONFIG_M5280)
+static unsigned int fec_hw[] = { (MCF_MBAR+0x1000) };
+#elif defined(CONFIG_M527x)
+static unsigned int fec_hw[] = { (MCF_MBAR+0x1000), (MCF_MBAR+0x1800) };
+#else
+static unsigned int fec_hw[] = { &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec) };
+#endif
+
+
+	
+
+static unsigned char	fec_mac_default[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+/* Forward declarations of some structures to support different PHYs
+*/
+
+typedef struct {
+	uint mii_data;
+	void (*funct)(uint mii_reg, struct net_device *dev);
+} phy_cmd_t;
+
+typedef struct {
+	uint id;
+	char *name;
+
+	const phy_cmd_t *config;
+	const phy_cmd_t *startup;
+	const phy_cmd_t *ack_int;
+	const phy_cmd_t *shutdown;
+} phy_info_t;
+
+/* The number of Tx and Rx buffers.  These are allocated from the page
+ * pool.  The code may assume these are power of two, so it it best
+ * to keep them that size.
+ * We don't need to allocate pages for the transmitter.  We just use
+ * the skbuffer directly.
+ */
+#define FEC_ENET_RX_PAGES	16
+#define FEC_ENET_RX_FRSIZE	2048
+#define FEC_ENET_RX_FRPPG	(PAGE_SIZE / FEC_ENET_RX_FRSIZE)
+#define RX_RING_SIZE		(FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES)
+#define FEC_ENET_TX_FRSIZE	2048
+#define FEC_ENET_TX_FRPPG	(PAGE_SIZE / FEC_ENET_TX_FRSIZE)
+#define TX_RING_SIZE		16	/* Must be power of two */
+#define TX_RING_MOD_MASK	15	/*   for this to work */
+
+/* Interrupt events/masks.
+*/
+#define FEC_ENET_HBERR	((uint)0x80000000)	/* Heartbeat error */
+#define FEC_ENET_BABR	((uint)0x40000000)	/* Babbling receiver */
+#define FEC_ENET_BABT	((uint)0x20000000)	/* Babbling transmitter */
+#define FEC_ENET_GRA	((uint)0x10000000)	/* Graceful stop complete */
+#define FEC_ENET_TXF	((uint)0x08000000)	/* Full frame transmitted */
+#define FEC_ENET_TXB	((uint)0x04000000)	/* A buffer was transmitted */
+#define FEC_ENET_RXF	((uint)0x02000000)	/* Full frame received */
+#define FEC_ENET_RXB	((uint)0x01000000)	/* A buffer was received */
+#define FEC_ENET_MII	((uint)0x00800000)	/* MII interrupt */
+#define FEC_ENET_EBERR	((uint)0x00400000)	/* SDMA bus error */
+#define FEC_ENET_UMINT	((uint)0x00200000)	/* Unmasked Interrupt Status */
+#define FEC_ENET_ALLINT	((uint)0xffe00000)	/* all the bits */
+
+/* The FEC stores dest/src/type, data, and checksum for receive packets.
+ */
+#define PKT_MAXBUF_SIZE		1518
+#define PKT_MINBUF_SIZE		64
+#define PKT_MAXBLR_SIZE		1520
+
+
+/*
+ * The 527x/528x RX control register also contains maximum frame size bits.
+ * Other FEC hardware does not, so we need to take that into account
+ * when setting it.
+ */
+#if defined(CONFIG_M5235) || defined(CONFIG_M527x) || \
+    defined(CONFIG_M5280) || defined(CONFIG_M5282)
+#define	OPT_FRAME_SIZE	(PKT_MAXBUF_SIZE << 16)
+#else
+#define	OPT_FRAME_SIZE	0
+#endif
+
+/* The FEC buffer descriptors track the ring buffers.  The rx_bd_base and
+ * tx_bd_base always point to the base of the buffer descriptors.  The
+ * cur_rx and cur_tx point to the currently available buffer.
+ * The dirty_tx tracks the current buffer that is being sent by the
+ * controller.  The cur_tx and dirty_tx are equal under both completely
+ * empty and completely full conditions.  The empty/ready indicator in
+ * the buffer descriptor determines the actual condition.
+ */
+struct fec_enet_private {
+	/* Hardware registers of the FEC device */
+	volatile fec_t   *hwp;
+
+	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
+	unsigned char *tx_bounce[TX_RING_SIZE];
+	struct	sk_buff* tx_skbuff[TX_RING_SIZE];
+	ushort	skb_cur;
+	ushort	skb_dirty;
+
+	/* CPM dual port RAM relative addresses. */
+	cbd_t	*rx_bd_base;		/* Address of Rx and Tx buffers. */
+	cbd_t	*tx_bd_base;
+	cbd_t	*cur_rx, *cur_tx;		/* The next free ring entry */
+	cbd_t	*dirty_tx;	/* The ring entries to be free()ed. */
+	struct net_device_stats stats;
+	uint	tx_full;
+	spinlock_t lock;
+
+	uint	phy_id;
+	uint	phy_id_done;
+	uint	phy_status;
+	uint	phy_speed;
+	phy_info_t *phy;
+	struct tq_struct phy_task;
+
+	uint	sequence_done;
+	uint	phy_addr;
+	unsigned char mac_addr[ETH_ALEN];
+
+	int	opened;
+	int	link;
+	int	old_link;
+	int	full_duplex;
+
+#if defined(CONFIG_FEC_IOCTL)
+  /*************************************
+	**global saves for fec_ioctl routines
+   *************************************/
+  u16		fec_ioctl_regval;	// saved value for last register requested
+  u16		fec_ioctl_reg;		// last requested register
+  u16		fec_ioctl_wait;		/* have a register value waiting
+								     0 => no outstanding register value
+									 1 => there is register value 
+									    (max allowed is one outstanding queued
+										 read request)
+									 2 => waiting for queued command to finish
+								*/
+  u16		fec_ioctl_reserve;	/* Reserved to word align */
+#endif
+};
+
+static int fec_enet_open(struct net_device *dev);
+static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static void fec_enet_mii(struct net_device *dev);
+static void fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs);
+static void  fec_enet_tx(struct net_device *dev);
+static void  fec_enet_rx(struct net_device *dev);
+static int fec_enet_close(struct net_device *dev);
+static struct net_device_stats *fec_enet_get_stats(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
+static void fec_restart(struct net_device *dev, int duplex);
+static void fec_stop(struct net_device *dev);
+static void	fec_enet_setup_hw_p1( struct net_device *dev);
+static void fec_enet_setup_hw_p2( struct net_device *dev);
+static void mii_discover_phy(uint mii_reg, struct net_device *dev);
+
+#if defined(CONFIG_FEC_IOCTL)
+static int fec_ioctl( struct net_device *dev, struct ifreq *rq, int cmd);
+#endif
+
+/* MII processing.  We keep this as simple as possible.  Requests are
+ * placed on the list (if there is room).  When the request is finished
+ * by the MII, an optional function may be called.
+ */
+typedef struct mii_list {
+	uint	mii_regval;
+	void	(*mii_func)(uint val, struct net_device *dev);
+	struct	mii_list *mii_next;
+} mii_list_t;
+
+#define		NMII	20
+mii_list_t	mii_cmds[NMII];
+mii_list_t	*mii_free;
+mii_list_t	*mii_head;
+mii_list_t	*mii_tail;
+
+static int	mii_queue(struct net_device *dev, int request, 
+				void (*func)(uint, struct net_device *));
+
+/* Make MII read/write commands for the FEC.
+*/
+#define mk_mii_read(REG)	(0x60020000 | ((REG & 0x1f) << 18))
+#define mk_mii_write(REG, VAL)	(0x50020000 | ((REG & 0x1f) << 18) | \
+						(VAL & 0xffff))
+#define mk_mii_end	0
+
+/* Transmitter timeout.
+*/
+#define TX_TIMEOUT (2*HZ)
+
+/* Register definitions for the PHY.
+*/
+
+#define MII_REG_CR          0  /* Control Register                         */
+#define MII_REG_SR          1  /* Status Register                          */
+#define MII_REG_PHYIR1      2  /* PHY Identification Register 1            */
+#define MII_REG_PHYIR2      3  /* PHY Identification Register 2            */
+#define MII_REG_ANAR        4  /* A-N Advertisement Register               */ 
+#define MII_REG_ANLPAR      5  /* A-N Link Partner Ability Register        */
+#define MII_REG_ANER        6  /* A-N Expansion Register                   */
+#define MII_REG_ANNPTR      7  /* A-N Next Page Transmit Register          */
+#define MII_REG_ANLPRNPR    8  /* A-N Link Partner Received Next Page Reg. */
+
+/* values for phy_status */
+
+#define PHY_CONF_ANE	0x0001  /* 1 auto-negotiation enabled */
+#define PHY_CONF_LOOP	0x0002  /* 1 loopback mode enabled */
+#define PHY_CONF_SPMASK	0x00f0  /* mask for speed */
+#define PHY_CONF_10HDX	0x0010  /* 10 Mbit half duplex supported */
+#define PHY_CONF_10FDX	0x0020  /* 10 Mbit full duplex supported */ 
+#define PHY_CONF_100HDX	0x0040  /* 100 Mbit half duplex supported */
+#define PHY_CONF_100FDX	0x0080  /* 100 Mbit full duplex supported */ 
+
+#define PHY_STAT_LINK	0x0100  /* 1 up - 0 down */
+#define PHY_STAT_FAULT	0x0200  /* 1 remote fault */
+#define PHY_STAT_ANC	0x0400  /* 1 auto-negotiation complete	*/
+#define PHY_STAT_SPMASK	0xf000  /* mask for speed */
+#define PHY_STAT_10HDX	0x1000  /* 10 Mbit half duplex selected	*/
+#define PHY_STAT_10FDX	0x2000  /* 10 Mbit full duplex selected	*/ 
+#define PHY_STAT_100HDX	0x4000  /* 100 Mbit half duplex selected */
+#define PHY_STAT_100FDX	0x8000  /* 100 Mbit full duplex selected */
+
+static int
+fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct fec_enet_private *fep;
+	volatile fec_t	*fecp;
+	volatile cbd_t	*bdp;
+
+	fep = dev->priv;
+	fecp = (volatile fec_t*)dev->base_addr;
+
+	if (!fep->link) {
+		/* Link is down or autonegotiation is in progress. */
+	    netif_stop_queue(dev);
+		return 1;
+	}
+
+	/* Fill in a Tx ring entry */
+	bdp = fep->cur_tx;
+
+#if !defined(final_version)
+	if (bdp->cbd_sc & BD_ENET_TX_READY) {
+		/* Ooops.  All transmit buffers are full.  Bail out.
+		 * This should not happen, since dev->tbusy should be set.
+		 */
+		printk("%s: tx queue full!.\n", dev->name);
+		return 1;
+	}
+#endif
+
+	/* Clear all of the status flags.
+	 */
+	bdp->cbd_sc &= ~BD_ENET_TX_STATS;
+
+	/* Set buffer length and buffer pointer.
+	*/
+	bdp->cbd_bufaddr = __pa(skb->data);
+	bdp->cbd_datlen = skb->len;
+
+#if defined(CONFIG_M5235) || defined(CONFIG_M527x) || \
+    defined(CONFIG_M5280) || defined(CONFIG_M5282)
+	/*
+	 *	On some FEC implementations data must be aligned on
+	 *	4-byte boundaries. Use bounce buffers to copy data
+	 *	and get it aligned. Ugh.
+	 */
+	if (bdp->cbd_bufaddr & 0x3) {
+		unsigned int index;
+		index = bdp - fep->tx_bd_base;
+		memcpy(fep->tx_bounce[index], (void *) bdp->cbd_bufaddr, bdp->cbd_datlen);
+		bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]);
+	}
+#endif
+
+	/* Save skb pointer.
+	*/
+	fep->tx_skbuff[fep->skb_cur] = skb;
+
+	fep->stats.tx_bytes += skb->len;
+	fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK;
+
+#if !defined(CONFIG_COLDFIRE)
+	/* Push the data cache so the CPM does not get stale memory
+	 * data.
+	 */
+	flush_dcache_range((unsigned long)skb->data,
+			   (unsigned long)skb->data + skb->len);
+#endif
+
+	spin_lock_irq(&fep->lock);
+
+	/* Send it on its way.  Tell FEC its ready, interrupt when done,
+	 * its the last BD of the frame, and to put the CRC on the end.
+	 */
+
+	bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR
+			| BD_ENET_TX_LAST | BD_ENET_TX_TC);
+
+
+	dev->trans_start = jiffies;
+
+	/* Trigger transmission start */
+	fecp->fec_x_des_active = 0x01000000;
+
+	/* If this was the last BD in the ring, start at the beginning again.
+	*/
+	if (bdp->cbd_sc & BD_ENET_TX_WRAP) {
+		bdp = fep->tx_bd_base;
+	} else {
+		bdp++;
+	}
+
+	if (bdp == fep->dirty_tx) {
+		fep->tx_full = 1;
+		netif_stop_queue(dev);
+	}
+
+	fep->cur_tx = (cbd_t *)bdp;
+
+	spin_unlock_irq(&fep->lock);
+
+	return 0;
+}
+
+static void
+fec_timeout(struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+
+	printk("%s: transmit timed out.\n", dev->name);
+	fep->stats.tx_errors++;
+#if !defined(final_version)
+	{
+	int	i;
+	cbd_t	*bdp;
+
+	printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n",
+	       (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "",
+	       (unsigned long)fep->dirty_tx,
+	       (unsigned long)fep->cur_rx);
+
+	bdp = fep->tx_bd_base;
+	printk(" tx: %u buffers\n",  TX_RING_SIZE);
+	for (i = 0 ; i < TX_RING_SIZE; i++) {
+		printk("  %08x: %04x %04x %08x\n", 
+		       (uint) bdp,
+		       bdp->cbd_sc,
+		       bdp->cbd_datlen,
+		       (int) bdp->cbd_bufaddr);
+		bdp++;
+	}
+
+	bdp = fep->rx_bd_base;
+	printk(" rx: %lu buffers\n",  (unsigned long) RX_RING_SIZE);
+	for (i = 0 ; i < RX_RING_SIZE; i++) {
+		printk("  %08x: %04x %04x %08x\n",
+		       (uint) bdp,
+		       bdp->cbd_sc,
+		       bdp->cbd_datlen,
+		       (int) bdp->cbd_bufaddr);
+		bdp++;
+	}
+	}
+#endif
+	fec_restart(dev, 0);
+	netif_wake_queue(dev);
+}
+
+/* The interrupt handler.
+ * This is called from the MPC core interrupt.
+ */
+static	void
+fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+{
+	struct	net_device *dev = dev_id;
+	volatile fec_t	*fecp;
+	uint	int_events;
+
+	fecp = (volatile fec_t*)dev->base_addr;
+
+	/* Get the interrupt events that caused us to be here.
+	*/
+	while ((int_events = fecp->fec_ievent) != 0) {
+		fecp->fec_ievent = int_events;
+		if ((int_events & (FEC_ENET_HBERR | FEC_ENET_BABR |
+				   FEC_ENET_BABT | FEC_ENET_EBERR)) != 0) {
+			printk("FEC ERROR %x\n", int_events);
+		}
+
+		/* Handle receive event in its own function.
+		 */
+		if (int_events & FEC_ENET_RXF)
+			fec_enet_rx(dev);
+
+		/* Transmit OK, or non-fatal error. Update the buffer
+		   descriptors. FEC handles all errors, we just discover
+		   them as part of the transmit process.
+		*/
+		if (int_events & FEC_ENET_TXF)
+			fec_enet_tx(dev);
+
+		if (int_events & FEC_ENET_MII)
+			fec_enet_mii(dev);
+
+	}
+}
+
+
+static void
+fec_enet_tx(struct net_device *dev)
+{
+	struct	fec_enet_private *fep;
+	volatile cbd_t	*bdp;
+	struct	sk_buff	*skb;
+
+	fep = dev->priv;
+	spin_lock(&fep->lock);
+	bdp = fep->dirty_tx;
+
+	while ((bdp->cbd_sc&BD_ENET_TX_READY) == 0) {
+		if (bdp == fep->cur_tx && fep->tx_full == 0) break;
+
+		skb = fep->tx_skbuff[fep->skb_dirty];
+		/* Check for errors. */
+		if (bdp->cbd_sc & (BD_ENET_TX_HB | BD_ENET_TX_LC |
+				   BD_ENET_TX_RL | BD_ENET_TX_UN |
+				   BD_ENET_TX_CSL)) {
+			fep->stats.tx_errors++;
+			if (bdp->cbd_sc & BD_ENET_TX_HB)  /* No heartbeat */
+				fep->stats.tx_heartbeat_errors++;
+			if (bdp->cbd_sc & BD_ENET_TX_LC)  /* Late collision */
+				fep->stats.tx_window_errors++;
+			if (bdp->cbd_sc & BD_ENET_TX_RL)  /* Retrans limit */
+				fep->stats.tx_aborted_errors++;
+			if (bdp->cbd_sc & BD_ENET_TX_UN)  /* Underrun */
+				fep->stats.tx_fifo_errors++;
+			if (bdp->cbd_sc & BD_ENET_TX_CSL) /* Carrier lost */
+				fep->stats.tx_carrier_errors++;
+		} else {
+			fep->stats.tx_packets++;
+		}
+
+#if !defined(final_version)
+		if (bdp->cbd_sc & BD_ENET_TX_READY)
+			printk("HEY! Enet xmit interrupt and TX_READY.\n");
+#endif
+		/* Deferred means some collisions occurred during transmit,
+		 * but we eventually sent the packet OK.
+		 */
+		if (bdp->cbd_sc & BD_ENET_TX_DEF)
+			fep->stats.collisions++;
+	    
+		/* Free the sk buffer associated with this last transmit.
+		 */
+		dev_kfree_skb_any(skb);
+		fep->tx_skbuff[fep->skb_dirty] = NULL;
+		fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK;
+	    
+		/* Update pointer to next buffer descriptor to be transmitted.
+		 */
+		if (bdp->cbd_sc & BD_ENET_TX_WRAP)
+			bdp = fep->tx_bd_base;
+		else
+			bdp++;
+	    
+		/* Since we have freed up a buffer, the ring is no longer
+		 * full.
+		 */
+		if (fep->tx_full) {
+			fep->tx_full = 0;
+			if (netif_queue_stopped(dev))
+				netif_wake_queue(dev);
+		}
+	}
+	fep->dirty_tx = (cbd_t *)bdp;
+	spin_unlock(&fep->lock);
+}
+
+
+/* During a receive, the cur_rx points to the current incoming buffer.
+ * When we update through the ring, if the next incoming buffer has
+ * not been given to the system, we just set the empty indicator,
+ * effectively tossing the packet.
+ */
+static void
+fec_enet_rx(struct net_device *dev)
+{
+	struct	fec_enet_private *fep;
+	volatile fec_t	*fecp;
+	volatile cbd_t *bdp;
+	struct	sk_buff	*skb;
+	ushort	pkt_len;
+	__u8 *data;
+
+	fep = dev->priv;
+	fecp = (volatile fec_t*)dev->base_addr;
+
+	/* First, grab all of the stats for the incoming packet.
+	 * These get messed up if we get called due to a busy condition.
+	 */
+	bdp = fep->cur_rx;
+
+while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) {
+
+#if !defined(final_version)
+	/* Since we have allocated space to hold a complete frame,
+	 * the last indicator should be set.
+	 */
+	if ((bdp->cbd_sc & BD_ENET_RX_LAST) == 0)
+		printk("FEC ENET: rcv is not +last\n");
+#endif
+
+	if (!fep->opened)
+		goto rx_processing_done;
+
+	/* Check for errors. */
+	if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
+			   BD_ENET_RX_CR | BD_ENET_RX_OV)) {
+		fep->stats.rx_errors++;       
+		if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
+		/* Frame too long or too short. */
+			fep->stats.rx_length_errors++;
+		}
+		if (bdp->cbd_sc & BD_ENET_RX_NO)	/* Frame alignment */
+			fep->stats.rx_frame_errors++;
+		if (bdp->cbd_sc & BD_ENET_RX_CR)	/* CRC Error */
+			fep->stats.rx_crc_errors++;
+		if (bdp->cbd_sc & BD_ENET_RX_OV)	/* FIFO overrun */
+			fep->stats.rx_fifo_errors++;
+	}
+
+	/* Report late collisions as a frame error.
+	 * On this error, the BD is closed, but we don't know what we
+	 * have in the buffer.  So, just drop this frame on the floor.
+	 */
+	if (bdp->cbd_sc & BD_ENET_RX_CL) {
+		fep->stats.rx_errors++;
+		fep->stats.rx_frame_errors++;
+		goto rx_processing_done;
+	}
+
+	/* Process the incoming frame.
+	 */
+	fep->stats.rx_packets++;
+#if !defined(CONFIG_M5235) && !defined(CONFIG_M527x) && \
+    !defined(CONFIG_M5282) && !defined(CONFIG_M5280)
+	if (fecp->fec_max_frm_len & 0x40000000)
+		fep->stats.multicast++;
+#endif
+	pkt_len = bdp->cbd_datlen;
+	fep->stats.rx_bytes += pkt_len;
+	data = (__u8*)__va(bdp->cbd_bufaddr);
+
+	/* This does 16 byte alignment, exactly what we need.
+	 * The packet length includes FCS, but we don't want to
+	 * include that when passing upstream as it messes up
+	 * bridging applications.
+	 */
+	skb = dev_alloc_skb(pkt_len-4);
+
+	if (skb == NULL) {
+		printk("%s: Memory squeeze, dropping packet.\n", dev->name);
+		fep->stats.rx_dropped++;
+	} else {
+		skb->dev = dev;
+		skb_put(skb,pkt_len-4);	/* Make room */
+		eth_copy_and_sum(skb,
+				 (unsigned char *)__va(bdp->cbd_bufaddr),
+				 pkt_len-4, 0);
+		skb->protocol=eth_type_trans(skb,dev);
+		netif_rx(skb);
+	}
+rx_processing_done:
+
+	/* Clear the status flags for this buffer.
+	*/
+	bdp->cbd_sc &= ~BD_ENET_RX_STATS;
+
+	/* Mark the buffer empty.
+	*/
+	bdp->cbd_sc |= BD_ENET_RX_EMPTY;
+
+	/* Update BD pointer to next entry.
+	*/
+	if (bdp->cbd_sc & BD_ENET_RX_WRAP)
+		bdp = fep->rx_bd_base;
+	else
+		bdp++;
+	
+	/* Doing this here will keep the FEC running while we process
+	 * incoming frames.  On a heavily loaded network, we should be
+	 * able to keep up at the expense of system resources.
+	 */
+	fecp->fec_r_des_active = 0x01000000;
+} /* while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) */
+
+	fep->cur_rx = (cbd_t *)bdp;
+}
+
+// ----------------------------------------------------------------
+#ifdef BIT_BANG_THE_MII
+static uint bit_bang_hack = 0xffffffff;
+
+// Per the ColdFire data sheet, MDIO is port AS bit 5 and MDC is port AS bit 4.
+// However, on the Avnet ColdFire 5282 board, these were connected reversed.
+// If they were connected correctly, we could have the FEC serialize and
+// deserialize via its MDATA and MSCR registers.  But instead we configure
+// those two pins as GPIO and bit-bang them directly.
+
+#define MDIO_BIT    4 // See above comment
+#define MDC_BIT     5 // See above comment
+
+#define MDC_HI     (1 << MDC_BIT)
+#define MDIO_HI    (1 << MDIO_BIT)
+
+#define MCF5282_GPIO_DDRAS      (*(volatile unsigned char  *)0x40100020)
+#define MCF5282_GPIO_CLRAS      (*(volatile unsigned char  *)0x40100048)
+#define MCF5282_GPIO_PORTASP    (*(volatile unsigned char  *)0x40100034)
+#define MCF5282_GPIO_PASPAR     (*(volatile unsigned char  *)0x40100056)
+
+// See above comment.  Configure port AS pins 5 and 4 for GPIO
+// by clearing PASPAR[11-10] and [9-8], respectively.
+void MII_bit_bang_initialize(void)
+{
+	MCF5282_GPIO_PASPAR &= ~0x0f00;
+}
+
+// ----------------------------------------------------------------
+// CF GPIO semantics are weird:
+// * To read bits, read ASP
+// * To set   a bit, write ASP
+// * To clear a bit, write CLRAS
+
+static int write_clock_and_read_data(
+	int clock_val)
+{
+	int rv;
+
+	// Data direction register (DDR):  1 for output, 0 for input.
+	MCF5282_GPIO_DDRAS &= ~MDIO_HI;   // We will read  the data
+	MCF5282_GPIO_DDRAS |=  MDC_HI;    // We will write the clock
+
+	// Read the data
+	if (MCF5282_GPIO_PORTASP & MDIO_HI)
+		rv = 1;
+	else
+		rv = 0;
+
+	// Write the clock
+	if (clock_val == 0)
+		MCF5282_GPIO_CLRAS   = ~MDC_HI; // Low  clock
+	else
+		MCF5282_GPIO_PORTASP =  MDC_HI; // High clock
+
+	udelay(1);
+	return rv;
+}
+
+// ----------------------------------------------------------------
+static void write_clock_and_data(
+	int clock_val,
+	int data_val)
+{
+	// Data direction register (DDR):  1 for output, 0 for input.
+	MCF5282_GPIO_DDRAS |= MDC_HI;     // We will write the clock
+	MCF5282_GPIO_DDRAS |= MDIO_HI;    // We will write the data
+
+	// Write the clock
+	if (clock_val == 0)
+		MCF5282_GPIO_CLRAS   = ~MDC_HI; // Low  clock
+	else
+		MCF5282_GPIO_PORTASP =  MDC_HI; // High clock
+
+	// Write the data
+	if (data_val == 0)
+		MCF5282_GPIO_CLRAS   = ~MDIO_HI; // Low  data
+	else
+		MCF5282_GPIO_PORTASP =  MDIO_HI; // High data
+
+	udelay(1);
+}
+
+static uint MII_bit_bang_read(uint regval)
+{
+	int  bit;
+	int  i;
+	uint result;
+	uint id   = (regval >> 23) & 0x1f;
+	uint addr = (regval >> 18) & 0x1f;
+
+	// Preamble:  Hold MDIO high for at least 32 MDC clocks (note that
+	// we drive the clock).
+	for (i = 0; i < 36; i++) {
+		write_clock_and_data(0, 1);
+		write_clock_and_data(1, 1);
+	}
+
+	// Setup:  Write 0, 1 to MDIO.
+	write_clock_and_data(0, 0);
+	write_clock_and_data(1, 0);
+
+	write_clock_and_data(0, 1);
+	write_clock_and_data(1, 1);
+
+	// Opcode:  Write 1, 0 to MDIO.
+	write_clock_and_data(0, 1);
+	write_clock_and_data(1, 1);
+
+	write_clock_and_data(0, 0);
+	write_clock_and_data(1, 0);
+
+	// 5 which-port bits
+	for (bit = 4; bit >= 0; bit--) {
+		write_clock_and_data(0, (id >> bit) & 1);
+		write_clock_and_data(1, (id >> bit) & 1);
+	}
+
+	// 5 register bits
+	for (bit = 4; bit >= 0; bit--) {
+		write_clock_and_data(0, (addr >> bit) & 1);
+		write_clock_and_data(1, (addr >> bit) & 1);
+	}
+
+	// Turn around
+	(void)write_clock_and_read_data(0);
+	(void)write_clock_and_read_data(1);
+	(void)write_clock_and_read_data(0);
+
+	// 16 data bits
+	result = 0;
+	for (bit = 15; bit >= 0; bit--) {
+		(void)write_clock_and_read_data(1);
+		result |= write_clock_and_read_data(0) << bit;
+	}
+
+	return result;
+}
+
+static void MII_bit_bang_write(uint regval)
+{
+	uint id   = (regval >> 23) & 0x1f;
+	uint addr = (regval >> 18) & 0x1f;
+	uint data = regval & 0xffff;
+	int  bit;
+	int  i;
+
+	// Preamble:  Hold MDIO high for at least 32 MDC clocks (note that
+	// we drive the clock).
+	for (i = 0; i < 36; i++) {
+		write_clock_and_data(0, 1);
+		write_clock_and_data(1, 1);
+	}
+
+	// ST (whatever that means):  Write 0, 1 to MDIO.
+	write_clock_and_data(0, 0);
+	write_clock_and_data(1, 0);
+
+	write_clock_and_data(0, 1);
+	write_clock_and_data(1, 1);
+
+	// Opcode:  Write 0, 1 to MDIO.
+	write_clock_and_data(0, 0);
+	write_clock_and_data(1, 0);
+
+	write_clock_and_data(0, 1);
+	write_clock_and_data(1, 1);
+
+	// 5 which-port bits
+	for (bit = 4; bit >= 0; bit--) {
+		write_clock_and_data(0, (id >> bit) & 1);
+		write_clock_and_data(1, (id >> bit) & 1);
+	}
+
+	// 5 register bits
+	for (bit = 4; bit >= 0; bit--) {
+		write_clock_and_data(0, (addr >> bit) & 1);
+		write_clock_and_data(1, (addr >> bit) & 1);
+	}
+
+	// Turn around
+	(void)write_clock_and_data(0, 1);
+	(void)write_clock_and_data(1, 1);
+	(void)write_clock_and_data(0, 0);
+	(void)write_clock_and_data(1, 0);
+
+	// 16 data bits
+	for (bit = 15; bit >= 0; bit--) {
+		(void)write_clock_and_data(0, (data >> bit) & 1);
+		(void)write_clock_and_data(1, (data >> bit) & 1);
+	}
+}
+
+#endif // BIT_BANG_THE_MII
+
+// ----------------------------------------------------------------
+static void
+fec_enet_mii(struct net_device *dev)
+{
+	struct	fec_enet_private *fep;
+	volatile fec_t *ep;
+	mii_list_t *mip;
+	uint mii_reg;
+
+	fep = (struct fec_enet_private *)dev->priv;
+	ep = fep->hwp;
+
+#ifdef BIT_BANG_THE_MII
+	mii_reg = bit_bang_hack;
+#else
+	mii_reg = ep->fec_mii_data;
+#endif
+
+	if ((mip = mii_head) == NULL) {
+		printk("MII and no head!\n");
+		return;
+	}
+
+	if (mip->mii_func != NULL)
+		(*(mip->mii_func))(mii_reg, dev);
+
+	mii_head = mip->mii_next;
+	mip->mii_next = mii_free;
+	mii_free = mip;
+
+	if ((mip = mii_head) != NULL)
+#ifdef BIT_BANG_THE_MII
+		MII_bit_bang_write(mip->mii_regval);
+		bit_bang_hack = MII_bit_bang_read(mip->mii_regval);
+#else
+		ep->fec_mii_data = mip->mii_regval;
+#endif
+}
+
+static int
+mii_queue(
+	struct net_device *dev,
+	int regval,
+	void (*func)(uint, struct net_device *))
+{
+	struct fec_enet_private *fep;
+	unsigned long flags;
+	mii_list_t *mip;
+	int retval;
+
+	/* Add PHY address to register command.
+	*/
+	fep = dev->priv;
+	regval |= fep->phy_addr << 23;
+
+	retval = 0;
+
+	save_flags(flags);
+	cli();
+
+	if ((mip = mii_free) != NULL) {
+		mii_free = mip->mii_next;
+		mip->mii_regval = regval;
+		mip->mii_func = func;
+		mip->mii_next = NULL;
+		if (mii_head) {
+			mii_tail->mii_next = mip;
+			mii_tail = mip;
+		} else {
+			mii_head = mii_tail = mip;
+#ifdef BIT_BANG_THE_MII
+			MII_bit_bang_write(regval);
+			bit_bang_hack = MII_bit_bang_read(regval);
+#else
+			fep->hwp->fec_mii_data = regval;
+#endif
+		}
+	} else {
+		retval = 1;
+	}
+
+	restore_flags(flags);
+
+	return(retval);
+}
+
+static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c)
+{
+	int k;
+
+	if(!c)
+		return;
+
+	for(k = 0; (c+k)->mii_data != mk_mii_end; k++) {
+		mii_queue(dev, (c+k)->mii_data, (c+k)->funct);
+	}
+}
+
+static void mii_parse_sr(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_STAT_LINK | PHY_STAT_FAULT | PHY_STAT_ANC);
+
+	if (mii_reg & 0x0004)
+		*s |= PHY_STAT_LINK;
+	if (mii_reg & 0x0010)
+		*s |= PHY_STAT_FAULT;
+	if (mii_reg & 0x0020)
+		*s |= PHY_STAT_ANC;
+}
+
+static void mii_parse_cr(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_CONF_ANE | PHY_CONF_LOOP);
+
+	if (mii_reg & 0x1000)
+		*s |= PHY_CONF_ANE;
+	if (mii_reg & 0x4000)
+		*s |= PHY_CONF_LOOP;
+}
+
+static void mii_parse_anar(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_CONF_SPMASK);
+
+	if (mii_reg & 0x0020)
+		*s |= PHY_CONF_10HDX;
+	if (mii_reg & 0x0040)
+		*s |= PHY_CONF_10FDX;
+	if (mii_reg & 0x0080)
+		*s |= PHY_CONF_100HDX;
+	if (mii_reg & 0x00100)
+		*s |= PHY_CONF_100FDX;
+}
+
+#if 0
+static void mii_disp_reg(uint mii_reg, struct net_device *dev)
+{
+	printk("reg %u = 0x%04x\n", (mii_reg >> 18) & 0x1f, mii_reg & 0xffff);
+}
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* The Level one LXT970 is used by many boards				     */
+
+#if defined(CONFIG_FEC_LXT970)
+
+#define MII_LXT970_MIRROR    16  /* Mirror register           */
+#define MII_LXT970_IER       17  /* Interrupt Enable Register */
+#define MII_LXT970_ISR       18  /* Interrupt Status Register */
+#define MII_LXT970_CONFIG    19  /* Configuration Register    */
+#define MII_LXT970_CSR       20  /* Chip Status Register      */
+
+static void mii_parse_lxt970_csr(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_STAT_SPMASK);
+
+	if (mii_reg & 0x0800) {
+		if (mii_reg & 0x1000)
+			*s |= PHY_STAT_100FDX;
+		else
+			*s |= PHY_STAT_100HDX;
+	} else {
+		if (mii_reg & 0x1000)
+			*s |= PHY_STAT_10FDX;
+		else
+			*s |= PHY_STAT_10HDX;
+	}
+}
+
+static phy_info_t phy_info_lxt970 = {
+	0x07810000, 
+	"LXT970",
+
+	(const phy_cmd_t []) {  /* config */
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* startup - enable interrupts */
+		{ mk_mii_write(MII_LXT970_IER, 0x0002), NULL },
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* ack_int */
+		/* read SR and ISR to acknowledge */
+		
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr },
+		{ mk_mii_read(MII_LXT970_ISR), NULL },
+
+		/* find out the current status */
+		
+		{ mk_mii_read(MII_LXT970_CSR), mii_parse_lxt970_csr },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* shutdown - disable interrupts */
+		{ mk_mii_write(MII_LXT970_IER, 0x0000), NULL },
+		{ mk_mii_end, }
+	},
+};
+	
+#endif /* CONFIG_FEC_LXT970 */
+
+/* ------------------------------------------------------------------------- */
+/* The Level one LXT971 is used on some of my custom boards                  */
+
+#if defined(CONFIG_FEC_LXT971)
+
+/* register definitions for the 971 */
+
+#define MII_LXT971_PCR       16  /* Port Control Register     */
+#define MII_LXT971_SR2       17  /* Status Register 2         */
+#define MII_LXT971_IER       18  /* Interrupt Enable Register */
+#define MII_LXT971_ISR       19  /* Interrupt Status Register */
+#define MII_LXT971_LCR       20  /* LED Control Register      */
+#define MII_LXT971_TCR       30  /* Transmit Control Register */
+
+/* 
+ * I had some nice ideas of running the MDIO faster...
+ * The 971 should support 8MHz and I tried it, but things acted really
+ * weird, so 2.5 MHz ought to be enough for anyone...
+ */
+
+static void mii_parse_lxt971_sr2(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC);
+
+	if (mii_reg & 0x0400) {
+		fep->link = 1;
+		*s |= PHY_STAT_LINK;
+	} else {
+		fep->link = 0;
+	}
+	if (mii_reg & 0x0080)
+		*s |= PHY_STAT_ANC;
+	if (mii_reg & 0x4000) {
+		if (mii_reg & 0x0200)
+			*s |= PHY_STAT_100FDX;
+		else
+			*s |= PHY_STAT_100HDX;
+	} else {
+		if (mii_reg & 0x0200)
+			*s |= PHY_STAT_10FDX;
+		else
+			*s |= PHY_STAT_10HDX;
+	}
+	if (mii_reg & 0x0008)
+		*s |= PHY_STAT_FAULT;
+}
+
+static phy_info_t phy_info_lxt971 = {
+	0x0001378e, 
+	"LXT971",
+	
+	(const phy_cmd_t []) {  /* config */  
+		/* limit to 10MBit because my prototype board
+		 * doesn't work with 100. */
+#if defined(CONFIG_COLDFIRE)
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 },
+#else
+		{ mk_mii_write(MII_REG_ANAR, 0x061), NULL }, /* 10 MBit */
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+#endif
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* startup - enable interrupts */
+		{ mk_mii_write(MII_LXT971_IER, 0x00f2), NULL },
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_write(MII_LXT971_LCR, 0xd422), NULL }, /* LED config */
+		/* Somehow does the 971 tell me that the link is down
+		 * the first read after power-up.
+		 * read here to get a valid value in ack_int */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr }, 
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* ack_int */
+		/* find out the current status */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr },
+		{ mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 },
+		/* we only need to read ISR to acknowledge */
+		{ mk_mii_read(MII_LXT971_ISR), NULL },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* shutdown - disable interrupts */
+		{ mk_mii_write(MII_LXT971_IER, 0x0000), NULL },
+		{ mk_mii_end, }
+	},
+};
+
+#endif /* CONFIG_FEC_LXT971 */
+
+
+/* ------------------------------------------------------------------------- */
+/* The Level one LXT972 is used on the Arcturus Networks uC5272/uC5282 dimm  */
+
+#if defined(CONFIG_FEC_LXT972)
+
+/* register definitions for the 972 */
+
+#define MII_LXT972_PCR       16  /* Port Control Register     */
+#define MII_LXT972_SR2       17  /* Status Register 2         */
+#define MII_LXT972_IER       18  /* Interrupt Enable Register */
+#define MII_LXT972_ISR       19  /* Interrupt Status Register */
+#define MII_LXT972_LCR       20  /* LED Control Register      */
+#define MII_LXT972_TCR       30  /* Transmit Control Register */
+
+static void mii_parse_lxt972_sr2(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC);
+
+	if (mii_reg & 0x0400) {
+		fep->link = 1;
+		*s |= PHY_STAT_LINK;
+	} else {
+		fep->link = 0;
+	}
+	if (mii_reg & 0x0080)
+		*s |= PHY_STAT_ANC;
+	if (mii_reg & 0x4000) {
+		if (mii_reg & 0x0200)
+			*s |= PHY_STAT_100FDX;
+		else
+			*s |= PHY_STAT_100HDX;
+	} else {
+		if (mii_reg & 0x0200)
+			*s |= PHY_STAT_10FDX;
+		else
+			*s |= PHY_STAT_10HDX;
+	}
+	if (mii_reg & 0x0008)
+		*s |= PHY_STAT_FAULT;
+}
+
+static phy_info_t phy_info_lxt972 = {
+	0x0001378e,
+	"LXT972",
+	
+	(const phy_cmd_t []) {  /* config */  
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_read(MII_LXT972_SR2), mii_parse_lxt972_sr2 },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* startup - enable interrupts */
+		{ mk_mii_write(MII_LXT972_IER, 0x00f2), NULL },
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		/* Somehow does the 972 tell me that the link is down
+		 * the first read after power-up.
+		 * read here to get a valid value in ack_int */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr }, 
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* ack_int */
+		/* find out the current status */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr },
+		{ mk_mii_read(MII_LXT972_SR2), mii_parse_lxt972_sr2 },
+		/* we only need to read ISR to acknowledge */
+		{ mk_mii_read(MII_LXT972_ISR), NULL },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* shutdown - disable interrupts */
+		{ mk_mii_write(MII_LXT972_IER, 0x0000), NULL },
+		{ mk_mii_end, }
+	},
+};
+
+#endif /* CONFIG_FEC_LXT972 */
+
+
+/* ------------------------------------------------------------------------- */
+/* The National DP83847 is used on the Future/Netburner Badge Board          */
+
+#if defined(CONFIG_FEC_DP83847)
+
+/* register definitions for the DP83847 */
+
+#define MII_DP83847_PHYSTST       16  /* PHY Status Register */
+
+static void mii_parse_dp83847_sr2(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC);
+
+  // Link up?
+	if (mii_reg & 0x0001) {
+		fep->link = 1;
+		*s |= PHY_STAT_LINK;
+	} else {
+		fep->link = 0;
+	}
+	// Status of link
+	if (mii_reg & 0x0010)     // Autonegotioation complete?
+		*s |= PHY_STAT_ANC;
+	if (mii_reg & 0x0002) {   // 10MBps?
+		if (mii_reg & 0x0004)   // Full Duplex?
+			*s |= PHY_STAT_10FDX;
+		else
+			*s |= PHY_STAT_10HDX;
+	} else {                  // 100 Mbps
+		if (mii_reg & 0x0004)   // Full Duplex?
+			*s |= PHY_STAT_100FDX;
+		else
+			*s |= PHY_STAT_100HDX;
+	}
+	if (mii_reg & 0x0008)
+		*s |= PHY_STAT_FAULT;
+}
+
+static phy_info_t phy_info_dp83847= {
+	0x020005c3, // oder 0x80017?
+	"DP83847",
+	
+	(const phy_cmd_t []) {  /* config */  
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_read(MII_DP83847_PHYSTST), mii_parse_dp83847_sr2 },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* startup - enable interrupts */
+		// { mk_mii_write(MII_LXT972_IER, 0x00f2), NULL },
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr }, 
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* ack_int - never happens, we don't have an interrupt */
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* shutdown */
+		{ mk_mii_end, }
+	},
+};
+
+#endif /* CONFIG_FEC_DP83847 */
+
+
+/* ------------------------------------------------------------------------- */
+/* The Quality Semiconductor QS6612 is used on the RPX CLLF                  */
+
+#if defined(CONFIG_FEC_QS6612)
+
+/* register definitions */
+
+#define MII_QS6612_MCR       17  /* Mode Control Register      */
+#define MII_QS6612_FTR       27  /* Factory Test Register      */
+#define MII_QS6612_MCO       28  /* Misc. Control Register     */
+#define MII_QS6612_ISR       29  /* Interrupt Source Register  */
+#define MII_QS6612_IMR       30  /* Interrupt Mask Register    */
+#define MII_QS6612_PCR       31  /* 100BaseTx PHY Control Reg. */
+
+static void mii_parse_qs6612_pcr(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_STAT_SPMASK);
+
+	switch((mii_reg >> 2) & 7) {
+	case 1: *s |= PHY_STAT_10HDX; break;
+	case 2: *s |= PHY_STAT_100HDX; break;
+	case 5: *s |= PHY_STAT_10FDX; break;
+	case 6: *s |= PHY_STAT_100FDX; break;
+	}
+}
+
+static phy_info_t phy_info_qs6612 = {
+	0x00181440, 
+	"QS6612",
+	
+	(const phy_cmd_t []) {  /* config */  
+//	{ mk_mii_write(MII_REG_ANAR, 0x061), NULL }, /* 10 MBit */
+
+		/* The PHY powers up isolated on the RPX, 
+		 * so send a command to allow operation.
+		 */
+
+		{ mk_mii_write(MII_QS6612_PCR, 0x0dc0), NULL },
+
+		/* parse cr and anar to get some info */
+
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* startup - enable interrupts */
+		{ mk_mii_write(MII_QS6612_IMR, 0x003a), NULL },
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* ack_int */
+		
+		/* we need to read ISR, SR and ANER to acknowledge */
+		
+		{ mk_mii_read(MII_QS6612_ISR), NULL },
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr },
+		{ mk_mii_read(MII_REG_ANER), NULL },
+
+		/* read pcr to get info */
+
+		{ mk_mii_read(MII_QS6612_PCR), mii_parse_qs6612_pcr },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* shutdown - disable interrupts */
+		{ mk_mii_write(MII_QS6612_IMR, 0x0000), NULL },
+		{ mk_mii_end, }
+	},
+};
+
+#endif /* CONFIG_FEC_QS6612 */
+
+
+/* ------------------------------------------------------------------------- */
+/* AMD AM79C874 phy                                                          */
+
+#if defined(CONFIG_FEC_AM79C874)
+
+/* register definitions for the 874 */
+
+#define MII_AM79C874_MFR       16  /* Miscellaneous Feature Register */
+#define MII_AM79C874_ICSR      17  /* Interrupt/Status Register      */
+#define MII_AM79C874_DR        18  /* Diagnostic Register            */
+#define MII_AM79C874_PMLR      19  /* Power and Loopback Register    */
+#define MII_AM79C874_MCR       21  /* ModeControl Register           */
+#define MII_AM79C874_DC        23  /* Disconnect Counter             */
+#define MII_AM79C874_REC       24  /* Recieve Error Counter          */
+
+static void mii_parse_am79c874_dr(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_STAT_SPMASK | PHY_STAT_ANC);
+
+	if (mii_reg & 0x0080)
+		*s |= PHY_STAT_ANC;
+	if (mii_reg & 0x0400)
+		*s |= ((mii_reg & 0x0800) ? PHY_STAT_100FDX : PHY_STAT_100HDX);
+	else
+		*s |= ((mii_reg & 0x0800) ? PHY_STAT_10FDX : PHY_STAT_10HDX);
+}
+
+static phy_info_t phy_info_am79c874 = {
+	0x00022561, 
+	"AM79C874",
+
+	(const phy_cmd_t []) {  /* config */  
+		/* limit to 10MBit because my prototype board
+		 * doesn't work with 100. */
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_read(MII_AM79C874_DR), mii_parse_am79c874_dr },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* startup - enable interrupts */
+		{ mk_mii_write(MII_AM79C874_ICSR, 0xff00), NULL },
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr }, 
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* ack_int */
+		/* find out the current status */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr },
+		{ mk_mii_read(MII_AM79C874_DR), mii_parse_am79c874_dr },
+		/* we only need to read ISR to acknowledge */
+		{ mk_mii_read(MII_AM79C874_ICSR), NULL },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* shutdown - disable interrupts */
+		{ mk_mii_write(MII_AM79C874_ICSR, 0x0000), NULL },
+		{ mk_mii_end, }
+	},
+};
+
+#endif /* CONFIG_FEC_AM79C874 */
+
+/* ------------------------------------------------------------------------- */
+/* Kendin KS8995M Phy5 Mode                                                  */
+
+#ifdef CONFIG_FEC_KS8995M_P5
+
+static phy_info_t phy_info_ks8995m = {
+	0x00221459, 
+	"KS8995M P5",
+	
+	(const phy_cmd_t []) {  /* config */
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* startup */
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr }, 
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* ack_int - never happens, we don't have an interrupt */
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* shutdown */
+		{ mk_mii_end, }
+	},
+};
+
+#endif /* CONFIG_FEC_KS8995M_P5 */
+
+
+
+#ifdef CONFIG_FEC_KS8721BL
+
+#define MII_KS8721BL_RXERCR   0x15
+#define MII_KS8721BL_ICSR     0x16
+#define MII_KS8721BL_PHYCR    0x1f
+
+static phy_info_t phy_info_ks8721bl = {
+	0x00022161,
+	"KS8721BL",
+	
+	(const phy_cmd_t []) {  /* config */
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* startup */
+		{ mk_mii_write(MII_KS8721BL_ICSR, 0xff00), NULL },
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr }, 
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* ack_int  */
+		/* find out the current status */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr },
+		/* we only need to read ISR to acknowledge */
+		{ mk_mii_read(MII_KS8721BL_ICSR), NULL },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* shutdown */
+		{ mk_mii_write(MII_KS8721BL_ICSR, 0x0000), NULL },
+		{ mk_mii_end, }
+	},
+};
+#endif /* CONFIG_FEC_KS8721BL */
+
+/*
+ * RTL8201BL (on DNP5280)
+ */
+#if defined(CONFIG_FEC_RTL8201BL)
+
+static phy_info_t phy_info_rtl8201bl = {
+   0x00000820,
+   "RTL8201BL",
+	(const phy_cmd_t []) {  /* config */
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* startup */
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* ack_int - never happens, we don't have
+									  an interrupt */
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* shutdown */
+		{ mk_mii_end, }
+	},
+};
+
+#endif /* CONFIG_FEC_RTL8201BL */
+
+/* ------------------------------------------------------------------------- */
+/* BROADCOM 5221 phy                                                         */
+
+#if defined(CONFIG_FEC_BCM5221)
+#define MII_BCM5221_IR 0x1A
+#define MII_BCM5221_AUX_CSR 0x18
+
+static void mii_parse_bcm5221_sr(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_STAT_LINK | PHY_STAT_FAULT | PHY_STAT_ANC);
+
+	fep->link = 0;
+
+	if (mii_reg & 0x0004) {
+		*s |= PHY_STAT_LINK;
+		fep->link = 1;
+	}
+	if (mii_reg & 0x0010)
+		*s |= PHY_STAT_FAULT;
+	if (mii_reg & 0x0020)
+		*s |= PHY_STAT_ANC;
+
+}
+
+static void mii_parse_bcm5221_sr2(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status); 
+
+	*s &= ~(PHY_STAT_SPMASK);
+
+	if (mii_reg & 0x0001) {
+		if (mii_reg & 0x0002)
+			*s |= PHY_STAT_100FDX;
+		else
+			*s |= PHY_STAT_100HDX;
+	} else {
+		if (mii_reg & 0x0002)
+			*s |= PHY_STAT_10FDX;
+		else
+			*s |= PHY_STAT_10HDX;
+	}
+}
+
+static phy_info_t phy_info_bcm5221 = {
+	0x0004061e,
+	"BCM5221",
+
+	(const phy_cmd_t []) { /* config */
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* startup - enable interrupts */
+		{ mk_mii_write(MII_BCM5221_IR, 0x4000), NULL },
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_read(MII_REG_SR), mii_parse_bcm5221_sr },
+		{ mk_mii_read(MII_REG_SR), mii_parse_bcm5221_sr },
+		{ mk_mii_read(MII_BCM5221_AUX_CSR), mii_parse_bcm5221_sr2 },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* ack_int */
+		/* find out the current status */
+		{ mk_mii_read(MII_REG_SR), mii_parse_bcm5221_sr }, /* clear etched bit */
+		{ mk_mii_read(MII_REG_SR), mii_parse_bcm5221_sr }, /* read status */
+		{ mk_mii_read(MII_BCM5221_AUX_CSR), mii_parse_bcm5221_sr2 },
+		{ mk_mii_read(MII_BCM5221_IR), NULL /*mii_parse_bcm5221_ir*/ }, /* ack */
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* shutdown - disable interrupts */
+		{ mk_mii_write(MII_BCM5221_IR, 0x0000), NULL },
+		{ mk_mii_end, }
+	},
+};
+
+#endif /* CONFIG_FEC_BCM5221 */
+
+static phy_info_t *phy_info[] = {
+
+#if defined(CONFIG_FEC_LXT970)
+	&phy_info_lxt970,
+#endif /* CONFIG_FEC_LXT970 */
+
+#if defined(CONFIG_FEC_LXT971)
+	&phy_info_lxt971,
+#endif /* CONFIG_FEC_LXT971 */
+
+#if defined(CONFIG_FEC_LXT972)
+	&phy_info_lxt972,
+#endif /* CONFIG_FEC_LXT972 */
+
+#if defined(CONFIG_FEC_QS6612)
+	&phy_info_qs6612,
+#endif /* CONFIG_FEC_QS6612 */
+
+#if defined(CONFIG_FEC_AM79C874)
+	&phy_info_am79c874,
+#endif /* CONFIG_FEC_AM79C874 */
+
+#if defined(CONFIG_FEC_KS8995M_P5)
+	&phy_info_ks8995m,
+#endif /* CONFIG_FEC_AM79C874 */
+
+#if defined(CONFIG_FEC_KS8721BL)
+	&phy_info_ks8721bl,
+#endif /* CONFIG_FEC_KS8721BL */
+
+#if defined(CONFIG_FEC_RTL8201BL)
+	&phy_info_rtl8201bl,
+#endif /* CONFIG_FEC_RTL8201BL */
+
+#if defined(CONFIG_FEC_DP83847)
+	&phy_info_dp83847,
+#endif /* CONFIG_FEC_DP83847 */
+
+#if defined(CONFIG_FEC_BCM5221)
+	&phy_info_bcm5221,
+#endif /* CONFIG_FEC_BCM5221 */
+
+	NULL
+};
+
+static void mii_display_status(struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	if (!fep->link && !fep->old_link) {
+		/* Link is still down - don't print anything */
+		return;
+	}
+
+	printk("%s: status: ", dev->name);
+
+	if (!fep->link) {
+		printk("link down");
+	} else {
+		printk("link up");
+
+		switch(*s & PHY_STAT_SPMASK) {
+		case PHY_STAT_100FDX: printk(", 100MBit Full Duplex"); break;
+		case PHY_STAT_100HDX: printk(", 100MBit Half Duplex"); break;
+		case PHY_STAT_10FDX: printk(", 10MBit Full Duplex"); break;
+		case PHY_STAT_10HDX: printk(", 10MBit Half Duplex"); break;
+		default:
+			printk(", Unknown speed/duplex");
+		}
+
+		if (*s & PHY_STAT_ANC)
+			printk(", auto-negotiation complete");
+	}
+
+	if (*s & PHY_STAT_FAULT)
+		printk(", remote fault");
+
+	printk(".\n");
+}
+
+static void mii_display_config(struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	printk("%s: config: auto-negotiation ", dev->name);
+
+	if (*s & PHY_CONF_ANE)
+		printk("on");
+	else
+		printk("off");
+
+	if (*s & PHY_CONF_100FDX)
+		printk(", 100FDX");
+	if (*s & PHY_CONF_100HDX)
+		printk(", 100HDX");
+	if (*s & PHY_CONF_10FDX)
+		printk(", 10FDX");
+	if (*s & PHY_CONF_10HDX)
+		printk(", 10HDX");
+	if (!(*s & PHY_CONF_SPMASK))
+		printk(", No speed/duplex selected?");
+
+	if (*s & PHY_CONF_LOOP)
+		printk(", loopback enabled");
+	
+	printk(".\n");
+
+	fep->sequence_done = 1;
+}
+
+static void mii_relink(struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	int duplex;
+
+	fep->link = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0;
+	mii_display_status(dev);
+	fep->old_link = fep->link;
+
+	if (fep->link) {
+		duplex = 0;
+		if (fep->phy_status & (PHY_STAT_100FDX | PHY_STAT_10FDX))
+			duplex = 1;
+		fec_restart(dev, duplex);
+		if (netif_queue_stopped(dev))
+		    netif_wake_queue(dev);
+
+	} else {
+		fec_stop(dev);
+	}
+}
+
+static void mii_queue_relink(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+
+	fep->phy_task.routine = (void *)mii_relink;
+	fep->phy_task.data = dev;
+	schedule_task(&fep->phy_task);
+}
+
+static void mii_queue_config(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+
+	fep->phy_task.routine = (void *)mii_display_config;
+	fep->phy_task.data = dev;
+	schedule_task(&fep->phy_task);
+}
+
+
+
+phy_cmd_t phy_cmd_relink[] = { { mk_mii_read(MII_REG_CR), mii_queue_relink },
+			       { mk_mii_end, } };
+phy_cmd_t phy_cmd_config[] = { { mk_mii_read(MII_REG_CR), mii_queue_config },
+			       { mk_mii_end, } };
+
+
+
+#if defined(M5272_PHY_STAT_INT) || !defined(CONFIG_M5272)
+static void
+#if defined(CONFIG_RPXCLASSIC)
+mii_link_interrupt(void *dev_id)
+#else
+mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+#endif
+{
+	struct net_device *dev = dev_id;
+	struct fec_enet_private *fep = dev->priv;
+
+#if defined(M5272_PHY_STAT_INT)
+	{
+		/* Acknowledge the interrupt */
+		volatile unsigned long  *icrp;
+
+		icrp = (volatile unsigned long *) (ICR_PHY_REG);
+		*icrp = (*icrp & ICR_PHY_MASK_IPL) | ICR_MASK_IP;
+	}
+#endif
+
+	if (fep->phy) {
+		mii_do_cmd(dev, fep->phy->ack_int);
+		/* restart and display status */
+		mii_do_cmd(dev, phy_cmd_relink);
+	}
+}
+#endif
+
+/* Read remainder of PHY ID.
+*/
+static void
+mii_discover_phy3(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep;
+	int	i;
+
+	fep = dev->priv;
+	fep->phy_id |= (mii_reg & 0xffff);
+	printk("fec: PHY @ 0x%x, ID 0x%08x", fep->phy_addr, fep->phy_id);
+
+	for(i = 0; phy_info[i]; i++) {
+		if(phy_info[i]->id == (fep->phy_id >> 4))
+			break;
+	}
+
+	if (phy_info[i]) {
+		printk(" -- %s\n", phy_info[i]->name);
+#if defined(M5272_PHY_STAT_INT)
+		if (request_irq(PHY_INT, mii_link_interrupt, 0, 
+						"fec(MII)", dev) != 0)
+			printk("FEC: Could not allocate MII IRQ(%d)!\n", PHY_INT);
+		{
+		/* Unmask interrupts at ColdFire 5272 SIM */
+			volatile unsigned long  *icrp;
+
+			icrp = (volatile unsigned long *) (ICR_PHY_REG);
+			*icrp = (*icrp & ICR_PHY_MASK) | ICR_PHY_SETUP;
+		}
+#endif
+	}
+	else {
+	    if (fep->phy_addr++ < 32) {
+		mii_queue(dev, mk_mii_read(MII_REG_PHYIR1),
+				  mii_discover_phy);
+		return;
+		}
+		else
+		    printk(" -- unknown PHY!\n");
+	}
+
+	fep->phy = phy_info[i];
+	fep->phy_id_done = 1;
+}
+
+/* Scan all of the MII PHY addresses looking for someone to respond
+ * with a valid ID.  This usually happens quickly.
+ */
+static void
+mii_discover_phy(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep;
+	volatile fec_t *fecp;
+	uint phytype;
+
+	fep = dev->priv;
+	fecp = fep->hwp;
+
+	if (fep->phy_addr < 32) {
+#if defined(CONFIG_FEC_RTL8201BL)
+		if ((phytype = (mii_reg & 0xffff)) != 0xffff) {
+#else
+		/* For all other cases we check for a valid phytype not 0x0000 or 0xffff */
+		if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) {
+#endif
+			
+			/* Got first part of ID, now get remainder.
+			*/
+			fep->phy_id = phytype << 16;
+			mii_queue(dev, mk_mii_read(MII_REG_PHYIR2),
+							mii_discover_phy3);
+		}
+		else {
+			fep->phy_addr++;
+			mii_queue(dev, mk_mii_read(MII_REG_PHYIR1),
+							mii_discover_phy);
+		}
+	} else {
+		printk("FEC: No PHY device found.\n");
+		/* Disable external MII interface */
+		fecp->fec_mii_speed = fep->phy_speed = 0;
+	}
+}
+
+static int
+fec_enet_open(struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+
+	/* I should reset the ring buffers here, but it's done in
+	 * the close routine because init already set them up
+	 */
+
+	fep->sequence_done = 0;
+	fep->link = 0;
+
+	if (fep->phy) {
+		mii_do_cmd(dev, fep->phy->ack_int);
+		mii_do_cmd(dev, fep->phy->config);
+		mii_do_cmd(dev, phy_cmd_config);  /* display configuration */
+
+		while(!fep->sequence_done)
+			schedule();
+
+		mii_do_cmd(dev, fep->phy->startup);
+#if defined( CONFIG_FEC_KS8995M_P5)
+		mii_do_cmd(dev, phy_cmd_relink);
+#endif
+#if !defined( M5272_PHY_STAT_INT)
+		fep->link = 1; /* Always assume we are connected (no interrupt
+						  to turn on/off link) */
+#endif
+		fec_enet_setup_hw_p1( dev);
+		netif_start_queue(dev);
+		fec_enet_setup_hw_p2( dev);
+	} else {
+		fep->link = 1; /* lets just try it and see */
+		/* no phy,  go full duplex,  it's most likely a hub chip */
+		fec_restart(dev, 1);
+		netif_start_queue(dev);
+	}
+
+	fep->opened = 1;
+	return 0;		/* Success */
+}
+
+static int
+fec_enet_close(struct net_device *dev)
+{
+	int i;
+	volatile cbd_t *bdp;
+	struct fec_enet_private *fep;
+	volatile fec_t *fecp;
+
+	fep = (struct fec_enet_private *)dev->priv;
+	fecp = fep->hwp;
+
+	/* open/close now works - but see notes below
+	 */
+  
+	fep->opened = 0;
+	netif_stop_queue(dev);
+	fec_stop(dev);
+
+	/**********************************************
+	 * Have to do all this after operations stopped
+	 **********************************************/
+	/* Set maximum receive buffer size.
+	*/
+	fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
+#if !defined(CONFIG_COLDFIRE)
+	fecp->fec_r_hash = PKT_MAXBUF_SIZE;
+#endif /* CONFIG_M5272 */
+
+	/* Set receive and transmit descriptor base.
+	*/
+	fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base));
+	fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base));
+
+	fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
+	fep->cur_rx = fep->rx_bd_base;
+
+  /******************************************
+   * Well, first let's free all the tx skb's 
+   * so we don't have a memory leak.
+   * -Bring ring back to init state (NOTE we
+   * should do this in the open, but then I'd
+   * have to shift code from the open AND we
+   * are NOT running as a module ...MaTed
+   ******************************************/
+  bdp = fep->tx_bd_base;
+  for (i = 0; i < TX_RING_SIZE; i++)
+  {
+	if (fep->tx_skbuff[i] != NULL)
+	{
+	  dev_kfree_skb_any(fep->tx_skbuff[i]);
+	  fep->tx_skbuff[i] = NULL;
+	}
+  }
+  /******************************************
+   * -Bring ring back to init state (NOTE we
+   * should do this in the open, but then I'd
+   * have to shift code from the open AND we
+   * are NOT running as a module ...MaTed
+   ******************************************/
+  bdp = fep->rx_bd_base;
+  for (i = 0; i < RX_RING_SIZE; i++)
+  {
+	/* Initialize the BD for every fragment in the page.
+	 */
+	bdp->cbd_sc = BD_ENET_RX_EMPTY;
+	bdp++;
+  }
+	/* Set the last buffer to wrap.
+	*/
+	bdp--;
+	bdp->cbd_sc |= BD_SC_WRAP;
+
+	/* ...and the same for transmmit.
+	*/
+	bdp = fep->tx_bd_base;
+	for (i=0; i<TX_RING_SIZE; i++) {
+
+		/* Initialize the BD for every fragment in the page.
+		*/
+		bdp->cbd_sc = 0;
+		bdp->cbd_bufaddr = 0;
+		bdp++;
+	}
+
+	/* Set the last buffer to wrap.
+	*/
+	bdp--;
+	bdp->cbd_sc |= BD_SC_WRAP;
+
+	return 0;
+}
+
+static struct net_device_stats *fec_enet_get_stats(struct net_device *dev)
+{
+	struct fec_enet_private *fep = (struct fec_enet_private *)dev->priv;
+
+	return &fep->stats;
+}
+
+/* Set or clear the multicast filter for this adaptor.
+ * Skeleton taken from sunlance driver.
+ * The CPM Ethernet implementation allows Multicast as well as individual
+ * MAC address filtering.  Some of the drivers check to make sure it is
+ * a group multicast address, and discard those that are not.  I guess I
+ * will do the same for now, but just remove the test if you want
+ * individual filtering as well (do the upper net layers want or support
+ * this kind of feature?).
+ */
+
+#define HASH_BITS	6		/* #bits in hash */
+#define CRC32_POLY	0xEDB88320
+
+static void set_multicast_list(struct net_device *dev)
+{
+	struct fec_enet_private *fep;
+	volatile fec_t *ep;
+	struct dev_mc_list *dmi;
+	unsigned int i, j, bit, data, crc;
+	unsigned char hash;
+
+	fep = (struct fec_enet_private *)dev->priv;
+	ep = fep->hwp;
+
+	if (dev->flags&IFF_PROMISC) {
+		/* Log any net taps. */
+		printk("%s: Promiscuous mode enabled.\n", dev->name);
+		ep->fec_r_cntrl |= 0x0008;
+	} else {
+
+		ep->fec_r_cntrl &= ~0x0008;
+
+		if (dev->flags & IFF_ALLMULTI) {
+			/* Catch all multicast addresses, so set the
+			 * filter to all 1's.
+			 */
+			ep->fec_hash_table_high = 0xffffffff;
+			ep->fec_hash_table_low = 0xffffffff;
+		} else {
+			/* Clear filter and add the addresses in hash register.
+			*/
+			ep->fec_hash_table_high = 0;
+			ep->fec_hash_table_low = 0;
+            
+			dmi = dev->mc_list;
+
+			for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) {
+				/* Only support group multicast for now.
+				*/
+				if (!(dmi->dmi_addr[0] & 1))
+					continue;
+			
+				/* calculate crc32 value of mac address
+				*/
+				crc = 0xffffffff;
+
+				for (i = 0; i < dmi->dmi_addrlen; i++) {
+					data = dmi->dmi_addr[i];
+					for (bit = 0; bit < 8; bit++,
+					data >>= 1) {
+						crc = (crc >> 1) ^
+						(((crc ^ data) & 1) ? CRC32_POLY : 0);
+					}
+				}
+
+				/* only upper 6 bits (HASH_BITS) are used
+				   which point to specific bit in he hash registers
+				*/
+				hash = (crc >> (32 - HASH_BITS)) & 0x3f;
+			
+				if (hash > 31)
+					ep->fec_hash_table_high |= 1 << (hash - 32);
+				else
+					ep->fec_hash_table_low |= 1 << hash;
+			}
+		}
+	}
+}
+
+/* Set a MAC change in hardware.
+ */
+static int
+fec_set_mac_address(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr=p;
+	struct fec_enet_private *fep;
+	volatile fec_t *fecp;
+
+	fep = (struct fec_enet_private *)dev->priv;
+	fecp = fep->hwp;
+
+	if (netif_running(dev))
+		return -EBUSY;
+
+	/* Set the device copy of the Ethernet address
+	*/
+	memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
+      
+	/* Set our copy of the Ethernet address 
+	*/
+	memcpy(fep->mac_addr, addr->sa_data,dev->addr_len);
+
+	/* Set station address.
+	*/
+	fecp->fec_addr_low = fep->mac_addr[3] | (fep->mac_addr[2] << 8) |
+		(fep->mac_addr[1] << 16) | (fep->mac_addr[0] << 24);
+	fecp->fec_addr_high = (fep->mac_addr[5] << 16) |
+		(fep->mac_addr[4] << 24);
+  
+	return 0;
+}
+
+/* Initialize the FEC Ethernet on 860T.
+ */
+int __init fec_enet_init(struct net_device *dev)
+{
+	struct fec_enet_private *fep;
+	unsigned long	mem_addr;
+	volatile cbd_t	*bdp;
+	cbd_t		*cbd_base;
+	volatile fec_t	*fecp;
+	unsigned char	*eap, *iap;
+	static int      probes = 0;
+	int		index, i, j;
+	unsigned char	tmpaddr[6];
+#if !defined(CONFIG_COLDFIRE)
+	pte_t		*pte;
+	extern		uint	_get_IMMR(void);
+	bd_t		*bd;
+	volatile	immap_t	*immap;
+
+	immap = (immap_t *)IMAP_ADDR;	/* pointer to internal registers */
+	bd = (bd_t *)__res;
+#endif
+
+	index = probes;
+	if (probes >= FEC_MAX)
+	  return(-ENXIO);
+	else
+	  probes++;
+
+	printk ("fec.c: Probe number %d with 0x%04lx\n",
+		probes, dev->base_addr);
+
+	fecp = (volatile fec_t *) fec_hw[index];
+
+	/* Save current MAC address */
+	*((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
+	*((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
+
+	/* Allocate some private information.
+	*/
+	fep = (struct fec_enet_private *)kmalloc(sizeof(*fep), GFP_KERNEL);
+	__clear_user(fep,sizeof(*fep));
+	fep->hwp = fecp;
+
+	/* Whack a reset.  We should wait for this.
+	*/
+	fecp->fec_ecntrl = FEC_ENET_RESET;
+	udelay(10);
+
+	/* Clear and enable interrupts */
+	fecp->fec_ievent = 0xffc0;
+	fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
+		FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
+	fecp->fec_hash_table_high = 0;
+	fecp->fec_hash_table_low = 0;
+	fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
+        //fecp->fec_ecntrl = 2; // this is too early PSW
+        fecp->fec_r_des_active = 0x01000000;
+
+	/*
+	 * Set the Ethernet address. If using multiple Enets on the 8xx,
+	 * this needs some work to get unique addresses.
+	 */
+	eap = (unsigned char *)fep->mac_addr;
+	for (i=0; (i<6); i++)
+		eap[i] = fec_mac_default[i];
+	eap[5] = index;
+
+#if defined(CONFIG_COLDFIRE)
+#if defined(CONFIG_NETtel) || defined(CONFIG_GILBARCONAP) || \
+    defined(CONFIG_SE1100) || defined(CONFIG_HW_FEITH)
+	/*
+	 * If the MAC is all 1's or 0's, used the default coded one.
+	 */
+#if defined(CONFIG_GILBARCONAP) || defined(CONFIG_SE1100) || \
+    defined(CONFIG_SCALES)
+	iap = (unsigned char *) 0xf0006000;
+#elif defined(CONFIG_CANCam)
+	iap = (unsigned char *) 0xf0020000;
+#else
+	iap = (unsigned char *) 0xf0006006;
+#endif
+	if (!iap[0] && !iap[1] && !iap[2] && !iap[3] && !iap[4] && !iap[5])
+		iap = eap;
+	if (iap[0] == 0xff && iap[1] == 0xff && iap[2] == 0xff &&
+	    iap[3] == 0xff && iap[4] == 0xff && iap[5] == 0xff)
+		iap = eap;
+#elif defined (CONFIG_MTD_KeyTechnology)
+	iap = (unsigned char *)0xffe04000;
+	if (!iap[0] && !iap[1] && !iap[2] && !iap[3] && !iap[4] && !iap[5])
+		iap = eap;
+	if (iap[0] == 0xff && iap[1] == 0xff && iap[2] == 0xff &&
+	    iap[3] == 0xff && iap[4] == 0xff && iap[5] == 0xff)
+		iap = eap;
+#elif defined(CONFIG_BOARD_UC5272)
+	memcpy(&tmpaddr, &fec_hwaddr, 6);
+	iap = &tmpaddr[0];
+#else
+	/*
+	 *	We will assume something else has written a valid MAC
+	 *	address into the FEC registers. Only problem is if no
+	 *	one did we might have an invalid address, so we force
+	 *	the first broadcast and multicast bits to 0.
+	 */
+	tmpaddr[0] &= 0xf8;
+	iap = tmpaddr;
+#endif /* CONFIG_NETtel || CONFIG_GILBARCONAP*/
+#else /* not defined(CONFIG_COLDFIRE) */
+	iap = bd->bi_enetaddr;
+#endif /* CONFIG_COLDFIRE */
+
+#if defined(CONFIG_RPXCLASSIC)
+	/* The Embedded Planet boards have only one MAC address in
+	 * the EEPROM, but can have two Ethernet ports.  For the
+	 * FEC port, we create another address by setting one of
+	 * the address bits above something that would have (up to
+	 * now) been allocated.
+	 */
+	for (i=0; i<6; i++)
+		tmpaddr[i] = *iap++;
+	tmpaddr[3] |= 0x80;
+	iap = tmpaddr;
+#endif
+
+	for (i=0; i<6; i++)
+		dev->dev_addr[i] = *eap++ = *iap++;
+
+	/* Allocate memory for buffer descriptors.
+	*/
+	if (((RX_RING_SIZE + TX_RING_SIZE) * sizeof(cbd_t)) > PAGE_SIZE) {
+		printk("FEC init error.  Need more space.\n");
+		printk("FEC initialization failed.\n");
+		return 1;
+	}
+	mem_addr = __get_free_page(GFP_KERNEL);
+	cbd_base = (cbd_t *)mem_addr;
+
+#if !defined(CONFIG_UCLINUX)
+	/* Make it uncached.
+	*/
+	pte = va_to_pte(mem_addr);
+	pte_val(*pte) |= _PAGE_NO_CACHE;
+	flush_tlb_page(init_mm.mmap, mem_addr);
+#endif /* CONFIG_UCLINUX */
+
+	/* Set receive and transmit descriptor base.
+	*/
+	fep->rx_bd_base = cbd_base;
+	fep->tx_bd_base = cbd_base + RX_RING_SIZE;
+
+	fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
+	fep->cur_rx = fep->rx_bd_base;
+
+	fep->skb_cur = fep->skb_dirty = 0;
+
+	/* Initialize the receive buffer descriptors.
+	*/
+	bdp = fep->rx_bd_base;
+	for (i=0; i<FEC_ENET_RX_PAGES; i++) {
+
+		/* Allocate a page.
+		*/
+		mem_addr = __get_free_page(GFP_KERNEL);
+
+#if !defined(CONFIG_UCLINUX)
+		/* Make it uncached.
+		*/
+		pte = va_to_pte(mem_addr);
+		pte_val(*pte) |= _PAGE_NO_CACHE;
+		flush_tlb_page(init_mm.mmap, mem_addr);
+#endif /* CONFIG_UCLINUX */
+
+		/* Initialize the BD for every fragment in the page.
+		*/
+		for (j=0; j<FEC_ENET_RX_FRPPG; j++) {
+			bdp->cbd_sc = BD_ENET_RX_EMPTY;
+			bdp->cbd_bufaddr = __pa(mem_addr);
+			mem_addr += FEC_ENET_RX_FRSIZE;
+			bdp++;
+		}
+	}
+
+	/* Set the last buffer to wrap.
+	*/
+	bdp--;
+	bdp->cbd_sc |= BD_SC_WRAP;
+
+	/* ...and the same for transmmit.
+	*/
+	bdp = fep->tx_bd_base;
+	for (i=0, j=FEC_ENET_TX_FRPPG; i<TX_RING_SIZE; i++) {
+#if defined(CONFIG_M5235) || defined(CONFIG_M527x) || \
+    defined(CONFIG_M5280) || defined(CONFIG_M5282)
+		if (j >= FEC_ENET_TX_FRPPG) {
+			mem_addr = __get_free_page(GFP_KERNEL);
+			j = 1;
+		} else {
+			mem_addr += FEC_ENET_TX_FRSIZE;
+			j++;
+		}
+		fep->tx_bounce[i] = (unsigned char *) mem_addr;
+#endif
+
+		/* Initialize the BD for every fragment in the page.
+		*/
+		bdp->cbd_sc = 0;
+		bdp->cbd_bufaddr = 0;
+		bdp++;
+	}
+
+	/* Set the last buffer to wrap.
+	*/
+	bdp--;
+	bdp->cbd_sc |= BD_SC_WRAP;
+
+	/* Set receive and transmit descriptor base.
+	*/
+	fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base));
+	fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base));
+
+	/* Install our interrupt handler.
+	*/
+#if defined(CONFIG_M5272)
+	/* Setup interrupt handlers. */
+	if (request_irq(86, fec_enet_interrupt, 0, "fec(RX)", dev) != 0)
+		printk("FEC: Could not allocate FEC(RX) IRQ(86)!\n");
+	if (request_irq(87, fec_enet_interrupt, 0, "fec(TX)", dev) != 0)
+		printk("FEC: Could not allocate FEC(TX) IRQ(87)!\n");
+	if (request_irq(88, fec_enet_interrupt, 0, "fec(OTHER)", dev) != 0)
+		printk("FEC: Could not allocate FEC(OTHER) IRQ(88)!\n");
+
+	/* Unmask interrupts at ColdFire 5272 SIM */
+	{
+		volatile unsigned long  *icrp;
+
+		icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR3);
+		*icrp = 0x00000ddd;
+	}
+#elif defined(CONFIG_M5235) || defined(CONFIG_M527x) || \
+      defined(CONFIG_M5282) || defined(CONFIG_M5280)
+	j = (index) ? 128 : 64;
+
+	/* Setup interrupt handlers. */
+	if (request_irq(j+23, fec_enet_interrupt, 0, "fec(TXF)", dev) != 0)
+		printk("FEC: Could not allocate FEC(TXF) IRQ(%d+23)!\n", j);
+	if (request_irq(j+24, fec_enet_interrupt, 0, "fec(TXB)", dev) != 0)
+		printk("FEC: Could not allocate FEC(TXB) IRQ(%d+24)!\n", j);
+	if (request_irq(j+25, fec_enet_interrupt, 0, "fec(TXFIFO)", dev) != 0)
+		printk("FEC: Could not allocate FEC(TXFIFO) IRQ(%d+25)!\n", j);
+	if (request_irq(j+26, fec_enet_interrupt, 0, "fec(TXCR)", dev) != 0)
+		printk("FEC: Could not allocate FEC(TXCR) IRQ(%d+26)!\n", j);
+
+	if (request_irq(j+27, fec_enet_interrupt, 0, "fec(RXF)", dev) != 0)
+		printk("FEC: Could not allocate FEC(RXF) IRQ(%d+27)!\n", j);
+	if (request_irq(j+28, fec_enet_interrupt, 0, "fec(RXB)", dev) != 0)
+		printk("FEC: Could not allocate FEC(RXB) IRQ(%d+28)!\n", j);
+
+	if (request_irq(j+29, fec_enet_interrupt, 0, "fec(MII)", dev) != 0)
+		printk("FEC: Could not allocate FEC(MII) IRQ(%d+29)!\n", j);
+	if (request_irq(j+30, fec_enet_interrupt, 0, "fec(LC)", dev) != 0)
+		printk("FEC: Could not allocate FEC(LC) IRQ(%d+30)!\n", j);
+	if (request_irq(j+31, fec_enet_interrupt, 0, "fec(HBERR)", dev) != 0)
+		printk("FEC: Could not allocate FEC(HBERR) IRQ(%d+31)!\n", j);
+	if (request_irq(j+32, fec_enet_interrupt, 0, "fec(GRA)", dev) != 0)
+		printk("FEC: Could not allocate FEC(GRA) IRQ(%d+32)!\n", j);
+	if (request_irq(j+33, fec_enet_interrupt, 0, "fec(EBERR)", dev) != 0)
+		printk("FEC: Could not allocate FEC(EBERR) IRQ(%d+33)!\n", j);
+	if (request_irq(j+34, fec_enet_interrupt, 0, "fec(BABT)", dev) != 0)
+		printk("FEC: Could not allocate FEC(BABT) IRQ(%d+34)!\n", j);
+	if (request_irq(j+35, fec_enet_interrupt, 0, "fec(BABR)", dev) != 0)
+		printk("FEC: Could not allocate FEC(BABR) IRQ(%d+35)!\n", j);
+
+	/* Unmask interrupts at ColdFire 5282 interrupt controller */
+	{
+		volatile unsigned char  *icrp;
+		volatile unsigned long  *imrp;
+
+		j = (index) ? MCFICM_INTC1 : MCFICM_INTC0;
+
+		icrp = (volatile unsigned char *) (MCF_IPSBAR + j +
+			MCFINTC_ICR0);
+		for (i = 23; (i < 36); i++)
+			icrp[i] = 0x23;
+
+		imrp = (volatile unsigned long *) (MCF_IPSBAR + j +
+			MCFINTC_IMRH);
+		*imrp &= ~0x0000000f;
+		imrp = (volatile unsigned long *) (MCF_IPSBAR + j +
+			MCFINTC_IMRL);
+		*imrp &= ~0xff800001;
+	}
+
+	/* Setup pin multplexing for ethernet/MII lines */
+#if defined(CONFIG_M5280) || defined(CONFIG_M5282)
+	*(volatile unsigned char *)(MCF_IPSBAR + MCF5282_GPIO_PEHLPAR) |= 0xc0;
+	*(volatile unsigned short *)(MCF_IPSBAR + MCF5282_GPIO_PASPAR) |= 0x0f00;
+#elif defined(CONFIG_M5235)
+	*(volatile unsigned char*)(MCF_IPSBAR + MCF5235_GPIO_PFECI2CPAR) |= 0xf0;
+#endif
+
+#else
+	if (request_8xxirq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0)
+		panic("Could not allocate FEC IRQ!");
+#endif
+
+#if defined(CONFIG_RPXCLASSIC)
+	/* Make Port C, bit 15 an input that causes interrupts.
+	*/
+	immap->im_ioport.iop_pcpar &= ~0x0001;
+	immap->im_ioport.iop_pcdir &= ~0x0001;
+	immap->im_ioport.iop_pcso &= ~0x0001;
+	immap->im_ioport.iop_pcint |= 0x0001;
+	cpm_install_handler(CPMVEC_PIO_PC15, mii_link_interrupt, dev);
+
+	/* Make LEDS reflect link status.
+	*/
+	*((uint *) RPX_CSR_ADDR) &= ~BCSR2_FETHLEDMODE;
+#endif
+#if defined(CONFIG_FADS)
+	if (request_8xxirq(SIU_IRQ2, mii_link_interrupt, 0, "mii", dev) != 0)
+		panic("Could not allocate MII IRQ!");
+#endif
+
+	dev->base_addr = (unsigned long)fecp;
+	dev->priv = fep;
+        /* enable the device at this location to stop boot hangs PSW */
+        fecp->fec_ecntrl = 2; 
+
+	ether_setup(dev);
+
+	/* The FEC Ethernet-specific entries in the device structure. */
+	dev->open = fec_enet_open;
+	dev->hard_start_xmit = fec_enet_start_xmit;
+	dev->tx_timeout = fec_timeout;
+	dev->watchdog_timeo = TX_TIMEOUT;
+	dev->stop = fec_enet_close;
+	dev->get_stats = fec_enet_get_stats;
+	dev->set_multicast_list = set_multicast_list;
+	dev->set_mac_address = fec_set_mac_address;
+#if defined(CONFIG_FEC_IOCTL)
+	dev->do_ioctl = &fec_ioctl;
+#endif
+	for (i=0; i<NMII-1; i++)
+		mii_cmds[i].mii_next = &mii_cmds[i+1];
+	mii_free = mii_cmds;
+
+#if defined(CONFIG_COLDFIRE)
+	fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
+	fecp->fec_x_cntrl = 0x00;
+
+	/* Set MII speed to 2.5 MHz
+	*/
+#if defined (CONFIG_M5272)
+	fep->phy_speed = (((MCF_CLK / 4) / (2500000 / 10)) + 5) / 10;
+	fep->phy_speed *= 2; /* see 5272 manual sec 11.5.8: MSCR */
+#elif defined(CONFIG_M5235) || defined(CONFIG_M527x) || \
+      defined (CONFIG_M5282) || defined(CONFIG_M5280)
+	fep->phy_speed = (((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10;
+	fep->phy_speed *= 2; /* see 5282 manual sec 17.5.4.7: MSCR */
+#endif	
+	fecp->fec_mii_speed = fep->phy_speed;
+
+	fec_restart(dev, 0);
+#else
+	/* Configure all of port D for MII.
+	*/
+	immap->im_ioport.iop_pdpar = 0x1fff;
+
+	/* Bits moved from Rev. D onward.
+	*/
+	if ((_get_IMMR() & 0xffff) < 0x0501)
+		immap->im_ioport.iop_pddir = 0x1c58;	/* Pre rev. D */
+	else
+		immap->im_ioport.iop_pddir = 0x1fff;	/* Rev. D and later */
+	
+	/* Set MII speed to 2.5 MHz
+	*/
+	fecp->fec_mii_speed = fep->phy_speed = 
+		((bd->bi_busfreq * 1000000) / 2500000) & 0x7e;
+#endif /* CONFIG_COLDFIRE */
+	printk("%s: FEC ENET Version 0.2, ", dev->name);
+	for (i=0; i<5; i++)
+		printk("%02x:", dev->dev_addr[i]);
+	printk("%02x\n", dev->dev_addr[5]);
+
+	/* Queue up command to detect the PHY and initialize the
+	 * remainder of the interface.
+	 */
+	fep->phy_id_done = 0;
+#if defined(CONFIG_M5272)
+	fep->phy_addr = PHY_START_ADDR;
+#endif /* CONFIG_M5272 */
+#ifdef BIT_BANG_THE_MII
+	MII_bit_bang_initialize();
+#endif
+	mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy);
+
+	return 0;
+}
+
+/* This function is called to start or restart the FEC during a link
+ * change.  This only happens when switching between half and full
+ * duplex.
+ */
+static void
+fec_restart(struct net_device *dev, int duplex)
+{
+	struct fec_enet_private *fep;
+	volatile cbd_t *bdp;
+	volatile fec_t *fecp;
+	int i;
+
+	fep = (struct fec_enet_private *)dev->priv;
+	fecp = fep->hwp;
+
+	/* Whack a reset.  We should wait for this.
+	*/
+	fecp->fec_ecntrl = 1;
+	udelay(10);
+
+	fec_enet_setup_hw_p1( dev);
+
+	/* Set receive and transmit descriptor base.
+	*/
+	fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base));
+	fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base));
+
+	fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
+	fep->cur_rx = fep->rx_bd_base;
+
+	/* Reset SKB transmit buffers.
+	*/
+	fep->skb_cur = fep->skb_dirty = 0;
+	for (i=0; i<=TX_RING_MOD_MASK; i++) {
+		if (fep->tx_skbuff[i] != NULL) {
+			dev_kfree_skb_any(fep->tx_skbuff[i]);
+			fep->tx_skbuff[i] = NULL;
+		}
+	}
+
+	/* Initialize the receive buffer descriptors.
+	*/
+	bdp = fep->rx_bd_base;
+	for (i=0; i<RX_RING_SIZE; i++) {
+
+		/* Initialize the BD for every fragment in the page.
+		*/
+		bdp->cbd_sc = BD_ENET_RX_EMPTY;
+		bdp++;
+	}
+
+	/* Set the last buffer to wrap.
+	*/
+	bdp--;
+	bdp->cbd_sc |= BD_SC_WRAP;
+
+	/* ...and the same for transmmit.
+	*/
+	bdp = fep->tx_bd_base;
+	for (i=0; i<TX_RING_SIZE; i++) {
+
+		/* Initialize the BD for every fragment in the page.
+		*/
+		bdp->cbd_sc = 0;
+		bdp->cbd_bufaddr = 0;
+		bdp++;
+	}
+
+	/* Set the last buffer to wrap.
+	*/
+	bdp--;
+	bdp->cbd_sc |= BD_SC_WRAP;
+
+	fep->full_duplex = duplex;
+	fec_enet_setup_hw_p2( dev );
+}
+
+static void
+fec_stop(struct net_device *dev)
+{
+	struct fec_enet_private *fep;
+	volatile fec_t *fecp;
+
+	fep = (struct fec_enet_private *)dev->priv;
+	fecp = fep->hwp;
+
+	fecp->fec_x_cntrl = FEC_ENET_GTS;	/* Graceful transmit stop */
+
+	while(!(fecp->fec_ievent & FEC_ENET_GRA));
+
+	/* Whack a reset.  We should wait for this.
+	*/
+	fecp->fec_ecntrl = FEC_ENET_RESET;
+	udelay(10);
+
+	/* Clear outstanding MII command interrupts.
+	*/
+	fecp->fec_ievent = FEC_ENET_MII;
+
+#if !defined(CONFIG_COLDFIRE)
+	/* Enable MII command finished interrupt 
+	*/
+	fecp->fec_ivec = (FEC_INTERRUPT/2) << 29;
+#endif /* !CONFIG_COLDFIRE */
+
+	fecp->fec_imask = FEC_ENET_MII;
+	fecp->fec_mii_speed = fep->phy_speed;
+}
+
+static void fec_enet_setup_hw_p1( struct net_device *dev )
+{
+	unsigned char *eap;
+	struct fec_enet_private *fep;
+	volatile fec_t *fecp;
+	int i;
+
+	fep = (struct fec_enet_private *)dev->priv;
+	fecp = fep->hwp;
+
+	/* Enable interrupts we wish to service.
+	*/
+	fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
+			   FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
+
+	/* Clear any outstanding interrupt.
+	*/
+	fecp->fec_ievent = FEC_ENET_ALLINT;
+
+#if !defined(CONFIG_COLDFIRE)
+	fecp->fec_ivec = (FEC_INTERRUPT/2) << 29;
+#endif /* !CONFIG_COLDFIRE */
+
+	/* Set station address.
+	*/
+	eap = (unsigned char *)&fep->mac_addr[0];
+	fecp->fec_addr_low = eap[3] | (eap[2] << 8) | (eap[1] << 16) |
+		(eap[0] << 24);
+	fecp->fec_addr_high = (eap[5] << 16) | (eap[4] << 24);
+
+	for (i=0; i<6; i++)
+		dev->dev_addr[i] = eap[i];
+
+	/* Reset all multicast.
+	*/
+	fecp->fec_hash_table_high = 0;
+	fecp->fec_hash_table_low = 0;
+
+	/* Set maximum receive buffer size.
+	*/
+	fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
+#if !defined(CONFIG_COLDFIRE)
+	fecp->fec_r_hash = PKT_MAXBUF_SIZE;
+#endif /* !CONFIG_COLDFIRE */
+
+	return;
+}
+
+static void 
+fec_enet_setup_hw_p2( struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile fec_t *fecp;
+
+	fecp = fep->hwp;
+
+	/* Enable MII mode.
+	*/
+	if (fep->full_duplex) {
+		fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;/* MII enable */
+		fecp->fec_x_cntrl = 0x04;		  /* FD enable */
+	}
+	else {
+		/* MII enable|No Rcv on Xmit */
+		fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x06;
+		fecp->fec_x_cntrl = 0x00;
+	}
+
+#if !defined(CONFIG_COLDFIRE)
+	/* Enable big endian and don't care about SDMA FC.
+	*/
+	fecp->fec_fun_code = 0x78000000;
+#endif /* !CONFIG_COLDFIRE */
+
+	/* Set MII speed.
+	*/
+	fecp->fec_mii_speed = fep->phy_speed;
+
+	/* And last, enable the transmit and receive processing.
+	*/
+	fecp->fec_ecntrl = 2;
+	fecp->fec_r_des_active = 0x01000000;
+    return;
+}
+
+#if defined(CONFIG_FEC_IOCTL)
+#define FEC_IOCTL_LXT972_STAT2	17		// lxt972 status 2 register
+
+/*******************************************************************
+ *  fec_ioctl_save_reg
+ * Description:
+ *	This routine saves the register read for fec_ioctl for subsequent
+ * retrieval by another user ioctl call (see below)
+ *
+ * Parameters:
+ *	uint mii_reg
+ *		- # of the register requested
+ *	struct net_device *dev
+ *		- dev entry
+ *
+ *	Returns:
+ *		0 -> SUCCESS
+ *	   -1 -> already an outstanding queued get request
+ *******************************************************************/
+static void fec_ioctl_save_reg( uint mii_reg, struct net_device *dev)
+{
+  struct fec_enet_private 	*fep 	= (struct fec_enet_private *)dev->priv;
+  fep->fec_ioctl_regval = mii_reg;	// save the value
+  fep->fec_ioctl_wait = 1;			// indicate value is saved
+  return;
+}
+
+/********************************************************************
+ *	FEC_IOCTL
+ * Description:
+ *	This routine implements Donald Becker's MII IOCTL interface. It 
+ * has a couple of minor extensions. At the present time only the
+ * extension has been implemented and tested. Portions of the other
+ * calls have implemented and not tested.  
+ *
+ * Parameters
+ *	- dev		- pointer to the device table
+ *	- rq		- pointer to the interface Request Structure which contains
+ *				a pointer to the ioctl data transfer area (see fec_ioctl.h)
+ */
+static int fec_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+  struct fec_enet_private 	*fep 	= (struct fec_enet_private *) dev->priv;
+
+  struct fec_ioctl_data 	*data	= (struct fec_ioctl_data *) &rq->ifr_data;
+
+  int						 retval	= 0;	// default is good return
+  int						 link_stat;	    // link status		
+
+  if (FEC_DEBUG > 5)
+	printk(" FEC_IOCTL**: entered: %s (dev-%p, rq-%p, cmd-%d) data-%p\n ",
+		   dev->name, dev, rq, cmd, data);
+
+	switch (cmd) {
+  case SIOCGMIIPHY:               /* Get address of MII PHY in use. */
+  case SIOCDEVPRIVATE:            /* for binary compat, remove in 2.5 */
+
+	if (FEC_DEBUG > 5)
+	  printk(" FEC_IOCTL**: SIOCGMIIPHY: %s returning data->phy_id %d\n ",
+			 dev->name, fep->phy_addr);
+
+	data->phy_id = fep->phy_addr;
+	break;
+
+	/* NO fall through - just do what was requested */
+  case SIOCGMIIREG:               /* Read MII PHY register. */
+  case SIOCDEVPRIVATE+1:          /* for binary compat, remove in 2.5 */
+	data->phy_id = fep->phy_addr;	// Setup - just because
+
+	if (FEC_DEBUG > 5)
+	  printk(" FEC_IOCTL**: SIOCGMIIREG: %s data->in %d, fec_ioctl_wait-%d\n ",
+			 dev->name, data->value_in, fep->fec_ioctl_wait);
+
+		if (data->value_in == SIOC_MIIREG_GET) {
+	  // check if already have an outstanding request (queued or waiting 
+	  //  to be read
+			if (fep->fec_ioctl_wait !=0) {
+		retval = -EALREADY;
+		data->link_speed = data->duplex = SIOC_FEC_RC_NOT_COMP;
+		break;
+	  }
+	  // queue the command to be issued
+	  fep->fec_ioctl_reg = data->reg;
+	  fep->fec_ioctl_wait = 2;	// waiting for queued command to complete
+	  
+	  mii_queue( dev, mk_mii_read( data->reg), fec_ioctl_save_reg);
+	  break;
+	}
+
+		if (data->value_in == SIOC_MIIREG_QUERY) {
+	  // check if we are still waiting for queued command to complete
+			if (fep->fec_ioctl_wait == 2) {
+		retval = -EAGAIN;		// try again (just the query
+		data->link_speed = data->duplex = SIOC_FEC_RC_NOT_COMP;
+		break;
+	  }
+	  // check if data available
+			if (fep->fec_ioctl_wait == 0) {
+		// not request outstanding and no data available
+		retval = -ENODATA;	// mismatch on the query
+		data->link_speed = data->duplex = SIOC_FEC_RC_NO_REQUEST;
+		break;
+	  }
+	  // We have valid data
+	  fep->fec_ioctl_wait = 0;	// mark as read
+	  data->value_out = fep->fec_ioctl_regval;	 // set read register
+
+			if (FEC_DEBUG > 5) {
+		printk(" FEC_IOCTL**: VALID DATA: %s internal (reg[%d] = 0x%x)\n ",
+			   dev->name, data->reg, data->value_out);
+		printk("         L**: VALID DATA: %s mii-tool (reg[%d] = 0x%x)\n ",
+			   dev->name, fep->fec_ioctl_reg, fep->fec_ioctl_regval);
+	  }
+
+	  // check if the register value passed as one we read
+	  if (fep->fec_ioctl_reg != data->reg)
+	  {
+		retval = -EINVAL;	// mismatch on the query invalid register passed
+		data->link_speed = data->duplex = SIOC_FEC_RC_WRONG_REG;
+		break;
+	  }
+
+	  // check if for the STAT2 register
+	  if (fep->fec_ioctl_reg == FEC_IOCTL_LXT972_STAT2)
+	  {
+		link_stat = (fep->fec_ioctl_regval &
+					 PHY_STATUS_REG_TWO_LINK) ? 1 : 0 ;
+		if (FEC_DEBUG > 4)
+		{
+		  printk("         **: STAT2 READ: %s link_stat/fep=%d/%d reg=0x%x\n ",
+				 dev->name, link_stat, fep->link, fep->fec_ioctl_regval);
+		}
+		if (link_stat)
+		{
+		  // need to translate (only available values)
+		  data->link_speed = (fep->fec_ioctl_regval & 
+							  PHY_STATUS_REG_TWO_MODE_100) ? 2 : 1 ;
+		  data->duplex = (fep->fec_ioctl_regval &
+						  PHY_STATUS_REG_TWO_DUPLEX_MODE) ? 1 : 0;
+		}
+		else
+		{	// link is down
+		  data->link_speed = data->duplex = SIOC_FEC_RC_NO_LINK;
+		  // no error return - is valid
+		  // retval = -EAGAIN;
+		}
+		if (FEC_DEBUG > 4)
+		{
+		  printk("          **: STAT2 DATA: %s link=%d duplex=%d\n ",
+				 dev->name, data->link_speed, data->duplex);
+		}
+	  }
+	  else
+	  {
+		// returning non STAT2 register value
+		// just return the values
+		// register already set, ret code is OK
+		// we don't modify passed the end of the 4 half words (original 
+		//  interface
+		//data->link_speed = data->duplex = SIOC_FEC_RC_WRONG_REG;
+	  }
+	}	
+		else {
+	  data->link_speed = data->duplex = SIOC_FEC_RC_WRONG_REG;
+	  retval = -ENOSYS;
+	}
+	break;
+
+  case SIOCSMIIREG:               /* Write MII PHY register. */
+  case SIOCDEVPRIVATE+2:          /* for binary compat, remove in 2.5 */
+	// queue the command to be issued - no function follow up
+	mii_queue( dev, mk_mii_write( data->reg, data->value_in), NULL);
+	break;
+
+  case SIOCETHTOOL:
+	// Not implemented yet :-( ...MaTed---
+	//	return fec_ethtool_ioctl( dev, (void *) rq->ifr_data);
+  default:
+	retval = -ENOSYS;
+	break;
+  }
+
+  return retval;
+}
+#endif // CONFIG_FEC_IOCTL
diff -urN linux-2.4.29/drivers/net/fec.h linux-2.4.29-uc1/drivers/net/fec.h
--- linux-2.4.29/drivers/net/fec.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/fec.h	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,178 @@
+/****************************************************************************/
+
+/*
+ *	fec.h  --  Fast Ethernet Controller for Motorola ColdFire
+ *		   5235, 5270, 5271, 5272, 5274, 5275, 5280 and 5282.
+ *
+ *	(C) Copyright 2000-2004, Greg Ungerer (gerg@snapgear.com)
+ *	(C) Copyright 2000-2001, Lineo (www.lineo.com)
+ */
+
+/****************************************************************************/
+#ifndef FEC_H
+#define	FEC_H
+/****************************************************************************/
+
+#if defined(CONFIG_M5235) || defined(CONFIG_M527x) || \
+    defined(CONFIG_M5282) || defined(CONFIG_M5280)
+/*
+ *	Just figures, Motorola would have to change the offsets for
+ *	registers in the same peripheral device on different models
+ *	of the ColdFire!
+ */
+typedef struct fec {
+	unsigned long	fec_reserved0;
+	unsigned long	fec_ievent;		/* Interrupt event reg */
+	unsigned long	fec_imask;		/* Interrupt mask reg */
+	unsigned long	fec_reserved1;
+	unsigned long	fec_r_des_active;	/* Receive descriptor reg */
+	unsigned long	fec_x_des_active;	/* Transmit descriptor reg */
+	unsigned long	fec_reserved2[3];
+	unsigned long	fec_ecntrl;		/* Ethernet control reg */
+	unsigned long	fec_reserved3[6];
+	unsigned long	fec_mii_data;		/* MII manage frame reg */
+	unsigned long	fec_mii_speed;		/* MII speed control reg */
+	unsigned long	fec_reserved4[7];
+	unsigned long	fec_mib_ctrlstat;	/* MIB control/status reg */
+	unsigned long	fec_reserved5[7];
+	unsigned long	fec_r_cntrl;		/* Receive control reg */
+	unsigned long	fec_reserved6[15];
+	unsigned long	fec_x_cntrl;		/* Transmit Control reg */
+	unsigned long	fec_reserved7[7];
+	unsigned long	fec_addr_low;		/* Low 32bits MAC address */
+	unsigned long	fec_addr_high;		/* High 16bits MAC address */
+	unsigned long	fec_opd;		/* Opcode + Pause duration */
+	unsigned long	fec_reserved8[10];
+	unsigned long	fec_hash_table_high;	/* High 32bits hash table */
+	unsigned long	fec_hash_table_low;	/* Low 32bits hash table */
+	unsigned long	fec_grp_hash_table_high;/* High 32bits hash table */
+	unsigned long	fec_grp_hash_table_low;	/* Low 32bits hash table */
+	unsigned long	fec_reserved9[7];
+	unsigned long	fec_x_wmrk;		/* FIFO transmit water mark */
+	unsigned long	fec_reserved10;
+	unsigned long	fec_r_bound;		/* FIFO receive bound reg */
+	unsigned long	fec_r_fstart;		/* FIFO receive start reg */
+	unsigned long	fec_reserved11[11];
+	unsigned long	fec_r_des_start;	/* Receive descriptor ring */
+	unsigned long	fec_x_des_start;	/* Transmit descriptor ring */
+	unsigned long	fec_r_buff_size;	/* Maximum receive buff size */
+} fec_t;
+
+#else
+
+/*
+ *	Define device register set address map.
+ */
+typedef struct fec {
+	unsigned long	fec_ecntrl;		/* Ethernet control reg */
+	unsigned long	fec_ievent;		/* Interrupt event reg */
+	unsigned long	fec_imask;		/* Interrupt mask reg */
+	unsigned long	fec_ivec;		/* Interrupt vec status reg */
+	unsigned long	fec_r_des_active;	/* Receive descriptor reg */
+	unsigned long	fec_x_des_active;	/* Transmit descriptor reg */
+	unsigned long	fec_reserved1[10];
+	unsigned long	fec_mii_data;		/* MII manage frame reg */
+	unsigned long	fec_mii_speed;		/* MII speed control reg */
+	unsigned long	fec_reserved2[17];
+	unsigned long	fec_r_bound;		/* FIFO receive bound reg */
+	unsigned long	fec_r_fstart;		/* FIFO receive start reg */
+	unsigned long	fec_reserved3[4];
+	unsigned long	fec_x_wmrk;		/* FIFO transmit water mark */
+	unsigned long	fec_reserved4;
+	unsigned long	fec_x_fstart;		/* FIFO transmit start reg */
+	unsigned long	fec_reserved5[21];
+	unsigned long	fec_r_cntrl;		/* Receive control reg */
+	unsigned long	fec_max_frm_len;	/* Maximum frame length reg */
+	unsigned long	fec_reserved6[14];
+	unsigned long	fec_x_cntrl;		/* Transmit Control reg */
+	unsigned long	fec_reserved7[158];
+	unsigned long	fec_addr_low;		/* Low 32bits MAC address */
+	unsigned long	fec_addr_high;		/* High 16bits MAC address */
+	unsigned long	fec_hash_table_high;	/* High 32bits hash table */
+	unsigned long	fec_hash_table_low;	/* Low 32bits hash table */
+	unsigned long	fec_r_des_start;	/* Receive descriptor ring */
+	unsigned long	fec_x_des_start;	/* Transmit descriptor ring */
+	unsigned long	fec_r_buff_size;	/* Maximum receive buff size */
+	unsigned long	reserved8[9];
+	unsigned long	fec_fifo_ram[112];	/* FIFO RAM buffer */
+} fec_t;
+
+#endif /* CONFIG_M5272 */
+
+/*
+ *	Define the buffer descriptor structure.
+ */
+typedef struct bufdesc {
+	unsigned short	cbd_sc;			/* Control and status info */
+	unsigned short	cbd_datlen;		/* Data length */
+	unsigned long	cbd_bufaddr;		/* Buffer address */
+} cbd_t;
+
+/*
+ *	Some definitions for the FEC Registers
+ */
+/* ECNTRL */
+#define FEC_ENET_TX_RT		0x02000000	/* Transmit Retime */
+#define FEC_ENET_ETHER_EN	0x00000002	/* Ethernet Enable */
+#define FEC_ENET_RESET		0x00000001	/* Ethernet Controller RESET */
+
+/* X_CNTRL */
+#define FEC_ENET_FDEN	0x00000004		/* Full Duplex Enable */
+#define FEC_ENET_HBC	0x00000002		/* Heartbeat Control */
+#define FEC_ENET_GTS	0x00000001		/* Graceful Transmit Stop */
+
+/*
+ *	The following definitions courtesy of commproc.h, which where
+ *	Copyright (c) 1997 Dan Malek (dmalek@jlc.net).
+ */
+#define BD_SC_EMPTY     ((ushort)0x8000)        /* Receive is empty */
+#define BD_SC_READY     ((ushort)0x8000)        /* Transmit is ready */
+#define BD_SC_WRAP      ((ushort)0x2000)        /* Last buffer descriptor */
+#define BD_SC_INTRPT    ((ushort)0x1000)        /* Interrupt on change */
+#define BD_SC_CM        ((ushort)0x0200)        /* Continous mode */
+#define BD_SC_ID        ((ushort)0x0100)        /* Rec'd too many idles */
+#define BD_SC_P         ((ushort)0x0100)        /* xmt preamble */
+#define BD_SC_BR        ((ushort)0x0020)        /* Break received */
+#define BD_SC_FR        ((ushort)0x0010)        /* Framing error */
+#define BD_SC_PR        ((ushort)0x0008)        /* Parity error */
+#define BD_SC_OV        ((ushort)0x0002)        /* Overrun */
+#define BD_SC_CD        ((ushort)0x0001)        /* ?? */
+
+/*
+ *	Buffer descriptor control/status used by Ethernet receive.
+ */
+#define BD_ENET_RX_EMPTY        ((ushort)0x8000)
+#define BD_ENET_RX_WRAP         ((ushort)0x2000)
+#define BD_ENET_RX_INTR         ((ushort)0x1000)
+#define BD_ENET_RX_LAST         ((ushort)0x0800)
+#define BD_ENET_RX_FIRST        ((ushort)0x0400)
+#define BD_ENET_RX_MISS         ((ushort)0x0100)
+#define BD_ENET_RX_LG           ((ushort)0x0020)
+#define BD_ENET_RX_NO           ((ushort)0x0010)
+#define BD_ENET_RX_SH           ((ushort)0x0008)
+#define BD_ENET_RX_CR           ((ushort)0x0004)
+#define BD_ENET_RX_OV           ((ushort)0x0002)
+#define BD_ENET_RX_CL           ((ushort)0x0001)
+#define BD_ENET_RX_STATS        ((ushort)0x013f)        /* All status bits */
+
+/*
+ *	Buffer descriptor control/status used by Ethernet transmit.
+ */
+#define BD_ENET_TX_READY        ((ushort)0x8000)
+#define BD_ENET_TX_PAD          ((ushort)0x4000)
+#define BD_ENET_TX_WRAP         ((ushort)0x2000)
+#define BD_ENET_TX_INTR         ((ushort)0x1000)
+#define BD_ENET_TX_LAST         ((ushort)0x0800)
+#define BD_ENET_TX_TC           ((ushort)0x0400)
+#define BD_ENET_TX_DEF          ((ushort)0x0200)
+#define BD_ENET_TX_HB           ((ushort)0x0100)
+#define BD_ENET_TX_LC           ((ushort)0x0080)
+#define BD_ENET_TX_RL           ((ushort)0x0040)
+#define BD_ENET_TX_RCMASK       ((ushort)0x003c)
+#define BD_ENET_TX_UN           ((ushort)0x0002)
+#define BD_ENET_TX_CSL          ((ushort)0x0001)
+#define BD_ENET_TX_STATS        ((ushort)0x03ff)        /* All status bits */
+
+
+/****************************************************************************/
+#endif /* FEC_H */
diff -urN linux-2.4.29/drivers/net/imq.c linux-2.4.29-uc1/drivers/net/imq.c
--- linux-2.4.29/drivers/net/imq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/imq.c	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,321 @@
+/*
+ *             Pseudo-driver for the intermediate queue device.
+ *
+ *             This program is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU General Public License
+ *             as published by the Free Software Foundation; either version
+ *             2 of the License, or (at your option) any later version.
+ *
+ * Authors:    Patrick McHardy, <kaber@trash.net>
+ *
+ * 	       The first version was written by Martin Devera, <devik@cdi.cz>
+ *
+ * Credits:    Jan Rafaj <imq2t@cedric.vabo.cz>
+ *              - Update patch to 2.4.21
+ *             Sebastian Strollo <sstrollo@nortelnetworks.com>
+ *              - Fix "Dead-loop on netdevice imq"-issue
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/if_arp.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+#include <linux/netfilter_ipv6.h>
+#endif
+#include <linux/imq.h>
+#include <net/pkt_sched.h>
+
+static nf_hookfn imq_nf_hook;
+
+static struct nf_hook_ops imq_ingress_ipv4 = {
+	{ NULL, NULL},
+	imq_nf_hook,
+	PF_INET,
+	NF_IP_PRE_ROUTING,
+	NF_IP_PRI_MANGLE + 1
+};
+
+static struct nf_hook_ops imq_egress_ipv4 = {
+	{ NULL, NULL},
+	imq_nf_hook,
+	PF_INET,
+	NF_IP_POST_ROUTING,
+	NF_IP_PRI_LAST
+};
+
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+static struct nf_hook_ops imq_ingress_ipv6 = {
+	{ NULL, NULL},
+	imq_nf_hook,
+	PF_INET6,
+	NF_IP6_PRE_ROUTING,
+	NF_IP6_PRI_MANGLE + 1
+};
+
+static struct nf_hook_ops imq_egress_ipv6 = {
+	{ NULL, NULL},
+	imq_nf_hook,
+	PF_INET6,
+	NF_IP6_POST_ROUTING,
+	NF_IP6_PRI_LAST
+};
+#endif
+
+static unsigned int numdevs = 2;
+
+MODULE_PARM(numdevs, "i");
+MODULE_PARM_DESC(numdevs, "number of imq devices");
+
+static struct net_device *imq_devs;
+
+
+static struct net_device_stats *imq_get_stats(struct net_device *dev)
+{
+	return (struct net_device_stats *)dev->priv;
+}
+
+/* called for packets kfree'd in qdiscs at places other than enqueue */
+static void imq_skb_destructor(struct sk_buff *skb)
+{
+	struct nf_info *info = skb->nf_info;
+
+	if (info) {
+		if (info->indev)
+			dev_put(info->indev);
+		if (info->outdev)
+			dev_put(info->outdev);
+		kfree(info);
+	}
+}
+
+static int imq_dev_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct net_device_stats *stats = (struct net_device_stats*) dev->priv;
+	
+	stats->tx_bytes += skb->len;
+	stats->tx_packets++;
+
+	skb->imq_flags = 0;
+	skb->destructor = NULL;
+	
+	dev->trans_start = jiffies;
+	nf_reinject(skb, skb->nf_info, NF_ACCEPT);
+	return 0;
+}
+
+static int imq_nf_queue(struct sk_buff *skb, struct nf_info *info,
+			void *data)
+{
+	struct net_device *dev;
+	struct net_device_stats *stats;
+	struct sk_buff *skb2 = NULL;
+	struct Qdisc *q;
+	unsigned int index = skb->imq_flags&IMQ_F_IFMASK;
+	int ret = -1;
+
+	if (index > numdevs) 
+		return -1;
+	
+	dev = imq_devs + index;
+	if (!(dev->flags & IFF_UP)) {
+		skb->imq_flags = 0;
+		nf_reinject(skb, info, NF_ACCEPT);
+		return 0;
+	}
+	dev->last_rx = jiffies;
+
+	if (skb->destructor) {
+		skb2 = skb;
+		skb = skb_clone(skb, GFP_ATOMIC);
+		if (!skb)
+			return -1;
+	}
+	skb->nf_info = info;
+
+	stats = (struct net_device_stats *)dev->priv;
+	stats->rx_bytes+= skb->len;
+	stats->rx_packets++;
+	
+	spin_lock_bh(&dev->queue_lock);
+	q = dev->qdisc;
+	if (q->enqueue) {
+		q->enqueue(skb_get(skb), q);
+		if (skb_shared(skb)) {
+			skb->destructor = imq_skb_destructor;
+			kfree_skb(skb);
+			ret = 0;
+		}
+	}
+	if (spin_is_locked(&dev->xmit_lock))
+		netif_schedule(dev);
+	else
+		qdisc_run(dev);
+	spin_unlock_bh(&dev->queue_lock);
+
+	if (skb2)
+		kfree_skb(ret ? skb : skb2);
+
+	return ret;
+}
+
+static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff **pskb,
+		   const struct net_device *indev,
+		   const struct net_device *outdev,
+		   int (*okfn)(struct sk_buff *))
+{
+	if ((*pskb)->imq_flags & IMQ_F_ENQUEUE)
+		return NF_QUEUE;
+
+	return NF_ACCEPT;
+}
+
+
+static int __init imq_init_hooks(void)
+{
+	int err;
+
+	if ((err = nf_register_queue_handler(PF_INET, imq_nf_queue, NULL)))
+		goto err1;
+	if ((err = nf_register_hook(&imq_ingress_ipv4)))
+		goto err2;
+	if ((err = nf_register_hook(&imq_egress_ipv4)))
+		goto err3;
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+	if ((err = nf_register_queue_handler(PF_INET6, imq_nf_queue, NULL)))
+		goto err4;
+	if ((err = nf_register_hook(&imq_ingress_ipv6)))
+		goto err5;
+	if ((err = nf_register_hook(&imq_egress_ipv6)))
+		goto err6;
+#endif
+	
+	return 0;
+	
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+err6:
+	nf_unregister_hook(&imq_ingress_ipv6);
+err5:
+	nf_unregister_queue_handler(PF_INET6);
+err4:
+	nf_unregister_hook(&imq_egress_ipv4);
+#endif
+err3:
+	nf_unregister_hook(&imq_ingress_ipv4);
+err2:
+	nf_unregister_queue_handler(PF_INET);
+err1:
+	return err;
+}
+
+static void __exit imq_unhook(void)
+{
+	nf_unregister_hook(&imq_ingress_ipv4);
+	nf_unregister_hook(&imq_egress_ipv4);
+	nf_unregister_queue_handler(PF_INET);
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+	nf_unregister_hook(&imq_ingress_ipv6);
+	nf_unregister_hook(&imq_egress_ipv6);
+	nf_unregister_queue_handler(PF_INET6);
+#endif
+}
+
+static int __init imq_dev_init(struct net_device *dev)
+{
+	dev->hard_start_xmit	= imq_dev_xmit;
+	dev->type		= ARPHRD_VOID;
+	dev->mtu		= 1500;
+	dev->tx_queue_len	= 30;
+	dev->flags		= IFF_NOARP;
+	dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
+	if (dev->priv == NULL)
+		return -ENOMEM;
+	memset(dev->priv, 0, sizeof(struct net_device_stats));
+	dev->get_stats		= imq_get_stats;
+
+	return 0;
+}
+
+static void imq_dev_uninit(struct net_device *dev)
+{
+	kfree(dev->priv);
+}
+
+static int __init imq_init_devs(void)
+{
+	struct net_device *dev;
+	int i;
+
+	if (!numdevs || numdevs > IMQ_MAX_DEVS) {
+		printk(KERN_ERR "numdevs has to be betweed 1 and %u\n",
+		       IMQ_MAX_DEVS);
+		return -EINVAL;
+	}
+
+	imq_devs = kmalloc(sizeof(struct net_device) * numdevs, GFP_KERNEL);
+	if (!imq_devs)
+		return -ENOMEM;
+	memset(imq_devs, 0, sizeof(struct net_device) * numdevs);
+
+	/* we start counting at zero */
+	numdevs--;
+
+	for (i = 0, dev = imq_devs; i <= numdevs; i++, dev++) {
+		SET_MODULE_OWNER(dev);
+		strcpy(dev->name, "imq%d");
+		dev->init   = imq_dev_init;
+		dev->uninit = imq_dev_uninit;
+
+		if (register_netdev(dev) < 0)
+			goto err_register;
+	}
+	return 0;
+
+err_register:
+	for (; i; i--)
+		unregister_netdev(--dev);
+	kfree(imq_devs);
+	return -EIO;
+}
+
+static void imq_cleanup_devs(void)
+{
+	int i;
+	struct net_device *dev = imq_devs;
+	
+	for (i = 0; i <= numdevs; i++)
+		unregister_netdev(dev++);
+
+	kfree(imq_devs);
+}
+
+static int __init imq_init_module(void)
+{
+	int err;
+
+	if ((err = imq_init_devs()))
+		return err;
+	if ((err = imq_init_hooks())) {
+		imq_cleanup_devs();
+		return err;
+	}
+
+	printk(KERN_INFO "imq driver loaded.\n");
+
+	return 0;
+}
+
+static void __exit imq_cleanup_module(void)
+{
+	imq_unhook();
+	imq_cleanup_devs();
+}
+
+module_init(imq_init_module);
+module_exit(imq_cleanup_module);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/drivers/net/intersil/device_config.h linux-2.4.29-uc1/drivers/net/intersil/device_config.h
--- linux-2.4.29/drivers/net/intersil/device_config.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/device_config.h	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,33 @@
+/*  $Header$
+ *
+ *  Copyright (C) 2001 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+ /* device_config.h */
+
+#define MAX_ASSOCIATIONS	128
+#define MAX_MAC_ALLOWED		1024
+#define MAX_WDS_LINKS		8
+
+/* Mib-2 tree Info */
+/* These are the system information variables. */
+
+/* default system contact */
+#define SYS_CONTACT "Unknown"
+
+/* system location */
+#define SYS_LOC "Unknown"
diff -urN linux-2.4.29/drivers/net/intersil/isl_38xx.c linux-2.4.29-uc1/drivers/net/intersil/isl_38xx.c
--- linux-2.4.29/drivers/net/intersil/isl_38xx.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/isl_38xx.c	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,341 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#define __KERNEL_SYSCALLS__
+
+#include <linux/version.h>
+#ifdef MODULE
+#ifdef MODVERSIONS
+#include <linux/modversions.h>
+#endif
+#include <linux/module.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
+#include <linux/types.h>
+#include <linux/unistd.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#include "isl_gen.h"
+#include "isl_38xx.h"
+#include "islpci_dev.h"
+#include "islpci_mgt.h"
+
+
+/******************************************************************************
+        Global variable definition section
+******************************************************************************/
+extern int pc_debug;
+
+int errno;
+
+/******************************************************************************
+    Device Interface & Control functions
+******************************************************************************/
+void isl38xx_enable_update_interrupt(void *device)
+{
+    u32 reg;
+
+    // set the update queue status bit in the Interrupt Enable Register
+    reg = readl(device + ISL38XX_INT_EN_REG);
+    reg |= ISL38XX_INT_IDENT_UPDATE;
+    writel(reg, device + ISL38XX_INT_EN_REG);
+}
+
+void isl38xx_disable_update_interrupt(void *device)
+{
+    u32 reg;
+
+    // clear the update queue status bit in the Interrupt Enable Register
+    reg = readl(device + ISL38XX_INT_EN_REG);
+    reg &= ~ISL38XX_INT_IDENT_UPDATE;
+    writel(reg, device + ISL38XX_INT_EN_REG);
+}
+
+void isl38xx_handle_sleep_request( isl38xx_control_block *control_block,
+    int *powerstate, void *device_base )
+{
+    // device requests to go into sleep mode
+    // check whether the transmit queues for data and management are empty
+    if( isl38xx_in_queue( control_block, ISL38XX_CB_TX_DATA_LQ))
+        // data tx queue not empty
+        return;
+
+    if( isl38xx_in_queue( control_block, ISL38XX_CB_TX_MGMTQ))
+        // management tx queue not empty
+        return;
+ 
+    // check also whether received frames are pending
+    if( isl38xx_in_queue( control_block, ISL38XX_CB_RX_DATA_LQ))
+        // data rx queue not empty
+        return;
+
+    if( isl38xx_in_queue( control_block, ISL38XX_CB_RX_MGMTQ))
+        // management rx queue not empty
+        return;
+
+//#if VERBOSE > SHOW_ERROR_MESSAGES 
+        DEBUG(SHOW_ANYTHING, "Device going to sleep mode\n" );
+//#endif
+     
+    // all queues are empty, allow the device to go into sleep mode
+    *powerstate = ISL38XX_PSM_POWERSAVE_STATE;
+
+    // assert the Sleep interrupt in the Device Interrupt Register
+    writel( ISL38XX_DEV_INT_SLEEP, device_base + ISL38XX_DEV_INT_REG);
+    udelay( ISL38XX_WRITEIO_DELAY );
+}
+
+void isl38xx_handle_wakeup( isl38xx_control_block *control_block,
+    int *powerstate, void *device_base)
+{
+    // device is in active state, update the powerstate flag
+    *powerstate = ISL38XX_PSM_ACTIVE_STATE;
+
+    // now check whether there are frames pending for the card
+    if( !isl38xx_in_queue( control_block, ISL38XX_CB_TX_DATA_LQ))
+        // data tx queue empty, no pending frames
+        if( !isl38xx_in_queue( control_block, ISL38XX_CB_TX_MGMTQ))
+            // management tx queue empty, no pending frames
+            return;
+
+//#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_ANYTHING, "Wake up handler trigger the device\n" );
+//#endif
+        
+    // either data or management transmit queue has a frame pending
+    // trigger the device by setting the Update bit in the Device Int reg
+    writel( ISL38XX_DEV_INT_UPDATE, device_base + ISL38XX_DEV_INT_REG);
+    udelay( ISL38XX_WRITEIO_DELAY );
+}
+
+void isl38xx_trigger_device( int *powerstate, void *device_base )
+{
+    struct timeval current_time;
+    u32 reg, counter = 0;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+        DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n" );
+#endif
+
+     // check whether the device is in power save mode
+    if( *powerstate == ISL38XX_PSM_POWERSAVE_STATE )
+    {
+        // device is in powersave, trigger the device for wakeup
+//#if VERBOSE > SHOW_ERROR_MESSAGES 
+        do_gettimeofday( &current_time );
+        DEBUG(SHOW_ANYTHING, "%08li.%08li Device wakeup triggered\n", 
+            current_time.tv_sec, current_time.tv_usec );
+//#endif
+
+        DEBUG(SHOW_ANYTHING, "%08li.%08li Device register read %08x\n", 
+            current_time.tv_sec, current_time.tv_usec,
+            readl( device_base + ISL38XX_CTRL_STAT_REG) );
+        udelay(ISL38XX_WRITEIO_DELAY);
+
+        if( reg = readl( device_base + ISL38XX_INT_IDENT_REG),
+            reg == 0xabadface )
+        {
+//#if VERBOSE > SHOW_ERROR_MESSAGES 
+            do_gettimeofday( &current_time );
+            DEBUG(SHOW_ANYTHING, "%08li.%08li Device register abadface\n", 
+                current_time.tv_sec, current_time.tv_usec );
+//#endif
+            // read the Device Status Register until Sleepmode bit is set
+            while( reg = readl( device_base + ISL38XX_CTRL_STAT_REG),
+                (reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0 )
+            {
+                udelay(ISL38XX_WRITEIO_DELAY);
+                counter++;   
+            }
+
+            DEBUG(SHOW_ANYTHING, "%08li.%08li Device register read %08x\n", 
+                current_time.tv_sec, current_time.tv_usec,
+                readl( device_base + ISL38XX_CTRL_STAT_REG) );
+            udelay(ISL38XX_WRITEIO_DELAY);
+
+//#if VERBOSE > SHOW_ERROR_MESSAGES 
+        do_gettimeofday( &current_time );
+        DEBUG(SHOW_ANYTHING, "%08li.%08li Device asleep counter %i\n", 
+            current_time.tv_sec, current_time.tv_usec, counter );
+//#endif
+        }
+    
+        // assert the Wakeup interrupt in the Device Interrupt Register
+        writel( ISL38XX_DEV_INT_WAKEUP, device_base + ISL38XX_DEV_INT_REG);
+        udelay(ISL38XX_WRITEIO_DELAY);
+
+        // perform another read on the Device Status Register
+        reg = readl( device_base + ISL38XX_CTRL_STAT_REG);
+        udelay(ISL38XX_WRITEIO_DELAY);
+
+//#if VERBOSE > SHOW_ERROR_MESSAGES 
+        do_gettimeofday( &current_time );
+        DEBUG(SHOW_ANYTHING, "%08li.%08li Device register read %08x\n", 
+            current_time.tv_sec, current_time.tv_usec, reg );
+//#endif
+    }
+    else
+    {
+        // device is (still) awake 
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+        DEBUG(SHOW_TRACING, "Device is in active state\n" );
+#endif
+        // trigger the device by setting the Update bit in the Device Int reg
+        writel(ISL38XX_DEV_INT_UPDATE, device_base + ISL38XX_DEV_INT_REG);
+        udelay(ISL38XX_WRITEIO_DELAY);
+    }
+}
+
+void isl38xx_interface_reset( void *device_base, dma_addr_t host_address )
+{
+    u32 reg;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_FUNCTION_CALLS, "isl38xx_interface_reset \n");
+#endif
+
+    // load the address of the control block in the device
+    writel( host_address, device_base + ISL38XX_CTRL_BLK_BASE_REG);
+    udelay(ISL38XX_WRITEIO_DELAY);
+
+#ifdef CONFIG_ARCH_ISL3893
+    /* enable the mini PCI target for the 3893 */
+    writel( 0x3893, device_base + ISL38XX_GEN_PURP_COM_REG_2);
+    udelay(ISL38XX_WRITEIO_DELAY);
+
+#endif
+    
+    // set the reset bit in the Device Interrupt Register
+    writel(ISL38XX_DEV_INT_RESET, device_base + ISL38XX_DEV_INT_REG);
+    udelay(ISL38XX_WRITEIO_DELAY);
+
+    // enable the interrupt for detecting initialization
+    reg = ISL38XX_INT_IDENT_INIT | ISL38XX_INT_IDENT_UPDATE |
+        ISL38XX_INT_IDENT_SLEEP | ISL38XX_INT_IDENT_WAKEUP;
+//    reg = ISL38XX_INT_IDENT_INIT;
+    writel(reg, device_base + ISL38XX_INT_EN_REG);
+    udelay(ISL38XX_WRITEIO_DELAY);
+}
+
+int isl38xx_upload_firmware( char *filename, void *device_base, 
+    dma_addr_t host_address )
+{
+    u32 reg;
+    int ifp;
+    long bcount, length;
+    mm_segment_t fs;
+    static char buffer[ISL38XX_MEMORY_WINDOW_SIZE];
+
+    // clear the RAMBoot and the Reset bit
+    reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
+    reg &= ~ISL38XX_CTRL_STAT_RESET;
+    reg &= ~ISL38XX_CTRL_STAT_RAMBOOT;
+    writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
+    udelay(ISL38XX_WRITEIO_DELAY);
+
+    // set the Reset bit without reading the register !
+    reg |= ISL38XX_CTRL_STAT_RESET;
+    writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
+    udelay(ISL38XX_WRITEIO_DELAY);
+
+    // clear the Reset bit
+    reg &= ~ISL38XX_CTRL_STAT_RESET;
+    writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
+
+    // wait a while for the device to reboot
+    mdelay(50);
+
+    // prepare the Direct Memory Base register
+    reg = ISL38XX_DEV_FIRMWARE_ADDRES;
+
+    // for file opening temporarily tell the kernel I am not a user for
+    // memory management segment access
+    
+    fs = get_fs();
+    set_fs(KERNEL_DS);
+
+    // open the file with the firmware for uploading
+    if (ifp = open( filename, O_RDONLY, 0 ), ifp < 0)
+    {
+        // error opening the file
+        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: Could not open file (%s)\n", filename );
+        set_fs(fs);
+        return -1;
+    }
+    // enter a loop which reads data blocks from the file and writes them
+    // to the Direct Memory Windows
+    do
+    {
+        // set the cards base address for writting the data
+        writel(reg, device_base + ISL38XX_DIR_MEM_BASE_REG);
+        length = 0;
+
+        // read a block of data until buffer is full or end of file
+        do
+        {
+            bcount = read(ifp, &buffer[length], sizeof(buffer) - length);
+            length += bcount;
+        }
+        while ((length != ISL38XX_MEMORY_WINDOW_SIZE) && (bcount != 0));
+
+        // write the data to the Direct Memory Window
+        memcpy_toio(device_base + ISL38XX_DIRECT_MEM_WIN, buffer, length);
+
+        // increment the write address
+        reg += ISL38XX_MEMORY_WINDOW_SIZE;
+    }
+    while (bcount != 0);
+
+    // close the file
+    close(ifp);
+
+    // switch back the segment setting
+    set_fs(fs);
+
+    // now reset the device
+    // clear the Reset & ClkRun bit, set the RAMBoot bit
+    reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
+	reg &= ~ISL38XX_CTRL_STAT_CLKRUN;
+    reg &= ~ISL38XX_CTRL_STAT_RESET;
+    reg |= ISL38XX_CTRL_STAT_RAMBOOT;
+    writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
+    udelay(ISL38XX_WRITEIO_DELAY);
+
+    // set the reset bit latches the host override and RAMBoot bits
+    // into the device for operation when the reset bit is reset
+    reg |= ISL38XX_CTRL_STAT_RESET;
+    writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
+    udelay(ISL38XX_WRITEIO_DELAY);
+
+    // clear the reset bit should start the whole circus
+    reg &= ~ISL38XX_CTRL_STAT_RESET;
+    writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
+    udelay(ISL38XX_WRITEIO_DELAY);
+
+    // now the last step is to reset the interface
+    isl38xx_interface_reset( device_base, host_address );
+
+    return 0;
+}
+
diff -urN linux-2.4.29/drivers/net/intersil/isl_38xx.h linux-2.4.29-uc1/drivers/net/intersil/isl_38xx.h
--- linux-2.4.29/drivers/net/intersil/isl_38xx.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/isl_38xx.h	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,172 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef _ISL_38XX_H
+#define _ISL_38XX_H
+
+#define ISL38XX_CB_RX_QSIZE                     8
+#define ISL38XX_CB_TX_QSIZE                     32
+
+// ISL38XX Access Point Specific definitions
+#define ISL38XX_MAX_WDS_LINKS                   8
+
+// ISL38xx Client Specific definitions
+#define ISL38XX_PSM_ACTIVE_STATE                0
+#define ISL38XX_PSM_POWERSAVE_STATE             1
+
+// ISL38XX Host Interface Definitions
+#define ISL38XX_PCI_MEM_SIZE                    0x02000
+#define ISL38XX_MEMORY_WINDOW_SIZE              0x01000
+#define ISL38XX_DEV_FIRMWARE_ADDRES             0x20000
+#define ISL38XX_WRITEIO_DELAY                   1               // in us
+#define ISL38XX_RESET_DELAY                     50              // in ms
+#define ISL38XX_WAIT_CYCLE                      10              // in 10ms
+#define ISL38XX_MAX_WAIT_CYCLES                 10
+
+// PCI Memory Area
+#define ISL38XX_HARDWARE_REG                    0x0000
+#define ISL38XX_CARDBUS_CIS                     0x0800
+#define ISL38XX_DIRECT_MEM_WIN                  0x1000
+
+// Hardware registers
+#define ISL38XX_DEV_INT_REG                     0x0000
+#define ISL38XX_INT_IDENT_REG                   0x0010
+#define ISL38XX_INT_ACK_REG                     0x0014
+#define ISL38XX_INT_EN_REG                      0x0018
+#define ISL38XX_GEN_PURP_COM_REG_1              0x0020
+#define ISL38XX_GEN_PURP_COM_REG_2              0x0024
+#define ISL38XX_CTRL_BLK_BASE_REG               ISL38XX_GEN_PURP_COM_REG_1
+#define ISL38XX_DIR_MEM_BASE_REG                0x0030
+#define ISL38XX_CTRL_STAT_REG                   0x0078
+
+// Device Interrupt register bits
+#define ISL38XX_DEV_INT_RESET                   0x0001
+#define ISL38XX_DEV_INT_UPDATE                  0x0002
+#define ISL38XX_DEV_INT_WAKEUP                  0x0008
+#define ISL38XX_DEV_INT_SLEEP                   0x0010
+#define ISL38XX_DEV_INT_ABORT                   0x0020
+
+// Interrupt Identification/Acknowledge/Enable register bits
+#define ISL38XX_INT_IDENT_UPDATE                0x0002
+#define ISL38XX_INT_IDENT_INIT                  0x0004
+#define ISL38XX_INT_IDENT_WAKEUP                0x0008
+#define ISL38XX_INT_IDENT_SLEEP                 0x0010
+#define ISL38XX_INT_SOURCES                     0x001E
+
+// Control/Status register bits
+#define ISL38XX_CTRL_STAT_SLEEPMODE             0x00000200
+#define	ISL38XX_CTRL_STAT_CLKRUN				0x00800000
+#define ISL38XX_CTRL_STAT_RESET                 0x10000000
+#define ISL38XX_CTRL_STAT_RAMBOOT               0x20000000
+#define ISL38XX_CTRL_STAT_STARTHALTED           0x40000000
+#define ISL38XX_CTRL_STAT_HOST_OVERRIDE         0x80000000
+
+// Control Block definitions
+#define ISL38XX_CB_RX_DATA_LQ                   0
+#define ISL38XX_CB_TX_DATA_LQ                   1
+#define ISL38XX_CB_RX_DATA_HQ                   2
+#define ISL38XX_CB_TX_DATA_HQ                   3
+#define ISL38XX_CB_RX_MGMTQ                     4
+#define ISL38XX_CB_TX_MGMTQ                     5
+#define ISL38XX_CB_QCOUNT                       6
+#define ISL38XX_CB_MGMT_QSIZE                   4
+#define ISL38XX_MIN_QTHRESHOLD                  4       // fragments
+
+// Memory Manager definitions
+#define MGMT_FRAME_SIZE                         1024    // >= size struct obj_bsslist
+#define MGMT_TX_FRAME_COUNT                     24      // max 4 + spare 4 + 8 init
+#define MGMT_RX_FRAME_COUNT                     24      // 4*4 + spare 8
+#define MGMT_FRAME_COUNT                        (MGMT_TX_FRAME_COUNT + MGMT_RX_FRAME_COUNT)
+#define MGMT_QBLOCK                             MGMT_FRAME_COUNT * MGMT_FRAME_SIZE
+#define CONTROL_BLOCK_SIZE                      1024    // should be enough
+#define PSM_FRAME_SIZE                          1536
+#define PSM_MINIMAL_STATION_COUNT               64
+#define PSM_FRAME_COUNT                         PSM_MINIMAL_STATION_COUNT
+#define PSM_BUFFER_SIZE                         PSM_FRAME_SIZE * PSM_FRAME_COUNT
+#define MAX_TRAP_RX_QUEUE                       4
+#define HOST_MEM_BLOCK                          MGMT_QBLOCK + CONTROL_BLOCK_SIZE + PSM_BUFFER_SIZE
+
+#define ALLOC_MODE_SINGLE                       0       // allocate all in a single block
+#define ALLOC_MODE_PAGED                        1       // allocate memory in fixed pages
+#define ALLOC_PAGE1_SIZE                        1024 * 128
+#define ALLOC_PAGEX_SIZE                        1024 * 16
+#define ALLOC_MAX_PAGES                         4
+#define ALLOC_MEMORY_MODE                       ALLOC_MODE_SINGLE
+
+// Fragment package definitions
+#define FRAGMENT_FLAG_MF                        0x0001
+#define MAX_FRAGMENT_SIZE                       1536
+
+typedef struct
+{
+    u32 address;                        // physical address on host
+    u16 size;                           // packet size
+    u16 flags;                          // set of bit-wise flags
+} isl38xx_fragment;
+
+struct isl38xx_cb
+{
+    u32 driver_curr_frag[ISL38XX_CB_QCOUNT];
+    u32 device_curr_frag[ISL38XX_CB_QCOUNT];
+    isl38xx_fragment rx_data_low[ISL38XX_CB_RX_QSIZE];
+    isl38xx_fragment tx_data_low[ISL38XX_CB_TX_QSIZE];
+    isl38xx_fragment rx_data_high[ISL38XX_CB_RX_QSIZE];
+    isl38xx_fragment tx_data_high[ISL38XX_CB_TX_QSIZE];
+    isl38xx_fragment rx_data_mgmt[ISL38XX_CB_MGMT_QSIZE];
+    isl38xx_fragment tx_data_mgmt[ISL38XX_CB_MGMT_QSIZE];
+};
+
+typedef struct isl38xx_cb isl38xx_control_block;
+
+static inline u32 isl38xx_in_queue(isl38xx_control_block * control_block,
+                             int queue)
+{
+    // determine the amount of fragments in the queue depending on the type
+    // of the queue, either transmit or receive
+    if ((queue == ISL38XX_CB_TX_DATA_LQ) || (queue == ISL38XX_CB_TX_DATA_HQ)
+        || (queue == ISL38XX_CB_TX_MGMTQ))
+    {
+        return (u32)((u32) le32_to_cpu(control_block->driver_curr_frag[queue])-
+                (u32) le32_to_cpu(control_block->device_curr_frag[queue]));
+    }
+    else if (queue == ISL38XX_CB_RX_MGMTQ)
+    {
+        return (u32) (ISL38XX_CB_MGMT_QSIZE -
+            ((u32) le32_to_cpu(control_block->driver_curr_frag[queue]) -
+            (u32) le32_to_cpu(control_block->device_curr_frag[queue])));
+    }
+    else
+    {
+        return (u32) (ISL38XX_CB_RX_QSIZE -
+            ((u32) le32_to_cpu(control_block->driver_curr_frag[queue]) -
+            (u32) le32_to_cpu(control_block->device_curr_frag[queue])));
+    }
+}
+
+
+void isl38xx_enable_update_interrupt( void * );
+void isl38xx_disable_update_interrupt( void * );
+void isl38xx_handle_sleep_request( isl38xx_control_block *, int *, void * );
+void isl38xx_handle_wakeup( isl38xx_control_block *, int *, void * );
+void isl38xx_trigger_device( int *, void * );
+void isl38xx_interface_reset( void *, dma_addr_t );
+int isl38xx_upload_firmware( char *, void *, dma_addr_t );
+
+
+#endif  // _ISL_38XX_H
diff -urN linux-2.4.29/drivers/net/intersil/isl_gen.c linux-2.4.29-uc1/drivers/net/intersil/isl_gen.c
--- linux-2.4.29/drivers/net/intersil/isl_gen.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/isl_gen.c	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,130 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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 <linux/version.h>
+#ifdef MODULE
+#ifdef MODVERSIONS
+#include <linux/modversions.h>
+#endif
+#include <linux/module.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
+#include <linux/skbuff.h>
+#include "isl_gen.h"
+
+
+
+/******************************************************************************
+    Global variable definition section
+******************************************************************************/
+extern int pc_debug;
+
+
+/******************************************************************************
+    Driver general functions
+******************************************************************************/
+void display_buffer(char *buffer, int length)
+{
+    if( ( pc_debug & SHOW_BUFFER_CONTENTS ) == 0 )
+        return;
+
+    while (length > 0)
+    {
+        printk( "[%02x]", *buffer & 255 );
+        length--;
+        buffer++;
+    }
+
+    printk( "\n" );
+}
+
+void print_frame(struct sk_buff *skb)
+{
+    int offset;
+
+    printk("pr_frame: size %d, skb->data %p, skb %p\n",
+        skb->len, skb->data, skb);
+    for (offset = 0; offset < skb->len; offset++)
+        printk("%02X ", skb->data[offset]);
+    printk("\n");
+}
+
+
+void string_to_macaddress( unsigned char *string, unsigned char *mac )
+{
+    unsigned char *wp = mac, *rp;
+    unsigned int value;
+    unsigned int count = 0;
+
+    for( rp = string; *rp != '\0'; rp++, wp++, count++ )
+    {
+        if( count == 6 )
+            break;
+
+        if( *rp >= '0' && *rp <= '9' )
+            value = *rp - '0';
+        else if( *rp >= 'a' && *rp <= 'f' )
+            value = *rp - 'a' + 10;
+        else if( *rp >= 'A' && *rp <= 'F' )
+            value = *rp - 'A' + 10;
+        else
+            break;
+
+        value <<= 4;
+            rp++;
+        if( *rp >= '0' && *rp <= '9' )
+            value |= *rp - '0';
+        else if( *rp >= 'a' && *rp <= 'f')
+            value |= *rp - 'a' + 10;
+        else if( *rp >= 'A' && *rp <= 'F')
+            value |= *rp - 'A' + 10;
+        else
+            break;
+
+        *wp = (unsigned char) value;
+    }
+}
+
+int address_compare( unsigned char *address1, unsigned char *address2 )
+{
+    u32 *address1_hi, *address2_hi;
+    u16 *address1_lo, *address2_lo;
+
+    address2_hi = (u32 *) address2;
+    address1_hi = (u32 *) address1;
+    address2_lo = (u16 *) (address2 + 4);
+    address1_lo = (u16 *) (address1 + 4);
+
+    DEBUG(SHOW_TRACING, "address_compare: a1 %08x:%04x a2 %08x:%04x\n",
+        *address1_hi, *address1_lo, *address2_hi, *address2_lo );
+
+    return ((*address2_hi == *address1_hi) && (*address2_lo == *address1_lo));
+}
+
+
+
+
+
+
+
+
+
diff -urN linux-2.4.29/drivers/net/intersil/isl_gen.h linux-2.4.29-uc1/drivers/net/intersil/isl_gen.h
--- linux-2.4.29/drivers/net/intersil/isl_gen.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/isl_gen.h	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,83 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef _ISL_GEN_H
+#define _ISL_GEN_H
+
+#include <linux/skbuff.h>
+
+
+// General driver definitions
+#define PCIVENDOR_INTERSIL                      0x1260UL
+#define PCIDEVICE_ISL3877                       0x3877UL
+#define PCIDEVICE_ISL3890                       0x3890UL
+#define PCIDEVICE_LATENCY_TIMER_MIN 			0x40
+#define PCIDEVICE_LATENCY_TIMER_VAL 			0x50
+
+// Debugging verbose definitions
+#define SHOW_NOTHING                            0x00    // overrules everything
+#define SHOW_ANYTHING                           0xFF
+#define SHOW_ERROR_MESSAGES                     0x01
+#define SHOW_TRAPS                              0x02
+#define SHOW_FUNCTION_CALLS                     0x04
+#define SHOW_TRACING                            0x08
+#define SHOW_QUEUE_INDEXES                      0x10
+#define SHOW_PIMFOR_FRAMES                      0x20
+#define SHOW_BUFFER_CONTENTS                    0x40
+#define VERBOSE                                 0x01
+
+
+
+/*
+ *  Function definitions
+ */
+
+//#if TARGET_SYSTEM == RAWPCI
+//#define K_DEBUG( f, m, args... ) if(( f & m ) != 0 ) printk( KERN_DEBUG args )
+//#else
+#define K_DEBUG( f, m, args... ) if(( f & m ) != 0 ) printk( KERN_INFO args )
+//#endif
+#define DEBUG( f, args... )     K_DEBUG( f, pc_debug, args )
+
+static inline void add_le32p(u32 *le_number, u32 add)
+{
+    *le_number = cpu_to_le32(le32_to_cpup(le_number) + add);
+}
+
+static inline void driver_lock( spinlock_t *lock, unsigned long *pflags )
+{
+  /* Disable interrupts and aquire the lock */
+  spin_lock_irqsave( lock, *pflags );
+}
+
+static inline void driver_unlock( spinlock_t *lock, unsigned long *pflags )
+{
+  /* Release the lock and reenable interrupts */
+  spin_unlock_irqrestore( lock, *pflags );
+}
+
+
+void display_buffer( char *, int );
+void schedule_wait( int );
+void print_frame( struct sk_buff * );
+void string_to_macaddress( unsigned char *, unsigned char * );
+int address_compare( unsigned char *, unsigned char * );
+
+
+#endif  // _ISL_GEN_H
diff -urN linux-2.4.29/drivers/net/intersil/isl.h linux-2.4.29-uc1/drivers/net/intersil/isl.h
--- linux-2.4.29/drivers/net/intersil/isl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/isl.h	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,31 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef _ISL_H
+#define _ISL_H
+
+/* INCLUDES */
+
+/* DEFINES */
+
+/* Structure definitions */
+
+/* Function prototypes. */
+
+#endif /* _ISL_H */
diff -urN linux-2.4.29/drivers/net/intersil/isl_ioctl.c linux-2.4.29-uc1/drivers/net/intersil/isl_ioctl.c
--- linux-2.4.29/drivers/net/intersil/isl_ioctl.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/isl_ioctl.c	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,2494 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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 <linux/version.h>
+#ifdef MODULE
+#ifdef MODVERSIONS
+#include <linux/modversions.h>
+#endif
+#include <linux/module.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
+#include <linux/kernel.h>
+#include <linux/if_arp.h>
+
+#include <asm/uaccess.h>
+
+#include <isl_ioctl.h>
+#include <isl_gen.h>
+#include <islpci_mgt.h>
+#include <bloboid.h>      // additional types and defs for isl38xx fw
+
+
+#ifdef WIRELESS_IOCTLS
+
+#undef IW_MAX_BITRATES
+#define	IW_MAX_BITRATES	16
+
+/******************************************************************************
+        Global variable definition section
+******************************************************************************/
+extern int pc_debug;
+
+int last_key_id = 0;
+struct iw_priv_args privtab[] =
+{
+        { SIOCIWFIRSTPRIV + 0x00, IW_PRIV_TYPE_INT | 1, 0,
+                "setauthenten" },
+        { SIOCIWFIRSTPRIV + 0x01, 0, IW_PRIV_TYPE_INT | 1,
+                "getauthenten" },
+        { SIOCIWFIRSTPRIV + 0x02, IW_PRIV_TYPE_INT | 1, 0,
+                "setunencrypt" },
+        { SIOCIWFIRSTPRIV + 0x03, 0, IW_PRIV_TYPE_INT | 1,
+                "getunencrypt" },
+        { SIOCIWFIRSTPRIV + 0x04, IW_PRIV_TYPE_INT | 1, 0,
+                "setprivinvok" },
+        { SIOCIWFIRSTPRIV + 0x05, 0, IW_PRIV_TYPE_INT | 1,
+                "getprivinvok" },
+        { SIOCIWFIRSTPRIV + 0x06, IW_PRIV_TYPE_INT | 1, 0,
+                "setdefkeyid" },
+        { SIOCIWFIRSTPRIV + 0x07, 0, IW_PRIV_TYPE_INT | 1,
+                "getdefkeyid" },
+        { SIOCIWFIRSTPRIV + 0x08, IW_PRIV_TYPE_CHAR | 16, 0,
+                "setdefkeyx" },
+        { SIOCIWFIRSTPRIV + 0x09, IW_PRIV_TYPE_INT | 1, IW_PRIV_TYPE_CHAR | 16,
+                "getdefkeyx" },
+        { SIOCIWFIRSTPRIV + 0x0A, 0, IW_PRIV_TYPE_INT | 4,
+                "getprivstat" },
+        { SIOCIWFIRSTPRIV + 0x0B, 0, IW_PRIV_TYPE_BYTE | IW_MAX_BITRATES,
+                "getsuprates" },
+        { SIOCIWFIRSTPRIV + 0x0C, IW_PRIV_TYPE_INT | 1, 0,
+                "setdtimper" },
+        { SIOCIWFIRSTPRIV + 0x0D, 0, IW_PRIV_TYPE_INT | 1,
+                "getdtimper" },
+        { SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_INT | 1, 0,
+                "setbeaconper" },
+        { SIOCIWFIRSTPRIV + 0x0F, 0, IW_PRIV_TYPE_INT | 1,
+                "getbeaconper" },
+        { SIOCIWFIRSTPRIV + 0x10, IW_PRIV_TYPE_CHAR | 12, 0,
+                "wdslinkadd" },
+        { SIOCIWFIRSTPRIV + 0x11, IW_PRIV_TYPE_CHAR | 12, 0,
+                "wdslinkdel" },
+        { SIOCIWFIRSTPRIV + 0x12, IW_PRIV_TYPE_CHAR | 12, 0,
+                "eapauthen" },
+        { SIOCIWFIRSTPRIV + 0x13, IW_PRIV_TYPE_CHAR | 12, 0,
+                "eapunauth" },
+        { SIOCIWFIRSTPRIV + 0x14, IW_PRIV_TYPE_INT | 1, 0,
+                "setdot1xen" },
+        { SIOCIWFIRSTPRIV + 0x15, 0, IW_PRIV_TYPE_INT | 1,
+                "getdot1xen" },
+        { SIOCIWFIRSTPRIV + 0x16, IW_PRIV_TYPE_CHAR | 32, 0,
+                "setstakeyx" }, // <address>:<key_nr>:<key>
+        { SIOCIWFIRSTPRIV + 0x17, IW_PRIV_TYPE_CHAR | 32, IW_PRIV_TYPE_CHAR | 32,
+                "getstakeyx" }, // <address>:<key_nr> -> <key>
+        { SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_INT | 1, 0,
+                "setfixedrate" },
+        { SIOCIWFIRSTPRIV + 0x19, 0, IW_PRIV_TYPE_INT | 1,
+                "getfixedrate" },
+/*
+        { SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_INT | 1, 0,
+                "setfragthresh" },
+        { SIOCIWFIRSTPRIV + 0x19, 0, IW_PRIV_TYPE_INT | 1,
+                "getfragthresh" },
+*/
+        { SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_INT | 1, 0,
+                "setpsm" },
+        { SIOCIWFIRSTPRIV + 0x1B, 0, IW_PRIV_TYPE_INT | 1,
+                "getpsm" },
+        { SIOCIWFIRSTPRIV + 0x1C, IW_PRIV_TYPE_INT | 1, 0,
+                "setnonerp" },
+        { SIOCIWFIRSTPRIV + 0x1D, 0, IW_PRIV_TYPE_INT | 1,
+                "getnonerp" },
+        { SIOCIWFIRSTPRIV + 0x1E, 0, IW_PRIV_TYPE_BYTE | 4, 
+                "getcountrystr" },
+        { SIOCIWFIRSTPRIV + 0x1F, 0, IW_PRIV_TYPE_BYTE | 16,
+                "checktraps" }
+};
+
+/******************************************************************************
+    Driver Management IOCTL functions
+******************************************************************************/
+int isl_ioctl_getrange(struct net_device *nwdev, struct iw_range *range )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    struct iw_range range_obj;
+    char *data;
+    unsigned long dlen;
+    int rvalue, counter, operation;
+
+    // request the device for the rates
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+       DOT11_OID_RATES, 0, NULL, IW_MAX_BITRATES+1, 0);
+
+    // enter sleep mode after supplying oid and local buffers for reception
+    // to the management queue receive mechanism
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_RATES, 
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // error in getting the response, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "getrates: bufaddr %p \n", range );
+#endif
+
+    // set the wireless extension version number
+    range_obj.we_version_source = SUPPORTED_WIRELESS_EXT;
+    range_obj.we_version_compiled = WIRELESS_EXT;
+
+    for( counter=0; counter < IW_MAX_BITRATES; counter++, data++ )
+    {
+        // check whether the rate value is set
+        if( *data )
+        {
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG( SHOW_TRACING, "rate: basic %i value %x \n",
+                (*data & 0x80) >> 7, *data & 0x7F );
+#endif
+
+            // convert the bitrates to Mbps
+            range_obj.bitrate[counter] = (double)(*data & 0x7F);
+            range_obj.bitrate[counter] *= 1000000;
+
+            // increment the number of rates counter
+            range_obj.num_bitrates++;
+        }
+    }
+
+    // return the data if the destination buffer is defined
+    if (copy_to_user( (void *) range, (void *) &range_obj,
+        sizeof(struct iw_range)))
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EFAULT;
+    }
+    
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setrange(struct net_device *nwdev, struct iw_range *range )
+{
+    return 0;
+}
+
+#if WIRELESS_EXT > 11
+
+int isl_ioctl_getstats(struct net_device *nwdev, struct iw_statistics *stats )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    struct iw_statistics stats_obj = { 0 };
+    long *data;
+    unsigned long dlen;
+    int rvalue, operation;
+
+    // request the device for the rates
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+       DOT11_OID_MPDUTXFAILED, 0, NULL, 4, 0);
+
+    // enter sleep mode after supplying oid and local buffers for reception
+    // to the management queue receive mechanism
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_MPDUTXFAILED,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // error in getting the response, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "MPDU Tx Failed: %lu \n", *data );
+        stats_obj.discard.retries = *data;
+#endif
+
+    // return the data if the destination buffer is defined
+    if (copy_to_user( (void *) stats, (void *) &stats_obj,
+        sizeof(struct iw_statistics)))
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EFAULT;
+    }
+    
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+
+int isl_ioctl_setstats(struct net_device *nwdev, struct iw_statistics *stats )
+{
+    return 0;
+}
+
+#endif
+
+int isl_ioctl_getauthenten(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *flag = (long *) wrq->u.data.pointer;
+    int rvalue, operation;
+    char *data;
+    unsigned long dlen;
+
+    // send a get object to get the filter setting
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_AUTHENABLE, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_AUTHENABLE,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+    *flag = (long) *data;
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Get Authenticate enable: %i\n", (int) *flag );
+#endif
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setauthenten(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *flag = (long *) wrq->u.data.pointer;
+    char filter[4] = { 0, 0, 0, 0 };
+    int rvalue, operation;
+    void *data;
+    unsigned long dlen;
+
+    filter[0] = (char) *flag;
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Set Authenticate enable: %i\n", (int) filter[0] );
+#endif
+
+    // send a set object to set the bsstype by placing it in the transmit queue
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET, DOT11_OID_AUTHENABLE,
+        0, &filter[0], 4, 0);
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_AUTHENABLE,
+        &operation, (void **) &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;       
+}
+
+int isl_ioctl_getprivfilter(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *flag = (long *) wrq->u.data.pointer;
+    int rvalue, operation;
+    char *data;
+    unsigned long dlen;
+
+    // send a get object to get the filter setting
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_EXUNENCRYPTED, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_EXUNENCRYPTED,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+    *flag = (long) *data;
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Get Privacy filter: %i\n", (int) *flag );
+#endif
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setprivfilter(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *flag = (long *) wrq->u.data.pointer;
+    char filter[4] = { 0, 0, 0, 0 };
+    int rvalue, operation;
+    void *data;
+    unsigned long dlen;
+
+    filter[0] = (char) *flag;
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Set Privacy filter: %i\n", (int) filter[0] );
+#endif
+
+    // send a set object to set the bsstype by placing it in the transmit queue
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET, DOT11_OID_EXUNENCRYPTED,
+        0, &filter[0], 4, 0);
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_EXUNENCRYPTED,
+        &operation, (void **) &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;
+}
+
+int isl_ioctl_getprivinvoke(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *flag = (long *) wrq->u.data.pointer;
+    int rvalue, operation;
+    char *data;
+    unsigned long dlen;
+
+    // send a get object to get the filter setting
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_PRIVACYINVOKED, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_PRIVACYINVOKED,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+    *flag = (long) *data;
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Get Privacy invoked: %i\n", (int) *flag );
+#endif
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setprivinvoke(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *flag = (long *) wrq->u.data.pointer;
+    char invoke[4] = { 0, 0, 0, 0 };
+    int rvalue, operation;
+    void *data;
+    unsigned long dlen;
+
+    invoke[0] = (char) *flag;
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Set Privacy invoked: %i\n", (int) invoke[0] );
+#endif
+
+    // send a set object to set the bsstype by placing it in the transmit queue
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_PRIVACYINVOKED, 0, &invoke[0], 4, 0);
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_PRIVACYINVOKED,
+        &operation, (void **) &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;    
+}
+
+int isl_ioctl_getdefkeyid(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *key = (long *) wrq->u.data.pointer;
+    int rvalue, operation;
+    char *data;
+    unsigned long dlen;
+
+    // send a get object to get the filter setting
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_DEFKEYID, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_DEFKEYID,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Get Default Key ID %i\n", (int) *key );
+#endif
+    *key = (long) *data;
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setdefkeyid(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *key = (long *) wrq->u.data.pointer;
+    char keyid[4] = { 0, 0, 0, 0 };
+    int rvalue, operation;
+    void *data;
+    unsigned long dlen;
+
+    keyid[0] = (char) *key;
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Set Default Key ID: %i\n", (int) keyid[0] );
+#endif
+
+    // send a set object to set the bsstype by placing it in the transmit queue
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_DEFKEYID, 0, &keyid[0], 4, 0);
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_DEFKEYID,
+        &operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+		return -EINVAL;
+    return rvalue;
+}
+
+int isl_ioctl_getdefkeyx(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    int *key = (int *) wrq->u.data.pointer;
+    int rvalue, operation;
+    struct obj_key *pkey;
+    unsigned long oid;
+    unsigned long dlen;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Get Default Key %i\n", (int) *key );
+#endif
+
+    switch (*key)
+    {
+        case 0:
+            oid = DOT11_OID_DEFKEY1;
+            break;
+
+        case 1:
+            oid = DOT11_OID_DEFKEY2;
+            break;
+
+        case 2:
+            oid = DOT11_OID_DEFKEY3;
+            break;
+
+        case 3:
+            oid = DOT11_OID_DEFKEY4;
+            break;
+
+        default:
+            return -EOPNOTSUPP;
+    }
+
+    // store the key value for future write operations
+    last_key_id = *key;
+
+    // send a get object to get the filter setting
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET, oid, 0, NULL,
+        sizeof(struct obj_key), 0);
+    if (rvalue = islpci_mgt_response(private_config, oid, &operation, 
+    	(void **) &pkey, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+    if (copy_to_user( (char *) key, (void *) pkey->key, pkey->length))
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EFAULT;
+    }
+    
+    wrq->u.data.length = sizeof(pkey->key);
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setdefkeyx(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    char *key = (char *) wrq->u.data.pointer;
+    void *data;
+    unsigned long dlen;
+    struct obj_key defkey;
+    unsigned long oid;
+    int rvalue, operation;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Set Default Key %i \n", last_key_id );
+#endif
+
+    switch (last_key_id)
+    {
+        case 0:
+            oid = DOT11_OID_DEFKEY1;
+            break;
+
+        case 1:
+            oid = DOT11_OID_DEFKEY2;
+            break;
+
+        case 2:
+            oid = DOT11_OID_DEFKEY3;
+            break;
+
+        case 3:
+            oid = DOT11_OID_DEFKEY4;
+            break;
+
+        default:
+            return -EOPNOTSUPP;
+    }
+
+    defkey.type = DOT11_PRIV_WEP;
+    defkey.length = strlen(key) > sizeof(defkey.key) ? sizeof(defkey.key) :
+        strlen(key);
+    if (copy_from_user(defkey.key, key, defkey.length))
+    {
+        return -EFAULT;
+    }
+    
+    // send a set object to set the bsstype by placing it in the transmit queue
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET, oid, 0, &defkey,
+        sizeof(struct obj_key), 0);
+
+    rvalue = islpci_mgt_response(private_config, oid, &operation, &data, &dlen,
+    	&entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;    
+}
+
+int isl_ioctl_getprivstat(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    int *stat = (int *) wrq->u.data.pointer;
+    int rvalue, operation;
+    char *data;
+    unsigned long dlen;
+
+    // send a get object to get transmit rejected frame count
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_PRIVTXREJECTED, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_PRIVTXREJECTED,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "MPDU Tx Rejected %i\n", (int) *data );
+#endif
+    *stat = (int) *data;
+    stat++;
+    islpci_mgt_release( private_config, entry );
+
+    // send a get object to get rejected unencrypted frame count
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_PRIVRXPLAIN, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_PRIVRXPLAIN,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "MPDU Rx Plain %i\n", (int) *data );
+#endif
+    *stat = (int) *data;
+    stat++;
+    islpci_mgt_release( private_config, entry );
+
+    // send a get object to get rejected crypted frame count
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_PRIVRXFAILED, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_PRIVRXFAILED,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "MPDU Rx Failed %i\n", (int) *data );
+#endif
+    *stat = (int) *data;
+    stat++;
+    islpci_mgt_release( private_config, entry );
+
+    // send a get object to get received no key frames
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_PRIVRXNOKEY, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_PRIVRXNOKEY,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "MPDU Rx No Key %i\n", (int) *data );
+#endif
+    *stat = (int) *data;
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_getsuprates(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    char *rates = (char *) wrq->u.data.pointer;
+    char *data;
+    unsigned long dlen;
+    int rvalue, operation;
+
+    // request the device for the rates
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+       DOT11_OID_SUPPORTEDRATES, 0, NULL, IW_MAX_BITRATES+1, 0);
+
+    // enter sleep mode after supplying oid and local buffers for reception
+    // to the management queue receive mechanism
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_SUPPORTEDRATES,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // error in getting the response, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+    if (copy_to_user( rates, data, IW_MAX_BITRATES+1))
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EFAULT;
+    }
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_getfixedrate(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *rate = (long *) wrq->u.data.pointer;
+    int rvalue, operation;
+    char *data;
+    unsigned long dlen;
+
+    // send a get object to get the filter setting
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_ALOFT_FIXEDRATE, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_ALOFT_FIXEDRATE,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+    *rate = (long) *data;
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Get Fixed Rate index: %i\n", (int) *rate );
+#endif
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setfixedrate(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *index = (long *) wrq->u.data.pointer;
+    char rate[4] = { 0, 0, 0, 0 };
+    void *data;
+    unsigned long dlen;
+    int rvalue, operation;
+
+    rate[0] = (char) *index;
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Set Fixed Rate index: %i\n", (int) rate[0] );
+#endif
+
+    // send a set object to set the bsstype by placing it in the transmit queue
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET, DOT11_OID_ALOFT_FIXEDRATE,
+        0, &rate[0], 4, 0);
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_ALOFT_FIXEDRATE,
+        &operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;        
+}
+
+
+int isl_ioctl_getdtimper(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *flag = (long *) wrq->u.data.pointer;
+    int rvalue, operation;
+    char *data;
+    unsigned long dlen;
+
+    // send a get object to get the filter setting
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_DTIMPERIOD, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_DTIMPERIOD,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+    *flag = (long) ( (*(data+3) & 0xff) <<24 | (*(data+2) & 0xff) <<16 | 
+	     (*(data+1) & 0xff) <<8 | (*data & 0xff)); 
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Get DTIM Period: %lx\n", *flag );
+#endif
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setdtimper(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *flag = (long *) wrq->u.data.pointer;
+    char period[4] = { 0, 0, 0, 0 };
+    void *data;
+    unsigned long dlen;
+    int rvalue, operation;
+
+    period[0] = (char) (*flag & 0xff);
+    period[1] = (char) ((*flag >> 8) & 0xff);
+    period[2] = (char) ((*flag >> 16) & 0xff);
+    period[3] = (char) ((*flag >> 24) & 0xff);
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Set DTIM Period: %i\n", (int) period[0] );
+#endif
+
+    // send a set object to set the bsstype by placing it in the transmit queue
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET, DOT11_OID_DTIMPERIOD,
+        0, &period[0], 4, 0);
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_DTIMPERIOD,
+        &operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;        
+}
+
+int isl_ioctl_getbeaconper(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *flag = (long *) wrq->u.data.pointer;
+    int rvalue, operation;
+    char *data;
+    unsigned long dlen;
+
+    // send a get object to get the filter setting
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_BEACONPERIOD, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_BEACONPERIOD,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+    *flag = (long) ( (*(data+3) & 0xff) <<24 | 
+		     (*(data+2) & 0xff) <<16 | 
+		     (*(data+1) & 0xff) <<8 |
+		     (*data & 0xff)); 
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Get Beacon Period: %lx\n", *flag );
+#endif
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setbeaconper(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *flag = (long *) wrq->u.data.pointer;
+    char period[4] = { 0, 0, 0, 0 };
+    void *data;
+    unsigned long dlen;
+    int rvalue, operation;
+
+    period[0] = (char) (*flag & 0xff);
+    period[1] = (char) ((*flag >> 8) & 0xff);
+    period[2] = (char) ((*flag >> 16) & 0xff);
+    period[3] = (char) ((*flag >> 24) & 0xff);
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Set Beacon Period: %i\n", (int) period[0] );
+#endif
+
+    // send a set object to set the bsstype by placing it in the transmit queue
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET, DOT11_OID_BEACONPERIOD,
+        0, &period[0], 4, 0);
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_BEACONPERIOD,
+        &operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;        
+}
+
+int isl_ioctl_getrate(struct net_device *nwdev, struct iw_param *bitrate )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    double rate;
+    int rvalue, operation;
+    char *data;
+    unsigned long dlen;
+
+    // send a get object to get the filter setting
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        GEN_OID_LINKSTATE, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, GEN_OID_LINKSTATE,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Current rate value %i\n", (int) *data );
+#endif
+
+    rate = (double) *data * 500000;
+    bitrate->value = (int) rate;
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_getrtsthresh(struct net_device *nwdev, struct iw_param *rts )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    int rvalue, operation;
+    long *data;
+    unsigned long dlen;
+
+    // send a get object to get the filter setting
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_RTSTHRESH, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_RTSTHRESH,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+    rts->value = *data;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Get RTS Thresh 0x%08x (%i)\n", rts->value, 
+    	rts->value );
+#endif
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setrtsthresh(struct net_device *nwdev, struct iw_param *rts )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    void *data;
+    int rvalue, operation;
+    unsigned long dlen;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Set RTS Thresh: 0x%08x\n", rts->value );
+#endif
+
+    // send a set object to set the bsstype by placing it in the transmit queue
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_RTSTHRESH, 0, &rts->value, 4, 0);
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_RTSTHRESH, 
+    	&operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;        
+}
+
+int isl_ioctl_getfragthresh(struct net_device *nwdev, struct iw_param *frag )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    int rvalue, operation;
+    long *data;
+    unsigned long dlen;
+
+    // send a get object to get the filter setting
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+    	DOT11_OID_FRAGTHRESH, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_FRAGTHRESH,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+    frag->value = *data;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "Get Frag Thresh 0x%08x (%i)\n", frag->value, 
+    	frag->value );
+#endif
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setfragthresh(struct net_device *nwdev, struct iw_param *frag )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    void *data;
+    unsigned long dlen;
+    int rvalue, operation;
+	
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "Set Frag Thresh: 0x%08x\n", frag->value );
+#endif
+
+    // send a set object to set the bsstype by placing it in the transmit queue
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_FRAGTHRESH, 0, &frag->value, 4, 0);
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_FRAGTHRESH, 
+    	&operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;
+}
+
+int isl_ioctl_wdslinkadd(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    unsigned char *address = (unsigned char *) wrq->u.data.pointer;
+    unsigned char macaddr[10];
+    void *data;
+    unsigned long dlen;
+    int rvalue, operation;
+
+    // convert the address string to a MAC address
+    string_to_macaddress( address, macaddr );
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "WDS Link Add addr %02X:%02X:%02X:%02X:%02X:%02X\n",
+        macaddr[0], macaddr[1], macaddr[2],
+        macaddr[3], macaddr[4], macaddr[5] );
+#endif
+
+    // transmit the object to the card
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_WDSLINKADD, 0, &macaddr[0], 6, 0);
+
+    // enter sleep mode after supplying oid and local buffers for reception
+    // to the management queue receive mechanism
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_WDSLINKADD,
+        &operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;
+}
+
+int isl_ioctl_wdslinkdel(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    unsigned char *address = (unsigned char *) wrq->u.data.pointer;
+    unsigned char macaddr[10];
+    void *data;
+    unsigned long dlen;
+    int rvalue, operation;
+
+    // convert the address string to a MAC address
+    string_to_macaddress( address, macaddr );
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "WDS Link Remove addr %02X:%02X:%02X:%02X:%02X:%02X\n",
+        macaddr[0], macaddr[1], macaddr[2],
+        macaddr[3], macaddr[4], macaddr[5] );
+#endif
+
+    // transmit the object to the card
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_WDSLINKREMOVE, 0, &macaddr[0], 6, 0);
+
+    // enter sleep mode after supplying oid and local buffers for reception
+    // to the management queue receive mechanism
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_WDSLINKREMOVE,
+        &operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;
+}
+
+int isl_ioctl_eapauthen(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    unsigned char *address = (unsigned char *) wrq->u.data.pointer;
+    unsigned char macaddr[10];
+    void *data;
+    unsigned long dlen;
+    int rvalue, operation;
+
+    // convert the address string to a MAC address
+    string_to_macaddress( address, macaddr );
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "EAP Auth STA addr %02X:%02X:%02X:%02X:%02X:%02X\n",
+        macaddr[0], macaddr[1], macaddr[2],
+        macaddr[3], macaddr[4], macaddr[5] );
+#endif
+
+    // transmit the object to the card
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_EAPAUTHSTA, 0, &macaddr[0], 6, 0);
+
+    // enter sleep mode after supplying oid and local buffers for reception
+    // to the management queue receive mechanism
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_EAPAUTHSTA, 
+    	&operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;
+}
+
+int isl_ioctl_eapunauth(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    unsigned char *address = (unsigned char *) wrq->u.data.pointer;
+    unsigned char macaddr[10];
+    void *data;
+    unsigned long dlen;
+    int rvalue, operation;
+
+    // convert the address string to a MAC address
+    string_to_macaddress( address, macaddr );
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "EAP Unauth STA addr %02X:%02X:%02X:%02X:%02X:%02X\n",
+        macaddr[0], macaddr[1], macaddr[2],
+        macaddr[3], macaddr[4], macaddr[5] );
+#endif
+
+    // transmit the object to the card
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_EAPUNAUTHSTA, 0, &macaddr[0], 6, 0);
+
+    // enter sleep mode after supplying oid and local buffers for reception
+    // to the management queue receive mechanism
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_EAPUNAUTHSTA, 
+    	&operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;        
+}
+
+
+int isl_ioctl_getdot1xen(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *flag = (long *) wrq->u.data.pointer;
+    int rvalue, operation;
+    char *data;
+    unsigned long dlen;
+
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_DOT1XENABLE, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_DOT1XENABLE,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Get .1x flag: %i\n", (int) *data );
+#endif
+
+    *flag = (long) *data;
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setdot1xen(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *flag = (long *) wrq->u.data.pointer;
+    char enabled[4] = { 0, 0, 0, 0 };
+    void *data;
+    unsigned long dlen;
+    int rvalue, operation;
+
+    enabled[0] = (char) *flag;
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Set .1x flag: %i\n", (int) enabled[0] );
+#endif
+
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_DOT1XENABLE, 0, &enabled[0], 4, 0);
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_DOT1XENABLE,
+        &operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;
+}
+
+int isl_ioctl_getstakeyx(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    unsigned char *parameter = (unsigned char *) wrq->u.data.pointer;
+    struct obj_stakey stakey, *pstakey;
+    int rvalue, operation;
+    unsigned long dlen;
+
+    // convert the address string to a MAC address
+    string_to_macaddress( parameter, stakey.address );
+
+    // increase the read parameter pointer and read the key number
+    parameter += 13;
+    stakey.keyid = *parameter - '0';;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "sta addr %02X:%02X:%02X:%02X:%02X:%02X key %i\n",
+        (unsigned char) stakey.address[0], (unsigned char) stakey.address[1],
+        (unsigned char) stakey.address[2], (unsigned char) stakey.address[3],
+        (unsigned char) stakey.address[4], (unsigned char) stakey.address[5],
+        (int) stakey.keyid );
+#endif
+
+    // send a get object to get the stations entry
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET, DOT11_OID_STAKEY, 0,
+        &stakey, sizeof(struct obj_stakey), 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_STAKEY,
+        &operation, (void **) &pstakey, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "key %s length %i\n", pstakey->key, pstakey->length );
+#endif
+
+    parameter = (unsigned char *) wrq->u.data.pointer;
+    if (copy_to_user( (char *) parameter, (void *) &pstakey->key,
+        sizeof(pstakey->key) ))
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EFAULT;
+    }
+    
+    wrq->u.data.length = sizeof(pstakey->key)+1;
+    parameter += sizeof(pstakey->key);
+    *parameter = '\0';
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setstakeyx(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    unsigned char *parameter = (unsigned char *) wrq->u.data.pointer;
+    struct obj_stakey stakey;
+    void *data;
+    int rvalue, operation;
+    unsigned long dlen;
+
+    // convert the address string to a MAC address
+    string_to_macaddress( parameter, stakey.address );
+
+    // increase the read parameter pointer and read the key number
+    parameter += 13;
+    stakey.keyid = *parameter - '0';
+
+    // increase the read parameter pointer to read the key
+    parameter += 2;
+    stakey.type = DOT11_PRIV_WEP;
+    stakey.length = strlen(parameter) > sizeof(stakey.key) ? sizeof(stakey.key) :
+        strlen(parameter);
+    if (copy_from_user( stakey.key, parameter, stakey.length))
+    {
+        return -EFAULT;
+    }
+    
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "sta addr %02X:%02X:%02X:%02X:%02X:%02X key %i\n",
+        (unsigned char) stakey.address[0], (unsigned char) stakey.address[1],
+        (unsigned char) stakey.address[2], (unsigned char) stakey.address[3],
+        (unsigned char) stakey.address[4], (unsigned char) stakey.address[5],
+        (int) stakey.keyid );
+#endif
+
+    // send a get object to get the stations entry
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET, DOT11_OID_STAKEY, 0,
+        &stakey, sizeof(struct obj_stakey), 0);
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_STAKEY, 
+    	&operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;    
+}
+
+int isl_ioctl_getessid(struct net_device *nwdev, struct iw_point *erq)
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    struct obj_ssid *essid_obj;
+    int rvalue, operation;
+    unsigned long dlen;
+
+    // request the device for the essid
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+       DOT11_OID_SSID, 0, NULL, sizeof(struct obj_ssid), 0);
+
+    // enter sleep mode after supplying oid and local buffers for reception
+    // to the management queue receive mechanism
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_SSID,
+        &operation, (void **) &essid_obj, &dlen, &entry ), rvalue != 0)
+    {
+        // error in getting the response, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "getessid: parameter at %p\n", (void *) essid_obj);
+#endif
+
+    // copy the data to the return structure
+    erq->flags = 1;             // set ESSID to ON for Wireless Extensions
+    erq->length = essid_obj->length + 1;
+    if (erq->pointer)
+        if (copy_to_user(erq->pointer, essid_obj->octets, erq->length))
+        {
+            islpci_mgt_release( private_config, entry );
+            return -EFAULT;
+        }
+        
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setessid(struct net_device *nwdev, struct iw_point *erq)
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    struct obj_ssid essid_obj;
+    void *data;
+    int rvalue, operation;
+    unsigned long dlen;
+
+    // prepare the structure for the set object
+    essid_obj.length = erq->length - 1;
+
+    if (copy_from_user(essid_obj.octets, erq->pointer, essid_obj.length))
+        return -EFAULT;
+
+    // request the device for the essid
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_SSID, 0, (void *) &essid_obj, sizeof(struct obj_ssid), 0);
+
+    // enter sleep mode after supplying oid and local buffers for reception
+    // to the management queue receive mechanism
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_SSID, 
+    	&operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;    
+}
+
+int isl_ioctl_getbssid(struct net_device *nwdev, char *id)
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    void *data;
+    int rvalue, operation;
+    unsigned long dlen;
+
+    // request the device for the essid
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_BSSID, 0, NULL, 6, 0);
+
+    // enter sleep mode after supplying oid and local buffers for reception
+    // to the management queue receive mechanism
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_BSSID, 
+    	&operation, &data, &dlen, &entry ), rvalue != 0)
+    {
+        // error in getting the response, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "getbssid: parameter at %p\n", data);
+#endif
+
+    // return the data if the destination buffer is defined
+    if (id)
+        if (copy_to_user(id, data, 6))
+        {
+            islpci_mgt_release( private_config, entry );
+            return -EFAULT;
+        }
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setbssid(struct net_device *nwdev, char *id)
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    char bssid[6];
+    void *data;
+    unsigned long dlen;
+    int rvalue, operation;
+
+    // prepare the structure for the set object
+    if (copy_from_user(&bssid[0], id, 6))
+        return -EFAULT;
+
+    // send a set object to set the bssid
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_BSSID, 0, &bssid[0], 6, 0);
+
+    // enter sleep mode after supplying oid and local buffers for reception
+    // to the management queue receive mechanism
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_BSSID, 
+    	&operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;
+}
+
+int isl_ioctl_getmode(struct net_device *nwdev, int *mode)
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    int bsstype;
+    int rvalue, operation;
+    char *data;
+    unsigned long dlen;
+
+    // send a get object to get the bsstype
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_BSSTYPE, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_BSSTYPE,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+    // returned the bsstype, store it
+    bsstype = (int) *data;
+    islpci_mgt_release( private_config, entry );
+
+    // send a get object to get the mode
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        OID_INL_MODE, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, OID_INL_MODE,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "getmode: parameter at %p\n", data);
+#endif
+
+    // translate the cards mode to the wireless mode values as good as possible
+    switch ((int) *data)
+    {
+        case INL_MODE_AP:
+            *mode = IW_MODE_MASTER;
+            break;
+
+        case INL_MODE_CLIENT:
+            if (bsstype == DOT11_BSSTYPE_IBSS)
+                *mode = IW_MODE_ADHOC;
+            else if (bsstype == DOT11_BSSTYPE_INFRA)
+                *mode = IW_MODE_INFRA;
+            else
+                *mode = IW_MODE_AUTO;
+            break;
+
+        default:                    // DOT11_BSSTYPE_ANY
+            *mode = IW_MODE_AUTO;
+            break;
+    }
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+
+int isl_ioctl_setmode(struct net_device *nwdev, int *mode)
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    char cardmode[4] = { 0, 0, 0, 0 };
+    char bsstype[4] = { 0, 0, 0, 0 };
+    void *data;
+    unsigned long dlen;
+    int rvalue, operation;
+
+    switch (*mode)
+    {
+        case IW_MODE_ADHOC:
+            bsstype[0] = DOT11_BSSTYPE_IBSS;
+            cardmode[0] = INL_MODE_CLIENT;
+            break;
+
+        case IW_MODE_INFRA:
+            bsstype[0] = DOT11_BSSTYPE_INFRA;
+            cardmode[0] = INL_MODE_CLIENT;
+            break;
+
+        case IW_MODE_MASTER:
+            bsstype[0] = DOT11_BSSTYPE_INFRA;
+            cardmode[0] = INL_MODE_AP;
+            break;
+
+        case IW_MODE_AUTO:
+            bsstype[0] = DOT11_BSSTYPE_ANY;
+            cardmode[0] = INL_MODE_CLIENT;
+            break;
+
+        default:
+            return -EOPNOTSUPP;
+    }
+
+    // send a set object to set the mode by placing it in the transmit queue
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        OID_INL_MODE, 0, &cardmode[0], 4, 0);
+    rvalue = islpci_mgt_response(private_config, OID_INL_MODE, 
+    	&operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( rvalue )
+        return rvalue;
+    else if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+
+    // send a set object to set the bsstype by placing it in the transmit queue
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_BSSTYPE, 0, &bsstype[0], 4, 0);
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_BSSTYPE, 
+    	&operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;
+}
+
+int isl_ioctl_getfreq(struct net_device *nwdev, struct iw_freq *frq)
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    u32 *data, channel;
+    unsigned long dlen;
+    int rvalue, operation;
+
+    // request the device for the channel
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_FREQUENCY, 0, NULL, 4, 0);
+
+    // enter sleep mode after supplying oid and local buffers for reception
+    // to the management queue receive mechanism
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_FREQUENCY,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // error in getting the response, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+    channel = *data;
+
+    // check whether it concern a channel number or a frequency
+    // this becomes difficult because the frequency is in kHz
+    if (channel < 1000)
+    {
+        // interpret the data as a channel
+        frq->m = le32_to_cpu( channel );
+        frq->e = 0;
+    }
+    else
+    {
+        // interpret the data as frequency
+        frq->m = le32_to_cpu( channel );
+        frq->e = 3;
+    }
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setfreq(struct net_device *nwdev, struct iw_freq *frq)
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    char channel[4] = { 0, 0, 0, 0 }, *data;
+    long mantisse;
+    long oid;
+    int exponent;
+    int rvalue, operation;
+    unsigned long dlen;
+
+    // prepare the structure for the set object
+    if (frq->m < 1000)
+    {
+        // structure value contains a channel indication
+	oid = DOT11_OID_CHANNEL;
+        channel[0] = (char) frq->m;
+        channel[1] = (char) (frq->m >> 8);
+    }
+    else
+    {
+        // structure contains a frequency indication
+		oid = DOT11_OID_FREQUENCY;
+	
+        // mantisse is larger than 1000, so make it kHz
+        mantisse = frq->m / 1000;
+        exponent = frq->e;
+
+        // process the exponent
+        while (exponent > 0)
+        {
+            mantisse *= 10;
+            exponent--;
+        }
+
+        // convert the frequency to the right byte order
+        channel[0] = (char) mantisse;
+        channel[1] = (char) (mantisse >> 8);
+        channel[2] = (char) (mantisse >> 16);
+        channel[3] = (char) (mantisse >> 24);
+    }
+
+    // send a set object to set the channel by placing it in the transmit queue
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET, oid, 0, &channel[0], 4, 0);
+
+    // enter sleep mode after supplying oid and local buffers for reception
+    // to the management queue receive mechanism
+    rvalue = islpci_mgt_response(private_config, oid, &operation, 
+    	(void **) &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;        
+}
+
+int isl_ioctl_getpsm(struct net_device *nwdev,
+    struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *psm = (long *) wrq->u.data.pointer;
+    int rvalue, operation;
+    long *data;
+    unsigned long dlen;
+
+    // send a get object to get the filter setting
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_PSM, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_PSM,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+    *psm = *data;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "Get PSM 0x%08lx (%li)\n", *psm, *psm );
+#endif
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setpsm(struct net_device *nwdev,
+    struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *psm = (long *) wrq->u.data.pointer;
+    void *data;
+    unsigned long dlen;
+    int rvalue, operation;
+	
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "Set PSM: 0x%08lx\n", (long) *psm );
+#endif
+
+    // send a set object to set the bsstype by placing it in the transmit queue
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_PSM, 0, psm, 4, 0);
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_PSM, &operation, 
+    	&data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;
+}
+
+int isl_ioctl_getnonerp(struct net_device *nwdev,
+    struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *erp = (long *) wrq->u.data.pointer;
+    int rvalue, operation;
+    char *data;
+    unsigned long dlen;
+
+    // send a get object to get the filter setting
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        DOT11_OID_NONERPPROTECTION, 0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_NONERPPROTECTION,
+        &operation, (void **) &data, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+    *erp = (long) *data;
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "Get Non ERP Protection: %i\n", (int) *erp );
+#endif
+
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_setnonerp(struct net_device *nwdev,
+    struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    long *nonerp = (long *) wrq->u.data.pointer;
+    char erp[4] = { 0, 0, 0, 0 };
+    void *data;
+    unsigned long dlen;
+    int rvalue, operation;
+
+    erp[0] = (char) *nonerp;
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "Set Non ERP Protection %i\n", (int) erp[0] );
+#endif
+
+    // send a set object to set the bsstype by placing it in the transmit queue
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET, DOT11_OID_NONERPPROTECTION,
+        0, &erp[0], 4, 0);
+    rvalue = islpci_mgt_response(private_config, DOT11_OID_NONERPPROTECTION,
+        &operation, &data, &dlen, &entry );
+    islpci_mgt_release( private_config, entry );
+    if( operation == PIMFOR_OP_ERROR )
+        return -EINVAL;
+    return rvalue;
+}
+
+int isl_ioctl_getcountrystring(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    queue_entry *entry = NULL;
+    char *cstring = (char *) wrq->u.data.pointer;
+    char *rstring;
+    int rvalue, operation;
+    unsigned long dlen;
+
+    // send a get object to get the filter setting
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET, DOT11_OID_COUNTRYSTRING, 
+    	0, NULL, 4, 0);
+    if (rvalue = islpci_mgt_response(private_config, DOT11_OID_COUNTRYSTRING, 
+    	&operation, (void **) &rstring, &dlen, &entry ), rvalue != 0)
+    {
+        // an error occurred, return the value
+        islpci_mgt_release( private_config, entry );
+        return rvalue;
+    }
+    else if( operation == PIMFOR_OP_ERROR )
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EINVAL;
+    }    
+
+    if (copy_to_user( (char *) cstring, (void *) rstring, 4))
+    {
+        islpci_mgt_release( private_config, entry );
+        return -EFAULT;
+    }
+    
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "Get Country String: %02x %02x %02x %02x\n", 
+    	rstring[0], rstring[1], rstring[2], rstring[3]  );
+#endif
+    
+    wrq->u.data.length = 4;
+    islpci_mgt_release( private_config, entry );
+    return 0;
+}
+
+int isl_ioctl_resetdevice(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Toggled the device reset flag\n");
+#endif
+
+    // set the kernel space reset flag
+    private_config->resetdevice = 1;
+
+    return 0;
+}
+
+int isl_ioctl_checktraps(struct net_device *nwdev, struct iwreq *wrq )
+{
+    islpci_private *private_config = nwdev->priv;
+    char *frame = (char *) wrq->u.data.pointer;
+    queue_entry *entry;
+    int device_id, operation, flags, length;
+    unsigned long oid;
+
+    // check whether the trap queue is empty
+    if( islpci_queue_size( private_config->remapped_device_base,
+        &private_config->trap_rx_queue ) == 0 )
+    {
+        // no entries in the trap queue
+#if VERBOSE > SHOW_ERROR_MESSAGES
+        DEBUG(SHOW_TRACING, "TRAP receive queue empty\n");
+#endif
+        return -ENOMSG;
+    }
+
+    // read a frame from the queue and return it
+    islpci_get_queue( private_config->remapped_device_base,
+        &private_config->trap_rx_queue, &entry );
+
+    // decode the PIMFOR frame for data length
+    pimfor_decode_header( (pimfor_header *) entry->host_address, &operation,
+        &oid, &device_id, &flags, &length );
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG( SHOW_TRACING, "TRAP: oid 0x%lx, device %i, flags 0x%x length %i\n",
+            oid, device_id, flags, length );
+#endif
+
+    // copy the frame to the data buffer
+    if (copy_to_user( frame, (void *) entry->host_address, PIMFOR_HEADER_SIZE+length ))
+    {
+        // free the entry to the freeq
+        islpci_put_queue(private_config->remapped_device_base,
+            &private_config->mgmt_rx_freeq, entry);
+
+        return -EFAULT;
+    }
+
+    // free the entry to the freeq
+    islpci_put_queue(private_config->remapped_device_base,
+        &private_config->mgmt_rx_freeq, entry);
+
+    return 0;
+}
+
+int isl_ioctl(struct net_device *nwdev, struct ifreq *rq, int cmd )
+{
+    struct iwreq *wrq = (struct iwreq *) rq;
+    islpci_private *private_config = nwdev->priv;
+    int error = 0;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    void *device = private_config->remapped_device_base;
+
+    DEBUG(SHOW_FUNCTION_CALLS, "isl_ioctl cmd %x \n", cmd);
+
+    DEBUG(SHOW_QUEUE_INDEXES, "Mgmt Tx Qs: free[%i] shdw[%i]\n",
+        islpci_queue_size(device, &private_config->mgmt_tx_freeq),
+        islpci_queue_size(device, &private_config->mgmt_tx_shadowq));
+#endif
+
+    switch (cmd)
+    {
+        case SIOCGIWNAME:
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCGIWNAME\n", nwdev->name);
+#endif
+            if( private_config->pci_dev_id == PCIDEVICE_ISL3877 )
+                strncpy( wrq->u.name, "PRISM Indigo", IFNAMSIZ );
+            else if( private_config->pci_dev_id == PCIDEVICE_ISL3890 )
+                strncpy( wrq->u.name, "PRISM Duette", IFNAMSIZ );
+            else
+                strncpy( wrq->u.name, "Unsupported card type", IFNAMSIZ );
+            break;
+
+        case SIOCGIWRATE:
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCGIWRATE\n", nwdev->name);
+#endif
+            error = isl_ioctl_getrate(nwdev, &wrq->u.bitrate );
+            break;
+
+	case SIOCGIWRTS:
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCGIWRTS\n", nwdev->name);
+#endif
+            error = isl_ioctl_getrtsthresh(nwdev, &wrq->u.rts );
+	    break;
+
+	case SIOCSIWRTS:
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCSIWRTS\n", nwdev->name);
+#endif
+            error = isl_ioctl_setrtsthresh(nwdev, &wrq->u.rts );
+	    break;
+
+	case SIOCGIWFRAG:
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCGIWFRAG\n", nwdev->name);
+#endif
+            error = isl_ioctl_getfragthresh(nwdev, &wrq->u.frag );
+	    break;
+
+	case SIOCSIWFRAG:
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCSIWFRAG\n", nwdev->name);
+#endif
+            error = isl_ioctl_setfragthresh(nwdev, &wrq->u.frag );
+	    break;
+
+        case SIOCGIWRANGE:
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCGIWRANGE\n", nwdev->name);
+#endif
+            error = isl_ioctl_getrange(nwdev,
+                (struct iw_range *) wrq->u.data.pointer );
+            wrq->u.data.length = sizeof(struct iw_range);
+            break;
+
+#if WIRELESS_EXT > 11
+//      case SIOCGIWSTATS:
+//          DEBUG(SHOW_TRACING, "%s: SIOCGIWSTATS\n", nwdev->name);
+//          error = isl_ioctl_getstats(nwdev,
+//              (struct iw_statistics *) wrq->u.data.pointer );
+//          break;
+#endif
+
+        case SIOCGIWESSID:
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCGIWESSID\n", nwdev->name);
+#endif
+            error = isl_ioctl_getessid(nwdev, &wrq->u.essid);
+            break;
+
+        case SIOCSIWESSID:
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCSIWESSID\n", nwdev->name);
+#endif
+            // check which operation is requied depending on the flag
+            if (wrq->u.essid.flags == 0)
+            {
+            // disable essid checking (ESSID promiscuous)
+                // is it supported by the card ?
+            return -EOPNOTSUPP;
+            }
+            else
+            {
+                // set the essid to the value supplied
+                error = isl_ioctl_setessid(nwdev, &wrq->u.essid);
+            }
+
+            break;
+
+        case SIOCGIWAP:
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCGIWAP\n", nwdev->name);
+#endif
+            wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
+            error = isl_ioctl_getbssid(nwdev, &wrq->u.ap_addr.sa_data[0]);
+            break;
+
+        case SIOCSIWAP:
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCSIWAP\n", nwdev->name);
+#endif
+            error = isl_ioctl_setbssid(nwdev, &wrq->u.ap_addr.sa_data[0]);
+            break;
+
+        case SIOCSIWMODE:
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCSIWMODE\n", nwdev->name);
+#endif
+            error = isl_ioctl_setmode(nwdev, &wrq->u.mode);
+            break;
+
+        case SIOCGIWMODE:
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCGIWMODE\n", nwdev->name);
+#endif
+            error = isl_ioctl_getmode(nwdev, &wrq->u.mode);
+            break;
+
+        case SIOCGIWFREQ:
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCGIWFREQ\n", nwdev->name);
+#endif
+            error = isl_ioctl_getfreq(nwdev, &wrq->u.freq);
+            break;
+
+        case SIOCSIWFREQ:
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCSIWFREQ\n", nwdev->name);
+#endif
+            error = isl_ioctl_setfreq(nwdev, &wrq->u.freq);
+            break;
+
+        case SIOCGIWPRIV:
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCGIWPRIV\n", nwdev->name);
+#endif
+            if (wrq->u.data.pointer)
+            {
+                if( error = verify_area(VERIFY_WRITE, wrq->u.data.pointer,
+                    sizeof(privtab)), error )
+                {
+#if VERBOSE > SHOW_ERROR_MESSAGES
+                    DEBUG(SHOW_TRACING, "verify_area error %i\n", error );
+#endif
+                    break;
+                }
+
+                wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
+                if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
+                {
+#if VERBOSE > SHOW_ERROR_MESSAGES
+                    DEBUG(SHOW_TRACING, "copy_to_user error %i\n", error );
+#endif
+                    error = -EFAULT;
+                }
+            }
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x00:                    // setauthenten
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+0 (setauthenten)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_setauthenten(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x01:                    // getauthenten
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+1 (getauthenten)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_getauthenten(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x02:                    // setunencrypted
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+2 (setunencrypt)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_setprivfilter(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x03:                    // getunencrypted
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+3 (getunencrypt)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_getprivfilter(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x04:                    // setprivinvoke
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+4 (setprivinvoke)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_setprivinvoke(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x05:                    // getprivinvoke
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+5 (getprivinvoke)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_getprivinvoke(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x06:                    // setdefkeyid
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+6 (setdefkeyid)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_setdefkeyid(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x07:                    // getdefkeyid
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+7 (getdefkeyid)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_getdefkeyid(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x08:                    // setdefkeyx
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+8 (setdefkeyx)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_setdefkeyx(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x09:                    // getdefkeyx
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+9 (getdefkeyx)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_getdefkeyx(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x0A:                    // getprivstat
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+10 (getprivstat)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_getprivstat(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x0B:                    // getsuprates
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+11 (getsuprates)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_getsuprates(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x0C:                    // setdtimper
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+12 (setdtimper)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_setdtimper(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x0D:                    // getdtimper
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+13 (getdtimper)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_getdtimper(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x0E:                    // setbeaconper
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+14 (setbeaconper)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_setbeaconper(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x0F:                    // getauthenten
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+15 (getbeaconper)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_getbeaconper(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x10:                    // wdslinkadd
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+16 (wdslinkadd)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_wdslinkadd(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x11:                    // wdslinkdel
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+17 (wdslinkdel)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_wdslinkdel(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x12:                    // eapauthen
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+18 (eapauthen)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_eapauthen(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x13:                    // eapunauth
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+19 (eapunauth)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_eapunauth(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x14:                    // setdot1xen
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+20 (setdot1xen)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_setdot1xen(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x15:                    // getdot1xen
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+21 (getdot1xen)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_getdot1xen(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x16:                    // setstakeyx
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+22 (setstakeyx)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_setstakeyx(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x17:                    // getstakeyx
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+23 (getstakeyx)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_getstakeyx(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x18:                    // setfixedrate
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+24 (setfixedrate)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_setfixedrate(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x19:                    // getfixedrate
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+25 (getfixedrate)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_getfixedrate(nwdev, wrq);
+            break;
+
+/*
+        case SIOCIWFIRSTPRIV + 0x18:                    // setfragthresh
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+24 (setfragthresh)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_setfragthresh(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x19:                    // getfragthresh
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+25 (getfragthresh)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_getfragthresh(nwdev, wrq);
+            break;
+*/
+        case SIOCIWFIRSTPRIV + 0x1A:                    // setpsm
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+26 (setpsm)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_setpsm(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x1B:                    // getpsm
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+27 (getpsm)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_getpsm(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x1C:                    // setnonerp
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+28 (setnonerp)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_setnonerp(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x1D:                    // getnonerp
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+29 (getnonerp)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_getnonerp(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x1E:                    // getcountrystr
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+30 (getcountrystr)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_getcountrystring(nwdev, wrq);
+            break;
+
+        case SIOCIWFIRSTPRIV + 0x1F:                    // checktraps
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "%s: SIOCIWFIRSTPRIV+31 (checktraps)\n",
+                nwdev->name);
+#endif
+            error = isl_ioctl_checktraps(nwdev, wrq);
+            break;
+
+        default:
+            error = -EOPNOTSUPP;
+    }
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_QUEUE_INDEXES,
+        "Mgmt Rx Qs: f[%i] s[%i] i[%i] t[%i] p[%i]\n",
+        islpci_queue_size(device, &private_config->mgmt_rx_freeq),
+        islpci_queue_size(device, &private_config->mgmt_rx_shadowq),
+        islpci_queue_size(device, &private_config->ioctl_rx_queue),
+        islpci_queue_size(device, &private_config->trap_rx_queue),
+        islpci_queue_size(device, &private_config->pimfor_rx_queue));
+#endif
+
+    return error;
+}
+
+#else   // no WIRELESS_IOCTLS
+
+int isl_ioctl(struct net_device *nwdev, struct ifreq *rq, int cmd )
+{
+    int error = 0;
+
+    switch (cmd)
+    {
+        default:
+            error = -EOPNOTSUPP;
+    }
+
+    return error;
+}
+
+#endif  // WIRELESS_IOCTLS
diff -urN linux-2.4.29/drivers/net/intersil/isl_ioctl.h linux-2.4.29-uc1/drivers/net/intersil/isl_ioctl.h
--- linux-2.4.29/drivers/net/intersil/isl_ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/isl_ioctl.h	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,81 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef _ISL_IOCTL_H
+#define _ISL_IOCTL_H
+
+
+#include <linux/wireless.h>
+
+#include <islpci_mgt.h>
+#include <bloboid.h>      // additional types and defs for 38xx firmware
+
+
+#define SUPPORTED_WIRELESS_EXT                  15
+
+
+int isl_ioctl_getrange( struct net_device *, struct iw_range * );
+int isl_ioctl_setrange( struct net_device *, struct iw_range * );
+
+#if WIRELESS_EXT > 11
+
+int isl_ioctl_getstats( struct net_device *, struct iw_statistics *);
+int isl_ioctl_setstats( struct net_device *, struct iw_statistics *);
+
+#endif
+
+int isl_ioctl_getauthenten( struct net_device *, struct iwreq * );
+int isl_ioctl_setauthenten( struct net_device *, struct iwreq * );
+int isl_ioctl_getprivfilter( struct net_device *, struct iwreq * );
+int isl_ioctl_setprivfilter( struct net_device *, struct iwreq * );
+int isl_ioctl_getprivinvoke( struct net_device *, struct iwreq * );
+int isl_ioctl_setprivinvoke( struct net_device *, struct iwreq * );
+int isl_ioctl_getdefkeyid( struct net_device *, struct iwreq * );
+int isl_ioctl_setdefkeyid( struct net_device *, struct iwreq * );
+int isl_ioctl_getdefkeyx( struct net_device *, struct iwreq * );
+int isl_ioctl_setdefkeyx( struct net_device *, struct iwreq * );
+int isl_ioctl_getprivstat( struct net_device *, struct iwreq * );
+int isl_ioctl_getsuprates( struct net_device *, struct iwreq * );
+int isl_ioctl_getfixedrate( struct net_device *, struct iwreq * );
+int isl_ioctl_setfixedrate( struct net_device *, struct iwreq * );
+int isl_ioctl_getbeaconper( struct net_device *, struct iwreq * );
+int isl_ioctl_setbeaconper( struct net_device *, struct iwreq * );
+int isl_ioctl_getrate( struct net_device *, struct iw_param * );
+int isl_ioctl_wdslinkadd( struct net_device *, struct iwreq * );
+int isl_ioctl_wdslinkdel( struct net_device *, struct iwreq * );
+int isl_ioctl_eapauthen( struct net_device *, struct iwreq * );
+int isl_ioctl_eapunauth( struct net_device *, struct iwreq * );
+int isl_ioctl_getdot1xen( struct net_device *, struct iwreq * );
+int isl_ioctl_setdot1xen( struct net_device *, struct iwreq * );
+int isl_ioctl_getstakeyx( struct net_device *, struct iwreq * );
+int isl_ioctl_setstakeyx( struct net_device *, struct iwreq * );
+int isl_ioctl_getessid( struct net_device *, struct iw_point * );
+int isl_ioctl_setessid( struct net_device *, struct iw_point * );
+int isl_ioctl_getbssid( struct net_device *, char * );
+int isl_ioctl_setbssid( struct net_device *, char * );
+int isl_ioctl_getmode( struct net_device *, int * );
+int isl_ioctl_setmode( struct net_device *, int * );
+int isl_ioctl_getfreq( struct net_device *, struct iw_freq * );
+int isl_ioctl_setfreq( struct net_device *, struct iw_freq * );
+int isl_ioctl_checktraps( struct net_device *, struct iwreq * );
+
+int isl_ioctl( struct net_device *, struct ifreq *, int );
+
+
+#endif  // _ISL_IOCTL_H
diff -urN linux-2.4.29/drivers/net/intersil/isl_mgt.c linux-2.4.29-uc1/drivers/net/intersil/isl_mgt.c
--- linux-2.4.29/drivers/net/intersil/isl_mgt.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/isl_mgt.c	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,562 @@
+/*  $Header$
+ *
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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 <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/rtnetlink.h>
+#include <linux/isil_netlink.h>
+#include <net/sock.h>
+
+#include "isl_mgt.h"
+
+#define IND_TABLE_SZ    15
+#define RESP_TABLE_SZ   15
+
+#ifndef NULL
+#   define  NULL ((void *)0)
+#endif
+
+// #define DRIVER_DEBUG 1
+
+unsigned int src_seq = 0;
+
+static struct ind_rec {
+    unsigned int   dev_type;
+    char           name[IFNAMSIZ];
+    unsigned int   dev_seq;
+    unsigned int   oid;
+    mgt_indication_t ind;
+} ind_table[IND_TABLE_SZ];
+
+static struct resp_rec {
+    unsigned int   src_id;
+    char           name[IFNAMSIZ];
+    unsigned int   src_seq;
+    unsigned int   oid;
+    mgt_response_t resp;
+} resp_table[RESP_TABLE_SZ];
+
+static mgt_confirm_t cnf_hndl = NULL;
+
+static int mgt_initialised = 0;
+static struct sock *nl_sock = NULL; /* netlink socket */
+
+static int ntl_confirm( unsigned int src_id, unsigned int src_seq,
+                        unsigned int dev_type, unsigned int dev_seq,
+                        unsigned int op, unsigned int oid, void *data, unsigned long len);
+static int ntl_transmit(pid_t pid, int seq, int operation,
+                        int oid, long *data, unsigned long data_len,
+                        int dev_type, int dev_id );
+static void ntl_receive(struct sock *sk, int len);
+
+static int pimfor_encode_header(int operation, unsigned long oid, int device_id,
+                                int flags, int length, struct pimfor_hdr *header);
+static int pimfor_decode_header(struct pimfor_hdr *header, int *version,
+                                int *operation, unsigned long *oid,
+                                int *device_id, int *flags, unsigned long *length);
+
+
+/********************************************************************
+*                      Management interfaces
+*********************************************************************/
+
+int mgt_ind_table_init = 0;
+
+int mgt_request( unsigned int dev_type, unsigned int dev_seq,
+                 unsigned int src_id,   unsigned int src_seq,
+                 unsigned int op, int oid, void *data, unsigned long len)
+{
+    int i;
+    int err = -EPFNOSUPPORT;
+    struct net_device *dev;
+    struct ind_rec *pi;
+    mgt_indication_t ind_oid = NULL;
+    mgt_indication_t ind_def = NULL;
+
+#ifdef DRIVER_DEBUG
+    printk (KERN_ERR "mgt_request(%d, %d, %d, %d, %d, %x, <data>, %d)\n",
+            dev_type, dev_seq, src_id, src_seq, op, oid, (unsigned int)len );
+#endif
+
+    if ( mgt_ind_table_init != -1 ) {
+
+        if ( ! (dev = dev_get_by_index( dev_seq ) ) )
+            return -1;
+
+        for ( i = 0, pi = ind_table; ( pi->ind != NULL ) && ( i < IND_TABLE_SZ ); i++, pi++ ) {
+           if ( ( pi->dev_seq == 0 ) && ( strncmp ( pi->name, dev->name, IFNAMSIZ ) == 0 ) ) {
+               mgt_ind_table_init++;
+               pi->dev_seq = dev_seq;
+           }
+        }
+
+        if ( i == mgt_ind_table_init ) {
+            mgt_ind_table_init = -1;
+        }
+
+        dev_put( dev );
+    }
+
+    for ( i = 0, pi = ind_table; i < IND_TABLE_SZ; i++, pi++ ) {
+        if ( ( pi->dev_type == dev_type ) && ( pi->dev_seq == dev_seq ) && ( pi->ind != NULL ) ) {
+            if ( pi->oid == oid ) {
+                ind_oid = pi->ind;
+                break;
+            } else if ( pi->oid == 0 ) {
+                ind_def = pi->ind;
+            }
+        }
+    }
+
+    /* only one request allowed (confirm); specific handlers have priority over default handler */
+    if ( ind_oid ) {
+        err = (*ind_oid)( dev_type, dev_seq, src_id, src_seq, op, oid, data, len );
+    } else if ( ind_def ) {
+        err = (*ind_def)( dev_type, dev_seq, src_id, src_seq, op, oid, data, len );
+    }
+
+    return err;
+}
+
+int mgt_resp_table_init = 0;
+
+int mgt_response( unsigned int src_id, unsigned int src_seq,
+                  unsigned int dev_type, unsigned int dev_seq,
+                  unsigned int op, int oid, void *data, unsigned long len)
+{
+    int i;
+    int err = 0;
+    struct net_device *dev;
+    struct resp_rec *pr;
+    mgt_response_t resp_oid = NULL;
+    mgt_response_t resp_def = NULL;
+
+#ifdef DRIVER_DEBUG
+    printk (KERN_ERR "mgt_response(%d, %d, %d, %d, %d, %x, <data>, %d)\n",
+            src_id, src_seq, dev_type, dev_seq, op, oid, (unsigned int)len );
+#endif
+
+    if ( mgt_resp_table_init != -1 ) {
+
+        if ( ! (dev = dev_get_by_index( dev_seq ) ) )
+            return -1;
+
+        for ( i = 0, pr = resp_table; ( pr->resp != NULL ) && ( i < RESP_TABLE_SZ ); i++, pr++ ) {
+           if ( ( pr->src_seq == 0 ) && ( strncmp ( pr->name, dev->name, IFNAMSIZ ) == 0 ) ) {
+               mgt_resp_table_init++;
+               pr->src_seq = dev_seq;
+           }
+        }
+
+        if ( i == mgt_resp_table_init ) {
+            mgt_resp_table_init = -1;
+        }
+
+        dev_put( dev );
+    }
+
+    for ( i = 0, pr = resp_table; i < RESP_TABLE_SZ; i++, pr++ ) {
+        if ( ( pr->src_id == src_id ) && ( pr->src_seq == src_seq ) && ( pr->resp != NULL ) ) {
+            if ( pr->oid == oid ) {
+                resp_oid = pr->resp;
+                break;
+            } else if ( pr->oid == 0 ) {
+                resp_def = pr->resp;
+            }
+        }
+    }
+
+    /* only one response allowed (indication); specific handlers have priority over default handler */
+    if ( resp_oid ) {
+        if ( (*resp_oid)( src_id, src_seq, dev_type, dev_seq, op, oid, data, len ) < 0)
+            err = -EPFNOSUPPORT;
+    } else if ( cnf_hndl ) {
+        if ( ( *cnf_hndl )( src_id, src_seq, dev_type, dev_seq, op, oid, data, len ) < 0 )
+            err = -EPFNOSUPPORT;
+    }
+
+    return err;
+}
+
+int mgt_confirm( unsigned int src_id, unsigned int src_seq,
+                  unsigned int dev_type, unsigned int dev_seq,
+                  unsigned int op, int oid, void *data, unsigned long len)
+{
+    return ntl_confirm( src_id, src_seq, dev_type, dev_seq, op, oid, data, len);
+}
+
+int mgt_indication_handler( unsigned int dev_type, char *dev_name,
+                            unsigned int oid, mgt_indication_t ind )
+{
+    int i;
+    struct ind_rec *pi;
+
+    if ( ind ) {
+        for ( i = 0, pi = ind_table; i < IND_TABLE_SZ; i++, pi++ ) {
+           if ( pi->ind == 0 ) {
+              pi->dev_type = dev_type;
+              strncpy( pi->name, dev_name, IFNAMSIZ );
+              pi->dev_seq  = 0;
+              pi->oid      = oid;
+              pi->ind      = ind;
+              return 0;
+           }
+        }
+    }
+
+    return -EPFNOSUPPORT;
+}
+
+int mgt_response_handler( unsigned int src_id, char *dev_name,
+                            unsigned int oid, mgt_response_t resp )
+{
+    int i;
+    struct resp_rec *pr;
+
+    if ( resp ) {
+        for ( i = 0, pr = resp_table; i < RESP_TABLE_SZ; i++, pr++ ) {
+           if ( pr->resp == 0 ) {
+              pr->src_id   = src_id;
+              strncpy( pr->name, dev_name, IFNAMSIZ );
+              pr->src_seq  = 0;
+              pr->oid      = oid;
+              pr->resp     = resp;
+              return 0;
+           }
+        }
+    }
+
+    return -EPFNOSUPPORT;
+}
+
+int mgt_confirm_handler( mgt_confirm_t cnf )
+{
+    if ( cnf ) {
+        cnf_hndl = cnf;
+        return 0;
+    }
+
+    return -EPFNOSUPPORT;
+}
+
+int mgt_ind_table_dump_hndl ( unsigned int dev_id,   unsigned int dev_seq,
+                              unsigned int src_id,   unsigned int src_seq,
+                              unsigned int op,       unsigned int oid, void *data, unsigned long len )
+{
+    int i;
+    struct ind_rec *pi;
+
+    printk (KERN_ERR "mgt_ind_table_dump_hndl(%d, %d, %d, %d, %d, %x, <data>, %d)\n",
+            dev_id, dev_seq, src_id, src_seq, op, oid, (unsigned int)len );
+
+    for ( i = 0, pi = ind_table; ( pi->ind != NULL ) && ( i < IND_TABLE_SZ ); i++, pi++ ) {
+        printk ( KERN_ERR "%d - %s - %d - %x - %p\n",
+                 pi->dev_type, pi->name, pi->dev_seq, pi->oid, pi->ind );
+    }
+}
+
+
+int mgt_initialize( void )
+{
+    int i;
+    struct ind_rec  *ip;
+    struct resp_rec *pr;
+
+#ifdef DRIVER_DEBUG
+    printk ( KERN_ERR "mgt_initialize(%d)\n", mgt_initialised );
+#endif
+
+    if( mgt_initialised )
+        return 0;
+
+    mgt_initialised = 1;
+
+    for ( i = 0, ip = ind_table; i < IND_TABLE_SZ; i++, ip++ ) {
+        ip->dev_type = 0;
+        ip->dev_seq  = 0;
+        ip->oid      = 0;
+        ip->ind      = NULL;
+    }
+
+    for ( i = 0, pr = resp_table; i < RESP_TABLE_SZ; i++, pr++ ) {
+        pr->src_id   = 0;
+        pr->src_seq  = 0;
+        pr->oid      = 0;
+        pr->resp     = NULL;
+    }
+
+    cnf_hndl = NULL;
+
+    /* Open the netlink socket */
+    if (nl_sock == NULL) {
+        if ( (nl_sock = netlink_kernel_create(NETLINK_ISIL, ntl_receive)) == NULL )
+            printk("netlink_kernel_create failed\n");
+    }
+
+    mgt_confirm_handler( ntl_confirm );
+
+    return 0;
+}
+
+int mgt_cleanup( void )
+{
+    if ( nl_sock ) {
+		sock_release( nl_sock->socket );
+    }
+
+    return 0;
+}
+
+
+/*********************************************************************
+*                        Netlink interface
+*********************************************************************/
+
+static int ntl_confirm( unsigned int src_id, unsigned int src_seq,
+                        unsigned int dev_type, unsigned int dev_seq,
+                        unsigned int op, unsigned int oid, void *data, unsigned long len)
+{
+    return ntl_transmit(src_id, src_seq, op, oid, (long*)data, len, dev_type, dev_seq );
+}
+
+static int ntl_transmit(pid_t pid, int seq, int operation, int oid, long *data, unsigned long data_len,
+                        int dev_type, int dev_id )
+{
+    unsigned char *old_tail;
+    struct sk_buff *skb;
+    struct nlmsghdr *nlh;
+    struct pimfor_hdr *pimfor_hdr;
+    size_t size;
+
+    int err = 0;
+    /* Trap group is mapped to dev_type. */
+    unsigned int trapgrp = dev_type;
+
+#ifdef DRIVER_DEBUG
+    printk(KERN_INFO "ntl_transmit: pid %d, seq %d, oper %d, oid %d, data ptr %p, data_len %lu, dev_id %d \n",
+                       pid, seq, operation, oid, data, data_len, dev_id);
+#endif
+
+    if ( nl_sock == NULL ) {
+        printk(KERN_ERR "ntl_transmit: no nl_sock\n");
+        return -EPFNOSUPPORT;
+    }
+
+    size = NLMSG_LENGTH(data_len + sizeof(struct pimfor_hdr));
+    skb = alloc_skb(size, GFP_ATOMIC);
+
+    if ( skb ) {
+
+        old_tail = skb->tail;
+        nlh = NLMSG_PUT(skb, pid, seq, NETLINK_TYPE_PIMFOR, size - NLMSG_ALIGN(sizeof(struct nlmsghdr)));
+        pimfor_hdr = (struct pimfor_hdr *)NLMSG_DATA(nlh);
+
+        pimfor_encode_header(operation, oid, dev_id, 0 /*flags*/, data_len, pimfor_hdr);
+        /* Add data after the PIMFOR header */
+        memcpy(PIMFOR_DATA(pimfor_hdr), data, data_len);
+
+        nlh->nlmsg_len = skb->tail - old_tail;
+        NETLINK_CB(skb).dst_groups = 0;
+    } else {
+
+        printk(KERN_ERR "ntl_transmit: alloc_skb failed\n");
+        return -EPFNOSUPPORT;
+    }
+
+    if (pid != 0 ) {
+        err = netlink_unicast(nl_sock, skb, pid, MSG_DONTWAIT);
+    } else {
+        if (trapgrp) {
+            netlink_broadcast(nl_sock, skb, pid, trapgrp ,GFP_ATOMIC );
+        }
+        else {
+            printk(KERN_WARNING "No trap group defined, drop packet.\n");
+            kfree_skb(skb);
+        }
+    }
+
+    return err;
+
+nlmsg_failure:
+    if ( skb )
+            kfree_skb(skb);
+    printk(KERN_ERR "ntl_transmit: NLMSG_PUT failed\n");
+    return -EPFNOSUPPORT;
+}
+
+static void ntl_receive(struct sock *sk, int len)
+{
+    int err;
+    struct sk_buff *skb;
+    pid_t pid;
+    struct nlmsghdr *nl_header;
+    __u32 seq;
+    struct pimfor_hdr *header;
+    char *data;
+    int version;
+    int operation;
+    unsigned long oid;
+    int dev_id;
+    int flags;
+    unsigned long length;
+  	struct net_device *dev;
+
+#ifdef DRIVER_DEBUG
+    printk(KERN_INFO "ntl_receive: sock %p, len %d \n", sk, len);
+#endif
+
+    do
+    {
+        if (rtnl_shlock_nowait())
+                return;
+
+        while ( (skb = skb_dequeue(&sk->receive_queue)) != NULL )
+        {
+            pid = NETLINK_CB(skb).pid;
+            nl_header = (struct nlmsghdr*) skb->data;
+            seq = nl_header->nlmsg_seq;
+            header = (struct pimfor_hdr*)(skb->data+(sizeof(struct nlmsghdr)));
+            data = PIMFOR_DATA(header);
+
+            if ( nl_header->nlmsg_type == NETLINK_TYPE_PIMFOR )
+            {
+                pimfor_decode_header(header, &version, &operation, &oid, &dev_id, &flags, &length);
+
+                if (version == PIMFOR_VERSION_1) {
+
+                    err = mgt_request( DEV_NETWORK, dev_id, pid, seq, operation, oid, data, length );
+
+                    if ( err < 0 ) {
+                        printk(KERN_INFO "ntl_receive: mgt_request(%d, %d, %d, %x, %d, %x, %d) returned %d\n",
+                               DEV_NETWORK, dev_id, pid, seq, operation, oid, length, err );
+                        netlink_ack(skb, nl_header, -EOPNOTSUPP );
+                    }
+
+                } else {
+                    printk(KERN_ERR "ntl_receive: version (%d) != PIMFOR_VERSION_1\n", version );
+                    netlink_ack(skb, nl_header, -EOPNOTSUPP );
+                }
+            } else {
+                printk(KERN_ERR "nl_header->nlmsg_type (%d) != NETLINK_TYPE_PIMFOR\n", nl_header->nlmsg_type );
+                netlink_ack(skb, nl_header, -EOPNOTSUPP );
+            }
+
+            kfree_skb(skb);
+        }
+        up(&rtnl_sem);
+
+    } while (nl_sock && nl_sock->receive_queue.qlen);
+}
+
+
+/*********************************************************************
+*                        PIMFOR
+*********************************************************************/
+
+/*
+ * PIMFOR (Proprietary Intersil Mechanism For Object Relay). PIMFOR is a simple
+ * request-response protocol used to query and set items of management information
+ * residing in the MVC. It is used to provide an object interface to device firmware.
+ *
+ * PIMFOR is also used for communication between applications and the driver.
+ * For the uAP, PIMFOR is used for communication between the driver and the MVC.
+ *
+ */
+
+
+/**********************************************************************
+ *  pimfor_encode_header
+ *
+ *  DESCRIPTION: XXX
+ *
+ *  PARAMETERS:	 XXX
+ *
+ *  RETURN:	 XXX
+ *
+ **********************************************************************/
+static int pimfor_encode_header(int operation, unsigned long oid, int device_id,
+                                int flags, int length, struct pimfor_hdr *header)
+{
+    //printk(KERN_INFO "pimfor_encode_header: oper %d, oid %d, dev_id %d, flags %d, length %d header ptr %p \n",
+    //                  operation, oid, device_id, flags, length, header);
+
+    if( !header )
+            return -EPFNOSUPPORT;
+
+    memset(header, 0, sizeof(struct pimfor_hdr));
+
+    /* byte oriented members */
+    header->version = PIMFOR_VERSION_1;
+    header->operation = operation;
+    header->device_id = device_id;
+    header->flags = flags;
+
+    /* word oriented members with byte order depending on the flags */
+    if (flags & PIMFOR_FLAG_LITTLE_ENDIAN) {
+            header->oid = cpu_to_le32(oid);
+            header->length = cpu_to_le32(length);
+    } else {
+            header->oid = cpu_to_be32(oid);
+            header->length = cpu_to_be32(length);
+    }
+    return 0;
+}
+
+/**********************************************************************
+ *  pimfor_decode_header
+ *
+ *  DESCRIPTION: XXX
+ *
+ *  PARAMETERS:	 XXX
+ *
+ *  RETURN:	 XXX
+ *
+ **********************************************************************/
+static int pimfor_decode_header(struct pimfor_hdr *header, int *version,
+                                int *operation, unsigned long *oid,
+                                int *device_id, int *flags, unsigned long *length)
+{
+    //printk(KERN_INFO "pimfor_decode_header: header ptr %p, version %d, oper %d, oid %d, device_id %d, flags %d, length %d \n",
+    //                      header, version, operation, oid, device_id, flags, length);
+
+    if(!header)
+            return -EPFNOSUPPORT;
+
+    /* byte oriented members */
+    *version   = header->version;
+    *operation = header->operation;
+    *device_id = header->device_id;
+    *flags = header->flags;
+
+    /* word oriented members with byte order depending on the flags */
+    if (*flags & PIMFOR_FLAG_LITTLE_ENDIAN) {
+            *oid = le32_to_cpu(header->oid);
+            *length = le32_to_cpu(header->length);
+    } else {
+            *oid = be32_to_cpu(header->oid);
+            *length = be32_to_cpu(header->length);
+    }
+
+    return 0;
+}
+
+
+EXPORT_SYMBOL(mgt_initialize);
+EXPORT_SYMBOL(mgt_response);
+EXPORT_SYMBOL(mgt_indication_handler);
diff -urN linux-2.4.29/drivers/net/intersil/isl_mgt.h linux-2.4.29-uc1/drivers/net/intersil/isl_mgt.h
--- linux-2.4.29/drivers/net/intersil/isl_mgt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/isl_mgt.h	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,65 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef _ISL_MGT_H
+#define _ISL_MGT_H
+
+#include <linux/isil_netlink.h>
+
+#define DEV_NETWORK      0                              /* seq of DEV_NETWORK: net_device ifindex */
+
+/* Map dev_type on trapgroup. */
+#define DEV_NETWORK_ETH          TRAPGRP_ETH_TRAPS      /* seq of DEV_NETWORK: net_device ifindex */
+#define DEV_NETWORK_WLAN         TRAPGRP_WLAN_TRAPS     /* seq of DEV_NETWORK: net_device ifindex */
+#define DEV_NETWORK_BLOB         TRAPGRP_BLOBDEV_TRAPS  /* seq of DEV_NETWORK: 0 */
+
+#define USR_NETLINK      1      
+
+typedef int (*mgt_indication_t)(unsigned int dev_type, unsigned int dev_seq, 
+                                unsigned int src_id, unsigned int src_seq, 
+                                unsigned int op, unsigned int oid, void *data, unsigned long len);
+typedef int (*mgt_response_t)(  unsigned int src_id, unsigned int src_seq,
+                                unsigned int dev_type, unsigned int dev_seq, 
+                                unsigned int op, unsigned int oid, void *data, unsigned long len);
+typedef int (*mgt_confirm_t)(   unsigned int src_id, unsigned int src_seq,
+                                unsigned int dev_type, unsigned int dev_seq, 
+                                unsigned int op, unsigned int oid, void *data, unsigned long len);
+
+int mgt_request( unsigned int dev_type, unsigned int dev_seq,              
+                 unsigned int src_id,   unsigned int src_seq,              
+                 unsigned int op, int oid, void *data, unsigned long len);
+int mgt_response( unsigned int src_id, unsigned int src_seq,
+                  unsigned int dev_type, unsigned int dev_seq, 
+                  unsigned int op, int oid, void *data, unsigned long len);
+int mgt_confirm( unsigned int src_id, unsigned int src_seq,
+                  unsigned int dev_type, unsigned int dev_seq, 
+                  unsigned int op, int oid, void *data, unsigned long len);
+
+int mgt_indication_handler( unsigned int dev_type, char *dev_name, 
+                            unsigned int oid, mgt_indication_t ind );
+int mgt_response_handler( unsigned int src_id, char *dev_name, 
+                            unsigned int oid, mgt_response_t resp );
+int mgt_confirm_handler( mgt_confirm_t cnf );
+
+int mgt_initialize( void );
+int mgt_dump_table( void );
+int mgt_cleanup( void );
+
+
+#endif /* _ISL_MGT_H */
diff -urN linux-2.4.29/drivers/net/intersil/islmvc_blob.c linux-2.4.29-uc1/drivers/net/intersil/islmvc_blob.c
--- linux-2.4.29/drivers/net/intersil/islmvc_blob.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islmvc_blob.c	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,392 @@
+/*  $Header$
+ *
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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 <linux/config.h>
+#include <linux/version.h>
+#include <linux/tty.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <asm/arch/blobcalls.h>
+#ifdef CONFIG_MVC_DEBUG_CONSOLE
+#include <linux/console.h>
+#endif
+#include "islmvc.h"
+#include "isl_mgt.h"
+extern unsigned int src_seq;
+
+#ifdef BLOB_V2
+#include <linux/timer.h>
+#include <linux_mvc_oids.h>
+static struct timer_list timer; /* For the reset button state polling loop. */
+#endif BLOB_V2
+
+/*
+ * The trap handling mechanism is different for BLOB V1 and BLOB V2.
+ *
+ */
+#ifdef BLOB_V2
+static inline void req_trap_handling(void)
+{
+    struct msg_conf     trapmsg;
+    struct obj_mlme     data_buf;
+
+    long                *new_buf = NULL;
+
+    /* Most traps are the size of an obj_mlme struct or less. If this does not fit the trap size
+       requirement, we are told so and will malloc a new buffer for the trap data. */
+    trapmsg.data = (long*)&data_buf;
+    trapmsg.size = sizeof(data_buf);
+
+    /* Get the trap from the MVC... */
+    if (blob_trap (&trapmsg) == BER_OVERFLOW)
+    {
+        /* The size of the buffer we passed was too small. Malloc a new buffer with correct size. */
+        if ((new_buf = kmalloc(trapmsg.size, GFP_ATOMIC)) == NULL)
+        {
+            printk(KERN_ERR "Couldn't malloc new trap buffer. \n");
+            return;
+        }
+
+        trapmsg.data = new_buf;
+        /* Okay, try again... */
+        if (blob_trap (&trapmsg) == BER_OVERFLOW)
+        {
+            printk(KERN_WARNING "Couldn't get trap message for the second time. Stopped trying... \n");
+            return;
+        }
+    }
+
+    mgt_response( 0, src_seq++, DEV_NETWORK_BLOB, BLOB_IFINDEX,
+       PIMFOR_OP_TRAP, trapmsg.oid, trapmsg.data, trapmsg.size);
+
+    /* When we malloced a new buffer, free it here. */
+    if (new_buf)
+        kfree(new_buf);
+
+}
+#else /* BLOB_V2 */
+static inline void req_trap_handling(void)
+{
+    struct msg_conf *trapmsg = blob_trap( );
+
+    if( trapmsg != NULL ) {
+        /* Since there is no size parameter in MVC v1 we use 100 for the length
+         * of the trap msg. This should be big enough to hold all trap msgs. */
+        mgt_response( 0, src_seq++, DEV_NETWORK_BLOB, BLOB_IFINDEX,
+            PIMFOR_OP_TRAP, trapmsg->oid, trapmsg->data, 100 );
+    }
+}
+#endif /* BLOB_V2 */
+
+/**********************************************************************
+ *  handle_blob_reqs
+ *
+ *  DESCRIPTION: Handle requests for device blob. These requests are
+ *		 handles within the Ethernet device. Therefore, traps
+ *		 for the blob device should be added to the Ethernet device.
+ *
+ *  PARAMETERS:	 NONE
+ *
+ *  RETURN:	 NONE
+ *
+ *  NOTE:	 Called from the interrupt service routine.
+ *
+ **********************************************************************/
+void handle_blob_reqs(void)
+{
+    int requests;
+
+    requests = blob_reqs();
+
+    if (!requests)
+    return;
+
+    if (requests & 0xFFFFEFE0) {
+        printk (" called with unknown requests: %d!!\n", requests);
+        return;
+    }
+
+    if (requests & REQTRAP)
+    {
+        req_trap_handling();
+    }
+
+    if (requests & REQWATCHDOG)
+    {
+        /* Lets trigger the blob watchdog service, for the BLOB device */
+        blob_watchdog();
+    }
+}
+
+
+
+/*
+ * ------------------------------------------------------------
+ * console driver
+ * ------------------------------------------------------------
+ */
+static int debugdev_enabled = 0;
+
+#ifdef CONFIG_MVC_DEBUG_CONSOLE
+
+static struct console mvc_dbg_cons;
+
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ *
+ *	The console_lock must be held when we get here.
+ */
+static void mvc_debug_console_write(struct console *co, const char *s,
+				unsigned count)
+{
+    struct msg_data debug_msg;
+
+    debug_msg.data = "<printk> ";
+    debug_msg.length = strlen(debug_msg.data);
+    debug_msg.max = 0;
+    dev_write(DEVICE_DEBUG, &debug_msg);
+
+    debug_msg.data = (unsigned char *)s;
+    debug_msg.length = count;
+    dev_write(DEVICE_DEBUG, &debug_msg);
+}
+
+static kdev_t mvc_debug_console_device(struct console *c)
+{
+    return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+/*
+ *	Setup initial baud/bits/parity/flow control. We do two things here:
+ *	- construct a cflag setting for the first rs_open()
+ *	- initialize the serial port
+ *	Return non-zero if we didn't find a serial port.
+ */
+static int __init mvc_debug_console_setup(struct console *co, char *options)
+{
+
+#ifdef BLOB_V2
+    struct msg_start start;
+#endif
+
+    int ret = -1;
+
+    if(!debugdev_enabled) {
+        /* start the MVC debug interface */
+
+#ifdef BLOB_V2
+        start.nr    = DEVICE_DEBUG;
+        start.mode  = MODE_NONE;
+
+        if(dev_start(DEVICE_DEBUG, &start) < BER_NONE)
+            goto out;
+#else
+        if(dev_start(DEVICE_DEBUG, 0) < BER_NONE)
+            goto out;
+#endif /* BLOB_V2 */
+
+        if(dev_run(DEVICE_DEBUG) < BER_NONE) {
+            dev_stop(DEVICE_DEBUG);
+            goto out;
+        }
+    }
+
+    co->cflag = CREAD | HUPCL | CLOCAL | B115200;
+    debugdev_enabled = 1;
+    ret = 0;
+out:
+    return ret;
+}
+
+static struct console mvc_dbg_cons = {
+    name:	"mvcdbg",
+    write:	mvc_debug_console_write,
+    device:	mvc_debug_console_device,
+    setup:	mvc_debug_console_setup,
+    flags:	CON_PRINTBUFFER,
+    index:	-1,
+};
+
+/*
+ *	Register console.
+ */
+void __init mvc_debug_console_init(void)
+{
+    register_console(&mvc_dbg_cons);
+}
+#endif
+
+
+/**********************************************************************
+ *  reset_button_state_timer
+ *
+ *  DESCRIPTION: The state of the reset button is checked here. If the
+ *               button is pressed, a trap is sent. A second trap is sent
+ *               when the button is released again.
+ *
+ *  PARAMETERS:	 Data, this holds the previous state of the reset button.
+ *
+ *  NOTE:        This code is ISL3893 specific.
+ *
+ **********************************************************************/
+#ifdef BLOB_V2
+static void reset_button_state_timer(unsigned long data)
+{
+    struct msg_conf msg;
+
+    long bank = 1;
+
+    msg.operation = OPSET;
+    msg.oid       = BLOB_OID_GPIOBANK;
+    msg.data      = &bank; /* GP Bank 1 */
+    msg.size      = sizeof(long);
+
+    /* Set the GPIO bank for the reset button */
+    if (blob_conf (&msg) < 0)
+        goto schedule;
+
+    msg.operation = OPGET;
+    msg.oid       = BLOB_OID_GPIOSTATUS;
+
+    /* Get the current status of the reset button */
+    if (blob_conf (&msg) < 0)
+        goto schedule;
+
+    if (!(*msg.data & 0x8000)) /* Button pressed */
+    {
+        if (timer.data) /* Button still pressed */
+            goto schedule;
+        else /* Button pressed for first time, send trap. */
+        {
+            timer.data = 1;
+            mgt_response( 0, src_seq++, DEV_NETWORK_BLOB, BLOB_IFINDEX,
+                          PIMFOR_OP_TRAP, GEN_OID_BUTTONSTATE, &timer.data, sizeof(long) );
+            goto schedule;
+        }
+    }
+
+    if (timer.data) /* Button released */
+    {
+        timer.data = 0;
+        /* Send the trap up... */
+        mgt_response( 0, src_seq++, DEV_NETWORK_BLOB, BLOB_IFINDEX,
+                      PIMFOR_OP_TRAP, GEN_OID_BUTTONSTATE, &timer.data, sizeof(long) );
+    }
+
+    /* Schedule this poll again... */
+schedule:
+    timer.expires = jiffies + 0,1*HZ; /* Every 100 ms */
+    add_timer(&timer);
+
+}
+#endif /* BLOB_V2 */
+
+
+/*
+ * Startup and exit functions
+ */
+static int __init prism_blobdrv_init(void)
+{
+    int ret = -ENODEV;
+
+#ifdef BLOB_V2
+    struct msg_start start;
+    struct msg_conf msg;
+    long watchdog = 0;
+#endif
+
+#ifdef CONFIG_MVC_DEBUG
+	/* Configure the MVC debug interface. */
+/* Is this needed?
+#ifdef BLOB_V2
+    struct msg_setup setup;
+
+    setup.rx_buf = NULL; // Use the MVC internal buffers
+    setup.tx_buf = NULL;
+
+    setup.rx_buf_size = 100;
+    setup.tx_buf_size = 100;
+
+    if (dev_setup(DEVICE_DEBUG, &setup) < BER_NONE)
+        goto out;
+#endif  // BLOB_V2
+*/
+
+    /* start the MVC debug interface */
+#ifdef BLOB_V2
+    start.nr    = DEVICE_DEBUG;
+    start.mode  = MODE_NONE;
+
+    if(dev_start(DEVICE_DEBUG, &start) < BER_NONE)
+            goto out;
+#else
+    if(dev_start(DEVICE_DEBUG, 0) < BER_NONE)
+            goto out;
+#endif /* BLOB_V2 */
+
+    if(dev_run(DEVICE_DEBUG) < BER_NONE) {
+            dev_stop(DEVICE_DEBUG);
+            goto out;
+    }
+
+    /* Schedule timer for checking the reset button status. */
+#ifdef BLOB_V2
+    init_timer(&timer);
+    timer.expires   = jiffies + 0,1*HZ; /* Every 100 ms */
+    timer.data      = 0; /* Initial state of the reset button. */
+    timer.function  = &reset_button_state_timer;	/* timer handler */
+    add_timer(&timer);
+#endif /* BLOB_V2 */
+
+    debugdev_enabled = 1;
+
+#ifdef BLOB_V2
+    msg.operation = OPSET;
+    msg.oid       = GEN_OID_WATCHDOG;
+    msg.data      = &watchdog;
+    msg.size      = sizeof(long);
+    /* Set the WATCHDOG on for the blob device */
+    blob_conf (&msg);
+#endif
+    ret = 0;
+out:
+#endif
+    return ret;
+}
+
+static void __exit prism_blobdrv_exit(void)
+{
+#ifdef CONFIG_MVC_DEBUG
+    debugdev_enabled = 0;
+
+    dev_halt(DEVICE_DEBUG);
+    dev_stop(DEVICE_DEBUG);
+#ifdef BLOB_V2
+    del_timer(&timer);
+#endif
+
+#endif
+}
+
+
+EXPORT_NO_SYMBOLS;
+
+module_init(prism_blobdrv_init);
+module_exit(prism_blobdrv_exit);
diff -urN linux-2.4.29/drivers/net/intersil/islmvc_dev.c linux-2.4.29-uc1/drivers/net/intersil/islmvc_dev.c
--- linux-2.4.29/drivers/net/intersil/islmvc_dev.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islmvc_dev.c	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,2724 @@
+/*  $Header$
+ *
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+/*
+ *  Intersil Ethernet driver for MVC v2.
+ *
+ *  Based on skeleton ethernet driver by Donald Becker.
+ *  Based on previous prism ethernet driver by M Schipper 2001.
+ *
+ *  Extended by WSM, Intersil 2002-2003.
+ *
+ *  Copyright 1993 United States Government as represented by the
+ *  Director, National Security Agency.
+ *  Copyright (C) 2001-2003 Intersil Americas Inc.
+ */
+
+
+/* Include files */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <asm/irq.h>
+#include <asm/arch/intctl.h> /* for uIRQ */
+
+/* Intersil include files */
+#include <linux_mvc_oids.h>
+#include <asm/arch/blobcalls.h>
+#include "islmvc.h"
+#include "isl_mgt.h"
+#include "islmvc_mgt.h"
+#include "isl_wds.h"
+
+#ifdef TEST_ON_POLDHU
+#include <asm/arch/serial.h>
+#include <asm/arch/gpio.h>
+#endif /* TEST_ON_POLDHU */
+
+/* End of include files */
+
+/* DEFINES */
+
+#define REQ_UNKNOWN (REQFRAMERX & REQFRAMERETURN & REQTRAP & REQFRAMEADD & REQSERVICE)
+
+/* STATES */
+#define PRISM_ETH_STOP  0
+#define PRISM_ETH_HALT  1
+#define PRISM_ETH_START 2
+#define PRISM_ETH_RUN   3
+
+/* defines for cache mask */
+#ifdef TEST_ON_POLDHU
+#define PRISM_CACHE_MASK 0x04000000
+#endif /* TEST_ON_POLDHU */
+
+/* DEFINES */
+/* Number of TX retries */
+#define TX_NR_RETRIES	10
+
+/* Offset in RAM between cache-able and non-cache-able RAM
+   point to the same physical RAM location. */
+#ifdef TEST_ON_POLDHU
+#define MAP_CACHED(data)   (data |  PRISM_CACHE_MASK)
+#define MAP_UNCACHED(data) (data &=  ~PRISM_CACHE_MASK)
+#endif /* TEST_ON_POLDHU */
+
+static const char *version = "version 0.4.0.0";
+/* The name of the card. Is used for messages and in the requests for irqs */
+static const char* cardname = "Prism Embedded MVC v2 packet IF";
+
+/* Static variable to indicate if a frame add failed. */
+static int frame_add_failed = 0;
+
+/* End of defines */
+
+/* Probe function is called from Space.c */
+int prism_mvc_probe(struct net_device *dev);
+
+#ifdef TEST_ON_POLDHU
+extern const unsigned char *blobtool_find_element(int id, int skip);
+#endif
+
+extern unsigned int src_seq;
+
+/* Start of local mvc prototypes */
+static int prism_eth_init(struct net_device *dev, int startp);
+static int prism_eth_start ( struct net_device *dev );
+static int prism_eth_run ( struct net_device *dev );
+static int local_net_open(struct net_device *dev);
+static void local_net_tx_timeout(struct net_device *dev);
+static int local_net_send_packet(struct sk_buff *skb, struct net_device *dev);
+static void local_net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static int local_net_close(struct net_device *dev);
+static inline void local_dev_handle_reqs(struct net_device *dev, int requests);
+
+/* Start of frame prototypes */
+static int  alloc_frame_pool(struct net_local *lp);
+static inline void req_frame_rx(struct net_device *dev);
+static inline void req_frame_return(struct net_device *dev);
+static inline void req_trap_handling(struct net_device *dev);
+static inline void req_frame_add(struct net_device *dev);
+static inline void req_service(struct net_device *dev);
+inline void copy_wds_to_frame(msg_frame *framep, unsigned char *WDS_Mac);
+static struct msg_frame *skb_to_frame (struct sk_buff *skb);
+static struct sk_buff *frame_to_skb (struct msg_frame *framep);
+static struct sk_buff *dev_copy_expand_skb (struct net_device *dev, const struct sk_buff *skb);
+static inline struct msg_frame *dev_alloc_frame (struct net_device *dev, int size);
+static inline void dev_free_frame (struct net_device *dev, struct msg_frame *frame);
+
+#ifdef BLOB_V2
+static int llc_to_wlan (struct sk_buff *skb);
+static int wlan_to_llc (struct sk_buff *skb);
+#endif
+
+/* Management prototypes */
+static int local_set_mac_addr(struct net_device *dev, void *addr);
+static struct net_device_stats *local_net_get_stats(struct net_device *dev);
+
+/* Begin of debug function prototypes */
+#if (NET_DEBUG & DBG_SKB)
+static int  dbg_frame_filter_check (struct net_device *dev, struct msg_frame *framep);
+static void dbg_dump_hex_assci (unsigned char *buf, int size);
+static int  dbg_check_area (unsigned char *p, int size, char *area_name);
+#endif
+
+#if (NET_DEBUG & (DBG_TX | DBG_RX | DBG_ERROR))
+static void dbg_print_frame (struct msg_frame *framep);
+#endif
+
+#if (NET_DEBUG & DBG_FRAME_SANITY)
+static void check_frame_skb(struct msg_frame *framep, char *file, int line);
+#endif
+
+/* FIXME, temp here for character driver... */
+extern void handle_blob_reqs(void);
+
+static int islmvc_initialized = 0;
+
+/****************************************************************
+ *								*
+ *    		    Begin of functions		                *
+ *								*
+ ***************************************************************/
+
+
+/****************************************************************
+ *								*
+ *    		Begin of driver configurator functions		*
+ *								*
+ ***************************************************************/
+
+
+/**********************************************************************
+ *  prism_mvc_probe
+ *
+ *  DESCRIPTION: Loops through the MVC Information structure trying to find
+ *               the interface that is encoded into the device base_addr.
+ *               The number in the base_addr is mapped to an MVC interface.
+ *               When the device is found, the device structure is initialized,
+ *               the MAC address is read from the PDA and set, the device functions
+ *               are set, the management handlers get initialized and the device
+ *               is put into the READY state.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 0       - when the device is found, initialized and started correctly.
+ *               -ENOMEM - when no memory could be allocated for the device.
+ *               -ENODEV - when the MVC information structure could not be found;
+ *                         when the device is not available;
+ *                         when the MAC address could not be found,
+ *               -EBUSY    when the device could not be started into the READY state.
+ *
+ *  NOTE:        Called from Space.c
+ *
+ **********************************************************************/
+int prism_mvc_probe(struct net_device *dev)
+{
+    int    nr_mvc_devices;  /* Nr of devices present on the MVC. */
+    unsigned char *mac_address;
+
+    char type;
+    int i;
+
+    struct bis_dev_element *dev_elem = NULL;
+    struct bis_dev_descr_element *dev_desc = NULL;
+    struct net_local *lp = NULL;
+    int dev_found = FALSE;
+    static int dev_first_802_3_found = 0;
+
+    islmvc_initialized = 0;
+
+    DEBUG((DBG_FUNC_CALL | DBG_OPEN), "prism_mvc_probe, dev %p, dev->base_addr = %lu \n", dev, dev->base_addr);
+
+    /*
+       We have the following (static) mapping for the devices. This mapping ensures
+       that the devices get the same device name, even when another device isn't available.
+
+       eth0 - LAN ethernet interface. (1)
+       eth1 - WLAN interface. (2)
+       eth2 - WAN ethernet interface. This interface is a hardware option. (3)
+
+       We know for which device this probe function is called because the dev->base_addr
+       is filled in Space.c with the corresponding number.
+    */
+    if (dev->base_addr == 1)      /* Probe for the LAN interface */
+        type = BIS_DT_802DOT3;
+    else if (dev->base_addr == 2) /* Probe for the WLAN interface */
+        type = BIS_DT_802DOT11;
+#if 0
+    else if (dev->base_addr == 3)
+        type = BIS_DT_802DOT3;
+#endif
+    else
+        return -ENODEV;
+
+    /* Allocate a new 'dev' if needed. */
+    if (dev == NULL)
+    {
+	/*
+	 * Don't allocate the private data here, it is done later
+	 * This makes it easier to free the memory when this driver
+	 * is used as a module.
+	 */
+	dev = init_etherdev(0,0);
+	if (dev == NULL)
+	    return -ENOMEM;
+    }
+
+    /* Get the number of devices available in the MVC. */
+    dev_elem = (struct bis_dev_element *) blobtool_find_element(BIS_DEVS, 0);
+
+    if (!dev_elem)
+    {
+        printk(KERN_ALERT "No dev_element found!!!");
+        return -ENODEV;
+    }
+
+#ifdef BLOB_V2
+    nr_mvc_devices = dev_elem->devs; /* MVC v2 */
+#else
+    nr_mvc_devices = dev_elem->dev;  /* MVC v1 */
+#endif /* TEST_ON_POLDHU */
+
+    DEBUG(DBG_OPEN, "Nr of MVC devices = %i \n", nr_mvc_devices);
+
+    /* Loop through the list and find the types of devices available... */
+    for (i = 0; i < nr_mvc_devices && !dev_found; i++)
+    {
+        dev_desc = (struct bis_dev_descr_element *) blobtool_find_element (BIS_DEVDESCR, i);
+
+        if (!dev_desc)
+        {
+            printk(KERN_ALERT "No dev_desc found!!!");
+            return -ENODEV;
+        }
+
+        /* Let's find out if the MVC accomodates this type... */
+        if (dev_desc->type == type)
+        {
+            /* For the WAN interface, we need the second device, so skip this device when we find the first... */
+            if (dev->base_addr == 1) {
+                dev_first_802_3_found = i;
+            } else if (dev->base_addr == 3 && dev_first_802_3_found == i) {
+                continue;
+            }
+
+            /* The MVC has a device with the right type for us... */
+            DEBUG(DBG_OPEN, "Found MVC device with type nr %i to use for %s \n", i, dev->name);
+
+            /* We (ab) use the base_addr field for storing the device number and device type for later reference. */
+
+            ADD_DEV_TYPE(dev->base_addr, type);
+            ADD_DEV_NR(dev->base_addr, i);
+
+            /* Initialize the device structure. */
+            if (dev->priv == NULL)
+            {
+            	dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+            	if (dev->priv == NULL)
+            	    return -ENOMEM;
+            }
+            memset(dev->priv, 0, sizeof(struct net_local));
+            lp = (struct net_local *)dev->priv;
+
+            lp->wdsp = kmalloc(sizeof(struct wds_priv), GFP_KERNEL);
+            if ( lp->wdsp == NULL)
+                return -ENOMEM;
+            memset(lp->wdsp, 0, sizeof(struct wds_priv));
+
+            /* Set max mtu, head and tail sizes for this MVC packet device */
+#ifdef BLOB_V2
+            lp->maxhead  = (dev_elem->header + 63) & ~3; // extra headspace for zero copy to mini PCI
+            lp->maxtail  = dev_elem->trailer;
+            lp->maxmtu   = dev_elem->mtu;
+
+            lp->maxnrframes = 200; /* FIXME, this should be part of MVC device descr
+            			    * changed to 200 queues in mvc bigger.
+            			    */
+            lp->dev_elem = dev_elem;
+
+            printk( "dev_elem, type %d, mtu %d, head %d, tail %d\n",
+		            dev_desc->type, lp->dev_elem->mtu,
+		            lp->dev_elem->header, lp->dev_elem->trailer);
+#else
+            lp->maxhead  = (dev_desc->header + 63) & ~3; // extra headspace for zero copy to mini PCI
+            lp->maxtail  = dev_desc->trailer;
+            lp->maxmtu   = dev_desc->mtu;
+
+            lp->maxnrframes = 100; /* FIXME, this should be part of MVC device descr */
+            lp->dev_desc = dev_desc;
+
+            printk( "dev_descr, nr %d, type %d, mtu %d, head %d, tail %d\n",
+		            lp->dev_desc->nr, lp->dev_desc->type, lp->dev_desc->mtu,
+		            lp->dev_desc->header, lp->dev_desc->trailer);
+#endif /* BLOB_V2 */
+
+            dev_found = TRUE;
+        }
+    }
+
+    if (!dev_found)
+    {
+        printk("Couldn't find an MVC device type (%ld) for %s \n", dev->base_addr, dev->name);
+        return -ENODEV;
+    }
+    else
+        printk(KERN_INFO "%s: %s %s found,", dev->name, cardname, version );
+
+    /* For both ethernet interfaces (LAN & WAN) and the onboard radio the same MAC address is used.
+       The MAC address of the WAN interface can be changed later to a different MAC address
+       to support MAC cloning for the WAN interface. */
+
+    /* Get the MAC address from the PDA. Function returns pointer to MACAddress. */
+    mac_address = pda_get_mac_address();
+
+    if (mac_address == NULL) /* If we couldn't get the MAC address from the PDA, exit... */
+    {
+        printk(KERN_ERR "Couldn't get MAC address for %s from PDA... aborting... \n", dev->name);
+        kfree(lp);
+        return -ENODEV;
+    }
+
+    memcpy(dev->dev_addr, mac_address, ETH_ALEN);
+    printk("Macaddress = %s\n", hwaddr2string(mac_address));
+
+    dev->open		    = local_net_open;
+    dev->stop		    = local_net_close;
+    dev->get_stats	    = local_net_get_stats;
+    dev->hard_start_xmit    = local_net_send_packet;
+    dev->irq                = IRQ_SOFINT;
+#ifdef HAVE_TX_TIMEOUT
+    dev->tx_timeout	    = local_net_tx_timeout;
+    dev->watchdog_timeo	    = 5 * HZ;
+#endif
+#ifdef HAVE_SET_MAC_ADDR
+    dev->set_mac_address    = local_set_mac_addr;
+#endif
+
+    /* Allocate the frame pool */
+    if (alloc_frame_pool(lp) < 0)
+    {
+        kfree(lp);
+        return -ENOMEM;
+    }
+
+    /* Fill in the fields of the device structure with ethernet values. */
+    ether_setup(dev);
+
+    /* Initialize the management handlers */
+    islmvc_mgt_init(dev);
+
+    /* Let's bring the device in the READY state */
+    if (prism_eth_init( dev, PRISM_ETH_START) < 0 )
+    {
+        kfree(lp);
+        printk(KERN_ERR "Couldn't start device %s \n", dev->name);
+        return -EBUSY;
+    }
+
+    return 0;
+}
+
+
+/**********************************************************************
+ *  prism_eth_init
+ *
+ *  DESCRIPTION: Initialise the MVC device to a specific state.
+ *
+ *  PARAMETERS:	 dev    - pointer to a linux net device struct.
+ * 		 startp - the operation to perform on the MVC
+ *
+ *  RETURN:	 0       - when the device is properly initialized.
+ *               -EBUSY  - when the device is not in the state it should
+ *                         be in, in order to change to the desired state.
+ *               -EINVAL - when the state or device type is not known;
+ *                       - when changing the state did not succeed.
+ *
+ *  NOTE:	 Depending on the current state some values should
+ * 		 possibly be reinitialised in the MVC.
+ *
+ **********************************************************************/
+static int prism_eth_init( struct net_device *dev, int startp )
+{
+    long state;
+#ifdef BLOB_V2
+    struct msg_start start;
+#endif
+
+    long dev_nr = GET_DEV_NR(dev->base_addr);
+    long type   = GET_DEV_TYPE(dev->base_addr);
+    int error   = 0;
+
+    DEBUG(DBG_FUNC_CALL | DBG_OPEN, "prism_eth_init, dev %s, startp %d, (dev_nr = %ld) \n", dev->name, startp, dev_nr);
+
+    state = dev_state (dev_nr);
+    DEBUG(DBG_OPEN, "dev_state, %ld...", state);
+
+    switch (startp)
+    {
+	case PRISM_ETH_STOP:  /* MVC State will end up being STSTOPPED */
+	    /*
+	     * In this case state doesn't really matter,
+	     * if not already stopped stop now!
+	     */
+	    if(state != STSTOPPED)
+	    {
+		DEBUG(DBG_OPEN, "dev_stop...");
+		error = dev_stop (dev_nr);
+	    }
+	break;
+	case PRISM_ETH_HALT:  /* MVC State will end up being STREADY */
+	    /*
+	     * Man can only HALT a device if it's RUNNING.
+	     */
+	    if(state == STRUNNING)
+	    {
+		DEBUG(DBG_OPEN, "dev_halt...");
+		error = dev_halt (dev_nr);
+	    }
+	    else
+	    {
+		error = -EBUSY;
+	    }
+	break;
+	case PRISM_ETH_START: /* MVC State will end up being STREADY */
+	    /*
+	     * Man can only START a device if it's STOPPED.
+             * When it's started for the first time, the state is == BER_UNSUP.
+	     */
+	    if(state == STSTOPPED || state == BER_UNSUP)
+	    {
+            DEBUG(DBG_OPEN, "dev_start...");
+
+#ifdef BLOB_V2
+            /* We can tell the MVC what device number we want to use. Use the one we figured out during the probe... */
+            start.nr    = dev_nr;
+
+            /* Determine the mode to start the device depending on it's type. */
+            if (type == BIS_DT_802DOT11) {
+                //start.mode  = MODE_AP;
+                start.mode = MODE_CLIENT;
+                
+                
+            }
+            else if (type == BIS_DT_802DOT3) {
+                start.mode  = MODE_PROMISCUOUS;
+            }
+            else {
+                printk(KERN_ERR "Unknown device type in prism_eth_init.\n");
+                return -EINVAL;
+            }
+
+            error = dev_start(dev_nr, &start);
+#else
+            error = dev_start(dev_nr, MODE_PROMISCUOUS);
+#endif /* BLOB_V2 */
+
+            if (error == BER_NONE)
+                error = prism_eth_start ( dev );
+	    }
+	    else
+	    {
+		DEBUG(DBG_OPEN, "state != STOPPED\n");
+                error = -EBUSY;
+	    }
+	break;
+	case PRISM_ETH_RUN:   /* MVC State will end up being RUNNING */
+	    /*
+	     * Man can only RUN a device if it's READY to run.
+	     */
+	    if(state == STREADY)
+	    {
+		DEBUG(DBG_OPEN, "dev_run...");
+		error = prism_eth_run ( dev );
+		if (error == 0)
+   	            error = dev_run (dev_nr);
+	    }
+	    else
+	    {
+		error = -EBUSY;
+	    }
+	break;
+        default:
+	    error = -EINVAL;
+    }
+    if (error != 0)
+    {
+        DEBUG((DBG_OPEN | DBG_ERROR), "error %d\n", error);
+        return -EINVAL;
+    }
+
+#if (NET_DEBUG & DBG_OPEN)
+    else
+    {
+	state = dev_state (dev_nr);
+	printk ("dev_state changed to %ld...\n", state);
+    }
+#endif
+
+    return 0;
+}
+
+/**********************************************************************
+ *  prism_eth_start
+ *
+ *  DESCRIPTION: This starts the device. It performs the following operations:
+ *                  Sets the device MAC address on the MVC.
+ *                  For a WLAN device, the MLME autonomy mode is set,
+ *                  and some calibration setting are taken from the PDA
+ *                  (Production Data Area) and send to the MVC.
+ *                  The device requests are handled.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 0       - when starting the device succeeded.
+ *               -EINVAL - when setting a setting failed.
+ *
+ **********************************************************************/
+static int prism_eth_start ( struct net_device *dev )
+{
+    int requests;
+    long mode;
+    int error;
+    int i;
+    struct obj_scan scan;	
+    
+    DEBUG(DBG_FUNC_CALL | DBG_OPEN, "prism_eth_start, dev->name %s\n", dev->name);
+
+    /* set the MAC address */
+    if (islmvc_send_mvc_msg(dev, OPSET, GEN_OID_MACADDRESS, (long*)dev->dev_addr, ETH_ALEN) < BER_NONE)
+        return -EINVAL;
+
+    DEBUG(DBG_OPEN, "MAC set..");
+
+    /* for the WLAN device, set the MLME mode (and calibration settings for MVC v2.) */
+    if (GET_DEV_TYPE(dev->base_addr) == BIS_DT_802DOT11)
+    {
+#ifdef BLOB_V2
+        /* Send some calibration values from the PDA to the MVC for MVC v2. */
+        set_rssi_linear_approximation_db(dev);
+        set_zif_tx_iq_calibr_data(dev);
+        set_hw_interface_variant(dev);
+        //set_calibration_data(dev);
+        	
+	printk("\n\n\t\t DUETTE APDK CLIENT MODE \n\n");
+		
+	/* Enable active scanning for every frequency in the scan structure. */
+	if ((error = islmvc_send_mvc_msg(dev, OPGET, DOT11_OID_SCAN, (long*)&scan, sizeof(struct obj_scan))) < 0)
+	     return -EINVAL;
+	
+	for (i = 0; i < scan.nr; i++) {
+	     scan.mhz[i] |= 0x8000;
+	}
+	scan.sweep = 0;
+	
+	if ((error = islmvc_send_mvc_msg(dev, OPSET, DOT11_OID_SCAN, (long*)&scan, sizeof(struct obj_scan))) < 0)
+	     return -EINVAL;
+	       
+	//FIXME, what mode to use for CLIENT MODE?
+	//mode = DOT11_MLME_INTERMEDIATE;
+	mode = DOT11_MLME_AUTO;
+#else
+        mode = DOT11_MLME_SIMPLE;
+#endif
+        if ((error = islmvc_send_mvc_msg(dev, OPSET, DOT11_OID_MLMEAUTOLEVEL, &mode, sizeof(long))) < 0)
+            return -EINVAL;
+
+  	DEBUG(DBG_OPEN, "MLME mode set..");
+
+    }
+
+    /* handle all device requests (= add frames) */
+    while ((requests = dev_reqs (GET_DEV_NR(dev->base_addr))) > BER_NONE)
+    {
+	local_dev_handle_reqs (dev, requests);
+    }
+    DEBUG(DBG_OPEN, "requests handled..\n");
+
+    return 0;
+}
+
+
+/**********************************************************************
+ *  prism_eth_run
+ *
+ *  DESCRIPTION: Empty function.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 0
+ *
+ **********************************************************************/
+static int prism_eth_run ( struct net_device *dev )
+{
+    DEBUG(DBG_FUNC_CALL | DBG_OPEN, "prism_eth_run, dev %s \n", dev->name);
+
+#if (defined(TEST_ON_POLDHU) && !defined(CONFIG_FREE_WLAN_PINS))
+    /* if we are starting the WLAN device, then... */
+    if (GET_DEV_TYPE(dev->base_addr) == BIS_DT_802DOT11)
+    {
+	/* don't disable the UART completely, this crashes the system ?! */
+	uUART->CR &= ~0x78;	/* disable UART interrupts */
+	/* make the UART pins free for the radio */
+	uGPIO->FSEL = (GPIOFSELUARTTx | GPIOFSELUARTRx) << 16;
+    }
+#endif /* TEST_ON_POLDHU && CONFIG_FREE_WLAN_PINS */
+
+    return 0;
+}
+
+#define MAX_DEVICES 16
+
+struct mvc_irq_table
+{
+    int num_devs;
+    struct net_device *dev_ptr[MAX_DEVICES];
+    int dev_nr[MAX_DEVICES];
+};
+
+
+/**********************************************************************
+ *  register_mvc_irq
+ *
+ *  DESCRIPTION: This registers the device to the internal device list.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 pointer to the irq table on success.
+ *               NULL when unable to register the device.
+ *
+ **********************************************************************/
+struct mvc_irq_table *register_mvc_irq(struct net_device *dev)
+{
+    unsigned long flags;
+
+    struct net_local *lp = (struct net_local *) dev->priv;
+
+    static struct mvc_irq_table stat_irq_table =
+        { 0, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } };
+
+    DEBUG(DBG_FUNC_CALL | DBG_OPEN, "register_mvc_irq %s\n", dev->name);
+
+    if (dev == NULL)
+        return NULL;
+
+    if (stat_irq_table.num_devs >= MAX_DEVICES)
+        return NULL;
+
+    save_flags_cli (flags);
+
+    stat_irq_table.dev_ptr[stat_irq_table.num_devs] = dev;
+    stat_irq_table.dev_nr[stat_irq_table.num_devs] = GET_DEV_NR(dev->base_addr);
+    stat_irq_table.num_devs++;
+
+    restore_flags(flags);
+
+    lp->mvcirq_table = &stat_irq_table;
+
+    return &stat_irq_table;
+
+}
+
+
+/**********************************************************************
+ *  unregister_mvc_irq
+ *
+ *  DESCRIPTION:  This unregisters the device from the internal device
+ *                list.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 0      - on success,
+ *               -1     - when unable to unregister the device.
+ *
+ **********************************************************************/
+int unregister_mvc_irq(struct net_device *dev)
+{
+    int i;
+    unsigned long flags;
+
+    int j = 0;
+    struct net_local *lp = (struct net_local *) dev->priv;
+
+    DEBUG(DBG_FUNC_CALL | DBG_OPEN, "unregister_mvc_irq %s\n", dev->name);
+
+    if (dev == NULL) {
+        printk("unregister_mvc_irq: dev == NULL, can't unregister.\n");
+        return -1;
+    }
+
+    save_flags_cli (flags);
+
+    for (i=0; i < MAX_DEVICES; i++) {
+        if (lp->mvcirq_table->dev_ptr[i] == dev) {
+            j++;
+        }
+
+        lp->mvcirq_table->dev_ptr[i] = lp->mvcirq_table->dev_ptr[j];
+        lp->mvcirq_table->dev_nr[i] = lp->mvcirq_table->dev_nr[j];
+        j++;
+    }
+
+    lp->mvcirq_table->num_devs--;
+
+    restore_flags(flags);
+
+    return 0;
+}
+
+
+
+/**********************************************************************
+ *  local_net_open
+ *
+ *  DESCRIPTION:  Open/initialize the board. This is called (in the current kernel)
+ *                sometime after booting when the 'ifconfig' program is run.
+ *                This routine should set everything up anew at each open, even
+ *                registers that "should" only need to be set once at boot, so that
+ *                there is non-reboot way to recover if something goes wrong.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 0      - on success,
+ *               -EBUSY - when unable to get IRQ or setting the device into
+ *                        running mode.
+ *
+ **********************************************************************/
+
+
+static int local_net_open(struct net_device *dev)
+{
+    long linkstate;
+
+    int retval = 0;
+
+#ifdef BLOB_V2
+    struct mvc_irq_table *irq_table = NULL;
+#endif
+
+    DEBUG(DBG_FUNC_CALL | DBG_OPEN, "local_net_open %s\n", dev->name);
+
+    /* Reset the hardware and set the card MAC address. */
+    if (prism_eth_init(dev, PRISM_ETH_RUN) < 0)
+    {
+        printk("Couldn't reset hardware \n");
+        return -EBUSY;
+    }
+
+    netif_start_queue (dev);
+
+#ifdef BLOB_V2
+    /* Register the IRQ in the mvc irq table. */
+    if ((irq_table = register_mvc_irq(dev)) == NULL) {
+        printk(KERN_ERR "Registering the IRQ in the internal table failed.\n");
+        return -EBUSY;
+    }
+
+    /* Dispatching the IRQ for the different devices is done in the local net interrupt function,
+       so we register the IRQ only once now. Still use SA_SHIRQ, as it's possible that another device
+       then the one we registered under frees the IRQ. */
+    if (irq_table->num_devs == 1)
+        retval = request_irq(dev->irq, &local_net_interrupt, SA_SHIRQ | SA_INTERRUPT, dev->name, irq_table);
+#else
+    retval = request_irq(dev->irq, &local_net_interrupt, SA_SHIRQ | SA_INTERRUPT,
+		    dev->name, dev);
+#endif
+
+    if (retval) {
+	printk("%s: unable to get IRQ %d (retval=%d).\n",
+	       dev->name, dev->irq, retval);
+	netif_stop_queue (dev);
+        unregister_mvc_irq(dev);
+        return -EBUSY;
+    }
+
+    /* determine initial linkstate for Ethernet interface (LAN or WAN) */
+    if (GET_DEV_TYPE(dev->base_addr) == BIS_DT_802DOT3) {
+        islmvc_send_mvc_msg(dev, OPGET, GEN_OID_LINKSTATE, &linkstate, sizeof(long));
+        if (linkstate == 0) {
+            netif_carrier_off(dev);
+        }
+    }
+
+    /* If the current device is host device for WDS devices, bring the WDS devices up and running. */
+    if (GET_DEV_TYPE(dev->base_addr) == BIS_DT_802DOT11)
+        open_wds_links(((struct net_local *)dev->priv)->wdsp);
+
+    return 0;
+}
+
+
+/**********************************************************************
+ *  local_net_tx_timeout
+ *
+ *  DESCRIPTION: Called when the kernel signals a tx timeout.
+ *               This functions checks the linkstate of the device.
+ *               If the link is down, the carrier flag of the devive is
+ *               put down.
+ *               If the link is not reported down, the interface is resetted.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:      Nothing.
+ *
+ **********************************************************************/
+#ifdef HAVE_TX_TIMEOUT
+static void local_net_tx_timeout(struct net_device *dev)
+{
+    long linkstate;
+
+    struct net_local *lp = (struct net_local *)dev->priv;
+
+    DEBUG(DBG_FUNC_CALL | DBG_TX, "local_net_tx_timeout, dev %s \n", dev->name);
+
+    islmvc_send_mvc_msg(dev, OPGET, GEN_OID_LINKSTATE, &linkstate, sizeof(long));
+
+    if (linkstate == 0)
+    {
+	printk(KERN_WARNING "%s: link down, network cable problem?\n", dev->name);
+
+	netif_carrier_off (dev);
+    }
+    else
+    {
+	
+	printk(KERN_WARNING "%s: reset interface\n", dev->name);
+
+	/* Try to restart the device. */
+	prism_eth_init(dev, PRISM_ETH_HALT);
+        prism_eth_init(dev, PRISM_ETH_RUN);
+	lp->stats.tx_errors++;
+        netif_wake_queue(dev);
+    }
+}
+#endif /* HAVE_TX_TIMEOUT */
+
+
+/**********************************************************************
+ *  local_net_send_packet
+ *
+ *  DESCRIPTION: This function puts an skbuf into an MVC frame,
+ *               updates the statistics and sends the frame to the local MVC.
+ *
+ *  PARAMETERS:	 skb - pointer to a linux packet buffer.
+ *               dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 0
+ *
+ **********************************************************************/
+static int local_net_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+    //FIXME, still needed for MVC v2?
+    static int tries = 1000000; /* give the first packet a lot of retries */
+
+    unsigned char *src;
+    struct sk_buff *skb2;
+    struct msg_frame *framep;
+    int error;
+    int WDSLink;
+    long linkstate;
+    unsigned char WDS_Mac[ETH_ALEN];
+
+    struct net_local *lp = (struct net_local *)dev->priv;
+    long dev_nr = GET_DEV_NR(dev->base_addr);
+
+    DEBUG((DBG_FUNC_CALL | DBG_TX), "local_net_send_packet, skb %p, dev %s \n", skb, dev->name);
+
+    /* If this skb came from a WDS device, the
+       skb->cb field will be filled with a WDSLink MACaddress.
+       Since the skb->cb field won't be cloned, we check it here. */
+    WDSLink = check_skb_for_wds(skb, WDS_Mac);
+
+    /* if the head or tail room doesn't comply with the device or
+       the skb is cloned .. */
+#ifdef BLOB_V2
+    if (skb_headroom (skb) < lp->dev_elem->header ||
+	skb_tailroom (skb) < lp->dev_elem->trailer ||
+	skb_cloned (skb))
+#else
+    if (skb_headroom (skb) < lp->dev_desc->header ||
+        skb_tailroom (skb) < lp->dev_desc->trailer ||
+        skb_cloned (skb))
+#endif
+    {
+#if (NET_DEBUG & DBG_TX)
+        if (!skb_cloned (skb))
+	{
+            DEBUG(DBG_TX, "no head/tail room, head:(%d,%d),tail(%d,%d)..",
+		skb_headroom (skb), lp->dev_elem->header,
+		skb_tailroom (skb), lp->dev_elem->trailer);
+	}
+#endif
+
+        /* see if we can shift the data in the buffer */
+	if (!skb_cloned (skb) &&
+	    skb_headroom (skb) + skb_tailroom (skb) >=
+#ifdef BLOB_V2
+            lp->dev_elem->header + lp->dev_elem->trailer)
+#else
+            lp->dev_desc->header + lp->dev_desc->trailer)
+#endif
+	{
+
+#ifdef BLOB_V2
+            DEBUG(DBG_TX, "shift data: %d..", lp->dev_elem->header - skb_headroom (skb));
+#else
+            DEBUG(DBG_TX, "shift data: %d..", lp->dev_desc->header - skb_headroom (skb));
+#endif
+
+	    src = skb->data;
+#ifdef BLOB_V2
+            skb_reserve (skb, lp->dev_elem->header - skb_headroom (skb));
+#else
+            skb_reserve (skb, lp->dev_desc->header - skb_headroom (skb));
+#endif
+	    memmove (skb->data, src, skb->len);
+            lp->tx_misaligned++;
+
+	}
+	else	/* copy to a new buffer with enough head and tail room */
+	{
+#if (NET_DEBUG & DBG_TX)
+	    if (skb_cloned (skb))
+		printk ("cloned sk_buff.. ");
+	    printk ("copy data.. ");
+#endif
+
+	    skb2 = dev_copy_expand_skb (dev, skb);
+	    dev_kfree_skb (skb);
+	    if (skb2 == NULL)
+            {
+                lp->stats.tx_dropped++;
+		return 0;
+            }
+	    skb = skb2;
+	}
+    }
+
+    if ((framep = skb_to_frame (skb)) == NULL)
+    {
+	DEBUG((DBG_TX | DBG_ERROR), "NO frame!!!\n");
+	dev_kfree_skb (skb);
+	lp->stats.tx_dropped++;
+        return 0;
+    }
+
+    /* send the frame to the local MVC */
+
+    DEBUG(DBG_TX, "send: size %d, headroom %d..", framep->size,
+            skb_headroom (framep->handle));
+#if (NET_DEBUG & DBG_TX)
+    dbg_print_frame( framep );
+#endif
+
+    /* Copy the found WDS MAC address in the msg_frame */
+    if (WDSLink == 1) 
+    	copy_wds_to_frame(framep, WDS_Mac);
+
+    do
+    {
+        error = dev_frame_tx (dev_nr, framep);
+        if (error == BER_OVERFLOW)
+            dev_service (dev_nr); /* Give the device some time to process */
+        tries--;
+    }
+    /* We can do this while:
+     * <BER_ERROR: 	If the frame is not queued.
+     * !BER_DSTUNKN: 	Destination isn't unknown (no need to retry, the 
+     * 			dev will not know it the next time either).
+     * !BER_UNSPEC:	The frame is not allowed by frame class 
+     *			(for instance, data to authenticated but not 
+     *			 associated clients) or by privacy settings
+     *			(for instance, no key installed while exclude
+     *			 unencrypted is set).
+     * tries:		Untill the retry counter is zero.
+     */
+    while (error < BER_NONE &&
+           error != BER_DSTUNKN && 
+           error != BER_UNSPEC && 
+           tries);
+    tries = TX_NR_RETRIES;
+
+    if (error < BER_NONE)
+    {
+    	/* On errors not unreachable or not allowed to send
+    	 * check if the linkstate is down and turn carrier off if so.
+    	 * When the error is queue overflow stop the queue in order
+    	 * to give the device some time to process the full queues.
+    	 * When other tx-ed frames return in the system the queue
+    	 * will be enabled.
+    	 */
+        if (error != BER_DSTUNKN && error != BER_UNSPEC)
+        {
+	    _DEBUG((DBG_TX | DBG_ERROR),
+	           KERN_INFO "TX dev: %s, NOT accepted!!\n", dev->name);
+
+            /* test if the link is down */
+            islmvc_send_mvc_msg(dev, OPGET, GEN_OID_LINKSTATE, &linkstate, sizeof(long));
+            if (linkstate == 0)		        /* Disable carrier and queues ? */
+                netif_carrier_off (dev);
+            else if (error == BER_OVERFLOW)     /* The device queue is full, backoff ! */  
+                netif_stop_queue (dev);
+
+        }
+        /* Count all error codes as dropped */
+	lp->stats.tx_dropped++;
+
+	/* abort the frame */
+	dev_free_frame (dev, framep);
+    }
+    else {
+        DEBUG((DBG_TX | DBG_WDS), "OK!!\n");
+    }
+    dev->trans_start = jiffies;
+ 
+    return 0;
+}
+
+
+/**********************************************************************
+ *  local_net_interrupt
+ *
+ *  DESCRIPTION: The typical workload of the driver:
+ *               Handle the network interface interrupts.
+ *
+ *  PARAMETERS:	 irq    - interrupt number, not used.
+ *               dev_id - pointer to the net_device struct, assigned when
+ *                        the IRQ was registered.
+ *               regs   - Not used.
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:        When frame_add_failed is set, we leave the while loop
+ *               to give the system some time to allocate memory.
+ *
+ **********************************************************************/
+#ifdef BLOB_V2
+static void local_net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+    int			    requests;
+    int                     i;
+    int                     bit;
+    int                     dev_nr;
+    unsigned int            reqs_pending;
+    struct mvc_irq_table    *irq_table;
+    struct net_local        *lp;
+    char                    *irq_stats;
+    struct net_device       *first_dev;
+
+    struct net_device	    *dev = NULL;
+
+    uIRQ->Soft = 0;	    /* remove soft irq */
+
+    DEBUG(DBG_FUNC_CALL | DBG_IRQ, "local_net_interrupt, irq %d, dev_id %p, regs %p \n", irq, dev_id, regs);
+
+    if (dev_id == NULL) {
+	printk(KERN_WARNING "%s: irq %d for unknown device.\n", cardname, irq);
+	return;
+    }
+
+    irq_table = (struct mvc_irq_table*) dev_id;
+
+    /* Get a pointer to the MVC irq stats. */
+    if ((first_dev = irq_table->dev_ptr[0]) == NULL)
+        BUG(); /* Should never happen! */
+
+    lp = (struct net_local*) first_dev->priv;
+    irq_stats = lp->dev_elem->irq_stats;
+
+    reqs_pending = ( (1 << (irq_table->num_devs)) -1);
+
+    /* Reset this variable */
+    frame_add_failed = 0;
+
+    while (reqs_pending && frame_add_failed != 1)
+    {
+        for (i=0; i < irq_table->num_devs; i++)
+        {
+            dev_nr = irq_table->dev_nr[i];
+
+            if (irq_stats[dev_nr]) {
+                irq_stats[dev_nr] = 0;
+                if ((dev = irq_table->dev_ptr[i]) == NULL)
+                    BUG(); /* Should never happen! */
+                if ((requests = dev_reqs(dev_nr)) > BER_NONE)
+                    local_dev_handle_reqs(dev, requests);
+            }
+            else {
+                bit = (1 << i);
+                reqs_pending &= ~bit;
+            }
+        }
+    }
+
+    handle_blob_reqs();
+
+    return;
+}
+
+#else /* !BLOB_V2 */
+
+static void local_net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+    int			requests;
+
+    struct net_device	*dev = NULL;
+
+    uIRQ->Soft = 0;	    /* remove soft irq */
+
+    _DEBUG(DBG_FUNC_CALL | DBG_IRQ, "local_net_interrupt, irq %d, dev_id %p, regs %p \n", irq, dev_id, regs);
+
+    if (dev_id == NULL)
+    {
+	printk(KERN_WARNING "%s: irq %d for unknown device.\n", cardname, irq);
+	return;
+    }
+
+    dev = (struct net_device *) dev_id;
+
+    /* We handle blob requests within the Ethernet device */
+    if (GET_DEV_TYPE(dev-> base_addr) == BIS_DT_802DOT3)
+	handle_blob_reqs();
+
+    /* Reset this variable */
+    frame_add_failed = 0;
+
+    if ((requests = dev_reqs (GET_DEV_NR(dev->base_addr))) > BER_NONE)
+    	local_dev_handle_reqs (dev, requests);
+
+    return;
+}
+
+#endif /* BLOB_V2 */
+
+/**********************************************************************
+ *  local_net_close
+ *
+ *  DESCRIPTION: The inverse routine to local_net_open().
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 0
+ *
+ **********************************************************************/
+static int local_net_close(struct net_device *dev)
+{
+    struct msg_frame *framep;
+
+    long dev_nr = GET_DEV_NR(dev->base_addr);
+    struct net_local *lp = (struct net_local *) dev->priv;
+
+    DEBUG(DBG_FUNC_CALL | DBG_CLOSE, "local_net_close, dev %s \n", dev->name);
+
+    /* If the current device is host device for WDS devices,
+       bring the associated WDS devices DOWN. */
+    if (GET_DEV_TYPE(dev->base_addr) == BIS_DT_802DOT11)
+        close_wds_links(((struct net_local *)dev->priv)->wdsp);
+
+    netif_stop_queue(dev);
+
+    if (dev_halt(dev_nr) >= BER_NONE)
+    {
+        while ((framep = dev_frame_return(dev_nr)) != NULL) {
+            dev_free_frame(dev, framep);
+        }
+    }
+
+    /* Dispatching the IRQ for the different devices is done in the local net interrupt function,
+       so we free the IRQ only for the last device. */
+    if (lp->mvcirq_table->num_devs == 1)
+        free_irq(dev->irq, dev);
+
+    unregister_mvc_irq(dev);
+
+    return 0;
+}
+
+
+/****************************************************************
+ *								*
+ *    		Begin of frame handling block			*
+ *              (driver configurator module)			*
+ *								*
+ ***************************************************************/
+
+
+/**********************************************************************
+ *  req_frame_rx
+ *
+ *  DESCRIPTION: Handle the frame rx requests.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:	 Inline function.
+ *
+ **********************************************************************/
+static inline void req_frame_rx(struct net_device *dev)
+{
+    struct msg_frame        *framep;
+    struct net_device       *wds_dev;
+    struct wds_net_local    *wds_lp;
+    struct sk_buff          *skb;
+
+    struct net_local        *lp = (struct net_local *) dev->priv;
+
+    DEBUG(DBG_IRQ, "..RX");
+
+    while ((framep = dev_frame_rx (GET_DEV_NR(dev->base_addr))) != NULL)
+    {
+        if (GET_DEV_TYPE(dev->base_addr) == BIS_DT_802DOT11)
+        {
+            /* Check if this frame contains one of the WDS addresses */
+#ifdef BLOB_V2
+            wds_dev = wds_find_device(framep->wds, ((struct net_local *)dev->priv)->wdsp);
+#else
+            wds_dev = wds_find_device(framep->wds_link, ((struct net_local *)dev->priv)->wdsp);
+#endif
+        }
+        else
+            wds_dev = NULL;
+
+        dev->last_rx = jiffies;
+        if (framep->size < 1569 && framep->status < 10)
+        {
+
+#if (NET_DEBUG & DBG_RX)
+            dbg_print_frame (framep);
+#endif
+#if (NET_DEBUG & DBG_SKB)
+            if (dbg_frame_filter_check (dev, framep))
+#endif
+            {
+                if ((skb = frame_to_skb (framep)) != NULL)
+                {
+                    skb->protocol = eth_type_trans( skb, dev );
+                    lp->stats.rx_packets++;
+                    lp->stats.rx_bytes += skb->len;
+
+                    /* This will change in the new WDS implementation. */
+                    if (wds_dev != NULL)
+                    {
+                        wds_lp = (struct wds_net_local *) wds_dev->priv;
+                        wds_lp->stats.rx_packets++;
+                        wds_lp->stats.rx_bytes += skb->len;
+                        skb->dev = wds_dev;
+                    }
+                    /* Give the data to the Linux kernel for further processing. */
+                    netif_rx(skb);
+                }
+                else
+                {
+                    /* No valid data in frame. It's dropped.*/
+                    lp->stats.rx_dropped++;
+                }
+            }
+        }
+        else
+            printk (KERN_ERR " RX, size %d, status %d!!\n",
+                    framep->size, framep->status);
+    }
+
+}
+
+
+/**********************************************************************
+ *  req_frame_return
+ *
+ *  DESCRIPTION: Handle the frame return requests.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:	 Inline function.
+ *
+ **********************************************************************/
+static inline void req_frame_return(struct net_device *dev)
+{
+    struct msg_frame    *framep;
+
+    struct net_local        *lp = (struct net_local *) dev->priv;
+
+    while ((framep = dev_frame_return (GET_DEV_NR(dev->base_addr))) != NULL)
+    {
+        _DEBUG(DBG_IRQ, "..RET");
+        if (framep->status <= FSRETURNED) /* Check these defines carefully with frame state defines.  */
+        {
+            if (framep->status <= FSTXSUCCESSFUL)
+            {
+                if (framep->status == FSTXSUCCESSFUL)
+                {
+                    lp->stats.tx_packets++;
+                    lp->stats.tx_bytes += framep->size;
+                }
+                else
+                {
+                    _DEBUG(DBG_TX, " TX error!!. status %d\n",
+                            framep->status);
+                    lp->stats.tx_errors++;
+                }
+                netif_wake_queue (dev);
+            }
+            dev_free_frame (dev, framep);
+        }
+        else
+            printk (KERN_ERR " RET, size %d, status %d!!\n",
+                    framep->size, framep->status);
+    }
+}
+
+
+/**********************************************************************
+ *  req_trap_handling
+ *
+ *  DESCRIPTION: Handle traps from the MVC.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:	 Inline function.
+ *
+ **********************************************************************/
+/*
+ *  The trap handling mechanism is different for Blob V1 and Blob V2.
+ *
+ */
+#ifdef BLOB_V2
+static inline void req_trap_handling(struct net_device *dev)
+{
+    struct msg_conf     trapmsg;
+    int                 dev_grp;
+    int                 dev_nr         = GET_DEV_NR(dev->base_addr);
+    int                 dev_type       = GET_DEV_TYPE(dev->base_addr);
+    unsigned char       *new_buf       = NULL;
+    unsigned char       local_buf[64];
+    long 		led_wlan_config_on  = 5;
+    long 		led_eth_config_on  = 2;
+    long		led_config_off = 0;
+
+    _DEBUG(DBG_IRQ, "..TRAP");
+
+    /* Most traps are the size of an obj_mlme struct or less. If this does not fit the trap size
+       requirement, we are told so and will malloc a new buffer for the trap data. */
+    trapmsg.data = (long*) &local_buf[0];
+    trapmsg.size = sizeof(local_buf);
+
+    /* Get the trap from the MVC... */
+    if (dev_trap (dev_nr, &trapmsg) == BER_OVERFLOW)
+    {
+        /* The size of the buffer we passed was too small. Malloc a new buffer with correct size. */
+        if ((new_buf = kmalloc(trapmsg.size, GFP_ATOMIC)) == NULL)
+        {
+            printk(KERN_ERR "Couldn't malloc new trap buffer. \n");
+            return;
+        }
+
+        trapmsg.data = (long *) new_buf;
+
+        /* Okay, try again... */
+        if (dev_trap (dev_nr, &trapmsg) == BER_OVERFLOW)
+        {
+            printk(KERN_WARNING "Couldn't get trap message for the second time. Stopped trying... \n");
+            return;
+        }
+    }
+
+    /* The Linkstate trap is partly handled in the driver. */
+    if (trapmsg.oid == GEN_OID_LINKSTATE)
+    {
+	if ( *trapmsg.data ) /* LINK State is UP... */
+	{
+	    /* Check the state of the link, and set/clear the corresponding LED accordingly*/
+	    if (islmvc_send_mvc_msg(dev, OPSET, GEN_OID_LEDCONFIG, 
+		    ((dev_type == BIS_DT_802DOT3) ? (long*)&led_eth_config_on : (long*)&led_wlan_config_on), 
+		    sizeof(led_eth_config_on)) < 0)
+		printk("req_trap_handling, couldn't set led config for dev %s\n", dev->name);
+	    printk ("%s: link up\n", dev->name);
+	    netif_carrier_on (dev);
+        }
+	else /* LINK State is DOWN... */
+	{
+	    if (islmvc_send_mvc_msg(dev, OPSET, GEN_OID_LEDCONFIG, (long*)&led_config_off, sizeof(led_config_off)) < 0)
+		printk("req_trap_handling, couldn't set led config 0 for dev %s\n", dev->name);		
+	    printk ("%s: link down\n", dev->name);
+	    netif_carrier_off (dev);
+	}
+    }
+
+    /* Determine the device group based on the device type. */
+    if (dev_type == BIS_DT_802DOT3)
+        dev_grp = DEV_NETWORK_ETH;
+    else if (dev_type == BIS_DT_802DOT11)
+        dev_grp = DEV_NETWORK_WLAN;
+    else
+        dev_grp = 0; /* Unknown device. Use no trapgrp. */
+
+    /* We handle all other traps in the generic part, and also send the GEN_OID_LINKSTATE up */
+    mgt_response( 0, src_seq++, dev_grp, dev->ifindex,
+       PIMFOR_OP_TRAP, trapmsg.oid, trapmsg.data, trapmsg.size);
+
+    /* When we malloced a new buffer, free it here. */
+    if (new_buf)
+        kfree(new_buf);
+}
+
+#else /* !BLOB_V2 */
+
+static inline void req_trap_handling(struct net_device *dev)
+{
+    struct msg_conf     *trapmsg;
+    int                 dev_grp;
+
+    int                 dev_nr      = GET_DEV_NR(dev->base_addr);
+    int                 dev_type    = GET_DEV_TYPE(dev->base_addr);
+
+    _DEBUG(DBG_IRQ, "..TRAP");
+
+    /* Get the trap from the MVC... */
+    if ((trapmsg = dev_trap (dev_nr)) != NULL)
+    {
+        /* This is an embedded MVC specific trap, so we handle it partly here... */
+        if (trapmsg->oid == GEN_OID_LINKSTATE && dev_type == BIS_DT_802DOT3)
+        {
+
+#ifdef TEST_ON_POLDHU
+            /* Set/Clear the Ethernet LED */
+            long mask = 1;
+            struct msg_conf config;
+
+            config.operation = OPSET;
+            config.data = &mask;
+
+            if( *trapmsg->data ) /* LINK State is UP... */
+            {
+                config.oid = BLOB_OID_LEDSET;
+                printk ("%s: link up\n", dev->name);
+                netif_carrier_on (dev);
+            }
+            else                 /* LINK State is DOWN... */
+            {
+                config.oid = BLOB_OID_LEDCLEAR;
+                printk ("%s: link down\n", dev->name);
+                netif_carrier_off (dev);
+            }
+
+            blob_conf( &config ); /* For setting/clearing the led */
+#endif /* TEST_ON_POLDHU */
+        }
+
+        /* Determine the device group based on the device type. */
+        if (dev_type == BIS_DT_802DOT3)
+            dev_grp = DEV_NETWORK_ETH;
+        else if (dev_type == BIS_DT_802DOT11)
+            dev_grp = DEV_NETWORK_WLAN;
+        else
+            dev_grp = 0; /* Unknown device. Use no trapgrp. */
+
+        /* We handle all other traps in the generic part, and also send the GEN_OID_LINKSTATE up */
+        mgt_response( 0, src_seq++, dev_grp, dev->ifindex,
+           PIMFOR_OP_TRAP, trapmsg->oid, trapmsg->data, 100 ); /* No trapsize parameter in BLOB V1 */
+    }
+}
+#endif /* BLOB_V2 */
+
+
+/**********************************************************************
+ *  req_frame_add
+ *
+ *  DESCRIPTION: Add frames to the device. If allocating a frame failed,
+ *               the static variable frame_add_failed is set to 1. We end
+ *               the interrupt service routine when this variable is set,
+ *               to give the system some time to allocate memory.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:	 Inline function.
+ *
+ **********************************************************************/
+static inline void req_frame_add(struct net_device *dev)
+{
+    struct msg_frame    *framep;
+    int                 nr_frames = 1;
+
+    _DEBUG((DBG_IRQ | DBG_FRAME), "..ADD");
+
+    while (nr_frames > 0) {
+        if ((framep = dev_alloc_frame (dev, 0)) != NULL) {
+	    _DEBUG(DBG_IRQ, "dev_alloc_frame returned %p pointer..", framep);
+	    if ((nr_frames = dev_frame_add (GET_DEV_NR(dev->base_addr), framep)) < BER_NONE) {
+	        dev_free_frame(dev, framep);
+	    }
+	}
+	else {
+            _DEBUG(DBG_IRQ, "dev_alloc_frame returned NULL pointer.\n");
+            frame_add_failed = 1;
+            return;
+        }
+    }
+}
+
+/**********************************************************************
+ *  req_service
+ *
+ *  DESCRIPTION: Service the device.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:	 Inline function.
+ *
+ **********************************************************************/
+static inline void req_service(struct net_device *dev)
+{
+    _DEBUG(DBG_IRQ, "..service");
+    dev_service (GET_DEV_NR(dev->base_addr));
+    dev_service (DEVICE_DEBUG); /* We service the debug device here. */
+}
+
+/**********************************************************************
+ *  req_watchdog_handling
+ *
+ *  DESCRIPTION: Watchdog handling the device.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:	 Inline function.
+ *
+ **********************************************************************/
+static inline void req_watchdog_handling(struct net_device *dev)
+{
+    _DEBUG(DBG_IRQ, "..watchdog request");
+    /*
+     * Here one can handle watchdog pending requests. The only device
+     * which watchdog is enabled by default is the BLOB device,
+     * and is handled in islmvc_blob.c.
+     * If you would like to use the watchdog function from any other
+     * device you should change the code here the make this function.
+     * and set the GEN_OID_WACHDOG for that specific device. Using this
+     * mechanism one can proxy watchdog even in user space applications.
+     */
+    //dev_watchdog (GET_DEV_NR(dev->base_addr));
+}
+
+/**********************************************************************
+ *  local_dev_handle_reqs
+ *
+ *  DESCRIPTION: Handle requests 'requests' for device 'dev'.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *		 requests - requests to handle
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:	 Also called from the interrupt service routine.
+ *
+ **********************************************************************/
+static inline void local_dev_handle_reqs(struct net_device *dev, int requests)
+{
+    _DEBUG(DBG_IRQ, "dev_handle_reqs, dev %s, requests %d\n", dev->name, requests);
+
+    if (requests & REQ_UNKNOWN) {
+        printk (" called with unknown requests: %d!!\n", requests);
+        return;
+    }
+    if (requests & REQFRAMERX) {
+        req_frame_rx(dev);
+    }
+    if (requests & REQFRAMEADD) {
+        req_frame_add(dev);
+    }
+    if (requests & REQFRAMERETURN) {
+        req_frame_return(dev);
+    }
+    if (requests & REQSERVICE) {
+        req_service(dev);
+    }
+    if (requests & REQTRAP) {
+        req_trap_handling(dev);
+    }
+    if (requests & REQWATCHDOG) {
+	req_watchdog_handling(dev);
+    }
+}
+
+
+/**********************************************************************
+ *  alloc_frame_pool
+ *
+ *  DESCRIPTION: Allocates a frame pool for the local MVC.
+ *               The frame pool is allocated and the free frame list
+ *               is allocated with these frames.
+ *
+ *  PARAMETERS:	 Pointer to the net_local structure lp.
+ *
+ *  RETURN:	 Zero on success, or -ENOMEM when malloc failed.
+ *
+ **********************************************************************/
+static int alloc_frame_pool(struct net_local *lp)
+{
+    int i;
+
+    DEBUG((DBG_FUNC_CALL | DBG_FRAME), "alloc_frame_pool, lp %p \n", lp);
+
+    /* allocate frame pool */
+    lp->frame_pool = kmalloc(sizeof(struct msg_frame) * lp->maxnrframes,
+ 			    GFP_KERNEL);
+    if (lp->frame_pool == NULL)
+	return -ENOMEM;
+
+    /* add all frames to the free frame list */
+    lp->frame_freelist = NULL;
+    for (i = 0; i < lp->maxnrframes; i++)
+    {
+	lp->frame_pool[i].handle = lp->frame_freelist;
+	lp->frame_freelist = &lp->frame_pool[i];
+    }
+
+    return 0;
+}
+
+/**********************************************************************
+ *  frame_alloc
+ *
+ *  DESCRIPTION: Allocates a frame from the free frames list.
+ *               The wds info in the frame is zeroed.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 framep pointer to allocated frame or NULL when alloc failed.
+ *
+ *  NOTE:        inline function.
+ *
+ **********************************************************************/
+static inline struct msg_frame *frame_alloc (struct net_device *dev)
+{
+    struct msg_frame *framep;
+    unsigned long flags;
+    msg_frame *wdsframep;
+
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME), "frame_alloc, dev %s \n", dev->name);
+
+    /* We could change this for a spinlock mechanism */
+    save_flags_cli (flags);
+
+    framep = ((struct net_local *)dev->priv)->frame_freelist;
+    if (framep)
+	((struct net_local *)dev->priv)->frame_freelist = framep->handle;
+
+    restore_flags(flags);
+
+    /* Make sure the wds info in the frame is zeroed */
+    if (framep)
+    {
+        wdsframep = (msg_frame*)framep;
+#ifdef BLOB_V2
+        memset(wdsframep->wds, 0, ETH_ALEN);
+#else
+        memset(wdsframep->wds_link, 0, ETH_ALEN);
+#endif /* TEST_ON_POLDHU */
+    }
+
+    return framep;
+}
+
+
+/**********************************************************************
+ *  frame_free
+ *
+ *  DESCRIPTION: Frees the frame pointed to by the framep.
+ *               It returns the framep to the free frames list.
+ *
+ *  PARAMETERS:	 dev    - pointer to a linux net device struct.
+ *               framep - pointer to msg_frame struct.
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:        Inline function.
+ *
+ **********************************************************************/
+static inline void frame_free (struct net_device *dev, struct msg_frame *framep)
+{
+    unsigned long flags;
+
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME), "frame_free, dev %s, framep %p \n", dev->name, framep);
+
+    if (!framep)
+        return;
+
+    save_flags_cli (flags);
+
+    framep->handle = ((struct net_local *)dev->priv)->frame_freelist;
+    ((struct net_local *)dev->priv)->frame_freelist = framep;
+
+    restore_flags(flags);
+}
+
+
+/**********************************************************************
+ *  copy_wds_to_frame
+ *
+ *  DESCRIPTION: This copies the WDS_Mac address into the msg_frame structure.
+ *
+ *  PARAMETERS:	 frame pointer to msg_frame structure
+ *               WDS MAC address to put into the frame.
+ *
+ *  RETURN:	 Nothing
+ *
+ *  NOTE:        inline function.
+ *
+ **********************************************************************/
+#ifdef BLOB_V2
+inline void copy_wds_to_frame(msg_frame *framep, unsigned char *WDS_Mac)
+{
+    /* Copy the found MAC addres in the msg_frame. */
+    memcpy(framep->wds, WDS_Mac, ETH_ALEN); /* MVC v1 */
+}
+#else
+inline void copy_wds_to_frame(msg_frame *framep, unsigned char *WDS_Mac)
+{
+    memcpy(framep->wds_link, WDS_Mac, ETH_ALEN); /* MVC v2 */
+}
+#endif
+
+
+/**********************************************************************
+ *  skb_to_frame
+ *
+ *  DESCRIPTION: Attach a prism frame structure to linux sk_buff 'skb'
+ *		 and initialize all fields of the frame structure with
+ *		 the current information of 'skb'.
+ *
+ *  PARAMETERS:	 skb - pointer to linux packet buffer.
+ *
+ *  RETURN:	 Pointer to the attached frame, or NULL if there wasn't
+ *		 enough memory.
+ *
+ **********************************************************************/
+/*
+ * The handling of frames is changed between MVC v1 and v2.
+ *
+ */
+#ifdef BLOB_V2
+static struct msg_frame *skb_to_frame (struct sk_buff *skb)
+{
+    struct msg_frame *framep;
+
+    int type = GET_DEV_TYPE(skb->dev->base_addr);
+
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME), "skb_to_frame, skb %p, dev %s \n", skb, skb->dev->name);
+
+    /* first malloc memory for msg_frame */
+    framep = frame_alloc (skb->dev);
+    if (framep != NULL)
+    {
+        framep->handle	 = (void *) skb;
+
+        /* Use this mpdu mapping for empty frames. */
+        if (skb->len < (2*ETH_ALEN)) {
+            framep->mpdu	 = (unsigned char *) skb->data;
+        }
+        else {
+            /* Need to do some formatting depending on the device type. */
+            if (type == BIS_DT_802DOT3) {
+                /*
+                    Nothing special to do for an 802.3 device...
+                    NOTE: This only works when the 802.3 device was started in MODE_PROMISCUOUS.
+                          When started in MODE_NORMAL need to add Source and Destination address to start of skb.
+                */
+                _DEBUG(DBG_TX, "skb_to_frame, 802.3...");
+                framep->mpdu	 = (unsigned char *) skb->data;
+            }
+            else if (type == BIS_DT_802DOT11) {
+                /*
+                    For 802.11 devices we need to do some frame formatting:
+                        - Remove Destination and Source address from mpdu data.
+                        - Add LLC + SNAP header to beginning of mpdu data.
+                */
+
+                /* Copy Destination and Source address into frame dest and src. */
+                memcpy(framep->dest, skb->data           , ETH_ALEN);
+                memcpy(framep->src,  skb->data + ETH_ALEN, ETH_ALEN);
+
+                /* Remove the Destination and Source Address from the skb. */
+                skb_pull(skb, 2 * ETH_ALEN);
+
+                /* convert the ethernet frame to WLAN */
+                llc_to_wlan( skb );
+
+                /* Okay, we're done. Point mpdu pointer to start of skb data. */
+                framep->mpdu	 = (unsigned char *) skb->data;
+            }
+            else {
+                printk(KERN_ERR "skb_to_frame: Unknown device type.\n");
+                /* Don't know how to format. Callers responsibility to free the skb. */
+                return NULL;
+            }
+        }
+
+        framep->size	 = skb->len;
+	framep->priority = -1; /* Priority isn't implemented yet.
+                                  We should map the skb->priority to the frame priority here. */
+    }
+    else
+        printk(KERN_WARNING "Frame pool full? \n");
+
+#if (NET_DEBUG & DBG_SKB)
+    memset (skb->head, 0, skb_headroom(skb));
+    memset (skb->tail, 0, skb_tailroom(skb));
+#endif
+
+#if (NET_DEBUG & DBG_FRAME_SANITY)
+    check_frame_skb(framep, __FILE__, __LINE__);
+#endif
+
+    return framep;
+}
+
+#else /* !BLOB_V2 */
+
+static struct msg_frame *skb_to_frame (struct sk_buff *skb)
+{
+    struct msg_frame *framep;
+
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME), "skb_to_frame, skb %p \n", skb);
+
+    /* first malloc memory for msg_frame */
+    framep = frame_alloc (skb->dev);
+    if (framep != NULL)
+    {
+	framep->handle	 = (void *) skb;
+	framep->mpdu	 = (unsigned char *) MAP_CACHED((unsigned)skb->data);
+        framep->size	 = skb->len;
+	framep->priority = -1; /* Priority isn't implemented yet.
+                                  We should map the skb->priority to the frame priority here. */
+        framep->bc_domain = 0;
+    }
+    else
+        printk(KERN_WARNING "Frame pool full? \n");
+
+#if (NET_DEBUG & DBG_SKB)
+    memset (skb->head, 0, skb_headroom(skb));
+    memset (skb->tail, 0, skb_tailroom(skb));
+#endif
+     return framep;
+}
+#endif /* BLOB_V2 */
+
+/**********************************************************************
+ *  frame_to_skb
+ *
+ *  DESCRIPTION: Update the fields of the linux sk_buff assigned to
+ *		 frame 'framep' just received from the MVC.
+  *		 The frame is freed.
+ *
+ *  PARAMETERS:	 framep - pointer to frame received from MVC.
+ *
+ *  RETURN:	 Pointer to the updated sk_buff that was assigned to the
+ *		 frame.
+ *
+ **********************************************************************/
+/*
+ * The handling of frames is changed between MVC v1 and v2.
+ *
+ */
+#ifdef BLOB_V2
+static struct sk_buff *frame_to_skb (struct msg_frame *framep)
+{
+    struct sk_buff *skb;
+    int offset, type;
+    unsigned char *src;
+
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME | DBG_IRQ), "frame_to_skb, framep %p \n", framep);
+
+#if (NET_DEBUG & DBG_FRAME_SANITY)
+    check_frame_skb(framep, __FILE__, __LINE__);
+#endif
+
+    skb = framep->handle;
+
+    type = GET_DEV_TYPE(skb->dev->base_addr);
+
+#if (NET_DEBUG & DBG_SKB)
+    /* Some sanity checking on the frame. */
+    if ((unsigned)framep->size > 1600 )
+        printk("Frame size (%d) is > 1600. Ok? \n", framep->size);
+    if (!framep->mpdu)
+        printk("framep->mpdu == NULL !!!\n");
+#endif
+
+    /* determine shift in framep->mpdu between add and rx */
+    offset = framep->mpdu - skb->data;
+
+    skb_reserve (skb, offset);
+    skb_put (skb, framep->size);
+
+#if (NET_DEBUG & DBG_SKB)
+    if (skb_headroom(skb) < 2*ETH_ALEN)
+        printk("frame_to_skb, not enough headroom (%d) to add SA and DA\n", skb_headroom(skb));
+#endif
+
+    /* Depending on the device type, we need to do some frame formatting. */
+    if (type == BIS_DT_802DOT3) {
+        _DEBUG(DBG_RX, "frame_to_skb, 802.3...");
+        /* Nothing special to do. */
+    }
+    else if (type == BIS_DT_802DOT11) {
+        _DEBUG(DBG_RX, "frame_to_skb, 802.11...");
+
+        /* Convert the WLAN frame back to ethernet LLC format */
+        wlan_to_llc( skb );
+
+        /* Add Source and Destination address to front of the skb. */
+        memcpy(skb_push(skb, ETH_ALEN), framep->src, ETH_ALEN);
+        memcpy(skb_push(skb, ETH_ALEN), framep->dest, ETH_ALEN);
+    }
+    else {
+        printk(KERN_ERR "frame_to_skb: Unknown device type.\n");
+        /* Don't know how to format. Drop it. Free frame & skb. */
+        frame_free (skb->dev, framep);
+        dev_kfree_skb(skb);
+        return NULL;
+    }
+
+    /* determine offset between IP header and a word boundary */
+    offset = (int) (skb->data + 6 + 6 + 2) & 0x03;
+
+    /* if there is any, shift the data */
+    if (offset)
+    {
+	struct net_local *lp = (struct net_local *)skb->dev->priv;
+	lp->rx_misaligned++;
+
+	if (skb_headroom (skb) < offset)
+	{
+	    if (skb_tailroom (skb) < (4 - offset))
+		printk(KERN_NOTICE "Unaligned skb\n");
+	    else
+		offset = 4 - offset;
+	}
+	else
+	    offset = -offset;
+#if (NET_DEBUG & DBG_RX)
+	printk ("frame_to_skb, need to shift data %d\n", offset);
+#endif
+	src = skb->data;
+	skb_reserve (skb, offset);
+	memmove (skb->data, src, skb->len);
+    }
+    skb->priority = -1; /* Priority isn't implemented yet. Add mapping between skb and frame priority here. */
+
+#if (NET_DEBUG & DBG_FRAME_SANITY)
+    check_frame_skb(framep, __FILE__, __LINE__);
+#endif
+
+    frame_free (skb->dev, framep);
+
+    return skb;
+}
+
+#else /* !BLOB_V2 */
+
+static struct sk_buff *frame_to_skb (struct msg_frame *framep)
+{
+     struct sk_buff *skb;
+    int offset;
+    unsigned char *src;
+
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME), "frame_to_skb, framep %p\n", framep);
+
+    skb = framep->handle;
+
+    /* first map pointer back in uncached area */
+    MAP_UNCACHED((unsigned)framep->mpdu);
+
+    /* determine shift in framep->mpdu between add and rx */
+    offset = framep->mpdu - skb->data;
+
+    skb_reserve (skb, offset);
+    skb_put (skb, framep->size);
+
+    /* determine offset between IP header and a word boundary */
+    offset = (int) (skb->data + 6 + 6 + 2) & 0x03;
+
+    /* if there is any, shift the data */
+    if (offset)
+    {
+	struct net_local *lp = (struct net_local *)skb->dev->priv;
+	lp->rx_misaligned++;
+
+	if (skb_headroom (skb) < offset)
+	{
+	    if (skb_tailroom (skb) < (4 - offset))
+		printk(KERN_NOTICE "Unaligned skb\n");
+	    else
+		offset = 4 - offset;
+	}
+	else
+	    offset = -offset;
+#if (NET_DEBUG & DBG_RX)
+	printk ("frame_to_skb, need to shift data %d\n", offset);
+#endif
+	src = skb->data;
+	skb_reserve (skb, offset);
+	memmove (skb->data, src, skb->len);
+    }
+    skb->priority = -1; /* Priority isn't implemented yet. Add mapping between skb and frame priority here. */
+
+    frame_free (skb->dev, framep);
+
+    return skb;
+}
+#endif /* BLOB_V2 */
+
+/**********************************************************************
+ *  dev_alloc_frame
+ *
+ *  DESCRIPTION: Allocate a frame and a sk_buff with MTU size 'size' for
+ *		 device 'dev'. Set all fields of the frame and the
+ *		 sk_buff. If size equals 0 then the maximum MTU size is
+ *		 used. The head and the tail room for the frame (and
+ *		 sk_buff) is equal to the maximum head and maximum tail
+ *		 room for all devices.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *		 size - the MTU size for the frame.
+ *
+ *  RETURN:	 Pointer to the allocated frame or NULL on error.
+ *
+ **********************************************************************/
+static inline struct msg_frame *dev_alloc_frame (struct net_device *dev, int size)
+{
+    struct sk_buff *skb;
+    struct msg_frame *framep;
+    int bufsize;
+    struct net_local *lp;
+
+    _DEBUG((DBG_FUNC_CALL | DBG_IRQ | DBG_FRAME), "dev_alloc_frame, dev %s, size %d \n", dev->name, size);
+
+    /* first allocate a sk_buff with enough head and tail room */
+    lp = (struct net_local *)dev->priv;
+    bufsize = lp->maxhead + 2 +
+		    (size ? size : lp->maxmtu) + lp->maxtail;
+    if ((skb = dev_alloc_skb (bufsize)) == NULL) {
+        _DEBUG(DBG_IRQ | DBG_FRAME, "dev_alloc_frame, dev_alloc_skb failed... \n");
+        return NULL;
+    }
+
+    /* fill in some sk_buff fields */
+    skb->dev = dev;
+    skb_reserve (skb, lp->maxhead + 2); /* word align IP header */
+
+    if ((framep = skb_to_frame(skb)) == NULL)
+        dev_kfree_skb(skb);
+
+    return framep;
+}
+
+
+/**********************************************************************
+ *  dev_free_frame
+ *
+ *  DESCRIPTION: Free MVC frame 'frame' and the attached sk_buff.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *               frame - address of frame to free
+ *
+ *  RETURN:	 Nothing.
+ *
+ **********************************************************************/
+static inline void dev_free_frame (struct net_device *dev, struct msg_frame *frame)
+{
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME), "dev_free_frame, dev %s, frame %p \n", dev->name, frame);
+
+#if (NET_DEBUG & DBG_FRAME_SANITY)
+    check_frame_skb(frame, __FILE__, __LINE__);
+#endif
+
+    if (frame->handle)
+	dev_kfree_skb_any (frame->handle);
+    frame_free (dev, frame);
+}
+
+/**********************************************************************
+ *  dev_copy_expand_skb
+ *
+ *  DESCRIPTION: Allocate a new sk_buff and copy the data of sk_buff
+ *		 'skb'. The new sk_buff will have the required head and
+ *		 tail room for device 'dev'.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *		 skb - the sk_buff to copy the data from
+ *
+ *  RETURN:	 Pointer to the new allocated sk_buff or NULL on error.
+ *
+ **********************************************************************/
+static struct sk_buff *dev_copy_expand_skb (struct net_device *dev,
+				const struct sk_buff *skb)
+{
+    int bufsize;
+    struct sk_buff *newskb;
+    struct net_local *lp = (struct net_local *)dev->priv;
+
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME), "dev_copy_expand_skb, dev %s, skb %p \n", dev->name, skb);
+
+#ifdef BLOB_V2
+    bufsize = skb->len + lp->dev_elem->header + lp->dev_elem->trailer;
+#else
+    bufsize = skb->len + lp->dev_desc->header + lp->dev_desc->trailer;
+#endif
+    if ((newskb = dev_alloc_skb (bufsize)) == NULL)
+	return NULL;
+
+    /* reserve head room */
+#ifdef BLOB_V2
+    skb_reserve (newskb, lp->dev_elem->header);
+#else
+    skb_reserve (newskb, lp->dev_desc->header);
+#endif
+
+    /* set the tail pointer and length */
+    skb_put(newskb, skb->len);
+
+    /* copy the data */
+    memcpy(newskb->data, skb->data, skb->len);
+    newskb->priority = skb->priority;
+
+    newskb->dev = dev;
+    return newskb;
+}
+
+/**********************************************************************
+ *  llc_to_wlan
+ *
+ *  DESCRIPTION: Converts the ethernet LLC frame to SNAP for WLAN
+ *
+ *  PARAMETERS:	 skb - buffer with ethernet frame to be converted
+ *
+ *  RETURN:	 Nothing.
+ *
+ **********************************************************************/
+/*
+ * The conversion of frames is removed from MVC v2
+ *
+ */
+#ifdef BLOB_V2
+static int llc_to_wlan (struct sk_buff *skb)
+{
+    unsigned int ethertype;
+
+    DEBUG((DBG_FUNC_CALL | DBG_FRAME), "llc_to_wlan, skb %p\n", skb);
+
+    ethertype = (unsigned int) ((skb->data[0] << 8) | skb->data[1]);
+
+    /*
+        Ethertype check should be 1500, but with 802.1Q it is possible that frames are
+        actually longer than 1500 bytes and thus regarded as ethertype frames. 1536 leaves
+        enough space for long frames and 1536 (XEROX NS IDP) is the first registered ethertype
+    */
+    if( ethertype >= 1536 )
+    {
+        DEBUG((DBG_FRAME), "llc_to_wlan, Ethernet II type %04x, converting to SNAP\n", ethertype);
+
+        /*
+            Make room for LLC (3 bytes) and for OUI field (3 bytes) of SNAP header.
+            Leave SNAP Type field unchanged.
+        */
+        skb_push(skb, 6);
+
+        /* LLC */
+        skb->data[0] = 0xAA; /* DSAP (1 byte) */
+        skb->data[1] = 0xAA; /* SSAP (1 byte) */
+        skb->data[2] = 0x03; /* Control (1 byte) */
+
+        /* SNAP */
+        skb->data[3] = 0x00; /* OUI (3 bytes) */
+        skb->data[4] = 0x00;
+
+        /*
+            Consult the Selective Translation Table (802.1H), which contains
+            ethernet types 8137 and 80F3
+        */
+        if( ethertype == 0x8137 || ethertype == 0x80F3 )
+            /* Bridge tunnel encapsulation */
+            skb->data[5] = 0xF8;
+        else
+            skb->data[5] = 0x00;
+    }
+    else
+    {
+        DEBUG((DBG_FRAME), "llc_to_wlan, Length %04x, Found 802.2, 802.3 or SNAP [%02x%02x]\n",
+            ethertype, skb->data[2], skb->data[3] );
+
+        /* Remove the length field from the skb. */
+        skb_pull(skb, 2);
+    }
+
+    return 0;
+}
+#endif
+
+/**********************************************************************
+ *  wlan_to_llc
+ *
+ *  DESCRIPTION: Converts the WLAN (SNAP) frame to ethernet LLC
+ *
+ *  PARAMETERS:	 skb - buffer with WLAN frame
+ *
+ *  RETURN:	 Nothing.
+ *
+ **********************************************************************/
+/*
+ * The conversion of frames is removed from MVC v2
+ *
+ */
+#ifdef BLOB_V2
+static int wlan_to_llc (struct sk_buff *skb)
+{
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME), "wlan_to_llc, frame %p, skb %p\n", framep, skb);
+
+    /*
+        802.1H: Check whether the WLAN frame has a SNAP header.
+        SNAP can always be converted to Ethernet II except for the protocols
+        in the Selective Translation Table
+    */
+    if( (skb->data[0] == 0xAA) && (skb->data[1] == 0xAA) && (skb->data[2] == 0x03) &&
+        (skb->data[3] == 0x00) && (skb->data[4] == 0x00) &&
+        ((skb->data[5] == 0x00) || (skb->data[5] == 0xF8)))
+    {
+        /*  Check the Selective Translation Table */
+        if( ((skb->data[6] == 0x81) && (skb->data[7] == 0x37)) ||
+            ((skb->data[6] == 0x80) && (skb->data[7] == 0xF3)) )
+        {
+            /* Check also the Bridge Tunnel Encapsulation */
+            if( skb->data[5] == 0xF8 )
+            {
+                /*
+                    Remove LLC (3 bytes) + OUI field (3 bytes) of SNAP header.
+                    Don't remove the type field (2 bytes) of the SNAP header.
+                */
+                skb_pull(skb, 6);
+            }
+            else
+            {
+                /*  Add the length of the buffer */
+                skb_push( skb, 2);
+                skb->data[0] = (unsigned char) ((skb->len-2)>>8);
+                skb->data[1] = (unsigned char) (skb->len-2);
+            }
+        }
+        else
+        {
+            /*
+                Remove LLC (3 bytes) + OUI field (3 bytes) of SNAP header.
+                Don't remove the type field (2 bytes) of the SNAP header.
+            */
+            skb_pull(skb, 6);
+        }
+
+        DEBUG((DBG_FRAME), "wlan_to_llc, Removed SNAP header, Ethertype still present\n");
+
+    }
+    else
+    {
+        DEBUG((DBG_FRAME), "wlan_to_llc, Ethertype %02x%02x, preappend Length %04x\n",
+            skb->data[0], skb->data[1], skb->len );
+
+        /*  Preappend the length of the buffer */
+        skb_push( skb, 2);
+        skb->data[0] = (unsigned char) ((skb->len-2)>>8);
+        skb->data[1] = (unsigned char) (skb->len-2);
+    }
+
+    return 0;
+}
+#endif
+
+/****************************************************************
+*								*
+*    		End of frame handling block                     *
+*               (driver configurator module)			*
+*								*
+***************************************************************/
+
+
+/****************************************************************
+ *								*
+ *    		End of driver configurator functions		*
+ *								*
+ ***************************************************************/
+
+/**********************************************************************
+ *  local_set_mac_addr
+ *
+ *  DESCRIPTION: This sets/changes the MAC address on the interface.
+ *               A MAC address containing all zeroes is used to reset
+ *               the MAC address to it's default.
+ *
+ *  PARAMETERS:	 dev  - pointer to a linux net device struct.
+ *               addr - pointer to new MAC address
+ *
+ *  RETURN:	 0 on succes.
+ *               -EINVAL on error.
+ *
+ **********************************************************************/
+#ifdef HAVE_SET_MAC_ADDR
+static int local_set_mac_addr(struct net_device *dev, void *addr)
+{
+    unsigned char mac_addr[ETH_ALEN];
+    unsigned char mac_null_addr[ETH_ALEN];
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "local_set_mac_addr, dev %s, addr %s \n", dev->name, (char*) addr);
+
+    memcpy(mac_addr, addr, ETH_ALEN);
+    memset(mac_null_addr, 0, ETH_ALEN);
+
+    /* A MAC address containing all zeroes is used to reset the MAC address to it's default. */
+    if (memcmp(mac_addr, mac_null_addr, ETH_ALEN) == 0)
+    {
+
+        /* Get the MAC address from the PDA. Function returns pointer to MACAddress. */
+        memcpy(mac_addr, pda_get_mac_address(), ETH_ALEN);
+
+        if (mac_addr == NULL)
+        {
+            printk(KERN_ERR "Couldn't get MAC address for %s from PDA...\n", dev->name);
+            return -EINVAL;
+        }
+    }
+
+    /* We don't allow multicast/broadcast MAC addresses. */
+    if (mac_addr[0] & 1)
+        return -EINVAL;
+
+    /* Send a message to the MVC that we want to use this MAC address... */
+    if (islmvc_send_mvc_msg(dev, OPSET, GEN_OID_MACADDRESS, (long*)mac_addr, ETH_ALEN) < 0);
+    {
+        printk("local_set_mac_addr, couldn't change MAC address %s for dev %s ",
+               hwaddr2string(mac_addr), dev->name);
+        return -EINVAL;
+    }
+
+    /* Okay, we succeeded, so use this MAC address from now on... */
+    memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
+    DEBUG(DBG_MGMT, "MAC address changed to %s. ", hwaddr2string(mac_addr));
+
+    return 0;
+}
+#endif /* HAVE_SET_MAC_ADDR */
+
+
+/**********************************************************************
+ *  local_net_get_stats
+ *
+ *  DESCRIPTION: Get the current statistics.
+ *               This may be called with the card open or closed.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 struct net_device stats pointer
+ *
+ **********************************************************************/
+static struct net_device_stats *local_net_get_stats(struct net_device *dev)
+{
+    long mvc_errors;
+
+    int dev_nr = GET_DEV_NR(dev->base_addr) - 1;
+    static long old_rx_failed[3]  = { 0, 0, 0 };
+    static long old_rx_dropped[3] = { 0, 0, 0 };
+
+    struct net_local *lp = (struct net_local *)dev->priv;
+    struct net_device_stats *stats = &lp->stats;
+
+    _DEBUG(DBG_FUNC_CALL | DBG_MGMT, "local_net_get_stats, dev %s \n", dev->name);
+
+    /*
+        Most statistics are updated in the driver code.
+        However, we can't update error counters for received packets that
+        were dropped or erroneous, since we don't get those packets from the MVC.
+        So, we ask the MVC for those errors...
+    */
+    if (!islmvc_send_mvc_msg(dev, OPGET, GEN_OID_MSDURXFAILED, &mvc_errors, sizeof(long))) {
+        stats->rx_errors += (mvc_errors - old_rx_failed[dev_nr]); /* Only add the difference from the previous count. */
+        old_rx_failed[dev_nr] = mvc_errors;
+    }
+
+    if (!islmvc_send_mvc_msg(dev, OPGET, GEN_OID_MSDURXDROPPED, &mvc_errors, sizeof(long))) {
+        stats->rx_dropped += (mvc_errors - old_rx_dropped[dev_nr]); /* Only add the difference from the previous count. */
+        old_rx_dropped[dev_nr] = mvc_errors;
+    }
+
+    return stats;
+}
+
+
+
+/***************************************************************
+*								*
+*    		Start of local debugging functions  		*
+*								*
+***************************************************************/
+
+#if (NET_DEBUG & (DBG_TX | DBG_RX | DBG_ERROR))
+/**********************************************************************
+ *  dbg_print_frame
+ *
+ *  DESCRIPTION: Print the fields of prism frame 'framep' and the data.
+ *
+ *  PARAMETERS:	 framep - pointer to a prism frame
+ *
+ *  RETURN:	 Nothing.
+ *
+ **********************************************************************/
+static void dbg_print_frame (struct msg_frame *framep)
+{
+    int offset;
+    struct sk_buff *skb;
+
+    skb = framep->handle;
+    printk ("framep: size %d, status %d, mpdu %p, skb->data %p, skb %p, skb->len %d \n",
+	    framep->size, framep->status, framep->mpdu, skb->data, skb, skb->len);
+    printk ("pr_frame: skb->head %p, skb->tail %p, skb->dev->name %s \n",
+            skb->head, skb->tail, skb->dev->name);
+    for (offset = 0; offset < framep->size; offset++)
+	printk ("%02X ", framep->mpdu[offset]);
+    printk ("\n");
+}
+#endif /* (NET_DEBUG & (DBG_TX | DBG_RX | DBG_ERROR)) */
+
+
+#if (NET_DEBUG & DBG_SKB)
+/**********************************************************************
+ *  dbg_frame_filter_check
+ *
+ *  DESCRIPTION: Filter frames not of interest for the Linux IP stack.
+ *		 (unicasts not containing our MAC address and Intersil
+ *		 debug frames). Perform some checks on the frame and
+ *		 print warnings if something suspious is found.
+ *
+ *  PARAMETERS:	 dev    - pointer to a linux net device struct.
+ *		 framep - pointer to the received prism frame
+ *
+ *  RETURN:	 0 if the frame is absorbed by this function, otherwise 1.
+ *
+ **********************************************************************/
+static int dbg_frame_filter_check (struct net_device *dev, struct msg_frame *framep)
+{
+    struct sk_buff *skb;
+    int offset;
+    unsigned char *src;
+    int mtu;
+
+    /* filer out unicast frames not directed to our MAC address */
+    if ((framep->mpdu[0] & 0x01) == 0)
+    {
+	for (offset = 0; offset < ETH_ALEN; offset++)
+	{
+	    if (framep->mpdu[offset] != dev->dev_addr[offset])
+	    {
+		dev_free_frame (dev, framep);
+		return 0;
+	    }
+	}
+    }
+
+    /* filer out Intersil debug frames */
+    if ((framep->mpdu[12] == 0x88) && (framep->mpdu[13] == 0x27))
+    {
+	dev_free_frame (dev, framep);
+	return 0;
+    }
+
+    skb = framep->handle;
+
+    /* first map pointer back in 0x08000000 area */
+#ifdef TEST_ON_POLDHU
+    MAP_UNCACHED((unsigned)framep->mpdu);
+#endif /* TEST_ON_POLDHU */
+
+    /* determine shift in framep->mpdu between add and rx */
+    offset = framep->mpdu - skb->data;
+
+    if (offset)
+    {
+	printk ("frame_to_skb: blob changed mpdu: %d!!!\n", offset);
+	dbg_print_frame (framep);
+    }
+    if (skb_tailroom (skb) < framep->size)
+	printk ("frame_to_skb: NOT enough room!! need %d, tailroom %d, len %d\n",
+		framep->size, skb_tailroom (skb), skb->len);
+
+#ifdef BLOB_V2
+    mtu = ((struct net_local *)dev->priv)->dev_elem->mtu;
+#else
+    mtu = ((struct net_local *)dev->priv)->dev_desc->mtu;
+#endif
+    offset = dbg_check_area (skb->head, framep->mpdu - skb->head, "header");
+    for (src = skb->end-1; (*src == 0) && (src > framep->mpdu+mtu); src--)
+	;
+    if (src > framep->mpdu+mtu)
+    {
+	dbg_check_area (framep->mpdu+mtu, (src - framep->mpdu+mtu) + 1, "trailer");
+	offset = 1;
+    }
+    if (offset)
+	dbg_print_frame (framep);
+    return 1;
+}
+
+
+/**********************************************************************
+ *  dbg_dump_hex_assci
+ *
+ *  DESCRIPTION: Dump the content of buffer 'buf' to the screen. The
+ *		 data is presented in hexadecimal and ASSCI form, 16
+ *		 bytes on each line.
+ *
+ *  PARAMETERS:	 buf  - pointer to buffer to display
+ *		 size - size of the buffer
+ *
+ *  RETURN:	 Nothing.
+ *
+ **********************************************************************/
+static void dbg_dump_hex_assci (unsigned char *buf, int size)
+{
+    int linesize, i;
+    unsigned char *p;
+
+    while (size)
+    {
+	linesize = size > 16 ? 16 : size;
+	size -= linesize;
+	for (p = buf, i = 0; i < linesize; i++, p++)
+	    printk (" %02X", *p);
+	for (; i < 17; i++)
+	    printk ("	");
+	for (i = 0; i < linesize; i++, buf++)
+	{
+	    if (*buf > 31 && *buf < 128)
+		printk ("%c", *buf);
+	    else
+		printk (".");
+	}
+	printk ("\n");
+    }
+}
+
+
+/**********************************************************************
+ *  dbg_check_area
+ *
+ *  DESCRIPTION: Check if a memory area contains all zero's. If not,
+ *		 print a warning, the address that isn't zero and dump
+ *		 the content of the rest of the area on the screen.
+ *
+ *  PARAMETERS:	 p	   - start address of the area to check
+ *		 size	   - size of the area
+ *		 area_name - name of the area that is displayed in the
+ *			     warning message
+ *
+ *  RETURN:	 0 if the whole area contains zero's, otherwise 1.
+ *
+ **********************************************************************/
+static int dbg_check_area (unsigned char *p, int size, char *area_name)
+{
+    while (size)
+    {
+	if (*p)
+	{
+	    printk ("WARNING: %s changed at %p!\n", area_name, p);
+	    dbg_dump_hex_assci (p, size);
+	    return 1;
+	}
+	p++;
+	size--;
+    }
+    return 0;
+}
+#endif /* (NET_DEBUG & DBG_SKB) */
+
+#if (NET_DEBUG & DBG_FRAME_SANITY)
+
+#define LINUX_VALID_ADDR(addr)  ((unsigned long)addr > 0x00040000 && (unsigned long)addr < 0x00800000)
+
+/**********************************************************************
+ *  check_frame_skb
+ *
+ *  DESCRIPTION: Do some sanity checking on the frame. This function
+ *               checks if the pointers and lengths are in a valid range.
+ *
+ *  PARAMETERS:	 framep	   - pointer to frame struct to check.
+ *		 file	   - name of the file the function was called from.
+ *		 line      - line number from wich this function is called.
+ *
+ *  RETURN:	 0 if the whole area contains zero's, otherwise 1.
+ *
+ **********************************************************************/
+static void check_frame_skb(struct msg_frame *framep, char *file, int line)
+{
+        struct sk_buff *skb;
+        int err = 0;
+        int print_size;
+
+        if(!LINUX_VALID_ADDR(framep)) {
+                printk("check_frame_skb (%s:%d): illegal framep %p\n", file, line,
+                        framep);
+                err = 1;
+        }
+
+        if(!LINUX_VALID_ADDR(framep->handle)) {
+                printk("check_frame_skb (%s:%d): illegal framep->handle %p\n", file, line,
+                        framep->handle);
+                err = 1;
+        }
+
+        if(!LINUX_VALID_ADDR(framep->mpdu)) {
+                printk("check_frame_skb (%s:%d): illegal framep->mpdu %p\n", file, line,
+                        framep->mpdu);
+                err = 1;
+        }
+
+        skb = framep->handle;
+
+        if(!LINUX_VALID_ADDR(skb->head)) {
+                printk("check_frame_skb (%s:%d): illegal skb->head %p\n", file, line,
+                        skb->head);
+                err = 1;
+        }
+
+        if(!LINUX_VALID_ADDR(skb->tail)) {
+                printk("check_frame_skb (%s:%d): illegal skb->tail %p\n", file, line,
+                        skb->tail);
+                err = 1;
+        }
+
+        if(!LINUX_VALID_ADDR(skb->data)) {
+                printk("check_frame_skb (%s:%d): illegal skb->data %p\n", file, line,
+                        skb->data);
+                err = 1;
+        }
+
+        if(skb->len > 1600 || framep->size > 1600) {
+                printk("check_frame_skb (%s:%d): illegal length skb->len %d framep->len %d\n",
+                        file, line, skb->len, framep->size);
+                err = 1;
+        }
+
+        if(err) {
+                int offset;
+
+                printk ("framep: size %d, status %d, mpdu %p, skb %p\n",
+                        framep->size, framep->status, framep->mpdu, skb);
+                printk ("skb->head %p, skb->data %p, skb->tail %p, skb->len %d, skb->dev->name %s \n",
+                        skb->head, skb->data, skb->tail, skb->len, skb->dev->name);
+
+                if(framep->size < 20)
+                        print_size = 20;
+                else if(framep->size > 1600)
+                        print_size = 1600;
+                else
+                        print_size = framep->size;
+
+                for (offset = 0; offset < print_size; offset++)
+                        printk ("%02X ", framep->mpdu[offset]);
+                printk ("\n");
+
+                __bug(file, line, NULL);
+        }
+}
+
+#endif /* (NET_DEBUG & DBG_FRAME_SANITY) */
+
+
+/***************************************************************
+*								*
+*    		End of local debugging functions  		*
+*								*
+***************************************************************/
+
diff -urN linux-2.4.29/drivers/net/intersil/islmvc_dev.c-ap linux-2.4.29-uc1/drivers/net/intersil/islmvc_dev.c-ap
--- linux-2.4.29/drivers/net/intersil/islmvc_dev.c-ap	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islmvc_dev.c-ap	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,2700 @@
+/*  $Header$
+ *
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+/*
+ *  Intersil Ethernet driver for MVC v2.
+ *
+ *  Based on skeleton ethernet driver by Donald Becker.
+ *  Based on previous prism ethernet driver by M Schipper 2001.
+ *
+ *  Extended by WSM, Intersil 2002-2003.
+ *
+ *  Copyright 1993 United States Government as represented by the
+ *  Director, National Security Agency.
+ *  Copyright (C) 2001-2003 Intersil Americas Inc.
+ */
+
+
+/* Include files */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <asm/irq.h>
+#include <asm/arch/intctl.h> /* for uIRQ */
+
+/* Intersil include files */
+#include <linux_mvc_oids.h>
+#include <asm/arch/blobcalls.h>
+#include "islmvc.h"
+#include "isl_mgt.h"
+#include "islmvc_mgt.h"
+#include "isl_wds.h"
+
+#ifdef TEST_ON_POLDHU
+#include <asm/arch/serial.h>
+#include <asm/arch/gpio.h>
+#endif /* TEST_ON_POLDHU */
+
+/* End of include files */
+
+/* DEFINES */
+
+#define REQ_UNKNOWN (REQFRAMERX & REQFRAMERETURN & REQTRAP & REQFRAMEADD & REQSERVICE)
+
+/* STATES */
+#define PRISM_ETH_STOP  0
+#define PRISM_ETH_HALT  1
+#define PRISM_ETH_START 2
+#define PRISM_ETH_RUN   3
+
+/* defines for cache mask */
+#ifdef TEST_ON_POLDHU
+#define PRISM_CACHE_MASK 0x04000000
+#endif /* TEST_ON_POLDHU */
+
+/* DEFINES */
+/* Number of TX retries */
+#define TX_NR_RETRIES	10
+
+/* Offset in RAM between cache-able and non-cache-able RAM
+   point to the same physical RAM location. */
+#ifdef TEST_ON_POLDHU
+#define MAP_CACHED(data)   (data |  PRISM_CACHE_MASK)
+#define MAP_UNCACHED(data) (data &=  ~PRISM_CACHE_MASK)
+#endif /* TEST_ON_POLDHU */
+
+static const char *version = "version 0.4.0.0";
+/* The name of the card. Is used for messages and in the requests for irqs */
+static const char* cardname = "Prism Embedded MVC v2 packet IF";
+
+/* Static variable to indicate if a frame add failed. */
+static int frame_add_failed = 0;
+
+/* End of defines */
+
+/* Probe function is called from Space.c */
+int prism_mvc_probe(struct net_device *dev);
+
+#ifdef TEST_ON_POLDHU
+extern const unsigned char *blobtool_find_element(int id, int skip);
+#endif
+
+extern unsigned int src_seq;
+
+/* Start of local mvc prototypes */
+static int prism_eth_init(struct net_device *dev, int startp);
+static int prism_eth_start ( struct net_device *dev );
+static int prism_eth_run ( struct net_device *dev );
+static int local_net_open(struct net_device *dev);
+static void local_net_tx_timeout(struct net_device *dev);
+static int local_net_send_packet(struct sk_buff *skb, struct net_device *dev);
+static void local_net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static int local_net_close(struct net_device *dev);
+static inline void local_dev_handle_reqs(struct net_device *dev, int requests);
+
+/* Start of frame prototypes */
+static int  alloc_frame_pool(struct net_local *lp);
+static inline void req_frame_rx(struct net_device *dev);
+static inline void req_frame_return(struct net_device *dev);
+static inline void req_trap_handling(struct net_device *dev);
+static inline void req_frame_add(struct net_device *dev);
+static inline void req_service(struct net_device *dev);
+inline void copy_wds_to_frame(msg_frame *framep, unsigned char *WDS_Mac);
+static struct msg_frame *skb_to_frame (struct sk_buff *skb);
+static struct sk_buff *frame_to_skb (struct msg_frame *framep);
+static struct sk_buff *dev_copy_expand_skb (struct net_device *dev, const struct sk_buff *skb);
+static inline struct msg_frame *dev_alloc_frame (struct net_device *dev, int size);
+static inline void dev_free_frame (struct net_device *dev, struct msg_frame *frame);
+
+#ifdef BLOB_V2
+static int llc_to_wlan (struct sk_buff *skb);
+static int wlan_to_llc (struct sk_buff *skb);
+#endif
+
+/* Management prototypes */
+static int local_set_mac_addr(struct net_device *dev, void *addr);
+static struct net_device_stats *local_net_get_stats(struct net_device *dev);
+
+/* Begin of debug function prototypes */
+#if (NET_DEBUG & DBG_SKB)
+static int  dbg_frame_filter_check (struct net_device *dev, struct msg_frame *framep);
+static void dbg_dump_hex_assci (unsigned char *buf, int size);
+static int  dbg_check_area (unsigned char *p, int size, char *area_name);
+#endif
+
+#if (NET_DEBUG & (DBG_TX | DBG_RX | DBG_ERROR))
+static void dbg_print_frame (struct msg_frame *framep);
+#endif
+
+#if (NET_DEBUG & DBG_FRAME_SANITY)
+static void check_frame_skb(struct msg_frame *framep, char *file, int line);
+#endif
+
+/* FIXME, temp here for character driver... */
+extern void handle_blob_reqs(void);
+
+static int islmvc_initialized = 0;
+
+/****************************************************************
+ *								*
+ *    		    Begin of functions		                *
+ *								*
+ ***************************************************************/
+
+
+/****************************************************************
+ *								*
+ *    		Begin of driver configurator functions		*
+ *								*
+ ***************************************************************/
+
+
+/**********************************************************************
+ *  prism_mvc_probe
+ *
+ *  DESCRIPTION: Loops through the MVC Information structure trying to find
+ *               the interface that is encoded into the device base_addr.
+ *               The number in the base_addr is mapped to an MVC interface.
+ *               When the device is found, the device structure is initialized,
+ *               the MAC address is read from the PDA and set, the device functions
+ *               are set, the management handlers get initialized and the device
+ *               is put into the READY state.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 0       - when the device is found, initialized and started correctly.
+ *               -ENOMEM - when no memory could be allocated for the device.
+ *               -ENODEV - when the MVC information structure could not be found;
+ *                         when the device is not available;
+ *                         when the MAC address could not be found,
+ *               -EBUSY    when the device could not be started into the READY state.
+ *
+ *  NOTE:        Called from Space.c
+ *
+ **********************************************************************/
+int prism_mvc_probe(struct net_device *dev)
+{
+    int    nr_mvc_devices;  /* Nr of devices present on the MVC. */
+    unsigned char *mac_address;
+
+    char type;
+    int i;
+
+    struct bis_dev_element *dev_elem = NULL;
+    struct bis_dev_descr_element *dev_desc = NULL;
+    struct net_local *lp = NULL;
+    int dev_found = FALSE;
+    static int dev_first_802_3_found = 0;
+
+    islmvc_initialized = 0;
+
+    DEBUG((DBG_FUNC_CALL | DBG_OPEN), "prism_mvc_probe, dev %p, dev->base_addr = %lu \n", dev, dev->base_addr);
+
+    /*
+       We have the following (static) mapping for the devices. This mapping ensures
+       that the devices get the same device name, even when another device isn't available.
+
+       eth0 - LAN ethernet interface. (1)
+       eth1 - WLAN interface. (2)
+       eth2 - WAN ethernet interface. This interface is a hardware option. (3)
+
+       We know for which device this probe function is called because the dev->base_addr
+       is filled in Space.c with the corresponding number.
+    */
+    if (dev->base_addr == 1)      /* Probe for the LAN interface */
+        type = BIS_DT_802DOT3;
+    else if (dev->base_addr == 2) /* Probe for the WLAN interface */
+        type = BIS_DT_802DOT11;
+    else if (dev->base_addr == 3)
+        type = BIS_DT_802DOT3;
+    else
+        return -ENODEV;
+
+    /* Allocate a new 'dev' if needed. */
+    if (dev == NULL)
+    {
+	/*
+	 * Don't allocate the private data here, it is done later
+	 * This makes it easier to free the memory when this driver
+	 * is used as a module.
+	 */
+	dev = init_etherdev(0,0);
+	if (dev == NULL)
+	    return -ENOMEM;
+    }
+
+    /* Get the number of devices available in the MVC. */
+    dev_elem = (struct bis_dev_element *) blobtool_find_element(BIS_DEVS, 0);
+
+    if (!dev_elem)
+    {
+        printk(KERN_ALERT "No dev_element found!!!");
+        return -ENODEV;
+    }
+
+#ifdef BLOB_V2
+    nr_mvc_devices = dev_elem->devs; /* MVC v2 */
+#else
+    nr_mvc_devices = dev_elem->dev;  /* MVC v1 */
+#endif /* TEST_ON_POLDHU */
+
+    DEBUG(DBG_OPEN, "Nr of MVC devices = %i \n", nr_mvc_devices);
+
+    /* Loop through the list and find the types of devices available... */
+    for (i = 0; i < nr_mvc_devices && !dev_found; i++)
+    {
+        dev_desc = (struct bis_dev_descr_element *) blobtool_find_element (BIS_DEVDESCR, i);
+
+        if (!dev_desc)
+        {
+            printk(KERN_ALERT "No dev_desc found!!!");
+            return -ENODEV;
+        }
+
+        /* Let's find out if the MVC accomodates this type... */
+        if (dev_desc->type == type)
+        {
+            /* For the WAN interface, we need the second device, so skip this device when we find the first... */
+            if (dev->base_addr == 1) {
+                dev_first_802_3_found = i;
+            } else if (dev->base_addr == 3 && dev_first_802_3_found == i) {
+                continue;
+            }
+
+            /* The MVC has a device with the right type for us... */
+            DEBUG(DBG_OPEN, "Found MVC device with type nr %i to use for %s \n", i, dev->name);
+
+            /* We (ab) use the base_addr field for storing the device number and device type for later reference. */
+
+            ADD_DEV_TYPE(dev->base_addr, type);
+            ADD_DEV_NR(dev->base_addr, i);
+
+            /* Initialize the device structure. */
+            if (dev->priv == NULL)
+            {
+            	dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+            	if (dev->priv == NULL)
+            	    return -ENOMEM;
+            }
+            memset(dev->priv, 0, sizeof(struct net_local));
+            lp = (struct net_local *)dev->priv;
+
+            lp->wdsp = kmalloc(sizeof(struct wds_priv), GFP_KERNEL);
+            if ( lp->wdsp == NULL)
+                return -ENOMEM;
+            memset(lp->wdsp, 0, sizeof(struct wds_priv));
+
+            /* Set max mtu, head and tail sizes for this MVC packet device */
+#ifdef BLOB_V2
+            lp->maxhead  = (dev_elem->header + 63) & ~3; // extra headspace for zero copy to mini PCI
+            lp->maxtail  = dev_elem->trailer;
+            lp->maxmtu   = dev_elem->mtu;
+
+            lp->maxnrframes = 200; /* FIXME, this should be part of MVC device descr
+            			    * changed to 200 queues in mvc bigger.
+            			    */
+            lp->dev_elem = dev_elem;
+
+            printk( "dev_elem, type %d, mtu %d, head %d, tail %d\n",
+		            dev_desc->type, lp->dev_elem->mtu,
+		            lp->dev_elem->header, lp->dev_elem->trailer);
+#else
+            lp->maxhead  = (dev_desc->header + 63) & ~3; // extra headspace for zero copy to mini PCI
+            lp->maxtail  = dev_desc->trailer;
+            lp->maxmtu   = dev_desc->mtu;
+
+            lp->maxnrframes = 100; /* FIXME, this should be part of MVC device descr */
+            lp->dev_desc = dev_desc;
+
+            printk( "dev_descr, nr %d, type %d, mtu %d, head %d, tail %d\n",
+		            lp->dev_desc->nr, lp->dev_desc->type, lp->dev_desc->mtu,
+		            lp->dev_desc->header, lp->dev_desc->trailer);
+#endif /* BLOB_V2 */
+
+            dev_found = TRUE;
+        }
+    }
+
+    if (!dev_found)
+    {
+        printk("Couldn't find an MVC device type (%ld) for %s \n", dev->base_addr, dev->name);
+        return -ENODEV;
+    }
+    else
+        printk(KERN_INFO "%s: %s %s found,", dev->name, cardname, version );
+
+    /* For both ethernet interfaces (LAN & WAN) and the onboard radio the same MAC address is used.
+       The MAC address of the WAN interface can be changed later to a different MAC address
+       to support MAC cloning for the WAN interface. */
+
+    /* Get the MAC address from the PDA. Function returns pointer to MACAddress. */
+    mac_address = pda_get_mac_address();
+
+    if (mac_address == NULL) /* If we couldn't get the MAC address from the PDA, exit... */
+    {
+        printk(KERN_ERR "Couldn't get MAC address for %s from PDA... aborting... \n", dev->name);
+        kfree(lp);
+        return -ENODEV;
+    }
+
+    memcpy(dev->dev_addr, mac_address, ETH_ALEN);
+    printk("Macaddress = %s\n", hwaddr2string(mac_address));
+
+    dev->open		    = local_net_open;
+    dev->stop		    = local_net_close;
+    dev->get_stats	    = local_net_get_stats;
+    dev->hard_start_xmit    = local_net_send_packet;
+    dev->irq                = IRQ_SOFINT;
+#ifdef HAVE_TX_TIMEOUT
+    dev->tx_timeout	    = local_net_tx_timeout;
+    dev->watchdog_timeo	    = 5 * HZ;
+#endif
+#ifdef HAVE_SET_MAC_ADDR
+    dev->set_mac_address    = local_set_mac_addr;
+#endif
+
+    /* Allocate the frame pool */
+    if (alloc_frame_pool(lp) < 0)
+    {
+        kfree(lp);
+        return -ENOMEM;
+    }
+
+    /* Fill in the fields of the device structure with ethernet values. */
+    ether_setup(dev);
+
+    /* Initialize the management handlers */
+    islmvc_mgt_init(dev);
+
+    /* Let's bring the device in the READY state */
+    if (prism_eth_init( dev, PRISM_ETH_START) < 0 )
+    {
+        kfree(lp);
+        printk(KERN_ERR "Couldn't start device %s \n", dev->name);
+        return -EBUSY;
+    }
+
+    return 0;
+}
+
+
+/**********************************************************************
+ *  prism_eth_init
+ *
+ *  DESCRIPTION: Initialise the MVC device to a specific state.
+ *
+ *  PARAMETERS:	 dev    - pointer to a linux net device struct.
+ * 		 startp - the operation to perform on the MVC
+ *
+ *  RETURN:	 0       - when the device is properly initialized.
+ *               -EBUSY  - when the device is not in the state it should
+ *                         be in, in order to change to the desired state.
+ *               -EINVAL - when the state or device type is not known;
+ *                       - when changing the state did not succeed.
+ *
+ *  NOTE:	 Depending on the current state some values should
+ * 		 possibly be reinitialised in the MVC.
+ *
+ **********************************************************************/
+static int prism_eth_init( struct net_device *dev, int startp )
+{
+    long state;
+#ifdef BLOB_V2
+    struct msg_start start;
+#endif
+
+    long dev_nr = GET_DEV_NR(dev->base_addr);
+    long type   = GET_DEV_TYPE(dev->base_addr);
+    int error   = 0;
+
+    DEBUG(DBG_FUNC_CALL | DBG_OPEN, "prism_eth_init, dev %s, startp %d, (dev_nr = %ld) \n", dev->name, startp, dev_nr);
+
+    state = dev_state (dev_nr);
+    DEBUG(DBG_OPEN, "dev_state, %ld...", state);
+
+    switch (startp)
+    {
+	case PRISM_ETH_STOP:  /* MVC State will end up being STSTOPPED */
+	    /*
+	     * In this case state doesn't really matter,
+	     * if not already stopped stop now!
+	     */
+	    if(state != STSTOPPED)
+	    {
+		DEBUG(DBG_OPEN, "dev_stop...");
+		error = dev_stop (dev_nr);
+	    }
+	break;
+	case PRISM_ETH_HALT:  /* MVC State will end up being STREADY */
+	    /*
+	     * Man can only HALT a device if it's RUNNING.
+	     */
+	    if(state == STRUNNING)
+	    {
+		DEBUG(DBG_OPEN, "dev_halt...");
+		error = dev_halt (dev_nr);
+	    }
+	    else
+	    {
+		error = -EBUSY;
+	    }
+	break;
+	case PRISM_ETH_START: /* MVC State will end up being STREADY */
+	    /*
+	     * Man can only START a device if it's STOPPED.
+             * When it's started for the first time, the state is == BER_UNSUP.
+	     */
+	    if(state == STSTOPPED || state == BER_UNSUP)
+	    {
+            DEBUG(DBG_OPEN, "dev_start...");
+
+#ifdef BLOB_V2
+            /* We can tell the MVC what device number we want to use. Use the one we figured out during the probe... */
+            start.nr    = dev_nr;
+
+            /* Determine the mode to start the device depending on it's type. */
+            if (type == BIS_DT_802DOT11) {
+                start.mode  = MODE_AP;
+            }
+            else if (type == BIS_DT_802DOT3) {
+                start.mode  = MODE_PROMISCUOUS;
+            }
+            else {
+                printk(KERN_ERR "Unknown device type in prism_eth_init.\n");
+                return -EINVAL;
+            }
+
+            error = dev_start(dev_nr, &start);
+#else
+            error = dev_start(dev_nr, MODE_PROMISCUOUS);
+#endif /* BLOB_V2 */
+
+            if (error == BER_NONE)
+                error = prism_eth_start ( dev );
+	    }
+	    else
+	    {
+		DEBUG(DBG_OPEN, "state != STOPPED\n");
+                error = -EBUSY;
+	    }
+	break;
+	case PRISM_ETH_RUN:   /* MVC State will end up being RUNNING */
+	    /*
+	     * Man can only RUN a device if it's READY to run.
+	     */
+	    if(state == STREADY)
+	    {
+		DEBUG(DBG_OPEN, "dev_run...");
+		error = prism_eth_run ( dev );
+		if (error == 0)
+   	            error = dev_run (dev_nr);
+	    }
+	    else
+	    {
+		error = -EBUSY;
+	    }
+	break;
+        default:
+	    error = -EINVAL;
+    }
+    if (error != 0)
+    {
+        DEBUG((DBG_OPEN | DBG_ERROR), "error %d\n", error);
+        return -EINVAL;
+    }
+
+#if (NET_DEBUG & DBG_OPEN)
+    else
+    {
+	state = dev_state (dev_nr);
+	printk ("dev_state changed to %ld...\n", state);
+    }
+#endif
+
+    return 0;
+}
+
+/**********************************************************************
+ *  prism_eth_start
+ *
+ *  DESCRIPTION: This starts the device. It performs the following operations:
+ *                  Sets the device MAC address on the MVC.
+ *                  For a WLAN device, the MLME autonomy mode is set,
+ *                  and some calibration setting are taken from the PDA
+ *                  (Production Data Area) and send to the MVC.
+ *                  The device requests are handled.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 0       - when starting the device succeeded.
+ *               -EINVAL - when setting a setting failed.
+ *
+ **********************************************************************/
+static int prism_eth_start ( struct net_device *dev )
+{
+    int requests;
+    long mode;
+    int error;
+
+    DEBUG(DBG_FUNC_CALL | DBG_OPEN, "prism_eth_start, dev->name %s\n", dev->name);
+
+    /* set the MAC address */
+    if (islmvc_send_mvc_msg(dev, OPSET, GEN_OID_MACADDRESS, (long*)dev->dev_addr, ETH_ALEN) < BER_NONE)
+        return -EINVAL;
+
+    DEBUG(DBG_OPEN, "MAC set..");
+
+    /* for the WLAN device, set the MLME mode (and calibration settings for MVC v2.) */
+    if (GET_DEV_TYPE(dev->base_addr) == BIS_DT_802DOT11)
+    {
+#ifdef BLOB_V2
+        /* Send some calibration values from the PDA to the MVC for MVC v2. */
+        set_rssi_linear_approximation_db(dev);
+        set_zif_tx_iq_calibr_data(dev);
+        set_hw_interface_variant(dev);
+
+        mode = DOT11_MLME_INTERMEDIATE;
+#else
+        mode = DOT11_MLME_SIMPLE;
+#endif
+        if ((error = islmvc_send_mvc_msg(dev, OPSET, DOT11_OID_MLMEAUTOLEVEL, &mode, sizeof(long))) < 0)
+            return -EINVAL;
+
+  	DEBUG(DBG_OPEN, "MLME mode set..");
+
+    }
+
+    /* handle all device requests (= add frames) */
+    while ((requests = dev_reqs (GET_DEV_NR(dev->base_addr))) > BER_NONE)
+    {
+	local_dev_handle_reqs (dev, requests);
+    }
+    DEBUG(DBG_OPEN, "requests handled..\n");
+
+    return 0;
+}
+
+
+/**********************************************************************
+ *  prism_eth_run
+ *
+ *  DESCRIPTION: Empty function.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 0
+ *
+ **********************************************************************/
+static int prism_eth_run ( struct net_device *dev )
+{
+    DEBUG(DBG_FUNC_CALL | DBG_OPEN, "prism_eth_run, dev %s \n", dev->name);
+
+#if (defined(TEST_ON_POLDHU) && !defined(CONFIG_FREE_WLAN_PINS))
+    /* if we are starting the WLAN device, then... */
+    if (GET_DEV_TYPE(dev->base_addr) == BIS_DT_802DOT11)
+    {
+	/* don't disable the UART completely, this crashes the system ?! */
+	uUART->CR &= ~0x78;	/* disable UART interrupts */
+	/* make the UART pins free for the radio */
+	uGPIO->FSEL = (GPIOFSELUARTTx | GPIOFSELUARTRx) << 16;
+    }
+#endif /* TEST_ON_POLDHU && CONFIG_FREE_WLAN_PINS */
+
+    return 0;
+}
+
+#define MAX_DEVICES 16
+
+struct mvc_irq_table
+{
+    int num_devs;
+    struct net_device *dev_ptr[MAX_DEVICES];
+    int dev_nr[MAX_DEVICES];
+};
+
+
+/**********************************************************************
+ *  register_mvc_irq
+ *
+ *  DESCRIPTION: This registers the device to the internal device list.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 pointer to the irq table on success.
+ *               NULL when unable to register the device.
+ *
+ **********************************************************************/
+struct mvc_irq_table *register_mvc_irq(struct net_device *dev)
+{
+    unsigned long flags;
+
+    struct net_local *lp = (struct net_local *) dev->priv;
+
+    static struct mvc_irq_table stat_irq_table =
+        { 0, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } };
+
+    DEBUG(DBG_FUNC_CALL | DBG_OPEN, "register_mvc_irq %s\n", dev->name);
+
+    if (dev == NULL)
+        return NULL;
+
+    if (stat_irq_table.num_devs >= MAX_DEVICES)
+        return NULL;
+
+    save_flags_cli (flags);
+
+    stat_irq_table.dev_ptr[stat_irq_table.num_devs] = dev;
+    stat_irq_table.dev_nr[stat_irq_table.num_devs] = GET_DEV_NR(dev->base_addr);
+    stat_irq_table.num_devs++;
+
+    restore_flags(flags);
+
+    lp->mvcirq_table = &stat_irq_table;
+
+    return &stat_irq_table;
+
+}
+
+
+/**********************************************************************
+ *  unregister_mvc_irq
+ *
+ *  DESCRIPTION:  This unregisters the device from the internal device
+ *                list.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 0      - on success,
+ *               -1     - when unable to unregister the device.
+ *
+ **********************************************************************/
+int unregister_mvc_irq(struct net_device *dev)
+{
+    int i;
+    unsigned long flags;
+
+    int j = 0;
+    struct net_local *lp = (struct net_local *) dev->priv;
+
+    DEBUG(DBG_FUNC_CALL | DBG_OPEN, "unregister_mvc_irq %s\n", dev->name);
+
+    if (dev == NULL) {
+        printk("unregister_mvc_irq: dev == NULL, can't unregister.\n");
+        return -1;
+    }
+
+    save_flags_cli (flags);
+
+    for (i=0; i < MAX_DEVICES; i++) {
+        if (lp->mvcirq_table->dev_ptr[i] == dev) {
+            j++;
+        }
+
+        lp->mvcirq_table->dev_ptr[i] = lp->mvcirq_table->dev_ptr[j];
+        lp->mvcirq_table->dev_nr[i] = lp->mvcirq_table->dev_nr[j];
+        j++;
+    }
+
+    lp->mvcirq_table->num_devs--;
+
+    restore_flags(flags);
+
+    return 0;
+}
+
+
+
+/**********************************************************************
+ *  local_net_open
+ *
+ *  DESCRIPTION:  Open/initialize the board. This is called (in the current kernel)
+ *                sometime after booting when the 'ifconfig' program is run.
+ *                This routine should set everything up anew at each open, even
+ *                registers that "should" only need to be set once at boot, so that
+ *                there is non-reboot way to recover if something goes wrong.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 0      - on success,
+ *               -EBUSY - when unable to get IRQ or setting the device into
+ *                        running mode.
+ *
+ **********************************************************************/
+
+
+static int local_net_open(struct net_device *dev)
+{
+    long linkstate;
+
+    int retval = 0;
+
+#ifdef BLOB_V2
+    struct mvc_irq_table *irq_table = NULL;
+#endif
+
+    DEBUG(DBG_FUNC_CALL | DBG_OPEN, "local_net_open %s\n", dev->name);
+
+    /* Reset the hardware and set the card MAC address. */
+    if (prism_eth_init(dev, PRISM_ETH_RUN) < 0)
+    {
+        printk("Couldn't reset hardware \n");
+        return -EBUSY;
+    }
+
+    netif_start_queue (dev);
+
+#ifdef BLOB_V2
+    /* Register the IRQ in the mvc irq table. */
+    if ((irq_table = register_mvc_irq(dev)) == NULL) {
+        printk(KERN_ERR "Registering the IRQ in the internal table failed.\n");
+        return -EBUSY;
+    }
+
+    /* Dispatching the IRQ for the different devices is done in the local net interrupt function,
+       so we register the IRQ only once now. Still use SA_SHIRQ, as it's possible that another device
+       then the one we registered under frees the IRQ. */
+    if (irq_table->num_devs == 1)
+        retval = request_irq(dev->irq, &local_net_interrupt, SA_SHIRQ | SA_INTERRUPT, dev->name, irq_table);
+#else
+    retval = request_irq(dev->irq, &local_net_interrupt, SA_SHIRQ | SA_INTERRUPT,
+		    dev->name, dev);
+#endif
+
+    if (retval) {
+	printk("%s: unable to get IRQ %d (retval=%d).\n",
+	       dev->name, dev->irq, retval);
+	netif_stop_queue (dev);
+        unregister_mvc_irq(dev);
+        return -EBUSY;
+    }
+
+    /* determine initial linkstate for Ethernet interface (LAN or WAN) */
+    if (GET_DEV_TYPE(dev->base_addr) == BIS_DT_802DOT3) {
+        islmvc_send_mvc_msg(dev, OPGET, GEN_OID_LINKSTATE, &linkstate, sizeof(long));
+        if (linkstate == 0) {
+            netif_carrier_off(dev);
+        }
+    }
+
+    /* If the current device is host device for WDS devices, bring the WDS devices up and running. */
+    if (GET_DEV_TYPE(dev->base_addr) == BIS_DT_802DOT11)
+        open_wds_links(((struct net_local *)dev->priv)->wdsp);
+
+    return 0;
+}
+
+
+/**********************************************************************
+ *  local_net_tx_timeout
+ *
+ *  DESCRIPTION: Called when the kernel signals a tx timeout.
+ *               This functions checks the linkstate of the device.
+ *               If the link is down, the carrier flag of the devive is
+ *               put down.
+ *               If the link is not reported down, the interface is resetted.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:      Nothing.
+ *
+ **********************************************************************/
+#ifdef HAVE_TX_TIMEOUT
+static void local_net_tx_timeout(struct net_device *dev)
+{
+    long linkstate;
+
+    struct net_local *lp = (struct net_local *)dev->priv;
+
+    DEBUG(DBG_FUNC_CALL | DBG_TX, "local_net_tx_timeout, dev %s \n", dev->name);
+
+    islmvc_send_mvc_msg(dev, OPGET, GEN_OID_LINKSTATE, &linkstate, sizeof(long));
+
+    if (linkstate == 0)
+    {
+	printk(KERN_WARNING "%s: link down, network cable problem?\n", dev->name);
+
+	netif_carrier_off (dev);
+    }
+    else
+    {
+	
+	printk(KERN_WARNING "%s: reset interface\n", dev->name);
+
+	/* Try to restart the device. */
+	prism_eth_init(dev, PRISM_ETH_HALT);
+        prism_eth_init(dev, PRISM_ETH_RUN);
+	lp->stats.tx_errors++;
+        netif_wake_queue(dev);
+    }
+}
+#endif /* HAVE_TX_TIMEOUT */
+
+
+/**********************************************************************
+ *  local_net_send_packet
+ *
+ *  DESCRIPTION: This function puts an skbuf into an MVC frame,
+ *               updates the statistics and sends the frame to the local MVC.
+ *
+ *  PARAMETERS:	 skb - pointer to a linux packet buffer.
+ *               dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 0
+ *
+ **********************************************************************/
+static int local_net_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+    //FIXME, still needed for MVC v2?
+    static int tries = 1000000; /* give the first packet a lot of retries */
+
+    unsigned char *src;
+    struct sk_buff *skb2;
+    struct msg_frame *framep;
+    int error;
+    int WDSLink;
+    long linkstate;
+    unsigned char WDS_Mac[ETH_ALEN];
+
+    struct net_local *lp = (struct net_local *)dev->priv;
+    long dev_nr = GET_DEV_NR(dev->base_addr);
+
+    DEBUG((DBG_FUNC_CALL | DBG_TX), "local_net_send_packet, skb %p, dev %s \n", skb, dev->name);
+
+    /* If this skb came from a WDS device, the
+       skb->cb field will be filled with a WDSLink MACaddress.
+       Since the skb->cb field won't be cloned, we check it here. */
+    WDSLink = check_skb_for_wds(skb, WDS_Mac);
+
+    /* if the head or tail room doesn't comply with the device or
+       the skb is cloned .. */
+#ifdef BLOB_V2
+    if (skb_headroom (skb) < lp->dev_elem->header ||
+	skb_tailroom (skb) < lp->dev_elem->trailer ||
+	skb_cloned (skb))
+#else
+    if (skb_headroom (skb) < lp->dev_desc->header ||
+        skb_tailroom (skb) < lp->dev_desc->trailer ||
+        skb_cloned (skb))
+#endif
+    {
+#if (NET_DEBUG & DBG_TX)
+        if (!skb_cloned (skb))
+	{
+            DEBUG(DBG_TX, "no head/tail room, head:(%d,%d),tail(%d,%d)..",
+		skb_headroom (skb), lp->dev_elem->header,
+		skb_tailroom (skb), lp->dev_elem->trailer);
+	}
+#endif
+
+        /* see if we can shift the data in the buffer */
+	if (!skb_cloned (skb) &&
+	    skb_headroom (skb) + skb_tailroom (skb) >=
+#ifdef BLOB_V2
+            lp->dev_elem->header + lp->dev_elem->trailer)
+#else
+            lp->dev_desc->header + lp->dev_desc->trailer)
+#endif
+	{
+
+#ifdef BLOB_V2
+            DEBUG(DBG_TX, "shift data: %d..", lp->dev_elem->header - skb_headroom (skb));
+#else
+            DEBUG(DBG_TX, "shift data: %d..", lp->dev_desc->header - skb_headroom (skb));
+#endif
+
+	    src = skb->data;
+#ifdef BLOB_V2
+            skb_reserve (skb, lp->dev_elem->header - skb_headroom (skb));
+#else
+            skb_reserve (skb, lp->dev_desc->header - skb_headroom (skb));
+#endif
+	    memmove (skb->data, src, skb->len);
+            lp->tx_misaligned++;
+
+	}
+	else	/* copy to a new buffer with enough head and tail room */
+	{
+#if (NET_DEBUG & DBG_TX)
+	    if (skb_cloned (skb))
+		printk ("cloned sk_buff.. ");
+	    printk ("copy data.. ");
+#endif
+
+	    skb2 = dev_copy_expand_skb (dev, skb);
+	    dev_kfree_skb (skb);
+	    if (skb2 == NULL)
+            {
+                lp->stats.tx_dropped++;
+		return 0;
+            }
+	    skb = skb2;
+	}
+    }
+
+    if ((framep = skb_to_frame (skb)) == NULL)
+    {
+	DEBUG((DBG_TX | DBG_ERROR), "NO frame!!!\n");
+	dev_kfree_skb (skb);
+	lp->stats.tx_dropped++;
+        return 0;
+    }
+
+    /* send the frame to the local MVC */
+
+    DEBUG(DBG_TX, "send: size %d, headroom %d..", framep->size,
+            skb_headroom (framep->handle));
+#if (NET_DEBUG & DBG_TX)
+    dbg_print_frame( framep );
+#endif
+
+    /* Copy the found WDS MAC address in the msg_frame */
+    if (WDSLink == 1) 
+    	copy_wds_to_frame(framep, WDS_Mac);
+
+    do
+    {
+        error = dev_frame_tx (dev_nr, framep);
+        if (error == BER_OVERFLOW)
+            dev_service (dev_nr); /* Give the device some time to process */
+        tries--;
+    }
+    /* We can do this while:
+     * <BER_ERROR: 	If the frame is not queued.
+     * !BER_DSTUNKN: 	Destination isn't unknown (no need to retry, the 
+     * 			dev will not know it the next time either).
+     * !BER_UNSPEC:	The frame is not allowed by frame class 
+     *			(for instance, data to authenticated but not 
+     *			 associated clients) or by privacy settings
+     *			(for instance, no key installed while exclude
+     *			 unencrypted is set).
+     * tries:		Untill the retry counter is zero.
+     */
+    while (error < BER_NONE &&
+           error != BER_DSTUNKN && 
+           error != BER_UNSPEC && 
+           tries);
+    tries = TX_NR_RETRIES;
+
+    if (error < BER_NONE)
+    {
+    	/* On errors not unreachable or not allowed to send
+    	 * check if the linkstate is down and turn carrier off if so.
+    	 * When the error is queue overflow stop the queue in order
+    	 * to give the device some time to process the full queues.
+    	 * When other tx-ed frames return in the system the queue
+    	 * will be enabled.
+    	 */
+        if (error != BER_DSTUNKN && error != BER_UNSPEC)
+        {
+	    _DEBUG((DBG_TX | DBG_ERROR),
+	           KERN_INFO "TX dev: %s, NOT accepted!!\n", dev->name);
+
+            /* test if the link is down */
+            islmvc_send_mvc_msg(dev, OPGET, GEN_OID_LINKSTATE, &linkstate, sizeof(long));
+            if (linkstate == 0)		        /* Disable carrier and queues ? */
+                netif_carrier_off (dev);
+            else if (error == BER_OVERFLOW)     /* The device queue is full, backoff ! */  
+                netif_stop_queue (dev);
+
+        }
+        /* Count all error codes as dropped */
+	lp->stats.tx_dropped++;
+
+	/* abort the frame */
+	dev_free_frame (dev, framep);
+    }
+    else {
+        DEBUG((DBG_TX | DBG_WDS), "OK!!\n");
+    }
+    dev->trans_start = jiffies;
+ 
+    return 0;
+}
+
+
+/**********************************************************************
+ *  local_net_interrupt
+ *
+ *  DESCRIPTION: The typical workload of the driver:
+ *               Handle the network interface interrupts.
+ *
+ *  PARAMETERS:	 irq    - interrupt number, not used.
+ *               dev_id - pointer to the net_device struct, assigned when
+ *                        the IRQ was registered.
+ *               regs   - Not used.
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:        When frame_add_failed is set, we leave the while loop
+ *               to give the system some time to allocate memory.
+ *
+ **********************************************************************/
+#ifdef BLOB_V2
+static void local_net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+    int			    requests;
+    int                     i;
+    int                     bit;
+    int                     dev_nr;
+    unsigned int            reqs_pending;
+    struct mvc_irq_table    *irq_table;
+    struct net_local        *lp;
+    char                    *irq_stats;
+    struct net_device       *first_dev;
+
+    struct net_device	    *dev = NULL;
+
+    uIRQ->Soft = 0;	    /* remove soft irq */
+
+    DEBUG(DBG_FUNC_CALL | DBG_IRQ, "local_net_interrupt, irq %d, dev_id %p, regs %p \n", irq, dev_id, regs);
+
+    if (dev_id == NULL) {
+	printk(KERN_WARNING "%s: irq %d for unknown device.\n", cardname, irq);
+	return;
+    }
+
+    irq_table = (struct mvc_irq_table*) dev_id;
+
+    /* Get a pointer to the MVC irq stats. */
+    if ((first_dev = irq_table->dev_ptr[0]) == NULL)
+        BUG(); /* Should never happen! */
+
+    lp = (struct net_local*) first_dev->priv;
+    irq_stats = lp->dev_elem->irq_stats;
+
+    reqs_pending = ( (1 << (irq_table->num_devs)) -1);
+
+    /* Reset this variable */
+    frame_add_failed = 0;
+
+    while (reqs_pending && frame_add_failed != 1)
+    {
+        for (i=0; i < irq_table->num_devs; i++)
+        {
+            dev_nr = irq_table->dev_nr[i];
+
+            if (irq_stats[dev_nr]) {
+                irq_stats[dev_nr] = 0;
+                if ((dev = irq_table->dev_ptr[i]) == NULL)
+                    BUG(); /* Should never happen! */
+                if ((requests = dev_reqs(dev_nr)) > BER_NONE)
+                    local_dev_handle_reqs(dev, requests);
+            }
+            else {
+                bit = (1 << i);
+                reqs_pending &= ~bit;
+            }
+        }
+    }
+
+    handle_blob_reqs();
+
+    return;
+}
+
+#else /* !BLOB_V2 */
+
+static void local_net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+    int			requests;
+
+    struct net_device	*dev = NULL;
+
+    uIRQ->Soft = 0;	    /* remove soft irq */
+
+    _DEBUG(DBG_FUNC_CALL | DBG_IRQ, "local_net_interrupt, irq %d, dev_id %p, regs %p \n", irq, dev_id, regs);
+
+    if (dev_id == NULL)
+    {
+	printk(KERN_WARNING "%s: irq %d for unknown device.\n", cardname, irq);
+	return;
+    }
+
+    dev = (struct net_device *) dev_id;
+
+    /* We handle blob requests within the Ethernet device */
+    if (GET_DEV_TYPE(dev-> base_addr) == BIS_DT_802DOT3)
+	handle_blob_reqs();
+
+    /* Reset this variable */
+    frame_add_failed = 0;
+
+    if ((requests = dev_reqs (GET_DEV_NR(dev->base_addr))) > BER_NONE)
+    	local_dev_handle_reqs (dev, requests);
+
+    return;
+}
+
+#endif /* BLOB_V2 */
+
+/**********************************************************************
+ *  local_net_close
+ *
+ *  DESCRIPTION: The inverse routine to local_net_open().
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 0
+ *
+ **********************************************************************/
+static int local_net_close(struct net_device *dev)
+{
+    struct msg_frame *framep;
+
+    long dev_nr = GET_DEV_NR(dev->base_addr);
+    struct net_local *lp = (struct net_local *) dev->priv;
+
+    DEBUG(DBG_FUNC_CALL | DBG_CLOSE, "local_net_close, dev %s \n", dev->name);
+
+    /* If the current device is host device for WDS devices,
+       bring the associated WDS devices DOWN. */
+    if (GET_DEV_TYPE(dev->base_addr) == BIS_DT_802DOT11)
+        close_wds_links(((struct net_local *)dev->priv)->wdsp);
+
+    netif_stop_queue(dev);
+
+    if (dev_halt(dev_nr) >= BER_NONE)
+    {
+        while ((framep = dev_frame_return(dev_nr)) != NULL) {
+            dev_free_frame(dev, framep);
+        }
+    }
+
+    /* Dispatching the IRQ for the different devices is done in the local net interrupt function,
+       so we free the IRQ only for the last device. */
+    if (lp->mvcirq_table->num_devs == 1)
+        free_irq(dev->irq, dev);
+
+    unregister_mvc_irq(dev);
+
+    return 0;
+}
+
+
+/****************************************************************
+ *								*
+ *    		Begin of frame handling block			*
+ *              (driver configurator module)			*
+ *								*
+ ***************************************************************/
+
+
+/**********************************************************************
+ *  req_frame_rx
+ *
+ *  DESCRIPTION: Handle the frame rx requests.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:	 Inline function.
+ *
+ **********************************************************************/
+static inline void req_frame_rx(struct net_device *dev)
+{
+    struct msg_frame        *framep;
+    struct net_device       *wds_dev;
+    struct wds_net_local    *wds_lp;
+    struct sk_buff          *skb;
+
+    struct net_local        *lp = (struct net_local *) dev->priv;
+
+    DEBUG(DBG_IRQ, "..RX");
+
+    while ((framep = dev_frame_rx (GET_DEV_NR(dev->base_addr))) != NULL)
+    {
+        if (GET_DEV_TYPE(dev->base_addr) == BIS_DT_802DOT11)
+        {
+            /* Check if this frame contains one of the WDS addresses */
+#ifdef BLOB_V2
+            wds_dev = wds_find_device(framep->wds, ((struct net_local *)dev->priv)->wdsp);
+#else
+            wds_dev = wds_find_device(framep->wds_link, ((struct net_local *)dev->priv)->wdsp);
+#endif
+        }
+        else
+            wds_dev = NULL;
+
+        dev->last_rx = jiffies;
+        if (framep->size < 1569 && framep->status < 10)
+        {
+
+#if (NET_DEBUG & DBG_RX)
+            dbg_print_frame (framep);
+#endif
+#if (NET_DEBUG & DBG_SKB)
+            if (dbg_frame_filter_check (dev, framep))
+#endif
+            {
+                if ((skb = frame_to_skb (framep)) != NULL)
+                {
+                    skb->protocol = eth_type_trans( skb, dev );
+                    lp->stats.rx_packets++;
+                    lp->stats.rx_bytes += skb->len;
+
+                    /* This will change in the new WDS implementation. */
+                    if (wds_dev != NULL)
+                    {
+                        wds_lp = (struct wds_net_local *) wds_dev->priv;
+                        wds_lp->stats.rx_packets++;
+                        wds_lp->stats.rx_bytes += skb->len;
+                        skb->dev = wds_dev;
+                    }
+                    /* Give the data to the Linux kernel for further processing. */
+                    netif_rx(skb);
+                }
+                else
+                {
+                    /* No valid data in frame. It's dropped.*/
+                    lp->stats.rx_dropped++;
+                }
+            }
+        }
+        else
+            printk (KERN_ERR " RX, size %d, status %d!!\n",
+                    framep->size, framep->status);
+    }
+
+}
+
+
+/**********************************************************************
+ *  req_frame_return
+ *
+ *  DESCRIPTION: Handle the frame return requests.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:	 Inline function.
+ *
+ **********************************************************************/
+static inline void req_frame_return(struct net_device *dev)
+{
+    struct msg_frame    *framep;
+
+    struct net_local        *lp = (struct net_local *) dev->priv;
+
+    while ((framep = dev_frame_return (GET_DEV_NR(dev->base_addr))) != NULL)
+    {
+        _DEBUG(DBG_IRQ, "..RET");
+        if (framep->status <= FSRETURNED) /* Check these defines carefully with frame state defines.  */
+        {
+            if (framep->status <= FSTXSUCCESSFUL)
+            {
+                if (framep->status == FSTXSUCCESSFUL)
+                {
+                    lp->stats.tx_packets++;
+                    lp->stats.tx_bytes += framep->size;
+                }
+                else
+                {
+                    _DEBUG(DBG_TX, " TX error!!. status %d\n",
+                            framep->status);
+                    lp->stats.tx_errors++;
+                }
+                netif_wake_queue (dev);
+            }
+            dev_free_frame (dev, framep);
+        }
+        else
+            printk (KERN_ERR " RET, size %d, status %d!!\n",
+                    framep->size, framep->status);
+    }
+}
+
+
+/**********************************************************************
+ *  req_trap_handling
+ *
+ *  DESCRIPTION: Handle traps from the MVC.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:	 Inline function.
+ *
+ **********************************************************************/
+/*
+ *  The trap handling mechanism is different for Blob V1 and Blob V2.
+ *
+ */
+#ifdef BLOB_V2
+static inline void req_trap_handling(struct net_device *dev)
+{
+    struct msg_conf     trapmsg;
+    int                 dev_grp;
+    int                 dev_nr         = GET_DEV_NR(dev->base_addr);
+    int                 dev_type       = GET_DEV_TYPE(dev->base_addr);
+    unsigned char       *new_buf       = NULL;
+    unsigned char       local_buf[64];
+    long 		led_wlan_config_on  = 5;
+    long 		led_eth_config_on  = 2;
+    long		led_config_off = 0;
+
+    _DEBUG(DBG_IRQ, "..TRAP");
+
+    /* Most traps are the size of an obj_mlme struct or less. If this does not fit the trap size
+       requirement, we are told so and will malloc a new buffer for the trap data. */
+    trapmsg.data = (long*) &local_buf[0];
+    trapmsg.size = sizeof(local_buf);
+
+    /* Get the trap from the MVC... */
+    if (dev_trap (dev_nr, &trapmsg) == BER_OVERFLOW)
+    {
+        /* The size of the buffer we passed was too small. Malloc a new buffer with correct size. */
+        if ((new_buf = kmalloc(trapmsg.size, GFP_ATOMIC)) == NULL)
+        {
+            printk(KERN_ERR "Couldn't malloc new trap buffer. \n");
+            return;
+        }
+
+        trapmsg.data = (long *) new_buf;
+
+        /* Okay, try again... */
+        if (dev_trap (dev_nr, &trapmsg) == BER_OVERFLOW)
+        {
+            printk(KERN_WARNING "Couldn't get trap message for the second time. Stopped trying... \n");
+            return;
+        }
+    }
+
+    /* The Linkstate trap is partly handled in the driver. */
+    if (trapmsg.oid == GEN_OID_LINKSTATE)
+    {
+	if ( *trapmsg.data ) /* LINK State is UP... */
+	{
+	    /* Check the state of the link, and set/clear the corresponding LED accordingly*/
+	    if (islmvc_send_mvc_msg(dev, OPSET, GEN_OID_LEDCONFIG, 
+		    ((dev_type == BIS_DT_802DOT3) ? (long*)&led_eth_config_on : (long*)&led_wlan_config_on), 
+		    sizeof(led_eth_config_on)) < 0)
+		printk("req_trap_handling, couldn't set led config for dev %s\n", dev->name);
+	    printk ("%s: link up\n", dev->name);
+	    netif_carrier_on (dev);
+        }
+	else /* LINK State is DOWN... */
+	{
+	    if (islmvc_send_mvc_msg(dev, OPSET, GEN_OID_LEDCONFIG, (long*)&led_config_off, sizeof(led_config_off)) < 0)
+		printk("req_trap_handling, couldn't set led config 0 for dev %s\n", dev->name);		
+	    printk ("%s: link down\n", dev->name);
+	    netif_carrier_off (dev);
+	}
+    }
+
+    /* Determine the device group based on the device type. */
+    if (dev_type == BIS_DT_802DOT3)
+        dev_grp = DEV_NETWORK_ETH;
+    else if (dev_type == BIS_DT_802DOT11)
+        dev_grp = DEV_NETWORK_WLAN;
+    else
+        dev_grp = 0; /* Unknown device. Use no trapgrp. */
+
+    /* We handle all other traps in the generic part, and also send the GEN_OID_LINKSTATE up */
+    mgt_response( 0, src_seq++, dev_grp, dev->ifindex,
+       PIMFOR_OP_TRAP, trapmsg.oid, trapmsg.data, trapmsg.size);
+
+    /* When we malloced a new buffer, free it here. */
+    if (new_buf)
+        kfree(new_buf);
+}
+
+#else /* !BLOB_V2 */
+
+static inline void req_trap_handling(struct net_device *dev)
+{
+    struct msg_conf     *trapmsg;
+    int                 dev_grp;
+
+    int                 dev_nr      = GET_DEV_NR(dev->base_addr);
+    int                 dev_type    = GET_DEV_TYPE(dev->base_addr);
+
+    _DEBUG(DBG_IRQ, "..TRAP");
+
+    /* Get the trap from the MVC... */
+    if ((trapmsg = dev_trap (dev_nr)) != NULL)
+    {
+        /* This is an embedded MVC specific trap, so we handle it partly here... */
+        if (trapmsg->oid == GEN_OID_LINKSTATE && dev_type == BIS_DT_802DOT3)
+        {
+
+#ifdef TEST_ON_POLDHU
+            /* Set/Clear the Ethernet LED */
+            long mask = 1;
+            struct msg_conf config;
+
+            config.operation = OPSET;
+            config.data = &mask;
+
+            if( *trapmsg->data ) /* LINK State is UP... */
+            {
+                config.oid = BLOB_OID_LEDSET;
+                printk ("%s: link up\n", dev->name);
+                netif_carrier_on (dev);
+            }
+            else                 /* LINK State is DOWN... */
+            {
+                config.oid = BLOB_OID_LEDCLEAR;
+                printk ("%s: link down\n", dev->name);
+                netif_carrier_off (dev);
+            }
+
+            blob_conf( &config ); /* For setting/clearing the led */
+#endif /* TEST_ON_POLDHU */
+        }
+
+        /* Determine the device group based on the device type. */
+        if (dev_type == BIS_DT_802DOT3)
+            dev_grp = DEV_NETWORK_ETH;
+        else if (dev_type == BIS_DT_802DOT11)
+            dev_grp = DEV_NETWORK_WLAN;
+        else
+            dev_grp = 0; /* Unknown device. Use no trapgrp. */
+
+        /* We handle all other traps in the generic part, and also send the GEN_OID_LINKSTATE up */
+        mgt_response( 0, src_seq++, dev_grp, dev->ifindex,
+           PIMFOR_OP_TRAP, trapmsg->oid, trapmsg->data, 100 ); /* No trapsize parameter in BLOB V1 */
+    }
+}
+#endif /* BLOB_V2 */
+
+
+/**********************************************************************
+ *  req_frame_add
+ *
+ *  DESCRIPTION: Add frames to the device. If allocating a frame failed,
+ *               the static variable frame_add_failed is set to 1. We end
+ *               the interrupt service routine when this variable is set,
+ *               to give the system some time to allocate memory.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:	 Inline function.
+ *
+ **********************************************************************/
+static inline void req_frame_add(struct net_device *dev)
+{
+    struct msg_frame    *framep;
+    int                 nr_frames = 1;
+
+    _DEBUG((DBG_IRQ | DBG_FRAME), "..ADD");
+
+    while (nr_frames > 0) {
+        if ((framep = dev_alloc_frame (dev, 0)) != NULL) {
+	    _DEBUG(DBG_IRQ, "dev_alloc_frame returned %p pointer..", framep);
+	    if ((nr_frames = dev_frame_add (GET_DEV_NR(dev->base_addr), framep)) < BER_NONE) {
+	        dev_free_frame(dev, framep);
+	    }
+	}
+	else {
+            _DEBUG(DBG_IRQ, "dev_alloc_frame returned NULL pointer.\n");
+            frame_add_failed = 1;
+            return;
+        }
+    }
+}
+
+/**********************************************************************
+ *  req_service
+ *
+ *  DESCRIPTION: Service the device.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:	 Inline function.
+ *
+ **********************************************************************/
+static inline void req_service(struct net_device *dev)
+{
+    _DEBUG(DBG_IRQ, "..service");
+    dev_service (GET_DEV_NR(dev->base_addr));
+    dev_service (DEVICE_DEBUG); /* We service the debug device here. */
+}
+
+/**********************************************************************
+ *  req_watchdog_handling
+ *
+ *  DESCRIPTION: Watchdog handling the device.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:	 Inline function.
+ *
+ **********************************************************************/
+static inline void req_watchdog_handling(struct net_device *dev)
+{
+    _DEBUG(DBG_IRQ, "..watchdog request");
+    /*
+     * Here one can handle watchdog pending requests. The only device
+     * which watchdog is enabled by default is the BLOB device,
+     * and is handled in islmvc_blob.c.
+     * If you would like to use the watchdog function from any other
+     * device you should change the code here the make this function.
+     * and set the GEN_OID_WACHDOG for that specific device. Using this
+     * mechanism one can proxy watchdog even in user space applications.
+     */
+    //dev_watchdog (GET_DEV_NR(dev->base_addr));
+}
+
+/**********************************************************************
+ *  local_dev_handle_reqs
+ *
+ *  DESCRIPTION: Handle requests 'requests' for device 'dev'.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *		 requests - requests to handle
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:	 Also called from the interrupt service routine.
+ *
+ **********************************************************************/
+static inline void local_dev_handle_reqs(struct net_device *dev, int requests)
+{
+    _DEBUG(DBG_IRQ, "dev_handle_reqs, dev %s, requests %d\n", dev->name, requests);
+
+    if (requests & REQ_UNKNOWN) {
+        printk (" called with unknown requests: %d!!\n", requests);
+        return;
+    }
+    if (requests & REQFRAMERX) {
+        req_frame_rx(dev);
+    }
+    if (requests & REQFRAMEADD) {
+        req_frame_add(dev);
+    }
+    if (requests & REQFRAMERETURN) {
+        req_frame_return(dev);
+    }
+    if (requests & REQSERVICE) {
+        req_service(dev);
+    }
+    if (requests & REQTRAP) {
+        req_trap_handling(dev);
+    }
+    if (requests & REQWATCHDOG) {
+	req_watchdog_handling(dev);
+    }
+}
+
+
+/**********************************************************************
+ *  alloc_frame_pool
+ *
+ *  DESCRIPTION: Allocates a frame pool for the local MVC.
+ *               The frame pool is allocated and the free frame list
+ *               is allocated with these frames.
+ *
+ *  PARAMETERS:	 Pointer to the net_local structure lp.
+ *
+ *  RETURN:	 Zero on success, or -ENOMEM when malloc failed.
+ *
+ **********************************************************************/
+static int alloc_frame_pool(struct net_local *lp)
+{
+    int i;
+
+    DEBUG((DBG_FUNC_CALL | DBG_FRAME), "alloc_frame_pool, lp %p \n", lp);
+
+    /* allocate frame pool */
+    lp->frame_pool = kmalloc(sizeof(struct msg_frame) * lp->maxnrframes,
+ 			    GFP_KERNEL);
+    if (lp->frame_pool == NULL)
+	return -ENOMEM;
+
+    /* add all frames to the free frame list */
+    lp->frame_freelist = NULL;
+    for (i = 0; i < lp->maxnrframes; i++)
+    {
+	lp->frame_pool[i].handle = lp->frame_freelist;
+	lp->frame_freelist = &lp->frame_pool[i];
+    }
+
+    return 0;
+}
+
+/**********************************************************************
+ *  frame_alloc
+ *
+ *  DESCRIPTION: Allocates a frame from the free frames list.
+ *               The wds info in the frame is zeroed.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 framep pointer to allocated frame or NULL when alloc failed.
+ *
+ *  NOTE:        inline function.
+ *
+ **********************************************************************/
+static inline struct msg_frame *frame_alloc (struct net_device *dev)
+{
+    struct msg_frame *framep;
+    unsigned long flags;
+    msg_frame *wdsframep;
+
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME), "frame_alloc, dev %s \n", dev->name);
+
+    /* We could change this for a spinlock mechanism */
+    save_flags_cli (flags);
+
+    framep = ((struct net_local *)dev->priv)->frame_freelist;
+    if (framep)
+	((struct net_local *)dev->priv)->frame_freelist = framep->handle;
+
+    restore_flags(flags);
+
+    /* Make sure the wds info in the frame is zeroed */
+    if (framep)
+    {
+        wdsframep = (msg_frame*)framep;
+#ifdef BLOB_V2
+        memset(wdsframep->wds, 0, ETH_ALEN);
+#else
+        memset(wdsframep->wds_link, 0, ETH_ALEN);
+#endif /* TEST_ON_POLDHU */
+    }
+
+    return framep;
+}
+
+
+/**********************************************************************
+ *  frame_free
+ *
+ *  DESCRIPTION: Frees the frame pointed to by the framep.
+ *               It returns the framep to the free frames list.
+ *
+ *  PARAMETERS:	 dev    - pointer to a linux net device struct.
+ *               framep - pointer to msg_frame struct.
+ *
+ *  RETURN:	 Nothing.
+ *
+ *  NOTE:        Inline function.
+ *
+ **********************************************************************/
+static inline void frame_free (struct net_device *dev, struct msg_frame *framep)
+{
+    unsigned long flags;
+
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME), "frame_free, dev %s, framep %p \n", dev->name, framep);
+
+    if (!framep)
+        return;
+
+    save_flags_cli (flags);
+
+    framep->handle = ((struct net_local *)dev->priv)->frame_freelist;
+    ((struct net_local *)dev->priv)->frame_freelist = framep;
+
+    restore_flags(flags);
+}
+
+
+/**********************************************************************
+ *  copy_wds_to_frame
+ *
+ *  DESCRIPTION: This copies the WDS_Mac address into the msg_frame structure.
+ *
+ *  PARAMETERS:	 frame pointer to msg_frame structure
+ *               WDS MAC address to put into the frame.
+ *
+ *  RETURN:	 Nothing
+ *
+ *  NOTE:        inline function.
+ *
+ **********************************************************************/
+#ifdef BLOB_V2
+inline void copy_wds_to_frame(msg_frame *framep, unsigned char *WDS_Mac)
+{
+    /* Copy the found MAC addres in the msg_frame. */
+    memcpy(framep->wds, WDS_Mac, ETH_ALEN); /* MVC v1 */
+}
+#else
+inline void copy_wds_to_frame(msg_frame *framep, unsigned char *WDS_Mac)
+{
+    memcpy(framep->wds_link, WDS_Mac, ETH_ALEN); /* MVC v2 */
+}
+#endif
+
+
+/**********************************************************************
+ *  skb_to_frame
+ *
+ *  DESCRIPTION: Attach a prism frame structure to linux sk_buff 'skb'
+ *		 and initialize all fields of the frame structure with
+ *		 the current information of 'skb'.
+ *
+ *  PARAMETERS:	 skb - pointer to linux packet buffer.
+ *
+ *  RETURN:	 Pointer to the attached frame, or NULL if there wasn't
+ *		 enough memory.
+ *
+ **********************************************************************/
+/*
+ * The handling of frames is changed between MVC v1 and v2.
+ *
+ */
+#ifdef BLOB_V2
+static struct msg_frame *skb_to_frame (struct sk_buff *skb)
+{
+    struct msg_frame *framep;
+
+    int type = GET_DEV_TYPE(skb->dev->base_addr);
+
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME), "skb_to_frame, skb %p, dev %s \n", skb, skb->dev->name);
+
+    /* first malloc memory for msg_frame */
+    framep = frame_alloc (skb->dev);
+    if (framep != NULL)
+    {
+        framep->handle	 = (void *) skb;
+
+        /* Use this mpdu mapping for empty frames. */
+        if (skb->len < (2*ETH_ALEN)) {
+            framep->mpdu	 = (unsigned char *) skb->data;
+        }
+        else {
+            /* Need to do some formatting depending on the device type. */
+            if (type == BIS_DT_802DOT3) {
+                /*
+                    Nothing special to do for an 802.3 device...
+                    NOTE: This only works when the 802.3 device was started in MODE_PROMISCUOUS.
+                          When started in MODE_NORMAL need to add Source and Destination address to start of skb.
+                */
+                _DEBUG(DBG_TX, "skb_to_frame, 802.3...");
+                framep->mpdu	 = (unsigned char *) skb->data;
+            }
+            else if (type == BIS_DT_802DOT11) {
+                /*
+                    For 802.11 devices we need to do some frame formatting:
+                        - Remove Destination and Source address from mpdu data.
+                        - Add LLC + SNAP header to beginning of mpdu data.
+                */
+
+                /* Copy Destination and Source address into frame dest and src. */
+                memcpy(framep->dest, skb->data           , ETH_ALEN);
+                memcpy(framep->src,  skb->data + ETH_ALEN, ETH_ALEN);
+
+                /* Remove the Destination and Source Address from the skb. */
+                skb_pull(skb, 2 * ETH_ALEN);
+
+                /* convert the ethernet frame to WLAN */
+                llc_to_wlan( skb );
+
+                /* Okay, we're done. Point mpdu pointer to start of skb data. */
+                framep->mpdu	 = (unsigned char *) skb->data;
+            }
+            else {
+                printk(KERN_ERR "skb_to_frame: Unknown device type.\n");
+                /* Don't know how to format. Callers responsibility to free the skb. */
+                return NULL;
+            }
+        }
+
+        framep->size	 = skb->len;
+	framep->priority = -1; /* Priority isn't implemented yet.
+                                  We should map the skb->priority to the frame priority here. */
+    }
+    else
+        printk(KERN_WARNING "Frame pool full? \n");
+
+#if (NET_DEBUG & DBG_SKB)
+    memset (skb->head, 0, skb_headroom(skb));
+    memset (skb->tail, 0, skb_tailroom(skb));
+#endif
+
+#if (NET_DEBUG & DBG_FRAME_SANITY)
+    check_frame_skb(framep, __FILE__, __LINE__);
+#endif
+
+    return framep;
+}
+
+#else /* !BLOB_V2 */
+
+static struct msg_frame *skb_to_frame (struct sk_buff *skb)
+{
+    struct msg_frame *framep;
+
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME), "skb_to_frame, skb %p \n", skb);
+
+    /* first malloc memory for msg_frame */
+    framep = frame_alloc (skb->dev);
+    if (framep != NULL)
+    {
+	framep->handle	 = (void *) skb;
+	framep->mpdu	 = (unsigned char *) MAP_CACHED((unsigned)skb->data);
+        framep->size	 = skb->len;
+	framep->priority = -1; /* Priority isn't implemented yet.
+                                  We should map the skb->priority to the frame priority here. */
+        framep->bc_domain = 0;
+    }
+    else
+        printk(KERN_WARNING "Frame pool full? \n");
+
+#if (NET_DEBUG & DBG_SKB)
+    memset (skb->head, 0, skb_headroom(skb));
+    memset (skb->tail, 0, skb_tailroom(skb));
+#endif
+     return framep;
+}
+#endif /* BLOB_V2 */
+
+/**********************************************************************
+ *  frame_to_skb
+ *
+ *  DESCRIPTION: Update the fields of the linux sk_buff assigned to
+ *		 frame 'framep' just received from the MVC.
+  *		 The frame is freed.
+ *
+ *  PARAMETERS:	 framep - pointer to frame received from MVC.
+ *
+ *  RETURN:	 Pointer to the updated sk_buff that was assigned to the
+ *		 frame.
+ *
+ **********************************************************************/
+/*
+ * The handling of frames is changed between MVC v1 and v2.
+ *
+ */
+#ifdef BLOB_V2
+static struct sk_buff *frame_to_skb (struct msg_frame *framep)
+{
+    struct sk_buff *skb;
+    int offset, type;
+    unsigned char *src;
+
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME | DBG_IRQ), "frame_to_skb, framep %p \n", framep);
+
+#if (NET_DEBUG & DBG_FRAME_SANITY)
+    check_frame_skb(framep, __FILE__, __LINE__);
+#endif
+
+    skb = framep->handle;
+
+    type = GET_DEV_TYPE(skb->dev->base_addr);
+
+#if (NET_DEBUG & DBG_SKB)
+    /* Some sanity checking on the frame. */
+    if ((unsigned)framep->size > 1600 )
+        printk("Frame size (%d) is > 1600. Ok? \n", framep->size);
+    if (!framep->mpdu)
+        printk("framep->mpdu == NULL !!!\n");
+#endif
+
+    /* determine shift in framep->mpdu between add and rx */
+    offset = framep->mpdu - skb->data;
+
+    skb_reserve (skb, offset);
+    skb_put (skb, framep->size);
+
+#if (NET_DEBUG & DBG_SKB)
+    if (skb_headroom(skb) < 2*ETH_ALEN)
+        printk("frame_to_skb, not enough headroom (%d) to add SA and DA\n", skb_headroom(skb));
+#endif
+
+    /* Depending on the device type, we need to do some frame formatting. */
+    if (type == BIS_DT_802DOT3) {
+        _DEBUG(DBG_RX, "frame_to_skb, 802.3...");
+        /* Nothing special to do. */
+    }
+    else if (type == BIS_DT_802DOT11) {
+        _DEBUG(DBG_RX, "frame_to_skb, 802.11...");
+
+        /* Convert the WLAN frame back to ethernet LLC format */
+        wlan_to_llc( skb );
+
+        /* Add Source and Destination address to front of the skb. */
+        memcpy(skb_push(skb, ETH_ALEN), framep->src, ETH_ALEN);
+        memcpy(skb_push(skb, ETH_ALEN), framep->dest, ETH_ALEN);
+    }
+    else {
+        printk(KERN_ERR "frame_to_skb: Unknown device type.\n");
+        /* Don't know how to format. Drop it. Free frame & skb. */
+        frame_free (skb->dev, framep);
+        dev_kfree_skb(skb);
+        return NULL;
+    }
+
+    /* determine offset between IP header and a word boundary */
+    offset = (int) (skb->data + 6 + 6 + 2) & 0x03;
+
+    /* if there is any, shift the data */
+    if (offset)
+    {
+	struct net_local *lp = (struct net_local *)skb->dev->priv;
+	lp->rx_misaligned++;
+
+	if (skb_headroom (skb) < offset)
+	{
+	    if (skb_tailroom (skb) < (4 - offset))
+		printk(KERN_NOTICE "Unaligned skb\n");
+	    else
+		offset = 4 - offset;
+	}
+	else
+	    offset = -offset;
+#if (NET_DEBUG & DBG_RX)
+	printk ("frame_to_skb, need to shift data %d\n", offset);
+#endif
+	src = skb->data;
+	skb_reserve (skb, offset);
+	memmove (skb->data, src, skb->len);
+    }
+    skb->priority = -1; /* Priority isn't implemented yet. Add mapping between skb and frame priority here. */
+
+#if (NET_DEBUG & DBG_FRAME_SANITY)
+    check_frame_skb(framep, __FILE__, __LINE__);
+#endif
+
+    frame_free (skb->dev, framep);
+
+    return skb;
+}
+
+#else /* !BLOB_V2 */
+
+static struct sk_buff *frame_to_skb (struct msg_frame *framep)
+{
+     struct sk_buff *skb;
+    int offset;
+    unsigned char *src;
+
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME), "frame_to_skb, framep %p\n", framep);
+
+    skb = framep->handle;
+
+    /* first map pointer back in uncached area */
+    MAP_UNCACHED((unsigned)framep->mpdu);
+
+    /* determine shift in framep->mpdu between add and rx */
+    offset = framep->mpdu - skb->data;
+
+    skb_reserve (skb, offset);
+    skb_put (skb, framep->size);
+
+    /* determine offset between IP header and a word boundary */
+    offset = (int) (skb->data + 6 + 6 + 2) & 0x03;
+
+    /* if there is any, shift the data */
+    if (offset)
+    {
+	struct net_local *lp = (struct net_local *)skb->dev->priv;
+	lp->rx_misaligned++;
+
+	if (skb_headroom (skb) < offset)
+	{
+	    if (skb_tailroom (skb) < (4 - offset))
+		printk(KERN_NOTICE "Unaligned skb\n");
+	    else
+		offset = 4 - offset;
+	}
+	else
+	    offset = -offset;
+#if (NET_DEBUG & DBG_RX)
+	printk ("frame_to_skb, need to shift data %d\n", offset);
+#endif
+	src = skb->data;
+	skb_reserve (skb, offset);
+	memmove (skb->data, src, skb->len);
+    }
+    skb->priority = -1; /* Priority isn't implemented yet. Add mapping between skb and frame priority here. */
+
+    frame_free (skb->dev, framep);
+
+    return skb;
+}
+#endif /* BLOB_V2 */
+
+/**********************************************************************
+ *  dev_alloc_frame
+ *
+ *  DESCRIPTION: Allocate a frame and a sk_buff with MTU size 'size' for
+ *		 device 'dev'. Set all fields of the frame and the
+ *		 sk_buff. If size equals 0 then the maximum MTU size is
+ *		 used. The head and the tail room for the frame (and
+ *		 sk_buff) is equal to the maximum head and maximum tail
+ *		 room for all devices.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *		 size - the MTU size for the frame.
+ *
+ *  RETURN:	 Pointer to the allocated frame or NULL on error.
+ *
+ **********************************************************************/
+static inline struct msg_frame *dev_alloc_frame (struct net_device *dev, int size)
+{
+    struct sk_buff *skb;
+    struct msg_frame *framep;
+    int bufsize;
+    struct net_local *lp;
+
+    _DEBUG((DBG_FUNC_CALL | DBG_IRQ | DBG_FRAME), "dev_alloc_frame, dev %s, size %d \n", dev->name, size);
+
+    /* first allocate a sk_buff with enough head and tail room */
+    lp = (struct net_local *)dev->priv;
+    bufsize = lp->maxhead + 2 +
+		    (size ? size : lp->maxmtu) + lp->maxtail;
+    if ((skb = dev_alloc_skb (bufsize)) == NULL) {
+        _DEBUG(DBG_IRQ | DBG_FRAME, "dev_alloc_frame, dev_alloc_skb failed... \n");
+        return NULL;
+    }
+
+    /* fill in some sk_buff fields */
+    skb->dev = dev;
+    skb_reserve (skb, lp->maxhead + 2); /* word align IP header */
+
+    if ((framep = skb_to_frame(skb)) == NULL)
+        dev_kfree_skb(skb);
+
+    return framep;
+}
+
+
+/**********************************************************************
+ *  dev_free_frame
+ *
+ *  DESCRIPTION: Free MVC frame 'frame' and the attached sk_buff.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *               frame - address of frame to free
+ *
+ *  RETURN:	 Nothing.
+ *
+ **********************************************************************/
+static inline void dev_free_frame (struct net_device *dev, struct msg_frame *frame)
+{
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME), "dev_free_frame, dev %s, frame %p \n", dev->name, frame);
+
+#if (NET_DEBUG & DBG_FRAME_SANITY)
+    check_frame_skb(frame, __FILE__, __LINE__);
+#endif
+
+    if (frame->handle)
+	dev_kfree_skb_any (frame->handle);
+    frame_free (dev, frame);
+}
+
+/**********************************************************************
+ *  dev_copy_expand_skb
+ *
+ *  DESCRIPTION: Allocate a new sk_buff and copy the data of sk_buff
+ *		 'skb'. The new sk_buff will have the required head and
+ *		 tail room for device 'dev'.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *		 skb - the sk_buff to copy the data from
+ *
+ *  RETURN:	 Pointer to the new allocated sk_buff or NULL on error.
+ *
+ **********************************************************************/
+static struct sk_buff *dev_copy_expand_skb (struct net_device *dev,
+				const struct sk_buff *skb)
+{
+    int bufsize;
+    struct sk_buff *newskb;
+    struct net_local *lp = (struct net_local *)dev->priv;
+
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME), "dev_copy_expand_skb, dev %s, skb %p \n", dev->name, skb);
+
+#ifdef BLOB_V2
+    bufsize = skb->len + lp->dev_elem->header + lp->dev_elem->trailer;
+#else
+    bufsize = skb->len + lp->dev_desc->header + lp->dev_desc->trailer;
+#endif
+    if ((newskb = dev_alloc_skb (bufsize)) == NULL)
+	return NULL;
+
+    /* reserve head room */
+#ifdef BLOB_V2
+    skb_reserve (newskb, lp->dev_elem->header);
+#else
+    skb_reserve (newskb, lp->dev_desc->header);
+#endif
+
+    /* set the tail pointer and length */
+    skb_put(newskb, skb->len);
+
+    /* copy the data */
+    memcpy(newskb->data, skb->data, skb->len);
+    newskb->priority = skb->priority;
+
+    newskb->dev = dev;
+    return newskb;
+}
+
+/**********************************************************************
+ *  llc_to_wlan
+ *
+ *  DESCRIPTION: Converts the ethernet LLC frame to SNAP for WLAN
+ *
+ *  PARAMETERS:	 skb - buffer with ethernet frame to be converted
+ *
+ *  RETURN:	 Nothing.
+ *
+ **********************************************************************/
+/*
+ * The conversion of frames is removed from MVC v2
+ *
+ */
+#ifdef BLOB_V2
+static int llc_to_wlan (struct sk_buff *skb)
+{
+    unsigned int ethertype;
+
+    DEBUG((DBG_FUNC_CALL | DBG_FRAME), "llc_to_wlan, skb %p\n", skb);
+
+    ethertype = (unsigned int) ((skb->data[0] << 8) | skb->data[1]);
+
+    /*
+        Ethertype check should be 1500, but with 802.1Q it is possible that frames are
+        actually longer than 1500 bytes and thus regarded as ethertype frames. 1536 leaves
+        enough space for long frames and 1536 (XEROX NS IDP) is the first registered ethertype
+    */
+    if( ethertype >= 1536 )
+    {
+        DEBUG((DBG_FRAME), "llc_to_wlan, Ethernet II type %04x, converting to SNAP\n", ethertype);
+
+        /*
+            Make room for LLC (3 bytes) and for OUI field (3 bytes) of SNAP header.
+            Leave SNAP Type field unchanged.
+        */
+        skb_push(skb, 6);
+
+        /* LLC */
+        skb->data[0] = 0xAA; /* DSAP (1 byte) */
+        skb->data[1] = 0xAA; /* SSAP (1 byte) */
+        skb->data[2] = 0x03; /* Control (1 byte) */
+
+        /* SNAP */
+        skb->data[3] = 0x00; /* OUI (3 bytes) */
+        skb->data[4] = 0x00;
+
+        /*
+            Consult the Selective Translation Table (802.1H), which contains
+            ethernet types 8137 and 80F3
+        */
+        if( ethertype == 0x8137 || ethertype == 0x80F3 )
+            /* Bridge tunnel encapsulation */
+            skb->data[5] = 0xF8;
+        else
+            skb->data[5] = 0x00;
+    }
+    else
+    {
+        DEBUG((DBG_FRAME), "llc_to_wlan, Length %04x, Found 802.2, 802.3 or SNAP [%02x%02x]\n",
+            ethertype, skb->data[2], skb->data[3] );
+
+        /* Remove the length field from the skb. */
+        skb_pull(skb, 2);
+    }
+
+    return 0;
+}
+#endif
+
+/**********************************************************************
+ *  wlan_to_llc
+ *
+ *  DESCRIPTION: Converts the WLAN (SNAP) frame to ethernet LLC
+ *
+ *  PARAMETERS:	 skb - buffer with WLAN frame
+ *
+ *  RETURN:	 Nothing.
+ *
+ **********************************************************************/
+/*
+ * The conversion of frames is removed from MVC v2
+ *
+ */
+#ifdef BLOB_V2
+static int wlan_to_llc (struct sk_buff *skb)
+{
+    _DEBUG((DBG_FUNC_CALL | DBG_FRAME), "wlan_to_llc, frame %p, skb %p\n", framep, skb);
+
+    /*
+        802.1H: Check whether the WLAN frame has a SNAP header.
+        SNAP can always be converted to Ethernet II except for the protocols
+        in the Selective Translation Table
+    */
+    if( (skb->data[0] == 0xAA) && (skb->data[1] == 0xAA) && (skb->data[2] == 0x03) &&
+        (skb->data[3] == 0x00) && (skb->data[4] == 0x00) &&
+        ((skb->data[5] == 0x00) || (skb->data[5] == 0xF8)))
+    {
+        /*  Check the Selective Translation Table */
+        if( ((skb->data[6] == 0x81) && (skb->data[7] == 0x37)) ||
+            ((skb->data[6] == 0x80) && (skb->data[7] == 0xF3)) )
+        {
+            /* Check also the Bridge Tunnel Encapsulation */
+            if( skb->data[5] == 0xF8 )
+            {
+                /*
+                    Remove LLC (3 bytes) + OUI field (3 bytes) of SNAP header.
+                    Don't remove the type field (2 bytes) of the SNAP header.
+                */
+                skb_pull(skb, 6);
+            }
+            else
+            {
+                /*  Add the length of the buffer */
+                skb_push( skb, 2);
+                skb->data[0] = (unsigned char) ((skb->len-2)>>8);
+                skb->data[1] = (unsigned char) (skb->len-2);
+            }
+        }
+        else
+        {
+            /*
+                Remove LLC (3 bytes) + OUI field (3 bytes) of SNAP header.
+                Don't remove the type field (2 bytes) of the SNAP header.
+            */
+            skb_pull(skb, 6);
+        }
+
+        DEBUG((DBG_FRAME), "wlan_to_llc, Removed SNAP header, Ethertype still present\n");
+
+    }
+    else
+    {
+        DEBUG((DBG_FRAME), "wlan_to_llc, Ethertype %02x%02x, preappend Length %04x\n",
+            skb->data[0], skb->data[1], skb->len );
+
+        /*  Preappend the length of the buffer */
+        skb_push( skb, 2);
+        skb->data[0] = (unsigned char) ((skb->len-2)>>8);
+        skb->data[1] = (unsigned char) (skb->len-2);
+    }
+
+    return 0;
+}
+#endif
+
+/****************************************************************
+*								*
+*    		End of frame handling block                     *
+*               (driver configurator module)			*
+*								*
+***************************************************************/
+
+
+/****************************************************************
+ *								*
+ *    		End of driver configurator functions		*
+ *								*
+ ***************************************************************/
+
+/**********************************************************************
+ *  local_set_mac_addr
+ *
+ *  DESCRIPTION: This sets/changes the MAC address on the interface.
+ *               A MAC address containing all zeroes is used to reset
+ *               the MAC address to it's default.
+ *
+ *  PARAMETERS:	 dev  - pointer to a linux net device struct.
+ *               addr - pointer to new MAC address
+ *
+ *  RETURN:	 0 on succes.
+ *               -EINVAL on error.
+ *
+ **********************************************************************/
+#ifdef HAVE_SET_MAC_ADDR
+static int local_set_mac_addr(struct net_device *dev, void *addr)
+{
+    unsigned char mac_addr[ETH_ALEN];
+    unsigned char mac_null_addr[ETH_ALEN];
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "local_set_mac_addr, dev %s, addr %s \n", dev->name, (char*) addr);
+
+    memcpy(mac_addr, addr, ETH_ALEN);
+    memset(mac_null_addr, 0, ETH_ALEN);
+
+    /* A MAC address containing all zeroes is used to reset the MAC address to it's default. */
+    if (memcmp(mac_addr, mac_null_addr, ETH_ALEN) == 0)
+    {
+
+        /* Get the MAC address from the PDA. Function returns pointer to MACAddress. */
+        memcpy(mac_addr, pda_get_mac_address(), ETH_ALEN);
+
+        if (mac_addr == NULL)
+        {
+            printk(KERN_ERR "Couldn't get MAC address for %s from PDA...\n", dev->name);
+            return -EINVAL;
+        }
+    }
+
+    /* We don't allow multicast/broadcast MAC addresses. */
+    if (mac_addr[0] & 1)
+        return -EINVAL;
+
+    /* Send a message to the MVC that we want to use this MAC address... */
+    if (islmvc_send_mvc_msg(dev, OPSET, GEN_OID_MACADDRESS, (long*)mac_addr, ETH_ALEN) < 0);
+    {
+        printk("local_set_mac_addr, couldn't change MAC address %s for dev %s ",
+               hwaddr2string(mac_addr), dev->name);
+        return -EINVAL;
+    }
+
+    /* Okay, we succeeded, so use this MAC address from now on... */
+    memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
+    DEBUG(DBG_MGMT, "MAC address changed to %s. ", hwaddr2string(mac_addr));
+
+    return 0;
+}
+#endif /* HAVE_SET_MAC_ADDR */
+
+
+/**********************************************************************
+ *  local_net_get_stats
+ *
+ *  DESCRIPTION: Get the current statistics.
+ *               This may be called with the card open or closed.
+ *
+ *  PARAMETERS:	 dev - pointer to a linux net device struct.
+ *
+ *  RETURN:	 struct net_device stats pointer
+ *
+ **********************************************************************/
+static struct net_device_stats *local_net_get_stats(struct net_device *dev)
+{
+    long mvc_errors;
+
+    int dev_nr = GET_DEV_NR(dev->base_addr) - 1;
+    static long old_rx_failed[3]  = { 0, 0, 0 };
+    static long old_rx_dropped[3] = { 0, 0, 0 };
+
+    struct net_local *lp = (struct net_local *)dev->priv;
+    struct net_device_stats *stats = &lp->stats;
+
+    _DEBUG(DBG_FUNC_CALL | DBG_MGMT, "local_net_get_stats, dev %s \n", dev->name);
+
+    /*
+        Most statistics are updated in the driver code.
+        However, we can't update error counters for received packets that
+        were dropped or erroneous, since we don't get those packets from the MVC.
+        So, we ask the MVC for those errors...
+    */
+    if (!islmvc_send_mvc_msg(dev, OPGET, GEN_OID_MSDURXFAILED, &mvc_errors, sizeof(long))) {
+        stats->rx_errors += (mvc_errors - old_rx_failed[dev_nr]); /* Only add the difference from the previous count. */
+        old_rx_failed[dev_nr] = mvc_errors;
+    }
+
+    if (!islmvc_send_mvc_msg(dev, OPGET, GEN_OID_MSDURXDROPPED, &mvc_errors, sizeof(long))) {
+        stats->rx_dropped += (mvc_errors - old_rx_dropped[dev_nr]); /* Only add the difference from the previous count. */
+        old_rx_dropped[dev_nr] = mvc_errors;
+    }
+
+    return stats;
+}
+
+
+
+/***************************************************************
+*								*
+*    		Start of local debugging functions  		*
+*								*
+***************************************************************/
+
+#if (NET_DEBUG & (DBG_TX | DBG_RX | DBG_ERROR))
+/**********************************************************************
+ *  dbg_print_frame
+ *
+ *  DESCRIPTION: Print the fields of prism frame 'framep' and the data.
+ *
+ *  PARAMETERS:	 framep - pointer to a prism frame
+ *
+ *  RETURN:	 Nothing.
+ *
+ **********************************************************************/
+static void dbg_print_frame (struct msg_frame *framep)
+{
+    int offset;
+    struct sk_buff *skb;
+
+    skb = framep->handle;
+    printk ("framep: size %d, status %d, mpdu %p, skb->data %p, skb %p, skb->len %d \n",
+	    framep->size, framep->status, framep->mpdu, skb->data, skb, skb->len);
+    printk ("pr_frame: skb->head %p, skb->tail %p, skb->dev->name %s \n",
+            skb->head, skb->tail, skb->dev->name);
+    for (offset = 0; offset < framep->size; offset++)
+	printk ("%02X ", framep->mpdu[offset]);
+    printk ("\n");
+}
+#endif /* (NET_DEBUG & (DBG_TX | DBG_RX | DBG_ERROR)) */
+
+
+#if (NET_DEBUG & DBG_SKB)
+/**********************************************************************
+ *  dbg_frame_filter_check
+ *
+ *  DESCRIPTION: Filter frames not of interest for the Linux IP stack.
+ *		 (unicasts not containing our MAC address and Intersil
+ *		 debug frames). Perform some checks on the frame and
+ *		 print warnings if something suspious is found.
+ *
+ *  PARAMETERS:	 dev    - pointer to a linux net device struct.
+ *		 framep - pointer to the received prism frame
+ *
+ *  RETURN:	 0 if the frame is absorbed by this function, otherwise 1.
+ *
+ **********************************************************************/
+static int dbg_frame_filter_check (struct net_device *dev, struct msg_frame *framep)
+{
+    struct sk_buff *skb;
+    int offset;
+    unsigned char *src;
+    int mtu;
+
+    /* filer out unicast frames not directed to our MAC address */
+    if ((framep->mpdu[0] & 0x01) == 0)
+    {
+	for (offset = 0; offset < ETH_ALEN; offset++)
+	{
+	    if (framep->mpdu[offset] != dev->dev_addr[offset])
+	    {
+		dev_free_frame (dev, framep);
+		return 0;
+	    }
+	}
+    }
+
+    /* filer out Intersil debug frames */
+    if ((framep->mpdu[12] == 0x88) && (framep->mpdu[13] == 0x27))
+    {
+	dev_free_frame (dev, framep);
+	return 0;
+    }
+
+    skb = framep->handle;
+
+    /* first map pointer back in 0x08000000 area */
+#ifdef TEST_ON_POLDHU
+    MAP_UNCACHED((unsigned)framep->mpdu);
+#endif /* TEST_ON_POLDHU */
+
+    /* determine shift in framep->mpdu between add and rx */
+    offset = framep->mpdu - skb->data;
+
+    if (offset)
+    {
+	printk ("frame_to_skb: blob changed mpdu: %d!!!\n", offset);
+	dbg_print_frame (framep);
+    }
+    if (skb_tailroom (skb) < framep->size)
+	printk ("frame_to_skb: NOT enough room!! need %d, tailroom %d, len %d\n",
+		framep->size, skb_tailroom (skb), skb->len);
+
+#ifdef BLOB_V2
+    mtu = ((struct net_local *)dev->priv)->dev_elem->mtu;
+#else
+    mtu = ((struct net_local *)dev->priv)->dev_desc->mtu;
+#endif
+    offset = dbg_check_area (skb->head, framep->mpdu - skb->head, "header");
+    for (src = skb->end-1; (*src == 0) && (src > framep->mpdu+mtu); src--)
+	;
+    if (src > framep->mpdu+mtu)
+    {
+	dbg_check_area (framep->mpdu+mtu, (src - framep->mpdu+mtu) + 1, "trailer");
+	offset = 1;
+    }
+    if (offset)
+	dbg_print_frame (framep);
+    return 1;
+}
+
+
+/**********************************************************************
+ *  dbg_dump_hex_assci
+ *
+ *  DESCRIPTION: Dump the content of buffer 'buf' to the screen. The
+ *		 data is presented in hexadecimal and ASSCI form, 16
+ *		 bytes on each line.
+ *
+ *  PARAMETERS:	 buf  - pointer to buffer to display
+ *		 size - size of the buffer
+ *
+ *  RETURN:	 Nothing.
+ *
+ **********************************************************************/
+static void dbg_dump_hex_assci (unsigned char *buf, int size)
+{
+    int linesize, i;
+    unsigned char *p;
+
+    while (size)
+    {
+	linesize = size > 16 ? 16 : size;
+	size -= linesize;
+	for (p = buf, i = 0; i < linesize; i++, p++)
+	    printk (" %02X", *p);
+	for (; i < 17; i++)
+	    printk ("	");
+	for (i = 0; i < linesize; i++, buf++)
+	{
+	    if (*buf > 31 && *buf < 128)
+		printk ("%c", *buf);
+	    else
+		printk (".");
+	}
+	printk ("\n");
+    }
+}
+
+
+/**********************************************************************
+ *  dbg_check_area
+ *
+ *  DESCRIPTION: Check if a memory area contains all zero's. If not,
+ *		 print a warning, the address that isn't zero and dump
+ *		 the content of the rest of the area on the screen.
+ *
+ *  PARAMETERS:	 p	   - start address of the area to check
+ *		 size	   - size of the area
+ *		 area_name - name of the area that is displayed in the
+ *			     warning message
+ *
+ *  RETURN:	 0 if the whole area contains zero's, otherwise 1.
+ *
+ **********************************************************************/
+static int dbg_check_area (unsigned char *p, int size, char *area_name)
+{
+    while (size)
+    {
+	if (*p)
+	{
+	    printk ("WARNING: %s changed at %p!\n", area_name, p);
+	    dbg_dump_hex_assci (p, size);
+	    return 1;
+	}
+	p++;
+	size--;
+    }
+    return 0;
+}
+#endif /* (NET_DEBUG & DBG_SKB) */
+
+#if (NET_DEBUG & DBG_FRAME_SANITY)
+
+#define LINUX_VALID_ADDR(addr)  ((unsigned long)addr > 0x00040000 && (unsigned long)addr < 0x00800000)
+
+/**********************************************************************
+ *  check_frame_skb
+ *
+ *  DESCRIPTION: Do some sanity checking on the frame. This function
+ *               checks if the pointers and lengths are in a valid range.
+ *
+ *  PARAMETERS:	 framep	   - pointer to frame struct to check.
+ *		 file	   - name of the file the function was called from.
+ *		 line      - line number from wich this function is called.
+ *
+ *  RETURN:	 0 if the whole area contains zero's, otherwise 1.
+ *
+ **********************************************************************/
+static void check_frame_skb(struct msg_frame *framep, char *file, int line)
+{
+        struct sk_buff *skb;
+        int err = 0;
+        int print_size;
+
+        if(!LINUX_VALID_ADDR(framep)) {
+                printk("check_frame_skb (%s:%d): illegal framep %p\n", file, line,
+                        framep);
+                err = 1;
+        }
+
+        if(!LINUX_VALID_ADDR(framep->handle)) {
+                printk("check_frame_skb (%s:%d): illegal framep->handle %p\n", file, line,
+                        framep->handle);
+                err = 1;
+        }
+
+        if(!LINUX_VALID_ADDR(framep->mpdu)) {
+                printk("check_frame_skb (%s:%d): illegal framep->mpdu %p\n", file, line,
+                        framep->mpdu);
+                err = 1;
+        }
+
+        skb = framep->handle;
+
+        if(!LINUX_VALID_ADDR(skb->head)) {
+                printk("check_frame_skb (%s:%d): illegal skb->head %p\n", file, line,
+                        skb->head);
+                err = 1;
+        }
+
+        if(!LINUX_VALID_ADDR(skb->tail)) {
+                printk("check_frame_skb (%s:%d): illegal skb->tail %p\n", file, line,
+                        skb->tail);
+                err = 1;
+        }
+
+        if(!LINUX_VALID_ADDR(skb->data)) {
+                printk("check_frame_skb (%s:%d): illegal skb->data %p\n", file, line,
+                        skb->data);
+                err = 1;
+        }
+
+        if(skb->len > 1600 || framep->size > 1600) {
+                printk("check_frame_skb (%s:%d): illegal length skb->len %d framep->len %d\n",
+                        file, line, skb->len, framep->size);
+                err = 1;
+        }
+
+        if(err) {
+                int offset;
+
+                printk ("framep: size %d, status %d, mpdu %p, skb %p\n",
+                        framep->size, framep->status, framep->mpdu, skb);
+                printk ("skb->head %p, skb->data %p, skb->tail %p, skb->len %d, skb->dev->name %s \n",
+                        skb->head, skb->data, skb->tail, skb->len, skb->dev->name);
+
+                if(framep->size < 20)
+                        print_size = 20;
+                else if(framep->size > 1600)
+                        print_size = 1600;
+                else
+                        print_size = framep->size;
+
+                for (offset = 0; offset < print_size; offset++)
+                        printk ("%02X ", framep->mpdu[offset]);
+                printk ("\n");
+
+                __bug(file, line, NULL);
+        }
+}
+
+#endif /* (NET_DEBUG & DBG_FRAME_SANITY) */
+
+
+/***************************************************************
+*								*
+*    		End of local debugging functions  		*
+*								*
+***************************************************************/
+
diff -urN linux-2.4.29/drivers/net/intersil/islmvc.h linux-2.4.29-uc1/drivers/net/intersil/islmvc.h
--- linux-2.4.29/drivers/net/intersil/islmvc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islmvc.h	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,125 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef _ISLMVC_H
+#define _ISLMVC_H
+
+/* So we can test parts of this driver on a poldhu based board. */
+#include <linux/autoconf.h>
+
+#ifdef CONFIG_POLDHU_TEST_DB_DRIVER
+#define TEST_ON_POLDHU 
+#else
+#undef TEST_ON_POLDHU
+#endif
+
+/* INCLUDES */
+
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/spinlock.h>
+#include <device_config.h>
+#include <linux/isil_netlink.h>
+
+/* DEFINES */
+#define TRUE  1
+#define FALSE 0
+
+/*
+ * MACROS to get and set the MVC device nr and MVC nr
+ */
+/* Add the device type, located in the first 16 bits, to var */
+#define ADD_DEV_TYPE(var, type) var = ((var & 0x0000FFFF) + (type << 16))
+/* Add the device number, located in the last 16 bits, to var */
+#define ADD_DEV_NR(var, dev_nr) var = ((var & 0xFFFF0000) + dev_nr)
+/* Return the MVC device number, located in the last 16 bits */
+#define GET_DEV_NR(var) (var & 0x0000FFFF)
+/* Return the device type, located in the first 16 bits */
+#define GET_DEV_TYPE(var) ((var & 0xFFFF0000) >> 16)
+
+/* Debug flag to get debug information for specific sections */
+#define DBG_TX	            0x00000001
+#define DBG_RX	            0x00000002
+#define DBG_IRQ	            0x00000004
+#define DBG_IOCTL           0x00000008
+#define DBG_OPEN            0x00000010
+#define DBG_CLOSE           0x00000020
+#define DBG_ERROR           0x00000040
+#define DBG_SKB	            0x00000080
+#define DBG_WDS	            0x00000100
+#define DBG_MGMT            0x00000200
+#define DBG_PROBE           0x00000400
+#define DBG_PIMFOR          0x00000800
+#define DBG_FRAME           0x00001000
+#define DBG_NETLINK         0x00002000
+#define DBG_TRAP            0x00004000
+#define	DBG_FUNC_CALL       0x00008000 
+#define DBG_FRAME_SANITY    0x00010000
+
+#define DBG_NONE	    0x00000000
+#define DBG_ALL	            0xFFFFFFFF
+
+#ifndef NET_DEBUG
+#define NET_DEBUG   (DBG_ERROR) 
+#endif
+static unsigned int net_debug = NET_DEBUG;
+
+/* macros to simplify debug checking */
+#define DEBUGLVL(x) if (net_debug & (x))
+// #define DEBUG(x,args...)  do{DEBUGLVL(x) printk(## args);}while(0)
+#define DEBUG(x,args...) 
+#define _DEBUG(x,args...) 
+
+struct client_information
+{
+    struct client_information *next_client;
+    struct client_information **pprev_client;
+    char                      mac_addr[ETH_ALEN];
+};
+
+/* Information that need to be kept for each device. */
+struct net_local
+{
+    struct net_device_stats	    stats;	/* tx/rx statistics */
+#ifdef BLOB_V2
+    struct bis_dev_element          *dev_elem;	        /* MVC element desriptor */
+#else    
+    struct bis_dev_descr_element    *dev_desc;	/* MVC device desriptor */
+#endif /* BLOB_V2 */
+    int				    maxhead;	/* maximum head, tail and mtu */
+    int				    maxtail;	/* sizes for all MVC devices */
+    int				    maxmtu;	/* (so we can bridge w/h copy)*/
+    struct trap_info                *traps;	/* registrated traps */
+    unsigned char	            *acl;
+    int				    acl_nr_items;
+    unsigned int		    tx_misaligned;
+    unsigned int		    rx_misaligned;
+    int				    maxnrframes;
+    struct msg_frame                *frame_pool;
+    struct msg_frame                *frame_freelist;
+    unsigned int		    watchdog_timeout;  /* 0 = Off */
+    unsigned int		    watchdog_event;
+    struct wds_priv                 *wdsp;
+    struct client_information       *assoc_table[MAX_ASSOCIATIONS];
+    struct mvc_irq_table            *mvcirq_table;
+};
+
+char *hwaddr2string(char *a);
+
+#endif /* !defined(_ISLMVC_H) */
diff -urN linux-2.4.29/drivers/net/intersil/islmvc_mgt.c linux-2.4.29-uc1/drivers/net/intersil/islmvc_mgt.c
--- linux-2.4.29/drivers/net/intersil/islmvc_mgt.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islmvc_mgt.c	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,1756 @@
+/*  $Header$
+ *
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+/* Begin of include files */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/rtnetlink.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <net/sock.h>
+#include <linux/netlink.h>
+
+#include <asm/arch/blobcalls.h>
+#include <linux_mvc_oids.h>
+#include "islmvc_mgt.h"
+#include "islmvc.h"
+#include "isl_wds.h"
+#include "isl_mgt.h"
+
+/* For setting/clearing LEDs on the isl3893 platform. */
+#ifdef BLOB_V2
+#include <asm-armnommu/arch-isl3893/gpio.h>
+#endif
+
+/* End of include files */
+
+struct wds_link_msg {
+    unsigned char mac[6];
+    char name[32];
+} __attribute__ ((packed));
+
+/* pointer to the netlink socket */
+struct sock *nl_sock = NULL;
+
+/* Static variable for the trap sequence counter */
+__u32 trap_seq = 0;
+
+extern unsigned int src_seq;
+
+struct frame_attachment *frame_attach[256][MAX_ASSOC_IDS];
+
+
+/****************************************************************
+ *
+ *      		Handlers
+ *
+ ***************************************************************/
+
+static int islmvc_send_mvc_msg_hndl( unsigned int dev_type, unsigned int dev_seq,
+                                    unsigned int src_id,   unsigned int src_seq,
+                                    unsigned int prismop,  unsigned int oid, void *data, unsigned long len);
+static int islmvc_wdslink_add_hndl( unsigned int, unsigned int, unsigned int, unsigned,
+                             unsigned int, unsigned int, void *, unsigned long );
+static int islmvc_wdslink_del_hndl( unsigned int, unsigned int, unsigned int, unsigned,
+                             unsigned int, unsigned int, void *, unsigned long );
+static int islmvc_dot11_oid_attachment_hndl( unsigned int src_id,   unsigned int src_seq,
+                             unsigned int dev_id,   unsigned int dev_seq,
+                             unsigned int op,       unsigned int oid, void *data, unsigned long len);
+//static int islmvc_dot11_oid_authenticate_hndl( unsigned int src_id,   unsigned int src_seq,
+//                             unsigned int dev_id,   unsigned int dev_seq,
+//                             unsigned int op,       unsigned int oid, void *data, unsigned long len);
+//static int islmvc_dot11_oid_associate_hndl( unsigned int src_id,   unsigned int src_seq,
+//                             unsigned int dev_id,   unsigned int dev_seq,
+//                             unsigned int op,       unsigned int oid, void *data, unsigned long len);
+
+#ifdef HANDLE_IAPP_IN_DRIVER
+static int islmvc_gen_iappframe_hndl( unsigned int src_id, unsigned int src_seq,
+                                     unsigned int dev_id,   unsigned int dev_seq,
+                                     unsigned int op,       unsigned int oid, void *data, unsigned long len);
+#endif /* HANDLE_IAPP_IN_DRIVER */
+
+#ifdef HANDLE_ASSOC_IN_DRIVER
+static int islmvc_dot11_oid_authenticate_hndl( unsigned int src_id, unsigned int src_seq,
+                                     unsigned int dev_id,   unsigned int dev_seq,
+                                     unsigned int op,       unsigned int oid, void *data, unsigned long len);
+static int islmvc_dot11_oid_associate_hndl( unsigned int src_id, unsigned int src_seq,
+                                     unsigned int dev_id,   unsigned int dev_seq,
+                                     unsigned int op,       unsigned int oid, void *data, unsigned long len);
+#endif /* HANDLE_ASSOC_IN_DRIVER */
+
+#ifdef BLOB_V2
+static int islmvc_gen_oid_led_set_hndl( unsigned int dev_id,   unsigned int dev_seq,
+                             unsigned int src_id,   unsigned int src_seq,
+                             unsigned int op,       unsigned int oid, void *data, unsigned long len);
+static int islmvc_gen_oid_led_clear_hndl( unsigned int dev_id,   unsigned int dev_seq,
+                             unsigned int src_id,   unsigned int src_seq,
+                             unsigned int op,       unsigned int oid, void *data, unsigned long len);
+#endif /* BLOB_V2 */
+
+
+static int mgmt_set_oid_attachment(char *data, struct net_device *dev, unsigned long length);
+
+unsigned char * pda_get_mac_address(void);
+
+
+
+
+/*
+ * Initializes all handlers for the specific OIDs and a generic handler for the rest.
+ *
+ */
+void islmvc_mgt_init(struct net_device *dev)
+{
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "islmvc_mgt_init for dev %s\n", dev->name);
+
+    mgt_initialize();
+    mgt_indication_handler ( DEV_NETWORK, dev->name, 0, islmvc_send_mvc_msg_hndl );
+
+    if (GET_DEV_TYPE(dev->base_addr) == BIS_DT_802DOT11) /* Only needed for 802.11 devices */
+    {
+        mgt_indication_handler ( DEV_NETWORK, dev->name, DOT11_OID_WDSLINKADD,   islmvc_wdslink_add_hndl );
+        mgt_indication_handler ( DEV_NETWORK, dev->name, DOT11_OID_WDSLINKREMOVE,islmvc_wdslink_del_hndl );
+        mgt_indication_handler ( DEV_NETWORK, dev->name, DOT11_OID_ATTACHMENT,   islmvc_dot11_oid_attachment_hndl );
+
+#ifdef HANDLE_IAPP_IN_DRIVER
+        mgt_response_handler ( DEV_NETWORK, dev->name, DOT11_OID_ASSOCIATE,     islmvc_gen_iappframe_hndl );
+        mgt_response_handler ( DEV_NETWORK, dev->name, DOT11_OID_ASSOCIATEEX,   islmvc_gen_iappframe_hndl );
+        mgt_response_handler ( DEV_NETWORK, dev->name, DOT11_OID_REASSOCIATE,   islmvc_gen_iappframe_hndl );
+        mgt_response_handler ( DEV_NETWORK, dev->name, DOT11_OID_REASSOCIATEEX, islmvc_gen_iappframe_hndl );
+#endif
+
+#ifdef HANDLE_ASSOC_IN_DRIVER
+        mgt_response_handler ( DEV_NETWORK, dev->name, DOT11_OID_AUTHENTICATE, islmvc_dot11_oid_authenticate_hndl );
+        mgt_response_handler ( DEV_NETWORK, dev->name, DOT11_OID_ASSOCIATE,    islmvc_dot11_oid_associate_hndl );
+#endif
+    }
+
+    /* Mgmt handlers for setting/clearing the LEDs. */
+#ifdef BLOB_V2
+    mgt_indication_handler ( DEV_NETWORK, dev->name, GEN_OID_LED_SET,   islmvc_gen_oid_led_set_hndl );
+    mgt_indication_handler ( DEV_NETWORK, dev->name, GEN_OID_LED_CLEAR, islmvc_gen_oid_led_clear_hndl );
+#endif BLOB_V2
+
+}
+
+
+/****************************************************************
+ *								*
+ *    		Begin of management handling functions		*
+ *								*
+ ***************************************************************/
+
+/* All OIDs */
+
+#define PRISMOP2DEVOP(op) (op == PIMFOR_OP_GET ) ? OPGET : ( (op == PIMFOR_OP_SET ) ? OPSET : -1 )
+
+static int islmvc_send_mvc_msg_hndl( unsigned int dev_type, unsigned int dev_seq,
+                                    unsigned int src_id,   unsigned int src_seq,
+                                    unsigned int prismop,  unsigned int oid, void *data, unsigned long len)
+{
+    struct net_device *dev;
+    unsigned int devop = PRISMOP2DEVOP(prismop);
+
+    _DEBUG(DBG_FUNC_CALL | DBG_MGMT,
+          "islmvc_send_mvc_msg_hndl, dev_type %d, dev_seq %d, src_id %d, src_seq %d, prismop %d, oid %x, data %p, len %lu \n",
+          dev_type, dev_seq, src_id, src_seq, prismop, oid, data, len);
+
+    if ( devop < 0 )
+        return -1;
+
+    if ( ! (dev = dev_get_by_index(dev_seq)) ) {
+        if ( (mgt_response( src_id, src_seq, dev_type, dev_seq, PIMFOR_OP_ERROR, oid, data, len)) < 0 ) {
+            return -1;
+        }
+        return 0;
+    }
+    dev_put( dev );
+
+    /* src_id and src_seq sunk */
+
+    if ( islmvc_send_mvc_msg( dev, devop, oid, data, len ) < 0 ) {
+        if ( (mgt_response( src_id, src_seq, dev_type, dev_seq, PIMFOR_OP_ERROR, oid, data, len)) < 0 ) {
+            return -1;
+        }
+        return 0;
+    }
+
+    if ( (mgt_response( src_id, src_seq, dev_type, dev_seq, PIMFOR_OP_RESPONSE, oid, data, len)) < 0 ) {
+        return -1;
+    }
+
+    return 0;
+}
+
+
+/**********************************************************************
+ *  islmvc_send_mvc_msg
+ *
+ *  DESCRIPTION: Send a message to perform on the MVC.
+ *
+ *  PARAMETERS:	 dev       - device to operate on.
+ *               operation - operation to perform.
+ *               oid       - OID to perform operation on.
+ *               data      - pointer to buffer that (will) hold the data.
+ *               data_len  - length of data.
+ *
+ *  RETURN:      0 on success
+ *               -EOVERFLOW when length of data is too small.
+ *               -EINVAL when operation did not succeed.
+ *
+ **********************************************************************/
+int islmvc_send_mvc_msg(struct net_device *dev, int operation, int oid, long* data, unsigned long data_len)
+{
+    int error = 0;
+    struct msg_conf msg;
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "islmvc_send_mvc_msg, dev %s, oper %d, oid %x, data %p, len %lu. \n",
+          dev->name, operation, oid, data, data_len);
+
+    msg.operation = operation;
+    msg.oid       = oid;
+    msg.data      = data;
+#ifdef BLOB_V2
+    msg.size      = data_len; /* MVC v2 only */
+#endif
+
+
+#ifdef TEST_ON_POLDHU
+    /*
+       OIDs for the blob device need some special handling. Don't know if MVC v2 still needs a
+       construction like this?
+    */
+
+    if ( (oid & 0xFF000000) == 0x80000000) /* This is an OID for the blob device */
+    {
+        DEBUG(DBG_MGMT, "Msg for the BLOB device...\n");
+        /* This is an OID for the BLOB device. We only allow access to the blob device via eth0  */
+        if (GET_DEV_TYPE(dev->base_addr) == BIS_DT_802DOT3)
+        {
+            /* Check if we're manipulating the WLAN LED.
+             * If so, we should halt the WLAN device.
+             */
+            error = BER_NONE;
+            switch (oid)
+            {
+                case BLOB_OID_LEDSET:
+                case BLOB_OID_LEDCLEAR:
+                if ( (*data & 2) &&
+                         (dev_state(1 /* DEVICE_WLAN*/ ) == STRUNNING) )
+                {
+                    error = dev_halt(1/* DEVICE_WLAN*/);
+                }
+                break;
+                case BLOB_OID_LED_RESET:
+                if ( (*data & 2) &&
+                         (dev_state(1 /* DEVICE_WLAN*/) == STREADY) )
+                {
+                    error = dev_run(1 /* DEVICE_WLAN*/);
+                }
+                return (error < BER_NONE) ? -EINVAL : 0;
+                default:
+                /* Not one of these */
+                break;
+            }
+            if (error < BER_NONE)
+                return -EINVAL;
+
+            if ((error = blob_conf(&msg)) < BER_NONE)
+                return -EINVAL;
+        }
+        else
+        {
+            return -EOPNOTSUPP;
+        }
+    }
+    else
+#endif /* TEST_ON_POLDHU */
+
+
+    /* Send message to MVC */
+    error = dev_conf (GET_DEV_NR(dev->base_addr), &msg);
+
+    if (error == BER_OVERFLOW)
+    {
+#ifdef BLOB_V2
+        printk("Size passed to MVC (%ld) not correct. MVC needs %ld\n", data_len, msg.size);
+#else
+        printk("Size passed to MVC (%ld) not correct.\n", data_len);
+#endif
+        return -EOVERFLOW;
+    }
+
+    /* Copy the message data for retrieval by the calling function. */
+    if (msg.data != NULL)
+        memcpy(data, msg.data, data_len);
+
+    if (error < 0)
+        return -EINVAL;
+    else
+        return error;
+}
+
+
+/**********************************************************************
+ *  islmvc_send_blob_msg
+ *
+ *  DESCRIPTION: Send a message to perform on the MVC blob device.
+ *
+ *  PARAMETERS:  operation - operation to perform.
+ *               oid       - OID to perform operation on.
+ *               data      - pointer to buffer that (will) hold the data.
+ *               data_len  - length of data.
+ *
+ *  RETURN:	 0 on success.
+ *               -EINVAL on error.
+ *
+ **********************************************************************/
+int islmvc_send_blob_msg(int operation, int oid, long* data, unsigned long data_len)
+{
+    int             error;
+    struct msg_conf msg;
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "islmvc_send_blob_msg, oper %d, oid %x, data %p, len %lu. \n",
+          operation, oid, data, data_len);
+
+    msg.operation = operation;
+    msg.oid       = oid;
+    msg.data      = data;
+#ifdef BLOB_V2
+    msg.size      = data_len;
+#endif
+
+    if ((error = blob_conf(&msg)) < BER_NONE)
+        return -EINVAL;
+
+    if (msg.data != NULL)
+        memcpy(data, msg.data, data_len);
+
+    return 0;
+
+}
+
+
+/****************************************************************
+ *								*
+ *    		End of management handling functions		*
+ *								*
+ ***************************************************************/
+
+
+/****************************************************************
+ *								*
+ *    	Functions to retrieve information from the PDA      *
+ *      (Production Data Area)                  	        *
+ *								*
+ ***************************************************************/
+#define PDR_END                                 0x0000
+#define PDR_MAC_ADDRESS                         0x0101
+#define PDR_INTERFACE_LIST                      0x1001
+#define PDR_RSSI_LINEAR_APPROXIMATION_DB        0x1905
+#define PDR_ZIF_TX_IQ_CALIBR_DATA		0x1906
+
+#define BR_IF_ID_ISL39300A                      0x0010
+
+#define BR_IF_VAR_ISL39000_SYNTH_MASK           0x0007
+#define BR_IF_VAR_ISL39000_SYNTH_1              0x0001
+#define BR_IF_VAR_ISL39000_SYNTH_2              0x0002
+#define BR_IF_VAR_ISL39000_SYNTH_3              0x0003
+
+#define BR_IF_VAR_ISL39000_IQ_CAL_MASK          0x0018
+#define BR_IF_VAR_ISL39000_IQ_CAL_PA_DETECTOR   0x0000
+#define BR_IF_VAR_ISL39000_IQ_CAL_DISABLED      0x0008
+#define BR_IF_VAR_ISL39000_IQ_CAL_ZIF           0x0010
+
+#define BR_IF_VAR_ISL39000_ASM_MASK		0x0400
+#define BR_IF_VAR_ISL39000_ASM_XSWON		0x0400
+
+#define PTR_PDA_AREA_START 0x00000208 /* Contents of address defines the start of the PDA area. */
+#ifdef CONFIG_MTD_PHYSMAP_START
+static unsigned long *Pda_area_start = (unsigned long*) (CONFIG_MTD_PHYSMAP_START + PTR_PDA_AREA_START);
+#else
+// configuration not set, assume it is 0.
+static unsigned long *Pda_area_start = (unsigned long*) PTR_PDA_AREA_START;
+#endif
+
+struct Pdr_Struct {
+   unsigned short   PdrLength;
+   unsigned short   PdrCode;
+   unsigned char    PdrData[2];
+};
+
+/**********************************************************************
+ *  pda_find_pdr
+ *
+ *  DESCRIPTION: Finds a Production Data Record in the PDA. (Production Data Area)
+ *
+ *  PARAMETERS:  pdrCode - code of production data record to find.
+ *
+ *  RETURN:	 Pointer to found PDR data, or NULL when not found.
+ *
+ **********************************************************************/
+static struct Pdr_Struct *pda_find_pdr (unsigned short pdrCode)
+{
+   unsigned short   pdaOffset = 0;
+   unsigned short    *pdaPtr;    /* Used as index through the PDA pointing to start of records. */
+   struct Pdr_Struct *pdrPtr;    /* Used as pointer to the contents of the record. */
+
+   pdaPtr = (unsigned short *) *Pda_area_start;
+   pdrPtr = (struct Pdr_Struct *) pdaPtr;
+
+   DEBUG(DBG_FUNC_CALL | DBG_MGMT, "pda_find_pdr, pdrCode = %x\n", pdrCode);
+
+  /* Walk through the cached PDA and check each PDR for it's PDRcode to match the one we are looking for. */
+   while (pdrPtr->PdrCode != PDR_END) {
+      if (pdrPtr->PdrCode == pdrCode) {
+         return pdrPtr;
+      } else {
+         pdaOffset = pdrPtr->PdrLength + 1;
+         /* If we get past 8k or we have an invalid PdrLength, return NULL
+            since this indicates an invalid PDA. */
+         if ((pdaOffset > 8192) || (pdrPtr->PdrLength == 65535) || (pdrPtr->PdrLength == 0)) {
+             return (struct Pdr_Struct *)0;
+         }
+        /* point to next record */
+         pdaPtr = (unsigned short *)pdaPtr + pdaOffset;
+         pdrPtr = (struct Pdr_Struct *)pdaPtr;
+      }
+   };
+
+   if (pdrCode == PDR_END) {
+      /* If we were looking for PDR_END, we found it */
+       return pdrPtr;
+   } else {
+      /* We were looking for another PDR and did not find it */
+     return (struct Pdr_Struct *)0;
+   }
+}
+
+
+/**********************************************************************
+ *  pda_get_mac_address
+ *
+ *  DESCRIPTION: Gets the MAC address from the PDA. (Production Data Area)
+ *
+ *  RETURN:	 Pointer to MAC address, or NULL when not found.
+ *
+ **********************************************************************/
+unsigned char * pda_get_mac_address(void)
+{
+   struct Pdr_Struct *pdrStructPtr;
+
+   DEBUG(DBG_FUNC_CALL | DBG_MGMT, "pda_get_mac_address\n");
+
+   pdrStructPtr = pda_find_pdr (PDR_MAC_ADDRESS);
+   if (pdrStructPtr) {
+       return (unsigned char *)(pdrStructPtr->PdrData);
+   } else {
+       return (unsigned char *)0;
+   }
+}
+
+#ifdef BLOB_V2
+
+/**********************************************************************
+ *  pda_get_rssi_linear_approximation_db
+ *
+ *  DESCRIPTION: Gets the RSSI vector from the PDA. (Production Data Area)
+ *
+ *  RETURN:	 Pointer to data structure, or NULL when not found.
+ *
+ **********************************************************************/
+short *pda_get_rssi_linear_approximation_db(void)
+{
+    struct Pdr_Struct *pdrStructPtr;
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "pda_get_rssi_linear_approximation_db\n");
+
+    pdrStructPtr = pda_find_pdr (PDR_RSSI_LINEAR_APPROXIMATION_DB);
+    if (pdrStructPtr) {
+        return (short*)(pdrStructPtr->PdrData);
+    } else {
+        return NULL;
+    }
+}
+
+
+/**********************************************************************
+ *  pda_get_zif_tx_iq_calibr_data
+ *
+ *  DESCRIPTION: Gets the zif TX IQ calibration data  from the PDA.
+ *
+ *  RETURN:	 Pointer to data structure, or NULL when not found.
+ *
+ **********************************************************************/
+struct obj_iqtable *pda_get_zif_tx_iq_calibr_data(int *len)
+{
+    struct Pdr_Struct *pdrStructPtr;
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "pda_get_zif_tx_iq_calibr_data\n");
+
+    pdrStructPtr = pda_find_pdr (PDR_ZIF_TX_IQ_CALIBR_DATA);
+
+    *len = 2 * pdrStructPtr->PdrLength - 1;
+
+    if (pdrStructPtr) {
+        return (struct obj_iqtable*)(pdrStructPtr->PdrData);
+    } else {
+        return NULL;
+    }
+}
+
+
+/**********************************************************************
+ *  pda_get_interface_list
+ *
+ *  DESCRIPTION: Gets the interface list from the PDA.
+ *
+ *  RETURN:	 Pointer to data structure, or NULL when not found.
+ *
+ **********************************************************************/
+struct Pdr_Struct *pda_get_interface_list(void)
+{
+    struct Pdr_Struct *pdrStructPtr;
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "pda_get_interface_list\n");
+
+    pdrStructPtr = pda_find_pdr (PDR_INTERFACE_LIST);
+    if (pdrStructPtr) {
+        return pdrStructPtr;
+    } else {
+        return NULL;
+    }
+}
+
+
+/**********************************************************************
+ *  set_rssi_linear_approximation_db
+ *
+ *  DESCRIPTION: Gets the RSSI linear approximation data from the PDA,
+ *               formats it into MVC parseable format, and sends it to
+ *               the MVC.
+ *
+ *  PARAMETERS:  dev - device to do setting on.
+ *
+ *  RETURN:	 0 on success. -EINVAL on error.
+ *
+ **********************************************************************/
+int set_rssi_linear_approximation_db(struct net_device *dev)
+{
+    short *rssi_pda_data;
+    struct obj_rssivector array[2];
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "set_rssi_linear_approximation_db\n");
+
+    if ((rssi_pda_data = pda_get_rssi_linear_approximation_db()) != NULL) {
+
+        /* Convert the data from PDA format to MVC format. */
+        array[0].a = (long)(*(rssi_pda_data));
+        rssi_pda_data++;
+        array[0].b = (long)(*(rssi_pda_data));
+        rssi_pda_data++;
+        array[1].a = (long)(*(rssi_pda_data));
+        rssi_pda_data++;
+        array[1].b = (long)(*(rssi_pda_data));
+
+        if (islmvc_send_mvc_msg(dev, OPSET, DOT11_OID_RSSIVECTOR, (long*)array, sizeof(array)) < BER_NONE)
+            return -EINVAL;
+    } else {
+        printk(KERN_INFO "Could't get the RSSI Vector from the PDA.\n");
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+
+/**********************************************************************
+ *  set_zif_tx_iq_calibr_data
+ *
+ *  DESCRIPTION: Get the zif tx iq calibration data, and send it to the MVC.
+ *
+ *  PARAMETERS:  dev - device to do setting on.
+ *
+ *  RETURN:	 0 on success. -EINVAL on error.
+ *
+ **********************************************************************/
+int set_zif_tx_iq_calibr_data(struct net_device *dev)
+{
+    struct obj_iqtable *iqtable;
+    int length;
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "set_zif_tx_iq_calibr_data\n");
+
+    if ((iqtable = pda_get_zif_tx_iq_calibr_data(&length)) != NULL)
+    {
+        if (islmvc_send_mvc_msg(dev, OPSET, DOT11_OID_IQCALIBRATIONTABLE, (long*)iqtable,
+                                length) < BER_NONE)
+        {
+            printk(KERN_INFO "Couldn't set IQ Calibration Table in MVC!\n");
+            return -EINVAL;
+        }
+    }
+    else
+    {
+        printk(KERN_INFO "Couldn't get the calibration table from the PDA.\n");
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+
+/**********************************************************************
+ *  set_hw_interface_variant
+ *
+ *  DESCRIPTION: Get the interface list from the PDA, process it's contents
+ *               and send it to the MVC.
+ *
+ *  PARAMETERS:  dev - device to do setting on.
+ *
+ *  RETURN:	 0 on success. -EINVAL on error.
+ *
+ **********************************************************************/
+int set_hw_interface_variant(struct net_device *dev)
+{
+    int i;
+    unsigned short temp;
+    struct Pdr_Struct *pdrPtr;
+    u_char* p;
+    long mvc_data;
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "set_hw_interface_variant\n");
+
+    if ((pdrPtr = pda_get_interface_list()) != NULL) {
+
+        p = &(pdrPtr->PdrData[0]);
+
+        for(i=0; i < (pdrPtr->PdrLength/5); i++) {
+            p = p + 2; /* skip role */
+
+            temp = (*p);
+            p++;
+            temp |= (*p << 8);
+            if(temp == BR_IF_ID_ISL39300A) {
+                /* found the HW interface */
+                p++; /* goto variant */
+
+                temp = (*p);
+                p++;
+                temp |= (*p << 8);
+
+                /* Synthesizer */
+                if((temp & BR_IF_VAR_ISL39000_SYNTH_MASK) == BR_IF_VAR_ISL39000_SYNTH_1) {
+                    mvc_data = 15;	// CMD_RADIO_CONFIG1
+                }
+                else if((temp & BR_IF_VAR_ISL39000_SYNTH_MASK) == BR_IF_VAR_ISL39000_SYNTH_2) {
+                    mvc_data = 18;	// CMD_RADIO_CONFIG4
+                }
+                else if((temp & BR_IF_VAR_ISL39000_SYNTH_MASK) == BR_IF_VAR_ISL39000_SYNTH_3) {
+                    mvc_data = 20;	// CMD_RADIO_CONFIG6
+                }
+                else {
+                    printk(KERN_INFO "Unknown synthesizer type in PDA.\n");
+                    mvc_data = -1;
+                }
+
+                if (mvc_data != -1) {
+                    if (islmvc_send_blob_msg(OPSET, MT_OID_MTCMD, (long*)&mvc_data, sizeof(mvc_data)) < BER_NONE)
+                        return -EINVAL;
+                }
+
+                /* IQ Calibration */
+                /* NOT IMPLEMENTED in MVC (YET).
+                if((temp & BR_IF_VAR_ISL39000_IQ_CAL_MASK) == BR_IF_VAR_ISL39000_IQ_CAL_PA_DETECTOR) {
+                    mvc_data = FIXME;
+                }
+                else if((temp & BR_IF_VAR_ISL39000_IQ_CAL_MASK) == BR_IF_VAR_ISL39000_IQ_CAL_DISABLED) {
+                    mvc_data = FIXME;
+                }
+                else if((temp & BR_IF_VAR_ISL39000_IQ_CAL_MASK) == BR_IF_VAR_ISL39000_IQ_CAL_ZIF) {
+                    mvc_data = FIXME;
+                }
+                else {
+                    printk(KERN_INFO "Unknown type for IQ Calibration in PDA.\n");
+                    mvc_data = -1;
+                }
+
+                if (mvc_data != -1) {
+                    if (islmvc_send_mvc_msg(dev, OPSET, MT_OID_MTCMD, (long*)&mvc_data, sizeof(mvc_data)) < BER_NONE)
+                        return -EINVAL;
+                }
+                */
+
+		if ((temp & BR_IF_VAR_ISL39000_ASM_MASK) == BR_IF_VAR_ISL39000_ASM_XSWON)
+		    mvc_data = 29;	// CMD_ANTSEL_MODE1
+		else
+		    mvc_data = 28;	// CMD_ANTSEL_MODE0
+
+		if (islmvc_send_mvc_msg(dev, OPSET, MT_OID_MTCMD, (long*)&mvc_data, sizeof(mvc_data)) < BER_NONE)
+		{
+		    return -EINVAL;
+		}
+                return 0;
+            }
+            else {
+                p = p + 7; /* goto next interface */
+            }
+        }
+
+        printk(KERN_INFO "No HW interface for the ISL39300A found in PDR INTERFACE_LIST !\n");
+    }
+    else {
+        printk(KERN_INFO "Couldn't get the interface list from the PDA.\n");
+    }
+
+    return -EINVAL;
+}
+
+#endif /* BLOB_V2 */
+
+/****************************************************************
+ *								*
+ *      	End of PDA retrieve functions                   *
+ *								*
+ ***************************************************************/
+
+
+/****************************************************************
+ *
+ *    			WDS Link handlers
+ *
+ ***************************************************************/
+
+static int islmvc_wdslink_add_hndl( unsigned int dev_id,   unsigned int dev_seq,
+                             unsigned int src_id,   unsigned int src_seq,
+                             unsigned int op,       unsigned int oid, void *data, unsigned long len)
+{
+    struct net_device *dev;
+    struct wds_link_msg *wlmp;
+    struct wds_priv *wdsp;
+
+    _DEBUG(DBG_FUNC_CALL | DBG_MGMT, "islmvc_wdslink_add_hndl, dev_id %d, dev_seq %d, src_id %d, src_seq %d, op %d, oid %x, data %p, len %lu \n",
+          dev_id, dev_seq, src_id, src_seq, op, oid, data, len);
+
+    if ( len != sizeof(struct wds_link_msg))
+        return -1;
+
+    wlmp = (struct wds_link_msg *)data;
+
+    if ( ! (dev = dev_get_by_index(dev_seq)) )
+        return -1;
+	dev_put( dev );
+
+    wdsp = ((struct net_local *)dev->priv)->wdsp;
+
+    if ( add_wds_link(dev, wdsp, wlmp->mac, wlmp->name) < 0 )
+        return -1;
+
+    if ( islmvc_send_mvc_msg( dev, op, oid, (long *)wlmp->mac, 6 ) < 0 )
+        return -1;
+
+    /* open the dot1X data port for the AP link */
+    if ( islmvc_send_mvc_msg( dev, op, DOT11_OID_EAPAUTHSTA, (long *)wlmp->mac, 6 ) < 0 )
+        return -1;
+
+    /*
+    printk ( KERN_ERR "islmvc_wdslink_add_hndl(%x.%x.%x.%x.%x.%x, %s)\n",
+             wlmp->mac[0], wlmp->mac[1], wlmp->mac[2], wlmp->mac[3], wlmp->mac[4], wlmp->mac[5], wlmp->name );
+    */
+    if ( (mgt_response( src_id, src_seq, dev_id, dev_seq, PIMFOR_OP_RESPONSE, oid, data, len)) < 0 )
+        return -1;
+
+    return 0;
+}
+
+static int islmvc_wdslink_del_hndl( unsigned int dev_id,   unsigned int dev_seq,
+                             unsigned int src_id,   unsigned int src_seq,
+                             unsigned int op,       unsigned int oid, void *data, unsigned long len)
+{
+    struct net_device *dev;
+    struct wds_link_msg *wlmp;
+    struct wds_priv *wdsp;
+
+    _DEBUG(DBG_FUNC_CALL | DBG_MGMT,
+          "islmvc_wdslink_del_hndl, dev_id %d, dev_seq %d, src_id %d, src_seq %d, op %d, oid %x, data %p, len %lu \n",
+          dev_id, dev_seq, src_id, src_seq, op, oid, data, len);
+
+    if ( len != sizeof(struct wds_link_msg))
+        return -1;
+
+    wlmp = (struct wds_link_msg *)data;
+
+    if ( ! (dev = dev_get_by_index(dev_seq)) )
+        return -1;
+   	dev_put( dev );
+
+    wdsp = ((struct net_local *)dev->priv)->wdsp;
+
+    /* close the dot1X data port for the AP link */
+
+    if ( islmvc_send_mvc_msg( dev, op, DOT11_OID_EAPUNAUTHSTA, (long *)wlmp->mac, 6 ) < 0 )
+        return -1;
+
+    if ( islmvc_send_mvc_msg( dev, op, oid, (long *)wlmp->mac, 6 ) < 0 )
+        return -1;
+
+    if ( del_wds_link(dev, wdsp, wlmp->mac, wlmp->name ) < 0 )
+        return -1;
+
+    /*
+    printk ( KERN_ERR "islmvc_wdslink_del_hndl(%x.%x.%x.%x.%x.%x, %s)\n",
+             wlmp->mac[0], wlmp->mac[1], wlmp->mac[2], wlmp->mac[3], wlmp->mac[4], wlmp->mac[5], wlmp->name );
+    */
+    if ( (mgt_response( src_id, src_seq, dev_id, dev_seq, PIMFOR_OP_RESPONSE, oid, data, len)) < 0 )
+        return -1;
+
+    return 0;
+}
+
+/****************************************************************
+ *
+ *    			DOT11 OID Attachment handler
+ *
+ ***************************************************************/
+static int islmvc_dot11_oid_attachment_hndl( unsigned int dev_id,   unsigned int dev_seq,
+                             unsigned int src_id,   unsigned int src_seq,
+                             unsigned int op,       unsigned int oid, void *data, unsigned long len)
+{
+    struct net_device *dev;
+
+    _DEBUG(DBG_FUNC_CALL | DBG_MGMT,
+          "islmvc_dot11_oid_attachment_hndl, dev_id %d, dev_seq %d, src_id %d, src_seq %d, op %d, oid %x, data %p, len %lu \n",
+          dev_id, dev_seq, src_id, src_seq, op, oid, data, len);
+
+    if ( ! (dev = dev_get_by_index(dev_seq)) )
+        return -1;
+	dev_put( dev );
+
+    if ( mgmt_set_oid_attachment(data, dev, len) < 0 )
+        return -1;
+
+    if ( (mgt_response( src_id, src_seq, dev_id, dev_seq, PIMFOR_OP_RESPONSE, oid, data, len)) < 0 )
+        return -1;
+
+    return 0;
+}
+
+
+/****************************************************************
+ *
+ *   		DOT11 OID Authentication/Association handlers
+ *
+ ***************************************************************/
+
+#ifdef HANDLE_ASSOC_IN_DRIVER
+/**********************************************************************
+ *
+ *  mgmt_authenticate
+ *
+ **********************************************************************/
+static void mgmt_authenticate (struct net_device *dev, char *data)
+{
+   struct obj_mlme *obj = (struct obj_mlme*) data;
+
+   DEBUG(DBG_FUNC_CALL | DBG_MGMT, "mgmt_authenticate, dev %s, data %p, (macaddress %s) \n",
+         dev->name, data, hwaddr2string(obj->address));
+
+   /* When there's no authentication application, we succeed always via this way... */
+   if (obj->state == DOT11_STATE_AUTHING)
+   {
+       obj->code  = 0; // = DOT11_SC_SUCCESFUL;
+       islmvc_send_mvc_msg(dev, OPSET, DOT11_OID_AUTHENTICATE, (long *) obj, sizeof(struct obj_mlme));
+   }
+
+}
+
+
+/* DOT11_OID_AUTHENTICATE */
+static int islmvc_dot11_oid_authenticate_hndl( unsigned int src_id, unsigned int src_seq,
+                                     unsigned int dev_id,   unsigned int dev_seq,
+                                     unsigned int op,       unsigned int oid, void *data, unsigned long len)
+{
+    struct net_device *dev;
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT,
+          "islmvc_dot11_oid_authenticate_hndl, src_id %d, src_seq %d, dev_id %d, dev_seq %d, op %d, oid %x, data %p, len %lu \n",
+          src_id, src_seq, dev_id, dev_seq, op, oid, data, len);
+
+    if ( ! (dev = dev_get_by_index(dev_seq)) )
+        return -1;
+	dev_put( dev );
+
+    mgmt_authenticate (dev, (char*) data);
+
+    return 0;
+}
+
+
+/**********************************************************************
+ *
+ *  mgmt_associate
+ *
+ **********************************************************************/
+static void mgmt_associate (struct net_device *dev, char *data)
+{
+   struct obj_mlme *obj = (struct obj_mlme*) data;
+
+   DEBUG(DBG_FUNC_CALL | DBG_MGMT, "mgmt_associate, dev %s, macaddress = %s\n",
+         dev->name, hwaddr2string(obj->address));
+
+   if (obj->state == DOT11_STATE_ASSOCING)
+   {
+       /* When there's no authentication application, we succeed always via this way... */
+       obj->code  = 0; // = DOT11_SC_SUCCESFUL;
+       islmvc_send_mvc_msg(dev, OPSET, DOT11_OID_ASSOCIATE, (long *) obj, sizeof(struct obj_mlme));
+   }
+}
+
+
+/* DOT11_OID_ASSOCIATE */
+static int islmvc_dot11_oid_associate_hndl( unsigned int src_id, unsigned int src_seq,
+                                     unsigned int dev_id,   unsigned int dev_seq,
+                                     unsigned int op,       unsigned int oid, void *data, unsigned long len)
+{
+    struct net_device *dev;
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT,
+          "islmvc_dot11_oid_associate_hndl, src_id %d, src_seq %d, dev_id %d, dev_seq %d, op %d, oid %x, data %p, len %lu \n",
+          src_id, src_seq, dev_id, dev_seq, op, oid, data, len);
+
+    if ( ! (dev = dev_get_by_index(dev_seq)) )
+        return -1;
+	dev_put( dev );
+
+    mgmt_associate (dev, (char*) data);
+
+    return 0;
+}
+
+#endif /* HANDLE_ASSOC_IN_DRIVER */
+
+
+
+#ifdef HANDLE_IAPP_IN_DRIVER
+/**********************************************************************
+ *
+ *              IAPP update frame generation
+ *
+ **********************************************************************/
+
+static int islmvc_gen_iappframe_hndl( unsigned int src_id, unsigned int src_seq,
+                                     unsigned int dev_id, unsigned int dev_seq,
+                                     unsigned int op, unsigned int oid, void *data, unsigned long len)
+{
+    struct obj_mlme *obj = (struct obj_mlme*) data;
+    struct net_device *dev;
+    struct sk_buff *skb;
+    unsigned char buf[20];
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT,
+          "islmvc_gen_iappframe_hndl, src_id %d, src_seq %d, dev_id %d, dev_seq %d, op %d, oid %x, data %p, len %lu \n",
+          src_id, src_seq, dev_id, dev_seq, op, oid, data, len);
+
+    if ( ! (dev = dev_get_by_index(dev_seq)) )
+        return -1;
+	dev_put( dev );
+
+    if (obj->state == DOT11_STATE_ASSOC)
+    {
+        // the client is successfully associated, now generate the IAPP update frame
+        DEBUG( DBG_MGMT, "islmvc_gen_iappframe_hndl, client %02x:%02x:%02x:%02x:%02x:%02x associated successfully \n",
+            obj->address[0], obj->address[1], obj->address[2], obj->address[3], obj->address[4], obj->address[5] );
+
+        memset(buf, 0xff, 6);		        // Broadcast Destination address
+        memcpy(buf + 6, obj->address, 6);	// Source address of associated client
+
+        buf[12] = 0;			        // Length of payload = 6 octets
+        buf[13] = 6;
+        buf[14] = 0;			        // DSAP
+        buf[15] = 0;			        // SSAP
+        buf[16] = 175;			        // Control field
+
+        buf[17] = 129;			        // XID = 129.1.0
+        buf[18] = 1;
+        buf[19] = 0;
+
+        skb = dev_alloc_skb(20+2);
+
+        if (skb)
+        {
+	    memcpy(skb_put(skb, 20), buf, 20);
+            skb->dev = dev;
+            skb->protocol = eth_type_trans(skb, dev);
+            skb->ip_summed = CHECKSUM_UNNECESSARY;
+            netif_rx(skb);
+        }
+        else
+        {
+            printk("Unable to allocate skb for IAPP update frame\n");
+        }
+    }
+
+    // pass on the frame to higher layer applications
+    return mgt_confirm( src_id, src_seq, dev_id, dev_seq, op, oid, data, len);
+}
+
+#endif /* HANDLE_IAPP_IN_DRIVER */
+
+
+/****************************************************************
+ *
+ *   		GENERIC OID SET/CLEAR LED handlers
+ *
+ ***************************************************************/
+
+#ifdef BLOB_V2
+static int islmvc_gen_oid_led_set_hndl( unsigned int dev_id,   unsigned int dev_seq,
+                             unsigned int src_id,   unsigned int src_seq,
+                             unsigned int op,       unsigned int oid, void *data, unsigned long len)
+{
+    struct net_device *dev;
+
+    _DEBUG(DBG_FUNC_CALL | DBG_MGMT,
+          "islmvc_gen_oid_les_set_hndl, src_id %d, src_seq %d, dev_id %d, dev_seq %d, op %d, oid %x, data %p, len %lu \n",
+          src_id, src_seq, dev_id, dev_seq, op, oid, data, len);
+
+    if ( ! (dev = dev_get_by_index(dev_seq)) )
+        return -1;
+	dev_put( dev );
+
+    if ( mgmt_set_led(dev, LED_SET) < 0 )
+        return -1;
+
+    if ( (mgt_response( src_id, src_seq, dev_id, dev_seq, PIMFOR_OP_RESPONSE, oid, data, len)) < 0 )
+        return -1;
+
+    return 0;
+}
+
+
+static int islmvc_gen_oid_led_clear_hndl( unsigned int dev_id,   unsigned int dev_seq,
+                             unsigned int src_id,   unsigned int src_seq,
+                             unsigned int op,       unsigned int oid, void *data, unsigned long len)
+{
+    struct net_device *dev;
+
+    _DEBUG(DBG_FUNC_CALL | DBG_MGMT,
+          "islmvc_gen_oid_led_clear_hndl, src_id %d, src_seq %d, dev_id %d, dev_seq %d, op %d, oid %x, data %p, len %lu \n",
+          src_id, src_seq, dev_id, dev_seq, op, oid, data, len);
+
+    if ( ! (dev = dev_get_by_index(dev_seq)) )
+        return -1;
+	dev_put( dev );
+
+    if ( mgmt_set_led(dev, LED_CLEAR) < 0 )
+        return -1;
+
+    if ( (mgt_response( src_id, src_seq, dev_id, dev_seq, PIMFOR_OP_RESPONSE, oid, data, len)) < 0 )
+        return -1;
+
+    return 0;
+}
+#endif /* BLOB_V2 */
+
+
+/****************************************************************
+ *
+ *    			Client table functions
+ *
+ ***************************************************************/
+
+#ifdef ENABLE_CLIENT_TABLE_CODE
+
+/**********************************************************************
+ *  mac_hash
+ *
+ *  DESCRIPTION: Computes hash value for a given mac-address.
+ *               Taken from bridging code by Lennert Buytenhek.
+ *
+ *  PARAMETERS:	 Pointer to mac address.
+ *
+ *  RETURN:      Hash value.
+ *
+ *  NOTE:        Inline function.
+ *
+ **********************************************************************/
+static inline int mac_hash(unsigned char *mac)
+{
+    unsigned long x;
+
+    //FIXME, use faster hash func.
+
+    x = mac[0];
+    x = (x << 2) ^ mac[1];
+    x = (x << 2) ^ mac[2];
+    x = (x << 2) ^ mac[3];
+    x = (x << 2) ^ mac[4];
+    x = (x << 2) ^ mac[5];
+
+    x ^= x >> 8;
+
+    return x & (MAC_HASH_SIZE - 1);
+}
+
+
+/*
+ * Inline function that links client into the association table.
+ */
+static inline void client_link(struct net_local *lp, struct client_information *cip, int hash)
+{
+	cip->next_client = lp->assoc_table[hash];
+
+        if(cip->next_client != NULL)
+            cip->next_client->pprev_client = &cip->next_client; //FIXME, check neccesity...
+        lp->assoc_table[hash] = cip;
+        cip->pprev_client = &lp->assoc_table[hash];
+}
+
+
+/*
+ * Inline function that removes client from the association table.
+ */
+static inline void client_unlink(struct client_information *cip)
+{
+	*(cip->pprev_client) = cip->next_client;
+	if (cip->next_client != NULL)
+		cip->next_client->pprev_client = cip->pprev_client;
+	cip->next_client = NULL;
+	cip->pprev_client= NULL;
+}
+
+
+/**********************************************************************
+ *  mgmt_find_client
+ *
+ *  DESCRIPTION: Searches the association table of the device for the
+ *               given client mac-address.
+ *
+ *  PARAMETERS:	 - pointer to device that holds the association table.
+ *               - pointer to mac address we're searching for.
+ *
+ *  RETURN:      Pointer to client_information struct or
+ *               NULL when client is not found.
+ *
+ *  NOTE:        Inline function.
+ *
+ **********************************************************************/
+static inline struct client_information *mgmt_find_client(struct net_device *dev, char *address)
+{
+    struct net_local *lp = dev->priv;
+    int hash = mac_hash(address);
+    struct client_information *cip = lp->assoc_table[hash];
+
+    while(cip != NULL)
+    {
+        if (!memcmp(cip->mac_addr, address, ETH_ALEN))
+            return (cip);
+
+        cip = cip->next_client;
+    }
+
+    _DEBUG(DBG_MGMT, "Address %s not found in assoc table... \n", hwaddr2string(address));
+
+    return NULL;
+}
+
+
+static int mgmt_add_client(struct net_device *dev, char *address)
+{
+    struct client_information *cip;
+    struct net_local *lp = dev->priv;
+    int hash;
+
+    hash = mac_hash(address);
+
+    cip = lp->assoc_table[hash];
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "mgmt_add_client, dev = %s, hash = %i, addr = %s \n",
+                    dev->name, hash, hwaddr2string(address));
+
+    while(cip != NULL)
+    {
+        if (!memcmp(cip->mac_addr, address, ETH_ALEN))
+        {
+            DEBUG(DBG_MGMT, "address %s already in assoc_table...\n", hwaddr2string(address));
+            return -EINVAL;
+        }
+
+        cip = cip->next_client;
+    }
+
+    cip = kmalloc(sizeof(*cip), GFP_ATOMIC);
+    if (cip == NULL)
+    {
+        printk("Unable to allocate memory for client \n");
+        return -ENOMEM;
+    }
+
+    DEBUG(DBG_MGMT, "Address %s not yet in table, going to add it...", hwaddr2string(address));
+
+    /* Fill in the client information fields... */
+    memcpy(cip->mac_addr, address, ETH_ALEN);
+
+    /* Link the client into the assoc table... */
+    client_link(lp, cip, hash);
+
+    return 0;
+
+}
+
+
+/*
+ * mgmt_del_client
+ *
+ * Removes a client from the assoc table of the device.
+ *
+ * RETURN: 0 when client is removed from assocation table.
+ *        -1 when client is not removed from assocation table.
+ */
+static int mgmt_del_client(struct net_device *dev, char *address)
+{
+    struct client_information *cip;
+    struct net_local *lp = dev->priv;
+    int hash;
+
+    hash = mac_hash(address);
+
+    cip = lp->assoc_table[hash];
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "mgmt_del_client, dev = %s, hash = %i, addr = %s \n",
+                    dev->name, hash, hwaddr2string(address));
+
+    while(cip != NULL)
+    {
+        if (!memcmp(cip->mac_addr, address, ETH_ALEN))
+        {
+            DEBUG(DBG_MGMT, "found address %2.2x.%2.2x.%2.2x.%2.2x.%2.2x.%2.2x to remove from assoc_table...\n",
+                   address[0], address[1], address[2], address[3], address[4], address[5]);
+
+            client_unlink(cip);
+            kfree(cip);
+            return 0;
+        }
+
+        cip = cip->next_client;
+    }
+
+    DEBUG(DBG_MGMT, "Address %2.2x.%2.2x.%2.2x.%2.2x.%2.2x.%2.2x not found in assoc table... \n",
+                    address[0], address[1], address[2], address[3], address[4], address[5]);
+
+    return -1;
+}
+
+#endif /* ENABLE_CLIENT_TABLE_CODE */
+
+
+/**********************************************************************
+ *  mgmt_make_obj_attachment
+ *
+ *  DESCRIPTION: Calculates the size of all cached information elements.
+ *               Mallocs a new obj attachment with this size.
+ *               Copies all information elements into the data of this
+ *               obj attachment.
+ *
+ *  PARAMETERS:	 Pointer to frame_attachment struct.
+ *               Pointer to old object attachment for oa type and id.
+ *
+ *  RETURN:	 Pointer to new object attachment when succesfully malloced
+ *               and data succesfully copied.
+ *               NULL when information element == NULL or kmalloc failed.
+ *
+ **********************************************************************/
+static struct obj_attachment *mgmt_make_obj_attachment(struct frame_attachment *fa, struct obj_attachment *old_oa)
+{
+    int i;
+
+    int totalsize = 0;
+    int offset = 0;
+    struct information_element *ie = fa->ie_root;
+    struct obj_attachment *oa = NULL;
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "mgmt_make_obj_attachment, fa %p, old_oa %p \n", fa, old_oa);
+
+    if (ie == NULL)
+    {
+        printk(KERN_WARNING "No information elements for this attachment found. \n");
+        return NULL;
+    }
+
+    /* We need to determine the total size of the information elements first. */
+    for (i=0; (i <= MAX_IE_ELEMENTS && ie != NULL); i++, ie=ie->next)
+        totalsize += (short)ie->size;
+
+    /* Set the pointer back to it's roots... */
+    ie = fa->ie_root;
+
+    /* Malloc a buffer for the obj_attachment + the data. */
+    if ( (oa = kmalloc( (sizeof(struct obj_attachment) + totalsize), GFP_KERNEL)) == NULL)
+        return NULL;
+
+    oa->type = old_oa->type;
+    oa->id   = old_oa->id;
+    oa->size = totalsize;
+
+    /* Copy the information elements into the buffer. */
+    for (i=0; (i <= MAX_IE_ELEMENTS && ie != NULL); i++, ie=ie->next)
+     {
+        if (ie->data == NULL || ie->size == 0)
+            continue;
+        memcpy((oa->data+offset), ie->data, ie->size);
+        offset += ie->size;
+    }
+
+    return(oa);
+}
+
+/**********************************************************************
+ *  mgmt_create_information_element
+ *
+ *  DESCRIPTION: Checks if we have an information element for this element id.
+ *               If so, it replaces the current element data for the new one,
+ *               or removes the element when size == 0.
+ *               If no previous information element for this id was found,
+ *               a new information element is malloced, and put into the list.
+ *
+ *  PARAMETERS:  Pointer to frame_attachment for this frame type.
+ *               Pointer to the information element data. Contains element id.
+ *               ie_size, which is the size of ie_data.
+ *
+ *  RETURN:	 0 when succesfully added or replaced.
+ *               1 when succesfully removed.
+ *               -ENOENT when the supplied element was not found in the cache
+ *               -ENOSPC when MAX_IE_ELEMENTS was reached.
+ *               -ENOMEM when we couldn't allocate memory for the information
+ *               element or elements data.
+ *
+ **********************************************************************/
+static int mgmt_create_information_element(struct frame_attachment *fa, char *ie_data, short ie_size)
+{
+    int i;
+    unsigned char elem_id;
+
+    struct information_element *ie   = fa->ie_root;
+    struct information_element *prev = ie;
+
+    /* The element id should be set as first parameter in the information element data. */
+    elem_id  = *ie_data;
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "mgmt_create_information_element, fa %p, ie_data %p, ie_size %d\n", fa, ie_data, ie_size);
+
+    /* Check if we have an id for this element */
+    for (i=0; (ie != NULL && i <= MAX_IE_ELEMENTS); i++)
+    {
+        if (ie->elem_id == elem_id)
+        {
+            if (ie->data == NULL)
+                DEBUG(DBG_MGMT, "Found information element, but it contains no data. \n");
+
+            DEBUG(DBG_MGMT, "Found information element %d with size %d\n", ie->elem_id, ie->size);
+
+            /* Valid information elements must have a size greater than 1. */
+            if (ie_size <= 1)
+            {
+                DEBUG(DBG_MGMT, "Going to remove information element %d \n", elem_id);
+
+                if (ie == fa->ie_root)
+                    fa->ie_root = ie->next;
+                else
+                    prev->next = ie->next;
+                kfree(ie);
+                return 1;
+            }
+            else
+            {
+                /* If size is the same or less as the previous data size and we have a buffer, copy the data */
+                if (ie->size <= ie_size && ie->data != NULL)
+                {
+                    ie->size = ie_size;
+                    memcpy(ie->data, ie_data, ie->size);
+                    DEBUG(DBG_MGMT, "IE size (%d) is same or less as the previous data size (%d). \n", ie_size, ie->size);
+                }
+                else
+                {
+                    /* We need to malloc a new area for the data. */
+                    kfree(ie->data); /* Free the old area first! */
+
+                    if ( (ie->data = kmalloc(ie_size, GFP_KERNEL)) == NULL)
+                    {
+                        printk(KERN_ERR "kmalloc of data for information element %d failed. \n", ie->elem_id);
+                        ie->size = 0;
+                        return -ENOMEM;
+                    }
+                    ie->size = ie_size;
+                    memcpy(ie->data, ie_data, ie->size);
+                    DEBUG(DBG_MGMT, "IE size (%d) is greater then the previous data size (%d). \n", ie_size, ie->size);
+                }
+
+                return 0;
+            }
+        }
+        else
+        {
+            prev = ie;
+            ie   = ie->next;
+        }
+    }
+
+    if (i == MAX_IE_ELEMENTS)
+    {
+        printk(KERN_WARNING "Element not found. Maximum information elements (%d) reached. \n", MAX_IE_ELEMENTS);
+        return -ENOSPC;
+    }
+
+    /* No element has been found in the cache mathing the supplied element ID */
+    DEBUG(DBG_MGMT, "We didn't find an element... add it.\n");
+
+    if (ie_size == 0) {
+        /* If ie_size == 0, we're asked to remove this element.
+           But since we didn't find an element in our list we can't do that. */
+        DEBUG(DBG_MGMT, "Asked to remove information element (%d), but no previous element found. \n", elem_id);
+        return -ENOENT;
+    }
+
+    /* Malloc a new information element. */
+    if ( (ie = kmalloc(sizeof(struct information_element), GFP_KERNEL)) == NULL) {
+        printk("Couldn't malloc memory for information element. \n");
+        return -ENOMEM;
+    }
+
+    ie->elem_id = elem_id;
+    ie->size    = 0;
+    ie->data    = NULL;
+    ie->next    = NULL;
+
+    if ( (ie->data = kmalloc(ie_size, GFP_KERNEL)) == NULL)
+    {
+        printk(KERN_ERR "kmalloc of data for information element failed. \n");
+        kfree(ie);
+        ie->size = 0;
+        return -ENOMEM;
+    }
+    ie->size = ie_size;
+    memcpy(ie->data, ie_data, ie_size);
+
+    /* Add the information element to the list. */
+    DEBUG(DBG_MGMT, "Add the information element to the list.\n");
+    ie->next    = fa->ie_root;
+    fa->ie_root = ie;
+    return 0;
+}
+
+
+/**********************************************************************
+ *  find_frame_attach
+ *
+ *  DESCRIPTION: Tries to find a frame attachment for frame type and
+ *               association id.
+ *
+ *  PARAMETERS:	 type - type of frame attachment.
+ *               id   - association id.
+ *
+ *  RETURN:	 - pointer to frame attachment when found.
+ *               - new frame attachment for this type when no frame attachment was
+ *                 found and malloc of new frame attachment succeeded.
+ *               - NULL when malloc failed.
+ *
+ **********************************************************************/
+static struct frame_attachment *find_frame_attach(short type, short id)
+{
+    struct frame_attachment *fa   = frame_attach[type][id];
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "find_frame_attach, type %x, id(+1) %x, (fa = %p).\n", type, id, fa);
+
+    if (fa == NULL) /* Not found */
+    {
+        /* No previous frame_attachment for this type and id. Malloc one. */
+        if ( (fa = kmalloc(sizeof(struct frame_attachment), GFP_KERNEL)) == NULL)
+        {
+            printk(KERN_ERR "Couldn't malloc space for frame_attachment. \n");
+            return NULL;
+        }
+        fa->next        = NULL;
+        fa->frame_type  = type;
+        fa->ie_root     = NULL;
+        fa->all_ie_data = NULL;
+
+        frame_attach[type][id] = fa;
+        DEBUG(DBG_MGMT, "find_frame_attach, no frame attachment found. Added it to the list. fa = %p\n", fa);
+        return(fa);
+    }
+    else {/* Found it */
+        DEBUG(DBG_MGMT, "find_frame_attach, frame attachment found. fa = %p\n", fa);
+        return(fa);
+
+    }
+}
+
+/**********************************************************************
+ *  mgmt_cache_frame_attachment
+ *
+ *  DESCRIPTION: Information elements in frame attachments must be cached
+ *               in the driver, as the MVC won't do that for us.
+ *
+ *  PARAMETERS:	 data       - pointer to the struct obj_attachment.
+ *               data_len   - length of the
+ *               dev        - pointer to device we need to send information
+ *                            elements to.
+ *
+ *  RETURN:	 0  when caching and sending the information elements to
+ *                  the MVC succeeded.
+ *               -1 when caching and sending information elements to the
+ *                  MVC failed.
+ *
+ **********************************************************************/
+static int mgmt_cache_frame_attachment(struct net_device *dev, char *data)
+{
+    int error;
+    struct obj_attachment   del_oa;
+
+    struct frame_attachment *fa     = NULL;
+    struct obj_attachment   *oa     = NULL;
+    struct obj_attachment   *old_oa = (struct obj_attachment *)data;
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "mgmt_cache_frame_attachment, dev %s, data %p \n", dev->name, data);
+
+    /* Find the corresponding frame_attachment for this type and id. If none exists, one is malloced for us.*/
+    if ( (fa = find_frame_attach(old_oa->type, old_oa->id+1)) == NULL) { /* id+1, as id can be -1. We map -1 to 0 this way. */
+        printk(KERN_ERR "Couldn't malloc space for frame attachment. \n");
+        return -ENOMEM;
+    }
+
+    /* Create information element in this frame attachment. */
+    if (error = mgmt_create_information_element(fa, old_oa->data, old_oa->size),
+        (error == -ENOSPC) || (error == -ENOMEM)) {
+        printk(KERN_WARNING "Error %d. Couldn't create information element in frame attachment (type %d, id %d). \n", error, old_oa->type, old_oa->id);
+        return -1;
+    }
+    else if ( error == -ENOENT )
+    {
+        DEBUG(DBG_MGMT, "Couldn't find information element in frame attachment (data %d). \n", old_oa->data);
+    }
+
+    /* Okay, we have a valid list of information elements now. Place them in one obj attachment. */
+    oa = mgmt_make_obj_attachment(fa, old_oa);
+
+    if (oa == NULL) {
+        printk(KERN_ERR "Couldn't make new object attachment for information elements. \n");
+        return -ENOMEM;
+    }
+
+    /* Delete/invalidate old attachment data on the MVC. */
+    del_oa.type = fa->frame_type;
+    del_oa.id   = old_oa->id;
+    del_oa.size = 0;
+
+    if (islmvc_send_mvc_msg(dev, OPSET, DOT11_OID_ATTACHMENT, (long*)&del_oa, sizeof(struct obj_attachment)) < BER_NONE)
+        printk(KERN_WARNING "Couldn't delete old attachment data (type = %x) from MVC.\n", fa->frame_type);
+
+    /* Now send the new attachment to the MVC. */
+    error = islmvc_send_mvc_msg(dev, OPSET, DOT11_OID_ATTACHMENT, (long*)oa, oa->size);
+
+    kfree(oa); /* No need to save it, as all data is available in the information elements list. */
+
+    if (error < 0) {
+        DEBUG(DBG_MGMT, "Error %d setting DOT11_OID_ATTACHMENT. \n", error);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+/**********************************************************************
+ *  mgmt_set_oid_attachment
+ *
+ *  DESCRIPTION: Information elements in frame attachments for management
+ *               frame types must be cached in the driver,
+ *               as the MVC won't do that for us.
+ *
+ *  PARAMETERS:	 data       - pointer to the struct obj_attachment.
+ *               dev        - pointer to device we need to send information
+ *                            elements to.
+ *               length     - Length of obj_attachment.
+ *
+ *  RETURN:	 0  when caching and sending the information elements to
+ *                  the MVC succeeded.
+ *               -1 when caching and sending information elements to the
+ *                  MVC failed.
+ *
+ **********************************************************************/
+static int mgmt_set_oid_attachment(char *data, struct net_device *dev, unsigned long length)
+{
+    int err;
+
+    struct obj_attachment *oa = (struct obj_attachment *)data;
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "mgmt_set_oid_attachment, data %p, dev %s, length %lu, (type = %x) \n",
+          data, dev->name, length, oa->type);
+
+    /* Only cache information elements for management frame types.
+       Send all other frame attachments through un-cached.*/
+    if ((oa->type & 0x0C /* D11FT_RESERVED */) != 0) {
+        DEBUG(DBG_MGMT, "mgmt_set_oid_attachment, No management frame type. Send through uncached. \n");
+        return (islmvc_send_mvc_msg(dev, OPSET, DOT11_OID_ATTACHMENT, (long*)data, length));
+    }
+
+    if ( (err = mgmt_cache_frame_attachment(dev, data)) != 0)
+        return -1;
+
+    return 0;
+}
+
+
+/**********************************************************************
+ *  mgmt_set_led
+ *
+ *  DESCRIPTION: Sets or clears the LED for device dev.
+ *
+ *  PARAMETERS:  dev - pointer to device we want to set the LED for.
+ *               mode - set or clear the LED.
+ *
+ *  RETURN:	 0  when setting/clearing the LED succeeded
+ *               -1 when setting/clearing the LED failed.
+ *
+ *  NOTE:       This code is ISL3893 specific.
+ *
+ **********************************************************************/
+#ifdef BLOB_V2
+int mgmt_set_led(struct net_device *dev, int mode)
+{
+    long data, mask, led;
+    long bank = 3; /* GP bank 3 */
+
+    DEBUG(DBG_FUNC_CALL | DBG_MGMT, "mgmt_set_led for %s, mode: %s led.\n",
+          dev->name, (mode == LED_SET ? "set" : "clear"));
+
+    /* Determine which LED to set/clear. */
+    switch (GET_DEV_NR(dev->base_addr))
+    {
+        case ETH_LAN: {
+            led = GPIO3_MASK_LED3;
+            break;
+        }
+        case ETH_WLAN: {
+            /* Beware, to set/clear wireless LED, ledconfig must be either 0, or 
+               wireless interface must be stopped. Otherwise, the MVC is driving 
+               the WLAN LED, and change is not reflected on the LED.
+               It's the users responsibility to do this.
+            */   
+            led = GPIO3_MASK_LED1;            
+            break;
+        }
+        case ETH_WAN: {
+            led = GPIO3_MASK_LED2;
+            break;
+        }
+        default: {
+            // FIXME: For demo LMAC crashes flash the USR1 LED !
+            led = GPIO3_MASK_LED0;
+//            return -1;
+        }
+    }
+
+    mask = gpio_set(led);
+
+    if (mode == LED_SET) {
+        data = gpio_set(led);
+    } else if (mode == LED_CLEAR) {
+        data = gpio_clr(led);
+    } else {
+        printk("Unknown mode (%d) for mgmt_set_led.\n", mode);
+        return -1;
+    }
+
+    /* Select the GPIO bank for this LED */
+    if (islmvc_send_blob_msg(OPSET, BLOB_OID_GPIOBANK, &bank, sizeof(long)) < 0)
+        return -1;
+    /* Set the GPIO Data Direction for this LED (ddr == mask) */
+    if (islmvc_send_blob_msg(OPSET, BLOB_OID_GPIODDR, &mask, sizeof(long)) < 0)
+        return -1;
+    /* Set the GPIO write mask for this LED*/
+    if (islmvc_send_blob_msg(OPSET, BLOB_OID_GPIOWM, &mask, sizeof(long)) < 0)
+        return -1;
+    /* Write the data to the GPIO bank */
+    if (islmvc_send_blob_msg(OPSET, BLOB_OID_GPIODATA, &data, sizeof(long)) < 0)
+        return -1;
+    
+    return 0;
+}
+#endif /* BLOB_V2 */
+
+
+/****************************************************************
+ *								*
+ *    			End of management functions		*
+ *								*
+ ***************************************************************/
+
+
+/***************************************************************
+*								*
+*    		Start of generic functions		        *
+*								*
+***************************************************************/
+
+
+void do_hard_print(char *string)
+{
+
+#ifdef CONFIG_POLDEBUG_PRINTK
+
+       struct msg_data debug_msg;
+
+       debug_msg.data = string;
+       debug_msg.length = strlen(string) + 1;
+       debug_msg.max = 0;
+
+       dev_write(DEVICE_DEBUG, &debug_msg);
+
+#endif /* CONFIG_POLDEBUG_PRINTK */
+
+}
+
+
+/*
+ * Returns a pointer to the human-readable hardware address of
+ * the client. Buffer is static from function and overwritten
+ * with each call
+ */
+char *hwaddr2string(char *a)
+{
+    static char buf[18];
+
+    snprintf(buf, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
+	    a[0], a[1], a[2], a[3], a[4], a[5]);
+
+    return(buf);
+}
+
+
+/****************************************************************
+ *								*
+ *    		    End of generic functions                    *
+ *								*
+ ***************************************************************/
+
+#ifdef BLOB_V2
+EXPORT_SYMBOL(mgmt_set_led);
+#endif
+EXPORT_SYMBOL(pda_get_mac_address);
diff -urN linux-2.4.29/drivers/net/intersil/islmvc_mgt.h linux-2.4.29-uc1/drivers/net/intersil/islmvc_mgt.h
--- linux-2.4.29/drivers/net/intersil/islmvc_mgt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islmvc_mgt.h	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,100 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2003 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef _ISLMVC_MGT_H
+#define _ISLMVC_MGT_H
+
+#include <device_config.h>
+
+/* Begin of DEFINES */
+
+/* 
+ * Uncomment this to enable the code for making a table of joined clients.
+ * If you want to use this, you also need to install handlers that add the client
+ * on an association and remove them on a disassociation.
+ */
+//#define ENABLE_CLIENT_TABLE_CODE
+
+#ifdef ENABLE_CLIENT_TABLE_CODE
+#define MAC_HASH_BITS 8
+#define MAC_HASH_SIZE (1 << MAC_HASH_BITS)
+
+/* Holds information about associated clients */
+struct client_information
+{
+    struct client_information *next_client;
+    struct client_information **pprev_client;
+    char                      mac_addr[ETH_ALEN];
+};
+
+#endif /* ENABLE_CLIENT_TABLE_CODE */
+
+#define MAX_ASSOC_IDS   MAX_ASSOCIATIONS+1 /* Association id can be -1. We add 1, so -1 maps on 0. */ 
+#define MAX_IE_ELEMENTS 20
+
+/* Include this definition if IAPP duplicate frame needs to be generated by the
+   driver in order to update all forwarding tables in the connected layer 2
+   devices */
+#define HANDLE_IAPP_IN_DRIVER
+
+/* Comment this out when an user space application is handling client association and authentication. 
+   This is temporarily used when no user space app is ready to do this for us.
+   FIXME, undef this when authentication application is ready!!!
+ */
+// #define HANDLE_ASSOC_IN_DRIVER
+
+//FIXME, check this for ISL3893.
+#define ETH_LAN     2
+#define ETH_WLAN    1
+#define ETH_WAN     3
+
+#define LED_SET     1
+#define LED_CLEAR   2
+
+/* Structure definitions */
+
+struct information_element
+{
+    struct information_element *next;   /* Pointer to next information element. */
+    unsigned char elem_id;              /* Identifier of the element. */
+    short size;                         /* Size of information element. */
+    char  *data;                        /* Data of information element (including elem_id and size) */
+};
+
+struct frame_attachment
+{
+    struct frame_attachment *next;       /* Pointer to next frame_attachment. */
+    short  frame_type;                   /* Frame type of this attachment. */
+    struct information_element *ie_root; /* Pointer to first information element for this attachment. */
+    char   *all_ie_data;                 /* Pointer to (temporary) buffer holding all information elements. */
+};
+
+
+/* mgmt */
+void islmvc_mgt_init(struct net_device *dev);
+int islmvc_send_mvc_msg(struct net_device *dev, int operation, int oid, long* data, unsigned long data_len);
+
+int mgmt_set_led(struct net_device *dev, int mode);
+
+unsigned char * pda_get_mac_address(void);
+int set_rssi_linear_approximation_db(struct net_device *dev);
+int set_zif_tx_iq_calibr_data(struct net_device *dev);
+int set_hw_interface_variant(struct net_device *dev);
+
+#endif /* _ISLMVC_MGT_H */
diff -urN linux-2.4.29/drivers/net/intersil/islpci.conf linux-2.4.29-uc1/drivers/net/intersil/islpci.conf
--- linux-2.4.29/drivers/net/intersil/islpci.conf	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islpci.conf	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,10 @@
+device "islpci_cb"
+  class "network" module "cb_enabler" module "islpci_cb"
+
+card "Intersil ISL3877 PRISM Indigo Wireless LAN Adapter"
+  pci 0x1260, 0x3877
+  bind "islpci_cb"
+
+card "Intersil ISL3890 PRISM Duette Wireless LAN Adapter"
+  pci 0x1260, 0x3890
+  bind "islpci_cb"
diff -urN linux-2.4.29/drivers/net/intersil/islpci_dev.c linux-2.4.29-uc1/drivers/net/intersil/islpci_dev.c
--- linux-2.4.29/drivers/net/intersil/islpci_dev.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islpci_dev.c	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,905 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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 <linux/version.h>
+#ifdef MODULE
+#ifdef MODVERSIONS
+#include <linux/modversions.h>
+#endif
+#include <linux/module.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/etherdevice.h>
+
+#include <asm/io.h>
+#ifdef CONFIG_ARCH_ISL3893
+#include <asm/arch/pci.h>
+#endif
+#include "isl_gen.h"
+#include "isl_38xx.h"
+
+#ifdef WIRELESS_IOCTLS
+#include "isl_ioctl.h"
+#endif
+
+#include "islpci_dev.h"
+#include "islpci_mgt.h"
+#include "islpci_eth.h"
+#include "islpci_hotplug.h"
+
+#ifdef WDS_LINKS
+#include "isl_mgt.h"
+#include "isl_wds.h"
+#endif
+
+/******************************************************************************
+        Global variable definition section
+******************************************************************************/
+extern int pc_debug;
+extern int init_mode;
+
+struct net_device *root_islpci_device = NULL;
+
+int firmware_uploaded = 0;
+
+
+/******************************************************************************
+    Device Interrupt Handler
+******************************************************************************/
+void islpci_interrupt(int irq, void *config, struct pt_regs *regs)
+{
+    u32 reg;
+    islpci_private *private_config = config;
+    void *device = private_config->device_id;
+    u16 status;
+    
+    // received an interrupt request on a shared IRQ line
+    // first check whether the device is in sleep mode
+    if( reg = readl( device + ISL38XX_CTRL_STAT_REG),
+        reg & ISL38XX_CTRL_STAT_SLEEPMODE )
+        // device is in sleep mode, IRQ was generated by someone else
+        return;
+    
+    // lock the interrupt handler
+    spin_lock( &private_config->slock );
+     
+#ifdef CONFIG_ARCH_ISL3893
+    // check the interrupt source on the host registers
+    reg = (u32) uPCI->ARMIntReg;
+    reg &= (u32) uPCI->ARMIntEnReg;
+    
+//    pci_unmap_single( private_config->pci_device, private_config->control_block, 
+//                    sizeof(struct isl38xx_cb), PCI_DMA_FROMDEVICE );
+    flush_cache_all();
+
+#else
+    // check whether there is any source of interrupt on the device
+    reg = readl(device + ISL38XX_INT_IDENT_REG);
+
+    // also check the contents of the Interrupt Enable Register, because this
+    // will filter out interrupt sources from other devices on the same irq !
+    reg &= readl(device + ISL38XX_INT_EN_REG);
+#endif
+
+    if (reg &= ISL38XX_INT_SOURCES, reg != 0)
+    {
+#ifdef CONFIG_ARCH_ISL3893
+        // write the acknowledge register on the host
+        uPCI->ARMIntAckReg = reg;
+#else
+        // reset the request bits in the Identification register
+        writel(reg, device + ISL38XX_INT_ACK_REG);
+#endif
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+        DEBUG(SHOW_FUNCTION_CALLS,
+	        "IRQ: Identification register value 0x%x \n", reg );
+#endif
+
+        // check for each bit in the register separately
+        if (reg & ISL38XX_INT_IDENT_UPDATE)
+        {
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+            // Queue has been updated
+            DEBUG(SHOW_TRACING, "IRQ: Update flag \n");
+
+            DEBUG(SHOW_QUEUE_INDEXES,
+                "CB drv Qs: [%i][%i][%i][%i][%i][%i]\n",
+                le32_to_cpu(private_config->control_block->driver_curr_frag[0]),
+                le32_to_cpu(private_config->control_block->driver_curr_frag[1]),
+                le32_to_cpu(private_config->control_block->driver_curr_frag[2]),
+                le32_to_cpu(private_config->control_block->driver_curr_frag[3]),
+                le32_to_cpu(private_config->control_block->driver_curr_frag[4]),
+                le32_to_cpu(private_config->control_block->driver_curr_frag[5])
+                );
+
+            DEBUG(SHOW_QUEUE_INDEXES,
+                "CB dev Qs: [%i][%i][%i][%i][%i][%i]\n",
+                le32_to_cpu(private_config->control_block->device_curr_frag[0]),
+                le32_to_cpu(private_config->control_block->device_curr_frag[1]),
+                le32_to_cpu(private_config->control_block->device_curr_frag[2]),
+                le32_to_cpu(private_config->control_block->device_curr_frag[3]),
+                le32_to_cpu(private_config->control_block->device_curr_frag[4]),
+                le32_to_cpu(private_config->control_block->device_curr_frag[5])
+                );
+#endif
+
+            // device is in active state, update the powerstate flag
+            private_config->powerstate = ISL38XX_PSM_ACTIVE_STATE;
+
+            // check all three queues in priority order
+            // call the PIMFOR receive function until the queue is empty
+            while (isl38xx_in_queue(private_config->control_block,
+                ISL38XX_CB_RX_MGMTQ) != 0)
+            {
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+                DEBUG(SHOW_TRACING, "Received frame in Management Queue\n");
+#endif
+                islpci_mgt_receive(private_config);
+
+                // call the pimfor transmit function for processing the next
+                // management frame in the shadow queue
+                islpci_mgt_transmit( private_config );
+            }
+
+            while (isl38xx_in_queue(private_config->control_block,
+                ISL38XX_CB_RX_DATA_LQ) != 0)
+            {
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+                DEBUG(SHOW_TRACING, "Received frame in Data Low Queue \n");
+#endif
+                islpci_eth_receive(private_config);
+            }
+
+		// check whether the data transmit queues were full
+            if (private_config->data_low_tx_full)
+            {
+                // check whether the transmit is not full anymore
+                if( ISL38XX_CB_TX_QSIZE - isl38xx_in_queue( private_config->control_block, 
+		            ISL38XX_CB_TX_DATA_LQ ) >= ISL38XX_MIN_QTHRESHOLD )
+                {
+                    // nope, the driver is ready for more network frames
+                    netif_wake_queue(private_config->my_module);
+
+                    // reset the full flag
+                    private_config->data_low_tx_full = 0;
+                }
+            }
+        }
+
+        if (reg & ISL38XX_INT_IDENT_INIT)
+        {
+            // Device has been initialized
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+            DEBUG(SHOW_TRACING, "IRQ: Init flag, device initialized \n");
+#endif
+
+            // perform card initlialization by sending objects
+            islpci_mgt_initialize( private_config );
+        }
+
+        if (reg & ISL38XX_INT_IDENT_SLEEP)
+        {
+            // Device intends to move to powersave state
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+            DEBUG(SHOW_ANYTHING, "IRQ: Sleep flag \n");
+#endif
+            isl38xx_handle_sleep_request( private_config->control_block,
+                &private_config->powerstate,
+                private_config->remapped_device_base );
+        }
+
+        if (reg & ISL38XX_INT_IDENT_WAKEUP)
+        {
+            // Device has been woken up to active state
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+            DEBUG(SHOW_ANYTHING, "IRQ: Wakeup flag \n");
+#endif
+        
+            isl38xx_handle_wakeup( private_config->control_block,
+                &private_config->powerstate,
+                private_config->remapped_device_base );
+        }
+    }
+
+    // unlock the interrupt handler
+    spin_unlock( &private_config->slock );
+
+    return;
+}
+
+
+/******************************************************************************
+    Network Interface Control & Statistical functions
+******************************************************************************/
+
+int islpci_open(struct net_device *nwdev)
+{
+    islpci_private *private_config = nwdev->priv;
+#ifdef CONFIG_ARCH_ISL3893
+    char cardmode[4] = { 0, 0, 0, 0 };
+#endif
+#ifdef WDS_LINKS
+  struct wds_priv *wdsp = private_config->wdsp;
+#endif
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_open (%p)\n", nwdev );
+#endif
+
+    // lock the driver code
+    //driver_lock( &private_config->slock, &flags );
+    
+#ifdef CONFIG_ARCH_ISL3893
+    /* check whether the firmware has been uploaded in the device */
+    if( !firmware_uploaded )
+    {
+        DEBUG(SHOW_ERROR_MESSAGES, "islpci_open failed: Firmware not uploaded\n" );
+        return -EIO;    
+    }
+
+    // set the mode again for starting the device
+    cardmode[0] = (char) init_mode;
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        OID_INL_MODE, 0, &cardmode[0], 4, 0);
+#endif
+
+    MOD_INC_USE_COUNT;
+
+#ifdef WDS_LINKS
+    open_wds_links(wdsp);
+#endif
+    
+    netif_start_queue(nwdev);
+//      netif_mark_up( nwdev );
+
+    // unlock the driver code
+    //driver_unlock( &private_config->slock, &flags );
+
+    return 0;
+}
+
+int islpci_close(struct net_device *nwdev)
+{
+//    islpci_private *private_config = nwdev->priv;
+//	unsigned long flags;
+        
+#ifdef WDS_LINKS
+  islpci_private *private_config = nwdev->priv;
+  struct wds_priv *wdsp = private_config->wdsp;
+#endif
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_close \n");
+#endif
+
+    // lock the driver code
+    //driver_lock( &private_config->slock, &flags );
+
+#ifdef WDS_LINKS
+    close_wds_links(wdsp);
+#endif
+    netif_stop_queue(nwdev);
+//      netif_mark_down( nwdev );
+
+    MOD_DEC_USE_COUNT;
+
+    // unlock the driver code
+    //driver_unlock( &private_config->slock, &flags );
+
+    return 0;
+}
+
+int islpci_reset(islpci_private * private_config, char *firmware )
+{
+    isl38xx_control_block *control_block = private_config->control_block;
+    queue_entry *entry;
+//	unsigned long flags;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_FUNCTION_CALLS, "isl38xx_reset \n");
+#endif
+
+    // lock the driver code
+    //driver_lock( &private_config->slock, &flags );
+
+    // stop the transmission of network frames to the driver
+    netif_stop_queue(private_config->my_module);
+
+    // disable all device interrupts
+    writel(0, private_config->remapped_device_base + ISL38XX_INT_EN_REG);
+
+    // flush all management queues
+    while( isl38xx_in_queue(control_block, ISL38XX_CB_TX_MGMTQ) != 0 )
+    {
+        islpci_get_queue(private_config->remapped_device_base,
+                &private_config->mgmt_tx_shadowq, &entry);
+        islpci_put_queue(private_config->remapped_device_base,
+                &private_config->mgmt_tx_freeq, entry);
+
+        // decrement the real management index
+        private_config->index_mgmt_tx--;
+    }
+
+//    while( isl38xx_in_queue(control_block, ISL38XX_CB_RX_MGMTQ) != 0 )
+//    {
+//        islpci_get_queue(private_config->remapped_device_base,
+//                &private_config->mgmt_rx_shadowq, &entry);
+//        islpci_put_queue(private_config->remapped_device_base,
+//                &private_config->mgmt_rx_freeq, entry);
+
+        // decrement the real management index
+//        private_config->index_mgmt_rx--;
+//    }
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "Firmware file: %s \n", firmware );
+#endif
+	
+    if (isl38xx_upload_firmware( firmware, private_config->remapped_device_base,
+        private_config->device_host_address ) == -1)
+    {
+        // error uploading the firmware
+        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: could not upload the firmware \n" );
+
+        // unlock the driver code
+        //driver_unlock( &private_config->slock, &flags );
+        return -1;
+    }
+    
+    // unlock the driver code
+    //driver_unlock( &private_config->slock, &flags );
+
+    return 0;
+}
+
+void islpci_set_multicast_list(struct net_device *dev)
+{
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_set_multicast_list \n");
+#endif
+}
+
+struct net_device_stats *islpci_statistics(struct net_device *nwdev)
+{
+    islpci_private *private_config = nwdev->priv;
+    char firmware[64];
+
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_statistics \n");
+
+#ifdef CONFIG_ARCH_ISL3893
+    
+    if ( ! firmware_uploaded ) {
+
+        if( private_config->pci_dev_id == PCIDEVICE_ISL3890 )
+            strcpy( firmware, ISL3890_IMAGE_FILE );
+        else
+            strcpy( firmware, ISL3877_IMAGE_FILE );
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "Upload firmware: %s, %p, %p \n", 
+          firmware, private_config->remapped_device_base, private_config->device_host_address );
+#endif
+
+        if (isl38xx_upload_firmware( firmware, private_config->remapped_device_base,
+            private_config->device_host_address ) == -1)
+        {
+            DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not upload the firmware \n", DRIVER_NAME );
+        }
+        else 
+        {       
+            /* set the firmware uploaded flag for skipping the firmware upload
+               the next time this function is called and for activating the
+               device on the open call */
+            firmware_uploaded = 1;
+        }
+    }
+#endif
+
+    return &private_config->statistics;
+}
+
+
+/******************************************************************************
+    Network device configuration functions
+******************************************************************************/
+int islpci_alloc_memory( islpci_private *private_config, int mode )
+{
+    long offset, counter, pages=0;
+    long allocated, assigned=0;
+    void *queue_base_addr;
+    dma_addr_t queue_bus_addr;
+    queue_entry *pointerq;
+
+    // handle the consistent DMA allocation depending on the memory allocation
+    // definitions made in isl_38xx.h.
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_alloc_memory \n");
+    
+    // First step is to determine the required memory areas for the driver
+    // Area 1: Control Block for the device interface
+    // Area 2: Power Save Mode Buffer for temporary frame storage. Be aware that
+    //         the number of supported stations in the AP determines the minimal
+    //         size of the buffer !
+    // Area 3: Driver Queuing System resources
+    DEBUG(SHOW_TRACING, "Area 1: Control Block fixed size:  %u bytes\n", CONTROL_BLOCK_SIZE );
+    DEBUG(SHOW_TRACING, "Area 2: PSM Buffer total size:     %u bytes\n", PSM_BUFFER_SIZE );
+    DEBUG(SHOW_TRACING, "Area 3: Q Management block size:   %u bytes\n", MGMT_QBLOCK );
+#endif
+
+    // handle the allocation mode
+    if( mode == ALLOC_MODE_PAGED )
+    {
+        // check whether the selected allocation mode fits the memory requirements
+        if( (PSM_BUFFER_SIZE + CONTROL_BLOCK_SIZE) > ALLOC_PAGE1_SIZE )
+        {
+            // required buffer is too large, change the memory requirement settings
+            DEBUG(SHOW_ERROR_MESSAGES, "Error: PSM Buffer & CB exceed page limit\n" );
+            return -1;
+        }
+
+        // set the allocated parameter for first page
+        allocated = ALLOC_PAGE1_SIZE;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+        DEBUG(SHOW_TRACING, "Consistent DMA Paged Allocation Mode\n" );
+#endif
+    }
+    else
+    {
+        // set the allocated parameter for single alloc
+        allocated = HOST_MEM_BLOCK;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+        DEBUG(SHOW_TRACING, "Consistent DMA Single Allocation Mode\n" );
+#endif
+    }
+
+    // perform the first allocation for either first page or single alloc
+    if( private_config->driver_mem_address = pci_alloc_consistent( 
+        private_config->pci_device, allocated, 
+        &private_config->device_host_address ), 
+        private_config->driver_mem_address == NULL)
+    {
+        // error allocating the block of PCI memory
+        DEBUG( SHOW_ERROR_MESSAGES,
+            "ERROR: Could not allocate DMA accessable memory \n" );
+        return -1;
+    }
+    
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "Device memory block at 0x%x \n", 
+        private_config->device_host_address );
+    DEBUG(SHOW_TRACING, "Driver memory block at 0x%p \n", 
+        private_config->driver_mem_address );
+    DEBUG(SHOW_TRACING, "Memory size alloc 0x%lx bytes\n", allocated );
+#endif
+        
+    // assign the Control Block to the first address of the allocated area
+    private_config->control_block = 
+        (isl38xx_control_block *) private_config->driver_mem_address;
+    assigned += CONTROL_BLOCK_SIZE;
+            
+    // set the Power Save Buffer pointer directly behind the CB
+    private_config->device_psm_buffer = 
+        private_config->device_host_address + CONTROL_BLOCK_SIZE;
+    assigned += PSM_BUFFER_SIZE;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "Control Block block at 0x%p sized %u bytes\n", 
+        private_config->control_block, CONTROL_BLOCK_SIZE );
+    DEBUG(SHOW_TRACING, "PSM Buffer at 0x%p sized %u bytes\n", 
+        (void *) private_config->device_psm_buffer, PSM_BUFFER_SIZE );
+#endif
+
+    // set the working pointers in page 1 when there is enough room
+    if( ((mode==ALLOC_MODE_PAGED) && (allocated-assigned>MGMT_FRAME_SIZE)) ||
+        (mode==ALLOC_MODE_SINGLE) )
+    {
+        // set the working pointers in the current page 1
+        queue_base_addr = private_config->driver_mem_address;
+        queue_base_addr += (CONTROL_BLOCK_SIZE + PSM_BUFFER_SIZE);
+        queue_bus_addr = private_config->device_host_address;
+        queue_bus_addr += (CONTROL_BLOCK_SIZE + PSM_BUFFER_SIZE);
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+        DEBUG(SHOW_TRACING, "Queue base addr at 0x%p with %u bytes\n", 
+            (void *) queue_base_addr, allocated-assigned );
+#endif
+    }
+    else
+    {
+        // first step will be to allocate a new page in the for-next
+        queue_base_addr = 0;
+        queue_bus_addr = 0;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+        DEBUG(SHOW_TRACING, "Queue base addr starts in new page\n" );
+#endif
+    }        
+
+    // determine the offset for each queue entry configuration
+    // allign on 16 byte boundary
+    offset = sizeof(queue_entry) / 16;
+    offset *= 16;
+    offset += ((sizeof(queue_entry) % 16) != 0 ? 16 : 0);
+
+    // assign memory for the management frames 
+    for (counter = 0; counter < MGMT_TX_FRAME_COUNT; counter++)
+    {
+        // check whether the frame can be stored in the current page
+        if( allocated - assigned < MGMT_FRAME_SIZE )
+        {
+            // increment and check the page counter 
+            if( pages++, pages == ALLOC_MAX_PAGES )
+            {
+                // too many pages required, increment the page count
+                DEBUG( SHOW_ERROR_MESSAGES,
+                    "ERROR: Too many pages required, increment page count or size\n" );
+                return -1;
+            }
+
+            // allocate a new area to store the new frame
+            if( queue_base_addr = pci_alloc_consistent( private_config->pci_device,
+                ALLOC_PAGEX_SIZE, &queue_bus_addr ), queue_base_addr == NULL)
+            {
+                // error allocating the block of PCI memory
+                DEBUG( SHOW_ERROR_MESSAGES,
+                    "ERROR: Could not allocate DMA accessable memory \n" );
+                return -1;
+            }
+            
+            // store the new base address in the private structure for freeing
+            private_config->q_base_addr[pages-1] = queue_base_addr;            
+            private_config->q_bus_addr[pages-1] = queue_bus_addr;            
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+            DEBUG( SHOW_TRACING, "New page %lu at %p with size %u bytes\n", 
+                pages, queue_base_addr, ALLOC_PAGEX_SIZE );
+#endif
+            
+            // update the working registers
+            allocated = ALLOC_PAGEX_SIZE;
+            assigned = 0;
+        }
+
+        // configure the queue entry at the beginning of the memory block
+        pointerq = (queue_entry *) queue_base_addr;
+        pointerq->host_address = (u32) queue_base_addr + offset;
+        pointerq->dev_address = (u32) queue_bus_addr + offset;
+        pointerq->size = MGMT_FRAME_SIZE - offset;
+        pointerq->fragments = 1;
+
+        // add the configured entry to the management tx root queue
+        islpci_put_queue(private_config->remapped_device_base, 
+            &private_config->mgmt_tx_freeq, pointerq);
+
+        // update the working pointers and registers
+        queue_base_addr += MGMT_FRAME_SIZE;
+        queue_bus_addr += MGMT_FRAME_SIZE;
+        assigned += MGMT_FRAME_SIZE;
+    }
+
+    for (counter = 0; counter < MGMT_RX_FRAME_COUNT; counter++)
+    {
+        // check whether the frame can be stored in the current page
+        if( allocated - assigned < MGMT_FRAME_SIZE )
+        {
+            // increment and check the page counter 
+            if( pages++, pages == ALLOC_MAX_PAGES )
+            {
+                // too many pages required, increment the page count
+                DEBUG( SHOW_ERROR_MESSAGES,
+                    "ERROR: Too many pages required, increment page count or size\n" );
+                return -1;
+            }
+
+            // allocate a new area to store the new frame
+            if( queue_base_addr = pci_alloc_consistent( private_config->pci_device,
+                ALLOC_PAGEX_SIZE, &queue_bus_addr ), queue_base_addr == NULL)
+            {
+                // error allocating the block of PCI memory
+                DEBUG( SHOW_ERROR_MESSAGES,
+                    "ERROR: Could not allocate DMA accessable memory \n" );
+                return -1;
+            }
+            
+            // store the new base address in the private structure for freeing
+            private_config->q_base_addr[pages-1] = queue_base_addr;            
+            private_config->q_bus_addr[pages-1] = queue_bus_addr;            
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+            DEBUG( SHOW_TRACING, "New page %lu at %p with size %u bytes\n", 
+                pages, queue_base_addr, ALLOC_PAGEX_SIZE );
+#endif
+            
+            // update the working registers
+            allocated = ALLOC_PAGEX_SIZE;
+            assigned = 0;
+        }
+
+        // configure the queue entry at the beginning of the memory block
+        pointerq = (queue_entry *) queue_base_addr;
+        pointerq->host_address = (u32) queue_base_addr + offset;
+        pointerq->dev_address = (u32) queue_bus_addr + offset;
+        pointerq->size = MGMT_FRAME_SIZE - offset;
+        pointerq->fragments = 1;
+
+        // add the configured entry to the management rx root queue
+        islpci_put_queue(private_config->remapped_device_base, 
+            &private_config->mgmt_rx_freeq, pointerq);
+
+        // update the working pointers and registers
+        queue_base_addr += MGMT_FRAME_SIZE;
+        queue_bus_addr += MGMT_FRAME_SIZE;
+        assigned += MGMT_FRAME_SIZE;
+    }
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "Queue end addr at 0x%p\n", (void *) queue_base_addr );
+#endif
+
+    return 0;
+}
+
+int islpci_free_memory( islpci_private *private_config, int mode )
+{
+    long counter;
+    
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_free_memory \n");
+#endif
+    // handle the allocation mode
+    if( mode == ALLOC_MODE_PAGED )
+    {
+        // free the separate pages
+        pci_free_consistent( private_config->pci_device, ALLOC_PAGE1_SIZE, 
+            private_config->driver_mem_address, 
+            private_config->device_host_address);
+
+        // check the additional pages to be freed
+        for( counter=0; counter < ALLOC_MAX_PAGES; counter++ )
+        {
+            // free the page is allocated
+            if( private_config->q_base_addr[counter] )
+            {
+                pci_free_consistent( private_config->pci_device, 
+                    ALLOC_PAGEX_SIZE, private_config->q_base_addr[counter],
+                    private_config->q_bus_addr[counter] );
+            }
+        }        
+    }
+    else
+    {
+        // single allocation mode
+        pci_free_consistent( private_config->pci_device, HOST_MEM_BLOCK, 
+            private_config->driver_mem_address, 
+            private_config->device_host_address);
+    }
+
+    return 0;
+}
+
+struct net_device * islpci_probe(struct net_device *nwdev, struct pci_dev *pci_device, long ioaddr, int irq)
+{
+    unsigned char mac_addr[ETH_ALEN];
+    long counter;
+    queue_entry *pointerq;
+    islpci_private *private_config;
+    struct sk_buff *skb;
+    
+    if (nwdev == NULL)
+    {
+    	nwdev = init_etherdev(0,0);
+    	if (nwdev == NULL)
+    	    return NULL;
+    }
+    
+    firmware_uploaded = 0;
+
+    // setup the structure members
+    nwdev->base_addr = ioaddr;
+    nwdev->irq = irq;
+
+    // initialize the function pointers
+    nwdev->open = &islpci_open;
+    nwdev->stop = &islpci_close;
+    nwdev->get_stats = &islpci_statistics;
+#ifdef WIRELESS_IOCTLS
+    nwdev->do_ioctl = &isl_ioctl;
+#endif
+
+    nwdev->hard_start_xmit = &islpci_eth_transmit;
+
+//    nwdev->set_multicast_list = &set_rx_mode;
+
+#ifdef HAVE_TX_TIMEOUT
+    nwdev->watchdog_timeo = ISLPCI_TX_TIMEOUT;
+    nwdev->tx_timeout = &islpci_eth_tx_timeout;
+#endif
+
+    // FIXme
+    mac_addr[0] = 0x01;
+    mac_addr[1] = 0x01;
+    mac_addr[2] = 0x01;
+    mac_addr[3] = 0x01;
+    mac_addr[4] = 0x01;
+    mac_addr[5] = 0x01;
+    mac_addr[6] = 0x01;
+    mac_addr[7] = 0x01;
+    memcpy(nwdev->dev_addr, mac_addr, ETH_ALEN);
+    ether_setup(nwdev);
+    
+    // allocate a private device structure to the network device 
+#ifdef CONFIG_ARCH_ISL3893
+    if ( ( private_config = kmalloc(sizeof(islpci_private), GFP_KERNEL ) ) == NULL )
+#else
+    if ( ( private_config = kmalloc(sizeof(islpci_private), GFP_KERNEL | GFP_DMA ) ) == NULL )
+#endif
+    {
+        // error allocating the DMA accessable memory area
+        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: Could not allocate additional "
+            "memory \n");
+        return NULL;
+    }
+
+    memset(private_config, 0, sizeof(islpci_private));
+    nwdev->priv = private_config;
+    private_config->next_module = root_islpci_device;
+    root_islpci_device = nwdev;
+    private_config->my_module = nwdev;
+    private_config->pci_device = pci_device;
+
+    // remap the PCI device base address to accessable
+    if (private_config->remapped_device_base = ioremap(nwdev->base_addr, 
+        ISL38XX_PCI_MEM_SIZE), private_config->remapped_device_base == NULL)
+    {
+        // error in remapping the PCI device memory address range
+        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: PCI memory remapping failed \n");
+        return NULL;
+    }
+    
+#ifdef CONFIG_ARCH_ISL3893
+    // make sure the device is not running (anymore)
+    writel(ISL38XX_DEV_INT_ABORT, private_config->remapped_device_base 
+        + ISL38XX_DEV_INT_REG);
+#endif
+
+    // save the start and end address of the PCI memory area
+    nwdev->mem_start = (unsigned long) private_config->remapped_device_base;
+    nwdev->mem_end = nwdev->mem_start + ISL38XX_PCI_MEM_SIZE;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "PCI Memory remapped to 0x%p \n", 
+        private_config->remapped_device_base );
+#endif
+
+    // initialize all the queues in the private configuration structure
+    islpci_init_queue(&private_config->mgmt_tx_freeq);
+    islpci_init_queue(&private_config->mgmt_rx_freeq);
+    islpci_init_queue(&private_config->mgmt_tx_shadowq);
+    islpci_init_queue(&private_config->mgmt_rx_shadowq);
+    islpci_init_queue(&private_config->ioctl_rx_queue);
+    islpci_init_queue(&private_config->trap_rx_queue);
+    islpci_init_queue(&private_config->pimfor_rx_queue);
+    
+#ifdef WDS_LINKS
+    private_config->wdsp = kmalloc(sizeof(struct wds_priv), GFP_KERNEL );
+    memset(private_config->wdsp, 0, sizeof(struct wds_priv));
+#endif    
+    
+    // allocate the consistent DMA memory depending on the mode    
+    if( islpci_alloc_memory( private_config, ALLOC_MEMORY_MODE ))
+        return NULL;
+ 
+    // clear the indexes in the frame pointer
+    for (counter = 0; counter < ISL38XX_CB_QCOUNT; counter++)
+    {
+        private_config->control_block->driver_curr_frag[counter] = cpu_to_le32(0);
+        private_config->control_block->device_curr_frag[counter] = cpu_to_le32(0);
+    }
+
+    // Joho, ready setting up the queueing stuff, now fill the shadow rx queues
+    // of both the management and data queues
+    for (counter = 0; counter < ISL38XX_CB_MGMT_QSIZE; counter++)
+    {
+        // get an entry from the freeq and put it in the shadow queue
+        if (islpci_get_queue(private_config->remapped_device_base, 
+            &private_config->mgmt_rx_freeq, &pointerq))
+        {
+            // Oops, no more entries in the freeq ?
+            DEBUG(SHOW_ERROR_MESSAGES, "Error: No more entries in freeq\n");
+            return NULL;
+        }
+        else
+        {
+            // use the entry for the device interface management rx queue
+            // these should always be inline !
+            private_config->control_block->rx_data_mgmt[counter].address =
+                cpu_to_le32(pointerq->dev_address);
+
+            // put the entry got from the freeq in the shadow queue
+            islpci_put_queue(private_config->remapped_device_base, 
+                &private_config->mgmt_rx_shadowq, pointerq);
+        }
+    }
+
+    for (counter = 0; counter < ISL38XX_CB_RX_QSIZE; counter++)
+    {
+        // allocate an sk_buff for received data frames storage
+		// each frame on receive size consists of 1 fragment
+	    // include any required allignment operations
+        if (skb = dev_alloc_skb(MAX_FRAGMENT_SIZE+2), skb == NULL)
+        {
+            // error allocating an sk_buff structure elements
+            DEBUG(SHOW_ERROR_MESSAGES, "Error allocating skb \n");
+            return NULL;
+        }
+
+		// add the new allocated sk_buff to the buffer array
+		private_config->data_low_rx[counter] = skb;
+
+		// map the allocated skb data area to pci
+        private_config->pci_map_rx_address[counter] = pci_map_single(
+        	private_config->pci_device, (void *) skb->data, MAX_FRAGMENT_SIZE+2,
+            PCI_DMA_FROMDEVICE );
+        if( private_config->pci_map_rx_address[counter] == (dma_addr_t) NULL )
+        {
+            // error mapping the buffer to device accessable memory address
+            DEBUG(SHOW_ERROR_MESSAGES, "Error mapping DMA address\n");
+            return NULL;
+        }
+
+		// update the fragment address values in the contro block rx queue
+        private_config->control_block->rx_data_low[counter].address = cpu_to_le32( (u32) 
+		 	private_config->pci_map_rx_address[counter] );
+    }
+
+    // since the receive queues are filled with empty fragments, now we can
+    // set the corresponding indexes in the Control Block
+    private_config->control_block->driver_curr_frag[ISL38XX_CB_RX_DATA_LQ] =
+        cpu_to_le32(ISL38XX_CB_RX_QSIZE);
+    private_config->control_block->driver_curr_frag[ISL38XX_CB_RX_MGMTQ] =
+        cpu_to_le32(ISL38XX_CB_MGMT_QSIZE);
+
+    // reset the real index registers and full flags
+    private_config->index_mgmt_rx = 0;
+	private_config->index_mgmt_tx = 0;
+    private_config->free_data_rx = 0;
+    private_config->free_data_tx = 0;
+    private_config->data_low_tx_full = 0;
+
+    // reset the queue read locks, process wait counter
+    private_config->ioctl_queue_lock = 0;
+    private_config->processes_in_wait = 0;
+
+    // set the power save state
+    private_config->powerstate = ISL38XX_PSM_ACTIVE_STATE;
+    private_config->resetdevice = 0;
+
+    return nwdev;
+}
+
+
diff -urN linux-2.4.29/drivers/net/intersil/islpci_dev.h linux-2.4.29-uc1/drivers/net/intersil/islpci_dev.h
--- linux-2.4.29/drivers/net/intersil/islpci_dev.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islpci_dev.h	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,125 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef _ISLPCI_DEV_H
+#define _ISLPCI_DEV_H
+
+
+#include <linux/netdevice.h>
+
+#ifdef CONFIG_ARCH_ISL3893
+#define INTERSIL_EVENTS 
+#define WDS_LINKS
+#endif
+
+#include "isl_38xx.h"
+#ifdef WDS_LINKS
+#include "isl_wds.h"
+#endif
+
+typedef struct
+{
+    u32 host_address;                   // mem address for the host
+    u32 dev_address;                    // mem address for the device
+    u16 size;                           // size of memory block or queue
+    u16 fragments;                      // nr of fragments in data part
+    void *next;                         // entry pointer to next in list
+    void *last;                         // for quick queue handling
+} queue_entry, queue_root;
+
+struct net_local
+{
+    // PCI bus allocation & configuration members
+    u8 pci_bus;                         // PCI bus id location
+    u8 pci_dev_fn;                      // PCI bus func location
+    u8 pci_irq;                         // PCI irq line
+    u16 pci_dev_id;	    	    	    // PCI device id
+
+    struct pci_dev *pci_device;         // PCI structure information
+    void *remapped_device_base;         // remapped device base address
+    dma_addr_t device_host_address;     // host memory address for dev
+    dma_addr_t device_psm_buffer;   	// host memory for PSM buffering
+    void *driver_mem_address;           // memory address for the driver
+    void *q_base_addr[ALLOC_MAX_PAGES]; // base addresses of page allocs
+    dma_addr_t q_bus_addr[ALLOC_MAX_PAGES]; // bus addresses of page allocs
+    void *device_id;                    // unique ID for shared IRQ
+
+    // kernel configuration members
+    struct net_device *next_module;
+    struct net_device *my_module;       // makes life earier....
+
+    // device queue interface members
+    struct isl38xx_cb *control_block;   // device control block
+    u32 index_mgmt_rx;                  // real index mgmt rx queue
+    u32 index_mgmt_tx;              	// read index mgmt tx queue
+    u32 free_data_rx;                 	// free pointer data rx queue
+    u32 free_data_tx;                	// free pointer data tx queue
+    u32 data_low_tx_full;               // full detected flag
+
+    // root free queue definitions
+    queue_root mgmt_tx_freeq;           // queue entry container mgmt tx
+    queue_root mgmt_rx_freeq;           // queue entry container mgmt rx
+
+    // driver queue definitions
+    queue_root mgmt_tx_shadowq;         // shadow queue mgmt tx
+    queue_root mgmt_rx_shadowq;         // shadow queue mgmt rx
+    queue_root ioctl_rx_queue;          // ioctl rx queue
+    queue_root trap_rx_queue;           // TRAP pimfor rx queue
+    queue_root pimfor_rx_queue;         // PIMFOR generated rx queue
+	struct sk_buff *data_low_tx[ISL38XX_CB_TX_QSIZE];
+	struct sk_buff *data_low_rx[ISL38XX_CB_RX_QSIZE];
+	dma_addr_t pci_map_tx_address[ISL38XX_CB_TX_QSIZE];
+	dma_addr_t pci_map_rx_address[ISL38XX_CB_RX_QSIZE];
+	
+    // driver network interface members
+    struct net_device_stats statistics;
+
+    // driver operational members
+    int mode;                           // device operation mode
+    int powerstate;                     // device power save state
+    int linkstate;                      // device link state
+    int ioctl_queue_lock;               // flag for locking queue read
+    int processes_in_wait;              // process wait counter
+    int wds_link_count;             	// number of wds link entries in table
+    int resetdevice;                    // reset the device flag
+	spinlock_t slock;		            // spinlock
+
+#ifdef WDS_LINKS
+    struct wds_priv *wdsp;
+#endif
+//    address_entry wds_link_table[ISL38XX_MAX_WDS_LINKS]; // WDS Link table
+};
+
+typedef struct net_local    islpci_private;
+
+#define ISLPCI_TX_TIMEOUT               (2*HZ)
+
+void islpci_interrupt(int, void *, struct pt_regs * );
+
+int islpci_open( struct net_device * );
+int islpci_close( struct net_device * );
+int islpci_reset( islpci_private *, char * );
+void islpci_set_multicast_list( struct net_device * );
+struct net_device_stats *islpci_statistics( struct net_device * );
+
+int islpci_alloc_memory( islpci_private *, int );
+int islpci_free_memory( islpci_private *, int );
+struct net_device * islpci_probe(struct net_device *nwdev, struct pci_dev *pci_device, long ioaddr, int irq);
+
+#endif  // _ISLPCI_DEV_H
diff -urN linux-2.4.29/drivers/net/intersil/islpci_eth.c linux-2.4.29-uc1/drivers/net/intersil/islpci_eth.c
--- linux-2.4.29/drivers/net/intersil/islpci_eth.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islpci_eth.c	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,528 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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 <linux/version.h>
+#ifdef MODULE
+#ifdef MODVERSIONS
+#include <linux/modversions.h>
+#endif
+#include <linux/module.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+
+#include "isl_gen.h"
+#include "isl_38xx.h"
+#include "islpci_eth.h"
+
+#ifdef WDS_LINKS
+#include "isl_mgt.h"
+#include "isl_wds.h"
+#endif
+
+/******************************************************************************
+        Global variable definition section
+******************************************************************************/
+extern int pc_debug;
+extern int init_wds;
+
+/******************************************************************************
+    Network Interface functions
+******************************************************************************/
+void islpci_eth_cleanup_transmit( islpci_private *private_config,
+    isl38xx_control_block *control_block )
+{
+	struct sk_buff *skb;
+	u32 index;
+	
+	// compare the control block read pointer with the free pointer
+	while( private_config->free_data_tx !=
+		le32_to_cpu( control_block->device_curr_frag[ISL38XX_CB_TX_DATA_LQ]) )
+	{
+		// read the index of the first fragment to be freed
+		index = private_config->free_data_tx % ISL38XX_CB_TX_QSIZE;
+
+		// check for holes in the arrays caused by multi fragment frames 
+		// searching for the last fragment of a frame
+    	if( private_config->pci_map_tx_address[index] != (dma_addr_t) NULL )
+		{
+			// entry is the last fragment of a frame
+			// free the skb structure and unmap pci memory
+			skb = private_config->data_low_tx[index];
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+            DEBUG( SHOW_TRACING, "cleanup skb %p skb->data %p skb->len %u truesize %u\n ", 
+                skb, skb->data, skb->len, skb->truesize );
+#endif
+
+			pci_unmap_single( private_config->pci_device, 
+                private_config->pci_map_tx_address[index], 
+				skb->len, PCI_DMA_TODEVICE );
+       		dev_kfree_skb( skb );
+		}
+		
+		// increment the free data low queue pointer
+		private_config->free_data_tx++;
+	}		
+}
+
+int islpci_eth_transmit(struct sk_buff *skb, struct net_device *nwdev)
+{
+    islpci_private *private_config = nwdev->priv;
+    isl38xx_control_block *control_block = private_config->control_block;
+    isl38xx_fragment *fragment;
+    u32 index, counter, pci_map_address;
+    int fragments;
+    int frame_size;
+    int offset;
+    struct sk_buff *newskb;
+    int newskb_offset;
+	unsigned long flags;
+	unsigned char wds_mac[6];
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_transmit \n");
+#endif
+
+    // lock the driver code
+    driver_lock( &private_config->slock, &flags );
+
+    // check whether the deviec is running
+//      if( !netif_running( nwdev ) )
+//      {
+//              DEBUG( SHOW_ERROR_MESSAGES, "%s: Tx on stopped device!\n",
+//                     nwdev->name);
+//              return 1;
+//      }
+
+//      tx_timeout_check( nwdev, islpci_eth_tx_timeout );
+//      skb_tx_check( nwdev, skb );
+
+    // determine the amount of fragments needed to store the frame
+    memset (wds_mac, 0, 6);
+#ifdef WDS_LINKS
+    check_skb_for_wds(skb, wds_mac);
+#ifdef ISLPCI_ETH_DEBUG
+    if ( wds_mac[0] || wds_mac[1] || wds_mac[2] || wds_mac[3] || wds_mac[4] || wds_mac[5] ) {
+        printk("islpci_eth_transmit:check_skb_for_wds ! %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 
+               wds_mac[0], wds_mac[1], wds_mac[2], wds_mac[3], wds_mac[4], wds_mac[5] );
+    } else {
+        printk("islpci_eth_transmit:check_skb_for_wds %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 
+               wds_mac[0], wds_mac[1], wds_mac[2], wds_mac[3], wds_mac[4], wds_mac[5] );
+    }
+#endif
+#endif
+    
+    frame_size = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+    if( init_wds ) frame_size += 6;
+    fragments = frame_size / MAX_FRAGMENT_SIZE;
+    fragments += frame_size % MAX_FRAGMENT_SIZE == 0 ? 0 : 1;
+
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "Fragments needed for frame %i\n", fragments);
+#endif
+
+    // check whether the destination queue has enough fragments for the frame
+    if (ISL38XX_CB_TX_QSIZE - isl38xx_in_queue( control_block, 
+		ISL38XX_CB_TX_DATA_LQ ) < fragments )
+    {
+        // Error, cannot add the frame because the queue is full
+        DEBUG(SHOW_ERROR_MESSAGES, "Error: Queue [%i] not enough room\n",
+	        ISL38XX_CB_TX_DATA_LQ);
+
+        // trigger the device by setting the Update bit in the Device Int reg
+        writel(ISL38XX_DEV_INT_UPDATE, private_config->remapped_device_base + 
+            ISL38XX_DEV_INT_REG);
+        udelay(ISL38XX_WRITEIO_DELAY);
+
+        // unlock the driver code
+        driver_unlock( &private_config->slock, &flags );
+        return -EBUSY;
+    }
+
+    // Check alignment and WDS frame formatting. The start of the packet should
+    // be aligned on a 4-byte boundary. If WDS is enabled add another 6 bytes
+    // and add WDS address information
+    if( ((int) skb->data & 0x03) | init_wds )
+    {
+        // get the number of bytes to add and re-allign
+        offset = (int) skb->data & 0x03;
+		offset += init_wds ? 6 : 0;		
+
+		// check whether the current skb can be used 
+        if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset))
+        {
+            unsigned char *src = skb->data;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+	        DEBUG(SHOW_TRACING, "skb offset %i wds %i\n", offset, init_wds );
+#endif
+
+			// allign the buffer on 4-byte boundary
+            skb_reserve(skb, (int) skb->data & 0x03 );
+            if( init_wds )
+            {
+            	// wds requires an additional address field of 6 bytes
+				skb_put( skb, 6 ); 
+#ifdef ISLPCI_ETH_DEBUG
+                printk("islpci_eth_transmit:wds_mac\n" );
+#endif			    
+                memmove( skb->data+6, src, skb->len );
+                memcpy( skb->data, wds_mac, 6 );
+            }
+            else
+			{
+                memmove( skb->data, src, skb->len );
+			}
+			
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+            DEBUG(SHOW_TRACING, "memmove %p %p %i \n", skb->data, src,
+                skb->len );
+#endif
+        }
+        else
+        {
+            newskb = dev_alloc_skb( init_wds ? skb->len+6 : skb->len );
+            newskb_offset = (int) newskb->data & 0x03;
+
+            // Check if newskb->data is aligned
+            if( newskb_offset )
+                skb_reserve(newskb, newskb_offset);
+
+            skb_put(newskb, init_wds ? skb->len+6 : skb->len );
+            if( init_wds )
+            {
+                memcpy( newskb->data+6, skb->data, skb->len );
+                memcpy( newskb->data, wds_mac, 6 );
+#ifdef ISLPCI_ETH_DEBUG
+                printk("islpci_eth_transmit:wds_mac\n" );
+#endif
+            }
+            else
+                memcpy( newskb->data, skb->data, skb->len );
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+            DEBUG(SHOW_TRACING, "memcpy %p %p %i wds %i\n", newskb->data,
+                skb->data, skb->len, init_wds );
+#endif
+
+            newskb->dev = skb->dev;
+            dev_kfree_skb(skb);
+            skb = newskb;
+        }
+    }
+
+    // display the buffer contents for debugging
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG( SHOW_BUFFER_CONTENTS, "\ntx %p ", skb->data );
+    display_buffer((char *) skb->data, skb->len );
+#endif
+
+	// map the skb buffer to pci memory for DMA operation
+	pci_map_address = pci_map_single( private_config->pci_device, 
+		(void *) skb->data, skb->len, PCI_DMA_TODEVICE );
+    if( pci_map_address == (dma_addr_t) NULL )
+	{
+    	// error mapping the buffer to device accessable memory address
+	    DEBUG(SHOW_ERROR_MESSAGES, "Error map DMA addr, data lost\n" );
+
+	    // free the skbuf structure before aborting
+    	dev_kfree_skb(skb);
+
+        // unlock the driver code
+        driver_unlock( &private_config->slock, &flags );
+	    return -EIO;
+    }
+
+	// place each fragment in the control block structure and store in the last
+	// needed fragment entry of the pci_map_tx_address and data_low_tx arrays 
+	// the skb frame information
+    for (counter = 0; counter < fragments; counter++ )
+	{
+		// get a pointer to the target control block fragment
+	    index = (counter + le32_to_cpu(
+	        control_block->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ])) %
+    	    ISL38XX_CB_TX_QSIZE;			
+	    fragment = &control_block->tx_data_low[index];
+	
+		// check whether this frame fragment is the last one
+		if( counter == fragments-1 )
+		{
+			// the fragment is the last one, add the streaming DMA mapping for 
+			// proper PCI bus operation
+    		private_config->pci_map_tx_address[index] = 
+                (dma_addr_t) pci_map_address;
+			
+			// store the skb address for future freeing 
+			private_config->data_low_tx[index] = skb;
+		}
+		else
+		{
+			// the fragment will be followed by more fragments
+			// clear the pci_map_tx_address and data_low_tx entries
+		    private_config->pci_map_tx_address[index] = (dma_addr_t) NULL;
+			private_config->data_low_tx[index] = NULL;
+		}
+			
+		// set the proper fragment start address and size information
+        fragment->address = cpu_to_le32( pci_map_address + 
+			counter*MAX_FRAGMENT_SIZE );
+        fragment->size = cpu_to_le16( frame_size > MAX_FRAGMENT_SIZE ?
+            MAX_FRAGMENT_SIZE : frame_size );
+        fragment->flags = cpu_to_le16( frame_size > MAX_FRAGMENT_SIZE ? 1 : 0 );
+        frame_size -= MAX_FRAGMENT_SIZE;
+	}
+
+	// ready loading all fragements to the control block and setup pci mapping
+	// update the control block interface information
+    add_le32p(&control_block->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ],
+        fragments);
+
+    // check whether the data tx queue is full now
+    if( ISL38XX_CB_TX_QSIZE - isl38xx_in_queue( control_block, 
+		ISL38XX_CB_TX_DATA_LQ ) < ISL38XX_MIN_QTHRESHOLD )
+    {
+        // stop the transmission of network frames to the driver
+        netif_stop_queue(nwdev);
+
+        // set the full flag for the data low transmission queue
+        private_config->data_low_tx_full = 1;
+    }
+
+    // trigger the device
+    isl38xx_trigger_device( &private_config->powerstate,
+        private_config->remapped_device_base );
+
+    // set the transmission time
+    nwdev->trans_start = jiffies;
+    private_config->statistics.tx_packets++;
+    private_config->statistics.tx_bytes += skb->len;
+
+    // cleanup the data low transmit queue
+    islpci_eth_cleanup_transmit( private_config, private_config->control_block );
+
+    // unlock the driver code
+    driver_unlock( &private_config->slock, &flags );
+    return 0;
+}
+
+int islpci_eth_receive(islpci_private * private_config)
+{
+    struct net_device *nw_device = private_config->my_module;
+    struct net_device *wds_dev = NULL;
+    struct wds_net_local *wds_lp;
+    isl38xx_control_block *control_block = private_config->control_block;
+#ifdef WDS_LINKS
+    struct wds_priv *wdsp = private_config->wdsp;
+#endif    
+    struct sk_buff *skb;
+    u16 size;
+    u32 index, offset;
+    unsigned char *src;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_receive \n");
+#endif
+
+    // the device has written an Ethernet frame in the data area
+    // of the sk_buff without updating the structure, do it now
+	index = private_config->free_data_rx % ISL38XX_CB_RX_QSIZE;
+    size = le16_to_cpu(control_block->rx_data_low[index].size);
+	skb = private_config->data_low_rx[index];
+    offset = ((u32) le32_to_cpu(control_block->rx_data_low[index].address) - 
+        (u32) skb->data ) & 3;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG( SHOW_TRACING, "frq->addr %x skb->data %p skb->len %u offset %u truesize %u\n ", 
+        control_block->rx_data_low[private_config->free_data_rx].address,
+		skb->data, skb->len, offset, skb->truesize );
+#endif
+
+    // delete the streaming DMA mapping before processing the skb
+    pci_unmap_single( private_config->pci_device, 
+        private_config->pci_map_rx_address[index],
+        MAX_FRAGMENT_SIZE+2, PCI_DMA_FROMDEVICE );
+
+	// update the skb structure and allign the buffer
+    skb_put( skb, size );
+    if( offset )
+    {
+		// shift the buffer allocation offset bytes to get the right frame
+        skb_pull( skb, 2 );
+		skb_put( skb, 2 );
+    }
+    
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    // display the buffer contents for debugging
+    DEBUG( SHOW_BUFFER_CONTENTS, "\nrx %p ", skb->data );
+    display_buffer((char *) skb->data, skb->len );
+#endif
+
+    // check whether WDS is enabled and whether the data frame is a WDS frame
+
+    if( init_wds )
+    {
+        // WDS enabled, check for the wds address on the first 6 bytes of the buffer
+#ifdef WDS_LINKS
+        wds_dev = wds_find_device( skb->data, wdsp ); 
+#ifdef ISLPCI_ETH_DEBUG
+        if ( wds_dev ) {
+            printk("islpci_eth_receive:wds_find_device ! %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 
+                   skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4], skb->data[5] );
+        } else {
+            printk("islpci_eth_receive:wds_find_device %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 
+                   skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4], skb->data[5] );
+        }
+#endif
+#endif
+        src = skb->data+6;
+        memmove( skb->data, src, skb->len-6 );
+        skb_trim( skb, skb->len-6 );
+    }
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "Fragment size %i in skb at %p\n", size, skb);
+    DEBUG(SHOW_TRACING, "Skb data at %p, length %i\n", skb->data, skb->len);
+
+    // display the buffer contents for debugging
+    DEBUG( SHOW_BUFFER_CONTENTS, "\nrx %p ", skb->data );
+    display_buffer((char *) skb->data, skb->len );
+#endif
+
+    // do some additional sk_buff and network layer parameters
+    skb->dev = nw_device;
+    skb->protocol = eth_type_trans(skb, nw_device);
+    skb->ip_summed = CHECKSUM_NONE;
+    private_config->statistics.rx_packets++;
+    private_config->statistics.rx_bytes += size;
+
+#ifdef WDS_LINKS
+        if ( wds_dev != NULL )
+        {
+            wds_lp = (struct wds_net_local *) wds_dev->priv;
+            wds_lp->stats.rx_packets++;
+            wds_lp->stats.rx_bytes += skb->len;            
+            skb->dev = wds_dev;
+        }
+#endif
+    // deliver the skb to the network layer
+#ifdef ISLPCI_ETH_DEBUG
+    printk("islpci_eth_receive:netif_rx %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 
+           skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4], skb->data[5] );
+#endif
+    netif_rx(skb);
+
+    // increment the read index for the rx data low queue
+    private_config->free_data_rx++;
+
+    // add one or more sk_buff structures
+    while( index = le32_to_cpu( 
+		control_block->driver_curr_frag[ISL38XX_CB_RX_DATA_LQ] ), 
+		index - private_config->free_data_rx < ISL38XX_CB_RX_QSIZE )
+    {
+        // allocate an sk_buff for received data frames storage
+	    // include any required allignment operations
+        if (skb = dev_alloc_skb(MAX_FRAGMENT_SIZE+2), skb == NULL)
+        {
+            // error allocating an sk_buff structure elements
+            DEBUG(SHOW_ERROR_MESSAGES, "Error allocating skb \n");
+            break;
+        }
+
+		// store the new skb structure pointer
+		index = index % ISL38XX_CB_RX_QSIZE;
+		private_config->data_low_rx[index] = skb;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+        DEBUG( SHOW_TRACING, "new alloc skb %p skb->data %p skb->len %u index %u truesize %u\n ", 
+            skb, skb->data, skb->len, index, skb->truesize );
+#endif
+
+        // set the streaming DMA mapping for proper PCI bus operation
+		private_config->pci_map_rx_address[index] = pci_map_single(
+			private_config->pci_device, (void *) skb->data, MAX_FRAGMENT_SIZE+2, 
+			PCI_DMA_FROMDEVICE );
+        if( private_config->pci_map_rx_address[index] == (dma_addr_t) NULL )
+        {
+            // error mapping the buffer to device accessable memory address
+            DEBUG(SHOW_ERROR_MESSAGES, "Error mapping DMA address\n");
+
+            // free the skbuf structure before aborting
+            dev_kfree_skb((struct sk_buff *) skb );
+            break;
+        }
+
+        // update the fragment address
+        control_block->rx_data_low[index].address = cpu_to_le32( (u32)
+		 	private_config->pci_map_rx_address[index] );
+
+        // increment the driver read pointer
+        add_le32p(&control_block->driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1 );
+    }
+
+    // trigger the device
+    isl38xx_trigger_device( &private_config->powerstate,
+        private_config->remapped_device_base );
+
+    return 0;
+}
+
+void islpci_eth_tx_timeout(struct net_device *nwdev)
+{
+    islpci_private *private_config = nwdev->priv;
+    struct net_device_stats *statistics = &private_config->statistics;
+//    unsigned long flags;
+//    int error = 0;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_tx_timeout \n");
+#endif
+
+    // lock the driver code
+    //driver_lock( &private_config->slock, &flags );
+
+    // increment the transmit error counter
+    statistics->tx_errors++;
+
+/*
+    // reset the device and restore its configuration
+    if (error = isl38xx_reset(private_config), error != 0)
+    {
+        DEBUG(SHOW_ERROR_MESSAGES, "Error %d on TX timeout card reset!\n",
+            error);
+    }
+    else
+    {
+        DEBUG(SHOW_ERROR_MESSAGES, "Driver stopped TX/RX ......\n");
+
+//        nwdev->trans_start = jiffies;
+//        netif_wake_queue( nwdev );
+    }
+*/
+
+    // unlock the driver code
+    //driver_unlock( &private_config->slock, &flags );
+    return;
+}
diff -urN linux-2.4.29/drivers/net/intersil/islpci_eth.h linux-2.4.29-uc1/drivers/net/intersil/islpci_eth.h
--- linux-2.4.29/drivers/net/intersil/islpci_eth.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islpci_eth.h	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,34 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef _ISLPCI_ETH_H
+#define _ISLPCI_ETH_H
+
+#include "isl_38xx.h"
+#include "islpci_dev.h"
+
+
+
+void islpci_eth_cleanup_transmit( islpci_private *, isl38xx_control_block * );
+int islpci_eth_transmit( struct sk_buff *, struct net_device * );
+int islpci_eth_receive( islpci_private * );
+void islpci_eth_tx_timeout( struct net_device * );
+
+
+#endif	// _ISL_GEN_H
diff -urN linux-2.4.29/drivers/net/intersil/islpci_hotplug.c linux-2.4.29-uc1/drivers/net/intersil/islpci_hotplug.c
--- linux-2.4.29/drivers/net/intersil/islpci_hotplug.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islpci_hotplug.c	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,377 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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 <linux/version.h>
+#ifdef MODULE
+#ifdef MODVERSIONS
+#include <linux/modversions.h>
+#endif
+#include <linux/module.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
+#include <linux/pci.h>
+#ifdef CONFIG_ARCH_ISL3893
+#include <asm/arch/pci.h>
+#endif
+#include "version_info.h"
+#include "isl_gen.h"
+#include "isl_38xx.h"
+#include "islpci_hotplug.h"
+#include "islpci_dev.h"
+
+#ifdef INTERSIL_EVENTS
+#include <bloboid.h>
+#include "isl_mgt.h"
+#include "islpci_mgt.h"
+#endif
+
+/******************************************************************************
+        Global variable definition section
+******************************************************************************/
+#ifdef MODULE
+MODULE_AUTHOR("W.Termorshuizen, R.Bastings");
+MODULE_DESCRIPTION("Intersil 802.11 Wireless LAN adapter");
+MODULE_LICENSE("GPL");
+#endif
+
+
+extern struct net_device *root_islpci_device;
+extern int pc_debug;
+
+struct pci_device_id pci_id_table[] =
+{
+    {
+        PCIVENDOR_INTERSIL, PCIDEVICE_ISL3877,
+        PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+        // Driver data, we just put the name here
+        (unsigned long) "Intersil PRISM Indigo Wireless LAN adapter"
+    },
+    {
+        PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
+        PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+        // Driver data, we just put the name here
+        (unsigned long) "Intersil PRISM Duette Wireless LAN adapter"
+    },
+    {
+        0, 0, 0, 0, 0, 0, 0
+    }
+};
+
+// register the device with the Hotplug facilities of the kernel
+#ifdef MODULE
+MODULE_DEVICE_TABLE( pci, pci_id_table );
+#endif
+
+struct pci_driver islpci_pci_drv_id =
+{
+    {},
+    DRIVER_NAME,                // Driver name
+    pci_id_table,               // id table
+    islpci_probe_pci,           // probe function
+    islpci_remove_pci,          // remove function
+    NULL,                       // save_state function
+    NULL,                       // suspend function
+    NULL,                       // resume function
+    NULL,                       // enable_wake function
+};
+
+/******************************************************************************
+    Module initialization functions
+******************************************************************************/
+
+#ifdef CONFIG_ARCH_ISL3893
+
+int prism_uap_probe(struct net_device *ndev)
+{
+    struct pci_dev *pdev = NULL;
+    int error;
+        
+    if ( ndev->base_addr != 4 )      
+        return -ENODEV;
+    
+    printk("prism_uap_probe(%s)\n", ndev->name );
+    
+    if ( pdev = pci_find_device( PCI_VENDOR_ID_INTERSIL, 0x3877, NULL ) ) 
+    {
+        printk("pci: Intersil 3877 found\n" );
+        
+        if ( error = islpci_probe_pci( ndev, pdev, &(pci_id_table[0])), error < 0 )
+        {
+            printk("islpci_probe_pci failed!\n" );
+            return error;
+        }
+
+        return 0;
+    }
+
+    if ( pdev = pci_find_device( PCI_VENDOR_ID_INTERSIL, 0x3890, NULL ) ) 
+    {
+        printk("pci: Intersil 3890 found\n" );
+        
+        if ( error = islpci_probe_pci( ndev, pdev, &(pci_id_table[1])), error < 0 )
+        {
+            printk("islpci_probe_pci failed!\n" );
+            return error;
+        }
+        
+        return 0;
+    }
+
+    // no device found
+    return -ENODEV;
+}
+
+int islpci_probe_pci(struct net_device *nw_device, struct pci_dev *pci_device,
+                     const struct pci_device_id *id)
+{
+#else
+int  islpci_probe_pci(struct pci_dev *pci_device, const struct pci_device_id *id)
+{
+    struct net_device *nw_device=NULL;
+#endif
+    void *phymem;
+    u16 irq;
+    u8 bus, devfn, latency_tmr;
+    islpci_private *private_config;
+    int rvalue, dev_id;
+    int dma_mask = 0xffffffff;
+    char firmware[256];
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_probe_pci\n");
+#endif
+
+    // Enable the pci device
+    if (pci_enable_device(pci_device))
+    {
+        DEBUG(SHOW_ERROR_MESSAGES, "%s: pci_enable_device() failed.\n",
+            DRIVER_NAME );
+        return -EIO;
+    }
+    // Figure out our resources
+    irq = pci_device->irq;
+    bus = pci_device->bus->number;
+    devfn = pci_device->devfn;
+    dev_id = pci_device->device;
+
+	// check whether the latency timer is set correctly
+#ifdef CONFIG_ARCH_ISL3893
+    pcibios_write_config_byte(bus, devfn, PCI_TRDY_TIMEOUT_VALUE, 0 );
+    pcibios_write_config_byte(bus, devfn, PCI_RETRY_TIMEOUT_VALUE, 0 );
+#else
+    pcibios_read_config_byte(bus, devfn, PCI_LATENCY_TIMER, &latency_tmr);
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+	DEBUG( SHOW_TRACING, "latency timer: %x\n", latency_tmr );
+#endif
+	if( latency_tmr < PCIDEVICE_LATENCY_TIMER_MIN )
+	{
+		// set the latency timer
+		pcibios_write_config_byte(bus, devfn, PCI_LATENCY_TIMER, 
+			PCIDEVICE_LATENCY_TIMER_VAL );
+	}
+#endif
+
+    // determine what the supported DMA memory region is
+    while( pci_set_dma_mask( pci_device, dma_mask ) != 0 )
+    {
+        // range not supported, shift the mask and check again
+        if( dma_mask >>=  1, dma_mask == 0 )
+        {
+            // mask is zero, DMA memory not supported by PCI
+            DEBUG(SHOW_ERROR_MESSAGES, "DMA Memory not supported\n" );
+            return -EIO;
+        }
+    }
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "DMA Memory support mask is 0x%x \n", dma_mask );
+#endif
+
+    // call for the physical address to address the PCI device
+    phymem = (void *) pci_resource_start(pci_device, 0);
+#ifdef CONFIG_ARCH_ISL3893
+    // FIXme
+    printk("!!pci_resource_start = %p, shound be 0x10000000\n", phymem );
+    phymem = 0x10000000;
+#endif
+    // request the pci device for regions ???
+    
+    if (rvalue = pci_request_regions(pci_device, DRIVER_NAME ), rvalue)
+    {
+        DEBUG(SHOW_ERROR_MESSAGES, "pci_request_regions failure, rvalue %i\n",
+            rvalue );
+        return -EIO;
+    }
+    
+    // enable PCI bus-mastering
+    pci_set_master(pci_device);
+
+    // Log the device resources information
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "islpci device: phymem:0x%lx, irq:%d \n",
+        (long) phymem, irq);
+#endif
+
+    // setup the network device interface and its structure
+    if (nw_device = islpci_probe(nw_device, pci_device, (long) phymem, (int) irq),
+        nw_device == NULL)
+    {
+        // error configuring the driver as a network device
+        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not configure "
+            "network device \n", DRIVER_NAME );
+        return -EIO;
+    }
+
+    // save the interrupt request line and use the remapped device base address
+    // as the device identification both for uniqueness and parameter passing
+    // to the interrupt handler
+    private_config = nw_device->priv;
+    private_config->pci_irq = irq;
+    private_config->pci_dev_id = dev_id;
+    private_config->device_id = private_config->remapped_device_base;
+	
+    spin_lock_init( &private_config->slock );
+
+    // request for the interrupt before uploading the firmware
+    printk("request_irq(%d)\n", irq );
+    if ( rvalue = request_irq(irq, &islpci_interrupt, SA_INTERRUPT | SA_SHIRQ, DRIVER_NAME, private_config), rvalue != 0 )
+    {
+        // error, could not hook the handler to the irq
+        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not install IRQ-handler \n", DRIVER_NAME );
+        return -EIO;
+    }
+
+#ifdef CONFIG_ARCH_ISL3893
+    uPCI->ARMIntEnReg = 0x20000FF;
+#endif
+
+#ifndef CONFIG_ARCH_ISL3893
+    // select the firmware file depending on the device id, take for default
+    // the 3877 firmware file
+    if( dev_id == PCIDEVICE_ISL3890 )
+    	strcpy( firmware, ISL3890_IMAGE_FILE );
+    else
+    	strcpy( firmware, ISL3877_IMAGE_FILE );
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "Firmware file: %s \n", firmware );
+#endif
+	
+    if (isl38xx_upload_firmware( firmware, private_config->remapped_device_base,
+        private_config->device_host_address ) == -1)
+    {
+        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not upload the "
+            "firmware \n", DRIVER_NAME );
+        return -EIO;
+    }
+#endif
+
+#ifdef CONFIG_ARCH_ISL3893
+    mgt_initialize();
+#endif
+
+#ifdef INTERSIL_EVENTS 
+    mgt_indication_handler ( DEV_NETWORK, nw_device->name, 0, islpci_mgt_indication );
+#endif
+#ifdef WDS_LINKS 
+    mgt_indication_handler ( DEV_NETWORK, nw_device->name, DOT11_OID_WDSLINKADD, islpci_wdslink_add_hndl );
+    mgt_indication_handler ( DEV_NETWORK, nw_device->name, DOT11_OID_WDSLINKREMOVE, islpci_wdslink_del_hndl );
+#endif
+
+    return 0;
+}
+
+void islpci_remove_pci( struct pci_dev *pci_device )
+{
+    struct net_device **devp, **next;
+    islpci_private *private_config;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_remove_pci\n");
+#endif
+
+    for (devp = &root_islpci_device; *devp; devp = next)
+    {
+        next = &((islpci_private *) (*devp)->priv)->next_module;
+        private_config = (*devp)->priv;
+
+        // free the interrupt request
+        writel(0, private_config->remapped_device_base + ISL38XX_INT_EN_REG);
+        free_irq(private_config->pci_irq, private_config);
+    }
+
+}
+
+int init_module( void )
+{
+    DEBUG(SHOW_ANYTHING, "Loaded %s, version %s\n", DRIVER_NAME, VERSIONID );
+
+    if (pci_register_driver(&islpci_pci_drv_id) <= 0)
+    {
+        DEBUG(SHOW_ERROR_MESSAGES, "%s: No devices found, driver not "
+            "installed.\n", DRIVER_NAME);
+        pci_unregister_driver(&islpci_pci_drv_id);
+        return -ENODEV;
+    }
+
+    return 0;
+}
+
+
+void cleanup_module( void )
+{
+    struct net_device *next_dev;
+    islpci_private *private_config;
+
+#ifdef INTERSIL_EVENTS
+    mgt_cleanup();
+#endif
+    
+    pci_unregister_driver(&islpci_pci_drv_id);
+
+    // No need to check MOD_IN_USE, as sys_delete_module() checks
+    while (root_islpci_device)
+    {
+        private_config = (islpci_private *) root_islpci_device->priv;
+        next_dev = private_config->next_module;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+        DEBUG(SHOW_TRACING, "Cleanup netdevice \n");
+#endif
+        // unregister the network device
+        unregister_netdev(root_islpci_device);
+
+        // free the PCI memory and unmap the remapped page
+        islpci_free_memory( private_config, ALLOC_MEMORY_MODE );
+        iounmap(private_config->remapped_device_base);
+        pci_release_regions(private_config->pci_device);
+
+        // free the separately allocated areas
+        kfree(private_config);
+        kfree(root_islpci_device);
+
+        // change the root device pointer to the next device for clearing
+        root_islpci_device = next_dev;
+    }
+
+    DEBUG(SHOW_ANYTHING, "Unloaded %s\n", DRIVER_NAME );
+}
diff -urN linux-2.4.29/drivers/net/intersil/islpci_hotplug.h linux-2.4.29-uc1/drivers/net/intersil/islpci_hotplug.h
--- linux-2.4.29/drivers/net/intersil/islpci_hotplug.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islpci_hotplug.h	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,54 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef _ISLPCI_HOTPLUG_H
+#define _ISLPCI_HOTPLUG_H
+
+
+#ifndef DRIVER_NAME
+#define DRIVER_NAME             "islpci"
+#endif
+
+#ifdef CONFIG_ARCH_ISL3893
+#define ISL3877_IMAGE_FILE      "/boot/3877.arm"
+#define ISL3890_IMAGE_FILE  	"/boot/3890.arm"
+#else
+#define ISL3877_IMAGE_FILE      "/etc/hotplug/isl3877.arm"
+#define ISL3890_IMAGE_FILE  	"/etc/hotplug/isl3890.arm"
+#endif
+
+// PCI Class & Sub-Class code, Network-'Other controller'
+#define PCI_CLASS_NETWORK_OTHERS 0x280
+
+#define PCI_TYPE                (PCI_USES_MEM | PCI_ADDR0 | PCI_NO_ACPI_WAKE)
+
+
+#ifdef CONFIG_ARCH_ISL3893
+int islpci_probe_pci(struct net_device *nw_device, struct pci_dev *pci_device,
+                     const struct pci_device_id *id);
+#else
+int islpci_probe_pci(struct pci_dev *pci_device, const struct pci_device_id *id);
+#endif
+
+void islpci_remove_pci( struct pci_dev * );
+int init_module( void );
+void cleanup_module( void );
+
+
+#endif  // _ISLPCI_HOTPLUG_H
diff -urN linux-2.4.29/drivers/net/intersil/islpci_mgt.c linux-2.4.29-uc1/drivers/net/intersil/islpci_mgt.c
--- linux-2.4.29/drivers/net/intersil/islpci_mgt.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islpci_mgt.c	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,1414 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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 <linux/config.h>
+#include <linux/netdevice.h>
+#ifdef MODULE
+#ifdef MODVERSIONS
+#include <linux/modversions.h>
+#endif
+#include <linux/module.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
+#include <asm/io.h>
+#ifdef CONFIG_ARCH_ISL3893
+#include <asm/arch/blobcalls.h>
+#endif
+#include <linux/pci.h>
+
+#include "isl_gen.h"
+#include "isl_38xx.h"
+#include "islpci_mgt.h"
+#include "bloboid.h"      // additional types and defs for isl38xx fw
+
+#ifdef CONFIG_ARCH_ISL3893
+#include "islpci_hotplug.h"
+#define INTERSIL_EVENTS
+#define WDS_LINKS
+#endif
+
+#ifdef INTERSIL_EVENTS
+#include "isl_mgt.h"
+#endif
+
+#ifdef WDS_LINKS
+#include "isl_wds.h"
+#endif
+
+#ifdef WIRELESS_EVENTS
+#if WIRELESS_EXT > 12
+#include <net/iw_handler.h>
+#endif
+#endif
+
+/******************************************************************************
+        Global variable definition section
+******************************************************************************/
+int pc_debug = VERBOSE;
+int init_mode = CARD_DEFAULT_MODE;
+int init_channel = CARD_DEFAULT_CHANNEL;
+int init_bsstype = CARD_DEFAULT_BSSTYPE;
+int init_wep = CARD_DEFAULT_WEP;
+int init_filter = CARD_DEFAULT_FILTER;
+int init_wds = CARD_DEFAULT_WDS;
+int init_authen = CARD_DEFAULT_AUTHEN;
+int init_dot1x = CARD_DEFAULT_DOT1X;
+int init_mlme = CARD_DEFAULT_MLME_MODE;
+char *init_ssid = NULL;
+
+#ifdef INTERSIL_EVENTS
+extern unsigned int src_seq;
+#endif
+extern int firmware_uploaded;
+
+#ifdef MODULE
+MODULE_PARM( pc_debug, "i" );
+MODULE_PARM( init_mode, "i" );
+MODULE_PARM( init_channel, "i" );
+MODULE_PARM( init_bsstype, "i" );
+MODULE_PARM( init_ssid, "s" );
+MODULE_PARM( init_wep, "i" );
+MODULE_PARM( init_filter, "i" );
+/* MODULE_PARM( init_wds, "i" ); */
+MODULE_PARM( init_authen, "i" );
+MODULE_PARM( init_dot1x, "i" );
+MODULE_PARM( init_mlme, "i" );
+#endif
+
+DECLARE_WAIT_QUEUE_HEAD(mgmt_queue_wait);
+
+/******************************************************************************
+    Frame (re)format functions
+******************************************************************************/
+void pimfor_encode_header(int operation, unsigned long oid,
+                                 int device_id, int flags, int length,
+                                 pimfor_header * header)
+{
+    // byte oriented members
+    header->version = PIMFOR_VERSION;
+    header->operation = operation;
+    header->device_id = device_id;
+    header->flags = flags;
+
+    // word oriented members with byte order depending on the flags
+    if (flags & PIMFOR_FLAG_LITTLE_ENDIAN)
+    {
+        // use little endian coding
+        header->oid[3] = oid >> 24;
+        header->oid[2] = oid >> 16;
+        header->oid[1] = oid >> 8;
+        header->oid[0] = oid;
+        header->length[3] = 0;
+        header->length[2] = 0;
+        header->length[1] = length >> 8;
+        header->length[0] = length;
+    }
+    else
+    {
+        // use big endian coding
+        header->oid[0] = oid >> 24;
+        header->oid[1] = oid >> 16;
+        header->oid[2] = oid >> 8;
+        header->oid[3] = oid;
+        header->length[0] = 0;
+        header->length[1] = 0;
+        header->length[2] = length >> 8;
+        header->length[3] = length;
+    }
+}
+
+void pimfor_decode_header(pimfor_header * header, int *operation,
+                                 unsigned long *oid, int *device_id,
+                                 int *flags, int *length)
+{
+    // byte oriented members
+    *operation = header->operation;
+    *device_id = header->device_id;
+    *flags = header->flags;
+
+    // word oriented members with byte order depending on the flags
+    if (*flags & PIMFOR_FLAG_LITTLE_ENDIAN)
+    {
+        // use little endian coding
+        *oid = ((int) header->oid[3] << 24) |
+            ((int) header->oid[2] << 16) |
+            ((int) header->oid[1] << 8) | ((int) header->oid[0]);
+        *length = ((int) header->length[1] << 8) |
+            ((int) header->length[0]);
+    }
+    else
+    {
+        // use big endian coding
+        *oid = ((int) header->oid[0] << 24) |
+            ((int) header->oid[1] << 16) |
+            ((int) header->oid[2] << 8) | ((int) header->oid[3]);
+        *length = ((int) header->length[2] << 8) |
+            ((int) header->length[3]);
+    }
+}
+
+/******************************************************************************
+    Memory Management functions
+******************************************************************************/
+void islpci_init_queue(queue_root * queue)
+{
+    queue->host_address = (u32) NULL;
+    queue->dev_address = (u32) NULL;
+    queue->size = 0;
+    queue->fragments = 0;
+}
+
+int islpci_put_queue(void *device, queue_root * queue, queue_entry * entry)
+{
+    queue_entry *last;
+
+    // the size and next members are both accessed from kernel code and from
+    // interrupt handler, disable the update interrupt as short as possible
+    isl38xx_disable_update_interrupt(device);
+
+    // check whether the queue is empty or not
+    if (queue->size == 0)
+    {
+        // queue is empty, add the entry at the start of the queue
+        queue->next = (void *) entry;
+        queue->last = (void *) entry;
+    }
+    else
+    {
+        // the queue is not empty, add the entry at the back
+        last = (queue_entry *) queue->last;
+        last->next = (void *) entry;
+        queue->last = (void *) entry;
+    }
+
+    // increment the queue size
+    queue->size++;
+
+    // enable the update interrupt again
+    isl38xx_enable_update_interrupt(device);
+
+    return 0;
+}
+
+int islpci_get_queue(void *device, queue_root * queue,
+                     queue_entry ** entry)
+{
+    queue_entry *first;
+
+    // the size and next members are both accessed from kernel code and from
+    // interrupt handler, disable the update interrupt as short as possible
+    isl38xx_disable_update_interrupt(device);
+
+    // check whether the queue is empty or not
+    if (queue->size == 0)
+    {
+        // queue is empty, nothing to get
+        // enable the update interrupt again
+        isl38xx_enable_update_interrupt(device);
+
+        return -1;
+    }
+    else
+    {
+        // the queue is not empty, get the entry at the start
+        first = (queue_entry *) queue->next;
+        queue->next = first->next;
+        first->next = NULL;
+        *entry = first;
+    }
+
+    // decrement the queue size
+    queue->size--;
+
+    // enable the update interrupt again
+    isl38xx_enable_update_interrupt(device);
+
+    return 0;
+}
+
+int islpci_queue_size(void *device, queue_root * queue)
+{
+    int qsize;
+
+    // disable the update interrupt of the device
+    isl38xx_disable_update_interrupt(device);
+
+    // read the size of the queue from the root entry
+    qsize = (int) queue->size;
+
+    // enable the update interrupt of the device
+    isl38xx_enable_update_interrupt(device);
+
+    return qsize;
+}
+
+
+/******************************************************************************
+    Driver Configuration functions
+******************************************************************************/
+void islpci_mgt_initialize( islpci_private *private_config )
+{
+    char configmode[4] = { INL_CONFIG_MANUALRUN, 0, 0, 0 };
+    char cardmode[4] = { 0, 0, 0, 0 };
+    char bsstype[4] =  { 0, 0, 0, 0 };
+    char channel[4] =  { 0, 0, 0, 0 };
+    char authen[4] = { 0, 0, 0, 0 };
+    char invoke[4] = { 0, 0, 0, 0 };
+    char exunencrypt[4] = { 0, 0, 0, 0 };
+    char dot1xen[4] = { 0, 0, 0, 0 };
+	char mlmemode[4] = { 0, 0, 0, 0 };
+    struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
+    struct obj_ssid essid_obj = { sizeof( CARD_DEFAULT_SSID ) - 1,
+                                CARD_DEFAULT_SSID };
+    struct obj_buffer psm_buffer = { cpu_to_le32(PSM_BUFFER_SIZE), 0 };
+
+    // store all device initialization management frames in the
+    // management transmit shadow queue
+    cardmode[0] = (char) init_mode;
+    channel[0] = (char) init_channel;
+    channel[1] = (char) (init_channel >> 8);
+    bsstype[0] = (char) init_bsstype;
+    authen[0] = (char) init_authen;
+    invoke[0] = (char) init_wep;
+    exunencrypt[0] = (char) init_filter;
+    dot1xen[0] = (char) init_dot1x;
+    mlmemode[0] = (char) init_mlme;
+    if( init_ssid != NULL )
+    {
+        // parameter specified when loading the module
+        essid_obj.length = strlen( init_ssid );
+        strcpy( essid_obj.octets, init_ssid );
+    }
+    psm_buffer.base = (void *) cpu_to_le32( private_config->device_psm_buffer );
+    if( init_wds )
+    {
+        // enable wds mode in the host interface
+        configmode[0] |= INL_CONFIG_WDS;
+    }
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "cardmode: %i \n", init_mode );
+    DEBUG(SHOW_TRACING, "channel: %i \n", init_channel );
+    DEBUG(SHOW_TRACING, "bsstype: %i \n", init_bsstype );
+    DEBUG(SHOW_TRACING, "wep: %i \n", init_wep );
+    DEBUG(SHOW_TRACING, "authen: %i \n", init_authen );
+    DEBUG(SHOW_TRACING, "filter: %i \n", init_filter );
+    DEBUG(SHOW_TRACING, "wds: %i \n", init_wds );
+    DEBUG(SHOW_TRACING, "ssid: %i %s \n", essid_obj.length, essid_obj.octets );
+    DEBUG(SHOW_TRACING, "psm: %p %li\n", psm_buffer.base, psm_buffer.size );
+#endif
+
+    // store all device initialization management frames in the
+    // management transmit shadow queue
+
+    //  get firmware configuration data
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET,
+        GEN_OID_MACADDRESS, 0, NULL, 6, 0);
+
+    // set the configuration mode to manual run & wds option
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        OID_INL_CONFIG, 0, &configmode[0], 4, 0);
+
+    // set the mode for stopping the device
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        OID_INL_MODE, 0, &cardmode[0], 4, 0);
+
+    // set the bsstype
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_BSSTYPE, 0, &bsstype[0], 4, 0);
+
+    // set the channel
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_CHANNEL, 0, &channel[0], 4, 0);
+
+    // set the SSID
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_SSID, 0, (void *) &essid_obj, sizeof(struct obj_ssid), 0);
+
+	// use the essid object to override the SSID 
+	essid_obj.length = sizeof( CARD_DEFAULT_SSIDOVERRIDE ) - 1;
+	memcpy( essid_obj.octets, CARD_DEFAULT_SSIDOVERRIDE, essid_obj.length );
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET, DOT11_OID_SSIDOVERRIDE,
+		0, (void *) &essid_obj, sizeof(struct obj_ssid), 0);
+
+    // set the PSM buffer object
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_PSMBUFFER, 0, (void *) cpu_to_le32( &psm_buffer ),
+        sizeof(struct obj_buffer), 0);
+
+    // set the authentication enable option
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_AUTHENABLE, 0, &authen[0], 4, 0);
+
+    // set the privacy invoked mode
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_PRIVACYINVOKED, 0, &invoke[0], 4, 0);
+
+    // set the exunencrypted object
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_EXUNENCRYPTED, 0, &exunencrypt[0], 4, 0);
+
+    // set default key 1
+    strcpy( key.key, CARD_DEFAULT_KEY1 );
+    key.length = strlen(CARD_DEFAULT_KEY1) > sizeof(key.key) ?
+        sizeof(key.key) : strlen(CARD_DEFAULT_KEY1);
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET, DOT11_OID_DEFKEY1, 0,
+        &key, sizeof(struct obj_key), 0);
+
+    // set default key 2
+    strcpy( key.key, CARD_DEFAULT_KEY2 );
+    key.length = strlen(CARD_DEFAULT_KEY2) > sizeof(key.key) ?
+        sizeof(key.key) : strlen(CARD_DEFAULT_KEY2);
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET, DOT11_OID_DEFKEY2, 0,
+        &key, sizeof(struct obj_key), 0);
+
+    // set default key 3
+    strcpy( key.key, CARD_DEFAULT_KEY3 );
+    key.length = strlen(CARD_DEFAULT_KEY3) > sizeof(key.key) ?
+        sizeof(key.key) : strlen(CARD_DEFAULT_KEY3);
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET, DOT11_OID_DEFKEY3, 0,
+        &key, sizeof(struct obj_key), 0);
+
+    // set default key 4
+    strcpy( key.key, CARD_DEFAULT_KEY4 );
+    key.length = strlen(CARD_DEFAULT_KEY4) > sizeof(key.key) ?
+        sizeof(key.key) : strlen(CARD_DEFAULT_KEY4);
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET, DOT11_OID_DEFKEY4, 0,
+        &key, sizeof(struct obj_key), 0);
+
+    // set the dot1x enable object
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_DOT1XENABLE, 0, &dot1xen[0], 4, 0);
+
+    // set the mlme mode object
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        DOT11_OID_MLMEAUTOLEVEL, 0, &mlmemode[0], 4, 0);
+
+#ifndef CONFIG_ARCH_ISL3893
+    // set the mode again for starting the device
+    islpci_mgt_queue(private_config, PIMFOR_OP_SET,
+        OID_INL_MODE, 0, &cardmode[0], 4, 0);
+#endif
+
+    // call the transmit function for triggering the transmitting of the
+    // first frame in the shadow queue
+    islpci_mgt_transmit( private_config );
+}
+
+/******************************************************************************
+    Device Interface functions
+******************************************************************************/
+int islpci_mgt_transmit(islpci_private * private_config)
+{
+    int fragments, counter;
+    isl38xx_control_block *control_block = private_config->control_block;
+    isl38xx_fragment *fragment;
+    u32 index, in_queue, in_shadowq;
+    queue_entry *entry;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_transmit \n");
+#endif
+
+    // check whether there is a pending response in the receive queue which
+    // needs to be handled first before applying a new frame
+    if( in_queue = isl38xx_in_queue(control_block, ISL38XX_CB_RX_MGMTQ),
+        in_queue != 0 )
+    {
+        // receive queue not empty
+#if VERBOSE > SHOW_ERROR_MESSAGES
+        DEBUG(SHOW_TRACING, "receive queue not empty\n");
+#endif
+        return 0;
+    }
+
+    // read the number of entries in the transmit queue and check whether the
+    // transmit queue is empty for receiving the next pimfor frame
+    if( in_queue = isl38xx_in_queue(control_block, ISL38XX_CB_TX_MGMTQ),
+        in_queue != 0 )
+    {
+        // transmit queue not empty
+#if VERBOSE > SHOW_ERROR_MESSAGES
+        DEBUG(SHOW_TRACING, "transmit queue not empty\n");
+#endif
+        // trigger the device
+        pci_map_single( private_config->pci_device, private_config->control_block, 
+                        sizeof(struct isl38xx_cb), PCI_DMA_BIDIRECTIONAL );
+        isl38xx_trigger_device( &private_config->powerstate, private_config->remapped_device_base );
+
+        return 0;
+    }
+
+    // first check whether a clean up should take place on the shadow queue
+    while( private_config->index_mgmt_tx > in_queue )
+    {
+        // free the first entry in the shadow queue which contains the
+        // PIMFOR frame transmitted to the device
+        islpci_get_queue(private_config->remapped_device_base,
+                &private_config->mgmt_tx_shadowq, &entry);
+        islpci_put_queue(private_config->remapped_device_base,
+                &private_config->mgmt_tx_freeq, entry);
+
+        // decrement the real management index
+        private_config->index_mgmt_tx--;
+    }
+
+    // check whether there is at least one frame in the shadowq
+    if( in_shadowq = islpci_queue_size( private_config->remapped_device_base,
+        &private_config->mgmt_tx_shadowq ), !in_shadowq )
+    {
+        // no entries in the shadowq, quit
+#if VERBOSE > SHOW_ERROR_MESSAGES
+        DEBUG(SHOW_TRACING, "shadowq empty, no more frames\n");
+#endif
+        return 0;
+    }
+
+    // there is a frame in the shadowq, get its fragments count
+    entry = (queue_entry *) &private_config->mgmt_tx_shadowq;
+    entry = (queue_entry *) entry->next;
+    fragments = entry->fragments;
+
+    // transmit the fragment(s) by placing them in the transmit queue
+    for (counter = 0; counter < fragments; counter++)
+    {
+        u16 fragment_flags;
+
+        // determine the fragment flags depending on the nr of fragments
+        fragment_flags = fragments - counter > 1 ? FRAGMENT_FLAG_MF : 0;
+
+        // get a pointer to the destination fragment using the frame counter
+        // and link it with the free queue entry data block
+        index = le32_to_cpu(control_block->driver_curr_frag[ISL38XX_CB_TX_MGMTQ]) %
+                ISL38XX_CB_MGMT_QSIZE;
+        fragment = &control_block->tx_data_mgmt[index];
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+        DEBUG(SHOW_TRACING, "Entry address %p\n", entry);
+        DEBUG(SHOW_TRACING, "Index in transmit queue %i\n", index);
+        DEBUG(SHOW_TRACING, "Fragment address %p\n", fragment);
+#endif
+
+        fragment->address = cpu_to_le32(entry->dev_address);
+        fragment->size = cpu_to_le16(entry->size);
+        fragment->flags = cpu_to_le16(fragment_flags);
+
+        // increment the index pointer, wrapping is not done on queue but
+        // on variable type range
+        add_le32p(&control_block->driver_curr_frag[ISL38XX_CB_TX_MGMTQ], 1);
+
+        // increment the queue entry pointer
+        entry = (queue_entry *) entry->next;
+    }
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Frame with [%i] fragments added to transmit queue \n",
+      fragments);
+#endif
+
+    // increment the read management queue index
+    private_config->index_mgmt_tx += fragments;
+
+    // flush the dcache write buffer
+    pci_map_single( private_config->pci_device, private_config->control_block, 
+                    sizeof(struct isl38xx_cb), PCI_DMA_TODEVICE );
+
+    // trigger the device
+    isl38xx_trigger_device( &private_config->powerstate, private_config->remapped_device_base );
+
+    return 0;
+}
+
+/*
+       // ====================================================
+        if( private_config->resetdevice == 1 )
+        {
+            DEBUG(SHOW_FUNCTION_CALLS,
+                    "Reset Device flag set, quit IRQ handler\n" );
+
+            DEBUG(SHOW_QUEUE_INDEXES,
+                "CB drv Qs: [%i][%i][%i][%i][%i][%i]\n",
+                le32_to_cpu(private_config->control_block->driver_curr_frag[0]),
+                le32_to_cpu(private_config->control_block->driver_curr_frag[1]),
+                le32_to_cpu(private_config->control_block->driver_curr_frag[2]),
+                le32_to_cpu(private_config->control_block->driver_curr_frag[3]),
+                le32_to_cpu(private_config->control_block->driver_curr_frag[4]),
+                le32_to_cpu(private_config->control_block->driver_curr_frag[5])
+                );
+
+            DEBUG(SHOW_QUEUE_INDEXES,
+                "CB dev Qs: [%i][%i][%i][%i][%i][%i]\n",
+                le32_to_cpu(private_config->control_block->device_curr_frag[0]),
+                le32_to_cpu(private_config->control_block->device_curr_frag[1]),
+                le32_to_cpu(private_config->control_block->device_curr_frag[2]),
+                le32_to_cpu(private_config->control_block->device_curr_frag[3]),
+                le32_to_cpu(private_config->control_block->device_curr_frag[4]),
+                le32_to_cpu(private_config->control_block->device_curr_frag[5])
+                );
+
+
+            return 0;
+        }
+        // ====================================================
+*/
+
+
+
+int islpci_mgt_queue(islpci_private * private_config,
+                                  int operation, unsigned long oid,
+                                  int flags, void *data, int length,
+                                  int use_tunnel_oid)
+{
+    int fragments, counter;
+    u32 source, destination;
+    queue_entry *entry;
+    char firmware[64];
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_queue \n");
+#endif
+
+#ifdef CONFIG_ARCH_ISL3893
+    /* check whether the firmware has been uploaded in the device */
+    if( !firmware_uploaded )
+    {
+        DEBUG(SHOW_ERROR_MESSAGES, "islpci_mgt_queue failed: Firmware not uploaded\n" );
+        return -1;    
+    }
+#endif
+
+    // determine the amount of fragments needed for the frame in case of a SET
+    if (use_tunnel_oid)
+    {
+        fragments = (length + 2 * PIMFOR_HEADER_SIZE) / MGMT_FRAME_SIZE;
+        if ((length + 2 * PIMFOR_HEADER_SIZE) % MGMT_FRAME_SIZE != 0)
+            fragments++;
+    }
+    else
+    {
+        fragments = (length + PIMFOR_HEADER_SIZE) / MGMT_FRAME_SIZE;
+        if ((length + PIMFOR_HEADER_SIZE) % MGMT_FRAME_SIZE != 0)
+        fragments++;
+    }
+
+    // check whether data is actually written to the device
+    if (operation == PIMFOR_OP_GET)
+    {
+        // operation is get, no data is actually written, reset the fragments
+        // counter to send a single fragment
+        fragments = 1;
+    }
+
+    // check whether the number of fragments doesn't exceed the maximal possible
+    // amount of frames in the transmit queue
+    if( fragments > ISL38XX_CB_MGMT_QSIZE )
+    {
+        // Oops, the fragment count exceeds the maximal value
+        DEBUG(SHOW_ERROR_MESSAGES, "Error: Frame with [%i] fragments is too "
+            "large \n", fragments );
+        return -1;
+    }
+
+    // check whether there is enough room for the fragment(s) in the freeq
+    if( islpci_queue_size( private_config->remapped_device_base,
+        &private_config->mgmt_tx_freeq ) < fragments )
+    {
+        // Oops, the management freeq does not have enough entries
+        DEBUG(SHOW_ERROR_MESSAGES, "Error: Management FreeQ not enough entries "
+            "for [%i] fragments \n", fragments );
+        return -1;
+    }
+
+    // queue the frame(s) in the transmit shadow queue
+    for (counter = 0, source = (u32) data; counter < fragments; counter++)
+    {
+        u16 fragment_size = 0;
+
+        // get an entry from the free queue for hosting the frame
+        islpci_get_queue(private_config->remapped_device_base,
+            &private_config->mgmt_tx_freeq, &entry);
+
+        // set the destination address to the entry data block for building
+        // the PIMFOR frame there
+        destination = entry->host_address;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+        DEBUG(SHOW_TRACING, "Entry address %p\n", entry);
+        DEBUG(SHOW_TRACING, "Destination address %x\n", destination);
+        DEBUG(SHOW_TRACING, "Destination for device %x\n", entry->dev_address);
+#endif
+
+        // place the PIMFOR header in the first fragment
+        if (counter == 0)
+        {
+            // check whether the frame should have a tunnel oid
+            if (use_tunnel_oid)
+            {
+                // start with a tunnel oid header
+                pimfor_encode_header(PIMFOR_OP_SET, OID_INL_TUNNEL,
+                     PIMFOR_DEV_ID_MHLI_MIB, flags,
+                     length + PIMFOR_HEADER_SIZE,
+                     (pimfor_header *) destination);
+
+                // set the fragment size and increment the destin pointer
+                fragment_size += PIMFOR_HEADER_SIZE;
+                destination += PIMFOR_HEADER_SIZE;
+            }
+
+            // create the header directly in the fragment data area
+            pimfor_encode_header(operation, oid, PIMFOR_DEV_ID_MHLI_MIB,
+                 flags, length, (pimfor_header *) destination);
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            // display the buffer contents for debugging
+            display_buffer((char *) destination, 12);
+#endif
+
+            // set the fragment size and increment the destin pointer
+            fragment_size += PIMFOR_HEADER_SIZE;
+            destination += PIMFOR_HEADER_SIZE;
+        }
+
+        // add the data to the fragment 
+        if( length != 0 && source != 0 )
+        {
+            int size = (length > (MGMT_FRAME_SIZE - fragment_size)) ?
+                MGMT_FRAME_SIZE - fragment_size : length;
+            memcpy((void *) destination, (void *) source, size);
+
+            // set the fragment size and flag members
+            fragment_size += size;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            // display the buffer contents for debugging
+            display_buffer((char *) destination, 12);
+#endif
+
+            // update the source pointer and the data length
+            source += size;
+            length -= size;
+        }
+
+        // save the number of fragments still to go in the frame together with
+        // the fragment size
+        entry->fragments = fragments - counter;
+        entry->size = fragment_size;
+
+        // store the entry in the tx shadow queue
+        islpci_put_queue(private_config->remapped_device_base,
+            &private_config->mgmt_tx_shadowq, entry);
+    }
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Frame with [%i] fragments added to shadow tx queue \n",
+        fragments);
+#endif
+
+    return 0;
+}
+
+int islpci_mgt_receive(islpci_private * private_config)
+{
+    struct net_device *nw_device = private_config->my_module;
+    isl38xx_control_block *control_block = private_config->control_block;
+    pimfor_header *received_header;
+    char *received_data;
+    int device_id, operation, flags, length;
+    unsigned long oid;
+    queue_entry *entry, *new_entry;
+
+#ifdef WIRELESS_EVENTS
+    union iwreq_data wrq;
+#endif
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_receive \n");
+#endif
+
+    // get the received response from the shadow queue
+    islpci_get_queue(private_config->remapped_device_base,
+                &private_config->mgmt_rx_shadowq, &entry);
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Entry address 0x%p\n", entry);
+    DEBUG(SHOW_TRACING, "Entry device address 0x%x\n", entry->dev_address);
+#endif
+
+    // determine how the process the fragment depending on the flags in the
+    // PIMFOR header, check for tunnel oid PIMFOR frames
+    received_header = (pimfor_header *) entry->host_address;
+    if (pimfor_decode_header(received_header, &operation, &oid, &device_id,
+        &flags, &length), oid == OID_INL_TUNNEL)
+    {
+#if VERBOSE > SHOW_ERROR_MESSAGES
+        DEBUG(SHOW_PIMFOR_FRAMES, "PIMFOR: Tunnel OID frame received \n");
+#endif
+
+        // PMFOR frame in fragment has the tunnel oid, redo the header decode
+        received_header = (pimfor_header *) (entry->host_address +
+            PIMFOR_HEADER_SIZE);
+        pimfor_decode_header(received_header, &operation, &oid, &device_id,
+            &flags, &length);
+    }
+
+    /* The device ID from the pimfor packet received from the MVC is always 0
+     * This is not the device_id we want to give to the applications above
+     * so lets get the device_id using the private net_local structure
+     */
+    device_id = private_config->my_module->ifindex;
+    
+    received_data = (char *) received_header + PIMFOR_HEADER_SIZE;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_PIMFOR_FRAMES,
+        "PIMFOR: op %i, oid 0x%lx, device %i, flags 0x%x length 0x%x \n",
+        operation, oid, device_id, flags, length);
+
+    // display the buffer contents for debugging
+    display_buffer((char *) received_header, sizeof(pimfor_header));
+    display_buffer(((char *) received_header) + PIMFOR_HEADER_SIZE, length );
+#endif
+
+    // PIMFOR frame created by this driver, handle its contents
+    // check whether the frame contains driver initialization data
+    if (oid == GEN_OID_MACADDRESS)
+    {
+        // a MAC address response message, store its contents
+        if ((operation == PIMFOR_OP_RESPONSE) && (length == 6))
+        {
+            // copy the MAC address received
+            memcpy(nw_device->dev_addr, received_data, 6);
+        }
+    }
+    else if (oid == OID_INL_MODE)
+    {
+        // the mode response message, store its contents
+        if ((operation == PIMFOR_OP_RESPONSE) && (length == 4))
+        {
+            // copy the low byte which is at the first byte location
+            private_config->mode = (int) *received_data;
+        }
+    }
+    else if (oid == GEN_OID_LINKSTATE)
+    {
+        // the mode response message, store its contents
+        if ((operation == PIMFOR_OP_RESPONSE) && (length == 4))
+        {
+            // copy the low byte which is at the first byte location
+            private_config->linkstate = (int) *received_data;
+        }
+    }
+	else if ( (oid >= DOT11_OID_DEAUTHENTICATE) && 
+		(oid <= DOT11_OID_REASSOCIATEEX) )
+	{
+		// received an mlme reply or trap message
+		islpci_mgt_mlme( oid, received_data );
+	}
+
+    // perform a check on the freeq whether the entry can be queued to other
+    // queues or must be hold to make sure there are enough
+    if( islpci_get_queue(private_config->remapped_device_base,
+        &private_config->mgmt_rx_freeq, &new_entry) == 0)
+    {
+        // succeeded in getting a new entry from the freeq
+        // refresh the device mgmt queue entry
+        control_block->rx_data_mgmt[private_config->index_mgmt_rx].address =
+            cpu_to_le32(new_entry->dev_address);
+
+        // put the new entry in the mgmt rx shadow queue
+        islpci_put_queue(private_config->remapped_device_base,
+                &private_config->mgmt_rx_shadowq, new_entry);
+
+        // deliver the held entry to the appropriate queue
+        if (flags & PIMFOR_FLAG_APPLIC_ORIGIN)
+        {
+            // PIMFOR frame originated by higher application, send the entire
+            // fragment up without processing
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+            DEBUG(SHOW_TRACING, "PIMFOR Application Originated \n");
+#endif
+
+            // send the entry to the PIMFOR receive queue for further processing
+            islpci_put_queue(private_config->remapped_device_base,
+                &private_config->pimfor_rx_queue, entry);
+        }
+        else
+        {
+            // check whether the frame concerns a response, error or trap
+            if (operation == PIMFOR_OP_TRAP)
+            {
+#if VERBOSE > SHOW_ERROR_MESSAGES
+                DEBUG(SHOW_TRAPS,
+                    "TRAP: oid 0x%lx, device %i, flags 0x%x length %i\n",
+                    oid, device_id, flags, length);
+#endif
+
+#ifdef INTERSIL_EVENTS
+                mgt_response( 0, src_seq++, DEV_NETWORK_WLAN, device_id,
+                              PIMFOR_OP_TRAP, oid, received_data, length );
+#endif
+                // check whether the TRAP should be deleted or queued depending
+                // on the queue size and whether the queue is read
+                if( islpci_queue_size( private_config->remapped_device_base,
+                    &private_config->trap_rx_queue ) > MAX_TRAP_RX_QUEUE )
+                {
+                    // free the entry to the freeq
+                    islpci_put_queue(private_config->remapped_device_base,
+                            &private_config->mgmt_rx_freeq, entry);
+                }
+                else
+                {
+                    // send the entry to the TRAP receive q
+                    islpci_put_queue(private_config->remapped_device_base,
+                        &private_config->trap_rx_queue, entry);
+
+#ifdef WIRELESS_EVENTS
+                    // signal user space application(s) that a TRAP is queued
+                    // use the AP MAC address get ioctl for signalling
+                        wrq.ap_addr.sa_family = ARPHRD_ETHER;
+                            memcpy( wrq.ap_addr.sa_data, nw_device->dev_addr, 6 );
+                            wireless_send_event( nw_device, SIOCGIWAP, &wrq, "ISIL" );
+#endif // WIRELESS_EVENTS
+                }
+            }
+            else
+            {
+                // received either a repsonse or an error
+                // send the entry to the IOCTL receive q for further processing
+                islpci_put_queue(private_config->remapped_device_base,
+                        &private_config->ioctl_rx_queue, entry);
+
+                // signal the waiting procs that a response has been received
+                wake_up_interruptible(&mgmt_queue_wait);
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+                DEBUG(SHOW_TRACING, "Wake up interruptible Mgmt Queue\n" );
+#endif
+            }
+        }
+    }
+    else
+    {
+        // not succeeded, use the held one and drop its contents
+        // refresh the device mgmt queue entry
+        control_block->rx_data_mgmt[private_config->index_mgmt_rx].address =
+            cpu_to_le32(entry->dev_address);
+
+        // put the old entry back in the mgmt rx shadow queue
+        islpci_put_queue(private_config->remapped_device_base,
+            &private_config->mgmt_rx_shadowq, entry);
+    }
+
+    // increment the driver read pointer
+    add_le32p(&control_block->driver_curr_frag[ISL38XX_CB_RX_MGMTQ], 1);
+
+    // trigger the device
+//    pci_map_single( private_config->pci_device, private_config->control_block, 
+//                    sizeof(struct isl38xx_cb), PCI_DMA_BIDIRECTIONAL );
+    isl38xx_trigger_device( &private_config->powerstate, private_config->remapped_device_base );
+
+    // increment and wrap the read index for the rx management queue
+    private_config->index_mgmt_rx = (private_config->index_mgmt_rx + 1) %
+        ISL38XX_CB_MGMT_QSIZE;
+
+    return 0;
+}
+
+int islpci_mgt_response(islpci_private * private_config, long oid, int* oper,
+                                 void **data, long *dlen, queue_entry **qentry )
+{
+    queue_entry *entry;
+    pimfor_header *received_header;
+    int q_size, counter, device_id, operation, flags, rlength;
+    int temp = ISL38XX_MAX_WAIT_CYCLES;
+    unsigned long received_oid;
+
+    DECLARE_WAITQUEUE(wait, current);
+
+    // check for other processes already waiting for response
+    if (private_config->processes_in_wait == 0)
+    {
+        // no process in the wait queue, flush the queue
+        while (islpci_queue_size(private_config->remapped_device_base,
+            &private_config->ioctl_rx_queue))
+        {
+            // flush each entry remaining in the queue
+            islpci_get_queue(private_config->remapped_device_base,
+                &private_config->ioctl_rx_queue, &entry);
+            islpci_put_queue(private_config->remapped_device_base,
+                &private_config->mgmt_rx_freeq, entry);
+        }
+    }
+
+    // trigger the transmission of the management shadowq before going to sleep
+    islpci_mgt_transmit( private_config );
+
+    // add the process to the wait queue and increment the process counter
+    add_wait_queue(&mgmt_queue_wait, &wait);
+    private_config->processes_in_wait++;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG(SHOW_TRACING, "Process enter sleep mode\n");
+#endif
+
+    while (1)
+    {
+        // go to sleep with the alarm bells on sharp
+        interruptible_sleep_on_timeout(&mgmt_queue_wait, ISL38XX_WAIT_CYCLE);
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+        DEBUG(SHOW_TRACING, "Woken up from a nap\n" );
+#endif
+
+        // hello there, I got woken up because there is either a response out
+        // there or the bells went off, check whether the lock is up
+        while (private_config->ioctl_queue_lock)
+        {
+            // the lock is up, another process is reading the ioctl rx queue
+            schedule_timeout(1 * HZ / 10);
+        }
+
+        // It's my turn, set the lock rightaway
+        private_config->ioctl_queue_lock = 1;
+
+        // check the IOCTL receive queue for responses
+        if( q_size = islpci_queue_size(private_config->remapped_device_base,
+            &private_config->ioctl_rx_queue), q_size != 0 )
+        {
+            // something in the queue, check every entry in the queue
+            for (counter = 0; counter < q_size; counter++)
+            {
+                // get the entry from the queue and read the header
+                islpci_get_queue(private_config->remapped_device_base,
+                    &private_config->ioctl_rx_queue, &entry);
+                received_header = (pimfor_header *) entry->host_address;
+
+                // check whether the oid response is for me
+                if( pimfor_decode_header(received_header, &operation,
+                    &received_oid, &device_id, &flags,&rlength ),
+                    oid == received_oid )
+                {
+#if VERBOSE > SHOW_ERROR_MESSAGES
+                    DEBUG(SHOW_TRACING, "IOCTL response found in queue.\n");
+#endif
+
+                    // found my response, return it all
+                    *data = (void *) received_header + PIMFOR_HEADER_SIZE;
+                    *qentry = entry;
+                    *dlen = rlength;
+		    *oper = operation;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+                    DEBUG(SHOW_TRACING, "Response source 0x%p\n", *data );
+#endif
+                    temp = 0;
+
+                    // continue and leave the sleepingroom
+                    goto leave;
+                }
+                else
+                {
+#if VERBOSE > SHOW_ERROR_MESSAGES
+                  DEBUG(SHOW_TRACING, "Skip received oid %lx \n", received_oid );
+#endif
+                }
+
+                // put the entry back in the queue
+                islpci_put_queue(private_config->remapped_device_base,
+                    &private_config->ioctl_rx_queue, entry);
+            }
+
+            // checked all entries in the queue without success
+            temp = -ETIMEDOUT;
+            goto leave;
+        }
+        else
+        {
+            // nothing in the queue, that's got to be a timeout
+            // decrement the retry timer stored in temp and check
+            if( temp--, !temp )
+            {
+                // max number of retries reached, really a problem
+                temp = -EBUSY;
+                goto leave;
+            }
+
+            // try another wakup on the card and wait for response
+            // when the device is sleeping
+            if( private_config->powerstate == ISL38XX_PSM_POWERSAVE_STATE )
+            {
+                // device is in powersave, trigger the device for wakeup
+#if VERBOSE > SHOW_ERROR_MESSAGES
+                DEBUG(SHOW_TRACING, "Device wakeup retrigger %i\n", temp );
+#endif
+                // assert the Wakeup interrupt in the Device Interrupt Register
+                writel( ISL38XX_DEV_INT_WAKEUP,
+                    private_config->remapped_device_base + ISL38XX_DEV_INT_REG);
+            }
+
+            // release the lock
+            private_config->ioctl_queue_lock = 0;
+        }
+    }
+
+leave:
+    private_config->processes_in_wait--;
+    private_config->ioctl_queue_lock = 0;
+    current->state = TASK_RUNNING;
+    remove_wait_queue(&mgmt_queue_wait, &wait);
+    return temp;
+}
+
+void islpci_mgt_release( islpci_private * private_config, queue_entry *entry )
+{
+    // free the entry is not NULL
+    if( entry != NULL )
+        islpci_put_queue(private_config->remapped_device_base,
+            &private_config->mgmt_rx_freeq, entry );
+}
+
+
+int islpci_mgt_mlme( unsigned long oid, char *received_data )
+{
+    struct obj_mlme *mlme = (struct obj_mlme *) received_data;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
+    DEBUG( SHOW_TRAPS, "mlme: oid %lx \n", oid );
+    DEBUG( SHOW_TRAPS, "mlme: address %02x:%02x:%02x:%02x:%02x:%02x\n",
+		mlme->address[0] & 0xFF, mlme->address[1] & 0xFF, mlme->address[2] & 0xFF, 
+		mlme->address[3] & 0xFF, mlme->address[4] & 0xFF, mlme->address[5] & 0xFF);
+    DEBUG( SHOW_TRAPS, "mlme: id %x, state %x, code %x \n", mlme->id, 
+		mlme->state, mlme->code );
+#endif
+	
+    switch( oid )
+    {
+        case DOT11_OID_AUTHENTICATE:
+            // check whether a station is authenticating
+            if( mlme->state == DOT11_STATE_AUTHING )
+            {
+                // STA is requesting to to be authenticated
+
+                // check the code of the object and handle it
+
+                // generate a response to the station
+                // positive: generate an Authenticate Confirm frame
+                // negative: generate a Deauthenicate Request frame
+            }
+            else
+            {
+                // notification that a STA has authenticated
+
+                // update the STA list to be maintained in the driver
+            }
+            break;
+
+        case DOT11_OID_DEAUTHENTICATE:
+            // read the STA address from the mlme object structure
+
+            // check the code of the object and handle it
+
+            // update the STA list to be maintained in the driver
+
+            break;
+
+        case DOT11_OID_ASSOCIATE:
+            // check whether a station is associating
+            if( mlme->state == DOT11_STATE_ASSOCING )
+            {
+                // STA is requesting to to be authenticated
+
+                // check the code of the object and handle it
+
+                // generate a response to the station
+                // positive: generate an Associate Confirm frame
+                // negative: generate a Disassociate Request frame
+            }
+            else
+            {
+                // notification that a STA has authenticated
+
+                // update the STA list to be maintained in the driver
+            }
+
+            break;
+
+
+        case DOT11_OID_DISASSOCIATE:
+            // read the STA address from the mlme object structure
+
+            // update the STA list to be maintained in the driver
+
+            break;
+
+		case DOT11_OID_BEACON:
+			// recevied a beacon indicate, do nothing
+#if VERBOSE > SHOW_ERROR_MESSAGES
+		    DEBUG( SHOW_TRAPS, "TRAP: Beacon Indicate\n" );
+#endif
+			break;
+			
+		case DOT11_OID_PROBE:
+			// recevied a probe indicate, do nothing
+#if VERBOSE > SHOW_ERROR_MESSAGES
+		    DEBUG( SHOW_TRAPS, "TRAP: Probe Indicate\n" );
+#endif
+			break;
+			
+        default:
+            // oid is not a TRAP from the MLME
+            return 0;
+    }
+
+    return 0;
+
+}
+
+/******************************************************************************
+        WDS Link Handlers
+******************************************************************************/
+
+#ifdef INTERSIL_EVENTS
+int islpci_mgt_indication( unsigned int dev_type, unsigned int dev_seq,
+                           unsigned int src_id, unsigned int src_seq,
+                           unsigned int op, unsigned int oid, void *data, unsigned long len)
+{
+    islpci_private *private_config;
+    struct net_device *dev;
+    char *datap;
+    unsigned long dlen;
+    queue_entry *entry = NULL;
+    int err = 0;
+    int operation;
+
+    if ( ! (dev = dev_get_by_index(dev_seq)) )
+        return -1;
+	dev_put( dev );
+	
+    private_config = dev->priv;
+    
+    islpci_mgt_queue(private_config, op, oid, 0, data, len, 0);
+    if ( ( err = islpci_mgt_response( private_config, oid, &operation, 
+    	(void **) &datap, &dlen, &entry ) ) < 0 ) {
+        islpci_mgt_release( private_config, entry );
+        printk("islpci_mgt_response returned %d\n", err );
+        return -1;
+    }
+
+    if ( dlen > len) {
+        dlen = len;
+    }
+    memcpy( data, datap, dlen );
+    
+    islpci_mgt_release( private_config, entry );
+
+    if ( (mgt_response( src_id, src_seq, dev_type, dev_seq, operation,
+    	 oid, data, dlen)) < 0)
+        return -1;
+
+    return 0;
+}
+#endif /* INTERSIL_EVENTS */
+
+#ifdef WDS_LINKS
+
+struct wds_link_msg {
+    unsigned char mac[6];
+    char name[32];
+} __attribute__ ((packed));
+
+int islpci_wdslink_add_hndl( unsigned int dev_type, unsigned int dev_seq,
+                             unsigned int src_id, unsigned int src_seq,
+                             unsigned int op, unsigned int oid, void *data, unsigned long len){
+    struct net_device *dev;
+    struct wds_link_msg *wlmp;
+    islpci_private *private_config;
+    char *datap;
+    unsigned long dlen;
+    queue_entry *entry = NULL;
+    int err = 0;
+    int operation;
+
+    if ( len != sizeof(struct wds_link_msg)) 
+        return -1;
+    
+    if ( ! (dev = dev_get_by_index(dev_seq)) )
+        return -1;
+	dev_put( dev );
+
+    private_config = dev->priv;
+
+    wlmp = (struct wds_link_msg *)data;
+    
+    printk ("islpci_wdslink_add_hndl(%x:%x:%x:%x:%x:%x)\n", wlmp->mac[0], 
+    	wlmp->mac[1], wlmp->mac[2], wlmp->mac[3], wlmp->mac[4], wlmp->mac[5] );
+    
+    if ( add_wds_link(dev, private_config->wdsp, wlmp->mac, wlmp->name) < 0 ) {
+        printk("islpci_wdslink_add_hndl:add_wds_link\n");
+    }
+    
+    islpci_mgt_queue(private_config, op, oid, 0, wlmp->mac, 6, 0);
+    if ( ( err = islpci_mgt_response( private_config, oid, &operation, 
+    	(void **) &datap, &dlen, &entry ) ) < 0 ) {
+        printk("islpci_mgt_response returned %d\n", err );
+    }
+
+    islpci_mgt_release( private_config, entry );
+    
+    if ( (mgt_response( src_id, src_seq, dev_type, dev_seq, operation, 
+    	oid, data, len)) < 0)
+        return -1;
+
+    return 0;
+}
+
+int islpci_wdslink_del_hndl( unsigned int dev_type, unsigned int dev_seq,
+                             unsigned int src_id, unsigned int src_seq,
+                             unsigned int op, unsigned int oid, void *data, unsigned long len)
+{
+    struct net_device *dev;
+    struct wds_link_msg *wlmp;
+    islpci_private *private_config;
+    char *datap;
+    unsigned long dlen;
+    queue_entry *entry = NULL;
+    int err = 0;
+    int operation;
+
+    if ( len != sizeof(struct wds_link_msg)) 
+        return -1;
+    
+    if ( ! (dev = dev_get_by_index(dev_seq)) )
+        return -1;
+	dev_put( dev );
+
+    private_config = dev->priv;
+
+    wlmp = (struct wds_link_msg *)data;
+    
+    printk ("islpci_wdslink_del_hndl(%x:%x:%x:%x:%x:%x)\n", wlmp->mac[0], 
+    	wlmp->mac[1], wlmp->mac[2], wlmp->mac[3], wlmp->mac[4], wlmp->mac[5] );
+    
+    if ( del_wds_link(dev, private_config->wdsp, wlmp->mac, wlmp->name ) < 0 ) {
+        printk("islpci_wdslink_del_hndl:del_wds_link\n");
+    }
+    
+    islpci_mgt_queue(private_config, op, oid, 0, wlmp->mac, 6, 0);
+    if ( ( err = islpci_mgt_response( private_config, oid, &operation, 
+    	(void **) &datap, &dlen, &entry ) ) < 0 ) {
+        printk("islpci_mgt_response returned %d\n", err );
+    }
+
+    islpci_mgt_release( private_config, entry );
+    
+    if ( (mgt_response( src_id, src_seq, dev_type, dev_seq, operation, 
+    	oid, data, len)) < 0)
+        return -1;
+
+    return 0;
+}
+#endif /* WDS_LINKS */
+
+#ifdef INTERSIL_EVENTS
+
+#define PDR_END              0x0000
+#define PDR_INTERFACE_LIST   0x1001
+
+struct pdr_struct {
+   unsigned short   length;
+   unsigned short   code;
+   unsigned char    data[2];
+} __attribute__ ((packed));
+
+static struct pdr_struct *pda_find_pdr (unsigned char *pda, unsigned short code )
+{
+   unsigned short     offset = 0;
+   struct pdr_struct *pdr;
+   
+   pdr = (struct pdr_struct *) pda;
+   
+   while (pdr->code != PDR_END) {
+      if (pdr->code == code) {
+         return pdr;
+      } else {
+         offset = pdr->length + 1;
+         /* invalid PDA: past 8k or invalid PdrLength */
+         if ((offset > 8192) || (pdr->length == 65535) || (pdr->length == 0)) {
+             return (struct pdr_struct *)0;
+         }
+         pdr = (struct pdr_struct *)pda;
+      }
+   }
+
+   if (code == PDR_END) {
+       return pdr;
+   } else {
+     return (struct pdr_struct *)0;
+   }
+}
+
+/* mgt_indication_handler ( DEV_NETWORK, dev->name, BLOB_OID_EXT_INTERFACE_LIST, islpci_interface_list_hndl ); */
+
+int islpci_interface_list_hndl( unsigned int dev_type, unsigned int dev_seq,
+                                unsigned int src_id, unsigned int src_seq,
+                                unsigned int op, unsigned int oid, void *data, unsigned long len)
+{
+    struct net_device *dev;
+    islpci_private *private_config;
+    unsigned char *datap;
+    unsigned long dlen;
+    queue_entry *entry = NULL;
+    struct pdr_struct *pdr;
+    int err = 0;
+    int operation;
+printk("Find dev_get_by_index(%d)\n", dev_seq);
+    if ( ! (dev = dev_get_by_index(dev_seq)) )
+        return -1;
+	dev_put( dev );
+
+    private_config = dev->priv;
+
+    printk ("islpci_pda_hndl()\n" );
+    
+    islpci_mgt_queue(private_config, PIMFOR_OP_GET, BLOB_OID_NVDATA, 0, 0, 0, 0);
+    if ( ( err = islpci_mgt_response( private_config, oid, &operation, 
+    	(void **) &datap, &dlen, &entry ) ) < 0 ) {
+        printk("islpci_mgt_response returned %d\n", err );
+    }
+    
+    if ( ( pdr = pda_find_pdr( datap, PDR_INTERFACE_LIST ) ) && ( pdr->length <= len ) ) {
+        memcpy( data, pdr->data, pdr->length );
+    } else {
+        memset( data, 0, len );
+    }
+
+    islpci_mgt_release( private_config, entry );
+    
+    if ( (mgt_response( src_id, src_seq, dev_type, dev_seq, operation,
+    	oid, data, len)) < 0)
+        return -1;
+
+    return 0;
+}
+
+#endif
diff -urN linux-2.4.29/drivers/net/intersil/islpci_mgt.h linux-2.4.29-uc1/drivers/net/intersil/islpci_mgt.h
--- linux-2.4.29/drivers/net/intersil/islpci_mgt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islpci_mgt.h	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,133 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef _ISLPCI_MGT_H
+#define _ISLPCI_MGT_H
+
+#include "islpci_dev.h"
+
+
+// Default card definitions
+#define CARD_DEFAULT_SSID                       "uAP"
+#define CARD_DEFAULT_SSIDOVERRIDE               "uAP"
+#define CARD_DEFAULT_CHANNEL                    4
+#define CARD_DEFAULT_MODE                       INL_MODE_AP
+#define CARD_DEFAULT_BSSTYPE                    DOT11_BSSTYPE_INFRA
+#define CARD_DEFAULT_KEY1                       "default_key_1"
+#define CARD_DEFAULT_KEY2                       "default_key_2"
+#define CARD_DEFAULT_KEY3                       "default_key_3"
+#define CARD_DEFAULT_KEY4                       "default_key_4"
+#define CARD_DEFAULT_WEP                        0
+#define CARD_DEFAULT_FILTER                     0
+#ifdef WDS_LINKS
+#define CARD_DEFAULT_WDS                        1
+#else
+#define CARD_DEFAULT_WDS                        0
+#endif
+#define	CARD_DEFAULT_AUTHEN                     DOT11_AUTH_OS
+#define	CARD_DEFAULT_DOT1X			            0
+#define CARD_DEFAULT_MLME_MODE			        DOT11_MLME_AUTO
+
+// PIMFOR package definitions
+#define PIMFOR_ETHERTYPE                        0x8828
+#define PIMFOR_HEADER_SIZE                      12
+#define PIMFOR_VERSION                          1
+#define PIMFOR_OP_GET                           0
+#define PIMFOR_OP_SET                           1
+#define PIMFOR_OP_RESPONSE                      2
+#define PIMFOR_OP_ERROR                         3
+#define PIMFOR_OP_TRAP                          4
+#define PIMFOR_OP_RESERVED                      5       // till 255
+#define PIMFOR_DEV_ID_MHLI_MIB                  0
+#define PIMFOR_FLAG_APPLIC_ORIGIN               0x01
+#define PIMFOR_FLAG_LITTLE_ENDIAN               0x02
+
+// Driver specific oid definitions (NDIS driver)
+#define OID_INL_TUNNEL                          0xFF020000
+#define OID_INL_MEMADDR                         0xFF020001
+#define OID_INL_MEMORY                          0xFF020002
+#define OID_INL_MODE                            0xFF020003
+#define OID_INL_COMPONENT_NR                    0xFF020004
+#define OID_INL_VERSION                         0xFF020005
+#define OID_INL_INTERFACE_ID                    0xFF020006
+#define OID_INL_COMPONENT_ID                    0xFF020007
+#define OID_INL_CONFIG                          0xFF020008
+
+// Mode object definitions (OID_INL_MODE)
+#define INL_MODE_NONE                           -1
+#define INL_MODE_PROMISCUOUS                    0
+#define INL_MODE_CLIENT                         1
+#define INL_MODE_AP                             2
+#define INL_MODE_SNIFFER                        3
+
+// Config object definitions (OID_INL_CONFIG)
+#define INL_CONFIG_MANUALRUN                    0x01
+#define INL_CONFIG_FRAMETRAP                    0x02
+#define INL_CONFIG_RXANNEX                      0x04
+#define INL_CONFIG_TXANNEX                      0x08
+#define INL_CONFIG_WDS                          0x10
+
+
+/*
+ *  Type definition section
+ *
+ *  The PIMFOR package is defined using all unsigned bytes, because this makes
+ *  it easier to handle 32 bits words on the two different systems the structure
+ *  defines only the header allowing copyless frame handling
+ */
+typedef struct
+{
+    u8 version;
+    u8 operation;
+    u8 oid[4];                          // 32 bits word
+    u8 device_id;
+    u8 flags;
+    u8 length[4];                       // 32 bits word
+} pimfor_header;
+
+void pimfor_encode_header( int, unsigned long, int, int, int, pimfor_header * );
+void pimfor_decode_header( pimfor_header *, int *, unsigned long *, int *,
+    	    	    	    	int *, int * );
+
+void islpci_init_queue( queue_root * );
+int islpci_put_queue( void *, queue_root *, queue_entry * );
+int islpci_get_queue( void *, queue_root *, queue_entry ** );
+int islpci_queue_size( void *, queue_root * );
+
+void islpci_mgt_initialize( islpci_private * );
+int islpci_mgt_transmit( islpci_private * );
+int islpci_mgt_queue( islpci_private *, int, unsigned long, int, void *, int, int);
+int islpci_mgt_receive( islpci_private * );
+int islpci_mgt_response(islpci_private *, long, int *, void **, long *, queue_entry** );
+void islpci_mgt_release( islpci_private *, queue_entry * );
+
+int islpci_mgt_mlme( unsigned long, char * );
+
+#ifdef INTERSIL_EVENTS
+int islpci_mgt_indication( unsigned int, unsigned int, unsigned int, unsigned int,
+                           unsigned int, unsigned int, void *, unsigned long );
+#endif
+#ifdef WDS_LINKS
+int islpci_wdslink_add_hndl( unsigned int, unsigned int, unsigned int, unsigned,
+                             unsigned int, unsigned int, void *, unsigned long );
+int islpci_wdslink_del_hndl( unsigned int, unsigned int, unsigned int, unsigned,
+                             unsigned int, unsigned int, void *, unsigned long );
+#endif
+
+#endif  // _ISLPCI_MGT_H
diff -urN linux-2.4.29/drivers/net/intersil/islpci_pcmcia.c linux-2.4.29-uc1/drivers/net/intersil/islpci_pcmcia.c
--- linux-2.4.29/drivers/net/intersil/islpci_pcmcia.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islpci_pcmcia.c	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,329 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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 <linux/version.h>
+#ifdef MODULE
+#ifdef MODVERSIONS
+#include <linux/modversions.h>
+#endif
+#include <linux/module.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
+#include <linux/pci.h>
+#include <pcmcia/driver_ops.h>
+
+#include "version_info.h"
+#include "isl_gen.h"
+#include "isl_38xx.h"
+#include "islpci_pcmcia.h"
+#include "islpci_dev.h"
+
+#ifdef INTERSIL_EVENTS
+#include <bloboid.h>
+#include "isl_mgt.h"
+#include "islpci_mgt.h"
+#endif
+
+/******************************************************************************
+        Global variable definition section
+******************************************************************************/
+MODULE_AUTHOR("W.Termorshuizen, R.Bastings");
+MODULE_DESCRIPTION("Intersil 802.11 Wireless LAN adapter");
+MODULE_LICENSE("GPL");
+
+
+extern struct net_device *root_islpci_device;
+extern int pc_debug;
+
+struct driver_operations islpci_ops =
+{
+    DRIVER_NAME, islpci_attach, islpci_suspend, islpci_resume, islpci_detach
+};
+
+
+/******************************************************************************
+    Module initialization functions
+******************************************************************************/
+dev_node_t *islpci_attach(dev_locator_t * loc)
+{
+    u32 io;
+    u16 dev_id;
+    u8 bus, devfn, irq, latency_tmr;
+    struct pci_dev *pci_device;
+    struct net_device *nw_device;
+    dev_node_t *node;
+    islpci_private *private_config;
+    int rvalue;
+    int dma_mask = 0xffffffff;
+    char firmware[256];
+
+    // perform some initial setting checks
+    if (loc->bus != LOC_PCI)
+        return NULL;
+    bus = loc->b.pci.bus;
+    devfn = loc->b.pci.devfn;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_attach(bus %d, function %d)\n",
+        bus, devfn);
+#endif
+
+    // get some pci settings for verification
+    pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &io);
+    pcibios_read_config_byte(bus, devfn, PCI_INTERRUPT_LINE, &irq);
+    pcibios_read_config_word(bus, devfn, PCI_DEVICE_ID, &dev_id);
+
+	// check whether the latency timer is set correctly
+    pcibios_read_config_byte(bus, devfn, PCI_LATENCY_TIMER, &latency_tmr);
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+	DEBUG( SHOW_TRACING, "latency timer: %x\n", latency_tmr );
+#endif
+	if( latency_tmr < PCIDEVICE_LATENCY_TIMER_MIN )
+	{
+		// set the latency timer
+		pcibios_write_config_byte(bus, devfn, PCI_LATENCY_TIMER, 
+			PCIDEVICE_LATENCY_TIMER_VAL );
+	}
+
+    if (io &= ~3, io == 0 || irq == 0)
+    {
+        DEBUG(SHOW_ERROR_MESSAGES, "The ISL38XX Ethernet interface was not "
+        "assigned an %s.\n" KERN_ERR "  It will not be activated.\n",
+        io == 0 ? "I/O address" : "IRQ");
+        return NULL;
+    }
+    // get pci device information by loading the pci_dev structure
+    if (pci_device = pci_find_slot(bus, devfn), pci_device == NULL)
+    {
+        // error reading the pci device structure
+        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not get PCI device "
+            "information \n", DRIVER_NAME );
+        return NULL;
+    }
+
+    // determine what the supported DMA memory region is
+    while( pci_set_dma_mask( pci_device, dma_mask ) != 0 )
+    {
+        // range not supported, shift the mask and check again
+        if( dma_mask >>=  1, dma_mask == 0 )
+        {
+            // mask is zero, DMA memory not supported by PCI
+            DEBUG(SHOW_ERROR_MESSAGES, "DMA Memory not supported\n" );
+            return NULL;
+        }
+    }
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "DMA Memory support mask is 0x%x \n", dma_mask );
+#endif
+
+    // setup the network device interface and its structure
+    if (nw_device = islpci_probe(NULL, pci_device, (long) io, (int) irq),
+        nw_device == NULL)
+    {
+        // error configuring the driver as a network device
+        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not configure "
+        "network device \n", DRIVER_NAME );
+        return NULL;
+    }
+
+#ifdef WDS_LINKS
+    mgt_indication_handler ( DEV_NETWORK, nw_device->name, DOT11_OID_WDSLINKADD, islpci_wdslink_add_hndl );
+    mgt_indication_handler ( DEV_NETWORK, nw_device->name, DOT11_OID_WDSLINKREMOVE, islpci_wdslink_del_hndl );
+#endif
+
+    // save the interrupt request line and use the remapped device base address
+    // as the device identification both for uniqueness and parameter passing
+    // to the interrupt handler
+    private_config = nw_device->priv;
+    private_config->pci_irq = irq;
+    private_config->pci_dev_id = dev_id;
+    private_config->device_id = private_config->remapped_device_base;
+	spin_lock_init( &private_config->slock );
+
+    // request for the interrupt before uploading the firmware
+    if (rvalue = request_irq(irq, &islpci_interrupt, SA_INTERRUPT | SA_SHIRQ,
+        DRIVER_NAME, private_config), rvalue != 0)
+    {
+        // error, could not hook the handler to the irq
+        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not install "
+            "IRQ-handler \n", DRIVER_NAME );
+        return NULL;
+    }
+
+    // select the firmware file depending on the device id, take for default
+    // the 3877 firmware file
+    if( dev_id == PCIDEVICE_ISL3890 )
+    	strcpy( firmware, ISL3890_IMAGE_FILE );
+    else
+    	strcpy( firmware, ISL3877_IMAGE_FILE );
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_TRACING, "Device %x, firmware file: %s \n", dev_id, firmware );
+#endif
+	
+    if (isl38xx_upload_firmware( firmware, private_config->remapped_device_base,
+        private_config->device_host_address  ) == -1)
+    {
+        // error uploading the firmware
+        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not upload the "
+        "firmware \n", DRIVER_NAME );
+        return NULL;
+    }
+
+    // finally setup the node structure with the device information
+    node = kmalloc(sizeof(dev_node_t), GFP_KERNEL);
+    strcpy(node->dev_name, nw_device->name);
+    node->major = 0;
+    node->minor = 0;
+    node->next = NULL;
+    MOD_INC_USE_COUNT;
+    return node;
+}
+
+void islpci_suspend(dev_node_t * node)
+{
+    struct net_device **devp, **next;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_suspend(%s)\n", node->dev_name);
+#endif
+
+    for (devp = &root_islpci_device; *devp; devp = next)
+    {
+        next = &((islpci_private *) (*devp)->priv)->next_module;
+        if (strcmp((*devp)->name, node->dev_name) == 0)
+        break;
+    }
+
+    if (*devp)
+    {
+//        long ioaddr = (*devp)->base_addr;
+//        islpci_pause(*devp);
+    }
+}
+
+void islpci_resume(dev_node_t * node)
+{
+    struct net_device **devp, **next;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_resume(%s)\n", node->dev_name);
+#endif
+
+    for (devp = &root_islpci_device; *devp; devp = next)
+    {
+        next = &((islpci_private *) (*devp)->priv)->next_module;
+        if (strcmp((*devp)->name, node->dev_name) == 0)
+        break;
+    }
+
+    if (*devp)
+    {
+//        islpci_restart(*devp);
+    }
+}
+
+void islpci_detach(dev_node_t * node)
+{
+    struct net_device **devp, **next;
+    islpci_private *private_config;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+    DEBUG(SHOW_FUNCTION_CALLS, "islpci_detach(%s)\n", node->dev_name);
+#endif
+
+    for (devp = &root_islpci_device; *devp; devp = next)
+    {
+        next = &((islpci_private *) (*devp)->priv)->next_module;
+        if (strcmp((*devp)->name, node->dev_name) == 0)
+        break;
+    }
+
+    if (*devp)
+    {
+        // free the interrupt request
+        private_config = (*devp)->priv;
+        writel(0, private_config->remapped_device_base + ISL38XX_INT_EN_REG);
+        free_irq(private_config->pci_irq, private_config);
+
+        // free the node
+        kfree(node);
+        MOD_DEC_USE_COUNT;
+    }
+}
+
+int init_module(void)
+{
+    DEBUG(SHOW_ANYTHING, "Loaded %s, version %s\n", DRIVER_NAME, VERSIONID );
+
+#ifdef INTERSIL_EVENTS
+    mgt_initialize();
+#endif
+    
+    register_driver(&islpci_ops);
+    
+#ifdef INTERSIL_EVENTS
+    mgt_indication_handler ( DEV_NETWORK, 0, 0, islpci_mgt_indication );
+#endif
+    
+    return 0;
+}
+
+void cleanup_module(void)
+{
+    struct net_device *next_dev;
+    islpci_private *private_config;
+
+#ifdef INTERSIL_EVENTS
+    mgt_cleanup();
+#endif
+    
+    unregister_driver(&islpci_ops);
+
+    /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+    while (root_islpci_device)
+    {
+        private_config = (islpci_private *) root_islpci_device->priv;
+        next_dev = private_config->next_module;
+
+#if VERBOSE > SHOW_ERROR_MESSAGES 
+        DEBUG(SHOW_TRACING, "Cleanup netdevice \n");
+#endif
+
+        // unregister the network device
+        unregister_netdev(root_islpci_device);
+
+        // free the PCI memory and unmap the remapped page
+        islpci_free_memory( private_config, ALLOC_MEMORY_MODE );
+        iounmap(private_config->remapped_device_base);
+
+        // free the separately allocated areas
+        kfree(private_config);
+        kfree(root_islpci_device);
+
+        // change the root device pointer to the next device for clearing
+        root_islpci_device = next_dev;
+    }
+    
+    DEBUG(SHOW_ANYTHING, "Unloaded %s\n", DRIVER_NAME );
+}
diff -urN linux-2.4.29/drivers/net/intersil/islpci_pcmcia.h linux-2.4.29-uc1/drivers/net/intersil/islpci_pcmcia.h
--- linux-2.4.29/drivers/net/intersil/islpci_pcmcia.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/islpci_pcmcia.h	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,40 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef _ISLPCI_PCMCIA_H
+#define _ISLPCI_PCMCIA_H
+
+
+#ifndef DRIVER_NAME
+#define DRIVER_NAME             "islpci_cb"
+#endif
+
+#define ISL3877_IMAGE_FILE      "/etc/pcmcia/isl3877.arm"
+#define ISL3890_IMAGE_FILE  	"/etc/pcmcia/isl3890.arm"
+
+
+dev_node_t *islpci_attach( dev_locator_t * );
+void islpci_suspend( dev_node_t * );
+void islpci_resume( dev_node_t * );
+void islpci_detach( dev_node_t * );
+int init_module( void );
+void cleanup_module( void );
+
+
+#endif  // _ISLPCI_PCMCIA_H
diff -urN linux-2.4.29/drivers/net/intersil/isl_wds.c linux-2.4.29-uc1/drivers/net/intersil/isl_wds.c
--- linux-2.4.29/drivers/net/intersil/isl_wds.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/isl_wds.c	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1,578 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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 <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/rtnetlink.h>
+#include <linux/isil_netlink.h>
+#include <linux/netdevice.h>
+
+#include "isl_wds.h"
+
+#define DEBUG(x,args...)
+#define _DEBUG(x, args...)
+
+
+/* End of include files */
+
+/****************************************************************
+ *								*
+ *    			Begin of WDS functions			*
+ *								*
+ ***************************************************************/
+
+
+/**********************************************************************
+ *  add_wds_link
+ *
+ *  DESCRIPTION: Add a WDSlink device to the system.
+ * 		  On adding a WDSLINK to the MVC the following should be done:
+ * 		  - Add a new device to the WDSlink devices list.
+ * 		  - Create a device for this WDSlink (dev_alloc wds%d)
+ * 		  - Register the just created dummy device (register_netdevice)
+ *               - Bring the just created device up and running by calling dev_open.
+ * 		  - Somehow the brigde needs to be told to accept the new interface.
+ *
+ *  PARAMETERS:  - MACAddress, MACAddress to add.
+ *               - dev points to device WDSLink need to be added to.
+ *
+ *
+ *  RETURN:	  0 if the device created OK, otherwise -1.
+ *
+ **********************************************************************/
+int add_wds_link(struct net_device *dev, struct wds_priv *wdsp, unsigned char *mac_addr, char *brifname )
+{  
+    int err = 0;
+    int i=0, j=0;
+
+    struct net_device *wds_dev;
+
+    DEBUG(DBG_FUNC_CALL | DBG_WDS, "add_wds_link \n");
+    
+    if ( ( dev == NULL ) || ( wdsp == NULL ) || ( mac_addr == NULL ) || ( brifname == NULL ) )
+    {
+        printk("add_wds_link(%lx, %lx, %lx, %lx) wrong parameter(s)!\n", 
+               (unsigned long)dev, (unsigned long)wdsp, (unsigned long)mac_addr, (unsigned long)brifname );
+        return -1;
+    }
+    /* If the parent device isn't bridged, the WDS will not work */
+    if (dev->br_port == NULL)
+    {
+        printk("add_wds_link: parent device (%s) not bridged; can't add WDS link\n", dev->name );
+        return -2;
+    }
+    /* First check if MAX_WDS_LINKS is reached */
+    if (wdsp->current_nof_wds_links == MAX_WDS_LINKS)
+    {
+    	/* Max number of links reached */
+    	printk( "add_wds_link: max number of WDS links (%d) reached!\n", MAX_WDS_LINKS );
+    	return -3;
+    }
+
+    /* If this MAC address is our own mac address */
+    if(memcmp(dev->dev_addr, mac_addr, 6) == 0)
+    {
+        DEBUG(DBG_WDS | DBG_ERROR,"add_wds_link: Cannot add WDS link for own MAC address: %2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x\n",
+                  mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
+        return -4;
+    }
+    
+    /* Check if this MAC addres is already in the list. */
+    for (i=0 ; i < MAX_WDS_LINKS; i++)
+    {   
+    	if (((struct wds_net_local*)(wdsp->wds_dev[i])) == NULL)
+            continue;
+        
+        /* If this MAC address is already linked don't add new WDS device */
+        if(memcmp(((struct wds_net_local*)(wdsp->wds_dev[i]->priv))->wds_mac, mac_addr, 6) == 0)
+    	{
+    	    DEBUG(DBG_WDS | DBG_ERROR,"add_wds_link: WDS link for MAC: %2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x already active!\n",
+    		      mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
+    	    return -5;
+    	}
+    }
+
+    /* Find an empty field to add WDS device */
+    for (i=0 ; i< MAX_WDS_LINKS; i++)
+    {
+    	if (wdsp->wds_dev[i] == NULL)
+    	{
+    	    /* We have found an empty structure
+    	     * So we can actualy create a new device for this link
+    	     */
+            sprintf( brifname, "%s_%d", dev->name, i ); 
+    	    if ( !(wdsp->wds_dev[i] = dev_alloc(brifname, &err) ) )
+    	    {
+                DEBUG(DBG_WDS | DBG_ERROR,"add_wds_link: dev_alloc() for WDS failed!\n");
+    	        return -6;
+    	    }
+    	    /* Get a pointer to this WDS device */
+    	    wds_dev = wdsp->wds_dev[i];
+    
+    	    /* May be overridden by piggyback drivers */
+    	    ether_setup(wds_dev);
+    
+    	    /* Initialize the device priv structure. */
+            wds_dev->priv = kmalloc(sizeof(struct wds_net_local), GFP_KERNEL);
+            if (wds_dev->priv == NULL) {
+                return -7;
+            }
+            memset(wds_dev->priv, 0, sizeof(struct wds_net_local));
+    	    /* Set the parent device for this WDS link */
+    	    ((struct wds_net_local*)(wds_dev->priv))->parent_dev = dev;
+            
+    	    /* Set WDS MAC in priv structure */
+    	    printk("add_wds_link: wds_mac=");
+    	    for (j = 0; j < 6; j++)
+                printk(" %2.2x", ((struct wds_net_local*)(wds_dev->priv))->wds_mac[j] = mac_addr[j] );
+    	    printk("\n");
+    
+    	    /* Retrieve and print the ethernet address. */
+    	    printk(" eth_mac=");
+    	    for (j = 0; j < 6; j++)
+                printk(" %2.2x", wds_dev->dev_addr[j] = ((struct wds_net_local*)(wds_dev->priv))->parent_dev->dev_addr[j] );
+    	    printk("\n");
+
+    	    wds_dev->addr_len = 6;
+    
+    	    /* Override the network functions we need to use */
+    	    wds_dev->open		        = wds_net_open;
+    	    wds_dev->stop		        = wds_net_close;
+    	    wds_dev->get_stats		    = wds_net_get_stats;
+    	    wds_dev->hard_start_xmit	= wds_net_send_packet;
+    	    wds_dev->do_ioctl		    = wds_net_ioctl;
+    
+    	    /* Make ifconfig display some details */
+    	    wds_dev->base_addr = 0;
+    
+    	    /* No need to lock cause the net_ioctl is already locked */
+    	    err = register_netdevice(wds_dev);
+    	    if (err)
+    	    {
+        		DEBUG(DBG_WDS | DBG_ERROR,"add_wds_link: register_netdev() for WDS failed!\n");
+        		return -8;
+    	    }
+    	    DEBUG(DBG_WDS, "add_wds_link: registered device name: %s\n", wds_dev->name);
+    
+    	    /* Bring the device up, when the root device is UP... */
+    	    if (dev->flags & IFF_UP)
+    	    {
+        		err = dev_open(wds_dev);
+        		if (err)
+        		{
+        		    DEBUG(DBG_WDS | DBG_ERROR,"add_wds_link: dev_open() for WDS failed!\n");
+        		    return -9;
+        		}
+        		DEBUG(DBG_WDS,"add_wds_link: bringing up device name: %s\n", wds_dev->name);
+    	    }
+    	    else
+    	    {
+                DEBUG(DBG_WDS,"add_wds_link: NOT bringing up device name: %s, cause root device isn't up yet...\n", wds_dev->name);
+    	    }
+
+    	    wdsp->current_nof_wds_links++;
+    	    return 0;
+    	}
+    }
+    /* This should not happen*/
+    DEBUG(DBG_WDS | DBG_ERROR,"add_wds_link: WDS link administration screwed\n");
+    return -13;
+}
+
+/**********************************************************************
+ *  del_wds_link
+ *
+ *  DESCRIPTION: Del a WDSlink device to the system.
+ * 		On deleting a WDSLINK from the MVC the following should be done:
+ *      - Bring the device down by calling dev_close.
+ * 		- Unregister the asociated dummy device (unregister_netdevice)
+ * 		- Free the allocated space for this device
+ * 		- Remove this device from the WDSlink devices list.
+ *
+ *  PARAMETERS:	 - mac_addr, mac_addr to remove.
+ *               - dev points to device WDSLink need to be removed from.
+ *
+ *
+ *  RETURN:	 0 if the device created OK, otherwise 1.
+ *
+ **********************************************************************/
+int del_wds_link(struct net_device *dev, struct wds_priv *wdsp, unsigned char *mac_addr, char *brifname )
+{
+    int err = 0;
+    int i = 0;
+
+    struct net_device *wds_dev;
+
+    DEBUG(DBG_FUNC_CALL, "del_wds_link \n");
+    
+    if ( ( dev == NULL ) || ( wdsp == NULL ) || ( mac_addr == NULL ) || ( brifname == NULL ) )
+    {
+        printk("del_wds_link(%lx, %lx, %lx, %lx) wrong parameter(s)!\n", 
+               (unsigned long)dev, (unsigned long)wdsp, (unsigned long)mac_addr, (unsigned long)brifname );
+        return -1;
+    }
+    
+    /* Check if this MAC addres is in the WDS link list. */
+    for (i=0 ; i< MAX_WDS_LINKS; i++)
+    {
+    	if( (wdsp->wds_dev[i]) && 
+            (memcmp(((struct wds_net_local*)(wdsp->wds_dev[i]->priv))->wds_mac, mac_addr, 6 ) == 0 ) )
+    	{
+            wds_dev = (struct net_device *)wdsp->wds_dev[i];
+            strcpy( brifname, wds_dev->name ); 
+            
+            /* Bring the device down */
+    	    err = dev_close(wds_dev);
+    	    if (err)
+    	    {
+    	    	DEBUG(DBG_WDS | DBG_ERROR,"del_wds_link: dev_close() for WDS failed!\n");
+    	    	return err;
+    	    }
+    	    /* No need to lock cause the net_ioctl is already locked */
+    	    
+            err = unregister_netdevice(wds_dev);
+    	    if (err != 0)
+    	    {
+        		DEBUG(DBG_WDS | DBG_ERROR,"del_wds_link: MAC: %2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x could not be unregistered!\n",
+        			mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
+        		return err;
+    	    }
+            
+    	    kfree(wds_dev->priv);
+    	    kfree(wds_dev);
+    	    wdsp->current_nof_wds_links--;
+    	    wdsp->wds_dev[i] = NULL;
+    
+    	    DEBUG(DBG_WDS, "del_wds_link: WDSLink removed succesfully\n");
+    	    return err;
+    	}
+    }
+    DEBUG(DBG_WDS | DBG_ERROR,"del_wds_link: MAC: %2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x is not a WDS link\n",
+	      mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
+    return -1;
+}
+
+/**********************************************************************
+ *  open_wds_links
+ *
+ *  DESCRIPTION: Brings all associated WDS devices up and running.
+ *
+ *  PARAMETERS:	 dev points to device WDS links are put under.
+ *
+ *  RETURN:	 Nothing.
+ *
+ **********************************************************************/
+int open_wds_links(struct wds_priv *wdsp)
+{
+    int i;
+    
+    DEBUG(DBG_FUNC_CALL, "open_wds_links \n");
+    
+    if ( wdsp == NULL ) {
+        printk ("open_wds_links: no resources");
+        return -1;
+    }
+    
+    /* Bring the associated WDS devices up and RUNNING. */
+    DEBUG(DBG_WDS, "Open all associated WDS links: ");
+    
+    for (i = 0; i < MAX_WDS_LINKS; i++) 
+    {   
+        if (wdsp->wds_dev[i] == NULL)
+            continue;
+        DEBUG(DBG_WDS, "WDS%d...",i);
+        dev_open(wdsp->wds_dev[i]);
+    }
+    DEBUG(DBG_WDS, "\n");              
+    return 0;
+}
+
+/**********************************************************************
+ *  close_wds_links
+ *
+ *  DESCRIPTION: Closes all associated WDS links for the device.
+ *
+ *  PARAMETERS:	 dev points to device WDS links are put under.
+ *
+ *  RETURN:	 Nothing.
+ *
+ **********************************************************************/
+int close_wds_links(struct wds_priv *wdsp)
+{   
+    int i;
+
+    DEBUG(DBG_FUNC_CALL, "close_wds_links \n");
+    
+    if ( wdsp == NULL ) {
+        printk ("close_wds_links: no resources");
+        return -1;
+    }
+
+    DEBUG(DBG_WDS, "Close associated WDS links: ");
+    for (i = 0; i < MAX_WDS_LINKS; i++) 
+    {
+        if (wdsp->wds_dev[i] == NULL)
+            continue;
+        DEBUG(DBG_WDS, "WDS%d...",i);
+        dev_close(wdsp->wds_dev[i]);
+    }
+    DEBUG(DBG_WDS, "\n");
+    return 0;
+}
+
+
+/**********************************************************************
+ *  check_skb_for_wds
+ *
+ *  DESCRIPTION: Checks the skb->cb field for the WDS Link magic.
+ *               It copies the MAC address into WDS_MAC.
+ *
+ *  PARAMETERS:	 pointer to sk_buff skb.
+ *               WDS_Mac, is updated with the found WDS Link MAC address. 
+ *
+ *  RETURN:	 Return 1 if a WDS link is found, 0 otherwise
+ *
+ *  NOTE:        inline fucntion.
+ *
+ **********************************************************************/
+inline int check_skb_for_wds(struct sk_buff *skb, unsigned char *wds_mac)
+{
+    /* If this skb came from a WDS device, the
+     * skb->cb field will be filled with a WDSLink mac_addr.
+     * Due to the reason the cb field is free to use, the MAC address
+     * will be packed in the following keys "WDSL"<MAC ADDRESS>".
+     */
+
+    if(*(long*)&skb->cb[0] == cpu_to_le32(0x4c534457)) /* WDSL */
+    {
+        memcpy(wds_mac, skb->cb+4, 6);       
+#if (NET_DEBUG & DBG_WDS)
+    	printk("net_send_packet: found wdsmac in skb: %2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x \n",
+    		wds_mac[0],wds_mac[1],wds_mac[2],wds_mac[3],wds_mac[4],wds_mac[5]);
+#endif
+        /* Make the WDS data invalid */
+        *(long*)&skb->cb[0] = 0;
+
+        return(1); //WDS Link is available */
+    }                                        
+    return(0); /* WDS Link is unavailable */ 
+}
+
+
+/**********************************************************************
+ *  wds_find_device
+ *
+ *  DESCRIPTION: Find the WDS device to use for receiving this data
+ *
+ *  PARAMETERS:	 unsigned char        *wds_mac - Pointer to the WDS MAC address
+ *  		 struct net_device    *dev    - The device the skb was
+ *                                              received on.
+ *
+ *  RETURN:	 *net_dev of the device found, otherwise NULL.
+ *
+ **********************************************************************/
+
+struct net_device *wds_find_device( unsigned char *wds_mac, struct wds_priv *wdsp )
+{
+    int i=0;
+
+    _DEBUG(DBG_FUNC_CALL | DBG_WDS | DBG_IRQ, "wds_find_device\n");
+    if ( wdsp == NULL ) {
+    	DEBUG(DBG_WDS, "wds_find_device: wds_priv not found, returning NULL\n");
+        return NULL;
+    }
+
+    if (wds_mac[0] == 0 && wds_mac[1] == 0 && 
+    	wds_mac[2] == 0 && wds_mac[3] == 0 &&
+    	wds_mac[4] == 0 && wds_mac[5] == 0)
+    {
+    	_DEBUG(DBG_WDS | DBG_IRQ, "wds_find_device: wds_mac no MAC found, returning NULL\n");
+    	return NULL;
+    }
+    for (i=0; i < MAX_WDS_LINKS; i++)
+    {
+    	if (wdsp->wds_dev[i] == NULL)
+    	    continue;
+            if(memcmp(((struct wds_net_local*)(wdsp->wds_dev[i]->priv))->wds_mac, wds_mac, 6) == 0)
+    	{
+    	    _DEBUG(DBG_WDS | DBG_IRQ, "wds_find_device: wds_mac MAC found, returning dev->name: %s\n",
+    	    	   wdsp->wds_dev[i]->name);
+    	    return ((struct net_device*)wdsp->wds_dev[i]);
+    	}
+    }
+    _DEBUG(DBG_WDS | DBG_IRQ, "wds_find_device: WDS from mac %2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x not in current config, returning NULL\n",
+    	   wds_mac[0],wds_mac[1],wds_mac[2],wds_mac[3],wds_mac[4],wds_mac[5]);
+
+    return NULL;
+}
+
+
+/**********************************************************************
+ *  wds_net_open
+ *
+ *  DESCRIPTION: Bring the WDS dev up and running.
+ * 		 The WDS device needs to be added to the bridge,
+ * 		 where the parent dev is also bridged.
+ *
+ *  PARAMETERS:	 struct net_device    *dev    - The WDS device
+ *
+ *  RETURN:	 zero on succes, otherwise error (<0).
+ *
+ **********************************************************************/
+int wds_net_open(struct net_device *dev)
+{
+    struct wds_net_local *wnlp = (struct wds_net_local *)dev->priv;
+    int err = 0;
+    
+    DEBUG(DBG_FUNC_CALL | DBG_WDS, "wds_net_open \n");
+    
+    netif_start_queue(dev);
+
+    /* Check if the parent device is bridged */
+    if (wnlp->parent_dev->br_port == NULL)
+    {
+	DEBUG(DBG_WDS | DBG_ERROR, "wds_net_open: Error parent device (%s) is not bridged, can't add WDS link.\n",lp->parent_dev->name);
+        return -1;
+    }
+
+    return err;
+}
+
+/**********************************************************************
+ *  wds_net_send_packet
+ *
+ *  DESCRIPTION: Sends a WDS packet via the WDS' parent device.
+ *               This function puts the WDS mac_addr in the skb->cb
+ *               private field, alters the device to send from into the
+ *               parent device for this WDS link and puts the skb into
+ *               the transmit device queue.
+ *
+ *  PARAMETERS:	 struct sk_buff    *skb -  skbuff to send.
+ *               struct net_device *dev -  wds device. 
+ *
+ *  RETURN:	 zero.
+ *
+ **********************************************************************/
+int wds_net_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+    struct wds_net_local *wnl = (struct wds_net_local *)dev->priv;
+
+    _DEBUG(DBG_FUNC_CALL | DBG_WDS, "wds_net_send_packet\n");
+    
+    if (wnl == NULL)
+    {
+    	printk("wds_net_send_packet: NULL pointer detected\n");
+    	return 0;
+    }
+    if ((wnl->parent_dev->flags & IFF_UP) && (dev->flags & IFF_UP))
+    {
+        /* OK lets copy the WDSlink MACAddres in the skb->cb fields */
+        memcpy(skb->cb, "WDSL", 4);
+        memcpy(skb->cb+4, ((struct wds_net_local*)(dev->priv))->wds_mac, dev->addr_len);
+
+        /* Set the "transmit" dev in this skb */
+        skb->dev = wnl->parent_dev;
+
+        /* Move this skb to the "transmit" devices queue */
+        if(dev_queue_xmit(skb) < 0)
+        {
+            printk("wds_net_send_packet: dev_queue_xmit failed\n");
+        }
+        /* Update stats for this device */
+        wnl->stats.tx_packets++;
+        wnl->stats.tx_bytes += skb->len;
+    }
+    return 0;
+}
+
+/**********************************************************************
+ *  wds_net_close
+ *
+ *  DESCRIPTION: Deletes the WDS device from the bridge.
+ *
+ *  PARAMETERS:	 struct net_device *dev - WDS device to remove.
+ *
+ *  RETURN:	 0 on success and -1 when parent device isn't bridged.
+ *
+ **********************************************************************/
+int wds_net_close(struct net_device *dev)
+{
+    int err = 0;
+    struct wds_net_local *lp = (struct wds_net_local *)dev->priv;
+
+    DEBUG(DBG_FUNC_CALL | DBG_WDS, "wds_net_close \n");
+    
+    netif_stop_queue(dev);
+
+    /* Check if the parent device is bridged */
+    if (lp->parent_dev->br_port == NULL)
+    {
+	DEBUG(DBG_WDS | DBG_ERROR, "wds_net_close: Error parent device (%s) is not bridged, can't close WDS link.\n",lp->parent_dev->name);
+        return -1;
+    }
+
+    return err;
+}
+
+
+/**********************************************************************
+ *  wds_net_get_stats
+ *
+ *  DESCRIPTION: Gets the statistics for the WDS device. 
+ *
+ *  PARAMETERS:	 struct net_device *dev - WDS device to get statistics from.
+ *
+ *  RETURN:	 pointer to net_device_stats struct.
+ *
+ **********************************************************************/
+struct net_device_stats* wds_net_get_stats(struct net_device *dev)
+{
+    struct wds_net_local *lp = (struct wds_net_local *)dev->priv;
+    struct net_device_stats *stats = &lp->stats;
+
+    _DEBUG(DBG_FUNC_CALL | DBG_WDS, "wds_net_get_stats \n");
+
+    return stats;
+}
+
+/**********************************************************************
+ *  wds_net_ioctl
+ *
+ *  DESCRIPTION: Ioctl for WDS devices are NOT supported. Tell them.
+ *
+ *  PARAMETERS:	 struct net_device *dev -
+ *               struct ifreq      *ifr -
+ *               int    cmd             -
+ *
+ *  RETURN:	 -EINVAL. 
+ *
+ **********************************************************************/
+int wds_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+    printk("wds_net_ioctl: Ioctls for WDS devices are NOT supported in this driver.\n");
+    return -EINVAL;
+}
+
+
+/***************************************************************
+*								*
+*    			End of WDS functions			*
+*								*
+***************************************************************/
+
diff -urN linux-2.4.29/drivers/net/intersil/isl_wds.h linux-2.4.29-uc1/drivers/net/intersil/isl_wds.h
--- linux-2.4.29/drivers/net/intersil/isl_wds.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/isl_wds.h	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,56 @@
+/*  $Header$
+ *  
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef _ISL_WDS_H
+#define _ISL_WDS_H
+
+#include <linux/netdevice.h>
+
+#ifndef MAX_WDS_LINKS
+#define MAX_WDS_LINKS         8
+#endif
+
+struct wds_priv
+{
+    struct net_device  *wds_dev[MAX_WDS_LINKS];
+    unsigned int 	    current_nof_wds_links;
+};
+
+struct wds_net_local
+{
+    struct net_device_stats	 stats;		/* tx/rx statistics */
+    struct net_device 	    *parent_dev;
+    unsigned char 		     wds_mac[6];
+};
+
+/* WDS */
+int add_wds_link(struct net_device *dev, struct wds_priv *wdsp, unsigned char *mac_addr, char *brifname );
+int del_wds_link(struct net_device *dev, struct wds_priv *wdsp, unsigned char *mac_addr, char *brifname );
+int open_wds_links(struct wds_priv *wdsp);
+int close_wds_links(struct wds_priv *wdsp);
+struct net_device *wds_find_device( unsigned char *wds_mac, struct wds_priv *wdsp );
+inline int check_skb_for_wds(struct sk_buff *skb, unsigned char *mac);
+int wds_net_open(struct net_device *dev);
+int wds_net_send_packet(struct sk_buff *skb, struct net_device *dev);
+int wds_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
+struct net_device_stats *wds_net_get_stats(struct net_device *dev);
+int wds_net_close(struct net_device *dev);
+
+#endif /* _ISL_WDS_H */
+
diff -urN linux-2.4.29/drivers/net/intersil/Makefile linux-2.4.29-uc1/drivers/net/intersil/Makefile
--- linux-2.4.29/drivers/net/intersil/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/Makefile	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,21 @@
+obj-y           :=
+obj-m           :=
+obj-n           :=
+obj-            :=
+
+mod-subdirs     := 
+
+O_TARGET := islmvc.o
+
+export-objs     :=  isl_mgt.o islmvc_mgt.o 
+list-multi	:=	
+rcpci-objs	:=	
+
+obj-$(CONFIG_ISIL_MVCDRIVER) += isl_mgt.o isl_wds.o islmvc_mgt.o islmvc_dev.o islmvc_blob.o
+obj-$(CONFIG_ISIL_UAP) += isl_gen.o islpci_hotplug.o islpci_dev.o islpci_eth.o islpci_mgt.o isl_38xx.o
+
+include $(TOPDIR)/Rules.make
+
+clean:
+	rm -f core *.o *.a *.s
+
diff -urN linux-2.4.29/drivers/net/intersil/Makefile.uap linux-2.4.29-uc1/drivers/net/intersil/Makefile.uap
--- linux-2.4.29/drivers/net/intersil/Makefile.uap	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/Makefile.uap	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,72 @@
+include ../../config.mk
+
+# For some reason keep your hands of "-O3"
+CFLAGS = -O3 -Wall -Wstrict-prototypes -pipe
+CPPFLAGS += $(PCDEBUG) -D__KERNEL__ -DMODULE 
+CPPFLAGS += -DBLOB_V2 -I . -I../../include/intersil
+CC = $(KCC) $(AFLAGS) $(KFLAGS)
+
+OBJECTS = isl_gen.o isl_38xx.o islpci_dev.o islpci_eth.o islpci_mgt.o 
+SRCS    = isl_gen.c isl_38xx.c islpci_dev.c islpci_eth.c islpci_mgt.c 
+
+ifdef CONFIG_CARDBUS
+SRCS    += islpci_pcmcia.c 
+OBJECTS += islpci_pcmcia.o 
+else
+SRCS    += islpci_hotplug.c 
+OBJECTS += islpci_hotplug.o 
+endif
+
+ifdef WIRELESS_IOCTLS
+SRCS    += isl_ioctl.c 
+OBJECTS += isl_ioctl.o 
+endif
+
+ifdef WIRELESS_EVENTS
+endif
+
+ifdef INTERSIL_EVENTS
+SRCS    += isl_mgt.c 
+OBJECTS += isl_mgt.o 
+endif
+ifdef WDS_LINKS
+SRCS    += isl_wds.c 
+OBJECTS += isl_wds.o 
+endif
+
+XFLAGS = $(CFLAGS) $(CPPFLAGS) $(MFLAG) -DEXPORT_SYMTAB
+
+ifdef CONFIG_CARDBUS
+MODULES = islpci_cb.o
+else
+MODULES = islpci.o
+endif
+
+all:	$(OBJECTS) $(MODULES)
+
+%o: %c
+	$(CC) -MD -c $(XFLAGS) $<
+	@mkdir -p .depfiles ; mv $*d .depfiles
+
+
+islpci_cb.o: $(OBJECTS)
+	$(LD) -r -o .$@ $(OBJECTS)
+	mv .$@ $@ ; chmod -x $@
+
+islpci.o: $(OBJECTS)
+	$(LD) -r -o .$@ $(OBJECTS)
+	mv .$@ $@ ; chmod -x $@
+
+clean:
+	rm -f *.o .*.o .depfiles/*.d
+
+install: install-modules
+	 cp islpci.conf /etc/pcmcia
+ifdef CONFIG_CARDBUS
+	 cp *.arm /etc/pcmcia
+else
+	 cp *.arm /etc/hotplug
+endif
+
+include ../../rules.mk
+
diff -urN linux-2.4.29/drivers/net/intersil/version_info.h linux-2.4.29-uc1/drivers/net/intersil/version_info.h
--- linux-2.4.29/drivers/net/intersil/version_info.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/intersil/version_info.h	2005-06-14 02:12:14.000000000 +0100
@@ -0,0 +1 @@
+#define VERSIONID       "1.0.1.0"
diff -urN linux-2.4.29/drivers/net/irda/Config.in linux-2.4.29-uc1/drivers/net/irda/Config.in
--- linux-2.4.29/drivers/net/irda/Config.in	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/irda/Config.in	2005-06-14 02:12:13.000000000 +0100
@@ -22,6 +22,9 @@
       dep_tristate '  ACTiSYS IR-200L dongle (Experimental)' CONFIG_ACT200L_DONGLE $CONFIG_IRDA
       dep_tristate '  Mobile Action MA600 dongle (Experimental)' CONFIG_MA600_DONGLE $CONFIG_IRDA
    fi
+   if [ "$CONFIG_ARCH_EP93XX" = "y" ]; then
+      dep_tristate '  Cirrus EP93xx SIR dongle' CONFIG_EP93XX_SIR $CONFIG_IRDA
+   fi
 fi
 
 comment 'FIR device drivers'
@@ -42,5 +45,8 @@
 if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
    dep_tristate 'SA1100 Internal IR' CONFIG_SA1100_FIR $CONFIG_IRDA
 fi
+if [ "$CONFIG_ARCH_EP93XX" = "y" ]; then
+   dep_tristate 'Cirrus EP93xx SIR/MIR/FIR' CONFIG_EP93XX_IRDA $CONFIG_IRDA
+fi
 
 endmenu
diff -urN linux-2.4.29/drivers/net/irda/ep93xx_irda.c linux-2.4.29-uc1/drivers/net/irda/ep93xx_irda.c
--- linux-2.4.29/drivers/net/irda/ep93xx_irda.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/irda/ep93xx_irda.c	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,3118 @@
+/*********************************************************************
+ *                
+ * Filename:      ep93xx_irda.c
+ * Version:       0.2
+ * Description:   Driver for the EP93xx SOC IrDA.
+ * Status:        Experimental.
+ *
+ * Copyright 2003 Cirrus Logic, Inc.
+ *
+ * Based loosely on the ali-ircc.c implementation:
+ *
+ *      Author:        Benjamin Kong <benjamin_kong@ali.com.tw>
+ *      Created at:    2000/10/16 03:46PM
+ *      Modified at:   2001/1/3 02:55PM
+ *      Modified by:   Benjamin Kong <benjamin_kong@ali.com.tw>
+ * 
+ *      Copyright (c) 2000 Benjamin Kong <benjamin_kong@ali.com.tw>
+ *      All Rights Reserved
+ *      
+ *      This program is free software; you can redistribute it and/or 
+ *      modify it under the terms of the GNU General Public License as 
+ *      published by the Free Software Foundation; either version 2 of 
+ *      the License, or (at your option) any later version.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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:
+ *      Free Software Foundation, Inc.
+ *      59 Temple Place, Suite 330 
+ *      Boston, MA  02111-1307  USA
+ ********************************************************************/
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/rtnetlink.h>
+#include <linux/serial_reg.h>
+
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/byteorder.h>
+
+#include <linux/pm.h>
+
+#include <net/irda/wrapper.h>
+#include <net/irda/irda.h>
+#include <net/irda/irmod.h>
+#include <net/irda/irlap_frame.h>
+#include <net/irda/irda_device.h>
+
+#include <asm/arch/dma.h>
+#include <net/irda/ep93xx_irda.h>
+#include <asm/arch/irqs.h>
+
+static char *driver_name = "ep93xx-irda";
+static char *SIR_str = "SIR only";
+static char *SIRMIR_str = "SIR/MIR only";
+static char *SIRFIR_str = "SIR/MIR only";
+static char *SIRMFIR_str = "SIR/MIR/FIR";
+
+
+/* 
+ * Turnaround time:  
+ * Min. time the HW can respond.
+ * 
+ * Interestingly, most drivers set this value to
+ * 0x1.  That would mean the index in bits_to_value
+ * would end up with a value of 0 and the min_turn_times
+ * array's [0] value is '10000'(us). 
+ *
+ * 0-7 are the only valid index positions for the 
+ * min_turn_times array.  With the bitshift discovery 
+ * method used (and the IrDA spec wanting contiguous bits), 
+ * only values of 0xFF, 0x7f, 0x3F, 0x1F, 0xF, 0x7, 0x3, 
+ * & 0x1 are valid assignments for this variable.
+ * 
+ * (look at qos.c's min_turn_times array, bits_to_value and
+ * msb_index functions to validate)
+ */
+static int qos_mtt_bits = 0x7;
+
+
+/*
+ * Modes the clock settings will support.
+ */
+static int g_iClkSupport = 0;
+
+
+/*
+ * Initialization prototypes.
+ */
+static int ep93xx_irda_init_9312(ep93xx_chip_t *chip);
+
+/*
+ * Currently known EP93xx SOC packages.
+ */
+static ep93xx_chip_t chips[] =
+{
+    	/* name|irqs|sir dmatx|sir dmarx|mfir dmatx|mfir dmarx|init func */
+	{ "EP9312", IRQ_UART2, IRQ_IRDA, DMATx_UART2, DMATx_IRDA, DMARx_IRDA, ep93xx_irda_init_9312 },
+	{ NULL }
+};
+
+/* 
+ * Max 4 instances (as is "standard" for an IrDA driver).
+ */
+static struct ep93xx_irda_cb *dev_self[] = { NULL, NULL, NULL, NULL };
+
+/* 
+ * Prototypes. 
+ */
+
+ /*
+  * General ep93xx family.
+  */
+ static int  ep93xx_irda_open(int i, ep93xx_chip_t *chip);
+ #ifdef MODULE
+ static int  ep93xx_irda_close(struct ep93xx_irda_cb *self);
+ #endif /* MODULE */
+ static int  ep93xx_irda_setup(ep93xx_chip_t *chip);
+ static int  ep93xx_irda_is_receiving(struct ep93xx_irda_cb *self);
+ static int  ep93xx_irda_net_init(struct net_device *dev);
+ static int  ep93xx_irda_net_open(struct net_device *dev);
+ static int  ep93xx_irda_net_close(struct net_device *dev);
+ static int  ep93xx_irda_net_ioctl(struct net_device *dev, struct ifreq *rq, 
+     int cmd);
+ static void ep93xx_irda_change_speed(struct ep93xx_irda_cb *self, 
+     __u32 baud);
+ static void ep93xx_irda_interrupt(int irq, void *dev_id, 
+     struct pt_regs *regs);
+#ifdef POWER_SAVING
+ static int ep93xx_irda_pmproc(struct pm_dev *dev, pm_request_t rqst, 
+		 void *data);
+ static void ep93xx_irda_suspend(struct ep93xx_irda_cb *self);
+ static void ep93xx _irda_wakeup(struct ep93xx_irda_cb *self);
+#endif 
+ static struct net_device_stats *ep93xx_irda_net_get_stats(struct net_device *dev);
+
+/* 
+ * Driver SIR functions 
+ */
+static void ep93xx_irda_sir_change_speed(struct ep93xx_irda_cb *priv, 
+                                         __u32 speed);
+static void ep93xx_irda_sir_interrupt(int irq, struct ep93xx_irda_cb *self, 
+                                      struct pt_regs *regs);
+static void ep93xx_irda_sir_receive(struct ep93xx_irda_cb *self);
+static void ep93xx_irda_sir_write_wakeup(struct ep93xx_irda_cb *self);
+static int ep93xx_irda_sir_write(int iFifo_size, __u8 *pBuf, int iLen);
+
+
+/* 
+ * Driver MIR/FIR functions 
+ */
+static void ep93xx_irda_mfir_change_speed(struct ep93xx_irda_cb *priv, 
+                                          __u32 speed);
+static void ep93xx_irda_mfir_interrupt(int irq, struct ep93xx_irda_cb *self, 
+                                       struct pt_regs *regs);
+
+
+
+/*
+ * Driver DMA functions
+ */
+static int  ep93xx_irda_dma_receive(struct ep93xx_irda_cb *self); 
+static int  ep93xx_irda_dma_receive_complete(struct ep93xx_irda_cb *self, unsigned int frameSize);
+static int  ep93xx_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev);
+static void ep93xx_irda_dma_xmit(struct ep93xx_irda_cb *self);
+static int  ep93xx_irda_dma_xmit_complete(struct ep93xx_irda_cb *self, int irqID);
+
+/* 
+ * State change functions 
+ */
+static void SIR2MFIR(struct ep93xx_irda_cb *self, __u32 TargetSpeed);
+static void MFIR2SIR(struct ep93xx_irda_cb *self, __u32 TargetSpeed);
+static void SetInterrupts(struct ep93xx_irda_cb *self, unsigned char enable);
+static void SetIR_Transmit(unsigned char ucEnable);
+static void SetIR_Receive(unsigned char ucEnable);
+static void SetDMA(struct ep93xx_irda_cb *self, unsigned char direction, 
+                   unsigned char enable);
+
+
+
+
+/*
+ * Local DEFINES 
+ */
+
+/*
+ * Define to signal usage of PIO mode only for transmits.
+ */
+#define PIO_TX
+
+
+/*
+ * Define to signal console printing of debug statements.
+ */
+//#define DEBUG
+#ifdef DEBUG
+
+	/*
+ 	 * DEBUG_LEVEL determines which DEBUG statements to print.
+	 */
+	#define DEBUG_LEVEL 1
+	#define EP93XX_DEBUG(x,y...) (x <= DEBUG_LEVEL) ? printk( ##y ) : 0
+#else
+	#define EP93XX_DEBUG(x,y...)
+#endif
+
+
+/*
+ * Function ep93xx_irda_init ()
+ *
+ *    Initialize block.  Verify some basic knowns before proceding setup/load.
+ *    
+ */
+int __init 
+ep93xx_irda_init(void)
+{
+    ep93xx_chip_t *chip;
+    unsigned long ulRegValue;
+    int ret = -ENODEV;
+    int i = 0;
+	
+    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+
+    /* 
+     * Check for all the EP93xx SOC packages we know about .
+     */
+    for(chip = chips; chip->name; chip++, i++) 
+    {
+	EP93XX_DEBUG(2, "%s(), Probing for %s ...\n", __FUNCTION__, chip->name);
+				
+ 	/* 
+         * Prepare to test some knowns for the SOC. 
+         */
+        ulRegValue = 0;
+
+        /*
+         *   Read the CHIP_ID register to make sure the family is correct.
+         */ 
+        ulRegValue = inl(SYSCON_CHIPID);
+        EP93XX_DEBUG(1, "SYSCON_CHIPID = 0x%x\n", ulRegValue);
+
+        if(chip->name)
+	{
+	    EP93XX_DEBUG(2, "%s(), Found %s SOC IrDA block, at 0x%03x\n",
+				__FUNCTION__, chip->name, IRDA_BASE);					
+            /*
+             * Resource usage is fixed.  Initialize and open.
+             */
+            chip->init(chip);
+			
+	    if(ep93xx_irda_open(i, chip) == 0)
+            {
+				ret = 0;
+            }
+
+	    i++;				
+	}
+	else
+	{
+	    EP93XX_DEBUG(2, "%s(), No %s SOC IrDA block found.\n", 
+                __FUNCTION__, chip->name);
+	}
+    }		
+		
+	EP93XX_DEBUG(2, "%s(), ----------------- End -----------------\n", 
+        __FUNCTION__);
+	return(ret);
+}
+
+
+/*
+ * Function ep93xx_irda_cleanup ()
+ *
+ *    Close all configured chips
+ *
+ */
+#ifdef MODULE
+static void 
+ep93xx_irda_cleanup(void)
+{
+	int i;
+
+	EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);	
+	
+	pm_unregister_all(ep93xx_irda_pmproc);
+
+	for(i = 0; i < 4; i++) 
+        {
+		if(dev_self[i])
+        	{
+			ep93xx_irda_close(dev_self[i]);
+         	}
+	}
+	
+	EP93XX_DEBUG(2, "%s(), ----------------- End -----------------\n", 
+        __FUNCTION__);
+}
+#endif /* MODULE */
+
+
+/*
+ * Function ep93xx_irda_open (int i, ep93xx_chip_t *info)
+ *
+ *    Open driver instance.
+ *
+ */
+static int 
+ep93xx_irda_open(int i, ep93xx_chip_t *info)
+{
+	struct net_device *dev;
+	struct ep93xx_irda_cb *self;
+#ifdef POWER_SAVING	
+	struct pm_dev *pmdev;
+#endif	
+	int err;
+	dma_addr_t rxdmaphys, txdmaphys;
+			
+	EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);	
+	
+    /* 
+     * Get setup for the attack run... 
+     */
+    if((ep93xx_irda_setup(info)) == -1)
+    {
+	return(-1);
+    }
+		
+    /* 
+     * Allocate a new instance of the driver 
+     */
+    self = kmalloc(sizeof(struct ep93xx_irda_cb), GFP_KERNEL);
+    if(self == NULL) 
+    {
+ 	ERROR("%s(), can't allocate memory for control block!\n", 
+            __FUNCTION__);
+	return(-ENOMEM);
+    }
+
+    memset(self, 0, sizeof(struct ep93xx_irda_cb));
+    spin_lock_init(&self->lock);
+   
+    /* 
+     * Track 'self' pointer 
+     */
+    dev_self[i] = self;
+    self->index = i;
+
+    /* 
+     * Save important SOC data, starting with IRQs used 
+     */
+    self->iSIR_irq = info->iSIR_IRQ;
+    self->iMFIR_irq = info->iMFIR_IRQ;
+
+    /* 
+     * ep93xx DMA port ids 
+     */
+    self->ePorts[DMA_SIR_TX] = info->eSIR_DMATx;
+    self->ePorts[DMA_MFIR_TX] = info->eMFIR_DMATx;
+    self->ePorts[DMA_MFIR_RX] = info->eMFIR_DMARx;
+    self->fifo_size = 16;
+
+    /* 
+     * Initialize QoS for this device 
+     */
+    irda_init_max_qos_capabilies(&self->qos);
+	
+    /* 
+     * Override some values returned by max_qos 
+     */
+    self->qos.baud_rate.bits = 0;
+    
+    if(g_iClkSupport & CLK_SIR)
+    {
+       self->qos.baud_rate.bits |= IR_9600|IR_19200|IR_38400|IR_57600|
+	       IR_115200;
+    }
+
+    if(g_iClkSupport & CLK_MIR)
+    {
+	self->qos.baud_rate.bits |= IR_576000|IR_1152000;
+    }
+
+    if(g_iClkSupport & CLK_FIR)
+    {
+	self->qos.baud_rate.bits |= (IR_4000000 << 8);
+    }
+    
+    /* 
+     * Turnaround time 
+     */
+    self->qos.min_turn_time.bits = qos_mtt_bits;
+			
+    irda_qos_bits_to_value(&self->qos);
+	
+    self->flags = IFF_SIR|IFF_MIR|IFF_FIR|IFF_DMA|IFF_PIO; 	
+
+    /* 
+     * Max DMA buffer size needed = (data_size + 6) * (window_size) + 6;
+     */
+    self->rx_buff.truesize = 14384; 
+    self->tx_buff.truesize = 14384;
+    
+    /* 
+     * Allocate memory 
+     */
+    self->rx_buff.head = (__u8 *)consistent_alloc(GFP_KERNEL|GFP_DMA, 
+		    self->rx_buff.truesize, &rxdmaphys);
+    
+    if(self->rx_buff.head == NULL) 
+    {
+ 	kfree(self);
+	return(-ENOMEM);
+    }
+
+    memcpy(&self->rx_dmaphysh, &rxdmaphys, sizeof(dma_addr_t));
+    memset(self->rx_buff.head, 0, self->rx_buff.truesize);
+	
+    self->tx_buff.head = (__u8 *) consistent_alloc(GFP_KERNEL|GFP_DMA,
+		    self->tx_buff.truesize, &txdmaphys);
+    
+    if(self->tx_buff.head == NULL) 
+    {
+	consistent_free(self->rx_buff.head, self->rx_buff.truesize, rxdmaphys);
+	kfree(self);
+	return(-ENOMEM);
+    }
+
+    memcpy(&self->tx_dmaphysh, &txdmaphys, sizeof(dma_addr_t));
+    memset(self->tx_buff.head, 0, self->tx_buff.truesize);
+
+    
+    /*
+     * Conversion buffer.  Temp holding space for DMA buffers.
+     * Needed for SIR RX.
+     */
+    self->conv_buf = (__u8 *) kmalloc(self->rx_buff.truesize,
+                        GFP_KERNEL);
+    memset(self->conv_buf, 0, self->rx_buff.truesize);
+
+    self->rx_buff.in_frame = FALSE;
+    self->rx_buff.state = OUTSIDE_FRAME;
+    self->tx_buff.data = self->tx_buff.head;
+    self->rx_buff.data = self->rx_buff.head;
+	
+    /* 
+     * Reset Tx queue info 
+     */
+    self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
+    self->tx_fifo.tail = self->tx_buff.head;
+
+    if(!(dev = dev_alloc("irda%d", &err))) 
+    {
+ 	ERROR("%s(), dev_alloc() failed!\n", __FUNCTION__);
+	return(-ENOMEM);
+    }
+
+    dev->priv = (void *) self;
+    self->netdev = dev;
+	
+    /*
+     * Override the network functions we need to use 
+     */
+    dev->init            = ep93xx_irda_net_init;
+    dev->hard_start_xmit = ep93xx_irda_hard_xmit;
+    dev->open            = ep93xx_irda_net_open;
+    dev->stop            = ep93xx_irda_net_close;
+    dev->do_ioctl        = ep93xx_irda_net_ioctl;
+    dev->get_stats	     = ep93xx_irda_net_get_stats;
+
+    rtnl_lock();
+    err = register_netdevice(dev);
+    rtnl_unlock();
+	
+    if(err) 
+    {
+	ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
+	return(-1);
+    }
+   
+    MESSAGE("IrDA: Registered device %s\n", dev->name);
+
+#ifdef POWER_SAVING
+	pmdev = pm_register(PM_SYS_DEV, PM_SYS_IRDA, ep93xx_irda_pmproc);
+
+    if(pmdev)
+    {
+            pmdev->data = self;
+    }
+#endif
+
+    EP93XX_DEBUG(2, "%s(), ----------------- End -----------------\n", 
+        __FUNCTION__);
+	
+    return(0);
+}
+
+
+#ifdef MODULE
+/*
+ * Function ep93xx_irda_close (self)
+ *
+ *    Close driver instance.
+ *
+ */
+static int 
+ep93xx_irda_close(struct ep93xx_irda_cb *self)
+{
+
+    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+
+    ASSERT(self != NULL, return -1;);
+
+    /*
+     * Remove netdevice 
+     */
+    if(self->netdev) 
+    {
+	rtnl_lock();
+	unregister_netdevice(self->netdev);
+	rtnl_unlock();
+    }
+
+    if(self->tx_buff.head)
+    {
+	consistent_free(self->tx_buff.head, self->tx_buff.truesize, 
+			self->tx_dmaphysh);
+    }
+	
+    if(self->rx_buff.head)
+    {
+	consistent_free(self->rx_buff.head, self->rx_buff.truesize, 
+			self->rx_dmaphysh);
+    }
+
+    dev_self[self->index] = NULL;
+    kfree(self);
+	
+    EP93XX_DEBUG(2, "%s(), ----------------- End -----------------\n", 
+        __FUNCTION__);
+	
+    return(0);
+}
+#endif /* MODULE */
+
+/*
+ * ep93xx_get_PLL_frequency
+ *
+ * Given a value for ClkSet1 or ClkSet2, calculate the PLL1 or PLL2 frequency.
+ */
+static unsigned long ep93xx_get_PLL_frequency( unsigned long ulCLKSET )
+{
+	ulong ulX1FBD, ulX2FBD, ulX2IPD, ulPS, ulPLL_Freq;
+
+	ulPS = (ulCLKSET & SYSCON_CLKSET1_PLL1_PS_MASK) >> SYSCON_CLKSET1_PLL1_PS_SHIFT; 	
+	ulX1FBD = (ulCLKSET & SYSCON_CLKSET1_PLL1_X1FBD1_MASK) >> SYSCON_CLKSET1_PLL1_X1FBD1_SHIFT;
+	ulX2FBD = (ulCLKSET & SYSCON_CLKSET1_PLL1_X2FBD2_MASK) >> SYSCON_CLKSET1_PLL1_X2FBD2_SHIFT;
+	ulX2IPD = (ulCLKSET & SYSCON_CLKSET1_PLL1_X2IPD_MASK) >> SYSCON_CLKSET1_PLL1_X2IPD_SHIFT;
+
+	/*
+	 * This may be off by a very small fraction of a percent.
+	 */
+	ulPLL_Freq = (((0x00e10000 * (ulX1FBD+1)) / (ulX2IPD+1)) * (ulX2FBD+1)) >> ulPS;
+
+	return ulPLL_Freq;
+}
+
+/*
+ * Function ep93xx_irda_init_9312 (chip)
+ *
+ *    Identify the EP9312 SOC's IrDA capabilities
+ *    as it is currently configured. 
+ */
+static int 
+ep93xx_irda_init_9312(ep93xx_chip_t *chip) 
+{
+    unsigned int uiMIRDiv = 0, uiUSBDiv = 0;
+    unsigned long ulPLL1, ulPLL2;
+       
+#define MIRCLK 18432000 
+    /*
+     * Identify the what modes the clocks will support.
+     * 		- SIR will always be supported.
+     * 		- MIR depends on processor speed. 
+     * 		- FIR should be supported.
+     */
+    
+    /*
+     * Dedicated clocks for UARTs, which is what SIR uses.
+     */
+    g_iClkSupport = CLK_SIR;
+
+	/*
+	 * Get the frequency of the two PLLs.
+	 */
+	ulPLL1 = ep93xx_get_PLL_frequency( inl(SYSCON_CLKSET1) );
+	ulPLL2 = ep93xx_get_PLL_frequency( inl(SYSCON_CLKSET2) );
+
+    /*
+     * MIR: Check PLL1 clock for one of our supported
+     * settings and  setup MIR clock, if the processor speed is
+     * MIR friendly.
+     * 
+     * 0xC000 sets MIR_CLK div on, internal clock
+     * source and PLL1 as the source.
+     *
+     * Need to find pre-clk divisor(2,2.5,3) and 7bit divisor.
+     */
+    if(!((ulPLL1 / 3) % MIRCLK) && 
+		    (((ulPLL1 / 3) / MIRCLK) < 0x7f))
+    {
+	    uiMIRDiv = (0x3 << 9) | (unsigned int)((ulPLL1 / 3) / MIRCLK);
+    } 
+    else if(!((unsigned long)((ulPLL1 * 5) / 2) % MIRCLK) &&
+		    ((((ulPLL1 * 5) / 2) / MIRCLK) < 0x7f))
+    {    
+	    uiMIRDiv = (0x2 << 9) | (unsigned int)(((ulPLL1 * 5) / 2) / MIRCLK);
+    }
+    else if(!((ulPLL1 / 2) % MIRCLK) && 
+		    (((ulPLL1 / 2) / MIRCLK) < 0x7f))
+    {
+	    uiMIRDiv = (0x1 << 9) | (unsigned int)((ulPLL1 / 2) / MIRCLK);
+    }
+
+    if(uiMIRDiv > 0)
+    {
+	    /*
+	     * Setup the MIR clock register and flag the 
+	     * driver to report MIR support.
+	     */
+	    uiMIRDiv |=  0xC000;
+	    outl(uiMIRDiv, SYSCON_MIRDIV);
+	    g_iClkSupport = CLK_MIR; 
+    }
+
+    /*
+     * FIR: Check PLL2 and make sure it's giving
+     * a CLK that the USBDiv can convert to 48mhz
+     */
+    uiUSBDiv = (inl(SYSCON_CLKSET2) >> 28) + 1;
+    if((uiUSBDiv == 0) || (uiUSBDiv == 16))
+    {
+	uiUSBDiv = 1;
+    }
+    
+    if((ulPLL2 / uiUSBDiv) == 48000000)
+    {
+	g_iClkSupport |= CLK_FIR;
+    }    
+	
+    return(0);
+}
+
+
+/*
+ * Function ep93xx_irda_setup (info)
+ *
+ *    Attempts to take ownership of UART2, configures for SIR
+ *    usage (lowest speed IrDA).
+ *
+ *	  Returns non-negative on success.
+ */
+static int 
+ep93xx_irda_setup(ep93xx_chip_t *info)
+{
+    unsigned int uiRegVal;
+    char *cptrSupport = NULL;
+
+    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+
+    /*
+     * Set UART2 to be an IrDA interface.
+     */
+    uiRegVal = inl(SYSCON_DEVCFG);
+    SysconSetLocked(SYSCON_DEVCFG, (uiRegVal | 
+			    (SYSCON_DEVCFG_IonU2 | SYSCON_DEVCFG_U2EN)));
+	
+    uiRegVal = inl(SYSCON_DEVCFG);
+
+    /*
+     * Set the pulse width.
+     */
+    outl(3, UART2ILPR);
+
+    /*
+     * Set SIREN bit in UART2 - this enables the SIR encoder/decoder.
+     */
+    uiRegVal = inl(UART2CR);
+    outl((uiRegVal | (U2CR_SIR|U2CR_UART)), UART2CR);
+    uiRegVal = 0;
+
+    /*
+     * Enable Ir in SIR mode.
+     */
+    outl(IrENABLE_SIR, IrEnable);
+ 
+    uiRegVal = inl(IrEnable);
+
+    switch(g_iClkSupport & (CLK_SIR|CLK_MIR|CLK_FIR))
+    {
+	    case 3:cptrSupport = SIRMIR_str; 
+		    break;
+	    case 5:cptrSupport = SIRFIR_str;
+		    break;
+	    case 7: cptrSupport = SIRMFIR_str;
+		    break;
+	
+	    default:cptrSupport = SIR_str;
+		    break;
+    } 
+
+    
+    MESSAGE("%s, driver loaded supporting %s (Cirrus Logic, Inc.).\n", 
+		    driver_name, cptrSupport);
+	
+    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);	
+	
+	return(0);
+}
+
+
+/*
+ * Function ep93xx_irda_interrupt (irq, dev_id, regs)
+ *
+ *    An interrupt from the chip has arrived. Time to do some work.
+ *
+ */
+static void 
+ep93xx_irda_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *) dev_id;
+	struct ep93xx_irda_cb *self;
+		
+	EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+		
+ 	if(!dev) 
+    	{
+		WARNING("%s: irq %d for unknown device.\n", driver_name, irq);
+		return;
+	}	
+
+	EP93XX_DEBUG(2, "%s(), for IRQ %d\n", __FUNCTION__, irq);
+
+	self = (struct ep93xx_irda_cb *) dev->priv;
+	
+	spin_lock(&self->lock);
+	
+	/* 
+	 * Dispatch interrupt handler for the IRQ signaled.
+	 */
+	if(irq == IRQ_IRDA)
+    	{
+		ep93xx_irda_mfir_interrupt(irq, self, regs);
+	}
+	else if(irq == IRQ_UART2)
+    	{
+		ep93xx_irda_sir_interrupt(irq, self, regs);	
+    	} 
+	else
+	{
+		WARNING("%s:  IRQ%d signaled but not recognized\n", 
+				driver_name, irq);
+	}
+
+	spin_unlock(&self->lock);
+	
+	EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);
+}
+
+
+/*
+ * Function ep93xx_irda_mfir_interrupt(irq, struct ep93xx_irda_cb *self, regs)
+ *
+ *    Handle MIR/FIR interrupt.
+ *
+ */
+static void 
+ep93xx_irda_mfir_interrupt(int irq, struct ep93xx_irda_cb *self, 
+                          struct pt_regs *regs)
+{
+    __u8 irqID;
+    int iLen, iVal, iWriteBack, iStatus;
+	
+    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+
+    /*
+     *  Identify the IRQ signal for MIR/FIR.  Branch on speed to
+     *  determine which register to check.
+     */
+    if(self->speed < 4000000)
+    {
+        /*
+         * Should be a MIR interrupt.
+         */
+        irqID = inl(MIIR);		
+    }
+    else
+    {
+        /*
+         * Should be a FIR interrupt.
+         */
+        irqID = inl(FIIR);		
+    }
+
+    /*
+     * Disable Interrupts
+     */
+    SetInterrupts(self, FALSE);
+        
+    if(!irqID)
+    {
+	EP93XX_DEBUG(1,"MFIR IRQ signalled, but no flag set? (speed = %d)\n", 
+			self->speed);
+    }
+
+    /*
+     * Determine why the interrupt (TX/RX?).  
+     */
+    if(irqID & (MFIIR_RXFL|MFIIR_RXIL|MFIIR_RXFC|MFIIR_RXFS))
+    {
+        /*
+         * Service the Rx related interrupt.
+         */
+
+	/*
+	 * Clear our write back value variable.
+	 */
+	iWriteBack = 0;
+	    
+        if(irqID & MFIIR_RXFL)
+        {
+          	EP93XX_DEBUG(1, 
+                "%s(), ******* Frame lost (RX) *******\n", __FUNCTION__);
+
+            /*
+             * Receive Frame Lost. A ROR occurred at the start of a new frame,
+             * before any data for the frame could be placed into the rx FIFO.
+             * The last entry in the FIFO already contains a valid EOF bit from
+	     * the previous frame and a FIFO overrun has occurred.  The frame is
+	     * lost.
+             */
+	    iWriteBack |= MFISR_RXFL;
+        }
+
+        if(irqID & MFIIR_RXIL)
+        {
+          	EP93XX_DEBUG(1, 
+                "%s(), ******* Info buffer lost (RX) *******\n", __FUNCTION__);
+
+            /*
+             * Receive Information Buffer Lost.  The last data for the frame
+             * has been read from the RX FIFO and the RFC bit is still set
+             * from the previous EOF.  The IrRIB register data for the previous
+             * frame has therefore been lost.
+             *
+             */
+	    iWriteBack |= MFISR_RXIL;
+
+        }
+
+        if(irqID & MFIIR_RXFC)
+        {
+          	EP93XX_DEBUG(1, 
+                "%s(), ******* Frame complete (RX) *******\n", __FUNCTION__);
+
+            /*
+             * Received Frame Complete.  The last data for frame has been
+             * read from the FIFO.  IrRIB now has IrFlag and byte count.
+             *
+             */
+            iVal = inw(IrRIB);
+            iLen = (iVal&IrRIB_ByteCt) >> 4;
+            iStatus = (iVal & (IrRIB_BUFFE | IrRIB_BUFOR | 
+				    IrRIB_BUFCRCERR | IrRIB_BUFRXABORT));
+	
+            EP93XX_DEBUG(1, "%s(), RX Length = 0x%.2x\n", __FUNCTION__, iLen);	
+            EP93XX_DEBUG(1, "%s(), RX Status = 0x%.2x (IrRIB = 0x%x)\n", 
+			    __FUNCTION__, iStatus, iVal);
+		  
+            
+            /* 
+             * Check for errors - the lower 4 bits signal errors.  However,
+	     * we ignore Buffered Framing errors, so only check the lower
+	     * 3 bits.
+             */
+            if((iStatus & 0x7) ||(iLen==0))
+            {
+ 	        EP93XX_DEBUG(1, "%s(), ************ RX Errors *********** \n",
+			       	__FUNCTION__);
+		        
+	        /* 
+                 * If there was errors, skip the frame.
+                 */
+	        self->stats.rx_errors++;
+		        
+	        self->rx_buff.data += iLen;
+		        
+	        if(iStatus & IrRIB_BUFRXABORT) 
+	        {
+		        self->stats.rx_frame_errors++;
+		        EP93XX_DEBUG(1, 
+                        "%s(), ************* ABORT Condition ************ \n", 
+                           __FUNCTION__);
+	        }
+        
+	        if(iStatus & IrRIB_BUFFE)
+	        {
+		        self->stats.rx_frame_errors++;
+		        EP93XX_DEBUG(1, 
+                         "%s(), ************* FRAME Errors ************ \n", 
+                           __FUNCTION__);
+	        }
+						        
+	        if(iStatus & IrRIB_BUFCRCERR) 
+	        {
+		        self->stats.rx_crc_errors++;
+		        EP93XX_DEBUG(1, 
+                         "%s(), ************* CRC Errors ************ \n", 
+                            __FUNCTION__);
+	        }
+		        
+	        if(iStatus & IrRIB_BUFOR)
+	        {
+		        self->stats.rx_frame_errors++;
+		        EP93XX_DEBUG(1, 
+                         "%s(), *********** Overran DMA buffer ********** \n", 
+                            __FUNCTION__);
+	        }
+
+	        if(iLen == 0)
+	        {
+		        self->stats.rx_frame_errors++;
+		        EP93XX_DEBUG(1, 
+                         "%s(), ********* Receive Frame Size = 0 ******** \n", 
+                            __FUNCTION__);
+	        }
+            }
+            else
+            {
+                /*
+                 * Looks okay, call handler.
+                 */
+                ep93xx_irda_dma_receive_complete(self, iLen);
+            }
+        }
+
+        if(irqID & MFIIR_RXFS)
+        {
+          	EP93XX_DEBUG(1, 
+                "%s(), ******* Buffer SR (RX) *******\n", __FUNCTION__);
+
+            /*
+             * Receive Buffer Service Request (RO).  Buffer is not empty and 
+             * the receiver is enabled, DMA service request signaled.
+             *
+             */
+        }
+
+	if(self->speed < 4000000)
+	{
+		outb(iWriteBack, MISR);
+	}
+	else
+	{
+		outb(iWriteBack, FISR);
+	}
+    }
+
+    if(irqID & (MFIIR_TXABORT|MFIIR_TXFC|MFIIR_TXFS))
+    {
+        /*
+         * Service the Tx related interrupt.
+         */
+
+        if(irqID & MFIIR_TXABORT)
+        {
+          	EP93XX_DEBUG(1, 
+                "%s(), ******* Frame abort (TX) *******\n", __FUNCTION__);
+
+            /*
+             * Transmit Frame Abort.  Transmitted frame has been terminated
+             * with an abort.
+             *
+             */
+        }
+
+        if(irqID & MFIIR_TXFC)
+        {
+          	EP93XX_DEBUG(1, 
+                "%s(), ******* Frame complete (TX) *******\n", __FUNCTION__);
+            
+            /*
+             * Transmitted Frame Complete.  The frame has been transmitted and
+             * terminated (possibly with an error).
+             */
+   	    if(ep93xx_irda_dma_xmit_complete(self, irqID))
+	    {
+		/*
+                 * Prepare for receive 
+                 */
+		ep93xx_irda_dma_receive(self);					
+		
+	    }
+        }
+
+        if(irqID & MFIIR_TXFS)
+        {
+          	EP93XX_DEBUG(1, 
+                "%s(), ******* Buffer SR (TX) *******\n", __FUNCTION__);
+
+            /*
+             * Transmit Buffer Service Request (RO).  TX buffer is not full and
+             * transmit is enabled, DMA service is signaled.
+             */
+         }
+    }
+
+    /*
+     * Restore Interupt
+     */
+    SetInterrupts(self, TRUE);
+    
+
+    EP93XX_DEBUG(1,
+	"ISR(), IrEnable = 0x%x, IrCtrl = 0x%x, IrFlag = 0x%x, FIMR = 0x%x\n",
+		inb(IrEnable), inb(IrCtrl), inw(IrFlag), inb(FIMR));
+
+    EP93XX_DEBUG(2, "%s(), ----------------- End ---------------\n", 
+		    __FUNCTION__);
+}
+
+/*
+ * Function ep93xx_irda_sir_interrupt(irq, self, eir)
+ *
+ *    Handle SIR interrupt.
+ *
+ */
+static void 
+ep93xx_irda_sir_interrupt(int irq, struct ep93xx_irda_cb *self, 
+                          struct pt_regs *regs)
+{
+    int iIrq, iLSR, iVal;
+	
+    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+	
+
+    iIrq = (char)inl(UART2IIR);
+
+    if(iIrq) 
+    {	
+		/* 
+        	 * Clear interrupt flags 
+        	 */
+		outl(0, UART2ICR);
+
+		EP93XX_DEBUG(2, "%s(), SIR IRQ (flag=0x%x)\n", 
+				__FUNCTION__, iIrq);
+
+
+        	if(iIrq & U2IICR_RXTOIRQ)
+        	{
+            		EP93XX_DEBUG(1, "%s(), Receive Timeout IRQ\n", 
+					__FUNCTION__);
+
+            		/*
+            		 * Check RSR for OE, BE & FE error conditions 
+			 * (and clear flags).
+            		 */
+            		iLSR = inl(UART2RSR);
+            		outl(0, UART2ECR);
+
+            		if(iLSR & U2RSR_OvnErr)
+            		{
+                		EP93XX_DEBUG(1, "%s(), Overrun Error\n", 
+						__FUNCTION__);
+                
+                		/*
+                 		 * Make certain we service the RX FIFO.
+                 		 */
+                		iIrq |= U2IICR_RXIRQ;
+            		}
+           		else if(iLSR & U2RSR_BrkErr)
+            		{
+                		EP93XX_DEBUG(1, "%s(), Break Error\n", 
+						__FUNCTION__);
+                		/*
+                		 * Clear the bad byte.
+                		 */
+                		inb(UART2DR);
+            		}
+            		else if(iLSR & U2RSR_FrmErr)
+            		{
+                		EP93XX_DEBUG(1, "%s(), Frame Error\n", 
+						__FUNCTION__);
+                		/*
+                		 * Clear the bad byte.
+                		 */
+                		inb(UART2DR);
+            		}
+
+        	}
+
+
+	if(iIrq & U2IICR_TXIRQ)
+        {
+            EP93XX_DEBUG(2, "%s(), Transmit IRQ\n", __FUNCTION__);
+            /*
+             * Tx'd a char, check Tx FIFO status.
+             */
+            iVal = inl(UART2FR);
+            if(iVal & U2FR_TXFE)
+            {
+#if U2_DMA_MODE
+                /*
+                 * TxFIFO is empty, check DMA position vs frame length.
+                 */
+                ep93xx_irda_dma_xmit_complete(self, iIrq);
+#else
+                /*
+                 * Check if more data to send.
+                 */
+                ep93xx_irda_sir_write_wakeup(self);
+#endif
+            }
+        }
+
+
+	if(iIrq & U2IICR_RXIRQ)
+        {
+	    EP93XX_DEBUG(2, "%s(), Receive IRQ\n", __FUNCTION__);
+            ep93xx_irda_sir_receive(self);
+        }
+
+
+        if(iIrq & U2IICR_MDMIRQ)
+        {
+            EP93XX_DEBUG(1, "%s(), Modem IRQ\n", __FUNCTION__);
+            /*
+             * Modem status, ignore but notify developer if in debug mode.
+             */
+        }
+    }
+    else
+    {
+        EP93XX_DEBUG(1, "%s(), An interrupt was signaled but not found.\n", 
+            __FUNCTION__);
+    }
+
+     EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);
+}
+
+
+/*
+ * Function ep93xx_irda_sir_receive (self)
+ *
+ *    Pull data from the RX FIFO and parse for
+ *    frames.
+ *
+ */
+static void 
+ep93xx_irda_sir_receive(struct ep93xx_irda_cb *self) 
+{
+	int iLoopCt = 0, iRxPkts = 0;
+	char cData;
+	
+	EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+			__FUNCTION__);
+	ASSERT(self != NULL, return;);
+
+	iRxPkts = self->stats.rx_packets;
+	/*  
+	 * Receive all characters in Rx FIFO, unwrap and unstuff them. 
+         * async_unwrap_char will deliver all found frames  
+	 */
+	do {
+		cData = inb(UART2DR);
+		async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, 
+				  cData);
+
+		EP93XX_DEBUG(2,"Byte = 0x%x\n", cData);
+
+ 		/* 
+		 * Avoid taking too much time in here.
+		 */
+		if (iLoopCt++ > 32) 
+        	{
+			EP93XX_DEBUG(1, "%s(), breaking!\n", __FUNCTION__);
+			break;
+		}
+		
+		
+	} while (!(inl(UART2FR) & U2FR_RXFE));	
+	
+	if(iRxPkts < self->stats.rx_packets)
+	{
+		EP93XX_DEBUG(2, "Received %d packets so far...\n", 
+				self->stats.rx_packets);
+		//mdelay(5);
+	}
+	
+	EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+			__FUNCTION__);	
+}
+
+
+
+/*
+ * Function ep93xx_irda_sir_write_wakeup (tty)
+ *
+ *    Called by the driver when there's room for more data.  If we have
+ *    more packets to send, we send them here.
+ *
+ */
+static void 
+ep93xx_irda_sir_write_wakeup(struct ep93xx_irda_cb *self)
+{
+	int iBytes = 0;
+	char cUART = 0;
+
+	ASSERT(self != NULL, return;);
+
+	EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+			__FUNCTION__);
+
+       SetInterrupts(self, FALSE);	
+       /* 
+        * Finished with frame?  
+        */
+	if (self->tx_buff.len > 0)  
+	{
+		/* 
+        	 * Write data left in transmit buffer 
+        	 */
+		iBytes = ep93xx_irda_sir_write(self->fifo_size, 
+				      self->tx_buff.data, self->tx_buff.len);
+		self->tx_buff.data += iBytes;
+		self->tx_buff.len  -= iBytes;
+	} 
+	else //if(!(inl(UART2FR) & U2FR_BUSY))
+	{
+		
+		if ((self->new_speed > 0)) 
+		{
+			/* 
+             		 * Wait until the TX FIFO is empty. 
+            		 */
+			do
+			{
+			    cUART=inl(UART2FR);
+  			    EP93XX_DEBUG(2, "Waiting on TX to complete...\n");
+			} while (cUART & U2FR_BUSY);
+			
+			EP93XX_DEBUG(1, 
+				"%s(), Changing speed! self->new_speed = %d\n", 
+        	        		__FUNCTION__, self->new_speed);
+			
+			ep93xx_irda_change_speed(self, self->new_speed);
+		}
+		else
+		{
+			/*
+			 * Notify the stack we're ready for more data.
+			 */
+			netif_wake_queue(self->netdev);
+		}
+		
+		self->stats.tx_packets++;
+		self->direction = DIR_RX;
+	}
+
+	SetInterrupts(self,TRUE);
+		
+	EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+			__FUNCTION__);	
+}
+
+
+/*
+ * Function ep93xx_irda_sir_write ()
+ *
+ *    Fill Tx FIFO with transmit data
+ *
+ */
+static int 
+ep93xx_irda_sir_write(int iFifo_size, __u8 *pBuf, int iLen)
+{
+	int iByteCt = 0;
+	
+	EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+			__FUNCTION__);
+       
+	/* 
+    	 * Fill TX FIFO with current frame.
+    	 */
+	while ((iFifo_size-- > 0) && (iByteCt < iLen)) 
+    	{
+		/*
+        	 * Transmit byte 
+        	 */
+		outl(pBuf[iByteCt], UART2DR);
+		EP93XX_DEBUG(2,"Tx Byte = 0x%x\n", pBuf[iByteCt]);
+		iByteCt++;
+	}
+	
+        EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+			__FUNCTION__);	
+	return(iByteCt);
+}
+
+
+/*
+ * Function ep93xx_irda_change_speed
+ *
+ *    Exposed interface function.  Check speed
+ *    and call worker function.
+ *
+ */
+static void 
+ep93xx_irda_change_speed(struct ep93xx_irda_cb *self, __u32 baud)
+{
+	unsigned long ulFlags;
+	
+	EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+	
+    if(self->speed == baud)
+    {
+        /*
+         * Desired speed is configured speed.
+         */
+        return;
+    }
+
+    EP93XX_DEBUG(1, "%s(), setting speed = %d \n", __FUNCTION__, baud);
+	
+    /*
+     * Turn off all interrupts.
+     */
+    save_flags(ulFlags);
+    cli();
+		
+    if(baud > 115200)
+    {
+    	/* 
+         * Change to MIR/FIR speed 
+         */
+  	 ep93xx_irda_mfir_change_speed(self, baud);
+
+ 	/*
+ 	 * Ready DMA for receive...
+ 	 */
+ 	ep93xx_irda_dma_receive(self);
+    }	
+    else
+    {
+        /* 
+         * Change to SIR speed 
+         */
+	ep93xx_irda_sir_change_speed(self, baud);
+	
+	/*
+	 * Ready for receive...
+	 */
+	self->direction = DIR_RX;
+	SetInterrupts(self, TRUE);
+    }
+
+
+
+    EP93XX_DEBUG(1, 
+	    "IrCtrl = 0x%x, IrEnable = 0x%x, FIMR = 0x%x, DMA = 0x%x\n", 
+		    inb(IrCtrl), inb(IrEnable), inb(FIMR), inb(IrDMACR));
+
+    /*
+     * Enable IRQs.
+     */
+    restore_flags(ulFlags);
+
+
+    /*
+     * Debug stuff - print packets tx/rx here.
+     */
+    EP93XX_DEBUG(2,"Packets:  RX = %d; TX = %d\n", self->stats.rx_packets, 
+		    self->stats.tx_packets);
+    
+    /*
+     * Notify the upper layers the driver is read to receive packets
+     * and to schedule the driver for service.
+     */
+    netif_wake_queue(self->netdev);	
+     	
+
+    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);
+}
+
+
+/*
+ * Function ep93xx_irda_mfir_change_speed
+ *
+ *    Adjusts speed for MFIR (possibly needs to handle 
+ *    transition from SIR).
+ *
+ */
+static void 
+ep93xx_irda_mfir_change_speed(struct ep93xx_irda_cb *self, __u32 speed)
+{
+    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+		
+    ASSERT(self != NULL, return;);
+
+    EP93XX_DEBUG(2, "%s(), self->speed = %d, change to speed = %d\n", 
+        __FUNCTION__, self->speed, speed);
+	
+    /* 
+     * Call regardless, no point duplicating code.
+     */
+    SIR2MFIR(self, speed);
+		
+    /* 
+     * Update accounting for new speed 
+     */
+    self->speed = speed;
+    self->new_speed = 0;
+		
+		
+    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);
+}
+
+
+/*
+ * Function ep93xx_irda_sir_change_speed (self, speed)
+ *
+ *    Adjusts speed for SIR (possibly needs to handle
+ *    transition from MFIR).
+ *
+ */
+static void 
+ep93xx_irda_sir_change_speed(struct ep93xx_irda_cb *priv, __u32 speed)
+{
+    struct ep93xx_irda_cb *self = (struct ep93xx_irda_cb *) priv;
+    unsigned int uiRegVal, uiCR_H, uiCR;
+
+    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+
+    ASSERT(self != NULL, return;);
+
+    EP93XX_DEBUG(2, "%s(), self->speed = %d, change to speed = %d\n", 
+        __FUNCTION__, self->speed, speed);
+
+    /*
+     * May be transitioning from MFIR to SIR.
+     */
+    if(self->speed > 115200)
+    {
+        MFIR2SIR(self, speed);
+    }
+
+    /* 
+     * Determine the clock and divisor 
+     */
+    uiRegVal = inl(SYSCON_PWRCNT);
+    if(uiRegVal & SYSCON_PWRCNT_UARTBAUD)
+    {
+        /* 
+         * UART CLK is 14.7456 
+         */
+	uiRegVal = 14.7456 * 1000000;
+    }
+    else
+    {
+        /* 
+         * UART CLK is 7.3728 
+         */
+	uiRegVal = 7.3728 * 1000000;
+    }
+	
+    uiRegVal /= (16*speed);
+    uiRegVal -= 1;    
+    
+    /* 
+     * IrDA ports use 8N1 
+     */
+    uiCR_H = U2CRH_WLen | U2CRH_FEn;
+	
+    /*
+     * Clear all related registers before we update.  Save
+     * CR first.
+     */
+    uiCR = inl(UART2CR);
+    
+    outb(0, UART2CR);
+    outb(0, UART2CR_M);
+    outb(0, UART2CR_L);
+    outb(0, UART2CR_H);
+    
+    /*
+     * Three write options for these registers:
+     *
+     *  - UART2CR_L, UART2CR_M, UARTCR_H
+     *  - UART2CR_M, UART2CR_L, UARTCR_H
+     *  - UART2CR_L || UART2CR_M, UART2CR_H
+     */
+    outb(((uiRegVal & 0xf00) >> 8), UART2CR_M);
+    outb((uiRegVal & 0xff), UART2CR_L);
+    outb(uiCR_H, UART2CR_H);
+    outb(uiCR, UART2CR);
+		
+		
+    /* 
+     * Update accounting for new speed 
+     */
+    self->speed = speed;
+    self->new_speed = 0;
+
+    /*
+     * The following is recommended by other implementations to maintain 
+     * connection from MIR/FIR speed transition:
+     * 
+     * 	                set DSR|CTS.
+     */
+    //uiRegVal = inl(UART2FR) & ~(U2FR_DSR | U2FR_CTS);
+    //outl(uiRegVal, UART2FR);
+	
+    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);	
+}
+
+
+/*
+ * Function ep93xx_irda_net_init (dev)
+ *
+ *    Initialize network device.
+ *
+ */
+static int 
+ep93xx_irda_net_init(struct net_device *dev)
+{
+	EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+	
+	/* 
+     * Setup to be a normal IrDA network device driver 
+     */
+	irda_device_setup(dev);
+
+	EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);
+	
+	return(0);
+}
+
+/*
+ * Function ep93xx_irda_net_open (dev)
+ *
+ *    Start the device.
+ *
+ */
+static int 
+ep93xx_irda_net_open(struct net_device *dev)
+{
+    struct ep93xx_irda_cb *self;
+    char hwname[64];
+    unsigned int uiRegVal;
+		
+    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+	
+    ASSERT(dev != NULL, return -1;);
+	
+    self = (struct ep93xx_irda_cb *) dev->priv;
+	
+    ASSERT(self != NULL, return 0;);
+	
+    /* 
+     * Request IRQs and install Interrupt Handler for them 
+     */
+    if(request_irq(self->iSIR_irq, ep93xx_irda_interrupt, 0, dev->name, dev)) 
+    {
+	WARNING("%s, unable to allocate irq=%d\n", driver_name, 
+			self->iSIR_irq);
+	return(-EAGAIN);
+    }
+
+    if(request_irq(self->iMFIR_irq, ep93xx_irda_interrupt, 0, dev->name, dev)) 
+    {
+	WARNING("%s, unable to allocate irq=%d\n", driver_name, 
+			self->iMFIR_irq);
+	return(-EAGAIN);
+    }
+	
+    /*
+     * Allocate the DMA channels through the ep9xx special DMA API. Clean up on 
+     * failure.  As there is no way to report failure in change_speed requests,
+     * get everything we need for all cases now.
+     */
+    if(ep93xx_dma_request(&(self->iDMAh[DMA_SIR_TX]), driver_name, 
+        		self->ePorts[DMA_SIR_TX]))
+    {
+	ERROR("%s, unable to allocate SIR dma tx channel.\n", driver_name);
+	free_irq(self->iSIR_irq, self);
+        free_irq(self->iMFIR_irq, self);
+	return(-EAGAIN);
+    }
+
+    if(ep93xx_dma_config(self->iDMAh[DMA_SIR_TX], IGNORE_CHANNEL_ERROR, 0,
+			    0, 0))
+    {
+	ERROR("%s, unable to config SIR dma tx channel.\n", driver_name);
+	ep93xx_dma_free(self->iDMAh[DMA_SIR_TX]);
+	free_irq(self->iSIR_irq, self);
+	free_irq(self->iMFIR_irq, self);
+	return(-EAGAIN);
+    }
+
+    if(ep93xx_dma_request(&(self->iDMAh[DMA_MFIR_TX]), driver_name, 
+			    self->ePorts[DMA_MFIR_TX]))
+    {
+	ERROR("%s, unable to allocate MFIR dma tx channel.\n", driver_name);
+        ep93xx_dma_free(self->iDMAh[DMA_SIR_TX]);
+	free_irq(self->iSIR_irq, self);
+        free_irq(self->iMFIR_irq, self);
+	return(-EAGAIN);
+    }
+
+    if(ep93xx_dma_config(self->iDMAh[DMA_MFIR_TX], IGNORE_CHANNEL_ERROR,
+			    0, 0, 0))
+    {
+	ERROR("%s, unable to configure MFIR dma tx channel.\n", driver_name);
+	ep93xx_dma_free(self->iDMAh[DMA_SIR_TX]);
+	ep93xx_dma_free(self->iDMAh[DMA_MFIR_TX]);
+	free_irq(self->iSIR_irq, self);
+	free_irq(self->iMFIR_irq, self);
+	return(-EAGAIN);
+    }
+
+    if(ep93xx_dma_request(&(self->iDMAh[DMA_MFIR_RX]), driver_name, 
+			    self->ePorts[DMA_MFIR_RX]))
+    {
+	ERROR("%s, unable to allocate MFIR dma rx channel.\n", driver_name);
+        ep93xx_dma_free(self->iDMAh[DMA_SIR_TX]);
+        ep93xx_dma_free(self->iDMAh[DMA_MFIR_TX]);
+	free_irq(self->iSIR_irq, self);
+        free_irq(self->iMFIR_irq, self);
+	return(-EAGAIN);
+    }
+
+    if(ep93xx_dma_config(self->iDMAh[DMA_MFIR_RX], IGNORE_CHANNEL_ERROR,
+			    0, 0, 0))
+    {
+	ERROR("%s, unable to configure MFIR dma rx channel.\n", driver_name);
+	ep93xx_dma_free(self->iDMAh[DMA_SIR_TX]);
+	ep93xx_dma_free(self->iDMAh[DMA_MFIR_TX]);
+	ep93xx_dma_free(self->iDMAh[DMA_MFIR_RX]);
+	free_irq(self->iSIR_irq, self);
+	free_irq(self->iMFIR_irq, self);
+	return(-EAGAIN);
+    }
+        
+    /* 
+     * Set start speed - 9600 (need to read clk first) 
+     */
+    ep93xx_irda_sir_change_speed(self, (__u32)9600);
+   
+    /* 
+     * Turn on recieve interrupts for SIR (starting point) 
+     */
+    uiRegVal = inl(UART2CR);
+    outl(uiRegVal|U2CR_RxIrq, UART2CR);
+    self->direction = DIR_RX;
+
+    /*
+     * Signal device is ready. 
+     */
+    netif_start_queue(dev); 
+	
+    /* 
+     * Give self a "hardware" name 
+     */
+    sprintf(hwname, "EP93XX-S/M/FIR @ 0x%03x", IRDA_BASE);
+
+    /* 
+     * Open new IrLAP layer instance, now that everything should be
+     * initialized properly 
+     */
+    self->irlap = irlap_open(dev, &self->qos, hwname);
+		
+    MOD_INC_USE_COUNT;
+
+    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);
+
+    return(0);
+}
+
+/*
+ * Function ep93xx_irda_net_close (dev)
+ *
+ *    Stop the device.
+ *
+ */
+static int 
+ep93xx_irda_net_close(struct net_device *dev)
+{	
+    struct ep93xx_irda_cb *self;
+    int i;
+				
+    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+		
+    ASSERT(dev != NULL, return -1;);
+
+    self = (struct ep93xx_irda_cb *) dev->priv;
+    ASSERT(self != NULL, return 0;);
+
+    /* 
+     * Stop device 
+     */
+    netif_stop_queue(dev);
+	
+    /*
+     *  Stop and remove instance of IrLAP 
+     */  
+    if (self->irlap)
+    {
+	irlap_close(self->irlap);
+    }
+
+    self->irlap = NULL;
+		
+    /* 
+     * Stop DMA channels & TX/RX. 
+     */
+    SetDMA(self, DIR_BOTH, FALSE);
+    SetIR_Transmit(FALSE);
+    SetIR_Receive(FALSE);
+
+
+    /* 
+     * Disable and release interrupts 
+     */
+    SetInterrupts(self, FALSE);
+	       
+    free_irq(self->iSIR_irq, dev);
+    free_irq(self->iMFIR_irq, dev);
+
+    /*
+     * release specialized EP93xx DMA channels 
+     */
+    for(i = 0; i < DMA_COUNT; i++)
+    {
+        ep93xx_dma_free(self->iDMAh[i]);
+    }
+
+    MOD_DEC_USE_COUNT;
+
+    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);
+	
+    return(0);
+}
+
+/*
+ * Function ep93xx_irda_hard_xmit(skb, dev)
+ *
+ *    Prep a frame for Tx, and signal Tx (via ep93xx_irda_xmit).
+ *
+ */
+static int 
+ep93xx_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+    struct ep93xx_irda_cb *self;
+    unsigned long ulFlags;
+    int iLength;
+    __u32 speed;
+    int mtt;
+	
+    EP93XX_DEBUG(2, "%s(), ---------------- Start -----------------\n", 
+        __FUNCTION__);
+    self = (struct ep93xx_irda_cb *) dev->priv;
+
+    SetDMA(self, self->direction, FALSE);
+    SetInterrupts(self, FALSE);
+
+    /*
+     * Getting ready to TX, so turn off RX.
+     */
+    //SetIR_Receive(FALSE);
+  
+    /* 
+     * Check if we need to change the speed 
+     */
+   speed = irda_get_next_speed(skb);
+   if((speed != self->speed) && (speed != -1)) 
+   {
+	   EP93XX_DEBUG(1,"Speed change queued (%d)\n", speed);
+	   self->new_speed = speed;
+   }
+	  
+    /* 
+     * Check for empty frame 
+     */
+    if((skb->len == 0) && (self->new_speed > 0)) 
+    {
+	EP93XX_DEBUG(1, "%s(), Empty frame for speed change.\n", __FUNCTION__);
+	ep93xx_irda_change_speed(self, speed); 
+	dev_kfree_skb(skb);
+	EP93XX_DEBUG(2,"%s(), ----------- SpeedOptOut ---------\n", 
+			__FUNCTION__);
+	return(0);
+    } 
+  
+   spin_lock_irqsave(&self->lock, ulFlags);
+
+   if((unsigned long)self->tx_fifo.tail % 0x10)
+   {
+	EP93XX_DEBUG(1, "Buffer not aligned?\n");
+   }
+   
+   /* 
+    * Register and copy this frame to DMA memory (do some alignment first).
+    */
+   self->tx_fifo.queue[self->tx_fifo.free].start = self->tx_fifo.tail;
+
+   if(self->speed <= 115200)
+   {
+        /* 
+         * SIR: Copy skb to tx_fifo while wrapping, stuffing and making CRC.
+         */
+         netif_stop_queue(dev);
+	 self->tx_buff.data = self->tx_buff.head;
+	 iLength = async_wrap_skb(skb, self->tx_buff.data, 
+			 self->tx_buff.truesize);
+	 self->tx_buff.len = iLength;
+   }
+   else
+   {
+	EP93XX_DEBUG(1,"MFIR XMIT : %d bytes\n", skb->len);
+	memcpy(self->tx_fifo.queue[self->tx_fifo.free].start,
+			skb->data, skb->len);
+
+	iLength = skb->len;
+	self->tx_fifo.queue[self->tx_fifo.free].len = iLength;
+	self->tx_fifo.tail += iLength;
+	self->tx_fifo.len++;
+	self->tx_fifo.free++;
+   }
+  
+   self->stats.tx_bytes += iLength;
+
+   /* 
+    * Start transmit (if not currently)
+    */
+   if(((self->tx_fifo.len == 1) || (iLength > 0))) 
+   {
+
+	self->direction = DIR_TX;
+        /* 
+         * Check if we must wait the min turn time or not 
+         */
+	mtt = irda_get_mtt(skb);
+	if(mtt) 
+	{
+		EP93XX_DEBUG(1, "%s(), ******* delay = %d ******* \n", 
+                    __FUNCTION__, mtt);
+
+		mdelay(mtt);
+        }
+	
+	/*
+	 * Enable TX
+	 */
+	SetIR_Transmit(TRUE);
+
+	
+   	/* 
+    	 * Enable appropriate interrupts.
+    	 */
+   	SetInterrupts(self, TRUE);
+		
+    	/* 
+    	 * Transmit frame, if MIR/FIR.
+    	 */
+	if(self->speed > 115200)
+	{
+	  	ep93xx_irda_dma_xmit(self);
+	}
+   } 
+
+   
+   /* 
+    * Not busy transmitting if window is not full 
+    */
+   if((self->tx_fifo.free < MAX_TX_WINDOW) && (self->speed > 115200))
+   {
+	netif_wake_queue(self->netdev);
+   }
+	
+   spin_unlock_irqrestore(&self->lock, ulFlags);
+   dev_kfree_skb(skb);
+
+   EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);	
+   return(0);
+}
+
+
+/*
+ * Function ep93xx_irda_dma_xmit(self)
+ *  
+ *    Start DMA of TX buffer.
+ *  
+ */
+static void 
+ep93xx_irda_dma_xmit(struct ep93xx_irda_cb *self)
+{
+    int i;
+#ifndef PIO_TX
+    int iResult;
+#endif    
+    unsigned long *ulDebug;
+    char *cDebug;
+		
+    EP93XX_DEBUG(1, "%s(), ---------------- Start -----------------\n", 
+        __FUNCTION__);	
+
+    //MESSAGE("DMA_TX start\n");
+    
+    /* 
+     * Disable DMA 
+     */
+    //SetDMA(self, DIR_BOTH, FALSE);
+    //self->direction = DIR_TX;
+    
+#ifdef PIO_TX   
+    ulDebug = (unsigned long *)self->tx_fifo.queue[self->tx_fifo.ptr].start;
+    cDebug = (char *)self->tx_fifo.queue[self->tx_fifo.ptr].start + 
+	    self->tx_fifo.queue[self->tx_fifo.ptr].len;
+
+    // hit the tail register if necessary
+    switch(self->tx_fifo.queue[self->tx_fifo.ptr].len % 4)
+    {
+	    case 3: cDebug -= 3;
+		    outl(*((unsigned long *)cDebug), IrDataTail1);
+		    break;
+	    case 2: cDebug -= 2;
+		    outl(*((unsigned long *)cDebug), IrDataTail2);
+		    break;
+            case 1: cDebug -= 1;
+		    outl(*((unsigned long *)cDebug), IrDataTail3);
+		    break;
+
+            default: EP93XX_DEBUG(1, "No tail data.\n");
+		    break;
+    }
+    SetDMA(self, self->direction, TRUE);
+    for(i = 0; i < (self->tx_fifo.queue[self->tx_fifo.ptr].len / 4); i++)
+    {
+	/*
+	 * Wait for a SR to be flagged.
+	 */
+ 	while(!(inb(FISR) & MFISR_TXSR))
+	{
+		mdelay(1);
+	}	
+	
+	outl(ulDebug[i], IrData);
+    }
+
+    EP93XX_DEBUG(1,"XMIT wrote %d bytes\n", 
+	    ((i * 4) + self->tx_fifo.queue[self->tx_fifo.ptr].len % 4));
+#else    
+    
+    if(self->speed <= 115200)
+    {
+        iResult = ep93xx_dma_add_buffer(self->iDMAh[DMA_SIR_TX], 
+            (unsigned int)self->tx_fifo.queue[self->tx_fifo.ptr].start, 0, 
+                self->tx_fifo.queue[self->tx_fifo.ptr].len, 0, 
+                    self->iDMAh[DMA_SIR_TX]);
+    }
+    else
+    {
+	    
+        iResult = ep93xx_dma_add_buffer(self->iDMAh[DMA_MFIR_TX], 
+            (unsigned int)self->tx_fifo.queue[self->tx_fifo.ptr].start, 0, 
+                self->tx_fifo.queue[self->tx_fifo.ptr].len, 1, 
+                    self->iDMAh[DMA_MFIR_TX]);
+    }
+	
+    if(iResult < 0)
+    {
+	EP93XX_DEBUG(1,"%s(), DMA add buffer failed (%d)\n", 
+			__FUNCTION__, iResult);
+    }
+
+    
+    /* 
+     * Enable DMA. 
+     */
+    SetDMA(self, self->direction, TRUE);
+#endif
+   
+    EP93XX_DEBUG(1, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);
+}
+
+
+/*
+ * Function ep93xx_irda_dma_xmit_complete(self)
+ *
+ *    Clean up after TX.
+ *
+ */
+static int 
+ep93xx_irda_dma_xmit_complete(struct ep93xx_irda_cb *self, int irqID)
+{
+    int ret = TRUE;
+#ifndef PIO_TX    
+    int iDMAh, iBufID, iTotalBytes;
+#endif    
+	
+    EP93XX_DEBUG(1, "%s(), ---------------- Start -----------------\n", 
+        __FUNCTION__);
+
+
+    /*
+     * Disable DMA.
+     */
+    SetDMA(self, DIR_TX, FALSE);
+    
+    /*
+     * Don't proceed until the transmitter goes idle.
+     */
+    do
+    {
+	mdelay(1); //new
+    }
+    while((inl(IrFlag) & IrFLAG_TXBUSY));
+
+#ifndef PIO_TX
+    /*
+     * Check for underrun. Due to SIP requirement and HW behavior, we'll
+     * need to check the DMA position to try and verify an underrun
+     * occured.
+     */
+    if(self->speed < 115200)
+    {
+        iDMAh = self->iDMAh[DMA_SIR_TX];
+    }
+    else
+    {
+        iDMAh = self->iDMAh[DMA_MFIR_TX];
+    }
+
+    ep93xx_dma_remove_buffer(iDMAh, &iBufID);
+    
+    ep93xx_dma_get_position(iDMAh, &iBufID, &iTotalBytes, 0);
+    
+    if((iTotalBytes < self->tx_fifo.queue[self->tx_fifo.ptr].len) && 
+		    (!(irqID & MFIIR_TXABORT)))
+    {
+	EP93XX_DEBUG(1,"TX Complete found a problem.\n");
+        self->stats.tx_errors++;
+ 	self->stats.tx_fifo_errors++;		
+    }
+    else
+    {
+
+	self->stats.tx_packets++;
+    }
+#else
+    if(!(irqID & MFIIR_TXABORT))
+    {
+	    /*
+	     * "Assume" everything went well.
+	     */
+	    self->stats.tx_packets++;
+    } 
+    else
+    {
+	    self->stats.tx_errors++;
+	    self->stats.tx_fifo_errors++;
+    }
+#endif
+    
+    /* 
+     * Check if we need to change the speed 
+     */
+    if(self->new_speed) 
+    {
+	EP93XX_DEBUG(1,"%s(), speed change queued - changing\n",
+			__FUNCTION__);
+        ep93xx_irda_change_speed(self, self->new_speed);
+	self->new_speed = 0;
+    }
+
+    /* 
+     * Finished with this frame, so prepare for next 
+     */
+    self->tx_fifo.ptr++;
+    self->tx_fifo.len--;
+
+    /* 
+     * Any frames to be sent back-to-back? 
+     */
+   if(self->tx_fifo.len) 
+   {
+	ep93xx_irda_dma_xmit(self);
+		
+	/*
+         * Not finished yet! 
+         */
+	ret = FALSE;
+   } 
+   else 
+   {	
+
+        /*
+	 * Disable TX
+	 */
+	SetIR_Transmit(FALSE); //new
+	   
+        /* 
+         * Reset Tx FIFO info 
+         */
+	self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
+	self->tx_fifo.tail = self->tx_buff.head;
+#ifndef PIO_TX
+        /*
+         * Flush the TX DMA (clears totalbytes for one thing).  
+         */
+        ep93xx_dma_flush(iDMAh);
+#endif	
+    }
+
+    /* 
+     * Make sure we have room for more frames 
+     */
+    if(self->tx_fifo.free < MAX_TX_WINDOW) 
+    {
+	/* 
+         * Not busy transmitting anymore.  Tell the network layer, 
+         * that we can accept more frames 
+         */
+	netif_wake_queue(self->netdev);
+	
+    }
+		
+
+    /*
+     * Re-start the DMA
+     */
+    //SetDMA(self, self->direction, TRUE);
+    EP93XX_DEBUG(1, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);	
+    return(ret);
+}
+
+/*
+ * Function ep93xx_irda_dma_receive (self)
+ *
+ *    Get ready to receive a frame. The device will initiate a DMA
+ *    if it starts to receive a frame.
+ *
+ */
+static int 
+ep93xx_irda_dma_receive(struct ep93xx_irda_cb *self) 
+{
+    int iResult;
+
+    EP93XX_DEBUG(2, "%s(), ---------------- Start -----------------\n", 
+        __FUNCTION__);
+
+    /* 
+     * Reset the Tx FIFO info 
+     */
+    self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
+    self->tx_fifo.tail = self->tx_buff.head;
+		
+    /* 
+     * Disable DMA until we're ready.
+     */
+    SetDMA(self, DIR_RX, FALSE);
+
+		
+    /* 
+     * Reset Rx FIFO info 
+     */
+    self->direction = DIR_RX;
+    self->rx_buff.data = self->rx_buff.head;
+		
+    /* 
+     * Reset Rx FIFO 
+     */
+    self->st_fifo.len = self->st_fifo.pending_bytes = 0;
+    self->st_fifo.tail = self->st_fifo.head = 0;
+    
+    /*
+     * Add the buffer to the DMA queue.
+     */
+    iResult = ep93xx_dma_add_buffer(self->iDMAh[DMA_MFIR_RX], 
+		    (unsigned int)self->rx_buff.data, 0, 
+		    	self->rx_buff.truesize, 1, self->iDMAh[DMA_MFIR_RX]);
+
+    if(iResult < 0)
+    {
+	EP93XX_DEBUG(1,"DMARx failed to add buffer\n");
+    }
+
+    /* 
+     * Enable RX & DMA
+     */
+    SetIR_Receive(TRUE);
+    SetDMA(self, DIR_RX, TRUE);
+
+    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);
+    return(0);
+}
+
+
+/*
+ * Function ep93xx_irda_dma_receive_complete(self, size)
+ *
+ *    Check for complete frame.  Massage as needed and
+ *    put it on the stack if it's "good".
+ *
+ */
+static int 
+ep93xx_irda_dma_receive_complete(struct ep93xx_irda_cb *self, 
+		unsigned int frameSize)
+{
+    struct st_fifo *st_fifo;
+    struct sk_buff *skb;
+    int iDMAh, iBufID, iTotalBytes;	
+    
+    EP93XX_DEBUG(2, "%s(), ---------------- Start -----------------\n", 
+        __FUNCTION__);
+    
+    /*
+     * Stop DMA.
+     */  
+    SetDMA(self, self->direction, FALSE);
+    
+    st_fifo = &self->st_fifo;		
+
+    iDMAh = self->iDMAh[DMA_MFIR_RX];
+    if(ep93xx_dma_remove_buffer(iDMAh, &iBufID) == -EINVAL)
+    {
+	EP93XX_DEBUG(1, "DMARx failed to remove buffer?\n");
+    }
+   
+    if(ep93xx_dma_get_position(iDMAh, &iBufID, &iTotalBytes, 0) == -EINVAL)
+    {
+        /*
+         * This can currently only happen if the handle is bad.
+         */
+	ERROR("%s(), ********* DMA_GET_POS FAILED *********\n", 
+            __FUNCTION__);
+    }
+
+    /*
+     * Flush the channel.
+     */
+    ep93xx_dma_flush(iDMAh);
+    
+    if((frameSize > 2047) && (self->speed > 115200))
+    {
+        /*
+         * By IrDA protocol, this is invalid.
+         */
+	EP93XX_DEBUG(1, "%s(), *******Rx frame size > 2047!****** \n", 
+			__FUNCTION__);
+    
+        self->stats.rx_errors++;
+	self->rx_buff.data += frameSize;
+        return(FALSE);
+    }
+
+    skb = dev_alloc_skb(frameSize+1);
+    if(skb == NULL)  
+    {
+	WARNING("%s(), memory squeeze, dropping frame.\n", 
+               __FUNCTION__);
+   	self->stats.rx_dropped++;
+  	return(FALSE);
+    }
+	
+    /* 
+     * Make sure IP header gets aligned 
+     */
+    skb_reserve(skb, 1); 
+
+    /* 
+     * HW does not stuff CRC32 into RX buffer.
+     */
+     skb_put(skb, frameSize);
+     memcpy(skb->data, self->rx_buff.data, frameSize);
+
+     /* 
+      * Move to next frame 
+      */
+     self->rx_buff.data += frameSize;
+     self->stats.rx_bytes += frameSize;
+     self->stats.rx_packets++;
+
+     skb->dev = self->netdev;
+     skb->mac.raw  = skb->data;
+     skb->protocol = htons(ETH_P_IRDA);
+     netif_rx(skb);       
+
+     //mdelay(5);
+
+     EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);	
+     return(TRUE);
+}
+
+/*
+ * Function ep93xx_irda_net_ioctl(dev, rq, cmd)
+ *
+ *    Process IOCTL commands for this device.
+ *
+ */
+static int 
+ep93xx_irda_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{ 
+    struct if_irda_req *irq = (struct if_irda_req *) rq;
+    struct ep93xx_irda_cb *self;
+    unsigned long ulFlags;
+    int iRet = 0;
+	
+    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+	
+    ASSERT(dev != NULL, return -1;);
+
+    self = dev->priv;
+
+    ASSERT(self != NULL, return -1;);
+
+    EP93XX_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
+	
+    switch(cmd) 
+    {
+	
+        case SIOCSBANDWIDTH: 
+            {
+                /* Set bandwidth */
+	        EP93XX_DEBUG(1, "%s(), SIOCSBANDWIDTH\n", __FUNCTION__);
+	        /* Root only */
+	        if (!capable(CAP_NET_ADMIN))
+               	{
+		        return(-EPERM);
+               	}
+	        ep93xx_irda_change_speed(self, irq->ifr_baudrate);		
+	        break;
+            }
+
+	    case SIOCSMEDIABUSY: 
+            {
+                /* Set media busy */
+	        EP93XX_DEBUG(2, "%s(), SIOCSMEDIABUSY\n", __FUNCTION__);
+	        if (!capable(CAP_NET_ADMIN))
+                {
+		        return(-EPERM);
+                }
+	        irda_device_set_media_busy(self->netdev, TRUE);
+	        break;
+            }
+
+	    case SIOCGRECEIVING: 
+            {
+                /* Check if we are receiving right now */
+	        EP93XX_DEBUG(2, "%s(), SIOCGRECEIVING - %d\n", __FUNCTION__, 
+					self->speed);
+	        /* Is it really needed ? And what about spinlock ? */
+	        save_flags(ulFlags);
+	        cli();	
+
+	        irq->ifr_receiving = ep93xx_irda_is_receiving(self);
+	        restore_flags(ulFlags);
+	        break;
+            }
+
+	    default:
+            {
+		        iRet = -EOPNOTSUPP;
+            }
+    }
+
+    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);	
+	
+    return(iRet);
+}
+
+
+/*
+ * Function ep93xx_irda_is_receiving(self)
+ *
+ *    Return TRUE is we are currently receiving a frame
+ *
+ */
+static int 
+ep93xx_irda_is_receiving(struct ep93xx_irda_cb *self)
+{
+    unsigned long ulFlags;
+    int iStatus = FALSE;
+	
+    EP93XX_DEBUG(2, "%s(), ---------------- Start -----------------\n", 
+        __FUNCTION__);
+	
+    ASSERT(self != NULL, return FALSE;);
+
+    spin_lock_irqsave(&self->lock, ulFlags);
+
+    if(self->speed > 115200) 
+    {
+    	EP93XX_DEBUG(1, "%s(), check MFIR.\n", __FUNCTION__);
+ 	if((inl(IrFlag) & IrFLAG_RXINFRM) != 0) 		
+	{
+		/* 
+		 * We are receiving something 
+		 */
+		EP93XX_DEBUG(1, "%s(), We are receiving something\n", 
+                		__FUNCTION__);
+		iStatus = TRUE;
+	}
+    } 
+    else
+    { 
+	iStatus = (self->rx_buff.state != OUTSIDE_FRAME);
+    }
+	
+    spin_unlock_irqrestore(&self->lock, ulFlags);
+
+    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);
+	
+    return(iStatus);
+}
+
+
+/*
+ * Function ep93xx_irda_net_get_stats(dev)
+ *
+ *    Return stats structure.
+ *
+ */
+static struct net_device_stats *
+ep93xx_irda_net_get_stats(struct net_device *dev)
+{
+    struct ep93xx_irda_cb *self = (struct ep93xx_irda_cb *) dev->priv;
+	
+    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+		
+    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);
+	
+    return(&self->stats);
+}
+
+#ifdef POWER_SAVING
+/*
+ * Function ep93xx_irda_suspend(self)
+ *
+ *    Called by the OS to indicate the system
+ *    is being suspended for PM.  Shut our hardware
+ *    down.
+ *
+ */
+static void 
+ep93xx_irda_suspend(struct ep93xx_irda_cb *self)
+{
+    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+	
+    MESSAGE("%s, Suspending\n", driver_name);
+
+    if(self->suspended)
+    {
+	return;
+    }
+
+    ep93xx_irda_net_close(self->netdev);
+
+    self->suspended = 1;
+	
+    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);	
+}
+
+
+/*
+ * Function ep93xx_irda_wakeup(self)
+ *
+ *    Called by the OS to indicate a resume from suspend is taking place.
+ *    Awaken the hardware. 
+ *
+ */
+static void 
+ep93xx_irda_wakeup(struct ep93xx_irda_cb *self)
+{
+    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+	
+    if(!self->suspended)
+    {
+	return;
+    }
+	
+    ep93xx_irda_net_open(self->netdev);
+	
+    MESSAGE("%s, Waking up\n", driver_name);
+
+    self->suspended = 0;
+	
+    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);
+}
+
+/*
+ * Function ep93xx_irda_pmproc(dev, rqst, data)
+ *
+ * Registered power management callback procedure.
+ *
+ */
+static int 
+ep93xx_irda_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data)
+{
+    struct ep93xx_irda_cb *self = (struct ep93xx_irda_cb*) dev->data;
+        
+    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+            __FUNCTION__);
+	
+    if(self) 
+    {
+	    switch(rqst) 
+            {
+		    case PM_SUSPEND:
+                        {
+                            ep93xx_irda_suspend(self);
+                            break;
+                        }
+                    case PM_RESUME:
+                        {
+                            ep93xx_irda_wakeup(self);
+                            break;
+                        }
+            }
+    }
+        
+    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+            __FUNCTION__);	
+        
+    return(0);
+}
+#endif
+
+/*
+ * Function SetInterrupts
+ *
+ *    Sets interrupts on/off based on speed and boolean.
+ *    A boolean value of TRUE turns on interrupts for 
+ *    the hardware that manages that IR speed.  FALSE turns them off.
+ *
+ */
+static void 
+SetInterrupts(struct ep93xx_irda_cb *self, unsigned char enable)
+{
+	
+    unsigned char ucRegVal = 0, ucRegMask = 0;
+    unsigned long ulRegAddr, ulRegAddr2;
+
+    EP93XX_DEBUG(2, "%s(), ----------- Start -----------\n", 
+        __FUNCTION__);	
+
+    EP93XX_DEBUG(2, "%s(), IRQs enable = %d, speed = %d\n", __FUNCTION__, 
+		    enable, self->speed);
+    
+
+    if(self->speed <= 115200)
+    {
+        /* Action on IRQs in SIR mode */
+        ulRegAddr = UART2CR;
+        ucRegVal = inl(ulRegAddr);
+
+	 
+	if(self->direction & DIR_TX)
+	{
+		ucRegMask |= U2CR_TxIrq;
+	} 
+	
+	if(self->direction & DIR_RX)
+	{
+		ucRegMask |= U2CR_RxIrq;
+	}
+	
+        if(enable)
+        {
+	    ucRegVal &= (char)~(U2CR_RxIrq|U2CR_TxIrq);	
+            ucRegVal |= (char)(ucRegMask);
+        }
+        else
+        {
+            ucRegVal &= (char)~(ucRegMask);
+        }
+    }
+    else
+    {
+	ucRegMask = 0;
+        if(self->speed <= 1152000)
+        {
+            /*
+             * Action on IRQs in MIR mode 
+             */
+            ulRegAddr = MIMR;
+	    ulRegAddr2 = MISR;
+        }
+        else
+        {
+            /* 
+             * Action on IRQs in FIR mode     
+             */     
+            ulRegAddr = FIMR;
+	    ulRegAddr2 = FISR;
+        }
+
+	if(self->direction & DIR_TX)
+	{
+		ucRegMask |= (MFIMR_TXABORT|MFIMR_TXFC);
+	}
+
+	if(self->direction & DIR_RX)
+	{
+		ucRegMask |= (MFIMR_RXFL|MFIMR_RXFC);
+	}
+	
+        /*
+         * Bit mask is the same for MIR/FIR.
+         */
+        if(enable)
+        {
+            ucRegVal |= (char)(ucRegMask);
+
+	    /*
+	     * Clear sticky bits before turning on IRQs
+	     */
+	    outl(MFISR_TXFC|MFISR_TXFABORT|MFISR_RXIL|MFISR_RXFL, ulRegAddr2);
+	    inl(ulRegAddr2);
+	    inl(IrRIB);
+        }
+        else
+        {
+            /*
+             * M/FIR IRQ registers only have IRQ related bits, safe
+             * to blast them therefore.
+             */
+            ucRegVal = 0;
+        }
+    }
+
+    outl(ucRegVal, ulRegAddr);
+      
+    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);	
+}
+
+static void 
+SetIR_Transmit(unsigned char ucEnable)
+{
+	unsigned long ulRegVal;
+	
+	ulRegVal = inb(IrCtrl);
+
+	if(ucEnable)
+	{
+		if(ulRegVal & IrCONTROL_TXON)
+		{
+			return;
+		}
+		else
+		{
+			outb(ulRegVal|IrCONTROL_TXON, IrCtrl);
+		}
+	}
+	else
+	{
+		if(!(ulRegVal & IrCONTROL_TXON))
+		{
+			return;
+		}
+		else
+		{
+			outb(ulRegVal&~(IrCONTROL_TXON), IrCtrl);
+		}
+
+	}
+}
+
+
+/*
+ * Function SetIR_Receive()
+ *
+ * 	Enables OR Disables RX & RXRP in IrCtrl based on
+ * 	supplied boolean.
+ */
+static void
+SetIR_Receive(unsigned char ucEnable)
+{
+	unsigned long ulRegVal;
+
+	ulRegVal = inb(IrCtrl);
+
+	if(ucEnable)
+	{
+		if((ulRegVal & (IrCONTROL_RXON|IrCONTROL_RXRP)) == 
+				(IrCONTROL_RXON|IrCONTROL_RXRP))
+		{
+			return;
+		}
+		else
+		{
+			outb(ulRegVal|IrCONTROL_RXON|IrCONTROL_RXRP, IrCtrl);
+		}
+	}
+	else
+	{
+		if(!(ulRegVal & (IrCONTROL_RXON & IrCONTROL_RXRP)))
+		{
+			return;
+		}
+		else
+		{
+			outb(ulRegVal&~(IrCONTROL_RXON|IrCONTROL_RXRP), 
+					IrCtrl);
+		}
+	}
+}
+
+
+/*
+ * Function SetDMA()
+ *
+ *    Enables or disables DMA  capability for current speed.
+ *    'enable' parameter determines action. Direction 
+ *    determines tx and/or rx DMA.
+ *
+ */
+static void
+SetDMA(struct ep93xx_irda_cb *self, unsigned char direction, 
+         unsigned char enable)
+{
+    int iRegVal, iDMARegVal;
+ 
+    
+    if(self->speed <= 115200)
+    {
+	/*
+	 * SIR section.  No DMA for SIR at this time.
+	 */
+        if(direction == DIR_RX)
+	{
+
+	}
+	else
+	{
+
+	}	
+    }
+    else
+    {    
+	 /*
+	  * MFIR Section
+	  */
+   
+	 /*
+	  * Read in current value.
+	  */
+	 iRegVal = iDMARegVal = inb(IrDMACR);
+      	 
+	 if(direction & DIR_RX)
+	 {
+		if(enable)
+		{
+			iRegVal |= IrDMACR_DMARXE;
+		}
+		else
+		{
+			iRegVal &= ~(IrDMACR_DMARXE);
+		}
+	 }
+	 
+	 if(direction & DIR_TX)
+	 {
+		 if(enable)
+		 {
+#ifndef PIO_TX			 
+			 iRegVal |= IrDMACR_DMATXE;
+#endif			 
+		 }
+		 else
+		 {
+#ifndef PIO_TX			 
+			 iRegVal &= ~(IrDMACR_DMATXE);
+#endif			 
+		 }
+	 }	 
+
+	 /*
+	  * Start or stop DMA engine, and update controlling registers
+	  * as appropriate.
+	  */	 
+	 if(enable)
+	 {	
+		if(direction & DIR_RX)
+		{
+			ep93xx_dma_start(self->iDMAh[DMA_MFIR_RX],1,0);
+			if(iRegVal != iDMARegVal)
+			{
+				outb(iRegVal, IrDMACR);
+			}
+		}
+
+		if(direction & DIR_TX)
+		{
+#ifndef PIO_TX		
+			if(iRegVal != iDMARegVal)
+			{	
+				outb(iRegVal, IrDMACR);
+			}
+			ep93xx_dma_start(self->iDMAh[DMA_MFIR_TX],1,0);
+#endif			
+		}
+	 }
+	 else
+	 { 
+		if(direction & DIR_RX)
+		{
+			ep93xx_dma_pause(self->iDMAh[DMA_MFIR_RX],1,0);
+			if(iRegVal != iDMARegVal)
+			{
+				outb(iRegVal, IrDMACR);
+			}
+		}
+
+		if(direction & DIR_TX)
+		{
+#ifndef PIO_TX			
+			ep93xx_dma_pause(self->iDMAh[DMA_MFIR_TX],1,0);
+			if(iRegVal != iDMARegVal)
+			{
+				outb(iRegVal, IrDMACR);
+			}
+#endif
+		}
+	 }
+
+#ifdef DEBUG	
+	 if(iRegVal != iDMARegVal)
+	 {
+		 EP93XX_DEBUG(1, "%s(), IrDMACR = 0x%x\n", 
+			 __FUNCTION__, inb(IrDMACR));
+	 }
+#endif	 
+    }
+}
+
+
+/*
+ * Function SIR2MFIR(self, TargetSpeed)
+ *
+ *    Reconfigures hardware for MIR/FIR transactions.
+ *
+ */
+static void 
+SIR2MFIR(struct ep93xx_irda_cb *self, __u32 TargetSpeed)
+{
+    unsigned long ulRegVal, ulReg, ulRegSR;
+		
+    EP93XX_DEBUG(2, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+    /*
+     * Suspend IrDA block
+     */
+    outb(0, IrCtrl);
+    
+    /*
+     * Now safe to disable, so disable IrDA block.
+     */
+    outb(0, IrEnable);
+    
+    /*
+     * Disable UART2, and clear CTRL registers.
+     */
+    outb(0, UART2CR);
+          
+    /*
+     * Disable private DMA for SIR/UART2.
+     */
+    SetDMA(self, DIR_BOTH, FALSE);
+
+    /*
+     * Need a slight delay, when IrENABLE gets set it may
+     * generate a SIP signal.  Give the target of our last
+     * SIR TX a chance to process before then.
+     */
+    mdelay(10);
+
+    /*
+     * Set IrDA enc/dec to MIR/FIR (based on target speed).
+     */
+    if(TargetSpeed < 4000000)
+    {
+        /* 
+         * MIR - enable MIR mode
+         */
+        outl(IrENABLE_MIR, IrEnable);
+
+        /* 
+         * set the MIR bit rate 
+         */
+        if(TargetSpeed == 1152000)
+        {
+            outb(IrCONTROL_MIRBR, IrCtrl);
+        }
+            
+        ulRegSR = MISR;
+    }
+    else
+    {
+	    
+        /* 
+         * FIR - turn on FIR clk, enable FIR mode 
+	 */
+	ulRegVal = inl(SYSCON_PWRCNT);
+	outl((ulRegVal | SYSCON_PWRCNT_FIREN), SYSCON_PWRCNT);
+	    
+        outb(IrENABLE_FIR, IrEnable);
+        
+        ulRegSR = FISR;
+    }
+
+    /*
+     * Clear sticky bits and clear RFC.
+     */
+    outl(MFISR_TXFC|MFISR_TXFABORT|MFISR_RXIL|MFISR_RXFL, ulRegSR);
+    inl(ulRegSR);
+    inl(IrRIB);
+ 
+    /*
+     * Enable IRQs.
+     */
+    if(TargetSpeed < 4000000)
+    {
+	ulReg = MIMR;
+    }
+    else
+    {
+	ulReg = FIMR;
+    }
+    ulRegVal = MFIMR_RXFL | MFIMR_RXIL| MFIMR_RXFC | MFIMR_RXFS;
+    outb(ulRegVal, ulReg);
+ 
+    /*
+     * Enable private DMA access.
+     */
+    //outb(IrDMACR_DMARXE, IrDMACR);
+    //self->direction |= DIR_RX;
+ 
+    /*
+     * Enable Tx/Rx.  This should result in a SIP broadcast, which should buy
+     * us 500ms to get ready.
+     */
+    //outb(IrCONTROL_RXRP|IrCONTROL_RXON, IrCtrl); // new
+   SetIR_Receive(TRUE);
+    
+    EP93XX_DEBUG(1, "IrEnable = 0x%x, IrCtrl = 0x%x, M/FISR = 0x%x\n", 
+    				inb(IrEnable), inb(IrCtrl), inl(ulRegSR));
+				
+    EP93XX_DEBUG(1,"M/FIMR = 0x%x, PWRCNT = 0x%x, DEVCFG = 0x%x\n", 
+    		inb(ulReg), inl(SYSCON_PWRCNT), inl(SYSCON_DEVCFG));
+			
+    EP93XX_DEBUG(2, "IrAdrMatchVal = 0x%x\n", inb(IrAdrMatchVal));
+    EP93XX_DEBUG(2, "IrFlag = 0x%x\n", inw(IrFlag));
+    EP93XX_DEBUG(2, "IrData = 0x%x\n", inl(IrData));
+    EP93XX_DEBUG(2, "IrRIB = 0x%x\n", inw(IrRIB));
+    EP93XX_DEBUG(2, "IrTR0 = 0x%x\n", inw(IrTR0));
+    EP93XX_DEBUG(2, "IrDMACR = 0x%x\n", inb(IrDMACR));
+    EP93XX_DEBUG(2, "SIRTR0 = 0x%x\n", inb(SIRTR0));
+    EP93XX_DEBUG(2, "MISR = 0x%x\n", inb(MISR));
+    EP93XX_DEBUG(2, "MIMR = 0x%x\n", inb(MIMR));
+    EP93XX_DEBUG(2, "MIIR = 0x%x\n", inb(MIIR));
+    EP93XX_DEBUG(2, "FISR = 0x%x\n", inb(FISR));
+    EP93XX_DEBUG(2, "FIMR = 0x%x\n", inb(FIMR));
+    EP93XX_DEBUG(2, "FIIR = 0x%x\n", inb(FIIR));
+
+
+    EP93XX_DEBUG(2, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);	
+}
+
+
+/*
+ * Function MFIR2SIR(self, TargetSpeed)
+ *
+ *    Reconfigures hardware for SIR transactions.
+ *
+ */
+static void 
+MFIR2SIR(struct ep93xx_irda_cb *self, __u32 TargetSpeed)
+{
+    unsigned long ulRegVal;
+    	
+    EP93XX_DEBUG(1, "%s(), ---------------- Start ----------------\n", 
+        __FUNCTION__);
+     
+    /*
+     * Disable all interrupts.
+     */
+    ulRegVal = self->direction;
+    self->direction = DIR_BOTH;
+    SetInterrupts(self, FALSE);
+    self->direction = ulRegVal;
+   
+    if(self->speed == 4000000)
+    {
+	    ulRegVal = inl(SYSCON_PWRCNT);
+	    ulRegVal &= ~(SYSCON_PWRCNT_FIREN);
+	    outl(ulRegVal, SYSCON_PWRCNT);
+    }
+    
+    /*
+     * Disable MIR/FIR private DMA and stop IrDA block.
+     */
+    outl(0, IrCtrl);
+    SetDMA(self, DIR_BOTH, FALSE);
+
+    /*
+    * Enable SIR in IR block.
+    */
+    outl(IrENABLE_SIR, IrEnable);
+    
+    /*
+     * Make certain DEVCFG is set as we need it.
+     */
+    ulRegVal = inl(SYSCON_DEVCFG);
+    SysconSetLocked(SYSCON_DEVCFG, (ulRegVal | 
+			    (SYSCON_DEVCFG_U2EN | SYSCON_DEVCFG_IonU2)));
+   
+   /*
+    * Enable SIR & UART on UART2 block.
+    */ 
+   outb(U2CR_SIR|U2CR_UART, UART2CR); 
+  
+    /*
+     * Enable SIR/UART2 private DMA.
+     */
+    //outl(U2DMACR_TXDMA|U2DMACR_RXDMA, UART2DMACR);
+   	
+    EP93XX_DEBUG(1, "%s(), ----------------- End ------------------\n", 
+        __FUNCTION__);
+}
+
+#ifdef MODULE
+MODULE_AUTHOR("Cirrus Logic, Inc.");
+MODULE_DESCRIPTION("EP93xx IrDA Driver");
+MODULE_LICENSE("GPL");
+
+
+MODULE_PARM(irq, "1-4i");
+MODULE_PARM_DESC(irq, "IRQ lines");
+MODULE_PARM(dma, "1-4i");
+MODULE_PARM_DESC(dma, "DMA channels");
+
+int init_module(void)
+{
+	return(ep93xx_irda_init());	
+}
+
+void cleanup_module(void)
+{
+	ep93xx_irda_cleanup();
+}
+#endif /* MODULE */
diff -urN linux-2.4.29/drivers/net/irda/ep93xx_sir.c linux-2.4.29-uc1/drivers/net/irda/ep93xx_sir.c
--- linux-2.4.29/drivers/net/irda/ep93xx_sir.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/irda/ep93xx_sir.c	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,181 @@
+/*
+ * SIR IR port driver for the Cirrus Logic EP93xx.
+ *
+ * SIR on the EP93xx hangs off of UART2 so this is emplemented
+ * as a dongle driver.
+ *
+ * Copyright 2003 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/module.h>
+#include <linux/delay.h>
+#include <linux/tty.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <net/irda/irda.h>
+#include <net/irda/irmod.h>
+#include <net/irda/irda_device.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/hardware/serial_amba.h>
+
+
+#undef DEBUG
+//#define DEBUG 1
+#ifdef DEBUG
+#define DPRINTK( x... )  printk( ##x )
+#else
+#define DPRINTK( x... )
+#endif
+
+
+/*
+ * We need access to the UART2 control register so we can
+ * do a read-modify-write and enable SIR.
+ */
+
+static void ep93xx_sir_open(dongle_t *self, struct qos_info *qos);
+static void ep93xx_sir_close(dongle_t *self);
+static int  ep93xx_sir_change_speed(struct irda_task *task);
+static int  ep93xx_sir_reset(struct irda_task *task);
+
+static struct dongle_reg dongle = {
+    Q_NULL,
+    IRDA_EP93XX_SIR,
+    ep93xx_sir_open,
+    ep93xx_sir_close,
+    ep93xx_sir_reset,
+    ep93xx_sir_change_speed
+};
+
+
+static void ep93xx_sir_open(dongle_t *self, struct qos_info *qos)
+{
+    unsigned int uiTemp;
+
+    DPRINTK("----------------\n ep93xx_sir_open \n-----------------\n");
+    
+    /* 
+     * Set UART2 to be an IrDA interface
+     */
+    uiTemp = inl(SYSCON_DEVCFG);
+    SysconSetLocked(SYSCON_DEVCFG, (uiTemp | SYSCON_DEVCFG_IonU2) );
+    
+    /*
+     * Set the pulse width.
+     */
+    //uiTemp = inl(UART2ILPR);
+	outl( 3, UART2ILPR );
+
+    /*
+     * Set SIREN bit in UART2 - this enables the SIR encoder/decoder.
+     */
+    uiTemp = inl(UART2CR);
+    outl( (uiTemp | AMBA_UARTCR_SIREN), UART2CR );
+
+    /*
+     * Enable Ir in SIR mode.
+     */
+    /* Write the reg twice because of the IrDA errata.  */
+	outl( IrEnable_EN_SIR, IrEnable );
+	outl( IrEnable_EN_SIR, IrEnable );
+    
+
+    MOD_INC_USE_COUNT;
+}
+
+static void ep93xx_sir_close(dongle_t *self)
+{
+    unsigned int uiTemp;
+
+    DPRINTK("----------------\n ep93xx_sir_close \n-----------------\n");
+
+    /*
+     * Disable Ir.
+     */
+     /* for now, don't write irda regs due to errata. */
+	//outl( IrEnable_EN_NONE, IrEnable );
+
+    /* 
+     * Set UART2 to be an UART
+     */
+    uiTemp = inl( SYSCON_DEVCFG );
+    SysconSetLocked(SYSCON_DEVCFG, (uiTemp & ~(SYSCON_DEVCFG_IonU2)) );
+
+    MOD_DEC_USE_COUNT;
+}
+
+/*
+ * Function ep93xx_sir_change_speed (task)
+ *
+ *   Change speed of the EP93xx I/R port. We don't have to do anything
+ *   here as long as the rate is being changed at the serial port
+ *   level.  irtty.c should take care of that.
+ */
+static int ep93xx_sir_change_speed(struct irda_task *task)
+{
+    DPRINTK("----------------\n ep93xx_sir_change_speed \n-----------------\n");
+    irda_task_next_state(task, IRDA_TASK_DONE);
+    return 0;
+}
+
+/*
+ * Function ep93xx_sir_reset (task)
+ *
+ *      Reset the EP93xx IrDA. We don't really have to do anything.
+ *
+ */
+static int ep93xx_sir_reset(struct irda_task *task)
+{
+    DPRINTK("----------------\n ep93xx_sir_reset \n-----------------\n");
+    irda_task_next_state(task, IRDA_TASK_DONE);
+    return 0;
+}
+
+/*
+ * Function ep93xx_sir_init(void)
+ *
+ *    Initialize EP93xx IrDA block in SIR mode.
+ *
+ */
+int __init ep93xx_sir_init(void)
+{
+    DPRINTK("----------------\n ep93xx_sir_init \n-----------------\n");
+	return irda_device_register_dongle(&dongle);
+}
+
+/*
+ * Function ep93xx_sir_cleanup(void)
+ *
+ *    Cleanup EP93xx IrDA module
+ *
+ */
+static void __exit ep93xx_sir_cleanup(void)
+{
+    DPRINTK("----------------\n ep93xx_sir_cleanup \n-----------------\n");
+    irda_device_unregister_dongle(&dongle);
+}
+
+MODULE_DESCRIPTION("EP93xx SIR IrDA driver");
+MODULE_LICENSE("GPL");
+        
+#ifdef MODULE
+module_init(ep93xx_sir_init);
+module_exit(ep93xx_sir_cleanup);
+#endif
diff -urN linux-2.4.29/drivers/net/irda/Makefile linux-2.4.29-uc1/drivers/net/irda/Makefile
--- linux-2.4.29/drivers/net/irda/Makefile	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/irda/Makefile	2005-06-14 02:12:13.000000000 +0100
@@ -34,5 +34,7 @@
 obj-$(CONFIG_MCP2120_DONGLE)	+= mcp2120.o
 obj-$(CONFIG_ACT200L_DONGLE)	+= act200l.o
 obj-$(CONFIG_MA600_DONGLE)	+= ma600.o
+obj-$(CONFIG_EP93XX_SIR)	+= ep93xx_sir.o
+obj-$(CONFIG_EP93XX_IRDA)	+= ep93xx_irda.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/net/irda/w83977af_ir.c linux-2.4.29-uc1/drivers/net/irda/w83977af_ir.c
--- linux-2.4.29/drivers/net/irda/w83977af_ir.c	2002-11-28 23:53:13.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/irda/w83977af_ir.c	2005-06-14 02:12:13.000000000 +0100
@@ -205,7 +205,7 @@
 
 	/* FIXME: The HP HDLS-1100 does not support 1152000! */
 	self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
-		IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8);
+		IR_115200/*|IR_576000|IR_1152000|(IR_4000000 << 8)*/;
 
 	/* The HP HDLS-1100 needs 1 ms according to the specs */
 	self->qos.min_turn_time.bits = qos_mtt_bits;
@@ -1339,7 +1339,12 @@
 	
 	switch (cmd) {
 	case SIOCSBANDWIDTH: /* Set bandwidth */
-		if (!capable(CAP_NET_ADMIN)) {
+		/*
+		 * This function will also be used by IrLAP to change the
+		 * speed, so we still must allow for speed change within
+		 * interrupt context.
+		 */
+		if (!in_interrupt() && !capable(CAP_NET_ADMIN)) {
 			ret = -EPERM;
 			goto out;
 		}
diff -urN linux-2.4.29/drivers/net/isl3893eth.c linux-2.4.29-uc1/drivers/net/isl3893eth.c
--- linux-2.4.29/drivers/net/isl3893eth.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/isl3893eth.c	2005-06-14 02:12:15.000000000 +0100
@@ -0,0 +1,669 @@
+/* isl3893.c: ISL3893 Direct Ethernet driver (bypassing MVC).
+ *
+ * Based on skeleton ethernet driver by Donald Becker.
+ * 
+ * Copyright 1993 United States Government as represented by the
+ * Director, National Security Agency.
+ *
+ * Modified by Arlet Ottens 2001.
+ * Modified by M. Thuys, Copyright (C) 2002 Intersil Americas Inc.
+ *
+ */
+
+static const char *version = "ISL3893 direct ethernet\n";
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <linux/errno.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+/****************************************************************************
+ * Ethernet defines. Since this is a temporary driver, we put them here and
+ * not in a nice header file. This way, the stuff can be removed by deleting
+ * one file
+ ****************************************************************************/
+
+/* - CTRL */
+#define	ETHCTRL				(0x0)
+#define	ETHCTRLHBD			(0x10000000)
+#define	ETHCTRLPS			(0x8000000)
+#define	ETHCTRLDRO			(0x800000)
+#define	ETHCTRLFDLBM			(0x200000)
+#define	ETHCTRLFDM			(0x100000)
+#define	ETHCTRLPM			(0x80000)
+#define	ETHCTRLPR			(0x40000)
+#define	ETHCTRLPB			(0x10000)
+#define	ETHCTRLHOF			(0x8000)
+#define	ETHCTRLIFE			(0x2000)
+#define	ETHCTRLLCC			(0x1000)
+#define	ETHCTRLDBP			(0x800)
+#define	ETHCTRLDRTY			(0x400)
+#define	ETHCTRLASTP			(0x100)
+#define	ETHCTRLBOLMT			(0xc0)
+#define	ETHCTRLBOLMTShift		(0x6)
+#define	ETHCTRLDC			(0x20)
+#define	ETHCTRLTE			(0x8)
+#define	ETHCTRLRE			(0x4)
+#define	ETHCTRLMask			(0x18bdbdec)
+#define	ETHCTRLAccessType		(RW)
+#define	ETHCTRLInitialValue		(0x40000)
+#define	ETHCTRLTestMask			(0x18bdbdec)
+
+/* - MAHR */
+#define	ETHMAHR				(0x4)
+#define	ETHMAHRMAH			(0xffff)
+#define	ETHMAHRMAHShift			(0x0)
+#define	ETHMAHRMask			(0xffff)
+#define	ETHMAHRAccessType		(RW)
+#define	ETHMAHRInitialValue		(0xffff)
+#define	ETHMAHRTestMask			(0xffff)
+
+/* - MALR */
+#define	ETHMALR				(0x8)
+#define	ETHMALRMAL			(0x0)
+#define	ETHMALRMALShift			(0x0)
+#define	ETHMALRMask			(0x0)
+#define	ETHMALRAccessType		(RW)
+#define	ETHMALRInitialValue		(0xffffffff)
+#define	ETHMALRTestMask			(0x0)
+
+/* - MHTHR */
+#define	ETHMHTHR			(0xc)
+#define	ETHMHTHRHTH			(0x0)
+#define	ETHMHTHRHTHShift		(0x0)
+#define	ETHMHTHRMask			(0x0)
+#define	ETHMHTHRAccessType		(RW)
+#define	ETHMHTHRInitialValue		(0x0)
+#define	ETHMHTHRTestMask		(0x0)
+
+/* - MHTLR */
+#define	ETHMHTLR			(0x10)
+#define	ETHMHTLRHTL			(0x0)
+#define	ETHMHTLRHTLShift		(0x0)
+#define	ETHMHTLRMask			(0x0)
+#define	ETHMHTLRAccessType		(RW)
+#define	ETHMHTLRInitialValue		(0x0)
+#define	ETHMHTLRTestMask		(0x0)
+
+/* - MIIAR */
+#define	ETHMIIAR			(0x14)
+#define	ETHMIIARTestMask		(0xffc2)
+#define	ETHMIIARPHYADR			(0xf800)
+#define	ETHMIIARPHYADRShift		(0xb)
+#define	ETHMIIARMIIADR			(0x7c0)
+#define	ETHMIIARMIIADRShift		(0x6)
+#define	ETHMIIARMIIWR			(0x2)
+#define	ETHMIIARMIIBUSY			(0x1)
+#define	ETHMIIARMask			(0xffc3)
+#define	ETHMIIARAccessType		(RW)
+#define	ETHMIIARInitialValue		(0x0)
+
+/* - MIIDR */
+#define	ETHMIIDR			(0x18)
+#define	ETHMIIDRPHYDATA			(0xffff)
+#define	ETHMIIDRPHYDATAShift		(0x0)
+#define	ETHMIIDRMask			(0xffff)
+#define	ETHMIIDRAccessType		(RW)
+#define	ETHMIIDRInitialValue		(0x0)
+#define	ETHMIIDRTestMask		(0xffff)
+
+/* - FCR */
+#define	ETHFCR				(0x1c)
+#define	ETHFCRTestMask			(0xffff0006)
+#define	ETHFCRPTIME			(0xfff80000)
+#define	ETHFCRPTIMEShift		(0x13)
+#define	ETHFCRPCP			(0x4)
+#define	ETHFCRFCE			(0x2)
+#define	ETHFCRFCB			(0x1)
+#define	ETHFCRMask			(0xfff80007)
+#define	ETHFCRAccessType		(RW)
+#define	ETHFCRInitialValue		(0x0)
+
+/* - VLAN1R */
+#define	ETHVLAN1R			(0x20)
+#define	ETHVLAN1RVLAN1			(0xffff)
+#define	ETHVLAN1RVLAN1Shift		(0x0)
+#define	ETHVLAN1RMask			(0xffff)
+#define	ETHVLAN1RAccessType		(RW)
+#define	ETHVLAN1RInitialValue		(0x0)
+#define	ETHVLAN1RTestMask		(0xffff)
+
+/* - VLAN2R */
+#define	ETHVLAN2R			(0x24)
+#define	ETHVLAN2RVLAN2			(0xffff)
+#define	ETHVLAN2RVLAN2Shift		(0x0)
+#define	ETHVLAN2RMask			(0xffff)
+#define	ETHVLAN2RAccessType		(RW)
+#define	ETHVLAN2RInitialValue		(0x0)
+#define	ETHVLAN2RTestMask		(0xffff)
+
+/* - INTEN */
+#define	ETHINTEN			(0x28)
+#define	ETHINTENRXENDEN			(0x4)
+#define	ETHINTENRXSTEN			(0x2)
+#define	ETHINTENTXENDEN			(0x1)
+#define	ETHINTENMask			(0x7)
+#define	ETHINTENAccessType		(RW)
+#define	ETHINTENInitialValue		(0x0)
+#define	ETHINTENTestMask		(0x7)
+
+/* - INTST */
+#define	ETHINTST			(0x2c)
+#define	ETHINTSTRXEND			(0x4)
+#define	ETHINTSTRXSTART			(0x2)
+#define	ETHINTSTTXEND			(0x1)
+#define	ETHINTSTMask			(0x7)
+#define	ETHINTSTAccessType		(RO)
+#define	ETHINTSTInitialValue		(0x0)
+#define	ETHINTSTTestMask		(0x7)
+
+/* - TXSTAT */
+#define	ETHTXSTAT			(0x30)
+#define	ETHTXSTATTXRETRY		(0x10000000)
+#define	ETHTXSTATHBF			(0x800)
+#define	ETHTXSTATCOLCNT			(0x400)
+#define	ETHTXSTATLCOLOB			(0x200)
+#define	ETHTXSTATDEF			(0x100)
+#define	ETHTXSTATURUN			(0x80)
+#define	ETHTXSTATEXCOL			(0x40)
+#define	ETHTXSTATTXLCOL			(0x20)
+#define	ETHTXSTATEXDEF			(0x10)
+#define	ETHTXSTATLCAR			(0x8)
+#define	ETHTXSTATNCAR			(0x4)
+#define	ETHTXSTATTXABORT		(0x1)
+#define	ETHTXSTATMask			(0x10000ffd)
+#define	ETHTXSTATAccessType		(RO)
+#define	ETHTXSTATInitialValue		(0x0)
+#define	ETHTXSTATTestMask		(0x10000ffd)
+
+/* - TXBCR */
+#define	ETHTXBCR			(0x34)
+#define	ETHTXBCRTXBC			(0xffff)
+#define	ETHTXBCRTXBCShift		(0x0)
+#define	ETHTXBCRMask			(0xffff)
+#define	ETHTXBCRAccessType		(RW)
+#define	ETHTXBCRInitialValue		(0x5ee)
+#define	ETHTXBCRTestMask		(0xffff)
+
+/* - TXADDR */
+#define	ETHTXADDR			(0x38)
+#define	ETHTXADDRTXBA			(0x1fffffff)
+#define	ETHTXADDRTXBAShift		(0x0)
+#define	ETHTXADDRMask			(0x1fffffff)
+#define	ETHTXADDRAccessType		(RW)
+#define	ETHTXADDRInitialValue		(0x0)
+#define	ETHTXADDRTestMask		(0x1fffffff)
+
+/* - TXCTRL */
+#define	ETHTXCTRL			(0x3c)
+#define	ETHTXCTRLTXFLUSH		(0x1)
+#define	ETHTXCTRLMask			(0x1)
+#define	ETHTXCTRLAccessType		(WO)
+#define	ETHTXCTRLInitialValue		(0x0)
+#define	ETHTXCTRLTestMask		(0x1)
+
+/* - RXSTAT */
+#define	ETHRXSTAT			(0x40)
+#define	ETHRXSTATMF			(0x80000000)
+#define	ETHRXSTATPF			(0x40000000)
+#define	ETHRXSTATBCP			(0x10000000)
+#define	ETHRXSTATMCP			(0x8000000)
+#define	ETHRXSTATUCP			(0x4000000)
+#define	ETHRXSTATCP			(0x2000000)
+#define	ETHRXSTATLE			(0x1000000)
+#define	ETHRXSTATRXVLAN2		(0x800000)
+#define	ETHRXSTATRXVLAN1		(0x400000)
+#define	ETHRXSTATCRCERR			(0x200000)
+#define	ETHRXSTATDRIB			(0x100000)
+#define	ETHRXSTATMIIERR			(0x80000)
+#define	ETHRXSTATPKTYPE			(0x40000)
+#define	ETHRXSTATRXLCOL			(0x20000)
+#define	ETHRXSTATPTL			(0x10000)
+#define	ETHRXSTATRUNT			(0x8000)
+#define	ETHRXSTATWDTO			(0x4000)
+#define	ETHRXSTATPKTLEN			(0x3fff)
+#define	ETHRXSTATPKTLENShift		(0x0)
+#define	ETHRXSTATMask			(0xdfffffff)
+#define	ETHRXSTATAccessType		(RO)
+#define	ETHRXSTATInitialValue		(0x0)
+#define	ETHRXSTATTestMask		(0xdfffffff)
+
+/* - RXBCR */
+#define	ETHRXBCR			(0x44)
+#define	ETHRXBCRRXBC			(0xffff)
+#define	ETHRXBCRRXBCShift		(0x0)
+#define	ETHRXBCRMask			(0xffff)
+#define	ETHRXBCRAccessType		(RW)
+#define	ETHRXBCRInitialValue		(0x5ee)
+#define	ETHRXBCRAccessType		(RW)
+#define	ETHRXBCRTestMask		(0xffff)
+
+/* - RXADDR */
+#define	ETHRXADDR			(0x48)
+#define	ETHRXADDRRXBA			(0x1fffffff)
+#define	ETHRXADDRRXBAShift		(0x0)
+#define	ETHRXADDRMask			(0x1fffffff)
+#define	ETHRXADDRAccessType		(RW)
+#define	ETHRXADDRInitialValue		(0x0)
+#define	ETHRXADDRTestMask		(0x1fffffff)
+
+/* - RXCTRL */
+#define	ETHRXCTRL			(0x4c)
+#define	ETHRXCTRLRXFLUSH		(0x1)
+#define	ETHRXCTRLMask			(0x1)
+#define	ETHRXCTRLAccessType		(WO)
+#define	ETHRXCTRLInitialValue		(0x0)
+#define	ETHRXCTRLTestMask		(0x1)
+
+/* C struct view */
+
+typedef struct s_ETH {
+ unsigned CTRL; /* @0 */
+ unsigned MAHR; /* @4 */
+ unsigned MALR; /* @8 */
+ unsigned MHTHR; /* @12 */
+ unsigned MHTLR; /* @16 */
+ unsigned MIIAR; /* @20 */
+ unsigned MIIDR; /* @24 */
+ unsigned FCR; /* @28 */
+ unsigned VLAN1R; /* @32 */
+ unsigned VLAN2R; /* @36 */
+ unsigned INTEN; /* @40 */
+ unsigned INTST; /* @44 */
+ unsigned TXSTAT; /* @48 */
+ unsigned TXBCR; /* @52 */
+ unsigned TXADDR; /* @56 */
+ unsigned TXCTRL; /* @60 */
+ unsigned RXSTAT; /* @64 */
+ unsigned RXBCR; /* @68 */
+ unsigned RXADDR; /* @72 */
+ unsigned RXCTRL; /* @76 */
+} s_ETH;
+
+#define uETH1 ((volatile struct s_ETH *) 0xc0000980)
+#define uETH2 ((volatile struct s_ETH *) 0xc0000a00)
+
+/****************************************************************************/
+
+/*
+ * The name of the card. Is used for messages and in the requests for
+ * io regions, irqs and dma channels
+ */
+static const char* cardname = "ethernet";
+
+/* First, a few definitions that the brave might change. */
+
+/* use 0 for production, 1 for verification, >2 for debug */
+#ifndef NET_DEBUG
+#define NET_DEBUG 2
+#endif
+static unsigned int net_debug = NET_DEBUG;
+
+/* macros to simplify debug checking */
+#if 1
+#define BUGMSG(args...) do{printk(## args);}while(0)
+#else
+#define BUGMSG(args...) 
+#endif
+
+#define PKT_BUF_SZ	1536	/* maximum packet size */
+
+/*
+ * mask of all rx errors
+ */
+#define ETHRXSTATERROR ( ETHRXSTATCRCERR | ETHRXSTATDRIB | \
+ 		         ETHRXSTATMIIERR | ETHRXSTATRUNT )
+
+/* Note, code depends on these being power of 2 */
+#define ETH_RXQ_SIZE	8
+#define ETH_TXQ_SIZE	8
+
+/* Information that need to be kept for each board. */
+struct net_local {
+	struct net_device_stats	    stats;		/* tx/rx statistics */
+	long open_time;					/* Useless example local info. */
+	volatile struct s_ETH *uEth;			/* Pointer to Ethernet device */
+	struct sk_buff *rx_frames[ETH_RXQ_SIZE];	/* frame RX ring */
+	int rxq_ptr;
+	struct sk_buff *tx_frames[ETH_TXQ_SIZE];	/* frame TX ring */
+	int txq_p;					/* TX produce pointer */
+	int txq_c;					/* TX consume pointer */
+};
+
+/* Index to functions, as function prototypes. */
+extern int isl3893_probe(struct net_device *dev);
+
+static int isl3893_probe1(struct net_device *dev, int ioaddr);
+static int net_open(struct net_device *dev);
+static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
+static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static int net_close(struct net_device *dev);
+static struct net_device_stats *net_get_stats(struct net_device *dev);
+
+static void chipset_init(struct net_device *dev, int startp);
+
+
+/*
+ * Check for a network adaptor of this type, and return '0' iff one exists.
+ * If dev->base_addr == 0, probe all likely locations.
+ * If dev->base_addr == 1, always return failure.
+ * If dev->base_addr == 2, allocate space for the device and return success
+ * (detachable devices only).
+ */
+int
+isl3893_ether_probe(struct net_device *dev)
+{
+	/* For now only detect eth0 */
+	if(dev->base_addr != 0)
+		return -ENODEV;
+
+	return isl3893_probe1( dev, 0 );
+}
+
+
+/*
+ * This is the real probe routine. 
+ */
+static int isl3893_probe1(struct net_device *dev, int ioaddr)
+{
+	static unsigned version_printed = 0;
+	u_char ether_address[] = "\x00\x10\x91\x00\xed\xcb";
+	int i;
+
+	/* Allocate a new 'dev' if needed. */
+	if (dev == NULL) {
+		/*
+		 * Don't allocate the private data here, it is done later
+		 * This makes it easier to free the memory when this driver
+		 * is used as a module.
+		 */
+		dev = init_etherdev(0, 0);
+		if (dev == NULL)
+			return -ENOMEM;
+	}
+
+	if (net_debug  &&  version_printed++ == 0)
+		printk(KERN_DEBUG "%s", version);
+
+	printk(KERN_INFO "%s: %s found, ", dev->name, cardname );
+
+	/* Fill in the 'dev' fields. */
+	if (dev->base_addr == 0)
+		dev->base_addr = ioaddr;
+
+	/* Retrieve and print the ethernet address. */
+	for (i = 0; i < 6; i++)
+		printk(" %2.2x", dev->dev_addr[i] = ether_address[i] );
+
+	/* Initialize the device structure. */
+	if (dev->priv == NULL) {
+		dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+		if (dev->priv == NULL)
+			return -ENOMEM;
+	}
+	memset(dev->priv, 0, sizeof(struct net_local));
+
+	dev->open		= net_open;
+	dev->stop		= net_close;
+	dev->get_stats		= net_get_stats;
+	dev->hard_start_xmit 	= net_send_packet;
+
+	ether_setup(dev);
+
+	SET_MODULE_OWNER(dev);
+
+	return 0;
+}
+
+static void chipset_init( struct net_device *dev, int startp )
+{
+	struct net_local *lp = (struct net_local *)dev->priv;
+	int i;
+
+	/* RX enable, TX enable, Promiscuous mode */
+	lp->uEth->CTRL = ETHCTRLRE | ETHCTRLTE | ETHCTRLPR;
+
+	/* Fill the RX FIFO */
+	lp->uEth->RXBCR = PKT_BUF_SZ;
+	for( i = 0; i < ETH_RXQ_SIZE; i++ ) {
+		lp->uEth->RXADDR = (int) lp->rx_frames[i]->data;
+	}
+	/* Enable RX end, TX end and RX start interrupts */
+	lp->uEth->INTEN = ETHINTENRXENDEN | ETHINTENRXSTEN | ETHINTENTXENDEN;
+}
+
+/*
+ * Open/initialize the board. This is called (in the current kernel)
+ * sometime after booting when the 'ifconfig' program is run.
+ *
+ * This routine should set everything up anew at each open, even
+ * registers that "should" only need to be set once at boot, so that
+ * there is non-reboot way to recover if something goes wrong.
+ */
+static int
+net_open(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *)dev->priv;
+	struct sk_buff *skb;
+	int irqval;
+	int i;
+
+	MOD_INC_USE_COUNT;
+
+	/* For now we always do Eth1 */
+	lp->uEth = uETH1;
+
+	BUGMSG("%s:Opening Ethernet interface ", dev->name);
+	if(lp->uEth == uETH1) {
+		BUGMSG("1\n");
+		dev->irq = IRQ_ETH1;
+	} else {
+		BUGMSG("2\n");
+		dev->irq = IRQ_ETH2;
+	}
+	irqval = request_irq(dev->irq, &net_interrupt, SA_INTERRUPT, cardname, NULL);
+
+	if (irqval) {
+		printk("%s: unable to get IRQ %d (irqval=%d).\n",
+			   dev->name, dev->irq, irqval);
+		return -EAGAIN;
+	}
+
+	/* Allocate Ethernet RX buffers */
+	for( i = 0; i < ETH_RXQ_SIZE; i++ ) {
+		skb = dev_alloc_skb( PKT_BUF_SZ );
+		if (skb == NULL) {
+			printk("%s: Could not allocate RX Ring buffer\n", dev->name);
+			while(i != 0)
+				dev_kfree_skb(lp->rx_frames[--i]);
+
+			return -ENOMEM;
+		}
+		skb->dev = dev;
+		skb->protocol = eth_type_trans(skb, dev);
+		skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
+		/* word align IP header */
+		skb_reserve( skb, 2 );
+    		lp->rx_frames[i] = skb;
+	}
+	lp->rxq_ptr = 0;
+	lp->txq_p = 0;
+	lp->txq_c = 0;
+
+	BUGMSG("%s: Resetting hardware\n", dev->name);
+	/* Reset the hardware here. */
+	chipset_init( dev, 1 );
+	lp->open_time = jiffies;
+
+	BUGMSG("%s: netif_start_queue\n", dev->name);
+	netif_start_queue(dev);
+	return 0;
+}
+
+static int
+net_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *)dev->priv;
+	short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+
+	BUGMSG("%s: net_send_packet p %d, c %d\n", dev->name, lp->txq_p, lp->txq_c);
+
+	if((lp->txq_p - lp->txq_c) > (ETH_TXQ_SIZE - 1)) {
+		printk("TX Queue full, dropping packet! (p %d, c %d)\n", lp->txq_p, lp->txq_c);
+		dev_kfree_skb(skb);
+		return 0;
+	}
+
+	/* Put packet in the Ethernet queue */
+	lp->uEth->TXBCR = length;
+	lp->uEth->TXADDR = (int)skb->data;
+
+	lp->tx_frames[lp->txq_p++ & (ETH_TXQ_SIZE - 1)] = skb;
+	dev->trans_start = jiffies;
+
+	BUGMSG("%s: net_send_packet finished\n", dev->name);
+	return 0;
+}
+
+/*
+ * The typical workload of the driver:
+ *   Handle the network interface interrupts.
+ */
+static void
+net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct net_device *dev;
+	struct net_local *lp;
+	int status = 0;
+
+	BUGMSG("net_interrupt..");
+	if (dev_id == NULL) {
+		printk(KERN_WARNING "%s: irq %d for unknown device.\n", cardname, irq);
+		return;
+	}
+
+	dev = (struct net_device *) dev_id;
+	lp = (struct net_local *) dev->priv;
+
+	status = lp->uEth->INTST;
+
+	/* RX Start: No frame available during frame RX */
+	if(status & ETHINTSTRXSTART) {
+		printk("PANIC: Ethernet RX Queue is empty: this should NEVER Occur!!!\n");
+		printk("rxq_ptr = %d\n", lp->rxq_ptr);
+	}
+
+	/* RX End: a frame is received successfully */
+	if(status & ETHINTSTRXEND) {
+		BUGMSG("RX end..");
+		do {
+			unsigned int rx_packet_stat = lp->uEth->RXSTAT;
+
+			if(rx_packet_stat & ETHRXSTATERROR) {
+				printk("RX Packet error 0x%.8x\n", rx_packet_stat);
+				lp->stats.rx_dropped++;
+				/* We reuse the frame */
+				lp->uEth->RXADDR = (int)lp->rx_frames[lp->rxq_ptr & (ETH_RXQ_SIZE -1)];
+			} else {
+				unsigned int length = (rx_packet_stat & 0x3fff);
+				struct sk_buff *skb;
+				struct sk_buff *newskb;
+
+				BUGMSG("rxq %d, skblen %d..", lp->rxq_ptr, length);
+				/* The received skb */
+				skb = lp->rx_frames[lp->rxq_ptr & (ETH_RXQ_SIZE -1)];
+				skb_put(skb, length);
+				lp->stats.rx_packets++;
+				lp->stats.rx_bytes += length;
+
+				/* Alloc new skb for rx_frame ringbuffer */
+				newskb = dev_alloc_skb( PKT_BUF_SZ );
+				if (newskb == NULL) {
+					/* We assume that we can consume and produce the RX ring
+					 * buffer at the same time. In this case, we cannot
+					 * produce so we will eventually crash ...
+					 */
+					printk("Cannot allocate skb. This is very bad.... We will CRASH!\n");
+				} else {
+					newskb->dev = dev;
+					newskb->protocol = eth_type_trans(skb, dev);
+					newskb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
+					/* word align IP header */
+					skb_reserve( newskb, 2 );
+					lp->rx_frames[lp->rxq_ptr & (ETH_RXQ_SIZE -1)] = newskb;
+					/* Put in Ethernet RX queue */
+					lp->uEth->RXADDR = (int) newskb->data;
+				}
+				lp->rxq_ptr++;
+				netif_rx(skb);
+			}
+		} while(lp->uEth->INTST & ETHINTSTRXEND);
+	}
+
+	if(status & ETHINTSTTXEND) {
+		BUGMSG("TX end..");
+		do {
+			unsigned int tx_packet_stat = lp->uEth->TXSTAT;
+			struct sk_buff *skb;
+
+			BUGMSG("*%d %d", lp->txq_p, lp->txq_c);
+			if(tx_packet_stat)
+				printk("TX Packet error 0x%.8x\n", tx_packet_stat);
+
+			skb = lp->tx_frames[lp->txq_c & (ETH_TXQ_SIZE -1)];
+			/* paranoia check should be removed */
+			if(skb == NULL) {
+				printk("ERROR: tx frame NULL\n");
+				break;
+			}
+			lp->tx_frames[lp->txq_c & (ETH_TXQ_SIZE -1)] = NULL;
+			lp->txq_c++;
+			lp->stats.tx_packets++;
+			dev_kfree_skb(skb);
+		} while(lp->uEth->INTST & ETHINTSTTXEND);
+	}
+	BUGMSG("\n");
+	return;
+}
+
+/* The inverse routine to net_open(). */
+static int
+net_close(struct net_device *dev)
+{
+	BUGMSG("%s: net_close\n", dev->name);
+
+	netif_stop_queue(dev); /* can't transmit any more */
+
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+/*
+ * Get the current statistics.
+ * This may be called with the card open or closed.
+ */
+static struct net_device_stats *
+net_get_stats(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *)dev->priv;
+
+	BUGMSG("%s: net_get_stats\n", dev->name);
+	return &lp->stats;
+}
diff -urN linux-2.4.29/drivers/net/kern_compat.h linux-2.4.29-uc1/drivers/net/kern_compat.h
--- linux-2.4.29/drivers/net/kern_compat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/kern_compat.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,233 @@
+#ifndef _KERN_COMPAT_H
+#define _KERN_COMPAT_H
+/* kern_compat.h: Linux PCI network adapter backward compatibility code. */
+/*
+	$Revision: 1.1 $ $Date: 2001/12/10 04:48:12 $
+
+	Kernel compatibility defines.
+	This file provides macros to mask the difference between kernel versions.
+	It is designed primarily to allow device drivers to be written so that
+	they work with a range of kernel versions.
+
+	Written 1999-2001 Donald Becker, Scyld Computing Corporation
+	This software may be used and distributed according to the terms
+	of the GNU General Public License (GPL), incorporated herein by
+	reference.  Drivers interacting with these functions are derivative
+	works and thus are covered the GPL.  They must include an explicit
+	GPL notice.
+
+	This code also provides inline scan and activate functions for PCI network
+	interfaces.  It has an interface identical to pci-scan.c, but is
+	intended as an include file to simplify using updated drivers with older
+	kernel versions.
+	This code version matches pci-scan.c:v0.05 9/16/99
+
+	The author may be reached as becker@scyld.com, or
+	Donald Becker
+	Scyld Computing Corporation
+	410 Severn Ave., Suite 210
+	Annapolis MD 21403
+
+	Other contributers:
+	<none>
+*/
+
+/* We try to use defined values to decide when an interface has changed or
+   added features, but we must have the kernel version number for a few. */
+#if ! defined(LINUX_VERSION_CODE)  ||  (LINUX_VERSION_CODE < 0x10000)
+#include <linux/version.h>
+#endif
+/* Older kernel versions didn't include modversions automatically. */
+#if LINUX_VERSION_CODE < 0x20300  &&  defined(MODVERSIONS)
+#include <linux/modversions.h>
+#endif
+
+/* There was no support for PCI address space mapping in 2.0, but the
+   Alpha needed it.  See the 2.2 documentation. */
+#if LINUX_VERSION_CODE < 0x20100  &&  ! defined(__alpha__)
+#define ioremap(a,b)\
+    (((unsigned long)(a) >= 0x100000) ? vremap(a,b) : (void*)(a))
+#define iounmap(v)\
+    do { if ((unsigned long)(v) >= 0x100000) vfree(v);} while (0)
+#endif
+
+/* Support for adding info about the purpose of and parameters for kernel
+   modules was added in 2.1. */
+#if LINUX_VERSION_CODE < 0x20115
+#define MODULE_AUTHOR(name)  extern int nonesuch
+#define MODULE_DESCRIPTION(string)  extern int nonesuch
+#define MODULE_PARM(varname, typestring)  extern int nonesuch
+#endif
+
+/* SMP and better multiarchitecture support were added.
+   Using an older kernel means we assume a little-endian uniprocessor.
+*/
+#if LINUX_VERSION_CODE < 0x20123
+#define hard_smp_processor_id() smp_processor_id()
+#define test_and_set_bit(val, addr) set_bit(val, addr)
+#define cpu_to_le16(val) (val)
+#define cpu_to_le32(val) (val)
+#define le16_to_cpu(val) (val)
+#define le16_to_cpus(val)		/* In-place conversion. */
+#define le32_to_cpu(val) (val)
+#define cpu_to_be16(val) ((((val) & 0xff) << 8) +  (((val) >> 8) & 0xff))
+#define cpu_to_be32(val) ((cpu_to_be16(val) << 16) + cpu_to_be16((val) >> 16))
+typedef long spinlock_t;
+#define SPIN_LOCK_UNLOCKED 0
+#define spin_lock(lock)
+#define spin_unlock(lock)
+#define spin_lock_irqsave(lock, flags)	save_flags(flags); cli();
+#define spin_unlock_irqrestore(lock, flags) restore_flags(flags);
+#endif
+
+#if LINUX_VERSION_CODE <= 0x20139
+#define	net_device_stats enet_statistics
+#else
+#define NETSTATS_VER2
+#endif
+
+/* These are used by the netdrivers to report values from the
+   MII (Media Indpendent Interface) management registers.
+*/
+#ifndef SIOCGMIIPHY
+#define SIOCGMIIPHY (SIOCDEVPRIVATE)		/* Get the PHY in use. */
+#define SIOCGMIIREG (SIOCDEVPRIVATE+1) 		/* Read a PHY register. */
+#define SIOCSMIIREG (SIOCDEVPRIVATE+2) 		/* Write a PHY register. */
+#endif
+#ifndef SIOCGPARAMS
+#define SIOCGPARAMS (SIOCDEVPRIVATE+3) 		/* Read operational parameters. */
+#define SIOCSPARAMS (SIOCDEVPRIVATE+4) 		/* Set operational parameters. */
+#endif
+
+#if !defined(HAVE_NETIF_MSG)
+enum {
+	NETIF_MSG_DRV           = 0x0001,
+	NETIF_MSG_PROBE         = 0x0002,
+	NETIF_MSG_LINK          = 0x0004,
+	NETIF_MSG_TIMER         = 0x0008,
+	NETIF_MSG_IFDOWN        = 0x0010,
+	NETIF_MSG_IFUP          = 0x0020,
+	NETIF_MSG_RX_ERR        = 0x0040,
+	NETIF_MSG_TX_ERR        = 0x0080,
+	NETIF_MSG_TX_QUEUED     = 0x0100,
+	NETIF_MSG_INTR          = 0x0200,
+	NETIF_MSG_TX_DONE       = 0x0400,
+	NETIF_MSG_RX_STATUS     = 0x0800,
+	NETIF_MSG_PKTDATA       = 0x1000,
+};
+#endif
+
+#if LINUX_VERSION_CODE < 0x20155
+#include <linux/bios32.h>
+#define PCI_SUPPORT_VER1
+/* A minimal version of the 2.2.* PCI support that handles configuration
+   space access.
+   Drivers that actually use pci_dev fields must do explicit compatibility.
+   Note that the struct pci_dev * "pointer" is actually a byte mapped integer!
+*/
+#if LINUX_VERSION_CODE < 0x20020
+struct pci_dev { int not_used; };
+#endif
+
+#define pci_find_slot(bus, devfn) (struct pci_dev*)((bus<<8) | devfn | 0xf0000)
+#define bus_number(pci_dev) ((((int)(pci_dev))>>8) & 0xff)
+#define devfn_number(pci_dev) (((int)(pci_dev)) & 0xff)
+
+#ifndef CONFIG_PCI
+extern inline int pci_present(void) { return 0; }
+#else
+#define pci_present pcibios_present
+#endif
+
+#define pci_read_config_byte(pdev, where, valp)\
+	pcibios_read_config_byte(bus_number(pdev), devfn_number(pdev), where, valp)
+#define pci_read_config_word(pdev, where, valp)\
+	pcibios_read_config_word(bus_number(pdev), devfn_number(pdev), where, valp)
+#define pci_read_config_dword(pdev, where, valp)\
+	pcibios_read_config_dword(bus_number(pdev), devfn_number(pdev), where, valp)
+#define pci_write_config_byte(pdev, where, val)\
+	pcibios_write_config_byte(bus_number(pdev), devfn_number(pdev), where, val)
+#define pci_write_config_word(pdev, where, val)\
+	pcibios_write_config_word(bus_number(pdev), devfn_number(pdev), where, val)
+#define pci_write_config_dword(pdev, where, val)\
+	pcibios_write_config_dword(bus_number(pdev), devfn_number(pdev), where, val)
+#else
+#define PCI_SUPPORT_VER2
+#endif
+
+/* The arg count changed, but function name did not.
+   We cover that bad choice by defining a new name.
+*/
+#if LINUX_VERSION_CODE < 0x20159
+#define dev_free_skb(skb) dev_kfree_skb(skb, FREE_WRITE);
+#define dev_free_skb_irq(skb) dev_kfree_skb(skb, FREE_WRITE);
+#elif LINUX_VERSION_CODE < 0x20400
+#define dev_free_skb(skb) dev_kfree_skb(skb);
+#define dev_free_skb_irq(skb) dev_kfree_skb(skb);
+#else
+#define dev_free_skb(skb) dev_kfree_skb(skb);
+#define dev_free_skb_irq(skb) dev_kfree_skb_irq(skb);
+#endif
+
+/* Added at the suggestion of Jes Sorensen. */
+#if LINUX_VERSION_CODE > 0x20153
+#include <linux/init.h>
+#else
+#define __init
+#define __initdata
+#define __initfunc(__arginit) __arginit
+#endif
+
+/* The old 'struct device' used a too-generic name. */
+#if LINUX_VERSION_CODE < 0x2030d
+#define net_device device
+#endif
+
+/* The 2.2 kernels added the start of capability-based security for operations
+   that formerally could only be done by root.
+*/
+#if ! defined(CAP_NET_ADMIN)
+#define capable(CAP_XXX) (suser())
+#endif
+
+#if ! defined(HAVE_NETIF_QUEUE)
+#define netif_wake_queue(dev)   do { clear_bit( 0, (void*)&(dev)->tbusy); mark_bh(NET_BH); } while (0)
+#define netif_start_tx_queue(dev) do { (dev)->tbusy = 0; dev->start = 1; } while (0)
+#define netif_stop_tx_queue(dev) do { (dev)->tbusy = 1; dev->start = 0; } while (0)
+#define netif_queue_paused(dev) ((dev)->tbusy != 0)
+/* Splitting these lines exposes a bug in some preprocessors. */
+#define netif_pause_tx_queue(dev) (test_and_set_bit( 0, (void*)&(dev)->tbusy))
+#define netif_unpause_tx_queue(dev) do { clear_bit( 0, (void*)&(dev)->tbusy); } while (0)
+#define netif_resume_tx_queue(dev) do { clear_bit( 0, (void*)&(dev)->tbusy); mark_bh(NET_BH); } while (0)
+
+#define netif_running(dev) ((dev)->start != 0)
+#define netif_device_attach(dev) do {; } while (0)
+#define netif_device_detach(dev) do {; } while (0)
+#define netif_device_present(dev) (1)
+#define netif_set_tx_timeout(dev, func, deltajiffs)   do {; } while (0)
+#define netif_link_down(dev)  (dev)->flags &= ~IFF_RUNNING;
+#define netif_link_up(dev)  (dev)->flags |= IFF_RUNNING
+
+#else
+
+#define netif_start_tx_queue(dev) netif_start_queue(dev)
+#define netif_stop_tx_queue(dev) netif_stop_queue(dev)
+#define netif_queue_paused(dev) netif_queue_stopped(dev)
+#define netif_resume_tx_queue(dev) netif_wake_queue(dev)
+/* Only used in transmit path.  No function in 2.4. */
+#define netif_pause_tx_queue(dev)  0
+#define netif_unpause_tx_queue(dev) do {; } while (0)
+
+#define netif_link_down(dev)  (dev)->flags &= ~IFF_RUNNING;
+#define netif_link_up(dev)  (dev)->flags |= IFF_RUNNING
+
+#endif
+
+#endif
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff -urN linux-2.4.29/drivers/net/ks8695/ks8695_cache.c linux-2.4.29-uc1/drivers/net/ks8695/ks8695_cache.c
--- linux-2.4.29/drivers/net/ks8695/ks8695_cache.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/ks8695/ks8695_cache.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,280 @@
+/*
+	Copyright (c) 2002, Micrel Kendin Operations
+
+	Written 2002 by LIQUN RUAN
+
+	This software may be used and distributed according to the terms of 
+	the GNU General Public License (GPL), incorporated herein by reference.
+	Drivers based on or derived from this code fall under the GPL and must
+	retain the authorship, copyright and license notice. This file is not
+	a complete program and may only be used when the entire operating
+	system is licensed under the GPL.
+
+	The author may be reached as lruan@kendin.com
+	Micrel Kendin Operations
+	486 Mercury Dr.
+	Sunnyvale, CA 94085
+
+	This driver is for Kendin's KS8695 SOHO Router Chipset as ethernet driver.
+
+	Support and updates available at
+	www.kendin.com or www.micrel.com
+
+*/
+#include "ks8695_drv.h"
+#include "ks8695_cache.h"
+
+/* for 922T, the values are fixed */
+#if	0
+static uint32_t	uICacheLineLen = 8;		/* 8 dwords, 32 bytes */
+static uint32_t	uICacheSize = 8192;		/* 8K cache size */
+#endif
+
+static uint32_t	bPowerSaving = FALSE;
+static uint32_t	bAllowPowerSaving = FALSE;
+
+/*
+ * ks8695_icache_read_c9
+ *	This function is use to read lockdown register
+ *
+ * Argument(s)
+ *	NONE
+ *
+ * Return(s)
+ *	NONE
+ */
+void ks8695_icache_read_c9(void)
+{
+	register int base;
+
+	__asm__(
+		"mrc p15, 0, %0, c9, c0, 1"
+		 : "=r" (base)
+		);
+
+	DRV_INFO("%s: lockdown index=%d", __FUNCTION__, (base >> 26));
+}
+
+#if	0
+/*
+ * ks8695_icache_lock
+ *	This function is use to lock given icache
+ *
+ * Argument(s)
+ *	icache_start	pointer to starting icache address
+ *	icache_end		pointer to ending icache address
+ *
+ * Return(s)
+ *	0		if success
+ *	error	otherwise
+ */
+int ks8695_icache_lock(void *icache_start, void *icache_end)
+{
+	uint32_t victim_base = (ICACHE_VICTIM_BASE << ICACHE_VICTIM_INDEX);
+	int	len;
+	spinlock_t	lock = SPIN_LOCK_UNLOCKED;
+	unsigned long flags;
+
+	len = (int)(icache_end - icache_start);
+	DRV_INFO("%s: start=%p, end=%p, len=%d, victim=0x%x", __FUNCTION__, icache_start, icache_end, len, victim_base);
+	
+	/* if lockdown lines are more than half of max associtivity */
+	if ((len / ICACHE_BYTES_PER_LINE) > (ICACHE_ASSOCITIVITY >> 1)) {
+		DRV_WARN("%s: lockdown lines = %d is too many, (Assoc=%d)", __FUNCTION__, (len / ICACHE_BYTES_PER_LINE), ICACHE_ASSOCITIVITY);
+		return -1;
+	}
+
+	spin_lock_irqsave(&lock, flags);
+
+	__asm__(
+		" \n\
+		ADRL	r0, ks8695_isr \n\
+		ADRL	r1, ks8695_isre \n\
+		MOV	r2, %1 \n\
+		MCR	p15, 0, r2, c9, c4, 1 \n\
+lock_loop: \n\
+		MCR	p15, 0, r0, c7, c13, 1 \n\
+		ADD	r0, r0, #32 \n\
+ \n\
+		AND	r3, r0, #0x60 \n\
+		CMP	r3, #0x0 \n\
+		ADDEQ	r2, r2, #0x1<<26 \n\
+		MCREQ	p15, 0, r2, c9, c0, 1 \n\
+		  \n\
+		CMP	r0, r1 \n\
+		BLE	lock_loop \n\
+ \n\
+		CMP	r3, #0x0 \n\
+		ADDNE	r2, r2, #0x1<<26 \n\
+		MCRNE	p15, 0, r2, c9, c0,	1 \n\
+		"
+		: "=r" (len)
+		: "r" (victim_base)
+		: "r0", "r1", "r2", "r3"
+		);
+
+		ks8695_icache_read_c9();
+
+#if	0
+	/* following are the assemble code for icache lock down, a C version should be implemented, accordingly */
+	ADRL	r0, start_address			; address pointer
+	ADRL	r1, end_address
+	MOV		r2, #lockdown_base<<26		; victim pointer
+	MCR		p15, 0, r2, c9, c0, 1
+
+loop
+	MCR		p15, 0, r0, c7, c13, 1		; prefetch ICache line
+	ADD		r0, r0, #32					; increment address pointer to next ICache line
+
+	; do we need to increment the victim pointer ?
+	; thest for segment 0, and if so, increment the victim pointer
+	; and write the Icache victime and lockdown base
+
+	AND		r3, r0, #0x60				; extract the segment bits from the addr.
+	CMP		r3, #0x0					; test the segment
+	ADDEQ	r2, r2, #0x1<<26			; if segment 0, increment victim pointer
+	MCREQ	p15, 0, r2, c9, c0, 1		; and write ICaceh victim and lockdown
+
+	; have we linefilled enough code?
+	; test for the address pointer being less than or equal to the end_address
+	; pointer and if so, loop and perform another linefill
+
+	CMP		r0, r1						; test for less than or equal to end_address
+	BLE		loop						; if not, loop
+
+	; have we exited with r3 pointer to segment 0?
+	; if so, the ICaceh victim and lockdown base has already been set to one higher
+	; than the last entry written.
+	; if not, increment the victim pointer and write the ICache victim and
+	; lockdown base.
+
+	CMP		r3, #0x0					; test for segments 1 to 3
+	ADDNE	r2, r2, #0x1 << 26			; if address is segment 1 to 3
+	MCRNE	p15, 0, r2, c9, c0,	1		; write ICache victim and lockdown base.
+
+#endif
+
+	spin_unlock_irqrestore(&lock, flags);
+
+	return 0;
+}
+#endif
+
+/*
+ * ks8695_icache_unlock
+ *	This function is use to unlock the icache locked previously
+ *
+ * Argument(s)
+ *	NONE.
+ *
+ * Return(s)
+ *	NONE.
+ */
+void ks8695_icache_unlock(void)
+{
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	__asm__(
+		" \n\
+		MOV r1, #0 \n\
+		MCR	p15, 0, r1, c9, c0, 1	/* reset victim base to 0 */ \n\
+		"
+	);
+
+	DRV_INFO("%s", __FUNCTION__);
+}
+
+/*
+ * ks8695_icache_change_policy
+ *	This function is use to change cache policy for ARM chipset
+ *
+ * Argument(s)
+ *	bRoundRobin		round robin or random mode
+ *
+ * Return(s)
+ *	NONE
+ */
+void ks8695_icache_change_policy(int bRoundRobin)
+{
+	uint32_t tmp;
+
+	__asm__ ( 
+		" \n\
+		mrc p15, 0, r1, c1, c0, 0 \n\
+		mov	r2, %1 \n\
+		cmp	r2, #0 \n\
+		orrne r1, r1, #0x4000 \n\
+		biceq r1, r1, #0x4000 \n\
+		mov	%0, r1 \n\
+		/* Write this to the control register */ \n\
+		mcr p15, 0, r1, c1, c0, 0 \n\
+		/* Make sure the pipeline is clear of any cached entries */ \n\
+		nop \n\
+		nop \n\
+		nop" 
+		: "=r" (tmp)
+		: "r" (bRoundRobin)
+		: "r1", "r2"
+		);
+
+/*#ifdef	DEBUG_THIS*/
+	DRV_INFO("Icache mode = %s", bRoundRobin ? "roundrobin" : "random");
+/*#endif*/
+}
+
+/*
+ * ks8695_enable_power_saving
+ *	This function is use to enable/disable power saving
+ *
+ * Argument(s)
+ *	bSaving		
+ *
+ * Return(s)
+ *	NONE
+ */
+void ks8695_enable_power_saving(int bEnablePowerSaving)
+{
+	bAllowPowerSaving = bEnablePowerSaving;
+}
+
+/*
+ * ks8695_power_saving
+ *	This function is use to put ARM chipset in low power mode (wait for interrupt)
+ *
+ * Argument(s)
+ *	bSaving		
+ *
+ * Return(s)
+ *	NONE
+ */
+void ks8695_power_saving(int bSaving)
+{
+	uint32_t tmp;
+
+	/* if not allowed by configuration option */
+	if (!bAllowPowerSaving)
+		return;
+
+	/* if already set */
+	if (bPowerSaving == bSaving)
+		return;
+
+	bPowerSaving = bSaving;
+
+	__asm__ ( 
+		" \n\
+		mov	r1, %1 \n\
+		mcr p15, 0, r1, c7, c0, 4 \n\
+		/* Make sure the pipeline is clear of any cached entries */ \n\
+		nop \n\
+		nop \n\
+		nop" 
+		: "=r" (tmp)
+		: "r" (bSaving)
+		: "r1", "r2"
+		);
+
+	DRV_INFO("%s: power saving = %s", __FUNCTION__, bSaving ? "enabled" : "disabled");
+}
diff -urN linux-2.4.29/drivers/net/ks8695/ks8695_cache.h linux-2.4.29-uc1/drivers/net/ks8695/ks8695_cache.h
--- linux-2.4.29/drivers/net/ks8695/ks8695_cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/ks8695/ks8695_cache.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,49 @@
+/*
+	Copyright (c) 2002, Micrel Kendin Operations
+
+	Written 2002 by LIQUN RUAN
+
+	This software may be used and distributed according to the terms of 
+	the GNU General Public License (GPL), incorporated herein by reference.
+	Drivers based on or derived from this code fall under the GPL and must
+	retain the authorship, copyright and license notice. This file is not
+	a complete program and may only be used when the entire operating
+	system is licensed under the GPL.
+
+	The author may be reached as lruan@kendin.com
+	Micrel Kendin Operations
+	486 Mercury Dr.
+	Sunnyvale, CA 94085
+
+	This driver is for Kendin's KS8695 SOHO Router Chipset as ethernet driver.
+
+	Support and updates available at
+	www.kendin.com/ks8695/
+
+*/
+#ifndef __KS8695_CACHE_H
+#define __KS8695_CACHE_H
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include "ks8695_drv.h"
+
+/* start ICache lockdown at ICACHE_VICTIM_BASE */
+#define	ICACHE_VICTIM_BASE		0
+#define	ICACHE_VICTIM_INDEX		26		/* victim index bit, specific to ARM922T */
+#define	ICACHE_ASSOCITIVITY		64		/* 64-WAY, specific to ARM922T */
+#define	ICACHE_BYTES_PER_LINE	128		/* 8 * 4 * 4, specific to ARM922T */
+
+extern void ks8695_icache_change_policy(int bRoundRobin);
+/*extern int ks8695_icache_lock(void *icache_start, void *icache_end);*/
+extern void ks8695_icache_unlock(void);
+extern int ks8695_icache_is_locked(void);
+extern void ks8695_icache_read_c9(void);
+void ks8695_power_saving(int bSaving);
+void ks8695_enable_power_saving(int bEnablePowerSaving);
+
+#endif /* __KS8695_CACHE_H */
diff -urN linux-2.4.29/drivers/net/ks8695/ks8695_chipdef.h linux-2.4.29-uc1/drivers/net/ks8695/ks8695_chipdef.h
--- linux-2.4.29/drivers/net/ks8695/ks8695_chipdef.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/ks8695/ks8695_chipdef.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,441 @@
+/*
+ *  ks8695_chipdef.h
+ *      This file defines the driver-independent constants, macro and
+ *      structures used in the Linux driver.
+ *
+ *  Copyright (c) 1998-2002 by Micrel-Kendin Operations. All rights reserved.
+ *
+ *  Modification History
+ *
+ *  Name        Date        Ver     Brief
+ *  ----------- ----------- ------- ------------------------------------------
+ *	RLQ	05/13/2000  1.0.0.0 Modified based on KS8695 Linux driver
+ *
+ */
+#ifndef __KS8695_CHIPDEF_H
+#define __KS8695_CHIPDEF_H
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+/* should change to system wise platform.h instead of local copy */
+//#include <asm/arch/platform.h>
+//#include "platform.h"
+
+#ifndef	BIT
+#define BIT(x) (1 << (x))
+#endif
+
+#ifndef	REG_MISC_CONTROL
+
+#define REG_MISC_CONTROL		0xEA08
+#define REG_LAN12_POWERMAGR		0xE84C
+#define REG_LAN34_POWERMAGR		0xE850
+
+#endif
+
+/* DMA related register offset */
+#define	REG_TXCTRL				0x0000
+#define	REG_RXCTRL				0x0004
+#define	REG_TXSTART				0x0008
+#define	REG_RXSTART				0x000c
+#define	REG_TXBASE				0x0010
+#define	REG_RXBASE				0x0014
+#define	REG_STATION_LOW			0x0018
+#define	REG_STATION_HIGH		0x001c
+
+#define	REG_MAC0_LOW			0x0080
+#define	REG_MAC0_HIGH			0x0084
+#define	REG_MAC1_LOW			0x0088
+#define	REG_MAC1_HIGH			0x008c
+#define	REG_MAC2_LOW			0x0090
+#define	REG_MAC2_HIGH			0x0094
+#define	REG_MAC3_LOW			0x0098
+#define	REG_MAC3_HIGH			0x009c
+#define	REG_MAC4_LOW			0x00a0
+#define	REG_MAC4_HIGH			0x00a4
+#define	REG_MAC5_LOW			0x00a8
+#define	REG_MAC5_HIGH			0x00ac
+#define	REG_MAC6_LOW			0x00b0
+#define	REG_MAC6_HIGH			0x00b4
+#define	REG_MAC7_LOW			0x00b8
+#define	REG_MAC7_HIGH			0x00bc
+#define	REG_MAC8_LOW			0x00c0
+#define	REG_MAC8_HIGH			0x00c4
+#define	REG_MAC9_LOW			0x00c8
+#define	REG_MAC9_HIGH			0x00cc
+#define	REG_MAC10_LOW			0x00d0
+#define	REG_MAC10_HIGH			0x00d4
+#define	REG_MAC11_LOW			0x00d8
+#define	REG_MAC11_HIGH			0x00dc
+#define	REG_MAC12_LOW			0x00e0
+#define	REG_MAC12_HIGH			0x00e4
+#define	REG_MAC13_LOW			0x00e8
+#define	REG_MAC13_HIGH			0x00ec
+#define	REG_MAC14_LOW			0x00f0
+#define	REG_MAC14_HIGH			0x00f4
+#define	REG_MAC15_LOW			0x00f8
+#define	REG_MAC15_HIGH			0x00fc
+
+/* register Bit field defines for Tx Ctrl and (some are shared with RX) */
+#define	DMA_SOFTRESET			0x80000000		/* DMA soft reset (shared with RX) */
+#define	DMA_UDPCHECKSUM			0x00040000		/* bit 18 (shared with RX) */
+#define	DMA_TCPCHECKSUM			0x00020000		/* bit 17 (shared with RX) */
+#define	DMA_IPCHECKSUM			0x00010000		/* bit 16 (shared with RX) */
+#define	DMA_FLOWCTRL			0x00000200		/* bit 9 (shared with RX) */
+#define	DMA_LOOPBACK			0x00000100		/* bit 8 */
+#define	DMA_ERRORFRAME			0x00000008		/* bit 3 */
+#define	DMA_PADDING				0x00000004		/* bit 2 */
+#define	DMA_CRC					0x00000002		/* bit 1 */
+#define	DMA_START				0x00000001		/* bit 0 (shared with RX) */
+
+#define	DMA_PBLTMASK			0x3f000000		/* DMA Burst Size bit mask (shared with RX) */
+#define	DMA_PBLTSHIFT			24				/* DMA Burst Size bit shift */
+
+/* some bits for RX Ctrl register */
+#define	DMA_BROADCAST			0x00000040		/* bit 6 */
+#define	DMA_MULTICAST			0x00000020		/* bit 5 */
+#define	DMA_UNICAST				0x00000010		/* bit 4 */
+#define	DMA_PROMISCUOUS			0x00000004		/* bit 2 */
+
+/* Addition station registers */
+#define	DMA_MACENABLE			0x80000000		/* enable/disable additional MAC station address */
+
+enum DMAID {
+	DMA_WAN = 0x6000,			/* WAN DMA */
+	DMA_LAN = 0x8000,			/* LAN DMA */
+#ifndef	CONFIG_ARCH_KS8695P
+	DMA_HPNA= 0xA000			/* HPNA DMA */
+#endif
+};
+
+/* DESC and Data buffer */
+#define DESC_ALIGNMENT			16	/* two dwords */
+
+/* Receive Descriptor */
+typedef struct
+{
+    volatile uint32_t RxFrameControl;
+    volatile uint32_t RxDMAFragLen;
+    volatile uint32_t RxDMAFragAddr;
+    volatile uint32_t RxDMANextPtr;
+} RXDESC, *PRXDESC;
+
+#define DESC_OWN_BIT			0x80000000		/* shared with Tx descriptor */
+
+/* In Linux, we use all 32 bits definitions! */
+/* Bits related to RxFrameControl */
+#define	RFC_FS					0x40000000		/* First Descriptor of the received frame */
+#define	RFC_LS					0x20000000		/* Last Descriptor of the received frame */
+#define	RFC_IPE					0x10000000		/* IP checksum generation */
+#define	RFC_TCPE				0x08000000		/* TCP checksum generation */
+#define	RFC_UDPE				0x04000000		/* UDP checksum generation */
+#define	RFC_ES					0x02000000		/* Error Summary */
+#define	RFC_MF					0x01000000		/* Multicast Frame */
+
+#define	RFC_RE					0x00080000		/* Report on MII/GMII error */
+#define	RFC_TL					0x00040000		/* Frame Too Long */
+#define	RFC_RF					0x00020000		/* Runt Frame */
+#define	RFC_CRC					0x00010000		/* CRC error */
+#define	RFC_FT					0x00008000		/* Frame Type */
+
+#define	RFC_SPN_MASK			0x00f00000		/* Switch engine destination port map, 20:23 */
+#define	RFC_FL_MASK				0x000007ff		/* Frame Length bit mask, 0:10 */
+#define	RFC_FRAMECTRL_MASK		(RFC_FS	| RFC_LS | RFC_ES | RFC_MF | RFC_RE | RFC_TL | RFC_CRC | RFC_FT | RFC_FL_MASK)
+
+/* Bits related to RxDMAFragLen */
+#define	RFC_RER					0x02000000		/* Receive End of Ring */
+#define	RFC_RBS_MASK			0x000007ff		/* Receive buffer Size bit mask, 0:10 */
+
+/* Transmit descriptor */
+typedef struct
+{
+    volatile uint32_t TxOwnBit;
+    volatile uint32_t TxFrameControl;
+    volatile uint32_t TxDMAFragAddr;
+    volatile uint32_t TxDMANextPtr;
+} TXDESC, *PTXDESC;
+
+/* Bits related to TxFrameControl */
+#define	TFC_IC					0x80000000		/* Interrupt on completion */
+#define	TFC_FS					0x40000000		/* first segment */
+#define	TFC_LS					0x20000000		/* last segment */
+#define	TFC_IPCKG				0x10000000		/* IP checksum generation */
+#define	TFC_TCPCKG				0x08000000		/* TCP checksum generation */
+#define	TFC_UDPCKG				0x04000000		/* UDP checksum generation */
+#define	TFC_TER					0x02000000		/* Transmit End of Ring */
+
+#define	TFC_SPN_MASK			0x00f00000		/* Switch engine destination port map, 20:23 */
+#define	TFC_TBS_MASK			0x000007ff		/* Transmit Buffer Size Mask (0:10) */
+#define	TFC_FRAMECTRL_MASK		(TFC_IC	| TFC_FS | TFC_LS | TFC_SPN_MASK | TFC_TBS_MASK)
+
+/* Interrupt related (shared among IMR, IER, ISR, IPR, and IQR) */
+#define	INT_WAN_LINK			0x80000000		/* WAN link change interrupt */
+#define	INT_WAN_TX				0x40000000		/* WAN Tx complete interrupt */
+#define	INT_WAN_RX				0x20000000		/* WAN Rx complete interrupt */
+#define	INT_WAN_TX_UNAVIAL		0x10000000		/* WAN Tx desc unavailable interrupt */
+#define	INT_WAN_RX_UNAVIAL		0x08000000		/* WAN Rx desc unavailable interrupt */
+#define	INT_WAN_TX_STOPPED		0x04000000		/* WAN Tx stopped interrupt */
+#define	INT_WAN_RX_STOPPED		0x02000000		/* WAN Rx stopped interrupt */
+
+#define	INT_WAN_MASK			0x7e000000		/* not include LINK interrupt bit */
+
+#define	INT_AMBA_BUS_ERROR		0x01000000		/* AMBA bus error interrupt */
+
+#define	INT_HPNA_TX				0x00800000		/* HPNA Tx complete interrupt */
+#define	INT_HPNA_RX				0x00400000		/* HPNA Rx complete interrupt */
+#define	INT_HPNA_TX_UNAVIAL		0x00200000		/* HPNA Tx desc unavailable interrupt */
+#define	INT_HPNA_RX_UNAVIAL		0x00100000		/* HPNA Rx desc unavailable interrupt */
+#define	INT_HPNA_TX_STOPPED		0x00080000		/* HPNA Tx stopped interrupt */
+#define	INT_HPNA_RX_STOPPED		0x00040000		/* HPNA Rx stopped interrupt */
+
+#define	INT_HPNA_MASK			0x00fc0000
+
+#define	INT_LAN_TX				0x00020000		/* LAN Tx complete interrupt */
+#define	INT_LAN_RX				0x00010000		/* LAN Rx complete interrupt */
+#define	INT_LAN_TX_UNAVIAL		0x00008000		/* LAN Tx desc unavailable interrupt */
+#define	INT_LAN_RX_UNAVIAL		0x00004000		/* LAN Rx desc unavailable interrupt */
+#define	INT_LAN_TX_STOPPED		0x00002000		/* LAN Tx stopped interrupt */
+#define	INT_LAN_RX_STOPPED		0x00001000		/* LAN Rx stopped interrupt */
+
+#define	INT_LAN_MASK			0x0003f000
+
+#define	INT_DMA_MASK			0xfefff000		/* interrupt bit mask for DMA (WAN, HPNA and LAN) */
+
+#define	INT_DMA_STOP_MASK		(INT_WAN_TX_STOPPED | INT_WAN_RX_STOPPED | INT_HPNA_TX_STOPPED | INT_HPNA_RX_STOPPED | INT_LAN_TX_STOPPED | INT_LAN_RX_STOPPED)
+#define	INT_TX_BIT				BIT(5)
+#define	INT_RX_BIT				BIT(4)
+#define	INT_TX_UNAVAIL_BIT		BIT(3)
+#define	INT_RX_UNAVAIL_BIT		BIT(2)
+#define	INT_TX_STOPPED_BIT		BIT(1)
+#define	INT_RX_STOPPED_BIT		BIT(0)
+
+/* MAC address */
+#define	MAC_ADDRESS_LEN			6
+#define	MAC_MAX_EXTRA			16
+
+typedef enum {
+	LED_SPEED,			/* 0 */
+	LED_LINK,
+	LED_FD,				/* full duplex */
+	LED_COLLISION,
+	LED_ACTIVITY,
+	LED_FD_COLLISION,	/* full duplex/collision */
+	LED_LINK_ACTIVITY,	/* link/activities */
+} LED_SELECTOR;
+
+/* register Bit field for Switch control 0 */
+#define	SW_CTRL0_AUTO_FAST_AGING	0x00100000	/* automic fast aging when link changed detected */
+#define	SW_CTRL0_ERROR_PKT		0x00080000		/* pass all error packets */
+#define	SW_CTRL0_ENABLE_PORT5	0x00040000		/* enable port 5 flow control */
+#define	SW_CTRL0_ENABLE_PORTS	0x00020000		/* enable flow control for port 1 - 4 */
+#define	SW_CTRL0_BUFFER_SHARE	0x00010000		/* buffer share mode */
+#define	SW_CTRL0_AGING_ENABLE	0x00008000		/* aging enable */
+#define	SW_CTRL0_FAST_AGING		0x00004000		/* fast aging enable */
+#define	SW_CTRL0_FAST_BACKOFF	0x00002000		/* fast back off */
+#define	SW_CTRL0_MISMATCH_DISCARD	0x00001000	/* VLAN mismatch discard */
+#define	SW_CTRL0_NO_BCAST_STORM_PROT	0x00000800		/* no broadcast storm proection tp ,cast pkts */
+#define	SW_CTRL0_PREAMBLE_MODE	0x00000400		/* back pressure mode */
+#define	SW_CTRL0_FLOWCTRL_FAIR	0x00000200		/* flow control fair mode */
+#define	SW_CTRL0_COLLISION_DROP	0x00000100		/* no excessive collision drop */
+#define	SW_CTRL0_LEN_CHECKING	0x00000080		/* enforced max length checking */
+#define	SW_CTRL0_6K_BUFFER		0x00000040		/* 6K byte buffer per port reserved for high priority pkts */
+#define	SW_CTRL0_BACK_PRESSURE	0x00000020		/* back pressure enable */
+#define	SW_CTRL0_SWITCH_ENABLE	0x00000001		/* enable switch bit */
+
+/* register Bit field for Auto Regotiation */
+#define	SW_AUTONEGO_COMPLETE	0x00004000		/* auto nego completed */
+#define	SW_AUTONEGO_RESTART		0x00002000		/* auto nego restart */
+#define	SW_AUTONEGO_ADV_PUASE	0x00001000		/* auto nego advertise PAUSE */
+#define	SW_AUTONEGO_ADV_100FD	0x00000800		/* auto nego advertise 100 FD */
+#define	SW_AUTONEGO_ADV_100HD	0x00000400		/* auto nego advertise 100 HD */
+#define	SW_AUTONEGO_ADV_10FD	0x00000200		/* auto nego advertise 10 FD */
+#define	SW_AUTONEGO_ADV_10HD	0x00000100		/* auto nego advertise 10 HD */
+#define	SW_AUTONEGO_STAT_LINK	0x00000080		/* auto nego link status */
+#define	SW_AUTONEGO_STAT_DUPLEX	0x00000040		/* auto nego duplex status (solved) */
+#define	SW_AUTONEGO_STAT_SPEED	0x00000020		/* auto nego speed status (solved) */
+#define	SW_AUTONEGO_PART_PAUSE	0x00000010		/* auto nego parterner pause */
+#define	SW_AUTONEGO_PART_100FD	0x00000008		/* auto nego parterner 100 FD */
+#define	SW_AUTONEGO_PART_100HD	0x00000004		/* auto nego parterner 100 HD */
+#define	SW_AUTONEGO_PART_10FD	0x00000002		/* auto nego parterner 10 FD */
+#define	SW_AUTONEGO_PART_10HD	0x00000001		/* auto nego parterner 10 HD */
+
+#define	SW_AUTONEGO_ADV_MASK	0x00001f00
+
+#define	SW_MAX_LAN_PORTS		4				/* max LAN ports */
+
+/* bits for SNMP data register (SEMCD) */
+#ifndef	CONFIG_ARCH_KS8695P
+#define	SW_SNMP_DATA_VALID	0x80000000		/* counter value is valid */
+#define	SW_SNMP_DATA_OVERFLOW	0x40000000		/* counter is overflow */
+#else
+#define	SW_SNMP_DATA_OVERFLOW	0x80000000		/* counter is overflow */
+#define	SW_SNMP_DATA_VALID	0x40000000		/* counter value is valid */
+#endif
+
+enum PORTS {
+	SW_PORT_1 = 0,
+	SW_PORT_2,
+	SW_PORT_3,
+	SW_PORT_4
+};
+
+/* bits related to power management */
+#define	POWER_POWERDOWN			0x00000010		/* port power down */
+#define	POWER_DMDX_DISABLE		0x00000008		/* disable auto MDI/MDIX */
+#define	POWER_FORCE_MDIX		0x00000004		/* if auto MDI/MDIX is disabled, force PHY into MDIX mode */
+#define	POWER_LOOPBACK			0x00000002		/* PHY loopback */
+
+#define SW_PHY_AUTO				0   /* autosense */
+#define SW_PHY_10BASE_T			1   /* 10Base-T */
+#define SW_PHY_10BASE_T_FD		2   /* 10Base-T Full Duplex */
+#define SW_PHY_100BASE_TX		3   /* 100Base-TX */
+#define SW_PHY_100BASE_TX_FD	4   /* 100Base-TX Full Duplex */
+
+#define SW_PHY_DEFAULT			SW_PHY_AUTO
+
+enum SPANNINGTREE {
+	SW_SPANNINGTREE_NONE,		/* no spanning tree */
+	SW_SPANNINGTREE_RX,			/* spanning tree, RX only */
+	SW_SPANNINGTREE_TX,			/* spanning tree, TX only */
+	SW_SPANNINGTREE_ALL,		/* spanning tree, both TX/RX */
+};
+
+/* bits related to port configuration register */
+#define	SW_PORT_DISABLE_AUTONEG	0x00008000		/* port disable auto nego */
+#define	SW_PORT_100BASE			0x00004000		/* force 100 when auto nego disabled */
+#define	SW_PORT_FULLDUPLEX		0x00002000		/* force full duplex when auto nego disabled */
+#define	SW_PORT_TX_SPANNINGTREE	0x00000080		/* spanning tree transmit enable */
+#define	SW_PORT_RX_SPANNINGTREE	0x00000040		/* spanning tree receive enable */
+#define	SW_PORT_NO_SPANNINGTREE	0x00000020		/* spanning tree disable */
+#define	SW_PORT_STORM_PROCTION	0x00000010		/* broadcast storm protection (ingress) */
+#define	SW_PORT_HI_PRIORITY		0x00000008		/* high priority (ingress) */
+#define	SW_PORT_TOS_ENABLE		0x00000004		/* Enable TOS based priotiry classification (ingress) */
+#define	SW_PORT_8021Q_ENABLE	0x00000002		/* Enable 802.1Q based priotiry classification (ingress) */
+#define	SW_PORT_PRIOTIRY_ENABLE	0x00000001		/* Enable priotiry function on the port (egress) */
+
+/* port 5 only */
+#define	SW_PORT_RX_DIRECT_MODE	0x00004000		/* receive direct mode for port 5 */
+#define	SW_PORT_TX_PRETAG_MODE	0x00002000		/* transmit pre-tag mode for port 5 */
+
+typedef struct _PORT_INFO {
+    uint16_t usTag;					/* tag value for the port (ingress) */
+	uint8_t byCrossTalkMask;		/* specify ports that this port can talk to */
+	uint8_t byStormProtection;		/* broadcast storm protection */
+	uint8_t bySpanningTree;			/* spanning tree */
+	uint8_t byDisableSpanningTreeLearn;	/* disable spanning tree learn for the port */
+	uint8_t byIngressPriority;		/* ingress priority */
+	uint8_t byIngressPriorityTOS;	/* TOS based ingress priority */
+	uint8_t byIngressPriority802_1P;/* 802.1p based ingress priority */
+	uint8_t byEgressPriority;		/* egress priority */
+} PORT_INFO, *PPORT_INFO;
+
+typedef struct _DMA_INFO {
+	unsigned short	usDMAId;	/* DMAID */
+	int32_t	nBaseAddr;		/* base address */
+	int32_t	nOffset;		/* DMA register offset */
+	uint8_t	bUseFIQ;		/* use FIQ or not */
+	uint32_t *pbaseVa;
+	uint32_t nResetCount;		/* DMA reset counter */
+
+	/* interrupt related */
+	uint32_t uIntMask;		/* interrupt mask checked within ISR */
+	uint32_t uLinkIntMask;		/* WAN link interrupt mask checked within ISR */
+	uint32_t uIntShift;		/* interrupt bit shift */
+
+	/* mac */
+	uint8_t stMacStation[MAC_ADDRESS_LEN];
+	uint8_t stMacCurrent[MAC_ADDRESS_LEN];
+	uint8_t stSwitchMac[MAC_ADDRESS_LEN];
+
+	/* spinlock */
+	spinlock_t	lock;		/* spin lock */
+	spinlock_t	lock_refill;	/* spin lock */
+
+	/* Tx related */
+	uint8_t	bTxStarted;		/* Tx DMA started or stopped! */
+	uint8_t	bTxFlowCtrl;		/* flow control for Tx DMA */
+	uint8_t	bTxOffLoad;		/* enable/disable Task offload for Tx DMA */
+	uint8_t	byTxPBL;		/* Tx PBL */
+	uint8_t bTxChecksum;		/* checksum enable/disable indicator */
+	uint8_t	bTxNoResource;		/* flag indicates out of Tx resource */
+	uint32_t uDebugDumpTxPkt;	/* flag to dump tx packet for debugging */
+
+	/* Tx desc related */
+	int32_t	nTxDesc;		/* number of Tx descriptors */
+	int32_t nTxDescNextAvail;	/* next available Tx descriptor */
+	int32_t nTxDescUsed;		/* used Tx descriptor */
+	volatile int32_t nTransmitCount;	/* number of packets to transmit */
+	int32_t nTxProcessedCount;	/* number of packets to transmitted */
+	int32_t	nTxDescTotal;		/* total number fo Tx descriptors */
+	int32_t nTransmitCoalescing;	/* Tx packets coalescing count */
+
+	TXDESC *pTxDescriptors;
+	dma_addr_t TxDescDMA;
+	struct ks8695_buffer *pTxSkb;
+	atomic_t nTxDescAvail;
+
+	/* Rx related */
+	uint8_t	bRxStarted;		/* Rx DMA started or stopped! */
+	uint8_t	bRxFlowCtrl;		/* flow control for Rx DMA */
+	uint8_t	bPort5FlowCtrl;		/* flow control for LAN port 5 */
+	uint8_t	bPortsFlowCtrl;		/* flow control for LAN port 1 - 4 */
+	uint8_t	byRxPBL;		/* Rx PBL */
+	uint8_t bRxChecksum;		/* checksum enable/disable indicator */
+	uint32_t uRxBufferLen;		/* rx buffer length */
+	uint32_t uDebugDumpRxPkt;	/* flag to dump rx packet for debugging */
+	uint32_t uRx1518plus;		/* rx packet counter for 1518 plus for debugging */
+	uint32_t uRxUnderSize;		/* rx packet counter for under size packets (< 64) */
+	uint32_t nMaxFilledCount;	/* max refilled count */
+	uint32_t nMaxProcessedCount;	/* max rx pkt count in one process cycle */
+
+	int32_t nRxDesc;		/* number of Rx descriptors */
+	int32_t nRxDescNextAvail;	/* next available Rx descriptor */
+	int32_t nRxDescNextToFill;	/* next Rx desc to fill new buffer to */
+	RXDESC *pRxDescriptors;
+	dma_addr_t RxDescDMA;
+	struct ks8695_buffer *pRxSkb;
+	atomic_t RxDescEmpty;		/* atomic flag for empty Rx descriptor  */
+	struct tasklet_struct rx_fill_tasklet;
+	int32_t	nRxDescTotal;		/* total number fo Rx descriptors */
+	int32_t	rx_fill_scheduled;	/* flag for rx fill schedule routine */
+
+#ifdef	RX_TASK
+	struct tasklet_struct rx_tasklet;
+	int32_t	rx_scheduled;		/* flag for rx receive task schedule routine */
+#endif
+
+#ifdef	TX_TASK
+	struct tasklet_struct tx_tasklet;
+	int32_t	tx_scheduled;		/* flag for tx receive task schedule routine */
+#endif
+
+	/* PHY related */
+	uint8_t	bAutoNegoInProgress[SW_MAX_LAN_PORTS];/* if set, means that auto nego is in progress!!! */
+	uint8_t	bLinkActive[SW_MAX_LAN_PORTS];		/* flag indicates whether link is active or not */
+	uint8_t bLinkChanged[SW_MAX_LAN_PORTS];		/* link changed indicator */
+	uint8_t bHalfDuplex[SW_MAX_LAN_PORTS];		/* HD/FD */
+	uint16_t usCType[SW_MAX_LAN_PORTS];		/* Convert type */
+	uint16_t usLinkSpeed[SW_MAX_LAN_PORTS];		/* link speed */
+	PORT_INFO	port[SW_MAX_LAN_PORTS + 1];	/* port related */
+	int32_t	nLinkChangeCount;			/* trace link change count */
+	uint8_t	byDisableAutoNego[SW_MAX_LAN_PORTS];	/* auto nego/disable auto nego/partial auto nego */
+	uint8_t bHalfDuplexDetected[SW_MAX_LAN_PORTS];	/* HD/FD detected based on partner's settings */
+
+	uint8_t	bRxDirectMode;				/* for port 5 only */
+	uint8_t	bTxRreTagMode;				/* for port 5 only */
+
+	uint8_t bPowerDownReset;	/* perform powerdown reset instead of soft reset */
+} DMA_INFO, *PDMA_INFO;
+
+typedef struct _INTCFG {
+	uint8_t	bFIQ;		/* use FIQ */
+	uint8_t	byPriority;	/* priority level for IRQ */
+} INTCFG, *PINTCFG;
+
+#endif	/*__KS8695_CHIPDEF_H*/
diff -urN linux-2.4.29/drivers/net/ks8695/ks8695_drv.h linux-2.4.29-uc1/drivers/net/ks8695/ks8695_drv.h
--- linux-2.4.29/drivers/net/ks8695/ks8695_drv.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/ks8695/ks8695_drv.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,210 @@
+/*
+	Copyright (c) 2002, Micrel Kendin Operations
+
+	Written 2002 by LIQUN RUAN
+
+	This software may be used and distributed according to the terms of 
+	the GNU General Public License (GPL), incorporated herein by reference.
+	Drivers based on or derived from this code fall under the GPL and must
+	retain the authorship, copyright and license notice. This file is not
+	a complete program and may only be used when the entire operating
+	system is licensed under the GPL.
+
+	The author may be reached as lruan@kendin.com
+	Micrel Kendin Operations
+	486 Mercury Dr.
+	Sunnyvale, CA 94085
+
+	This driver is for Kendin's KS8695 SOHO Router Chipset as ethernet driver.
+
+	Support and updates available at
+	www.kendin.com/ks8695/
+
+*/
+#ifndef __KS8695DRV_H
+#define __KS8695DRV_H
+
+struct _ADAPTER_STRUCT;
+typedef struct _ADAPTER_STRUCT ADAPTER_STRUCT, *PADAPTER_STRUCT;
+
+#include <linux/config.h>
+#include "ks8695_kcompat.h"
+//#include <linux/module.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include "ks8695_chipdef.h"
+
+#include "ks8695_fxhw.h"
+
+#define BAR_0						0
+
+#define DRV_INFO(S, args...)		printk(KERN_INFO "eth info: " S "\n" , ##args)
+#define DRV_DBG(S, args...)			printk(KERN_DEBUG "eth dbg: " S "\n" , ## args)
+#define DRV_ERR(S, args...)			printk(KERN_ERR "eth err: " S "\n" , ## args)
+#define DRV_WARN(S, args...)		printk(KERN_WARNING "eth warning: " S "\n" , ## args)
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#ifndef	ARM_LINUX
+#include <linux/malloc.h>
+#else
+/* arm linux complain about using malloc.h and suggested to use slab.h instead */
+#include <linux/slab.h>
+#endif
+#include <linux/interrupt.h>
+#include <linux/string.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <linux/capability.h>
+
+#define TRUE			1
+#define FALSE			0
+
+/* command line options defaults */
+#define TXDESC_DEFAULT	128	
+#define TXDESC_MAX		256
+#define TXDESC_MIN		64
+
+#define RXDESC_DEFAULT	128 
+#define RXDESC_MAX		256
+#define RXDESC_MIN		64
+
+#define OPTION_UNSET    	-1
+#define OPTION_DISABLED 	0
+#define OPTION_ENABLED  	1
+
+#if defined(CONFIG_MACH_LITE300) || defined(CONFIG_MACH_CM4008) || \
+    defined(CONFIG_MACH_CM41xx)
+#define RXCHECKSUM_DEFAULT	OPTION_DISABLED
+#define TXCHECKSUM_DEFAULT	OPTION_DISABLED
+#else
+#define RXCHECKSUM_DEFAULT	OPTION_ENABLED
+#define TXCHECKSUM_DEFAULT	OPTION_ENABLED
+#endif
+#define FLOWCONTROL_DEFAULT	OPTION_ENABLED
+
+#define PBL_DEFAULT		8	     /* 0 for unlimited, other value for (4 * x), our VxWorks shows that 8 is optimized */	
+
+// Supported RX Buffer Sizes
+#define BUFFER_1568		1568		/* 0x620 */
+#define BUFFER_2048		2048
+#define	BUFFER_4K		4096
+
+// standard ethernet header
+#define ENET_HEADER_SIZE                14
+#define MAXIMUM_ETHERNET_PACKET_SIZE	1514
+#define MINIMUM_ETHERNET_PACKET_SIZE	60
+#define ETH_CRC_LENGTH			4
+#define ETH_LENGTH_OF_ADDRESS		6
+
+#define KS8695_ROUNDUP(size, unit) (unit * ((size + unit - 1) / unit))
+
+// socket buffer
+struct ks8695_buffer {
+	struct sk_buff *skb;
+	dma_addr_t     dma;
+	unsigned long  length;
+	int            direction;
+};
+
+// Adapter->flags definitions
+#define KS8695_BOARD_OPEN	0
+
+/* board specific private data structure */
+struct _ADAPTER_STRUCT {
+	struct _ADAPTER_STRUCT *next;
+	struct _ADAPTER_STRUCT *prev;
+
+	uint32_t flags;
+	uint32_t bd_number;
+	struct timer_list timer_id;
+
+	struct net_device *netdev;
+	struct pci_dev *pdev;
+	struct net_device_stats net_stats;
+
+	DMA_INFO	stDMAInfo;					/* DMA information */
+	u8	rev;		/* revision, for KS8695P */
+};
+
+#define	DI		(Adapter->stDMAInfo)		/* Dma Information */
+#define	DPI		(Adapter->stDMAInfo.port)	/* Dma Port Inforamtion */
+
+/* ks8695_main.c */
+extern int ks8695_init_module(void);
+extern void ks8695_exit_module(void);
+extern int ks8695_probe(struct pci_dev *pdev,
+                                 const struct pci_device_id *ent);
+extern void ks8695_remove(struct pci_dev *pdev);
+extern void ks8695_delete(PADAPTER_STRUCT Adapter);
+extern int ks8695_open(struct net_device *netdev);
+extern int ks8695_close(struct net_device *netdev);
+extern void ks8695_set_multi(struct net_device *netdev);
+extern int ks8695_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
+extern struct net_device_stats *ks8695_get_stats(struct net_device *netdev);
+extern int ks8695_change_mtu(struct net_device *netdev, int new_mtu);
+extern int ks8695_set_mac(struct net_device *netdev, void *p);
+extern void ks8695_isr(int irq, void *data, struct pt_regs *regs);
+/* for I-cache lockdown or FIQ purpose */
+extern void ks8695_isre(void);	/* to fix compiler complain if integrated with kernel */
+extern void ks8695_isr_link(int irq, void *data, struct pt_regs *regs);
+extern int ks8695_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
+extern void ks8695_watchdog(unsigned long data);
+
+/* ks8695_fxhw.c */
+extern BOOLEAN ks8695_ChipInit(PADAPTER_STRUCT Adapter, BOOLEAN bResetPhy);
+extern void macSetLoopback(PADAPTER_STRUCT Adapter, BOOLEAN bLoopback);
+extern void macStopAll(PADAPTER_STRUCT Adapter);
+extern void macStartRx(PADAPTER_STRUCT Adapter, BOOLEAN bStart);
+extern void macStartTx(PADAPTER_STRUCT Adapter, BOOLEAN bStart);
+extern int macSetStationEx(PADAPTER_STRUCT Adapter, UCHAR *pMac, UINT uIndex);
+extern int macResetStationEx(PADAPTER_STRUCT Adapter, UCHAR *pMac);
+extern void macGetStationAddress(PADAPTER_STRUCT Adapter, uint8_t *pMacAddress);
+extern void macEnableInterrupt(PADAPTER_STRUCT Adapter, BOOLEAN bEnable);
+extern void macSetStationAddress(PADAPTER_STRUCT Adapter, uint8_t *pMacAddress);
+extern int macGetIndexStationEx(PADAPTER_STRUCT Adapter);
+
+/* switch related */
+extern void swSetLED(PADAPTER_STRUCT Adapter, BOOLEAN bLED1, LED_SELECTOR nSel);
+extern int swGetPhyStatus(PADAPTER_STRUCT Adapter, UINT uPort);
+extern UINT swReadSNMPReg(PADAPTER_STRUCT Adapter, UINT uIndex);
+extern void swResetSNMPInfo(PADAPTER_STRUCT Adapter);
+extern void swEnableSwitch(PADAPTER_STRUCT Adapter, UINT enable);
+extern void swDetectPhyConnection(PADAPTER_STRUCT Adapter, UINT uPort);
+extern BOOLEAN swPhyLoopback(PADAPTER_STRUCT Adapter, UINT uPort, BOOLEAN bLoopback);
+extern BOOLEAN swGetWANLinkStatus(PADAPTER_STRUCT Adapter);
+extern void swAutoNegoAdvertisement(PADAPTER_STRUCT Adapter, UINT uPort);
+extern void swPhyReset(PADAPTER_STRUCT Adapter, UINT uPort);
+extern void swConfigureMediaType(PADAPTER_STRUCT Adapter, UINT uPort, UINT uSpeed, UINT uDuplex);
+extern void swConfigTagRemoval(PADAPTER_STRUCT Adapter, UINT uPort, UINT bRemoval);
+extern void swConfigTagInsertion(PADAPTER_STRUCT Adapter, UINT uPort, UINT bInsert);
+extern void swConfigurePort(PADAPTER_STRUCT Adapter, UINT uPort);
+
+extern void gpioSet(PADAPTER_STRUCT Adapter, UINT uPort, UINT bSet);
+
+#ifdef	CONFIG_ARCH_KS8695P
+extern void enablePhyLoopback(PADAPTER_STRUCT Adapter, UINT uPort, UINT bEnable);
+extern void enableRemoteLoopback(PADAPTER_STRUCT Adapter, UINT uPort, UINT bEnable);
+extern void enablePhyIsolate(PADAPTER_STRUCT Adapter, UINT uPort, UINT bEnable);
+extern void forcePhyLink(PADAPTER_STRUCT Adapter, UINT uPort, UINT bEnable);
+extern void dumpDynamicMacTable(PADAPTER_STRUCT Adapter);
+extern void dumpStaticMacTable(PADAPTER_STRUCT Adapter);
+void enableTxRateControl(PADAPTER_STRUCT Adapter, UINT uPort, UINT bEnable,
+	UINT bEnableLow, UINT bEnableHigh);
+void enableRxRateControl(PADAPTER_STRUCT Adapter, UINT uPort, UINT bEnable,
+	UINT bEnableLow, UINT bEnableHigh);
+void setTxRate(PADAPTER_STRUCT Adapter, UINT uPort, UINT lrate, UINT hrate);
+void setRxRate(PADAPTER_STRUCT Adapter, UINT uPort, UINT lrate, UINT hrate);
+#endif
+
+#endif /* __KS8695DRV_H */
diff -urN linux-2.4.29/drivers/net/ks8695/ks8695_fxhw.c linux-2.4.29-uc1/drivers/net/ks8695/ks8695_fxhw.c
--- linux-2.4.29/drivers/net/ks8695/ks8695_fxhw.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/ks8695/ks8695_fxhw.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,2751 @@
+/*
+	Copyright (c) 2002-2003, Micrel Semiconductor
+
+	Written 2002 by LIQUN RUAN
+
+	This software may be used and distributed according to the terms of 
+	the GNU General Public License (GPL), incorporated herein by reference.
+	Drivers based on or derived from this code fall under the GPL and must
+	retain the authorship, copyright and license notice. This file is not
+	a complete program and may only be used when the entire operating
+	system is licensed under the GPL.
+
+	The author may be reached as liqun.ruan@micrel.com
+	Micrel Semiconductor
+	1931 Fortune Dr.
+	San Jose, CA 95131
+
+	This driver is for Micrel's KS8695/KS8695P SOHO Router Chipset as ethernet driver.
+
+	Support and updates available at
+	www.micrel.com/ks8695/		not ready yet!!!
+
+*/
+#include "ks8695_drv.h"
+#include "ks8695_chipdef.h"
+#include "ks8695_ioctrl.h"
+#include "ks8695_cache.h"
+
+static int macReset(PADAPTER_STRUCT Adapter);
+static void macConfigure(PADAPTER_STRUCT Adapter);
+static void macConfigureFlow(PADAPTER_STRUCT Adapter, uint8_t bFlowCtrl);
+static void macConfigureInterrupt(PADAPTER_STRUCT Adapter);
+
+static void swConfigure(PADAPTER_STRUCT Adapter);
+static void swCreateLookUpTable(PADAPTER_STRUCT Adapter);
+
+static void gpioConfigure(PADAPTER_STRUCT Adapter);
+
+#ifdef	CONFIG_ARCH_KS8695P
+void forceFlowControl(PADAPTER_STRUCT Adapter, UINT uPort, UINT bOn);
+void backPressureEnable(PADAPTER_STRUCT Adapter, UINT uPort, UINT bOn);
+#endif
+
+/*
+ * ks8695_ChipInit
+ *	This function is used to do chip initialization.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *	bResetPhy	flag indicates whether to reset PHY as well
+ *
+ * Return(s)
+ *	TRUE	if success
+ *	FALSE	otherwise
+ */
+BOOLEAN ks8695_ChipInit(PADAPTER_STRUCT Adapter, BOOLEAN bResetPhy)
+{
+	BOOLEAN bStatus;
+	struct net_device *netdev = Adapter->netdev;
+	UINT i;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	if (bResetPhy) {
+		/* phy related initialization */
+		i = 0;
+		swPhyReset(Adapter, i);
+		if (DMA_LAN == DI.usDMAId) {
+			for (i = 1; i < SW_MAX_LAN_PORTS; i++) {
+				swPhyReset(Adapter, i);
+				/* turn off GPIO, to make sure that if there is no cable connection, no light */
+				gpioSet(Adapter, i, FALSE);
+			}
+		}
+		swAutoNegoAdvertisement(Adapter, 0);
+		if (DMA_LAN == DI.usDMAId) {
+			for (i = 1; i < SW_MAX_LAN_PORTS; i++) {
+				swAutoNegoAdvertisement(Adapter, i);
+			}
+		}
+	}
+
+	/* setup mac related stuff */
+	bStatus = macReset(Adapter);
+	if (bStatus) {
+		DRV_ERR("%s: macReset failed", __FUNCTION__);
+		return FALSE;
+	}
+	macConfigure(Adapter);
+	macConfigureInterrupt(Adapter);
+
+	/* turn off GPIO, to make sure that if there is no cable connection, no light */
+	gpioSet(Adapter, 0, FALSE);
+	/* configuration switch related to LAN only */
+	if (DMA_LAN == DI.usDMAId) {
+		swConfigure(Adapter);
+		swCreateLookUpTable(Adapter);
+		for (i = 1; i < SW_MAX_LAN_PORTS; i++) {
+			/* turn off GPIO, to make sure that if there is no cable connection, no light */
+			gpioSet(Adapter, i, FALSE);
+		}
+	}
+
+	/* copy the MAC address out of Station registers */
+	macSetStationAddress(Adapter, DI.stMacStation);
+	if (netdev->addr_len < MAC_ADDRESS_LEN)
+		netdev->addr_len = MAC_ADDRESS_LEN;
+	memcpy(netdev->dev_addr, DI.stMacStation, netdev->addr_len);
+	memcpy(DI.stMacCurrent, netdev->dev_addr, netdev->addr_len);
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("MAC address %02X:%02X:%02X:%02X:%02X:%02X", 
+		DI.stMacStation[0], 
+		DI.stMacStation[1],
+		DI.stMacStation[2],
+		DI.stMacStation[3], 
+		DI.stMacStation[4],
+		DI.stMacStation[5]); 
+#endif
+
+	gpioConfigure(Adapter);
+
+	/*RLQ, 11/20/2002, fix based on AN112. Changing transmitter gain in KS8695 to improve
+	  the calbe length at which the Ethernet can operate */
+	if (0 == Adapter->rev) {
+		/* for KS8695 */
+		KS8695_WRITE_REG(KS8695_WAN_PHY_CONTROL, 0x0000b000);
+	}
+	else {
+		/* for KS8695P, rev A */
+		KS8695_WRITE_REG(KS8695_WAN_PHY_CONTROL, 0x0200b000);
+	}
+
+	return bStatus ? FALSE : TRUE;
+}
+
+#define	IRQ_WAN_LEVEL	12
+#define	IRQ_LAN_LEVEL	10
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+#define	IRQ_HPNA_LEVEL	8
+#endif
+
+/* move to source file later */
+static INTCFG stDMAIntCfg[32] = {
+	{ 0, -1 },		/* -1 don't touch, it's not ours */
+	{ 0, -1 },
+	{ 0, -1 },
+	{ 0, -1 },
+	{ 0, -1 },
+	{ 0, -1 },
+	{ 0, -1 },
+	{ 0, -1 },
+	{ 0, -1 },
+	{ 0, -1 },
+	{ 0, -1 },
+	{ 0, -1 },		/* bit 11 */
+
+	{ 0, 0x0b },		/* bit 12, LAN */
+	{ 0, 0x0b },
+	{ 0, 0x0a },
+	{ 0, 0x0a },
+	{ 0, 0x0f },
+	{ 0, 0x0f },
+
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	{ 0, IRQ_HPNA_LEVEL },	/* bit 18, HPNA */
+	{ 0, IRQ_HPNA_LEVEL },
+	{ 0, IRQ_HPNA_LEVEL },
+	{ 0, IRQ_HPNA_LEVEL },
+	{ 0, IRQ_HPNA_LEVEL },
+	{ 0, IRQ_HPNA_LEVEL },
+#else
+	{ 0, -1 },		/* bit 18, KS8695P doesn't have HPNA port */
+	{ 0, -1 },
+	{ 0, -1 },
+	{ 0, -1 },
+	{ 0, -1 },
+	{ 0, -1 },
+#endif
+	{ 0, -1 },		/* bit 24 */
+
+	{ 0, 0x0b },		/* bit 25, WAN */
+	{ 0, 0x0b },
+	{ 0, 0x0a },
+	{ 0, 0x0a },
+	{ 0, 0x0f },
+	{ 0, 0x0f },
+	{ 0, IRQ_WAN_LEVEL }	/* WAN link */
+};
+
+/*
+ * macReset
+ *	This function will execute a soft reset the chipset.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *
+ * Return(s)
+ *	0		if success
+ *	none zero otherwise
+ */
+int macReset(PADAPTER_STRUCT Adapter)
+{
+	int nTimeOut = 1000;
+	UINT32 uReg;
+	unsigned long flags;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	spin_lock_irqsave(&DI.lock, flags);
+	/*spin_lock(&DI.lock);*/
+	/* disable IER if any */
+	uReg = KS8695_READ_REG(KS8695_INT_ENABLE);
+	switch (DI.usDMAId) {
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	case DMA_HPNA:
+		uReg &= ~INT_HPNA_MASK;
+		break;
+#endif
+
+	case DMA_LAN:
+		uReg &= ~INT_LAN_MASK;
+		break;
+
+	default:
+	case DMA_WAN:
+		uReg &= ~INT_WAN_MASK;
+		break;
+	}
+	KS8695_WRITE_REG(KS8695_INT_ENABLE, uReg);
+	/*spin_unlock(&DI.lock);*/
+	spin_unlock_irqrestore(&DI.lock, flags);
+
+	/* reset corresponding register and wait for completion */
+	KS8695_WRITE_REG(REG_TXCTRL + DI.nOffset, DMA_SOFTRESET);
+	do
+	{
+		DelayInMilliseconds(1);
+		uReg = KS8695_READ_REG(REG_TXCTRL + DI.nOffset);
+		if (!(uReg & DMA_SOFTRESET))
+			break;
+	} while (--nTimeOut);
+
+	if (nTimeOut < 1) {
+		DRV_ERR("%s> timeout error", __FUNCTION__);
+		return -ETIMEDOUT;
+	}
+
+	/* clear statistic counters */
+	swResetSNMPInfo(Adapter);
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s> succeeded (timeout count=%d)", __FUNCTION__, nTimeOut);
+#endif
+
+	return 0;
+}
+
+/*
+ * macConfigure
+ *	This function is used to set MAC control register based on configurable
+ *  option settings.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *
+ * Return(s)
+ *	NONE
+ */
+void macConfigure(PADAPTER_STRUCT Adapter)
+{
+	UINT uRxReg, uTxReg;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	/* read TX mode register */
+	uTxReg = KS8695_READ_REG(REG_TXCTRL + DI.nOffset);
+	/* clear PBL bits first */
+	uTxReg &= ~DMA_PBLTMASK;				/* 29:24 */
+	if (DI.byTxPBL)
+		uTxReg |= ((uint32_t)DI.byTxPBL << DMA_PBLTSHIFT);
+
+	if (DI.bTxChecksum) {
+		uTxReg |= (DMA_IPCHECKSUM | DMA_TCPCHECKSUM | DMA_UDPCHECKSUM);
+	}
+	else {
+		uTxReg &= ~(DMA_IPCHECKSUM | DMA_TCPCHECKSUM | DMA_UDPCHECKSUM);
+	}
+
+	if (DI.bTxFlowCtrl)
+	{
+		uTxReg |= DMA_FLOWCTRL;
+	}
+	else {
+		uTxReg &= ~DMA_FLOWCTRL;
+	}
+	uTxReg |= (DMA_PADDING | DMA_CRC);
+	/* write TX mode register */
+	KS8695_WRITE_REG(REG_TXCTRL + DI.nOffset, uTxReg);
+
+	/* read RX mode register */
+	uRxReg = KS8695_READ_REG(REG_RXCTRL + DI.nOffset);
+	/* clear PBL bits first */
+	uRxReg &= ~DMA_PBLTMASK;				/* 29:24 */
+	if (DI.byRxPBL)
+		uRxReg |= ((uint32_t)DI.byRxPBL << DMA_PBLTSHIFT);
+	/* checksum */
+	if (DI.bRxChecksum) {
+		uRxReg |= (DMA_IPCHECKSUM | DMA_TCPCHECKSUM | DMA_UDPCHECKSUM);
+	}
+	else {
+		uRxReg &= ~(DMA_IPCHECKSUM | DMA_TCPCHECKSUM | DMA_UDPCHECKSUM);
+	}
+	/* flow control */
+	if (DI.bRxFlowCtrl)
+	{
+		uRxReg |= DMA_FLOWCTRL;
+	}
+	else {
+		uRxReg &= ~DMA_FLOWCTRL;
+	}
+	/* set unicast only, and let ks8695_set_multi function to set the rest */
+	uRxReg |= DMA_UNICAST;
+
+	/* write RX mode register */
+	KS8695_WRITE_REG(REG_RXCTRL + DI.nOffset, uRxReg);
+}
+
+/*
+ * macConfigureFlow
+ *	This function is used to set mac flow control as a workaround for WAN port.
+ *  option settings.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *	bFlowCtrl	flow control to set
+ *
+ * Return(s)
+ *	NONE
+ */
+void macConfigureFlow(PADAPTER_STRUCT Adapter, uint8_t bFlowCtrl)
+{
+	UINT uRxReg, uTxReg;
+	BOOLEAN bTxStarted, bRxStarted;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s: flowctrl = %d", __FUNCTION__, bFlowCtrl);
+#endif
+
+	/* need to stop mac engines if started */
+	bTxStarted = DI.bTxStarted;
+	bRxStarted = DI.bRxStarted;
+	if (bRxStarted)
+		macStartRx(Adapter, FALSE);
+	if (bTxStarted)
+		macStartTx(Adapter, FALSE);
+
+	/* read TX mode register */
+	uTxReg = KS8695_READ_REG(REG_TXCTRL + DI.nOffset);
+	if (bFlowCtrl)
+	{
+		uTxReg |= DMA_FLOWCTRL;
+	}
+	else {
+		uTxReg &= ~DMA_FLOWCTRL;
+	}
+	/* write TX mode register */
+	KS8695_WRITE_REG(REG_TXCTRL + DI.nOffset, uTxReg);
+
+	/* read RX mode register */
+	uRxReg = KS8695_READ_REG(REG_RXCTRL + DI.nOffset);
+	if (bFlowCtrl)
+	{
+		uRxReg |= DMA_FLOWCTRL;
+	}
+	else {
+		uRxReg &= ~DMA_FLOWCTRL;
+	}
+	/* write RX mode register */
+	KS8695_WRITE_REG(REG_RXCTRL + DI.nOffset, uRxReg);
+
+	if (bRxStarted)
+		macStartRx(Adapter, TRUE);
+	if (bTxStarted)
+		macStartTx(Adapter, TRUE);
+}
+
+/*
+ * macSetLoopback
+ *	This function is used to set MAC lookback mode (for debugging purpose)
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *
+ * Return(s)
+ *	NONE
+ */
+void macSetLoopback(PADAPTER_STRUCT Adapter, BOOLEAN bLoopback)
+{
+	UINT uTxReg;
+	BOOLEAN bTxStarted, bRxStarted;
+
+	bTxStarted = DI.bTxStarted;
+	bRxStarted = DI.bRxStarted;
+	if (bRxStarted)
+		macStartRx(Adapter, FALSE);
+	if (bTxStarted)
+		macStartTx(Adapter, FALSE);
+
+	/* read TX mode register */
+	uTxReg = KS8695_READ_REG(REG_TXCTRL + DI.nOffset);
+
+	if (bLoopback)
+	{
+		uTxReg |= DMA_LOOPBACK;
+	}
+	else {
+		uTxReg &= ~DMA_LOOPBACK;
+	}
+
+	/* write TX mode register */
+	KS8695_WRITE_REG(REG_TXCTRL + DI.nOffset, uTxReg);
+
+	if (bRxStarted)
+		macStartRx(Adapter, TRUE);
+	if (bTxStarted)
+		macStartTx(Adapter, TRUE);
+}
+
+/*
+ *  macStartRx
+ *      This routine will start/stop RX machine.
+ *
+ *  Inputs:
+ *      Adapter		pointer to ADAPTER_STRUCT data structure.
+ *		bStart		TRUE if start Rx machine, FALSE if stop it
+ *
+ *  Returns:
+ *      NONE
+ */
+void macStartRx(PADAPTER_STRUCT Adapter, BOOLEAN bStart)
+{
+	UINT32 uReg;
+
+	uReg = KS8695_READ_REG(REG_RXCTRL + DI.nOffset);
+	if (bStart) {
+		/* start RX machine */
+		uReg |= DMA_START;
+		DI.bRxStarted = FALSE;
+	} else {
+		/* Stop RX machine */
+		uReg &= ~DMA_START;
+		DI.bRxStarted = FALSE;
+	}
+	KS8695_WRITE_REG(REG_RXCTRL + DI.nOffset, uReg);
+
+	/* if there descriptors available for rx, tick off Rx engine */
+	if (bStart) {
+		if (atomic_read(&DI.RxDescEmpty) < DI.nRxDescTotal) {
+			KS8695_WRITE_REG(REG_RXSTART + DI.nOffset, 1);
+		}
+	}
+	else {
+		/* clear corresponding ISR bits after stopped */
+		KS8695_WRITE_REG(KS8695_INT_STATUS, DI.uIntMask);
+	}
+}
+
+/*
+ *  macStartTx
+ *      This routine will start/stop TX machine.
+ *
+ *  Inputs:
+ *      Adapter		pionter to ADAPTER_STRUCT data structure.
+ *		bStart		TRUE if start Tx machine, FALSE if stop it
+ *
+ *  Returns:
+ *      NONE
+ */
+void macStartTx(PADAPTER_STRUCT Adapter, BOOLEAN bStart)
+{
+	UINT32 uReg;
+
+	uReg = KS8695_READ_REG(REG_TXCTRL + DI.nOffset);
+	if (bStart) {
+		/* start TX machine */
+		uReg |= DMA_START;
+		KS8695_WRITE_REG(REG_TXCTRL + DI.nOffset, uReg);
+		DI.bTxStarted = FALSE;
+		/* clear corresponding ISR bits after stopped */
+		KS8695_WRITE_REG(KS8695_INT_STATUS, DI.uIntMask);
+	} else {
+		/* Stop TX machine */
+		uReg &= ~DMA_START;
+		KS8695_WRITE_REG(REG_TXCTRL + DI.nOffset, uReg);
+		DelayInMilliseconds(2);
+		DI.bTxStarted = FALSE;
+	}
+}
+
+/*
+ * macStopAll
+ *	This function is use to stop both Tx/Rx.
+ *
+ * Argument(s)
+ *      Adapter		pionter to ADAPTER_STRUCT data structure.
+ *
+ * Return(s)
+ *	NONE
+ */
+void macStopAll(PADAPTER_STRUCT Adapter)
+{
+	/* stop Rx and Tx */
+	macStartRx(Adapter, FALSE);
+	macStartTx(Adapter, FALSE);
+	
+	/* disable interrupt!!! */
+	macEnableInterrupt(Adapter, FALSE);
+}
+
+/*
+ * macSetStationEx
+ *	This function is use to set extra MAC station address
+ *
+ * Argument(s)
+ *      Adapter		pionter to ADAPTER_STRUCT data structure.
+ *		pMac		pointer to mac address buffer (should be 6)
+ *		uIndex		index of extra mac address to set
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+int macSetStationEx(PADAPTER_STRUCT Adapter, UCHAR *pMac, UINT uIndex)
+{
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	/* do we need to set multicast addr to extra station registers? */
+	if (uIndex < MAC_MAX_EXTRA) {
+		uint32_t uLowAddress, uHighAddress;
+
+		uLowAddress = (*(pMac + 5)		|
+					  (*(pMac + 4) << 8)	|
+					  (*(pMac + 3) << 16)|
+					  *(pMac + 2) << 24);
+
+		uHighAddress = (*(pMac + 1)		|
+					   *pMac << 8);
+
+		/* make sure mac address is not all zero */
+		if (uLowAddress | uHighAddress) {
+			/* enable additional MAC */
+			uHighAddress |= DMA_MACENABLE;
+			KS8695_WRITE_REG(REG_MAC0_LOW + DI.nOffset + uIndex * 8, uLowAddress);
+			KS8695_WRITE_REG(REG_MAC0_HIGH + DI.nOffset + uIndex * 8, uHighAddress);
+			return 0;
+		}
+	}
+
+	return ~EINVAL;
+}
+
+/*
+ * macResetStationEx
+ *	This function is use to clear extra MAC station address if set before
+ *
+ * Argument(s)
+ *      Adapter		pionter to ADAPTER_STRUCT data structure.
+ *		nIndex		index of extra mac address to set
+ *		pMac		pointer to mac address buffer (should be 6)
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+int macResetStationEx(PADAPTER_STRUCT Adapter, UCHAR *pMac)
+{
+	int	i, j;
+	uint32_t uLowAddress, uHighAddress;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	uLowAddress = (*(pMac + 5)		|
+				  (*(pMac + 4) << 8)	|
+				  (*(pMac + 3) << 16)|
+				  *(pMac + 2) << 24);
+
+	uHighAddress = (*(pMac + 1)		|
+				   *pMac << 8);
+
+	/* set mac enable bit for comparison purpose only! */
+	uHighAddress |= DMA_MACENABLE;
+
+	/* if match is found, remove it (set to 0) */
+	for (i = 0; i < MAC_MAX_EXTRA; i++) {
+		j = i * 8;
+		if (uLowAddress == KS8695_READ_REG(REG_MAC0_LOW + DI.nOffset + j) &&
+			uHighAddress == KS8695_READ_REG(REG_MAC0_HIGH + DI.nOffset + j)) {
+			KS8695_WRITE_REG(REG_MAC0_LOW + DI.nOffset + j, 0);
+			KS8695_WRITE_REG(REG_MAC0_HIGH + DI.nOffset + j, 0);
+		}
+	}
+
+    return 0;
+}
+
+/*
+ * macGetIndexStationEx
+ *	This function is use to get the index of empty station
+ *
+ * Argument(s)
+ *      Adapter		pionter to ADAPTER_STRUCT data structure.
+ *
+ * Return(s)
+ *	nIndex			index of empty to use
+ *	negative value	if it is full
+ */
+int macGetIndexStationEx(PADAPTER_STRUCT Adapter)
+{
+	int	i;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	for (i = 0; i < MAC_MAX_EXTRA; i++) {
+		if (!(KS8695_READ_REG(REG_MAC0_HIGH + DI.nOffset + i * 8) & DMA_MACENABLE)) {
+			return i;
+		}
+	}
+
+	DRV_WARN("%s: no empty slot for Additional Station Address", __FUNCTION__);
+    return -1;
+}
+
+/* Interrupt Bit definitions */
+#define	IB_WAN_LINK		31
+#define	IB_WAN_RX_STOPPED	25
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+#define	IB_HPNA_TX		23
+#define	IB_HPNA_RX_STOPPED	18
+#endif
+#define	IB_LAN_TX		17
+#define	IB_LAN_RX_STOPPED	12
+
+/*
+ *  macConfigureInterrupt
+ *      This routine is used to configure interrupt priority
+ *
+ *  Inputs:
+ *      Adapter		pionter to ADAPTER_STRUCT data structure.
+ *
+ *  Returns:
+ *      NONE
+ */
+void macConfigureInterrupt(PADAPTER_STRUCT Adapter)
+{
+	int	i;
+	UINT	uIMR, uIPR = 0;
+	unsigned long flags;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	spin_lock_irqsave(&DI.lock, flags);
+	/*spin_lock(&DI.lock);*/
+	uIMR = KS8695_READ_REG(KS8695_INT_CONTL);
+	switch (DI.usDMAId) {
+		case DMA_LAN:
+			for (i = IB_LAN_RX_STOPPED; i <= IB_LAN_TX; i++) {
+				if (stDMAIntCfg[i].bFIQ) {
+					uIMR |= (1L << i);
+					DI.bUseFIQ = TRUE;
+				}
+				else {
+					uIMR &= ~(1L << i);
+					uIPR |= ((UINT)(stDMAIntCfg[i].byPriority) & 0xf) << (i - IB_LAN_RX_STOPPED + 1) * 4;
+				}
+			}
+			KS8695_WRITE_REG(KS8695_INT_LAN_PRIORITY, uIPR);
+			break;
+
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+		case DMA_HPNA:
+			for (i = IB_HPNA_RX_STOPPED; i <= IB_HPNA_TX; i++) {
+				if (stDMAIntCfg[i].bFIQ) {
+					uIMR |= (1L << i);
+					DI.bUseFIQ = TRUE;
+				}
+				else {
+					uIMR &= ~(1L << i);
+					uIPR |= ((UINT)(stDMAIntCfg[i].byPriority) & 0xf) << (i - IB_HPNA_RX_STOPPED + 1) * 4;
+				}
+			}
+			KS8695_WRITE_REG(KS8695_INT_HPNA_PRIORITY, uIPR);
+			break;
+#endif
+
+		case DMA_WAN:
+		default:
+			for (i = IB_WAN_RX_STOPPED; i <= IB_WAN_LINK; i++) {
+				if (stDMAIntCfg[i].bFIQ) {
+					uIMR |= (1L << i);
+					DI.bUseFIQ = TRUE;
+				}
+				else {
+					uIMR &= ~(1L << i);
+					uIPR |= ((UINT)(stDMAIntCfg[i].byPriority) & 0xf) << (i - IB_WAN_RX_STOPPED + 1) * 4;
+				}
+			}
+			KS8695_WRITE_REG(KS8695_INT_WAN_PRIORITY, uIPR);
+			break;
+	}
+	KS8695_WRITE_REG(KS8695_INT_CONTL, uIMR);
+	/*spin_unlock(&DI.lock);*/
+	spin_unlock_irqrestore(&DI.lock, flags);
+}
+
+/*
+ *  macEnableInterrupt
+ *      This routine is used to enable/disable interrupt related to MAC only
+ *
+ *  Inputs:
+ *      Adapter		pionter to ADAPTER_STRUCT data structure.
+ *		bEnable		enable/disable interrupt
+ *
+ *  Returns:
+ *      NONE
+ */
+void macEnableInterrupt(PADAPTER_STRUCT Adapter, BOOLEAN bEnable)
+{
+	UINT	uIER;
+
+	spin_lock(&DI.lock);
+	uIER = KS8695_READ_REG(KS8695_INT_ENABLE);
+	switch (DI.usDMAId) {
+		case DMA_LAN:
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+		case DMA_HPNA:
+#endif
+			if (bEnable)
+				uIER |= DI.uIntMask;
+			else
+				uIER &= ~DI.uIntMask;
+			break;
+
+		case DMA_WAN:
+			if (bEnable)
+				uIER |= (DI.uIntMask | DI.uLinkIntMask);
+			else
+				uIER &= ~(DI.uIntMask | DI.uLinkIntMask);
+			break;
+
+		default:
+			DRV_INFO("unsupported option");
+			break;
+	}
+	KS8695_WRITE_REG(KS8695_INT_ENABLE, uIER);
+	spin_unlock(&DI.lock);
+	ks8695_power_saving(bEnable);
+}
+
+/*
+ * macGetStationAddress
+ *	This function reads MAC address from station address registers.
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT struct
+ *  pMacAddress	pointer to a byte array to hold MAC address (at least 6 bytes long)
+ *
+ * Return(s)
+ *	NONE.
+ */
+void macGetStationAddress(PADAPTER_STRUCT Adapter, uint8_t *pMacAddress)
+{
+	UINT32 uTmp;
+	int i;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	/* read low 4 buytes, byte order (e.g. in our NIC card, 00101a00000d) */
+	uTmp = KS8695_READ_REG(REG_STATION_LOW + DI.nOffset);
+	for (i = (MAC_ADDRESS_LEN - 1); i > 1; i--)
+	{
+		pMacAddress[i] = (UCHAR)(uTmp & 0x0ff);
+		uTmp >>= 8;
+	}
+	/* read high 2 bytes */
+	uTmp = KS8695_READ_REG(REG_STATION_HIGH + DI.nOffset);
+	pMacAddress[1] = (UCHAR)(uTmp & 0x0ff);
+	uTmp >>= 8;
+	pMacAddress[0] = (UCHAR)(uTmp & 0x0ff);
+}
+
+/*
+ * macSetStationAddress
+ *	This function sets MAC address to given type (WAN, LAN or HPHA)
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT struct
+ *  pMacAddress	pointer to a byte array to hold MAC address (at least 6 bytes long)
+ *
+ * Return(s)
+ *	NONE.
+ */
+void macSetStationAddress(PADAPTER_STRUCT Adapter, uint8_t *pMacAddress)
+{
+	UINT32 uLow, uHigh;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	uLow = ((UINT32)pMacAddress[2] << 24);
+	uLow += ((UINT32)pMacAddress[3] << 16);
+	uLow += ((UINT32)pMacAddress[4] << 8);
+	uLow += pMacAddress[5];
+	uHigh = ((UINT32)pMacAddress[0] << 8) + pMacAddress[1];
+	KS8695_WRITE_REG(REG_STATION_LOW + DI.nOffset, uLow);
+	KS8695_WRITE_REG(REG_STATION_HIGH + DI.nOffset, uHigh);
+}
+
+/*
+ * swConfigurePort
+ *	This function is used to configure a give port for LAN.
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT struct
+ *  uPort		port to start
+ *
+ * Return(s)
+ *	NONE.
+ */
+void swConfigurePort(PADAPTER_STRUCT Adapter, UINT uPort)
+{
+	UINT	uReg, uOff;
+	BOOLEAN	bPort5 = FALSE;
+
+	if (uPort >= SW_MAX_LAN_PORTS) {
+		if (SW_MAX_LAN_PORTS == uPort) {
+			/* port 5 */
+			bPort5 = TRUE;
+		}
+		else {
+			/* out of range */
+			DRV_INFO("%s: port %d to configure out of range", __FUNCTION__, uPort);
+			return;
+		}
+	}
+#ifndef	CONFIG_ARCH_KS8695P
+	uOff = KS8695_SWITCH_PORT1 + uPort * 4;
+#else
+	if (bPort5)
+		uOff = KS8695_SEP5C1;
+	else
+		uOff = KS8695_SEP1C1 + uPort * 0x0c;
+#endif
+
+	uReg = 0;
+	uReg |= (UINT)DPI[uPort].usTag << 16;
+
+	if (!bPort5) {
+		/* connection media type */
+		/*uReg &= ~(SW_PORT_DISABLE_AUTONEG | SW_PORT_100BASE | SW_PORT_FULLDUPLEX);*/
+		if (SW_PHY_AUTO != DI.usCType[uPort]) {
+			uReg |= SW_PORT_DISABLE_AUTONEG;
+			if (SW_PHY_100BASE_TX == DI.usCType[uPort] || 
+				SW_PHY_100BASE_TX_FD == DI.usCType[uPort]) {
+				uReg |= SW_PORT_100BASE;
+			}
+			if (SW_PHY_10BASE_T_FD == DI.usCType[uPort] || 
+				SW_PHY_100BASE_TX_FD == DI.usCType[uPort]) {
+				uReg |= SW_PORT_FULLDUPLEX;
+			}
+		}
+	}
+	else {
+		/* Rx direct mode */
+		if (DI.bRxDirectMode) {
+			uReg |= SW_PORT_RX_DIRECT_MODE;
+		}
+		/* Tx Pre-tag mode */
+		if (DI.bTxRreTagMode) {
+			uReg |= SW_PORT_TX_PRETAG_MODE;
+		}
+	}
+
+	/* cross talk bit mask */
+	uReg |= ((UINT)(DPI[uPort].byCrossTalkMask & 0x1f)) << 8;
+
+	/* spanning tree */
+	if (SW_SPANNINGTREE_ALL == DPI[uPort].bySpanningTree) {
+		uReg |= SW_PORT_TX_SPANNINGTREE | SW_PORT_RX_SPANNINGTREE;
+	}
+	else {
+		if (SW_SPANNINGTREE_TX == DPI[uPort].bySpanningTree) {
+			uReg |= SW_PORT_TX_SPANNINGTREE;
+		}
+		if (SW_SPANNINGTREE_RX == DPI[uPort].bySpanningTree) {
+			uReg |= SW_PORT_RX_SPANNINGTREE;
+		}
+	}
+	if (DPI[uPort].byDisableSpanningTreeLearn) {
+		uReg |= SW_PORT_NO_SPANNINGTREE;
+	}
+	/* ingress broadcast storm protection */
+	if (DPI[uPort].byStormProtection) {
+		uReg |= SW_PORT_STORM_PROCTION;
+	}
+	/* ingress priority */
+	if (DPI[uPort].byIngressPriority) {
+		uReg |= SW_PORT_HI_PRIORITY;
+	}
+	if (DPI[uPort].byIngressPriorityTOS) {
+		uReg |= SW_PORT_TOS_ENABLE;
+	}
+	if (DPI[uPort].byIngressPriority802_1P) {
+		uReg |= SW_PORT_8021Q_ENABLE;
+	}
+	/* egress priority */
+	if (DPI[uPort].byEgressPriority) {
+		uReg |= SW_PORT_PRIOTIRY_ENABLE;
+	}
+	KS8695_WRITE_REG(uOff, uReg);
+	/* need 20 cpu clock delay for switch related registers */
+	DelayInMicroseconds(10);
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s: uOff=0x%08x, reg=0x%08x", __FUNCTION__, uOff, uReg);
+#endif
+}
+
+/*
+ * swEnableSwitch
+ *	This function is used to enable/disable switch
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT struct
+ *  enable		enable/disable switch
+ *
+ * Return(s)
+ *	NONE.
+ */
+void swEnableSwitch(PADAPTER_STRUCT Adapter, UINT enable)
+{
+	UINT	uReg;
+
+	uReg = KS8695_READ_REG(KS8695_SWITCH_CTRL0);
+	if (enable) {
+		uReg |= SW_CTRL0_SWITCH_ENABLE;
+		/* for debug purpose */
+		/*uReg |= 0x00080000;*/
+	} else {
+		uReg &= ~SW_CTRL0_SWITCH_ENABLE;
+		/* for debug purpose */
+		/*uReg &= ~0x00080000;*/
+	}
+
+	KS8695_WRITE_REG(KS8695_SWITCH_CTRL0, uReg);
+	/* need 20 cpu clock delay for switch related registers */
+	DelayInMicroseconds(10);
+}
+
+/*
+ * swReadSNMPReg
+ *	This function is used to read SNMP registers
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *	uIndex		index of SNMP register to read
+ *
+ * Return(s)
+ *	value read
+ */
+UINT swReadSNMPReg(PADAPTER_STRUCT Adapter, UINT uIndex)
+{
+#ifndef	CONFIG_ARCH_KS8695P
+	UINT	uValue, uTimeout = 0;
+
+	if (uIndex >= 512)
+		uIndex = 511;
+
+	KS8695_WRITE_REG(KS8695_MANAGE_COUNTER, uIndex);
+	DelayInMicroseconds(10);
+	do {
+		uValue = KS8695_READ_REG(KS8695_MANAGE_DATA);
+		if (uValue & SW_SNMP_DATA_VALID) {
+			if (uValue & SW_SNMP_DATA_OVERFLOW) {
+				KS8695_WRITE_REG(KS8695_MANAGE_DATA, SW_SNMP_DATA_OVERFLOW);
+			}
+			/* clear status bits */
+			uValue &= 0x3fffffff;
+			return uValue;
+		}
+		DelayInMilliseconds(1);
+	} 
+	while (uTimeout++ < 2000);
+
+	if (uValue & SW_SNMP_DATA_OVERFLOW) {
+		KS8695_WRITE_REG(KS8695_MANAGE_DATA, SW_SNMP_DATA_OVERFLOW);
+	}
+#else
+	u32	reg, value, timeout = 0;
+
+	reg = KS8695_SEIAC_READ | KS8695_SEIAC_TAB_MIB | (KS8695_SEIAC_INDEX_MASK & uIndex);
+	do {
+		KS8695_WRITE_REG(KS8695_SEIAC, reg);
+		DelayInMicroseconds(10);
+
+		value = KS8695_READ_REG(KS8695_SEIADL);
+		if (value & SW_SNMP_DATA_VALID) {
+			if (value & SW_SNMP_DATA_OVERFLOW) {
+				reg = KS8695_SEIAC_WRITE | KS8695_SEIAC_TAB_MIB | (KS8695_SEIAC_INDEX_MASK & uIndex);
+				KS8695_WRITE_REG(KS8695_SEIAC, reg);
+			}
+			/* clear status bits */
+			value &= 0x3fffffff;
+			return value;
+		}
+	}
+	while (timeout++ < 2000);
+
+	printk("%s: timeout\n", __FUNCTION__);
+#endif
+	return 0;
+}
+
+/*
+ * swConfigure
+ *	This function is used to config switch engine. It is assume that
+ *	the BIST is performed already (by boot loader).
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *
+ * Return(s)
+ *	NONE
+ */
+void swConfigure(PADAPTER_STRUCT Adapter)
+{
+	UINT uReg, i;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	if (DMA_LAN == DI.usDMAId) {
+		/* read switch control 0 register */
+		uReg = KS8695_READ_REG(KS8695_SWITCH_CTRL0);
+		/* flow control for LAN ports */
+		if (DI.bPort5FlowCtrl)
+		{
+			/* flow control for port 5 */
+			uReg |= SW_CTRL0_ENABLE_PORT5;
+		}
+		else {
+			uReg &= ~SW_CTRL0_ENABLE_PORT5;
+		}
+#ifndef	CONFIG_ARCH_KS8695P
+		if (DI.bPortsFlowCtrl)
+		{
+			/* four flow control for each LAN port */
+			uReg |= SW_CTRL0_ENABLE_PORTS;
+		}
+		else {
+			uReg &= ~SW_CTRL0_ENABLE_PORTS;
+		}
+#else
+#if	0
+		/* RLQ, need to verify */
+		for (i = 0; i < SW_MAX_LAN_PORTS; i++) {
+			forceFlowControl(Adapter, i, DI.bPortsFlowCtrl);
+			//if (!DI.bPortsFlowCtrl)
+			//	backPressureEnable(Adapter, i, DI.bPortsFlowCtrl);
+			backPressureEnable(Adapter, i, TRUE);
+		}
+#endif
+#endif
+
+		/*RLQ, 11/20/2002, requested by Hock, backpressure will fix packet 
+		 * drop problem in half duplex mode
+		 */
+		uReg |= 0x00000020;		/* bit 5 */
+
+		/* set flow control fairness mode based on LAN flow control settings, should use */
+
+		/* read switch control 0 register */
+		KS8695_WRITE_REG(KS8695_SWITCH_CTRL0, uReg);
+		/* need 20 cpu clock delay for switch related registers */
+		DelayInMicroseconds(10);
+		
+		/* configure LAN port 1-4 and Port 5 */
+		for (i = 0; i <= SW_MAX_LAN_PORTS; i++) 
+			swConfigurePort(Adapter, i);
+	}
+	else {
+		DRV_INFO("%s: type (%x) not supported", __FUNCTION__, DI.usDMAId);
+	}
+}
+
+/*
+ * swSetLED
+ *	This function is used to set given LED
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT struct
+ *  bLED1		TRUE for LED1 and FALSE for LED0
+ *	nSel		emum type LED_SELECTOR
+ *
+ * Return(s)
+ *	NONE.
+ */
+void swSetLED(PADAPTER_STRUCT Adapter, BOOLEAN bLED1, LED_SELECTOR nSel)
+{
+	UINT32 uReg;
+
+	switch (DI.usDMAId) {
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	case DMA_HPNA:
+		/* there is no LED for HPNA */
+		break;
+#endif
+
+	case DMA_WAN:
+		uReg = KS8695_READ_REG(KS8695_WAN_CONTROL);
+		if (bLED1) {
+			uReg &= 0xffffff8f;		/* 6:4 */
+			uReg |= (UINT)(nSel & 0x07) << 4;
+		}
+		else {
+			uReg &= 0xfffffff8;		/* 2:0 */
+			uReg |= (UINT)(nSel & 0x07);
+		}
+		KS8695_WRITE_REG(KS8695_WAN_CONTROL, uReg);
+		/* need 20 cpu clock delay for switch related registers */
+		DelayInMicroseconds(10);
+		return;
+
+	default:
+	case DMA_LAN:
+		uReg = KS8695_READ_REG(KS8695_SWITCH_CTRL0);
+		if (bLED1) {
+			uReg &= 0xf1ffffff;		/* 27:25 */
+			uReg |= (UINT)(nSel & 0x07) << 25;
+		}
+		else {
+			uReg &= 0xfe3fffff;		/* 24:22 */
+			uReg |= (UINT)(nSel & 0x07) << 22;
+		}
+		KS8695_WRITE_REG(KS8695_SWITCH_CTRL0, uReg);
+		/* need 20 cpu clock delay for switch related registers */
+		DelayInMicroseconds(10);
+		break;
+	}
+}
+
+/*
+ * swAutoNegoStart
+ *	This function is used to start auto negotiation process
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT struct
+ *  uPort		port to start
+ *
+ * Return(s)
+ *	NONE.
+ */
+void swAutoNegoStart(PADAPTER_STRUCT Adapter, UINT uPort)
+{
+	UINT	uReg, uOff, uShift = 0;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s: port=%d, bAutoNegoInProgress=%d", __FUNCTION__, uPort, DI.bAutoNegoInProgress[uPort]);
+#endif
+
+	switch (DI.usDMAId) {
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	case DMA_HPNA:
+		/* there is no auto nego for HPNA */
+		return;
+#endif
+
+	case DMA_WAN:
+		uOff = KS8695_WAN_CONTROL;
+		uShift = 16;
+		break;
+
+	default:
+	case DMA_LAN:
+		switch (uPort) {
+		case SW_PORT_4:
+			uOff = KS8695_SWITCH_AUTO1;
+			uShift = 16;
+			break;
+
+		case SW_PORT_3:
+			uOff = KS8695_SWITCH_AUTO1;
+			break;
+
+		case SW_PORT_2:
+			uOff = KS8695_SWITCH_AUTO0;
+			uShift = 16;
+			break;
+
+		case SW_PORT_1:
+		default:
+			uOff = KS8695_SWITCH_AUTO0;
+			break;
+		}
+		break;
+	}
+
+	/* if not auto nego */
+	if (SW_PHY_AUTO != DI.usCType[uPort]) {
+		return;
+	}
+	DI.bAutoNegoInProgress[uPort] = TRUE;
+	uReg = KS8695_READ_REG(uOff);
+	uReg |= ((UINT)SW_AUTONEGO_RESTART << uShift);
+	KS8695_WRITE_REG(uOff, uReg);
+	/* need 20 cpu clock delay for switch related registers */
+	DelayInMicroseconds(10);
+}
+
+/*
+ * swAutoNegoAdvertisement
+ *	This function is used to set PHY Advertisement.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *  uPort		port to advertise
+ *
+ * Return(s)
+ *	NONE
+ */
+void swAutoNegoAdvertisement(PADAPTER_STRUCT Adapter, UINT uPort)
+{
+	UINT	uReg, uOff, uShift = 0;
+
+#ifdef	DEBUG_THIS
+    DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	switch (DI.usDMAId) {
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	case DMA_HPNA:
+		/* there is no auto nego feature for HPNA DMA, but I'll assume that
+		   if SW_PHY_AUTO is set, use 100/FD as default
+		 */ 
+		uReg = KS8695_READ_REG(KS8695_MISC_CONTROL) & 0xfffffffc;
+		if (SW_PHY_AUTO == DI.usCType[uPort]) {
+			uReg |= 0x00000003;
+		}
+		else {
+			if (SW_PHY_100BASE_TX == DI.usCType[uPort] || 
+				SW_PHY_100BASE_TX_FD == DI.usCType[uPort]) {
+				uReg |= 0x00000002;
+			}
+			if (SW_PHY_10BASE_T_FD == DI.usCType[uPort] || 
+				SW_PHY_100BASE_TX_FD == DI.usCType[uPort]) {
+				uReg |= 0x00000001;
+			}
+		}
+		KS8695_WRITE_REG(REG_MISC_CONTROL, uReg);
+		/* need 20 cpu clock delay for switch related registers */
+		DelayInMicroseconds(10);
+		return;
+#endif
+
+	case DMA_WAN:
+		uOff = KS8695_WAN_CONTROL;
+		uShift = 16;
+		break;
+
+	default:
+	case DMA_LAN:
+		switch (uPort) {
+		case SW_PORT_4:
+			uOff = KS8695_SWITCH_AUTO1;
+			break;
+
+		case SW_PORT_3:
+			uOff = KS8695_SWITCH_AUTO1;
+			uShift = 16;
+			break;
+
+		case SW_PORT_2:
+			uOff = KS8695_SWITCH_AUTO0;
+			break;
+
+		case SW_PORT_1:
+		default:
+			uOff = KS8695_SWITCH_AUTO0;
+			uShift = 16;
+			break;
+		}
+		break;
+	}
+	uReg = KS8695_READ_REG(uOff);
+	/* clear corresponding bits first */
+	uReg &= ~(SW_AUTONEGO_ADV_MASK << uShift);
+	if (SW_PHY_AUTO == DI.usCType[uPort])
+	{
+		uReg |= (SW_AUTONEGO_ADV_100FD | SW_AUTONEGO_ADV_100HD |
+			SW_AUTONEGO_ADV_10FD | SW_AUTONEGO_ADV_10HD) << uShift;
+	}
+	else
+	{
+		/* Manually set */
+		switch (DI.usCType[uPort])
+		{
+		case SW_PHY_100BASE_TX_FD:
+			uReg |= SW_AUTONEGO_ADV_100FD << uShift;
+			break;
+
+		case SW_PHY_100BASE_TX:
+			uReg |= SW_AUTONEGO_ADV_100HD << uShift;
+			break;
+
+		case SW_PHY_10BASE_T_FD:
+			uReg |= SW_AUTONEGO_ADV_10FD << uShift;
+			break;
+
+		case SW_PHY_10BASE_T:
+			uReg |= SW_AUTONEGO_ADV_10HD << uShift;
+			break;
+
+		default:
+			/* Unsupported media type found! */
+			DRV_WARN("%s> Unsupported media type found!", __FUNCTION__);
+			return;
+		}
+	}
+
+	if (DI.bRxFlowCtrl)
+		uReg |= SW_AUTONEGO_ADV_PUASE << uShift;
+
+	uReg &= ~((UINT)SW_AUTONEGO_RESTART << uShift);
+	KS8695_WRITE_REG(uOff, uReg);
+	/* need 20 cpu clock delay for switch related registers */
+	DelayInMicroseconds(10);
+}
+
+/*
+ * swGetWANLinkStatus
+ *	This function is used to get WAN link status.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *  uPort		port to query
+ *
+ * Return(s)
+ *	TRUE	if link is up
+ *	FALSE	if link is down
+ */
+BOOLEAN swGetWANLinkStatus(PADAPTER_STRUCT Adapter)
+{
+	UINT	uReg;
+
+	uReg = KS8695_READ_REG(KS8695_WAN_CONTROL);
+	/* if not linked yet */
+	if (!(uReg & ((UINT)SW_AUTONEGO_STAT_LINK << 16))) {
+#ifdef	DEBUG_THIS
+		DRV_INFO("WAN link is down");
+#endif
+		return FALSE;
+	}
+#ifdef	DEBUG_THIS
+	DRV_INFO("WAN link is up");
+#endif
+
+	return TRUE;
+}
+
+/*
+ * swGetPhyStatus
+ *	This function is used to get the status of auto negotiation.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *  uPort		port to query
+ *
+ * Return(s)
+ *	TRUE	if connected
+ *	FALSE	otherwise
+ */
+int swGetPhyStatus(PADAPTER_STRUCT Adapter, UINT uPort)
+{
+	UINT	uReg, uOff, uShift = 0;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	switch (DI.usDMAId) {
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	case DMA_HPNA:
+		/* temp */
+		uReg = KS8695_READ_REG(REG_MISC_CONTROL);
+		DI.usLinkSpeed[uPort] = (uReg & 0x00000002) ? SPEED_100 : SPEED_10;
+		DI.bHalfDuplex[uPort] = (uReg & 0x00000001) ? FULL_DUPLEX : HALF_DUPLEX;
+		/* note that there is no register bit corresponding to HPNA's link status
+		   therefore don't report it */
+		DI.bLinkActive[uPort] = TRUE;
+		return TRUE;
+#endif
+
+	case DMA_WAN:
+		uOff = KS8695_WAN_CONTROL;
+		uShift = 16;
+		break;
+
+	default:
+	case DMA_LAN:
+		switch (uPort) {
+		case SW_PORT_4:
+			uOff = KS8695_SWITCH_AUTO1;
+			break;
+
+		case SW_PORT_3:
+			uOff = KS8695_SWITCH_AUTO1;
+			uShift = 16;
+			break;
+
+		case SW_PORT_2:
+			uOff = KS8695_SWITCH_AUTO0;
+			break;
+
+		case SW_PORT_1:
+		default:
+			uOff = KS8695_SWITCH_AUTO0;
+			uShift = 16;
+			break;
+		}
+	}
+
+	uReg = KS8695_READ_REG(uOff);
+	/* if not linked yet */
+	if (!(uReg & ((UINT)SW_AUTONEGO_STAT_LINK << uShift))) {
+		DI.bLinkActive[uPort] = FALSE;
+		DI.usLinkSpeed[uPort] = SPEED_UNKNOWN;
+		DI.bHalfDuplex[uPort] = 0;
+		gpioSet(Adapter, uPort, FALSE);
+		return FALSE;
+	}
+	DI.bLinkActive[uPort] = TRUE;
+	if (SW_PHY_AUTO == DI.usCType[uPort]) {
+		/* if auto nego complete */
+		//RLQ, 12/18/2003, bug
+		if (uReg & ((UINT)SW_AUTONEGO_COMPLETE << uShift)) {
+			/* clear auto nego restart bit */
+			uReg &= ~((UINT)SW_AUTONEGO_RESTART << uShift);
+			KS8695_WRITE_REG(uOff, uReg);
+			DelayInMicroseconds(10);
+
+			DI.usLinkSpeed[uPort] = (uReg & ((UINT)SW_AUTONEGO_STAT_SPEED << uShift)) ? SPEED_100 : SPEED_10;
+			DI.bHalfDuplex[uPort] = (uReg & ((UINT)SW_AUTONEGO_STAT_DUPLEX << uShift)) ? FULL_DUPLEX : HALF_DUPLEX;
+			DI.bAutoNegoInProgress[uPort] = FALSE;
+			
+			gpioSet(Adapter, uPort, SPEED_100 == DI.usLinkSpeed[uPort]);
+			/*RLQ, need to verify real duplex mode instead report it correct here */
+			/* duplex bit may not right if partner doesn't support all mode, do further detection */
+			if ((uReg & (SW_AUTONEGO_PART_100FD | SW_AUTONEGO_PART_100HD | SW_AUTONEGO_PART_10FD | SW_AUTONEGO_PART_10HD) << uShift)
+				!= (SW_AUTONEGO_PART_100FD | SW_AUTONEGO_PART_100HD | SW_AUTONEGO_PART_10FD | SW_AUTONEGO_PART_10HD)) {
+				if (SPEED_100 == DI.usLinkSpeed[uPort]) {
+					if ((uReg & (SW_AUTONEGO_PART_100FD << uShift))) {
+						DI.bHalfDuplexDetected[uPort] = FULL_DUPLEX;
+#ifdef	CONFIG_ARCH_KS8695P
+						forceFlowControl(Adapter, uPort, TRUE);
+						backPressureEnable(Adapter, uPort, FALSE);
+#endif
+					} else {
+						DI.bHalfDuplexDetected[uPort] = HALF_DUPLEX;
+#ifdef	CONFIG_ARCH_KS8695P
+						forceFlowControl(Adapter, uPort, FALSE);
+						backPressureEnable(Adapter, uPort, TRUE);
+#endif
+					}
+				}
+				else {
+					if ((uReg & (SW_AUTONEGO_PART_10FD << uShift))) {
+						DI.bHalfDuplexDetected[uPort] = FULL_DUPLEX;
+#ifdef	CONFIG_ARCH_KS8695P
+						forceFlowControl(Adapter, uPort, TRUE);
+						backPressureEnable(Adapter, uPort, FALSE);
+#endif
+					}
+					else {
+						DI.bHalfDuplexDetected[uPort] = HALF_DUPLEX;
+#ifdef	CONFIG_ARCH_KS8695P
+						forceFlowControl(Adapter, uPort, FALSE);
+						backPressureEnable(Adapter, uPort, TRUE);
+#endif
+					}
+				}
+			}
+
+			/* software workaround for flow control, need to know partner's flow control */
+			if (DMA_WAN == DI.usDMAId) {	/* currently do it to WAN only, there is no problem to LAN, will do HPNA later */
+				uint8_t	bFlowCtrl;
+
+				/* we need to check partner's control flow setting for the matching, if not, changes ours */
+				bFlowCtrl = ((SW_AUTONEGO_PART_PAUSE << uShift) & uReg) ? TRUE : FALSE;
+				if (bFlowCtrl != DI.bRxFlowCtrl) {	/* Tx same as Rx, so test Rx should be enough */
+					/* need to change ours accordingly, which will overwrite current one */
+					macConfigureFlow(Adapter, bFlowCtrl);
+				}
+			}
+#ifdef	DEBUG_THIS
+			DRV_INFO("%s> Auto Nego completed", __FUNCTION__);
+#endif
+		}
+		else {
+#ifdef	DEBUG_THIS
+			/* auto nego in progress */
+			DRV_INFO("%s> Auto Nego in progress...", __FUNCTION__);
+#endif
+			/* wait for next timer */
+			DI.bLinkActive[uPort] = FALSE;
+			DI.usLinkSpeed[uPort] = SPEED_UNKNOWN;
+			DI.bHalfDuplex[uPort] = 0;
+		}
+	}
+	else {
+#ifdef	DEBUG_THIS
+		DRV_INFO("%s: media type=%d, port=%d", __FUNCTION__, DI.usCType[uPort], uPort);
+#endif
+
+		/* manually connection */
+		if (SW_PHY_10BASE_T_FD == DI.usCType[uPort] || SW_PHY_100BASE_TX_FD == DI.usCType[uPort]) {
+			DI.bHalfDuplex[uPort] = FULL_DUPLEX;
+#ifdef	CONFIG_ARCH_KS8695P
+			forceFlowControl(Adapter, uPort, TRUE);
+			backPressureEnable(Adapter, uPort, FALSE);
+#endif
+		}
+		else {
+			DI.bHalfDuplex[uPort] = HALF_DUPLEX;
+#ifdef	CONFIG_ARCH_KS8695P
+			forceFlowControl(Adapter, uPort, FALSE);
+			backPressureEnable(Adapter, uPort, TRUE);
+#endif
+		}
+		if (SW_PHY_100BASE_TX_FD == DI.usCType[uPort] || SW_PHY_100BASE_TX == DI.usCType[uPort]) {
+			DI.usLinkSpeed[uPort] = SPEED_100;
+			gpioSet(Adapter, uPort, TRUE);
+		}
+		else {
+			DI.usLinkSpeed[uPort] = SPEED_10;
+			gpioSet(Adapter, uPort, FALSE);
+		}
+
+		/* software workaround for flow control, need to know partner's flow control */
+		if (DMA_WAN == DI.usDMAId) {	/* currently do it to WAN only, there is no problem to LAN, will do HPNA later */
+			macConfigureFlow(Adapter, FULL_DUPLEX == DI.bHalfDuplex[uPort] ? TRUE : FALSE);
+		}
+	}
+	return TRUE;
+}
+
+/*
+ * swDetectPhyConnection
+ *	This function is used to start auto negotiation
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT struct
+ *  uPort		port to start
+ *
+ * Return(s)
+ *	NONE.
+ */
+void swDetectPhyConnection(PADAPTER_STRUCT Adapter, UINT uPort)
+{
+	/*if (SW_PHY_AUTO == DI.usCType[uPort] && !DI.bAutoNegoInProgress[uPort] && DI.bLinkChanged[uPort]) {*/
+	if (LINK_SELECTION_FORCED != DI.byDisableAutoNego[uPort] && !DI.bAutoNegoInProgress[uPort] && DI.bLinkChanged[uPort]) {
+		swAutoNegoStart(Adapter, uPort);
+		DI.bLinkChanged[uPort] = FALSE;
+		DI.bLinkActive[uPort] = FALSE;
+	}
+	swGetPhyStatus(Adapter, uPort);
+}
+
+/*
+ * swPhyReset
+ *	This function is used to reset phy chipset (powerdown or soft reset).
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *  uPort		port to start
+ *
+ * Return(s)
+ *	NONE
+ */
+void swPhyReset(PADAPTER_STRUCT Adapter, UINT uPort)
+{
+	UINT	uReg, uShift = 0;
+	UINT	uPowerReg;
+	/*RLQ, workaround */
+	UINT	uReg1;
+
+#ifdef	DEBUG_THIS
+    DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	/* IEEE spec. of auto nego bit */
+	uReg1 = BIT(7);
+	switch (DI.usDMAId) {
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	case DMA_HPNA:
+		return;
+#endif
+
+	case DMA_WAN:
+		uPowerReg = KS8695_WAN_POWERMAGR;
+		break;
+
+	default:
+	case DMA_LAN:
+		switch (uPort) {
+		case SW_PORT_4:
+			uPowerReg = KS8695_LAN34_POWERMAGR;
+			break;
+
+		case SW_PORT_3:
+			uPowerReg = KS8695_LAN34_POWERMAGR;
+			uShift = 16;
+			break;
+
+		case SW_PORT_2:
+			uPowerReg = KS8695_LAN12_POWERMAGR;
+			break;
+
+		case SW_PORT_1:
+		default:
+			uPowerReg = KS8695_LAN12_POWERMAGR;
+			uShift = 16;
+			break;
+		}
+	}
+
+	if (DI.bPowerDownReset) {
+		int	nCount = 0;
+		
+		uReg = KS8695_READ_REG(uPowerReg);
+		KS8695_WRITE_REG(uPowerReg, uReg | ((UINT)POWER_POWERDOWN << uShift));
+		/* need 20 cpu clock delay for switch related registers */
+		/*DelayInMicroseconds(10);*/
+		do {
+			DelayInMilliseconds(50);
+		} while (nCount++ < 4);
+		uReg &= ~((UINT)POWER_POWERDOWN << uShift);
+		/* turn off IEEE auto nego */
+		uReg &= ~(uReg1 << uShift);
+		KS8695_WRITE_REG(uPowerReg, uReg);
+		/* need 20 cpu clock delay for switch related registers */
+		DelayInMicroseconds(10);
+	}
+	else {
+		uReg = KS8695_READ_REG(uPowerReg);
+		/* turn off IEEE auto nego */
+		uReg &= ~(uReg1 << uShift);
+		KS8695_WRITE_REG(uPowerReg, uReg);
+		/* need 20 cpu clock delay for switch related registers */
+		DelayInMicroseconds(10);
+	}
+}
+
+/*
+ * swConfigureMediaType
+ *	This function is used to set linke media type (forced)
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *  uPort		port to start
+ *	uSpeed		media speed to set
+ *	uDuplex		media duplex to set
+ *
+ * Return(s)
+ *	TRUE	if succeeded
+ *	FALSE	otherwise
+ */
+void swConfigureMediaType(PADAPTER_STRUCT Adapter, UINT uPort, UINT uSpeed, UINT uDuplex)
+{
+	UINT32 uReg, uOffset;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	switch (DI.usDMAId) {
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	case DMA_HPNA:
+		/* there is no way to force HPNA */
+		return;
+#endif
+
+	case DMA_WAN:
+		uOffset = KS8695_WAN_CONTROL;
+		uPort = 0;
+		break;
+
+	default:
+	case DMA_LAN:
+		if (uPort >= SW_MAX_LAN_PORTS) {
+			DRV_WARN("%s: port (%d) gave is out of range", __FUNCTION__, uPort);
+			return;
+		}
+#ifndef	CONFIG_ARCH_KS8695P
+		uOffset = KS8695_SWITCH_PORT1 + uPort * 4;
+#else
+		if (SW_MAX_LAN_PORTS == uPort)
+			uOffset = KS8695_SEP5C1;
+		else
+			uOffset = KS8695_SWITCH_PORT1 + uPort * 0x0c;
+#endif
+		break;
+	}
+
+	uReg = KS8695_READ_REG(uOffset);
+	/* clear corresponding bits first */
+	uReg &= 0xFFFF1FFF;
+	if (LINK_SELECTION_FORCED == DI.byDisableAutoNego[uPort]) {
+		uReg |= SW_PORT_DISABLE_AUTONEG;
+		/* force to half duplex */
+		DI.bRxFlowCtrl = FALSE;
+		DI.bTxFlowCtrl = FALSE;
+		if (uSpeed) {
+			uReg |= SW_PORT_100BASE;
+			if (uDuplex) {
+				uReg |= SW_PORT_FULLDUPLEX;
+				DI.usCType[uPort] = SW_PHY_100BASE_TX_FD;
+			}
+			else {
+				DI.usCType[uPort] = SW_PHY_100BASE_TX;
+			}
+		}
+		else {
+			if (uDuplex) {
+				uReg |= SW_PORT_FULLDUPLEX;
+				DI.usCType[uPort] = SW_PHY_10BASE_T_FD;
+			}
+			else {
+				DI.usCType[uPort] = SW_PHY_10BASE_T;
+			}
+		}
+	}
+	else {
+		if (DMA_WAN == DI.usDMAId) {
+			DI.bRxFlowCtrl = FLOWCONTROL_DEFAULT;
+			DI.bTxFlowCtrl = FLOWCONTROL_DEFAULT;
+		}
+		if (LINK_SELECTION_FULL_AUTO == DI.byDisableAutoNego[uPort]) {
+			DI.usCType[uPort] = SW_PHY_AUTO;
+		} else {
+			switch (uSpeed) {
+				case 0:
+					if (uDuplex) 
+						DI.usCType[uPort] = SW_PHY_10BASE_T_FD;		/* 10Base-TX Full Duplex */
+					else {
+						/* don't advertise flow control in half duplex case */
+						if (DMA_WAN == DI.usDMAId) {
+							DI.bRxFlowCtrl = FALSE;
+							DI.bTxFlowCtrl = FALSE;
+						}
+						DI.usCType[uPort] = SW_PHY_10BASE_T;		/* 10Base-T Half Duplex */
+					}
+					break;
+
+				case 1:
+				default:
+					if (uDuplex)
+						DI.usCType[uPort] = SW_PHY_100BASE_TX_FD;	/* 100Base-TX Full Duplex */
+					else {
+						/* don't advertise flow control in half duplex case */
+						if (DMA_WAN == DI.usDMAId) {
+							DI.bRxFlowCtrl = FALSE;
+							DI.bTxFlowCtrl = FALSE;
+						}
+						DI.usCType[uPort] = SW_PHY_100BASE_TX;		/* 100Base-TX Half Duplex */
+					}
+					break;
+			}
+		}
+	}
+
+	KS8695_WRITE_REG(uOffset, uReg);
+	/* need 20 cpu clock delay for switch related registers */
+	DelayInMicroseconds(10);
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s: media type=%d, offset=0x%08x, port=%d", __FUNCTION__, DI.usCType[uPort], uOffset, uPort);
+#endif
+
+	DI.bLinkChanged[uPort] = TRUE;
+	DI.bLinkActive[uPort] = FALSE;		/* watchdog routine will check link status if reset this variable!!! */
+	swPhyReset(Adapter, uPort);
+	swAutoNegoAdvertisement(Adapter, uPort);
+	swDetectPhyConnection(Adapter, uPort);
+}
+
+/*
+ * swPhyLoopback
+ *	This function is used to set loopback in PHY layer.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *  uPort		port to start
+ *	bLoopback	indicates loopback enable or not
+ *
+ * Return(s)
+ *	TRUE	if succeeded
+ *	FALSE	otherwise
+ */
+BOOLEAN swPhyLoopback(PADAPTER_STRUCT Adapter, UINT uPort, BOOLEAN bLoopback)
+{
+	UINT	uReg, uOff, uShift = 0;
+
+	switch (DI.usDMAId) {
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	case DMA_HPNA:
+		return FALSE;
+#endif
+
+	case DMA_WAN:
+		uOff = KS8695_WAN_POWERMAGR;
+		uShift = 0;
+		break;
+
+	default:
+	case DMA_LAN:
+		switch (uPort) {
+		case SW_PORT_4:
+			uOff = KS8695_LAN34_POWERMAGR;
+			break;
+
+		case SW_PORT_3:
+			uOff = KS8695_LAN34_POWERMAGR;
+			uShift = 16;
+			break;
+
+		case SW_PORT_2:
+			uOff = KS8695_LAN12_POWERMAGR;
+			break;
+
+		case SW_PORT_1:
+		default:
+			uOff = KS8695_LAN12_POWERMAGR;
+			uShift = 16;
+			break;
+		}
+	}
+
+	uReg = KS8695_READ_REG(uOff);
+	if (bLoopback)
+		uReg |= ((UINT)POWER_LOOPBACK << uShift);
+	else
+		uReg &= ~((UINT)POWER_LOOPBACK << uShift);
+	KS8695_WRITE_REG(uOff, uReg);
+	/* need 20 cpu clock delay for switch related registers */
+	DelayInMicroseconds(10);
+
+	return TRUE;
+}
+
+/*
+ * swGetMacAddress
+ *	This function is use to get switch engine Mac address and store it in stSwitchMac.
+ *
+ * Argument(s)
+ *  Adapter		pionter to ADAPTER_STRUCT data structure.
+ *
+ * Return(s)
+ *	NONE
+ */
+void swGetMacAddress(PADAPTER_STRUCT Adapter)
+{
+	UINT32 uTmp;
+	int i;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	uTmp = KS8695_READ_REG(KS8695_SWITCH_MAC_LOW);
+	for (i = (MAC_ADDRESS_LEN - 1); i > 1; i--)
+	{
+		DI.stSwitchMac[i] = (UCHAR)(uTmp & 0x0ff);
+		uTmp >>= 8;
+	}
+	/* read high 2 bytes */
+	uTmp = KS8695_READ_REG(KS8695_SWITCH_MAC_HIGH);
+	DI.stSwitchMac[1] = (UCHAR)(uTmp & 0x0ff);
+	uTmp >>= 8;
+	DI.stSwitchMac[0] = (UCHAR)(uTmp & 0x0ff);
+}
+
+/*
+ * swSetMacAddress
+ *	This function is use to set switch engine Mac address.
+ *
+ * Argument(s)
+ *  Adapter		pionter to ADAPTER_STRUCT data structure.
+ *	pMac		pointer to mac address buffer (should be 6)
+ *
+ * Return(s)
+ *	NONE
+ */
+void swSetMacAddress(PADAPTER_STRUCT Adapter, UCHAR *pMac)
+{
+	uint32_t uLowAddress, uHighAddress;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	memcpy(&DI.stSwitchMac, pMac, MAC_ADDRESS_LEN);
+	uLowAddress = (*(pMac + 5)		|
+				  (*(pMac + 4) << 8)	|
+				  (*(pMac + 3) << 16)|
+				  *(pMac + 3) << 24);
+
+	uHighAddress = (*(pMac + 1)		|
+				   *pMac << 8);
+
+	KS8695_WRITE_REG(KS8695_SWITCH_MAC_LOW, uLowAddress);
+	/* need 20 cpu clock delay for switch related registers */
+	DelayInMicroseconds(10);
+	KS8695_WRITE_REG(KS8695_SWITCH_MAC_HIGH, uHighAddress);
+	/* need 20 cpu clock delay for switch related registers */
+	DelayInMicroseconds(10);
+}
+
+/*
+ * swResetSNMPInfo
+ *	This function is use to get SNMP counters information
+ *
+ * Argument(s)
+ *  Adapter		pionter to ADAPTER_STRUCT data structure.
+ *
+ * Return(s)
+ *	NONE
+ */
+void swResetSNMPInfo(PADAPTER_STRUCT Adapter)
+{
+	memset(&Adapter->net_stats, 0, sizeof(Adapter->net_stats));
+}
+
+/*
+ * swCreateLookUpTable
+ *	This function is use to create loopup table.
+ *
+ * Argument(s)
+ *  Adapter		pionter to ADAPTER_STRUCT data structure.
+ *
+ * Return(s)
+ *	NONE
+ */
+void swCreateLookUpTable(PADAPTER_STRUCT Adapter)
+{
+	unsigned int mac = 0, index = 0, tmp = 0, portmap = 0;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	mac = 0x01020304;
+	portmap = 0x10000;
+
+#ifndef	CONFIG_ARCH_KS8695P
+	for (index=0; index<5; index++)
+	{
+		KS8695_WRITE_REG(KS8695_SWITCH_LUE_HIGH, 0x200000 + (portmap << index));
+		DelayInMicroseconds(10);
+
+		KS8695_WRITE_REG(KS8695_SWITCH_LUE_LOW, mac++);
+		DelayInMicroseconds(10);
+
+		KS8695_WRITE_REG(KS8695_SWITCH_LUE_CTRL, index);
+		DelayInMicroseconds(10);
+		
+		do 
+		{
+			tmp = KS8695_READ_REG(KS8695_SWITCH_LUE_CTRL) & 0x1000; 
+		} while (tmp);
+	}
+#else
+	index = index;	/* no complain pls */
+	/* the user can program other MAC addresses for static table */
+	tmp = 0x0002;		/* e.g. this is the MAC high and low addr for the notebook I am using for test */
+	mac = 0xa55d1590;
+
+	KS8695_WRITE_REG(KS8695_SEIAC, 
+		KS8695_SEIAC_WRITE | KS8695_SEIAC_TAB_STATIC | (KS8695_SEIAC_INDEX_MASK & index));
+	DelayInMicroseconds(10);
+
+	KS8695_WRITE_REG(KS8695_SEIADH1, 0x200000 + (portmap << index) + tmp);
+	DelayInMicroseconds(10);
+
+	KS8695_WRITE_REG(KS8695_SEIADL, mac);
+	DelayInMicroseconds(10);
+#endif
+}
+
+/*
+ * swConfigTagRemoval
+ *	This function is use to configure tag removal for ingress to given port.
+ *
+ * Argument(s)
+ *  Adapter		pionter to ADAPTER_STRUCT data structure.
+ *	uPort		port for the tag to insert
+ *	bRemoval	enable/disable removal
+ *
+ * Return(s)
+ *	NONE
+ */
+void swConfigTagRemoval(PADAPTER_STRUCT Adapter, UINT uPort, UINT bRemoval)
+{
+	uint32_t	uReg;
+
+	uReg = KS8695_READ_REG(KS8695_SWITCH_ADVANCED);
+	if (bRemoval) {
+		uReg |= (1L << (22 + uPort));
+	}
+	else {
+		uReg &= ~(1L << (22 + uPort));
+	}
+	KS8695_WRITE_REG(KS8695_SWITCH_ADVANCED, uReg);
+	/* need 20 cpu clock delay for switch related registers */
+	DelayInMicroseconds(10);
+}
+
+/*
+ * swConfigTagInsertion
+ *	This function is use to configure tag insertion for engress to given port.
+ *
+ * Argument(s)
+ *  Adapter		pionter to ADAPTER_STRUCT data structure.
+ *	uPort		port for the tag to insert
+ *	bInsert		enable/disable insertion
+ *
+ * Return(s)
+ *	NONE
+ */
+void swConfigTagInsertion(PADAPTER_STRUCT Adapter, UINT uPort, UINT bInsert)
+{
+	uint32_t	uReg;
+
+	uReg = KS8695_READ_REG(KS8695_SWITCH_ADVANCED);
+	if (bInsert) {
+		uReg |= (1L << (17 + uPort));
+	}
+	else {
+		uReg &= ~(1L << (17 + uPort));
+	}
+	KS8695_WRITE_REG(KS8695_SWITCH_ADVANCED, uReg);
+	/* need 20 cpu clock delay for switch related registers */
+	DelayInMicroseconds(10);
+}
+
+/*
+ * gpioConfigure
+ *	This function is use to configure GPIO pins required for extra LEDs
+ *	as speed indicators.
+ *
+ * Argument(s)
+ *  Adapter		pionter to ADAPTER_STRUCT data structure.
+ *
+ * Return(s)
+ *	NONE
+ */
+void gpioConfigure(PADAPTER_STRUCT Adapter)
+{
+#if !defined(CONFIG_MACH_CM4008) && !defined(CONFIG_MACH_CM41xx)
+	uint32_t	uReg;
+	uint32_t	shift = 0;
+
+#ifdef	KS8695P_MEDIABOX	/* note that flag is defined in platform.h for mediabox platform */
+	shift = 1;		/* shift one bit to right for mediabox, that is from 3-7 - 5-8 */
+#endif
+
+	uReg = KS8695_READ_REG(KS8695_GPIO_MODE);
+	switch (DI.usDMAId) {
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	case DMA_HPNA:
+		return;
+#endif
+
+	case DMA_LAN:
+		uReg |= (0xf0 << shift);	/* GPIO 4-7 for port 1-4 or 5-8 for 1-4 for mediabox, configure them as output */
+		break;
+
+	default:
+	case DMA_WAN:
+		uReg |= (0x08 << shift);	/* GPIO 3 for WAN port, or GPIO 4 in mediabox platform */
+		break;
+	}
+	KS8695_WRITE_REG(KS8695_GPIO_MODE, uReg);
+#endif
+}
+
+/*
+ * gpioSet
+ *	This function is use to set/reset given GPIO pin corresponding to the port.
+ *
+ * Argument(s)
+ *  Adapter		pionter to ADAPTER_STRUCT data structure.
+ *  uPort		port for the tag to insert
+ *  bSet		enable/disable LED
+ *
+ * Return(s)
+ *  NONE
+ */
+void gpioSet(PADAPTER_STRUCT Adapter, UINT uPort, UINT bSet)
+{
+#if !defined(CONFIG_MACH_CM4008) && !defined(CONFIG_MACH_CM41xx)
+	uint32_t	uReg;
+	uint32_t 	shift = 0;
+
+#ifdef	KS8695P_MEDIABOX	/* note that flag is defined in platform.h for mediabox platform */
+	shift = 1;		/* if mediabox, shift one bit to right, that is from bit 4-7 shift to bit 5-8 */
+#endif
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s: port %d, %s", __FUNCTION__, uPort, bSet ? "100" : "10");
+#endif
+
+	uReg = KS8695_READ_REG(KS8695_GPIO_DATA);
+	switch (DI.usDMAId) {
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	case DMA_HPNA:
+		return;
+#endif
+
+	case DMA_LAN:
+		if (bSet)
+			uReg &= ~(1 << (uPort + 4 + shift));	/* low for LED on */
+		else
+			uReg |= (1 << (uPort + 4 + shift));	/* high for LED off */
+		break;
+
+	default:
+	case DMA_WAN:
+		if (bSet)
+			uReg &= ~(0x08 << shift);	/* low for LED on */
+		else
+			uReg |= (0x08 << shift);	/* high for LED off */
+		break;
+	}
+	KS8695_WRITE_REG(KS8695_GPIO_DATA, uReg);
+#endif
+}
+
+#ifdef	CONFIG_ARCH_KS8695P
+/*
+ * configureVID
+ *	This function is use to configure VID for given port
+ *
+ * Argument(s)
+ *  Adapter	pionter to ADAPTER_STRUCT data structure.
+ *  uPort	uport to turn on/off Led
+ *  bFilter	enable/disable ingress VLAN filtering
+ *  bDiscard	discard Non PVID packets or not
+ *
+ * Return(s)
+ *	NONE
+ */
+void configureVID(PADAPTER_STRUCT Adapter, UINT uPort, UINT bFilter, UINT bDiscard)
+{
+	u32	uReg, off;
+
+	if (uPort > SW_MAX_LAN_PORTS) {
+		printk("%s: port is out of range\n", __FUNCTION__);
+		return;
+	}
+	if (SW_MAX_LAN_PORTS == uPort) 
+		off = KS8695_SEP5C2;
+	else
+		off = KS8695_SEP1C2 + uPort * 0x0c;
+
+	uReg = KS8695_READ_REG(off);
+	if (bFilter)
+		uReg &= ~KS8695_SEPC2_VLAN_FILTER;
+	else
+		uReg |= KS8695_SEPC2_VLAN_FILTER;
+	if (bDiscard)
+		uReg &= ~KS8695_SEPC2_DISCARD_NON_PVID;
+	else
+		uReg |= KS8695_SEPC2_DISCARD_NON_PVID;
+	KS8695_WRITE_REG(off, uReg);
+	DelayInMicroseconds(10);
+}
+
+/*
+ * backPressureEnable
+ *	This function is use to enable/disable back pressure for given port
+ *
+ * Argument(s)
+ *  Adapter	pionter to ADAPTER_STRUCT data structure.
+ *  uPort	uport to turn on/off Led
+ *  bOn		on/off the flow control
+ *
+ * Return(s)
+ *	NONE
+ */
+void backPressureEnable(PADAPTER_STRUCT Adapter, UINT uPort, UINT bOn)
+{
+	u32	uReg, off;
+
+	if (uPort > SW_MAX_LAN_PORTS) {
+		printk("%s: port is out of range\n", __FUNCTION__);
+		return;
+	}
+	if (SW_MAX_LAN_PORTS == uPort) 
+		off = KS8695_SEP5C2;
+	else
+		off = KS8695_SEP1C2 + uPort * 0x0c;
+
+	uReg = KS8695_READ_REG(off);
+	if (bOn)
+		uReg &= ~KS8695_SEPC2_BACK_PRESSURE_EN;
+	else
+		uReg |= KS8695_SEPC2_BACK_PRESSURE_EN;
+	KS8695_WRITE_REG(off, uReg);
+	DelayInMicroseconds(10);
+}
+
+/*
+ * forceFlowControl
+ *	This function is use to force flow control on the port, regardless of AN result
+ *
+ * Argument(s)
+ *  Adapter	pionter to ADAPTER_STRUCT data structure.
+ *  uPort	uport to turn on/off Led
+ *  bOn		on/off the flow control
+ *
+ * Return(s)
+ *	NONE
+ */
+void forceFlowControl(PADAPTER_STRUCT Adapter, UINT uPort, UINT bOn)
+{
+	u32	uReg, off;
+
+	if (uPort > SW_MAX_LAN_PORTS) {
+		printk("%s: port is out of range\n", __FUNCTION__);
+		return;
+	}
+	if (SW_MAX_LAN_PORTS == uPort) 
+		off = KS8695_SEP5C2;
+	else
+		off = KS8695_SEP1C2 + uPort * 0x0c;
+
+	uReg = KS8695_READ_REG(off);
+	if (bOn) {
+		uReg &= ~KS8695_SEPC2_FORCE_FLOW_CTRL;
+	} else {
+		uReg |= KS8695_SEPC2_FORCE_FLOW_CTRL;
+	}
+	KS8695_WRITE_REG(off, uReg);
+	DelayInMicroseconds(10);
+}
+
+/*
+ * setTxRate
+ *	This function is use to set transmit priority rate control for KS8695P
+ *
+ * Argument(s)
+ *  Adapter		pionter to ADAPTER_STRUCT data structure.
+ *  uPort		uport to set
+ *  lrate		low rate to set
+ *  hrate		high rate to set
+ *
+ * Return(s)
+ *	NONE
+ */
+void setTxRate(PADAPTER_STRUCT Adapter, UINT uPort, UINT lrate, UINT hrate)
+{
+	u32	uReg, off;
+
+	if (uPort > SW_MAX_LAN_PORTS) {
+		printk("%s: port is out of range\n", __FUNCTION__);
+		return;
+	}
+	if (SW_MAX_LAN_PORTS == uPort) 
+		off = KS8695_SEP5C2;
+	else
+		off = KS8695_SEP1C2 + uPort * 0x0c;
+	uReg = KS8695_READ_REG(off);
+	/* clear rate bits first */
+	uReg &= ~(KS8695_SEPC2_TX_H_RATECTRL_MASK + KS8695_SEPC2_TX_L_RATECTRL_MASK);
+	uReg = ((hrate << 12) & KS8695_SEPC2_TX_H_RATECTRL_MASK) + (lrate & KS8695_SEPC2_TX_L_RATECTRL_MASK);
+	KS8695_WRITE_REG(off, uReg);
+	DelayInMicroseconds(10);
+}
+
+/*
+ * setRxRate
+ *	This function is use to set receive priority rate control for KS8695P
+ *
+ * Argument(s)
+ *  Adapter		pionter to ADAPTER_STRUCT data structure.
+ *  uPort		uport to set
+ *  lrate		low rate to set
+ *  hrate		high rate to set
+ *
+ * Return(s)
+ *  NONE
+ */
+void setRxRate(PADAPTER_STRUCT Adapter, UINT uPort, UINT lrate, UINT hrate)
+{
+	u32	uReg, off;
+
+	if (uPort > SW_MAX_LAN_PORTS) {
+		printk("%s: port is out of range\n", __FUNCTION__);
+		return;
+	}
+	if (SW_MAX_LAN_PORTS == uPort) 
+		off = KS8695_SEP5C3;
+	else
+		off = KS8695_SEP1C3 + uPort * 0x0c;
+	uReg = KS8695_READ_REG(off);
+	/* clear rate bits first */
+	uReg &= ~(KS8695_SEPC3_RX_H_RATECTRL_MASK + KS8695_SEPC3_RX_L_RATECTRL_MASK);
+	uReg = ((hrate << 20) & KS8695_SEPC3_RX_H_RATECTRL_MASK) + 
+		((lrate << 8) & KS8695_SEPC3_RX_L_RATECTRL_MASK);
+	KS8695_WRITE_REG(off, uReg);
+	DelayInMicroseconds(10);
+}
+
+/*
+ * enableRxRateFlowControl
+ *	This function is use to enable/disalbe receive priority rate flow control for KS8695P
+ *
+ * Argument(s)
+ *  Adapter		pionter to ADAPTER_STRUCT data structure.
+ *  uPort		uport to set
+ *  bEnableLowFlow	enable low rate flow control
+ *  bEnableHighFlow	enable high rate flow control
+ *
+ * Return(s)
+ *  NONE
+ */
+void enableRxRateFlowControl(PADAPTER_STRUCT Adapter, UINT uPort, 
+	UINT bEnableLowFlow, UINT bEnableHighFlow)
+{
+	u32	uReg, off;
+
+	if (uPort > SW_MAX_LAN_PORTS) {
+		printk("%s: port is out of range\n", __FUNCTION__);
+		return;
+	}
+	if (SW_MAX_LAN_PORTS == uPort) 
+		off = KS8695_SEP5C3;
+	else
+		off = KS8695_SEP1C3 + uPort * 0x0c;
+	uReg = KS8695_READ_REG(off);
+	if (bEnableLowFlow) 
+		uReg |= KS8695_SEPC3_RX_L_RATEFLOW_EN;
+	else
+		uReg &= ~KS8695_SEPC3_RX_L_RATEFLOW_EN;
+	if (bEnableHighFlow) 
+		uReg |= KS8695_SEPC3_RX_H_RATEFLOW_EN;
+	else
+		uReg &= ~KS8695_SEPC3_RX_H_RATEFLOW_EN;
+
+	KS8695_WRITE_REG(off, uReg);
+	DelayInMicroseconds(10);
+}
+
+/*
+ * enableRxRateControl
+ *	This function is use to enable/disalbe receive priority rate control for KS8695P
+ *
+ * Argument(s)
+ *  Adapter		pionter to ADAPTER_STRUCT data structure.
+ *  uPort		uport to set
+ *  bEnable		enable/disable differential priority control
+ *  bEnableLow		enable low rate control
+ *  bEnableHigh		enable high rate control
+ *
+ * Return(s)
+ *	NONE
+ */
+void enableRxRateControl(PADAPTER_STRUCT Adapter, UINT uPort, UINT bEnable,
+	UINT bEnableLow, UINT bEnableHigh)
+{
+	u32	uReg, off;
+
+	if (uPort > SW_MAX_LAN_PORTS) {
+		printk("%s: port is out of range\n", __FUNCTION__);
+		return;
+	}
+	if (SW_MAX_LAN_PORTS == uPort) 
+		off = KS8695_SEP5C3;
+	else
+		off = KS8695_SEP1C3 + uPort * 0x0c;
+	uReg = KS8695_READ_REG(off);
+	if (bEnable) 
+		uReg |= KS8695_SEPC3_RX_DIF_RATECTRL_EN;
+	else
+		uReg &= ~KS8695_SEPC3_RX_DIF_RATECTRL_EN;
+	if (bEnableLow) 
+		uReg |= KS8695_SEPC3_RX_L_RATECTRL_EN;
+	else
+		uReg &= ~KS8695_SEPC3_RX_L_RATECTRL_EN;
+	if (bEnableHigh) 
+		uReg |= KS8695_SEPC3_RX_H_RATECTRL_EN;
+	else
+		uReg &= ~KS8695_SEPC3_RX_H_RATECTRL_EN;
+
+	KS8695_WRITE_REG(off, uReg);
+	DelayInMicroseconds(10);
+}
+
+/*
+ * enableTxRateControl
+ *	This function is use to enable/disalbe transmit priority rate control for KS8695P
+ *
+ * Argument(s)
+ *  Adapter		pionter to ADAPTER_STRUCT data structure.
+ *  uPort		uport to set
+ *  bEnable		enable/disable differential priority control
+ *  bEnableLow	enable low rate control
+ *  bEnableHigh	enable high rate control
+ *
+ * Return(s)
+ *	NONE
+ */
+void enableTxRateControl(PADAPTER_STRUCT Adapter, UINT uPort, UINT bEnable,
+	UINT bEnableLow, UINT bEnableHigh)
+{
+	u32	uReg, off;
+
+	if (uPort > SW_MAX_LAN_PORTS) {
+		printk("%s: port is out of range\n", __FUNCTION__);
+		return;
+	}
+	if (SW_MAX_LAN_PORTS == uPort)
+		off = KS8695_SEP5C3;
+	else
+		off = KS8695_SEP1C3 + uPort * 0x0c;
+	uReg = KS8695_READ_REG(off);
+	if (bEnable) 
+		uReg |= KS8695_SEPC3_TX_DIF_RATECTRL_EN;
+	else
+		uReg &= ~KS8695_SEPC3_TX_DIF_RATECTRL_EN;
+	if (bEnableLow) 
+		uReg |= KS8695_SEPC3_TX_L_RATECTRL_EN;
+	else
+		uReg &= ~KS8695_SEPC3_TX_L_RATECTRL_EN;
+	if (bEnableHigh) 
+		uReg |= KS8695_SEPC3_TX_H_RATECTRL_EN;
+	else
+		uReg &= ~KS8695_SEPC3_TX_H_RATECTRL_EN;
+
+	KS8695_WRITE_REG(off, uReg);
+	DelayInMicroseconds(10);
+}
+
+/*
+ * dumpDynamicMacTable
+ *	This function is use to dump entries in dynamic MAC table
+ *
+ * Argument(s)
+ *  Adapter		pionter to ADAPTER_STRUCT data structure.
+ *
+ * Return(s)
+ *	NONE
+ */
+void dumpDynamicMacTable(PADAPTER_STRUCT Adapter)
+{
+	u32	reg, v1, v2, timeout = 1000, i = 0;
+
+	printk("Entry   Port   FID    Mac\n");
+	do {
+		reg = KS8695_SEIAC_READ | KS8695_SEIAC_TAB_DYNAMIC | (KS8695_SEIAC_INDEX_MASK & i);
+		KS8695_WRITE_REG(KS8695_SEIAC, reg);
+		DelayInMicroseconds(10);
+
+		v1 = KS8695_READ_REG(KS8695_SEIADH2);
+		if (v1 & 0x10) {	/* bit 68 = (68 - 64) */
+			/* no valid entries */
+			printk("0 entry\n");
+			return;
+		}
+		v2 = KS8695_READ_REG(KS8695_SEIADH1);
+		/* if valid entries */
+		if (!(v2 & 0x00800000)) {	/* bit 55 */
+#if 0
+			entries = ((v1 & 0xf) << 6) + (v2 >> 26) + 1;
+			/* currently just dump first 16 entries (max 1K entries) for demon purpose */
+			if (entries > 16) {
+				printk("%s: more than 16 entries...(v1=0x%08x, v2=0x%08x)\n", 
+					__FUNCTION__, v1, v2);
+				return;
+			}
+#endif
+			v1 = KS8695_READ_REG(KS8695_SEIADL);
+			printk("%04d    %04d   %4d   %02x:%02x:%02x:%02x:%02x:%02x\n", i, 
+				(v2 >> 20) & 0x7, (v2 >> 16) & 0xf,
+				((v2 >> 8) & 0xff), (v2 & 0xff), 
+				((v1 >> 24) & 0xff), ((v1 >> 16) & 0xff), ((v1 >> 8) & 0xff), (v1 & 0xff));
+			timeout = 0;
+			i++;
+		}
+		DelayInMicroseconds(1);
+	} while (timeout-- > 0 || i >= 16);
+
+	if (timeout < 1)
+		printk("%s: timeout error\n", __FUNCTION__);
+	if (i >= 16) {
+		printk("%s: more than 16 entries...v2=0x%08x\n", 
+			__FUNCTION__, v2);
+	}
+}
+
+/*
+ * disable8021xFlowControl
+ *	This function is use to disable IEEE 802.1x flow control
+ *
+ * Argument(s)
+ *  Adapter	pionter to ADAPTER_STRUCT data structure.
+ *  bTxDisable	disable/enable IEEE 802.1x transmit flow control
+ *  bRxDisable	disable/enable IEEE 802.1x receive flow control
+ *
+ * Return(s)
+ *	NONE
+ */
+void disable8021xFlowControl(PADAPTER_STRUCT Adapter, UINT bTxDisable, UINT bRxDisable)
+{
+	u32	uReg, off;
+
+	off = KS8695_SEC1;
+	uReg = KS8695_READ_REG(off);
+	if (bTxDisable) {
+		uReg |= KS8695_SEC1_NO_TX_8021X_FLOW_CTRL;
+	} else {
+		uReg &= ~KS8695_SEC1_NO_TX_8021X_FLOW_CTRL;
+	}
+	if (bRxDisable) {
+		uReg |= KS8695_SEC1_NO_RX_8021X_FLOW_CTRL;
+	} else {
+		uReg &= ~KS8695_SEC1_NO_RX_8021X_FLOW_CTRL;
+	}
+	KS8695_WRITE_REG(off, uReg);
+	DelayInMicroseconds(10);
+}
+
+/*
+ * enablePhyLoopback
+ *	This function is enable/disable phy loopback for given port
+ *
+ * Argument(s)
+ *  Adapter	pionter to ADAPTER_STRUCT data structure.
+ *  uPort	port to set
+ *  bEnable	disable/enable phy loopback
+ *
+ * Return(s)
+ *	NONE
+ */
+void enablePhyLoopback(PADAPTER_STRUCT Adapter, UINT uPort, UINT bEnable)
+{
+	u32	uReg, off, shift;
+
+	if (uPort > SW_MAX_LAN_PORTS) {
+		printk("%s: port is out of range\n", __FUNCTION__);
+		return;
+	}
+	if (SW_MAX_LAN_PORTS == uPort) {
+		off = KS8695_WAN_POWERMAGR;
+	}
+	else {
+		if (uPort < 2)
+			off = KS8695_LPPM12;
+		else
+			off = KS8695_LPPM34;
+	}
+	shift = uPort % 2 ? 0: 1;	
+	uReg = KS8695_READ_REG(off);
+	if (bEnable) {
+		uReg |= (KS8695_LPPM_PHY_LOOPBACK << (shift * 16));
+	} else {
+		uReg &= ~(KS8695_LPPM_PHY_LOOPBACK << (shift * 16));
+	}
+	KS8695_WRITE_REG(off, uReg);
+	DelayInMicroseconds(10);
+}
+
+/*
+ * enableRemoteLoopback
+ *	This function is enable/disable remote loopback for given port
+ *
+ * Argument(s)
+ *  Adapter	pionter to ADAPTER_STRUCT data structure.
+ *  uPort	port to set
+ *  bEnable	disable/enable remote loopback
+ *
+ * Return(s)
+ *	NONE
+ */
+void enableRemoteLoopback(PADAPTER_STRUCT Adapter, UINT uPort, UINT bEnable)
+{
+	u32	uReg, off, shift;
+
+	if (uPort > SW_MAX_LAN_PORTS) {
+		printk("%s: port is out of range\n", __FUNCTION__);
+		return;
+	}
+	if (SW_MAX_LAN_PORTS == uPort) {
+		off = KS8695_WAN_POWERMAGR;
+	}
+	else {
+		if (uPort < 2)
+			off = KS8695_LPPM12;
+		else
+			off = KS8695_LPPM34;
+	}
+	shift = uPort % 2 ? 0: 1;	
+	uReg = KS8695_READ_REG(off);
+	if (bEnable) {
+		uReg |= (KS8695_LPPM_RMT_LOOPBACK << (shift * 16));
+	} else {
+		uReg &= ~(KS8695_LPPM_RMT_LOOPBACK << (shift * 16));
+	}
+	KS8695_WRITE_REG(off, uReg);
+	DelayInMicroseconds(10);
+}
+
+/*
+ * enablePhyIsolate
+ *	This function is enable/disable phy isolation for given port
+ *
+ * Argument(s)
+ *  Adapter	pionter to ADAPTER_STRUCT data structure.
+ *  uPort	port to set
+ *  bEnable	disable/enable phy isolation
+ *
+ * Return(s)
+ *	NONE
+ */
+void enablePhyIsolate(PADAPTER_STRUCT Adapter, UINT uPort, UINT bEnable)
+{
+	u32	uReg, off, shift;
+
+	if (uPort > SW_MAX_LAN_PORTS) {
+		printk("%s: port is out of range\n", __FUNCTION__);
+		return;
+	}
+	if (SW_MAX_LAN_PORTS == uPort) {
+		off = KS8695_WAN_POWERMAGR;
+	}
+	else {
+		if (uPort < 2)
+			off = KS8695_LPPM12;
+		else
+			off = KS8695_LPPM34;
+	}
+	shift = uPort % 2 ? 0: 1;	
+	uReg = KS8695_READ_REG(off);
+	if (bEnable) {
+		uReg |= (KS8695_LPPM_PHY_ISOLATE << (shift * 16));
+	} else {
+		uReg &= ~(KS8695_LPPM_PHY_ISOLATE << (shift * 16));
+	}
+	KS8695_WRITE_REG(off, uReg);
+	DelayInMicroseconds(10);
+}
+
+/*
+ * forcePhyLink
+ *	This function is enable/disable Link for give port
+ *
+ * Argument(s)
+ *  Adapter	pionter to ADAPTER_STRUCT data structure.
+ *  uPort	port to set
+ *  bEnable	disable/enable phy isolation
+ *
+ * Return(s)
+ *	NONE
+ */
+void forcePhyLink(PADAPTER_STRUCT Adapter, UINT uPort, UINT bEnable)
+{
+	u32	uReg, off, shift;
+
+	if (uPort > SW_MAX_LAN_PORTS) {
+		printk("%s: port is out of range\n", __FUNCTION__);
+		return;
+	}
+	if (SW_MAX_LAN_PORTS == uPort) {
+		off = KS8695_WAN_POWERMAGR;
+	}
+	else {
+		if (uPort < 2)
+			off = KS8695_LPPM12;
+		else
+			off = KS8695_LPPM34;
+	}
+	shift = uPort % 2 ? 0: 1;	
+	uReg = KS8695_READ_REG(off);
+	if (bEnable) {
+		uReg |= (KS8695_LPPM_FORCE_LINK << (shift * 16));
+	} else {
+		uReg &= ~(KS8695_LPPM_FORCE_LINK << (shift * 16));
+	}
+	KS8695_WRITE_REG(off, uReg);
+	DelayInMicroseconds(10);
+}
+
+/*
+ * dumpStaticMacTable
+ *	This function is use to dump entries in static MAC table
+ *
+ * Argument(s)
+ *  Adapter		pionter to ADAPTER_STRUCT data structure.
+ *
+ * Return(s)
+ *	NONE
+ */
+void dumpStaticMacTable(PADAPTER_STRUCT Adapter)
+{
+	u32	reg, v1, v2, i = 0;
+
+	printk("Entry   Port   FID    Mac\n");
+	for (i = 0; i < 8; i++) {
+		reg = KS8695_SEIAC_READ | KS8695_SEIAC_TAB_STATIC | (KS8695_SEIAC_INDEX_MASK & i);
+		KS8695_WRITE_REG(KS8695_SEIAC, reg);
+		DelayInMicroseconds(10);
+
+		v2 = KS8695_READ_REG(KS8695_SEIADH1);
+		/* if table entry is valid */
+		if (v2 & 0x00200000) {
+			v1 = KS8695_READ_REG(KS8695_SEIADL);
+			printk("%04d    0x%02x   %4d   %02x:%02x:%02x:%02x:%02x:%02x\n", i, 
+				(v2 >> 16) & 0x1f, (v2 >> 24) & 0xf,
+				((v2 >> 8) & 0xff), (v2 & 0xff), 
+				((v1 >> 24) & 0xff), ((v1 >> 16) & 0xff), ((v1 >> 8) & 0xff), (v1 & 0xff));
+		}
+	}
+}
+#endif
+
diff -urN linux-2.4.29/drivers/net/ks8695/ks8695_fxhw.h linux-2.4.29-uc1/drivers/net/ks8695/ks8695_fxhw.h
--- linux-2.4.29/drivers/net/ks8695/ks8695_fxhw.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/ks8695/ks8695_fxhw.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,46 @@
+/*
+	Copyright (c) 2002, Micrel Kendin Operations
+
+	Written 2002 by LIQUN RUAN
+
+	This software may be used and distributed according to the terms of 
+	the GNU General Public License (GPL), incorporated herein by reference.
+	Drivers based on or derived from this code fall under the GPL and must
+	retain the authorship, copyright and license notice. This file is not
+	a complete program and may only be used when the entire operating
+	system is licensed under the GPL.
+
+	The author may be reached as lruan@kendin.com
+	Micrel Kendin Operations
+	486 Mercury Dr.
+	Sunnyvale, CA 94085
+
+	This driver is for Kendin's KS8695 SOHO Router Chipset as ethernet driver.
+
+	Support and updates available at
+	www.kendin.com/ks8695/
+
+*/
+#ifndef KS8695_FXHW_H
+#define KS8695_FXHW_H
+#include "ks8695_drv.h"
+
+#define ASSERT(x) if(!(x)) panic("KS8695: x")
+#define DelayInMicroseconds(x) udelay(x)
+#define DelayInMilliseconds(x) mdelay(x)
+
+typedef uint8_t UCHAR, UINT8, BOOLEAN, *PUCHAR;
+typedef uint16_t USHORT, UINT16, *PUSHORT;
+typedef uint32_t UINT, ULONG, UINT32, *PUINT, *PULONG;
+
+#define SPEED_UNKNOWN					0
+#define SPEED_10						10
+#define SPEED_100						100
+#define FULL_DUPLEX						1		// default for full duplex
+#define HALF_DUPLEX						0
+
+#define KS8695_WRITE_REG(reg, value)		((*(volatile uint32_t *)(Adapter->stDMAInfo.nBaseAddr + (reg))) = value)
+#define KS8695_READ_REG(reg)				(*(volatile uint32_t *)(Adapter->stDMAInfo.nBaseAddr + (reg)))
+
+#endif /*KS8695_FXHW_H*/
+
diff -urN linux-2.4.29/drivers/net/ks8695/ks8695_ioctrl.h linux-2.4.29-uc1/drivers/net/ks8695/ks8695_ioctrl.h
--- linux-2.4.29/drivers/net/ks8695/ks8695_ioctrl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/ks8695/ks8695_ioctrl.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,151 @@
+/*
+ * ks8695_ictrol.h
+ *      This header file defines the ioctrols supported by the driver.
+ *
+ *  Copyright (c) 2002-2003, Micrel Semiconductor. All rights reserved.
+ *
+ *  Modification History
+ *
+ *  Name        Date        Ver     Brief
+ *  ----------- ----------- ------- --------------------------------------------
+ *	RLQ	06/03/2003  1.0.0.6 Added new features for KS8695P
+ *	RLQ	08/22/2002  1.0.0.0 First created for sharing among driver, this and web module
+ */
+#ifndef	__KS8695_IOCTRL_H
+#define	__KS8695_IOCTRL_H
+
+/*
+ * local defines
+ */
+enum {
+	REG_DMA_DUMP,			/* dump all base DMA registers (based on current driver is for) */
+	REG_DMA_STATION_DUMP,		/* dump all DMA extra station registers */
+	REG_UART_DUMP,			/* dump all UART related registers */
+	REG_INT_DUMP,			/* dump all Interrupt related registers */
+	REG_TIMER_DUMP,			/* dump all Timer related registers */
+	REG_GPIO_DUMP,			/* dump all GPIO related registers */
+	REG_SWITCH_DUMP,		/* dump all Switch related registers */
+	REG_MISC_DUMP,			/* dump all misc registers */
+	REG_SNMP_DUMP,			/* dump all SNMP registers */
+
+	DRV_VERSION,			/* get driver version, (we need this since proc is removed from driver) */
+
+	DUMP_PCI_SPACE,			/* dump PCI configuration space for KS8695P */
+	DUMP_BRIDGE_REG,		/* dump bridge related register for KS8695P */
+
+	MEMORY_DUMP,			/* to dump given memory */
+	MEMORY_SEARCH,			/* to search for given data pattern */
+
+	REG_WRITE,			/* to write IO register */
+
+	DEBUG_DUMP_TX_PACKET,		/* to debug ethernet packet to transmit */
+	DEBUG_DUMP_RX_PACKET,		/* to debug ethernet packet received */
+
+	DEBUG_RESET_DESC,		/* to reset Rx descriptors */
+	DEBUG_STATISTICS,		/* debug statistics */
+	DEBUG_DESCRIPTORS,		/* debug descriptors */
+
+	DEBUG_LINK_STATUS,		/* debug link status */
+
+	CONFIG_LINK_TYPE,		/* configure link media type */
+	CONFIG_STATION_EX,		/* configure additional station */
+
+	/* switch configuration for web page */
+	CONFIG_SWITCH_GET,		/* get switch configuration settings */
+	CONFIG_SWITCH_SET,		/* set switch configuration settings */
+};
+
+/* defined configured SWITCH SUBID */
+enum CONFIG_SWITCH_SUBID {
+	/* configuration related to basic switch web page */
+	CONFIG_SW_SUBID_ON,				/* turn on/off switch for LAN */
+	CONFIG_SW_SUBID_PORT_VLAN,			/* configure port VLAN ID, and Engress mode */
+	CONFIG_SW_SUBID_PRIORITY,			/* configure port priority */
+
+	/* configuration related to advanced switch web page */
+	CONFIG_SW_SUBID_ADV_LINK_SELECTION,		/* configure port link selection */
+	CONFIG_SW_SUBID_ADV_CTRL,			/* configure switch control register */
+	CONFIG_SW_SUBID_ADV_MIRRORING,			/* configure switch port mirroring */
+	CONFIG_SW_SUBID_ADV_THRESHOLD,			/* configure threshold for both 802.1p and broadcast storm protection */
+	CONFIG_SW_SUBID_ADV_DSCP,			/* configure switch DSCP priority */
+
+	/* configuration related to Switch internal web page */
+	CONFIG_SW_SUBID_INTERNAL_LED,			/* configure LED for all */
+	CONFIG_SW_SUBID_INTERNAL_MISC,			/* configure misc. */
+	CONFIG_SW_SUBID_INTERNAL_SPANNINGTREE,		/* configure spanning tree */
+
+	/* configuration phy related features for KS8695P */
+	CONFIG_SW_SUBID_PHY_IF,				/* configure PHY interface, for KS8695P only */
+	CONFIG_SW_SUBID_SEC1,				/* configure Switch Engine Control 1 register 0xE804 */
+
+	/* for KS8695P only */
+	CONFIG_SW_SUBID_GENERIC_DUMP,			/* generic dump for KS8695), e.g. Dynamic Mac Table, or switch registers */
+	CONFIG_SW_SUBID_RATE_CTRL,			/* high/low priority rate control */
+};
+
+enum  GENERIC_DUMP {
+	GENERIC_DUMP_STATIC,		/* dump static Mac table */
+	GENERIC_DUMP_DYNAMIC,		/* dump dynamic Mac table */
+	GENERIC_DUMP_VLAN,		/* dump VLAN table */
+	GENERIC_DUMP_SWITCH_REGS,	/* dump switch registers for KS8695P */
+};
+
+/* defined configured SWITCH SUBID */
+enum _DEBUG_PACKET {		/* debug packet bit definition */
+	DEBUG_PACKET_LEN	= 0x00000001,		/* debug packet length */
+	DEBUG_PACKET_HEADER	= 0x00000002,		/* debug packet header */
+	DEBUG_PACKET_CONTENT	= 0x00000004,		/* debug packet content */
+	DEBUG_PACKET_OVSIZE	= 0x00000008,		/* dump rx over sized packet content */
+	DEBUG_PACKET_UNDERSIZE	= 0x00000010,		/* prompt rx under sized packet */
+};
+
+#define	REG_DMA_MAX		8
+#define	REG_DMA_STATION_MAX	32
+#define	REG_UART_MAX		9
+#define	REG_INT_MAX		14
+#define	REG_TIMER_MAX		5
+#define	REG_GPIO_MAX		3
+#define	REG_SWITCH_MAX		21
+#define	REG_MISC_MAX		7
+#define	REG_SNMP_MAX		138
+
+#define	DUMP_BUFFER_MAX		1024
+
+#define SW_PHY_AUTO		0   /* autosense */
+#define SW_PHY_10BASE_T		1   /* 10Base-T */
+#define SW_PHY_10BASE_T_FD	2   /* 10Base-T Full Duplex */
+#define SW_PHY_100BASE_TX	3   /* 100Base-TX */
+#define SW_PHY_100BASE_TX_FD	4   /* 100Base-TX Full Duplex */
+
+/* use __packed in armcc later */
+typedef struct {
+	uint8_t		byId;
+	uint16_t	usLen;
+	union {
+		uint32_t	uData[0];
+		uint16_t	usData[0];
+		uint8_t		byData[0];
+	} u;
+} IOCTRL, *PIOCTRL;
+
+typedef struct {
+	uint8_t		byId;
+	uint16_t	usLen;
+	uint8_t		bySubId;
+	union {
+		uint32_t	uData[0];
+		uint16_t	usData[0];
+		uint8_t		byData[0];
+	} u;
+} IOCTRL_SWITCH, *PIOCTRL_SWITCH;
+
+enum _LINK_SELECTION {
+	LINK_SELECTION_FULL_AUTO = 0,		/* fully auto nego */
+	LINK_SELECTION_FORCED,				/* forced mode, no auto nego */
+	LINK_SELECTION_PARTIAL_AUTO,		/* partial auto nego */
+};
+
+/* The proprietary IOCTL code for PHY IO access */
+#define SIOC_KS8695_IOCTRL	(SIOCDEVPRIVATE + 15)
+
+#endif	/*__KS8695_IOCTRL_H*/
diff -urN linux-2.4.29/drivers/net/ks8695/ks8695_kcompat.h linux-2.4.29-uc1/drivers/net/ks8695/ks8695_kcompat.h
--- linux-2.4.29/drivers/net/ks8695/ks8695_kcompat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/ks8695/ks8695_kcompat.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,316 @@
+/*****************************************************************************
+ *****************************************************************************
+
+ Copyright (c) 1999 - 2001, Intel Corporation 
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without 
+ modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice, 
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright notice,
+     this list of conditions and the following disclaimer in the documentation 
+     and/or other materials provided with the distribution.
+
+  3. Neither the name of Intel Corporation nor the names of its contributors 
+     may be used to endorse or promote products derived from this software 
+     without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+
+ *****************************************************************************
+ *****************************************************************************/
+
+/* Macros to make drivers compatible with 2.2, 2.4 Linux kernels
+ *
+ * In order to make a single network driver work with all 2.2, 2.4 kernels
+ * these compatibility macros can be used.
+ * They are backwards compatible implementations of the latest APIs.
+ * The idea is that these macros will let you use the newest driver with old
+ * kernels, but can be removed when working with the latest and greatest.
+ */
+
+#ifndef __KS8695_LINUX_KERNEL_COMPAT_H
+#define __KS8695_LINUX_KERNEL_COMPAT_H
+
+#include <linux/version.h>
+
+/* a good type to have */
+/* in Linux a long is always the same length as a pointer */
+typedef unsigned long int uintptr_t;
+
+/*****************************************************************************
+ **
+ **  PCI Bus Changes
+ **
+ *****************************************************************************/
+
+/* Accessing the BAR registers from the PCI device structure
+ * Changed from base_address[bar] to resource[bar].start in 2.3.13
+ * The pci_resource_start inline function was introduced in 2.3.43 
+ */
+#if   ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13) )
+#define pci_resource_start(dev, bar) \
+		(((dev)->base_address[(bar)] & PCI_BASE_ADDRESS_SPACE_IO) ? \
+		 ((dev)->base_address[(bar)] & PCI_BASE_ADDRESS_IO_MASK) : \
+		 ((dev)->base_address[(bar)] & PCI_BASE_ADDRESS_MEM_MASK))
+#elif ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) )
+#define pci_resource_start(dev, bar) \
+		(((dev)->resource[(bar)] & PCI_BASE_ADDRESS_SPACE_IO) ? \
+		 ((dev)->resource[(bar)] & PCI_BASE_ADDRESS_IO_MASK) : \
+		 ((dev)->resource[(bar)] & PCI_BASE_ADDRESS_MEM_MASK))
+#endif
+
+/* Starting with 2.3.23 drivers are supposed to call pci_enable_device
+ * to make sure I/O and memory regions have been mapped and potentially 
+ * bring the device out of a low power state
+ */
+#if   ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,23) )
+#define pci_enable_device(dev) (0)
+#endif
+
+/* Dynamic DMA mapping
+ * Instead of using virt_to_bus, bus mastering PCI drivers should use the DMA 
+ * mapping API to get bus addresses.  This lets some platforms use dynamic 
+ * mapping to use PCI devices that do not support DAC in a 64-bit address space
+ */
+#if   ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,41) )
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+
+#if (( LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) ) || \
+     ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) ) )
+typedef unsigned long dma_addr_t;
+#endif
+
+#define PCI_DMA_TODEVICE   1
+#define PCI_DMA_FROMDEVICE 2
+
+extern inline void *pci_alloc_consistent (struct pci_dev *dev, 
+                                          size_t size, 
+                                          dma_addr_t *dma_handle) {
+    void *vaddr = kmalloc(size, GFP_KERNEL);
+    if(vaddr != NULL) {
+        *dma_handle = virt_to_phys(vaddr);
+    }
+    return vaddr; 
+}
+
+extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
+{ return 1; }
+
+extern inline void pci_free_consistent(struct pci_dev *hwdev, size_t size, 
+                                       void *cpu_addr, dma_addr_t dma_handle)
+{ kfree(cpu_addr); return; }
+
+static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+                                        size_t size, int direction)
+{ return virt_to_phys(ptr); }
+
+static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+                                    size_t size, int direction)
+{ return; }
+/* Ug, this is ks8695 specific */
+#define pci_resource_len(a,b)        (128 * 1024)
+
+static inline int request_mem_region(uintptr_t addr, ...) { return 1; }
+static inline int release_mem_region(uintptr_t addr, ...) { return 0; }
+#endif
+
+
+/*****************************************************************************
+ **
+ **  Network Device API Changes
+ **
+ *****************************************************************************/
+
+/* In 2.3.14 the device structure was renamed to net_device 
+ */
+#if   ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,14) )
+#define net_device device
+#endif
+
+/* 'Softnet' network stack changes merged in 2.3.43 
+ * these are 2.2 compatible defines for the new network interface API
+ * 2.3.47 added some more inline functions for softnet to remove explicit 
+ * bit tests in drivers
+ */
+#if   ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) )
+#define netif_start_queue(dev)   clear_bit  (0, &(dev)->tbusy)
+#define netif_stop_queue(dev)    set_bit    (0, &(dev)->tbusy)
+#define netif_wake_queue(dev)    { clear_bit(0, &(dev)->tbusy); \
+                                                mark_bh(NET_BH); }
+#define netif_running(dev)       test_bit(0, &(dev)->start)
+#define netif_queue_stopped(dev) test_bit(0, &(dev)->tbusy)
+#elif ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,47) )
+#define netif_running(dev)       test_bit(LINK_STATE_START, &(dev)->state)
+#define netif_queue_stopped(dev) test_bit(LINK_STATE_XOFF,  &(dev)->state)
+#endif
+
+/* Softnet changes also affected how SKBs are handled
+ * Special calls need to be made now while in an interrupt handler
+ */
+#if   ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) )
+#define dev_kfree_skb_irq(skb) dev_kfree_skb(skb)
+#endif
+
+/*****************************************************************************
+ **
+ **  General Module / Driver / Kernel API Changes
+ **
+ *****************************************************************************/
+
+/* New module_init macro added in 2.3.13 - replaces init_module entry point
+ * If MODULE is defined, it expands to an init_module definition
+ * If the driver is staticly linked to the kernel, it creates the proper 
+ * function pointer for the initialization routine to be called
+ * (no more Space.c)
+ * module_exit does the same thing for cleanup_module
+ */
+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13) )
+#define module_init(fn) int  init_module   (void) { return fn(); }
+#define module_exit(fn) void cleanup_module(void) { return fn(); }
+#endif
+
+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) )
+#ifndef __KS8695_MAIN__
+#define __NO_VERSION__
+#endif
+#endif
+
+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,47) )
+#define PCI_ANY_ID (~0U)
+
+struct pci_device_id {
+    unsigned int vendor, device;
+    unsigned int subvendor, subdevice;
+    unsigned int class, classmask;
+    unsigned long driver_data;
+};
+
+#define MODULE_DEVICE_TABLE(bus, dev_table)
+
+struct pci_driver {
+	char *name;
+	struct pci_device_id *id_table;
+	int (*probe)(struct pci_dev *dev, const struct pci_device_id *id);
+	void (*remove)(struct pci_dev *dev);
+	void (*suspend)(struct pci_dev *dev);
+	void (*resume)(struct pci_dev *dev);
+	/* track devices on Linux 2.2, used by module_init and unregister_driver */
+	/* not to be used by the driver directly */
+	/* assumes single function device with function #0 to simplify */
+	uint32_t pcimap[256];
+};
+
+static inline int pci_module_init(struct pci_driver *drv)
+{
+	struct pci_dev *pdev;
+	struct pci_device_id *pciid;
+	uint16_t subvendor, subdevice;
+	int board_count = 0;
+
+	/* walk the global pci device list looking for matches */
+	for (pdev = pci_devices; pdev != NULL; pdev = pdev->next) {
+		pciid = &drv->id_table[0];
+		pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subvendor);
+		pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subdevice);
+		
+		while (pciid->vendor != 0) {
+			if(((pciid->vendor == pdev->vendor) ||
+				(pciid->vendor == PCI_ANY_ID)) &&
+
+			   ((pciid->device == pdev->device) ||
+				(pciid->device == PCI_ANY_ID)) &&
+
+			   ((pciid->subvendor == subvendor) ||
+				(pciid->subvendor == PCI_ANY_ID)) &&
+
+			   ((pciid->subdevice == subdevice) ||
+				(pciid->subdevice == PCI_ANY_ID))) {
+
+				if(drv->probe(pdev, pciid) == 0) {
+					board_count++;
+
+					/* keep track of pci devices found */
+					set_bit((pdev->devfn >> 3),
+							&(drv->pcimap[pdev->bus->number]));
+				}
+				break;
+			}
+			pciid++;
+		}
+	}
+
+	return (board_count > 0) ? 0 : -ENODEV;
+}
+
+static inline void pci_unregister_driver(struct pci_driver *drv)
+{
+	int i, bit;
+	struct pci_dev *pdev;
+
+	/* search the pci device bitmap and release them all */
+	for(i = 0; i < 256; i++) {
+		/* ffs = find first set bit */
+		for(bit = ffs(drv->pcimap[i]); bit > 0; bit = ffs(drv->pcimap[i])) {
+			bit--;
+			pdev = pci_find_slot(i, (bit << 3));
+			drv->remove(pdev);
+			clear_bit(bit, &drv->pcimap[i]);
+		}
+	}
+}
+#endif
+
+/* Taslets */
+
+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) )
+
+#include <linux/interrupt.h>
+#define tasklet_struct tq_struct
+
+static inline void tasklet_init(struct tasklet_struct *t,
+				void (*func)(unsigned long), unsigned long data)
+{
+	t->next = NULL;
+	t->sync = 0;
+	t->routine = (void *)(void *)func;
+	t->data = (void *)data;
+}
+
+static inline void tasklet_schedule(struct tasklet_struct *t)
+{
+	queue_task(t, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+	return;
+}
+
+static inline void tasklet_disable(struct tasklet_struct *t)
+{
+	return;
+}
+
+static inline void tasklet_enable(struct tasklet_struct *t)
+{
+	return;
+}
+
+#endif
+
+#endif /* __KS8695_LINUX_KERNEL_COMPAT_H */
+
diff -urN linux-2.4.29/drivers/net/ks8695/ks8695_main.c linux-2.4.29-uc1/drivers/net/ks8695/ks8695_main.c
--- linux-2.4.29/drivers/net/ks8695/ks8695_main.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/ks8695/ks8695_main.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,4054 @@
+/*
+	Copyright (c) 2002-2003, Micrel Semiconductor
+
+	Written 2002 by LIQUN RUAN
+
+	This software may be used and distributed according to the terms of 
+	the GNU General Public License (GPL), incorporated herein by reference.
+	Drivers based on or derived from this code fall under the GPL and must
+	retain the authorship, copyright and license notice. This file is not
+	a complete program and may only be used when the entire operating
+	system is licensed under the GPL.
+
+	The author may be reached as liqun.ruan@micrel.com
+	Micrel Semiconductor
+	1931 Fortune Dr.
+	San Jose, CA 95131
+
+	This driver is for Micrel's KS8695/KS8695P SOHO Router Chipset as ethernet driver.
+
+	Support and updates available at
+	www.micrel.com/ks8695/		not ready yet!!!
+
+*/
+#define __KS8695_MAIN__
+#include "ks8695_drv.h"
+#include "ks8695_ioctrl.h"
+#include "ks8695_cache.h"
+#include <asm-arm/unaligned.h>
+
+/* define which external ports do what... */
+#if defined(CONFIG_MACH_CM4008) || defined(CONFIG_MACH_CM41xx) || \
+    defined(CONFIG_MACH_LITE300)
+#define	LANPORT		0
+#define	WANPORT		1
+#define	HPNAPORT	2
+#else
+#define	WANPORT		0
+#define	LANPORT		1
+#define	HPNAPORT	2
+#endif
+
+#undef	  USE_TX_UNAVAIL
+#undef	  USE_RX_UNAVAIL
+#undef	  PACKET_DUMP
+
+/* process recevied packet in task ReceiveProcessTask().*/
+//RLQ, defined in Makfile
+//#define	  RX_TASK
+//#define	  TX_TASK
+
+/* process recevied packet in ISR.*/
+#undef    HANDLE_RXPACKET_BY_INTERRUPT
+#ifdef    HANDLE_RXPACKET_BY_INTERRUPT
+#undef	  RX_TASK
+#undef	  TX_TASK
+#endif
+
+#define	USE_FIQ
+
+/* these functions are not standard linux kernel funcitons. We added these in the consistent.c under /arch/mm */
+/* it call virt_to_phys include virt_to_bus to get physical address */
+extern void *consistent_alloc_ex(int gfp, size_t size, dma_addr_t *dma_handle);
+extern void consistent_free_ex(void *vaddr, size_t size, dma_addr_t handle);
+
+static int offset = 2;		/* shift 2 bytes so that IP header can align to dword boundary */
+
+/* update dcache by ourself only if no PCI subsystem is used */
+#define KS8695_MAX_INTLOOP	1
+#define	WATCHDOG_TICK		3
+
+#ifndef	CONFIG_ARCH_KS8695P
+#ifdef	KS8695X
+char ks8695_driver_name[] = "ks8695X SOHO Router 10/100T Ethernet Dirver";
+char ks8695_driver_string[]="Micrel KS8695X Ethernet Network Driver";
+#else
+char ks8695_driver_name[] = "ks8695 SOHO Router 10/100T Ethernet Dirver";
+char ks8695_driver_string[]="Micrel KS8695 Ethernet Network Driver";
+#endif	/*KS8695X*/
+#else
+char ks8695_driver_name[] = "ks8695P SOHO Router 10/100T Ethernet Dirver";
+char ks8695_driver_string[]="Micrel KS8695P Ethernet Network Driver";
+#endif //CONFIG_ARCH_KS8695P
+char ks8695_driver_version[] = "1.0.0.20";
+char ks8695_copyright[] = "Copyright (c) 2002-2004 Micrel Semiconductor Corp.";
+
+PADAPTER_STRUCT ks8695_adapter_list = NULL;
+
+#if defined(CONFIG_MACH_CM4008) || defined(CONFIG_MACH_CM41xx)
+#define KS8695_MAX_NIC		1		/* Only 1 LAN port used */
+#elif !defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+#define KS8695_MAX_NIC		3		/* 0 for WAN, 1 for LAN and 2 for HPHA */
+#else
+#define KS8695_MAX_NIC		2		/* 0 for WAN and 1 for LAN, KS8695X doesn't have HPNA port either */
+#endif //CONFIG_ARCH_KS8695P
+
+#define	STAT_NET(x)			(Adapter->net_stats.x)
+
+static struct pci_dev pci_dev_mimic[KS8695_MAX_NIC];
+static int	pci_dev_index = 0;		/* max dev probe allowed */
+
+#define KS8695_OPTION_INIT	{ [0 ... KS8695_MAX_NIC - 1] = OPTION_UNSET }
+
+static int TxDescriptors[KS8695_MAX_NIC] = KS8695_OPTION_INIT;
+static int RxDescriptors[KS8695_MAX_NIC] = KS8695_OPTION_INIT;
+static int Speed[KS8695_MAX_NIC] = KS8695_OPTION_INIT;
+static int Duplex[KS8695_MAX_NIC] = KS8695_OPTION_INIT;
+static int FlowControl[KS8695_MAX_NIC] = KS8695_OPTION_INIT;
+static int RxChecksum[KS8695_MAX_NIC] = KS8695_OPTION_INIT;
+static int TxChecksum[KS8695_MAX_NIC] = KS8695_OPTION_INIT;
+static int TxPBL[KS8695_MAX_NIC] = KS8695_OPTION_INIT;
+static int RxPBL[KS8695_MAX_NIC] = KS8695_OPTION_INIT;
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+static int HPNA = OPTION_UNSET;
+#endif
+#ifdef	__KS8695_CACHE_H
+static int PowerSaving = 0;		/* default is off */
+static int ICacheLockdown = 0;		/* default is off */
+static int RoundRobin = 1;		/* default Icache is roundrobin */
+#endif
+
+/* if defined as module */
+#ifdef MODULE
+
+#ifndef	CONFIG_ARCH_KS8695P
+#ifdef	KS8695X
+MODULE_AUTHOR("Micrel Semiconductor, <liqun.ruan@micrel.com>");
+MODULE_DESCRIPTION("Micrel KS8695X SOHO Router Ethernet Network Driver");
+#else
+/* for historical reason */
+MODULE_AUTHOR("Micrel Kendin Operations, <lruan@kendin.com>");
+MODULE_DESCRIPTION("Micrel Kendin KS8695 SOHO Router Ethernet Network Driver");
+#endif
+#else
+MODULE_AUTHOR("Micrel Semiconductor, <liqun.ruan@micrel.com>");
+MODULE_DESCRIPTION("Micrel KS8695P SOHO Router Ethernet Network Driver");
+#endif
+#ifdef	ARM_LINUX
+MODULE_LICENSE("GPL");
+#endif
+
+MODULE_PARM(TxDescriptors,	"1-" __MODULE_STRING(KS8695_MAX_NIC) "i");
+MODULE_PARM(RxDescriptors,	"1-" __MODULE_STRING(KS8695_MAX_NIC) "i");
+MODULE_PARM(Speed,		"1-" __MODULE_STRING(KS8695_MAX_NIC) "i");
+MODULE_PARM(Duplex,		"1-" __MODULE_STRING(KS8695_MAX_NIC) "i");
+MODULE_PARM(FlowControl,	"1-" __MODULE_STRING(KS8695_MAX_NIC) "i");
+MODULE_PARM(RxChecksum,		"1-" __MODULE_STRING(KS8695_MAX_NIC) "i");
+MODULE_PARM(TxChecksum,		"1-" __MODULE_STRING(KS8695_MAX_NIC) "i");
+MODULE_PARM(TxPBL,		"1-" __MODULE_STRING(KS8695_MAX_NIC) "i");
+MODULE_PARM(RxPBL,		"1-" __MODULE_STRING(KS8695_MAX_NIC) "i");
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+MODULE_PARM(HPNA,		"1-i");
+#endif
+MODULE_PARM(PowerSaving,	"1-i");
+MODULE_PARM(ICacheLockdown,	"1-i");
+MODULE_PARM(RoundRobin,		"1-i");
+
+EXPORT_SYMBOL(ks8695_init_module);
+EXPORT_SYMBOL(ks8695_exit_module);
+EXPORT_SYMBOL(ks8695_probe);
+EXPORT_SYMBOL(ks8695_remove);
+EXPORT_SYMBOL(ks8695_open);
+EXPORT_SYMBOL(ks8695_close);
+EXPORT_SYMBOL(ks8695_xmit_frame);
+EXPORT_SYMBOL(ks8695_isr);
+EXPORT_SYMBOL(ks8695_isr_link);
+EXPORT_SYMBOL(ks8695_set_multi);
+EXPORT_SYMBOL(ks8695_change_mtu);
+EXPORT_SYMBOL(ks8695_set_mac);
+EXPORT_SYMBOL(ks8695_get_stats);
+EXPORT_SYMBOL(ks8695_watchdog);
+EXPORT_SYMBOL(ks8695_ioctl);
+
+/* for I-cache lockdown or FIQ purpose */
+EXPORT_SYMBOL(ks8695_isre);
+
+#endif	//MODULE
+
+int ks8695_module_probe(void);
+EXPORT_SYMBOL(ks8695_module_probe);
+
+/*********************************************************************
+ * Fast timer poll support
+ *********************************************************************/
+
+#if defined(CONFIG_FAST_TIMER)
+#define FAST_POLL 1
+#include <linux/fast_timer.h>
+static void ks8695_fast_poll(void *arg);
+static int ks8695_poll_ready;
+#endif
+
+/*********************************************************************
+ * Local Function Prototypes
+ *********************************************************************/
+static void CheckConfigurations(PADAPTER_STRUCT Adapter);
+static int  SoftwareInit(PADAPTER_STRUCT Adapter);
+static int  HardwareInit(PADAPTER_STRUCT Adapter);
+static int  AllocateTxDescriptors(PADAPTER_STRUCT Adapter);
+static int  AllocateRxDescriptors(PADAPTER_STRUCT Adapter);
+static void FreeTxDescriptors(PADAPTER_STRUCT Adapter);
+static void FreeRxDescriptors(PADAPTER_STRUCT Adapter);
+static void UpdateStatsCounters(PADAPTER_STRUCT Adapter);
+#if	0
+static int	ProcessTxInterrupts(PADAPTER_STRUCT Adapter);
+static int	ProcessRxInterrupts(PADAPTER_STRUCT Adapter);
+#endif
+static void ReceiveBufferFill(uintptr_t data);
+static void CleanTxRing(PADAPTER_STRUCT Adapter);
+static void CleanRxRing(PADAPTER_STRUCT Adapter);
+static void InitTxRing(PADAPTER_STRUCT Adapter);
+static void InitRxRing(PADAPTER_STRUCT Adapter);
+/*static void ReceiveBufferFillEx(PADAPTER_STRUCT Adapter);*/
+#ifdef	__KS8695_CACHE_H
+static int ks8695_icache_lock2(void *icache_start, void *icache_end);
+#endif
+
+#ifdef	RX_TASK
+static void ReceiveProcessTask(uintptr_t data);
+#endif
+#ifdef	TX_TASK
+static void TransmitProcessTask(uintptr_t data);
+#endif
+
+/*
+ * ResetDma
+ *	This function is use to reset DMA in case Tx DMA was sucked due to 
+ *	heavy traffic condition.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+static __inline void ResetDma(PADAPTER_STRUCT Adapter)
+{
+	struct net_device *netdev;
+	/*BOOLEAN	bTxStarted, bRxStarted;*/
+	UINT uRxReg;
+
+#ifdef	DEBUG_THIS 
+	if (DMA_LAN == DI.usDMAId) {
+		DRV_INFO("%s: LAN", __FUNCTION__);
+	} else if (DMA_WAN == DI.usDMAId) {
+		DRV_INFO("%s: WAN", __FUNCTION__);
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	} else {
+		DRV_INFO("%s: HPNA", __FUNCTION__);
+#endif
+	}
+#endif 
+
+	if (!test_bit(KS8695_BOARD_OPEN, &Adapter->flags)) {
+		DRV_INFO("%s: driver not opened yet", __FUNCTION__);
+		return;
+	}
+
+	netdev = Adapter->netdev;
+
+#ifdef	RX_TASK
+	tasklet_disable(&DI.rx_tasklet);
+#endif
+#ifdef	TX_TASK
+	tasklet_disable(&DI.tx_tasklet);
+#endif
+	netif_stop_queue(netdev);
+
+	macStopAll(Adapter);
+
+	CleanRxRing(Adapter);
+	InitRxRing(Adapter);
+	CleanTxRing(Adapter);
+	InitTxRing(Adapter);
+
+	ks8695_ChipInit(Adapter, FALSE);
+
+	KS8695_WRITE_REG(KS8695_INT_STATUS, DI.uIntMask);
+
+	/* read RX mode register */
+	uRxReg = KS8695_READ_REG(REG_RXCTRL + DI.nOffset);
+	if (netdev->flags & IFF_PROMISC) {
+		uRxReg |= DMA_PROMISCUOUS;
+	}
+	if (netdev->flags & (IFF_ALLMULTI | IFF_MULTICAST)) {
+		uRxReg |= DMA_MULTICAST;
+	}
+	uRxReg |= DMA_BROADCAST;
+
+	/* write RX mode register */
+	KS8695_WRITE_REG(REG_RXCTRL + DI.nOffset, uRxReg);
+
+	KS8695_WRITE_REG(REG_RXBASE + DI.nOffset, cpu_to_le32(DI.RxDescDMA));
+	KS8695_WRITE_REG(REG_TXBASE + DI.nOffset, cpu_to_le32(DI.TxDescDMA));
+	macEnableInterrupt(Adapter, TRUE);
+
+#ifdef	RX_TASK
+	tasklet_enable( &DI.rx_tasklet );
+	if (DI.rx_scheduled) {
+		tasklet_hi_schedule(&DI.rx_tasklet);
+	}
+#endif
+#ifdef	TX_TASK
+	tasklet_enable( &DI.tx_tasklet );
+	if (DI.tx_scheduled) {
+		tasklet_hi_schedule(&DI.tx_tasklet);
+	}
+#endif
+	netif_start_queue(netdev);
+
+	/*if (bRxStarted)*/
+		macStartRx(Adapter, TRUE);
+	/*if (bTxStarted)*/
+		macStartTx(Adapter, TRUE);
+}
+
+/*
+ * ks8695_dump_packet
+ *	This function is use to dump given packet for debugging.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *	data		pointer to the beginning of the packet to dump
+ *	len			length of the packet
+ *	flag		debug flag
+ *
+ * Return(s)
+ *	NONE.
+ */
+#ifndef PING_READY
+static __inline void ks8695_dump_packet(PADAPTER_STRUCT Adapter, unsigned char *data, int len, UINT flag)
+{
+	/* we may need to have locking mechamism to use this function, since Rx call it within INT context
+	   and Tx call it in normal context */
+
+	if (flag && len >= 18) {
+		if (flag & DEBUG_PACKET_LEN) {
+			printk("Pkt Len=%d\n", len);
+		}
+		if (flag & DEBUG_PACKET_CONTENT) {
+			int	j = 0, k;
+
+			do {
+				printk("\n %08x   ", (int)(data+j));
+				for (k = 0; (k < 16 && len); k++, data++, len--) {
+					printk("%02x  ", *data);
+				}
+				j += 16;
+			} while (len > 0);
+			printk("\n");
+		}
+	}
+}
+#endif
+
+#ifdef PING_READY
+static __inline void ks8695_dump_packet(PADAPTER_STRUCT Adapter, unsigned char *data, int len, UINT flag)
+{
+	/* we may need to have locking mechamism to use this function, since Rx call it within INT context
+	   and Tx call it in normal context */
+
+	    DRV_INFO("%s", __FUNCTION__); 
+
+	if (flag && len >= 18) {
+		if (flag & DEBUG_PACKET_LEN) {
+			printk("Pkt Len=%d\n", len);
+		}
+		if (flag & DEBUG_PACKET_HEADER) {
+			printk("DA=%02x:%02x:%02x:%02x:%02x:%02x\n", 
+				*data, *(data + 1), *(data + 2), *(data + 3), *(data + 4), *(data + 5));
+			printk("SA=%02x:%02x:%02x:%02x:%02x:%02x\n", 
+				*(data + 6), *(data + 7), *(data + 8), *(data + 9), *(data + 10), *(data + 11));
+			printk("Type=%04x (%d)\n", ntohs(*(unsigned short *)(data + 12)), ntohs(*(unsigned short *)(data + 12)));
+		}
+		if (flag & DEBUG_PACKET_CONTENT) {
+			int	j = 0, k;
+
+			/* skip DA/SA/TYPE, ETH_HLEN is defined in if_ether.h under include/linux dir */
+			data += ETH_HLEN;
+			/*len -= (ETH_HLEN + ETH_CRC_LENGTH);*/
+			len -= ETH_HLEN;
+			do {
+				printk("\n %04d   ", j);
+				for (k = 0; (k < 16 && len); k++, data++, len--) {
+					printk("%02x  ", *data);
+				}
+				j += 16;
+			} while (len > 0);
+			/* last dump crc field */
+			/*printk("\nCRC=%04x\n", ntohl(*(unsigned int *)data));*/
+		}
+	}
+}
+#endif
+
+
+/*
+ * ks8695_relink
+ *	This function is use to setup link in case some dynamic configuration
+ *	is applied via ifconfig! if driver is opened!
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *
+ * Return(s)
+ *	NONE.
+ */
+static void ks8695_relink(PADAPTER_STRUCT Adapter)
+{
+	if (test_bit(KS8695_BOARD_OPEN, &Adapter->flags)) {
+		/* reset the flag even if it is auto nego is in progress
+		   to make sure we don't miss it!!! */
+		if (DMA_LAN != DI.usDMAId) {
+			swDetectPhyConnection(Adapter, 0);
+		}
+		else {
+			int	i;
+
+			for (i = 0; i < SW_MAX_LAN_PORTS; i++) {
+				swDetectPhyConnection(Adapter, i);
+			}
+		}
+	}
+}
+
+/*
+ * ks8695_report_carrier
+ *	This function is use to report carrier status to net device
+ *
+ * Argument(s)
+ *	netdev		pointer to net_device structure.
+ *	carrier		carrier status (0 off, non zero on)
+ *
+ * Return(s)
+ *	NONE.
+ */
+static void ks8695_report_carrier(struct net_device *netdev, int carrier)
+{
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	/* if link is on */
+	if (carrier) {
+		netif_carrier_on(netdev);
+		netif_carrier_ok(netdev);
+	}
+	else {
+		netif_carrier_off(netdev);
+	}
+}
+
+/*
+ * ks8695_module_probe
+ *	This function is used to simulate pci's probe function.
+ *
+ * Argument(s)
+ *	NONE.
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+int ks8695_module_probe(void)
+{
+	spinlock_t	eth_lock = SPIN_LOCK_UNLOCKED;
+	unsigned long flags;
+	int	nRet;
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	int nHPHA = 0;
+#endif
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+#ifdef	__KS8695_CACHE_H
+	if (RoundRobin) {
+		ks8695_icache_change_policy(RoundRobin);
+	}
+	if (ICacheLockdown)
+		ks8695_icache_lock2(ks8695_isr, ks8695_isre);
+#endif
+	
+	if (pci_dev_index >= KS8695_MAX_NIC)
+		return -EINVAL;
+
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	/* if user enabled HPNA */
+	if (HPNA != OPTION_UNSET) {
+		nHPHA = HPNA ? 1 : 0;
+	}
+#endif
+
+#ifdef	__KS8695_CACHE_H
+	/* if allow power saving, default no power saving (wait for interrupt) */
+	if (PowerSaving) {
+		ks8695_enable_power_saving(PowerSaving);
+	}
+#endif
+
+	nRet = 0;
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	/* default WAN and LAN, plus HPNA if enabled by the user */
+	for (pci_dev_index = 0; pci_dev_index < (2 + nHPHA); pci_dev_index++) {
+#else
+	/* KS8695P and KS8695X has only WAN and LAN */
+	for (pci_dev_index = 0; pci_dev_index < KS8695_MAX_NIC; pci_dev_index++) {
+#endif
+		if (0 == pci_dev_index) {
+			strcpy(pci_dev_mimic[pci_dev_index].name, "WAN Port");
+			pci_dev_mimic[pci_dev_index].irq = 29;
+		}
+		else if (1 == pci_dev_index) {
+			strcpy(pci_dev_mimic[pci_dev_index].name, "LAN Port");
+			pci_dev_mimic[pci_dev_index].irq = 22;
+		}
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+		else {
+			strcpy(pci_dev_mimic[pci_dev_index].name, "HPNA Port");
+			pci_dev_mimic[pci_dev_index].irq = 14;
+		}
+#endif
+#ifdef	DEBUG_THIS
+		DRV_INFO("%s: set ks8695_probe(%d)", __FUNCTION__, pci_dev_index);
+#endif
+		spin_lock_irqsave(&eth_lock, flags);
+		/* we don't use pci id field, so set it to NULL */
+		nRet = ks8695_probe(&pci_dev_mimic[pci_dev_index], NULL);
+		spin_unlock_irqrestore(&eth_lock, flags);
+		/* if error happened */
+		if (nRet) {
+			DRV_ERR("%s: ks8695_probe(%d) failed, error code = 0x%08x", __FUNCTION__, pci_dev_index, nRet);
+			break;
+		}
+	}
+
+	return nRet;
+}
+
+/*
+ * hook_irqs
+ *	This function is used to hook irqs associated to given DMA type
+ *
+ * Argument(s)
+ *	netdev	pointer to netdev structure.
+ *	req		request or free interrupts
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+static int hook_irqs(struct net_device *netdev, int req)
+{
+	PADAPTER_STRUCT Adapter = netdev->priv;
+#ifndef FAST_POLL
+	int	i;
+#endif
+
+	switch (DI.usDMAId) {
+	default:
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	case DMA_HPNA:
+#endif
+	case DMA_LAN:
+		break;
+
+	case DMA_WAN:
+		if (DI.uLinkIntMask & INT_WAN_LINK) {
+			if (req) {
+#ifndef	USE_FIQ
+				if (request_irq(31, &ks8695_isr_link, SA_SHIRQ, pci_dev_mimic[Adapter->bd_number].name, netdev)) {
+#else
+				if (request_irq(31, &ks8695_isr_link, SA_SHIRQ | SA_INTERRUPT, pci_dev_mimic[Adapter->bd_number].name, netdev)) {
+#endif
+					return -EBUSY;
+				}
+			}
+			else {
+				free_irq(31, netdev);
+			}
+		}
+		break;
+	}
+
+#ifdef FAST_POLL
+	if (req)
+		fast_timer_add(ks8695_fast_poll, netdev);
+	else
+		fast_timer_remove(ks8695_fast_poll, netdev);
+#else
+	/* each DMA has 6 interrupt bits associated, except WAN which has one extra, INT_WAN_LINK */
+	for (i = 0; i < 6; i++) {
+		if (DI.uIntMask & (1L << (DI.uIntShift + i))) {
+			if (req) {
+#ifndef	USE_FIQ
+				if (request_irq(i + DI.uIntShift, &ks8695_isr, SA_SHIRQ, pci_dev_mimic[Adapter->bd_number].name, netdev)) {
+#else
+				if (request_irq(i + DI.uIntShift, &ks8695_isr, SA_SHIRQ | SA_INTERRUPT, pci_dev_mimic[Adapter->bd_number].name, netdev)) {
+#endif
+					return -EBUSY;
+				}
+			}
+			else {
+				free_irq(i + DI.uIntShift, netdev);
+			}
+		}
+	}
+#endif /* FAST_POLL */
+
+	return 0;
+}
+
+/*
+ *	Determine MAC addresses for ethernet ports.
+ */
+#if defined(CONFIG_MACH_CM4008) || defined(CONFIG_MACH_CM41xx)
+#define	MAC_OFFSET	0x1c000
+#define MAC_DEFAULT	0x00, 0x13, 0xc6, 0x00, 0x00, 0x00
+#elif defined(CONFIG_MACH_LITE300)
+#define	MAC_OFFSET	0x0c000
+#define	MAC_DEFAULT	0x00, 0xd0, 0xcf, 0x00, 0x00, 0x00
+#endif
+
+#ifdef MAC_OFFSET
+/*
+ *	Ideally we want to use the MAC addresses stored in flash.
+ *	But we do some sanity checks in case they are not present
+ *	first.
+ */
+void ks8695_getmac(unsigned char *dst, int index)
+{
+	unsigned char dm[] = { MAC_DEFAULT };
+	unsigned char *src, *mp, *ep;
+	int i;
+
+	/* Construct a default MAC address just in case */
+	dm[ETH_LENGTH_OF_ADDRESS-1] = index;
+	src = &dm[0];
+
+	ep = ioremap(0x02000000, 0x20000);
+	if (ep) {
+		/* Check if flash MAC is valid */
+		mp = ep + MAC_OFFSET + (index * ETH_LENGTH_OF_ADDRESS);
+		for (i = 0; (i < ETH_LENGTH_OF_ADDRESS); i++) {
+			if ((mp[i] != 0) && (mp[i] != 0xff)) {
+				src = mp;
+				break;
+			}
+		}
+	}
+
+	memcpy(dst, src, ETH_LENGTH_OF_ADDRESS);
+
+	if (ep)
+		iounmap(ep);
+}
+#else
+void ks8695_getmac(unsigned char *dst, int index)
+{
+	static char *macs[] = {
+		0x00, 0x10, 0xa1, 0x00, 0x10, 0x01,
+	};
+	memcpy(dst, macs[index], ETH_LENGTH_OF_ADDRESS);
+	macs[ETH_LENGTH_OF_ADDRESS-1]++;
+}
+#endif
+
+/*
+ * ks8695_init_module
+ *	This function is the first routine called when the driver is loaded.
+ *
+ * Argument(s)
+ *	NONE.
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+int ks8695_init_module(void)
+{
+	int	nRet;
+
+	/* Print the driver ID string and copyright notice */
+	DRV_INFO(" %s, version %s,  %s", 
+		ks8695_driver_string, ks8695_driver_version, ks8695_copyright);
+
+#ifdef	DEBUG_THIS
+	DRV_INFO(" IO Address=0x%x", IO_ADDRESS(KS8695_IO_BASE));
+#endif
+
+	nRet = ks8695_module_probe();
+
+	return nRet;
+}
+
+module_init(ks8695_init_module);
+
+/*
+ * ks8695_exit_module
+ *	This function is called just before the driver is removed from memory.
+ *
+ * Argument(s)
+ *	NONE.
+ *
+ * Return(s)
+ *	NONE.
+ */
+void ks8695_exit_module(void)
+{
+#ifdef	DEBUG_THIS
+#ifdef MODULE
+	DRV_INFO("%s: pci_dev_index=%d", __FUNCTION__, pci_dev_index);
+#else
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+#endif
+
+	{	
+		int i;
+
+#ifdef	__KS8695_CACHE_H
+		if (ICacheLockdown)
+			ks8695_icache_unlock();
+#endif
+		for (i = pci_dev_index; i > 0; i--) {
+			ks8695_remove(&pci_dev_mimic[i - 1]);
+		}
+		pci_dev_index = 0;
+	}
+}
+
+module_exit(ks8695_exit_module);
+
+/*
+ * ks8695_probe
+ *	This function initializes an adapter identified by a pci_dev
+ *  structure. Note that KS8695 eval board doesn't have PCI bus at all,
+ *	but the driver uses that since it was derived from a PCI based driver
+ *	originally.
+ *
+ * Argument(s)
+ *  pdev	pointer to PCI device information struct
+ *  ent		pointer to PCI device ID structure (ks8695_pci_table)
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+int ks8695_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	struct net_device *netdev = NULL;
+	PADAPTER_STRUCT Adapter;
+	static int cards_found = 0;
+	int	nRet;
+
+	/* Register a new network interface and allocate private data
+	   structure (ADAPTER_STRUCT) */
+	netdev = init_etherdev(netdev, sizeof(ADAPTER_STRUCT));
+	if (NULL == netdev) {
+		DRV_ERR("init_etherdev failed");
+		return -ENOMEM;
+	}
+
+	Adapter = (PADAPTER_STRUCT) netdev->priv;
+	memset(Adapter, 0, sizeof(ADAPTER_STRUCT));
+	Adapter->netdev = netdev;
+	Adapter->pdev = pdev;
+
+	/* chain the ADAPTER_STRUCT into the list */
+	if (ks8695_adapter_list)
+		ks8695_adapter_list->prev = Adapter;
+	Adapter->next = ks8695_adapter_list;
+	ks8695_adapter_list = Adapter;
+
+	/* simply tell the network interface we are using this irq, but the driver
+	   use more for each DMA, look for /proc/interrupts for details */
+	netdev->irq = pdev->irq;
+
+	Adapter->stDMAInfo.nBaseAddr = IO_ADDRESS(KS8695_IO_BASE);
+	netdev->mem_start = IO_ADDRESS(KS8695_IO_BASE);
+	netdev->mem_end = netdev->mem_start + 0xffff;
+
+/* #ifdef	DEBUG_THIS */
+	DRV_INFO("VA = 0x%08x, PA=0x%08x", Adapter->stDMAInfo.nBaseAddr, KS8695_IO_BASE);
+/* #endif */
+
+	/* set up function pointers to driver entry points */
+	netdev->open               = &ks8695_open;
+	netdev->stop               = &ks8695_close;
+	netdev->hard_start_xmit    = &ks8695_xmit_frame;
+	netdev->get_stats          = &ks8695_get_stats;
+	netdev->set_multicast_list = &ks8695_set_multi;
+	netdev->set_mac_address    = &ks8695_set_mac;
+	netdev->change_mtu         = &ks8695_change_mtu;
+	netdev->do_ioctl           = &ks8695_ioctl;
+	if (DI.bTxChecksum) 
+		netdev->features   |= NETIF_F_HW_CSUM;
+
+#ifdef	CONFIG_ARCH_KS8695P
+	Adapter->rev = (KS8695_READ_REG(KS8695_REVISION_ID) >> 0x4) & 0xf;
+#else
+#ifdef	KS8695X
+	Adapter->rev = (KS8695_READ_REG(KS8695_REVISION_ID) >> 0x4) & 0xf;
+#else
+	Adapter->rev = 0;
+#endif	/*KS8695X*/
+#endif
+
+	/* the card will tell which driver it will be */
+	Adapter->bd_number = cards_found;
+
+	if (WANPORT == cards_found) {
+		/* for WAN */
+		DI.usDMAId = DMA_WAN;
+		DI.nOffset = DMA_WAN;
+		DI.uIntMask = INT_WAN_MASK;
+		DI.uLinkIntMask = INT_WAN_LINK;
+
+#ifndef	USE_RX_UNAVAIL
+		/* clear Rx buf unavail bit */
+		DI.uIntMask &= ~BIT(27);
+#endif
+
+#ifndef	USE_TX_UNAVAIL
+		/* clear Tx buf unavail bit */
+		DI.uIntMask &= ~BIT(28);
+#endif
+		/* DMA's stop bit is a little bit different compared with KS9020, so disable them first */
+		DI.uIntMask &= ~BIT(26);	
+		DI.uIntMask &= ~BIT(25);
+		DI.uIntShift = 25;
+
+		/* set default mac address for WAN */
+		ks8695_getmac(DI.stMacStation, cards_found);
+
+	} else if (LANPORT == cards_found) {
+		/* for LAN */
+		DI.usDMAId = DMA_LAN;
+		DI.nOffset = DMA_LAN;
+		DI.uIntMask = INT_LAN_MASK;
+
+#ifndef	USE_RX_UNAVAIL
+		/* clear Rx buf unavail bit */
+		DI.uIntMask &= ~BIT(14);
+#endif
+
+#ifndef	USE_TX_UNAVAIL
+		/* clear Tx buf unavail bit */
+		DI.uIntMask &= ~BIT(15);
+#endif
+		DI.uIntMask &= ~BIT(13);	
+		DI.uIntMask &= ~BIT(12);
+		DI.uIntShift = 12;
+
+		ks8695_getmac(DI.stMacStation, cards_found);
+
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	} else if (HPNAPORT == cards_found) {
+		/* for HPNA */
+		DI.usDMAId = DMA_HPNA;
+		DI.nOffset = DMA_HPNA;
+		DI.uIntMask = INT_HPNA_MASK;
+#ifdef	RX_TASK
+		/* clear Rx buf unavail bit */
+		DI.uIntMask &= ~BIT(20);
+#endif
+#ifndef	USE_TX_UNAVAIL
+		/* clear Tx buf unavail bit */
+		/* if use Tx coalescing, don't disable Tx Complete bit */
+		DI.uIntMask &= ~BIT(21);
+#else
+		/* clear Tx Completed bit */
+		DI.uIntMask &= ~BIT(23);
+#endif
+		DI.uIntMask &= ~BIT(19);	
+		DI.uIntMask &= ~BIT(18);
+
+		DI.uIntShift = 18;
+		ks8695_getmac(DI.stMacStation, cards_found);
+#endif
+	} else {
+		DRV_ERR("%s: card id out of range (%d)", __FUNCTION__, cards_found);
+		return -ENODEV;
+	}
+
+	nRet = SoftwareInit(Adapter);
+	if (nRet) {
+		DRV_ERR("%s: SoftwareInit failed", __FUNCTION__);
+		ks8695_remove(pdev);
+		return nRet;
+	}
+	CheckConfigurations(Adapter);
+
+	/* reset spinlock */
+	DI.lock = SPIN_LOCK_UNLOCKED;
+	DI.lock_refill = SPIN_LOCK_UNLOCKED;
+
+	/* finally, we get around to setting up the hardware */
+	if (HardwareInit(Adapter) < 0) {
+		DRV_ERR("%s: HardwareInit failed", __FUNCTION__);
+		ks8695_remove(pdev);
+		return -ENODEV;
+	}
+	cards_found++;
+
+	/* set LED 0 for speed */
+	swSetLED(Adapter, FALSE, LED_SPEED);
+	/* set LED 1 for link/activities */
+	swSetLED(Adapter, TRUE, LED_LINK_ACTIVITY);
+
+	return 0;
+}
+
+/*
+ * ks8695_remove
+ *	This function is called by the PCI subsystem to alert the driver
+ *  that it should release a PCI device. It is called to clean up from
+ *  a failure in ks8695_probe.
+ *
+ * Argument(s)
+ *  pdev	pointer to PCI device information struct
+ *
+ * Return(s)
+ *	NONE.
+ */
+void ks8695_remove(struct pci_dev *pdev)
+{
+	struct net_device *netdev;
+	PADAPTER_STRUCT Adapter;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	/* find the Adapter struct that matches this PCI device */
+	for (Adapter = ks8695_adapter_list; Adapter != NULL; Adapter = Adapter->next) {
+		if (Adapter->pdev == pdev)
+			break;
+	}
+	/* if no match is found */
+	if (Adapter == NULL)
+		return;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s: match found, bd_num = %d", __FUNCTION__, Adapter->bd_number);
+#endif
+
+	netdev = Adapter->netdev;
+
+	if (test_bit(KS8695_BOARD_OPEN, &Adapter->flags))
+		ks8695_close(netdev);
+
+	/* remove from the adapter list */
+	if (ks8695_adapter_list == Adapter)
+		ks8695_adapter_list = Adapter->next;
+	if (Adapter->next != NULL)
+		Adapter->next->prev = Adapter->prev;
+	if (Adapter->prev != NULL)
+		Adapter->prev->next = Adapter->next;
+
+	/* free the net_device _and_ ADAPTER_STRUCT memory */
+	unregister_netdev(netdev);
+	kfree(netdev);
+}
+
+/*
+ * CheckConfigurations
+ *	This function checks all command line paramters for valid user
+ *  input. If an invalid value is given, or if no user specified
+ *  value exists, a default value is used.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *
+ * Return(s)
+ *	NONE.
+ */
+static void CheckConfigurations(PADAPTER_STRUCT Adapter)
+{
+	int board = Adapter->bd_number, i;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s (board number = %d)", __FUNCTION__, board);
+#endif
+
+	/* Transmit Descriptor Count */
+	if (TxDescriptors[board] == OPTION_UNSET) {
+		DI.nTxDescTotal = TXDESC_DEFAULT;	/* 256 | 128 | 64(d) */
+	} else if ((TxDescriptors[board] > TXDESC_MAX) &&
+			   (TxDescriptors[board] < TXDESC_MIN)) {
+		DRV_WARN("Invalid TxDescriptor specified (%d), using default %d",
+			   TxDescriptors[board], TXDESC_DEFAULT);
+		DI.nTxDescTotal = TXDESC_DEFAULT;
+	} else {
+		DRV_INFO("User specified TxDescriptors %d is used", TxDescriptors[board]);
+		DI.nTxDescTotal = TxDescriptors[board];
+	}
+	/* Tx coalescing, currently can only be used if buffer unavailable bit is set */
+	DI.nTransmitCoalescing = (DI.nTxDescTotal >> 3);
+
+	/* Receive Descriptor Count */
+	if (RxDescriptors[board] == OPTION_UNSET) {
+		DI.nRxDescTotal = RXDESC_DEFAULT;		/* 256(d) | 128 | 64 */
+	} else if ((RxDescriptors[board] > RXDESC_MAX) ||
+			   (RxDescriptors[board] < RXDESC_MIN)) {
+		DRV_WARN("Invalid RxDescriptor specified (%d), using default %d",
+			   RxDescriptors[board], RXDESC_DEFAULT);
+	} else {
+		DRV_INFO("User specified RxDescriptors %d is used", RxDescriptors[board]);
+		DI.nRxDescTotal = RxDescriptors[board];
+	}
+
+	/* Receive Checksum Offload Enable */
+	if (RxChecksum[board] == OPTION_UNSET) {
+		DI.bRxChecksum = RXCHECKSUM_DEFAULT;		/* enabled */
+	} else if ((RxChecksum[board] != OPTION_ENABLED) && (RxChecksum[board] != OPTION_DISABLED)) {
+		DRV_INFO("Invalid RxChecksum specified (%i), using default of %i",
+			RxChecksum[board], RXCHECKSUM_DEFAULT);
+		DI.bRxChecksum = RXCHECKSUM_DEFAULT;
+	} else {
+		DRV_INFO("Receive Checksum Offload %s",
+			RxChecksum[board] == OPTION_ENABLED ? "Enabled" : "Disabled");
+		DI.bRxChecksum = RxChecksum[board];
+	}
+
+	/* Transmit Checksum Offload Enable configuration */
+	if (OPTION_UNSET == TxChecksum[board]) {
+		DI.bTxChecksum = TXCHECKSUM_DEFAULT;		/* disabled */
+	} else if ((OPTION_ENABLED != TxChecksum[board]) && (OPTION_DISABLED != TxChecksum[board])) {
+		DRV_INFO("Invalid TxChecksum specified (%i), using default of %i",
+			TxChecksum[board], TXCHECKSUM_DEFAULT);
+		DI.bTxChecksum = TXCHECKSUM_DEFAULT;
+	} else {
+		DRV_INFO("Transmit Checksum Offload specified %s",
+			TxChecksum[board] == OPTION_ENABLED ? "Enabled" : "Disabled");
+		DI.bTxChecksum = TxChecksum[board];
+	}
+
+	/* Flow Control */
+	if (FlowControl[board] == OPTION_UNSET) {
+		DI.bRxFlowCtrl = FLOWCONTROL_DEFAULT;		/* enabled */
+	} else if ((OPTION_ENABLED != FlowControl[board]) && (OPTION_DISABLED != FlowControl[board])) {
+		DRV_INFO("Invalid FlowControl specified (%i), using default %i",
+			   FlowControl[board], FLOWCONTROL_DEFAULT);
+		DI.bRxFlowCtrl = FLOWCONTROL_DEFAULT;
+	} else {
+		DRV_INFO("Flow Control %s", FlowControl[board] == OPTION_ENABLED ?
+			"Enabled" : "Disabled");
+		DI.bRxFlowCtrl = FlowControl[board];
+	}
+	/* currently Tx control flow shares the setting of Rx control flow */
+	DI.bTxFlowCtrl = DI.bRxFlowCtrl;
+
+	/* Perform PHY PowerDown Reset instead of soft reset, the Option function can 
+	   be overwritten by user later */
+	DI.bPowerDownReset = TRUE;
+
+	/* Programmable Burst Length */
+	if (OPTION_UNSET == TxPBL[board]) {
+		DI.byTxPBL = PBL_DEFAULT;		/* FIFO size */
+	} else if ((0 != TxPBL[board]) && (1 != TxPBL[board]) && (2 != TxPBL[board]) && (4 != TxPBL[board]) &&
+		(8 != TxPBL[board]) && (16 != TxPBL[board]) && (32 != TxPBL[board])) {
+		DRV_INFO("Invalid TX Programmable Burst Length specified (%i), using default of %i",
+			TxPBL[board], PBL_DEFAULT);
+		DI.byTxPBL = PBL_DEFAULT;
+	} else {
+		DRV_INFO("Programmable Burst Length specified %d bytes", TxPBL[board]);
+		DI.byTxPBL = TxPBL[board];
+	}
+
+	if (OPTION_UNSET == RxPBL[board]) {
+		DI.byRxPBL = PBL_DEFAULT;		/* FIFO size */
+	} else if ((0 != TxPBL[board]) && (1 != RxPBL[board]) && (2 != RxPBL[board]) && (4 != RxPBL[board]) &&
+		(8 != RxPBL[board]) && (16 != RxPBL[board]) && (32 != RxPBL[board])) {
+		DRV_INFO("Invalid TX Programmable Burst Length specified (%i), using default of %i",
+			RxPBL[board], PBL_DEFAULT);
+		DI.byRxPBL = PBL_DEFAULT;
+	} else {
+		DRV_INFO("Programmable Burst Length specified %d bytes", RxPBL[board]);
+		DI.byRxPBL = RxPBL[board];
+	}
+
+	/* User speed and/or duplex options */
+	if (Duplex[board] == OPTION_UNSET && Speed[board] == OPTION_UNSET) {
+		DI.usCType[0] = SW_PHY_DEFAULT;
+	}
+	else {
+		switch (Speed[board]) {
+			case 10:
+				if (Duplex[board])
+					DI.usCType[0] = SW_PHY_10BASE_T_FD;		/* 10Base-TX Full Duplex */
+				else {
+					/* don't advertise flow control in half duplex case */
+					if (DMA_WAN == DI.usDMAId) {
+						DI.bRxFlowCtrl = FALSE;
+						DI.bTxFlowCtrl = FALSE;
+					}
+					DI.usCType[0] = SW_PHY_10BASE_T;		/* 10Base-T Half Duplex */
+				}
+				break;
+
+			case 100:
+			default:
+				if (Duplex[board])
+					DI.usCType[0] = SW_PHY_100BASE_TX_FD;	/* 100Base-TX Full Duplex */
+				else {
+					/* don't advertise flow control in half duplex case */
+					if (DMA_WAN == DI.usDMAId) {
+						DI.bRxFlowCtrl = FALSE;
+						DI.bTxFlowCtrl = FALSE;
+					}
+					DI.usCType[0] = SW_PHY_100BASE_TX;		/* 100Base-TX Half Duplex */
+				}
+				break;
+		}
+	}
+
+	if (DMA_LAN == DI.usDMAId) {
+		/*TEMP, currently assume all other ports share same configuration with
+		  first one, will add more options for LAN ports later */
+		for (i = 1; i < SW_MAX_LAN_PORTS; i++) {
+			DI.usCType[i] = DI.usCType[0];
+		}
+
+		/* initialize some variables which do not have user configurable options */
+		for (i = 0; i <= SW_MAX_LAN_PORTS; i++) {
+			DPI[i].byCrossTalkMask = 0x1f;
+			DPI[i].bySpanningTree = SW_SPANNINGTREE_ALL;
+			DPI[i].byDisableSpanningTreeLearn = FALSE;
+		}
+
+		/* set default as direct mode for port 5, so no lookup table is checking */
+		DI.bRxDirectMode = FALSE;
+		DI.bTxRreTagMode = FALSE;
+
+		DI.bPort5FlowCtrl = DI.bRxFlowCtrl;
+		DI.bPortsFlowCtrl = DI.bRxFlowCtrl;
+	}
+}
+
+/*
+ * SoftwareInit
+ *	This function initializes the Adapter private data structure.
+ *
+ * Argument(s)
+ *  Adapter	pointer to ADAPTER_STRUCT structure
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+static int SoftwareInit(PADAPTER_STRUCT Adapter)
+{
+	struct net_device *netdev = Adapter->netdev;
+
+	/* Initial Receive Buffer Length */
+	if ((netdev->mtu + ENET_HEADER_SIZE + ETH_CRC_LENGTH) <= BUFFER_1568) {
+		DI.uRxBufferLen = BUFFER_1568;	/* 0x620 */
+	}
+	else {
+		DI.uRxBufferLen = BUFFER_2048;	/* 0x800 */
+	}
+
+	/* please update link status within watchdog routine */
+	DI.bLinkChanged[0] = TRUE;
+	if (DMA_LAN == DI.usDMAId) {	/* if LAN driver, 3 more ports */
+		DI.bLinkChanged[1] = TRUE;
+		DI.bLinkChanged[2] = TRUE;
+		DI.bLinkChanged[3] = TRUE;
+	}
+
+	return 0;
+}
+
+/*
+ * HardwareInit
+ *	This function initializes the hardware to a configuration as specified by the
+ *  Adapter structure, including mac I/F, switch engine, IRQ and others.
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT structure
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+static int HardwareInit(PADAPTER_STRUCT Adapter)
+{
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	/* note that chip reset should only take once 
+	   if three driver instances are used for WAN, LAN and HPNA respectively for KS8695
+	   For KS8695P only two driver instances are used (WAN and LAN) */
+	if (!ks8695_ChipInit(Adapter, TRUE)) {
+		DRV_ERR("Hardware Initialization Failed");
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * ks8695_open
+ *	This function is called when a network interface is made
+ *  active by the system (IFF_UP). At this point all resources needed
+ *  for transmit and receive operations are allocated, the interrupt
+ *  handler is registered with the OS, the watchdog timer is started,
+ *  and the stack is notified when the interface is ready.
+ *
+ * Argument(s)
+ *  netdev		pointer to net_device struct
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+int ks8695_open(struct net_device *netdev)
+{
+	PADAPTER_STRUCT Adapter = netdev->priv;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	/* prevent multiple opens on same driver instance */
+	if (test_and_set_bit(KS8695_BOARD_OPEN, &Adapter->flags)) {
+		return -EBUSY;
+	}
+#ifdef FAST_POLL
+	ks8695_poll_ready = 0;
+#endif
+
+	/* stop Tx/Rx and disable interrupt */
+	macStopAll(Adapter);
+	if (DMA_LAN == DI.usDMAId) {
+		swEnableSwitch(Adapter, FALSE);
+	}
+
+	if (HardwareInit(Adapter) < 0) {
+		clear_bit(KS8695_BOARD_OPEN, &Adapter->flags);
+		return -EBUSY;
+	}
+
+	/* allocate transmit descriptors */
+	if (AllocateTxDescriptors(Adapter) != 0) {
+		clear_bit(KS8695_BOARD_OPEN, &Adapter->flags);
+		return -ENOMEM;
+	}
+	/* set base address for Tx DMA */
+	KS8695_WRITE_REG(REG_TXBASE + DI.nOffset, cpu_to_le32(DI.TxDescDMA));
+	macStartTx(Adapter, TRUE);
+
+	/* allocate receive descriptors and buffers */
+	if (AllocateRxDescriptors(Adapter) != 0) {
+		FreeTxDescriptors(Adapter);
+		clear_bit(KS8695_BOARD_OPEN, &Adapter->flags);
+		return -ENOMEM;
+	}
+	/* set base address for Rx DMA */
+	KS8695_WRITE_REG(REG_RXBASE + DI.nOffset, cpu_to_le32(DI.RxDescDMA));
+	macStartRx(Adapter, TRUE);
+
+	/* hook the interrupt */
+	if (hook_irqs(netdev, TRUE)) {
+		DRV_ERR("%s: hook_irqs failed", __FUNCTION__);
+		clear_bit(KS8695_BOARD_OPEN, &Adapter->flags);
+		FreeTxDescriptors(Adapter);
+		FreeRxDescriptors(Adapter);
+		return -EBUSY;
+	}
+
+	/* fill Rx ring with sk_buffs */
+	ReceiveBufferFill((unsigned long)Adapter);
+
+#ifdef	RX_TASK
+	/* if use task based rx process, initialize it */
+	/* Initialize the tasklet again may crash the kernel. */
+	if ( DI.rx_tasklet.func == ReceiveProcessTask ) {
+		tasklet_enable( &DI.rx_tasklet );
+	}
+	else
+		tasklet_init(&DI.rx_tasklet, ReceiveProcessTask, (unsigned long)Adapter);
+#endif
+#ifdef	TX_TASK
+	/* if use task based tx process, initialize it */
+	/* Initialize the tasklet again may crash the kernel. */
+	if ( DI.tx_tasklet.func == TransmitProcessTask ) {
+		tasklet_enable( &DI.tx_tasklet );
+	}
+	else
+		tasklet_init(&DI.tx_tasklet, TransmitProcessTask, (unsigned long)Adapter);
+#endif
+
+	/* Set the watchdog timer for 2 seconds */
+	init_timer(&Adapter->timer_id);
+
+	Adapter->timer_id.function = &ks8695_watchdog;
+	Adapter->timer_id.data = (unsigned long) netdev;
+	mod_timer(&Adapter->timer_id, (jiffies + WATCHDOG_TICK * HZ));
+
+	/* stats accumulated while down are dropped
+	 * this does not clear the running total */
+	swResetSNMPInfo(Adapter);
+
+	if (DMA_LAN == DI.usDMAId) {
+		swEnableSwitch(Adapter, TRUE);
+	}
+	macEnableInterrupt(Adapter, TRUE);
+
+	/* clear tbusy bit */
+	netif_start_queue(netdev);
+
+	/* if defined as module */
+#ifdef MODULE
+	MOD_INC_USE_COUNT;
+#endif
+
+#ifdef FAST_POLL
+	ks8695_poll_ready++;
+#endif
+	return 0;
+}
+
+/*
+ * ks8695_close
+ *	This function is called when an interface is de-activated by the network 
+ *	module (IFF_DOWN).
+ *
+ * Argument(s)
+ *  netdev		pointer to net_device struct
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+int ks8695_close(struct net_device *netdev)
+{
+	PADAPTER_STRUCT Adapter = netdev->priv;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	if (!test_bit(KS8695_BOARD_OPEN, &Adapter->flags))
+		return 0;
+
+	/* stop all */
+	macStopAll(Adapter);
+	if (DMA_LAN == DI.usDMAId) {
+		swEnableSwitch(Adapter, FALSE);
+	}
+
+	netif_stop_queue(netdev);
+	hook_irqs(netdev, FALSE);
+	del_timer(&Adapter->timer_id);
+
+#ifdef	RX_TASK
+	tasklet_disable(&DI.rx_tasklet);
+	DI.rx_scheduled = FALSE;
+#endif
+#ifdef	TX_TASK
+	tasklet_disable(&DI.tx_tasklet);
+	DI.tx_scheduled = FALSE;
+#endif
+	FreeTxDescriptors(Adapter);
+	FreeRxDescriptors(Adapter);
+
+	/* if defined as module */
+#ifdef MODULE
+	MOD_DEC_USE_COUNT;
+#endif
+
+	clear_bit(KS8695_BOARD_OPEN, &Adapter->flags);
+
+	return 0;
+}
+
+/*
+ * InitTxRing
+ *	This function is used to initialize Tx descriptor ring.
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT struct
+ *
+ * Return(s)
+ *	NONE
+ */
+void InitTxRing(PADAPTER_STRUCT Adapter)
+{
+	int i;
+	TXDESC	*pTxDesc = DI.pTxDescriptors;
+	UINT32	uPA = DI.TxDescDMA;
+
+	for (i = 0; i < DI.nTxDescTotal - 1; i++, pTxDesc++) {
+		uPA += sizeof(TXDESC);		/* pointer to next Tx Descriptor */
+		pTxDesc->TxDMANextPtr = cpu_to_le32(uPA);
+	}
+	/* last descriptor should point back to the beginning */
+	pTxDesc->TxDMANextPtr = cpu_to_le32(DI.TxDescDMA);
+	pTxDesc->TxFrameControl |= cpu_to_le32(TFC_TER);
+}
+
+/*
+ * AllocateTxDescriptors
+ *	This function is used to allocate Tx descriptors, including allocate memory,
+ *	alignment adjustment, variable initialization and so on.
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT struct
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+static int AllocateTxDescriptors(PADAPTER_STRUCT Adapter)
+{
+	int size;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	/* allocate data buffers for transmission */
+	size = sizeof(struct ks8695_buffer) * DI.nTxDescTotal;
+	DI.pTxSkb = kmalloc(size, GFP_KERNEL);
+	if (DI.pTxSkb == NULL) {
+		return -ENOMEM;
+	}
+	memset(DI.pTxSkb, 0, size);
+
+	/* round up to nearest 4K */
+	size = KS8695_ROUNDUP(DI.nTxDescTotal * sizeof(TXDESC) + DESC_ALIGNMENT, BUFFER_4K);
+	DI.pTxDescriptors = consistent_alloc_ex(GFP_KERNEL | GFP_DMA, size, &DI.TxDescDMA);
+	if (NULL == DI.pTxDescriptors) {
+		kfree(DI.pTxSkb);
+		DI.pTxSkb = NULL;
+		return -ENOMEM;
+	}
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("TXDESC> DataBuf=0x%08x, Descriptor=0x%08x, PA=0x%08x", (UINT)DI.pTxSkb, (UINT)DI.pTxDescriptors, (UINT)DI.TxDescDMA);
+#endif
+	memset(DI.pTxDescriptors, 0, size);
+
+	atomic_set(&DI.nTxDescAvail, DI.nTxDescTotal);
+	DI.nTxDescNextAvail = 0;
+	DI.nTxDescUsed = 0;
+	DI.nTransmitCount = 0;
+	DI.nTxProcessedCount = 0;
+	DI.bTxNoResource = 0;
+
+	InitTxRing(Adapter);
+
+    return 0;
+}
+
+/*
+ * InitRxRing
+ *	This function is used to initialize Rx descriptor ring.
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT struct
+ *
+ * Return(s)
+ *	NONE
+ */
+void InitRxRing(PADAPTER_STRUCT Adapter)
+{
+	int i;
+	RXDESC	*pRxDesc = DI.pRxDescriptors;
+	UINT32	uPA = DI.RxDescDMA;
+
+	for (i = 0; i < DI.nRxDescTotal - 1; i++, pRxDesc++) {
+		uPA += sizeof(RXDESC);		/* pointer to next Rx Descriptor */
+		pRxDesc->RxDMANextPtr = cpu_to_le32(uPA);
+	}
+	/* last descriptor should point back to the beginning */
+	pRxDesc->RxDMANextPtr = cpu_to_le32(DI.RxDescDMA);
+	pRxDesc->RxDMAFragLen &= cpu_to_le32(~RFC_RBS_MASK);
+}
+
+/*
+ * AllocateRxDescriptors
+ *	This function is used to setup Rx descriptors, including allocate memory, receive SKBs
+ *	alignment adjustment, variable initialization and so on.
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT struct
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+static int AllocateRxDescriptors(PADAPTER_STRUCT Adapter)
+{
+	int size;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	size = sizeof(struct ks8695_buffer) * DI.nRxDescTotal;
+	DI.pRxSkb = kmalloc(size, GFP_KERNEL);
+	if (DI.pRxSkb == NULL) {
+		return -ENOMEM;
+	}
+	memset(DI.pRxSkb, 0, size);
+
+	/* Round up to nearest 4K */
+	size = KS8695_ROUNDUP(DI.nRxDescTotal * sizeof(RXDESC) + DESC_ALIGNMENT, BUFFER_4K);
+	DI.pRxDescriptors = consistent_alloc_ex(GFP_KERNEL | GFP_DMA, size, &DI.RxDescDMA);
+	if (NULL == DI.pRxDescriptors) {
+		kfree(DI.pRxSkb);
+		DI.pRxSkb = NULL;
+		return -ENOMEM;
+	}
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("RXDESC> DataBuf=0x%08x, Descriptor=0x%08x, PA=0x%08x", 
+			(UINT)DI.pRxSkb, (UINT)DI.pRxDescriptors, (UINT)DI.RxDescDMA);
+#endif
+
+	memset(DI.pRxDescriptors, 0, size);
+
+	DI.nRxDescNextAvail = 0;
+	atomic_set(&DI.RxDescEmpty, DI.nRxDescTotal);
+	DI.nRxDescNextToFill = 0;
+
+	InitRxRing(Adapter);
+
+	return 0;
+}
+
+/*
+ * FreeTxDescriptors
+ *	This function is used to free Tx resources.
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT struct
+ *
+ * Return(s)
+ *	NONE.
+ */
+static void FreeTxDescriptors(PADAPTER_STRUCT Adapter)
+{
+	int size;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	CleanTxRing(Adapter);
+
+	kfree(DI.pTxSkb);
+	DI.pTxSkb = NULL;
+
+	size = KS8695_ROUNDUP(DI.nTxDescTotal * sizeof(TXDESC) + DESC_ALIGNMENT, BUFFER_4K);
+	consistent_free_ex((void *)DI.pTxDescriptors, size, DI.TxDescDMA);
+	DI.pTxDescriptors = NULL;
+	DI.TxDescDMA = 0;
+}
+
+/*
+ * CleanTxRing
+ *	This function is used to go through Tx descriptor list and clean up any pending resources.
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT struct
+ *
+ * Return(s)
+ *	NONE.
+ */
+static void CleanTxRing(PADAPTER_STRUCT Adapter)
+{
+	unsigned long size;
+	TXDESC	*pTxDesc = DI.pTxDescriptors;
+	int i;
+
+	/* free pending sk_buffs if any */
+	for (i = 0; i < DI.nTxDescTotal; i++, pTxDesc++) {
+		if (NULL != DI.pTxSkb[i].skb) {
+			dev_kfree_skb(DI.pTxSkb[i].skb);
+			DI.pTxSkb[i].skb = NULL;
+
+			/* reset corresponding Tx Descriptor structure as well */
+			pTxDesc->TxDMAFragAddr = 0;
+			pTxDesc->TxOwnBit = 0;
+			pTxDesc->TxFrameControl = 0;
+		}
+	}
+	DI.nTransmitCount = 0;
+	DI.nTxProcessedCount = 0;
+
+	size = sizeof(struct ks8695_buffer) * DI.nTxDescTotal;
+	memset(DI.pTxSkb, 0, size);
+
+	size = KS8695_ROUNDUP(DI.nTxDescTotal * sizeof(TXDESC) + DESC_ALIGNMENT, BUFFER_4K);
+	memset(DI.pTxDescriptors, 0, size);
+	atomic_set(&DI.nTxDescAvail, DI.nTxDescTotal);
+	DI.nTxDescNextAvail = 0;
+	DI.nTxDescUsed = 0;
+
+	/* for safety!!! */
+	KS8695_WRITE_REG(REG_TXBASE + DI.nOffset, 0);
+}
+
+/*
+ * FreeRxDescriptors
+ *	This function is used to free Rx resources.
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT struct
+ *
+ * Return(s)
+ *	NONE.
+ */
+static void FreeRxDescriptors(PADAPTER_STRUCT Adapter)
+{
+	int size;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+#if 0
+#ifdef	RX_TASK
+	tasklet_disable(&DI.rx_tasklet);
+	DI.rx_scheduled = FALSE;
+#endif
+#ifdef	TX_TASK
+	tasklet_disable(&DI.tx_tasklet);
+	DI.tx_scheduled = FALSE;
+#endif
+#endif
+
+	CleanRxRing(Adapter);
+
+	kfree(DI.pRxSkb);
+	DI.pRxSkb = NULL;
+
+	size = KS8695_ROUNDUP(DI.nRxDescTotal * sizeof(RXDESC) + DESC_ALIGNMENT, BUFFER_4K);
+	consistent_free_ex((void *)DI.pRxDescriptors, size, DI.RxDescDMA);
+	DI.pRxDescriptors = NULL;
+	DI.RxDescDMA = 0;
+}
+
+/*
+ * CleanRxRing
+ *	This function is used to go through Rx descriptor list and clean up any pending resources.
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT struct
+ *
+ * Return(s)
+ *	NONE.
+ */
+static void CleanRxRing(PADAPTER_STRUCT Adapter)
+{
+	unsigned long size;
+	RXDESC	*pRxDesc = DI.pRxDescriptors;
+	int i;
+
+	/* Free pending sk_buffs if any */
+	for (i = 0; i < DI.nRxDescTotal; i++, pRxDesc++) {
+		if (DI.pRxSkb[i].skb != NULL) {
+			dev_kfree_skb(DI.pRxSkb[i].skb);
+			DI.pRxSkb[i].skb = NULL;
+
+			/* reset corresponding Rx Descriptor structure as well */
+			pRxDesc->RxFrameControl &= cpu_to_le32(~(RFC_FRAMECTRL_MASK | DESC_OWN_BIT));
+			pRxDesc->RxDMAFragLen = 0;
+			pRxDesc->RxDMAFragAddr = 0;
+		}
+	}
+
+	size = sizeof(struct ks8695_buffer) * DI.nRxDescTotal;
+	memset(DI.pRxSkb, 0, size);
+
+	size = KS8695_ROUNDUP(DI.nRxDescTotal * sizeof(RXDESC) + DESC_ALIGNMENT, BUFFER_4K);
+	memset(DI.pRxDescriptors, 0, size);
+	atomic_set(&DI.RxDescEmpty, DI.nRxDescTotal);
+	DI.nRxDescNextAvail = 0;
+	DI.nRxDescNextToFill = 0;
+
+	/* for safety!!! */
+	KS8695_WRITE_REG(REG_RXBASE + DI.nOffset, 0);
+}
+
+/*
+ * ks8695_set_multi
+ *	This function is used to set Multicast and Promiscuous mode. It is 
+ *	called whenever the multicast address list or the network interface
+ *	flags are updated. This routine is resposible for configuring the 
+ *	hardware for proper multicast, promiscuous mode, and all-multi behavior.
+ *
+ * Argument(s)
+ *  Adapter		pointer to ADAPTER_STRUCT struct
+ *
+ * Return(s)
+ *	NONE.
+ */
+void ks8695_set_multi(struct net_device *netdev)
+{
+	PADAPTER_STRUCT Adapter = netdev->priv;
+	uint32_t uReg;
+#if	0
+	uint32_t HwLowAddress, HwHighAddress;
+	uint16_t HashValue, HashReg, HashBit;
+	struct dev_mc_list *mc_ptr;
+#endif
+
+	BOOLEAN	bRxStarted;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	bRxStarted = DI.bRxStarted;
+	if (bRxStarted)
+		macStartRx(Adapter, FALSE);
+
+	/* read RX mode register in order to set hardware filter mode */
+	uReg = KS8695_READ_REG(REG_RXCTRL + DI.nOffset);
+	uReg |= DMA_UNICAST | DMA_BROADCAST;
+	uReg &= ~(DMA_PROMISCUOUS | DMA_MULTICAST);
+
+	if (netdev->flags & IFF_PROMISC) {
+		uReg |= DMA_PROMISCUOUS;
+	}
+	if (netdev->flags & (IFF_ALLMULTI | IFF_MULTICAST)) {
+		uReg |= DMA_MULTICAST;
+	}
+
+	KS8695_WRITE_REG(REG_RXCTRL + DI.nOffset, uReg);
+
+	if (bRxStarted)
+		macStartRx(Adapter, TRUE);
+
+	ks8695_relink(Adapter);
+}
+
+/*
+ * ks8695_watchdog
+ *	This function is a timer callback routine for updating statistics infomration.
+ *
+ * Argument(s)
+ *  data		pointer to net_device struct
+ *
+ * Return(s)
+ *	NONE.
+ */
+void ks8695_watchdog(unsigned long data)
+{
+	struct net_device *netdev = (struct net_device *)data;
+	PADAPTER_STRUCT Adapter = netdev->priv;
+	int	carrier;
+
+	if (DMA_LAN == DI.usDMAId) {
+		static int	nCheck = 0;
+
+		if (nCheck++ > 6) {
+			int	i;
+			uint8_t	bLinkActive[SW_MAX_LAN_PORTS];
+
+			nCheck = 0;
+			for (i = 0; i < SW_MAX_LAN_PORTS; i++) {
+				/* keep a track for previous link active state */
+				bLinkActive[i] = DI.bLinkActive[i];
+
+				carrier = swGetPhyStatus(Adapter, i);
+				/* if current link state is not same as previous state, means link state changed */
+				if (bLinkActive[i] != DI.bLinkActive[i]) {
+					DI.bLinkChanged[i] = TRUE;
+					ks8695_report_carrier(netdev, carrier);
+				}
+				/* note that since LAN doesn't have Interrupt bit for link status change */
+				/* we have to check it to make sure if link is lost, restart it!!! */
+				if (!DI.bLinkActive[i]) {
+					swDetectPhyConnection(Adapter, i);
+				}
+			}
+		}
+	}
+	else {
+		if (!DI.bLinkActive[0]) {
+			carrier = swGetPhyStatus(Adapter, 0);
+			ks8695_report_carrier(netdev, carrier);
+		}
+#ifndef	TX_TASK
+		/* handling WAN DMA sucked case if any */
+		/*if (DMA_WAN == DI.usDMAId) {*/
+		{	/* all driver ? */
+			static int	nCount = 0;
+
+			/* if no tx resource is reported */
+			if (DI.bTxNoResource) {
+				nCount++;
+				/* if happened 5 times (WATCHDOG_TICK seconds * 5), means most likely, the WAN Tx DMA is died,
+				   reset it again */
+				if (nCount > 5) {
+					DI.nResetCount++;
+					ResetDma(Adapter);
+					DI.bTxNoResource = FALSE;
+					/* wake queue will call mark_bh(NET_BH) to resume tx */
+					netif_wake_queue(netdev);
+					nCount = 0;
+				}
+			}
+		}
+#endif
+	}
+	UpdateStatsCounters(Adapter);
+
+	/* Reset the timer */
+	mod_timer(&Adapter->timer_id, jiffies + WATCHDOG_TICK * HZ);
+}
+
+/*
+ * ks8695_xmit_frame
+ *	This function is used to called by the stack to initiate a transmit.
+ *  The out of resource condition is checked after each successful Tx
+ *  so that the stack can be notified, preventing the driver from
+ *  ever needing to drop a frame.  The atomic operations on
+ *  nTxDescAvail are used to syncronize with the transmit
+ *  interrupt processing code without the need for a spinlock.
+ *
+ * Argument(s)
+ *  skb			buffer with frame data to transmit
+ *  netdev		pointer to network interface device structure
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+int ks8695_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+	PADAPTER_STRUCT Adapter = netdev->priv;
+	TXDESC *pTxDesc;
+	int i, len;
+	char *data;
+	unsigned long flags;
+
+#if 1
+	struct sk_buff* org_skb = skb;
+
+	/* Hardware has problem sending out short frames in which the first
+	 * 4 bytes of MAC destination address are replaced with data at
+	 * location 0x28 after sending out ICMP packets.
+	 */
+	if ( skb->len <= 48 ) {
+		skb = dev_alloc_skb( 50 );
+		if ( !skb ) {
+			Adapter->net_stats.tx_aborted_errors++;
+			return 1;
+		}
+		memcpy( skb->data, org_skb->data, org_skb->len );
+		memset( &skb->data[ org_skb->len ], 0, 50 - org_skb->len );
+		skb->len = 50;
+		dev_kfree_skb( org_skb );
+	}
+#endif
+	len = skb->len;
+	data = skb->data;
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s> len=%d", __FUNCTION__, len); 
+#endif
+
+
+	i = DI.nTxDescNextAvail;
+	pTxDesc = &DI.pTxDescriptors[i];
+
+	DI.pTxSkb[i].skb = skb;
+	DI.pTxSkb[i].length = len;
+	DI.pTxSkb[i].direction = PCI_DMA_TODEVICE;
+	consistent_sync(data, DI.uRxBufferLen, PCI_DMA_TODEVICE);
+	DI.pTxSkb[i].dma = virt_to_phys(data);
+
+	/* set DMA buffer address */
+	pTxDesc->TxDMAFragAddr = cpu_to_le32(DI.pTxSkb[i].dma);
+
+#ifdef	PACKET_DUMP
+	ks8695_dump_packet(Adapter, data, len, DI.uDebugDumpTxPkt);
+#endif
+
+
+#if	0
+	if (DMA_LAN == DI.usDMAId) {
+		/* may need to set SPN for IGCP for LAN driver, but do it later; */
+	}
+#endif
+
+	__save_flags_cli(flags);
+	/* note that since we have set the last Tx descriptor back to the first to form */
+	/* a ring, there is no need to keep ring end flag for performance sake */
+	/* clear some bits operation for optimization!!! */
+#ifndef	USE_TX_UNAVAIL
+	pTxDesc->TxFrameControl = cpu_to_le32((TFC_FS | TFC_LS | TFC_IC) | (len & TFC_TBS_MASK));
+#else
+	if ((DI.nTransmitCount + 1) % DI.nTransmitCoalescing) {
+		pTxDesc->TxFrameControl = cpu_to_le32((TFC_FS | TFC_LS) | (len & TFC_TBS_MASK));
+	}
+	else {
+		pTxDesc->TxFrameControl = cpu_to_le32((TFC_FS | TFC_LS | TFC_IC) | (len & TFC_TBS_MASK));
+	}
+#endif
+
+	/* set own bit */
+	pTxDesc->TxOwnBit = cpu_to_le32(DESC_OWN_BIT);
+
+	/* eanble read transfer for the packet!!! */
+	KS8695_WRITE_REG(REG_TXSTART + DI.nOffset, 1);
+
+	/*atomic_dec(&DI.nTxDescAvail);*/
+	/*__save_flags_cli(flags);*/
+	DI.nTxDescAvail.counter--;
+	/* update pending transimt packet count */
+	DI.nTransmitCount++;
+	__restore_flags(flags);
+	if (atomic_read(&DI.nTxDescAvail) <= 1) {
+#ifdef	DEBUG_THIS
+		if (DMA_WAN == DI.usDMAId)
+			DRV_WARN("%s> no WAN tx descriptors available, tx suspended, nTransmitCount=%d", __FUNCTION__, DI.nTransmitCount);
+		else if (DMA_LAN == DI.usDMAId)
+			DRV_WARN("%s> no LAN tx descriptors available, tx suspended, nTransmitCount=%d", __FUNCTION__, DI.nTransmitCount);
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+		else
+			DRV_WARN("%s> no HPNA tx descriptors available, tx suspended, nTransmitCount=%d", __FUNCTION__, DI.nTransmitCount);
+#endif
+#endif
+		DI.bTxNoResource = TRUE;
+		netif_stop_queue(netdev);
+#ifdef	TX_TASK
+		/* try eanble read transfer again */
+		KS8695_WRITE_REG(REG_TXSTART + DI.nOffset, 1);
+		if (FALSE == DI.tx_scheduled) {
+			DI.tx_scheduled = TRUE;
+			tasklet_hi_schedule(&DI.tx_tasklet);
+		}
+#endif
+	}
+
+	/* adv to next available descriptor */
+	DI.nTxDescNextAvail = ++DI.nTxDescNextAvail % DI.nTxDescTotal;
+	netdev->trans_start = jiffies;
+
+	return 0;
+}
+
+/*
+ * ks8695_get_stats
+ *	This function is used to get NIC's SNMP staticstics.
+ *
+ * Argument(s)
+ *  netdev		network interface device structure
+ *
+ * Return(s)
+ *	pointer to net_device_stats structure
+ */
+struct net_device_stats *ks8695_get_stats(struct net_device *netdev)
+{
+    PADAPTER_STRUCT Adapter = netdev->priv;
+
+#ifdef	DEBUG_THIS
+    DRV_INFO("ks8695_get_stats");
+#endif
+
+    return &Adapter->net_stats;
+}
+
+/*
+ * ks8695_change_mtu
+ *	This function is use to change the Maximum Transfer Unit.
+ *
+ * Argument(s)
+ *	netdev		pointer to net_device structure.
+ *	new_mtu		new_mtu new value for maximum frame size
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+int ks8695_change_mtu(struct net_device *netdev, int new_mtu)
+{
+	PADAPTER_STRUCT Adapter = netdev->priv;
+	uint32_t old_mtu = DI.uRxBufferLen;
+
+	DRV_INFO("%s", __FUNCTION__);
+
+	if (new_mtu <= DI.uRxBufferLen) {
+		netdev->mtu = new_mtu;
+		return 0;
+	}
+
+	if ((new_mtu < MINIMUM_ETHERNET_PACKET_SIZE - ENET_HEADER_SIZE) ||
+		new_mtu > BUFFER_2048 - ENET_HEADER_SIZE) {
+		DRV_ERR("%s> Invalid MTU setting", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	if (new_mtu <= BUFFER_1568 - ENET_HEADER_SIZE) {
+		DI.uRxBufferLen = BUFFER_1568;
+	} else {
+		DI.uRxBufferLen = BUFFER_2048;
+	}
+
+	if (old_mtu != DI.uRxBufferLen) {
+		/* put DEBUG_THIS after verification please */
+		DRV_INFO("%s, old=%d, new=%d", __FUNCTION__, old_mtu, DI.uRxBufferLen);
+		ResetDma(Adapter);
+	}
+
+	netdev->mtu = new_mtu;
+	ks8695_relink(Adapter);
+
+	return 0;
+}
+
+/*
+ * ks8695_set_mac
+ *	This function is use to change Ethernet Address of the NIC.
+ *
+ * Argument(s)
+ *	netdev		pointer to net_device structure.
+ *	p			pointer to sockaddr structure
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+int ks8695_set_mac(struct net_device *netdev, void *p)
+{
+	PADAPTER_STRUCT Adapter = netdev->priv;
+	struct sockaddr *addr = (struct sockaddr *)p;
+	BOOLEAN	bRxStarted, bTxStarted;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	bRxStarted = DI.bRxStarted;
+	bTxStarted = DI.bTxStarted;
+	if (bRxStarted)
+		macStartRx(Adapter, FALSE);
+	if (bTxStarted)
+		macStartTx(Adapter, FALSE);
+
+	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+	memcpy(DI.stMacCurrent, addr->sa_data, netdev->addr_len);
+	macSetStationAddress(Adapter, DI.stMacCurrent);
+
+	if (bRxStarted)
+		macStartRx(Adapter, TRUE);
+	if (bTxStarted)
+		macStartTx(Adapter, TRUE);
+
+	ks8695_relink(Adapter);
+
+	return 0;
+}
+
+/*
+ * UpdateStatsCounters
+ *	This function is used to update the board statistics counters.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure
+ *
+ * Return(s)
+ *	NONE
+ */
+static void UpdateStatsCounters(PADAPTER_STRUCT Adapter)
+{
+	struct net_device_stats *stats;
+	
+	stats= &Adapter->net_stats;
+}
+
+/*
+ * CheckState
+ *	This function is used to handle error conditions if any.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure
+ *	uISR		bit values of ISR register
+ *
+ * Return(s)
+ *	NONE.
+ */
+static __inline void CheckState(PADAPTER_STRUCT Adapter, UINT32 uISR)
+{
+	BOOLEAN	bTxStopped = FALSE, bRxStopped = FALSE;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s", __FUNCTION__);
+#endif
+
+	/* clear all bits other than stop */
+	uISR &= (DI.uIntMask & INT_DMA_STOP_MASK);
+	switch (DI.usDMAId) {
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	case DMA_HPNA:
+		if (uISR & INT_HPNA_TX_STOPPED)
+			bTxStopped = TRUE;
+		if (uISR & INT_HPNA_RX_STOPPED)
+			bRxStopped = TRUE;
+		break;
+#endif
+
+	case DMA_LAN:
+		if (uISR & INT_LAN_TX_STOPPED)
+			bTxStopped = TRUE;
+		if (uISR & INT_LAN_RX_STOPPED)
+			bRxStopped = TRUE;
+		break;
+
+	default:
+	case DMA_WAN:
+		if (uISR & INT_WAN_TX_STOPPED)
+			bTxStopped = TRUE;
+		if (uISR & INT_WAN_RX_STOPPED)
+			bRxStopped = TRUE;
+		break;
+	}
+
+	if (bRxStopped) {
+		/* if Rx started already, then it is a problem! */
+		if (DI.bRxStarted) {
+			DRV_WARN("%s> RX stopped, ISR=0x%08x", __FUNCTION__, uISR);
+
+			macStartRx(Adapter, FALSE);
+			DelayInMilliseconds(2);
+			macStartRx(Adapter, TRUE);
+		}
+		else {
+			/* ACK and clear the bit */
+			KS8695_WRITE_REG(KS8695_INT_STATUS, uISR);
+		}
+	}
+	if (bTxStopped) {
+		/* if Tx started already, then it is a problem! */
+		if (DI.bTxStarted) {
+			DRV_WARN("%s> TX stopped, ISR=0x%08x", __FUNCTION__, uISR);
+
+			macStartTx(Adapter, FALSE);
+			DelayInMilliseconds(2);
+			macStartTx(Adapter, TRUE);
+		}
+		else {
+			/* ACK and clear the bit */
+			KS8695_WRITE_REG(KS8695_INT_STATUS, uISR);
+		}
+	}
+}
+
+/*
+ * CheckLinkState
+ *	This function is used to check link status to see whether link has changed or not.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *	uISR		ISR register (should be IMSR) to check
+ *
+ * Return(s)
+ *	TRUE	if link change has detected
+ *	FALSE	otherwise
+ */
+static __inline BOOLEAN CheckLinkState(PADAPTER_STRUCT Adapter, UINT uISR)
+{
+	BOOLEAN	bLinkChanged = FALSE;
+	int	i;
+
+	switch (DI.usDMAId) {
+#if	!defined(CONFIG_ARCH_KS8695P) && !defined(KS8695X)
+	case DMA_HPNA:
+		/* what to do? */
+		return FALSE;
+#endif
+
+	case DMA_WAN:
+		if (uISR & INT_WAN_LINK) {
+			bLinkChanged = TRUE;
+			DI.bLinkChanged[0] = TRUE;
+		}
+		break;
+
+	default:
+	case DMA_LAN:
+		for (i = 0; i < SW_MAX_LAN_PORTS; i++) {
+			if (FALSE == DI.bLinkChanged[i]) {
+				UINT	uReg = KS8695_READ_REG(KS8695_SWITCH_AUTO0 + (i >> 1));
+				if (0 == (i % 2))
+					uReg >>= 16;
+				if (!(uReg & SW_AUTONEGO_STAT_LINK)) {
+					bLinkChanged = TRUE;
+					DI.bLinkChanged[i] = TRUE;
+				}
+			}
+		}
+		break;
+	}
+
+	return bLinkChanged;
+}
+
+/*
+ * ProcessTxInterrupts
+ *	This function is use to process Tx interrupt, reclaim resources after 
+ *	transmit completes.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *
+ * Return(s)
+ *	how many number of Tx packets are not processed yet.
+ */
+static int __inline ProcessTxInterrupts(PADAPTER_STRUCT Adapter)
+{
+	int i;
+	TXDESC *TransmitDescriptor;
+	unsigned long flags;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s> )", __FUNCTION__); 
+#endif
+
+	i = DI.nTxDescUsed;
+	TransmitDescriptor = &DI.pTxDescriptors[i];
+	while (!(le32_to_cpu(TransmitDescriptor->TxOwnBit) & DESC_OWN_BIT) && DI.nTransmitCount > 0) {
+		/* note that WAN DMA doesn't have statistics counters associated with,
+		   therefore use local variables to track them instead */
+		STAT_NET(tx_packets)++;
+		STAT_NET(tx_bytes) += DI.pTxSkb[i].length;
+		dev_kfree_skb_irq(DI.pTxSkb[i].skb);
+		DI.pTxSkb[i].skb = NULL;
+
+		__save_flags_cli(flags);
+		DI.nTxDescAvail.counter++;
+		DI.nTransmitCount--;
+		__restore_flags(flags);
+		
+		/* clear corresponding fields */
+		TransmitDescriptor->TxDMAFragAddr = 0;
+
+		/* clear all related bits, including len field, control bits and port bits */
+		TransmitDescriptor->TxFrameControl = 0;
+
+		/* to next Tx descriptor */
+		i = (i + 1) % DI.nTxDescTotal;
+		TransmitDescriptor = &DI.pTxDescriptors[i];
+		DI.nTxProcessedCount++;
+	}
+	DI.nTxDescUsed = i;
+
+	if (DI.bTxNoResource && netif_queue_stopped(Adapter->netdev) &&
+	   (atomic_read(&DI.nTxDescAvail) > ((DI.nTxDescTotal * 3) >> 2))) {	/* 3/4 */
+		DI.bTxNoResource = FALSE;
+		netif_wake_queue(Adapter->netdev);
+#ifdef	DEBUG_THIS
+		DRV_INFO("%s> Tx process resumed", __FUNCTION__);
+#endif
+	}
+
+	return DI.nTransmitCount;
+}
+
+
+/*
+ * ProcessRxInterrupts
+ *	This function is use to process Rx interrupt, send received data up
+ *	the network stack. 
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *
+ * Return(s)
+ *	how many Rx packets are processed.
+ */
+static int __inline ProcessRxInterrupts(PADAPTER_STRUCT Adapter)
+{
+	RXDESC *CurrentDescriptor, *pBegin;
+	int i, nProcessed = 0;
+	uint32_t Length;
+	uint32_t uFrameCtrl;
+	struct sk_buff *skb;
+	struct sk_buff *copy_skb;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s> )", __FUNCTION__); 
+#endif
+
+	i = DI.nRxDescNextAvail;
+	pBegin = CurrentDescriptor = &DI.pRxDescriptors[i];
+
+	while (!((uFrameCtrl = le32_to_cpu(CurrentDescriptor->RxFrameControl)) & DESC_OWN_BIT)) {
+		skb = DI.pRxSkb[i].skb;
+        	/* it should never goes here */
+		if (NULL == skb) 
+        	{
+			if (!(0 == CurrentDescriptor->RxFrameControl && 0 == CurrentDescriptor->RxDMAFragLen
+				&& 0 == CurrentDescriptor->RxDMAFragAddr)) {
+				DRV_INFO("%s: inconsistency error, rx desc index=%d", __FUNCTION__, i);
+			}
+			break;
+		}
+
+		/* length with CRC bytes included */
+		Length = (uFrameCtrl & RFC_FL_MASK);
+
+		/* test both bits to make sure single packet */
+		if ((uFrameCtrl & (RFC_LS | RFC_FS)) != (RFC_LS | RFC_FS)) {
+			DRV_INFO("%s> spanning packet detected (framectrl=0x%08x, rx desc index=%d)", __FUNCTION__, uFrameCtrl, i);
+			if (uFrameCtrl & RFC_FS) {
+				/* first segment */
+				Length = DI.uRxBufferLen;
+				DRV_INFO(" first segment, len=%d", Length);
+				/* compensite offset CRC */
+				Length += ETH_CRC_LENGTH;
+			}
+			else if (uFrameCtrl & RFC_LS) {
+				/* last segment */
+				if (Length > DI.uRxBufferLen + ETH_CRC_LENGTH) {
+					Length -= DI.uRxBufferLen;
+					DRV_INFO(" last segment, len=%d", Length);
+				}
+				else {
+					DRV_WARN("%s> under size packet (len=%d, buffer=%d)", __FUNCTION__, Length, DI.uRxBufferLen);
+					STAT_NET(rx_errors)++;
+					goto CLEAN_UP;
+				}
+			}
+			else {
+				if (0 == uFrameCtrl) {
+					/* race condition ? */
+					DRV_WARN("FragLen=0x%08x, FragAddr=0x%08x, RxNextPtr=0x%08x, RxDescEmpty=%d, pkt dropped", 
+						CurrentDescriptor->RxDMAFragLen, CurrentDescriptor->RxDMAFragAddr, CurrentDescriptor->RxDMANextPtr, atomic_read(&DI.RxDescEmpty));
+#ifdef	PACKET_DUMP
+					ks8695_dump_packet(Adapter, skb->data, DI.uRxBufferLen, DEBUG_PACKET_LEN | DEBUG_PACKET_HEADER | DEBUG_PACKET_CONTENT);
+#endif
+				}
+				else {
+					DRV_WARN("%s> error spanning packet, dropped", __FUNCTION__);
+				}
+				STAT_NET(rx_errors)++;
+				goto CLEAN_UP;
+			}
+		}
+
+		/* if error happened!!! */
+		if (uFrameCtrl & (RFC_ES | RFC_RE)) {
+			DRV_WARN("%s> error found (framectrl=0x%08x)", __FUNCTION__, uFrameCtrl);
+			STAT_NET(rx_errors)++;
+			if (uFrameCtrl & RFC_TL) {
+				STAT_NET(rx_length_errors)++;
+			}
+			if (uFrameCtrl & RFC_CRC) {
+				STAT_NET(rx_crc_errors)++;
+			}
+			if (uFrameCtrl & RFC_RF) {
+				STAT_NET(rx_length_errors)++;
+			}
+			/* if errors other than ES happened!!! */
+			if (uFrameCtrl & RFC_RE) {
+				DRV_WARN("%s> RFC_RE (MII) (framectrl=0x%08x)", __FUNCTION__, uFrameCtrl);
+				STAT_NET(rx_errors)++;
+			}
+			/* RLQ, 11/07/2002, added more check to IP/TCP/UDP checksum errors */
+			if (uFrameCtrl | (RFC_IPE | RFC_TCPE | RFC_UDPE)) {
+				STAT_NET(rx_errors)++;
+			}
+			goto CLEAN_UP;
+		}
+
+#ifdef	MORE_ERROR_TRACKING
+		/* for debug purpose */
+		if (Length > 1518) {
+			DI.uRx1518plus++;
+
+			/* note that printout affects the performance figure quite lots, so don't display
+			   it when conducting performance test, like Chariot */
+			if (DI.uDebugDumpRxPkt & DEBUG_PACKET_OVSIZE) {
+				DRV_INFO("%s> oversize pkt, size=%d, RxDesc=%d", __FUNCTION__, Length, i);
+			}
+
+			/* do early drop */
+			STAT_NET(rx_errors)++;
+			goto CLEAN_UP;
+		}
+
+		/* for debug purpose */
+		if (Length < 64) {
+			DI.uRxUnderSize++;
+			/* note that printout affects the performance figure quite lots, so don't display
+			   it when conducting performance test, like Chariot */
+			if (DI.uDebugDumpRxPkt & DEBUG_PACKET_UNDERSIZE) {
+				DRV_INFO("%s> under pkt, size=%d, RxDesc=%d", __FUNCTION__, Length, i);
+			}
+			/* do early drop */
+			STAT_NET(rx_errors)++;
+			goto CLEAN_UP;
+		}
+#endif /* #ifdef	MORE_ERROR_TRACKING */
+
+		/* 
+         	 * if we are here, means a valid packet received!!! Get length of the pacekt 
+         	 */
+
+		/* offset CRC bytes! */
+		Length -= ETH_CRC_LENGTH;
+
+		/* to do something ? */
+		consistent_sync(skb->data, DI.uRxBufferLen, PCI_DMA_FROMDEVICE);
+
+#ifdef	PACKET_DUMP
+		/* build in debug mechanism */
+		ks8695_dump_packet(Adapter, skb->data, Length, DI.uDebugDumpRxPkt);
+#endif
+
+		/* 
+		 * copy recevied data to a new skb buffer in order to make IP header 32 bit alignment.
+		 */
+		copy_skb = dev_alloc_skb(Length + offset );
+		if ( copy_skb == NULL) 
+		{
+		    STAT_NET(rx_dropped)++;
+		    goto CLEAN_UP;
+		}
+		copy_skb->dev = Adapter->netdev;
+		skb_reserve(copy_skb, offset); /* offset frame by 2 bytes */
+
+		/* read pkt_len bytes into new skb buf */
+		memcpy ( skb_put(copy_skb, Length), skb->data, Length ); 
+
+		/* pass the copied skb with IP header alignment to uplayer */
+		skb = copy_skb;
+
+		/* check and set Rx Checksum Offload flag */
+		if (DI.bRxChecksum) 
+		    /* tell upper edge that the driver handled it already! */
+		    skb->ip_summed = CHECKSUM_UNNECESSARY;
+		else 
+		    skb->ip_summed = CHECKSUM_NONE;
+
+		skb->protocol = eth_type_trans(skb, Adapter->netdev);
+		netif_rx(skb);
+		nProcessed++;
+
+		/* note that WAN DMA doesn't have statistics counters associated with,
+		   therefore use local variables to track them instead */
+		STAT_NET(rx_packets)++;
+		STAT_NET(rx_bytes) += Length;
+		if (uFrameCtrl & RFC_MF)
+		    STAT_NET(multicast)++;
+		Adapter->netdev->last_rx = jiffies;
+
+CLEAN_UP:
+		/* 
+		 * done with this descriptor, let ks8695 DMA own it again 
+         	*/
+		CurrentDescriptor->RxFrameControl &= cpu_to_le32(~(RFC_FRAMECTRL_MASK)); 
+		if (pBegin != CurrentDescriptor)
+			CurrentDescriptor->RxFrameControl |= cpu_to_le32(DESC_OWN_BIT);
+
+        	/* go to next rx descriptor */
+		i = (i + 1) % DI.nRxDescTotal;
+		CurrentDescriptor = &DI.pRxDescriptors[i];
+		if (pBegin == CurrentDescriptor)	/* one round already */
+			break;
+	} /* while (!((uFrameCtrl = le32_to_cpu(CurrentDescriptor->RxFrameControl)) & DESC_OWN_BIT)) { */
+	if (nProcessed)
+		pBegin->RxFrameControl |= cpu_to_le32(DESC_OWN_BIT);
+
+	DI.nRxDescNextAvail = i;
+
+	/* enable Rx engine!!! */
+	KS8695_WRITE_REG(REG_RXSTART + DI.nOffset, 1);
+
+	return nProcessed;
+}
+
+#ifdef FAST_POLL
+static void ks8695_fast_poll(void *arg)
+{
+	PADAPTER_STRUCT Adapter = ((struct net_device *)arg)->priv;
+	int i, irq;
+
+	if (ks8695_poll_ready) {
+		for (i = 0; (i < 6); i++) {
+			irq = DI.uIntShift + i;
+			if (DI.uIntMask & (1L << irq))
+				ks8695_isr(irq, arg, NULL);
+		}
+	}
+}
+#endif
+
+#ifdef HANDLE_RXPACKET_BY_INTERRUPT
+/*
+ * ks8695_isr
+ *	This function is the Interrupt Service Routine.
+ *
+ * Argument(s)
+ *	irq		interrupt number
+ *	data	pointer to net_device structure
+ *	regs	pointer to pt_regs structure
+ *
+ * Return(s)
+ *	NONE.
+ */
+void ks8695_isr(int irq, void *data, struct pt_regs *regs)
+{
+	PADAPTER_STRUCT Adapter = ((struct net_device *)data)->priv;
+	uint32_t uISR, uISR1, uIER;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s> HANDLE_RXPACKET_BY_INTERRUPT.)", __FUNCTION__); 
+#endif
+
+	uISR1 = (1L << irq);
+	uIER = KS8695_READ_REG(KS8695_INT_ENABLE);
+
+	/* disable corresponding interrupt */
+	KS8695_WRITE_REG(KS8695_INT_ENABLE, uIER & ~uISR1);
+
+	/* ACK */
+	KS8695_WRITE_REG(KS8695_INT_STATUS, uISR1);
+
+	uISR = uISR1 >> DI.uIntShift;
+
+	/* handle Receive Interrupt */
+	if (uISR & INT_RX_BIT)
+		ProcessRxInterrupts(Adapter);
+
+	/* handle Transmit Done Interrupt */
+#ifndef	USE_TX_UNAVAIL
+	if (uISR & INT_TX_BIT) {
+#else
+	if (DI.nTransmitCount) {
+#endif
+		ProcessTxInterrupts(Adapter);
+	}
+
+	/* Restore Previous Interrupt Settings */
+	KS8695_WRITE_REG(KS8695_INT_ENABLE, uIER );
+
+}
+
+#endif /* #ifdef HANDLE_RXPACKET_BY_INTERRUPT */
+
+
+#ifdef RX_TASK
+/*
+ * ks8695_isr
+ *	This function is the Interrupt Service Routine.
+ *
+ * Argument(s)
+ *	irq		interrupt number
+ *	data	pointer to net_device structure
+ *	regs	pointer to pt_regs structure
+ *
+ * Return(s)
+ *	NONE.
+ */
+void ks8695_isr(int irq, void *data, struct pt_regs *regs)
+{
+	PADAPTER_STRUCT Adapter = ((struct net_device *)data)->priv;
+	uint32_t uISR, uISR1, uIER;
+
+#ifdef	  PACKET_DUMP
+	DRV_INFO("%s> RX_TASK ?)", __FUNCTION__); 
+#endif
+
+	uISR1 = (1L << irq);
+	uIER = KS8695_READ_REG(KS8695_INT_ENABLE);
+
+	/* disable corresponding interrupt */
+	KS8695_WRITE_REG(KS8695_INT_ENABLE, uIER & ~uISR1);
+
+	/* ACK */
+	KS8695_WRITE_REG(KS8695_INT_STATUS, uISR1);
+
+	uISR = uISR1 >> DI.uIntShift;
+
+	switch (uISR) {
+	    /* handle Receive Interrupt */
+		case INT_RX_BIT: 
+			if (FALSE == DI.rx_scheduled) {
+				DI.rx_scheduled = TRUE;
+				tasklet_hi_schedule(&DI.rx_tasklet);
+			}
+			uISR1 = 0;
+			break;
+
+	    /* handle Transmit Done Interrupt */
+		case INT_TX_BIT:
+#ifdef	USE_TX_UNAVAIL
+	    /* handle Transmit Buffer Unavailable Interrupt */
+		case INT_TX_UNAVAIL_BIT:
+		case (INT_TX_UNAVAIL_BIT | INT_TX_BIT):
+#endif
+#ifndef	TX_TASK
+			ProcessTxInterrupts(Adapter);
+#else
+			if (FALSE == DI.tx_scheduled) {
+				DI.tx_scheduled = TRUE;
+				tasklet_hi_schedule(&DI.tx_tasklet);
+			}
+			uISR1 = 0;
+#endif
+			break;
+
+#ifdef	USE_RX_UNAVAIL
+	    /* handle Receive Buffer Unavailable Interrupt */
+		case INT_RX_UNAVAIL_BIT:
+			break;
+#endif
+	}
+
+	/* Restore Previous Interrupt if not a scheduled task */
+	if (uISR1) {
+		KS8695_WRITE_REG(KS8695_INT_ENABLE, uIER );
+	}
+}
+
+#endif	/*RX_TASK*/
+
+/*
+ * ks8695_isre
+ * for I-cache lockdown or FIQ purpose. Make sure this function is after ks8695_isr immediately.
+ *
+ * Argument(s)
+ *	NONE.
+ *
+ */
+void ks8695_isre(void)
+{
+	/* just for the end of ks8695_isr routine, unless we find a way to define end of function
+	   within ks8695_isr itself */
+}
+
+/*
+ * ks8695_isr_link
+ *	This function is to process WAN link change interrupt as a special case
+ *
+ * Argument(s)
+ *	irq		interrupt number
+ *	data	pointer to net_device structure
+ *	regs	pointer to pt_regs structure
+ *
+ * Return(s)
+ *	NONE.
+ */
+void ks8695_isr_link(int irq, void *data, struct pt_regs *regs)
+{
+	PADAPTER_STRUCT Adapter = ((struct net_device *)data)->priv;
+	UINT	uIER;
+
+	spin_lock(&DI.lock);
+	uIER = KS8695_READ_REG(KS8695_INT_ENABLE) & ~INT_WAN_LINK;
+	KS8695_WRITE_REG(KS8695_INT_ENABLE, uIER);
+	spin_unlock(&DI.lock);
+
+	DI.nLinkChangeCount++;
+	DI.bLinkChanged[0] = TRUE;
+
+	/* start auto nego only when link is down */
+	if (!swGetWANLinkStatus(Adapter)) {
+		swPhyReset(Adapter, 0);
+		swAutoNegoAdvertisement(Adapter, 0);
+		swDetectPhyConnection(Adapter, 0);
+	}
+
+	/* ACK */
+	KS8695_WRITE_REG(KS8695_INT_STATUS, INT_WAN_LINK);
+	spin_lock(&DI.lock);
+	uIER = KS8695_READ_REG(KS8695_INT_ENABLE) | INT_WAN_LINK;
+	KS8695_WRITE_REG(KS8695_INT_ENABLE, uIER);
+	spin_unlock(&DI.lock);
+}
+
+
+/*
+ * ReceiveBufferFill
+ *	This function is use to replace used receive buffers with new SBBs
+ *	to Rx descriptors.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *
+ * Return(s)
+ *	NONE.
+ */
+static void ReceiveBufferFill(uintptr_t data)
+{
+	PADAPTER_STRUCT Adapter = (PADAPTER_STRUCT) data;
+	RXDESC *CurrentDescriptor, *pBegin;
+	struct sk_buff *skb;
+	unsigned long flags;
+	int i;
+
+	if (!test_bit(KS8695_BOARD_OPEN, &Adapter->flags)) {
+		DI.rx_fill_scheduled = FALSE;
+		/* enable Rx engine!!! */
+		KS8695_WRITE_REG(REG_RXSTART + DI.nOffset, 1);
+		return;
+	}
+
+	i = DI.nRxDescNextToFill;
+	pBegin = CurrentDescriptor = &DI.pRxDescriptors[i];
+
+	//__save_flags_cli(flags);
+	while (NULL == DI.pRxSkb[i].skb) {
+		skb = alloc_skb(DI.uRxBufferLen + offset, GFP_ATOMIC | GFP_DMA);
+		if (NULL == skb) {
+			/*DRV_WARN("%s> alloc_skb failed, refill rescheduled again", __FUNCTION__);*/
+			break;
+		}
+
+		skb->dev = Adapter->netdev;
+		DI.pRxSkb[i].length = DI.uRxBufferLen;
+		DI.pRxSkb[i].direction = PCI_DMA_FROMDEVICE;
+#ifndef	RX_TASK
+		consistent_sync(skb->data, DI.uRxBufferLen, PCI_DMA_FROMDEVICE);
+#endif
+		DI.pRxSkb[i].dma = virt_to_phys(skb->data);
+
+		/* to avoid possible race problem, make the change of these variables atomic */
+		__save_flags_cli(flags);
+		DI.pRxSkb[i].skb = skb;
+
+		/* setup Rx descriptor!!! */
+		CurrentDescriptor->RxDMAFragAddr = cpu_to_le32(DI.pRxSkb[i].dma);
+		CurrentDescriptor->RxDMAFragLen = cpu_to_le32(DI.uRxBufferLen);
+		CurrentDescriptor->RxFrameControl |= cpu_to_le32(DESC_OWN_BIT);
+
+		DI.RxDescEmpty.counter--;
+		__restore_flags(flags);
+
+		i = (i + 1) % DI.nRxDescTotal;
+		CurrentDescriptor = &DI.pRxDescriptors[i];
+		if (pBegin == CurrentDescriptor) /* one round already */
+			break;
+	}
+	DI.nRxDescNextToFill = i;
+	//__restore_flags(flags);
+	
+	DI.rx_fill_scheduled = FALSE;
+
+	/* enable Rx engine!!! */
+	KS8695_WRITE_REG(REG_RXSTART + DI.nOffset, 1);
+}
+
+
+
+static int	ks8695_ioctl_switch(PADAPTER_STRUCT Adapter, PIOCTRL_SWITCH pIoCtrl);
+
+/*
+ * ks8695_ioctl
+ *	This function is the ioctl entry point. It handles some driver specific IO
+ *	functions.
+ *
+ * Argument(s)
+ *	netdev		pointer to net_device structure.
+ *	ifr			pointer to ifreq structure
+ *	cmd			io cmd 
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+int ks8695_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+    PADAPTER_STRUCT Adapter = netdev->priv;
+	PIOCTRL	pIoCtrl;
+	int	nRet = -1;
+
+    /*DRV_INFO("%s> cmd = 0x%x", __FUNCTION__, cmd); */
+	pIoCtrl = (PIOCTRL)ifr->ifr_data;
+
+    switch(cmd) {
+		case SIOC_KS8695_IOCTRL:
+			if (ifr->ifr_data) {
+				UINT32	*pReg, i;
+
+				switch (pIoCtrl->byId)
+				{
+					case REG_DMA_DUMP:
+						if (pIoCtrl->usLen >= (4 * (1 + REG_DMA_MAX) + 3)) { /* 1 + 2 + 4 + 8 * 4 */
+							pReg = pIoCtrl->u.uData;
+							/* tell debug application its offset */
+							*pReg++ = DI.nOffset;
+							for (i = REG_TXCTRL; i <= REG_STATION_HIGH ; i += 4, pReg++) {
+								*pReg = (UINT32)KS8695_READ_REG(i + DI.nOffset);
+							}
+							nRet = 0;
+						}
+						break;
+
+					case REG_DMA_STATION_DUMP:
+						if (pIoCtrl->usLen >= (4 * REG_DMA_STATION_MAX + 3)) { /* 1 + 2 + 16 * 2 * 4 */
+							pReg = pIoCtrl->u.uData;
+							for (i = REG_MAC0_LOW; i <= REG_MAC15_HIGH ; i += 8) {
+								*pReg++ = (UINT32)KS8695_READ_REG(i + DI.nOffset);
+								*pReg++ = (UINT32)KS8695_READ_REG(i + DI.nOffset + 4);
+							}
+							nRet = 0;
+						}
+						break;
+
+					case REG_UART_DUMP:
+						if (pIoCtrl->usLen >= (4 * REG_UART_MAX + 3)) { /* 1 + 2 + 9 * 4 */
+							pReg = pIoCtrl->u.uData;
+							for (i = KS8695_UART_RX_BUFFER; i <= KS8695_UART_STATUS ; i += 4, pReg++) {
+								*pReg = (UINT32)KS8695_READ_REG(i);
+							}
+							nRet = 0;
+						}
+						break;
+
+					case REG_INT_DUMP:
+						if (pIoCtrl->usLen >= (4 * REG_INT_MAX + 3)) { /* 1 + 2 + 14 * 4 */
+							pReg = pIoCtrl->u.uData;
+							for (i = KS8695_INT_CONTL; i <= KS8695_IRQ_PEND_PRIORITY ; i += 4, pReg++) {
+								*pReg = (UINT32)KS8695_READ_REG(i);
+							}
+							nRet = 0;
+						}
+						break;
+
+					/* Timer receive related */
+					case REG_TIMER_DUMP:
+						if (pIoCtrl->usLen >= (4 * REG_TIMER_MAX + 3)) { /* 1 + 2 + 5 * 4 */
+							pReg = pIoCtrl->u.uData;
+							for (i = KS8695_TIMER_CTRL; i <= KS8695_TIMER0_PCOUNT ; i += 4, pReg++) {
+								*pReg = (UINT32)KS8695_READ_REG(i);
+							}
+							nRet = 0;
+						}
+						break;
+
+					/* GPIO receive related */
+					case REG_GPIO_DUMP:
+						if (pIoCtrl->usLen >= (4 * REG_GPIO_MAX + 3)) { /* 1 + 2 + 3 * 4 */
+							pReg = pIoCtrl->u.uData;
+							for (i = KS8695_GPIO_MODE; i <= KS8695_GPIO_DATA ; i += 4, pReg++) {
+								*pReg = (UINT32)KS8695_READ_REG(i);
+							}
+							nRet = 0;
+						}
+						break;
+
+					case REG_SWITCH_DUMP:
+						if (pIoCtrl->usLen >= (4 * REG_SWITCH_MAX + 3)) { /* 1 + 2 + 21 * 4 */
+							pReg = pIoCtrl->u.uData;
+							for (i = KS8695_SWITCH_CTRL0; i <= KS8695_LAN34_POWERMAGR ; i += 4, pReg++) {
+								*pReg = (UINT32)KS8695_READ_REG(i);
+							}
+							nRet = 0;
+						}
+						break;
+
+					case REG_MISC_DUMP:
+						if (pIoCtrl->usLen >= (4 * REG_MISC_MAX + 3)) { /* 1 + 2 + 7 * 4 */
+							pReg = pIoCtrl->u.uData;
+							for (i = KS8695_DEVICE_ID; i <= KS8695_WAN_PHY_STATUS ; i += 4, pReg++) {
+								*pReg = (UINT32)KS8695_READ_REG(i);
+							}
+							nRet = 0;
+						}
+						break;
+
+					case REG_SNMP_DUMP:
+						/* do we need to restrict its read to LAN driver only? May be later! */
+						if (pIoCtrl->usLen >= (4 * REG_SNMP_MAX + 3)) { /* 1 + 2 + 138 * 4 */
+							/* each port (1-4) takes 32 counters, and last 10 counters for port */
+							pReg = pIoCtrl->u.uData;
+							for (i = 0; i <= REG_SNMP_MAX ; i++, pReg++) {
+								*pReg = swReadSNMPReg(Adapter, i);
+								DelayInMicroseconds(10);
+							}
+							nRet = 0;
+						}
+						break;
+
+					case DRV_VERSION:
+						if (pIoCtrl->usLen >= 19) { /* 1 + 2 + 16 */
+							if (0 == Adapter->rev) 
+								strncpy(pIoCtrl->u.byData, ks8695_driver_version, 15);
+							else {
+								if ((strlen(ks8695_driver_version) + 4) <= 15) {
+									sprintf(pIoCtrl->u.byData, "%s, 95P.PING.01", ks8695_driver_version);
+								}
+								else
+									strncpy(pIoCtrl->u.byData, ks8695_driver_version, 15);
+							}
+							nRet = 0;
+						}
+						break;
+
+#ifdef	CONFIG_ARCH_KS8695P
+					case DUMP_PCI_SPACE:
+						if (pIoCtrl->usLen >= sizeof(IOCTRL)) { /* 1 + 2 + 1 */
+							if (Adapter->rev) {
+								i = 0;
+								printk("----- PCI conf Space -----\n");
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(KS8695_2000)); i += 4;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(KS8695_2004)); i += 4;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(KS8695_2008)); i += 4;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(KS8695_200C)); i += 4;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(KS8695_2010)); i += 4;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(KS8695_2014)); i += 4;
+								i = 0x2c;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(KS8695_202C)); i += 4;
+								i = 0x3c;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(KS8695_203C)); i += 4;
+								nRet = 0;
+							}	
+						}
+						break;
+
+					case DUMP_BRIDGE_REG:
+						if (pIoCtrl->usLen >= sizeof(IOCTRL)) { /* 1 + 2 + 1 + 1 (optional) */
+							if (Adapter->rev) {
+								printk("----- Bridge Conf Registers -----\n");
+								i = KS8695_2100;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(i));
+								i = KS8695_2104;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(i));
+
+								i = KS8695_2200;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(i));
+								i = KS8695_2204;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(i));
+								i = KS8695_2208;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(i));
+								i = KS8695_220C;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(i));
+								i = KS8695_2210;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(i));
+								i = KS8695_2214;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(i));
+								i = KS8695_2218;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(i));
+								i = KS8695_221C;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(i));
+								i = KS8695_2220;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(i));
+								i = KS8695_2224;
+								printk("0x%04x          0x%08x\n", i, KS8695_READ_REG(i));
+								nRet = 0;
+							}
+						}
+						break;
+#endif //CONFIG_ARCH_KS8695P
+					case MEMORY_DUMP:
+						/* dump 32 dwords each time */
+						if (pIoCtrl->usLen >= (4 * 32 + 3)) { /* 1 + 2 + 1 + 1 (optional) */
+							UINT32	*pReg1;
+
+							/* note that the address is in the first dword, when returned will contain data */
+							pReg = pIoCtrl->u.uData;
+							pReg1 = (UINT32 *)(*pReg);
+
+#ifdef	DEBUG_THIS
+							DRV_INFO("addr=0x%08x, 0x%0x8", pReg1, *pReg1);
+#endif
+							/* if no null pointer */
+							if (pReg1 && (0xc0000000 == ((UINT)pReg1 & 0xc0000000))) {
+								for (i = 0; i <= 32 ; i++, pReg++, pReg1++) {
+									*pReg = *pReg1;
+								}
+								nRet = 0;
+							}
+							else {
+								DRV_INFO("%s> invalid address: 0x%08x", __FUNCTION__, *pReg1);
+								nRet = -EINVAL;
+							}
+						}
+						break;
+
+					case MEMORY_SEARCH:
+						/* dump 32 dwords each time */
+						if (pIoCtrl->usLen > 3 && pIoCtrl->usLen < 128) { /* 1 + 2 + optional length */
+							DRV_INFO("%s> not implemented yet", __FUNCTION__);
+							nRet = 0;
+						}
+						break;
+
+					case REG_WRITE:
+						/* write control register */
+						if (pIoCtrl->usLen >= 7) { /* 1 + 2 + 1 * 4 */
+							UINT	uReg;
+
+							uReg = pIoCtrl->u.uData[0];
+							if (uReg >= 0xffff) {
+								return -EINVAL;
+							}
+							if (pIoCtrl->usLen < 11) {
+								/* if no parameter is given, display register value instead */
+								printk("Reg(0x%04x) = 0x%08x", uReg, KS8695_READ_REG(uReg));
+							}
+							else {
+								KS8695_WRITE_REG(uReg, pIoCtrl->u.uData[1]);
+							}
+							nRet = 0;
+						}
+						break;
+
+					case DEBUG_DUMP_TX_PACKET:
+						/* set dump tx packet flag */
+						if (pIoCtrl->usLen >= 7) { /* 1 + 2 + 4 */
+							DI.uDebugDumpTxPkt = pIoCtrl->u.uData[0];
+#ifndef	PACKET_DUMP
+							DRV_INFO("%s> DumpTxPkt was disabled", __FUNCTION__);
+#endif
+							nRet = 0;
+						}
+						break;
+
+					case DEBUG_DUMP_RX_PACKET:
+						/* set dump rx packet flag */
+						if (pIoCtrl->usLen >= 7) { /* 1 + 2 + 4 */
+							DI.uDebugDumpRxPkt = pIoCtrl->u.uData[0];
+#ifndef	PACKET_DUMP
+							DRV_INFO("%s> DumpRxPkt was disabled", __FUNCTION__);
+#endif
+							nRet = 0;
+						}
+						break;
+
+					case DEBUG_RESET_DESC:
+						/* set dump rx packet flag */
+						if (pIoCtrl->usLen == 3) { /* 1 + 2 */
+							ResetDma(Adapter);
+							nRet = 0;
+						}
+						break;
+
+					case DEBUG_STATISTICS:
+						/* printout statistical counters */
+						if (pIoCtrl->usLen == 3) { /* 1 + 2 */
+							printk("------- statistics TX -------\n");
+							printk("tx_packets      = %12u\n", (UINT)STAT_NET(tx_packets));
+							printk("tx_bytes        = %12u\n", (UINT)STAT_NET(tx_bytes));
+							printk("tx_dropped      = %12u\n", (UINT)STAT_NET(tx_dropped));
+							printk("tx_errors       = %12u\n", (UINT)STAT_NET(tx_errors));
+
+							printk("------- statistics RX -------\n");
+							printk("rx_packets      = %12u\n", (UINT)STAT_NET(rx_packets));
+							printk("rx_bytes        = %12u\n", (UINT)STAT_NET(rx_bytes));
+							printk("rx_dropped      = %12u\n", (UINT)STAT_NET(rx_dropped));
+							printk("rx_errors       = %12u\n", (UINT)STAT_NET(rx_errors));
+							printk("rx_length_errors= %12u\n", (UINT)STAT_NET(rx_length_errors));
+							printk("rx_crc_errors   = %12u\n", (UINT)STAT_NET(rx_crc_errors));
+							printk("collisions      = %12u\n", (UINT)STAT_NET(collisions));
+							printk("multicast       = %12u\n", (UINT)STAT_NET(multicast));
+							printk("rx_missed_errors= %12u\n", (UINT)STAT_NET(rx_missed_errors));
+							printk("rx_length_errors= %12u\n", (UINT)STAT_NET(rx_length_errors));
+							printk("over size pkts  = %12u\n", (UINT)DI.uRx1518plus);
+							printk("under size pkts = %12u\n", (UINT)DI.uRxUnderSize);
+							printk("TransmitCount   = %12u\n", DI.nTransmitCount);
+
+							printk("------- Misc -------\n");
+							printk("DMA reset count = %12d\n", DI.nResetCount);
+							printk("Link change cnt = %12d\n", DI.nLinkChangeCount);
+							nRet = 0;
+						}
+						break;
+
+					case DEBUG_DESCRIPTORS:
+						/* printout descriptors info */
+						if (pIoCtrl->usLen == 3) { /* 1 + 2 */
+							printk("------ TX Descriptors ------\n");
+							printk("descriptor VA   = 0x%08x\n", (UINT)DI.pTxDescriptors);
+							printk("total           = %10d\n", DI.nTxDescTotal);
+							printk("available       = %10d\n", atomic_read(&DI.nTxDescAvail));
+							printk("next available  = %10d\n", DI.nTxDescNextAvail);
+							printk("no resource     = %10d\n", DI.bTxNoResource);
+							printk("------ RX Descriptors ------\n");
+							printk("descriptor VA   = 0x%08x\n", (UINT)DI.pRxDescriptors);
+							printk("total           = %10d\n", DI.nRxDescTotal);
+							printk("next to fill    = %10d\n", DI.nRxDescNextToFill);
+							printk("next available  = %10d\n", DI.nRxDescNextAvail);
+							printk("empty           = %10d\n", atomic_read(&DI.RxDescEmpty));
+							nRet = 0;
+						}
+						break;
+
+					case DEBUG_LINK_STATUS:
+						/* printout link status */
+						if (pIoCtrl->usLen >= 3) { /* 1 + 2 */
+							int	i;
+
+							if (DMA_LAN != DI.usDMAId) {
+								/* RLQ, 1.0.0.14, modified for UPNP query */
+								if (pIoCtrl->usLen == 15) {	/* 3 + 3 * 4 */
+									UINT32	*pReg;
+
+									/* note that the address is in the first dword, when returned will contain data */
+									pReg = pIoCtrl->u.uData;
+									i = 0;
+									*pReg++ = DI.bLinkActive[i];	/* link active */
+									if (!DI.bLinkActive[i]) {
+										*pReg++ = 0;				/* speed */
+										*pReg = 0;					/* duplex */
+									}
+									else {
+										*pReg++ = (SPEED_100 == DI.usLinkSpeed[i]) ? 100000000 : 10000000;
+										*pReg = DI.bHalfDuplex[i];
+									}
+								}
+								else {	/* for back compatible with ks8695_debug utility */
+									i = 0;
+									if (!DI.bLinkActive[i]) {
+										printk("Link = Down, Speed=Unknown, Duplex=Unknown\n");
+									}
+									else {
+										if (SW_PHY_AUTO == DI.usCType[i]) {
+											printk("Link=Up, Speed=%s, Duplex (read)=%s, Duplex (detected)=%s\n",
+												SPEED_100 == DI.usLinkSpeed[i] ? "100" : "10", 
+												DI.bHalfDuplex[i] ? "Full Duplex" : "Half Duplex",
+												DI.bHalfDuplexDetected[i] ? "Full Duplex" : "Half Duplex");
+										}
+										else {
+											printk("Link=Up, Speed=%s, Duplex=%s\n",
+												SPEED_100 == DI.usLinkSpeed[i] ? "100" : "10", 
+												DI.bHalfDuplex[i] ? "Full Duplex" : "Half Duplex");
+										}
+									}
+								}
+							}
+							else {
+								/* RLQ, 1.0.0.14, modified for UPNP query */
+								if (pIoCtrl->usLen == 3 + 3 * 4 * SW_MAX_LAN_PORTS) {	/* 3 + 3 * 4 * 4 = 51 */
+									UINT32	*pReg;
+
+									/* note that the address is in the first dword, when returned will contain data */
+									pReg = pIoCtrl->u.uData;
+									for (i = 0; i < SW_MAX_LAN_PORTS; i++) {
+										*pReg++ = DI.bLinkActive[i];	/* link active */
+										if (!DI.bLinkActive[i]) {
+											*pReg++ = 0;				/* speed */
+											*pReg++ = 0;				/* duplex */
+										}
+										else {
+											*pReg++ = (SPEED_100 == DI.usLinkSpeed[i]) ? 100000000 : 10000000;
+											*pReg++ = DI.bHalfDuplex[i];
+										}
+									}
+								}
+								else {
+									for (i = 0; i < SW_MAX_LAN_PORTS; i++) {
+										if (DI.bLinkActive[i]) {
+											printk("Port[%d]  Speed=%s, Duplex (read)=%s, Duplex (detected)=%s\n", (i + 1),
+												SPEED_100 == DI.usLinkSpeed[i] ? "100" : "10", 
+												DI.bHalfDuplex[i] ? "Full Duplex" : "Half Duplex",
+											DI.bHalfDuplexDetected[i] ? "Full Duplex" : "Half Duplex");
+										}
+										else {
+											printk("Port[%d]  Speed = Unknown, Duplex = Unknown\n", (i + 1));
+										}
+									}
+								}
+							}
+							nRet = 0;
+						}
+						break;
+
+					case CONFIG_LINK_TYPE:
+						/* configure link media type (forced mode without auto nego) */
+						if (pIoCtrl->usLen == 19) { /* 1 + 2 + 4 * 4*/
+							uint32_t	uPort;
+							uint32_t	uSpeed;
+							uint32_t	uDuplex;
+
+							pReg = pIoCtrl->u.uData;
+							if (DMA_LAN != DI.usDMAId) {
+								uPort = 0;
+								pReg++;
+							} else {
+								uPort = *pReg++;
+								if (uPort >= SW_MAX_LAN_PORTS) {
+									DRV_WARN("%s> LAN port out of range (%d)", __FUNCTION__, uPort);
+									break;
+								}
+							}
+							DI.byDisableAutoNego[uPort] = *pReg++;
+							uSpeed = *pReg++;
+							uDuplex = *pReg;
+							/*DRV_INFO("%s> port=%d, disable autonego=%d, 100=%d, duplex=%d", __FUNCTION__, uPort, DI.byDisableAutoNego[uPort], uSpeed, uDuplex);*/
+							swConfigureMediaType(Adapter, uPort, uSpeed, uDuplex);
+							nRet = 0;
+						}
+						break;
+
+					case CONFIG_STATION_EX:
+						/* configure link media type (forced mode without auto nego) */
+						if (pIoCtrl->usLen == 13) { /* 1 + 2 + 4 + 6 */
+							pReg = pIoCtrl->u.uData;
+
+							/* uData[0] = set, byData[4-9] = mac address */
+							if (pIoCtrl->u.uData[0]) {
+								int	i;
+
+								i = macGetIndexStationEx(Adapter);
+								if (i >= 0) {
+									macSetStationEx(Adapter, &pIoCtrl->u.byData[4], i);
+									nRet = 0;
+								}
+							}
+							else {
+								macResetStationEx(Adapter, &pIoCtrl->u.byData[4]);
+								nRet = 0;
+							}
+						}
+						break;
+
+					case CONFIG_SWITCH_GET:
+						/* we don't really need it since the OS always boots at super mode */
+						/* if that is not the case, then enable following line, and add header file if missing ? */
+						/*if (!capable(CAP_NET_ADMIN)) return -EPERM;*/
+						/* !!! fall over !!! */
+
+					case CONFIG_SWITCH_SET:
+						/* for LAN driver only */
+						if (DMA_LAN == DI.usDMAId) {
+							return ks8695_ioctl_switch(Adapter, (PIOCTRL_SWITCH)ifr->ifr_data);
+						}
+						else {
+							if (CONFIG_SW_SUBID_ADV_LINK_SELECTION == ((PIOCTRL_SWITCH)ifr->ifr_data)->bySubId) {
+								return ks8695_ioctl_switch(Adapter, (PIOCTRL_SWITCH)ifr->ifr_data);
+							}
+							else {
+								/* filter out the IF supported for WAN */
+								return -EPERM;
+							}
+						}
+						break;
+
+					default:
+						DRV_INFO("%s> unsupported parameters: id=%d, len=%d", __FUNCTION__, pIoCtrl->byId, pIoCtrl->usLen);
+						return -EOPNOTSUPP;
+				}
+				break;
+			}
+
+		default:
+			return -EOPNOTSUPP;
+    }
+
+    return nRet;
+}
+
+/*
+ * ks8695_ioctl_switch
+ *	This function is used to configure CONFIG_SWITCH_SUBID related functions, for web page based
+ *	configuration or for ks8695_debug tool.
+ *
+ * Argument(s)
+ *	Adapter		pointer to ADAPTER_STRUCT structure.
+ *	pIoCtrl		pointer to IOCTRL_SWITCH structure.
+ *
+ * Return(s)
+ *	0				if success
+ *	negative value	if failed
+ */
+int ks8695_ioctl_switch(PADAPTER_STRUCT Adapter, PIOCTRL_SWITCH pIoCtrl)
+{
+	int	nRet = -1;
+	uint32_t	uPort, uReg;
+
+    switch(pIoCtrl->bySubId) {
+		case CONFIG_SW_SUBID_ON:
+			if (pIoCtrl->usLen == 8) { /* 1 + 2 + 1 + 4 */
+				if (CONFIG_SWITCH_SET == pIoCtrl->byId) 
+					swEnableSwitch(Adapter, pIoCtrl->u.uData[0]);
+				else {
+					/* return current switch status */
+					pIoCtrl->u.uData[0] = (KS8695_READ_REG(KS8695_SWITCH_CTRL0) & SW_CTRL0_SWITCH_ENABLE) ? TRUE : FALSE;
+				}
+				nRet = 0;
+			}
+			break;
+
+		case CONFIG_SW_SUBID_PORT_VLAN:
+			if (pIoCtrl->usLen == 20) { /* 1 + 2 + 1 + 4 * 4 */
+				uPort = pIoCtrl->u.uData[0];
+				if (uPort >= SW_MAX_LAN_PORTS) {
+					DRV_WARN("%s> LAN port out of range (%d)", __FUNCTION__, uPort);
+					break;
+				}
+				if (CONFIG_SWITCH_SET == pIoCtrl->byId) {
+					uint32_t	bInsertion;
+
+					DPI[uPort].usTag = (uint16_t)pIoCtrl->u.uData[1];
+					/* note that the driver doesn't use VLAN name, so the web page needs to remember it */
+					bInsertion = pIoCtrl->u.uData[2];
+					DPI[uPort].byCrossTalkMask = (uint8_t)(pIoCtrl->u.uData[3] & 0x1f);
+#ifdef	DEBUG_THIS
+					DRV_INFO("%s> port=%d, VID=%d, EgressMode=%s, crosstalk bit=0x%x", __FUNCTION__, uPort, DPI[uPort].usTag, bInsertion ? "tagged" : "untagged");
+#endif
+					swConfigurePort(Adapter, uPort);
+					swConfigTagInsertion(Adapter, uPort, bInsertion);
+				}
+				else {
+					pIoCtrl->u.uData[1] = (uint32_t)DPI[uPort].usTag;
+					pIoCtrl->u.uData[2] = (KS8695_READ_REG(KS8695_SWITCH_ADVANCED) & (1L << (17 + uPort))) ? TRUE : FALSE;
+					pIoCtrl->u.uData[3] = (uint32_t)DPI[uPort].byCrossTalkMask;
+				}
+				nRet = 0;
+			}
+			break;
+
+		case CONFIG_SW_SUBID_PRIORITY:
+			if (pIoCtrl->usLen == 32) { /* 1 + 2 + 1 + 4 * 7 */
+				uPort = pIoCtrl->u.uData[0];
+				if (uPort >= SW_MAX_LAN_PORTS) {
+					DRV_WARN("%s> LAN port out of range (%d)", __FUNCTION__, uPort);
+					break;
+				}
+				if (CONFIG_SWITCH_SET == pIoCtrl->byId) {
+					uint32_t	bRemoval;
+
+					DPI[uPort].byIngressPriorityTOS		= (uint8_t)pIoCtrl->u.uData[1];
+					DPI[uPort].byIngressPriority802_1P	= (uint8_t)pIoCtrl->u.uData[2];
+					DPI[uPort].byIngressPriority		= (uint8_t)pIoCtrl->u.uData[3];
+					DPI[uPort].byEgressPriority			= (uint8_t)pIoCtrl->u.uData[4];
+					bRemoval = (uint8_t)pIoCtrl->u.uData[5];
+					DPI[uPort].byStormProtection		= (uint8_t)pIoCtrl->u.uData[6];
+#ifdef	DEBUG_THIS
+					DRV_INFO("%s> port=%d, DSCPEnable=%d, IngressPriority802_1P=%d, IngressPriority=%d,"
+						"EgressPriority=%d, IngressTagRemoval=%d, StormProtection=%d", __FUNCTION__, uPort, 
+						DPI[uPort].byIngressPriorityTOS, DPI[uPort].byIngressPriority802_1P, DPI[uPort].byIngressPriority,
+						DPI[uPort].byEgressPriority, bRemoval, DPI[uPort].byStormProtection);
+#endif
+					swConfigurePort(Adapter, uPort);
+					swConfigTagRemoval(Adapter, uPort, bRemoval);
+				}
+				else {
+					pIoCtrl->u.uData[1]	= (uint32_t)DPI[uPort].byIngressPriorityTOS;
+					pIoCtrl->u.uData[2]	= (uint32_t)DPI[uPort].byIngressPriority802_1P;
+					pIoCtrl->u.uData[3]	= (uint32_t)DPI[uPort].byIngressPriority;
+					pIoCtrl->u.uData[4]	= (uint32_t)DPI[uPort].byEgressPriority;
+					pIoCtrl->u.uData[6]	= (uint32_t)DPI[uPort].byStormProtection;
+					uReg = KS8695_READ_REG(KS8695_SWITCH_ADVANCED);
+					pIoCtrl->u.uData[5] = uReg & (1L << (22 + uPort)) ? TRUE : FALSE;
+				}
+				nRet = 0;
+			}
+			break;
+
+		case CONFIG_SW_SUBID_ADV_LINK_SELECTION:
+			if (pIoCtrl->usLen >= 16) { /* 1 + 2 + 1 + 4 * (3 | 4) */
+				uPort = pIoCtrl->u.uData[0];
+				if (uPort >= SW_MAX_LAN_PORTS) {
+					DRV_WARN("%s> LAN port out of range (%d)", __FUNCTION__, uPort);
+					break;
+				}
+				if (DMA_LAN != DI.usDMAId) {
+					uPort = 0;
+				}
+				if (CONFIG_SWITCH_SET == pIoCtrl->byId) {
+					uint32_t	uDuplex;
+
+					if (pIoCtrl->usLen < 20) {
+						uDuplex = 0;
+					}
+					else {
+						uDuplex = pIoCtrl->u.uData[3];
+					}
+					/* auto nego or forced mode */
+					DI.byDisableAutoNego[uPort] = pIoCtrl->u.uData[1];
+					swConfigureMediaType(Adapter, uPort, pIoCtrl->u.uData[2], uDuplex);
+				}
+				else {
+					pIoCtrl->u.uData[1] = DI.usCType[uPort];
+					pIoCtrl->u.uData[2] = (uint32_t)DI.byDisableAutoNego[uPort];
+				}
+				nRet = 0;
+			}
+			break;
+
+		case CONFIG_SW_SUBID_ADV_CTRL:
+			if (pIoCtrl->usLen == 24) { /* 1 + 2 + 1 + 4 * 5 */
+				uReg = KS8695_READ_REG(KS8695_SWITCH_CTRL0);
+				if (CONFIG_SWITCH_SET == pIoCtrl->byId) {
+					if (pIoCtrl->u.uData[0]) {
+						uReg |= SW_CTRL0_FLOWCTRL_FAIR;
+					}
+					else {
+						uReg &= ~SW_CTRL0_FLOWCTRL_FAIR;
+					}
+					if (pIoCtrl->u.uData[1]) {
+						uReg |= SW_CTRL0_LEN_CHECKING;
+					}
+					else {
+						uReg &= ~SW_CTRL0_LEN_CHECKING;
+					}
+					if (pIoCtrl->u.uData[2]) {
+						uReg |= SW_CTRL0_AUTO_FAST_AGING;
+					}
+					else {
+						uReg &= ~SW_CTRL0_AUTO_FAST_AGING;
+					}
+					if (pIoCtrl->u.uData[3]) {
+						uReg |= SW_CTRL0_NO_BCAST_STORM_PROT;
+					}
+					else {
+						uReg &= ~SW_CTRL0_NO_BCAST_STORM_PROT;
+					}
+					uReg &= 0xfffffff3;	/* clear priority scheme fields, 3:2 */
+					uReg |= (pIoCtrl->u.uData[4] & 0x3) << 2;
+					KS8695_WRITE_REG(KS8695_SWITCH_CTRL0, uReg);
+					/* need 20 cpu clock delay for switch related registers */
+					DelayInMicroseconds(10);
+				}
+				else {
+					pIoCtrl->u.uData[0] = uReg & SW_CTRL0_FLOWCTRL_FAIR ? TRUE : FALSE;
+					pIoCtrl->u.uData[1] = uReg & SW_CTRL0_LEN_CHECKING ? TRUE : FALSE;
+					pIoCtrl->u.uData[2] = uReg & SW_CTRL0_AUTO_FAST_AGING ? TRUE : FALSE;
+					pIoCtrl->u.uData[3] = uReg & SW_CTRL0_NO_BCAST_STORM_PROT ? TRUE : FALSE;
+					pIoCtrl->u.uData[4] = (uReg >> 2) & 0x3;
+				}
+				nRet = 0;
+			}
+			break;
+
+		case CONFIG_SW_SUBID_ADV_MIRRORING:
+			if (pIoCtrl->usLen == 24) { /* 1 + 2 + 1 + 4 * 5 */
+				uReg = KS8695_READ_REG(KS8695_SWITCH_ADVANCED);
+				/* note that the port start from 1 - 5 instead of 0 - 5 used internally in the driver */
+				if (CONFIG_SWITCH_SET == pIoCtrl->byId) {
+					uReg &= 0xfffe0000;		/* currently, WEB page allows only on sniffer */
+					/* sniffer port */
+					if (pIoCtrl->u.uData[0] > 0 && pIoCtrl->u.uData[0] <= 5) {
+						uReg |= (1L << (pIoCtrl->u.uData[0] - 1)) << 11;
+					}
+					/* Tx mirror port */
+					if (pIoCtrl->u.uData[1] > 0 && pIoCtrl->u.uData[1] <= 5) {
+						uReg |= (1L << (pIoCtrl->u.uData[1] - 1)) << 6;
+					}
+					/* Rx mirror port */
+					if (pIoCtrl->u.uData[2] > 0 && pIoCtrl->u.uData[2] <= 5) {
+						uReg |= (1L << (pIoCtrl->u.uData[2] - 1)) << 1;
+					}
+					/* sniffer mode, 1 for AND 0 for OR */
+					if (pIoCtrl->u.uData[3]) {
+						uReg |= 0x00010000;		/* bit 16 */
+					}
+					/* IGMP trap enable */
+					if (pIoCtrl->u.uData[4]) {
+						uReg |= 0x00000001;		/* bit 0 */
+					}
+					KS8695_WRITE_REG(KS8695_SWITCH_ADVANCED, uReg);
+					/* need 20 cpu clock delay for switch related registers */
+					DelayInMicroseconds(10);
+				}
+				else {
+					pIoCtrl->u.uData[0] = (uReg >> 11) & 0x1f;
+					pIoCtrl->u.uData[1] = (uReg >> 6) & 0x1f;
+					pIoCtrl->u.uData[2] = (uReg >> 1) & 0x1f;
+					pIoCtrl->u.uData[3] = (uReg & 0x00010000) ? TRUE : FALSE;
+					pIoCtrl->u.uData[4] = (uReg & 0x00000001) ? TRUE : FALSE;
+				}
+				nRet = 0;
+			}
+			break;
+
+		case CONFIG_SW_SUBID_ADV_THRESHOLD:
+			if (pIoCtrl->usLen == 12) { /* 1 + 2 + 1 + 4 * 2 */
+				uReg = KS8695_READ_REG(KS8695_SWITCH_CTRL1);	/* 0xE804 */
+				if (CONFIG_SWITCH_SET == pIoCtrl->byId) {
+					uReg &= 0x00ffffff;	/* bit 31:24 */
+					uReg |= (pIoCtrl->u.uData[0] & 0xff) << 24;
+					KS8695_WRITE_REG(KS8695_SWITCH_CTRL1, uReg);
+					DelayInMicroseconds(10);
+
+					uReg = KS8695_READ_REG(KS8695_SWITCH_CTRL0);
+					uReg &= 0x8fffffff;	/* bit 30:28 */
+					uReg |= (pIoCtrl->u.uData[1] & 0x07) << 28;
+					KS8695_WRITE_REG(KS8695_SWITCH_CTRL0, uReg);
+					/* need 20 cpu clock delay for switch related registers */
+					DelayInMicroseconds(10);
+				}
+				else {
+					pIoCtrl->u.uData[0] = (uReg >> 24);
+					uReg = KS8695_READ_REG(KS8695_SWITCH_CTRL0);
+					pIoCtrl->u.uData[1] = (uReg >> 28) & 0x07;
+				}
+				nRet = 0;
+			}
+			break;
+
+		case CONFIG_SW_SUBID_ADV_DSCP:
+			if (pIoCtrl->usLen == 12) { /* 1 + 2 + 1 + 4 * 2 */
+				if (CONFIG_SWITCH_SET == pIoCtrl->byId) {
+					/* DSCP high */
+					KS8695_WRITE_REG(KS8695_DSCP_HIGH, pIoCtrl->u.uData[0]);
+					DelayInMicroseconds(10);
+					/* DSCP low */
+					KS8695_WRITE_REG(KS8695_DSCP_LOW, pIoCtrl->u.uData[1]);
+					DelayInMicroseconds(10);
+				}
+				else {
+					pIoCtrl->u.uData[0] = KS8695_READ_REG(KS8695_DSCP_HIGH);
+					pIoCtrl->u.uData[1] = KS8695_READ_REG(KS8695_DSCP_LOW);
+				}
+				nRet = 0;
+			}
+			break;
+
+		case CONFIG_SW_SUBID_INTERNAL_LED:
+			if (pIoCtrl->usLen == 12) { /* 1 + 2 + 1 + 4 * 2 */
+				uint8_t	byLed0, byLed1;
+
+				if (CONFIG_SWITCH_SET == pIoCtrl->byId) {
+					byLed0 = (uint8_t)pIoCtrl->u.uData[0];
+					byLed1 = (uint8_t)pIoCtrl->u.uData[1];
+					if (byLed0 <= LED_LINK_ACTIVITY && byLed1 <= LED_LINK_ACTIVITY) {
+						swSetLED(Adapter, FALSE, byLed0);
+						swSetLED(Adapter, TRUE, byLed1);
+
+						/* can we set WAN here as well or separate it to WAN driver ? */
+						{
+							uReg = KS8695_READ_REG(KS8695_WAN_CONTROL);
+							uReg &= 0xffffff88;		/* 6:4, 2:0 */
+							uReg |= (uint32_t)byLed1 << 4;
+							uReg |= (uint32_t)byLed0;
+							KS8695_WRITE_REG(KS8695_WAN_CONTROL, uReg);
+							/* need 20 cpu clock delay for switch related registers */
+							DelayInMicroseconds(10);
+						}
+					}
+					else {	/* out of range error */
+						DRV_WARN("%s> LED setting out of range", __FUNCTION__);
+						break;
+					}
+				}
+				else {
+					/* note that currently, all LED use same settings, so there is no
+					   need to define port in the IF */
+					/* LAN */
+					uReg = KS8695_READ_REG(KS8695_SWITCH_CTRL0);
+
+					pIoCtrl->u.uData[0] = (uint32_t)((uReg >> 22) & 0x7);
+					pIoCtrl->u.uData[1] = (uint32_t)((uReg >> 25) & 0x7);
+				}
+				nRet = 0;
+			}
+			break;
+
+		case CONFIG_SW_SUBID_INTERNAL_MISC:
+			if (pIoCtrl->usLen == 44) { /* 1 + 2 + 1 + 4 * 10 */
+				uReg = KS8695_READ_REG(KS8695_SWITCH_CTRL0);
+				if (CONFIG_SWITCH_SET == pIoCtrl->byId) {
+					if (pIoCtrl->u.uData[0]) {
+						uReg |= SW_CTRL0_ERROR_PKT;
+					}
+					else {
+						uReg &= ~SW_CTRL0_ERROR_PKT;
+					}
+					if (pIoCtrl->u.uData[1]) {
+						uReg |= SW_CTRL0_BUFFER_SHARE;
+					}
+					else {
+						uReg &= ~SW_CTRL0_BUFFER_SHARE;
+					}
+					if (pIoCtrl->u.uData[2]) {
+						uReg |= SW_CTRL0_AGING_ENABLE;
+					}
+					else {
+						uReg &= ~SW_CTRL0_AGING_ENABLE;
+					}
+					if (pIoCtrl->u.uData[3]) {
+						uReg |= SW_CTRL0_FAST_AGING;
+					}
+					else {
+						uReg &= ~SW_CTRL0_FAST_AGING;
+					}
+					if (pIoCtrl->u.uData[4]) {
+						uReg |= SW_CTRL0_FAST_BACKOFF;
+					}
+					else {
+						uReg &= ~SW_CTRL0_FAST_BACKOFF;
+					}
+					if (pIoCtrl->u.uData[5]) {
+						uReg |= SW_CTRL0_6K_BUFFER;
+					}
+					else {
+						uReg &= ~SW_CTRL0_6K_BUFFER;
+					}
+					if (pIoCtrl->u.uData[6]) {
+						uReg |= SW_CTRL0_MISMATCH_DISCARD;
+					}
+					else {
+						uReg &= ~SW_CTRL0_MISMATCH_DISCARD;
+					}
+					if (pIoCtrl->u.uData[7]) {
+						uReg |= SW_CTRL0_COLLISION_DROP;
+					}
+					else {
+						uReg &= ~SW_CTRL0_COLLISION_DROP;
+					}
+					if (pIoCtrl->u.uData[8]) {
+						uReg |= SW_CTRL0_BACK_PRESSURE;
+					}
+					else {
+						uReg &= ~SW_CTRL0_BACK_PRESSURE;
+					}
+					if (pIoCtrl->u.uData[9]) {
+						uReg |= SW_CTRL0_PREAMBLE_MODE;
+					}
+					else {
+						uReg &= ~SW_CTRL0_PREAMBLE_MODE;
+					}
+					KS8695_WRITE_REG(KS8695_SWITCH_CTRL0, uReg);
+					/* need 20 cpu clock delay for switch related registers */
+					DelayInMicroseconds(10);
+				}
+				else {
+					pIoCtrl->u.uData[0] = uReg & SW_CTRL0_ERROR_PKT ? TRUE : FALSE;
+					pIoCtrl->u.uData[1] = uReg & SW_CTRL0_BUFFER_SHARE ? TRUE : FALSE;
+					pIoCtrl->u.uData[2] = uReg & SW_CTRL0_AGING_ENABLE ? TRUE : FALSE;
+					pIoCtrl->u.uData[3] = uReg & SW_CTRL0_FAST_AGING ? TRUE : FALSE;
+					pIoCtrl->u.uData[4] = uReg & SW_CTRL0_FAST_BACKOFF ? TRUE : FALSE;
+					pIoCtrl->u.uData[5] = uReg & SW_CTRL0_6K_BUFFER ? TRUE : FALSE;
+					pIoCtrl->u.uData[6] = uReg & SW_CTRL0_MISMATCH_DISCARD ? TRUE : FALSE;
+					pIoCtrl->u.uData[7] = uReg & SW_CTRL0_COLLISION_DROP ? TRUE : FALSE;
+					pIoCtrl->u.uData[8] = uReg & SW_CTRL0_BACK_PRESSURE ? TRUE : FALSE;
+					pIoCtrl->u.uData[9] = uReg & SW_CTRL0_PREAMBLE_MODE ? TRUE : FALSE;
+				}
+				nRet = 0;
+			}
+			break;
+
+		case CONFIG_SW_SUBID_INTERNAL_SPANNINGTREE:
+			if (pIoCtrl->usLen == 20) { /* 1 + 2 + 1 + 4 * 4 */
+				uint32_t	uTxSpanning, uRxSpanning;
+
+				uPort = pIoCtrl->u.uData[0];
+				if (uPort >= SW_MAX_LAN_PORTS) {
+					DRV_WARN("%s> LAN port out of range (%d)", __FUNCTION__, uPort);
+					break;
+				}
+				if (CONFIG_SWITCH_SET == pIoCtrl->byId) {
+					uTxSpanning = pIoCtrl->u.uData[1];
+					uRxSpanning = pIoCtrl->u.uData[2];
+					DPI[uPort].byDisableSpanningTreeLearn = pIoCtrl->u.uData[3];
+					if (uTxSpanning) {
+						if (uRxSpanning)
+							DPI[uPort].bySpanningTree = SW_SPANNINGTREE_ALL;
+						else
+							DPI[uPort].bySpanningTree = SW_SPANNINGTREE_TX;
+					}
+					else {
+						if (uRxSpanning)
+							DPI[uPort].bySpanningTree = SW_SPANNINGTREE_RX;
+						else
+							DPI[uPort].bySpanningTree = SW_SPANNINGTREE_NONE;
+					}
+					swConfigurePort(Adapter, uPort);
+				}
+				else {
+					uTxSpanning = uRxSpanning = FALSE;
+					if (SW_SPANNINGTREE_ALL == DPI[uPort].bySpanningTree) {
+						uTxSpanning = uRxSpanning = TRUE;
+					}
+					else if (SW_SPANNINGTREE_TX == DPI[uPort].bySpanningTree) {
+						uTxSpanning = TRUE;
+					}
+					else if (SW_SPANNINGTREE_RX == DPI[uPort].bySpanningTree) {
+						uRxSpanning = TRUE;
+					}
+					pIoCtrl->u.uData[1] = uTxSpanning;
+					pIoCtrl->u.uData[2] = uRxSpanning;
+					pIoCtrl->u.uData[3] = (uint32_t)DPI[uPort].byDisableSpanningTreeLearn;
+				}
+				nRet = 0;
+			}
+			break;
+			
+#ifdef	CONFIG_ARCH_KS8695P
+		case CONFIG_SW_SUBID_PHY_IF:
+			if (pIoCtrl->usLen == 24) { /* 1 + 2 + 1 + 4 + 4 * 4 */
+				u32	off, shift = 0;
+
+				uPort = pIoCtrl->u.uData[0];
+				if (DMA_WAN == DI.usDMAId)
+					uPort = 0;
+				if (uPort > SW_MAX_LAN_PORTS) {
+					DRV_WARN("%s> LAN port out of range (%d)", __FUNCTION__, uPort);
+					break;
+				}
+				if (uPort == SW_MAX_LAN_PORTS)
+					off = KS8695_WAN_POWERMAGR;
+				else {
+					if (uPort < 2)
+						off = KS8695_LPPM12;
+					else
+						off = KS8695_LPPM34;
+				}
+				if (!(uPort % 2))
+					shift = 1;
+				uReg = KS8695_READ_REG(off);
+				if (CONFIG_SWITCH_SET == pIoCtrl->byId) {
+					enablePhyLoopback(Adapter, uPort, pIoCtrl->u.uData[1]);
+					enableRemoteLoopback(Adapter, uPort, pIoCtrl->u.uData[2]);
+					enablePhyIsolate(Adapter, uPort, pIoCtrl->u.uData[3]);
+					forcePhyLink(Adapter, uPort, pIoCtrl->u.uData[4]);
+				}
+				else {
+					pIoCtrl->u.uData[1] = (uReg & (KS8695_LPPM_PHY_LOOPBACK << (shift * 16))) ? 1 : 0;
+					pIoCtrl->u.uData[2] = (uReg & (KS8695_LPPM_RMT_LOOPBACK << (shift * 16))) ? 1 : 0;
+					pIoCtrl->u.uData[3] = (uReg & (KS8695_LPPM_PHY_ISOLATE << (shift * 16))) ? 1 : 0;
+					pIoCtrl->u.uData[4] = (uReg & (KS8695_LPPM_FORCE_LINK << (shift * 16))) ? 1 : 0;
+				}
+				nRet = 0;
+			}
+			break;
+
+		case CONFIG_SW_SUBID_SEC1:
+			if (pIoCtrl->usLen == 36) { /* 1 + 2 + 1 + 4 * 8 */
+				uReg = KS8695_READ_REG(KS8695_SEC1);
+				if (CONFIG_SWITCH_SET == pIoCtrl->byId) {
+					if (pIoCtrl->u.uData[0])
+						uReg |= KS8695_SEC1_NO_IEEE_AN;
+					else
+						uReg &= ~KS8695_SEC1_NO_IEEE_AN;
+					if (pIoCtrl->u.uData[1])
+						uReg |= KS8695_SEC1_TPID_MODE;
+					else
+						uReg &= ~KS8695_SEC1_TPID_MODE;
+					if (pIoCtrl->u.uData[2])
+						uReg |= KS8695_SEC1_NO_TX_8021X_FLOW_CTRL;
+					else
+						uReg &= ~KS8695_SEC1_NO_TX_8021X_FLOW_CTRL;
+					if (pIoCtrl->u.uData[3])
+						uReg |= KS8695_SEC1_NO_RX_8021X_FLOW_CTRL;
+					else
+						uReg &= ~KS8695_SEC1_NO_RX_8021X_FLOW_CTRL;
+					if (pIoCtrl->u.uData[4])
+						uReg |= KS8695_SEC1_HUGE_PACKET;
+					else
+						uReg &= ~KS8695_SEC1_HUGE_PACKET;
+					if (pIoCtrl->u.uData[5])
+						uReg |= KS8695_SEC1_8021Q_VLAN_EN;
+					else
+						uReg &= ~KS8695_SEC1_8021Q_VLAN_EN;
+					if (pIoCtrl->u.uData[6])
+						uReg |= KS8695_SEC1_MII_10BT;
+					else
+						uReg &= ~KS8695_SEC1_MII_10BT;
+					if (pIoCtrl->u.uData[7])
+						uReg |= KS8695_SEC1_NULL_VID;
+					else
+						uReg &= ~KS8695_SEC1_NULL_VID;
+					KS8695_WRITE_REG(KS8695_SEC1, uReg);
+					DelayInMicroseconds(10);
+				}
+				else {
+					pIoCtrl->u.uData[0] = (uReg & KS8695_SEC1_NO_IEEE_AN) ? 1 : 0;
+					pIoCtrl->u.uData[1] = (uReg & KS8695_SEC1_TPID_MODE) ? 1 : 0;
+					pIoCtrl->u.uData[2] = (uReg & KS8695_SEC1_NO_TX_8021X_FLOW_CTRL) ? 1 : 0;
+					pIoCtrl->u.uData[3] = (uReg & KS8695_SEC1_NO_RX_8021X_FLOW_CTRL) ? 1 : 0;
+					pIoCtrl->u.uData[4] = (uReg & KS8695_SEC1_HUGE_PACKET) ? 1 : 0;
+					pIoCtrl->u.uData[5] = (uReg & KS8695_SEC1_8021Q_VLAN_EN) ? 1 : 0;
+					pIoCtrl->u.uData[6] = (uReg & KS8695_SEC1_MII_10BT) ? 1 : 0;
+					pIoCtrl->u.uData[7] = (uReg & KS8695_SEC1_NULL_VID) ? 1 : 0;
+				}
+				nRet = 0;
+			}
+			break;
+
+		case CONFIG_SW_SUBID_GENERIC_DUMP:
+			if (pIoCtrl->usLen == 8) { /* 1 + 2 + 1 + 4 */
+				int i;
+
+				switch (pIoCtrl->u.uData[0]) {
+					case GENERIC_DUMP_DYNAMIC:
+						dumpDynamicMacTable(Adapter);
+						nRet = 0;
+						break;
+
+					case GENERIC_DUMP_SWITCH_REGS:
+						printk("--Reg--   ---Value--\n");
+						for (i = KS8695_SEC0; i <= KS8695_LPPM34; i += 4) {
+							printk(" 0x%04x   0x%08x\n", i, KS8695_READ_REG(i));
+						}
+						nRet = 0;
+						break;
+
+					case GENERIC_DUMP_STATIC:
+						dumpStaticMacTable(Adapter);
+						nRet = 0;
+						break;
+
+					default:
+					case GENERIC_DUMP_VLAN:
+						DRV_INFO("%s> not implemented yet", __FUNCTION__);
+						break;
+				};
+			}
+			break;
+
+		case CONFIG_SW_SUBID_RATE_CTRL:
+			if (pIoCtrl->usLen == 32) { /* 1 + 2 + 4 * 7 */
+				u32	off, tx, v1 = 0;
+
+				uPort = pIoCtrl->u.uData[0];
+				if (DMA_WAN == DI.usDMAId)
+					uPort = 0;
+				if (uPort > SW_MAX_LAN_PORTS) {
+					DRV_WARN("%s> LAN port out of range (%d)", __FUNCTION__, uPort);
+					break;
+				}
+				tx = pIoCtrl->u.uData[1];
+				if (uPort == SW_MAX_LAN_PORTS) {
+					off = KS8695_SEP5C3;
+					if (tx) v1 = KS8695_READ_REG(KS8695_SEP5C2);
+				} else {
+					off = KS8695_SEP1C3 + uPort * 0x0c;
+					if (tx) v1 = KS8695_READ_REG(KS8695_SEP1C2 + uPort * 0x0c);
+				}
+				uReg = KS8695_READ_REG(off);
+				if (CONFIG_SWITCH_SET == pIoCtrl->byId) {
+					if (tx) {
+						setTxRate(Adapter, uPort, pIoCtrl->u.uData[2], pIoCtrl->u.uData[3]);
+						enableTxRateControl(Adapter, uPort, pIoCtrl->u.uData[4], pIoCtrl->u.uData[5], pIoCtrl->u.uData[6]);
+					}
+					else {
+						setRxRate(Adapter, uPort, pIoCtrl->u.uData[2], pIoCtrl->u.uData[3]);
+						enableRxRateControl(Adapter, uPort, pIoCtrl->u.uData[4], pIoCtrl->u.uData[5], pIoCtrl->u.uData[6]);
+					}
+				}
+				else {
+					if (tx) {
+						pIoCtrl->u.uData[2] = (v1 & KS8695_SEPC2_TX_L_RATECTRL_MASK);
+						pIoCtrl->u.uData[3] = ((v1 & KS8695_SEPC2_TX_H_RATECTRL_MASK) >> 12);
+						pIoCtrl->u.uData[4] = (uReg & KS8695_SEPC3_TX_DIF_RATECTRL_EN) ? 1 : 0;
+						pIoCtrl->u.uData[5] = (uReg & KS8695_SEPC3_TX_L_RATECTRL_EN) ? 1 : 0;
+						pIoCtrl->u.uData[6] = (uReg & KS8695_SEPC3_TX_H_RATECTRL_EN) ? 1 : 0;
+					}
+					else {
+						pIoCtrl->u.uData[2] = ((uReg & KS8695_SEPC3_RX_L_RATECTRL_MASK) >> 8);
+						pIoCtrl->u.uData[3] = ((uReg & KS8695_SEPC3_RX_H_RATECTRL_MASK) >> 20);
+						pIoCtrl->u.uData[4] = (uReg & KS8695_SEPC3_RX_DIF_RATECTRL_EN) ? 1 : 0;
+						pIoCtrl->u.uData[5] = (uReg & KS8695_SEPC3_RX_L_RATECTRL_EN) ? 1 : 0;
+						pIoCtrl->u.uData[6] = (uReg & KS8695_SEPC3_RX_H_RATECTRL_EN) ? 1 : 0;
+					}
+				}
+				nRet = 0;
+			}
+			break;
+#endif
+
+		default:
+			DRV_INFO("%s> unsupported parameters: id=%d, len=%d", __FUNCTION__, pIoCtrl->byId, pIoCtrl->usLen);
+			return -EOPNOTSUPP;
+	}
+
+	return nRet;
+}
+
+#ifdef	__KS8695_CACHE_H
+/*
+ * ks8695_icache_lock
+ *	This function is use to lock given icache
+ *
+ * Argument(s)
+ *	icache_start	pointer to starting icache address
+ *	icache_end		pointer to ending icache address
+ *
+ * Return(s)
+ *	0		if success
+ *	error	otherwise
+ */
+int ks8695_icache_lock2(void *icache_start, void *icache_end)
+{
+	uint32_t victim_base = ICACHE_VICTIM_BASE << ICACHE_VICTIM_INDEX;
+	spinlock_t	lock = SPIN_LOCK_UNLOCKED;
+	unsigned long flags;
+#ifdef	DEBUG_THIS
+	int	len;
+
+	len = (int)(icache_end - icache_start);
+	DRV_INFO("%s: start=%p, end=%p, len=%d", __FUNCTION__, icache_start, icache_end, len);
+	/* if lockdown lines are more than half of max associtivity */
+	if ((len / ICACHE_BYTES_PER_LINE) > (ICACHE_ASSOCITIVITY >> 1)) {
+		DRV_WARN("%s: lockdown lines = %d is too many, (Assoc=%d)", __FUNCTION__, (len / ICACHE_BYTES_PER_LINE), ICACHE_ASSOCITIVITY);
+		return -1;
+	}
+#endif
+
+	spin_lock_irqsave(&lock, flags);
+	
+	__asm__(
+		" \n\
+		ADRL	r0, ks8695_isr		/* compile complains if icache_start is given instead */ \n\
+		ADRL	r1, ks8695_isre		/* compile complains if icache_end is given instead */ \n\
+		MOV	r2, %0 \n\
+		MCR	p15, 0, r2, c9, c4, 1 \n\
+ \n\
+lock_loop: \n\
+		MCR	p15, 0, r0, c7, c13, 1 \n\
+		ADD	r0, r0, #32 \n\
+ \n\
+		AND	r3, r0, #0x60 \n\
+		CMP	r3, #0x0 \n\
+		ADDEQ	r2, r2, #0x1<<26		/* ICACHE_VICTIM_INDEX */ \n\
+		MCREQ	p15, 0, r2, c9, c0, 1 \n\
+		  \n\
+		CMP	r0, r1 \n\
+		BLE	lock_loop \n\
+ \n\
+		CMP	r3, #0x0 \n\
+		ADDNE	r2, r2, #0x1<<26		/* ICACHE_VICTIM_INDEX */ \n\
+		MCRNE	p15, 0, r2, c9, c0,	1 \n\
+		"
+		:
+		: "r" (victim_base)
+		: "r0", "r1", "r2", "r3"
+	);
+
+#ifdef	DEBUG_THIS
+	ks8695_icache_read_c9();
+#endif
+
+	spin_unlock_irqrestore(&lock, flags);
+
+	return 0;
+}
+#endif /*__KS8695_CACHE_H*/
+
+#ifdef	RX_TASK
+/*
+ * ReceiveProcessTask
+ *	This function is use to process Rx interrupt, send received data up
+ *	the network stack. 
+ *
+ * Argument(s)
+ *	data		pointer to ADAPTER_STRUCT structure.
+ *
+ * Return(s)
+ *	NONE
+ */
+static void ReceiveProcessTask(uintptr_t data)
+{
+	PADAPTER_STRUCT Adapter = (PADAPTER_STRUCT)data;
+	UINT32 uFrameCtrl;
+	RXDESC *CurrentDescriptor;
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s> )", __FUNCTION__); 
+#endif
+
+	/* 
+         * Process receive packet by call ProcessRxInterrupts() 
+	*/ 
+	ProcessRxInterrupts(Adapter);
+
+	/* 
+         * if there are pending rx interrupt, reschedule rx task again 
+	*/
+	CurrentDescriptor = &DI.pRxDescriptors[DI.nRxDescNextAvail];
+	uFrameCtrl = CurrentDescriptor->RxFrameControl; 
+	if  (!(uFrameCtrl & DESC_OWN_BIT)) 
+    	{
+#ifdef	TX_TASK
+		if (DI.nTransmitCount > (DI.nTxDescTotal >> 1)) {
+			/* try eanble read transfer again */
+			KS8695_WRITE_REG(REG_TXSTART + DI.nOffset, 1);
+			if (FALSE == DI.tx_scheduled) {
+				DI.tx_scheduled = TRUE;
+				tasklet_hi_schedule(&DI.tx_tasklet);
+			}
+		}
+#endif
+		tasklet_hi_schedule(&DI.rx_tasklet);
+	}	
+	else 
+    	{
+		DI.rx_scheduled = FALSE;
+		/* enable corresponding Rx Interrupt again */
+		KS8695_WRITE_REG(KS8695_INT_ENABLE, KS8695_READ_REG(KS8695_INT_ENABLE) | 
+			((uint32_t)INT_RX_BIT << DI.uIntShift));
+	}
+}
+
+#endif /*RX_TASK*/
+
+#ifdef	TX_TASK
+/*
+ * TransmitProcessTask
+ *	This function is use to process Tx interrupt in task level, reclaim resources after 
+ *	transmit completed.
+ *
+ * Argument(s)
+ *	data		pointer to ADAPTER_STRUCT structure.
+ *
+ * Return(s)
+ *	NONE.
+ */
+static void TransmitProcessTask(uintptr_t data)
+{
+	PADAPTER_STRUCT Adapter = (PADAPTER_STRUCT)data;
+
+
+#ifdef	DEBUG_THIS
+	DRV_INFO("%s> )", __FUNCTION__); 
+#endif
+
+	/* 
+     * Process free transmit data buffer by call ProcessTxInterrupts() 
+     */ 
+	ProcessTxInterrupts(Adapter);
+
+
+	/* 
+     * if there are pending tx interrupt, reschedule tx task again 
+     */
+#ifndef	USE_TX_UNAVAIL
+	if (KS8695_READ_REG(KS8695_INT_STATUS) & ((uint32_t)INT_TX_BIT << DI.uIntShift)) {
+#else
+	if (KS8695_READ_REG(KS8695_INT_STATUS) & 
+		((uint32_t)(INT_TX_BIT | INT_TX_UNAVAIL_BIT) << DI.uIntShift) & DI.uIntMask) {
+#endif
+		/* Acknowledge the transmit interrupt let this routine becomes
+		 * an infinite loop.
+		 */
+		KS8695_WRITE_REG( KS8695_INT_STATUS,
+			( uint32_t ) INT_TX_BIT << DI.uIntShift );
+		tasklet_hi_schedule(&DI.tx_tasklet);
+	}	
+	else 
+    {
+		DI.tx_scheduled = FALSE;
+		/* enable corresponding Tx Interrupt again */
+#ifndef	USE_TX_UNAVAIL
+		KS8695_WRITE_REG(KS8695_INT_ENABLE, KS8695_READ_REG(KS8695_INT_ENABLE) | 
+			((uint32_t)INT_TX_BIT << DI.uIntShift));
+#else
+		KS8695_WRITE_REG(KS8695_INT_ENABLE, KS8695_READ_REG(KS8695_INT_ENABLE) | 
+			((uint32_t)(INT_TX_BIT | INT_TX_UNAVAIL_BIT) << DI.uIntShift) & DI.uIntMask);
+#endif
+	}
+
+
+
+}
+#endif /*TX_TASK*/
+
+/* ks8695_main.c */
diff -urN linux-2.4.29/drivers/net/ks8695/Makefile linux-2.4.29-uc1/drivers/net/ks8695/Makefile
--- linux-2.4.29/drivers/net/ks8695/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/ks8695/Makefile	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,20 @@
+#
+# Makefile for the Tulip ethernet driver
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+O_TARGET := ks8695e.o
+
+obj-y   := ks8695_main.o ks8695_fxhw.o ks8695_cache.o
+obj-m   := $(O_TARGET)
+
+#EXTRA_CFLAGS += -I. -DPCI -DMEM_MAPPED_IO -Wno-strict-prototypes 
+EXTRA_CFLAGS += -DRX_TASK -DTX_TASK -I. -DARM_LINUX -DEXPORT_SYMTAB -Wno-strict-prototypes 
+include $(TOPDIR)/Rules.make
+
+clean:
+	rm -f core *.o 
diff -urN linux-2.4.29/drivers/net/linuxfet.c linux-2.4.29-uc1/drivers/net/linuxfet.c
--- linux-2.4.29/drivers/net/linuxfet.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/linuxfet.c	2005-06-14 02:12:15.000000000 +0100
@@ -0,0 +1,3002 @@
+
+/*
+**
+**
+**  VIA Technologies, Inc.              
+**
+**  Fast Ethernet Adapter
+**
+**  Linux Driver
+**
+**  v3.28  Nov. 2001
+**
+**
+*/
+
+/* These identify the driver base version and may not be removed. */
+static const char version[] = "linuxfet.c : v3.28 11/15/2001\n";
+
+#include "linuxfet.h"
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+static void *via_probe1(struct pci_dev *pdev, void *init_dev, unsigned long ioaddr, int irq, int chip_idx, int find_cnt, u32 revision);
+static int  pci_drv_register(drv_id_info *drv_id, void *initial_device);
+static void pci_drv_unregister(drv_id_info *drv_id);
+static void VLAN_tagging(struct net_device *dev);
+static void turn_on_MII_link(struct net_device *dev);
+static int  pci_find(struct pci_dev *pdev, int findtype);
+static int  acpi_wake(struct pci_dev *pdev);
+static int init_device_data(struct net_device *dev, struct pci_dev *pdev, unsigned long ioaddr, u32 revision, int irq, int chip_idx, int card_idx);
+static void SafeDisableMiiAuto(struct net_device *dev);
+static unsigned int  mdio_read(struct net_device *dev, int phy_id, int location);
+static void mdio_write(struct net_device *dev, int phy_id, int location, unsigned int value);
+//static void CAM_data_read(struct net_device *dev, int select_CAM, unsigned char CAM_address, unsigned char *value);
+static void CAM_data_write(struct net_device *dev, int select_CAM, unsigned char CAM_address, unsigned char *value);
+//static unsigned int CAM_mask_read(struct net_device *dev, int select_CAM);
+static void CAM_mask_write(struct net_device *dev, int select_CAM, unsigned int mask);
+//static void netdev_reset(struct net_device *dev);
+static int  netdev_open(struct net_device *dev);
+static void set_flow_control(struct net_device *dev);
+static void flow_control_ability(struct net_device *dev);
+static void set_media_duplex_mode(struct net_device *dev);
+static void restart_autonegotiation(struct net_device *dev);
+static void enable_autonegotiation(struct net_device *dev);
+static void check_legacy_force(struct net_device *dev);
+static int check_n_way_force(struct net_device *dev, int change_flag);
+static void do_autonegotiation(struct net_device *dev);
+//static void netdev_timer(unsigned long data);
+//static void tx_timeout(struct net_device *dev);
+static void init_ring(struct net_device *dev);
+static int  start_tx(struct sk_buff *skb, struct net_device *dev);
+static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+static int  netdev_rx(struct net_device *dev);
+static void  netdev_tx(struct net_device *dev);
+static void netdev_error(struct net_device *dev, int intr_status);
+static void set_rx_mode(struct net_device *dev);
+static struct net_device_stats *get_stats(struct net_device *dev);
+static int  mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int  netdev_close(struct net_device *dev);
+static void checksum_offload(struct sk_buff *skb, u32 rx_PQSTS);
+int (*register_cb_hook)(drv_id_info *did);
+void (*unregister_cb_hook)(drv_id_info *did);
+
+static int	debug = 3;			/* 1 normal messages, 0 quiet .. 7 verbose. */
+
+
+static int	min_pci_latency = 32;
+
+
+/* The user-configurable values.
+   These may be modified when a driver module is loaded.*/   
+static int	max_interrupt_work = 20;
+
+/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
+   Setting to > 1518 effectively disables this feature. */
+static int	rx_copybreak = 0;
+
+#define	MAX_UNITS 8     /* More are supported, limit only on speed_duplex */
+
+/* speed_duplex[] is used for setting the speed and duplex mode of NIC.
+   0: indicate autonegotiation for both speed and duplex mode
+   1: indicate 100Mbps half duplex mode
+   2: indicate 100Mbps full duplex mode
+   3: indicate 10Mbps half duplex mode
+   4: indicate 10Mbps full duplex mode
+*/
+static int      speed_duplex[MAX_UNITS]= {0, 0, 0, 0, 0, 0, 0, 0};
+
+/* enable_tagging[] is used for enabling VID setting.
+   0: disable VID seeting(default).
+   1: enable VID setting.
+*/
+static int      enable_tagging[MAX_UNITS]={0, 0, 0, 0, 0, 0, 0, 0};
+
+/* VID_setting[] is used for setting the VID of NIC.
+   0: default VID.
+   1-4094: other VIDs.
+*/
+static int      VID_setting[MAX_UNITS]={0, 0, 0, 0, 0, 0, 0, 0};
+
+/* csum_offload[] is used for setting the checksum offload ability of NIC.
+   0: disable csum_offload[checksum offload(default).
+   1: enable checksum offload. (We only support RX checksum offload now)
+*/
+static int      csum_offload[MAX_UNITS]={0, 0, 0, 0, 0, 0, 0, 0};
+
+/* flow_control[] is used for setting the flow control ability of NIC.
+   1: hardware deafult(default). Use Hardware default value in ANAR.
+   2: disable PAUSE in ANAR.
+   3: enable PAUSE in ANAR.
+*/
+static int      flow_control[MAX_UNITS]={1, 1, 1, 1, 1, 1, 1, 1};
+
+/* IP_byte_align[] is used for IP header DWORD byte aligned
+   0: indicate the IP header won't be DWORD byte aligned.(Default) .
+   1: indicate the IP header will be DWORD byte aligned.
+      In some enviroment, the IP header should be DWORD byte aligned,
+      or the packet will be droped when we receive it. (eg: IPVS)
+*/
+static int	IP_byte_align[MAX_UNITS] = {0, 0, 0, 0, 0, 0, 0, 0};
+
+/* tx_thresh[] is used for controlling the transmit fifo threshold.
+   0: indicate the txfifo threshold is 128 bytes.
+   1: indicate the txfifo threshold is 256 bytes.
+   2: indicate the txfifo threshold is 512 bytes.
+   3: indicate the txfifo threshold is 1024 bytes.
+   4: indicate that we use store and forward
+*/
+static int	tx_thresh[MAX_UNITS] = {0, 0, 0, 0, 0, 0, 0, 0};
+
+/* rx_thresh[] is used for controlling the receive fifo threshold.
+   0: indicate the rxfifo threshold is 64 bytes.
+   1: indicate the rxfifo threshold is 32 bytes.
+   2: indicate the rxfifo threshold is 128 bytes.
+   3: indicate the rxfifo threshold is 256 bytes.
+   4: indicate the rxfifo threshold is 512 bytes.
+   5: indicate the rxfifo threshold is 768 bytes.
+   6: indicate the rxfifo threshold is 1024 bytes.   
+   7: indicate that we use store and forward
+*/
+static int	rx_thresh[MAX_UNITS] = {0, 0, 0, 0, 0, 0, 0, 0};
+
+/* DMA_length[] is used for controlling the DMA length
+   0: 8 DWORDs
+   1: 16 DWORDs
+   2: 32 DWORDs
+   3: 64 DWORDs
+   4: 128 DWORDs
+   5: 256 DWORDs
+   6: SF(flush till emply)
+   7: SF(flush till emply)
+*/
+static int	DMA_length[MAX_UNITS] = {1, 1, 1, 1, 1, 1, 1, 1};
+
+/* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
+   The Rhine has a 64 element 8390-like hash table.  */
+static const int	multicast_filter_limit = 32;
+
+pci_id_info pci_tbl[] = {
+    {"VIA VT86C100A Fast Ethernet Adapter                         ", 
+        {0x30431106, 0xffffffff, 0x01001106, 0xffffffff, },
+        RHINE_IOTYPE, 128, FET_CanHaveMII | FET_ReqTxAlign | FET_HasDavicomPhy},
+    {"VIA PCI 10/100Mb Fast Ethernet Adapter                      ",
+        {0x30651106, 0xffffffff, 0x01021106, 0xffffffff, },
+        RHINE_IOTYPE, RHINEII_IOSIZE, FET_CanHaveMII | FET_HasWOL },
+    {"VIA VT6105 Rhine III Management Adapter                     ",
+        {0x31061106, 0xffffffff, 0x01051106, 0xffffffff, },
+        RHINE_IOTYPE, RHINEII_IOSIZE, FET_CanHaveMII | FET_HasWOL },
+    {0,},						/* 0 terminated list. */
+};
+
+
+drv_id_info via_rhine_drv_id = {
+    "linuxfet", 0, PCI_CLASS_NETWORK_ETHERNET<<8, pci_tbl, via_probe1,};
+/* Offsets to the device registers.
+*/
+
+
+#if LINUX_VERSION_CODE > 0x20118  &&  defined(MODULE)
+MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
+MODULE_DESCRIPTION("PCI 10/100Mb Fast Ethernet Adapter");
+MODULE_PARM(debug, "i");
+MODULE_PARM(min_pci_latency, "i");
+MODULE_PARM(max_interrupt_work, "i");
+MODULE_PARM(rx_copybreak, "i");
+MODULE_PARM(speed_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(VID_setting, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(csum_offload, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(enable_tagging, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(flow_control, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(IP_byte_align, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(tx_thresh, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(rx_thresh, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(DMA_length, "1-" __MODULE_STRING(MAX_UNITS) "i");
+
+#endif
+
+
+/* A list of our installed devices, for removing the driver module. */
+static struct net_device *root_net_dev = NULL;
+
+#if (LINUX_VERSION_CODE >= 0x20200)
+/* Grrrr.. complex abstaction layers with negative benefit. */
+static int pci_drv_register(drv_id_info *drv_id, void *initial_device)
+{
+	int chip_idx, cards_found = 0;
+	struct pci_dev *pdev = NULL;
+	pci_id_info *pci_tbl = drv_id->pci_dev_tbl;
+	void *newdev;
+        u32 revision;
+
+	while ((pdev = pci_find_class(drv_id->pci_class, pdev)) != 0) {
+		u32 pci_id, pci_subsys_id, pci_class_rev;
+		u16 pci_command, new_command;
+		int pci_flags;
+		long pciaddr;			/* Bus address. */
+		unsigned long ioaddr;			/* Mapped address for this processor. */
+                
+		pci_read_config_dword(pdev, PCI_VENDOR_ID, &pci_id);
+		/* Offset 0x2c is PCI_SUBSYSTEM_ID aka PCI_SUBSYSTEM_VENDOR_ID. */
+		pci_read_config_dword(pdev, 0x2c, &pci_subsys_id);
+		pci_read_config_dword(pdev, PCI_REVISION_ID, &pci_class_rev);
+                
+                revision = (pci_class_rev << 24) >> 24;
+		if (debug > 3)
+			printk(KERN_DEBUG "PCI ID %8.8x subsystem ID is %8.8x.\n",
+				   pci_id, pci_subsys_id);
+		for (chip_idx = 0; pci_tbl[chip_idx].name; chip_idx++) {
+			pci_id_info *chip = &pci_tbl[chip_idx];
+			if ((pci_id & chip->id.pci_mask) == chip->id.pci
+				&& (pci_subsys_id&chip->id.subsystem_mask) == chip->id.subsystem
+				&& (pci_class_rev&chip->id.revision_mask) == chip->id.revision)
+				break;
+		}
+		if (pci_tbl[chip_idx].name == 0) 		/* Compiled out! */
+			continue;
+
+		pci_flags = pci_tbl[chip_idx].pci_flags;
+#if (LINUX_VERSION_CODE >= 0x02030c)
+		/* Wow. A oversized, hard-to-use abstraction. Bogus. */
+		pciaddr = pdev->resource[(pci_flags >> 4) & 7].start;
+                ioaddr = pci_resource_start(pdev, 0);
+
+#else /* LINUX_VERSION_CODE >= 0x20200 */
+		pciaddr = pdev->base_address[(pci_flags >> 4) & 7];
+#if defined(__alpha__)			/* Really any machine with 64 bit addressing. */
+		if (pci_flags & FET_PCI_ADDR_64BITS)
+			pciaddr |= ((long)pdev->base_address[((pci_flags>>4)&7)+ 1]) << 32;
+#endif /* defined(__alpha__) */
+
+		if (debug > 3)
+			printk(KERN_INFO "Found %s at PCI address %#lx, mapped IRQ %d.\n",
+				   pci_tbl[chip_idx].name, pciaddr, pdev->irq);
+
+		if ((pciaddr & PCI_BASE_ADDRESS_SPACE_IO)) {
+			ioaddr = pciaddr & PCI_BASE_ADDRESS_IO_MASK;
+			if (check_region(ioaddr, pci_tbl[chip_idx].io_size))
+				continue;
+		} else if ((ioaddr = (long)ioremap(pciaddr & PCI_BASE_ADDRESS_MEM_MASK,
+										   pci_tbl[chip_idx].io_size)) == 0) {
+			printk(KERN_INFO "Failed to map PCI address %#lx for device "
+				   "'%s'.\n", pciaddr, pci_tbl[chip_idx].name);
+			continue;
+		}
+#endif /* LINUX_VERSION_CODE >= 0x20200 */
+		if ( ! (pci_flags & FET_PCI_NO_ACPI_WAKE))
+			acpi_wake(pdev);
+		pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
+		new_command = pci_command | (pci_flags & 7);
+		if (pci_command != new_command) {
+			printk(KERN_INFO "  The PCI BIOS has not enabled the"
+				   " device at %d/%d!  Updating PCI command %4.4x->%4.4x.\n",
+				   pdev->bus->number, pdev->devfn, pci_command, new_command);
+			pci_write_config_word(pdev, PCI_COMMAND, new_command);
+		}
+
+		newdev = drv_id->probe1(pdev, initial_device,
+								ioaddr, pdev->irq, chip_idx, cards_found, revision);
+		if (newdev  && (pci_flags & PCI_COMMAND_MASTER))
+			pci_set_master(pdev);
+		if (newdev  && (pci_flags & PCI_COMMAND_MASTER)  &&
+			! (pci_flags & FET_PCI_NO_MIN_LATENCY)) {
+			u8 pci_latency;
+			pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
+			if (pci_latency < min_pci_latency) {
+				printk(KERN_INFO "  PCI latency timer (CFLT) is "
+					   "unreasonably low at %d.  Setting to %d clocks.\n",
+					   pci_latency, min_pci_latency);
+				pci_write_config_byte(pdev, PCI_LATENCY_TIMER, min_pci_latency);
+			}
+		}
+		initial_device = 0;
+		cards_found++;
+	}
+
+	if ((drv_id->flags & FET_PCI_HOTSWAP)
+		&& register_cb_hook
+		&& (*register_cb_hook)(drv_id) == 0) {
+		MOD_INC_USE_COUNT;
+		return 0;
+	} else
+		return cards_found ? 0 : -ENODEV;
+}
+#else /* LINUX_VERSION_CODE >= 0x20200 */
+static int pci_drv_register(drv_id_info *drv_id, void *initial_device)
+{
+	int pci_index, cards_found = 0;
+	unsigned char pci_bus, pci_device_fn;
+	struct pci_dev *pdev;
+	pci_id_info *pci_tbl = drv_id->pci_dev_tbl;
+	void *newdev;
+        u32 revision;
+
+	if ( ! pcibios_present())
+		return -ENODEV;
+
+	for (pci_index = 0; pci_index < 0xff; pci_index++) {
+		u32 pci_id, subsys_id, pci_class_rev;
+		u16 pci_command, new_command;
+		int chip_idx, irq, pci_flags;
+		long pciaddr;
+		unsigned long ioaddr;
+		u32 pci_busaddr;
+		u8 pci_irq_line;
+
+		if (pcibios_find_class (drv_id->pci_class, pci_index,
+								&pci_bus, &pci_device_fn)
+			!= PCIBIOS_SUCCESSFUL)
+			break;
+		pcibios_read_config_dword(pci_bus, pci_device_fn,
+								  PCI_VENDOR_ID, &pci_id);
+		/* Offset 0x2c is PCI_SUBSYSTEM_ID aka PCI_SUBSYSTEM_VENDOR_ID. */
+		pcibios_read_config_dword(pci_bus, pci_device_fn, 0x2c, &subsys_id);
+		pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_REVISION_ID, &pci_class_rev);
+
+		for (chip_idx = 0; pci_tbl[chip_idx].name; chip_idx++) {
+			pci_id_info *chip = &pci_tbl[chip_idx];
+			if ((pci_id & chip->id.pci_mask) == chip->id.pci
+				&& (subsys_id & chip->id.subsystem_mask) == chip->id.subsystem
+				&& (pci_class_rev&chip->id.revision_mask) == chip->id.revision)
+				break;
+		}
+		if (pci_tbl[chip_idx].name == 0) 		/* Compiled out! */
+			continue;
+
+		pci_flags = pci_tbl[chip_idx].pci_flags;
+		pdev = pci_find_slot(pci_bus, pci_device_fn);
+		pcibios_read_config_byte(pci_bus, pci_device_fn,
+								 PCI_INTERRUPT_LINE, &pci_irq_line);
+		irq = pci_irq_line;
+		pcibios_read_config_dword(pci_bus, pci_device_fn,
+								  ((pci_flags >> 2) & 0x1C) + 0x10,
+								  &pci_busaddr);
+		pciaddr = pci_busaddr;
+#if defined(__alpha__)
+		if (pci_flags & FET_PCI_ADDR_64BITS) {
+			pcibios_read_config_dword(pci_bus, pci_device_fn,
+									  ((pci_flags >> 2) & 0x1C) + 0x14,
+									  &pci_busaddr);
+			pciaddr |= ((long)pci_busaddr)<<32;
+		}
+#endif /* defined(__alpha__) */
+
+		if (debug > 3)
+			printk(KERN_INFO "Found %s at PCI address %#lx, IRQ %d.\n",
+				   pci_tbl[chip_idx].name, pciaddr, irq);
+
+		if ((pciaddr & PCI_BASE_ADDRESS_SPACE_IO)) {
+			ioaddr = pciaddr & PCI_BASE_ADDRESS_IO_MASK;
+			if (check_region(ioaddr, pci_tbl[chip_idx].io_size))
+				continue;
+		} else if ((ioaddr = (long)ioremap(pciaddr & PCI_BASE_ADDRESS_MEM_MASK,
+										   pci_tbl[chip_idx].io_size)) == 0) {
+			printk(KERN_INFO "Failed to map PCI address %#lx.\n",
+				   pciaddr);
+			continue;
+		}
+
+		if ( ! (pci_flags & FET_PCI_NO_ACPI_WAKE))
+			acpi_wake(pdev);
+		pcibios_read_config_word(pci_bus, pci_device_fn,
+								 PCI_COMMAND, &pci_command);
+		new_command = pci_command | (pci_flags & 7);
+		if (pci_command != new_command) {
+			printk(KERN_INFO "  The PCI BIOS has not enabled the"
+				   " device at %d/%d!  Updating PCI command %4.4x->%4.4x.\n",
+				   pci_bus, pci_device_fn, pci_command, new_command);
+			pcibios_write_config_word(pci_bus, pci_device_fn,
+									  PCI_COMMAND, new_command);
+		}
+
+		newdev = drv_id->probe1(pdev, initial_device,
+							   ioaddr, irq, chip_idx, cards_found, revision);
+
+		if (newdev  && (pci_flags & PCI_COMMAND_MASTER)  &&
+			! (pci_flags & FET_PCI_NO_MIN_LATENCY)) {
+			u8 pci_latency;
+			pcibios_read_config_byte(pci_bus, pci_device_fn,
+									 PCI_LATENCY_TIMER, &pci_latency);
+			if (pci_latency < min_pci_latency) {
+				printk(KERN_INFO "  PCI latency timer (CFLT) is "
+					   "unreasonably low at %d.  Setting to %d clocks.\n",
+					   pci_latency, min_pci_latency);
+				pcibios_write_config_byte(pci_bus, pci_device_fn,
+										  PCI_LATENCY_TIMER, min_pci_latency);
+			}
+		}
+		initial_device = 0;
+		cards_found++;
+	}
+
+	if ((drv_id->flags & FET_PCI_HOTSWAP)
+		&& register_cb_hook
+		&& (*register_cb_hook)(drv_id) == 0) {
+		MOD_INC_USE_COUNT;
+		return 0;
+	} else
+		return cards_found ? 0 : -ENODEV;
+}
+#endif /* LINUX_VERSION_CODE >= 0x20200 */
+
+
+static void pci_drv_unregister(drv_id_info *drv_id)
+{
+	/* We need do something only with CardBus support. */
+	if (unregister_cb_hook) {
+		(*unregister_cb_hook)(drv_id);
+		MOD_DEC_USE_COUNT;
+	}
+	return;
+}
+
+/*
+  Search PCI configuration space for the specified capability registers.
+  Return the index, or 0 on failure.
+*/
+static int pci_find(struct pci_dev *pdev, int findtype)
+{
+	u16 pci_status, cap_type;
+	u8 pci_cap_idx;
+	int cap_idx;
+
+	pci_read_config_word(pdev, PCI_STATUS, &pci_status);
+	if ( ! (pci_status & PCI_STATUS_CAP_LIST))
+		return 0;
+	pci_read_config_byte(pdev, PCI_CAPABILITY_LIST, &pci_cap_idx);
+	cap_idx = pci_cap_idx;
+	for (cap_idx = pci_cap_idx; cap_idx; cap_idx = (cap_type >> 8) & 0xff) {
+		pci_read_config_word(pdev, cap_idx, &cap_type);
+		if ((cap_type & 0xff) == findtype)
+			return cap_idx;
+	}
+	return 0;
+}
+
+
+/* Change a device from D3 (sleep) to D0 (active).
+   Return the old power state.
+   This is more complicated than you might first expect since most cards
+   forget all PCI config info during the transition! */
+static int acpi_wake(struct pci_dev *pdev)
+{
+	u32 base[5], romaddr;
+	u16 pci_command, pwr_command;
+	u8  pci_latency, pci_cacheline, irq;
+	int i, pwr_cmd_idx = pci_find(pdev, PCI_CAP_ID_PM);
+
+	if (pwr_cmd_idx == 0)
+		return 0;
+	pci_read_config_word(pdev, pwr_cmd_idx + 4, &pwr_command);
+	if ((pwr_command & 3) == 0)
+		return 0;
+	pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
+	for (i = 0; i < 5; i++)
+		pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0 + i*4,
+								  &base[i]);
+	pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &romaddr);
+	pci_read_config_byte( pdev, PCI_LATENCY_TIMER, &pci_latency);
+	pci_read_config_byte( pdev, PCI_CACHE_LINE_SIZE, &pci_cacheline);
+	pci_read_config_byte( pdev, PCI_INTERRUPT_LINE, &irq);
+
+	pci_write_config_word(pdev, pwr_cmd_idx + 4, 0x0000);
+	for (i = 0; i < 5; i++)
+		if (base[i])
+			pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0 + i*4,
+									   base[i]);
+	pci_write_config_dword(pdev, PCI_ROM_ADDRESS, romaddr);
+	pci_write_config_byte( pdev, PCI_INTERRUPT_LINE, irq);
+	pci_write_config_byte( pdev, PCI_CACHE_LINE_SIZE, pci_cacheline);
+	pci_write_config_byte( pdev, PCI_LATENCY_TIMER, pci_latency);
+	pci_write_config_word( pdev, PCI_COMMAND, pci_command | 5);
+	return pwr_command & 3;
+}
+static void *via_probe1(struct pci_dev *pdev, void *init_dev,
+                        unsigned long ioaddr, int irq, int chip_idx, int card_idx, u32 revision)
+{
+    struct net_device *dev;
+    int i;
+    unsigned char byOrgValue;
+    int ww;
+    u8 mode3_reg;
+
+    // if vt3065     
+    if (revision>=0x40) {
+       // clear sticky bit before reset & read ethernet address
+       byOrgValue = readb(ioaddr + FET_STICKHW);    
+       byOrgValue = byOrgValue & 0xFC;
+       writeb(byOrgValue, ioaddr + FET_STICKHW);        
+       // disable force PME-enable 
+       writeb(0x80, ioaddr + FET_WOLCG_CLR);
+       // disable power-event config bit
+       writeb(0xFF, ioaddr + FET_WOLCR_CLR);
+       // clear power status 
+       writeb(0xFF, ioaddr + FET_PWRCSR_CLR);   
+    }
+    
+        
+    /* Reset the chip to erase previous misconfiguration. */
+    writew(FET_CmdReset, ioaddr + FET_CR0);
+    // if vt3043 delay after reset
+    if (revision <0x40) {
+       udelay(10000);
+    }
+
+    // polling till software reset complete
+    // W_MAX_TIMEOUT is the timeout period
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        if ((readw(ioaddr + FET_CR0) & FET_CmdReset) == 0 )
+            break;
+    }
+       
+    // issue AUTOLoad in EECSR to reload eeprom
+    writeb(0x20, ioaddr + FET_EECSR);
+      
+    // if vt3065 delay after reset
+    if (revision >=0x40 ) { 
+
+        // delay 8ms to let MAC stable
+        mdelay(8);
+        // for 3065D, EEPROM reloaded will cause bit 0 in CFGA turned on.
+        // it makes MAC receive magic packet automatically. So, driver turn it off.
+        writeb(readb(ioaddr + FET_CFGA) & 0xFE, ioaddr + FET_CFGA);
+    }
+
+    /* turn on bit2 in PCI configuration register 0x53 , only for 3065*/
+    if (revision >= 0x40) {
+        pci_read_config_byte(pdev,PCI_REG_MODE3,&mode3_reg);
+        pci_write_config_byte(pdev,PCI_REG_MODE3,mode3_reg|MODE3_MIION);
+    }
+
+    /* back off algorithm ,disable the right-most 4-bit off FET_CFGD*/
+    writeb(readb(ioaddr + FET_CFGD) & (~(FET_CRADOM | FET_CAP | FET_MBA | FET_BAKOPT)), ioaddr + FET_CFGD);
+#if (LINUX_VERSION_CODE >= 0x20341)
+    dev = init_etherdev(NULL, sizeof(netdev_private));
+#else
+    dev = init_etherdev(init_dev, 0);
+#endif
+    printk(KERN_INFO "%s: %s\n",dev->name, pci_tbl[chip_idx].name);
+    printk(KERN_INFO "%s: IO Address = 0x%lx, MAC Address = ",dev->name, ioaddr);
+    /* Ideally we would read the EEPROM but access may be locked. */
+    for (i = 0; i < 6; i++)
+        dev->dev_addr[i] = readb(ioaddr + FET_PAR + i);
+    for (i = 0; i < 5; i++)
+            printk("%2.2x:", dev->dev_addr[i]);
+    printk("%2.2x, IRQ = %d.\n", dev->dev_addr[i], irq);
+
+    if (init_device_data (dev, pdev, ioaddr, revision, irq, chip_idx, card_idx) == -1)
+       return NULL;
+    return dev;
+}
+
+static int init_device_data(struct net_device *dev, struct pci_dev *pdev, unsigned long ioaddr, u32 revision, int irq, int chip_idx, int card_idx)
+{
+    netdev_private *np;
+#if (LINUX_VERSION_CODE < 0x20341)
+    void *priv_mem;
+    void *pSRdTemp, *pSRdTemp_aligned;
+    void *pSTdTemp, *pSTdTemp_aligned;
+#endif
+    int i;
+
+    /* Make certain the descriptor lists are cache-aligned. */
+#if (LINUX_VERSION_CODE >= 0x20341)
+    np = dev->priv;
+    if (revision >= 0x80 && enable_tagging[np->card_idx] == 1)
+        np->ring = pci_alloc_consistent(pdev,(sizeof(rx_desc) * RX_RING_SIZE)+(sizeof(tx_desc) * TX_RING_SIZE * 8), &np->ring_dma);
+    else
+        np->ring = pci_alloc_consistent(pdev,(sizeof(rx_desc) * RX_RING_SIZE)+(sizeof(tx_desc) * TX_RING_SIZE), &np->ring_dma);
+
+    /* Check for the very unlikely case of no memory. */
+    if (np->ring == NULL)
+        return -1;
+    np->rx_ring = np->ring;
+    if (revision >= 0x80 && enable_tagging[np->card_idx] == 1) {
+        for (i = 0; i < 8; i++) {
+            np->tx_ring[i] = np->ring + (sizeof(rx_desc) * RX_RING_SIZE) + (sizeof(tx_desc) * TX_RING_SIZE * i);
+        }
+    }
+    else {
+        np->tx_ring[0] = np->ring + (sizeof(rx_desc) * RX_RING_SIZE);
+        for (i = 1; i < 8; i++)
+            np->tx_ring[i] = NULL;
+    }
+    np->pdev=pdev;
+#else
+    priv_mem = kmalloc(sizeof(*np) + PRIV_ALIGN, GFP_KERNEL);
+//    printk("chenyp:priv_mem=%x\n",priv_mem);
+    pSRdTemp=kmalloc((sizeof(rx_desc) * RX_RING_SIZE) + PRIV_ALIGN, GFP_KERNEL);
+//    printk("chenyp: init_device_data: pSRdTemp=%x\n",pSRdTemp);
+    if (revision >= 0x80) {
+        pSTdTemp=kmalloc((sizeof(tx_desc) * TX_RING_SIZE * 8) + PRIV_ALIGN, GFP_KERNEL);
+        //printk("chenyp: init_device_data: pSTdTemp=%x\n",pSTdTemp);
+    }
+    else {
+        pSTdTemp=kmalloc((sizeof(tx_desc) * TX_RING_SIZE) + PRIV_ALIGN, GFP_KERNEL);
+//        printk("chenyp:pSTdTemp=%x\n",pSTdTemp);
+
+    }
+    /* Check for the very unlikely case of no memory. */
+    if (priv_mem == NULL || pSRdTemp == NULL || pSTdTemp == NULL)
+        return -1;
+
+    pSRdTemp_aligned = (void *)(((long)pSRdTemp + PRIV_ALIGN) & ~PRIV_ALIGN);
+    pSTdTemp_aligned = (void *)(((long)pSTdTemp + PRIV_ALIGN) & ~PRIV_ALIGN);
+    memset(pSRdTemp_aligned, 0, sizeof(rx_desc) * RX_RING_SIZE);
+    if (revision >= 0x80)
+        memset(pSTdTemp_aligned, 0, sizeof(rx_desc) * TX_RING_SIZE * 8);
+    else
+        memset(pSTdTemp_aligned, 0, sizeof(rx_desc) * TX_RING_SIZE);
+    dev->priv = np = (void *)(((long)priv_mem + PRIV_ALIGN) & ~PRIV_ALIGN);
+    memset(np, 0, sizeof(*np));
+    np->priv_addr = priv_mem;
+    np->rx_ring = (rx_desc*)pSRdTemp_aligned;
+    if (revision >= 0x80) {
+        for (i = 0; i < 8; i++) {
+            np->tx_ring[i] = (tx_desc *)(pSTdTemp_aligned + (sizeof(rx_desc) * TX_RING_SIZE * i));
+        }
+    }
+    else {
+        np->tx_ring[0] = (tx_desc *)pSTdTemp_aligned;
+        for (i = 1; i < 8; i++)
+            np->tx_ring[i] = NULL;
+    }
+    np->priv_rd = pSRdTemp;
+    np->priv_td = pSTdTemp;
+
+#endif
+
+
+#ifdef USE_IO_OPS
+    request_region(ioaddr, pci_tbl[chip_idx].io_size, dev->name);
+#endif /* ifdef USE_IO_OPS */
+
+    /* Reset the chip to erase previous misconfiguration. */
+//    writew(FET_CmdReset, ioaddr + FET_CR0);
+
+    dev->base_addr = ioaddr;
+    dev->irq = irq;
+    np->next_module = root_net_dev;
+    root_net_dev = dev;
+    np->pci_dev = pdev;
+    np->chip_idx = chip_idx;
+    np->card_idx = card_idx;
+    np->drv_flags = pci_tbl[chip_idx].drv_flags;
+    np->revision =revision;
+
+    /* The chip-specific entries in the device structure. */
+    dev->open = &netdev_open;
+    dev->hard_start_xmit = &start_tx;
+    dev->stop = &netdev_close;
+    dev->get_stats = &get_stats;
+    dev->set_multicast_list = &set_rx_mode;
+    dev->do_ioctl = &mii_ioctl;
+
+    if (np->drv_flags & FET_CanHaveMII) {
+        np->phy_addr = readb(ioaddr + FET_MIICFG) & 0x1f;
+        np->advertising = mdio_read(dev, np->phy_addr, 4);
+    }
+/*
+    //add by chenyp,MACM
+    {
+    	unsigned char value[8];
+
+    	value[0]=0x12;
+    	value[1]=0x23;
+    	value[2]=0x34;
+    	value[3]=0x45;
+    	value[4]=0x56;
+    	value[5]=0x67;
+    	value[6]=0x78;
+    	value[7]=0x89;
+    	CAM_data_write(dev,0,0,value);
+
+    	value[0]=0xab;
+    	value[1]=0xcd;
+    	value[2]=0xef;
+    	value[3]=0x12;
+    	value[4]=0x34;
+    	value[5]=0x56;
+    	value[6]=0x78;
+    	value[7]=0x9a;
+    	CAM_data_write(dev,0,1,value);
+
+    	value[0]=0x55;
+    	value[1]=0x55;
+    	value[2]=0x55;
+    	value[3]=0x55;
+    	value[4]=0x66;
+    	value[5]=0x66;
+    	value[6]=0x66;
+    	value[7]=0x66;
+       CAM_data_write(dev,0,2,value);
+
+    	value[0]=0x77;
+    	value[1]=0x77;
+    	value[2]=0x77;
+    	value[3]=0x77;
+    	value[4]=0x88;
+    	value[5]=0x88;
+    	value[6]=0x88;
+    	value[7]=0x88;
+        CAM_data_write(dev,0,3,value);
+
+    	value[0]=0x12;
+    	value[1]=0x34;
+    	value[2]=0x56;
+    	value[3]=0x78;
+    	value[4]=0x9a;
+    	value[5]=0xbc;
+    	value[6]=0xde;
+    	value[7]=0xf0;
+    	CAM_data_write(dev,1,0,value);
+
+    	value[0]=0x23;
+    	value[1]=0x34;
+    	value[2]=0x45;
+    	value[3]=0x56;
+    	value[4]=0x67;
+    	value[5]=0x78;
+    	value[6]=0x89;
+    	value[7]=0x9a;
+    	CAM_data_write(dev,1,1,value);
+
+    	value[0]=0x55;
+    	value[1]=0x55;
+    	value[2]=0x55;
+    	value[3]=0x55;
+    	value[4]=0x66;
+    	value[5]=0x66;
+    	value[6]=0x66;
+    	value[7]=0x66;
+       CAM_data_write(dev,1,2,value);
+
+    	value[0]=0x77;
+    	value[1]=0x77;
+    	value[2]=0x77;
+    	value[3]=0x77;
+    	value[4]=0x88;
+    	value[5]=0x88;
+    	value[6]=0x88;
+    	value[7]=0x88;
+        CAM_data_write(dev,1,3,value);
+CAM_mask_write(dev,0,0x12345678);
+printk("mask1=%x\n",CAM_mask_read(dev,0) );
+CAM_mask_write(dev,1,0xabcdefab);
+printk("mask2=%x\n",CAM_mask_read(dev,1) );
+    }
+*/
+    return 0;
+}
+
+void SafeDisableMiiAuto(struct net_device *dev)
+{
+    unsigned long ioaddr = dev->base_addr;
+    netdev_private *np = (netdev_private *)dev->priv;
+    int ww;
+
+    /* before read mii data, we must turn off mauto */
+    writeb(0, ioaddr + FET_MIICR);
+
+    // for VT3043 only
+    if (np->revision < 0x20) {
+        // turn off MSRCEN
+        // NOTE.... address of MII should be 0x01,
+        //          otherwise SRCI will invoked
+        writeb(0x01, ioaddr + FET_MIIADR);
+        mdelay(1);
+
+        // turn on MAUTO
+        writeb(0x80, ioaddr + FET_MIICR);
+
+        // W_MAX_TIMEOUT is the timeout period
+        for (ww = 0; ww < 0x3fff; ww++) {
+            if (readb(ioaddr + FET_MIIADR) & 0x20)
+                break;
+        }
+
+        // as soon as MDONE is on, 
+        // this is the right time to turn off MAUTO
+        writeb(0, ioaddr + FET_MIICR);
+    }
+    else {                   
+        // as soon as MIDLE is on, MAUTO is really stoped
+        for (ww = 0; ww < 0x3fff; ww++) {
+            if (readb(ioaddr + FET_MIIADR) & 0x80)
+                break;
+        }
+    }
+}
+/* Read and write over the MII Management Data I/O (MDIO) interface. */
+static unsigned int mdio_read(struct net_device *dev, int phy_id, int regnum)
+{
+    unsigned long ioaddr = dev->base_addr;
+    unsigned char byMIICRbak;
+    unsigned int wMII_DATA_REG;
+    netdev_private *np = (netdev_private *)dev->priv;
+    int ww;
+
+    /* backup MIICR*/
+    byMIICRbak = readb(ioaddr + FET_MIICR);
+
+    /* before read mii data, we must turn off MAUTO */
+    SafeDisableMiiAuto(dev);
+
+    /* write PHY id */
+    writeb(phy_id, ioaddr + FET_MIICFG);
+
+    /* write MII address */
+    writeb(regnum, ioaddr + FET_MIIADR);
+
+    /* Trigger reading */
+    writeb(readb(ioaddr+FET_MIICR) | 0x40, ioaddr + FET_MIICR);   
+    
+    /* waiting read complete. */
+    for (ww = 0; ww < 0x3fff; ww++)
+        if (!(readb(ioaddr + FET_MIICR) & 0x40))
+            break;
+
+    /* read MII register's data */
+    wMII_DATA_REG = readw(ioaddr + FET_MII_DATA_REG);
+
+    /* for VT3043 only */
+    if (np->revision < 0x20)
+        mdelay(1);
+
+    /* the value of MAD4-MAD0 bit must be 00001 before we turn on MAUTO */
+    /* or the LNKFL bit in MIISR will be incorrect */
+    writeb(0x01, ioaddr + FET_MIIADR);
+
+    /* restore MII Data & turn on MAUTO*/
+    writeb(byMIICRbak | 0x80, ioaddr + FET_MIICR);
+
+    /* waiting for MDONE turn on. */
+    for (ww = 0; ww < 0x3fff; ww++)
+        if (readb(ioaddr + FET_MIIADR) & 0x20)
+            break;
+
+    /* turn on MSRCEN ater MDONE has turned on */    
+    writeb( 0x40, ioaddr + FET_MIIADR);
+
+    return wMII_DATA_REG;        
+}
+
+static void mdio_write(struct net_device *dev, int phy_id, int regnum, unsigned int value)
+{
+    unsigned long ioaddr = dev->base_addr;
+    unsigned char byMIICRbak;
+    netdev_private *np = (netdev_private *)dev->priv;
+    int ww = 0;    
+
+    if (phy_id == np->phy_addr) {
+		switch (regnum) {
+//		case 0:				
+//			if (value & 0x9000)	
+//				np->duplex_lock = 0;
+//			else
+//				np->full_duplex = (value & 0x0100) ? 1 : 0;
+//			break;
+		case 4: np->advertising = value;
+		        break;
+		}
+	}
+
+    /* backup MIICR */
+    byMIICRbak = readb(ioaddr + FET_MIICR);
+
+    /* write PHY id */
+    writeb(phy_id, ioaddr + FET_MIICFG);
+
+    /* before write MII data, we must turn off MAUTO */
+    SafeDisableMiiAuto(dev);
+
+    /* write MII register's ddress */
+    writeb(regnum, ioaddr + FET_MIIADR);
+
+    /* write MII register's data */
+    writew(value, ioaddr + FET_MII_DATA_REG);
+
+    /* Trigger writing */
+    writeb(readb(ioaddr+FET_MIICR) | 0x20, ioaddr+FET_MIICR);
+
+    /* waiting for write complete. */
+    for (ww = 0; ww < 0x3fff; ww++)
+        if (!(readb(ioaddr + FET_MIICR) & 0x20))
+            break;
+
+    // for VT3043 only
+    if (np->revision < 0x20)
+        mdelay(1);
+
+    /* the value of MAD4-MAD0 bit must be 00001 before we turn on MAUTO */
+    /* or the LNKFL bit in MIISR will be incorrect */
+    writeb( 0x01, ioaddr + FET_MIIADR);
+
+    /* restore MII Data & turn on MAUTO*/
+    writeb(byMIICRbak | 0x80, ioaddr + FET_MIICR);
+
+    /* waiting for MDONE turn on. */
+    for (ww = 0; ww < 0x3fff; ww++)
+        if (readb(ioaddr + FET_MIIADR) & 0x20)
+            break;
+
+    /* turn on MSRCEN ater MDONE has turned on */    
+    writeb( 0x40, ioaddr + FET_MIIADR);
+
+    return;
+}
+
+#ifdef CAM_data_read
+//if select_CAM=0, read MCAM , else if slect_CAM=1, read VCAM
+static void CAM_data_read(struct net_device *dev, int select_CAM, unsigned char CAM_address, unsigned char *value)
+{
+    unsigned long ioaddr = dev->base_addr;
+    int uu;
+    unsigned char FET_CAMC_temp;
+
+    // invalid address
+    if (CAM_address & 0xE0)
+        printk("%s: the CAM address is invalid.\n", dev->name);
+
+    // enable/select CAM controller
+    FET_CAMC_temp = CAMC_CAMEN | (select_CAM ? CAMC_VCAMSL : 0);
+    writeb(FET_CAMC_temp, ioaddr + FET_CAMC);
+
+    // set CAM entry address
+    writeb(CAM_address, ioaddr + FET_CAMADD);
+
+    // issue read command
+    writeb(CAMC_CAMRD | FET_CAMC_temp, ioaddr + FET_CAMC);
+
+    // wait 2us for read completed
+    udelay(2);
+
+    if (select_CAM == CAMC_SELECT_VCAM) {
+        // read VID CAM data
+        *((unsigned int *)value)= readw(ioaddr + FET_VCAMD0);
+    }
+    else {
+        // read Multicast CAM data
+        for (uu = 0; uu < 6; uu++)
+            *(value + uu)=readb(ioaddr + FET_MCAMD0 + uu);            
+    }
+    
+    // disable CAMEN and return TRUE
+    writeb(0, ioaddr + FET_CAMC);
+
+    return;
+
+}
+#endif
+
+//if select_CAM=0, write MCAM , else if slect_CAM=1, write VCAM
+static void CAM_data_write(struct net_device *dev, int select_CAM, unsigned char CAM_address, unsigned char *value)
+{
+    unsigned long ioaddr = dev->base_addr;
+    int uu;
+    unsigned char FET_CAMC_temp;
+
+    // invalid address
+    if (CAM_address & 0xE0)
+        printk("%s: the CAM address is invalid.\n", dev->name);
+
+    // enable/select CAM controller
+    FET_CAMC_temp = CAMC_CAMEN | (select_CAM ? CAMC_VCAMSL : 0);
+    writeb(FET_CAMC_temp, ioaddr + FET_CAMC);
+
+    // set CAM entry address
+    writeb(CAM_address, ioaddr + FET_CAMADD);
+ 
+    if (select_CAM == CAMC_SELECT_VCAM) {
+        // read VID CAM data
+        writew(*((unsigned int *)value), ioaddr + FET_VCAMD0);
+    }
+    else {
+        // read Multicast CAM data
+        for (uu = 0; uu < 6; uu++)
+            writeb(*(value + uu), ioaddr + FET_MCAMD0 + uu);
+    }
+    // issue write command
+    writeb(CAMC_CAMWR | FET_CAMC_temp , ioaddr + FET_CAMC);
+
+    // wait 1us before next CAMWR    
+    udelay(1);
+
+    // disable CAMEN and return TRUE
+    writeb(0, ioaddr + FET_CAMC);
+}
+
+#ifdef CAM_mask_read
+//if select_CAM=0, read MCAM mask, else if slect_CAM=1, read VCAM mask
+static unsigned int CAM_mask_read(struct net_device *dev, int select_CAM)
+{
+    unsigned long ioaddr = dev->base_addr;
+    unsigned int mask_temp;
+
+    // enable CAMEN
+    writeb(CAMC_CAMEN | (select_CAM ? CAMC_VCAMSL : 0), ioaddr + FET_CAMC);
+
+    // read mask       
+    mask_temp = readl(ioaddr + FET_CAMMSK);
+    
+    // disable CAMEN
+    writeb(0, ioaddr + FET_CAMC);
+    return mask_temp;
+}
+#endif
+
+//if select_CAM=0, write MCAM mask, else if slect_CAM=1, write VCAM mask
+static void CAM_mask_write(struct net_device *dev, int select_CAM, unsigned int mask)
+{
+    unsigned long ioaddr = dev->base_addr;
+
+    // enable CAMEN
+    writeb(CAMC_CAMEN | (select_CAM ? CAMC_VCAMSL : 0), ioaddr + FET_CAMC);
+       
+    // write mask
+    writel(mask, ioaddr + FET_CAMMSK);
+    
+    // disable CAMEN
+    writeb(0, ioaddr + FET_CAMC);
+}
+
+#ifdef reset
+/* reset the chip */
+static void netdev_reset(struct net_device *dev)
+{
+    unsigned long ioaddr = dev->base_addr;
+    int ww;
+
+    /* Reset the chip. */
+    writew(FET_CmdReset | readw(ioaddr + FET_CR0), ioaddr + FET_CR0);
+    // polling till software reset complete
+    // W_MAX_TIMEOUT is the timeout period
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        if ((readw(ioaddr + FET_CR0) & FET_CmdReset) == 0 )
+            break;
+    }
+}
+#endif
+
+static void VLAN_tagging(struct net_device *dev)
+{
+    netdev_private *np = (netdev_private *)dev->priv;
+    unsigned long ioaddr = dev->base_addr;
+    unsigned int VCAM_temp = 0;
+
+    VCAM_temp= (enable_tagging[np->card_idx] == 1 && (VID_setting[np->card_idx] < 4095) && (VID_setting[np->card_idx] > 0))
+                   ? VID_setting[np->card_idx] : 0;
+ //   printk("chenyp:VCAM_temp=%x\n", VCAM_temp);
+
+    // set {PQEN, RTGOPT} = {1,0} in TCR
+    // in this mode, tx: all packet tagged,  rx: both untagged/tagged packets
+    writeb((readb(ioaddr + FET_TCR) & 0xEF) | 0x01, ioaddr + FET_TCR);
+
+    // Disable tagging
+    if (enable_tagging[np->card_idx] != 1) {
+        // VLAN CAM[0]= 0
+        CAM_data_write(dev, 1, 0, (unsigned char *)&VCAM_temp);
+
+        // VLAN CAM mask = 1
+        CAM_mask_write(dev,1,0x00000001);
+    }
+    else {
+        // Enable tagging, no VLAN setting
+        if (VCAM_temp == 0) {
+            // VLAN CAM[0]= 0
+            CAM_data_write(dev, 1, 0, (unsigned char *)&VCAM_temp);
+
+            // VLAN CAM mask = 1
+            CAM_mask_write(dev,1,0x00000001);
+
+        }
+        // Enable tagging, VLAN setting to single or multiple VID and VID !=0
+        else {
+            // VLAN CAM[0]= user defined value
+            CAM_data_write(dev, 1, 0, (unsigned char *)&VCAM_temp);
+
+            // VLAN CAM mask = 1
+            CAM_mask_write(dev,1,0x00000001);
+        }
+    }
+    // set VIDFR =1 in BCR1, VLAN ID hardware filtering.
+    writeb(readb(ioaddr + FET_BCR1) | 0x80, ioaddr + FET_BCR1);
+
+}
+static void turn_on_MII_link(struct net_device *dev)
+{
+    unsigned long ioaddr = dev->base_addr;
+    unsigned int MIICRbak;
+    int ww;
+
+    MIICRbak = readb(ioaddr + FET_MIICR);
+    SafeDisableMiiAuto(dev);
+    writeb(0x01, ioaddr + FET_MIIADR);
+    outb(MIICRbak | 0x80, ioaddr + FET_MIICR);
+    for (ww = 0; ww < 0x3fff; ww++)
+    if (readb(ioaddr + FET_MIIADR) & 0x20)
+        break;
+    /* turn on MSRCEN ater MDONE has turned on */    
+    writeb(0x40, ioaddr + FET_MIIADR);
+    mdelay(3);
+}
+static int netdev_open(struct net_device *dev)
+{
+    netdev_private *np = (netdev_private *)dev->priv;
+    unsigned long ioaddr = dev->base_addr;
+    int i;
+
+//    netdev_reset(dev);
+
+    MOD_INC_USE_COUNT;
+
+    if (request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev)) {
+
+        MOD_DEC_USE_COUNT;
+        return -EAGAIN;
+    }
+
+    if (debug > 1)
+        printk(KERN_INFO "%s: netdev_open() irq %d.\n",
+               dev->name, dev->irq);
+    init_ring(dev);
+    writel(virt_to_bus(np->rx_ring), ioaddr + FET_CURR_RX_DESC_ADDR);
+//    printk("chenyp:readl(np->rx_ring)=%x\n",readl(ioaddr + FET_CURR_RX_DESC_ADDR));
+    if (np->revision >= 0x80 && enable_tagging[np->card_idx] == 1) {
+        for (i = 0; i < 8; i++) {
+    	    writel(virt_to_bus(np->tx_ring[i]), ioaddr + FET_CURR_TX_DESC_ADDR + ((7 - i) * 4));
+ //           printk("chenyp:virt_to_bus(np->tx_ring[ %d ])=%xreadl(np->tx_ring %d)=%x\n",i,virt_to_bus(np->tx_ring[i]),i,ioaddr + FET_CURR_TX_DESC_ADDR + (i * 4));
+
+        }
+    }
+    else /* np->revision < 0x80 */
+    	writel(virt_to_bus(np->tx_ring[0]), ioaddr + FET_CURR_TX_DESC_ADDR);
+    for (i = 0; i < 6; i++)
+        writeb(dev->dev_addr[i], ioaddr + FET_PAR + i);
+
+    /* Initialize other registers. */    
+    // Turn on bit3 (OFSET) in TCR during MAC initialization.
+    writeb(readb(ioaddr + FET_TCR) | FET_TCR_OFSET, ioaddr + FET_TCR);
+
+    /* turn on MII link change */
+    /* if the MAD4-0 is not 0x0001, then Link Fail will be on */
+    turn_on_MII_link(dev);
+
+#if (LINUX_VERSION_CODE >= 0x02032a)
+    netif_start_queue(dev);
+#else /* (LINUX_VERSION_CODE >= 0x02032a) */
+    dev->tbusy = 0;
+    dev->interrupt = 0;
+    dev->start = 1;
+#endif /* (LINUX_VERSION_CODE >= 0x02032a) */
+
+    /* Configure the FIFO thresholds. */
+    np->tx_thresh = (tx_thresh[np->card_idx] >= 0 && tx_thresh[np->card_idx] <= 4) ? tx_thresh[np->card_idx]: 0;
+    np->rx_thresh = (rx_thresh[np->card_idx] >= 0 && rx_thresh[np->card_idx] <= 7) ? rx_thresh[np->card_idx]: 0;
+    np->DMA_length = (DMA_length[np->card_idx] >= 0 && DMA_length[np->card_idx] <= 7) ? DMA_length[np->card_idx]: 1;
+
+    // Set rx threshold, default = 64 bytes
+    writeb((readb(ioaddr + FET_BCR0) & 0xC7) | (np->rx_thresh << 3), ioaddr + FET_BCR0);
+    writeb((readb(ioaddr + FET_RCR) & 0x1F) | (np->rx_thresh << 5), ioaddr + FET_RCR);
+
+    // Set tx threshold, default = 128 bytes
+    writeb((readb(ioaddr + FET_BCR1) & 0xC7) | (np->tx_thresh << 3), ioaddr + FET_BCR1);
+    writeb((readb(ioaddr + FET_TCR) & 0x1F) | (np->tx_thresh << 5), ioaddr + FET_TCR);
+
+    // Set DMA length, default = 16 DWORDs = 64 bytes
+    writeb((readb(ioaddr + FET_BCR0) & 0xF8) | np->DMA_length , ioaddr + FET_BCR0);
+   
+    set_rx_mode(dev);
+
+    if (np->revision >= 0x80)
+        set_flow_control(dev);
+
+    set_media_duplex_mode(dev);
+
+    if (np->revision >= 0x80) {
+        /* For non-blocking priority transmit, set {TXQBKT1, TXQBKT0} -> {1,1} */
+        /* So, the Tx Queue Block Counter = 8 packets*/
+        writeb(readb(ioaddr + FET_GFTEST) | 0x30, ioaddr + FET_GFTEST);
+        /* Set non-blocking priority transmit*/
+        writeb(readb(ioaddr + FET_BCR1) | 0x40, ioaddr + FET_BCR1);
+    }
+    if (np->revision >= 0x40)
+       flow_control_ability (dev);
+
+    /* 802.1p/Q tagging user setting and behavior */
+    if (np->revision >= 0x80)
+        VLAN_tagging(dev);
+
+
+
+    /* Enable interrupts by setting the interrupt mask. */
+    writew(FET_ISR_PRX | FET_ISR_PTX | FET_ISR_RXE | FET_ISR_TXE | 
+           FET_ISR_TU | FET_ISR_RU | FET_ISR_BE | FET_ISR_CNT |
+           FET_ISR_ERI | FET_ISR_UDFI | FET_ISR_OVFI | FET_ISR_PKTRACE | 
+           FET_ISR_NORBF | FET_ISR_ABTI | FET_ISR_SRCI ,
+           ioaddr + FET_IMR0);
+
+    np->chip_cmd = FET_CmdStart|FET_CmdTxOn|FET_CmdRxOn|FET_CmdNoTxPoll;
+    if (np->full_duplex)
+        np->chip_cmd |= FET_CmdFDuplex;
+    writeb((np->chip_cmd & 0xff), ioaddr + FET_CR0);
+    writeb( (np->chip_cmd >>8) |readb(ioaddr + FET_CR1), ioaddr + FET_CR1);
+    
+    /* The LED outputs of various MII xcvrs should be configured.  */
+    /* For NS or Mison phys, turn on bit 1 in register 0x17 */
+    /* For ESI phys, turn on bit 7 in register 0x17. */
+    mdio_write(dev, np->phy_addr, 0x17, mdio_read(dev, np->phy_addr, 0x17) |
+               (np->drv_flags & FET_HasESIPhy) ? 0x0080 : 0x0001);
+
+    if (debug > 2)
+        printk(KERN_INFO "%s: Done netdev_open(), status %4.4x "
+               "MII status: %4.4x.\n",
+               dev->name, readw(ioaddr + FET_CR0),
+               mdio_read(dev, np->phy_addr, 1));
+    /* Set the timer to check for link beat. */
+    //init_timer(&np->timer);
+    //np->timer.expires = jiffies + 2;
+    //np->timer.data = (unsigned long)dev;
+    //np->timer.function = &netdev_timer;             /* timer handler */
+    //add_timer(&np->timer);
+//printk("chenyp:netdev_open:phy0=%x, phy1=%x, phy2=%x, phy3=%x, phy4=%x, phy5=%x, mac8=%x, mac99=%x mac80=%x\n",mdio_read(dev,np->phy_addr,0),mdio_read(dev,np->phy_addr,1),mdio_read(dev,np->phy_addr,2),mdio_read(dev,np->phy_addr,3),mdio_read(dev,np->phy_addr,4),mdio_read(dev,np->phy_addr,5),readb(ioaddr+0x08),readb(ioaddr+0x99),readb(ioaddr+0x80));
+
+    return 0;
+}
+
+static void do_autonegotiation(struct net_device *dev)
+{
+    netdev_private *np = (netdev_private *)dev->priv;
+    unsigned long ioaddr = dev->base_addr;
+
+    /* check whether link fail */
+    if (readb(ioaddr + FET_MIISR) & 0x02){
+        printk(KERN_INFO "%s: Link Fail.\n",dev->name);
+        np->full_duplex = 0;
+        np->chip_cmd &= FET_CmdNoFDuplex;
+        return;
+    }
+    /* check speed*/
+    /* read N_SPD10 bit in MII Status Register */
+    if (readb(ioaddr + FET_MIISR) & 0x01)
+        printk(KERN_INFO "%s: Autonegotiation result: 10Mbps", dev->name);
+    else
+        printk(KERN_INFO "%s: Autonegotiation result: 100Mbps", dev->name);
+    /* check duplex mode*/
+    /* if VT3106, check N_FDX bit in MII Status Register directly */
+    if (np->revision >= 0x80) {
+        if (readb(ioaddr + FET_MIISR) & 0x04) {
+            printk(" full duplex mode.\n");
+            /* Set MAC operating in Full Duplex Mode*/
+            writew(readw(ioaddr + FET_CR0) | 0x0400, ioaddr + FET_CR0);
+            np->full_duplex = 1;
+            np->chip_cmd |= FET_CmdFDuplex;
+        }
+        else {
+            printk(" half duplex mode.\n");
+            /* Set MAC operating in Half Duplex Mode*/
+            writew(readw(ioaddr + FET_CR0) & 0xfbff, ioaddr + FET_CR0);
+            np->full_duplex = 0;
+            np->chip_cmd &= FET_CmdNoFDuplex;
+        }
+    }
+    else {
+        /* if VT3065 or VT3043, check ANAR and ANLPAR in MII Registers of PHY */
+        if ((mdio_read(dev, np->phy_addr, 4) & mdio_read(dev, np->phy_addr, 5)) & 0x0140 ) {
+            printk(" full duplex mode.\n");
+            /* Set MAC operating in Full Duplex Mode*/
+            writew(readw(ioaddr + FET_CR0) | 0x0400, ioaddr + FET_CR0);
+            np->full_duplex = 1;
+            np->chip_cmd |= FET_CmdFDuplex;
+        }
+        else {
+            printk(" half duplex mode.\n");
+            /* Set MAC operating in Half Duplex Mode*/
+            writew(readw(ioaddr + FET_CR0) & 0xfbff, ioaddr + FET_CR0);
+            np->full_duplex = 0;
+            np->chip_cmd &= FET_CmdNoFDuplex;
+        }
+    }
+}
+
+/* Do lagacy force if in force mode*/
+static void check_legacy_force(struct net_device *dev)
+{
+    netdev_private *np = (netdev_private *)dev->priv;
+    unsigned long ioaddr = dev->base_addr;
+    unsigned int FET_BCR1_temp = 0;
+
+//printk("chenyp:legacy_force\n");
+    /* If MEDEN bit in CFGC is on, then it's forced mode, 
+       otherwise, it use autonegotiation. Only for VT3065 and VT3043 */
+    if(np->revision < 0x80 && readb(ioaddr + FET_CFGC) & 0x80){
+        /* if MED2 bit in BCR0 is on, then it use autonegotiation*/
+        if (readb(ioaddr + FET_BCR0) & 0x80)
+            np->auto_negotiation = 1;
+        else {
+            np->auto_negotiation = 0;
+
+            FET_BCR1_temp = readb(ioaddr + FET_BCR1);
+            FET_BCR1_temp = FET_BCR1_temp & 0xC0 ;
+
+            /* Disable autonigotiation */
+            mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) & 0xEFFF);
+
+            /* set loopback in MII to un-link in 100M mode, */
+            /* in 10M mode set this bit cannot make it un-link */
+            /* but it doesn't matter */
+            mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) | 0x4000);
+
+            if (FET_BCR1_temp == 0x00) {
+                printk(KERN_INFO "%s: Force to 10Mbps Half duplex mode.\n", dev->name);
+                /* Set speed 10Mbps */
+                mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) & 0xDFFF);
+                /* Set half duplex */
+                mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) & 0xFEFF);
+                /* Set MAC operating in Half Duplex Mode*/
+                writew(readw(ioaddr + FET_CR0) & 0xfbff, ioaddr + FET_CR0);
+                np->full_duplex = 0;
+                np->chip_cmd &= FET_CmdNoFDuplex;
+            }
+            else if (FET_BCR1_temp == 0x40) {
+                printk(KERN_INFO "%s: Force to 100Mbps Half duplex mode.\n", dev->name);
+                /* Set speed 100Mbps */
+                mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) | 0x2000);
+                /* Set half duplex */
+                mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) & 0xFEFF);
+                /* Set MAC operating in Half Duplex Mode*/
+                writew(readw(ioaddr + FET_CR0) & 0xfbff, ioaddr + FET_CR0);
+                np->full_duplex = 0;
+                np->chip_cmd &= FET_CmdNoFDuplex;
+            }
+            else if (FET_BCR1_temp == 0x80) {
+                printk(KERN_INFO "%s: Force to 10Mbps Full duplex mode.\n", dev->name);
+                /* Set speed 10Mbps */
+                mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) & 0xDFFF);
+                /* Set full duplex */
+                mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) | 0x0100);
+                /* Set MAC operating in Full Duplex Mode*/
+                writew(readw(ioaddr + FET_CR0) | 0x0400, ioaddr + FET_CR0);
+                np->full_duplex = 1;
+                np->chip_cmd |= FET_CmdFDuplex;
+            }
+            else if (FET_BCR1_temp == 0xC0) {
+                printk(KERN_INFO "%s: Force to 100Mbps Full duplex mode.\n", dev->name);
+                /* Set speed 100Mbps */
+                mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) | 0x2000);
+                /* Set full duplex */
+                mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) | 0x0100);
+                /* Set MAC operating in Full Duplex Mode*/
+                writew(readw(ioaddr + FET_CR0) | 0x0400, ioaddr + FET_CR0);
+                np->full_duplex = 1;
+                np->chip_cmd |= FET_CmdFDuplex;
+            }
+            /* delay to avoid link down from force-10M to force-100M */
+            mdelay(300);
+
+            /* clear LPBK bit in BMCR register to re-link */
+            mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) & 0xBFFF);
+        }
+    }
+    else {
+        /* Check whether user define the speed and duplex mode */
+        if (np->card_idx < MAX_UNITS  &&  speed_duplex[np->card_idx] > 0 && speed_duplex[np->card_idx] <= 4) {
+            np->auto_negotiation = 0;
+
+            /* Disable autonigotiation */
+            mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) & 0xEFFF);
+
+            /* set loopback in MII to un-link in 100M mode, */
+            /* in 10M mode set this bit cannot make it un-link */
+            /* but it doesn't matter */
+            mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) | 0x4000);
+
+            if (speed_duplex[np->card_idx] == 1) {
+                printk(KERN_INFO "%s: Force to 100Mbps Half duplex mode.\n", dev->name);
+                /* Set speed 100Mbps */
+                mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) | 0x2000);
+                /* Set half duplex */
+                mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) & 0xFEFF);
+                /* Set MAC operating in Half Duplex Mode*/
+                writew(readw(ioaddr + FET_CR0) & 0xfbff, ioaddr + FET_CR0);
+                np->full_duplex = 0;
+                np->chip_cmd &= FET_CmdNoFDuplex;
+            }
+            else if (speed_duplex[np->card_idx] == 2) {
+                printk(KERN_INFO "%s: Force to 100Mbps Full duplex mode.\n", dev->name);
+                /* Set speed 100Mbps */
+                mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) | 0x2000);
+                /* Set full duplex */
+                mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) | 0x0100);
+                /* Set MAC operating in Full Duplex Mode*/
+                writew(readw(ioaddr + FET_CR0) | 0x0400, ioaddr + FET_CR0);
+                np->full_duplex = 1;
+                np->chip_cmd |= FET_CmdFDuplex;
+            }
+            else if (speed_duplex[np->card_idx] == 3) {
+                printk(KERN_INFO "%s: Force to 10Mbps Half duplex mode.\n", dev->name);
+                /* Set speed 10Mbps */
+                mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) & 0xDFFF);
+                /* Set half duplex */
+                mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) & 0xFEFF);
+                /* Set MAC operating in Half Duplex Mode*/
+                writew(readw(ioaddr + FET_CR0) & 0xfbff, ioaddr + FET_CR0);
+                np->full_duplex = 0;
+                np->chip_cmd &= FET_CmdNoFDuplex;
+            }
+            else if (speed_duplex[np->card_idx] == 4) {
+                printk(KERN_INFO "%s: Force to 10Mbps Full duplex mode.\n", dev->name);
+                /* Set speed 10Mbps */
+                mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) & 0xDFFF);
+                /* Set full duplex */
+                mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) | 0x0100);
+                /* Set MAC operating in Full Duplex Mode*/
+                writew(readw(ioaddr + FET_CR0) | 0x0400, ioaddr + FET_CR0);
+                np->full_duplex = 1;
+                np->chip_cmd |= FET_CmdFDuplex;
+            }
+            /* delay to avoid link down from force-10M to force-100M */
+            mdelay(300);
+
+            /* clear LPBK bit in BMCR register to re-link */
+            mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) & 0xBFFF);
+        }
+        else
+            np->auto_negotiation = 1;
+    }
+}
+
+/* Restart autonegotiation */
+static void restart_autonegotiation(struct net_device *dev)
+{
+    netdev_private *np = (netdev_private *)dev->priv;
+    unsigned int i;
+
+    /* Restart autonegotiation */
+    mdio_write(dev, np->phy_addr, 0, mdio_read (dev, np->phy_addr, 0) | 0x0200);
+    /* Wait until N-WAY finished*/
+    mdelay(2500); /* delay for 2.5 seconds */
+    for (i=0; i<0x1ff; i++)
+        if (mdio_read(dev, np->phy_addr, 1) & 0x0020)
+            break;
+}
+
+/* Turn on AUTO bit in MII regiser */
+static void enable_autonegotiation(struct net_device *dev)
+{
+    netdev_private *np = (netdev_private *)dev->priv;
+    unsigned int i;
+    unsigned int PHY_BMCR_temp = 0;
+
+    PHY_BMCR_temp = mdio_read(dev, np->phy_addr, 0);
+
+    /* Set Autonegotiation enable (ANEG_EN bit in Control register ) */
+    mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) | 0x1000);
+
+    /* Forced mode to auto mode, it will cause autonegotiation restart */
+    /* Wait until N-WAY finished*/
+    if (!( PHY_BMCR_temp & 0x1000)) {
+        mdelay(2300);
+        for (i=0; i<0x1ff; i++)
+            if (mdio_read(dev, np->phy_addr, 1) & 0x0020)
+                break;
+    }
+}
+
+/* Do N-WAY force if in force mode */
+static int check_n_way_force (struct net_device *dev, int change_flag)
+{
+    netdev_private *np = (netdev_private *)dev->priv;
+    unsigned long ioaddr = dev->base_addr;
+    unsigned int MII_BMCR_temp = 0, MII_ANAR_temp=0;
+//printk("chenyp:n_way_force\n");
+    /* Read original BMCR and ANAR value from MII */
+    MII_BMCR_temp = mdio_read(dev, np->phy_addr, 0) ;
+    MII_ANAR_temp = mdio_read(dev, np->phy_addr, 4) & 0x01E0;
+
+    /* Check whether user define the speed and duplex mode */
+    if (np->card_idx < MAX_UNITS  &&  speed_duplex[np->card_idx] > 0 && speed_duplex[np->card_idx] <= 4) {
+        np->auto_negotiation = 0;
+
+        /* Force to 100Mbps Half duplex */
+        if (speed_duplex[np->card_idx] == 1) {
+            printk(KERN_INFO "%s: Force to 100Mbps Half duplex mode.\n", dev->name);
+            /* Compare user defined mode with original ANAR value*/
+            /* If the setting is the same, do nothing, or we msut write the new setting to ANAR */
+            if (MII_ANAR_temp != 0x0080) {
+                change_flag |= 1;
+                /*Write the new setting to ANAR */
+                mdio_write(dev, np->phy_addr, 4, (mdio_read(dev, np->phy_addr, 4) & 0xFE1F) | 0x0080);
+//                printk("chenyp:mdio_read(dev, np->phy_addr, 4)=%x\n", mdio_read(dev, np->phy_addr, 4));
+            }
+
+            /* Set speed 100Mbps */
+            mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) | 0x2000);
+            /* Set half duplex */
+            mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) & 0xFEFF);
+
+            /* If AUTO bit is on and the setting is changed, issue REAUTO in BMCR */
+            if ((MII_BMCR_temp & 0x1000) && (change_flag == 1))
+                restart_autonegotiation(dev);
+            else if (!(MII_BMCR_temp & 0x1000))
+                enable_autonegotiation(dev);
+
+            /* Set MAC operating in Half Duplex Mode*/
+            writew(readw(ioaddr + FET_CR0) & 0xfbff, ioaddr + FET_CR0);
+            np->full_duplex = 0;
+            np->chip_cmd &= FET_CmdNoFDuplex;
+        }
+        /* Force to 100Mbps Full duplex mode */
+        else if (speed_duplex[np->card_idx] == 2) {
+            printk(KERN_INFO "%s: Force to 100Mbps Full duplex mode.\n", dev->name);
+            /* Compare user defined mode with original ANAR value*/
+            /* If the setting is the same, do nothing, or we must write the new setting to ANAR */
+            if (MII_ANAR_temp != 0x0100) {
+                change_flag |= 1;
+                /*Write the new setting to ANAR */
+                mdio_write(dev, np->phy_addr, 4, (mdio_read(dev, np->phy_addr, 4) & 0xFE1F) | 0x0100);
+//                printk("chenyp:mdio_read(dev, np->phy_addr, 4)=%x\n", mdio_read(dev, np->phy_addr, 4));
+            }
+
+            /* Set speed 100Mbps */
+            mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) | 0x2000);
+            /* Set full duplex */
+            mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) | 0x0100);
+
+            /* If AUTO bit is on and the setting is changed, issue REAUTO in BMCR */
+            if ((MII_BMCR_temp & 0x1000) && (change_flag == 1))
+                restart_autonegotiation(dev);
+            else if (!(MII_BMCR_temp & 0x1000))
+                enable_autonegotiation(dev);
+
+            /* Set MAC operating in Full Duplex Mode*/
+            writew(readw(ioaddr + FET_CR0) | 0x0400, ioaddr + FET_CR0);
+            np->full_duplex = 1;
+            np->chip_cmd |= FET_CmdFDuplex;
+        }
+        /* Force to 10Mbps Half duplex mode */
+        else if (speed_duplex[np->card_idx] == 3) {
+            printk(KERN_INFO "%s: Force to 10Mbps Half duplex mode.\n", dev->name);
+            /* Compare user defined mode with original ANAR value*/
+            /* If the setting is the same, do nothing, or we msut write the new setting to ANAR */
+            if (MII_ANAR_temp != 0x0020) {
+                change_flag |= 1;
+                /*Write the new setting to ANAR */
+                mdio_write(dev, np->phy_addr, 4, (mdio_read(dev, np->phy_addr, 4) & 0xFE1F) | 0x0020);
+//                printk("chenyp:mdio_read(dev, np->phy_addr, 4)=%x\n", mdio_read(dev, np->phy_addr, 4));
+            }
+            /* Set speed 10Mbps */
+            mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) & 0xDFFF);
+            /* Set half duplex */
+            mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) & 0xFEFF);
+
+            /* If AUTO bit is on and the setting is changed, issue REAUTO in BMCR */
+            if ((MII_BMCR_temp & 0x1000) && (change_flag == 1))
+                restart_autonegotiation(dev);
+            else if (!(MII_BMCR_temp & 0x1000))
+                enable_autonegotiation(dev);
+
+            /* Set MAC operating in Half Duplex Mode*/
+            writew(readw(ioaddr + FET_CR0) & 0xfbff, ioaddr + FET_CR0);
+            np->full_duplex = 0;
+            np->chip_cmd &= FET_CmdNoFDuplex;
+        }
+        /* Force to 10Mbps Full duplex mode */
+        else if (speed_duplex[np->card_idx] == 4) {
+            printk(KERN_INFO "%s: Force to 10Mbps Full duplex mode.\n", dev->name);
+            /* Compare user defined mode with original ANAR value*/
+            /* If the setting is the same, do nothing, or we msut write the new setting to ANAR */
+            if (MII_ANAR_temp != 0x0040) {
+                change_flag |= 1;
+                /*Write the new setting to ANAR */
+                mdio_write(dev, np->phy_addr, 4, (mdio_read(dev, np->phy_addr, 4) & 0xFE1F) | 0x0040);
+//                printk("chenyp:mdio_read(dev, np->phy_addr, 4)=%x\n", mdio_read(dev, np->phy_addr, 4));
+            }
+
+            /* Set speed 10Mbps */
+            mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) & 0xDFFF);
+            /* Set full duplex */
+            mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) | 0x0100);
+
+            /* If AUTO bit is on and the setting is changed, issue REAUTO in BMCR */
+            if ((MII_BMCR_temp & 0x1000) && (change_flag == 1))
+                restart_autonegotiation(dev);
+            else if (!(MII_BMCR_temp & 0x1000))
+                enable_autonegotiation(dev);
+
+            /* Set MAC operating in Full Duplex Mode*/
+            writew(readw(ioaddr + FET_CR0) | 0x0400, ioaddr + FET_CR0);
+            np->full_duplex = 1;
+            np->chip_cmd |= FET_CmdFDuplex;
+        }
+    }
+    else
+        np->auto_negotiation = 1;
+    return change_flag;
+}
+
+static void set_media_duplex_mode(struct net_device *dev)
+{
+    netdev_private *np = (netdev_private *)dev->priv;
+    int change_flag =0;
+    unsigned long ioaddr = dev->base_addr;
+    /* record whether the ANAR value is changed, then we need trigger N-WAY*/
+
+
+    /* For flow control , according to user defined flow control option, */
+    /* to set the PAUSE ability in PHY's ANAR register*/
+    /* Only for VT3065 and VT3106*/
+    if (np->revision >= 0x40 && flow_control[np->card_idx] != 1) {
+        unsigned int MII_ANAR_temp=0;
+
+        /* Backup the value of PHY's ANAR register */
+        MII_ANAR_temp = mdio_read(dev, np->phy_addr, 4);
+
+        /* Disable PAUSE in ANAR*/
+        if (flow_control[np->card_idx] == 2) {
+            /* Check whether the PUASE has already be disabled*/
+            /* If not, disable it*/
+            if(MII_ANAR_temp & 0x0400) {
+                change_flag = 1;
+                mdio_write(dev, np->phy_addr, 4, MII_ANAR_temp & 0xFBFF);
+            }
+        }
+        /* Enable PAUSE in ANAR*/
+        if (flow_control[np->card_idx] == 3) {
+            /* Check whether the PUASE has already be enabled*/
+            /* If not, enable it*/
+            if(!(MII_ANAR_temp & 0x0400)) {
+                change_flag = 1;
+                mdio_write(dev, np->phy_addr, 4, MII_ANAR_temp | 0x0400);
+            }
+        }
+    }     
+    if (np->revision >= 0x80 || (np->revision >= 0x40 && np->revision < 0x80 && !(readb(ioaddr + FET_CFGC) & 0x80)))
+        change_flag=check_n_way_force(dev, change_flag);
+    else
+        check_legacy_force(dev);
+
+    /* For N-WAY force in VT3106 or VT3072 phy */
+    /* Make sure the PHY is VT3106's PHY or VT3072*/
+    /* So we check PHY REG 'h3 (PHY Identifier1) bit[9:4] is 6'b110100*/
+    if((mdio_read(dev, np->phy_addr, 3) & 0x03f0) == 0x0340 ||
+      ((mdio_read(dev, np->phy_addr, 3) & 0x03f0) == 0x0320 && 
+       (mdio_read(dev, np->phy_addr, 3) & 0x000f) >= 5)) {
+//      printk("chenyp:yes,it's 3072 phy here\n");
+        /* if forced mode, turn on bit 0 else turn off bit 0 in MII 0x10 register */
+        if(np->auto_negotiation == 0 && (np->revision >= 0x80 || (np->revision >= 0x40 && np->revision < 0x80 && !(readb(ioaddr + FET_CFGC) & 0x80))))
+            /* write PHY REG 'h10(PHY MODE CONFIG) bit[0] as 1'b1 */
+            mdio_write(dev, np->phy_addr, 0x10, mdio_read(dev, np->phy_addr, 0x10) | 0x0001);
+        else
+            /* write PHY REG 'h10(PHY MODE CONFIG) bit[0] as 1'b0 */
+            mdio_write(dev, np->phy_addr, 0x10, mdio_read(dev, np->phy_addr, 0x10) & 0xfffe);
+    }
+//printk("chenyp:set_media_force_mode:after force:phy0=%x, phy1=%x, phy2=%x, phy3=%x, phy4=%x, phy5=%x, mac8=%x, mac9=%x mac6d=%x\n",mdio_read(dev,np->phy_addr,0),mdio_read(dev,np->phy_addr,1),mdio_read(dev,np->phy_addr,2),mdio_read(dev,np->phy_addr,3),mdio_read(dev,np->phy_addr,4),mdio_read(dev,np->phy_addr,5),readb(ioaddr+0x08),readb(ioaddr+0x09),readb(ioaddr+0x6d));
+
+    if (np->auto_negotiation == 1) {
+        unsigned int PHY_BMCR_temp = 0;
+        unsigned int PHY_ANAR_temp = 0;
+        int restart_auto = 0;
+        int i;
+
+        PHY_BMCR_temp = mdio_read(dev, np->phy_addr, 0);
+        PHY_ANAR_temp = mdio_read(dev, np->phy_addr, 4);
+
+        /* Set Autonegotiation enable (ANEG_EN bit in Control register ) */
+        mdio_write(dev, np->phy_addr, 0 , mdio_read(dev, np->phy_addr, 0) | 0x1000);
+
+        // check the ANAR value is correct
+        // if not, write back the correct value, and retrigger Autonegotiation
+        if ((PHY_ANAR_temp & 0x01E0) != 0x01E0) {
+            mdio_write(dev, np->phy_addr, 4, PHY_ANAR_temp | 0x01E0);
+            restart_auto = 1;
+        }
+
+        /* for VT3043(DAVICOM) only, fix DaviCom PHY's bug */
+        if (np->revision < 0x20 ) {
+            unsigned int phy_ID;
+
+            phy_ID = (mdio_read(dev, np->phy_addr, 2) << 16) | (mdio_read(dev, np->phy_addr, 3));
+            if (phy_ID >= CID_DAVICOM && phy_ID < CID_DAVICOM_B)
+                restart_auto = 1;
+        }
+        if (restart_auto == 1)
+            restart_autonegotiation(dev);
+        /* Forced mode to auto mode, it will cause autonegotiation restart */
+        /* Wait until N-WAY finished*/
+        else if (!( PHY_BMCR_temp & 0x1000) && !(mdio_read(dev, np->phy_addr, 1) & 0x0020)) {
+            mdelay(2300);
+            for (i=0; i<0x1ff; i++)
+                if (mdio_read(dev, np->phy_addr, 1) & 0x0020)
+                    break;
+        }
+        do_autonegotiation(dev);
+    }
+}
+/* Set flow control capability accroding to ANAR and ANLPAR register in MII */
+/* The half duplex flow control capability is turn off now, because it's not in the spec.*/
+/* Follow the table 28B-3 in the IEEE Standard 802.3, 2000 Edition to set */
+/* full duplex flow control capability*/
+static void flow_control_ability(struct net_device *dev)
+{
+    netdev_private *np = (netdev_private *)dev->priv;
+    unsigned long ioaddr = dev->base_addr;
+    unsigned int PHYANAR_temp, PHYANLPAR_temp, MIISR_temp, FlowCR1_temp, Micr0_temp;
+
+    if (np->revision >= 0x40 && np->revision < 0x80) {
+       /* Read the old value of FlowCR1 register */
+        Micr0_temp = readb(ioaddr + FET_Micr0);
+
+        /*check whether NIC is operated in full duplex mode */
+        /* in full duplex mode*/
+        if (np->full_duplex == 1) {
+            /* read PAUSE and ASM_DIR in PHYANAR and MIISR register*/
+            PHYANAR_temp = (mdio_read(dev, np->phy_addr, 4) & 0x0C00) >> 10;
+            PHYANLPAR_temp = (mdio_read(dev, np->phy_addr, 5) & 0x0C00) >> 10;
+
+            /* Local: ASM_DIR=1, PAUSE=0   Remote: ASM_DIR=1, PAUSE=1*/
+            if ( (PHYANAR_temp & 0x02) && (!(PHYANAR_temp & 0x01)) && (PHYANLPAR_temp & 0x02) && (PHYANLPAR_temp & 0x01)) {
+                /* Disable PAUSE receive */
+                Micr0_temp = Micr0_temp & 0xF7;
+            }
+            /* Local: ASM_DIR=Don't care, PAUSE=1   Remote: ASM_DIR=Don't care, PAUSE=1*/
+            else if (PHYANAR_temp & 0x01 && PHYANLPAR_temp & 0x01) {
+                /* Enable PAUSE receive */
+                Micr0_temp = Micr0_temp | 0x08;
+            }
+            /* Local: ASM_DIR=1, PAUSE=1   Remote: ASM_DIR=1, PAUSE=0*/
+            else if ( (PHYANAR_temp & 0x02) && (PHYANAR_temp & 0x01) && (PHYANLPAR_temp & 0x02) && (!(PHYANLPAR_temp & 0x01))) {
+                /* Enable PAUSE receive */
+                Micr0_temp = Micr0_temp | 0x08;
+            }
+            /* Other conditions*/
+            else {
+                /* Disable PAUSE receive */
+                Micr0_temp = Micr0_temp & 0xF7;
+            }
+        }
+        /* in half duplex mode*/
+        else {
+            /* Disable PAUSE receive */
+            Micr0_temp = Micr0_temp & 0xF7;        
+        }
+        /* Disable half duplex flow control */
+        Micr0_temp = Micr0_temp & 0xFB;
+
+        /* Disable full duplex PAUSE transmit */
+        Micr0_temp = Micr0_temp & 0xEF;
+
+        /* Set the Micr0 register*/
+        writeb( Micr0_temp , ioaddr + FET_Micr0);
+    }
+    else if (np->revision >= 0x80) {
+        /* Read the old value of FlowCR1 register */
+        FlowCR1_temp = readb(ioaddr + FET_FlowCR1);
+
+
+        /*check whether NIC is operated in full duplex mode */
+        /* in full duplex mode*/
+        if (np->full_duplex == 1) {
+            /* read PAUSE and ASM_DIR in PHYANAR and MIISR register*/
+            PHYANAR_temp = (mdio_read(dev, np->phy_addr, 4) & 0x0C00) >> 10;
+            MIISR_temp = (readb(ioaddr + FET_MIISR) & 0x60) >> 5;
+
+            /* Local: ASM_DIR=1, PAUSE=0   Remote: ASM_DIR=1, PAUSE=1*/
+            if ( (PHYANAR_temp & 0x02) && (!(PHYANAR_temp & 0x01)) && (MIISR_temp & 0x02) && (MIISR_temp & 0x01)) {
+                /* Enable PAUSE transmit */
+                FlowCR1_temp = FlowCR1_temp | 0x04;
+                /* Disable PAUSE receive */
+                FlowCR1_temp = FlowCR1_temp & 0xFD;
+            }
+            /* Local: ASM_DIR=Don't care, PAUSE=1   Remote: ASM_DIR=Don't care, PAUSE=1*/
+            else if (PHYANAR_temp & 0x01 && MIISR_temp & 0x01) {
+                /* Enable PAUSE transmit */
+                FlowCR1_temp = FlowCR1_temp | 0x04;
+                /* Enable PAUSE receive */
+                FlowCR1_temp = FlowCR1_temp | 0x02;
+            }
+            /* Local: ASM_DIR=1, PAUSE=1   Remote: ASM_DIR=1, PAUSE=0*/
+            else if ( (PHYANAR_temp & 0x02) && (PHYANAR_temp & 0x01) && (MIISR_temp & 0x02) && (!(MIISR_temp & 0x01))) {
+                /* Disable PAUSE transmit */
+                FlowCR1_temp = FlowCR1_temp & 0xFB;
+                /* Enable PAUSE receive */
+                FlowCR1_temp = FlowCR1_temp | 0x02;
+            }
+            /* Other conditions*/
+            else {
+                /* Disable PAUSE transmit */
+                FlowCR1_temp = FlowCR1_temp & 0xFB;
+                /* Disable PAUSE receive */
+                FlowCR1_temp = FlowCR1_temp & 0xFD;
+            }
+        }
+        /* in half duplex mode*/
+        else {
+            /* Disable PAUSE transmit */
+            FlowCR1_temp = FlowCR1_temp & 0xFB;
+            /* Disable PAUSE receive */
+            FlowCR1_temp = FlowCR1_temp & 0xFD;        
+        }
+        /* Disable half duplex flow control */
+        FlowCR1_temp = FlowCR1_temp & 0xFE;
+
+        /* Set the FlowCR1 register*/
+        writeb( FlowCR1_temp , ioaddr + FET_FlowCR1);
+    }
+}
+
+static void set_flow_control(struct net_device *dev)
+{
+    unsigned long ioaddr = dev->base_addr;
+    unsigned int temp_FlowCR1=0;
+
+    /* Set {XHITH1, XHITH0, XLTH1, XLTH0} in FlowCR1 to {1, 0, 1, 1} depend on RD=64*/
+    /* Turn on XNOEN in FlowCR1*/
+    temp_FlowCR1 = (readb(ioaddr + FET_FlowCR1) | 0xB8);
+    writeb(temp_FlowCR1, ioaddr + FET_FlowCR1);
+
+    /* Set TxPauseTimer to 0xFFFF */
+    writew(0xFFFF, ioaddr + FET_TxPauseTimer);
+
+    /* Initialize RBRDU to Rx buffer count.*/
+    writeb(64, ioaddr + FET_FlowCR0);
+}
+
+#ifdef netdev_timer
+static void netdev_timer(unsigned long data)
+{
+    struct net_device *dev = (struct net_device *)data;
+    netdev_private *np = (netdev_private *)dev->priv;
+    int next_tick = 10*HZ;
+
+#if (LINUX_VERSION_CODE >= 0x02032a)
+    if (netif_queue_stopped(dev) != 0
+        && np->cur_tx[0] - np->dirty_tx[0] > 1
+        && jiffies - dev->trans_start > TX_TIMEOUT) {
+#else
+    if (test_bit(0, (void*)&dev->tbusy) != 0
+        && np->cur_tx[0] - np->dirty_tx[0] > 1
+        && jiffies - dev->trans_start > TX_TIMEOUT) {
+#endif
+        tx_timeout(dev);
+        return;
+    }
+    // link change will generate interrupt so we must not set_media_duplex_mode in timer
+    //set_media_duplex_mode(dev);
+    
+
+    np->timer.expires = jiffies + next_tick;
+    add_timer(&np->timer);
+}
+#endif
+#ifdef tx_timeout
+static void tx_timeout(struct net_device *dev)
+{
+    netdev_private *np = (netdev_private *)dev->priv;
+    unsigned long ioaddr = dev->base_addr;
+
+    printk(KERN_INFO "%s: Transmit timed out, status %4.4x, PHY status "
+           "%4.4x, resetting...\n",
+           dev->name, readw(ioaddr + FET_ISR0),
+           mdio_read(dev, np->phy_addr, 1));
+
+    /* Perhaps we should reinitialize the hardware here. */
+    dev->if_port = 0;
+    /* Stop and restart the chip's Tx processes . */
+    netdev_close(dev);
+    netdev_open(dev);
+        
+    /* Trigger an immediate transmit demand. */
+    dev->trans_start = jiffies;
+    np->stats.tx_errors++;
+    return;
+}
+#endif
+
+/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
+static void init_ring(struct net_device *dev)
+{
+    netdev_private *np = (netdev_private *)dev->priv;
+    int i, j;
+
+    if (np->revision >= 0x80 && enable_tagging[np->card_idx] == 1) {
+        for (i = 0; i < 8 ; i++) {
+            np->tx_full[i] = 0;
+            np->cur_tx[i] = 0;
+            np->dirty_tx[i] = 0;
+        }
+    }
+    else {
+        np->tx_full[0] = 0;
+        np->cur_tx[0] = 0;
+        np->dirty_tx[0] = 0;
+    }
+    np->cur_rx = 0; 
+    np->dirty_rx = 0;
+    np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
+    np->rx_head_desc = &np->rx_ring[0];
+
+    for (i = 0; i < RX_RING_SIZE; i++) {
+        np->rx_ring[i].rx_status = 0;
+        np->rx_ring[i].desc_length = cpu_to_le32(np->rx_buf_sz);
+        np->rx_ring[i].next_desc = virt_to_le32desc(&np->rx_ring[i+1]);
+        np->rx_skbuff[i] = 0;
+    }
+
+    /* Mark the last entry as wrapping the ring. */
+    np->rx_ring[i-1].next_desc = virt_to_le32desc(&np->rx_ring[0]);
+
+    /* Fill in the Rx buffers.  Handle allocation failure gracefully. */
+    for (i = 0; i < RX_RING_SIZE; i++) {
+        struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz);
+
+        np->rx_skbuff[i] = skb;
+        if (skb == NULL)
+            break;
+        skb->dev = dev;         /* Mark as being used by this device. */
+#if (LINUX_VERSION_CODE >= 0x020400)
+        np->rx_skbuff_dma[i]=pci_map_single(np->pdev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+
+        np->rx_ring[i].addr = cpu_to_le32(np->rx_skbuff_dma[i]);
+#else
+        np->rx_ring[i].addr = virt_to_le32desc(skb->tail);
+#endif
+        np->rx_ring[i].rx_status = cpu_to_le32(FET_DescOwn);
+    }
+    np->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
+
+    if (np->revision >= 0x80 && enable_tagging[np->card_idx] == 1) {
+        for (i = 0; i < 8; i++) {
+#if (LINUX_VERSION_CODE >= 0x20341)
+            np->tx_bufs[i] = pci_alloc_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE, &np->tx_bufs_dma[i]);
+#endif
+            for (j = 0; j < TX_RING_SIZE; j++) {
+                np->tx_skbuff[i][j] = 0;
+                np->tx_ring[i][j].tx_status = 0;
+                np->tx_ring[i][j].desc_length = cpu_to_le32(0x00e08000);
+                np->tx_ring[i][j].next_desc = virt_to_le32desc(&np->tx_ring[i][j+1]);
+#if (LINUX_VERSION_CODE >= 0x20341)
+                np->tx_buf[i][j] = np->tx_bufs[i] + PKT_BUF_SZ * j;
+#else
+                np->tx_buf[i][j] = kmalloc(PKT_BUF_SZ, GFP_KERNEL);
+#endif
+            }
+            np->tx_ring[i][j-1].next_desc = virt_to_le32desc(&np->tx_ring[i][0]);
+        }
+    }
+    else {
+#if (LINUX_VERSION_CODE >= 0x20341)
+        np->tx_bufs[0] = pci_alloc_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE, &np->tx_bufs_dma[0]);
+#endif
+        for (i = 0; i < TX_RING_SIZE; i++) {
+            np->tx_skbuff[0][i] = 0;
+            np->tx_ring[0][i].tx_status = 0;
+            np->tx_ring[0][i].desc_length = cpu_to_le32(0x00e08000);
+            np->tx_ring[0][i].next_desc = virt_to_le32desc(&np->tx_ring[0][i+1]);
+#if (LINUX_VERSION_CODE >= 0x20341)
+            np->tx_buf[0][i] = np->tx_bufs[0] + PKT_BUF_SZ * i;
+#else
+            np->tx_buf[0][i] = kmalloc(PKT_BUF_SZ, GFP_KERNEL);
+//           printk("chenyp:np->tx_buf[0][ %d ]=%x\n",i, np->tx_buf[0][i]);
+
+#endif
+        }
+        np->tx_ring[0][i-1].next_desc = virt_to_le32desc(&np->tx_ring[0][0]);
+    }
+    return;
+}
+
+static int start_tx(struct sk_buff *skb, struct net_device *dev)
+{
+    netdev_private *np = (netdev_private *)dev->priv;
+    unsigned entry;
+    unsigned int queue;
+    unsigned int VID = ((VID_setting[np->card_idx] < 4095) && (VID_setting[np->card_idx] > 0))
+                        ? VID_setting[np->card_idx] : 0;
+
+
+//printk("chenyp:start_tx:phy0=%x, phy1=%x, phy2=%x, phy3=%x, phy4=%x, phy5=%x, mac8=%x, mac99=%x mac80=%x\n",mdio_read(dev,np->phy_addr,0),mdio_read(dev,np->phy_addr,1),mdio_read(dev,np->phy_addr,2),mdio_read(dev,np->phy_addr,3),mdio_read(dev,np->phy_addr,4),mdio_read(dev,np->phy_addr,5),readb(ioaddr+0x08),readb(ioaddr+0x99),readb(ioaddr+0x80));
+    if( np->revision >= 0x80 && enable_tagging[np->card_idx] == 1)
+        queue = skb->priority % 8;
+    else
+        queue = 0;
+
+//printk("chenyp:start_tx:0x09=%x, 0x08=%x, tx=%x, rx=%x\n",readb(dev->base_addr+0x09), readb(dev->base_addr+0x08),readl(dev->base_addr+0x18),readl(dev->base_addr+0x1c));
+    /* Block a timer-based transmit from overlapping.  This could better be
+       done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
+
+#if(LINUX_VERSION_CODE >= 0x02032a)
+    if (netif_queue_stopped(dev)) {
+        netif_stop_queue(dev);
+        if (jiffies - dev->trans_start > TX_TIMEOUT)
+              ;
+//            tx_timeout(dev);
+        return 1;
+    }
+    else
+        netif_stop_queue(dev);
+#else
+    if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
+        /* This watchdog code is redundant with the media monitor timer. */
+        if (jiffies - dev->trans_start > TX_TIMEOUT){
+              ;
+//            tx_timeout(dev);
+        }
+        return 1;
+    }
+#endif
+
+    /* Explicitly flush packet data cache lines here. */
+
+    /* Caution: the write order is important here, set the descriptor word
+       with the "ownership" bit last.  No SMP locking is needed if the
+       cur_tx is incremented after the descriptor is consistent.  */
+
+    /* Calculate the next Tx descriptor entry. */
+    entry = np->cur_tx[queue] % TX_RING_SIZE;
+    np->tx_skbuff[queue][entry] = skb;
+   
+    if ((np->drv_flags & FET_ReqTxAlign)  && (long)skb->data & 3) {
+		/* Must use alignment buffer. */
+        memcpy(np->tx_buf[queue][entry], skb->data, skb->len);
+	np->tx_ring[queue][entry].addr = virt_to_le32desc(np->tx_buf[queue][entry]);
+    } else {
+#if (LINUX_VERSION_CODE >= 0x020400)
+        np->tx_skbuff_dma[queue][entry] = pci_map_single(np->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
+//        printk("chenyp:start_tx:pci_map_single:tx_skbuff_dma[ %d ][ %d ]=%x, len=%x\n",queue,entry, np->tx_skbuff_dma[queue][entry],skb->len);
+
+	np->tx_ring[queue][entry].addr =cpu_to_le32(np->tx_skbuff_dma[queue][entry]);
+#else
+	np->tx_ring[queue][entry].addr =virt_to_le32desc(skb->data);
+#endif
+    }
+    np->tx_ring[queue][entry].desc_length =
+        cpu_to_le32(0x00E08000 | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN));
+    if (np->revision >= 0x80) {
+        // for 802.1p/Q tagging
+        // if enable tagging, set Instag = 1 in TCR of RD
+        if (enable_tagging[np->card_idx] == 1 ) {
+            np->tx_ring[queue][entry].desc_length |= cpu_to_le32(0x00020000);
+            np->tx_ring[queue][entry].tx_status = cpu_to_le32(VID << 16);
+            np->tx_ring[queue][entry].tx_status |= cpu_to_le32(queue << 28) ;
+        }
+        np->tx_ring[queue][entry].tx_status |= cpu_to_le32(FET_DescOwn);
+    }
+    else
+        np->tx_ring[queue][entry].tx_status = cpu_to_le32(FET_DescOwn);    
+    np->cur_tx[queue]++;
+
+    /* Set the corresponding bits in TXQWAK to specify */
+    /* packets in which queues are to be sent */
+    if( np->revision >= 0x80 && enable_tagging[np->card_idx] == 1)
+        writeb(1 << queue, dev->base_addr + FET_TXQWAK);
+
+    /* Explicitly flush descriptor cache lines here. */
+
+    /* Wake the potentially-idle transmit channel. */
+    writeb(FET_CmdTxDemand1 | readb(dev->base_addr + FET_CR1) , dev->base_addr + FET_CR1);
+    if (np->cur_tx[queue] - np->dirty_tx[queue] < TX_QUEUE_LEN - 1)
+#if (LINUX_VERSION_CODE >= 0x02032a)
+        netif_wake_queue(dev);
+#else
+        clear_bit(0, (void*)&dev->tbusy);       /* Typical path */
+#endif
+    else
+    
+        np->tx_full[queue] = 1;
+    dev->trans_start = jiffies;
+    if (debug > 4) {
+        printk(KERN_INFO "%s: Transmit frame #%d queued in slot %d.\n",
+               dev->name, np->cur_tx[queue], entry);
+    }
+//    printk("chenyp:intr:%x %x \n",readb(ioaddr+0x08),readb(ioaddr+0x09));
+    return 0;
+}
+
+
+
+static void netdev_tx(struct net_device *dev)
+{
+    netdev_private *np = (netdev_private *)dev->priv;
+    unsigned long ioaddr = dev->base_addr;
+    unsigned int queue;
+
+    for (queue = 0; queue < 8; queue++) {
+        for (; np->cur_tx[queue] - np->dirty_tx[queue] > 0; np->dirty_tx[queue]++) {
+            int entry = np->dirty_tx[queue] % TX_RING_SIZE;
+            int txstatus = le32_to_cpu(np->tx_ring[queue][entry].tx_status);
+
+            if (txstatus & FET_DescOwn)
+                break;
+            if (debug > 6)
+                printk(KERN_INFO " Tx scavenge %d status %4.4x.\n",
+                       entry, txstatus);
+            if (txstatus & 0x8000) {
+                if (debug > 1)
+                    printk(KERN_INFO "%s: Transmit error, Tx status %4.4x.\n",
+                           dev->name, txstatus);
+                np->stats.tx_errors++;
+                
+                if (txstatus & 0x0800) { 
+                    /* uderrun happen */
+                    if (np->tx_thresh < 0x04) {
+                        np->tx_thresh += 1;
+                        writeb((readb(ioaddr + FET_BCR1) & 0xc7) | (np->tx_thresh << 3), ioaddr + FET_BCR1);
+                        writeb((readb(ioaddr + FET_TCR) & 0x1f) | (np->tx_thresh << 5), ioaddr + FET_TCR);
+                    }
+                    if (debug > 1)
+                        printk(KERN_INFO "%s: Transmitter underrun, increasing Tx "
+                        "threshold setting to %2.2x.\n", dev->name, np->tx_thresh);
+
+                    np->tx_ring[queue][entry].tx_status = cpu_to_le32(FET_DescOwn);
+                    writel(virt_to_bus(&np->tx_ring[queue][entry]), ioaddr + FET_CURR_TX_DESC_ADDR + (queue * 4));
+                    if (np->revision >= 0x80 && enable_tagging[np->card_idx] == 1)
+                        /* Set the corresponding bits in TXQWAK to specify */
+                        /* packets in which queues are to be sent */
+                        writeb(1 << queue, dev->base_addr + FET_TXQWAK);
+
+                    /* Turn on Tx On*/
+                    writew(FET_CmdTxOn | np->chip_cmd, dev->base_addr + FET_CR0);        
+
+                    /* Stats counted in Tx-done handler, just restart Tx. */
+                    writeb(FET_CmdTxDemand1 | readb(dev->base_addr + FET_CR1) , dev->base_addr + FET_CR1);
+
+                    break;
+                }    
+                if (txstatus & 0x0400) np->stats.tx_carrier_errors++;
+                if (txstatus & 0x0200) np->stats.tx_window_errors++;
+                if (txstatus & 0x0100) { 
+                    np->stats.tx_aborted_errors++;
+                    np->tx_ring[queue][entry].tx_status = cpu_to_le32(FET_DescOwn);
+                    writel(virt_to_bus(&np->tx_ring[queue][entry]), ioaddr + FET_CURR_TX_DESC_ADDR + (queue * 4));
+
+                    /* Set the corresponding bits in TXQWAK to specify */
+                    /* packets in which queues are to be sent */
+                    if (np->revision >= 0x80 && enable_tagging[np->card_idx] == 1)
+                        writeb(1 << queue, dev->base_addr + FET_TXQWAK);
+
+                    /* Turn on Tx On*/
+                    writew(FET_CmdTxOn | np->chip_cmd, dev->base_addr + FET_CR0);        
+                    /* Stats counted in Tx-done handler, just restart Tx. */
+                    writeb(FET_CmdTxDemand1 | readb(dev->base_addr + FET_CR1) , dev->base_addr + FET_CR1);
+                    printk(KERN_ERR "Tx Abort");
+                    break; 
+                }    
+                if (txstatus & 0x0080) np->stats.tx_heartbeat_errors++;
+                if (txstatus & 0x0002) np->stats.tx_fifo_errors++;
+#ifdef ETHER_STATS
+                if (txstatus & 0x0100) np->stats.collisions16++;
+#endif
+                /* Transmitter restarted in 'abnormal' handler. */
+            } else {
+#ifdef ETHER_STATS
+                if (txstatus & 0x0001) np->stats.tx_deferred++;
+#endif
+                np->stats.collisions += (txstatus >> 3) & 15;
+#if defined(NETSTATS_VER2)
+                np->stats.tx_bytes += np->tx_skbuff[queue][entry]->len;
+#endif
+                np->stats.tx_packets++;
+            }
+            /* Free the original skb. */
+#if (LINUX_VERSION_CODE >= 0x020400)
+            if (np->tx_skbuff_dma[queue][entry] != 0) {
+                pci_unmap_single(np->pdev, np->tx_skbuff_dma[queue][entry], np->tx_skbuff[queue][entry]->len, PCI_DMA_TODEVICE);
+//                printk("chenyp:netdev_tx:pci_unmap_single: np->tx_skbuff_dma[ %d ][ %d ]=%x,len=%x\n",queue,entry, np->tx_skbuff_dma[queue][entry],np->tx_skbuff[queue][entry]->len);
+                np->tx_skbuff_dma[queue][entry] = 0;
+            }
+#endif
+            dev_free_skb(np->tx_skbuff[queue][entry]);
+
+            np->tx_skbuff[queue][entry] = 0;
+        }
+#if (LINUX_VERSION_CODE >= 0x02032a)
+        if (np->tx_full[queue] && netif_queue_stopped(dev)
+            && np->cur_tx[queue] - np->dirty_tx[queue] < TX_QUEUE_LEN - 4) {
+#else
+        if (np->tx_full[queue] && dev->tbusy
+            && np->cur_tx[queue] - np->dirty_tx[queue] < TX_QUEUE_LEN - 4) {
+#endif
+            /* The ring is no longer full, clear tbusy. */
+            np->tx_full[queue] = 0;
+#if (LINUX_VERSION_CODE >= 0x02032a)
+            netif_wake_queue(dev);
+#else
+            clear_bit(0, (void*)&dev->tbusy);
+            mark_bh(NET_BH);
+#endif
+        }
+        if (np->revision < 0x80 || (np->revision >= 0x80 && enable_tagging[np->card_idx] != 1))
+            break;
+    }
+}
+
+/* The interrupt handler does all of the Rx thread work and cleans up
+   after the Tx thread. */
+static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
+{
+    struct net_device *dev = (struct net_device *)dev_instance;
+    unsigned long ioaddr = dev->base_addr;
+    int boguscnt = max_interrupt_work;
+
+
+    do {
+        u32 intr_status = readw(ioaddr + FET_ISR0);
+
+        /* Acknowledge all of the current interrupt sources ASAP. */
+        writew(intr_status & 0xffff, ioaddr + FET_ISR0);
+
+        if (debug > 4)
+            printk(KERN_INFO "%s: Interrupt, status %4.4x.\n",
+                   dev->name, intr_status);
+
+        if (intr_status == 0)
+            break;
+//printk("chenyp:intr_hand:phy0=%x, phy1=%x, phy2=%x, phy3=%x, phy4=%x, phy5=%x, mac8=%x, mac9=%x mac6d=%x\n",mdio_read(dev,np->phy_addr,0),mdio_read(dev,np->phy_addr,1),mdio_read(dev,np->phy_addr,2),mdio_read(dev,np->phy_addr,3),mdio_read(dev,np->phy_addr,4),mdio_read(dev,np->phy_addr,5),readb(ioaddr+0x08),readb(ioaddr+0x09),readb(ioaddr+0x6d));
+
+        if (intr_status & (FET_ISR_PRX | FET_ISR_RXE | FET_ISR_PKTRACE |
+                           FET_ISR_GENI | FET_ISR_RU | FET_ISR_NORBF))
+            netdev_rx(dev);
+	netdev_tx(dev);
+//chenyp
+//    printk("chenyp:intr:%x %x \n",readb(ioaddr+0x08),readb(ioaddr+0x09));
+        /* Abnormal error summary/uncommon events handlers. */
+        if (intr_status & (FET_ISR_BE | FET_ISR_SRCI | FET_ISR_CNT | FET_ISR_TXE | FET_ISR_TU))
+            netdev_error(dev, intr_status);
+
+        if (--boguscnt < 0) {
+            if (debug > 1) 
+                printk(KERN_INFO "%s: Too much work at interrupt, "
+                       "status=0x%4.4x.\n",
+                   dev->name, intr_status);
+            break;
+        }
+    } while (1);
+
+    if (debug > 3)
+        printk(KERN_INFO "%s: exiting interrupt, status=%#4.4x.\n",
+               dev->name, readw(ioaddr + FET_ISR0));
+
+    return;
+}
+
+static void checksum_offload(struct sk_buff *skb, u32 rx_PQSTS)
+{
+    if (rx_PQSTS & IPKT) {
+        if (!(rx_PQSTS & IPOK)) {
+            skb->ip_summed = CHECKSUM_NONE;
+            return;
+        }
+        else {
+            if (rx_PQSTS & TCPKT) {
+                if (!(rx_PQSTS & TUOK)) {
+                    skb->ip_summed = CHECKSUM_NONE;
+                    return;
+                }
+            }
+            if (rx_PQSTS & UDPKT) {
+                if (!(rx_PQSTS & TUOK)) {
+                    skb->ip_summed = CHECKSUM_NONE;
+                    return;
+                }
+            }
+        }
+        skb->ip_summed = CHECKSUM_UNNECESSARY;
+    }
+}
+/* Because our RD needed be DWORD byte aligned, so IP won't be DWORD byte aligned*/
+/* We must shift 2 bytes of the data for IP header DWORD byte aligned */
+static void shift_for_IP_byte_aligned(struct sk_buff *skb, unsigned int pkt_len)
+{
+//   char tmp;
+    int i;
+
+    for (i = pkt_len - 1; i >= 0 ; i--)
+        *(skb->data + i + 2) = *(skb->data + i);
+    skb->data += 2;
+    skb->tail += 2;
+}
+
+/* This routine is logically part of the interrupt handler, but isolated
+   for clarity and better register allocation. */
+static int netdev_rx(struct net_device *dev)
+{
+    netdev_private *np = (netdev_private *)dev->priv;
+    unsigned long ioaddr = dev->base_addr;
+    int entry = np->cur_rx % RX_RING_SIZE;
+    int boguscnt = np->dirty_rx + RX_RING_SIZE - np->cur_rx;
+    u32 rx_PQSTS;
+
+    if (debug > 4) {
+        printk(KERN_INFO " In netdev_rx(), entry %d status %8.8x.\n",
+               entry, np->rx_head_desc->rx_status);
+    }
+
+    /* If EOP is set on the next entry, it's a new packet. Send it up. */
+    while ( ! (np->rx_head_desc->rx_status & cpu_to_le32(FET_DescOwn))) {
+        rx_desc *desc = np->rx_head_desc;
+        u32 desc_status = le32_to_cpu(desc->rx_status);
+        int data_size = desc_status >> 16;
+
+        if (debug > 4)
+            printk(KERN_INFO "  netdev_rx() status is %4.4x.\n",
+                   desc_status);
+        if (--boguscnt < 0)
+            break;
+
+#if (LINUX_VERSION_CODE >= 0x020400)
+        if (np->rx_skbuff_dma[entry] != 0) {
+            pci_unmap_single (np->pdev, np->rx_skbuff_dma[entry], np->rx_buf_sz , PCI_DMA_FROMDEVICE);
+//               printk("chenyp:netdev_rx:pci_unmap_single: rx_skbuff_dma[ %d ]=%x, len=%x\n",entry,np->rx_skbuff_dma[entry],np->rx_buf_sz);
+            np->rx_skbuff_dma[entry] = 0;
+        }
+#endif
+        /* for 802.1p/Q tagging, if enable tagging,and we don't set VID (VID = 0) */
+        /* then we must drops untagged packets */
+        if (np->revision >= 0x80 && enable_tagging[np->card_idx] == 1 && VID_setting[np->card_idx] != 0) {
+            /* untagged frame ,drop it*/
+            if (!(np->rx_head_desc->desc_length & 0x00010000)) {
+                entry = (++np->cur_rx) % RX_RING_SIZE;
+                np->rx_head_desc = &np->rx_ring[entry];
+                continue;
+            }
+        }
+        if ( (desc_status & (FET_RxWholePkt | FET_RxErr)) !=  FET_RxWholePkt) {
+            if ((desc_status & FET_RxWholePkt) !=  FET_RxWholePkt) {
+                printk(KERN_INFO "%s: Oversized Ethernet frame spanned "
+                       "multiple buffers, entry %#x length %d status %4.4x!\n",
+                       dev->name, np->cur_rx, data_size, desc_status);
+                printk(KERN_INFO "%s: Oversized Ethernet frame %p vs %p.\n",
+                       dev->name, np->rx_head_desc,
+                       &np->rx_ring[np->cur_rx % RX_RING_SIZE]);
+                np->stats.rx_length_errors++;
+            } else if (desc_status & FET_RxErr) {
+                /* There was a error. */
+                if (debug > 2)
+                    printk(KERN_INFO "  netdev_rx() Rx error was %8.8x.\n",
+                           desc_status);
+                np->stats.rx_errors++;
+                if (desc_status & 0x0030) np->stats.rx_length_errors++;
+                if (desc_status & 0x0048) np->stats.rx_fifo_errors++;
+                if (desc_status & 0x0004) np->stats.rx_frame_errors++;
+                if (desc_status & 0x0002) np->stats.rx_crc_errors++;
+            }
+        } else {
+            struct sk_buff *skb;
+            /* Length should omit the CRC */
+            int pkt_len = data_size - 4;
+            unsigned int wLen = 0, wSAP = 0, wActualLen = 0;
+
+            /* For conforming IEEE 802.3 spec
+             * If the incoming packet is IEE 802.3 frmae/IEEE 802.3 SNAP frame, get
+             * RX_Length in RDES0 from the incoming packet, subtract Ethernet header
+             * length and CRC length from it. Then, compare the result with L/T field
+             * of the packet. If they're not equal, descard this packet.
+             */
+
+            wLen = (*(np->rx_skbuff[entry]->tail + 12) << 8) + (*(np->rx_skbuff[entry]->tail + 13));
+            if ( wLen >= 46 && wLen <= 1500) {   // IEEE 802.3/IEEE 802.3 SNAP frame
+    	        wSAP = (*(np->rx_skbuff[entry]->tail + 14) << 8) + (*(np->rx_skbuff[entry]->tail + 15));
+                if (wSAP != 0xFFFF)               // exclude Novell's Ethernet 802.3 frame
+                    wActualLen = data_size - U_HEADER_LEN - U_CRC_LEN;         // real packet length
+            }
+            if (!(wLen >= 46 && wLen <= 1500 && wSAP != 0xFFFF && wLen != wActualLen)) {
+                /* Check if the packet is long enough to accept without copying
+                   to a minimally-sized skbuff. */
+                if (pkt_len < rx_copybreak
+                    && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+//        printk("chenyp:dev_alloc_skb:skb=%x\n",skb);
+
+                    skb->dev = dev;
+                    skb_reserve(skb, 2);    /* 16 byte align the IP header */
+#if HAS_IP_COPYSUM          /* Call copy + cksum if available. */
+                    eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0);
+                    skb_put(skb, pkt_len);
+#else
+                    memcpy(skb_put(skb, pkt_len), np->rx_skbuff[entry]->tail,
+                           pkt_len);
+#endif
+        	} else {
+        	    if( IP_byte_align[np->card_idx] == 1) { /* for byte align the IP header, or the checksum will fail in some condition*/
+                        skb = np->rx_skbuff[entry];
+                        shift_for_IP_byte_aligned(skb, pkt_len);
+                        skb_put(skb, pkt_len);
+                        np->rx_skbuff[entry] = NULL;
+                    }
+                    else {
+                        skb_put(skb = np->rx_skbuff[entry], pkt_len);
+                        np->rx_skbuff[entry] = NULL;
+                    }
+                }
+                skb->protocol = eth_type_trans(skb, dev);
+                skb->ip_summed = CHECKSUM_NONE;
+
+                /* receive checksum_offload */
+                if (np->revision >= 0x80 && csum_offload[np->card_idx] == 1) {
+                    rx_PQSTS = le32_to_cpu((np->rx_head_desc->desc_length << 8) >> 24);
+                    checksum_offload(skb, rx_PQSTS);
+                }
+                netif_rx(skb);
+                dev->last_rx = jiffies;
+#if defined(NETSTATS_VER2)
+                np->stats.rx_bytes += skb->len;
+#endif
+                np->stats.rx_packets++;
+            }
+        }
+        entry = (++np->cur_rx) % RX_RING_SIZE;
+        np->rx_head_desc = &np->rx_ring[entry];
+    }
+
+    /* Refill the Rx ring buffers. */
+    for (; np->cur_rx - np->dirty_rx > 0; np->dirty_rx++) {
+        struct sk_buff *skb;
+        entry = np->dirty_rx % RX_RING_SIZE;
+        if (np->rx_skbuff[entry] == NULL) {
+            skb = dev_alloc_skb(np->rx_buf_sz);
+//        printk("chenyp:dev_alloc_skb:skb=%x\n",skb);
+
+            np->rx_skbuff[entry] = skb;
+            if (skb == NULL)
+                break;          /* Better luck next round. */
+            skb->dev = dev;         /* Mark as being used by this device. */
+#if (LINUX_VERSION_CODE >= 0x020400)
+            np->rx_skbuff_dma[entry]=pci_map_single(np->pdev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+//            printk("chenyp:netdev_rx:pci_map_single:rx_skbuff_dma%d=%x, len=%x\n",entry, np->rx_skbuff_dma[entry],np->rx_buf_sz);
+
+            np->rx_ring[entry].addr = cpu_to_le32(np->rx_skbuff_dma[entry]);
+#else
+            np->rx_ring[entry].addr = virt_to_le32desc(skb->tail);
+#endif
+        }
+        np->rx_ring[entry].rx_status = cpu_to_le32(FET_DescOwn);
+
+        // update RXRDU in FlowCR1 after return descriptor/buffer to MAC.
+        if (np->revision >=0x80 )
+            writeb(1, ioaddr + FET_FlowCR0);
+    }
+
+    /* Pre-emptively restart Rx engine. */
+    //writew(FET_CmdRxDemand | np->chip_cmd, dev->base_addr + FET_CR0);
+    return 0;
+}
+
+static void netdev_error(struct net_device *dev, int intr_status)
+{
+    netdev_private *np = (netdev_private *)dev->priv;
+    unsigned long ioaddr = dev->base_addr;
+    int i;
+
+    /* Port Status change*/
+    if (intr_status & FET_ISR_SRCI ) {
+        /*check whether link fail */
+        if (readb(ioaddr + FET_MIISR) & 0x02) {
+            printk(KERN_INFO "%s: Link Fail.\n",dev->name);
+            np->full_duplex = 0;
+            np->chip_cmd &= FET_CmdNoFDuplex;
+	} else {
+            if (np->revision >=0x80)
+                set_flow_control(dev);
+
+            if (np->revision < 0x20 )
+                /* wait for writing  back the ANLPAR in PHY and MIISR in MAC */
+                /* then we won't get the wrong value in do_autonegotiation function */
+                mdelay(100);
+
+            /* In auto mode, check the speed and duplex mode again */
+            /* In force mode, do nothing */
+            if (np->auto_negotiation == 1)
+                do_autonegotiation(dev);
+            printk(KERN_INFO "%s: Link success.\n", dev->name);
+
+            /* if VT3106 and VT3065 */
+            if (np->revision >= 0x40)
+                flow_control_ability (dev);
+        }
+        if (debug > 5)
+            printk(KERN_ERR "%s: MII status changed: Autonegotiation "
+                   "advertising %4.4x  partner %4.4x.\n", dev->name,
+               mdio_read(dev, np->phy_addr, 4),
+               mdio_read(dev, np->phy_addr, 5)
+               );            
+    }
+    if (intr_status & FET_ISR_CNT) {
+        np->stats.rx_crc_errors += readw(ioaddr + FET_CRC_tally);
+        np->stats.rx_missed_errors  += readw(ioaddr + FET_MPA_tally);
+        writel(0, ioaddr + FET_MPA_tally);
+    }
+    if (intr_status & FET_ISR_TXE) {
+             
+       
+    }
+    if (intr_status & FET_ISR_TU) {
+    }
+    if ((intr_status & ~(FET_ISR_SRCI | FET_ISR_CNT |
+                         FET_ISR_TXE|FET_ISR_ABTI))) {
+        if (debug > 3)                                                
+        printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
+               dev->name, intr_status);
+        if (np->revision >= 0x80)
+            for(i = 0; i < 8; i++) {
+                /* Set the corresponding bits in TXQWAK to specify */
+                /* packets in which queues are to be sent */
+                writeb(1 << i, dev->base_addr + FET_TXQWAK);
+            }
+        /* Recovery for other fault sources not known. */
+        writeb(FET_CmdTxDemand1 | readb(dev->base_addr + FET_CR1) , dev->base_addr + FET_CR1);
+    }
+       
+}
+
+static struct net_device_stats *get_stats(struct net_device *dev)
+{
+    netdev_private *np = (netdev_private *)dev->priv;
+    unsigned long ioaddr = dev->base_addr;
+
+    /* Nominally we should lock this segment of code for SMP, although
+       the vulnerability window is very small and statistics are
+       non-critical. */
+    np->stats.rx_crc_errors += readw(ioaddr + FET_CRC_tally);
+    np->stats.rx_missed_errors  += readw(ioaddr + FET_MPA_tally);
+    writel(0, ioaddr + FET_MPA_tally);
+    np->stats.rx_missed_errors=0;
+    np->stats.rx_crc_errors=0;
+    return &np->stats;
+}
+
+/* The big-endian AUTODIN II ethernet CRC calculation.
+   N.B. Do not use for bulk data, use a table-based routine instead.
+   This is common code and should be moved to net/core/crc.c */
+static unsigned const ethernet_polynomial = 0x04c11db7U;
+static inline u32 ether_crc(int length, unsigned char *data)
+{
+    int crc = -1;
+
+    while(--length >= 0) {
+        unsigned char current_octet = *data++;
+        int bit;
+        for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
+            crc = (crc << 1) ^
+                ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
+        }
+    }
+    return crc;
+}
+
+static void set_rx_mode(struct net_device *dev)
+{
+    unsigned long ioaddr = dev->base_addr;
+    u32 mc_filter[2];           /* Multicast hash filter */
+    u8 rx_mode;                 /* Note: 0x02=accept runt, 0x01=accept errs */
+
+    if (dev->flags & IFF_PROMISC) {         /* Set promiscuous. */
+        /* Unconditionally log net taps. */
+        printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
+        rx_mode = 0x1C;
+    } else if ((dev->mc_count > multicast_filter_limit)
+               ||  (dev->flags & IFF_ALLMULTI)) {
+        /* Too many to match, or accept all multicasts. */
+        writel(0xffffffff, ioaddr + FET_MAR0);
+        writel(0xffffffff, ioaddr + FET_MAR4);
+        rx_mode = 0x0C;
+    } else {
+        struct dev_mc_list *mclist;
+        int i;
+        memset(mc_filter, 0, sizeof(mc_filter));
+        for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+             i++, mclist = mclist->next) {
+            set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26,
+                    mc_filter);
+        }
+        writel(mc_filter[0], ioaddr + FET_MAR0);
+        writel(mc_filter[1], ioaddr + FET_MAR4);
+        rx_mode = 0x0C;
+    }
+    writeb(readb(ioaddr + FET_RCR) | rx_mode, ioaddr + FET_RCR);
+}
+
+static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	u16 *data = (u16 *)&rq->ifr_data;
+
+	switch(cmd) {
+	case SIOCGMIIPHY:		/* Get the address of the PHY in use. */
+		data[0] = ((netdev_private *)dev->priv)->phy_addr & 0x1f;
+		/* Fall Through */
+	case SIOCGMIIREG:		/* Read the specified MII register. */
+		data[3] = mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f);
+		return 0;
+	case SIOCSMIIREG:		/* Write the specified MII register */
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
+		return 0;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int netdev_close(struct net_device *dev)
+{
+    unsigned long ioaddr = dev->base_addr;
+    netdev_private *np = (netdev_private *)dev->priv;
+    int i, j;
+    int ww;
+
+#if (LINUX_VERSION_CODE >= 0x02032a)
+    netif_stop_queue(dev);
+#else
+    dev->start = 0;
+    dev->tbusy = 1;
+#endif
+    if (debug > 1)
+        printk(KERN_INFO "%s: Shutting down ethercard, status was %4.4x.\n",
+               dev->name, readw(ioaddr + FET_CR0));
+
+    /* Disable interrupts by clearing the interrupt mask. */
+    writew(0x0000, ioaddr + FET_IMR0);
+    /* if the chip is 3065, we must patch shutdown bug*/
+    
+    if ((np->revision >= 0x40) && (np->revision <= 0x80)) { 
+
+        //Nic Loop Back On
+        writeb(readb(ioaddr + FET_TCR) | 0x01, ioaddr + FET_TCR);
+        
+       //Tx Off
+        writeb(readb(ioaddr + FET_CR0) & 0xEF, ioaddr + FET_CR0);
+        
+        // W_MAX_TIMEOUT is the timeout period
+        for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+            if((readb(ioaddr + FET_CR0) & 0x10) == 0)
+                break; 
+        } 
+        
+        //Rx Off
+        writeb(readb(ioaddr + FET_CR0) & 0xF7, ioaddr + FET_CR0);
+        
+        // W_MAX_TIMEOUT is the timeout period
+        for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+            if((readb(ioaddr + FET_CR0) & 0x08) == 0)
+                break; 
+        } 
+        
+        if (ww == W_MAX_TIMEOUT) {
+    
+            // Turn on fifo test
+            writew(readw(ioaddr + FET_GFTEST) | 0x0001, ioaddr + FET_GFTEST);
+            // Turn on fifo reject
+            writew(readw(ioaddr + FET_GFTEST) | 0x0800, ioaddr + FET_GFTEST);
+            // Turn off fifo test
+            writew(readw(ioaddr + FET_GFTEST) & 0xFFFE, ioaddr + FET_GFTEST);
+        }
+        
+        //Nic Loop Back Off
+        writeb(readb(ioaddr + FET_TCR) & 0xFE, ioaddr + FET_TCR);
+    }
+    
+    /* Stop the chip's Tx and Rx processes. */
+    writew(FET_CmdStop, ioaddr + FET_CR0);
+    del_timer(&np->timer);
+
+    free_irq(dev->irq, dev);
+    /* Free all the skbuffs in the Rx queue. */
+    for (i = 0; i < RX_RING_SIZE; i++) {
+        np->rx_ring[i].rx_status = 0;
+        np->rx_ring[i].addr = 0xBADF00D0; /* An invalid address. */
+        if (np->rx_skbuff[i]) {
+#if LINUX_VERSION_CODE < 0x20100
+            np->rx_skbuff[i]->free = 1;
+#endif
+            dev_free_skb(np->rx_skbuff[i]);
+//            printk("chenyp:dev_free_skb: np->rx_skbuff[ %d ]=%x\n",i,np->rx_skbuff[i]);
+        }
+        np->rx_skbuff[i] = 0;
+    }
+    if (np->revision >= 0x80) {
+        for (j = 0; j < 8; j++) {
+#if (LINUX_VERSION_CODE >= 0x20341)
+            if (np->tx_bufs[j])
+                pci_free_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE, np->tx_bufs[j], np->tx_bufs_dma[j]);
+#endif
+            for (i = 0; i < TX_RING_SIZE; i++) {
+                if (np->tx_skbuff[j][i])
+                    dev_free_skb(np->tx_skbuff[j][i]);
+//                    printk("chenyp:dev_free_skb:np->tx_skbuff[ %d ][ %d ]=%x\n",j, i,np->tx_skbuff[j][i]);
+
+                np->tx_skbuff[j][i] = 0;
+                if (np->tx_buf[j][i]) {
+#if (LINUX_VERSION_CODE < 0x20341)
+                    kfree(np->tx_buf[j][i]);
+//                    printk("chenyp:kfree:np->tx_buf[ %d ][ %d ]=%x\n",j,i,np->tx_buf[j][i]);
+#endif
+                    np->tx_buf[j][i] = 0;
+                }
+            }
+        }
+    }
+    else {
+#if (LINUX_VERSION_CODE >= 0x20341)
+        if (np->tx_bufs[0]) {
+            pci_free_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE, np->tx_bufs[0], np->tx_bufs_dma[0]);
+        }
+
+#endif
+        for (i = 0; i < TX_RING_SIZE; i++) {
+            if (np->tx_skbuff[0][i])
+                dev_free_skb(np->tx_skbuff[0][i]);
+//                    printk("chenyp:dev_free_skb:tx_skbuff[0][ %d ]=%x\n",i,np->tx_skbuff[0][i]);
+
+            np->tx_skbuff[0][i] = 0;
+#if (LINUX_VERSION_CODE < 0x20341)
+            if (np->tx_buf[0][i]) {
+                kfree(np->tx_buf[0][i]);
+//                    printk("chenyp:kfree:np->tx_buf[ 0 ][ %d ]=%x\n",i,np->tx_buf[0][i]);
+
+                np->tx_buf[0][i] = 0;
+            }
+#endif
+        }
+    }
+    MOD_DEC_USE_COUNT;
+    return 0;
+}
+
+#ifndef MODULE
+#if LINUX_VERSION_CODE > 0x02032a
+
+
+enum via_rhine_chips {
+         VT3043 = 0,
+         VT6102,
+         VT6105,
+};
+
+static struct pci_device_id linux_fet_pci_tbl[] __devinitdata =
+{
+	{0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT3043},
+	{0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6102},
+	{0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105},
+	{0,}			/* terminate list */
+};
+
+MODULE_DEVICE_TABLE(pci, linux_fet_pci_tbl);
+static int __devinit linux_fet_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+    struct net_device *dev;
+    netdev_private *np;
+    int i;
+    unsigned char byOrgValue;
+    int ww;
+    u8 mode3_reg;
+    u32 revision=0x42;
+    int chip_idx = (int) ent->driver_data;
+    static int card_idx = -1;
+    long ioaddr;
+    int io_size;
+    int pci_flags;
+    u32 pci_class_rev;
+    pci_read_config_dword(pdev, PCI_REVISION_ID, &pci_class_rev);
+
+    revision = (pci_class_rev << 24) >> 24;
+    card_idx++;
+	pci_flags = pci_tbl[chip_idx].pci_flags;
+	io_size = pci_tbl[chip_idx].io_size;
+
+        /* Ask low-level code to enable I/O and memory. */
+        /* Wake up the device if it was suspended. */
+	if (pci_enable_device (pdev))
+		goto err_out;
+
+	/* this should always be supported */
+	if (!pci_dma_supported(pdev, 0xffffffff)) {
+		printk(KERN_ERR "32-bit PCI DMA addresses not supported by the card!?\n");
+		goto err_out;
+	}
+	pdev->dma_mask=0xffffffff;
+	/* sanity check */
+	if ((pci_resource_len (pdev, 0) < io_size) ||
+	    (pci_resource_len (pdev, 1) < io_size)) {
+		printk (KERN_ERR "Insufficient PCI resources, aborting\n");
+		goto err_out;
+	}
+
+	ioaddr = pci_resource_start (pdev,  0);
+	/* enable PCI bus-mastering */
+//	if (pci_flags & PCI_USES_MASTER)
+		pci_set_master (pdev);
+	/* request all PIO and MMIO regions just to make sure
+	 * noone else attempts to use any portion of our I/O space */
+
+
+
+	dev = alloc_etherdev(sizeof(*np));
+	if (dev == NULL) {
+		printk (KERN_ERR "init_ethernet failed for card #%d\n",
+			card_idx);
+		goto err_out_free_dma;
+	}
+	SET_MODULE_OWNER(dev);
+	if (register_netdev (dev)){
+            
+	    goto err_out;
+        }
+	if (pci_request_regions (pdev, dev->name))
+		goto err_out;
+
+    // if vt3065     
+    if (revision>=0x40) {
+       // clear sticky bit before reset & read ethernet address
+       byOrgValue = readb(ioaddr + FET_STICKHW);    
+       byOrgValue = byOrgValue & 0xFC;
+       writeb(byOrgValue, ioaddr + FET_STICKHW);        
+       // disable force PME-enable 
+       writeb(0x80, ioaddr + FET_WOLCG_CLR);
+       // disable power-event config bit
+       writeb(0xFF, ioaddr + FET_WOLCR_CLR);
+       // clear power status 
+       writeb(0xFF, ioaddr + FET_PWRCSR_CLR);   
+    }
+    
+        
+    /* Reset the chip to erase previous misconfiguration. */
+    writew(FET_CmdReset, ioaddr + FET_CR0);
+    // if vt3043 delay after reset
+    if (revision <0x40) {
+       udelay(10000);
+    }
+
+    // polling till software reset complete
+    // W_MAX_TIMEOUT is the timeout period
+    for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+        if ((readw(ioaddr + FET_CR0) & FET_CmdReset) == 0 )
+            break;
+    }
+       
+    // issue AUTOLoad in EECSR to reload eeprom
+    writeb(0x20, ioaddr + FET_EECSR);
+      
+    // if vt3065 delay after reset
+    if (revision >=0x40 ) { 
+
+        // delay 8ms to let MAC stable
+        mdelay(8);
+        // for 3065D, EEPROM reloaded will cause bit 0 in CFGA turned on.
+        // it makes MAC receive magic packet automatically. So, driver turn it off.
+        writeb(readb(ioaddr + FET_CFGA) & 0xFE, ioaddr + FET_CFGA);
+    }
+
+    /* turn on bit2 in PCI configuration register 0x53 , only for 3065*/
+    if (revision >= 0x40) {
+        pci_read_config_byte(pdev,PCI_REG_MODE3,&mode3_reg);
+        pci_write_config_byte(pdev,PCI_REG_MODE3,mode3_reg|MODE3_MIION);
+    }
+
+    /* back off algorithm ,disable the right-most 4-bit off FET_CFGD*/
+    writeb(readb(ioaddr + FET_CFGD) & (~(FET_CRADOM | FET_CAP | FET_MBA | FET_BAKOPT)), ioaddr + FET_CFGD);
+
+ //   dev = init_etherdev(init_dev, 0);
+
+    printk(KERN_INFO "%s: %s\n",dev->name, pci_tbl[chip_idx].name);
+    printk(KERN_INFO "%s: IO Address = 0x%lx, MAC Address = ",dev->name, ioaddr);
+    /* Ideally we would read the EEPROM but access may be locked. */
+    for (i = 0; i < 6; i++)
+        dev->dev_addr[i] = readb(ioaddr + FET_PAR + i);
+    for (i = 0; i < 5; i++)
+            printk("%2.2x:", dev->dev_addr[i]);
+    printk("%2.2x, IRQ = %d.\n", dev->dev_addr[i], pdev->irq);
+    if (init_device_data (dev, pdev, ioaddr, revision, pdev->irq, chip_idx, card_idx) == -1)
+       return -ENOMEM;
+    return 0;
+err_out_free_dma:
+err_out:
+	return -ENODEV;
+}
+static void __devexit linux_fet_remove_one (struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata (pdev);
+//	struct rtl8139_private *np;
+
+	printk ("%s: enter linux_fet_remove_one\n", dev->name);
+
+//	assert (dev != NULL);
+//	np = dev->priv;
+//	assert (np != NULL);
+
+//	unregister_netdev (dev);
+
+//	__rtl8139_cleanup_dev (dev);
+
+	printk ("%s: leave linux_fet_remove_one\n", dev->name);
+
+}
+
+static struct pci_driver linux_fet_driver = {
+	name:		"linux_fet",
+	id_table:	linux_fet_pci_tbl,
+	probe:		linux_fet_init_one,
+	remove:		linux_fet_remove_one,
+
+};
+
+static int __init linux_fet_init (void)
+{
+/* this is printed whether or not devices are found in probe */
+
+	printk(version);
+/* ifdef MODULE */
+	return pci_module_init (&linux_fet_driver);
+}
+
+static void __exit linux_fet_cleanup (void)
+{
+//	printk("chenyp:exit binding\n");
+
+	pci_unregister_driver (&linux_fet_driver);
+}
+
+module_init(linux_fet_init);
+module_exit(linux_fet_cleanup);
+
+#else /* LINUX_VERSION_CODE > 0x02032a */
+int via_rhine_probe(struct net_device *dev)
+{
+    if (debug)
+        printk(KERN_INFO "%s", version);
+    return pci_drv_register(&via_rhine_drv_id, dev);
+}
+#endif /* if LINUX_VERSION_CODE > 0x02032a */
+#endif /* ifndef MODULE */
+
+#ifdef MODULE
+int init_module(void)
+{
+    if (debug)                  /* Emit version even if no cards detected. */
+        printk(KERN_INFO "%s", version);
+    return pci_drv_register(&via_rhine_drv_id, NULL);
+}
+
+void cleanup_module(void)
+{
+    struct net_device *next_dev;
+//    int i;
+
+    pci_drv_unregister(&via_rhine_drv_id);
+
+    /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+    while (root_net_dev) {
+        netdev_private *np = (void *)(root_net_dev->priv);
+        unregister_netdev(root_net_dev);
+#ifdef USE_IO_OPS
+        release_region(root_net_dev->base_addr, pci_tbl[np->chip_idx].io_size);
+#else
+        iounmap((char *)(root_net_dev->base_addr));
+#endif
+        next_dev = np->next_module;
+#if (LINUX_VERSION_CODE >= 0x20341)
+    if (np->ring) {
+        if (np->revision >= 0x80)
+            pci_free_consistent(np->pdev,(sizeof(rx_desc) * RX_RING_SIZE)+(sizeof(tx_desc) * TX_RING_SIZE * 8), np->ring, np->ring_dma);
+        else
+            pci_free_consistent(np->pdev,(sizeof(rx_desc) * RX_RING_SIZE)+(sizeof(tx_desc) * TX_RING_SIZE), np->ring, np->ring_dma);
+    }
+#else
+        if (np->priv_addr) {
+            kfree(np->priv_addr);
+//            printk("chenyp:kfree:np->priv_addr=%x\n",np->priv_addr);
+        }
+        if (np->priv_rd) {
+            kfree(np->priv_rd);
+//            printk("chenyp:kfree:np->priv_rd=%x\n",np->priv_rd);
+        }
+        if (np->priv_td) {
+            kfree(np->priv_td);
+//            printk("chenyp:kfree:np->priv_rd=%x\n",np->priv_td);
+        }
+#endif
+        kfree(root_net_dev);
+//        printk("chenyp:kfree:root_net_dev=%x\n",root_net_dev);
+
+        root_net_dev = next_dev;
+    }
+}
+
+#endif  /* ifdef MODULE*/
diff -urN linux-2.4.29/drivers/net/linuxfet.h linux-2.4.29-uc1/drivers/net/linuxfet.h
--- linux-2.4.29/drivers/net/linuxfet.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/linuxfet.h	2005-06-14 02:12:15.000000000 +0100
@@ -0,0 +1,483 @@
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif
+/* Include files, designed to support most kernel versions 2.0.0 and later. */
+#include <linux/config.h>
+
+#if defined(CONFIG_SMP) && ! defined(__SMP__)
+#define __SMP__
+#endif
+
+#if defined(MODULE) && defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS)
+#define MODVERSIONS
+/* Older kernels do not include this automatically. */
+#endif
+
+#include <linux/version.h>
+#if (LINUX_VERSION_CODE < 0x20341) &&  defined(MODVERSIONS)
+#include <linux/modversions.h>
+#endif
+
+#include <linux/module.h>
+
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#if LINUX_VERSION_CODE > 0x02032a
+#include <linux/init.h>
+#endif
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/malloc.h>
+#include <linux/interrupt.h>
+#include <linux/string.h>
+#include <linux/if.h>
+#include <asm/io.h>
+#include <asm/processor.h>      /* Processor type for cache alignment. */
+#include <asm/bitops.h>
+
+#if (LINUX_VERSION_CODE < 0x20155)
+#include <linux/bios32.h>
+/* A minimal version of the 2.2.* PCI support that handles configuration
+   space access.
+   Drivers that actually use pci_dev fields must do explicit compatibility.
+   Note that the struct pci_dev * "pointer" is actually a byte mapped integer!
+*/
+#if (LINUX_VERSION_CODE < 0x20020)
+typedef struct _pci_dev {
+    int not_used;
+} pci_dev;
+#endif
+
+#define pci_find_slot(bus, devfn) (struct pci_dev*)((bus<<8) | devfn | 0xf0000)
+#define bus_number(pci_dev) ((((int)(pci_dev)) >> 8) & 0xff)
+#define devfn_number(pci_dev) (((int)(pci_dev)) & 0xff)
+
+#ifndef CONFIG_PCI
+extern inline int pci_present(void)
+{ 
+    return 0;
+}
+#else
+#define pci_present pcibios_present
+#endif
+
+#define pci_read_config_byte(pdev, where, valp)\
+    pcibios_read_config_byte(bus_number(pdev), devfn_number(pdev), where, valp)
+#define pci_read_config_word(pdev, where, valp)\
+    pcibios_read_config_word(bus_number(pdev), devfn_number(pdev), where, valp)
+#define pci_read_config_dword(pdev, where, valp)\
+    pcibios_read_config_dword(bus_number(pdev), devfn_number(pdev), where, valp)
+#define pci_write_config_byte(pdev, where, val)\
+    pcibios_write_config_byte(bus_number(pdev), devfn_number(pdev), where, val)
+#define pci_write_config_word(pdev, where, val)\
+    pcibios_write_config_word(bus_number(pdev), devfn_number(pdev), where, val)
+#define pci_write_config_dword(pdev, where, val)\
+    pcibios_write_config_dword(bus_number(pdev), devfn_number(pdev), where, val)
+#endif
+
+/* Keep the ring sizes a power of two for compile efficiency.
+   The compiler will convert <unsigned>'%'<2^N> into a bit mask.
+   Making the Tx ring too large decreases the effectiveness of channel
+   bonding and packet priority.
+   There are no ill effects from too-large receive rings. */
+#define TX_RING_SIZE	16
+#define TX_QUEUE_LEN	16      /* Limit ring entries actually used.  */
+#define RX_RING_SIZE	64      /* for flow control, so wee need more RDs */
+#define U_HEADER_LEN	14
+#define U_CRC_LEN	4
+#define PCI_REG_MODE3	0x53
+#define MODE3_MIION	0x04    /* in PCI_REG_MOD3 OF PCI space */
+#define PRIV_ALIGN	15  /* Required alignment mask */
+
+/* Operational parameters that usually are not changed. */
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT	(2*HZ)
+#define PKT_BUF_SZ	1900                 /* Size of each temporary Rx buffer.*/
+
+/* for checksum offload */
+#define IPOK		0x20
+#define TUOK		0x10
+#define IPKT		0x08
+#define TCPKT		0x04
+#define UDPKT		0x02
+#define TAG		0x01
+
+/* DaviCom PHY ID */
+#define CID_DAVICOM         0x0181B800    // OUI = 00-60-6E , 0x0181 B800
+#define CID_DAVICOM_B       0x0181B802    //
+
+/* These are used by the netdrivers to report values from the
+   MII (Media Indpendent Interface) management registers.
+*/
+#ifndef SIOCGMIIPHY
+//warning You are using an old kern_compat.h version.
+#define SIOCGMIIPHY	(SIOCDEVPRIVATE)		/* Get the PHY in use. */
+#define SIOCGMIIREG	(SIOCDEVPRIVATE + 1) 		/* Read a PHY register. */
+#define SIOCSMIIREG	(SIOCDEVPRIVATE + 2) 		/* Write a PHY register. */
+#define SIOCGPARAMS	(SIOCDEVPRIVATE + 3) 		/* Read operational parameters. */
+#define SIOCSPARAMS	(SIOCDEVPRIVATE + 4) 		/* Set operational parameters. */
+#endif
+// for CAM Controller
+#define CAMC_CAMEN 	0x01
+#define CAMC_VCAMSL	0x02
+#define CAMC_SELECT_MCAM 0x00
+#define CAMC_SELECT_VCAM 0x01
+#define CAMC_CAMRD	0x08
+#define CAMC_CAMWR	0x04
+
+/* Condensed bus+endian portability operations. */
+#define virt_to_le32desc(addr)	cpu_to_le32(virt_to_bus(addr))
+#define le32desc_to_virt(addr)	bus_to_virt(le32_to_cpu(addr))
+
+#define USE_IO_OPS
+#undef readb
+#undef readw
+#undef readl
+#undef writeb
+#undef writew
+#undef writel
+#define readb	inb
+#define readw	inw
+#define readl	inl
+#define writeb	outb
+#define writew	outw
+#define writel	outl
+
+// max time out delay time
+#define W_MAX_TIMEOUT	0x0FFFU
+	
+#define RHINE_IOTYPE	(FET_PCI_USES_IO  | FET_PCI_USES_MASTER | FET_PCI_ADDR0)
+#define RHINEII_IOSIZE	256
+
+#if (LINUX_VERSION_CODE < 0x20100)
+#define PCI_CAPABILITY_LIST	0x34	/* Offset of first capability list entry */
+#define PCI_STATUS_CAP_LIST	0x10	/* Support capability List */
+#define PCI_CAP_ID_PM	0x01	/* Power Management */
+#endif
+
+/* SMP and better multiarchitecture support were added.
+   Using an older kernel means we assume a little-endian uniprocessor.
+*/
+#if (LINUX_VERSION_CODE < 0x20123)
+#define hard_smp_processor_id()	smp_processor_id()
+#define test_and_set_bit(val, addr)	set_bit(val, addr)
+#define le16_to_cpu(val)	(val)
+#define cpu_to_le16(val)	(val)
+#define le16_to_cpus(val)
+#define le32_to_cpu(val)	(val)
+#define cpu_to_le32(val)	(val)
+typedef long	spinlock_t;
+#define SPIN_LOCK_UNLOCKED	0
+#define spin_lock(lock)
+#define spin_unlock(lock)
+#define spin_lock_irqsave(lock, flags)	save_flags(flags); cli();
+#define spin_unlock_irqrestore(lock, flags)	restore_flags(flags);
+#endif
+
+#if (LINUX_VERSION_CODE <= 0x20139)
+#define	net_device_stats	enet_statistics
+#else
+#define	NETSTATS_VER2
+#endif
+
+/* There was no support for PCI address space mapping in 2.0, but the
+   Alpha needed it.  See the 2.2 documentation. */
+#if (LINUX_VERSION_CODE < 0x20100) && (!defined(__alpha__))
+#define ioremap(a,b)	(((unsigned long)(a) >= 0x100000) ? vremap(a,b) : (void*)(a))
+#define iounmap(v)	do { if ((unsigned long)(v) >= 0x100000) vfree(v);} while (0)
+#endif
+
+/* The arg count changed, but function name did not.
+   We cover that bad choice by defining a new name.
+*/
+#if (LINUX_VERSION_CODE > 0x020343)
+#define dev_free_skb(skb)	dev_kfree_skb_irq(skb)
+#elif (LINUX_VERSION_CODE < 0x020159)
+#define dev_free_skb(skb)	dev_kfree_skb(skb, FREE_WRITE);
+#else
+#define dev_free_skb(skb)	dev_kfree_skb(skb);
+#endif
+
+/* The old 'struct device' used a too-generic name. */
+#if (LINUX_VERSION_CODE < 0x2030d)
+#define net_device	device
+#endif
+
+/* The 2.2 kernels added the start of capability-based security for operations
+   that formerally could only be done by root.
+*/
+#if (!defined(CAP_NET_ADMIN))
+#define capable(CAP_XXX)	(suser())
+#endif
+
+/* Support for adding info about the purpose of and parameters for kernel
+   modules was added in 2.1. */
+#if (LINUX_VERSION_CODE < 0x20115)
+#define MODULE_AUTHOR(name)	extern int nonesuch
+#define MODULE_DESCRIPTION(string)	extern int nonesuch
+#define MODULE_PARM(varname, typestring)	extern int nonesuch
+#endif
+
+/*
+  These are the structures in the table that drives the PCI probe routines.
+  Note the matching code uses a bitmask: more specific table entries should
+  be placed before "catch-all" entries.
+
+  The table must be zero terminated.
+*/
+typedef enum _chip_capability_flags {
+    FET_CanHaveMII = 1,
+    FET_HasESIPhy = 2,
+    FET_HasDavicomPhy = 4,
+    FET_ReqTxAlign = 0x10,
+    FET_HasWOL = 0x20,
+} chip_capability_flags;
+
+typedef enum _pci_id_flags_bits {
+    /* Set PCI command register bits before calling probe1(). */
+    FET_PCI_USES_IO = 1,
+    FET_PCI_USES_MEM = 2,
+    FET_PCI_USES_MASTER = 4,
+    /* Read and map the single following PCI BAR. */
+    FET_PCI_ADDR0 = 0 << 4,
+    FET_PCI_ADDR1 = 1 << 4,
+    FET_PCI_ADDR2 = 2 << 4,
+    FET_PCI_ADDR3 = 3 << 4,
+    FET_PCI_ADDR_64BITS = 0x100,
+    FET_PCI_NO_ACPI_WAKE = 0x200,
+    FET_PCI_NO_MIN_LATENCY = 0x400,
+} pci_id_flags_bits;
+
+typedef enum _drv_id_flags {
+    FET_PCI_HOTSWAP = 1, /* Leave module loaded for Cardbus-like chips. */
+} drv_id_flags;
+
+typedef enum _drv_pwr_action {
+    FET_DRV_NOOP,			/* No action. */
+    FET_DRV_ATTACH,			/* The driver may expect power ops. */
+    FET_DRV_SUSPEND,		/* Machine suspending, next event RESUME or DETACH. */
+    FET_DRV_RESUME,			/* Resume from previous SUSPEND  */
+    FET_DRV_DETACH,			/* Card will-be/is gone. Valid from SUSPEND! */
+    FET_DRV_PWR_WakeOn,		/* Put device in e.g. Wake-On-LAN mode. */
+    FET_DRV_PWR_DOWN,		/* Go to lowest power mode. */
+    FET_DRV_PWR_UP,			/* Go to normal power mode. */
+} drv_pwr_action;
+
+typedef enum _register_offsets {
+    FET_PAR = 0x00,
+    FET_RCR = 0x06,
+    FET_TCR = 0x07,
+    FET_CR0 = 0x08,
+    FET_CR1 = 0x09,
+    FET_TXQWAK = 0x0A,
+    FET_ISR0 = 0x0C,
+    FET_IMR0 = 0x0E,
+    FET_MAR0 = 0x10,     //Muilticast Hash Table/CAM content access register
+    FET_MAR4 = 0x14,     //Muilticast Hash Table/CAM content access register
+    FET_MCAMD0 = 0x10,
+    FET_MCAMD4 = 0x14,
+    FET_VCAMD0 = 0x16,
+    FET_CURR_RX_DESC_ADDR = 0x18,
+    FET_CURR_TX_DESC_ADDR = 0x1C,
+    FET_GFTEST = 0x54,
+    FET_MIICFG = 0x6C,
+    FET_MIISR = 0x6D,
+    FET_BCR0 = 0x6E,
+    FET_BCR1 = 0x6F,
+    FET_MIICR = 0x70,
+    FET_MIIADR = 0x71,
+    FET_MII_DATA_REG = 0x72,
+    FET_EECSR = 0x74,
+    FET_CFGA = 0x78,
+    FET_CFGB = 0x79,
+    FET_CFGC = 0x7A,
+    FET_CFGD = 0x7B,
+    FET_MPA_tally = 0x7C,
+    FET_CRC_tally = 0x7E,
+    FET_Micr0 = 0x80,
+    FET_STICKHW = 0x83,
+    FET_CAMMSK = 0x88,
+    FET_CAMC = 0x92,
+    FET_CAMADD =0x93,
+    FET_PHYANAR = 0x95, /* for VT3106 */
+    FET_FlowCR0 = 0x98, /* for VT3106 */
+    FET_FlowCR1 = 0x99, /* for VT3106 */
+    FET_TxPauseTimer = 0x9A,
+    FET_WOLCR_CLR = 0xA4,
+    FET_WOLCG_CLR = 0xA7,
+    FET_PWRCSR_CLR = 0xAC
+} register_offsets;
+
+/* Bits in the interrupt status/mask registers. */
+typedef enum _intr_status_bits {
+    FET_ISR_PRX = 0x0001,
+    FET_ISR_PTX = 0x0002,
+    FET_ISR_RXE = 0x0004,
+    FET_ISR_TXE = 0x0008,
+    FET_ISR_TU = 0x0010,
+    FET_ISR_RU = 0x0020,
+    FET_ISR_BE = 0x0040,
+    FET_ISR_CNT = 0x0080,
+    FET_ISR_ERI = 0x0100,
+    FET_ISR_UDFI = 0x0200,
+    FET_ISR_OVFI = 0x0400,
+    FET_ISR_PKTRACE = 0x0800,
+    FET_ISR_NORBF = 0x1000,
+    FET_ISR_ABTI = 0x2000,
+    FET_ISR_SRCI = 0x4000,
+    FET_ISR_GENI = 0x8000,
+    FET_ISR_NormalSummary = 0x0003,
+    FET_ISR_AbnormalSummary = 0xC260,
+} intr_status_bits;
+
+typedef enum _FET_CFGD_bits {
+    FET_CRADOM = 0x08,
+    FET_CAP = 0x04,
+    FET_MBA = 0X02,
+    FET_BAKOPT = 0x01
+} FET_CFGD_bits;
+
+typedef enum _FET_TCR_bits {
+    FET_TCR_LB0 = 0x02,
+    FET_TCR_LB1 = 0X04,
+    FET_TCR_OFSET = 0x08,
+    FET_TCR_RTFT0 = 0x20,
+    FET_TCR_RTFT1 = 0x40,
+    FET_TCR_RTSF = 0x80
+} _FET_TCR_bits;
+
+/* Bits in *_desc.status */
+typedef enum _rx_status_bits {
+    FET_RxOK = 0x8000,
+    FET_RxWholePkt = 0x0300,
+    FET_RxErr = 0x008F
+} rx_status_bits;
+
+typedef enum _desc_status_bits {
+    FET_DescOwn = 0x80000000,
+    FET_DescEndPacket = 0x4000,
+    FET_DescIntr = 0x1000,
+} desc_status_bits;
+
+/* Bits in CR0 and CR1. */
+typedef enum _chip_cmd_bits {
+    FET_CmdInit = 0x0001,
+    FET_CmdStart = 0x0002,
+    FET_CmdStop = 0x0004,
+    FET_CmdRxOn = 0x0008,
+    FET_CmdTxOn = 0x0010,
+    FET_CmdTxDemand1 = 0x20,
+    FET_CmdRxDemand1 = 0x40,
+    FET_CmdEarlyRx = 0x0100,
+    FET_CmdEarlyTx = 0x0200,
+    FET_CmdFDuplex = 0x0400,
+    FET_CmdNoFDuplex = 0xFBFF,
+    FET_CmdNoTxPoll = 0x0800,
+    FET_CmdReset = 0x8000,
+} chip_cmd_bits;
+
+typedef struct _match_info {
+    int	pci, pci_mask, subsystem, subsystem_mask;
+    int	revision, revision_mask; 				/* Only 8 bits. */
+} match_info;
+
+typedef struct _pci_id_info {
+    const char	*name;
+    match_info	id;
+    pci_id_flags_bits	pci_flags;
+    int	io_size;				/* Needed for I/O region check or ioremap(). */
+    int	drv_flags;				/* Driver use, intended as capability flags. */
+} pci_id_info;
+
+typedef struct _drv_id_info {
+    const char	*name;			/* Single-word driver name. */
+    int	flags;
+    int	pci_class;				/* Typically PCI_CLASS_NETWORK_ETHERNET<<8. */
+    pci_id_info	*pci_dev_tbl;
+    void *(*probe1)(struct pci_dev *pdev, void *dev_ptr, unsigned long ioaddr, int irq, int table_idx, int fnd_cnt, u32 revision);
+    /* Optional, called for suspend, resume and detach. */
+    int (*pwr_event)(void *dev, int event);
+} drv_id_info;
+
+
+/* The Rx and Tx buffer descriptors. */
+typedef struct _rx_desc {
+    s32	rx_status;
+    u32	desc_length;
+    u32	addr;
+    u32	next_desc;
+} rx_desc;
+
+typedef struct _tx_desc {
+    s32	tx_status;
+    u32	desc_length;
+    u32	addr;
+    u32	next_desc;
+} tx_desc;
+
+/* for VT3106 */
+typedef struct _IEEE_8021Q_header {
+    u16 tag_protocol;
+    u16 tag_control;
+} IEEE_8021Q_header;
+
+
+
+typedef struct _netdev_private {
+    rx_desc* rx_ring;
+    tx_desc* tx_ring[8];
+
+#if (LINUX_VERSION_CODE >= 0x20341)
+    struct pci_dev *pdev;
+    void *ring;
+    dma_addr_t ring_dma;
+    void *tx_bufs[8];
+    dma_addr_t tx_bufs_dma[8];
+#if (LINUX_VERSION_CODE >= 0x020400)
+    dma_addr_t tx_skbuff_dma[8][TX_RING_SIZE];
+    dma_addr_t rx_skbuff_dma[RX_RING_SIZE];
+#endif //#if (LINUX_VERSION_CODE >= 0x020400)
+#else //#if (LINUX_VERSION_CODE >= 0x20341)
+    void	*priv_addr;                    /* Unaligned address for kfree */
+    void        *priv_rd;               /* Unaligned address for rx descriptors */
+    void        *priv_td;               /* Unaligned address for tx descriptors */    
+#endif ////#if (LINUX_VERSION_CODE >= 0x20341)
+    /* The addresses of receive-in-place skbuffs. */
+    struct	sk_buff* rx_skbuff[RX_RING_SIZE];
+    /* The saved address of a sent-in-place packet/buffer, for later free(). */
+    struct	sk_buff* tx_skbuff[8][TX_RING_SIZE];
+    unsigned char	*tx_buf[8][TX_RING_SIZE];    /* Tx bounce buffers */
+    struct	net_device *next_module;     /* Link for devices of this type. */
+    struct	net_device_stats stats;
+    struct	timer_list timer;    /* Media monitoring timer. */
+    /* Frequently used values: keep some adjacent for cache effect. */
+    int	chip_idx, card_idx, drv_flags;
+    struct	pci_dev *pci_dev;
+    rx_desc	*rx_head_desc;
+    unsigned int	cur_rx, dirty_rx;      /* Producer/consumer ring indices */
+    unsigned int	cur_tx[8], dirty_tx[8];
+    unsigned int	rx_buf_sz;             /* Based on MTU+slack. */
+    u16	chip_cmd;                       /* Current setting for CR0 and CR1 */
+    unsigned int	tx_full[8];             /* The Tx queue is full. */
+    /* These values are keep track of the transceiver/media in use. */
+    unsigned int	full_duplex;         /* Full-duplex operation requested. */
+    unsigned int	auto_negotiation;    /* 1:auto mode, 0:force mode */
+    u8	tx_thresh;
+    u8	rx_thresh;
+    u8  DMA_length;
+    /* MII transceiver section. */
+    int	mii_cnt;                        /* MII device addresses. */
+    u16	advertising;                    /* NWay media advertisement */
+    unsigned char	phy_addr;              /* MII device addresses. */
+    u8	revision;
+    /* Descriptor rings first for alignment. */
+} netdev_private;
+
diff -urN linux-2.4.29/drivers/net/Makefile linux-2.4.29-uc1/drivers/net/Makefile
--- linux-2.4.29/drivers/net/Makefile	2005-01-19 14:09:56.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/Makefile	2005-06-14 02:12:12.000000000 +0100
@@ -35,6 +35,10 @@
   obj-y += bonding/bonding.o
 endif
 
+ifeq ($(CONFIG_KS8695),y)
+  obj-y += ks8695/ks8695e.o
+endif
+
 ifeq ($(CONFIG_ISDN_PPP),y)
   obj-$(CONFIG_ISDN) += slhc.o
 endif
@@ -54,6 +58,7 @@
 subdir-$(CONFIG_E100) += e100
 subdir-$(CONFIG_E1000) += e1000
 subdir-$(CONFIG_BONDING) += bonding
+subdir-$(CONFIG_KS8695) += ks8695
 
 #
 # link order important here
@@ -96,6 +101,10 @@
 obj-$(CONFIG_TC35815) += tc35815.o
 obj-$(CONFIG_TIGON3) += tg3.o
 
+mod-subdirs     +=	xilinx_enet
+subdir-$(CONFIG_XILINX_ENET) += xilinx_enet
+obj-$(CONFIG_XILINX_ENET) += xilinx_enet/xilinx_enet.o
+
 ifeq ($(CONFIG_E100),y)
   obj-y += e100/e100.o
 endif
@@ -155,10 +164,26 @@
 obj-$(CONFIG_LNE390) += lne390.o 8390.o
 obj-$(CONFIG_NE3210) += ne3210.o 8390.o
 obj-$(CONFIG_NET_SB1250_MAC) += sb1250-mac.o
+
+#
+# uClinux network drivers
+#
+obj-$(CONFIG_VIA_RHINE_FET) += linuxfet.o
+obj-$(CONFIG_ETH_S3C2500) += s3c2500.o
+obj-$(CONFIG_ETH_S3C4510) += s3c4510.o
+obj-$(CONFIG_ETH_S3C4530) += s3c4530.o
+obj-$(CONFIG_SMC91111) += smc91111.o
+obj-$(CONFIG_FEC) += fec.o
+obj-$(CONFIG_ETHER_NETARM) += netarmeth.o
+obj-$(CONFIG_ETHER_NS7520) += ns7520_eth.o
+obj-$(CONFIG_UCCS8900) += uCcs8900.o
+obj-$(CONFIG_SKYEYENE2k) += skyeyene2k.o
+
 obj-$(CONFIG_B44) += b44.o
 obj-$(CONFIG_FORCEDETH) += forcedeth.o
 
 obj-$(CONFIG_PPP) += ppp_generic.o slhc.o
+obj-$(CONFIG_PPP) += ppp_generic.o slhc.o ppp_mppe.o
 obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
 obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
 obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
@@ -172,6 +197,7 @@
 
 obj-$(CONFIG_STRIP) += strip.o
 obj-$(CONFIG_DUMMY) += dummy.o
+obj-$(CONFIG_IMQ) += imq.o
 obj-$(CONFIG_DE600) += de600.o
 obj-$(CONFIG_DE620) += de620.o
 obj-$(CONFIG_AT1500) += lance.o
@@ -192,6 +218,7 @@
 obj-$(CONFIG_3C515) += 3c515.o
 obj-$(CONFIG_EEXPRESS) += eexpress.o
 obj-$(CONFIG_EEXPRESS_PRO) += eepro.o
+obj-$(CONFIG_RTL8139) += rtl8139.o pci-scan.o
 obj-$(CONFIG_8139CP) += 8139cp.o mii.o
 obj-$(CONFIG_8139TOO) += 8139too.o mii.o
 obj-$(CONFIG_WAVELAN) += wavelan.o
@@ -234,6 +261,7 @@
 obj-$(CONFIG_ARIADNE) += ariadne.o
 obj-$(CONFIG_CS89x0) += cs89x0.o
 obj-$(CONFIG_ARM_CIRRUS) += cirrus.o
+obj-$(CONFIG_EP93XX_ETHERNET) += ep93xx_eth.o
 obj-$(CONFIG_MACSONIC) += macsonic.o
 obj-$(CONFIG_MACMACE) += macmace.o
 obj-$(CONFIG_MAC89x0) += mac89x0.o
@@ -242,10 +270,14 @@
 obj-$(CONFIG_DL2K) += dl2k.o
 obj-$(CONFIG_R8169) += r8169.o
 obj-$(CONFIG_AMD8111_ETH) += amd8111e.o mii.o
+obj-$(CONFIG_C5471_NET) += eth_c5471.o eth_c5471hw.o
+obj-$(CONFIG_ISL3893_ETHERNET) += isl3893eth.o
+obj-$(CONFIG_ISIL_MVCDRIVER) += intersil/islmvc.o
 
 # non-drivers/net drivers who want mii lib
 obj-$(CONFIG_PCMCIA_SMC91C92) += mii.o
 obj-$(CONFIG_USB_USBNET) += mii.o
+obj-$(CONFIG_AT91_ETHER) += mii.o
 
 obj-$(CONFIG_IBMVETH) += ibmveth.o
 
@@ -255,6 +287,12 @@
 obj-y		+= ../acorn/net/acorn-net.o
 endif
 
+subdir-$(CONFIG_CNXT_EMAC_82)	+= cnxt_emac
+obj-$(CONFIG_CNXT_EMAC_82)	+= cnxt_emac/emac_drv.o
+ifeq ($(CONFIG_CNXT_EMAC_82),m)
+	mod-subdirs	+= cnxt_emac
+endif
+
 #
 # HIPPI adapters
 #
diff -urN linux-2.4.29/drivers/net/md32_common.h linux-2.4.29-uc1/drivers/net/md32_common.h
--- linux-2.4.29/drivers/net/md32_common.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/md32_common.h	2005-06-14 02:12:15.000000000 +0100
@@ -0,0 +1,607 @@
+/* crypto/md32_common.h */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+ * This is a generic 32 bit "collector" for message digest algorithms.
+ * Whenever needed it collects input character stream into chunks of
+ * 32 bit values and invokes a block function that performs actual hash
+ * calculations.
+ *
+ * Porting guide.
+ *
+ * Obligatory macros:
+ *
+ * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
+ *	this macro defines byte order of input stream.
+ * HASH_CBLOCK
+ *	size of a unit chunk HASH_BLOCK operates on.
+ * HASH_LONG
+ *	has to be at lest 32 bit wide, if it's wider, then
+ *	HASH_LONG_LOG2 *has to* be defined along
+ * HASH_CTX
+ *	context structure that at least contains following
+ *	members:
+ *		typedef struct {
+ *			...
+ *			HASH_LONG	Nl,Nh;
+ *			HASH_LONG	data[HASH_LBLOCK];
+ *			int		num;
+ *			...
+ *			} HASH_CTX;
+ * HASH_UPDATE
+ *	name of "Update" function, implemented here.
+ * HASH_TRANSFORM
+ *	name of "Transform" function, implemented here.
+ * HASH_FINAL
+ *	name of "Final" function, implemented here.
+ * HASH_BLOCK_HOST_ORDER
+ *	name of "block" function treating *aligned* input message
+ *	in host byte order, implemented externally.
+ * HASH_BLOCK_DATA_ORDER
+ *	name of "block" function treating *unaligned* input message
+ *	in original (data) byte order, implemented externally (it
+ *	actually is optional if data and host are of the same
+ *	"endianess").
+ * HASH_MAKE_STRING
+ *	macro convering context variables to an ASCII hash string.
+ *
+ * Optional macros:
+ *
+ * B_ENDIAN or L_ENDIAN
+ *	defines host byte-order.
+ * HASH_LONG_LOG2
+ *	defaults to 2 if not states otherwise.
+ * HASH_LBLOCK
+ *	assumed to be HASH_CBLOCK/4 if not stated otherwise.
+ * HASH_BLOCK_DATA_ORDER_ALIGNED
+ *	alternative "block" function capable of treating
+ *	aligned input message in original (data) order,
+ *	implemented externally.
+ *
+ * MD5 example:
+ *
+ *	#define DATA_ORDER_IS_LITTLE_ENDIAN
+ *
+ *	#define HASH_LONG		MD5_LONG
+ *	#define HASH_LONG_LOG2		MD5_LONG_LOG2
+ *	#define HASH_CTX		MD5_CTX
+ *	#define HASH_CBLOCK		MD5_CBLOCK
+ *	#define HASH_LBLOCK		MD5_LBLOCK
+ *	#define HASH_UPDATE		MD5_Update
+ *	#define HASH_TRANSFORM		MD5_Transform
+ *	#define HASH_FINAL		MD5_Final
+ *	#define HASH_BLOCK_HOST_ORDER	md5_block_host_order
+ *	#define HASH_BLOCK_DATA_ORDER	md5_block_data_order
+ *
+ *					<appro@fy.chalmers.se>
+ */
+
+#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+#error "DATA_ORDER must be defined!"
+#endif
+
+#ifndef HASH_CBLOCK
+#error "HASH_CBLOCK must be defined!"
+#endif
+#ifndef HASH_LONG
+#error "HASH_LONG must be defined!"
+#endif
+#ifndef HASH_CTX
+#error "HASH_CTX must be defined!"
+#endif
+
+#ifndef HASH_UPDATE
+#error "HASH_UPDATE must be defined!"
+#endif
+#ifndef HASH_TRANSFORM
+#error "HASH_TRANSFORM must be defined!"
+#endif
+#ifndef HASH_FINAL
+#error "HASH_FINAL must be defined!"
+#endif
+
+#ifndef HASH_BLOCK_HOST_ORDER
+#error "HASH_BLOCK_HOST_ORDER must be defined!"
+#endif
+
+#if 0
+/*
+ * Moved below as it's required only if HASH_BLOCK_DATA_ORDER_ALIGNED
+ * isn't defined.
+ */
+#ifndef HASH_BLOCK_DATA_ORDER
+#error "HASH_BLOCK_DATA_ORDER must be defined!"
+#endif
+#endif
+
+#ifndef HASH_LBLOCK
+#define HASH_LBLOCK	(HASH_CBLOCK/4)
+#endif
+
+#ifndef HASH_LONG_LOG2
+#define HASH_LONG_LOG2	2
+#endif
+
+/*
+ * Engage compiler specific rotate intrinsic function if available.
+ */
+#undef ROTATE
+#ifndef PEDANTIC
+# if defined(_MSC_VER)
+#  define ROTATE(a,n)	_lrotl(a,n)
+# elif defined(__MWERKS__)
+#  if defined(__POWERPC__)
+#   define ROTATE(a,n)	__rlwinm(a,n,0,31)
+#  elif defined(__MC68K__)
+    /* Motorola specific tweak. <appro@fy.chalmers.se> */
+#   define ROTATE(a,n)	( n<24 ? __rol(a,n) : __ror(a,32-n) )
+#  else
+#   define ROTATE(a,n)	__rol(a,n)
+#  endif
+# elif defined(__GNUC__) && __GNUC__>=2 && !defined(NO_ASM) && !defined(NO_INLINE_ASM)
+  /*
+   * Some GNU C inline assembler templates. Note that these are
+   * rotates by *constant* number of bits! But that's exactly
+   * what we need here...
+   *
+   * 					<appro@fy.chalmers.se>
+   */
+#  if defined(__i386)
+#   define ROTATE(a,n)	({ register unsigned int ret;	\
+				asm (			\
+				"roll %1,%0"		\
+				: "=r"(ret)		\
+				: "I"(n), "0"(a)	\
+				: "cc");		\
+			   ret;				\
+			})
+#  elif defined(__powerpc) || defined(__ppc)
+#   define ROTATE(a,n)	({ register unsigned int ret;	\
+				asm (			\
+				"rlwinm %0,%1,%2,0,31"	\
+				: "=r"(ret)		\
+				: "r"(a), "I"(n));	\
+			   ret;				\
+			})
+#  endif
+# endif
+
+/*
+ * Engage compiler specific "fetch in reverse byte order"
+ * intrinsic function if available.
+ */
+# if defined(__GNUC__) && __GNUC__>=2 && !defined(NO_ASM) && !defined(NO_INLINE_ASM)
+  /* some GNU C inline assembler templates by <appro@fy.chalmers.se> */
+#  if defined(__i386) && !defined(I386_ONLY)
+#   define BE_FETCH32(a)	({ register unsigned int l=(a);\
+				asm (			\
+				"bswapl %0"		\
+				: "=r"(l) : "0"(l));	\
+			  l;				\
+			})
+#  elif defined(__powerpc)
+#   define LE_FETCH32(a)	({ register unsigned int l;	\
+				asm (			\
+				"lwbrx %0,0,%1"		\
+				: "=r"(l)		\
+				: "r"(a));		\
+			   l;				\
+			})
+
+#  elif defined(__sparc) && defined(ULTRASPARC)
+#  define LE_FETCH32(a)	({ register unsigned int l;		\
+				asm (				\
+				"lda [%1]#ASI_PRIMARY_LITTLE,%0"\
+				: "=r"(l)			\
+				: "r"(a));			\
+			   l;					\
+			})
+#  endif
+# endif
+#endif /* PEDANTIC */
+
+#if HASH_LONG_LOG2==2	/* Engage only if sizeof(HASH_LONG)== 4 */
+/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */
+#ifdef ROTATE
+/* 5 instructions with rotate instruction, else 9 */
+#define REVERSE_FETCH32(a,l)	(					\
+		l=*(const HASH_LONG *)(a),				\
+		((ROTATE(l,8)&0x00FF00FF)|(ROTATE((l&0x00FF00FF),24)))	\
+				)
+#else
+/* 6 instructions with rotate instruction, else 8 */
+#define REVERSE_FETCH32(a,l)	(				\
+		l=*(const HASH_LONG *)(a),			\
+		l=(((l>>8)&0x00FF00FF)|((l&0x00FF00FF)<<8)),	\
+		ROTATE(l,16)					\
+				)
+/*
+ * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|...
+ * It's rewritten as above for two reasons:
+ *	- RISCs aren't good at long constants and have to explicitely
+ *	  compose 'em with several (well, usually 2) instructions in a
+ *	  register before performing the actual operation and (as you
+ *	  already realized:-) having same constant should inspire the
+ *	  compiler to permanently allocate the only register for it;
+ *	- most modern CPUs have two ALUs, but usually only one has
+ *	  circuitry for shifts:-( this minor tweak inspires compiler
+ *	  to schedule shift instructions in a better way...
+ *
+ *				<appro@fy.chalmers.se>
+ */
+#endif
+#endif
+
+#ifndef ROTATE
+#define ROTATE(a,n)     (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
+#endif
+
+/*
+ * Make some obvious choices. E.g., HASH_BLOCK_DATA_ORDER_ALIGNED
+ * and HASH_BLOCK_HOST_ORDER ought to be the same if input data
+ * and host are of the same "endianess". It's possible to mask
+ * this with blank #define HASH_BLOCK_DATA_ORDER though...
+ *
+ *				<appro@fy.chalmers.se>
+ */
+#if defined(B_ENDIAN)
+#  if defined(DATA_ORDER_IS_BIG_ENDIAN)
+#    if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2
+#      define HASH_BLOCK_DATA_ORDER_ALIGNED	HASH_BLOCK_HOST_ORDER
+#    endif
+#  elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+#    ifndef HOST_FETCH32
+#      ifdef LE_FETCH32
+#        define HOST_FETCH32(p,l)	LE_FETCH32(p)
+#      elif defined(REVERSE_FETCH32)
+#        define HOST_FETCH32(p,l)	REVERSE_FETCH32(p,l)
+#      endif
+#    endif
+#  endif
+#elif defined(L_ENDIAN)
+#  if defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+#    if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2
+#      define HASH_BLOCK_DATA_ORDER_ALIGNED	HASH_BLOCK_HOST_ORDER
+#    endif
+#  elif defined(DATA_ORDER_IS_BIG_ENDIAN)
+#    ifndef HOST_FETCH32
+#      ifdef BE_FETCH32
+#        define HOST_FETCH32(p,l)	BE_FETCH32(p)
+#      elif defined(REVERSE_FETCH32)
+#        define HOST_FETCH32(p,l)	REVERSE_FETCH32(p,l)
+#      endif
+#    endif
+#  endif
+#endif
+
+#if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
+#ifndef HASH_BLOCK_DATA_ORDER
+#error "HASH_BLOCK_DATA_ORDER must be defined!"
+#endif
+#endif
+
+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
+
+#define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))<<24),		\
+			 l|=(((unsigned long)(*((c)++)))<<16),		\
+			 l|=(((unsigned long)(*((c)++)))<< 8),		\
+			 l|=(((unsigned long)(*((c)++)))    ),		\
+			 l)
+#define HOST_p_c2l(c,l,n)	{					\
+			switch (n) {					\
+			case 0: l =((unsigned long)(*((c)++)))<<24;	\
+			case 1: l|=((unsigned long)(*((c)++)))<<16;	\
+			case 2: l|=((unsigned long)(*((c)++)))<< 8;	\
+			case 3: l|=((unsigned long)(*((c)++)));		\
+				} }
+#define HOST_p_c2l_p(c,l,sc,len) {					\
+			switch (sc) {					\
+			case 0: l =((unsigned long)(*((c)++)))<<24;	\
+				if (--len == 0) break;			\
+			case 1: l|=((unsigned long)(*((c)++)))<<16;	\
+				if (--len == 0) break;			\
+			case 2: l|=((unsigned long)(*((c)++)))<< 8;	\
+				} }
+/* NOTE the pointer is not incremented at the end of this */
+#define HOST_c2l_p(c,l,n)	{					\
+			l=0; (c)+=n;					\
+			switch (n) {					\
+			case 3: l =((unsigned long)(*(--(c))))<< 8;	\
+			case 2: l|=((unsigned long)(*(--(c))))<<16;	\
+			case 1: l|=((unsigned long)(*(--(c))))<<24;	\
+				} }
+#define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)>>24)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)    )&0xff),	\
+			 l)
+
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+
+#define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))    ),		\
+			 l|=(((unsigned long)(*((c)++)))<< 8),		\
+			 l|=(((unsigned long)(*((c)++)))<<16),		\
+			 l|=(((unsigned long)(*((c)++)))<<24),		\
+			 l)
+#define HOST_p_c2l(c,l,n)	{					\
+			switch (n) {					\
+			case 0: l =((unsigned long)(*((c)++)));		\
+			case 1: l|=((unsigned long)(*((c)++)))<< 8;	\
+			case 2: l|=((unsigned long)(*((c)++)))<<16;	\
+			case 3: l|=((unsigned long)(*((c)++)))<<24;	\
+				} }
+#define HOST_p_c2l_p(c,l,sc,len) {					\
+			switch (sc) {					\
+			case 0: l =((unsigned long)(*((c)++)));		\
+				if (--len == 0) break;			\
+			case 1: l|=((unsigned long)(*((c)++)))<< 8;	\
+				if (--len == 0) break;			\
+			case 2: l|=((unsigned long)(*((c)++)))<<16;	\
+				} }
+/* NOTE the pointer is not incremented at the end of this */
+#define HOST_c2l_p(c,l,n)	{					\
+			l=0; (c)+=n;					\
+			switch (n) {					\
+			case 3: l =((unsigned long)(*(--(c))))<<16;	\
+			case 2: l|=((unsigned long)(*(--(c))))<< 8;	\
+			case 1: l|=((unsigned long)(*(--(c))));		\
+				} }
+#define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)    )&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>>24)&0xff),	\
+			 l)
+
+#endif
+
+/*
+ * Time for some action:-)
+ */
+
+void HASH_UPDATE (HASH_CTX *c, const void *data_, unsigned long len)
+	{
+	const unsigned char *data=data_;
+	register HASH_LONG * p;
+	register unsigned long l;
+	int sw,sc,ew,ec;
+
+	if (len==0) return;
+
+	l=(c->Nl+(len<<3))&0xffffffffL;
+	/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
+	 * Wei Dai <weidai@eskimo.com> for pointing it out. */
+	if (l < c->Nl) /* overflow */
+		c->Nh++;
+	c->Nh+=(len>>29);
+	c->Nl=l;
+
+	if (c->num != 0)
+		{
+		p=c->data;
+		sw=c->num>>2;
+		sc=c->num&0x03;
+
+		if ((c->num+len) >= HASH_CBLOCK)
+			{
+			l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l;
+			for (; sw<HASH_LBLOCK; sw++)
+				{
+				HOST_c2l(data,l); p[sw]=l;
+				}
+			HASH_BLOCK_HOST_ORDER (c,p,1);
+			len-=(HASH_CBLOCK-c->num);
+			c->num=0;
+			/* drop through and do the rest */
+			}
+		else
+			{
+			c->num+=len;
+			if ((sc+len) < 4) /* ugly, add char's to a word */
+				{
+				l=p[sw]; HOST_p_c2l_p(data,l,sc,len); p[sw]=l;
+				}
+			else
+				{
+				ew=(c->num>>2);
+				ec=(c->num&0x03);
+				l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l;
+				for (; sw < ew; sw++)
+					{
+					HOST_c2l(data,l); p[sw]=l;
+					}
+				if (ec)
+					{
+					HOST_c2l_p(data,l,ec); p[sw]=l;
+					}
+				}
+			return;
+			}
+		}
+
+	sw=len/HASH_CBLOCK;
+	if (sw > 0)
+		{
+#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
+		/*
+		 * Note that HASH_BLOCK_DATA_ORDER_ALIGNED gets defined
+		 * only if sizeof(HASH_LONG)==4.
+		 */
+		if ((((unsigned long)data)%4) == 0)
+			{
+			/* data is properly aligned so that we can cast it: */
+			HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,sw);
+			sw*=HASH_CBLOCK;
+			data+=sw;
+			len-=sw;
+			}
+		else
+#if !defined(HASH_BLOCK_DATA_ORDER)
+			while (sw--)
+				{
+				memcpy (p=c->data,data,HASH_CBLOCK);
+				HASH_BLOCK_DATA_ORDER_ALIGNED(c,p,1);
+				data+=HASH_CBLOCK;
+				len-=HASH_CBLOCK;
+				}
+#endif
+#endif
+#if defined(HASH_BLOCK_DATA_ORDER)
+			{
+			HASH_BLOCK_DATA_ORDER(c,data,sw);
+			sw*=HASH_CBLOCK;
+			data+=sw;
+			len-=sw;
+			}
+#endif
+		}
+
+	if (len!=0)
+		{
+		p = c->data;
+		c->num = len;
+		ew=len>>2;	/* words to copy */
+		ec=len&0x03;
+		for (; ew; ew--,p++)
+			{
+			HOST_c2l(data,l); *p=l;
+			}
+		HOST_c2l_p(data,l,ec);
+		*p=l;
+		}
+	}
+
+
+void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data)
+	{
+#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
+	if ((((unsigned long)data)%4) == 0)
+		/* data is properly aligned so that we can cast it: */
+		HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,1);
+	else
+#if !defined(HASH_BLOCK_DATA_ORDER)
+		{
+		memcpy (c->data,data,HASH_CBLOCK);
+		HASH_BLOCK_DATA_ORDER_ALIGNED (c,c->data,1);
+		}
+#endif
+#endif
+#if defined(HASH_BLOCK_DATA_ORDER)
+	HASH_BLOCK_DATA_ORDER (c,data,1);
+#endif
+	}
+
+
+void HASH_FINAL (unsigned char *md, HASH_CTX *c)
+	{
+	register HASH_LONG *p;
+	register unsigned long l;
+	register int i,j;
+	static const unsigned char end[4]={0x80,0x00,0x00,0x00};
+	const unsigned char *cp=end;
+
+	/* c->num should definitly have room for at least one more byte. */
+	p=c->data;
+	i=c->num>>2;
+	j=c->num&0x03;
+
+#if 0
+	/* purify often complains about the following line as an
+	 * Uninitialized Memory Read.  While this can be true, the
+	 * following p_c2l macro will reset l when that case is true.
+	 * This is because j&0x03 contains the number of 'valid' bytes
+	 * already in p[i].  If and only if j&0x03 == 0, the UMR will
+	 * occur but this is also the only time p_c2l will do
+	 * l= *(cp++) instead of l|= *(cp++)
+	 * Many thanks to Alex Tang <altitude@cic.net> for pickup this
+	 * 'potential bug' */
+#ifdef PURIFY
+	if (j==0) p[i]=0; /* Yeah, but that's not the way to fix it:-) */
+#endif
+	l=p[i];
+#else
+	l = (j==0) ? 0 : p[i];
+#endif
+	HOST_p_c2l(cp,l,j); p[i++]=l; /* i is the next 'undefined word' */
+
+	if (i>(HASH_LBLOCK-2)) /* save room for Nl and Nh */
+		{
+		if (i<HASH_LBLOCK) p[i]=0;
+		HASH_BLOCK_HOST_ORDER (c,p,1);
+		i=0;
+		}
+	for (; i<(HASH_LBLOCK-2); i++)
+		p[i]=0;
+
+#if   defined(DATA_ORDER_IS_BIG_ENDIAN)
+	p[HASH_LBLOCK-2]=c->Nh;
+	p[HASH_LBLOCK-1]=c->Nl;
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+	p[HASH_LBLOCK-2]=c->Nl;
+	p[HASH_LBLOCK-1]=c->Nh;
+#endif
+	HASH_BLOCK_HOST_ORDER (c,p,1);
+
+#ifndef HASH_MAKE_STRING
+#error "HASH_MAKE_STRING must be defined!"
+#else
+	HASH_MAKE_STRING(c,md);
+#endif
+
+	c->num=0;
+	/* clear stuff, HASH_BLOCK may be leaving some stuff on the stack
+	 * but I'm not worried :-)
+	memset((void *)c,0,sizeof(HASH_CTX));
+	 */
+	}
diff -urN linux-2.4.29/drivers/net/mppe.h linux-2.4.29-uc1/drivers/net/mppe.h
--- linux-2.4.29/drivers/net/mppe.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/mppe.h	2005-06-14 02:12:15.000000000 +0100
@@ -0,0 +1,46 @@
+#ifndef MPPE_H
+#define MPPE_H
+
+typedef struct mppe_state {
+    int    us_unit;	/* Interface unit number */
+    u_char us_id;		/* Current id */
+    u_char us_allowed;
+    int    us_type;
+    char   *us_number;    /* Telefone Number */
+} mppe_state;
+
+
+extern struct protent mppe_protent;
+
+#define MPPE_CONFOPTION 18
+#define MPPC		0x01
+#define MPPE_40BIT	0x20
+#define MPPE_128BIT	0x40
+
+#define PPP_MPPE	0x00FD
+#define PPP_MPPC	PPP_MPPE
+
+#define MPPE_BIT_A	0x80
+#define MPPE_BIT_B	0x40
+#define MPPE_BIT_C	0x20
+#define MPPE_BIT_D	0x10
+#define MPPE_BIT_FLUSHED MPPE_BIT_A
+#define MPPE_BIT_ENCRYPTED MPPE_BIT_D
+#define MPPE_CCOUNT	0x0FFF
+
+#define MPPC_BIT_RESET	MPPE_BIT_A
+#define MPPC_BIT_FLUSH	MPPE_BIT_B
+#define MPPC_BIT_COMP	MPPC_BIT_C
+
+#define MPPE_40_SALT0	0xD1
+#define MPPE_40_SALT1	0x26
+#define MPPE_40_SALT2	0x9E
+
+#define MPPE_MINLEN 4
+
+#define MPPE_REQ    1
+#define MPPE_RESP   2
+#define MPPE_ACK    3
+
+#endif
+/*==FILEVERSION 970728==*/
diff -urN linux-2.4.29/drivers/net/ne.c linux-2.4.29-uc1/drivers/net/ne.c
--- linux-2.4.29/drivers/net/ne.c	2005-01-19 14:09:56.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/ne.c	2005-06-14 02:12:15.000000000 +0100
@@ -29,6 +29,8 @@
     last in cleanup_modue()
     Richard Guenther    : Added support for ISAPnP cards
     Paul Gortmaker	: Discontinued PCI support - use ne2k-pci.c instead.
+    Greg Ungerer        : added some coldfire addressing code.
+    Yoshinori Sato      : added H8/300H support.
 
 */
 
@@ -54,6 +56,22 @@
 #include <linux/etherdevice.h>
 #include "8390.h"
 
+#ifdef CONFIG_COLDFIRE
+#define COLDFIRE_NE2000_FUNCS
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfne.h>
+unsigned char   ne_defethaddr[] = { 0x00, 0xd0, 0xcf, 0x00, 0x00, 0x01 };
+#endif /* CONFIG_COLDFIRE */
+#if defined(CONFIG_M5307) && defined(CONFIG_NETtel)
+static unsigned int ne_portlist[] = { NE2000_ADDR0, NE2000_ADDR1, 0 };
+static unsigned int ne_irqlist[] =  { NE2000_IRQ_VECTOR0,NE2000_IRQ_VECTOR1,0 };
+#endif
+
+#if defined(CONFIG_CPU_H8300H)
+#include <asm/h8300_ne.h>
+#endif
+
 /* Some defines that people can play with if so inclined. */
 
 /* Do we support clones that don't adhere to 14,15 of the SAprom ? */
@@ -164,7 +182,31 @@
 
 int __init ne_probe(struct net_device *dev)
 {
-	unsigned int base_addr = dev->base_addr;
+	int base_addr = (dev && dev->base_addr != 0xffe0) ? dev->base_addr : 0;
+
+#if defined (CONFIG_NETtel) && defined (CONFIG_M5307)
+    static int index = 0;
+	if (!ne_portlist[index])
+		return -ENXIO;
+    dev->base_addr = base_addr = ne_portlist[index];
+    dev->irq = ne_irqlist[index++];
+#elif defined(CONFIG_COLDFIRE)
+	static int once = 0;
+	if (once)
+		return -ENXIO;
+	if (base_addr == 0) {
+		dev->base_addr = base_addr = NE2000_ADDR;
+		dev->irq = NE2000_IRQ_VECTOR;
+		once++;
+	}
+#elif defined(CONFIG_CPU_H8300H)
+	static int once = 0;
+	if (once)
+		return -ENXIO;
+	dev->base_addr = base_addr = NE2000_ADDR;
+	dev->irq = NE2000_IRQ_VECTOR;
+	once++;
+#endif
 
 	SET_MODULE_OWNER(dev);
 
@@ -242,6 +284,7 @@
 	int reg0, ret;
 	static unsigned version_printed;
 
+#if !defined(CONFIG_COLDFIRE)
 #ifdef CONFIG_TOSHIBA_RBTX4927
 #include <asm/tx4927/toshiba_rbtx4927.h>
 	ioaddr = RBTX4927_RTL_8019_BASE;
@@ -251,6 +294,7 @@
 
 	if (!request_region(ioaddr, NE_IO_EXTENT, dev->name))
 		return -EBUSY;
+#endif
 
 	reg0 = inb_p(ioaddr);
 	if (reg0 == 0xFF) {
@@ -343,10 +387,94 @@
 			wordlength = 1;
 	}
 
+#if defined(CONFIG_M5307) || defined(CONFIG_M5407)
+    {
+	outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
+	for(i = 0; i < 6; i++)
+	{
+		SA_prom[i] = inb(ioaddr + i + 1);
+	}
+	SA_prom[14] = SA_prom[15] = 0x57;
+    }
+#endif /* CONFIG_M5307 || CONFIG_M5407 */
+#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3)
+    {
+	unsigned char *ep;
+	static int nr = 0;
+	ep = (unsigned char *) (0xf0006000 + (nr++ * 6));
+	/*
+	 * MAC address should be in FLASH, check that it is valid.
+	 * If good use it, otherwise use the default.
+	 */
+	if (((ep[0] == 0xff) && (ep[1] == 0xff) && (ep[2] == 0xff) &&
+	    (ep[3] == 0xff) && (ep[4] == 0xff) && (ep[5] == 0xff)) ||
+	    ((ep[0] == 0) && (ep[1] == 0) && (ep[2] == 0) &&
+	    (ep[3] == 0) && (ep[4] == 0) && (ep[5] == 0))) {
+		ep = (unsigned char *) &ne_defethaddr[0];
+		ne_defethaddr[5]++;
+	}
+
+	for(i = 0; i < 6; i++)
+		SA_prom[i] = ep[i];
+	SA_prom[14] = SA_prom[15] = 0x57;
+
+#if 0
+	{
+		unsigned char val;
+		/*
+	 	 * Set ethernet interface to be AUI.
+	 	 */
+		val = inb_p(ioaddr + EN0_RCNTHI);
+		outb_p(0x01 , (ioaddr + EN0_RCNTHI));
+	}
+#endif
+
+#if defined(CONFIG_M5206e) && defined(CONFIG_NETtel)
+	wordlength = 1;
+
+	/* We must set the 8390 for 8bit mode. */
+	outb_p(0x48, ioaddr + EN0_DCFG);
+#endif
+	start_page = NESM_START_PG;
+	stop_page = NESM_STOP_PG;
+    }
+#elif defined(CONFIG_CFV240)
+    {
+	unsigned char *ep = (unsigned char *) 0xffc0406b;
+	/*
+	 * MAC address should be in FLASH, check that it is valid.
+	 * If good use it, otherwise use the default.
+	 */
+	if (((ep[0] == 0xff) && (ep[1] == 0xff) && (ep[2] == 0xff) &&
+	    (ep[3] == 0xff) && (ep[4] == 0xff) && (ep[5] == 0xff)) ||
+	    ((ep[0] == 0) && (ep[1] == 0) && (ep[2] == 0) &&
+	    (ep[3] == 0) && (ep[4] == 0) && (ep[5] == 0))) {
+		ep = (unsigned char *) &ne_defethaddr[0];
+		ne_defethaddr[5]++;
+	}
+	outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
+	for(i = 0; i < 6; i++)
+		SA_prom[i] = ep[i];
+	SA_prom[14] = SA_prom[15] = 0x57;
+    }
+#elif defined(CONFIG_M5206e)
+    {
+	outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
+	for(i = 0; i < 6; i++)
+	{
+		SA_prom[i] = inb(ioaddr + i + 1);
+	}
+	SA_prom[14] = SA_prom[15] = 0x57;
+    }
+#endif /* CONFIG_M5206e */
+
+#if !(defined(CONFIG_M5206e) && defined(CONFIG_NETtel))
 	if (wordlength == 2)
 	{
+#ifndef CONFIG_COLDFIRE
 		for (i = 0; i < 16; i++)
 			SA_prom[i] = SA_prom[i+i];
+#endif
 		/* We must set the 8390 for word mode. */
 		outb_p(0x49, ioaddr + EN0_DCFG);
 		start_page = NESM_START_PG;
@@ -362,6 +490,12 @@
 		stop_page = NE1SM_STOP_PG;
 #endif
 	}
+#endif
+#if defined(CONFIG_CPU_H8300H)
+	start_page = NESM_START_PG;
+	stop_page = NESM_STOP_PG;
+	H8300_INIT_NE();
+#endif
 
 	neX000 = (SA_prom[14] == 0x57  &&  SA_prom[15] == 0x57);
 	ctron =  (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d);
@@ -445,6 +579,10 @@
 	/* Snarf the interrupt now.  There's no point in waiting since we cannot
 	   share and the board will usually be enabled. */
 	ret = request_irq(dev->irq, ei_interrupt, 0, name, dev);
+#ifdef CONFIG_COLDFIRE
+	if (ret == 0)
+		ne2000_irqsetup(dev->irq);
+#endif
 	if (ret) {
 		printk (" unable to get IRQ %d (errno=%d).\n", dev->irq, ret);
 		goto err_out_kfree;
@@ -485,7 +623,9 @@
 	kfree(dev->priv);
 	dev->priv = NULL;
 err_out:
+#if !defined(CONFIG_COLDFIRE) && !defined(CONFIG_CPU_H8300H)
 	release_region(ioaddr, NE_IO_EXTENT);
+#endif
 	return ret;
 }
 
diff -urN linux-2.4.29/drivers/net/netarmeth.c linux-2.4.29-uc1/drivers/net/netarmeth.c
--- linux-2.4.29/drivers/net/netarmeth.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/netarmeth.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,1391 @@
+/*
+ * drivers/net/netarmeth.c
+ *
+ * Copyright (C) 2000 NETsilicon, Inc.
+ * Copyright (C) 2000 WireSpeed Communications Corporation
+ * Copyright (C) 2001 IMMS gGmbH
+ *
+ * This software is copyrighted by WireSpeed. LICENSEE agrees that
+ * it will not delete this copyright notice, trademarks or protective
+ * notices from any copy made by LICENSEE.
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall WireSpeed
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : Jackie Smith Cashion and David Smith
+ *             Rolf Peukert (Kernel 2.4.x adaption in progress,
+ *                           added support for AMD 79C901 HomePHY)
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+/* for netarm_dma_module.h included via <asm/io.h> */
+#define OLD_STYLE_NETARM_DMA_CONFIGURATION
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+
+#include "netarmeth.h"
+
+/* Function Prototypes (used internally in this module) */
+
+static void na_disable_eth_irqs(void);
+static void na_enable_eth_irqs(void);
+static void na_get_mac_addr(struct net_device *dev);
+static void na_rx_fifo_reset(unsigned long ldev);
+static void na_enable_timer(struct net_device *dev);
+static void na_disable_timer(struct net_device *dev);
+static void na_reset_rx_fifo(struct netarmeth_dev *na_dev);
+static void na_load_mca_hash_table(struct dev_mc_list *mc_list);
+
+/* Static Global Variables */
+
+static const char *cardname = "netarmeth"; // Interface Name
+
+
+/*--------------------------------------------------------------------*
+	Utility Functions
+ *--------------------------------------------------------------------*/
+
+/* Enable and disable functions for DMA interrupts.
+   The ethernet service interrupts are not needed in DMA mode. */
+
+static void
+na_disable_eth_irqs(void)
+{
+  NA_PRINTK("na_disable_eth_irqs\n");
+
+  disable_irq(IRQ_DMA01);
+  disable_irq(IRQ_DMA02);
+}
+
+static void
+na_enable_eth_irqs(void)
+{
+  NA_PRINTK("na_enable_eth_irqs\n");
+
+  enable_irq(IRQ_DMA01);
+  enable_irq(IRQ_DMA02);
+}
+
+
+// The Ethernet controller contains three station address registers.  Each
+// 32 bit register contains 16 bits of the 48 bit MAC address. Ignore the high
+// 16 bits of each register.
+
+static void
+na_get_mac_addr(struct net_device *dev)
+{
+  unsigned short *p;
+
+  NA_PRINTK("na_get_mac_addr\n");
+
+  p = (unsigned short *) dev->dev_addr;
+  p[0] = (unsigned short) inl_t(get_eth_reg_addr(NETARM_ETH_SAL_STATION_ADDR_1));
+  p[1] = (unsigned short) inl_t(get_eth_reg_addr(NETARM_ETH_SAL_STATION_ADDR_2));
+  p[2] = (unsigned short) inl_t(get_eth_reg_addr(NETARM_ETH_SAL_STATION_ADDR_3));
+
+  NA_PRINTK2("  %X %X %X %X %X %X\n",
+    dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+    dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+}
+
+
+static void
+na_rx_fifo_reset(unsigned long ldev)
+{
+  struct net_device *dev = (struct net_device *)ldev;
+  struct netarmeth_dev *na_dev = dev->priv;
+
+  /* If we're still receiving packets, keep going. */
+  if (na_dev->stats.rx_packets != na_dev->rx_fifo_packets) {
+    na_dev->rx_fifo_packets = na_dev->stats.rx_packets;
+    NA_PRINTK2("na_rx_fifo_reset 1\n");
+  }
+  else if (inl_t(get_eth_reg_addr(NETARM_ETH_GEN_CTRL)) & NETARM_ETH_GCR_ERXDMA
+	   && !(inl_t(get_dma_reg_addr(NETARM_DMA1A_STATUS)) & 0xdf000000)
+	   && ((inl_t(get_eth_reg_addr(NETARM_ETH_GEN_STAT)) & 0x0a000000)
+	       == 0x02000000)) { 
+      na_reset_rx_fifo(na_dev);	    
+  }
+  na_enable_timer(dev);
+}
+
+static void
+na_enable_timer(struct net_device *dev)
+{
+  struct netarmeth_dev *na_dev;
+
+  na_dev = dev->priv;
+    
+  na_dev->rx_fifo_packets = na_dev->stats.rx_packets;
+  init_timer(&na_dev->rx_fifo_timer);
+  na_dev->rx_fifo_timer.function = na_rx_fifo_reset;
+  na_dev->rx_fifo_timer.data = (unsigned long) dev;
+  na_dev->rx_fifo_timer.expires = jiffies + (HZ >> 3);
+  add_timer(&na_dev->rx_fifo_timer);
+}
+
+static void
+na_disable_timer(struct net_device *dev)
+{
+  struct netarmeth_dev *na_dev;
+
+  na_dev = dev->priv;    
+  del_timer(&na_dev->rx_fifo_timer);
+}
+
+static void
+na_reset_rx_fifo(struct netarmeth_dev *na_dev)
+{
+  unsigned long reg;
+  int           i;
+
+  NA_PRINTK("na_reset_rx_fifo\n");
+
+  // Disable receive DMA.
+
+  outl_t((inl_t(get_eth_reg_addr(NETARM_ETH_GEN_CTRL))
+	  & ~NETARM_ETH_GCR_ERXDMA),
+	 get_eth_reg_addr(NETARM_ETH_GEN_CTRL));
+
+  // Disable receive FIFO.
+
+  outl_t((inl_t(get_eth_reg_addr(NETARM_ETH_GEN_CTRL)) & ~NETARM_ETH_GCR_ERX),
+	 get_eth_reg_addr(NETARM_ETH_GEN_CTRL));
+
+  // Disable DMA
+
+  outl_t((inl_t(get_dma_reg_addr(NETARM_DMA1A_CONTROL)) & 0x7ffffc00),
+	 get_dma_reg_addr(NETARM_DMA1A_CONTROL));
+
+  // Delay 20 microsconds.
+
+  udelay(20);
+
+  // If NRIP or CAIP is set, reset them.
+  
+  reg = inl_t(get_dma_reg_addr(NETARM_DMA1A_CONTROL));
+  if (reg & 0x20000000) {
+    reg &= 0x20f00000;
+    outl_t(reg, get_dma_reg_addr(NETARM_DMA1A_CONTROL));
+  }
+
+  // Reset DMA descriptors
+
+  for (i = 0; i < NA_MAX_RX_BUF; i++) {
+    na_dev->rx_dma_desc[i].src_buf_ptr  = (unsigned long) virt_to_bus(na_dev->rx_skb[i]->data);
+    na_dev->rx_dma_desc[i].src_buf_ptr &= ~(NETARM_DMA_BD0_LAST
+					    | NETARM_DMA_BD0_IDONE);
+    na_dev->rx_dma_desc[i].buf_len      = NA_MAX_ETH_FRAME;
+    na_dev->rx_dma_desc[i].stat         = 0;
+    // Clear the F bit.
+    na_dev->rx_dma_desc[i].buf_len     &= ~NETARM_DMA_BD1_FULL;
+  }
+  na_dev->rx_dma_desc[NA_MAX_RX_BUF-1].src_buf_ptr |= NETARM_DMA_BD0_WRAP;
+  na_dev->rx_sw_index = 0;
+
+  // Reenable DMA
+
+  outl_t((inl_t(get_dma_reg_addr(NETARM_DMA1A_CONTROL)) | 0x80000000),
+	 get_dma_reg_addr(NETARM_DMA1A_CONTROL));
+
+  // Reenable receive FIFO.
+
+  outl_t((inl_t(get_eth_reg_addr(NETARM_ETH_GEN_CTRL)) | NETARM_ETH_GCR_ERX),
+	 get_eth_reg_addr(NETARM_ETH_GEN_CTRL));
+
+  // Reenable receive DMA.
+
+  outl_t((inl_t(get_eth_reg_addr(NETARM_ETH_GEN_CTRL))
+	  | NETARM_ETH_GCR_ERXDMA),
+	 get_eth_reg_addr(NETARM_ETH_GEN_CTRL));
+}
+
+static inline void
+na_start_xmit(struct netarmeth_dev *na_dev)
+{
+  unsigned long reg;
+  struct sk_buff *skb = skb_dequeue(&na_dev->tx_skb_queue);
+    
+  if (skb == NULL) return;
+
+  // The skb will be free'd in na_tx_interrupt.
+
+  na_dev->tx_skb = skb;
+
+  // Set up the transmit DMA buffer descriptor.
+
+  na_dev->tx_dma_desc.src_buf_ptr  = (unsigned long) virt_to_bus(skb->data);
+  na_dev->tx_dma_desc.src_buf_ptr |= (NETARM_DMA_BD0_WRAP
+				      | NETARM_DMA_BD0_IDONE
+				      | NETARM_DMA_BD0_LAST);
+  na_dev->tx_dma_desc.buf_len      = skb->len;
+  na_dev->tx_dma_desc.stat         = 0;
+  na_dev->tx_dma_desc.buf_len     |= NETARM_DMA_BD1_FULL;
+
+  // Clear possible Not Ready interrupt and reactivate DMA channel.
+
+  reg = (inl_t(get_dma_reg_addr(NETARM_DMA2_STATUS))
+	 & NETARM_DMA_STAT_INT_EN_MASK) | NETARM_DMA_STAT_NR_INTPEN;
+  outl_t(reg, get_dma_reg_addr(NETARM_DMA2_STATUS));
+}
+
+
+/*--------------------------------------------------------------------*
+  Functions for the Media Independent Interface (MII)
+
+  These functions assume the current Ethernet controller configuration
+  uses an ENABLE or Home PHY through the MII interface.
+ *--------------------------------------------------------------------*/
+
+static unsigned long
+na_mii_poll_busy(void)
+{
+	unsigned long start_time, current_time;
+
+	// Poll until the busy bit is clear or one second has elapsed.
+	// (this is PHY-type-independent)
+
+	start_time = current_time = jiffies;
+	while ((current_time < start_time + NA_MII_POLL_BUSY_DELAY) &&
+	       (inl_t(get_eth_reg_addr(NETARM_ETH_MII_IND)) &
+	        NETARM_ETH_MIII_BUSY)) {
+		current_time = jiffies;
+	}
+	if (current_time < start_time + NA_MII_POLL_BUSY_DELAY) {
+		return (1);
+	} else {
+		NA_PRINTK("na_mii_poll_busy - one second elapsed.\n");
+		return (0);
+	}
+}
+
+// na_mii_identify_phy
+//
+// This function tries to identify the PHY chip in the current hardware
+// configuration.
+//
+// Return Values:
+//   NA_ENABLE_PHY (0)
+//   NA_LEVEL1_PHY (1)
+//   NA_HOME_PHY (2)	-> declared in netarmeth.h
+
+static na_phy_type
+na_mii_identify_phy(void)
+{
+	int id_reg_a, id_reg_b;
+
+	NA_PRINTK("na_mii_identify_phy\n");
+
+	/* check for Enable PHY */
+	outl_t(0x402, get_eth_reg_addr(NETARM_ETH_MII_ADDR));
+	outl_t((inl_t(get_eth_reg_addr(NETARM_ETH_MII_CMD)) | NETARM_ETH_MIIC_RSTAT),
+	       get_eth_reg_addr(NETARM_ETH_MII_CMD));
+	na_mii_poll_busy();
+	id_reg_a = inl_t(get_eth_reg_addr(NETARM_ETH_MII_READ));
+
+	if (id_reg_a == 0x0043) {
+		/* This must be an Enable or a Lucent LU3X31 PHY chip */
+		NA_PRINTK("  Enable PHY\n");
+		return (NA_ENABLE_PHY);
+	}
+
+	/* check for AMD 79C901 HomePHY */
+	outl_t(0x102, get_eth_reg_addr(NETARM_ETH_MII_ADDR));
+	outl_t((inl_t(get_eth_reg_addr(NETARM_ETH_MII_CMD)) | NETARM_ETH_MIIC_RSTAT),
+	       get_eth_reg_addr(NETARM_ETH_MII_CMD));
+	na_mii_poll_busy();
+	id_reg_a = inl_t(get_eth_reg_addr(NETARM_ETH_MII_READ));
+
+	outl_t(0x103, get_eth_reg_addr(NETARM_ETH_MII_ADDR));
+	outl_t((inl_t(get_eth_reg_addr(NETARM_ETH_MII_CMD)) | NETARM_ETH_MIIC_RSTAT),
+	       get_eth_reg_addr(NETARM_ETH_MII_CMD));
+	na_mii_poll_busy();
+	id_reg_b = inl_t(get_eth_reg_addr(NETARM_ETH_MII_READ));
+
+	if ((id_reg_a == 0x0000) && (id_reg_b == 0x6b71)) {
+		/* This must be an AMD Home PHY chip */
+		NA_PRINTK("  Home PHY\n");
+		return (NA_HOME_PHY);
+	}
+
+	/* else, i.e. default */
+	NA_PRINTK("  Level 1 PHY\n");
+	return (NA_LEVEL1_PHY);
+}
+
+static void
+na_mii_reset(struct net_device *dev)
+{
+	struct netarmeth_dev *na_dev;
+
+	NA_PRINTK("na_mii_reset\n");
+
+	if (dev == NULL) {
+		NA_PRINTK("na_mii_reset - NULL parameter\n");
+		return;
+	}
+	na_dev = dev->priv;
+
+	na_dev->phy_type = na_mii_identify_phy();
+	if ((na_dev->phy_type != NA_ENABLE_PHY) &&
+	    (na_dev->phy_type != NA_HOME_PHY)) {
+		printk(KERN_WARNING "%s:  Found other than Enable, Lucent or Home PHY.\n", dev->name);
+	}
+
+	/* select appropriate Control register */
+	if (na_dev->phy_type == NA_HOME_PHY)
+		outl_t(0x100, get_eth_reg_addr(NETARM_ETH_MII_ADDR));
+	else
+		outl_t(0x400, get_eth_reg_addr(NETARM_ETH_MII_ADDR));
+
+	outl_t(0x8000, get_eth_reg_addr(NETARM_ETH_MII_WRITE));
+	na_mii_poll_busy();
+
+	outl_t(0, get_eth_reg_addr(NETARM_ETH_MII_WRITE));
+	na_mii_poll_busy();
+}
+
+static unsigned long
+na_mii_negotiate(struct netarmeth_dev *na_dev)
+{
+	unsigned long start_time, current_time;
+	unsigned long read_data;
+
+	NA_PRINTK("na_mii_negotiate\n");
+
+	/* Select Autonegotiation Advertisement register */
+	if (na_dev->phy_type == NA_HOME_PHY)
+		outl_t(0x101, get_eth_reg_addr(NETARM_ETH_MII_ADDR));
+	else
+		outl_t(0x404, get_eth_reg_addr(NETARM_ETH_MII_ADDR));
+
+	/* Enable auto-negotiation */
+	outl_t(0x01E1, get_eth_reg_addr(NETARM_ETH_MII_WRITE));
+	na_mii_poll_busy();
+
+	/* Select Control register */
+	if (na_dev->phy_type == NA_HOME_PHY)
+		outl_t(0x100, get_eth_reg_addr(NETARM_ETH_MII_ADDR));
+	else
+		outl_t(0x400, get_eth_reg_addr(NETARM_ETH_MII_ADDR));
+
+	/* Restart auto-negotiation */
+	outl_t(0x1200, get_eth_reg_addr(NETARM_ETH_MII_WRITE));
+	na_mii_poll_busy();
+
+	// Wait for auto-negotiation to complete or for predefined delay to elapse.
+
+	start_time = current_time = jiffies;
+	do {
+		/* Select Status register */
+		if (na_dev->phy_type == NA_HOME_PHY)
+			outl_t(0x101, get_eth_reg_addr(NETARM_ETH_MII_ADDR));
+		else
+			outl_t(0x401, get_eth_reg_addr(NETARM_ETH_MII_ADDR));
+
+		outl_t((inl_t(get_eth_reg_addr(NETARM_ETH_MII_CMD))
+		        | NETARM_ETH_MIIC_RSTAT),
+		       get_eth_reg_addr(NETARM_ETH_MII_CMD));
+		na_mii_poll_busy();
+
+		read_data = inl_t(get_eth_reg_addr(NETARM_ETH_MII_READ));
+		if ((read_data & 0x0024) == 0x0024) {
+			return (0);
+		}
+		current_time = jiffies;
+	} while (current_time < start_time + NA_MII_NEGOTIATE_DELAY);
+
+	NA_PRINTK("  MII negotiation delay elapsed\n");
+	return (1);
+}
+
+// na_mii_check_speed
+//
+// Determine the operating speed of the Ethernet interface.
+//
+// Return Values:
+//   NA_10MBPS  (0):   10 Mbps
+//   NA_100MBPS (1):  100 Mbps
+
+static unsigned long
+na_mii_check_speed(struct netarmeth_dev *na_dev)
+{
+	// Check link status.  If 0, default to 100 Mbps.
+	NA_PRINTK("na_mii_check_speed\n");
+
+	if (na_dev->phy_type == NA_HOME_PHY) {
+		/* The AMD Home PHY only supports 10 Mbps anyway */
+		NA_PRINTK("  returning NA_10MBPS (HomePHY)\n");
+		na_dev->media_100BaseT = NA_10MBPS;
+	} else {
+		/* Read Status register */
+		outl_t(0x401, get_eth_reg_addr(NETARM_ETH_MII_ADDR));
+		outl_t((inl_t(get_eth_reg_addr(NETARM_ETH_MII_CMD)) | NETARM_ETH_MIIC_RSTAT),
+		       get_eth_reg_addr(NETARM_ETH_MII_CMD));
+		na_mii_poll_busy();
+
+		if ((inl_t(get_eth_reg_addr(NETARM_ETH_MII_READ)) & 0x0004) == 0) {
+			NA_PRINTK("  returning NA_100MBPS (link is down)\n");
+			na_dev->media_100BaseT = NA_100MBPS;
+		} else {
+			/* Now it's OK to check the normal speed status */
+			outl_t(0x417, get_eth_reg_addr(NETARM_ETH_MII_ADDR));
+			outl_t((inl_t(get_eth_reg_addr(NETARM_ETH_MII_CMD)) | NETARM_ETH_MIIC_RSTAT),
+			       get_eth_reg_addr(NETARM_ETH_MII_CMD));
+			na_mii_poll_busy();
+
+			if ((inl_t(get_eth_reg_addr(NETARM_ETH_MII_READ)) & 0x0200) != 0) {
+				NA_PRINTK("  returning NA_100MBPS (b)\n");
+				na_dev->media_100BaseT = NA_100MBPS;
+			} else {
+				NA_PRINTK("  returning NA_10MBPS\n");
+				na_dev->media_100BaseT = NA_10MBPS;
+			}
+		}
+	}
+	return(na_dev->media_100BaseT);
+}
+
+/*--------------------------------------------------------------------*
+	MULTICAST ADDRESS HASH TABLE FUNCTIONS
+ *--------------------------------------------------------------------*/
+
+static void
+na_set_hash_bit(unsigned char *hash_table, int bit)
+{
+  int byte_index, bit_index;
+
+  NA_PRINTK3("na_set_hash_bit\n");
+
+  byte_index = bit >> 3;
+  bit_index = bit & 7;
+  hash_table[byte_index] |= (1 << bit_index);
+}
+
+// na_rotate
+//
+// Input arguments:
+//   reg         value to rotate
+//   direction   LEFT or RIGHT
+//   bits        # of bits to rotate
+
+static unsigned short
+na_rotate (unsigned short reg, int direction, int bits)
+{
+  int index;
+
+  NA_PRINTK3("na_rotate:  %X %s %d.\n",
+    reg, ((direction == NA_LEFT) ? "LEFT" : "RIGHT"), bits);
+
+  if (direction == NA_LEFT) {
+    for (index = 0; index < bits; index++) {
+      if (reg & 0x8000) {           // if high bit set
+        reg = (reg << 1) | 1;       // shift left and or in 1
+      } else {
+        reg <<= 1;
+      }
+    }
+  } else {                          // if ror
+    for (index = 0; index < bits; index++) {
+      if (reg & 1) {                // if low bit set
+        reg = (reg >> 1) | 0x8000;  // shift right and or in hi bit
+      } else {
+        reg >>= 1;
+      }
+    }
+  }
+  NA_PRINTK3("  returning %X\n", reg);
+  return (reg);
+}
+
+// na_calculate_hash_bit
+//
+// This routine calculates the bit to set in the CRC hash table
+// to enable receipt of the specified multicast address.
+//
+// Return Value:  bit position to set in hash table
+
+static int
+na_calculate_hash_bit(unsigned char *mca)
+{
+  unsigned short  copy_mca[3];
+  unsigned short *mcap, bp, bx;
+  unsigned long   crc;
+  int             result, mca_word, bit_index;
+
+  NA_PRINTK3("na_calculate_hash_bit\n");
+
+  memcpy (copy_mca, mca, sizeof(copy_mca));
+
+  mcap = copy_mca;
+  crc = 0xffffffffL;
+
+  for (mca_word = 0; mca_word < 3; mca_word++) {
+    bp = *mcap;                              // get word of address
+    mcap++;
+
+    for (bit_index = 0; bit_index < 16; bit_index++) {
+      bx = (unsigned short) (crc >> 16);     // get high word of crc
+      bx = na_rotate(bx, NA_LEFT, 1);        // bit 31 to lsb
+      bx ^= bp;                              // combine with incoming
+      crc <<= 1;                             // shift crc left 1 bit
+      bx &= 1;                               // get control bit
+      if (bx) {                              // if bit set
+        crc ^= NA_POLYNOMIAL;                // xero crc with polynomial
+      }
+      crc |= bx;                             // or in control bit
+      bp = na_rotate(bp, NA_RIGHT, 1);
+    }
+  }
+
+  // CRC calculation done.  The 6-bit result resides in bits locations 28:23.
+
+  result = (crc >> 23) & 0x3f;
+
+  return (result);
+}
+
+// na_load_mca_hash_table
+//
+// This function generates the multicast address hash table from the
+// multicast addresses contained in the provided linked list.  This function
+// loads this table into the Ethernet controller.
+
+static void
+na_load_mca_hash_table(struct dev_mc_list *mc_list)
+{
+  unsigned short      hash_table[4];
+  struct dev_mc_list *mc_list_entry;
+  int                 bit_number;
+
+  NA_PRINTK("na_load_mca_hash_table\n");
+
+  // Generate the hash table.
+
+  memset(hash_table, 0, sizeof(hash_table));
+
+  for (mc_list_entry = mc_list;
+       mc_list_entry != NULL;
+       mc_list_entry = mc_list_entry->next)
+  {
+    NA_PRINTK("  multicast address:  %X %X %X %X %X %X\n",
+      mc_list_entry->dmi_addr[0], mc_list_entry->dmi_addr[1],
+      mc_list_entry->dmi_addr[2], mc_list_entry->dmi_addr[3],
+      mc_list_entry->dmi_addr[4], mc_list_entry->dmi_addr[5]);
+
+    bit_number = na_calculate_hash_bit(mc_list_entry->dmi_addr);
+    na_set_hash_bit((unsigned char *) hash_table, bit_number);
+  }
+  NA_PRINTK("  hash table:  %X %X %X %X\n",
+    hash_table[0], hash_table[1], hash_table[2], hash_table[3]);    
+
+  // Load the hash table into the Ethernet controller.
+
+  outl_t(hash_table[0], get_eth_reg_addr(NETARM_ETH_SAL_HASH_TBL_1));
+  outl_t(hash_table[1], get_eth_reg_addr(NETARM_ETH_SAL_HASH_TBL_2));
+  outl_t(hash_table[2], get_eth_reg_addr(NETARM_ETH_SAL_HASH_TBL_3));
+  outl_t(hash_table[3], get_eth_reg_addr(NETARM_ETH_SAL_HASH_TBL_4));
+}
+
+
+/*--------------------------------------------------------------------*
+	Interrupt Functions
+ *--------------------------------------------------------------------*/
+
+static void
+netarmeth_rx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+  struct net_device    *dev;
+  struct netarmeth_dev *na_dev;
+  unsigned long         status_reg, reg;
+  struct sk_buff       *current_skb, *new_skb;
+  int                   hw_index;
+
+  NA_PRINTK2("netarmeth_rx_interrupt\n");
+
+  dev = dev_id;
+  if (dev == NULL) {
+    printk(KERN_WARNING "Ethernet receive interrupt, null device structure.\n");
+
+    status_reg = inl_t(get_dma_reg_addr(NETARM_DMA1A_STATUS));
+    status_reg &= (NETARM_DMA_STAT_INTPEN_MASK | NETARM_DMA_STAT_INT_EN_MASK);
+    // Acknowledge the pending interrupts.
+    outl_t(status_reg, get_dma_reg_addr(NETARM_DMA1A_STATUS));
+    return;
+  }
+  na_dev = dev->priv;
+/*
+  if (na_dev->rx_interrupt) {
+    // Normally this can not happen, but I want to make sure.
+    NA_PRINTK("rx irq recursion\n");
+    return;
+  }
+*/
+  na_dev->rx_interrupt = 1;
+
+  // Determine which receive interrupts are pending.  Acknowledge the
+  // pending interrupts by setting the interrupt pending bits in the
+  // DMA Status Register.  If a Normal Completion or Buffer Not Ready
+  // interrupt is pending process the received buffer(s) from the
+  // receive DMA descriptor ring.
+
+  status_reg = inl_t(get_dma_reg_addr(NETARM_DMA1A_STATUS));
+  NA_PRINTK2("  DMA 1A status: %lX\n", status_reg);
+
+  status_reg &= (NETARM_DMA_STAT_INTPEN_MASK | NETARM_DMA_STAT_INT_EN_MASK);
+  // Acknowledge the pending interrupts.
+  outl_t(status_reg, get_dma_reg_addr(NETARM_DMA1A_STATUS));
+
+  if (status_reg & (NETARM_DMA_STAT_NC_INTPEN | NETARM_DMA_STAT_NR_INTPEN))
+  {
+    if (status_reg & NETARM_DMA_STAT_NR_INTPEN)
+    {
+	/* "F" bit in DMA buffer descriptor in incorrect state */
+	NA_PRINTK("  *** NR interrupt ***\n");
+    }
+
+    // Process all the receive DMA buffer descriptors that have the
+    // "full" bit set until the descriptor indicated by the hardware
+    // DMA descriptor index is processed.
+
+    reg = inl_t(get_dma_reg_addr(NETARM_DMA1A_CONTROL));
+    hw_index = NETARM_DMA_CTL_INDEX(reg) >> 3; // Bytes / 8
+    NA_PRINTK2("  hw_index: %lX, %d.\n", reg, hw_index);
+
+    do
+    {
+      NA_PRINTK2("  sw_index: %d.\n", na_dev->rx_sw_index);
+
+      if (na_dev->rx_dma_desc[na_dev->rx_sw_index].buf_len
+	  & NETARM_DMA_BD1_FULL) {
+
+        reg = na_dev->rx_dma_desc[na_dev->rx_sw_index].stat;
+        NA_PRINTK2(" RX desc[%d] stat: %lX\n", na_dev->rx_sw_index, reg);
+
+        if ((reg & NA_RXSTAT_ERR_MASK) || ((reg & NA_RXSTAT_RXOK) == 0))
+	{
+          // Receive Error.
+          NA_PRINTK("  Receive error.\n");
+          na_dev->stats.rx_errors++;
+
+          // If an overrun has occurred, the receive FIFO must be reset.
+          if (reg & NA_RXSTAT_ROVER)
+	  {
+            NA_PRINTK("  Reset receive FIFO.\n");
+            na_dev->stats.rx_fifo_errors++;
+            na_reset_rx_fifo(na_dev);
+          }
+          new_skb = na_dev->rx_skb[na_dev->rx_sw_index];
+        }
+	else if (reg & NA_RXSTAT_RXOK)
+	{
+          // Good Frame.
+          NA_PRINTK2("  Good Frame.\n");
+
+          // Save the current skb (receive buffer).
+          current_skb = na_dev->rx_skb[na_dev->rx_sw_index];
+
+          // Allocate a new skb to replace the one consumed by the current
+          // frame.  If a new new skb cannot be allocated, ignore (discard)
+          // this frame and reuse the original skb for a future frame.
+
+          new_skb = dev_alloc_skb(NA_MAX_ETH_FRAME + 2);
+          if (new_skb == NULL)
+	  {
+            NA_PRINTK("  dev_alloc_skb failure.\n");
+            na_dev->stats.rx_dropped++;
+            new_skb = na_dev->rx_skb[na_dev->rx_sw_index];
+	  } 
+	  else
+	  {
+	    // Pass the frame up.
+	    na_dev->stats.rx_packets++;
+
+	    reg = na_dev->rx_dma_desc[na_dev->rx_sw_index].buf_len
+		& ~NETARM_DMA_BD1_FULL;
+            NA_PRINTK3("  buf_len: %ld.\n", reg);
+            NA_PRINTK3("  %X %X %X %X %X %X %X %X %X %X %X %X %X %X\n",
+              current_skb->data[0], current_skb->data[1],
+              current_skb->data[2], current_skb->data[3],
+              current_skb->data[4], current_skb->data[5],
+              current_skb->data[6], current_skb->data[7],
+              current_skb->data[8], current_skb->data[9],
+              current_skb->data[10], current_skb->data[11],
+              current_skb->data[12], current_skb->data[13]);
+
+            skb_put(current_skb, reg);
+            current_skb->dev       = dev;
+            current_skb->protocol  = eth_type_trans(current_skb, dev);
+//            current_skb->ip_summed = CHECKSUM_UNNECESSARY;
+	    skb_pull(current_skb, 2);
+
+            netif_rx(current_skb);
+	  }
+        } 
+	else
+	{
+          // Discard frame.
+          NA_PRINTK("  RX unexpected receive status\n");
+          na_dev->stats.rx_errors++;
+          new_skb = na_dev->rx_skb[na_dev->rx_sw_index];
+	}
+
+        // Re-initialize the receive DMA descriptor.
+        na_dev->rx_skb[na_dev->rx_sw_index] = new_skb;
+        na_dev->rx_dma_desc[na_dev->rx_sw_index].src_buf_ptr =
+          (unsigned long) virt_to_bus(new_skb->data);
+
+        if (na_dev->rx_sw_index == NA_MAX_RX_BUF-1) {
+          na_dev->rx_dma_desc[NA_MAX_RX_BUF-1].src_buf_ptr
+	      |= NETARM_DMA_BD0_WRAP;
+        }
+        na_dev->rx_dma_desc[na_dev->rx_sw_index].buf_len  = NA_MAX_ETH_FRAME;
+        na_dev->rx_dma_desc[na_dev->rx_sw_index].stat     = 0;
+        na_dev->rx_dma_desc[na_dev->rx_sw_index].buf_len &= ~NETARM_DMA_BD1_FULL;
+
+        // Clear possible Not Ready interrupt and reactivate the DMA channel.
+	status_reg &= (NETARM_DMA_STAT_INTPEN_MASK
+		       | NETARM_DMA_STAT_INT_EN_MASK);
+	status_reg |= NETARM_DMA_STAT_NR_INTPEN;
+	// Acknowledge the pending interrupts.
+	outl_t(status_reg, get_dma_reg_addr(NETARM_DMA1A_STATUS));
+      }
+      else
+      {
+        // F bit is not set.
+        NA_PRINTK("  RX skipping descriptor.\n");
+      }
+
+      // Increment the receive DMA descriptor index.
+      na_dev->rx_sw_index++;
+      if (na_dev->rx_sw_index >= NA_MAX_RX_BUF) {
+        na_dev->rx_sw_index = 0;
+      }
+    } while (na_dev->rx_sw_index != hw_index);
+  }
+  else
+  {
+    NA_PRINTK("  RX Error Completion Interrupt\n");
+    na_dev->stats.rx_errors++;
+  }
+  na_dev->rx_interrupt = 0;
+}
+
+
+static void
+netarmeth_tx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+  struct net_device    *dev;
+  struct netarmeth_dev *na_dev;
+  unsigned long         status_reg;
+
+  NA_PRINTK2("netarmeth_tx_interrupt\n");
+
+  dev = dev_id;
+  if (dev == NULL) {
+    printk(KERN_WARNING "Ethernet transmit interrupt, null device structure.\n");
+
+    status_reg = inl_t(get_dma_reg_addr(NETARM_DMA2_STATUS));
+    status_reg &= (NETARM_DMA_STAT_INTPEN_MASK | NETARM_DMA_STAT_INT_EN_MASK);
+    // Acknowledge the pending interrupts.
+    outl_t(status_reg, get_dma_reg_addr(NETARM_DMA2_STATUS));
+
+    return;
+  }
+
+  na_dev = dev->priv;
+/*
+  if (na_dev->tx_interrupt) {
+    // Normally this can not happen, but I want to make sure.
+    NA_PRINTK("tx irq recursion\n");
+    return;
+  }
+*/
+  na_dev->tx_interrupt = 1;
+
+  // Determine which receive interrupts are pending.  Acknowledge the pending
+  // interrupts by setting the interrupt pending bits in the DMA Status
+  // Register.
+
+  status_reg = inl_t(get_dma_reg_addr(NETARM_DMA2_STATUS));
+  NA_PRINTK2("  DMA 2 status: %lX\n", status_reg);
+
+  status_reg &= (NETARM_DMA_STAT_INTPEN_MASK | NETARM_DMA_STAT_INT_EN_MASK);
+  // Acknowledge the pending interrupts.
+  outl_t(status_reg, get_dma_reg_addr(NETARM_DMA2_STATUS));
+
+  if (status_reg & NETARM_DMA_STAT_NC_INTPEN) {
+    na_dev->stats.tx_packets++;
+  } else {
+    na_dev->stats.tx_errors++;
+  }
+  if (na_dev->tx_skb) {
+    dev_kfree_skb_irq(na_dev->tx_skb); /* was FREE_WRITE */
+    /* fixed? calling dev_kfree_skb() from an interrupt caused a warning */
+    na_dev->tx_skb = NULL;
+  }
+  if (! skb_queue_empty(&na_dev->tx_skb_queue)) {
+    na_start_xmit(na_dev);  
+  }
+  else {
+    na_dev->tbusy = 0;
+  }
+  // mark_bh(NET_BH); not longer available, instead using
+  netif_wake_queue(dev);
+  na_dev->tx_interrupt = 0;
+}
+
+
+/*--------------------------------------------------------------------*
+	Hardware Initialization Functions
+ *--------------------------------------------------------------------*/
+
+static void
+na_reset_dma(void)
+{
+  NA_PRINTK("na_reset_dma\n");
+
+  /* Disable each channel, clear buffer pointer and interrupt bits */
+  outl_t((inl_t(get_dma_reg_addr(NETARM_DMA1A_CONTROL)) &
+	  ~NETARM_DMA_CTL_ENABLE), get_dma_reg_addr(NETARM_DMA1A_CONTROL));
+  outl_t(0, get_dma_reg_addr(NETARM_DMA1A_BFR_DESCRPTOR_PTR));
+  outl_t(0, get_dma_reg_addr(NETARM_DMA1A_STATUS));
+
+  outl_t((inl_t(get_dma_reg_addr(NETARM_DMA1B_CONTROL)) &
+	  ~NETARM_DMA_CTL_ENABLE), get_dma_reg_addr(NETARM_DMA1B_CONTROL));
+  outl_t(0, get_dma_reg_addr(NETARM_DMA1B_BFR_DESCRPTOR_PTR));
+  outl_t(0, get_dma_reg_addr(NETARM_DMA1B_STATUS));
+
+  outl_t((inl_t(get_dma_reg_addr(NETARM_DMA1C_CONTROL)) &
+	  ~NETARM_DMA_CTL_ENABLE), get_dma_reg_addr(NETARM_DMA1C_CONTROL));
+  outl_t(0, get_dma_reg_addr(NETARM_DMA1C_BFR_DESCRPTOR_PTR));
+  outl_t(0, get_dma_reg_addr(NETARM_DMA1C_STATUS));
+
+  outl_t((inl_t(get_dma_reg_addr(NETARM_DMA1D_CONTROL)) &
+	  ~NETARM_DMA_CTL_ENABLE), get_dma_reg_addr(NETARM_DMA1D_CONTROL));
+  outl_t(0, get_dma_reg_addr(NETARM_DMA1D_BFR_DESCRPTOR_PTR));
+  outl_t(0, get_dma_reg_addr(NETARM_DMA1D_STATUS));
+
+  outl_t((inl_t(get_dma_reg_addr(NETARM_DMA2_CONTROL)) &
+	  ~NETARM_DMA_CTL_ENABLE), get_dma_reg_addr(NETARM_DMA2_CONTROL));
+  outl_t(0, get_dma_reg_addr(NETARM_DMA2_BFR_DESCRPTOR_PTR));
+  outl_t(0, get_dma_reg_addr(NETARM_DMA2_STATUS));
+}
+
+// na_enable_dma
+
+static void
+na_enable_dma(struct net_device *dev)
+{
+  struct netarmeth_dev *na_dev;
+  unsigned long         reg;
+
+  NA_PRINTK("na_enable_dma\n");
+
+  na_dev = dev->priv;  
+
+  // Configure the DMA channels for transmit and receive.
+
+  outl_t((unsigned long) virt_to_bus(na_dev->rx_dma_desc),
+	 get_dma_reg_addr(NETARM_DMA1A_BFR_DESCRPTOR_PTR));
+  outl_t((NETARM_DMA_STAT_NC_INT_EN | NETARM_DMA_STAT_EC_INT_EN
+	  | NETARM_DMA_STAT_NR_INT_EN | NETARM_DMA_STAT_CA_INT_EN),
+	 get_dma_reg_addr(NETARM_DMA1A_STATUS));
+
+  outl_t((unsigned long) virt_to_bus(&na_dev->tx_dma_desc),
+	 get_dma_reg_addr(NETARM_DMA2_BFR_DESCRPTOR_PTR));
+  outl_t((NETARM_DMA_STAT_NC_INT_EN | NETARM_DMA_STAT_EC_INT_EN),
+	 get_dma_reg_addr(NETARM_DMA2_STATUS));
+
+  // Turn on each channel.
+
+  reg = NETARM_DMA_CTL_ENABLE | NETARM_DMA_CTL_BUS_100_PERCENT |
+        NETARM_DMA_CTL_MODE_FB_TO_MEM | NETARM_DMA_CTL_BURST_16_BYTE;
+  outl_t(reg, get_dma_reg_addr(NETARM_DMA1A_CONTROL));
+
+  if (na_dev->media_100BaseT) {
+    reg = NETARM_DMA_CTL_ENABLE | NETARM_DMA_CTL_BUS_100_PERCENT |
+          NETARM_DMA_CTL_MODE_FB_FROM_MEM | NETARM_DMA_CTL_BURST_16_BYTE;
+  } else {
+    reg = NETARM_DMA_CTL_ENABLE | NETARM_DMA_CTL_BUS_100_PERCENT |
+	  NETARM_DMA_CTL_MODE_FB_FROM_MEM;
+  }
+  outl_t(reg, get_dma_reg_addr(NETARM_DMA2_CONTROL));
+}
+
+
+// This function assumes the current Ethernet controller configuration uses
+// the ENABLE PHY through the MII interface.  The original vxWorks NET+ARM
+// Ethernet driver, upon which this driver initialization code is modeled,
+// also only supports the MII PHY but describes the initialization of the
+// ENDEC PHY.  (See eth_chip_reset() in NccEthCtrl.c from the NET+ARM vxWorks
+// source.)
+
+static void
+na_reset_eth(struct net_device *dev)
+{
+  struct netarmeth_dev *na_dev;
+
+  NA_PRINTK("na_reset_eth\n");
+
+  na_dev = dev->priv;
+
+  na_mii_reset(dev);
+
+  // Since this driver is designed for the NET+ARM-40, assume the NET+ARM clock
+  // is set to 25Mhz.
+
+  outl_t((NETARM_ETH_PCSC_CLKS_25M | NETARM_ETH_PCSC_ENJAB |
+	  NETARM_ETH_PCSC_NOCFR), get_eth_reg_addr(NETARM_ETH_PCS_CFG));
+
+  na_mii_negotiate(na_dev);
+  na_mii_check_speed(na_dev);
+
+  // Delay after resetting the chip before attempting to read/clear the
+  // statistics counters.
+
+  udelay(1000); // Delay 1 millisecond.  (Maybe this should be 1 second.)
+
+  // Turn receive on.
+  // Enable statistics register autozero on read.
+  // Do not insert MAC address on transmit.
+  // Do not enable special test modes.
+
+  outl_t((NETARM_ETH_STLC_AUTOZ | NETARM_ETH_STLC_RXEN),
+	 get_eth_reg_addr(NETARM_ETH_STL_CFG));
+
+  // Read MIB statistics counters to zero them.
+
+  inl_t(get_eth_reg_addr(NETARM_ETH_MIB_LCC));
+  inl_t(get_eth_reg_addr(NETARM_ETH_MIB_EDC));
+  inl_t(get_eth_reg_addr(NETARM_ETH_MIB_MCC));
+  inl_t(get_eth_reg_addr(NETARM_ETH_MIB_CRCEC));
+  inl_t(get_eth_reg_addr(NETARM_ETH_MIB_AEC));
+  inl_t(get_eth_reg_addr(NETARM_ETH_MIB_CEC));
+  inl_t(get_eth_reg_addr(NETARM_ETH_MIB_LFC));
+  inl_t(get_eth_reg_addr(NETARM_ETH_MIB_SFC));
+}
+
+// na_enable_eth
+
+static void
+na_enable_eth(struct net_device *dev)
+{
+  unsigned long reg;
+
+  NA_PRINTK("na_enable_eth\n");
+
+  // Set the inter-packet gap delay to 0.96us for MII.
+  // The NET+ARM H/W Reference Guide indicates that the Back-to-back IPG
+  // Gap Timer Register should be set to 0x15 and the Non Back-to-back IPG
+  // Gap Timer Register should be set to 0x00000C12 for the MII PHY.
+
+  outl_t(0x15, get_eth_reg_addr(NETARM_ETH_B2B_IPG_GAP_TMR));
+  outl_t(0x00000C12, get_eth_reg_addr(NETARM_ETH_NB2B_IPG_GAP_TMR));
+
+  // Add CRC to end of packets.
+  // Pad packets to minimum length of 64 bytes.
+  // Allow unlimited length transmit packets.
+  // Receive all broadcast packets.
+  //
+  // NOTE:  Multicast addressing is NOT enabled here currently.
+
+  outl_t((NETARM_ETH_MACC_CRCEN | NETARM_ETH_MACC_PADEN
+	  | NETARM_ETH_MACC_HUGEN), get_eth_reg_addr(NETARM_ETH_MAC_CFG));
+  outl_t(NETARM_ETH_SALF_BROAD, get_eth_reg_addr(NETARM_ETH_SAL_FILTER));
+  
+  // JSC - Determine how ifconfig passes in a special MAC address.
+  // Set it here.
+  na_get_mac_addr(dev); // JSC !!!
+
+  NA_PRINTK("  MCA Hash Table: %lX %lX %lX %lX\n",
+	    inl_t(get_eth_reg_addr(NETARM_ETH_SAL_HASH_TBL_1)),
+	    inl_t(get_eth_reg_addr(NETARM_ETH_SAL_HASH_TBL_2)),
+	    inl_t(get_eth_reg_addr(NETARM_ETH_SAL_HASH_TBL_3)),
+	    inl_t(get_eth_reg_addr(NETARM_ETH_SAL_HASH_TBL_4)));
+
+  // Clear any outstanding Ethernet DMA interrupts.
+
+  // Receive
+  outl_t(NETARM_DMA_STAT_INTPEN_MASK, get_dma_reg_addr(NETARM_DMA1A_STATUS));
+  // Transmit
+  outl_t(NETARM_DMA_STAT_INTPEN_MASK, get_dma_reg_addr(NETARM_DMA2_STATUS));
+
+  // Configure the Ethernet DMA channels.
+
+  na_enable_dma(dev);
+
+  // Associate the Ethernet DMA IRQs with the appropriate interrupt service
+  // routines.  No need to call request_dma.  The DMA controller assignments
+  // are hardwired.
+
+  if (request_irq(IRQ_DMA01, netarmeth_rx_interrupt, 0, cardname, dev)) {
+    printk(KERN_WARNING "%s:  request_irq(IRQ_DMA01) failure.\n", dev->name);
+  }
+  if (request_irq(IRQ_DMA02, netarmeth_tx_interrupt, 0, cardname, dev)) {
+    printk(KERN_WARNING "%s:  request_irq(IRQ_DMA02) failure.\n", dev->name);
+  }
+
+  // Autozero statistics registers after reading.
+  // Enable packet receiver.
+  // (This was already set in na_reset_eth.)
+
+  outl_t((NETARM_ETH_STLC_AUTOZ | NETARM_ETH_STLC_RXEN),
+	 get_eth_reg_addr(NETARM_ETH_STL_CFG));
+
+  // Enable receive FIFO.  Enable receive DMA.
+  // Enable transmit FIFO. Enable transmit DMA.
+
+  reg = NETARM_ETH_GCR_ERX | NETARM_ETH_GCR_ERXDMA | NETARM_ETH_GCR_ETX
+      | NETARM_ETH_GCR_ETXDMA | NETARM_ETH_GCR_PNA;
+  outl_t(reg, get_eth_reg_addr(NETARM_ETH_GEN_CTRL));
+}
+
+
+/*--------------------------------------------------------------------*
+	Exported Functions
+ *--------------------------------------------------------------------*/
+
+// netarmeth_open
+//
+// This function is typically called by ifconfig during system startup.
+// The Ethernet and DMA controllers are initialized and enabled here.
+
+static int
+netarmeth_open(struct net_device *dev)
+{
+  struct netarmeth_dev *na_dev;
+
+  NA_PRINTK("netarmeth_open\n");
+
+  na_dev = dev->priv;
+
+  // Disable interrupts from the Ethernet DMA channels.
+
+  na_disable_eth_irqs();
+
+  // Reset the Ethernet DMA channels.
+
+  na_reset_dma();
+
+  // Reset the Ethernet controller, and determine the line speed.
+
+  na_reset_eth(dev);
+
+  // Enable the Ethernet controller and the DMA channels.
+  // na_enable_eth calls na_enable_dma.
+
+  na_enable_eth(dev);
+
+  // Enable Ethernet and DMA interrupts.
+
+  na_dev->tbusy = 0;
+  na_dev->tx_interrupt = 0;
+  na_dev->rx_interrupt = 0;
+  na_enable_eth_irqs();
+
+  // Enable timer
+  na_enable_timer(dev);
+
+  na_dev->start = 1;
+
+  return (0);
+}
+
+
+static int
+netarmeth_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+  struct netarmeth_dev *na_dev;
+
+  NA_PRINTK2("netarmeth_start_xmit\n");
+
+  na_dev = dev->priv;
+
+  // Put skb on the queue
+  skb_queue_tail(&na_dev->tx_skb_queue, skb);
+  
+  if (test_and_set_bit(0, (void *) &na_dev->tbusy) == 0) {
+    NA_PRINTK2("%s:  Transmit idle, sending packet.\n", dev->name);
+    na_start_xmit(na_dev);
+  }
+  return (0);
+}
+
+
+static int
+netarmeth_close(struct net_device *dev)
+{
+  struct netarmeth_dev *na_dev;
+  struct sk_buff *skb;
+
+  NA_PRINTK("netarmeth_close\n");
+
+  na_dev = dev->priv;
+  na_dev->tbusy = 1;
+  na_dev->start = 0;
+
+  // Disable interrupts from the Ethernet DMA channels.
+
+  na_disable_eth_irqs();
+
+  // Reset the Ethernet DMA channels.
+
+  na_reset_dma();
+
+  // Clear any outstanding Ethernet DMA interrupts.
+
+  // Receive
+  outl_t(NETARM_DMA_STAT_INTPEN_MASK, get_dma_reg_addr(NETARM_DMA1A_STATUS));
+  // Transmit
+  outl_t(NETARM_DMA_STAT_INTPEN_MASK, get_dma_reg_addr(NETARM_DMA2_STATUS));
+
+  // Release the Ethernet DMA IRQs.
+
+  free_irq(IRQ_DMA01, dev);
+  free_irq(IRQ_DMA02, dev);
+
+  // Disable the timer.
+
+  na_disable_timer(dev);
+
+  // Free any buffers left in the hardware transmit queue
+
+  while ((skb = skb_dequeue(&na_dev->tx_skb_queue))) {
+    dev_kfree_skb(skb);  /* was FREE_WRITE */
+  }
+  return (0);
+}
+
+
+static struct net_device_stats *
+netarmeth_get_stats(struct net_device *dev)
+{
+  struct netarmeth_dev *na_dev;
+  unsigned long         flags;
+
+  NA_PRINTK("netarmeth_get_stats\n");
+
+  na_dev = dev->priv;
+
+  save_flags_cli(flags);
+
+  // CRC Errors
+  na_dev->stats.rx_crc_errors += inl_t(get_eth_reg_addr(NETARM_ETH_MIB_CRCEC));
+  // Alignment Errors
+  na_dev->stats.rx_frame_errors += inl_t(get_eth_reg_addr(NETARM_ETH_MIB_AEC));
+  // Long Frames
+  na_dev->stats.rx_length_errors
+      += inl_t(get_eth_reg_addr(NETARM_ETH_MIB_LFC));
+  // Short Frames
+  na_dev->stats.rx_length_errors
+      += inl_t(get_eth_reg_addr(NETARM_ETH_MIB_SFC));
+  // Late Collisions
+  na_dev->stats.tx_aborted_errors
+      += inl_t(get_eth_reg_addr(NETARM_ETH_MIB_LCC));
+  // Excessive Deferrals
+  na_dev->stats.tx_aborted_errors
+      += inl_t(get_eth_reg_addr(NETARM_ETH_MIB_EDC));
+  // Maximum Collisions
+  na_dev->stats.tx_aborted_errors
+      += inl_t(get_eth_reg_addr(NETARM_ETH_MIB_MCC));
+
+  restore_flags(flags);
+  return (&na_dev->stats);
+}
+
+// netarmeth_set_multicast_list
+//
+// Always accept all broadcast frames.
+
+static void
+netarmeth_set_multicast_list(struct net_device *dev)
+{
+  NA_PRINTK("netarmeth_set_multicast_list\n");
+
+  if (dev->flags & IFF_PROMISC)
+  {
+    // Enable promiscuous mode.
+    NA_PRINTK("  Enable promiscuous mode.\n");
+    outl_t(NETARM_ETH_SALF_PRO, get_eth_reg_addr(NETARM_ETH_SAL_FILTER));
+  }
+  else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > NA_MAX_MCA)
+  {
+    // Accept all multicast packets.
+    NA_PRINTK("  Accept all multicast packets.\n");
+    outl_t((NETARM_ETH_SALF_PRM | NETARM_ETH_SALF_BROAD),
+	   get_eth_reg_addr(NETARM_ETH_SAL_FILTER));
+  }
+  else if (dev->mc_count)
+  {
+    // Accept multicast packets using the hash table.
+    NA_PRINTK("  Accept multicast packets.  Load hash table.\n");
+    na_load_mca_hash_table(dev->mc_list);
+    outl_t((NETARM_ETH_SALF_PRA | NETARM_ETH_SALF_BROAD),
+	   get_eth_reg_addr(NETARM_ETH_SAL_FILTER));
+  }
+  else
+  {
+    // Accept frames addressed to this station.
+    NA_PRINTK("  Accept frames addressed to this station.\n");
+    outl_t(NETARM_ETH_SALF_BROAD, get_eth_reg_addr(NETARM_ETH_SAL_FILTER));
+  }
+  NA_PRINTK("  returning.\n");
+}
+
+// netarmeth_timeout
+//
+// copied from the am79c961 driver
+
+static void netarmeth_timeout(struct net_device *dev)
+{
+	NA_PRINTK("%s: transmit timed out, network cable problem?\n", dev->name);
+
+	/* FIXME: shouldn't we shutdown and restart the transmitter? */
+
+	netif_wake_queue(dev);
+}
+
+
+// netarmeth_init
+//
+// The NET+ARM Ethernet controller is an integral part of the NET+ARM chip.
+// The CSRs are located at fixed addresses.  The Ethernet controller always
+// uses DMA channels 1 and 2.  Therefore, this probe routine does not need
+// to locate the Ethernet controller.  This routine simply initializes the
+// device structure and the DMA buffer descriptors and registers the interrupt
+// service routines with LINUX.
+
+static int __init
+netarmeth_init(void)
+{
+  struct net_device    *dev;
+  struct netarmeth_dev *na_dev;
+  int                   i, j;
+
+  
+  NA_PRINTK("netarmeth_init() entered\n");
+
+  // Initialize the Device Structure.
+
+  // Allocate a device structure.  Device structures are allocated
+  // in Space.c for "built in" drivers.  Do not allocate the private data
+  // area at this time. (why not? --rp)
+
+  dev  = init_etherdev( NULL, sizeof(struct netarmeth_dev));
+  if (dev == NULL) {
+      return (-ENOMEM);
+  }
+  NA_PRINTK("  dev: %X, dev->name: %s\n", (unsigned int) dev, dev->name);
+
+  SET_MODULE_OWNER(dev);
+
+  // Initialize the private data area.
+
+  na_dev = dev->priv;
+  memset(na_dev, 0, sizeof(struct netarmeth_dev));
+
+  // ether_setup initializes the device structure with standard
+  // Ethernet values.
+
+  ether_setup(dev);
+
+  // No need to call request_region.  The Ethernet (and DMA) controller CSR
+  // addresses are hardwired.
+
+  dev->base_addr = NETARM_ETH_MODULE_BASE;
+
+  // Get the MAC address from the Ethernet controller.
+
+  na_get_mac_addr(dev); // this sets dev->dev_addr
+
+  // Specify the exported driver functions.
+
+  dev->open               = netarmeth_open;
+  dev->stop               = netarmeth_close;
+  dev->hard_start_xmit    = netarmeth_start_xmit;
+  dev->get_stats          = netarmeth_get_stats;
+  dev->set_multicast_list = netarmeth_set_multicast_list;
+  dev->tx_timeout         = netarmeth_timeout;
+
+  // Initialize the transmit DMA buffer descriptor.
+
+  NA_PRINTK2("  tx_dma_desc: %X\n", (unsigned int)&na_dev->tx_dma_desc);
+
+  na_dev->tx_dma_desc.src_buf_ptr = 0;
+  na_dev->tx_dma_desc.buf_len = 0;
+  na_dev->tx_dma_desc.stat = 0;
+
+  skb_queue_head_init(&na_dev->tx_skb_queue);
+
+  // Initialize the receive DMA buffer descriptors.  Allocate an skb
+  // (receive buffer) for each descriptor.
+
+  for (i = 0; i < NA_MAX_RX_BUF; i++) {
+    na_dev->rx_skb[i] = dev_alloc_skb(NA_MAX_ETH_FRAME + 2);
+    if (na_dev->rx_skb[i] == NULL) {
+      for (j = 0; j < i; j++) {
+        dev_kfree_skb(na_dev->rx_skb[j]); /* was FREE_READ */
+        na_dev->rx_skb[j] = NULL;
+      }
+      return (-ENOMEM);
+    }    
+  }
+
+  NA_PRINTK2("  rx_dma_desc[0]: %X\n", (unsigned int)&na_dev->rx_dma_desc[0]);
+
+  for (i = 0; i < NA_MAX_RX_BUF; i++) {
+    na_dev->rx_dma_desc[i].src_buf_ptr = 
+      (unsigned long) virt_to_bus(na_dev->rx_skb[i]->data);
+    na_dev->rx_dma_desc[i].buf_len     = NA_MAX_ETH_FRAME + 2;
+    na_dev->rx_dma_desc[i].stat        = 0;
+    // Clear the F bit.
+    na_dev->rx_dma_desc[i].buf_len     &= ~NETARM_DMA_BD1_FULL;
+  }
+  na_dev->rx_dma_desc[NA_MAX_RX_BUF-1].src_buf_ptr |= NETARM_DMA_BD0_WRAP;
+  na_dev->rx_sw_index = 0;
+
+  NA_PRINTK("netarmeth_init: returning 0\n");
+  return (0);
+}
+
+module_init(netarmeth_init);
+MODULE_DESCRIPTION("NET+ARM ethernet driver");
+MODULE_AUTHOR("Rolf Peukert <peukert@imms.de>");
+
diff -urN linux-2.4.29/drivers/net/netarmeth.h linux-2.4.29-uc1/drivers/net/netarmeth.h
--- linux-2.4.29/drivers/net/netarmeth.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/netarmeth.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,132 @@
+/*
+ * drivers/net/netarmeth.h
+ *
+ * Copyright (C) 2000 NETsilicon, Inc.
+ * Copyright (C) 2000 WireSpeed Communications Corporation
+ * Copyright (C) 2001 IMMS gGmbH
+ *
+ * This software is copyrighted by WireSpeed. LICENSEE agrees that
+ * it will not delete this copyright notice, trademarks or protective
+ * notices from any copy made by LICENSEE.
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall WireSpeed
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : Jackie Smith Cashion and David Smith
+ *             Rolf Peukert (Linux Kernel 2.4.x adaption)
+ */
+
+#undef NA_DEBUG
+// #define NA_DEBUG 1
+
+#ifdef NA_DEBUG
+#define NA_PRINTK(fmt, arg...) printk(KERN_INFO fmt, ##arg)
+#else
+#define NA_PRINTK(fmt, arg...)
+#endif
+
+#if (NA_DEBUG > 1)
+#define NA_PRINTK2(fmt, arg...) printk(KERN_INFO fmt, ##arg)
+#else
+#define NA_PRINTK2(fmt, arg...)
+#endif
+
+#if (NA_DEBUG > 2)
+#define NA_PRINTK3(fmt, arg...) printk(KERN_INFO fmt, ##arg)
+#else
+#define NA_PRINTK3(fmt, arg...)
+#endif
+
+// DMA Buffer Descriptor
+
+struct na_dma_buf_desc {
+  unsigned long  src_buf_ptr;  // Source Buffer Pointer (actually bits 0:28)
+  unsigned short buf_len;      // Buffer Length (actually bits 0:14)
+  unsigned short stat;         // Status (bits 16:31)
+};
+
+// Ethernet Receive Status Register in DMA Buffer Descriptor Status Field
+#define NA_RXSTAT_ERR_MASK 0x07E0 // Error Mask
+#define NA_RXSTAT_RXOK     0x2000 // Receive Packet OK
+#define NA_RXSTAT_ROVER    0x0020 // Receive Overflow (Overrun)
+
+// General Purpose Definitions
+
+#define NA_TRUE       1
+#define NA_FALSE      0
+
+#define NA_10MBPS     0
+#define NA_100MBPS    1
+
+#define NA_LEFT  0
+#define NA_RIGHT 1
+
+#define NA_POLYNOMIAL 0x4c11db6L
+
+#define NA_MAX_ETH_FRAME 1526
+#define NA_MAX_ETH_FRAME_ALIGN (NA_MAX_ETH_FRAME + (NA_MAX_ETH_FRAME % 32))
+#define NA_MAX_TX_BUF 1
+//#define NA_MAX_RX_BUF 8
+#define NA_MAX_RX_BUF 24
+
+#define NA_MAX_MCA 64 // Maximum number of multicast addresses in hash table
+
+// MII polling timeout value
+// jiffies = number of 100 Hz ticks (1/100 seconds) since system boot
+#define NA_MII_POLL_BUSY_DELAY 100    // 100 jiffies = 1 second
+
+// MII negotiation timeout value
+#define NA_MII_NEGOTIATE_DELAY 500    // 500 jiffies = 5 seconds
+
+/* Type of the PHY chip attached to the NetARM */
+typedef enum {NA_ENABLE_PHY, NA_LEVEL1_PHY, NA_HOME_PHY} na_phy_type;
+
+// NET+ARM Ethernet Driver Private Data
+
+struct netarmeth_dev {
+  unsigned long           media_100BaseT;             // NA_10MBPS or NA_100MBPS
+  struct na_dma_buf_desc  tx_dma_desc;
+  struct na_dma_buf_desc  rx_dma_desc[NA_MAX_RX_BUF];
+  int                     rx_sw_index;
+  struct sk_buff         *tx_skb;
+  struct sk_buff_head	  tx_skb_queue;
+  struct sk_buff         *rx_skb[NA_MAX_RX_BUF];
+  struct net_device_stats stats;
+  struct timer_list       rx_fifo_timer;
+  int                     rx_fifo_packets;
+  /* Low-level status flags: */
+  unsigned long		  tbusy; /* transmitter busy (must be long for bitops) */
+  volatile unsigned char  start,		/* start an operation	*/
+                          rx_interrupt,		/* receive interrupt arrived */
+                          tx_interrupt;		/* transmit interrupt arrived */
+  na_phy_type             phy_type; /* identified PHY chip */
+};
+
+/*
+ * Translated address IO functions
+ *
+ * IO address has already been translated to a virtual address
+ */
+#define outb_t(v,p)	(*(volatile unsigned char *)(p) = (v))
+#define outw_t(v,p)	(*(volatile unsigned short *)(p) = (v))
+#define outl_t(v,p)	(*(volatile unsigned long *)(p) = (v))
+
+#define inb_t(p) 	 (*(volatile unsigned char *)(p))
+#define inw_t(p) 	(*(volatile unsigned short *)(p))
+#define inl_t(p)	(*(volatile unsigned long *)(p))
+
diff -urN linux-2.4.29/drivers/net/ns7520_eth.c linux-2.4.29-uc1/drivers/net/ns7520_eth.c
--- linux-2.4.29/drivers/net/ns7520_eth.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/ns7520_eth.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,1791 @@
+/***********************************************************************
+ *
+ *  Copyright 2003 by FS Forth-Systeme GmbH.
+ *  All rights reserved.
+ *
+ *  $Id: ns7520_eth.c,v 1.3 2003/08/28 19:17:56 art Exp $
+ *  @Author: Markus Pietrek
+ *  @Descr: The ethernet driver for the NS7520. It is partly based on
+ *          the netarm_eth.c and snull.c and some hints (of yet
+ *          undocumented bugs)
+ *          are taken from NetOS 5.1 sources [3] and NET+50/20M Hardware
+ *          Reference Manual [4]
+ *          Currently it is only tested on UNC20.
+ *          The only PHY supported yet is the LXT971A
+ *          For a list of references [1] and [2] have a look at
+ *          ns7520_eth.h
+ *          Link status changes 10/100 MBit or full/half are not detected
+ *          yet. This requires a timer polling PHY_LXT971_STAT2 for LINKCHG
+ *  @References: NS7520_errata_90000352.pdf [5]
+ *  
+ ***********************************************************************/
+/***********************************************************************
+ *
+ *  @History:
+ *     2003/08/28 : Adapted version by Art Shipkowski <art@videon-central.com>
+ *                  released to uClinux-dist sources.
+ *     2003/06/16 : fixed a buffer overrun in interrupt rx
+ *     2003/06/05 : fixed some minor issues with the order of multicast
+ *                  initialization, comments and names. As of a bug of the chip
+ *                  itself, multicasts are not filtered by the NS7520 :-(
+ *     2003/05/20 : BugID 200: ethernet: IRQ31 is locking the system 
+ *                  ethernet transmit lock on underrun fixed
+ *     2003/04/25 : BugID 153: too many packet looses on ping -f
+ *                  fixed race condition transmit, use IDONE DMA Interrupt
+ *                  correctly for transmit and not any longer for receive.
+ ************************************************************************/
+
+#include <linux/module.h>	// MODULE_AUTHOR
+#include <linux/init.h>		// module_init
+#include <linux/sched.h>	// request_irq
+#include <linux/netdevice.h>    // net_device
+#include <linux/etherdevice.h>  // eth_type_trans
+#include <linux/ioport.h>	// request_region
+#include <linux/timer.h>	// add_timer
+
+#include <asm/irq.h>		// IRQ_*
+#include <asm/delay.h>		// udelay
+#include <asm/memory.h>  // virt_to_bus and friends
+#if 0
+#include <asm/arch/netarm_dma.h>    // netarm_dmaChannelEnable
+#include <asm/arch/modnet_eeprom.h> // NaNvramReadEthParams
+#else
+#include <asm/arch/netarm_registers.h>
+#endif
+#include "ns7520_eth.h"		    // all the register stuff
+
+#define DEBUG_INIT		1
+#define DEBUG_MAJOR		2
+#define DEBUG_MINOR		3
+#define DEBUG_INTERRUPT		4
+#define DEBUG_ETH		5
+#define DEBUG_MII		6
+#define DEBUG_MII_LOW		7
+#define DEBUG_ALL		DEBUG_ETH
+
+//#define DEBUG_VERBOSE		DEBUG_MINOR
+
+#ifdef DEBUG_VERBOSE
+# define DEBUG_ARGS( n, args... ) \
+	if( n <= DEBUG_VERBOSE ) \
+		printk( KERN_INFO __FILE__ ": " args )
+# define DEBUG_FN( n ) \
+	if( n <= DEBUG_VERBOSE ) \
+		printk( KERN_INFO "%s:line %d\n", __FUNCTION__,__LINE__ );
+# define ASSERT(expr, func) \
+	if(!(expr)) { \
+        	printk( KERN_ERR "Assertion failed! %s:%s:line %d %s\n", \
+        	__FILE__,__FUNCTION__,__LINE__,(#expr));  \
+        	func }
+#else
+# define DEBUG_ARGS( n, expr, args... )
+# define DEBUG_FN( n )
+# define ASSERT(expr, func)
+#endif // DEBUG
+
+// use default FS Forth-Systeme GmbH MAC address
+#define NS7520_DEFAULT_MAC	  { 0x00, 0x04, 0xf3, 0x00, 0x06, 0x35 }
+
+#define NS7520_ETH_REGION1_START  NS7520_ETH_MODULE_BASE + NS7520_ETH_EGCR
+#define NS7520_ETH_REGION1_LEN	  (NS7520_ETH_ERSR - NS7520_ETH_EGCR + 4 )
+#define NS7520_ETH_REGION2_START  NS7520_ETH_MODULE_BASE + NS7520_ETH_MAC1 
+#define NS7520_ETH_REGION2_LEN    (NS7520_ETH_SA3 - NS7520_ETH_MAC1 + 4 )
+#define NS7520_ETH_REGION3_START  NS7520_ETH_MODULE_BASE + NS7520_ETH_SAFR
+#define NS7520_ETH_REGION3_LEN	  4
+#define NS7520_ETH_REGION4_START  NS7520_ETH_MODULE_BASE + NS7520_ETH_HT1
+#define NS7520_ETH_REGION4_LEN	  (NS7520_ETH_HT4 - NS7520_ETH_HT1 + 4 )
+
+#define NS7520_TIMEOUT		  5*HZ // in jiffies
+#define NS7520_MII_NEG_DELAY      5*HZ  // in jiffies
+
+#define NS7520_DRIVER_NAME	  "ns7520_eth"
+
+#define NS7520_RX_DESC		  24 // number of receive buffer descriptors
+#define NS7520_ETH_FRAME_LEN	  1520 // NS7520 accepts 1520 byte packets
+				       // instead of 1518
+
+#define NS7520_POLYNOMIAL	  0x4c11db6L // taken from [1] p183
+#define NS7520_LEFT		  0          // left rotation
+#define NS7520_RIGHT		  1          // right rotation
+
+/* ns7520_private contains private data to this module */
+struct ns7520_private_t
+{
+	netarm_dmaBufferDescFb_t aRxDmaBuffer[ NS7520_RX_DESC ]; // receive
+								// buffer desc 
+	netarm_dmaBufferDescFb_t txDmaBuffer; // transmit buffer desc
+
+	struct net_device_stats stats; // the ethernet interface statistics
+	struct sk_buff* pTxSkb; // receive packet buffers
+	struct sk_buff* apRxSkb[ NS7520_RX_DESC ]; // receive packet buffers
+	spinlock_t lock;	// locking for multiple processes
+
+	struct timer_list rxLockupTimer; // timer for receive lockups
+	unsigned long rxFifoPackets; // packets since last rxLockupTimer event
+	volatile unsigned char rxLockupTimerDisable;  // if 1, rxLockupTimer
+                                                      // doesn't refresh
+	unsigned short uiLastLinkStatus; // stores the last detected link
+                                         // information 10/100 half/full auto
+	                                 // 0xff is empty
+	unsigned int unLastRxDmaDescIndex; // last dma desc index used
+};
+
+static unsigned char aucMACAddr[ ETH_ALEN ] = NS7520_DEFAULT_MAC;
+
+static PhyType PhyDetected = PHY_NONE;
+static unsigned int nPhyMaxMdioClock = 250000; // defaults to 2.5 MHz
+
+static int  ns7520_init_module( void );
+static void ns7520_cleanup_module( void );
+static int  ns7520_init_device( struct net_device* pDev );
+static int  ns7520_open( struct net_device* pDev );
+static int  ns7520_release( struct net_device* pDev );
+static int  ns7520_start_xmit( struct sk_buff* pSkb, struct net_device* pDev );
+static struct net_device_stats* ns7520_stats( struct net_device* pDev );
+static void ns7520_set_multicast_list( struct net_device* pDev );
+static int  ns7520_set_mac_address( struct net_device* pDev, void *pMacAddr);
+static void ns7520_rx_interrupt( int nIrq, void* vpDev_id,struct pt_regs* pRegs);
+static void ns7520_tx_interrupt( int nIrq, void* vpDev_id,struct pt_regs* pRegs);
+static void ns7520_irqs_disable( void );
+static void ns7520_irqs_enable( void );
+static void netarm_dma_disable( char cMode );
+static void netarm_dma_enable( char cMode, struct net_device* pDev  );
+static char ns7520_eth_reset( struct net_device* pDev );
+static void ns7520_eth_enable( struct net_device* pDev );
+static void ns7520_rx_fifo_reset( struct net_device* pDev );
+static void ns7520_tx_fifo_reset( struct net_device* pDev );
+static void ns7520_rx_lockup_detect( unsigned long ulDev );
+static void ns7520_rx_lockup_timer_enable( struct net_device* pDev );
+static void ns7520_rx_lockup_timer_disable( struct net_device* pDev );
+static void ns7520_tx_timeout( struct net_device* pDev );
+static void ns7520_link_force( struct net_device* pDev );
+static void ns7520_link_auto_negotiate( struct net_device* pDev );
+static void ns7520_link_update_egcr( struct net_device* pDev );
+static void ns7520_link_print_changed( struct net_device* pDev );
+
+// the PHY stuff
+
+static char ns7520_mii_identify_phy( void );
+static unsigned short ns7520_mii_read( unsigned short uiRegister );
+static void ns7520_mii_write( unsigned short uiRegister, unsigned short uiData );
+static unsigned int ns7520_mii_get_clock_divisor( unsigned int unMaxMDIOClk );
+static unsigned int ns7520_mii_poll_busy( void );
+
+// the multicast stuff
+
+static void ns7520_load_mca_hash_table( struct dev_mc_list* pMcList );
+static void ns7520_set_hash_bit( unsigned char* pucHashTable, int nBit );
+static int ns7520_calculate_hash_bit( unsigned char* pucMac );
+static unsigned short ns7520_rotate( unsigned short uiReg,
+				     int nDirection,
+				     int nBits );
+
+// declared later due to ns7520_init_device
+struct net_device ns7520_devs =
+{
+    name: "eth%d",		// ethernet device
+    init: ns7520_init_device,	// init function
+};
+
+
+/***********************************************************************
+ * @Function: ns7520_init_device
+ * @Return: 0 or 1 on failure
+ * @Descr: configures and registers the ethernet driver in the stack
+ ***********************************************************************/
+
+static int ns7520_init_device( struct net_device* pDev )
+{
+	DEBUG_FN( DEBUG_INIT );
+
+	ether_setup( pDev ); // assign default values
+
+	pDev->open              = ns7520_open;
+	pDev->stop              = ns7520_release;
+	pDev->hard_start_xmit   = ns7520_start_xmit;
+	pDev->get_stats         = ns7520_stats;
+	pDev->set_multicast_list= ns7520_set_multicast_list;
+	pDev->set_mac_address   = ns7520_set_mac_address;
+	pDev->tx_timeout        = ns7520_tx_timeout;
+	pDev->watchdog_timeo    = NS7520_TIMEOUT;
+
+	pDev->base_addr 	= NS7520_ETH_MODULE_BASE;
+	pDev->features		= NETIF_F_HW_CSUM;
+	pDev->flags		= IFF_MULTICAST | IFF_BROADCAST;
+
+	SET_MODULE_OWNER( pDev );
+
+	spin_lock_init( & ((struct ns7520_private_t *) pDev->priv)->lock );
+
+	return 0;
+}
+
+
+/***********************************************************************
+ * @Function: ns7520_open
+ * @Return: 0 on success otherwise error
+ * @Descr: reserves memory, ports and interrupts, initializes ethernet
+ *         driver
+ ***********************************************************************/
+
+static int ns7520_open( struct net_device* pDev )
+{
+	int nRes = -EBUSY;
+	struct ns7520_private_t* pPriv;
+	int i;
+	
+	DEBUG_FN( DEBUG_INIT );
+
+	MOD_INC_USE_COUNT;
+
+	// request memory regions & interrupts
+
+	if( request_region( NS7520_ETH_REGION1_START,
+			    NS7520_ETH_REGION1_LEN,
+			    NS7520_DRIVER_NAME ) == NULL )
+	    goto error_region1;
+	if( request_region( NS7520_ETH_REGION2_START,
+			    NS7520_ETH_REGION2_LEN,
+			    NS7520_DRIVER_NAME ) == NULL )
+	    goto error_region2;
+	if( request_region( NS7520_ETH_REGION3_START,
+			    NS7520_ETH_REGION3_LEN,
+			    NS7520_DRIVER_NAME ) == NULL )
+	    goto error_region3;
+	if( request_region( NS7520_ETH_REGION4_START,
+			    NS7520_ETH_REGION4_LEN,
+			    NS7520_DRIVER_NAME ) == NULL )
+	    goto error_region4;
+	if( request_irq( IRQ_DMA01, 
+			 ns7520_rx_interrupt,
+			 SA_SAMPLE_RANDOM,
+			 NS7520_DRIVER_NAME " receive",
+			 pDev ) )
+	    goto error_irq_rx;
+	if( request_irq( IRQ_DMA02, 
+			 ns7520_tx_interrupt,
+			 SA_SAMPLE_RANDOM,
+			 NS7520_DRIVER_NAME " transmit",
+			 pDev ) )
+	    goto error_irq_tx;
+
+	// allocate private field
+	pPriv = pDev->priv = kmalloc(sizeof(struct ns7520_private_t),GFP_KERNEL);
+	if( pPriv == NULL )
+	{
+	    nRes = -ENOMEM;
+	    goto error_nomem;
+	}
+	
+	memset( pPriv, 0, sizeof(struct ns7520_private_t) );
+	// just to be sure
+	ASSERT( NULL == 0, return -ENOMEM; );
+	
+	// preallocate any receive skb buffers for DMA transfer
+	// !we receive the rx interrupt after one packet has been copied!
+	for( i = 0; i < NS7520_RX_DESC; i++ )
+	{
+	    pPriv->apRxSkb[ i ] = dev_alloc_skb( NS7520_ETH_FRAME_LEN + 2 );
+	    if( pPriv->apRxSkb[ i ] == NULL )
+	    {
+		nRes = -ENOMEM;
+		goto error;
+	    }
+	    pPriv->apRxSkb[ i ]->dev = pDev;
+	}
+
+	// all ok, continue with hardware initialization
+	// from here we have access to ports
+
+	memcpy( pDev->dev_addr, aucMACAddr, ETH_ALEN );
+
+
+	ns7520_irqs_disable();
+	netarm_dma_disable( 3 );
+
+	if( !ns7520_eth_reset( pDev ) )
+	{
+	    nRes = -ENODEV;
+	    goto error;
+	}
+
+	ns7520_eth_enable( pDev );
+	ns7520_irqs_enable();
+	ns7520_rx_lockup_timer_enable( pDev );
+	
+	// assign hardware address
+
+	*get_eth_reg_addr(NS7520_ETH_SA1)=pDev->dev_addr[5]<<8|pDev->dev_addr[4];
+	*get_eth_reg_addr(NS7520_ETH_SA2)=pDev->dev_addr[3]<<8|pDev->dev_addr[2];
+	*get_eth_reg_addr(NS7520_ETH_SA3)=pDev->dev_addr[1]<<8|pDev->dev_addr[0];
+
+	netif_start_queue( pDev );
+
+	return 0;
+
+	// release IRQ
+  error:
+	if( pPriv != NULL )
+	{
+	    // free skb buffers
+	    for( i = 0; i < NS7520_RX_DESC; i++ )
+	    {
+		if( pPriv->apRxSkb[ i ] != NULL )
+		    dev_kfree_skb( pPriv->apRxSkb[ i ] );
+		else
+		    // no more buffers allocated
+		    break;
+	    }
+	    kfree( pPriv );
+	}
+  error_nomem:
+	free_irq( IRQ_DMA02, NULL );
+  error_irq_tx:
+	free_irq( IRQ_DMA01, NULL );
+  error_irq_rx:
+	release_region( NS7520_ETH_REGION4_START, NS7520_ETH_REGION4_LEN );
+  error_region4:
+	release_region( NS7520_ETH_REGION3_START, NS7520_ETH_REGION3_LEN );
+  error_region3:
+	release_region( NS7520_ETH_REGION2_START, NS7520_ETH_REGION2_LEN );
+  error_region2:
+	release_region( NS7520_ETH_REGION1_START, NS7520_ETH_REGION1_LEN );
+  error_region1:
+	MOD_DEC_USE_COUNT;
+	return nRes;
+}
+
+
+/***********************************************************************
+ * @Function: ns7520_release
+ * @Return: 0 on success otherwise error
+ * @Descr: releases memory, ports and interrupts. Disables chip
+ ***********************************************************************/
+
+static int ns7520_release( struct net_device* pDev )
+{
+	struct ns7520_private_t* pPriv = (struct ns7520_private_t*) pDev->priv;
+	int i;
+	
+	DEBUG_FN( DEBUG_INIT );
+
+	netif_stop_queue( pDev ); // can't transmit any more
+
+	// disable hardware
+
+	ns7520_irqs_disable();
+	netarm_dma_disable( 3 );
+
+	// clear outstanding interrupts
+	*get_dma_reg_addr( NETARM_DMA_CHANNEL_1A, NETARM_DMA_STATUS ) =
+	    NETARM_DMA_STATUS_IP_MA;
+	*get_dma_reg_addr( NETARM_DMA_CHANNEL_2, NETARM_DMA_STATUS ) =
+	    NETARM_DMA_STATUS_IP_MA;
+
+	// disable receive and txmit
+
+	*get_eth_reg_addr( NS7520_ETH_EGCR ) &= ~(NS7520_ETH_EGCR_ERX |
+						  NS7520_ETH_EGCR_ERXDMA |
+						  NS7520_ETH_EGCR_ETX |
+						  NS7520_ETH_EGCR_ETXDMA );
+
+	*get_eth_reg_addr( NS7520_ETH_MAC1 ) &= ~NS7520_ETH_MAC1_RXEN;
+
+	// disable timer
+	ns7520_rx_lockup_timer_disable( pDev );
+	
+	// free ressources
+	// interrupts and regions
+
+	free_irq( IRQ_DMA02, pDev );
+	free_irq( IRQ_DMA01, pDev );
+	release_region( NS7520_ETH_REGION4_START, NS7520_ETH_REGION4_LEN );
+	release_region( NS7520_ETH_REGION3_START, NS7520_ETH_REGION3_LEN );
+	release_region( NS7520_ETH_REGION2_START, NS7520_ETH_REGION2_LEN );
+	release_region( NS7520_ETH_REGION1_START, NS7520_ETH_REGION1_LEN );
+
+	// DMA buffers
+	for( i = 0; i < NS7520_RX_DESC; i++ )
+	    dev_kfree_skb( pPriv->apRxSkb[ i ] );
+
+	if( pPriv->pTxSkb != NULL )
+	{
+	    // we won't transmit it any longer
+	    dev_kfree_skb( pPriv->pTxSkb );
+	    pPriv->pTxSkb = NULL;
+	}
+	
+	kfree( pPriv );
+
+
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+
+/***********************************************************************
+ * @Function: ns7520_start_xmit
+ * @Return: 0 if packet assigned for transmission otherwise error
+ * @Descr: prepares and send a packet to hardware transmit. Only one DMA
+ *         buffer desc is used.
+ ***********************************************************************/
+
+static int ns7520_start_xmit( struct sk_buff* pSkb, struct net_device* pDev )
+{
+	int nLen;
+	struct ns7520_private_t* pPriv = (struct ns7520_private_t *) pDev->priv;
+	unsigned long ulFlags;
+
+	DEBUG_FN( DEBUG_INTERRUPT );
+	
+        spin_lock_irqsave( &pPriv->lock, ulFlags );
+
+	nLen = pSkb->len < ETH_ZLEN ? ETH_ZLEN : pSkb->len;
+	pDev->trans_start = jiffies; // save the timestamp
+	
+	// Remember the skb, so we can free it at interrupt time
+	// in case the last one has not been freed, give warning
+	ASSERT( pPriv->pTxSkb == NULL, ; );
+	pPriv->pTxSkb = pSkb;
+
+	// set up DMA buffer descriptor
+	pPriv->txDmaBuffer.l.bits.srcPtr = (unsigned int)virt_to_bus(pSkb->data);
+	pPriv->txDmaBuffer.h.bits.bufLen = pSkb->len;
+	pPriv->txDmaBuffer.h.bits.full   = 1;
+
+	// packet is transmitted anywhere later, stop queue until then
+	netif_stop_queue( pDev );
+
+	// retrigger DMA transfer by clearing NRIP
+	*get_dma_reg_addr( NETARM_DMA_CHANNEL_2, NETARM_DMA_STATUS ) |= 
+	    NETARM_DMA_STATUS_IP_NR;
+
+	spin_unlock_irqrestore( &pPriv->lock, ulFlags );
+
+	return 0;
+}
+
+
+/***********************************************************************
+ * @Function: ns7520_stats
+ * @Return: a pointer to the device statistics
+ * @Descr: the device receive, transmit and error statistics
+ ***********************************************************************/
+
+static struct net_device_stats* ns7520_stats( struct net_device* pDev )
+{
+	struct ns7520_private_t* pPriv = (struct ns7520_private_t*) pDev->priv;
+	
+	DEBUG_FN( DEBUG_MINOR );
+	
+	return &pPriv->stats;
+}
+
+
+/***********************************************************************
+ * @Function: ns7520_set_multicast_list
+ * @Return: nothing
+ * @Descr: updates the multicast list and enabled/disables promiscuous
+ *         mode
+ *         Always accept broadcasts addresses
+ ***********************************************************************/
+
+static void ns7520_set_multicast_list( struct net_device* pDev )
+{
+	unsigned int unSAFR;
+
+    	DEBUG_FN( DEBUG_MINOR );
+
+	unSAFR = *get_eth_reg_addr( NS7520_ETH_SAFR );
+
+	// disable all multicast modes
+	unSAFR &= ~( NS7520_ETH_SAFR_PRO |
+		     NS7520_ETH_SAFR_PRM |
+		     NS7520_ETH_SAFR_PRA );
+
+	if( pDev->flags & IFF_PROMISC )
+	{
+	    DEBUG_ARGS( DEBUG_MINOR, "Promiscuous mode\n" );
+	    *get_eth_reg_addr( NS7520_ETH_SAFR ) = unSAFR | NS7520_ETH_SAFR_PRO;
+	    return;
+	} else if( pDev->flags & IFF_ALLMULTI )	{
+	    DEBUG_ARGS( DEBUG_MINOR, "Accept all multicast packets\n" );
+	    *get_eth_reg_addr( NS7520_ETH_SAFR ) = unSAFR |
+		NS7520_ETH_SAFR_BROAD |
+		NS7520_ETH_SAFR_PRM;
+	    return;
+	} else if( !(pDev->flags & IFF_MULTICAST) ) {
+	    // TODO: check if broadcasts will be delivered correctly or if they
+	    // need multicasts to be enabled
+	    DEBUG_ARGS( DEBUG_MINOR,
+			"Accept only direct addressed and broadcast packets\n" );
+	    *get_eth_reg_addr( NS7520_ETH_SAFR ) = unSAFR |
+		NS7520_ETH_SAFR_BROAD;
+	    return;
+	}
+
+	DEBUG_ARGS( DEBUG_MINOR,
+		    "Accept multicast list\n" );
+
+	// store multicast list of kernel into chip
+	ns7520_load_mca_hash_table( pDev->mc_list );
+
+	*get_eth_reg_addr( NS7520_ETH_SAFR ) = unSAFR |
+	    NS7520_ETH_SAFR_BROAD |
+	    NS7520_ETH_SAFR_PRA;
+
+}
+
+/***********************************************************************
+ * @Function: ns7520_set_mac_address
+ * @Return: nothing
+ * @Descr: sets the mac address based upon what we are told to set it to
+ ***********************************************************************/
+static int 
+ns7520_set_mac_address(struct net_device* pDev, void *pMacAddr)
+{
+	int i;
+	struct sockaddr *addr=pMacAddr;
+
+	if (netif_running(pDev))
+		return -EBUSY;
+ 
+	/* Set the device copy of the Ethernet address
+	*/
+	memcpy(pDev->dev_addr, addr->sa_data, ETH_ALEN);
+      
+	/* Set our copy of the Ethernet address 
+	*/
+	for (i = 0; i < ETH_ALEN; i++)
+	{
+		aucMACAddr[i] = pDev->dev_addr[i];
+	}
+
+	/* Set station address.
+	*/
+	*get_eth_reg_addr(NS7520_ETH_SA1)=pDev->dev_addr[5]<<8|pDev->dev_addr[4];
+	*get_eth_reg_addr(NS7520_ETH_SA2)=pDev->dev_addr[3]<<8|pDev->dev_addr[2];
+	*get_eth_reg_addr(NS7520_ETH_SA3)=pDev->dev_addr[1]<<8|pDev->dev_addr[0];
+  
+	return 0;
+}
+/***********************************************************************
+ * @Function: ns7520_rx_interrupt
+ * @Return: nothing
+ * @Descr: DMA receive hardware interrupt handler, runs with interrupts
+ *         enabled
+ ***********************************************************************/
+
+static void ns7520_rx_interrupt( int nIrq, void* vpDev_id, struct pt_regs* pRegs)
+{
+	struct net_device* pDev = (struct net_device*) vpDev_id;
+	struct ns7520_private_t* pPriv;
+	unsigned int unIndex;
+	unsigned int unDmaStatus;
+	unsigned int unCurrentDmaDescIndex;
+	
+	DEBUG_FN( DEBUG_INTERRUPT );
+
+	ASSERT( pDev != NULL, return; ); // a little bit paranoid here
+
+	// lock device
+	pPriv = (struct ns7520_private_t*) pDev->priv;
+	spin_lock( &pPriv->lock );
+
+	// now handle hardware request
+
+	unDmaStatus = *get_dma_reg_addr(NETARM_DMA_CHANNEL_1A,NETARM_DMA_STATUS);
+
+	// acknowledge pending interrupts, IE_ are cleared on interrupt
+	// interrupt handler
+	*get_dma_reg_addr( NETARM_DMA_CHANNEL_1A, NETARM_DMA_STATUS ) =
+	    unDmaStatus | NETARM_DMA_STATUS_IP_MA |
+	    NETARM_DMA_STATUS_IE_NC |
+	    NETARM_DMA_STATUS_IE_EC |
+	    NETARM_DMA_STATUS_IE_NR |
+	    NETARM_DMA_STATUS_IE_CA;
+
+	// now check the status fields
+	// IP_NR may be called even if no interrupt enable is set
+	if( (unDmaStatus &
+	     (NETARM_DMA_STATUS_IP_EC |
+	      NETARM_DMA_STATUS_IP_CA |
+	      NETARM_DMA_STATUS_IP_PC) ) ||
+	    ((unDmaStatus & (NETARM_DMA_STATUS_IP_NR|NETARM_DMA_STATUS_IE_NR ))==
+	     (NETARM_DMA_STATUS_IE_NR | NETARM_DMA_STATUS_IP_NR)))
+	{
+	    printk( KERN_WARNING NS7520_DRIVER_NAME
+		    ": error interrupt, status is 0x%x\n", unDmaStatus );
+	}
+
+	// check for full buffer and give it to kernel
+	// last descriptor modified by DMA control so we don't have to check all
+	unCurrentDmaDescIndex = ((*get_dma_reg_addr( NETARM_DMA_CHANNEL_1A,
+						     NETARM_DMA_CONTROL )) &
+				 NETARM_DMA_CONTROL_INDEX ) / 8;
+	ASSERT( unCurrentDmaDescIndex < NS7520_RX_DESC, return; ); // skip
+								   // package
+	unIndex = pPriv->unLastRxDmaDescIndex;
+
+	do
+	{
+	    if( pPriv->aRxDmaBuffer[ unIndex ].h.bits.full )
+	    {
+		if( pPriv->aRxDmaBuffer[unIndex].h.bits.status & 
+		    NS7520_ETH_ERSR_RXOK )
+		{
+		    // update statistics
+		    pPriv->stats.rx_packets++;
+		    pPriv->stats.rx_bytes +=
+			pPriv->aRxDmaBuffer[ unIndex ].h.bits.bufLen;
+
+		    // I guess the user would be glad to get this packet, so
+		    // give it 
+        if (pPriv->apRxSkb[ unIndex ]->data_len)
+        {
+          printk("[%d]skb->data_len bad value %d\n", unIndex, pPriv->apRxSkb[ unIndex ]->data_len);
+        }
+		    skb_put( pPriv->apRxSkb[ unIndex ],
+			     pPriv->aRxDmaBuffer[ unIndex ].h.bits.bufLen - 4 );
+		    pPriv->apRxSkb[ unIndex ]->protocol =
+			eth_type_trans( pPriv->apRxSkb[ unIndex ],
+				    pDev );
+		    pPriv->apRxSkb[ unIndex ]->ip_summed = CHECKSUM_UNNECESSARY;
+	    
+		    skb_reserve( pPriv->apRxSkb[ unIndex ], 2 ); // align 16byte
+		    netif_rx( pPriv->apRxSkb[ unIndex ] );
+
+		    // allocate new skb buffer as control of old one is given to
+		    // kernel and reset dma buffer
+		    pPriv->apRxSkb[unIndex] = dev_alloc_skb(
+			NS7520_ETH_FRAME_LEN + 2 );
+		    if( pPriv->apRxSkb[ unIndex ] == NULL )
+			// no memory is serious enough to panic
+			panic( NS7520_DRIVER_NAME
+			       ": couldn't allocate next skb buffer\n" );
+		    pPriv->apRxSkb[ unIndex ]->dev = pDev;
+
+		    pPriv->aRxDmaBuffer[ unIndex ].h.bits.full = 0;
+		    // buffer size has been set to read bytes by dma controller
+		    pPriv->aRxDmaBuffer[unIndex].h.bits.bufLen =
+			NS7520_ETH_FRAME_LEN;
+		    pPriv->aRxDmaBuffer[ unIndex ].h.bits.status = 0;
+		    // set new buffer address
+		    pPriv->aRxDmaBuffer[ unIndex ].l.bits.srcPtr =
+			(unsigned int)virt_to_bus(pPriv->apRxSkb[unIndex]->data);
+		} else {
+		    pPriv->stats.rx_errors++;
+		    if( pPriv->aRxDmaBuffer[ unIndex ].h.bits.status &
+			(NS7520_ETH_ERSR_RXCRC |
+			 NS7520_ETH_ERSR_RXDR |
+			 NS7520_ETH_ERSR_RXCV ) )
+			pPriv->stats.rx_crc_errors++;
+		    
+		    if( pPriv->aRxDmaBuffer[ unIndex ].h.bits.status &
+			(NS7520_ETH_ERSR_RXLNG |
+			 NS7520_ETH_ERSR_RXSHT) )
+			pPriv->stats.rx_frame_errors++;
+		    
+		    if( pPriv->aRxDmaBuffer[ unIndex ].h.bits.status &
+			NS7520_ETH_ERSR_ROVER )
+		    {
+			DEBUG_ARGS( DEBUG_MAJOR,
+				    "Receive Overrun, resetting FIFO\n" );
+			// a reset of RX FIFO is still necessary with NS7520
+			ns7520_rx_fifo_reset( pDev );
+		    }
+
+		    if( pPriv->aRxDmaBuffer[ unIndex ].h.bits.full )
+		    {
+			// reset to default values in case an error happened
+			// and the full bit has been set already by DMA,
+			// if not unset, it would the DMA controller hangs at
+			// this descriptor => "IRQ31 disabled"
+			pPriv->aRxDmaBuffer[ unIndex ].h.bits.bufLen =
+			    NS7520_ETH_FRAME_LEN;
+			pPriv->aRxDmaBuffer[ unIndex ].h.bits.status = 0;
+			pPriv->aRxDmaBuffer[ unIndex ].h.bits.full = 0;
+		    }
+		}
+	    }
+	    unIndex++;
+	    if( unIndex >= NS7520_RX_DESC )
+		// wrap to beginning of desc List
+		unIndex = 0;
+	} while( unIndex != unCurrentDmaDescIndex );
+
+	pPriv->unLastRxDmaDescIndex = unIndex;
+	
+	// unlock device
+	spin_unlock( &pPriv->lock );
+}
+
+/***********************************************************************
+ * @Function: ns7520_tx_interrupt
+ * @Return: nothing
+ * @Descr: DMA transmit hardware interrupt handler, runs with interrupts
+ *         enabled
+ ***********************************************************************/
+
+static void ns7520_tx_interrupt( int nIrq, void* vpDev_id, struct pt_regs* pRegs)
+{
+	struct net_device* pDev = (struct net_device*) vpDev_id;
+	struct ns7520_private_t* pPriv;
+	unsigned int unDmaStatus;
+	unsigned int unTxStatus;
+	char cFreeSkb = 0;
+
+	DEBUG_FN( DEBUG_INTERRUPT );
+
+	ASSERT( pDev != NULL, return; ); // a little bit paranoid here
+
+	// lock device
+	pPriv = (struct ns7520_private_t*) pDev->priv;
+	spin_lock( &pPriv->lock );
+
+	// now handle hardware request
+	unDmaStatus = *get_dma_reg_addr(NETARM_DMA_CHANNEL_2,NETARM_DMA_STATUS);
+	unTxStatus = *get_eth_reg_addr( NS7520_ETH_ETSR );
+
+	// acknowledge pending interrupts
+	*get_dma_reg_addr( NETARM_DMA_CHANNEL_2, NETARM_DMA_STATUS ) =
+	    unDmaStatus | NETARM_DMA_STATUS_IP_MA;
+
+	// now check the status fields
+	// IP_NR may be called even if no interrupt enable is set
+	if( (unDmaStatus &
+	     (NETARM_DMA_STATUS_IP_EC |
+	      NETARM_DMA_STATUS_IP_CA |
+	      NETARM_DMA_STATUS_IP_PC) ) ||
+	    ((unDmaStatus & (NETARM_DMA_STATUS_IP_NR|NETARM_DMA_STATUS_IE_NR ))==
+	     (NETARM_DMA_STATUS_IE_NR | NETARM_DMA_STATUS_IP_NR)))
+	{
+	    DEBUG_ARGS( DEBUG_MINOR,
+			"error interrupt, status is 0x%x\n", unDmaStatus );
+	}
+
+	if( (unTxStatus & NS7520_ETH_ETSR_TXOK) == NS7520_ETH_ETSR_TXOK )
+	{
+	    pPriv->stats.tx_packets++;
+	    pPriv->stats.tx_bytes +=  pPriv->pTxSkb->len;
+	    cFreeSkb = 1;
+	} else if( unTxStatus & ( NS7520_ETH_ETSR_TXAL |
+				  NS7520_ETH_ETSR_TXAED |
+				  NS7520_ETH_ETSR_TXAEC |
+				  NS7520_ETH_ETSR_TXAUR |
+				  NS7520_ETH_ETSR_TXAJ |
+				  NS7520_ETH_ETSR_TXDEF |
+				  NS7520_ETH_ETSR_TXCRC |
+				  NS7520_ETH_ETSR_TXCOLC ) )
+	{
+	    char cRetransmit = 1;
+
+	    // the packets have been flushed and not been transmitted, so
+	    // retrigger them
+	    pPriv->stats.tx_errors++;
+	    if( unTxStatus & (NS7520_ETH_ETSR_TXAL |
+			      NS7520_ETH_ETSR_TXAEC ) )
+		pPriv->stats.collisions++;
+	    else if( unTxStatus & NS7520_ETH_ETSR_TXAED )
+		pPriv->stats.tx_carrier_errors++;
+	    else if( unTxStatus & NS7520_ETH_ETSR_TXDEF )
+	    {
+		pPriv->stats.tx_carrier_errors++;
+		cRetransmit = 0;
+		cFreeSkb = 1;
+	    }
+
+	    if( (unTxStatus & (NS7520_ETH_ETSR_TXAUR | NS7520_ETH_ETSR_TXCOLC))&&
+		pPriv->txDmaBuffer.h.bits.full == 1 &&
+		!unDmaStatus )
+	    {
+		// see [5] ethernet transmit considerations
+		DEBUG_ARGS( DEBUG_MAJOR,
+			    "aborted transmit" );
+		ns7520_tx_fifo_reset( pDev );
+	    }
+	    
+	    if( unTxStatus & (NS7520_ETH_ETSR_TXAJ |
+			      NS7520_ETH_ETSR_TXCRC ) )
+	    {
+		DEBUG_ARGS( DEBUG_MINOR,
+			    "packet tx skipped, status is 0x%x\n",
+			    unTxStatus );
+		
+		cRetransmit = 0;
+		cFreeSkb = 1;
+		pPriv->stats.tx_aborted_errors++;
+	    }
+
+	    if( cRetransmit )
+	    {
+		// the DMA has already transferred the data into the Ethernet
+		// FIFO and cleared the full bit.
+		pPriv->txDmaBuffer.h.bits.full = 1;
+		
+		// retrigger DMA transfer by clearing NRIP
+		*get_dma_reg_addr( NETARM_DMA_CHANNEL_2, NETARM_DMA_STATUS ) |= 
+		    NETARM_DMA_STATUS_IP_NR;
+	    }
+	} else
+	    DEBUG_ARGS( DEBUG_MAJOR,
+			"unknown error, status is 0x%x\n",
+			unTxStatus );
+
+	if( cFreeSkb )
+	{
+	    // data has been send, free buffer
+	    dev_kfree_skb_irq( pPriv->pTxSkb );
+	    pPriv->pTxSkb = NULL;
+	    // next packet can be send
+	    netif_wake_queue( pDev );
+	}
+	
+	// unlock device
+	spin_unlock( &pPriv->lock );
+}
+
+static void ns7520_irqs_disable( void )
+{
+	DEBUG_FN( DEBUG_ETH );
+
+	disable_irq( IRQ_DMA01 );
+	disable_irq( IRQ_DMA02 );
+}
+
+static void ns7520_irqs_enable( void )
+{
+	DEBUG_FN( DEBUG_ETH );
+
+	enable_irq( IRQ_DMA01 );
+	enable_irq( IRQ_DMA02 );
+}
+
+/***********************************************************************
+ * @Function: netarm_dma_disable
+ * @Return: nothing
+ * @Descr: disable the DMA channels and clear pending interrupts
+ *         bit 0 of cMode means enable transmit, bit 1 of cMode means enable
+ *         receive
+ ***********************************************************************/
+
+static void netarm_dma_disable( char cMode )
+{
+	DEBUG_FN( DEBUG_MINOR );
+
+	if( ( cMode & 2 ) == 2 )
+	{
+	    netarm_dmaChannelDisable( NETARM_DMA_CHANNEL_1A );
+	    netarm_dmaChannelDisable( NETARM_DMA_CHANNEL_1B );
+	    netarm_dmaChannelDisable( NETARM_DMA_CHANNEL_1C );
+	    netarm_dmaChannelDisable( NETARM_DMA_CHANNEL_1D );
+	}
+	
+	if( ( cMode & 1 ) == 1 )
+	    netarm_dmaChannelDisable( NETARM_DMA_CHANNEL_2 );
+}
+
+/***********************************************************************
+ * @Function: netarm_dma_enable
+ * @Return: nothing
+ * @Descr: enables the DMA channels, clears the interrupts and
+ *         configures buffer pointers
+ *         bit 0 of cMode means enable transmit, bit 1 of cMode means enable
+ *         receive
+ ***********************************************************************/
+
+static void netarm_dma_enable( char cMode, struct net_device* pDev )
+{
+	struct ns7520_private_t* pPriv = (struct ns7520_private_t*) pDev->priv;
+	int i;
+
+	DEBUG_FN( DEBUG_MINOR );
+
+	if( ( cMode & 2 ) == 2 )
+	{
+	    // configure channels for transmit and receive, clear pending,
+	    netarm_dmaBufferDescInit( pPriv->aRxDmaBuffer,
+				      NS7520_RX_DESC,
+				      0 );
+	
+	    for( i = 0; i < NS7520_RX_DESC; i++ )
+	    {
+		// link the src pointer to the skb buffer
+		pPriv->aRxDmaBuffer[ i ].l.bits.srcPtr =
+		    virt_to_bus( pPriv->apRxSkb[ i ]->data );
+		pPriv->aRxDmaBuffer[ i ].h.bits.bufLen = NS7520_ETH_FRAME_LEN;
+	    }
+
+	    // use NRIP for receive lockup interrupts
+	    netarm_dmaChannelEnable( NETARM_DMA_CHANNEL_1A,
+				     pPriv->aRxDmaBuffer,
+				     NETARM_DMA_CONTROL_BB_100 |
+				     NETARM_DMA_CONTROL_MODE_PER2MEM |
+				     ((pPriv->uiLastLinkStatus &
+				       PHY_LXT971_STAT2_100BTX) ?
+				      NETARM_DMA_CONTROL_BTE_4 :
+				      NETARM_DMA_CONTROL_BTE_1 ),
+				     NETARM_DMA_STATUS_IP_MA |
+				     NETARM_DMA_STATUS_IE_NC |
+				     NETARM_DMA_STATUS_IE_EC |
+				     NETARM_DMA_STATUS_IE_NR |
+				     NETARM_DMA_STATUS_IE_CA );
+	}
+	
+	    
+	if( ( cMode & 1 ) == 1 )
+	{
+	    // [3] eth_enable_dma uses IDONE for txmit
+	    netarm_dmaBufferDescInit( &pPriv->txDmaBuffer, 1, 1 );
+	    pPriv->txDmaBuffer.l.bits.last = 1;
+	
+	    netarm_dmaChannelEnable( NETARM_DMA_CHANNEL_2,
+				     &pPriv->txDmaBuffer,
+				     NETARM_DMA_CONTROL_BB_100 |
+				     NETARM_DMA_CONTROL_MODE_MEM2PER |
+				     ((pPriv->uiLastLinkStatus &
+				       PHY_LXT971_STAT2_100BTX) ?
+				      NETARM_DMA_CONTROL_BTE_4 :
+				      NETARM_DMA_CONTROL_BTE_1 ),
+				     NETARM_DMA_STATUS_IP_EC |
+				     NETARM_DMA_STATUS_IE_EC );
+	}
+}
+
+/***********************************************************************
+ * @Function: ns7520_eth_reset
+ * @Return: 0 on failure otherwise 1
+ * @Descr: resets the ethernet interface and the PHY,
+ *         performs auto negotiation or fixed modes
+ *         Clears MIB statistics
+ ***********************************************************************/
+
+static char ns7520_eth_reset( struct net_device* pDev )
+{
+	struct ns7520_private_t* pPriv = (struct ns7520_private_t*) pDev->priv;
+
+	DEBUG_FN( DEBUG_MINOR );
+
+	// reset and initialize PHY
+
+	*get_eth_reg_addr( NS7520_ETH_MAC1 ) &= ~NS7520_ETH_MAC1_SRST;
+
+	// we don't support hot plugging of PHY, therefore we don't reset
+	// PhyDetected and nPhyMaxMdioClock here. The risk is if the setting is
+	// incorrect the first open
+	// may detect the PHY correctly but succeding will fail
+	// For reseting the PHY and identifying we have to use the standard
+	// MDIO CLOCK value 2.5 MHz only after hardware reset
+	// After having identified the PHY we will do faster
+
+	*get_eth_reg_addr( NS7520_ETH_MCFG ) =
+	    ns7520_mii_get_clock_divisor( nPhyMaxMdioClock );
+
+	// reset PHY
+	ns7520_mii_write( PHY_COMMON_CTRL, PHY_COMMON_CTRL_RESET );
+	ns7520_mii_write( PHY_COMMON_CTRL, 0 );
+
+	udelay( 300 );		// [2] p.70 says 300us reset recovery time
+
+	// MII clock has been setup to default, ns7520_mii_identify_phy should
+	// work for all
+
+	if( !ns7520_mii_identify_phy() )
+	{
+	    printk( KERN_ERR NS7520_DRIVER_NAME ": Unsupported PHY, aborting\n");
+	    return 0;
+	}
+
+	// now take the highest MDIO clock possible after detection
+	*get_eth_reg_addr( NS7520_ETH_MCFG ) =
+	    ns7520_mii_get_clock_divisor( nPhyMaxMdioClock );
+
+
+	// PHY has been detected, so there can be no abort reason and we can
+	// finish initializing ethernet
+
+	pPriv->uiLastLinkStatus = 0xff; // undefined
+	
+#if 0    
+  // use parameters defined
+  ns7520_link_force( pDev );
+#else
+  ns7520_link_auto_negotiate( pDev );
+#endif  
+
+	if( PhyDetected == PHY_LXT971A )
+	    // set LED2 to link mode
+	    ns7520_mii_write( PHY_LXT971_LED_CFG,
+			      PHY_LXT971_LED_CFG_LINK_ACT << 
+			      PHY_LXT971_LED_CFG_SHIFT_LED2);
+
+	return 1;
+}
+
+/***********************************************************************
+ * @Function: ns7520_eth_enable
+ * @Return: nothing
+ * @Descr: configures ethernet for link mode, enables FIFO and DMA
+ ***********************************************************************/
+
+
+static void ns7520_eth_enable( struct net_device* pDev )
+{
+	DEBUG_FN( DEBUG_MINOR );
+
+	// of course we want broadcasts
+	netarm_dma_enable( 3, pDev );
+
+	*get_eth_reg_addr( NS7520_ETH_MAC1 ) = NS7520_ETH_MAC1_RXEN;
+	*get_eth_reg_addr( NS7520_ETH_SUPP ) = NS7520_ETH_SUPP_JABBER;
+	*get_eth_reg_addr( NS7520_ETH_MAC1 ) = NS7520_ETH_MAC1_RXEN;
+
+	// the kernel may give packets < 60 bytes, for example arp
+	*get_eth_reg_addr( NS7520_ETH_MAC2 ) = NS7520_ETH_MAC2_CRCEN |
+	    NS7520_ETH_MAC2_PADEN |
+	    NS7520_ETH_MAC2_HUGE;
+
+	// enable receive FIFO and DMA
+	// enable transmit FIFO and DMA
+	// clear soft reset and enable receive logic, use 10/100 Mbps MII
+	*get_eth_reg_addr( NS7520_ETH_EGCR ) =
+	    NS7520_ETH_EGCR_ETXWM_75 |
+	    NS7520_ETH_EGCR_ERX |
+	    NS7520_ETH_EGCR_ERXDMA |
+	    NS7520_ETH_EGCR_ETX |
+	    NS7520_ETH_EGCR_ETXDMA |
+	    NS7520_ETH_EGCR_PNA |
+	    NS7520_ETH_EGCR_ITXA;
+
+	*get_eth_reg_addr( NS7520_ETH_EGCR ) |=
+	    NS7520_ETH_EGCR_ERXREG;
+}
+
+
+/***********************************************************************
+ * @Function: ns7520_rx_fifo_reset
+ * @Return: nothing
+ * @Descr: resets the RX FIFO after an EFE/DMA module RX DMA stall
+ *         condition [4]. Errata
+ ***********************************************************************/
+
+static void ns7520_rx_fifo_reset( struct net_device* pDev )
+{
+	DEBUG_FN( DEBUG_MAJOR );
+	
+	// disable DMA
+	*get_eth_reg_addr( NS7520_ETH_EGCR ) &= ~NS7520_ETH_EGCR_ERXDMA;
+	*get_eth_reg_addr( NS7520_ETH_EGCR ) &= ~NS7520_ETH_EGCR_ERX;
+	netarm_dma_disable( 2 );
+
+	udelay( 20 );
+
+	// reinit DMA
+	netarm_dma_enable( 2, pDev );
+	*get_eth_reg_addr( NS7520_ETH_EGCR ) |= NS7520_ETH_EGCR_ERXDMA |
+	    NS7520_ETH_EGCR_ERX;
+}
+
+/***********************************************************************
+ * @Function: ns7520_tx_fifo_reset
+ * @Return: nothing
+ * @Descr: resets the TX FIFO as described in [5], Ethernet transmitter
+ *         considerations 
+ ***********************************************************************/
+
+static void ns7520_tx_fifo_reset( struct net_device* pDev )
+{
+	DEBUG_FN( DEBUG_MAJOR );
+	
+	// disable DMA
+	*get_eth_reg_addr( NS7520_ETH_EGCR ) &= ~NS7520_ETH_EGCR_ETXDMA;
+	*get_eth_reg_addr( NS7520_ETH_EGCR ) &= ~NS7520_ETH_EGCR_ETX;
+	netarm_dma_disable( 1 );
+
+	// reinit DMA
+	netarm_dmaChannelDisable( NETARM_DMA_CHANNEL_2 );
+	netarm_dma_enable( 1, pDev );
+	*get_eth_reg_addr( NS7520_ETH_EGCR ) |= NS7520_ETH_EGCR_ETXDMA |
+	    NS7520_ETH_EGCR_ETX;
+}
+
+
+static void ns7520_rx_lockup_detect( unsigned long ulDev )
+{
+	struct net_device* pDev = (struct net_device*) ulDev;
+	struct ns7520_private_t* pPriv = (struct ns7520_private_t*) pDev->priv;
+
+	DEBUG_FN( DEBUG_INTERRUPT );
+
+	if( pPriv->rxFifoPackets != pPriv->stats.rx_packets )
+	    pPriv->rxFifoPackets = pPriv->stats.rx_packets;
+	else
+	{
+	    // check for lockup
+	    // from NetARM 50 Hardware Reference Manual EFE/DMA module RX DMA
+	    // stall condition
+	    if( (*get_eth_reg_addr( NS7520_ETH_EGSR ) &
+		 (NS7520_ETH_EGSR_RXBR | NS7520_ETH_EGSR_RXREGR ) ) ==
+		NS7520_ETH_EGSR_RXBR )
+	    {
+		DEBUG_ARGS( DEBUG_MAJOR,
+			    "Receive lockup detected, resetting FIFO\n" );
+		ns7520_rx_fifo_reset( pDev );
+	    }
+	}
+
+	if( !test_bit( 0, (void*) &pPriv->rxLockupTimerDisable ) )
+	    // refresh the timer if not in disabling mode
+	    mod_timer( &pPriv->rxLockupTimer,
+		       jiffies + HZ);
+}
+
+/***********************************************************************
+ * @Function: ns7520_rx_lockup_timer_enable
+ * @Return: void
+ * @Descr: in case the RX FIFO has locked up (NetARM+50 Errata
+ *         EFE/DMA module RX DMA stall condition) is still existing in
+ *         NS7520, this timer resets the RX FIFO
+ ***********************************************************************/
+
+static void ns7520_rx_lockup_timer_enable( struct net_device* pDev )
+{
+	struct ns7520_private_t* pPriv = (struct ns7520_private_t*) pDev->priv;
+
+	DEBUG_FN( DEBUG_MINOR );
+
+	// in case we have been reopened it may be != 0
+	pPriv->rxLockupTimerDisable = 0;
+	pPriv->rxFifoPackets = pPriv->stats.rx_packets;
+
+	init_timer( &pPriv->rxLockupTimer );
+	pPriv->rxLockupTimer.function = ns7520_rx_lockup_detect;
+	pPriv->rxLockupTimer.data = (unsigned long) pDev;
+	pPriv->rxLockupTimer.expires = jiffies + HZ;
+	add_timer( &pPriv->rxLockupTimer );
+}
+
+/***********************************************************************
+ * @Function: ns7520_rx_lockup_timer_disable
+ * @Return: void
+ * @Descr: in case the RX FIFO has locked up (NetARM+50 Errata
+ *         EFE/DMA module RX DMA stall condition) is still existing in
+ *         NS7520, this timer resets the RX FIFO
+ ***********************************************************************/
+
+static void ns7520_rx_lockup_timer_disable( struct net_device* pDev )
+{
+	struct ns7520_private_t* pPriv = (struct ns7520_private_t*) pDev->priv;
+
+	DEBUG_FN( DEBUG_MINOR );
+
+	// disable timer so it won't try to modificate itself before
+	// del_timer_sync runs
+	set_bit( 0, &pPriv->rxLockupTimerDisable );
+	del_timer_sync( &pPriv->rxLockupTimer );
+}
+
+
+/***********************************************************************
+ * @Function: ns7520_tx_timeout
+ * @Return: nothing
+ * @Descr: handles transmit timeouts by flushing the tx buffer
+ ***********************************************************************/
+
+static void ns7520_tx_timeout( struct net_device* pDev )
+{
+	struct ns7520_private_t* pPriv = (struct ns7520_private_t*) pDev->priv;
+
+	DEBUG_FN( DEBUG_MINOR );
+
+	// handle interrupt manually
+	// in case there is just a receive lockup, the packet will be sent
+	// multiple times though. The receiver should handle this
+	ns7520_tx_interrupt( 0, pDev, NULL );
+
+	pPriv->stats.tx_errors++;
+}
+
+/***********************************************************************
+ * @Function: ns7520_link_force
+ * @Return: void
+ * @Descr: configures eth and MII to use the link mode defined in
+ *         ucLinkMode
+ ***********************************************************************/
+
+static void ns7520_link_force( struct net_device* pDev )
+{
+	struct ns7520_private_t* pPriv = (struct ns7520_private_t*) pDev->priv;
+	unsigned short uiControl;
+	
+	DEBUG_FN( DEBUG_MAJOR );
+
+	uiControl = ns7520_mii_read( PHY_COMMON_CTRL );
+	uiControl &= ~( PHY_COMMON_CTRL_SPD_MA |
+			PHY_COMMON_CTRL_AUTO_NEG |
+			PHY_COMMON_CTRL_DUPLEX );
+
+	pPriv->uiLastLinkStatus = 0;
+	
+#if 0  
+  /* Left around to help someone add commandline options later */
+	if( ( ucLinkMode & MODNET_EEPROM_AUTONEG_SPEED_MASK ) ==
+	    MODNET_EEPROM_AUTONEG_SPEED_100 )
+	{
+	    uiControl |= PHY_COMMON_CTRL_SPD_100;
+	    pPriv->uiLastLinkStatus |= PHY_LXT971_STAT2_100BTX;
+	} else
+	    uiControl |= PHY_COMMON_CTRL_SPD_10;
+
+	if( ( ucLinkMode & MODNET_EEPROM_AUTONEG_DUPLEX_MASK ) ==
+	    MODNET_EEPROM_AUTONEG_DUPLEX_FULL )
+	{
+	    uiControl |= PHY_COMMON_CTRL_DUPLEX;
+	    pPriv->uiLastLinkStatus |= PHY_LXT971_STAT2_DUPLEX_MODE;
+	}
+#endif
+
+	ns7520_mii_write( PHY_COMMON_CTRL, uiControl );
+
+	ns7520_link_print_changed( pDev );
+	ns7520_link_update_egcr( pDev );
+}
+
+/***********************************************************************
+ * @Function: ns7520_link_auto_negotiate
+ * @Return: void
+ * @Descr: performs auto-negotation of link.
+ ***********************************************************************/
+
+static void ns7520_link_auto_negotiate( struct net_device* pDev )
+{
+	unsigned long ulStartJiffies;
+	unsigned short uiStatus;
+
+	DEBUG_FN( DEBUG_MAJOR );
+
+	// run auto-negotation
+	// define what we are capable of
+	ns7520_mii_write( PHY_COMMON_AUTO_ADV,
+			  PHY_COMMON_AUTO_ADV_100BTXFD |
+			  PHY_COMMON_AUTO_ADV_100BTX |
+			  PHY_COMMON_AUTO_ADV_10BTFD |
+			  PHY_COMMON_AUTO_ADV_10BT |
+			  PHY_COMMON_AUTO_ADV_802_3 );
+	// start auto-negotiation
+	ns7520_mii_write( PHY_COMMON_CTRL,
+			  PHY_COMMON_CTRL_AUTO_NEG |
+			  PHY_COMMON_CTRL_RES_AUTO );
+	// wait for completion
+
+	ulStartJiffies = jiffies;
+	while( jiffies < ulStartJiffies + NS7520_MII_NEG_DELAY )
+	{
+	    uiStatus = ns7520_mii_read( PHY_COMMON_STAT );
+	    if((uiStatus & (PHY_COMMON_STAT_AN_COMP|PHY_COMMON_STAT_LNK_STAT)) ==
+	       (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT) ) 
+	    {
+		// lucky we are, auto-negotiation succeeded
+		ns7520_link_print_changed( pDev );
+		ns7520_link_update_egcr( pDev );
+
+		return;
+	    }
+	}
+
+	DEBUG_ARGS( DEBUG_MAJOR, "auto-negotiation timed out\n" );
+	// ignore invalid link settings
+}
+
+/***********************************************************************
+ * @Function: ns7520_link_update_egcr
+ * @Return: void
+ * @Descr: updates the EGCR and MAC2 link status after mode change or
+ *         auto-negotation
+ ***********************************************************************/
+
+static void ns7520_link_update_egcr( struct net_device* pDev )
+{
+	struct ns7520_private_t* pPriv = (struct ns7520_private_t*) pDev->priv;
+	unsigned int unEGCR;
+	unsigned int unMAC2;
+	unsigned int unIPGT;
+
+	DEBUG_FN( DEBUG_ETH );
+
+	unEGCR = *get_eth_reg_addr( NS7520_ETH_EGCR );
+	unMAC2 = *get_eth_reg_addr( NS7520_ETH_MAC2 );
+	unIPGT = *get_eth_reg_addr( NS7520_ETH_IPGT ) & ~NS7520_ETH_IPGT_IPGT;
+
+	unEGCR &= ~NS7520_ETH_EGCR_EFULLD;
+	unMAC2 &= ~NS7520_ETH_MAC2_FULLD;
+	if( (pPriv->uiLastLinkStatus & PHY_LXT971_STAT2_DUPLEX_MODE) 
+	    == PHY_LXT971_STAT2_DUPLEX_MODE )
+	{
+	    unEGCR |= NS7520_ETH_EGCR_EFULLD;
+	    unMAC2 |= NS7520_ETH_MAC2_FULLD;
+	    unIPGT |= 0x15;	// see [1] p. 167
+	} else
+	    unIPGT |= 0x12;	// see [1] p. 167
+
+	*get_eth_reg_addr( NS7520_ETH_MAC2 ) = unMAC2;
+	*get_eth_reg_addr( NS7520_ETH_EGCR ) = unEGCR;
+	*get_eth_reg_addr( NS7520_ETH_IPGT ) = unIPGT;
+}
+
+/***********************************************************************
+ * @Function: ns7520_link_print_changed
+ * @Return: void
+ * @Descr: checks whether the link status has changed and if so prints
+ *         the new mode
+ ***********************************************************************/
+
+static void ns7520_link_print_changed( struct net_device* pDev )
+{
+	struct ns7520_private_t* pPriv = (struct ns7520_private_t*) pDev->priv;
+	unsigned short uiStatus;
+	unsigned short uiControl;
+	
+	DEBUG_FN( DEBUG_ETH );
+
+	uiControl = ns7520_mii_read( PHY_COMMON_CTRL );
+
+	if( (uiControl & PHY_COMMON_CTRL_AUTO_NEG) == PHY_COMMON_CTRL_AUTO_NEG )
+	{
+	    // PHY_COMMON_STAT_LNK_STAT is only set on autonegotiation
+	    uiStatus = ns7520_mii_read( PHY_COMMON_STAT );
+
+	    if( !( uiStatus & PHY_COMMON_STAT_LNK_STAT) )
+	    {
+		printk( KERN_WARNING NS7520_DRIVER_NAME ": link down\n" );
+		netif_carrier_off( pDev );
+	    } else {
+		if( !netif_carrier_ok( pDev ) )
+		    // we are online again, enable it
+		    netif_carrier_on( pDev );
+		
+		if( PhyDetected == PHY_LXT971A )
+		{
+		    uiStatus = ns7520_mii_read( PHY_LXT971_STAT2 );
+		    uiStatus &= (PHY_LXT971_STAT2_100BTX |
+				 PHY_LXT971_STAT2_DUPLEX_MODE |
+				 PHY_LXT971_STAT2_AUTO_NEG );
+		    
+		    // mask out all uninteresting parts
+		}
+		// other PHYs must store there link information in uiStatus
+		// as PHY_LXT971
+	    }
+	} else {
+	    //  mode has been forced, so uiStatus should be the same as the last
+	    //  link status, enforce printing
+	    uiStatus = pPriv->uiLastLinkStatus;
+	    pPriv->uiLastLinkStatus = 0xff;
+	}
+	
+	if( uiStatus != pPriv->uiLastLinkStatus )
+	{
+	    // save current link status
+	    pPriv->uiLastLinkStatus = uiStatus;
+
+	    // print new link status 
+	    
+	    printk( KERN_INFO NS7520_DRIVER_NAME
+		    ": link mode %i Mbps %s duplex %s\n",
+		    (uiStatus & PHY_LXT971_STAT2_100BTX) ? 100 : 10,
+		    (uiStatus & PHY_LXT971_STAT2_DUPLEX_MODE)?"full":"half",
+		    (uiStatus & PHY_LXT971_STAT2_AUTO_NEG)?"(auto)":"" );
+	}
+}
+
+/***********************************************************************
+ * the MII low level stuff
+ ***********************************************************************/
+
+/***********************************************************************
+ * @Function: ns7520_mii_identify_phy
+ * @Return: 1 if supported PHY has been detected otherwise 0
+ * @Descr: checks for supported PHY and prints the IDs.
+ ***********************************************************************/
+
+static char ns7520_mii_identify_phy( void )
+{
+	unsigned short uiID1;
+	unsigned short uiID2;
+	unsigned char* szName;
+	char cRes = 0;
+	
+	DEBUG_FN( DEBUG_MII );
+	
+	PhyDetected = (PhyType) uiID1 = ns7520_mii_read( PHY_COMMON_ID1 );
+
+	switch( PhyDetected )
+	{
+	    case PHY_LXT971A:
+		szName = "LXT971A";
+		uiID2 = ns7520_mii_read( PHY_COMMON_ID2 );
+		nPhyMaxMdioClock = PHY_LXT971_MDIO_MAX_CLK;
+		cRes = 1;
+		break;
+	    case PHY_NONE:
+	    default:
+		// in case uiID1 == 0 && uiID2 == 0 we may have the wrong
+		// address or reset sets the wrong NS7520_ETH_MCFG_CLKS
+		
+		uiID2 = 0;
+		szName = "unknown";
+		nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
+		PhyDetected = PHY_NONE;
+	}
+
+	printk( KERN_INFO NS7520_DRIVER_NAME
+		": PHY (0x%x, 0x%x) = %s detected\n",
+		uiID1,
+		uiID2,
+		szName );
+
+	return cRes;
+}
+
+
+/***********************************************************************
+ * @Function: ns7520_mii_read
+ * @Return: the data read from PHY register uiRegister
+ * @Descr: the data read may be invalid if timed out. If so, a message
+ *         is printed but the invalid data is returned.
+ *         The fixed device address is being used.
+ ***********************************************************************/
+
+static unsigned short ns7520_mii_read( unsigned short uiRegister )
+{
+	DEBUG_FN( DEBUG_MII_LOW );
+
+	// write MII register to be read
+	*get_eth_reg_addr( NS7520_ETH_MADR ) = NS7520_ETH_PHY_ADDRESS|uiRegister;
+
+	*get_eth_reg_addr( NS7520_ETH_MCMD ) = NS7520_ETH_MCMD_READ;
+
+	if( !ns7520_mii_poll_busy() )
+	    printk( KERN_WARNING NS7520_DRIVER_NAME
+		    ": MII still busy in read\n" );
+	// continue to read
+
+	// as of [3] MII.c ns7520_mii_read the bit is not cleared automatically
+	// by the NS7520
+	*get_eth_reg_addr( NS7520_ETH_MCMD ) = 0;
+
+	return (unsigned short) (*get_eth_reg_addr( NS7520_ETH_MRDD ) );
+}
+
+
+/***********************************************************************
+ * @Function: ns7520_mii_write
+ * @Return: nothing
+ * @Descr: writes the data to the PHY register. In case of a timeout,
+ *         no special handling is performed but a message printed
+ *         The fixed device address is being used.
+ ***********************************************************************/
+
+static void ns7520_mii_write( unsigned short uiRegister, unsigned short uiData )
+{
+	DEBUG_FN( DEBUG_MII_LOW );
+
+	// write MII register to be written
+	*get_eth_reg_addr( NS7520_ETH_MADR ) = NS7520_ETH_PHY_ADDRESS|uiRegister;
+
+	*get_eth_reg_addr( NS7520_ETH_MWTD ) = uiData;
+
+	if( !ns7520_mii_poll_busy() )
+	    printk( KERN_WARNING NS7520_DRIVER_NAME 
+		    ": MII still busy in write\n");
+}
+
+
+/***********************************************************************
+ * @Function: ns7520_mii_poll_busy
+ * @Return: 0 if timed out otherwise the remaing timeout
+ * @Descr: waits until the MII has completed a command or it times out
+ *         code may be interrupted by hard interrupts.
+ *         It is not checked what happens on multiple actions when
+ *         the first is still being busy and we timeout.
+ ***********************************************************************/
+
+static unsigned int ns7520_mii_poll_busy( void )
+{
+	// I don't have any real figures how long an MDI read or write
+	// can last, so I took it from [3] MII.c (ns7520_mii_poll_busy). But
+	// in [2] p.24 we have about 40 bits and on [2] 
+	// p.69 we see a clock time of 125ns => about 6us each. Add a
+	// little bit of overhead. So these amount of iterations
+	// should be enough 
+	unsigned int unTimeout = 1000;
+
+	DEBUG_FN( DEBUG_MII_LOW );
+
+	while( (( *get_eth_reg_addr( NS7520_ETH_MIND ) & NS7520_ETH_MIND_BUSY) 
+		== NS7520_ETH_MIND_BUSY ) && 
+	       unTimeout )
+	       unTimeout--;
+
+	return unTimeout;
+}
+
+/***********************************************************************
+ * @Function: ns7520_mii_get_clock_divisor
+ * @Return: the clock divisor that should be used in NS7520_ETH_MCFG_CLKS
+ * @Descr: if no clock divisor can be calculated for the
+ *         current SYSCLK and the maximum MDIO Clock, a warning is printed
+ *         and the greatest divisor is taken
+ ***********************************************************************/
+
+static unsigned int ns7520_mii_get_clock_divisor( unsigned int unMaxMDIOClk )
+{
+	struct 
+	{
+		unsigned int unSysClkDivisor;
+		unsigned int unClks; // field for NS7520_ETH_MCFG_CLKS
+	} PHYClockDivisors[] =
+	{ 
+	    {  4, NS7520_ETH_MCFG_CLKS_4 },
+	    {  6, NS7520_ETH_MCFG_CLKS_6 },
+	    {  8, NS7520_ETH_MCFG_CLKS_8 },
+	    { 10, NS7520_ETH_MCFG_CLKS_10 },
+	    { 14, NS7520_ETH_MCFG_CLKS_14 },
+	    { 20, NS7520_ETH_MCFG_CLKS_20 },
+	    { 28, NS7520_ETH_MCFG_CLKS_28 }
+	};
+	
+	int nIndexSysClkDiv;
+	int nArraySize = sizeof(PHYClockDivisors) / sizeof(PHYClockDivisors[0]);
+	unsigned int unClks = NS7520_ETH_MCFG_CLKS_28; // defaults to
+	// greatest div
+
+	DEBUG_FN( DEBUG_INIT );
+
+	for( nIndexSysClkDiv=0; nIndexSysClkDiv < nArraySize; nIndexSysClkDiv++ )
+	{
+	    // find first sysclock divisor that isn't higher than 2.5 MHz clock
+	    if( NETARM_XTAL_FREQ /
+		PHYClockDivisors[nIndexSysClkDiv].unSysClkDivisor<=unMaxMDIOClk)
+	    {
+		unClks = PHYClockDivisors[ nIndexSysClkDiv ].unClks;
+		break;
+	    }
+	}
+
+	DEBUG_ARGS( DEBUG_INIT,
+		    "Taking MDIO Clock bit mask 0x%0x for max clock %i\n",
+		    unClks,
+		    unMaxMDIOClk );
+		    
+	// return greatest divisor
+	return unClks;
+}
+
+/***********************************************************************
+ * MULTICAST ADDRESS HASH TABLE FUNCTIONS
+ * Taken from netarm_eth.c and [1]
+ ***********************************************************************/
+
+
+/***********************************************************************
+ * @Function: ns7520_load_mca_hash_table
+ * @Return: nothing
+ * @Descr: This function generates the multicast address hash table from the
+ *         multicast addresses contained in the provided linked list.  This
+ *         function loads this table into the Ethernet controller.
+ ***********************************************************************/
+
+static void ns7520_load_mca_hash_table( struct dev_mc_list* pMcList )
+{
+	unsigned short      auiHashTable[ 4 ];
+	struct dev_mc_list* pMcListEntry;
+	int                 nBitNumber;
+	
+	// Generate the hash table.
+	
+	memset( auiHashTable, 0, sizeof( auiHashTable ) );
+	
+	for( pMcListEntry = pMcList;
+	     pMcListEntry != NULL;
+	     pMcListEntry = pMcListEntry->next)
+	{
+	    DEBUG_ARGS( DEBUG_MINOR,
+			"  multicast address:  %X %X %X %X %X %X\n",
+			pMcListEntry->dmi_addr[0], pMcListEntry->dmi_addr[1],
+			pMcListEntry->dmi_addr[2], pMcListEntry->dmi_addr[3],
+			pMcListEntry->dmi_addr[4], pMcListEntry->dmi_addr[5] );
+
+	    nBitNumber = ns7520_calculate_hash_bit( pMcListEntry->dmi_addr );
+	    ns7520_set_hash_bit( (unsigned char *) auiHashTable, nBitNumber );
+	}
+	DEBUG_ARGS( DEBUG_MINOR,
+		    "  hash table:  %hX %hX %hX %hX\n",
+		    auiHashTable[ 0 ], auiHashTable[ 1 ],
+		    auiHashTable[ 2 ], auiHashTable[ 3 ] );    
+
+	// Load the hash table into the Ethernet controller.
+
+	*get_eth_reg_addr( NS7520_ETH_HT1 ) = auiHashTable[ 0 ];
+	*get_eth_reg_addr( NS7520_ETH_HT2 ) = auiHashTable[ 1 ];
+	*get_eth_reg_addr( NS7520_ETH_HT3 ) = auiHashTable[ 2 ];
+	*get_eth_reg_addr( NS7520_ETH_HT4 ) = auiHashTable[ 3 ];
+}
+
+/***********************************************************************
+ * @Function: ns7520_set_hash_bit
+ * @Return: nothing
+ * @Descr: sets a bit in the hash table
+ ***********************************************************************/
+
+static void ns7520_set_hash_bit( unsigned char* pucHashTable, int nBit )
+{
+	int nByteIndex;
+	int nBitIndex;
+	
+	nByteIndex = nBit >> 3;
+	nBitIndex = nBit & 7;
+	pucHashTable[ nByteIndex ] |= (1 << nBitIndex );
+}
+
+
+/***********************************************************************
+ * @Function: ns7520_calculate_hash_bit
+ * @Return: bit position to set in hash table
+ * @Descr:  This routine calculates the bit to set in the CRC hash table
+ *          to enable receipt of the specified multicast address.
+ ***********************************************************************/
+
+static int ns7520_calculate_hash_bit( unsigned char* pucMac )
+{
+	unsigned short  unCopyMac[ 3 ];
+	unsigned short* punMac;
+	unsigned short  unBp;
+	unsigned short  unBx;
+	unsigned long   ulCrc;
+	int             nResult;
+	int             nMacWord;
+	int             nBitIndex;
+
+	// pucMac may not be 32 bit aligned
+	memcpy( unCopyMac, pucMac, sizeof( unCopyMac ) );
+	
+	punMac = unCopyMac;
+	ulCrc = 0xffffffffL;
+	
+	for( nMacWord = 0; nMacWord < 3; nMacWord++ )
+	{
+	    unBp = *punMac;                            // get word of address
+	    punMac++;
+	    
+	    for( nBitIndex = 0; nBitIndex < 16; nBitIndex++ )
+	    {
+		unBx = (unsigned short) (ulCrc >> 16);  // get high word of crc
+		unBx = ns7520_rotate(unBx,NS7520_LEFT,1); // bit 31 to lsb
+		unBx ^= unBp;                           // combine with incoming
+		ulCrc <<= 1;                           // shift crc left 1 bit
+		unBx &= 1;                             // get control bit
+		if( unBx )                             // if bit set
+		    ulCrc ^= NS7520_POLYNOMIAL;        // xor crc with polynomial
+		ulCrc |= unBx;                         // or in control bit
+		unBp = ns7520_rotate( unBp, NS7520_RIGHT, 1 );
+	    }
+	}
+	
+	// CRC calculation done.  The 6-bit result resides in bits locations
+	// 28:23.
+	
+	nResult = (ulCrc >> 23) & 0x3f;
+	
+	return nResult;
+}
+
+
+/***********************************************************************
+ * @Function: ns7520_rotate
+ * @Return: rotated short
+ * @Descr: 
+ *      rotates an unsigned short a number of bit
+ *      reg         value to rotate
+ *      direction   NS7520_LEFT or NS7520_RIGHT
+ *      bits        # of bits to rotate
+ ***********************************************************************/
+
+static unsigned short ns7520_rotate( unsigned short uiReg,
+				     int nDirection,
+				     int nBits )
+{
+	int i;
+	
+	if( nDirection == NS7520_LEFT )
+	{
+	    for( i = 0; i < nBits; i++ )
+	    {
+		if( uiReg & 0x8000 )            // if high bit set
+		    uiReg = (uiReg << 1) | 1;   // shift left and or in 1
+		else
+		    uiReg <<= 1;
+	    }
+	} else {                                // if ror
+	    for( i = 0; i < nBits; i++ )
+	    {
+		if( uiReg & 1 )                 // if low bit set
+		    uiReg = (uiReg>>1)|0x8000;  // shift right and or in hi bit 
+		else
+		    uiReg >>= 1;
+	    }
+	}
+
+	return uiReg;
+}
+
+// ns7520_init_module, ns7520_cleanup_module at end as of linux convention
+
+/***********************************************************************
+ * @Function: ns7520_init_module
+ * @Return: 0 if successfull otherwise error
+ * @Descr: initialized the NS7520 ethernet interface. Doesn't perform
+ *         any hardware detection.
+ ***********************************************************************/
+
+static int ns7520_init_module( void )
+{
+	int nRes = 0;
+	
+	printk( KERN_INFO "NS7520 Ethernet Driver Initialized\n" );
+
+	if( ( nRes = register_netdev( &ns7520_devs ) ) )
+	{
+	    printk( KERN_INFO NS7520_DRIVER_NAME ": Error %i registering %s\n",
+		    nRes,
+		    ns7520_devs.name );
+
+	    return ENODEV;
+	}
+
+	return 0;
+}
+
+
+/***********************************************************************
+ * @Function: ns7520_cleanup_module
+ * @Return: nothing
+ * @Descr: deinitialized module
+ ***********************************************************************/
+
+static void ns7520_cleanup_module( void )
+{
+	printk( KERN_INFO "NS7520 Ethernet Driver removing\n" );
+
+	unregister_netdev( &ns7520_devs );
+	// unregister_netdev accesses the stats, so kfree must be later
+        kfree( ns7520_devs.priv );
+}
+
+module_init( ns7520_init_module );
+module_exit( ns7520_cleanup_module );
+
+MODULE_AUTHOR( "Markus Pietrek <mpietrek@fsforth.de>");
+MODULE_DESCRIPTION("NS7520 Ethernet Driver On UNC20 From FS Forth Systeme GmbH");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/drivers/net/ns7520_eth.h linux-2.4.29-uc1/drivers/net/ns7520_eth.h
--- linux-2.4.29/drivers/net/ns7520_eth.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/ns7520_eth.h	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,564 @@
+/***********************************************************************
+ *
+ *  Copyright 2003 by FS Forth-Systeme GmbH.
+ *  All rights reserved.
+ *
+ *  $Id: ns7520_eth.h,v 1.1 2003/08/28 17:40:35 art Exp $
+ *  @Author: Markus Pietrek
+ *  @Descr: Defines the NS7520 ethernet registers.
+ *          Stick with the old ETH prefix names instead going to the
+ *          new EFE names in the manual.
+ *          NS7520_ETH_* refer to NS7520 Hardware
+ *           Reference/January 2003 [1]
+ *          PHY_LXT971_* refer to Intel LXT971 Datasheet 
+ *           #249414 Rev. 02 [2]
+ *          Partly derived from netarm_eth_module.h
+ *          
+ *  
+ ***********************************************************************/
+
+#ifndef FS_NS7520_ETH_H
+#define FS_NS7520_ETH_H
+
+/* The port addresses */
+
+#define	NS7520_ETH_MODULE_BASE	 (0xFF800000)
+#define get_eth_reg_addr(c) \
+     ((volatile unsigned int*) ( NS7520_ETH_MODULE_BASE + ( c ) ) )
+
+#define NS7520_ETH_EGCR		 (0x0000)     // Ethernet Gen Control
+#define NS7520_ETH_EGSR		 (0x0004)     // Ethernet Gen Status
+#define NS7520_ETH_FIFO		 (0x0008)     // FIFO Data
+#define NS7520_ETH_FIFOL	 (0x000C)     // FIFO Data Last
+#define NS7520_ETH_ETSR		 (0x0010)     // Ethernet Transmit Status
+#define NS7520_ETH_ERSR		 (0x0014)     // Ethernet Receive Status
+#define NS7520_ETH_MAC1		 (0x0400)     // MAC Config 1
+#define NS7520_ETH_MAC2		 (0x0404)     // MAC Config 2
+#define NS7520_ETH_IPGT		 (0x0408)     // Back2Back InterPacket Gap
+#define NS7520_ETH_IPGR		 (0x040C)     // non back2back InterPacket Gap
+#define NS7520_ETH_CLRT		 (0x0410)     // Collision Window/Retry
+#define NS7520_ETH_MAXF		 (0x0414)     // Maximum Frame Register
+#define NS7520_ETH_SUPP		 (0x0418)     // PHY Support
+#define NS7520_ETH_TEST		 (0x041C)     // Test Register
+#define NS7520_ETH_MCFG		 (0x0420)     // MII Management Configuration
+#define NS7520_ETH_MCMD		 (0x0424)     // MII Management Command
+#define NS7520_ETH_MADR		 (0x0428)     // MII Management Address
+#define NS7520_ETH_MWTD		 (0x042C)     // MII Management Write Data
+#define NS7520_ETH_MRDD		 (0x0430)     // MII Management Read Data
+#define NS7520_ETH_MIND		 (0x0434)     // MII Management Indicators
+#define NS7520_ETH_SMII		 (0x0438)     // SMII Status Register
+#define NS7520_ETH_SA1		 (0x0440)     // Station Address 1
+#define NS7520_ETH_SA2		 (0x0444)     // Station Address 2
+#define NS7520_ETH_SA3		 (0x0448)     // Station Address 3
+#define NS7520_ETH_SAFR		 (0x05C0)     // Station Address Filter
+#define NS7520_ETH_HT1		 (0x05D0)     // Hash Table 1
+#define NS7520_ETH_HT2		 (0x05D4)     // Hash Table 2
+#define NS7520_ETH_HT3		 (0x05D8)     // Hash Table 3
+#define NS7520_ETH_HT4		 (0x05DC)     // Hash Table 4
+
+// EGCR Ethernet General Control Register Bit Fields
+
+#define NS7520_ETH_EGCR_ERX	 (0x80000000) // Enable Receive FIFO
+#define NS7520_ETH_EGCR_ERXDMA	 (0x40000000) // Enable Receive DMA
+#define NS7520_ETH_EGCR_ERXLNG	 (0x20000000) // Accept Long packets
+#define NS7520_ETH_EGCR_ERXSHT	 (0x10000000) // Accept Short packets
+#define NS7520_ETH_EGCR_ERXREG	 (0x08000000) // Enable Receive Data Interrupt
+#define NS7520_ETH_EGCR_ERFIFOH	 (0x04000000) // Enable Receive Half-Full Int
+#define NS7520_ETH_EGCR_ERXBR	 (0x02000000) // Enable Receive buffer ready
+#define NS7520_ETH_EGCR_ERXBAD	 (0x01000000) // Accept bad receive packets
+#define NS7520_ETH_EGCR_ETX	 (0x00800000) // Enable Transmit FIFO
+#define NS7520_ETH_EGCR_ETXDMA	 (0x00400000) // Enable Transmit DMA
+#define NS7520_ETH_EGCR_ETXWM_R  (0x00300000) // Enable Transmit FIFO mark Reserv
+#define NS7520_ETH_EGCR_ETXWM_75 (0x00200000) // Enable Transmit FIFO mark 75%
+#define NS7520_ETH_EGCR_ETXWM_50 (0x00100000) // Enable Transmit FIFO mark 50%
+#define NS7520_ETH_EGCR_ETXWM_25 (0x00000000) // Enable Transmit FIFO mark 25%
+#define NS7520_ETH_EGCR_ETXREG	 (0x00080000) // Enable Transmit Data Read Int
+#define NS7520_ETH_EGCR_ETFIFOH	 (0x00040000) // Enable Transmit Fifo Half Int
+#define NS7520_ETH_EGCR_ETXBC	 (0x00020000) // Enable Transmit Buffer Compl Int
+#define NS7520_ETH_EGCR_EFULLD	 (0x00010000) // Enable Full Duplex Operation
+#define NS7520_ETH_EGCR_MODE_MA  (0x0000C000) // Mask
+#define NS7520_ETH_EGCR_MODE_SEE (0x0000C000) // 10 Mbps SEEQ ENDEC PHY
+#define NS7520_ETH_EGCR_MODE_LEV (0x00008000) // 10 Mbps Level1 ENDEC PHY
+#define NS7520_ETH_EGCR_RES1     (0x00002000) // Reserved
+#define NS7520_ETH_EGCR_RXCINV	 (0x00001000) // Invert the receive clock input
+#define NS7520_ETH_EGCR_TXCINV	 (0x00000800) // Invert the transmit clock input
+#define NS7520_ETH_EGCR_PNA	 (0x00000400) // pSOS pNA buffer 
+#define NS7520_ETH_EGCR_MAC_RES	 (0x00000200) // MAC Software reset
+#define NS7520_ETH_EGCR_ITXA	 (0x00000100) // Insert Transmit Source Address
+#define NS7520_ETH_EGCR_ENDEC_MA (0x000000FC) // ENDEC media control bits
+#define NS7520_ETH_EGCR_EXINT_MA (0x00000003) // Mask
+#define NS7520_ETH_EGCR_EXINT_RE (0x00000003) // Reserved
+#define NS7520_ETH_EGCR_EXINT_TP (0x00000002) // TP-PMD Mode
+#define NS7520_ETH_EGCR_EXINT_10 (0x00000001) // 10-MBit Mode
+#define NS7520_ETH_EGCR_EXINT_NO (0x00000000) // MII normal operation
+
+// EGSR Ethernet General Status Register Bit Fields
+
+#define NS7520_ETH_EGSR_RES1	 (0xC0000000) // Reserved
+#define NS7520_ETH_EGSR_RXFDB_MA (0x30000000) // Receive FIFO mask
+#define NS7520_ETH_EGSR_RXFDB_3	 (0x30000000) // Receive FIFO 3 bytes available
+#define NS7520_ETH_EGSR_RXFDB_2	 (0x20000000) // Receive FIFO 2 bytes available
+#define NS7520_ETH_EGCR_RXFDB_1	 (0x10000000) // Receive FIFO 1 Bytes available
+#define NS7520_ETH_EGCR_RXFDB_4	 (0x00000000) // Receive FIFO 4 Bytes available
+#define NS7520_ETH_EGSR_RXREGR	 (0x08000000) // Receive Register Ready
+#define NS7520_ETH_EGSR_RXFIFOH	 (0x04000000) // Receive FIFO Half Full
+#define NS7520_ETH_EGSR_RXBR	 (0x02000000) // Receive Buffer Ready
+#define NS7520_ETH_EGSR_RXSKIP	 (0x01000000) // Receive Buffer Skip
+#define NS7520_ETH_EGSR_RES2	 (0x00F00000) // Reserved
+#define NS7520_ETH_EGSR_TXREGE	 (0x00080000) // Transmit Register Empty
+#define NS7520_ETH_EGSR_TXFIFOH	 (0x00040000) // Transmit FIFO half empty
+#define NS7520_ETH_EGSR_TXBC	 (0x00020000) // Transmit buffer complete
+#define NS7520_ETH_EGSR_TXFIFOE	 (0x00010000) // Transmit FIFO empty
+#define NS7520_ETH_EGSR_RXPINS	 (0x0000FC00) // ENDEC Phy Status
+#define NS7520_ETH_EGSR_RES3	 (0x000003FF) // Reserved
+
+// ETSR Ethernet Transmit Status Register Bit Fields
+
+#define NS7520_ETH_ETSR_RES1	 (0xFFFF0000) // Reserved
+#define NS7520_ETH_ETSR_TXOK	 (0x00008000) // Packet transmitted OK
+#define NS7520_ETH_ETSR_TXBR	 (0x00004000) // Broadcast packet transmitted
+#define NS7520_ETH_ETSR_TXMC	 (0x00002000) // Multicast packet transmitted
+#define NS7520_ETH_ETSR_TXAL	 (0x00001000) // Transmit abort - late collision
+#define NS7520_ETH_ETSR_TXAED	 (0x00000800) // Transmit abort - deferral
+#define NS7520_ETH_ETSR_TXAEC	 (0x00000400) // Transmit abort - exc collisions
+#define NS7520_ETH_ETSR_TXAUR	 (0x00000200) // Transmit abort - underrun
+#define NS7520_ETH_ETSR_TXAJ	 (0x00000100) // Transmit abort - jumbo
+#define NS7520_ETH_ETSR_RES2	 (0x00000080) // Reserved
+#define NS7520_ETH_ETSR_TXDEF	 (0x00000040) // Transmit Packet Deferred
+#define NS7520_ETH_ETSR_TXCRC	 (0x00000020) // Transmit CRC error
+#define NS7520_ETH_ETSR_RES3	 (0x00000010) // Reserved
+#define NS7520_ETH_ETSR_TXCOLC   (0x0000000F) // Transmit Collision Count
+
+// ERSR Ethernet Receive Status Register Bit Fields
+
+#define NS7520_ETH_ERSR_RXSIZE	 (0xFFFF0000) // Receive Buffer Size
+#define NS7520_ETH_ERSR_RXCE	 (0x00008000) // Receive Carrier Event 
+#define NS7520_ETH_ERSR_RXDV	 (0x00004000) // Receive Data Violation Event
+#define NS7520_ETH_ERSR_RXOK	 (0x00002000) // Receive Packet OK
+#define NS7520_ETH_ERSR_RXBR	 (0x00001000) // Receive Broadcast Packet
+#define NS7520_ETH_ERSR_RXMC	 (0x00000800) // Receive Multicast Packet
+#define NS7520_ETH_ERSR_RXCRC	 (0x00000400) // Receive Packet has CRC error
+#define NS7520_ETH_ERSR_RXDR	 (0x00000200) // Receive Packet has dribble error
+#define NS7520_ETH_ERSR_RXCV	 (0x00000100) // Receive Packet code violation
+#define NS7520_ETH_ERSR_RXLNG	 (0x00000080) // Receive Packet too long
+#define NS7520_ETH_ERSR_RXSHT	 (0x00000040) // Receive Packet too short
+#define NS7520_ETH_ERSR_ROVER	 (0x00000020) // Recive overflow
+#define NS7520_ETH_ERSR_RES	 (0x0000001F) // Reserved
+
+// MAC1 MAC Configuration Register 1 Bit Fields
+
+#define NS7520_ETH_MAC1_RES1 	 (0xFFFF0000) // Reserved
+#define NS7520_ETH_MAC1_SRST	 (0x00008000) // Soft Reset
+#define NS7520_ETH_MAC1_SIMMRST	 (0x00004000) // Simulation Reset
+#define NS7520_ETH_MAC1_RES2	 (0x00003000) // Reserved
+#define NS7520_ETH_MAC1_RPEMCSR	 (0x00000800) // Reset PEMCS/RX
+#define NS7520_ETH_MAC1_RPERFUN	 (0x00000400) // Reset PERFUN
+#define NS7520_ETH_MAC1_RPEMCST	 (0x00000200) // Reset PEMCS/TX
+#define NS7520_ETH_MAC1_RPETFUN	 (0x00000100) // Reset PETFUN
+#define NS7520_ETH_MAC1_RES3	 (0x000000E0) // Reserved
+#define NS7520_ETH_MAC1_LOOPBK	 (0x00000010) // Internal Loopback
+#define NS7520_ETH_MAC1_TXFLOW	 (0x00000008) // TX flow control
+#define NS7520_ETH_MAC1_RXFLOW	 (0x00000004) // RX flow control
+#define NS7520_ETH_MAC1_PALLRX	 (0x00000002) // Pass ALL receive frames
+#define NS7520_ETH_MAC1_RXEN	 (0x00000001) // Receive enable
+
+// MAC Configuration Register 2 Bit Fields
+
+#define NS7520_ETH_MAC2_RES1 	 (0xFFFF8000) // Reserved
+#define NS7520_ETH_MAC2_EDEFER	 (0x00004000) // Excess Deferral
+#define NS7520_ETH_MAC2_BACKP	 (0x00002000) // Backpressure/NO back off
+#define NS7520_ETH_MAC2_NOBO	 (0x00001000) // No back off
+#define NS7520_ETH_MAC2_RES2	 (0x00000C00) // Reserved
+#define NS7520_ETH_MAC2_LONGP	 (0x00000200) // Long Preable enforcement
+#define NS7520_ETH_MAC2_PUREP	 (0x00000100) // Pure preamble enforcement
+#define NS7520_ETH_MAC2_AUTOP	 (0x00000080) // Auto detect PAD enable
+#define NS7520_ETH_MAC2_VLANP	 (0x00000040) // VLAN pad enable
+#define NS7520_ETH_MAC2_PADEN  	 (0x00000020) // PAD/CRC enable
+#define NS7520_ETH_MAC2_CRCEN	 (0x00000010) // CRC enable
+#define NS7520_ETH_MAC2_DELCRC	 (0x00000008) // Delayed CRC
+#define NS7520_ETH_MAC2_HUGE	 (0x00000004) // Huge frame enable
+#define NS7520_ETH_MAC2_FLENC	 (0x00000002) // Frame length checking
+#define NS7520_ETH_MAC2_FULLD	 (0x00000001) // Full duplex
+
+// IPGT Back-to-Back Inter-Packet-Gap Register Bit Fields
+
+#define NS7520_ETH_IPGT_RES	 (0xFFFFFF80) // Reserved
+#define NS7520_ETH_IPGT_IPGT	 (0x0000007F) // Back-to-Back Interpacket Gap
+
+// IPGR Non Back-to-Back Inter-Packet-Gap Register Bit Fields
+
+#define NS7520_ETH_IPGR_RES1	 (0xFFFF8000) // Reserved
+#define NS7520_ETH_IPGR_IPGR1	 (0x00007F00) // Non Back-to-back Interpacket Gap
+#define NS7520_ETH_IPGR_RES2	 (0x00000080) // Reserved
+#define NS7520_ETH_IPGR_IPGR2	 (0x0000007F) // Non back-to-back Interpacket Gap
+
+// CLRT Collision Windows/Collision Retry Register Bit Fields
+
+#define NS7520_ETH_CLRT_RES1	 (0xFFFFC000) // Reserved
+#define NS7520_ETH_CLRT_CWIN	 (0x00003F00) // Collision Windows
+#define NS7520_ETH_CLRT_RES2	 (0x000000F0) // Reserved
+#define	NS7520_ETH_CLRT_RETX	 (0x0000000F) // Retransmission maximum
+
+// MAXF Maximum Frame Register Bit Fields
+
+#define NS7520_ETH_MAXF_RES1	 (0xFFFF0000) // Reserved
+#define NS7520_ETH_MAXF_MAXF	 (0x0000FFFF) // Maximum frame length
+
+// SUPP PHY Support Register Bit Fields
+
+#define NS7520_ETH_SUPP_RES1	 (0xFFFFFF00) // Reserved
+#define NS7520_ETH_SUPP_RPE100X	 (0x00000080) // Reset PE100X module
+#define NS7520_ETH_SUPP_FORCEQ	 (0x00000040) // Force Quit
+#define NS7520_ETH_SUPP_NOCIPH	 (0x00000020) // No Cipher
+#define NS7520_ETH_SUPP_DLINKF	 (0x00000010) // Disable link fail
+#define NS7520_ETH_SUPP_RPE10T	 (0x00000008) // Reset PE10T module
+#define NS7520_ETH_SUPP_RES2	 (0x00000004) // Reserved
+#define NS7520_ETH_SUPP_JABBER	 (0x00000002) // Enable Jabber protection
+#define NS7520_ETH_SUPP_BITMODE	 (0x00000001) // Bit Mode
+
+// TEST Register Bit Fields
+
+#define NS7520_ETH_TEST_RES1	 (0xFFFFFFF8) // Reserved
+#define NS7520_ETH_TEST_TBACK	 (0x00000004) // Test backpressure
+#define NS7520_ETH_TEST_TPAUSE	 (0x00000002) // Test Pause
+#define NS7520_ETH_TEST_SPQ	 (0x00000001) // Shortcut pause quanta
+
+// MCFG MII Management Configuration Register Bit Fields
+
+#define NS7520_ETH_MCFG_RES1	 (0xFFFF0000) // Reserved
+#define NS7520_ETH_MCFG_RMIIM	 (0x00008000) // Reset MII management
+#define NS7520_ETH_MCFG_RES2	 (0x00007FE0) // Reserved
+#define NS7520_ETH_MCFG_CLKS_MA	 (0x0000001C) // Clock Select
+#define NS7520_ETH_MCFG_CLKS_4	 (0x00000004) // Sysclk / 4
+#define NS7520_ETH_MCFG_CLKS_6	 (0x00000008) // Sysclk / 6
+#define NS7520_ETH_MCFG_CLKS_8	 (0x0000000C) // Sysclk / 8
+#define NS7520_ETH_MCFG_CLKS_10	 (0x00000010) // Sysclk / 10
+#define NS7520_ETH_MCFG_CLKS_14	 (0x00000014) // Sysclk / 14
+#define NS7520_ETH_MCFG_CLKS_20	 (0x00000018) // Sysclk / 20
+#define NS7520_ETH_MCFG_CLKS_28	 (0x0000001C) // Sysclk / 28
+#define NS7520_ETH_MCFG_SPRE	 (0x00000002) // Suppress preamble
+#define NS7520_ETH_MCFG_SCANI	 (0x00000001) // Scan increment
+
+// MCMD MII Management Command Register Bit Fields
+
+#define NS7520_ETH_MCMD_RES1	 (0xFFFFFFFC) // Reserved
+#define NS7520_ETH_MCMD_SCAN	 (0x00000002) // Automatically Scan for Read Data
+#define NS7520_ETH_MCMD_READ	 (0x00000001) // Single scan for Read Data
+
+// MCMD MII Management Address Register Bit Fields
+
+#define NS7520_ETH_MADR_RES1	 (0xFFFFE000) // Reserved
+#define NS7520_ETH_MADR_DADR	 (0x00001F00) // MII PHY device address
+#define NS7520_ETH_MADR_RES2	 (0x000000E0) // Reserved
+#define NS7520_ETH_MADR_RADR	 (0x0000001F) // MII PHY register address
+
+// MWTD MII Management Write Data Register Bit Fields
+
+#define NS7520_ETH_MWTD_RES1	 (0xFFFF0000) // Reserved
+#define NS7520_ETH_MWTD_MWTD	 (0x0000FFFF) // MII Write Data
+
+// MRRD MII Management Read Data Register Bit Fields
+
+#define NS7520_ETH_MRRD_RES1	 (0xFFFF0000) // Reserved
+#define NS7520_ETH_MRRD_MRDD	 (0x0000FFFF) // MII Read Data
+
+// MIND MII Management Indicators Register Bit Fields
+
+#define NS7520_ETH_MIND_RES1	 (0xFFFFFFF8) // Reserved
+#define NS7520_ETH_MIND_NVALID	 (0x00000004) // Read Data not valid
+#define NS7520_ETH_MIND_SCAN	 (0x00000002) // Automatically scan for read data
+#define NS7520_ETH_MIND_BUSY	 (0x00000001) // MII interface busy
+
+// SMII Status Register Bit Fields
+
+#define NS7520_ETH_SMII_RES1	 (0xFFFFFFE0) // Reserved
+#define NS7520_ETH_SMII_CLASH	 (0x00000010) // MAC-to-MAC with PHY
+#define NS7520_ETH_SMII_JABBER	 (0x00000008) // Jabber condition present
+#define NS7520_ETH_SMII_LINK	 (0x00000004) // Link OK
+#define NS7520_ETH_SMII_DUPLEX	 (0x00000002) // Full-duplex operation
+#define NS7520_ETH_SMII_SPEED	 (0x00000001) // 100 Mbps
+
+// SA1 Station Address 1 Register Bit Fields
+
+#define NS7520_ETH_SA1_RES1	 (0xFFFF0000) // Reserved
+#define NS7520_ETH_SA1_OCTET1	 (0x0000FF00) // Station Address octet 1
+#define NS7520_ETH_SA1_OCTET2	 (0x000000FF) // Station Address octet 2
+
+// SA2 Station Address 2 Register Bit Fields
+
+#define NS7520_ETH_SA2_RES1	 (0xFFFF0000) // Reserved
+#define NS7520_ETH_SA2_OCTET3	 (0x0000FF00) // Station Address octet 3
+#define NS7520_ETH_SA2_OCTET4	 (0x000000FF) // Station Address octet 4
+
+// SA3 Station Address 3 Register Bit Fields
+
+#define NS7520_ETH_SA3_RES1	 (0xFFFF0000) // Reserved
+#define NS7520_ETH_SA3_OCTET5	 (0x0000FF00) // Station Address octet 5
+#define NS7520_ETH_SA3_OCTET6	 (0x000000FF) // Station Address octet 6
+
+// SAFR Station Address Filter Register Bit Fields
+
+#define NS7520_ETH_SAFR_RES1	 (0xFFFFFFF0) // Reserved
+#define NS7520_ETH_SAFR_PRO	 (0x00000008) // Enable Promiscuous mode
+#define NS7520_ETH_SAFR_PRM	 (0x00000004) // Accept ALL multicast packets
+#define NS7520_ETH_SAFR_PRA	 (0x00000002) // Accept multicast packets table
+#define NS7520_ETH_SAFR_BROAD	 (0x00000001) // Accept ALL Broadcast packets
+
+// HT1 Hash Table 1 Register Bit Fields
+
+#define NS7520_ETH_HT1_RES1	 (0xFFFF0000) // Reserved
+#define NS7520_ETH_HT1_HT1	 (0x0000FFFF) // CRC value 15-0
+
+// HT2 Hash Table 2 Register Bit Fields
+
+#define NS7520_ETH_HT2_RES1	 (0xFFFF0000) // Reserved
+#define NS7520_ETH_HT2_HT2	 (0x0000FFFF) // CRC value 31-16
+
+// HT3 Hash Table 3 Register Bit Fields
+
+#define NS7520_ETH_HT3_RES1	 (0xFFFF0000) // Reserved
+#define NS7520_ETH_HT3_HT3	 (0x0000FFFF) // CRC value 47-32
+
+// HT4 Hash Table 4 Register Bit Fields
+
+#define NS7520_ETH_HT4_RES1	 (0xFFFF0000) // Reserved
+#define NS7520_ETH_HT4_HT4	 (0x0000FFFF) // CRC value 63-48
+
+// PHY definitions (LXT971A)
+// TODO move it later to a file of it's own with all the code to handle the
+// registers
+
+#define PHY_COMMON_CTRL    	 (0x00)	      // Control Register
+#define PHY_COMMON_STAT    	 (0x01)	      // Status Register
+#define PHY_COMMON_ID1    	 (0x02)	      // PHY Identification Register 1
+#define PHY_COMMON_ID2           (0x03)       // PHY Identification Register 2
+#define PHY_COMMON_AUTO_ADV      (0x04)	      // Auto-neg Advert Reg
+#define PHY_COMMON_AUTO_LNKB     (0x05)	      // Auto-neg Link Ability Reg
+#define PHY_COMMON_AUTO_EXP      (0x06)       // Auto-neg expansion Reg
+#define PHY_COMMON_AUTO_NEXT     (0x07)       // Auto-neg Next Page Tx Reg
+#define PHY_COMMON_AUTO_LNKN     (0x08)       // Auto-neg Link Partner Rx Reg
+#define PHY_LXT971_PORT_CFG      (0x10)       // Port Configuration Register
+#define PHY_LXT971_STAT2         (0x11)       // Status Register #2
+#define PHY_LXT971_INT_ENABLE    (0x12)       // Interrupt Enable Register
+#define PHY_LXT971_INT_STATUS    (0x13)       // Interrupt Status Register
+#define PHY_LXT971_LED_CFG       (0x14)       // Interrupt LED Configuration
+#define PHY_LXT971_DIG_CFG       (0x1A)       // Digital Config Register
+#define PHY_LXT971_TX_CTRL       (0x1E)       // Transmit Control Register
+
+// CTRL PHY Control Register Bit Fields
+#define PHY_COMMON_CTRL_RESET  	 (0x8000)     // Reset PHY
+#define PHY_COMMON_CTRL_LOOPBACK (0x4000)     // Loopback mode
+#define PHY_COMMON_CTRL_SPD_MA   (0x2040)     // Speed Mask
+#define PHY_COMMON_CTRL_SPD_10   (0x0000)     // Speed 10 Mbps
+#define PHY_COMMON_CTRL_SPD_100  (0x2000)     // Speed 100 Mbps
+#define PHY_COMMON_CTRL_SPD_1000 (0x0040)     // Speed 1000 Mbps
+#define PHY_COMMON_CTRL_SPD_RES  (0x2040)     // Speed 1000 Mbps
+#define PHY_COMMON_CTRL_AUTO_NEG (0x1000)     // Auto Negotiation enable
+#define PHY_COMMON_CTRL_POWER_DN (0x0800)     // Power Down
+#define PHY_COMMON_CTRL_ISOLATE	 (0x0400)     // Isolate
+#define PHY_COMMON_CTRL_RES_AUTO (0x0200)     // Restart Auto-Negotation
+#define PHY_COMMON_CTRL_DUPLEX	 (0x0100)     // Full Duplex Mode  
+#define PHY_COMMON_CTRL_COL_TEST (0x0080)     // Collision Test
+#define PHY_COMMON_CTRL_RES1     (0x003F)     // Reserved
+
+// STAT Status Register Bit Fields
+
+#define PHY_COMMON_STAT_100BT4	 (0x8000)     // able to perform 100BaseT4
+#define PHY_COMMON_STAT_100BXFD	 (0x4000)     // able to perform 100BaseX full du
+#define PHY_COMMON_STAT_100BXHD	 (0x2000)     // able to perform 100BaseX half du
+#define PHY_COMMON_STAT_10BTFD	 (0x1000)     // able to perform 10BaseT full dup
+#define PHY_COMMON_STAT_10BTHD	 (0x0800)     // able to perform 10BaseT half dup
+#define PHY_COMMON_STAT_100BT2FD (0x0400)     // able to perform 100BaseT2 full d
+#define PHY_COMMON_STAT_100BT2HD (0x0200)     // able to perform 100BaseT2 half d
+#define PHY_COMMON_STAT_EXT_STAT (0x0100)     // extendes status register #15
+#define PHY_COMMON_STAT_RES1	 (0x0080)     // Reserved
+#define PHY_COMMON_STAT_MF_PSUP	 (0x0040)     // mangement frames preamble suppre
+#define PHY_COMMON_STAT_AN_COMP  (0x0020)     // Auto-negotation complete
+#define PHY_COMMON_STAT_RMT_FLT	 (0x0010)     // Remote Fault
+#define PHY_COMMON_STAT_AN_CAP	 (0x0008)     // Auto-negotiation capable
+#define PHY_COMMON_STAT_LNK_STAT (0x0004)     // Link Status (Up)
+#define PHY_COMMON_STAT_JAB_DTCT (0x0002)     // Jabber Condition detected
+#define PHY_COMMON_STAT_EXT_CAP	 (0x0001)     // Extendes Register Capabilities
+
+
+// AUTO_ADV Auto-neg Advert Register Bit Fields
+
+#define PHY_COMMON_AUTO_ADV_NP       	(0x8000) // send multiple pages
+#define PHY_COMMON_AUTO_ADV_RES1        (0x4000) // Reserved
+#define PHY_COMMON_AUTO_ADV_RMT_FLT     (0x2000) // Remote Fault
+#define PHY_COMMON_AUTO_ADV_RES2        (0x1000) // Reserved
+#define PHY_COMMON_AUTO_ADV_AS_PAUSE    (0x0800) // Pause operation
+#define PHY_COMMON_AUTO_ADV_PAUSE       (0x0400) // Pause
+#define PHY_COMMON_AUTO_ADV_100BT4      (0x0200) // 100 BaseT4
+#define PHY_COMMON_AUTO_ADV_100BTXFD   	(0x0100) // 100 BaseTX Full Duplex
+#define PHY_COMMON_AUTO_ADV_100BTX      (0x0080) // 100 Base TX capable
+#define PHY_COMMON_AUTO_ADV_10BTFD   	(0x0040) // 10 Base T Full Duplex
+#define PHY_COMMON_AUTO_ADV_10BT     	(0x0020) // 10 Base T Full Duplex
+#define PHY_COMMON_AUTO_ADV_SEL_FLD_MA  (0x001F) // Selector Field
+#define PHY_COMMON_AUTO_ADV_802_9       (0x0002) // 802.9
+#define PHY_COMMON_AUTO_ADV_802_3       (0x0001) // 802.3
+
+// AUTO_LNKB Auto-neg Link Ability Register Bit Fields
+
+#define PHY_COMMON_AUTO_LNKB_NP       	(0x8000) // send multiple pages
+#define PHY_COMMON_AUTO_LNKB_ACK        (0x4000) // Acknowledge
+#define PHY_COMMON_AUTO_LNKB_RMT_FLT    (0x2000) // Remote Fault
+#define PHY_COMMON_AUTO_LNKB_RES2       (0x1000) // Reserved
+#define PHY_COMMON_AUTO_LNKB_AS_PAUSE   (0x0800) // Pause operation
+#define PHY_COMMON_AUTO_LNKB_PAUSE      (0x0400) // Pause
+#define PHY_COMMON_AUTO_LNKB_100BT4     (0x0200) // 100 BaseT4
+#define PHY_COMMON_AUTO_LNKB_100BTXFD   (0x0100) // 100 BaseTX Full Duplex
+#define PHY_COMMON_AUTO_LNKB_100BTX     (0x0080) // 100 Base TX capable
+#define PHY_COMMON_AUTO_LNKB_10BTFD   	(0x0040) // 10 Base T Full Duplex
+#define PHY_COMMON_AUTO_LNKB_10BT     	(0x0020) // 10 Base T Full Duplex
+#define PHY_COMMON_AUTO_LNKB_SEL_FLD_MA (0x001F) // Selector Field
+#define PHY_COMMON_AUTO_LNKB_802_9      (0x0002) // 802.9
+#define PHY_COMMON_AUTO_LNKB_802_3      (0x0001) // 802.3
+
+// AUTO_EXP Auto-neg Expansion Register Bit Fields
+
+#define PHY_COMMON_AUTO_EXP_RES1        (0xFFC0) // Reserved
+#define PHY_COMMON_AUTO_EXP_BASE_PAGE   (0x0020) // Base Page
+#define PHY_COMMON_AUTO_EXP_PAR_DT_FLT  (0x0010) // Parallel detection fault
+#define PHY_COMMON_AUTO_EXP_LNK_NP_CAP  (0x0008) // Link Partner Nxt Page Cap
+#define PHY_COMMON_AUTO_EXP_NP_CAP      (0x0004) // Next Page Capable
+#define PHY_COMMON_AUTO_EXP_PAGE_REC    (0x0002) // Page Received
+#define PHY_COMMON_AUTO_EXP_LNK_AN_CAP  (0x0001) // Link Partner Auto Neg Cap
+
+// AUTO_NEXT Aut-neg Next Page Tx Register Bit Fields
+
+#define PHY_COMMON_AUTO_NEXT_NP         (0x8000) // Next Page
+#define PHY_COMMON_AUTO_NEXT_RES1       (0x4000) // Reserved
+#define PHY_COMMON_AUTO_NEXT_MSG_PAGE   (0x2000) // Message Page
+#define PHY_COMMON_AUTO_NEXT_ACK_2      (0x1000) // Acknowledge 2
+#define PHY_COMMON_AUTO_NEXT_TOGGLE     (0x0800) // Toggle
+#define PHY_COMMON_AUTO_NEXT_MSG        (0x07FF) // Message
+
+// AUTO_LNKN Auto-neg Link Partner Rx Reg Bit Fields
+
+#define PHY_COMMON_AUTO_LNKN_NP         (0x8000) // Next Page
+#define PHY_COMMON_AUTO_LNKN_ACK        (0x4000) // Acknowledge
+#define PHY_COMMON_AUTO_LNKN_MSG_PAGE   (0x2000) // Message Page
+#define PHY_COMMON_AUTO_LNKN_ACK_2      (0x1000) // Acknowledge 2
+#define PHY_COMMON_AUTO_LNKN_TOGGLE     (0x0800) // Toggle
+#define PHY_COMMON_AUTO_LNKN_MSG        (0x07FF) // Message
+
+// PORT_CFG Port Configuration Register Bit Fields
+
+#define PHY_LXT971_PORT_CFG_RES1        (0x8000) // Reserved
+#define PHY_LXT971_PORT_CFG_FORCE_LNK   (0x4000) // Force Link Pass
+#define PHY_LXT971_PORT_CFG_TX_DISABLE  (0x2000) // Transmit Disable
+#define PHY_LXT971_PORT_CFG_BYPASS_SCR  (0x1000) // Bypass Scrambler
+#define PHY_LXT971_PORT_CFG_RES2        (0x0800) // Reserved
+#define PHY_LXT971_PORT_CFG_JABBER      (0x0400) // Disable Jabber Correction
+#define PHY_LXT971_PORT_CFG_SQE	        (0x0200) // Enable Heart Beat
+#define PHY_LXT971_PORT_CFG_TP_LOOPBACK (0x0100) // Disable TP Loopack (10BT)
+#define PHY_LXT971_PORT_CFG_CRS_SEL     (0x0080) // CRS deasserts extends
+#define PHY_LXT971_PORT_CFG_SLEEP_MODE  (0x0040) // Enable Sleep Mode
+#define PHY_LXT971_PORT_CFG_PRE_EN      (0x0020) // Preamble Enable
+#define PHY_LXT971_PORT_CFG_SLEEP_T_MA  (0x0018) // Sleep Timer Mask
+#define PHY_LXT971_PORT_CFG_SLEEP_T_104 (0x0010) // Sleep Timer 1.04 seconds
+#define PHY_LXT971_PORT_CFG_SLEEP_T_200 (0x0001) // Sleep Timer 2 seconds
+#define PHY_LXT971_PORT_CFG_SLEEP_T_304 (0x0000) // Sleep Timer 3.04 seconds
+#define PHY_LXT971_PORT_CFG_FLT_CODE_EN (0x0004) // Fault Code Enable
+#define PHY_LXT971_PORT_CFG_ALT_NP      (0x0002) // Alternate NP
+#define PHY_LXT971_PORT_CFG_FIBER_SEL   (0x0001) // Fiber Select Mode
+
+// STAT2 Status Register #2 Bit Fields
+
+#define PHY_LXT971_STAT2_RES1   	(0x8000) // Reserved
+#define PHY_LXT971_STAT2_100BTX 	(0x4000) // operating in 100BaseTX
+#define PHY_LXT971_STAT2_TX_STATUS	(0x2000) // is transmitting a packet
+#define PHY_LXT971_STAT2_RX_STATUS	(0x1000) // is receiveing a packet
+#define PHY_LXT971_STAT2_COL_STATUS	(0x0800) // Collision is occuring
+#define PHY_LXT971_STAT2_LINK   	(0x0400) // Link is up
+#define PHY_LXT971_STAT2_DUPLEX_MODE	(0x0200) // Duplex Mode
+#define PHY_LXT971_STAT2_AUTO_NEG	(0x0100) // Auto negotiation process
+#define PHY_LXT971_STAT2_AUTO_NEG_COMP 	(0x0080) // Auto negotation complete
+#define PHY_LXT971_STAT2_RES2   	(0x0040) // Reserved
+#define PHY_LXT971_STAT2_POLARITY	(0x0020) // Polarity is reversed
+#define PHY_LXT971_STAT2_PAUSE  	(0x0010) // Device Pause capable
+#define PHY_LXT971_STAT2_ERROR  	(0x0008) // Error occured
+#define PHY_LXT971_STAT2_RES3   	(0x0007) // Reserved
+
+// INT_ENABLE Interrupt Enable Register Bit Fields
+
+#define PHY_LXT971_INT_ENABLE_RES1      (0xFF00) // Reserved
+#define PHY_LXT971_INT_ENABLE_ANMSK     (0x0080) // Mask For Auto Negotiate Compl
+#define PHY_LXT971_INT_ENABLE_SPEEDMSK  (0x0040) // Mask for Speed
+#define PHY_LXT971_INT_ENABLE_DUPLEXMSK (0x0020) // Mask for Duplex Mode
+#define PHY_LXT971_INT_ENABLE_LINKMSK   (0x0010) // Mask for Link Status
+#define PHY_LXT971_INT_ENABLE_RES2      (0x000C) // Reserved
+#define PHY_LXT971_INT_ENABLE_INTEN     (0x0002) // Interrupts Enable
+#define PHY_LXT971_INT_ENABLE_TINT      (0x0001) // Force Interrupt on MDINT
+
+// INT_STATUS Interrupt Status Register Bit Fields
+
+#define PHY_LXT971_INT_STATUS_RES1      (0xFF00) // Reserved
+#define PHY_LXT971_INT_STATUS_ANDONE    (0x0080) // Auto Negotiate Complete
+#define PHY_LXT971_INT_STATUS_SPEEDCHG  (0x0040) // Speed Change
+#define PHY_LXT971_INT_STATUS_DUPLEXCHG (0x0020) // Duplex Change
+#define PHY_LXT971_INT_STATUS_LINKCHG   (0x0010) // Link Status Change
+#define PHY_LXT971_INT_STATUS_RES2      (0x0008) // Reserved
+#define PHY_LXT971_INT_STATUS_MDINT     (0x0004) // MDINT pending
+#define PHY_LXT971_INT_STATUS_RES3      (0x0003) // Reserved
+
+// LED_CFG Interrupt LED Configuration Register Bit Fields
+
+#define PHY_LXT971_LED_CFG_SHIFT_LED1   (0x000C) // Shift LED1 Config left
+#define PHY_LXT971_LED_CFG_SHIFT_LED2   (0x0008) // Shift LED2 Config left
+#define PHY_LXT971_LED_CFG_SHIFT_LED3   (0x0004) // Shift LED3 Config left
+#define PHY_LXT971_LED_CFG_LEDFREQ_MA	(0x000C) // LED Frequency
+#define PHY_LXT971_LED_CFG_LEDFREQ_RES	(0x000C) // Reserved
+#define PHY_LXT971_LED_CFG_LEDFREQ_100	(0x0008) // Stretch 100ms
+#define PHY_LXT971_LED_CFG_LEDFREQ_60	(0x0004) // Stretch 60ms
+#define PHY_LXT971_LED_CFG_LEDFREQ_30	(0x0000) // Stretch 30ms
+#define PHY_LXT971_LED_CFG_PULSE_STR    (0x0002) // Disable Pulse Stretching
+#define PHY_LXT971_LED_CFG_RES1         (0x0001) // Reserved
+
+// only one of these values must be shifted for each SHIFT_LED? 
+
+#define PHY_LXT971_LED_CFG_UNUSED1      (0x000F) // Unused
+#define PHY_LXT971_LED_CFG_DUPLEX_COL   (0x000E) // Duplex and Collision
+#define PHY_LXT971_LED_CFG_LINK_ACT     (0x000D) // Link and Activiity
+#define PHY_LXT971_LED_CFG_LINK_RX      (0x000C) // Link and Receive
+#define PHY_LXT971_LED_CFG_TEST_BLK_SLW (0x000B) // Test Mode blink slow
+#define PHY_LXT971_LED_CFG_TEST_BLK_FST (0x000A) // Test Mode blink fast
+#define PHY_LXT971_LED_CFG_TEST_OFF     (0x0009) // Test Mode LED OFF
+#define PHY_LXT971_LED_CFG_TEST_ON      (0x0008) // Test Mode LED ON
+#define PHY_LXT971_LED_CFG_RX_OR_TX     (0x0007) // Receive or Transmit Status
+#define PHY_LXT971_LED_CFG_UNUSED2      (0x0006) // Unused
+#define PHY_LXT971_LED_CFG_DUPLEX       (0x0005) // Duplex Status
+#define PHY_LXT971_LED_CFG_LINK	        (0x0004) // Link Status
+#define PHY_LXT971_LED_CFG_COLLISION    (0x0003) // Collision Status
+#define PHY_LXT971_LED_CFG_RECEIVE      (0x0002) // Receive Status
+#define PHY_LXT971_LED_CFG_TRANSMIT     (0x0001) // Transmit Status
+#define PHY_LXT971_LED_CFG_SPEED        (0x0000) // Speed Status
+
+// DIG_CFG Digitial Configuration Register Bit Fields
+
+#define PHY_LXT971_DIG_CFG_RES1 	(0xF000) // Reserved
+#define PHY_LXT971_DIG_CFG_MII_DRIVE	(0x0800) // MII drive strength increase
+#define PHY_LXT971_DIG_CFG_RES2 	(0x0400) // Reserved
+#define PHY_LXT971_DIG_CFG_SHOW_SYMBOL	(0x0200) // Map Symbol Error to RXER
+#define PHY_LXT971_DIG_CFG_RES3 	(0x01FF) // Reserved
+
+#define PHY_LXT971_MDIO_MAX_CLK		8000000  // it is capable of 8 MHz
+
+// TX_CTRL Transmit Control Register Bit Fields
+// documentation is buggy for this register, therefore setting not included
+
+typedef enum 
+{
+    PHY_NONE    = 0x0000, // no PHY detected yet
+    PHY_LXT971A = 0x0013
+} PhyType;
+
+#define PHY_MDIO_MAX_CLK		2500000  // default is 2.5 MHz
+
+#define NS7520_ETH_PHY_ADDRESS   (0x0000)     // For Orthos we exploit the reserved address
+#ifndef NS7520_ETH_PHY_ADDRESS
+# define NS7520_ETH_PHY_ADDRESS	 (0x0100)     // suitable for UNC20
+#endif // NETARM_ETH_PHY_ADDRESS
+
+#endif // FS_NS7520_ETH_H
diff -urN linux-2.4.29/drivers/net/pci-scan.c linux-2.4.29-uc1/drivers/net/pci-scan.c
--- linux-2.4.29/drivers/net/pci-scan.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/pci-scan.c	2005-06-14 02:12:08.000000000 +0100
@@ -0,0 +1,580 @@
+/* pci-scan.c: Linux PCI network adapter support code. */
+/*
+	Originally written 1999-2001 by Donald Becker.
+
+	This software may be used and distributed according to the terms
+	of the GNU General Public License (GPL), incorporated herein by
+	reference.  Drivers interacting with these functions are derivative
+	works and thus are covered the GPL.  They must include an explicit
+	GPL notice.
+
+	This code provides common scan and activate functions for PCI network
+	interfaces.
+
+	The author may be reached as becker@scyld.com, or
+	Donald Becker
+	Scyld Computing Corporation
+	410 Severn Ave., Suite 210
+	Annapolis MD 21403
+
+	Other contributers:
+*/
+static const char version[] =
+"pci-scan.c:v1.08 9/28/2001  Donald Becker <becker@scyld.com>"
+" http://www.scyld.com/linux/drivers.html\n";
+
+/* A few user-configurable values that may be modified when a module. */
+
+static int debug = 1;			/* 1 normal messages, 0 quiet .. 7 verbose. */
+static int min_pci_latency = 32;
+
+#if ! defined(__KERNEL__)
+#define __KERNEL__ 1
+#endif
+#if !defined(__OPTIMIZE__)
+#warning  You must compile this file with the correct options!
+#warning  See the last lines of the source file.
+#error You must compile this driver with the proper options, including "-O".
+#endif
+
+#if defined(MODULE) && ! defined(EXPORT_SYMTAB)
+#define EXPORT_SYMTAB
+#endif
+
+#include <linux/config.h>
+#if defined(CONFIG_SMP) && ! defined(__SMP__)
+#define __SMP__
+#endif
+#if defined(MODULE) && defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS)
+#define MODVERSIONS
+#endif
+
+#include <linux/version.h>
+#include <linux/module.h>
+/* Older kernels do not include this automatically. */
+#if LINUX_VERSION_CODE < 0x20300  &&  defined(MODVERSIONS)
+#include <linux/modversions.h>
+#endif
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/malloc.h>
+#include <asm/io.h>
+#include "pci-scan.h"
+#include "kern_compat.h"
+#if defined(CONFIG_APM)  &&  LINUX_VERSION_CODE < 0x20400 
+#include <linux/apm_bios.h>
+#endif
+
+#if (LINUX_VERSION_CODE >= 0x20100) && defined(MODULE)
+char kernel_version[] = UTS_RELEASE;
+#endif
+#if (LINUX_VERSION_CODE < 0x20100)
+#define PCI_CAPABILITY_LIST	0x34	/* Offset of first capability list entry */
+#define PCI_STATUS_CAP_LIST	0x10	/* Support Capability List */
+#define PCI_CAP_ID_PM		0x01	/* Power Management */
+#endif
+
+int (*register_cb_hook)(struct drv_id_info *did);
+void (*unregister_cb_hook)(struct drv_id_info *did);
+
+#if LINUX_VERSION_CODE > 0x20118  &&  defined(MODULE)
+MODULE_PARM(debug, "i");
+MODULE_PARM(min_pci_latency, "i");
+#if defined(EXPORT_SYMTAB)
+EXPORT_SYMBOL_NOVERS(pci_drv_register);
+EXPORT_SYMBOL_NOVERS(pci_drv_unregister);
+EXPORT_SYMBOL_NOVERS(acpi_wake);
+EXPORT_SYMBOL_NOVERS(acpi_set_pwr_state);
+EXPORT_SYMBOL_NOVERS(register_cb_hook);
+EXPORT_SYMBOL_NOVERS(unregister_cb_hook);
+#endif
+#endif
+
+/* List of registered drivers. */
+static struct drv_id_info *drv_list;
+/* List of detected PCI devices, for APM events. */
+static struct dev_info {
+	struct dev_info *next;
+	void *dev;
+	struct drv_id_info *drv_id;
+	int flags;
+} *dev_list;
+
+/*
+  This code is not intended to support every configuration.
+  It is intended to minimize duplicated code by providing the functions
+  needed in almost every PCI driver.
+
+  The "no kitchen sink" policy:
+  Additional features and code will be added to this module only if more
+  than half of the drivers for common hardware would benefit from the feature.
+*/
+
+/*
+  Ideally we would detect and number all cards of a type (e.g. network) in
+  PCI slot order.
+  But that does not work with hot-swap card, CardBus cards and added drivers.
+  So instead we detect just the each chip table in slot order.
+
+  This routine takes a PCI ID table, scans the PCI bus, and calls the
+  associated attach/probe1 routine with the hardware already activated and
+  single I/O or memory address already mapped.
+
+  This routine will later be supplemented with CardBus and hot-swap PCI
+  support using the same table.  Thus the pci_chip_tbl[] should not be
+  marked as __initdata.
+*/
+
+#if LINUX_VERSION_CODE >= 0x20200
+/* Grrrr.. complex abstaction layers with negative benefit. */
+int pci_drv_register(struct drv_id_info *drv_id, void *initial_device)
+{
+	int chip_idx, cards_found = 0;
+	struct pci_dev *pdev = NULL;
+	struct pci_id_info *pci_tbl = drv_id->pci_dev_tbl;
+	struct drv_id_info *drv;
+	void *newdev;
+
+
+	/* Ignore a double-register attempt. */
+	for (drv = drv_list; drv; drv = drv->next)
+		if (drv == drv_id)
+			return -EBUSY;
+
+	while ((pdev = pci_find_class(drv_id->pci_class, pdev)) != 0) {
+		u32 pci_id, pci_subsys_id, pci_class_rev;
+		u16 pci_command, new_command;
+		int pci_flags;
+		long pciaddr;			/* Bus address. */
+		long ioaddr;			/* Mapped address for this processor. */
+
+		pci_read_config_dword(pdev, PCI_VENDOR_ID, &pci_id);
+		/* Offset 0x2c is PCI_SUBSYSTEM_ID aka PCI_SUBSYSTEM_VENDOR_ID. */
+		pci_read_config_dword(pdev, 0x2c, &pci_subsys_id);
+		pci_read_config_dword(pdev, PCI_REVISION_ID, &pci_class_rev);
+
+		if (debug > 3)
+			printk(KERN_DEBUG "PCI ID %8.8x subsystem ID is %8.8x.\n",
+				   pci_id, pci_subsys_id);
+		for (chip_idx = 0; pci_tbl[chip_idx].name; chip_idx++) {
+			struct pci_id_info *chip = &pci_tbl[chip_idx];
+			if ((pci_id & chip->id.pci_mask) == chip->id.pci
+				&& (pci_subsys_id&chip->id.subsystem_mask) == chip->id.subsystem
+				&& (pci_class_rev&chip->id.revision_mask) == chip->id.revision)
+				break;
+		}
+		if (pci_tbl[chip_idx].name == 0) 		/* Compiled out! */
+			continue;
+
+		pci_flags = pci_tbl[chip_idx].pci_flags;
+#if LINUX_VERSION_CODE >= 0x2030C
+		/* Wow. A oversized, hard-to-use abstraction. Bogus. */
+		pciaddr = pdev->resource[(pci_flags >> 4) & 7].start;
+#else
+		pciaddr = pdev->base_address[(pci_flags >> 4) & 7];
+#if defined(__alpha__)			/* Really any machine with 64 bit addressing. */
+		if (pci_flags & PCI_ADDR_64BITS)
+			pciaddr |= ((long)pdev->base_address[((pci_flags>>4)&7)+ 1]) << 32;
+#endif
+#endif
+		if (debug > 2)
+			printk(KERN_INFO "Found %s at PCI address %#lx, mapped IRQ %d.\n",
+				   pci_tbl[chip_idx].name, pciaddr, pdev->irq);
+
+		if ( ! (pci_flags & PCI_UNUSED_IRQ)  &&
+			 (pdev->irq == 0 || pdev->irq == 255)) {
+			if (pdev->bus->number == 32) 	/* Broken CardBus activation. */
+				printk(KERN_WARNING "Resources for CardBus device '%s' have"
+					   " not been allocated.\n"
+					   KERN_WARNING "Activation has been delayed.\n",
+					   pci_tbl[chip_idx].name);
+			else
+				printk(KERN_WARNING "PCI device '%s' was not assigned an "
+					   "IRQ.\n"
+					   KERN_WARNING "It will not be activated.\n",
+				   pci_tbl[chip_idx].name);
+			continue;
+		}
+		if ((pci_flags & PCI_BASE_ADDRESS_SPACE_IO)) {
+			ioaddr = pciaddr & PCI_BASE_ADDRESS_IO_MASK;
+			if (check_region(ioaddr, pci_tbl[chip_idx].io_size))
+				continue;
+		} else if ((ioaddr = (long)ioremap(pciaddr & PCI_BASE_ADDRESS_MEM_MASK,
+										   pci_tbl[chip_idx].io_size)) == 0) {
+			printk(KERN_INFO "Failed to map PCI address %#lx for device "
+				   "'%s'.\n", pciaddr, pci_tbl[chip_idx].name);
+			continue;
+		}
+		if ( ! (pci_flags & PCI_NO_ACPI_WAKE))
+			acpi_wake(pdev);
+		pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
+		new_command = pci_command | (pci_flags & 7);
+		if (pci_command != new_command) {
+			printk(KERN_INFO "  The PCI BIOS has not enabled the"
+				   " device at %d/%d!  Updating PCI command %4.4x->%4.4x.\n",
+				   pdev->bus->number, pdev->devfn, pci_command, new_command);
+			pci_write_config_word(pdev, PCI_COMMAND, new_command);
+		}
+
+		newdev = drv_id->probe1(pdev, initial_device,
+								ioaddr, pdev->irq, chip_idx, cards_found);
+		if (newdev == NULL)
+			continue;
+		initial_device = 0;
+		cards_found++;
+		if (pci_flags & PCI_COMMAND_MASTER) {
+			pci_set_master(pdev);
+			if ( ! (pci_flags & PCI_NO_MIN_LATENCY)) {
+				u8 pci_latency;
+				pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
+				if (pci_latency < min_pci_latency) {
+					printk(KERN_INFO "  PCI latency timer (CFLT) is "
+						   "unreasonably low at %d.  Setting to %d clocks.\n",
+						   pci_latency, min_pci_latency);
+					pci_write_config_byte(pdev, PCI_LATENCY_TIMER,
+										  min_pci_latency);
+				}
+			}
+		}
+		{
+			struct dev_info *devp =
+				kmalloc(sizeof(struct dev_info), GFP_KERNEL);
+			if (devp == 0)
+				continue;
+			devp->next = dev_list;
+			devp->dev = newdev;
+			devp->drv_id = drv_id;
+			dev_list = devp;
+		}
+	}
+
+	if (((drv_id->flags & PCI_HOTSWAP)
+		 && register_cb_hook && (*register_cb_hook)(drv_id) == 0)
+		|| cards_found) {
+		MOD_INC_USE_COUNT;
+		drv_id->next = drv_list;
+		drv_list = drv_id;
+		return 0;
+	} else
+		return -ENODEV;
+}
+#else
+int pci_drv_register(struct drv_id_info *drv_id, void *initial_device)
+{
+	int pci_index, cards_found = 0;
+	unsigned char pci_bus, pci_device_fn;
+	struct pci_dev *pdev;
+	struct pci_id_info *pci_tbl = drv_id->pci_dev_tbl;
+	void *newdev;
+
+	if ( ! pcibios_present())
+		return -ENODEV;
+
+	for (pci_index = 0; pci_index < 0xff; pci_index++) {
+		u32 pci_id, subsys_id, pci_class_rev;
+		u16 pci_command, new_command;
+		int chip_idx, irq, pci_flags;
+		long pciaddr;
+		long ioaddr;
+		u32 pci_busaddr;
+		u8 pci_irq_line;
+
+		if (pcibios_find_class (drv_id->pci_class, pci_index,
+								&pci_bus, &pci_device_fn)
+			!= PCIBIOS_SUCCESSFUL)
+			break;
+		pcibios_read_config_dword(pci_bus, pci_device_fn,
+								  PCI_VENDOR_ID, &pci_id);
+		/* Offset 0x2c is PCI_SUBSYSTEM_ID aka PCI_SUBSYSTEM_VENDOR_ID. */
+		pcibios_read_config_dword(pci_bus, pci_device_fn, 0x2c, &subsys_id);
+		pcibios_read_config_dword(pci_bus, pci_device_fn,
+								  PCI_REVISION_ID, &pci_class_rev);
+
+		for (chip_idx = 0; pci_tbl[chip_idx].name; chip_idx++) {
+			struct pci_id_info *chip = &pci_tbl[chip_idx];
+			if ((pci_id & chip->id.pci_mask) == chip->id.pci
+				&& (subsys_id & chip->id.subsystem_mask) == chip->id.subsystem
+				&& (pci_class_rev&chip->id.revision_mask) == chip->id.revision)
+				break;
+		}
+		if (pci_tbl[chip_idx].name == 0) 		/* Compiled out! */
+			continue;
+
+		pci_flags = pci_tbl[chip_idx].pci_flags;
+		pdev = pci_find_slot(pci_bus, pci_device_fn);
+		pcibios_read_config_byte(pci_bus, pci_device_fn,
+								 PCI_INTERRUPT_LINE, &pci_irq_line);
+		irq = pci_irq_line;
+		pcibios_read_config_dword(pci_bus, pci_device_fn,
+								  ((pci_flags >> 2) & 0x1C) + 0x10,
+								  &pci_busaddr);
+		pciaddr = pci_busaddr;
+#if defined(__alpha__)
+		if (pci_flags & PCI_ADDR_64BITS) {
+			pcibios_read_config_dword(pci_bus, pci_device_fn,
+									  ((pci_flags >> 2) & 0x1C) + 0x14,
+									  &pci_busaddr);
+			pciaddr |= ((long)pci_busaddr)<<32;
+		}
+#endif
+
+		if (debug > 2)
+			printk(KERN_INFO "Found %s at PCI address %#lx, IRQ %d.\n",
+				   pci_tbl[chip_idx].name, pciaddr, irq);
+
+		if ( ! (pci_flags & PCI_UNUSED_IRQ)  &&
+			 (irq == 0 || irq == 255)) {
+			if (pci_bus == 32) 	/* Broken CardBus activation. */
+				printk(KERN_WARNING "Resources for CardBus device '%s' have"
+					   " not been allocated.\n"
+					   KERN_WARNING "It will not be activated.\n",
+					   pci_tbl[chip_idx].name);
+			else
+				printk(KERN_WARNING "PCI device '%s' was not assigned an "
+					   "IRQ.\n"
+					   KERN_WARNING "It will not be activated.\n",
+				   pci_tbl[chip_idx].name);
+			continue;
+		}
+
+		if ((pciaddr & PCI_BASE_ADDRESS_SPACE_IO)) {
+			ioaddr = pciaddr & PCI_BASE_ADDRESS_IO_MASK;
+			if (check_region(ioaddr, pci_tbl[chip_idx].io_size))
+				continue;
+		} else if ((ioaddr = (long)ioremap(pciaddr & PCI_BASE_ADDRESS_MEM_MASK,
+										   pci_tbl[chip_idx].io_size)) == 0) {
+			printk(KERN_INFO "Failed to map PCI address %#lx.\n",
+				   pciaddr);
+			continue;
+		}
+
+		if ( ! (pci_flags & PCI_NO_ACPI_WAKE))
+			acpi_wake(pdev);
+		pcibios_read_config_word(pci_bus, pci_device_fn,
+								 PCI_COMMAND, &pci_command);
+		new_command = pci_command | (pci_flags & 7);
+		if (pci_command != new_command) {
+			printk(KERN_INFO "  The PCI BIOS has not enabled the"
+				   " device at %d/%d!  Updating PCI command %4.4x->%4.4x.\n",
+				   pci_bus, pci_device_fn, pci_command, new_command);
+			pcibios_write_config_word(pci_bus, pci_device_fn,
+									  PCI_COMMAND, new_command);
+		}
+
+		newdev = drv_id->probe1(pdev, initial_device,
+							   ioaddr, irq, chip_idx, cards_found);
+
+		if (newdev  && (pci_flags & PCI_COMMAND_MASTER)  &&
+			! (pci_flags & PCI_NO_MIN_LATENCY)) {
+			u8 pci_latency;
+			pcibios_read_config_byte(pci_bus, pci_device_fn,
+									 PCI_LATENCY_TIMER, &pci_latency);
+			if (pci_latency < min_pci_latency) {
+				printk(KERN_INFO "  PCI latency timer (CFLT) is "
+					   "unreasonably low at %d.  Setting to %d clocks.\n",
+					   pci_latency, min_pci_latency);
+				pcibios_write_config_byte(pci_bus, pci_device_fn,
+										  PCI_LATENCY_TIMER, min_pci_latency);
+			}
+		}
+		if (newdev) {
+			struct dev_info *devp =
+				kmalloc(sizeof(struct dev_info), GFP_KERNEL);
+			if (devp) {
+				devp->next = dev_list;
+				devp->dev = newdev;
+				devp->drv_id = drv_id;
+				dev_list = devp;
+			}
+		}
+		initial_device = 0;
+		cards_found++;
+	}
+
+	if (((drv_id->flags & PCI_HOTSWAP)
+		 && register_cb_hook && (*register_cb_hook)(drv_id) == 0)
+		|| cards_found) {
+		MOD_INC_USE_COUNT;
+		drv_id->next = drv_list;
+		drv_list = drv_id;
+		return 0;
+	} else
+		return cards_found ? 0 : -ENODEV;
+}
+#endif
+
+void pci_drv_unregister(struct drv_id_info *drv_id)
+{
+	struct drv_id_info **drvp;
+	struct dev_info **devip = &dev_list;
+
+	if (unregister_cb_hook)
+		(*unregister_cb_hook)(drv_id);
+
+	for (drvp = &drv_list; *drvp; drvp = &(*drvp)->next)
+		if (*drvp == drv_id) {
+			*drvp = (*drvp)->next;
+			MOD_DEC_USE_COUNT;
+			break;
+		}
+	while (*devip) {
+		struct dev_info *thisdevi = *devip;
+		if (thisdevi->drv_id == drv_id) {
+			*devip = thisdevi->next;
+			kfree(thisdevi);
+		} else
+			devip = &(*devip)->next;
+	}
+
+	return;
+}
+
+/*
+  Search PCI configuration space for the specified capability registers.
+  Return the index, or 0 on failure.
+*/
+static int pci_find_capability(struct pci_dev *pdev, int findtype)
+{
+	u16 pci_status, cap_type;
+	u8 pci_cap_idx;
+	int cap_idx;
+
+	pci_read_config_word(pdev, PCI_STATUS, &pci_status);
+	if ( ! (pci_status & PCI_STATUS_CAP_LIST))
+		return 0;
+	pci_read_config_byte(pdev, PCI_CAPABILITY_LIST, &pci_cap_idx);
+	cap_idx = pci_cap_idx;
+	for (cap_idx = pci_cap_idx; cap_idx; cap_idx = (cap_type >> 8) & 0xff) {
+		pci_read_config_word(pdev, cap_idx, &cap_type);
+		if ((cap_type & 0xff) == findtype)
+			return cap_idx;
+	}
+	return 0;
+}
+
+
+/* Change a device from D3 (sleep) to D0 (active).
+   Return the old power state.
+   This is more complicated than you might first expect since most cards
+   forget all PCI config info during the transition! */
+int acpi_wake(struct pci_dev *pdev)
+{
+	u32 base[5], romaddr;
+	u16 pci_command, pwr_command;
+	u8  pci_latency, pci_cacheline, irq;
+	int i, pwr_cmd_idx = pci_find_capability(pdev, PCI_CAP_ID_PM);
+
+	if (pwr_cmd_idx == 0)
+		return 0;
+	pci_read_config_word(pdev, pwr_cmd_idx + 4, &pwr_command);
+	if ((pwr_command & 3) == 0)
+		return 0;
+	pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
+	for (i = 0; i < 5; i++)
+		pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0 + i*4,
+								  &base[i]);
+	pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &romaddr);
+	pci_read_config_byte( pdev, PCI_LATENCY_TIMER, &pci_latency);
+	pci_read_config_byte( pdev, PCI_CACHE_LINE_SIZE, &pci_cacheline);
+	pci_read_config_byte( pdev, PCI_INTERRUPT_LINE, &irq);
+
+	pci_write_config_word(pdev, pwr_cmd_idx + 4, 0x0000);
+	for (i = 0; i < 5; i++)
+		if (base[i])
+			pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0 + i*4,
+									   base[i]);
+	pci_write_config_dword(pdev, PCI_ROM_ADDRESS, romaddr);
+	pci_write_config_byte( pdev, PCI_INTERRUPT_LINE, irq);
+	pci_write_config_byte( pdev, PCI_CACHE_LINE_SIZE, pci_cacheline);
+	pci_write_config_byte( pdev, PCI_LATENCY_TIMER, pci_latency);
+	pci_write_config_word( pdev, PCI_COMMAND, pci_command | 5);
+	return pwr_command & 3;
+}
+
+int acpi_set_pwr_state(struct pci_dev *pdev, enum acpi_pwr_state new_state)
+{
+	u16 pwr_command;
+	int pwr_cmd_idx = pci_find_capability(pdev, PCI_CAP_ID_PM);
+
+	if (pwr_cmd_idx == 0)
+		return 0;
+	pci_read_config_word(pdev, pwr_cmd_idx + 4, &pwr_command);
+	if ((pwr_command & 3) == ACPI_D3  &&  new_state != ACPI_D3)
+		acpi_wake(pdev);		/* The complicated sequence. */
+	pci_write_config_word(pdev, pwr_cmd_idx + 4,
+							  (pwr_command & ~3) | new_state);
+	return pwr_command & 3;
+}
+
+#if defined(CONFIG_APM)  &&  LINUX_VERSION_CODE < 0x20400 
+static int handle_apm_event(apm_event_t event)
+{
+	static int down = 0;
+	struct dev_info *devi;
+
+	if (debug > 1)
+		printk(KERN_DEBUG "pci-scan: Handling APM event %d for driver "
+			   "list %s...\n",
+			   event, drv_list->name);
+	return 0;
+	switch (event) {
+	case APM_SYS_SUSPEND:
+	case APM_USER_SUSPEND:
+		if (down) {
+			printk(KERN_DEBUG "pci-scan: Received extra suspend event\n");
+			break;
+		}
+		down = 1;
+		for (devi = dev_list; devi; devi = devi->next)
+			if (devi->drv_id->pwr_event)
+				devi->drv_id->pwr_event(devi->dev, DRV_SUSPEND);
+		break;
+	case APM_NORMAL_RESUME:
+	case APM_CRITICAL_RESUME:
+		if (!down) {
+			printk(KERN_DEBUG "pci-scan: Received bogus resume event\n");
+			break;
+		}
+		for (devi = dev_list; devi; devi = devi->next)
+			if (devi->drv_id->pwr_event)
+				devi->drv_id->pwr_event(devi->dev, DRV_RESUME);
+		down = 0;
+		break;
+	}
+	return 0;
+}
+#endif /* CONFIG_APM */
+
+#ifdef MODULE
+int init_module(void)
+{
+#if defined(CONFIG_APM)  &&  LINUX_VERSION_CODE < 0x20400 
+	apm_register_callback(&handle_apm_event);
+#endif
+	return 0;
+}
+void cleanup_module(void)
+{
+#if defined(CONFIG_APM)  &&  LINUX_VERSION_CODE < 0x20400 
+	apm_unregister_callback(&handle_apm_event);
+#endif
+	if (dev_list != NULL)
+		printk(KERN_WARNING "pci-scan: Unfreed device references.\n");
+	return;
+}
+#endif
+
+
+/*
+ * Local variables:
+ *  compile-command: "gcc -DMODULE -D__KERNEL__ -DEXPORT_SYMTAB -Wall -Wstrict-prototypes -O6 -c pci-scan.c"
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff -urN linux-2.4.29/drivers/net/pci-scan.h linux-2.4.29-uc1/drivers/net/pci-scan.h
--- linux-2.4.29/drivers/net/pci-scan.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/pci-scan.h	2005-06-14 02:12:11.000000000 +0100
@@ -0,0 +1,90 @@
+#ifndef _PCI_SCAN_H
+#define _PCI_SCAN_H
+/*
+  version 1.02 $Version:$ $Date: 2001/12/10 04:48:12 $
+   Copyright 1999-2001 Donald Becker / Scyld Computing Corporation
+   This software is part of the Linux kernel.  It may be used and
+   distributed according to the terms of the GNU Public License,
+   incorporated herein by reference.
+*/
+
+/*
+  These are the structures in the table that drives the PCI probe routines.
+  Note the matching code uses a bitmask: more specific table entries should
+  be placed before "catch-all" entries.
+
+  The table must be zero terminated.
+*/
+enum pci_id_flags_bits {
+	/* Set PCI command register bits before calling probe1(). */
+	PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
+	/* Read and map the single following PCI BAR. */
+	PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4,
+	PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400,
+	PCI_UNUSED_IRQ=0x800,
+};
+
+struct pci_id_info {
+	const char *name;
+	struct match_info {
+		int	pci, pci_mask, subsystem, subsystem_mask;
+		int revision, revision_mask; 				/* Only 8 bits. */
+	} id;
+	enum pci_id_flags_bits pci_flags;
+	int io_size;				/* Needed for I/O region check or ioremap(). */
+	int drv_flags;				/* Driver use, intended as capability flags. */
+};
+
+enum drv_id_flags {
+	PCI_HOTSWAP=1, /* Leave module loaded for Cardbus-like chips. */
+};
+enum drv_pwr_action {
+	DRV_NOOP,			/* No action. */
+	DRV_ATTACH,			/* The driver may expect power ops. */
+	DRV_SUSPEND,		/* Machine suspending, next event RESUME or DETACH. */
+	DRV_RESUME,			/* Resume from previous SUSPEND  */
+	DRV_DETACH,			/* Card will-be/is gone. Valid from SUSPEND! */
+	DRV_PWR_WakeOn,		/* Put device in e.g. Wake-On-LAN mode. */
+	DRV_PWR_DOWN,		/* Go to lowest power mode. */
+	DRV_PWR_UP,			/* Go to normal power mode. */
+};
+
+struct drv_id_info {
+	const char *name;			/* Single-word driver name. */
+	int flags;
+	int pci_class;				/* Typically PCI_CLASS_NETWORK_ETHERNET<<8. */
+	struct pci_id_info *pci_dev_tbl;
+	void *(*probe1)(struct pci_dev *pdev, void *dev_ptr,
+					long ioaddr, int irq, int table_idx, int fnd_cnt);
+	/* Optional, called for suspend, resume and detach. */
+	int (*pwr_event)(void *dev, int event);
+	/* Internal values. */
+	struct drv_id_info *next;
+	void *cb_ops;
+};
+
+/*  PCI scan and activate.
+	Scan PCI-like hardware, calling probe1(..,dev,..) on devices that match.
+	Returns -ENODEV, a negative number, if no cards are found. */
+
+extern int pci_drv_register(struct drv_id_info *drv_id, void *initial_device);
+extern void pci_drv_unregister(struct drv_id_info *drv_id);
+
+
+/*  ACPI routines.
+	Wake (change to ACPI D0 state) or set the ACPI power level of a sleeping
+	ACPI device.  Returns the old power state.  */
+
+int acpi_wake(struct pci_dev *pdev);
+enum  acpi_pwr_state {ACPI_D0, ACPI_D1, ACPI_D2, ACPI_D3};
+int acpi_set_pwr_state(struct pci_dev *pdev, enum acpi_pwr_state state);
+
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
+#endif
diff -urN linux-2.4.29/drivers/net/pcnet32.c linux-2.4.29-uc1/drivers/net/pcnet32.c
--- linux-2.4.29/drivers/net/pcnet32.c	2005-01-19 14:09:56.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/pcnet32.c	2005-06-14 02:12:15.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: pcnet32.c,v 1.21 2003/11/12 05:11:28 yoshfuji Exp $ */
+
 /* pcnet32.c: An AMD PCnet32 ethernet driver for linux. */
 /*
  *	Copyright 1996-1999 Thomas Bogendoerfer
@@ -47,6 +49,10 @@
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 
+#ifdef CONFIG_LEDMAN
+#include <linux/ledman.h>
+#endif
+
 #include <asm/bitops.h>
 #include <asm/dma.h>
 #include <asm/io.h>
@@ -1696,6 +1702,11 @@
     int entry;
     unsigned long flags;
 
+#ifdef CONFIG_LEDMAN
+    ledman_cmd(LEDMAN_CMD_SET,
+	(dev->name[3] == '0') ? LEDMAN_LAN1_TX : LEDMAN_LAN2_TX);
+#endif
+
     spin_lock_irqsave(&lp->lock, flags);
 
     if (netif_msg_tx_queued(lp)) {
@@ -1915,6 +1926,11 @@
     int entry = lp->cur_rx & RX_RING_MOD_MASK;
     int boguscnt = RX_RING_SIZE / 2;
 
+#ifdef CONFIG_LEDMAN
+    ledman_cmd(LEDMAN_CMD_SET,
+	(dev->name[3] == '0') ? LEDMAN_LAN1_RX : LEDMAN_LAN2_RX);
+#endif
+
     /* If we own the next entry, it's a new packet. Send it up. */
     while ((short)le16_to_cpu(lp->rx_ring[entry].status) >= 0) {
 	int status = (short)le16_to_cpu(lp->rx_ring[entry].status) >> 8;
@@ -1950,6 +1966,9 @@
 		lp->stats.rx_errors++;
 	    } else {
 		int rx_in_place = 0;
+#ifdef CONFIG_PCNET32_VMWARE
+		int rx_revbytes = 0;
+#endif
 
 		if (pkt_len > rx_copybreak) {
 		    struct sk_buff *newskb;
@@ -2004,10 +2023,23 @@
 			    pkt_len,0);
 		}
 		lp->stats.rx_bytes += skb->len;
+#ifdef CONFIG_PCNET32_VMWARE
+		rx_revbytes = skb->len;
+#endif
 		skb->protocol=eth_type_trans(skb,dev);
+#ifdef CONFIG_PCNET32_VMWARE
+		if (skb->protocol == 0) {
+			dev_kfree_skb(skb);
+			lp->stats.rx_bytes -= rx_revbytes;
+		} else {
+			netif_rx(skb);
+			lp->stats.rx_packets++;
+		}
+#else
 		netif_rx(skb);
 		dev->last_rx = jiffies;
 		lp->stats.rx_packets++;
+#endif
 	    }
 	}
 	/*
diff -urN linux-2.4.29/drivers/net/ppp_async.c linux-2.4.29-uc1/drivers/net/ppp_async.c
--- linux-2.4.29/drivers/net/ppp_async.c	2005-01-19 14:09:56.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/ppp_async.c	2005-06-14 02:12:12.000000000 +0100
@@ -996,7 +996,7 @@
 	data += 4;
 	dlen -= 4;
 	/* data[0] is code, data[1] is length */
-	while (dlen >= 2 && dlen >= data[1]) {
+	while (dlen >= 2 && dlen >= data[1] && data[1] >= 2) {
 		switch (data[0]) {
 		case LCP_MRU:
 			val = (data[2] << 8) + data[3];
diff -urN linux-2.4.29/drivers/net/ppp_generic.c linux-2.4.29-uc1/drivers/net/ppp_generic.c
--- linux-2.4.29/drivers/net/ppp_generic.c	2003-08-25 12:44:42.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/ppp_generic.c	2005-06-14 02:12:13.000000000 +0100
@@ -1031,7 +1031,10 @@
 	/* try to do packet compression */
 	if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
 	    && proto != PPP_LCP && proto != PPP_CCP) {
-		new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len,
+		int comp_overhead = (ppp->xcomp->compress_proto == CI_MPPE) ?
+			4 : 0;
+		new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len
+				    + comp_overhead,
 				    GFP_ATOMIC);
 		if (new_skb == 0) {
 			printk(KERN_ERR "PPP: no memory (comp pkt)\n");
@@ -1044,7 +1047,8 @@
 		/* compressor still expects A/C bytes in hdr */
 		len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
 					   new_skb->data, skb->len + 2,
-					   ppp->dev->mtu + PPP_HDRLEN);
+					   ppp->dev->mtu + PPP_HDRLEN + 
+					   comp_overhead);
 		if (len > 0 && (ppp->flags & SC_CCP_UP)) {
 			kfree_skb(skb);
 			skb = new_skb;
@@ -1323,9 +1327,9 @@
 {
 	ppp_recv_lock(ppp);
 	/* ppp->dev == 0 means interface is closing down */
-	if (ppp->dev != 0)
+	if (ppp->dev != 0) {
 		ppp_receive_frame(ppp, skb, pch);
-	else
+	} else
 		kfree_skb(skb);
 	ppp_recv_unlock(ppp);
 }
@@ -2071,6 +2075,25 @@
 		}
 		break;
 
+	case CCP_RESETREQ:
+		if ((ppp->flags & SC_CCP_UP) == 0)
+			break;
+		/*
+		 * not all MPPE implementations ACK reset requests so we
+		 * have to assume they will,  which is ok as MPPE doesn't
+		 * ever need resetting any way
+		 */
+		if (!inbound && 
+ 		((ppp->xcomp && (ppp->xcomp->compress_proto == CI_MPPE)) 
+ 		|| (ppp->rcomp && (ppp->rcomp->compress_proto == CI_MPPE)))) {
+
+			if (ppp->rc_state && (ppp->rstate & SC_DECOMP_RUN)) {
+				ppp->rcomp->decomp_reset(ppp->rc_state);
+				ppp->rstate &= ~SC_DC_ERROR;
+			}
+		}
+		break;
+
 	case CCP_RESETACK:
 		/* reset the [de]compressor */
 		if ((ppp->flags & SC_CCP_UP) == 0)
diff -urN linux-2.4.29/drivers/net/ppp_mppe.c linux-2.4.29-uc1/drivers/net/ppp_mppe.c
--- linux-2.4.29/drivers/net/ppp_mppe.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/ppp_mppe.c	2005-06-14 02:12:09.000000000 +0100
@@ -0,0 +1,677 @@
+/*
+ *  ==FILEVERSION 9906180==
+ *
+ * ppp_mppe.c - MPPE "compressor/decompressor" module.
+ *
+ * Copyright (c) 1994 Árpád Magosányi <mag@bunuel.tii.matav.hu>
+ * All rights reserved.
+ * Copyright (c) 1999 Tim Hockin, Cobalt Networks Inc. <thockin@cobaltnet.com>
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation is hereby granted, provided that the above copyright
+ * notice appears in all copies.  This software is provided without any
+ * warranty, express or implied. The Australian National University
+ * makes no representations about the suitability of this software for
+ * any purpose.
+ *
+ * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
+ * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+ * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
+ * OR MODIFICATIONS.
+ *
+ * From: deflate.c,v 1.1 1996/01/18 03:17:48 paulus Exp
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/slab.h>
+
+#undef VERSION
+/* a nice define to generate linux version numbers */
+#define VERSION(major,minor,patch) (((((major)<<8)+(minor))<<8)+(patch))
+
+#if LINUX_VERSION_CODE >= VERSION(2,1,4)
+#include <linux/vmalloc.h>
+#endif
+#include <linux/errno.h>
+#include <linux/sched.h>	/* to get the struct task_struct */
+#include <linux/string.h>	/* used in new tty drivers */
+#include <linux/signal.h>	/* used in new tty drivers */
+
+#include <asm/system.h>
+
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/inet.h>
+#include <linux/ioctl.h>
+#include <linux/init.h>
+
+#include <linux/ppp_defs.h>
+#include <linux/ppp-comp.h>
+#include "rc4_enc.c"
+#include "rc4_skey.c"
+#include "sha1dgst.c"
+#include "mppe.h"
+
+/*
+ * State for a mppe "(de)compressor".
+ */
+struct ppp_mppe_state {
+    unsigned int	ccount; /*coherency count */
+    RC4_KEY		RC4_send_key; /* chap-ms-v2 dictates 2 keys */
+    RC4_KEY		RC4_recv_key;
+    unsigned char	session_send_key[16];
+    unsigned char	session_recv_key[16];
+    unsigned char	master_send_key[16];
+    unsigned char	master_recv_key[16];
+    int			keylen;
+    int                 stateless;
+    int                 decomp_error;
+    unsigned int	bits;
+    int			unit;
+    int			debug;
+    int			mru;
+    struct compstat 	stats;
+};
+
+#define MPPE_CCOUNT_FROM_PACKET(ibuf)	((((ibuf)[4] & 0x0f) << 8) + (ibuf)[5])
+#define MPPE_BITS(ibuf) 	((ibuf)[4] & 0xf0 )
+#define MPPE_CTRLHI(state)	((((state)->ccount & 0xf00)>>8)|((state)->bits))
+#define MPPE_CTRLLO(state)	((state)->ccount & 0xff)
+ 
+#define MPPE_OVHD		4
+
+/* Procedures from the MPPE draft */
+
+/*
+ * Pads used in key derivation
+ */
+static unsigned char  SHAPad1[40] =
+        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static unsigned char  SHAPad2[40] =
+        {0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+         0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+         0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+         0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2};
+
+/*
+ * SHAInit(), SHAUpdate() and SHAFinal() functions are an
+ * implementation of Secure Hash Algorithm (SHA-1) [7]. These are
+ * available in public domain or can be licensed from
+ * RSA Data Security, Inc.
+ *
+ * 1) H is 8 bytes long for 40 bit session keys.
+ * 2) H is 16 bytes long for 128 bit session keys.
+ * 3) H' is same as H when this routine is called for the first time
+ *    for the session.
+ * 4) The generated key is returned in H'. This is the "current" key.
+ */
+static void
+GetNewKeyFromSHA(StartKey, SessionKey, SessionKeyLength, InterimKey)
+    unsigned char *StartKey;
+    unsigned char *SessionKey;
+    unsigned long SessionKeyLength;
+    unsigned char *InterimKey;
+{
+    SHA_CTX Context;
+    unsigned char Digest[SHA_DIGEST_LENGTH];
+
+    SHA1_Init(&Context);
+    SHA1_Update(&Context, StartKey, SessionKeyLength);
+    SHA1_Update(&Context, SHAPad1, 40);
+    SHA1_Update(&Context, SessionKey, SessionKeyLength);
+    SHA1_Update(&Context, SHAPad2, 40);
+    SHA1_Final(Digest,&Context);
+    memcpy(InterimKey, Digest, SessionKeyLength);
+}
+
+static void
+mppe_synchronize_key(struct ppp_mppe_state *state)
+{
+    /* get new keys and flag our state as such */
+    RC4_set_key(&(state->RC4_send_key),state->keylen,state->session_send_key);
+    RC4_set_key(&(state->RC4_recv_key),state->keylen,state->session_recv_key);
+
+    state->bits=MPPE_BIT_FLUSHED|MPPE_BIT_ENCRYPTED;
+}
+
+
+static void
+mppe_initialize_key(struct ppp_mppe_state *state)
+{
+    /* generate new session keys */
+    GetNewKeyFromSHA(state->master_send_key, state->master_send_key,
+	state->keylen, state->session_send_key);
+    GetNewKeyFromSHA(state->master_recv_key, state->master_recv_key,
+	state->keylen, state->session_recv_key);
+
+    if(state->keylen == 8) {
+	/* cripple them from 64bit->40bit */
+        state->session_send_key[0]=state->session_recv_key[0] = MPPE_40_SALT0;
+        state->session_send_key[1]=state->session_recv_key[1] = MPPE_40_SALT1;
+        state->session_send_key[2]=state->session_recv_key[2] = MPPE_40_SALT2;
+    }
+
+    mppe_synchronize_key(state);
+}
+
+
+static void
+mppe_change_key(struct ppp_mppe_state *state)
+{
+    unsigned char InterimSendKey[16];
+    unsigned char InterimRecvKey[16];
+
+    /* get temp keys */
+    GetNewKeyFromSHA(state->master_send_key, state->session_send_key,
+	state->keylen, InterimSendKey);
+    GetNewKeyFromSHA(state->master_recv_key, state->session_recv_key,
+	state->keylen, InterimRecvKey);
+
+    /* build RC4 keys from the temp keys */
+    RC4_set_key(&(state->RC4_send_key), state->keylen, InterimSendKey);
+    RC4_set_key(&(state->RC4_recv_key), state->keylen, InterimRecvKey);
+
+    /* make new session keys */
+    RC4(&(state->RC4_send_key), state->keylen, InterimSendKey,
+	state->session_send_key);
+    RC4(&(state->RC4_recv_key), state->keylen, InterimRecvKey,
+	state->session_recv_key);
+
+    if(state->keylen == 8)
+    {
+	/* cripple them from 64->40 bits*/
+        state->session_send_key[0]=state->session_recv_key[0] = MPPE_40_SALT0;
+        state->session_send_key[1]=state->session_recv_key[1] = MPPE_40_SALT1;
+        state->session_send_key[2]=state->session_recv_key[2] = MPPE_40_SALT2;
+    }
+
+    /* make the final rc4 keys */
+    RC4_set_key(&(state->RC4_send_key), state->keylen, state->session_send_key);
+    RC4_set_key(&(state->RC4_recv_key), state->keylen, state->session_recv_key);
+
+    state->bits |= MPPE_BIT_FLUSHED; 
+}
+
+
+#ifdef DEBUG
+/* Utility procedures to print a buffer in hex/ascii */
+static void
+ppp_print_hex (register __u8 *out, const __u8 *in, int count)
+{
+	register __u8 next_ch;
+	static char hex[] = "0123456789ABCDEF";
+
+	while (count-- > 0) {
+		next_ch = *in++;
+		*out++ = hex[(next_ch >> 4) & 0x0F];
+		*out++ = hex[next_ch & 0x0F];
+		++out;
+	}
+}
+
+
+static void
+ppp_print_char (register __u8 *out, const __u8 *in, int count)
+{
+	register __u8 next_ch;
+
+	while (count-- > 0) {
+		next_ch = *in++;
+
+		if (next_ch < 0x20 || next_ch > 0x7e)
+			*out++ = '.';
+		else {
+			*out++ = next_ch;
+			if (next_ch == '%')   /* printk/syslogd has a bug !! */
+				*out++ = '%';
+		}
+	}
+	*out = '\0';
+}
+
+
+static void
+ppp_print_buffer (const __u8 *name, const __u8 *buf, int count)
+{
+	__u8 line[44];
+
+	if (name != (__u8 *) NULL)
+		printk (KERN_DEBUG "ppp: %s, count = %d\n", name, count);
+
+	while (count > 8) {
+		memset (line, 32, 44);
+		ppp_print_hex (line, buf, 8);
+		ppp_print_char (&line[8 * 3], buf, 8);
+		printk (KERN_DEBUG "%s\n", line);
+		count -= 8;
+		buf += 8;
+	}
+
+	if (count > 0) {
+		memset (line, 32, 44);
+		ppp_print_hex (line, buf, count);
+		ppp_print_char (&line[8 * 3], buf, count);
+		printk (KERN_DEBUG "%s\n", line);
+	}
+}
+#endif
+
+/* our 'compressor' proper */
+static void	*mppe_comp_alloc __P((unsigned char *, int));
+static void	mppe_comp_free __P((void *));
+static int	mppe_comp_init __P((void *, unsigned char *,
+					int, int, int, int));
+static int	mppe_decomp_init __P((void *, unsigned char *,
+					int, int, int, int, int));
+static int	mppe_compress __P((void *, unsigned char *,
+					unsigned char *, int, int));
+static void	mppe_incomp __P((void *, unsigned char *, int));
+static int	mppe_decompress __P((void *, unsigned char *,
+					int, unsigned char *, int));
+static void	mppe_comp_reset __P((void *));
+static void	mppe_comp_stats __P((void *, struct compstat *));
+
+
+/* cleanup the compressor */
+static void
+mppe_comp_free(void *arg)
+{
+    struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+
+    if (state) {
+	    kfree(state);
+	    MOD_DEC_USE_COUNT;
+    }
+}
+
+
+/* allocate space for a compressor.  */
+static void *
+mppe_comp_alloc(unsigned char *options, int opt_len)
+{
+    struct ppp_mppe_state *state;
+
+    if (((2*8)+3 != opt_len && (2*16)+3 != opt_len) /* 2 keys + 3 */ 
+       || options[0] != CI_MPPE || options[1] != CILEN_MPPE) {
+	    printk(KERN_DEBUG "compress rejected: opt_len=%u,o[0]=%x,o[1]=%x\n",
+		opt_len,options[0],options[1]);
+	    return NULL;
+    }
+
+    state = (struct ppp_mppe_state *)kmalloc(sizeof(*state), GFP_KERNEL);
+    if (state == NULL)
+	return NULL;
+
+    MOD_INC_USE_COUNT;
+
+    memset (state, 0, sizeof (struct ppp_mppe_state));
+
+    /* write the data in options to the right places */
+    memcpy(&state->stateless,options+2,1);
+
+    state->keylen = (opt_len-3)/2;
+    memcpy(state->master_send_key,options+3,state->keylen);
+    memcpy(state->master_recv_key,options+3+state->keylen,state->keylen);
+
+    mppe_initialize_key(state);
+
+    return (void *) state;
+}
+
+
+static int
+mppe_comp_init(void *arg, unsigned char *options, int opt_len, int unit, 
+		int hdrlen, int debug)
+{
+    struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
+
+    if (options[0] != CI_MPPE || options[1] != CILEN_MPPE) {
+    	printk(KERN_DEBUG "compress rejected: opt_len=%u,o[0]=%x,o[1]=%x\n",
+	    opt_len,options[0],options[1]);
+	return 0;
+    }
+
+    state->ccount = 0;
+    state->unit  = unit;
+    state->debug = debug;
+
+    /* 19 is the min (2*keylen) + 3 */
+    if(opt_len >= 19) {
+        memcpy(&state->stateless,options+2,1);
+
+    	state->keylen = (opt_len-3)/2;
+    	memcpy(state->master_send_key,options+3,state->keylen);
+    	memcpy(state->master_recv_key,options+3+state->keylen,state->keylen);
+
+    	mppe_initialize_key(state);
+    }
+
+    return 1;
+}
+
+
+static int
+mppe_decomp_init(void *arg, unsigned char *options, int opt_len, int unit,
+		int hdrlen, int mru, int debug)
+{
+    struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
+
+    if (options[0] != CI_MPPE || options[1] != CILEN_MPPE) {
+	printk(KERN_DEBUG"options are bad: %x %x\n",options[0],options[1]);
+	return 0;
+    }
+
+    state->ccount = 0;
+    state->unit  = unit;
+    state->debug = debug;
+    state->mru = mru;
+
+    /* 19 is the min (2*keylen)+3 */
+    if(opt_len >= 19) {
+	memcpy(&state->stateless,options+2,1);
+
+	state->keylen = (opt_len-3)/2;
+	memcpy(state->master_send_key,options+3,state->keylen);
+	memcpy(state->master_recv_key,options+3+state->keylen,state->keylen);
+
+	mppe_initialize_key(state);
+    }
+
+    return 1;
+}
+
+
+static void
+mppe_comp_reset(void *arg)
+{
+    struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
+
+    printk(KERN_DEBUG "mppe_comp_reset\n");
+
+    (state->stats).in_count = 0;
+    (state->stats).bytes_out = 0;
+    (state->stats).ratio = 0;
+
+    mppe_synchronize_key(state);
+}
+
+
+static void
+mppe_update_count(struct ppp_mppe_state *state)
+{
+    if(!state->stateless)
+    {
+        if ( 0xff == (state->ccount&0xff)){ 
+	    /* time to change keys */
+	    if ( 0xfff == (state->ccount&0xfff)){
+		state->ccount = 0;
+	    } else {
+		(state->ccount)++;
+	    }
+	    mppe_change_key(state);
+        } else {
+            state->ccount++;
+        }
+    } else {
+        if ( 0xFFF == (state->ccount & 0xFFF)) {
+	    state->ccount = 0;
+        } else {
+	    (state->ccount)++;
+	}
+       	mppe_change_key(state);
+    }
+}
+
+
+/* the big nasty */
+int
+mppe_compress(void *arg, unsigned char *rptr, unsigned char *obuf, 
+		int isize, int osize)
+{
+    struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+    int proto, olen;
+    unsigned char *wptr;
+
+#ifdef DEBUG
+    ppp_print_buffer("mppe_encrypt",rptr,isize);
+#endif
+
+    if(osize < isize+MPPE_OVHD) {
+	printk(KERN_DEBUG "Not enough space to encrypt packet: %d<%d+%d!\n",
+		osize, isize, MPPE_OVHD);
+	return 0;
+    }
+
+    /* Check that the protocol is in the range we handle. */
+    proto = PPP_PROTOCOL(rptr);
+    if (proto < 0x0021 || proto > 0x00FA )
+	return 0;
+
+    wptr = obuf;
+
+    /* Copy over the PPP header and store the 2-byte sequence number. */
+    wptr[0] = PPP_ADDRESS(rptr);
+    wptr[1] = PPP_CONTROL(rptr);
+    wptr[2] = PPP_MPPE >>8;
+    wptr[3] = PPP_MPPE;
+    wptr += PPP_HDRLEN;
+    wptr[0] = MPPE_CTRLHI(state);
+    wptr[1] = MPPE_CTRLLO(state);
+    wptr += 2;
+
+    state->bits=MPPE_BIT_ENCRYPTED;
+    mppe_update_count(state);
+
+    /* read from rptr, write to wptr adjust for PPP_HDRLEN */
+    RC4(&(state->RC4_send_key),isize-2,rptr+2,wptr);
+    olen=isize+MPPE_OVHD;
+
+    (state->stats).comp_bytes += isize;
+    (state->stats).comp_packets++;
+
+#ifdef DEBUG
+    ppp_print_buffer("mppe_encrypt out",obuf,olen);
+#endif
+
+    return olen;
+}
+
+
+static void
+mppe_comp_stats(void *arg, struct compstat *stats)
+{
+    struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
+
+    /* since we don't REALLY compress at all, this should be OK */
+    (state->stats).in_count = (state->stats).unc_bytes;
+    (state->stats).bytes_out = (state->stats).comp_bytes;
+
+    /* this _SHOULD_ always be 1 */
+    (state->stats).ratio = (state->stats).in_count/(state->stats).bytes_out;
+
+    *stats = state->stats;
+   
+}
+
+
+/* the other big nasty */
+int
+mppe_decompress(void *arg, unsigned char *ibuf, int isize, 
+		unsigned char *obuf, int osize)
+{
+    struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
+    int seq;
+
+    if (isize <= PPP_HDRLEN + MPPE_OVHD) {
+	if (state->debug) {
+	    printk(KERN_DEBUG "mppe_decompress%d: short packet (len=%d)\n",
+		state->unit, isize);
+	}
+
+	return DECOMP_ERROR;
+    }
+    
+    if(osize < isize - MPPE_OVHD) {
+	printk(KERN_DEBUG "mppe_decompress%d: encrypted packet is too big: %d<%d-%d!\n",
+		state->unit, osize, isize, MPPE_OVHD);
+	return DECOMP_ERROR;
+    }
+
+    /* Check the sequence number. */
+    seq = MPPE_CCOUNT_FROM_PACKET(ibuf);
+
+    if(!state->stateless && (MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED)) {
+        state->decomp_error = 0;
+        state->ccount = seq;
+    }
+
+    if(state->decomp_error) {
+        return DECOMP_ERROR;
+    }
+
+    if (seq != state->ccount) {
+	if (state->debug) {
+	    printk(KERN_DEBUG "mppe_decompress%d: bad seq # %d, expected %d\n",
+		   state->unit, seq, state->ccount);
+	}
+
+        while(state->ccount != seq) {
+            mppe_update_count(state);
+	}
+
+        /*
+         * Packets with bad sequence numbers can still be decrypted
+         * successfully when stateless compression is in use.
+         */
+        if (!state->stateless) {
+            mppe_update_count(state);
+
+	    return DECOMP_ERROR;
+        }
+    }
+
+    /*
+     * Fill in the first part of the PPP header.  The protocol field
+     * comes from the decompressed data.
+     */
+    obuf[0] = PPP_ADDRESS(ibuf);
+    obuf[1] = PPP_CONTROL(ibuf);
+    obuf += 2;
+
+    if(!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
+        printk(KERN_DEBUG"ERROR: not an encrypted packet");
+        mppe_synchronize_key(state);
+	return DECOMP_ERROR;
+    } else {
+	if(!state->stateless && (MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED))
+	    mppe_synchronize_key(state);
+	mppe_update_count(state);
+
+	/* decrypt - adjust for PPP_HDRLEN + MPPE_OVHD - mru should be OK */
+	RC4(&(state->RC4_recv_key),isize-6,ibuf+6,obuf);
+
+	(state->stats).unc_bytes += (isize-MPPE_OVHD);
+	(state->stats).unc_packets ++;
+
+	return isize-MPPE_OVHD;
+    }
+}
+
+
+/* Incompressible data has arrived - add it to the history.  */
+static void
+mppe_incomp(void *arg, unsigned char *ibuf, int icnt)
+{
+    struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
+
+    (state->stats).inc_bytes += icnt;
+    (state->stats).inc_packets++;
+}
+
+/* 
+ * Help for Alpha users who have problems with undefined symbols on
+ * module load
+ */
+#ifdef ALPHA
+#include "../../arch/s390/kernel/floatlib.c"
+#endif
+
+
+/*************************************************************
+ * Module interface table
+ *************************************************************/
+
+/* These are in ppp.c */
+extern int  ppp_register_compressor   (struct compressor *cp);
+extern void ppp_unregister_compressor (struct compressor *cp);
+
+/*
+ * Procedures exported to if_ppp.c.
+ */
+struct compressor ppp_mppe = {
+    CI_MPPE,			/* compress_proto */
+    mppe_comp_alloc,		/* comp_alloc */
+    mppe_comp_free,		/* comp_free */
+    mppe_comp_init,		/* comp_init */
+    mppe_comp_reset,		/* comp_reset */
+    mppe_compress,		/* compress */
+    mppe_comp_stats,		/* comp_stat */
+    mppe_comp_alloc,		/* decomp_alloc */
+    mppe_comp_free,		/* decomp_free */
+    mppe_decomp_init,		/* decomp_init */
+    mppe_comp_reset,		/* decomp_reset */
+    mppe_decompress,		/* decompress */
+    mppe_incomp,		/* incomp */
+    mppe_comp_stats,		/* decomp_stat */
+};
+
+
+/*************************************************************
+ * Module support routines
+ *************************************************************/
+
+static int __init
+init_module(void)
+{  
+    int answer = ppp_register_compressor(&ppp_mppe);
+    if (answer == 0) {
+    	printk(KERN_INFO "PPP MPPE compression module registered\n");
+    }
+    return answer;
+}
+     
+
+void
+cleanup_module(void)
+{
+    if (MOD_IN_USE) {
+    	printk (KERN_INFO "MPPE module busy, remove delayed\n");
+    } else {
+	ppp_unregister_compressor (&ppp_mppe);
+	printk(KERN_INFO "PPP MPPE compression module unregistered\n");
+    }
+}
+
+module_init(init_module);
+module_exit(cleanup_module);
+
diff -urN linux-2.4.29/drivers/net/rc4_enc.c linux-2.4.29-uc1/drivers/net/rc4_enc.c
--- linux-2.4.29/drivers/net/rc4_enc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/rc4_enc.c	2005-06-14 02:12:10.000000000 +0100
@@ -0,0 +1,315 @@
+/* crypto/rc4/rc4_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc4.h>
+#include "rc4_locl.h"
+
+/* RC4 as implemented from a posting from
+ * Newsgroups: sci.crypt
+ * From: sterndark@netcom.com (David Sterndark)
+ * Subject: RC4 Algorithm revealed.
+ * Message-ID: <sternCvKL4B.Hyy@netcom.com>
+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
+ */
+
+void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
+	     unsigned char *outdata)
+	{
+        register RC4_INT *d;
+        register RC4_INT x,y,tx,ty;
+	int i;
+        
+        x=key->x;     
+        y=key->y;     
+        d=key->data; 
+
+#if defined(RC4_CHUNK)
+	/*
+	 * The original reason for implementing this(*) was the fact that
+	 * pre-21164a Alpha CPUs don't have byte load/store instructions
+	 * and e.g. a byte store has to be done with 64-bit load, shift,
+	 * and, or and finally 64-bit store. Peaking data and operating
+	 * at natural word size made it possible to reduce amount of
+	 * instructions as well as to perform early read-ahead without
+	 * suffering from RAW (read-after-write) hazard. This resulted
+	 * in ~40%(**) performance improvement on 21064 box with gcc.
+	 * But it's not only Alpha users who win here:-) Thanks to the
+	 * early-n-wide read-ahead this implementation also exhibits
+	 * >40% speed-up on SPARC and 20-30% on 64-bit MIPS (depending
+	 * on sizeof(RC4_INT)).
+	 *
+	 * (*)	"this" means code which recognizes the case when input
+	 *	and output pointers appear to be aligned at natural CPU
+	 *	word boundary
+	 * (**)	i.e. according to 'apps/openssl speed rc4' benchmark,
+	 *	crypto/rc4/rc4speed.c exhibits almost 70% speed-up...
+	 *
+	 * Cavets.
+	 *
+	 * - RC4_CHUNK="unsigned long long" should be a #1 choice for
+	 *   UltraSPARC. Unfortunately gcc generates very slow code
+	 *   (2.5-3 times slower than one generated by Sun's WorkShop
+	 *   C) and therefore gcc (at least 2.95 and earlier) should
+	 *   always be told that RC4_CHUNK="unsigned long".
+	 *
+	 *					<appro@fy.chalmers.se>
+	 */
+
+# define RC4_STEP	( \
+			x=(x+1) &0xff,	\
+			tx=d[x],	\
+			y=(tx+y)&0xff,	\
+			ty=d[y],	\
+			d[y]=tx,	\
+			d[x]=ty,	\
+			(RC4_CHUNK)d[(tx+ty)&0xff]\
+			)
+
+	if ( ( ((unsigned long)indata  & (sizeof(RC4_CHUNK)-1)) | 
+	       ((unsigned long)outdata & (sizeof(RC4_CHUNK)-1)) ) == 0 )
+		{
+		RC4_CHUNK ichunk,otp;
+		const union { long one; char little; } is_endian = {1};
+
+		/*
+		 * I reckon we can afford to implement both endian
+		 * cases and to decide which way to take at run-time
+		 * because the machine code appears to be very compact
+		 * and redundant 1-2KB is perfectly tolerable (i.e.
+		 * in case the compiler fails to eliminate it:-). By
+		 * suggestion from Terrel Larson <terr@terralogic.net>
+		 * who also stands for the is_endian union:-)
+		 *
+		 * Special notes.
+		 *
+		 * - is_endian is declared automatic as doing otherwise
+		 *   (declaring static) prevents gcc from eliminating
+		 *   the redundant code;
+		 * - compilers (those I've tried) don't seem to have
+		 *   problems eliminating either the operators guarded
+		 *   by "if (sizeof(RC4_CHUNK)==8)" or the condition
+		 *   expressions themselves so I've got 'em to replace
+		 *   corresponding #ifdefs from the previous version;
+		 * - I chose to let the redundant switch cases when
+		 *   sizeof(RC4_CHUNK)!=8 be (were also #ifdefed
+		 *   before);
+		 * - in case you wonder "&(sizeof(RC4_CHUNK)*8-1)" in
+		 *   [LB]ESHFT guards against "shift is out of range"
+		 *   warnings when sizeof(RC4_CHUNK)!=8 
+		 *
+		 *			<appro@fy.chalmers.se>
+		 */
+		if (!is_endian.little)
+			{	/* BIG-ENDIAN CASE */
+# define BESHFT(c)	(((sizeof(RC4_CHUNK)-(c)-1)*8)&(sizeof(RC4_CHUNK)*8-1))
+			for (;len&-sizeof(RC4_CHUNK);len-=sizeof(RC4_CHUNK))
+				{
+				ichunk  = *(RC4_CHUNK *)indata;
+				otp  = RC4_STEP<<BESHFT(0);
+				otp |= RC4_STEP<<BESHFT(1);
+				otp |= RC4_STEP<<BESHFT(2);
+				otp |= RC4_STEP<<BESHFT(3);
+				if (sizeof(RC4_CHUNK)==8)
+					{
+					otp |= RC4_STEP<<BESHFT(4);
+					otp |= RC4_STEP<<BESHFT(5);
+					otp |= RC4_STEP<<BESHFT(6);
+					otp |= RC4_STEP<<BESHFT(7);
+					}
+				*(RC4_CHUNK *)outdata = otp^ichunk;
+				indata  += sizeof(RC4_CHUNK);
+				outdata += sizeof(RC4_CHUNK);
+				}
+			if (len)
+				{
+				RC4_CHUNK mask=(RC4_CHUNK)-1, ochunk;
+
+				ichunk = *(RC4_CHUNK *)indata;
+				ochunk = *(RC4_CHUNK *)outdata;
+				otp = 0;
+				i = BESHFT(0);
+				mask <<= (sizeof(RC4_CHUNK)-len)<<3;
+				switch (len&(sizeof(RC4_CHUNK)-1))
+					{
+					case 7:	otp  = RC4_STEP<<i, i-=8;
+					case 6:	otp |= RC4_STEP<<i, i-=8;
+					case 5:	otp |= RC4_STEP<<i, i-=8;
+					case 4:	otp |= RC4_STEP<<i, i-=8;
+					case 3:	otp |= RC4_STEP<<i, i-=8;
+					case 2:	otp |= RC4_STEP<<i, i-=8;
+					case 1:	otp |= RC4_STEP<<i, i-=8;
+					case 0: ; /*
+						   * it's never the case,
+						   * but it has to be here
+						   * for ultrix?
+						   */
+					}
+				ochunk &= ~mask;
+				ochunk |= (otp^ichunk) & mask;
+				*(RC4_CHUNK *)outdata = ochunk;
+				}
+			key->x=x;     
+			key->y=y;
+			return;
+			}
+		else
+			{	/* LITTLE-ENDIAN CASE */
+# define LESHFT(c)	(((c)*8)&(sizeof(RC4_CHUNK)*8-1))
+			for (;len&-sizeof(RC4_CHUNK);len-=sizeof(RC4_CHUNK))
+				{
+				ichunk  = *(RC4_CHUNK *)indata;
+				otp  = RC4_STEP;
+				otp |= RC4_STEP<<8;
+				otp |= RC4_STEP<<16;
+				otp |= RC4_STEP<<24;
+				if (sizeof(RC4_CHUNK)==8)
+					{
+					otp |= RC4_STEP<<LESHFT(4);
+					otp |= RC4_STEP<<LESHFT(5);
+					otp |= RC4_STEP<<LESHFT(6);
+					otp |= RC4_STEP<<LESHFT(7);
+					}
+				*(RC4_CHUNK *)outdata = otp^ichunk;
+				indata  += sizeof(RC4_CHUNK);
+				outdata += sizeof(RC4_CHUNK);
+				}
+			if (len)
+				{
+				RC4_CHUNK mask=(RC4_CHUNK)-1, ochunk;
+
+				ichunk = *(RC4_CHUNK *)indata;
+				ochunk = *(RC4_CHUNK *)outdata;
+				otp = 0;
+				i   = 0;
+				mask >>= (sizeof(RC4_CHUNK)-len)<<3;
+				switch (len&(sizeof(RC4_CHUNK)-1))
+					{
+					case 7:	otp  = RC4_STEP,    i+=8;
+					case 6:	otp |= RC4_STEP<<i, i+=8;
+					case 5:	otp |= RC4_STEP<<i, i+=8;
+					case 4:	otp |= RC4_STEP<<i, i+=8;
+					case 3:	otp |= RC4_STEP<<i, i+=8;
+					case 2:	otp |= RC4_STEP<<i, i+=8;
+					case 1:	otp |= RC4_STEP<<i, i+=8;
+					case 0: ; /*
+						   * it's never the case,
+						   * but it has to be here
+						   * for ultrix?
+						   */
+					}
+				ochunk &= ~mask;
+				ochunk |= (otp^ichunk) & mask;
+				*(RC4_CHUNK *)outdata = ochunk;
+				}
+			key->x=x;     
+			key->y=y;
+			return;
+			}
+		}
+#endif
+#define LOOP(in,out) \
+		x=((x+1)&0xff); \
+		tx=d[x]; \
+		y=(tx+y)&0xff; \
+		d[x]=ty=d[y]; \
+		d[y]=tx; \
+		(out) = d[(tx+ty)&0xff]^ (in);
+
+#ifndef RC4_INDEX
+#define RC4_LOOP(a,b,i)	LOOP(*((a)++),*((b)++))
+#else
+#define RC4_LOOP(a,b,i)	LOOP(a[i],b[i])
+#endif
+
+	i=(int)(len>>3L);
+	if (i)
+		{
+		for (;;)
+			{
+			RC4_LOOP(indata,outdata,0);
+			RC4_LOOP(indata,outdata,1);
+			RC4_LOOP(indata,outdata,2);
+			RC4_LOOP(indata,outdata,3);
+			RC4_LOOP(indata,outdata,4);
+			RC4_LOOP(indata,outdata,5);
+			RC4_LOOP(indata,outdata,6);
+			RC4_LOOP(indata,outdata,7);
+#ifdef RC4_INDEX
+			indata+=8;
+			outdata+=8;
+#endif
+			if (--i == 0) break;
+			}
+		}
+	i=(int)len&0x07;
+	if (i)
+		{
+		for (;;)
+			{
+			RC4_LOOP(indata,outdata,0); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,1); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,2); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,3); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,4); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,5); if (--i == 0) break;
+			RC4_LOOP(indata,outdata,6); if (--i == 0) break;
+			}
+		}               
+	key->x=x;     
+	key->y=y;
+	}
diff -urN linux-2.4.29/drivers/net/rc4_locl.h linux-2.4.29-uc1/drivers/net/rc4_locl.h
--- linux-2.4.29/drivers/net/rc4_locl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/rc4_locl.h	2005-06-14 02:12:09.000000000 +0100
@@ -0,0 +1,4 @@
+#ifndef HEADER_RC4_LOCL_H
+#define HEADER_RC4_LOCL_H
+#include <openssl/opensslconf.h>
+#endif
diff -urN linux-2.4.29/drivers/net/rc4_skey.c linux-2.4.29-uc1/drivers/net/rc4_skey.c
--- linux-2.4.29/drivers/net/rc4_skey.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/rc4_skey.c	2005-06-14 02:12:09.000000000 +0100
@@ -0,0 +1,117 @@
+/* crypto/rc4/rc4_skey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <openssl/rc4.h>
+#include "rc4_locl.h"
+#include <openssl/opensslv.h>
+
+const char *RC4_version="RC4" OPENSSL_VERSION_PTEXT;
+
+const char *RC4_options(void)
+	{
+#ifdef RC4_INDEX
+	if (sizeof(RC4_INT) == 1)
+		return("rc4(idx,char)");
+	else
+		return("rc4(idx,int)");
+#else
+	if (sizeof(RC4_INT) == 1)
+		return("rc4(ptr,char)");
+	else
+		return("rc4(ptr,int)");
+#endif
+	}
+
+/* RC4 as implemented from a posting from
+ * Newsgroups: sci.crypt
+ * From: sterndark@netcom.com (David Sterndark)
+ * Subject: RC4 Algorithm revealed.
+ * Message-ID: <sternCvKL4B.Hyy@netcom.com>
+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
+ */
+
+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
+	{
+        register RC4_INT tmp;
+        register int id1,id2;
+        register RC4_INT *d;
+        unsigned int i;
+        
+        d= &(key->data[0]);
+	for (i=0; i<256; i++)
+		d[i]=i;
+        key->x = 0;     
+        key->y = 0;     
+        id1=id2=0;     
+
+#define SK_LOOP(n) { \
+		tmp=d[(n)]; \
+		id2 = (data[id1] + tmp + id2) & 0xff; \
+		if (++id1 == len) id1=0; \
+		d[(n)]=d[id2]; \
+		d[id2]=tmp; }
+
+	for (i=0; i < 256; i+=4)
+		{
+		SK_LOOP(i+0);
+		SK_LOOP(i+1);
+		SK_LOOP(i+2);
+		SK_LOOP(i+3);
+		}
+	}
+    
diff -urN linux-2.4.29/drivers/net/rtl8139.c linux-2.4.29-uc1/drivers/net/rtl8139.c
--- linux-2.4.29/drivers/net/rtl8139.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/rtl8139.c	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,1637 @@
+/* rtl8139.c: A RealTek RTL8129/8139 Fast Ethernet driver for Linux. */
+/*
+	Written 1997-2001 by Donald Becker.
+	This software may be used and distributed according to the terms of
+	the GNU General Public License (GPL), incorporated herein by reference.
+	Drivers based on or derived from this code fall under the GPL and must
+	retain the authorship, copyright and license notice.  This file is not
+	a complete program and may only be used when the entire operating
+	system is licensed under the GPL.
+
+	This driver is for boards based on the RTL8129 and RTL8139 PCI ethernet
+	chips.
+
+	The author may be reached as becker@scyld.com, or C/O
+	Scyld Computing Corporation
+	410 Severn Ave., Suite 210
+	Annapolis MD 21403
+
+	Support and updates available at
+	http://www.scyld.com/network/rtl8139.html
+
+	Twister-tuning table provided by Kinston <shangh@realtek.com.tw>.
+*/
+
+/* These identify the driver base version and may not be removed. */
+static const char versionA[] =
+"rtl8139.c:v1.16a 11/13/2001 Donald Becker, becker@scyld.com.\n";
+static const char versionB[] =
+" http://www.scyld.com/network/rtl8139.html\n";
+
+#ifndef USE_MEM_OPS
+/* Note: Register access width and timing restrictions apply in MMIO mode.
+   This updated driver should nominally work, but I/O mode is better tested. */
+#define USE_IO_OPS
+#endif
+
+/* The user-configurable values.
+   These may be modified when a driver module is loaded.*/
+static int debug = 1;			/* 1 normal messages, 0 quiet .. 7 verbose. */
+/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
+static int max_interrupt_work = 20;
+
+/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
+   The RTL chips use a 64 element hash table based on the Ethernet CRC.  It
+   is efficient to update the hardware filter, but recalculating the table
+   for a long filter list is painful.  */
+static int multicast_filter_limit = 32;
+
+/* Used to pass the full-duplex flag, etc. */
+#define MAX_UNITS 8		/* More are supported, limit only on options */
+static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+/* Operational parameters that are set at compile time. */
+
+/* Maximum size of the in-memory receive ring (smaller if no memory). */
+#define RX_BUF_LEN_IDX	2			/* 0==8K, 1==16K, 2==32K, 3==64K */
+/* Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). */
+#define TX_BUF_SIZE	1536
+
+/* PCI Tuning Parameters
+   Threshold is bytes transferred to chip before transmission starts. */
+#define TX_FIFO_THRESH 256	/* In bytes, rounded down to 32 byte units. */
+
+/* The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024. */
+#define RX_FIFO_THRESH	4		/* Rx buffer level before first PCI xfer.  */
+#define RX_DMA_BURST	4		/* Maximum PCI burst, '4' is 256 bytes */
+#define TX_DMA_BURST	4		/* Calculate as 16<<val. */
+
+/* Operational parameters that usually are not changed. */
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT  (6*HZ)
+
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif
+#if !defined(__OPTIMIZE__)
+#warning  You must compile this file with the correct options!
+#warning  See the last lines of the source file.
+#error You must compile this driver with "-O".
+#endif
+
+#include <linux/config.h>
+#if defined(CONFIG_SMP) && ! defined(__SMP__)
+#define __SMP__
+#endif
+#if defined(MODULE) && defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS)
+#define MODVERSIONS
+#endif
+
+#include <linux/version.h>
+#include <linux/module.h>
+#if LINUX_VERSION_CODE < 0x20300  &&  defined(MODVERSIONS)
+#include <linux/modversions.h>
+#endif
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/malloc.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <asm/processor.h>		/* Processor type for cache alignment. */
+#include <asm/bitops.h>
+#include <asm/io.h>
+
+#if LINUX_VERSION_CODE >= 0x20300
+#include <linux/spinlock.h>
+#elif LINUX_VERSION_CODE >= 0x20200
+#include <asm/spinlock.h>
+#endif
+
+#ifdef INLINE_PCISCAN
+#include "k_compat.h"
+#else
+#include "pci-scan.h"
+#include "kern_compat.h"
+#endif
+
+#ifdef CONFIG_LEDMAN
+#include <linux/ledman.h>
+#endif
+
+#if (LINUX_VERSION_CODE >= 0x20100)  &&  defined(MODULE)
+char kernel_version[] = UTS_RELEASE;
+#endif
+
+/*
+				Theory of Operation
+
+I. Board Compatibility
+
+This device driver is designed for the RealTek RTL8129 series, the RealTek
+Fast Ethernet controllers for PCI and CardBus.  This chip is used on many
+low-end boards, sometimes with custom chip labels.
+
+
+II. Board-specific settings
+
+PCI bus devices are configured by the system at boot time, so no jumpers
+need to be set on the board.  The system BIOS will assign the
+PCI INTA signal to a (preferably otherwise unused) system IRQ line.
+Note: Kernel versions earlier than 1.3.73 do not support shared PCI
+interrupt lines.
+
+III. Driver operation
+
+IIIa. Rx Ring buffers
+
+The receive unit uses a single linear ring buffer rather than the more
+common (and more efficient) descriptor-based architecture.  Incoming frames
+are sequentially stored into the Rx region, and the host copies them into
+skbuffs.
+
+Comment: While it is theoretically possible to process many frames in place,
+any delay in Rx processing would block the Rx ring and cause us to drop
+frames.  It would be difficult to design a protocol stack where the data
+buffer could be recalled by the device driver.
+
+IIIb. Tx operation
+
+The RTL8129 uses a fixed set of four Tx descriptors in register space.  Tx
+frames must be 32 bit aligned.  Linux aligns the IP header on word
+boundaries, and 14 byte ethernet header means that almost all frames will
+need to be copied to an alignment buffer.  The driver statically allocates
+alignment the four alignment buffers at open() time.
+
+IVb. References
+
+http://www.realtek.com.tw/cn/cn.html
+http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
+
+IVc. Errata
+
+*/
+
+
+static void *rtl8139_probe1(struct pci_dev *pdev, void *init_dev,
+							long ioaddr, int irq, int chip_idx, int find_cnt);
+static int rtl_pwr_event(void *dev_instance, int event);
+
+enum chip_capability_flags {HAS_MII_XCVR=0x01, HAS_CHIP_XCVR=0x02,
+							HAS_LNK_CHNG=0x04, HAS_DESC=0x08};
+#ifdef USE_IO_OPS
+#define RTL8139_IOTYPE  PCI_USES_MASTER|PCI_USES_IO |PCI_ADDR0
+#else
+#define RTL8139_IOTYPE  PCI_USES_MASTER|PCI_USES_MEM|PCI_ADDR1
+#endif
+#define RTL8129_CAPS  HAS_MII_XCVR
+#define RTL8139_CAPS  HAS_CHIP_XCVR|HAS_LNK_CHNG
+#define RTL8139D_CAPS  HAS_CHIP_XCVR|HAS_LNK_CHNG|HAS_DESC
+
+/* Note: Update the marked constant in _attach() if the RTL8139B entry moves.*/
+static struct pci_id_info pci_tbl[] = {
+	{"RealTek RTL8139C+, 64 bit high performance",
+	 { 0x813910ec, 0xffffffff, 0,0, 0x10, 0xff},
+	 RTL8139_IOTYPE, 0x80, RTL8139D_CAPS, },
+#if 1
+	/* Raw 8139 with no serial EEPRON will produce ID of 8129! */
+	{"RealTek RTL8139 Fast Ethernet", { 0x812910ec, 0xffffffff,},
+	 RTL8139_IOTYPE, 0x80, RTL8139_CAPS, },
+#else
+	{"RealTek RTL8129 Fast Ethernet", { 0x812910ec, 0xffffffff,},
+	 RTL8139_IOTYPE, 0x80, RTL8129_CAPS, },
+#endif
+	{"RealTek RTL8139 Fast Ethernet", { 0x813910ec, 0xffffffff,},
+	 RTL8139_IOTYPE, 0x80, RTL8139_CAPS, },
+	{"RealTek RTL8139B PCI/CardBus",  { 0x813810ec, 0xffffffff,},
+	 RTL8139_IOTYPE, 0x80, RTL8139_CAPS, },
+	{"SMC1211TX EZCard 10/100 (RealTek RTL8139)", { 0x12111113, 0xffffffff,},
+	 RTL8139_IOTYPE, 0x80, RTL8139_CAPS, },
+	{"Accton MPX5030 (RealTek RTL8139)", { 0x12111113, 0xffffffff,},
+	 RTL8139_IOTYPE, 0x80, RTL8139_CAPS, },
+	{"D-Link DFE-538TX (RealTek RTL8139)", { 0x13001186, 0xffffffff,},
+	 RTL8139_IOTYPE, 0x80, RTL8139_CAPS, },
+	{0,},						/* 0 terminated list. */
+};
+
+struct drv_id_info rtl8139_drv_id = {
+	"realtek", PCI_HOTSWAP, PCI_CLASS_NETWORK_ETHERNET<<8, pci_tbl,
+	rtl8139_probe1, rtl_pwr_event };
+
+#ifndef USE_IO_OPS
+#undef inb
+#undef inw
+#undef inl
+#undef outb
+#undef outw
+#undef outl
+#define inb readb
+#define inw readw
+#define inl readl
+#define outb writeb
+#define outw writew
+#define outl writel
+#endif
+
+/* The rest of these values should never change. */
+#define NUM_TX_DESC	4			/* Number of Tx descriptor registers. */
+
+/* Symbolic offsets to registers. */
+enum RTL8129_registers {
+	MAC0=0,						/* Ethernet hardware address. */
+	MAR0=8,						/* Multicast filter. */
+	TxStatus0=0x10,				/* Transmit status (Four 32bit registers). */
+	TxAddr0=0x20,				/* Tx descriptors (also four 32bit). */
+	RxBuf=0x30, RxEarlyCnt=0x34, RxEarlyStatus=0x36,
+	ChipCmd=0x37, RxBufPtr=0x38, RxBufAddr=0x3A,
+	IntrMask=0x3C, IntrStatus=0x3E,
+	TxConfig=0x40, RxConfig=0x44,
+	Timer=0x48,					/* A general-purpose counter. */
+	RxMissed=0x4C,				/* 24 bits valid, write clears. */
+	Cfg9346=0x50, Config0=0x51, Config1=0x52,
+	FlashReg=0x54, GPPinData=0x58, GPPinDir=0x59, MII_SMI=0x5A, HltClk=0x5B,
+	MultiIntr=0x5C, TxSummary=0x60,
+	MII_BMCR=0x62, MII_BMSR=0x64, NWayAdvert=0x66, NWayLPAR=0x68,
+	NWayExpansion=0x6A,
+	/* Undocumented registers, but required for proper operation. */
+	FIFOTMS=0x70,	/* FIFO Control and test. */
+	CSCR=0x74,	/* Chip Status and Configuration Register. */
+	PARA78=0x78, PARA7c=0x7c,	/* Magic transceiver parameter register. */
+};
+
+enum ChipCmdBits {
+	CmdReset=0x10, CmdRxEnb=0x08, CmdTxEnb=0x04, RxBufEmpty=0x01, };
+
+/* Interrupt register bits, using my own meaningful names. */
+enum IntrStatusBits {
+	PCIErr=0x8000, PCSTimeout=0x4000,
+	RxFIFOOver=0x40, RxUnderrun=0x20, RxOverflow=0x10,
+	TxErr=0x08, TxOK=0x04, RxErr=0x02, RxOK=0x01,
+};
+enum TxStatusBits {
+	TxHostOwns=0x2000, TxUnderrun=0x4000, TxStatOK=0x8000,
+	TxOutOfWindow=0x20000000, TxAborted=0x40000000, TxCarrierLost=0x80000000,
+};
+enum RxStatusBits {
+	RxMulticast=0x8000, RxPhysical=0x4000, RxBroadcast=0x2000,
+	RxBadSymbol=0x0020, RxRunt=0x0010, RxTooLong=0x0008, RxCRCErr=0x0004,
+	RxBadAlign=0x0002, RxStatusOK=0x0001,
+};
+
+/* Twister tuning parameters from RealTek.
+   Completely undocumented, but required to tune bad links. */
+enum CSCRBits {
+	CSCR_LinkOKBit=0x0400, CSCR_LinkChangeBit=0x0800,
+	CSCR_LinkStatusBits=0x0f000, CSCR_LinkDownOffCmd=0x003c0,
+	CSCR_LinkDownCmd=0x0f3c0,
+};
+#define PARA78_default	0x78fa8388
+#define PARA7c_default	0xcb38de43 			/* param[0][3] */
+#define PARA7c_xxx		0xcb38de43
+unsigned long param[4][4]={
+	{0xcb39de43, 0xcb39ce43, 0xfb38de03, 0xcb38de43},
+	{0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83},
+	{0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83},
+	{0xbb39de43, 0xbb39ce43, 0xbb39ce83, 0xbb39ce83}
+};
+
+#define PRIV_ALIGN	15 	/* Desired alignment mask */
+struct rtl8129_private {
+	struct net_device *next_module;
+	void *priv_addr;					/* Unaligned address for kfree */
+	int chip_id;
+	int drv_flags;
+	struct pci_dev *pci_dev;
+	struct net_device_stats stats;
+	struct timer_list timer;	/* Media selection timer. */
+	unsigned char *rx_ring;
+	unsigned int cur_rx;		/* Index into the Rx buffer of next Rx pkt. */
+	unsigned int rx_buf_len;	/* Size (8K 16K 32K or 64KB) of the Rx ring */
+	unsigned int rx_config;
+	unsigned int cur_tx, dirty_tx, tx_flag;
+	unsigned long tx_full;				/* The Tx queue is full. */
+	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
+	struct sk_buff* tx_skbuff[NUM_TX_DESC];
+	unsigned char *tx_buf[NUM_TX_DESC];	/* Tx bounce buffers */
+	unsigned char *tx_bufs;				/* Tx bounce buffer region. */
+	char phys[4];						/* MII device addresses. */
+	u16 advertising;					/* NWay media advertisement */
+	char twistie, twist_row, twist_col;	/* Twister tune state. */
+	unsigned int full_duplex:1;			/* Full-duplex operation requested. */
+	unsigned int duplex_lock:1;
+	unsigned int default_port:4;		/* Last dev->if_port value. */
+	unsigned int media2:4;				/* Secondary monitored media port. */
+	unsigned int medialock:1;			/* Don't sense media type. */
+	unsigned int mediasense:1;			/* Media sensing in progress. */
+};
+
+MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
+MODULE_DESCRIPTION("RealTek RTL8129/8139 Fast Ethernet driver");
+MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(multicast_filter_limit, "i");
+MODULE_PARM(max_interrupt_work, "i");
+MODULE_PARM(debug, "i");
+
+static int rtl8129_open(struct net_device *dev);
+static void rtl_hw_start(struct net_device *dev);
+static int read_eeprom(long ioaddr, int location, int addr_len);
+static int mdio_read(struct net_device *dev, int phy_id, int location);
+static void mdio_write(struct net_device *dev, int phy_id, int location, int val);
+static void rtl8129_timer(unsigned long data);
+static void rtl8129_tx_timeout(struct net_device *dev);
+static void rtl8129_init_ring(struct net_device *dev);
+static int rtl8129_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static int rtl8129_rx(struct net_device *dev);
+static void rtl8129_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static int rtl8129_close(struct net_device *dev);
+static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static struct net_device_stats *rtl8129_get_stats(struct net_device *dev);
+static inline u32 ether_crc(int length, unsigned char *data);
+static void set_rx_mode(struct net_device *dev);
+
+
+/* A list of all installed RTL8129 devices, for removing the driver module. */
+static struct net_device *root_rtl8129_dev = NULL;
+
+#ifndef MODULE
+int rtl8139_probe(struct net_device *dev)
+{
+	static int did_version = 0;			/* Already printed version info. */
+
+	if (debug > 0  &&  did_version++ == 0)
+		printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
+	return pci_drv_register(&rtl8139_drv_id, dev);
+}
+#endif
+
+static void *rtl8139_probe1(struct pci_dev *pdev, void *init_dev,
+							long ioaddr, int irq, int chip_idx, int found_cnt)
+{
+	struct net_device *dev;
+	struct rtl8129_private *np;
+	void *priv_mem;
+	int i, option = found_cnt < MAX_UNITS ? options[found_cnt] : 0;
+
+	dev = init_etherdev(init_dev, 0);
+
+	printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ",
+		   dev->name, pci_tbl[chip_idx].name, ioaddr, irq);
+
+	/* Bring the chip out of low-power mode. */
+	outb(0x00, ioaddr + Config1);
+
+#if 1
+	for (i = 0; i < 6; i++)
+		dev->dev_addr[i] = inb(ioaddr + MAC0 + i);
+#else
+	{
+		int addr_len = read_eeprom(ioaddr, 0, 8) == 0x8129 ? 8 : 6;
+		for (i = 0; i < 3; i++)
+			((u16 *)(dev->dev_addr))[i] =
+				le16_to_cpu(read_eeprom(ioaddr, i+7, addr_len));
+	}
+#endif
+
+	for (i = 0; i < 5; i++)
+		printk("%2.2x:", dev->dev_addr[i]);
+	printk("%2.2x.\n", dev->dev_addr[i]);
+
+	/* Make certain elements e.g. descriptor lists are aligned. */
+	priv_mem = kmalloc(sizeof(*np) + PRIV_ALIGN, GFP_KERNEL);
+	/* Check for the very unlikely case of no memory. */
+	if (priv_mem == NULL)
+		return NULL;
+
+	/* We do a request_region() to register /proc/ioports info. */
+	request_region(ioaddr, pci_tbl[chip_idx].io_size, dev->name);
+
+	dev->base_addr = ioaddr;
+	dev->irq = irq;
+
+	dev->priv = np = (void *)(((long)priv_mem + PRIV_ALIGN) & ~PRIV_ALIGN);
+	memset(np, 0, sizeof(*np));
+	np->priv_addr = priv_mem;
+
+	np->next_module = root_rtl8129_dev;
+	root_rtl8129_dev = dev;
+
+	np->pci_dev = pdev;
+	np->chip_id = chip_idx;
+	np->drv_flags = pci_tbl[chip_idx].drv_flags;
+
+	/* Find the connected MII xcvrs.
+	   Doing this in open() would allow detecting external xcvrs later, but
+	   takes too much time. */
+	if (np->drv_flags & HAS_MII_XCVR) {
+		int phy, phy_idx = 0;
+		for (phy = 0; phy < 32 && phy_idx < sizeof(np->phys); phy++) {
+			int mii_status = mdio_read(dev, phy, 1);
+			if (mii_status != 0xffff  &&  mii_status != 0x0000) {
+				np->phys[phy_idx++] = phy;
+				np->advertising = mdio_read(dev, phy, 4);
+				printk(KERN_INFO "%s: MII transceiver %d status 0x%4.4x "
+					   "advertising %4.4x.\n",
+					   dev->name, phy, mii_status, np->advertising);
+			}
+		}
+		if (phy_idx == 0) {
+			printk(KERN_INFO "%s: No MII transceivers found!  Assuming SYM "
+				   "transceiver.\n",
+				   dev->name);
+			np->phys[0] = 32;
+		}
+	} else
+		np->phys[0] = 32;
+
+	/* Put the chip into low-power mode. */
+	outb(0xC0, ioaddr + Cfg9346);
+	outb(0x03, ioaddr + Config1);
+	outb('H', ioaddr + HltClk);		/* 'R' would leave the clock running. */
+
+	/* The lower four bits are the media type. */
+	if (option > 0) {
+		np->full_duplex = (option & 0x210) ? 1 : 0;
+		np->default_port = option & 0xff;
+		if (np->default_port)
+			np->medialock = 1;
+	}
+
+	if (found_cnt < MAX_UNITS  &&  full_duplex[found_cnt] > 0)
+		np->full_duplex = full_duplex[found_cnt];
+
+	if (np->full_duplex) {
+		printk(KERN_INFO "%s: Media type forced to Full Duplex.\n", dev->name);
+		/* Changing the MII-advertised media because might prevent
+		   re-connection. */
+		np->duplex_lock = 1;
+	}
+	if (np->default_port) {
+		printk(KERN_INFO "  Forcing %dMbs %s-duplex operation.\n",
+			   (option & 0x20 ? 100 : 10),
+			   (option & 0x10 ? "full" : "half"));
+		mdio_write(dev, np->phys[0], 0,
+				   ((option & 0x20) ? 0x2000 : 0) | 	/* 100mbps? */
+				   ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */
+	}
+
+	/* The Rtl8129-specific entries in the device structure. */
+	dev->open = &rtl8129_open;
+	dev->hard_start_xmit = &rtl8129_start_xmit;
+	dev->stop = &rtl8129_close;
+	dev->get_stats = &rtl8129_get_stats;
+	dev->set_multicast_list = &set_rx_mode;
+	dev->do_ioctl = &mii_ioctl;
+
+	return dev;
+}
+
+/* Serial EEPROM section. */
+
+/*  EEPROM_Ctrl bits. */
+#define EE_SHIFT_CLK	0x04	/* EEPROM shift clock. */
+#define EE_CS			0x08	/* EEPROM chip select. */
+#define EE_DATA_WRITE	0x02	/* EEPROM chip data in. */
+#define EE_WRITE_0		0x00
+#define EE_WRITE_1		0x02
+#define EE_DATA_READ	0x01	/* EEPROM chip data out. */
+#define EE_ENB			(0x80 | EE_CS)
+
+/* Delay between EEPROM clock transitions.
+   No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
+ */
+
+#define eeprom_delay()	inl(ee_addr)
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define EE_WRITE_CMD	(5)
+#define EE_READ_CMD		(6)
+#define EE_ERASE_CMD	(7)
+
+static int read_eeprom(long ioaddr, int location, int addr_len)
+{
+	int i;
+	unsigned retval = 0;
+	long ee_addr = ioaddr + Cfg9346;
+	int read_cmd = location | (EE_READ_CMD << addr_len);
+
+	outb(EE_ENB & ~EE_CS, ee_addr);
+	outb(EE_ENB, ee_addr);
+
+	/* Shift the read command bits out. */
+	for (i = 4 + addr_len; i >= 0; i--) {
+		int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+		outb(EE_ENB | dataval, ee_addr);
+		eeprom_delay();
+		outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+		eeprom_delay();
+	}
+	outb(EE_ENB, ee_addr);
+	eeprom_delay();
+
+	for (i = 16; i > 0; i--) {
+		outb(EE_ENB | EE_SHIFT_CLK, ee_addr);
+		eeprom_delay();
+		retval = (retval << 1) | ((inb(ee_addr) & EE_DATA_READ) ? 1 : 0);
+		outb(EE_ENB, ee_addr);
+		eeprom_delay();
+	}
+
+	/* Terminate the EEPROM access. */
+	outb(~EE_CS, ee_addr);
+	return retval;
+}
+
+/* MII serial management: mostly bogus for now. */
+/* Read and write the MII management registers using software-generated
+   serial MDIO protocol.
+   The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
+   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
+   "overclocking" issues. */
+#define MDIO_DIR		0x80
+#define MDIO_DATA_OUT	0x04
+#define MDIO_DATA_IN	0x02
+#define MDIO_CLK		0x01
+#define MDIO_WRITE0 (MDIO_DIR)
+#define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT)
+
+#define mdio_delay(mdio_addr)	inb(mdio_addr)
+
+static char mii_2_8139_map[8] = {MII_BMCR, MII_BMSR, 0, 0, NWayAdvert,
+								 NWayLPAR, NWayExpansion, 0 };
+
+/* Syncronize the MII management interface by shifting 32 one bits out. */
+static void mdio_sync(long mdio_addr)
+{
+	int i;
+
+	for (i = 32; i >= 0; i--) {
+		outb(MDIO_WRITE1, mdio_addr);
+		mdio_delay(mdio_addr);
+		outb(MDIO_WRITE1 | MDIO_CLK, mdio_addr);
+		mdio_delay(mdio_addr);
+	}
+	return;
+}
+static int mdio_read(struct net_device *dev, int phy_id, int location)
+{
+	long mdio_addr = dev->base_addr + MII_SMI;
+	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
+	int retval = 0;
+	int i;
+
+	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
+		return location < 8 && mii_2_8139_map[location] ?
+			inw(dev->base_addr + mii_2_8139_map[location]) : 0;
+	}
+	mdio_sync(mdio_addr);
+	/* Shift the read command bits out. */
+	for (i = 15; i >= 0; i--) {
+		int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;
+
+		outb(MDIO_DIR | dataval, mdio_addr);
+		mdio_delay(mdio_addr);
+		outb(MDIO_DIR | dataval | MDIO_CLK, mdio_addr);
+		mdio_delay(mdio_addr);
+	}
+
+	/* Read the two transition, 16 data, and wire-idle bits. */
+	for (i = 19; i > 0; i--) {
+		outb(0, mdio_addr);
+		mdio_delay(mdio_addr);
+		retval = (retval << 1) | ((inb(mdio_addr) & MDIO_DATA_IN) ? 1 : 0);
+		outb(MDIO_CLK, mdio_addr);
+		mdio_delay(mdio_addr);
+	}
+	return (retval>>1) & 0xffff;
+}
+
+static void mdio_write(struct net_device *dev, int phy_id, int location,
+					   int value)
+{
+	long mdio_addr = dev->base_addr + MII_SMI;
+	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
+	int i;
+
+	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
+		long ioaddr = dev->base_addr;
+		if (location == 0) {
+			outb(0xC0, ioaddr + Cfg9346);
+			outw(value, ioaddr + MII_BMCR);
+			outb(0x00, ioaddr + Cfg9346);
+		} else if (location < 8  &&  mii_2_8139_map[location])
+			outw(value, ioaddr + mii_2_8139_map[location]);
+		return;
+	}
+	mdio_sync(mdio_addr);
+
+	/* Shift the command bits out. */
+	for (i = 31; i >= 0; i--) {
+		int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
+		outb(dataval, mdio_addr);
+		mdio_delay(mdio_addr);
+		outb(dataval | MDIO_CLK, mdio_addr);
+		mdio_delay(mdio_addr);
+	}
+	/* Clear out extra bits. */
+	for (i = 2; i > 0; i--) {
+		outb(0, mdio_addr);
+		mdio_delay(mdio_addr);
+		outb(MDIO_CLK, mdio_addr);
+		mdio_delay(mdio_addr);
+	}
+	return;
+}
+
+
+static int rtl8129_open(struct net_device *dev)
+{
+	struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	int rx_buf_len_idx;
+
+	MOD_INC_USE_COUNT;
+	if (request_irq(dev->irq, &rtl8129_interrupt, SA_SHIRQ, dev->name, dev)) {
+		MOD_DEC_USE_COUNT;
+		return -EAGAIN;
+	}
+
+	/* The Rx ring allocation size is 2^N + delta, which is worst-case for
+	   the kernel binary-buddy allocation.  We allocate the Tx bounce buffers
+	   at the same time to use some of the otherwise wasted space.
+	   The delta of +16 is required for dribble-over because the receiver does
+	   not wrap when the packet terminates just beyond the end of the ring. */
+	rx_buf_len_idx = RX_BUF_LEN_IDX;
+	do {
+		tp->rx_buf_len = 8192 << rx_buf_len_idx;
+		tp->rx_ring = kmalloc(tp->rx_buf_len + 16 +
+							  (TX_BUF_SIZE * NUM_TX_DESC), GFP_KERNEL);
+	} while (tp->rx_ring == NULL  &&  --rx_buf_len_idx >= 0);
+
+	if (tp->rx_ring == NULL) {
+		if (debug > 0)
+			printk(KERN_ERR "%s: Couldn't allocate a %d byte receive ring.\n",
+				   dev->name, tp->rx_buf_len);
+		MOD_DEC_USE_COUNT;
+		return -ENOMEM;
+	}
+	tp->tx_bufs = tp->rx_ring + tp->rx_buf_len + 16;
+
+	rtl8129_init_ring(dev);
+	tp->full_duplex = tp->duplex_lock;
+	tp->tx_flag = (TX_FIFO_THRESH<<11) & 0x003f0000;
+	tp->rx_config =
+		(RX_FIFO_THRESH << 13) | (rx_buf_len_idx << 11) | (RX_DMA_BURST<<8);
+
+	rtl_hw_start(dev);
+	netif_start_tx_queue(dev);
+
+	if (debug > 1)
+		printk(KERN_DEBUG"%s: rtl8129_open() ioaddr %#lx IRQ %d"
+			   " GP Pins %2.2x %s-duplex.\n",
+			   dev->name, ioaddr, dev->irq, inb(ioaddr + GPPinData),
+			   tp->full_duplex ? "full" : "half");
+
+	/* Set the timer to switch to check for link beat and perhaps switch
+	   to an alternate media type. */
+	init_timer(&tp->timer);
+	tp->timer.expires = jiffies + 3*HZ;
+	tp->timer.data = (unsigned long)dev;
+	tp->timer.function = &rtl8129_timer;
+	add_timer(&tp->timer);
+
+	return 0;
+}
+
+/* Start the hardware at open or resume. */
+static void rtl_hw_start(struct net_device *dev)
+{
+	struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	int i;
+
+	/* Soft reset the chip. */
+	outb(CmdReset, ioaddr + ChipCmd);
+	/* Check that the chip has finished the reset. */
+	for (i = 1000; i > 0; i--)
+		if ((inb(ioaddr + ChipCmd) & CmdReset) == 0)
+			break;
+	/* Restore our idea of the MAC address. */
+	outb(0xC0, ioaddr + Cfg9346);
+	outl(cpu_to_le32(*(u32*)(dev->dev_addr + 0)), ioaddr + MAC0 + 0);
+	outl(cpu_to_le32(*(u32*)(dev->dev_addr + 4)), ioaddr + MAC0 + 4);
+
+	/* Hmmm, do these belong here? */
+	tp->cur_rx = 0;
+
+	/* Must enable Tx/Rx before setting transfer thresholds! */
+	outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
+	outl(tp->rx_config, ioaddr + RxConfig);
+	/* Check this value: the documentation contradicts ifself.  Is the
+	   IFG correct with bit 28:27 zero, or with |0x03000000 ? */
+	outl((TX_DMA_BURST<<8), ioaddr + TxConfig);
+
+	/* This is check_duplex() */
+	if (tp->phys[0] >= 0  ||  (tp->drv_flags & HAS_MII_XCVR)) {
+		u16 mii_reg5 = mdio_read(dev, tp->phys[0], 5);
+		if (mii_reg5 == 0xffff)
+			;					/* Not there */
+		else if ((mii_reg5 & 0x0100) == 0x0100
+				 || (mii_reg5 & 0x00C0) == 0x0040)
+			tp->full_duplex = 1;
+		if (debug > 1)
+			printk(KERN_INFO"%s: Setting %s%s-duplex based on"
+				   " auto-negotiated partner ability %4.4x.\n", dev->name,
+				   mii_reg5 == 0 ? "" :
+				   (mii_reg5 & 0x0180) ? "100mbps " : "10mbps ",
+				   tp->full_duplex ? "full" : "half", mii_reg5);
+	}
+
+	outb(tp->full_duplex ? 0x60 : 0x20, ioaddr + Config1);
+	outb(0x00, ioaddr + Cfg9346);
+
+	outl(virt_to_bus(tp->rx_ring), ioaddr + RxBuf);
+	/* Start the chip's Tx and Rx process. */
+	outl(0, ioaddr + RxMissed);
+	set_rx_mode(dev);
+	outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
+	/* Enable all known interrupts by setting the interrupt mask. */
+	outw(PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver
+		 | TxErr | TxOK | RxErr | RxOK, ioaddr + IntrMask);
+
+}
+
+static void rtl8129_timer(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct rtl8129_private *np = (struct rtl8129_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	int next_tick = 60*HZ;
+	int mii_reg5 = mdio_read(dev, np->phys[0], 5);
+
+	if (! np->duplex_lock  &&  mii_reg5 != 0xffff) {
+		int duplex = (mii_reg5&0x0100) || (mii_reg5 & 0x01C0) == 0x0040;
+		if (np->full_duplex != duplex) {
+			np->full_duplex = duplex;
+			printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d link"
+				   " partner ability of %4.4x.\n", dev->name,
+				   np->full_duplex ? "full" : "half", np->phys[0], mii_reg5);
+			outb(0xC0, ioaddr + Cfg9346);
+			outb(np->full_duplex ? 0x60 : 0x20, ioaddr + Config1);
+			outb(0x00, ioaddr + Cfg9346);
+		}
+	}
+#if LINUX_VERSION_CODE < 0x20300
+	/* Check for bogusness. */
+	if (inw(ioaddr + IntrStatus) & (TxOK | RxOK)) {
+		int status = inw(ioaddr + IntrStatus);			/* Double check */
+		if (status & (TxOK | RxOK)  &&  ! dev->interrupt) {
+			printk(KERN_ERR "%s: RTL8139 Interrupt line blocked, status %x.\n",
+				   dev->name, status);
+			rtl8129_interrupt(dev->irq, dev, 0);
+		}
+	}
+	if (dev->tbusy  &&  jiffies - dev->trans_start >= 2*TX_TIMEOUT)
+		rtl8129_tx_timeout(dev);
+#else
+	if (netif_queue_paused(dev)  &&
+		np->cur_tx - np->dirty_tx > 1  &&
+		(jiffies - dev->trans_start) > TX_TIMEOUT) {
+		rtl8129_tx_timeout(dev);
+	}
+#endif
+
+#if defined(RTL_TUNE_TWISTER)
+	/* This is a complicated state machine to configure the "twister" for
+	   impedance/echos based on the cable length.
+	   All of this is magic and undocumented.
+	   */
+	if (np->twistie) switch(np->twistie) {
+	case 1: {
+		if (inw(ioaddr + CSCR) & CSCR_LinkOKBit) {
+			/* We have link beat, let us tune the twister. */
+			outw(CSCR_LinkDownOffCmd, ioaddr + CSCR);
+			np->twistie = 2;	/* Change to state 2. */
+			next_tick = HZ/10;
+		} else {
+			/* Just put in some reasonable defaults for when beat returns. */
+			outw(CSCR_LinkDownCmd, ioaddr + CSCR);
+			outl(0x20,ioaddr + FIFOTMS);	/* Turn on cable test mode. */
+			outl(PARA78_default ,ioaddr + PARA78);
+			outl(PARA7c_default ,ioaddr + PARA7c);
+			np->twistie = 0;	/* Bail from future actions. */
+		}
+	} break;
+	case 2: {
+		/* Read how long it took to hear the echo. */
+		int linkcase = inw(ioaddr + CSCR) & CSCR_LinkStatusBits;
+		if (linkcase == 0x7000) np->twist_row = 3;
+		else if (linkcase == 0x3000) np->twist_row = 2;
+		else if (linkcase == 0x1000) np->twist_row = 1;
+		else np->twist_row = 0;
+		np->twist_col = 0;
+		np->twistie = 3;	/* Change to state 2. */
+		next_tick = HZ/10;
+	} break;
+	case 3: {
+		/* Put out four tuning parameters, one per 100msec. */
+		if (np->twist_col == 0) outw(0, ioaddr + FIFOTMS);
+		outl(param[(int)np->twist_row][(int)np->twist_col], ioaddr + PARA7c);
+		next_tick = HZ/10;
+		if (++np->twist_col >= 4) {
+			/* For short cables we are done.
+			   For long cables (row == 3) check for mistune. */
+			np->twistie = (np->twist_row == 3) ? 4 : 0;
+		}
+	} break;
+	case 4: {
+		/* Special case for long cables: check for mistune. */
+		if ((inw(ioaddr + CSCR) & CSCR_LinkStatusBits) == 0x7000) {
+			np->twistie = 0;
+			break;
+		} else {
+			outl(0xfb38de03, ioaddr + PARA7c);
+			np->twistie = 5;
+			next_tick = HZ/10;
+		}
+	} break;
+	case 5: {
+		/* Retune for shorter cable (column 2). */
+		outl(0x20,ioaddr + FIFOTMS);
+		outl(PARA78_default,  ioaddr + PARA78);
+		outl(PARA7c_default,  ioaddr + PARA7c);
+		outl(0x00,ioaddr + FIFOTMS);
+		np->twist_row = 2;
+		np->twist_col = 0;
+		np->twistie = 3;
+		next_tick = HZ/10;
+	} break;
+	}
+#endif
+
+	if (debug > 2) {
+		if (np->drv_flags & HAS_MII_XCVR)
+			printk(KERN_DEBUG"%s: Media selection tick, GP pins %2.2x.\n",
+				   dev->name, inb(ioaddr + GPPinData));
+		else
+			printk(KERN_DEBUG"%s: Media selection tick, Link partner %4.4x.\n",
+				   dev->name, inw(ioaddr + NWayLPAR));
+		printk(KERN_DEBUG"%s:  Other registers are IntMask %4.4x IntStatus %4.4x"
+			   " RxStatus %4.4x.\n",
+			   dev->name, inw(ioaddr + IntrMask), inw(ioaddr + IntrStatus),
+			   inl(ioaddr + RxEarlyStatus));
+		printk(KERN_DEBUG"%s:  Chip config %2.2x %2.2x.\n",
+			   dev->name, inb(ioaddr + Config0), inb(ioaddr + Config1));
+	}
+
+	np->timer.expires = jiffies + next_tick;
+	add_timer(&np->timer);
+}
+
+static void rtl8129_tx_timeout(struct net_device *dev)
+{
+	struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	int mii_reg, i;
+
+	if (debug > 0)
+		printk(KERN_ERR "%s: Transmit timeout, status %2.2x %4.4x "
+			   "media %2.2x.\n",
+			   dev->name, inb(ioaddr + ChipCmd), inw(ioaddr + IntrStatus),
+			   inb(ioaddr + GPPinData));
+
+	/* Disable interrupts by clearing the interrupt mask. */
+	outw(0x0000, ioaddr + IntrMask);
+	/* Emit info to figure out what went wrong. */
+	printk(KERN_DEBUG "%s: Tx queue start entry %d  dirty entry %d%s.\n",
+		   dev->name, tp->cur_tx, tp->dirty_tx, tp->tx_full ? ", full" : "");
+	for (i = 0; i < NUM_TX_DESC; i++)
+		printk(KERN_DEBUG "%s:  Tx descriptor %d is %8.8x.%s\n",
+			   dev->name, i, inl(ioaddr + TxStatus0 + i*4),
+			   i == tp->dirty_tx % NUM_TX_DESC ? " (queue head)" : "");
+	printk(KERN_DEBUG "%s: MII #%d registers are:", dev->name, tp->phys[0]);
+	for (mii_reg = 0; mii_reg < 8; mii_reg++)
+		printk(" %4.4x", mdio_read(dev, tp->phys[0], mii_reg));
+	printk(".\n");
+
+	/* Stop a shared interrupt from scavenging while we are. */
+	tp->dirty_tx = tp->cur_tx = 0;
+	/* Dump the unsent Tx packets. */
+	for (i = 0; i < NUM_TX_DESC; i++) {
+		if (tp->tx_skbuff[i]) {
+			dev_free_skb(tp->tx_skbuff[i]);
+			tp->tx_skbuff[i] = 0;
+			tp->stats.tx_dropped++;
+		}
+	}
+	rtl_hw_start(dev);
+	netif_unpause_tx_queue(dev);
+	tp->tx_full = 0;
+	return;
+}
+
+
+/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
+static void
+rtl8129_init_ring(struct net_device *dev)
+{
+	struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
+	int i;
+
+	tp->tx_full = 0;
+	tp->dirty_tx = tp->cur_tx = 0;
+
+	for (i = 0; i < NUM_TX_DESC; i++) {
+		tp->tx_skbuff[i] = 0;
+		tp->tx_buf[i] = &tp->tx_bufs[i*TX_BUF_SIZE];
+	}
+}
+
+static int
+rtl8129_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	int entry;
+
+#ifdef CONFIG_LEDMAN
+	ledman_cmd(LEDMAN_CMD_SET,
+		(dev->name[3] == '0') ? LEDMAN_LAN1_TX : LEDMAN_LAN2_TX);
+#endif
+
+	if (netif_pause_tx_queue(dev) != 0) {
+		/* This watchdog code is redundant with the media monitor timer. */
+		if (jiffies - dev->trans_start > TX_TIMEOUT)
+			rtl8129_tx_timeout(dev);
+		return 1;
+	}
+
+	/* Calculate the next Tx descriptor entry. */
+	entry = tp->cur_tx % NUM_TX_DESC;
+
+	tp->tx_skbuff[entry] = skb;
+	if ((long)skb->data & 3) {			/* Must use alignment buffer. */
+		memcpy(tp->tx_buf[entry], skb->data, skb->len);
+		outl(virt_to_bus(tp->tx_buf[entry]), ioaddr + TxAddr0 + entry*4);
+	} else
+		outl(virt_to_bus(skb->data), ioaddr + TxAddr0 + entry*4);
+	/* Note: the chip doesn't have auto-pad! */
+	outl(tp->tx_flag | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN),
+		 ioaddr + TxStatus0 + entry*4);
+
+	/* There is a race condition here -- we might read dirty_tx, take an
+	   interrupt that clears the Tx queue, and only then set tx_full.
+	   So we do this in two phases. */
+	if (++tp->cur_tx - tp->dirty_tx >= NUM_TX_DESC) {
+		set_bit(0, &tp->tx_full);
+		if (tp->cur_tx - (volatile unsigned int)tp->dirty_tx < NUM_TX_DESC) {
+			clear_bit(0, &tp->tx_full);
+			netif_unpause_tx_queue(dev);
+		} else
+			netif_stop_tx_queue(dev);
+	} else
+		netif_unpause_tx_queue(dev);
+
+	dev->trans_start = jiffies;
+	if (debug > 4)
+		printk(KERN_DEBUG"%s: Queued Tx packet at %p size %d to slot %d.\n",
+			   dev->name, skb->data, (int)skb->len, entry);
+
+	return 0;
+}
+
+/* The interrupt handler does all of the Rx thread work and cleans up
+   after the Tx thread. */
+static void rtl8129_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *)dev_instance;
+	struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
+	int boguscnt = max_interrupt_work;
+	long ioaddr = dev->base_addr;
+	int link_changed = 0;		/* Grrr, avoid bogus "uninitialized" warning */
+
+#if defined(__i386__)  &&  LINUX_VERSION_CODE < 0x20123
+	/* A lock to prevent simultaneous entry bug on Intel SMP machines. */
+	if (test_and_set_bit(0, (void*)&dev->interrupt)) {
+		printk(KERN_ERR"%s: SMP simultaneous entry of an interrupt handler.\n",
+			   dev->name);
+		dev->interrupt = 0;	/* Avoid halting machine. */
+		return;
+	}
+#endif
+
+	do {
+		int status = inw(ioaddr + IntrStatus);
+		/* Acknowledge all of the current interrupt sources ASAP, but
+		   an first get an additional status bit from CSCR. */
+		if (status & RxUnderrun)
+			link_changed = inw(ioaddr+CSCR) & CSCR_LinkChangeBit;
+		outw(status, ioaddr + IntrStatus);
+
+		if (debug > 4)
+			printk(KERN_DEBUG"%s: interrupt  status=%#4.4x new intstat=%#4.4x.\n",
+				   dev->name, status, inw(ioaddr + IntrStatus));
+
+		if ((status & (PCIErr|PCSTimeout|RxUnderrun|RxOverflow|RxFIFOOver
+					   |TxErr|TxOK|RxErr|RxOK)) == 0)
+			break;
+
+		if (status & (RxOK|RxUnderrun|RxOverflow|RxFIFOOver))/* Rx interrupt */
+			rtl8129_rx(dev);
+
+		if (status & (TxOK | TxErr)) {
+			unsigned int dirty_tx = tp->dirty_tx;
+
+			while (tp->cur_tx - dirty_tx > 0) {
+				int entry = dirty_tx % NUM_TX_DESC;
+				int txstatus = inl(ioaddr + TxStatus0 + entry*4);
+
+				if ( ! (txstatus & (TxStatOK | TxUnderrun | TxAborted)))
+					break;			/* It still hasn't been Txed */
+
+				/* Note: TxCarrierLost is always asserted at 100mbps. */
+				if (txstatus & (TxOutOfWindow | TxAborted)) {
+					/* There was an major error, log it. */
+					if (debug > 1)
+						printk(KERN_NOTICE"%s: Transmit error, Tx status %8.8x.\n",
+							   dev->name, txstatus);
+					tp->stats.tx_errors++;
+					if (txstatus&TxAborted) {
+						tp->stats.tx_aborted_errors++;
+						outl(TX_DMA_BURST << 8, ioaddr + TxConfig);
+					}
+					if (txstatus&TxCarrierLost) tp->stats.tx_carrier_errors++;
+					if (txstatus&TxOutOfWindow) tp->stats.tx_window_errors++;
+#ifdef ETHER_STATS
+					if ((txstatus & 0x0f000000) == 0x0f000000)
+						tp->stats.collisions16++;
+#endif
+				} else {
+					if (txstatus & TxUnderrun) {
+						/* Add 64 to the Tx FIFO threshold. */
+						if (tp->tx_flag <  0x00300000)
+							tp->tx_flag += 0x00020000;
+						tp->stats.tx_fifo_errors++;
+					}
+					tp->stats.collisions += (txstatus >> 24) & 15;
+#if LINUX_VERSION_CODE > 0x20119
+					tp->stats.tx_bytes += txstatus & 0x7ff;
+#endif
+					tp->stats.tx_packets++;
+				}
+
+				/* Free the original skb. */
+				dev_free_skb_irq(tp->tx_skbuff[entry]);
+				tp->tx_skbuff[entry] = 0;
+				if (test_bit(0, &tp->tx_full)) {
+					/* The ring is no longer full, clear tbusy. */
+					clear_bit(0, &tp->tx_full);
+					netif_resume_tx_queue(dev);
+				}
+				dirty_tx++;
+			}
+
+#ifndef final_version
+			if (tp->cur_tx - dirty_tx > NUM_TX_DESC) {
+				printk(KERN_ERR"%s: Out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
+					   dev->name, dirty_tx, tp->cur_tx, (int)tp->tx_full);
+				dirty_tx += NUM_TX_DESC;
+			}
+#endif
+			tp->dirty_tx = dirty_tx;
+		}
+
+		/* Check uncommon events with one test. */
+		if (status & (PCIErr|PCSTimeout |RxUnderrun|RxOverflow|RxFIFOOver
+					  |TxErr|RxErr)) {
+			if (debug > 2)
+				printk(KERN_NOTICE"%s: Abnormal interrupt, status %8.8x.\n",
+					   dev->name, status);
+
+			if (status == 0xffff)
+				break;
+			/* Update the error count. */
+			tp->stats.rx_missed_errors += inl(ioaddr + RxMissed);
+			outl(0, ioaddr + RxMissed);
+
+			if ((status & RxUnderrun)  &&  link_changed  &&
+				(tp->drv_flags & HAS_LNK_CHNG)) {
+				/* Really link-change on new chips. */
+				int lpar = inw(ioaddr + NWayLPAR);
+				int duplex = (lpar&0x0100) || (lpar & 0x01C0) == 0x0040
+					|| tp->duplex_lock;
+				if (debug > 1)
+					printk(KERN_DEBUG "%s: Link changed, link partner "
+						   "%4.4x new duplex %d.\n",
+						   dev->name, lpar, duplex);
+				if (tp->full_duplex != duplex) {
+					tp->full_duplex = duplex;
+					outb(0xC0, ioaddr + Cfg9346);
+					outb(tp->full_duplex ? 0x60 : 0x20, ioaddr + Config1);
+					outb(0x00, ioaddr + Cfg9346);
+				}
+				status &= ~RxUnderrun;
+			}
+			if (status & (RxUnderrun | RxOverflow | RxErr | RxFIFOOver))
+				tp->stats.rx_errors++;
+
+			if (status & (PCSTimeout)) tp->stats.rx_length_errors++;
+			if (status & (RxUnderrun|RxFIFOOver)) tp->stats.rx_fifo_errors++;
+			if (status & RxOverflow) {
+				tp->stats.rx_over_errors++;
+				tp->cur_rx = inw(ioaddr + RxBufAddr) % tp->rx_buf_len;
+				outw(tp->cur_rx - 16, ioaddr + RxBufPtr);
+			}
+			if (status & PCIErr) {
+				u32 pci_cmd_status;
+				pci_read_config_dword(tp->pci_dev, PCI_COMMAND, &pci_cmd_status);
+
+				printk(KERN_ERR "%s: PCI Bus error %4.4x.\n",
+					   dev->name, pci_cmd_status);
+			}
+		}
+		if (--boguscnt < 0) {
+			printk(KERN_WARNING"%s: Too much work at interrupt, "
+				   "IntrStatus=0x%4.4x.\n",
+				   dev->name, status);
+			/* Clear all interrupt sources. */
+			outw(0xffff, ioaddr + IntrStatus);
+			break;
+		}
+	} while (1);
+
+	if (debug > 3)
+		printk(KERN_DEBUG"%s: exiting interrupt, intr_status=%#4.4x.\n",
+			   dev->name, inw(ioaddr + IntrStatus));
+
+#if defined(__i386__)  &&  LINUX_VERSION_CODE < 0x20123
+	clear_bit(0, (void*)&dev->interrupt);
+#endif
+	return;
+}
+
+/* The data sheet doesn't describe the Rx ring at all, so I'm guessing at the
+   field alignments and semantics. */
+static int rtl8129_rx(struct net_device *dev)
+{
+	struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	unsigned char *rx_ring = tp->rx_ring;
+	u16 cur_rx = tp->cur_rx;
+
+	if (debug > 4)
+		printk(KERN_DEBUG"%s: In rtl8129_rx(), current %4.4x BufAddr %4.4x,"
+			   " free to %4.4x, Cmd %2.2x.\n",
+			   dev->name, cur_rx, inw(ioaddr + RxBufAddr),
+			   inw(ioaddr + RxBufPtr), inb(ioaddr + ChipCmd));
+
+#ifdef CONFIG_LEDMAN
+	ledman_cmd(LEDMAN_CMD_SET,
+		(dev->name[3] == '0') ? LEDMAN_LAN1_RX : LEDMAN_LAN2_RX);
+#endif
+
+	while ((inb(ioaddr + ChipCmd) & RxBufEmpty) == 0) {
+		int ring_offset = cur_rx % tp->rx_buf_len;
+		u32 rx_status = le32_to_cpu(*(u32*)(rx_ring + ring_offset));
+		int rx_size = rx_status >> 16; 				/* Includes the CRC. */
+
+		if (debug > 4) {
+			int i;
+			printk(KERN_DEBUG"%s:  rtl8129_rx() status %4.4x, size %4.4x,"
+				   " cur %4.4x.\n",
+				   dev->name, rx_status, rx_size, cur_rx);
+			printk(KERN_DEBUG"%s: Frame contents ", dev->name);
+			for (i = 0; i < 70; i++)
+				printk(" %2.2x", rx_ring[ring_offset + i]);
+			printk(".\n");
+		}
+		if (rx_status & (RxBadSymbol|RxRunt|RxTooLong|RxCRCErr|RxBadAlign)) {
+			if (debug > 1)
+				printk(KERN_DEBUG"%s: Ethernet frame had errors,"
+					   " status %8.8x.\n", dev->name, rx_status);
+			if (rx_status == 0xffffffff) {
+				if (debug > 0)
+					printk(KERN_NOTICE"%s: Invalid receive status at ring "
+						   "offset %4.4x\n", dev->name, ring_offset);
+				rx_status = 0;
+			}
+			if (rx_status & RxTooLong) {
+				if (debug > 0)
+					printk(KERN_NOTICE"%s: Oversized Ethernet frame, status %4.4x!\n",
+						   dev->name, rx_status);
+				/* A.C.: The chip hangs here. */
+			}
+			tp->stats.rx_errors++;
+			if (rx_status & (RxBadSymbol|RxBadAlign))
+				tp->stats.rx_frame_errors++;
+			if (rx_status & (RxRunt|RxTooLong)) tp->stats.rx_length_errors++;
+			if (rx_status & RxCRCErr) tp->stats.rx_crc_errors++;
+			/* Reset the receiver, based on RealTek recommendation. (Bug?) */
+			tp->cur_rx = 0;
+			outb(CmdTxEnb, ioaddr + ChipCmd);
+			/* A.C.: Reset the multicast list. */
+			set_rx_mode(dev);
+			outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
+		} else {
+			/* Malloc up new buffer, compatible with net-2e. */
+			/* Omit the four octet CRC from the length. */
+			struct sk_buff *skb;
+			int pkt_size = rx_size - 4;
+
+			skb = dev_alloc_skb(pkt_size + 2);
+			if (skb == NULL) {
+				printk(KERN_WARNING"%s: Memory squeeze, deferring packet.\n",
+					   dev->name);
+				/* We should check that some rx space is free.
+				   If not, free one and mark stats->rx_dropped++. */
+				tp->stats.rx_dropped++;
+				break;
+			}
+			skb->dev = dev;
+			skb_reserve(skb, 2);	/* 16 byte align the IP fields. */
+			if (ring_offset + rx_size > tp->rx_buf_len) {
+				int semi_count = tp->rx_buf_len - ring_offset - 4;
+				/* This could presumably use two calls to copy_and_sum()? */
+				memcpy(skb_put(skb, semi_count), &rx_ring[ring_offset + 4],
+					   semi_count);
+				memcpy(skb_put(skb, pkt_size-semi_count), rx_ring,
+					   pkt_size-semi_count);
+				if (debug > 4) {
+					int i;
+					printk(KERN_DEBUG"%s:  Frame wrap @%d",
+						   dev->name, semi_count);
+					for (i = 0; i < 16; i++)
+						printk(" %2.2x", rx_ring[i]);
+					printk(".\n");
+					memset(rx_ring, 0xcc, 16);
+				}
+			} else {
+				eth_copy_and_sum(skb, &rx_ring[ring_offset + 4],
+								 pkt_size, 0);
+				skb_put(skb, pkt_size);
+			}
+			skb->protocol = eth_type_trans(skb, dev);
+			netif_rx(skb);
+#if LINUX_VERSION_CODE > 0x20119
+			tp->stats.rx_bytes += pkt_size;
+#endif
+			tp->stats.rx_packets++;
+		}
+
+		cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
+		outw(cur_rx - 16, ioaddr + RxBufPtr);
+	}
+	if (debug > 4)
+		printk(KERN_DEBUG"%s: Done rtl8129_rx(), current %4.4x BufAddr %4.4x,"
+			   " free to %4.4x, Cmd %2.2x.\n",
+			   dev->name, cur_rx, inw(ioaddr + RxBufAddr),
+			   inw(ioaddr + RxBufPtr), inb(ioaddr + ChipCmd));
+	tp->cur_rx = cur_rx;
+	return 0;
+}
+
+static int
+rtl8129_close(struct net_device *dev)
+{
+	long ioaddr = dev->base_addr;
+	struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
+	int i;
+
+	netif_stop_tx_queue(dev);
+
+	if (debug > 1)
+		printk(KERN_DEBUG"%s: Shutting down ethercard, status was 0x%4.4x.\n",
+			   dev->name, inw(ioaddr + IntrStatus));
+
+	/* Disable interrupts by clearing the interrupt mask. */
+	outw(0x0000, ioaddr + IntrMask);
+
+	/* Stop the chip's Tx and Rx DMA processes. */
+	outb(0x00, ioaddr + ChipCmd);
+
+	/* Update the error counts. */
+	tp->stats.rx_missed_errors += inl(ioaddr + RxMissed);
+	outl(0, ioaddr + RxMissed);
+
+	del_timer(&tp->timer);
+
+	free_irq(dev->irq, dev);
+
+	for (i = 0; i < NUM_TX_DESC; i++) {
+		if (tp->tx_skbuff[i])
+			dev_free_skb(tp->tx_skbuff[i]);
+		tp->tx_skbuff[i] = 0;
+	}
+	kfree(tp->rx_ring);
+	tp->rx_ring = 0;
+
+	/* Green! Put the chip in low-power mode. */
+	outb(0xC0, ioaddr + Cfg9346);
+	outb(0x03, ioaddr + Config1);
+	outb('H', ioaddr + HltClk);		/* 'R' would leave the clock running. */
+
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct rtl8129_private *np = (struct rtl8129_private *)dev->priv;
+	u16 *data = (u16 *)&rq->ifr_data;
+
+	switch(cmd) {
+	case SIOCGMIIPHY:		/* Get the address of the PHY in use. */
+		data[0] = np->phys[0] & 0x3f;
+		/* Fall Through */
+	case SIOCGMIIREG:		/* Read the specified MII register. */
+		data[3] = mdio_read(dev, data[0], data[1] & 0x1f);
+		return 0;
+	case SIOCSMIIREG:		/* Write the specified MII register */
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		if (data[0] == np->phys[0]) {
+			u16 value = data[2];
+			switch (data[1]) {
+			case 0:
+				/* Check for autonegotiation on or reset. */
+				np->medialock = (value & 0x9000) ? 0 : 1;
+				if (np->medialock)
+					np->full_duplex = (value & 0x0100) ? 1 : 0;
+				break;
+			case 4: np->advertising = value; break;
+			}
+		}
+		mdio_write(dev, data[0], data[1] & 0x1f, data[2]);
+		return 0;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static struct net_device_stats *
+rtl8129_get_stats(struct net_device *dev)
+{
+	struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+
+	if (netif_running(dev)) {
+		tp->stats.rx_missed_errors += inl(ioaddr + RxMissed);
+		outl(0, ioaddr + RxMissed);
+	}
+
+	return &tp->stats;
+}
+
+/* Set or clear the multicast filter for this adaptor.
+   This routine is not state sensitive and need not be SMP locked. */
+
+static unsigned const ethernet_polynomial = 0x04c11db7U;
+static inline u32 ether_crc(int length, unsigned char *data)
+{
+	int crc = -1;
+
+	while (--length >= 0) {
+		unsigned char current_octet = *data++;
+		int bit;
+		for (bit = 0; bit < 8; bit++, current_octet >>= 1)
+			crc = (crc << 1) ^
+				((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
+	}
+	return crc;
+}
+
+/* Bits in RxConfig. */
+enum rx_mode_bits {
+	AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0x08,
+	AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01,
+};
+
+static void set_rx_mode(struct net_device *dev)
+{
+	struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	u32 mc_filter[2];		 /* Multicast hash filter */
+	int i, rx_mode;
+
+	if (debug > 3)
+		printk(KERN_DEBUG"%s:   set_rx_mode(%4.4x) done -- Rx config %8.8x.\n",
+			   dev->name, dev->flags, inl(ioaddr + RxConfig));
+
+	/* Note: do not reorder, GCC is clever about common statements. */
+	if (dev->flags & IFF_PROMISC) {
+		/* Unconditionally log net taps. */
+		printk(KERN_NOTICE"%s: Promiscuous mode enabled.\n", dev->name);
+		rx_mode = AcceptBroadcast|AcceptMulticast|AcceptMyPhys|AcceptAllPhys;
+		mc_filter[1] = mc_filter[0] = 0xffffffff;
+	} else if ((dev->mc_count > multicast_filter_limit)
+			   || (dev->flags & IFF_ALLMULTI)) {
+		/* Too many to filter perfectly -- accept all multicasts. */
+		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+		mc_filter[1] = mc_filter[0] = 0xffffffff;
+	} else {
+		struct dev_mc_list *mclist;
+		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+		mc_filter[1] = mc_filter[0] = 0;
+		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+			 i++, mclist = mclist->next)
+			set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26, mc_filter);
+	}
+	/* We can safely update without stopping the chip. */
+	outl(tp->rx_config | rx_mode, ioaddr + RxConfig);
+	outl(mc_filter[0], ioaddr + MAR0 + 0);
+	outl(mc_filter[1], ioaddr + MAR0 + 4);
+	return;
+}
+
+
+static int rtl_pwr_event(void *dev_instance, int event)
+{
+	struct net_device *dev = dev_instance;
+	struct rtl8129_private *np = (struct rtl8129_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+
+	if (debug > 1)
+		printk("%s: Handling power event %d.\n", dev->name, event);
+	switch(event) {
+	case DRV_ATTACH:
+		MOD_INC_USE_COUNT;
+		break;
+	case DRV_SUSPEND:
+		netif_device_detach(dev);
+		/* Disable interrupts, stop Tx and Rx. */
+		outw(0x0000, ioaddr + IntrMask);
+		outb(0x00, ioaddr + ChipCmd);
+		/* Update the error counts. */
+		np->stats.rx_missed_errors += inl(ioaddr + RxMissed);
+		outl(0, ioaddr + RxMissed);
+		break;
+	case DRV_RESUME:
+		netif_device_attach(dev);
+		rtl_hw_start(dev);
+		break;
+	case DRV_DETACH: {
+		struct net_device **devp, **next;
+		if (dev->flags & IFF_UP) {
+			dev_close(dev);
+			dev->flags &= ~(IFF_UP|IFF_RUNNING);
+		}
+		unregister_netdev(dev);
+		release_region(dev->base_addr, pci_tbl[np->chip_id].io_size);
+#ifndef USE_IO_OPS
+		iounmap((char *)dev->base_addr);
+#endif
+		for (devp = &root_rtl8129_dev; *devp; devp = next) {
+			next = &((struct rtl8129_private *)(*devp)->priv)->next_module;
+			if (*devp == dev) {
+				*devp = *next;
+				break;
+			}
+		}
+		if (np->priv_addr)
+			kfree(np->priv_addr);
+		kfree(dev);
+		MOD_DEC_USE_COUNT;
+		break;
+	}
+	}
+
+	return 0;
+}
+
+#ifdef CARDBUS
+
+#include <pcmcia/driver_ops.h>
+
+static dev_node_t *rtl8139_attach(dev_locator_t *loc)
+{
+	struct net_device *dev;
+	u16 dev_id;
+	u32 pciaddr;
+	u8 bus, devfn, irq;
+	long hostaddr;
+	/* Note: the chip index should match the 8139B pci_tbl[] entry. */
+	int chip_idx = 2;
+
+	if (loc->bus != LOC_PCI) return NULL;
+	bus = loc->b.pci.bus; devfn = loc->b.pci.devfn;
+	printk(KERN_DEBUG "rtl8139_attach(bus %d, function %d)\n", bus, devfn);
+#ifdef USE_IO_OPS
+	pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &pciaddr);
+	hostaddr = pciaddr & PCI_BASE_ADDRESS_IO_MASK;
+#else
+	pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_1, &pciaddr);
+	hostaddr = (long)ioremap(pciaddr & PCI_BASE_ADDRESS_MEM_MASK,
+							 pci_tbl[chip_idx].io_size);
+#endif
+	pcibios_read_config_byte(bus, devfn, PCI_INTERRUPT_LINE, &irq);
+	pcibios_read_config_word(bus, devfn, PCI_DEVICE_ID, &dev_id);
+	if (hostaddr == 0 || irq == 0) {
+		printk(KERN_ERR "The %s interface at %d/%d was not assigned an %s.\n"
+			   KERN_ERR "  It will not be activated.\n",
+			   pci_tbl[chip_idx].name, bus, devfn,
+			   hostaddr == 0 ? "address" : "IRQ");
+		return NULL;
+	}
+	dev = rtl8139_probe1(pci_find_slot(bus, devfn), NULL,
+						 hostaddr, irq, chip_idx, 0);
+	if (dev) {
+		dev_node_t *node = kmalloc(sizeof(dev_node_t), GFP_KERNEL);
+		strcpy(node->dev_name, dev->name);
+		node->major = node->minor = 0;
+		node->next = NULL;
+		MOD_INC_USE_COUNT;
+		return node;
+	}
+	return NULL;
+}
+
+static void rtl8139_detach(dev_node_t *node)
+{
+	struct net_device **devp, **next;
+	printk(KERN_INFO "rtl8139_detach(%s)\n", node->dev_name);
+	for (devp = &root_rtl8129_dev; *devp; devp = next) {
+		next = &((struct rtl8129_private *)(*devp)->priv)->next_module;
+		if (strcmp((*devp)->name, node->dev_name) == 0) break;
+	}
+	if (*devp) {
+		struct rtl8129_private *np =
+			(struct rtl8129_private *)(*devp)->priv;
+		unregister_netdev(*devp);
+		release_region((*devp)->base_addr, pci_tbl[np->chip_id].io_size);
+#ifndef USE_IO_OPS
+		iounmap((char *)(*devp)->base_addr);
+#endif
+		kfree(*devp);
+		if (np->priv_addr)
+			kfree(np->priv_addr);
+		*devp = *next;
+		kfree(node);
+		MOD_DEC_USE_COUNT;
+	}
+}
+
+struct driver_operations realtek_ops = {
+	"realtek_cb",
+	rtl8139_attach, /*rtl8139_suspend*/0, /*rtl8139_resume*/0, rtl8139_detach
+};
+
+#endif  /* Cardbus support */
+
+int rtl8139_init_module(void)
+{
+	if (debug)					/* Emit version even if no cards detected. */
+		printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
+#ifdef CARDBUS
+	register_driver(&realtek_ops);
+	return 0;
+#else
+	return pci_module_init(&rtl8139_drv_id);
+#endif
+}
+
+void rtl8139_cleanup_module(void)
+{
+	struct net_device *next_dev;
+
+#ifdef CARDBUS
+	unregister_driver(&realtek_ops);
+#else
+	pci_unregister_driver(&rtl8139_drv_id);
+#endif
+
+	while (root_rtl8129_dev) {
+		struct rtl8129_private *np = (void *)(root_rtl8129_dev->priv);
+		unregister_netdev(root_rtl8129_dev);
+		release_region(root_rtl8129_dev->base_addr,
+					   pci_tbl[np->chip_id].io_size);
+#ifndef USE_IO_OPS
+		iounmap((char *)(root_rtl8129_dev->base_addr));
+#endif
+		next_dev = np->next_module;
+		if (np->priv_addr)
+			kfree(np->priv_addr);
+		kfree(root_rtl8129_dev);
+		root_rtl8129_dev = next_dev;
+	}
+}
+
+module_init(rtl8139_init_module);
+module_exit(rtl8139_cleanup_module);
+
+/*
+ * Local variables:
+ *  compile-command: "gcc -DMODULE -Wall -Wstrict-prototypes -O6 -c rtl8139.c"
+ *  cardbus-compile-command: "gcc -DCARDBUS -DMODULE -Wall -Wstrict-prototypes -O6 -c rtl8139.c -o realtek_cb.o -I/usr/src/pcmcia/include/"
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff -urN linux-2.4.29/drivers/net/s3c2500.c linux-2.4.29-uc1/drivers/net/s3c2500.c
--- linux-2.4.29/drivers/net/s3c2500.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/s3c2500.c	2005-06-14 02:12:09.000000000 +0100
@@ -0,0 +1,3034 @@
+/***********************************************************************
+ *  s3c2500.c : Samsung S3c2500x/a/b ethernet driver for linux
+
+    S3c2500 Communication Processor
+    Copyright (c) 2002-2003 Arcturus Networks Inc. <www.ArcturusNetworks.com>
+			    by MaTed mated@ArcturusNetworks.com 
+
+      based on isa-skeleton: A network driver outline for linux.
+	    Written 1993-94 by Donald Becker.
+
+		Copyright 2002 Arcturus Networks Inc.
+
+	Copyright 1993 United States Government as represented by the
+	Director, National Security Agency.
+
+	This software may be used and distributed according to the terms
+	of the GNU Public License, incorporated herein by reference.
+
+	The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
+	Center of Excellence in Space Data and Information Sciences
+	   Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
+
+	This file is the first go at creating a driver for the ethernet driver
+        used by the S3C SOC. The core is the 10/100 MB Sierra Research core
+        for which there doesn't appear to be a driver for the Linux
+        operating system.
+
+	Known Limitations:
+	- Because the S3c controller is "intelligent", it manages the
+	buffer list on its own. Therefore you create the Buffer List for
+	the controller without knowing the length required. A maximum MTU
+	buffer is pre-allocated regardless of the actual requirements. Either
+	the controller firmware can be changed to pick buffers whose size
+	is closer to the actual size required, or we can memcpy (ugh!!!) to
+	a smaller buffer.
+    
+    - We need to invalidate the cache for the received buffer. If we do it
+    after we know the length, then we are doing during interrupt time (but
+    we are only invalidating the section we need to (also faster). If we do
+    it when we are preallocating the buffers, we must do the entire buffer,
+    which takes longer. Best solution would be to move it up one level, but
+    we should only do it for ethernet packets.
+
+	- module support is either non-existant or not tested (it was a SOC
+	afterall)
+
+*************************************************************************/
+
+/************************************************************************
+ * modification history
+ * --------------------
+ *	07/02/02 MaTed <mated@ArcturusNetworks.com>
+ *			- eth0 is the LAN side for some of the MIB application stuff.
+ *			  - on the 2500 (ArcNet board), eth1 is the Kendin switch, so we
+ *				need to reverse the assignments so the Kendin is eth0 (LAN 
+ *				side)
+ *			- PHY's will be changing on the new 2500 board as well
+ *			  - want to table drive the PHY.
+ *			  - going from two LSI PHYs to an intel and a Kendin switch
+ *
+ *	06/07/02 MaTed <mated@ArcturusNetworks.com>
+ *			- Algorithm change - tx now will interrupt every packet
+ *			  - CPU saving over accurate count of collisions
+ * 	05/13/02 MaTed <mated@ArcturusNetworks.com>
+ *			- Initial port to s3c2500x using s3c4530 as base
+ *			- * Nomemclature change frame descriptors are now buffer
+ *				descriptors - there are no frame descriptors, make the
+ *				change in your mind for now
+ * 	10/29/01 MaTed <mated@ArcturusNetworks.com> first go 
+ *	- PLEASE set TABS==4
+ ************************************************************************/
+/*
+  Sources:
+  - source is available from Arcturus Networks
+ 
+  Finally, keep in mind that the Linux kernel is has an API, not
+  ABI. Proprietary object-code-only distributions are not permitted
+  under the GPL.
+*/
+
+
+/***************************************
+ * CONFIGURATION
+ ***************************************/
+// MiniProfiling enable
+#define MPROFILE	0		// enable miniprofile
+// Next is so globals only set up here
+#define S3C2500_ETHERNET	1	
+
+/***********************************************
+ * INCLUDES - includes are in the included file
+ ***********************************************/
+#include "s3c2500.h"
+
+#include <asm/s3cmprofile.h>	// for the mprofiling
+
+#ifdef CONFIG_ETH_S3C2500	/* skip the entire file if not configured 	*/
+
+/*
+ * The K should give us a unique tag (date / time / revision) when pulled from
+ * BitKeeper - see bitkeeper keywords
+ */
+static const char *version =
+"S3C2500: ETH driver. Version 1.14 <www.ArcturusNetworks.com>\n";
+
+#define s3c_mdelay(n) mdelay(n)	// renamed for debugging of mdelay timing
+
+/************* DEBUG **********/
+// Also see .h file for NET_DEBUG (the higher the #, more debug code included
+
+#define VERBOSE 5		// Higher the number, The more output
+
+#define	DEBUG_CRC_OFF	0
+#define DEBUG_PHY_DUMP	0
+#define	PHY_DEBUG		0
+
+#define DEBUG_RX_DUMP	0	// for dumping Rx Structures
+#define DEBUG_SKB_DATALEN	0	// debugging skb->data_len problem (closed)
+
+#define MATED_RX_OF_BUG	0	// log and print last 10 rx buffer sizes
+                            //  on RX Overflow
+/*********** end debug *******/
+
+/*********************** MORE Configuration *********************************/
+// Define zero or more of the following
+// - can also be used to force a 100 Full duplex link
+#if defined(CONFIG_BOARD_EVS3C2500RGP) || defined(CONFIG_BOARD_S3C2500REFRGP)
+	// for eth0 ( swapped from ethernet 1) channel 0- Kendin on VX
+#define	PHY_0_FORCE	PHY_CONTROL_SPEED_100_FULL
+#endif
+#if 0		// 0-> autonegotiate
+// for eth1 ( swapped from ethernet 0) channel 1 -INTEL  
+//#define	PHY_1_FORCE PHY_CONTROL_SPEED_100_FULL
+#define	PHY_1_FORCE PHY_CONTROL_SPEED_100_HALF
+#endif
+
+/****************************************************************************
+ * A bit of an introduction for the algorithms used herein
+ * - This driver has been rewritten to use the more traditional copy buffers
+ *   - the copy routine is more optimized in that it is rolled out and
+ *     we have preknowledge that it begins on a WORD boundary with the first
+ *     two bytes being dummies
+ * - the transmit complete interrupt is not used
+******************************************************************************/
+
+/*
+ * The name of the card. Is used for messages and in the requests for
+ * io regions, irqs and dma channels
+ */
+// static const char* cardname = "s3c2500";
+
+/**********************************************
+Compile time directives
+***********************************************/
+#define NO_INCLUDE_MAC_RX_INT	1		// do not include (or set up) the
+										//  MAC receive interrupt
+										//  - Currently unused
+#define	ENABLE_DESTRUCTOR		0		// use destructor to set
+										//  - Needs work if enabled (previous
+										//    version)
+/************************************************************************
+	"Knobs" that adjust features and parameters.
+*******************************************************************/
+
+/* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
+/**** Currently unused ...MaTed--- ****/
+static const int mtu = 1500;
+
+/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
+#define RX_ALL_PKTS	1
+#if !RX_ALL_PKTS	/* We have to handle all the rx pkts, 
+					   latency problems ...MaTed */
+#define MAXINT_WORK_RX		RX_NUM_FD/ 16	// set to one eight of Rx buffers
+//#define MAXINT_WORK_RX		RX_NUM_FD/ 4	// set to one quarter of Rx buffers
+/*
+#define MAXINT_WORK_RX		RX_NUM_FD/ 2	// set to one half of Rx buffers
+*/
+//static int max_interrupt_work = MAXINT_WORK;
+#endif
+
+/******************************************************
+ * Internal S3C2500 data structures
+ * Should have made this into an array of 
+ *  two structures --- Maybe later ...MaTed---
+ ******************************************************/
+static	UINT32	numS3c2500Macs	= 0;	// number of macs
+#if 1	// force reversal of eth0 and eth1 assignements
+static	CSR * 	MacBases[ ETH_MAXUNITS] = {(CSR *) 0xf00c0000,
+										   (CSR *) 0xf00a0000};
+static	UINT32	PhyHwAddr[ ETH_MAXUNITS] = { MPHYHWADDR1, MPHYHWADDR0};
+static	UINT32	IRQNumTx[ETH_MAXUNITS] = { ETH1_TX_IRQ, ETH0_TX_IRQ};
+static	UINT32	IRQNumRx[ETH_MAXUNITS] = { ETH1_RX_IRQ, ETH0_RX_IRQ};
+static	char *	IntNames[2 * ETH_MAXUNITS ]
+            = {"eth1-s3cTX", "eth1-s3cRX", "eth0-s3cTX", "eth0-s3cRX"};
+static	char *	MacName[]
+	= {"S3c2500-1", "S3c2500-0", "unknown"};
+static	char *	MacHWAddr[]	= {"HWADDR1", "HWADDR0", "unknown"};
+#else
+static	CSR * 	MacBases[ ETH_MAXUNITS] = {(CSR *) 0xf00a0000,
+										   (CSR *) 0xf00c0000};
+static	UINT32	PhyHwAddr[ ETH_MAXUNITS] = { MPHYHWADDR0, MPHYHWADDR1};
+static	UINT32	IRQNumTx[ETH_MAXUNITS] = { ETH0_TX_IRQ, ETH1_TX_IRQ};
+static	UINT32	IRQNumRx[ETH_MAXUNITS] = { ETH0_RX_IRQ, ETH1_RX_IRQ};
+static	char *	IntNames[2 * ETH_MAXUNITS ]
+            = {"eth0-s3cTX", "eth0-s3cRX", "eth1-s3cTX", "eth1-s3cRX"};
+static	char *	MacName[]
+//	= {"ethaddr0", "ethaddr1", "ethaddr2", "unknown"};
+//	= {"S3c2500-0", "S3c2500-1", "S3c2500-2", "unknown"};
+	= {"S3c2500-0", "S3c2500-1", "unknown"};
+static	char *	MacHWAddr[]	= {"HWADDR0", "HWADDR1", "unknown"};
+#endif
+
+  /*
+   * Structures for S3c2500 frame descriptors
+   * - These four structure will be allocated on a boundary so 
+   *   so the structures can be accessed without cacheing
+   * - For now we don't align, - need special linker script and area
+   */
+typedef struct 
+{
+RxFD	___align16	rxFdArray [ETH_MAXUNITS] [ RX_NUM_FD];
+TxFD	___align16	txFdArray [ETH_MAXUNITS] [ TX_NUM_FD];
+#if CONFIG_WBUFFER
+TxBUFF	___align16	txFdBuffers [ETH_MAXUNITS] [ TX_NUM_FD];
+#endif // CONFIG_WBUFFER
+} FDAArea;
+
+FDAArea	* FDescUncached;	// pointer to area kmalloc'd
+
+#if MATED_RX_OF_BUG			// printk the previous buffer lengths
+#define RX_OF_MAX_LOG	10
+// It would be NICE to init this array, but it's only debug
+UINT32	rx_len_array[ ETH_MAXUNITS] [RX_OF_MAX_LOG];
+	// index into rx_len_array- where next will go in
+UINT32	rx_len_index[ETH_MAXUNITS] = {0,0};
+int position_output = 0;
+#endif
+
+/************************************************************************
+ * Internal Function Declarations - all static
+ ************************************************************************/
+
+static _INLINE_ UINT16 incIndex( UINT16 index, UINT16 max);
+static _INLINE_ int PHYWait( UINT32 chan );
+static int WritePhy( UINT32 chan, UINT32 reg, UINT32 data );
+static int ReadPhy( UINT32 chan, UINT32 reg, UINT32 * data );
+static _INLINE_ int txFull( ND dev );
+static void SetupPHY( UINT32 chan, UINT32 mode );
+static ULONG PHYCheckCable(  S3C2500_MAC * np);
+static int PhyInit( ND dev );
+static ULONG SetupTxFDs( ND dev );
+static ULONG SetupRxFDs( ND dev);
+static _INLINE_ void EnableInt( UINT32 chan );
+static _INLINE_ void DisableInt( UINT32 chan );
+static _INLINE_ void EnableTxRx( UINT32 chan );
+static _INLINE_ void DisableTxRx( UINT32 chan );
+static int Reset( UINT32 chan );
+static void SetupRegistersTx( ND dev );
+static void SetupRegistersRx( ND dev );
+//static _INLINE_ void SetUpTxFrmPtrRegister( ND dev);
+static _INLINE_ ULONG TxRxInit( ND dev);
+static int SetMacAddr( ND dev, void * addr);
+static int SetUpARC( ND dev, void * addr);
+#if ENABLE_IOCTL
+static _INLINE_ void SetSpeed100( UINT32 chan );
+static _INLINE_ void SetSpeed10( UINT32 chan );
+#endif	// ENABLE_IOCTL
+
+/* Index to functions, as function prototypes. */
+
+int __init	s3c2500_probe( ND dev);
+static int	s3c2500_InitVars( ND dev, UINT32 chan);
+static _INLINE_ int s3c2500_request_irq_mem( ND dev, UINT32 chan);
+
+static int	s3c2500_probe1( ND dev, UINT32 chan);
+static _INLINE_ int s3c2500LogTxMACError( ND dev, int status);
+static _INLINE_ int s3c2500LogRxBdmaError( ND dev, int status);
+static void	s3c2500_tx_timeout( ND dev);
+static _INLINE_ int 	s3c2500InitPriv( ND dev, UINT32 chan );
+
+static int	s3c2500_open( ND dev);
+static int	s3c2500_send_packet( struct sk_buff *skb, ND dev);
+/* two interrupt routines - with one helper */
+static void	s3c2500_Tx( int irq, void *dev_id, struct pt_regs * regs);
+//static _INLINE_ void TxPktCompletion( ND dev);
+static void TxPktCompletion( ND dev);
+static void	s3c2500_Rx( int irq, void *dev_id, struct pt_regs * regs);
+#if DEBUG_RX_DUMP
+static void dumpRx( UINT32 chan, S3C2500_MAC * priv, char * where);
+static void RXFDS_Dump( RxFDS * fds, char * str);
+#endif
+#if	ENABLE_DESTRUCTOR 
+/ We cause an error, because there are problems with this  ...MaTed---
+static void	s3c2500Destructor( struct sk_buff *skb);
+#endif
+static int	s3c2500_close( ND dev);
+static struct net_device_stats	*s3c2500_get_stats( ND dev);
+static void	set_multicast_list( ND dev);
+static void	HardwareSetFilter( ND dev);
+
+#if DEBUG_PHY_DUMP
+static void DumpPhyReg( UINT32 chan);
+#endif
+
+/************************************
+ * Temporary routines
+ ************************************/
+#define S3C2500_TEMP_ROUT1 1
+#if S3C2500_TEMP_ROUT1 
+// what do I need to include to get this one
+#define abs(x) (((int)x < 0)? -x : x)
+#endif
+
+#if 0	// All the setup is down elsewhere now
+// need the real versions when data cache get enabled
+/*****************************************************
+ * s3c2500_uncache_region( start, size )
+ * Description:
+ *		This routine force memory starting at "start" for a length
+ *	of "size" bytes to always be uncached memory
+ * NOTES:
+ *	- the start parameter must be on a memory boundary of "size", i.e.
+ *	if size is 1 MB, then start must be on a 1MB boundary.
+ *	- kmalloc is guarenteed to return allocated memory on the 
+ *	boundary 
+ * Parameters:
+ *		start	- pointer to the first location of the region to be
+ *				  made uncachable
+ *				- must start on boundary of "size"
+ *		size	- number of bytes for the region to be uncached
+ *				- this value MUST be a power of 2
+ * Returns:
+ *		S3C2500_SUCCESS == 0 	- successfull
+ *		-1						- Address invalid
+ *								- probably address is outside of ram
+ *		-2						- invalid size parameter
+ *		-3						- No free region
+ *								- Only 4 available
+ *****************************************************/
+int _INLINE_ s3c2500_uncache_region( void * start_addr, unsigned int size)
+{
+  // the third parm == 0 => data
+  return( ask_s3c2500_uncache_region( start_addr, size, 0) );
+}
+
+# if 0	// I don't believe we will be using these routines
+int s3c_invalidate_cache( void * start_address, unsigned int length)
+{
+  return (S3C2500_SUCCESS);
+}
+int s3c_flush_cache_region( void * start_addr, unsigned int size)
+{
+  asm("				\
+");
+       
+  return (S3C2500_SUCCESS);
+}
+# endif
+#endif
+/************************************************************************
+ * Utility routines / defines
+ ************************************************************************/
+// NOTE: assumes baseAddr will reflect channel number (A/B)
+#define WriteCSR( reg, value) \
+		((volatile UINT32)(((CSR *)( baseAddr))->reg) = (value))
+#define ReadCSR( reg) ((volatile UINT32)(((CSR *) (baseAddr))->reg))
+
+/***************************************************************************
+ *	Function Name:      txFull
+ *
+ *  Purpose:	Returns 0 if tx Queue in not full, !=0 if full
+ *
+ *  Inputs:     ND dev
+ ***************************************************************************/
+static _INLINE_ int 
+txFull( ND dev)
+{
+  S3C2500_MAC *	np = (S3C2500_MAC *) dev->priv;
+  return (np->ringTx.num) >= (np->ringTx.max);
+}
+/***************************************************************************
+ *	Function Name:      incIndex
+ *
+ *  Purpose:	Returns new index
+ *
+ *  Inputs:     index and max
+ ***************************************************************************/
+static _INLINE_ UINT16
+incIndex( UINT16 index, UINT16 max)
+{
+  return ( (++index > max) ? 0 : index); 
+}
+/*************************************************************************
+ * PHYWait - Waits for Station Management to become non-busy
+ *
+ * This inline routine is a helper to wait for Station Management to 
+ *	become non-busy - ie for the command to complete
+ *
+ * returns	S3C2500_SUCCESS if succesfully written
+ *       	other returns indicate timeout or other error
+ *************************************************************************/
+static _INLINE_ int 
+PHYWait( UINT32 chan)
+{
+  UINT32 i = 0;
+  CSR * baseAddr = MacBases[ chan ];
+
+  while (( ReadCSR( SmCtl)) & MPHYbusy)
+  {
+    if ( i++ >= PHY_BUSYLOOP_COUNT)
+    {
+      if ( VERBOSE > 2)
+      {
+		printk( "S3C2500-PHY: *** BUSY Timeout! ***\n");
+      }
+      return( S3C2500_TIMEOUT);
+    }
+	s3c_mdelay( PHY10MSDELAY);	// 10 millisecond delay per loop
+  }
+  return( S3C2500_SUCCESS);
+}
+/*************************************************************************
+ * WritePHY - writes data to phy
+ *
+ * This routine is a helper to write Phy data
+ *
+ * data is written to reg of the PHY at addr
+ * returns	S3c2500_SUCCESS if succesfully written
+ *       	other returns indicate timeout or other error
+ *************************************************************************/
+static int 
+WritePhy( UINT32 chan, UINT32 reg, UINT32 data)
+{
+  int 		rc;
+  CSR * 	baseAddr = MacBases[ chan ];
+  UINT32	addr = PhyHwAddr[ chan ];
+
+  if ( S3C2500_SUCCESS != ( rc= PHYWait( chan )))
+	return( rc);
+  WriteCSR( SmData, data);  	/* set data */
+  WriteCSR( SmCtl, MPHYwrite | MPHYbusy | reg | addr);	// send WRITE cmd
+#if PHY_DEBUG
+  printk( "S3C2500-PHY: wrote 0x%08x to PHY%d register 0x%x\n",
+		  (int) data, (int) addr, (int) reg);
+#endif
+  return( PHYWait( chan ));
+}
+/*************************************************************************
+ * ReadPHY - reads data from phy
+ *
+ * This routine is a helper to read Phy data
+ *
+ * data is read from reg of the PHY at addr
+ * returns	S3C2500_SUCCESS if succesfully read
+ *       	other returns indicate timeout or other error
+ *************************************************************************/
+static int 
+ReadPhy( UINT32 chan, UINT32 reg, UINT32 * data)
+{
+  int 		rc;
+  CSR * 	baseAddr = MacBases[ chan ];
+  UINT32	addr = PhyHwAddr[ chan ];
+
+  	// wait for any previous command to complete
+  if ( S3C2500_SUCCESS != ( rc= PHYWait( chan )))
+	return( rc);
+  WriteCSR( SmCtl, MPHYbusy | reg | addr );	// send READ cmd
+  // wait for read command to complete
+  if ( S3C2500_SUCCESS != ( rc= PHYWait( chan )))
+	return( rc);
+  *data = ReadCSR( SmData);  	/* get data */
+#if PHY_DEBUG
+    printk( "S3C2500-PHY: read 0x%08x from PHY%d register 0x%x\n",
+			(int) *data, (int) addr, (int) reg);
+#endif
+  return (rc);					/* return success */
+}
+/*************************************************************************
+ * SetupPHY - initialize and configure the PHY device.
+ *
+ * This routine initializes and configures the PHY device 
+ *	***** NOTE: the LED values used for initialization are overwritten
+ *
+ * Loopback=disabled
+ * Speed = 100/10
+ * Auto-Negotiation Restart = mode enabled --- FIXME NOTE: Assumption that
+ *									   -- FIXME		Negotiation had not
+ *										- FIXME		previously run ???
+ * Power Down = 0 normal
+ * Isolate = 0 normal
+ * Restart Auto-Negotiation = 0
+ * Duplex = 1 Full / 0 Half
+ * Collision Test = 0 Disabled
+ *
+ **** parm mode values *****
+ * For Full Dup 10Mbps:  0x0100
+ * For Half Dup 10Mbps:  0x0000
+ * For Full Dup 100Mbps: 0x2100
+ * For Half Dup 100Mbps: 0x2000
+ * For Auto Negotiate:   0x1000		- half duplex 10 advertised
+ * For Auto Negotiate:   0x1100		- full/half duplex 10 advertised
+ * For Auto Negotiate:   0x3000		- half duplex 10/100 advertised
+ * For Auto Negotiate:   0x3100		- full/half duplex 10/100 advertised
+ * For Restart AutoNeg:  0x0200		- current values retained
+ *
+ *************************************************************************/
+static void 
+SetupPHY( UINT32 chan, UINT32 mode) 
+{
+  UINT32	j;		// loop counter - what else would I be
+  UINT32	data;	// save the data read back from the control register
+
+  /* First reset the PHY */
+  WritePhy( chan, PHYCtl, PHYCtlReset);
+  /*
+   * Read the Reset bit(0.15) of the PHY to see if the reset is completed.
+   */
+  for ( j = 0; j < PHY_RESETLOOP_COUNT; j++)
+  {
+    if (S3C2500_SUCCESS != ReadPhy( chan, PHYCtl, &data))
+	{
+	  if (VERBOSE > 2)
+		{
+		  printk( "S3C2500-PHY: RESET command not accepted! ***\n");
+		}
+	  return;
+	}
+    if ( (data & PHY_RESET) == 0)
+    {
+      if ( VERBOSE > 2 )
+      {
+		printk( "S3C2500-PHY reset\n");
+      }
+      break;
+    }
+	s3c_mdelay( PHY10MSDELAY);	// 10 mS - Hopefully someone will do something
+	                //  to mdelay so it might actually do something
+	                //  these time slices allocated to it. Right now
+                    //  it's a hard loop
+  }
+#ifdef PHY_INTEL
+  s3c_mdelay( PHY10MSDELAY);	// just in case
+  // change the LED to right link/activity LEFT->speed
+  WritePhy( chan, PHYLedCfg, PHYLEDCFG);
+#endif
+
+#if PHY_DEBUG
+  printk( "S3C2500-PHY: setting up mode-%08x\n", (int) mode);
+#endif
+  if (S3C2500_SUCCESS != ReadPhy( chan, PHYCtl, &data))
+  {
+	if (VERBOSE > 2)
+	  {
+		printk( "S3C2500-PHY: Read mode command not accepted! ***\n");
+	  }
+	return;
+  }
+#if PHY_DEBUG
+  printk( "S3C2500-PHY: Original mode-%08x\n", (int) data);
+#endif
+  /*
+   * Rules for mode
+   *  if b12 is set	- autonegotiation is enabled -> for the other bits set
+   *				- advertizing will match 
+   *  if b12 is reset - no autonegotian, adverting is not changed
+   *  b13 set to 100 MbS (includes 10 if autoneg) 
+   *  b13 reset -> 10 Mbs only 
+   *  b8 set FULL DUPLEX (autonegiate -> HALF Duplex included)
+   *  b8 reset Half Duplex
+   */
+  if (0 == (mode & PHY_CONTROL_AUTONEG))
+  {	// No autonegotiate - just write mode and done
+	if (S3C2500_SUCCESS != WritePhy( chan, PHYCtl, mode))
+	{
+	if (VERBOSE > 2)
+	  {
+		printk( "S3C2500-PHY: Mode change failed for Control\n");
+	  }
+	}
+	return;		// no autonegotiation - no advertising
+  }
+
+#if 1	// allow mode control
+  // Advertise to the world what we will negotiate
+  if (S3C2500_SUCCESS != ReadPhy( chan, PHYANegAd, &data))
+  {
+	if (VERBOSE > 2)
+	  {
+		printk( "S3C2500-PHY: Read Negotiate Advertize not accepted! ***\n");
+	  }
+	return;
+  }
+  data &= ~PHYANegAdMask;
+  switch (mode & (PHY_CONTROL_SELECT_SPEED | PHY_CONTROL_DUPLEXMODE))
+  {
+  case PHY_CONTROL_SELECT_SPEED | PHY_CONTROL_DUPLEXMODE:
+	data |= PHYB8 | PHYB7 | PHYB6 | PHYB5;
+	break;
+  case PHY_CONTROL_SELECT_SPEED:
+	data |= PHYB7 | PHYB5;
+	break;
+  case PHY_CONTROL_DUPLEXMODE:
+	data |= PHYB6 | PHYB5;
+	break;
+  case 0:
+	data |= PHYB5;
+	break;
+  }
+#else
+  // put in everything
+  data = PHYLEDANEG;
+#endif  // end of allow mode control
+  if (S3C2500_SUCCESS != WritePhy( chan, PHYANegAd, data))
+  {
+	if (VERBOSE > 2)
+	  {
+		printk( "S3C2500-PHY: Mode change failed for Advertise\n");
+	  }
+	return;
+  }
+  /* since we are auto negotiating, force a restart */
+  mode |= PHY_CONTROL_RESTART_AUTONEG;	// just in case
+  if (S3C2500_SUCCESS != WritePhy( chan, PHYCtl, mode))
+  {
+	if (VERBOSE > 2)
+	  {
+		printk( "S3C2500-PHY: Autonegotiate failed to restart\n");
+	  }
+	return;
+  }
+  // check for the end of the negotiation start
+  j = 0;
+  ReadPhy( chan, PHYCtl, &data);
+  while ( data & PHY_CONTROL_RESTART_AUTONEG)
+  {
+    if ( j++ >= PHY_NEGLOOP_COUNT)
+    {
+	  if ( VERBOSE > 1)
+      {
+		printk( "S3C2500-PHY: * Restart AutoNegotiate did not complete ");
+		printk( " Will check again later ***\n");
+      }
+      return;
+    }
+	s3c_mdelay( PHY10MSDELAY);	// 10 millisecond delay per loop
+	ReadPhy( chan, PHYCtl, &data);
+  }
+#ifdef PHY_INTEL
+  s3c_mdelay( PHY10MSDELAY);	// just in case
+  // change the LED to right link/activity LEFT->speed
+  WritePhy( chan, PHYLedCfg, PHYLEDCFG);
+#endif
+  return;
+}
+/*************************************************************************
+  * PHYCheckCable - Check for Cable connection to the PHY 972.
+  *
+  *
+  * RETURNS: S3C2500_SUCCESS, or S3C2500_FAIL
+  * ** * NOTE: routine now sets ph
+  * Needs to be modified according to the PHY, and 
+  * needs to be modified according to the SPEC of Level1 972
+  *
+  **************************************************************************/
+static UINT32 
+PHYCheckCable( S3C2500_MAC * np)
+{
+  UINT32	data, data2;
+  UINT32	chan = np->channel;
+
+  if (S3C2500_SUCCESS != ReadPhy( chan, PHYStat2, &data2))
+  {
+	if ( VERBOSE > 2)
+	  {
+		printk( "S3C2500-CheckCable: Read status 2 command not accepted! ***\n");
+	  }
+	return (S3C2500_FAIL);
+  }
+#ifdef PHY_LSI
+  if (S3C2500_SUCCESS != ReadPhy( chan, PHYStat, &data))
+  {
+	if ( VERBOSE > 2)
+	  {
+		printk( "S3C2500-CheckCable: Read status command not accepted! ***\n");
+	  }
+	return (S3C2500_FAIL);
+  }
+#else
+#ifdef PHY_INTEL
+  data = data2;				// I know this is klugy ...MaTed---
+#endif
+#endif  // else PHY_LSI
+#if PHY_DEBUG
+  printk("S3C2500-CheckCable: Status = 0x%x - Status 2 = 0x%x\n", 
+		 (int) data, (int) data2);
+#endif
+  if (!(data & PHY_STATUS_LINK_UP))
+    return( S3C2500_FAIL);
+  else if ( VERBOSE )
+	{
+	  if (data2 & PHY_STATUS_LINK_100)
+	  {
+		printk( "S3C2500-PHY: running at 100 Mbps, ");
+		np->phySpeedNeg = 2;		// 0 and 3 are autoneg indicators
+	  }
+	  else
+	  {
+		printk( "S3C2500-PHY: set for 10 Mbps,  ");
+		np->phySpeedNeg = 1;		// 0 and 3 are autoneg indicators
+	  }
+	  
+	  if(data2 & PHY_STATUS_LINK_DUPLEX)
+	  {
+		printk( "FULL Duplex Mode.\n");
+		np->phyDpxNeg = 1;
+	  }
+	  else
+	  {
+		printk( "HALF Duplex Mode. \n");
+		np->phyDpxNeg = 0;
+	  }
+	}
+  return S3C2500_SUCCESS;
+}
+/*************************************************************************
+ * PhyInit - initialize and configure the PHY device.
+ *
+ * This routine initialize and configure the PHY device 
+ *
+ * RETURNS: S3C2500_SUCCESS, or S3C2500_FAIL
+ * Needs to be modified according to the PHY, and 
+ * needs to be modified according to the SPEC of Level1 972.
+ **************************************************************************/
+static int 
+PhyInit( ND dev)
+{
+  S3C2500_MAC *	np = (S3C2500_MAC *) dev->priv;
+  UINT32	chan = np->channel;
+  CSR *		baseAddr = (CSR *) (dev->base_addr);
+  UINT32	status = S3C2500_SUCCESS;
+  UINT32	i;
+#if !(defined( PHY_0_FORCE ) && defined( PHY_1_FORCE ))
+  static const UINT32 modeList[] = 
+  {
+	PHY_CONTROL_AUTONEG_HALF_10,	PHY_CONTROL_SPEED_10_HALF,
+	PHY_CONTROL_SPEED_100_HALF,		PHY_CONTROL_AUTONEG_HALF_100,
+	PHY_CONTROL_AUTONEG_FULL_10, 	PHY_CONTROL_SPEED_10_FULL,
+	PHY_CONTROL_SPEED_100_FULL,		PHY_CONTROL_AUTONEG_FULL_100
+  };	
+#endif
+
+  /* Kendin switch has not PHY - setup and return */
+#if defined(CONFIG_BOARD_EVS3C2500RGP) || defined(CONFIG_BOARD_S3C2500REFRGP)
+  if (chan == 0)
+	{
+		printk( "S3C2500-PHY: running at 100 Mbps, ");
+		np->phySpeedNeg = 2;		// 0 and 3 are autoneg indicators
+		printk( "FULL Duplex Mode.\n");
+		np->phyDpxNeg = 1;
+		return ( S3C2500_SUCCESS);
+	}	  
+#endif   // CONFIG_BOARD_EVS3C2500RGP or CONFIG_BOARD_S3C2500REFRGP
+
+#if DEBUG_PHY_DUMP
+  DumpPhyReg( chan );
+#endif	//DEBUG_PHY_DUMP
+
+  // Setup duplex and speed to pass on
+  //   automatic get 0
+  // setup Station Management data -- NOTE: Incomplete Data
+#if defined( PHY_0_FORCE ) && defined( PHY_1_FORCE )
+  SetupPHY( chan, (chan) ? PHY_1_FORCE : PHY_0_FORCE);
+#else
+  #if defined( PHY_0_FORCE )
+    SetupPHY( chan, (chan) 
+			  ? modeList[ np->phySpeed + (np->phyDpx << 2)]
+			  : PHY_0_FORCE);
+  #endif
+  #if defined( PHY_1_FORCE )
+	SetupPHY( chan, (chan) 
+			  ? PHY_1_FORCE
+			  : modeList[ np->phySpeed + (np->phyDpx << 2)]);
+  #endif
+  #if !(defined( PHY_0_FORCE ) || defined( PHY_1_FORCE ))
+	SetupPHY( chan, modeList[ np->phySpeed + (np->phyDpx << 2)]);
+  #endif
+#endif
+
+  for ( i = 0; i < PHY_BUSYLOOP_COUNT; i++) 
+  {
+	if ( S3C2500_SUCCESS == (status = PHYCheckCable( np )))
+	{
+	  if ( VERBOSE )
+      {
+		printk( "S3C2500-PHY: Cable detected\n");
+	  }
+	  break;
+	}
+	s3c_mdelay( PHY10MSDELAY);	// 10 mS
+  }
+  if ( status != S3C2500_SUCCESS)
+  {
+    printk( "S3C2500: **** We believe NO Cable is connected to MAC %s %08lx\n", 
+			dev->name, (UINT32) baseAddr);
+  }
+#if DEBUG_PHY_DUMP
+  DumpPhyReg( chan );
+#endif	//DEBUG_PHY_DUMP
+
+#if 0		// no failure if no cable
+  return ( status);
+#else
+  return ( S3C2500_SUCCESS);
+#endif
+} 
+/*********************************************************************
+ *	Function Name:  SetupTxFDs
+ *
+ * Purpose: For transmit frame and buffer descriptors
+ *          - set up initial values for these.
+ *	    	- setup queue pointers
+ *			- FDS setup as a ring 
+ *
+ *	** Assumes called just after dev set up, and priv defined
+ *
+ * Inputs:  Pointer to dev structure
+ *
+ * Return Value:
+ *	S3C2500_SUCCESS
+ *	S3C2500_FAIL
+ *********************************************************************/
+static ULONG 
+SetupTxFDs( ND dev )
+{
+  int 			i;
+  S3C2500_MAC *	np = dev->priv;			// pointer to private are
+  RINGBUFF 	  *	ringTx = & np->ringTx;	// pointer to tx ring buffer
+  int 			baseAddr = dev->base_addr;
+
+  if (0 == np)		// we could drop this test
+  {
+    return ( S3C2500_FAIL);
+  }
+  /* Setup the ring indices */
+  ringTx->first
+    = ringTx->last = ringTx->num = 0;	// no buffers in use
+  ringTx->max = TX_NUM_FD - 1;
+
+  /* for all the tx frames */
+  for(i = 0; i < TX_NUM_FD; i++) 
+  {  
+#if CONFIG_WBUFFER
+	// this needs checking - WBUFFER never in use yet ...MaTed---
+	np->txFd[ i ].FDDataPtr = np->txBuff[ i ].FDData;
+#else	// FDDataPtr gets setup in send_packet, if no write caching
+	// if you need to debug, might want to set the corresponding SKB
+	// in txBuff (txSkb) to NULL - it's not a required thing
+
+#endif // CONFIG_WBUFFER
+//	np->txFd[ i ].FDLength = 0x0000;		// don't need this either
+	np->txFd[ i ].FDStat = TxWidSet16;		// ownership and preset offset
+  }	
+  if ( VERBOSE > 1)
+  {
+    printk( KERN_INFO "SetupTxFDs-for %s, First buff %x, Last %x\n",
+	    dev->name, (int) &np->txFd[ 0 ],
+	    (int) &np->txFd[ TX_NUM_FD - 1]);
+  }
+  /*
+   * Now tell the MAC about the buffers
+   */
+  WriteCSR( TxPtr, np->txFd);
+  WriteCSR( TxCnt, 0);		// none ready to go
+  return ( S3C2500_SUCCESS);
+}
+/***********************************************************************
+ * Function Name:	SetupRxFDs                              
+ *                                                                          
+ * Purpose: Prepare memory for receive buffers and frame descriptors
+ *
+ *	** Assumes called just after dev set up, and priv defined
+ *
+ * Inputs:  Pointer to dev structure
+ *
+ * Return Value:
+ *	S3C2500_SUCCESS
+ *	S3C2500_FAIL
+ ***********************************************************************/
+static ULONG SetupRxFDs( ND dev)
+{
+  int 				i;
+  S3C2500_MAC * np = (S3C2500_MAC *) dev->priv;	// pointer to the private 
+                                                //  s3c2500 area
+  RINGBUFF 			* ringRx = & np->ringRx;	// pointer to rx ring buffer
+  int 				baseAddr = dev->base_addr;
+
+  if ( 0 == np)
+  {
+    return ( S3C2500_FAIL);
+  }
+  /* Setup the ring indices */
+  ringRx->first
+	= 0;	// no buffers in use
+  // ** NOTE last is set one behind first
+  ringRx->max = ringRx->last = RX_NUM_FD - 1;
+
+  /*
+   * Initialize the FD Area. Give the ownership of each 16
+   * byte block to the controller - ready to RX. (The patterns of
+   * 0xBBB etc is for debugging only!)
+   ** NOTE We do the last one - even though 
+   ** NOTE: We don't do the last one, spacer for EOL
+   */
+  for ( i = 0; i < RX_NUM_FD; i++)
+  {
+	/*
+	 * Each FD points to a large enough buffer so that for each
+	 * incoming packet will fit in one buffer.
+	 *
+	 */
+	np->rxSkb[ i ].FDskb 
+	  = __dev_alloc_skb( MAX_PKT_SIZE, GFP_ATOMIC | GFP_DMA);
+	np->rxFd[ i ].FDDataPtr = np->rxSkb[ i ].FDskb->data;	/* point to skb 
+															   data buffer */
+	np->rxFd[ i ].FDLength = PKT_BUF_SZ;	// think the compiler is smart
+	np->rxFd[ i ].FDStat = OWNERSHIP16;		//  enough to put these two lines 
+	                                        //  together??
+	skb_reserve( np->rxSkb[ i ].FDskb, 2);         // alignment 
+
+    if (NET_DEBUG > 1) // mated_debugging
+	{
+	  ASSERT( np->rxSkb[ i ].FDskb->list == 0);
+	}
+  }
+  // we aren't going to stop the BDMA engine from getting to the 
+  //	last one, It stops itself
+  // Need to put in the EOL (last one owned by CPU)
+  // NOTE: ALL entries including the last one have an uncached SKB assigned
+  //		We just mark it as unused
+  np->rxFd[ RX_NUM_FD - 1 ].FDStat = 0;
+  np->rxFd[ RX_NUM_FD - 1 ].FDLength = 0;
+
+  //  np->rxFd[ RX_NUM_FD - 1 ].FDDataPtr = NULL;	// point to Nothing
+
+  if ( VERBOSE > 1)
+  {
+    printk( "SetupRxFDs-for %s\n", dev->name);
+  }
+  /*
+   * Now tell the MAC about the buffers
+   */
+  WriteCSR( RxPtr, np->rxFd);
+  WriteCSR( RxCnt, RX_NUM_FD - 1);	/* one less than number of buffers
+									   IE, the last one in the list */
+  return ( S3C2500_SUCCESS);
+}
+/**********************************************************************
+ * Function Name:	EnableInt
+ *
+ *   Purpose:       Enables the Interrupt for the Dev
+ *					- Interrupt enables are in 5 different registers
+ *   
+ *   Parameters:    Device
+ ***********************************************************************/
+static _INLINE_ void 
+//static void 
+EnableInt( UINT32 chan)
+{
+  CSR * baseAddr = MacBases[ chan ];
+
+  // Street proofing
+  if (NET_DEBUG > 4)
+	{
+	  if (chan != 0 && chan != 1)
+		printk ("SC32500: EnableInt - BAD CHANNEL [%d] specified !! \n",
+				(UINT16) chan );
+	}
+  // temp disable (is this needed??)
+	// disable all temporarily
+  WriteCSR( TxIntEn, ReadCSR( TxIntEn ) & ~ TxINTMask );
+  WriteCSR( RxIntEn, ReadCSR( RxIntEn ) & ~ RxINTMask );
+
+  /* Enable Interrupts */
+  /* first logic level */
+  enable_irq( IRQNumRx[ chan ]);
+  enable_irq( IRQNumTx[ chan ]);
+  /* then from the hardware */
+  s3c2500_unmask_irq( IRQNumRx[ chan ]);;
+  s3c2500_unmask_irq( IRQNumTx[ chan ]);
+
+  /* Enable MAC and BDMA interrupts - ones we want to use */
+  WriteCSR( TxIntEn, ReadCSR( TxIntEn ) | TxINTMask );
+  WriteCSR( RxIntEn, ReadCSR( RxIntEn ) | RxINTMask );
+}
+/**********************************************************************
+ * Function Name:	DisableInt
+ *
+ *   Purpose:   Disables the Interrupt for the specified Dev
+ *   
+ *   Parameters:    Device
+ ***********************************************************************/
+static _INLINE_ void 
+DisableInt( UINT32 chan )
+{
+  CSR * baseAddr = MacBases[ chan ];
+
+  // Street proofing
+  if ( NET_DEBUG > 4 )
+	{
+	  if (chan != 0 && chan != 1)
+		printk ("SC32500: DisableInt - BAD CHANNEL specified !! \n");
+	}
+	// disable all
+  WriteCSR( TxIntEn, ReadCSR( TxIntEn ) & ~ TxINTMask );
+  WriteCSR( RxIntEn, ReadCSR( RxIntEn ) & ~ RxINTMask );
+
+  /* Disable Interrupts */
+  /* first logic level */
+  disable_irq( IRQNumRx[ chan ]);
+  disable_irq( IRQNumTx[ chan ]);
+  /* then from the hardware */
+  s3c2500_mask_irq( IRQNumRx[ chan ]);;
+  s3c2500_mask_irq( IRQNumTx[ chan ]);
+
+}
+/**********************************************************************
+ * Function Name:	EnableTxRx
+ *
+ *   Purpose:   Starts transmission and reception.
+ *   
+ *   Parameters:    Ethernet channel
+ ***********************************************************************/
+static _INLINE_ void 
+EnableTxRx( UINT32 chan )
+{
+  CSR * baseAddr = MacBases[ chan ];
+  // Tx Enable AND not Tx Halt
+  /* Enable Transmission */
+  WriteCSR( TxCtl, (( ReadCSR( TxCtl)) | BTxEN));
+
+  WriteCSR( MacTxCtl, (( ReadCSR( MacTxCtl)) | MTxEn) & ~MTxHalt);
+
+  /* Enable Reception    */
+  WriteCSR( RxCtl, (( ReadCSR( RxCtl)) | BRxEN));
+  // rx Enable AND not Rx Halt
+  WriteCSR( MacRxCtl, (( ReadCSR( MacRxCtl)) | MRxEn) & ~MRxHalt);
+
+  /* Turn off the Rx/Tx halts */
+  WriteCSR( MacCtl, (( ReadCSR( MacCtl)) & ~(MHaltReq | MHaltImm)));
+}
+/**********************************************************************
+ * Function Name:	DisableTxRx
+ *
+ *   Purpose:   Stops transmission and reception.
+ *   
+ *   Parameters:    Ethernet channel
+ ***********************************************************************/
+static _INLINE_ void 
+DisableTxRx( UINT32 chan)
+{
+  CSR * baseAddr = MacBases[ chan ];
+
+  /* Turn on both the Rx/Tx halts - immediate and request */
+  WriteCSR( MacCtl, (( ReadCSR( MacCtl)) | MHaltReq | MHaltImm));
+
+  /* Disable Transmission - disable and request halts (redundant??) */
+  WriteCSR( TxCtl, (( ReadCSR( TxCtl)) & ~BTxEN));
+  WriteCSR( MacTxCtl, (( ReadCSR( MacTxCtl)) | MTxHalt) & ~MTxEn);
+
+  /* Disable Reception - disable and request halts (redundant??) */
+  WriteCSR( RxCtl, (( ReadCSR( RxCtl)) & ~BRxEN));
+  // rx Enable AND not Rx Halt
+  WriteCSR( MacRxCtl, (( ReadCSR( MacRxCtl)) | MRxHalt) & ~MRxEn);
+}
+/*************************************************************************
+ * Function Name:	Reset
+ *
+ * Purpose:	To reset the MAC.
+ *
+ * Return Value:    S3C2500_FAIL on failure
+ *                  S3C2500_SUCCESS on success
+ **************************************************************************/
+static int
+Reset( UINT32 chan)
+{
+  UINT32 	i = 0;
+  CSR * 	baseAddr = MacBases[ chan ];
+
+  // Stop all tx / rx
+  //WriteCSR( MacCtl, (( ReadCSR( MacCtl)) | MCtlHaltImm));
+  DisableTxRx( chan);
+  s3c_mdelay( PHY10MSDELAY);	// 10 mS
+  // reset the BDMA TX block
+  WriteCSR( TxCtl, BTxRS);
+  s3c_mdelay( PHY10MSDELAY);	// 10 mS
+  // reset the BDMA RX block
+  WriteCSR( RxCtl, BRxRS);
+  s3c_mdelay( PHY10MSDELAY);	// 10 mS
+
+  // Software reset of all MAC control and status register 
+  //   and MAC state machine
+  WriteCSR( MacCtl, MReset);
+  // bit is cleared when done...wait
+  while (MReset & ReadCSR( MacCtl))
+  {
+	if (i++ >  MCtlReset_BUSY_LOOP)
+	  break;
+	s3c_mdelay( PHY10MSDELAY);	// 10 mS
+  }
+  if ( NET_DEBUG > 1 )
+	{
+	  if (i >= MCtlReset_BUSY_LOOP)
+		printk( "SC3: MAC did not come out of RESET :-( \n");
+	}
+  // setup the BDMA rx Word Alignment (must be done directly after reset)
+  WriteCSR( RxCtl, BRxSetup_RESET);
+
+  return ( S3C2500_SUCCESS);
+}
+/*************************************************************************
+ * Function Name:	SetupRegistersTX
+ *
+ * Purpose:	To setup the transmit register values
+ *		NOTE: We assume that only the BRxCtl register has any which needs
+ *			  to be preserved.
+ **************************************************************************/
+//static _INLINE_ void 
+static void 
+SetupRegistersTx( ND dev )
+{
+  //  S3C2500_MAC * priv = dev->priv;
+  CSR * 	baseAddr = (CSR *) dev->base_addr;
+
+  WriteCSR( TxCnt, TX_NUM_FD);		// The number of Tx FDs in the above arrary
+  WriteCSR( TxCtl, BTxSetup);		// Buffered DMA transmit control reg
+
+  WriteCSR( MacTxCtl, MTxCtlSetup);	// Transmit Control
+  return;
+}
+/*************************************************************************
+ * Function Name:	SetupRegistersRX
+ *
+ * Purpose:	To setup the receive register values
+ * 			NOTE: if a register has both RX and TX it's in here
+ **************************************************************************/
+//static _INLINE_ void 
+static void 
+SetupRegistersRx( ND dev )
+{
+  //  S3C2500_MAC * np = dev->priv;
+  CSR * 	baseAddr = (CSR *) dev->base_addr;
+  UINT32	i;
+
+  // BDMA rx setup
+  WriteCSR( RxCtl,BRxSetup_RESET);	// Buffered DMA receive control reg
+
+  // Number of buffer descriptors
+  WriteCSR( RxCnt, RX_NUM_FD);		// Number of buffer descriptors
+  // setup maximum Rx frame buffer sizes ...FIXME ...MaTed--- CHECK this
+  WriteCSR( RxSz, MAX_PKT_SIZE | ((PKT_BUF_SZ) << 16));	// Receive Frame 
+                                    // maximum size
+  for (i = 0; i < 32; i++)
+  {
+	WriteCSR( Cam[i], 0xffffffff);	// CAM Content, set for broadcast
+  }
+  WriteCSR( CamCtl, CAMCtlSETUP);	// CAM Control - Accept anything
+#if DEBUG_CRC_OFF
+  WriteCSR( MacRxCtl, MRxEn | MIgnoreCRC);	// Rx Control - NO CRC Check
+#else
+  WriteCSR( MacRxCtl, MRxCtlSETUP);	// Rx Control
+#endif
+  WriteCSR( MacCtl, MCtlSETUP);		// Full Duplex 100 (might change later)
+
+  WriteCSR( CamEn, 0x04);			// CAM Enable, third entry
+
+  return;
+}
+/*************************************************************************
+ *	Function Name:		TxRxInit
+ *
+ *   Purpose:	Set up the Ethernet to receive and transmit data.
+ *
+ *			NOTE: Check the order that things happen
+ *				It needs to be checked (too many routines) FIXME ...MaTed---
+ *
+ *   Return Value:  S3C2500_FAIL on failure
+ *                  S3C2500_SUCCESS on success
+ *					- Always Succeeds
+ **************************************************************************/
+static _INLINE_ ULONG 
+TxRxInit( ND dev)
+{
+  S3C2500_MAC * np = dev->priv;
+  CSR * 	baseAddr = (CSR *) dev->base_addr;
+  UINT32	chan = np->channel;
+
+  SetupRegistersTx( dev );
+  SetupRegistersRx( dev );
+  DisableTxRx( chan );
+  DisableInt( chan );
+  // ...MaTed--- changed to always bring up the interface
+  PhyInit( dev);
+  /* Make sure the MAC knows the speed and duplex that has been set up */
+  /* ** NOTE: we can remove all the other places we have set up duplex 
+	 and speed */
+  if (np->phyDpxNeg == 0)	// set to negotiated speed, not default
+  {	// forcing HALF duplex, default is FULL
+	WriteCSR( MacCtl, MCtlSETUP & ~MFullDup);
+  }
+  return (S3C2500_SUCCESS);
+}
+
+
+static int
+SetMacAddr( ND dev, void * addrin)
+{
+  struct sockaddr *addr = addrin;
+
+  if (netif_running(dev))
+    return -EBUSY;
+
+  memcpy( dev->dev_addr, addr->sa_data, dev->addr_len);
+
+  return SetUpARC(dev, addrin);
+}
+/*************************************************************************
+ * Function Name:		SetUpARC
+ *
+ * Purpose:	Setup the ARC memory MAC HW address...
+ *			- NOTE Only sets up one entry - 3rd entry
+ *					- 0 and 1 and 18 are reserved for MAC Control packets
+ *
+ * Parameters:	basePort    - base address of the MAC register set
+ *				addr
+ *			    - pointer to array of 6 bytes for the MAC HW 
+ *				address
+ **************************************************************************/
+static int
+SetUpARC( ND dev, void * addrin)
+{
+  //  S3C2500_MAC * np = dev->priv;
+  CSR * 	baseAddr = (CSR *) dev->base_addr;
+  UINT32	save;
+  UCHAR	   * addr = (UCHAR *) addrin;
+
+  /* NOTE: This routine assumes little endian setup of UINT32 */
+
+  /* don't update while active */
+  save = ReadCSR( CamEn);		// we leave other bits alone (later)
+  WriteCSR( CamEn, 0x00000000);	// don't use any ARC entries
+  /* Enter Address at third entry - hard code */
+  WriteCSR( Cam[3], addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24 );
+  WriteCSR( Cam[4], (ReadCSR( Cam[4]) & 0xffff0000) | addr[4] | addr[5] << 8);
+
+  /* Enable Third Address - b2 */
+  save |= 0x8;
+  WriteCSR( CamEn, save);
+  /* Enable ARC Compare +BCAST */
+  //  WriteCSR( basePort, ARCCtl, (ARC_CompEn | ARC_BroadAcc | ARC_StationAcc));
+  // Make it accept anything within dest
+  WriteCSR( CamCtl, MCompEn | MBroad | MGroup | MStation);
+  return ( 0);
+}
+#ifdef ENABLE_IOCTL	
+....NOTE this section not coded  ...MaTed---
+// Still unsure how IOCTLs coordinate with other calls
+/*************************************************************************
+ * Function Name:	SetSpeed100
+ *
+ * Purpose:	To Set the MAC in 100 mode.
+ *	NOTE: The actual speed is determined by the PHY
+ *	that is connected to this MAC.
+ *	NOTE: this routine is not used - for later implemtation of IOCTL
+ *        ** routine needs check and FIXME ** ...MaTed---
+ *		  ** needs to talk to the PHY
+ **************************************************************************/
+static _INLINE_ void 
+SetSpeed100( void)
+{
+  WriteCSR( MacCtl, (( ReadCSR(MacCtl)) & ~MLOOP10) );
+
+  // Need to reprogram the PHY as well
+  /* Should we wait for the MLLINK10 bit to be low ??? */
+}
+/*************************************************************************
+ * Function Name:	SetSpeed10
+ *
+ * Purpose:	To Set the MAC in 10 MBPS mode.
+ *	NOTE: The speed of the PHY should match this speed.
+ *	NOTE: this routine is not used - for later implemtation of IOCTL
+ *        ** routine needs check and FIXME ** ...MaTed---
+ *		  ** needs to talk to the PHY
+ **************************************************************************/
+static _INLINE_ void 
+SetSpeed10( void)
+{
+  WriteCSR( MacCtl, (( ReadCSR( MacCtl)) | MLOOP10 ));
+
+  // Need to reprogram the PHY as well
+	/* Should we wait for the MLINK10 bit to be high ???  */
+}
+#endif	// ENABLE_IOCTL
+/************************************************************************
+ * The following routines do the work
+ ************************************************************************/
+/************************************************************************
+ * Check for a network adaptor of this type, and return '0' iff one exists.
+ *  - we just allocate them the number of times I'm called
+ *  NOTE: we ignore the following values for base_addr ...MaTed
+ * If dev->base_addr == 0, probe all likely locations.
+ * If dev->base_addr == 1, always return failure.
+ * If dev->base_addr == 2, allocate space for the device and return success
+ * (detachable devices only).
+ ************************************************************************/
+int __init 
+s3c2500_probe( ND dev)
+{
+  // check if all allocated
+  if (numS3c2500Macs >= ETH_MAXUNITS)
+	return (-ENODEV);
+  // SET_MODULE_OWNER( dev);
+  dev->irq = IRQNumTx[ numS3c2500Macs ];	// just put in tx (rx is plus 1)
+  dev->base_addr = (int) MacBases[ numS3c2500Macs ];// just put start base addr
+  //  ((S3C2500_MAC *) dev->priv)->channel = numS3c2500Macs;
+  if ( check_mem_region( dev->base_addr, MAC_IO_EXTENT))
+    return (-ENODEV);
+  if ( s3c2500_probe1( dev, numS3c2500Macs) == S3C2500_SUCCESS)
+  {
+	numS3c2500Macs++;		   		// increment the number of s3c2500s found
+    return (S3C2500_SUCCESS);
+  }
+  return (-ENODEV);
+}
+/************************************************************************
+ * This routine initializes all the vars in dev and private areas
+ ************************************************************************/
+static int
+s3c2500_InitVars( ND dev, UINT32 chan)
+{
+  /* Initialize the device structure. */
+  if ( dev->priv == NULL)
+  {
+    dev->priv = kmalloc( sizeof( S3C2500_MAC), GFP_KERNEL);
+    if ( dev->priv == NULL)
+	{
+      return ( -ENOMEM);
+	}
+	s3c2500InitPriv( dev, chan);	// initialize the Mac Private structure
+    spin_lock_init( &((S3C2500_MAC *) dev->priv)->txLock);
+    spin_lock_init( &((S3C2500_MAC *) dev->priv)->rxLock);
+  }
+  dev->open				= &s3c2500_open;
+  dev->stop				= &s3c2500_close;
+  dev->hard_start_xmit	= &s3c2500_send_packet;
+  dev->get_stats		= &s3c2500_get_stats;
+  dev->set_multicast_list = &set_multicast_list;
+
+  dev->tx_timeout		= &s3c2500_tx_timeout;
+  dev->watchdog_timeo	= MY_TX_TIMEOUT; 
+  dev->set_mac_address	= &SetMacAddr;
+  /*
+   * Fill in the rest of the fields of the device structure 
+   * with ethernet values. 
+   */
+#if	ENABLE_DESTRUCTOR 
+  //... Destructors weren't always called - memory leaks in on...MaTed---
+  priv->destructor 	= &s3c2500Destructor;
+#endif
+  /*
+   * The following can be implemented but hasn't been
+   */
+  //  dev->do_ioctl		= &s3c2500_do_ioctl;
+  return ( S3C2500_SUCCESS);
+}
+/************************************************************************
+ * This is the real probe routine. Linux has a history of friendly device
+ * probes on the ISA bus. A good device probes avoids doing writes, and
+ * verifies that the correct device exists and functions.
+ * -- This version is hard coded to just find only the hard coded addresses
+ *		It will only be called NUM_HW_ADDR times.
+ * NOTE: now gets HW address from external routine. If there is no
+ *  bootloader, then this routine must still return a HW address ...MaTed ---
+ ************************************************************************/
+// #define MATED_SKIPMAC 1	// external routine NOT available for MAC address
+static int __init 
+s3c2500_probe1( ND dev, UINT32 chan)
+{
+  int 	    		i;
+  static unsigned 	version_printed = 0;
+  char *			ptr;
+  int 				rc;		//return code
+
+  //  void * 			tptr;			/* temporary pointer */
+
+#ifdef MATED_SKIPMAC
+  char		dummyMacAddr[6] = {0,2,4,8,16,32};
+#endif
+
+  if ( version_printed++ == 0)
+  {
+	/* This section just gets called once, that's why the code doesn't
+	   seem like it belongs here */
+	// Forcing ethernet h/w to reset, just so soft reset doesn't fail
+	Reset( 0 );
+	Reset( 1 );
+
+	//	if (NET_DEBUG > 2)
+	if (CONFIG_ETH_DMA_PRIORITY)	/* change the priority of the 
+									   DMA channels */
+	{
+#if CONFIG_DMA_PRIORITY_ROBIN 	// force the DMA priority type
+	  printk("S3C2500: DMA arbitration set to round-robin:\n");
+	  /* Forcing DMA arbitration to round-robin */
+	  *(volatile unsigned int *)SYSCFG &= 0x3ffffffe; 
+#else
+	  printk("S3C2500: DMA arbitration set to fixed priority:\n");
+	  /* Forcing DMA arbitration to fixed priority round-robin */
+	  *(volatile unsigned int *)SYSCFG |= 0x00000001; 
+#endif
+	  printk("  * HPRIR-0x%lx and HPRIF-0x%lx changed to ",
+			 *((UINT32 *) HPRIR), *((UINT32 *) HPRIF));
+	
+	  /*****************************************************
+	   * test code to up DMA priority of GMDA, eth0 and eth1
+	   * 0x110fe0 gives (37 total - 133 Mhz bus))
+	   * HDLCC 2/37 of 1/2 the bus
+	   * HDLCB 2/37 of 1/2 the bus
+	   * HDLCA 1/37 of 1/2 the bus
+	   * eth0 (I reverse it)
+	   *       16/37 of 1/2 the bus
+	   * eth1 (reversed in software)
+	   *       15/37 of the bus
+	   * GDMA  1/37 of 1/2 the bus
+       ** but because GDMA is not used, there is no card for HDLCA
+	   ** HDLCC gets 2, HDLCB - 3, eth0 - 16 and eth1 - 16
+	   ** (3.6, 5.4, 9.8, and 9.8 Mhz)
+	   ******************************************************/
+
+	  *((UINT32 *) HPRIR) = 0x110fe0;
+
+	  /*********************************************************
+	   * give Controller 0 (which is eth1 -WAN) highest priority
+	   * then eth0, HDLCB, HDLCC, GDMA, and HDLCA
+	   *********************************************************/
+
+	  *((UINT32 *) HPRIF) = 0x305421;
+
+	  printk("HPRIF-0x%lx and HPRIR-0x%lx \n ", 
+			 *((UINT32 *) HPRIR), *((UINT32 *) HPRIF));
+	}
+
+	/*** This section rewritten - with new page_alloc2() modification ***/ 
+#if !defined(CONFIG_UNCACHED_MEM)
+#error	"**** ERROR: this version of the driver requires CONFIG_UNCACHED_MEM;"
+#endif
+	// request uncache memory
+	
+	if (NULL == (FDescUncached = kmalloc( sizeof(FDAArea), GFP_DMA)))
+	  return( S3C2500_FAIL);
+
+	if (NET_DEBUG )
+	{
+	  printk( KERN_INFO "%s", version);
+	  if (NET_DEBUG > 3)
+	  {
+		printk( KERN_INFO 
+				"S3C2500: Buffer Address = [0x%p]\n", 
+				FDescUncached);
+	  }
+	}
+  }
+
+  printk( KERN_INFO "%s: %s found at %08lx, ", dev->name, MacName[ chan ], 
+		  dev->base_addr);
+  /* Fill in the 'dev' fields. */
+#ifdef MATED_SKIPMAC
+  ptr = dummyMacAddr;
+#else
+  ptr = get_MAC_address( MacHWAddr[ chan ]);
+#endif
+
+  memcpy( dev->dev_addr, ptr, NUM_HW_ADDR);
+  for ( i = 0; i < NUM_HW_ADDR; i++)
+  {
+    printk("%02x.", dev->dev_addr[ i]);
+  }
+  printk( "\n");
+  dev->addr_len = NUM_HW_ADDR;
+  if ( s3c2500_request_irq_mem( dev, chan))
+  {
+	return ( -EAGAIN);
+  }
+  Reset( chan );			// Force initial conditions
+  DisableInt( chan );
+  ether_setup( dev);
+  DisableInt( chan);
+  SetupRegistersTx( dev );
+  SetupRegistersRx( dev );
+  DisableTxRx( chan );
+  DisableInt( chan );
+  //  return( s3c2500_InitVars( dev));
+  if (S3C2500_SUCCESS != (rc = s3c2500_InitVars( dev, chan)))
+	{
+	  return( rc);
+	}
+  // might be a bit redundant with the initial probe -- But ...
+  // Zero out the stats
+  memset( &((S3C2500_MAC *) dev->priv)->stats, 0, 
+		  sizeof( struct net_device_stats ));
+  return( S3C2500_SUCCESS );
+}
+/*******************************************
+ * Blocks the multiple requests to set IRQ
+ *******************************************/
+static int	run_request = 0;
+/**********************************************************************
+ * s3c2500_request_irq_mem - routine to set the interrupt vectors and mem
+ **********************************************************************/
+static _INLINE_ int
+s3c2500_request_irq_mem( ND dev, UINT32 chan)
+{
+  int		 	rc;
+
+  if (run_request++ < numS3c2500Macs)
+	{
+	  return (S3C2500_SUCCESS);
+	}
+  /*
+   * The ethernet MACS have fixed interrupts, allocate the interrupt
+   * vector now. There is no point in waiting since no other device
+   * can use the interrupt, and this marks the irq as busy. Jumpered
+   * interrupts are typically not reported by the boards. 
+   *
+   * The S3C2500 allocates 2 interrupts for each of the two MACs
+   */
+
+  if ( (rc = request_irq( IRQNumTx[ chan ], &s3c2500_Tx, SA_INTERRUPT,
+						 IntNames[ 2 * chan ], dev)))
+  {
+    printk( KERN_WARNING "%s: unable to get IRQ %d (irqval=%d).\n",
+	    dev->name, (UINT16) IRQNumTx[ chan ], (UINT16) rc);
+    return ( -EAGAIN);
+  }
+  if ( (rc = request_irq( IRQNumRx[ chan ], &s3c2500_Rx, SA_INTERRUPT,
+						  IntNames [ 1 + 2 * chan ], dev)))
+  {
+    printk( KERN_WARNING "%s: unable to get IRQ %d (irqval=%d).\n",
+	    dev->name, (UINT16) IRQNumRx[ chan ], (UINT16) rc);
+	free_irq( IRQNumTx[ chan ], dev);	// free the one we got
+    return ( -EAGAIN);
+  }
+  /* Grab the region so that no one else tries to probe our ioports. */
+  if (! request_mem_region( dev->base_addr, sizeof(CSR),
+							dev->name))
+  {
+    printk( KERN_WARNING "%s: unable to get memory/io address region %lx\n",
+	    dev->name, dev->base_addr);
+	free_irq( IRQNumTx[ chan ], dev);
+	free_irq( IRQNumRx[ chan ], dev);
+    return (-EAGAIN);
+  }
+  run_request = 1;
+  return (rc);
+}
+/**********************************************************************
+ * s3c2500_release_irq_mem - routine to release the interrupt vectors and mem
+ **********************************************************************/
+static _INLINE_ int
+s3c2500_release_irq_mem( ND dev)
+{
+  UINT32		chan = ((S3C2500_MAC *) dev->priv)->channel;
+
+  if (run_request < numS3c2500Macs)	/* did we allocate them yet */
+	{
+	  return( S3C2500_SUCCESS);
+	}
+  /* release all the interrupts */
+	free_irq( IRQNumTx[ chan ], dev);
+	free_irq( IRQNumRx[ chan ], dev);
+
+  /* Release the region so that some else (including ourselves) can have it */
+  release_mem_region( dev->base_addr, sizeof(CSR) );
+
+  run_request--;	/* someone else can use it now */
+  return ( S3C2500_SUCCESS);
+}
+/***********************************************************************
+ * log transmit MAC errors - status register is
+ * *** NOT *** the same as the
+ *		status in the FD block - juse the FD.status (multiple packets)
+ * ** Coded for the FD block (txtimeout has to be modified)
+ *	returns S3C2500_FAIL if error
+ *			S3C2500_SUCCESS if status did not show error
+ ***********************************************************************/
+static _INLINE_ int 
+ s3c2500LogTxMACError( ND dev, int status)
+{
+  S3C2500_MAC * priv = dev->priv;
+  CSR *			baseAddr = (CSR *) (dev->base_addr);
+  UINT32		RegStat = ReadCSR( MacTxStat);
+
+  if (status & TxS_Coll)
+  {
+	priv->stats.collisions ++;	// we got at least one collision
+  }
+  if ( RegStat & MCollCnt)
+  {
+	priv->stats.collisions += ( RegStat & MCollCnt) >> 8;	// add collisions
+  }
+#if 0
+  // If the transmission is complete, we ignore FIFO underrun
+  if (status & TxS_Comp)
+	status &= ~TxS_Under;
+#endif
+  if (0 == (status 
+			& (TxS_ExColl + TxS_LateColl + TxS_Defer + TxS_Paused
+			   + TxS_MaxDefer + TxS_Halted + TxS_NCarr + TxS_Par 
+			   + TxS_Under + TxS_SQErr)))
+  {
+	return ( S3C2500_SUCCESS);
+  }
+  priv->stats.tx_errors++;				// we have an error
+  // now log specific error
+  if ( status & (TxS_ExColl))
+  {
+	priv->stats.collisions += 16;	// at least 16 collisions occurred
+  }
+  if ( status & (TxS_MaxDefer + TxS_Paused + TxS_Halted + TxS_ExColl 
+				 + TxS_Halted))
+    priv->stats.tx_aborted_errors++;
+  if ( status & (TxS_LateColl))
+    priv->stats.tx_window_errors++;
+  if ( status & TxS_NCarr)
+    priv->stats.tx_carrier_errors++;
+  if ( status & (TxS_Par + TxS_Under))	// Underrun is here??
+    priv->stats.tx_fifo_errors++;
+
+  if (NET_DEBUG > 3 && 0)	// special output for debugging
+  {
+	CSR         *	baseAddr 	= (CSR *) (dev->base_addr);
+	if (status & TxS_Under)
+	{
+	  printk(" **TxFIFO underrun- Controller Cnt-%ld First-%d Status-0x%x\n",
+			 ReadCSR( TxCnt), priv->ringTx.first, status);
+	}
+  }
+
+  if ( status & (TxS_SQErr + TxS_Defer))
+    priv->stats.tx_heartbeat_errors++;
+#if 0	// there are circumstances when the  transmitter has to be restarted
+        // I haven't found one yet, but as a reminder ...MaTed---
+  if ( status & (TXS__PARITY + ???))
+	// restart transmitter
+#endif
+  return ( S3C2500_FAIL);
+}
+/***********************************************************************
+ * log receive BDMA errors
+ *	returns S3C2500_FAIL if error
+ *			S3C2500_SUCCESS if status did not show error
+ * - status passed should be from the F Descriptor
+ ***********************************************************************/
+static _INLINE_ int 
+s3c2500LogRxBdmaError( ND dev, int status)
+{
+  S3C2500_MAC * 	priv = dev->priv;
+
+  // Check if there were errors
+  if (0 == (status 
+	    & (RxS_OvMax + RxS_AlignErr + RxS_CrcErr + RxS_OFlow +
+		   RxS_MUFS + RxS_RxPar + RxS_Halted )))
+//	    & (RxS_OvMax + RxS_AlignErr + RxS_CrcErr +
+  {
+    return ( S3C2500_SUCCESS);
+  }
+  priv->stats.rx_errors++;
+  // now log specific errors
+  if ( status & ( RxS_OvMax + RxS_MUFS ))
+    priv->stats.rx_length_errors++;
+  if ( status & ( RxS_CrcErr ))
+    priv->stats.rx_crc_errors++;
+  if ( status & ( RxS_AlignErr ))
+    priv->stats.rx_frame_errors++;
+
+  if (NET_DEBUG > 3 && 0)	// special output for debugging
+  {
+	CSR         *	baseAddr 	= (CSR *) (dev->base_addr);
+	if (status & RxS_OFlow)
+	{
+#if (MATED_RX_OF_BUG)		// printk the previous buffer lengths
+	  {
+		int i;
+		int index = rx_len_index[ priv->channel];
+
+		printk("*Rx OF(%ld)- BRXBDCNT-%ld First-%d Stat-0x%x IntStat-0x%lx\n"
+			   " TxNum [%6ld] ",
+			   priv->channel, ReadCSR( RxCnt), 
+			   priv->ringRx.first, status, ReadCSR(RxStat),
+			   priv->stats.tx_packets);
+		for (i = 0; i < RX_OF_MAX_LOG; i++)
+		{
+		  index = (index == 0) ? RX_OF_MAX_LOG - 1 : index - 1;
+		  printk("%4ld ", rx_len_array[ priv->channel][ index]);
+		}
+		printk("-\n");
+	  }
+#endif // MATED_RX_OF_BUG
+
+#define SAMSUNG_WANTED_DEBUG 0
+	  if ( SAMSUNG_WANTED_DEBUG)
+	  {
+		printk("*RxF OF(%ld)- BRXBDCNT-%ld BDMARXCON-0x%lx BDMATXCON-0x%lx",
+			   priv->channel, ReadCSR( RxCnt), 
+			   ReadCSR( RxCtl), ReadCSR( TxCtl));
+		printk(" MACCON-0x%lx MACRXCON-0x%lx MACTXCON-0x%lx\n",
+			   ReadCSR( MacCtl), ReadCSR( MacRxCtl), ReadCSR( MacTxCtl));
+		printk(" *CAMCON-0x%lx CAMEN-0x%lx First-%d Stat-0x%x IntStat-0x%lx\n",
+			   ReadCSR( CamCtl), ReadCSR( CamEn),
+			   priv->ringRx.first, status, ReadCSR(RxStat));
+	  }
+	}
+  }
+
+  if ( status & ( RxS_OFlow + RxS_RxPar ))
+    priv->stats.rx_fifo_errors++;
+  if ( status & ( RxS_Halted ))	// may be other updaters to this
+    priv->stats.rx_missed_errors++;
+  return ( S3C2500_FAIL);
+}
+/***********************************************************************
+ * Transmit timeout
+ *	Kernel calls this routine when a transmit has timed out
+ ***********************************************************************/
+static void 
+s3c2500_tx_timeout( ND dev)
+{
+  S3C2500_MAC *	priv = dev->priv;
+  CSR *			baseAddr = (CSR *) (dev->base_addr);
+  UINT32		BStat = ReadCSR( TxStat);
+  UINT32		MacStat  = ReadCSR( MacTxStat);
+
+  if (NET_DEBUG > 3)
+	{
+	  printk( KERN_ERR "%s: transmit timed out: NUM= %d, MacTXStatus=0x%08lX ",
+			  dev->name, priv->ringTx.num, MacStat );
+	  printk( KERN_ERR "MacBDMAStatus=0x%08lX ", BStat );
+	}
+  /********************************************************
+   * NOTE: This section probably needs more work ...MaTed--- FIXME
+   * - much of this has been fixed with the OPEN/CLOSE updates
+   *   but we should add more to reset the Ethernet controller
+   *   as well - NOTE: reset now occurs in CLOSE routine
+  ********************************************************/
+  // We are going to reset the MAC
+  //  - all packets - both rx and tx may be discarded
+  //  - have to change logic to allow errors to stay around
+
+	// Can't call error routine - bits no longer the same;
+	//(void) s3c2500LogTxMACError( dev, MacStatus);
+	//  (void) s3c2500LogTxBDMAError( dev, BDMAStatus);
+  if ( MacStat & MCollCnt)
+  {
+	priv->stats.collisions += ( MacStat & MCollCnt) >> 8;	// add collisions
+  }
+  if (0 == (BStat 
+	    & (ExColl + Underflow + DeferErr + NoCarr + LateColl + TxParErr)))
+  {
+	priv->stats.tx_errors++;
+	// now log specific error
+	if ( BStat & ExColl)
+	  priv->stats.collisions += 16;	// at least 16 collisions occurred
+	if ( BStat & (TxParErr + Underflow))	// Underrun is here??
+	  priv->stats.tx_fifo_errors++;
+	if ( BStat &  DeferErr)
+	  priv->stats.tx_heartbeat_errors++;
+	if ( BStat & NoCarr)
+	  priv->stats.tx_carrier_errors++;
+	if ( BStat &  LateColl)
+	  priv->stats.tx_window_errors++;
+	//	if ( BStat & (TxS_MaxDefer + TxS_Paused + TxS_Halted + TxS_ExColl 
+	//				   + TxS_Halted))
+	//	  priv->stats.tx_aborted_errors++;
+  }
+
+  // FIXME ...MaTed--- the close  / open has not been fully tested
+  s3c2500_close( dev);
+
+  s3c2500_open( dev);
+  // Kick the MAC to check if there is something to send
+  // - this is unnecessary, unless we add code to only do the
+  //   close/open every 2nd or third time ...MaTed
+  //WriteCSR( DMACtl, ReadCSR( DMACtl) | DMA_CTL_TxWakeUp);
+
+  /* If we have space available to accept new transmit
+   * requests, wake up the queueing layer.  This would
+   * be the case if the chipset_init() call above just
+   * flushes out the tx queue and empties it.
+   *
+   * If instead, the tx queue is retained then the
+   * netif_wake_queue() call should be placed in the
+   * TX completion interrupt handler of the driver instead
+   * of here.
+   */
+  if (!txFull( dev))
+    netif_wake_queue( dev);
+  dev->trans_start = jiffies;		// reset the start time
+  return;
+}
+/************************************************************************
+ * initialize all the data in private area
+ ************************************************************************/
+static _INLINE_ int 
+s3c2500InitPriv( ND dev, UINT32 chan )
+{
+  S3C2500_MAC * np 			= dev->priv;
+  CSR *			baseAddr 	= (CSR *) (dev->base_addr);
+  RET_CODE	  	rc;
+
+  memset( np, 0, sizeof( S3C2500_MAC));
+  
+  /* setup the MAC HW address */
+  SetUpARC( dev, dev->dev_addr);
+  /* setup channel number */
+  ((S3C2500_MAC *) dev->priv)->channel = numS3c2500Macs;
+
+  // ******** Enhancement FIXME-pickup duplex and speed from commandline 
+  // ********  OR from Bootloader envirnment variable ...MaTed---
+  // - if you want to force, userland force later
+  // np->phySpeed = 2;		// Force 100
+  // np->phySpeed = 0;		// automatic MII mode force speed = 10
+  np->phySpeed = 3;			// automatic MII mode 
+  //  np->phySpeed = 1;		// Force 10 Mb/s endec
+
+  /* Mac CNTL Full Duplex */
+  np->phyDpx = 1;			/* Full Duplex */
+  //np->phyDpx = 0;			/* Half Duplex, if MII_Conn is High?? */
+
+  /* set channel */
+  np->channel = chan;
+
+  /* set Frame Descriptors */
+  np->rxFd = FDescUncached->rxFdArray[ chan ];
+  np->txFd = FDescUncached->txFdArray[ chan ];
+
+#if (CONFIG_WBUFFER)
+	np->txBuff = FDescUncached->txFdBuffers[ chan ];
+#endif
+
+  // Setup in SetupTxFDs
+  WriteCSR( RxPtr, np->rxFd);	/* Rx frame descriptor start 	*/
+  /* Setup indices into Frame Descriptor array */
+  np->ringRx.first = np->ringRx.num = 0;
+  np->ringRx.max = np->ringRx.last = RX_NUM_FD-1;		// maximum value
+  /* Setup the ring buffer indices */
+  np->ringTx.first = np->ringTx.last = np->ringTx.num = 0;
+  np->ringTx.max = TX_NUM_FD-1;
+
+  /***  NOTE this array needs to be in a region that is non-cachable 	***/
+  WriteCSR( TxPtr, np->txFd);// changed to address of fixed array
+  /*
+   * NOW set up the S3c2500 MAC struct
+   */
+  if ((rc = SetupTxFDs( dev)))
+    return (rc);
+  if ((rc = SetupRxFDs( dev)))
+    return (rc);
+  // no error
+  return ( S3C2500_SUCCESS);
+}
+/************************************************************************
+ * Open/initialize the board. This is called (in the current kernel)
+ * sometime after booting when the 'ifconfig' program is run.
+ *
+ * This routine should set everything up anew at each open, even
+ * registers that "should" only need to be set once at boot, so that
+ * there is non-reboot way to recover if something goes wrong.
+ ***********************************************************************/
+static int
+s3c2500_open( ND dev)
+{
+  S3C2500_MAC * np = (S3C2500_MAC *) dev->priv;
+  //  UINT		basePort = dev->base_addr;
+  RET_CODE		rc;
+
+#if MPROFILE		// clear miniprofile
+  {
+	int 		i;
+	profileAddrIndex = 0;	/* start at the beginning */
+	for (i = 0; i < ProfileArraySize; i++)
+	  {
+		profileArray[ i ].code = 0;
+	  }
+  }
+#endif
+  /*
+   * This is used if the interrupt line can turned off (shared).
+   * - Can we share? - might as well register
+   */
+#if 0	// open only in probe routine - it is an embedded device ...MaTed---
+  rc = s3c2500_request_irq_mem( dev, np->channel);
+  TDEBUG("S3C2500_OPEN: request_irq_mem rc=%d\n", rc);
+  if (rc)
+	{
+	  printk( KERN_ERR "S3C2500: Cannot get irq/mem rc=%d\n", rc);
+	  return -EAGAIN;
+	}
+#endif
+  // We are leaving priv intact
+  //  if (S3C2500_SUCCESS != (rc = s3c2500_InitVars( dev)))
+  //    return (rc);
+  /* Reset the hardware here. Don't forget to set the station address. */
+  if (S3C2500_SUCCESS != (rc = TxRxInit( dev)))
+	{
+	  printk( KERN_ERR "S3C2500: Phys init failed \n");
+	  return (rc);
+	}
+  EnableTxRx( np->channel );
+  EnableInt( np->channel );
+
+  //  priv->open_time = jiffies;
+  /* We are now ready to accept transmit requests from
+   * the queueing layer of the networking.
+   */
+  netif_start_queue( dev);
+
+  return S3C2500_SUCCESS;
+}
+/************************************************************************
+ * Description:
+ *	This routine is called by the upper layers send out a SKB on the device
+ *		specified by dev
+ * NOTES:This will only be invoked if your driver is _not_ in XOFF state.
+ * What this means is that you need not check it, and that this
+ * invariant will hold if you make sure that the netif_*_queue()
+ * calls are done at the proper times.
+ ************************************************************************/
+static int s3c2500_send_packet( struct sk_buff *skb, ND dev)
+{
+  S3C2500_MAC 	  *	np 			= dev->priv;
+  int 				baseAddr 	= dev->base_addr;
+  //  short			length;
+  //  UCHAR		   	  *	buf 	= skb->data;
+  TxFD 			  *	fdPtr 		= np->txFd;
+#if ! CONFIG_WBUFFER
+  TxBUFF		  * txSkb		= np->txSkb;
+#endif // ! CONFIG_WBUFFER
+  RINGBUFF		  *	ringTx 		= & np->ringTx;
+  UINT16			first 		= ringTx->first;
+  UINT32			temp;
+
+  enterCnt(0x300);		// ******-******* Profiling code
+  // make minimum length for TX
+  //  Don't need this, the controller does it for me
+  //length = ETH_MIN_LEN < skb->len ? skb->len : ETH_MIN_LEN;
+
+  /* If some error occurs while trying to transmit this
+   * packet, you should return '1' from this function.
+   * In such a case you _may not_ do anything to the
+   * SKB, it is still owned by the network queueing
+   * layer when an error is returned.  This means you
+   * may not modify any SKB fields, you may not free
+   * the SKB, etc.
+   */
+
+  if (NET_DEBUG > 5)
+	{
+	  printk( KERN_ERR "%s: Send: %3d len=%d SKB=%p\n", 
+			  dev->name, (unsigned int) first, (unsigned int) skb->len, skb);
+	}
+  if (NET_DEBUG > 6)
+	{
+	  int i;
+	  printk( KERN_ERR "S3C2500_SEND: Length %d\n - data=", skb->len);
+	  for ( i = 0; i < skb->len; i++)
+		{
+		  printk("%02x ", skb->data[ i]);
+		}
+	  printk("\n");
+	}
+  if (NET_DEBUG > 3)
+	{
+	  ASSERT( atomic_read( &skb->users) == 1);
+	}
+
+#if (NET_DEBUG > 3 && 0) // temp code to verify full size packet transfer
+                         //  for TESTING only (NET_DEBUG should be higher)
+                         //  ...MaTed---
+  if (skb->len != 1514)	// maximum size packet
+  {
+	printk(" T%1ld-%3d %4d ", np->channel, first, skb->len);
+	if (++position_output > 5)
+	{
+	  position_output = 0;
+	  printk("\n");
+	}
+  }
+#endif
+
+  /* This is the most common case for modern hardware.
+   * The spinlock protects this code from the TX complete
+   * hardware interrupt handler.  Queue flow control is
+   * thus managed under this lock as well.
+   */
+  spin_lock_irq( &np->txLock);
+
+  TxPktCompletion( dev );		// clear out the packets already sent
+
+  /* Check to see if there is room */
+  if (txFull( dev ))	// < to guarentee at least one spot
+  {
+    printk( KERN_ERR "TX overflow on %s\n", dev->name);
+	// MAKE Sure transmitter was enabled -- maybe that will clear it up 
+	//	WriteCSR( TxCtl, temp | BTxEN);
+	//	WriteCSR( MacTxCtl, (ReadCSR( MacTxCtl) | MTxCtlTxEn) & ~MTxHalt);
+	EnableTxRx( np->channel);
+	spin_unlock_irq( &np->txLock);
+    return ( -1);	// tell upper layer to requeue
+  }
+  if (NET_DEBUG > 4)
+  {
+	  /* another paranoid check (next should be owned by system */
+	if (fdPtr[ first ].FDStat & OWNERSHIP)
+	{
+	  printk( KERN_ERR "TX ownership problem on %s\n", dev->name);
+	  spin_unlock_irq( &np->txLock);
+	  return (-1);
+	}
+  }
+
+  enterCnt(0x301);		// ******-******* Profiling code
+
+#if (CONFIG_WBUFFER)
+  {
+	/* 
+	 * - copy the data to the transmit buffer
+	 * - we skip the first two bytes of the tx buffer (just filler)
+	 * because we want the copy to be word to word aligned
+	 */
+	memcpy( np->txBuff[ first].FDData + 2, skb->data, skb->len);
+	// leave this in until we check if it's faster to copy the extra two
+	//  bytes ...MaTed---
+	//  memcpy( np->txBuff[ first], skb->data - 2, skb->len + 2);
+  }
+#else
+  {
+	txSkb[ first].FDskb = skb;
+	fdPtr[ first ].FDDataPtr = skb->data;
+  }
+#endif 
+  fdPtr[ first ].FDLength = skb->len;
+  if (NET_DEBUG > 3)
+  {
+	ASSERT( atomic_read( &skb->users) == 1);
+  }
+  if (NET_DEBUG > 5)
+  {
+	if (atomic_read( &skb->users) != 1)
+	{
+	  printk("SKB:%08lx, users:%lx\n",
+			 (UINT32) &skb, 
+			 (UINT32) atomic_read( &skb->users));
+	}
+  }
+  if (CONFIG_WBUFFER)
+  {
+	dev_kfree_skb_irq (skb);		// done with the skb - free it
+  }
+
+  ringTx->num ++;			// another buffer in the ring
+  ringTx->first = incIndex( first ,ringTx->max);
+  dev->trans_start = jiffies;
+  enterCnt(0x302);		// ******-******* Profiling code
+  fdPtr[ first ].FDStat = TxWidSet16 + OWNERSHIP16;	// 2 byte offset,
+                                                    // clear stat
+                                                    // Pass to BDMA
+
+  // Let the MAC know there is something to send (in case it stopped )
+  // ...Note the check is from example code (why?), extra comp is for compliler
+  if (! ((temp = ReadCSR( TxCtl)) & BTxEN))
+  {
+	WriteCSR( TxCtl, temp | BTxEN);
+  }
+  WriteCSR( MacTxCtl, ReadCSR( MacTxCtl) | MTxEn);
+
+#if !NO_TX_COMP_INT	// check to see if we need to turn this back on 
+                        // - probably extraneous
+  // turn on tx completion interrupt
+  WriteCSR( TxIntEn, ReadCSR( TxIntEn ) | TxCompIE );
+#endif
+
+  enterCnt(0x303);		// ******-******* Profiling code
+  /* If we just used up the very last entry in the
+   * TX ring on this device, tell the queueing
+   * layer to send no more.
+   */
+  if (txFull( dev))
+  {
+    netif_stop_queue( dev);
+  }
+
+  enterCnt(0x304);		// ******-******* Profiling code
+#if NO_TX_COMP_INT
+  TxPktCompletion( dev );
+#endif
+
+  /* 
+   * When the TX completion hw interrupt arrives (or TxPktCompletion()
+   * is called), most of the transmit statistics are updated.
+   */
+  spin_unlock_irq( &np->txLock);
+
+  enterCnt(0x3ff);		// ******-******* Profiling code
+  return 0;
+}
+/************************************************************************
+ * Helper routine to collect stats on tx completion and release skbs
+ * MUST be called with spin_lock already invoked
+ ************************************************************************/
+//static _INLINE_ void
+static void
+TxPktCompletion( ND dev)
+{
+  S3C2500_MAC 	  *	np 			= dev->priv;
+  int 				baseAddr 	= dev->base_addr;
+  TxFD 			  *	txFd 		= np->txFd;
+  RINGBUFF		  *	ringTx 		= & np->ringTx;
+#if ! CONFIG_WBUFFER
+  TxFD 			  *	fdPtr 		= np->txFd;
+  TxBUFF		  * txSkb		= np->txSkb;
+#endif // ! CONFIG_WBUFFER
+  UINT32			S3cTxCnt;
+  UINT16			MissCnt;
+  UINT16			last;
+
+  // set the count where the Mac transmit Pointer is at - don't try to 
+  //  catch the next one "going" to happen
+  S3cTxCnt = ReadCSR( TxCnt);
+
+  while ( (last = ringTx->last) != S3cTxCnt)	// It's possible that there 
+	                                //  was nothing sent
+  {
+	/*** Only in here if MAC processed at least one packet */
+    // checks to see if there was an error as well
+	if (S3C2500_SUCCESS == s3c2500LogTxMACError( dev, txFd[ last ].FDStat))
+	{
+	  np->stats.tx_bytes += np->txFd->FDLength;	// total bytes transmitted
+	  // NOTE: only good packets were transmitted (whereas rx can get bad)
+	  np->stats.tx_packets++;			// total packets transmitted
+	}
+	else
+	{ // a tx error of some kind occurred
+	  // clear EMISSCNT register , by read (example code)
+	  MissCnt = (UINT16) ReadCSR( MissCnt);
+#if 0	// This seems wrong, might need something but not this ...MaTed---
+	  SetupRegistersTx( dev );		// force Tx registers if error
+#endif
+	}
+	/*
+	 * The following stuff we have to do regardless if the packet
+	 *	transmission had errors or not
+	 */
+	// update the number of collisions
+	//  *** NOTE: if multiple packets, this is probably wrong ...MaTed---
+	np->stats.collisions += (ReadCSR( MacTxStat) & MCollCnt) >> MCollShift;
+	if ( ! CONFIG_WBUFFER)
+	{
+	  dev_kfree_skb_irq( txSkb[ last].FDskb );
+	  /* This has been moved out of the optional NET_DEBUG section
+	   *  because s3c2500_close routine needs to know which SKBs 
+	   *  are currently still occupying locations (I know I should 
+	   *  have only cleared the ones between the indices, BUT...MaTed---
+	   */
+	  txSkb[ last ].FDskb = NULL;
+	  if (NET_DEBUG > 2)
+	  {
+		fdPtr[ last ].FDDataPtr = NULL;
+	  }
+	}
+	// Clearing parts of the FD structure (probably not needed ??? )
+	if (NET_DEBUG > 2)
+	{
+	  txFd[ last ].FDLength = 0x0000;		// turn off length
+	}
+
+	if (NET_DEBUG > 1)
+	{
+	  // Might have to move this outside the conditional
+	  txFd[ last ].FDStat = 0x0000;		// Turn off status, keep ownership
+	}
+	// Move on to the next in the list
+	ringTx->last = incIndex( last, ringTx->max);
+	ringTx->num--;
+  }
+}
+/************************************************************************
+ * This handles TX complete events posted by the device interrupt.
+ * - includes the following
+ *	- transmit of a frame completed (*** Do we want this enabled??? **)
+ *	- Sent all frames (stopped by owner bit)
+ *		- it would be nice to use this interrupt rather than the MAC "Send"
+ *		per packet, but error status and busy cause probs 
+ *		- the interrupt should be disabled serves no purpose
+ *		- two parts to this, we disable the interrupt (see EnableInt )
+ *		but enable the stop (no skip frame)
+ *	- Interrupt on control packet after MAC sends
+ *		- we don't currently send control packets, so this int is never
+ *		envoked.
+ *		- we will leave it enabled though
+ *	- Tx Buffer Empty
+ *		- leaving this off too
+ ************************************************************************/
+void s3c2500_Tx( int irq, void *dev_id, struct pt_regs * regs)
+{
+  ND 			dev 		= dev_id;
+  CSR 		  *	baseAddr 	= (CSR *) (dev->base_addr);
+  S3C2500_MAC *	np 			= dev->priv;
+  UINT32		status;
+
+  enterCntVal(0x100, ReadCSR( TxStat));		// ******-******* Profiling code
+  spin_lock( &np->txLock);
+  status = ReadCSR( TxStat);	// save interrupting status to clear
+
+#if ! NO_TX_COMP_INT	// do we have packet completion interrrupt turned off?
+  TxPktCompletion( dev);
+#endif
+
+  // checks to see if there was an additional (MAC/BDMA internal) error as well
+#if 0
+  if ( status & BTxEmpty )
+  {
+	printk( "%s: Invalid interrupt! Transmit Buffer Empty \n", dev->name);
+  } else if (status & BTxNO )
+#else
+  if (status & BTxNO )
+#endif
+  {
+#if 0	// occurs end of every transmit - can optimize around this? ...MaTed---
+	if (NET_DEBUG > 4)
+	  {
+		printk( "%s: Shutting Tx Down - No owner for TX buffer [0x%08x]\n",
+				dev->name, ((int) ReadCSR( TxPtr)));
+	  }
+#endif
+#if 0	// the transmit Enable is automatically cleared on Not Owner
+	// Shut down the transmitter - nothing to send
+	WriteCSR( TxCtl, (( ReadCSR( TxCtl)) & ~BTxEN));
+#endif
+	// Disable the NoOwnership Interrupt
+	WriteCSR( TxIntEn, ReadCSR( TxIntEn ) & ~BTxNOIE );
+  } else if ((NET_DEBUG > 3) && status & TxCFcomp )
+	{	/* we currently aren't supporting control packets */
+	  printk( "%s: Invalid interrupt! Control Packet Sent \n", dev->name);
+	}
+  // Now we clear the interrupts
+  WriteCSR( TxStat, ReadCSR(TxStat) & (~(status & TxINTMask)));
+  // done with critical section
+  spin_unlock( &np->txLock);
+  enterCnt(0x1FF);		// ******-******* Profiling code
+}
+/************************************************************************
+ *NOTE this needs updating ...MaTed---
+ * Rx interrupt - Frame received (others ??)
+ * We have a good packet(s), get it/them out of the buffers.
+ * - we take both BL and FDA from the MAC.first
+ *   - move them to the front.last
+ *	 - buffer is stripped off, added to skb head, skb address stored in ??
+ *	- continue while MAC.first != MAC.last
+ * 	- other things to check / do
+ *		- ensure all four entries are set to SYS_OWNS_xx
+ * Additional code - if the next position is owned by the CPU,
+ *	we will drop the current packet, and stay in the same place
+ ************************************************************************/
+static void
+s3c2500_Rx( int irq, void *dev_id, struct pt_regs * regs)
+{
+  ND			dev 		= dev_id;
+  S3C2500_MAC *	np	 		= (S3C2500_MAC *)dev->priv;
+  CSR         *	baseAddr 	= (CSR *) (dev->base_addr);
+  RINGBUFF    *	ringRx		= & np->ringRx;
+  RxFD		  *	rxFd		= np->rxFd;
+  UINT32		bMacRxStat 	= 0;		// MAC Rx Status interrupt reset bits
+  UINT32 		bRxStat		= 0;		// BDMA and frame errors interrupt 
+                                        //  reset bits
+  UINT16	first;			// first received buffer went here
+  UINT16	last;			// the last buffer is the spacer - no length
+                            //  and owned by CPU
+//  UINT32	i;				// we comment this so no one freaks about it
+                            //  loop counter
+//  UINT16	next;			// next buffer to be used
+  UINT32	temp;
+  UINT16	MacRxCnt;		// H/W Receive Index
+  UINT32	MacRxStat;		// MAC Rx Status - special errors
+                            // - only check 8, 11
+  UINT32 	RxStat;			// BDMA and frame errors
+                            // - only look at bit 0, 17, 18
+                            // - bits 1-5 take from frame desc status
+                            // - 16 is the interrupt and must be cleared
+                            // - 19, 20 and 21 we ignore for now
+  UINT16	MissCnt;		// missed error count temp hold
+  UINT32	status;			// Frame Status
+  UINT16	len;			// Frame Length
+#if !RX_ALL_PKTS
+  int 		boguscount = MAXINT_WORK_RX;	// maximum number of 
+#endif
+  struct sk_buff *	skb;	// so we can access skb structures
+
+  enterCnt(0x200);		// ******-******* Profiling code
+  /*
+   * This protects us from concurrent execution of
+   * our dev->hard_start_xmit function above.
+   */
+  spin_lock( &np->rxLock);
+
+  // get the two status registers - we don't check all bits because 
+  //  we haven't enabled them - if you enable other rx features, add the check
+  // - Have made assumption that things like BMRXSTAT.BRxMSO cannot occur
+  //   without BMRXINTEN.BRxMSOIE being sset
+  RxStat = ReadCSR( RxStat);
+  MacRxStat = ReadCSR( MacRxStat);
+
+  // checks to see if there was an error as well
+  if (RxStat & BRxNO )
+  {
+	bRxStat |= BRxNO;			// set bit for clear interrupts below
+
+	// get continuous interrupt ...MaTed---
+
+	// we assume that the later release of the buffer will fix things
+	// BDMA rx setup
+	// Is this enough to recover ...MaTed---
+    //  - we are willing to toss any packets we 
+    //  - currently have, but there is more needed
+	/* FIXME: there must be something to do HERE ...MaTed--- */
+
+	if (NET_DEBUG > 3)
+	{
+	  printk( "%s: Interrupt! Not owner of RX buffer \n", dev->name);
+	}
+	if (NET_DEBUG > 4)
+    {	// show me the internals - did we run out of space?
+	  printk("  first-%d last-%d MacRxCnt-%ld max-%d\n",
+			  ringRx->first, ringRx->last, ReadCSR( RxCnt), ringRx->max);
+	  for(temp=0; temp <ringRx->max; temp +=4)
+	  {
+		printk("  %3ld Len-%d Stat-0x%x Len-%d Stat-0x%x Len-%d Stat-0x%x"
+			   " Len-%d Stat-0x%x\n ",
+			   temp,
+			   rxFd[ temp ].FDLength, rxFd[ temp ].FDStat,
+			   rxFd[ temp + 1].FDLength, rxFd[ temp + 1].FDStat,
+			   rxFd[ temp + 2].FDLength, rxFd[ temp + 2].FDStat,
+			   rxFd[ temp + 3].FDLength, rxFd[ temp + 3].FDStat);
+	  }
+	}
+  }
+  if (RxStat & MissRoll )
+  {
+	bRxStat |= MissRoll;		// set bit for clear interrupts at end
+	MissCnt = (UINT16) ReadCSR( MissCnt);	// clears interrupting condition as
+	                                        //  well
+	if (NET_DEBUG > 1)
+	  {
+		printk( "%s: Interrupt! Missed Error Count rolled over - %d\n", 
+				dev->name, MissCnt);
+	  }
+  }
+
+  // *** I don't think I need this unless MACRXCON.MShortEn is set
+  // ***  but I leave it in until I get an answer back from Samsung ...MaTed---
+  if (MacRxStat & MRxShort )
+  {
+	bMacRxStat |= MRxShort;		// set bit for clear interrupts at end
+	// continue with processing
+	if (NET_DEBUG > 3 )
+	{
+	  printk( "%s: Short Rx Frame - discarded MacRxStat = %0lx, RxStat " \
+			  "= %0lx\n",
+			  dev->name, MacRxStat, RxStat);
+	}
+  }
+#if 0 // Code not needed if we keep the spacing (for full condition 1 blank)
+  /*******************************************
+   * New code to anticipate upcoming possible 
+   * Not Owned interrupt. We will maintain two 
+   * empty FDs (owned by BDMA) in order to not
+   * get the interrupt. This means that if we 
+   * cannot keep the buffer spacing, we drop
+   * the oldest buffers in the list (not ideal,
+   * but it should work. The two FD following
+   * MacRxCnt will be dropped if they are occupied
+   *******************************************/
+#define MAC_RX_CNT_EMPTY	2	// number of entries to keep empty
+  for (i = 0; i < MAC_RX_CNT_EMPTY; i++)
+  {
+	temp = incIndex (MacRxCnt, ringRx->max);
+	if (ringRx->first == temp && 
+		(0 == (rxFd[ temp ].FDStat & OWNERSHIP16 )))
+    {
+	  // give the buffer to BDMA and drop the packet
+	  rxFd[ temp ].FDLength = PKT_BUF_SZ;
+	  rxFd[ temp ].FDStat = OWNERSHIP16;
+	  // we gave it back, advance
+	  ringRx->first = incIndex(ringRx->first, ringRx->max);
+	  // update stats to indicate we tossed the packet
+	  np->stats.rx_missed_errors ++;
+	  np->stats.rx_errors ++;
+	}
+  }
+#endif // 0
+
+  // reset all the interrupting sources, clear to get next receive
+  //  the ones that were set are cleared 
+  // is there a problem with setting ones which were not set ???
+  // ** this is how the DIAG code does it (but it's not correct)
+  bRxStat |= BRxEarly;	// this I never use but seems to be on, so clear anyway
+  bRxStat |= BRxDone;	/* setup to clear the Done interrupt (compiler should
+						 * stick these two together ...MaTed---)
+						 */
+#if 0
+  printk("----bRxStat=0x%lx RxStat=0x%lx bMacRxStat=0x%lx MacRxStat=0x%lx\n",
+		 bRxStat, ReadCSR( RxStat),
+		 bMacRxStat, ReadCSR( MacRxStat));
+#endif
+
+  WriteCSR( RxStat, RxStat & ~bRxStat);
+  WriteCSR( MacRxStat, bMacRxStat);
+
+  MacRxCnt = ReadCSR( RxCnt);	/* Count that the controller is using 
+								 *  - Just handle ones we have the interrupt
+								 *	for. We could reloop and check, but we'd 
+								 *  still have the interrupt to handle
+								 *	so ...MaTed---
+								 */
+#if !RX_ALL_PKTS
+  // boguscount makes sure we don't spend too much time in ISR
+  while (MacRxCnt != ringRx->first && boguscount-- > 0)
+#else
+  while (MacRxCnt != ringRx->first)
+#endif
+  {
+	enterCnt(0x201);		// ******-******* Profiling code
+	first = ringRx->first;	// we make a copy because it's faster
+	                        //  - should change to pointers
+	// NOW we deal with the FD stuff
+    status = rxFd[ first ].FDStat;
+    len = rxFd[ first ].FDLength;
+
+	if (len == 0)
+	{ /* 
+	   *   This happens when the MAC determines there is an error
+	   * Since most of the time something else has caused the MAC to
+	   * set the status. Just need to make sure we do NOT let the
+	   * packet get through with an error.
+	   *	NOTE the error check must match the one in s3c2500LogRdmaError
+	   */
+
+	  if (NET_DEBUG > 4)
+	  {
+		printk( "%s: rx'd ZERO length packet Status=%0lx... Skipped\n",
+				dev->name, status);
+	  }
+
+	  // check if other errors set
+	  // If No error is previously set, set as CrcErr
+	  if (0 == (status 
+			  & (RxS_OvMax + RxS_AlignErr + RxS_CrcErr + RxS_OFlow +
+				 RxS_MUFS + RxS_RxPar + RxS_Halted )))
+	  {
+		  status |= RxS_CrcErr;	// forces CRC stat to increment
+		// No break - treat as error in packet
+		//break;
+	  }
+	}
+#if 1		// Sanity check -- can probably turn this off ...MaTed---
+	if ( status & OWNERSHIP16)
+	{ // This should not happen
+	  if (NET_DEBUG > 3)		// raised from 2 to 3
+	  {
+		printk( "%s: Encountered rx packet not owned\n", dev->name);
+	  }
+	  // We should do something more here to recover ...MaTed---
+	  bRxStat |= BRxDone;			// setup to clear the Done interrupt
+	  status |= RxS_CrcErr;	// forces CRC stat to increment
+	  // No break - treat as error in packet
+	  //break;
+	}
+#endif	// 1 - Sanity check
+
+#if (MATED_RX_OF_BUG)	// Aquire len data to ring
+	{
+#if 0
+	  printk("R%1ld-%3d %4d-%ld\n", np->channel, first, len, 
+			 rx_len_index[ np->channel]);
+	  if (++position_output > 5)
+	  {
+		position_output = 0;
+		printk("\n");
+	  }
+#endif
+	  rx_len_array[ np->channel] [rx_len_index[ np->channel]]
+		= len;
+	  rx_len_index[ np->channel] ++;
+	  if (rx_len_index[ np->channel] == RX_OF_MAX_LOG )
+		rx_len_index[ np->channel] = 0;
+	}
+#endif (MATED_RX_OF_BUG)	// Aquire len data to ring
+
+	// check if the frame was received without error
+	if (S3C2500_SUCCESS == s3c2500LogRxBdmaError( dev, status))
+	{	// good frame received
+	  skb = np->rxSkb[ first ].FDskb;
+      np->stats.rx_bytes += len;
+	  np->stats.rx_packets++;
+	  // update lengths
+	  skb->tail += len;
+	  skb->len += len;
+	  skb->dev = dev;
+	  skb->protocol = eth_type_trans( skb, dev);
+	  dev->last_rx = jiffies;
+#if 0
+  	  skb = dev_alloc_skb( len + 2 );
+	  if (skb == NULL)
+	  {
+		printk(KERN_NOTICE "%s: Memory squeeze, dropping packet. \n",
+			   dev->name);
+		np->stats.rx_dropped++;
+#if 0	/* we now clear the interrupts on the way in ...MaTed */
+		bRxStat |= BRxDone;			// setup to clear the Done interrupt
+#endif
+		break;
+	  }
+	  /* 'skb->data' points to the start of sk_buff data area. */
+	  skb_put( skb, len);			/* update the length in the skb */
+
+      np->stats.rx_bytes += len;
+	  np->stats.rx_packets++;
+#endif
+	  enterCnt(0x202);		// ******-******* Profiling code
+	  if (NET_DEBUG > 5)
+	  {
+		printk( KERN_ERR "%s: Rx: Before: %d %d len=%d SKB=0x%p DATA=0x%p\n", 
+				dev->name, (unsigned int) ringRx->first,
+				(unsigned int) ringRx->last,
+				(unsigned int) skb->len, skb, skb->data);
+	  }
+	  if ((NET_DEBUG > 6) || DEBUG_CRC_OFF)
+	  {
+		int i,j;
+		printk( KERN_ERR "S3C2500_Rx: Length %d\n", skb->len);
+		for ( j = 0; j < (skb->len & ~ 15); j += 16)
+		{
+		  for ( i = j; i < j + 16; i += 2)
+		  {
+			printk("%04x ", 
+				   (UINT16) (skb->data[ i + 1 ] + (skb->data[ i ]<<8)));
+		  }
+		  printk("\n");
+		}
+		for ( i = (skb->len & ~ 15); i < skb->len; i += 2)
+		{
+		  printk("%04x ",
+				 (UINT16) (skb->data[ i + 1 ] + (skb->data[ i ]<<8)));
+		}
+		printk("\n");
+	  }
+	  if (DEBUG_CRC_OFF)
+		skb->len -= 4;	// drop CRC
+
+	  enterCnt(0x203);		// ******-******* Profiling code
+#if (NET_DEBUG > 3 && 0) // just to test rx maximum rate 
+	                     //   -- and overflow error ...MaTed---
+	  dev_kfree_skb_irq( skb );
+#else
+      netif_rx( skb);					// give the SKB to the kernel
+#endif
+	  skb = __dev_alloc_skb( MAX_PKT_SIZE, GFP_ATOMIC | GFP_DMA);
+	  np->rxSkb[ first ].FDskb = skb;
+	  rxFd[ first ].FDDataPtr 
+		= skb->data;			/* point to skb  data buffer */
+	  skb_reserve( skb, 2);		/* 16 bit align the IP header
+								    - original buffer is 32 bit aligned */
+#if 0	// done later -keeping empty space
+	  rxFd[ first ].FDLength = PKT_BUF_SZ;	// think the compiler is smart
+	  rxFd[ first ].FDStat = OWNERSHIP16;	//  enough to put these two lines 
+	                                        //  together??
+#endif
+	}
+
+	last = ringRx->last;		// pointer to the old spacer
+	// Mark the new frame Descriptor as not usable - spacer
+	rxFd[ first ].FDLength = 0;
+	rxFd[ first ].FDStat = 0;
+	// Advance first (on error we still advance - no purpose to resuse)
+	ringRx->last = ringRx->first;		// space of one
+	ringRx->first = incIndex( first, ringRx->max);
+
+	// The one that was the spacer is now the newest one for the BMDA engine
+	rxFd[ last ].FDLength = PKT_BUF_SZ;
+	rxFd[ last ].FDStat = OWNERSHIP16;		// last thing to do is give access
+
+#if 0	// We clear the interrupts before the while loop ...MaTed---
+	// we will turn off the bits after the do {}while ...MaTed---
+	// have to clear to get next frame receive interrupt (table 7-25.)
+	bRxStat |= BRxDone;			// setup to clear the Done interrupt
+                                //  - requires write a zero to it
+#endif
+	if (NET_DEBUG > 5)
+	{
+	  skb = np->rxSkb[ first ].FDskb;
+	  printk( KERN_ERR "%s: Rx: Bottom: %d %d len=%d first-SKB=0x%p "
+			  "first-DATA=0x%p\n", 
+			  dev->name, (unsigned int) ringRx->first,
+			  (unsigned int) ringRx->last,
+			  (unsigned int) skb->len, skb, skb->data);
+	}
+	// if there are no buffers left, we're done anyways (last one is marker)
+	if (rxFd[ ringRx->first].FDDataPtr == NULL)
+	  break;
+  }
+
+#if 0	// I'll rid of this after I verify that the above is true ...MaTed
+  // have to clear to get next receive
+  WriteCSR( BdmaStat, ReadCSR( BdmaStat) | bdmaStatus);
+#endif
+
+  /*
+   * I think we can move the following two enables up 
+   * into the error handling. Rx will only be disabled 
+   * on Not Owner (and only on RxCtl)
+   */
+  if ( !( BRxEN & (temp = ReadCSR( RxCtl))))
+	WriteCSR( RxCtl, temp  | BRxEN);
+
+#if 0	// only RxCtl gets rx disabled
+  if ( !( MRxEn & (temp = ReadCSR( MacRxCtl))))
+	WriteCSR( MacRxCtl, temp  | MRxEn);
+#endif
+	
+  spin_unlock( &priv->rxLock);		// Again do I need this ???
+  enterCnt(0x2ff);		// ******-******* Profiling code
+  return;
+}
+#if DEBUG_RX_DUMP
+/************************************************************************
+ * 	Dump Rx data structures
+ *	
+ *
+ *
+ *
+ ************************************************************************/
+static void
+dumpRx( S3C2500_MAC * priv, char * where )
+{
+  BPTR	* Rx 		= &priv->qRx;
+  BPTR	* RxWait 	= &priv->qRxWait;
+
+  printk( KERN_INFO "\n   ***** %s *****\n", where);
+  printk( KERN_INFO "** Rx first-[%p] last-[%p] num-[%ld]\n",
+		  Rx->first, Rx->last, Rx->num);
+  RXFDS_Dump( (RxFDS *) (Rx->first), "First");
+  if (Rx->first != NULL)
+	RXFDS_Dump( (RxFDS *) (((RxFDS *) (Rx->first))->fd.FDNext),
+				"First->Next");
+  RXFDS_Dump( (RxFDS *) (Rx->last), "Last");
+  if (Rx->last != NULL)
+	RXFDS_Dump( (RxFDS *) (((RxFDS *) (Rx->last))->fd.FDNext),
+				"Last->Next");
+
+  printk( KERN_INFO "** Wait first-[%p] last-[%p] num-[%ld]\n",
+		  RxWait->first, RxWait->last, RxWait->num);
+  RXFDS_Dump( (RxFDS *) (RxWait->first), "Wait First");
+  if (RxWait->first != NULL)
+	RXFDS_Dump( (RxFDS *) (((RxFDS *) (RxWait->first))->fd.FDNext),
+				"Wait First->Next");
+  RXFDS_Dump( (RxFDS *) (RxWait->last), "Wait Last");
+  if (RxWait->last !=NULL)
+	RXFDS_Dump( (RxFDS *) (((RxFDS *) (RxWait->last))->fd.FDNext),
+				"Wait Last->Next");
+  return;
+}
+/***********************************************************************
+ * Dump RxFDS Struct
+ ***********************************************************************/
+static void
+RXFDS_Dump( RxFDS * fds, char * str)
+{
+  if (fds == NULL)
+	{
+	  printk( KERN_INFO "   ---- %s NULL Address ----\n", str);
+	  return;
+	}
+  printk( KERN_INFO "  ---- %s Ptr-[%p] Next-[%p] Data-[%p] Len-[0x%x] Skb-[%p]\n",
+		  str, fds, fds->fd.FDNext, fds->fd.FDDataPtr, fds->fd.FDLength,
+		  fds->skb);
+  //  printk( KERN_INFO "  ---- SKB  HeadNext-[%p] Data-[%p] Len-[0x%x] Skb-[%p]\n",
+  return;
+}
+#endif // DEBUG_RX_DUMP
+/************************************************************************
+ * static int s3c2500_close( ND dev)
+ * Description:
+ *	- The inverse routine to net_open().
+ * Parameters:
+ *	- Pointer to network device structure - everthing resloved through 
+ *	this pointer
+ * NOTES:
+ *	- Sections have been '#if 0' out to make the open / close pairs 
+ *	work (ifconfig up / down).
+ * 	- We not only release the buffers here, we reallocate them as well.
+ *	We should move the reallocation to the open(), but that means 
+ *	straightening out more code. Since this is a core process, we have
+ *	the buffers ALWAYS allocated. 
+ ************************************************************************/
+static int
+s3c2500_close( ND dev)
+{
+  S3C2500_MAC 		* np	 	= dev->priv;
+  UINT32			chan		= np->channel;
+  UINT32			i;
+  //  int 			basePort	= dev->base_addr;
+#if 1 // debug ...MaTed
+  // RINGBUFF 	  	* ringTx 	= & np->ringTx;	// pointer to tx ring buffer
+  RINGBUFF 		* ringRx 	= & np->ringRx;	// pointer to rx ring buffer
+#endif
+  //  struct	sk_buff	* skb;
+
+#if MPROFILE		// dump miniprofile to console
+  UINT32			calcTemp;		// temp to calculate time
+#endif
+
+  netif_stop_queue( dev);
+
+  /* Flush the Tx and disable Rx here. */
+  DisableTxRx( chan );
+  DisableInt( chan );
+
+  Reset( chan );				// Reset the H/W
+  mdelay( MDELAY_RESET);	// just in case - Let ethernet MAC complete reset
+
+  // Release all TX buffers we own - please no memory leaks
+  spin_lock_irq( &np->txLock);
+  /* for all the tx frames */
+  for( i = 0; i < TX_NUM_FD; i++) 
+  {  
+	// we have to release any skb's we have
+#if !CONFIG_WBUFFER
+	if (np->txSkb[ i ].FDskb != NULL)
+    {
+	  ASSERT( atomic_read( &(np->txSkb[ i ].FDskb->users)) == 1);
+	  dev_kfree_skb( np->txSkb[ i ].FDskb );
+	  np->txSkb[ i ].FDskb = NULL;
+	}
+#else // !CONFIG_WBUFFER
+	// the Data buffers stay in FDAArea, pointers reset in SetupTxFDs() nothing
+	//	to do
+#endif // !CONFIG_WBUFFER
+  }
+  /* Reset all the tx frame descriptors */
+  SetupTxFDs( dev);
+  spin_unlock_irq( &np->TxLock);
+
+  spin_lock_irq( &np->rxLock);
+
+  if (NET_DEBUG > 4)
+  {
+	printk( " s3c2500_close: Rx First-%d Last-%d\n", 
+			ringRx->first, ringRx->last );
+  }
+
+  // Release all the Rx SKB's (we reallocate later (actually in a moment)
+  for ( i = 0; i < RX_NUM_FD ; i++)
+  {
+	if (1 && NET_DEBUG > 3)
+	{
+	  ASSERT( atomic_read( &(np->rxSkb[ i ].FDskb->users)) == 1);
+	}
+	
+	if (1 && NET_DEBUG > 3)
+	{
+	  ASSERT( np->rxSkb[ i ].FDskb->list == 0);
+	}
+	dev_kfree_skb( np->rxSkb[ i ].FDskb );
+  }
+  /* Reset all the rx frame descriptors */
+  /* Yes this would be better in the open() routine, but for now */
+  SetupRxFDs( dev );
+
+#if 0		// ...MaTed--- need later for insmod, but not yet
+  /* Release the region */
+  s3c2500_release_irq_mem( dev );
+#endif
+
+  spin_unlock_irq( &np->RxLock);
+
+#if 0		// ...MaTed--- need later for insmod, but not yet
+  /* release the priv area with the buffers and all the strcutures */
+  kfree( np);
+#endif
+
+#if MPROFILE		// dump miniprofile to console
+  printk("  Profile index = %ld\r\n", profileAddrIndex);
+  printk("index  Code  Address     Jiffie   Counter Difference Time-(83Mhz)\r\n");
+  for (i = 0; i < ProfileArraySize; i++)
+	{
+	  if (profileArray[ i ].code != 0)
+		{
+		  if ( (profileArray[ i ].code & 0xff) == 0)
+			{
+			  printk("\t\t------------------------------------------------\n");
+			}
+		  printk("%5ld, %04x, %8p, %8ld, %8ld, %8ld %10ld uS\r\n",
+				 i,
+				 profileArray[ i ].code,
+				 profileArray[ i ].addr,
+				 profileArray[ i ].jiffie,
+				 profileArray[ i ].counter,
+				 calcTemp = ( i == 0) ? profileArray [ i ].counter
+				           : profileArray[ i ].counter
+				             - profileArray[ i - 1].counter,
+#if 1	// 83 Mhz
+				 ((calcTemp * 12048)+500000) / 1000000);
+#else	// 75 MHz
+				 ((calcTemp * 13333)+500000) / 1000000);
+#endif		  
+	      mdelay(60);		// to compensate for console serial bug ...MaTed---
+		}
+	}
+  // Clear the values - just in case
+  for (i = 0; i < ProfileArraySize; i++)
+	{
+	  profileArray[ i ].code 	= 0;
+	  profileArray [ i ].addr 	= 0;
+	  profileArray [ i ].jiffie	= 0;
+	  profileArray [ i ].counter= 0;
+	}
+  profileAddrIndex = 0;
+#endif
+  return 0;
+}
+/************************************************************************
+ * Get the current statistics.
+ * This may be called with the card or closed.
+ ************************************************************************/
+static struct net_device_stats *s3c2500_get_stats( ND dev)
+{
+  S3C2500_MAC *	priv = (S3C2500_MAC *) dev->priv;
+
+  return (&priv->stats);
+}
+/************************************************************************
+ * Set or clear the multicast filter for this adaptor.
+ * num_addrs == -1	Promiscuous mode, receive all packets
+ * num_addrs == 0	Normal mode, clear multicast list
+ * num_addrs > 0	Multicast mode, receive normal and MC packets,
+ *			and do best-effort filtering.
+ ************************************************************************/
+static void
+set_multicast_list( ND dev)
+{
+  int 	baseAddr	= dev->base_addr;
+
+  WriteCSR( CamEn, 0);			// turn off ARC usage for now
+
+  if (dev->flags & IFF_PROMISC)
+  {
+    /* Enable promiscuous mode */
+    WriteCSR( CamCtl, ReadCSR( CamCtl) | MNegCAM);
+  }
+  else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > HW_MAX_ADDRS)
+  {
+    WriteCSR( CamCtl, MCompEn | MBroad | MGroup);
+  }
+  else if (dev->mc_count)
+  {
+    /* Walk the address list, and load the filter */
+    HardwareSetFilter( dev);
+    
+    WriteCSR( CamCtl, ReadCSR( CamCtl) | MBroad);
+  }
+  else // setup for normal
+  {
+    /* setup the MAC HW address */
+    SetUpARC( dev, dev->dev_addr);
+
+    WriteCSR( CamEn, 1 << 2);	    // Enable only the third entry
+    WriteCSR( CamCtl,  (MCompEn | MGroup | MBroad | MStation));
+  }
+}
+/************************************************************************
+ * HardwareSetFilter
+ ************************************************************************/
+static void HardwareSetFilter( ND dev )
+{
+  UINT	    			i 			= 0;
+  int 					baseAddr	= dev->base_addr;
+  struct dev_mc_list  *	ptr 		= dev->mc_list;
+  //  UINT32			temp;
+  //  UINT16 		  *	addrHalfPtr;
+
+  UINT32				enableMask 	= 0;
+
+  /*
+   * NOTE: this section has never been tested ...MaTed---
+   */
+  while (ptr && i < HW_MAX_ADDRS - 1)
+  {
+	if ( i & 1)
+    {	// odd entry starting at the third location 
+	  WriteCSR( Cam[ 3 + (i * 3) / 2],
+				((0x0000ffff & ReadCSR( Cam[ 3 + (i * 3) / 2] ))
+				| (ptr->dmi_addr[ 1 ] << 24 )
+				| (ptr->dmi_addr[ 0 ] << 16 )));
+	  WriteCSR( Cam[4 + (i * 3) / 2],
+				(ptr->dmi_addr[ 5 ] << 24)
+				| (ptr->dmi_addr[ 4 ] << 16)
+				| (ptr->dmi_addr[ 3 ] << 8)
+				| (ptr->dmi_addr[ 2 ]));
+	}
+	else
+	{
+	  WriteCSR( Cam[3 + (i * 3) / 2],
+				((ptr->dmi_addr[ 3 ] << 24)
+				| (ptr->dmi_addr[ 2 ] << 16)
+				| (ptr->dmi_addr[ 1 ] << 8)
+				| (ptr->dmi_addr[ 0 ])));
+	  WriteCSR( Cam[4 + (i * 3) / 2],
+				(0xffff0000 & ReadCSR( Cam[4 + (i * 3) / 2] ))
+				| (ptr->dmi_addr[ 4 ] )
+				| (ptr->dmi_addr[ 5 ] << 8));
+	}
+	enableMask |= (1 << ( i + 2 ));
+    i++;
+	ptr = ptr->next;
+  }
+  WriteCSR( CamEn, enableMask);	    // Enable all the entries
+  if (i != dev->mc_count)
+  {
+	printk("S3C2500: %s - MultiCast Count (%d) != pointers (%d)\n",
+		   dev->name, dev->mc_count, i);
+  }
+  return;
+}
+
+/*********************************************
+ * Module support
+ *********************************************/
+
+#ifdef MODULE
+// ***** NOTE: support not yet completed ...MaTed --
+
+static struct net_device this_device;
+static int io = 0x300;
+static int irq;
+static int dma;
+static int mem;
+
+int init_module(void)
+{
+  int result;
+
+  if (io == 0)
+    printk(KERN_WARNING "%s: You shouldn't use auto-probing with insmod!\n",
+	   cardname);
+
+  /* Copy the parameters from insmod into the device structure. */
+  this_device.base_addr = io;
+  this_device.irq       = irq;
+  this_device.dma       = dma;
+  this_device.mem_start = mem;
+  this_device.init      = netcard_probe;
+
+  if ((result = register_netdev(&this_device)) != 0)
+    return result;
+
+  return 0;
+}
+
+void
+cleanup_module(void)
+{
+  /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+  unregister_netdev(&this_device);
+  /*
+   * If we don't do this, we can't re-insmod it later.
+   * Release irq/dma here, when you have jumpered versions and
+   * allocate them in net_probe1().
+   */
+  /*
+    free_irq(this_device.irq, dev);
+    free_dma(this_device.dma);
+  */
+  release_mem_region(this_device.base_addr, NETCARD_IO_EXTENT);
+
+  if (this_device.priv)
+    kfree(this_device.priv);
+}
+
+#endif /* MODULE */
+
+#if DEBUG_PHY_DUMP
+/*********************************************
+ * Dump all the phy registers
+ *********************************************/
+void DumpPhyReg( UINT32 chan)
+{
+  int i;
+  UINT32	Array[4];
+
+  printk( "**** Phy register dump \n");
+  for (i=0; i<=32; i+=4)
+  {
+	(void) ReadPhy( chan, i+0, &Array[0]);
+	(void) ReadPhy( chan, i+1, &Array[1]);
+	(void) ReadPhy( chan, i+2, &Array[2]);
+	(void) ReadPhy( chan, i+3, &Array[3]);
+
+	printk(" Addr[%d], 0x%08x - 0x%08x - 0x%08x - 0x%08x\n",
+		   i, (int) Array[0], (int) Array[1], 
+		   (int) Array[2], (int) Array[3]);
+  }
+}
+#endif	//DEBUG_PHY_DUMP
+
+/*
+ * Local variables:
+ *  compile-command:
+ *	gcc -D__KERNEL__ -Wall -Wstrict-prototypes -Wwrite-strings
+ *	-Wredundant-decls -O2 -m486 -c s3c2500.c.c
+ *  version-control: t
+ *  kept-new-versions: 5
+ *  tab-width: 4
+ *  c-indent-level: 2
+ * End:
+ */
+#endif // CONFIG_ETH_S3C2500
diff -urN linux-2.4.29/drivers/net/s3c2500.h linux-2.4.29-uc1/drivers/net/s3c2500.h
--- linux-2.4.29/drivers/net/s3c2500.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/s3c2500.h	2005-06-14 02:12:15.000000000 +0100
@@ -0,0 +1,1384 @@
+/***********************************************************************/
+/*                                                                     */
+/* Samsung s3c2500x/a/b Ethernet Driver Header                         */
+/* Copyright 2002 Arcturus Networks Inc.                               */
+/*                                                                     */
+/***********************************************************************/
+/* s3c2500.h */
+/*
+ * modification history
+ * --------------------
+ *
+ * 	05/13/01 MaTed <MaTed@ArcturusNetworks.com>
+ *			- Initial port to s3c2500x using s3c4530 as base
+ *			- * Nomemclature change frame descriptors are now buffer
+ *				descriptors - there are no frame descriptors, make the
+ *				change in your mind for now
+ *			- ** NOTE: Section Numbers refer to an obsoleted version
+ *			  **       of the S3c2500X manual :-(
+ *	10/22/01 MaTed
+ *			- Initial version for linux - Samsung
+ *			- please set TABS == 4
+ *
+ */
+
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/if.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+//#include <linux/mm.h>
+//#include <asm/bootst.h>		// only for bgetenv ...MaTed---
+#include <asm/arch/irq.h>
+#include <asm/arch/hardware.h>
+#include <asm/irq.h>
+
+#if 0	// do we need this ...MaTed---
+#include <asm/addrspace.h>
+#endif
+
+/*************************
+ * Configuration
+ * FIXME: These should move up to configuration
+ *************************/
+#define CONFIG_WBUFFER	0				/* 0 => no wbuffer 
+										   => no write caching */
+#define CONFIG_ETH_DMA_PRIORITY 1		/* we will change the priority 
+										   of the DMA channels */
+#define CONFIG_DMA_PRIORITY_ROBIN 0		/* force the DMA priority type 
+										   to round-robin
+										   (0=> fixed priority */
+/****************
+ * DEBUG MACROS
+ ***************/
+/* use 0 for production, 1 for verification, > 2 for debug 	*/
+/* NOTE: NET_DEBUG must be defined ...MaTed---				*/
+#ifndef NET_DEBUG
+#define NET_DEBUG 1		// lots of debug at level 6 (highest so far is 7)
+//#define NET_DEBUG 3		// lots of debug at level 6 (highest so far is 7)
+//#define NET_DEBUG 7		// lots of debug at level 6 (highest so far is 7)
+#endif
+
+#if NET_DEBUG > 0
+// NOTE: NO panic used when in a driver - I might be in the kernel
+#define ASSERT(expr) \
+  if(!(expr)) \
+  { \
+    printk( "\n" __FILE__ ":%d: Assertion " #expr " failed!\n",__LINE__); \
+  }
+#define TDEBUG(x...) printk(KERN_DEBUG ## x)
+#else
+#define ASSERT(expr)
+#define TDEBUG(x...)
+#endif
+
+/********************
+ * Macro Definitions
+ ********************/
+#ifndef ___align16
+#define ___align16 __attribute__((__aligned__(16)))
+#endif 
+/*
+ * Setup some shorthand
+ */
+//	#define CSR  ((MAC_CSR)(dev->offset))
+
+// so we can source debug by nulling this	
+#define _INLINE_ inline
+
+// just some more shorthand
+#define ND struct net_device *
+
+/***********************
+ * Replacement Defines
+ ***********************/
+#define NUM_HW_ADDR		6		// number of bytes in ethernet HW address 
+
+/***************************************
+ * CONFIGURATION
+ ***************************************/
+// Only one of the following can be defined
+#if defined(CONFIG_BOARD_EVS3C2500RGP) || defined(CONFIG_BOARD_S3C2500REFRGP)
+#define	PHY_INTEL	1	/* define if Intel PHY - LEDs and some others 	*/
+						/*  Forces Kendin switch on primary channel		*/
+#endif
+#ifdef CONFIG_BOARD_SMDK2500
+#define	PHY_LSI		1	/* define if LSI L80225						  	*/
+#endif
+
+// If this is set, the TxPktCompletion (free's tx'd packets) will be 
+//  called at the end of the send_pkt routine instead of the Tx completion
+//  interrupt.
+// No tx Completion interrupt at end of packet, just seems to take up time
+#define NO_TX_COMP_INT	1
+
+// Have to make sure that destructor is always called and
+//  no one ever frees the skb data before I trust this
+//  would have a very hard bug to trace or replicate ...MaTed---
+// **** This is disabled because in 2.4.17, some SKBs do NOT call the
+// **** destructor routine => memory leak. Might want to turn it back
+// **** on if the problem(s) are fixed -- should be MORE efficient than
+// **** repeatedly deleting and creating SKB's
+#undef ZERO_COPY_BUFFER
+
+// IOCTL setup not fully implemented, just some routines
+#undef ENABLE_IOCTL
+
+/***********************************
+ *
+ * S3c2500 Memory configuration defines
+ *
+ ***********************************/
+#if  (L1_CACHE_BYTES == 32)
+#define L1_CACHE_SHIFT 5
+#elif (L1_CACHE_BYTES == 16)
+  #define L1_CACHE_SHIFT 4
+  #else
+    **************** BAD L1 CACHE LINE not 16 or 32 ***********
+#endif
+
+/***********************************
+ *
+ * S3c2500 Ethernet MAC Configuration
+ *
+ ***********************************/
+#define HW_MAX_CAM		((32 * 4) / NUM_HW_ADDR)	/* number of entries 
+													   in CAM for address	*/
+#define HW_MAX_ADDRS	HW_MAX_CAM - 5		// maximum usable ARC entries
+											//  0, 1 and 18 reserved
+											// we ignore 19 and 20
+#define ETH_MAXUNITS	2		// number of ethernet channels
+#define ETH_MIN_LEN		64		// minimum length to xmit is 64
+								//  Verify OK for all protocols
+/* * * *  Tunable defines * * * */
+/**** NOTE: Next 2 parameters must be power of 2 ****/
+/****       Must match with SET_BRxNBD 			 ****/
+#define RX_NUM_FD		128		// Max number of receive frames to set up
+								// (HARD MAX)
+/**** See SET_BTxNBD for matching value (power of 2) ...MaTed--- ****/
+#if NO_TX_COMP_INT
+#define TX_NUM_FD		64		// Maximum number of transmit frames to set up
+#else
+#define TX_NUM_FD		64		// Maximum number of transmit frames to set up
+#endif
+/* The number of low I/O ports used by the ethercard.????...MaTed---????? */
+#define MY_TX_TIMEOUT  ((400*HZ)/1000)
+#define MDELAY_RESET	500		// Set for 1/2 Sec - needs checking to shorten
+
+/*********************
+ * Error Return Codes
+ *********************/
+typedef int					RET_CODE;
+
+#define	S3C2500_SUCCESS		0		// function call was successful
+#define S3C2500_FAIL		-1		// general error code
+#define S3C2500_TIMEOUT		-1000	// timeout error
+
+/**********************
+ * S3C2500 Buffer Sizes
+ **********************/
+#define MAX_PKT_SIZE	1536	// bigger than need be ? (but 3x512)
+//#define MAX_FRAME_SIZE	MAX_PKT_SIZE - 4 // controller is four less
+//#define MAX_FRAME_SIZE	1522
+
+// Realize that this is bigger than needs to be - does this cause a problem?
+//   Yes for MTU generation ??? Force 1514 ...MaTed---
+//  -- the upper layers break down tx stuff, rx?? ...MaTed---
+//#define PKT_BUF_SZ  	MAX_PKT_SIZE - 22	// Size of each Rx buffer
+#define PKT_BUF_SZ  	1520	// Size of each Rx buffer
+
+/* Reserve all the stuff - nothing between used (each adapter has this 
+ *  size from the base address of the ...MaTed--- */
+#define MAC_IO_EXTENT	(0xB00FC - 0xA0000)
+
+/****************
+ * EXTERNS
+ ****************/
+
+
+/*********************************************************************
+ * typedefs
+ * - wish these were predefined somewhere else ...MaTed---
+ *********************************************************************/
+typedef unsigned int	UINT;
+typedef	unsigned long	ULONG;
+typedef unsigned long	UINT32;
+typedef unsigned short	UINT16;
+typedef unsigned char	UINT8;
+typedef	unsigned char	UCHAR;
+
+/***************************************************
+ *  Ethernet MAC Base address and interrupt vectors
+ ***************************************************/
+// Each Mac has Two interrupts
+#define ETH0_TX_IRQ		SRC_IRQ_ETH_TX0	/* TX IRQ for ETHERNET 0			*/
+#define ETH0_RX_IRQ		SRC_IRQ_ETH_RX0	/* RX IRQ for ETHERNET 0			*/
+#define ETH1_TX_IRQ		SRC_IRQ_ETH_TX1	/* TX IRQ for ETHERNET 1			*/
+#define ETH1_RX_IRQ		SRC_IRQ_ETH_RX1	/* RX IRQ for ETHERNET 1			*/
+
+/***********************************************
+ * Misc Addresses
+ ***********************************************/
+#if 0
+#define	WriteBufferEn	0x04	/* Write Buffer enable bit mask				*/
+#endif
+
+/*********************************************************
+ * Interrupt Controller (we ignore External ints for now)
+ *********************************************************/
+#define INTMOD		0xF0140000	// Internal interrupt mode register
+                                //  Setting a bit => FIQ mode
+#define INTMSK      0xF0140008	// Interrupt Mask 
+
+#define INTPND      (SRB_BASE+0x4004)
+
+// Interrupt Priority registers (16.4.3)
+#define INTPRI0     0xF0140020
+#define INTPRI1     0xF0140024
+#define INTPRI2     0xF0140028
+#define INTPRI3     0xF014002C
+#define INTPRI4     0xF0140030
+#define INTPRI5     0xF0140034
+#define INTPRI6     0xF0140038
+#define INTPRI7     0xF014003C
+#define INTPRI8     0xF0140040
+#define INTPRI9     0xF0140044
+
+#define INTOFFSET   0xF014001C
+// Returns valuse for highest priorty int pending (0x15->0x18 for Ethernet)
+#define INTOSET_FIQ 0xF0140018
+#define INTOSET_IRQ 0xF014001C
+
+/***********************************************
+ * Ethernet BDMA Register Address
+ ***********************************************/
+#define BDMATXCON	0x0000		/* Buffered DMA Transmit Control			*/
+#define BDMARXCON	0x0004		/* Buffered DMA Receive Control				*/
+#define BDMATXDPTR	0x0008		/* BDMA Transmit Frame Descriptor Start
+								   Address									*/
+#define BDMARXDPTR	0x000C		/* BDMA Receive Frame Descriptor Start
+								   Address									*/
+#define BTXBDCNT	0x0010		/* BDMA Tx buffer descriptor counter		*/
+#define BRXBDCNT	0x0014		/* BDMA Rx buffer descriptor counter		*/
+#define BMTXINTEN	0x0018		/* BDMA/MAC Tx Interrupt enable
+								   register						  			*/
+#define BMRXINTEN	0x001C		/* BDMA/MAC Rx Interrupt enable
+								   register									*/
+#define BMTXSTAT	0x0020		/* BDMA/MAC Tx Status register				*/
+#define BMRXSTAT	0x0024		/* BDMA/MAC Rx Status register				*/
+#define BDMARXLEN  	0x0028		/* BDMA Receive frame Size					*/
+#define CFTXSTAT	0x0030		/* Transmit control frame status			*/
+/***********************************************
+ * Ethernet MAC Register Address
+ ***********************************************/
+#define MACCON		0x10000		/* MAC control								*/
+#define CAMCON		0x10004		/* CAM control								*/
+#define MACTXCON    0x10008		/* Transmit control							*/
+#define MACTXSTAT   0x1000C		/* Transmit status							*/
+#define MACRXCON    0x10010		/* Receive control							*/
+#define MACRXSTAT   0x10014		/* Receive status							*/
+#define STADATA		0x10018		/* Station management data					*/
+#define STACON		0x1001C		/* Station management control and 
+								   address									*/
+#define CAMEN		0x10028		/* CAM enable								*/
+#define MISSCNT		0x1003C		/* Missed error count						*/
+#define PZCNT		0x10040		/* Pause count								*/
+#define RMPZCNT		0x10044		/* Remote pause count						*/
+#define CAM     	0x10080		/* CAM content 32 words 0080-00fc			*/
+/***********************************************
+ * Ethernet MAC Register Offsets
+ ***********************************************/
+#define ETH0OFF		0xF00A0000	/* Offsetset for register - Ethernet 0		*/
+#define ETH1OFF		0xF00C0000	/* Offsetset for register - Ethernet 1		*/
+
+/*********************************************************
+ * Buffered DMA Transmit Control Register Masks (7.5.1.1)
+ * BDMATXCON - offset 0x0000
+ *********************************************************/
+#define BTxNBD		0x000f	/* BDMA Tx # of Buffer Descriptors (Power 
+							   of 2)										*/
+#define BTxMSL		0x0070	/* BDMA Tx Start Level							*/
+#define BTxEN		0x0400	/* BDMA Tx enable NOTE: BDMATXDPTR set 1st		*/
+#define BTxRS		0x0800	/* BDMA Tx reset - set to '1' to reset Tx		*/
+
+#if NO_TX_COMP_INT
+#define SET_BTxNBD	6		/*  - 64 TX Frames Descriptors
+								  - Must match with TX_NUM_FD 				*/
+#else
+#define SET_BTxNBD	6		/*  - 64 TX Frames Descriptors
+								  - Must match with TX_NUM_FD 				*/
+#endif
+//#define SET_BTxMSL	0x0070	/* 7/8 fill BDMA Tx Start Level				*/
+//#define SET_BTxMSL	0x0060	/* 6/8 fill BDMA Tx Start Level				*/
+#define SET_BTxMSL	0x0020	/* 2/8 fill BDMA Tx Start Level				*/
+//#define SET_BTxMSL	0x0000	/* No wait Tx Start Level					*/
+
+#define BTxSetup	(SET_BTxNBD | SET_BTxMSL)
+
+/*********************************************************
+ * Buffered DMA Receive Control Register (7-.5.1.2)
+ * BDMARXCON - offset 0x0004
+ *********************************************************/
+#define BRxNBD		0x000f	/* BDMA Rx # of Buffer Descriptors (Power 
+							   of 2) - 128									*/
+#define BRxWA		0x0030	/* BDMA Rx word alignment (0->3 bytes)			*/
+#define BRxEN		0x0400	/* BDMA Rx Enable, BDMARXDPTR must be set		*/
+#define BRxRS		0x0800	/* BDMA Rx reset - set to '1' to reset Tx		*/
+
+#define SET_BRxNBD	7		/* - 128 Rx Frames Descriptors
+								 - Must match with RX_NUM_FD */
+
+#define SET_BRxWA	0x0020	/* Set for 2 byte alignment, LINUX TCP/IP stack */
+
+/*  RxAlign                     bits 4 to 5   */
+#define BRxAlignSkip0	(0x00<<4)	/* Do not skip any bytes on rx			*/
+#define BRxAlignSkip1	(0x01<<4)	/* Skip 1st byte on rx					*/
+#define BRxAlignSkip2	(0x02<<4)	/* Skip 2nd byte on rx					*/
+#define BRxAlignSkip3	(0x03<<4)	/* Skip 3rd byte on rx					*/
+
+#define	BRxSetup_RESET	(SET_BRxNBD | BRxAlignSkip2 )
+
+#if 0 // previous setups from 4530 code
+#define BRxSetup	(BRxBurstSize | BRxSTSKO | BRxMAINC | BRxDIE |
+					 BRxNLIE | BRxNOIE | BRxMSOIE | BRxLittle |
+					 BRxAlignSkip2 | BRxEN | BRxEmpty )
+#define BRxSetup	(BRxBurstSize | BRxSTSKO | BRxMAINC | BRxDIE | \
+					 BRxNLIE | BRxNOIE | BRxLittle | \
+					 BRxAlignSkip2 | BRxEN )
+#endif
+/*********************************************************
+ * BDMA Transmit Buffer Descriptor Start Address (7.5.1.3)
+ * BDMATXDPTR - offset 0x0008
+ *********************************************************/
+
+/*********************************************************
+ * BDMA Receive Buffer Descriptor Start Address (7.5.1.4)
+ * BDMARXDPTR - offset 0x000C
+ *********************************************************/
+
+/*********************************************************
+ * BDMA Transmit Buffer Counter (7.5.1.5)
+ * BTXBDCNT - offset 0x0010
+ *********************************************************/
+#define BDMATXCNT	0x0fff	/* BDMA Tx buffer descriptor Counter,
+							   Current address = BDMATXDPTR 
+							   + (BTXBDCNT << 3)							*/
+/*********************************************************
+ * BDMA Receive Buffer Counter (7.5.1.6)
+ * BRXBDCNT - offset 0x0014
+ *********************************************************/
+#define BDMARXCNT	0x0fff	/* BDMA Rx buffer descriptor Counter,
+							   Current address = BDMARXDPTR 
+							   + (BRXBDCNT << 3)							*/
+/*********************************************************
+ * BDMA/MAC Transmit Interrupt Enable (7.5.1.7)
+ * BMTXINTEN - offset 0x0018
+ *********************************************************/
+#define ExCollIE	0x0001	/* Enable MAC Tx excessive collision-ExColl		*/
+#define UnderflowIE	0x0002	/* Enable MAC Tx underflow-Underflow 		 	*/
+#define DeferErrIE	0x0004	/* Enable MAC Tx deferral-DeferErr			 	*/
+#define NoCarrIE	0x0008	/* Enable MAC Tx no carrier-NoCarr				*/
+#define LateCollIE	0x0010	/* Enable MAC Tx late collision-LateColl		*/
+#define TxParErrIE	0x0020	/* Enable MAC Tx transmit parity-TxParErr		*/
+#define TxCompIE	0x0040	/* Enable MAC Tx completion-TxComp				*/
+#define TxCFcompIE	0x10000	/* Tx complete to send control frame 
+							   interrupt enable-TxCFcomp					*/
+#define BTxNOIE		0x20000	/* BDMA Tx not owner interrupt enable-BTxNO		*/
+#define BTxEmptyIE	0x40000	/* BDMA Tx Buffer empty interrupt enable
+							   -BTxEmpty									*/
+#if NO_TX_COMP_INT
+#define TxINTMask	(ExCollIE | UnderflowIE | DeferErrIE | NoCarrIE \
+                     | LateCollIE | TxParErrIE | TxCFcompIE)
+	 /*
+                     | LateCollIE | TxParErrIE | TxCFcompIE \
+                     | BTxNOIE | BTxEmptyIE)
+	 */
+#else
+#define TxINTMask	(ExCollIE | UnderflowIE | DeferErrIE | NoCarrIE \
+                     | LateCollIE | TxParErrIE | TxCompIE | TxCFcompIE \
+                     | BTxNOIE | BTxEmptyIE) 
+#endif
+/*********************************************************
+ * BDMA/MAC Transmit Interrupt Status (7.5.1.8)
+ * BDTXSTAT - offset 0x0020
+ *********************************************************/
+#define ExColl		0x0001	/* MAC Tx excessive collision-ExColl			*/
+#define Underflow	0x0002	/* MAC Tx underflow-Underflow 		 			*/
+#define DeferErr	0x0004	/* MAC Tx deferral-DeferErr			 			*/
+#define NoCarr		0x0008	/* MAC Tx no carrier-NoCarr						*/
+#define LateColl	0x0010	/* MAC Tx late collision-LateColl				*/
+#define TxParErr	0x0020	/* MAC Tx transmit parity-TxParErr				*/
+#define TxComp		0x0040	/* MAC Tx completion-TxComp						*/
+#define TxCFcomp	0x10000	/* Tx complete to send control frame-TxCFcomp	*/
+#define BTxNO		0x20000	/* BDMA Tx not owner-BTxNO						*/
+#define BTxEmpty	0x40000	/* BDMA Tx Buffer empty-BTxEmpty				*/
+
+/*********************************************************
+ * BDMA/MAC Receive Interrupt Enable (7.5.1.9)
+ * BDRXINTIE - offset 0x001C
+ *********************************************************/
+#define MissRollIE	0x0001	/* MAC Rx missed roll-MissRoll 			 		*/
+#define AlignErrIE	0x0002	/* MAC Rx alignment-AlignErr					*/
+#define CRCErrIE	0x0004	/* MAC Rx CRC error-CRCErr						*/
+#define OverflowIE	0x0008	/* MAC Rx overflow-Overflow						*/
+#define LongErrIE	0x0010	/* MAC Rx long error-LongErr					*/
+#define RxParErrIE	0x0020	/* MAC Rx receive parity-RxParErr				*/
+#define BRxDoneIE	0x10000	/* BDMA Rx done for every received 
+							   frames-BRxDone								*/
+#define BRxNOIE		0x20000	/* BDMA Rx not owner interrupt-BRxNO			*/
+#define BRxMSOIE	0x40000	/* BDMA Rx maximum size over interrupt
+							   -BRxMSO										*/
+#define BRxFullIE	0x80000	/* BDMA Rx buffer(BRxBUFF) Overflow 
+							   Interrupt-BRxFull							*/
+#define BRxEarlyIE	0x100000	/* BDMA Rx early notification 
+								   interrupt-BRxEarly						*/
+#if 0	// don't want to handle all these ...MaTed---
+	    // - most will done by the frame having the status bit set in the
+	    // status section of the RX Frame descriptor
+#define RxINTMask	(MissRollIE | AlignErrIE | CRCErrIE | OverflowIE \
+                    | LongErrIE | RxParErrIE | BRxNOIE | BRxDoneIE \
+                    | BRxMSOIE | BRxFullIE | BRxEarlyIE) 
+#else
+#define RxINTMask	( MissRollIE | BRxNOIE | BRxDoneIE ) 
+#endif
+/*********************************************************
+ * BDMA/MAC Receive Interrupt Status (7.5.1.10)
+ * BDRXSTAT - offset 0x0024
+ *********************************************************/
+#define MissRoll	0x0001	/* MAC Rx missed roll-MissRoll 			 		*/
+#define AlignErr	0x0002	/* MAC Rx alignment-AlignErr					*/
+#define CRCErr		0x0004	/* MAC Rx CRC error-CRCErr						*/
+#define Overflow	0x0008	/* MAC Rx overflow-Overflow						*/
+#define LongErr		0x0010	/* MAC Rx long error-LongErr					*/
+#define RxParErr	0x0020	/* MAC Rx receive parity-RxParErr				*/
+#define BRxDone		0x10000	/* BDMA Rx done for every received 
+							   frames-BRxDone								*/
+#define BRxNO		0x20000	/* BDMA Rx not owner interrupt-BRxNO			*/
+#define BRxMSO		0x40000	/* BDMA Rx maximum size over interrupt
+							   -BRxMSO										*/
+#define BRxFull		0x80000	/* BDMA Rx buffer(BRxBUFF) Overflow 
+							   Interrupt-BRxFull							*/
+#define BRxEarly	0x100000	/* BDMA Rx early notification 
+								   interrupt-BRxEarly						*/
+#define BRxFRF		0x200000	/* An additional data frame is received
+								   in the BDMA receive buffer				*/
+#define BRxBUFF		0x7c00000	/* Number of frames in BRxBUFF				*/
+
+/*********************************************************
+ * BDMA Receive Frame Size (7.5.1.11)
+ * BDRXSTAT - offset 0x0028
+ *********************************************************/
+#define BRxBS	0x00000FFF	/* This register value specifies the buffer
+							   size allocated to each buffer descriptor.
+							   Thus, for an incoming frame larger than
+							   the BRxBS, multiple buffer descriptors
+							   are used for the frame reception.
+							   Note: BRxBS value has to keep multiples
+							   of 16 in byte unit. For long packet 
+							   reception larger than 1518 bytes, the 
+							   BRxBS should be at least 4 bytes larger 
+							   than the BRxMFS or less than 1518 bytes.		*/
+#define BRxMFS	0x0FFF0000	/* BDMA Maximum Rx Frame Size (BRxMFS) This 
+							   register value controls how many bytes 
+							   per frame can be saved to memory. If 
+							   the received frame size exceeds these 
+							   values, an error condition is reported.
+							   Note: BRxMFS value has to keep multiples 
+							   of 16 in byte unit							*/
+
+/*********************************************************
+ * MAC Transmit Control Frame Status (7.5.2.1)
+ * The transmit control frame status register, CFTXSTAT provides
+ * the status of a MAC control frame as it is sent to a remote station.
+ * This operation is controlled by the MSdPause bit in the transmit 
+ * control register, MACTXCON. It is the responsibility of the BDMA 
+ * engine to read this register and to generate an interrupt to notify
+ * the system that the transmission of a MAC control packet has been
+ * completed.
+ * CFTXSTAT - offset 0x0030
+ *********************************************************/
+#define MACCTLTXSTAT	0xFFFF	/* A 16-bit value indicating the status of
+								   a MAC control packet as it is sent to a 
+								   remote station. Read by the BDMA engine.	*/
+
+/*********************************************************
+ * MAC Control Register  (7.5.2.2)
+ * The MAC control register provides global control and status 
+ * information for the MAC. The missed roll/link10 bit is a status 
+ * bit. All other bits are MAC control bits. MAC control register 
+ * settings affect both transmission and reception. After a reset 
+ * is complete, the MAC controller clears the reset bit. Not all
+ * PHYs support full-duplex operation. (Setting the MAC loopback
+ * bit overrides the full-duplex bit.) Also, some 10-Mb/s PHYs may
+ * interpret the loop10 bit to control different functions, and
+ * manipulate the link10 bit to indicate a different status condition.
+ * MACCON - offset 0x10000
+ *********************************************************/
+#define MHaltReq	0x0001	/* Halt request (MHaltReq) Set this bit to
+							   stop data frame transmission and
+							   reception as soon as Tx/Rx of any current
+							   frames has been completed					*/
+#define MHaltImm	0x0002	/* Halt immediate (MHaltImm) Set this bit
+							   to immediately stop all transmission
+							   and reception 								*/
+#define MReset		0x0004	/*  Software reset (MReset) Set this bit
+								to reset all MAC control and status
+								register and MAC state machines. This
+								bit is automatically cleared				*/
+#define MFullDup	0x0008	/*  Full-duplex Set this bit to start
+								transmission while reception is in
+								progress									*/
+#define MLoopBack	0x0010	/*  MAC loopback (MLoopBack) Set this bit
+								to cause transmission signals to be
+								presented as input to the receive
+								circuit without leaving the controller		*/
+#define MMIIOFF		0x0040	/*  MII-OFF Use this bit to select the
+								connection mode. If this bit is set to
+								one, 10 M bits/s interface will select
+								the 10 M bits/s endec. Otherwise, the
+								MII will be selected						*/
+#define MLOOP10		0x0080	/*  Loop 10 Mb/s (MLOOP10) If this bit is
+								set, the Loop_10 external signal is
+								asserted to the 10-Mb/s endec				*/
+#define MMDCOFF		0x1000	/* MDC-OFF Clear this bit to enable the MDC
+							   clock generation for power management. If
+							   it is set to one, the MDC clock
+							   generation is disabled						*/
+#define MLINK10		0x8000	/*  Link status 10 Mb/s (MLINK10),
+								read-only This bit value is read as a
+								buffered signal on the link 10 pin.			*/
+
+#define MCtlReset_BUSY_LOOP	100 /* Number of loops to wait for MReset bit	*/
+#define MCtlSETUP	(MFullDup)
+#define MCtlFullDupShift	3
+/*********************************************************
+ * CAM Control Register (7.5.2.3
+ *	CAMCON - offset 0x0x10004
+ *********************************************************/
+#define MStation	0x0001	/* Station accept (MStation) Set this bit
+							   to accept unicast (i.e. station) frames  	*/
+#define MGroup		0x0002	/* Group accept (MGroup) Set this bit to 
+							   accept multicast (i.e. group) frames. 		*/
+#define MBroad		0x0004	/* Broadcast accept (MBroad) Set this bit to
+							   accept broadcast frames. 					*/
+#define MNegCAM		0x0008	/* Negative CAM (MNegCAM) Set this bit to
+							   enable the Negative CAM comparison mode. 	*/
+#define MCompEn		0x0010	/* Compare enable (MCompEn) Set this bit to
+							   enable the CAM comparison mode.				*/
+#define CAMCtlSETUP     (MStation | MGroup | MBroad | MCompEn)
+
+/*********************************************************
+ * MAC Transmit Control Register (7.5.2.4)
+ * MACTXCON - offset 0x10008
+ *********************************************************/
+#define MTxEn		0x0001	/* Transmit enable (MTxEn) Set this bit to 
+							   enable transmission. To stop transmission 
+							   immediately, clear the transmit enable
+							   bit to  0									*/
+#define MTxHalt		0x0002	/* Transmit halt request (MTxHalt) Set this
+							   bit to halt the transmission after
+							   completing the transmission of any
+							   current frame								*/
+#define MNoPad		0x0004	/* Suppress padding (MNoPad) Set this bit
+							   not to generate pad bytes for frames of 
+							   less than 64 bytes							*/
+#define MNoCRC		0x0008	/* Suppress CRC (MNoCRC) Set this bit to 
+							   suppress addition of a CRC at the end of 
+							   a frame.										*/
+#define MFBack		0x0010	/* Fast back-off (MFBack) Set this bit to 
+							   use faster back-off times for testing 		*/
+#define MNoDef		0x0020	/* No defer (MNoDef) Set this bit to disable
+							   the defer counter. (The defer counter 
+							   keeps counting until the carrier sense 
+							   (CrS) bit is turned off.						*/
+#define MSdPause	0x0040	/* Send Pause (MSdPause) Set this bit to 
+							   send a pause command or other MAC control 
+							   frame. The send pause bit is 
+							   automatically cleared when a complete MAC 
+							   control frame has been transmitted. 
+							   Writing a  0  to this register bit has 
+							   no effect									*/
+#define MSQEn		0x0080	/* MII 10-Mb/s SQE test mode enable (MSQEn)
+							   Set this bit to enable MII 10-Mb/s SQE
+							   test mode									*/
+
+#define MTxCtlSetup (0)		/* None of these on								*/
+
+/*********************************************************
+ * MAC Transmit Status Register (7.5.2.5)
+ * A transmission status flag is set in the transmit status
+ * register, MACTXSTAT, whenever the corresponding event
+ * occurs. In addition, an interrupt is generated if the
+ * corresponding enable bit in the transmit control register
+ * is set. A MAC TxFIFO parity error sets TxParErr, and also
+ * clears MTxEn, if the interrupt is enabled.
+ * MACTXSTAT - offset 0x1000C
+ *********************************************************/
+#define MACTXERR	0x00ff	/*  These bits are equivalent to the
+								BMTXSTAT.7~0								*/
+#define MCollCnt	0x0f00	/* Transmission collision count (MCollCnt)
+							   This 4-bit value is the count of 
+							   collisions that occurred while 
+							   successfully transmitting the frame			*/
+#define MTxDefer	0x1000	/* Transmission deferred (MTxDefer) This
+							   bit is set if transmission of a frame 
+							   was deferred because of a delay during
+							   transmission									*/
+#define SQEErr		0x2000	/* Signal quality error (SQEErr) According
+							   to the IEEE802.3 specification, the SQE
+							   signal reports the status of the PMA (MAU
+							   or transceiver) operation to the MAC
+							   layer. After transmission is complete and
+							   1.6 ms has elapsed, a collision detection
+							   signal is issued for 1.5 ms to the MAC
+							   layer. This signal is called the SQE test
+							   signal. The MAC sets this bit if this
+							   signal is not reported within the IFG
+							   time of 6.4ms 								*/
+#define MTxHalted	0x4000	/* Transmission halted (MTxHalted) This bit
+							   is set if the MTxEn bit is cleared or the
+							   MHaltImm bit is set							*/
+#define MPaused		0x8000	/* Paused (MPaused) This bit is set if
+							   transmission of frame was delayed due to
+							   a Pause being received						*/
+#define MCollShift	0x08	/* Amount to shift collisions */
+/*********************************************************
+ * MAC Receive Control Register (7.5.2.6)
+ * MACRXCON - offset 0x10010
+ *********************************************************/
+#define MRxEn		0x0001	/* Receive enable (MRxEn) Set this bit to
+							   1  to enable MAC receive operation. If
+							   0 , stop reception immediately				*/
+#define MRxHalt		0x0002	/* Receive halt request (MRxHalt) Set
+							   this bit to halt reception after
+							   completing the reception of any
+							   current frame								*/
+#define MLongEn		0x0004	/* Long enable (MLongEn) Set this bit to
+							   receive frames with lengths greater
+							   than 1518 bytes								*/
+#define MShortEn	0x0008	/* Short enable (MShortEn) Set this bit
+							   to receive frames with lengths less
+							   than 64 bytes								*/
+#define MStripCRC	0x0010	/* Strip CRC value (MStripCRC) Set this
+							   bit to check the CRC, and then strip
+							   it from the message							*/
+#define MPassCtl	0x0020	/* Pass control frame (MPassCtl) Set this
+							   bit to enable the passing of control
+							   frames to a MAC client						*/
+#define MIgnoreCRC	0x0040	/* Ignore CRC value (MIgnoreCRC) Set this
+							   bit to disable CRC value checking			*/
+
+// From usage- we enable rx interrupts later ...MaTed---
+#define MRxCtlSETUP             (MRxEn | MStripCRC )
+
+/*********************************************************
+ * MAC Receive Status Register (7.5.2.7)
+ * MACRXSTAT - offset 0x10014
+ *********************************************************/
+#define MACRXERR	0x00ff	/* These bits are equal to the BMRXSTAT.7~		*/
+#define MRxShort	0x0100	/* Short Frame Error (MRxShort) This bit is
+							   set if the frame was received with short
+							   frame										*/
+#define MRx10Stat	0x0200	/* Receive 10-Mb/s status (MRx10Stat) This
+							   bit is set to  1  if the frame was
+							   received over the 7-wire interface or to
+							   0  if the frame was received over the MII	*/
+#define MRxHalted	0x0400	/* Reception halted (MRxHalted) This bit is
+							   set if the MRxEn bit is cleared or the
+							   MHaltImm bit is set							*/
+#define MCtlRecd	0x0800	/* Control frame received (MCtlRecd) This
+							   bit is set if the frame received is a
+							   MAC control frame (type = 0x8808), if the
+							   CAM recognizes the frame address, and if
+							   the frame length is 64 bytes					*/
+
+/*********************************************************
+ * MAC Station Management Data Register (7.5.2.8)
+ * STADATA - offset 0x10018
+ *********************************************************/
+#define STAMANDATA	0xffff	/* This register contains a 16-bit data
+							   value for the station management
+							   function.									*/
+
+/*********************************************************
+ * MAC Station Management Data Control and Address Register 
+ *		(7.5.2.9)
+ * The MAC controller provides support for reading and
+ * writing3 station management data to the PHY. Setting
+ * options in station management registers does not
+ * affect the controller. Some PHYs may not support the
+ * option to suppress preambles after the first operation.
+ * STACON - offset 0x1001c
+ *********************************************************/
+#define MPHYRegAddr	0x001F	/* PHY register address (MPHYRegAddr) A
+							   5-bit address, contained in the PHY,
+							   of the register to be read or written		*/
+					// RGP boards have Intel PHY at address 0
+#if defined(CONFIG_BOARD_EVS3C2500RGP) || defined(CONFIG_BOARD_S3C2500REFRGP)
+#define MPHYHWADDR0	0x00 	/* PHY H/W Address 0x1							*/
+#define MPHYHWADDR1	0x00 	/* PHY H/W Address 0x2							*/
+#endif
+#ifdef CONFIG_BOARD_SMDK2500	// SMDK has LSI PHYs at strappable addresses
+#define MPHYHWADDR0	0x20 	/* PHY H/W Address 0x1							*/
+#define MPHYHWADDR1	0x40 	/* PHY H/W Address 0x2							*/
+#endif
+#define MPHYaddr	0x03E0	/* PHY address (MPHYaddr) The 5-bit
+							   address of the PHY device to be read
+							   or written									*/
+#define MPHYwrite	0x0400	/* Write (MPHYwrite) To initiate a write
+							   operation, set this bit to  1 . For a
+							   read operation, clear it to  0 				*/
+#define MPHYbusy	0x0800	/* Busy bit (MPHYbusy) To start a read or
+							   write operation, set this bit to 1.
+							   The MAC controller clears the Busy bit
+							   automatically when the operation is
+							   completed								   	*/
+#define MPreSup		0x1000	/* Preamble suppress (MPreSup) If you set
+							   this bit, the preamble is not sent to
+							   the PHY. If it is clear, the preamble
+							   is sent										*/
+#define MMDCrate	0xE000	/* MDC clock rate (MMDCrate) Controls the
+							   MDC period. The default value is `011.
+							   MDC period = MMDCrate ´ 4 + 32 Example)
+							   MMDCrate = 011,
+							   MDC period = 44 x (1/system clock			*/
+
+/*********************************************************
+ * CAM Enable Register (7.5.2.10)
+ * CAMEN - offset 0x10028
+ *********************************************************/
+#define CAMENBIT	0x1fffff	/* Set the bits in this 21-bit value to
+								   selectively enable CAM locations 20
+								   through 0. To disable a CAM location,
+								   clear the appropriate bit.	   			*/
+
+/*********************************************************
+ * MAC Missed Error Count Register (7.5.2.11)
+ * The value in the missed error count register, MISSCNT,
+ * indicates the number of frames that were discarded due
+ * to various type of errors. Together with status
+ * information on frames transmitted and received, the
+ * missed error count register and the two pause count
+ * registers provide the information required for station
+ * management. Reading the missed error counter register
+ * clears the register. It is then the responsibility of
+ * software to maintain a global count with more bits of
+ * precision. The counter rolls over from 0x7FFF to 0x8000
+ * and sets the corresponding bit in the MAC control
+ * register. It also generates an interrupt if the
+ * corresponding interrupt enable bit is set. If station
+ * management software wants more frequent interrupts,
+ * you can set the missed error count register to a value
+ * closer to the rollover value of 0x7FFF. For example,
+ * setting a register to 0x7F00 would generate an
+ * interrupt when the count value reaches 256 occurrences.
+ * MISSCNTT - offset 0x1003C
+ *********************************************************/
+#define MissErrCnt	0xFFFF	/* (MissErrCnt) The number of valid
+							   packets rejected by the MAC unit
+							   because of MAC RxFIFO overflows,
+							   parity errors, or because the MRxEn
+							   bit was cleared. This count does not
+							   include the number of packets
+							   rejected by the CAM.							*/
+
+/*********************************************************
+ * MAC Received Pause Count Register (7.5.2.12)
+ * The received pause count register, PZCNT, stores the
+ * current value of the 16-bit received pause counter.
+ * MISSCNT - offset 0x10040
+ *********************************************************/
+#define MACPCNT		0xFFFF	/* The count value indicates the number of
+							   time slots the transmitter was paused
+							   due to the receipt of control pause
+							   operation frames from the MAC.				*/
+
+/*********************************************************
+ * MAC Remote Pause Count Register (7.5.2.13)
+ *	RMPZCNT  - offset 0x10044
+ *********************************************************/
+#define MACRMPZCNT	0xFFFF	/* The count value indicates the number
+							   of time slots that a remote MAC was
+							   paused as a result of its sending
+							   control pause operation frames.				*/
+
+/*********************************************************
+ * Content Addressable Memory (CAM) Register (7.5.2.14)
+ * CAM - offset 0x10080 ~ 0x100FC
+ *********************************************************/
+#define CAMVAL	0xFFFFFFFF	/* The CPU uses the CAM content register as
+							   data for destination address. To activate
+							   the CAM function, you must set the
+							   appropriate enable bits in CAM enable
+							   register.									*/
+/**************************************************/
+
+/**********************************************
+ * Structure Definitions
+ **********************************************/
+/* Combined BDMA and MAC Registers for S3c2500 */
+typedef struct
+{
+  volatile UINT32 TxCtl;	/* 0x00 Buffered DMA transmit control reg		*/
+  volatile UINT32 RxCtl;	/* 0x04 Buffered DMA receive control reg		*/
+  volatile UINT32 TxPtr;	/* 0x08 Tx frame descriptor start addr			*/
+  volatile UINT32 RxPtr;	/* 0x0c Rx frame descriptor start addr			*/
+  volatile UINT32 TxCnt;	/* 0x10 BDMA Tx buffer descriptor counter		*/
+  volatile UINT32 RxCnt;	/* 0x14 BDMA Rx buffer descriptor counter 		*/
+  volatile UINT32 TxIntEn;	/* 0x18 BDMA/MAC Tx Interrupt enable
+							   register 									*/
+  volatile UINT32 RxIntEn;	/* 0x1c BDMA/MAC Rx Interrupt enable
+							   register 									*/
+  volatile UINT32 TxStat;	/* 0x20 BDMA/MAC Tx Status register				*/
+  volatile UINT32 RxStat;	/* 0x24 BDMA/MAC Rx Status register				*/
+  volatile UINT32 RxSz;		/* 0x28 Receive Frame Size						*/
+  volatile UINT32 TxCf;		/* 0x30 Transmit control frame status			*/
+  UINT8  reserve1 [0xffd0];	/* spacer to next 64KB block					*/
+  volatile UINT32 MacCtl;	/* 0x10000 MAC Control							*/
+  volatile UINT32 CamCtl;	/* 0x10004 CAM Control							*/
+  volatile UINT32 MacTxCtl;	/* 0x10008 MAC Tx Control						*/
+  volatile UINT32 MacTxStat;/* 0x1000c MAC Tx Status						*/
+  volatile UINT32 MacRxCtl;	/* 0x10010 MAC Rx Control					   	*/
+  volatile UINT32 MacRxStat;/* 0x10014 MAC Rx Status						*/
+  volatile UINT32 SmData;	/* 0x10018 Station Management Data				*/
+  volatile UINT32 SmCtl;	/* 0x1001c Station Management Control 
+							   and address									*/
+  UINT8 reserve2 [8];		/* spacer										*/
+  volatile UINT32 CamEn;	/* 0x10028 CAM Enable							*/
+  UINT8 reserve3 [16];		/* spacer										*/
+  volatile UINT32 MissCnt;	/* 0x1003c Missed Error Count					*/
+  volatile UINT32 PauseCnt;	/* 0x10040 Received Pause command Count	*/
+  volatile UINT32 RemPauseCnt; /* 0x10044 Remote Pause Cnt (we sent 
+								  PAUSE)									*/
+  UINT8 reserve4 [0x38];	/* spacer										*/
+  volatile UINT32 Cam[60];	/* 0x10080 -> 0x100fc, CAM Content Only 1st
+							   21*6 bytes used								*/
+} CSR;
+
+/**********************************************************
+ * Frame Descriptor, Buffer Descriptor related parameters.
+ **********************************************************/
+
+#define	OWNERSHIP	0x80000000	/* bit set for BDMA owns FD					*/
+#define OWNERSHIP16	0x8000		/* bit set for BDMA owns FD - 16 bit access */
+#if 0
+#define RELOAD		0x10000		/* bit set tells addRxSKBs to allocate new
+								   skb - only set when an error occurred
+								   NOTE that we get to reuse the stat only
+								   because we KNOW that bottom two bits of
+								   16 bit are always 2 (FOR US ONLY) 		*/
+#define RELOAD16	0x0001		/* 16 bit access							*/
+#endif // 0 Will remove after checking manual
+/*****************************
+ * Rx Descriptor Control Bits
+ *****************************/
+#define SKIPBD	0x40000000	/* Set to skip this Buffer Descriptor when 
+							   ownership is cleared							*/
+#define SOFR	0x20000000	/* Set by BDMA to indicate Start of Frame 		*/
+#define EOFR	0x10000000	/* Set by BDMA to indicate End of Frame			*/
+#define DONEFR	0x08000000	/* Set by BDMA on the first BD when the
+							   reception of a frame finished and it
+							   used multiple BD's. 							*/
+/*****************************
+ * Rx Descriptor Status Bits
+ *****************************/
+             /* SET IF ....									*/
+#define RxS_OvMax	0x0400		/* Over Maximum Size (BRxMFS)				*/
+#define RxS_Halted	0x0200		/* The reception of next frame is
+								   halted when MACCON.1 (MHaltImm)
+								   is set, or when MACRXCON.0
+								   (MRxEn) is clear.						*/
+#define RxS_Rx10	0x0100		/* Packet rx'd on 7 wire interface
+								   -reset -> rx'd on MII					*/
+#define RxS_Done	0x0080		/* The reception process by the BDMA
+								   is done.									*/
+#define RxS_RxPar	0x0040		/* MAC rx FIFO detected parity error		*/
+#define RxS_MUFS	0x0020		/* Set when the size of the Rx frame is
+							       larger than the Maximum Untagged Frame
+							       Size(1518bytes) if the long packet is
+							       not enabled in the MAC Rx control
+							       register.								*/
+#define RxS_OFlow	0x0010		/* MAC rx FIFO was full when byte rx'd		*/
+#define RxS_CrcErr	0x0008		/* CRC error OR PHY asserted Rx_er			*/
+#define RxS_AlignErr	0x0004	/* Frame length != mutliple of 8 bits
+								   and the CRC was invalid					*/
+
+
+#define lRxS_OvMax	0x04000000	/* Over Maximum Size (BRxMFS)				*/
+#define lRxS_Halted	0x02000000	/* The reception of next frame is
+								   halted when MACCON.1 (MHaltImm)
+								   is set, or when MACRXCON.0
+								   (MRxEn) is clear.						*/
+#define lRxS_Rx10	0x01000000	/* Packet rx'd on 7 wire interface
+								   -reset -> rx'd on MII					*/
+#define lRxS_Done	0x00800000	/* The reception process by the BDMA
+								   is done.									*/
+#define lRxS_RxPar	0x00400000	/* MAC rx FIFO detected parity error		*/
+#define lRxS_MUFS	0x00200000	/* Set when the size of the Rx frame is
+								   larger than the Maximum Untagged Frame
+								   Size(1518bytes) if the long packet is
+								   not enabled in the MAC Rx control
+								   register.								*/
+#define lRxS_OFlow	0x00100000	/* MAC rx FIFO was full when byte rx'd		*/
+#define lRxS_CrcErr	0x00080000	/* CRC error OR PHY asserted Rx_er			*/
+#define lRxS_AlignErr	0x00040000	/* Frame length != mutliple of 8 bits
+									   and the CRC was invalid				*/
+
+/*****************************
+ * Tx Descriptor Status Bits
+ * - read only status bits
+ *****************************/
+#define TxS_Paused	0x2000		/* transmission paused due to the
+								   reception of a Pause control frame		*/
+#define TxS_Halted	0x1000		/* The transmission of the next frame
+								   is halted when MACCON.1 (MHaltImm)
+								   is set, or when MACTXCON.0 (MTxEn)
+								   is clear.								*/
+#define TxS_SQErr	0x0800		/* SQE error								*/
+#define TxS_Defer	0x0400		/* transmission deferred					*/
+#define TxS_Coll	0x0200		/* The collision is occured in
+								   half-duplex. The current frame will 
+								   be retried								*/
+#define TxS_Comp	0x0100		/* tx complete or discarded 				*/
+#define TxS_Par		0x0080		/* tx FIFO parity error 					*/
+#define TxS_LateColl	0x0040	/* tx coll after 512 bit times 				*/
+#define TxS_NCarr	0x0020		/* carrier sense not detected 				*/
+#define TxS_MaxDefer	0x0010	/* tx defered for max_defer (24284-bit
+								  times). Frame aborted						*/
+#define TxS_Under	0x0008		/* tx (FIFO) underrun 						*/
+#define TxS_ExColl	0x0004		/* 16 collisions occured, aborted			*/
+
+
+#define lTxS_Paused	0x20000000	/* transmission paused due to the
+								   reception of a Pause control frame		*/
+#define lTxS_Halted	0x10000000	/* The transmission of the next frame
+								   is halted when MACCON.1 (MHaltImm)
+								   is set, or when MACTXCON.0 (MTxEn)
+								   is clear.								*/
+#define lTxS_SQErr	0x08000000	/* SQE error								*/
+#define lTxS_Defer	0x04000000	/* transmission deferred					*/
+#define lTxS_Coll	0x02000000	/* The collision is occured in
+								   half-duplex. The current frame will 
+								   be retried								*/
+#define lTxS_Comp	0x01000000	/* tx complete or discarded 				*/
+#define lTxS_Par	0x00800000	/* tx FIFO parity error 					*/
+#define lTxS_LateColl	0x00400000	/* tx coll after 512 bit times 			*/
+#define lTxS_NCarr	0x00200000	/* carrier sense not detected 				*/
+#define lTxS_MaxDefer	0x00100000	/* tx defered for max_defer (24284-bit
+								   times). Frame aborted					*/
+#define lTxS_Under	0x00080000	/* tx (FIFO) underrun 						*/
+#define lTxS_ExColl	0x00040000	/* 16 collisions occured, aborted			*/
+
+/*****************************
+ * Tx Widget Bits
+ *****************************/
+#define TxWidALIGN	0x00030000	/* Alignment of the buffer					*/
+#define TxWidSetup	0x00020000	/* two byte offset							*/
+#define TxWidSet16	0x0002		/* two byte offset							*/
+
+/*****************************
+ * Tx Descriptor Length Bits
+ *****************************/
+#define TxLEN		0x0000FFFF	/* Tx Length 								*/
+
+/*****************************************************************
+ * PHYS defines
+ *****************************************************************/
+/**********************************************
+ * PHY - LX972 / L80225 register and defines
+ *    -NOTE references from intel documentation
+ **********************************************/
+
+//#define	PHYAddr			0x00001		/* Address of the PHY on the SMDK2500 	*/
+/******* registers *********/
+#define PHYCtl		0 	// Control Register Refer to Table 37 on page 58 
+#define PHYStat		1	// Status Register #1 Refer to Table 38 on page 58
+#define	PHYId1		2 	// PHY Identification Register 1 Refer to Table 39
+                        //	on page 59
+#define PHYId2		3	// PHY Identification Register 2 Refer to 
+						//	Table 40 on page 60
+#define PHYANegAd	4	// Auto-Negotiation Advertisement Register
+                        //	Refer to Table 41 on page 61
+#define PHYANegLink	5	// Auto-Negotiation Link Partner Base Page Ability 
+					    //	Register Refer to Table 42 on page 62
+#ifdef PHY_INTEL
+#define PHYANegEx	6	// Auto-Negotiation Expansion Register Refer to 
+					    //	Table 43 on page 63
+#define PHYANegNext 7	// Auto-Negotiation Next Page Transmit Register
+					    //	Refer to Table 44 on page 63
+#define PHYANegLPart 8 	// Auto-Negotiation Link Partner Received Next Page
+					    //	Register Refer to Table 45 on page 64
+#define PHY100Ctl	9 	// 1000BASE-T/100BASE-T2 Control Register Not 
+					    //	Implemented
+#define PHY100Stat	10	// 1000BASE-T/100BASE-T2 Status Register Not 
+					    //	Implemented
+#define PHYExStat	15	// Extended Status Register Not Implemented
+#define	PHYPortCfg	16 	//	Port Configuration Register Refer to Table 
+					    //	46 on page 64
+#define PHYStat2	17	// Status Register #2 Refer to Table 47 on page 65
+
+#define PHYIntEn	18	// Interrupt Enable Register Refer to Table 48 
+						//	on page 66
+#define PHYIntStat	19	// Interrupt Status Register Refer to Table 49
+						//	on page 66
+#define	PHYLedCfg	20	// LED Configuration Register Refer to Table 50
+						//	on page 68
+		// 21- 29 Reserved
+#define	PHYTxCtl	30 	// Transmit Control Register Refer to Table 51
+						//	on page 69
+#endif
+#ifdef PHY_LSI
+#define PHYStat2	18	// Phy Status - Duplex and speed
+#endif
+/*** Only some of the defines - ones I used ...MaTed ***/
+#define PHY10MSDELAY	10		// should be 10 for 10 MS delay...FIXME
+                                //  but I think the mdelay routine is wrong
+#define	PHYCtlReset		0x8000	// reset
+#define PHYANegAdMask	0x1e0	// bits for duplex and speed (972)
+#define PHYB8			0x100	// bit 8
+#define PHYB7			0x080	// bit 7
+#define PHYB6			0x040	// bit 6
+#define PHYB5			0x020	// bit 5
+#if 0	// testing leds
+#define	PHYLEDCFG		0xA8F2	// LED 1 (left - blink fast
+								//     2 (right - ON
+#else
+// NOTES: leds are wired reverse from HEI
+# if 0
+#define	PHYLEDCFG		0x0DF2	// LED 1 (left - link and activity
+								//     2 (right - Speed)
+# else
+#define	PHYLEDCFG		0xD0F2	// LED 1 (right - Speed)
+								//     2 (left - link and activity
+# endif
+#endif
+#define	PHYLEDANEG		0x1e1	// Advertize AutoNeg all speed / duplex
+
+#define PHY_BUSYLOOP_COUNT	100	// each loop is 10mS -> 1S
+#define PHY_RESETLOOP_COUNT	10	// number of times to check reset 
+							    //  10 ms between checks - manual
+								//  states 300 uS max fro reset to work
+#define	PHY_NEGLOOP_COUNT	150	// 1.5 seconds for Autoneg to complete
+
+#define PHY_RESET		0x8000
+/**** Following are from previous version of the PHY routines -- delete ***/
+#ifdef PHY_INTEL
+#define PHY_LINK_UP		0x0400
+#define PHYMODE_100		0x4000 /* for 100 mbps								*/
+#define PHYFULL_DUPLEX	0x0200
+
+#define SPEED_AUTO		0xFFFFFF9F	/* Set the MAC speed to Automatic mode.
+									   AND operation 						*/
+#define SPEED_10		0xFFFFFFBF	/* Set the MAC speed to Automatic mode.
+									   OR operation 						*/
+#endif
+
+#define PHY_10MBS       1
+#define PHY_100MBS      2
+#define PHY_AUTO_SPEED  0
+
+// These don't really match up
+#define PHY_FULL_DPX    1
+#define PHY_HALF_DPX    0
+#define PHY_AUTO_DPX    2
+
+/**********************************
+ * Bit Defines for PHY972_CONTROL
+ **********************************/
+#define PHY_CONTROL_RESET           0x8000
+#define PHY_CONTROL_LOOPBACK        0x4000
+#define PHY_CONTROL_SELECT_SPEED    0x2000
+#define PHY_CONTROL_AUTONEG			0x1000
+#define PHY_CONTROL_POWERDOWN       0x0800
+#define PHY_CONTROL_ISOLATE         0x0400
+#define PHY_CONTROL_RESTART_AUTONEG 0x0200
+#define PHY_CONTROL_DUPLEXMODE      0x0100
+#define PHY_CONTROL_COLLISION_TEST  0x0080
+#define PHY_CONTROL_SPEED_10_HALF   0x0000
+#define PHY_CONTROL_SPEED_10_FULL   (PHY_CONTROL_DUPLEXMODE)
+#define PHY_CONTROL_SPEED_100_HALF  (PHY_CONTROL_SELECT_SPEED )
+#define PHY_CONTROL_SPEED_100_FULL  (PHY_CONTROL_SELECT_SPEED \
+			                            | PHY_CONTROL_DUPLEXMODE)
+#define PHY_CONTROL_AUTONEG_HALF_10	(0x1000 | PHY_CONTROL_RESTART_AUTONEG)
+#define PHY_CONTROL_AUTONEG_FULL_10	(0X1100 | PHY_CONTROL_RESTART_AUTONEG)
+#define PHY_CONTROL_AUTONEG_HALF_100	(0x3000 | PHY_CONTROL_RESTART_AUTONEG)
+#define PHY_CONTROL_AUTONEG_FULL_100	(0X3100 | PHY_CONTROL_RESTART_AUTONEG)
+ 
+/*****************************************
+ * Bit Defines for PHY972_STATUS_REG_ONE
+ *****************************************/
+    /* not used                            0x8000  */
+#ifdef	PHY_INTEL
+#define PHY_STATUS_REG_TWO_MODE_100             0x4000
+#define PHY_STATUS_REG_TWO_TX_STATUS            0x2000
+#define PHY_STATUS_REG_TWO_RX_STATUS            0x1000
+#define PHY_STATUS_REG_TWO_COLLISION_STATUS     0x0800
+#define PHY_STATUS_REG_TWO_LINK                 0x0400
+#define PHY_STATUS_REG_TWO_DUPLEX_MODE          0x0200
+#define PHY_STATUS_REG_TWO_AUTO_NEGOTIATION     0x0100
+#define PHY_STATUS_REG_TWO_AUTO_NEGO_COMPELETE  0x0080
+    /* not used                                 0x0040  */
+#define PHY_STATUS_REG_TWO_POLARITY             0x0020
+#define PHY_STATUS_REG_TWO_PAUSE                0x0010
+#define PHY_STATUS_REG_TWO_ERROR                0x0008
+    /* not used                                 0x0004  */
+    /* not used                                 0x0002  */
+    /* not used                                 0x0001  */
+#endif
+#ifdef	PHY_LSI
+#define PHY_STATUS_REG_LINK                 	0x0004
+#define PHY_STATUS_REG_TWO_MODE_100             0x0080
+#define PHY_STATUS_REG_TWO_DUPLEX_MODE          0x0040
+#endif
+
+/*******************************************
+ * redefinition for merged status 
+ *******************************************/
+#ifdef PHY_LSI
+#define PHY_STATUS_LINK_UP	PHY_STATUS_REG_LINK		// mask for determinig if
+                                                    //  link up
+#define PHY_STATUS_LINK_100	PHY_STATUS_REG_TWO_MODE_100	// mask for 100 Mbs
+#define PHY_STATUS_LINK_DUPLEX	PHY_STATUS_REG_TWO_DUPLEX_MODE	// mask for
+                                                                // full duplex
+#endif
+#ifdef PHY_INTEL
+#define PHY_STATUS_LINK_UP	PHY_LINK_UP		// mask for determining if
+                                            //  link up
+#define PHY_STATUS_LINK_100	PHYMODE_100		// mask for 100 Mbs
+#define PHY_STATUS_LINK_DUPLEX	PHYFULL_DUPLEX	// mask for full duplex
+#endif
+
+/*********************************************************************
+ +---------------+---------------+---------------+---------------+
+  Byte 3          Byte 2          Byte 1          Byte 0
+ +---------------+---------------+---------------+---------------+
+                        RX FRAME DESCRIPTOR
+ +---------------------------------------------------------------+
+ |                          Buffer Pointer	    		         |0x00
+ +---------+---------------------+-------------------------------+
+ |  Flags  |      Status         |                               |
+ |O B S E D|M H 1 D P U O C A - -|	          Frame Length       |0x04
+ +-+-+-+-+-+---------------------+-------------------------------+
+  3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+      FLAGS
+ 	O - Ownership 1->BDMA, 0->CPU
+   B - Skip BD 
+   S - SOF - First BD for a frame
+   S - EOF - Last BD for a frame
+   D - Done (set on first BD when frame finished)
+      Status
+   M - MSO - bigger than max size
+   H - Halted
+   1 - Rx'd over 10 Mbps interface
+   D - BRxDone
+   U - Parity Error
+   O - Overflow in FIFO
+   C - CRC error
+   A - Alignment error
+
+                        TX FRAME DESCRIPTOR
+ +---------------------------------------------------------------+
+ |                          Buffer Pointer	    		         |0x00
+ +---------------------------+---+-------------------------------+
+ |            Status         |   |                               |
+ |O - - H Q D C F P L N E U X|Wid|	          Tx Length          |0x04
+ +-+-+-+-+-+---------------------+-------------------------------+
+  3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+      Status
+ 	O - Ownership 1->BDMA, 0->CPU
+   H - Halted
+   Q - SQEErr - Signal Quality Error
+   D - Defer - Transmission of the frame was deferred
+   C - Coll - Collision occurred in half-duplex - will be retried
+   F - Finished - The transmission has Completed
+   P - ParErr - Parity error in FIFO
+   L - Late Coll - The collision occurred after 64 byte times
+   N - NoCarr - No Carrier Sense was detected during MAC Tx
+   E - DeferErr - Frame aborted - deferred 24284-bit times
+   U - Underflow - FIFO underflow
+   X - ExColl - Frame aborted - 16 consecutive collisions
+      Widget
+   Wid - Transmission alignment - number of bytes
+
+*******************************************************************/
+
+/***********************************************
+ * RX Frame Descriptors for Ethernet MAC of S3c2500
+ * - this structure needs to be accessed as
+ * uncached memory.
+ ***********************************************/
+typedef struct _RxFD
+{
+  volatile	UCHAR *		FDDataPtr;
+  volatile	UINT16      FDLength;
+  volatile	UINT16		FDStat;		// Ownership, Flags and Status
+} RxFD;
+
+/************************************************
+ * RX Frame Control
+ * - parallels RxFD structure to keep data in it.
+ *   I.E. same index as RxFD
+ * - just keeps the SKB
+ * - total structure must be word multiple
+ * *FIXME: get rid of of the structure definition
+ * *FIXME:  it just adds another layer ...MaTed
+ ************************************************/
+typedef struct _RxFrCtl
+{
+  struct sk_buff * FDskb;		/* the skb handles are preallocated uncached
+								   skb's. Always keep an entry here 		*/
+}RxFrCtl;
+/***********************************************
+ * TX Frame Descriptors for Ethernet MAC of S3c2500
+ * - this structure needs to be accessed as
+ * uncached memory.
+ ***********************************************/
+typedef struct _TxFD
+{
+  volatile	UCHAR	*FDDataPtr;	// Pointer to data to be tx'd
+  volatile	UINT16	FDLength;	// Length of the Data
+  volatile	UINT16	FDStat;		// Ownership, Status and Widget
+} TxFD;
+
+/************************************************
+ * TX Frame Buffer
+ * - parallels TxFD structure  to keep data in it.
+ *   I.E. same index for both
+ * - these buffers need to be in uncached memory
+ * - total structure must be word multiple
+ ************************************************/
+typedef struct _TxBUFF
+{
+#if CONFIG_WBUFFER
+  UCHAR	FDData[ MAX_PKT_SIZE];	/* must be word multiple the first 2 bytes
+								   are filler which gives the upper protocol
+								   layers aligned access to the header. The 
+								   BDMA engine needs the Data buffer aligned
+								   on a word boundary (so we just tell the
+								   BDMA to skip the first 2 bytes */
+#else
+  struct sk_buff * FDskb;		/* the skb handles are saved so we can
+								   free them after the controller has
+								   finished sending the skb data 		*/
+#endif // CONFIG_WBUFFER
+} TxBUFF;
+
+/**********************
+ * Control structures
+ **********************/
+/********************************
+ * Simple Ring Buffer Struct
+ * - Should check if UINT16 better than UINT32 in code generation ...MaTed---
+ ********************************/
+typedef struct _RINGBUFF
+{
+  UINT16	first;	// indexfirst in the linked list (first empty)
+  UINT16	last;	// last in the linked list (last used)
+  UINT16	num;	// number of elements in the linked list
+                    //  mostly for stats, full and empty detection
+  UINT16	max;	// Maximum index of elements in the ring
+} RINGBUFF;
+  
+/**********************************************************
+ * PRIV structure
+ * Information that need to be kept for each MAC / board
+ *  Use net_device.priv to keep pointer to this struct
+ **********************************************************/
+typedef struct
+{  /* MAC specific information */
+   /*
+   * configuration parameters,
+   * - user can override later in /proc?? (still have to do this)
+   */
+  UINT8		phySpeed;		// 00-Auto, 0x1-10 Mbs, 0x2-100Mbs, 0x3-Auto
+  UINT8		phyDpx;			// duplex 00-Half, 0x1-Full (not valid with??)
+  UINT16	tcbTxThresh;	// Transmit Threshold for fifo dma xfer
+
+  /*
+   * Keep track of Negotiated speeds
+   */
+  UINT8		phySpeedNeg;	// 0x1-10 Mbs, 0x2-100Mbs
+  UINT8		phyDpxNeg;		// duplex 00-Half, 0x1-Full
+  /*
+   * Keep track of which controller this structure applies to
+   * - for the 2500 it is either 0 or 1
+   */
+  UINT32	channel;
+
+  /* Tx control lock.  This protects the transmit buffer ring
+   * state along with the "tx full" state of the driver.  This
+   * means all netif_queue flow control actions are protected
+   * by this lock as well.
+   */
+  spinlock_t	txLock;
+
+  /* Rx control lock.  This protects the receive buffer ring
+   * state of the driver.
+   * NOTE: we might not need this - check ...MaTed---
+   */
+  spinlock_t	rxLock;
+
+  /*
+   * Need a storage place to save which SKB destructor routine to use
+   */
+  void (*destructor)(struct sk_buff *);   /* Destruct function */
+/************************************************************************
+ * For Receive and Transmit, S3c2500 Buffer Control Structure.		*
+ * Each Structre points to it own buffer space and contains interface   *
+ * related information. The structre contains the link list for the     *
+ * buffer.                                                              *
+ ************************************************************************/
+  /*
+   * Queue control into data structures to S3C2500 MAC
+   */
+  RINGBUFF	ringRx;	// Receive Frame Descriptor ring buffer pointers
+  RINGBUFF	ringTx;	// Transmit Frame Descriptor ring buffer pointers
+
+  /*
+   * Pointers to Data structures to communicate with S3C2500 MAC
+   * NOTE: these structures must be accessed uncached
+   */
+  RxFD	*	rxFd;		// Pointer to receive frame descriptors
+  TxFD	*	txFd;		// Pointer to transmit frame descriptors
+
+  /*
+   * Arrays of skb pointers which keep Data associated with S3c2500 frame
+   *	descriptors.
+   */
+  RxFrCtl	rxSkb[ RX_NUM_FD];	// Pointer to array of receive buffers
+#if !CONFIG_WBUFFER		// Skb's if no WBUFF, Uncached Buffers if WBUFF
+  TxBUFF 	txSkb[ TX_NUM_FD];	// Pointer to array of transmit skb pointer
+#endif // !CONFIG_WBUFFER
+  /*
+   * Statistics 
+   */
+  struct net_device_stats	stats;		// standard statistics
+  struct
+  {
+	UINT32	BRxNl;	// BDMARxPtr has null list
+	UINT32	BRxNo;	// BDMA rx is not the owner of the current data frame
+					//	pointed to. Rx is stopped
+	UINT32	BTxCp;	// BDMA tx indicates MAC sent a control packet
+	UINT32	BTxNl;	// BDMATxPtr has a null list
+	UINT32	BTxNo;	// BDMA tx is not the owner of the current data frame
+					//	pointed to. Tx is stopped
+  } bdmaStats;
+} S3C2500_MAC;
+
+/********************************************************************
+ * Prototypes for external routines
+ ********************************************************************/
+extern void enable_samsung_irq( int int_num);
+extern void disable_samsung_irq( int int_num);
+//extern inline void invalidate_dcache_line( unsigned long addr);
+extern unsigned char * get_MAC_address( char * name);
+//extern int get_ethernet_addr( char * ethaddr_name, char *ethernet_addr);
+//extern int s3c_flush_cache_region( void * start_addr, unsigned int size);
+//extern int s3c_invalidate_cache( void * start_address, unsigned int length);
+
+extern int ask_s3c2500_uncache_region( void * start_addr, unsigned int size,
+									  unsigned int flag);
diff -urN linux-2.4.29/drivers/net/s3c4510.c linux-2.4.29-uc1/drivers/net/s3c4510.c
--- linux-2.4.29/drivers/net/s3c4510.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/s3c4510.c	2005-06-14 02:12:15.000000000 +0100
@@ -0,0 +1,557 @@
+/*
+ * linux/deriver/net/s3c4510.c
+ * Ethernet driver for Samsung 4510B
+ * Copyright (C) 2002 Mac Wang <mac@os.nctu.edu.tw>
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>       // printk()
+#include <linux/slab.h>		// kmalloc()
+#include <linux/errno.h>	// error codes
+#include <linux/types.h>	// size_t
+#include <linux/interrupt.h>	// mark_bh
+
+#include <linux/in.h>
+#include <linux/netdevice.h>    // net_device
+#include <linux/etherdevice.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+
+#include <asm/irq.h>
+#include "s3c4510.h"
+
+#undef DEBUG
+#ifdef	DEBUG
+#define TRACE(str, args...)	printk("S3C4510 eth: " str, ## args)
+#else
+#define TRACE(str, args...)
+#endif
+
+
+static int timeout = 100;	// tx watchdog ticks 100 = 1s
+static char *version = "Samsung S3C4510 Ethernet driver version 0.1 (2002-02-20) <mac@os.nctu.edu.tw>\n";
+
+/*
+ * This structure is private to each device. It is used to pass
+ * packets in and out, so there is place for a packet
+ */
+struct s3c4510_priv {
+	struct net_device_stats stats;
+
+	unsigned long tx_ptr;
+	unsigned long gtx_ptr;
+	unsigned long rx_ptr;
+
+	// Frame Descriptor linked list for S3C4510 MAC, initialized by FD_init()
+	volatile struct FrameDesc rx_fd[RX_FRAME_SIZE];
+	volatile struct FrameDesc tx_fd[TX_FRAME_SIZE];
+
+	// Frame Buffer for S3C4510 MAC
+	volatile struct ethframe  rx_buf[RX_FRAME_SIZE];
+	volatile struct ethframe  tx_buf[TX_FRAME_SIZE];
+	
+	spinlock_t lock;
+
+	struct sk_buff *skb;
+};
+
+/* --------------------- *
+ * MII support functions *
+ * --------------------- */
+void MIIWrite(unsigned long PhyInAddr, unsigned long PhyAddr, unsigned long PhyData)
+{
+	CSR_WRITE(STADATA, PhyData);
+	CSR_WRITE(STACON, PhyInAddr | PhyAddr | MiiBusy | PHYREGWRITE);
+	while(CSR_READ(STACON) & MiiBusy);
+}
+
+unsigned long MIIRead(unsigned long PhyInAddr, unsigned long PhyAddr)
+{
+	CSR_WRITE(STACON, PhyInAddr | PhyAddr | MiiBusy);
+	while(CSR_READ(STACON) & MiiBusy);
+	return CSR_READ(STADATA);
+}
+
+/*
+ *
+ */
+void FD_Init(struct net_device *dev)
+{
+	struct s3c4510_priv *priv = (struct s3c4510_priv *) dev->priv;
+
+	struct FrameDesc *FD_ptr;
+	struct FrameDesc *FD_start_ptr;
+	struct FrameDesc *FD_last_ptr = NULL;
+	unsigned long FB_base;
+	unsigned long i;
+
+	// TxFDInitialize() in diag code
+	// Get Frame descriptor's base address
+	// +0x4000000 is for setting this area to non-cacheable area.
+	CSR_WRITE(BDMATXPTR, (unsigned long) priv->tx_fd + 0x4000000);
+	priv->gtx_ptr = priv->tx_ptr = CSR_READ(BDMATXPTR);
+
+	// Get Transmit buffer base address.
+	FB_base = (unsigned long) priv->tx_buf + 0x4000000;
+
+	// Generate linked list.
+	FD_start_ptr = FD_ptr = (struct FrameDesc *)priv->tx_ptr;
+	FD_last_ptr = NULL;
+
+	for(i = 0; i < TX_FRAME_SIZE; i++) {
+		if(FD_last_ptr == NULL)
+			FD_last_ptr = FD_ptr;
+		else
+			FD_last_ptr -> NextFrameDescriptor = (unsigned long)FD_ptr;
+
+		FD_ptr->FrameDataPtr = (unsigned long)(FB_base & CPU_owner);
+		FD_ptr->Reserved = 0;
+		FD_ptr->StatusAndFrameLength = (unsigned long)0x0;
+		FD_last_ptr = FD_ptr;
+		FD_ptr++;
+		FB_base += sizeof(struct ethframe);
+	}
+
+	//Make Frame descriptor to ring buffer type.
+	FD_last_ptr->NextFrameDescriptor = (unsigned long)FD_start_ptr;
+
+	// RxFDInitialize() in diag code
+	// Get Frame descriptor's base address
+	CSR_WRITE(BDMARXPTR, (unsigned long) priv->rx_fd + 0x4000000);
+	priv->rx_ptr = CSR_READ(BDMARXPTR);
+
+	// Get Transmit buffer base address
+	FB_base = (unsigned long)priv->rx_buf + 0x4000000;
+
+	// Generate linked list
+	FD_start_ptr = FD_ptr = (struct FrameDesc *)priv->rx_ptr;
+	FD_last_ptr = NULL;
+
+	for(i = 0; i < RX_FRAME_SIZE; i++) {
+		if(FD_last_ptr == NULL )
+			FD_last_ptr = FD_ptr;
+		else
+			FD_last_ptr -> NextFrameDescriptor = (unsigned long)FD_ptr;
+
+		FD_ptr->FrameDataPtr = (unsigned long)(FB_base | BDMA_owner);
+		FD_ptr->Reserved = 0;
+		FD_ptr->StatusAndFrameLength = (unsigned long)0x0;
+		FD_ptr->NextFrameDescriptor = 0x0;
+
+		FD_last_ptr = FD_ptr;
+		FD_ptr++;
+		FB_base += sizeof(struct ethframe);
+	}   
+
+	// Make Frame descriptor to ring buffer type.
+	FD_last_ptr->NextFrameDescriptor = (unsigned long)FD_start_ptr;
+}
+
+
+/*
+ * rx
+ */
+void s3c4510_rx(int irq, void *dev_id, struct pt_regs *regs)
+{
+//	int i;
+	int len;
+	unsigned char *data;
+	struct sk_buff *skb;
+	struct FrameDesc *FD_ptr;
+	unsigned long CFD_ptr;
+	unsigned long RxStat;
+	unsigned long BDMAStat;
+	struct net_device *dev = (struct net_device *) dev_id;
+	struct s3c4510_priv *priv = (struct s3c4510_priv *) dev->priv;
+	TRACE("rx\n");
+
+	spin_lock(&priv->lock);
+
+	// 1. Get current frame descriptor and status
+	CFD_ptr = CSR_READ(BDMARXPTR);
+	BDMAStat = CSR_READ(BDMASTAT);
+
+	// 2. Clear BDMA status register bit by write 1
+	CSR_WRITE(BDMASTAT, BDMAStat | S_BRxRDF);
+
+	do {
+		// 3. Check Null List Interrupt
+		/*
+		if(CSR_READ(BDMASTAT) & BRxNL) {
+			CSR_WRITE(BDMASTAT, );
+		}
+		*/
+
+		// 4. Get Rx Frame Descriptor
+		FD_ptr = (struct FrameDesc *) priv->rx_ptr;
+		RxStat = (FD_ptr->StatusAndFrameLength >> 16) & 0xffff;
+		
+		// 5. If Rx frame is good, then process received frame
+		if(RxStat & Good){
+			len = (FD_ptr->StatusAndFrameLength & 0xffff) - 4;
+			data = (unsigned char *) FD_ptr->FrameDataPtr + 2;
+
+			// 6. Get received frame to memory buffer
+			skb = dev_alloc_skb(len+2);
+			if(!skb) {
+				printk("S3C4510 eth: low on mem - packet dropped\n");
+				priv->stats.rx_dropped++;
+				return;
+			}
+//			memcpy(skb_put(skb, len), data, len);
+/*
+			printk("len: %d\n", len);
+			for(i = 0; i < len; i++)
+			{
+				printk("%3x", data[i]);
+				if((i+1)%16==0)
+					printk("\n");
+			}
+			printk("\n");
+*/
+			skb->dev = dev;
+			skb_reserve(skb, 2);
+			skb_put(skb, len);
+			eth_copy_and_sum(skb, data, len, 0);
+			skb->protocol = eth_type_trans(skb, dev);
+			priv->stats.rx_packets++;
+			priv->stats.rx_bytes += len;
+			netif_rx(skb);
+		}
+		else {
+			// 7. If Rx frame has error, then process err frame
+			priv->stats.rx_errors++;
+			if(RxStat & LongErr)
+				priv->stats.rx_length_errors++;
+			if(RxStat & OvMax)
+				priv->stats.rx_over_errors++;
+			if(RxStat & CRCErr)
+				priv->stats.rx_crc_errors++;
+			if(RxStat & AlignErr)
+				priv->stats.rx_frame_errors++;
+			if(RxStat & Overflow)
+				priv->stats.rx_fifo_errors++;
+			
+		}
+		// 8. Change ownership to BDMA for next use
+		FD_ptr -> FrameDataPtr |= BDMA_owner;
+
+		// Save Current Status and Frame Length field, and clear
+		FD_ptr -> StatusAndFrameLength = 0x0;
+
+		// 9. Get Next Frame Descriptor pointer to process
+		priv->rx_ptr = (unsigned long)(FD_ptr -> NextFrameDescriptor);
+	}while(CFD_ptr != priv->rx_ptr);
+
+	// 10. Check Notowner status
+	if(CSR_READ(BDMASTAT) & S_BRxNO) {
+		CSR_WRITE(BDMASTAT, S_BRxNO);
+	}
+		
+	spin_unlock(&priv->lock);
+}
+
+/*
+ * tx
+ */
+void s3c4510_tx(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct FrameDesc *FD_ptr;
+	unsigned long CFD_ptr;
+	unsigned long *FB_ptr;
+	unsigned long status;
+	struct net_device *dev = (struct net_device *) dev_id;
+	struct s3c4510_priv *priv = (struct s3c4510_priv *) dev->priv;
+	TRACE("tx\n");
+
+	spin_lock(&priv->lock);
+
+	CFD_ptr = CSR_READ(BDMATXPTR);
+	while(priv->gtx_ptr != CFD_ptr)
+	{
+		FD_ptr = (struct FrameDesc *) priv->gtx_ptr;
+		FB_ptr = (unsigned long *) &FD_ptr->FrameDataPtr;
+
+		if(!(*FB_ptr & BDMA_owner))
+		{
+			status = (FD_ptr->StatusAndFrameLength >> 16) & 0xffff;
+			if(status & Comp) {
+				priv->stats.tx_packets++;
+			}
+			else {
+				priv->stats.tx_errors++;
+				if(status & TxPar)
+					priv->stats.tx_aborted_errors++;
+				if(status & NCarr)
+					priv->stats.tx_carrier_errors++;
+				if(status & Under)
+					priv->stats.tx_fifo_errors++;
+				if(status & LateColl)
+					priv->stats.tx_window_errors++;
+				if(status & ExColl)
+					priv->stats.collisions++;
+			}
+		}
+	
+		// Clear Framedata pointer already used
+		FD_ptr->StatusAndFrameLength = 0x0;
+		priv->gtx_ptr = (unsigned long) FD_ptr->NextFrameDescriptor;
+	}
+	
+	spin_unlock(&priv->lock);
+	return;
+}
+
+/*
+ * Open and Close
+ */
+int s3c4510_open(struct net_device *dev)
+{
+	int i;
+	unsigned long status;
+	MOD_INC_USE_COUNT;
+
+	TRACE("open\n");
+
+	// Disable irqs
+	disable_irq(INT_BDMATX);
+	disable_irq(INT_BDMARX);
+	disable_irq(INT_MACTX);
+	disable_irq(INT_MACRX);
+
+	// register rx isr
+	if(request_irq(INT_BDMARX, &s3c4510_rx, SA_INTERRUPT, "eth rx isr", dev)) {
+		printk(KERN_ERR "s3c4510: Can't get irq %d\n", INT_BDMARX);
+		return -EAGAIN;
+	}
+
+	// register tx isr
+	if(request_irq(INT_MACTX, &s3c4510_tx, SA_INTERRUPT, "eth tx isr", dev)) {
+		printk(KERN_ERR "s3c4510: Can't get irq %d\n", INT_MACTX);
+		return -EAGAIN;
+	}
+#if 0
+	printk("Reseting PHY\n");
+	MIIWrite(0x0, 0x0, 1<<15);
+	while((MIIRead(0x0, 0x0) & (1<<15)));
+	
+	
+	printk("Perform AN again\n");
+	MIIWrite(0x0, 0x0, MIIRead(0x0, 0x0) & ~(1<<12));
+//	while(!(MIIRead(0x11, 0x0) & (1<<4)));
+
+	MIIWrite(0x0, 0x0, 1<<13|1<<8);
+	
+	status = MIIRead(0x11, 0x0);
+	if(status & 1<<15)
+		printk("10M/b  ");
+	else
+		printk("100M/b  ");
+	if(status & 1<<14)
+		printk("Full duplex\n");
+	else	printk("Half duplex\n");
+#endif	
+	// reset BDMA and MAC
+	CSR_WRITE(BDMARXCON, BRxRS);
+	CSR_WRITE(BDMATXCON, BTxRS);
+	CSR_WRITE(MACON, Reset);
+	CSR_WRITE(BDMARXLSZ, sizeof(struct ethframe));
+	CSR_WRITE(MACON, gMACCON);
+
+	FD_Init(dev);
+
+	for(i = 0; i < (int)dev->addr_len-2; i++)
+		CAM_Reg(0) = (CAM_Reg(0) << 8) | dev->dev_addr[i];
+	for(i = (int)dev->addr_len-2; i < (int)dev->addr_len; i++)
+		CAM_Reg(1) = (CAM_Reg(1) << 8) | dev->dev_addr[i];
+	CAM_Reg(1) = (CAM_Reg(1) << 16);
+
+	CSR_WRITE(CAMEN, 0x0001);
+	CSR_WRITE(CAMCON, gCAMCON);
+
+	enable_irq(INT_BDMARX);
+	enable_irq(INT_MACTX);
+
+	// ReadyMACTx();
+	CSR_WRITE(BDMATXCON, gBDMATXCON);
+	CSR_WRITE(MACTXCON, gMACTXCON);
+	// ReadyMACRx();
+	CSR_WRITE(BDMARXCON, gBDMARXCON);
+	CSR_WRITE(MACRXCON, gMACRXCON);
+
+	// Start the transmit queue
+	netif_start_queue(dev);
+	
+	return 0;
+}
+
+int s3c4510_stop(struct net_device *dev)
+{
+	TRACE("stop\n");
+	CSR_WRITE(BDMATXCON, 0);
+	CSR_WRITE(BDMARXCON, 0);
+	CSR_WRITE(MACTXCON, 0);
+	CSR_WRITE(MACRXCON, 0);
+
+	free_irq(INT_BDMARX, dev);
+	free_irq(INT_MACTX, dev);
+
+	netif_stop_queue(dev);
+	MOD_DEC_USE_COUNT;
+	
+	return 0;
+}
+
+int s3c4510_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+//	int i;
+	int len;
+	char *data;
+	struct s3c4510_priv *priv = (struct s3c4510_priv *) dev->priv;
+
+	struct FrameDesc	*FD_ptr;	// frame descriptor pointer
+	volatile unsigned long	*FB_ptr;	// frame data pointer
+	unsigned char		*FB_data;	// frame data
+
+	TRACE("start_xmit\n");
+/*
+	printk("sk_buff->len: %d\n", skb->len);
+	printk("sk_buff->data_len: %d\n", skb->data_len);
+	for(i = 0; i < skb->len; i++) {
+		printk("%4x", skb->data[i]);
+		if((i+1)%16 ==0)
+			printk("\n");
+	}
+	printk("\n");
+*/
+	len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+	data = skb->data;
+	dev->trans_start = jiffies;
+	
+	// 1. Get Tx frame descriptor & data pointer
+	FD_ptr = (struct FrameDesc *) priv->tx_ptr;
+	FB_ptr = (unsigned long *) &FD_ptr->FrameDataPtr;
+	FB_data = (unsigned char *) FD_ptr->FrameDataPtr;
+
+	// 2. Check BDMA ownership
+	if(*FB_ptr & BDMA_owner) {
+		printk("no tx buffer\n");
+//		check it later
+//		netif_stop_queue(dev);
+		return 1;
+	}
+	
+	// 3. Prepare Tx Frame data to Frame buffer
+	memcpy(FB_data, data, len);
+	
+	// 4. Set Tx Frame flag & Length Field
+	FD_ptr->Reserved = (Padding | CRCMode | FrameDataPtrInc | LittleEndian | WA00 | MACTxIntEn);
+	FD_ptr->StatusAndFrameLength = (len & 0xFFFF);
+	
+	// 5. Change ownership to BDMA
+	FD_ptr->FrameDataPtr |= BDMA_owner;
+
+	// 6. Enable MAC and BDMA Tx control register
+	CSR_WRITE(BDMATXCON, gBDMATXCON);
+	CSR_WRITE(MACTXCON, gMACTXCON);
+
+	// 7. Change the Tx frame descriptor for next use
+	priv->tx_ptr = (unsigned long)(FD_ptr->NextFrameDescriptor);
+
+	dev_kfree_skb(skb);
+	
+	return 0;
+}
+
+struct net_device_stats *s3c4510_get_stats(struct net_device *dev)
+{
+	struct s3c4510_priv *priv = (struct s3c4510_priv *) dev->priv;
+	TRACE("get_stats\n");
+	return &priv->stats;
+}
+
+/*
+ * The init function, invoked by register_netdev()
+ */
+int s3c4510_init(struct net_device *dev)
+{
+	int i;
+	TRACE("init\n");
+	ether_setup(dev);	// Assign some of the fields
+
+	// set net_device methods
+	dev->open = s3c4510_open;
+	dev->stop = s3c4510_stop;
+//	dev->ioctl = s3c4510_ioctl;
+	dev->get_stats = s3c4510_get_stats;
+//	dev->tx_timeout = s3c4510_tx_timeout;
+	dev->hard_start_xmit = s3c4510_start_xmit;
+
+	// set net_device data members
+	dev->watchdog_timeo = timeout;
+	dev->irq = 17;
+	dev->dma = 0;
+
+	// set MAC address manually
+	dev->dev_addr[0] = 0x00;
+	dev->dev_addr[1] = 0x40;
+	dev->dev_addr[2] = 0x95;
+	dev->dev_addr[3] = 0x36;
+	dev->dev_addr[4] = 0x35;
+	dev->dev_addr[5] = 0x34;
+
+	printk(KERN_INFO "%s: ", dev->name);
+	for(i = 0; i < 6; i++)
+		printk("%2.2x%c", dev->dev_addr[i], (i==5) ? ' ' : ':');
+	printk("\n");
+
+	SET_MODULE_OWNER(dev);
+
+	dev->priv = kmalloc(sizeof(struct s3c4510_priv), GFP_KERNEL);
+	if(dev->priv == NULL)
+		return -ENOMEM;
+	memset(dev->priv, 0, sizeof(struct s3c4510_priv));
+	spin_lock_init(&((struct s3c4510_priv *) dev->priv)->lock);
+	return 0;
+}
+
+struct net_device s3c4510_netdevs = {
+	init: s3c4510_init,
+};
+
+/*
+ * Finally, the module stuff
+ */
+int __init s3c4510_init_module(void)
+{
+	int result;
+	TRACE("init_module\n");
+
+	//Print version information
+	printk(KERN_INFO "%s", version);
+
+	//register_netdev will call s3c4510_init()
+	if((result = register_netdev(&s3c4510_netdevs)))
+		printk("S3C4510 eth: Error %i registering device \"%s\"\n", result, s3c4510_netdevs.name);
+	return result ? 0 : -ENODEV;
+}
+
+void __exit s3c4510_cleanup(void)
+{
+	TRACE("cleanup\n");
+	kfree(s3c4510_netdevs.priv);
+	unregister_netdev(&s3c4510_netdevs);
+	return;
+}
+
+module_init(s3c4510_init_module);
+module_exit(s3c4510_cleanup);
+
+MODULE_DESCRIPTION("Samsung 4510B ethernet driver");
+MODULE_AUTHOR("Mac Wang <mac@os.nctu.edu.tw>");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/drivers/net/s3c4510.h linux-2.4.29-uc1/drivers/net/s3c4510.h
--- linux-2.4.29/drivers/net/s3c4510.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/s3c4510.h	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,230 @@
+#ifndef __S3C4510_H
+#define __S3C4510_H
+
+#define RX_FRAME_SIZE 10
+#define TX_FRAME_SIZE 5
+
+struct FrameDesc {
+	unsigned long FrameDataPtr;		// [31] Ownership 0=CPU, 1=BDMA
+	unsigned long Reserved;
+	unsigned long StatusAndFrameLength;	// [31:16] Rx Status, [15:0] Frame Length
+	unsigned long NextFrameDescriptor;
+};
+
+struct ethframe {
+	unsigned char dst[ETH_ALEN];
+	unsigned char src[ETH_ALEN];
+	unsigned short proto;
+	unsigned char data[ETH_DATA_LEN+22];
+};
+
+struct s3c4510_mac_init_block {
+	unsigned short mode;
+	unsigned char phys_addr[6];
+//	unsigned filter[2];
+
+	unsigned long tx_ptr;
+	unsigned long gtx_ptr;
+	unsigned long rx_ptr;
+
+	struct FrameDesc rx_fd[RX_FRAME_SIZE];
+	struct FrameDesc tx_fd[TX_FRAME_SIZE];
+
+	struct ethframe rx_buf[RX_FRAME_SIZE];
+	struct ethframe tx_buf[TX_FRAME_SIZE];
+};
+
+/* ----------------------------------------- *
+ * Definitions of Samsung 4510 MAC registers *
+ * ----------------------------------------- */
+
+#define MaxRxFrameSize	(1520)
+
+/* -------------------------------------- *
+ * Buffered DMA Transmit Control Register *
+ * -------------------------------------- */
+#define BTxBRST		(0x0000F) /* [4:0] */
+#define BTxSTSKO	(0x00020)
+#define BTxCCPIE	(0x00080)
+#define BTxNLIE		(0x00100)
+#define BTxNOIE		(0x00200)
+#define BTxEmpty	(0x00400)
+//#define BTxMSL		/* [13:11] */
+#define BTxMSL000	(0x00000)
+#define BTxMSL001	(0x00800)
+#define BTxMSL010	(0x01000)
+#define BTxMSL011	(0x01800)
+#define BTxMSL100	(0x02000)
+#define BTxMSL101	(0x02800)
+#define BTxMSL110	(0x03000)
+#define BTxMSL111	(0x03800)
+#define BTxEn		(0x04000)
+#define BTxRS		(0x08000)
+
+/* ------------------------------------- *
+ * Buffered DMA Receive Control Register *
+ * ------------------------------------- */
+#define BRxBRST		(0x0000F) /* [4:0] */
+#define BRxSTSKO	(0x00020)
+#define BRxMAINC	(0x00040)
+#define BRxDIE		(0x00080)
+#define BRxNLIE		(0x00100)
+#define BRxNOIE		(0x00200)
+#define BRxMSOIE	(0x00400)
+#define BRxLittle	(0x00800)
+//#define BRxWA		/* [13:12] */
+#define BRxWA01		(0x01000)
+#define BRxWA10		(0x02000)
+#define BRxWA11		(0x03000)
+#define BRxEn		(0x04000)
+#define BRxRS		(0x08000)
+#define BRxEmpty	(0x10000)
+#define BRxEarly	(0x20000)
+
+/* -------------------- *
+ * BDMA Status Register *
+ * -------------------- */
+#define S_BRxRDF	(0x00001)
+#define S_BRxNL		(0x00002)
+#define S_BRxNO		(0x00004)
+#define S_BRxMSO	(0x00008)
+#define S_BRxEmpty	(0x00010)
+#define S_BRxSEarly	(0x00020)
+#define S_BRxFRF	(0x00080)
+#define S_BRxNFR	(0x00080)
+#define S_BTxCCP	(0x10000)
+#define S_BTxNL		(0x20000)
+#define S_BTxNO		(0x40000)
+#define S_BTxEmpty	(0x100000)
+
+/* -------------------- *
+ * MAC Control Register *
+ * -------------------- */
+#define HaltReq		(0x00001)
+#define HaltImm		(0x00002)
+#define Reset		(0x00004)
+#define FullDup		(0x00008)
+#define MACLoop		(0x00010)
+#define MIIOFF		(0x00040)
+#define Loop10		(0x00080)
+#define MissRoll	(0x00400)
+#define MDCOFF		(0x01000)
+#define EnMissRoll	(0x02000)
+#define Link10		(0x08000)
+
+/* ----------------------------- *
+ * MAC Transmit Control Register *
+ * ----------------------------- */
+#define TxEn		(0x0001)
+#define TxHalt		(0x0002)
+#define NoPad		(0x0004)
+#define NoCRC		(0x0008)
+#define FBack		(0x0010)
+#define NoDef		(0x0020)
+#define SdPause		(0x0040)
+#define SQEn		(0x0080)
+#define EnUnder		(0x0100)
+#define EnDefer		(0x0200)
+#define EnNCarr		(0x0400)
+#define EnExColl	(0x0800)
+#define EnLateColl	(0x1000)
+#define EnTxPar		(0x2000)
+#define EnComp		(0x4000)
+
+/* ---------------------------- *
+ * MAC Receive Control Register *
+ * ---------------------------- */
+#define RxEn		(0x0001)
+#define RxHalt		(0x0002)
+#define LongEn		(0x0004)
+#define ShortEn		(0x0008)
+#define StripCRC	(0x0010)
+#define PassCtl		(0x0020)
+#define IgnoreCRC	(0x0040)
+//#define 		(0x0080)
+#define EnAlign		(0x0100)
+#define EnCRCErr	(0x0200)
+#define EnOver		(0x0400)
+#define EnLongErr	(0x0800)
+//#define 		(0x1000)
+#define EnRxPar		(0x2000)
+#define EnGood		(0x4000)
+
+/* -------------------- *
+ * CAM Control Register *
+ * -------------------- */
+#define StationAcc	(0x0001)
+#define GroupAcc	(0x0002)
+#define BroadAcc	(0x0004)
+#define NegCAM		(0x0008)
+#define CompEn		(0x0010)
+
+/* Tx & Rx Frame Descriptor Ownership bit[31](O) */ 
+#define BDMA_owner	0x80000000 /* BDMA */
+#define CPU_owner	0x7fffffff /* CPU  */
+
+/* ------------------------------- *
+ * Tx Frame Descriptor Description *
+ * ------------------------------- */
+#define Padding		(0x00)
+#define NoPadding	(0x01)
+#define CRCMode		(0x00)
+#define NoCRCMode	(0x02)
+#define MACTxIntEn	(0x04)
+#define MACTxIntDis	(0x00)
+#define LittleEndian	(0x08)
+#define BigEndian	(0x00)
+#define FrameDataPtrInc	(0x10)
+#define FrameDataPtrDec	(0x00)
+#define WA00		(0x00)
+#define WA01		(0x20)
+#define WA10		(0x40)
+#define WA11		(0x60)
+
+/* --------- *
+ * Tx Status *
+ * --------- */
+#define TxCollCntMask	(0x000F)
+#define ExColl		(0x0010)
+#define TxDefer		(0x0020)
+#define Paused		(0x0040)
+#define IntTx		(0x0080)
+#define Under		(0x0100)
+#define Defer		(0x0200)
+#define NCarr		(0x0400)
+#define SQErr		(0x0800)
+#define LateColl	(0x1000)
+#define TxPar		(0x2000)
+#define Comp		(0x4000)
+#define TxHalted	(0x8000)
+
+/* --------- *
+ * Rx Status *
+ * --------- */
+#define OvMax		(0x0004)
+#define CtlRcv		(0x0020)
+#define IntRx		(0x0040)
+#define Rx10stat	(0x0080)
+#define AlignErr	(0x0100)
+#define CRCErr		(0x0200)
+#define Overflow	(0x0400)
+#define LongErr		(0x0800)
+#define RxPar		(0x2000)
+#define Good		(0x4000)
+#define RxHalted	(0x8000)
+
+/* ------------- *
+ * MII Registers *
+ * ------------- */
+#define MiiBusy		(1<<11)
+#define PHYREGWRITE	(1<<10)
+
+enum {
+	gMACCON = FullDup,
+	gMACTXCON = EnComp | TxEn,
+	gMACRXCON = RxEn,
+	gBDMATXCON = BTxBRST | BTxMSL110 | BTxSTSKO | BTxEn,
+	gBDMARXCON = BRxDIE | BRxEn | BRxLittle | BRxMAINC | BRxBRST | BRxNLIE | BRxNOIE | BRxSTSKO | BRxWA10,
+	gCAMCON = CompEn | BroadAcc
+};
+#endif /* __S3C4510_H */
diff -urN linux-2.4.29/drivers/net/s3c4530.c linux-2.4.29-uc1/drivers/net/s3c4530.c
--- linux-2.4.29/drivers/net/s3c4530.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/s3c4530.c	2005-06-14 02:12:15.000000000 +0100
@@ -0,0 +1,2887 @@
+/***********************************************************************
+ *  s3c.c : Samsung S3C4530A ethernet driver for linux
+
+    S3C4530A Communication Processor
+    Copyright (c) Copyright 2001-2002 Arcturus Networks Inc.
+                                      by MaTed <www.ArcturusNetworks.com>
+
+      based on isa-skeleton: A network driver outline for linux.
+	    Written 1993-94 by Donald Becker.
+
+		(c) Copyright 2001 Arcturus Networks Inc.
+
+	Copyright 1993 United States Government as represented by the
+	Director, National Security Agency.
+
+	This software may be used and distributed according to the terms
+	of the GNU Public License, incorporated herein by reference.
+
+	The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
+	Center of Excellence in Space Data and Information Sciences
+	   Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
+
+	This file is the first go at creating a driver for the ethernet driver
+        used by the S3C SOC. The core is the 10/100 MB Sierra Research core
+        for which there doesn't appear to be a driver for the Linux
+        operating system.
+
+	Known Limitations:
+	- Because the S3c controller is so "intelligent", it manages the
+	buffer list on it's own. Therefore you create the Buffer List for
+	the controller without knowing the length required. A maximum MTU
+	buffer is pre-allocated regardless of the actual requirements. Either
+	the controller firmware can be changed to pick buffers whose size
+	is closer to the actual size required, or we can memcpy (ugh!!!) to
+	a smaller buffer.
+
+	- module support is either non-existant or not tested (it was a SOC
+	afterall)
+
+*************************************************************************/
+
+/************************************************************************
+ * modification history
+ * --------------------
+ *
+ * 08/16/02     Michael Durrant <mdurrant@ArcturusNetworks.com>
+ * 10/29/01	MaTed (Ted Ma)      First go
+ *	- PLEASE set TABS==4
+ ************************************************************************/
+/*
+  Sources:
+  - source is available from Arcturus Networks Inc. 
+    www.ArcturusNetworks.com 
+ 
+  Finally, keep in mind that the Linux kernel is has an API, not
+  ABI. Proprietary object-code-only distributions are not permitted
+  under the GPL.
+*/
+#include "s3c4530.h"
+
+#ifdef CONFIG_ETH_S3C4530	/* skip the entire file if not configured 	*/
+
+static const char *version =
+"s3c4530.c: Network driver by Arcturus Networks Inc. <www.ArcturusNetworks.com>\n";
+
+/************* DEBUG **********/
+#define VERBOSE y
+#ifdef VERBOSE
+UINT	verbose = 5;
+#endif
+
+#define DEBUG_PHY_DUMP	0
+#define	PHY_DEBUG		0
+
+#define DEBUG_RX_DUMP	0	// for dumping Rx Structures
+
+// #define DumpJiffies(x) printk("----s3c:%s Jiffies=[%x]\n",x, jiffies);
+#define DEBUG_SINT 0		// debugging interrupts (s3c ones)
+#if DEBUG_SINT
+#define SINT(x, y) printk("S3INT %s=%0x\n", x, y);
+#else
+#define SINT(x, y)
+#endif
+
+#define DEBUG_INCTXPTR	0	// debugging incrementing txPtr
+#if DEBUG_INCTXPTR
+S3C_MAC * PrivPtr;			// for debugging when dev / priv structs NA
+#define CHECK_ITXPTR(instr)	\
+if (((int) ReadCSR( TxPtr)) != (int) PrivPtr->qTx.first) { \
+  printk( "DEBUG_INCTXPTR: %s:read %x ", \
+		 (char *) #instr, (int) ReadCSR( TxPtr)); \
+  if (0 == (0x3 & ((int) ReadCSR(TxPtr)))) \
+	printk( "DataPtr=0x%x\n", \
+		   (int) (((TxFD *) (ReadCSR( TxPtr)))->FDDataPtr)); \
+	else \
+	  printk( "DataPtr is not word aligned !! \n"); \
+	printk( "           ***: setting to %x\n", \
+			(int) WriteCSR(TxPtr, PrivPtr->qTx.first)); }
+#else
+#define CHECK_ITXPTR(x)
+#endif
+#define MATED_DEBUG	0		/* Tracking down bad "grow" ? Mostly verify 
+							   it is grow that kills things ...MaTed---*/
+#if MATED_DEBUG
+#define SMEM_CHECK( index) \
+	if (((*((int *)(0x7cfea8))) & 3) != 0) { \
+      printk("\n @@@@* * MEMORY STOMPED!\n"); \
+    } \
+	printk("     * * Memory check! %s\n   ---- 0x%x-0x7cfea8 = 0x%x\n", \
+		   #index, (int) ((int *)(0x7cfea8)), (*((int *)(0x7cfea8)))); \
+	printk("     FILE [%s] FUNCTION [%s] - LINE #%d\n", \
+		   __FILE__, __FUNCTION__, __LINE__); \
+    (*((int *)(0x7cfea8))) = (*((int*)(0x7cfea8))) & ~3; \
+	printk("    @* Memory set to 0x%x\n", (*((int *)(0x7cfea8))) );
+#define SMEM_CHECKQ( index) \
+	if (((*((int *)(0x7cfea8))) & 3) != 0) { \
+      printk("\n @@@@* * MEMORY STOMPED!\n"); \
+	printk("     * * Memory check! %s 0x%x-0x7cfea8 = 0x%x\n", \
+		   #index, (int) ((int *)(0x7cfea8)), (*((int *)(0x7cfea8)))); \
+	printk("     FILE [%s] FUNCTION [%s] - LINE #%d\n", \
+		   __FILE__, __FUNCTION__, __LINE__); \
+    (*((int *)(0x7cfea8))) = (*((int*)(0x7cfea8))) & ~3; \
+	printk("    @* Memory set to 0x%x\n", (*((int *)(0x7cfea8))) ); \
+    }
+#else
+#define SMEM_CHECK( index)
+#endif
+
+/*********** end debug *******/
+
+/*
+  A bit of an introduction for the algorithms used herein
+  - implemented with zero copy.
+    - receive - skb's are preallocated with a maximum sized buffer and the 
+				data is dma'd into the preallocated buffer. We may add a 
+				section to copy the buffer down so we don't use as much
+				memory resources - but that's still to be implemented
+			  - Has the disadvantage of potentially	thrashing memory by 
+				alloc / dealloc SKB's.
+	- transmit - skb's are attached to the ring buffer. When the MAC 
+				 either transmits the packet or discards it (we don't
+				 guarentee delivery at this level), the skb is freed
+  - all rx buffers are pre-allocated when the MAC is opened
+  - we will use one interrupt per packet sent or received *****FIXME mated
+    - we cold drop the TX interrupt - just remember to enable if backpressure 
+	stops tx_send_packet
+*/
+/*
+ * The name of the card. Is used for messages and in the requests for
+ * io regions, irqs and dma channels
+ */
+static const char* cardname = "s3c";
+
+/*
+ * Setup a base address where offset < 4024 (2**12 - max 
+ *	immediate offset for ARM)
+ */
+static CSR * const baseAddr = ((CSR *) ((BDMA_BASE) | 0x04000000));	// uncached
+
+/**********************************************
+Compile time directives
+***********************************************/
+#define NO_INCLUDE_MAC_RX_INT	1		// do not include (or set up) the
+										//  MAC receive interrupt
+#define	ENABLE_DESTRUCTOR		0		// use destructor to set 
+/************************************************************************
+	"Knobs" that adjust features and parameters.
+    - Set the copy breakpoint for the copy-only-tiny-frames scheme.
+      - Setting to > 1512 effectively disables this feature.
+	  *** NOT implemented *** FixMe ...MaTed
+*******************************************************************/
+static const int rx_copybreak = 1536;
+
+/* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
+/**** Currently unused ...MaTed--- ****/
+static const int mtu = 1500;
+
+/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
+//  We might need this back - right now handle as many as buffers allow
+// *** Hard coded in s3c_tx and s3c_rx ...MaTed---
+//static int max_interrupt_work = 32; 
+
+static UINT net_debug = NET_DEBUG;
+
+/******************************************************
+ * Internal S3C data structures
+ ******************************************************/
+UINT32	numS3cMacs	= 0;	// number of macs
+char *		MacName[]
+//	= {"ethaddr0", "ethaddr1", "ethaddr2", "unknown"};
+	= {"HWADDR0", "HWADDR1", "HWADDR2", "unknown"};
+
+/************************************************************************
+ * Internal Function Declarations - all static
+ ************************************************************************/
+
+static _INLINE_ int PHYWait( void);
+static int WritePhy( UINT32 addr, UINT32 reg, UINT32 data);
+static int ReadPhy( UINT32 addr, UINT32 reg, UINT32 * data);
+static _INLINE_ int txFull( ND dev);
+static void SetupPHY( UINT32 mode);
+static ULONG PHYCheckCable( void);
+static int PhyInit( ND dev);
+static ULONG SetupTxFDs( ND dev );
+static ULONG SetupRxFDs( ND dev);
+static _INLINE_ void EnableInt( void );
+static _INLINE_ void DisableInt( void);
+static _INLINE_ void EnableTxRx( void );
+static _INLINE_ void DisableTxRx( void );
+static int Reset( void);
+static void SetupRegistersTx( void);
+static void SetupRegistersRx( void);
+static _INLINE_ void SetUpTxFrmPtrRegister( ND dev);
+static _INLINE_ ULONG TxRxInit( ND dev);
+static int SetMacAddr( ND dev, void * addr);
+static int SetUpARC( ND dev, void * addr);
+#if ENABLE_IOCTL
+static _INLINE_ void SetSpeed100( void);
+static _INLINE_ void SetSpeed10( void);
+#endif	// ENABLE_IOCTL
+// ***** FIXME ** InvalidateCacheLIne should move to other file ...MaTed---
+_INLINE_ void InvalidateCacheLine( UINT32 bufaddr);
+_INLINE_ void InvalidateBuffer( void * bufaddr, UINT length);
+_INLINE_ void FlushCache(void);
+
+/* Index to functions, as function prototypes. */
+
+int __init	s3c_probe( ND dev);
+static int	s3c_InitVars( ND dev);
+static _INLINE_ int s3c_request_irq_mem( ND dev);
+
+static int	s3c_probe1( ND dev);
+static _INLINE_ int s3cLogTxMACError( ND dev, int status);
+static _INLINE_ int s3cLogRxBdmaError( ND dev, int status);
+static void	s3c_tx_timeout( ND dev);
+static _INLINE_ int 	s3cInitPriv( ND dev );
+
+static int	s3c_open( ND dev);
+static int	s3c_send_packet( struct sk_buff *skb, ND dev);
+/* four interrupt routines - with one helper */
+static void	s3c_MacTx( int irq, void *dev_id, struct pt_regs * regs);
+static _INLINE_ void TxPktCompletion( ND dev);
+static void	s3c_BdmaTx( int irq, void *dev_id, struct pt_regs * regs);
+#if ! NO_INCLUDE_MAC_RX_INT
+static void	s3c_MacRx( int irq, void *dev_id, struct pt_regs * regs);
+#endif
+static void	s3c_BdmaRx( int irq, void *dev_id, struct pt_regs * regs);
+static void s3cAddRxSKBs( ND dev, UINT32 MaxIn, UINT32 MinIn );
+#if DEBUG_RX_DUMP
+static void dumpRx( S3C_MAC * priv, char * where);
+static void RXFDS_Dump( RxFDS * fds, char * str);
+#endif
+#if	ENABLE_DESTRUCTOR 
+static void	s3cDestructor( struct sk_buff *skb);
+#endif
+static int	s3c_close( ND dev);
+static struct net_device_stats	*s3c_get_stats( ND dev);
+static void	set_multicast_list( ND dev);
+static void	HardwareSetFilter( ND dev);
+
+#if DEBUG_PHY_DUMP
+static void DumpPhyReg( void);
+#endif
+
+/************************************
+ * Temporary routines
+ ************************************/
+#define S3C_TEMP_ROUTINES 0
+#if S3C_TEMP_ROUTINES
+static int get_ethernet_addr(char * MatchName, char * addr);
+#endif
+
+/************************************************************************
+ * Utility routines
+ ************************************************************************/
+// NOTE: assumes base is already KSEG1 ????
+#if 0
+#define WriteCSR(base, reg, value) \
+		((volatile UINT32)(((CSR *)( base))->reg) = (value))
+#define ReadCSR(base,  reg) ((volatile UINT32)(((CSR *) (base))->reg))
+#else
+#define WriteCSR(reg, value) (baseAddr->reg = (UINT32) (value))
+#define ReadCSR( reg) (baseAddr->reg)
+#endif
+
+#if 0	// ...MaTed--- don't need this here
+/***************************************************************************
+ * Interface to boot environment variables
+ ***************************************************************************/
+int		errno; 		// the macros want this - not friendly  ...MaTed---
+// _bsc1(char *, readbenv,   int, a)
+//_bsc1(char *, getbenv, char *, a)
+// _bsc1(int,    setbenv, char *, a)
+#endif
+                                         
+/***************************************************************************
+ *	Function Name:      txFull
+ *
+ *  Purpose:	Returns 0 if tx Queue in not full, !=0 if full
+ *
+ *  Inputs:     ND dev
+ ***************************************************************************/
+static _INLINE_ int 
+txFull( ND dev)
+{
+  return ((TX_NUM_FD - 1) <= ((S3C_MAC *)dev->priv)->qTx.num);
+}
+/*************************************************************************
+ * PHYWait - Waits for Station Management to become non-busy
+ *
+ * This inline routine is a helper to wait for Station Management to 
+ *	become non-busy - ie for the command to complete
+ *
+ * returns	S3c_SUCCESS if succesfully written
+ *       	other returns indicate timeout or other error
+ *************************************************************************/
+static _INLINE_ int 
+PHYWait( void)
+{
+  UINT32 i = 0;
+
+  while (( ReadCSR( SmCtl)) & MStBusy)
+  {
+    if ( i++ >= PHY_BUSYLOOP_COUNT)
+    {
+#ifdef VERBOSE
+      if ( verbose)
+      {
+		printk( "S3C4530-PHY: *** BUSY Timeout! ***\n");
+      }
+#endif
+      return( S3C_TIMEOUT);
+    }
+	mdelay( 10);	// 10 millisecond delay per loop
+  }
+  return( S3C_SUCCESS);
+}
+/*************************************************************************
+ * WritePHY - writes data to phy972
+ *
+ * This routine is a helper to write Phy data
+ *
+ * data is written to reg of the PHY at addr
+ * returns	S3c_SUCCESS if succesfully written
+ *       	other returns indicate timeout or other error
+ *************************************************************************/
+static int 
+WritePhy( UINT32 addr, UINT32 reg, UINT32 data)
+{
+  int rc;
+
+  if ( S3C_SUCCESS != ( rc= PHYWait()))
+	return( rc);
+  WriteCSR( SmData, data);  	/* set data */
+  WriteCSR( SmCtl, MStWr | MStBusy | reg | addr << 5);	// send WRITE cmd
+#if PHY_DEBUG
+    printk( "S3C4530-PHY: wrote 0x%08x to PHY%d register 0x%x\n",
+			(int) data, (int) addr, (int) reg);
+#endif
+	return( PHYWait());
+}
+/*************************************************************************
+ * ReadPHY - reads data from phy972
+ *
+ * This routine is a helper to read Phy data
+ *
+ * data is read from reg of the PHY at addr
+ * returns	S3C_SUCCESS if succesfully read
+ *       	other returns indicate timeout or other error
+ *************************************************************************/
+static int 
+ReadPhy( UINT32 addr, UINT32 reg, UINT32 * data)
+{
+  int rc;
+
+  	// wait for any previous command to complete
+  if ( S3C_SUCCESS != ( rc= PHYWait()))
+	return( rc);
+  WriteCSR( SmCtl, MStBusy | reg | addr << 5);	// send READ cmd
+  // wait for read command to complete
+  if ( S3C_SUCCESS != ( rc= PHYWait()))
+	return( rc);
+  *data = ReadCSR( SmData);  	/* get data */
+#if PHY_DEBUG
+    printk( "S3C4530-PHY: read 0x%08x from PHY%d register 0x%x\n",
+			(int) *data, (int) addr, (int) reg);
+#endif
+  return (rc);					/* return success */
+}
+/*************************************************************************
+ * SetupPHY - initialize and configure the PHY device.
+ *
+ * This routine initializes and configures the PHY device 
+ *	***** NOTE: the LED values used for initialization are overwritten
+ *
+ * LevelOne LXT972
+ * Loopback=disabled
+ * Speed = 100/10
+ * Auto-Negotiation Restart = mode enabled --- FIXME NOTE: Assumption that
+ *									   -- FIXME		Negotiation had not
+ *										- FIXME		previously run ???
+ * Power Down = 0 normal
+ * Isolate = 0 normal
+ * Restart Auto-Negotiation = 0
+ * Duplex = 1 Full / 0 Half
+ * Collision Test = 0 Disabled
+ *
+ **** parm mode values *****
+ * For Full Dup 10Mbps:  0x0100
+ * For Half Dup 10Mbps:  0x0000
+ * For Full Dup 100Mbps: 0x2100
+ * For Half Dup 100Mbps: 0x2000
+ * For Auto Negotiate:   0x1000		- half duplex 10 advertised
+ * For Auto Negotiate:   0x1100		- full/half duplex 10 advertised
+ * For Auto Negotiate:   0x3000		- half duplex 10/100 advertised
+ * For Auto Negotiate:   0x3100		- full/half duplex 10/100 advertised
+ * For Restart AutoNeg:  0x0200		- current values retained
+ *
+ *************************************************************************/
+static void 
+SetupPHY( UINT32 mode) 
+{
+  UINT32	j;
+  UINT32	data;
+
+  /* First reset the PHY */
+  WritePhy( PHYAddr, PHYCtl, PHYCtlReset);
+  /*
+   * Read the Reset bit(0.15) of the PHY to see if the reset is completed.
+   */
+  for ( j = 0; j < PHY_RESETLOOP_COUNT; j++)
+  {
+    if (S3C_SUCCESS != ReadPhy( PHYAddr, PHYCtl, &data))
+	{
+#ifdef VERBOSE
+	  printk( "S3C4530-PHY: RESET command not accepted! ***\n");
+#endif
+	  return;
+	}
+    if ( (data & PHY_RESET) == 0)
+    {
+#ifdef VERBOSE
+      if ( verbose)
+      {
+		printk( "S3C-PHY reset\n");
+      }
+#endif
+      break;
+    }
+	mdelay( 10);	// 10 mS
+  }
+
+  mdelay( 10);	// just in case
+  // change the LED to right lin/activity LEFT->speed
+  WritePhy( PHYAddr, PHYLedCfg, PHYLEDCFG);
+
+#if PHY_DEBUG
+  printk( "S3C4530-PHY: setting up mode-%08x\n", (int) mode);
+#endif
+  if (S3C_SUCCESS != ReadPhy( PHYAddr, PHYCtl, &data))
+  {
+#ifdef VERBOSE
+	printk( "S3C4530-PHY: Read mode command not accepted! ***\n");
+#endif
+	return;
+  }
+#if PHY_DEBUG
+  printk( "S3C4530-PHY: Original mode-%08x\n", (int) data);
+#endif
+  /*
+   * Rules for mode
+   *  if b12 is set	- autonegotiation is enabled -> for the other bits set
+   *				- advertizing will match 
+   *  if b12 is reset - no autonegotian, adverting is not changed
+   *  b13 set to 100 MbS (includes 10 if autoneg) 
+   *  b13 reset -> 10 Mbs only 
+   *  b8 set FULL DUPLEX (autonegiate -> HALF Duplex included)
+   *  b8 reset Half Duplex
+   */
+  if (0 == (mode & PHY_CONTROL_AUTONEG))
+  {	// No autonegotiate - just write mode and done
+	if (S3C_SUCCESS != WritePhy( PHYAddr, PHYCtl, mode))
+	{
+#ifdef VERBOSE
+		printk( "S3C4530-PHY: Mode change failed for Control\n");
+#endif
+	}
+	return;		// no autonegotiation - no advertising
+  }
+
+#if 1
+  // Advertise to the world what we will negotiate
+  if (S3C_SUCCESS != ReadPhy( PHYAddr, PHYANegAd, &data))
+  {
+#ifdef VERBOSE
+	printk( "S3C4530-PHY: Read Negotiate Advertize not accepted! ***\n");
+#endif
+	return;
+  }
+  data &= ~PHYANegAdMask;
+  switch (mode & (PHY_CONTROL_SELECT_SPEED | PHY_CONTROL_DUPLEXMODE))
+  {
+  case PHY_CONTROL_SELECT_SPEED | PHY_CONTROL_DUPLEXMODE:
+	data |= PHYB8 | PHYB7 | PHYB6 | PHYB5;
+	break;
+  case PHY_CONTROL_SELECT_SPEED:
+	data |= PHYB7 | PHYB5;
+	break;
+  case PHY_CONTROL_DUPLEXMODE:
+	data |= PHYB6 | PHYB5;
+	break;
+  case 0:
+	data |= PHYB5;
+	break;
+  }
+#else
+  // put in everything
+  data = PHYLEDANEG;
+#endif
+  if (S3C_SUCCESS != WritePhy( PHYAddr, PHYANegAd, data))
+  {
+#ifdef VERBOSE
+	printk( "S3C4530-PHY: Mode change failed for Advertise\n");
+#endif
+	return;
+  }
+  /* since we are auto negotiating, force a restart */
+  mode |= PHY_CONTROL_RESTART_AUTONEG;	// just in case
+  if (S3C_SUCCESS != WritePhy( PHYAddr, PHYCtl, mode))
+  {
+#ifdef VERBOSE
+	printk( "S3C4530-PHY: Autonegotiate failed to restart\n");
+#endif
+	return;
+  }
+#if 1 // let the next routine check for the end of the negotiation
+  j = 0;
+  ReadPhy( PHYAddr, PHYCtl, &data);
+  while ( data & PHY_CONTROL_RESTART_AUTONEG)
+  {
+    if ( j++ >= PHY_NEGLOOP_COUNT)
+    {
+#ifdef VERBOSE
+      if ( verbose)
+      {
+		printk( "S3C4530-PHY: * Restart AutoNegotiate did not complete ");
+		printk( " Will check again later ***\n");
+      }
+#endif
+      return;
+    }
+	mdelay( 10);	// 10 millisecond delay per loop
+	ReadPhy( PHYAddr, PHYCtl, &data);
+  }
+#endif
+  return;
+}
+/*************************************************************************
+ * PHYCheckCable - Check for Cable connection to the PHY 972.
+ *
+ *
+ * RETURNS: S3C_SUCCESS, or S3C_FAIL
+ * Needs to be modified according to the PHY, and 
+ * needs to be modified according to the SPEC of Level1 972
+ **************************************************************************/
+static UINT32 
+PHYCheckCable( void)
+{
+  UINT32	data;
+
+  if (S3C_SUCCESS != ReadPhy( PHYAddr, PHYStat2, &data))
+  {
+#ifdef VERBOSE
+	printk( "S3C-CheckCable: Read status 2 command not accepted! ***\n");
+#endif
+	return (S3C_FAIL);
+  }
+#if PHY_DEBUG
+  printk("S3C-CheckCable: Status 2 = 0x%x\n", (int) data);
+#endif
+  if (!(data & PHY_LINK_UP))
+    return( S3C_FAIL);
+#ifdef VERBOSE
+  else
+  {
+	if ( verbose)
+    {
+	  if (data & PHYMODE_100)
+		printk( "S3C4530-PHY: running at 100 Mbps, ");
+	  else
+		printk( "S3C4530-PHY: set for 10 Mbps,  ");
+	  
+	  if(data & PHYFULL_DUPLEX)
+		printk( "FULL Duplex Mode.\n");
+	  else
+		printk( "HALF Duplex Mode. \n");
+	}
+  }
+#endif
+  return S3C_SUCCESS;
+}
+/*************************************************************************
+ * PhyInit - initialize and configure the PHY device.
+ *
+ * This routine initialize and configure the PHY device 
+ *
+ * RETURNS: S3C_SUCCESS, or S3C_FAIL
+ * Needs to be modified according to the PHY, and 
+ * needs to be modified according to the SPEC of Level1 972.
+ **************************************************************************/
+static int 
+PhyInit( ND dev)
+{
+  S3C_MAC *	np = (S3C_MAC *) dev->priv;
+ 
+  UINT32	status = S3C_SUCCESS;
+   UINT32	i;
+  static const UINT32 modeList[] = 
+  {
+	PHY_CONTROL_AUTONEG_HALF_10,	PHY_CONTROL_SPEED_10_HALF,
+	PHY_CONTROL_SPEED_100_HALF,	PHY_CONTROL_AUTONEG_HALF_100,
+	PHY_CONTROL_AUTONEG_FULL_10, 	PHY_CONTROL_SPEED_10_FULL,
+	PHY_CONTROL_SPEED_100_FULL,	PHY_CONTROL_AUTONEG_FULL_100
+  };	
+  // Setup duplex and speed to pass on
+  //   automatic get 0
+  // setup Station Management data -- NOTE: Incomplete Data
+#define MATED_PHYTEST 0
+#if MATED_PHYTEST
+  //  SetupPHY( PHY_CONTROL_AUTONEG_FULL_10);
+  SetupPHY( PHY_CONTROL_SPEED_100_FULL);
+#else
+  SetupPHY( modeList[ np->phySpeed + (np->phyDpx << 2)]);
+#endif
+
+  for ( i = 0; i < PHY_BUSYLOOP_COUNT; i++) 
+  {
+	if ( S3C_SUCCESS == (status = PHYCheckCable( )))
+	{
+#ifdef VERBOSE
+	  if ( verbose)
+      {
+		printk( "S3C4530-PHY: Cable detected\n");
+	  }
+#endif
+	  break;
+	}
+	mdelay( 10);	// 10 mS
+  }
+  //#ifdef VERBOSE
+  if ( status != S3C_SUCCESS)
+  {
+    printk( "S3C4530-PHY: **** NO Cable is connected to MAC %s %08lx\n", 
+			dev->name, (UINT32) baseAddr);
+  }
+  //#endif
+#if DEBUG_PHY_DUMP
+  DumpPhyReg();
+#endif	//DEBUG_PHY_DUMP
+
+#if 0		// no failure if no cable
+  return ( status);
+#else
+  return ( S3C_SUCCESS);
+#endif
+} 
+/*********************************************************************
+ *	Function Name:  SetupTxFDs
+ *
+ * Purpose: For transmit frame and buffer descriptors
+ *          - set up initial values for these.
+ *	    	- setup queue pointers
+ *			- FDS setup as a ring 
+ *
+ *	** Assumes called just after dev set up, and priv defined
+ *
+ * Inputs:  Pointer to dev structure
+ *
+ * Return Value:
+ *	S3C_SUCCESS
+ *	S3C_FAIL
+ *********************************************************************/
+static ULONG 
+SetupTxFDs( ND dev )
+{
+  int i;
+
+  TxFDS * tptr;		// temporary pointer
+  TxFDS * lastPtr;	// keep last pointer to update
+  S3C_MAC *	priv;	//pointer to private area
+
+  if (0 == (priv =  dev->priv))
+  {
+    return ( S3C_FAIL);
+  }
+
+  /* Setup the Queue pointers */
+  tptr	// pointer to first in ring
+    = priv->qTx.first
+    = priv->qTx.last
+    = &priv->txFd[ 0];
+  priv->qTx.num = 0;	// no buffers in use
+
+  lastPtr
+    = &priv->txFd[ TX_NUM_FD - 1];
+
+  /* for all the tx frames */
+  for(i = 0; i < TX_NUM_FD; i++) 
+  {  
+    /*  CPU Ownership and Uncached and index and crash ( not word aligned) */
+    tptr->fd.FDDataPtr	= (UCHAR *) (0x4000000 | (i * 4 + 1));
+    tptr->fd.FDStat	    = 0x00000000;
+    tptr->fd.FDLength	= 0x0000;			// nothing there yet
+	//	tptr->fd.FDModes	= TxWidSetup;		// set widget bits (pg 7-18)
+	tptr->fd.FDModes	= 0;				// Do setup only for packet being sent/
+	tptr->skb			= (struct sk_buff *) NULL;
+
+    lastPtr->fd.FDNext	= (TxFD *) tptr;	// Cast just for warning
+	//  link is for top "half"
+    lastPtr = tptr++;
+  }	
+#ifdef VERBOSE
+  if ( verbose)
+  {
+    printk( KERN_INFO "SetupTxFDs-for %s, First buff %x, Last %x\n",
+	    dev->name, (int) &priv->txFd[ 0 ],
+	    (int) &priv->txFd[ TX_NUM_FD - 1]);
+  }
+#endif
+  InvalidateBuffer( &priv->txFd, TX_NUM_FD * sizeof( TxFDS));
+  /* now tell the MAC about the beginning of the TX buffers */
+  /*** NOPE gets done in TxRxInit */
+  // WriteCSR( TxPtr, priv->qTx.first);
+  return ( S3C_SUCCESS);
+}
+/***********************************************************************
+ * Function Name:	SetupRxFDs                              
+ *                                                                          
+ * Purpose: Prepare memory for receive buffers and frame descriptors
+ *
+ *	** Assumes called just after dev set up, and priv defined
+ *
+ * Inputs:  Pointer to dev structure
+ *
+ * Return Value:
+ *	S3C_SUCCESS
+ *	S3C_FAIL
+ ***********************************************************************/
+static ULONG SetupRxFDs( ND dev)
+{
+  int 				i;
+  S3C_MAC			* priv;		// pointer to the private s3c area
+  RxFDS				* ftPtr;	// temp pointer for FDA (rx fram descriptor)
+  RxFDS				* fLastPtr;	// last pointer for FDA
+  RxFDS				* saveLastPtr;	// last pointer for FDA
+  struct sk_buff 	* skb;
+
+  if ( 0 == (priv = (S3C_MAC *) dev->priv))
+  {
+    return ( S3C_FAIL);
+  }
+  /*
+   * Setup the Queue pointers
+   */
+  /** First the Fd **/
+  ftPtr	// pointer to first in ring
+    = priv->qRx.first
+    = &priv->rxFd[ 0];
+  priv->qRx.num = RX_NUM_FD;	// buffers in use
+  priv->qRx.last
+    = fLastPtr
+	= saveLastPtr
+    = (RxFDS *) &priv->rxFd[ RX_NUM_FD - 1];	// last one
+
+  /* 
+   * The Wait list only keeps track of FDs which don't have SKB's
+   * - filled and put back on end of Rx queue later
+   */
+  priv->qRxWait.first
+	= priv->qRxWait.last
+	= NULL;						// point to nothing
+  priv->qRxWait.num = 0;		// all given to MAC
+
+  /*
+   * Initialize the FD Area. Give the ownership of each 16
+   * byte block to the controller - ready to RX. (The patterns of
+   * 0xBBB etc is for debugging only!)
+   ** NOTE: There is no EOL bit (original code had)
+   */
+#if MATED_DEBUG
+  SMEM_CHECK("****** S3C: SetupRxFDs before loop before delay ***:");
+  {
+	int iMaTed;
+	for (iMaTed=0; iMaTed<500; iMaTed++)
+	  printk(" %c",8);
+  }
+#endif
+  SMEM_CHECK("****** S3C: SetupRxFDs before loop after delay ***:");
+  for ( i = 0; i < RX_NUM_FD; i++)
+  {
+	/*
+	 * Each FD points to a large enough buffer so that for each
+	 * incoming packet will fit in one buffer.
+	 *
+	 */
+	// we preallocate SKBs
+	skb = dev_alloc_skb( PKT_BUF_SZ);
+	if (skb == NULL)
+    {
+	  printk( KERN_NOTICE "%s: Unable to allocate buffers.\n",
+			  dev->name);
+	}
+	//	SMEM_CHECK("S3C: RxFDs- in skb Allocate loop after alloc");
+	ASSERT( 0 == (OWNERSHIP & (UINT32) skb->data));	// address space limited to 
+											//  lower 2GB
+	//get data offset
+	// We invalidate cache after mac dma's data (might be shorter)
+	// InvalidateBuffer( skb->data, PKT_BUF_SZ);	// don't want old contents
+	// But we do have to make sure we don't have outstanding writes to 
+	//  the buffer
+	FlushCache();
+	ftPtr->fd.FDDataPtr = (UCHAR *) ((UINT32)skb->data | OWNERSHIP);
+	ftPtr->skb = skb;		// save for later
+	InvalidateBuffer( (void *) ftPtr->fd.FDDataPtr, PKT_BUF_SZ);
+	skb->dev = dev;
+#if	ENABLE_DESTRUCTOR 
+	skb->destructor = priv->destructor;
+#endif
+	skb_reserve( skb, 2);			// 16 byte alignment - for TCP
+	ftPtr->fd.FDLength = PKT_BUF_SZ;
+	ftPtr->fd.FDStat = 0;				// Mac wil fill this in
+
+    // Now do the links	
+    fLastPtr->fd.FDNext   = (RxFD *) ftPtr;
+    fLastPtr = ftPtr++;
+	SMEM_CHECK("S3C: RxFDs- in skb Allocate loop at end");
+  }
+  SMEM_CHECK("****** S3C: SetupRxFDs after setup loop ***:");
+#if 1	// we aren't going to stop the BDAM engine from getting to the 
+		//	last one, It stops itself
+  // Need to put in the EOL
+  // We should just fix the above loop not to set the OWNERSHIP bit on the
+  //   last one, but it's only initialization ...MaTed---
+  saveLastPtr->fd.FDDataPtr = (UCHAR *) 
+	(~OWNERSHIP & (UINT) saveLastPtr->fd.FDDataPtr);
+#endif
+
+    priv->rxFd[ RX_NUM_FD - 1].fd.FDNext = (RxFD *) NULL;	// last one
+
+#ifdef VERBOSE
+  if ( verbose)
+  {
+    printk( "SetupRxFDs-for %s\n", dev->name);
+  }
+#endif
+  // This invalidates the header structures
+  InvalidateBuffer( &priv->rxFd, RX_NUM_FD * sizeof( RxFDS));
+  /*
+   * Now tell the MAC about the buffers
+   */
+  WriteCSR( RxPtr, priv->qRx.first);
+  return ( S3C_SUCCESS);
+}
+/**********************************************************************
+ * Function Name:	EnableInt
+ *
+ *   Purpose:       Enables the Interrupt for the Dev
+ *					- Interrupt enables are in 5 different registers
+ *   
+ *   Parameters:    Device
+ ***********************************************************************/
+static _INLINE_ void 
+EnableInt( void)
+{
+  // temp disable (is this needed??)
+	// disable all temporarily
+  WriteCSR( TxCtl, ReadCSR( TxCtl ) & ~ BTxINTMask );
+  WriteCSR( RxCtl, ReadCSR( RxCtl )	& ~ BRxINTMask );
+  WriteCSR( MacCtl, ReadCSR( MacCtl ) & ~ MCtlINTMask );
+  WriteCSR( MacTxCtl, ReadCSR( MacTxCtl ) & ~ (MTxCtlINTMask | MTxCtlEnComp ));
+  WriteCSR( MacRxCtl, ReadCSR( MacRxCtl ) & ~ MRxCtlINTMask );
+  
+  /* Enable Interrupts */
+  /* first logic level */
+#if !NO_INCLUDE_MAC_RX_INT
+  enable_irq( MAC_RX_IRQ);
+#endif
+  enable_irq( MAC_TX_IRQ);
+  enable_irq( BDMA_RX_IRQ);
+  enable_irq( BDMA_TX_IRQ);
+  /* then from the hardware */
+#if !NO_INCLUDE_MAC_RX_INT
+  s3c4530_unmask_irq( MAC_RX_IRQ);
+#endif
+  s3c4530_unmask_irq( MAC_TX_IRQ);
+  s3c4530_unmask_irq( BDMA_RX_IRQ);
+  s3c4530_unmask_irq( BDMA_TX_IRQ);
+
+  /* Enable MAC and BDMA interrupts - everything for now */
+  WriteCSR( TxCtl, ReadCSR( TxCtl ) | BTxINTMask );
+  WriteCSR( RxCtl, ReadCSR( RxCtl )	| BRxINTMask );
+  // Right Now I don't even know what vector this goes to
+  //  It only contains a error counter rolls over I don't 
+  //  have a reason for it. FIXME later ...MaTed---
+  //  WriteCSR( MacCtl, ReadCSR( MacCtl ) | MXtlINTMask );
+  WriteCSR( MacTxCtl, ReadCSR( MacTxCtl ) | MTxCtlINTMask );
+  WriteCSR( MacRxCtl, ReadCSR( MacRxCtl ) | MRxCtlINTMask );
+
+  CHECK_ITXPTR("EnableInt")
+}
+/**********************************************************************
+ * Function Name:	DisableInt
+ *
+ *   Purpose:   Disables the Interrupt for the specified Dev
+ *   
+ *   Parameters:    Device
+ ***********************************************************************/
+static _INLINE_ void 
+DisableInt( void )
+{
+	// disable all temporarily
+  WriteCSR( TxCtl, ReadCSR( TxCtl ) & ~ BTxINTMask );
+  WriteCSR( RxCtl, ReadCSR( RxCtl )	& ~ BRxINTMask );
+  // See above routine for comments
+  //  WriteCSR( MacCtl, ReadCSR( MacCtl ) & ~ MXtlINTMask );
+  WriteCSR( MacTxCtl, ReadCSR( MacTxCtl ) & ~ (MTxCtlINTMask | MTxCtlEnComp));
+  WriteCSR( MacRxCtl, ReadCSR( MacRxCtl ) & ~ MRxCtlINTMask );
+  
+  /* Disable Interrupt */
+  /* first the H/W */
+#if !NO_INCLUDE_MAC_RX_INT
+  s3c4530_mask_irq( MAC_RX_IRQ);
+#endif
+  s3c4530_mask_irq( MAC_TX_IRQ);
+  s3c4530_mask_irq( BDMA_RX_IRQ);
+  s3c4530_mask_irq( BDMA_TX_IRQ);
+  /* then the logical */
+#if !NO_INCLUDE_MAC_RX_INT
+  disable_irq( MAC_RX_IRQ);
+#endif
+  disable_irq( MAC_TX_IRQ);
+  disable_irq( BDMA_RX_IRQ);
+  disable_irq( BDMA_TX_IRQ);
+
+  CHECK_ITXPTR("DisableInt")
+}
+/**********************************************************************
+ * Function Name:	EnableTxRx
+ *
+ *   Purpose:   Starts transmission and reception.
+ *   
+ *   Parameters:    MAC basePort
+ ***********************************************************************/
+static _INLINE_ void 
+EnableTxRx( void )
+{
+  /* Enable Transmission */
+  // -- Only enable the Tx when there is something to send moved 
+  //     to s3c_send_packet
+  // WriteCSR( TxCtl, (( ReadCSR( TxCtl)) | BTxEN));
+  // tx Enable AND not Tx Halt
+  WriteCSR( MacTxCtl, (( ReadCSR( MacTxCtl)) | MTxCtlTxEn) & ~MTxCtlTxHalt);
+
+  /* Enable Reception    */
+  WriteCSR( RxCtl, (( ReadCSR( RxCtl)) | BRxEN));
+  // rx Enable AND not Rx Halt
+  WriteCSR( MacRxCtl, (( ReadCSR( MacRxCtl)) | MRxCtlRxEn) & ~MRxCtlRxHalt);
+
+  CHECK_ITXPTR("EnableTxRx")
+}
+/**********************************************************************
+ * Function Name:	DisableTxRx
+ *
+ *   Purpose:   Stops transmission and reception.
+ *   
+ *   Parameters:    MAC basePort.
+ ***********************************************************************/
+static _INLINE_ void 
+DisableTxRx( void)
+{
+  /* Cancel Transmission */
+  WriteCSR( TxCtl, (( ReadCSR( TxCtl)) & ~ BTxEN));
+  // disable Tx and cause immediate halt
+  WriteCSR( MacTxCtl, (( ReadCSR( MacTxCtl)) & ~ MTxCtlTxEn) | MTxCtlTxHalt);
+  /* Cancel Reception    */
+  WriteCSR( RxCtl, (( ReadCSR( RxCtl)) & ~BRxEN));
+  // rx disable AND immediate Rx Halt
+  WriteCSR( MacRxCtl, (( ReadCSR( MacRxCtl)) & ~ MRxCtlRxEn) | MRxCtlRxHalt);
+
+  CHECK_ITXPTR("DisableTxRx")
+}
+/*************************************************************************
+ * Function Name:	Reset
+ *
+ * Purpose:	To reset the MAC.
+ *
+ * Return Value:    S3C_FAIL on failure
+ *                  S3C_SUCCESS on success
+ **************************************************************************/
+static int
+Reset( void)
+{
+  UINT32 	i = 0;
+
+  // Stop all tx / rx
+  WriteCSR( MacCtl, (( ReadCSR( MacCtl)) | MCtlHaltImm));
+  mdelay( 10);	// 10 mS
+  // reset the BDMA TX block
+  WriteCSR( TxCtl, BTxRS);
+  // reset the BDMA RX block
+  WriteCSR( RxCtl, BRxRS);
+
+  // Software reset of all MAC control and status register 
+  //   and MAC state machine
+  WriteCSR( MacCtl, MCtlReset);
+  while (MCtlReset & ReadCSR( MacCtl))
+  {
+	if (i++ >  MCtlReset_BUSY_LOOP)
+	  break;
+	mdelay( 10);	// 10 mS
+  }
+#if NET_DEBUG > 1
+  if (i >= MCtlReset_BUSY_LOOP)
+	printk( "SC3: MAC did not come out of RESET :-( \n");
+#endif
+  // setup the BDMA rx Word Alignment (must be done directly after reset
+  WriteCSR( RxCtl, BRxSetup_RESET);
+
+  CHECK_ITXPTR("Reset")
+
+  return ( S3C_SUCCESS);
+}
+/*************************************************************************
+ * Function Name:	SetupRegistersTX
+ *
+ * Purpose:	To setup the transmit register values
+ *		NOTE: We assume that only the BRxCtl register has any which needs
+ *			  to be preserved.
+ **************************************************************************/
+//static _INLINE_ void 
+static void 
+SetupRegistersTx( void)
+{
+
+  WriteCSR( TxCtl, BTxSetup);		// Buffered DMA transmit control reg
+  // setup in TxRxInit
+  // WriteCSR( TxPtr, priv->qTx.first); // Tx frame descriptor start addr
+  WriteCSR( MacTxCtl, MTxCtlSetup);	// Transmit Control
+
+  CHECK_ITXPTR("SetupRegistersTx")
+  return;
+}
+/*************************************************************************
+ * Function Name:	SetupRegistersRX
+ *
+ * Purpose:	To setup the receive register values
+ * 			NOTE: if a register has both RX and TX it's in here
+ **************************************************************************/
+//static _INLINE_ void 
+static void 
+SetupRegistersRx( void)
+{
+  UINT32	i;
+
+  // BDMA rx setup
+  WriteCSR( RxCtl,BRxSetup);	// Buffered DMA receive control reg
+  // Setup in SetupTxFDs
+  // WriteCSR( RxPtr;		/* 0x0c Rx frame descriptor start addr		*/
+  WriteCSR( RxLSz, PKT_BUF_SZ);	// Receive Frame maximum size
+  for (i = 0; i < 32; i++)
+  {
+	WriteCSR( Cam[i], 0xffffffff);		// CAM Content, set for broadcast
+  }
+  WriteCSR( CamCtl, CAMCtlSETUP);		// CAM Control - Accept anything
+  WriteCSR( MacRxCtl, MRxCtlSETUP);		// Rx Control
+  WriteCSR( MacCtl, MCtlSETUP);			// Full Duplex 100
+
+  WriteCSR( CamEn, 0x04);				// CAM Enable, third entry
+  CHECK_ITXPTR("SetupRegisterRx")
+}
+/*************************************************************************
+ * Function Name:	SetUpTxFrmPtrRegister
+ *
+ * Purpose:	tell the mac where the Tx Frames are
+ **************************************************************************/
+static _INLINE_ void
+SetUpTxFrmPtrRegister( ND dev)
+{
+  S3C_MAC * 	priv = dev->priv;
+
+  // NOTE: TxPtr doesn't care about uncached / cached (only bits 0:25)
+  WriteCSR( TxPtr, priv->qTx.first);
+}
+/*************************************************************************
+ *	Function Name:		TxRxInit
+ *
+ *   Purpose:	Set up the Ethernet to receive and transmit data.
+ *
+ *			NOTE: Check the order that things happen
+ *				It needs to be checked (too many routines) FIXME ...MaTed---
+ *
+ *   Return Value:  S3C_FAIL on failure
+ *                  S3C_SUCCESS on success
+ *					- Always Succeeds
+ **************************************************************************/
+static _INLINE_ ULONG 
+TxRxInit( ND dev)
+{
+  //  Reset( dev);
+  SetUpTxFrmPtrRegister( dev);	// do this before setting BDMA registers
+  SetupRegistersTx( );
+  SetupRegistersRx( );
+  DisableTxRx( );
+  DisableInt( );
+  // ...MaTed--- changed to always bring up the interface
+  PhyInit( dev);
+
+  CHECK_ITXPTR("TxRxInit")
+
+  return (S3C_SUCCESS);
+}
+
+
+static int
+SetMacAddr( ND dev, void * addrin)
+{
+  struct sockaddr *addr = addrin;
+
+  if (netif_running(dev))
+    return -EBUSY;
+
+  memcpy( dev->dev_addr, addr->sa_data, dev->addr_len);
+
+  return SetUpARC(dev, addrin);
+}
+/*************************************************************************
+ * Function Name:		SetUpARC
+ *
+ * Purpose:	Setup the ARC memory MAC HW address...
+ *			- NOTE Only sets up one entry - 3rd entry
+ *					- 0 and 1 and 18 are reserved for MAC Control packets
+ *
+ * Parameters:	basePort    - base address of the MAC register set
+ *				addr
+ *			    - pointer to array of 6 bytes for the MAC HW 
+ *				address
+ **************************************************************************/
+static int
+SetUpARC( ND dev, void * addrin)
+{
+  UINT32	save;
+  UCHAR	   * addr = (UCHAR *) addrin;
+
+  /* NOTE: This routine assumes little endian setup of UINT32 */
+
+  /* don't update while active */
+  save = ReadCSR( CamEn);		// we leave other bits alone (later)
+  WriteCSR( CamEn, 0x00000000);	// don't use any ARC entries
+  /* Enter Address at third entry - hard code */
+  WriteCSR( Cam[3], addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24 );
+  WriteCSR( Cam[4], (ReadCSR( Cam[4]) & 0xffff0000) | addr[4] | addr[5] << 8);
+#if 0
+  // ** NOTE you could speed this up by using a UINT32 and
+  //    a UINT16 = statement (regardless of endian), but this is clearer
+  //	...MaTed---
+  WriteCSR( Cam [2 * 6 + 0 ], addr [0]);
+  WriteCSR( Cam [2 * 6 + 1 ], addr [1]);
+  WriteCSR( Cam [2 * 6 + 2 ], addr [2]);
+  WriteCSR( Cam [2 * 6 + 3 ], addr [3]);
+  WriteCSR( Cam [2 * 6 + 4 ], addr [4]);
+  WriteCSR( Cam [2 * 6 + 5 ], addr [5]);
+#endif
+  /* Enable Third Address */
+  save |= 0x8;
+  WriteCSR( CamEn, save);
+  /* Enable ARC Compare +BCAST */
+  //  WriteCSR( basePort, ARCCtl, (ARC_CompEn | ARC_BroadAcc | ARC_StationAcc));
+  // Make it accept anything within dest
+  WriteCSR( CamCtl, CompEn | BroadAcc | GroupAcc | StationAcc);
+  return ( 0);
+}
+#ifdef ENABLE_IOCTL
+/*************************************************************************
+ * Function Name:	SetSpeed100
+ *
+ * Purpose:	To Set the MAC in 100 mode.
+ *	NOTE: The actual speed is determined by the PHY
+ *	that is connected to this MAC.
+ *	NOTE: this routine is not used - for later implemtation of IOCTL
+ *        ** routine needs check and FIXME ** ...MaTed---
+ *		  ** needs to talk to the PHY
+ **************************************************************************/
+static _INLINE_ void 
+SetSpeed100( void)
+{
+  WriteCSR( MacCtl, (( ReadCSR(MacCtl)) & MCtlLoop10) );
+}
+/*************************************************************************
+ * Function Name:	SetSpeed10
+ *
+ * Purpose:	To Set the MAC in 10 MBPS mode.
+ *	NOTE: The speed of the PHY should match this speed.
+ *	NOTE: this routine is not used - for later implemtation of IOCTL
+ *        ** routine needs check and FIXME ** ...MaTed---
+ *		  ** needs to talk to the PHY
+ **************************************************************************/
+static _INLINE_ void 
+SetSpeed10( void)
+{
+  WriteCSR( MacCtl, (( ReadCSR( MacCtl)) & ~MCtlLoop10 );
+}
+#endif	// ENABLE_IOCTL
+/************************************************************************
+ * Function Name:	InvalidateCacheLine
+ * Purpose:	Invalidate cache which contains the address
+ * 		- we reduce to start on 16 byte boundary (should own to
+ *			lower 16 byte boundary 
+ * 		- should "own" to next higher 16 byte boundary
+ *		** Using two different algorithms - one just uses the tagline
+ *		**  flushes the cache lines regardless of the tags
+ *		** The other checks the tags and only does something if it
+ *		**	matches the buffer address
+/ ***********************************************************************/
+_INLINE_ void 
+InvalidateCacheLine( UINT32 bufaddr)
+{
+  UINT32 *	TagRamPtr = (UINT32 *) CACHE_TAG_RAM;
+
+#if 1	// fastest way - intrusive
+  TagRamPtr[ 0xff & (bufaddr >> L1_CACHE_SHIFT)] = 0;
+#else
+#if 1	// preserve tags !?? FOR WHY
+  TagRamPtr[ 0xff & (bufaddr >> L1_CACHE_SHIFT)] &= 0X3FFFFFF;
+#else	// only zero if 14 bit tag matches
+{ 
+  UINT32	Tag;
+  UINT32	tagline
+
+  Tag &= 0x3fff000;
+  tagline =  0xff & (bufaddr >> L1_CACHE_SHIFT);
+  if ( (Tag >> (16 - L1_CACHE_SHIFT) == (0x3fff & TagRamPtr[ tagline ]))
+  {
+	TagRomPtr[ tagline } &= 0xbfffffff;
+  }
+  else
+  {	// checking against Set 1 tag
+	/ / / / NOTE: the  following not fixed for L1_CACHE_SHIFT / / ...MaTed---
+	if ( (Tag << 3) == (0x1fff8000 & TagRamPtr[ tagline ]))
+    {
+	  TagRomPtr[ tagline } &= 0x7fffffff;	// top bit
+	}
+  }
+#endif
+#endif
+  return;
+}
+/************************************************************************
+ * Function Name:	InvalidateBuffer
+ * Purpose:	Invalidate buffer cache
+ * 		- must start on 16 byte boundary
+ * 		- must "own" to next higher 16 byte boundary from end of buffer
+ *      NOTE: can be 32 bytes in cache line
+/ ***********************************************************************/
+_INLINE_ void 
+InvalidateBuffer( void * bufaddr, UINT length)
+{
+  // by computed goto would be optimized - for now call routine
+  UINT32 end; 
+
+  end = ((ULONG) bufaddr + length + L1_CACHE_BYTES) & ~(L1_CACHE_BYTES -1);
+  bufaddr = (void *) ((UINT) bufaddr & ~(L1_CACHE_BYTES - 1));
+  while ( (ULONG) bufaddr < end )
+  {
+    InvalidateCacheLine( (UINT32) bufaddr );
+    bufaddr += L1_CACHE_BYTES;
+  }
+  return;
+}
+/************************************************************************
+ * Function Name:	FlushCache
+ *
+ * Purpose:	Ensure no outstanding writes
+ *		- we are using write through - I'm not even sure this is 
+ *		required, but ...MaTed---
+ ***********************************************************************/
+//static _INLINE_ void 
+void 
+FlushCache(void)
+{
+#define	TEST_WRITE_FLUSH 0
+#if TEST_WRITE_FLUSH
+  unsigned long xflags;
+
+  UINT32	* ad1, * ad2, * ad3, * ad4;		// address to mod / check
+  /* NOTE: original test had 4096 as array sizes - kills kernel, but is the 
+	 proper test ...MaTed */
+  UINT32	val1[100], val2[100], val3[100], val4[100];
+  UINT32	sav1, sav2, sav3, sav4;
+
+  // NOTE: this test cannot execute from inside interrupt routine
+  local_irq_save(xflags);
+  ad1 = val1;
+  ad2 = val2;
+  ad3 = val3;
+  ad4 = val4;
+
+  sav1 = *ad1;
+  sav2 = *ad2;
+  sav3 = *ad3;
+  sav4 = *ad4;
+
+  *((UINT32 *) (SYSCFG)) &= ~WriteBufferEn;	// bit off
+
+  ASSERT( sav1 == *ad1);
+  ASSERT( sav2 == *ad2);
+  ASSERT( sav3 == *ad3);
+  ASSERT( sav4 == *ad4);
+
+  *((UINT32 *) (SYSCFG)) |= WriteBufferEn;	// bit on
+
+  ASSERT( sav1 == *ad1);
+  ASSERT( sav2 == *ad2);
+  ASSERT( sav3 == *ad3);
+  ASSERT( sav4 == *ad4);
+
+  local_irq_restore(xflags);
+#else
+  *((UINT32 *) (SYSCFG)) &= ~WriteBufferEn;	// bit off
+  *((UINT32 *) (SYSCFG)) |= WriteBufferEn;	// bit on
+
+#endif
+}
+/************************************************************************
+ * The following routines do the work
+ ************************************************************************/
+/************************************************************************
+ * Check for a network adaptor of this type, and return '0' iff one exists.
+ *  - we just allocate them the number of times I'm called
+ *  NOTE: we ignore the following values for base_addr ...MaTed
+ * If dev->base_addr == 0, probe all likely locations.
+ * If dev->base_addr == 1, always return failure.
+ * If dev->base_addr == 2, allocate space for the device and return success
+ * (detachable devices only).
+ ************************************************************************/
+int __init 
+s3c_probe( ND dev)
+{
+  SMEM_CHECK("****** S3C probe ***:");
+  // check if all allocated
+  if (numS3cMacs >= ETH_MAXUNITS)
+	return (-ENODEV);
+  // SET_MODULE_OWNER( dev);
+  dev->irq = BDMA_RX_IRQ;				// just put in 1 of four
+  dev->base_addr = (UINT32) baseAddr;	// just put start base addr
+
+  if ( check_mem_region( dev->base_addr, MAC_IO_EXTENT))
+    return (-ENODEV);
+  if ( s3c_probe1( dev) == S3C_SUCCESS)
+  {
+	numS3cMacs++;					// increment the number of s3cs found
+	SMEM_CHECK("S3C Leave probe:");
+    return S3C_SUCCESS;
+  }
+  return (-ENODEV);
+}
+/************************************************************************
+ * This routine initializes all the vars in dev and private areas
+ ************************************************************************/
+static int
+s3c_InitVars( ND dev)
+{
+  S3C_MAC * priv = dev->priv;			// initializtion will be overwritten 1st time
+
+  //  SMEM_CHECK("****** S3C Entering InitVars ***:");
+  /* Initialize the device structure. */
+  if ( dev->priv == NULL)
+  {
+    dev->priv = kmalloc( sizeof( S3C_MAC), GFP_KERNEL);
+    if ( dev->priv == NULL)
+      return ( -ENOMEM);
+#if DEBUG_INCTXPTR
+	PrivPtr = (S3C_MAC *) dev->priv;
+#endif
+    s3cInitPriv( dev);	// initialize the Mac Private structure
+    priv = (S3C_MAC *) dev->priv;
+    spin_lock_init( &priv->lock);
+  }
+  dev->open				= &s3c_open;
+  dev->stop				= &s3c_close;
+  dev->hard_start_xmit	= &s3c_send_packet;
+  dev->get_stats		= &s3c_get_stats;
+  dev->set_multicast_list = &set_multicast_list;
+
+  dev->tx_timeout		= &s3c_tx_timeout;
+  dev->watchdog_timeo	= MY_TX_TIMEOUT; 
+  dev->set_mac_address	= &SetMacAddr;
+  /*
+   * Fill in the rest of the fields of the device structure 
+   * with ethernet values. 
+   */
+#if	ENABLE_DESTRUCTOR 
+  priv->destructor 	= &s3cDestructor;
+#endif
+  /*
+   * The following can be implemented but hasn't been
+   */
+  //  dev->do_ioctl		= &s3c_do_ioctl;
+  SMEM_CHECK("****** S3C Exiting InitVars ***:");
+  return ( S3C_SUCCESS);
+}
+/************************************************************************
+ * This is the real probe routine. Linux has a history of friendly device
+ * probes on the ISA bus. A good device probes avoids doing writes, and
+ * verifies that the correct device exists and functions.
+ * -- This version is hard codedto just find the one hard coded address
+ *		It will only be called once.
+ * NOTE: now gets HW address from external routine. If there is no
+ *  bootloader, then this routine must still return a HW address ...MaTed ---
+ ************************************************************************/
+static int __init 
+s3c_probe1( ND dev)
+{
+  int 	    i;
+  static unsigned version_printed = 0;
+  char *	ptr;
+  int 		rc;		//return code
+  S3C_MAC *	priv;
+
+  if (net_debug  &&  version_printed++ == 0)
+    printk( KERN_INFO "%s", version);
+
+  printk( KERN_INFO "\n%s: %s found at %08x, ", dev->name, cardname, 
+		  (UINT) baseAddr);
+  /* Fill in the 'dev' fields. */
+
+  ptr = get_MAC_address("dev0");
+
+  memcpy( dev->dev_addr, ptr, NUM_HW_ADDR);
+  for ( i = 0; i < NUM_HW_ADDR; i++)
+  {
+    printk("%02x.", dev->dev_addr[ i]);
+  }
+  printk( "\n");
+  dev->addr_len = NUM_HW_ADDR;
+  if ( s3c_request_irq_mem( dev))
+  {
+	return ( -EAGAIN);
+  }
+  Reset( );			// Force initial conditions
+  DisableInt( );
+  ether_setup( dev);
+  DisableInt( );
+  SetupRegistersTx( );
+  SMEM_CHECK("****** S3C-between setupTx and Rx Reg ***:");
+  SetupRegistersRx( );
+  SMEM_CHECK("****** S3C-after Setup Rx registers ***:");
+  DisableTxRx( );
+  DisableInt( );
+  //  return( s3c_InitVars( dev));
+  if (S3C_SUCCESS != (rc = s3c_InitVars( dev)))
+	return( rc);
+  // might be a bit redundant with the initial probe -- But ...
+  // Zero out the stats
+  priv = dev->priv;		// wasn't init'd before this
+  memset( &priv->stats, 0, sizeof( struct net_device_stats ));
+  return( S3C_SUCCESS );
+}
+/*******************************************
+ * Blocks the multiple requests to set IRQ
+ *******************************************/
+static int	run_request = 0;
+/**********************************************************************
+ * s3c_request_irq_mem - routine to set the interrupt vectors and mem
+ **********************************************************************/
+static _INLINE_ int
+s3c_request_irq_mem( ND dev)
+{
+  int		 	rc;
+
+  if (run_request)
+	return (S3C_SUCCESS);
+  /*
+   * The ethernet MACS have fixed interrupts, allocate the interrupt
+   * vector now. There is no point in waiting since no other device
+   * can use the interrupt, and this marks the irq as busy. Jumpered
+   * interrupts are typically not reported by the boards. MAC 0 is 
+   * fixed at IRQ 10, MAC 1 is fixed IRQ11
+   *
+   * The S3C4530A allocates 4 interrupts to the MAC, do all four
+   */
+
+#if !NO_INCLUDE_MAC_RX_INT		// skip this one - useless ...MaTed---
+  if ( (rc = request_irq( MAC_RX_IRQ, &s3c_MacRx, 0, cardname, dev)))
+  {
+    printk( KERN_WARNING "%s: unable to get IRQ %d (irqval=%d).\n",
+	    dev->name, MAC_RX_IRQ, rc);
+    return ( -EAGAIN);
+  }
+#endif
+  if ( (rc = request_irq( MAC_TX_IRQ, &s3c_MacTx, 0, cardname, dev)))
+  {
+    printk( KERN_WARNING "%s: unable to get IRQ %d (irqval=%d).\n",
+	    dev->name, MAC_TX_IRQ, rc);
+#if !NO_INCLUDE_MAC_RX_INT		// skip this one - useless ...MaTed---
+	free_irq( MAC_RX_IRQ, dev);
+#endif
+    return ( -EAGAIN);
+  }
+  if ( (rc = request_irq( BDMA_RX_IRQ, &s3c_BdmaRx, 0, cardname, dev)))
+  {
+    printk( KERN_WARNING "%s: unable to get IRQ %d (irqval=%d).\n",
+	    dev->name, BDMA_RX_IRQ, rc);
+#if !NO_INCLUDE_MAC_RX_INT		// skip this one - useless ...MaTed---
+	free_irq( MAC_RX_IRQ, dev);
+#endif
+	free_irq( MAC_TX_IRQ, dev);
+    return ( -EAGAIN);
+  }
+  if ( (rc = request_irq( BDMA_TX_IRQ, &s3c_BdmaTx, 0, cardname, dev)))
+  {
+    printk( KERN_WARNING "%s: unable to get IRQ %d (irqval=%d).\n",
+	    dev->name, BDMA_TX_IRQ, rc);
+#if !NO_INCLUDE_MAC_RX_INT		// skip this one - useless ...MaTed---
+	free_irq( MAC_RX_IRQ, dev);
+#endif
+	free_irq( MAC_TX_IRQ, dev);
+	free_irq( BDMA_RX_IRQ, dev);
+    return ( -EAGAIN);
+  }
+  /* Grab the region so that no one else tries to probe our ioports. */
+  if (! request_mem_region( (UINT32) baseAddr, sizeof(CSR), cardname))
+  {
+    printk( KERN_WARNING "%s: unable to get memory/io address region %x\n",
+	    dev->name, (UINT) baseAddr);
+#if !NO_INCLUDE_MAC_RX_INT		// skip this one - useless ...MaTed---
+	free_irq( MAC_RX_IRQ, dev);
+#endif
+	free_irq( MAC_TX_IRQ, dev);
+	free_irq( BDMA_RX_IRQ, dev);
+	free_irq( BDMA_TX_IRQ, dev);
+    return (-EAGAIN);
+  }
+  run_request = 1;
+  return (rc);
+}
+/**********************************************************************
+ * s3c_release_irq_mem - routine to release the interrupt vectors and mem
+ **********************************************************************/
+static _INLINE_ int
+s3c_release_irq_mem( ND dev)
+{
+  if (run_request == 0)	/* did we allocate them yet */
+	return( S3C_SUCCESS);
+
+  /* release all the interrupts */
+#if !NO_INCLUDE_MAC_RX_INT
+  free_irq( MAC_RX_IRQ, dev);
+#endif
+  free_irq( MAC_TX_IRQ, dev);
+  free_irq( BDMA_RX_IRQ, dev);
+  free_irq( BDMA_TX_IRQ, dev);
+
+  /* Release the region so that some else (including ourselves) can have it */
+  release_mem_region( (UINT32) baseAddr, sizeof(CSR) );
+
+  run_request = 0;	/* someone else can use it now */
+  return ( S3C_SUCCESS);
+}
+/***********************************************************************
+ * log transmit MAC errors - status register is the same as the
+ *		status in the FD block - juse the FD.status (multiple packets)
+ *	returns S3C_FAIL if error
+ *			S3C_SUCCESS if status did not show error
+ ***********************************************************************/
+static _INLINE_ int 
+ s3cLogTxMACError( ND dev, int status)
+{
+  S3C_MAC * 	priv = dev->priv;
+
+  priv->stats.collisions += status & TxCollCnt_mask;
+  if (0 == (status 
+	    & (TxExColl + TxLateColl + TxDefer + TxPaused + TxMaxDefer + 
+		   TxHalted + TxNCarr + TxPar + TxUnder + TxSQErr)))
+  {
+    return ( S3C_SUCCESS);
+  }
+  priv->stats.tx_errors++;				// we have an error
+  // now log specific error
+  if ( status & (TxExColl))
+	   priv->stats.collisions += 16;	// at least 16 collisions occurred
+  if ( status & (TxMaxDefer + TxPaused + TxHalted + TxExColl + TxHalted))
+    priv->stats.tx_aborted_errors++;
+  if ( status & (TxLateColl))
+    priv->stats.tx_window_errors++;
+  if ( status & TxNCarr)
+    priv->stats.tx_carrier_errors++;
+  if ( status & (TxPar + TxUnder))	// Underrun is here??
+    priv->stats.tx_fifo_errors++;
+  if ( status & (TxSQErr + TxDefer))
+    priv->stats.tx_heartbeat_errors++;
+#if 0	// there are circumstances when the  transmitter has to be restarted
+  if ( status & (TX_PARITY + ???))
+	// restart transmitter
+#endif
+  return ( S3C_FAIL);
+}
+/***********************************************************************
+ * log receive BDMA errors
+ *	returns S3C_FAIL if error
+ *			S3C_SUCCESS if status did not show error
+ * - status passed should be from the F Descriptor
+ ***********************************************************************/
+static _INLINE_ int 
+s3cLogRxBdmaError( ND dev, int status)
+{
+  S3C_MAC * 	priv = dev->priv;
+
+
+#if 0
+  if ( 0 != status & RxSGood)
+#else   // Alternately we could check the errors
+  if (0 == (status 
+	    & (RxS_OvMax + RxS_AlignErr + RxS_CrcErr + RxS_Overflow +
+		   RxS_LongErr + RxS_RxPar + RXS_RxHalted )))
+#endif
+  {
+    return ( S3C_SUCCESS);
+  }
+  priv->stats.rx_errors++;
+  // now log specific errors
+  if ( status & ( RxS_OvMax + RxS_LongErr ))
+    priv->stats.rx_length_errors++;
+#if 0
+// NOTE: this is an error which should get updated in the RX BDMA interrupt
+  if ( status & ())
+    priv->stats.rx_over_errors++;
+#endif
+  if ( status & ( RxS_CrcErr ))
+    priv->stats.rx_crc_errors++;
+  if ( status & ( RxS_AlignErr ))
+    priv->stats.rx_frame_errors++;
+  if ( status & ( RxS_Overflow + RxS_RxPar ))
+    priv->stats.rx_fifo_errors++;
+  if ( status & ( RXS_RxHalted ))	// may be other updaters to this
+    priv->stats.rx_missed_errors++;
+  return ( S3C_FAIL);
+}
+/***********************************************************************
+ * Transmit timeout
+ *	Kernel calls this routine when a transmit has timed out
+ ***********************************************************************/
+static void 
+s3c_tx_timeout( ND dev)
+{
+  S3C_MAC *		priv = dev->priv;
+  //  UINT32		basePort = dev->base_addr;
+  UINT32		MacStatus  = ReadCSR( MacTxStat);
+
+#if (NET_DEBUG > 3)
+  UINT32		BDMAStatus  = ReadCSR( BdmaStat);
+
+  printk( KERN_ERR "%s: transmit timed out: NUM= %ld, MacTXStatus=0x%08lX ",
+		  dev->name, priv->qTx.num, MacStatus );
+  printk( KERN_ERR "MacBDMAStatus=0x%08lX ", BDMAStatus );
+
+#endif
+  /********************************************************
+NOTE: This section needs a lot more work ...MaTed--- FIXME
+  ********************************************************/
+  // We are going to reset the MAC
+  //  - all packets - both rx and tx may be discarded
+  //  - have to change logic to allow errors to stay around
+
+  priv->stats.tx_errors++;
+  (void) s3cLogTxMACError( dev, MacStatus);
+  //  (void) s3cLogTxBDMAError( dev, BDMAStatus);
+
+  // FIXME ...MaTed--- the close  / open has not been checked
+  s3c_close( dev);
+
+  s3c_open( dev);
+  // Kick the MAC to check if there is something to send
+  // - this is unnecessary, unless we add code to only do the
+  //   close/open every 2nd or third time ...MaTed
+  //WriteCSR( DMACtl, ReadCSR( DMACtl) | DMA_CTL_TxWakeUp);
+
+  /* If we have space available to accept new transmit
+   * requests, wake up the queueing layer.  This would
+   * be the case if the chipset_init() call above just
+   * flushes out the tx queue and empties it.
+   *
+   * If instead, the tx queue is retained then the
+   * netif_wake_queue() call should be placed in the
+   * TX completion interrupt handler of the driver instead
+   * of here.
+   */
+  if (!txFull( dev))
+    netif_wake_queue( dev);
+  dev->trans_start = jiffies;		// reset the start time
+  return;
+}
+/************************************************************************
+ * initialize all the data in private area
+ ************************************************************************/
+static _INLINE_ int 
+s3cInitPriv( ND dev )
+{
+  S3C_MAC	* priv 	= dev->priv;
+  RET_CODE	  rc;
+
+  memset( priv, 0, sizeof( S3C_MAC));
+  
+  /* setup the MAC HW address */
+  SetUpARC( dev, dev->dev_addr);
+
+  // **Enhancement FIXME-pickup duplex and speed from commandline ...MaTed---
+  // - if you want to force, userland force later
+  // priv->phySpeed = 2;		// Force 100
+  // priv->phySpeed = 0;		// automatic MII mode force speed = 10
+  priv->phySpeed = 3;			// automatic MII mode 
+  //  priv->phySpeed = 1;		// Force 10 Mb/s endec
+  WriteCSR( MacCtl, (ReadCSR( MacCtl) & ~(MCtlMII_Off + MCtlLoop10))
+			| (priv->phySpeed << MCtl10Shift1)
+			| (priv->phySpeed << MCtl10Shift2));
+
+  /* Mac CNTL Full Duplex */
+  priv->phyDpx = 1;				/* Full Duplex */
+  //priv->phyDpx = 0;		/* Half Duplex, if MII_Conn is High?? */
+  WriteCSR( MacCtl, (ReadCSR( MacCtl) & ~ MCtlFullDup )
+			| priv->phyDpx << MCtlFullDupShift);
+  /*
+   * NOW set up the S3c MAC struct
+   */
+  if ((rc = SetupTxFDs( dev)))
+    return (rc);
+  SMEM_CHECK("****** S3C Between SetupTxFDs and RxFDs ***:");
+  if ((rc = SetupRxFDs( dev)))
+    return (rc);
+  // no error
+  return ( S3C_SUCCESS);
+}
+/************************************************************************
+ * Open/initialize the board. This is called (in the current kernel)
+ * sometime after booting when the 'ifconfig' program is run.
+ *
+ * This routine should set everything up anew at each open, even
+ * registers that "should" only need to be set once at boot, so that
+ * there is non-reboot way to recover if something goes wrong.
+ ***********************************************************************/
+static int
+s3c_open( ND dev)
+{
+  //  S3C_MAC *priv = (S3C_MAC *) dev->priv;
+  //  UINT		basePort = dev->base_addr;
+  RET_CODE	rc;
+
+#if 0	// why doesn't this get called during ifconfig ....MaTed---
+  printk( KERN_INFO "\n******** s3c_open called ********** \n");
+#endif
+#if 0
+  // moved this section from the probe routine
+  Reset( );			// Force initial conditions
+  DisableInt( );
+  ether_setup( dev);
+  DisableInt( );
+  SetupRegistersTx( );
+  SMEM_CHECK("****** S3C-between setupTx and Rx Reg ***:");
+  SetupRegistersRx( );
+  SMEM_CHECK("****** S3C-after Setup Rx registers ***:");
+  DisableTxRx( );
+  DisableInt( );
+  s3c_InitVars( dev);
+#endif
+  //  SetupRegistersTx( );
+  //SetupRegistersRx( );
+  //DisableTxRx( );
+  //DisableInt( );
+  /*
+   * This is used if the interrupt line can turned off (shared).
+   * - Can we share? - might as well register
+   */
+  //  if ( s3c_request_irq_mem( dev))
+  rc = s3c_request_irq_mem( dev);
+  TDEBUG("S3C_OPEN: request_irq_mem rc=%d\n", rc);
+  if (rc)
+  {
+	printk( KERN_ERR "S3C4530: Cannot get irq/mem rc=%d\n", rc);
+    return -EAGAIN;
+  }
+
+  /*
+   * Always allocate the DMA channel after the IRQ,
+   * and clean up on failure. NO DMA used
+   */
+  //  Reset( dev);		// reset the MAC
+  // We are leaving priv intact
+  //  if (S3C_SUCCESS != (rc = s3c_InitVars( dev)))
+  //    return (rc);
+  /* Reset the hardware here. Don't forget to set the station address. */
+  if (S3C_SUCCESS != (rc = TxRxInit( dev)))
+  {
+	printk( KERN_ERR "S3C4530: Phys init failed \n");
+	return (rc);
+  }
+  // The following is done in TXRXInit
+  //  SetupRegistersTx( dev);
+  //  SetupRegistersRx( dev);
+  //  DisableTxRx( dev->base_addr);
+  //  SetUpTxFrmPtrRegister( dev);
+  //  PhyInit( dev);
+  // let the controller go again
+
+  EnableTxRx( );
+  EnableInt( );
+
+  //  priv->open_time = jiffies;
+  /* We are now ready to accept transmit requeusts from
+   * the queueing layer of the networking.
+   */
+  netif_start_queue( dev);
+
+  return S3C_SUCCESS;
+}
+/************************************************************************
+ This will only be invoked if your driver is _not_ in XOFF state.
+ * What this means is that you need not check it, and that this
+ * invariant will hold if you make sure that the netif_*_queue()
+ * calls are done at the proper times.
+ ************************************************************************/
+static int s3c_send_packet( struct sk_buff *skb, ND dev)
+{
+  S3C_MAC 		  *	priv = dev->priv;
+  //  int 				basePort = dev->base_addr;
+  //  short			length;
+  UCHAR		   	  *	buf = skb->data;
+  BPTR *			bptr = &priv->qTx;
+  TxFDS *			fdbdPtr;
+#if (NET_DEBUG > 4)
+  TxFDS *			tempPtr;
+#endif
+  UINT32			temp;
+
+  // make minimum length for TX
+  //  Don't need this, the controller does it for me
+  //length = ETH_MIN_LEN < skb->len ? skb->len : ETH_MIN_LEN;
+
+  /* If some error occurs while trying to transmit this
+   * packet, you should return '1' from this function.
+   * In such a case you _may not_ do anything to the
+   * SKB, it is still owned by the network queueing
+   * layer when an error is returned.  This means you
+   * may not modify any SKB fields, you may not free
+   * the SKB, etc.
+   */
+#if (NET_DEBUG > 4)
+  /* Paranoid check to see if there is room - by pointers */
+  /* ?? I don't need this inside */
+  if (bptr->first == ((TxFDS *) (bptr->last))->fd.FDNext)
+  {
+    printk( KERN_ERR "TX overflow on %s\n", dev->name);
+	// MAKE Sure transmitter was enabled -- maybe that will clear it up 
+	if (! ((temp = ReadCSR( TxCtl)) & BTxEN))
+	  WriteCSR( TxCtl, temp | BTxEN);
+	WriteCSR( MacTxCtl, ReadCSR( MacTxCtl) | MTxCtlTxEn);
+    return ( -1);
+  }
+#endif
+#if (NET_DEBUG > 4)
+  /* another paranoid check (next should be owned by system */
+  tempPtr = (TxFDS *) (((TxFDS *) bptr->last)->fd.FDNext);
+  if (((UINT32) ((TxFDS *) UnCache((UINT32)tempPtr))->fd.FDNext) & OWNERSHIP)
+  {
+    printk( KERN_ERR "TX ownership problem on %s\n", dev->name);
+
+    return (-1);
+  }
+#endif
+#if (NET_DEBUG > 5)
+  printk( KERN_ERR "S3C_SEND: 0%08X Skb length %d\n", 
+		  (unsigned int) dev->base_addr, (unsigned int) skb->len);
+  //  {
+	//	int i;
+	//	printk( KERN_ERR "S3C_SEND: Skb length %d\n - data=", skb->len);
+	//	for ( i = 0; i < skb->len; i++)
+	//	{
+	//	  printk( KERN_ERR "[%02x] ", skb->data[ i]);
+	//	}
+	//	printk( KERN_ERR "\n");
+  //  }
+#endif
+#if (NET_DEBUG > 3)
+  ASSERT( atomic_read( &skb->users) == 1);
+#endif
+#if 0	//we don't invalidate the cache for writes only for reads
+  InvalidateBuffer( buf, skb->len);
+#endif
+  /* This is the most common case for modern hardware.
+   * The spinlock protects this code from the TX complete
+   * hardware interrupt handler.  Queue flow control is
+   * thus managed under this lock as well.
+   */
+  spin_lock_irq( &priv->lock);
+
+  fdbdPtr = (TxFDS *) bptr->last;
+  // move to next buffer in list
+  bptr->last = (void *) ((UINT32)(fdbdPtr->fd.FDNext));
+
+  fdbdPtr->fd.FDLength = skb->len;
+
+  fdbdPtr->fd.FDModes	= TxWidSetup;		// set widget bits (pg 7-18)
+  //fdbdPtr->fd.FDModes = TxWidIE | TxWidLITTLE | TxWidINC;
+
+  fdbdPtr->skb = skb;
+#if (NET_DEBUG > 3)
+  ASSERT( atomic_read( &skb->users) == 1);
+#endif
+  bptr->num++;				// added one buffer  
+
+  // Pass Control and buffer address
+  fdbdPtr->fd.FDDataPtr = (UCHAR *) ((((UINT32) buf) - 2 )| OWNERSHIP);
+  FlushCache();				// just in case
+  // Let the MAC know there is something to send (in case it stopped )
+  // ...Note the check is from example code (why?), extra comp is for compliler
+  if (! ((temp = ReadCSR( TxCtl)) & BTxEN))
+	WriteCSR( TxCtl, temp | BTxEN);
+  WriteCSR( MacTxCtl, ReadCSR( MacTxCtl) | MTxCtlTxEn);
+  dev->trans_start = jiffies;
+
+  TxPktCompletion( dev );
+
+  /* If we just used up the very last entry in the
+   * TX ring on this device, tell the queueing
+   * layer to send no more.
+   */
+  if (txFull( dev))
+  {
+    netif_stop_queue( dev);
+	// turn on tx completion interrupt
+	WriteCSR( MacTxCtl, ReadCSR( MacTxCtl ) | MTxCtlEnComp );
+  }
+
+  /* When the TX completion hw interrupt arrives, this
+   * is when the transmit statistics are updated.
+   */
+  spin_unlock_irq( &priv->lock);
+
+  return 0;
+}
+/************************************************************************
+ * This handles TX complete events posted by the MAC portion of the
+ * device via interrupts.
+ ************************************************************************/
+void s3c_MacTx( int irq, void *dev_id, struct pt_regs * regs)
+{
+  ND 				dev = dev_id;
+  S3C_MAC *			priv = dev->priv;
+
+  /* This protects us from concurrent execution of
+   * our dev->hard_start_xmit function above.
+   */
+  spin_lock( &priv->lock);
+
+  TxPktCompletion( dev );
+
+  /* If we had stopped the queue due to a "tx full"
+   * condition, and space has now been made available,
+   * wake up the queue.
+   **** Since we alway do a netif_wake_queue in the interrupt routine
+   ****  whats this for??? ...MaTed--- (it's in the skeleton)
+   */
+#if 1 	// since we always call netif_wake_queue WHY?
+  if ( netif_queue_stopped( dev) && ! txFull( dev))
+  {
+	netif_wake_queue( dev);
+	// turn off tx completion interrupt
+	WriteCSR( MacTxCtl, ReadCSR( MacTxCtl ) & ~MTxCtlEnComp );
+  }
+#endif
+  spin_unlock( &priv->lock);
+  FlushCache();
+}
+/************************************************************************
+ * Helper routine to collect stats on tx completion and release skbs
+ * MUST be called with spin_lock already invoked
+ ************************************************************************/
+static _INLINE_ void
+TxPktCompletion( ND dev)
+{
+  S3C_MAC *			priv = dev->priv;
+  BPTR *			txPtr;
+  TxFDS *			UtxPtrFirst;
+  UINT32			status;
+  struct sk_buff *	skb;
+  UINT32			S3cTxPtr;
+  UINT16	  		MissedErrorCnt;
+
+  txPtr = &priv->qTx;
+  UtxPtrFirst = (TxFDS *) (UnCache (txPtr->first));
+  // set the point where the Mac transmit Pointer is at - don't try to 
+  //  catch the next one "going" to happen
+  S3cTxPtr = UnCache( ReadCSR( TxPtr));
+
+  SINT(" MTx:stat", ((int)  UtxPtrFirst->fd.FDStat));
+  //  SINT(" Mac Tx interrupt: TxPtr", ((int) S3cTxPtr ));
+  while ((UINT32) UtxPtrFirst != S3cTxPtr)	// It's possible that there 
+											//  is nothing to send
+  {
+	/*** Only in here if MAC processed at least one packet */
+    // checks to see if there was an error as well
+    status = (UINT32)  UtxPtrFirst->fd.FDStat;
+	if (S3C_SUCCESS == s3cLogTxMACError( dev, status))
+	{
+	  skb = ((TxFDS*)(txPtr->first))->skb;
+	  priv->stats.tx_bytes += skb->len;	// total bytes transmitted
+	  // NOTE: only good packets were transmitted (whereas rx can get bad)
+	  priv->stats.tx_packets++;			// total packets transmitted
+	}
+	else
+	{
+	  // a tx error of some kind occurred
+      priv->stats.tx_errors++;	// could/should move this into routine
+	  // clear EMISSCNT register , by read (example code)
+	  MissedErrorCnt = ReadCSR( MissCnt);
+	  SetupRegistersTx( );		// force Tx registers if error
+	}
+	/*
+	 * The following stuff we have to do regardless if the packet
+	 *	transmission had errors or not
+	 */
+	// update the number of collisions
+	priv->stats.collisions += ReadCSR( MacTxStat) & MTxStTxColl;
+	// Clearing parts of the FD structure (probably not needed ??? )
+	UtxPtrFirst->fd.FDModes = 0x0;		// turn off the Mode bits
+	UtxPtrFirst->fd.FDLength = 0x0;		// turn off the Length
+	UtxPtrFirst->fd.FDStat = 0x0;		// turn off the Status bits
+	// get pointer to skb where we saved it
+	skb = UtxPtrFirst->skb;
+#if (NET_DEBUG > 4)
+	ASSERT( atomic_read( &skb->users) == 1);
+#endif
+#if (NET_DEBUG > 5)
+	if (atomic_read( &skb->users) != 1)
+	{
+	  printk("SKB:%08x, txPtrFirst:%08x, users:%x\n",
+			 (UINT32) skb, (UINT32) UtxPtrFirst, (UINT32) skb->users);
+	}
+#endif
+	dev_kfree_skb_irq (skb);		// release it regardless
+	// Move on to the next in the list
+	txPtr->first = (void *) ((TxFD *)(txPtr->first))->FDNext;
+	FlushCache();
+	UtxPtrFirst = (TxFDS *) (UNCACHE_ADDR | (UINT32) (txPtr->first));
+	txPtr->num--;
+  }
+}
+/************************************************************************
+ * This handles TX complete events posted by the BDMA portion of the
+ * device via interrupts.
+ * - includes the following
+ *	- Sent all frames (stopped by owner bit)
+ *		- it would be nice to use this interrupt rather than the MAC "Send"
+ *		per packet, but error status and busy cause probs 
+ *		- the interrupt should be disabled serves no purpose
+ *		- two parts to this, we disable the interrupt (see EnableInt )
+ *		but enable the stop (no skip frame)
+ *	- Interrupt on control packet after MAC sends
+ *		- we don't currently send control packets, so this int is never
+ *		envoked.
+ *		- we will leave it enabled though
+ *	- Null List Interrupt
+ *		- this is bad - should never happen
+ *		- enabled as debug tool
+ *	- Tx Buffer Empty
+ *		- leaving this off too
+ ************************************************************************/
+void s3c_BdmaTx( int irq, void *dev_id, struct pt_regs * regs)
+{
+  ND 		dev = dev_id;
+  S3C_MAC *	priv = dev->priv;
+  UINT32	status;
+
+  SINT("BTx:Stat", ((int) ReadCSR(BdmaStat)) );
+  CHECK_ITXPTR("EnableInt");
+  /* This protects us from concurrent execution of
+   * our dev->hard_start_xmit function above.
+   */
+  spin_lock( &priv->lock);
+
+  // checks to see if there was an error as well
+  status = ReadCSR( BdmaStat);
+  WriteCSR( BdmaStat, status & 0xFFFF0000);	// From example code (clear all)
+  if ( status & BTxEmpty )
+  {
+	printk( "%s: Invalid interrupt! Transmit Buffer Empty \n", dev->name);
+  } else if (status & BTxNO )
+  {
+	printk( "%s: Invalid interrupt! No owner for TX buffer [0x%08x]\n",
+			dev->name, ((int) ReadCSR( TxPtr)));
+  } else if (status & BTxNL )
+  {
+	printk( "%s: Invalid interrupt! Transmit Null List \n", dev->name);
+  } else if (status & BTxCCP )
+  {
+	printk( "%s: Invalid interrupt! Control Packet Sent \n", dev->name);
+  }
+  spin_unlock( &priv->lock);
+}
+/************************************************************************
+ * We have a good packet(s), get it/them out of the buffers.
+ * - we take both BL and FDA from the MAC.first
+ *   - move them to the front.last
+ *	 - buffer is stripped off, added to skb head, skb address stored in ??
+ *	- continue while MAC.first != MAC.last
+ * 	- other things to check / do
+ *		- ensure all four entries are set to SYS_OWNS_xx
+ ************************************************************************/
+#if !NO_INCLUDE_MAC_RX_INT
+static void
+s3c_MacRx( int irq, void *dev_id, struct pt_regs * regs)
+{
+  ND 				dev 	= dev_id;
+  UINT				status;
+
+  status = ReadCSR( MacRxStat);
+  SINT("MRx: Stat", ((int) status) );
+
+  if (status & MRxStGood)
+	return;
+
+  if ( status & (MRxStAlignErr | MRxStCRCErr | MRxStOverflow
+				 | MRxStLongErr | MRxStRxPar | MRxStRxHalted))
+  {
+#if NET_DEBUG
+	printk( "%s: MAC Rx Error: 0x%x\n", dev->name, status);
+#endif
+  }
+  return;
+}
+#endif
+/************************************************************************
+ * BDMA receive interrupt - special conditions
+ ************************************************************************/
+static void
+s3c_BdmaRx( int irq, void *dev_id, struct pt_regs * regs)
+{
+  ND		dev 	= dev_id;
+  S3C_MAC *	priv 	= (S3C_MAC *)dev->priv;
+  UINT32	status;
+  UINT32	bdmaStatus;
+
+  UINT 				boguscount = RX_NUM_FD / 4;	// set to one quarter 
+												//  of buffers - was 10
+  BPTR *			Rx			= &priv->qRx;	// is & extraneous?
+  BPTR *			RxWait		= &priv->qRxWait;
+  struct sk_buff *	skb			= NULL;	 // initialize just to get rid 
+										//  of warning
+  UINT				len;
+  UINT32			MacRxPtr;
+  RxFD *			nextFirstPtr;
+  UINT32			temp;
+
+  // Rx First
+#define FdFirst 	((RxFDS *) ( Rx->first))
+  // Rx Last
+#define FdLast 		((RxFDS *) ( Rx->last))
+  // Wait first - when skb cannot be filled now
+#define FdWaitFirst ((RxFDS *) ( RxWait->first))
+  // Wait last
+#define FdWaitLast 	((RxFDS *) ( RxWait->last))
+
+  // UnCached versions
+  // Rx First
+#define UFdFirst 		((RxFDS *) ( UnCache( (UINT32) Rx->first)))
+  // Rx Last
+#define UFdLast 		((RxFDS *) ( UnCache( (UINT32) Rx->last)))
+  // Wait first - when skb cannot be filled now
+#define UFdWaitFirst 	((RxFDS *) ( UnCache( (UINT32) RxWait->first)))
+  // Wait last
+#define UFdWaitLast 	((RxFDS *) ( UnCache( (UINT32) RxWait->last)))
+
+  SINT("BRx: Stat", ((int) ReadCSR( BdmaStat)) );
+  /* This protects us from concurrent execution of
+   * our dev->hard_start_xmit function above.
+   */
+  spin_lock( &priv->lock);
+  MacRxPtr = UnCache( ReadCSR( RxPtr));
+  bdmaStatus = ReadCSR( BdmaStat);
+
+  //  SINT(" Mac Rx interrupt: First Stat", ((int) UFdFirst->fd.FDStat));
+
+  while (MacRxPtr != (UINT32) UFdFirst)
+  {
+	// checks to see if there was an error as well
+	if ( bdmaStatus & BRxNL )
+    {
+	  printk( "%s: Invalid interrupt! Rx dma Pointer is NULL\n", dev->name);
+	  WriteCSR( BdmaStat, bdmaStatus | BRxNL);	// clear status register
+
+	  // Serious error -- needs a few things reset 
+	  // -- Is this too much though ....MaTed---
+	  TxRxInit( dev);
+	  EnableTxRx( );
+	  EnableInt( );
+	  break;
+	} else if (bdmaStatus & BRxNO )
+	{
+	  printk( "%s: Invalid Interrupt! Not owner of RX buffer \n", dev->name);
+	  WriteCSR( BdmaStat, bdmaStatus | BRxNO);	// clear status register
+	  SetupRegistersRx( );	// Is this enough to recover ...MaTed---
+	  break;
+	} else if (bdmaStatus & BRxMSO )
+    {
+	  printk( "%s: Invalid interrupt! Rx frame bigger than buffer\n", 
+			  dev->name);
+	  WriteCSR( BdmaStat, bdmaStatus | BRxMSO);	// clear status register
+	  // still have to do something to the data structures
+	  //  I will assume that some other error in the FD status will flag
+#if 0
+	} else if (bdmaStatus & BRxStEmpty )
+    {
+	  printk( "%s: Invalid interrupt! Rx Buffer Empty\n", dev->name);
+#endif
+	}
+	// NOW we deal with the FD stuff
+    status = UFdFirst->fd.FDStat;
+    len = UFdFirst->fd.FDLength;
+
+	if (len == 0)
+	{ // This should not happen
+#if (NET_DEBUG >3)
+	  printk( "%s: rx'd ZERO length packet... Skipped\n", dev->name);
+#endif
+	  status |= RxS_LongErr;	// forces length stat to increment
+		// No break - treat as error in packet
+		//break;
+	}
+#if 1		// Sanity check -- can probably turn this off ...MaTed---
+	if ( ((UINT32) (UFdFirst->fd.FDDataPtr)) & OWNERSHIP)
+	{ // This should not happen
+#if (NET_DEBUG >3)
+	  printk( "%s: Encountered rx packet not owned\n", dev->name);
+#endif
+	  break;
+	}
+#endif	// 1 - Sanity check
+
+	nextFirstPtr = (RxFD *) (FdFirst->fd.FDNext);	// save the new First
+	if (S3C_SUCCESS == s3cLogRxBdmaError( dev, status))
+    {
+	  skb = UFdFirst->skb;
+      priv->stats.rx_bytes += len;
+	  priv->stats.rx_packets++;
+	  // update lengths 
+	  skb->tail += len;
+	  skb->len += len;
+	  InvalidateBuffer( skb->data, len);// want the real data
+	  skb->protocol = eth_type_trans( skb, dev);
+      netif_rx( skb);					// give the SKB to the kernel
+
+	  // Now move Frame Descriptor to the front of the WAIT list
+	  // This does the first half of pulling it out of the circular queue
+	  //	by putting the buffer on the wait list
+	  (RxFDS *) (FdFirst)->fd.FDNext = FdWaitFirst;
+	  FdWaitFirst = FdFirst;
+	  
+	  RxWait->num ++;		// keep track that we added it to the wait list
+	  Rx->num --;			// will be incremented in destructor
+	  //	  FlushCache();			// Force out to memory
+
+	}
+	else
+	{   // On error we'll stay with the original skb
+	  // we had an error in the packet, we're keeping the skb
+	  FdFirst->fd.FDLength = PKT_BUF_SZ;	// reset in case
+	  // Want to put this one at the end of the list (obtuse reasons)
+	  FdFirst->fd.FDNext = NULL;	// last one can has zero for next
+									//	to stop BDMA engine
+	  FdFirst->fd.FDDataPtr = (UCHAR*) ((UINT32) (FdLast->fd.FDDataPtr) 
+									   & ~OWNERSHIP);
+	  // Link first to the one last one - link was already to here (should
+	  //  have been to here anyway (mind skb Memory Squeeze)
+	  // Give the FDA back to the MAC
+	  // First check if the last one in the list was still ours
+	  ASSERT( 0 == (OWNERSHIP & (UINT32) (FdLast->fd.FDDataPtr)));
+
+	  // Last thing to do (just in case) is to link to the end
+	  ((RxFD *) FdLast)->FDNext = (RxFD *) (FdFirst);
+	  // Give ownership to MAC / BDMA of the FD
+ 	  FdLast->fd.FDDataPtr = (UCHAR*) ((UINT32) (FdLast->fd.FDDataPtr) 
+									   |= OWNERSHIP);
+	  FdLast = FdFirst;			// moved first to back
+	}
+	// advance the first
+	FdFirst = nextFirstPtr;		// save the new First
+	// have to clear to get next receive ??required?? ...MaTed---
+	WriteCSR( BdmaStat, ReadCSR( BdmaStat) & ~BRxRDF);
+	FlushCache();
+	// if there are no buffers left, we're done anyways (last one is marker)
+	if (FdFirst->fd.FDDataPtr == NULL)
+	  break;
+	if (!boguscount--)
+	  break;	// don't want to spend too much time in ISR
+  }
+#if !ENABLE_DESTRUCTOR
+  // Note try playing with the MinIn parm (1 is for debugging)
+  s3cAddRxSKBs( dev, RX_NUM_FD / 4, 1);		// put back SKBs into rx Q
+#endif
+
+  // have to clear to get next receive
+  WriteCSR( BdmaStat, ReadCSR( BdmaStat) | bdmaStatus);
+
+  if ( !( BRxEN & (temp = ReadCSR( RxCtl))))
+	WriteCSR( RxCtl, temp  | BRxEN);
+
+  if ( !( MRxCtlRxEn & (temp = ReadCSR( MacRxCtl))))
+	WriteCSR( MacRxCtl, temp  | MRxCtlRxEn);
+	
+  spin_unlock( &priv->lock);		// Again do I need this ???
+  return;
+}
+/************************************************************************
+ * This routine adds as many SKBs as the Rx Wait queue requires IF they are
+ *	available.
+ * The number of SKBs added depends on the qRxWait.num - number of entries
+ * 	in the wait queue. Wait queue is filled with skbs, setup and then 
+ *	reattached to the Rx Queue. We assign a maximum of MaxIn skb's
+ *	MinIn defines how many have to be on the Wait Queue before we cycle
+ *	through to fill them
+ *
+ * NOTE: special handling required if all Rx queue has been depleted
+ *	
+ * NOTE: If called in an interrupt context, the caller must own the
+ *	priv->lock. If NOT an interrupt, the priv-> must not be owned ...MaTed---
+ ************************************************************************/
+static void
+s3cAddRxSKBs( ND dev, UINT32 MaxIn, UINT32 MinIn )
+{
+  S3C_MAC *	priv 	= (S3C_MAC *)dev->priv;
+  BPTR	  * Rx		= &priv->qRx;
+  BPTR	  * RxWait	= &priv->qRxWait;
+  //  UINT32	SaveNum	= Rx->num;
+  UINT32	numXfer = 0;
+  RxFDS *	tempPtr;
+  RxFDS *	nextTempPtr	= NULL;
+  struct sk_buff *	skb;
+
+  // Rx First
+#define First 	((RxFDS *) ( Rx->first))
+  // Rx Last
+#define Last 	((RxFDS *) ( Rx->last))
+  // After Last
+#define After	((RxFDS *) (Last->fd.FDNext))
+  // Wait first - when skb cannot be filled now
+#define FdWaitFirst ((RxFDS *) ( RxWait->first))
+  // Wait last
+#define FdWaitLast 	((RxFDS *) ( RxWait->last))
+
+  if (RxWait->num < MinIn)
+	return;
+
+  // Move spinlock outside of the loop. Needs algorithm change and
+  //  much care to put it back inside the loop - may require mutiple
+  //  lock / unlock sequences ...MaTed---
+  if ( !in_irq())
+	spin_lock_irq( &priv->lock);		// Lock it down
+  tempPtr = FdWaitFirst;	// keep track of the Head of the list
+  while (RxWait->num && MaxIn --)
+  {
+	// get a newr skb to fill waiting head of wait list
+	/* Malloc up new skb header. Let's leave the headroom */
+	skb = dev_alloc_skb( PKT_BUF_SZ);      
+	if (skb == NULL)
+	{
+	  printk(KERN_NOTICE "%s: Memory squeeze.\n", dev->name);
+	  break;	// add it next time
+	}
+	InvalidateBuffer( (void *) skb->data, PKT_BUF_SZ);
+	skb->dev = dev;
+#if ENABLE_DESTRUCTOR
+	skb->destructor = priv->destructor;
+#endif
+	// NOTE: Assumption made that b31 of skb->data is 0 *********
+	FdWaitFirst->fd.FDDataPtr
+	  = (UCHAR *) ((UINT32) (skb->data) | OWNERSHIP);	// BDMA owns
+	// reserve after saving the buffer address
+	// NOTE Should combine this reserve with the dev_alloc_skb ->alloc_skb
+	//  - for efficiency only, but skb->data would have to be corrected
+	skb_reserve( skb, 2);		// 16 byte align
+	FdWaitFirst->skb = skb;			// save for later reception
+	FdWaitFirst->fd.FDLength = PKT_BUF_SZ;
+	nextTempPtr = FdWaitFirst;
+	FdWaitFirst = FdWaitFirst->fd.FDNext;
+	RxWait->num --;
+	numXfer ++;
+  }
+  // the Wait list first has advanced over the ones we moved
+  // Last one attached to have a NULL Next Frame Descriptor and no Ownership
+  if (nextTempPtr == NULL)	// Nothing to do if nothing was done
+  {
+	return;
+  }
+  nextTempPtr->fd.FDDataPtr
+	= (UCHAR *) (~OWNERSHIP & (UINT32) (nextTempPtr->fd.FDDataPtr));
+  nextTempPtr->fd.FDNext = NULL;
+  // WaitFirst is pointing to the beginning of the wait queue
+  // we move from nextTempPtr to tempPtr back to end of main queue
+  // *** I'm not sure what the order should be for the next two instructions
+  //  **  or if they should be uncached operations
+  Last->fd.FDNext = (RxFD *) tempPtr;
+  Last->fd.FDDataPtr =(UCHAR *) ((UINT32) ( Last->fd.FDDataPtr) | OWNERSHIP);
+  Last = nextTempPtr;	// move the last pointer
+  Rx->num += numXfer;	// number that we put back
+  FlushCache();			// Force out to memory
+  // Moved the spin lock outside the loop - need to change things to move it
+  //  back in ...MaTed---
+	if ( !in_irq())
+	  spin_unlock_irq( &priv->lock);		// unlock it
+  return;
+}
+#if DEBUG_RX_DUMP
+/************************************************************************
+ * 	Dump Rx data structures
+ *	
+ *
+ *
+ *
+ ************************************************************************/
+static void
+dumpRx( S3C_MAC * priv, char * where )
+{
+  BPTR	* Rx = &priv->qRx;
+  BPTR	* RxWait = &priv->qRxWait;
+
+  printk( KERN_INFO "\n   ***** %s *****\n", where);
+  printk( KERN_INFO "** Rx first-[%p] last-[%p] num-[%ld]\n",
+		  Rx->first, Rx->last, Rx->num);
+  RXFDS_Dump( (RxFDS *) (Rx->first), "First");
+  if (Rx->first != NULL)
+	RXFDS_Dump( (RxFDS *) (((RxFDS *) (Rx->first))->fd.FDNext),
+				"First->Next");
+  RXFDS_Dump( (RxFDS *) (Rx->last), "Last");
+  if (Rx->last != NULL)
+	RXFDS_Dump( (RxFDS *) (((RxFDS *) (Rx->last))->fd.FDNext),
+				"Last->Next");
+
+  printk( KERN_INFO "** Wait first-[%p] last-[%p] num-[%ld]\n",
+		  RxWait->first, RxWait->last, RxWait->num);
+  RXFDS_Dump( (RxFDS *) (RxWait->first), "Wait First");
+  if (RxWait->first != NULL)
+	RXFDS_Dump( (RxFDS *) (((RxFDS *) (RxWait->first))->fd.FDNext),
+				"Wait First->Next");
+  RXFDS_Dump( (RxFDS *) (RxWait->last), "Wait Last");
+  if (RxWait->last !=NULL)
+	RXFDS_Dump( (RxFDS *) (((RxFDS *) (RxWait->last))->fd.FDNext),
+				"Wait Last->Next");
+  return;
+}
+/***********************************************************************
+ * Dump RxFDS Struct
+ ***********************************************************************/
+static void
+RXFDS_Dump( RxFDS * fds, char * str)
+{
+  if (fds == NULL)
+  {
+	printk( KERN_INFO "   ---- %s NULL Address ----\n", str);
+	return;
+  }
+  printk( KERN_INFO "  ---- %s Ptr-[%p] Next-[%p] Data-[%p] Len-[0x%x] Skb-[%p]\n",
+		  str, fds, fds->fd.FDNext, fds->fd.FDDataPtr, fds->fd.FDLength,
+		  fds->skb);
+  //  printk( KERN_INFO "  ---- SKB  HeadNext-[%p] Data-[%p] Len-[0x%x] Skb-[%p]\n",
+  return;
+}
+#endif
+#if ENABLE_DESTRUCTOR
+/************************************************************************
+ * The destructor routine called when SKB is finally dead
+ *  - put the buffer back onto the correct free list and 
+ *    set the skb->head == 0
+ *	- called indirectly through s3cDestructor0 / 1
+ ****NOTE: this routine cannot be called in an interrupt context
+ ************************************************************************/
+static void
+s3cDestructor( struct sk_buff *skb)
+{
+  ND		dev		= skb->dev;
+  //  S3C_MAC * priv 	= dev->priv;
+
+  SINT("Destruct: SKB", ((int) skb));
+
+  if ( ! dev )	// check for NULL dev - why does this happen
+	return;
+
+  // The MinIn parm is just a guess - needs to be tuned ...MaTed---
+  s3cAddRxSKBs( dev, RX_NUM_FD, RX_NUM_FD/16 );
+}
+#endif
+#if 0	// old copy delete later - might want the code still
+/************************************************************************
+ * The destructor routine called when SKB is finally dead
+ *  - put the buffer back onto the correct free list and 
+ *    set the skb->head == 0
+ *	- called indirectly through s3cDestructor0 / 1
+ ****NOTE: this routine cannot be called in an interrupt context
+ ************************************************************************/
+static void
+s3cDestructor( struct sk_buff *skb)
+{
+  ND		dev		= skb->dev;
+  S3C_MAC * priv 	= dev->priv;
+  BPTR	  * Rx		= &priv->qRx;
+  BPTR	  * RxWait	= &priv->qRxWait;
+  UINT 				boguscount = RX_NUM_FD; 	// set to # of buffers
+  
+  struct sk_buff	* newSkb;
+
+  SINT("Destruct: SKB", ((int) skb));
+
+  // Rx First
+#define FdFirst 	((RxFDS *) ( Rx->first))
+  // Rx Last
+#define FdLast 		((RxFDS *) ( Rx->last))
+  // Wait first - when skb cannot be filled now
+#define FdWaitFirst ((RxFDS *) ( RxWait->first))
+  // Wait last
+#define FdWaitLast 	((RxFDS *) ( RxWait->last))
+
+  // UnCached versions
+  // Rx First
+#define UFdFirst 		((RxFDS *) ( UnCache( (UINT32) Rx->first)))
+  // Rx Last
+#define UFdLast 		((RxFDS *) ( UnCache( (UINT32) Rx->last)))
+  // Wait first - when skb cannot be filled now
+#define UFdWaitFirst 	((RxFDS *) ( UnCache( (UINT32) RxWait->first)))
+  // Wait last
+#define UFdWaitLast 	((RxFDS *) ( UnCache( (UINT32) RxWait->last)))
+
+  // Clean up the old skb so we never see it again
+  //  - Already done by skb_headerinit
+  //skb->dev = 0;
+  //skb->destructor = NULL;
+
+#if 0
+  printk("Destruct:dev=%x\n",(int) dev);
+#endif
+  if ( (! dev)  || in_irq() )	// check for NULL dev - why does this happen
+	return;
+
+  // The front buffers may need skb attached back - then attached onto the
+  //  active buffers in the MAC list
+  while( RxWait->num)		// put all the buffers back in that we need
+							//  if we can get them
+  {
+	// first get another skb to replace the one we gave away
+	/* Malloc up new skb header. */
+	newSkb = dev_alloc_skb( PKT_BUF_SZ);      
+	if (newSkb == NULL)
+	{
+	  //  No buffers, let's get out of here
+	  break;	
+	}
+	spin_lock_irq( &priv->lock);		// Again do I need this - I think so???
+	newSkb->dev = dev;
+	newSkb->destructor = priv->destructor;
+	// NOTE: Assumption made that b31 of skb->data is 0 *********
+	FdWaitFirst->fd.FDDataPtr = newSkb->data;
+	// reserve after saving the buffer address
+	skb_reserve( newSkb, 2);			// 16 byte align
+	FdWaitFirst->skb = newSkb;			// save for later reception
+	FdWaitFirst->fd.FDLength = PKT_BUF_SZ;
+	// Put the buffer at the end of the normal list
+	/******************************************************************
+	* NOTE: Algorithm change - There is no EOL BIT, so we have to be
+	* more careful. The BMDA engine will stop itself, we just have to 
+	* make sure we don't give it back before everything is ready (last)
+	* - Make corresponding change in setup routine
+	*******************************************************************/
+	// Link first wait to the one last normal active
+	FdLast->fd.FDNext = (RxFD *) FdWaitFirst;
+	// Give the FDA back to the MAC
+	FdLast = FdWaitFirst;			// moved first wait to back
+	FdWaitFirst = FdWaitFirst->fd.FDNext;
+	//	FdWaitLast->fd.FDNext = FdWaitFirst;	// circular back to front
+	FdLast->fd.FDNext = (RxFD *) FdFirst;		// make it circular
+	RxWait->num--;				// keep track that we took it off 
+									//	the wait list
+	Rx->num++;					// and put it on ready list
+	FdLast->fd.FDDataPtr = (UCHAR *) (((UINT32) (FdLast->fd.FDDataPtr)) 
+									  |= OWNERSHIP);	// give back to MAC
+	// have to clear to get next receive - just in case
+	WriteCSR( BdmaStat, ReadCSR( BdmaStat) & ~BRxRDF);
+	FlushCache();
+	if (!boguscount--)
+	  break;	// don't want to spend too much time in ISR
+	spin_unlock_irq( &priv->lock);		// Again do I need this ???
+  }
+  if ( netif_queue_stopped( dev) && ! txFull( dev))
+    netif_wake_queue( dev);
+  return;
+}
+#endif
+/************************************************************************
+ * The inverse routine to net_open().
+ ************************************************************************/
+static int
+s3c_close( ND dev)
+{
+  S3C_MAC *	priv 		= dev->priv;
+  //  int 		basePort	= dev->base_addr;
+  //  BPTR *	TxPtr 		= &priv->qTx;
+  //  BPTR *	RxPtr		= &priv->qRx;
+
+  //  TxFDS *	txPtrFirst;
+  //  struct sk_buff *skb;
+
+  netif_stop_queue( dev);
+
+  /* Flush the Tx and disable Rx here. */
+  DisableTxRx();
+  DisableInt();
+  //  Reset();				// Shut it down
+
+  // Release all buffers we own - please no memory leaks
+  // * first the TX buffers
+  spin_lock_irq( &priv->lock);
+#if 0		// ...MaTed--- need later for insmod, but not yet
+  // We really should release the skb's -- when we get open to be called
+  while (TxPtr->num != 0)	// It's possible that there is nothing
+  {
+	txPtrFirst = (TxFDS *) (TxPtr->first);
+	// get pointer to skb where we saved it
+	skb = txPtrFirst->skb;
+	ASSERT( atomic_read( &skb->users) == 1);
+	dev_kfree_skb (skb);		// release it
+	// move to next buffer
+	TxPtr->first = (void *) (((TxFDS *)(TxPtr->first))->fd.FDNext);
+	TxPtr->num--;
+  }
+
+  // release all the rx skb's
+  while (RxPtr->num != 0)	// It's possible that there is nothing
+  {
+	// release it
+	dev_kfree_skb ( ((RxFDS *) (RxPtr->first))->skb);
+	RxPtr->first = (void *) (((RxFDS *) (RxPtr->first))->fd.FDNext);
+	RxPtr->num--;
+  }
+#endif
+  // NOTE: do not have any skb's on the WAIT list with current algorithm
+
+#if 0		// ...MaTed--- need later for insmod, but not yet
+  /* Release the region */
+  s3c_release_irq_mem( dev );
+#endif
+
+  spin_unlock_irq( &priv->lock);
+
+#if 0		// ...MaTed--- need later for insmod, but not yet
+  /* release the priv area with the buffers and all the strcutures */
+  kfree( priv);
+#endif
+
+  return 0;
+}
+/************************************************************************
+ * Get the current statistics.
+ * This may be called with the card or closed.
+ ************************************************************************/
+static struct net_device_stats *s3c_get_stats( ND dev)
+{
+  S3C_MAC *priv = (S3C_MAC *)dev->priv;
+
+  return (&priv->stats);
+}
+/************************************************************************
+ * Set or clear the multicast filter for this adaptor.
+ * num_addrs == -1	Promiscuous mode, receive all packets
+ * num_addrs == 0	Normal mode, clear multicast list
+ * num_addrs > 0	Multicast mode, receive normal and MC packets,
+ *			and do best-effort filtering.
+ ************************************************************************/
+static void
+set_multicast_list( ND dev)
+{
+  //  int		ioaddr = dev->base_addr;
+
+  WriteCSR( CamEn, 0);			// turn off ARC usage for now
+
+  if (dev->flags & IFF_PROMISC)
+  {
+    /* Enable promiscuous mode */
+    WriteCSR( CamCtl, ReadCSR( CamCtl) | NegCAM);
+  }
+  else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > HW_MAX_ADDRS)
+  {
+    WriteCSR( CamCtl, CompEn | BroadAcc | GroupAcc);
+  }
+  else if (dev->mc_count)
+  {
+    /* Walk the address list, and load the filter */
+    HardwareSetFilter( dev);
+    
+    WriteCSR( CamCtl, ReadCSR( CamCtl) | BroadAcc);
+  }
+  else // setup for normal
+  {
+    /* setup the MAC HW address */
+    SetUpARC( dev, dev->dev_addr);
+
+    WriteCSR( CamEn, 1 << 2);	    // Enable only the third entry
+    WriteCSR( CamCtl,  (CompEn | GroupAcc | BroadAcc | StationAcc));
+  }
+}
+/************************************************************************
+ * HardwareSetFilter
+ ************************************************************************/
+static void HardwareSetFilter( ND dev )
+{
+  UINT	    i = 0;
+  //  UINT32    port = dev->base_addr;
+  struct    dev_mc_list * ptr = dev->mc_list;
+  //  UINT32	temp;
+  //  UINT16 *	addrHalfPtr;
+
+  UINT32	enableMask = 0;
+
+  /*
+   * NOTE: this section has never been tested ...MaTed---
+   */
+  while (ptr && i < HW_MAX_ADDRS - 1)
+  {
+	if ( i & 1)
+    {	// odd entry starting at the third location 
+	  WriteCSR( Cam[ 3 + (i * 3) / 2],
+				((0x0000ffff & ReadCSR( Cam[ 3 + (i * 3) / 2] ))
+				| (ptr->dmi_addr[ 1 ] << 24 )
+				| (ptr->dmi_addr[ 0 ] << 16 )));
+	  WriteCSR( Cam[4 + (i * 3) / 2],
+				(ptr->dmi_addr[ 5 ] << 24)
+				| (ptr->dmi_addr[ 4 ] << 16)
+				| (ptr->dmi_addr[ 3 ] << 8)
+				| (ptr->dmi_addr[ 2 ]));
+	}
+	else
+	{
+	  WriteCSR( Cam[3 + (i * 3) / 2],
+				((ptr->dmi_addr[ 3 ] << 24)
+				| (ptr->dmi_addr[ 2 ] << 16)
+				| (ptr->dmi_addr[ 1 ] << 8)
+				| (ptr->dmi_addr[ 0 ])));
+	  WriteCSR( Cam[4 + (i * 3) / 2],
+				(0xffff0000 & ReadCSR( Cam[4 + (i * 3) / 2] ))
+				| (ptr->dmi_addr[ 4 ] )
+				| (ptr->dmi_addr[ 5 ] << 8));
+	}
+	enableMask |= (1 << ( i + 2 ));
+    i++;
+	ptr = ptr->next;
+  }
+  WriteCSR( CamEn, enableMask);	    // Enable all the entries
+  if (i != dev->mc_count)
+  {
+	printk("S3C4530: %s - MultiCast Count (%d) != pointers (%d)\n",
+		   dev->name, dev->mc_count, i);
+  }
+  return;
+}
+
+
+/*********************************************
+ * Module support
+ *********************************************/
+
+#ifdef MODULE
+// ***** NOTE: support not yet completed ...MaTed --
+
+static struct net_device this_device;
+static int io = 0x300;
+static int irq;
+static int dma;
+static int mem;
+
+int init_module(void)
+{
+  int result;
+
+  if (io == 0)
+    printk(KERN_WARNING "%s: You shouldn't use auto-probing with insmod!\n",
+	   cardname);
+
+  /* Copy the parameters from insmod into the device structure. */
+  this_device.base_addr = io;
+  this_device.irq       = irq;
+  this_device.dma       = dma;
+  this_device.mem_start = mem;
+  this_device.init      = netcard_probe;
+
+  if ((result = register_netdev(&this_device)) != 0)
+    return result;
+
+  return 0;
+}
+
+void
+cleanup_module(void)
+{
+  /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+  unregister_netdev(&this_device);
+  /*
+   * If we don't do this, we can't re-insmod it later.
+   * Release irq/dma here, when you have jumpered versions and
+   * allocate them in net_probe1().
+   */
+  /*
+    free_irq(this_device.irq, dev);
+    free_dma(this_device.dma);
+  */
+  release_mem_region(this_device.base_addr, NETCARD_IO_EXTENT);
+
+  if (this_device.priv)
+    kfree(this_device.priv);
+}
+
+#endif /* MODULE */
+
+#if DEBUG_PHY_DUMP
+/*********************************************
+ * Dump all the phy registers
+ *********************************************/
+void DumpPhyReg(void)
+{
+  int i;
+  UINT32	Array[4];
+
+  printk( "**** Phy register dump \n");
+  for (i=0; i<=32; i+=4)
+  {
+	(void) ReadPhy( PHYAddr, i+0, &Array[0]);
+	(void) ReadPhy( PHYAddr, i+1, &Array[1]);
+	(void) ReadPhy( PHYAddr, i+2, &Array[2]);
+	(void) ReadPhy( PHYAddr, i+3, &Array[3]);
+
+	printk(" Addr[%d], 0x%08x - 0x%08x - 0x%08x - 0x%08x\n",
+		   i, (int) Array[0], (int) Array[1], 
+		   (int) Array[2], (int) Array[3]);
+  }
+}
+#endif	//DEBUG_PHY_DUMP
+
+/*
+ * Local variables:
+ *  compile-command:
+ *	gcc -D__KERNEL__ -Wall -Wstrict-prototypes -Wwrite-strings
+ *	-Wredundant-decls -O2 -m486 -c s3c.c.c
+ *  version-control: t
+ *  kept-new-versions: 5
+ *  tab-width: 4
+ *  c-indent-level: 2
+ * End:
+ */
+#endif // CONFIG_SAMSUNG_S3C
+
+#if S3C_TEMP_ROUTINES
+static int get_ethernet_addr(char * MatchName, char * addr)
+{
+#if 1	// pull the hw eternet address from the boot loader
+  char *p;
+  if ((p = getbenv (ETH1_ENV_NAME)) == ((char *) 0))
+  {
+	//	printf ("Error: No MAC for S3C4530!\n");
+	return -ENODEV;
+  }
+  //  printf ("S3C4530 MAC=[%s]\n", p);
+  while (*p != 0)
+	*addr++ = *p++;
+  return (0);		// returns success
+#else
+  /* this dummy routine always returns a fixed IP in addr */
+  addr[0] = 192;
+  addr[1] = 168;
+  addr[2] = 15;
+  addr[3] = 2;
+  return (0);		// returns success
+#endif
+}
+#endif
diff -urN linux-2.4.29/drivers/net/s3c4530.h linux-2.4.29-uc1/drivers/net/s3c4530.h
--- linux-2.4.29/drivers/net/s3c4530.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/s3c4530.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,1091 @@
+/***********************************************************************/
+/*                                                                     */
+/* Samsung s3c4530a Ethernet Driver Header                             */
+/* Copyright 2001 Arcturus Networks Inc and Lineo Canada Corp.         */
+/*                                                                     */
+/***********************************************************************/
+/* s3c4530.h */
+/*
+ * modification history
+ * --------------------
+ *
+ *	10/22/01	MaTed
+ *			- Initial version for linux 
+ *			- please set TABS == 4
+ *
+ */
+
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/if.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+//#include <asm/bootst.h>		// only for bgetenv ...MaTed---
+#include <asm/arch/irq.h>
+#include <asm/irq.h>
+
+#if 0	// do we need this ...MaTed---
+#include <asm/addrspace.h>
+#endif
+
+/***************************************
+ * We want ours - not from hardware.h
+ ***************************************/
+#undef BDMATXCON   0x9000		/* Buffered DMA Transmit Control			*/
+#undef BDMARXCON   0x9004		/* Buffered DMA Receive Control				*/
+#undef BDMATXPTR   0x9008		/* BDMA Transmit Frame Descriptor Start
+								   Address									*/
+#undef BDMARXPTR   0x900C		/* BDMA Receive Frame Descriptor Start
+								   Address									*/
+#undef BDMARXLSZ   0x9010		/* BDMA Receive frame maximum Size			*/
+#undef BDMASTAT    0x9014		/* BDMA Status								*/
+// I don't know what the next one is yet ...MaTed---
+#undef ETXSTAT     0x9040		/* Transmit control frame status 			*/
+#undef CAM     	0x9100		/* CAM content 32 words 9100-917c			*/
+#undef BDMATXBUF   0x9200		/* Tx Buffer - test mode only				*/
+#undef BDMARXBUF	0x9800		/* Rx Buffer - test mode only				*/
+#undef BDMARXBUF1	0x9900		/* Rx Buffer - test mode only				*/
+/***********************************************
+ * Ethernet MAC Register Address
+ ***********************************************/
+#undef MACON       0xA000		/* MAC control								*/
+#undef CAMCON      0xA004		/* CAM control								*/
+#undef MATXCON     0xA008		/* Transmit control							*/
+#undef MATXSTAT    0xA00C		/* Transmit status							*/
+#undef MARXCON     0xA010		/* Receive control							*/
+#undef MARXSTAT    0xA014		/* Receive status							*/
+#undef STADATA     0xA018		/* Station management data					*/
+#undef STACON      0xA01C		/* Station management control and address	*/
+#undef CAMEN       0xA028		/* CAM enable								*/
+#undef EMISSCNT    0xA03C		/* Missed error count						*/
+#undef EPZCNT      0xA040		/* Pause count								*/
+#undef ERMPZCNT    0xA044		/* Remote pause count						*/
+
+#undef HW_MAX_ADDRS	HW_MAX_CAM - 5		// maximum usable ARC entries
+#undef BRxEmpty	0x010000	/* Rx buffer empty interrupt enable			*/
+#undef BRxEarly	0x020000	/* Rx early notify interrupt enable			*/
+#undef	BRxRDF		0x000001	/* Rx Done frame							*/
+#undef	BRxNL		0x000002	/* Rx Null List								*/
+#undef	BRxNO		0x000004	/* Rx Not Owner								*/
+#undef	BRxMSO		0x000008	/* Rx Maximum Size Over						*/
+#undef	BRxFRF		0x000080	/* One more frame in the BDMA receive Buffer*/
+#undef	BRxNFR		0x00ff00	/* Total number of data frames currently
+								   in the BDMA receive buffer				*/
+#undef	BTxCCP		0x010000	/* Tx completed sending control packet		*/
+#undef	BTxNL		0x020000	/* Tx Null List								*/
+#undef	BTxNO		0x040000	/* Tx Not Owner								*/
+#undef	BTxEmpty	0x100000	/* Tx Buffer Empty							*/
+
+
+/****************
+ * DEBUG MACROS
+ ***************/
+/* use 0 for production, 1 for verification, >2 for debug */
+#ifndef NET_DEBUG
+#define NET_DEBUG 1
+#endif
+
+#if NET_DEBUG > 0
+// NOTE: NO panic used when in a driver - I might be in the kernel
+#define ASSERT(expr) \
+  if(!(expr)) { \
+    printk( "\n" __FILE__ ":%d: Assertion " #expr " failed!\n",__LINE__); \
+  }
+#define TDEBUG(x...) printk(KERN_DEBUG ## x)
+#else
+#define ASSERT(expr)
+#define TDEBUG(x...)
+#endif
+
+/********************
+ * Macro Definitions
+ ********************/
+#ifndef ___align16
+#define ___align16 __attribute__((__aligned__(16)))
+#endif 
+/*
+ * Setup some shorthand
+ */
+//	#define CSR  ((MAC_CSR)(dev->offset))
+
+// so we can source debug by nulling this	
+#define _INLINE_ inline
+
+// just some more shorthand
+#define ND struct net_device *
+
+/***********************
+ * Replacement Defines
+ ***********************/
+#define NUM_HW_ADDR		6		// number of bytes in ethernet HW address 
+
+/****************
+ * CONFIGURATION
+ ****************/
+// Use skb's, but dma straight into them -- exclusive to below ...MaTed---
+#define ZERO_COPY_SKB	1
+
+// Have to make sure that destructor is always called and
+//  no one ever frees the skb data before I trust this
+//  would have a very hard bug to trace or replicate ...MaTed---
+#undef ZERO_COPY_BUFFER
+
+// IOCTL setup not fully implemented, just some routines
+#undef ENABLE_IOCTL
+
+/***********************************
+ *
+ * S3c Memory configuration defines
+ *
+ ***********************************/
+#if  (L1_CACHE_BYTES == 32)
+#define L1_CACHE_SHIFT 5
+#elif (L1_CACHE_BYTES == 16)
+  #define L1_CACHE_SHIFT 4
+  #else
+    **************** BAD L1 CACHE LINE not 16 or 32 ***********
+#endif
+
+/***********************************
+ *
+ * S3c Ethernet MAC Configuration
+ *
+ ***********************************/
+#define HW_MAX_CAM		((32 * 4) / NUM_HW_ADDR)	/* number of entries 
+													   in CAM for address	*/
+#define HW_MAX_ADDRS	HW_MAX_CAM - 5		// maximum usable ARC entries
+											//  0, 1 and 18 reserved
+											// we ignore 19 and 20
+#define ETH_MAXUNITS	1
+
+#define TX_THRESH_HOLD	512		// value for tuning tx threshold (minimum value
+								// that works is best)
+								//  - passed to sierra controller 
+#define	TX_POLL_CTR		0x80	// Count between polls, 0 to disable
+#define ETH_MIN_LEN		64		// minimum length to xmit is 64
+								//  Verify OK for all protocols
+/* Tunable defines */
+#define RX_NUM_FD		256		// Max number of receive frames to set up
+								// (HARD MAX)
+#if 1
+#define TX_NUM_FD		64		// Maximum number of transmit frames to set up
+#else
+#define TX_NUM_FD		32		// Maximum number of transmit frames to set up
+								// (SOFT MAX) -- NOTE: do not make too big or 
+#endif
+#define RX_NUM_SKB		R`X_NUM_FD	// Total number of receive
+									// buffers allocated
+#define RX_NOTE_BUF		RX_NUM_FD / 2	// Notify on half full
+
+#define TX_NUM_SKB		TX_NUM_FD	// Total number of receive
+									// buffers allocated
+#define TX_NOTE_BUF		TX_NUM_FD / 2	// Notify on half frames unused
+
+/* The number of low I/O ports used by the ethercard.????...MaTed---????? */
+#define MY_TX_TIMEOUT  ((400*HZ)/1000)
+
+/*********************
+ * Error Return Codes
+ *********************/
+typedef int					RET_CODE;
+
+#define	S3C_SUCCESS		0	// function call was successful
+#define S3C_FAIL		-1	// general error code
+#define S3C_TIMEOUT		-1000	// timeout error
+
+/**********************
+ * S3C Buffer Sizes
+ **********************/
+#define MAX_PKT_SIZE		1536		// bigger than need be ? (but 3x512)
+//#define MAX_FRAME_SIZE	1522
+// Realize that this is bigger than needs to be - does this cause a problem?
+//  -- the upper layers break down tx stuff, rx?? ...MaTed---
+#define PKT_BUF_SZ  		MAX_PKT_SIZE	// Size of each Rx buffer
+
+/* Reserve all the stuff - nothing between used ...MaTed--- */
+#define MAC_IO_EXTENT	(0xAFFF - 0x9000)
+
+/****************
+ * EXTERNS
+ ****************/
+
+
+/*********************************************************************
+ * typedefs
+ *********************************************************************/
+typedef unsigned int	UINT;
+typedef	unsigned long	ULONG;
+typedef unsigned long	UINT32;
+typedef unsigned short	UINT16;
+typedef unsigned char	UINT8;
+typedef	unsigned char	UCHAR;
+
+/*****************
+ *  Ethernet MAC
+ *****************/
+#define SRB_BASE        0x03FF0000
+#define	BDMA_BASE		SRB_BASE+0x9000	/* Base address to BDMA Controller	*/
+#define	MAC_BASE		SRB_BASE+0xa000	/* Base address to MAC Controller	*/
+#define	CACHE_TAG_RAM	0x11000000		/* base address to Tag RAM			*/
+
+#define	UNCACHE_ADDR	0x04000000		/* forces to uncached access		*/
+#define UnCache( x) (UNCACHE_ADDR | (UINT32) (x)) 
+
+// Each Mac has four interrupts
+#define MAC_RX_IRQ		19			/* RX IRQ for MAC						*/
+#define MAC_TX_IRQ		18			/* TX IRQ for MAC						*/
+#define BDMA_RX_IRQ		17			/* RX IRQ for BDMA						*/
+#define BDMA_TX_IRQ		16			/* TX IRQ for BDMA						*/
+
+/***********************************************
+ * Misc Addresses
+ ***********************************************/
+//#define	SYSCFG		0x0000	/* System configuration register			*/
+
+#define	WriteBufferEn	0x04	/* Write Buffer enable bit mask				*/
+
+/****************************************
+ * Interrupt Controller
+ ****************************************/
+#define INTMOD      (SRB_BASE+0x4000)
+#define INTPND      (SRB_BASE+0x4004)
+#define INTMSK      (SRB_BASE+0x4008)
+#define INTPRI0     (SRB_BASE+0x400C)
+#define INTPRI1     (SRB_BASE+0x4010)
+#define INTPRI2     (SRB_BASE+0x4014)
+#define INTPRI3     (SRB_BASE+0x4018)
+#define INTPRI4     (SRB_BASE+0x401C)
+#define INTPRI5     (SRB_BASE+0x4020)
+#define INTOFFSET   (SRB_BASE+0x4024)
+#define INTOSET_FIQ (SRB_BASE+0x4030)
+#define INTOSET_IRQ (SRB_BASE+0x4034)
+
+#define _IRQ0       0
+#define _IRQ1       1
+#define _IRQ2       2
+#define _IRQ3       3
+#define _URTTx0     4
+#define _URTRx0     5
+#define _URTTx1     6
+#define _URTRx1     7
+#define _GDMA0      8
+#define _GDMA1      9
+#define _TC0        10
+#define _TC1        11
+#define _HDLCATx    12
+#define _HDLCARx    13
+#define _HDLCBTx    14
+#define _HDLCBRx    15
+#define _BDMATx     16
+#define _BDMARx     17
+#define _MACTx      18
+#define _MACRx      19
+#define _I2C        20
+#define _GLOBAL     21
+
+/***********************************************
+ * Ethernet BDMA Register Address
+ ***********************************************/
+#define BDMATXCON   0x9000		/* Buffered DMA Transmit Control			*/
+#define BDMARXCON   0x9004		/* Buffered DMA Receive Control				*/
+#define BDMATXPTR   0x9008		/* BDMA Transmit Frame Descriptor Start
+								   Address									*/
+#define BDMARXPTR   0x900C		/* BDMA Receive Frame Descriptor Start
+								   Address									*/
+#define BDMARXLSZ   0x9010		/* BDMA Receive frame maximum Size			*/
+#define BDMASTAT    0x9014		/* BDMA Status								*/
+// I don't know what the next one is yet ...MaTed---
+#define ETXSTAT     0x9040		/* Transmit control frame status 			*/
+#define CAM     	0x9100		/* CAM content 32 words 9100-917c			*/
+#define BDMATXBUF   0x9200		/* Tx Buffer - test mode only				*/
+#define BDMARXBUF	0x9800		/* Rx Buffer - test mode only				*/
+#define BDMARXBUF1	0x9900		/* Rx Buffer - test mode only				*/
+/***********************************************
+ * Ethernet MAC Register Address
+ ***********************************************/
+#define MACON       0xA000		/* MAC control								*/
+#define CAMCON      0xA004		/* CAM control								*/
+#define MATXCON     0xA008		/* Transmit control							*/
+#define MATXSTAT    0xA00C		/* Transmit status							*/
+#define MARXCON     0xA010		/* Receive control							*/
+#define MARXSTAT    0xA014		/* Receive status							*/
+#define STADATA     0xA018		/* Station management data					*/
+#define STACON      0xA01C		/* Station management control and address	*/
+#define CAMEN       0xA028		/* CAM enable								*/
+#define EMISSCNT    0xA03C		/* Missed error count						*/
+#define EPZCNT      0xA040		/* Pause count								*/
+#define ERMPZCNT    0xA044		/* Remote pause count						*/
+
+/***********************************************
+ * Ethernet BDMA Register Offsets (from 0x9000)
+ ***********************************************/
+#define BOTXCON   	0x0000		/* Buffered DMA Transmit Control			*/
+#define BORXCON   	0x0004		/* Buffered DMA Receive Control				*/
+#define BOTXPTR   	0x0008		/* BDMA Transmit Frame Descriptor Start
+								   Address									*/
+#define BORXPTR   	0x000C		/* BDMA Receive Frame Descriptor Start
+								   Address									*/
+#define BORXLSZ   	0x0010		/* BDMA Receive frame maximum Size			*/
+#define BOSTAT    	0x0014		/* BDMA Status								*/
+// I don't know what the next one is yet ...MaTed---
+#define BOETXSTAT	0x0040		/* Transmit control frame status 			*/
+#define BOCAM     	0x0100		/* CAM content 32 words 9100-917c			*/
+#define BOTXBUF		0x0200		/* Tx Buffer - test mode only				*/
+#define BORXBUF1	0x0800		/* Rx Buffer - test mode only				*/
+#define BORXBUF2	0x0900		/* Rx Buffer - test mode only				*/
+/***********************************************
+ * Ethernet MAC Register Offsets (from (0x9000)
+ ***********************************************/
+#define MOCON       0x1000		/* MAC control								*/
+#define MOCAMCON    0x1004		/* CAM control								*/
+#define MOTXCON     0x1008		/* Transmit control							*/
+#define MOTXSTAT    0x100C		/* Transmit status							*/
+#define MORXCON     0x1010		/* Receive control							*/
+#define MORXSTAT    0x1014		/* Receive status							*/
+#define MOSTADATA	0x1018		/* Station management data					*/
+#define MOSTACON    0x101C		/* Station management control and address	*/
+#define MOCAMEN     0x1028		/* CAM enable								*/
+#define MOEMISSCNT  0x103C		/* Missed error count						*/
+#define MOEPZCNT	0x1040		/* Pause count								*/
+#define MOERMPZCNT	0x1044		/* Remote pause count						*/
+/*********************************************************
+ * Buffered DMA Transmit Control Register (7-23 -> 7-25)
+ * BDMATXCON - offset 0x9000
+ *********************************************************/
+#define	BTxBRST_MASK	0x001f	/* Mask for DMA Burst Size (pg 7-23)		*/
+#define BTxSTSKO		0x0020	/* Tx stop/skip by owner bit				*/
+
+#define BTxCCPIE		0x0080	/* Tx complete to send control packet
+								   interrupt enable							*/
+#define BTxNLIE			0x0100	/* Tx Null List interrupt enable			*/
+#define BTxNOIE			0x0200	/* Tx not owner interrupt enable			*/
+#define BTxEMPTY		0x0400	/* Tx buffer empty interrupt bit			*/
+#define BTxMSL			0x3800	/* transmit to Mac Tx Start Level			*/
+#define BTxEN			0x4000	/* Tx Enable								*/
+#define BTxRS			0x8000	/* Tx reset - just the BDMA tx Block		*/
+/* Interrrupt enable bits */
+//	#define BTxINTMask		(BTxSTSKO | BTxCCPIE | BTxNLIE | BTxNOIE 
+//								| BTxEMPTY)
+//#define BTxINTMask		(BTxSTSKO | BTxCCPIE | BTxNLIE )
+#define BTxINTMask		(BTxSTSKO | BTxCCPIE )
+/*  TxM Start Level                     bits 11 to 13   */
+#define BTxFill		(6<<11)  	/* Fill n / 8th's of BDMA tx before MAC		*/
+/* setup size for rx dma burst size FIXME...MaTed--- */
+#define BTxBurstSIZE	(16)	/* 16 words == 64 bytes		  				*/
+
+//#define BTxSetup	(BTxBurstSIZE | BTxSTSKO | BTxCCPIE | BTxNLIE | BTxNOIE 
+//					 | BTxEMPTY | BTxFill | BTxEN )
+#define BTxSetup	(BTxBurstSIZE | BTxSTSKO | BTxFill )
+//#define BTxSETUP	(BtxBurstSIZE | BtxFill)	// 16 word dma burst, fill 2/8
+												//  of MAC Start Level
+/*********************************************************
+ * Buffered DMA Receive Control Register (7-26 -> 7-29)
+ * BDMARXCON - offset 0x9004
+ *********************************************************/
+#define BRxBRST		0x00001f	/* Mask for DMA Burst size					*/
+#define BRxSTSKO	0x000020	/* Stop/Skip frame by owner bit				*/
+#define BRxMAINC	0x000040	/* RX memory address inc / dec				*/
+#define BRxDIE		0x000080	/* every received frame interrupt enable	*/
+#define BRxNLIE		0x000100	/* Null List interrupt enable				*/
+#define BRxNOIE		0x000200	/* Not owner interrupt enable				*/
+#define BRxMSOIE	0x000400	/* Maximum size over interrupt enable		*/
+#define BRxLittle	0x000800	/* Little / Big Endian (SET 1)				*/
+//***** NOTE WA must be set ONCE after reset - forced in Reset()
+#define BRxWA		0x003000	/* Rx word alignment "10" -> 2				*/
+#define BRxEN		0x004000	/* Rx Enable								*/
+#define BRxRS		0x008000	/* Rx reset									*/
+#define BRxEmpty	0x010000	/* Rx buffer empty interrupt enable			*/
+#define BRxEarly	0x020000	/* Rx early notify interrupt enable			*/
+
+#define BRxINTMask	(BRxSTSKO | BRxDIE | BRxNLIE | BRxNOIE | BRxMSOIE \
+					 | BRxEmpty | BRxEarly)
+
+/*  RxAlign                     bits 12 to 13   */
+#define BRxAlignSkip0	(0x00<<12)  /* Do not skip any bytes on rx			*/
+#define BRxAlignSkip1	(0x01<<12)  /* Skip 1st byte on rx					*/
+#define BRxAlignSkip2	(0x02<<12)  /* Skip 2nd byte on rx					*/
+#define BRxAlignSkip3	(0x03<<12)  /* Skip 3rd byte on rx					*/
+/* setup size for rx dma burst size FIXME...MaTed--- */
+//#define BRxBurstSize	(16)	/* 16 words == 64 bytes		  				*/
+#define BRxBurstSize	(0x1f)	/* 32 words == 128bytes	(max value)			*/
+
+// Not sure of MAINC, Empty, En (sooner or later), some other ENables
+// ...MaTed---
+#define	BRxSetup_RESET	(BRxBurstSize | BRxSTSKO | BRxMAINC | \
+						 BRxLittle | BRxAlignSkip2 )
+//#define BRxSetup	(BRxBurstSize | BRxSTSKO | BRxMAINC | BRxDIE |
+//					 BRxNLIE | BRxNOIE | BRxMSOIE | BRxLittle |
+//					 BRxAlignSkip2 | BRxEN | BRxEmpty )
+#define BRxSetup	(BRxBurstSize | BRxSTSKO | BRxMAINC | BRxDIE | \
+					 BRxNLIE | BRxNOIE | BRxLittle | \
+					 BRxAlignSkip2 | BRxEN )
+
+/*********************************************************
+ * Buffered DMA Status Register (7-32 -> 7-34)
+ * BDMASTAT - offset 0x9014
+ *********************************************************/
+#define	BRxRDF		0x000001	/* Rx Done frame							*/
+#define	BRxNL		0x000002	/* Rx Null List								*/
+#define	BRxNO		0x000004	/* Rx Not Owner								*/
+#define	BRxMSO		0x000008	/* Rx Maximum Size Over						*/
+#define	BRxStEmpty	0x000010	/* Rx buffer Empty							*/
+#define	BRxSEarly	0x000020	/* Early Notification						*/
+#define	BRxFRF		0x000080	/* One more frame in the BDMA receive Buffer*/
+#define	BRxNFR		0x00ff00	/* Total number of data frames currently
+								   in the BDMA receive buffer				*/
+#define	BTxCCP		0x010000	/* Tx completed sending control packet		*/
+#define	BTxNL		0x020000	/* Tx Null List								*/
+#define	BTxNO		0x040000	/* Tx Not Owner								*/
+#define	BTxEmpty	0x100000	/* Tx Buffer Empty							*/
+/*********************************************************
+ * MAC Control Register (7-36)
+ * MACON - offset 0xA000
+ *********************************************************/
+#define	MCtlHaltReq		0x0001	/* Halt request								*/
+#define	MCtlHaltImm		0x0002	/* Halt immediate							*/
+#define	MCtlReset		0x0004	/* Software reset							*/
+#define	MCtlFullDup		0x0008	/* Full Duplex								*/
+#define	MCtlLoop		0x0010	/* Set for loopback testing					*/
+#define	MCtlMII_Off		0x0040	/* set to connect to 10 MbS endec, 0 for
+								   MII										*/
+#define	MCtlLoop10		0x0080	/* Bit asserted to the 10MbS endec (set 0)	*/
+#define	MCtlMissRoll	0x0400	/* Bit set when the missed error counter 
+								   rolls over								*/
+#define	MCtlMDC_OFF		0x1000	/* Clear this bit to enable MDC clock 
+								   generation for power management			*/
+#define	MCtlEnMissRoll	0x2000	/* Enable missed error counter rollover
+								   interrupt								*/
+#define	MCtlLink10		0x8000	/* Link Status 10 Mb/S to Link10 pin		*/
+// Which IRQ does this interrupt go to ...MaTed-- not implemented FIXME
+#define	MCtlINTMask		MCtlEnMissRoll
+#define MCtlReset_BUSY_LOOP		100
+#define MCtlSETUP	(MCtlFullDup )
+
+#define MCtlFullDupShift	3
+#define MCtl10Shift1		6
+#define MCtl10Shift2		7
+/*********************************************************
+ * MAC CAM Control Register (7-37)
+ * CAMCON - offset 0xA004
+ *********************************************************/
+#define StationAcc	0x00000001	/* Accept Station/Unicast addresses			*/
+#define GroupAcc	0x00000002	/* Accept Group/Multicast addresses			*/
+#define BroadAcc	0x00000004	/* Accept the Broadcast addresses			*/
+#define NegCAM		0x00000008	/* Reject, rather than accept
+								   CAM-recognized entries					*/
+#define CompEn		0x00000010	/* Enable compare mode						*/
+
+#if 0	// definition above calculates the value ...MaTed--- 
+#define HW_MAX_ADDRS	21		/* CAM consists of 32 words					*/
+#endif
+#define CAMCtlSETUP	(StationAcc | GroupAcc | BroadAcc | CompEn)
+
+/*********************************************************
+ * MAC Transmit Control Register (7-38)
+ * MACTXCON - offset 0xA008
+ *********************************************************/
+#define	MTxCtlTxEn			0x0001	/* Transmit Enable, clear stop
+									   immediate   							*/
+#define	MTxCtlTxHalt		0x0002	/* Transmit Halt, set stops after current
+									   Packet								*/
+#define	MTxCtlNoPad			0x0004	/* Suppress Padding for pkts <64 bytes	*/
+#define	MTxCtlNoCRC			0x0008	/* Suppress CRC							*/
+#define	MTxCtlFBack			0x0010	/* Fast Back-off - testing only			*/
+#define	MTxCtlNoDef			0x0020	/* No defer - disable the counter counting
+									   until the carrier sense bit is turned
+									   off 									*/
+#define	MTxCtlSdPause		0x0040	/* Send Pause (or other MAC control)	*/
+#define	MTxCtlSQEn			0x0080	/* SQE test mode - set to enable MII bit
+																		   	*/
+#define	MTxCtlEnUnder		0x0100	/* Enable tx FIFO underun interrupt		*/
+#define	MTxCtlEnDefer		0x0200	/* Enable max deferral time interrupt	*/
+#define	MTxCtlEnNCarr		0x0400	/* Enable no carrier while tx interrupt	*/
+#define	MTxCtlEnExColl		0x0800	/* Enable >16 collisions during tx
+									   interrupt							*/
+#define	MTxCtlEnLateColl	0x1000	/* Enable Late Collision interrupt		*/
+#define	MTxCtlEnTxParity	0x2000	/* Enable MAC tx FIFO parity interrupt 	*/
+#define	MTxCtlEnComp		0x4000	/* Enable completion (tx or discard)
+									   interrupt							*/
+#define MTxCtlINTMask	(MTxCtlEnUnder | MTxCtlEnDefer | MTxCtlEnNCarr | \
+						 MTxCtlEnExColl | MTxCtlEnLateColl |		\
+						 MTxCtlEnTxParity)
+// #define MTxCtlSetup	(MTxCtlTxEn | MTxCtlSQEn |  MTxCtlEnUnder |  
+#define MTxCtlSetup	(MTxCtlEnUnder | 	\
+					 MTxCtlEnDefer | MTxCtlEnNCarr | 				\
+					 MTxCtlEnExColl | MTxCtlEnLateColl | 			\
+					 MTxCtlEnTxParity)
+
+/*********************************************************
+ * MAC Transmit Status Register (7-39)
+ * MACTXSTAT - offset 0xA00C
+ *********************************************************/
+#define MTxStTxColl		0x000f	/* Transmit Collision Count					*/
+#define MTxStExColl		0x0010	/* Excessive Collision - tx aborted			*/
+#define MTxStTxDefer	0x0020	/* Transmit deferred - pkt tx was deferred	*/
+#define MTxStPause		0x0040	/* tx delayed due to rx of PAUSE			*/
+#define MTxStIntTx		0x0080	/* Transmit caused interrupt				*/
+#define MTxStUnder		0x0100	/* Underrun - tx FIFO went empty during tx	*/
+#define MTxStDefer		0x0200	/* Set if MAC defers tx because of
+								   MAX_DEFERAL								*/
+#define MTxStNCarr		0x0400	/* Set if no carrier sense during
+								   transmission of packet					*/
+#define MTxStSQE		0x0800	/* Signal Quality Error - see description	*/
+#define MTxStLateColl	0x1000	/* Late Collision - collision after 64 
+								   byte times								*/
+#define MTxStTxPar		0x2000	/* Tx FIFO parity error (manual typo)		*/
+#define MTxStComp		0x4000	/* Completion - MAC tx or discard 1 pkt		*/
+#define MTxStTxHalted	0x8000	/* tx halted by TxEn of HaltImm bits		*/
+/*********************************************************
+ * MAC Receive Control Register (7-40)
+ * MACRXCON - offset 0xA010
+ *********************************************************/
+#define	MRxCtlRxEn		0x0001	/* Rx Enable								*/
+#define	MRxCtlRxHalt	0x0002	/* Rx Halt Request (after rx of current
+								   pkt)										*/
+#define	MRxCtlLongEn	0x0004	/* Long Enable - receive packets >1518 Bytes*/
+#define	MRxCtlShortEn	0x0008	/* Allow rx of pkt < 64 bytes				*/
+#define	MRxCtlStripCRC	0x0010	/* Checks CRC and then strips from msg		*/
+#define	MRxCtlPassCtl	0x0020	/* Enable passing of control pkts to MAC
+								   client									*/
+#define	MRxCtlIgnoreCRC	0x0040	/* Disable CRC value checking				*/
+#define	MRxCtlEnAlign	0x0100	/* Enable alignment interrupt - length is
+								   not a multile of 8 bits and CRC is
+								   invalid									*/
+#define	MRxCtlEnCRCErr	0x0200	/* Enable CRC error interrupt - invalid
+								   CRC or PHY asserts Rx_er					*/
+#define	MRxCtlEnOver	0x0400	/* Enable overflow interrupt - rx when MAC
+								   rx FIFO is full							*/
+#define	MRxCtlEnLongErr	0x0800	/* Enable interrupt on long pkts - see
+								   description								*/
+#define	MRxCtlEnRxPar	0x2000	/* Enable a rx parity interrupt if MAC rx
+								   FIFO  detects parity error				*/
+#define	MRxCtlEnGood	0x4000	/* Enable good (error-free rx of a complete 
+								   data packet) interrupt					*/
+#define MRxCtlINTMask	(MRxCtlEnAlign | MRxCtlEnCRCErr | MRxCtlEnOver |	\
+						 MRxCtlEnLongErr | MRxCtlEnRxPar | MRxCtlEnGood)
+//#define MRxCtlSETUP		(MRxCtlRxEn | MRxCtlStripCRC | MRxCtlINTMask )
+// From usage- we enable rx interrupts later ...MaTed---
+#define MRxCtlSETUP		(MRxCtlRxEn | MRxCtlStripCRC )
+/*********************************************************
+ * MAC Receive Status Register (7-41)
+ * MACRXSTAT - offset 0xA014
+ *********************************************************/
+#define MRxStCtlRead	0x0020	/* Set if MAC Control frame	(type=8808H)
+								   matches CAM and length == 64 			*/
+#define MRxStIntRx		0x0040	/* Interrupt on Rx	*/
+#define MRxStRx10Stat	0x0080	/* set if rx packet over 7 wire, reset if
+								   rx'd	 over MII							*/
+#define MRxStAlignErr	0x0100	/* Set if fram length in bits not a
+								   multiple	of 8 and CRC invalid 			*/
+#define MRxStCRCErr		0x0200	/* CRC does not compute OR PHY asserted
+								   Rx_er									*/
+#define MRxStOverflow	0x0400	/* Set if MAC rx FIFO full when it was
+								   needed to store a rx'd byte				*/
+#define MRxStLongErr	0x0800	/* Set if MAC rx'd frame > 1518 bytes		*/
+#define MRxStRxPar		0x2000	/* Set if parity error in MAC rx FIFO		*/
+#define MRxStGood		0x4000	/* Set if pkt with NO errors rx'd			*/
+#define MRxStRxHalted	0x8000	/* Set if rx halted by RxEn->0 or HaltImm
+								   set										*/
+/*************************************************************
+ * MAC Station Management Data Control and Address (pg 7-43)
+ * STACON - offset 0xA01C
+ *************************************************************/
+#define MStAddr		0x001f	/* 5 bit address contained in PHY of the register
+							   to be read or written						*/
+#define MStPHY		0x03e0	/* 5 bit address of the PHY to be r/w			*/
+#define MStWr		0x0400	/* Set to 1 to iniate write op					*/
+#define MStBusy		0x0800	/* to start r/w op set to 1, MAC clears when
+							   cmd completes								*/
+#define MStPreSup	0x1000	/* Preamble Suppress							*/
+#define MStMDC		0xe000	/* MDC clock rating see doc						*/
+
+/**************************************************/
+
+
+/**********************************************
+ * Structure Definitions
+ **********************************************/
+#if 0 // ...MaTed--- just use the combined one
+/* BDMA Registers for S3c - offset to 0x9000 */
+typedef struct bdma_csr
+{
+  volatile UINT32 TxCtl;		/* 0x00 Buffered DMA transmit control reg	*/
+  volatile UINT32 RxCtl;		/* 0x04 Buffered DMA receive control reg	*/
+  volatile UINT32 TxPtr;		/* 0x08 Tx frame descriptor start addr		*/
+  volatile UINT32 RxPtr;		/* 0x0c Rx frame descriptor start addr		*/
+  volatile UINT32 RxLSz;		/* 0x10 Receive Frame maximum size			*/
+  volatile UINT32 BdmaStat;		/* 0x14 BDMA Status							*/
+  volatile UINT32 reserve1[10];	/* 0x18, 1c, 20, 24, 28, 2c, 30, 34, 38, 3c */
+  volatile UINT32 TxCtlFrStat;	/* 0x40 Transmit control frame status (MAC)	*/
+  volatile UINT32 reserve2[47];	/* 0x44 - 0xfc								*/
+  volatile UINT32 Cam[ 32];		/* 0x100-17f								*/
+} BDMA_CSR;
+/* MAC Registers for S3c - offset to 0xA000 */
+typedef struct mac_csr
+{
+  volatile UINT32 MacCtl;		/* 0x00 MAC Control							*/
+  volatile UINT32 CamCtl;		/* 0x04 CAM Control							*/
+  volatile UINT32 MacTxCtl;		/* 0x08 Transmit Control					*/
+  volatile UINT32 MacTxStat;	/* 0x0c Transmit Status						*/
+  volatile UINT32 MacRxCtl;		/* 0x10 Receive Control						*/
+  volatile UINT32 MacRxStat;	/* 0x14 Receive Status						*/
+  volatile UINT32 SmData;		/* 0x18 Station Management Data				*/
+  volatile UINT32 SmCtl;		/* 0x1c Station Management Control 
+								   and address								*/
+  volatile UINT32 reserve1[2];	/* 0x20 and 0x24 reserved					*/
+  volatile UINT32 CamEn;		/* 0x28 CAM Enable							*/
+  volatile UINT32 reserve2[4];	/* 0x2c, 0x30, 0x34, 0x38 reserve			*/
+  volatile UINT32 MissCnt;		/* 0x3c Missed Error Count					*/
+  volatile UINT32 PauseCnt;		/* 0x40 Received Pause command Count		*/
+  volatile UINT32 RemPauseCnt;	/* 0x44 Remote Pause Count (we sent PAUSE)	*/
+} MAC_CSR;
+#endif // if 0
+/* Combined BDMA and MAC Registers for S3c */
+typedef struct
+{
+  volatile UINT32 TxCtl;		/* 0x00 Buffered DMA transmit control reg	*/
+  volatile UINT32 RxCtl;		/* 0x04 Buffered DMA receive control reg	*/
+  volatile UINT32 TxPtr;		/* 0x08 Tx frame descriptor start addr		*/
+  volatile UINT32 RxPtr;		/* 0x0c Rx frame descriptor start addr		*/
+  volatile UINT32 RxLSz;		/* 0x10 Receive Frame maximum size			*/
+  volatile UINT32 BdmaStat;		/* 0x14 BDMA Status							*/
+  volatile UINT32 reserve1[10];	/* 0x18, 1c, 20, 24, 28, 2c, 30, 34, 38, 3c */
+  volatile UINT32 TxCtlFrStat;	/* 0x40 Transmit control frame status (MAC)	*/
+  volatile UINT32 reserve2[47];	/* 0x44 - 0xfc								*/
+  volatile UINT32 Cam[64];		/* 0x100 -> 0x1ff, CAM Content Only 1st
+								   21*6 bytes used							*/
+  volatile UCHAR  TestTxBuff[256];	/* 0x200 -> 0x2ff, Tx Test buffer		*/
+  UCHAR		reserve3[0x500];		/* 0x300 -> 0x7ff						*/
+  volatile UCHAR  TestRxBuff1[256];	/* 0x800 -> 0x8ff, Rx Test buffer		*/
+  volatile UCHAR  TestRxBuff2[256];	/* 0x900 -> 0x9ff, Rx test buffer		*/
+  UCHAR		reserve4[0x600];	/* 0xa00 -> 0xfff							*/
+  volatile UINT32 MacCtl;		/* 0x1000 MAC Control						*/
+  volatile UINT32 CamCtl;		/* 0x1004 CAM Control						*/
+  volatile UINT32 MacTxCtl;		/* 0x1008 Transmit Control					*/
+  volatile UINT32 MacTxStat;	/* 0x100c Transmit Status					*/
+  volatile UINT32 MacRxCtl;		/* 0x1010 Receive Control					*/
+  volatile UINT32 MacRxStat;	/* 0x1014 Receive Status					*/
+  volatile UINT32 SmData;		/* 0x1018 Station Management Data			*/
+  volatile UINT32 SmCtl;		/* 0x101c Station Management Control 
+								   and address								*/
+  volatile UINT32 reserve5[2];	/* 0x1020 and 0x24 reserved					*/
+  volatile UINT32 CamEn;		/* 0x1028 CAM Enable						*/
+  volatile UINT32 reserve6[4];	/* 0x102c, 0x30, 0x34, 0x38 reserve			*/
+  volatile UINT32 MissCnt;		/* 0x103c Missed Error Count				*/
+  volatile UINT32 PauseCnt;		/* 0x1040 Received Pause command Count		*/
+  volatile UINT32 RemPauseCnt;	/* 0x1044 Remote Pause Cnt (we sent PAUSE)	*/
+} CSR;
+
+/**********************************************************
+ * Frame Descriptor, Buffer Descriptor related parameters.
+ **********************************************************/
+
+#define	OWNERSHIP			0x80000000	/* bit to set for BDMA owns FD		*/
+
+/*****************************
+ * Rx Descriptor Status Bits
+ *****************************/
+									/* SET IF ....						*/
+#define	RxS_OvMax			0x0008	/* Over Maximum Size				*/
+#define	RxS_CtlRcv			0x0020	/* MAC Control Packet Rx'd			*/
+#define	RxS_IntRx			0x0040	/* Interrupt on Rx					*/
+#define RxS_Rx10Stat		0x0080	/* Packet rx'd on 7 wire interface
+									   -reset -> rx'd on MII			*/
+#define	RxS_AlignErr		0x0100	/* Frame length != mutliple of 8 bits
+									   and the CRC was invalid			*/
+#define	RxS_CrcErr			0x0200	/* CRC error OR PHY asserted Rx_er	*/
+#define	RxS_Overflow		0x0400	/* MAC rx FIFO was full when byte 
+									   received							*/
+#define	RxS_LongErr  		0x0800	/* rx'd frame > 1518 bytes			*/
+#define RxS_RxPar			0x2000	/* MAC rx FIFO detected parity error*/
+#define RxS_Good			0x4000	/* Successfully received a packet
+									   with no errors					*/
+#define RXS_RxHalted		0x8000	/* rx interrupted by user (rxEn or
+									   haltimm)							*/
+/*****************************
+ * Tx Descriptor Status Bits
+ *****************************/
+#define TxCollCnt_mask  0x000f		/* # tx collisions						*/
+#define TxCollCnt_shift      0
+#define TxExColl        0x0010		/* 16 collisions occured				*/
+#define TxDefer         0x0020		/* transmission defered					*/
+#define TxPaused        0x0040		/* transmission paused 					*/
+#define TxInt           0x0080		/* pkt tx caused an interrupt 			*/
+#define TxUnder         0x0100		/* tx underrun 							*/
+#define TxMaxDefer      0x0200		/* tx defered for max_defer 			*/
+#define TxNCarr         0x0400		/* carrier sense not detected 			*/
+#define TxSQErr         0x0800		/* SQE error 							*/
+#define TxLateColl      0x1000		/* tx coll after 512 bit times 			*/
+#define TxPar           0x2000		/* tx FIFO parity error 				*/
+#define TxComp          0x4000		/* tx complete or discarded 			*/
+#define TxHalted        0x8000		/* tx halted OR error 					*/
+
+/*****************************
+ * Tx Widget Bits
+ *****************************/
+#define TxWidNoPAD	0x0001			/* set for no padding					*/
+#define TxWidCRC	0x0002			/* set for no CRC 						*/
+#define TxWidIE	 	0x0004			/* Set for interrupt after completion	*/
+#define TxWidLITTLE	0x0008			/* Set for Little endian buffer			*/
+#define TxWidINC	0x0010			/* set for frame data pointer increment	*/
+#define TxWidALIGN	0x0060			/* Alignment of the buffer				*/
+
+#define TxWidSetup	(TxWidIE | TxWidLITTLE | TxWidINC | (2 << 5))
+
+/*****************************************************************
+ * PHYS defines
+ *****************************************************************/
+/**********************************************
+ * PHY - LX972 register and defines
+ **********************************************/
+#define	PHYAddr			0x0001		/* Address of the LX972 for HEI board	*/
+/******* registers *********/
+#define PHYCtl		0 	// Control Register Refer to Table 37 on page 58 
+#define PHYStat		1	// Status Register #1 Refer to Table 38 on page 58
+#define	PHYId1		2 	// PHY Identification Register 1 Refer to Table 39
+						//	on page 59
+#define PHYId2		3	// PHY Identification Register 2 Refer to 
+						//	Table 40 on page 60
+#define PHYANegAd	4	// Auto-Negotiation Advertisement Register
+						//	Refer to Table 41 on page 61
+#define	PHYANegLink 5	// Auto-Negotiation Link Partner Base Page Ability 
+						//	Register Refer to Table 42 on page 62
+#define PHYANegEx	6	// Auto-Negotiation Expansion Register Refer to 
+						//	Table 43 on page 63
+#define PHYANegNext 7	// Auto-Negotiation Next Page Transmit Register
+						//	Refer to Table 44 on page 63
+#define PHYANegLPart 8 	// Auto-Negotiation Link Partner Received Next Page
+						//	Register Refer to Table 45 on page 64
+#define PHY100Ctl	9 	// 1000BASE-T/100BASE-T2 Control Register Not 
+						//	Implemented
+#define PHY100Stat	10	// 1000BASE-T/100BASE-T2 Status Register Not 
+						//	Implemented
+#define PHYExStat	15	// Extended Status Register Not Implemented
+#define	PHYPortCfg	16 	//	Port Configuration Register Refer to Table 
+						//	46 on page 64
+#define PHYStat2	17	// Status Register #2 Refer to Table 47 on page 65
+#define PHYIntEn	18 	// Interrupt Enable Register Refer to Table 48 
+						//	on page 66
+#define PHYIntStat	19	// Interrupt Status Register Refer to Table 49
+						//	on page 66
+#define	PHYLedCfg	20	// LED Configuration Register Refer to Table 50
+						//	on page 68
+		// 21- 29 Reserved
+#define	PHYTxCtl	30 	// Transmit Control Register Refer to Table 51
+						//	on page 69
+/*** Only some of the defines - ones I used ...MaTed ***/
+#define	PHYCtlReset				0x8000	// reset
+#define PHYANegAdMask			0x1e0	// bits for duplex and speed (972)
+#define PHYB8					0x100	// bit 8
+#define PHYB7					0x080	// bit 7
+#define PHYB6					0x040	// bit 6
+#define PHYB5					0x020	// bit 5
+#define	PHYLEDCFG				0xD0F2	// LED 1 (left - link and activity
+										//     2 (right - Speed)
+#define	PHYLEDANEG				0x1e1	// Advertize AutoNeg all speed / duplex
+
+#define PHY_BUSYLOOP_COUNT		100		// each loop is 10mS -> 1S
+#define PHY_RESETLOOP_COUNT		10		// number of times to check reset 
+										//  10 ms between checks - manual
+										//  states 300 uS max fro reset to work
+#define	PHY_NEGLOOP_COUNT		150		// 1.5 seconds for Autoneg to complete
+
+/**** Following are from previous version of the PHY routines -- delete ***/
+#define PHY_RESET		0x8000
+#define PHY_LINK_UP		0x0400
+#define PHYMODE_100		0x4000 /* for 100 mbps*/
+#define PHYFULL_DUPLEX	0x0200
+
+#define SPEED_AUTO		0xFFFFFF9F	/* Set the MAC speed to Automatic mode.
+									   AND operation */
+#define SPEED_10		0xFFFFFFBF	/* Set the MAC speed to Automatic mode.
+									   OR operation */
+
+#define PHY_10MBS       1
+#define PHY_100MBS      2
+#define PHY_AUTO_SPEED  0
+
+// These don't really match up
+#define PHY_FULL_DPX    1
+#define PHY_HALF_DPX    0
+#define PHY_AUTO_DPX    2
+
+/**********************************
+ * Bit Defines for PHY972_CONTROL
+ **********************************/
+#define PHY_CONTROL_RESET           0x8000
+#define PHY_CONTROL_LOOPBACK        0x4000
+#define PHY_CONTROL_SELECT_SPEED    0x2000
+#define PHY_CONTROL_AUTONEG		    0x1000
+#define PHY_CONTROL_POWERDOWN       0x0800
+#define PHY_CONTROL_ISOLATE         0x0400
+#define PHY_CONTROL_RESTART_AUTONEG 0x0200
+#define PHY_CONTROL_DUPLEXMODE      0x0100
+#define PHY_CONTROL_COLLISION_TEST  0x0080
+#define PHY_CONTROL_SPEED_10_HALF   0x0000
+#define PHY_CONTROL_SPEED_10_FULL   (PHY_CONTROL_DUPLEXMODE)
+#define PHY_CONTROL_SPEED_100_HALF  (PHY_CONTROL_SELECT_SPEED )
+#define PHY_CONTROL_SPEED_100_FULL  (PHY_CONTROL_SELECT_SPEED \
+			| PHY_CONTROL_DUPLEXMODE)
+#define PHY_CONTROL_AUTONEG_HALF_10	(0x1000 | PHY_CONTROL_RESTART_AUTONEG)
+#define PHY_CONTROL_AUTONEG_FULL_10	(0X1100 | PHY_CONTROL_RESTART_AUTONEG)
+#define PHY_CONTROL_AUTONEG_HALF_100	(0x3000 | PHY_CONTROL_RESTART_AUTONEG)
+#define PHY_CONTROL_AUTONEG_FULL_100	(0X3100 | PHY_CONTROL_RESTART_AUTONEG)
+ 
+/*****************************************
+ * Bit Defines for PHY972_STATUS_REG_ONE
+ *****************************************/
+    /* not used                                     0x8000  */
+#define PHY_STATUS_REG_TWO_MODE_100             0x4000
+#define PHY_STATUS_REG_TWO_TX_STATUS            0x2000
+#define PHY_STATUS_REG_TWO_RX_STATUS            0x1000
+#define PHY_STATUS_REG_TWO_COLLISION_STATUS     0x0800
+#define PHY_STATUS_REG_TWO_LINK                 0x0400
+#define PHY_STATUS_REG_TWO_DUPLEX_MODE          0x0200
+#define PHY_STATUS_REG_TWO_AUTO_NEGOTIATION     0x0100
+#define PHY_STATUS_REG_TWO_AUTO_NEGO_COMPELETE  0x0080
+    /* not used                                 0x0040  */
+#define PHY_STATUS_REG_TWO_POLARITY             0x0020
+#define PHY_STATUS_REG_TWO_PAUSE                0x0010
+#define PHY_STATUS_REG_TWO_ERROR                0x0008
+    /* not used                                 0x0004  */
+    /* not used                                 0x0002  */
+    /* not used                                 0x0001  */
+
+/*******************************************
+ +--------+---------+--------+-------------+
+  Byte 3     Byte 2    Byte 1     Byte 0
+ +--------+---------+--------+-------------+
+            RX FRAME DESCRIPTOR
+ +--+--------------------------------------+
+ |O |        Frame Data Pointer			   | 0x00
+ +--+--------------------------------------+
+ |              Reserved			       | 0x04
+ +------------------+----------------------+
+ |   Rx Status      |		Frame Length   | 0x08	
+ +------------------+----------------------+
+ |       Next Frame Descriptor Pointer     | 0x0c
+ +-----------------------------------------+
+	O - Ownership 1->BDMA, 0->CPU
+
+
+           TX FRAME DESCRIPTOR
+ +--+--------------------------------------+
+ |O |        Frame Data Pointer			   | 0x00
+ +--+-------------------------+--+-+-+-+-+-+
+ |              Reserved	  |WA|A|L|T|C|P| 0x04
+ +------------------+---------+--+-+-+-+-+-+
+ |   Tx Status      |		Frame Length   | 0x08	
+ +------------------+----------------------+
+ |       Next Frame Descriptor Pointer     | 0x0c
+ +-----------------------------------------+
+	O - Ownership: 1->BDMA, 0->CPU
+	P - No Padding:	1->No Padding Mode, 0->Padding enabled
+	C - No CRC: 1->No CRC, 0->CRC enabled
+	T - TX Interrupt Enable: 1->Interrupt Enable after tx of this frame
+	L - Little Endian: 1->little endian, 0->Big Endian mode
+	A - Frame data pointer increment: 1->increment. 0-> decrement
+	WA- Widget Alignment: (cf fig 7-7)
+
+**********************************************/
+
+
+#if 0	// bit patterns didn't compile well ...MaTed
+/***********************************************
+ * Rx Status for Ethernet MAC of S3c
+ ***********************************************/
+typedef struct _RxST
+{
+  UINT	reserve1 	: 3;
+									/* SET IF ....						*/
+  UINT	OvMax 	: 1;	//	0x0008	Over Maximum Size
+  UNIT	reserve2	: 1;
+  UINT	CtlRxd		: 1;	//	0x0020	MAC Control Packet Rx'd
+  UINT	IntRx		: 1;	//	0x0040	Interrupt on Rx
+qq  UINT	Rx10Stat	: 1;	//	0x0080	Packet rx'd on 7 wire interface
+							//		   -reset -> rx'd on MII
+  UINT	AlignErr	: 1;	//	0x0100	Frame length != mutliple of 8 bits
+							//			and the CRC was invalid
+  UINT	CRCErr		: 1;	//	0x0200	CRC error OR PHY asserted Rx_er
+  UINT	OverflowErr	: 1;	//	0x0400	MAC rx FIFO was full when byte 
+							//			received
+  UINT	LongErr		: 1;	//	0x0800	rx'd frame > 1518 bytes
+  UINT	reserve3	: 1;
+  UINT	RxParErr	: 1;	//	0x2000	MAC rx FIFO detected parity error
+  UINT	RxGood		: 1;	//	0x4000	Successfully received a packet
+							//			with no errors
+  UINT	RxHalted	: 1;	//	0x8000	rx interrupted by user (rxEn or
+							//		   haltimm)
+} RxST;
+/***********************************************
+ * Tx Status for Ethernet MAC of S3c
+ ***********************************************/
+typedef struct _TxST
+{
+  UINT CollCnt	:4;	//	0x000f	# tx collisions
+  UINT ExColl	:1;	//	0x0010	16 collisions occured
+  UINT Defer	:1;	//	0x0020	transmission defered
+  UINT Paused	:1;	//	0x0040	transmission paused
+  UINT IntTx	:1;	//	0x0080	pkt tx caused an interrupt
+  UINT Under	:1;	//	0x0100	tx underrun
+  UINT Defer	:1;	//	0x0200	defered for max_defer
+  UINT NoCarr	:1;	//	0x0400	carrier sense not detected
+  UINT SQErr	:1;	//	0x0800	SQE error
+  UINT LateColl :1;	//	0x1000	tx coll after 512 bit times
+  UINT TxPar	:1;	//	0x2000	tx FIFO parity error
+  UINT Comp		:1;	//	0x4000	tx complete or discarded
+  UINT TxHalted	:1;	//	0x8000	tx halted OR error
+} TxST;
+/******************************
+ * Tx Modes (FD)
+ ******************************/
+typedef struct _TxMODE
+{
+  UINT P	:1;	// No Padding:	1->No Padding Mode, 0->Padding enabled
+  UINT C	:1;	// No CRC: 1->No CRC, 0->CRC enabled
+  UINT T	:1;	// TX Interrupt Enable: 1->Interrupt Enable after tx 
+				//  of this frame
+  UINT L	:1;	// Little Endian: 1->little endian, 0->Big Endian mode
+  UINT A	:1;	// Frame data pointer increment: 1->increment. 0-> decrement
+  UINT WA	:1;	// Widget Alignment: (cf fig 7-7)
+} TxMODE;
+#endif	// if 0
+/***********************************************
+ * RX Frame Descriptors for Ethernet MAC of S3c
+ ***********************************************/
+typedef struct _RxFD
+{
+  volatile	UCHAR		*	FDDataPtr;
+  UINT32       				reserved;
+  volatile	UINT16        	FDLength;
+  //  volatile	RxST		FDStat;
+  volatile	UINT16			FDStat;
+  volatile	struct _RxFD *	FDNext;
+} RxFD;
+/******************************
+ * RX Frame Descriptor System 
+ ******************************/
+typedef struct _RxFDS
+{
+  RxFD				fd;			// rx frame descriptor
+  struct sk_buff *	skb;		// address of preallocated SKB
+  // NOTE :: FIXME ...MaTed--- the next probably isn't needed
+  UINT32			reserve[ 3 ];	// NOTE: keeping Quad word alligned
+}RxFDS;
+/***********************************************
+ * TX Frame Descriptors for Ethernet MAC of S3c
+ ***********************************************/
+typedef struct _TxFD
+{
+  volatile	UCHAR		  *	FDDataPtr;	// Pointer to data to be tx'd
+  //volatile	TXMODES		FDModes;   	
+  volatile	UCHAR			FDModes;   	
+  UCHAR						reserve2;
+  UINT16		        	reserve1;
+  //  volatile	TxST        FDStat;
+  volatile	UINT16	       	FDLength;
+  volatile	UINT16	       	FDStat;
+  volatile	struct _TxFD  *	FDNext;
+} TxFD;
+/******************************
+ * TX Frame Descriptor System 
+ ******************************/
+typedef struct _TxFDS
+{
+  TxFD				fd;			// tx frame descriptor
+  struct sk_buff *	skb;		// skb that is being txmitted
+  // NOTE :: FIXME ...MaTed--- the next probably isn't needed
+  UINT32 *			reserve[ 3 ];	// NOTE: keeping Quad word alligned
+} TxFDS;
+
+
+/*****************************************
+ * Single Rx Buffer
+ *****************************************/
+typedef struct _RxBUF
+{
+  UCHAR	buffer[ PKT_BUF_SZ ];
+} RxBUF;
+/**********************
+ * Control structures
+ **********************/
+/********************************
+ * Simple Buffer Pointer Struct
+ ********************************/
+typedef struct _BPTR
+{
+  void *	first;		// first in the linked list
+  void *	last;		// last in the linked list
+  UINT32	num;		// number of elements in the linked list
+                        //  mostly for stats
+} BPTR;
+  
+/**********************************************************
+ * PRIV structure
+ * Information that need to be kept for each MAC / board
+ *  Use net_device.priv to keep pointer to this struct
+ **********************************************************/
+typedef struct
+{  /* MAC specific infomation */
+   /*
+   * configuration parameters,
+   * - user can override later in /proc?? (still have to do this)
+   */
+  UINT8		phySpeed;		// 00-Auto, 0x1-10 Mbs, 0x2-100Mbs, 0x3-Auto
+  UINT8		phyDpx;			// duplex 00-Half, 0x1-Full (not valid with??)
+  UINT16	tcbTxThresh;	// Transmit Threshold for fifo dma xfer
+ 
+  /* Tx control lock.  This protects the transmit buffer ring
+   * state along with the "tx full" state of the driver.  This
+   * means all netif_queue flow control actions are protected
+   * by this lock as well.
+   */
+  spinlock_t	lock;
+
+  /*
+   * Need a storage place to save which SKB destructor routine to use
+   */
+  void (*destructor)(struct sk_buff *);   /* Destruct function */
+/************************************************************************
+ * For Receive and Transmit, S3c Buffer Control Structure.		*
+ * Each Structre points to it own buffer space and contains interface   *
+ * related information. The structre contains the link list for the     *
+ * buffer.                                                              *
+ ************************************************************************/
+  /*
+   * Queue control into data structures to S3C MAC
+   */
+  BPTR	qRx;		// Receive Frame Descriptor Ready List
+  BPTR	qRxWait;	// Receive Frame Descriptor Not Ready List
+  BPTR	qTx;		// Transmit Frame Descriptor List
+
+  /*
+   * Data structures to communicate with S3C MAC
+   */
+  RxFDS ___align16	rxFd[ RX_NUM_FD ];
+  TxFDS	___align16	txFd[ TX_NUM_FD ];
+  /*** Statistics ***/
+  struct net_device_stats	stats;		// standard statistics
+  struct
+  {
+	UINT32	BRxNl;		// BDMARxPtr has null list
+	UINT32	BRxNo;		// BDMA rx is not the owner of the current data frame
+						//	pointed to. Rx is stopped
+	UINT32	BTxCp;		// BDMA tx indicates MAC sent a control packet
+	UINT32	BTxNl;		// BDMATxPtr has a null list
+	UINT32	BTxNo;		// BDMA tx is not the owner of the current data frame
+						//	pointed to. Tx is stopped
+  } bdmaStats;
+} S3C_MAC;
+
+
+/********************************************************************
+ * Prototypes for external routines
+ ********************************************************************/
+extern void enable_samsung_irq( int int_num);
+extern void disable_samsung_irq( int int_num);
+extern inline void invalidate_dcache_line( unsigned long addr);
+extern unsigned char * get_MAC_address( char * name);
+//extern int get_ethernet_addr( char * ethaddr_name, char *ethernet_addr);
diff -urN linux-2.4.29/drivers/net/sha1dgst.c linux-2.4.29-uc1/drivers/net/sha1dgst.c
--- linux-2.4.29/drivers/net/sha1dgst.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sha1dgst.c	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,73 @@
+/* crypto/sha/sha1dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#if !defined(NO_SHA1) && !defined(NO_SHA)
+
+#undef  SHA_0
+#define SHA_1
+
+#include <openssl/opensslv.h>
+
+const char *SHA1_version="SHA1" OPENSSL_VERSION_PTEXT;
+
+/* The implementation is in ../md32_common.h */
+
+#include "sha_locl.h"
+
+#endif
+
diff -urN linux-2.4.29/drivers/net/sha_locl.h linux-2.4.29-uc1/drivers/net/sha_locl.h
--- linux-2.4.29/drivers/net/sha_locl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sha_locl.h	2005-06-14 02:12:15.000000000 +0100
@@ -0,0 +1,473 @@
+/* crypto/sha/sha_locl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef __KERNEL__
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#include <openssl/opensslconf.h>
+#include <openssl/sha.h>
+
+#ifndef SHA_LONG_LOG2
+#define SHA_LONG_LOG2	2	/* default to 32 bits */
+#endif
+
+#define DATA_ORDER_IS_BIG_ENDIAN
+
+#define HASH_LONG               SHA_LONG
+#define HASH_LONG_LOG2          SHA_LONG_LOG2
+#define HASH_CTX                SHA_CTX
+#define HASH_CBLOCK             SHA_CBLOCK
+#define HASH_LBLOCK             SHA_LBLOCK
+#define HASH_MAKE_STRING(c,s)   do {	\
+	unsigned long ll;		\
+	ll=(c)->h0; HOST_l2c(ll,(s));	\
+	ll=(c)->h1; HOST_l2c(ll,(s));	\
+	ll=(c)->h2; HOST_l2c(ll,(s));	\
+	ll=(c)->h3; HOST_l2c(ll,(s));	\
+	ll=(c)->h4; HOST_l2c(ll,(s));	\
+	} while (0)
+
+#if defined(SHA_0)
+
+# define HASH_UPDATE             	SHA_Update
+# define HASH_TRANSFORM          	SHA_Transform
+# define HASH_FINAL              	SHA_Final
+# define HASH_INIT			SHA_Init
+# define HASH_BLOCK_HOST_ORDER   	sha_block_host_order
+# define HASH_BLOCK_DATA_ORDER   	sha_block_data_order
+# define Xupdate(a,ix,ia,ib,ic,id)	(ix=(a)=(ia^ib^ic^id))
+
+  void sha_block_host_order (SHA_CTX *c, const void *p,int num);
+  void sha_block_data_order (SHA_CTX *c, const void *p,int num);
+
+#elif defined(SHA_1)
+
+# define HASH_UPDATE             	SHA1_Update
+# define HASH_TRANSFORM          	SHA1_Transform
+# define HASH_FINAL              	SHA1_Final
+# define HASH_INIT			SHA1_Init
+# define HASH_BLOCK_HOST_ORDER   	sha1_block_host_order
+# define HASH_BLOCK_DATA_ORDER   	sha1_block_data_order
+# if defined(__MWERKS__) && defined(__MC68K__)
+   /* Metrowerks for Motorola fails otherwise:-( <appro@fy.chalmers.se> */
+#  define Xupdate(a,ix,ia,ib,ic,id)	do { (a)=(ia^ib^ic^id);		\
+					     ix=(a)=ROTATE((a),1);	\
+					} while (0)
+# else
+#  define Xupdate(a,ix,ia,ib,ic,id)	( (a)=(ia^ib^ic^id),	\
+					  ix=(a)=ROTATE((a),1)	\
+					)
+# endif
+
+# ifdef SHA1_ASM
+#  if defined(__i386) || defined(_M_IX86) || defined(__INTEL__)
+#   define sha1_block_host_order		sha1_block_asm_host_order
+#   define DONT_IMPLEMENT_BLOCK_HOST_ORDER
+#   define sha1_block_data_order		sha1_block_asm_data_order
+#   define DONT_IMPLEMENT_BLOCK_DATA_ORDER
+#   define HASH_BLOCK_DATA_ORDER_ALIGNED	sha1_block_asm_data_order
+#  endif
+# endif
+  void sha1_block_host_order (SHA_CTX *c, const void *p,int num);
+  void sha1_block_data_order (SHA_CTX *c, const void *p,int num);
+
+#else
+# error "Either SHA_0 or SHA_1 must be defined."
+#endif
+
+#include "md32_common.h"
+
+#define INIT_DATA_h0 0x67452301UL
+#define INIT_DATA_h1 0xefcdab89UL
+#define INIT_DATA_h2 0x98badcfeUL
+#define INIT_DATA_h3 0x10325476UL
+#define INIT_DATA_h4 0xc3d2e1f0UL
+
+void HASH_INIT (SHA_CTX *c)
+	{
+	c->h0=INIT_DATA_h0;
+	c->h1=INIT_DATA_h1;
+	c->h2=INIT_DATA_h2;
+	c->h3=INIT_DATA_h3;
+	c->h4=INIT_DATA_h4;
+	c->Nl=0;
+	c->Nh=0;
+	c->num=0;
+	}
+
+#define K_00_19	0x5a827999UL
+#define K_20_39 0x6ed9eba1UL
+#define K_40_59 0x8f1bbcdcUL
+#define K_60_79 0xca62c1d6UL
+
+/* As  pointed out by Wei Dai <weidai@eskimo.com>, F() below can be
+ * simplified to the code in F_00_19.  Wei attributes these optimisations
+ * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
+ * #define F(x,y,z) (((x) & (y))  |  ((~(x)) & (z)))
+ * I've just become aware of another tweak to be made, again from Wei Dai,
+ * in F_40_59, (x&a)|(y&a) -> (x|y)&a
+ */
+#define	F_00_19(b,c,d)	((((c) ^ (d)) & (b)) ^ (d)) 
+#define	F_20_39(b,c,d)	((b) ^ (c) ^ (d))
+#define F_40_59(b,c,d)	(((b) & (c)) | (((b)|(c)) & (d))) 
+#define	F_60_79(b,c,d)	F_20_39(b,c,d)
+
+#define BODY_00_15(i,a,b,c,d,e,f,xi) \
+	(f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
+	Xupdate(f,xi,xa,xb,xc,xd); \
+	(f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
+	Xupdate(f,xi,xa,xb,xc,xd); \
+	(f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+	Xupdate(f,xa,xa,xb,xc,xd); \
+	(f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+	Xupdate(f,xa,xa,xb,xc,xd); \
+	(f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+	Xupdate(f,xa,xa,xb,xc,xd); \
+	(f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#ifdef X
+#undef X
+#endif
+#ifndef MD32_XARRAY
+  /*
+   * Originally X was an array. As it's automatic it's natural
+   * to expect RISC compiler to accomodate at least part of it in
+   * the register bank, isn't it? Unfortunately not all compilers
+   * "find" this expectation reasonable:-( On order to make such
+   * compilers generate better code I replace X[] with a bunch of
+   * X0, X1, etc. See the function body below...
+   *					<appro@fy.chalmers.se>
+   */
+# define X(i)	XX##i
+#else
+  /*
+   * However! Some compilers (most notably HP C) get overwhelmed by
+   * that many local variables so that we have to have the way to
+   * fall down to the original behavior.
+   */
+# define X(i)	XX[i]
+#endif
+
+#ifndef DONT_IMPLEMENT_BLOCK_HOST_ORDER
+void HASH_BLOCK_HOST_ORDER (SHA_CTX *c, const void *d, int num)
+	{
+	const SHA_LONG *W=d;
+	register unsigned long A,B,C,D,E,T;
+#ifndef MD32_XARRAY
+	unsigned long	XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+			XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
+#else
+	SHA_LONG	XX[16];
+#endif
+
+	A=c->h0;
+	B=c->h1;
+	C=c->h2;
+	D=c->h3;
+	E=c->h4;
+
+	for (;;)
+		{
+	BODY_00_15( 0,A,B,C,D,E,T,W[ 0]);
+	BODY_00_15( 1,T,A,B,C,D,E,W[ 1]);
+	BODY_00_15( 2,E,T,A,B,C,D,W[ 2]);
+	BODY_00_15( 3,D,E,T,A,B,C,W[ 3]);
+	BODY_00_15( 4,C,D,E,T,A,B,W[ 4]);
+	BODY_00_15( 5,B,C,D,E,T,A,W[ 5]);
+	BODY_00_15( 6,A,B,C,D,E,T,W[ 6]);
+	BODY_00_15( 7,T,A,B,C,D,E,W[ 7]);
+	BODY_00_15( 8,E,T,A,B,C,D,W[ 8]);
+	BODY_00_15( 9,D,E,T,A,B,C,W[ 9]);
+	BODY_00_15(10,C,D,E,T,A,B,W[10]);
+	BODY_00_15(11,B,C,D,E,T,A,W[11]);
+	BODY_00_15(12,A,B,C,D,E,T,W[12]);
+	BODY_00_15(13,T,A,B,C,D,E,W[13]);
+	BODY_00_15(14,E,T,A,B,C,D,W[14]);
+	BODY_00_15(15,D,E,T,A,B,C,W[15]);
+
+	BODY_16_19(16,C,D,E,T,A,B,X( 0),W[ 0],W[ 2],W[ 8],W[13]);
+	BODY_16_19(17,B,C,D,E,T,A,X( 1),W[ 1],W[ 3],W[ 9],W[14]);
+	BODY_16_19(18,A,B,C,D,E,T,X( 2),W[ 2],W[ 4],W[10],W[15]);
+	BODY_16_19(19,T,A,B,C,D,E,X( 3),W[ 3],W[ 5],W[11],X( 0));
+
+	BODY_20_31(20,E,T,A,B,C,D,X( 4),W[ 4],W[ 6],W[12],X( 1));
+	BODY_20_31(21,D,E,T,A,B,C,X( 5),W[ 5],W[ 7],W[13],X( 2));
+	BODY_20_31(22,C,D,E,T,A,B,X( 6),W[ 6],W[ 8],W[14],X( 3));
+	BODY_20_31(23,B,C,D,E,T,A,X( 7),W[ 7],W[ 9],W[15],X( 4));
+	BODY_20_31(24,A,B,C,D,E,T,X( 8),W[ 8],W[10],X( 0),X( 5));
+	BODY_20_31(25,T,A,B,C,D,E,X( 9),W[ 9],W[11],X( 1),X( 6));
+	BODY_20_31(26,E,T,A,B,C,D,X(10),W[10],W[12],X( 2),X( 7));
+	BODY_20_31(27,D,E,T,A,B,C,X(11),W[11],W[13],X( 3),X( 8));
+	BODY_20_31(28,C,D,E,T,A,B,X(12),W[12],W[14],X( 4),X( 9));
+	BODY_20_31(29,B,C,D,E,T,A,X(13),W[13],W[15],X( 5),X(10));
+	BODY_20_31(30,A,B,C,D,E,T,X(14),W[14],X( 0),X( 6),X(11));
+	BODY_20_31(31,T,A,B,C,D,E,X(15),W[15],X( 1),X( 7),X(12));
+
+	BODY_32_39(32,E,T,A,B,C,D,X( 0),X( 2),X( 8),X(13));
+	BODY_32_39(33,D,E,T,A,B,C,X( 1),X( 3),X( 9),X(14));
+	BODY_32_39(34,C,D,E,T,A,B,X( 2),X( 4),X(10),X(15));
+	BODY_32_39(35,B,C,D,E,T,A,X( 3),X( 5),X(11),X( 0));
+	BODY_32_39(36,A,B,C,D,E,T,X( 4),X( 6),X(12),X( 1));
+	BODY_32_39(37,T,A,B,C,D,E,X( 5),X( 7),X(13),X( 2));
+	BODY_32_39(38,E,T,A,B,C,D,X( 6),X( 8),X(14),X( 3));
+	BODY_32_39(39,D,E,T,A,B,C,X( 7),X( 9),X(15),X( 4));
+
+	BODY_40_59(40,C,D,E,T,A,B,X( 8),X(10),X( 0),X( 5));
+	BODY_40_59(41,B,C,D,E,T,A,X( 9),X(11),X( 1),X( 6));
+	BODY_40_59(42,A,B,C,D,E,T,X(10),X(12),X( 2),X( 7));
+	BODY_40_59(43,T,A,B,C,D,E,X(11),X(13),X( 3),X( 8));
+	BODY_40_59(44,E,T,A,B,C,D,X(12),X(14),X( 4),X( 9));
+	BODY_40_59(45,D,E,T,A,B,C,X(13),X(15),X( 5),X(10));
+	BODY_40_59(46,C,D,E,T,A,B,X(14),X( 0),X( 6),X(11));
+	BODY_40_59(47,B,C,D,E,T,A,X(15),X( 1),X( 7),X(12));
+	BODY_40_59(48,A,B,C,D,E,T,X( 0),X( 2),X( 8),X(13));
+	BODY_40_59(49,T,A,B,C,D,E,X( 1),X( 3),X( 9),X(14));
+	BODY_40_59(50,E,T,A,B,C,D,X( 2),X( 4),X(10),X(15));
+	BODY_40_59(51,D,E,T,A,B,C,X( 3),X( 5),X(11),X( 0));
+	BODY_40_59(52,C,D,E,T,A,B,X( 4),X( 6),X(12),X( 1));
+	BODY_40_59(53,B,C,D,E,T,A,X( 5),X( 7),X(13),X( 2));
+	BODY_40_59(54,A,B,C,D,E,T,X( 6),X( 8),X(14),X( 3));
+	BODY_40_59(55,T,A,B,C,D,E,X( 7),X( 9),X(15),X( 4));
+	BODY_40_59(56,E,T,A,B,C,D,X( 8),X(10),X( 0),X( 5));
+	BODY_40_59(57,D,E,T,A,B,C,X( 9),X(11),X( 1),X( 6));
+	BODY_40_59(58,C,D,E,T,A,B,X(10),X(12),X( 2),X( 7));
+	BODY_40_59(59,B,C,D,E,T,A,X(11),X(13),X( 3),X( 8));
+
+	BODY_60_79(60,A,B,C,D,E,T,X(12),X(14),X( 4),X( 9));
+	BODY_60_79(61,T,A,B,C,D,E,X(13),X(15),X( 5),X(10));
+	BODY_60_79(62,E,T,A,B,C,D,X(14),X( 0),X( 6),X(11));
+	BODY_60_79(63,D,E,T,A,B,C,X(15),X( 1),X( 7),X(12));
+	BODY_60_79(64,C,D,E,T,A,B,X( 0),X( 2),X( 8),X(13));
+	BODY_60_79(65,B,C,D,E,T,A,X( 1),X( 3),X( 9),X(14));
+	BODY_60_79(66,A,B,C,D,E,T,X( 2),X( 4),X(10),X(15));
+	BODY_60_79(67,T,A,B,C,D,E,X( 3),X( 5),X(11),X( 0));
+	BODY_60_79(68,E,T,A,B,C,D,X( 4),X( 6),X(12),X( 1));
+	BODY_60_79(69,D,E,T,A,B,C,X( 5),X( 7),X(13),X( 2));
+	BODY_60_79(70,C,D,E,T,A,B,X( 6),X( 8),X(14),X( 3));
+	BODY_60_79(71,B,C,D,E,T,A,X( 7),X( 9),X(15),X( 4));
+	BODY_60_79(72,A,B,C,D,E,T,X( 8),X(10),X( 0),X( 5));
+	BODY_60_79(73,T,A,B,C,D,E,X( 9),X(11),X( 1),X( 6));
+	BODY_60_79(74,E,T,A,B,C,D,X(10),X(12),X( 2),X( 7));
+	BODY_60_79(75,D,E,T,A,B,C,X(11),X(13),X( 3),X( 8));
+	BODY_60_79(76,C,D,E,T,A,B,X(12),X(14),X( 4),X( 9));
+	BODY_60_79(77,B,C,D,E,T,A,X(13),X(15),X( 5),X(10));
+	BODY_60_79(78,A,B,C,D,E,T,X(14),X( 0),X( 6),X(11));
+	BODY_60_79(79,T,A,B,C,D,E,X(15),X( 1),X( 7),X(12));
+	
+	c->h0=(c->h0+E)&0xffffffffL; 
+	c->h1=(c->h1+T)&0xffffffffL;
+	c->h2=(c->h2+A)&0xffffffffL;
+	c->h3=(c->h3+B)&0xffffffffL;
+	c->h4=(c->h4+C)&0xffffffffL;
+
+	if (--num <= 0) break;
+
+	A=c->h0;
+	B=c->h1;
+	C=c->h2;
+	D=c->h3;
+	E=c->h4;
+
+	W+=SHA_LBLOCK;
+		}
+	}
+#endif
+
+#ifndef DONT_IMPLEMENT_BLOCK_DATA_ORDER
+void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, int num)
+	{
+	const unsigned char *data=p;
+	register unsigned long A,B,C,D,E,T,l;
+#ifndef MD32_XARRAY
+	unsigned long	XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+			XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
+#else
+	SHA_LONG	XX[16];
+#endif
+
+	A=c->h0;
+	B=c->h1;
+	C=c->h2;
+	D=c->h3;
+	E=c->h4;
+
+	for (;;)
+		{
+
+	HOST_c2l(data,l); X( 0)=l;		HOST_c2l(data,l); X( 1)=l;
+	BODY_00_15( 0,A,B,C,D,E,T,X( 0));	HOST_c2l(data,l); X( 2)=l;
+	BODY_00_15( 1,T,A,B,C,D,E,X( 1));	HOST_c2l(data,l); X( 3)=l;
+	BODY_00_15( 2,E,T,A,B,C,D,X( 2));	HOST_c2l(data,l); X( 4)=l;
+	BODY_00_15( 3,D,E,T,A,B,C,X( 3));	HOST_c2l(data,l); X( 5)=l;
+	BODY_00_15( 4,C,D,E,T,A,B,X( 4));	HOST_c2l(data,l); X( 6)=l;
+	BODY_00_15( 5,B,C,D,E,T,A,X( 5));	HOST_c2l(data,l); X( 7)=l;
+	BODY_00_15( 6,A,B,C,D,E,T,X( 6));	HOST_c2l(data,l); X( 8)=l;
+	BODY_00_15( 7,T,A,B,C,D,E,X( 7));	HOST_c2l(data,l); X( 9)=l;
+	BODY_00_15( 8,E,T,A,B,C,D,X( 8));	HOST_c2l(data,l); X(10)=l;
+	BODY_00_15( 9,D,E,T,A,B,C,X( 9));	HOST_c2l(data,l); X(11)=l;
+	BODY_00_15(10,C,D,E,T,A,B,X(10));	HOST_c2l(data,l); X(12)=l;
+	BODY_00_15(11,B,C,D,E,T,A,X(11));	HOST_c2l(data,l); X(13)=l;
+	BODY_00_15(12,A,B,C,D,E,T,X(12));	HOST_c2l(data,l); X(14)=l;
+	BODY_00_15(13,T,A,B,C,D,E,X(13));	HOST_c2l(data,l); X(15)=l;
+	BODY_00_15(14,E,T,A,B,C,D,X(14));
+	BODY_00_15(15,D,E,T,A,B,C,X(15));
+
+	BODY_16_19(16,C,D,E,T,A,B,X( 0),X( 0),X( 2),X( 8),X(13));
+	BODY_16_19(17,B,C,D,E,T,A,X( 1),X( 1),X( 3),X( 9),X(14));
+	BODY_16_19(18,A,B,C,D,E,T,X( 2),X( 2),X( 4),X(10),X(15));
+	BODY_16_19(19,T,A,B,C,D,E,X( 3),X( 3),X( 5),X(11),X( 0));
+
+	BODY_20_31(20,E,T,A,B,C,D,X( 4),X( 4),X( 6),X(12),X( 1));
+	BODY_20_31(21,D,E,T,A,B,C,X( 5),X( 5),X( 7),X(13),X( 2));
+	BODY_20_31(22,C,D,E,T,A,B,X( 6),X( 6),X( 8),X(14),X( 3));
+	BODY_20_31(23,B,C,D,E,T,A,X( 7),X( 7),X( 9),X(15),X( 4));
+	BODY_20_31(24,A,B,C,D,E,T,X( 8),X( 8),X(10),X( 0),X( 5));
+	BODY_20_31(25,T,A,B,C,D,E,X( 9),X( 9),X(11),X( 1),X( 6));
+	BODY_20_31(26,E,T,A,B,C,D,X(10),X(10),X(12),X( 2),X( 7));
+	BODY_20_31(27,D,E,T,A,B,C,X(11),X(11),X(13),X( 3),X( 8));
+	BODY_20_31(28,C,D,E,T,A,B,X(12),X(12),X(14),X( 4),X( 9));
+	BODY_20_31(29,B,C,D,E,T,A,X(13),X(13),X(15),X( 5),X(10));
+	BODY_20_31(30,A,B,C,D,E,T,X(14),X(14),X( 0),X( 6),X(11));
+	BODY_20_31(31,T,A,B,C,D,E,X(15),X(15),X( 1),X( 7),X(12));
+
+	BODY_32_39(32,E,T,A,B,C,D,X( 0),X( 2),X( 8),X(13));
+	BODY_32_39(33,D,E,T,A,B,C,X( 1),X( 3),X( 9),X(14));
+	BODY_32_39(34,C,D,E,T,A,B,X( 2),X( 4),X(10),X(15));
+	BODY_32_39(35,B,C,D,E,T,A,X( 3),X( 5),X(11),X( 0));
+	BODY_32_39(36,A,B,C,D,E,T,X( 4),X( 6),X(12),X( 1));
+	BODY_32_39(37,T,A,B,C,D,E,X( 5),X( 7),X(13),X( 2));
+	BODY_32_39(38,E,T,A,B,C,D,X( 6),X( 8),X(14),X( 3));
+	BODY_32_39(39,D,E,T,A,B,C,X( 7),X( 9),X(15),X( 4));
+
+	BODY_40_59(40,C,D,E,T,A,B,X( 8),X(10),X( 0),X( 5));
+	BODY_40_59(41,B,C,D,E,T,A,X( 9),X(11),X( 1),X( 6));
+	BODY_40_59(42,A,B,C,D,E,T,X(10),X(12),X( 2),X( 7));
+	BODY_40_59(43,T,A,B,C,D,E,X(11),X(13),X( 3),X( 8));
+	BODY_40_59(44,E,T,A,B,C,D,X(12),X(14),X( 4),X( 9));
+	BODY_40_59(45,D,E,T,A,B,C,X(13),X(15),X( 5),X(10));
+	BODY_40_59(46,C,D,E,T,A,B,X(14),X( 0),X( 6),X(11));
+	BODY_40_59(47,B,C,D,E,T,A,X(15),X( 1),X( 7),X(12));
+	BODY_40_59(48,A,B,C,D,E,T,X( 0),X( 2),X( 8),X(13));
+	BODY_40_59(49,T,A,B,C,D,E,X( 1),X( 3),X( 9),X(14));
+	BODY_40_59(50,E,T,A,B,C,D,X( 2),X( 4),X(10),X(15));
+	BODY_40_59(51,D,E,T,A,B,C,X( 3),X( 5),X(11),X( 0));
+	BODY_40_59(52,C,D,E,T,A,B,X( 4),X( 6),X(12),X( 1));
+	BODY_40_59(53,B,C,D,E,T,A,X( 5),X( 7),X(13),X( 2));
+	BODY_40_59(54,A,B,C,D,E,T,X( 6),X( 8),X(14),X( 3));
+	BODY_40_59(55,T,A,B,C,D,E,X( 7),X( 9),X(15),X( 4));
+	BODY_40_59(56,E,T,A,B,C,D,X( 8),X(10),X( 0),X( 5));
+	BODY_40_59(57,D,E,T,A,B,C,X( 9),X(11),X( 1),X( 6));
+	BODY_40_59(58,C,D,E,T,A,B,X(10),X(12),X( 2),X( 7));
+	BODY_40_59(59,B,C,D,E,T,A,X(11),X(13),X( 3),X( 8));
+
+	BODY_60_79(60,A,B,C,D,E,T,X(12),X(14),X( 4),X( 9));
+	BODY_60_79(61,T,A,B,C,D,E,X(13),X(15),X( 5),X(10));
+	BODY_60_79(62,E,T,A,B,C,D,X(14),X( 0),X( 6),X(11));
+	BODY_60_79(63,D,E,T,A,B,C,X(15),X( 1),X( 7),X(12));
+	BODY_60_79(64,C,D,E,T,A,B,X( 0),X( 2),X( 8),X(13));
+	BODY_60_79(65,B,C,D,E,T,A,X( 1),X( 3),X( 9),X(14));
+	BODY_60_79(66,A,B,C,D,E,T,X( 2),X( 4),X(10),X(15));
+	BODY_60_79(67,T,A,B,C,D,E,X( 3),X( 5),X(11),X( 0));
+	BODY_60_79(68,E,T,A,B,C,D,X( 4),X( 6),X(12),X( 1));
+	BODY_60_79(69,D,E,T,A,B,C,X( 5),X( 7),X(13),X( 2));
+	BODY_60_79(70,C,D,E,T,A,B,X( 6),X( 8),X(14),X( 3));
+	BODY_60_79(71,B,C,D,E,T,A,X( 7),X( 9),X(15),X( 4));
+	BODY_60_79(72,A,B,C,D,E,T,X( 8),X(10),X( 0),X( 5));
+	BODY_60_79(73,T,A,B,C,D,E,X( 9),X(11),X( 1),X( 6));
+	BODY_60_79(74,E,T,A,B,C,D,X(10),X(12),X( 2),X( 7));
+	BODY_60_79(75,D,E,T,A,B,C,X(11),X(13),X( 3),X( 8));
+	BODY_60_79(76,C,D,E,T,A,B,X(12),X(14),X( 4),X( 9));
+	BODY_60_79(77,B,C,D,E,T,A,X(13),X(15),X( 5),X(10));
+	BODY_60_79(78,A,B,C,D,E,T,X(14),X( 0),X( 6),X(11));
+	BODY_60_79(79,T,A,B,C,D,E,X(15),X( 1),X( 7),X(12));
+	
+	c->h0=(c->h0+E)&0xffffffffL; 
+	c->h1=(c->h1+T)&0xffffffffL;
+	c->h2=(c->h2+A)&0xffffffffL;
+	c->h3=(c->h3+B)&0xffffffffL;
+	c->h4=(c->h4+C)&0xffffffffL;
+
+	if (--num <= 0) break;
+
+	A=c->h0;
+	B=c->h1;
+	C=c->h2;
+	D=c->h3;
+	E=c->h4;
+
+		}
+	}
+#endif
diff -urN linux-2.4.29/drivers/net/sk98lin/h/lm80.h linux-2.4.29-uc1/drivers/net/sk98lin/h/lm80.h
--- linux-2.4.29/drivers/net/sk98lin/h/lm80.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/lm80.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	lm80.h	
  * Project:	Gigabit Ethernet Adapters, Common Modules
+ * Version:	$Revision: 2.1 $
+ * Date:	$Date: 2003/10/27 14:16:08 $
  * Purpose:	Contains all defines for the LM80 Chip
  *		(National Semiconductor).
  *
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skaddr.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skaddr.h
--- linux-2.4.29/drivers/net/sk98lin/h/skaddr.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skaddr.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skaddr.h
  * Project:	Gigabit Ethernet Adapters, ADDR-Modul
+ * Version:	$Revision: 2.1 $
+ * Date:	$Date: 2003/10/27 14:16:07 $
  * Purpose:	Header file for Address Management (MC, UC, Prom).
  *
  ******************************************************************************/
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skcsum.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skcsum.h
--- linux-2.4.29/drivers/net/sk98lin/h/skcsum.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skcsum.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skcsum.h
  * Project:	GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
+ * Version:	$Revision: 2.2 $
+ * Date:	$Date: 2003/12/29 15:37:26 $
  * Purpose:	Store/verify Internet checksum in send/receive packets.
  *
  ******************************************************************************/
@@ -155,9 +157,7 @@
 typedef struct s_Csum {
 	/* Enabled receive SK_PROTO_XXX bit flags. */
 	unsigned ReceiveFlags[SK_MAX_NETS];
-#ifdef TX_CSUM
 	unsigned TransmitFlags[SK_MAX_NETS];
-#endif /* TX_CSUM */
 
 	/* The protocol statistics structure; one per supported protocol. */
 	SKCS_PROTO_STATS ProtoStats[SK_MAX_NETS][SKCS_NUM_PROTOCOLS];
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skdebug.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skdebug.h
--- linux-2.4.29/drivers/net/sk98lin/h/skdebug.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skdebug.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skdebug.h
  * Project:	Gigabit Ethernet Adapters, Common Modules
+ * Version:	$Revision: 2.2 $
+ * Date:	$Date: 2004/02/26 16:06:06 $
  * Purpose:	SK specific DEBUG support
  *
  ******************************************************************************/
@@ -56,6 +58,9 @@
 #define SK_DBGMOD_ADDR	0x00000080L	/* ADDR module */
 #define SK_DBGMOD_PECP	0x00000100L	/* PECP module */
 #define SK_DBGMOD_POWM	0x00000200L	/* Power Management module */
+#ifdef SK_ASF
+#define SK_DBGMOD_ASF	0x00000400L	/* ASF module */
+#endif
 
 /* Debug events */
 
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skdrv1st.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skdrv1st.h
--- linux-2.4.29/drivers/net/sk98lin/h/skdrv1st.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skdrv1st.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skdrv1st.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:	$Revision: 1.4 $
+ * Date:	$Date: 2004/07/09 13:22:05 $
  * Purpose:	First header file for driver and all other modules
  *
  ******************************************************************************/
@@ -20,20 +22,6 @@
  *
  ******************************************************************************/
 
-/******************************************************************************
- *
- * Description:
- *
- * This is the first include file of the driver, which includes all
- * neccessary system header files and some of the GEnesis header files.
- * It also defines some basic items.
- *
- * Include File Hierarchy:
- *
- *	see skge.c
- *
- ******************************************************************************/
-
 #ifndef __INC_SKDRV1ST_H
 #define __INC_SKDRV1ST_H
 
@@ -62,7 +50,6 @@
 #error You must compile this driver with "-O".
 #endif
 
-#include <linux/version.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -95,6 +82,10 @@
 #include	"h/lm80.h"
 #include	"h/xmac_ii.h"
 
+#ifndef SK_BMU_RX_WM_PEX
+#define SK_BMU_RX_WM_PEX 0x80
+#endif
+
 #ifdef __LITTLE_ENDIAN
 #define SK_LITTLE_ENDIAN
 #else
@@ -193,3 +184,8 @@
 
 #endif
 
+/*******************************************************************************
+ *
+ * End of file
+ *
+ ******************************************************************************/
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skdrv2nd.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skdrv2nd.h
--- linux-2.4.29/drivers/net/sk98lin/h/skdrv2nd.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skdrv2nd.h	2005-06-14 02:12:09.000000000 +0100
@@ -1,15 +1,17 @@
 /******************************************************************************
  *
- * Name:	skdrv2nd.h
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Purpose:	Second header file for driver and all other modules
+ * Name:        skdrv2nd.h
+ * Project:     GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:     $Revision: 1.28 $
+ * Date:        $Date: 2004/07/27 08:07:34 $
+ * Purpose:     Second header file for driver and all other modules
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
  *	(C)Copyright 1998-2002 SysKonnect GmbH.
- *	(C)Copyright 2002-2003 Marvell.
+ *	(C)Copyright 2002-2004 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -40,10 +42,11 @@
 #include "h/skqueue.h"
 #include "h/skgehwt.h"
 #include "h/sktimer.h"
-#include "h/ski2c.h"
+#include "h/sktwsi.h"
 #include "h/skgepnmi.h"
 #include "h/skvpd.h"
 #include "h/skgehw.h"
+#include "h/sky2le.h"
 #include "h/skgeinit.h"
 #include "h/skaddr.h"
 #include "h/skgesirq.h"
@@ -51,151 +54,121 @@
 #include "h/skrlmt.h"
 #include "h/skgedrv.h"
 
-#define SK_PCI_ISCOMPLIANT(result, pdev) {     \
-    result = SK_FALSE; /* default */     \
-    /* 3Com (0x10b7) */     \
-    if (pdev->vendor == 0x10b7) {     \
-        /* Gigabit Ethernet Adapter (0x1700) */     \
-        if ((pdev->device == 0x1700)) { \
-            result = SK_TRUE;     \
-        }     \
-    /* SysKonnect (0x1148) */     \
-    } else if (pdev->vendor == 0x1148) {     \
-        /* SK-98xx Gigabit Ethernet Server Adapter (0x4300) */     \
-        /* SK-98xx V2.0 Gigabit Ethernet Adapter (0x4320) */     \
-        if ((pdev->device == 0x4300) || \
-            (pdev->device == 0x4320)) { \
-            result = SK_TRUE;     \
-        }     \
-    /* D-Link (0x1186) */     \
-    } else if (pdev->vendor == 0x1186) {     \
-        /* Gigabit Ethernet Adapter (0x4c00) */     \
-        if ((pdev->device == 0x4c00)) { \
-            result = SK_TRUE;     \
-        }     \
-    /* Marvell (0x11ab) */     \
-    } else if (pdev->vendor == 0x11ab) {     \
-        /* Gigabit Ethernet Adapter (0x4320) */     \
-        if ((pdev->device == 0x4320)) { \
-            result = SK_TRUE;     \
-        }     \
-    /* CNet (0x1371) */     \
-    } else if (pdev->vendor == 0x1371) {     \
-        /* GigaCard Network Adapter (0x434e) */     \
-        if ((pdev->device == 0x434e)) { \
-            result = SK_TRUE;     \
-        }     \
-    /* Linksys (0x1737) */     \
-    } else if (pdev->vendor == 0x1737) {     \
-        /* Gigabit Network Adapter (0x1032) */     \
-        /* Gigabit Network Adapter (0x1064) */     \
-        if ((pdev->device == 0x1032) || \
-            (pdev->device == 0x1064)) { \
-            result = SK_TRUE;     \
-        }     \
-    } else {     \
-        result = SK_FALSE;     \
-    }     \
-}
+/******************************************************************************
+ *
+ * Generic ISR defines
+ *
+ ******************************************************************************/
 
+#define SkIsrRetVar     void
+#define SkIsrRetNone    NULL
+#define SkIsrRetHandled NULL
+
+#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
+#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)
+#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb)
 
-extern SK_MBUF		*SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned);
-extern void		SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*);
-extern SK_U64		SkOsGetTime(SK_AC*);
-extern int		SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
-extern int		SkPciReadCfgWord(SK_AC*, int, SK_U16*);
-extern int		SkPciReadCfgByte(SK_AC*, int, SK_U8*);
-extern int		SkPciWriteCfgDWord(SK_AC*, int, SK_U32);
-extern int		SkPciWriteCfgWord(SK_AC*, int, SK_U16);
-extern int		SkPciWriteCfgByte(SK_AC*, int, SK_U8);
-extern int		SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
-
-#ifdef SK_DIAG_SUPPORT
-extern int		SkDrvEnterDiagMode(SK_AC *pAc);
-extern int		SkDrvLeaveDiagMode(SK_AC *pAc);
-#endif
+/******************************************************************************
+ *
+ * Global function prototypes
+ *
+ ******************************************************************************/
+
+extern SK_MBUF *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned);
+extern void SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*);
+extern SK_U64 SkOsGetTime(SK_AC*);
+extern int SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
+extern int SkPciReadCfgWord(SK_AC*, int, SK_U16*);
+extern int SkPciReadCfgByte(SK_AC*, int, SK_U8*);
+extern int SkPciWriteCfgDWord(SK_AC*, int, SK_U32);
+extern int SkPciWriteCfgWord(SK_AC*, int, SK_U16);
+extern int SkPciWriteCfgByte(SK_AC*, int, SK_U8);
+extern int SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
+extern int SkDrvEnterDiagMode(SK_AC *pAc);
+extern int SkDrvLeaveDiagMode(SK_AC *pAc);
+
+/******************************************************************************
+ *
+ * Linux specific RLMT buffer structure (SK_MBUF typedef in skdrv1st)!
+ *
+ ******************************************************************************/
 
 struct s_DrvRlmtMbuf {
-	SK_MBUF		*pNext;		/* Pointer to next RLMT Mbuf. */
-	SK_U8		*pData;		/* Data buffer (virtually contig.). */
-	unsigned	Size;		/* Data buffer size. */
-	unsigned	Length;		/* Length of packet (<= Size). */
-	SK_U32		PortIdx;	/* Receiving/transmitting port. */
+	SK_MBUF         *pNext;    /* Pointer to next RLMT Mbuf.       */
+	SK_U8           *pData;    /* Data buffer (virtually contig.). */
+	unsigned         Size;     /* Data buffer size.                */
+	unsigned         Length;   /* Length of packet (<= Size).      */
+	SK_U32           PortIdx;  /* Receiving/transmitting port.     */
 #ifdef SK_RLMT_MBUF_PRIVATE
-	SK_RLMT_MBUF	Rlmt;		/* Private part for RLMT. */
-#endif  /* SK_RLMT_MBUF_PRIVATE */
-	struct sk_buff	*pOs;		/* Pointer to message block */
+	SK_RLMT_MBUF     Rlmt;     /* Private part for RLMT.           */
+#endif
+	struct sk_buff  *pOs;      /* Pointer to message block         */
 };
 
+/******************************************************************************
+ *
+ * Linux specific TIME defines
+ *
+ ******************************************************************************/
 
-/*
- * Time macros
- */
 #if SK_TICKS_PER_SEC == 100
 #define SK_PNMI_HUNDREDS_SEC(t)	(t)
 #else
-#define SK_PNMI_HUNDREDS_SEC(t)	((((unsigned long)t) * 100) / \
-										(SK_TICKS_PER_SEC))
+#define SK_PNMI_HUNDREDS_SEC(t) ((((unsigned long)t)*100)/(SK_TICKS_PER_SEC))
 #endif
 
-/*
- * New SkOsGetTime
- */
 #define SkOsGetTimeCurrent(pAC, pUsec) {\
 	struct timeval t;\
 	do_gettimeofday(&t);\
 	*pUsec = ((((t.tv_sec) * 1000000L)+t.tv_usec)/10000);\
 }
 
+/******************************************************************************
+ *
+ * Linux specific IOCTL defines and typedefs
+ *
+ ******************************************************************************/
 
-/*
- * ioctl definitions
- */
-#define		SK_IOCTL_BASE		(SIOCDEVPRIVATE)
-#define		SK_IOCTL_GETMIB		(SK_IOCTL_BASE + 0)
-#define		SK_IOCTL_SETMIB		(SK_IOCTL_BASE + 1)
-#define		SK_IOCTL_PRESETMIB	(SK_IOCTL_BASE + 2)
-#define		SK_IOCTL_GEN		(SK_IOCTL_BASE + 3)
-#define		SK_IOCTL_DIAG		(SK_IOCTL_BASE + 4)
-
-typedef struct s_IOCTL	SK_GE_IOCTL;
+#define	SK_IOCTL_BASE       (SIOCDEVPRIVATE)
+#define	SK_IOCTL_GETMIB     (SK_IOCTL_BASE + 0)
+#define	SK_IOCTL_SETMIB     (SK_IOCTL_BASE + 1)
+#define	SK_IOCTL_PRESETMIB  (SK_IOCTL_BASE + 2)
+#define	SK_IOCTL_GEN        (SK_IOCTL_BASE + 3)
+#define	SK_IOCTL_DIAG       (SK_IOCTL_BASE + 4)
 
+typedef struct s_IOCTL SK_GE_IOCTL;
 struct s_IOCTL {
 	char*		pData;
 	unsigned int	Len;
 };
 
+/******************************************************************************
+ *
+ * Generic sizes and length definitions
+ *
+ ******************************************************************************/
+
+#define TX_RING_SIZE  (24*1024)  /* GEnesis/Yukon */
+#define RX_RING_SIZE  (24*1024)  /* GEnesis/Yukon */
+#define RX_MAX_NBR_BUFFERS   128  /* Yukon-EC/-II */
+#define TX_MAX_NBR_BUFFERS   128  /* Yukon-EC/-II */
+
+#define	ETH_BUF_SIZE        1560  /* multiples of 8 bytes */
+#define	ETH_MAX_MTU         1514
+#define ETH_MIN_MTU         60
+#define ETH_MULTICAST_BIT   0x01
+#define SK_JUMBO_MTU        9000
+
+#define TX_PRIO_LOW    0 /* asynchronous queue */
+#define TX_PRIO_HIGH   1 /* synchronous queue */
+#define DESCR_ALIGN   64 /* alignment of Rx/Tx descriptors */
+
+/******************************************************************************
+ *
+ * PNMI related definitions
+ *
+ ******************************************************************************/
 
-/*
- * define sizes of descriptor rings in bytes
- */
-
-#define		TX_RING_SIZE	(8*1024)
-#define		RX_RING_SIZE	(24*1024)
-
-/*
- * Buffer size for ethernet packets
- */
-#define	ETH_BUF_SIZE	1540
-#define	ETH_MAX_MTU	1514
-#define ETH_MIN_MTU	60
-#define ETH_MULTICAST_BIT	0x01
-#define SK_JUMBO_MTU	9000
-
-/*
- * transmit priority selects the queue: LOW=asynchron, HIGH=synchron
- */
-#define TX_PRIO_LOW	0
-#define TX_PRIO_HIGH	1
-
-/*
- * alignment of rx/tx descriptors
- */
-#define DESCR_ALIGN	64
-
-/*
- * definitions for pnmi. TODO
- */
 #define SK_DRIVER_RESET(pAC, IoC)	0
 #define SK_DRIVER_SENDEVENT(pAC, IoC)	0
 #define SK_DRIVER_SELFTEST(pAC, IoC)	0
@@ -204,20 +177,16 @@
 #define SK_DRIVER_SET_MTU(pAc,IoC,i,v)	0
 #define SK_DRIVER_PRESET_MTU(pAc,IoC,i,v)	0
 
-/*
-** Interim definition of SK_DRV_TIMER placed in this file until 
-** common modules have boon finallized
-*/
-#define SK_DRV_TIMER			11 
-#define	SK_DRV_MODERATION_TIMER		1
-#define SK_DRV_MODERATION_TIMER_LENGTH  1000000  /* 1 second */
-#define SK_DRV_RX_CLEANUP_TIMER		2
-#define SK_DRV_RX_CLEANUP_TIMER_LENGTH	1000000	 /* 100 millisecs */
-
-/*
-** Definitions regarding transmitting frames 
-** any calculating any checksum.
-*/
+
+/******************************************************************************
+ *
+ * Various offsets and sizes
+ *
+ ******************************************************************************/
+
+#define	SK_DRV_MODERATION_TIMER         1   /* id */
+#define SK_DRV_MODERATION_TIMER_LENGTH  1   /* 1 second */
+
 #define C_LEN_ETHERMAC_HEADER_DEST_ADDR 6
 #define C_LEN_ETHERMAC_HEADER_SRC_ADDR  6
 #define C_LEN_ETHERMAC_HEADER_LENTYPE   2
@@ -243,114 +212,341 @@
 #define C_PROTO_ID_UDP                  17       /* refer to RFC 790 or Stevens'   */
 #define C_PROTO_ID_TCP                  6        /* TCP/IP illustrated for details */
 
-/* TX and RX descriptors *****************************************************/
+/******************************************************************************
+ *
+ * Tx and Rx descriptor definitions
+ *
+ ******************************************************************************/
 
 typedef struct s_RxD RXD; /* the receive descriptor */
-
 struct s_RxD {
-	volatile SK_U32	RBControl;	/* Receive Buffer Control */
-	SK_U32		VNextRxd;	/* Next receive descriptor,low dword */
-	SK_U32		VDataLow;	/* Receive buffer Addr, low dword */
-	SK_U32		VDataHigh;	/* Receive buffer Addr, high dword */
-	SK_U32		FrameStat;	/* Receive Frame Status word */
-	SK_U32		TimeStamp;	/* Time stamp from XMAC */
-	SK_U32		TcpSums;	/* TCP Sum 2 / TCP Sum 1 */
-	SK_U32		TcpSumStarts;	/* TCP Sum Start 2 / TCP Sum Start 1 */
-	RXD		*pNextRxd;	/* Pointer to next Rxd */
-	struct sk_buff	*pMBuf;		/* Pointer to Linux' socket buffer */
+	volatile SK_U32  RBControl;     /* Receive Buffer Control            */
+	SK_U32           VNextRxd;      /* Next receive descriptor,low dword */
+	SK_U32           VDataLow;      /* Receive buffer Addr, low dword    */
+	SK_U32           VDataHigh;     /* Receive buffer Addr, high dword   */
+	SK_U32           FrameStat;     /* Receive Frame Status word         */
+	SK_U32           TimeStamp;     /* Time stamp from XMAC              */
+	SK_U32           TcpSums;       /* TCP Sum 2 / TCP Sum 1             */
+	SK_U32           TcpSumStarts;  /* TCP Sum Start 2 / TCP Sum Start 1 */
+	RXD             *pNextRxd;      /* Pointer to next Rxd               */
+	struct sk_buff  *pMBuf;         /* Pointer to Linux' socket buffer   */
 };
 
 typedef struct s_TxD TXD; /* the transmit descriptor */
-
 struct s_TxD {
-	volatile SK_U32	TBControl;	/* Transmit Buffer Control */
-	SK_U32		VNextTxd;	/* Next transmit descriptor,low dword */
-	SK_U32		VDataLow;	/* Transmit Buffer Addr, low dword */
-	SK_U32		VDataHigh;	/* Transmit Buffer Addr, high dword */
-	SK_U32		FrameStat;	/* Transmit Frame Status Word */
-	SK_U32		TcpSumOfs;	/* Reserved / TCP Sum Offset */
-	SK_U16		TcpSumSt;	/* TCP Sum Start */
-	SK_U16		TcpSumWr;	/* TCP Sum Write */
-	SK_U32		TcpReserved;	/* not used */
-	TXD		*pNextTxd;	/* Pointer to next Txd */
-	struct sk_buff	*pMBuf;		/* Pointer to Linux' socket buffer */
+	volatile SK_U32  TBControl;     /* Transmit Buffer Control            */
+	SK_U32           VNextTxd;      /* Next transmit descriptor,low dword */
+	SK_U32           VDataLow;      /* Transmit Buffer Addr, low dword    */
+	SK_U32           VDataHigh;     /* Transmit Buffer Addr, high dword   */
+	SK_U32           FrameStat;     /* Transmit Frame Status Word         */
+	SK_U32           TcpSumOfs;     /* Reserved / TCP Sum Offset          */
+	SK_U16           TcpSumSt;      /* TCP Sum Start                      */
+	SK_U16           TcpSumWr;      /* TCP Sum Write                      */
+	SK_U32           TcpReserved;   /* not used                           */
+	TXD             *pNextTxd;      /* Pointer to next Txd                */
+	struct sk_buff  *pMBuf;         /* Pointer to Linux' socket buffer    */
 };
 
-/* Used interrupt bits in the interrupts source register *********************/
+/******************************************************************************
+ *
+ * Generic Yukon-II defines
+ *
+ ******************************************************************************/
+
+#define LE_SIZE   sizeof(SK_HWLE)
+#define MAX_NUM_FRAGS   (MAX_SKB_FRAGS + 1)
+#define MIN_LEN_OF_LE_TAB   128
+#define MAX_LEN_OF_LE_TAB   4096
+#define MAX_UNUSED_RX_LE_WORKING   8
+#ifdef MAX_FRAG_OVERHEAD
+#undef MAX_FRAG_OVERHEAD
+#define MAX_FRAG_OVERHEAD   4
+#endif
+// as we have a maximum of 16 physical fragments,
+// maximum 1 ADDR64 per physical fragment
+// maximum 4 LEs for VLAN, Csum, LargeSend, Packet
+#define MIN_LE_FREE_REQUIRED   ((16*2) + 4)
+#define IS_GMAC(pAc)   (!pAc->GIni.GIGenesis)
+#ifdef USE_SYNC_TX_QUEUE
+#define TXS_MAX_LE   256
+#else /* !USE_SYNC_TX_QUEUE */
+#define TXS_MAX_LE   0
+#endif
 
-#define DRIVER_IRQS	((IS_IRQ_SW)   | \
-			(IS_R1_F)      |(IS_R2_F)  | \
-			(IS_XS1_F)     |(IS_XA1_F) | \
-			(IS_XS2_F)     |(IS_XA2_F))
-
-#define SPECIAL_IRQS	((IS_HW_ERR)   |(IS_I2C_READY)  | \
-			(IS_EXT_REG)   |(IS_TIMINT)     | \
-			(IS_PA_TO_RX1) |(IS_PA_TO_RX2)  | \
-			(IS_PA_TO_TX1) |(IS_PA_TO_TX2)  | \
-			(IS_MAC1)      |(IS_LNK_SYNC_M1)| \
-			(IS_MAC2)      |(IS_LNK_SYNC_M2)| \
-			(IS_R1_C)      |(IS_R2_C)       | \
-			(IS_XS1_C)     |(IS_XA1_C)      | \
-			(IS_XS2_C)     |(IS_XA2_C))
-
-#define IRQ_MASK	((IS_IRQ_SW)   | \
-			(IS_R1_B)      |(IS_R1_F)     |(IS_R2_B) |(IS_R2_F) | \
-			(IS_XS1_B)     |(IS_XS1_F)    |(IS_XA1_B)|(IS_XA1_F)| \
-			(IS_XS2_B)     |(IS_XS2_F)    |(IS_XA2_B)|(IS_XA2_F)| \
-			(IS_HW_ERR)    |(IS_I2C_READY)| \
-			(IS_EXT_REG)   |(IS_TIMINT)   | \
-			(IS_PA_TO_RX1) |(IS_PA_TO_RX2)| \
-			(IS_PA_TO_TX1) |(IS_PA_TO_TX2)| \
-			(IS_MAC1)      |(IS_MAC2)     | \
-			(IS_R1_C)      |(IS_R2_C)     | \
-			(IS_XS1_C)     |(IS_XA1_C)    | \
-			(IS_XS2_C)     |(IS_XA2_C))
+#define ETHER_MAC_HDR_LEN   (6+6+2) // MAC SRC ADDR, MAC DST ADDR, TYPE
+#define IP_HDR_LEN   20
+#define TCP_CSUM_OFFS   0x10
+#define UDP_CSUM_OFFS   0x06
+#define TXA_MAX_LE   256
+#define RX_MAX_LE   256
+#define ST_MAX_LE   (SK_MAX_MACS)*((3*RX_MAX_LE)+(TXA_MAX_LE)+(TXS_MAX_LE))
+
+/******************************************************************************
+ *
+ * Structures specific for Yukon-II
+ *
+ ******************************************************************************/
+
+typedef	struct s_frag SK_FRAG;
+struct s_frag {
+ 	SK_FRAG       *pNext;
+ 	char          *pVirt;
+  	SK_U64         pPhys;
+ 	unsigned int   FragLen;
+};
 
-#define IRQ_HWE_MASK	(IS_ERR_MSK) /* enable all HW irqs */
+typedef	struct s_packet SK_PACKET;
+struct s_packet {
+	/* Common infos: */
+	SK_PACKET       *pNext;         /* pointer for packet queues          */
+	unsigned int     PacketLen;     /* length of packet                   */
+	unsigned int     NumFrags;      /* nbr of fragments (for Rx always 1) */
+	SK_FRAG         *pFrag;         /* fragment list                      */
+	SK_FRAG          FragArray[MAX_NUM_FRAGS]; /* TX fragment array       */
+	unsigned int     NextLE;        /* next LE to use for the next packet */
+
+	/* Private infos: */
+	struct sk_buff	*pMBuf;         /* Pointer to Linux' socket buffer    */
+};
+
+typedef	struct s_queue SK_PKT_QUEUE;
+struct s_queue {
+ 	SK_PACKET       *pHead;
+ 	SK_PACKET       *pTail;
+	spinlock_t       QueueLock;     /* serialize packet accesses          */
+};
+
+/*******************************************************************************
+ *
+ * Macros specific for Yukon-II queues
+ *
+ ******************************************************************************/
+
+#define IS_Q_EMPTY(pQueue)  ((pQueue)->pHead != NULL) ? SK_FALSE : SK_TRUE
+#define IS_Q_LOCKED(pQueue) spin_is_locked(&((pQueue)->QueueLock))
+
+#define PLAIN_POP_FIRST_PKT_FROM_QUEUE(pQueue, pPacket)	{	\
+        if ((pQueue)->pHead != NULL) {				\
+		(pPacket)       = (pQueue)->pHead;		\
+		(pQueue)->pHead = (pPacket)->pNext;		\
+		if ((pQueue)->pHead == NULL) {			\
+			(pQueue)->pTail = NULL;			\
+		}						\
+		(pPacket)->pNext = NULL;			\
+	} else {						\
+		(pPacket) = NULL;				\
+	}							\
+}
+
+#define PLAIN_PUSH_PKT_AS_FIRST_IN_QUEUE(pQueue, pPacket) {	\
+	if ((pQueue)->pHead != NULL) {				\
+		(pPacket)->pNext = (pQueue)->pHead;		\
+	} else {						\
+		(pPacket)->pNext = NULL;			\
+		(pQueue)->pTail  = (pPacket);			\
+	}							\
+      	(pQueue)->pHead  = (pPacket);				\
+}
+
+#define PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(pQueue, pPacket) {	\
+	(pPacket)->pNext = NULL;				\
+	if ((pQueue)->pTail != NULL) {				\
+		(pQueue)->pTail->pNext = (pPacket);		\
+	} else {						\
+		(pQueue)->pHead        = (pPacket);		\
+	}							\
+	(pQueue)->pTail = (pPacket);				\
+}
+
+#define PLAIN_PUSH_MULTIPLE_PKT_AS_LAST_IN_QUEUE(pQueue,pPktGrpStart,pPktGrpEnd) { \
+	if ((pPktGrpStart) != NULL) {					\
+		if ((pQueue)->pTail != NULL) {				\
+			(pQueue)->pTail->pNext = (pPktGrpStart);	\
+		} else {						\
+			(pQueue)->pHead = (pPktGrpStart);		\
+		}							\
+		(pQueue)->pTail = (pPktGrpEnd);				\
+	}								\
+}
+
+/* Required: 'Flags' */ 
+#define POP_FIRST_PKT_FROM_QUEUE(pQueue, pPacket)	{	\
+	spin_lock_irqsave(&((pQueue)->QueueLock), Flags);	\
+	if ((pQueue)->pHead != NULL) {				\
+		(pPacket)       = (pQueue)->pHead;		\
+		(pQueue)->pHead = (pPacket)->pNext;		\
+		if ((pQueue)->pHead == NULL) {			\
+			(pQueue)->pTail = NULL;			\
+		}						\
+		(pPacket)->pNext = NULL;			\
+	} else {						\
+		(pPacket) = NULL;				\
+	}							\
+	spin_unlock_irqrestore(&((pQueue)->QueueLock), Flags);	\
+}
+
+/* Required: 'Flags' */
+#define PUSH_PKT_AS_FIRST_IN_QUEUE(pQueue, pPacket)	{	\
+	spin_lock_irqsave(&(pQueue)->QueueLock, Flags);		\
+	if ((pQueue)->pHead != NULL) {				\
+		(pPacket)->pNext = (pQueue)->pHead;		\
+	} else {						\
+		(pPacket)->pNext = NULL;			\
+		(pQueue)->pTail  = (pPacket);			\
+	}							\
+	(pQueue)->pHead = (pPacket);				\
+	spin_unlock_irqrestore(&(pQueue)->QueueLock, Flags);	\
+}
+
+/* Required: 'Flags' */
+#define PUSH_PKT_AS_LAST_IN_QUEUE(pQueue, pPacket)	{	\
+	(pPacket)->pNext = NULL;				\
+	spin_lock_irqsave(&(pQueue)->QueueLock, Flags);		\
+	if ((pQueue)->pTail != NULL) {				\
+		(pQueue)->pTail->pNext = (pPacket);		\
+	} else {						\
+		(pQueue)->pHead = (pPacket);			\
+	}							\
+	(pQueue)->pTail = (pPacket);				\
+	spin_unlock_irqrestore(&(pQueue)->QueueLock, Flags);	\
+}
+
+/* Required: 'Flags' */
+#define PUSH_MULTIPLE_PKT_AS_LAST_IN_QUEUE(pQueue,pPktGrpStart,pPktGrpEnd) {	\
+	if ((pPktGrpStart) != NULL) {					\
+		spin_lock_irqsave(&(pQueue)->QueueLock, Flags);		\
+		if ((pQueue)->pTail != NULL) {				\
+			(pQueue)->pTail->pNext = (pPktGrpStart);	\
+		} else {						\
+			(pQueue)->pHead = (pPktGrpStart);		\
+		}							\
+		(pQueue)->pTail = (pPktGrpEnd);				\
+		spin_unlock_irqrestore(&(pQueue)->QueueLock, Flags);	\
+	}								\
+}
+
+/*******************************************************************************
+ *
+ * Used interrupt bits in the interrupts source register
+ *
+ ******************************************************************************/
+
+#define DRIVER_IRQS	((IS_IRQ_SW) | \
+			 (IS_R1_F)   | (IS_R2_F)  | \
+			 (IS_XS1_F)  | (IS_XA1_F) | \
+			 (IS_XS2_F)  | (IS_XA2_F))
+
+#define TX_COMPL_IRQS	((IS_XS1_B)  | (IS_XS1_F) | \
+			 (IS_XA1_B)  | (IS_XA1_F) | \
+			 (IS_XS2_B)  | (IS_XS2_F) | \
+			 (IS_XA2_B)  | (IS_XA2_F))
+
+#define NAPI_DRV_IRQS	((IS_R1_F)   | (IS_R2_F) | \
+			 (IS_XS1_F)  | (IS_XA1_F)| \
+			 (IS_XS2_F)  | (IS_XA2_F))
+
+#define Y2_DRIVER_IRQS	((Y2_IS_STAT_BMU) | (Y2_IS_IRQ_SW) | (Y2_IS_POLL_CHK))
+
+#define SPECIAL_IRQS	((IS_HW_ERR)    |(IS_I2C_READY)  | \
+			 (IS_EXT_REG)   |(IS_TIMINT)     | \
+			 (IS_PA_TO_RX1) |(IS_PA_TO_RX2)  | \
+			 (IS_PA_TO_TX1) |(IS_PA_TO_TX2)  | \
+			 (IS_MAC1)      |(IS_LNK_SYNC_M1)| \
+			 (IS_MAC2)      |(IS_LNK_SYNC_M2)| \
+			 (IS_R1_C)      |(IS_R2_C)       | \
+			 (IS_XS1_C)     |(IS_XA1_C)      | \
+			 (IS_XS2_C)     |(IS_XA2_C))
+
+#define Y2_SPECIAL_IRQS	((Y2_IS_HW_ERR)   |(Y2_IS_ASF)      | \
+			 (Y2_IS_TWSI_RDY) |(Y2_IS_TIMINT)   | \
+			 (Y2_IS_IRQ_PHY2) |(Y2_IS_IRQ_MAC2) | \
+			 (Y2_IS_CHK_RX2)  |(Y2_IS_CHK_TXS2) | \
+			 (Y2_IS_CHK_TXA2) |(Y2_IS_IRQ_PHY1) | \
+			 (Y2_IS_IRQ_MAC1) |(Y2_IS_CHK_RX1)  | \
+			 (Y2_IS_CHK_TXS1) |(Y2_IS_CHK_TXA1))
+
+#define IRQ_MASK	((IS_IRQ_SW)    | \
+			 (IS_R1_F)      |(IS_R2_F)     | \
+			 (IS_XS1_F)     |(IS_XA1_F)    | \
+			 (IS_XS2_F)     |(IS_XA2_F)    | \
+			 (IS_HW_ERR)    |(IS_I2C_READY)| \
+			 (IS_EXT_REG)   |(IS_TIMINT)   | \
+			 (IS_PA_TO_RX1) |(IS_PA_TO_RX2)| \
+			 (IS_PA_TO_TX1) |(IS_PA_TO_TX2)| \
+			 (IS_MAC1)      |(IS_MAC2)     | \
+			 (IS_R1_C)      |(IS_R2_C)     | \
+			 (IS_XS1_C)     |(IS_XA1_C)    | \
+			 (IS_XS2_C)     |(IS_XA2_C))
+
+#define Y2_IRQ_MASK	((Y2_DRIVER_IRQS) | (Y2_SPECIAL_IRQS))
+
+#define IRQ_HWE_MASK	(IS_ERR_MSK)		/* enable all HW irqs */
+#define Y2_IRQ_HWE_MASK	(Y2_HWE_ALL_MSK)	/* enable all HW irqs */
 
 typedef struct s_DevNet DEV_NET;
 
 struct s_DevNet {
-	struct			proc_dir_entry *proc;
-	int             PortNr;
-	int             NetNr;
-	int             Mtu;
-	int             Up;
-	SK_AC   *pAC;
+	struct		proc_dir_entry *proc;
+	int		PortNr;
+	int		NetNr;
+	int		Mtu;
+	int		Up;
+	char		InitialDevName[20];
+	SK_AC		*pAC;
 };  
 
-typedef struct s_TxPort		TX_PORT;
+/*******************************************************************************
+ *
+ * Rx/Tx Port structures
+ *
+ ******************************************************************************/
 
-struct s_TxPort {
-	/* the transmit descriptor rings */
-	caddr_t		pTxDescrRing;	/* descriptor area memory */
-	SK_U64		VTxDescrRing;	/* descr. area bus virt. addr. */
-	TXD		*pTxdRingHead;	/* Head of Tx rings */
-	TXD		*pTxdRingTail;	/* Tail of Tx rings */
-	TXD		*pTxdRingPrev;	/* descriptor sent previously */
-	int		TxdRingFree;	/* # of free entrys */
-	spinlock_t	TxDesRingLock;	/* serialize descriptor accesses */
-	caddr_t		HwAddr;		/* bmu registers address */
-	int		PortIndex;	/* index number of port (0 or 1) */
+typedef struct s_TxPort	TX_PORT;
+struct s_TxPort {                       /* the transmit descriptor rings */
+	caddr_t         pTxDescrRing;   /* descriptor area memory        */
+	SK_U64          VTxDescrRing;   /* descr. area bus virt. addr.   */
+	TXD            *pTxdRingHead;   /* Head of Tx rings              */
+	TXD            *pTxdRingTail;   /* Tail of Tx rings              */
+	TXD            *pTxdRingPrev;   /* descriptor sent previously    */
+	int             TxdRingPrevFree;/* previously # of free entrys   */
+	int             TxdRingFree;    /* # of free entrys              */
+	spinlock_t      TxDesRingLock;  /* serialize descriptor accesses */
+	caddr_t         HwAddr;         /* bmu registers address         */
+	int             PortIndex;      /* index number of port (0 or 1) */
+	SK_PACKET      *TransmitPacketTable;
+	SK_LE_TABLE     TxALET;         /* tx (async) list element table */
+	SK_LE_TABLE     TxSLET;         /* tx (sync) list element table  */
+	SK_PKT_QUEUE    TxQ_free;
+	SK_PKT_QUEUE    TxAQ_waiting;
+	SK_PKT_QUEUE    TxSQ_waiting;
+	SK_PKT_QUEUE    TxAQ_working;
+	SK_PKT_QUEUE    TxSQ_working;
 };
 
-typedef struct s_RxPort		RX_PORT;
-
-struct s_RxPort {
-	/* the receive descriptor rings */
-	caddr_t		pRxDescrRing;	/* descriptor area memory */
-	SK_U64		VRxDescrRing;   /* descr. area bus virt. addr. */
-	RXD		*pRxdRingHead;	/* Head of Rx rings */
-	RXD		*pRxdRingTail;	/* Tail of Rx rings */
-	RXD		*pRxdRingPrev;	/* descriptor given to BMU previously */
-	int		RxdRingFree;	/* # of free entrys */
-	spinlock_t	RxDesRingLock;	/* serialize descriptor accesses */
-	int		RxFillLimit;	/* limit for buffers in ring */
-	caddr_t		HwAddr;		/* bmu registers address */
-	int		PortIndex;	/* index number of port (0 or 1) */
+typedef struct s_RxPort	RX_PORT;
+struct s_RxPort {                       /* the receive descriptor rings  */
+	caddr_t         pRxDescrRing;   /* descriptor area memory        */
+	SK_U64          VRxDescrRing;   /* descr. area bus virt. addr.   */
+	RXD            *pRxdRingHead;   /* Head of Rx rings              */
+	RXD            *pRxdRingTail;   /* Tail of Rx rings              */
+	RXD            *pRxdRingPrev;   /* descr given to BMU previously */
+	int             RxdRingFree;    /* # of free entrys              */
+	spinlock_t      RxDesRingLock;  /* serialize descriptor accesses */
+	int             RxFillLimit;    /* limit for buffers in ring     */
+	caddr_t         HwAddr;         /* bmu registers address         */
+	int             PortIndex;      /* index number of port (0 or 1) */
+	SK_BOOL         UseRxCsum;      /* use Rx checksumming (yes/no)  */
+	SK_PACKET      *ReceivePacketTable;
+	SK_LE_TABLE     RxLET;          /* rx list element table         */
+	SK_PKT_QUEUE    RxQ_working;
+	SK_PKT_QUEUE    RxQ_waiting;
 };
 
-/* Definitions needed for interrupt moderation *******************************/
+/*******************************************************************************
+ *
+ * Interrupt masks used in combination with interrupt moderation
+ *
+ ******************************************************************************/
 
 #define IRQ_EOF_AS_TX     ((IS_XA1_F)     | (IS_XA2_F))
 #define IRQ_EOF_SY_TX     ((IS_XS1_F)     | (IS_XS2_F))
@@ -362,139 +558,146 @@
 #define IRQ_MASK_SP_TX    ((SPECIAL_IRQS)    | (IRQ_MASK_TX_ONLY))
 #define IRQ_MASK_RX_TX_SP ((SPECIAL_IRQS)    | (IRQ_MASK_TX_RX))
 
-#define C_INT_MOD_NONE                 1
-#define C_INT_MOD_STATIC               2
-#define C_INT_MOD_DYNAMIC              4
-
-#define C_CLK_FREQ_GENESIS      53215000 /* shorter: 53.125 MHz  */
-#define C_CLK_FREQ_YUKON        78215000 /* shorter: 78.125 MHz  */
-
-#define C_INTS_PER_SEC_DEFAULT      2000 
-#define C_INT_MOD_ENABLE_PERCENTAGE   50 /* if higher 50% enable */
-#define C_INT_MOD_DISABLE_PERCENTAGE  50 /* if lower 50% disable */
-#define C_INT_MOD_IPS_LOWER_RANGE     30
-#define C_INT_MOD_IPS_UPPER_RANGE     40000
-
-
-typedef struct s_DynIrqModInfo  DIM_INFO;
-struct s_DynIrqModInfo {
-	unsigned long   PrevTimeVal;
-	unsigned int    PrevSysLoad;
-	unsigned int    PrevUsedTime;
-	unsigned int    PrevTotalTime;
-	int             PrevUsedDescrRatio;
-	int             NbrProcessedDescr;
-        SK_U64          PrevPort0RxIntrCts;
-        SK_U64          PrevPort1RxIntrCts;
-        SK_U64          PrevPort0TxIntrCts;
-        SK_U64          PrevPort1TxIntrCts;
-	SK_BOOL         ModJustEnabled;     /* Moderation just enabled yes/no */
-
-	int             MaxModIntsPerSec;            /* Moderation Threshold */
-	int             MaxModIntsPerSecUpperLimit;  /* Upper limit for DIM  */
-	int             MaxModIntsPerSecLowerLimit;  /* Lower limit for DIM  */
-
-	long            MaskIrqModeration;   /* ModIrqType (eg. 'TxRx')      */
-	SK_BOOL         DisplayStats;        /* Stats yes/no                 */
-	SK_BOOL         AutoSizing;          /* Resize DIM-timer on/off      */
-	int             IntModTypeSelect;    /* EnableIntMod (eg. 'dynamic') */
+#define IRQ_MASK_Y2_TX_ONLY  (Y2_IS_STAT_BMU)
+#define IRQ_MASK_Y2_RX_ONLY  (Y2_IS_STAT_BMU)
+#define IRQ_MASK_Y2_SP_ONLY  (SPECIAL_IRQS)
+#define IRQ_MASK_Y2_TX_RX    ((IRQ_MASK_TX_ONLY)| (IRQ_MASK_RX_ONLY))
+#define IRQ_MASK_Y2_SP_RX    ((SPECIAL_IRQS)    | (IRQ_MASK_RX_ONLY))
+#define IRQ_MASK_Y2_SP_TX    ((SPECIAL_IRQS)    | (IRQ_MASK_TX_ONLY))
+#define IRQ_MASK_Y2_RX_TX_SP ((SPECIAL_IRQS)    | (IRQ_MASK_TX_RX))
 
-	SK_TIMER        ModTimer; /* just some timer */
-};
+/*******************************************************************************
+ *
+ * Defines and typedefs regarding interrupt moderation
+ *
+ ******************************************************************************/
 
-typedef struct s_PerStrm	PER_STRM;
+#define C_INT_MOD_NONE			1
+#define C_INT_MOD_STATIC		2
+#define C_INT_MOD_DYNAMIC		4
+
+#define C_CLK_FREQ_GENESIS		 53215000 /* or:  53.125 MHz */
+#define C_CLK_FREQ_YUKON		 78215000 /* or:  78.125 MHz */
+#define C_CLK_FREQ_YUKON_EC		125000000 /* or: 125.000 MHz */
+
+#define C_Y2_INTS_PER_SEC_DEFAULT	5000 
+#define C_INTS_PER_SEC_DEFAULT		2000 
+#define C_INT_MOD_IPS_LOWER_RANGE	30        /* in IRQs/second */
+#define C_INT_MOD_IPS_UPPER_RANGE	40000     /* in IRQs/second */
+
+typedef struct s_DynIrqModInfo {
+	SK_U64     PrevPort0RxIntrCts;
+	SK_U64     PrevPort1RxIntrCts;
+	SK_U64     PrevPort0TxIntrCts;
+	SK_U64     PrevPort1TxIntrCts;
+	SK_U64     PrevPort0StatusLeIntrCts;
+	SK_U64     PrevPort1StatusLeIntrCts;
+	int        MaxModIntsPerSec;            /* Moderation Threshold   */
+	int        MaxModIntsPerSecUpperLimit;  /* Upper limit for DIM    */
+	int        MaxModIntsPerSecLowerLimit;  /* Lower limit for DIM    */
+	long       MaskIrqModeration;           /* IRQ Mask (eg. 'TxRx')  */
+	int        IntModTypeSelect;            /* Type  (eg. 'dynamic')  */
+	int        DynIrqModSampleInterval;     /* expressed in seconds!  */
+	SK_TIMER   ModTimer;                    /* Timer for dynamic mod. */
+} DIM_INFO;
 
 #define SK_ALLOC_IRQ	0x00000001
-
-#ifdef SK_DIAG_SUPPORT
 #define	DIAG_ACTIVE		1
 #define	DIAG_NOTACTIVE		0
-#endif
 
 /****************************************************************************
+ *
  * Per board structure / Adapter Context structure:
- *	Allocated within attach(9e) and freed within detach(9e).
- *	Contains all 'per device' necessary handles, flags, locks etc.:
- */
-struct s_AC  {
-	SK_GEINIT	GIni;		/* GE init struct */
-	SK_PNMI		Pnmi;		/* PNMI data struct */
-	SK_VPD		vpd;		/* vpd data struct */
-	SK_QUEUE	Event;		/* Event queue */
-	SK_HWT		Hwt;		/* Hardware Timer control struct */
-	SK_TIMCTRL	Tim;		/* Software Timer control struct */
-	SK_I2C		I2c;		/* I2C relevant data structure */
-	SK_ADDR		Addr;		/* for Address module */
-	SK_CSUM		Csum;		/* for checksum module */
-	SK_RLMT		Rlmt;		/* for rlmt module */
-	spinlock_t	SlowPathLock;	/* Normal IRQ lock */
-	SK_PNMI_STRUCT_DATA PnmiStruct;	/* structure to get all Pnmi-Data */
-	int			RlmtMode;	/* link check mode to set */
-	int			RlmtNets;	/* Number of nets */
-	
-	SK_IOC		IoBase;		/* register set of adapter */
-	int		BoardLevel;	/* level of active hw init (0-2) */
-	char		DeviceStr[80];	/* adapter string from vpd */
-	SK_U32		AllocFlag;	/* flag allocation of resources */
-	struct pci_dev	*PciDev;	/* for access to pci config space */
-	SK_U32		PciDevId;	/* pci device id */
-	struct SK_NET_DEVICE	*dev[2];	/* pointer to device struct */
-	char		Name[30];	/* driver name */
-	struct SK_NET_DEVICE	*Next;		/* link all devices (for clearing) */
-	int		RxBufSize;	/* length of receive buffers */
-        struct net_device_stats stats;	/* linux 'netstat -i' statistics */
-	int		Index;		/* internal board index number */
-
-	/* adapter RAM sizes for queues of active port */
-	int		RxQueueSize;	/* memory used for receive queue */
-	int		TxSQueueSize;	/* memory used for sync. tx queue */
-	int		TxAQueueSize;	/* memory used for async. tx queue */
-
-	int		PromiscCount;	/* promiscuous mode counter  */
-	int		AllMultiCount;  /* allmulticast mode counter */
-	int		MulticCount;	/* number of different MC    */
-					/*  addresses for this board */
-					/*  (may be more than HW can)*/
-
-	int		HWRevision;	/* Hardware revision */
-	int		ActivePort;	/* the active XMAC port */
-	int		MaxPorts;		/* number of activated ports */
-	int		TxDescrPerRing;	/* # of descriptors per tx ring */
-	int		RxDescrPerRing;	/* # of descriptors per rx ring */
-
-	caddr_t		pDescrMem;	/* Pointer to the descriptor area */
-	dma_addr_t	pDescrMemDMA;	/* PCI DMA address of area */
-
-	/* the port structures with descriptor rings */
-	TX_PORT		TxPort[SK_MAX_MACS][2];
-	RX_PORT		RxPort[SK_MAX_MACS];
-
-	unsigned int	CsOfs1;		/* for checksum calculation */
-	unsigned int	CsOfs2;		/* for checksum calculation */
-	SK_U32		CsOfs;		/* for checksum calculation */
-
-	SK_BOOL		CheckQueue;	/* check event queue soon */
-	SK_TIMER        DrvCleanupTimer;/* to check for pending descriptors */
-	DIM_INFO        DynIrqModInfo;  /* all data related to DIM */
-
-	/* Only for tests */
-	int		PortUp;
-	int		PortDown;
-	int		ChipsetType;	/*  Chipset family type 
-					 *  0 == Genesis family support
-					 *  1 == Yukon family support
-					 */
-#ifdef SK_DIAG_SUPPORT
-	SK_U32		DiagModeActive;		/* is diag active?	*/
-	SK_BOOL		DiagFlowCtrl;		/* for control purposes	*/
-	SK_PNMI_STRUCT_DATA PnmiBackup;		/* backup structure for all Pnmi-Data */
-	SK_BOOL         WasIfUp[SK_MAX_MACS];   /* for OpenClose while 
-						 * DIAG is busy with NIC 
-						 */
-#endif
+ * Contains all 'per device' necessary handles, flags, locks etc.:
+ *
+ ******************************************************************************/
 
+struct s_AC  {
+	SK_GEINIT                GIni;          /* GE init struct             */
+	SK_PNMI                  Pnmi;          /* PNMI data struct           */
+	SK_VPD                   vpd;           /* vpd data struct            */
+	SK_QUEUE                 Event;         /* Event queue                */
+	SK_HWT                   Hwt;           /* Hardware Timer ctrl struct */
+	SK_TIMCTRL               Tim;           /* Software Timer ctrl struct */
+	SK_I2C                   I2c;           /* I2C relevant data structure*/
+	SK_ADDR                  Addr;          /* for Address module         */
+	SK_CSUM                  Csum;          /* for checksum module        */
+	SK_RLMT                  Rlmt;          /* for rlmt module            */
+	spinlock_t               SlowPathLock;  /* Normal IRQ lock            */
+	SK_PNMI_STRUCT_DATA      PnmiStruct;    /* struct for all Pnmi-Data   */
+	int                      RlmtMode;      /* link check mode to set     */
+	int                      RlmtNets;      /* Number of nets             */
+	SK_IOC                   IoBase;        /* register set of adapter    */
+	int                      BoardLevel;    /* level of hw init (0-2)     */
+	char                     DeviceStr[80]; /* adapter string from vpd    */
+	SK_U32                   AllocFlag;     /* alloc flag of resources    */
+	struct pci_dev          *PciDev;        /* for access to pci cfg space*/
+	SK_U32                   PciDevId;      /* pci device id              */
+	struct SK_NET_DEVICE    *dev[2];        /* pointer to device struct   */
+	char                     Name[30];      /* driver name                */
+	struct SK_NET_DEVICE    *Next;          /* link all devs for cleanup  */
+	int                      RxBufSize;     /* length of receive buffers  */
+	struct net_device_stats  stats;         /* linux 'netstat -i' stats   */
+	int                      Index;         /* internal board idx number  */
+	int                      RxQueueSize;   /* memory used for RX queue   */
+	int                      TxSQueueSize;  /* memory used for TXS queue  */
+	int                      TxAQueueSize;  /* memory used for TXA queue  */
+	int                      PromiscCount;  /* promiscuous mode counter   */
+	int                      AllMultiCount; /* allmulticast mode counter  */
+	int                      MulticCount;   /* number of MC addresses used*/
+	int                      HWRevision;	/* Hardware revision          */
+	int                      ActivePort;	/* the active XMAC port       */
+	int                      MaxPorts;      /* number of activated ports  */
+	int                      TxDescrPerRing;/* # of descriptors TX ring   */
+	int                      RxDescrPerRing;/* # of descriptors RX ring   */
+	caddr_t                  pDescrMem;     /* Ptr to the descriptor area */
+	dma_addr_t               pDescrMemDMA;  /* PCI DMA address of area    */
+	TX_PORT                  TxPort[SK_MAX_MACS][2];
+	RX_PORT                  RxPort[SK_MAX_MACS];
+	SK_LE_TABLE              TxListElement[SK_MAX_MACS][2];
+	SK_LE_TABLE              RxListElement[SK_MAX_MACS];
+	SK_LE_TABLE              StatusLETable; 
+	unsigned                 SizeOfAlignedLETables;	
+	spinlock_t               SetPutIndexLock;
+	int                      MaxUnusedRxLeWorking;
+	unsigned int             CsOfs1;        /* for checksum calculation   */
+	unsigned int             CsOfs2;        /* for checksum calculation   */
+	SK_U32                   CsOfs;         /* for checksum calculation   */
+	SK_BOOL                  CheckQueue;    /* check event queue soon     */
+	DIM_INFO                 DynIrqModInfo; /* all data related to IM     */
+	int                      PortUp;
+	int                      PortDown;
+	int                      ChipsetType;   /* 0=GENESIS; 1=Yukon         */
+	SK_U32                   DiagModeActive;/* is diag active?            */
+	SK_BOOL                  DiagFlowCtrl;  /* for control purposes       */
+	SK_PNMI_STRUCT_DATA      PnmiBackup;    /* backup structure for PNMI  */
+	SK_BOOL                  WasIfUp[SK_MAX_MACS]; 
 };
 
 
-#endif /* __INC_SKDRV2ND_H */
+/*******************************************************************************
+ *
+ * Defines and typedefs regarding power management
+ *
+ ******************************************************************************/
+
 
+#ifdef SK_CONFIG_PM
+typedef enum _SK_DEVICE_POWER_STATE
+{
+	SkDeviceStateUnspecified = 0,
+	SkDeviceStateD0,
+	SkDeviceStateD1,
+	SkDeviceStateD2,
+	SkDeviceStateD3,
+	SkDeviceStateMaximum
+} SK_DEVICE_POWER_STATE, *PSK_DEVICE_POWER_STATE;
+#endif
+
+#endif
+
+/*******************************************************************************
+ *
+ * End of file
+ *
+ ******************************************************************************/
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skerror.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skerror.h
--- linux-2.4.29/drivers/net/sk98lin/h/skerror.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skerror.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skerror.h
  * Project:	Gigabit Ethernet Adapters, Common Modules
+ * Version:	$Revision: 2.2 $
+ * Date:	$Date: 2004/05/24 15:27:19 $
  * Purpose:	SK specific Error log support
  *
  ******************************************************************************/
@@ -9,13 +11,12 @@
 /******************************************************************************
  *
  *	(C)Copyright 1998-2002 SysKonnect.
- *	(C)Copyright 2002-2003 Marvell.
+ *	(C)Copyright 2002-2004 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
  *	the Free Software Foundation; either version 2 of the License, or
  *	(at your option) any later version.
- *
  *	The information in this file is provided "AS IS" without warranty.
  *
  ******************************************************************************/
@@ -34,7 +35,6 @@
 #define	SK_ERRCL_HW			(1L<<4)	/* Hardware Failure */
 #define	SK_ERRCL_COMM		(1L<<5)	/* Communication error */
 
-
 /*
  * Define Error Code Bases
  */
@@ -47,7 +47,9 @@
 #define	SK_ERRBASE_I2C		 700	/* Base Error number for I2C module */
 #define	SK_ERRBASE_QUEUE	 800	/* Base Error number for Scheduler */
 #define	SK_ERRBASE_ADDR		 900	/* Base Error number for Address module */
-#define SK_ERRBASE_PECP		1000    /* Base Error number for PECP */
+#define SK_ERRBASE_PECP		1000	/* Base Error number for PECP */
 #define	SK_ERRBASE_DRV		1100	/* Base Error number for Driver */
+#define SK_ERRBASE_ASF		1200	/* Base Error number for ASF */
 
 #endif	/* _INC_SKERROR_H_ */
+
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skgedrv.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skgedrv.h
--- linux-2.4.29/drivers/net/sk98lin/h/skgedrv.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skgedrv.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skgedrv.h
  * Project:	Gigabit Ethernet Adapters, Common Modules
+ * Version:	$Revision: 2.1 $
+ * Date:	$Date: 2003/10/27 14:16:08 $
  * Purpose:	Interface with the driver
  *
  ******************************************************************************/
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skgehw.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skgehw.h
--- linux-2.4.29/drivers/net/sk98lin/h/skgehw.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skgehw.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skgehw.h
  * Project:	Gigabit Ethernet Adapters, Common Modules
+ * Version:	$Revision: 2.42 $
+ * Date:	$Date: 2004/08/13 09:21:20 $
  * Purpose:	Defines and Macros for the Gigabit Ethernet Adapter Product Family
  *
  ******************************************************************************/
@@ -9,13 +11,12 @@
 /******************************************************************************
  *
  *	(C)Copyright 1998-2002 SysKonnect.
- *	(C)Copyright 2002-2003 Marvell.
+ *	(C)Copyright 2002-2004 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
  *	the Free Software Foundation; either version 2 of the License, or
  *	(at your option) any later version.
- *
  *	The information in this file is provided "AS IS" without warranty.
  *
  ******************************************************************************/
@@ -112,6 +113,16 @@
 #define SHIFT1(x)	((x) << 1)
 #define SHIFT0(x)	((x) << 0)
 
+/* Macro for arbitrary alignment of a given pointer */
+#define ALIGN_ADDR( ADDRESS, GRANULARITY ) { \
+    SK_UPTR addr = (SK_UPTR)(ADDRESS); \
+    if (addr & ((GRANULARITY)-1)) { \
+        addr += (GRANULARITY); \
+        addr &= ~(SK_UPTR)((GRANULARITY)-1); \
+        ADDRESS = (void *)addr; \
+    }\
+}
+
 /*
  * Configuration Space header
  * Since this module is used for different OS', those may be
@@ -130,12 +141,12 @@
 #define PCI_BIST		0x0f	/*  8 bit	Built-in selftest */
 #define PCI_BASE_1ST	0x10	/* 32 bit	1st Base address */
 #define PCI_BASE_2ND	0x14	/* 32 bit	2nd Base address */
-	/* Byte 0x18..0x2b:	reserved */
+	/* Bytes 0x18..0x2b:	reserved */
 #define PCI_SUB_VID		0x2c	/* 16 bit	Subsystem Vendor ID */
 #define PCI_SUB_ID		0x2e	/* 16 bit	Subsystem ID */
 #define PCI_BASE_ROM	0x30	/* 32 bit	Expansion ROM Base Address */
 #define PCI_CAP_PTR		0x34	/*  8 bit 	Capabilities Ptr */
-	/* Byte 0x35..0x3b:	reserved */
+	/* Bytes 0x35..0x3b:	reserved */
 #define PCI_IRQ_LINE	0x3c	/*  8 bit	Interrupt Line */
 #define PCI_IRQ_PIN		0x3d	/*  8 bit	Interrupt Pin */
 #define PCI_MIN_GNT		0x3e	/*  8 bit	Min_Gnt */
@@ -145,19 +156,59 @@
 #define PCI_OUR_REG_2	0x44	/* 32 bit 	Our Register 2 */
 	/* Power Management Region */
 #define PCI_PM_CAP_ID	0x48	/*  8 bit 	Power Management Cap. ID */
-#define PCI_PM_NITEM	0x49	/*  8 bit 	Next Item Ptr */
+#define PCI_PM_NITEM	0x49	/*  8 bit 	PM Next Item Pointer */
 #define PCI_PM_CAP_REG	0x4a	/* 16 bit 	Power Management Capabilities */
 #define PCI_PM_CTL_STS	0x4c	/* 16 bit 	Power Manag. Control/Status */
 	/* Byte 0x4e:	reserved */
 #define PCI_PM_DAT_REG	0x4f	/*  8 bit 	Power Manag. Data Register */
 	/* VPD Region */
 #define PCI_VPD_CAP_ID	0x50	/*  8 bit 	VPD Cap. ID */
-#define PCI_VPD_NITEM	0x51	/*  8 bit 	Next Item Ptr */
+#define PCI_VPD_NITEM	0x51	/*  8 bit 	VPD Next Item Pointer */
 #define PCI_VPD_ADR_REG	0x52	/* 16 bit 	VPD Address Register */
 #define PCI_VPD_DAT_REG	0x54	/* 32 bit 	VPD Data Register */
-	/* Byte 0x58..0x59:	reserved */
+	/* Bytes 0x58..0x59:	reserved */
 #define PCI_SER_LD_CTRL	0x5a	/* 16 bit 	SEEPROM Loader Ctrl (YUKON only) */
-	/* Byte 0x5c..0xff:	reserved */
+	/* Bytes 0x5c..0xfc:	used by Yukon-2 */
+#define PCI_MSI_CAP_ID	0x5c	/*  8 bit	MSI Capability ID Register */
+#define PCI_MSI_NITEM	0x5d	/*  8 bit	MSI Next Item Pointer */
+#define PCI_MSI_CTRL	0x5e	/* 16 bit	MSI Message Control */
+#define PCI_MSI_ADR_LO	0x60	/* 32 bit	MSI Message Address (Lower) */
+#define PCI_MSI_ADR_HI	0x64	/* 32 bit	MSI Message Address (Upper) */
+#define PCI_MSI_DATA	0x68	/* 16 bit	MSI Message Data */
+	/* Bytes 0x6a..0x6b:	reserved */
+#define PCI_X_CAP_ID	0x6c	/*  8 bit	PCI-X Capability ID Register */
+#define PCI_X_NITEM		0x6d	/*  8 bit	PCI-X Next Item Pointer */
+#define PCI_X_COMMAND	0x6e	/* 16 bit	PCI-X Command */
+#define PCI_X_PE_STAT	0x70	/* 32 bit	PCI-X / PE Status */
+#define PCI_CAL_CTRL	0x74	/* 16 bit	PCI Calibration Control Register */
+#define PCI_CAL_STAT	0x76	/* 16 bit	PCI Calibration Status Register */
+#define PCI_DISC_CNT	0x78	/* 16 bit	PCI Discard Counter */
+#define PCI_RETRY_CNT	0x7a	/*  8 bit	PCI Retry Counter */
+	/* Byte 0x7b:	reserved */
+#define PCI_OUR_STATUS	0x7c	/* 32 bit 	Adapter Status Register */
+	/* Bytes 0x80..0xdf:	reserved */
+
+/* PCI Express Capability */
+#define PEX_CAP_ID		0xe0	/*  8 bit	PEX Capability ID */
+#define PEX_NITEM		0xe1	/*  8 bit	PEX Next Item Pointer */
+#define PEX_CAP_REG		0xe2	/* 16 bit	PEX Capability Register */
+#define PEX_DEV_CAP		0xe4	/* 32 bit	PEX Device Capabilities */
+#define PEX_DEV_CTRL	0xe8	/* 16 bit	PEX Device Control */
+#define PEX_DEV_STAT	0xea	/* 16 bit	PEX Device Status */
+#define PEX_LNK_CAP		0xec	/* 32 bit	PEX Link Capabilities */
+#define PEX_LNK_CTRL	0xf0	/* 16 bit	PEX Link Control */
+#define PEX_LNK_STAT	0xf2	/* 16 bit	PEX Link Status */
+	/* Bytes 0xf4..0xff:	reserved */
+
+/* PCI Express Extended Capabilities */
+#define PEX_ADV_ERR_REP		0x100	/* 32 bit	PEX Advanced Error Reporting */
+#define PEX_UNC_ERR_STAT	0x104	/* 32 bit	PEX Uncorr. Errors Status */
+#define PEX_UNC_ERR_MASK	0x108	/* 32 bit	PEX Uncorr. Errors Mask */
+#define PEX_UNC_ERR_SEV		0x10c	/* 32 bit	PEX Uncorr. Errors Severity */
+#define PEX_COR_ERR_STAT	0x110	/* 32 bit	PEX Correc. Errors Status */
+#define PEX_COR_ERR_MASK	0x114	/* 32 bit	PEX Correc. Errors Mask */
+#define PEX_ADV_ERR_CAP_C	0x118	/* 32 bit	PEX Advanced Error Cap./Ctrl */
+#define PEX_HEADER_LOG		0x11c	/* 4x32 bit	PEX Header Log Register */
 
 /*
  * I2C Address (PCI Config)
@@ -178,7 +229,7 @@
 #define PCI_ADSTEP		BIT_7S		/* Address Stepping */
 #define PCI_PERREN		BIT_6S		/* Parity Report Response enable */
 #define PCI_VGA_SNOOP	BIT_5S		/* VGA palette snoop */
-#define PCI_MWIEN		BIT_4S		/* Memory write an inv cycl ena */
+#define PCI_MWIEN		BIT_4S		/* Memory write an inv cycl enable */
 #define PCI_SCYCEN		BIT_3S		/* Special Cycle enable */
 #define PCI_BMEN		BIT_2S		/* Bus Master enable */
 #define PCI_MEMEN		BIT_1S		/* Memory Space Access enable */
@@ -227,33 +278,42 @@
 #define PCI_MEMSIZE		0x4000L		/* use 16 kB Memory Base */
 #define PCI_MEMBASE_MSK 0xffffc000L	/* Bit 31..14:	Memory Base Address */
 #define PCI_MEMSIZE_MSK 0x00003ff0L	/* Bit 13.. 4:	Memory Size Req. */
-#define PCI_PREFEN		BIT_3		/* Prefetchable */
-#define PCI_MEM_TYP		(3L<<2)		/* Bit	2.. 1:	Memory Type */
+#define PCI_PREFEN		BIT_3		/* Prefetch enable */
+#define PCI_MEM_TYP_MSK	(3L<<1)		/* Bit	2.. 1:	Memory Type Mask */
+#define PCI_MEMSPACE	BIT_0		/* Memory Space Indicator */
+
 #define PCI_MEM32BIT	(0L<<1)		/* Base addr anywhere in 32 Bit range */
 #define PCI_MEM1M		(1L<<1)		/* Base addr below 1 MegaByte */
 #define PCI_MEM64BIT	(2L<<1)		/* Base addr anywhere in 64 Bit range */
-#define PCI_MEMSPACE	BIT_0		/* Memory Space Indicator */
 
 /*	PCI_BASE_2ND	32 bit	2nd Base address */
 #define PCI_IOBASE		0xffffff00L	/* Bit 31.. 8:	I/O Base address */
 #define PCI_IOSIZE		0x000000fcL	/* Bit	7.. 2:	I/O Size Requirements */
-									/* Bit	1:	reserved */
+								/* Bit	1:	reserved */
 #define PCI_IOSPACE		BIT_0		/* I/O Space Indicator */
 
 /*	PCI_BASE_ROM	32 bit	Expansion ROM Base Address */
 #define PCI_ROMBASE_MSK	0xfffe0000L	/* Bit 31..17:	ROM Base address */
 #define PCI_ROMBASE_SIZ	(0x1cL<<14)	/* Bit 16..14:	Treat as Base or Size */
 #define PCI_ROMSIZE		(0x38L<<11)	/* Bit 13..11:	ROM Size Requirements */
-									/* Bit 10.. 1:	reserved */
+								/* Bit 10.. 1:	reserved */
 #define PCI_ROMEN		BIT_0		/* Address Decode enable */
 
 /* Device Dependent Region */
 /*	PCI_OUR_REG_1		32 bit	Our Register 1 */
-									/* Bit 31..29:	reserved */
+								/* Bit 31..29:	reserved */
 #define PCI_PHY_COMA	BIT_28		/* Set PHY to Coma Mode (YUKON only) */
 #define PCI_TEST_CAL	BIT_27		/* Test PCI buffer calib. (YUKON only) */
 #define PCI_EN_CAL		BIT_26		/* Enable PCI buffer calib. (YUKON only) */
 #define PCI_VIO			BIT_25		/* PCI I/O Voltage, 0 = 3.3V, 1 = 5V */
+/* Yukon-2 */
+#define PCI_Y2_PIG_ENA		BIT_31	/* Enable Plug-in-Go (YUKON-2) */
+#define PCI_Y2_DLL_DIS		BIT_30	/* Disable PCI DLL (YUKON-2) */
+#define PCI_Y2_PHY2_COMA	BIT_29	/* Set PHY 2 to Coma Mode (YUKON-2) */
+#define PCI_Y2_PHY1_COMA	BIT_28	/* Set PHY 1 to Coma Mode (YUKON-2) */
+#define PCI_Y2_PHY2_POWD	BIT_27	/* Set PHY 2 to Power Down (YUKON-2) */
+#define PCI_Y2_PHY1_POWD	BIT_26	/* Set PHY 1 to Power Down (YUKON-2) */
+								/* Bit 25:	reserved */
 #define PCI_DIS_BOOT	BIT_24		/* Disable BOOT via ROM */
 #define PCI_EN_IO		BIT_23		/* Mapping to I/O space */
 #define PCI_EN_FPROM	BIT_22		/* Enable FLASH mapping to memory */
@@ -264,9 +324,10 @@
 #define PCI_PAGE_32K	(1L<<20)	/*		32 k pages	*/
 #define PCI_PAGE_64K	(2L<<20)	/*		64 k pages	*/
 #define PCI_PAGE_128K	(3L<<20)	/*		128 k pages	*/
-									/* Bit 19:	reserved	*/
+								/* Bit 19:	reserved	*/
 #define PCI_PAGEREG		(7L<<16)	/* Bit 18..16:	Page Register	*/
 #define PCI_NOTAR		BIT_15		/* No turnaround cycle */
+#define PCI_PEX_LEGNAT	BIT_15		/* PEX PM legacy/native mode (YUKON-2) */
 #define PCI_FORCE_BE	BIT_14		/* Assert all BEs on MR */
 #define PCI_DIS_MRL		BIT_13		/* Disable Mem Read Line */
 #define PCI_DIS_MRM		BIT_12		/* Disable Mem Read Multiple */
@@ -277,12 +338,11 @@
 #define PCI_SKEW_DAS	(0xfL<<4)	/* Bit	7.. 4:	Skew Ctrl, DAS Ext */
 #define PCI_SKEW_BASE	0xfL		/* Bit	3.. 0:	Skew Ctrl, Base	*/
 
-
 /*	PCI_OUR_REG_2		32 bit	Our Register 2 */
 #define PCI_VPD_WR_THR	(0xffL<<24)	/* Bit 31..24:	VPD Write Threshold */
 #define PCI_DEV_SEL		(0x7fL<<17)	/* Bit 23..17:	EEPROM Device Select */
 #define PCI_VPD_ROM_SZ	(7L<<14)	/* Bit 16..14:	VPD ROM Size	*/
-									/* Bit 13..12:	reserved	*/
+								/* Bit 13..12:	reserved	*/
 #define PCI_PATCH_DIR	(0xfL<<8)	/* Bit 11.. 8:	Ext Patches dir 3..0 */
 #define PCI_PATCH_DIR_3	BIT_11
 #define PCI_PATCH_DIR_2	BIT_10
@@ -295,21 +355,20 @@
 #define PCI_EXT_PATCH_0	BIT_4
 #define PCI_EN_DUMMY_RD	BIT_3		/* Enable Dummy Read */
 #define PCI_REV_DESC	BIT_2		/* Reverse Desc. Bytes */
-									/* Bit	1:	reserved */
+								/* Bit	1:	reserved */
 #define PCI_USEDATA64	BIT_0		/* Use 64Bit Data bus ext */
 
-
 /* Power Management Region */
 /*	PCI_PM_CAP_REG		16 bit	Power Management Capabilities */
 #define PCI_PME_SUP_MSK	(0x1f<<11)	/* Bit 15..11:	PM Event Support Mask */
-#define PCI_PME_D3C_SUP	BIT_15S		/* PME from D3cold Support (if Vaux) */
+#define PCI_PME_D3C_SUP	BIT_15S		/* PME from D3cold Support (if VAUX) */
 #define PCI_PME_D3H_SUP	BIT_14S		/* PME from D3hot Support */
 #define PCI_PME_D2_SUP	BIT_13S		/* PME from D2 Support */
 #define PCI_PME_D1_SUP	BIT_12S		/* PME from D1 Support */
 #define PCI_PME_D0_SUP	BIT_11S		/* PME from D0 Support */
 #define PCI_PM_D2_SUP	BIT_10S		/* D2 Support in 33 MHz mode */
 #define PCI_PM_D1_SUP	BIT_9S		/* D1 Support */
-									/* Bit	8.. 6:	reserved */
+								/* Bit	8.. 6:	reserved */
 #define PCI_PM_DSI		BIT_5S		/* Device Specific Initialization */
 #define PCI_PM_APS		BIT_4S		/* Auxialiary Power Source */
 #define PCI_PME_CLOCK	BIT_3S		/* PM Event Clock */
@@ -320,7 +379,7 @@
 #define PCI_PM_DAT_SCL	(3<<13)		/* Bit 14..13:	Data Reg. scaling factor */
 #define PCI_PM_DAT_SEL	(0xf<<9)	/* Bit 12.. 9:	PM data selector field */
 #define PCI_PME_EN		BIT_8S		/* Enable PME# generation (YUKON only) */
-									/* Bit	7.. 2:	reserved */
+								/* Bit	7.. 2:	reserved */
 #define PCI_PM_STATE_MSK	3		/* Bit	1.. 0:	Power Management State */
 
 #define PCI_PM_STATE_D0		0		/* D0:	Operational (default) */
@@ -331,7 +390,59 @@
 /* VPD Region */
 /*	PCI_VPD_ADR_REG		16 bit	VPD Address Register */
 #define PCI_VPD_FLAG	BIT_15S		/* starts VPD rd/wr cycle */
-#define PCI_VPD_ADR_MSK	0x7fffL		/* Bit 14.. 0:	VPD address mask */
+#define PCI_VPD_ADR_MSK	0x7fffL		/* Bit 14.. 0:	VPD Address Mask */
+
+/* PCI_OUR_STATUS		32 bit 	Adapter Status Register (Yukon-2) */
+#define PCI_OS_PCI64B	BIT_31		/* Conventional PCI 64 bits Bus */
+#define PCI_OS_PCIX		BIT_30		/* PCI-X Bus */
+#define PCI_OS_MODE_MSK	(3<<28)		/* Bit 29..28:	PCI-X Bus Mode Mask */
+#define PCI_OS_PCI66M	BIT_27		/* PCI 66 MHz Bus */
+#define PCI_OS_PCI_X	BIT_26		/* PCI/PCI-X Bus (0 = PEX) */
+#define PCI_OS_DLLE_MSK	(3<<24)		/* Bit 25..24:	DLL Status Indication */
+#define PCI_OS_DLLR_MSK	(0xf<<20)	/* Bit 23..20:	DLL Row Counters Values */
+#define PCI_OS_DLLC_MSK	(0xf<<16)	/* Bit 19..16:	DLL Col. Counters Values */
+								/* Bit 15.. 8:	reserved */
+
+#define PCI_OS_SPEED(val)	((val & PCI_OS_MODE_MSK) >> 28)	/* PCI-X Speed */
+/* possible values for the speed field of the register */
+#define PCI_OS_SPD_PCI		0		/* PCI Conventional Bus */
+#define PCI_OS_SPD_X66		1		/* PCI-X 66MHz Bus */
+#define PCI_OS_SPD_X100		2		/* PCI-X 100MHz Bus */
+#define PCI_OS_SPD_X133		3		/* PCI-X 133MHz Bus */
+
+/* PEX_DEV_CTRL			16 bit	PEX Device Control (Yukon-2) */
+								/* Bit 15	reserved */
+#define PEX_DC_MAX_RRS_MSK	(7<<12)	/* Bit 14..12:	Max. Read Request Size */
+#define PEX_DC_EN_NO_SNOOP	BIT_11S	/* Enable No Snoop */
+#define PEX_DC_EN_AUX_POW	BIT_10S	/* Enable AUX Power */
+#define PEX_DC_EN_PHANTOM	BIT_9S	/* Enable Phantom Functions */
+#define PEX_DC_EN_EXT_TAG	BIT_8S	/* Enable Extended Tag Field */
+#define PEX_DC_MAX_PLS_MSK	(7<<5)	/* Bit  7.. 5:	Max. Payload Size Mask */
+#define PEX_DC_EN_REL_ORD	BIT_4S	/* Enable Relaxed Ordering */
+#define PEX_DC_EN_UNS_RQ_RP	BIT_3S	/* Enable Unsupported Request Reporting */
+#define PEX_DC_EN_FAT_ER_RP	BIT_2S	/* Enable Fatal Error Reporting */
+#define PEX_DC_EN_NFA_ER_RP	BIT_1S	/* Enable Non-Fatal Error Reporting */
+#define PEX_DC_EN_COR_ER_RP	BIT_0S	/* Enable Correctable Error Reporting */
+
+#define PEX_DC_MAX_RD_RQ_SIZE(x)	(SHIFT12(x) & PEX_DC_MAX_RRS_MSK)
+
+/* PEX_UNC_ERR_STAT	 PEX Uncorrectable Errors Status Register (Yukon-2) */
+								/* Bit 31..21	reserved */
+#define	PEX_UNSUP_REQ 	BIT_20		/* Unsupported Request Error */
+									/* ECRC Error (not supported) */
+#define PEX_MALFOR_TLP	BIT_18		/* Malformed TLP */
+									/* Receiver Overflow (not supported) */
+#define PEX_UNEXP_COMP	BIT_16		/* Unexpected Completion */
+									/* Completer Abort (not supported) */
+#define PEX_COMP_TO		BIT_14		/* Completion Timeout */
+#define PEX_FLOW_CTRL_P	BIT_13		/* Flow Control Protocol Error */
+#define PEX_POIS_TLP	BIT_12		/* Poisoned TLP */
+								/* Bit 11.. 5:	reserved */
+#define PEX_DATA_LINK_P BIT_4		/* Data Link Protocol Error */
+								/* Bit  3.. 1:	reserved */
+									/* Training Error (not supported) */
+
+#define PEX_FATAL_ERRORS	(PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P)
 
 /*	Control Register File (Address Map) */
 
@@ -347,8 +458,14 @@
 #define B0_IMSK			0x000c	/* 32 bit	Interrupt Mask Register */
 #define B0_HWE_ISRC		0x0010	/* 32 bit	HW Error Interrupt Src Reg */
 #define B0_HWE_IMSK		0x0014	/* 32 bit	HW Error Interrupt Mask Reg */
-#define B0_SP_ISRC		0x0018	/* 32 bit	Special Interrupt Source Reg */
-	/* 0x001c:		reserved */
+#define B0_SP_ISRC		0x0018	/* 32 bit	Special Interrupt Source Reg 1 */
+
+/* Special ISR registers (Yukon-2 only) */
+#define B0_Y2_SP_ISRC2	0x001c	/* 32 bit	Special Interrupt Source Reg 2 */
+#define B0_Y2_SP_ISRC3	0x0020	/* 32 bit	Special Interrupt Source Reg 3 */
+#define B0_Y2_SP_EISR	0x0024	/* 32 bit	Enter ISR Reg */
+#define B0_Y2_SP_LISR	0x0028	/* 32 bit	Leave ISR Reg */
+#define B0_Y2_SP_ICR	0x002c	/* 32 bit	Interrupt Control Reg */
 
 /* B0 XMAC 1 registers (GENESIS only) */
 #define B0_XM1_IMSK		0x0020	/* 16 bit r/w	XMAC 1 Interrupt Mask Register*/
@@ -399,13 +516,22 @@
 #define B2_PMD_TYP		0x0119	/*  8 bit	PMD type */
 #define B2_MAC_CFG		0x011a	/*  8 bit	MAC Configuration / Chip Revision */
 #define B2_CHIP_ID		0x011b	/*  8 bit 	Chip Identification Number */
-	/* Eprom registers are currently of no use */
+	/* Eprom registers */
 #define B2_E_0			0x011c	/*  8 bit	EPROM Byte 0 (ext. SRAM size */
+/* Yukon and Genesis */
 #define B2_E_1			0x011d	/*  8 bit	EPROM Byte 1 (PHY type) */
 #define B2_E_2			0x011e	/*  8 bit	EPROM Byte 2 */
+/* Yukon-2 */
+#define B2_Y2_CLK_GATE	0x011d	/*  8 bit	Clock Gating (Yukon-2) */
+#define B2_Y2_HW_RES	0x011e	/*  8 bit	HW Resources (Yukon-2) */
+
 #define B2_E_3			0x011f	/*  8 bit	EPROM Byte 3 */
+
+/* Yukon and Genesis */
 #define B2_FAR			0x0120	/* 32 bit	Flash-Prom Addr Reg/Cnt */
 #define B2_FDP			0x0124	/*  8 bit	Flash-Prom Data Port */
+/* Yukon-2 */
+#define B2_Y2_CLK_CTRL	0x0120	/* 32 bit	Core Clock Frequency Control */
 	/* 0x0125 - 0x0127:	reserved */
 #define B2_LD_CTRL		0x0128	/*  8 bit	EPROM loader control register */
 #define B2_LD_TEST		0x0129	/*  8 bit	EPROM loader test register */
@@ -437,6 +563,10 @@
 #define B2_BSC_CTRL		0x0178	/*  8 bit	Blink Source Counter Control */
 #define B2_BSC_STAT		0x0179	/*  8 bit	Blink Source Counter Status */
 #define B2_BSC_TST		0x017a	/* 16 bit	Blink Source Counter Test Reg */
+	
+/* Yukon-2 */
+#define Y2_PEX_PHY_DATA	0x0170	/* 16 bit	PEX PHY Data Register */
+#define Y2_PEX_PHY_ADDR	0x0172	/* 16 bit	PEX PHY Address Register */
 	/* 0x017c - 0x017f:	reserved */
 
 /*
@@ -446,9 +576,13 @@
 #define B3_RAM_ADDR		0x0180	/* 32 bit	RAM Address, to read or write */
 #define B3_RAM_DATA_LO	0x0184	/* 32 bit	RAM Data Word (low dWord) */
 #define B3_RAM_DATA_HI	0x0188	/* 32 bit	RAM Data Word (high dWord) */
-	/* 0x018c - 0x018f:	reserved */
+
+#define SELECT_RAM_BUFFER(rb, addr) (addr | (rb << 6))	/* Yukon-2 only */
+
+    /* 0x018c - 0x018f:	reserved */
 
 /* RAM Interface Registers */
+/* Yukon-2: use SELECT_RAM_BUFFER() to access the RAM buffer */
 /*
  * The HW-Spec. calls this registers Timeout Value 0..11. But this names are
  * not usable in SW. Please notice these are NOT real timeouts, these are
@@ -515,8 +649,8 @@
 	/* 0x01ea - 0x01eb:	reserved */
 #define B3_PA_TOVAL_TX2	0x01ec	/* 16 bit	Timeout Val Tx Path MAC 2 */
 	/* 0x01ee - 0x01ef:	reserved */
-#define B3_PA_CTRL	0x01f0	/* 16 bit	Packet Arbiter Ctrl Register */
-#define B3_PA_TEST	0x01f2	/* 16 bit	Packet Arbiter Test Register */
+#define B3_PA_CTRL		0x01f0	/* 16 bit	Packet Arbiter Ctrl Register */
+#define B3_PA_TEST		0x01f2	/* 16 bit	Packet Arbiter Test Register */
 	/* 0x01f4 - 0x01ff:	reserved */
 
 /*
@@ -530,7 +664,16 @@
 #define TXA_CTRL		0x0210	/*  8 bit	Tx Arbiter Control Register */
 #define TXA_TEST		0x0211	/*  8 bit	Tx Arbiter Test Register */
 #define TXA_STAT		0x0212	/*  8 bit	Tx Arbiter Status Register */
-	/* 0x0213 - 0x027f:	reserved */
+	/* 0x0213 - 0x021f:	reserved */
+	
+	/* RSS key registers for Yukon-2 Family */
+#define B4_RSS_KEY		0x0220	/* 4x32 bit RSS Key register (Yukon-2) */
+	/* RSS key register offsets */
+#define KEY_IDX_0		0		/* offset for location of KEY 0 */
+#define KEY_IDX_1		4		/* offset for location of KEY 1 */
+#define KEY_IDX_2		8		/* offset for location of KEY 2 */
+#define KEY_IDX_3		12		/* offset for location of KEY 3 */
+		
 	/* 0x0280 - 0x0292:	MAC 2 */
 	/* 0x0213 - 0x027f:	reserved */
 
@@ -568,8 +711,37 @@
 #define Q_T1_SV	0x3f	/*  8 bit	Test Register 1 Supervisor SM */
 #define Q_T2	0x40	/* 32 bit	Test Register 2	*/
 #define Q_T3	0x44	/* 32 bit	Test Register 3	*/
+
+/* Yukon-2 */
+#define Q_DONE	0x24	/* 16 bit	Done Index 		(Yukon-2 only) */
+#define Q_WM	0x40	/* 16 bit	FIFO Watermark */
+#define Q_AL	0x42	/*  8 bit	FIFO Alignment */
+#define Q_RSP	0x44	/* 16 bit	FIFO Read Shadow Pointer */
+#define Q_RSL	0x46	/*  8 bit	FIFO Read Shadow Level */
+#define Q_RP	0x48	/*  8 bit	FIFO Read Pointer */
+#define Q_RL	0x4a	/*  8 bit	FIFO Read Level */
+#define Q_WP	0x4c	/*  8 bit	FIFO Write Pointer */
+#define Q_WSP	0x4d	/*  8 bit	FIFO Write Shadow Pointer */
+#define Q_WL	0x4e	/*  8 bit	FIFO Write Level */
+#define Q_WSL	0x4f	/*  8 bit	FIFO Write Shadow Level */
 	/* 0x48 - 0x7f:	reserved */
 
+/* Queue Prefetch Unit Offsets, use Y2_PREF_Q_ADDR() to address (Yukon-2 only)*/
+#define Y2_B8_PREF_REGS			0x0450
+
+#define PREF_UNIT_CTRL_REG		0x00	/* 32 bit	Prefetch Control register */
+#define PREF_UNIT_LAST_IDX_REG	0x04	/* 16 bit	Last Index */
+#define PREF_UNIT_ADDR_LOW_REG	0x08	/* 32 bit	List start addr, low part */
+#define PREF_UNIT_ADDR_HI_REG	0x0c	/* 32 bit	List start addr, high part*/
+#define PREF_UNIT_GET_IDX_REG	0x10	/* 16 bit	Get Index */
+#define PREF_UNIT_PUT_IDX_REG	0x14	/* 16 bit	Put Index */
+#define PREF_UNIT_FIFO_WP_REG	0x20	/*  8 bit 	FIFO write pointer */
+#define PREF_UNIT_FIFO_RP_REG	0x24	/*  8 bit	FIFO read pointer */
+#define PREF_UNIT_FIFO_WM_REG	0x28	/*  8 bit	FIFO watermark */
+#define PREF_UNIT_FIFO_LEV_REG	0x2c	/*  8 bit	FIFO level */
+
+#define PREF_UNIT_MASK_IDX  0x0fff
+
 /*
  *	Bank 16 - 23
  */
@@ -581,17 +753,17 @@
 #define RB_END			0x04	/* 32 bit	RAM Buffer End Address */
 #define RB_WP			0x08	/* 32 bit	RAM Buffer Write Pointer */
 #define RB_RP			0x0c	/* 32 bit	RAM Buffer Read Pointer */
-#define RB_RX_UTPP		0x10	/* 32 bit	Rx Upper Threshold, Pause Pack */
-#define RB_RX_LTPP		0x14	/* 32 bit	Rx Lower Threshold, Pause Pack */
+#define RB_RX_UTPP		0x10	/* 32 bit	Rx Upper Threshold, Pause Packet */
+#define RB_RX_LTPP		0x14	/* 32 bit	Rx Lower Threshold, Pause Packet */
 #define RB_RX_UTHP		0x18	/* 32 bit	Rx Upper Threshold, High Prio */
 #define RB_RX_LTHP		0x1c	/* 32 bit	Rx Lower Threshold, High Prio */
 	/* 0x10 - 0x1f:	reserved at Tx RAM Buffer Registers */
 #define RB_PC			0x20	/* 32 bit	RAM Buffer Packet Counter */
 #define RB_LEV			0x24	/* 32 bit	RAM Buffer Level Register */
-#define RB_CTRL			0x28	/*  8 bit	RAM Buffer Control Register */
+#define RB_CTRL			0x28	/* 32 bit	RAM Buffer Control Register */
 #define RB_TST1			0x29	/*  8 bit	RAM Buffer Test Register 1 */
-#define RB_TST2			0x2A	/*  8 bit	RAM Buffer Test Register 2 */
-	/* 0x2c - 0x7f:	reserved */
+#define RB_TST2			0x2a	/*  8 bit	RAM Buffer Test Register 2 */
+	/* 0x2b - 0x7f:	reserved */
 
 /*
  *	Bank 24
@@ -626,13 +798,15 @@
 #define LNK_LED_REG		0x0c3c	/*  8 bit	Link LED Register */
 	/* 0x0c3d - 0x0c3f:	reserved */
 
-/* Receive GMAC FIFO (YUKON only), use MR_ADDR() to access */
+/* Receive GMAC FIFO (YUKON and Yukon-2), use MR_ADDR() to access */
 #define RX_GMF_EA		0x0c40	/* 32 bit	Rx GMAC FIFO End Address */
 #define RX_GMF_AF_THR	0x0c44	/* 32 bit	Rx GMAC FIFO Almost Full Thresh. */
 #define RX_GMF_CTRL_T	0x0c48	/* 32 bit	Rx GMAC FIFO Control/Test */
 #define RX_GMF_FL_MSK	0x0c4c	/* 32 bit	Rx GMAC FIFO Flush Mask */
 #define RX_GMF_FL_THR	0x0c50	/* 32 bit	Rx GMAC FIFO Flush Threshold */
-	/* 0x0c54 - 0x0c5f:	reserved */
+#define RX_GMF_TR_THR	0x0c54	/* 32 bit	Rx Truncation Threshold (Yukon-2) */
+	/* 0x0c58 - 0x0c5b:	reserved */
+#define RX_GMF_VLAN		0x0c5c	/* 32 bit 	Rx VLAN Type Register (Yukon-2) */
 #define RX_GMF_WP		0x0c60	/* 32 bit 	Rx GMAC FIFO Write Pointer */
 	/* 0x0c64 - 0x0c67:	reserved */
 #define RX_GMF_WLEV		0x0c68	/* 32 bit 	Rx GMAC FIFO Write Level */
@@ -674,11 +848,12 @@
 #define TX_LED_TST		0x0d29	/*  8 bit	Transmit LED Cnt Test Reg */
 	/* 0x0d2a - 0x0d3f:	reserved */
 
-/* Transmit GMAC FIFO (YUKON only), use MR_ADDR() to access */
+/* Transmit GMAC FIFO (YUKON and Yukon-2), use MR_ADDR() to access */
 #define TX_GMF_EA		0x0d40	/* 32 bit	Tx GMAC FIFO End Address */
 #define TX_GMF_AE_THR	0x0d44	/* 32 bit	Tx GMAC FIFO Almost Empty Thresh.*/
 #define TX_GMF_CTRL_T	0x0d48	/* 32 bit	Tx GMAC FIFO Control/Test */
-	/* 0x0d4c - 0x0d5f:	reserved */
+	/* 0x0d4c - 0x0d5b:	reserved */
+#define TX_GMF_VLAN		0x0d5c	/* 32 bit 	Tx VLAN Type Register (Yukon-2) */
 #define TX_GMF_WP		0x0d60	/* 32 bit 	Tx GMAC FIFO Write Pointer */
 #define TX_GMF_WSP		0x0d64	/* 32 bit 	Tx GMAC FIFO Write Shadow Ptr. */
 #define TX_GMF_WLEV		0x0d68	/* 32 bit 	Tx GMAC FIFO Write Level */
@@ -711,12 +886,84 @@
 #define GMAC_TI_ST_CTRL	0x0e18	/*  8 bit	Time Stamp Timer Ctrl Reg */
 	/* 0x0e19:	reserved */
 #define GMAC_TI_ST_TST	0x0e1a	/*  8 bit	Time Stamp Timer Test Reg */
-	/* 0x0e1b - 0x0e7f:	reserved */
+	/* 0x0e1b - 0x0e1f:	reserved */
+
+/* Polling Unit Registers (Yukon-2 only) */
+#define POLL_CTRL			0x0e20	/* 32 bit	Polling Unit Control Reg */
+#define POLL_LAST_IDX		0x0e24	/* 16 bit	Polling Unit List Last Index */
+	/* 0x0e26 - 0x0e27:	reserved */
+#define POLL_LIST_ADDR_LO	0x0e28	/* 32 bit	Poll. List Start Addr (low) */
+#define POLL_LIST_ADDR_HI	0x0e2c	/* 32 bit	Poll. List Start Addr (high) */
+	/* 0x0e30 - 0x0e3f:	reserved */
+
+/* ASF Subsystem Registers (Yukon-2 only) */
+#define B28_Y2_SMB_CONFIG	0x0e40	/* 32 bit	ASF SMBus Config Register */
+#define B28_Y2_SMB_CSD_REG	0x0e44	/* 32 bit	ASF SMB Control/Status/Data */
+	/* 0x0e48 - 0x0e5f: reserved */
+#define B28_Y2_ASF_IRQ_V_BASE	0x0e60	/* 32 bit	ASF IRQ Vector Base */
+	/* 0x0e64 - 0x0e67: reserved */
+#define B28_Y2_ASF_STAT_CMD	0x0e68	/* 32 bit	ASF Status and Command Reg */
+#define B28_Y2_ASF_HOST_COM	0x0e6c	/* 32 bit	ASF Host Communication Reg */
+#define B28_Y2_DATA_REG_1	0x0e70	/* 32 bit	ASF/Host Data Register 1 */
+#define B28_Y2_DATA_REG_2	0x0e74	/* 32 bit	ASF/Host Data Register 2 */
+#define B28_Y2_DATA_REG_3	0x0e78	/* 32 bit	ASF/Host Data Register 3 */
+#define B28_Y2_DATA_REG_4	0x0e7c	/* 32 bit	ASF/Host Data Register 4 */
 
 /*
  *	Bank 29
  */
-	/* 0x0e80 - 0x0efc:	reserved */
+
+/* Status BMU Registers (Yukon-2 only)*/
+#define STAT_CTRL			0x0e80	/* 32 bit	Status BMU Control Reg */
+#define STAT_LAST_IDX		0x0e84	/* 16 bit	Status BMU Last Index */
+	/* 0x0e85 - 0x0e86:	reserved */
+#define STAT_LIST_ADDR_LO	0x0e88	/* 32 bit	Status List Start Addr (low) */
+#define STAT_LIST_ADDR_HI	0x0e8c	/* 32 bit	Status List Start Addr (high) */
+#define STAT_TXA1_RIDX		0x0e90	/* 16 bit	Status TxA1 Report Index Reg */
+#define STAT_TXS1_RIDX		0x0e92	/* 16 bit	Status TxS1 Report Index Reg */
+#define STAT_TXA2_RIDX		0x0e94	/* 16 bit	Status TxA2 Report Index Reg */
+#define STAT_TXS2_RIDX		0x0e96	/* 16 bit	Status TxS2 Report Index Reg */
+#define STAT_TX_IDX_TH		0x0e98	/* 16 bit	Status Tx Index Threshold Reg */
+	/* 0x0e9a - 0x0e9b:	reserved */
+#define STAT_PUT_IDX		0x0e9c	/* 16 bit	Status Put Index Reg */
+	/* 0x0e9e - 0x0e9f:	reserved */
+
+/* FIFO Control/Status Registers (Yukon-2 only)*/
+#define STAT_FIFO_WP		0x0ea0	/*  8 bit	Status FIFO Write Pointer Reg */
+	/* 0x0ea1 - 0x0ea3:	reserved */
+#define STAT_FIFO_RP		0x0ea4	/*  8 bit	Status FIFO Read Pointer Reg */
+	/* 0x0ea5:	reserved */
+#define STAT_FIFO_RSP		0x0ea6	/*  8 bit	Status FIFO Read Shadow Ptr */
+	/* 0x0ea7:	reserved */
+#define STAT_FIFO_LEVEL		0x0ea8	/*  8 bit	Status FIFO Level Reg */
+	/* 0x0ea9:	reserved */
+#define STAT_FIFO_SHLVL		0x0eaa	/*  8 bit	Status FIFO Shadow Level Reg */
+	/* 0x0eab:	reserved */
+#define STAT_FIFO_WM		0x0eac	/*  8 bit	Status FIFO Watermark Reg */
+#define STAT_FIFO_ISR_WM	0x0ead	/*  8 bit	Status FIFO ISR Watermark Reg */
+	/* 0x0eae - 0x0eaf:	reserved */
+
+/* Level and ISR Timer Registers (Yukon-2 only)*/
+#define STAT_LEV_TIMER_INI	0x0eb0	/* 32 bit	Level Timer Init. Value Reg */
+#define STAT_LEV_TIMER_CNT	0x0eb4	/* 32 bit	Level Timer Counter Reg */
+#define STAT_LEV_TIMER_CTRL	0x0eb8	/*  8 bit	Level Timer Control Reg */
+#define STAT_LEV_TIMER_TEST	0x0eb9	/*  8 bit	Level Timer Test Reg */
+	/* 0x0eba - 0x0ebf:	reserved */
+#define STAT_TX_TIMER_INI	0x0ec0	/* 32 bit	Tx Timer Init. Value Reg */
+#define STAT_TX_TIMER_CNT	0x0ec4	/* 32 bit	Tx Timer Counter Reg */
+#define STAT_TX_TIMER_CTRL	0x0ec8	/*  8 bit	Tx Timer Control Reg */
+#define STAT_TX_TIMER_TEST	0x0ec9	/*  8 bit	Tx Timer Test Reg */
+	/* 0x0eca - 0x0ecf:	reserved */
+#define STAT_ISR_TIMER_INI	0x0ed0	/* 32 bit	ISR Timer Init. Value Reg */
+#define STAT_ISR_TIMER_CNT	0x0ed4	/* 32 bit	ISR Timer Counter Reg */
+#define STAT_ISR_TIMER_CTRL	0x0ed8	/*  8 bit	ISR Timer Control Reg */
+#define STAT_ISR_TIMER_TEST	0x0ed9	/*  8 bit	ISR Timer Test Reg */
+	/* 0x0eda - 0x0eff:	reserved */
+
+#define ST_LAST_IDX_MASK    0x007f  /* Last Index Mask */
+#define ST_TXRP_IDX_MASK    0x0fff  /* Tx Report Index Mask */
+#define ST_TXTH_IDX_MASK    0x0fff  /* Tx Threshold Index Mask */
+#define ST_WM_IDX_MASK		0x3f	/* FIFO Watermark Index Mask */
 
 /*
  *	Bank 30
@@ -740,11 +987,9 @@
 #define WOL_MATCH_RES	0x0f23	/*  8 bit	WOL Match Result Reg */
 #define WOL_MAC_ADDR_LO	0x0f24	/* 32 bit	WOL MAC Address Low */
 #define WOL_MAC_ADDR_HI	0x0f28	/* 16 bit	WOL MAC Address High */
-#define WOL_PATT_RPTR	0x0f2c	/*  8 bit	WOL Pattern Read Ptr */
-
-/* use this macro to access above registers */
-#define WOL_REG(Reg)	((Reg) + (pAC->GIni.GIWolOffs))
-
+#define WOL_PATT_PME	0x0f2a	/*  8 bit   WOL PME Match Enable (Yukon-2) */
+#define WOL_PATT_ASFM	0x0f2b	/*  8 bit   WOL ASF Match Enable (Yukon-2) */
+#define WOL_PATT_RPTR	0x0f2c	/*  8 bit	WOL Pattern Read Pointer */
 
 /* WOL Pattern Length Registers (YUKON only) */
 
@@ -762,11 +1007,22 @@
  */
 /* 0x0f80 - 0x0fff:	reserved */
 
+/* WOL registers link 2 */
+
+/* use this macro to access WOL registers */
+#define WOL_REG(Port, Reg)	((Reg) + ((Port)*0x80) + (pAC->GIni.GIWolOffs))
+
 /*
  *	Bank 32	- 33
  */
 #define WOL_PATT_RAM_1	0x1000	/*  WOL Pattern RAM Link 1 */
+#define WOL_PATT_RAM_2  0x1400  /*  WOL Pattern RAM Link 2 */
+
+/* use this macro to retrieve the pattern ram base address */
+#define WOL_PATT_RAM_BASE(Port) (WOL_PATT_RAM_1 + (Port)*0x400)
 
+/* offset to configuration space on Yukon-2 */
+#define Y2_CFG_SPC 		0x1c00
 /*
  *	Bank 0x22 - 0x3f
  */
@@ -800,11 +1056,24 @@
 								/* Bit 7:	reserved */
 #define RAP_RAP			0x3f	/* Bit 6..0:	0 = block 0,..,6f = block 6f */
 
+/*	B0_CTST			24 bit	Control/Status register */
+								/* Bit 23..18:	reserved */
+#define Y2_VMAIN_AVAIL	BIT_17		/* VMAIN available (YUKON-2 only) */
+#define Y2_VAUX_AVAIL	BIT_16		/* VAUX available (YUKON-2 only) */
+								/* Bit 15..14:	reserved */
+#define Y2_ASF_ENABLE	BIT_13S		/* ASF Unit Enable (YUKON-2 only) */
+#define Y2_ASF_DISABLE	BIT_12S		/* ASF Unit Disable (YUKON-2 only) */
+#define Y2_CLK_RUN_ENA	BIT_11S		/* CLK_RUN Enable  (YUKON-2 only) */
+#define Y2_CLK_RUN_DIS	BIT_10S		/* CLK_RUN Disable (YUKON-2 only) */
+#define Y2_LED_STAT_ON	BIT_9S		/* Status LED On  (YUKON-2 only) */
+#define Y2_LED_STAT_OFF	BIT_8S		/* Status LED Off (YUKON-2 only) */
+								/* Bit  7.. 0:	same as below */
+
 /*	B0_CTST			16 bit	Control/Status register */
 								/* Bit 15..14:	reserved */
-#define CS_CLK_RUN_HOT	BIT_13S		/* CLK_RUN hot m. (YUKON-Lite only) */
-#define CS_CLK_RUN_RST	BIT_12S		/* CLK_RUN reset  (YUKON-Lite only) */
-#define CS_CLK_RUN_ENA	BIT_11S		/* CLK_RUN enable (YUKON-Lite only) */
+#define CS_CLK_RUN_HOT	BIT_13S		/* CLK_RUN Hot m. (YUKON-Lite only) */
+#define CS_CLK_RUN_RST	BIT_12S		/* CLK_RUN Reset  (YUKON-Lite only) */
+#define CS_CLK_RUN_ENA	BIT_11S		/* CLK_RUN Enable (YUKON-Lite only) */
 #define CS_VAUX_AVAIL	BIT_10S		/* VAUX available (YUKON only) */
 #define CS_BUS_CLOCK	BIT_9S		/* Bus Clock 0/1 = 33/66 MHz */
 #define CS_BUS_SLOT_SZ	BIT_8S		/* Slot Size 0/1 = 32/64 bit slot */
@@ -812,15 +1081,15 @@
 #define CS_CL_SW_IRQ	BIT_6S		/* Clear IRQ SW Request */
 #define CS_STOP_DONE	BIT_5S		/* Stop Master is finished */
 #define CS_STOP_MAST	BIT_4S		/* Command Bit to stop the master */
-#define CS_MRST_CLR		BIT_3S		/* Clear Master reset	*/
-#define CS_MRST_SET		BIT_2S		/* Set Master reset	*/
-#define CS_RST_CLR		BIT_1S		/* Clear Software reset	*/
-#define CS_RST_SET		BIT_0S		/* Set   Software reset	*/
+#define CS_MRST_CLR		BIT_3S		/* Clear Master Reset */
+#define CS_MRST_SET		BIT_2S		/* Set   Master Reset */
+#define CS_RST_CLR		BIT_1S		/* Clear Software Reset	*/
+#define CS_RST_SET		BIT_0S		/* Set   Software Reset	*/
 
-/*	B0_LED			 8 Bit	LED register */
+/*	B0_LED			 8 Bit	LED register (GENESIS only)*/
 								/* Bit  7.. 2:	reserved */
-#define LED_STAT_ON		BIT_1S		/* Status LED on	*/
-#define LED_STAT_OFF	BIT_0S		/* Status LED off	*/
+#define LED_STAT_ON		BIT_1S		/* Status LED On	*/
+#define LED_STAT_OFF	BIT_0S		/* Status LED Off	*/
 
 /*	B0_POWER_CTRL	 8 Bit	Power Control reg (YUKON only) */
 #define PC_VAUX_ENA		BIT_7		/* Switch VAUX Enable  */
@@ -832,6 +1101,7 @@
 #define PC_VCC_ON		BIT_1       /* Switch VCC On  */
 #define PC_VCC_OFF		BIT_0       /* Switch VCC Off */
 
+/* Yukon and Genesis */
 /*	B0_ISRC			32 bit	Interrupt Source Register */
 /*	B0_IMSK			32 bit	Interrupt Mask Register */
 /*	B0_SP_ISRC		32 bit	Special Interrupt Source Reg */
@@ -877,12 +1147,51 @@
 #define IS_XA2_F		BIT_1		/* Q_XA2 End of Frame */
 #define IS_XA2_C		BIT_0		/* Q_XA2 Encoding Error */
 
+/*						(Yukon-2)			*/
+/*	B0_ISRC			32 bit	Interrupt Source Register */
+/*	B0_IMSK			32 bit	Interrupt Mask Register */
+/*	B0_SP_ISRC		32 bit	Special Interrupt Source Reg */
+/*	B2_IRQM_MSK 	32 bit	IRQ Moderation Mask */
+/*	B0_Y2_SP_ISRC2	32 bit	Special Interrupt Source Reg 2 */
+/*	B0_Y2_SP_ISRC3	32 bit	Special Interrupt Source Reg 3 */
+/*	B0_Y2_SP_EISR	32 bit	Enter ISR Reg */
+/*	B0_Y2_SP_LISR	32 bit	Leave ISR Reg */
+#define Y2_IS_PORT_MASK(Port, Mask)	((Mask) << (Port*8))
+#define Y2_IS_HW_ERR	BIT_31		/* Interrupt HW Error */
+#define Y2_IS_STAT_BMU	BIT_30		/* Status BMU Interrupt */
+#define Y2_IS_ASF		BIT_29		/* ASF subsystem Interrupt */
+							/* Bit 28: reserved */
+#define Y2_IS_POLL_CHK	BIT_27		/* Check IRQ from polling unit */
+#define Y2_IS_TWSI_RDY	BIT_26		/* IRQ on end of TWSI Tx */
+#define Y2_IS_IRQ_SW	BIT_25		/* SW forced IRQ	*/
+#define Y2_IS_TIMINT	BIT_24		/* IRQ from Timer	*/
+							/* Bit 23..16 reserved */
+						/* Link 2 Interrupts */
+#define Y2_IS_IRQ_PHY2	BIT_12      /* Interrupt from PHY 2 */
+#define Y2_IS_IRQ_MAC2	BIT_11      /* Interrupt from MAC 2 */
+#define Y2_IS_CHK_RX2	BIT_10      /* Descriptor error Rx 2 */
+#define Y2_IS_CHK_TXS2	BIT_9       /* Descriptor error TXS 2 */
+#define Y2_IS_CHK_TXA2	BIT_8       /* Descriptor error TXA 2 */
+							/* Bit  7.. 5 reserved */
+						/* Link 1 interrupts */
+#define Y2_IS_IRQ_PHY1	BIT_4       /* Interrupt from PHY 1 */
+#define Y2_IS_IRQ_MAC1	BIT_3       /* Interrupt from MAC 1 */
+#define Y2_IS_CHK_RX1	BIT_2       /* Descriptor error Rx 1 */
+#define Y2_IS_CHK_TXS1	BIT_1       /* Descriptor error TXS 1 */
+#define Y2_IS_CHK_TXA1	BIT_0       /* Descriptor error TXA 1 */
+
+#define Y2_IS_L1_MASK	0x0000001fUL	/* IRQ Mask for port 1 */	
 
+#define Y2_IS_L2_MASK	0x00001f00UL	/* IRQ Mask for port 2 */	
+
+#define Y2_IS_ALL_MSK	0xef001f1fUL	/* All Interrupt bits */
+
+/* Yukon and Genesis */
 /*	B0_HWE_ISRC		32 bit	HW Error Interrupt Src Reg */
 /*	B0_HWE_IMSK		32 bit	HW Error Interrupt Mask Reg */
 /*	B2_IRQM_HWE_MSK	32 bit	IRQ Moderation HW Error Mask */
 #define IS_ERR_MSK		0x00000fffL	/* 		All Error bits */
-								/* Bit 31..14:	reserved */
+							/* Bit 31..14:	reserved */
 #define IS_IRQ_TIST_OV	BIT_13	/* Time Stamp Timer Overflow (YUKON only) */
 #define IS_IRQ_SENSOR	BIT_12	/* IRQ from Sensor (YUKON only) */
 #define IS_IRQ_MST_ERR	BIT_11	/* IRQ master error detected */
@@ -898,6 +1207,43 @@
 #define IS_R1_PAR_ERR	BIT_1	/* Queue R1 Parity Error */
 #define IS_R2_PAR_ERR	BIT_0	/* Queue R2 Parity Error */
 
+						/* Yukon-2 */
+/*	B0_HWE_ISRC		32 bit	HW Error Interrupt Src Reg */
+/*	B0_HWE_IMSK		32 bit	HW Error Interrupt Mask Reg */
+/*	B2_IRQM_HWE_MSK	32 bit	IRQ Moderation HW Error Mask */
+						/* Bit: 31..30 reserved */
+#define Y2_IS_TIST_OV	BIT_29	/* Time Stamp Timer overflow interrupt */
+#define Y2_IS_SENSOR	BIT_28	/* Sensor interrupt */
+#define Y2_IS_MST_ERR	BIT_27	/* Master error interrupt */
+#define Y2_IS_IRQ_STAT	BIT_26	/* Status exception interrupt */
+#define Y2_IS_PCI_EXP	BIT_25	/* PCI-Express interrupt */
+#define Y2_IS_PCI_NEXP	BIT_24	/* PCI-Express error similar to PCI error */
+						/* Bit: 23..14 reserved */
+						/* Link 2 */
+#define Y2_IS_PAR_RD2	BIT_13	/* Read RAM parity error interrupt */
+#define Y2_IS_PAR_WR2	BIT_12	/* Write RAM parity error interrupt */
+#define Y2_IS_PAR_MAC2	BIT_11	/* MAC hardware fault interrupt */
+#define Y2_IS_PAR_RX2	BIT_10	/* Parity Error Rx Queue 2 */
+#define Y2_IS_TCP_TXS2	BIT_9	/* TCP length mismatch sync Tx queue IRQ */
+#define Y2_IS_TCP_TXA2	BIT_8	/* TCP length mismatch async Tx queue IRQ */
+						/* Bit:  9.. 6 reserved */
+						/* Link 1 */
+#define Y2_IS_PAR_RD1	BIT_5	/* Read RAM parity error interrupt */
+#define Y2_IS_PAR_WR1	BIT_4	/* Write RAM parity error interrupt */
+#define Y2_IS_PAR_MAC1	BIT_3	/* MAC hardware fault interrupt */
+#define Y2_IS_PAR_RX1	BIT_2	/* Parity Error Rx Queue 1 */
+#define Y2_IS_TCP_TXS1	BIT_1	/* TCP length mismatch sync Tx queue IRQ */
+#define Y2_IS_TCP_TXA1	BIT_0	/* TCP length mismatch async Tx queue IRQ */
+
+#define Y2_HWE_L1_MASK	(Y2_IS_PAR_RD1 | Y2_IS_PAR_WR1 | Y2_IS_PAR_MAC1 |\
+						 Y2_IS_PAR_RX1 | Y2_IS_TCP_TXS1| Y2_IS_TCP_TXA1)
+#define Y2_HWE_L2_MASK	(Y2_IS_PAR_RD2 | Y2_IS_PAR_WR2 | Y2_IS_PAR_MAC2 |\
+						 Y2_IS_PAR_RX2 | Y2_IS_TCP_TXS2| Y2_IS_TCP_TXA2)
+
+#define Y2_HWE_ALL_MSK	(Y2_IS_TIST_OV | /* Y2_IS_SENSOR | */ Y2_IS_MST_ERR |\
+						 Y2_IS_IRQ_STAT | Y2_IS_PCI_EXP | Y2_IS_PCI_NEXP |\
+						 Y2_HWE_L1_MASK | Y2_HWE_L2_MASK)
+
 /*	B2_CONN_TYP		 8 bit	Connector type */
 /*	B2_PMD_TYP		 8 bit	PMD type */
 /*	Values of connector and PMD type comply to SysKonnect internal std */
@@ -906,19 +1252,64 @@
 #define CFG_CHIP_R_MSK	(0xf<<4)	/* Bit 7.. 4: Chip Revision */
 									/* Bit 3.. 2:	reserved */
 #define CFG_DIS_M2_CLK	BIT_1S		/* Disable Clock for 2nd MAC */
-#define CFG_SNG_MAC		BIT_0S		/* MAC Config: 0=2 MACs / 1=1 MAC*/
+#define CFG_SNG_MAC		BIT_0S		/* MAC Config: 0 = 2 MACs; 1 = 1 MAC */
 
 /*	B2_CHIP_ID		 8 bit 	Chip Identification Number */
 #define CHIP_ID_GENESIS		0x0a	/* Chip ID for GENESIS */
 #define CHIP_ID_YUKON		0xb0	/* Chip ID for YUKON */
 #define CHIP_ID_YUKON_LITE	0xb1	/* Chip ID for YUKON-Lite (Rev. A1-A3) */
 #define CHIP_ID_YUKON_LP	0xb2	/* Chip ID for YUKON-LP */
+#define CHIP_ID_YUKON_XL	0xb3	/* Chip ID for YUKON-2 XL */
+#define CHIP_ID_YUKON_EC	0xb6	/* Chip ID for YUKON-2 EC */
+#define CHIP_ID_YUKON_FE	0xb7	/* Chip ID for YUKON-2 FE */
 
 #define CHIP_REV_YU_LITE_A1	3		/* Chip Rev. for YUKON-Lite A1,A2 */
 #define CHIP_REV_YU_LITE_A3	7		/* Chip Rev. for YUKON-Lite A3 */
 
+#define CHIP_REV_YU_EC_A1	0		/* Chip Rev. for Yukon-EC A1/A0 */
+#define CHIP_REV_YU_EC_A2	1		/* Chip Rev. for Yukon-EC A2 */
+
+/*	B2_Y2_CLK_GATE	 8 bit	Clock Gating (Yukon-2 only) */
+#define Y2_STATUS_LNK2_INAC	BIT_7S	/* Status Link 2 inactiv (0 = activ) */
+#define Y2_CLK_GAT_LNK2_DIS	BIT_6S	/* Disable clock gating Link 2 */
+#define Y2_COR_CLK_LNK2_DIS	BIT_5S	/* Disable Core clock Link 2 */
+#define Y2_PCI_CLK_LNK2_DIS	BIT_4S	/* Disable PCI clock Link 2 */
+#define Y2_STATUS_LNK1_INAC	BIT_3S	/* Status Link 1 inactiv (0 = activ) */
+#define Y2_CLK_GAT_LNK1_DIS	BIT_2S	/* Disable clock gating Link 1 */
+#define Y2_COR_CLK_LNK1_DIS	BIT_1S	/* Disable Core clock Link 1 */
+#define Y2_PCI_CLK_LNK1_DIS	BIT_0S	/* Disable PCI clock Link 1 */
+
+/*	B2_Y2_HW_RES	8 bit 	HW Resources (Yukon-2 only) */
+								/* Bit 7.. 5:	reserved */
+#define CFG_LED_MODE_MSK	(7<<2)	/* Bit  4.. 2:	LED Mode Mask */
+#define CFG_LINK_2_AVAIL	BIT_1S	/* Link 2 available */
+#define CFG_LINK_1_AVAIL	BIT_0S	/* Link 1 available */
+
+#define CFG_LED_MODE(x)		(((x) & CFG_LED_MODE_MSK) >> 2)
+#define CFG_DUAL_MAC_MSK	(CFG_LINK_2_AVAIL | CFG_LINK_1_AVAIL)
+
+#define CFG_LED_SING_ACT_LNK	0	/* Single LED ACT/LNK mode */
+#define CFG_LED_DUAL_ACT_LNK	1	/* Dual   LED ACT/LNK mode */
+
+/*	B2_E_3			 8 bit 	lower 4 bits used for HW self test result */
+#define B2_E3_RES_MASK	0x0f
+
 /*	B2_FAR			32 bit	Flash-Prom Addr Reg/Cnt */
-#define FAR_ADDR		0x1ffffL	/* Bit 16.. 0:	FPROM Address mask */
+#define FAR_ADDR		0x1ffffL	/* Bit 16.. 0:	FPROM Address Mask */
+
+/*	B2_Y2_CLK_CTRL	32 bit	Core Clock Frequency Control Register (Yukon-2/EC) */
+								/* Bit 31..24:	reserved */
+/* Yukon-EC/FE */
+#define Y2_CLK_DIV_VAL_MSK	(0xff<<16)	/* Bit 23..16:	Clock Divisor Value */
+#define Y2_CLK_DIV_VAL(x)	(SHIFT16(x) & Y2_CLK_DIV_VAL_MSK)
+/* Yukon-2 */
+#define Y2_CLK_DIV_VAL2_MSK	(7<<21)		/* Bit 23..21:	Clock Divisor Value */
+#define Y2_CLK_SELECT2_MSK	(0x1f<<16)	/* Bit 20..16:	Clock Select */
+#define Y2_CLK_DIV_VAL_2(x)	(SHIFT21(x) & Y2_CLK_DIV_VAL2_MSK)
+#define Y2_CLK_SEL_VAL_2(x)	(SHIFT16(x) & Y2_CLK_SELECT_MSK)
+								/* Bit 15.. 2:	reserved */
+#define Y2_CLK_DIV_ENA		BIT_1S	/* Enable  Core Clock Division */
+#define Y2_CLK_DIV_DIS		BIT_0S	/* Disable Core Clock Division */
 
 /*	B2_LD_CTRL		 8 bit	EPROM loader control register */
 /*	Bits are currently reserved */
@@ -958,9 +1349,6 @@
 #define DPT_START		BIT_1S	/* Start Descriptor Poll Timer */
 #define DPT_STOP		BIT_0S	/* Stop  Descriptor Poll Timer */
 
-/*	B2_E_3			 8 bit 	lower 4 bits used for HW self test result */
-#define B2_E3_RES_MASK	0x0f
-
 /*	B2_TST_CTRL1	 8 bit	Test Control Register 1 */
 #define TST_FRC_DPERR_MR	BIT_7S	/* force DATAPERR on MST RD */
 #define TST_FRC_DPERR_MW	BIT_6S	/* force DATAPERR on MST WR */
@@ -980,7 +1368,7 @@
 #define TST_FRC_APERR_2M64	BIT_0S	/* AddrPERR on 2. phase */
 
 /*	B2_GP_IO		32 bit	General Purpose I/O Register */
-							/* Bit 31..26:	reserved */
+						/* Bit 31..26:	reserved */
 #define GP_DIR_9	BIT_25	/* IO_9 direct, 0=In/1=Out */
 #define GP_DIR_8	BIT_24	/* IO_8 direct, 0=In/1=Out */
 #define GP_DIR_7	BIT_23	/* IO_7 direct, 0=In/1=Out */
@@ -1030,10 +1418,8 @@
 #define I2C_DATA		BIT_1S		/* I2C Data Port	*/
 #define I2C_CLK			BIT_0S		/* I2C Clock Port	*/
 
-/*
- * I2C Address
- */
-#define I2C_SENS_ADDR	LM80_ADDR	/* I2C Sensor Address, (Volt and Temp)*/
+/* I2C Address */
+#define I2C_SENS_ADDR	LM80_ADDR	/* I2C Sensor Address (Volt and Temp) */
 
 
 /*	B2_BSC_CTRL		 8 bit	Blink Source Counter Control */
@@ -1050,16 +1436,20 @@
 #define BSC_T_OFF	BIT_1S		/* Test mode off */
 #define BSC_T_STEP	BIT_0S		/* Test step */
 
+/*	Y2_PEX_PHY_ADDR/DATA		PEX PHY address and data reg  (Yukon-2 only) */
+#define PEX_RD_ACCESS	BIT_31	/* Access Mode Read = 1, Write = 0 */
+#define PEX_DB_ACCESS	BIT_30	/* Access to debug register */
+
 
 /*	B3_RAM_ADDR		32 bit	RAM Address, to read or write */
 					/* Bit 31..19:	reserved */
 #define RAM_ADR_RAN	0x0007ffffL	/* Bit 18.. 0:	RAM Address Range */
 
 /* RAM Interface Registers */
-/*	B3_RI_CTRL		16 bit	RAM Iface Control Register */
+/*	B3_RI_CTRL		16 bit	RAM Interface Control Register */
 								/* Bit 15..10:	reserved */
-#define RI_CLR_RD_PERR	BIT_9S	/* Clear IRQ RAM Read Parity Err */
-#define RI_CLR_WR_PERR	BIT_8S	/* Clear IRQ RAM Write Parity Err*/
+#define RI_CLR_RD_PERR	BIT_9S	/* Clear IRQ RAM Read  Parity Err */
+#define RI_CLR_WR_PERR	BIT_8S	/* Clear IRQ RAM Write Parity Err */
 								/* Bit	7.. 2:	reserved */
 #define RI_RST_CLR		BIT_1S	/* Clear RAM Interface Reset */
 #define RI_RST_SET		BIT_0S	/* Set   RAM Interface Reset */
@@ -1169,7 +1559,7 @@
 								/* Bit 31..16:	reserved */
 #define BC_MAX			0xffff	/* Bit 15.. 0:	Byte counter */
 
-/* BMU Control Status Registers */
+/* BMU Control / Status Registers	(Yukon and Genesis) */
 /*	B0_R1_CSR		32 bit	BMU Ctrl/Stat Rx Queue 1 */
 /*	B0_R2_CSR		32 bit	BMU Ctrl/Stat Rx Queue 2 */
 /*	B0_XA1_CSR		32 bit	BMU Ctrl/Stat Sync Tx Queue 1 */
@@ -1210,6 +1600,42 @@
 						CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\
 						CSR_TRANS_RUN)
 
+/* Rx BMU Control / Status Registers (Yukon-2) */
+#define BMU_IDLE			BIT_31	/* BMU Idle State */
+#define BMU_RX_TCP_PKT		BIT_30	/* Rx TCP Packet (when RSS Hash enabled) */
+#define BMU_RX_IP_PKT		BIT_29	/* Rx IP  Packet (when RSS Hash enabled) */
+								/* Bit 28..16:	reserved */
+#define BMU_ENA_RX_RSS_HASH	BIT_15	/* Enable  Rx RSS Hash */
+#define BMU_DIS_RX_RSS_HASH	BIT_14	/* Disable Rx RSS Hash */
+#define BMU_ENA_RX_CHKSUM	BIT_13	/* Enable  Rx TCP/IP Checksum Check */
+#define BMU_DIS_RX_CHKSUM	BIT_12	/* Disable Rx TCP/IP Checksum Check */
+#define BMU_CLR_IRQ_PAR		BIT_11	/* Clear IRQ on Parity errors (Rx) */
+#define BMU_CLR_IRQ_TCP		BIT_11	/* Clear IRQ on TCP segmen. error (Tx) */
+									
+#define BMU_CLR_IRQ_CHK		BIT_10	/* Clear IRQ Check */
+#define BMU_STOP			BIT_9   /* Stop  Rx/Tx Queue */
+#define BMU_START			BIT_8	/* Start Rx/Tx Queue */
+#define BMU_FIFO_OP_ON		BIT_7	/* FIFO Operational On */
+#define BMU_FIFO_OP_OFF 	BIT_6	/* FIFO Operational Off */
+#define BMU_FIFO_ENA		BIT_5	/* Enable FIFO */
+#define BMU_FIFO_RST		BIT_4	/* Reset  FIFO */
+#define BMU_OP_ON			BIT_3	/* BMU Operational On */
+#define BMU_OP_OFF			BIT_2	/* BMU Operational Off */
+#define BMU_RST_CLR			BIT_1	/* Clear BMU Reset (Enable) */
+#define BMU_RST_SET			BIT_0	/* Set   BMU Reset */
+
+#define BMU_CLR_RESET		(BMU_FIFO_RST | BMU_OP_OFF | BMU_RST_CLR)
+#define BMU_OPER_INIT		(BMU_CLR_IRQ_PAR | BMU_CLR_IRQ_CHK | BMU_START | \
+							BMU_FIFO_ENA | BMU_OP_ON)
+							
+/* Tx BMU Control / Status Registers (Yukon-2) */
+								/* Bit 31: same as for Rx */
+								/* Bit 30..14:	reserved */
+#define BMU_TX_IPIDINCR_ON	BIT_13	/* Enable  IP ID Increment */
+#define BMU_TX_IPIDINCR_OFF	BIT_12	/* Disable IP ID Increment */
+#define BMU_TX_CLR_IRQ_TCP	BIT_11	/* Clear IRQ on TCP segm. length mism. */
+								/* Bit 10..0: same as for Rx */
+
 /*	Q_F				32 bit	Flag Register */
 									/* Bit 31..28:	reserved */
 #define F_ALM_FULL		BIT_27		/* Rx FIFO: almost full */
@@ -1258,6 +1684,13 @@
 								/* Bit  3:	reserved */
 #define T3_VRAM_MSK		7		/* Bit  2.. 0:	Virtual RAM Buffer Address */
 
+/* Queue Prefetch Unit Offsets, use Y2_PREF_Q_ADDR() to address (Yukon-2 only)*/
+/* PREF_UNIT_CTRL_REG	32 bit	Prefetch Control register */
+#define PREF_UNIT_OP_ON		BIT_3	/* prefetch unit operational */
+#define PREF_UNIT_OP_OFF	BIT_2	/* prefetch unit not operational */
+#define PREF_UNIT_RST_CLR	BIT_1	/* Clear Prefetch Unit Reset */
+#define PREF_UNIT_RST_SET	BIT_0	/* Set   Prefetch Unit Reset */
+
 /* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */
 /*	RB_START		32 bit	RAM Buffer Start Address */
 /*	RB_END			32 bit	RAM Buffer End Address */
@@ -1273,24 +1706,24 @@
 #define RB_MSK	0x0007ffff	/* Bit 18.. 0:	RAM Buffer Pointer Bits */
 
 /*	RB_TST2			 8 bit	RAM Buffer Test Register 2 */
-								/* Bit 7.. 4:	reserved */
-#define RB_PC_DEC		BIT_3S	/* Packet Counter Decrem */
+							/* Bit 7.. 4:	reserved */
+#define RB_PC_DEC		BIT_3S	/* Packet Counter Decrement */
 #define RB_PC_T_ON		BIT_2S	/* Packet Counter Test On */
-#define RB_PC_T_OFF		BIT_1S	/* Packet Counter Tst Off */
-#define RB_PC_INC		BIT_0S	/* Packet Counter Increm */
+#define RB_PC_T_OFF		BIT_1S	/* Packet Counter Test Off */
+#define RB_PC_INC		BIT_0S	/* Packet Counter Increment */
 
 /*	RB_TST1			 8 bit	RAM Buffer Test Register 1 */
 							/* Bit 7:	reserved */
 #define RB_WP_T_ON		BIT_6S	/* Write Pointer Test On */
 #define RB_WP_T_OFF		BIT_5S	/* Write Pointer Test Off */
-#define RB_WP_INC		BIT_4S	/* Write Pointer Increm */
+#define RB_WP_INC		BIT_4S	/* Write Pointer Increment */
 								/* Bit 3:	reserved */
 #define RB_RP_T_ON		BIT_2S	/* Read Pointer Test On */
 #define RB_RP_T_OFF		BIT_1S	/* Read Pointer Test Off */
-#define RB_RP_DEC		BIT_0S	/* Read Pointer Decrement */
+#define RB_RP_INC		BIT_0S	/* Read Pointer Increment */
 
 /*	RB_CTRL			 8 bit	RAM Buffer Control Register */
-								/* Bit 7.. 6:	reserved */
+							/* Bit 7.. 6:	reserved */
 #define RB_ENA_STFWD	BIT_5S	/* Enable  Store & Forward */
 #define RB_DIS_STFWD	BIT_4S	/* Disable Store & Forward */
 #define RB_ENA_OP_MD	BIT_3S	/* Enable  Operation Mode */
@@ -1298,6 +1731,21 @@
 #define RB_RST_CLR		BIT_1S	/* Clear RAM Buf STM Reset */
 #define RB_RST_SET		BIT_0S	/* Set   RAM Buf STM Reset */
 
+/* Yukon-2 */
+							/* Bit 31..20:	reserved */
+#define RB_CNT_DOWN		BIT_19	/* Packet Counter Decrement */
+#define RB_CNT_TST_ON	BIT_18  /* Packet Counter Test On */
+#define RB_CNT_TST_OFF	BIT_17	/* Packet Counter Test Off */
+#define RB_CNT_UP		BIT_16	/* Packet Counter Increment */
+							/* Bit 15:	reserved */
+#define RB_WP_TST_ON	BIT_14  /* Write Pointer Test On */
+#define RB_WP_TST_OFF	BIT_13	/* Write Pointer Test Off */
+#define RB_WP_UP		BIT_12	/* Write Pointer Increment  */
+							/* Bit 11:	reserved */
+#define RB_RP_TST_ON	BIT_10  /* Read Pointer Test On */
+#define RB_RP_TST_OFF	BIT_9	/* Read Pointer Test Off */
+#define RB_RP_UP		BIT_8	/* Read Pointer Increment */
+
 
 /* Receive and Transmit MAC FIFO Registers (GENESIS only) */
 
@@ -1370,7 +1818,7 @@
 					/* Bit 7:	reserved */
 #define MFF_WP_T_ON		BIT_6S	/* Write Pointer Test On */
 #define MFF_WP_T_OFF	BIT_5S	/* Write Pointer Test Off */
-#define MFF_WP_INC		BIT_4S	/* Write Pointer Increm */
+#define MFF_WP_INC		BIT_4S	/* Write Pointer Increment */
 							/* Bit 3:	reserved */
 #define MFF_RP_T_ON		BIT_2S	/* Read Pointer Test On */
 #define MFF_RP_T_OFF	BIT_1S	/* Read Pointer Test Off */
@@ -1389,12 +1837,16 @@
 
 /*	RX_LED_CTRL		 8 bit	Receive LED Cnt Control Reg */
 /*	TX_LED_CTRL		 8 bit	Transmit LED Cnt Control Reg */
+							/* Bit 7.. 3:	reserved */
+#define LED_START		BIT_2S	/* Start Counter */
+#define LED_STOP		BIT_1S	/* Stop Counter */
+#define LED_STATE		BIT_0S	/* Rx/Tx: LED State, 1=LED On */
+
 /*	LNK_SYNC_CTRL	 8 bit	Link Sync Cnt Control Register */
 							/* Bit 7.. 3:	reserved */
-#define LED_START		BIT_2S	/* Start Timer */
-#define LED_STOP		BIT_1S	/* Stop Timer */
-#define LED_STATE		BIT_0S	/* Rx/Tx: LED State, 1=LED on */
-#define LED_CLR_IRQ		BIT_0S	/* Lnk: 	Clear Link IRQ */
+#define LNK_START		BIT_2S	/* Start Counter */
+#define LNK_STOP		BIT_1S	/* Stop Counter */
+#define LNK_CLR_IRQ		BIT_0S	/* Clear Link IRQ */
 
 /*	RX_LED_TST		 8 bit	Receive LED Cnt Test Register */
 /*	TX_LED_TST		 8 bit	Transmit LED Cnt Test Register */
@@ -1405,13 +1857,13 @@
 #define LED_T_STEP		BIT_0S	/* LED Counter Step */
 
 /*	LNK_LED_REG	 	 8 bit	Link LED Register */
-								/* Bit 7.. 6:	reserved */
+							/* Bit 7.. 6:	reserved */
 #define LED_BLK_ON		BIT_5S	/* Link LED Blinking On */
 #define LED_BLK_OFF		BIT_4S	/* Link LED Blinking Off */
 #define LED_SYNC_ON		BIT_3S	/* Use Sync Wire to switch LED */
 #define LED_SYNC_OFF	BIT_2S	/* Disable Sync Wire Input */
-#define LED_ON			BIT_1S	/* switch LED on */
-#define LED_OFF			BIT_0S	/* switch LED off */
+#define LED_ON			BIT_1S	/* Switch LED On */
+#define LED_OFF			BIT_0S	/* Switch LED Off */
 
 /*	Receive and Transmit GMAC FIFO Registers (YUKON only) */
 
@@ -1431,60 +1883,111 @@
 /*	TX_GMF_RLEV		32 bit 	Tx GMAC FIFO Read Level */
 
 /*	RX_GMF_CTRL_T	32 bit	Rx GMAC FIFO Control/Test */
-						/* Bits 31..15:	reserved */
-#define GMF_WP_TST_ON	BIT_14		/* Write Pointer Test On */
-#define GMF_WP_TST_OFF	BIT_13		/* Write Pointer Test Off */
-#define GMF_WP_STEP		BIT_12		/* Write Pointer Step/Increment */
+						/* Bit 31..28 reserved */
+#define RX_TRUNC_ON		BIT_27  /* enable  packet truncation */
+#define RX_TRUNC_OFF	BIT_26	/* disable packet truncation */
+#define RX_VLAN_STRIP_ON	BIT_25	/* enable  VLAN stripping */
+#define RX_VLAN_STRIP_OFF	BIT_24	/* disable VLAN stripping */
+						/* Bit 23..15 reserved */
+#define GMF_WP_TST_ON	BIT_14	/* Write Pointer Test On */
+#define GMF_WP_TST_OFF	BIT_13	/* Write Pointer Test Off */
+#define GMF_WP_STEP		BIT_12	/* Write Pointer Step/Increment */
 						/* Bit 11:	reserved */
-#define GMF_RP_TST_ON	BIT_10		/* Read Pointer Test On */
-#define GMF_RP_TST_OFF	BIT_9		/* Read Pointer Test Off */
-#define GMF_RP_STEP		BIT_8		/* Read Pointer Step/Increment */
-#define GMF_RX_F_FL_ON	BIT_7		/* Rx FIFO Flush Mode On */
-#define GMF_RX_F_FL_OFF	BIT_6		/* Rx FIFO Flush Mode Off */
-#define GMF_CLI_RX_FO	BIT_5		/* Clear IRQ Rx FIFO Overrun */
-#define GMF_CLI_RX_FC	BIT_4		/* Clear IRQ Rx Frame Complete */
-#define GMF_OPER_ON		BIT_3		/* Operational Mode On */
-#define GMF_OPER_OFF	BIT_2		/* Operational Mode Off */
-#define GMF_RST_CLR		BIT_1		/* Clear GMAC FIFO Reset */
-#define GMF_RST_SET		BIT_0		/* Set   GMAC FIFO Reset */
-
-/*	TX_GMF_CTRL_T	32 bit	Tx GMAC FIFO Control/Test */
-						/* Bits 31..19:	reserved */
-#define GMF_WSP_TST_ON	BIT_18		/* Write Shadow Pointer Test On */
-#define GMF_WSP_TST_OFF	BIT_17		/* Write Shadow Pointer Test Off */
-#define GMF_WSP_STEP	BIT_16		/* Write Shadow Pointer Step/Increment */
-						/* Bits 15..7: same as for RX_GMF_CTRL_T */
-#define GMF_CLI_TX_FU	BIT_6		/* Clear IRQ Tx FIFO Underrun */
-#define GMF_CLI_TX_FC	BIT_5		/* Clear IRQ Tx Frame Complete */
-#define GMF_CLI_TX_PE	BIT_4		/* Clear IRQ Tx Parity Error */
+#define GMF_RP_TST_ON	BIT_10	/* Read Pointer Test On */
+#define GMF_RP_TST_OFF	BIT_9	/* Read Pointer Test Off */
+#define GMF_RP_STEP		BIT_8	/* Read Pointer Step/Increment */
+#define GMF_RX_F_FL_ON	BIT_7	/* Rx FIFO Flush Mode On */
+#define GMF_RX_F_FL_OFF	BIT_6	/* Rx FIFO Flush Mode Off */
+#define GMF_CLI_RX_FO	BIT_5	/* Clear IRQ Rx FIFO Overrun */
+#define GMF_CLI_RX_FC	BIT_4	/* Clear IRQ Rx Frame Complete */
+#define GMF_OPER_ON		BIT_3	/* Operational Mode On */
+#define GMF_OPER_OFF	BIT_2	/* Operational Mode Off */
+#define GMF_RST_CLR		BIT_1	/* Clear GMAC FIFO Reset */
+#define GMF_RST_SET		BIT_0	/* Set   GMAC FIFO Reset */
+
+/*	TX_GMF_CTRL_T	32 bit	Tx GMAC FIFO Control/Test (YUKON and Yukon-2) */
+						/* Bits 31..26: reserved */
+#define TX_VLAN_TAG_ON	BIT_25	/* enable  VLAN tagging */
+#define TX_VLAN_TAG_OFF	BIT_24	/* disable VLAN tagging */
+						/* Bits 23..19: reserved */
+#define GMF_WSP_TST_ON	BIT_18	/* Write Shadow Pointer Test On */
+#define GMF_WSP_TST_OFF	BIT_17	/* Write Shadow Pointer Test Off */
+#define GMF_WSP_STEP	BIT_16	/* Write Shadow Pointer Step/Increment */
+						/* Bits 15..8: same as for RX_GMF_CTRL_T */
+						/* Bit 7:	reserved */
+#define GMF_CLI_TX_FU	BIT_6	/* Clear IRQ Tx FIFO Underrun */
+#define GMF_CLI_TX_FC	BIT_5	/* Clear IRQ Tx Frame Complete */
+#define GMF_CLI_TX_PE	BIT_4	/* Clear IRQ Tx Parity Error */
 						/* Bits 3..0: same as for RX_GMF_CTRL_T */
 
 #define GMF_RX_CTRL_DEF		(GMF_OPER_ON | GMF_RX_F_FL_ON)
 #define GMF_TX_CTRL_DEF		GMF_OPER_ON
 
+#define RX_GMF_AF_THR_MIN	0x0c	/* Rx GMAC FIFO Almost Full Thresh. min. */
 #define RX_GMF_FL_THR_DEF	0x0a	/* Rx GMAC FIFO Flush Threshold default */
 
 /*	GMAC_TI_ST_CTRL	 8 bit	Time Stamp Timer Ctrl Reg (YUKON only) */
-								/* Bit 7.. 3:	reserved */
-#define GMT_ST_START	BIT_2S		/* Start Time Stamp Timer */
-#define GMT_ST_STOP		BIT_1S		/* Stop  Time Stamp Timer */
-#define GMT_ST_CLR_IRQ	BIT_0S		/* Clear Time Stamp Timer IRQ */
-
+							/* Bit 7.. 3:	reserved */
+#define GMT_ST_START	BIT_2S	/* Start Time Stamp Timer */
+#define GMT_ST_STOP		BIT_1S	/* Stop  Time Stamp Timer */
+#define GMT_ST_CLR_IRQ	BIT_0S	/* Clear Time Stamp Timer IRQ */
+
+/*  POLL_CTRL		32 bit	Polling Unit control register (Yukon-2 only) */
+							/* Bit 31.. 6:	reserved */
+#define PC_CLR_IRQ_CHK	BIT_5	/* Clear IRQ Check */
+#define PC_POLL_RQ		BIT_4	/* Poll Request Start */
+#define PC_POLL_OP_ON	BIT_3	/* Operational Mode On */
+#define PC_POLL_OP_OFF	BIT_2	/* Operational Mode Off */
+#define PC_POLL_RST_CLR	BIT_1	/* Clear Polling Unit Reset (Enable) */
+#define PC_POLL_RST_SET	BIT_0	/* Set   Polling Unit Reset */
+
+
+/* The bit definition of the following registers is still missing! */
+/* B28_Y2_SMB_CONFIG		32 bit	ASF SMBus Config Register */
+/* B28_Y2_SMB_CSD_REG		32 bit	ASF SMB Control/Status/Data */
+/* B28_Y2_ASF_IRQ_V_BASE	32 bit	ASF IRQ Vector Base */
+
+/* B28_Y2_ASF_STAT_CMD		32 bit	ASF Status and Command Reg */
+/* This register is used by the host driver software */
+						/* Bit 31:5	reserved */
+#define Y2_ASF_OS_PRES	BIT_4	/* ASF operationg system present */
+#define Y2_ASF_UC_STATE (BIT_3|BIT_2)	/* ASF uC State */
+#define Y2_ASF_CLK_HALT 0		/* ASF system clock stopped */
+#define Y2_ASF_RESET	BIT_3	/* ASF system in reset state */
+#define Y2_ASF_RUNNING	BIT_2	/* ASF system operational */
+#define Y2_ASF_CLR_HSTI BIT_1	/* Clear ASF IRQ */
+#define Y2_ASF_IRQ		BIT_0	/* Issue an IRQ to ASF system */
+
+/* B28_Y2_ASF_HOST_COM	32 bit	ASF Host Communication Reg */
+/* This register is used by the ASF firmware */
+						/* Bit 31:2	reserved */
+#define Y2_ASF_CLR_ASFI BIT_1	/* Clear host IRQ */
+#define Y2_ASF_HOST_IRQ BIT_0	/* Issue an IRQ to HOST system */
+
+
+/*  STAT_CTRL		32 bit	Status BMU control register (Yukon-2 only) */
+							/* Bit  7.. 5:	reserved */
+#define SC_STAT_CLR_IRQ	BIT_4	/* Status Burst IRQ clear */
+#define SC_STAT_OP_ON	BIT_3	/* Operational Mode On */
+#define SC_STAT_OP_OFF	BIT_2	/* Operational Mode Off */
+#define SC_STAT_RST_CLR	BIT_1	/* Clear Status Unit Reset (Enable) */
+#define SC_STAT_RST_SET	BIT_0	/* Set   Status Unit Reset */
+	
 /*	GMAC_CTRL		32 bit	GMAC Control Reg (YUKON only) */
 						/* Bits 31.. 8:	reserved */
-#define GMC_H_BURST_ON	BIT_7		/* Half Duplex Burst Mode On */
-#define GMC_H_BURST_OFF	BIT_6		/* Half Duplex Burst Mode Off */
-#define GMC_F_LOOPB_ON	BIT_5		/* FIFO Loopback On */
-#define GMC_F_LOOPB_OFF	BIT_4		/* FIFO Loopback Off */
-#define GMC_PAUSE_ON	BIT_3		/* Pause On */
-#define GMC_PAUSE_OFF	BIT_2		/* Pause Off */
-#define GMC_RST_CLR		BIT_1		/* Clear GMAC Reset */
-#define GMC_RST_SET		BIT_0		/* Set   GMAC Reset */
+#define GMC_H_BURST_ON	BIT_7	/* Half Duplex Burst Mode On */
+#define GMC_H_BURST_OFF	BIT_6	/* Half Duplex Burst Mode Off */
+#define GMC_F_LOOPB_ON	BIT_5	/* FIFO Loopback On */
+#define GMC_F_LOOPB_OFF	BIT_4	/* FIFO Loopback Off */
+#define GMC_PAUSE_ON	BIT_3	/* Pause On */
+#define GMC_PAUSE_OFF	BIT_2	/* Pause Off */
+#define GMC_RST_CLR		BIT_1	/* Clear GMAC Reset */
+#define GMC_RST_SET		BIT_0	/* Set   GMAC Reset */
 
 /*	GPHY_CTRL		32 bit	GPHY Control Reg (YUKON only) */
 						/* Bits 31..29:	reserved */
 #define GPC_SEL_BDT		BIT_28	/* Select Bi-Dir. Transfer for MDC/MDIO */
-#define GPC_INT_POL_HI	BIT_27	/* IRQ Polarity is Active HIGH */
+#define GPC_INT_POL		BIT_27	/* IRQ Polarity is Active Low */
 #define GPC_75_OHM		BIT_26	/* Use 75 Ohm Termination instead of 50 */
 #define GPC_DIS_FC		BIT_25	/* Disable Automatic Fiber/Copper Detection */
 #define GPC_DIS_SLEEP	BIT_24	/* Disable Energy Detect */
@@ -1538,14 +2041,14 @@
 
 /*	GMAC_IRQ_SRC	 8 bit	GMAC Interrupt Source Reg (YUKON only) */
 /*	GMAC_IRQ_MSK	 8 bit	GMAC Interrupt Mask   Reg (YUKON only) */
-#define GM_IS_TX_CO_OV	BIT_5		/* Transmit Counter Overflow IRQ */
-#define GM_IS_RX_CO_OV	BIT_4		/* Receive Counter Overflow IRQ */
-#define GM_IS_TX_FF_UR	BIT_3		/* Transmit FIFO Underrun */
-#define GM_IS_TX_COMPL	BIT_2		/* Frame Transmission Complete */
-#define GM_IS_RX_FF_OR	BIT_1		/* Receive FIFO Overrun */
-#define GM_IS_RX_COMPL	BIT_0		/* Frame Reception Complete */
+#define GM_IS_RX_CO_OV	BIT_5S		/* Receive Counter Overflow IRQ */
+#define GM_IS_TX_CO_OV	BIT_4S		/* Transmit Counter Overflow IRQ */
+#define GM_IS_TX_FF_UR	BIT_3S		/* Transmit FIFO Underrun */
+#define GM_IS_TX_COMPL	BIT_2S		/* Frame Transmission Complete */
+#define GM_IS_RX_FF_OR	BIT_1S		/* Receive FIFO Overrun */
+#define GM_IS_RX_COMPL	BIT_0S		/* Frame Reception Complete */
 
-#define GMAC_DEF_MSK	(GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \
+#define GMAC_DEF_MSK	(GM_IS_RX_CO_OV | GM_IS_TX_CO_OV | \
 						GM_IS_TX_FF_UR)
 
 /*	GMAC_LINK_CTRL	16 bit	GMAC Link Control Reg (YUKON only) */
@@ -1577,15 +2080,19 @@
 
 #define WOL_CTL_DEFAULT				\
 	(WOL_CTL_DIS_PME_ON_LINK_CHG |	\
-	WOL_CTL_DIS_PME_ON_PATTERN |	\
-	WOL_CTL_DIS_PME_ON_MAGIC_PKT |	\
-	WOL_CTL_DIS_LINK_CHG_UNIT |		\
-	WOL_CTL_DIS_PATTERN_UNIT |		\
-	WOL_CTL_DIS_MAGIC_PKT_UNIT)
+	 WOL_CTL_DIS_PME_ON_PATTERN |	\
+	 WOL_CTL_DIS_PME_ON_MAGIC_PKT |	\
+	 WOL_CTL_DIS_LINK_CHG_UNIT |	\
+	 WOL_CTL_DIS_PATTERN_UNIT |		\
+	 WOL_CTL_DIS_MAGIC_PKT_UNIT)
 
 /*	WOL_MATCH_CTL	 8 bit	WOL Match Control Reg */
 #define WOL_CTL_PATT_ENA(x)				(BIT_0 << (x))
 
+/*	WOL_PATT_PME	8 bit   WOL PME Match Enable (Yukon-2) */
+#define WOL_PATT_FORCE_PME				BIT_7	/* Generates a PME */
+#define WOL_PATT_MATCH_PME_ALL			0x7f
+
 #define SK_NUM_WOL_PATTERN		7
 #define SK_PATTERN_PER_WORD		4
 #define SK_BITMASK_PATTERN		7
@@ -1604,17 +2111,17 @@
 	SK_U32	TxAdrLo;		/* Physical Tx Buffer Address lower dword */
 	SK_U32	TxAdrHi;		/* Physical Tx Buffer Address upper dword */
 	SK_U32	TxStat;			/* Transmit Frame Status Word */
-#ifndef	SK_USE_REV_DESC
+#ifndef SK_USE_REV_DESC
 	SK_U16	TxTcpOffs;		/* TCP Checksum Calculation Start Value */
 	SK_U16	TxRes1;			/* 16 bit reserved field */
 	SK_U16	TxTcpWp;		/* TCP Checksum Write Position */
 	SK_U16	TxTcpSp;		/* TCP Checksum Calculation Start Position */
-#else	/* SK_USE_REV_DESC */
+#else  /* SK_USE_REV_DESC */
 	SK_U16	TxRes1;			/* 16 bit reserved field */
 	SK_U16	TxTcpOffs;		/* TCP Checksum Calculation Start Value */
 	SK_U16	TxTcpSp;		/* TCP Checksum Calculation Start Position */
 	SK_U16	TxTcpWp;		/* TCP Checksum Write Position */
-#endif	/* SK_USE_REV_DESC */
+#endif /* SK_USE_REV_DESC */
 	SK_U32  TxRes2;			/* 32 bit reserved field */
 } SK_HWTXD;
 
@@ -1626,29 +2133,260 @@
 	SK_U32	RxAdrHi;		/* Physical Rx Buffer Address upper dword */
 	SK_U32	RxStat;			/* Receive Frame Status Word */
 	SK_U32	RxTiSt;			/* Receive Time Stamp (from XMAC on GENESIS) */
-#ifndef	SK_USE_REV_DESC
-	SK_U16	RxTcpSum1;		/* TCP Checksum 1 */
-	SK_U16	RxTcpSum2;		/* TCP Checksum 2 */
+#ifndef SK_USE_REV_DESC
+	SK_U16	RxTcpSum1;		/* Rx TCP Checksum 1 */
+	SK_U16	RxTcpSum2;		/* Rx TCP Checksum 2 */
 	SK_U16	RxTcpSp1;		/* TCP Checksum Calculation Start Position 1 */
 	SK_U16	RxTcpSp2;		/* TCP Checksum Calculation Start Position 2 */
-#else	/* SK_USE_REV_DESC */
-	SK_U16	RxTcpSum2;		/* TCP Checksum 2 */
-	SK_U16	RxTcpSum1;		/* TCP Checksum 1 */
+#else  /* SK_USE_REV_DESC */
+	SK_U16	RxTcpSum2;		/* Rx TCP Checksum 2 */
+	SK_U16	RxTcpSum1;		/* Rx TCP Checksum 1 */
 	SK_U16	RxTcpSp2;		/* TCP Checksum Calculation Start Position 2 */
 	SK_U16	RxTcpSp1;		/* TCP Checksum Calculation Start Position 1 */
-#endif	/* SK_USE_REV_DESC */
+#endif /* SK_USE_REV_DESC */
 } SK_HWRXD;
 
 /*
  * Drivers which use the reverse descriptor feature (PCI_OUR_REG_2)
  * should set the define SK_USE_REV_DESC.
- * Structures are 'normaly' not endianess dependent. But in
- * this case the SK_U16 fields are bound to bit positions inside the
- * descriptor. RxTcpSum1 e.g. must start at bit 0 within the 6.th DWord.
+ * Structures are 'normally' not endianess dependent. But in this case
+ * the SK_U16 fields are bound to bit positions inside the descriptor.
+ * RxTcpSum1 e.g. must start at bit 0 within the 7.th DWord.
  * The bit positions inside a DWord are of course endianess dependent and
- * swaps if the DWord is swapped by the hardware.
+ * swap if the DWord is swapped by the hardware.
  */
 
+/* YUKON-2 descriptors ******************************************************/
+
+typedef struct _TxChksum {
+#ifndef SK_USE_REV_DESC
+	SK_U16	TxTcpWp;		/* TCP Checksum Write Position */
+	SK_U16	TxTcpSp;		/* TCP Checksum Calculation Start Position */
+#else  /* SK_USE_REV_DESC */
+	SK_U16	TxTcpSp;		/* TCP Checksum Calculation Start Position */
+	SK_U16	TxTcpWp;		/* TCP Checksum Write Position */
+#endif /* SK_USE_REV_DESC */
+} SK_HWTXCS;
+
+typedef struct _LargeSend {
+#ifndef SK_USE_REV_DESC
+	SK_U16 Length;		/* Large Send Segment Length */
+	SK_U16 Reserved;	/* reserved */
+#else  /* SK_USE_REV_DESC */
+	SK_U16 Reserved;	/* reserved */
+	SK_U16 Length;		/* Large Send Segment Length */
+#endif /* SK_USE_REV_DESC */
+} SK_HWTXLS;
+
+typedef union u_HwTxBuf {
+	SK_U16	BufLen;		/* Tx Buffer Length */
+	SK_U16	VlanTag;	/* VLAN Tag */
+	SK_U16	InitCsum;	/* Init. Checksum */
+} SK_HWTXBUF;
+
+/* Tx List Element structure */
+typedef struct s_HwLeTx {
+    union {
+        SK_U32	BufAddr;	/* Tx LE Buffer Address high/low */
+        SK_HWTXCS ChkSum;	/* Tx LE TCP Checksum parameters */
+		SK_HWTXLS LargeSend;/* Large Send length */
+    } TxUn;
+#ifndef SK_USE_REV_DESC
+    SK_HWTXBUF	Send;
+	SK_U8	ControlFlags;	/* Tx LE Control field or Lock Number */
+    SK_U8	Opcode;		    /* Tx LE Opcode field */
+#else  /* SK_USE_REV_DESC */
+    SK_U8	Opcode;		    /* Tx LE Opcode field */
+    SK_U8	ControlFlags;	/* Tx LE Control field or Lock Number */
+    SK_HWTXBUF	Send;
+#endif /* SK_USE_REV_DESC */
+} SK_HWLETX;
+
+typedef struct _RxChkSum{
+#ifndef SK_USE_REV_DESC
+	SK_U16	RxTcpSp1;		/* TCP Checksum Calculation Start Position 1 */
+	SK_U16	RxTcpSp2;		/* TCP Checksum Calculation Start Position 2 */
+#else  /* SK_USE_REV_DESC */
+	SK_U16	RxTcpSp2;		/* TCP Checksum Calculation Start Position 2 */
+	SK_U16	RxTcpSp1;		/* TCP Checksum Calculation Start Position 1 */
+#endif /* SK_USE_REV_DESC */
+} SK_HWRXCS;
+
+/* Rx List Element structure */
+typedef struct s_HwLeRx {
+    union {
+        SK_U32	BufAddr;	/* Rx LE Buffer Address high/low */
+        SK_HWRXCS ChkSum;	/* Rx LE TCP Checksum parameters */
+    } RxUn;
+#ifndef SK_USE_REV_DESC
+	SK_U16	BufferLength;	/* Rx LE Buffer Length field */
+    SK_U8	ControlFlags;	/* Rx LE Control field */
+    SK_U8	Opcode;		    /* Rx LE Opcode field */
+#else  /* SK_USE_REV_DESC */
+    SK_U8	Opcode;		    /* Rx LE Opcode field */
+    SK_U8	ControlFlags;	/* Rx LE Control field */
+	SK_U16	BufferLength;	/* Rx LE Buffer Length field */
+#endif /* SK_USE_REV_DESC */
+} SK_HWLERX;
+
+typedef struct s_StRxTCPChkSum {
+#ifndef SK_USE_REV_DESC
+	SK_U16	RxTCPSum1;		/* Rx TCP Checksum 1 */
+	SK_U16	RxTCPSum2;		/* Rx TCP Checksum 2 */
+#else  /* SK_USE_REV_DESC */
+	SK_U16	RxTCPSum2;		/* Rx TCP Checksum 2 */
+	SK_U16	RxTCPSum1;		/* Rx TCP Checksum 1 */
+#endif /* SK_USE_REV_DESC */
+} SK_HWSTCS;
+
+typedef struct s_StRxRssFlags {
+#ifndef SK_USE_REV_DESC
+	SK_U8	FlagField;		/* contains TCP and IP flags */
+	SK_U8	reserved;		/* reserved */
+#else  /* SK_USE_REV_DESC */
+	SK_U8	reserved;		/* reserved */
+	SK_U8	FlagField;		/* contains TCP and IP flags */
+#endif /* SK_USE_REV_DESC */
+} SK_HWSTRSS;
+
+/* bit definition of RSS LE bit 32/33 (SK_HWSTRSS.FlagField) */
+								/* bit 7..2 reserved */
+#define RSS_TCP_FLAG	BIT_1S	/* RSS value related to TCP area */
+#define RSS_IP_FLAG		BIT_0S	/* RSS value related to IP area */
+/* StRxRssValue is valid if at least RSS_IP_FLAG is set. */
+/* For protocol errors or other protocols an empty RSS LE is generated. */
+
+typedef union u_HwStBuf {
+	SK_U16	BufLen;		/* Rx Buffer Length */
+	SK_U16	VlanTag;	/* VLAN Tag */
+	SK_U16	StTxStatHi;	/* Tx Queue Status (high) */
+	SK_HWSTRSS	Rss;	/* Flag Field for TCP and IP protocol */
+} SK_HWSTBUF;
+
+/* Status List Element structure */
+typedef struct s_HwLeSt {
+    union {
+        SK_U32	StRxStatWord;	/* Rx Status Dword */
+        SK_U32	StRxTimeStamp;	/* Rx Timestamp */
+		SK_HWSTCS StRxTCPCSum;	/* Rx TCP Checksum */
+        SK_U32	StTxStatLow;	/* Tx Queue Status (low) */
+		SK_U32	StRxRssValue;	/* Rx RSS value */
+    } StUn;
+#ifndef SK_USE_REV_DESC
+    SK_HWSTBUF	Stat;
+    SK_U8	Link;			/* Status LE Link field */
+    SK_U8	Opcode;		    /* Status LE Opcode field */
+#else  /* SK_USE_REV_DESC */
+    SK_U8	Opcode;		    /* Status LE Opcode field */
+    SK_U8	Link;			/* Status LE Link field */
+    SK_HWSTBUF	Stat;
+#endif /* SK_USE_REV_DESC */
+} SK_HWLEST;
+
+/* Special Action List Element */
+typedef struct s_HwLeSa {
+#ifndef SK_USE_REV_DESC
+	SK_U16	TxAIdxVld;		/* Special Action LE TxA Put Index field */
+	SK_U16	TxSIdxVld;      /* Special Action LE TxS Put Index field */
+	SK_U16	RxIdxVld;       /* Special Action LE Rx Put Index field */
+    SK_U8	Link;			/* Special Action LE Link field */
+    SK_U8	Opcode;		    /* Special Action LE Opcode field */
+#else  /* SK_USE_REV_DESC */
+	SK_U16	TxSIdxVld;      /* Special Action LE TxS Put Index field */
+	SK_U16	TxAIdxVld;		/* Special Action LE TxA Put Index field */
+    SK_U8	Opcode;		    /* Special Action LE Opcode field */
+    SK_U8	Link;			/* Special Action LE Link field */
+	SK_U16	RxIdxVld;       /* Special Action LE Rx Put Index field */
+#endif /* SK_USE_REV_DESC */
+} SK_HWLESA;
+
+/* Common List Element union */
+typedef union u_HwLeTxRxSt {
+    /* transmit list element structure */
+    SK_HWLETX Tx;
+    /* receive list element structure */
+    SK_HWLERX Rx;
+    /* status list element structure */
+    SK_HWLEST St;
+    /* special action list element structure */
+    SK_HWLESA Sa;
+} SK_HWLE;
+
+/* mask and shift value to get tx async queue status for port 1 */
+#define STLE_TXA1_MSKL		0x00000fff
+#define STLE_TXA1_SHIFTL	0
+
+/* mask and shift value to get tx sync queue status for port 1 */
+#define STLE_TXS1_MSKL		0x00fff000
+#define STLE_TXS1_SHIFTL	12
+
+/* mask and shift value to get tx async queue status for port 2 */
+#define STLE_TXA2_MSKL		0xff000000
+#define STLE_TXA2_SHIFTL	24
+#define STLE_TXA2_MSKH		0x000f
+/* this one shifts up */
+#define STLE_TXA2_SHIFTH	8
+
+/* mask and shift value to get tx sync queue status for port 2 */
+#define STLE_TXS2_MSKL		0x00000000
+#define STLE_TXS2_SHIFTL	0
+#define STLE_TXS2_MSKH		0xfff0
+#define STLE_TXS2_SHIFTH	4
+
+/* YUKON-2  bit values */
+#define HW_OWNER        BIT_7
+#define SW_OWNER        0
+
+#define PU_PUTIDX_VALID		BIT_12
+
+/* YUKON-2  Control flags */
+#define UDPTCP          BIT_0S
+#define CALSUM          BIT_1S
+#define WR_SUM          BIT_2S
+#define INIT_SUM        BIT_3S
+#define LOCK_SUM		BIT_4S
+#define INS_VLAN		BIT_5S
+#define FRC_STAT		BIT_6S
+#define EOP				BIT_7S
+
+#define TX_LOCK			BIT_8S
+#define BUF_SEND		BIT_9S
+#define PACKET_SEND		BIT_10S
+
+#define NO_WARNING		BIT_14S
+#define NO_UPDATE		BIT_15S
+
+/* YUKON-2  Rx/Tx opcodes defines */
+#define	OP_TCPWRITE		0x11
+#define	OP_TCPSTART		0x12
+#define	OP_TCPINIT		0x14
+#define	OP_TCPLCK		0x18
+#define OP_TCPCHKSUM    OP_TCPSTART
+#define OP_TCPIS        (OP_TCPINIT | OP_TCPSTART)
+#define OP_TCPLW        (OP_TCPLCK | OP_TCPWRITE)
+#define OP_TCPLSW       (OP_TCPLCK | OP_TCPSTART | OP_TCPWRITE)
+#define OP_TCPLISW      (OP_TCPLCK | OP_TCPINIT | OP_TCPSTART | OP_TCPWRITE)
+#define OP_ADDR64       0x21
+#define OP_VLAN         0x22
+#define OP_ADDR64VLAN   (OP_ADDR64 | OP_VLAN)
+#define OP_LRGLEN       0x24
+#define OP_LRGLENVLAN   (OP_LRGLEN | OP_VLAN)
+#define OP_BUFFER       0x40
+#define OP_PACKET       0x41
+#define OP_LARGESEND    0x43
+
+/* YUKON-2  STATUS opcodes defines */
+#define OP_RXSTAT       0x60
+#define OP_RXTIMESTAMP  0x61
+#define OP_RXVLAN       0x62
+#define OP_RXCHKS		0x64
+#define OP_RXCHKSVLAN	( OP_RXCHKS | OP_RXVLAN )
+#define OP_RXTIMEVLAN   ( OP_RXTIMESTAMP | OP_RXVLAN )
+#define OP_RSS_HASH		0x65
+#define OP_TXINDEXLE    0x68
+
+/* YUKON-2  SPECIAL opcodes defines */
+#define OP_PUTIDX       0x70
 
 /* Descriptor Bit Definition */
 /*	TxCtrl		Transmit Buffer Control Field */
@@ -1683,6 +2421,10 @@
 
 /* macros ********************************************************************/
 
+/* Macro fro accessing the key registers */
+#define RSS_KEY_ADDR(Port, KeyIndex)	\
+		((B4_RSS_KEY | ( ((Port)!=0) ? 0x80 : 0))+(KeyIndex))
+
 /* Receive and Transmit Queues */
 #define Q_R1	0x0000		/* Receive Queue 1 */
 #define Q_R2	0x0080		/* Receive Queue 2 */
@@ -1691,6 +2433,10 @@
 #define Q_XS2	0x0300		/* Synchronous Transmit Queue 2 */
 #define Q_XA2	0x0380		/* Asynchronous Transmit Queue 2 */
 
+#define Q_ASF_R1	0x100	/* ASF Rx Queue 1 */
+#define Q_ASF_R2	0x180	/* ASF Rx Queue 2 */
+#define Q_ASF_T1	0x140	/* ASF Tx Queue 1 */
+#define Q_ASF_T2	0x1c0	/* ASF Tx Queue 2 */
 /*
  *	Macro Q_ADDR()
  *
@@ -1702,11 +2448,27 @@
  *	Offs	Queue register offset.
  *				Values: Q_D, Q_DA_L ... Q_T2, Q_T3
  *
- * usage	SK_IN32(pAC, Q_ADDR(Q_R2, Q_BC), pVal)
+ * usage	SK_IN32(IoC, Q_ADDR(Q_R2, Q_BC), pVal)
  */
 #define Q_ADDR(Queue, Offs)	(B8_Q_REGS + (Queue) + (Offs))
 
 /*
+ *	Macro Y2_PREF_Q_ADDR()
+ *
+ *	Use this macro to access the Prefetch Units of the receive and
+ *	transmit queues of Yukon-2.
+ *
+ * para:	
+ *	Queue	Queue to access.
+ *				Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, Q_XA2,
+ *	Offs	Queue register offset.
+ *				Values: PREF_UNIT_CTRL_REG ... PREF_UNIT_FIFO_LEV_REG
+ *
+ * usage	SK_IN16(IoC, Y2_Q_ADDR(Q_R2, PREF_UNIT_GET_IDX_REG), pVal)
+ */
+#define Y2_PREF_Q_ADDR(Queue, Offs)	(Y2_B8_PREF_REGS + (Queue) + (Offs))
+
+/*
  *	Macro RB_ADDR()
  *
  *	Use this macro to access the RAM Buffer Registers.
@@ -1717,14 +2479,14 @@
  *	Offs	Queue register offset.
  *				Values: RB_START, RB_END ... RB_LEV, RB_CTRL
  *
- * usage	SK_IN32(pAC, RB_ADDR(Q_R2, RB_RP), pVal)
+ * usage	SK_IN32(IoC, RB_ADDR(Q_R2, RB_RP), pVal)
  */
 #define RB_ADDR(Queue, Offs)	(B16_RAM_REGS + (Queue) + (Offs))
 
 
 /* MAC Related Registers */
-#define MAC_1		0	/* belongs to the port near the slot */
-#define MAC_2		1	/* belongs to the port far away from the slot */
+#define MAC_1		0	/* 1st port */
+#define MAC_2		1	/* 2nd port */
 
 /*
  *	Macro MR_ADDR()
@@ -1738,18 +2500,17 @@
  *				Values: RX_MFF_EA, RX_MFF_WP ... LNK_LED_REG,
  *						TX_MFF_EA, TX_MFF_WP ... TX_LED_TST
  *
- * usage	SK_IN32(pAC, MR_ADDR(MAC_1, TX_MFF_EA), pVal)
+ * usage	SK_IN32(IoC, MR_ADDR(MAC_1, TX_MFF_EA), pVal)
  */
 #define MR_ADDR(Mac, Offs)	(((Mac) << 7) + (Offs))
 
-#ifdef	SK_LITTLE_ENDIAN
+#ifdef SK_LITTLE_ENDIAN
 #define XM_WORD_LO	0
 #define XM_WORD_HI	1
-#else	/* !SK_LITTLE_ENDIAN */
+#else  /* !SK_LITTLE_ENDIAN */
 #define XM_WORD_LO	1
 #define XM_WORD_HI	0
-#endif	/* !SK_LITTLE_ENDIAN */
-
+#endif /* !SK_LITTLE_ENDIAN */
 
 /*
  * macros to access the XMAC (GENESIS only)
@@ -2069,12 +2830,14 @@
  *	Use this macro to access PCI config register from the I/O space.
  *
  * para:
+ *	pAC		Pointer to adapter context
  *	Addr	PCI configuration register to access.
  *			Values:	PCI_VENDOR_ID ... PCI_VPD_ADR_REG,
  *
- * usage	SK_IN16(pAC, PCI_C(PCI_VENDOR_ID), pVal);
+ * usage	SK_IN16(IoC, PCI_C(pAC, PCI_VENDOR_ID), pVal);
  */
-#define PCI_C(Addr)	(B7_CFG_SPC + (Addr))	/* PCI Config Space */
+#define PCI_C(p, Addr)		\
+	(((CHIP_ID_YUKON_2(p)) ? Y2_CFG_SPC : B7_CFG_SPC) + (Addr))
 
 /*
  *	Macro SK_HW_ADDR(Base, Addr)
@@ -2086,7 +2849,7 @@
  *	Addr	Address offset
  *
  * usage:	May be used in SK_INxx and SK_OUTxx macros
- *		#define SK_IN8(pAC, Addr, pVal) ...\
+ *		#define SK_IN8(IoC, Addr, pVal) ...\
  *			*pVal = (SK_U8)inp(SK_HW_ADDR(pAC->Hw.Iop, Addr)))
  */
 #ifdef SK_MEM_MAPPED_IO
@@ -2111,6 +2874,21 @@
 #define SK_HWAC_LINK_LED(pAC, IoC, Port, Mode) \
 	SK_OUT8(IoC, MR_ADDR(Port, LNK_LED_REG), Mode);
 
+#define SK_SET_GPIO(IoC, Bit) { \
+	SK_U32	DWord;				\
+	SK_IN32(IoC, B2_GP_IO, &DWord);						\
+	DWord |= ((GP_DIR_0 << (Bit)) | (GP_IO_0 << (Bit)));\
+	SK_OUT32(IoC, B2_GP_IO, DWord);						\
+}
+	
+#define SK_CLR_GPIO(IoC, Bit) { \
+	SK_U32	DWord;				\
+	SK_IN32(IoC, B2_GP_IO, &DWord);		\
+	DWord &= ~(GP_IO_0 << (Bit));		\
+	SK_OUT32(IoC, B2_GP_IO, DWord);		\
+}
+
+#define SK_GE_PCI_FIFO_SIZE		1600	/* PCI FIFO Size */
 
 /* typedefs *******************************************************************/
 
@@ -2122,3 +2900,4 @@
 #endif	/* __cplusplus */
 
 #endif	/* __INC_SKGEHW_H */
+
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skgehwt.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skgehwt.h
--- linux-2.4.29/drivers/net/sk98lin/h/skgehwt.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skgehwt.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skhwt.h
  * Project:	Gigabit Ethernet Adapters, Event Scheduler Module
+ * Version:	$Revision: 2.1 $
+ * Date:	$Date: 2003/10/27 14:16:09 $
  * Purpose:	Defines for the hardware timer functions
  *
  ******************************************************************************/
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skgeinit.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skgeinit.h
--- linux-2.4.29/drivers/net/sk98lin/h/skgeinit.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skgeinit.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skgeinit.h
  * Project:	Gigabit Ethernet Adapters, Common Modules
+ * Version:	$Revision: 2.30 $
+ * Date:	$Date: 2004/08/13 09:12:18 $
  * Purpose:	Structures and prototypes for the GE Init Module
  *
  ******************************************************************************/
@@ -9,13 +11,12 @@
 /******************************************************************************
  *
  *	(C)Copyright 1998-2002 SysKonnect.
- *	(C)Copyright 2002-2003 Marvell.
+ *	(C)Copyright 2002-2004 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
  *	the Free Software Foundation; either version 2 of the License, or
  *	(at your option) any later version.
- *
  *	The information in this file is provided "AS IS" without warranty.
  *
  ******************************************************************************/
@@ -58,14 +59,17 @@
 #define SK_XMIT_DUR		0x002faf08UL	/*  50 ms */
 #define SK_BLK_DUR		0x01dcd650UL	/* 500 ms */
 
-#define SK_DPOLL_DEF	0x00ee6b28UL	/* 250 ms at 62.5 MHz */
+#define SK_DPOLL_DEF	0x00ee6b28UL	/* 250 ms at 62.5 MHz (Genesis) */
+#define SK_DPOLL_DEF_Y2	0x0000124fUL	/*  75 us (Yukon-2) */
 
 #define SK_DPOLL_MAX	0x00ffffffUL	/* 268 ms at 62.5 MHz */
-										/* 215 ms at 78.12 MHz */
+										/* 215 ms at 78.12 MHz (Yukon) */
 
 #define SK_FACT_62		100			/* is given in percent */
 #define SK_FACT_53		 85         /* on GENESIS:	53.12 MHz */
 #define SK_FACT_78		125			/* on YUKON:	78.12 MHz */
+#define SK_FACT_100		161			/* on YUKON-FE:	100 MHz */
+#define SK_FACT_125		202			/* on YUKON-EC:	125 MHz */
 
 /* Timeout values */
 #define SK_MAC_TO_53	72			/* MAC arbiter timeout */
@@ -81,10 +85,16 @@
 #define SK_RB_LLPP_B	(16 * 1024)	/* Lower Level for big Queues */
 
 #ifndef SK_BMU_RX_WM
-#define SK_BMU_RX_WM	0x600		/* BMU Rx Watermark */
+#define SK_BMU_RX_WM		0x600	/* BMU Rx Watermark */
 #endif
+
 #ifndef SK_BMU_TX_WM
-#define SK_BMU_TX_WM	0x600		/* BMU Tx Watermark */
+#define SK_BMU_TX_WM		0x600	/* BMU Tx Watermark */
+#endif
+
+/* performance sensitive drivers should set this define to 0x80 */
+#ifndef SK_BMU_RX_WM_PEX
+#define SK_BMU_RX_WM_PEX	0x600	/* BMU Rx Watermark for PEX */
 #endif
 
 /* XMAC II Rx High Watermark */
@@ -102,31 +112,25 @@
 #define SK_JUMBO_LINK	3		/* driver uses jumbo frames */
 
 /* Minimum RAM Buffer Rx Queue Size */
-#define SK_MIN_RXQ_SIZE	16		/* 16 kB */
+#define SK_MIN_RXQ_SIZE	(((pAC)->GIni.GIYukon2) ? 10 : 16)		/* 10/16 kB */
 
 /* Minimum RAM Buffer Tx Queue Size */
-#define SK_MIN_TXQ_SIZE	16		/* 16 kB */
+#define SK_MIN_TXQ_SIZE	(((pAC)->GIni.GIYukon2) ? 10 : 16)		/* 10/16 kB */
 
-/* Queue Size units */
-#define QZ_UNITS		0x7
+/* Queue Size units (Genesis/Yukon) */
+#define QZ_UNITS		7
 #define QZ_STEP			8
 
+/* Queue Size units (Yukon-2) */
+#define QZ_STEP_Y2		1
+
 /* Percentage of queue size from whole memory */
 /* 80 % for receive */
-#define RAM_QUOTA_RX	80L
+#define RAM_QUOTA_RX	80
 /* 0% for sync transfer */
-#define	RAM_QUOTA_SYNC	0L
+#define	RAM_QUOTA_SYNC	0
 /* the rest (20%) is taken for async transfer */
 
-/* Get the rounded queue size in Bytes in 8k steps */
-#define ROUND_QUEUE_SIZE(SizeInBytes)					\
-	((((unsigned long) (SizeInBytes) + (QZ_STEP*1024L)-1) / 1024) &	\
-	~(QZ_STEP-1))
-
-/* Get the rounded queue size in KBytes in 8k steps */
-#define ROUND_QUEUE_SIZE_KB(Kilobytes) \
-	ROUND_QUEUE_SIZE((Kilobytes) * 1024L)
-
 /* Types of RAM Buffer Queues */
 #define SK_RX_SRAM_Q	1	/* small receive queue */
 #define SK_RX_BRAM_Q	2	/* big receive queue */
@@ -264,10 +268,15 @@
 
 /* PHY power down modes */
 #define PHY_PM_OPERATIONAL_MODE		0	/* PHY operational mode */
-#define PHY_PM_DEEP_SLEEP			1	/* coma mode --> minimal power */
+#define PHY_PM_DEEP_SLEEP			1	/* Coma mode --> minimal power */
 #define PHY_PM_IEEE_POWER_DOWN		2	/* IEEE 22.2.4.1.5 compl. power down */
-#define PHY_PM_ENERGY_DETECT		3	/* energy detect */
-#define PHY_PM_ENERGY_DETECT_PLUS	4	/* energy detect plus */
+#define PHY_PM_ENERGY_DETECT		3	/* Energy detect */
+#define PHY_PM_ENERGY_DETECT_PLUS	4	/* Energy detect plus */
+
+/* PCI Bus Types */
+#define SK_PCI_BUS		0x0001		/* normal PCI bus */
+#define SK_PCIX_BUS		0x0002      /* PCI-X bus */
+#define SK_PEX_BUS		0x0004      /* PCI-Express bus */
 
 /* Default receive frame limit for Workaround of XMAC Errata */
 #define SK_DEF_RX_WA_LIM	SK_CONSTU64(100)
@@ -276,6 +285,7 @@
 #define SK_ACT_LED_BLINK	(1<<0)	/* Active LED blinking */
 #define SK_DUP_LED_NORMAL	(1<<1)	/* Duplex LED normal */
 #define SK_LED_LINK100_ON	(1<<2)	/* Link 100M LED on */
+#define SK_DUAL_LED_ACT_LNK	(1<<3)	/* Dual LED ACT/LNK configuration */
 
 /* Link Partner Status */
 #define SK_LIPA_UNKNOWN	0	/* Link partner is in unknown state */
@@ -288,18 +298,160 @@
 /* Max. Auto-neg. timeouts before link detection in sense mode is reset */
 #define SK_MAX_ANEG_TO	10	/* Max. 10 times the sense mode is reset */
 
+
+/******************************************************************************
+ *
+ * HW_FEATURE() macro
+ */
+
+/* DWORD 0: Features */
+#define HWF_SYNC_TX_SUP			0x00800000UL	/* synch tx queue available */
+#define HWF_SINGLE_PORT_DEVICE	0x00400000UL	/* device has only one LAN IF */
+#define HWF_JUMBO_FRAMES_SUP	0x00200000UL	/* Jumbo frames supported */
+#define HWF_TX_TCP_CSUM_SUP		0x00100000UL	/* TCP tx checksum supported */
+#define HWF_TX_UDP_CSUM_SUP		0x00080000UL	/* UDP tx checksum supported */
+#define HWF_RX_CSUM_SUP			0x00040000UL	/* RX checksum supported */
+#define HWF_TCP_SEGM_SUP		0x00020000UL	/* TCP segmentation supported */
+#define HWF_RSS_HASH_SUP		0x00010000UL	/* RSS Hash supported */
+#define HWF_PORT_VLAN_SUP		0x00008000UL	/* VLAN can be config per port*/
+#define HWF_ROLE_PARAM_SUP		0x00004000UL	/* Role parameter supported */
+#define HWF_LOW_PMODE_SUP		0x00002000UL	/* Low Power Mode supported */
+#define HWF_ENERGIE_DEMO_SUP	0x00001000UL	/* Energie detect mode supp. */
+#define HWF_SPEED1000_SUP		0x00000800UL	/* Line Speed 1000 supported */
+#define HWF_SPEED100_SUP		0x00000400UL	/* Line Speed 100 supported */
+#define HWF_SPEED10_SUP			0x00000200UL	/* Line Speed 10 supported */
+#define HWF_AUTONEGSENSE_SUP	0x00000100UL	/* Autoneg Sense supported */
+#define HWF_PHY_LOOPB_MD_SUP	0x00000080UL	/* PHY loopback mode supp. */
+#define HWF_ASF_SUP				0x00000040UL	/* ASF support possible */
+#define HWF_QS_STEPS_1kB		0x00000020UL	/* The rx/tx queues can be */
+												/* configured in units of 1 kB*/
+#define HWF_OWN_RAM_PER_PORT	0x00000010UL	/* Each port has a separate */
+												/* RAM buffer */
+#define HWF_MIN_LED_IF			0x00000008UL	/* Minimal LED interface */
+												/* (e.g. for Yukon-EC) */
+#define HWF_LIST_ELEMENTS_USED	0x00000004UL	/* HW uses list elements */
+												/* (otherwise desc. are used) */
+#define HWF_GMAC_INSIDE			0x00000002UL	/* device contains GMAC */
+#define HWF_TWSI_PRESENT		0x00000001UL	/* TWSI sensor bus present */
+
+/*-RMV- DWORD 1: Deviations */
+#define HWF_WA_DEV_427			0x10000400UL	/*-RMV- 4.27 (Tx Done Rep) */
+#define HWF_WA_DEV_42			0x10000200UL	/*-RMV- 4.2 (pref unit burst)*/
+#define HWF_WA_DEV_46			0x10000100UL	/*-RMV- 4.6 (CPU crash II) */
+#define HWF_WA_DEV_43_418		0x10000080UL	/*-RMV- 4.3 & 4.18 (PCI unexp */
+												/*-RMV- compl&Stat BMU deadl) */
+#define HWF_WA_DEV_420			0x10000040UL	/*-RMV- 4.20 (Status BMU ov) */
+#define HWF_WA_DEV_423			0x10000020UL	/*-RMV- 4.23 (TCP Segm Hang) */
+#define HWF_WA_DEV_424			0x10000010UL	/*-RMV- 4.24 (MAC reg over wr)*/
+#define HWF_WA_DEV_425			0x10000008UL	/*-RMV- 4.25 (Magic packet */
+												/*-RMV- with odd offset) */
+#define HWF_WA_DEV_428			0x10000004UL	/*-RMV- 4.28 (Poll-U &BigEndi)*/
+#define HWF_WA_FIFO_FLUSH_YLA0	0x10000002UL	/*-RMV- dis Rx GMAC FIFO Flush*/
+												/*-RMV- for Yu-L Rev. A0 only */
+#define HWF_WA_COMA_MODE		0x10000001UL	/*-RMV- Coma Mode WA req */
+
+/* DWORD 2: still unused */
+/* DWORD 3: still unused */
+
+
+/*
+ * HW_FEATURE()	-	returns whether the feature is serviced or not
+ */
+#define HW_FEATURE(pAC, ReqFeature) \
+	(((pAC)->GIni.HwF.Features[((ReqFeature) & 0x30000000UL) >> 28] &\
+	 ((ReqFeature) & 0x0fffffffUL)) != 0)
+
+#define HW_FEAT_LIST	0
+#define HW_DEV_LIST		1
+
+#define SET_HW_FEATURE_MASK(pAC, List, OffMaskValue, OnMaskValue) {	\
+	if ((List) == HW_FEAT_LIST || (List) == HW_DEV_LIST) {			\
+		(pAC)->GIni.HwF.OffMask[List] = (OffMaskValue);				\
+		(pAC)->GIni.HwF.OnMask[List] = (OnMaskValue);				\
+	}																\
+}
+
+/* driver access macros for GIni structure ***********************************/
+
+#define CHIP_ID_YUKON_2(pAC)		((pAC)->GIni.GIYukon2)
+#define HW_SYNC_TX_SUPPORTED(pAC)						\
+		((pAC)->GIni.GIChipId != CHIP_ID_YUKON_EC &&	\
+		 (pAC)->GIni.GIChipId != CHIP_ID_YUKON_FE)
+
+#define HW_MS_TO_TICKS(pAC, MsTime) \
+	((MsTime) * (62500L/100) * (pAC)->GIni.GIHstClkFact)
+
+#if 0
+/* still under construction */
+#define HW_IS_SINGLE_PORT(pAC)		((pAC)->GIni.GIMacsFound == 1)
+#define HW_NUMBER_OF_PORTS(pAC)		((pAC)->GIni.GIMacsFound)
+
+#define HW_TX_UDP_CSUM_SUPPORTED(pAC) \
+	((((pAC)->GIni.GIChipId >= CHIP_ID_YUKON) && ((pAC)->GIni.GIChipRev != 0))
+
+#define HW_DEFAULT_LINESPEED(pAC)	\
+	((!(pAC)->GIni.GIGenesis && (pAC)->GIni.GICopperType) ? \
+	SK_LSPEED_AUTO : SK_LSPEED_1000MBPS)
+
+#define HW_ROLE_PARAM_SUPPORTED(pAC)	((pAC)->GIni.GICopperType)
+
+#define HW_SPEED1000_SUPPORTED(pAC, Port)		\
+	 ((pAC)->GIni.GP[Port].PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS)
+
+#define HW_SPEED100_SUPPORTED(pAC, Port)		\
+	 ((pAC)->GIni.GP[Port].PLinkSpeedCap & SK_LSPEED_CAP_100MBPS)
+
+#define HW_SPEED10_SUPPORTED(pAC, Port)		\
+	 ((pAC)->GIni.GP[Port].PLinkSpeedCap & SK_LSPEED_CAP_10MBPS)
+
+#define HW_AUTONEGSENSE_SUPPORTED(pAC)  ((pAC)->GIni.GP[0].PhyType==SK_PHY_XMAC)
+
+#define HW_FREQ_TO_CARD_TICKS(pAC, AdapterClkSpeed, Freq) \
+	(((AdapterClkSpeed / 100) * (pAC)->GIni.GIHstClkFact) / Freq)
+
+#define HW_IS_LINK_UP(pAC, Port)		((pAC)->GIni.GP[Port].PHWLinkUp)
+#define HW_LINK_SPEED_USED(pAC, Port)	((pAC)->GIni.GP[Port].PLinkSpeedUsed)
+#define HW_RAM_SIZE(pAC)				((pAC)->GIni.GIRamSize)
+
+#define HW_ENA_JUMBO_FRAME_SUPPORT(pAC) (pAC)->GIni.GIPortUsage = SK_JUMBO_LINK
+#define HW_DIS_JUMBO_FRAME_SUPPORT(pAC) (pAC)->GIni.GIPortUsage = ????
+#define HW_PHY_LP_MODE_SUPPORTED(pAC)	(pAC0->???
+#define HW_ASF_ACTIVE(pAC)				???
+#define RAWIO_OUT32(pAC, pAC->RegIrqMask, pAC->GIni.GIValIrqMask)...
+
+/* macro to check whether tx csum is supported */
+#define HW_TX_CSUM_SUPPORTED(pAC)	((pAC)->GIni.GIChipId != CHIP_ID_GENESIS)
+
+BMU_UDP_CHECK : BMU_TCP_CHECK;
+
+/* macro for - Own Bit mirrored to DWORD7 (Yukon LP receive descriptor) */
+#endif /* 0 */
+
+
 /* structures *****************************************************************/
 
 /*
+ * HW Feature structure
+ */
+typedef struct s_HwFeatures {
+	SK_U32	Features[4];	/* Feature list */
+	SK_U32	OffMask[4];		/* Off Mask */
+	SK_U32	OnMask[4];		/* On Mask */
+} SK_HW_FEATURES;
+
+/*
  * MAC specific functions
  */
 typedef struct s_GeMacFunc {
-	int  (*pFnMacUpdateStats)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
-	int  (*pFnMacStatistic)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
-							SK_U16 StatAddr, SK_U32 SK_FAR *pVal);
-	int  (*pFnMacResetCounter)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
-	int  (*pFnMacOverflow)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
-						   SK_U16 IStatus, SK_U64 SK_FAR *pVal);
+	int	(*pFnMacUpdateStats)(SK_AC *, SK_IOC, unsigned int);
+	int	(*pFnMacStatistic)(SK_AC *, SK_IOC, unsigned int, SK_U16, SK_U32 SK_FAR *);
+	int	(*pFnMacResetCounter)(SK_AC *, SK_IOC, unsigned int);
+	int	(*pFnMacOverflow)(SK_AC *, SK_IOC, unsigned int, SK_U16, SK_U64 SK_FAR *);
+	void (*pSkGeSirqIsr)(SK_AC *, SK_IOC, SK_U32);
+#ifdef SK_DIAG
+	int	(*pFnMacPhyRead)(SK_AC *, SK_IOC, int, int, SK_U16 SK_FAR *);
+	int	(*pFnMacPhyWrite)(SK_AC *, SK_IOC, int, int, SK_U16);
+#endif /* SK_DIAG */
 } SK_GEMACFUNC;
 
 /*
@@ -309,7 +461,7 @@
 #ifndef SK_DIAG
 	SK_TIMER	PWaTimer;	/* Workaround Timer */
 	SK_TIMER	HalfDupChkTimer;
-#endif /* SK_DIAG */
+#endif /* !SK_DIAG */
 	SK_U32	PPrevShorts;	/* Previous Short Counter checking */
 	SK_U32	PPrevFcs;		/* Previous FCS Error Counter checking */
 	SK_U64	PPrevRx;		/* Previous RxOk Counter checking */
@@ -365,6 +517,8 @@
 	int		PMacJamLen;		/* MAC Jam length */
 	int		PMacJamIpgVal;	/* MAC Jam IPG */
 	int		PMacJamIpgData;	/* MAC IPG Jam to Data */
+	int		PMacBackOffLim;	/* MAC Back-off Limit */
+	int		PMacDataBlind;	/* MAC Data Blinder */
 	int		PMacIpgData;	/* MAC Data IPG */
 	SK_BOOL PMacLimit4;		/* reset collision counter and backoff algorithm */
 } SK_GEPORT;
@@ -377,18 +531,24 @@
 	int			GIChipId;		/* Chip Identification Number */
 	int			GIChipRev;		/* Chip Revision Number */
 	SK_U8		GIPciHwRev;		/* PCI HW Revision Number */
+	SK_U8		GIPciBus;		/* PCI Bus Type (PCI / PCIX / PEX)*/
 	SK_BOOL		GIGenesis;		/* Genesis adapter ? */
-	SK_BOOL		GIYukon;		/* YUKON-A1/Bx chip */
+	SK_BOOL		GIYukon;		/* YUKON family (1 and 2) */
 	SK_BOOL		GIYukonLite;	/* YUKON-Lite chip */
+	SK_BOOL		GIYukon2;		/* YUKON-2 chip (-XL, -EC or -FE) */
+	SK_U8		GIConTyp;		/* Connector Type */
+	SK_U8		GIPmdTyp;		/* PMD Type */
 	SK_BOOL		GICopperType;	/* Copper Type adapter ? */
 	SK_BOOL		GIPciSlot64;	/* 64-bit PCI Slot */
 	SK_BOOL		GIPciClock66;	/* 66 MHz PCI Clock */
 	SK_BOOL		GIVauxAvail;	/* VAUX available (YUKON) */
 	SK_BOOL		GIYukon32Bit;	/* 32-Bit YUKON adapter */
+	SK_BOOL		GIAsfEnabled;	/* ASF subsystem enabled */
 	SK_U16		GILedBlinkCtrl;	/* LED Blink Control */
 	int			GIMacsFound;	/* Number of MACs found on this adapter */
 	int			GIMacType;		/* MAC Type used on this adapter */
-	int			GIHstClkFact;	/* Host Clock Factor (62.5 / HstClk * 100) */
+	int			GIChipCap;		/* Adapter's Capabilities */
+	int			GIHstClkFact;	/* Host Clock Factor (HstClk / 62.5 * 100) */
 	int			GIPortUsage;	/* Driver Port Usage */
 	int			GILevel;		/* Initialization Level completed */
 	int			GIRamSize;		/* The RAM size of the adapter in kB */
@@ -396,8 +556,10 @@
 	SK_U32		GIRamOffs;		/* RAM Address Offset for addr calculation */
 	SK_U32		GIPollTimerVal;	/* Descr. Poll Timer Init Val (HstClk ticks) */
 	SK_U32		GIValIrqMask;	/* Value for Interrupt Mask */
+	SK_U32		GIValHwIrqMask;	/* Value for Interrupt Mask */
 	SK_U32		GITimeStampCnt;	/* Time Stamp High Counter (YUKON only) */
 	SK_GEPORT	GP[SK_MAX_MACS];/* Port Dependent Information */
+	SK_HW_FEATURES HwF;			/* HW Features struct */
 	SK_GEMACFUNC GIFunc;		/* MAC depedent functions */
 } SK_GEINIT;
 
@@ -462,6 +624,24 @@
 /*
  * public functions in skgeinit.c
  */
+extern void SkGePortVlan(
+	SK_AC	*pAC,
+	SK_IOC	IoC,
+	int		Port,
+	SK_BOOL Enable);
+
+extern void SkGeRxRss(
+	SK_AC	*pAC,
+	SK_IOC	IoC,
+	int		Port,
+	SK_BOOL	Enable);
+
+extern void SkGeRxCsum(
+	SK_AC	*pAC,
+	SK_IOC	IoC,
+	int		Port,
+	SK_BOOL Enable);
+
 extern void	SkGePollRxD(
 	SK_AC	*pAC,
 	SK_IOC	IoC,
@@ -622,28 +802,28 @@
 	int		Port,
 	SK_BOOL	Enable);
 
-extern void	SkXmPhyRead(
+extern int	SkXmPhyRead(
 	SK_AC	*pAC,
 	SK_IOC	IoC,
 	int		Port,
 	int		Addr,
 	SK_U16	SK_FAR *pVal);
 
-extern void	SkXmPhyWrite(
+extern int	SkXmPhyWrite(
 	SK_AC	*pAC,
 	SK_IOC	IoC,
 	int		Port,
 	int		Addr,
 	SK_U16	Val);
 
-extern void	SkGmPhyRead(
+extern int	SkGmPhyRead(
 	SK_AC	*pAC,
 	SK_IOC	IoC,
 	int		Port,
 	int		Addr,
 	SK_U16	SK_FAR *pVal);
 
-extern void	SkGmPhyWrite(
+extern int	SkGmPhyWrite(
 	SK_AC	*pAC,
 	SK_IOC	IoC,
 	int		Port,
@@ -727,6 +907,7 @@
 	int		Port,
 	SK_BOOL	StartTest);
 
+#ifdef SK_PHY_LP_MODE
 extern int SkGmEnterLowPowerMode(
 	SK_AC	*pAC,
 	SK_IOC	IoC,
@@ -737,6 +918,7 @@
 	SK_AC	*pAC,
 	SK_IOC	IoC,
 	int		Port);
+#endif /* SK_PHY_LP_MODE */
 
 #ifdef SK_DIAG
 extern void	SkGePhyRead(
@@ -792,6 +974,9 @@
 extern void	SkGeXmitLED();
 extern void	SkGeInitRamIface();
 extern int	SkGeInitAssignRamToQueues();
+extern void SkGePortVlan();
+extern void SkGeRxCsum();
+extern void SkGeRxRss();
 
 /*
  * public functions in skxmac2.c
@@ -812,11 +997,11 @@
 extern void	SkMacAutoNegLipaPhy();
 extern void SkMacSetRxTxEn();
 extern void	SkXmInitMac();
-extern void	SkXmPhyRead();
-extern void	SkXmPhyWrite();
+extern int	SkXmPhyRead();
+extern int	SkXmPhyWrite();
 extern void	SkGmInitMac();
-extern void	SkGmPhyRead();
-extern void	SkGmPhyWrite();
+extern int	SkGmPhyRead();
+extern int	SkGmPhyWrite();
 extern void	SkXmClrExactAddr();
 extern void	SkXmInitDupMd();
 extern void	SkXmInitPauseMd();
@@ -830,8 +1015,10 @@
 extern int	SkXmOverflowStatus();
 extern int	SkGmOverflowStatus();
 extern int	SkGmCableDiagStatus();
+#ifdef SK_PHY_LP_MODE
 extern int	SkGmEnterLowPowerMode();
 extern int	SkGmLeaveLowPowerMode();
+#endif /* SK_PHY_LP_MODE */
 
 #ifdef SK_DIAG
 extern void	SkGePhyRead();
@@ -842,10 +1029,11 @@
 extern void	SkXmSendCont();
 #endif /* SK_DIAG */
 
-#endif	/* SK_KR_PROTO */
+#endif /* SK_KR_PROTO */
 
 #ifdef __cplusplus
 }
 #endif	/* __cplusplus */
 
 #endif	/* __INC_SKGEINIT_H_ */
+
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skgepnm2.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skgepnm2.h
--- linux-2.4.29/drivers/net/sk98lin/h/skgepnm2.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skgepnm2.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skgepnm2.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:	$Revision: 2.3 $
+ * Date:	$Date: 2004/03/19 16:19:59 $
  * Purpose:	Defines for Private Network Management Interface
  *
  ****************************************************************************/
@@ -68,9 +70,9 @@
 /*
  * VCT internal status values
  */
-#define SK_PNMI_VCT_PENDING	32
-#define SK_PNMI_VCT_TEST_DONE	64
-#define SK_PNMI_VCT_LINK	128
+#define SK_PNMI_VCT_PENDING		0x20
+#define SK_PNMI_VCT_TEST_DONE	0x40
+#define SK_PNMI_VCT_LINK		0x80
 
 /*
  * Internal table definitions
@@ -321,7 +323,7 @@
 						vSt, \
 						pAC->Pnmi.MacUpdatedFlag, \
 						pAC->Pnmi.RlmtUpdatedFlag, \
-						pAC->Pnmi.SirqUpdatedFlag))}}
+						pAC->Pnmi.SirqUpdatedFlag));}}
 
 #else	/* !DEBUG */
 
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skgepnmi.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skgepnmi.h
--- linux-2.4.29/drivers/net/sk98lin/h/skgepnmi.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skgepnmi.h	2005-06-14 02:12:09.000000000 +0100
@@ -1,7 +1,9 @@
 /*****************************************************************************
  *
  * Name:	skgepnmi.h
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
+ * Project:	Gigabit Ethernet Adapters, PNMI-Module
+ * Version:	$Revision: 2.8 $
+ * Date:	$Date: 2004/06/14 06:55:26 $
  * Purpose:	Defines for Private Network Management Interface
  *
  ****************************************************************************/
@@ -29,7 +31,7 @@
 #include "h/sktypes.h"
 #include "h/skerror.h"
 #include "h/sktimer.h"
-#include "h/ski2c.h"
+#include "h/sktwsi.h"
 #include "h/skaddr.h"
 #include "h/skrlmt.h"
 #include "h/skvpd.h"
@@ -39,7 +41,6 @@
  */
 #define SK_PNMI_MDB_VERSION		0x00030001	/* 3.1 */
 
-
 /*
  * Event definitions
  */
@@ -52,16 +53,13 @@
 #define SK_PNMI_EVT_UTILIZATION_TIMER	7	/* Timer event for Utiliza. */
 #define SK_PNMI_EVT_CLEAR_COUNTER		8	/* Clear statistic counters */
 #define SK_PNMI_EVT_XMAC_RESET			9	/* XMAC will be reset */
-
 #define SK_PNMI_EVT_RLMT_PORT_UP		10	/* Port came logically up */
 #define SK_PNMI_EVT_RLMT_PORT_DOWN		11	/* Port went logically down */
 #define SK_PNMI_EVT_RLMT_SEGMENTATION	13	/* Two SP root bridges found */
 #define SK_PNMI_EVT_RLMT_ACTIVE_DOWN	14	/* Port went logically down */
 #define SK_PNMI_EVT_RLMT_ACTIVE_UP		15	/* Port came logically up */
-#define SK_PNMI_EVT_RLMT_SET_NETS		16	/* 1. Parameter is number of nets
-												1 = single net; 2 = dual net */
-#define SK_PNMI_EVT_VCT_RESET		17	/* VCT port reset timer event started with SET. */
-
+#define SK_PNMI_EVT_RLMT_SET_NETS		16	/* Number of nets (1 or 2). */
+#define SK_PNMI_EVT_VCT_RESET			17	/* VCT port reset timer event started with SET. */
 
 /*
  * Return values
@@ -76,7 +74,6 @@
 #define SK_PNMI_ERR_UNKNOWN_NET 	7
 #define SK_PNMI_ERR_NOT_SUPPORTED	10
 
-
 /*
  * Return values of driver reset function SK_DRIVER_RESET() and
  * driver event function SK_DRIVER_EVENT()
@@ -84,19 +81,17 @@
 #define SK_PNMI_ERR_OK			0
 #define SK_PNMI_ERR_FAIL		1
 
-
 /*
  * Return values of driver test function SK_DRIVER_SELFTEST()
  */
 #define SK_PNMI_TST_UNKNOWN		(1 << 0)
-#define SK_PNMI_TST_TRANCEIVER		(1 << 1)
+#define SK_PNMI_TST_TRANCEIVER	(1 << 1)
 #define SK_PNMI_TST_ASIC		(1 << 2)
 #define SK_PNMI_TST_SENSOR		(1 << 3)
-#define SK_PNMI_TST_POWERMGMT		(1 << 4)
+#define SK_PNMI_TST_POWERMGMT	(1 << 4)
 #define SK_PNMI_TST_PCI			(1 << 5)
 #define SK_PNMI_TST_MAC			(1 << 6)
 
-
 /*
  * RLMT specific definitions
  */
@@ -350,6 +345,7 @@
 #define OID_SKGE_VCT_GET				0xFF020200
 #define OID_SKGE_VCT_SET				0xFF020201
 #define OID_SKGE_VCT_STATUS				0xFF020202
+#define OID_SKGE_VCT_CAPABILITIES		0xFF020203
 
 #ifdef SK_DIAG_SUPPORT
 /* Defines for driver DIAG mode. */
@@ -365,22 +361,66 @@
 #define OID_SKGE_PHY_TYPE				0xFF020215
 #define OID_SKGE_PHY_LP_MODE			0xFF020216
 
+/*
+ * Added for new DualNet IM driver V2
+ * these OIDs should later  be in pnmi.h
+ */
+#define OID_SKGE_MAC_COUNT		0xFF020217
+#define OID_SKGE_DUALNET_MODE		0xFF020218
+#define OID_SKGE_SET_TAGHEADER	0xFF020219
+
+#ifdef SK_ASF
+/* Defines for ASF */
+#define OID_SKGE_ASF                    0xFF02021a
+#define OID_SKGE_ASF_STORE_CONFIG       0xFF02021b
+#define OID_SKGE_ASF_ENA                0xFF02021c
+#define OID_SKGE_ASF_RETRANS            0xFF02021d
+#define OID_SKGE_ASF_RETRANS_INT        0xFF02021e
+#define OID_SKGE_ASF_HB_ENA             0xFF02021f
+#define OID_SKGE_ASF_HB_INT             0xFF020220
+#define OID_SKGE_ASF_WD_ENA             0xFF020221
+#define OID_SKGE_ASF_WD_TIME            0xFF020222
+#define OID_SKGE_ASF_IP_SOURCE          0xFF020223
+#define OID_SKGE_ASF_MAC_SOURCE			0xFF020224
+#define OID_SKGE_ASF_IP_DEST            0xFF020225
+#define OID_SKGE_ASF_MAC_DEST           0xFF020226
+#define OID_SKGE_ASF_COMMUNITY_NAME     0xFF020227
+#define OID_SKGE_ASF_RSP_ENA            0xFF020228  
+#define OID_SKGE_ASF_RETRANS_COUNT_MIN	0xFF020229
+#define OID_SKGE_ASF_RETRANS_COUNT_MAX	0xFF02022a
+#define OID_SKGE_ASF_RETRANS_INT_MIN	0xFF02022b
+#define OID_SKGE_ASF_RETRANS_INT_MAX	0xFF02022c
+#define OID_SKGE_ASF_HB_INT_MIN			0xFF02022d
+#define OID_SKGE_ASF_HB_INT_MAX			0xFF02022e
+#define OID_SKGE_ASF_WD_TIME_MIN		0xFF02022f
+#define OID_SKGE_ASF_WD_TIME_MAX		0xFF020230
+#define OID_SKGE_ASF_HB_CAP				0xFF020231
+#define OID_SKGE_ASF_WD_TIMER_RES		0xFF020232
+#define OID_SKGE_ASF_GUID				0xFF020233
+#define OID_SKGE_ASF_KEY_OP				0xFF020234
+#define OID_SKGE_ASF_KEY_ADM			0xFF020235
+#define OID_SKGE_ASF_KEY_GEN			0xFF020236
+#define OID_SKGE_ASF_CAP				0xFF020237
+#define OID_SKGE_ASF_PAR_1				0xFF020238
+#define OID_SKGE_ASF_OVERALL_OID        0xFF020239
+#endif /* SK_ASF */
+
 /* VCT struct to store a backup copy of VCT data after a port reset. */
 typedef struct s_PnmiVct {
 	SK_U8			VctStatus;
-	SK_U8			PCableLen;
-	SK_U32			PMdiPairLen[4];
-	SK_U8			PMdiPairSts[4];
+	SK_U8			CableLen;
+	SK_U32			MdiPairLen[4];
+	SK_U8			MdiPairSts[4];
 } SK_PNMI_VCT;
 
 
 /* VCT status values (to be given to CPA via OID_SKGE_VCT_STATUS). */
-#define SK_PNMI_VCT_NONE		0
-#define SK_PNMI_VCT_OLD_VCT_DATA	1
-#define SK_PNMI_VCT_NEW_VCT_DATA	2
-#define SK_PNMI_VCT_OLD_DSP_DATA	4
-#define SK_PNMI_VCT_NEW_DSP_DATA	8
-#define SK_PNMI_VCT_RUNNING		16
+#define SK_PNMI_VCT_NONE			0x00
+#define SK_PNMI_VCT_OLD_VCT_DATA	0x01
+#define SK_PNMI_VCT_NEW_VCT_DATA	0x02
+#define SK_PNMI_VCT_OLD_DSP_DATA	0x04
+#define SK_PNMI_VCT_NEW_DSP_DATA	0x08
+#define SK_PNMI_VCT_RUNNING			0x10
 
 
 /* VCT cable test status. */
@@ -388,7 +428,12 @@
 #define SK_PNMI_VCT_SHORT_CABLE			1
 #define SK_PNMI_VCT_OPEN_CABLE			2
 #define SK_PNMI_VCT_TEST_FAIL			3
-#define SK_PNMI_VCT_IMPEDANCE_MISMATCH		4
+#define SK_PNMI_VCT_IMPEDANCE_MISMATCH	4
+#define SK_PNMI_VCT_NOT_PRESENT			5
+
+/* VCT capabilities (needed for OID_SKGE_VCT_CAPABILITIES. */
+#define SK_PNMI_VCT_SUPPORTED			1
+#define SK_PNMI_VCT_NOT_SUPPORTED		0
 
 #define	OID_SKGE_TRAP_SEN_WAR_LOW		500
 #define OID_SKGE_TRAP_SEN_WAR_UPP		501
@@ -417,7 +462,6 @@
 #define	SK_SET_FULL_MIB			5
 #define	SK_PRESET_FULL_MIB		6
 
-
 /*
  * Define error numbers and messages for syslog
  */
@@ -450,7 +494,7 @@
 #define SK_PNMI_ERR014		(SK_ERRBASE_PNMI + 14)
 #define SK_PNMI_ERR014MSG	"Vpd: Cannot read VPD keys"
 #define SK_PNMI_ERR015		(SK_ERRBASE_PNMI + 15)
-#define SK_PNMI_ERR015MSG	"Vpd: Internal array for VPD keys to small"
+#define SK_PNMI_ERR015MSG	"Vpd: Internal array for VPD keys too small"
 #define SK_PNMI_ERR016		(SK_ERRBASE_PNMI + 16)
 #define SK_PNMI_ERR016MSG	"Vpd: Key string too long"
 #define SK_PNMI_ERR017		(SK_ERRBASE_PNMI + 17)
@@ -492,9 +536,9 @@
 #define SK_PNMI_ERR036		(SK_ERRBASE_PNMI + 36)
 #define SK_PNMI_ERR036MSG	""
 #define SK_PNMI_ERR037		(SK_ERRBASE_PNMI + 37)
-#define SK_PNMI_ERR037MSG	"Rlmt: SK_RLMT_MODE_CHANGE event return not 0"
+#define SK_PNMI_ERR037MSG	"Rlmt: SK_RLMT_MODE_CHANGE event returned not 0"
 #define SK_PNMI_ERR038		(SK_ERRBASE_PNMI + 38)
-#define SK_PNMI_ERR038MSG	"Rlmt: SK_RLMT_PREFPORT_CHANGE event return not 0"
+#define SK_PNMI_ERR038MSG	"Rlmt: SK_RLMT_PREFPORT_CHANGE event returned not 0"
 #define SK_PNMI_ERR039		(SK_ERRBASE_PNMI + 39)
 #define SK_PNMI_ERR039MSG	"RlmtStat: Unknown OID"
 #define SK_PNMI_ERR040		(SK_ERRBASE_PNMI + 40)
@@ -512,9 +556,9 @@
 #define SK_PNMI_ERR046		(SK_ERRBASE_PNMI + 46)
 #define SK_PNMI_ERR046MSG	"Monitor: Unknown OID"
 #define SK_PNMI_ERR047		(SK_ERRBASE_PNMI + 47)
-#define SK_PNMI_ERR047MSG	"SirqUpdate: Event function returns not 0"
+#define SK_PNMI_ERR047MSG	"SirqUpdate: Event function returned not 0"
 #define SK_PNMI_ERR048		(SK_ERRBASE_PNMI + 48)
-#define SK_PNMI_ERR048MSG	"RlmtUpdate: Event function returns not 0"
+#define SK_PNMI_ERR048MSG	"RlmtUpdate: Event function returned not 0"
 #define SK_PNMI_ERR049		(SK_ERRBASE_PNMI + 49)
 #define SK_PNMI_ERR049MSG	"SkPnmiInit: Invalid size of 'CounterOffset' struct!!"
 #define SK_PNMI_ERR050		(SK_ERRBASE_PNMI + 50)
@@ -824,23 +868,25 @@
 } SK_PNMI_STRUCT_DATA;
 
 #define SK_PNMI_STRUCT_SIZE	(sizeof(SK_PNMI_STRUCT_DATA))
+
+/* The ReturnStatus field must be located before VpdFreeBytes! */
 #define SK_PNMI_MIN_STRUCT_SIZE	((unsigned int)(SK_UPTR)\
 				 &(((SK_PNMI_STRUCT_DATA *)0)->VpdFreeBytes))
-														/*
-														 * ReturnStatus field
-														 * must be located
-														 * before VpdFreeBytes
-														 */
 
 /*
  * Various definitions
  */
+#define SK_PNMI_EVT_TIMER_CHECK		28125000L	/* 28125 ms */
+
+#define SK_PNMI_VCT_TIMER_CHECK		 4000000L	/* 4 sec. */
+
 #define SK_PNMI_MAX_PROTOS		3
 
-#define SK_PNMI_CNT_NO			66	/* Must have the value of the enum
-									 * SK_PNMI_MAX_IDX. Define SK_PNMI_CHECK
-									 * for check while init phase 1
-									 */
+/*
+ * SK_PNMI_CNT_NO must have the value of the enum SK_PNMI_MAX_IDX.
+ * Define SK_PNMI_CHECK to check this during init level SK_INIT_IO.
+ */
+#define SK_PNMI_CNT_NO			66
 
 /*
  * Estimate data structure
@@ -854,14 +900,6 @@
 
 
 /*
- * VCT timer data structure
- */
-typedef struct s_VctTimer {
-	SK_TIMER		VctTimer;
-} SK_PNMI_VCT_TIMER;
-
-
-/*
  * PNMI specific adapter context structure
  */
 typedef struct s_PnmiPort {
@@ -931,9 +969,9 @@
 	unsigned int	TrapQueueEnd;
 	unsigned int	TrapBufPad;
 	unsigned int	TrapUnique;
-	SK_U8		VctStatus[SK_MAX_MACS];
-	SK_PNMI_VCT	VctBackup[SK_MAX_MACS];
-	SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS];
+	SK_U8			VctStatus[SK_MAX_MACS];
+	SK_PNMI_VCT		VctBackup[SK_MAX_MACS];
+	SK_TIMER		VctTimeout[SK_MAX_MACS];
 #ifdef SK_DIAG_SUPPORT
 	SK_U32			DiagAttached;
 #endif /* SK_DIAG_SUPPORT */
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skgesirq.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skgesirq.h
--- linux-2.4.29/drivers/net/sk98lin/h/skgesirq.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skgesirq.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,20 +2,21 @@
  *
  * Name:	skgesirq.h
  * Project:	Gigabit Ethernet Adapters, Common Modules
- * Purpose:	SK specific Gigabit Ethernet special IRQ functions
+ * Version:	$Revision: 2.3 $
+ * Date:	$Date: 2004/05/28 14:42:03 $
+ * Purpose:	Gigabit Ethernet special IRQ functions
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
  *	(C)Copyright 1998-2002 SysKonnect.
- *	(C)Copyright 2002-2003 Marvell.
+ *	(C)Copyright 2002-2004 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
  *	the Free Software Foundation; either version 2 of the License, or
  *	(at your option) any later version.
- *
  *	The information in this file is provided "AS IS" without warranty.
  *
  ******************************************************************************/
@@ -42,10 +43,10 @@
 #define SK_HWEV_SET_SPEED		9	/* Set Link Speed by PNMI */
 #define SK_HWEV_HALFDUP_CHK		10	/* Half Duplex Hangup Workaround */
 
-#define SK_WA_ACT_TIME		(5000000UL)	/* 5 sec */
-#define SK_WA_INA_TIME		(100000UL)	/* 100 msec */
+#define SK_WA_ACT_TIME		1000000UL	/* 1000 msec (1 sec) */
+#define SK_WA_INA_TIME		 100000UL	/*  100 msec */
 
-#define SK_HALFDUP_CHK_TIME	(10000UL)	/* 10 msec */
+#define SK_HALFDUP_CHK_TIME	  10000UL	/*   10 msec */
 
 /*
  * Define the error numbers and messages
@@ -100,10 +101,35 @@
 #define SKERR_SIRQ_E024MSG	"FIFO overflow error"
 #define SKERR_SIRQ_E025		(SKERR_SIRQ_E024+1)
 #define SKERR_SIRQ_E025MSG	"2 Pair Downshift detected"
+#define SKERR_SIRQ_E026		(SKERR_SIRQ_E025+1)
+#define SKERR_SIRQ_E026MSG	"Uncorrectable PCI Express error"
+#define SKERR_SIRQ_E027		(SKERR_SIRQ_E026+1)
+#define SKERR_SIRQ_E027MSG	"PCI express protocol violation error"
+#define SKERR_SIRQ_E028		(SKERR_SIRQ_E027+1)
+#define SKERR_SIRQ_E028MSG	"Parity error on RAM 1 (read)"
+#define SKERR_SIRQ_E029		(SKERR_SIRQ_E028+1)
+#define SKERR_SIRQ_E029MSG	"Parity error on RAM 1 (write)"
+#define SKERR_SIRQ_E030		(SKERR_SIRQ_E029+1)
+#define SKERR_SIRQ_E030MSG	"Parity error on RAM 2 (read)"
+#define SKERR_SIRQ_E031		(SKERR_SIRQ_E030+1)
+#define SKERR_SIRQ_E031MSG	"Parity error on RAM 2 (write)"
+#define SKERR_SIRQ_E032		(SKERR_SIRQ_E031+1)
+#define SKERR_SIRQ_E032MSG	"TCP segmentation error async. queue 1"
+#define SKERR_SIRQ_E033		(SKERR_SIRQ_E032+1)
+#define SKERR_SIRQ_E033MSG	"TCP segmentation error sync. queue 1"
+#define SKERR_SIRQ_E034		(SKERR_SIRQ_E033+1)
+#define SKERR_SIRQ_E034MSG	"TCP segmentation error async. queue 2"
+#define SKERR_SIRQ_E035		(SKERR_SIRQ_E034+1)
+#define SKERR_SIRQ_E035MSG	"TCP segmentation error sync. queue 2"
+#define SKERR_SIRQ_E036		(SKERR_SIRQ_E035+1)
+#define SKERR_SIRQ_E036MSG	"CHECK failure polling unit"
 
 extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus);
 extern int  SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
 extern void SkHWLinkUp(SK_AC *pAC, SK_IOC IoC, int Port);
 extern void SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port);
+extern void SkGeYuSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus);
+extern void SkYuk2SirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus);
 
 #endif	/* _INC_SKGESIRQ_H_ */
+
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skgetwsi.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skgetwsi.h
--- linux-2.4.29/drivers/net/sk98lin/h/skgetwsi.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skgetwsi.h	2005-06-14 02:12:09.000000000 +0100
@@ -0,0 +1,233 @@
+/******************************************************************************
+ *
+ * Name:	skgetwsi.h
+ * Project:	Gigabit Ethernet Adapters, TWSI-Module
+ * Version:	$Revision: 1.2 $
+ * Date:	$Date: 2004/11/17 05:40:48 $
+ * Purpose:	Special defines for TWSI
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *	(C)Copyright 1998-2002 SysKonnect.
+ *	(C)Copyright 2002-2004 Marvell.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2 of the License, or
+ *	(at your option) any later version.
+ *	The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/*
+ * SKGETWSI.H	contains all SK-98xx specific defines for the TWSI handling
+ */
+
+#ifndef _INC_SKGETWSI_H_
+#define _INC_SKGETWSI_H_
+
+/*
+ * Macros to access the B2_I2C_CTRL
+ */
+#define SK_I2C_CTL(IoC, flag, dev, dev_size, reg, burst) \
+	SK_OUT32(IoC, B2_I2C_CTRL,\
+		(flag ? 0x80000000UL : 0x0L) | \
+		(((SK_U32)reg << 16) & I2C_ADDR) | \
+		(((SK_U32)dev << 9) & I2C_DEV_SEL) | \
+		(dev_size & I2C_DEV_SIZE) | \
+		((burst << 4) & I2C_BURST_LEN))
+
+#define SK_I2C_STOP(IoC) {			\
+	SK_U32	I2cCtrl;				\
+	SK_IN32(IoC, B2_I2C_CTRL, &I2cCtrl);		\
+	SK_OUT32(IoC, B2_I2C_CTRL, I2cCtrl | I2C_STOP);	\
+}
+
+#define SK_I2C_GET_CTL(IoC, pI2cCtrl)	SK_IN32(IoC, B2_I2C_CTRL, pI2cCtrl)
+
+/*
+ * Macros to access the TWSI SW Registers
+ */
+#define SK_I2C_SET_BIT(IoC, SetBits) {			\
+	SK_U8	OrgBits;				\
+	SK_IN8(IoC, B2_I2C_SW, &OrgBits);		\
+	SK_OUT8(IoC, B2_I2C_SW, OrgBits | (SK_U8)(SetBits));	\
+}
+
+#define SK_I2C_CLR_BIT(IoC, ClrBits) {			\
+	SK_U8	OrgBits;				\
+	SK_IN8(IoC, B2_I2C_SW, &OrgBits);		\
+	SK_OUT8(IoC, B2_I2C_SW, OrgBits & ~((SK_U8)(ClrBits)));	\
+}
+
+#define SK_I2C_GET_SW(IoC, pI2cSw)	SK_IN8(IoC, B2_I2C_SW, pI2cSw)
+
+/*
+ * define the possible sensor states
+ */
+#define	SK_SEN_IDLE		0	/* Idle: sensor not read */
+#define	SK_SEN_VALUE	1	/* Value Read cycle */
+#define	SK_SEN_VALEXT	2	/* Extended Value Read cycle */
+
+/*
+ * Conversion factor to convert read Voltage sensor to milli Volt
+ * Conversion factor to convert read Temperature sensor to 10th degree Celsius
+ */
+#define	SK_LM80_VT_LSB		22	/* 22mV LSB resolution */
+#define	SK_LM80_TEMP_LSB	10	/* 1 degree LSB resolution */
+#define	SK_LM80_TEMPEXT_LSB	 5	/* 0.5 degree LSB resolution for ext. val. */
+
+/*
+ * formula: counter = (22500*60)/(rpm * divisor * pulses/2)
+ * assuming: 6500rpm, 4 pulses, divisor 1
+ */
+#define SK_LM80_FAN_FAKTOR	((22500L*60)/(1*2))
+
+/*
+ * Define sensor management data
+ * Maximum is reached on Genesis copper dual port and Yukon-64
+ * Board specific maximum is in pAC->I2c.MaxSens
+ */
+#define	SK_MAX_SENSORS	8	/* maximal no. of installed sensors */
+#define	SK_MIN_SENSORS	5	/* minimal no. of installed sensors */
+
+/*
+ * To watch the state machine (SM) use the timer in two ways
+ * instead of one as hitherto
+ */
+#define	SK_TIMER_WATCH_SM		0	/* Watch the SM to finish in a spec. time */
+#define	SK_TIMER_NEW_GAUGING	1	/* Start a new gauging when timer expires */
+
+/*
+ * Defines for the individual thresholds
+ */
+
+#define C_PLUS_15		1.15
+#define C_PLUS_10		1.10
+#define C_PLUS_5		1.05
+#define C_MINUS_5		0.95
+#define C_MINUS_10		0.90
+#define C_MINUS_15		0.85
+
+/* Temperature sensor */
+#define	SK_SEN_TEMP_HIGH_ERR	800	/* Temperature High Err  Threshold */
+#define	SK_SEN_TEMP_HIGH_WARN	700	/* Temperature High Warn Threshold */
+#define	SK_SEN_TEMP_LOW_WARN	100	/* Temperature Low  Warn Threshold */
+#define	SK_SEN_TEMP_LOW_ERR		  0	/* Temperature Low  Err  Threshold */
+
+/* VCC which should be 5 V */
+#define	SK_SEN_PCI_5V_HIGH_ERR		5588	/* Voltage PCI High Err  Threshold */
+#define	SK_SEN_PCI_5V_HIGH_WARN		5346	/* Voltage PCI High Warn Threshold */
+#define	SK_SEN_PCI_5V_LOW_WARN		4664	/* Voltage PCI Low  Warn Threshold */
+#define	SK_SEN_PCI_5V_LOW_ERR		4422	/* Voltage PCI Low  Err  Threshold */
+
+/*
+ * VIO may be 5 V or 3.3 V. Initialization takes two parts:
+ * 1. Initialize lowest lower limit and highest higher limit.
+ * 2. After the first value is read correct the upper or the lower limit to
+ *    the appropriate C constant.
+ *
+ * Warning limits are +-5% of the exepected voltage.
+ * Error limits are +-10% of the expected voltage.
+ */
+
+/* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */
+
+#define	SK_SEN_PCI_IO_5V_HIGH_ERR	5566	/* + 10% V PCI-IO High Err Threshold */
+#define	SK_SEN_PCI_IO_5V_HIGH_WARN	5324	/* +  5% V PCI-IO High Warn Threshold */
+					/*		5000	mVolt */
+#define	SK_SEN_PCI_IO_5V_LOW_WARN	4686	/* -  5% V PCI-IO Low Warn Threshold */
+#define	SK_SEN_PCI_IO_5V_LOW_ERR	4444	/* - 10% V PCI-IO Low Err Threshold */
+
+#define	SK_SEN_PCI_IO_RANGE_LIMITER	4000	/* 4000 mV range delimiter */
+
+/* correction values for the second pass */
+#define	SK_SEN_PCI_IO_3V3_HIGH_ERR	3850	/* + 15% V PCI-IO High Err Threshold */
+#define	SK_SEN_PCI_IO_3V3_HIGH_WARN	3674	/* + 10% V PCI-IO High Warn Threshold */
+					/*		3300	mVolt */
+#define	SK_SEN_PCI_IO_3V3_LOW_WARN	2926	/* - 10% V PCI-IO Low Warn Threshold */
+#define	SK_SEN_PCI_IO_3V3_LOW_ERR	2772	/* - 15% V PCI-IO Low Err  Threshold */
+
+/*
+ * VDD voltage
+ */
+#define	SK_SEN_VDD_HIGH_ERR		3630	/* Voltage ASIC High Err  Threshold */
+#define	SK_SEN_VDD_HIGH_WARN	3476	/* Voltage ASIC High Warn Threshold */
+#define	SK_SEN_VDD_LOW_WARN		3146	/* Voltage ASIC Low  Warn Threshold */
+#define	SK_SEN_VDD_LOW_ERR		2970	/* Voltage ASIC Low  Err  Threshold */
+
+/*
+ * PHY PLL 3V3 voltage
+ */
+#define	SK_SEN_PLL_3V3_HIGH_ERR		3630	/* Voltage PMA High Err  Threshold */
+#define	SK_SEN_PLL_3V3_HIGH_WARN	3476	/* Voltage PMA High Warn Threshold */
+#define	SK_SEN_PLL_3V3_LOW_WARN		3146	/* Voltage PMA Low  Warn Threshold */
+#define	SK_SEN_PLL_3V3_LOW_ERR		2970	/* Voltage PMA Low  Err  Threshold */
+
+/*
+ * VAUX (YUKON only)
+ */
+#define	SK_SEN_VAUX_3V3_VAL		3300	/* Voltage VAUX 3.3 Volt */
+
+#define	SK_SEN_VAUX_3V3_HIGH_ERR	(SK_I32)(SK_SEN_VAUX_3V3_VAL * C_PLUS_10)
+#define	SK_SEN_VAUX_3V3_HIGH_WARN	(SK_I32)(SK_SEN_VAUX_3V3_VAL * C_PLUS_5)
+#define	SK_SEN_VAUX_3V3_LOW_WARN	(SK_I32)(SK_SEN_VAUX_3V3_VAL * C_MINUS_5)
+#define	SK_SEN_VAUX_3V3_LOW_ERR		(SK_I32)(SK_SEN_VAUX_3V3_VAL * C_MINUS_10)
+
+#define	SK_SEN_VAUX_RANGE_LIMITER	1000	/* 1000 mV range delimiter */
+
+/*
+ * PHY 2V5 voltage
+ */
+#define	SK_SEN_PHY_2V5_VAL		2500	/* Voltage PHY 2.5 Volt */
+
+#define	SK_SEN_PHY_2V5_HIGH_ERR		(SK_I32)(SK_SEN_PHY_2V5_VAL * C_PLUS_10)
+#define	SK_SEN_PHY_2V5_HIGH_WARN	(SK_I32)(SK_SEN_PHY_2V5_VAL * C_PLUS_5)
+#define	SK_SEN_PHY_2V5_LOW_WARN		(SK_I32)(SK_SEN_PHY_2V5_VAL * C_MINUS_5)
+#define	SK_SEN_PHY_2V5_LOW_ERR		(SK_I32)(SK_SEN_PHY_2V5_VAL * C_MINUS_10)
+
+/*
+ * ASIC Core 1V5 voltage (YUKON only)
+ */
+#define	SK_SEN_CORE_1V5_VAL		1500	/* Voltage ASIC Core 1.5 Volt */
+
+#define	SK_SEN_CORE_1V5_HIGH_ERR	(SK_I32)(SK_SEN_CORE_1V5_VAL * C_PLUS_10)
+#define	SK_SEN_CORE_1V5_HIGH_WARN	(SK_I32)(SK_SEN_CORE_1V5_VAL * C_PLUS_5)
+#define	SK_SEN_CORE_1V5_LOW_WARN	(SK_I32)(SK_SEN_CORE_1V5_VAL * C_MINUS_5)
+#define	SK_SEN_CORE_1V5_LOW_ERR 	(SK_I32)(SK_SEN_CORE_1V5_VAL * C_MINUS_10)
+
+/*
+ * ASIC Core 1V2 voltage (YUKON-2 only)
+ */
+#define	SK_SEN_CORE_1V2_VAL		1300	/* Voltage ASIC Core 1.3 Volt */
+
+#define	SK_SEN_CORE_1V2_HIGH_ERR	(SK_I32)(SK_SEN_CORE_1V2_VAL * C_PLUS_15)
+#define	SK_SEN_CORE_1V2_HIGH_WARN	(SK_I32)(SK_SEN_CORE_1V2_VAL * C_PLUS_10)
+#define	SK_SEN_CORE_1V2_LOW_WARN	(SK_I32)(SK_SEN_CORE_1V2_VAL * C_MINUS_5)
+#define	SK_SEN_CORE_1V2_LOW_ERR 	(SK_I32)(SK_SEN_CORE_1V2_VAL * C_MINUS_10)
+
+/*
+ * FAN 1 speed
+ */
+/* assuming: 6500rpm +-15%, 4 pulses,
+ * warning at:	80 %
+ * error at:	70 %
+ * no upper limit
+ */
+#define	SK_SEN_FAN_HIGH_ERR		20000	/* FAN Speed High Err Threshold */
+#define	SK_SEN_FAN_HIGH_WARN	20000	/* FAN Speed High Warn Threshold */
+#define	SK_SEN_FAN_LOW_WARN		 5200	/* FAN Speed Low Warn Threshold */
+#define	SK_SEN_FAN_LOW_ERR		 4550	/* FAN Speed Low Err Threshold */
+
+/*
+ * Some Voltages need dynamic thresholds
+ */
+#define	SK_SEN_DYN_INIT_NONE		 0  /* No dynamic init of thresholds */
+#define	SK_SEN_DYN_INIT_PCI_IO		10  /* Init PCI-IO with new thresholds */
+#define	SK_SEN_DYN_INIT_VAUX		11  /* Init VAUX with new thresholds */
+
+extern	int SkLm80ReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
+#endif	/* n_INC_SKGETWSI_H */
+
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skqueue.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skqueue.h
--- linux-2.4.29/drivers/net/sk98lin/h/skqueue.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skqueue.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skqueue.h
  * Project:	Gigabit Ethernet Adapters, Event Scheduler Module
+ * Version:	$Revision: 2.3 $
+ * Date:	$Date: 2004/05/14 13:39:15 $
  * Purpose:	Defines for the Event queue
  *
  ******************************************************************************/
@@ -20,6 +22,10 @@
  *
  ******************************************************************************/
 
+/*
+ * SKQUEUE.H	contains all defines and types for the event queue
+ */
+
 #ifndef _SKQUEUE_H_
 #define _SKQUEUE_H_
 
@@ -39,6 +45,9 @@
 #define	SKGE_RSF	11	/* RSF Aggregation Event Class */
 #define	SKGE_MARKER	12	/* MARKER Aggregation Event Class */
 #define	SKGE_FD		13	/* FD Distributor Event Class */
+#ifdef SK_ASF
+#define	SKGE_ASF	14	/* ASF Event Class */
+#endif
 
 /*
  * define event queue as circular buffer
@@ -84,5 +93,11 @@
 #define	SKERR_Q_E001MSG	"Event queue overflow"
 #define	SKERR_Q_E002	(SKERR_Q_E001+1)
 #define	SKERR_Q_E002MSG	"Undefined event class"
+#define	SKERR_Q_E003	(SKERR_Q_E001+2)
+#define	SKERR_Q_E003MSG	"Event queued in Init Level 0"
+#define	SKERR_Q_E004	(SKERR_Q_E001+3)
+#define	SKERR_Q_E004MSG	"Error Reported from Event Fuction (Queue Blocked)"
+#define	SKERR_Q_E005	(SKERR_Q_E001+4)
+#define	SKERR_Q_E005MSG	"Event scheduler called in Init Level 0 or 1"
 #endif	/* _SKQUEUE_H_ */
 
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skrlmt.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skrlmt.h
--- linux-2.4.29/drivers/net/sk98lin/h/skrlmt.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skrlmt.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skrlmt.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:	$Revision: 2.1 $
+ * Date:	$Date: 2003/10/27 14:16:09 $
  * Purpose:	Header file for Redundant Link ManagemenT.
  *
  ******************************************************************************/
diff -urN linux-2.4.29/drivers/net/sk98lin/h/sktimer.h linux-2.4.29-uc1/drivers/net/sk98lin/h/sktimer.h
--- linux-2.4.29/drivers/net/sk98lin/h/sktimer.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/sktimer.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	sktimer.h
  * Project:	Gigabit Ethernet Adapters, Event Scheduler Module
+ * Version:	$Revision: 2.1 $
+ * Date:	$Date: 2003/10/27 14:16:09 $
  * Purpose:	Defines for the timer functions
  *
  ******************************************************************************/
diff -urN linux-2.4.29/drivers/net/sk98lin/h/sktwsi.h linux-2.4.29-uc1/drivers/net/sk98lin/h/sktwsi.h
--- linux-2.4.29/drivers/net/sk98lin/h/sktwsi.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/sktwsi.h	2005-06-14 02:12:09.000000000 +0100
@@ -0,0 +1,177 @@
+/******************************************************************************
+ *
+ * Name:	sktwsi.h
+ * Project:	Gigabit Ethernet Adapters, TWSI-Module
+ * Version:	$Revision: 1.2 $
+ * Date:	$Date: 2004/11/17 05:40:48 $
+ * Purpose:	Defines to access Voltage and Temperature Sensor
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *	(C)Copyright 1998-2002 SysKonnect.
+ *	(C)Copyright 2002-2003 Marvell.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2 of the License, or
+ *	(at your option) any later version.
+ *
+ *	The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/*
+ * SKTWSI.H	contains all TWSI specific defines
+ */
+
+#ifndef _SKTWSI_H_
+#define _SKTWSI_H_
+
+typedef struct  s_Sensor SK_SENSOR;
+
+#include "h/skgetwsi.h"
+
+/*
+ * Define the TWSI events.
+ */
+#define SK_I2CEV_IRQ	1	/* IRQ happened Event */
+#define SK_I2CEV_TIM	2	/* Timeout event */
+#define SK_I2CEV_CLEAR	3	/* Clear MIB Values */
+
+/*
+ * Define READ and WRITE Constants.
+ */
+#define I2C_READ	0
+#define I2C_WRITE	1
+#define I2C_BURST	1
+#define I2C_SINGLE	0
+
+#define SKERR_I2C_E001		(SK_ERRBASE_I2C+0)
+#define SKERR_I2C_E001MSG	"Sensor index unknown"
+#define SKERR_I2C_E002		(SKERR_I2C_E001+1)
+#define SKERR_I2C_E002MSG	"TWSI: transfer does not complete"
+#define SKERR_I2C_E003		(SKERR_I2C_E002+1)
+#define SKERR_I2C_E003MSG	"LM80: NAK on device send"
+#define SKERR_I2C_E004		(SKERR_I2C_E003+1)
+#define SKERR_I2C_E004MSG	"LM80: NAK on register send"
+#define SKERR_I2C_E005		(SKERR_I2C_E004+1)
+#define SKERR_I2C_E005MSG	"LM80: NAK on device (2) send"
+#define SKERR_I2C_E006		(SKERR_I2C_E005+1)
+#define SKERR_I2C_E006MSG	"Unknown event"
+#define SKERR_I2C_E007		(SKERR_I2C_E006+1)
+#define SKERR_I2C_E007MSG	"LM80 read out of state"
+#define SKERR_I2C_E008		(SKERR_I2C_E007+1)
+#define SKERR_I2C_E008MSG	"Unexpected sensor read completed"
+#define SKERR_I2C_E009		(SKERR_I2C_E008+1)
+#define SKERR_I2C_E009MSG	"WARNING: temperature sensor out of range"
+#define SKERR_I2C_E010		(SKERR_I2C_E009+1)
+#define SKERR_I2C_E010MSG	"WARNING: voltage sensor out of range"
+#define SKERR_I2C_E011		(SKERR_I2C_E010+1)
+#define SKERR_I2C_E011MSG	"ERROR: temperature sensor out of range"
+#define SKERR_I2C_E012		(SKERR_I2C_E011+1)
+#define SKERR_I2C_E012MSG	"ERROR: voltage sensor out of range"
+#define SKERR_I2C_E013		(SKERR_I2C_E012+1)
+#define SKERR_I2C_E013MSG	"ERROR: couldn't init sensor"
+#define SKERR_I2C_E014		(SKERR_I2C_E013+1)
+#define SKERR_I2C_E014MSG	"WARNING: fan sensor out of range"
+#define SKERR_I2C_E015		(SKERR_I2C_E014+1)
+#define SKERR_I2C_E015MSG	"ERROR: fan sensor out of range"
+#define SKERR_I2C_E016		(SKERR_I2C_E015+1)
+#define SKERR_I2C_E016MSG	"TWSI: active transfer does not complete"
+
+/*
+ * Define Timeout values
+ */
+#define SK_I2C_TIM_LONG		2000000L	/* 2 seconds */
+#define SK_I2C_TIM_SHORT	 100000L	/* 100 milliseconds */
+#define SK_I2C_TIM_WATCH	1000000L	/* 1 second */
+
+/*
+ * Define trap and error log hold times
+ */
+#ifndef	SK_SEN_ERR_TR_HOLD
+#define SK_SEN_ERR_TR_HOLD		(4*SK_TICKS_PER_SEC)
+#endif
+#ifndef	SK_SEN_ERR_LOG_HOLD
+#define SK_SEN_ERR_LOG_HOLD		(60*SK_TICKS_PER_SEC)
+#endif
+#ifndef	SK_SEN_WARN_TR_HOLD
+#define SK_SEN_WARN_TR_HOLD		(15*SK_TICKS_PER_SEC)
+#endif
+#ifndef	SK_SEN_WARN_LOG_HOLD
+#define SK_SEN_WARN_LOG_HOLD	(15*60*SK_TICKS_PER_SEC)
+#endif
+
+/*
+ * Defines for SenType
+ */
+#define SK_SEN_UNKNOWN	0
+#define SK_SEN_TEMP		1
+#define SK_SEN_VOLT		2
+#define SK_SEN_FAN		3
+
+/*
+ * Define for the SenErrorFlag
+ */
+#define SK_SEN_ERR_NOT_PRESENT	0	/* Error Flag: Sensor not present */
+#define SK_SEN_ERR_OK			1	/* Error Flag: O.K. */
+#define SK_SEN_ERR_WARN			2	/* Error Flag: Warning */
+#define SK_SEN_ERR_ERR			3	/* Error Flag: Error */
+#define SK_SEN_ERR_FAULTY		4	/* Error Flag: Faulty */
+
+/*
+ * Define the Sensor struct
+ */
+struct	s_Sensor {
+	char	*SenDesc;			/* Description */
+	int		SenType;			/* Voltage or Temperature */
+	SK_I32	SenValue;			/* Current value of the sensor */
+	SK_I32	SenThreErrHigh;		/* High error Threshhold of this sensor */
+	SK_I32	SenThreWarnHigh;	/* High warning Threshhold of this sensor */
+	SK_I32	SenThreErrLow;		/* Lower error Threshold of the sensor */
+	SK_I32	SenThreWarnLow;		/* Lower warning Threshold of the sensor */
+	int		SenErrFlag;			/* Sensor indicated an error */
+	SK_BOOL	SenInit;			/* Is sensor initialized ? */
+	SK_U64	SenErrCts;			/* Error trap counter */
+	SK_U64	SenWarnCts;			/* Warning trap counter */
+	SK_U64	SenBegErrTS;		/* Begin error timestamp */
+	SK_U64	SenBegWarnTS;		/* Begin warning timestamp */
+	SK_U64	SenLastErrTrapTS;	/* Last error trap timestamp */
+	SK_U64	SenLastErrLogTS;	/* Last error log timestamp */
+	SK_U64	SenLastWarnTrapTS;	/* Last warning trap timestamp */
+	SK_U64	SenLastWarnLogTS;	/* Last warning log timestamp */
+	int		SenState;			/* Sensor State (see HW specific include) */
+	int		(*SenRead)(SK_AC *pAC, SK_IOC IoC, struct s_Sensor *pSen);
+								/* Sensors read function */
+	SK_U16	SenReg;				/* Register Address for this sensor */
+	SK_U8	SenDev;				/* Device Selection for this sensor */
+};
+
+typedef	struct	s_I2c {
+	SK_SENSOR	SenTable[SK_MAX_SENSORS];	/* Sensor Table */
+	int			CurrSens;	/* Which sensor is currently queried */
+	int			MaxSens;	/* Max. number of sensors */
+	int			TimerMode;	/* Use the timer also to watch the state machine */
+	int			InitLevel;	/* Initialized Level */
+#ifndef SK_DIAG
+	int			DummyReads;	/* Number of non-checked dummy reads */
+	SK_TIMER	SenTimer;	/* Sensors timer */
+#endif /* !SK_DIAG */
+} SK_I2C;
+
+extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level);
+extern int SkI2cWrite(SK_AC *pAC, SK_IOC IoC, SK_U32 Data, int Dev, int Size,
+					   int Reg, int Burst);
+extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
+#ifdef SK_DIAG
+extern	SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg,
+						 int Burst);
+#else /* !SK_DIAG */
+extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
+extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC);
+extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC);
+#endif /* !SK_DIAG */
+#endif /* n_SKTWSI_H */
+
diff -urN linux-2.4.29/drivers/net/sk98lin/h/sktypes.h linux-2.4.29-uc1/drivers/net/sk98lin/h/sktypes.h
--- linux-2.4.29/drivers/net/sk98lin/h/sktypes.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/sktypes.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	sktypes.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:	$Revision: 1.2 $
+ * Date:	$Date: 2004/07/09 13:29:49 $
  * Purpose:	Define data types for Linux
  *
  ******************************************************************************/
@@ -20,48 +22,28 @@
  *
  ******************************************************************************/
  
-/******************************************************************************
- *
- * Description:
- *
- * In this file, all data types that are needed by the common modules
- * are mapped to Linux data types.
- * 
- *
- * Include File Hierarchy:
- *
- *
- ******************************************************************************/
-
 #ifndef __INC_SKTYPES_H
 #define __INC_SKTYPES_H
 
-
-/* defines *******************************************************************/
-
-/*
- * Data types with a specific size. 'I' = signed, 'U' = unsigned.
- */
-#define SK_I8	s8
-#define SK_U8	u8
-#define SK_I16	s16
-#define SK_U16	u16
-#define SK_I32	s32
-#define SK_U32	u32
-#define SK_I64	s64
-#define SK_U64	u64
-
-#define SK_UPTR	ulong		/* casting pointer <-> integral */
-
-/*
-* Boolean type.
-*/
-#define SK_BOOL		SK_U8
-#define SK_FALSE	0
-#define SK_TRUE		(!SK_FALSE)
-
-/* typedefs *******************************************************************/
-
-/* function prototypes ********************************************************/
+#define SK_I8    s8    /* 8 bits (1 byte) signed       */
+#define SK_U8    u8    /* 8 bits (1 byte) unsigned     */
+#define SK_I16  s16    /* 16 bits (2 bytes) signed     */
+#define SK_U16  u16    /* 16 bits (2 bytes) unsigned   */
+#define SK_I32  s32    /* 32 bits (4 bytes) signed     */
+#define SK_U32  u32    /* 32 bits (4 bytes) unsigned   */
+#define SK_I64  s64    /* 64 bits (8 bytes) signed     */
+#define SK_U64  u64    /* 64 bits (8 bytes) unsigned   */
+
+#define SK_UPTR	ulong  /* casting pointer <-> integral */
+
+#define SK_BOOL   SK_U8
+#define SK_FALSE  0
+#define SK_TRUE   (!SK_FALSE)
 
 #endif	/* __INC_SKTYPES_H */
+
+/*******************************************************************************
+ *
+ * End of file
+ *
+ ******************************************************************************/
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skversion.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skversion.h
--- linux-2.4.29/drivers/net/sk98lin/h/skversion.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skversion.h	2005-06-14 02:12:09.000000000 +0100
@@ -1,15 +1,17 @@
 /******************************************************************************
  *
- * Name:	version.h
+ * Name:	skversion.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Purpose:	SK specific Error log support
+ * Version:	$Revision: 1.3 $
+ * Date:	$Date: 2004/07/09 13:33:59 $
+ * Purpose:	specific version strings and numbers
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
  *	(C)Copyright 1998-2002 SysKonnect GmbH.
- *	(C)Copyright 2002-2003 Marvell.
+ *	(C)Copyright 2002-2004 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -20,17 +22,15 @@
  *
  ******************************************************************************/
 
-#ifdef	lint
-static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH.";
-static const char SysKonnectBuildNumber[] =
-	"@(#)SK-BUILD: 6.22 PL: 01"; 
-#endif	/* !defined(lint) */
-
-#define BOOT_STRING	"sk98lin: Network Device Driver v6.22\n" \
-			"(C)Copyright 1999-2004 Marvell(R)."
-
-#define VER_STRING	"6.22"
-#define DRIVER_FILE_NAME	"sk98lin"
-#define DRIVER_REL_DATE		"Jan-30-2004"
-
+#define BOOT_STRING  "sk98lin: Network Device Driver v7.06\n" \
+                     "(C)Copyright 1999-2004 Marvell(R)."
+#define VER_STRING   "7.06"
+#define PATCHLEVEL   "04"
+#define DRIVER_FILE_NAME   "sk98lin"
+#define DRIVER_REL_DATE    "Aug-20-2004"
 
+/*******************************************************************************
+ *
+ * End of file
+ *
+ ******************************************************************************/
diff -urN linux-2.4.29/drivers/net/sk98lin/h/skvpd.h linux-2.4.29-uc1/drivers/net/sk98lin/h/skvpd.h
--- linux-2.4.29/drivers/net/sk98lin/h/skvpd.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/skvpd.h	2005-06-14 02:12:09.000000000 +0100
@@ -1,20 +1,22 @@
 /******************************************************************************
  *
  * Name:	skvpd.h
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
+ * Project:	Gigabit Ethernet Adapters, VPD-Module
+ * Version:	$Revision: 2.5 $
+ * Date:	$Date: 2004/08/11 14:36:16 $
  * Purpose:	Defines and Macros for VPD handling
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2003 SysKonnect GmbH.
+ *	(C)Copyright 1998-2002 SysKonnect.
+ *	(C)Copyright 2002-2004 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
  *	the Free Software Foundation; either version 2 of the License, or
  *	(at your option) any later version.
- *
  *	The information in this file is provided "AS IS" without warranty.
  *
  ******************************************************************************/
@@ -46,6 +48,8 @@
 #define	VPD_YA		"YA"	/* Asset Tag Identifier */
 #define VPD_VL		"VL"	/* First Error Log Message (SK specific) */
 #define VPD_VF		"VF"	/* Second Error Log Message (SK specific) */
+#define VPD_VB		"VB"	/* Boot Agent ROM Configuration (SK specific) */
+#define VPD_VE		"VE"	/* EFI UNDI Configuration (SK specific) */
 #define VPD_RW		"RW"	/* Remaining Read / Write Area */
 
 /* 'type' values for vpd_setup_para() */
@@ -133,49 +137,49 @@
 #define VPD_IN16(pAC,IoC,Addr,pVal)	(void)SkPciReadCfgWord(pAC,Addr,pVal)
 #define VPD_IN32(pAC,IoC,Addr,pVal)	(void)SkPciReadCfgDWord(pAC,Addr,pVal)
 #else	/* VPD_DO_IO */
-#define VPD_OUT8(pAC,IoC,Addr,Val)	SK_OUT8(IoC,PCI_C(Addr),Val)
-#define VPD_OUT16(pAC,IoC,Addr,Val)	SK_OUT16(IoC,PCI_C(Addr),Val)
-#define VPD_OUT32(pAC,IoC,Addr,Val)	SK_OUT32(IoC,PCI_C(Addr),Val)
-#define VPD_IN8(pAC,IoC,Addr,pVal)	SK_IN8(IoC,PCI_C(Addr),pVal)
-#define VPD_IN16(pAC,IoC,Addr,pVal)	SK_IN16(IoC,PCI_C(Addr),pVal)
-#define VPD_IN32(pAC,IoC,Addr,pVal)	SK_IN32(IoC,PCI_C(Addr),pVal)
+#define VPD_OUT8(pAC,IoC,Addr,Val)	SK_OUT8(IoC,PCI_C(pAC,Addr),Val)
+#define VPD_OUT16(pAC,IoC,Addr,Val)	SK_OUT16(IoC,PCI_C(pAC,Addr),Val)
+#define VPD_OUT32(pAC,IoC,Addr,Val)	SK_OUT32(IoC,PCI_C(pAC,Addr),Val)
+#define VPD_IN8(pAC,IoC,Addr,pVal)	SK_IN8(IoC,PCI_C(pAC,Addr),pVal)
+#define VPD_IN16(pAC,IoC,Addr,pVal)	SK_IN16(IoC,PCI_C(pAC,Addr),pVal)
+#define VPD_IN32(pAC,IoC,Addr,pVal)	SK_IN32(IoC,PCI_C(pAC,Addr),pVal)
 #endif	/* VPD_DO_IO */
 #else	/* SKDIAG */
 #define VPD_OUT8(pAC,Ioc,Addr,Val) {			\
 		if ((pAC)->DgT.DgUseCfgCycle)			\
 			SkPciWriteCfgByte(pAC,Addr,Val);	\
 		else									\
-			SK_OUT8(pAC,PCI_C(Addr),Val);		\
+			SK_OUT8(pAC,PCI_C(pAC,Addr),Val);	\
 		}
 #define VPD_OUT16(pAC,Ioc,Addr,Val) {			\
 		if ((pAC)->DgT.DgUseCfgCycle)			\
 			SkPciWriteCfgWord(pAC,Addr,Val);	\
 		else						\
-			SK_OUT16(pAC,PCI_C(Addr),Val);		\
+			SK_OUT16(pAC,PCI_C(pAC,Addr),Val);	\
 		}
 #define VPD_OUT32(pAC,Ioc,Addr,Val) {			\
 		if ((pAC)->DgT.DgUseCfgCycle)			\
 			SkPciWriteCfgDWord(pAC,Addr,Val);	\
 		else						\
-			SK_OUT32(pAC,PCI_C(Addr),Val); 		\
+			SK_OUT32(pAC,PCI_C(pAC,Addr),Val);	\
 		}
 #define VPD_IN8(pAC,Ioc,Addr,pVal) {			\
 		if ((pAC)->DgT.DgUseCfgCycle) 			\
 			SkPciReadCfgByte(pAC,Addr,pVal);	\
 		else						\
-			SK_IN8(pAC,PCI_C(Addr),pVal); 		\
+			SK_IN8(pAC,PCI_C(pAC,Addr),pVal);	\
 		}
 #define VPD_IN16(pAC,Ioc,Addr,pVal) {			\
 		if ((pAC)->DgT.DgUseCfgCycle) 			\
 			SkPciReadCfgWord(pAC,Addr,pVal);	\
 		else						\
-			SK_IN16(pAC,PCI_C(Addr),pVal); 		\
+			SK_IN16(pAC,PCI_C(pAC,Addr),pVal);	\
 		}
 #define VPD_IN32(pAC,Ioc,Addr,pVal) {			\
 		if ((pAC)->DgT.DgUseCfgCycle)			\
 			SkPciReadCfgDWord(pAC,Addr,pVal);	\
 		else						\
-			SK_IN32(pAC,PCI_C(Addr),pVal);		\
+			SK_IN32(pAC,PCI_C(pAC,Addr),pVal);	\
 		}
 #endif	/* nSKDIAG */
 
@@ -238,7 +242,12 @@
 	SK_IOC		IoC,
 	char		*msg);
 
-#ifdef	SKDIAG
+int VpdInit(
+	SK_AC		*pAC,
+	SK_IOC		IoC);
+
+#if defined(SKDIAG) || defined(SK_ASF)
+
 extern int	VpdReadBlock(
 	SK_AC		*pAC,
 	SK_IOC		IoC,
@@ -252,7 +261,9 @@
 	char		*buf,
 	int			addr,
 	int			len);
-#endif	/* SKDIAG */
+
+#endif	/* SKDIAG || SK_ASF */
+
 #else	/* SK_KR_PROTO */
 extern SK_U32	VpdReadDWord();
 extern int	VpdSetupPara();
diff -urN linux-2.4.29/drivers/net/sk98lin/h/sky2le.h linux-2.4.29-uc1/drivers/net/sk98lin/h/sky2le.h
--- linux-2.4.29/drivers/net/sk98lin/h/sky2le.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/sky2le.h	2005-06-14 02:12:09.000000000 +0100
@@ -0,0 +1,872 @@
+/******************************************************************************
+ *
+ * Name:	sky2le.h
+ * Project:	Gigabit Ethernet Adapters, Common Modules
+ * Version:	$Revision: 1.2 $
+ * Date:	$Date: 2004/11/17 05:40:48 $
+ * Purpose:	Common list element definitions and access macros.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *	(C)Copyright 2003 Marvell.
+ *	All Rights Reserved
+ *
+ *	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL
+ *	The copyright notice above does not evidence any
+ *	actual or intended publication of such source code.
+ *
+ *	This Module contains Proprietary Information of Marvell
+ *	and should be treated as Confidential.
+ *
+ *	The information in this file is provided for the exclusive use of
+ *	the licensees of Marvell.
+ *	Such users have the right to use, modify, and incorporate this code
+ *	into products for purposes authorized by the license agreement
+ *	provided they include this notice and the associated copyright notice
+ *	with any such product.
+ *	The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKY2LE_H
+#define __INC_SKY2LE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif	/* __cplusplus */
+
+
+/* defines ********************************************************************/
+
+#define MIN_LEN_OF_LE_TAB	128
+#define MAX_LEN_OF_LE_TAB	4096
+#ifdef USE_POLLING_UNIT
+#define NUM_LE_POLLING_UNIT	2
+#endif
+#define MAX_FRAG_OVERHEAD       10
+
+/* Macro for aligning a given value */
+#define SK_ALIGN_SIZE(Value, Alignment, AlignedVal)	{						\
+	(AlignedVal) = (((Value) + (Alignment) - 1) & (~((Alignment) - 1)));	\
+}
+
+/******************************************************************************
+ *
+ * LE2DWord() - Converts the given Little Endian value to machine order value
+ *
+ * Description:
+ *	This function converts the Little Endian value received as an argument to
+ *  the machine order value.
+ *
+ * Returns:
+ *	The converted value
+ *
+ */
+
+#ifdef SK_LITTLE_ENDIAN
+
+#define LE2DWord(value)	(value)
+
+#else	/* !SK_LITTLE_ENDIAN */
+
+#define LE2DWord(value)				\
+	((((value)<<24L)&0xff000000L) +	\
+	(((value)<< 8L)&0x00ff0000L) +	\
+	(((value)>> 8L)&0x0000ff00L) +	\
+	(((value)>>24L)&0x000000ffL))
+
+#endif	/* !SK_LITTLE_ENDIAN */
+
+/******************************************************************************
+ *
+ * DWord2LE() - Converts the given value to a Little Endian value
+ *
+ * Description:
+ *	This function converts the value received as an argument to a Little Endian
+ *  value on Big Endian machines. If the machine running the code is Little
+ *  Endian, then no conversion is done.
+ *
+ * Returns:
+ *	The converted value
+ *
+ */
+
+#ifdef SK_LITTLE_ENDIAN
+
+#define DWord2LE(value) (value)
+
+#else	/* !SK_LITTLE_ENDIAN */
+
+#define DWord2LE(value) 			\
+	((((value)<<24L)&0xff000000L) +	\
+	(((value)<< 8L)&0x00ff0000L) +	\
+	(((value)>> 8L)&0x0000ff00L) +	\
+	(((value)>>24L)&0x000000ffL))
+
+#endif	/* !SK_LITTLE_ENDIAN */
+
+/******************************************************************************
+ *
+ * LE2Word() - Converts the given Little Endian value to machine order value
+ *
+ * Description:
+ *	This function converts the Little Endian value received as an argument to
+ *  the machine order value.
+ *
+ * Returns:
+ *	The converted value
+ *
+ */
+
+#ifdef SK_LITTLE_ENDIAN
+
+#define LE2Word(value) (value)
+
+#else	/* !SK_LITTLE_ENDIAN */
+
+#define LE2Word(value)			\
+	((((value)<< 8L)&0xff00) +	\
+	(((value)>> 8L)&0x00ff))
+
+#endif	/* !SK_LITTLE_ENDIAN */
+
+/******************************************************************************
+ *
+ * Word2LE() - Converts the given value to a Little Endian value
+ *
+ * Description:
+ *	This function converts the value received as an argument to a Little Endian
+ *  value on Big Endian machines. If the machine running the code is Little
+ *  Endian, then no conversion is done.
+ *
+ * Returns:
+ *	The converted value
+ *
+ */
+
+#ifdef SK_LITTLE_ENDIAN
+
+#define Word2LE(value) (value)
+
+#else	/* !SK_LITTLE_ENDIAN */
+
+#define Word2LE(value) 			\
+	((((value)<< 8L)&0xff00) +	\
+	(((value)>> 8L)&0x00ff))
+
+#endif	/* !SK_LITTLE_ENDIAN */
+
+/******************************************************************************
+ *
+ * Transmit list element macros
+ *
+ */
+
+#define TXLE_SET_ADDR(pLE, Addr)	\
+	((pLE)->Tx.TxUn.BufAddr = DWord2LE(Addr))
+#define TXLE_SET_LSLEN(pLE, Len)	\
+	((pLE)->Tx.TxUn.LargeSend.Length = Word2LE(Len))
+#define TXLE_SET_STACS(pLE, Start)	\
+	((pLE)->Tx.TxUn.ChkSum.TxTcpSp = Word2LE(Start))
+#define TXLE_SET_WRICS(pLE, Write)	\
+	((pLE)->Tx.TxUn.ChkSum.TxTcpWp = Word2LE(Write))
+#define TXLE_SET_INICS(pLE, Ini)	((pLE)->Tx.Send.InitCsum = Word2LE(Ini))
+#define TXLE_SET_LEN(pLE, Len)		((pLE)->Tx.Send.BufLen = Word2LE(Len))
+#define TXLE_SET_VLAN(pLE, Vlan)	((pLE)->Tx.Send.VlanTag = Word2LE(Vlan))
+#define TXLE_SET_LCKCS(pLE, Lock)	((pLE)->Tx.ControlFlags = (Lock))
+#define TXLE_SET_CTRL(pLE, Ctrl)	((pLE)->Tx.ControlFlags = (Ctrl))
+#define TXLE_SET_OPC(pLE, Opc)		((pLE)->Tx.Opcode = (Opc))
+
+
+#define TXLE_GET_ADDR(pLE)		LE2DWord((pLE)->Tx.TxUn.BufAddr)
+#define TXLE_GET_LSLEN(pLE)		LE2Word((pLE)->Tx.TxUn.LargeSend.Length)
+#define TXLE_GET_STACS(pLE)		LE2Word((pLE)->Tx.TxUn.ChkSum.TxTcpSp)
+#define TXLE_GET_WRICS(pLE)		LE2Word((pLE)->Tx.TxUn.ChkSum.TxTcpWp)
+#define TXLE_GET_INICS(pLE)		LE2Word((pLE)->Tx.Send.InitCsum)
+#define TXLE_GET_LEN(pLE) 		LE2Word((pLE)->Tx.Send.BufLen)
+#define TXLE_GET_VLAN(pLE)		LE2Word((pLE)->Tx.Send.VlanTag)
+#define TXLE_GET_LCKCS(pLE)		((pLE)->Tx.ControlFlags)
+#define TXLE_GET_CTRL(pLE)		((pLE)->Tx.ControlFlags)
+#define TXLE_GET_OPC(pLE)		((pLE)->Tx.Opcode)
+
+/******************************************************************************
+ *
+ * Receive list element macros
+ *
+ */
+
+#define RXLE_SET_ADDR(pLE, Addr)	\
+	((pLE)->Rx.RxUn.BufAddr = (SK_U32) DWord2LE(Addr))
+#define RXLE_SET_STACS2(pLE, Offs)	\
+	((pLE)->Rx.RxUn.ChkSum.RxTcpSp2 = Word2LE(Offs))
+#define RXLE_SET_STACS1(pLE, Offs)	\
+	((pLE)->Rx.RxUn.ChkSum.RxTcpSp1 = Word2LE(Offs))
+#define RXLE_SET_LEN(pLE, Len)		((pLE)->Rx.BufferLength = Word2LE(Len))
+#define RXLE_SET_CTRL(pLE, Ctrl)	((pLE)->Rx.ControlFlags = (Ctrl))
+#define RXLE_SET_OPC(pLE, Opc)		((pLE)->Rx.Opcode = (Opc))
+
+
+#define RXLE_GET_ADDR(pLE)		LE2DWord((pLE)->Rx.RxUn.BufAddr)
+#define RXLE_GET_STACS2(pLE)	LE2Word((pLE)->Rx.RxUn.ChkSum.RxTcpSp2)
+#define RXLE_GET_STACS1(pLE)	LE2Word((pLE)->Rx.RxUn.ChkSum.RxTcpSp1)
+#define RXLE_GET_LEN(pLE) 		LE2Word((pLE)->Rx.BufferLength)
+#define RXLE_GET_CTRL(pLE)		((pLE)->Rx.ControlFlags)
+#define RXLE_GET_OPC(pLE)		((pLE)->Rx.Opcode)
+
+/******************************************************************************
+ *
+ * Status list element macros
+ *
+ */
+
+#define STLE_SET_OPC(pLE, Opc)		((pLE)->St.Opcode = (Opc))
+
+#define STLE_GET_FRSTATUS(pLE)	LE2DWord((pLE)->St.StUn.StRxStatWord)
+#define STLE_GET_TIST(pLE)		LE2DWord((pLE)->St.StUn.StRxTimeStamp)
+#define STLE_GET_TCP1(pLE)		LE2Word((pLE)->St.StUn.StRxTCPCSum.RxTCPSum1)
+#define STLE_GET_TCP2(pLE)		LE2Word((pLE)->St.StUn.StRxTCPCSum.RxTCPSum2)
+#define STLE_GET_LEN(pLE)		LE2Word((pLE)->St.Stat.BufLen)
+#define STLE_GET_VLAN(pLE)		LE2Word((pLE)->St.Stat.VlanTag)
+#define STLE_GET_LINK(pLE)		((pLE)->St.Link)
+#define STLE_GET_OPC(pLE)		((pLE)->St.Opcode)
+#define STLE_GET_DONE_IDX(pLE,LowVal,HighVal) {			\
+	(LowVal) = LE2DWord((pLE)->St.StUn.StTxStatLow);	\
+	(HighVal) = LE2Word((pLE)->St.Stat.StTxStatHi);		\
+}
+
+#define STLE_GET_RSS(pLE)		LE2DWord((pLE)->St.StUn.StRxRssValue)
+#define STLE_GET_IPBIT(pLE)		((pLE)->St.Stat.Rss.FlagField & RSS_IP_FLAG)
+#define STLE_GET_TCPBIT(pLE)	((pLE)->St.Stat.Rss.FlagField & RSS_TCP_FLAG)
+
+
+/* I always take both values as a paramter to avoid typos */
+#define STLE_GET_DONE_IDX_TXA1(LowVal,HighVal)			\
+	(((LowVal) & STLE_TXA1_MSKL) >> STLE_TXA1_SHIFTL)
+#define STLE_GET_DONE_IDX_TXS1(LowVal,HighVal)			\
+	((LowVal & STLE_TXS1_MSKL) >> STLE_TXS1_SHIFTL)
+#define STLE_GET_DONE_IDX_TXA2(LowVal,HighVal)			\
+	(((LowVal & STLE_TXA2_MSKL) >> STLE_TXA2_SHIFTL) + 	\
+	((HighVal & STLE_TXA2_MSKH) << STLE_TXA2_SHIFTH))
+#define STLE_GET_DONE_IDX_TXS2(LowVal,HighVal)			\
+	((HighVal & STLE_TXS2_MSKL) >> STLE_TXS2_SHIFTL)
+
+
+#define SK_Y2_RXSTAT_CHECK_PKT(Len, RxStat, IsOk) {				\
+	(IsOk) = (((RxStat) & GMR_FS_RX_OK) == GMR_FS_RX_OK) &&		\
+			 (((RxStat) & GMR_FS_ANY_ERR) == 0);				\
+																\
+	if ((IsOk) && ((SK_U16)(((RxStat) & GMR_FS_LEN_MSK) >>  	\
+		GMR_FS_LEN_SHIFT) != (Len))) {							\
+		/* length in MAC status differs from length in LE */	\
+		(IsOk) = SK_FALSE;										\
+	}															\
+}
+
+
+/******************************************************************************
+ *
+ * Polling unit list element macros
+ *
+ * NOTE: the Idx must be <= 0xfff and PU_PUTIDX_VALID makes them valid
+ *
+ */
+
+#ifdef USE_POLLING_UNIT
+
+#define POLE_SET_OPC(pLE, Opc)		((pLE)->Sa.Opcode = (Opc))
+#define POLE_SET_LINK(pLE, Port)	((pLE)->Sa.Link = (Port))
+#define POLE_SET_RXIDX(pLE, Idx)	((pLE)->Sa.RxIdxVld = Word2LE(Idx))
+#define POLE_SET_TXAIDX(pLE, Idx)	((pLE)->Sa.TxAIdxVld = Word2LE(Idx))
+#define POLE_SET_TXSIDX(pLE, Idx)	((pLE)->Sa.TxSIdxVld = Word2LE(Idx))
+
+#define POLE_GET_OPC(pLE)		((pLE)->Sa.Opcode)
+#define POLE_GET_LINK(pLE)		((pLE)->Sa.Link)
+#define POLE_GET_RXIDX(pLE)		LE2Word((pLE)->Sa.RxIdxVld)
+#define POLE_GET_TXAIDX(pLE)	LE2Word((pLE)->Sa.TxAIdxVld)
+#define POLE_GET_TXSIDX(pLE)	LE2Word((pLE)->Sa.TxSIdxVld)
+
+#endif	/* USE_POLLING_UNIT */
+
+/******************************************************************************
+ *
+ * Debug macros for list elements
+ *
+ */
+
+#ifdef DEBUG
+
+#define SK_DBG_DUMP_RX_LE(pLE)	{										\
+	SK_U8	Opcode;														\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("=== RX_LIST_ELEMENT @addr: %p cont: %02x %02x %02x %02x %02x %02x %02x %02x\n",	\
+		pLE, ((SK_U8 *) pLE)[0], ((SK_U8 *) pLE)[1], ((SK_U8 *) pLE)[2],\
+		((SK_U8 *) pLE)[3], ((SK_U8 *) pLE)[4], ((SK_U8 *) pLE)[5],		\
+		((SK_U8 *) pLE)[6], ((SK_U8 *) pLE)[7])); 						\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("\t (16bit) %04x %04x %04x %04x\n",							\
+		((SK_U16 *) pLE)[0], ((SK_U16 *) pLE)[1], ((SK_U16 *) pLE)[2],	\
+		((SK_U16 *) pLE)[3])); 											\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("\t (32bit) %08x %08x\n",										\
+		((SK_U32 *) pLE)[0], ((SK_U32 *) pLE)[1])); 					\
+	Opcode = RXLE_GET_OPC(pLE);											\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					   	\
+		("\tOwn belongs to %s\n", ((Opcode & HW_OWNER) == HW_OWNER) ? 	\
+		 "Hardware" : "Software"));										\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("\tOpc: 0x%x ",Opcode));								   		\
+	switch (Opcode & (~HW_OWNER)) {									  	\
+	case OP_BUFFER:														\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,			   		\
+			("\tOP_BUFFER\n"));									   		\
+		break;															\
+	case OP_PACKET:									  	  	   			\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,			   		\
+			("\tOP_PACKET\n"));								   			\
+		break;															\
+	case OP_ADDR64:												   		\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tOP_ADDR64\n"));								   			\
+		break;															\
+	case OP_TCPSTART:												   	\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tOP_TCPPAR\n"));									   		\
+		break;															\
+	case SW_OWNER:														\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,			   		\
+			("\tunused LE\n"));									   		\
+		break;															\
+	default:														   	\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tunknown Opcode!!!\n"));								   	\
+		break;															\
+	}																	\
+	if ((Opcode & OP_BUFFER) == OP_BUFFER) {							\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tControl: 0x%x\n", RXLE_GET_CTRL(pLE)));					\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tBufLen: 0x%x\n", RXLE_GET_LEN(pLE)));					\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tLowAddr: 0x%x\n", RXLE_GET_ADDR(pLE)));					\
+	}																	\
+	if ((Opcode & OP_ADDR64) == OP_ADDR64) {							\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tHighAddr: 0x%x\n", RXLE_GET_ADDR(pLE)));				\
+	}																	\
+	if ((Opcode & OP_TCPSTART) == OP_TCPSTART) {	  		  			\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tTCP Sum Start 1 : 0x%x\n", RXLE_GET_STACS1(pLE)));		\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tTCP Sum Start 2 : 0x%x\n", RXLE_GET_STACS2(pLE)));		\
+	}																	\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("=====================\n"));									\
+}
+
+#define SK_DBG_DUMP_TX_LE(pLE)	{										\
+	SK_U8	Opcode;														\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("=== TX_LIST_ELEMENT @addr: %p cont: %02x %02x %02x %02x %02x %02x %02x %02x\n",	\
+		pLE, ((SK_U8 *) pLE)[0], ((SK_U8 *) pLE)[1], ((SK_U8 *) pLE)[2],\
+		((SK_U8 *) pLE)[3], ((SK_U8 *) pLE)[4], ((SK_U8 *) pLE)[5],		\
+		((SK_U8 *) pLE)[6], ((SK_U8 *) pLE)[7])); 						\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("\t (16bit) %04x %04x %04x %04x\n",							\
+		((SK_U16 *) pLE)[0], ((SK_U16 *) pLE)[1], ((SK_U16 *) pLE)[2],	\
+		((SK_U16 *) pLE)[3])); 											\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("\t (32bit) %08x %08x\n",										\
+		((SK_U32 *) pLE)[0], ((SK_U32 *) pLE)[1])); 					\
+	Opcode = TXLE_GET_OPC(pLE);										   	\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					   	\
+		("\tOwn belongs to %s\n", ((Opcode & HW_OWNER) == HW_OWNER) ? 	\
+		"Hardware" : "Software"));										\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					   	\
+		("\tOpc: 0x%x ",Opcode));								   		\
+	switch (Opcode & (~HW_OWNER)) {									   	\
+	case OP_TCPCHKSUM:										 	      	\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tOP_TCPCHKSUM\n"));									   	\
+		break;											   		 		\
+	case OP_TCPIS:										  		  	   	\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tOP_TCPIS\n"));										   	\
+		break;												  		  	\
+	case OP_TCPLCK:													   	\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,		   	    	\
+			("\tOP_TCPLCK\n"));								   	    	\
+		break;												   		 	\
+	case OP_TCPLW:													   	\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,		   	    	\
+			("\tOP_TCPLW\n"));								   	    	\
+		break;															\
+	case OP_TCPLSW:													   	\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tOP_TCPLSW\n"));										   	\
+		break;															\
+	case OP_TCPLISW:												   	\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tOP_TCPLISW\n"));						 		   	   	\
+		break;											 		   		\
+	case OP_ADDR64:										 		   	   	\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,	  	     	   	\
+			("\tOP_ADDR64\n"));										   	\
+		break;															\
+	case OP_VLAN:													   	\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,			   		\
+			("\tOP_VLAN\n"));										   	\
+		break;															\
+	case OP_ADDR64VLAN:												   	\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tOP_ADDR64VLAN\n"));								   		\
+		break;															\
+	case OP_LRGLEN:													   	\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tOP_LRGLEN\n"));										   	\
+		break;															\
+	case OP_LRGLENVLAN:												   	\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,			   		\
+			("\tOP_LRGLENVLAN\n"));									   	\
+		break;															\
+	case OP_BUFFER:													   	\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tOP_BUFFER\n"));									   		\
+		break;															\
+	case OP_PACKET:												   		\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tOP_PACKET\n"));										   	\
+		break;															\
+	case OP_LARGESEND:													\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,			   		\
+			("\tOP_LARGESEND\n"));									   	\
+		break;															\
+	case SW_OWNER:														\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,			   		\
+			("\tunused LE\n"));										   	\
+		break;															\
+	default:														   	\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tunknown Opcode!!!\n"));								   	\
+		break;															\
+	}																	\
+	if ((Opcode & OP_BUFFER) == OP_BUFFER) {							\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tControl: 0x%x\n", TXLE_GET_CTRL(pLE)));					\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tBufLen: 0x%x\n", TXLE_GET_LEN(pLE)));					\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tLowAddr: 0x%x\n", TXLE_GET_ADDR(pLE)));					\
+	}																	\
+	if ((Opcode & OP_ADDR64) == OP_ADDR64) {							\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tHighAddr: 0x%x\n", TXLE_GET_ADDR(pLE)));				\
+	}																	\
+	if ((Opcode & OP_VLAN) == OP_VLAN) {								\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tVLAN Id: 0x%x\n", TXLE_GET_VLAN(pLE)));					\
+	}																	\
+	if ((Opcode & OP_LRGLEN) == OP_LRGLEN) {				   			\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tLarge send length: 0x%x\n", TXLE_GET_LSLEN(pLE)));		\
+	}																	\
+	if ((Opcode &(~HW_OWNER)) <= OP_ADDR64) {							\
+		if ((Opcode & OP_TCPWRITE) == OP_TCPWRITE) {					\
+			SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				\
+				("\tTCP Sum Write: 0x%x\n", TXLE_GET_WRICS(pLE)));		\
+		}																\
+		if ((Opcode & OP_TCPSTART) == OP_TCPSTART) {					\
+			SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				\
+				("\tTCP Sum Start: 0x%x\n", TXLE_GET_STACS(pLE)));		\
+		}																\
+		if ((Opcode & OP_TCPINIT) == OP_TCPINIT) {					  	\
+			SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				\
+				("\tTCP Sum Init: 0x%x\n", TXLE_GET_INICS(pLE)));		\
+		}																\
+		if ((Opcode & OP_TCPLCK) == OP_TCPLCK) {					  	\
+			SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				\
+				("\tTCP Sum Lock: 0x%x\n", TXLE_GET_LCKCS(pLE)));		\
+		}																\
+	}																	\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("=====================\n"));									\
+}
+	
+#define SK_DBG_DUMP_ST_LE(pLE)	{ 										\
+	SK_U8	Opcode;														\
+	SK_U16	HighVal;													\
+	SK_U32	LowVal;														\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("=== ST_LIST_ELEMENT @addr: %p contains: %02x %02x %02x %02x %02x %02x %02x %02x\n",	\
+		pLE, ((SK_U8 *) pLE)[0], ((SK_U8 *) pLE)[1], ((SK_U8 *) pLE)[2],\
+		((SK_U8 *) pLE)[3], ((SK_U8 *) pLE)[4], ((SK_U8 *) pLE)[5],		\
+		((SK_U8 *) pLE)[6], ((SK_U8 *) pLE)[7])); 						\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("\t (16bit) %04x %04x %04x %04x\n",							\
+		((SK_U16 *) pLE)[0], ((SK_U16 *) pLE)[1], ((SK_U16 *) pLE)[2],	\
+		((SK_U16 *) pLE)[3])); 											\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("\t (32bit) %08x %08x\n",										\
+		((SK_U32 *) pLE)[0], ((SK_U32 *) pLE)[1])); 					\
+	Opcode = STLE_GET_OPC(pLE);											\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					   	\
+		("\tOwn belongs to %s\n", ((Opcode & HW_OWNER) == SW_OWNER) ? 	\
+		"Hardware" : "Software"));										\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("\tOpc: 0x%x",	Opcode));										\
+	Opcode &= (~HW_OWNER);												\
+	switch (Opcode) {													\
+	case OP_RXSTAT:										 	     		\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tOP_RXSTAT\n"));								   			\
+		break;															\
+	case OP_RXTIMESTAMP:												\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tOP_RXTIMESTAMP\n"));									\
+		break;															\
+	case OP_RXVLAN:											  			\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tOP_RXVLAN\n"));										   	\
+		break;															\
+	case OP_RXCHKS:											  			\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,	 		   	   	\
+			("\tOP_RXCHKS\n"));										   	\
+		break;											 		   		\
+	case OP_RXCHKSVLAN:									 	     		\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,	 		   	   	\
+			("\tOP_RXCHKSVLAN\n"));						 		   	   	\
+		break;											 		   		\
+	case OP_RXTIMEVLAN:									 	     		\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,	   		 	   	\
+			("\tOP_RXTIMEVLAN\n"));						   		 	   	\
+		break;											   		 		\
+	case OP_RSS_HASH:											  		\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tOP_RSS_HASH\n"));									   	\
+		break;															\
+	case OP_TXINDEXLE:											  		\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tOP_TXINDEXLE\n"));						  		  	   	\
+		break;															\
+	case HW_OWNER:											  			\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tunused LE\n"));						  		  	   		\
+		break;															\
+	default:												  			\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tunknown status list element!!!\n"));				   	\
+		break;															\
+	}																	\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("\tPort: %c\n", 'A' + STLE_GET_LINK(pLE)));					\
+	if (Opcode == OP_RXSTAT) {											\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tFrameLen: 0x%x\n", STLE_GET_LEN(pLE)));					\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tFrameStat: 0x%x\n", STLE_GET_FRSTATUS(pLE)));			\
+	}																	\
+	if ((Opcode & OP_RXVLAN) == OP_RXVLAN) {							\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tVLAN Id: 0x%x\n", STLE_GET_VLAN(pLE)));					\
+	}																	\
+	if ((Opcode & OP_RXTIMESTAMP) == OP_RXTIMESTAMP) {					\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tTimestamp: 0x%x\n", STLE_GET_TIST(pLE)));				\
+	}																	\
+	if ((Opcode & OP_RXCHKS) == OP_RXCHKS) {							\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tTCP: 0x%x 0x%x\n", STLE_GET_TCP1(pLE),					\
+			STLE_GET_TCP2(pLE)));										\
+	}																	\
+	if (Opcode == OP_TXINDEXLE) {										\
+		STLE_GET_DONE_IDX(pLE, LowVal, HighVal);						\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tTx Index TxA1: 0x%x\n",									\
+			STLE_GET_DONE_IDX_TXA1(LowVal,HighVal)));					\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tTx Index TxS1: 0x%x\n",									\
+			STLE_GET_DONE_IDX_TXS1(LowVal,HighVal)));					\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tTx Index TxA2: 0x%x\n",									\
+			STLE_GET_DONE_IDX_TXA2(LowVal,HighVal)));					\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,					\
+			("\tTx Index TxS2: 0x%x\n",									\
+			STLE_GET_DONE_IDX_TXS2(LowVal,HighVal)));					\
+	}																	\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("=====================\n"));									\
+}
+
+#ifdef USE_POLLING_UNIT
+#define SK_DBG_DUMP_PO_LE(pLE)	{										\
+	SK_U8	Opcode;														\
+	SK_U16	Idx;														\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("=== PO_LIST_ELEMENT @addr: %p cont: %02x %02x %02x %02x %02x %02x %02x %02x\n",	\
+		pLE, ((SK_U8 *) pLE)[0], ((SK_U8 *) pLE)[1], ((SK_U8 *) pLE)[2],\
+		((SK_U8 *) pLE)[3], ((SK_U8 *) pLE)[4], ((SK_U8 *) pLE)[5],		\
+		((SK_U8 *) pLE)[6], ((SK_U8 *) pLE)[7])); 						\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("\t (16bit) %04x %04x %04x %04x\n",							\
+		((SK_U16 *) pLE)[0], ((SK_U16 *) pLE)[1], ((SK_U16 *) pLE)[2],	\
+		((SK_U16 *) pLE)[3])); 											\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("\t (32bit) %08x %08x\n",										\
+		((SK_U32 *) pLE)[0], ((SK_U32 *) pLE)[1])); 					\
+	Opcode = POLE_GET_OPC(pLE);											\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		 ("\tOwn belongs to %s\n", ((Opcode & HW_OWNER) == HW_OWNER) ? 	\
+		  "Hardware" : "Software"));									\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		 ("\tOpc: 0x%x ",Opcode));										\
+	if ((Opcode & ~HW_OWNER) == OP_PUTIDX) {							\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,			   		\
+			("\tOP_PUTIDX\n"));								   			\
+	}																	\
+	else {																\
+		SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,				   	\
+			("\tunknown Opcode!!!\n"));								   	\
+	}																	\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,			   			\
+		("\tPort %c\n", 'A' + POLE_GET_LINK(pLE)));						\
+	Idx = POLE_GET_TXAIDX(pLE);											\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,			   			\
+		("\tTxA Index is 0x%X and %svalid\n", Idx,						\
+		(Idx & PU_PUTIDX_VALID) ? "" : "not "));						\
+	Idx = POLE_GET_TXSIDX(pLE);											\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,			   			\
+		("\tTxS Index is 0x%X and %svalid\n", Idx,						\
+		(Idx & PU_PUTIDX_VALID) ? "" : "not "));						\
+	Idx = POLE_GET_RXIDX(pLE);											\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,			   			\
+		("\tRx Index is 0x%X and %svalid\n", Idx,						\
+		(Idx & PU_PUTIDX_VALID) ? "" : "not "));						\
+	SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,						\
+		("=====================\n"));									\
+}
+#endif	/* USE_POLLING_UNIT */
+
+#else	/* !DEBUG */
+
+#define SK_DBG_DUMP_RX_LE(pLE)
+#define SK_DBG_DUMP_TX_LE(pLE)
+#define SK_DBG_DUMP_ST_LE(pLE)
+#define SK_DBG_DUMP_PO_LE(pLE)
+
+#endif	/* !DEBUG */
+
+/******************************************************************************
+ *
+ * Macros for listelement tables
+ *
+ *
+ */
+
+#define LE_SIZE sizeof(SK_HWLE)
+#define LE_TAB_SIZE(NumElements)	((NumElements) * LE_SIZE)
+
+/* Number of unused list elements in table
+ * this macro always returns the number of free listelements - 1
+ * this way we want to guarantee that always one LE remains unused
+ */
+#define NUM_FREE_LE_IN_TABLE(pTable) 									\
+	( ((pTable)->Put >= (pTable)->Done) ?									\
+	(NUM_LE_IN_TABLE(pTable) - (pTable)->Put + (pTable)->Done - 1) :	\
+	((pTable)->Done - (pTable)->Put - 1) )
+
+/* total number of list elements in table */
+#define NUM_LE_IN_TABLE(pTable)		((pTable)->Num)
+	
+/* get next unused rx list element */
+#define GET_RX_LE(pLE, pTable) {										\
+	pLE = &(pTable)->pLETab[(pTable)->Put];								\
+	(pTable)->Put = ((pTable)->Put + 1) % NUM_LE_IN_TABLE(pTable);		\
+}
+	
+/* get next unused tx list element */
+#define GET_TX_LE(pLE, pTable)	GET_RX_LE(pLE, pTable)
+
+/* get next status list element expected to be finished by hw */
+#define GET_ST_LE(pLE, pTable) {										\
+	pLE = &(pTable)->pLETab[(pTable)->Done];							\
+	(pTable)->Done = ((pTable)->Done +1) % NUM_LE_IN_TABLE(pTable);		\
+}
+
+#ifdef USE_POLLING_UNIT
+/* get next polling unit list element for port */
+#define GET_PO_LE(pLE, pTable, Port) {									\
+	pLE = &(pTable)->pLETab[(Port)];									\
+}
+#endif	/* USE_POLLING_UNIT */
+
+#define GET_PUT_IDX(pTable)			((pTable)->Put)
+
+#define UPDATE_HWPUT_IDX(pTable)	{(pTable)->HwPut = (pTable)->Put; }
+
+/*
+ * get own bit of next status LE
+ * if the result is != 0 there has been at least one status LE finished
+ */
+#define OWN_OF_FIRST_LE(pTable)											\
+	(STLE_GET_OPC(&(pTable)->pLETab[(pTable)->Done]) & HW_OWNER)
+
+#define SET_DONE_INDEX(pTable, Idx)	(pTable)->Done = (Idx);
+
+#define GET_DONE_INDEX(pTable)	((pTable)->Done)
+
+#ifdef SAFE_BUT_SLOW
+
+/* check own bit of LE before current done idx */
+#define CHECK_STLE_OVERFLOW(pTable, IsOk) {						\
+		unsigned i;												\
+		if ((i = (pTable)->Done) == 0) {						\
+			i = NUM_LE_IN_TABLE(pTable);						\
+		}														\
+		else {													\
+			i = i - 1; 											\
+		}														\
+		if (STLE_GET_OPC(&(pTable)->pLETab[i]) == HW_OWNER) {	\
+			(IsOk) = SK_TRUE;									\
+		}														\
+		else {													\
+			(IsOk) = SK_FALSE;									\
+		}														\
+	}
+
+
+/*
+ * for Yukon2 the hardware is not polling the list elements, so it
+ * is not necessary to change the own-bit of rx or tx-LEs before
+ * reusing them
+ * but it might make debugging easier if one simply can see whether
+ * a LE has been worked on
+ */
+	
+#define CLEAR_LE_OWN(pTable, Idx)								\
+	STLE_SET_OPC(&(pTable)->pLETab[(Idx)], SW_OWNER)
+
+/*
+ * clear all own bits starting from old done index up to the LE before
+ * the new done index
+ */
+#define CLEAR_LE_OWN_FROM_DONE_TO(pTable, To) {					\
+		int i;													\
+		i = (pTable)->Done;										\
+		while (i != To) {										\
+			CLEAR_LE_OWN(pTable, i);							\
+			i = (i + 1) % NUM_LE_IN_TABLE(pTable);				\
+		}														\
+	}
+
+#else	/* !SAFE_BUT_SLOW */
+
+#define CHECK_STLE_OVERFLOW(pTable, IsOk)
+#define CLEAR_LE_OWN(pTable, Idx)
+#define CLEAR_LE_OWN_FROM_DONE_TO(pTable, To)
+
+#endif	/* !SAFE_BUT_SLOW */
+
+
+/* typedefs *******************************************************************/
+
+typedef struct s_LetRxTx {
+	SK_U16	VlanId;			/* VLAN Id given down last time */
+	SK_U16	TcpWp;			/* TCP Checksum Write Position */
+	SK_U16	TcpSp1;			/* TCP Checksum Calculation Start Position 1 */
+	SK_U16	TcpSp2;			/* TCP Checksum Calculation Start Position 2 */
+	SK_U16	MssValue;		/* Maximum Segment Size */
+	SK_U16	Reserved1;		/* reserved word for furture extensions */
+	SK_U16	Reserved2;		/* reserved word for furture extensions */
+	SK_U16	Reserved3;		/* reserved word for furture extensions */
+} SK_LET_RX_TX;
+
+typedef struct s_LetStat {
+	SK_U32	RxTimeStamp;	/* Receive Timestamp */
+	SK_U32	RssHashValue;	/* RSS Hash Value */
+	SK_BOOL	RssIsIp;		/* RSS Hash Value: IP packet detected */
+	SK_BOOL	RssIsTcp;		/* RSS Hash Value: IP+TCP packet detected */
+	SK_U16	VlanId;			/* VLAN Id given received by Status BMU */
+	SK_U16	TcpSum1;		/* TCP checksum 1 (status BMU) */
+	SK_U16	TcpSum2;		/* TCP checksum 2 (status BMU) */
+} SK_LET_STAT;
+
+
+typedef union s_LetBmuSpec {
+	SK_LET_RX_TX	RxTx;	/* Rx/Tx BMU specific variables */
+	SK_LET_STAT		Stat;	/* Status BMU specific variables */
+} SK_LET_BMU_S;
+
+
+
+typedef	struct s_le_table SK_LE_TABLE;
+
+struct s_le_table {
+	/* all LE's between Done and HWPut are owned by the hardware */
+	/* all LE's between Put and Done can be used from Software */
+	/* all LE's between HWPut and Put are currently processed in DriverSend */
+	unsigned Done;			/* done index - consumed from HW and available */
+	unsigned Put;			/* put index - to be given to hardware */
+	unsigned HwPut;			/* put index actually given to hardware */
+	unsigned Num;			/* total number of list elements */
+	SK_HWLE *pLETab;		/* virtual address of list element table */
+	SK_U32	pPhyLETABLow;	/* physical address of list element table */
+	SK_U32	pPhyLETABHigh;	/* physical address of list element table */
+	/* values to remember in order to save some LEs */
+	SK_U32	BufHighAddr;	/* high addr given down last time */
+	SK_LET_BMU_S Bmu;		/* contains BMU specific information */
+	SK_U32	private;		/* driver private variable free usable */
+	SK_U16	TcpInitCsum;	/* Init. Checksum */
+};
+
+/* function prototypes ********************************************************/
+
+#ifndef	SK_KR_PROTO
+
+/*
+ * public functions in sky2le.c
+ */
+extern void SkGeY2SetPutIndex(
+	SK_AC	*pAC,
+	SK_IOC	IoC,
+	SK_U32 StartAddrPrefetchUnit,
+	SK_LE_TABLE *pLETab);
+
+extern void SkGeY2InitPrefetchUnit(
+	SK_AC	*pAC,
+	SK_IOC	IoC,
+	unsigned int Queue,
+	SK_LE_TABLE *pLETab);
+
+extern void SkGeY2InitStatBmu(
+	SK_AC	*pAC,
+	SK_IOC	IoC,
+	SK_LE_TABLE *pLETab);
+
+extern void SkGeY2InitPollUnit(
+	SK_AC	*pAC,
+	SK_IOC	IoC,
+	SK_LE_TABLE *pLETab);
+
+extern void SkGeY2InitSingleLETable(
+	SK_AC	*pAC,
+	SK_LE_TABLE *pLETab,
+	unsigned int NumLE,
+	void	*pVMem,
+	SK_U32	PMemLowAddr,
+	SK_U32	PMemHighAddr);
+
+#else	/* SK_KR_PROTO */
+extern void SkGeY2SetPutIndex();
+extern void SkGeY2InitPrefetchUnit();
+extern void SkGeY2InitStatBmu();
+extern void SkGeY2InitPollUnit();
+extern void SkGeY2InitSingleLETable();
+#endif	/* SK_KR_PROTO */
+
+#ifdef __cplusplus
+}
+#endif	/* __cplusplus */
+
+#endif	/* __INC_SKY2LE_H */
+
diff -urN linux-2.4.29/drivers/net/sk98lin/h/xmac_ii.h linux-2.4.29-uc1/drivers/net/sk98lin/h/xmac_ii.h
--- linux-2.4.29/drivers/net/sk98lin/h/xmac_ii.h	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/h/xmac_ii.h	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	xmac_ii.h
  * Project:	Gigabit Ethernet Adapters, Common Modules
+ * Version:	$Revision: 2.7 $
+ * Date:	$Date: 2004/07/02 15:01:01 $
  * Purpose:	Defines and Macros for Gigabit Ethernet Controller
  *
  ******************************************************************************/
@@ -9,13 +11,12 @@
 /******************************************************************************
  *
  *	(C)Copyright 1998-2002 SysKonnect.
- *	(C)Copyright 2002-2003 Marvell.
+ *	(C)Copyright 2002-2004 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
  *	the Free Software Foundation; either version 2 of the License, or
  *	(at your option) any later version.
- *
  *	The information in this file is provided "AS IS" without warranty.
  *
  ******************************************************************************/
@@ -447,7 +448,7 @@
 /*
  * Receive Frame Status Encoding
  */
-#define XMR_FS_LEN	(0x3fffUL<<18)	/* Bit 31..18:	Rx Frame Length */
+#define XMR_FS_LEN_MSK	(0x3fffUL<<18)	/* Bit 31..18:	Rx Frame Length */
 #define XMR_FS_2L_VLAN	(1L<<17)	/* Bit 17:	tagged wh 2Lev VLAN ID*/
 #define XMR_FS_1L_VLAN	(1L<<16)	/* Bit 16:	tagged wh 1Lev VLAN ID*/
 #define XMR_FS_BC		(1L<<15)	/* Bit 15:	Broadcast Frame */
@@ -467,6 +468,8 @@
 #define XMR_FS_ERR		(1L<<1)		/* Bit  1:	Frame Error */
 #define XMR_FS_MCTRL	(1L<<0)		/* Bit  0:	MAC Control Packet */
 
+#define XMR_FS_LEN_SHIFT	18
+
 /*
  * XMR_FS_ERR will be set if
  *	XMR_FS_FCS_ERR, XMR_FS_LNG_ERR, XMR_FS_RUNT,
@@ -508,7 +511,7 @@
 #define PHY_BCOM_NEPG		0x07	/* 16 bit r/w	Next Page Register */
 #define PHY_BCOM_NEPG_LP	0x08	/* 16 bit r/o	Next Page Link Partner */
 	/* Broadcom-specific registers */
-#define PHY_BCOM_1000T_CTRL	0x09	/* 16 bit r/w	1000Base-T Ctrl Reg */
+#define PHY_BCOM_1000T_CTRL	0x09	/* 16 bit r/w	1000Base-T Control Reg */
 #define PHY_BCOM_1000T_STAT	0x0a	/* 16 bit r/o	1000Base-T Status Reg */
 	/* 0x0b - 0x0e:		reserved */
 #define PHY_BCOM_EXT_STAT	0x0f	/* 16 bit r/o	Extended Status Reg */
@@ -539,7 +542,7 @@
 #define PHY_MARV_NEPG		0x07	/* 16 bit r/w	Next Page Register */
 #define PHY_MARV_NEPG_LP	0x08	/* 16 bit r/o	Next Page Link Partner */
 	/* Marvel-specific registers */
-#define PHY_MARV_1000T_CTRL	0x09	/* 16 bit r/w	1000Base-T Ctrl Reg */
+#define PHY_MARV_1000T_CTRL	0x09	/* 16 bit r/w	1000Base-T Control Reg */
 #define PHY_MARV_1000T_STAT	0x0a	/* 16 bit r/o	1000Base-T Status Reg */
 	/* 0x0b - 0x0e:		reserved */
 #define PHY_MARV_EXT_STAT	0x0f	/* 16 bit r/o	Extended Status Reg */
@@ -550,13 +553,21 @@
 #define PHY_MARV_EXT_CTRL	0x14	/* 16 bit r/w	Ext. PHY Specific Ctrl */
 #define PHY_MARV_RXE_CNT	0x15	/* 16 bit r/w	Receive Error Counter */
 #define PHY_MARV_EXT_ADR	0x16	/* 16 bit r/w	Ext. Ad. for Cable Diag. */
-	/* 0x17:		reserved */
+#define PHY_MARV_PORT_IRQ	0x17	/* 16 bit r/o	Port 0 IRQ (88E1111 only) */
 #define PHY_MARV_LED_CTRL	0x18	/* 16 bit r/w	LED Control Reg */
 #define PHY_MARV_LED_OVER	0x19	/* 16 bit r/w	Manual LED Override Reg */
 #define PHY_MARV_EXT_CTRL_2	0x1a	/* 16 bit r/w	Ext. PHY Specific Ctrl 2 */
 #define PHY_MARV_EXT_P_STAT	0x1b	/* 16 bit r/w	Ext. PHY Spec. Stat Reg */
 #define PHY_MARV_CABLE_DIAG	0x1c	/* 16 bit r/o	Cable Diagnostic Reg */
-	/* 0x1d - 0x1f:		reserved */
+#define PHY_MARV_PAGE_ADDR	0x1d	/* 16 bit r/w	Extended Page Address Reg */
+#define PHY_MARV_PAGE_DATA	0x1e	/* 16 bit r/w	Extended Page Data Reg */
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+#define PHY_MARV_FE_LED_PAR	0x16	/* 16 bit r/w	LED Parallel Select Reg. */
+#define PHY_MARV_FE_LED_SER	0x17	/* 16 bit r/w	LED Stream Select S. LED */
+#define PHY_MARV_FE_VCT_TX	0x1a	/* 16 bit r/w	VCT Reg. for TXP/N Pins */
+#define PHY_MARV_FE_VCT_RX	0x1b	/* 16 bit r/o	VCT Reg. for RXP/N Pins */
+#define PHY_MARV_FE_SPEC_2	0x1c	/* 16 bit r/w	Specific Control Reg. 2 */
 
 /*----------------------------------------------------------------------------*/
 /*
@@ -572,7 +583,7 @@
 #define PHY_LONE_NEPG		0x07	/* 16 bit r/w	Next Page Register */
 #define PHY_LONE_NEPG_LP	0x08	/* 16 bit r/o	Next Page Link Partner */
 	/* Level One-specific registers */
-#define PHY_LONE_1000T_CTRL	0x09	/* 16 bit r/w	1000Base-T Control Reg*/
+#define PHY_LONE_1000T_CTRL	0x09	/* 16 bit r/w	1000Base-T Control Reg */
 #define PHY_LONE_1000T_STAT	0x0a	/* 16 bit r/o	1000Base-T Status Reg */
 	/* 0x0b -0x0e:		reserved */
 #define PHY_LONE_EXT_STAT	0x0f	/* 16 bit r/o	Extended Status Reg */
@@ -616,7 +627,7 @@
 
 /*
  * PHY bit definitions
- * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are
+ * Bits defined as PHY_X_..., PHY_B_..., PHY_L_..., PHY_N_... or PHY_M_... are
  * XMAC/Broadcom/LevelOne/National/Marvell-specific.
  * All other are general.
  */
@@ -627,14 +638,14 @@
 /*****  PHY_LONE_CTRL	16 bit r/w	PHY Control Register *****/
 #define PHY_CT_RESET	(1<<15)	/* Bit 15: (sc)	clear all PHY related regs */
 #define PHY_CT_LOOP		(1<<14)	/* Bit 14:	enable Loopback over PHY */
-#define PHY_CT_SPS_LSB	(1<<13) /* Bit 13: (BC,L1) Speed select, lower bit */
+#define PHY_CT_SPS_LSB	(1<<13) /* Bit 13:  Speed select, lower bit */
 #define PHY_CT_ANE		(1<<12)	/* Bit 12:	Auto-Negotiation Enabled */
-#define PHY_CT_PDOWN	(1<<11)	/* Bit 11: (BC,L1) Power Down Mode */
-#define PHY_CT_ISOL		(1<<10)	/* Bit 10: (BC,L1) Isolate Mode */
+#define PHY_CT_PDOWN	(1<<11)	/* Bit 11:  Power Down Mode */
+#define PHY_CT_ISOL		(1<<10)	/* Bit 10:  Isolate Mode */
 #define PHY_CT_RE_CFG	(1<<9)	/* Bit  9: (sc) Restart Auto-Negotiation */
 #define PHY_CT_DUP_MD	(1<<8)	/* Bit  8:	Duplex Mode */
-#define PHY_CT_COL_TST	(1<<7)	/* Bit  7: (BC,L1) Collision Test enabled */
-#define PHY_CT_SPS_MSB	(1<<6)	/* Bit  6: (BC,L1) Speed select, upper bit */
+#define PHY_CT_COL_TST	(1<<7)	/* Bit  7:  Collision Test enabled */
+#define PHY_CT_SPS_MSB	(1<<6)	/* Bit  6:  Speed select, upper bit */
 								/* Bit  5..0:	reserved */
 
 #define PHY_CT_SP1000	PHY_CT_SPS_MSB	/* enable speed of 1000 Mbps */
@@ -647,15 +658,15 @@
 /*****  PHY_MARV_STAT	16 bit r/w	PHY Status Register *****/
 /*****  PHY_LONE_STAT	16 bit r/w	PHY Status Register *****/
 								/* Bit 15..9:	reserved */
-				/*	(BC/L1) 100/10 Mbps cap bits ignored*/
+				/*	(BC/L1) 100/10 Mbps cap bits ignored */
 #define PHY_ST_EXT_ST	(1<<8)	/* Bit  8:	Extended Status Present */
 								/* Bit  7:	reserved */
-#define PHY_ST_PRE_SUP	(1<<6)	/* Bit  6: (BC/L1) preamble suppression */
+#define PHY_ST_PRE_SUP	(1<<6)	/* Bit  6:  Preamble Suppression */
 #define PHY_ST_AN_OVER	(1<<5)	/* Bit  5:	Auto-Negotiation Over */
 #define PHY_ST_REM_FLT	(1<<4)	/* Bit  4:	Remote Fault Condition Occured */
 #define PHY_ST_AN_CAP	(1<<3)	/* Bit  3:	Auto-Negotiation Capability */
 #define PHY_ST_LSYNC	(1<<2)	/* Bit  2:	Link Synchronized */
-#define PHY_ST_JAB_DET	(1<<1)	/* Bit  1: (BC/L1) Jabber Detected */
+#define PHY_ST_JAB_DET	(1<<1)	/* Bit  1:  Jabber Detected */
 #define PHY_ST_EXT_REG	(1<<0)	/* Bit  0:	Extended Register available */
 
 
@@ -665,7 +676,7 @@
 /*****	PHY_LONE_ID1		16 bit r/o	PHY ID1 Register */
 #define PHY_I1_OUI_MSK	(0x3f<<10)	/* Bit 15..10:	Organization Unique ID */
 #define PHY_I1_MOD_NUM	(0x3f<<4)	/* Bit  9.. 4:	Model Number */
-#define PHY_I1_REV_MSK	0x0f		/* Bit  3.. 0:	Revision Number */
+#define PHY_I1_REV_MSK	0xf			/* Bit  3.. 0:	Revision Number */
 
 /* different Broadcom PHY Ids */
 #define PHY_BCOM_ID1_A1		0x6041
@@ -979,7 +990,7 @@
 #define PHY_L_QS_DUP_MOD	(1<<9)	/* Bit  9:	Full/Half Duplex */
 #define PHY_L_QS_AN			(1<<8)	/* Bit  8:	AutoNeg is On */
 #define PHY_L_QS_AN_C		(1<<7)	/* Bit  7:	AN is Complete */
-#define PHY_L_QS_LLE		(7<<4)	/* Bit  6:	Line Length Estim. */
+#define PHY_L_QS_LLE		(7<<4)	/* Bit  6..4:	Line Length Estim. */
 #define PHY_L_QS_PAUSE		(1<<3)	/* Bit  3:	LP advertised Pause */
 #define PHY_L_QS_AS_PAUSE	(1<<2)	/* Bit  2:	LP adv. asym. Pause */
 #define PHY_L_QS_ISOLATE	(1<<1)	/* Bit  1:	CIM Isolated */
@@ -1027,9 +1038,8 @@
 									/* Bit  9..0:	not described */
 
 /*****  PHY_LONE_CIM		16 bit r/o	CIM Reg *****/
-#define PHY_L_CIM_ISOL		(255<<8)/* Bit 15..8:	Isolate Count */
-#define PHY_L_CIM_FALSE_CAR	(255<<0)/* Bit  7..0:	False Carrier Count */
-
+#define PHY_L_CIM_ISOL		(0xff<<8)	/* Bit 15..8:	Isolate Count */
+#define PHY_L_CIM_FALSE_CAR	0xff		/* Bit  7..0:	False Carrier Count */
 
 /*
  * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding
@@ -1039,7 +1049,6 @@
 #define PHY_L_P_ASYM_MD		(2<<10)	/* Bit 11..10:	asymmetric Pause Mode */
 #define PHY_L_P_BOTH_MD		(3<<10)	/* Bit 11..10:	both Pause Mode */
 
-
 /*
  * National-Specific
  */
@@ -1084,22 +1093,24 @@
  */
 /*****  PHY_MARV_AUNE_ADV	16 bit r/w	Auto-Negotiation Advertisement *****/
 /*****  PHY_MARV_AUNE_LP	16 bit r/w	Link Part Ability Reg *****/
-#define PHY_M_AN_NXT_PG		BIT_15	/* Request Next Page */
-#define PHY_M_AN_ACK		BIT_14	/* (ro)	Acknowledge Received */
-#define PHY_M_AN_RF			BIT_13	/* Remote Fault */
-									/* Bit 12:	reserved */
-#define PHY_M_AN_ASP		BIT_11	/* Asymmetric Pause */
-#define PHY_M_AN_PC			BIT_10	/* MAC Pause implemented */
-#define PHY_M_AN_100_FD		BIT_8	/* Advertise 100Base-TX Full Duplex */
-#define PHY_M_AN_100_HD		BIT_7	/* Advertise 100Base-TX Half Duplex */
-#define PHY_M_AN_10_FD		BIT_6	/* Advertise 10Base-TX Full Duplex */
-#define PHY_M_AN_10_HD		BIT_5	/* Advertise 10Base-TX Half Duplex */
+#define PHY_M_AN_NXT_PG		BIT_15S	/* Request Next Page */
+#define PHY_M_AN_ACK		BIT_14S	/* (ro)	Acknowledge Received */
+#define PHY_M_AN_RF			BIT_13S	/* Remote Fault */
+								/* Bit 12:	reserved */
+#define PHY_M_AN_ASP		BIT_11S	/* Asymmetric Pause */
+#define PHY_M_AN_PC			BIT_10S	/* MAC Pause implemented */
+#define PHY_M_AN_100_T4		BIT_9S	/* Not cap. 100Base-T4 (always 0) */
+#define PHY_M_AN_100_FD		BIT_8S	/* Advertise 100Base-TX Full Duplex */
+#define PHY_M_AN_100_HD		BIT_7S	/* Advertise 100Base-TX Half Duplex */
+#define PHY_M_AN_10_FD		BIT_6S	/* Advertise 10Base-TX Full Duplex */
+#define PHY_M_AN_10_HD		BIT_5S	/* Advertise 10Base-TX Half Duplex */
+#define PHY_M_AN_SEL_MSK	(0x1f<<4)	/* Bit  4.. 0:	Selector Field Mask */
 
 /* special defines for FIBER (88E1011S only) */
-#define PHY_M_AN_ASP_X		BIT_8	/* Asymmetric Pause */
-#define PHY_M_AN_PC_X		BIT_7	/* MAC Pause implemented */
-#define PHY_M_AN_1000X_AHD	BIT_6	/* Advertise 10000Base-X Half Duplex */
-#define PHY_M_AN_1000X_AFD	BIT_5	/* Advertise 10000Base-X Full Duplex */
+#define PHY_M_AN_ASP_X		BIT_8S	/* Asymmetric Pause */
+#define PHY_M_AN_PC_X		BIT_7S	/* MAC Pause implemented */
+#define PHY_M_AN_1000X_AHD	BIT_6S	/* Advertise 10000Base-X Half Duplex */
+#define PHY_M_AN_1000X_AFD	BIT_5S	/* Advertise 10000Base-X Full Duplex */
 
 /* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */
 #define PHY_M_P_NO_PAUSE_X	(0<<7)	/* Bit  8.. 7:	no Pause Mode */
@@ -1109,102 +1120,144 @@
 
 /*****  PHY_MARV_1000T_CTRL	16 bit r/w	1000Base-T Control Reg *****/
 #define PHY_M_1000C_TEST	(7<<13)	/* Bit 15..13:	Test Modes */
-#define PHY_M_1000C_MSE		(1<<12)	/* Bit 12:	Manual Master/Slave Enable */
-#define PHY_M_1000C_MSC		(1<<11)	/* Bit 11:	M/S Configuration (1=Master) */
-#define PHY_M_1000C_MPD		(1<<10)	/* Bit 10:	Multi-Port Device */
-#define PHY_M_1000C_AFD		(1<<9)	/* Bit  9:	Advertise Full Duplex */
-#define PHY_M_1000C_AHD		(1<<8)	/* Bit  8:	Advertise Half Duplex */
+#define PHY_M_1000C_MSE		BIT_12S	/* Manual Master/Slave Enable */
+#define PHY_M_1000C_MSC		BIT_11S	/* M/S Configuration (1=Master) */
+#define PHY_M_1000C_MPD		BIT_10S	/* Multi-Port Device */
+#define PHY_M_1000C_AFD		BIT_9S	/* Advertise Full Duplex */
+#define PHY_M_1000C_AHD		BIT_8S	/* Advertise Half Duplex */
 									/* Bit  7..0:	reserved */
 
 /*****  PHY_MARV_PHY_CTRL	16 bit r/w	PHY Specific Ctrl Reg *****/
 #define PHY_M_PC_TX_FFD_MSK	(3<<14)	/* Bit 15..14:	Tx FIFO Depth Mask */
 #define PHY_M_PC_RX_FFD_MSK	(3<<12)	/* Bit 13..12:	Rx FIFO Depth Mask */
-#define PHY_M_PC_ASS_CRS_TX	(1<<11)	/* Bit 11:	Assert CRS on Transmit */
-#define PHY_M_PC_FL_GOOD	(1<<10)	/* Bit 10:	Force Link Good */
+#define PHY_M_PC_ASS_CRS_TX	BIT_11S	/* Assert CRS on Transmit */
+#define PHY_M_PC_FL_GOOD	BIT_10S	/* Force Link Good */
 #define PHY_M_PC_EN_DET_MSK	(3<<8)	/* Bit  9.. 8:	Energy Detect Mask */
-#define PHY_M_PC_ENA_EXT_D	(1<<7)	/* Bit  7:	Enable Ext. Distance (10BT) */
+#define PHY_M_PC_ENA_EXT_D	BIT_7S	/* Enable Ext. Distance (10BT) */
 #define PHY_M_PC_MDIX_MSK	(3<<5)	/* Bit  6.. 5:	MDI/MDIX Config. Mask */
-#define PHY_M_PC_DIS_125CLK	(1<<4)	/* Bit  4:	Disable 125 CLK */
-#define PHY_M_PC_MAC_POW_UP	(1<<3)	/* Bit  3:	MAC Power up */
-#define PHY_M_PC_SQE_T_ENA	(1<<2)	/* Bit  2:	SQE Test Enabled */
-#define PHY_M_PC_POL_R_DIS	(1<<1)	/* Bit  1:	Polarity Reversal Disabled */
-#define PHY_M_PC_DIS_JABBER	(1<<0)	/* Bit  0:	Disable Jabber */
+#define PHY_M_PC_DIS_125CLK	BIT_4S	/* Disable 125 CLK */
+#define PHY_M_PC_MAC_POW_UP	BIT_3S	/* MAC Power up */
+#define PHY_M_PC_SQE_T_ENA	BIT_2S	/* SQE Test Enabled */
+#define PHY_M_PC_POL_R_DIS	BIT_1S	/* Polarity Reversal Disabled */
+#define PHY_M_PC_DIS_JABBER	BIT_0S	/* Disable Jabber */
 
 #define PHY_M_PC_EN_DET			SHIFT8(2)	/* Energy Detect (Mode 1) */
 #define PHY_M_PC_EN_DET_PLUS	SHIFT8(3)	/* Energy Detect Plus (Mode 2) */
 
-#define PHY_M_PC_MDI_XMODE(x)	SHIFT5(x)	
+#define PHY_M_PC_MDI_XMODE(x)	(SHIFT5(x) & PHY_M_PC_MDIX_MSK)	
+
 #define PHY_M_PC_MAN_MDI	0    	/* 00 = Manual MDI configuration */
 #define PHY_M_PC_MAN_MDIX	1		/* 01 = Manual MDIX configuration */
 #define PHY_M_PC_ENA_AUTO	3		/* 11 = Enable Automatic Crossover */
 
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+#define PHY_M_PC_ENA_DTE_DT	BIT_15S	/* Enable Data Terminal Equ. (DTE) Detect */
+#define PHY_M_PC_ENA_ENE_DT	BIT_14S	/* Enable Energy Detect (sense & pulse) */
+#define PHY_M_PC_DIS_NLP_CK	BIT_13S	/* Disable Normal Link Puls (NLP) Check */
+#define PHY_M_PC_ENA_LIP_NP	BIT_12S	/* Enable Link Partner Next Page Reg. */
+#define PHY_M_PC_DIS_NLP_GN	BIT_11S	/* Disable Normal Link Puls Generation */
+
+#define PHY_M_PC_DIS_SCRAMB	BIT_9S	/* Disable Scrambler */
+#define PHY_M_PC_DIS_FEFI	BIT_8S	/* Disable Far End Fault Indic. (FEFI) */
+
+#define PHY_M_PC_SH_TP_SEL	BIT_6S	/* Shielded Twisted Pair Select */
+#define PHY_M_PC_RX_FD_MSK	(3<<2)	/* Bit  3.. 2:	Rx FIFO Depth Mask */
+
 /*****  PHY_MARV_PHY_STAT	16 bit r/o	PHY Specific Status Reg *****/
 #define PHY_M_PS_SPEED_MSK	(3<<14)	/* Bit 15..14:	Speed Mask */
-#define PHY_M_PS_SPEED_1000	(1<<15)	/*       10 = 1000 Mbps */
-#define PHY_M_PS_SPEED_100	(1<<14)	/*       01 =  100 Mbps */
+#define PHY_M_PS_SPEED_1000	BIT_15S	/*       10 = 1000 Mbps */
+#define PHY_M_PS_SPEED_100	BIT_14S	/*       01 =  100 Mbps */
 #define PHY_M_PS_SPEED_10	0		/*       00 =   10 Mbps */
-#define PHY_M_PS_FULL_DUP	(1<<13)	/* Bit 13:	Full Duplex */
-#define PHY_M_PS_PAGE_REC	(1<<12)	/* Bit 12:	Page Received */
-#define PHY_M_PS_SPDUP_RES	(1<<11)	/* Bit 11:	Speed & Duplex Resolved */
-#define PHY_M_PS_LINK_UP	(1<<10)	/* Bit 10:	Link Up */
-#define PHY_M_PS_CABLE_MSK	(3<<7)	/* Bit  9.. 7:	Cable Length Mask */
-#define PHY_M_PS_MDI_X_STAT	(1<<6)	/* Bit  6:	MDI Crossover Stat (1=MDIX) */
-#define PHY_M_PS_DOWNS_STAT	(1<<5)	/* Bit  5:	Downshift Status (1=downsh.) */
-#define PHY_M_PS_ENDET_STAT	(1<<4)	/* Bit  4:	Energy Detect Status (1=act) */
-#define PHY_M_PS_TX_P_EN	(1<<3)	/* Bit  3:	Tx Pause Enabled */
-#define PHY_M_PS_RX_P_EN	(1<<2)	/* Bit  2:	Rx Pause Enabled */
-#define PHY_M_PS_POL_REV	(1<<1)	/* Bit  1:	Polarity Reversed */
-#define PHY_M_PC_JABBER		(1<<0)	/* Bit  0:	Jabber */
+#define PHY_M_PS_FULL_DUP	BIT_13S	/* Full Duplex */
+#define PHY_M_PS_PAGE_REC	BIT_12S	/* Page Received */
+#define PHY_M_PS_SPDUP_RES	BIT_11S	/* Speed & Duplex Resolved */
+#define PHY_M_PS_LINK_UP	BIT_10S	/* Link Up */
+#define PHY_M_PS_CABLE_MSK	(7<<7)	/* Bit  9.. 7:  Cable Length Mask */
+#define PHY_M_PS_MDI_X_STAT	BIT_6S	/* MDI Crossover Stat (1=MDIX) */
+#define PHY_M_PS_DOWNS_STAT	BIT_5S	/* Downshift Status (1=downsh.) */
+#define PHY_M_PS_ENDET_STAT	BIT_4S	/* Energy Detect Status (1=act) */
+#define PHY_M_PS_TX_P_EN	BIT_3S	/* Tx Pause Enabled */
+#define PHY_M_PS_RX_P_EN	BIT_2S	/* Rx Pause Enabled */
+#define PHY_M_PS_POL_REV	BIT_1S	/* Polarity Reversed */
+#define PHY_M_PS_JABBER		BIT_0S	/* Jabber */
 
 #define PHY_M_PS_PAUSE_MSK	(PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN)
 
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+#define PHY_M_PS_DTE_DETECT	BIT_15S	/* Data Terminal Equipment (DTE) Detected */
+#define PHY_M_PS_RES_SPEED	BIT_14S	/* Resolved Speed (1=100 Mbps, 0=10 Mbps */
+	
 /*****  PHY_MARV_INT_MASK	16 bit r/w	Interrupt Mask Reg *****/
 /*****  PHY_MARV_INT_STAT	16 bit r/o	Interrupt Status Reg *****/
-#define PHY_M_IS_AN_ERROR	(1<<15)	/* Bit 15:	Auto-Negotiation Error */
-#define PHY_M_IS_LSP_CHANGE	(1<<14)	/* Bit 14:	Link Speed Changed */
-#define PHY_M_IS_DUP_CHANGE	(1<<13)	/* Bit 13:	Duplex Mode Changed */
-#define PHY_M_IS_AN_PR		(1<<12)	/* Bit 12:	Page Received */
-#define PHY_M_IS_AN_COMPL	(1<<11)	/* Bit 11:	Auto-Negotiation Completed */
-#define PHY_M_IS_LST_CHANGE	(1<<10)	/* Bit 10:	Link Status Changed */
-#define PHY_M_IS_SYMB_ERROR	(1<<9)	/* Bit  9:	Symbol Error */
-#define PHY_M_IS_FALSE_CARR	(1<<8)	/* Bit  8:	False Carrier */
-#define PHY_M_IS_FIFO_ERROR	(1<<7)	/* Bit  7:	FIFO Overflow/Underrun Error */
-#define PHY_M_IS_MDI_CHANGE	(1<<6)	/* Bit  6:	MDI Crossover Changed */
-#define PHY_M_IS_DOWNSH_DET	(1<<5)	/* Bit  5:	Downshift Detected */
-#define PHY_M_IS_END_CHANGE	(1<<4)	/* Bit  4:	Energy Detect Changed */
-									/* Bit  3..2:	reserved */
-#define PHY_M_IS_POL_CHANGE	(1<<1)	/* Bit  1:	Polarity Changed */
-#define PHY_M_IS_JABBER		(1<<0)	/* Bit  0:	Jabber */
+#define PHY_M_IS_AN_ERROR	BIT_15S	/* Auto-Negotiation Error */
+#define PHY_M_IS_LSP_CHANGE	BIT_14S	/* Link Speed Changed */
+#define PHY_M_IS_DUP_CHANGE	BIT_13S	/* Duplex Mode Changed */
+#define PHY_M_IS_AN_PR		BIT_12S	/* Page Received */
+#define PHY_M_IS_AN_COMPL	BIT_11S	/* Auto-Negotiation Completed */
+#define PHY_M_IS_LST_CHANGE	BIT_10S	/* Link Status Changed */
+#define PHY_M_IS_SYMB_ERROR	BIT_9S	/* Symbol Error */
+#define PHY_M_IS_FALSE_CARR	BIT_8S	/* False Carrier */
+#define PHY_M_IS_FIFO_ERROR	BIT_7S	/* FIFO Overflow/Underrun Error */
+#define PHY_M_IS_MDI_CHANGE	BIT_6S	/* MDI Crossover Changed */
+#define PHY_M_IS_DOWNSH_DET	BIT_5S	/* Downshift Detected */
+#define PHY_M_IS_END_CHANGE	BIT_4S	/* Energy Detect Changed */
+								/* Bit   3:	reserved */
+#define PHY_M_IS_DTE_CHANGE	BIT_2S	/* DTE Power Det. Status Changed */
+									/* (88E1111 only) */
+#define PHY_M_IS_POL_CHANGE	BIT_1S	/* Polarity Changed */
+#define PHY_M_IS_JABBER		BIT_0S	/* Jabber */
 
 #define PHY_M_DEF_MSK		(PHY_M_IS_AN_ERROR | PHY_M_IS_AN_PR | \
 							PHY_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR)
 
 /*****  PHY_MARV_EXT_CTRL	16 bit r/w	Ext. PHY Specific Ctrl *****/
-#define PHY_M_EC_M_DSC_MSK	(3<<10)	/* Bit 11..10:	Master downshift counter */
-#define PHY_M_EC_S_DSC_MSK	(3<<8)	/* Bit  9.. 8:	Slave  downshift counter */
+#define PHY_M_EC_ENA_BC_EXT	BIT_15S	/* Enable Block Carr. Ext. (88E1111 only) */
+#define PHY_M_EC_ENA_LIN_LB	BIT_14S	/* Enable Line Loopback (88E1111 only) */
+								/* Bit 13:	reserved */
+#define PHY_M_EC_DIS_LINK_P	BIT_12S	/* Disable Link Pulses (88E1111 only) */
+#define PHY_M_EC_M_DSC_MSK	(3<<10)	/* Bit 11..10:	Master Downshift Counter */
+									/* (88E1011 only) */
+#define PHY_M_EC_S_DSC_MSK	(3<<8)	/* Bit  9.. 8:	Slave  Downshift Counter */
+									/* (88E1011 only) */
+#define PHY_M_EC_M_DSC_MSK2	(7<<9)	/* Bit 11.. 9:	Master Downshift Counter */
+									/* (88E1111 only) */
+#define PHY_M_EC_DOWN_S_DIS	BIT_8S	/* Downshift Disable (88E1111 only) */
+#define PHY_M_EC_RX_TIM_CT	BIT_7S	/* RGMII Rx Timing Control*/
 #define PHY_M_EC_MAC_S_MSK	(7<<4)	/* Bit  6.. 4:	Def. MAC interface speed */
-#define PHY_M_EC_FIB_AN_ENA	(1<<3)	/* Bit  3:	Fiber Auto-Neg. Enable */
+#define PHY_M_EC_FIB_AN_ENA	BIT_3S	/* Fiber Auto-Neg. Enable (88E1011S only) */
+#define PHY_M_EC_DTE_D_ENA	BIT_2S	/* DTE Detect Enable (88E1111 only) */
+#define PHY_M_EC_TX_TIM_CT	BIT_1S	/* RGMII Tx Timing Control */
+#define PHY_M_EC_TRANS_DIS	BIT_0S	/* Transmitter Disable (88E1111 only) */
 
 #define PHY_M_EC_M_DSC(x)		SHIFT10(x)	/* 00=1x; 01=2x; 10=3x; 11=4x */
 #define PHY_M_EC_S_DSC(x)		SHIFT8(x)	/* 00=dis; 01=1x; 10=2x; 11=3x */
 #define PHY_M_EC_MAC_S(x)		SHIFT4(x)	/* 01X=0; 110=2.5; 111=25 (MHz) */
 
+#define PHY_M_EC_M_DSC_2(x)		SHIFT9(x)	/* 000=1x; 001=2x; 010=3x; 011=4x */
+											/* 100=5x; 101=6x; 110=7x; 111=8x */
 #define MAC_TX_CLK_0_MHZ	2
 #define MAC_TX_CLK_2_5_MHZ	6
 #define MAC_TX_CLK_25_MHZ	7
 
 /*****  PHY_MARV_LED_CTRL	16 bit r/w	LED Control Reg *****/
-#define PHY_M_LEDC_DIS_LED	(1<<15)	/* Bit 15:	Disable LED */
+#define PHY_M_LEDC_DIS_LED	BIT_15S	/* Disable LED */
 #define PHY_M_LEDC_PULS_MSK	(7<<12)	/* Bit 14..12:  Pulse Stretch Mask */
-#define PHY_M_LEDC_F_INT	(1<<11)	/* Bit 11:	Force Interrupt */
+#define PHY_M_LEDC_F_INT	BIT_11S	/* Force Interrupt */
 #define PHY_M_LEDC_BL_R_MSK	(7<<8)	/* Bit 10.. 8:  Blink Rate Mask */
-									/* Bit  7.. 5:	reserved */
+#define PHY_M_LEDC_DP_C_LSB	BIT_7S	/* Duplex Control (LSB, 88E1111 only) */
+#define PHY_M_LEDC_TX_C_LSB	BIT_6S	/* Tx Control (LSB, 88E1111 only) */
+#define PHY_M_LEDC_LK_C_MSK	(7<<3)	/* Bit  5.. 3:	Link Control Mask */
+									/* (88E1111 only) */
+								/* Bit  7.. 5:	reserved (88E1011 only) */
 #define PHY_M_LEDC_LINK_MSK	(3<<3)	/* Bit  4.. 3:	Link Control Mask */
-#define PHY_M_LEDC_DP_CTRL	(1<<2)	/* Bit  2:	Duplex Control */
-#define PHY_M_LEDC_RX_CTRL	(1<<1)	/* Bit  1:	Rx activity / Link */
-#define PHY_M_LEDC_TX_CTRL	(1<<0)	/* Bit  0:	Tx activity / Link */
+									/* (88E1011 only) */
+#define PHY_M_LEDC_DP_CTRL	BIT_2S	/* Duplex Control */
+#define PHY_M_LEDC_DP_C_MSB	BIT_2S	/* Duplex Control (MSB, 88E1111 only) */
+#define PHY_M_LEDC_RX_CTRL	BIT_1S	/* Rx Activity / Link */
+#define PHY_M_LEDC_TX_CTRL	BIT_0S	/* Tx Activity / Link */
+#define PHY_M_LEDC_TX_C_MSB	BIT_0S	/* Tx Control (MSB, 88E1111 only) */
 
-#define PHY_M_LED_PULS_DUR(x)	SHIFT12(x)	/* Pulse Stretch Duration */
+#define PHY_M_LED_PULS_DUR(x)	(SHIFT12(x) & PHY_M_LEDC_PULS_MSK)
 
 #define	PULS_NO_STR		0		/* no pulse stretching */
 #define	PULS_21MS		1		/* 21 ms to 42 ms */
@@ -1215,7 +1268,7 @@
 #define PULS_670MS		6		/* 670 ms to 1.3 s */
 #define PULS_1300MS		7		/* 1.3 s to 2.7 s */
 
-#define PHY_M_LED_BLINK_RT(x)	SHIFT8(x)	/* Blink Rate */
+#define PHY_M_LED_BLINK_RT(x)	(SHIFT8(x) & PHY_M_LEDC_BL_R_MSK)
 
 #define BLINK_42MS		0		/* 42 ms */
 #define BLINK_84MS		1		/* 84 ms */
@@ -1225,6 +1278,8 @@
 								/* values 5 - 7: reserved */
 
 /*****  PHY_MARV_LED_OVER	16 bit r/w	Manual LED Override Reg *****/
+#define PHY_M_LED_MO_SGMII(x)	SHIFT14(x)	/* Bit 15..14:  SGMII AN Timer */
+										/* Bit 13..12:	reserved */
 #define PHY_M_LED_MO_DUP(x)		SHIFT10(x)	/* Bit 11..10:  Duplex */
 #define PHY_M_LED_MO_10(x)		SHIFT8(x)	/* Bit  9.. 8:  Link 10 */
 #define PHY_M_LED_MO_100(x)		SHIFT6(x)	/* Bit  7.. 6:  Link 100 */
@@ -1238,30 +1293,35 @@
 #define MO_LED_ON			3
 
 /*****  PHY_MARV_EXT_CTRL_2	16 bit r/w	Ext. PHY Specific Ctrl 2 *****/
-									/* Bit 15.. 7:	reserved */
-#define PHY_M_EC2_FI_IMPED	(1<<6)	/* Bit  6:	Fiber Input  Impedance */
-#define PHY_M_EC2_FO_IMPED	(1<<5)	/* Bit  5:	Fiber Output Impedance */
-#define PHY_M_EC2_FO_M_CLK	(1<<4)	/* Bit  4:	Fiber Mode Clock Enable */
-#define PHY_M_EC2_FO_BOOST	(1<<3)	/* Bit  3:	Fiber Output Boost */
+								/* Bit 15.. 7:	reserved */
+#define PHY_M_EC2_FI_IMPED	BIT_6S	/* Fiber Input  Impedance */
+#define PHY_M_EC2_FO_IMPED	BIT_5S	/* Fiber Output Impedance */
+#define PHY_M_EC2_FO_M_CLK	BIT_4S	/* Fiber Mode Clock Enable */
+#define PHY_M_EC2_FO_BOOST	BIT_3S	/* Fiber Output Boost */
 #define PHY_M_EC2_FO_AM_MSK	7		/* Bit  2.. 0:	Fiber Output Amplitude */
 
 /*****	PHY_MARV_EXT_P_STAT 16 bit r/w	Ext. PHY Specific Status *****/
-#define PHY_M_FC_AUTO_SEL	(1<<15)	/* Bit 15:	Fiber/Copper Auto Sel. dis. */
-#define PHY_M_FC_AN_REG_ACC (1<<14) /* Bit 14:	Fiber/Copper Autoneg. reg acc */
-#define PHY_M_FC_RESULUTION (1<<13)	/* Bit 13:	Fiber/Copper Resulution */
-#define PHY_M_SER_IF_AN_BP  (1<<12) /* Bit 12:	Ser IF autoneg. bypass enable */
-#define PHY_M_SER_IF_BP_ST	(1<<11) /* Bit 11:	Ser IF autoneg. bypass status */
-#define PHY_M_IRQ_POLARITY	(1<<10) /* Bit 10:	IRQ polarity */
-									/* Bit 9..4: reserved */
-#define PHY_M_UNDOC1		(1<< 7) /* undocumented bit !! */
-#define PHY_M_MODE_MASK		(0xf<<0)/* Bit 3..0: copy of HWCFG MODE[3:0] */
-
+#define PHY_M_FC_AUTO_SEL	BIT_15S	/* Fiber/Copper Auto Sel. Dis. */
+#define PHY_M_FC_AN_REG_ACC	BIT_14S	/* Fiber/Copper AN Reg. Access */
+#define PHY_M_FC_RESOLUTION	BIT_13S	/* Fiber/Copper Resolution */
+#define PHY_M_SER_IF_AN_BP	BIT_12S	/* Ser. IF AN Bypass Enable */
+#define PHY_M_SER_IF_BP_ST	BIT_11S	/* Ser. IF AN Bypass Status */
+#define PHY_M_IRQ_POLARITY	BIT_10S	/* IRQ polarity */
+#define PHY_M_DIS_AUT_MED	BIT_9S	/* Disable Aut. Medium Reg. Selection */
+									/* (88E1111 only) */
+								/* Bit  9.. 4: reserved (88E1011 only) */
+#define PHY_M_UNDOC1		BIT_7S	/* undocumented bit !! */
+#define PHY_M_DTE_POW_STAT	BIT_4S	/* DTE Power Status (88E1111 only) */
+#define PHY_M_MODE_MASK		0xf		/* Bit  3.. 0: copy of HWCFG MODE[3:0] */
 
 /*****  PHY_MARV_CABLE_DIAG	16 bit r/o	Cable Diagnostic Reg *****/
-#define PHY_M_CABD_ENA_TEST	(1<<15)	/* Bit 15:	Enable Test */
-#define PHY_M_CABD_STAT_MSK	(3<<13)	/* Bit 14..13:	Status */
-									/* Bit 12.. 8:	reserved */
-#define PHY_M_CABD_DIST_MSK	0xff	/* Bit  7.. 0:	Distance */
+#define PHY_M_CABD_ENA_TEST	BIT_15S		/* Enable Test (Page 0) */
+#define PHY_M_CABD_DIS_WAIT	BIT_15S		/* Disable Waiting Period (Page 1) */
+										/* (88E1111 only) */
+#define PHY_M_CABD_STAT_MSK	(3<<13)		/* Bit 14..13:	Status Mask */
+#define PHY_M_CABD_AMPL_MSK	(0x1f<<8)	/* Bit 12.. 8:	Amplitude Mask */
+										/* (88E1111 only) */
+#define PHY_M_CABD_DIST_MSK	0xff		/* Bit  7.. 0:	Distance Mask */
 
 /* values for Cable Diagnostic Status (11=fail; 00=OK; 10=open; 01=short) */
 #define CABD_STAT_NORMAL	0
@@ -1269,6 +1329,38 @@
 #define CABD_STAT_OPEN		2
 #define CABD_STAT_FAIL		3
 
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+/*****  PHY_MARV_FE_LED_PAR		16 bit r/w	LED Parallel Select Reg. *****/
+									/* Bit 15..12: reserved (used internally) */
+#define PHY_M_FELP_LED2_MSK	(0xf<<8)	/* Bit 11.. 8:	LED2 Mask (LINK) */
+#define PHY_M_FELP_LED1_MSK	(0xf<<4)	/* Bit  7.. 4:	LED1 Mask (ACT) */
+#define PHY_M_FELP_LED0_MSK	0xf			/* Bit  3.. 0:	LED0 Mask (SPEED) */
+
+#define PHY_M_FELP_LED2_CTRL(x)	(SHIFT8(x) & PHY_M_FELP_LED2_MSK)
+#define PHY_M_FELP_LED1_CTRL(x)	(SHIFT4(x) & PHY_M_FELP_LED1_MSK)
+#define PHY_M_FELP_LED0_CTRL(x)	(SHIFT0(x) & PHY_M_FELP_LED0_MSK)
+
+#define LED_PAR_CTRL_COLX	0x00
+#define LED_PAR_CTRL_ERROR	0x01
+#define LED_PAR_CTRL_DUPLEX	0x02
+#define LED_PAR_CTRL_DP_COL	0x03
+#define LED_PAR_CTRL_SPEED	0x04
+#define LED_PAR_CTRL_LINK	0x05
+#define LED_PAR_CTRL_TX		0x06
+#define LED_PAR_CTRL_RX		0x07
+#define LED_PAR_CTRL_ACT	0x08
+#define LED_PAR_CTRL_LNK_RX	0x09
+#define LED_PAR_CTRL_LNK_AC	0x0a
+#define LED_PAR_CTRL_ACT_BL	0x0b
+#define LED_PAR_CTRL_TX_BL	0x0c
+#define LED_PAR_CTRL_RX_BL	0x0d
+#define LED_PAR_CTRL_COL_BL	0x0e
+#define LED_PAR_CTRL_INACT	0x0f
+
+/*****  PHY_MARV_FE_SPEC_2		16 bit r/w	Specific Control Reg. 2 *****/
+#define PHY_M_FESC_DIS_WAIT	BIT_2S		/* Disable TDR Waiting Period */
+#define PHY_M_FESC_ENA_MCLK	BIT_1S		/* Enable MAC Rx Clock in sleep mode */
+#define PHY_M_FESC_SEL_CL_A	BIT_0S		/* Select Class A driver (100B-TX) */
 
 /*
  * GMAC registers
@@ -1429,141 +1521,158 @@
  */
 
 /*	GM_GP_STAT	16 bit r/o	General Purpose Status Register */
-#define GM_GPSR_SPEED		(1<<15) /* Bit 15:	Port Speed (1 = 100 Mbps) */
-#define GM_GPSR_DUPLEX		(1<<14) /* Bit 14:	Duplex Mode (1 = Full) */
-#define GM_GPSR_FC_TX_DIS	(1<<13) /* Bit 13:	Tx Flow-Control Mode Disabled */
-#define GM_GPSR_LINK_UP		(1<<12)	/* Bit 12:	Link Up Status */
-#define GM_GPSR_PAUSE		(1<<11)	/* Bit 11:	Pause State */
-#define GM_GPSR_TX_ACTIVE	(1<<10)	/* Bit 10:	Tx in Progress */
-#define GM_GPSR_EXC_COL		(1<<9)	/* Bit  9:	Excessive Collisions Occured */
-#define GM_GPSR_LAT_COL		(1<<8)	/* Bit  8:	Late Collisions Occured */
-								/* Bit  7..6:	reserved */
-#define GM_GPSR_PHY_ST_CH	(1<<5)	/* Bit  5:	PHY Status Change */
-#define GM_GPSR_GIG_SPEED	(1<<4)	/* Bit  4:	Gigabit Speed (1 = 1000 Mbps) */
-#define GM_GPSR_PART_MODE	(1<<3)	/* Bit  3:	Partition mode */
-#define GM_GPSR_FC_RX_DIS	(1<<2)	/* Bit  2:	Rx Flow-Control Mode Disabled */
-#define GM_GPSR_PROM_EN		(1<<1)	/* Bit  1:	Promiscuous Mode Enabled */
-								/* Bit  0:	reserved */
+#define GM_GPSR_SPEED		BIT_15S	/* Port Speed (1 = 100 Mbps) */
+#define GM_GPSR_DUPLEX		BIT_14S	/* Duplex Mode (1 = Full) */
+#define GM_GPSR_FC_TX_DIS	BIT_13S	/* Tx Flow-Control Mode Disabled */
+#define GM_GPSR_LINK_UP		BIT_12S	/* Link Up Status */
+#define GM_GPSR_PAUSE		BIT_11S	/* Pause State */
+#define GM_GPSR_TX_ACTIVE	BIT_10S	/* Tx in Progress */
+#define GM_GPSR_EXC_COL		BIT_9S	/* Excessive Collisions Occured */
+#define GM_GPSR_LAT_COL		BIT_8S	/* Late Collisions Occured */
+								/* Bit   7.. 6:	reserved */
+#define GM_GPSR_PHY_ST_CH	BIT_5S	/* PHY Status Change */
+#define GM_GPSR_GIG_SPEED	BIT_4S	/* Gigabit Speed (1 = 1000 Mbps) */
+#define GM_GPSR_PART_MODE	BIT_3S	/* Partition mode */
+#define GM_GPSR_FC_RX_DIS	BIT_2S	/* Rx Flow-Control Mode Disabled */
+								/* Bit   2.. 0:	reserved */
 	
 /*	GM_GP_CTRL	16 bit r/w	General Purpose Control Register */
-								/* Bit 15:	reserved */
-#define GM_GPCR_PROM_ENA	(1<<14)	/* Bit 14:	Enable Promiscuous Mode */
-#define GM_GPCR_FC_TX_DIS	(1<<13) /* Bit 13:	Disable Tx Flow-Control Mode */
-#define GM_GPCR_TX_ENA		(1<<12) /* Bit 12:	Enable Transmit */
-#define GM_GPCR_RX_ENA		(1<<11) /* Bit 11:	Enable Receive */
-#define GM_GPCR_BURST_ENA	(1<<10)	/* Bit 10:	Enable Burst Mode */
-#define GM_GPCR_LOOP_ENA	(1<<9)	/* Bit  9:	Enable MAC Loopback Mode */
-#define GM_GPCR_PART_ENA	(1<<8)	/* Bit  8:	Enable Partition Mode */
-#define GM_GPCR_GIGS_ENA	(1<<7)	/* Bit  7:	Gigabit Speed (1000 Mbps) */
-#define GM_GPCR_FL_PASS		(1<<6)	/* Bit  6:	Force Link Pass */
-#define GM_GPCR_DUP_FULL	(1<<5)	/* Bit  5:	Full Duplex Mode */
-#define GM_GPCR_FC_RX_DIS	(1<<4)	/* Bit  4:	Disable Rx Flow-Control Mode */
-#define GM_GPCR_SPEED_100	(1<<3)  /* Bit  3:	Port Speed 100 Mbps */
-#define GM_GPCR_AU_DUP_DIS	(1<<2)	/* Bit  2:	Disable Auto-Update Duplex */
-#define GM_GPCR_AU_FCT_DIS	(1<<1)	/* Bit  1:	Disable Auto-Update Flow-C. */
-#define GM_GPCR_AU_SPD_DIS	(1<<0)	/* Bit  0:	Disable Auto-Update Speed */
+#define GM_GPCR_RMII_PH_ENA	BIT_15S	/* Enable RMII for PHY (Yukon-FE only) */
+#define GM_GPCR_RMII_LB_ENA	BIT_14S	/* Enable RMII Loopback (Yukon-FE only) */
+#define GM_GPCR_FC_TX_DIS	BIT_13S	/* Disable Tx Flow-Control Mode */
+#define GM_GPCR_TX_ENA		BIT_12S	/* Enable Transmit */
+#define GM_GPCR_RX_ENA		BIT_11S	/* Enable Receive */
+								/* Bit 10:	reserved */
+#define GM_GPCR_LOOP_ENA	BIT_9S	/* Enable MAC Loopback Mode */
+#define GM_GPCR_PART_ENA	BIT_8S	/* Enable Partition Mode */
+#define GM_GPCR_GIGS_ENA	BIT_7S	/* Gigabit Speed (1000 Mbps) */
+#define GM_GPCR_FL_PASS		BIT_6S	/* Force Link Pass */
+#define GM_GPCR_DUP_FULL	BIT_5S	/* Full Duplex Mode */
+#define GM_GPCR_FC_RX_DIS	BIT_4S	/* Disable Rx Flow-Control Mode */
+#define GM_GPCR_SPEED_100	BIT_3S	/* Port Speed 100 Mbps */
+#define GM_GPCR_AU_DUP_DIS	BIT_2S	/* Disable Auto-Update Duplex */
+#define GM_GPCR_AU_FCT_DIS	BIT_1S	/* Disable Auto-Update Flow-C. */
+#define GM_GPCR_AU_SPD_DIS	BIT_0S	/* Disable Auto-Update Speed */
 
 #define GM_GPCR_SPEED_1000	(GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
 #define GM_GPCR_AU_ALL_DIS	(GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |\
 							 GM_GPCR_AU_SPD_DIS)
 	
 /*	GM_TX_CTRL				16 bit r/w	Transmit Control Register */
-#define GM_TXCR_FORCE_JAM	(1<<15)	/* Bit 15:	Force Jam / Flow-Control */
-#define GM_TXCR_CRC_DIS		(1<<14)	/* Bit 14:	Disable insertion of CRC */
-#define GM_TXCR_PAD_DIS		(1<<13)	/* Bit 13:	Disable padding of packets */
-#define GM_TXCR_COL_THR_MSK	(1<<10)	/* Bit 12..10:	Collision Threshold */
+#define GM_TXCR_FORCE_JAM	BIT_15S	/* Force Jam / Flow-Control */
+#define GM_TXCR_CRC_DIS		BIT_14S	/* Disable insertion of CRC */
+#define GM_TXCR_PAD_DIS		BIT_13S	/* Disable padding of packets */
+#define GM_TXCR_COL_THR_MSK	(7<<10)	/* Bit 12..10:	Collision Threshold Mask */
+								/* Bit   9.. 8:	reserved */
+#define GM_TXCR_PAD_PAT_MSK	0xff	/* Bit  7.. 0:	Padding Pattern Mask */
+									/* (Yukon-2 only) */
 
 #define TX_COL_THR(x)		(SHIFT10(x) & GM_TXCR_COL_THR_MSK)
 
 #define TX_COL_DEF			0x04
 	
 /*	GM_RX_CTRL				16 bit r/w	Receive Control Register */
-#define GM_RXCR_UCF_ENA		(1<<15)	/* Bit 15:	Enable Unicast filtering */
-#define GM_RXCR_MCF_ENA		(1<<14)	/* Bit 14:	Enable Multicast filtering */
-#define GM_RXCR_CRC_DIS		(1<<13)	/* Bit 13:	Remove 4-byte CRC */
-#define GM_RXCR_PASS_FC		(1<<12)	/* Bit 12:	Pass FC packets to FIFO */
+#define GM_RXCR_UCF_ENA		BIT_15S	/* Enable Unicast filtering */
+#define GM_RXCR_MCF_ENA		BIT_14S	/* Enable Multicast filtering */
+#define GM_RXCR_CRC_DIS		BIT_13S	/* Remove 4-byte CRC */
+#define GM_RXCR_PASS_FC		BIT_12S	/* Pass FC packets to FIFO (Yukon-1 only) */
+								/* Bit  11.. 0:	reserved */
 	
 /*	GM_TX_PARAM				16 bit r/w	Transmit Parameter Register */
-#define GM_TXPA_JAMLEN_MSK	(0x03<<14)	/* Bit 15..14:	Jam Length */
-#define GM_TXPA_JAMIPG_MSK	(0x1f<<9)	/* Bit 13..9:	Jam IPG */
-#define GM_TXPA_JAMDAT_MSK	(0x1f<<4)	/* Bit  8..4:	IPG Jam to Data */
-								/* Bit  3..0:	reserved */
+#define GM_TXPA_JAMLEN_MSK	(3<<14)		/* Bit 15..14:	Jam Length */
+#define GM_TXPA_JAMIPG_MSK	(0x1f<<9)	/* Bit 13.. 9:	Jam IPG */
+#define GM_TXPA_JAMDAT_MSK	(0x1f<<4)	/* Bit  8.. 4:	IPG Jam to Data */
+#define GM_TXPA_BO_LIM_MSK	0x0f		/* Bit  3.. 0:	Backoff Limit Mask */
+										/* (Yukon-2 only) */
 
 #define TX_JAM_LEN_VAL(x)	(SHIFT14(x) & GM_TXPA_JAMLEN_MSK)
 #define TX_JAM_IPG_VAL(x)	(SHIFT9(x) & GM_TXPA_JAMIPG_MSK)
 #define TX_IPG_JAM_DATA(x)	(SHIFT4(x) & GM_TXPA_JAMDAT_MSK)
+#define TX_BACK_OFF_LIM(x)	((x) & GM_TXPA_BO_LIM_MSK)
 
 #define TX_JAM_LEN_DEF		0x03
 #define TX_JAM_IPG_DEF		0x0b
 #define TX_IPG_JAM_DEF		0x1c
+#define TX_BOF_LIM_DEF		0x04
 
 /*	GM_SERIAL_MODE			16 bit r/w	Serial Mode Register */
-#define GM_SMOD_DATABL_MSK	(0x1f<<11)	/* Bit 15..11:	Data Blinder (r/o) */
-#define GM_SMOD_LIMIT_4		(1<<10)	/* Bit 10:	4 consecutive Tx trials */
-#define GM_SMOD_VLAN_ENA	(1<<9)	/* Bit  9:	Enable VLAN  (Max. Frame Len) */
-#define GM_SMOD_JUMBO_ENA	(1<<8)	/* Bit  8:	Enable Jumbo (Max. Frame Len) */
-								/* Bit  7..5:	reserved */
-#define GM_SMOD_IPG_MSK		0x1f	/* Bit 4..0:	Inter-Packet Gap (IPG) */
+#define GM_SMOD_DATABL_MSK	(0x1f<<11)	/* Bit 15..11:	Data Blinder */
+										/* r/o on Yukon, r/w on Yukon-EC */
+#define GM_SMOD_LIMIT_4		BIT_10S	/* 4 consecutive Tx trials */
+#define GM_SMOD_VLAN_ENA	BIT_9S	/* Enable VLAN  (Max. Frame Len) */
+#define GM_SMOD_JUMBO_ENA	BIT_8S	/* Enable Jumbo (Max. Frame Len) */
+								/* Bit   7.. 5:	reserved */
+#define GM_SMOD_IPG_MSK		0x1f	/* Bit  4.. 0:	Inter-Packet Gap (IPG) */
 	
 #define DATA_BLIND_VAL(x)	(SHIFT11(x) & GM_SMOD_DATABL_MSK)
-#define DATA_BLIND_DEF		0x04
+#define IPG_DATA_VAL(x)		((x) & GM_SMOD_IPG_MSK)
 
-#define IPG_DATA_VAL(x)		(x & GM_SMOD_IPG_MSK)
+#define DATA_BLIND_DEF		0x04
 #define IPG_DATA_DEF		0x1e
 
 /*	GM_SMI_CTRL				16 bit r/w	SMI Control Register */
 #define GM_SMI_CT_PHY_A_MSK	(0x1f<<11)	/* Bit 15..11:	PHY Device Address */
 #define GM_SMI_CT_REG_A_MSK	(0x1f<<6)	/* Bit 10.. 6:	PHY Register Address */
-#define GM_SMI_CT_OP_RD		(1<<5)	/* Bit  5:	OpCode Read (0=Write)*/
-#define GM_SMI_CT_RD_VAL	(1<<4)	/* Bit  4:	Read Valid (Read completed) */
-#define GM_SMI_CT_BUSY		(1<<3)	/* Bit  3:	Busy (Operation in progress) */
-								/* Bit   2..0:	reserved */
+#define GM_SMI_CT_OP_RD		BIT_5S	/* OpCode Read (0=Write)*/
+#define GM_SMI_CT_RD_VAL	BIT_4S	/* Read Valid (Read completed) */
+#define GM_SMI_CT_BUSY		BIT_3S	/* Busy (Operation in progress) */
+								/* Bit   2.. 0:	reserved */
 	
 #define GM_SMI_CT_PHY_AD(x)	(SHIFT11(x) & GM_SMI_CT_PHY_A_MSK)
 #define GM_SMI_CT_REG_AD(x)	(SHIFT6(x) & GM_SMI_CT_REG_A_MSK)
 
 	/*	GM_PHY_ADDR				16 bit r/w	GPHY Address Register */
-								/* Bit  15..6:	reserved */
-#define GM_PAR_MIB_CLR		(1<<5)	/* Bit  5:	Set MIB Clear Counter Mode */
-#define GM_PAR_MIB_TST		(1<<4)	/* Bit  4:	MIB Load Counter (Test Mode) */
-								/* Bit   3..0:	reserved */
+								/* Bit  15.. 6:	reserved */
+#define GM_PAR_MIB_CLR		BIT_5S	/* Set MIB Clear Counter Mode */
+#define GM_PAR_MIB_TST		BIT_4S	/* MIB Load Counter (Test Mode) */
+								/* Bit   3.. 0:	reserved */
 	
 /* Receive Frame Status Encoding */
-#define GMR_FS_LEN	(0xffffUL<<16)	/* Bit 31..16:	Rx Frame Length */
+#define GMR_FS_LEN_MSK	(0xffffUL<<16)	/* Bit 31..16:	Rx Frame Length */
 								/* Bit  15..14:	reserved */
-#define GMR_FS_VLAN		(1L<<13)	/* Bit 13:	VLAN Packet */
-#define GMR_FS_JABBER	(1L<<12)	/* Bit 12:	Jabber Packet */
-#define GMR_FS_UN_SIZE	(1L<<11)	/* Bit 11:	Undersize Packet */
-#define GMR_FS_MC		(1L<<10)	/* Bit 10:	Multicast Packet */
-#define GMR_FS_BC		(1L<<9)		/* Bit  9:	Broadcast Packet */
-#define GMR_FS_RX_OK	(1L<<8)		/* Bit  8:	Receive OK (Good Packet) */
-#define GMR_FS_GOOD_FC	(1L<<7)		/* Bit  7:	Good Flow-Control Packet */
-#define GMR_FS_BAD_FC	(1L<<6)		/* Bit  6:	Bad  Flow-Control Packet */
-#define GMR_FS_MII_ERR	(1L<<5)		/* Bit  5:	MII Error */
-#define GMR_FS_LONG_ERR	(1L<<4)		/* Bit  4:	Too Long Packet */
-#define GMR_FS_FRAGMENT	(1L<<3)		/* Bit  3:	Fragment */
+#define GMR_FS_VLAN			BIT_13	/* VLAN Packet */
+#define GMR_FS_JABBER		BIT_12	/* Jabber Packet */
+#define GMR_FS_UN_SIZE		BIT_11	/* Undersize Packet */
+#define GMR_FS_MC			BIT_10	/* Multicast Packet */
+#define GMR_FS_BC			BIT_9	/* Broadcast Packet */
+#define GMR_FS_RX_OK		BIT_8	/* Receive OK (Good Packet) */
+#define GMR_FS_GOOD_FC		BIT_7	/* Good Flow-Control Packet */
+#define GMR_FS_BAD_FC		BIT_6	/* Bad  Flow-Control Packet */
+#define GMR_FS_MII_ERR		BIT_5	/* MII Error */
+#define GMR_FS_LONG_ERR		BIT_4	/* Too Long Packet */
+#define GMR_FS_FRAGMENT		BIT_3	/* Fragment */
 								/* Bit  2:	reserved */
-#define GMR_FS_CRC_ERR	(1L<<1)		/* Bit  1:	CRC Error */
-#define GMR_FS_RX_FF_OV	(1L<<0)		/* Bit  0:	Rx FIFO Overflow */
+#define GMR_FS_CRC_ERR		BIT_1	/* CRC Error */
+#define GMR_FS_RX_FF_OV		BIT_0	/* Rx FIFO Overflow */
+
+#define GMR_FS_LEN_SHIFT	16
 
 /*
  * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR)
  */
-#define GMR_FS_ANY_ERR	(GMR_FS_CRC_ERR | \
-			GMR_FS_LONG_ERR | \
+#ifdef SK_DIAG
+#define GMR_FS_ANY_ERR		( \
+			GMR_FS_RX_FF_OV | \
+			GMR_FS_CRC_ERR | \
 			GMR_FS_MII_ERR | \
 			GMR_FS_BAD_FC | \
 			GMR_FS_GOOD_FC | \
 			GMR_FS_JABBER)
-
-/* Rx GMAC FIFO Flush Mask (default) */
-#define RX_FF_FL_DEF_MSK	(GMR_FS_CRC_ERR | \
+#else
+#define GMR_FS_ANY_ERR		( \
 			GMR_FS_RX_FF_OV | \
+			GMR_FS_CRC_ERR | \
+			GMR_FS_FRAGMENT | \
+			GMR_FS_LONG_ERR | \
 			GMR_FS_MII_ERR | \
 			GMR_FS_BAD_FC | \
 			GMR_FS_GOOD_FC | \
 			GMR_FS_UN_SIZE | \
 			GMR_FS_JABBER)
+#endif
+
+/* Rx GMAC FIFO Flush Mask (default) */
+#define RX_FF_FL_DEF_MSK	GMR_FS_ANY_ERR
 
 /* typedefs *******************************************************************/
 
diff -urN linux-2.4.29/drivers/net/sk98lin/Makefile linux-2.4.29-uc1/drivers/net/sk98lin/Makefile
--- linux-2.4.29/drivers/net/sk98lin/Makefile	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/sk98lin/Makefile	2005-06-14 02:12:09.000000000 +0100
@@ -1,7 +1,57 @@
-# File: drivers/sk98lin/Makefile
+#******************************************************************************
 #
-# Makefile for the SysKonnect SK-98xx device driver.
+# Name:         skge.c
+# Project:      GEnesis, PCI Gigabit Ethernet Adapter
+# Version:      $Revision: 1.9 $
+# Date:         $Date: 2004/07/13 15:54:50 $
+# Purpose:      The main driver source module
 #
+#******************************************************************************
+
+#******************************************************************************
+#
+#	(C)Copyright 1998-2002 SysKonnect GmbH.
+#	(C)Copyright 2002-2004 Marvell.
+#
+#	Makefile for Marvell Yukon chipset and SysKonnect Gigabit Ethernet 
+#	Server Adapter driver. (Kernel 2.4)
+#
+#	Author: Mirko Lindner (mlindner@syskonnect.de)
+#		Ralph Roesler (rroesler@syskonnect.de)
+#
+#	Address all question to: linux@syskonnect.de
+#
+#	This program is free software; you can redistribute it and/or modify
+#	it under the terms of the GNU General Public License as published by
+#	the Free Software Foundation; either version 2 of the License, or
+#	(at your option) any later version.
+#
+#	The information in this file is provided "AS IS" without warranty.
+# 
+#******************************************************************************
+
+#******************************************************************************
+#
+# History:
+#
+#	$Log: Makefile2.4,v $
+#	Revision 1.9  2004/07/13 15:54:50  rroesler
+#	Add: file skethtool.c
+#	Fix: corrected header regarding copyright
+#	Fix: minor typos corrected
+#	
+#	Revision 1.8  2004/06/08 08:40:36  mlindner
+#	Fix: Add CONFIG_SK98LIN_ZEROCOPY as default value
+#	
+#	Revision 1.7  2004/06/03 16:06:56  mlindner
+#	Fix: Added compile flag SK_DIAG_SUPPORT
+#	
+#	Revision 1.6  2004/06/02 08:02:59  mlindner
+#	Add: Changed header information and inserted a GPL statement
+#	
+#
+#******************************************************************************
+
 
 #
 # Standalone driver params
@@ -14,13 +64,16 @@
 
 obj-y :=	\
 		skge.o		\
+		sky2.o		\
+		skethtool.o	\
+		sky2le.o	\
 		skdim.o		\
 		skaddr.o	\
 		skgehwt.o	\
 		skgeinit.o	\
 		skgepnmi.o	\
 		skgesirq.o	\
-		ski2c.o		\
+		sktwsi.o	\
 		sklm80.o	\
 		skqueue.o	\
 		skrlmt.o	\
@@ -78,7 +131,9 @@
 # SK_DBGCAT_DRV_INT_SRC         0x04000000      interrupts sources
 # SK_DBGCAT_DRV_EVENT           0x08000000      driver events
 
-EXTRA_CFLAGS += -I. -DSK_DIAG_SUPPORT -DSK_USE_CSUM -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
+EXTRA_CFLAGS += -I. -DSK_USE_CSUM -DSK_DIAG_SUPPORT -DGENESIS \
+		-DCONFIG_SK98LIN_ZEROCOPY -DYUKON -DYUK2 \
+		$(DBGDEF) $(SKPARAM)
 
 include $(TOPDIR)/Rules.make
 
@@ -86,7 +141,3 @@
 	rm -f core *.o *.a *.s
 
 
-
-
-
-
diff -urN linux-2.4.29/drivers/net/sk98lin/skaddr.c linux-2.4.29-uc1/drivers/net/sk98lin/skaddr.c
--- linux-2.4.29/drivers/net/sk98lin/skaddr.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/skaddr.c	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skaddr.c
  * Project:	Gigabit Ethernet Adapters, ADDR-Module
+ * Version:	$Revision: 2.2 $
+ * Date:	$Date: 2003/11/24 12:22:01 $
  * Purpose:	Manage Addresses (Multicast and Unicast) and Promiscuous Mode.
  *
  ******************************************************************************/
@@ -42,7 +44,7 @@
 
 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skaddr.c,v 1.52 2003/06/02 13:46:15 tschilli Exp $ (C) Marvell.";
+	"@(#) $Id: skaddr.c,v 2.2 2003/11/24 12:22:01 mkarl Exp $ (C) Marvell.";
 #endif /* DEBUG ||!LINT || !SK_SLIM */
 
 #define __SKADDR_C
@@ -211,7 +213,7 @@
 					pAC->Addr.Net[i].PermanentMacAddress.a[2],
 					pAC->Addr.Net[i].PermanentMacAddress.a[3],
 					pAC->Addr.Net[i].PermanentMacAddress.a[4],
-					pAC->Addr.Net[i].PermanentMacAddress.a[5]))
+					pAC->Addr.Net[i].PermanentMacAddress.a[5]));
 			
 			SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
 				("Logical MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
@@ -221,7 +223,7 @@
 					pAC->Addr.Net[i].CurrentMacAddress.a[2],
 					pAC->Addr.Net[i].CurrentMacAddress.a[3],
 					pAC->Addr.Net[i].CurrentMacAddress.a[4],
-					pAC->Addr.Net[i].CurrentMacAddress.a[5]))
+					pAC->Addr.Net[i].CurrentMacAddress.a[5]));
 		}
 #endif	/* DEBUG */
 
@@ -264,7 +266,7 @@
 					pAPort->PermanentMacAddress.a[2],
 					pAPort->PermanentMacAddress.a[3],
 					pAPort->PermanentMacAddress.a[4],
-					pAPort->PermanentMacAddress.a[5]))
+					pAPort->PermanentMacAddress.a[5]));
 			
 			SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
 				("SkAddrInit: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
@@ -273,7 +275,7 @@
 					pAPort->CurrentMacAddress.a[2],
 					pAPort->CurrentMacAddress.a[3],
 					pAPort->CurrentMacAddress.a[4],
-					pAPort->CurrentMacAddress.a[5]))
+					pAPort->CurrentMacAddress.a[5]));
 #endif /* DEBUG */
 		}
 		/* pAC->Addr.InitDone = SK_INIT_IO; */
@@ -337,10 +339,14 @@
 	}
 	
 	if (pAC->GIni.GIGenesis) {
+#ifdef GENESIS
 		ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags);
+#endif
 	}
 	else {
+#ifdef YUKON
 		ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags);
+#endif
 	}
 
 	return (ReturnCode);
@@ -350,7 +356,7 @@
 #endif /* !SK_SLIM */
 
 #ifndef SK_SLIM
-
+#ifdef GENESIS
 /******************************************************************************
  *
  *	SkAddrXmacMcClear - clear the multicast table
@@ -402,11 +408,11 @@
 	return (SK_ADDR_SUCCESS);
 	
 }	/* SkAddrXmacMcClear */
-
+#endif	/* GENESIS */
 #endif /* !SK_SLIM */
 
 #ifndef SK_SLIM
-
+#ifdef YUKON
 /******************************************************************************
  *
  *	SkAddrGmacMcClear - clear the multicast table
@@ -445,7 +451,7 @@
 			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
 			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
 			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
-			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
+			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]));
 #endif	/* DEBUG */
 
 	/* Clear InexactFilter */
@@ -487,7 +493,7 @@
 			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
 			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
 			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
-			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
+			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]));
 #endif	/* DEBUG */
 	
 	if (!(Flags & SK_MC_SW_ONLY)) {
@@ -497,9 +503,10 @@
 	return (SK_ADDR_SUCCESS);
 
 }	/* SkAddrGmacMcClear */
+#endif	/* YUKON */
 
 #ifndef SK_ADDR_CHEAT
-
+#ifdef GENESIS
 /******************************************************************************
  *
  *	SkXmacMcHash - hash multicast address
@@ -536,8 +543,9 @@
 	return (Crc & ((1 << HASH_BITS) - 1));
 
 }	/* SkXmacMcHash */
+#endif	/* GENESIS */
 
-
+#ifdef YUKON
 /******************************************************************************
  *
  *	SkGmacMcHash - hash multicast address
@@ -595,7 +603,7 @@
 	return (Crc & ((1 << HASH_BITS) - 1));
 
 }	/* SkGmacMcHash */
-
+#endif	/* YUKON */
 #endif	/* !SK_ADDR_CHEAT */
 
 /******************************************************************************
@@ -636,17 +644,21 @@
 	}
 	
 	if (pAC->GIni.GIGenesis) {
+#ifdef GENESIS
 		ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
+#endif
 	}
 	else {
+#ifdef YUKON
 		ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
+#endif
 	}
 
 	return (ReturnCode);
 
 }	/* SkAddrMcAdd */
 
-
+#ifdef GENESIS
 /******************************************************************************
  *
  *	SkAddrXmacMcAdd - add a multicast address to a port
@@ -756,8 +768,9 @@
 	}
 
 }	/* SkAddrXmacMcAdd */
+#endif	/* GENESIS */
 
-
+#ifdef YUKON
 /******************************************************************************
  *
  *	SkAddrGmacMcAdd - add a multicast address to a port
@@ -819,7 +832,7 @@
 			pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[4],
 			pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[5],
 			pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[6],
-			pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7]))
+			pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7]));
 #endif	/* DEBUG */
 	}
 	else {	/* not permanent => DRV */
@@ -843,7 +856,7 @@
 			pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[4],
 			pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[5],
 			pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[6],
-			pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7]))
+			pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7]));
 #endif	/* DEBUG */
 	}
 	
@@ -858,7 +871,7 @@
 	return (SK_MC_FILTERING_INEXACT);
 	
 }	/* SkAddrGmacMcAdd */
-
+#endif	/* YUKON */
 #endif /* !SK_SLIM */
 
 /******************************************************************************
@@ -946,13 +959,13 @@
 	SK_ADDR_PORT	*pAPort;
 
 	SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-		("SkAddrXmacMcUpdate on Port %u.\n", PortNumber))
+		("SkAddrXmacMcUpdate on Port %u.\n", PortNumber));
 	
 	pAPort = &pAC->Addr.Port[PortNumber];
 
 #ifdef DEBUG
 	SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-		("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
+		("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]));
 #endif /* DEBUG */
 
 	/* Start with 0 to also program the logical MAC address. */
@@ -1041,7 +1054,7 @@
 				pAPort->Exact[i].a[2],
 				pAPort->Exact[i].a[3],
 				pAPort->Exact[i].a[4],
-				pAPort->Exact[i].a[5]))
+				pAPort->Exact[i].a[5]));
 	}
 #endif /* DEBUG */
 
@@ -1093,13 +1106,13 @@
 	SK_ADDR_PORT	*pAPort;
 
 	SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-		("SkAddrGmacMcUpdate on Port %u.\n", PortNumber))
+		("SkAddrGmacMcUpdate on Port %u.\n", PortNumber));
 	
 	pAPort = &pAC->Addr.Port[PortNumber];
 
 #ifdef DEBUG
 	SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
-		("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
+		("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]));
 #endif /* DEBUG */
 	
 #ifndef SK_SLIM
@@ -1155,7 +1168,7 @@
 			pAPort->Exact[0].a[2],
 			pAPort->Exact[0].a[3],
 			pAPort->Exact[0].a[4],
-			pAPort->Exact[0].a[5]))
+			pAPort->Exact[0].a[5]));
 	
 	SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
 		("SkAddrGmacMcUpdate: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
@@ -1164,7 +1177,7 @@
 			pAPort->CurrentMacAddress.a[2],
 			pAPort->CurrentMacAddress.a[3],
 			pAPort->CurrentMacAddress.a[4],
-			pAPort->CurrentMacAddress.a[5]))
+			pAPort->CurrentMacAddress.a[5]));
 #endif /* DEBUG */
 	
 #ifndef SK_SLIM
@@ -1371,7 +1384,7 @@
 				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2],
 				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3],
 				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4],
-				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5]))
+				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5]));
 		
 		SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
 			("SkAddrOverride: New logical MAC Address: %02X %02X %02X %02X %02X %02X\n",
@@ -1380,7 +1393,7 @@
 				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2],
 				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3],
 				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4],
-				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5]))
+				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5]));
 #endif /* DEBUG */
 
         /* Write address to first exact match entry of active port. */
diff -urN linux-2.4.29/drivers/net/sk98lin/skcsum.c linux-2.4.29-uc1/drivers/net/sk98lin/skcsum.c
--- linux-2.4.29/drivers/net/sk98lin/skcsum.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/skcsum.c	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skcsum.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:	$Revision: 2.1 $
+ * Date:	$Date: 2003/10/27 14:16:08 $
  * Purpose:	Store/verify Internet checksum in send/receive packets.
  *
  ******************************************************************************/
@@ -23,7 +25,7 @@
 
 #ifndef lint
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skcsum.c,v 1.12 2003/08/20 13:55:53 mschmid Exp $ (C) SysKonnect.";
+	"@(#) $Id: skcsum.c,v 2.1 2003/10/27 14:16:08 amock Exp $ (C) SysKonnect.";
 #endif	/* !lint */
 
 /******************************************************************************
diff -urN linux-2.4.29/drivers/net/sk98lin/skdim.c linux-2.4.29-uc1/drivers/net/sk98lin/skdim.c
--- linux-2.4.29/drivers/net/sk98lin/skdim.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/skdim.c	2005-06-14 02:12:09.000000000 +0100
@@ -1,16 +1,29 @@
 /******************************************************************************
  *
- * Name:	skdim.c
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Purpose:	All functions to maintain interrupt moderation
+ * Name:        skdim.c
+ * Project:     GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:     $Revision: 1.5 $
+ * Date:        $Date: 2004/07/17 13:28:43 $
+ * Purpose:     All functions regardig interrupt moderation
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
  *	(C)Copyright 1998-2002 SysKonnect GmbH.
- *	(C)Copyright 2002-2003 Marvell.
+ *	(C)Copyright 2002-2004 Marvell.
  *
+ *	Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet 
+ *      Server Adapters.
+ *
+ *	Author: Ralph Roesler (rroesler@syskonnect.de)
+ *	        Mirko Lindner (mlindner@syskonnect.de)
+ *
+ *	Address all question to: linux@syskonnect.de
+ *
+ *	The technical manual for the adapters is available from SysKonnect's
+ *	web pages: www.syskonnect.com
+ *	
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
  *	the Free Software Foundation; either version 2 of the License, or
@@ -18,709 +31,367 @@
  *
  *	The information in this file is provided "AS IS" without warranty.
  *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * Description:
- *
- * This module is intended to manage the dynamic interrupt moderation on both   
- * GEnesis and Yukon adapters.
- *
- * Include File Hierarchy:
- *
- *	"skdrv1st.h"
- *	"skdrv2nd.h"
- *
- ******************************************************************************/
-
-#ifndef	lint
-static const char SysKonnectFileId[] =
-	"@(#) $Id: skdim.c,v 1.5 2003/11/28 12:55:40 rroesler Exp $ (C) SysKonnect.";
-#endif
-
-#define __SKADDR_C
-
-#ifdef __cplusplus
-#error C++ is not yet supported.
-extern "C" {
-#endif
-
-/*******************************************************************************
-**
-** Includes
-**
-*******************************************************************************/
+ *****************************************************************************/
 
-#ifndef __INC_SKDRV1ST_H
 #include "h/skdrv1st.h"
-#endif
-
-#ifndef __INC_SKDRV2ND_H
 #include "h/skdrv2nd.h"
-#endif
-
-#include	<linux/kernel_stat.h>
-
-/*******************************************************************************
-**
-** Defines
-**
-*******************************************************************************/
 
-/*******************************************************************************
-**
-** Typedefs
-**
-*******************************************************************************/
+/******************************************************************************
+ *
+ * Local Function Prototypes
+ *
+ *****************************************************************************/
 
-/*******************************************************************************
-**
-** Local function prototypes 
-**
-*******************************************************************************/
-
-static unsigned int GetCurrentSystemLoad(SK_AC *pAC);
-static SK_U64       GetIsrCalls(SK_AC *pAC);
-static SK_BOOL      IsIntModEnabled(SK_AC *pAC);
-static void         SetCurrIntCtr(SK_AC *pAC);
-static void         EnableIntMod(SK_AC *pAC); 
-static void         DisableIntMod(SK_AC *pAC);
-static void         ResizeDimTimerDuration(SK_AC *pAC);
-static void         DisplaySelectedModerationType(SK_AC *pAC);
-static void         DisplaySelectedModerationMask(SK_AC *pAC);
-static void         DisplayDescrRatio(SK_AC *pAC);
+static SK_U64 getIsrCalls(SK_AC *pAC);
+static SK_BOOL isIntModEnabled(SK_AC *pAC);
+static void setCurrIntCtr(SK_AC *pAC);
+static void enableIntMod(SK_AC *pAC); 
+static void disableIntMod(SK_AC *pAC);
 
-/*******************************************************************************
-**
-** Global variables
-**
-*******************************************************************************/
+#define M_DIMINFO pAC->DynIrqModInfo
 
-/*******************************************************************************
-**
-** Local variables
-**
-*******************************************************************************/
+/******************************************************************************
+ *
+ * Global Functions
+ *
+ *****************************************************************************/
 
-/*******************************************************************************
-**
-** Global functions 
-**
-*******************************************************************************/
+/*****************************************************************************
+ *
+ * 	SkDimModerate - Moderates the IRQs depending on the current needs
+ *
+ * Description:
+ *	Moderation of IRQs depends on the number of occurred IRQs with 
+ *	respect to the previous moderation cycle.
+ *
+ * Returns:	N/A
+ *
+ */
+void SkDimModerate(
+SK_AC *pAC)  /* pointer to adapter control context */
+{
+	SK_U64  IsrCalls = getIsrCalls(pAC);
+
+	SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==> SkDimModerate\n"));
+
+	if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
+		if (isIntModEnabled(pAC)) {
+			if (IsrCalls < M_DIMINFO.MaxModIntsPerSecLowerLimit) {
+				disableIntMod(pAC);
+			}
+		} else {
+			if (IsrCalls > M_DIMINFO.MaxModIntsPerSecUpperLimit) {
+				enableIntMod(pAC);
+			}
+		}
+	}
+	setCurrIntCtr(pAC);
 
-/*******************************************************************************
-** Function     : SkDimModerate
-** Description  : Called in every ISR to check if moderation is to be applied
-**                or not for the current number of interrupts
-** Programmer   : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns      : void (!)
-** Notes        : -
-*******************************************************************************/
-
-void 
-SkDimModerate(SK_AC *pAC) {
-    unsigned int CurrSysLoad    = 0;  /* expressed in percent */
-    unsigned int LoadIncrease   = 0;  /* expressed in percent */
-    SK_U64       ThresholdInts  = 0;
-    SK_U64       IsrCallsPerSec = 0;
+	SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("<== SkDimModerate\n"));
+}
 
-#define M_DIMINFO pAC->DynIrqModInfo
+/*****************************************************************************
+ *
+ * 	SkDimStartModerationTimer - Starts the moderation timer
+ *
+ * Description:
+ *	Dynamic interrupt moderation is regularly checked using the
+ *	so-called moderation timer. This timer is started with this function.
+ *
+ * Returns:	N/A
+ */
+void SkDimStartModerationTimer(
+SK_AC *pAC) /* pointer to adapter control context */
+{
+	SK_EVPARA   EventParam;   /* Event struct for timer event */
+ 
+	SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
+			("==> SkDimStartModerationTimer\n"));
 
-    if (!IsIntModEnabled(pAC)) {
-        if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
-            CurrSysLoad = GetCurrentSystemLoad(pAC);
-            if (CurrSysLoad > 75) {
-                    /* 
-                    ** More than 75% total system load! Enable the moderation 
-                    ** to shield the system against too many interrupts.
-                    */
-                    EnableIntMod(pAC);
-            } else if (CurrSysLoad > M_DIMINFO.PrevSysLoad) {
-                LoadIncrease = (CurrSysLoad - M_DIMINFO.PrevSysLoad);
-                if (LoadIncrease > ((M_DIMINFO.PrevSysLoad *
-                                         C_INT_MOD_ENABLE_PERCENTAGE) / 100)) {
-                    if (CurrSysLoad > 10) {
-                        /* 
-                        ** More than 50% increase with respect to the 
-                        ** previous load of the system. Most likely this 
-                        ** is due to our ISR-proc...
-                        */
-                        EnableIntMod(pAC);
-                    }
-                }
-            } else {
-                /*
-                ** Neither too much system load at all nor too much increase
-                ** with respect to the previous system load. Hence, we can leave
-                ** the ISR-handling like it is without enabling moderation.
-                */
-            }
-            M_DIMINFO.PrevSysLoad = CurrSysLoad;
-        }   
-    } else {
-        if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
-            ThresholdInts  = ((M_DIMINFO.MaxModIntsPerSec *
-                                   C_INT_MOD_DISABLE_PERCENTAGE) / 100);
-            IsrCallsPerSec = GetIsrCalls(pAC);
-            if (IsrCallsPerSec <= ThresholdInts) {
-                /* 
-                ** The number of interrupts within the last second is 
-                ** lower than the disable_percentage of the desried 
-                ** maxrate. Therefore we can disable the moderation.
-                */
-                DisableIntMod(pAC);
-                M_DIMINFO.MaxModIntsPerSec = 
-                   (M_DIMINFO.MaxModIntsPerSecUpperLimit +
-                    M_DIMINFO.MaxModIntsPerSecLowerLimit) / 2;
-            } else {
-                /*
-                ** The number of interrupts per sec is the same as expected.
-                ** Evalulate the descriptor-ratio. If it has changed, a resize 
-                ** in the moderation timer might be usefull
-                */
-                if (M_DIMINFO.AutoSizing) {
-                    ResizeDimTimerDuration(pAC);
-                }
-            }
-        }
-    }
-
-    /*
-    ** Some information to the log...
-    */
-    if (M_DIMINFO.DisplayStats) {
-        DisplaySelectedModerationType(pAC);
-        DisplaySelectedModerationMask(pAC);
-        DisplayDescrRatio(pAC);
-    }
+	if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
+		SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
+		EventParam.Para32[0] = SK_DRV_MODERATION_TIMER;
+		SkTimerStart(pAC, pAC->IoBase,
+			&pAC->DynIrqModInfo.ModTimer,
+			pAC->DynIrqModInfo.DynIrqModSampleInterval * 1000000,
+			SKGE_DRV, SK_DRV_TIMER, EventParam);
+	}
 
-    M_DIMINFO.NbrProcessedDescr = 0; 
-    SetCurrIntCtr(pAC);
+	SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
+			("<== SkDimStartModerationTimer\n"));
 }
 
-/*******************************************************************************
-** Function     : SkDimStartModerationTimer
-** Description  : Starts the audit-timer for the dynamic interrupt moderation
-** Programmer   : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns      : void (!)
-** Notes        : -
-*******************************************************************************/
-
-void 
-SkDimStartModerationTimer(SK_AC *pAC) {
-    SK_EVPARA    EventParam;   /* Event struct for timer event */
- 
-    SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
-    EventParam.Para32[0] = SK_DRV_MODERATION_TIMER;
-    SkTimerStart(pAC, pAC->IoBase, &pAC->DynIrqModInfo.ModTimer,
-                 SK_DRV_MODERATION_TIMER_LENGTH,
-                 SKGE_DRV, SK_DRV_TIMER, EventParam);
-}
+/*****************************************************************************
+ *
+ * 	SkDimEnableModerationIfNeeded - Enables or disables any moderationtype
+ *
+ * Description:
+ *	This function effectively initializes the IRQ moderation of a network
+ *	adapter. Depending on the configuration, this might be either static
+ *	or dynamic. If no moderation is configured, this function will do
+ *	nothing.
+ *
+ * Returns:	N/A
+ */
+void SkDimEnableModerationIfNeeded(
+SK_AC *pAC)  /* pointer to adapter control context */
+{
+	SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
+			("==> SkDimEnableModerationIfNeeded\n"));
+
+	if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_NONE) {
+		if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) {
+			enableIntMod(pAC);   
+		} else { /* must be C_INT_MOD_DYNAMIC */
+			SkDimStartModerationTimer(pAC);
+		}
+	}
 
-/*******************************************************************************
-** Function     : SkDimEnableModerationIfNeeded
-** Description  : Either enables or disables moderation
-** Programmer   : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns      : void (!)
-** Notes        : This function is called when a particular adapter is opened
-**                There is no Disable function, because when all interrupts 
-**                might be disable, the moderation timer has no meaning at all
-******************************************************************************/
-
-void
-SkDimEnableModerationIfNeeded(SK_AC *pAC) {
-
-    if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) {
-        EnableIntMod(pAC);   /* notification print in this function */
-    } else if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
-        SkDimStartModerationTimer(pAC);
-        if (M_DIMINFO.DisplayStats) {
-            printk("Dynamic moderation has been enabled\n");
-        }
-    } else {
-        if (M_DIMINFO.DisplayStats) {
-            printk("No moderation has been enabled\n");
-        }
-    }
+	SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
+			("<== SkDimEnableModerationIfNeeded\n"));
 }
 
-/*******************************************************************************
-** Function     : SkDimDisplayModerationSettings
-** Description  : Displays the current settings regaring interrupt moderation
-** Programmer   : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns      : void (!)
-** Notes        : -
-*******************************************************************************/
-
-void 
-SkDimDisplayModerationSettings(SK_AC *pAC) {
-    DisplaySelectedModerationType(pAC);
-    DisplaySelectedModerationMask(pAC);
-}
+/*****************************************************************************
+ *
+ * 	SkDimDisableModeration - disables moderation if it is enabled
+ *
+ * Description:
+ *	Disabling of the moderation requires that is enabled already.
+ *
+ * Returns:	N/A
+ */
+void SkDimDisableModeration(
+SK_AC  *pAC,                /* pointer to adapter control context */
+int     CurrentModeration)  /* type of current moderation         */
+{
+	SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
+			("==> SkDimDisableModeration\n"));
+
+	if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_NONE) {
+		if (CurrentModeration == C_INT_MOD_STATIC) {
+			disableIntMod(pAC);
+		} else { /* must be C_INT_MOD_DYNAMIC */
+			SkTimerStop(pAC, pAC->IoBase, &M_DIMINFO.ModTimer);
+			disableIntMod(pAC);
+		}
+	}
 
-/*******************************************************************************
-**
-** Local functions 
-**
-*******************************************************************************/
+	SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
+			("<== SkDimDisableModeration\n"));
+}
 
-/*******************************************************************************
-** Function     : GetCurrentSystemLoad
-** Description  : Retrieves the current system load of the system. This load
-**                is evaluated for all processors within the system.
-** Programmer   : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns      : unsigned int: load expressed in percentage
-** Notes        : The possible range being returned is from 0 up to 100.
-**                Whereas 0 means 'no load at all' and 100 'system fully loaded'
-**                It is impossible to determine what actually causes the system
-**                to be in 100%, but maybe that is due to too much interrupts.
-*******************************************************************************/
-
-static unsigned int
-GetCurrentSystemLoad(SK_AC *pAC) {
-	unsigned long jif         = jiffies;
-	unsigned int  UserTime    = 0;
-	unsigned int  SystemTime  = 0;
-	unsigned int  NiceTime    = 0;
-	unsigned int  IdleTime    = 0;
-	unsigned int  TotalTime   = 0;
-	unsigned int  UsedTime    = 0;
-	unsigned int  SystemLoad  = 0;
-
-#ifdef CONFIG_SMP
-	unsigned int  SKNumCpus   = smp_num_cpus;
-#else
-	unsigned int  SKNumCpus   = 1;
-#endif
+/******************************************************************************
+ *
+ * Local Functions
+ *
+ *****************************************************************************/
 
-	unsigned int  NbrCpu      = 0;
+/*****************************************************************************
+ *
+ * 	getIsrCalls - evaluate the number of IRQs handled in mod interval
+ *
+ * Description:
+ *	Depending on the selected moderation mask, this function will return
+ *	the number of interrupts handled in the previous moderation interval.
+ *	This evaluated number is based on the current number of interrupts
+ *	stored in PNMI-context and the previous stored interrupts.
+ *
+ * Returns:
+ *	the number of IRQs handled
+ */
+static SK_U64 getIsrCalls(
+SK_AC *pAC)  /* pointer to adapter control context */
+{
+	SK_U64   RxPort0IntDiff = 0, RxPort1IntDiff = 0;
+	SK_U64   TxPort0IntDiff = 0, TxPort1IntDiff = 0;
+	SK_U64   StatusPort0IntDiff = 0, StatusPort1IntDiff = 0;
+
+        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==>getIsrCalls\n"));
+
+	if (!CHIP_ID_YUKON_2(pAC)) {
+		if ((M_DIMINFO.MaskIrqModeration == IRQ_MASK_TX_ONLY) ||
+		    (M_DIMINFO.MaskIrqModeration == IRQ_MASK_SP_TX)) {
+			if (pAC->GIni.GIMacsFound == 2) {
+				TxPort1IntDiff = 
+					pAC->Pnmi.Port[1].TxIntrCts - 
+					M_DIMINFO.PrevPort1TxIntrCts;
+			}
+			TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - 
+					M_DIMINFO.PrevPort0TxIntrCts;
+		} else if ((M_DIMINFO.MaskIrqModeration == IRQ_MASK_RX_ONLY) ||
+		           (M_DIMINFO.MaskIrqModeration == IRQ_MASK_SP_RX)) {
+			if (pAC->GIni.GIMacsFound == 2) {
+				RxPort1IntDiff =
+					pAC->Pnmi.Port[1].RxIntrCts - 
+					M_DIMINFO.PrevPort1RxIntrCts;
+			}
+			RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - 
+					M_DIMINFO.PrevPort0RxIntrCts;
+		} else {
+			if (pAC->GIni.GIMacsFound == 2) {
+				RxPort1IntDiff = 
+					pAC->Pnmi.Port[1].RxIntrCts - 
+					M_DIMINFO.PrevPort1RxIntrCts;
+				TxPort1IntDiff =
+					pAC->Pnmi.Port[1].TxIntrCts - 
+					M_DIMINFO.PrevPort1TxIntrCts;
+			} 
+			RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - 
+					M_DIMINFO.PrevPort0RxIntrCts;
+			TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - 
+					M_DIMINFO.PrevPort0TxIntrCts;
+		}
+        	SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
+				("==>getIsrCalls (!CHIP_ID_YUKON_2)\n"));
+		return (RxPort0IntDiff + RxPort1IntDiff + 
+		        TxPort0IntDiff + TxPort1IntDiff);
+	}
 
-    for (NbrCpu = 0; NbrCpu < SKNumCpus; NbrCpu++) {
-#ifdef _LINUX_PROCESS_TIMING_H
 	/*
-	** all seconds and usec values being obtained from the
-	** process_timing entries need to be adapted to jiffies
-	** (in case we have a system supporting process times)
+	** We have a Yukon2 compliant chipset if we come up to here
+	**
+	if (pAC->GIni.GIMacsFound == 2) {
+		StatusPort1IntDiff = pAC->Pnmi.Port[1].StatusLeIntrCts - 
+					M_DIMINFO.PrevPort1StatusIntrCts;
+	}
+	StatusPort0IntDiff = pAC->Pnmi.Port[0].StatusLeIntrCts - 
+				M_DIMINFO.PrevPort0StatusIntrCts;
 	*/
-        UserTime   = UserTime   + (kstat_percpu[NbrCpu].user.tv_sec * 10)
-	                        + (kstat_percpu[NbrCpu].user.tv_usec/100000);
-        NiceTime   = NiceTime   + (kstat_percpu[NbrCpu].nice.tv_sec * 10)
-	                        + (kstat_percpu[NbrCpu].nice.tv_usec/100000);
-        SystemTime = SystemTime + (kstat_percpu[NbrCpu].system.tv_sec * 10)
-	                        + (kstat_percpu[NbrCpu].system.tv_usec/100000);
-#else
-        UserTime   = UserTime   + kstat.per_cpu_user[NbrCpu];
-        NiceTime   = NiceTime   + kstat.per_cpu_nice[NbrCpu];
-        SystemTime = SystemTime + kstat.per_cpu_system[NbrCpu];
-#endif
-    }
-
-	UsedTime  = UserTime + NiceTime + SystemTime;
-
-	IdleTime  = jif * SKNumCpus - UsedTime;
-	TotalTime = UsedTime + IdleTime;
-
-	SystemLoad = ( 100 * (UsedTime  - M_DIMINFO.PrevUsedTime) ) /
-						(TotalTime - M_DIMINFO.PrevTotalTime);
+        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
+			("==>getIsrCalls (CHIP_ID_YUKON_2)\n"));
+	return (StatusPort0IntDiff + StatusPort1IntDiff);
+}
 
-	if (M_DIMINFO.DisplayStats) {
-		printk("Current system load is: %u\n", SystemLoad);
+/*****************************************************************************
+ *
+ * 	setCurrIntCtr - stores the current number of interrupts
+ *
+ * Description:
+ *	Stores the current number of occurred interrupts in the adapter
+ *	context. This is needed to evaluate the  umber of interrupts within
+ *	the moderation interval.
+ *
+ * Returns:	N/A
+ *
+ */
+static void setCurrIntCtr(
+SK_AC *pAC)  /* pointer to adapter control context */
+{
+        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==>setCurrIntCtr\n"));
+
+	if (!CHIP_ID_YUKON_2(pAC)) {
+		if (pAC->GIni.GIMacsFound == 2) {
+			M_DIMINFO.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts;
+			M_DIMINFO.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts;
+		} 
+		M_DIMINFO.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts;
+		M_DIMINFO.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts;
+        	SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
+				("<== setCurrIntCtr (!CHIP_ID_YUKON_2)\n"));
+		return;
 	}
 
-	M_DIMINFO.PrevTotalTime = TotalTime;
-	M_DIMINFO.PrevUsedTime  = UsedTime;
-
-	return (SystemLoad);
+	/*
+	** We have a Yukon2 compliant chipset if we come up to here
+	**
+	if (pAC->GIni.GIMacsFound == 2) {
+		M_DIMINFO.PrevPort1StatusIntrCts = pAC->Pnmi.Port[1].StatusLeIntrCts;
+	} 
+	M_DIMINFO.PrevPort0StatusIntrCts = pAC->Pnmi.Port[0].StatusLeIntrCts;
+	*/
+        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
+			("<== setCurrIntCtr (CHIP_ID_YUKON_2)\n"));
 }
 
-/*******************************************************************************
-** Function     : GetIsrCalls
-** Description  : Depending on the selected moderation mask, this function will
-**                return the number of interrupts handled in the previous time-
-**                frame. This evaluated number is based on the current number 
-**                of interrupts stored in PNMI-context and the previous stored 
-**                interrupts.
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : int:   the number of interrupts being executed in the last
-**                       timeframe
-** Notes        : It makes only sense to call this function, when dynamic 
-**                interrupt moderation is applied
-*******************************************************************************/
-
-static SK_U64
-GetIsrCalls(SK_AC *pAC) {
-    SK_U64   RxPort0IntDiff = 0;
-    SK_U64   RxPort1IntDiff = 0;
-    SK_U64   TxPort0IntDiff = 0;
-    SK_U64   TxPort1IntDiff = 0;
-
-    if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_TX_ONLY) {
-        if (pAC->GIni.GIMacsFound == 2) {
-            TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts - 
-                             pAC->DynIrqModInfo.PrevPort1TxIntrCts;
-        }
-        TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - 
-                         pAC->DynIrqModInfo.PrevPort0TxIntrCts;
-    } else if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_RX_ONLY) {
-        if (pAC->GIni.GIMacsFound == 2) {
-            RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - 
-                             pAC->DynIrqModInfo.PrevPort1RxIntrCts;
-        }
-        RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - 
-                         pAC->DynIrqModInfo.PrevPort0RxIntrCts;
-    } else {
-        if (pAC->GIni.GIMacsFound == 2) {
-            RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - 
-                             pAC->DynIrqModInfo.PrevPort1RxIntrCts;
-            TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts - 
-                             pAC->DynIrqModInfo.PrevPort1TxIntrCts;
-        } 
-        RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - 
-                         pAC->DynIrqModInfo.PrevPort0RxIntrCts;
-        TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - 
-                         pAC->DynIrqModInfo.PrevPort0TxIntrCts;
-    }
-
-    return (RxPort0IntDiff + RxPort1IntDiff + TxPort0IntDiff + TxPort1IntDiff);
+/*****************************************************************************
+ *
+ * 	isIntModEnabled - returns the current state of interrupt moderation
+ *
+ * Description:
+ *	This function retrieves the current value of the interrupt moderation
+ *	command register. Its content determines whether any moderation is 
+ *	running or not.
+ *
+ * Returns:
+ *	SK_TRUE : IRQ moderation is currently active
+ *	SK_FALSE: No IRQ moderation is active
+ */
+static SK_BOOL isIntModEnabled(
+SK_AC *pAC)  /* pointer to adapter control context */
+{
+	unsigned long CtrCmd;
+
+        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==>isIntModEnabled\n"));
+
+	SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd);
+	if ((CtrCmd & TIM_START) == TIM_START) {
+        	SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
+			("<== isIntModEnabled (SK_TRUE)\n"));
+		return SK_TRUE;
+	}
+        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
+			("<== isIntModEnabled (SK_FALSE)\n"));
+	return SK_FALSE;
 }
 
-/*******************************************************************************
-** Function     : GetRxCalls
-** Description  : This function will return the number of times a receive inter-
-**                rupt was processed. This is needed to evaluate any resizing 
-**                factor.
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : SK_U64: the number of RX-ints being processed
-** Notes        : It makes only sense to call this function, when dynamic 
-**                interrupt moderation is applied
-*******************************************************************************/
-
-static SK_U64
-GetRxCalls(SK_AC *pAC) {
-    SK_U64   RxPort0IntDiff = 0;
-    SK_U64   RxPort1IntDiff = 0;
-
-    if (pAC->GIni.GIMacsFound == 2) {
-        RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - 
-                         pAC->DynIrqModInfo.PrevPort1RxIntrCts;
-    }
-    RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - 
-                     pAC->DynIrqModInfo.PrevPort0RxIntrCts;
-
-    return (RxPort0IntDiff + RxPort1IntDiff);
-}
+/*****************************************************************************
+ *
+ * 	enableIntMod - enables the interrupt moderation
+ *
+ * Description:
+ *	Enabling the interrupt moderation is done by putting the desired
+ *	moderation interval in the B2_IRQM_INI register, specifying the
+ *	desired maks in the B2_IRQM_MSK register and finally starting the
+ *	IRQ moderation timer using the B2_IRQM_CTRL register.
+ *
+ * Returns:	N/A
+ *
+ */
+static void enableIntMod(
+SK_AC *pAC)  /* pointer to adapter control context */
+{
+	unsigned long ModBase;
+
+        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==> enableIntMod\n"));
+
+	if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+		ModBase = C_CLK_FREQ_GENESIS / M_DIMINFO.MaxModIntsPerSec;
+	} else if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) {
+		ModBase = C_CLK_FREQ_YUKON_EC / M_DIMINFO.MaxModIntsPerSec;
+	} else {
+		ModBase = C_CLK_FREQ_YUKON / M_DIMINFO.MaxModIntsPerSec;
+	}
 
-/*******************************************************************************
-** Function     : SetCurrIntCtr
-** Description  : Will store the current number orf occured interrupts in the 
-**                adapter context. This is needed to evaluated the number of 
-**                interrupts within a current timeframe.
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : void (!)
-** Notes        : -
-*******************************************************************************/
-
-static void
-SetCurrIntCtr(SK_AC *pAC) {
-    if (pAC->GIni.GIMacsFound == 2) {
-        pAC->DynIrqModInfo.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts;
-        pAC->DynIrqModInfo.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts;
-    } 
-    pAC->DynIrqModInfo.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts;
-    pAC->DynIrqModInfo.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts;
-}
+	SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
+	SK_OUT32(pAC->IoBase, B2_IRQM_MSK, M_DIMINFO.MaskIrqModeration);
+	SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
 
-/*******************************************************************************
-** Function     : IsIntModEnabled()
-** Description  : Retrieves the current value of the interrupts moderation
-**                command register. Its content determines whether any 
-**                moderation is running or not.
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : SK_TRUE  : if mod timer running
-**                SK_FALSE : if no moderation is being performed
-** Notes        : -
-*******************************************************************************/
-
-static SK_BOOL
-IsIntModEnabled(SK_AC *pAC) {
-    unsigned long CtrCmd;
-
-    SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd);
-    if ((CtrCmd & TIM_START) == TIM_START) {
-       return SK_TRUE;
-    } else {
-       return SK_FALSE;
-    }
+        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("<== enableIntMod\n"));
 }
 
-/*******************************************************************************
-** Function     : EnableIntMod()
-** Description  : Enables the interrupt moderation using the values stored in
-**                in the pAC->DynIntMod data structure
-** Programmer   : Ralph Roesler
-** Last Modified: 22-mar-03
-** Returns      : -
-** Notes        : -
-*******************************************************************************/
-
-static void
-EnableIntMod(SK_AC *pAC) {
-    unsigned long ModBase;
-
-    if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-       ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
-    } else {
-       ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
-    }
-
-    SK_OUT32(pAC->IoBase, B2_IRQM_INI,  ModBase);
-    SK_OUT32(pAC->IoBase, B2_IRQM_MSK,  pAC->DynIrqModInfo.MaskIrqModeration);
-    SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
-    if (M_DIMINFO.DisplayStats) {
-        printk("Enabled interrupt moderation (%i ints/sec)\n",
-               M_DIMINFO.MaxModIntsPerSec);
-    }
-}
+/*****************************************************************************
+ *
+ * 	disableIntMod - disables the interrupt moderation
+ *
+ * Description:
+ *	Disabling the interrupt moderation is done by stopping the
+ *	IRQ moderation timer using the B2_IRQM_CTRL register.
+ *
+ * Returns:	N/A
+ *
+ */
+static void disableIntMod(
+SK_AC *pAC)  /* pointer to adapter control context */
+{
+        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==> disableIntMod\n"));
 
-/*******************************************************************************
-** Function     : DisableIntMod()
-** Description  : Disbles the interrupt moderation independent of what inter-
-**                rupts are running or not
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : -
-** Notes        : -
-*******************************************************************************/
-
-static void 
-DisableIntMod(SK_AC *pAC) {
-
-    SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP);
-    if (M_DIMINFO.DisplayStats) {
-        printk("Disabled interrupt moderation\n");
-    }
-} 
+	SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP);
 
-/*******************************************************************************
-** Function     : ResizeDimTimerDuration();
-** Description  : Checks the current used descriptor ratio and resizes the 
-**                duration timer (longer/smaller) if possible. 
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : -
-** Notes        : There are both maximum and minimum timer duration value. 
-**                This function assumes that interrupt moderation is already
-**                enabled!
-*******************************************************************************/
-
-static void 
-ResizeDimTimerDuration(SK_AC *pAC) {
-    SK_BOOL IncreaseTimerDuration;
-    int     TotalMaxNbrDescr;
-    int     UsedDescrRatio;
-    int     RatioDiffAbs;
-    int     RatioDiffRel;
-    int     NewMaxModIntsPerSec;
-    int     ModAdjValue;
-    long    ModBase;
-
-    /*
-    ** Check first if we are allowed to perform any modification
-    */
-    if (IsIntModEnabled(pAC)) { 
-        if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_DYNAMIC) {
-            return; 
-        } else {
-            if (M_DIMINFO.ModJustEnabled) {
-                M_DIMINFO.ModJustEnabled = SK_FALSE;
-                return;
-            }
-        }
-    }
-
-    /*
-    ** If we got until here, we have to evaluate the amount of the
-    ** descriptor ratio change...
-    */
-    TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
-    UsedDescrRatio   = (M_DIMINFO.NbrProcessedDescr * 100) / TotalMaxNbrDescr;
-
-    if (UsedDescrRatio > M_DIMINFO.PrevUsedDescrRatio) {
-        RatioDiffAbs = (UsedDescrRatio - M_DIMINFO.PrevUsedDescrRatio);
-        RatioDiffRel = (RatioDiffAbs * 100) / UsedDescrRatio;
-        M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
-        IncreaseTimerDuration = SK_FALSE;  /* in other words: DECREASE */
-    } else if (UsedDescrRatio < M_DIMINFO.PrevUsedDescrRatio) {
-        RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
-        RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
-        M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
-        IncreaseTimerDuration = SK_TRUE;   /* in other words: INCREASE */
-    } else {
-        RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
-        RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
-        M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
-        IncreaseTimerDuration = SK_TRUE;   /* in other words: INCREASE */
-    }
-
-    /*
-    ** Now we can determine the change in percent
-    */
-    if ((RatioDiffRel >= 0) && (RatioDiffRel <= 5) ) {
-       ModAdjValue = 1;  /*  1% change - maybe some other value in future */
-    } else if ((RatioDiffRel > 5) && (RatioDiffRel <= 10) ) {
-       ModAdjValue = 1;  /*  1% change - maybe some other value in future */
-    } else if ((RatioDiffRel > 10) && (RatioDiffRel <= 15) ) {
-       ModAdjValue = 1;  /*  1% change - maybe some other value in future */
-    } else {
-       ModAdjValue = 1;  /*  1% change - maybe some other value in future */
-    }
-
-    if (IncreaseTimerDuration) {
-       NewMaxModIntsPerSec =  M_DIMINFO.MaxModIntsPerSec +
-                             (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
-    } else {
-       NewMaxModIntsPerSec =  M_DIMINFO.MaxModIntsPerSec -
-                             (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
-    }
-
-    /* 
-    ** Check if we exceed boundaries...
-    */
-    if ( (NewMaxModIntsPerSec > M_DIMINFO.MaxModIntsPerSecUpperLimit) ||
-         (NewMaxModIntsPerSec < M_DIMINFO.MaxModIntsPerSecLowerLimit)) {
-        if (M_DIMINFO.DisplayStats) {
-            printk("Cannot change ModTim from %i to %i ints/sec\n",
-                   M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
-        }
-        return;
-    } else {
-        if (M_DIMINFO.DisplayStats) {
-            printk("Resized ModTim from %i to %i ints/sec\n",
-                   M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
-        }
-    }
-
-    M_DIMINFO.MaxModIntsPerSec = NewMaxModIntsPerSec;
-
-    if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
-        ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
-    } else {
-        ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
-    }
-
-    /* 
-    ** We do not need to touch any other registers
-    */
-    SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
+        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("<== disableIntMod\n"));
 } 
 
 /*******************************************************************************
-** Function     : DisplaySelectedModerationType()
-** Description  : Displays what type of moderation we have
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : void!
-** Notes        : -
-*******************************************************************************/
-
-static void
-DisplaySelectedModerationType(SK_AC *pAC) {
-
-    if (pAC->DynIrqModInfo.DisplayStats) {
-        if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) {
-             printk("Static int moderation runs with %i INTS/sec\n",
-                    pAC->DynIrqModInfo.MaxModIntsPerSec);
-        } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
-             if (IsIntModEnabled(pAC)) {
-                printk("Dynamic int moderation runs with %i INTS/sec\n",
-                       pAC->DynIrqModInfo.MaxModIntsPerSec);
-             } else {
-                printk("Dynamic int moderation currently not applied\n");
-             }
-        } else {
-             printk("No interrupt moderation selected!\n");
-        }
-    }
-}
-
-/*******************************************************************************
-** Function     : DisplaySelectedModerationMask()
-** Description  : Displays what interrupts are moderated
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : void!
-** Notes        : -
-*******************************************************************************/
-
-static void
-DisplaySelectedModerationMask(SK_AC *pAC) {
-
-    if (pAC->DynIrqModInfo.DisplayStats) {
-        if (pAC->DynIrqModInfo.IntModTypeSelect != C_INT_MOD_NONE) {
-            switch (pAC->DynIrqModInfo.MaskIrqModeration) {
-                case IRQ_MASK_TX_ONLY: 
-                   printk("Only Tx-interrupts are moderated\n");
-                   break;
-                case IRQ_MASK_RX_ONLY: 
-                   printk("Only Rx-interrupts are moderated\n");
-                   break;
-                case IRQ_MASK_SP_ONLY: 
-                   printk("Only special-interrupts are moderated\n");
-                   break;
-                case IRQ_MASK_TX_RX: 
-                   printk("Tx- and Rx-interrupts are moderated\n");
-                   break;
-                case IRQ_MASK_SP_RX: 
-                   printk("Special- and Rx-interrupts are moderated\n");
-                   break;
-                case IRQ_MASK_SP_TX: 
-                   printk("Special- and Tx-interrupts are moderated\n");
-                   break;
-                case IRQ_MASK_RX_TX_SP:
-                   printk("All Rx-, Tx and special-interrupts are moderated\n");
-                   break;
-                default:
-                   printk("Don't know what is moderated\n");
-                   break;
-            }
-        } else {
-            printk("No specific interrupts masked for moderation\n");
-        }
-    } 
-}
-
-/*******************************************************************************
-** Function     : DisplayDescrRatio
-** Description  : Like the name states...
-** Programmer   : Ralph Roesler
-** Last Modified: 23-mar-03
-** Returns      : void!
-** Notes        : -
-*******************************************************************************/
-
-static void
-DisplayDescrRatio(SK_AC *pAC) {
-    int TotalMaxNbrDescr = 0;
-
-    if (pAC->DynIrqModInfo.DisplayStats) {
-        TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
-        printk("Ratio descriptors: %i/%i\n",
-               M_DIMINFO.NbrProcessedDescr, TotalMaxNbrDescr);
-    }
-}
-
-/*******************************************************************************
-**
-** End of file
-**
-*******************************************************************************/
+ *
+ * End of file
+ *
+ ******************************************************************************/
diff -urN linux-2.4.29/drivers/net/sk98lin/skethtool.c linux-2.4.29-uc1/drivers/net/sk98lin/skethtool.c
--- linux-2.4.29/drivers/net/sk98lin/skethtool.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/skethtool.c	2005-06-14 02:12:09.000000000 +0100
@@ -0,0 +1,1252 @@
+/******************************************************************************
+ *
+ * Name:        skethtool.c
+ * Project:     GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:     $Revision: 1.2 $
+ * Date:        $Date: 2004/11/17 05:40:48 $
+ * Purpose:     All functions regarding ethtool handling
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *	(C)Copyright 1998-2002 SysKonnect GmbH.
+ *	(C)Copyright 2002-2004 Marvell.
+ *
+ *	Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet 
+ *      Server Adapters.
+ *
+ *	Author: Ralph Roesler (rroesler@syskonnect.de)
+ *	        Mirko Lindner (mlindner@syskonnect.de)
+ *
+ *	Address all question to: linux@syskonnect.de
+ *
+ *	The technical manual for the adapters is available from SysKonnect's
+ *	web pages: www.syskonnect.com
+ *	
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2 of the License, or
+ *	(at your option) any later version.
+ *
+ *	The information in this file is provided "AS IS" without warranty.
+ *
+ *****************************************************************************/
+
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+#include "h/skversion.h"
+#include <linux/ethtool.h>
+#include <linux/module.h>
+#include <linux/timer.h>
+
+/******************************************************************************
+ *
+ * External Functions and Data
+ *
+ *****************************************************************************/
+
+extern void SkDimDisableModeration(SK_AC *pAC, int CurrentModeration);
+extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);
+
+/******************************************************************************
+ *
+ * Defines
+ *
+ *****************************************************************************/
+
+#ifndef ETHT_STATSTRING_LEN
+#define ETHT_STATSTRING_LEN 32
+#endif
+
+#define SK98LIN_STAT(m)	sizeof(((SK_AC *)0)->m),offsetof(SK_AC, m)
+
+#define SUPP_COPPER_ALL (SUPPORTED_10baseT_Half  | SUPPORTED_10baseT_Full  | \
+                         SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
+                         SUPPORTED_1000baseT_Half| SUPPORTED_1000baseT_Full| \
+                         SUPPORTED_TP)
+
+#define ADV_COPPER_ALL  (ADVERTISED_10baseT_Half  | ADVERTISED_10baseT_Full  | \
+                         ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
+                         ADVERTISED_1000baseT_Half| ADVERTISED_1000baseT_Full| \
+                         ADVERTISED_TP)
+
+#define SUPP_FIBRE_ALL  (SUPPORTED_1000baseT_Full | \
+                         SUPPORTED_FIBRE          | \
+                         SUPPORTED_Autoneg)
+
+#define ADV_FIBRE_ALL   (ADVERTISED_1000baseT_Full | \
+                         ADVERTISED_FIBRE          | \
+                         ADVERTISED_Autoneg)
+
+/******************************************************************************
+ *
+ * Local Function Prototypes
+ *
+ *****************************************************************************/
+
+#ifdef ETHTOOL_GSET
+static void getSettings(SK_AC *pAC, int port, struct ethtool_cmd *ecmd);
+#endif
+#ifdef ETHTOOL_SSET
+static int setSettings(SK_AC *pAC, int port, struct ethtool_cmd *ecmd);
+#endif
+#ifdef ETHTOOL_GPAUSEPARAM
+static void getPauseParams(SK_AC *pAC, int port, struct ethtool_pauseparam *epause);
+#endif
+#ifdef ETHTOOL_SPAUSEPARAM
+static int setPauseParams(SK_AC *pAC, int port, struct ethtool_pauseparam *epause);
+#endif
+#ifdef ETHTOOL_GDRVINFO
+static void getDriverInfo(SK_AC *pAC, int port, struct ethtool_drvinfo *edrvinfo);
+#endif
+#ifdef ETHTOOL_PHYS_ID
+static int startLocateNIC(SK_AC *pAC, int port, struct ethtool_value *blinkSecs);
+static void toggleLeds(unsigned long ptr);
+#endif
+#ifdef ETHTOOL_GCOALESCE
+static void getModerationParams(SK_AC *pAC, int port, struct ethtool_coalesce *ecoalesc);
+#endif
+#ifdef ETHTOOL_SCOALESCE
+static int setModerationParams(SK_AC *pAC, int port, struct ethtool_coalesce *ecoalesc);
+#endif
+#ifdef ETHTOOL_GWOL
+static void getWOLsettings(SK_AC *pAC, int port, struct ethtool_wolinfo *ewol);
+#endif
+#ifdef ETHTOOL_SWOL
+static int setWOLsettings(SK_AC *pAC, int port, struct ethtool_wolinfo *ewol);
+#endif
+
+static int getPortNumber(struct net_device *netdev, struct ifreq *ifr);
+
+/******************************************************************************
+ *
+ * Local Variables
+ *
+ *****************************************************************************/
+
+struct sk98lin_stats {
+	char stat_string[ETHT_STATSTRING_LEN];
+	int  sizeof_stat;
+	int  stat_offset;
+};
+
+static struct sk98lin_stats sk98lin_etht_stats_port0[] = {
+	{ "rx_packets" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxOkCts) },
+	{ "tx_packets" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxOkCts) },
+	{ "rx_bytes" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxOctetsOkCts) },
+	{ "tx_bytes" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxOctetsOkCts) },
+	{ "rx_errors" , SK98LIN_STAT(PnmiStruct.InErrorsCts) },
+	{ "tx_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxSingleCollisionCts) },
+	{ "rx_dropped" , SK98LIN_STAT(PnmiStruct.RxNoBufCts) },
+	{ "tx_dropped" , SK98LIN_STAT(PnmiStruct.TxNoBufCts) },
+	{ "multicasts" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxMulticastOkCts) },
+	{ "collisions" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxSingleCollisionCts) },
+	{ "rx_length_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxRuntCts) },
+	{ "rx_buffer_overflow_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxFifoOverflowCts) },
+	{ "rx_crc_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxFcsCts) },
+	{ "rx_frame_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxFramingCts) },
+	{ "rx_too_short_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxShortsCts) },
+	{ "rx_too_long_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxTooLongCts) },
+	{ "rx_carrier_extension_errors", SK98LIN_STAT(PnmiStruct.Stat[0].StatRxCextCts) },
+	{ "rx_symbol_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxSymbolCts) },
+	{ "rx_llc_mac_size_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxIRLengthCts) },
+	{ "rx_carrier_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxCarrierCts) },
+	{ "rx_jabber_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxJabberCts) },
+	{ "rx_missed_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxMissedCts) },
+	{ "tx_abort_collision_errors" , SK98LIN_STAT(stats.tx_aborted_errors) },
+	{ "tx_carrier_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxCarrierCts) },
+	{ "tx_buffer_underrun_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxFifoUnderrunCts) },
+	{ "tx_heartbeat_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxCarrierCts) } ,
+	{ "tx_window_errors" , SK98LIN_STAT(stats.tx_window_errors) }
+};
+
+static struct sk98lin_stats sk98lin_etht_stats_port1[] = {
+	{ "rx_packets" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxOkCts) },
+	{ "tx_packets" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxOkCts) },
+	{ "rx_bytes" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxOctetsOkCts) },
+	{ "tx_bytes" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxOctetsOkCts) },
+	{ "rx_errors" , SK98LIN_STAT(PnmiStruct.InErrorsCts) },
+	{ "tx_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxSingleCollisionCts) },
+	{ "rx_dropped" , SK98LIN_STAT(PnmiStruct.RxNoBufCts) },
+	{ "tx_dropped" , SK98LIN_STAT(PnmiStruct.TxNoBufCts) },
+	{ "multicasts" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxMulticastOkCts) },
+	{ "collisions" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxSingleCollisionCts) },
+	{ "rx_length_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxRuntCts) },
+	{ "rx_buffer_overflow_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxFifoOverflowCts) },
+	{ "rx_crc_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxFcsCts) },
+	{ "rx_frame_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxFramingCts) },
+	{ "rx_too_short_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxShortsCts) },
+	{ "rx_too_long_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxTooLongCts) },
+	{ "rx_carrier_extension_errors", SK98LIN_STAT(PnmiStruct.Stat[1].StatRxCextCts) },
+	{ "rx_symbol_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxSymbolCts) },
+	{ "rx_llc_mac_size_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxIRLengthCts) },
+	{ "rx_carrier_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxCarrierCts) },
+	{ "rx_jabber_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxJabberCts) },
+	{ "rx_missed_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxMissedCts) },
+	{ "tx_abort_collision_errors" , SK98LIN_STAT(stats.tx_aborted_errors) },
+	{ "tx_carrier_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxCarrierCts) },
+	{ "tx_buffer_underrun_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxFifoUnderrunCts) },
+	{ "tx_heartbeat_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxCarrierCts) } ,
+	{ "tx_window_errors" , SK98LIN_STAT(stats.tx_window_errors) }
+};
+
+#define SK98LIN_STATS_LEN sizeof(sk98lin_etht_stats_port0) / sizeof(struct sk98lin_stats)
+
+static int nbrBlinkQuarterSeconds;
+static int currentPortIndex;
+static SK_BOOL isLocateNICrunning   = SK_FALSE;
+static SK_BOOL isDualNetCard        = SK_FALSE;
+static SK_BOOL doSwitchLEDsOn       = SK_FALSE;
+static SK_BOOL boardWasDown[2]      = { SK_FALSE, SK_FALSE };
+static struct timer_list locateNICtimer;
+
+/******************************************************************************
+ *
+ * Global Functions
+ *
+ *****************************************************************************/
+
+/*****************************************************************************
+ *
+ * 	SkEthIoctl - IOCTL entry point for all ethtool queries
+ *
+ * Description:
+ *	Any IOCTL request that has to deal with the ethtool command tool is
+ *	dispatched via this function.
+ *
+ * Returns:
+ *	==0:	everything fine, no error
+ *	!=0:	the return value is the error code of the failure 
+ */
+int SkEthIoctl(
+struct net_device *netdev,  /* the pointer to netdev structure       */
+struct ifreq      *ifr)     /* what interface the request refers to? */
+{
+	DEV_NET             *pNet        = (DEV_NET*) netdev->priv;
+	SK_AC               *pAC         = pNet->pAC;
+	void                *pAddr       = ifr->ifr_data;
+	int                  port        = getPortNumber(netdev, ifr);
+	SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct;
+	SK_U32               Size        = sizeof(SK_PNMI_STRUCT_DATA);
+	SK_U32               cmd;
+	struct sk98lin_stats *sk98lin_etht_stats = 
+		(port == 0) ? sk98lin_etht_stats_port0 : sk98lin_etht_stats_port1;
+
+        if (get_user(cmd, (uint32_t *) pAddr)) {
+                return -EFAULT;
+	}
+
+	switch(cmd) {
+#ifdef ETHTOOL_GSET
+	case ETHTOOL_GSET: {
+		struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+		getSettings(pAC, port, &ecmd);
+		if(copy_to_user(pAddr, &ecmd, sizeof(ecmd))) {
+			return -EFAULT;
+		}
+		return 0;
+	}
+	break;
+#endif
+#ifdef ETHTOOL_SSET
+	case ETHTOOL_SSET: {
+		struct ethtool_cmd ecmd;
+		if(copy_from_user(&ecmd, pAddr, sizeof(ecmd))) {
+			return -EFAULT;
+		}
+		return setSettings(pAC, port, &ecmd);
+	}
+	break;
+#endif
+#ifdef ETHTOOL_GDRVINFO
+	case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo drvinfo = { ETHTOOL_GDRVINFO };
+		getDriverInfo(pAC, port, &drvinfo);
+		if(copy_to_user(pAddr, &drvinfo, sizeof(drvinfo))) {
+			return -EFAULT;
+		}
+		return 0;
+	}
+	break;
+#endif
+#ifdef ETHTOOL_GSTRINGS
+	case ETHTOOL_GSTRINGS: {
+		struct ethtool_gstrings gstrings = { ETHTOOL_GSTRINGS };
+		char *strings = NULL;
+		int err = 0;
+		if(copy_from_user(&gstrings, pAddr, sizeof(gstrings))) {
+			return -EFAULT;
+		}
+		switch(gstrings.string_set) {
+#ifdef ETHTOOL_GSTATS
+			case ETH_SS_STATS: {
+				int i;
+				gstrings.len = SK98LIN_STATS_LEN;
+				if ((strings = kmalloc(SK98LIN_STATS_LEN*ETHT_STATSTRING_LEN,GFP_KERNEL)) == NULL) {
+					return -ENOMEM;
+				}
+				for(i=0; i < SK98LIN_STATS_LEN; i++) {
+					memcpy(&strings[i * ETHT_STATSTRING_LEN],
+						&(sk98lin_etht_stats[i].stat_string),
+						ETHT_STATSTRING_LEN);
+				}
+			}
+			break;
+#endif
+			default:
+				return -EOPNOTSUPP;
+		}
+		if(copy_to_user(pAddr, &gstrings, sizeof(gstrings))) {
+			err = -EFAULT;
+		}
+		pAddr += offsetof(struct ethtool_gstrings, data);
+		if(!err && copy_to_user(pAddr, strings, gstrings.len * ETH_GSTRING_LEN)) {
+			err = -EFAULT;
+		}
+		kfree(strings);
+		return err;
+	}
+#endif
+#ifdef ETHTOOL_GSTATS
+	case ETHTOOL_GSTATS: {
+		struct {
+			struct ethtool_stats eth_stats;
+			uint64_t data[SK98LIN_STATS_LEN];
+		} stats = { {ETHTOOL_GSTATS, SK98LIN_STATS_LEN} };
+		int i;
+
+		if (pNet->Up) {
+			SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, port);
+		}
+		for(i = 0; i < SK98LIN_STATS_LEN; i++) {
+			if (pNet->Up) {
+				stats.data[i] = (sk98lin_etht_stats[i].sizeof_stat ==
+					sizeof(uint64_t)) ?
+					*(uint64_t *)((char *)pAC +
+						sk98lin_etht_stats[i].stat_offset) :
+					*(uint32_t *)((char *)pAC +
+						sk98lin_etht_stats[i].stat_offset);
+			} else {
+				stats.data[i] = (sk98lin_etht_stats[i].sizeof_stat ==
+					sizeof(uint64_t)) ? (uint64_t) 0 : (uint32_t) 0;
+			}
+		}
+		if(copy_to_user(pAddr, &stats, sizeof(stats))) {
+			return -EFAULT;
+		}
+		return 0;
+	}
+#endif
+#ifdef ETHTOOL_PHYS_ID
+	case ETHTOOL_PHYS_ID: {
+		struct ethtool_value blinkSecs;
+		if(copy_from_user(&blinkSecs, pAddr, sizeof(blinkSecs))) {
+			return -EFAULT;
+		}
+		return startLocateNIC(pAC, port, &blinkSecs);
+	}
+#endif
+#ifdef ETHTOOL_GPAUSEPARAM
+	case ETHTOOL_GPAUSEPARAM: {
+		struct ethtool_pauseparam epause = { ETHTOOL_GPAUSEPARAM };
+		getPauseParams(pAC, port, &epause);
+		if(copy_to_user(pAddr, &epause, sizeof(epause))) {
+			return -EFAULT;
+		}
+		return 0;
+	}
+#endif
+#ifdef ETHTOOL_SPAUSEPARAM
+	case ETHTOOL_SPAUSEPARAM: {
+		struct ethtool_pauseparam epause;
+		if(copy_from_user(&epause, pAddr, sizeof(epause))) {
+			return -EFAULT;
+		}
+		return setPauseParams(pAC, port, &epause);
+	}
+#endif
+#ifdef ETHTOOL_GSG
+	case ETHTOOL_GSG: {
+		struct ethtool_value edata = { ETHTOOL_GSG };
+		edata.data = (netdev->features & NETIF_F_SG) != 0;
+		if (copy_to_user(pAddr, &edata, sizeof(edata))) {
+			return -EFAULT;
+		}
+		return 0;
+	}
+#endif
+#ifdef ETHTOOL_SSG
+	case ETHTOOL_SSG: {
+		struct ethtool_value edata;
+		if (copy_from_user(&edata, pAddr, sizeof(edata))) {
+                        return -EFAULT;
+		}
+		if (pAC->ChipsetType) {
+		/* Don't handle if Genesis chipset */
+			if (edata.data) {
+				netdev->features |= NETIF_F_SG;
+			} else {
+				netdev->features &= ~NETIF_F_SG;
+			}
+		}
+		return 0;
+	}
+#endif
+#ifdef ETHTOOL_GRXCSUM
+	case ETHTOOL_GRXCSUM: {
+		struct ethtool_value edata = { ETHTOOL_GRXCSUM };
+		edata.data = pAC->RxPort[port].UseRxCsum;
+		if (copy_to_user(pAddr, &edata, sizeof(edata))) {
+			return -EFAULT;
+		}
+		return 0;
+	}
+#endif
+#ifdef ETHTOOL_SRXCSUM
+	case ETHTOOL_SRXCSUM: {
+		struct ethtool_value edata;
+		if (copy_from_user(&edata, pAddr, sizeof(edata))) {
+			return -EFAULT;
+		}
+		pAC->RxPort[port].UseRxCsum = edata.data;
+                return 0;
+	}
+#endif
+#ifdef ETHTOOL_GTXCSUM
+	case ETHTOOL_GTXCSUM: {
+		struct ethtool_value edata = { ETHTOOL_GTXCSUM };
+		edata.data = ((netdev->features & NETIF_F_IP_CSUM) != 0);
+		if (copy_to_user(pAddr, &edata, sizeof(edata))) {
+			return -EFAULT;
+		}
+		return 0;
+	}
+#endif
+#ifdef ETHTOOL_STXCSUM
+	case ETHTOOL_STXCSUM: {
+		struct ethtool_value edata;
+		if (copy_from_user(&edata, pAddr, sizeof(edata))) {
+			return -EFAULT;
+		}
+
+		if (pAC->ChipsetType) {
+		/* Don't handle if Genesis chipset */
+			if (edata.data) {
+				netdev->features |= NETIF_F_IP_CSUM;
+			} else {
+				netdev->features &= ~NETIF_F_IP_CSUM;
+			}
+		}
+		return 0;
+	}
+#endif
+#ifdef ETHTOOL_NWAY_RST
+	case ETHTOOL_NWAY_RST: {
+		if(netif_running(netdev)) {
+			(*netdev->stop)(netdev);
+			(*netdev->open)(netdev);
+		}
+		return 0;
+	}
+#endif
+#ifdef NETIF_F_TSO
+#ifdef ETHTOOL_GTSO
+	case ETHTOOL_GTSO: {
+		struct ethtool_value edata = { ETHTOOL_GTSO };
+		edata.data = (netdev->features & NETIF_F_TSO) != 0;
+		if (copy_to_user(pAddr, &edata, sizeof(edata))) {
+			return -EFAULT;
+		}
+		return 0;
+	}
+#endif
+#ifdef ETHTOOL_STSO
+	case ETHTOOL_STSO: {
+		struct ethtool_value edata;
+		if (CHIP_ID_YUKON_2(pAC)) {
+			if (copy_from_user(&edata, pAddr, sizeof(edata))) {
+				return -EFAULT;
+			}
+			if (edata.data) {
+				netdev->features |= NETIF_F_TSO;
+			} else {
+				netdev->features &= ~NETIF_F_TSO;
+			}
+			return 0;
+		}
+                return -EOPNOTSUPP;
+	}
+#endif
+#endif
+#ifdef ETHTOOL_GCOALESCE
+	case ETHTOOL_GCOALESCE: {
+		struct ethtool_coalesce ecoalesc = { ETHTOOL_GCOALESCE };
+		getModerationParams(pAC, port, &ecoalesc);
+		if(copy_to_user(pAddr, &ecoalesc, sizeof(ecoalesc))) {
+			return -EFAULT;
+		}
+		return 0;
+	}
+#endif
+#ifdef ETHTOOL_SCOALESCE
+	case ETHTOOL_SCOALESCE: {
+		struct ethtool_coalesce ecoalesc;
+		if(copy_from_user(&ecoalesc, pAddr, sizeof(ecoalesc))) {
+			return -EFAULT;
+		}
+		return setModerationParams(pAC, port, &ecoalesc);
+	}
+#endif
+#ifdef ETHTOOL_GWOL
+	case ETHTOOL_GWOL: {
+		struct ethtool_wolinfo ewol = { ETHTOOL_GWOL };
+		getWOLsettings(pAC, port, &ewol);
+		if(copy_to_user(pAddr, &ewol, sizeof(ewol))) {
+			return -EFAULT;
+		}
+		return 0;
+	}
+#endif
+#ifdef ETHTOOL_SWOL
+	case ETHTOOL_SWOL: {
+		struct ethtool_wolinfo ewol;
+		if(copy_from_user(&ewol, pAddr, sizeof(ewol))) {
+			return -EFAULT;
+		}
+		return setWOLsettings(pAC, port, &ewol);
+	}
+#endif
+        default:
+                return -EOPNOTSUPP;
+        }
+} /* SkEthIoctl() */
+
+/******************************************************************************
+ *
+ * Local Functions
+ *
+ *****************************************************************************/
+
+#ifdef ETHTOOL_GSET
+/*****************************************************************************
+ *
+ * 	getSettings - retrieves the current settings of the selected adapter
+ *
+ * Description:
+ *	The current configuration of the selected adapter is returned.
+ *	This configuration involves a)speed, b)duplex and c)autoneg plus
+ *	a number of other variables.
+ *
+ * Returns:	N/A
+ *
+ */
+static void getSettings(
+SK_AC              *pAC,  /* pointer to adapter control context      */
+int                 port, /* the port of the selected adapter        */
+struct ethtool_cmd *ecmd) /* mandatory command structure for results */
+{
+	SK_GEPORT *pPort = &pAC->GIni.GP[port];
+
+	static int DuplexAutoNegConfMap[9][3]= {
+		{ -1                     , -1         , -1              },
+		{ 0                      , -1         , -1              },
+		{ SK_LMODE_HALF          , DUPLEX_HALF, AUTONEG_DISABLE },
+		{ SK_LMODE_FULL          , DUPLEX_FULL, AUTONEG_DISABLE },
+		{ SK_LMODE_AUTOHALF      , DUPLEX_HALF, AUTONEG_ENABLE  },
+		{ SK_LMODE_AUTOFULL      , DUPLEX_FULL, AUTONEG_ENABLE  },
+		{ SK_LMODE_AUTOBOTH      , DUPLEX_FULL, AUTONEG_ENABLE  },
+		{ SK_LMODE_AUTOSENSE     , -1         , -1              },
+		{ SK_LMODE_INDETERMINATED, -1         , -1              }
+	};
+
+	static int SpeedConfMap[6][2] = {
+		{ 0                       , -1 },
+		{ SK_LSPEED_AUTO          , SPEED_1000 },
+		{ SK_LSPEED_10MBPS        , SPEED_10   },
+		{ SK_LSPEED_100MBPS       , SPEED_100  },
+		{ SK_LSPEED_1000MBPS      , SPEED_1000 },
+		{ SK_LSPEED_INDETERMINATED, 0          }
+	};
+
+	ecmd->phy_address = port;
+	ecmd->speed       = SpeedConfMap[pPort->PLinkSpeedUsed][1];
+	ecmd->duplex      = DuplexAutoNegConfMap[pPort->PLinkModeStatus][1];
+	ecmd->autoneg     = DuplexAutoNegConfMap[pPort->PLinkModeStatus][2];
+	ecmd->transceiver = XCVR_INTERNAL;
+
+	if (pAC->GIni.GICopperType) {
+		ecmd->port        = PORT_TP;
+		ecmd->supported   = (SUPP_COPPER_ALL|SUPPORTED_Autoneg);
+		ecmd->advertising = (ADV_COPPER_ALL);
+		if (ecmd->autoneg == AUTONEG_ENABLE) {
+			ecmd->advertising |= ADVERTISED_Autoneg;
+		} 
+	} else {
+		ecmd->port        = PORT_FIBRE;
+		ecmd->supported   = (SUPP_FIBRE_ALL);
+		ecmd->advertising = (ADV_FIBRE_ALL);
+	}
+}
+#endif
+
+#ifdef ETHTOOL_SSET
+/*****************************************************************************
+ *
+ *	setSettings - configures the settings of a selected adapter
+ *
+ * Description:
+ *	Possible settings that may be altered are a)speed, b)duplex or 
+ *	c)autonegotiation.
+ *
+ * Returns:
+ *	==0:	everything fine, no error
+ *	!=0:	the return value is the error code of the failure 
+ */
+static int setSettings(
+SK_AC              *pAC,  /* pointer to adapter control context    */
+int                 port, /* the port of the selected adapter      */
+struct ethtool_cmd *ecmd) /* command structure containing settings */
+{
+	DEV_NET     *pNet  = (DEV_NET *) pAC->dev[port]->priv;
+	SK_U32       Instance;
+	char         Buf[4];
+	unsigned int Len = 1;
+	int Ret;
+
+	if (port == 0) {
+		Instance = (pAC->RlmtNets == 2) ? 1 : 2;
+	} else {
+		Instance = (pAC->RlmtNets == 2) ? 2 : 3;
+	}
+
+	if (ecmd->autoneg == AUTONEG_DISABLE) {
+		if (ecmd->duplex == DUPLEX_FULL) { 
+			*Buf = (char) SK_LMODE_FULL;
+		} else {
+			*Buf = (char) SK_LMODE_HALF;
+		}
+	} else {
+		if (ecmd->duplex == DUPLEX_FULL) { 
+			*Buf = (char) SK_LMODE_AUTOFULL;
+		} else {
+			*Buf = (char) SK_LMODE_AUTOHALF;
+		}
+	}
+
+	Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE, 
+				&Buf, &Len, Instance, pNet->NetNr);
+
+	if (Ret != SK_PNMI_ERR_OK) {
+		return -EINVAL;
+	}
+
+	if (ecmd->speed == SPEED_1000) {
+		*Buf = (char) SK_LSPEED_1000MBPS;
+	} else if (ecmd->speed == SPEED_100) {
+		*Buf = (char) SK_LSPEED_100MBPS;
+	} else {
+		*Buf = (char) SK_LSPEED_10MBPS;
+	}
+
+	Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, 
+				&Buf, &Len, Instance, pNet->NetNr);
+
+	if (Ret != SK_PNMI_ERR_OK) {
+		return -EINVAL;
+	}
+	return 0;
+}
+#endif
+
+#ifdef ETHTOOL_GPAUSEPARAM
+/*****************************************************************************
+ *
+ * 	getPauseParams - retrieves the pause parameters
+ *
+ * Description:
+ *	All current pause parameters of a selected adapter are placed 
+ *	in the passed ethtool_pauseparam structure and are returned.
+ *
+ * Returns:	N/A
+ *
+ */
+static void getPauseParams(
+SK_AC                     *pAC,    /* pointer to adapter control context */
+int                        port,   /* the port of the selected adapter   */
+struct ethtool_pauseparam *epause) /* pause parameter struct for result  */
+{
+	SK_GEPORT *pPort            = &pAC->GIni.GP[port];
+	SK_BOOL    isAutoNegEnabled = SK_TRUE;
+
+	if (pPort->PLinkModeConf == SK_LMODE_HALF || 
+	    pPort->PLinkModeConf == SK_LMODE_FULL) {
+                isAutoNegEnabled = SK_FALSE;
+        }
+
+	epause->autoneg  = isAutoNegEnabled;
+	epause->rx_pause = 0;
+	epause->tx_pause = 0;
+
+	if (isAutoNegEnabled) {
+		if (pPort->PFlowCtrlMode & SK_FLOW_MODE_LOC_SEND) {
+			epause->tx_pause = 1;
+		}
+		if ((pPort->PFlowCtrlMode & SK_FLOW_MODE_SYMMETRIC) ||
+		    (pPort->PFlowCtrlMode & SK_FLOW_MODE_SYM_OR_REM)) {
+			epause->tx_pause = 1;
+			epause->rx_pause = 1;
+		}
+	}
+}
+#endif
+
+#ifdef ETHTOOL_SPAUSEPARAM
+/*****************************************************************************
+ *
+ *	setPauseParams - configures the pause parameters of an adapter
+ *
+ * Description:
+ *	This function sets the Rx or Tx pause parameters 
+ *
+ * Returns:
+ *	==0:	everything fine, no error
+ *	!=0:	the return value is the error code of the failure 
+ */
+static int setPauseParams(
+SK_AC                     *pAC,    /* pointer to adapter control context */
+int                        port,   /* the port of the selected adapter   */
+struct ethtool_pauseparam *epause) /* pause parameter struct with params */
+{
+	SK_GEPORT *pPort            = &pAC->GIni.GP[port];
+	DEV_NET   *pNet             = (DEV_NET *) pAC->dev[port]->priv;
+	int        PrevSpeedVal     = pPort->PLinkSpeedUsed;
+
+	SK_U32       Instance;
+	char         Buf[4];
+	unsigned int	Len = 1;
+	int		Ret;
+
+        if (port == 0) {
+                Instance = (pAC->RlmtNets == 2) ? 1 : 2;
+        } else {
+                Instance = (pAC->RlmtNets == 2) ? 2 : 3;
+        }
+
+	if (epause->autoneg == AUTONEG_DISABLE) {
+		if (pPort->PLinkModeConf == SK_LMODE_AUTOHALF) {
+			*Buf = (char) SK_LMODE_HALF;
+		}
+		if ((pPort->PLinkModeConf == SK_LMODE_AUTOFULL) ||
+		    (pPort->PLinkModeConf == SK_LMODE_AUTOBOTH)) {
+			*Buf = (char) SK_LMODE_FULL;
+		}
+	} 
+
+	if (epause->autoneg == AUTONEG_ENABLE) {
+		if (pPort->PLinkModeConf == SK_LMODE_HALF) {
+			// pPort->PLinkModeConf = SK_LMODE_AUTOHALF;
+			*Buf = (char) SK_LMODE_AUTOHALF;
+		}
+		if (pPort->PLinkModeConf == SK_LMODE_FULL) {
+			// pPort->PLinkModeConf = SK_LMODE_AUTOBOTH;
+			*Buf = (char) SK_LMODE_AUTOBOTH;
+		}
+	}
+
+        Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE,
+                                &Buf, &Len, Instance, pNet->NetNr);
+
+        if (Ret != SK_PNMI_ERR_OK) {
+                printk("ethtool: error changing autoneg parameter\n");
+        }
+
+	if(epause->rx_pause && epause->tx_pause) {
+		// pPort->PFlowCtrlMode = SK_FLOW_MODE_SYMMETRIC;
+		*Buf = (char) SK_FLOW_MODE_SYMMETRIC;
+	} else if (epause->rx_pause && !epause->tx_pause) {
+		// pPort->PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
+		*Buf = (char) SK_FLOW_MODE_SYM_OR_REM;
+	} else if(!epause->rx_pause && epause->tx_pause) {
+		// pPort->PFlowCtrlMode = SK_FLOW_MODE_LOC_SEND;
+		*Buf = (char) SK_FLOW_MODE_LOC_SEND;
+	} else {
+		// pPort->PFlowCtrlMode = SK_FLOW_MODE_NONE;
+		*Buf = (char) SK_FLOW_MODE_NONE;
+	}
+
+        Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_FLOWCTRL_MODE,
+                                &Buf, &Len, Instance, pNet->NetNr);
+
+        if (Ret != SK_PNMI_ERR_OK) {
+                printk("ethtool: error changing rx/tx pause parameters\n");
+        }
+
+	/*
+	** It may be that autoneg has been disabled! Therefore set
+	** the speed to the previously used value...
+	*/
+	if (epause->autoneg == AUTONEG_DISABLE) {
+		if ((PrevSpeedVal == SK_LSPEED_AUTO) ||
+		    (PrevSpeedVal == SK_LSPEED_INDETERMINATED)) {
+			PrevSpeedVal = SK_LSPEED_100MBPS;
+		}
+		*Buf = (char) PrevSpeedVal;
+
+		Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, 
+					&Buf, &Len, Instance, pNet->NetNr);
+
+		if (Ret != SK_PNMI_ERR_OK) {
+			printk("ethtool: setting the speed parameter\n");
+		}
+	}
+        return 0;
+}
+#endif
+
+#ifdef ETHTOOL_GCOALESCE
+/*****************************************************************************
+ *
+ * 	getModerationParams - retrieves the IRQ moderation settings 
+ *
+ * Description:
+ *	All current IRQ moderation settings of a selected adapter are placed 
+ *	in the passed ethtool_coalesce structure and are returned.
+ *
+ * Returns:	N/A
+ *
+ */
+static void getModerationParams(
+SK_AC                   *pAC,      /* pointer to adapter control context */
+int                      port,     /* the port of the selected adapter   */
+struct ethtool_coalesce *ecoalesc) /* IRQ moderation struct for results  */
+{
+	DIM_INFO *Info = &pAC->DynIrqModInfo;
+	SK_BOOL UseTxIrqModeration = SK_FALSE;
+	SK_BOOL UseRxIrqModeration = SK_FALSE;
+
+	if (Info->IntModTypeSelect != C_INT_MOD_NONE) {
+		if (CHIP_ID_YUKON_2(pAC)) {
+			UseRxIrqModeration = SK_TRUE;
+			UseTxIrqModeration = SK_TRUE;
+		} else {
+			if ((Info->MaskIrqModeration == IRQ_MASK_RX_ONLY) ||
+			    (Info->MaskIrqModeration == IRQ_MASK_SP_RX)   ||
+			    (Info->MaskIrqModeration == IRQ_MASK_RX_TX_SP)) {
+				UseRxIrqModeration = SK_TRUE;
+			}
+			if ((Info->MaskIrqModeration == IRQ_MASK_TX_ONLY) ||
+			    (Info->MaskIrqModeration == IRQ_MASK_SP_TX)   ||
+			    (Info->MaskIrqModeration == IRQ_MASK_RX_TX_SP)) {
+				UseTxIrqModeration = SK_TRUE;
+			}
+		}
+
+		if (UseRxIrqModeration) {
+			ecoalesc->rx_coalesce_usecs = 1000000 / Info->MaxModIntsPerSec;
+		}
+		if (UseTxIrqModeration) {
+			ecoalesc->tx_coalesce_usecs = 1000000 / Info->MaxModIntsPerSec;
+		}
+		if (Info->IntModTypeSelect == C_INT_MOD_DYNAMIC) {
+			ecoalesc->rate_sample_interval = Info->DynIrqModSampleInterval; 
+			if (UseRxIrqModeration) {
+				ecoalesc->use_adaptive_rx_coalesce = 1;
+				ecoalesc->rx_coalesce_usecs_low = 
+					1000000 / Info->MaxModIntsPerSecLowerLimit;
+				ecoalesc->rx_coalesce_usecs_high = 
+					1000000 / Info->MaxModIntsPerSecUpperLimit;
+			}
+			if (UseTxIrqModeration) {
+				ecoalesc->use_adaptive_tx_coalesce = 1;
+				ecoalesc->tx_coalesce_usecs_low = 
+					1000000 / Info->MaxModIntsPerSecLowerLimit;
+				ecoalesc->tx_coalesce_usecs_high = 
+					1000000 / Info->MaxModIntsPerSecUpperLimit;
+			}
+		}
+	}
+}
+#endif
+
+#ifdef ETHTOOL_SCOALESCE
+/*****************************************************************************
+ *
+ *	setModerationParams - configures the IRQ moderation of an adapter
+ *
+ * Description:
+ *	Depending on the desired IRQ moderation parameters, either a) static,
+ *	b) dynamic or c) no moderation is configured. 
+ *
+ * Returns:
+ *	==0:	everything fine, no error
+ *	!=0:	the return value is the error code of the failure 
+ */
+static int setModerationParams(
+SK_AC                   *pAC,      /* pointer to adapter control context */
+int                      port,     /* the port of the selected adapter   */
+struct ethtool_coalesce *ecoalesc) /* IRQ moderation struct with params  */
+{
+	DIM_INFO  *Info             = &pAC->DynIrqModInfo;
+	int        PrevModeration   = Info->IntModTypeSelect;
+
+	if ((ecoalesc->rx_coalesce_usecs) || (ecoalesc->tx_coalesce_usecs)) {
+		if (!CHIP_ID_YUKON_2(pAC)) {
+			if ((Info->MaskIrqModeration == IRQ_MASK_SP_RX) ||
+			    (Info->MaskIrqModeration == IRQ_MASK_SP_TX) ||
+			    (Info->MaskIrqModeration == IRQ_MASK_RX_TX_SP)) {
+				Info->MaskIrqModeration = IRQ_MASK_SP_ONLY;
+			} 
+		}
+		Info->IntModTypeSelect = C_INT_MOD_STATIC;
+		if (ecoalesc->rx_coalesce_usecs) {
+			Info->MaxModIntsPerSec = 
+				1000000 / ecoalesc->rx_coalesce_usecs;
+			if (!CHIP_ID_YUKON_2(pAC)) {
+				if (Info->MaskIrqModeration == IRQ_MASK_TX_ONLY) {
+					Info->MaskIrqModeration = IRQ_MASK_TX_RX;
+				} 
+				if (Info->MaskIrqModeration == IRQ_MASK_SP_ONLY) {
+					Info->MaskIrqModeration = IRQ_MASK_SP_RX;
+				} 
+				if (Info->MaskIrqModeration == IRQ_MASK_SP_TX) {
+					Info->MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+				}
+			} else {
+				Info->MaskIrqModeration = Y2_IRQ_MASK;
+			}
+		}
+		if (ecoalesc->tx_coalesce_usecs) {
+			Info->MaxModIntsPerSec = 
+				1000000 / ecoalesc->tx_coalesce_usecs;
+			if (!CHIP_ID_YUKON_2(pAC)) {
+				if (Info->MaskIrqModeration == IRQ_MASK_RX_ONLY) {
+					Info->MaskIrqModeration = IRQ_MASK_TX_RX;
+				} 
+				if (Info->MaskIrqModeration == IRQ_MASK_SP_ONLY) {
+					Info->MaskIrqModeration = IRQ_MASK_SP_TX;
+				} 
+				if (Info->MaskIrqModeration == IRQ_MASK_SP_RX) {
+					Info->MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+				}
+			} else {
+				Info->MaskIrqModeration = Y2_IRQ_MASK;
+			}
+		}
+		if ((ecoalesc->rate_sample_interval)  ||
+		    (ecoalesc->rx_coalesce_usecs_low) ||
+		    (ecoalesc->tx_coalesce_usecs_low) ||
+		    (ecoalesc->rx_coalesce_usecs_high)||
+		    (ecoalesc->tx_coalesce_usecs_high)) {
+			Info->IntModTypeSelect = C_INT_MOD_DYNAMIC;
+			if (ecoalesc->rate_sample_interval) {
+				Info->DynIrqModSampleInterval = 
+					ecoalesc->rate_sample_interval; 
+			}
+			if (ecoalesc->rx_coalesce_usecs_low) {
+				Info->MaxModIntsPerSecLowerLimit = 
+					1000000 / ecoalesc->rx_coalesce_usecs_low;
+			}
+			if (ecoalesc->tx_coalesce_usecs_low) {
+				Info->MaxModIntsPerSecLowerLimit = 
+					1000000 / ecoalesc->tx_coalesce_usecs_low;
+			}
+			if (ecoalesc->rx_coalesce_usecs_high) {
+				Info->MaxModIntsPerSecUpperLimit = 
+					1000000 / ecoalesc->rx_coalesce_usecs_high;
+			}
+			if (ecoalesc->tx_coalesce_usecs_high) {
+				Info->MaxModIntsPerSecUpperLimit = 
+					1000000 / ecoalesc->tx_coalesce_usecs_high;
+			}
+		}
+	} else {
+		Info->IntModTypeSelect = C_INT_MOD_NONE;
+	}
+
+	if ((PrevModeration         == C_INT_MOD_NONE) &&
+	    (Info->IntModTypeSelect != C_INT_MOD_NONE)) {
+		SkDimEnableModerationIfNeeded(pAC);
+	}
+	if ((PrevModeration         != C_INT_MOD_NONE) &&
+	    (Info->IntModTypeSelect == C_INT_MOD_NONE)) {
+		SkDimDisableModeration(pAC, PrevModeration);
+	}
+
+        return 0;
+}
+#endif
+
+#ifdef ETHTOOL_GWOL
+/*****************************************************************************
+ *
+ * 	getWOLsettings - retrieves the WOL settings of the selected adapter
+ *
+ * Description:
+ *	All current WOL settings of a selected adapter are placed in the 
+ *	passed ethtool_wolinfo structure and are returned to the caller.
+ *
+ * Returns:	N/A
+ *
+ */
+static void getWOLsettings(
+SK_AC                  *pAC,  /* pointer to adapter control context  */
+int                     port, /* the port of the selected adapter    */
+struct ethtool_wolinfo *ewol) /* mandatory WOL structure for results */
+{
+	ewol->supported = 
+		WAKE_PHY|WAKE_MAGIC|WAKE_UCAST|WAKE_MCAST|WAKE_BCAST;
+	
+	ewol->wolopts =
+		WAKE_PHY|WAKE_MAGIC|WAKE_UCAST|WAKE_MCAST|WAKE_BCAST;
+
+	return;
+}
+#endif
+
+#ifdef ETHTOOL_SWOL
+/*****************************************************************************
+ *
+ *	setWOLsettings - configures the WOL settings of a selected adapter
+ *
+ * Description:
+ *	The WOL settings of a selected adapter are configured regarding
+ *	the parameters in the passed ethtool_wolinfo structure.
+ *
+ * Returns:
+ *	==0:	everything fine, no error
+ *	!=0:	the return value is the error code of the failure 
+ */
+static int setWOLsettings(
+SK_AC                  *pAC,  /* pointer to adapter control context */
+int                     port, /* the port of the selected adapter   */
+struct ethtool_wolinfo *ewol) /* WOL structure containing settings  */
+{
+	return 0;
+}
+#endif
+
+#ifdef ETHTOOL_GDRVINFO
+/*****************************************************************************
+ *
+ * 	getDriverInfo - returns generic driver and adapter information
+ *
+ * Description:
+ *	Generic driver information is returned via this function, such as
+ *	the name of the driver, its version and and firmware version.
+ *	In addition to this, the location of the selected adapter is 
+ *	returned as a bus info string (e.g. '01:05.0').
+ *	
+ * Returns:	N/A
+ *
+ */
+static void getDriverInfo(
+SK_AC                  *pAC,      /* pointer to adapter control context   */
+int                     port,     /* the port of the selected adapter     */
+struct ethtool_drvinfo *edrvinfo) /* mandatory info structure for results */
+{
+	char versionString[32];
+
+	snprintf(versionString, 32, "%s (%s)", VER_STRING, PATCHLEVEL);
+	strncpy(edrvinfo->driver, DRIVER_FILE_NAME , 32);
+	strncpy(edrvinfo->version, versionString , 32);
+	strncpy(edrvinfo->fw_version, "N/A", 32);
+	strncpy(edrvinfo->bus_info, pAC->PciDev->slot_name, 32);
+#ifdef  ETHTOOL_GSTATS
+	edrvinfo->n_stats = SK98LIN_STATS_LEN;
+#endif
+}
+#endif
+
+#ifdef ETHTOOL_PHYS_ID
+/*****************************************************************************
+ *
+ * 	startLocateNIC - start the locate NIC feature of the elected adapter 
+ *
+ * Description:
+ *	This function is used if the user want to locate a particular NIC.
+ *	All LEDs are regularly switched on and off, so the NIC can easily
+ *	be identified.
+ *
+ * Returns:	
+ *	==0:	everything fine, no error, locateNIC test was started
+ *	!=0:	one locateNIC test runs already
+ *
+ */
+static int startLocateNIC(
+SK_AC                *pAC,        /* pointer to adapter control context        */
+int                   port,       /* the port of the selected adapter          */
+struct ethtool_value *blinkSecs)  /* how long the LEDs should blink in seconds */
+{
+	struct SK_NET_DEVICE *pDev      = pAC->dev[port];
+	DEV_NET              *pNet      = (DEV_NET *) pAC->dev[port]->priv;
+	int                   OtherPort = (port) ? 0 : 1;
+	struct SK_NET_DEVICE *pOtherDev = pAC->dev[OtherPort];
+	DEV_NET              *pOtherNet = (DEV_NET *) pAC->dev[OtherPort]->priv;
+
+	if (isLocateNICrunning) {
+		return -EFAULT;
+	}
+	isLocateNICrunning = SK_TRUE;
+	currentPortIndex = port;
+	isDualNetCard = (pDev != pOtherDev) ? SK_TRUE : SK_FALSE;
+
+	if (!pNet->Up) {
+		(*pDev->open)(pDev);
+		boardWasDown[0] = SK_TRUE;
+	} else {
+		boardWasDown[0] = SK_FALSE;
+	}
+
+	if (isDualNetCard) {
+		if (!pOtherNet->Up) {
+			(*pOtherDev->open)(pOtherDev);
+			boardWasDown[1] = SK_TRUE;
+		} else {
+			boardWasDown[1] = SK_FALSE;
+		}
+	}
+
+	if ((blinkSecs->data < 1) || (blinkSecs->data > 30)) {
+		blinkSecs->data = 3; /* three seconds default */
+	}
+	nbrBlinkQuarterSeconds = 4*blinkSecs->data;
+
+	init_timer(&locateNICtimer);
+	locateNICtimer.function = toggleLeds;
+	locateNICtimer.data     = (unsigned long) pAC;
+	locateNICtimer.expires  = jiffies + 1*HZ; /* initially 1sec */
+	add_timer(&locateNICtimer);
+
+	return 0;
+}
+
+/*****************************************************************************
+ *
+ * 	toggleLeds - Changes the LED state of an adapter
+ *
+ * Description:
+ *	This function changes the current state of all LEDs of an adapter so
+ *	that it can be located by a user. If the requested time interval for
+ *	this test has elapsed, this function cleans up everything that was 
+ *	temporarily setup during the locate NIC test. This involves of course
+ *	also closing or opening any adapter so that the initial board state 
+ *	is recovered.
+ *
+ * Returns:	N/A
+ *
+ */
+static void toggleLeds(
+unsigned long ptr)  /* holds the pointer to adapter control context */
+{
+	SK_AC                *pAC       = (SK_AC *) ptr;
+	int                   port      = currentPortIndex;
+	SK_IOC                IoC       = pAC->IoBase;
+	struct SK_NET_DEVICE *pDev      = pAC->dev[port];
+	int                   OtherPort = (port) ? 0 : 1;
+	struct SK_NET_DEVICE *pOtherDev = pAC->dev[OtherPort];
+
+	SK_U16  YukLedOn = (PHY_M_LED_MO_DUP(MO_LED_ON)  |
+			    PHY_M_LED_MO_10(MO_LED_ON)   |
+			    PHY_M_LED_MO_100(MO_LED_ON)  |
+			    PHY_M_LED_MO_1000(MO_LED_ON) | 
+			    PHY_M_LED_MO_RX(MO_LED_ON));
+	SK_U16  YukLedOff = (PHY_M_LED_MO_DUP(MO_LED_OFF)  |
+			     PHY_M_LED_MO_10(MO_LED_OFF)   |
+			     PHY_M_LED_MO_100(MO_LED_OFF)  |
+			     PHY_M_LED_MO_1000(MO_LED_OFF) | 
+			     PHY_M_LED_MO_RX(MO_LED_OFF));
+
+	nbrBlinkQuarterSeconds--;
+	if (nbrBlinkQuarterSeconds <= 0) {
+		(*pDev->stop)(pDev);
+		if (isDualNetCard) {
+			(*pOtherDev->stop)(pOtherDev);
+		}
+
+		if (!boardWasDown[0]) {
+			(*pDev->open)(pDev);
+		}
+		if (isDualNetCard) {
+			(*pOtherDev->open)(pOtherDev);
+		}
+		isDualNetCard      = SK_FALSE;
+		isLocateNICrunning = SK_FALSE;
+		return;
+	}
+
+	doSwitchLEDsOn = (doSwitchLEDsOn) ? SK_FALSE : SK_TRUE;
+	if (doSwitchLEDsOn) {
+		if (pAC->GIni.GIGenesis) {
+			SK_OUT8(IoC,MR_ADDR(port,LNK_LED_REG),(SK_U8)SK_LNK_ON);
+			SkGeYellowLED(pAC,IoC,LED_ON >> 1);
+			SkGeXmitLED(pAC,IoC,MR_ADDR(port,RX_LED_INI),SK_LED_TST);
+			if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM) {
+				SkXmPhyWrite(pAC,IoC,port,PHY_BCOM_P_EXT_CTRL,PHY_B_PEC_LED_ON);
+			} else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE) {
+				SkXmPhyWrite(pAC,IoC,port,PHY_LONE_LED_CFG,0x0800);
+			} else {
+				SkGeXmitLED(pAC,IoC,MR_ADDR(port,TX_LED_INI),SK_LED_TST);
+			}
+		} else {
+			SkGmPhyWrite(pAC,IoC,port,PHY_MARV_LED_CTRL,0);
+			SkGmPhyWrite(pAC,IoC,port,PHY_MARV_LED_OVER,YukLedOn);
+		}
+	} else {
+		if (pAC->GIni.GIGenesis) {
+			SK_OUT8(IoC,MR_ADDR(port,LNK_LED_REG),(SK_U8)SK_LNK_OFF);
+			SkGeYellowLED(pAC,IoC,LED_OFF >> 1);
+			SkGeXmitLED(pAC,IoC,MR_ADDR(port,RX_LED_INI),SK_LED_DIS);
+			if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM) {
+				SkXmPhyWrite(pAC,IoC,port,PHY_BCOM_P_EXT_CTRL,PHY_B_PEC_LED_OFF);
+			} else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE) {
+				SkXmPhyWrite(pAC,IoC,port,PHY_LONE_LED_CFG,PHY_L_LC_LEDT);
+			} else {
+				SkGeXmitLED(pAC,IoC,MR_ADDR(port,TX_LED_INI),SK_LED_DIS);
+			}
+		} else {
+			SkGmPhyWrite(pAC,IoC,port,PHY_MARV_LED_CTRL,0);
+			SkGmPhyWrite(pAC,IoC,port,PHY_MARV_LED_OVER,YukLedOff);
+		}
+	}
+
+	locateNICtimer.function = toggleLeds;
+	locateNICtimer.data     = (unsigned long) pAC;
+	locateNICtimer.expires  = jiffies + (1*HZ)/4; /* 250ms */
+	add_timer(&locateNICtimer);
+} 
+#endif
+
+/*****************************************************************************
+ *
+ * 	getPortNumber - evaluates the port number of an interface
+ *
+ * Description:
+ *	It may be that the current interface refers to one which is located
+ *	on a dual net adapter. Hence, this function will return the correct
+ *	port for further use.
+ *
+ * Returns:
+ *	the port number that corresponds to the selected adapter
+ *
+ */
+static int getPortNumber(
+struct net_device *netdev,  /* the pointer to netdev structure       */
+struct ifreq      *ifr)     /* what interface the request refers to? */
+{
+	DEV_NET *pNet = (DEV_NET*) netdev->priv;
+	SK_AC   *pAC  = pNet->pAC;
+
+	if (pAC->dev[1] != pAC->dev[0]) {
+		if (!strcmp(pAC->dev[1]->name, ifr->ifr_name)) {
+			return 1; /* port index 1 */
+		}
+	}
+	return 0;
+}
+
+/*******************************************************************************
+ *
+ * End of file
+ *
+ ******************************************************************************/
diff -urN linux-2.4.29/drivers/net/sk98lin/skge.c linux-2.4.29-uc1/drivers/net/sk98lin/skge.c
--- linux-2.4.29/drivers/net/sk98lin/skge.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/skge.c	2005-06-14 02:12:09.000000000 +0100
@@ -1,25 +1,23 @@
 /******************************************************************************
  *
- * Name:	skge.c
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.43 $
- * Date:       	$Date: 2004/01/29 15:47:07 $
- * Purpose:	The main driver source module
+ * Name:        skge.c
+ * Project:     GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:     $Revision: 1.59 $
+ * Date:        $Date: 2004/08/17 10:03:26 $
+ * Purpose:     The main driver source module
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
  *	(C)Copyright 1998-2002 SysKonnect GmbH.
- *	(C)Copyright 2002-2003 Marvell.
+ *	(C)Copyright 2002-2004 Marvell.
  *
  *	Driver for Marvell Yukon chipset and SysKonnect Gigabit Ethernet 
  *      Server Adapters.
  *
- *	Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and
- *	SysKonnects GEnesis Solaris driver
- *	Author: Christoph Goos (cgoos@syskonnect.de)
- *	        Mirko Lindner (mlindner@syskonnect.de)
+ *	Author: Mirko Lindner (mlindner@syskonnect.de)
+ *	        Ralph Roesler (rroesler@syskonnect.de)
  *
  *	Address all question to: linux@syskonnect.de
  *
@@ -38,71 +36,33 @@
 
 /******************************************************************************
  *
- * Possible compiler options (#define xxx / -Dxxx):
- *
- *	debugging can be enable by changing SK_DEBUG_CHKMOD and
- *	SK_DEBUG_CHKCAT in makefile (described there).
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
  * Description:
  *
- *	This is the main module of the Linux GE driver.
- *	
- *	All source files except skge.c, skdrv1st.h, skdrv2nd.h and sktypes.h
- *	are part of SysKonnect's COMMON MODULES for the SK-98xx adapters.
- *	Those are used for drivers on multiple OS', so some thing may seem
- *	unnecessary complicated on Linux. Please do not try to 'clean up'
- *	them without VERY good reasons, because this will make it more
- *	difficult to keep the Linux driver in synchronisation with the
- *	other versions.
- *
- * Include file hierarchy:
- *
- *	<linux/module.h>
- *
- *	"h/skdrv1st.h"
- *		<linux/types.h>
- *		<linux/kernel.h>
- *		<linux/string.h>
- *		<linux/errno.h>
- *		<linux/ioport.h>
- *		<linux/slab.h>
- *		<linux/interrupt.h>
- *		<linux/pci.h>
- *		<asm/byteorder.h>
- *		<asm/bitops.h>
- *		<asm/io.h>
- *		<linux/netdevice.h>
- *		<linux/etherdevice.h>
- *		<linux/skbuff.h>
- *	    those three depending on kernel version used:
- *		<linux/bios32.h>
- *		<linux/init.h>
- *		<asm/uaccess.h>
- *		<net/checksum.h>
- *
- *		"h/skerror.h"
- *		"h/skdebug.h"
- *		"h/sktypes.h"
- *		"h/lm80.h"
- *		"h/xmac_ii.h"
- *
- *      "h/skdrv2nd.h"
- *		"h/skqueue.h"
- *		"h/skgehwt.h"
- *		"h/sktimer.h"
- *		"h/ski2c.h"
- *		"h/skgepnmi.h"
- *		"h/skvpd.h"
- *		"h/skgehw.h"
- *		"h/skgeinit.h"
- *		"h/skaddr.h"
- *		"h/skgesirq.h"
- *		"h/skcsum.h"
- *		"h/skrlmt.h"
+ *	All source files in this sk98lin directory except of the sk98lin 
+ *	Linux specific files
+ *
+ *		- skdim.c
+ *		- skethtool.c
+ *		- skge.c
+ *		- skproc.c
+ *		- sky2.c
+ *		- Makefile
+ *		- h/skdrv1st.h
+ *		- h/skdrv2nd.h
+ *		- h/sktypes.h
+ *		- h/skversion.h
+ *
+ *	are part of SysKonnect's common modules for the SK-9xxx adapters.
+ *
+ *	Those common module files which are not Linux specific are used to 
+ *	build drivers on different OS' (e.g. Windows, MAC OS) so that those
+ *	drivers are based on the same set of files
+ *
+ *	At a first glance, this seems to complicate things unnescessarily on 
+ *	Linux, but please do not try to 'clean up' them without VERY good 
+ *	reasons, because this will make it more difficult to keep the sk98lin
+ *	driver for Linux in synchronisation with the other drivers running on
+ *	other operating systems.
  *
  ******************************************************************************/
 
@@ -110,6 +70,7 @@
 
 #include	<linux/module.h>
 #include	<linux/init.h>
+#include	<linux/ethtool.h>
 
 #ifdef CONFIG_PROC_FS
 #include 	<linux/proc_fs.h>
@@ -133,22 +94,17 @@
 /* use the receive hw checksum driver functionality */
 #define USE_SK_RX_CHECKSUM
 
-/* use the scatter-gather functionality with sendfile() */
-#define SK_ZEROCOPY
+/* use TCP segmentation offload if possible */
+#define USE_SK_TSO_FEATURE	
 
-/* use of a transmit complete interrupt */
-#define USE_TX_COMPLETE
-
-/*
- * threshold for copying small receive frames
- * set to 0 to avoid copying, set to 9001 to copy all frames
- */
-#define SK_COPY_THRESHOLD	50
+/* threshold for copying small RX frames; 0 avoids copying, 9001 copies all */
+#define SK_COPY_THRESHOLD 50
 
 /* number of adapters that can be configured via command line params */
-#define SK_MAX_CARD_PARAM	16
-
+#define SK_MAX_CARD_PARAM 16
 
+/* use of a transmit complete interrupt */
+/* #define USE_TX_COMPLETE */
 
 /*
  * use those defines for a compile-in version of the driver instead
@@ -168,21 +124,13 @@
 // #define CON_TYPE 	{"Auto", }
 // #define RLMT_MODE	{"CheckLinkState", }
 
-#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
-#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)
-#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb)
-
-
 /* Set blink mode*/
 #define OEM_CONFIG_VALUE (	SK_ACT_LED_BLINK | \
 				SK_DUP_LED_NORMAL | \
 				SK_LED_LINK100_ON)
 
-
-/* Isr return value */
-#define SkIsrRetVar	void
-#define SkIsrRetNone	NULL
-#define SkIsrRetHandled	NULL
+#define CLEAR_AND_START_RX(Port) SK_OUT8(pAC->IoBase, RxQueueAddr[(Port)]+Q_CSR, CSR_START | CSR_IRQ_CL_F)
+#define CLEAR_TX_IRQ(Port,Prio) SK_OUT8(pAC->IoBase, TxQueueAddr[(Port)][(Prio)]+Q_CSR, CSR_IRQ_CL_F)
 
 
 /*******************************************************************************
@@ -191,12 +139,22 @@
  *
  ******************************************************************************/
 
+static int 	__devinit sk98lin_init_device(struct pci_dev *pdev, const struct pci_device_id *ent);
+static void 	sk98lin_remove_device(struct pci_dev *pdev);
+#ifdef SK_CONFIG_PM
+static int	sk98lin_suspend(struct pci_dev *pdev, uint32_t state);
+static int	sk98lin_resume(struct pci_dev *pdev);
+static void	SkHWSetDState(SK_AC *pAC, SK_IOC IoC, SK_DEVICE_POWER_STATE State);
+static void	SkHWSwitchPower(SK_AC *pAC, SK_IOC IoC, SK_DEVICE_POWER_STATE State);
+static int	SkSetPortSpeed(SK_AC *pAC, SK_IOC IoC, SK_U8 Speed);
+static void	SkEnableWOMagicPacket(SK_AC *pAC, SK_IOC IoC, SK_MAC_ADDR MacAddr);
+#endif
 static void	FreeResources(struct SK_NET_DEVICE *dev);
 static int	SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC);
 static SK_BOOL	BoardAllocMem(SK_AC *pAC);
 static void	BoardFreeMem(SK_AC *pAC);
 static void	BoardInitMem(SK_AC *pAC);
-static void	SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL);
+static void	SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, int*, SK_BOOL);
 static SkIsrRetVar	SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs);
 static SkIsrRetVar	SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs);
 static int	SkGeOpen(struct SK_NET_DEVICE *dev);
@@ -212,24 +170,22 @@
 static void	FreeTxDescriptors(SK_AC*pAC, TX_PORT*);
 static void	FillRxRing(SK_AC*, RX_PORT*);
 static SK_BOOL	FillRxDescriptor(SK_AC*, RX_PORT*);
+#ifdef CONFIG_SK98LIN_NAPI
+static int	SkGePoll(struct net_device *dev, int *budget);
+static void	ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL, int*, int);
+#else
 static void	ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL);
-static void	ClearAndStartRx(SK_AC*, int);
-static void	ClearTxIrq(SK_AC*, int, int);
+#endif
 static void	ClearRxRing(SK_AC*, RX_PORT*);
 static void	ClearTxRing(SK_AC*, TX_PORT*);
 static int	SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu);
 static void	PortReInitBmu(SK_AC*, int);
 static int	SkGeIocMib(DEV_NET*, unsigned int, int);
 static int	SkGeInitPCI(SK_AC *pAC);
-static void	StartDrvCleanupTimer(SK_AC *pAC);
-static void	StopDrvCleanupTimer(SK_AC *pAC);
-static int	XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);
-
-#ifdef SK_DIAG_SUPPORT
 static SK_U32   ParseDeviceNbrFromSlotName(const char *SlotName);
 static int      SkDrvInitAdapter(SK_AC *pAC, int devNbr);
 static int      SkDrvDeInitAdapter(SK_AC *pAC, int devNbr);
-#endif
+static int	XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);
 
 /*******************************************************************************
  *
@@ -237,6 +193,27 @@
  *
  ******************************************************************************/
 
+extern SK_BOOL SkY2AllocateResources(SK_AC *pAC);
+extern void SkY2FreeResources(SK_AC *pAC);
+extern void SkY2AllocateRxBuffers(SK_AC *pAC,SK_IOC IoC,int Port);
+extern void SkY2FreeRxBuffers(SK_AC *pAC,SK_IOC IoC,int Port);
+extern void SkY2FreeTxBuffers(SK_AC *pAC,SK_IOC IoC,int Port);
+extern SkIsrRetVar SkY2Isr(int irq,void *dev_id,struct pt_regs *ptregs);
+extern int SkY2Xmit(struct sk_buff *skb,struct SK_NET_DEVICE *dev);
+extern void SkY2PortStop(SK_AC *pAC,SK_IOC IoC,int Port,int Dir,int RstMode);
+extern void SkY2PortStart(SK_AC *pAC,SK_IOC IoC,int Port);
+extern int SkY2RlmtSend(SK_AC *pAC,int PortNr,struct sk_buff *pMessage);
+extern void SkY2RestartStatusUnit(SK_AC *pAC);
+#ifdef CONFIG_SK98LIN_NAPI
+extern int SkY2Poll(struct net_device *dev, int *budget);
+#endif
+
+extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);	
+extern void SkDimStartModerationTimer(SK_AC *pAC);
+extern void SkDimModerate(SK_AC *pAC);
+
+extern int SkEthIoctl(struct net_device *netdev, struct ifreq *ifr);
+
 #ifdef CONFIG_PROC_FS
 static const char 	SK_Root_Dir_entry[] = "sk98lin";
 static struct		proc_dir_entry *pSkRootDir = NULL;
@@ -248,11 +225,6 @@
 				void	*data);
 #endif
 
-extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);	
-extern void SkDimDisplayModerationSettings(SK_AC *pAC);
-extern void SkDimStartModerationTimer(SK_AC *pAC);
-extern void SkDimModerate(SK_AC *pAC);
-
 #ifdef DEBUG
 static void	DumpMsg(struct sk_buff*, char*);
 static void	DumpData(char*, int);
@@ -262,13 +234,12 @@
 /* global variables *********************************************************/
 static const char *BootString = BOOT_STRING;
 struct SK_NET_DEVICE *SkGeRootDev = NULL;
-static int probed __initdata = 0;
 static SK_BOOL DoPrintInterfaceChange = SK_TRUE;
 
 /* local variables **********************************************************/
 static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
 static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
-
+static int sk98lin_max_boards_found = 0;
 
 #ifdef CONFIG_PROC_FS
 static struct proc_dir_entry	*pSkRootDir;
@@ -276,271 +247,350 @@
 
 
 
+static struct pci_device_id sk98lin_pci_tbl[] __devinitdata = {
+/*	{ pci_vendor_id, pci_device_id, * SAMPLE ENTRY! *
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, */
+	{ 0x10b7, 0x1700, /* 3Com (10b7), Gigabit Ethernet Adapter */
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ 0x1148, 0x4300, /* SysKonnect (1148), SK-98xx Gigabit Ethernet Server Adapter */
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ 0x1148, 0x4320, /* SysKonnect (1148), SK-98xx V2.0 Gigabit Ethernet Adapter */
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ 0x1148, 0x9E00, /* SysKonnect (1148), SK-9Exx 10/100/1000Base-T Adapter */
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ 0x1186, 0x4c00, /* D-Link (1186), Gigabit Ethernet Adapter */
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ 0x11ab, 0x4320, /* Marvell (11ab), Gigabit Ethernet Controller */
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ 0x11ab, 0x4350, /* Marvell (11ab), Fast Ethernet Controller */
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ 0x11ab, 0x4351, /* Marvell (11ab), Fast Ethernet Controller */
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ 0x11ab, 0x4360, /* Marvell (11ab), Gigabit Ethernet Controller */
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ 0x11ab, 0x4361, /* Marvell (11ab), Gigabit Ethernet Controller */
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ 0x11ab, 0x4362, /* Marvell (11ab), Gigabit Ethernet Controller */
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ 0x11ab, 0x5005, /* Marvell (11ab), Belkin */
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ 0x1371, 0x434e, /* CNet (1371), GigaCard Network Adapter */
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ 0x1737, 0x1032, /* Linksys (1737), Gigabit Network Adapter */
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ 0x1737, 0x1064, /* Linksys (1737), Gigabit Network Adapter */
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, sk98lin_pci_tbl);
+
+static struct pci_driver sk98lin_driver = {
+	.name		= DRIVER_FILE_NAME,
+	.id_table	= sk98lin_pci_tbl,
+	.probe		= sk98lin_init_device,
+	.remove		= __devexit_p(sk98lin_remove_device),
+#ifdef SK_CONFIG_PM
+	.suspend	= sk98lin_suspend,
+	.resume		= sk98lin_resume
+#endif
+};
+
+
 /*****************************************************************************
  *
- * 	skge_probe - find all SK-98xx adapters
+ * 	sk98lin_init_device - initialize the adapter
  *
  * Description:
- *	This function scans the PCI bus for SK-98xx adapters. Resources for
- *	each adapter are allocated and the adapter is brought into Init 1
+ *	This function initializes the adapter. Resources for
+ *	the adapter are allocated and the adapter is brought into Init 1
  *	state.
  *
  * Returns:
  *	0, if everything is ok
  *	!=0, on error
  */
-static int __init skge_probe (void)
+static int __devinit sk98lin_init_device(struct pci_dev *pdev,
+				  const struct pci_device_id *ent)
+
 {
-	int			boards_found = 0;
-	int			vendor_flag = SK_FALSE;
+	static SK_BOOL 		sk98lin_boot_string = SK_FALSE;
+	static SK_BOOL 		sk98lin_proc_entry = SK_FALSE;
+	static int		sk98lin_boards_found = 0;
 	SK_AC			*pAC;
 	DEV_NET			*pNet = NULL;
-	struct pci_dev	*pdev = NULL;
 	struct SK_NET_DEVICE *dev = NULL;
-	SK_BOOL DeviceFound = SK_FALSE;
-	SK_BOOL BootStringCount = SK_FALSE;
 	int			retval;
 #ifdef CONFIG_PROC_FS
 	int			proc_root_initialized = 0;
 	struct proc_dir_entry	*pProcFile;
 #endif
 
-	if (probed)
-		return -ENODEV;
-	probed++;
-
-	if (!pci_present()) {		/* is PCI support present? */
-		return -ENODEV;
+	retval = pci_enable_device(pdev);
+	if (retval) {
+		printk(KERN_ERR "Cannot enable PCI device, "
+			"aborting.\n");
+		return retval;
 	}
 
-	while((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev))) {
+	dev = NULL;
+	pNet = NULL;
 
-		dev = NULL;
-		pNet = NULL;
 
+	/* INSERT * We have to find the power-management capabilities */
+	/* Find power-management capability. */
 
-		SK_PCI_ISCOMPLIANT(vendor_flag, pdev);
-		if (!vendor_flag)
-			continue;
 
-		/* Configure DMA attributes. */
-		if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL) &&
-			pci_set_dma_mask(pdev, (u64) 0xffffffff))
-			continue;
 
+	/* Configure DMA attributes. */
+	retval = pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL);
+	if (!retval) {
+		retval = pci_set_dma_mask(pdev, (u64) 0xffffffff);
+		if (retval)
+			return retval;
+	} else {
+		return retval;
+	}
 
-		if ((dev = init_etherdev(dev, sizeof(DEV_NET))) == NULL) {
-			printk(KERN_ERR "Unable to allocate etherdev "
-			       "structure!\n");
-			break;
-		}
 
-		pNet = dev->priv;
-		pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
-		if (pNet->pAC == NULL){
-			unregister_netdev(dev);
-			dev->get_stats = NULL;
-			kfree(dev->priv);
-			printk(KERN_ERR "Unable to allocate adapter "
-			       "structure!\n");
-			break;
-		}
+	if ((dev = init_etherdev(dev, sizeof(DEV_NET))) == NULL) {
+		printk(KERN_ERR "Unable to allocate etherdev "
+			"structure!\n");
+		return -ENODEV;
+	}
 
-		/* Print message */
-		if (!BootStringCount) {
-			/* set display flag to TRUE so that */
-			/* we only display this string ONCE */
-			BootStringCount = SK_TRUE;
-			printk("%s\n", BootString);
-		}
+	pNet = dev->priv;
+	pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
+	if (pNet->pAC == NULL){
+		unregister_netdev(dev);
+		dev->get_stats = NULL;
+		kfree(dev->priv);
+		printk(KERN_ERR "Unable to allocate adapter "
+			"structure!\n");
+		return -ENODEV;
+	}
 
-		memset(pNet->pAC, 0, sizeof(SK_AC));
-		pAC = pNet->pAC;
-		pAC->PciDev = pdev;
-		pAC->PciDevId = pdev->device;
-		pAC->dev[0] = dev;
-		pAC->dev[1] = dev;
-		sprintf(pAC->Name, "SysKonnect SK-98xx");
-		pAC->CheckQueue = SK_FALSE;
 
-		pNet->Mtu = 1500;
-		pNet->Up = 0;
-		dev->irq = pdev->irq;
-		retval = SkGeInitPCI(pAC);
-		if (retval) {
-			printk("SKGE: PCI setup failed: %i\n", retval);
-			unregister_netdev(dev);
-			dev->get_stats = NULL;
-			kfree(dev);
-			continue;
-		}
+	/* Print message */
+	if (!sk98lin_boot_string) {
+		/* set display flag to TRUE so that */
+		/* we only display this string ONCE */
+		sk98lin_boot_string = SK_TRUE;
+		printk("%s\n", BootString);
+	}
+
+	memset(pNet->pAC, 0, sizeof(SK_AC));
+	pAC = pNet->pAC;
+	pAC->PciDev = pdev;
+	pAC->PciDevId = pdev->device;
+	pAC->dev[0] = dev;
+	pAC->dev[1] = dev;
+	sprintf(pAC->Name, "SysKonnect SK-98xx");
+	pAC->CheckQueue = SK_FALSE;
 
-		dev->open =		&SkGeOpen;
-		dev->stop =		&SkGeClose;
+	pNet->Mtu = 1500;
+	pNet->Up = 0;
+	dev->irq = pdev->irq;
+	retval = SkGeInitPCI(pAC);
+	if (retval) {
+		printk("SKGE: PCI setup failed: %i\n", retval);
+		unregister_netdev(dev);
+		dev->get_stats = NULL;
+		kfree(dev);
+		return -ENODEV;
+	}
+
+
+	dev->open =		&SkGeOpen;
+	dev->stop =		&SkGeClose;
+	dev->get_stats =	&SkGeStats;
+	dev->set_multicast_list = &SkGeSetRxMode;
+	dev->set_mac_address =	&SkGeSetMacAddr;
+	dev->do_ioctl =		&SkGeIoctl;
+	dev->change_mtu =	&SkGeChangeMtu;
+	dev->flags &= 		~IFF_RUNNING;
+
+	pAC->Index = sk98lin_boards_found;
+
+	if (SkGeBoardInit(dev, pAC)) {
+		unregister_netdev(dev);
+		kfree(dev);
+		return -ENODEV;
+	} else {
+		ProductStr(pAC);
+	}
+
+	/* shifter to later moment in time... */
+	if (CHIP_ID_YUKON_2(pAC)) {
+		dev->hard_start_xmit =	&SkY2Xmit;
+	} else {
 		dev->hard_start_xmit =	&SkGeXmit;
-		dev->get_stats =	&SkGeStats;
-		dev->set_multicast_list = &SkGeSetRxMode;
-		dev->set_mac_address =	&SkGeSetMacAddr;
-		dev->do_ioctl =		&SkGeIoctl;
-		dev->change_mtu =	&SkGeChangeMtu;
-		dev->flags &= 		~IFF_RUNNING;
+	}
 
-#ifdef SK_ZEROCOPY
+#ifdef NETIF_F_TSO
+#ifdef USE_SK_TSO_FEATURE	
+	if (CHIP_ID_YUKON_2(pAC)) {
+		dev->features |= NETIF_F_TSO;
+	}
+#endif
+#endif
+#ifdef CONFIG_SK98LIN_ZEROCOPY
+	if (pAC->GIni.GIChipId != CHIP_ID_GENESIS)
+		dev->features |= NETIF_F_SG;
+#endif
 #ifdef USE_SK_TX_CHECKSUM
-
-		if (pAC->ChipsetType) {
-			/* Use only if yukon hardware */
-			/* SK and ZEROCOPY - fly baby... */
-			dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-		}
+	if (pAC->GIni.GIChipId != CHIP_ID_GENESIS)
+		dev->features |= NETIF_F_IP_CSUM;
 #endif
+#ifdef USE_SK_RX_CHECKSUM
+	pAC->RxPort[0].UseRxCsum = SK_TRUE;
 #endif
 
-		pAC->Index = boards_found;
+	/* Save the hardware revision */
+	pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
+		(pAC->GIni.GIPciHwRev & 0x0F);
 
-		if (SkGeBoardInit(dev, pAC)) {
-			unregister_netdev(dev);
-			kfree(dev);
-			continue;
-		}
+	/* Set driver globals */
+	pAC->Pnmi.pDriverFileName    = DRIVER_FILE_NAME;
+	pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE;
 
+	SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA));
+	SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), 
+			sizeof(SK_PNMI_STRUCT_DATA));
 
-		/* Print adapter specific string from vpd */
-		ProductStr(pAC);
-		printk("%s: %s\n", dev->name, pAC->DeviceStr);
 
-		/* Print configuration settings */
-		printk("      PrefPort:%c  RlmtMode:%s\n",
-			'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
-			(pAC->RlmtMode==0)  ? "Check Link State" :
-			((pAC->RlmtMode==1) ? "Check Link State" :
-			((pAC->RlmtMode==3) ? "Check Local Port" :
-			((pAC->RlmtMode==7) ? "Check Segmentation" :
-			((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
+	/* Save initial device name */
+	strcpy(pNet->InitialDevName, dev->name);
 
-		SkGeYellowLED(pAC, pAC->IoBase, 1);
+	/* Print adapter specific string from vpd and config settings */
+	printk("%s: %s\n", pNet->InitialDevName, pAC->DeviceStr);
+	printk("      PrefPort:%c  RlmtMode:%s\n",
+		'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
+		(pAC->RlmtMode==0)  ? "Check Link State" :
+		((pAC->RlmtMode==1) ? "Check Link State" :
+		((pAC->RlmtMode==3) ? "Check Local Port" :
+		((pAC->RlmtMode==7) ? "Check Segmentation" :
+		((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
 
+	SkGeYellowLED(pAC, pAC->IoBase, 1);
 
-		memcpy((caddr_t) &dev->dev_addr,
-			(caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
+	memcpy((caddr_t) &dev->dev_addr,
+		(caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
 
-		/* First adapter... Create proc and print message */
+	/* First adapter... Create proc and print message */
 #ifdef CONFIG_PROC_FS
-		if (!DeviceFound) {
-			DeviceFound = SK_TRUE;
-			SK_MEMCPY(&SK_Root_Dir_entry, BootString,
-				sizeof(SK_Root_Dir_entry) - 1);
-
-			/*Create proc (directory)*/
-			if(!proc_root_initialized) {
-				pSkRootDir = create_proc_entry(SK_Root_Dir_entry,
-					S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net);
-				pSkRootDir->owner = THIS_MODULE;
-				proc_root_initialized = 1;
-			}
+	if (!sk98lin_proc_entry) {
+		sk98lin_proc_entry = SK_TRUE;
+		SK_MEMCPY(&SK_Root_Dir_entry, BootString,
+			sizeof(SK_Root_Dir_entry) - 1);
+
+		/*Create proc (directory)*/
+		if(!proc_root_initialized) {
+			pSkRootDir = create_proc_entry(SK_Root_Dir_entry,
+			S_IFDIR | S_IRUGO | S_IXUGO, proc_net);
+			pSkRootDir->owner = THIS_MODULE;
+			proc_root_initialized = 1;
 		}
+	}
 
-		/* Create proc file */
-		pProcFile = create_proc_entry(dev->name,
-			S_IFREG | S_IXUSR | S_IWGRP | S_IROTH,
-			pSkRootDir);
+	/* Create proc file */
+	pProcFile = create_proc_entry(dev->name,
+		S_IFREG | S_IRUSR | S_IRGRP | S_IROTH,
+		pSkRootDir);
 
-		pProcFile->read_proc   = sk_proc_read;
-		pProcFile->write_proc  = NULL;
-		pProcFile->nlink       = 1;
-		pProcFile->size        = sizeof(dev->name + 1);
-		pProcFile->data        = (void *)pProcFile;
-		pProcFile->owner       = THIS_MODULE;
+	pProcFile->read_proc   = sk_proc_read;
+	pProcFile->write_proc  = NULL;
+	pProcFile->nlink       = 1;
+	pProcFile->size        = sizeof(dev->name + 1);
+	pProcFile->data        = (void *)pProcFile;
+	pProcFile->owner       = THIS_MODULE;
 #endif
 
-		pNet->PortNr = 0;
-		pNet->NetNr  = 0;
+	pNet->PortNr = 0;
+	pNet->NetNr  = 0;
 
-		boards_found++;
+	sk98lin_boards_found++;
+	pci_set_drvdata(pdev, dev);
 
-		/* More then one port found */
-		if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
-			if ((dev = init_etherdev(NULL, sizeof(DEV_NET))) == 0) {
-				printk(KERN_ERR "Unable to allocate etherdev "
-					"structure!\n");
-				break;
-			}
+	/* More then one port found */
+	if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
+		if ((dev = init_etherdev(NULL, sizeof(DEV_NET))) == 0) {
+			printk(KERN_ERR "Unable to allocate etherdev "
+				"structure!\n");
+			return -ENODEV;
+		}
 
-			pAC->dev[1]   = dev;
-			pNet          = dev->priv;
-			pNet->PortNr  = 1;
-			pNet->NetNr   = 1;
-			pNet->pAC     = pAC;
-			pNet->Mtu     = 1500;
-			pNet->Up      = 0;
-
-			dev->open               = &SkGeOpen;
-			dev->stop               = &SkGeClose;
-			dev->hard_start_xmit    = &SkGeXmit;
-			dev->get_stats          = &SkGeStats;
-			dev->set_multicast_list = &SkGeSetRxMode;
-			dev->set_mac_address    = &SkGeSetMacAddr;
-			dev->do_ioctl           = &SkGeIoctl;
-			dev->change_mtu         = &SkGeChangeMtu;
-			dev->flags             &= ~IFF_RUNNING;
+		pAC->dev[1]   = dev;
+		pNet          = dev->priv;
+		pNet->PortNr  = 1;
+		pNet->NetNr   = 1;
+		pNet->pAC     = pAC;
+		pNet->Mtu     = 1500;
+		pNet->Up      = 0;
 
-#ifdef SK_ZEROCOPY
+		if (CHIP_ID_YUKON_2(pAC)) {
+			dev->hard_start_xmit = &SkY2Xmit;
+		} else {
+			dev->hard_start_xmit = &SkGeXmit;
+		}
+		dev->open               = &SkGeOpen;
+		dev->stop               = &SkGeClose;
+		dev->get_stats          = &SkGeStats;
+		dev->set_multicast_list = &SkGeSetRxMode;
+		dev->set_mac_address    = &SkGeSetMacAddr;
+		dev->do_ioctl           = &SkGeIoctl;
+		dev->change_mtu         = &SkGeChangeMtu;
+		dev->flags             &= ~IFF_RUNNING;
+
+#ifdef NETIF_F_TSO
+#ifdef USE_SK_TSO_FEATURE	
+		if (CHIP_ID_YUKON_2(pAC)) {
+			dev->features |= NETIF_F_TSO;
+		}
+#endif
+#endif
+#ifdef CONFIG_SK98LIN_ZEROCOPY
+		/* Don't handle if Genesis chipset */
+		if (pAC->GIni.GIChipId != CHIP_ID_GENESIS)
+			dev->features |= NETIF_F_SG;
+#endif
 #ifdef USE_SK_TX_CHECKSUM
-			if (pAC->ChipsetType) {
-				/* SG and ZEROCOPY - fly baby... */
-				dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-			}
+		/* Don't handle if Genesis chipset */
+		if (pAC->GIni.GIChipId != CHIP_ID_GENESIS)
+			dev->features |= NETIF_F_IP_CSUM;
 #endif
+#ifdef USE_SK_RX_CHECKSUM
+		pAC->RxPort[1].UseRxCsum = SK_TRUE;
 #endif
 
+
+		/* Save initial device name */
+		strcpy(pNet->InitialDevName, dev->name);
+
 #ifdef CONFIG_PROC_FS
-			pProcFile = create_proc_entry(dev->name,
-				S_IFREG | S_IXUSR | S_IWGRP | S_IROTH,
-				pSkRootDir);
-			pProcFile->read_proc  = sk_proc_read;
-			pProcFile->write_proc = NULL;
-			pProcFile->nlink      = 1;
-			pProcFile->size       = sizeof(dev->name + 1);
-			pProcFile->data       = (void *)pProcFile;
-			pProcFile->owner      = THIS_MODULE;
+		pProcFile = create_proc_entry(dev->name,
+			S_IFREG | S_IRUSR | S_IRGRP | S_IROTH,
+			pSkRootDir);
+		pProcFile->read_proc  = sk_proc_read;
+		pProcFile->write_proc = NULL;
+		pProcFile->nlink      = 1;
+		pProcFile->size       = sizeof(dev->name + 1);
+		pProcFile->data       = (void *)pProcFile;
+		pProcFile->owner      = THIS_MODULE;
 #endif
 
-			memcpy((caddr_t) &dev->dev_addr,
-			(caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6);
+		memcpy((caddr_t) &dev->dev_addr,
+		(caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6);
 	
-			printk("%s: %s\n", dev->name, pAC->DeviceStr);
-			printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
-		}
-
-		/* Save the hardware revision */
-		pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
-			(pAC->GIni.GIPciHwRev & 0x0F);
-
-		/* Set driver globals */
-		pAC->Pnmi.pDriverFileName    = DRIVER_FILE_NAME;
-		pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE;
-
-		SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA));
-		SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), 
-				sizeof(SK_PNMI_STRUCT_DATA));
-
-		/*
-		 * This is bollocks, but we need to tell the net-init
-		 * code that it shall go for the next device.
-		 */
-#ifndef MODULE
-		dev->base_addr = 0;
-#endif
+		printk("%s: %s\n", pNet->InitialDevName, pAC->DeviceStr);
+		printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
 	}
 
-	/*
-	 * If we're at this point we're going through skge_probe() for
-	 * the first time.  Return success (0) if we've initialized 1
-	 * or more boards. Otherwise, return failure (-ENODEV).
-	 */
+	pAC->Index = sk98lin_boards_found;
+	sk98lin_max_boards_found = sk98lin_boards_found;
+	return 0;
+}
 
-	return boards_found;
-} /* skge_probe */
 
 
 /*****************************************************************************
@@ -566,7 +616,7 @@
 	dev->mem_start = pci_resource_start (pdev, 0);
 	pci_set_master(pdev);
 
-	if (pci_request_regions(pdev, pAC->Name) != 0) {
+	if (pci_request_regions(pdev, DRIVER_FILE_NAME) != 0) {
 		retval = 2;
 		goto out_disable;
 	}
@@ -603,6 +653,315 @@
 	return retval;
 }
 
+#ifdef SK_CONFIG_PM
+/*****************************************************************************
+ *
+ * 	sk98lin_resume - Resume the the card
+ *
+ * Description:
+ *	This function resumes the card into the D0 state
+ *
+ * Returns: N/A
+ *	
+ */
+static int sk98lin_resume(struct pci_dev *pdev)
+{
+	DEV_NET			*pNet;
+	SK_AC			*pAC;
+	struct 			net_device *dev = pci_get_drvdata(pdev);
+	pNet = (DEV_NET*) dev->priv;
+	pAC = pNet->pAC;
+
+	/* Set the power state to D0 */
+	pci_set_power_state(pdev, 0);
+	pci_restore_state(pdev, pAC->PciState);
+	pci_enable_wake(pdev, 3, 0);
+	pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
+
+
+	/* Set the adapter power state to D0 */
+	SkHWSetDState(pAC, pAC->IoBase, 0);
+
+	/* Reinit the adapter and start the port again */
+	SkDrvLeaveDiagMode(pAC);
+
+	netif_device_attach(dev);
+
+	return 0;
+}
+ 
+/*****************************************************************************
+ *
+ * 	sk98lin_suspend - Suspend the card
+ *
+ * Description:
+ *	This function suspends the card into a defined state
+ *
+ * Returns: N/A
+ *	
+ */
+static int sk98lin_suspend(struct pci_dev *pdev, uint32_t state)
+{
+DEV_NET			*pNet;
+SK_AC			*pAC;
+SK_U16			PciPMControlStatus;
+SK_U16			PciPMCapabilities;
+SK_MAC_ADDR		MacAddr;
+struct 			net_device *dev = pci_get_drvdata(pdev);
+int			i;
+
+	pNet = (DEV_NET*) dev->priv;
+	pAC = pNet->pAC;
+	netif_device_detach(dev);
+
+	/* Device still busy */
+	if(netif_running(dev)) {
+		/* Maybe we have to close the adapter */
+	}
+
+	/* Stop the adapter */
+	SkDrvEnterDiagMode(pAC);
+
+	/* read the PM control/status register from the PCI config space */
+	SK_IN16(pAC->IoBase, PCI_C(pAC, PCI_PM_CTL_STS), &PciPMControlStatus);
+
+	/* read the power management capabilities from the config space */
+	SK_IN16(pAC->IoBase, PCI_C(pAC, PCI_PM_CAP_REG), &PciPMCapabilities);
+
+
+	/*
+	 * The GE chipset and the first revision of yukon does not 
+	 * support power management
+	 */
+	if (((pAC->GIni.GIChipId == CHIP_ID_YUKON) && 
+		(pAC->GIni.GIChipRev == 0)) ||
+		(pAC->GIni.GIChipId == CHIP_ID_GENESIS)) {
+	/* Power management not supported */
+		printk("Power management not supported\n");
+	} else {
+	/* Enable power management */
+		/* Enable WakeUp with Magic Packet */
+		/* get MAC address from adapter */
+		for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
+			/* virtual address: will be used for data */
+			SK_IN8(pAC->IoBase, (B2_MAC_1 + i), &MacAddr.a[i]);
+		}
+
+		/* enable wake up through amd magic packet */
+		SkEnableWOMagicPacket(pAC, pAC->IoBase, MacAddr);
+
+		/* Set port spee to 100MBit */
+		SkSetPortSpeed(pAC, pAC->IoBase, SK_LSPEED_100MBPS);
+
+		/* Switch the power state */
+		SkHWSwitchPower(pAC, pAC->IoBase, state);
+
+		/*   Set the power state
+		 *
+		 * in DState 3 no I/O access to the adapter is possible
+		 * we can only access its PCI Config space through PCI
+		 * BIOS functions
+		 */
+		SkHWSetDState(pAC, pAC->IoBase, state);
+
+		pci_enable_wake(pdev, 3, 1);
+		pci_enable_wake(pdev, 4, 1);	/* 4 == D3 cold */
+		pci_save_state(pdev, pAC->PciState);
+
+		/* Set state */
+		pci_set_power_state(pdev, state);
+	}
+	return 0;
+}
+
+/******************************************************************************
+ *
+ *	SkHWSetDState - Set the desired DState by writing it into the PCI
+ *		config space of the adapter
+ *
+ * Context:
+ *	init, pageable
+ *	the adapter must be de-initialized before calling this function
+ *
+ * Returns:
+ *	SK_POWER_ERR_OK			- everything's fine
+ */
+
+static void SkHWSetDState(
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O context */
+SK_DEVICE_POWER_STATE	State)	/* requested DState */
+{
+	SK_U16	PmCtlSts;
+	SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);
+
+	/* reset all DState bits */
+	PmCtlSts &= ~(PCI_PM_STATE_D3);
+
+	switch(State) {
+	case SkDeviceStateD0 :
+		PmCtlSts |= PCI_PM_STATE_D0;
+		break;
+	case SkDeviceStateD1 :
+		PmCtlSts |= PCI_PM_STATE_D1;
+		break;
+	case SkDeviceStateD2 :
+		PmCtlSts |= PCI_PM_STATE_D2;
+		break;
+	case SkDeviceStateD3 :
+		PmCtlSts |= (PCI_PM_STATE_D3 | PCI_PME_EN);
+		break;
+	}
+	SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PmCtlSts);
+
+}	/* SkHWSetDState */
+
+/******************************************************************************
+ *
+ *	SkHWSwitchPower - Switch the adapter internal power switches according
+ *		to the selected DState
+ *
+ * Context:
+ *	init, pageable
+ *
+ * Returns:
+ *	SK_POWER_ERR_OK			- everything's fine
+ */
+
+static void SkHWSwitchPower(
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O context */
+SK_DEVICE_POWER_STATE	State)
+{
+	SK_U8 Byte;
+
+	Byte = PC_VAUX_ENA | PC_VCC_ENA;
+
+	if (State == SkDeviceStateD3) {
+		/* switch power to Vaux */
+		Byte |= PC_VAUX_ON | PC_VCC_OFF;
+	}
+	else {
+		/* switch power to Vcc */
+		Byte |= PC_VAUX_OFF | PC_VCC_ON;
+	}
+
+	SK_OUT8(IoC, B0_POWER_CTRL, Byte);
+
+}	/* SkHWSwitchPower */
+
+
+/*****************************************************************************
+*
+* SkSetPortSpeed - switch the link speed of a specific port
+*
+* Description:
+*
+* Notes:
+*
+* Function Parameters:
+*	pAC - A pointer to our adapter info struct.
+*	IoC - 
+* 	Speed - link speed to switch to
+*
+* Context:
+*	IRQL -
+*
+* Returns:
+*
+*/
+static int SkSetPortSpeed(
+SK_AC	*pAC,
+SK_IOC	IoC,
+SK_U8	Speed)
+{
+	SK_GEPORT 	*pGePort;
+	SK_EVPARA 	EvPara;
+
+	pGePort = &pAC->GIni.GP[0];
+
+	/* Stop port */
+	SkY2PortStop(pAC, pAC->IoBase, 0, SK_STOP_ALL, SK_HARD_RST);
+
+	/* Set port's link speed. */
+	if (Speed == SK_LSPEED_100MBPS) {
+		/* Set port's link mode. */
+		pGePort->PLinkSpeed = SK_LSPEED_100MBPS;
+		pGePort->PLinkModeConf = 
+			pGePort->PLinkMode = SK_LMODE_AUTOBOTH;
+	}
+	else {
+		/* Set port's link mode. */
+		pGePort->PLinkSpeed = SK_LSPEED_1000MBPS;
+		pGePort->PLinkModeConf = 
+			pGePort->PLinkMode = SK_LMODE_FULL;
+	}
+
+	/* Set port's flow control mode */
+	pGePort->PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
+
+	/* Set port's Master/Slave param */
+	pGePort->PMSMode = SK_MS_MODE_AUTO;
+
+	/* Start the port again so we can switch to the new Link speed */
+	SkY2PortStart(pAC, pAC->IoBase, 0);
+
+	return(0);
+}
+
+/******************************************************************************
+ *
+ *	SkEnableWOMagicPacket - Enable Wake on Magic Packet on the adapter
+ *
+ * Context:
+ *	init, pageable
+ *	the adapter should be de-initialized before calling this function
+ *
+ * Returns:
+ *	nothing
+ */
+
+static void SkEnableWOMagicPacket(
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O context */
+SK_MAC_ADDR	MacAddr)	/* MacAddr expected in magic packet */
+{
+	SK_U16	Word;
+	SK_U32	DWord;
+	int 	i;
+	int		HwPortIndex;
+
+	/* use Port 0 as long as we do not have any dual port cards which support WOL */
+	HwPortIndex = 0;
+	DWord = 0;
+
+	for (i = 0; i < 4; i++) {
+		DWord = DWord << 8;
+		DWord |= MacAddr.a[3 - i];
+	}
+
+	Word = 0;
+	for (i = 0; i < 2; i++) {
+		Word = Word << 8;
+		Word |= MacAddr.a[5 - i];
+	}
+
+	/* write MAC address the WOL state machine is waiting for */
+	SK_OUT32(IoC, WOL_REG(HwPortIndex, WOL_MAC_ADDR_LO), DWord);
+	SK_OUT16(IoC, WOL_REG(HwPortIndex, WOL_MAC_ADDR_HI), Word);
+
+	SK_IN16(IoC, WOL_REG(HwPortIndex, WOL_CTRL_STAT), &Word);
+
+	/* enable wake on AMD magic packet */
+	Word &= ~(WOL_CTL_DIS_MAGIC_PKT_UNIT | WOL_CTL_DIS_PME_ON_MAGIC_PKT);
+	Word |= WOL_CTL_ENA_MAGIC_PKT_UNIT | WOL_CTL_ENA_PME_ON_MAGIC_PKT |
+		WOL_CTL_CLEAR_RESULT;
+
+	SK_OUT16(IoC, WOL_REG(HwPortIndex, WOL_CTRL_STAT), Word);
+
+}	/* SkEnableWOMagicPacket */
+#endif
+
 
 /*****************************************************************************
  *
@@ -657,16 +1016,9 @@
 MODULE_PARM(ConType,	"1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
 MODULE_PARM(PrefPort,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
 MODULE_PARM(RlmtMode,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-/* not used, just there because every driver should have them: */
-MODULE_PARM(options,    "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i");
-MODULE_PARM(debug,      "i");
-/* used for interrupt moderation */
 MODULE_PARM(IntsPerSec,     "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i");
 MODULE_PARM(Moderation,     "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(Stats,          "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
 MODULE_PARM(ModerationMask, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(AutoSizing,     "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-
 
 #ifdef LINK_SPEED_A
 static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED;
@@ -746,47 +1098,14 @@
 static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", };
 #endif
 
-static int debug = 0; /* not used */
-static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */
-
 static int   IntsPerSec[SK_MAX_CARD_PARAM];
 static char *Moderation[SK_MAX_CARD_PARAM];
 static char *ModerationMask[SK_MAX_CARD_PARAM];
-static char *AutoSizing[SK_MAX_CARD_PARAM];
-static char *Stats[SK_MAX_CARD_PARAM];
 
 
 /*****************************************************************************
  *
- * 	skge_init_module - module initialization function
- *
- * Description:
- *	Very simple, only call skge_probe and return approriate result.
- *
- * Returns:
- *	0, if everything is ok
- *	!=0, on error
- */
-static int __init skge_init_module(void)
-{
-	int cards;
-	SkGeRootDev = NULL;
-	
-	/* just to avoid warnings ... */
-	debug = 0;
-	options[0] = 0;
-
-	cards = skge_probe();
-	if (cards == 0) {
-		printk("sk98lin: No adapter found.\n");
-	}
-	return cards ? 0 : -ENODEV;
-} /* skge_init_module */
-
-
-/*****************************************************************************
- *
- * 	skge_cleanup_module - module unload function
+ * 	sk98lin_remove_device - device deinit function
  *
  * Description:
  *	Disable adapter if it is still running, free resources,
@@ -794,73 +1113,86 @@
  *
  * Returns: N/A
  */
-static void __exit skge_cleanup_module(void)
+
+static void sk98lin_remove_device(struct pci_dev *pdev)
 {
 DEV_NET		*pNet;
 SK_AC		*pAC;
 struct SK_NET_DEVICE *next;
 unsigned long Flags;
 SK_EVPARA EvPara;
+struct net_device *dev = pci_get_drvdata(pdev);
 
-	while (SkGeRootDev) {
-		pNet = (DEV_NET*) SkGeRootDev->priv;
-		pAC = pNet->pAC;
-		next = pAC->Next;
 
-		netif_stop_queue(SkGeRootDev);
-		SkGeYellowLED(pAC, pAC->IoBase, 0);
+	/* Device not available. Return. */
+	if (!dev)
+		return;
 
-		if(pAC->BoardLevel == SK_INIT_RUN) {
-			/* board is still alive */
-			spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-			EvPara.Para32[0] = 0;
-			EvPara.Para32[1] = -1;
-			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-			EvPara.Para32[0] = 1;
-			EvPara.Para32[1] = -1;
-			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
-			SkEventDispatcher(pAC, pAC->IoBase);
-			/* disable interrupts */
-			SK_OUT32(pAC->IoBase, B0_IMSK, 0);
-			SkGeDeInit(pAC, pAC->IoBase);
-			spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-			pAC->BoardLevel = SK_INIT_DATA;
-			/* We do NOT check here, if IRQ was pending, of course*/
-		}
-
-		if(pAC->BoardLevel == SK_INIT_IO) {
-			/* board is still alive */
-			SkGeDeInit(pAC, pAC->IoBase);
-			pAC->BoardLevel = SK_INIT_DATA;
-		}
-
-		if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){
-			unregister_netdev(pAC->dev[1]);
-			kfree(pAC->dev[1]);
-		}
+	pNet = (DEV_NET*) dev->priv;
+	pAC = pNet->pAC;
+	next = pAC->Next;
 
-		FreeResources(SkGeRootDev);
+	netif_stop_queue(dev);
+	SkGeYellowLED(pAC, pAC->IoBase, 0);
 
-		SkGeRootDev->get_stats = NULL;
-		/*
-		 * otherwise unregister_netdev calls get_stats with
-		 * invalid IO ...  :-(
-		 */
-		unregister_netdev(SkGeRootDev);
-		kfree(SkGeRootDev);
-		kfree(pAC);
-		SkGeRootDev = next;
+	if(pAC->BoardLevel == SK_INIT_RUN) {
+		/* board is still alive */
+		spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+		EvPara.Para32[0] = 0;
+		EvPara.Para32[1] = -1;
+		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+		EvPara.Para32[0] = 1;
+		EvPara.Para32[1] = -1;
+		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+		SkEventDispatcher(pAC, pAC->IoBase);
+		/* disable interrupts */
+		SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+		SkGeDeInit(pAC, pAC->IoBase);
+		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+		pAC->BoardLevel = SK_INIT_DATA;
+		/* We do NOT check here, if IRQ was pending, of course*/
+	}
+
+	if(pAC->BoardLevel == SK_INIT_IO) {
+		/* board is still alive */
+		SkGeDeInit(pAC, pAC->IoBase);
+		pAC->BoardLevel = SK_INIT_DATA;
+	}
+
+	if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){
+		unregister_netdev(pAC->dev[1]);
+		kfree(pAC->dev[1]);
 	}
 
+	FreeResources(dev);
+
 #ifdef CONFIG_PROC_FS
-	/* clear proc-dir */
-	remove_proc_entry(pSkRootDir->name, proc_net);
+	/* Remove the sk98lin procfs device entries */
+	if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){
+		remove_proc_entry(pAC->dev[1]->name, pSkRootDir);
+	}
+	remove_proc_entry(pNet->InitialDevName, pSkRootDir);
 #endif
 
-} /* skge_cleanup_module */
+	dev->get_stats = NULL;
+	/*
+	 * otherwise unregister_netdev calls get_stats with
+	 * invalid IO ...  :-(
+	 */
+	unregister_netdev(dev);
+	kfree(dev);
+	kfree(pAC);
+	sk98lin_max_boards_found--;
+
+#ifdef CONFIG_PROC_FS
+	/* Remove all Proc entries if last device */
+	if (sk98lin_max_boards_found == 0) {
+		/* clear proc-dir */
+		remove_proc_entry(pSkRootDir->name, proc_net);
+	}
+#endif
 
-module_init(skge_init_module);
-module_exit(skge_cleanup_module);
+}
 
 
 /*****************************************************************************
@@ -899,7 +1231,9 @@
 		spin_lock_init(&pAC->TxPort[i][0].TxDesRingLock);
 		spin_lock_init(&pAC->RxPort[i].RxDesRingLock);
 	}
+
 	spin_lock_init(&pAC->SlowPathLock);
+	spin_lock_init(&pAC->SetPutIndexLock);	/* for Yukon2 chipsets */
 
 	/* level 0 init common modules here */
 	
@@ -923,10 +1257,7 @@
 	SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString);
 	SK_PNMI_SET_DRIVER_VER(pAC, VerStr);
 
-	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
 	/* level 1 init common modules here (HW init) */
-	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
 	if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
 		printk("sk98lin: HWInit (1) failed.\n");
 		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
@@ -940,49 +1271,79 @@
 	SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
 
 	/* Set chipset type support */
-	pAC->ChipsetType = 0;
 	if ((pAC->GIni.GIChipId == CHIP_ID_YUKON) ||
-		(pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) {
-		pAC->ChipsetType = 1;
+		(pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) ||
+		(pAC->GIni.GIChipId == CHIP_ID_YUKON_LP)) {
+		pAC->ChipsetType = 1;	/* Yukon chipset (descriptor logic) */
+	} else if (CHIP_ID_YUKON_2(pAC)) {
+		pAC->ChipsetType = 2;	/* Yukon2 chipset (list logic) */
+	} else {
+		pAC->ChipsetType = 0;	/* Genesis chipset (descriptor logic) */
 	}
 
 	GetConfiguration(pAC);
 	if (pAC->RlmtNets == 2) {
-		pAC->GIni.GIPortUsage = SK_MUL_LINK;
+ 		pAC->GIni.GIPortUsage = SK_MUL_LINK;
 	}
 
 	pAC->BoardLevel = SK_INIT_IO;
 	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
 
-	if (pAC->GIni.GIMacsFound == 2) {
-		 Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
-	} else if (pAC->GIni.GIMacsFound == 1) {
-		Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ,
-			pAC->Name, dev);
-	} else {
-		printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
-		       pAC->GIni.GIMacsFound);
-		return -EAGAIN;
+	if (!CHIP_ID_YUKON_2(pAC)) {
+#ifdef CONFIG_SK98LIN_NAPI
+		dev->poll =  &SkGePoll;
+		dev->weight = 64;
+#endif
+		if (pAC->GIni.GIMacsFound == 2) {
+			Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, dev->name, dev);
+		} else if (pAC->GIni.GIMacsFound == 1) {
+			Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, dev->name, dev);
+		} else {
+			printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
+				pAC->GIni.GIMacsFound);
+			return -EAGAIN;
+		}
+	}
+	else {
+		Ret = request_irq(dev->irq, SkY2Isr, SA_SHIRQ, dev->name, dev);
+#ifdef CONFIG_SK98LIN_NAPI
+		dev->poll =  &SkY2Poll;
+		dev->weight = 64;
+#endif
 	}
 
 	if (Ret) {
 		printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n",
-		       dev->irq);
+			dev->irq);
 		return -EAGAIN;
 	}
 	pAC->AllocFlag |= SK_ALLOC_IRQ;
 
-	/* Alloc memory for this board (Mem for RxD/TxD) : */
-	if(!BoardAllocMem(pAC)) {
-		printk("No memory for descriptor rings.\n");
-       		return(-EAGAIN);
+	/* 
+	** Alloc descriptor/LETable memory for this board (both RxD/TxD)
+	*/
+	if (CHIP_ID_YUKON_2(pAC)) {
+		if (!SkY2AllocateResources(pAC)) {
+			printk("No memory for Yukon2 settings\n");
+			return(-EAGAIN);
+		}
+	} else {
+		if(!BoardAllocMem(pAC)) {
+			printk("No memory for descriptor rings.\n");
+			return(-EAGAIN);
+		}
 	}
 
+#ifdef SK_USE_CSUM
 	SkCsSetReceiveFlags(pAC,
 		SKCS_PROTO_IP | SKCS_PROTO_TCP | SKCS_PROTO_UDP,
 		&pAC->CsOfs1, &pAC->CsOfs2, 0);
 	pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1;
+#endif
 
+	/*
+	** Function BoardInitMem() for Yukon dependent settings...
+	*/
 	BoardInitMem(pAC);
 	/* tschilling: New common function with minimum size check. */
 	DualNet = SK_FALSE;
@@ -1094,6 +1455,12 @@
 
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("BoardFreeMem\n"));
+
+	if (CHIP_ID_YUKON_2(pAC)) {
+		SkY2FreeResources(pAC);
+		return;
+	}
+
 #if (BITS_PER_LONG == 32)
 	AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
 #else
@@ -1112,7 +1479,7 @@
  * 	BoardInitMem - initiate the descriptor rings
  *
  * Description:
- *	This function sets the descriptor rings up in memory.
+ *	This function sets the descriptor rings or LETables up in memory.
  *	The adapter is initialized with the descriptor start addresses.
  *
  * Returns:	N/A
@@ -1127,34 +1494,37 @@
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("BoardInitMem\n"));
 
-	RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
-	pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize;
-	TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
-	pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize;
+	if (!pAC->GIni.GIYukon2) {
+		RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
+		pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize;
+		TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
+		pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize;
 	
-	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-		SetupRing(
-			pAC,
-			pAC->TxPort[i][0].pTxDescrRing,
-			pAC->TxPort[i][0].VTxDescrRing,
-			(RXD**)&pAC->TxPort[i][0].pTxdRingHead,
-			(RXD**)&pAC->TxPort[i][0].pTxdRingTail,
-			(RXD**)&pAC->TxPort[i][0].pTxdRingPrev,
-			&pAC->TxPort[i][0].TxdRingFree,
-			SK_TRUE);
-		SetupRing(
-			pAC,
-			pAC->RxPort[i].pRxDescrRing,
-			pAC->RxPort[i].VRxDescrRing,
-			&pAC->RxPort[i].pRxdRingHead,
-			&pAC->RxPort[i].pRxdRingTail,
-			&pAC->RxPort[i].pRxdRingPrev,
-			&pAC->RxPort[i].RxdRingFree,
-			SK_FALSE);
+		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+			SetupRing(
+				pAC,
+				pAC->TxPort[i][0].pTxDescrRing,
+				pAC->TxPort[i][0].VTxDescrRing,
+				(RXD**)&pAC->TxPort[i][0].pTxdRingHead,
+				(RXD**)&pAC->TxPort[i][0].pTxdRingTail,
+				(RXD**)&pAC->TxPort[i][0].pTxdRingPrev,
+				&pAC->TxPort[i][0].TxdRingFree,
+				&pAC->TxPort[i][0].TxdRingPrevFree,
+				SK_TRUE);
+			SetupRing(
+				pAC,
+				pAC->RxPort[i].pRxDescrRing,
+				pAC->RxPort[i].VRxDescrRing,
+				&pAC->RxPort[i].pRxdRingHead,
+				&pAC->RxPort[i].pRxdRingTail,
+				&pAC->RxPort[i].pRxdRingPrev,
+				&pAC->RxPort[i].RxdRingFree,
+				&pAC->RxPort[i].RxdRingFree,
+				SK_FALSE);
+		}
 	}
 } /* BoardInitMem */
 
-
 /*****************************************************************************
  *
  * 	SetupRing - create one descriptor ring
@@ -1174,6 +1544,7 @@
 RXD		**ppRingTail,	/* address where the tail should be written */
 RXD		**ppRingPrev,	/* address where the tail should be written */
 int		*pRingFree,	/* address where the # of free descr. goes */
+int		*pRingPrevFree,	/* address where the # of free descr. goes */
 SK_BOOL		IsTx)		/* flag: is this a tx ring */
 {
 int	i;		/* loop counter */
@@ -1216,11 +1587,12 @@
 	}
 	pPrevDescr->pNextRxd = (RXD*) pMemArea;
 	pPrevDescr->VNextRxd = VMemArea;
-	pDescr = (RXD*) pMemArea;
-	*ppRingHead = (RXD*) pMemArea;
-	*ppRingTail = *ppRingHead;
-	*ppRingPrev = pPrevDescr;
-	*pRingFree = DescrNum;
+	pDescr               = (RXD*) pMemArea;
+	*ppRingHead          = (RXD*) pMemArea;
+	*ppRingTail          = *ppRingHead;
+	*ppRingPrev          = pPrevDescr;
+	*pRingFree           = DescrNum;
+	*pRingPrevFree       = DescrNum;
 } /* SetupRing */
 
 
@@ -1296,6 +1668,24 @@
 		return;
 	}
 
+#ifdef CONFIG_SK98LIN_NAPI
+	if (netif_rx_schedule_prep(dev)) {
+		pAC->GIni.GIValIrqMask &= ~(NAPI_DRV_IRQS);
+		SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
+		__netif_rx_schedule(dev);
+	}
+
+#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
+	if (IntSrc & IS_XA1_F) {
+		CLEAR_TX_IRQ(0, TX_PRIO_LOW);
+	}
+	if (IntSrc & IS_XA2_F) {
+		CLEAR_TX_IRQ(1, TX_PRIO_LOW);
+	}
+#endif
+
+
+#else
 	while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
 #if 0 /* software irq currently not used */
 		if (IntSrc & IS_IRQ_SW) {
@@ -1309,6 +1699,7 @@
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF RX1 IRQ\n"));
 			ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
+			CLEAR_AND_START_RX(0);
 			SK_PNMI_CNT_RX_INTR(pAC, 0);
 		}
 		if (IntSrc & IS_R2_F) {
@@ -1316,6 +1707,7 @@
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF RX2 IRQ\n"));
 			ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
+			CLEAR_AND_START_RX(1);
 			SK_PNMI_CNT_RX_INTR(pAC, 1);
 		}
 #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
@@ -1323,6 +1715,7 @@
 			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF AS TX1 IRQ\n"));
+			CLEAR_TX_IRQ(0, TX_PRIO_LOW);
 			SK_PNMI_CNT_TX_INTR(pAC, 0);
 			spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
 			FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
@@ -1332,6 +1725,7 @@
 			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF AS TX2 IRQ\n"));
+			CLEAR_TX_IRQ(1, TX_PRIO_LOW);
 			SK_PNMI_CNT_TX_INTR(pAC, 1);
 			spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
 			FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]);
@@ -1342,38 +1736,28 @@
 			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF SY TX1 IRQ\n"));
+			CLEAR_TX_IRQ(0, TX_PRIO_HIGH);
 			SK_PNMI_CNT_TX_INTR(pAC, 1);
 			spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
 			FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
 			spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
-			ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
 		}
 		if (IntSrc & IS_XS2_F) {
 			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF SY TX2 IRQ\n"));
+			CLEAR_TX_IRQ(1, TX_PRIO_HIGH);
 			SK_PNMI_CNT_TX_INTR(pAC, 1);
 			spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
 			FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH);
 			spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
-			ClearTxIrq(pAC, 1, TX_PRIO_HIGH);
 		}
 #endif
 #endif
 
-		/* do all IO at once */
-		if (IntSrc & IS_R1_F)
-			ClearAndStartRx(pAC, 0);
-		if (IntSrc & IS_R2_F)
-			ClearAndStartRx(pAC, 1);
-#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
-		if (IntSrc & IS_XA1_F)
-			ClearTxIrq(pAC, 0, TX_PRIO_LOW);
-		if (IntSrc & IS_XA2_F)
-			ClearTxIrq(pAC, 1, TX_PRIO_LOW);
-#endif
 		SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
 	} /* while (IntSrc & IRQ_MASK != 0) */
+#endif
 
 	IntSrc &= pAC->GIni.GIValIrqMask;
 	if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
@@ -1387,18 +1771,12 @@
 		SkEventDispatcher(pAC, pAC->IoBase);
 		spin_unlock(&pAC->SlowPathLock);
 	}
-	/*
-	 * do it all again is case we cleared an interrupt that
-	 * came in after handling the ring (OUTs may be delayed
-	 * in hardware buffers, but are through after IN)
-	 *
-	 * rroesler: has been commented out and shifted to
-	 *           SkGeDrvEvent(), because it is timer
-	 *           guarded now
-	 *
+
+#ifndef CONFIG_SK98LIN_NAPI
+	/* Handle interrupts */
 	ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
 	ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
-	 */
+#endif
 
 	if (pAC->CheckQueue) {
 		pAC->CheckQueue = SK_FALSE;
@@ -1445,6 +1823,21 @@
 		return;
 	}
 	
+#ifdef CONFIG_SK98LIN_NAPI
+	if (netif_rx_schedule_prep(dev)) {
+		// CLEAR_AND_START_RX(0);
+		// CLEAR_TX_IRQ(0, TX_PRIO_LOW);
+		pAC->GIni.GIValIrqMask &= ~(NAPI_DRV_IRQS);
+		SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
+		__netif_rx_schedule(dev);
+	} 
+
+#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
+	if (IntSrc & IS_XA1_F) {
+		CLEAR_TX_IRQ(0, TX_PRIO_LOW);
+	}
+#endif
+#else
 	while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
 #if 0 /* software irq currently not used */
 		if (IntSrc & IS_IRQ_SW) {
@@ -1458,6 +1851,7 @@
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF RX1 IRQ\n"));
 			ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
+			CLEAR_AND_START_RX(0);
 			SK_PNMI_CNT_RX_INTR(pAC, 0);
 		}
 #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
@@ -1465,6 +1859,7 @@
 			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF AS TX1 IRQ\n"));
+			CLEAR_TX_IRQ(0, TX_PRIO_LOW);
 			SK_PNMI_CNT_TX_INTR(pAC, 0);
 			spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
 			FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
@@ -1475,24 +1870,18 @@
 			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
 				SK_DBGCAT_DRV_INT_SRC,
 				("EOF SY TX1 IRQ\n"));
+			CLEAR_TX_IRQ(0, TX_PRIO_HIGH);
 			SK_PNMI_CNT_TX_INTR(pAC, 0);
 			spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
 			FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
 			spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
-			ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
 		}
 #endif
 #endif
 
-		/* do all IO at once */
-		if (IntSrc & IS_R1_F)
-			ClearAndStartRx(pAC, 0);
-#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
-		if (IntSrc & IS_XA1_F)
-			ClearTxIrq(pAC, 0, TX_PRIO_LOW);
-#endif
 		SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
 	} /* while (IntSrc & IRQ_MASK != 0) */
+#endif
 	
 	IntSrc &= pAC->GIni.GIValIrqMask;
 	if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
@@ -1506,17 +1895,10 @@
 		SkEventDispatcher(pAC, pAC->IoBase);
 		spin_unlock(&pAC->SlowPathLock);
 	}
-	/*
-	 * do it all again is case we cleared an interrupt that
-	 * came in after handling the ring (OUTs may be delayed
-	 * in hardware buffers, but are through after IN)
-	 *
-	 * rroesler: has been commented out and shifted to
-	 *           SkGeDrvEvent(), because it is timer
-	 *           guarded now
-	 *
+
+#ifndef CONFIG_SK98LIN_NAPI
 	ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
-	 */
+#endif
 
 	/* IRQ is processed - Enable IRQs again*/
 	SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
@@ -1524,7 +1906,6 @@
 		return;
 } /* SkGeIsrOnePort */
 
-
 /****************************************************************************
  *
  *	SkGeOpen - handle start of initialized adapter
@@ -1542,27 +1923,22 @@
  *	!= 0 on error
  */
 static int SkGeOpen(
-struct SK_NET_DEVICE	*dev)
+struct SK_NET_DEVICE *dev)  /* the device that is to be opened */
 {
-	DEV_NET			*pNet;
-	SK_AC			*pAC;
-	unsigned long	Flags;		/* for spin lock */
-	int				i;
-	SK_EVPARA		EvPara;		/* an event parameter union */
+	DEV_NET        *pNet = (DEV_NET*) dev->priv;
+	SK_AC          *pAC  = pNet->pAC;
+	unsigned long   Flags;    /* for the spin locks    */
+	int             CurrMac;  /* loop ctr for ports    */
+	SK_EVPARA       EvPara;   /* event parameter union */
 
-	pNet = (DEV_NET*) dev->priv;
-	pAC = pNet->pAC;
-	
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC));
 
-#ifdef SK_DIAG_SUPPORT
 	if (pAC->DiagModeActive == DIAG_ACTIVE) {
 		if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
 			return (-1);   /* still in use by diag; deny actions */
 		} 
 	}
-#endif
 
 
 	/* Set blink mode */
@@ -1599,18 +1975,31 @@
 		pAC->BoardLevel = SK_INIT_RUN;
 	}
 
-	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-		/* Enable transmit descriptor polling. */
-		SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
-		FillRxRing(pAC, &pAC->RxPort[i]);
+	for (CurrMac=0; CurrMac<pAC->GIni.GIMacsFound; CurrMac++) {
+		if (CHIP_ID_YUKON_2(pAC)) {
+			SkY2PortStart(pAC, pAC->IoBase, CurrMac);
+		} else {
+			/* Enable transmit descriptor polling. */
+			SkGePollTxD(pAC, pAC->IoBase, CurrMac, SK_TRUE);
+			FillRxRing(pAC, &pAC->RxPort[CurrMac]);
+			SkMacRxTxEnable(pAC, pAC->IoBase, pNet->PortNr);
+		}
 	}
-	SkGeYellowLED(pAC, pAC->IoBase, 1);
 
-	StartDrvCleanupTimer(pAC);
+	SkGeYellowLED(pAC, pAC->IoBase, 1);
 	SkDimEnableModerationIfNeeded(pAC);	
-	SkDimDisplayModerationSettings(pAC);
 
-	pAC->GIni.GIValIrqMask &= IRQ_MASK;
+	if (!CHIP_ID_YUKON_2(pAC)) {
+		/*
+		** Has been setup already at SkGeInit(SK_INIT_IO),
+		** but additional masking added for Genesis & Yukon
+		** chipsets -> modify it...
+		*/
+		pAC->GIni.GIValIrqMask &= IRQ_MASK;
+#ifndef USE_TX_COMPLETE
+		pAC->GIni.GIValIrqMask &= ~(TX_COMPL_IRQS);
+#endif
+	}
 
 	/* enable Interrupts */
 	SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
@@ -1659,24 +2048,22 @@
  *	error code - on error
  */
 static int SkGeClose(
-struct SK_NET_DEVICE	*dev)
+struct SK_NET_DEVICE *dev)  /* the device that is to be closed */
 {
-	DEV_NET		*pNet;
-	DEV_NET		*newPtrNet;
-	SK_AC		*pAC;
-
-	unsigned long	Flags;		/* for spin lock */
-	int		i;
-	int		PortIdx;
-	SK_EVPARA	EvPara;
-
+	DEV_NET         *pNet = (DEV_NET*) dev->priv;
+	SK_AC           *pAC  = pNet->pAC;
+	DEV_NET         *newPtrNet;
+	unsigned long    Flags;        /* for the spin locks           */
+	int              CurrMac;      /* loop ctr for the current MAC */
+	int              PortIdx;
+	SK_EVPARA        EvPara;
+#ifdef CONFIG_SK98LIN_NAPI
+	int              WorkToDo = 1; /* min(*budget, dev->quota);    */
+	int              WorkDone = 0;
+#endif
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
 
-	pNet = (DEV_NET*) dev->priv;
-	pAC = pNet->pAC;
-
-#ifdef SK_DIAG_SUPPORT
 	if (pAC->DiagModeActive == DIAG_ACTIVE) {
 		if (pAC->DiagFlowCtrl == SK_FALSE) {
 			MOD_DEC_USE_COUNT;
@@ -1696,7 +2083,6 @@
 			pAC->DiagFlowCtrl = SK_FALSE;
 		}
 	}
-#endif
 
 	netif_stop_queue(dev);
 
@@ -1705,8 +2091,6 @@
 	else
 		PortIdx = pNet->NetNr;
 
-        StopDrvCleanupTimer(pAC);
-
 	/*
 	 * Clear multicast table, promiscuous mode ....
 	 */
@@ -1724,8 +2108,14 @@
 		SkEventDispatcher(pAC, pAC->IoBase);
 		SK_OUT32(pAC->IoBase, B0_IMSK, 0);
 		/* stop the hardware */
-		SkGeDeInit(pAC, pAC->IoBase);
-		pAC->BoardLevel = SK_INIT_DATA;
+		/* SkGeDeInit(pAC, pAC->IoBase);	*/
+		/* pAC->BoardLevel = SK_INIT_DATA;	*/
+		if (CHIP_ID_YUKON_2(pAC)) {
+			SkY2PortStop(pAC, pAC->IoBase, 0, SK_STOP_ALL, SK_HARD_RST);
+		}
+		else {
+			SkGeStopPort(pAC, pAC->IoBase, 0, SK_STOP_ALL, SK_HARD_RST);
+		}
 		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
 	} else {
 
@@ -1740,24 +2130,52 @@
 		/* Stop port */
 		spin_lock_irqsave(&pAC->TxPort[pNet->PortNr]
 			[TX_PRIO_LOW].TxDesRingLock, Flags);
-		SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr,
-			SK_STOP_ALL, SK_HARD_RST);
+		if (CHIP_ID_YUKON_2(pAC)) {
+			SkY2PortStop(pAC, pAC->IoBase, pNet->PortNr,
+				SK_STOP_ALL, SK_HARD_RST);
+		}
+		else {
+			SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr,
+				SK_STOP_ALL, SK_HARD_RST);
+		}
 		spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr]
 			[TX_PRIO_LOW].TxDesRingLock, Flags);
 	}
 
 	if (pAC->RlmtNets == 1) {
 		/* clear all descriptor rings */
-		for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-			ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
-			ClearRxRing(pAC, &pAC->RxPort[i]);
-			ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);
+		for (CurrMac=0; CurrMac<pAC->GIni.GIMacsFound; CurrMac++) {
+			if (!CHIP_ID_YUKON_2(pAC)) {
+#ifdef CONFIG_SK98LIN_NAPI
+				WorkToDo = 1;
+				ReceiveIrq(pAC,&pAC->RxPort[CurrMac],
+						SK_TRUE,&WorkDone,WorkToDo);
+#else
+				ReceiveIrq(pAC,&pAC->RxPort[CurrMac],SK_TRUE);
+#endif
+				ClearRxRing(pAC, &pAC->RxPort[CurrMac]);
+				ClearTxRing(pAC, &pAC->TxPort[CurrMac][TX_PRIO_LOW]);
+			} else {
+				SkY2FreeRxBuffers(pAC, pAC->IoBase, CurrMac);
+				SkY2FreeTxBuffers(pAC, pAC->IoBase, CurrMac);
+			}
 		}
 	} else {
 		/* clear port descriptor rings */
-		ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE);
-		ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
-		ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);
+		if (!CHIP_ID_YUKON_2(pAC)) {
+#ifdef CONFIG_SK98LIN_NAPI
+			WorkToDo = 1;
+			ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE, &WorkDone, WorkToDo);
+#else
+			ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE);
+#endif
+			ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
+			ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);
+		}
+		else {
+			SkY2FreeRxBuffers(pAC, pAC->IoBase, pNet->PortNr);
+			SkY2FreeTxBuffers(pAC, pAC->IoBase, pNet->PortNr);
+		}
 	}
 
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
@@ -1828,9 +2246,11 @@
 	}
 
 	/* Transmitter out of resources? */
+#ifdef USE_TX_COMPLETE
 	if (Rc <= 0) {
 		netif_stop_queue(dev);
 	}
+#endif
 
 	/* If not taken, give buffer ownership back to the
 	 * queueing layer.
@@ -1842,6 +2262,53 @@
 	return (0);
 } /* SkGeXmit */
 
+#ifdef CONFIG_SK98LIN_NAPI
+/*****************************************************************************
+ *
+ * 	SkGePoll - NAPI Rx polling callback for GEnesis and Yukon chipsets
+ *
+ * Description:
+ *	Called by the Linux system in case NAPI polling is activated
+ *
+ * Returns:
+ *	The number of work data still to be handled
+ */
+static int SkGePoll(struct net_device *dev, int *budget) 
+{
+SK_AC	*pAC = ((DEV_NET*)(dev->priv))->pAC; /* pointer to adapter context */
+int	WorkToDo = min(*budget, dev->quota);
+int	WorkDone = 0;
+
+	if (pAC->dev[0] != pAC->dev[1]) {
+#ifdef USE_TX_COMPLETE
+		spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
+		FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]);
+		spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
+#endif
+		ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE, &WorkDone, WorkToDo);
+	}
+#ifdef USE_TX_COMPLETE
+	spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
+	FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
+	spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
+#endif
+	ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE, &WorkDone, WorkToDo);
+
+	*budget -= WorkDone;
+	dev->quota -= WorkDone;
+
+	if(WorkDone < WorkToDo) {
+		netif_rx_complete(dev);
+		/* enable interrupts again */
+		pAC->GIni.GIValIrqMask |= (NAPI_DRV_IRQS);
+#ifndef USE_TX_COMPLETE
+		pAC->GIni.GIValIrqMask &= ~(TX_COMPL_IRQS);
+#endif
+		SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
+	}
+	return (WorkDone >= WorkToDo);
+} /* SkGePoll */
+#endif
 
 /*****************************************************************************
  *
@@ -1866,7 +2333,7 @@
  *	< 0 - on failure: other problems ( -> return failure to upper layers)
  */
 static int XmitFrame(
-SK_AC 		*pAC,		/* pointer to adapter context           */
+SK_AC 		*pAC,		/* pointer to adapter context	        */
 TX_PORT		*pTxPort,	/* pointer to struct of port to send to */
 struct sk_buff	*pMessage)	/* pointer to send-message              */
 {
@@ -1882,11 +2349,14 @@
 
 	spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
 #ifndef USE_TX_COMPLETE
-	FreeTxDescriptors(pAC, pTxPort);
+	if ((pTxPort->TxdRingPrevFree - pTxPort->TxdRingFree) > 6)  {
+		FreeTxDescriptors(pAC, pTxPort);
+		pTxPort->TxdRingPrevFree = pTxPort->TxdRingFree;
+	}
 #endif
 	if (pTxPort->TxdRingFree == 0) {
 		/* 
-		** no enough free descriptors in ring at the moment.
+		** not enough free descriptors in ring at the moment.
 		** Maybe free'ing some old one help?
 		*/
 		FreeTxDescriptors(pAC, pTxPort);
@@ -1914,6 +2384,7 @@
 	*/
 	if (BytesSend < C_LEN_ETHERNET_MINSIZE) {
 		if ((pMessage = skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) == NULL) {
+			spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
 			return 0;
 		}
 		pMessage->len = C_LEN_ETHERNET_MINSIZE;
@@ -1971,7 +2442,7 @@
 				   BMU_IRQ_EOF |
 #endif
 				   pMessage->len;
-        } else {
+	} else {
 		pTxd->TBControl = BMU_OWN | BMU_STF | BMU_CHECK | 
 				  BMU_SW  | BMU_EOF |
 #ifdef USE_TX_COMPLETE
@@ -2391,33 +2862,40 @@
  * Returns:	N/A
  */
 static void ReceiveIrq(
-	SK_AC		*pAC,			/* pointer to adapter context */
-	RX_PORT		*pRxPort,		/* pointer to receive port struct */
-	SK_BOOL		SlowPathLock)	/* indicates if SlowPathLock is needed */
-{
-RXD				*pRxd;			/* pointer to receive descriptors */
-SK_U32			Control;		/* control field of descriptor */
-struct sk_buff	*pMsg;			/* pointer to message holding frame */
-struct sk_buff	*pNewMsg;		/* pointer to a new message for copying frame */
-int				FrameLength;	/* total length of received frame */
-int				IpFrameLength;
-SK_MBUF			*pRlmtMbuf;		/* ptr to a buffer for giving a frame to rlmt */
-SK_EVPARA		EvPara;			/* an event parameter union */	
-unsigned long	Flags;			/* for spin lock */
-int				PortIndex = pRxPort->PortIndex;
-unsigned int	Offset;
-unsigned int	NumBytes;
-unsigned int	ForRlmt;
-SK_BOOL			IsBc;
-SK_BOOL			IsMc;
-SK_BOOL  IsBadFrame; 			/* Bad frame */
-
-SK_U32			FrameStat;
-unsigned short	Csum1;
-unsigned short	Csum2;
-unsigned short	Type;
-int				Result;
-SK_U64			PhysAddr;
+#ifdef CONFIG_SK98LIN_NAPI
+SK_AC    *pAC,          /* pointer to adapter context          */
+RX_PORT  *pRxPort,      /* pointer to receive port struct      */
+SK_BOOL   SlowPathLock, /* indicates if SlowPathLock is needed */
+int      *WorkDone,
+int       WorkToDo)
+#else
+SK_AC    *pAC,          /* pointer to adapter context          */
+RX_PORT  *pRxPort,      /* pointer to receive port struct      */
+SK_BOOL   SlowPathLock) /* indicates if SlowPathLock is needed */
+#endif
+{
+	RXD             *pRxd;          /* pointer to receive descriptors         */
+	struct sk_buff  *pMsg;          /* pointer to message holding frame       */
+	struct sk_buff  *pNewMsg;       /* pointer to new message for frame copy  */
+	SK_MBUF         *pRlmtMbuf;     /* ptr to buffer for giving frame to RLMT */
+	SK_EVPARA        EvPara;        /* an event parameter union        */	
+	SK_U32           Control;       /* control field of descriptor     */
+	unsigned long    Flags;         /* for spin lock handling          */
+	int              PortIndex = pRxPort->PortIndex;
+	int              FrameLength;   /* total length of received frame  */
+	int              IpFrameLength; /* IP length of the received frame */
+	unsigned int     Offset;
+	unsigned int     NumBytes;
+	unsigned int     RlmtNotifier;
+	SK_BOOL          IsBc;          /* we received a broadcast packet  */
+	SK_BOOL          IsMc;          /* we received a multicast packet  */
+	SK_BOOL          IsBadFrame;    /* the frame received is bad!      */
+	SK_U32           FrameStat;
+	unsigned short   Csum1;
+	unsigned short   Csum2;
+	unsigned short   Type;
+	int              Result;
+	SK_U64           PhysAddr;
 
 rx_start:	
 	/* do forever; exit if BMU_OWN found */
@@ -2439,6 +2917,13 @@
 
 		Control = pRxd->RBControl;
 	
+#ifdef CONFIG_SK98LIN_NAPI
+		if (*WorkDone >= WorkToDo) {
+			break;
+		}
+		(*WorkDone)++;
+#endif
+
 		/* check if this descriptor is ready */
 		if ((Control & BMU_OWN) != 0) {
 			/* this descriptor is not yet ready */
@@ -2447,7 +2932,6 @@
 			FillRxRing(pAC, pRxPort);
 			return;
 		}
-                pAC->DynIrqModInfo.NbrProcessedDescr++;
 
 		/* get length of frame and check it */
 		FrameLength = Control & BMU_BBC;
@@ -2466,8 +2950,8 @@
 		FrameStat = pRxd->FrameStat;
 
 		/* check for frame length mismatch */
-#define XMR_FS_LEN_SHIFT        18
-#define GMR_FS_LEN_SHIFT        16
+#define XMR_FS_LEN_SHIFT	18
+#define GMR_FS_LEN_SHIFT	16
 		if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
 			if (FrameLength != (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)) {
 				SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
@@ -2477,8 +2961,7 @@
 					(SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
 				goto rx_failed;
 			}
-		}
-		else {
+		} else {
 			if (FrameLength != (SK_U32) (FrameStat >> GMR_FS_LEN_SHIFT)) {
 				SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
 					SK_DBGCAT_DRV_RX_PROGRESS,
@@ -2558,13 +3041,11 @@
 
 			pMsg = pNewMsg;
 
-		}
-		else {
+		} else {
 			/*
 			 * if large frame, or SKB allocation failed, pass
 			 * the SKB directly to the networking
 			 */
-
 			PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
 			PhysAddr |= (SK_U64) pRxd->VDataLow;
 
@@ -2573,119 +3054,75 @@
 					 PhysAddr,
 					 pAC->RxBufSize - 2,
 					 PCI_DMA_FROMDEVICE);
+			skb_put(pMsg, FrameLength); /* set message len */
+			pMsg->ip_summed = CHECKSUM_NONE; /* initial default */
 
-			/* set length in message */
-			skb_put(pMsg, FrameLength);
-			/* hardware checksum */
-			Type = ntohs(*((short*)&pMsg->data[12]));
-
-#ifdef USE_SK_RX_CHECKSUM
-			if (Type == 0x800) {
-				Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff);
-				Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff);
-				IpFrameLength = (int) ntohs((unsigned short)
-								((unsigned short *) pMsg->data)[8]);
-
-				/*
-				 * Test: If frame is padded, a check is not possible!
-				 * Frame not padded? Length difference must be 14 (0xe)!
-				 */
-				if ((FrameLength - IpFrameLength) != 0xe) {
-				/* Frame padded => TCP offload not possible! */
-					pMsg->ip_summed = CHECKSUM_NONE;
-				} else {
-				/* Frame not padded => TCP offload! */
-					if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) &&
-						(pAC->GIni.GIChipId == CHIP_ID_GENESIS)) ||
-						(pAC->ChipsetType)) {
-						Result = SkCsGetReceiveInfo(pAC,
-							&pMsg->data[14],
-							Csum1, Csum2, pRxPort->PortIndex);
-						if (Result ==
-							SKCS_STATUS_IP_FRAGMENT ||
-							Result ==
-							SKCS_STATUS_IP_CSUM_OK ||
-							Result ==
-							SKCS_STATUS_TCP_CSUM_OK ||
-							Result ==
-							SKCS_STATUS_UDP_CSUM_OK) {
-								pMsg->ip_summed =
-								CHECKSUM_UNNECESSARY;
-						}
-						else if (Result ==
-							SKCS_STATUS_TCP_CSUM_ERROR ||
-							Result ==
-							SKCS_STATUS_UDP_CSUM_ERROR ||
-							Result ==
-							SKCS_STATUS_IP_CSUM_ERROR_UDP ||
-							Result ==
-							SKCS_STATUS_IP_CSUM_ERROR_TCP ||
-							Result ==
-							SKCS_STATUS_IP_CSUM_ERROR ) {
-							/* HW Checksum error */
-							SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-							SK_DBGCAT_DRV_RX_PROGRESS,
-							("skge: CRC error. Frame dropped!\n"));
-							goto rx_failed;
-						} else {
-								pMsg->ip_summed =
-								CHECKSUM_NONE;
-						}
-					}/* checksumControl calculation valid */
-				} /* Frame length check */
-			} /* IP frame */
-#else
-			pMsg->ip_summed = CHECKSUM_NONE;	
-#endif
+			if (pRxPort->UseRxCsum) {
+				Type = ntohs(*((short*)&pMsg->data[12]));
+				if (Type == 0x800) {
+					IpFrameLength = (int) ntohs((unsigned short)
+							((unsigned short *) pMsg->data)[8]);
+					if ((FrameLength - IpFrameLength) == 0xe) {
+						Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff);
+						Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff);
+						if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) &&
+							(pAC->GIni.GIChipId == CHIP_ID_GENESIS)) ||
+							(pAC->ChipsetType)) {
+							Result = SkCsGetReceiveInfo(pAC, &pMsg->data[14],
+								Csum1, Csum2, PortIndex);
+							if ((Result == SKCS_STATUS_IP_FRAGMENT) ||
+							    (Result == SKCS_STATUS_IP_CSUM_OK)  ||
+							    (Result == SKCS_STATUS_TCP_CSUM_OK) ||
+							    (Result == SKCS_STATUS_UDP_CSUM_OK)) {
+								pMsg->ip_summed = CHECKSUM_UNNECESSARY;
+							} else if ((Result == SKCS_STATUS_TCP_CSUM_ERROR)    ||
+							           (Result == SKCS_STATUS_UDP_CSUM_ERROR)    ||
+							           (Result == SKCS_STATUS_IP_CSUM_ERROR_UDP) ||
+							           (Result == SKCS_STATUS_IP_CSUM_ERROR_TCP) ||
+							           (Result == SKCS_STATUS_IP_CSUM_ERROR)) {
+								/* HW Checksum error */
+								SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+								SK_DBGCAT_DRV_RX_PROGRESS,
+								("skge: CRC error. Frame dropped!\n"));
+								goto rx_failed;
+							} else {
+								pMsg->ip_summed = CHECKSUM_NONE;
+							}
+						}/* checksumControl calculation valid */
+					} /* Frame length check */
+				} /* IP frame */
+			} /* pRxPort->UseRxCsum */
 		} /* frame > SK_COPY_TRESHOLD */
 		
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV,	1,("V"));
-		ForRlmt = SK_RLMT_RX_PROTOCOL;
-#if 0
-		IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC;
-#endif
+		RlmtNotifier = SK_RLMT_RX_PROTOCOL;
 		SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength,
-			IsBc, &Offset, &NumBytes);
+					IsBc, &Offset, &NumBytes);
 		if (NumBytes != 0) {
-#if 0
-			IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC;
-#endif
-			SK_RLMT_LOOKAHEAD(pAC, PortIndex,
-				&pMsg->data[Offset],
-				IsBc, IsMc, &ForRlmt);
+			SK_RLMT_LOOKAHEAD(pAC,PortIndex,&pMsg->data[Offset],
+						IsBc,IsMc,&RlmtNotifier);
 		}
-		if (ForRlmt == SK_RLMT_RX_PROTOCOL) {
-					SK_DBG_MSG(NULL, SK_DBGMOD_DRV,	1,("W"));
+		if (RlmtNotifier == SK_RLMT_RX_PROTOCOL) {
+			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,	1,("W"));
 			/* send up only frames from active port */
-			if ((PortIndex == pAC->ActivePort) ||
-				(pAC->RlmtNets == 2)) {
-				/* frame for upper layer */
+			if ((PortIndex == pAC->ActivePort)||(pAC->RlmtNets == 2)) {
 				SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U"));
 #ifdef xDEBUG
 				DumpMsg(pMsg, "Rx");
 #endif
-				SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
-					FrameLength, pRxPort->PortIndex);
-
-				pMsg->dev = pAC->dev[pRxPort->PortIndex];
-				pMsg->protocol = eth_type_trans(pMsg,
-					pAC->dev[pRxPort->PortIndex]);
-				netif_rx(pMsg);
-				pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
-			}
-			else {
-				/* drop frame */
+				SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,FrameLength,PortIndex);
+				pMsg->dev = pAC->dev[PortIndex];
+				pMsg->protocol = eth_type_trans(pMsg,pAC->dev[PortIndex]);
+				netif_rx(pMsg); /* frame for upper layer */
+				pAC->dev[PortIndex]->last_rx = jiffies;
+			} else {
 				SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-					SK_DBGCAT_DRV_RX_PROGRESS,
-					("D"));
-				DEV_KFREE_SKB(pMsg);
+					SK_DBGCAT_DRV_RX_PROGRESS,("D"));
+				DEV_KFREE_SKB(pMsg); /* drop frame */
 			}
-			
-		} /* if not for rlmt */
-		else {
-			/* packet for rlmt */
+		} else { /* packet for RLMT stack */
 			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-				SK_DBGCAT_DRV_RX_PROGRESS, ("R"));
+				SK_DBGCAT_DRV_RX_PROGRESS,("R"));
 			pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
 				pAC->IoBase, FrameLength);
 			if (pRlmtMbuf != NULL) {
@@ -2713,32 +3150,22 @@
 				}
 
 				SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-					SK_DBGCAT_DRV_RX_PROGRESS,
-					("Q"));
+					SK_DBGCAT_DRV_RX_PROGRESS,("Q"));
 			}
-			if ((pAC->dev[pRxPort->PortIndex]->flags &
-				(IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
-				(ForRlmt & SK_RLMT_RX_PROTOCOL) ==
-				SK_RLMT_RX_PROTOCOL) {
-				pMsg->dev = pAC->dev[pRxPort->PortIndex];
-				pMsg->protocol = eth_type_trans(pMsg,
-					pAC->dev[pRxPort->PortIndex]);
+			if ((pAC->dev[PortIndex]->flags & (IFF_PROMISC | IFF_ALLMULTI)) ||
+			    (RlmtNotifier & SK_RLMT_RX_PROTOCOL)) {
+				pMsg->dev = pAC->dev[PortIndex];
+				pMsg->protocol = eth_type_trans(pMsg,pAC->dev[PortIndex]);
 				netif_rx(pMsg);
-				pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
-			}
-			else {
+				pAC->dev[PortIndex]->last_rx = jiffies;
+			} else {
 				DEV_KFREE_SKB(pMsg);
 			}
-
-		} /* if packet for rlmt */
+		} /* if packet for RLMT stack */
 	} /* for ... scanning the RXD ring */
 
 	/* RXD ring is empty -> fill and restart */
 	FillRxRing(pAC, pRxPort);
-	/* do not start if called from Close */
-	if (pAC->BoardLevel > SK_INIT_DATA) {
-		ClearAndStartRx(pAC, PortIndex);
-	}
 	return;
 
 rx_failed:
@@ -2762,49 +3189,6 @@
 
 } /* ReceiveIrq */
 
-
-/*****************************************************************************
- *
- * 	ClearAndStartRx - give a start receive command to BMU, clear IRQ
- *
- * Description:
- *	This function sends a start command and a clear interrupt
- *	command for one receive queue to the BMU.
- *
- * Returns: N/A
- *	none
- */
-static void ClearAndStartRx(
-SK_AC	*pAC,		/* pointer to the adapter context */
-int	PortIndex)	/* index of the receive port (XMAC) */
-{
-	SK_OUT8(pAC->IoBase,
-		RxQueueAddr[PortIndex]+Q_CSR,
-		CSR_START | CSR_IRQ_CL_F);
-} /* ClearAndStartRx */
-
-
-/*****************************************************************************
- *
- * 	ClearTxIrq - give a clear transmit IRQ command to BMU
- *
- * Description:
- *	This function sends a clear tx IRQ command for one
- *	transmit queue to the BMU.
- *
- * Returns: N/A
- */
-static void ClearTxIrq(
-SK_AC	*pAC,		/* pointer to the adapter context */
-int	PortIndex,	/* index of the transmit port (XMAC) */
-int	Prio)		/* priority or normal queue */
-{
-	SK_OUT8(pAC->IoBase, 
-		TxQueueAddr[PortIndex][Prio]+Q_CSR,
-		CSR_IRQ_CL_F);
-} /* ClearTxIrq */
-
-
 /*****************************************************************************
  *
  * 	ClearRxRing - remove all buffers from the receive ring
@@ -3018,6 +3402,10 @@
 unsigned long	Flags;
 int		i;
 SK_EVPARA 	EvPara;
+#ifdef CONFIG_SK98LIN_NAPI
+int		WorkToDo = 1; // min(*budget, dev->quota);
+int		WorkDone = 0;
+#endif
 
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeChangeMtu starts now...\n"));
@@ -3033,7 +3421,6 @@
 		return -EINVAL;
 	}
 
-#ifdef SK_DIAG_SUPPORT
 	if (pAC->DiagModeActive == DIAG_ACTIVE) {
 		if (pAC->DiagFlowCtrl == SK_FALSE) {
 			return -1; /* still in use, deny any actions of MTU */
@@ -3041,7 +3428,6 @@
 			pAC->DiagFlowCtrl = SK_FALSE;
 		}
 	}
-#endif
 
 	pNet->Mtu = NewMtu;
 	pOtherNet = (DEV_NET*)pAC->dev[1 - pNet->NetNr]->priv;
@@ -3050,6 +3436,9 @@
 	}
 
 	pAC->RxBufSize = NewMtu + 32;
+	while (pAC->RxBufSize % 8) { /* RxBufSize must be a multiple of 8 */
+		pAC->RxBufSize = pAC->RxBufSize + 1;
+	}
 	dev->mtu = NewMtu;
 
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
@@ -3082,8 +3471,7 @@
 	SkEventDispatcher(pAC, pAC->IoBase);
 
 	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-		spin_lock_irqsave(
-			&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock, Flags);
+		spin_lock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
 		netif_stop_queue(pAC->dev[i]);
 
 	}
@@ -3134,7 +3522,6 @@
 	** enable/disable hardware support for long frames
 	*/
 	if (NewMtu > 1500) {
-// pAC->JumboActivated = SK_TRUE; /* is never set back !!! */
 		pAC->GIni.GIPortUsage = SK_JUMBO_LINK;
 	} else {
 	    if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
@@ -3151,9 +3538,8 @@
 	SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
 	SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
 	SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
-	
+
 	/*
-	** tschilling:
 	** Speed and others are set back to default in level 1 init!
 	*/
 	GetConfiguration(pAC);
@@ -3167,23 +3553,35 @@
 	SkTimerInit(pAC, pAC->IoBase, SK_INIT_RUN);
 
 	/*
-	** clear and reinit the rx rings here
+	** clear and reinit the rx rings here, because of new MTU size
 	*/
 	for (i=0; i<pAC->GIni.GIMacsFound; i++) {
-		ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
-		ClearRxRing(pAC, &pAC->RxPort[i]);
-		FillRxRing(pAC, &pAC->RxPort[i]);
+		if (CHIP_ID_YUKON_2(pAC)) {
+			SkY2FreeRxBuffers(pAC, pAC->IoBase, i);
+			SkY2FreeTxBuffers(pAC, pAC->IoBase, i);
+			SkY2AllocateRxBuffers(pAC, pAC->IoBase, i);
+			SkY2RestartStatusUnit(pAC);
+			SkY2PortStart(pAC, pAC->IoBase, i);
+		} else {
+#ifdef CONFIG_SK98LIN_NAPI
+			WorkToDo = 1;
+			ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE, &WorkDone, WorkToDo);
+#else
+			ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
+#endif
+			ClearRxRing(pAC, &pAC->RxPort[i]);
+			FillRxRing(pAC, &pAC->RxPort[i]);
 
-		/* 
-		** Enable transmit descriptor polling
-		*/
-		SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
-		FillRxRing(pAC, &pAC->RxPort[i]);
-	};
+			/* 
+			** Enable transmit descriptor polling
+			*/
+			SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
+			FillRxRing(pAC, &pAC->RxPort[i]);
+		}
+	}
 
 	SkGeYellowLED(pAC, pAC->IoBase, 1);
 	SkDimEnableModerationIfNeeded(pAC);	
-	SkDimDisplayModerationSettings(pAC);
 
 	netif_start_queue(pAC->dev[pNet->PortNr]);
 	for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) {
@@ -3253,42 +3651,38 @@
 {
 DEV_NET *pNet = (DEV_NET*) dev->priv;
 SK_AC	*pAC = pNet->pAC;
-SK_PNMI_STRUCT_DATA *pPnmiStruct;       /* structure for all Pnmi-Data */
-SK_PNMI_STAT    *pPnmiStat;             /* pointer to virtual XMAC stat. data */
-SK_PNMI_CONF    *pPnmiConf;             /* pointer to virtual link config. */
-unsigned int    Size;                   /* size of pnmi struct */
+SK_PNMI_STRUCT_DATA *pPnmiStruct;	/* structure for all Pnmi-Data */
+SK_PNMI_STAT    *pPnmiStat;		/* pointer to virtual XMAC stat. data */
+SK_PNMI_CONF    *pPnmiConf;		/* pointer to virtual link config. */
+unsigned int    Size;			/* size of pnmi struct */
 unsigned long	Flags;			/* for spin lock */
 
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeStats starts now...\n"));
 	pPnmiStruct = &pAC->PnmiStruct;
 
-#ifdef SK_DIAG_SUPPORT
-        if ((pAC->DiagModeActive == DIAG_NOTACTIVE) &&
-                (pAC->BoardLevel == SK_INIT_RUN)) {
-#endif
-        SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
-        spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-        Size = SK_PNMI_STRUCT_SIZE;
-		SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
-        spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-#ifdef SK_DIAG_SUPPORT
+	if ((pAC->DiagModeActive == DIAG_NOTACTIVE) &&
+		(pAC->BoardLevel == SK_INIT_RUN)) {
+		SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
+		spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+		Size = SK_PNMI_STRUCT_SIZE;
+			SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
+		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
 	}
-#endif
 
-        pPnmiStat = &pPnmiStruct->Stat[0];
-        pPnmiConf = &pPnmiStruct->Conf[0];
+	pPnmiStat = &pPnmiStruct->Stat[0];
+	pPnmiConf = &pPnmiStruct->Conf[0];
 
 	pAC->stats.rx_packets = (SK_U32) pPnmiStruct->RxDeliveredCts & 0xFFFFFFFF;
 	pAC->stats.tx_packets = (SK_U32) pPnmiStat->StatTxOkCts & 0xFFFFFFFF;
 	pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts;
 	pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts;
 	
-        if (pNet->Mtu <= 1500) {
-                pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
-        } else {
-                pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
-                        pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF);
+	if (pNet->Mtu <= 1500) {
+		pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
+	} else {
+		pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
+			pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF);
 	}
 
 
@@ -3335,28 +3729,27 @@
  */
 static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd)
 {
-DEV_NET		*pNet;
-SK_AC		*pAC;
-void		*pMemBuf;
-struct pci_dev  *pdev = NULL;
-SK_GE_IOCTL	Ioctl;
-unsigned int	Err = 0;
-int		Size = 0;
-int             Ret = 0;
-unsigned int	Length = 0;
-int		HeaderLength = sizeof(SK_U32) + sizeof(SK_U32);
+	DEV_NET          *pNet = (DEV_NET*) dev->priv;
+	SK_AC            *pAC  = pNet->pAC;
+	struct pci_dev   *pdev = NULL;
+	void             *pMemBuf;
+	SK_GE_IOCTL       Ioctl;
+	unsigned int      Err = 0;
+	unsigned int      Length = 0;
+	int               HeaderLength = sizeof(SK_U32) + sizeof(SK_U32);
+	int               Size = 0;
+	int               Ret = 0;
 
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeIoctl starts now...\n"));
 
-	pNet = (DEV_NET*) dev->priv;
-	pAC = pNet->pAC;
-	
 	if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
 		return -EFAULT;
 	}
 
 	switch(cmd) {
+	case SIOCETHTOOL:
+		return SkEthIoctl(dev, rq);
 	case SK_IOCTL_SETMIB:
 	case SK_IOCTL_PRESETMIB:
 		if (!capable(CAP_NET_ADMIN)) return -EPERM;
@@ -3405,8 +3798,7 @@
 fault_gen:
 		kfree(pMemBuf); /* cleanup everything */
 		break;
-#ifdef SK_DIAG_SUPPORT
-       case SK_IOCTL_DIAG:
+	case SK_IOCTL_DIAG:
 		if (!capable(CAP_NET_ADMIN)) return -EPERM;
 		if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
 			Length = Ioctl.Len;
@@ -3443,7 +3835,6 @@
 fault_diag:
 		kfree(pMemBuf); /* cleanup everything */
 		break;
-#endif
 	default:
 		Err = -EOPNOTSUPP;
 	}
@@ -3523,17 +3914,18 @@
 SK_I32	Port;		/* preferred port */
 SK_BOOL	AutoSet;
 SK_BOOL DupSet;
-int	LinkSpeed          = SK_LSPEED_AUTO;	/* Link speed */
-int	AutoNeg            = 1;			/* autoneg off (0) or on (1) */
-int	DuplexCap          = 0;			/* 0=both,1=full,2=half */
-int	FlowCtrl           = SK_FLOW_MODE_SYM_OR_REM;	/* FlowControl  */
-int	MSMode             = SK_MS_MODE_AUTO;	/* master/slave mode    */
-
-SK_BOOL IsConTypeDefined   = SK_TRUE;
-SK_BOOL IsLinkSpeedDefined = SK_TRUE;
-SK_BOOL IsFlowCtrlDefined  = SK_TRUE;
-SK_BOOL IsRoleDefined      = SK_TRUE;
-SK_BOOL IsModeDefined      = SK_TRUE;
+int	LinkSpeed		= SK_LSPEED_AUTO;	/* Link speed */
+int	AutoNeg			= 1;			/* autoneg off (0) or on (1) */
+int	DuplexCap		= 0;			/* 0=both,1=full,2=half */
+int	FlowCtrl		= SK_FLOW_MODE_SYM_OR_REM;	/* FlowControl  */
+int	MSMode			= SK_MS_MODE_AUTO;	/* master/slave mode    */
+int	IrqModMaskOffset	= 6;			/* all ints moderated=default */
+
+SK_BOOL IsConTypeDefined	= SK_TRUE;
+SK_BOOL IsLinkSpeedDefined	= SK_TRUE;
+SK_BOOL IsFlowCtrlDefined	= SK_TRUE;
+SK_BOOL IsRoleDefined		= SK_TRUE;
+SK_BOOL IsModeDefined		= SK_TRUE;
 /*
  *	The two parameters AutoNeg. and DuplexCap. map to one configuration
  *	parameter. The mapping is described by this table:
@@ -3551,6 +3943,15 @@
 		  {SK_LMODE_AUTOBOTH , SK_LMODE_AUTOFULL , SK_LMODE_AUTOHALF },
 		  {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} };
 
+SK_U32	IrqModMask[7][2] =
+		{ { IRQ_MASK_RX_ONLY , Y2_DRIVER_IRQS  },
+		  { IRQ_MASK_TX_ONLY , Y2_DRIVER_IRQS  },
+		  { IRQ_MASK_SP_ONLY , Y2_SPECIAL_IRQS },
+		  { IRQ_MASK_SP_RX   , Y2_IRQ_MASK     },
+		  { IRQ_MASK_TX_RX   , Y2_DRIVER_IRQS  },
+		  { IRQ_MASK_SP_TX   , Y2_IRQ_MASK     },
+		  { IRQ_MASK_RX_TX_SP, Y2_IRQ_MASK     } };
+
 #define DC_BOTH	0
 #define DC_FULL 1
 #define DC_HALF 2
@@ -3590,7 +3991,7 @@
 	** 
 	** This ConType parameter is used for all ports of the adapter!
 	*/
-        if ( (ConType != NULL)                && 
+	if ( (ConType != NULL)                && 
 	     (pAC->Index < SK_MAX_CARD_PARAM) &&
 	     (ConType[pAC->Index] != NULL) ) {
 
@@ -3616,40 +4017,40 @@
 			M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
 			M_CurrPort.PLinkSpeed    = SK_LSPEED_AUTO;
 		    }
-                } else if (strcmp(ConType[pAC->Index],"100FD")==0) {
+		} else if (strcmp(ConType[pAC->Index],"100FD")==0) {
 		    for (Port = 0; Port < SK_MAX_MACS; Port++) {
 			M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
 			M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
 			M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
 			M_CurrPort.PLinkSpeed    = SK_LSPEED_100MBPS;
 		    }
-                } else if (strcmp(ConType[pAC->Index],"100HD")==0) {
+		} else if (strcmp(ConType[pAC->Index],"100HD")==0) {
 		    for (Port = 0; Port < SK_MAX_MACS; Port++) {
 			M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
 			M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
 			M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
 			M_CurrPort.PLinkSpeed    = SK_LSPEED_100MBPS;
 		    }
-                } else if (strcmp(ConType[pAC->Index],"10FD")==0) {
+		} else if (strcmp(ConType[pAC->Index],"10FD")==0) {
 		    for (Port = 0; Port < SK_MAX_MACS; Port++) {
 			M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
 			M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
 			M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
 			M_CurrPort.PLinkSpeed    = SK_LSPEED_10MBPS;
 		    }
-                } else if (strcmp(ConType[pAC->Index],"10HD")==0) {
+		} else if (strcmp(ConType[pAC->Index],"10HD")==0) {
 		    for (Port = 0; Port < SK_MAX_MACS; Port++) {
 			M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
 			M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
 			M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
 			M_CurrPort.PLinkSpeed    = SK_LSPEED_10MBPS;
 		    }
-                } else { 
+		} else { 
 		    printk("sk98lin: Illegal value \"%s\" for ConType\n", 
 			ConType[pAC->Index]);
 		    IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */
 		}
-        } else {
+	} else {
 	    IsConTypeDefined = SK_FALSE; /* No ConType defined */
 	}
 
@@ -3668,14 +4069,30 @@
 		} else if (strcmp(Speed_A[pAC->Index],"100")==0) {
 		    LinkSpeed = SK_LSPEED_100MBPS;
 		} else if (strcmp(Speed_A[pAC->Index],"1000")==0) {
-		    LinkSpeed = SK_LSPEED_1000MBPS;
+		    if ((pAC->PciDev->vendor == 0x11ab ) &&
+		    	(pAC->PciDev->device == 0x4350)) {
+				LinkSpeed = SK_LSPEED_100MBPS;
+				printk("sk98lin: Illegal value \"%s\" for Speed_A.\n"
+					"Gigabit speed not possible with this chip revision!",
+					Speed_A[pAC->Index]);
+			} else {
+				LinkSpeed = SK_LSPEED_1000MBPS;
+		    }
 		} else {
 		    printk("sk98lin: Illegal value \"%s\" for Speed_A\n",
 			Speed_A[pAC->Index]);
 		    IsLinkSpeedDefined = SK_FALSE;
 		}
 	} else {
-	    IsLinkSpeedDefined = SK_FALSE;
+		if ((pAC->PciDev->vendor == 0x11ab ) && 
+			(pAC->PciDev->device == 0x4350)) {
+			/* Gigabit speed not supported
+			 * Swith to speed 100
+			 */
+			LinkSpeed = SK_LSPEED_100MBPS;
+		} else {
+			IsLinkSpeedDefined = SK_FALSE;
+		}
 	}
 
 	/* 
@@ -3770,9 +4187,6 @@
 	}
 	
 	if (!AutoSet && DupSet) {
-		printk("sk98lin: Port A: Duplex setting not"
-			" possible in\n    default AutoNegotiation mode"
-			" (Sense).\n    Using AutoNegotiation On\n");
 		AutoNeg = AN_ON;
 	}
 	
@@ -3800,7 +4214,7 @@
 		    FlowCtrl = SK_FLOW_MODE_NONE;
 		} else {
 		    printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n",
-                        FlowCtrl_A[pAC->Index]);
+			FlowCtrl_A[pAC->Index]);
 		    IsFlowCtrlDefined = SK_FALSE;
 		}
 	} else {
@@ -3892,7 +4306,7 @@
 	** Decide whether to set new config value if somethig valid has
 	** been received.
 	*/
-        if (IsLinkSpeedDefined) {
+	if (IsLinkSpeedDefined) {
 	    pAC->GIni.GP[1].PLinkSpeed = LinkSpeed;
 	}
 
@@ -3968,9 +4382,6 @@
 	}
 	
 	if (!AutoSet && DupSet) {
-		printk("sk98lin: Port B: Duplex setting not"
-			" possible in\n    default AutoNegotiation mode"
-			" (Sense).\n    Using AutoNegotiation On\n");
 		AutoNeg = AN_ON;
 	}
 
@@ -4114,6 +4525,7 @@
 	/*
 	** Check the interrupt moderation parameters
 	*/
+	pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
 	if (Moderation[pAC->Index] != NULL) {
 		if (strcmp(Moderation[pAC->Index], "") == 0) {
 			pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
@@ -4127,70 +4539,49 @@
 	   		printk("sk98lin: Illegal value \"%s\" for Moderation.\n"
 				"      Disable interrupt moderation.\n",
 				Moderation[pAC->Index]);
-			pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
-		}
-	} else {
-		pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
-	}
-
-	if (Stats[pAC->Index] != NULL) {
-		if (strcmp(Stats[pAC->Index], "Yes") == 0) {
-			pAC->DynIrqModInfo.DisplayStats = SK_TRUE;
-		} else {
-			pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
 		}
 	} else {
-		pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
+/* Set interrupt moderation if wished */
+#ifdef CONFIG_SK98LIN_STATINT
+		pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC;
+#endif
 	}
 
 	if (ModerationMask[pAC->Index] != NULL) {
 		if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) {
-			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
+			IrqModMaskOffset = 0;
 		} else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) {
-			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY;
+			IrqModMaskOffset = 1;
 		} else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) {
-			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY;
+			IrqModMaskOffset = 2;
 		} else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) {
-			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
+			IrqModMaskOffset = 3;
 		} else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) {
-			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
+			IrqModMaskOffset = 3;
 		} else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) {
-			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
+			IrqModMaskOffset = 4;
 		} else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) {
-			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
+			IrqModMaskOffset = 4;
 		} else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) {
-			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
+			IrqModMaskOffset = 5;
 		} else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) {
-			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
-		} else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) {
-			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-		} else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) {
-			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-		} else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) {
-			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-		} else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) {
-			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-		} else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) {
-			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-		} else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) {
-			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-		} else { /* some rubbish */
-			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
-		}
-	} else {  /* operator has stated nothing */
-		pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
-	}
-
-	if (AutoSizing[pAC->Index] != NULL) {
-		if (strcmp(AutoSizing[pAC->Index], "On") == 0) {
-			pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
-		} else {
-			pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
+			IrqModMaskOffset = 5;
+		} else { /* some rubbish stated */
+			// IrqModMaskOffset = 6; ->has been initialized
+			// already at the begin of this function...
 		}
-	} else {  /* operator has stated nothing */
-		pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
+	}
+	if (!CHIP_ID_YUKON_2(pAC)) {
+		pAC->DynIrqModInfo.MaskIrqModeration = IrqModMask[IrqModMaskOffset][0];
+	} else {
+		pAC->DynIrqModInfo.MaskIrqModeration = IrqModMask[IrqModMaskOffset][1];
 	}
 
+	if (!CHIP_ID_YUKON_2(pAC)) {
+		pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
+	} else {
+		pAC->DynIrqModInfo.MaxModIntsPerSec = C_Y2_INTS_PER_SEC_DEFAULT;
+	}
 	if (IntsPerSec[pAC->Index] != 0) {
 		if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) || 
 			(IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) {
@@ -4199,28 +4590,25 @@
 				IntsPerSec[pAC->Index],
 				C_INT_MOD_IPS_LOWER_RANGE,
 				C_INT_MOD_IPS_UPPER_RANGE,
-				C_INTS_PER_SEC_DEFAULT);
-			pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
+				pAC->DynIrqModInfo.MaxModIntsPerSec);
 		} else {
 			pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index];
 		}
-	} else {
-		pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
-	}
+	} 
 
 	/*
 	** Evaluate upper and lower moderation threshold
 	*/
 	pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit =
 		pAC->DynIrqModInfo.MaxModIntsPerSec +
-		(pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
+		(pAC->DynIrqModInfo.MaxModIntsPerSec / 5);
 
 	pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit =
 		pAC->DynIrqModInfo.MaxModIntsPerSec -
-		(pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
-
-	pAC->DynIrqModInfo.PrevTimeVal = jiffies;  /* initial value */
+		(pAC->DynIrqModInfo.MaxModIntsPerSec / 5);
 
+	pAC->DynIrqModInfo.DynIrqModSampleInterval = 
+		SK_DRV_MODERATION_TIMER_LENGTH;
 
 } /* GetConfiguration */
 
@@ -4256,45 +4644,6 @@
 	}
 } /* ProductStr */
 
-/*****************************************************************************
- *
- *      StartDrvCleanupTimer - Start timer to check for descriptors which
- *                             might be placed in descriptor ring, but
- *                             havent been handled up to now
- *
- * Description:
- *      This function requests a HW-timer fo the Yukon card. The actions to
- *      perform when this timer expires, are located in the SkDrvEvent().
- *
- * Returns: N/A
- */
-static void
-StartDrvCleanupTimer(SK_AC *pAC) {
-    SK_EVPARA    EventParam;   /* Event struct for timer event */
-
-    SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
-    EventParam.Para32[0] = SK_DRV_RX_CLEANUP_TIMER;
-    SkTimerStart(pAC, pAC->IoBase, &pAC->DrvCleanupTimer,
-                 SK_DRV_RX_CLEANUP_TIMER_LENGTH,
-                 SKGE_DRV, SK_DRV_TIMER, EventParam);
-}
-
-/*****************************************************************************
- *
- *      StopDrvCleanupTimer - Stop timer to check for descriptors
- *
- * Description:
- *      This function requests a HW-timer fo the Yukon card. The actions to
- *      perform when this timer expires, are located in the SkDrvEvent().
- *
- * Returns: N/A
- */
-static void
-StopDrvCleanupTimer(SK_AC *pAC) {
-    SkTimerStop(pAC, pAC->IoBase, &pAC->DrvCleanupTimer);
-    SK_MEMSET((char *) &pAC->DrvCleanupTimer, 0, sizeof(SK_TIMER));
-}
-
 /****************************************************************************/
 /* functions for common modules *********************************************/
 /****************************************************************************/
@@ -4383,7 +4732,9 @@
 SK_U64 SkOsGetTime(SK_AC *pAC)
 {
 	SK_U64	PrivateJiffies;
+
 	SkOsGetTimeCurrent(pAC, &PrivateJiffies);
+
 	return PrivateJiffies;
 } /* SkOsGetTime */
 
@@ -4538,28 +4889,31 @@
  *	
  */
 int SkDrvEvent(
-SK_AC *pAC,		/* pointer to adapter context */
-SK_IOC IoC,		/* io-context */
-SK_U32 Event,		/* event-id */
-SK_EVPARA Param)	/* event-parameter */
-{
-SK_MBUF		*pRlmtMbuf;	/* pointer to a rlmt-mbuf structure */
-struct sk_buff	*pMsg;		/* pointer to a message block */
-int		FromPort;	/* the port from which we switch away */
-int		ToPort;		/* the port we switch to */
-SK_EVPARA	NewPara;	/* parameter for further events */
-int		Stat;
-unsigned long	Flags;
-SK_BOOL		DualNet;
+SK_AC     *pAC,    /* pointer to adapter context */
+SK_IOC     IoC,    /* IO control context         */
+SK_U32     Event,  /* event-id                   */
+SK_EVPARA  Param)  /* event-parameter            */
+{
+	SK_MBUF         *pRlmtMbuf;   /* pointer to a rlmt-mbuf structure   */
+	struct sk_buff  *pMsg;        /* pointer to a message block         */
+	SK_EVPARA        NewPara;     /* parameter for further events       */
+	SK_BOOL          DualNet;
+	SK_U32           Reason;
+	unsigned long    Flags;
+	int              FromPort;    /* the port from which we switch away */
+	int              ToPort;      /* the port we switch to              */
+	int              Stat;
+#ifdef CONFIG_SK98LIN_NAPI
+	int              WorkToDo = 1; /* min(*budget, dev->quota); */
+	int              WorkDone = 0;
+#endif
 
 	switch (Event) {
 	case SK_DRV_ADAP_FAIL:
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
 			("ADAPTER FAIL EVENT\n"));
 		printk("%s: Adapter failed.\n", pAC->dev[0]->name);
-		/* disable interrupts */
-		SK_OUT32(pAC->IoBase, B0_IMSK, 0);
-		/* cgoos */
+		SK_OUT32(pAC->IoBase, B0_IMSK, 0); /* disable interrupts */
 		break;
 	case SK_DRV_PORT_FAIL:
 		FromPort = Param.Para32[0];
@@ -4570,10 +4924,8 @@
 		} else {
 			printk("%s: Port B failed.\n", pAC->dev[1]->name);
 		}
-		/* cgoos */
 		break;
-	case SK_DRV_PORT_RESET:	 /* SK_U32 PortIdx */
-		/* action list 4 */
+	case SK_DRV_PORT_RESET:
 		FromPort = Param.Para32[0];
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
 			("PORT RESET EVENT, Port: %d ", FromPort));
@@ -4582,176 +4934,187 @@
 		spin_lock_irqsave(
 			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
 			Flags);
-
-		SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
+		if (CHIP_ID_YUKON_2(pAC)) {
+			SkY2PortStop(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
+		} else {
+			SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
+		}
 		pAC->dev[Param.Para32[0]]->flags &= ~IFF_RUNNING;
 		spin_unlock_irqrestore(
 			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
 			Flags);
 		
-		/* clear rx ring from received frames */
-		ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE);
-		
-		ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
+		if (!CHIP_ID_YUKON_2(pAC)) {
+#ifdef CONFIG_SK98LIN_NAPI
+			WorkToDo = 1;
+			ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE, &WorkDone, WorkToDo);
+#else
+			ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE);
+#endif
+			ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
+		}
 		spin_lock_irqsave(
 			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
 			Flags);
 		
-		/* tschilling: Handling of return value inserted. */
-		if (SkGeInitPort(pAC, IoC, FromPort)) {
-			if (FromPort == 0) {
-				printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name);
-			} else {
-				printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name);
+		if (CHIP_ID_YUKON_2(pAC)) {
+			SkY2PortStart(pAC, IoC, FromPort);
+		} else {
+			/* tschilling: Handling of return value inserted. */
+			if (SkGeInitPort(pAC, IoC, FromPort)) {
+				if (FromPort == 0) {
+					printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name);
+				} else {
+					printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name);
+				}
 			}
+			SkAddrMcUpdate(pAC,IoC, FromPort);
+			PortReInitBmu(pAC, FromPort);
+			SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
+			CLEAR_AND_START_RX(FromPort);
 		}
-		SkAddrMcUpdate(pAC,IoC, FromPort);
-		PortReInitBmu(pAC, FromPort);
-		SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
-		ClearAndStartRx(pAC, FromPort);
 		spin_unlock_irqrestore(
 			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
 			Flags);
 		break;
-	case SK_DRV_NET_UP:	 /* SK_U32 PortIdx */
-		/* action list 5 */
+	case SK_DRV_NET_UP:
 		FromPort = Param.Para32[0];
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-			("NET UP EVENT, Port: %d ", Param.Para32[0]));
-		/* Mac update */
-		SkAddrMcUpdate(pAC,IoC, FromPort);
-
+			("NET UP EVENT, Port: %d ", FromPort));
+		SkAddrMcUpdate(pAC,IoC, FromPort); /* Mac update */
 		if (DoPrintInterfaceChange) {
-		printk("%s: network connection up using"
-			" port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]);
+			printk("%s: network connection up using port %c\n",
+				pAC->dev[FromPort]->name, 'A'+FromPort);
 
-		/* tschilling: Values changed according to LinkSpeedUsed. */
-		Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed;
-		if (Stat == SK_LSPEED_STAT_10MBPS) {
-			printk("    speed:           10\n");
-		} else if (Stat == SK_LSPEED_STAT_100MBPS) {
-			printk("    speed:           100\n");
-		} else if (Stat == SK_LSPEED_STAT_1000MBPS) {
-			printk("    speed:           1000\n");
-		} else {
-			printk("    speed:           unknown\n");
-		}
+			/* tschilling: Values changed according to LinkSpeedUsed. */
+			Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed;
+			if (Stat == SK_LSPEED_STAT_10MBPS) {
+				printk("    speed:           10\n");
+			} else if (Stat == SK_LSPEED_STAT_100MBPS) {
+				printk("    speed:           100\n");
+			} else if (Stat == SK_LSPEED_STAT_1000MBPS) {
+				printk("    speed:           1000\n");
+			} else {
+				printk("    speed:           unknown\n");
+			}
 
+			Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
+			if ((Stat == SK_LMODE_STAT_AUTOHALF) ||
+			    (Stat == SK_LMODE_STAT_AUTOFULL)) {
+				printk("    autonegotiation: yes\n");
+			} else {
+				printk("    autonegotiation: no\n");
+			}
 
-		Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
-		if (Stat == SK_LMODE_STAT_AUTOHALF ||
-			Stat == SK_LMODE_STAT_AUTOFULL) {
-			printk("    autonegotiation: yes\n");
-		}
-		else {
-			printk("    autonegotiation: no\n");
-		}
-		if (Stat == SK_LMODE_STAT_AUTOHALF ||
-			Stat == SK_LMODE_STAT_HALF) {
-			printk("    duplex mode:     half\n");
-		}
-		else {
-			printk("    duplex mode:     full\n");
-		}
-		Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus;
-		if (Stat == SK_FLOW_STAT_REM_SEND ) {
-			printk("    flowctrl:        remote send\n");
-		}
-		else if (Stat == SK_FLOW_STAT_LOC_SEND ){
-			printk("    flowctrl:        local send\n");
-		}
-		else if (Stat == SK_FLOW_STAT_SYMMETRIC ){
-			printk("    flowctrl:        symmetric\n");
-		}
-		else {
-			printk("    flowctrl:        none\n");
-		}
-		
-		/* tschilling: Check against CopperType now. */
-		if ((pAC->GIni.GICopperType == SK_TRUE) &&
-			(pAC->GIni.GP[FromPort].PLinkSpeedUsed ==
-			SK_LSPEED_STAT_1000MBPS)) {
-			Stat = pAC->GIni.GP[FromPort].PMSStatus;
-			if (Stat == SK_MS_STAT_MASTER ) {
-				printk("    role:            master\n");
+			if ((Stat == SK_LMODE_STAT_AUTOHALF) ||
+			    (Stat == SK_LMODE_STAT_HALF)) {
+				printk("    duplex mode:     half\n");
+			} else {
+				printk("    duplex mode:     full\n");
 			}
-			else if (Stat == SK_MS_STAT_SLAVE ) {
-				printk("    role:            slave\n");
+
+			Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus;
+			if (Stat == SK_FLOW_STAT_REM_SEND ) {
+				printk("    flowctrl:        remote send\n");
+			} else if (Stat == SK_FLOW_STAT_LOC_SEND ) {
+				printk("    flowctrl:        local send\n");
+			} else if (Stat == SK_FLOW_STAT_SYMMETRIC ) {
+				printk("    flowctrl:        symmetric\n");
+			} else {
+				printk("    flowctrl:        none\n");
 			}
-			else {
-				printk("    role:            ???\n");
+		
+			/* tschilling: Check against CopperType now. */
+			if ((pAC->GIni.GICopperType == SK_TRUE) &&
+				(pAC->GIni.GP[FromPort].PLinkSpeedUsed ==
+				SK_LSPEED_STAT_1000MBPS)) {
+				Stat = pAC->GIni.GP[FromPort].PMSStatus;
+				if (Stat == SK_MS_STAT_MASTER ) {
+					printk("    role:            master\n");
+				} else if (Stat == SK_MS_STAT_SLAVE ) {
+					printk("    role:            slave\n");
+				} else {
+					printk("    role:            ???\n");
+				}
 			}
-		}
 
-		/* 
-		   Display dim (dynamic interrupt moderation) 
-		   informations
-		 */
-		if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC)
-			printk("    irq moderation:  static (%d ints/sec)\n",
+			/* Display interrupt moderation informations */
+			if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) {
+				printk("    irq moderation:  static (%d ints/sec)\n",
 					pAC->DynIrqModInfo.MaxModIntsPerSec);
-		else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC)
-			printk("    irq moderation:  dynamic (%d ints/sec)\n",
+			} else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
+				printk("    irq moderation:  dynamic (%d ints/sec)\n",
 					pAC->DynIrqModInfo.MaxModIntsPerSec);
-		else
-			printk("    irq moderation:  disabled\n");
+			} else {
+				printk("    irq moderation:  disabled\n");
+			}
+	
+#ifdef NETIF_F_TSO
+			if (CHIP_ID_YUKON_2(pAC)) {
+				if (pAC->dev[FromPort]->features & NETIF_F_TSO) {
+					printk("    tcp offload:     enabled\n");
+				} else {
+					printk("    tcp offload:     disabled\n");
+				}
+			}
+#endif
 
+			if (pAC->dev[FromPort]->features & NETIF_F_SG) {
+				printk("    scatter-gather:  enabled\n");
+			} else {
+				printk("    scatter-gather:  disabled\n");
+			}
 
-#ifdef SK_ZEROCOPY
-		if (pAC->ChipsetType)
-#ifdef USE_SK_TX_CHECKSUM
-			printk("    scatter-gather:  enabled\n");
-#else
-			printk("    tx-checksum:     disabled\n");
-#endif
-		else
-			printk("    scatter-gather:  disabled\n");
-#else
-			printk("    scatter-gather:  disabled\n");
-#endif
+			if (pAC->dev[FromPort]->features & NETIF_F_IP_CSUM) {
+				printk("    tx-checksum:     enabled\n");
+			} else {
+				printk("    tx-checksum:     disabled\n");
+			}
 
-#ifndef USE_SK_RX_CHECKSUM
-			printk("    rx-checksum:     disabled\n");
+			if (pAC->RxPort[FromPort].UseRxCsum) {
+				printk("    rx-checksum:     enabled\n");
+			} else {
+				printk("    rx-checksum:     disabled\n");
+			}
+#ifdef CONFIG_SK98LIN_NAPI
+			printk("    rx-polling:      enabled\n");
 #endif
-
 		} else {
-                        DoPrintInterfaceChange = SK_TRUE;
-                }
+			DoPrintInterfaceChange = SK_TRUE;
+		}
 	
-		if ((Param.Para32[0] != pAC->ActivePort) &&
-			(pAC->RlmtNets == 1)) {
+		if ((FromPort != pAC->ActivePort)&&(pAC->RlmtNets == 1)) {
 			NewPara.Para32[0] = pAC->ActivePort;
-			NewPara.Para32[1] = Param.Para32[0];
-			SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN,
-				NewPara);
+			NewPara.Para32[1] = FromPort;
+			SkEventQueue(pAC,SKGE_DRV,SK_DRV_SWITCH_INTERN,NewPara);
 		}
 
 		/* Inform the world that link protocol is up. */
-		pAC->dev[Param.Para32[0]]->flags |= IFF_RUNNING;
-
+		netif_wake_queue(pAC->dev[0]);
+		pAC->dev[FromPort]->flags |= IFF_RUNNING;
 		break;
-	case SK_DRV_NET_DOWN:	 /* SK_U32 Reason */
-		/* action list 7 */
+	case SK_DRV_NET_DOWN:	
+		Reason   = Param.Para32[0];
+		FromPort = Param.Para32[1];
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
 			("NET DOWN EVENT "));
 		if (DoPrintInterfaceChange) {
-			printk("%s: network connection down\n", 
-				pAC->dev[Param.Para32[1]]->name);
+			if (pAC->dev[FromPort]->flags & IFF_RUNNING) {
+				printk("%s: network connection down\n", 
+					pAC->dev[FromPort]->name);
+			}
 		} else {
 			DoPrintInterfaceChange = SK_TRUE;
 		}
-		pAC->dev[Param.Para32[1]]->flags &= ~IFF_RUNNING;
+		pAC->dev[FromPort]->flags &= ~IFF_RUNNING;
 		break;
-	case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
-		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-			("PORT SWITCH HARD "));
-	case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
-	/* action list 6 */
-		printk("%s: switching to port %c\n", pAC->dev[0]->name,
-			'A'+Param.Para32[1]);
-	case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
+	case SK_DRV_SWITCH_HARD:   /* FALL THRU */
+	case SK_DRV_SWITCH_SOFT:   /* FALL THRU */
+	case SK_DRV_SWITCH_INTERN: 
 		FromPort = Param.Para32[0];
-		ToPort = Param.Para32[1];
+		ToPort   = Param.Para32[1];
+		printk("%s: switching from port %c to port %c\n",
+			pAC->dev[0]->name, 'A'+FromPort, 'A'+ToPort);
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
 			("PORT SWITCH EVENT, From: %d  To: %d (Pref %d) ",
 			FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort));
@@ -4762,26 +5125,38 @@
 		spin_lock_irqsave(
 			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
 			Flags);
-		spin_lock_irqsave(
-			&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
-		SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
-		SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST);
-		spin_unlock_irqrestore(
-			&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
+		spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
+		if (CHIP_ID_YUKON_2(pAC)) {
+			SkY2PortStop(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
+			SkY2PortStop(pAC, IoC, ToPort, SK_STOP_ALL, SK_HARD_RST);
+		}
+		else {
+			SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
+			SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST);
+		}
+		spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
 		spin_unlock_irqrestore(
 			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
 			Flags);
 
-		ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */
-		ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */
 		
-		ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
-		ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]);
+		if (!CHIP_ID_YUKON_2(pAC)) {
+#ifdef CONFIG_SK98LIN_NAPI
+			WorkToDo = 1;
+			ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE, &WorkDone, WorkToDo);
+			ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE, &WorkDone, WorkToDo);
+#else
+			ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */
+			ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */
+#endif
+			ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
+			ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]);
+		} 
+
 		spin_lock_irqsave(
 			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
 			Flags);
-		spin_lock_irqsave(
-			&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
+		spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
 		pAC->ActivePort = ToPort;
 #if 0
 		SetQueueSizes(pAC);
@@ -4796,8 +5171,7 @@
 			pAC,
 			pAC->ActivePort,
 			DualNet)) {
-			spin_unlock_irqrestore(
-				&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
+			spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
 			spin_unlock_irqrestore(
 				&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
 				Flags);
@@ -4805,62 +5179,59 @@
 			break;
 		}
 #endif
-		/* tschilling: Handling of return values inserted. */
-		if (SkGeInitPort(pAC, IoC, FromPort) ||
-			SkGeInitPort(pAC, IoC, ToPort)) {
-			printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name);
+		if (!CHIP_ID_YUKON_2(pAC)) {
+			/* tschilling: Handling of return values inserted. */
+			if (SkGeInitPort(pAC, IoC, FromPort) ||
+				SkGeInitPort(pAC, IoC, ToPort)) {
+				printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name);
+			}
 		}
 		if (Event == SK_DRV_SWITCH_SOFT) {
 			SkMacRxTxEnable(pAC, IoC, FromPort);
 		}
+
 		SkMacRxTxEnable(pAC, IoC, ToPort);
 		SkAddrSwap(pAC, IoC, FromPort, ToPort);
 		SkAddrMcUpdate(pAC, IoC, FromPort);
 		SkAddrMcUpdate(pAC, IoC, ToPort);
-		PortReInitBmu(pAC, FromPort);
-		PortReInitBmu(pAC, ToPort);
-		SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
-		SkGePollTxD(pAC, IoC, ToPort, SK_TRUE);
-		ClearAndStartRx(pAC, FromPort);
-		ClearAndStartRx(pAC, ToPort);
-		spin_unlock_irqrestore(
-			&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags);
+
+		if (!CHIP_ID_YUKON_2(pAC)) {
+			PortReInitBmu(pAC, FromPort);
+			PortReInitBmu(pAC, ToPort);
+			SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
+			SkGePollTxD(pAC, IoC, ToPort, SK_TRUE);
+			CLEAR_AND_START_RX(FromPort);
+			CLEAR_AND_START_RX(ToPort);
+		} else {
+			SkY2PortStart(pAC, IoC, FromPort);
+			SkY2PortStart(pAC, IoC, ToPort);
+		}
+		spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
 		spin_unlock_irqrestore(
 			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
 			Flags);
 		break;
 	case SK_DRV_RLMT_SEND:	 /* SK_MBUF *pMb */
-		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
-			("RLS "));
+		SK_DBG_MSG(NULL,SK_DBGMOD_DRV,SK_DBGCAT_DRV_EVENT,("RLS "));
 		pRlmtMbuf = (SK_MBUF*) Param.pParaPtr;
 		pMsg = (struct sk_buff*) pRlmtMbuf->pOs;
 		skb_put(pMsg, pRlmtMbuf->Length);
-		if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW],
-			pMsg) < 0)
-
-			DEV_KFREE_SKB_ANY(pMsg);
+		if (!CHIP_ID_YUKON_2(pAC)) {
+			if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW],
+				pMsg) < 0) {
+				DEV_KFREE_SKB_ANY(pMsg);
+			}
+		} else {
+			if (SkY2RlmtSend(pAC, pRlmtMbuf->PortIdx, pMsg) < 0) {
+				DEV_KFREE_SKB_ANY(pMsg);
+			}
+		}
 		break;
 	case SK_DRV_TIMER:
 		if (Param.Para32[0] == SK_DRV_MODERATION_TIMER) {
-			/*
-			** expiration of the moderation timer implies that
-			** dynamic moderation is to be applied
-			*/
+			/* check what IRQs are to be moderated */
 			SkDimStartModerationTimer(pAC);
 			SkDimModerate(pAC);
-                        if (pAC->DynIrqModInfo.DisplayStats) {
-			    SkDimDisplayModerationSettings(pAC);
-                        }
-                } else if (Param.Para32[0] == SK_DRV_RX_CLEANUP_TIMER) {
-			/*
-			** check if we need to check for descriptors which
-			** haven't been handled the last millisecs
-			*/
-			StartDrvCleanupTimer(pAC);
-			if (pAC->GIni.GIMacsFound == 2) {
-				ReceiveIrq(pAC, &pAC->RxPort[1], SK_FALSE);
-			}
-			ReceiveIrq(pAC, &pAC->RxPort[0], SK_FALSE);
 		} else {
 			printk("Expiration of unknown timer\n");
 		}
@@ -4924,8 +5295,6 @@
 
 } /* SkErrorLog */
 
-#ifdef SK_DIAG_SUPPORT
-
 /*****************************************************************************
  *
  *	SkDrvEnterDiagMode - handles DIAG attach request
@@ -4993,16 +5362,16 @@
 			sizeof(SK_PNMI_STRUCT_DATA));
 	pAc->DiagModeActive    = DIAG_NOTACTIVE;
 	pAc->Pnmi.DiagAttached = SK_DIAG_IDLE;
-        if (pAc->WasIfUp[0] == SK_TRUE) {
-                pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
+	if (pAc->WasIfUp[0] == SK_TRUE) {
+		pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
 		DoPrintInterfaceChange = SK_FALSE;
-                SkDrvInitAdapter(pAc, 0);    /* first device  */
-        }
-        if (pAc->WasIfUp[1] == SK_TRUE) {
-                pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
+		SkDrvInitAdapter(pAc, 0);    /* first device  */
+	}
+	if (pAc->WasIfUp[1] == SK_TRUE) {
+		pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
 		DoPrintInterfaceChange = SK_FALSE;
-                SkDrvInitAdapter(pAc, 1);    /* second device */
-        }
+		SkDrvInitAdapter(pAc, 1);    /* second device */
+	}
 	return(0);
 }
 
@@ -5145,14 +5514,25 @@
 
 } /* SkDrvInitAdapter */
 
-#endif
+static int __init sk98lin_init(void)
+{
+	return pci_module_init(&sk98lin_driver);
+}
+
+static void __exit sk98lin_cleanup(void)
+{
+	pci_unregister_driver(&sk98lin_driver);
+}
+
+module_init(sk98lin_init);
+module_exit(sk98lin_cleanup);
+
 
 #ifdef DEBUG
 /****************************************************************************/
 /* "debug only" section *****************************************************/
 /****************************************************************************/
 
-
 /*****************************************************************************
  *
  *	DumpMsg - print a frame
@@ -5163,9 +5543,11 @@
  * Returns: N/A
  *	
  */
-static void DumpMsg(struct sk_buff *skb, char *str)
+static void DumpMsg(
+struct sk_buff *skb,  /* linux' socket buffer  */
+char           *str)  /* additional msg string */
 {
-	int	msglen;
+	int msglen = (skb->len > 64) ? 64 : skb->len;
 
 	if (skb == NULL) {
 		printk("DumpMsg(): NULL-Message\n");
@@ -5177,19 +5559,14 @@
 		return;
 	}
 
-	msglen = skb->len;
-	if (msglen > 64)
-		msglen = 64;
-
-	printk("--- Begin of message from %s , len %d (from %d) ----\n", str, msglen, skb->len);
-
+	printk("DumpMsg: PhysPage: %p\n", 
+		page_address(virt_to_page(skb->data)));
+	printk("--- Begin of message from %s , len %d (from %d) ----\n", 
+		str, msglen, skb->len);
 	DumpData((char *)skb->data, msglen);
-
 	printk("------- End of message ---------\n");
 } /* DumpMsg */
 
-
-
 /*****************************************************************************
  *
  *	DumpData - print a data area
@@ -5201,23 +5578,22 @@
  * Returns: N/A
  *	
  */
-static void DumpData(char *p, int size)
-{
-register int    i;
-int	haddr, addr;
-char	hex_buffer[180];
-char	asc_buffer[180];
-char	HEXCHAR[] = "0123456789ABCDEF";
-
-	addr = 0;
-	haddr = 0;
-	hex_buffer[0] = 0;
-	asc_buffer[0] = 0;
+static void DumpData(
+char  *p,     /* pointer to area containing the data */
+int    size)  /* the size of that data area in bytes */
+{
+	register int  i;
+	int           haddr = 0, addr = 0;
+	char          hex_buffer[180] = { '\0' };
+	char          asc_buffer[180] = { '\0' };
+	char          HEXCHAR[] = "0123456789ABCDEF";
+
 	for (i=0; i < size; ) {
-		if (*p >= '0' && *p <='z')
+		if (*p >= '0' && *p <='z') {
 			asc_buffer[addr] = *p;
-		else
+		} else {
 			asc_buffer[addr] = '.';
+		}
 		addr++;
 		asc_buffer[addr] = 0;
 		hex_buffer[haddr] = HEXCHAR[(*p & 0xf0) >> 4];
@@ -5243,27 +5619,24 @@
  *	DumpLong - print a data area as long values
  *
  * Description:
- *	This function prints a area of data to the system logfile/to the
+ *	This function prints a long variable to the system logfile/to the
  *	console.
  *
  * Returns: N/A
  *	
  */
-static void DumpLong(char *pc, int size)
-{
-register int    i;
-int	haddr, addr;
-char	hex_buffer[180];
-char	asc_buffer[180];
-char	HEXCHAR[] = "0123456789ABCDEF";
-long	*p;
-int	l;
-
-	addr = 0;
-	haddr = 0;
-	hex_buffer[0] = 0;
-	asc_buffer[0] = 0;
-	p = (long*) pc;
+static void DumpLong(
+char  *pc,    /* location of the variable to print */
+int    size)  /* how large is the variable?        */
+{
+	register int   i;
+	int            haddr = 0, addr = 0;
+	char           hex_buffer[180] = { '\0' };
+	char           asc_buffer[180] = { '\0' };
+	char           HEXCHAR[] = "0123456789ABCDEF";
+	long          *p = (long*) pc;
+	int            l;
+
 	for (i=0; i < size; ) {
 		l = (long) *p;
 		hex_buffer[haddr] = HEXCHAR[(l >> 28) & 0xf];
diff -urN linux-2.4.29/drivers/net/sk98lin/skgehwt.c linux-2.4.29-uc1/drivers/net/sk98lin/skgehwt.c
--- linux-2.4.29/drivers/net/sk98lin/skgehwt.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/skgehwt.c	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skgehwt.c
  * Project:	Gigabit Ethernet Adapters, Event Scheduler Module
+ * Version:	$Revision: 2.2 $
+ * Date:	$Date: 2004/05/28 13:39:04 $
  * Purpose:	Hardware Timer
  *
  ******************************************************************************/
@@ -9,7 +11,7 @@
 /******************************************************************************
  *
  *	(C)Copyright 1998-2002 SysKonnect GmbH.
- *	(C)Copyright 2002-2003 Marvell.
+ *	(C)Copyright 2002-2004 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -25,7 +27,7 @@
  */
 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skgehwt.c,v 1.15 2003/09/16 13:41:23 rschmidt Exp $ (C) Marvell.";
+	"@(#) $Id: skgehwt.c,v 2.2 2004/05/28 13:39:04 rschmidt Exp $ (C) Marvell.";
 #endif
 
 #include "h/skdrv1st.h"		/* Driver Specific Definitions */
@@ -42,10 +44,10 @@
 /*
  * Prototypes of local functions.
  */
-#define	SK_HWT_MAX	(65000)
+#define	SK_HWT_MAX	65000UL * 160		/* ca. 10 sec. */
 
 /* correction factor */
-#define	SK_HWT_FAC	(1000 * (SK_U32)pAC->GIni.GIHstClkFact / 100)
+#define	SK_HWT_FAC	(10 * (SK_U32)pAC->GIni.GIHstClkFact / 16)
 
 /*
  * Initialize hardware timer.
@@ -71,29 +73,21 @@
 void	SkHwtStart(
 SK_AC	*pAC,	/* Adapters context */
 SK_IOC	Ioc,	/* IoContext */
-SK_U32	Time)	/* Time in units of 16us to load the timer with. */
+SK_U32	Time)	/* Time in usec to load the timer */
 {
-	SK_U32	Cnt;
-
 	if (Time > SK_HWT_MAX)
 		Time = SK_HWT_MAX;
 
 	pAC->Hwt.TStart = Time;
 	pAC->Hwt.TStop = 0L;
 
-	Cnt = Time;
-
-	/*
-	 * if time < 16 us
-	 *	time = 16 us
-	 */
-	if (!Cnt) {
-		Cnt++;
+	if (!Time) {
+		Time = 1L;
 	}
 
-	SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC);
-	
-	SK_OUT16(Ioc, B2_TI_CTRL, TIM_START);	/* Start timer. */
+	SK_OUT32(Ioc, B2_TI_INI, Time * SK_HWT_FAC);
+
+	SK_OUT16(Ioc, B2_TI_CTRL, TIM_START);	/* Start timer */
 
 	pAC->Hwt.TActive = SK_TRUE;
 }
@@ -107,13 +101,12 @@
 SK_IOC	Ioc)	/* IoContext */
 {
 	SK_OUT16(Ioc, B2_TI_CTRL, TIM_STOP);
-	
+
 	SK_OUT16(Ioc, B2_TI_CTRL, TIM_CLR_IRQ);
 
 	pAC->Hwt.TActive = SK_FALSE;
 }
 
-
 /*
  *	Stop hardware timer and read time elapsed since last start.
  *
@@ -127,6 +120,9 @@
 {
 	SK_U32	TRead;
 	SK_U32	IStatus;
+	SK_U32	TimerInt;
+
+	TimerInt = CHIP_ID_YUKON_2(pAC) ? Y2_IS_TIMINT : IS_TIMINT;
 
 	if (pAC->Hwt.TActive) {
 		
@@ -137,15 +133,15 @@
 
 		SK_IN32(Ioc, B0_ISRC, &IStatus);
 
-		/* Check if timer expired (or wraped around) */
-		if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) {
-			
+		/* Check if timer expired (or wrapped around) */
+		if ((TRead > pAC->Hwt.TStart) || ((IStatus & TimerInt) != 0)) {
+
 			SkHwtStop(pAC, Ioc);
-			
+
 			pAC->Hwt.TStop = pAC->Hwt.TStart;
 		}
 		else {
-			
+
 			pAC->Hwt.TStop = pAC->Hwt.TStart - TRead;
 		}
 	}
@@ -160,9 +156,9 @@
 SK_IOC	Ioc)	/* IoContext */
 {
 	SkHwtStop(pAC, Ioc);
-	
+
 	pAC->Hwt.TStop = pAC->Hwt.TStart;
-	
+
 	SkTimerDone(pAC, Ioc);
 }
 
diff -urN linux-2.4.29/drivers/net/sk98lin/skgeinit.c linux-2.4.29-uc1/drivers/net/sk98lin/skgeinit.c
--- linux-2.4.29/drivers/net/sk98lin/skgeinit.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/skgeinit.c	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skgeinit.c
  * Project:	Gigabit Ethernet Adapters, Common Modules
+ * Version:	$Revision: 2.56 $
+ * Date:	$Date: 2004/08/13 09:38:27 $
  * Purpose:	Contains functions to initialize the adapter
  *
  ******************************************************************************/
@@ -9,18 +11,16 @@
 /******************************************************************************
  *
  *	(C)Copyright 1998-2002 SysKonnect.
- *	(C)Copyright 2002-2003 Marvell.
+ *	(C)Copyright 2002-2004 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
  *	the Free Software Foundation; either version 2 of the License, or
  *	(at your option) any later version.
- *
  *	The information in this file is provided "AS IS" without warranty.
  *
  ******************************************************************************/
 
-
 #include "h/skdrv1st.h"
 #include "h/skdrv2nd.h"
 
@@ -30,7 +30,7 @@
 
 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skgeinit.c,v 1.97 2003/10/02 16:45:31 rschmidt Exp $ (C) Marvell.";
+	"@(#) $Id: skgeinit.c,v 2.56 2004/08/13 09:38:27 rschmidt Exp $ (C) Marvell.";
 #endif
 
 struct s_QOffTab {
@@ -58,6 +58,101 @@
 
 /******************************************************************************
  *
+ *	SkGePortVlan() -	Enable / Disable VLAN support
+ *
+ * Description:
+ *	Enable or disable the VLAN support of the selected port.
+ *	The new configuration is *not* saved over any SkGeStopPort() and
+ *	SkGeInitPort() calls.
+ *	Currently this function is only supported on Yukon-2/EC adapters.
+ *
+ * Returns:
+ *	nothing
+ */
+void SkGePortVlan(
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
+int		Port,	/* Port number */
+SK_BOOL	Enable)	/* Flag */
+{
+	if (CHIP_ID_YUKON_2(pAC)) {
+		if (Enable) {
+			SK_OUT32(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON);
+			SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
+		}
+		else {
+			SK_OUT32(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF);
+			SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
+		}
+	}
+}
+
+
+/******************************************************************************
+ *
+ *	SkGeRxRss() -	Enable / Disable RSS Hash Calculation
+ *
+ * Description:
+ *	Enable or disable the RSS hash calculation of the selected port.
+ *	The new configuration is *not* saved over any SkGeStopPort() and
+ *	SkGeInitPort() calls.
+ *	Currently this function is only supported on Yukon-2/EC adapters.
+ *
+ * Returns:
+ *	nothing
+ */
+void SkGeRxRss(
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
+int		Port,	/* Port number */
+SK_BOOL	Enable)	/* Flag */
+{
+	if (CHIP_ID_YUKON_2(pAC)) {
+		if (Enable) {
+			SK_OUT32(IoC, Q_ADDR(pAC->GIni.GP[Port].PRxQOff, Q_CSR),
+				BMU_ENA_RX_RSS_HASH);
+		}
+		else {
+			SK_OUT32(IoC, Q_ADDR(pAC->GIni.GP[Port].PRxQOff, Q_CSR),
+				BMU_DIS_RX_RSS_HASH);
+		}
+	}
+}
+
+/******************************************************************************
+ *
+ *	SkGeRxCsum() -	Enable / Disable Receive Checksum
+ *
+ * Description:
+ *	Enable or disable the checksum of the selected port.
+ *	The new configuration is *not* saved over any SkGeStopPort() and
+ *	SkGeInitPort() calls.
+ *	Currently this function is only supported on Yukon-2/EC adapters.
+ *
+ * Returns:
+ *	nothing
+ */
+void SkGeRxCsum(
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
+int		Port,	/* Port number */
+SK_BOOL	Enable)	/* Flag */
+{
+	if (CHIP_ID_YUKON_2(pAC)) {
+		if (Enable) {
+			SK_OUT32(IoC, Q_ADDR(pAC->GIni.GP[Port].PRxQOff, Q_CSR),
+				BMU_ENA_RX_CHKSUM);
+		}
+		else {
+			SK_OUT32(IoC, Q_ADDR(pAC->GIni.GP[Port].PRxQOff, Q_CSR),
+				BMU_DIS_RX_CHKSUM);
+		}
+	}
+}
+
+
+/******************************************************************************
+ *
  *	SkGePollRxD() - Enable / Disable Descriptor Polling of RxD Ring
  *
  * Description:
@@ -70,8 +165,8 @@
  *	nothing
  */
 void SkGePollRxD(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL PollRxD)	/* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
 {
@@ -79,8 +174,8 @@
 
 	pPrt = &pAC->GIni.GP[Port];
 
-	SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), (PollRxD) ?
-		CSR_ENA_POL : CSR_DIS_POL);
+	SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), (SK_U32)((PollRxD) ?
+		CSR_ENA_POL : CSR_DIS_POL));
 }	/* SkGePollRxD */
 
 
@@ -98,8 +193,8 @@
  *	nothing
  */
 void SkGePollTxD(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL PollTxD)	/* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
 {
@@ -113,7 +208,7 @@
 	if (pPrt->PXSQSize != 0) {
 		SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord);
 	}
-	
+
 	if (pPrt->PXAQSize != 0) {
 		SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord);
 	}
@@ -134,8 +229,8 @@
  *	nothing
  */
 void SkGeYellowLED(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		State)		/* yellow LED state, 0 = OFF, 0 != ON */
 {
 	if (State == 0) {
@@ -168,8 +263,8 @@
  *	nothing
  */
 void SkGeXmitLED(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Led,		/* offset to the LED Init Value register */
 int		Mode)		/* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */
 {
@@ -196,7 +291,7 @@
 		SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_OFF);
 		break;
 	}
-			
+
 	/*
 	 * 1000BT: The Transmit LED is driven by the PHY.
 	 * But the default LED configuration is used for
@@ -226,7 +321,7 @@
  *	1:	configuration error
  */
 static int DoCalcAddr(
-SK_AC		*pAC, 				/* adapter context */
+SK_AC		*pAC, 				/* Adapter Context */
 SK_GEPORT	SK_FAR *pPrt,		/* port index */
 int			QuSize,				/* size of the queue to configure in kB */
 SK_U32		SK_FAR *StartVal,	/* start value for address calculation */
@@ -263,12 +358,40 @@
 
 /******************************************************************************
  *
+ *	SkGeRoundQueueSize() - Round the given queue size to the adpaters QZ units
+ *
+ * Description:
+ *	This function rounds the given queue size in kBs to adapter specific
+ *	queue size units (Genesis and Yukon: 8kB, Yukon-2/EC 1kB).
+ *
+ * Returns:
+ *	the rounded queue size in kB	
+ */
+static int SkGeRoundQueueSize(
+SK_AC	*pAC,		/* Adapter Context */
+int	QueueSizeKB)	/* Queue size in kB */
+{
+	int QueueSizeSteps;
+
+	if (CHIP_ID_YUKON_2(pAC)) {
+		QueueSizeSteps = QZ_STEP_Y2;
+	}
+	else {
+		QueueSizeSteps = QZ_STEP;
+	}
+
+	return ((QueueSizeKB + QueueSizeSteps-1) & ~(QueueSizeSteps-1));
+}	/* SkGeRoundQueueSize */
+
+
+/******************************************************************************
+ *
  *	SkGeInitAssignRamToQueues() - allocate default queue sizes
  *
  * Description:
  *	This function assigns the memory to the different queues and ports.
  *	When DualNet is set to SK_TRUE all ports get the same amount of memory.
- *  Otherwise the first port gets most of the memory and all the
+ *	Otherwise the first port gets most of the memory and all the
  *	other ports just the required minimum.
  *	This function can only be called when pAC->GIni.GIRamSize and
  *	pAC->GIni.GIMacsFound have been initialized, usually this happens
@@ -281,28 +404,38 @@
  */
 
 int SkGeInitAssignRamToQueues(
-SK_AC	*pAC,			/* Adapter context */
+SK_AC	*pAC,			/* Adapter Context */
 int		ActivePort,		/* Active Port in RLMT mode */
-SK_BOOL	DualNet)		/* adapter context */
+SK_BOOL	DualNet)		/* Dual Net active */
 {
 	int	i;
 	int	UsedKilobytes;			/* memory already assigned */
 	int	ActivePortKilobytes;	/* memory available for active port */
+	int MinQueueSize;			/* min. memory for queues */
 	SK_GEPORT *pGePort;
 
 	UsedKilobytes = 0;
 
 	if (ActivePort >= pAC->GIni.GIMacsFound) {
+
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
 			("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n",
 			ActivePort));
 		return(1);
 	}
-	if (((pAC->GIni.GIMacsFound * (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE)) +
-		((RAM_QUOTA_SYNC == 0) ? 0 : SK_MIN_TXQ_SIZE)) > pAC->GIni.GIRamSize) {
+
+	MinQueueSize = SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE;
+
+	if (MinQueueSize > pAC->GIni.GIRamSize) {
+		MinQueueSize = pAC->GIni.GIRamSize;
+	}
+
+	if ((pAC->GIni.GIMacsFound * MinQueueSize +
+		 RAM_QUOTA_SYNC * SK_MIN_TXQ_SIZE) > pAC->GIni.GIRamSize) {
+
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
 			("SkGeInitAssignRamToQueues: Not enough memory (%d)\n",
-			 pAC->GIni.GIRamSize));
+			pAC->GIni.GIRamSize));
 		return(2);
 	}
 
@@ -312,13 +445,13 @@
 		for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
 
 			pGePort = &pAC->GIni.GP[i];
-			
+
 			/* take away the minimum memory for active queues */
-			ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
+			ActivePortKilobytes -= MinQueueSize;
 
 			/* receive queue gets the minimum + 80% of the rest */
-			pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((
-				ActivePortKilobytes * (unsigned long) RAM_QUOTA_RX) / 100))
+			pGePort->PRxQSize = SkGeRoundQueueSize(pAC,
+				(int)((long)ActivePortKilobytes * RAM_QUOTA_RX) / 100)
 				+ SK_MIN_RXQ_SIZE;
 
 			ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
@@ -327,11 +460,11 @@
 			pGePort->PXSQSize = 0;
 
 			/* asynchronous transmit queue */
-			pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes +
-				SK_MIN_TXQ_SIZE);
+			pGePort->PXAQSize = SkGeRoundQueueSize(pAC,
+				ActivePortKilobytes + SK_MIN_TXQ_SIZE);
 		}
 	}
-	else {	
+	else {
 		/* Rlmt Mode or single link adapter */
 
 		/* Set standby queue size defaults for all standby ports */
@@ -353,30 +486,28 @@
 
 		/* assign it to the active port */
 		/* first take away the minimum memory */
-		ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
+		ActivePortKilobytes -= MinQueueSize;
 		pGePort = &pAC->GIni.GP[ActivePort];
 
 		/* receive queue get's the minimum + 80% of the rest */
-		pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((ActivePortKilobytes *
-			(unsigned long) RAM_QUOTA_RX) / 100)) + SK_MIN_RXQ_SIZE;
+		pGePort->PRxQSize = SkGeRoundQueueSize(pAC,
+			(int)((long)ActivePortKilobytes * RAM_QUOTA_RX) / 100) +
+			MinQueueSize/2;
 
-		ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
+		ActivePortKilobytes -= (pGePort->PRxQSize - MinQueueSize/2);
 
 		/* synchronous transmit queue */
 		pGePort->PXSQSize = 0;
 
 		/* asynchronous transmit queue */
-		pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes) +
-			SK_MIN_TXQ_SIZE;
+		pGePort->PXAQSize = SkGeRoundQueueSize(pAC, ActivePortKilobytes) +
+			MinQueueSize/2;
 	}
-#ifdef VCPU
-	VCPUprintf(0, "PRxQSize=%u, PXSQSize=%u, PXAQSize=%u\n",
-		pGePort->PRxQSize, pGePort->PXSQSize, pGePort->PXAQSize);
-#endif /* VCPU */
 
 	return(0);
 }	/* SkGeInitAssignRamToQueues */
 
+
 /******************************************************************************
  *
  *	SkGeCheckQSize() - Checks the Adapters Queue Size Configuration
@@ -387,12 +518,12 @@
  *	used ports.
  *	This requirements must be fullfilled to have a valid configuration:
  *		- The size of all queues must not exceed GIRamSize.
- *		- The queue sizes must be specified in units of 8 kB.
+ *		- The queue sizes must be specified in units of 8 kB (Genesis & Yukon).
  *		- The size of Rx queues of available ports must not be
- *		  smaller than 16 kB.
+ *		  smaller than 16 kB (Genesis & Yukon) resp. 10 kB (Yukon-2).
  *		- The size of at least one Tx queue (synch. or asynch.)
- *        of available ports must not be smaller than 16 kB
- *        when Jumbo Frames are used.
+ *		  of available ports must not be smaller than 16 kB (Genesis & Yukon),
+ *		  resp. 10 kB (Yukon-2) when Jumbo Frames are used.
  *		- The RAM start and end addresses must not be changed
  *		  for ports which are already initialized.
  *	Furthermore SkGeCheckQSize() defines the Start and End Addresses
@@ -403,7 +534,7 @@
  *	1:	Queue Size Configuration invalid
  */
 static int SkGeCheckQSize(
-SK_AC	 *pAC,		/* adapter context */
+SK_AC	 *pAC,		/* Adapter Context */
 int		 Port)		/* port index */
 {
 	SK_GEPORT *pPrt;
@@ -413,44 +544,51 @@
 	SK_U32	StartAddr;
 #ifndef SK_SLIM
 	int	UsedMem;	/* total memory used (max. found ports) */
-#endif	
+#endif
 
 	Rtv = 0;
-	
+
 #ifndef SK_SLIM
 
 	UsedMem = 0;
+	Rtv = 0;
 	for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
 		pPrt = &pAC->GIni.GP[i];
 
-		if ((pPrt->PRxQSize & QZ_UNITS) != 0 ||
-			(pPrt->PXSQSize & QZ_UNITS) != 0 ||
-			(pPrt->PXAQSize & QZ_UNITS) != 0) {
+		if (CHIP_ID_YUKON_2(pAC)) {
+			UsedMem = 0;
+		}
+		else if (((pPrt->PRxQSize & QZ_UNITS) != 0 ||
+				  (pPrt->PXSQSize & QZ_UNITS) != 0 ||
+				  (pPrt->PXAQSize & QZ_UNITS) != 0)) {
 
 			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
 			return(1);
 		}
 
-		if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) {
+#ifndef SK_DIAG
+		if (i == Port && pAC->GIni.GIRamSize > SK_MIN_RXQ_SIZE &&
+			pPrt->PRxQSize < SK_MIN_RXQ_SIZE) {
 			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG);
 			return(1);
 		}
-		
+
 		/*
 		 * the size of at least one Tx queue (synch. or asynch.) has to be > 0.
 		 * if Jumbo Frames are used, this size has to be >= 16 kB.
 		 */
 		if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) ||
 			(pAC->GIni.GIPortUsage == SK_JUMBO_LINK &&
-            ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) ||
+			((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) ||
 			 (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) {
 				SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG);
 				return(1);
 		}
-		
+#endif /* !SK_DIAG */
+
 		UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize;
 	}
-	
+
 	if (UsedMem > pAC->GIni.GIRamSize) {
 		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
 		return(1);
@@ -462,6 +600,14 @@
 	for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
 		pPrt = &pAC->GIni.GP[i];
 
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+			("Port %d: RxQSize=%u, TxAQSize=%u, TxSQSize=%u\n",
+			i, pPrt->PRxQSize, pPrt->PXAQSize, pPrt->PXSQSize));
+
+		if (CHIP_ID_YUKON_2(pAC)) {
+			StartAddr = 0;
+		}
+
 		/* Calculate/Check values for the receive queue */
 		Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PRxQSize, &StartAddr,
 			&pPrt->PRxQRamStart, &pPrt->PRxQRamEnd);
@@ -501,8 +647,8 @@
  *	nothing
  */
 static void SkGeInitMacArb(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC)		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC)		/* I/O Context */
 {
 	/* release local reset */
 	SK_OUT16(IoC, B3_MA_TO_CTRL, MA_RST_CLR);
@@ -541,8 +687,8 @@
  *	nothing
  */
 static void SkGeInitPktArb(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC)		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC)		/* I/O Context */
 {
 	/* release local reset */
 	SK_OUT16(IoC, B3_PA_CTRL, PA_RST_CLR);
@@ -581,14 +727,11 @@
  *	nothing
  */
 static void SkGeInitMacFifo(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_U16	Word;
-#ifdef VCPU
-	SK_U32	DWord;
-#endif /* VCPU */
 	/*
 	 * For each FIFO:
 	 *	- release local reset
@@ -596,31 +739,29 @@
 	 *	- setup defaults for the control register
 	 *	- enable the FIFO
 	 */
-	
+
 #ifdef GENESIS
 	if (pAC->GIni.GIGenesis) {
 		/* Configure Rx MAC FIFO */
 		SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR);
 		SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF);
 		SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD);
-	
+
 		/* Configure Tx MAC FIFO */
 		SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR);
 		SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
 		SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
-	
+
 		/* Enable frame flushing if jumbo frames used */
 		if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
 			SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH);
 		}
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
-		/* set Rx GMAC FIFO Flush Mask */
-		SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK);
-		
+
 		Word = (SK_U16)GMF_RX_CTRL_DEF;
 
 		/* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */
@@ -628,23 +769,27 @@
 
 			Word &= ~GMF_RX_F_FL_ON;
 		}
-		
-		/* Configure Rx MAC FIFO */
+
+		/* Configure Rx GMAC FIFO */
 		SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
 		SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word);
-		
-		/* set Rx GMAC FIFO Flush Threshold (default: 0x0a -> 56 bytes) */
-		SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
-		
-		/* Configure Tx MAC FIFO */
+
+		/* set Rx GMAC FIFO Flush Mask (after clearing reset) */
+		SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK);
+
+		Word = (SK_U16)RX_GMF_FL_THR_DEF;	/* default: 0x0a -> 56 bytes) */
+
+		if (pAC->GIni.GIAsfEnabled) {
+			Word -= 2;						/* for ASF: 0x08 -> 40 bytes) */
+		}
+
+		/* set Rx GMAC FIFO Flush Threshold (after clearing reset) */
+		SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), Word);
+
+		/* Configure Tx GMAC FIFO */
 		SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
 		SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF);
-		
-#ifdef VCPU
-		SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord);
-		SK_IN32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), &DWord);
-#endif /* VCPU */
-		
+
 		/* set Tx GMAC FIFO Almost Empty Threshold */
 /*		SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */
 	}
@@ -652,7 +797,7 @@
 
 }	/* SkGeInitMacFifo */
 
-#ifdef	SK_LNK_SYNC_CNT
+#ifdef SK_LNK_SYNC_CNT
 /******************************************************************************
  *
  *	SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting
@@ -673,8 +818,8 @@
  *	nothing
  */
 void SkGeLoadLnkSyncCnt(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 SK_U32	CntVal)		/* Counter value */
 {
@@ -684,7 +829,7 @@
 	SK_BOOL	IrqPend;
 
 	/* stop counter */
-	SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP);
+	SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LNK_STOP);
 
 	/*
 	 * ASIC problem:
@@ -697,6 +842,7 @@
 	IrqPend = SK_FALSE;
 	SK_IN32(IoC, B0_ISRC, &ISrc);
 	SK_IN32(IoC, B0_IMSK, &OrgIMsk);
+	
 	if (Port == MAC_1) {
 		NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1;
 		if ((ISrc & IS_LNK_SYNC_M1) != 0) {
@@ -709,6 +855,7 @@
 			IrqPend = SK_TRUE;
 		}
 	}
+
 	if (!IrqPend) {
 		SK_OUT32(IoC, B0_IMSK, NewIMsk);
 	}
@@ -717,15 +864,17 @@
 	SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal);
 
 	/* start counter */
-	SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START);
+	SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LNK_START);
 
 	if (!IrqPend) {
-		/* clear the unexpected IRQ, and restore the interrupt mask */
-		SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ);
+		/* clear the unexpected IRQ */
+		SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LNK_CLR_IRQ);
+		
+		/* restore the interrupt mask */
 		SK_OUT32(IoC, B0_IMSK, OrgIMsk);
 	}
 }	/* SkGeLoadLnkSyncCnt*/
-#endif	/* SK_LNK_SYNC_CNT */
+#endif /* SK_LNK_SYNC_CNT */
 
 #if defined(SK_DIAG) || defined(SK_CFG_SYNC)
 /******************************************************************************
@@ -757,8 +906,8 @@
  *		synchronous queue is configured
  */
 int SkGeCfgSync(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 SK_U32	IntTime,	/* Interval Timer Value in units of 8ns */
 SK_U32	LimCount,	/* Number of bytes to transfer during IntTime */
@@ -776,16 +925,16 @@
 		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
 		return(1);
 	}
-	
+
 	if (pAC->GIni.GP[Port].PXSQSize == 0) {
 		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG);
 		return(2);
 	}
-	
+
 	/* calculate register values */
 	IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100;
 	LimCount = LimCount / 8;
-	
+
 	if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) {
 		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
 		return(1);
@@ -803,13 +952,13 @@
 	 */
 	SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
 		TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
-	
+
 	SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime);
 	SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount);
-	
+
 	SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
 		(SK_U8)(SyncMode & (TXA_ENA_ALLOC | TXA_DIS_ALLOC)));
-	
+
 	if (IntTime != 0 || LimCount != 0) {
 		SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_START_RC);
 	}
@@ -830,10 +979,10 @@
  * Returns:
  *	nothing
  */
-static void DoInitRamQueue(
-SK_AC	*pAC,			/* adapter context */
-SK_IOC	IoC,			/* IO context */
-int		QuIoOffs,		/* Queue IO Address Offset */
+void DoInitRamQueue(
+SK_AC	*pAC,			/* Adapter Context */
+SK_IOC	IoC,			/* I/O Context */
+int		QuIoOffs,		/* Queue I/O Address Offset */
 SK_U32	QuStartAddr,	/* Queue Start Address */
 SK_U32	QuEndAddr,		/* Queue End Address */
 int		QuType)			/* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */
@@ -866,8 +1015,7 @@
 
 			/* continue with SK_RX_BRAM_Q */
 		case SK_RX_BRAM_Q:
-			/* write threshold for Rx Queue */
-
+			/* write threshold for Rx Queue (Pause packets) */
 			SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal);
 			SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal);
 
@@ -910,8 +1058,8 @@
  *	nothing
  */
 static void SkGeInitRamBufs(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT *pPrt;
@@ -919,7 +1067,7 @@
 
 	pPrt = &pAC->GIni.GP[Port];
 
-	if (pPrt->PRxQSize == SK_MIN_RXQ_SIZE) {
+	if (pPrt->PRxQSize <= SK_MIN_RXQ_SIZE) {
 		RxQType = SK_RX_SRAM_Q; 	/* small Rx Queue */
 	}
 	else {
@@ -928,10 +1076,10 @@
 
 	DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart,
 		pPrt->PRxQRamEnd, RxQType);
-	
+
 	DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart,
 		pPrt->PXsQRamEnd, SK_TX_RAM_Q);
-	
+
 	DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart,
 		pPrt->PXaQRamEnd, SK_TX_RAM_Q);
 
@@ -952,26 +1100,37 @@
  *	nothing
  */
 void SkGeInitRamIface(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC)		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC)		/* I/O Context */
 {
-	/* release local reset */
-	SK_OUT16(IoC, B3_RI_CTRL, RI_RST_CLR);
+	int i;
+	int RamBuffers;
 
-	/* configure timeout values */
-	SK_OUT8(IoC, B3_RI_WTO_R1, SK_RI_TO_53);
-	SK_OUT8(IoC, B3_RI_WTO_XA1, SK_RI_TO_53);
-	SK_OUT8(IoC, B3_RI_WTO_XS1, SK_RI_TO_53);
-	SK_OUT8(IoC, B3_RI_RTO_R1, SK_RI_TO_53);
-	SK_OUT8(IoC, B3_RI_RTO_XA1, SK_RI_TO_53);
-	SK_OUT8(IoC, B3_RI_RTO_XS1, SK_RI_TO_53);
-	SK_OUT8(IoC, B3_RI_WTO_R2, SK_RI_TO_53);
-	SK_OUT8(IoC, B3_RI_WTO_XA2, SK_RI_TO_53);
-	SK_OUT8(IoC, B3_RI_WTO_XS2, SK_RI_TO_53);
-	SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53);
-	SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53);
-	SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53);
+	if (CHIP_ID_YUKON_2(pAC)) {
+		RamBuffers = pAC->GIni.GIMacsFound;
+	}
+	else {
+		RamBuffers = 1;
+	}
+	
+	for (i = 0; i < RamBuffers; i++) {
+		/* release local reset */
+		SK_OUT16(IoC, SELECT_RAM_BUFFER(i, B3_RI_CTRL), RI_RST_CLR);
 
+		/* configure timeout values */
+		SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_R1), SK_RI_TO_53);
+		SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XA1), SK_RI_TO_53);
+		SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XS1), SK_RI_TO_53);
+		SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_R1), SK_RI_TO_53);
+		SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XA1), SK_RI_TO_53);
+		SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XS1), SK_RI_TO_53);
+		SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_R2), SK_RI_TO_53);
+		SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XA2), SK_RI_TO_53);
+		SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XS2), SK_RI_TO_53);
+		SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_R2), SK_RI_TO_53);
+		SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XA2), SK_RI_TO_53);
+		SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
+	}
 }	/* SkGeInitRamIface */
 
 
@@ -986,8 +1145,8 @@
  *	nothing
  */
 static void SkGeInitBmu(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
@@ -998,29 +1157,63 @@
 
 	RxWm = SK_BMU_RX_WM;
 	TxWm = SK_BMU_TX_WM;
-	
-	if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) {
-		/* for better performance */
-		RxWm /= 2;
-		TxWm /= 2;
-	}
 
-	/* Rx Queue: Release all local resets and set the watermark */
-	SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET);
-	SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm);
+	if (CHIP_ID_YUKON_2(pAC)) {
 
-	/*
-	 * Tx Queue: Release all local resets if the queue is used !
-	 * 		set watermark
-	 */
-	if (pPrt->PXSQSize != 0) {
-		SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET);
-		SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm);
+		if (pAC->GIni.GIPciBus == SK_PEX_BUS) {
+			/* for better performance set it to 128 */
+			RxWm = SK_BMU_RX_WM_PEX;		
+		}
+
+		/* Rx Queue: Release all local resets and set the watermark */
+		SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), BMU_CLR_RESET);
+		SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), BMU_OPER_INIT);
+		SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), BMU_FIFO_OP_ON);
+		SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_WM), RxWm);
+
+		/*
+		 * Tx Queue: Release all local resets if the queue is used !
+		 * 		set watermark
+		 */
+		if (pPrt->PXSQSize != 0 && HW_SYNC_TX_SUPPORTED(pAC)) {
+			/* Yukon-EC doesn't have a synchronous Tx queue */
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), BMU_CLR_RESET);
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), BMU_OPER_INIT);
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), BMU_FIFO_OP_ON);
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_WM), TxWm);
+		}
+		
+		if (pPrt->PXAQSize != 0) {
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_CLR_RESET);
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_OPER_INIT);
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_FIFO_OP_ON);
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_WM), TxWm);
+		}
 	}
-	
-	if (pPrt->PXAQSize != 0) {
-		SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET);
-		SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm);
+	else {
+		if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) {
+			/* for better performance */
+			RxWm /= 2;
+			TxWm /= 2;
+		}
+
+		/* Rx Queue: Release all local resets and set the watermark */
+		SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET);
+		SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm);
+
+		/*
+		 * Tx Queue: Release all local resets if the queue is used !
+		 * 		set watermark
+		 */
+		if (pPrt->PXSQSize != 0) {
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET);
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm);
+		}
+
+		if (pPrt->PXAQSize != 0) {
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET);
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm);
+		}
 	}
 	/*
 	 * Do NOT enable the descriptor poll timers here, because
@@ -1044,20 +1237,29 @@
  */
 static SK_U32 TestStopBit(
 SK_AC	*pAC,		/* Adapter Context */
-SK_IOC	IoC,		/* IO Context */
-int		QuIoOffs)	/* Queue IO Address Offset */
+SK_IOC	IoC,		/* I/O Context */
+int		QuIoOffs)	/* Queue I/O Address Offset */
 {
 	SK_U32	QuCsr;	/* CSR contents */
 
 	SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
 	
-	if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) {
-		/* Stop Descriptor overridden by start command */
-		SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP);
+	if (CHIP_ID_YUKON_2(pAC)) {
+		if ((QuCsr & (BMU_STOP | BMU_IDLE)) == 0) {
+			/* Stop Descriptor overridden by start command */
+			SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), BMU_STOP);
 
-		SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
+			SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
+		}
+	}
+	else {
+		if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) {
+			/* Stop Descriptor overridden by start command */
+			SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP);
+
+			SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
+		}
 	}
-	
 	return(QuCsr);
 }	/* TestStopBit */
 
@@ -1141,56 +1343,83 @@
  *	  SWITCH_PORT.
  */
 void SkGeStopPort(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* I/O context */
-int		Port,	/* port to stop (MAC_1 + n) */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
+int		Port,	/* Port to stop (MAC_1 + n) */
 int		Dir,	/* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */
 int		RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */
 {
-#ifndef SK_DIAG
-	SK_EVPARA Para;
-#endif /* !SK_DIAG */
 	SK_GEPORT *pPrt;
-	SK_U32	DWord;
+	SK_U32	RxCsr;
 	SK_U32	XsCsr;
 	SK_U32	XaCsr;
 	SK_U64	ToutStart;
+	SK_U32	CsrStart;
+	SK_U32	CsrStop;
+	SK_U32	CsrIdle;
+	SK_U32	CsrTest;
+	SK_U8 	rsl;	/* FIFO read shadow level */
+	SK_U8	rl;		/* FIFO read level */
 	int		i;
 	int		ToutCnt;
 
 	pPrt = &pAC->GIni.GP[Port];
 
+	/* set the proper values of Q_CSR register layout depending on the chip id */
+	if (CHIP_ID_YUKON_2(pAC)) {
+		CsrStart = BMU_START;
+		CsrStop = BMU_STOP;
+		CsrIdle = BMU_IDLE;
+		CsrTest = BMU_IDLE;
+	}
+	else {
+		CsrStart = CSR_START;
+		CsrStop = CSR_STOP;
+		CsrIdle = CSR_SV_IDLE;
+		CsrTest = CSR_SV_IDLE | CSR_STOP;
+	}
+
 	if ((Dir & SK_STOP_TX) != 0) {
-		/* disable receiver and transmitter */
-		SkMacRxTxDisable(pAC, IoC, Port);
-		
+
+		if (!pAC->GIni.GIAsfEnabled) {
+			/* disable receiver and transmitter */
+			SkMacRxTxDisable(pAC, IoC, Port);
+		}
+
 		/* stop both transmit queues */
 		/*
 		 * If the BMU is in the reset state CSR_STOP will terminate
 		 * immediately.
 		 */
-		SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP);
-		SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP);
+		SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CsrStop);
+		SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CsrStop);
 
 		ToutStart = SkOsGetTime(pAC);
 		ToutCnt = 0;
 		do {
-			/*
-			 * Clear packet arbiter timeout to make sure
-			 * this loop will terminate.
-			 */
-			SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
-				PA_CLR_TO_TX1 : PA_CLR_TO_TX2));
-
-			/*
-			 * If the transfer stucks at the MAC the STOP command will not
-			 * terminate if we don't flush the XMAC's transmit FIFO !
-			 */
-			SkMacFlushTxFifo(pAC, IoC, Port);
+#ifdef GENESIS
+			if (pAC->GIni.GIGenesis) {
+				/* Clear Tx packet arbiter timeout IRQ */
+				SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
+					PA_CLR_TO_TX1 : PA_CLR_TO_TX2));
 
-			XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);
+				/*
+				 * If the transfer stucks at the MAC the STOP command will not
+				 * terminate if we don't flush the XMAC's transmit FIFO !
+				 */
+				SkMacFlushTxFifo(pAC, IoC, Port);
+			}
+#endif /* GENESIS */
+			
 			XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff);
 
+			if (HW_SYNC_TX_SUPPORTED(pAC)) {
+				XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);
+			}
+			else {
+				XsCsr = XaCsr;
+			}
+
 			if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) {
 				/*
 				 * Timeout of 1/18 second reached.
@@ -1198,18 +1427,12 @@
 				 */
 				ToutCnt++;
 				if (ToutCnt > 1) {
-					/* Might be a problem when the driver event handler
-					 * calls StopPort again. XXX.
+					/*
+					 * If BMU stop doesn't terminate, we assume
+					 * we have a stable state and can reset the
+					 * BMU, Pref Unit, and RAM buffer now.
 					 */
-
-					/* Fatal Error, Loop aborted */
-					SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018,
-						SKERR_HWI_E018MSG);
-#ifndef SK_DIAG
-					Para.Para64 = Port;
-					SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-#endif /* !SK_DIAG */
-					return;
+					break;				/* ====> leave do/while loop here */
 				}
 				/*
 				 * Cache incoherency workaround: Assume a start command
@@ -1217,48 +1440,84 @@
 				 */
 				ToutStart = SkOsGetTime(pAC);
 
-				if ((XsCsr & CSR_STOP) != 0) {
-					SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START);
+				if ((XsCsr & CsrStop) != 0) {
+					SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CsrStart);
+				}
+				if ((XaCsr & CsrStop) != 0) {
+					SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CsrStart);
+				}
+
+				/*
+				 * After the previous operations the X(s|a)Csr does no
+				 * longer contain the proper values
+				 */
+				XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff);
+
+				if (HW_SYNC_TX_SUPPORTED(pAC)) {
+					XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);
 				}
-				if ((XaCsr & CSR_STOP) != 0) {
-					SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START);
+				else {
+					XsCsr = XaCsr;
 				}
 			}
 
 			/*
 			 * Because of the ASIC problem report entry from 21.08.1998 it is
 			 * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set.
+			 * (valid for GENESIS only)
 			 */
-		} while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE ||
-				 (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
+		} while (((XsCsr & CsrTest) != CsrIdle ||
+				  (XaCsr & CsrTest) != CsrIdle));
 
-		/* Reset the MAC depending on the RstMode */
-		if (RstMode == SK_SOFT_RST) {
-			SkMacSoftRst(pAC, IoC, Port);
+		if (pAC->GIni.GIAsfEnabled) {
+
+			pPrt->PState = (RstMode == SK_SOFT_RST) ? SK_PRT_STOP :
+				SK_PRT_RESET;
 		}
 		else {
-			SkMacHardRst(pAC, IoC, Port);
+			/* Reset the MAC depending on the RstMode */
+			if (RstMode == SK_SOFT_RST) {
+				SkMacSoftRst(pAC, IoC, Port);
+			}
+			else {
+				SkMacHardRst(pAC, IoC, Port);
+			}
 		}
- 		
+
 		/* Disable Force Sync bit and Enable Alloc bit */
 		SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
 			TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
-		
+
 		/* Stop Interval Timer and Limit Counter of Tx Arbiter */
 		SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L);
 		SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L);
 
 		/* Perform a local reset of the port's Tx path */
+		if (CHIP_ID_YUKON_2(pAC)) {
+			/* Reset the PCI FIFO of the async Tx queue */
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR),
+				BMU_RST_SET | BMU_FIFO_RST);
+			/* Reset the PCI FIFO of the sync Tx queue */
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR),
+				BMU_RST_SET | BMU_FIFO_RST);
+			/* Reset the Tx prefetch units */
+			SK_OUT32(IoC, Y2_PREF_Q_ADDR(pPrt->PXaQOff, PREF_UNIT_CTRL_REG),
+				PREF_UNIT_RST_SET);
+			SK_OUT32(IoC, Y2_PREF_Q_ADDR(pPrt->PXsQOff, PREF_UNIT_CTRL_REG),
+				PREF_UNIT_RST_SET);
+		}
+		else {
+			/* Reset the PCI FIFO of the async Tx queue */
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET);
+			/* Reset the PCI FIFO of the sync Tx queue */
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET);
+		}
 
-		/* Reset the PCI FIFO of the async Tx queue */
-		SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET);
-		/* Reset the PCI FIFO of the sync Tx queue */
-		SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET);
 		/* Reset the RAM Buffer async Tx queue */
 		SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET);
 		/* Reset the RAM Buffer sync Tx queue */
 		SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET);
-		
+
 		/* Reset Tx MAC FIFO */
 #ifdef GENESIS
 		if (pAC->GIni.GIGenesis) {
@@ -1270,71 +1529,114 @@
 			SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS);
 		}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
-		if (pAC->GIni.GIYukon) {
-			/* Reset TX MAC FIFO */
+		if (pAC->GIni.GIYukon && !pAC->GIni.GIAsfEnabled) {
+			/* Reset Tx MAC FIFO */
 			SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
 		}
+
+		/* set Pause Off */
+		SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_PAUSE_OFF);
 #endif /* YUKON */
 	}
 
 	if ((Dir & SK_STOP_RX) != 0) {
-		/*
-		 * The RX Stop Command will not terminate if no buffers
-		 * are queued in the RxD ring. But it will always reach
-		 * the Idle state. Therefore we can use this feature to
-		 * stop the transfer of received packets.
-		 */
-		/* stop the port's receive queue */
-		SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP);
 		
-		i = 100;
-		do {
+		if (CHIP_ID_YUKON_2(pAC)) {
 			/*
-			 * Clear packet arbiter timeout to make sure
-			 * this loop will terminate
+			 * The RX Stop command will not work for Yukon-2 if the BMU does not
+			 * reach the end of packet and since we can't make sure that we have
+			 * incoming data, we must reset the BMU while it is not during a DMA
+			 * transfer. Since it is possible that the RX path is still active,
+			 * the RX RAM buffer will be stopped first, so any possible incoming
+			 * data will not trigger a DMA. After the RAM buffer is stopped, the
+			 * BMU is polled until any DMA in progress is ended and only then it
+			 * will be reset.
 			 */
-			SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
-				PA_CLR_TO_RX1 : PA_CLR_TO_RX2));
 
-			DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff);
+			/* Disable the RAM Buffer receive queue */
+			SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_DIS_OP_MD);
 
-			/* timeout if i==0 (bug fix for #10748) */
-			if (--i == 0) {
-				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024,
-					SKERR_HWI_E024MSG);
-				break;
+			i = 0xffff;
+			while (--i) {
+				SK_IN8(IoC, RB_ADDR(pPrt->PRxQOff, Q_RSL), &rsl);
+				SK_IN8(IoC, RB_ADDR(pPrt->PRxQOff, Q_RL), &rl);
+				
+				if (rsl == rl) {
+					break;
+				}
 			}
+
+			/*
+			 * If the rx side is blocked the above loop
+			 * cannot terminate. But, if there was any traffic
+			 * it should be terminated, now. However, stop the
+			 * RX BMU and prefetch unit!
+			 */
+			SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR),
+				BMU_RST_SET | BMU_FIFO_RST);
+			/* reset the Rx prefetch unit */
+			SK_OUT32(IoC, Y2_PREF_Q_ADDR(pPrt->PRxQOff, PREF_UNIT_CTRL_REG),
+				PREF_UNIT_RST_SET);
+		}
+		else {
 			/*
-			 * because of the ASIC problem report entry from 21.08.98
-			 * it is required to wait until CSR_STOP is reset and
-			 * CSR_SV_IDLE is set.
+			 * The RX Stop Command will not terminate if no buffers
+			 * are queued in the RxD ring. But it will always reach
+			 * the Idle state. Therefore we can use this feature to
+			 * stop the transfer of received packets.
 			 */
-		} while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
+			/* stop the port's receive queue */
+			SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CsrStop);
+
+			i = 100;
+			do {
+#ifdef GENESIS
+				if (pAC->GIni.GIGenesis) {
+					/* Clear Rx packet arbiter timeout IRQ */
+					SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
+						PA_CLR_TO_RX1 : PA_CLR_TO_RX2));
+				}
+#endif /* GENESIS */
+
+				RxCsr = TestStopBit(pAC, IoC, pPrt->PRxQOff);
 
-		/* The path data transfer activity is fully stopped now */
+				/* timeout if i==0 (bug fix for #10748) */
+				if (--i == 0) {
+					SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024,
+						SKERR_HWI_E024MSG);
+					break;
+				}
+			/*
+			 * Because of the ASIC problem report entry from 21.08.1998 it is
+			 * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set.
+			 * (valid for GENESIS only)
+			 */
+			} while ((RxCsr & CsrTest) != CsrIdle);
+			/* The path data transfer activity is fully stopped now */
 
-		/* Perform a local reset of the port's Rx path */
+			/* Perform a local reset of the port's Rx path */
+			/*	Reset the PCI FIFO of the Rx queue */
+			SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET);
+		}
 
-		 /*	Reset the PCI FIFO of the Rx queue */
-		SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET);
 		/* Reset the RAM Buffer receive queue */
 		SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET);
 
 		/* Reset Rx MAC FIFO */
 #ifdef GENESIS
 		if (pAC->GIni.GIGenesis) {
-			
+
 			SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET);
 
 			/* switch Rx LED off, stop the LED counter */
 			SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS);
 		}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
-		if (pAC->GIni.GIYukon) {
+		if (pAC->GIni.GIYukon && !pAC->GIni.GIAsfEnabled) {
 			/* Reset Rx MAC FIFO */
 			SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
 		}
@@ -1354,8 +1656,8 @@
  *	nothing
  */
 static void SkGeInit0(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC)		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC)		/* I/O Context */
 {
 	int i;
 	SK_GEPORT *pPrt;
@@ -1398,18 +1700,25 @@
 		pPrt->PMacJamLen = TX_JAM_LEN_DEF;
 		pPrt->PMacJamIpgVal	= TX_JAM_IPG_DEF;
 		pPrt->PMacJamIpgData = TX_IPG_JAM_DEF;
+		pPrt->PMacBackOffLim = TX_BOF_LIM_DEF;
+		pPrt->PMacDataBlind = DATA_BLIND_DEF;
 		pPrt->PMacIpgData = IPG_DATA_DEF;
 		pPrt->PMacLimit4 = SK_FALSE;
 	}
 
 	pAC->GIni.GIPortUsage = SK_RED_LINK;
 	pAC->GIni.GILedBlinkCtrl = (SK_U16)OemConfig.Value;
-	pAC->GIni.GIValIrqMask = IS_ALL_MSK;
+	pAC->GIni.GIChipCap = 0;
+
+	for (i = 0; i < 4; i++) {
+		pAC->GIni.HwF.Features[i]= 0x00000000;
+		pAC->GIni.HwF.OnMask[i]	 = 0x00000000;
+		pAC->GIni.HwF.OffMask[i] = 0x00000000;
+	}
 
 }	/* SkGeInit0*/
 
 #ifdef SK_PCI_RESET
-
 /******************************************************************************
  *
  *	SkGePciReset() - Reset PCI interface
@@ -1425,8 +1734,8 @@
  *	1:	Power state could not be changed to 3.
  */
 static int SkGePciReset(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC)		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC)		/* I/O Context */
 {
 	int		i;
 	SK_U16	PmCtlSts;
@@ -1449,7 +1758,7 @@
 	/* We know the RAM Interface Arbiter is enabled. */
 	SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D3);
 	SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);
-	
+
 	if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D3) {
 		return(1);
 	}
@@ -1459,7 +1768,7 @@
 
 	/* Check for D0 state. */
 	SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);
-	
+
 	if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D0) {
 		return(1);
 	}
@@ -1468,11 +1777,24 @@
 	SkPciReadCfgWord(pAC, PCI_COMMAND, &PciCmd);
 	SkPciReadCfgByte(pAC, PCI_CACHE_LSZ, &Cls);
 	SkPciReadCfgDWord(pAC, PCI_BASE_1ST, &Bp1);
-	SkPciReadCfgDWord(pAC, PCI_BASE_2ND, &Bp2);
+
+	/*
+	 * Compute the location in PCI config space of BAR2
+	 * relativ to the location of BAR1
+	 */
+	if ((Bp1 & PCI_MEM_TYP_MSK) == PCI_MEM64BIT) {
+		/* BAR1 is 64 bits wide */
+		i = 8;
+	}
+	else {
+		i = 4;
+	}
+
+	SkPciReadCfgDWord(pAC, PCI_BASE_1ST + i, &Bp2);
 	SkPciReadCfgByte(pAC, PCI_LAT_TIM, &Lat);
-	
-	if (PciCmd != 0 || Cls != (SK_U8)0 || Lat != (SK_U8)0 ||
-		(Bp1 & 0xfffffff0L) != 0 || Bp2 != 1) {
+
+	if (PciCmd != 0 || Cls != 0 || (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1 ||
+		Lat != 0) {
 		return(1);
 	}
 
@@ -1483,9 +1805,66 @@
 
 	return(0);
 }	/* SkGePciReset */
-
 #endif /* SK_PCI_RESET */
 
+
+/******************************************************************************
+ *
+ *	SkGeSetUpSupFeatures() - Collect Feature List for HW_FEATURE Macro
+ *
+ * Description:
+ *	This function collects the available features and required
+ *	deviation services of the Adapter and provides these
+ *	information in the GIHwF struct. Theses information is used as
+ *	default value and may be overritten by the driver using the
+ *	SET_HW_FEATURE_MASK() macro in its Init0 phase.
+ *
+ * Notice:
+ *	Unsing the On and Off mask: Never switch on the same bit in both
+ *	masks simultaneously. However, if doing the Off mask will win.
+ *	
+ * Returns:
+ *	nothing
+ */
+static void SkGeSetUpSupFeatures(
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC)		/* I/O Context */
+{
+	int i;
+
+	switch (pAC->GIni.GIChipId) {
+	case CHIP_ID_YUKON_EC:
+		if (pAC->GIni.GIChipRev == CHIP_REV_YU_EC_A1) {
+			/* A0/A1 */
+			pAC->GIni.HwF.Features[HW_DEV_LIST] = 	
+				HWF_WA_DEV_42  | HWF_WA_DEV_46 | HWF_WA_DEV_43_418 |
+				HWF_WA_DEV_420 | HWF_WA_DEV_423 |
+				HWF_WA_DEV_424 | HWF_WA_DEV_425 | HWF_WA_DEV_427 |
+				HWF_WA_DEV_428;
+		}
+		else if (pAC->GIni.GIChipRev == CHIP_REV_YU_EC_A2) {
+			/* A2 */
+			pAC->GIni.HwF.Features[HW_DEV_LIST] =
+				HWF_WA_DEV_424 | HWF_WA_DEV_425 | HWF_WA_DEV_427 |
+				HWF_WA_DEV_428;
+		}
+		break;
+	case CHIP_ID_YUKON_FE:
+		pAC->GIni.HwF.Features[HW_DEV_LIST] = HWF_WA_DEV_427;
+		break;
+	case CHIP_ID_YUKON_XL:
+		pAC->GIni.HwF.Features[HW_DEV_LIST] = HWF_WA_DEV_427;
+		break;
+	}
+
+	for (i = 0; i < 4; i++) {
+		pAC->GIni.HwF.Features[i] =
+			(pAC->GIni.HwF.Features[i] | pAC->GIni.HwF.OnMask[i]) &
+				~pAC->GIni.HwF.OffMask[i];
+	}
+}	/* SkGeSetUpSupFeatures */
+
+
 /******************************************************************************
  *
  *	SkGeInit1() - Level 1 Initialization
@@ -1508,73 +1887,190 @@
  *	6:	HW self test failed
  */
 static int SkGeInit1(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC)		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC)		/* I/O Context */
 {
 	SK_U8	Byte;
 	SK_U16	Word;
-	SK_U16	CtrlStat;
+	SK_U32	CtrlStat;
+	SK_U32	VauxAvail;
 	SK_U32	DWord;
+	SK_U32	PowerDownBit;
+	SK_GEPORT *pPrt;
 	int	RetVal;
 	int	i;
 
 	RetVal = 0;
 
-	/* save CLK_RUN bits (YUKON-Lite) */
-	SK_IN16(IoC, B0_CTST, &CtrlStat);
+	/* save CLK_RUN & ASF_ENABLE bits (YUKON-Lite, YUKON-EC) */
+	SK_IN32(IoC, B0_CTST, &CtrlStat);
 
 #ifdef SK_PCI_RESET
 	(void)SkGePciReset(pAC, IoC);
 #endif /* SK_PCI_RESET */
 
-	/* do the SW-reset */
-	SK_OUT8(IoC, B0_CTST, CS_RST_SET);
-
 	/* release the SW-reset */
+	/* Important: SW-reset has to be cleared here, to ensure
+	 * the CHIP_ID can be read IO-mapped based, too -
+	 * remember the RAP register can only be written if
+	 * SW-reset is cleared.
+	 */
 	SK_OUT8(IoC, B0_CTST, CS_RST_CLR);
 
+	/* read Chip Identification Number */
+	SK_IN8(IoC, B2_CHIP_ID, &Byte);
+	pAC->GIni.GIChipId = Byte;
+
+	pAC->GIni.GIAsfEnabled = SK_FALSE;
+
+	/* ASF support only for Yukon-2 */
+	if ((pAC->GIni.GIChipId >= CHIP_ID_YUKON_XL) &&
+		(pAC->GIni.GIChipId <= CHIP_ID_YUKON_EC)) {
+#ifdef SK_ASF
+		if ((CtrlStat & Y2_ASF_ENABLE) != 0) {
+			/* do the SW-reset only if ASF is not enabled */
+			pAC->GIni.GIAsfEnabled = SK_TRUE;
+		}
+#else /* !SK_ASF */
+		/* Put ASF system in reset state */
+		SK_OUT32(IoC, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
+
+		/* Disable ASF Unit */
+		SK_OUT16(IoC, B0_CTST, Y2_ASF_DISABLE);
+#endif /* !SK_ASF */
+	}
+
+	if (!pAC->GIni.GIAsfEnabled) {
+		/* set the SW-reset */
+		SK_OUT8(IoC, B0_CTST, CS_RST_SET);
+
+		/* release the SW-reset */
+		SK_OUT8(IoC, B0_CTST, CS_RST_CLR);
+	}
+
 	/* reset all error bits in the PCI STATUS register */
 	/*
 	 * Note: PCI Cfg cycles cannot be used, because they are not
 	 *		 available on some platforms after 'boot time'.
 	 */
-	SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
-	
+	SK_IN16(IoC, PCI_C(pAC, PCI_STATUS), &Word);
+
 	SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-	SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
-	SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+	SK_OUT16(IoC, PCI_C(pAC, PCI_STATUS), Word | (SK_U16)PCI_ERRBITS);
 
 	/* release Master Reset */
 	SK_OUT8(IoC, B0_CTST, CS_MRST_CLR);
 
 #ifdef CLK_RUN
 	CtrlStat |= CS_CLK_RUN_ENA;
-#endif /* CLK_RUN */
 
 	/* restore CLK_RUN bits */
 	SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat &
 		(CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA)));
+#endif /* CLK_RUN */
+
+	if ((pAC->GIni.GIChipId >= CHIP_ID_YUKON_XL) &&
+		(pAC->GIni.GIChipId <= CHIP_ID_YUKON_FE)) {
+
+		pAC->GIni.GIYukon2 = SK_TRUE;
+		pAC->GIni.GIValIrqMask = Y2_IS_ALL_MSK;
+		pAC->GIni.GIValHwIrqMask = Y2_HWE_ALL_MSK;
+
+		VauxAvail = Y2_VAUX_AVAIL;
+
+		SK_IN32(IoC, PCI_C(pAC, PCI_OUR_STATUS), &DWord);
+
+		if ((DWord & PCI_OS_PCI_X) != 0) {
+			/* this is a PCI/PCIX bus */
+			pAC->GIni.GIPciBus = (SK_U8)(((DWord & PCI_OS_PCIX) != 0) ?
+				SK_PCIX_BUS : SK_PCI_BUS);
+
+			/* check if 64-bit PCI Slot is present */
+			pAC->GIni.GIPciSlot64 = (SK_BOOL)((DWord & PCI_OS_PCI64B) != 0);
+
+			/* check if 66 MHz PCI Clock is active */
+			pAC->GIni.GIPciClock66 = (SK_BOOL)((DWord & PCI_OS_PCI66M) != 0);
+		}
+		else {
+			/* this is a PEX bus */
+			pAC->GIni.GIPciBus = SK_PEX_BUS;
+
+			/* Clear any PEX errors */
+			SK_OUT32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), 0xffffffffUL);
+		}
+		/*
+		 * Yukon-2 chips family has a different way of providing
+		 * the number of MACs available
+		 */
+		pAC->GIni.GIMacsFound = 1;
+
+		SK_IN8(IoC, B2_Y2_HW_RES, &Byte);
+
+		if (CHIP_ID_YUKON_2(pAC)) {
+			/*
+			 * OEM config value is overwritten and should not
+			 * be used for Yukon-2
+			 */
+			pAC->GIni.GILedBlinkCtrl |= SK_ACT_LED_BLINK;
+
+			if (CFG_LED_MODE(Byte) == CFG_LED_DUAL_ACT_LNK) {
+
+				pAC->GIni.GILedBlinkCtrl |= SK_DUAL_LED_ACT_LNK;
+			}
+		}
+
+		if ((Byte & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) {
+
+			SK_IN8(IoC, B2_Y2_CLK_GATE, &Byte);
+
+			if (!(Byte & Y2_STATUS_LNK2_INAC)) {
+				pAC->GIni.GIMacsFound++;
+			}
+		}
+
+		if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) {
+#ifdef XXX
+			if (pAC->GIni.GIPciBus != SK_PEX_BUS) {
+				/* Enable Core Clock Division */
+				SK_OUT32(IoC, B2_Y2_CLK_CTRL, Y2_CLK_DIV_VAL_2(0) |
+					Y2_CLK_DIV_ENA);
+			}
+#endif /* XXX */
+#ifdef VCPU
+		/* temporary WA for reported number of links */
+			pAC->GIni.GIMacsFound = 2;
+#endif /* VCPU */
+		}
+
+		/* read Chip Revision */
+		SK_IN8(IoC, B2_MAC_CFG, &Byte);
+
+		pAC->GIni.GIChipCap = Byte & 0x0f;
+	}
+	else {
+		pAC->GIni.GIYukon2 = SK_FALSE;
+		pAC->GIni.GIValIrqMask = IS_ALL_MSK;
+		pAC->GIni.GIValHwIrqMask = 0;	/* not activated */
+
+		VauxAvail = CS_VAUX_AVAIL;
+
+		/* read number of MACs and Chip Revision */
+		SK_IN8(IoC, B2_MAC_CFG, &Byte);
+
+		pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2;
+	}
 
-	/* read Chip Identification Number */
-	SK_IN8(IoC, B2_CHIP_ID, &Byte);
-	pAC->GIni.GIChipId = Byte;
-	
-	/* read number of MACs */
-	SK_IN8(IoC, B2_MAC_CFG, &Byte);
-	pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2;
-	
 	/* get Chip Revision Number */
 	pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4);
 
-	/* get diff. PCI parameters */
-	SK_IN16(IoC, B0_CTST, &CtrlStat);
-	
 	/* read the adapters RAM size */
 	SK_IN8(IoC, B2_E_0, &Byte);
-	
+
 	pAC->GIni.GIGenesis = SK_FALSE;
 	pAC->GIni.GIYukon = SK_FALSE;
 	pAC->GIni.GIYukonLite = SK_FALSE;
+	pAC->GIni.GIVauxAvail = SK_FALSE;
 
 #ifdef GENESIS
 	if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
@@ -1590,57 +2086,60 @@
 			pAC->GIni.GIRamSize = (int)Byte * 512;
 			pAC->GIni.GIRamOffs = 0;
 		}
-		/* all GE adapters work with 53.125 MHz host clock */
+		/* all GENESIS adapters work with 53.125 MHz host clock */
 		pAC->GIni.GIHstClkFact = SK_FACT_53;
-		
+
 		/* set Descr. Poll Timer Init Value to 250 ms */
 		pAC->GIni.GIPollTimerVal =
 			SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100;
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) {
-		
+
 		pAC->GIni.GIYukon = SK_TRUE;
-		
+
 		pAC->GIni.GIRamSize = (Byte == (SK_U8)0) ? 128 : (int)Byte * 4;
-		
+
 		pAC->GIni.GIRamOffs = 0;
-		
-		/* WA for chip Rev. A */
+
+		/* WA for Yukon chip Rev. A */
 		pAC->GIni.GIWolOffs = (pAC->GIni.GIChipId == CHIP_ID_YUKON &&
 			pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0;
-		
+
 		/* get PM Capabilities of PCI config space */
-		SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word);
+		SK_IN16(IoC, PCI_C(pAC, PCI_PM_CAP_REG), &Word);
 
 		/* check if VAUX is available */
-		if (((CtrlStat & CS_VAUX_AVAIL) != 0) &&
+		if (((CtrlStat & VauxAvail) != 0) &&
 			/* check also if PME from D3cold is set */
 			((Word & PCI_PME_D3C_SUP) != 0)) {
 			/* set entry in GE init struct */
 			pAC->GIni.GIVauxAvail = SK_TRUE;
 		}
-		
-		if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) {
-			/* this is Rev. A1 */
-			pAC->GIni.GIYukonLite = SK_TRUE;
-		}
-		else {
-			/* save Flash-Address Register */
-			SK_IN32(IoC, B2_FAR, &DWord);
 
-			/* test Flash-Address Register */
-			SK_OUT8(IoC, B2_FAR + 3, 0xff);
-			SK_IN8(IoC, B2_FAR + 3, &Byte);
+		if (!CHIP_ID_YUKON_2(pAC)) {
 
-			if (Byte != 0) {
-				/* this is Rev. A0 */
+			if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) {
+				/* this is Rev. A1 */
 				pAC->GIni.GIYukonLite = SK_TRUE;
+			}
+			else {
+				/* save Flash-Address Register */
+				SK_IN32(IoC, B2_FAR, &DWord);
+
+				/* test Flash-Address Register */
+				SK_OUT8(IoC, B2_FAR + 3, 0xff);
+				SK_IN8(IoC, B2_FAR + 3, &Byte);
+
+				if (Byte != 0) {
+					/* this is Rev. A0 */
+					pAC->GIni.GIYukonLite = SK_TRUE;
 
-				/* restore Flash-Address Register */
-				SK_OUT32(IoC, B2_FAR, DWord);
+					/* restore Flash-Address Register */
+					SK_OUT32(IoC, B2_FAR, DWord);
+				}
 			}
 		}
 
@@ -1648,70 +2147,128 @@
 		SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA |
 			PC_VAUX_OFF | PC_VCC_ON));
 
-		/* read the Interrupt source */
-		SK_IN32(IoC, B0_ISRC, &DWord);
-		
-		if ((DWord & IS_HW_ERR) != 0) {
-			/* read the HW Error Interrupt source */
-			SK_IN32(IoC, B0_HWE_ISRC, &DWord);
-			
-			if ((DWord & IS_IRQ_SENSOR) != 0) {
-				/* disable HW Error IRQ */
-				pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;
+		if (!pAC->GIni.GIAsfEnabled) {
+
+			for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+				/* set GMAC Link Control reset */
+				SK_OUT8(IoC, MR_ADDR(i, GMAC_LINK_CTRL), (SK_U8)GMLC_RST_SET);
+
+				/* clear GMAC Link Control reset */
+				SK_OUT8(IoC, MR_ADDR(i, GMAC_LINK_CTRL), (SK_U8)GMLC_RST_CLR);
 			}
 		}
-		
-		for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-			/* set GMAC Link Control reset */
-			SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET);
 
-			/* clear GMAC Link Control reset */
-			SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
+		if (CHIP_ID_YUKON_2(pAC)) {
+			/* for PCI-Express the PCI_CLK is substituted by the core clock */
+			if (pAC->GIni.GIPciBus == SK_PEX_BUS) {
+				/* PEX adapters work with different host clock */
+				if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
+					/* Yukon-FE works with 100 MHz host clock */
+					pAC->GIni.GIHstClkFact = SK_FACT_100;
+				}
+				else {
+					/* Yukon-EC/XL (PEX) work with 125 MHz host clock */
+					pAC->GIni.GIHstClkFact = SK_FACT_125;
+				}
+			}
+			else {
+				/* non-PEX adapters work with 156 MHz host clock */
+				pAC->GIni.GIHstClkFact = 2 * SK_FACT_78;
+			}
+
+			pAC->GIni.GIPollTimerVal =		/* ca. 75 us */
+				SK_DPOLL_DEF_Y2 * (SK_U32)pAC->GIni.GIHstClkFact / 100;
+
+			/* set power down bit */
+			PowerDownBit = PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD;
+
+#ifdef SK_PHY_LP_MODE_DEEP_SLEEP
+			/* Disable Core Clock Division */
+			SK_OUT32(IoC, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS);
+#endif
 		}
-		/* all YU chips work with 78.125 MHz host clock */
-		pAC->GIni.GIHstClkFact = SK_FACT_78;
-		
-		pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX;	/* 215 ms */
+		else {
+			/* YUKON adapters work with 78 MHz host clock */
+			pAC->GIni.GIHstClkFact = SK_FACT_78;
+
+			pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX;	/* 215 ms */
+
+			/* read the Interrupt source */
+			SK_IN32(IoC, B0_ISRC, &DWord);
+
+			if ((DWord & IS_HW_ERR) != 0) {
+				/* read the HW Error Interrupt source */
+				SK_IN32(IoC, B0_HWE_ISRC, &DWord);
+
+				if ((DWord & IS_IRQ_SENSOR) != 0) {
+					/* disable HW Error IRQ */
+					pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;
+				}
+			}
+			/* set power down bit */
+			PowerDownBit = PCI_PHY_COMA;
+		}
+
+#ifdef SK_PHY_LP_MODE_DEEP_SLEEP
+
+		SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &DWord);
+
+		/* Release PHY from PowerDown/COMA Mode */
+		SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), DWord & ~PowerDownBit);
+#endif
 	}
 #endif /* YUKON */
 
-	/* check if 64-bit PCI Slot is present */
-	pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0);
-	
-	/* check if 66 MHz PCI Clock is active */
-	pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0);
+	SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+	if (!CHIP_ID_YUKON_2(pAC)) {
+		/* check if 64-bit PCI Slot is present */
+		pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0);
+
+		/* check if 66 MHz PCI Clock is active */
+		pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0);
+	}
 
 	/* read PCI HW Revision Id. */
-	SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte);
+	SK_IN8(IoC, PCI_C(pAC, PCI_REV_ID), &Byte);
 	pAC->GIni.GIPciHwRev = Byte;
 
+	/* read connector type */
+	SK_IN8(IoC, B2_CONN_TYP, &pAC->GIni.GIConTyp);
+
 	/* read the PMD type */
 	SK_IN8(IoC, B2_PMD_TYP, &Byte);
-	pAC->GIni.GICopperType = (SK_U8)(Byte == 'T');
 
-	/* read the PHY type */
+	pAC->GIni.GIPmdTyp = Byte;
+
+	pAC->GIni.GICopperType = (SK_BOOL)(Byte == 'T' || Byte == '1') ||
+		pAC->GIni.GIYukon2;
+
+	/* read the PHY type (Yukon and Genesis) */
 	SK_IN8(IoC, B2_E_1, &Byte);
 
 	Byte &= 0x0f;	/* the PHY type is stored in the lower nibble */
 	for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-		
+
+		pPrt = &pAC->GIni.GP[i];
+
 #ifdef GENESIS
 		if (pAC->GIni.GIGenesis) {
 			switch (Byte) {
 			case SK_PHY_XMAC:
-				pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC;
+				pPrt->PhyAddr = PHY_ADDR_XMAC;
 				break;
 			case SK_PHY_BCOM:
-				pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM;
-				pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
+				pPrt->PhyAddr = PHY_ADDR_BCOM;
+				pPrt->PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
 					SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE);
 				break;
 #ifdef OTHER_PHY
 			case SK_PHY_LONE:
-				pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE;
+				pPrt->PhyAddr = PHY_ADDR_LONE;
 				break;
 			case SK_PHY_NAT:
-				pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT;
+				pPrt->PhyAddr = PHY_ADDR_NAT;
 				break;
 #endif /* OTHER_PHY */
 			default:
@@ -1721,65 +2278,97 @@
 			}
 		}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 		if (pAC->GIni.GIYukon) {
-			
-			if (Byte < (SK_U8)SK_PHY_MARV_COPPER) {
+
+			if ((Byte < (SK_U8)SK_PHY_MARV_COPPER) || CHIP_ID_YUKON_2(pAC)) {
 				/* if this field is not initialized */
 				Byte = (SK_U8)SK_PHY_MARV_COPPER;
-				
+
 				pAC->GIni.GICopperType = SK_TRUE;
 			}
-			
-			pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV;
-			
+
+			pPrt->PhyAddr = PHY_ADDR_MARV;
+
 			if (pAC->GIni.GICopperType) {
 
-				pAC->GIni.GP[i].PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_AUTO |
-					SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS |
-					SK_LSPEED_CAP_1000MBPS);
-				
-				pAC->GIni.GP[i].PLinkSpeed = (SK_U8)SK_LSPEED_AUTO;
-				
-				pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
+				if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE ||
+					(pAC->GIni.GIChipId == CHIP_ID_YUKON_EC &&
+					pAC->GIni.GIChipCap == 2)) {
+
+					pPrt->PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_100MBPS |
+						SK_LSPEED_CAP_10MBPS);
+
+					pAC->GIni.GIRamSize = 4;
+				}
+				else {
+					pPrt->PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_1000MBPS |
+						SK_LSPEED_CAP_100MBPS | SK_LSPEED_CAP_10MBPS |
+						SK_LSPEED_CAP_AUTO);
+				}
+
+				pPrt->PLinkSpeed = (SK_U8)SK_LSPEED_AUTO;
+
+				pPrt->PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
 					SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE);
 			}
 			else {
 				Byte = (SK_U8)SK_PHY_MARV_FIBER;
 			}
 		}
+
+		/* Clear TWSI IRQ */
+		SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
+
 #endif /* YUKON */
-		
-		pAC->GIni.GP[i].PhyType = (int)Byte;
-		
+
+		pPrt->PhyType = (int)Byte;
+
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
-			("PHY type: %d  PHY addr: %04x\n", Byte,
-			pAC->GIni.GP[i].PhyAddr));
+			("PHY type: %d  PHY addr: %04x\n",
+			Byte, pPrt->PhyAddr));
 	}
-	
+
 	/* get MAC Type & set function pointers dependent on */
 #ifdef GENESIS
 	if (pAC->GIni.GIGenesis) {
-		
+
 		pAC->GIni.GIMacType = SK_MAC_XMAC;
 
 		pAC->GIni.GIFunc.pFnMacUpdateStats	= SkXmUpdateStats;
 		pAC->GIni.GIFunc.pFnMacStatistic	= SkXmMacStatistic;
 		pAC->GIni.GIFunc.pFnMacResetCounter	= SkXmResetCounter;
 		pAC->GIni.GIFunc.pFnMacOverflow		= SkXmOverflowStatus;
+#ifdef SK_DIAG
+		pAC->GIni.GIFunc.pFnMacPhyRead		= SkXmPhyRead;
+		pAC->GIni.GIFunc.pFnMacPhyWrite		= SkXmPhyWrite;
+#else	/* SK_DIAG */
+		pAC->GIni.GIFunc.pSkGeSirqIsr		= SkGeYuSirqIsr;
+#endif /* !SK_DIAG */
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
-		
+
 		pAC->GIni.GIMacType = SK_MAC_GMAC;
 
 		pAC->GIni.GIFunc.pFnMacUpdateStats	= SkGmUpdateStats;
 		pAC->GIni.GIFunc.pFnMacStatistic	= SkGmMacStatistic;
 		pAC->GIni.GIFunc.pFnMacResetCounter	= SkGmResetCounter;
 		pAC->GIni.GIFunc.pFnMacOverflow		= SkGmOverflowStatus;
+#ifdef SK_DIAG
+		pAC->GIni.GIFunc.pFnMacPhyRead		= SkGmPhyRead;
+		pAC->GIni.GIFunc.pFnMacPhyWrite		= SkGmPhyWrite;
+#else	/* SK_DIAG */
+		if (CHIP_ID_YUKON_2(pAC)) {
+			pAC->GIni.GIFunc.pSkGeSirqIsr	= SkYuk2SirqIsr;
+		}
+		else {
+			pAC->GIni.GIFunc.pSkGeSirqIsr	= SkGeYuSirqIsr;
+		}
+#endif /* !SK_DIAG */
 
 #ifdef SPECIAL_HANDLING
 		if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
@@ -1792,7 +2381,9 @@
 #endif
 	}
 #endif /* YUKON */
-	
+
+	SkGeSetUpSupFeatures(pAC, IoC);
+
 	return(RetVal);
 }	/* SkGeInit1 */
 
@@ -1813,9 +2404,12 @@
  *	nothing
  */
 static void SkGeInit2(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC)		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC)		/* I/O Context */
 {
+#ifdef YUKON
+	SK_U16	Word;
+#endif /* YUKON */
 #ifdef GENESIS
 	SK_U32	DWord;
 #endif /* GENESIS */
@@ -1849,13 +2443,13 @@
 		SkGeInitPktArb(pAC, IoC);
 	}
 #endif /* GENESIS */
-	
-#ifdef YUKON
+
+#ifdef xSK_DIAG
 	if (pAC->GIni.GIYukon) {
 		/* start Time Stamp Timer */
 		SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START);
 	}
-#endif /* YUKON */
+#endif /* SK_DIAG */
 
 	/* enable the Tx Arbiters */
 	for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
@@ -1865,8 +2459,34 @@
 	/* enable the RAM Interface Arbiter */
 	SkGeInitRamIface(pAC, IoC);
 
+#ifdef YUKON
+	if (CHIP_ID_YUKON_2(pAC)) {
+
+		if (pAC->GIni.GIPciBus == SK_PEX_BUS) {
+
+			SK_IN16(IoC, PCI_C(pAC, PEX_DEV_CTRL), &Word);
+
+			/* change Max. Read Request Size to 2048 bytes */
+			Word &= ~PEX_DC_MAX_RRS_MSK;
+			Word |= PEX_DC_MAX_RD_RQ_SIZE(4);
+
+			SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+
+			SK_OUT16(IoC, PCI_C(pAC, PEX_DEV_CTRL), Word);
+
+			SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+		}
+
+		/*
+		 * Writing the HW Error Mask Reg. will not generate an
+		 * IRQ as long as the B0_IMSK is not set by the driver.
+		 */
+		SK_OUT32(IoC, B0_HWE_IMSK, pAC->GIni.GIValHwIrqMask);
+	}
+#endif /* YUKON */
 }	/* SkGeInit2 */
 
+
 /******************************************************************************
  *
  *	SkGeInit() - Initialize the GE Adapter with the specified level.
@@ -1888,7 +2508,7 @@
  *				if Number of MACs > SK_MAX_MACS
  *
  *			After returning from Level 0 the adapter
- *			may be accessed with IO operations.
+ *			may be accessed with I/O operations.
  *
  *	Level	2:	start the Blink Source Counter
  *
@@ -1897,14 +2517,14 @@
  *	1:	Number of MACs exceeds SK_MAX_MACS	(after level 1)
  *	2:	Adapter not present or not accessible
  *	3:	Illegal initialization level
- *	4:	Initialization Level 1 Call missing
+ *	4:	Initialization level 1 call missing
  *	5:	Unexpected PHY type detected
  *	6:	HW self test failed
  */
 int	SkGeInit(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
-int		Level)		/* initialization level */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
+int		Level)		/* Initialization Level */
 {
 	int		RetVal;		/* return value */
 	SK_U32	DWord;
@@ -1919,7 +2539,7 @@
 		SkGeInit0(pAC, IoC);
 		pAC->GIni.GILevel = SK_INIT_DATA;
 		break;
-	
+
 	case SK_INIT_IO:
 		/* Initialization Level 1 */
 		RetVal = SkGeInit1(pAC, IoC);
@@ -1931,22 +2551,24 @@
 		SK_OUT32(IoC, B2_IRQM_INI, SK_TEST_VAL);
 		SK_IN32(IoC, B2_IRQM_INI, &DWord);
 		SK_OUT32(IoC, B2_IRQM_INI, 0L);
-		
+
 		if (DWord != SK_TEST_VAL) {
 			RetVal = 2;
 			break;
 		}
 
+#ifdef DEBUG
 		/* check if the number of GIMacsFound matches SK_MAX_MACS */
 		if (pAC->GIni.GIMacsFound > SK_MAX_MACS) {
 			RetVal = 1;
 			break;
 		}
+#endif /* DEBUG */
 
 		/* Level 1 successfully passed */
 		pAC->GIni.GILevel = SK_INIT_IO;
 		break;
-	
+
 	case SK_INIT_RUN:
 		/* Initialization Level 2 */
 		if (pAC->GIni.GILevel != SK_INIT_IO) {
@@ -1956,12 +2578,13 @@
 			RetVal = 4;
 			break;
 		}
+
 		SkGeInit2(pAC, IoC);
 
 		/* Level 2 successfully passed */
 		pAC->GIni.GILevel = SK_INIT_RUN;
 		break;
-	
+
 	default:
 		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG);
 		RetVal = 3;
@@ -1984,77 +2607,79 @@
  *	nothing
  */
 void SkGeDeInit(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC)		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC)		/* I/O Context */
 {
 	int	i;
 	SK_U16	Word;
 
-#ifdef SK_PHY_LP_MODE
-	SK_U8	Byte;
+#ifdef SK_PHY_LP_MODE_DEEP_SLEEP
 	SK_U16	PmCtlSts;
-#endif /* SK_PHY_LP_MODE */
+#endif
 
 #if (!defined(SK_SLIM) && !defined(VCPU))
 	/* ensure I2C is ready */
 	SkI2cWaitIrq(pAC, IoC);
-#endif	
-
-	/* stop all current transfer activity */
-	for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-		if (pAC->GIni.GP[i].PState != SK_PRT_STOP &&
-			pAC->GIni.GP[i].PState != SK_PRT_RESET) {
-
-			SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST);
-		}
-	}
+#endif
 
-#ifdef SK_PHY_LP_MODE
-    /*
+#ifdef SK_PHY_LP_MODE_DEEP_SLEEP
+	/*
 	 * for power saving purposes within mobile environments
-	 * we set the PHY to coma mode and switch to D3 power state.
+	 * we set the PHY to coma mode.
 	 */
-	if (pAC->GIni.GIYukonLite &&
-		pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+#ifndef SK_DIAG
+	if (pAC->GIni.GIVauxAvail) {
+		/* switch power to VAUX */
+		SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA |
+			PC_VAUX_ON | PC_VCC_OFF));
+	}
+#endif /* SK_DIAG */
+
+	if (CHIP_ID_YUKON_2(pAC) && !pAC->GIni.GIAsfEnabled
+#ifdef XXX
+		|| pAC->GIni.GIYukonLite &&
+		pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3
+#endif
+		) {
 
 		/* for all ports switch PHY to coma mode */
 		for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-			
-			SkGmEnterLowPowerMode(pAC, IoC, i, PHY_PM_DEEP_SLEEP);
-		}
-
-		if (pAC->GIni.GIVauxAvail) {
-			/* switch power to VAUX */
-			Byte = PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF;
 
-			SK_OUT8(IoC, B0_POWER_CTRL, Byte);
+			(void)SkGmEnterLowPowerMode(pAC, IoC, i, PHY_PM_DEEP_SLEEP);
 		}
-		
-		/* switch to D3 state */
-		SK_IN16(IoC, PCI_C(PCI_PM_CTL_STS), &PmCtlSts);
-
-		PmCtlSts |= PCI_PM_STATE_D3;
+	}
+#else /* !SK_PHY_LP_MODE_DEEP_SLEEP */
 
-		SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+	if (!pAC->GIni.GIAsfEnabled) {
+		/* stop all current transfer activity */
+		for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+			if (pAC->GIni.GP[i].PState != SK_PRT_STOP &&
+				pAC->GIni.GP[i].PState != SK_PRT_RESET) {
 
-		SK_OUT16(IoC, PCI_C(PCI_PM_CTL_STS), PmCtlSts);
+				SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST);
+			}
+		}
 	}
-#endif /* SK_PHY_LP_MODE */
 
 	/* Reset all bits in the PCI STATUS register */
 	/*
 	 * Note: PCI Cfg cycles cannot be used, because they are not
 	 *	 available on some platforms after 'boot time'.
 	 */
-	SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
-	
+	SK_IN16(IoC, PCI_C(pAC, PCI_STATUS), &Word);
+
 	SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-	SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
+
+	SK_OUT16(IoC, PCI_C(pAC, PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
+
 	SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 
-	/* do the reset, all LEDs are switched off now */
-	SK_OUT8(IoC, B0_CTST, CS_RST_SET);
-	
+	if (!pAC->GIni.GIAsfEnabled) {
+		/* set the SW-reset */
+		SK_OUT8(IoC, B0_CTST, CS_RST_SET);
+	}
+#endif /* !SK_PHY_LP_MODE_DEEP_SLEEP */
+
 	pAC->GIni.GILevel = SK_INIT_DATA;
 }	/* SkGeDeInit */
 
@@ -2088,8 +2713,8 @@
  *	2:	The port has to be stopped before it can be initialized again.
  */
 int SkGeInitPort(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port to configure */
 {
 	SK_GEPORT *pPrt;
@@ -2100,8 +2725,8 @@
 		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG);
 		return(1);
 	}
-	
-	if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) {
+
+	if (pPrt->PState >= SK_PRT_INIT) {
 		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG);
 		return(2);
 	}
@@ -2118,29 +2743,29 @@
 		SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
 		SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA);
 		/* The Link LED is initialized by RLMT or Diagnostics itself */
-		
+
 		SkXmInitMac(pAC, IoC, Port);
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
 
 		SkGmInitMac(pAC, IoC, Port);
 	}
 #endif /* YUKON */
-	
+
 	/* do NOT initialize the Link Sync Counter */
 
 	SkGeInitMacFifo(pAC, IoC, Port);
-	
+
 	SkGeInitRamBufs(pAC, IoC, Port);
-	
+
 	if (pPrt->PXSQSize != 0) {
 		/* enable Force Sync bit if synchronous queue available */
 		SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC);
 	}
-	
+
 	SkGeInitBmu(pAC, IoC, Port);
 
 	/* mark port as initialized */
@@ -2148,3 +2773,4 @@
 
 	return(0);
 }	/* SkGeInitPort */
+
diff -urN linux-2.4.29/drivers/net/sk98lin/skgemib.c linux-2.4.29-uc1/drivers/net/sk98lin/skgemib.c
--- linux-2.4.29/drivers/net/sk98lin/skgemib.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/skgemib.c	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skgemib.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:	$Revision: 2.6 $
+ * Date:	$Date: 2004/06/14 06:51:42 $
  * Purpose:	Private Network Management Interface Management Database
  *
  ****************************************************************************/
@@ -249,6 +251,168 @@
 		0,
 		SK_PNMI_RW, DiagActions, 0},
 #endif /* SK_DIAG_SUPPORT */
+#ifdef SK_ASF
+    {OID_SKGE_ASF,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_STORE_CONFIG,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_ENA,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_RETRANS,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_RETRANS_INT,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_HB_ENA,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_HB_INT,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_WD_ENA,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_WD_TIME,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_IP_SOURCE,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_MAC_SOURCE,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_IP_DEST,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_MAC_DEST,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_COMMUNITY_NAME,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_RSP_ENA,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_RETRANS_COUNT_MIN,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_RETRANS_COUNT_MAX,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_RETRANS_INT_MIN,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_RETRANS_INT_MAX,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_HB_INT_MIN,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_HB_INT_MAX,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_WD_TIME_MIN,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_WD_TIME_MAX,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_HB_CAP,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_WD_TIMER_RES,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_GUID,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_KEY_OP,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_KEY_ADM,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_KEY_GEN,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_CAP,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_PAR_1,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+    {OID_SKGE_ASF_OVERALL_OID,
+        0,
+        0,
+        0,
+        SK_PNMI_RW, Asf, 0},
+#endif /* SK_ASF */
 	{OID_SKGE_MDB_VERSION,
 		1,
 		0,
@@ -1071,6 +1235,11 @@
 		0,
 		0,
 		SK_PNMI_RO, Vct, 0},
+	{OID_SKGE_VCT_CAPABILITIES,
+		0,
+		0,
+		0,
+		SK_PNMI_RO, Vct, 0},
 	{OID_SKGE_BOARDLEVEL,
 		0,
 		0,
diff -urN linux-2.4.29/drivers/net/sk98lin/skgepnmi.c linux-2.4.29-uc1/drivers/net/sk98lin/skgepnmi.c
--- linux-2.4.29/drivers/net/sk98lin/skgepnmi.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/skgepnmi.c	2005-06-14 02:12:09.000000000 +0100
@@ -1,7 +1,9 @@
 /*****************************************************************************
  *
  * Name:	skgepnmi.c
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
+ * Project:	Gigabit Ethernet Adapters, PNMI-Module
+ * Version:	$Revision: 2.13 $
+ * Date:	$Date: 2004/06/14 06:50:30 $
  * Purpose:	Private Network Management Interface
  *
  ****************************************************************************/
@@ -20,10 +22,10 @@
  *
  ******************************************************************************/
 
-#ifndef _lint
+#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell.";
-#endif /* !_lint */
+	"@(#) $Id: skgepnmi.c,v 2.13 2004/06/14 06:50:30 tschilli Exp $ (C) Marvell.";
+#endif
 
 #include "h/skdrv1st.h"
 #include "h/sktypes.h"
@@ -35,12 +37,14 @@
 #include "h/skcsum.h"
 #include "h/skvpd.h"
 #include "h/skgehw.h"
+#include "h/sky2le.h"
 #include "h/skgeinit.h"
 #include "h/skdrv2nd.h"
 #include "h/skgepnm2.h"
 #ifdef SK_POWER_MGMT
 #include "h/skgepmgt.h"
-#endif
+#endif /* SK_POWER_MGMT */
+
 /* defines *******************************************************************/
 
 #ifndef DEBUG
@@ -69,7 +73,6 @@
 int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
 	unsigned int * pLen, SK_U32 NetIndex);
 
-
 /*
  * Private Function prototypes
  */
@@ -109,6 +112,12 @@
 PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
 	unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
 PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
+PNMI_STATIC void VctGetResults(SK_AC *, SK_IOC, SK_U32);
+#ifdef SK_ASF
+PNMI_STATIC int Asf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
+    char *pBuf, unsigned int *pLen, SK_U32 Instance,
+    unsigned int TableIndex, SK_U32 NetIndex);
+#endif /* SK_ASF */
 
 /*
  * Table to correlate OID with handler function and index to
@@ -350,17 +359,13 @@
  *	Always 0
  */
 int SkPnmiInit(
-SK_AC *pAC,		/* Pointer to adapter context */
-SK_IOC IoC,		/* IO context handle */
-int Level)		/* Initialization level */
+SK_AC	*pAC,		/* Pointer to adapter context */
+SK_IOC	IoC,		/* IO context handle */
+int		Level)		/* Initialization level */
 {
 	unsigned int	PortMax;	/* Number of ports */
 	unsigned int	PortIndex;	/* Current port index in loop */
-	SK_U16		Val16;		/* Multiple purpose 16 bit variable */
-	SK_U8		Val8;		/* Mulitple purpose 8 bit variable */
-	SK_EVPARA	EventParam;	/* Event struct for timer event */
-	SK_PNMI_VCT	*pVctBackupData;
-
+	SK_EVPARA		EventParam;	/* Event struct for timer event */
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 		("PNMI: SkPnmiInit: Called, level=%d\n", Level));
@@ -369,9 +374,11 @@
 
 	case SK_INIT_DATA:
 		SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
+		
 		pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
 		pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
 		pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
+		
 		for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
 
 			pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
@@ -405,51 +412,42 @@
 		break;
 
 	case SK_INIT_IO:
-		/*
-		 * Reset MAC counters
-		 */
+
+		/* Reset MAC counters. */
 		PortMax = pAC->GIni.GIMacsFound;
 
 		for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
 
 			pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
 		}
-		
+
 		/* Initialize DSP variables for Vct() to 0xff => Never written! */		
 		for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
 			pAC->GIni.GP[PortIndex].PCableLen = 0xff;
-			pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
-			pVctBackupData->PCableLen = 0xff;
+			pAC->Pnmi.VctBackup[PortIndex].CableLen = 0xff;
 		}
-		
-		/*
-		 * Get pci bus speed
-		 */
-		SK_IN16(IoC, B0_CTST, &Val16);
-		if ((Val16 & CS_BUS_CLOCK) == 0) {
 
-			pAC->Pnmi.PciBusSpeed = 33;
+		/* Get PCI bus speed. */
+		if (pAC->GIni.GIPciClock66) {
+
+			pAC->Pnmi.PciBusSpeed = 66;
 		}
 		else {
-			pAC->Pnmi.PciBusSpeed = 66;
+			pAC->Pnmi.PciBusSpeed = 33;
 		}
 
-		/*
-		 * Get pci bus width
-		 */
-		SK_IN16(IoC, B0_CTST, &Val16);
-		if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
+		/* Get PCI bus width. */
+		if (pAC->GIni.GIPciSlot64) {
 
-			pAC->Pnmi.PciBusWidth = 32;
+			pAC->Pnmi.PciBusWidth = 64;
 		}
 		else {
-			pAC->Pnmi.PciBusWidth = 64;
+			pAC->Pnmi.PciBusWidth = 32;
 		}
 
-		/*
-		 * Get chipset
-		 */
+		/* Get chipset. */
 		switch (pAC->GIni.GIChipId) {
+		
 		case CHIP_ID_GENESIS:
 			pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
 			break;
@@ -462,53 +460,27 @@
 			break;
 		}
 
-		/*
-		 * Get PMD and DeviceType
-		 */
-		SK_IN8(IoC, B2_PMD_TYP, &Val8);
-		switch (Val8) {
+		/* Get PMD and Device Type. */
+		switch (pAC->GIni.GIPmdTyp) {
+		
 		case 'S':
 			pAC->Pnmi.PMD = 3;
-			if (pAC->GIni.GIMacsFound > 1) {
-
-				pAC->Pnmi.DeviceType = 0x00020002;
-			}
-			else {
-				pAC->Pnmi.DeviceType = 0x00020001;
-			}
+			pAC->Pnmi.DeviceType = 0x00020001;
 			break;
 
 		case 'L':
 			pAC->Pnmi.PMD = 2;
-			if (pAC->GIni.GIMacsFound > 1) {
-
-				pAC->Pnmi.DeviceType = 0x00020004;
-			}
-			else {
-				pAC->Pnmi.DeviceType = 0x00020003;
-			}
+			pAC->Pnmi.DeviceType = 0x00020003;
 			break;
 
 		case 'C':
 			pAC->Pnmi.PMD = 4;
-			if (pAC->GIni.GIMacsFound > 1) {
-
-				pAC->Pnmi.DeviceType = 0x00020006;
-			}
-			else {
-				pAC->Pnmi.DeviceType = 0x00020005;
-			}
+			pAC->Pnmi.DeviceType = 0x00020005;
 			break;
 
 		case 'T':
 			pAC->Pnmi.PMD = 5;
-			if (pAC->GIni.GIMacsFound > 1) {
-
-				pAC->Pnmi.DeviceType = 0x00020008;
-			}
-			else {
-				pAC->Pnmi.DeviceType = 0x00020007;
-			}
+			pAC->Pnmi.DeviceType = 0x00020007;
 			break;
 
 		default :
@@ -517,11 +489,14 @@
 			break;
 		}
 
-		/*
-		 * Get connector
-		 */
-		SK_IN8(IoC, B2_CONN_TYP, &Val8);
-		switch (Val8) {
+		if (pAC->GIni.GIMacsFound > 1) {
+
+			pAC->Pnmi.DeviceType++;
+		}
+		
+		/* Get connector type. */
+		switch (pAC->GIni.GIConTyp) {
+		
 		case 'C':
 			pAC->Pnmi.Connector = 2;
 			break;
@@ -549,17 +524,17 @@
 		break;
 
 	case SK_INIT_RUN:
-		/*
-		 * Start timer for RLMT change counter
-		 */
+
+		/* Start timer for RLMT change counter. */
 		SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
+		
 		SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
-			28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
+			SK_PNMI_EVT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
 			EventParam);
 		break;
 
 	default:
-		break; /* Nothing todo */
+		break; /* Nothing to do. */
 	}
 
 	return (0);
@@ -639,7 +614,6 @@
 		("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
 			Id, *pLen, Instance, NetIndex));
 
-
 	return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
 		Instance, NetIndex));
 }
@@ -721,7 +695,6 @@
 	unsigned int	TmpLen;
 	char		KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
 
-
 	SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
 		("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
 			*pLen, NetIndex));
@@ -730,22 +703,19 @@
 
 		if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
 
-			SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
-				(SK_U32)(-1));
+			SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT, (SK_U32)(-1));
 		}
 
 		*pLen = SK_PNMI_STRUCT_SIZE;
 		return (SK_PNMI_ERR_TOO_SHORT);
 	}
 
-    /*
-     * Check NetIndex
-     */
+	/* Check NetIndex. */
 	if (NetIndex >= pAC->Rlmt.NumNets) {
 		return (SK_PNMI_ERR_UNKNOWN_NET);
 	}
 
-	/* Update statistic */
+	/* Update statistics. */
 	SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
 
 	if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
@@ -770,15 +740,12 @@
 		return (Ret);
 	}
 
-	/*
-	 * Increment semaphores to indicate that an update was
-	 * already done
-	 */
+	/* Increment semaphores to indicate that an update was already done. */
 	pAC->Pnmi.MacUpdatedFlag ++;
 	pAC->Pnmi.RlmtUpdatedFlag ++;
 	pAC->Pnmi.SirqUpdatedFlag ++;
 
-	/* Get vpd keys for instance calculation */
+	/* Get VPD keys for instance calculation. */
 	Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
 	if (Ret != SK_PNMI_ERR_OK) {
 
@@ -792,13 +759,13 @@
 		return (SK_PNMI_ERR_GENERAL);
 	}
 
-	/* Retrieve values */
+	/* Retrieve values. */
 	SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
+	
 	for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
 
 		InstanceNo = IdTable[TableIndex].InstanceNo;
-		for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
-			InstanceCnt ++) {
+		for (InstanceCnt = 1; InstanceCnt <= InstanceNo; InstanceCnt ++) {
 
 			DstOffset = IdTable[TableIndex].Offset +
 				(InstanceCnt - 1) *
@@ -995,7 +962,6 @@
 	unsigned int	PhysPortIndex;
     unsigned int	MaxNetNumber;
 	int			CounterIndex;
-	int			Ret;
 	SK_U16		MacStatus;
 	SK_U64		OverflowStatus;
 	SK_U64		Mask;
@@ -1009,12 +975,7 @@
 	SK_U64		Delta;
 	SK_PNMI_ESTIMATE *pEst;
 	SK_U32		NetIndex;
-	SK_GEPORT	*pPrt;
-	SK_PNMI_VCT	*pVctBackupData;
 	SK_U32		RetCode;
-	int		i;
-	SK_U32		CableLength;
-
 
 #ifdef DEBUG
 	if (Event != SK_PNMI_EVT_XMAC_RESET) {
@@ -1045,9 +1006,7 @@
 #endif /* DEBUG */
 		OverflowStatus = 0;
 
-		/*
-		 * Check which source caused an overflow interrupt.
-		 */
+		/* Check which source caused an overflow interrupt. */
 		if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
 				MacStatus, &OverflowStatus) != 0) ||
 			(OverflowStatus == 0)) {
@@ -1065,7 +1024,6 @@
 
 			Mask = (SK_U64)1 << CounterIndex;
 			if ((OverflowStatus & Mask) == 0) {
-
 				continue;
 			}
 
@@ -1097,9 +1055,7 @@
 			case SK_PNMI_HRX_IRLENGTH:
 			case SK_PNMI_HRX_RESERVED:
 			
-			/*
-			 * the following counters aren't be handled (id > 63)
-			 */
+			/* The following counters aren't be handled (id > 63). */
 			case SK_PNMI_HTX_SYNC:
 			case SK_PNMI_HTX_SYNC_OCTET:
 				break;
@@ -1186,7 +1142,7 @@
 		if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
 
 			SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
-				("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
+				("PNMI: ERR: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
 				(unsigned int)Param.Para64));
 			return (0);
 		}
@@ -1205,16 +1161,14 @@
 	case SK_PNMI_EVT_CHG_EST_TIMER:
 		/*
 		 * Calculate port switch average on a per hour basis
-		 *   Time interval for check       : 28125 ms
+		 *   Time interval for check       : 28125 ms (SK_PNMI_EVT_TIMER_CHECK)
 		 *   Number of values for average  : 8
 		 *
 		 * Be careful in changing these values, on change check
 		 *   - typedef of SK_PNMI_ESTIMATE (Size of EstValue
 		 *     array one less than value number)
 		 *   - Timer initialization SkTimerStart() in SkPnmiInit
-		 *   - Delta value below must be multiplicated with
-		 *     power of 2
-		 *
+		 *   - Delta value below must be multiplicated with power of 2
 		 */
 		pEst = &pAC->Pnmi.RlmtChangeEstimate;
 		CounterIndex = pEst->EstValueIndex + 1;
@@ -1237,7 +1191,7 @@
 			Delta = NewestValue - OldestValue;
 		}
 		else {
-			/* Overflow situation */
+			/* Overflow situation. */
 			Delta = (SK_U64)(0 - OldestValue) + NewestValue;
 		}
 
@@ -1263,8 +1217,9 @@
 		}
 
 		SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
+		
 		SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
-			28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
+			SK_PNMI_EVT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
 			EventParam);
 		break;
 
@@ -1308,29 +1263,25 @@
 				(unsigned int)Param.Para64));
 			return (0);
 		}
-#endif
+#endif /* DEBUG */
+
 		PhysPortIndex = (unsigned int)Param.Para64;
 
-		/*
-		 * Update XMAC statistic to get fresh values
-		 */
-		Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
-		if (Ret != SK_PNMI_ERR_OK) {
+		/* Update XMAC statistic to get fresh values. */
+		if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
+			SK_PNMI_ERR_OK) {
 
 			SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
 			return (0);
 		}
-		/*
-		 * Increment semaphore to indicate that an update was
-		 * already done
-		 */
+
+		/* Increment semaphore to indicate that an update was already done. */
 		pAC->Pnmi.MacUpdatedFlag ++;
 
 		for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
 			CounterIndex ++) {
 
 			if (!StatAddr[CounterIndex][MacType].GetOffset) {
-
 				continue;
 			}
 
@@ -1363,14 +1314,15 @@
 		QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
 		(void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
-		/* Bugfix for XMAC errata (#10620)*/
+		/* Bugfix for XMAC errata (#10620). */
 		if (MacType == SK_MAC_XMAC) {
-			/* Add incremental difference to offset (#10620)*/
+			/* Add incremental difference to offset (#10620). */
 			(void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
 				XM_RXE_SHT_ERR, &Val32);
 			
 			Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
 				 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
+			
 			pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
 				Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
 		}
@@ -1400,7 +1352,7 @@
 		QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
 		(void)SK_DRIVER_SENDEVENT(pAC, IoC);
 
-		/* Bugfix #10620 - get zero level for incremental difference */
+		/* Bugfix #10620 - get zero level for incremental difference. */
 		if (MacType == SK_MAC_XMAC) {
 
 			(void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
@@ -1432,17 +1384,13 @@
 		}
 #endif /* DEBUG */
 
-		/*
-		 * For now, ignore event if NetIndex != 0.
-		 */
+		/* For now, ignore event if NetIndex != 0. */
 		if (Param.Para32[1] != 0) {
 
 			return (0);
 		}
 
-		/*
-		 * Nothing to do if port is already inactive
-		 */
+		/* Nothing to do if port is already inactive. */
 		if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
 			return (0);
@@ -1473,7 +1421,6 @@
 			CounterIndex ++) {
 
 			if (!StatAddr[CounterIndex][MacType].GetOffset) {
-
 				continue;
 			}
 
@@ -1482,9 +1429,7 @@
 			pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
 		}
 
-		/*
-		 * Set port to inactive
-		 */
+		/* Set port to inactive. */
 		pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
 
 		pAC->Pnmi.MacUpdatedFlag --;
@@ -1510,25 +1455,19 @@
 		}
 #endif /* DEBUG */
 
-		/*
-		 * For now, ignore event if NetIndex != 0.
-		 */
+		/* For now, ignore event if NetIndex != 0. */
 		if (Param.Para32[1] != 0) {
 
 			return (0);
 		}
 
-		/*
-		 * Nothing to do if port is already active
-		 */
+		/* Nothing to do if port is already inactive. */
 		if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
 
 			return (0);
 		}
 
-		/*
-		 * Statistic maintenance
-		 */
+		/* Statistic maintenance. */
 		pAC->Pnmi.RlmtChangeCts ++;
 		pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
 
@@ -1562,7 +1501,6 @@
 			CounterIndex ++) {
 
 			if (!StatAddr[CounterIndex][MacType].GetOffset) {
-
 				continue;
 			}
 
@@ -1571,16 +1509,14 @@
 			pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
 		}
 
-		/* Set port to active */
+		/* Set port to active. */
 		pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
 
 		pAC->Pnmi.MacUpdatedFlag --;
 		break;
 
 	case SK_PNMI_EVT_RLMT_SEGMENTATION:
-		/*
-		 * Para.Para32[0] contains the NetIndex.
-		 */
+		/* Para.Para32[0] contains the NetIndex. */
 
 		/*
 		 * Store a trap message in the trap buffer and generate an event for
@@ -1595,71 +1531,53 @@
 		 *  Param.Para32[0] contains the number of Nets.
 		 *  Param.Para32[1] is reserved, contains -1.
 		 */
-	    /*
-    	 * Check number of nets
-		 */
+	    /* Check number of nets. */
 		MaxNetNumber = pAC->GIni.GIMacsFound;
-		if (((unsigned int)Param.Para32[0] < 1)
-			|| ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
+		
+		if (((unsigned int)Param.Para32[0] < 1) ||
+			((unsigned int)Param.Para32[0] > MaxNetNumber)) {
+			
 			return (SK_PNMI_ERR_UNKNOWN_NET);
 		}
 
-        if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
+        if ((unsigned int)Param.Para32[0] == 1) { /* SingleNet mode. */
         	pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
         }
-        else { /* dual net mode */
+        else { /* DualNet mode. */
         	pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
         }
         break;
 
     case SK_PNMI_EVT_VCT_RESET:
 		PhysPortIndex = Param.Para32[0];
-		pPrt = &pAC->GIni.GP[PhysPortIndex];
-		pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
 		
 		if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
+			
 			RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
+			
 			if (RetCode == 2) {
 				/*
 				 * VCT test is still running.
 				 * Start VCT timer counter again.
 				 */
-				SK_MEMSET((char *) &Param, 0, sizeof(Param));
+				SK_MEMSET((char *)&Param, 0, sizeof(Param));
+				
 				Param.Para32[0] = PhysPortIndex;
 				Param.Para32[1] = -1;
-				SkTimerStart(pAC, IoC,
-					&pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
-				4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
+				
+				SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex],
+					SK_PNMI_VCT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
+				
 				break;
 			}
-			pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
-			pAC->Pnmi.VctStatus[PhysPortIndex] |=
-				(SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
 			
-			/* Copy results for later use to PNMI struct. */
-			for (i = 0; i < 4; i++)  {
-				if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
-					if ((pPrt->PMdiPairLen[i] > 35) &&
-						(pPrt->PMdiPairLen[i] < 0xff)) {
-						pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
-					}
-				}
-				if ((pPrt->PMdiPairLen[i] > 35) &&
-					(pPrt->PMdiPairLen[i] != 0xff)) {
-					CableLength = 1000 *
-						(((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
-				}
-				else {
-					CableLength = 0;
-				}
-				pVctBackupData->PMdiPairLen[i] = CableLength;
-				pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
-			}
+			VctGetResults(pAC, IoC, PhysPortIndex);
 			
-			Param.Para32[0] = PhysPortIndex;
-			Param.Para32[1] = -1;
-			SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
-			SkEventDispatcher(pAC, IoC);
+			EventParam.Para32[0] = PhysPortIndex;
+			EventParam.Para32[1] = -1;
+			SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, EventParam);
+
+			/* SkEventDispatcher(pAC, IoC); */
 		}
 		
 		break;
@@ -1707,14 +1625,13 @@
 	unsigned int	TableIndex;
 	int		Ret;
 
-
 	if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
 
 		*pLen = 0;
 		return (SK_PNMI_ERR_UNKNOWN_OID);
 	}
 	
-    /* Check NetIndex */
+    /* Check NetIndex. */
 	if (NetIndex >= pAC->Rlmt.NumNets) {
 		return (SK_PNMI_ERR_UNKNOWN_NET);
 	}
@@ -1764,22 +1681,20 @@
 	SK_U32		Instance;
 	SK_U32		Id;
 
-
-	/* Check if the passed buffer has the right size */
+	/* Check if the passed buffer has the right size. */
 	if (*pLen < SK_PNMI_STRUCT_SIZE) {
 
-		/* Check if we can return the error within the buffer */
+		/* Check if we can return the error within the buffer. */
 		if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
 
-			SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
-				(SK_U32)(-1));
+			SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT, (SK_U32)(-1));
 		}
 
 		*pLen = SK_PNMI_STRUCT_SIZE;
 		return (SK_PNMI_ERR_TOO_SHORT);
 	}
 	
-    /* Check NetIndex */
+    /* Check NetIndex. */
 	if (NetIndex >= pAC->Rlmt.NumNets) {
 		return (SK_PNMI_ERR_UNKNOWN_NET);
 	}
@@ -1807,12 +1722,11 @@
 	pAC->Pnmi.RlmtUpdatedFlag ++;
 	pAC->Pnmi.SirqUpdatedFlag ++;
 
-	/* Preset/Set values */
+	/* PRESET/SET values. */
 	for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
 
 		if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
 			(IdTable[TableIndex].Access != SK_PNMI_WO)) {
-
 			continue;
 		}
 
@@ -1823,8 +1737,7 @@
 			InstanceCnt ++) {
 
 			DstOffset = IdTable[TableIndex].Offset +
-				(InstanceCnt - 1) *
-				IdTable[TableIndex].StructSize;
+				(InstanceCnt - 1) * IdTable[TableIndex].StructSize;
 
 			/*
 			 * Because VPD multiple instance variables are
@@ -1834,9 +1747,7 @@
 			 */
 			Instance = (SK_U32)InstanceCnt;
 
-			/*
-			 * Evaluate needed buffer length
-			 */
+			/* Evaluate needed buffer length. */
 			Len = 0;
 			Ret = IdTable[TableIndex].Func(pAC, IoC,
 				SK_PNMI_GET, IdTable[TableIndex].Id,
@@ -1852,8 +1763,7 @@
 				pAC->Pnmi.SirqUpdatedFlag --;
 
 				SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
-				SK_PNMI_SET_STAT(pBuf,
-					SK_PNMI_ERR_GENERAL, DstOffset);
+				SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_GENERAL, DstOffset);
 				*pLen = SK_PNMI_MIN_STRUCT_SIZE;
 				return (SK_PNMI_ERR_GENERAL);
 			}
@@ -1875,7 +1785,7 @@
 				}
 			}
 
-			/* Call the OID handler function */
+			/* Call the OID handler function. */
 			Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
 				IdTable[TableIndex].Id, pBuf + DstOffset,
 				&Len, Instance, TableIndex, NetIndex);
@@ -1886,8 +1796,7 @@
 				pAC->Pnmi.SirqUpdatedFlag --;
 
 				SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
-				SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
-					DstOffset);
+				SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE, DstOffset);
 				*pLen = SK_PNMI_MIN_STRUCT_SIZE;
 				return (SK_PNMI_ERR_BAD_VALUE);
 			}
@@ -1921,7 +1830,7 @@
 
 		if (IdTable[i].Id == Id) {
 
-			return i;
+			return (i);
 		}
 	}
 
@@ -1962,16 +1871,13 @@
 {
 	if (Id != OID_SKGE_ALL_DATA) {
 
-		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
-			SK_PNMI_ERR003MSG);
+		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003, SK_PNMI_ERR003MSG);
 
 		*pLen = 0;
 		return (SK_PNMI_ERR_GENERAL);
 	}
 
-	/*
-	 * Check instance. We only handle single instance variables
-	 */
+	/* Check instance. We only handle single instance variables. */
 	if (Instance != (SK_U32)(-1) && Instance != 1) {
 
 		*pLen = 0;
@@ -2030,10 +1936,7 @@
 	int	Ret;
 	SK_U32	ActionOp;
 
-
-	/*
-	 * Check instance. We only handle single instance variables
-	 */
+	/* Check instance. We only handle single instance variables. */
 	if (Instance != (SK_U32)(-1) && Instance != 1) {
 
 		*pLen = 0;
@@ -2046,10 +1949,10 @@
 		return (SK_PNMI_ERR_TOO_SHORT);
 	}
 
-	/* Check if a get should be performed */
+	/* Check if a GET should be performed. */
 	if (Action == SK_PNMI_GET) {
 
-		/* A get is easy. We always return the same value */
+		/* A GET is easy. We always return the same value. */
 		ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
 		SK_PNMI_STORE_U32(pBuf, ActionOp);
 		*pLen = sizeof(SK_U32);
@@ -2057,13 +1960,13 @@
 		return (SK_PNMI_ERR_OK);
 	}
 
-	/* Continue with PRESET/SET action */
+	/* Continue with PRESET/SET action. */
 	if (*pLen > sizeof(SK_U32)) {
 
 		return (SK_PNMI_ERR_BAD_VALUE);
 	}
 
-	/* Check if the command is a known one */
+	/* Check if the command is a known one. */
 	SK_PNMI_READ_U32(pBuf, ActionOp);
 	if (*pLen > sizeof(SK_U32) ||
 		(ActionOp != SK_PNMI_ACT_IDLE &&
@@ -2075,7 +1978,7 @@
 		return (SK_PNMI_ERR_BAD_VALUE);
 	}
 
-	/* A preset ends here */
+	/* A PRESET ends here. */
 	if (Action == SK_PNMI_PRESET) {
 
 		return (SK_PNMI_ERR_OK);
@@ -2084,19 +1987,15 @@
 	switch (ActionOp) {
 
 	case SK_PNMI_ACT_IDLE:
-		/* Nothing to do */
+		/* Nothing to do. */
 		break;
 
 	case SK_PNMI_ACT_RESET:
-		/*
-		 * Perform a driver reset or something that comes near
-		 * to this.
-		 */
+		/* Perform a driver reset or something that comes near to this. */
 		Ret = SK_DRIVER_RESET(pAC, IoC);
 		if (Ret != 0) {
 
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
-				SK_PNMI_ERR005MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005, SK_PNMI_ERR005MSG);
 
 			return (SK_PNMI_ERR_GENERAL);
 		}
@@ -2113,13 +2012,12 @@
 		break;
 
 	case SK_PNMI_ACT_RESETCNT:
-		/* Set all counters and timestamps to zero */
+		/* Set all counters and timestamps to zero. */
 		ResetCounter(pAC, IoC, NetIndex);
 		break;
 
 	default:
-		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
-			SK_PNMI_ERR006MSG);
+		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006, SK_PNMI_ERR006MSG);
 
 		return (SK_PNMI_ERR_GENERAL);
 	}
@@ -2163,25 +2061,21 @@
 	SK_U32  StatVal32;
 	SK_BOOL Is64BitReq = SK_FALSE;
 
-	/*
-	 * Only the active Mac is returned
-	 */
+	/* Only the active MAC is returned. */
 	if (Instance != (SK_U32)(-1) && Instance != 1) {
 
 		*pLen = 0;
 		return (SK_PNMI_ERR_UNKNOWN_INST);
 	}
 
-	/*
-	 * Check action type
-	 */
+	/* Check action type. */
 	if (Action != SK_PNMI_GET) {
 
 		*pLen = 0;
 		return (SK_PNMI_ERR_READ_ONLY);
 	}
 
-	/* Check length */
+	/* Check length. */
 	switch (Id) {
 
 	case OID_802_3_PERMANENT_ADDRESS:
@@ -2202,12 +2096,12 @@
 
 #else /* SK_NDIS_64BIT_CTR */
 
-		/* for compatibility, at least 32bit are required for OID */
+		/* For compatibility, at least 32 bits are required for OID. */
 		if (*pLen < sizeof(SK_U32)) {
 			/*
-			* but indicate handling for 64bit values,
-			* if insufficient space is provided
-			*/
+			 * Indicate handling for 64 bit values,
+			 * if insufficient space is provided.
+			 */
 			*pLen = sizeof(SK_U64);
 			return (SK_PNMI_ERR_TOO_SHORT);
 		}
@@ -2223,16 +2117,14 @@
 	 * to indicate that an update was already done.
 	 */
 	Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
-	if ( Ret != SK_PNMI_ERR_OK) {
+	if (Ret != SK_PNMI_ERR_OK) {
 
 		*pLen = 0;
 		return (Ret);
 	}
 	pAC->Pnmi.MacUpdatedFlag ++;
 
-	/*
-	 * Get value (MAC Index 0 identifies the virtual MAC)
-	 */
+	/* Get value (MAC index 0 identifies the virtual MAC). */
 	switch (Id) {
 
 	case OID_802_3_PERMANENT_ADDRESS:
@@ -2248,7 +2140,7 @@
 	default:
 		StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
 
-		/* by default 32bit values are evaluated */
+		/* By default 32 bit values are evaluated. */
 		if (!Is64BitReq) {
 			StatVal32 = (SK_U32)StatVal;
 			SK_PNMI_STORE_U32(pBuf, StatVal32);
@@ -2302,21 +2194,19 @@
 	int				MacType;
 	int				Ret;
 	SK_U64			StatVal;
-	
-	
 
-	/* Calculate instance if wished. MAC index 0 is the virtual MAC */
+	/* Calculate instance if wished. MAC index 0 is the virtual MAC. */
 	PhysPortMax = pAC->GIni.GIMacsFound;
 	LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
 	
 	MacType = pAC->GIni.GIMacType;
 
-	if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
+	if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* DualNet mode. */
 		LogPortMax--;
 	}
 
-	if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
-		/* Check instance range */
+	if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried. */
+		/* Check instance range. */
 		if ((Instance < 1) || (Instance > LogPortMax)) {
 
 			*pLen = 0;
@@ -2326,20 +2216,20 @@
 		Limit = LogPortIndex + 1;
 	}
 
-	else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
+	else { /* Instance == (SK_U32)(-1), get all Instances of that OID. */
 
 		LogPortIndex = 0;
 		Limit = LogPortMax;
 	}
 
-	/* Check action */
+	/* Check action. */
 	if (Action != SK_PNMI_GET) {
 
 		*pLen = 0;
 		return (SK_PNMI_ERR_READ_ONLY);
 	}
 
-	/* Check length */
+	/* Check length. */
 	if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
 
 		*pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
@@ -2358,7 +2248,7 @@
 	}
 	pAC->Pnmi.MacUpdatedFlag ++;
 
-	/* Get value */
+	/* Get value. */
 	Offset = 0;
 	for (; LogPortIndex < Limit; LogPortIndex ++) {
 
@@ -2464,19 +2354,16 @@
 	unsigned int	Limit;
 	unsigned int	Offset = 0;
 
-	/*
-	 * Calculate instance if wished. MAC index 0 is the virtual
-	 * MAC.
-	 */
+	/* Calculate instance if wished. MAC index 0 is the virtual MAC. */
 	PhysPortMax = pAC->GIni.GIMacsFound;
 	LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
 
-	if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
+	if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* DualNet mode. */
 		LogPortMax--;
 	}
 
-	if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
-		/* Check instance range */
+	if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried. */
+		/* Check instance range. */
 		if ((Instance < 1) || (Instance > LogPortMax)) {
 
 			*pLen = 0;
@@ -2485,27 +2372,23 @@
 		LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
 		Limit = LogPortIndex + 1;
 	}
-	else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
+	else { /* Instance == (SK_U32)(-1), get all Instances of that OID. */
 
 		LogPortIndex = 0;
 		Limit = LogPortMax;
 	}
 
-	/*
-	 * Perform Action
-	 */
+	/* Perform action. */
 	if (Action == SK_PNMI_GET) {
 
-		/* Check length */
+		/* Check length. */
 		if (*pLen < (Limit - LogPortIndex) * 6) {
 
 			*pLen = (Limit - LogPortIndex) * 6;
 			return (SK_PNMI_ERR_TOO_SHORT);
 		}
 
-		/*
-		 * Get value
-		 */
+		/* Get value. */
 		for (; LogPortIndex < Limit; LogPortIndex ++) {
 
 			switch (Id) {
@@ -2529,8 +2412,7 @@
 						&pAC->Addr.Net[NetIndex].PermanentMacAddress);
 				}
 				else {
-					PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-						pAC, LogPortIndex);
+					PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
 
 					CopyMac(pBuf + Offset,
 						&pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
@@ -2539,8 +2421,7 @@
 				break;
 
 			default:
-				SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
-					SK_PNMI_ERR008MSG);
+				SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008, SK_PNMI_ERR008MSG);
 
 				*pLen = 0;
 				return (SK_PNMI_ERR_GENERAL);
@@ -2551,8 +2432,8 @@
 	}
 	else {
 		/*
-		 * The logical MAC address may not be changed only
-		 * the physical ones
+		 * The logical MAC address may not be changed,
+		 * only the physical ones.
 		 */
 		if (Id == OID_SKGE_PHYS_FAC_ADDR) {
 
@@ -2560,19 +2441,16 @@
 			return (SK_PNMI_ERR_READ_ONLY);
 		}
 
-		/*
-		 * Only the current address may be changed
-		 */
+		/* Only the current address may be changed. */
 		if (Id != OID_SKGE_PHYS_CUR_ADDR) {
 
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
-				SK_PNMI_ERR009MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009, SK_PNMI_ERR009MSG);
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
 		}
 
-		/* Check length */
+		/* Check length. */
 		if (*pLen < (Limit - LogPortIndex) * 6) {
 
 			*pLen = (Limit - LogPortIndex) * 6;
@@ -2584,32 +2462,26 @@
 			return (SK_PNMI_ERR_BAD_VALUE);
 		}
 
-		/*
-		 * Check Action
-		 */
+		/* Check action. */
 		if (Action == SK_PNMI_PRESET) {
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_OK);
 		}
 
-		/*
-		 * Set OID_SKGE_MAC_CUR_ADDR
-		 */
+		/* Set OID_SKGE_MAC_CUR_ADDR.  */
 		for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
 
 			/*
 			 * A set to virtual port and set of broadcast
-			 * address will be ignored
+			 * address will be ignored.
 			 */
 			if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
 				"\xff\xff\xff\xff\xff\xff", 6) == 0) {
-
 				continue;
 			}
 
-			PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
-				LogPortIndex);
+			PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
 
 			Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
 				(SK_MAC_ADDR *)(pBuf + Offset),
@@ -2662,10 +2534,7 @@
 	unsigned int	Offset = 0;
 	SK_U64		StatVal;
 
-
-	/*
-	 * Calculate instance if wished
-	 */
+	/* Calculate instance if wished. */
 	if (Instance != (SK_U32)(-1)) {
 
 		if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
@@ -2681,25 +2550,21 @@
 		Limit = SKCS_NUM_PROTOCOLS;
 	}
 
-	/*
-	 * Check action
-	 */
+	/* Check action. */
 	if (Action != SK_PNMI_GET) {
 
 		*pLen = 0;
 		return (SK_PNMI_ERR_READ_ONLY);
 	}
 
-	/* Check length */
+	/* Check length. */
 	if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
 
 		*pLen = (Limit - Index) * sizeof(SK_U64);
 		return (SK_PNMI_ERR_TOO_SHORT);
 	}
 
-	/*
-	 * Get value
-	 */
+	/* Get value. */
 	for (; Index < Limit; Index ++) {
 
 		switch (Id) {
@@ -2725,8 +2590,7 @@
 			break;
 
 		default:
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
-				SK_PNMI_ERR010MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010, SK_PNMI_ERR010MSG);
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
@@ -2736,9 +2600,7 @@
 		Offset += sizeof(SK_U64);
 	}
 
-	/*
-	 * Store used buffer space
-	 */
+	/* Store used buffer space. */
 	*pLen = Offset;
 
 	return (SK_PNMI_ERR_OK);
@@ -2781,10 +2643,7 @@
 	SK_U32		Val32;
 	SK_U64		Val64;
 
-
-	/*
-	 * Calculate instance if wished
-	 */
+	/* Calculate instance if wished. */
 	if ((Instance != (SK_U32)(-1))) {
 
 		if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
@@ -2801,16 +2660,14 @@
 		Limit = (unsigned int) pAC->I2c.MaxSens;
 	}
 
-	/*
-	 * Check action
-	 */
+	/* Check action. */
 	if (Action != SK_PNMI_GET) {
 
 		*pLen = 0;
 		return (SK_PNMI_ERR_READ_ONLY);
 	}
 
-	/* Check length */
+	/* Check length. */
 	switch (Id) {
 
 	case OID_SKGE_SENSOR_VALUE:
@@ -2869,38 +2726,33 @@
 		break;
 
 	default:
-		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
-			SK_PNMI_ERR012MSG);
+		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012, SK_PNMI_ERR012MSG);
 
 		*pLen = 0;
 		return (SK_PNMI_ERR_GENERAL);
 
 	}
 
-	/*
-	 * Get value
-	 */
+	/* Get value. */
 	for (Offset = 0; Index < Limit; Index ++) {
 
 		switch (Id) {
 
 		case OID_SKGE_SENSOR_INDEX:
 			*(pBuf + Offset) = (char)Index;
-			Offset += sizeof(char);
+			Offset ++;
 			break;
 
 		case OID_SKGE_SENSOR_DESCR:
 			Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
-			SK_MEMCPY(pBuf + Offset + 1,
-				pAC->I2c.SenTable[Index].SenDesc, Len);
+			SK_MEMCPY(pBuf + Offset + 1, pAC->I2c.SenTable[Index].SenDesc, Len);
 			*(pBuf + Offset) = (char)Len;
 			Offset += Len + 1;
 			break;
 
 		case OID_SKGE_SENSOR_TYPE:
-			*(pBuf + Offset) =
-				(char)pAC->I2c.SenTable[Index].SenType;
-			Offset += sizeof(char);
+			*(pBuf + Offset) = (char)pAC->I2c.SenTable[Index].SenType;
+			Offset ++;
 			break;
 
 		case OID_SKGE_SENSOR_VALUE:
@@ -2937,9 +2789,8 @@
 			break;
 
 		case OID_SKGE_SENSOR_STATUS:
-			*(pBuf + Offset) =
-				(char)pAC->I2c.SenTable[Index].SenErrFlag;
-			Offset += sizeof(char);
+			*(pBuf + Offset) = (char)pAC->I2c.SenTable[Index].SenErrFlag;
+			Offset ++;
 			break;
 
 		case OID_SKGE_SENSOR_WAR_CTS:
@@ -2976,9 +2827,7 @@
 		}
 	}
 
-	/*
-	 * Store used buffer space
-	 */
+	/* Store used buffer space. */
 	*pLen = Offset;
 
 	return (SK_PNMI_ERR_OK);
@@ -3032,9 +2881,7 @@
 	int		Ret;
 	SK_U32		Val32;
 
-	/*
-	 * Get array of all currently stored VPD keys
-	 */
+	/* Get array of all currently stored VPD keys. */
 	Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
 	if (Ret != SK_PNMI_ERR_OK) {
 		*pLen = 0;
@@ -3079,21 +2926,19 @@
 		}
 	}
 
-	/*
-	 * Get value, if a query should be performed
-	 */
+	/* Get value, if a query should be performed. */
 	if (Action == SK_PNMI_GET) {
 
 		switch (Id) {
 
 		case OID_SKGE_VPD_FREE_BYTES:
-			/* Check length of buffer */
+			/* Check length of buffer. */
 			if (*pLen < sizeof(SK_U32)) {
 
 				*pLen = sizeof(SK_U32);
 				return (SK_PNMI_ERR_TOO_SHORT);
 			}
-			/* Get number of free bytes */
+			/* Get number of free bytes. */
 			pVpdStatus = VpdStat(pAC, IoC);
 			if (pVpdStatus == NULL) {
 
@@ -3118,7 +2963,7 @@
 			break;
 
 		case OID_SKGE_VPD_ENTRIES_LIST:
-			/* Check length */
+			/* Check length. */
 			for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
 
 				Len += SK_STRLEN(KeyArr[Index]) + 1;
@@ -3129,7 +2974,7 @@
 				return (SK_PNMI_ERR_TOO_SHORT);
 			}
 
-			/* Get value */
+			/* Get value. */
 			*(pBuf) = (char)Len - 1;
 			for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
 
@@ -3148,7 +2993,7 @@
 			break;
 
 		case OID_SKGE_VPD_ENTRIES_NUMBER:
-			/* Check length */
+			/* Check length. */
 			if (*pLen < sizeof(SK_U32)) {
 
 				*pLen = sizeof(SK_U32);
@@ -3161,7 +3006,7 @@
 			break;
 
 		case OID_SKGE_VPD_KEY:
-			/* Check buffer length, if it is large enough */
+			/* Check buffer length, if it is large enough. */
 			for (Len = 0, Index = FirstIndex;
 				Index < LastIndex; Index ++) {
 
@@ -3177,31 +3022,27 @@
 			 * Get the key to an intermediate buffer, because
 			 * we have to prepend a length byte.
 			 */
-			for (Offset = 0, Index = FirstIndex;
-				Index < LastIndex; Index ++) {
+			for (Offset = 0, Index = FirstIndex; Index < LastIndex; Index ++) {
 
 				Len = SK_STRLEN(KeyArr[Index]);
 
 				*(pBuf + Offset) = (char)Len;
-				SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
-					Len);
+				SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index], Len);
 				Offset += Len + 1;
 			}
 			*pLen = Offset;
 			break;
 
 		case OID_SKGE_VPD_VALUE:
-			/* Check the buffer length if it is large enough */
-			for (Offset = 0, Index = FirstIndex;
-				Index < LastIndex; Index ++) {
+			/* Check the buffer length if it is large enough. */
+			for (Offset = 0, Index = FirstIndex; Index < LastIndex; Index ++) {
 
 				BufLen = 256;
 				if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
 					(int *)&BufLen) > 0 ||
 					BufLen >= SK_PNMI_VPD_DATALEN) {
 
-					SK_ERR_LOG(pAC, SK_ERRCL_SW,
-						SK_PNMI_ERR021,
+					SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR021,
 						SK_PNMI_ERR021MSG);
 
 					return (SK_PNMI_ERR_GENERAL);
@@ -3218,16 +3059,14 @@
 			 * Get the value to an intermediate buffer, because
 			 * we have to prepend a length byte.
 			 */
-			for (Offset = 0, Index = FirstIndex;
-				Index < LastIndex; Index ++) {
+			for (Offset = 0, Index = FirstIndex; Index < LastIndex; Index ++) {
 
 				BufLen = 256;
 				if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
 					(int *)&BufLen) > 0 ||
 					BufLen >= SK_PNMI_VPD_DATALEN) {
 
-					SK_ERR_LOG(pAC, SK_ERRCL_SW,
-						SK_PNMI_ERR022,
+					SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR022,
 						SK_PNMI_ERR022MSG);
 
 					*pLen = 0;
@@ -3248,8 +3087,7 @@
 				return (SK_PNMI_ERR_TOO_SHORT);
 			}
 
-			for (Offset = 0, Index = FirstIndex;
-				Index < LastIndex; Index ++) {
+			for (Offset = 0, Index = FirstIndex; Index < LastIndex; Index ++) {
 
 				if (VpdMayWrite(KeyArr[Index])) {
 
@@ -3275,15 +3113,14 @@
 			break;
 
 		default:
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
-				SK_PNMI_ERR023MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023, SK_PNMI_ERR023MSG);
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
 		}
 	}
 	else {
-		/* The only OID which can be set is VPD_ACTION */
+		/* The only OID which can be set is VPD_ACTION. */
 		if (Id != OID_SKGE_VPD_ACTION) {
 
 			if (Id == OID_SKGE_VPD_FREE_BYTES ||
@@ -3297,8 +3134,7 @@
 				return (SK_PNMI_ERR_READ_ONLY);
 			}
 
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
-				SK_PNMI_ERR024MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024, SK_PNMI_ERR024MSG);
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
@@ -3314,14 +3150,11 @@
 			return (SK_PNMI_ERR_TOO_SHORT);
 		}
 
-		/*
-		 * The first byte contains the VPD action type we should
-		 * perform.
-		 */
+		/* The first byte contains the VPD action type we should perform. */
 		switch (*pBuf) {
 
 		case SK_PNMI_VPD_IGNORE:
-			/* Nothing to do */
+			/* Nothing to do. */
 			break;
 
 		case SK_PNMI_VPD_CREATE:
@@ -3353,13 +3186,13 @@
 			SK_MEMCPY(Buf, pBuf + 4, Offset);
 			Buf[Offset] = 0;
 
-			/* A preset ends here */
+			/* A PRESET ends here. */
 			if (Action == SK_PNMI_PRESET) {
 
 				return (SK_PNMI_ERR_OK);
 			}
 
-			/* Write the new entry or modify an existing one */
+			/* Write the new entry or modify an existing one .*/
 			Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
 			if (Ret == SK_PNMI_VPD_NOWRITE ) {
 
@@ -3391,7 +3224,7 @@
 			break;
 
 		case SK_PNMI_VPD_DELETE:
-			/* Check if the buffer size is plausible */
+			/* Check if the buffer size is plausible. */
 			if (*pLen < 3) {
 
 				*pLen = 3;
@@ -3406,7 +3239,7 @@
 			KeyStr[1] = pBuf[2];
 			KeyStr[2] = 0;
 
-			/* Find the passed key in the array */
+			/* Find the passed key in the array. */
 			for (Index = 0; Index < KeyNo; Index ++) {
 
 				if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
@@ -3414,6 +3247,7 @@
 					break;
 				}
 			}
+
 			/*
 			 * If we cannot find the key it is wrong, so we
 			 * return an appropriate error value.
@@ -3429,7 +3263,7 @@
 				return (SK_PNMI_ERR_OK);
 			}
 
-			/* Ok, you wanted it and you will get it */
+			/* Ok, you wanted it and you will get it. */
 			Ret = VpdDelete(pAC, IoC, KeyStr);
 			if (Ret != SK_PNMI_VPD_OK) {
 
@@ -3507,18 +3341,14 @@
 	char		Buf[256];
 	int			MacType;
 
-	/*
-	 * Check instance. We only handle single instance variables.
-	 */
+	/* Check instance. We only handle single instance variables. */
 	if (Instance != (SK_U32)(-1) && Instance != 1) {
 
 		*pLen = 0;
 		return (SK_PNMI_ERR_UNKNOWN_INST);
 	}
 
-	/*
-	 * Check action. We only allow get requests.
-	 */
+	/* Check action. We only allow get requests. */
 	if (Action != SK_PNMI_GET) {
 
 		*pLen = 0;
@@ -3527,9 +3357,7 @@
 	
 	MacType = pAC->GIni.GIMacType;
 	
-	/*
-	 * Check length for the various supported OIDs
-	 */
+	/* Check length for the various supported OIDs. */
 	switch (Id) {
 
 	case OID_GEN_XMIT_ERROR:
@@ -3543,14 +3371,12 @@
 
 #else /* SK_NDIS_64BIT_CTR */
 
-		/*
-		 * for compatibility, at least 32bit are required for oid
-		 */
+		/* For compatibility, at least 32bit are required for OID. */
 		if (*pLen < sizeof(SK_U32)) {
 			/*
-			* but indicate handling for 64bit values,
-			* if insufficient space is provided
-			*/
+			 * Indicate handling for 64bit values,
+			 * if insufficient space is provided.
+			 */
 			*pLen = sizeof(SK_U64);
 			return (SK_PNMI_ERR_TOO_SHORT);
 		}
@@ -3621,11 +3447,11 @@
 		break;
 
 	default:
-		/* Checked later */
+		/* Checked later. */
 		break;
 	}
 
-	/* Update statistic */
+	/* Update statistics. */
 	if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
 		Id == OID_SKGE_TX_HW_ERROR_CTS ||
 		Id == OID_SKGE_IN_ERRORS_CTS ||
@@ -3633,7 +3459,8 @@
 		Id == OID_GEN_XMIT_ERROR ||
 		Id == OID_GEN_RCV_ERROR) {
 
-		/* Force the XMAC to update its statistic counters and
+		/*
+		 * Force the XMAC to update its statistic counters and
 		 * Increment semaphore to indicate that an update was
 		 * already done.
 		 */
@@ -3682,9 +3509,7 @@
 		}
 	}
 
-	/*
-	 * Retrieve value
-	 */
+	/* Retrieve value. */
 	switch (Id) {
 
 	case OID_SKGE_SUPPORTED_LIST:
@@ -3694,11 +3519,11 @@
 			*pLen = Len;
 			return (SK_PNMI_ERR_TOO_SHORT);
 		}
-		for (Offset = 0, Index = 0; Offset < Len;
-			Offset += sizeof(SK_U32), Index ++) {
+		for (Offset = 0, Index = 0; Offset < Len; Index ++) {
 
 			Val32 = (SK_U32)IdTable[Index].Id;
 			SK_PNMI_STORE_U32(pBuf + Offset, Val32);
+			Offset += sizeof(SK_U32);
 		}
 		*pLen = Len;
 		break;
@@ -3724,8 +3549,7 @@
 	case OID_SKGE_DRIVER_DESCR:
 		if (pAC->Pnmi.pDriverDescription == NULL) {
 
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
-				SK_PNMI_ERR007MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007, SK_PNMI_ERR007MSG);
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
@@ -3734,8 +3558,7 @@
 		Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
 		if (Len > SK_PNMI_STRINGLEN1) {
 
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
-				SK_PNMI_ERR029MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029, SK_PNMI_ERR029MSG);
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
@@ -3754,8 +3577,7 @@
 	case OID_SKGE_DRIVER_VERSION:
 		if (pAC->Pnmi.pDriverVersion == NULL) {
 
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
-				SK_PNMI_ERR030MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, SK_PNMI_ERR030MSG);
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
@@ -3764,8 +3586,7 @@
 		Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
 		if (Len > SK_PNMI_STRINGLEN1) {
 
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
-				SK_PNMI_ERR031MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, SK_PNMI_ERR031MSG);
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
@@ -3784,8 +3605,7 @@
 	case OID_SKGE_DRIVER_RELDATE:
 		if (pAC->Pnmi.pDriverReleaseDate == NULL) {
 
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
-				SK_PNMI_ERR053MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR053, SK_PNMI_ERR053MSG);
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
@@ -3794,8 +3614,7 @@
 		Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
 		if (Len > SK_PNMI_STRINGLEN1) {
 
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
-				SK_PNMI_ERR054MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR054, SK_PNMI_ERR054MSG);
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
@@ -3814,8 +3633,7 @@
 	case OID_SKGE_DRIVER_FILENAME:
 		if (pAC->Pnmi.pDriverFileName == NULL) {
 
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
-				SK_PNMI_ERR055MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR055, SK_PNMI_ERR055MSG);
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
@@ -3824,8 +3642,7 @@
 		Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
 		if (Len > SK_PNMI_STRINGLEN1) {
 
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
-				SK_PNMI_ERR056MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR056, SK_PNMI_ERR056MSG);
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
@@ -3851,8 +3668,7 @@
 		Len = 256;
 		if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
 
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
-				SK_PNMI_ERR032MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032, SK_PNMI_ERR032MSG);
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
@@ -3860,8 +3676,7 @@
 		Len ++;
 		if (Len > SK_PNMI_STRINGLEN1) {
 
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
-				SK_PNMI_ERR033MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033, SK_PNMI_ERR033MSG);
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
@@ -3877,7 +3692,6 @@
 		break;
 
 	case OID_SKGE_HW_VERSION:
-		/* Oh, I love to do some string manipulation */
 		if (*pLen < 5) {
 
 			*pLen = 5;
@@ -3886,9 +3700,9 @@
 		Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
 		pBuf[0] = 4;
 		pBuf[1] = 'v';
-		pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
+		pBuf[2] = (char)('0' | ((Val8 >> 4) & 0x0f));
 		pBuf[3] = '.';
-		pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
+		pBuf[4] = (char)('0' | (Val8 & 0x0f));
 		*pLen = 5;
 		break;
 
@@ -3911,12 +3725,12 @@
 		break;
 
 	case OID_SKGE_VAUXAVAIL:
-		*pBuf = (char) pAC->GIni.GIVauxAvail;
+		*pBuf = (char)pAC->GIni.GIVauxAvail;
 		*pLen = sizeof(char);
 		break;
 
 	case OID_SKGE_BUS_TYPE:
-		*pBuf = (char) SK_PNMI_BUS_PCI;
+		*pBuf = (char)SK_PNMI_BUS_PCI;
 		*pLen = sizeof(char);
 		break;
 
@@ -3965,31 +3779,31 @@
 		break;
 
 	case OID_SKGE_RLMT_MONITOR_NUMBER:
-/* XXX Not yet implemented by RLMT therefore we return zero elements */
+		/* Not yet implemented by RLMT, therefore we return zero elements. */
 		Val32 = 0;
 		SK_PNMI_STORE_U32(pBuf, Val32);
 		*pLen = sizeof(SK_U32);
 		break;
 
 	case OID_SKGE_TX_SW_QUEUE_LEN:
-		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 		if (MacType == SK_MAC_XMAC) {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
 					pAC->Pnmi.BufPort[1].TxSwQueueLen;
 			}			
 		}
 		else {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
 					pAC->Pnmi.Port[1].TxSwQueueLen;
@@ -4001,24 +3815,24 @@
 
 
 	case OID_SKGE_TX_SW_QUEUE_MAX:
-		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 		if (MacType == SK_MAC_XMAC) {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
 					pAC->Pnmi.BufPort[1].TxSwQueueMax;
 			}
 		}
 		else {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
 					pAC->Pnmi.Port[1].TxSwQueueMax;
@@ -4029,24 +3843,24 @@
 		break;
 
 	case OID_SKGE_TX_RETRY:
-		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 		if (MacType == SK_MAC_XMAC) {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
 					pAC->Pnmi.BufPort[1].TxRetryCts;
 			}
 		}
 		else {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.Port[0].TxRetryCts +
 					pAC->Pnmi.Port[1].TxRetryCts;
@@ -4057,24 +3871,24 @@
 		break;
 
 	case OID_SKGE_RX_INTR_CTS:
-		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 		if (MacType == SK_MAC_XMAC) {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
 					pAC->Pnmi.BufPort[1].RxIntrCts;
 			}
 		}
 		else {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.Port[0].RxIntrCts +
 					pAC->Pnmi.Port[1].RxIntrCts;
@@ -4085,24 +3899,24 @@
 		break;
 
 	case OID_SKGE_TX_INTR_CTS:
-		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 		if (MacType == SK_MAC_XMAC) {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
 					pAC->Pnmi.BufPort[1].TxIntrCts;
 			}
 		}
 		else {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.Port[0].TxIntrCts +
 					pAC->Pnmi.Port[1].TxIntrCts;
@@ -4113,24 +3927,24 @@
 		break;
 
 	case OID_SKGE_RX_NO_BUF_CTS:
-		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 		if (MacType == SK_MAC_XMAC) {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
 					pAC->Pnmi.BufPort[1].RxNoBufCts;
 			}
 		}
 		else {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
 					pAC->Pnmi.Port[1].RxNoBufCts;
@@ -4141,24 +3955,24 @@
 		break;
 
 	case OID_SKGE_TX_NO_BUF_CTS:
-		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 		if (MacType == SK_MAC_XMAC) {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
 					pAC->Pnmi.BufPort[1].TxNoBufCts;
 			}
 		}
 		else {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
 					pAC->Pnmi.Port[1].TxNoBufCts;
@@ -4169,24 +3983,24 @@
 		break;
 
 	case OID_SKGE_TX_USED_DESCR_NO:
-		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 		if (MacType == SK_MAC_XMAC) {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
 					pAC->Pnmi.BufPort[1].TxUsedDescrNo;
 			}
 		}
 		else {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
 					pAC->Pnmi.Port[1].TxUsedDescrNo;
@@ -4197,24 +4011,24 @@
 		break;
 
 	case OID_SKGE_RX_DELIVERED_CTS:
-		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 		if (MacType == SK_MAC_XMAC) {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
 					pAC->Pnmi.BufPort[1].RxDeliveredCts;
 			}
 		}
 		else {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
 					pAC->Pnmi.Port[1].RxDeliveredCts;
@@ -4225,24 +4039,24 @@
 		break;
 
 	case OID_SKGE_RX_OCTETS_DELIV_CTS:
-		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 		if (MacType == SK_MAC_XMAC) {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
 					pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
 			}
 		}
 		else {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
 					pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
@@ -4263,13 +4077,13 @@
 		break;
 
 	case OID_SKGE_IN_ERRORS_CTS:
-		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 		if (MacType == SK_MAC_XMAC) {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = Val64RxHwErrs +
 					pAC->Pnmi.BufPort[0].RxNoBufCts +
@@ -4277,11 +4091,11 @@
 			}
 		}
 		else {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = Val64RxHwErrs +
 					pAC->Pnmi.Port[0].RxNoBufCts +
@@ -4293,13 +4107,13 @@
 		break;
 
 	case OID_SKGE_OUT_ERROR_CTS:
-		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 		if (MacType == SK_MAC_XMAC) {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = Val64TxHwErrs +
 					pAC->Pnmi.BufPort[0].TxNoBufCts +
@@ -4307,11 +4121,11 @@
 			}
 		}
 		else {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = Val64TxHwErrs +
 					pAC->Pnmi.Port[0].TxNoBufCts +
@@ -4323,24 +4137,24 @@
 		break;
 
 	case OID_SKGE_ERR_RECOVERY_CTS:
-		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 		if (MacType == SK_MAC_XMAC) {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
 					pAC->Pnmi.BufPort[1].ErrRecoveryCts;
 			}
 		}
 		else {
-			/* Dual net mode */
+			/* DualNet mode. */
 			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 				Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
 			}
-			/* Single net mode */
+			/* SingleNet mode. */
 			else {
 				Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
 					pAC->Pnmi.Port[1].ErrRecoveryCts;
@@ -4364,7 +4178,7 @@
 		break;
 
 	case OID_GEN_RCV_ERROR:
-		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 		if (MacType == SK_MAC_XMAC) {
 			Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
 		}
@@ -4373,7 +4187,7 @@
 		}
 
 		/*
-		 * by default 32bit values are evaluated
+		 * By default 32bit values are evaluated.
 		 */
 		if (!Is64BitReq) {
 			Val32 = (SK_U32)Val64;
@@ -4387,7 +4201,7 @@
 		break;
 
 	case OID_GEN_XMIT_ERROR:
-		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 		if (MacType == SK_MAC_XMAC) {
 			Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
 		}
@@ -4396,7 +4210,7 @@
 		}
 
 		/*
-		 * by default 32bit values are evaluated
+		 * By default 32bit values are evaluated.
 		 */
 		if (!Is64BitReq) {
 			Val32 = (SK_U32)Val64;
@@ -4410,7 +4224,7 @@
 		break;
 
 	case OID_GEN_RCV_NO_BUFFER:
-		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+		/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 		if (MacType == SK_MAC_XMAC) {
 			Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
 		}
@@ -4419,7 +4233,7 @@
 		}
 
 		/*
-		 * by default 32bit values are evaluated
+		 * By default 32bit values are evaluated.
 		 */
 		if (!Is64BitReq) {
 			Val32 = (SK_U32)Val64;
@@ -4439,8 +4253,7 @@
 		break;
 
 	default:
-		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
-			SK_PNMI_ERR034MSG);
+		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034, SK_PNMI_ERR034MSG);
 
 		*pLen = 0;
 		return (SK_PNMI_ERR_GENERAL);
@@ -4497,25 +4310,17 @@
 	SK_U32		Val32;
 	SK_U64		Val64;
 
-
-	/*
-	 * Check instance. Only single instance OIDs are allowed here.
-	 */
+	/* Check instance. Only single instance OIDs are allowed here. */
 	if (Instance != (SK_U32)(-1) && Instance != 1) {
 
 		*pLen = 0;
 		return (SK_PNMI_ERR_UNKNOWN_INST);
 	}
 
-	/*
-	 * Perform the requested action.
-	 */
+	/* Perform the requested action. */
 	if (Action == SK_PNMI_GET) {
 
-		/*
-		 * Check if the buffer length is large enough.
-		 */
-
+		/* Check if the buffer length is large enough. */
 		switch (Id) {
 
 		case OID_SKGE_RLMT_MODE:
@@ -4548,8 +4353,7 @@
 			break;
 
 		default:
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
-				SK_PNMI_ERR035MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035, SK_PNMI_ERR035MSG);
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
@@ -4568,9 +4372,7 @@
 		}
 		pAC->Pnmi.RlmtUpdatedFlag ++;
 
-		/*
-		 * Retrieve Value
-		*/
+		/* Retrieve value. */
 		switch (Id) {
 
 		case OID_SKGE_RLMT_MODE:
@@ -4648,17 +4450,17 @@
 		pAC->Pnmi.RlmtUpdatedFlag --;
 	}
 	else {
-		/* Perform a preset or set */
+		/* Perform a PRESET or SET. */
 		switch (Id) {
 
 		case OID_SKGE_RLMT_MODE:
-			/* Check if the buffer length is plausible */
+			/* Check if the buffer length is plausible. */
 			if (*pLen < sizeof(char)) {
 
 				*pLen = sizeof(char);
 				return (SK_PNMI_ERR_TOO_SHORT);
 			}
-			/* Check if the value range is correct */
+			/* Check if the value range is correct. */
 			if (*pLen != sizeof(char) ||
 				(*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
 				*(SK_U8 *)pBuf > 15) {
@@ -4666,21 +4468,21 @@
 				*pLen = 0;
 				return (SK_PNMI_ERR_BAD_VALUE);
 			}
-			/* The preset ends here */
+			/* The PRESET ends here. */
 			if (Action == SK_PNMI_PRESET) {
 
 				*pLen = 0;
 				return (SK_PNMI_ERR_OK);
 			}
-			/* Send an event to RLMT to change the mode */
+			/* Send an event to RLMT to change the mode. */
 			SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
+			
 			EventParam.Para32[0] |= (SK_U32)(*pBuf);
 			EventParam.Para32[1] = 0;
 			if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
 				EventParam) > 0) {
 
-				SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
-					SK_PNMI_ERR037MSG);
+				SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037, SK_PNMI_ERR037MSG);
 
 				*pLen = 0;
 				return (SK_PNMI_ERR_GENERAL);
@@ -4688,20 +4490,25 @@
 			break;
 
 		case OID_SKGE_RLMT_PORT_PREFERRED:
-			/* Check if the buffer length is plausible */
+			/* PRESET/SET action makes no sense in Dual Net mode. */
+			if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+				break;
+			}
+			
+			/* Check if the buffer length is plausible. */
 			if (*pLen < sizeof(char)) {
 
 				*pLen = sizeof(char);
 				return (SK_PNMI_ERR_TOO_SHORT);
 			}
-			/* Check if the value range is correct */
+			/* Check if the value range is correct. */
 			if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
 				(SK_U8)pAC->GIni.GIMacsFound) {
 
 				*pLen = 0;
 				return (SK_PNMI_ERR_BAD_VALUE);
 			}
-			/* The preset ends here */
+			/* The PRESET ends here. */
 			if (Action == SK_PNMI_PRESET) {
 
 				*pLen = 0;
@@ -4714,13 +4521,13 @@
 			 * make the decision which is the preferred port.
 			 */
 			SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
+			
 			EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
 			EventParam.Para32[1] = NetIndex;
 			if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
 				EventParam) > 0) {
 
-				SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
-					SK_PNMI_ERR038MSG);
+				SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038, SK_PNMI_ERR038MSG);
 
 				*pLen = 0;
 				return (SK_PNMI_ERR_GENERAL);
@@ -4728,22 +4535,20 @@
 			break;
 
 		case OID_SKGE_RLMT_CHANGE_THRES:
-			/* Check if the buffer length is plausible */
+			/* Check if the buffer length is plausible. */
 			if (*pLen < sizeof(SK_U64)) {
 
 				*pLen = sizeof(SK_U64);
 				return (SK_PNMI_ERR_TOO_SHORT);
 			}
-			/*
-			 * There are not many restrictions to the
-			 * value range.
-			 */
+			
+			/* There are not many restrictions to the value range. */
 			if (*pLen != sizeof(SK_U64)) {
 
 				*pLen = 0;
 				return (SK_PNMI_ERR_BAD_VALUE);
 			}
-			/* A preset ends here */
+			/* The PRESET ends here. */
 			if (Action == SK_PNMI_PRESET) {
 
 				*pLen = 0;
@@ -4758,7 +4563,7 @@
 			break;
 
 		default:
-			/* The other OIDs are not be able for set */
+			/* The other OIDs are not be able for set. */
 			*pLen = 0;
 			return (SK_PNMI_ERR_READ_ONLY);
 		}
@@ -4803,54 +4608,49 @@
 	SK_U32		Val32;
 	SK_U64		Val64;
 
-	/*
-	 * Calculate the port indexes from the instance.
-	 */
+
+	/* Calculate the port indexes from the instance. */
 	PhysPortMax = pAC->GIni.GIMacsFound;
 
 	if ((Instance != (SK_U32)(-1))) {
-		/* Check instance range */
+		/* Check instance range. */
 		if ((Instance < 1) || (Instance > PhysPortMax)) {
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_UNKNOWN_INST);
 		}
 
-		/* Single net mode */
+		/* SingleNet mode. */
 		PhysPortIndex = Instance - 1;
 
-		/* Dual net mode */
+		/* DualNet mode. */
 		if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 			PhysPortIndex = NetIndex;
 		}
 
-		/* Both net modes */
+		/* Both net modes. */
 		Limit = PhysPortIndex + 1;
 	}
 	else {
-		/* Single net mode */
+		/* SingleNet mode. */
 		PhysPortIndex = 0;
 		Limit = PhysPortMax;
 
-		/* Dual net mode */
+		/* DualNet mode. */
 		if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
 			PhysPortIndex = NetIndex;
 			Limit = PhysPortIndex + 1;
 		}
 	}
 
-	/*
-	 * Currently only get requests are allowed.
-	 */
+	/* Currently only GET requests are allowed. */
 	if (Action != SK_PNMI_GET) {
 
 		*pLen = 0;
 		return (SK_PNMI_ERR_READ_ONLY);
 	}
 
-	/*
-	 * Check if the buffer length is large enough.
-	 */
+	/* Check if the buffer length is large enough. */
 	switch (Id) {
 
 	case OID_SKGE_RLMT_PORT_INDEX:
@@ -4874,8 +4674,7 @@
 		break;
 
 	default:
-		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
-			SK_PNMI_ERR039MSG);
+		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039, SK_PNMI_ERR039MSG);
 
 		*pLen = 0;
 		return (SK_PNMI_ERR_GENERAL);
@@ -4893,9 +4692,7 @@
 	}
 	pAC->Pnmi.RlmtUpdatedFlag ++;
 
-	/*
-	 * Get value
-	 */
+	/* Get value. */
 	Offset = 0;
 	for (; PhysPortIndex < Limit; PhysPortIndex ++) {
 
@@ -5008,19 +4805,21 @@
 	int			Ret;
 	SK_EVPARA	EventParam;
 	SK_U32		Val32;
+#ifdef SK_PHY_LP_MODE
+	SK_U8	CurrentPhyPowerState;
+#endif /* SK_PHY_LP_MODE */
 
-	/*
-	 * Calculate instance if wished. MAC index 0 is the virtual MAC.
-	 */
+
+	/* Calculate instance if wished. MAC index 0 is the virtual MAC. */
 	PhysPortMax = pAC->GIni.GIMacsFound;
 	LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
 
-	if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
+	if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* DualNet mode. */
 		LogPortMax--;
 	}
 
-	if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
-		/* Check instance range */
+	if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried. */
+		/* Check instance range. */
 		if ((Instance < 1) || (Instance > LogPortMax)) {
 
 			*pLen = 0;
@@ -5030,18 +4829,16 @@
 		Limit = LogPortIndex + 1;
 	}
 
-	else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
+	else { /* Instance == (SK_U32)(-1), get all Instances of that OID. */
 
 		LogPortIndex = 0;
 		Limit = LogPortMax;
 	}
 
-	/*
-	 * Perform action
-	 */
+	/* Perform action. */
 	if (Action == SK_PNMI_GET) {
 
-		/* Check length */
+		/* Check length. */
 		switch (Id) {
 
 		case OID_SKGE_PMD:
@@ -5079,8 +4876,7 @@
 			break;
 
 		default:
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
-				SK_PNMI_ERR041MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041, SK_PNMI_ERR041MSG);
 			*pLen = 0;
 			return (SK_PNMI_ERR_GENERAL);
 		}
@@ -5096,9 +4892,7 @@
 		}
 		pAC->Pnmi.SirqUpdatedFlag ++;
 
-		/*
-		 * Get value
-		 */
+		/* Get value. */
 		Offset = 0;
 		for (; LogPortIndex < Limit; LogPortIndex ++) {
 
@@ -5108,107 +4902,99 @@
 
 			case OID_SKGE_PMD:
 				*pBufPtr = pAC->Pnmi.PMD;
-				Offset += sizeof(char);
+				Offset ++;
 				break;
 
 			case OID_SKGE_CONNECTOR:
 				*pBufPtr = pAC->Pnmi.Connector;
-				Offset += sizeof(char);
+				Offset ++;
 				break;
 
 			case OID_SKGE_PHY_TYPE:
-				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
 					if (LogPortIndex == 0) {
 						continue;
 					}
-					else {
-						/* Get value for physical ports */
-						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
-							pAC, LogPortIndex);
-						Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
-						SK_PNMI_STORE_U32(pBufPtr, Val32);
-					}
+					/* Get value for physical port. */
+					PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
+					Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
 				}
-				else { /* DualNetMode */
+				else { /* DualNet mode. */
 					
 					Val32 = pAC->GIni.GP[NetIndex].PhyType;
-					SK_PNMI_STORE_U32(pBufPtr, Val32);
 				}
+				SK_PNMI_STORE_U32(pBufPtr, Val32);
 				Offset += sizeof(SK_U32);
 				break;
 
 #ifdef SK_PHY_LP_MODE
 			case OID_SKGE_PHY_LP_MODE:
-				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
 					if (LogPortIndex == 0) {
 						continue;
 					}
-					else {
-						/* Get value for physical ports */
-						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
-						Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
-						*pBufPtr = Val8;
-					}
+					/* Get value for physical port. */
+					PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
+					*pBufPtr = (SK_U8)pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
 				}
-				else { /* DualNetMode */
+				else { /* DualNet mode. */
 					
-					Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
-					*pBufPtr = Val8;
+					*pBufPtr = (SK_U8)pAC->GIni.GP[NetIndex].PPhyPowerState;
 				}
 				Offset += sizeof(SK_U8);
 				break;
 #endif
 
 			case OID_SKGE_LINK_CAP:
-				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
 					if (LogPortIndex == 0) {
-						/* Get value for virtual port */
+						/* Get value for virtual port. */
 						VirtualConf(pAC, IoC, Id, pBufPtr);
 					}
 					else {
-						/* Get value for physical ports */
+						/* Get value for physical port. */
 						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 							pAC, LogPortIndex);
 
 						*pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
 					}
 				}
-				else { /* DualNetMode */
+				else { /* DualNet mode. */
 					
 					*pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
 				}
-				Offset += sizeof(char);
+				Offset ++;
 				break;
 
 			case OID_SKGE_LINK_MODE:
-				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
 					if (LogPortIndex == 0) {
-						/* Get value for virtual port */
+						/* Get value for virtual port. */
 						VirtualConf(pAC, IoC, Id, pBufPtr);
 					}
 					else {
-						/* Get value for physical ports */
+						/* Get value for physical port. */
 						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 							pAC, LogPortIndex);
 
 						*pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
 					}
 				}
-				else { /* DualNetMode */
+				else { /* DualNet mode. */
 				
 					*pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
 				}
-				Offset += sizeof(char);
+				Offset ++;
 				break;
 
 			case OID_SKGE_LINK_MODE_STATUS:
-				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
 					if (LogPortIndex == 0) {
-						/* Get value for virtual port */
+						/* Get value for virtual port. */
 						VirtualConf(pAC, IoC, Id, pBufPtr);
 					}
 					else {
-						/* Get value for physical port */
+						/* Get value for physical port. */
 						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 							pAC, LogPortIndex);
 
@@ -5216,147 +5002,147 @@
 							CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
 					}
 				}
-				else { /* DualNetMode */
+				else { /* DualNet mode. */
 					
 					*pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
 				}
-				Offset += sizeof(char);
+				Offset ++;
 				break;
 
 			case OID_SKGE_LINK_STATUS:
-				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
 					if (LogPortIndex == 0) {
-						/* Get value for virtual port */
+						/* Get value for virtual port. */
 						VirtualConf(pAC, IoC, Id, pBufPtr);
 					}
 					else {
-						/* Get value for physical ports */
+						/* Get value for physical port. */
 						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 							pAC, LogPortIndex);
 	
 						*pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
 					}
 				}
-				else { /* DualNetMode */
+				else { /* DualNet mode. */
 
 					*pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
 				}
-				Offset += sizeof(char);
+				Offset ++;
 				break;
 
 			case OID_SKGE_FLOWCTRL_CAP:
-				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
 					if (LogPortIndex == 0) {
-						/* Get value for virtual port */
+						/* Get value for virtual port. */
 						VirtualConf(pAC, IoC, Id, pBufPtr);
 					}
 					else {
-						/* Get value for physical ports */
+						/* Get value for physical port. */
 						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 							pAC, LogPortIndex);
 	
 						*pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
 					}
 				}
-				else { /* DualNetMode */
+				else { /* DualNet mode. */
 				
 					*pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
 				}
-				Offset += sizeof(char);
+				Offset ++;
 				break;
 
 			case OID_SKGE_FLOWCTRL_MODE:
-				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
 					if (LogPortIndex == 0) {
-						/* Get value for virtual port */
+						/* Get value for virtual port. */
 						VirtualConf(pAC, IoC, Id, pBufPtr);
 					}
 					else {
-						/* Get value for physical port */
+						/* Get value for physical port. */
 						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 							pAC, LogPortIndex);
 	
 						*pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
 					}
 				}
-				else { /* DualNetMode */
+				else { /* DualNet mode. */
 
 					*pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
 				}
-				Offset += sizeof(char);
+				Offset ++;
 				break;
 
 			case OID_SKGE_FLOWCTRL_STATUS:
-				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
 					if (LogPortIndex == 0) {
-						/* Get value for virtual port */
+						/* Get value for virtual port. */
 						VirtualConf(pAC, IoC, Id, pBufPtr);
 					}
 					else {
-						/* Get value for physical port */
+						/* Get value for physical port. */
 						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 							pAC, LogPortIndex);
 	
 						*pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
 					}
 				}
-				else { /* DualNetMode */
+				else { /* DualNet mode. */
 
 					*pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
 				}
-				Offset += sizeof(char);
+				Offset ++;
 				break;
 
 			case OID_SKGE_PHY_OPERATION_CAP:
-				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet Mode. */
 					if (LogPortIndex == 0) {
-						/* Get value for virtual port */
+						/* Get value for virtual port. */
 						VirtualConf(pAC, IoC, Id, pBufPtr);
 					}
 					else {
-						/* Get value for physical ports */
+						/* Get value for physical port. */
 						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 							pAC, LogPortIndex);
 	
 						*pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
 					}
 				}
-				else { /* DualNetMode */
+				else { /* DualNet mode. */
 				
 					*pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
 				}
-				Offset += sizeof(char);
+				Offset ++;
 				break;
 
 			case OID_SKGE_PHY_OPERATION_MODE:
-				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
 					if (LogPortIndex == 0) {
-						/* Get value for virtual port */
+						/* Get value for virtual port. */
 						VirtualConf(pAC, IoC, Id, pBufPtr);
 					}
 					else {
-						/* Get value for physical port */
+						/* Get value for physical port. */
 						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 							pAC, LogPortIndex);
 
 						*pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
 					}
 				}
-				else { /* DualNetMode */
+				else { /* DualNet mode. */
 				
 					*pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
 				}
-				Offset += sizeof(char);
+				Offset ++;
 				break;
 
 			case OID_SKGE_PHY_OPERATION_STATUS:
-				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
 					if (LogPortIndex == 0) {
-						/* Get value for virtual port */
+						/* Get value for virtual port. */
 						VirtualConf(pAC, IoC, Id, pBufPtr);
 					}
 					else {
-						/* Get value for physical port */
+						/* Get value for physical port. */
 						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 							pAC, LogPortIndex);
 	
@@ -5367,70 +5153,70 @@
 				
 					*pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
 				}
-				Offset += sizeof(char);
+				Offset ++;
 				break;
 
 			case OID_SKGE_SPEED_CAP:
-				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
 					if (LogPortIndex == 0) {
-						/* Get value for virtual port */
+						/* Get value for virtual port. */
 						VirtualConf(pAC, IoC, Id, pBufPtr);
 					}
 					else {
-						/* Get value for physical ports */
+						/* Get value for physical port. */
 						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 							pAC, LogPortIndex);
 	
 						*pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
 					}
 				}
-				else { /* DualNetMode */
+				else { /* DualNet mode. */
 				
 					*pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
 				}
-				Offset += sizeof(char);
+				Offset ++;
 				break;
 
 			case OID_SKGE_SPEED_MODE:
-				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
 					if (LogPortIndex == 0) {
-						/* Get value for virtual port */
+						/* Get value for virtual port. */
 						VirtualConf(pAC, IoC, Id, pBufPtr);
 					}
 					else {
-						/* Get value for physical port */
+						/* Get value for physical port. */
 						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 							pAC, LogPortIndex);
 	
 						*pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
 					}
 				}
-				else { /* DualNetMode */
+				else { /* DualNet mode. */
 
 					*pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
 				}
-				Offset += sizeof(char);
+				Offset ++;
 				break;
 
 			case OID_SKGE_SPEED_STATUS:
-				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
 					if (LogPortIndex == 0) {
-						/* Get value for virtual port */
+						/* Get value for virtual port. */
 						VirtualConf(pAC, IoC, Id, pBufPtr);
 					}
 					else {
-						/* Get value for physical port */
+						/* Get value for physical port. */
 						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
 							pAC, LogPortIndex);
 	
 						*pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
 					}
 				}
-				else { /* DualNetMode */
+				else { /* DualNet mode. */
 
 					*pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
 				}
-				Offset += sizeof(char);
+				Offset ++;
 				break;
 			
 			case OID_SKGE_MTU:
@@ -5483,40 +5269,33 @@
 			return (SK_PNMI_ERR_TOO_SHORT);
 		}
 		break;
-#endif
+#endif /* SK_PHY_LP_MODE */
 
 	case OID_SKGE_MTU:
-		if (*pLen < sizeof(SK_U32)) {
+		if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
 
-			*pLen = sizeof(SK_U32);
+			*pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
 			return (SK_PNMI_ERR_TOO_SHORT);
 		}
-		if (*pLen != sizeof(SK_U32)) {
-
-			*pLen = 0;
-			return (SK_PNMI_ERR_BAD_VALUE);
-		}
 		break;
-
+	
     default:
 		*pLen = 0;
 		return (SK_PNMI_ERR_READ_ONLY);
 	}
 
-	/*
-	 * Perform preset or set
-	 */
+	/* Perform PRESET or SET. */
 	Offset = 0;
 	for (; LogPortIndex < Limit; LogPortIndex ++) {
 
+		Val8 = *(pBuf + Offset);
+
 		switch (Id) {
 
 		case OID_SKGE_LINK_MODE:
-			/* Check the value range */
-			Val8 = *(pBuf + Offset);
+			/* Check the value range. */
 			if (Val8 == 0) {
-
-				Offset += sizeof(char);
+				Offset++;
 				break;
 			}
 			if (Val8 < SK_LMODE_HALF ||
@@ -5527,51 +5306,68 @@
 				return (SK_PNMI_ERR_BAD_VALUE);
 			}
 
-			/* The preset ends here */
+			/* The PRESET ends here. */
 			if (Action == SK_PNMI_PRESET) {
 
 				return (SK_PNMI_ERR_OK);
 			}
 
-			if (LogPortIndex == 0) {
-
-				/*
-				 * The virtual port consists of all currently
-				 * active ports. Find them and send an event
-				 * with the new link mode to SIRQ.
-				 */
-				for (PhysPortIndex = 0;
-					PhysPortIndex < PhysPortMax;
-					PhysPortIndex ++) {
-
-					if (!pAC->Pnmi.Port[PhysPortIndex].
-						ActiveFlag) {
-
-						continue;
-					}
+			if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+				if (LogPortIndex == 0) {
+					/*
+					 * The virtual port consists of all currently
+					 * active ports. Find them and send an event
+					 * with the new link mode to SIRQ.
+					 */
+					for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
+						PhysPortIndex ++) {
 
-					EventParam.Para32[0] = PhysPortIndex;
+						if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+							continue;
+						}
+						
+						EventParam.Para32[0] = PhysPortIndex;
+						EventParam.Para32[1] = (SK_U32)Val8;
+						if (SkGeSirqEvent(pAC, IoC,
+							SK_HWEV_SET_LMODE,
+							EventParam) > 0) {
+							
+							SK_ERR_LOG(pAC, SK_ERRCL_SW,
+								SK_PNMI_ERR043,
+								SK_PNMI_ERR043MSG);
+							
+							*pLen = 0;
+							return (SK_PNMI_ERR_GENERAL);
+						}
+					} /* for */
+				}
+				else {
+					/*
+					 * Send an event with the new link mode to
+					 * the SIRQ module.
+					 */
+					EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
+						pAC, LogPortIndex);
 					EventParam.Para32[1] = (SK_U32)Val8;
-					if (SkGeSirqEvent(pAC, IoC,
-						SK_HWEV_SET_LMODE,
+					if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
 						EventParam) > 0) {
-
+						
 						SK_ERR_LOG(pAC, SK_ERRCL_SW,
 							SK_PNMI_ERR043,
 							SK_PNMI_ERR043MSG);
-
+						
 						*pLen = 0;
 						return (SK_PNMI_ERR_GENERAL);
 					}
 				}
 			}
-			else {
+			else { /* DualNet mode. */
+
 				/*
 				 * Send an event with the new link mode to
 				 * the SIRQ module.
 				 */
-				EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
-					pAC, LogPortIndex);
+				EventParam.Para32[0] = NetIndex;
 				EventParam.Para32[1] = (SK_U32)Val8;
 				if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
 					EventParam) > 0) {
@@ -5584,15 +5380,13 @@
 					return (SK_PNMI_ERR_GENERAL);
 				}
 			}
-			Offset += sizeof(char);
+			Offset++;
 			break;
 
 		case OID_SKGE_FLOWCTRL_MODE:
-			/* Check the value range */
-			Val8 = *(pBuf + Offset);
+			/* Check the value range. */
 			if (Val8 == 0) {
-
-				Offset += sizeof(char);
+				Offset++;
 				break;
 			}
 			if (Val8 < SK_FLOW_MODE_NONE ||
@@ -5603,30 +5397,48 @@
 				return (SK_PNMI_ERR_BAD_VALUE);
 			}
 
-			/* The preset ends here */
+			/* The PRESET ends here. */
 			if (Action == SK_PNMI_PRESET) {
 
 				return (SK_PNMI_ERR_OK);
 			}
 
-			if (LogPortIndex == 0) {
+			if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+				if (LogPortIndex == 0) {
+					/*
+					 * The virtual port consists of all currently
+					 * active ports. Find them and send an event
+					 * with the new flow control mode to SIRQ.
+					 */
+					for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
+						PhysPortIndex ++) {
 
-				/*
-				 * The virtual port consists of all currently
-				 * active ports. Find them and send an event
-				 * with the new flow control mode to SIRQ.
-				 */
-				for (PhysPortIndex = 0;
-					PhysPortIndex < PhysPortMax;
-					PhysPortIndex ++) {
+						if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+							continue;
+						}
 
-					if (!pAC->Pnmi.Port[PhysPortIndex].
-						ActiveFlag) {
+						EventParam.Para32[0] = PhysPortIndex;
+						EventParam.Para32[1] = (SK_U32)Val8;
+						if (SkGeSirqEvent(pAC, IoC,
+							SK_HWEV_SET_FLOWMODE,
+							EventParam) > 0) {
+
+							SK_ERR_LOG(pAC, SK_ERRCL_SW,
+								SK_PNMI_ERR044,
+								SK_PNMI_ERR044MSG);
 
-						continue;
+							*pLen = 0;
+							return (SK_PNMI_ERR_GENERAL);
+						}
 					}
-
-					EventParam.Para32[0] = PhysPortIndex;
+				}
+				else {
+					/*
+					 * Send an event with the new flow control
+					 * mode to the SIRQ module.
+					 */
+					EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
+						pAC, LogPortIndex);
 					EventParam.Para32[1] = (SK_U32)Val8;
 					if (SkGeSirqEvent(pAC, IoC,
 						SK_HWEV_SET_FLOWMODE,
@@ -5641,17 +5453,16 @@
 					}
 				}
 			}
-			else {
+			else { /* DualNet mode. */
+				
 				/*
-				 * Send an event with the new flow control
-				 * mode to the SIRQ module.
+				 * Send an event with the new link mode to
+				 * the SIRQ module.
 				 */
-				EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
-					pAC, LogPortIndex);
+				EventParam.Para32[0] = NetIndex;
 				EventParam.Para32[1] = (SK_U32)Val8;
-				if (SkGeSirqEvent(pAC, IoC,
-					SK_HWEV_SET_FLOWMODE, EventParam)
-					> 0) {
+				if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_FLOWMODE,
+					EventParam) > 0) {
 
 					SK_ERR_LOG(pAC, SK_ERRCL_SW,
 						SK_PNMI_ERR044,
@@ -5661,15 +5472,14 @@
 					return (SK_PNMI_ERR_GENERAL);
 				}
 			}
-			Offset += sizeof(char);
+			Offset++;
 			break;
 
 		case OID_SKGE_PHY_OPERATION_MODE :
-			/* Check the value range */
-			Val8 = *(pBuf + Offset);
+			/* Check the value range. */
 			if (Val8 == 0) {
-				/* mode of this port remains unchanged */
-				Offset += sizeof(char);
+				/* Mode of this port remains unchanged. */
+				Offset++;
 				break;
 			}
 			if (Val8 < SK_MS_MODE_AUTO ||
@@ -5680,34 +5490,51 @@
 				return (SK_PNMI_ERR_BAD_VALUE);
 			}
 
-			/* The preset ends here */
+			/* The PRESET ends here. */
 			if (Action == SK_PNMI_PRESET) {
 
 				return (SK_PNMI_ERR_OK);
 			}
 
-			if (LogPortIndex == 0) {
+			if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+				if (LogPortIndex == 0) {
+					/*
+					 * The virtual port consists of all currently
+					 * active ports. Find them and send an event
+					 * with new master/slave (role) mode to SIRQ.
+					 */
+					for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
+						PhysPortIndex ++) {
 
-				/*
-				 * The virtual port consists of all currently
-				 * active ports. Find them and send an event
-				 * with new master/slave (role) mode to SIRQ.
-				 */
-				for (PhysPortIndex = 0;
-					PhysPortIndex < PhysPortMax;
-					PhysPortIndex ++) {
+						if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+							continue;
+						}
 
-					if (!pAC->Pnmi.Port[PhysPortIndex].
-						ActiveFlag) {
+						EventParam.Para32[0] = PhysPortIndex;
+						EventParam.Para32[1] = (SK_U32)Val8;
+						if (SkGeSirqEvent(pAC, IoC,
+							SK_HWEV_SET_ROLE,
+							EventParam) > 0) {
+
+							SK_ERR_LOG(pAC, SK_ERRCL_SW,
+								SK_PNMI_ERR042,
+								SK_PNMI_ERR042MSG);
 
-						continue;
+							*pLen = 0;
+							return (SK_PNMI_ERR_GENERAL);
+						}
 					}
-
-					EventParam.Para32[0] = PhysPortIndex;
+				}
+				else {
+					/*
+					 * Send an event with the new master/slave
+					 * (role) mode to the SIRQ module.
+					 */
+					EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
+						pAC, LogPortIndex);
 					EventParam.Para32[1] = (SK_U32)Val8;
 					if (SkGeSirqEvent(pAC, IoC,
-						SK_HWEV_SET_ROLE,
-						EventParam) > 0) {
+						SK_HWEV_SET_ROLE, EventParam) > 0) {
 
 						SK_ERR_LOG(pAC, SK_ERRCL_SW,
 							SK_PNMI_ERR042,
@@ -5718,16 +5545,16 @@
 					}
 				}
 			}
-			else {
+			else { /* DualNet mode. */
+
 				/*
-				 * Send an event with the new master/slave
-				 * (role) mode to the SIRQ module.
+				 * Send an event with the new link mode to
+				 * the SIRQ module.
 				 */
-				EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
-					pAC, LogPortIndex);
+				EventParam.Para32[0] = NetIndex;
 				EventParam.Para32[1] = (SK_U32)Val8;
-				if (SkGeSirqEvent(pAC, IoC,
-					SK_HWEV_SET_ROLE, EventParam) > 0) {
+				if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_ROLE,
+					EventParam) > 0) {
 
 					SK_ERR_LOG(pAC, SK_ERRCL_SW,
 						SK_PNMI_ERR042,
@@ -5737,16 +5564,13 @@
 					return (SK_PNMI_ERR_GENERAL);
 				}
 			}
-
-			Offset += sizeof(char);
+			Offset++;
 			break;
 
 		case OID_SKGE_SPEED_MODE:
-			/* Check the value range */
-			Val8 = *(pBuf + Offset);
+			/* Check the value range. */
 			if (Val8 == 0) {
-
-				Offset += sizeof(char);
+				Offset++;
 				break;
 			}
 			if (Val8 < (SK_LSPEED_AUTO) ||
@@ -5757,29 +5581,49 @@
 				return (SK_PNMI_ERR_BAD_VALUE);
 			}
 
-			/* The preset ends here */
+			/* The PRESET ends here. */
 			if (Action == SK_PNMI_PRESET) {
 
 				return (SK_PNMI_ERR_OK);
 			}
 
-			if (LogPortIndex == 0) {
+			if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+				if (LogPortIndex == 0) {
 
-				/*
-				 * The virtual port consists of all currently
-				 * active ports. Find them and send an event
-				 * with the new flow control mode to SIRQ.
-				 */
-				for (PhysPortIndex = 0;
-					PhysPortIndex < PhysPortMax;
-					PhysPortIndex ++) {
+					/*
+					 * The virtual port consists of all currently
+					 * active ports. Find them and send an event
+					 * with the new flow control mode to SIRQ.
+					 */
+					for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
+						PhysPortIndex ++) {
 
-					if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+						if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+							continue;
+						}
 
-						continue;
-					}
+						EventParam.Para32[0] = PhysPortIndex;
+						EventParam.Para32[1] = (SK_U32)Val8;
+						if (SkGeSirqEvent(pAC, IoC,
+							SK_HWEV_SET_SPEED,
+							EventParam) > 0) {
+
+							SK_ERR_LOG(pAC, SK_ERRCL_SW,
+								SK_PNMI_ERR045,
+								SK_PNMI_ERR045MSG);
 
-					EventParam.Para32[0] = PhysPortIndex;
+							*pLen = 0;
+							return (SK_PNMI_ERR_GENERAL);
+						}
+					}
+				}
+				else {
+					/*
+					 * Send an event with the new flow control
+					 * mode to the SIRQ module.
+					 */
+					EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
+						pAC, LogPortIndex);
 					EventParam.Para32[1] = (SK_U32)Val8;
 					if (SkGeSirqEvent(pAC, IoC,
 						SK_HWEV_SET_SPEED,
@@ -5794,16 +5638,15 @@
 					}
 				}
 			}
-			else {
+			else { /* DualNet mode. */
+				
 				/*
-				 * Send an event with the new flow control
-				 * mode to the SIRQ module.
+				 * Send an event with the new link mode to
+				 * the SIRQ module.
 				 */
-				EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
-					pAC, LogPortIndex);
+				EventParam.Para32[0] = NetIndex;
 				EventParam.Para32[1] = (SK_U32)Val8;
-				if (SkGeSirqEvent(pAC, IoC,
-					SK_HWEV_SET_SPEED,
+				if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_SPEED,
 					EventParam) > 0) {
 
 					SK_ERR_LOG(pAC, SK_ERRCL_SW,
@@ -5814,23 +5657,25 @@
 					return (SK_PNMI_ERR_GENERAL);
 				}
 			}
-			Offset += sizeof(char);
+			Offset++;
 			break;
 
-		case OID_SKGE_MTU :
-			/* Check the value range */
-			Val32 = *(SK_U32*)(pBuf + Offset);
+		case OID_SKGE_MTU:
+			/* Check the value range. */
+			SK_PNMI_READ_U32((pBuf + Offset), Val32);
+
 			if (Val32 == 0) {
-				/* mtu of this port remains unchanged */
+				/* MTU of this port remains unchanged. */
 				Offset += sizeof(SK_U32);
 				break;
 			}
+
 			if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
 				*pLen = 0;
 				return (SK_PNMI_ERR_BAD_VALUE);
 			}
 
-			/* The preset ends here */
+			/* The PRESET ends here. */
 			if (Action == SK_PNMI_PRESET) {
 				return (SK_PNMI_ERR_OK);
 			}
@@ -5841,116 +5686,69 @@
 
 			Offset += sizeof(SK_U32);
 			break;
-		
+
 #ifdef SK_PHY_LP_MODE
 		case OID_SKGE_PHY_LP_MODE:
-			/* The preset ends here */
+			/* The PRESET ends here. */
 			if (Action == SK_PNMI_PRESET) {
 
 				return (SK_PNMI_ERR_OK);
 			}
 
-			if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+			if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
 				if (LogPortIndex == 0) {
 					Offset = 0;
 					continue;
 				}
-				else {
-					/* Set value for physical ports */
-					PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
-
-					switch (*(pBuf + Offset)) {
-						case 0:
-							/* If LowPowerMode is active, we can leave it. */
-							if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
-
-								Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
-								
-								if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3)	{
-									
-									SkDrvInitAdapter(pAC);
-								}
-								break;
-							}
-							else {
-								*pLen = 0;
-								return (SK_PNMI_ERR_GENERAL);
-							}
-						case 1:
-						case 2:
-						case 3:
-						case 4:
-							/* If no LowPowerMode is active, we can enter it. */
-							if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
-
-								if ((*(pBuf + Offset)) < 3)	{
-								
-									SkDrvDeInitAdapter(pAC);
-								}
-
-								Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
-								break;
-							}
-							else {
-								*pLen = 0;
-								return (SK_PNMI_ERR_GENERAL);
-							}
-						default:
-							*pLen = 0;
-							return (SK_PNMI_ERR_BAD_VALUE);
-					}
-				}
 			}
-			else { /* DualNetMode */
-				
-				switch (*(pBuf + Offset)) {
-					case 0:
-						/* If we are in a LowPowerMode, we can leave it. */
-						if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
+			/* Set value for physical port. */
+			PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
+			CurrentPhyPowerState = pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
 
-							Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
-							
-							if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3)	{
+			switch (Val8) {
+				case PHY_PM_OPERATIONAL_MODE:
+					/* If LowPowerMode is active, we can leave it. */
+					if (CurrentPhyPowerState) {
 
-								SkDrvInitAdapter(pAC);
-							}
-							break;
-						}
-						else {
-							*pLen = 0;
-							return (SK_PNMI_ERR_GENERAL);
-						}
-					
-					case 1:
-					case 2:
-					case 3:
-					case 4:
-						/* If we are not already in LowPowerMode, we can enter it. */
-						if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
-
-							if ((*(pBuf + Offset)) < 3)	{
-
-								SkDrvDeInitAdapter(pAC);
-							}
-							else {
-
-								Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
-							}
-							break;
-						}
-						else {
-							*pLen = 0;
-							return (SK_PNMI_ERR_GENERAL);
+						Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
+						
+						if ((CurrentPhyPowerState == PHY_PM_DEEP_SLEEP) ||
+							(CurrentPhyPowerState == PHY_PM_IEEE_POWER_DOWN)) {
+							
+							SkDrvInitAdapter(pAC);
 						}
-					
-					default:
+						break;
+					}
+					else {
 						*pLen = 0;
-						return (SK_PNMI_ERR_BAD_VALUE);
-				}
+						return (SK_PNMI_ERR_GENERAL);
+					}
+				case PHY_PM_DEEP_SLEEP:
+				case PHY_PM_IEEE_POWER_DOWN:
+					/* If no LowPowerMode is active, we can enter it. */
+					if (!CurrentPhyPowerState) {
+						SkDrvDeInitAdapter(pAC);
+					}
+
+				case PHY_PM_ENERGY_DETECT:
+				case PHY_PM_ENERGY_DETECT_PLUS:
+					/* If no LowPowerMode is active, we can enter it. */
+					if (!CurrentPhyPowerState) {
+
+						Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
+						break;
+					}
+					else {
+						*pLen = 0;
+						return (SK_PNMI_ERR_GENERAL);
+					}
+				default:
+					*pLen = 0;
+					return (SK_PNMI_ERR_BAD_VALUE);
 			}
-			Offset += sizeof(SK_U8);
+			Offset++;
 			break;
-#endif
+#endif /* SK_PHY_LP_MODE */
 
 		default:
             SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
@@ -6000,14 +5798,11 @@
 	unsigned int	Limit;
 	unsigned int	Offset;
 	unsigned int	Entries;
-
 	
-	/*
-	 * Calculate instance if wished.
-	 */
-	/* XXX Not yet implemented. Return always an empty table. */
+	/* Not implemented yet. Return always an empty table. */
 	Entries = 0;
 
+	/* Calculate instance if wished. */
 	if ((Instance != (SK_U32)(-1))) {
 
 		if ((Instance < 1) || (Instance > Entries)) {
@@ -6024,12 +5819,10 @@
 		Limit = Entries;
 	}
 
-	/*
-	 * Get/Set value
-	*/
+	/* GET/SET value. */
 	if (Action == SK_PNMI_GET) {
 
-		for (Offset=0; Index < Limit; Index ++) {
+		for (Offset = 0; Index < Limit; Index ++) {
 
 			switch (Id) {
 
@@ -6051,32 +5844,29 @@
 		*pLen = Offset;
 	}
 	else {
-		/* Only MONITOR_ADMIN can be set */
+		/* Only MONITOR_ADMIN can be set. */
 		if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_READ_ONLY);
 		}
 
-		/* Check if the length is plausible */
+		/* Check if the length is plausible. */
 		if (*pLen < (Limit - Index)) {
 
 			return (SK_PNMI_ERR_TOO_SHORT);
 		}
-		/* Okay, we have a wide value range */
+		/* Okay, we have a wide value range. */
 		if (*pLen != (Limit - Index)) {
 
 			*pLen = 0;
 			return (SK_PNMI_ERR_BAD_VALUE);
 		}
-/*
-		for (Offset=0; Index < Limit; Index ++) {
-		}
-*/
-/*
- * XXX Not yet implemented. Return always BAD_VALUE, because the table
- * is empty.
- */
+
+		/*
+		 * Not yet implemented. Return always BAD_VALUE,
+		 * because the table is empty.
+		 */
 		*pLen = 0;
 		return (SK_PNMI_ERR_BAD_VALUE);
 	}
@@ -6117,14 +5907,12 @@
 	PortActiveFlag = SK_FALSE;
 	PhysPortMax = pAC->GIni.GIMacsFound;
 	
-	for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
-		PhysPortIndex ++) {
+	for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; PhysPortIndex ++) {
 
 		pPrt = &pAC->GIni.GP[PhysPortIndex];
 
-		/* Check if the physical port is active */
+		/* Check if the physical port is active. */
 		if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
-
 			continue;
 		}
 
@@ -6133,12 +5921,13 @@
 		switch (Id) {
 
 		case OID_SKGE_PHY_TYPE:
-			/* Check if it is the first active port */
+			/* Check if it is the first active port. */
 			if (*pBuf == 0) {
 				Val32 = pPrt->PhyType;
 				SK_PNMI_STORE_U32(pBuf, Val32);
 				continue;
 			}
+			break;
 
 		case OID_SKGE_LINK_CAP:
 
@@ -6152,7 +5941,7 @@
 			break;
 
 		case OID_SKGE_LINK_MODE:
-			/* Check if it is the first active port */
+			/* Check if it is the first active port. */
 			if (*pBuf == 0) {
 
 				*pBuf = pPrt->PLinkModeConf;
@@ -6160,9 +5949,8 @@
 			}
 
 			/*
-			 * If we find an active port with a different link
-			 * mode than the first one we return a value that
-			 * indicates that the link mode is indeterminated.
+			 * If we find an active port with a different link mode
+			 * than the first one we return indeterminated.
 			 */
 			if (*pBuf != pPrt->PLinkModeConf) {
 
@@ -6171,10 +5959,10 @@
 			break;
 
 		case OID_SKGE_LINK_MODE_STATUS:
-			/* Get the link mode of the physical port */
+			/* Get the link mode of the physical port. */
 			Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
 
-			/* Check if it is the first active port */
+			/* Check if it is the first active port. */
 			if (*pBuf == 0) {
 
 				*pBuf = Val8;
@@ -6182,10 +5970,8 @@
 			}
 
 			/*
-			 * If we find an active port with a different link
-			 * mode status than the first one we return a value
-			 * that indicates that the link mode status is
-			 * indeterminated.
+			 * If we find an active port with a different link mode status
+			 * than the first one we return indeterminated.
 			 */
 			if (*pBuf != Val8) {
 
@@ -6194,10 +5980,10 @@
 			break;
 
 		case OID_SKGE_LINK_STATUS:
-			/* Get the link status of the physical port */
+			/* Get the link status of the physical port. */
 			Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
 
-			/* Check if it is the first active port */
+			/* Check if it is the first active port. */
 			if (*pBuf == 0) {
 
 				*pBuf = Val8;
@@ -6205,10 +5991,8 @@
 			}
 
 			/*
-			 * If we find an active port with a different link
-			 * status than the first one, we return a value
-			 * that indicates that the link status is
-			 * indeterminated.
+			 * If we find an active port with a different link status
+			 * than the first one we return indeterminated.
 			 */
 			if (*pBuf != Val8) {
 
@@ -6217,7 +6001,7 @@
 			break;
 
 		case OID_SKGE_FLOWCTRL_CAP:
-			/* Check if it is the first active port */
+			/* Check if it is the first active port. */
 			if (*pBuf == 0) {
 
 				*pBuf = pPrt->PFlowCtrlCap;
@@ -6232,7 +6016,7 @@
 			break;
 
 		case OID_SKGE_FLOWCTRL_MODE:
-			/* Check if it is the first active port */
+			/* Check if it is the first active port. */
 			if (*pBuf == 0) {
 
 				*pBuf = pPrt->PFlowCtrlMode;
@@ -6240,9 +6024,8 @@
 			}
 
 			/*
-			 * If we find an active port with a different flow
-			 * control mode than the first one, we return a value
-			 * that indicates that the mode is indeterminated.
+			 * If we find an active port with a different flow-control mode
+			 * than the first one we return indeterminated.
 			 */
 			if (*pBuf != pPrt->PFlowCtrlMode) {
 
@@ -6251,7 +6034,7 @@
 			break;
 
 		case OID_SKGE_FLOWCTRL_STATUS:
-			/* Check if it is the first active port */
+			/* Check if it is the first active port. */
 			if (*pBuf == 0) {
 
 				*pBuf = pPrt->PFlowCtrlStatus;
@@ -6259,10 +6042,8 @@
 			}
 
 			/*
-			 * If we find an active port with a different flow
-			 * control status than the first one, we return a
-			 * value that indicates that the status is
-			 * indeterminated.
+			 * If we find an active port with a different flow-control status
+			 * than the first one we return indeterminated.
 			 */
 			if (*pBuf != pPrt->PFlowCtrlStatus) {
 
@@ -6271,7 +6052,7 @@
 			break;
 		
 		case OID_SKGE_PHY_OPERATION_CAP:
-			/* Check if it is the first active port */
+			/* Check if it is the first active port. */
 			if (*pBuf == 0) {
 
 				*pBuf = pPrt->PMSCap;
@@ -6286,7 +6067,7 @@
 			break;
 
 		case OID_SKGE_PHY_OPERATION_MODE:
-			/* Check if it is the first active port */
+			/* Check if it is the first active port. */
 			if (*pBuf == 0) {
 
 				*pBuf = pPrt->PMSMode;
@@ -6294,9 +6075,8 @@
 			}
 
 			/*
-			 * If we find an active port with a different master/
-			 * slave mode than the first one, we return a value
-			 * that indicates that the mode is indeterminated.
+			 * If we find an active port with a different master/slave mode
+			 * than the first one we return indeterminated.
 			 */
 			if (*pBuf != pPrt->PMSMode) {
 
@@ -6305,7 +6085,7 @@
 			break;
 
 		case OID_SKGE_PHY_OPERATION_STATUS:
-			/* Check if it is the first active port */
+			/* Check if it is the first active port. */
 			if (*pBuf == 0) {
 
 				*pBuf = pPrt->PMSStatus;
@@ -6313,10 +6093,8 @@
 			}
 
 			/*
-			 * If we find an active port with a different master/
-			 * slave status than the first one, we return a
-			 * value that indicates that the status is
-			 * indeterminated.
+			 * If we find an active port with a different master/slave status
+			 * than the first one we return indeterminated.
 			 */
 			if (*pBuf != pPrt->PMSStatus) {
 
@@ -6325,7 +6103,7 @@
 			break;
 		
 		case OID_SKGE_SPEED_MODE:
-			/* Check if it is the first active port */
+			/* Check if it is the first active port. */
 			if (*pBuf == 0) {
 
 				*pBuf = pPrt->PLinkSpeed;
@@ -6333,9 +6111,8 @@
 			}
 
 			/*
-			 * If we find an active port with a different flow
-			 * control mode than the first one, we return a value
-			 * that indicates that the mode is indeterminated.
+			 * If we find an active port with a different link speed
+			 * than the first one we return indeterminated.
 			 */
 			if (*pBuf != pPrt->PLinkSpeed) {
 
@@ -6344,7 +6121,7 @@
 			break;
 		
 		case OID_SKGE_SPEED_STATUS:
-			/* Check if it is the first active port */
+			/* Check if it is the first active port. */
 			if (*pBuf == 0) {
 
 				*pBuf = pPrt->PLinkSpeedUsed;
@@ -6352,10 +6129,8 @@
 			}
 
 			/*
-			 * If we find an active port with a different flow
-			 * control status than the first one, we return a
-			 * value that indicates that the status is
-			 * indeterminated.
+			 * If we find an active port with a different link speed used
+			 * than the first one we return indeterminated.
 			 */
 			if (*pBuf != pPrt->PLinkSpeedUsed) {
 
@@ -6365,9 +6140,7 @@
 		}
 	}
 
-	/*
-	 * If no port is active return an indeterminated answer
-	 */
+	/* If no port is active return an indeterminated answer. */
 	if (!PortActiveFlag) {
 
 		switch (Id) {
@@ -6484,16 +6257,15 @@
 {
 	SK_U8	Result;
 
-	/* Get the current mode, which can be full or half duplex */
+	/* Get the current mode, which can be full or half duplex. */
 	Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
 
-	/* Check if no valid mode could be found (link is down) */
+	/* Check if no valid mode could be found (link is down). */
 	if (Result < SK_LMODE_STAT_HALF) {
 
 		Result = SK_LMODE_STAT_UNKNOWN;
 	}
 	else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
-
 		/*
 		 * Auto-negotiation was used to bring up the link. Change
 		 * the already found duplex status that it indicates
@@ -6538,22 +6310,19 @@
 	int			Index;
 	int			Ret;
 
-
 	SK_MEMSET(pKeyArr, 0, KeyArrLen);
 
-	/*
-	 * Get VPD key list
-	 */
+	/* Get VPD key list. */
 	Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
 		(int *)pKeyNo);
+	
 	if (Ret > 0) {
 
-		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
-			SK_PNMI_ERR014MSG);
+		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014, SK_PNMI_ERR014MSG);
 
 		return (SK_PNMI_ERR_GENERAL);
 	}
-	/* If no keys are available return now */
+	/* If no keys are available return now. */
 	if (*pKeyNo == 0 || BufKeysLen == 0) {
 
 		return (SK_PNMI_ERR_OK);
@@ -6561,12 +6330,11 @@
 	/*
 	 * If the key list is too long for us trunc it and give a
 	 * errorlog notification. This case should not happen because
-	 * the maximum number of keys is limited due to RAM limitations
+	 * the maximum number of keys is limited due to RAM limitations.
 	 */
 	if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
 
-		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
-			SK_PNMI_ERR015MSG);
+		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015, SK_PNMI_ERR015MSG);
 
 		*pKeyNo = SK_PNMI_VPD_ENTRIES;
 	}
@@ -6579,14 +6347,12 @@
 		Offset ++) {
 
 		if (BufKeys[Offset] != 0) {
-
 			continue;
 		}
 
 		if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
 
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
-				SK_PNMI_ERR016MSG);
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016, SK_PNMI_ERR016MSG);
 			return (SK_PNMI_ERR_GENERAL);
 		}
 
@@ -6597,7 +6363,7 @@
 		StartOffset = Offset + 1;
 	}
 
-	/* Last key not zero terminated? Get it anyway */
+	/* Last key not zero terminated? Get it anyway. */
 	if (StartOffset < Offset) {
 
 		SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
@@ -6626,19 +6392,18 @@
 {
 	SK_EVPARA	EventParam;
 
-
 	/* Was the module already updated during the current PNMI call? */
 	if (pAC->Pnmi.SirqUpdatedFlag > 0) {
 
 		return (SK_PNMI_ERR_OK);
 	}
 
-	/* Send an synchronuous update event to the module */
+	/* Send an synchronuous update event to the module. */
 	SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
-	if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
+	
+	if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam)) {
 
-		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
-			SK_PNMI_ERR047MSG);
+		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047, SK_PNMI_ERR047MSG);
 
 		return (SK_PNMI_ERR_GENERAL);
 	}
@@ -6666,21 +6431,19 @@
 {
 	SK_EVPARA	EventParam;
 
-
 	/* Was the module already updated during the current PNMI call? */
 	if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
 
 		return (SK_PNMI_ERR_OK);
 	}
 
-	/* Send an synchronuous update event to the module */
+	/* Send an synchronuous update event to the module. */
 	SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 	EventParam.Para32[0] = NetIndex;
 	EventParam.Para32[1] = (SK_U32)-1;
 	if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
 
-		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
-			SK_PNMI_ERR048MSG);
+		SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048, SK_PNMI_ERR048MSG);
 
 		return (SK_PNMI_ERR_GENERAL);
 	}
@@ -6718,20 +6481,20 @@
 		return (SK_PNMI_ERR_OK);
 	}
 
-	/* Send an update command to all MACs specified */
+	/* Send an update command to all MACs specified. */
 	for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
 
 		/*
 		 * 2002-09-13 pweber:	Freeze the current SW counters.
 		 *                      (That should be done as close as
 		 *                      possible to the update of the
-		 *                      HW counters)
+		 *                      HW counters).
 		 */
 		if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
 			pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
 		}
 			
-		/* 2002-09-13 pweber:  Update the HW counter  */
+		/* 2002-09-13 pweber:  Update the HW counter.  */
 		if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
 
 			return (SK_PNMI_ERR_GENERAL);
@@ -6769,19 +6532,19 @@
 	SK_U64			Val = 0;
 
 
-	if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {	/* Dual net mode */
+	if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {	/* DualNet mode. */
 
 		PhysPortIndex = NetIndex;
 		
 		Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
 	}
-	else {	/* Single Net mode */
+	else {	/* SingleNet mode. */
 
 		if (LogPortIndex == 0) {
 
 			PhysPortMax = pAC->GIni.GIMacsFound;
 
-			/* Add counter of all active ports */
+			/* Add counter of all active ports. */
 			for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
 				PhysPortIndex ++) {
 
@@ -6791,11 +6554,11 @@
 				}
 			}
 
-			/* Correct value because of port switches */
+			/* Correct value because of port switches. */
 			Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
 		}
 		else {
-			/* Get counter value of physical port */
+			/* Get counter value of physical port. */
 			PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
 			
 			Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
@@ -6841,7 +6604,7 @@
 	
 	MacType = pAC->GIni.GIMacType;
 	
-	/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
+	/* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
 	if (MacType == SK_MAC_XMAC) {
 		pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
 	}
@@ -6909,7 +6672,7 @@
 	case SK_PNMI_HTX_BURST:
 	case SK_PNMI_HTX_EXCESS_DEF:
 	case SK_PNMI_HTX_CARRIER:
-		/* Not supported by GMAC */
+		/* Not supported by GMAC. */
 		if (MacType == SK_MAC_GMAC) {
 			return (Val);
 		}
@@ -6921,7 +6684,7 @@
 		break;
 
 	case SK_PNMI_HTX_MACC:
-		/* GMAC only supports PAUSE MAC control frames */
+		/* GMAC only supports PAUSE MAC control frames. */
 		if (MacType == SK_MAC_GMAC) {
 			HelpIndex = SK_PNMI_HTX_PMACC;
 		}
@@ -6938,7 +6701,7 @@
 
 	case SK_PNMI_HTX_COL:
 	case SK_PNMI_HRX_UNDERSIZE:
-		/* Not supported by XMAC */
+		/* Not supported by XMAC. */
 		if (MacType == SK_MAC_XMAC) {
 			return (Val);
 		}
@@ -6950,7 +6713,7 @@
 		break;
 
 	case SK_PNMI_HTX_DEFFERAL:
-		/* Not supported by GMAC */
+		/* Not supported by GMAC. */
 		if (MacType == SK_MAC_GMAC) {
 			return (Val);
 		}
@@ -6968,7 +6731,7 @@
 			HighVal = 0;
 		}
 		else {
-			/* Otherwise get contents of hardware register */
+			/* Otherwise get contents of hardware register. */
 			(void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 										  StatAddr[StatIndex][MacType].Reg,
 										  &LowVal);
@@ -6977,7 +6740,7 @@
 		break;
 
 	case SK_PNMI_HRX_BADOCTET:
-		/* Not supported by XMAC */
+		/* Not supported by XMAC. */
 		if (MacType == SK_MAC_XMAC) {
 			return (Val);
 		}
@@ -6996,7 +6759,7 @@
 		return (Val);
 
 	case SK_PNMI_HRX_LONGFRAMES:
-		/* For XMAC the SW counter is managed by PNMI */
+		/* For XMAC the SW counter is managed by PNMI. */
 		if (MacType == SK_MAC_XMAC) {
 			return (pPnmiPrt->StatRxLongFrameCts);
 		}
@@ -7016,7 +6779,7 @@
 		Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
 
 		if (MacType == SK_MAC_GMAC) {
-			/* For GMAC the SW counter is additionally managed by PNMI */
+			/* For GMAC the SW counter is additionally managed by PNMI. */
 			Val += pPnmiPrt->StatRxFrameTooLongCts;
 		}
 		else {
@@ -7034,20 +6797,19 @@
 		break;
 		
 	case SK_PNMI_HRX_SHORTS:
-		/* Not supported by GMAC */
+		/* Not supported by GMAC. */
 		if (MacType == SK_MAC_GMAC) {
 			/* GM_RXE_FRAG?? */
 			return (Val);
 		}
 		
 		/*
-		 * XMAC counts short frame errors even if link down (#10620)
-		 *
-		 * If link-down the counter remains constant
+		 * XMAC counts short frame errors even if link down (#10620).
+		 * If the link is down, the counter remains constant.
 		 */
 		if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
 
-			/* Otherwise get incremental difference */
+			/* Otherwise get incremental difference. */
 			(void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
 										  StatAddr[StatIndex][MacType].Reg,
 										  &LowVal);
@@ -7070,7 +6832,7 @@
 	case SK_PNMI_HRX_IRLENGTH:
 	case SK_PNMI_HRX_SYMBOL:
 	case SK_PNMI_HRX_CEXT:
-		/* Not supported by GMAC */
+		/* Not supported by GMAC. */
 		if (MacType == SK_MAC_GMAC) {
 			return (Val);
 		}
@@ -7082,7 +6844,7 @@
 		break;
 
 	case SK_PNMI_HRX_PMACC_ERR:
-		/* For GMAC the SW counter is managed by PNMI */
+		/* For GMAC the SW counter is managed by PNMI. */
 		if (MacType == SK_MAC_GMAC) {
 			return (pPnmiPrt->StatRxPMaccErr);
 		}
@@ -7093,13 +6855,13 @@
 		HighVal = pPnmiPrt->CounterHigh[StatIndex];
 		break;
 
-	/* SW counter managed by PNMI */
+	/* SW counter managed by PNMI. */
 	case SK_PNMI_HTX_SYNC:
 		LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
 		HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
 		break;
 
-	/* SW counter managed by PNMI */
+	/* SW counter managed by PNMI. */
 	case SK_PNMI_HTX_SYNC_OCTET:
 		LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
 		HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
@@ -7107,17 +6869,19 @@
 
 	case SK_PNMI_HRX_FCS:
 		/*
-		 * Broadcom filters FCS errors and counts it in
-		 * Receive Error Counter register
+		 * Broadcom filters FCS errors and counts them in
+		 * Receive Error Counter register.
 		 */
 		if (pPrt->PhyType == SK_PHY_BCOM) {
-			/* do not read while not initialized (PHY_READ hangs!)*/
+#ifdef GENESIS
+			/* Do not read while not initialized (PHY_READ hangs!). */
 			if (pPrt->PState != SK_PRT_RESET) {
 				SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
 				
 				LowVal = Word;
 			}
 			HighVal = pPnmiPrt->CounterHigh[StatIndex];
+#endif /* GENESIS */
 		}
 		else {
 			(void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
@@ -7137,7 +6901,7 @@
 
 	Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
 
-	/* Correct value because of possible XMAC reset. XMAC Errata #2 */
+	/* Correct value because of possible XMAC reset (XMAC Errata #2). */
 	Val += pPnmiPrt->CounterOffset[StatIndex];
 
 	return (Val);
@@ -7162,22 +6926,21 @@
 	unsigned int	PhysPortIndex;
 	SK_EVPARA	EventParam;
 
-
 	SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
 
-	/* Notify sensor module */
+	/* Notify sensor module. */
 	SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
 
-	/* Notify RLMT module */
+	/* Notify RLMT module. */
 	EventParam.Para32[0] = NetIndex;
 	EventParam.Para32[1] = (SK_U32)-1;
 	SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
 	EventParam.Para32[1] = 0;
 
-	/* Notify SIRQ module */
+	/* Notify SIRQ module. */
 	SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
 
-	/* Notify CSUM module */
+	/* Notify CSUM module. */
 #ifdef SK_USE_CSUM
 	EventParam.Para32[0] = NetIndex;
 	EventParam.Para32[1] = (SK_U32)-1;
@@ -7185,7 +6948,7 @@
 		EventParam);
 #endif /* SK_USE_CSUM */
 	
-	/* Clear XMAC statistic */
+	/* Clear XMAC statistics. */
 	for (PhysPortIndex = 0; PhysPortIndex <
 		(unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
 
@@ -7212,13 +6975,13 @@
 			PhysPortIndex].StatRxPMaccErr));
 	}
 
-	/*
-	 * Clear local statistics
-	 */
+	/* Clear local statistics. */
 	SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
 		  sizeof(pAC->Pnmi.VirtualCounterOffset));
+	
 	pAC->Pnmi.RlmtChangeCts = 0;
 	pAC->Pnmi.RlmtChangeTime = 0;
+	
 	SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
 		sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
 	pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
@@ -7255,23 +7018,21 @@
 SK_U32 TrapId,		/* SNMP ID of the trap */
 unsigned int Size)	/* Space needed for trap entry */
 {
-	unsigned int		BufPad = pAC->Pnmi.TrapBufPad;
-	unsigned int		BufFree = pAC->Pnmi.TrapBufFree;
-	unsigned int		Beg = pAC->Pnmi.TrapQueueBeg;
-	unsigned int		End = pAC->Pnmi.TrapQueueEnd;
+	unsigned int	BufPad = pAC->Pnmi.TrapBufPad;
+	unsigned int	BufFree = pAC->Pnmi.TrapBufFree;
+	unsigned int	Beg = pAC->Pnmi.TrapQueueBeg;
+	unsigned int	End = pAC->Pnmi.TrapQueueEnd;
 	char			*pBuf = &pAC->Pnmi.TrapBuf[0];
 	int			Wrap;
-	unsigned int		NeededSpace;
-	unsigned int		EntrySize;
+	unsigned int	NeededSpace;
+	unsigned int	EntrySize;
 	SK_U32			Val32;
 	SK_U64			Val64;
 
-
-	/* Last byte of entry will get a copy of the entry length */
+	/* Last byte of entry will get a copy of the entry length. */
 	Size ++;
 
-	/*
-	 * Calculate needed buffer space */
+	/* Calculate needed buffer space. */
 	if (Beg >= Size) {
 
 		NeededSpace = Size;
@@ -7286,7 +7047,7 @@
 	 * Check if enough buffer space is provided. Otherwise
 	 * free some entries. Leave one byte space between begin
 	 * and end of buffer to make it possible to detect whether
-	 * the buffer is full or empty
+	 * the buffer is full or empty.
 	 */
 	while (BufFree < NeededSpace + 1) {
 
@@ -7325,13 +7086,13 @@
 	}
 	BufFree -= NeededSpace;
 
-	/* Save the current offsets */
+	/* Save the current offsets. */
 	pAC->Pnmi.TrapQueueBeg = Beg;
 	pAC->Pnmi.TrapQueueEnd = End;
 	pAC->Pnmi.TrapBufPad = BufPad;
 	pAC->Pnmi.TrapBufFree = BufFree;
 
-	/* Initialize the trap entry */
+	/* Initialize the trap entry. */
 	*(pBuf + Beg + Size - 1) = (char)Size;
 	*(pBuf + Beg) = (char)Size;
 	Val32 = (pAC->Pnmi.TrapUnique) ++;
@@ -7366,7 +7127,6 @@
 	unsigned int	Len;
 	unsigned int	DstOff = 0;
 
-
 	while (Trap != End) {
 
 		Len = (unsigned int)*(pBuf + Trap);
@@ -7411,7 +7171,6 @@
 	unsigned int	Entries = 0;
 	unsigned int	TotalLen = 0;
 
-
 	while (Trap != End) {
 
 		Len = (unsigned int)*(pBuf + Trap);
@@ -7468,14 +7227,14 @@
 	unsigned int	DescrLen;
 	SK_U32		Val32;
 
-
-	/* Get trap buffer entry */
+	/* Get trap buffer entry. */
 	DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
+	
 	pBuf = GetTrapEntry(pAC, TrapId,
 		SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
 	Offset = SK_PNMI_TRAP_SIMPLE_LEN;
 
-	/* Store additionally sensor trap related data */
+	/* Store additionally sensor trap related data. */
 	Val32 = OID_SKGE_SENSOR_INDEX;
 	SK_PNMI_STORE_U32(pBuf + Offset, Val32);
 	*(pBuf + Offset + 4) = 4;
@@ -7520,7 +7279,6 @@
 	char	*pBuf;
 	SK_U32	Val32;
 
-
 	pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
 		SK_PNMI_TRAP_RLMT_CHANGE_LEN);
 
@@ -7548,7 +7306,6 @@
 	char	*pBuf;
 	SK_U32	Val32;
 
-
 	pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
 
 	Val32 = OID_SKGE_RLMT_PORT_INDEX;
@@ -7568,12 +7325,11 @@
  *	Nothing
  */
 PNMI_STATIC void CopyMac(
-char *pDst,		/* Pointer to destination buffer */
+char		*pDst,	/* Pointer to destination buffer */
 SK_MAC_ADDR *pMac)	/* Pointer of Source */
 {
 	int	i;
 
-
 	for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
 
 		*(pDst + i) = pMac->a[i];
@@ -7613,17 +7369,14 @@
 	
 	SK_U32	RetCode = SK_PNMI_ERR_GENERAL;
 
-	/*
-	 * Check instance. We only handle single instance variables
-	 */
+	/* Check instance. We only handle single instance variables. */
 	if (Instance != (SK_U32)(-1) && Instance != 1) {
 
 		*pLen = 0;
 		return (SK_PNMI_ERR_UNKNOWN_INST);
 	}
 	
-    
-    /* Check length */
+    /* Check length. */
     switch (Id) {
 
     case OID_PNP_CAPABILITIES:
@@ -7661,14 +7414,10 @@
         break;
     }
 	
-    /*
-	 * Perform action
-	 */
+	/* Perform action. */
 	if (Action == SK_PNMI_GET) {
 
-		/*
-		 * Get value
-		 */
+		/* Get value. */
 		switch (Id) {
 
 		case OID_PNP_CAPABILITIES:
@@ -7676,18 +7425,21 @@
 			break;
 
 		case OID_PNP_QUERY_POWER:
-			/* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
-			 the miniport to indicate whether it can transition its NIC
-			 to the low-power state.
-			 A miniport driver must always return NDIS_STATUS_SUCCESS
-			 to a query of OID_PNP_QUERY_POWER. */
+			/*
+			 * The Windows DDK describes: An OID_PNP_QUERY_POWER requests
+			 * the miniport to indicate whether it can transition its NIC
+			 * to the low-power state.
+			 * A miniport driver must always return NDIS_STATUS_SUCCESS
+			 * to a query of OID_PNP_QUERY_POWER.
+			 */
 			*pLen = sizeof(SK_DEVICE_POWER_STATE);;
             RetCode = SK_PNMI_ERR_OK;
 			break;
 
-			/* NDIS handles these OIDs as write-only.
+			/*
+			 * NDIS handles these OIDs as write-only.
 			 * So in case of get action the buffer with written length = 0
-			 * is returned
+			 * is returned.
 			 */
 		case OID_PNP_SET_POWER:
 		case OID_PNP_ADD_WAKE_UP_PATTERN:
@@ -7708,13 +7460,11 @@
 		return (RetCode);
 	}
 	
-
-	/*
-	 * Perform preset or set
-	 */
+	/* Perform PRESET or SET. */
 	
-	/* POWER module does not support PRESET action */
+	/* The POWER module does not support PRESET action. */
 	if (Action == SK_PNMI_PRESET) {
+
 		return (SK_PNMI_ERR_OK);
 	}
 
@@ -7746,7 +7496,7 @@
 #ifdef SK_DIAG_SUPPORT
 /*****************************************************************************
  *
- * DiagActions - OID handler function of Diagnostic driver 
+ * DiagActions - OID handler function of Diagnostic driver
  *
  * Description:
  *	The code is simple. No description necessary.
@@ -7773,22 +7523,17 @@
 unsigned int TableIndex, /* Index to the Id table */
 SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode always zero */
 {
-
 	SK_U32	DiagStatus;
 	SK_U32	RetCode = SK_PNMI_ERR_GENERAL;
 
-	/*
-	 * Check instance. We only handle single instance variables.
-	 */
+	/* Check instance. We only handle single instance variables. */
 	if (Instance != (SK_U32)(-1) && Instance != 1) {
 
 		*pLen = 0;
 		return (SK_PNMI_ERR_UNKNOWN_INST);
 	}
 
-	/*
-	 * Check length.
-	 */
+    /* Check length. */
 	switch (Id) {
 
 	case OID_SKGE_DIAG_MODE:
@@ -7806,10 +7551,9 @@
 	}
 
 	/* Perform action. */
-
-	/* GET value. */
 	if (Action == SK_PNMI_GET) {
 
+		/* Get value. */
 		switch (Id) {
 
 		case OID_SKGE_DIAG_MODE:
@@ -7824,14 +7568,15 @@
 			RetCode = SK_PNMI_ERR_GENERAL;
 			break;
 		}
-		return (RetCode); 
+		return (RetCode);
 	}
 
 	/* From here SET or PRESET value. */
 	
 	/* PRESET value is not supported. */
 	if (Action == SK_PNMI_PRESET) {
-		return (SK_PNMI_ERR_OK); 
+
+		return (SK_PNMI_ERR_OK);
 	}
 
 	/* SET value. */
@@ -7843,7 +7588,7 @@
 
 				/* Attach the DIAG to this adapter. */
 				case SK_DIAG_ATTACHED:
-					/* Check if we come from running */
+					/* Check if we come from running. */
 					if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
 
 						RetCode = SkDrvLeaveDiagMode(pAC);
@@ -7878,7 +7623,7 @@
 						/* If DiagMode is not active, we can enter it. */
 						if (!pAC->DiagModeActive) {
 
-							RetCode = SkDrvEnterDiagMode(pAC); 
+							RetCode = SkDrvEnterDiagMode(pAC);
 						}
 						else {
 
@@ -7897,7 +7642,7 @@
 					break;
 
 				case SK_DIAG_IDLE:
-					/* Check if we come from running */
+					/* Check if we come from running. */
 					if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
 
 						RetCode = SkDrvLeaveDiagMode(pAC);
@@ -7943,7 +7688,7 @@
 
 /*****************************************************************************
  *
- * Vct - OID handler function of  OIDs
+ * Vct - OID handler function of OIDs for Virtual Cable Tester (VCT)
  *
  * Description:
  *	The code is simple. No description necessary.
@@ -7979,15 +7724,13 @@
 	SK_U32		PhysPortIndex;
 	SK_U32		Limit;
 	SK_U32		Offset;
-	SK_BOOL		Link;
-	SK_U32		RetCode = SK_PNMI_ERR_GENERAL;
-	int		i;
+	SK_U32		RetCode;
+	int			i;
 	SK_EVPARA	Para;
-	SK_U32		CableLength;
 	
-	/*
-	 * Calculate the port indexes from the instance.
-	 */
+	RetCode = SK_PNMI_ERR_GENERAL;
+	
+	/* Calculate the port indexes from the instance. */
 	PhysPortMax = pAC->GIni.GIMacsFound;
 	LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
 	
@@ -7997,7 +7740,11 @@
 	}
 	
 	if ((Instance != (SK_U32) (-1))) {
-		/* Check instance range. */
+		/*
+		 * Get one instance of that OID, so check the instance range:
+		 * There is no virtual port with an Instance == 1, so we get
+		 * the values from one physical port only.
+		 */
 		if ((Instance < 2) || (Instance > LogPortMax)) {
 			*pLen = 0;
 			return (SK_PNMI_ERR_UNKNOWN_INST);
@@ -8013,34 +7760,26 @@
 	}
 	else {
 		/*
-		 * Instance == (SK_U32) (-1), get all Instances of that OID.
-		 *
-		 * Not implemented yet. May be used in future releases.
+		 * Instance == (SK_U32) (-1), so get all instances of that OID.
+		 * There is no virtual port with an Instance == 1, so we get
+		 * the values from all physical ports.
 		 */
 		PhysPortIndex = 0;
 		Limit = PhysPortMax;
 	}
 	
 	pPrt = &pAC->GIni.GP[PhysPortIndex];
-	if (pPrt->PHWLinkUp) {
-		Link = SK_TRUE;
-	}
-	else {
-		Link = SK_FALSE;
-	}
 	
-	/* Check MAC type */
-	if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
+	/* Check MAC type. */
+	if ((Id != OID_SKGE_VCT_CAPABILITIES) &&
+		(pPrt->PhyType != SK_PHY_MARV_COPPER)) {
 		*pLen = 0;
-		return (SK_PNMI_ERR_GENERAL);
+		return (SK_PNMI_ERR_NOT_SUPPORTED);
 	}
 	
-	/* Initialize backup data pointer. */
-	pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
-	
-	/* Check action type */
+	/* Check action type. */
 	if (Action == SK_PNMI_GET) {
-		/* Check length */
+		/* Check length. */
 		switch (Id) {
 		
 		case OID_SKGE_VCT_GET:
@@ -8051,6 +7790,7 @@
 			break;
 		
 		case OID_SKGE_VCT_STATUS:
+		case OID_SKGE_VCT_CAPABILITIES:
 			if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
 				*pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
 				return (SK_PNMI_ERR_TOO_SHORT);
@@ -8062,70 +7802,73 @@
 			return (SK_PNMI_ERR_GENERAL);
 		}	
 		
-		/* Get value */
+		/* Get value. */
 		Offset = 0;
 		for (; PhysPortIndex < Limit; PhysPortIndex++) {
+			
 			switch (Id) {
 			
 			case OID_SKGE_VCT_GET:
-				if ((Link == SK_FALSE) &&
+				if (!pPrt->PHWLinkUp &&
 					(pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
+
 					RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
+					
 					if (RetCode == 0) {
-						pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
-						pAC->Pnmi.VctStatus[PhysPortIndex] |=
-							(SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
 						
-						/* Copy results for later use to PNMI struct. */
-						for (i = 0; i < 4; i++)  {
-							if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
-								if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
-									pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
-								}
-							}
-							if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
-								CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
-							}
-							else {
-								CableLength = 0;
-							}
-							pVctBackupData->PMdiPairLen[i] = CableLength;
-							pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
-						}
+						/* VCT test is finished, so save the data. */
+						VctGetResults(pAC, IoC, PhysPortIndex);
 
 						Para.Para32[0] = PhysPortIndex;
 						Para.Para32[1] = -1;
 						SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
-						SkEventDispatcher(pAC, IoC);
-					}
-					else {
-						; /* VCT test is running. */
+
+						/* SkEventDispatcher(pAC, IoC); */
 					}
 				}
 				
+				/* Initialize backup data pointer. */
+				pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
+				
 				/* Get all results. */
 				CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
-				Offset += sizeof(SK_U8);
+				
+				Offset++;
 				*(pBuf + Offset) = pPrt->PCableLen;
-				Offset += sizeof(SK_U8);
+				Offset++;
 				for (i = 0; i < 4; i++)  {
-					SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
+
+					SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->MdiPairLen[i]);
 					Offset += sizeof(SK_U32);
 				}
 				for (i = 0; i < 4; i++)  {
-					*(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
-					Offset += sizeof(SK_U8);
+
+					*(pBuf + Offset) = pVctBackupData->MdiPairSts[i];
+					Offset++;
 				}
 				
 				RetCode = SK_PNMI_ERR_OK;
 				break;
-		
+
 			case OID_SKGE_VCT_STATUS:
 				CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
-				Offset += sizeof(SK_U8);
+
+				Offset++;
 				RetCode = SK_PNMI_ERR_OK;
 				break;
-			
+
+			case OID_SKGE_VCT_CAPABILITIES:
+				if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
+					*(pBuf + Offset) = SK_PNMI_VCT_NOT_SUPPORTED;
+				}
+				else {
+					*(pBuf + Offset) = SK_PNMI_VCT_SUPPORTED;
+				}
+				Offset++;
+
+				RetCode = SK_PNMI_ERR_OK;
+				break;
+
 			default:
 				*pLen = 0;
 				return (SK_PNMI_ERR_GENERAL);
@@ -8141,7 +7884,7 @@
 	 * buffer length is plausible.
 	 */
 	
-	/* Check length */
+	/* Check length. */
 	switch (Id) {
 	case OID_SKGE_VCT_SET:
 		if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
@@ -8155,36 +7898,39 @@
 		return (SK_PNMI_ERR_GENERAL);
 	}
 	
-	/*
-	 * Perform preset or set.
-	 */
+	/* Perform PRESET or SET. */
 	
 	/* VCT does not support PRESET action. */
 	if (Action == SK_PNMI_PRESET) {
+
 		return (SK_PNMI_ERR_OK);
 	}
 	
 	Offset = 0;
 	for (; PhysPortIndex < Limit; PhysPortIndex++) {
+
+		pPrt = &pAC->GIni.GP[PhysPortIndex];
+
 		switch (Id) {
 		case OID_SKGE_VCT_SET: /* Start VCT test. */
-			if (Link == SK_FALSE) {
+			if (!pPrt->PHWLinkUp) {
 				SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
 				
 				RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
+				
 				if (RetCode == 0) { /* RetCode: 0 => Start! */
 					pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
-					pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
-					pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
+					pAC->Pnmi.VctStatus[PhysPortIndex] &=
+						~(SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_LINK);
 					
-					/*
-					 * Start VCT timer counter.
-					 */
-					SK_MEMSET((char *) &Para, 0, sizeof(Para));
+					/* Start VCT timer counter. */
+					SK_MEMSET((char *)&Para, 0, sizeof(Para));
 					Para.Para32[0] = PhysPortIndex;
 					Para.Para32[1] = -1;
-					SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
-						4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
+					
+					SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex],
+						SK_PNMI_VCT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
+					
 					SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
 					RetCode = SK_PNMI_ERR_OK;
 				}
@@ -8212,6 +7958,57 @@
 } /* Vct */
 
 
+PNMI_STATIC void VctGetResults(
+SK_AC		*pAC,
+SK_IOC		IoC,
+SK_U32		Port)
+{
+	SK_GEPORT	*pPrt;
+	int			i;
+	SK_U8		PairLen;
+	SK_U8		PairSts;
+	SK_U32		CableLength;
+	
+	pPrt = &pAC->GIni.GP[Port];
+
+	/* Copy results for later use to PNMI struct. */
+	for (i = 0; i < 4; i++)  {
+
+		PairLen = pPrt->PMdiPairLen[i];
+
+		if (((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) == 0) && (i > 1)) {
+			PairSts = SK_PNMI_VCT_NOT_PRESENT;
+		}
+		else {
+			PairSts = pPrt->PMdiPairSts[i];
+		}
+
+		if ((PairSts == SK_PNMI_VCT_NORMAL_CABLE) &&
+			(PairLen > 28) && (PairLen < 0xff)) {
+
+			PairSts = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
+		}
+
+		/* Ignore values <= 35, the linear factor is 4/5 (trend line). */
+		if ((PairLen > 35) && (PairLen < 0xff)) {
+			
+			CableLength = 1000UL * (PairLen - 35) * 4 / 5;
+		}
+		else {
+			/* No cable or short cable. */
+			CableLength = 0;
+		}
+
+		pAC->Pnmi.VctBackup[Port].MdiPairLen[i] = CableLength;
+		pAC->Pnmi.VctBackup[Port].MdiPairSts[i] = PairSts;
+	}
+
+	pAC->Pnmi.VctStatus[Port] &= ~SK_PNMI_VCT_PENDING;
+	pAC->Pnmi.VctStatus[Port] |= (SK_PNMI_VCT_NEW_VCT_DATA |
+		SK_PNMI_VCT_TEST_DONE);
+
+} /* GetVctResults */
+
 PNMI_STATIC void CheckVctStatus(
 SK_AC		*pAC,
 SK_IOC		IoC,
@@ -8221,6 +8018,7 @@
 {
 	SK_GEPORT 	*pPrt;
 	SK_PNMI_VCT	*pVctData;
+	SK_U8		VctStatus;
 	SK_U32		RetCode;
 	
 	pPrt = &pAC->GIni.GP[PhysPortIndex];
@@ -8228,11 +8026,13 @@
 	pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
 	pVctData->VctStatus = SK_PNMI_VCT_NONE;
 	
+	VctStatus = pAC->Pnmi.VctStatus[PhysPortIndex];
+	
 	if (!pPrt->PHWLinkUp) {
 		
 		/* Was a VCT test ever made before? */
-		if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
-			if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
+		if (VctStatus & SK_PNMI_VCT_TEST_DONE) {
+			if (VctStatus & SK_PNMI_VCT_LINK) {
 				pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
 			}
 			else {
@@ -8242,11 +8042,12 @@
 		
 		/* Check VCT test status. */
 		RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
+		
 		if (RetCode == 2) { /* VCT test is running. */
 			pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
 		}
 		else { /* VCT data was copied to pAC here. Check PENDING state. */
-			if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
+			if (VctStatus & SK_PNMI_VCT_PENDING) {
 				pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
 			}
 		}
@@ -8256,16 +8057,14 @@
 		}
 	}
 	else {
-		
 		/* Was a VCT test ever made before? */
-		if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
+		if (VctStatus & SK_PNMI_VCT_TEST_DONE) {
 			pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
 			pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
 		}
 		
 		/* DSP only valid in 100/1000 modes. */
-		if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
-			SK_LSPEED_STAT_10MBPS) {	
+		if (pPrt->PLinkSpeedUsed != SK_LSPEED_STAT_10MBPS) {
 			pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
 		}
 	}
@@ -8311,29 +8110,29 @@
 	ReturnCode = SK_PNMI_ERR_GENERAL;
 	
 	SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
-	SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
+	SK_MEMCPY(&Oid, (char *)pBuf + sizeof(SK_I32), sizeof(SK_U32));
 	HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
 	*pLen = *pLen - HeaderLength;
-	SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
+	SK_MEMCPY((char *)pBuf + sizeof(SK_I32), (char *)pBuf + HeaderLength, *pLen);
 	
 	switch(Mode) {
 	case SK_GET_SINGLE_VAR:
-		ReturnCode = SkPnmiGetVar(pAC, IoC, Oid, 
-				(char *) pBuf + sizeof(SK_I32), pLen,
+		ReturnCode = SkPnmiGetVar(pAC, IoC, Oid,
+				(char *)pBuf + sizeof(SK_I32), pLen,
 				((SK_U32) (-1)), NetIndex);
 		SK_PNMI_STORE_U32(pBuf, ReturnCode);
 		*pLen = *pLen + sizeof(SK_I32);
 		break;
 	case SK_PRESET_SINGLE_VAR:
-		ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid, 
-				(char *) pBuf + sizeof(SK_I32), pLen,
+		ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid,
+				(char *)pBuf + sizeof(SK_I32), pLen,
 				((SK_U32) (-1)), NetIndex);
 		SK_PNMI_STORE_U32(pBuf, ReturnCode);
 		*pLen = *pLen + sizeof(SK_I32);
 		break;
 	case SK_SET_SINGLE_VAR:
-		ReturnCode = SkPnmiSetVar(pAC, IoC, Oid, 
-				(char *) pBuf + sizeof(SK_I32), pLen,
+		ReturnCode = SkPnmiSetVar(pAC, IoC, Oid,
+				(char *)pBuf + sizeof(SK_I32), pLen,
 				((SK_U32) (-1)), NetIndex);
 		SK_PNMI_STORE_U32(pBuf, ReturnCode);
 		*pLen = *pLen + sizeof(SK_I32);
@@ -8354,3 +8153,86 @@
 	return (ReturnCode);
 
 } /* SkGeIocGen */
+
+#ifdef SK_ASF
+/*****************************************************************************
+ *
+ * Asf
+ *
+ * Description:
+ *  The code is simple. No description necessary.
+ *
+ * Returns:
+ *  SK_PNMI_ERR_OK           The request was successfully performed.
+ *  SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *  SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
+ *                           the correct data (e.g. a 32bit value is
+ *                           needed, but a 16 bit value was passed).
+ *  SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
+ *                           exist (e.g. port instance 3 on a two port
+ *                           adapter.
+ */
+
+PNMI_STATIC int Asf(
+SK_AC *pAC,     /* Pointer to adapter context */
+SK_IOC IoC,     /* IO context handle */
+int Action,     /* GET/PRESET/SET action */
+SK_U32 Id,      /* Object ID that is to be processed */
+char *pBuf,     /* Buffer used for the management data transfer */
+unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
+SK_U32 Instance,    /* Instance (1..n) that is to be queried or -1 */
+unsigned int TableIndex, /* Index to the Id table */
+SK_U32 NetIndex)    /* NetIndex (0..n), in single net mode always zero */
+{
+    SK_U32  RetCode = SK_PNMI_ERR_GENERAL;
+
+    /*
+     * Check instance. We only handle single instance variables.
+     */
+    if (Instance != (SK_U32)(-1) && Instance != 1) {
+
+        *pLen = 0;
+        return (SK_PNMI_ERR_UNKNOWN_INST);
+    }
+
+    /* Perform action. */
+    /* GET value. */
+    if (Action == SK_PNMI_GET) {
+        switch (Id) {
+            case OID_SKGE_ASF:  
+                RetCode = SkAsfGet(pAC, IoC, (SK_U8 *) pBuf, pLen);
+                break;
+            default:
+                RetCode = SkAsfGetOid( pAC, IoC, Id, Instance, (SK_U8 *) pBuf, pLen );
+                break;
+        }
+
+        return (RetCode); 
+    }
+
+    /* PRESET value. */
+    if (Action == SK_PNMI_PRESET) { 
+        switch (Id) {
+            case OID_SKGE_ASF:
+                RetCode = SkAsfPreSet(pAC, IoC, (SK_U8 *) pBuf, pLen);
+                break;
+            default:
+                RetCode = SkAsfPreSetOid( pAC, IoC, Id, Instance, (SK_U8 *) pBuf, pLen );
+                break;
+        }
+    }
+
+    /* SET value. */
+    if (Action == SK_PNMI_SET) {
+        switch (Id) {
+            case OID_SKGE_ASF:
+                RetCode = SkAsfSet(pAC, IoC, (SK_U8 *) pBuf, pLen);
+                break;
+            default:
+                RetCode = SkAsfSetOid( pAC, IoC, Id, Instance, (SK_U8 *) pBuf, pLen );
+                break;
+        }
+    }
+    return (RetCode);
+}
+#endif /* SK_ASF */
diff -urN linux-2.4.29/drivers/net/sk98lin/skgesirq.c linux-2.4.29-uc1/drivers/net/sk98lin/skgesirq.c
--- linux-2.4.29/drivers/net/sk98lin/skgesirq.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/skgesirq.c	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skgesirq.c
  * Project:	Gigabit Ethernet Adapters, Common Modules
+ * Version:	$Revision: 2.17 $
+ * Date:	$Date: 2004/07/02 15:24:06 $
  * Purpose:	Special IRQ module
  *
  ******************************************************************************/
@@ -9,13 +11,12 @@
 /******************************************************************************
  *
  *	(C)Copyright 1998-2002 SysKonnect.
- *	(C)Copyright 2002-2003 Marvell.
+ *	(C)Copyright 2002-2004 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
  *	the Free Software Foundation; either version 2 of the License, or
  *	(at your option) any later version.
- *
  *	The information in this file is provided "AS IS" without warranty.
  *
  ******************************************************************************/
@@ -36,7 +37,7 @@
  *	right after this ISR.
  *
  *	The Interrupt source register of the adapter is NOT read by this module.
- *  SO if the drivers implementor needs a while loop around the
+ *	SO if the drivers implementor needs a while loop around the
  *	slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for
  *	each loop entered.
  *
@@ -44,11 +45,6 @@
  *
  */
 
-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
-static const char SysKonnectFileId[] =
-	"@(#) $Id: skgesirq.c,v 1.92 2003/09/16 14:37:07 rschmidt Exp $ (C) Marvell.";
-#endif
-
 #include "h/skdrv1st.h"		/* Driver Specific Definitions */
 #ifndef SK_SLIM
 #include "h/skgepnmi.h"		/* PNMI Definitions */
@@ -56,6 +52,13 @@
 #endif
 #include "h/skdrv2nd.h"		/* Adapter Control and Driver specific Def. */
 
+/* local variables ************************************************************/
+
+#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+static const char SysKonnectFileId[] =
+	"@(#) $Id: skgesirq.c,v 2.17 2004/07/02 15:24:06 rschmidt Exp $ (C) Marvell.";
+#endif
+
 /* local function prototypes */
 #ifdef GENESIS
 static int	SkGePortCheckUpXmac(SK_AC*, SK_IOC, int, SK_BOOL);
@@ -107,8 +110,8 @@
  * Returns: N/A
  */
 static void SkHWInitDefSense(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O context */
 int		Port)	/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
@@ -143,8 +146,8 @@
  *
  */
 static SK_U8 SkHWSenseGetNext(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O context */
 int		Port)	/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
@@ -153,18 +156,18 @@
 
 	pPrt->PAutoNegTimeOut = 0;
 
-    if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
+	if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
 		/* Leave all as configured */
 		return(pPrt->PLinkModeConf);
 	}
 
-    if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) {
+	if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) {
 		/* Return next mode AUTOBOTH */
-        return ((SK_U8)SK_LMODE_AUTOBOTH);
+		return((SK_U8)SK_LMODE_AUTOBOTH);
 	}
 
 	/* Return default autofull */
-    return ((SK_U8)SK_LMODE_AUTOFULL);
+	return((SK_U8)SK_LMODE_AUTOFULL);
 }	/* SkHWSenseGetNext */
 
 
@@ -177,8 +180,8 @@
  * Returns: N/A
  */
 static void SkHWSenseSetNext(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O context */
 int		Port,		/* Port Index (MAC_1 + n) */
 SK_U8	NewMode)	/* New Mode to be written in sense mode */
 {
@@ -188,7 +191,7 @@
 
 	pPrt->PAutoNegTimeOut = 0;
 
-    if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
+	if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
 		return;
 	}
 
@@ -212,8 +215,8 @@
  * Returns: N/A
  */
 void SkHWLinkDown(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
@@ -225,11 +228,11 @@
 
 	/* Disable Receiver and Transmitter */
 	SkMacRxTxDisable(pAC, IoC, Port);
-	
+
 	/* Init default sense mode */
 	SkHWInitDefSense(pAC, IoC, Port);
 
-	if (pPrt->PHWLinkUp == SK_FALSE) {
+	if (!pPrt->PHWLinkUp) {
 		return;
 	}
 
@@ -240,8 +243,8 @@
 	pPrt->PHWLinkUp = SK_FALSE;
 
 	/* Reset Port stati */
-    pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
-    pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
+	pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
+	pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
 	pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_INDETERMINATED;
 
 	/* Re-init Phy especially when the AutoSense default is set now */
@@ -264,8 +267,8 @@
  * Returns: N/A
  */
 void SkHWLinkUp(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O context */
 int		Port)	/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
@@ -279,11 +282,11 @@
 
 	pPrt->PHWLinkUp = SK_TRUE;
 	pPrt->PAutoNegFail = SK_FALSE;
-    pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
+	pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
 
-    if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF &&
-        pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL &&
-        pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) {
+	if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF &&
+		pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL &&
+		pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) {
 		/* Link is up and no Auto-negotiation should be done */
 
 		/* Link speed should be the configured one */
@@ -306,14 +309,14 @@
 			pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_FULL;
 		}
 		else {
-            pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF;
+			pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF;
 		}
 
 		/* No flow control without auto-negotiation */
-        pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
+		pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
 
 		/* enable Rx/Tx */
-        (void)SkMacRxTxEnable(pAC, IoC, Port);
+		(void)SkMacRxTxEnable(pAC, IoC, Port);
 	}
 }	/* SkHWLinkUp */
 
@@ -327,14 +330,16 @@
  * Returns: N/A
  */
 static void SkMacParity(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
-int		Port)	/* Port Index of the port failed */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O context */
+int		Port)	/* Port Index (MAC_1 + n) */
 {
 	SK_EVPARA	Para;
 	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
 	SK_U32		TxMax;		/* Tx Max Size Counter */
 
+	TxMax = 0;
+
 	pPrt = &pAC->GIni.GP[Port];
 
 	/* Clear IRQ Tx Parity Error */
@@ -353,7 +358,7 @@
 			pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE));
 	}
 #endif /* YUKON */
-	
+
 	if (pPrt->PCheckPar) {
 
 		if (Port == MAC_1) {
@@ -364,7 +369,7 @@
 		}
 		Para.Para64 = Port;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-		
+
 		Para.Para32[0] = Port;
 		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
 
@@ -376,7 +381,7 @@
 	if (pAC->GIni.GIGenesis) {
 		/* Snap statistic counters */
 		(void)SkXmUpdateStats(pAC, IoC, Port);
-		
+
 		(void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax);
 	}
 #endif /* GENESIS */
@@ -397,15 +402,15 @@
 
 /******************************************************************************
  *
- *	SkGeHwErr() - Hardware Error service routine
+ *	SkGeYuHwErr() - Hardware Error service routine (Genesis and Yukon)
  *
  * Description: handles all HW Error interrupts
  *
  * Returns: N/A
  */
-static void SkGeHwErr(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+static void SkGeYuHwErr(
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O context */
 SK_U32	HwStatus)	/* Interrupt status word */
 {
 	SK_EVPARA	Para;
@@ -421,10 +426,10 @@
 		}
 
 		/* Reset all bits in the PCI STATUS register */
-		SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
-		
+		SK_IN16(IoC, PCI_C(pAC, PCI_STATUS), &Word);
+
 		SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-        SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
+		SK_OUT16(IoC, PCI_C(pAC, PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
 		SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 
 		Para.Para64 = 0;
@@ -482,14 +487,18 @@
 #endif /* YUKON */
 
 	if ((HwStatus & IS_RAM_RD_PAR) != 0) {
+
 		SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR);
+
 		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG);
 		Para.Para64 = 0;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
 	}
 
 	if ((HwStatus & IS_RAM_WR_PAR) != 0) {
+
 		SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR);
+
 		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG);
 		Para.Para64 = 0;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
@@ -510,7 +519,7 @@
 		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG);
 		Para.Para64 = MAC_1;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-		
+
 		Para.Para32[0] = MAC_1;
 		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
 	}
@@ -522,24 +531,244 @@
 		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG);
 		Para.Para64 = MAC_2;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
-		
+
 		Para.Para32[0] = MAC_2;
 		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
 	}
-}	/* SkGeHwErr */
+}	/* SkGeYuHwErr */
+
+#ifdef YUK2
+/******************************************************************************
+ *
+ *	SkYuk2HwPortErr() - Service HW Errors for specified port (Yukon-2 only)
+ *
+ * Description: handles the HW Error interrupts for a specific port.
+ *
+ * Returns: N/A
+ */
+static void SkYuk2HwPortErr(
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
+SK_U32	HwStatus,	/* Interrupt status word */
+int		Port)		/* Port Index (MAC_1 + n) */
+{
+	int Queue;
+	SK_EVPARA	Para;
 
+	if (Port == MAC_2) {
+		HwStatus >>= 8;
+	}
+
+	if ((HwStatus & Y2_HWE_L1_MASK) == 0) {
+		return;
+	}
+
+	if ((HwStatus & Y2_IS_PAR_RD1) != 0) {
+		/* Clear IRQ */
+		SK_OUT16(IoC, SELECT_RAM_BUFFER(Port, B3_RI_CTRL), RI_CLR_RD_PERR);
+
+		if (Port == MAC_1) {
+			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E028, SKERR_SIRQ_E028MSG);
+		}
+		else {
+			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E030, SKERR_SIRQ_E030MSG);
+		}
+	}
+
+	if ((HwStatus & Y2_IS_PAR_WR1) != 0) {
+		/* Clear IRQ */
+		SK_OUT16(IoC, SELECT_RAM_BUFFER(Port, B3_RI_CTRL), RI_CLR_WR_PERR);
+
+		if (Port == MAC_1) {
+			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E029, SKERR_SIRQ_E029MSG);
+		}
+		else {
+			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E031, SKERR_SIRQ_E031MSG);
+		}
+	}
+
+	if ((HwStatus & Y2_IS_PAR_MAC1) != 0) {
+		/* Clear IRQ */
+		SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), GMF_CLI_TX_PE);
+
+		if (Port == MAC_1) {
+			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG);
+		}
+		else {
+			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG);
+		}
+	}
+
+	if ((HwStatus & Y2_IS_PAR_RX1) != 0) {
+		if (Port == MAC_1) {
+			Queue = Q_R1;
+			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG);
+		}
+		else {
+			Queue = Q_R2;
+			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG);
+		}
+		/* Clear IRQ */
+		SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_PAR);
+	}
+
+	if ((HwStatus & Y2_IS_TCP_TXS1) != 0) {
+		if (Port == MAC_1) {
+			Queue = Q_XS1;
+			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E033, SKERR_SIRQ_E033MSG);
+		}
+		else {
+			Queue = Q_XS2;
+			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E035, SKERR_SIRQ_E035MSG);
+		}
+		/* Clear IRQ */
+		SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_TCP);
+	}
+
+	if ((HwStatus & Y2_IS_TCP_TXA1) != 0) {
+		if (Port == MAC_1) {
+			Queue = Q_XA1;
+			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E032, SKERR_SIRQ_E032MSG);
+		}
+		else {
+			Queue = Q_XA2;
+			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E034, SKERR_SIRQ_E034MSG);
+		}
+		/* Clear IRQ */
+		SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_TCP);
+	}
+
+	Para.Para64 = Port;
+	SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+
+	Para.Para32[0] = Port;
+	SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+
+}	/* SkYuk2HwPortErr */
 
 /******************************************************************************
  *
- *	SkGeSirqIsr() - Special Interrupt Service Routine
+ *	SkYuk2HwErr() - Hardware Error service routine (Yukon-2 only)
  *
- * Description: handles all non data transfer specific interrupts (slow path)
+ * Description: handles all HW Error interrupts
+ *
+ * Returns: N/A
+ */
+static void SkYuk2HwErr(
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
+SK_U32	HwStatus)	/* Interrupt status word */
+{
+	SK_EVPARA	Para;
+	SK_U16		Word;
+	SK_U32		DWord;
+	int			i;
+
+	/* This is necessary only for Rx timing measurements */
+	if ((HwStatus & Y2_IS_TIST_OV) != 0) {
+		/* increment Time Stamp Timer counter (high) */
+		pAC->GIni.GITimeStampCnt++;
+
+		/* Clear Time Stamp Timer IRQ */
+		SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ);
+	}
+
+	/* Evaluate Y2_IS_PCI_NEXP before Y2_IS_MST_ERR or Y2_IS_IRQ_STAT */
+	if ((HwStatus & Y2_IS_PCI_NEXP) != 0) {
+		/* PCI-Express Error occured which is not described in PEX spec. */
+		/*
+		 * This error is also mapped either to Master Abort (Y2_IS_MST_ERR)
+		 * or Target Abort (Y2_IS_IRQ_STAT) bit and can only be cleared there.
+		 * Therefore handle this event just by printing an error log entry.
+		 */
+		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E027, SKERR_SIRQ_E027MSG);
+	}
+
+	if ((HwStatus & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) != 0) {
+		/* PCI Errors occured */
+		if ((HwStatus & Y2_IS_IRQ_STAT) != 0) {
+			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG);
+		}
+		else {
+			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG);
+		}
+
+		/* Reset all bits in the PCI STATUS register */
+		SK_IN16(IoC, PCI_C(pAC,PCI_STATUS), &Word);
+
+		SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+		SK_OUT16(IoC, PCI_C(pAC,PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
+		SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+		Para.Para64 = 0;
+		SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
+	}
+
+	if ((HwStatus & Y2_IS_PCI_EXP) != 0) {
+		/* PCI-Express uncorrectable Error occured */
+		/*
+		 * On PCI-Express bus bridges are called root complexes.
+		 * PCI-Express errors are recognized by the root complex too,
+		 * which requests the system to handle the problem. After error
+		 * occurence it may be that no access to the adapter may be performed
+		 * any longer.
+		 */
+		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E026, SKERR_SIRQ_E026MSG);
+
+		/* Save uncorrectable error status */
+		SK_IN32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), &DWord);
+
+		/* clear the interrupt */
+		SK_OUT32(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+		SK_OUT32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), 0xffffffffUL);
+		SK_OUT32(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+		if ((DWord & PEX_FATAL_ERRORS) != 0) {
+			/* Stop only, if the uncorrectable error is fatal */	
+			Para.Para64 = 0;
+			SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
+
+			pAC->GIni.GIValHwIrqMask &= ~Y2_IS_PCI_EXP;
+			/* Rewrite HW IRQ mask */
+			SK_OUT32(IoC, B0_HWE_IMSK, pAC->GIni.GIValHwIrqMask);
+		}
+	}
+
+	for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+
+		SkYuk2HwPortErr(pAC, IoC, HwStatus, i);
+	}
+
+}	/* SkYuk2HwErr */
+#endif /* YUK2 */
+
+/******************************************************************************
+ *
+ *	SkGeSirqIsr() - Wrapper for Special Interrupt Service Routine
+ *
+ * Description: calls the preselected special ISR (slow path)
  *
  * Returns: N/A
  */
 void SkGeSirqIsr(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O context */
+SK_U32	Istatus)	/* Interrupt status word */
+{
+	pAC->GIni.GIFunc.pSkGeSirqIsr(pAC, IoC, Istatus);
+}
+
+/******************************************************************************
+ *
+ *	SkGeYuSirqIsr() - Special Interrupt Service Routine
+ *
+ * Description: handles all non data transfer specific interrupts (slow path)
+ *
+ * Returns: N/A
+ */
+void SkGeYuSirqIsr(
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 SK_U32	Istatus)	/* Interrupt status word */
 {
 	SK_EVPARA	Para;
@@ -551,8 +780,8 @@
 	if (((Istatus & IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) {
 		/* read the HW Error Interrupt source */
 		SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
-		
-		SkGeHwErr(pAC, IoC, RegVal32);
+
+		SkGeYuHwErr(pAC, IoC, RegVal32);
 	}
 
 	/*
@@ -567,7 +796,7 @@
 	}
 
 	if (((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) != 0) &&
-	    pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) {
+		pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) {
 		/* MAC 2 was not initialized but Packet timeout occured */
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005,
 			SKERR_SIRQ_E005MSG);
@@ -588,7 +817,7 @@
 	}
 
 	if ((Istatus & IS_PA_TO_TX1) != 0) {
-		
+
 		pPrt = &pAC->GIni.GP[0];
 
 		/* May be a normal situation in a server with a slow network */
@@ -615,7 +844,7 @@
 				SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
 					&Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, 0),
 					pAC->Rlmt.Port[0].Net->NetNumber);
-				
+
 				pPrt->LastOctets = Octets;
 #endif /* XXX */
 				/* Snap statistic counters */
@@ -624,11 +853,11 @@
 				(void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_HI, &RegVal32);
 
 				pPrt->LastOctets = (SK_U64)RegVal32 << 32;
-				
+
 				(void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_LO, &RegVal32);
 
 				pPrt->LastOctets += RegVal32;
-				
+
 				Para.Para32[0] = 0;
 				SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
 					SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
@@ -638,7 +867,7 @@
 	}
 
 	if ((Istatus & IS_PA_TO_TX2) != 0) {
-		
+
 		pPrt = &pAC->GIni.GP[1];
 
 		/* May be a normal situation in a server with a slow network */
@@ -656,7 +885,7 @@
 				SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
 					&Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, 1),
 					pAC->Rlmt.Port[1].Net->NetNumber);
-				
+
 				pPrt->LastOctets = Octets;
 #endif /* XXX */
 				/* Snap statistic counters */
@@ -665,11 +894,11 @@
 				(void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_HI, &RegVal32);
 
 				pPrt->LastOctets = (SK_U64)RegVal32 << 32;
-				
+
 				(void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_LO, &RegVal32);
 
 				pPrt->LastOctets += RegVal32;
-				
+
 				Para.Para32[0] = 1;
 				SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
 					SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
@@ -682,6 +911,7 @@
 	if ((Istatus & IS_R1_C) != 0) {
 		/* Clear IRQ */
 		SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C);
+
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006,
 			SKERR_SIRQ_E006MSG);
 		Para.Para64 = MAC_1;
@@ -693,6 +923,7 @@
 	if ((Istatus & IS_R2_C) != 0) {
 		/* Clear IRQ */
 		SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C);
+
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007,
 			SKERR_SIRQ_E007MSG);
 		Para.Para64 = MAC_2;
@@ -704,6 +935,7 @@
 	if ((Istatus & IS_XS1_C) != 0) {
 		/* Clear IRQ */
 		SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C);
+
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008,
 			SKERR_SIRQ_E008MSG);
 		Para.Para64 = MAC_1;
@@ -715,6 +947,7 @@
 	if ((Istatus & IS_XA1_C) != 0) {
 		/* Clear IRQ */
 		SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C);
+
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009,
 			SKERR_SIRQ_E009MSG);
 		Para.Para64 = MAC_1;
@@ -726,6 +959,7 @@
 	if ((Istatus & IS_XS2_C) != 0) {
 		/* Clear IRQ */
 		SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C);
+
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010,
 			SKERR_SIRQ_E010MSG);
 		Para.Para64 = MAC_2;
@@ -737,6 +971,7 @@
 	if ((Istatus & IS_XA2_C) != 0) {
 		/* Clear IRQ */
 		SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C);
+
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011,
 			SKERR_SIRQ_E011MSG);
 		Para.Para64 = MAC_2;
@@ -749,39 +984,37 @@
 	if ((Istatus & IS_EXT_REG) != 0) {
 		/* Test IRQs from PHY */
 		for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
-			
+
 			pPrt = &pAC->GIni.GP[i];
-			
+
 			if (pPrt->PState == SK_PRT_RESET) {
 				continue;
 			}
-			
+
 #ifdef GENESIS
 			if (pAC->GIni.GIGenesis) {
-				
+
 				switch (pPrt->PhyType) {
-				
+
 				case SK_PHY_XMAC:
 					break;
-				
+
 				case SK_PHY_BCOM:
 					SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt);
-	
+
 					if ((PhyInt & ~PHY_B_DEF_MSK) != 0) {
 						SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-							("Port %d Bcom Int: 0x%04X\n",
-							i, PhyInt));
+							("Port %d PHY Int: 0x%04X\n", i, PhyInt));
 						SkPhyIsrBcom(pAC, IoC, i, PhyInt);
 					}
 					break;
 #ifdef OTHER_PHY
 				case SK_PHY_LONE:
 					SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt);
-					
+
 					if ((PhyInt & PHY_L_DEF_MSK) != 0) {
 						SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-							("Port %d Lone Int: %x\n",
-							i, PhyInt));
+							("Port %d PHY Int: 0x%04X\n", i, PhyInt));
 						SkPhyIsrLone(pAC, IoC, i, PhyInt);
 					}
 					break;
@@ -797,8 +1030,7 @@
 
 				if ((PhyInt & PHY_M_DEF_MSK) != 0) {
 					SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-						("Port %d Marv Int: 0x%04X\n",
-						i, PhyInt));
+						("Port %d PHY Int: 0x%04X\n", i, PhyInt));
 					SkPhyIsrGmac(pAC, IoC, i, PhyInt);
 				}
 			}
@@ -806,13 +1038,13 @@
 		}
 	}
 
-	/* I2C Ready interrupt */
+	/* TWSI Ready interrupt */
 	if ((Istatus & IS_I2C_READY) != 0) {
 #ifdef SK_SLIM
-        SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
-#else		
+		SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
+#else
 		SkI2cIsr(pAC, IoC);
-#endif		
+#endif
 	}
 
 	/* SW forced interrupt */
@@ -827,7 +1059,7 @@
 		 * us only a link going down.
 		 */
 		/* clear interrupt */
-		SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ);
+		SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LNK_CLR_IRQ);
 	}
 
 	/* Check MAC after link sync counter */
@@ -842,7 +1074,7 @@
 		 * us only a link going down.
 		 */
 		/* clear interrupt */
-		SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ);
+		SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LNK_CLR_IRQ);
 	}
 
 	/* Check MAC after link sync counter */
@@ -858,13 +1090,189 @@
 			/* read the HW Error Interrupt source */
 			SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
 
-			SkGeHwErr(pAC, IoC, RegVal32);
+			SkGeYuHwErr(pAC, IoC, RegVal32);
 		}
 
 		SkHwtIsr(pAC, IoC);
 	}
 
-}	/* SkGeSirqIsr */
+}	/* SkGeYuSirqIsr */
+
+#ifdef YUK2
+/******************************************************************************
+ *
+ *	SkYuk2PortSirq() - Service HW Errors for specified port (Yukon-2 only)
+ *
+ * Description: handles the HW Error interrupts for a specific port.
+ *
+ * Returns: N/A
+ */
+static void SkYuk2PortSirq(
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
+SK_U32	IStatus,	/* Interrupt status word */
+int		Port)		/* Port Index (MAC_1 + n) */
+{
+	SK_EVPARA	Para;
+	int Queue;
+	SK_U16	PhyInt;
+
+	if (Port == MAC_2) {
+		IStatus >>= 8;
+	}
+
+	/* Interrupt from PHY */
+	if ((IStatus & Y2_IS_IRQ_PHY1) != 0) {
+		/* Read PHY Interrupt Status */
+		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyInt);
+
+		if ((PhyInt & PHY_M_DEF_MSK) != 0) {
+			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+				("Port %d PHY Int: 0x%04X\n", Port, PhyInt));
+			SkPhyIsrGmac(pAC, IoC, Port, PhyInt);
+		}
+	}
+
+	/* Interrupt from MAC */
+	if ((IStatus & Y2_IS_IRQ_MAC1) != 0) {
+		SkMacIrq(pAC, IoC, Port);
+	}
+
+	if ((IStatus & (Y2_IS_CHK_RX1 | Y2_IS_CHK_TXS1 | Y2_IS_CHK_TXA1)) != 0) {
+		if ((IStatus & Y2_IS_CHK_RX1) != 0) {
+			if (Port == MAC_1) {
+				Queue = Q_R1;
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E006,
+					SKERR_SIRQ_E006MSG);
+			}
+			else {
+				Queue = Q_R2;
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E007,
+					SKERR_SIRQ_E007MSG);
+			}
+			/* Clear IRQ */
+			SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_CHK);
+		}
+
+		if ((IStatus & Y2_IS_CHK_TXS1) != 0) {
+			if (Port == MAC_1) {
+				Queue = Q_XS1;
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E008,
+					SKERR_SIRQ_E008MSG);
+			}
+			else {
+				Queue = Q_XS2;
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E010,
+					SKERR_SIRQ_E010MSG);
+			}
+			/* Clear IRQ */
+			SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_CHK);
+		}
+
+		if ((IStatus & Y2_IS_CHK_TXA1) != 0) {
+			if (Port == MAC_1) {
+				Queue = Q_XA1;
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E009,
+					SKERR_SIRQ_E009MSG);
+			}
+			else {
+				Queue = Q_XA2;
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E011,
+					SKERR_SIRQ_E011MSG);
+			}
+			/* Clear IRQ */
+			SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_CHK);
+		}
+
+		Para.Para64 = Port;
+		SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+
+		Para.Para32[0] = Port;
+		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+	}
+}	/* SkYuk2PortSirq */
+#endif /* YUK2 */
+
+/******************************************************************************
+ *
+ *	SkYuk2SirqIsr() - Special Interrupt Service Routine	(Yukon-2 only)
+ *
+ * Description: handles all non data transfer specific interrupts (slow path)
+ *
+ * Returns: N/A
+ */
+void SkYuk2SirqIsr(
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
+SK_U32	Istatus)	/* Interrupt status word */
+{
+#ifdef YUK2
+	SK_EVPARA	Para;
+	SK_U32		RegVal32;	/* Read register value */
+	SK_U32		DwValue;
+
+	/* HW Error indicated ? */
+	if (((Istatus & Y2_IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) {
+		/* read the HW Error Interrupt source */
+		SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
+
+		SkYuk2HwErr(pAC, IoC, RegVal32);
+	}
+
+	/* Interrupt from ASF Subsystem */
+	if ((Istatus & Y2_IS_ASF) != 0) {
+		/* clear IRQ */
+		/* later on clearing should be done in ASF ISR handler */
+		SK_IN32(IoC, B28_Y2_ASF_STAT_CMD, &DwValue);
+		DwValue |= Y2_ASF_CLR_HSTI;
+		SK_OUT32(IoC, B28_Y2_ASF_STAT_CMD, DwValue);
+		/* Call IRQ handler in ASF Module */
+		/* TBD */
+	}
+
+	/* Check IRQ from polling unit */
+	if ((Istatus & Y2_IS_POLL_CHK) != 0) {
+		/* Clear IRQ */
+		SK_OUT32(IoC, POLL_CTRL, PC_CLR_IRQ_CHK);
+
+		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E036,
+			SKERR_SIRQ_E036MSG);
+		Para.Para64 = 0;
+		SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
+	}
+
+	/* TWSI Ready interrupt */
+	if ((Istatus & Y2_IS_TWSI_RDY) != 0) {
+#ifdef SK_SLIM
+		SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
+#else
+		SkI2cIsr(pAC, IoC);
+#endif
+	}
+
+	/* SW forced interrupt */
+	if ((Istatus & Y2_IS_IRQ_SW) != 0) {
+		/* clear the software IRQ */
+		SK_OUT8(IoC, B0_CTST, CS_CL_SW_IRQ);
+	}
+
+	if ((Istatus & Y2_IS_L1_MASK) != 0) {
+		SkYuk2PortSirq(pAC, IoC, Istatus, MAC_1);
+	}
+
+	if ((Istatus & Y2_IS_L2_MASK) != 0) {
+		SkYuk2PortSirq(pAC, IoC, Istatus, MAC_2);
+	}
+
+	/* Timer interrupt (served last) */
+	if ((Istatus & Y2_IS_TIMINT) != 0) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+			("Timer Int: 0x%08X\n", Istatus));
+		SkHwtIsr(pAC, IoC);
+	}
+#endif	/* YUK2 */
+
+}	/* SkYuk2SirqIsr */
 
 
 #ifdef GENESIS
@@ -878,8 +1286,8 @@
  */
 static int SkGePortCheckShorts(
 SK_AC	*pAC,		/* Adapter Context */
-SK_IOC	IoC,		/* IO Context */
-int		Port)		/* Which port should be checked */
+SK_IOC	IoC,		/* I/O Context */
+int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_U32		Shorts;			/* Short Event Counter */
 	SK_U32		CheckShorts;	/* Check value for Short Event Counter */
@@ -907,9 +1315,9 @@
 	RxCts = 0;
 
 	for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) {
-		
+
 		(void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp);
-		
+
 		RxCts += (SK_U64)RxTmp;
 	}
 
@@ -926,10 +1334,10 @@
 		CheckShorts = 2;
 
 		(void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts);
-		
+
 		if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
-		    pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN &&
-		    (pPrt->PLinkMode == SK_LMODE_HALF ||
+			pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN &&
+			(pPrt->PLinkMode == SK_LMODE_HALF ||
 			 pPrt->PLinkMode == SK_LMODE_FULL)) {
 			/*
 			 * This is autosensing and we are in the fallback
@@ -939,7 +1347,7 @@
 				/* Nothing received, restart link */
 				pPrt->PPrevFcs = FcsErrCts;
 				pPrt->PPrevShorts = Shorts;
-				
+
 				return(SK_HW_PS_RESTART);
 			}
 			else {
@@ -948,7 +1356,7 @@
 		}
 
 		if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) ||
-		    (!(FcsErrCts - pPrt->PPrevFcs))) {
+			(!(FcsErrCts - pPrt->PPrevFcs))) {
 			/*
 			 * Note: The compare with zero above has to be done the way shown,
 			 * otherwise the Linux driver will have a problem.
@@ -993,15 +1401,15 @@
  */
 static int SkGePortCheckUp(
 SK_AC	*pAC,		/* Adapter Context */
-SK_IOC	IoC,		/* IO Context */
-int		Port)		/* Which port should be checked */
+SK_IOC	IoC,		/* I/O Context */
+int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
 	SK_BOOL		AutoNeg;	/* Is Auto-negotiation used ? */
 	int			Rtv;		/* Return value */
 
 	Rtv = SK_HW_PS_NONE;
-	
+
 	pPrt = &pAC->GIni.GP[Port];
 
 	if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
@@ -1015,7 +1423,7 @@
 	if (pAC->GIni.GIGenesis) {
 
 		switch (pPrt->PhyType) {
-		
+
 		case SK_PHY_XMAC:
 			Rtv = SkGePortCheckUpXmac(pAC, IoC, Port, AutoNeg);
 			break;
@@ -1036,7 +1444,7 @@
 	
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
-		
+
 		Rtv = SkGePortCheckUpGmac(pAC, IoC, Port, AutoNeg);
 	}
 #endif /* YUKON */
@@ -1057,8 +1465,8 @@
  */
 static int SkGePortCheckUpXmac(
 SK_AC	*pAC,		/* Adapter Context */
-SK_IOC	IoC,		/* IO Context */
-int		Port,		/* Which port should be checked */
+SK_IOC	IoC,		/* I/O Context */
+int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	AutoNeg)	/* Is Auto-negotiation used ? */
 {
 	SK_U32		Shorts;		/* Short Event Counter */
@@ -1096,7 +1504,7 @@
 			XM_IN16(IoC, Port, XM_ISRC, &Isrc);
 			IsrcSum |= Isrc;
 			SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
-			
+
 			if ((Isrc & XM_IS_INP_ASS) == 0) {
 				/* It has been in sync since last time */
 				/* Restart the PORT */
@@ -1122,7 +1530,7 @@
 				 *  check whether the link is now o.k.
 				 */
 				pPrt->PLinkResCt++;
-				
+
 				pPrt->PAutoNegTimeOut = 0;
 
 				if (pPrt->PLinkResCt < SK_MAX_LRESTART) {
@@ -1130,13 +1538,13 @@
 				}
 
 				pPrt->PLinkResCt = 0;
-				
+
 				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 					("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum));
 			}
 			else {
 				pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
-				
+
 				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 					("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum));
 
@@ -1176,7 +1584,7 @@
 		}
 		else {
 			SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc);
-			
+
 			if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) {
 				return(SK_HW_PS_RESTART);
 			}
@@ -1215,10 +1623,10 @@
 				/* Get PHY parameters, for debugging only */
 				SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb);
 				SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
-				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 					("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n",
 					 Port, LpAb, ResAb));
-					
+
 				/* Try next possible mode */
 				NextMode = SkHWSenseGetNext(pAC, IoC, Port);
 				SkHWLinkDown(pAC, IoC, Port);
@@ -1234,10 +1642,10 @@
 			 * (clear Page Received bit if set)
 			 */
 			SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat);
-			
+
 			return(SK_HW_PS_LINK);
 		}
-		
+
 		/* AutoNeg not done, but HW link is up. Check for timeouts */
 		pPrt->PAutoNegTimeOut++;
 		if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
@@ -1281,14 +1689,14 @@
 		/* Link is up and we don't need more */
 #ifdef DEBUG
 		if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
-			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 				("ERROR: Lipa auto detected on port %d\n", Port));
 		}
 #endif /* DEBUG */
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
 			("Link sync(GP), Port %d\n", Port));
 		SkHWLinkUp(pAC, IoC, Port);
-		
+
 		/*
 		 * Link sync (GP) and so assume a good connection. But if not received
 		 * a bunch of frames received in a time slot (maybe broken tx cable)
@@ -1312,8 +1720,8 @@
  */
 static int SkGePortCheckUpBcom(
 SK_AC	*pAC,		/* Adapter Context */
-SK_IOC	IoC,		/* IO Context */
-int		Port,		/* Which port should be checked */
+SK_IOC	IoC,		/* I/O Context */
+int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	AutoNeg)	/* Is Auto-negotiation used ? */
 {
 	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
@@ -1332,74 +1740,6 @@
 	/* Check for No HCD Link events (#10523) */
 	SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc);
 
-#ifdef xDEBUG
-	if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT) ==
-		(PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) {
-
-		SK_U32	Stat1, Stat2, Stat3;
-
-		Stat1 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
-		CMSMPrintString(
-			pAC->pConfigTable,
-			MSG_TYPE_RUNTIME_INFO,
-			"CheckUp1 - Stat: %x, Mask: %x",
-			(void *)Isrc,
-			(void *)Stat1);
-
-		Stat1 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
-		Stat2 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2);
-		Stat1 = Stat1 << 16 | Stat2;
-		Stat2 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
-		Stat3 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
-		Stat2 = Stat2 << 16 | Stat3;
-		CMSMPrintString(
-			pAC->pConfigTable,
-			MSG_TYPE_RUNTIME_INFO,
-			"Ctrl/Stat: %x, AN Adv/LP: %x",
-			(void *)Stat1,
-			(void *)Stat2);
-
-		Stat1 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
-		Stat2 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
-		Stat1 = Stat1 << 16 | Stat2;
-		Stat2 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
-		Stat3 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3);
-		Stat2 = Stat2 << 16 | Stat3;
-		CMSMPrintString(
-			pAC->pConfigTable,
-			MSG_TYPE_RUNTIME_INFO,
-			"AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
-			(void *)Stat1,
-			(void *)Stat2);
-
-		Stat1 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
-		Stat2 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
-		Stat1 = Stat1 << 16 | Stat2;
-		Stat2 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
-		Stat3 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
-		Stat2 = Stat2 << 16 | Stat3;
-		CMSMPrintString(
-			pAC->pConfigTable,
-			MSG_TYPE_RUNTIME_INFO,
-			"PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
-			(void *)Stat1,
-			(void *)Stat2);
-	}
-#endif /* DEBUG */
-
 	if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) {
 		/*
 		 * Workaround BCom Errata:
@@ -1412,14 +1752,6 @@
 			(SK_U16)(Ctrl & ~PHY_CT_LOOP));
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 			("No HCD Link event, Port %d\n", Port));
-#ifdef xDEBUG
-		CMSMPrintString(
-			pAC->pConfigTable,
-			MSG_TYPE_RUNTIME_INFO,
-			"No HCD link event, port %d.",
-			(void *)Port,
-			(void *)NULL);
-#endif /* DEBUG */
 	}
 
 	/* Not obsolete: link status bit is latched to 0 and autoclearing! */
@@ -1429,72 +1761,6 @@
 		return(SK_HW_PS_NONE);
 	}
 
-#ifdef xDEBUG
-	{
-		SK_U32	Stat1, Stat2, Stat3;
-
-		Stat1 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
-		CMSMPrintString(
-			pAC->pConfigTable,
-			MSG_TYPE_RUNTIME_INFO,
-			"CheckUp1a - Stat: %x, Mask: %x",
-			(void *)Isrc,
-			(void *)Stat1);
-
-		Stat1 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
-		Stat2 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
-		Stat1 = Stat1 << 16 | PhyStat;
-		Stat2 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
-		Stat3 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
-		Stat2 = Stat2 << 16 | Stat3;
-		CMSMPrintString(
-			pAC->pConfigTable,
-			MSG_TYPE_RUNTIME_INFO,
-			"Ctrl/Stat: %x, AN Adv/LP: %x",
-			(void *)Stat1,
-			(void *)Stat2);
-
-		Stat1 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
-		Stat2 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
-		Stat1 = Stat1 << 16 | Stat2;
-		Stat2 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
-		Stat3 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
-		Stat2 = Stat2 << 16 | ResAb;
-		CMSMPrintString(
-			pAC->pConfigTable,
-			MSG_TYPE_RUNTIME_INFO,
-			"AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
-			(void *)Stat1,
-			(void *)Stat2);
-
-		Stat1 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
-		Stat2 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
-		Stat1 = Stat1 << 16 | Stat2;
-		Stat2 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
-		Stat3 = 0;
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
-		Stat2 = Stat2 << 16 | Stat3;
-		CMSMPrintString(
-			pAC->pConfigTable,
-			MSG_TYPE_RUNTIME_INFO,
-			"PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
-			(void *)Stat1,
-			(void *)Stat2);
-	}
-#endif /* DEBUG */
-
 	/*
 	 * Here we usually can check whether the link is in sync and
 	 * auto-negotiation is done.
@@ -1503,7 +1769,7 @@
 	SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
 
 	SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
-	
+
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 		("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
 
@@ -1511,57 +1777,45 @@
 
 	if ((ResAb & PHY_B_1000S_MSF) != 0) {
 		/* Error */
-		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-			("Master/Slave Fault port %d\n", Port));
-		
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+			("Master/Slave Fault, ResAb: 0x%04X\n", ResAb));
+
 		pPrt->PAutoNegFail = SK_TRUE;
 		pPrt->PMSStatus = SK_MS_STAT_FAULT;
-		
+
 		return(SK_HW_PS_RESTART);
 	}
 
 	if ((PhyStat & PHY_ST_LSYNC) == 0) {
 		return(SK_HW_PS_NONE);
 	}
-	
+
 	pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
 		SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
-	
+
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 		("Port %d, ResAb: 0x%04X\n", Port, ResAb));
 
 	if (AutoNeg) {
+		/* Auto-Negotiation Over ? */
 		if ((PhyStat & PHY_ST_AN_OVER) != 0) {
 			
 			SkHWLinkUp(pAC, IoC, Port);
-			
+
 			Done = SkMacAutoNegDone(pAC, IoC, Port);
-			
+
 			if (Done != SK_AND_OK) {
 #ifdef DEBUG
 				/* Get PHY parameters, for debugging only */
 				SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb);
 				SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat);
-				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 					("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
 					Port, LpAb, ExtStat));
 #endif /* DEBUG */
 				return(SK_HW_PS_RESTART);
 			}
 			else {
-#ifdef xDEBUG
-				/* Dummy read ISR to prevent extra link downs/ups */
-				SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
-
-				if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
-					CMSMPrintString(
-						pAC->pConfigTable,
-						MSG_TYPE_RUNTIME_INFO,
-						"CheckUp2 - Stat: %x",
-						(void *)ExtStat,
-						(void *)NULL);
-				}
-#endif /* DEBUG */
 				return(SK_HW_PS_LINK);
 			}
 		}
@@ -1570,29 +1824,15 @@
 		/* Link is up and we don't need more. */
 #ifdef DEBUG
 		if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
-			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 				("ERROR: Lipa auto detected on port %d\n", Port));
 		}
 #endif /* DEBUG */
 
-#ifdef xDEBUG
-		/* Dummy read ISR to prevent extra link downs/ups */
-		SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
-
-		if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
-			CMSMPrintString(
-				pAC->pConfigTable,
-				MSG_TYPE_RUNTIME_INFO,
-				"CheckUp3 - Stat: %x",
-				(void *)ExtStat,
-				(void *)NULL);
-		}
-#endif /* DEBUG */
-		
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
 			("Link sync(GP), Port %d\n", Port));
 		SkHWLinkUp(pAC, IoC, Port);
-		
+
 		return(SK_HW_PS_LINK);
 	}
 
@@ -1613,14 +1853,13 @@
  */
 static int SkGePortCheckUpGmac(
 SK_AC	*pAC,		/* Adapter Context */
-SK_IOC	IoC,		/* IO Context */
-int		Port,		/* Which port should be checked */
+SK_IOC	IoC,		/* I/O Context */
+int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	AutoNeg)	/* Is Auto-negotiation used ? */
 {
 	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
 	int			Done;
-	SK_U16		PhyIsrc;	/* PHY Interrupt source */
-	SK_U16		PhyStat;	/* PPY Status */
+	SK_U16		PhyStat;	/* PHY Status */
 	SK_U16		PhySpecStat;/* PHY Specific Status */
 	SK_U16		ResAb;		/* Master/Slave resolution */
 	SK_EVPARA	Para;
@@ -1640,86 +1879,81 @@
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 		("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
 
-	/* Read PHY Interrupt Status */
-	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyIsrc);
+	SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
 
-	if ((PhyIsrc & PHY_M_IS_AN_COMPL) != 0) {
-		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-			("Auto-Negotiation Completed, PhyIsrc: 0x%04X\n", PhyIsrc));
-	}
+	if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) {
 
-	if ((PhyIsrc & PHY_M_IS_LSP_CHANGE) != 0) {
-		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-			("Link Speed Changed, PhyIsrc: 0x%04X\n", PhyIsrc));
-	}
+		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
 
-	SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
-	
-	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
+		if ((ResAb & PHY_B_1000S_MSF) != 0) {
+			/* Error */
+			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+				("Master/Slave Fault, ResAb: 0x%04X\n", ResAb));
 
-	if ((ResAb & PHY_B_1000S_MSF) != 0) {
-		/* Error */
-		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-			("Master/Slave Fault port %d\n", Port));
-		
-		pPrt->PAutoNegFail = SK_TRUE;
-		pPrt->PMSStatus = SK_MS_STAT_FAULT;
-		
-		return(SK_HW_PS_RESTART);
+			pPrt->PAutoNegFail = SK_TRUE;
+			pPrt->PMSStatus = SK_MS_STAT_FAULT;
+
+			return(SK_HW_PS_RESTART);
+		}
 	}
 
 	/* Read PHY Specific Status */
 	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
-	
+
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 		("Phy1000BT: 0x%04X, PhySpecStat: 0x%04X\n", ResAb, PhySpecStat));
 
 #ifdef DEBUG
 	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &Word);
 
-	if ((PhyIsrc & PHY_M_IS_AN_PR) != 0 || (Word & PHY_ANE_RX_PG) != 0 ||
+	if ((Word & PHY_ANE_RX_PG) != 0 ||
 		(PhySpecStat & PHY_M_PS_PAGE_REC) != 0)  {
 		/* Read PHY Next Page Link Partner */
 		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_NEPG_LP, &Word);
 
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-			("Page Received, NextPage: 0x%04X\n", Word));
+			("Page received, NextPage: 0x%04X\n", Word));
 	}
 #endif /* DEBUG */
 
 	if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) {
+		/* Link down */
 		return(SK_HW_PS_NONE);
 	}
-	
-	if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0 ||
-		(PhyIsrc & PHY_M_IS_DOWNSH_DET) != 0) {
+
+	if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0) {
 		/* Downshift detected */
 		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E025, SKERR_SIRQ_E025MSG);
-		
+
 		Para.Para64 = Port;
 		SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para);
-		
+
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-			("Downshift detected, PhyIsrc: 0x%04X\n", PhyIsrc));
+			("Downshift detected, PhySpecStat: 0x%04X\n", PhySpecStat));
+	}
+
+	if ((PhySpecStat & PHY_M_PS_MDI_X_STAT) != 0) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+			("MDI Xover detected, PhyStat: 0x%04X\n", PhySpecStat));
 	}
 
 	pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
 		SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
-	
+
 	pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7);
-	
+
 	if (AutoNeg) {
 		/* Auto-Negotiation Over ? */
 		if ((PhyStat & PHY_ST_AN_OVER) != 0) {
-			
+
 			SkHWLinkUp(pAC, IoC, Port);
-			
+
 			Done = SkMacAutoNegDone(pAC, IoC, Port);
-			
+
 			if (Done != SK_AND_OK) {
 				return(SK_HW_PS_RESTART);
 			}
-			
+
 			return(SK_HW_PS_LINK);
 		}
 	}
@@ -1727,7 +1961,7 @@
 		/* Link is up and we don't need more */
 #ifdef DEBUG
 		if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
-			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 				("ERROR: Lipa auto detected on port %d\n", Port));
 		}
 #endif /* DEBUG */
@@ -1735,7 +1969,7 @@
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
 			("Link sync, Port %d\n", Port));
 		SkHWLinkUp(pAC, IoC, Port);
-		
+
 		return(SK_HW_PS_LINK);
 	}
 
@@ -1756,8 +1990,8 @@
  */
 static int SkGePortCheckUpLone(
 SK_AC	*pAC,		/* Adapter Context */
-SK_IOC	IoC,		/* IO Context */
-int		Port,		/* Which port should be checked */
+SK_IOC	IoC,		/* I/O Context */
+int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	AutoNeg)	/* Is Auto-negotiation used ? */
 {
 	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
@@ -1786,7 +2020,7 @@
 	StatSum |= PhyStat;
 
 	SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
-	
+
 	if ((PhyStat & PHY_ST_LSYNC) == 0) {
 		/* Save Auto-negotiation Done bit */
 		pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER);
@@ -1800,17 +2034,21 @@
 	}
 
 	if (AutoNeg) {
+		/* Auto-Negotiation Over ? */
 		if ((StatSum & PHY_ST_AN_OVER) != 0) {
+
 			SkHWLinkUp(pAC, IoC, Port);
+
 			Done = SkMacAutoNegDone(pAC, IoC, Port);
+
 			if (Done != SK_AND_OK) {
 				/* Get PHY parameters, for debugging only */
 				SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb);
 				SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat);
-				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 					("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
 					 Port, LpAb, ExtStat));
-					
+
 				/* Try next possible mode */
 				NextMode = SkHWSenseGetNext(pAC, IoC, Port);
 				SkHWLinkDown(pAC, IoC, Port);
@@ -1831,7 +2069,7 @@
 				return(SK_HW_PS_LINK);
 			}
 		}
-		
+
 		/* AutoNeg not done, but HW link is up. Check for timeouts */
 		pPrt->PAutoNegTimeOut++;
 		if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
@@ -1854,7 +2092,7 @@
 		/* Link is up and we don't need more */
 #ifdef DEBUG
 		if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
-			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 				("ERROR: Lipa auto detected on port %d\n", Port));
 		}
 #endif /* DEBUG */
@@ -1864,11 +2102,12 @@
 		 * extra link down/ups
 		 */
 		SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
-		
+
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
 			("Link sync(GP), Port %d\n", Port));
+
 		SkHWLinkUp(pAC, IoC, Port);
-		
+
 		return(SK_HW_PS_LINK);
 	}
 
@@ -1887,8 +2126,8 @@
  */
 static int SkGePortCheckUpNat(
 SK_AC	*pAC,		/* Adapter Context */
-SK_IOC	IoC,		/* IO Context */
-int		Port,		/* Which port should be checked */
+SK_IOC	IoC,		/* I/O Context */
+int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	AutoNeg)	/* Is Auto-negotiation used ? */
 {
 	/* todo: National */
@@ -1907,7 +2146,7 @@
  */
 int	SkGeSirqEvent(
 SK_AC		*pAC,		/* Adapter Context */
-SK_IOC		IoC,		/* Io Context */
+SK_IOC		IoC,		/* I/O Context */
 SK_U32		Event,		/* Module specific Event */
 SK_EVPARA	Para)		/* Event specific Parameter */
 {
@@ -1926,7 +2165,7 @@
 	switch (Event) {
 	case SK_HWEV_WATIM:
 		if (pPrt->PState == SK_PRT_RESET) {
-		
+
 			PortStat = SK_HW_PS_NONE;
 		}
 		else {
@@ -1956,19 +2195,23 @@
 			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para);
 			break;
 		}
-		
+
 		/* Start again the check Timer */
 		if (pPrt->PHWLinkUp) {
+			
 			Val32 = SK_WA_ACT_TIME;
 		}
 		else {
 			Val32 = SK_WA_INA_TIME;
-		}
 
-		/* Todo: still needed for non-XMAC PHYs??? */
+			if (pAC->GIni.GIYukon) {
+				Val32 *= 5;
+			}
+		}
 		/* Start workaround Errata #2 timer */
 		SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Val32,
 			SKGE_HWAC, SK_HWEV_WATIM, Para);
+
 		break;
 
 	case SK_HWEV_PORT_START:
@@ -1988,6 +2231,7 @@
 		/* Start workaround Errata #2 timer */
 		SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
 			SKGE_HWAC, SK_HWEV_WATIM, Para);
+
 		break;
 
 	case SK_HWEV_PORT_STOP:
@@ -2095,11 +2339,11 @@
 				(void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_HI, &Val32);
 
 				Octets = (SK_U64)Val32 << 32;
-				
+
 				(void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_LO, &Val32);
 
 				Octets += Val32;
-				
+
 				if (pPrt->LastOctets == Octets) {
 					/* Tx hanging, a FIFO flush restarts it */
 					SkMacFlushTxFifo(pAC, IoC, Port);
@@ -2108,7 +2352,7 @@
 		}
 		break;
 #endif /* GENESIS */
-	
+
 	default:
 		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG);
 		break;
@@ -2129,8 +2373,8 @@
  */
 static void SkPhyIsrBcom(
 SK_AC		*pAC,		/* Adapter Context */
-SK_IOC		IoC,		/* Io Context */
-int			Port,		/* Port Num = PHY Num */
+SK_IOC		IoC,		/* I/O Context */
+int			Port,		/* Port Index (MAC_1 + n) */
 SK_U16		IStatus)	/* Interrupt Status */
 {
 	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
@@ -2143,7 +2387,7 @@
 		SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E022,
 			SKERR_SIRQ_E022MSG);
 	}
-	
+
 	if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) {
 
 		SkHWLinkDown(pAC, IoC, Port);
@@ -2172,8 +2416,8 @@
  */
 static void SkPhyIsrGmac(
 SK_AC		*pAC,		/* Adapter Context */
-SK_IOC		IoC,		/* Io Context */
-int			Port,		/* Port Num = PHY Num */
+SK_IOC		IoC,		/* I/O Context */
+int			Port,		/* Port Index (MAC_1 + n) */
 SK_U16		IStatus)	/* Interrupt Status */
 {
 	SK_GEPORT	*pPrt;		/* GIni Port struct pointer */
@@ -2182,37 +2426,62 @@
 
 	pPrt = &pAC->GIni.GP[Port];
 
-	if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) {
-
-		SkHWLinkDown(pAC, IoC, Port);
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+		("PHY IRQ, PhyIsrc: 0x%04X\n", IStatus));
 
-		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word);
+	if ((IStatus & PHY_M_IS_LST_CHANGE) != 0) {
 
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-			("AutoNeg.Adv: 0x%04X\n", Word));
-		
-		/* Set Auto-negotiation advertisement */
-		if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) {
-			/* restore Asymmetric Pause bit */
-			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV,
-				(SK_U16)(Word | PHY_M_AN_ASP));
-		}
-		
+			("Link Status changed\n", IStatus));
+
 		Para.Para32[0] = (SK_U32)Port;
-		/* Signal to RLMT */
-		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+
+		if (pPrt->PHWLinkUp) {
+			
+			SkHWLinkDown(pAC, IoC, Port);
+
+			SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word);
+
+			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+				("AutoNeg.Adv: 0x%04X\n", Word));
+
+			/* Set Auto-negotiation advertisement */
+			if (pAC->GIni.GIChipId != CHIP_ID_YUKON_FE &&
+				pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) {
+				/* restore Asymmetric Pause bit */
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV,
+					(SK_U16)(Word | PHY_M_AN_ASP));
+			}
+
+			/* Signal to RLMT */
+			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+		}
+		else {
+
+			if ((IStatus & PHY_M_IS_AN_COMPL) != 0) {
+				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+					("Auto-Negotiation completed\n"));
+			}
+
+			if ((IStatus & PHY_M_IS_LSP_CHANGE) != 0) {
+				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+					("Link Speed changed\n"));
+			}
+
+			SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_WATIM, Para);
+		}
 	}
-	
+
 	if ((IStatus & PHY_M_IS_AN_ERROR) != 0) {
 		/* Auto-Negotiation Error */
 		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG);
 	}
-	
+
 	if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) {
 		/* FIFO Overflow/Underrun Error */
 		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG);
 	}
-	
+
 }	/* SkPhyIsrGmac */
 #endif /* YUKON */
 
@@ -2228,8 +2497,8 @@
  */
 static void SkPhyIsrLone(
 SK_AC	*pAC,		/* Adapter Context */
-SK_IOC	IoC,		/* Io Context */
-int		Port,		/* Port Num = PHY Num */
+SK_IOC	IoC,		/* I/O Context */
+int		Port,		/* Port Index (MAC_1 + n) */
 SK_U16	IStatus)	/* Interrupt Status */
 {
 	SK_EVPARA	Para;
diff -urN linux-2.4.29/drivers/net/sk98lin/sklm80.c linux-2.4.29-uc1/drivers/net/sk98lin/sklm80.c
--- linux-2.4.29/drivers/net/sk98lin/sklm80.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/sklm80.c	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	sklm80.c
  * Project:	Gigabit Ethernet Adapters, TWSI-Module
+ * Version:	$Revision: 1.1 $
+ * Date:	$Date: 2003/12/19 14:02:31 $
  * Purpose:	Functions to access Voltage and Temperature Sensor (LM80)
  *
  ******************************************************************************/
@@ -25,7 +27,7 @@
 */
 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
 static const char SysKonnectFileId[] =
-	"@(#) $Id: sklm80.c,v 1.22 2003/10/20 09:08:21 rschmidt Exp $ (C) Marvell. ";
+	"@(#) $Id: sklm80.c,v 1.1 2003/12/19 14:02:31 mschmid Exp $ (C) Marvell. ";
 #endif
 
 #include "h/skdrv1st.h"		/* Driver Specific Definitions */
@@ -109,12 +111,12 @@
 /*
  * read a sensors value (LM80 specific)
  *
- * This function reads a sensors value from the I2C sensor chip LM80.
+ * This function reads a sensors value from the TWSI sensor chip LM80.
  * The sensor is defined by its index into the sensors database in the struct
  * pAC points to.
  *
  * Returns	1 if the read is completed
- *		0 if the read must be continued (I2C Bus still allocated)
+ *		0 if the read must be continued (TWSI Bus still allocated)
  */
 int SkLm80ReadSensor(
 SK_AC		*pAC,	/* Adapter Context */
diff -urN linux-2.4.29/drivers/net/sk98lin/skproc.c linux-2.4.29-uc1/drivers/net/sk98lin/skproc.c
--- linux-2.4.29/drivers/net/sk98lin/skproc.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/skproc.c	2005-06-14 02:12:09.000000000 +0100
@@ -2,26 +2,36 @@
  *
  * Name:	skproc.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Purpose:	Funktions to display statictic data
+ * Version:	$Revision: 1.14 $
+ * Date:	$Date: 2004/07/26 15:01:36 $
+ * Purpose:	Functions to display statictic data
  *
  ******************************************************************************/
  
 /******************************************************************************
  *
  *	(C)Copyright 1998-2002 SysKonnect GmbH.
- *	(C)Copyright 2002-2003 Marvell.
+ *	(C)Copyright 2002-2004 Marvell.
  *
+ *	Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet 
+ *      Server Adapters.
+ *
+ *	Author: Ralph Roesler (rroesler@syskonnect.de)
+ *	        Mirko Lindner (mlindner@syskonnect.de)
+ *
+ *	Address all question to: linux@syskonnect.de
+ *
+ *	The technical manual for the adapters is available from SysKonnect's
+ *	web pages: www.syskonnect.com
+ *	
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
  *	the Free Software Foundation; either version 2 of the License, or
  *	(at your option) any later version.
  *
- *	Created 22-Nov-2000
- *	Author: Mirko Lindner (mlindner@syskonnect.de)
- *
  *	The information in this file is provided "AS IS" without warranty.
  *
- ******************************************************************************/
+ *****************************************************************************/
 
 #include <linux/proc_fs.h>
 
@@ -30,9 +40,16 @@
 #include "h/skversion.h"
 
 extern struct SK_NET_DEVICE *SkGeRootDev;
+
+/******************************************************************************
+ *
+ * Local Function Prototypes and Local Variables
+ *
+ *****************************************************************************/
+
 static int sk_proc_print(void *writePtr, char *format, ...);
 static void sk_gen_browse(void *buffer);
-int len;
+static int len;
 
 struct proc_dir_entry *file = NULL;
 
@@ -41,19 +58,21 @@
  *      sk_proc_read - show proc information of a particular adapter
  *
  * Description:
- *  This function fills the proc entry with statistic data about 
- *  the ethernet device. It invokes the generic sk_gen_browse() to
- *  print out all items one per one.
+ *	This function fills the proc entry with statistic data about 
+ *	the ethernet device. It invokes the generic sk_gen_browse() to
+ *	print out all items one per one.
  *  
- * Returns: number of bytes written
+ * Returns:
+ *	the number of bytes written
  *      
  */
-int sk_proc_read(char   *buffer,
-		char  **buffer_location,
-		off_t   offset,
-		int     buffer_length,
-		int    *eof,
-		void   *data)
+int sk_proc_read(
+char   *buffer,           /* the buffer holding the display results */
+char  **buffer_location,  /* the buffer location                    */
+off_t   offset,           /* additional offset                      */
+int     buffer_length,    /* total buffer length                    */
+int    *eof,              /* End Of File (EOF) indication           */
+void   *data)             /* the data pointer                       */
 {
 	void *castedBuffer = (void *) buffer;
 	file               = (struct proc_dir_entry*) data;
@@ -77,16 +96,18 @@
  * 	sk_gen_browse -generic  print "summaries" entry 
  *
  * Description:
- *  This function fills the proc entry with statistic data about 
- *  the ethernet device.
+ *	This function fills the proc entry with statistic data about 
+ *	the ethernet device.
  *  
- * Returns: -
+ * Returns:	N/A
  *	
  */
-static void sk_gen_browse(void *buffer)
+static void sk_gen_browse(
+void *buffer)  /* buffer where the statistics will be stored in */
 {
 	struct SK_NET_DEVICE	*SkgeProcDev = SkGeRootDev;
 	struct SK_NET_DEVICE	*next;
+	SK_BOOL			DisableStatistic = 0;
 	SK_PNMI_STRUCT_DATA 	*pPnmiStruct;
 	SK_PNMI_STAT		*pPnmiStat;
 	unsigned long		Flags;	
@@ -94,6 +115,7 @@
 	DEV_NET			*pNet;
 	SK_AC			*pAC;
 	char			sens_msg[50];
+	int 			card_type;
 	int			MaxSecurityCount = 0;
 	int 			t;
 	int 			i;
@@ -116,7 +138,7 @@
 
 			spin_lock_irqsave(&pAC->SlowPathLock, Flags);
 			Size = SK_PNMI_STRUCT_SIZE;
-#ifdef SK_DIAG_SUPPORT
+			DisableStatistic = 0;
 			if (pAC->BoardLevel == SK_INIT_DATA) {
 				SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA));
 				if (pAC->DiagModeActive == DIAG_NOTACTIVE) {
@@ -125,13 +147,13 @@
 			} else {
 				SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1);
 			}
-#else
-			SkPnmiGetStruct(pAC, pAC->IoBase, 
-				pPnmiStruct, &Size, t-1);
-#endif
 			spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-	
 			if (strcmp(pAC->dev[t-1]->name, file->name) == 0) {
+				if (!pAC->GIni.GIYukon32Bit)
+					card_type = 64;
+				else
+					card_type = 32;
+
 				pPnmiStat = &pPnmiStruct->Stat[0];
 				len = sk_proc_print(buffer, 
 					"\nDetailed statistic for device %s\n",
@@ -143,6 +165,17 @@
 				len += sk_proc_print(buffer, 
 					"\nBoard statistics\n\n");
 				len += sk_proc_print(buffer,
+					"Card name                      %s\n",
+					pAC->DeviceStr);
+				len += sk_proc_print(buffer,
+					"Vendor/Device ID               %x/%x\n",
+					pAC->PciDev->vendor,
+					pAC->PciDev->device);
+				len += sk_proc_print(buffer,
+					"Card type (Bit)                %d\n",
+					card_type);
+					
+				len += sk_proc_print(buffer,
 					"Active Port                    %c\n",
 					'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
 					Net[t-1].PrefPort]->PortNumber);
@@ -151,177 +184,215 @@
 					'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
 					Net[t-1].PrefPort]->PortNumber);
 
+				if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC)
+					len += sk_proc_print(buffer,
+					"Interrupt Moderation           static (%d ints/sec)\n",
+					pAC->DynIrqModInfo.MaxModIntsPerSec);
+				else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC)
+					len += sk_proc_print(buffer,
+					"Interrupt Moderation           dynamic (%d ints/sec)\n",
+					pAC->DynIrqModInfo.MaxModIntsPerSec);
+				else
+					len += sk_proc_print(buffer,
+					"Interrupt Moderation           disabled\n");
+
+				if (CHIP_ID_YUKON_2(pAC)) {
+					len += sk_proc_print(buffer,
+						"Bus type                       PCI Express\n",
+						pPnmiStruct->BusSpeed);
+				} else {
+					len += sk_proc_print(buffer,
+						"Bus speed (MHz)                %d\n",
+						pPnmiStruct->BusSpeed);
+					len += sk_proc_print(buffer,
+						"Bus width (Bit)                %d\n",
+						pPnmiStruct->BusWidth);
+				}
 				len += sk_proc_print(buffer,
-					"Bus speed (MHz)                %d\n",
-					pPnmiStruct->BusSpeed);
-
-				len += sk_proc_print(buffer,
-					"Bus width (Bit)                %d\n",
-					pPnmiStruct->BusWidth);
+					"Driver version                 %s (%s)\n",
+					VER_STRING, PATCHLEVEL);
 				len += sk_proc_print(buffer,
-					"Driver version                 %s\n",
-					VER_STRING);
+					"Driver release date            %s\n",
+					pAC->Pnmi.pDriverReleaseDate);
 				len += sk_proc_print(buffer,
 					"Hardware revision              v%d.%d\n",
 					(pAC->GIni.GIPciHwRev >> 4) & 0x0F,
 					pAC->GIni.GIPciHwRev & 0x0F);
 
-				/* Print sensor informations */
-				for (i=0; i < pAC->I2c.MaxSens; i ++) {
-					/* Check type */
-					switch (pAC->I2c.SenTable[i].SenType) {
-					case 1:
-						strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-						strcat(sens_msg, " (C)");
-						len += sk_proc_print(buffer,
-							"%-25s      %d.%02d\n",
-							sens_msg,
-							pAC->I2c.SenTable[i].SenValue / 10,
-							pAC->I2c.SenTable[i].SenValue % 10);
-
-						strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-						strcat(sens_msg, " (F)");
-						len += sk_proc_print(buffer,
-							"%-25s      %d.%02d\n",
-							sens_msg,
-							((((pAC->I2c.SenTable[i].SenValue)
-							*10)*9)/5 + 3200)/100,
-							((((pAC->I2c.SenTable[i].SenValue)
-							*10)*9)/5 + 3200) % 10);
-						break;
-					case 2:
-						strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-						strcat(sens_msg, " (V)");
-						len += sk_proc_print(buffer,
-							"%-25s      %d.%03d\n",
-							sens_msg,
-							pAC->I2c.SenTable[i].SenValue / 1000,
-							pAC->I2c.SenTable[i].SenValue % 1000);
-						break;
-					case 3:
-						strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-						strcat(sens_msg, " (rpm)");
-						len += sk_proc_print(buffer,
-							"%-25s      %d\n",
-							sens_msg,
-							pAC->I2c.SenTable[i].SenValue);
-						break;
-					default:
-						break;
-					}
+				if (!pNet->Up) {
+					len += sk_proc_print(buffer,
+						"\n      Device %s is down.\n"
+						"      Therefore no statistics are available.\n"
+						"      After bringing the device up (ifconfig)"
+						" statistics will\n"
+						"      be displayed.\n",
+						pAC->dev[t-1]->name);
+					DisableStatistic = 1;
 				}
-				
-				/*Receive statistics */
-				len += sk_proc_print(buffer, 
-				"\nReceive statistics\n\n");
 
-				len += sk_proc_print(buffer,
-					"Received bytes                 %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxOctetsOkCts);
-				len += sk_proc_print(buffer,
-					"Received packets               %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxOkCts);
+				/* Display only if statistic info available */
+				/* Print sensor informations */
+				if (!DisableStatistic) {
+					for (i=0; i < pAC->I2c.MaxSens; i ++) {
+						/* Check type */
+						switch (pAC->I2c.SenTable[i].SenType) {
+						case 1:
+							strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+							strcat(sens_msg, " (C)");
+							len += sk_proc_print(buffer,
+								"%-25s      %d.%02d\n",
+								sens_msg,
+								pAC->I2c.SenTable[i].SenValue / 10,
+								pAC->I2c.SenTable[i].SenValue %
+								10);
+
+							strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+							strcat(sens_msg, " (F)");
+							len += sk_proc_print(buffer,
+								"%-25s      %d.%02d\n",
+								sens_msg,
+								((((pAC->I2c.SenTable[i].SenValue)
+								*10)*9)/5 + 3200)/100,
+								((((pAC->I2c.SenTable[i].SenValue)
+								*10)*9)/5 + 3200) % 10);
+							break;
+						case 2:
+							strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+							strcat(sens_msg, " (V)");
+							len += sk_proc_print(buffer,
+								"%-25s      %d.%03d\n",
+								sens_msg,
+								pAC->I2c.SenTable[i].SenValue / 1000,
+								pAC->I2c.SenTable[i].SenValue % 1000);
+							break;
+						case 3:
+							strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+							strcat(sens_msg, " (rpm)");
+							len += sk_proc_print(buffer,
+								"%-25s      %d\n",
+								sens_msg,
+								pAC->I2c.SenTable[i].SenValue);
+							break;
+						default:
+							break;
+						}
+					}
+			
+					/*Receive statistics */
+					len += sk_proc_print(buffer, 
+					"\nReceive statistics\n\n");
+
+					len += sk_proc_print(buffer,
+						"Received bytes                 %Lu\n",
+						(unsigned long long) pPnmiStat->StatRxOctetsOkCts);
+					len += sk_proc_print(buffer,
+						"Received packets               %Lu\n",
+						(unsigned long long) pPnmiStat->StatRxOkCts);
 #if 0
-				if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && 
-					pAC->HWRevision < 12) {
-					pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - 
-						pPnmiStat->StatRxShortsCts;
-					pPnmiStat->StatRxShortsCts = 0;
-				}
+					if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && 
+						pAC->HWRevision < 12) {
+						pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - 
+							pPnmiStat->StatRxShortsCts;
+						pPnmiStat->StatRxShortsCts = 0;
+					}
+#endif
+					if (pNet->Mtu > 1500) 
+						pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
+							pPnmiStat->StatRxTooLongCts;
+
+					len += sk_proc_print(buffer,
+						"Receive errors                 %Lu\n",
+						(unsigned long long) pPnmiStruct->InErrorsCts);
+					len += sk_proc_print(buffer,
+						"Receive dropped                %Lu\n",
+						(unsigned long long) pPnmiStruct->RxNoBufCts);
+					len += sk_proc_print(buffer,
+						"Received multicast             %Lu\n",
+						(unsigned long long) pPnmiStat->StatRxMulticastOkCts);
+#ifdef ADVANCED_STATISTIC_OUTPUT
+					len += sk_proc_print(buffer,
+						"Receive error types\n");
+					len += sk_proc_print(buffer,
+						"   length                      %Lu\n",
+						(unsigned long long) pPnmiStat->StatRxRuntCts);
+					len += sk_proc_print(buffer,
+						"   buffer overflow             %Lu\n",
+						(unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
+					len += sk_proc_print(buffer,
+						"   bad crc                     %Lu\n",
+						(unsigned long long) pPnmiStat->StatRxFcsCts);
+					len += sk_proc_print(buffer,
+						"   framing                     %Lu\n",
+						(unsigned long long) pPnmiStat->StatRxFramingCts);
+					len += sk_proc_print(buffer,
+						"   missed frames               %Lu\n",
+						(unsigned long long) pPnmiStat->StatRxMissedCts);
+
+					if (pNet->Mtu > 1500)
+						pPnmiStat->StatRxTooLongCts = 0;
+
+					len += sk_proc_print(buffer,
+						"   too long                    %Lu\n",
+						(unsigned long long) pPnmiStat->StatRxTooLongCts);					
+					len += sk_proc_print(buffer,
+						"   carrier extension           %Lu\n",
+						(unsigned long long) pPnmiStat->StatRxCextCts);				
+					len += sk_proc_print(buffer,
+						"   too short                   %Lu\n",
+						(unsigned long long) pPnmiStat->StatRxShortsCts);				
+					len += sk_proc_print(buffer,
+						"   symbol                      %Lu\n",
+						(unsigned long long) pPnmiStat->StatRxSymbolCts);				
+					len += sk_proc_print(buffer,
+						"   LLC MAC size                %Lu\n",
+						(unsigned long long) pPnmiStat->StatRxIRLengthCts);				
+					len += sk_proc_print(buffer,
+						"   carrier event               %Lu\n",
+						(unsigned long long) pPnmiStat->StatRxCarrierCts);				
+					len += sk_proc_print(buffer,
+						"   jabber                      %Lu\n",
+						(unsigned long long) pPnmiStat->StatRxJabberCts);				
 #endif
-				if (pNet->Mtu > 1500) 
-					pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
-						pPnmiStat->StatRxTooLongCts;
-
-				len += sk_proc_print(buffer,
-					"Receive errors                 %Lu\n",
-					(unsigned long long) pPnmiStruct->InErrorsCts);
-				len += sk_proc_print(buffer,
-					"Receive dropped                %Lu\n",
-					(unsigned long long) pPnmiStruct->RxNoBufCts);
-				len += sk_proc_print(buffer,
-					"Received multicast             %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxMulticastOkCts);
-				len += sk_proc_print(buffer,
-					"Receive error types\n");
-				len += sk_proc_print(buffer,
-					"   length                      %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxRuntCts);
-				len += sk_proc_print(buffer,
-					"   buffer overflow             %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
-				len += sk_proc_print(buffer,
-					"   bad crc                     %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxFcsCts);
-				len += sk_proc_print(buffer,
-					"   framing                     %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxFramingCts);
-				len += sk_proc_print(buffer,
-					"   missed frames               %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxMissedCts);
-
-				if (pNet->Mtu > 1500)
-					pPnmiStat->StatRxTooLongCts = 0;
-
-				len += sk_proc_print(buffer,
-					"   too long                    %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxTooLongCts);					
-				len += sk_proc_print(buffer,
-					"   carrier extension           %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxCextCts);				
-				len += sk_proc_print(buffer,
-					"   too short                   %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxShortsCts);				
-				len += sk_proc_print(buffer,
-					"   symbol                      %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxSymbolCts);				
-				len += sk_proc_print(buffer,
-					"   LLC MAC size                %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxIRLengthCts);				
-				len += sk_proc_print(buffer,
-					"   carrier event               %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxCarrierCts);				
-				len += sk_proc_print(buffer,
-					"   jabber                      %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxJabberCts);				
-
 
-				/*Transmit statistics */
-				len += sk_proc_print(buffer, 
-				"\nTransmit statistics\n\n");
+					/*Transmit statistics */
+					len += sk_proc_print(buffer, 
+					"\nTransmit statistics\n\n");
 				
-				len += sk_proc_print(buffer,
-					"Transmited bytes               %Lu\n",
-					(unsigned long long) pPnmiStat->StatTxOctetsOkCts);
-				len += sk_proc_print(buffer,
-					"Transmited packets             %Lu\n",
-					(unsigned long long) pPnmiStat->StatTxOkCts);
-				len += sk_proc_print(buffer,
-					"Transmit errors                %Lu\n",
-					(unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
-				len += sk_proc_print(buffer,
-					"Transmit dropped               %Lu\n",
-					(unsigned long long) pPnmiStruct->TxNoBufCts);
-				len += sk_proc_print(buffer,
-					"Transmit collisions            %Lu\n",
-					(unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
-				len += sk_proc_print(buffer,
-					"Transmit error types\n");
-				len += sk_proc_print(buffer,
-					"   excessive collision         %ld\n",
-					pAC->stats.tx_aborted_errors);
-				len += sk_proc_print(buffer,
-					"   carrier                     %Lu\n",
-					(unsigned long long) pPnmiStat->StatTxCarrierCts);
-				len += sk_proc_print(buffer,
-					"   fifo underrun               %Lu\n",
-					(unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
-				len += sk_proc_print(buffer,
-					"   heartbeat                   %Lu\n",
-					(unsigned long long) pPnmiStat->StatTxCarrierCts);
-				len += sk_proc_print(buffer,
-					"   window                      %ld\n",
-					pAC->stats.tx_window_errors);
+					len += sk_proc_print(buffer,
+						"Transmitted bytes              %Lu\n",
+						(unsigned long long) pPnmiStat->StatTxOctetsOkCts);
+					len += sk_proc_print(buffer,
+						"Transmitted packets            %Lu\n",
+						(unsigned long long) pPnmiStat->StatTxOkCts);
+					len += sk_proc_print(buffer,
+						"Transmit errors                %Lu\n",
+						(unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
+					len += sk_proc_print(buffer,
+						"Transmit dropped               %Lu\n",
+						(unsigned long long) pPnmiStruct->TxNoBufCts);
+					len += sk_proc_print(buffer,
+						"Transmit collisions            %Lu\n",
+						(unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
+#ifdef ADVANCED_STATISTIC_OUTPUT
+					len += sk_proc_print(buffer,
+						"Transmit error types\n");
+					len += sk_proc_print(buffer,
+						"   excessive collision         %ld\n",
+						pAC->stats.tx_aborted_errors);
+					len += sk_proc_print(buffer,
+						"   carrier                     %Lu\n",
+						(unsigned long long) pPnmiStat->StatTxCarrierCts);
+					len += sk_proc_print(buffer,
+						"   fifo underrun               %Lu\n",
+						(unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
+					len += sk_proc_print(buffer,
+						"   heartbeat                   %Lu\n",
+						(unsigned long long) pPnmiStat->StatTxCarrierCts);
+					len += sk_proc_print(buffer,
+						"   window                      %ld\n",
+						pAC->stats.tx_window_errors);
+#endif
+				} /* if (!DisableStatistic) */
 				
 			} /* if (strcmp(pACname, currDeviceName) == 0) */
 		}
@@ -331,16 +402,20 @@
 
 /*****************************************************************************
  *
- *      sk_proc_print -generic line print  
+ *      sk_proc_print - generic line print  
  *
  * Description:
- *  This function fills the proc entry with statistic data about 
- *  the ethernet device.
+ *	This function fills the proc entry with statistic data about the 
+ *	ethernet device.
  *  
- * Returns: number of bytes written
+ * Returns:
+ *	the number of bytes written
  *      
  */ 
-static int sk_proc_print(void *writePtr, char *format, ...)
+static int sk_proc_print(
+void *writePtr, /* the buffer pointer         */
+char *format,   /* the format of the string   */
+...)            /* variable list of arguments */
 {   
 #define MAX_LEN_SINGLE_LINE 256
 	char     str[MAX_LEN_SINGLE_LINE];
diff -urN linux-2.4.29/drivers/net/sk98lin/skqueue.c linux-2.4.29-uc1/drivers/net/sk98lin/skqueue.c
--- linux-2.4.29/drivers/net/sk98lin/skqueue.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/skqueue.c	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skqueue.c
  * Project:	Gigabit Ethernet Adapters, Event Scheduler Module
+ * Version:	$Revision: 2.3 $
+ * Date:	$Date: 2004/05/14 13:28:18 $
  * Purpose:	Management of an event queue.
  *
  ******************************************************************************/
@@ -20,12 +22,13 @@
  *
  ******************************************************************************/
 
+
 /*
  *	Event queue and dispatcher
  */
 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skqueue.c,v 1.20 2003/09/16 13:44:00 rschmidt Exp $ (C) Marvell.";
+	"@(#) $Id: skqueue.c,v 2.3 2004/05/14 13:28:18 malthoff Exp $ (C) Marvell.";
 #endif
 
 #include "h/skdrv1st.h"		/* Driver Specific Definitions */
@@ -45,10 +48,16 @@
 
 #define PRINTF(a,b,c)
 
-/*
- * init event queue management
+/******************************************************************************
  *
- * Must be called during init level 0.
+ *	SkEventInit() - init event queue management
+ *
+ * Description:
+ * 	This function initializes event queue management.
+ *	It must be called during init level 0.
+ *
+ * Returns:
+ *	nothing
  */
 void	SkEventInit(
 SK_AC	*pAC,	/* Adapter context */
@@ -64,8 +73,17 @@
 	}
 }
 
-/*
- * add event to queue
+/******************************************************************************
+ *
+ *	SkEventQueue()	-	add event to queue
+ *
+ * Description:
+ *	This function adds an event to the event queue.
+ *	At least Init Level 1 is required to queue events,
+ *	but will be scheduled add Init Level 2.
+ *
+ * returns:
+ *	nothing
  */
 void	SkEventQueue(
 SK_AC		*pAC,	/* Adapters context */
@@ -73,26 +91,45 @@
 SK_U32		Event,	/* Event to be queued */
 SK_EVPARA	Para)	/* Event parameter */
 {
-	pAC->Event.EvPut->Class = Class;
-	pAC->Event.EvPut->Event = Event;
-	pAC->Event.EvPut->Para = Para;
+
+	if (pAC->GIni.GILevel == SK_INIT_DATA) {
+		SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E003, SKERR_Q_E003MSG);
+	}
+	else {
+		pAC->Event.EvPut->Class = Class;
+		pAC->Event.EvPut->Event = Event;
+		pAC->Event.EvPut->Para = Para;
 	
-	if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT])
-		pAC->Event.EvPut = pAC->Event.EvQueue;
+		if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT])
+			pAC->Event.EvPut = pAC->Event.EvQueue;
 
-	if (pAC->Event.EvPut == pAC->Event.EvGet) {
-		SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG);
+		if (pAC->Event.EvPut == pAC->Event.EvGet) {
+			SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG);
+		}
 	}
 }
 
-/*
- * event dispatcher
- *	while event queue is not empty
- *		get event from queue
- *		send command to state machine
- *	end
- *	return error reported by individual Event function
- *		0 if no error occured.
+/******************************************************************************
+ *
+ *	SkEventDispatcher() -	 Event Dispatcher
+ *
+ * Description:
+ *	The event dispatcher performs the following operations:
+ *		o while event queue is not empty
+ *			- get event from queue
+ *			- send event to state machine
+ *		  end
+ *
+ * CAUTION:
+ *	The event functions MUST report an error if performing a reinitialization
+ *	of the event queue, e.g. performing level Init 0..2 while in dispatcher
+ *	call!
+ *  ANY OTHER return value delays scheduling the other events in the
+ *	queue. In this case the event blocks the queue until
+ *  the error condition is cleared!
+ *
+ * Returns:
+ *	The return value error reported by individual event function
  */
 int	SkEventDispatcher(
 SK_AC	*pAC,	/* Adapters Context */
@@ -102,6 +139,10 @@
 	SK_U32			Class;
 	int			Rtv;
 
+	if (pAC->GIni.GILevel != SK_INIT_RUN) {
+		SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E005, SKERR_Q_E005MSG);
+	}
+
 	pEv = pAC->Event.EvGet;
 	
 	PRINTF("dispatch get %x put %x\n", pEv, pAC->Event.ev_put);
@@ -149,6 +190,11 @@
 			Rtv = SkFdEvent(pAC, Ioc, pEv->Event, pEv->Para);
 			break;
 #endif /* SK_USE_LAC_EV */
+#ifdef SK_ASF
+		case SKGE_ASF :
+			Rtv = SkAsfEvent(pAC,Ioc,pEv->Event,pEv->Para);
+			break ;
+#endif
 #ifdef	SK_USE_CSUM
 		case SKGE_CSUM :
 			Rtv = SkCsEvent(pAC, Ioc, pEv->Event, pEv->Para);
@@ -160,6 +206,20 @@
 		}
 
 		if (Rtv != 0) {
+			/* 
+			 * Special Case: See CAUTION statement above.
+			 * We assume the event queue is reset.
+			 */
+			if (pAC->Event.EvGet != pAC->Event.EvQueue &&
+				pAC->Event.EvGet != pEv) {
+				/*
+				 * Create an error log entry if the
+				 * event queue isn't reset.
+				 * In this case it may be blocked.
+				 */
+				SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E004, SKERR_Q_E004MSG);
+			}
+
 			return(Rtv);
 		}
 
diff -urN linux-2.4.29/drivers/net/sk98lin/skrlmt.c linux-2.4.29-uc1/drivers/net/sk98lin/skrlmt.c
--- linux-2.4.29/drivers/net/sk98lin/skrlmt.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/skrlmt.c	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skrlmt.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:	$Revision: 2.2 $
+ * Date:	$Date: 2003/11/24 12:27:57 $
  * Purpose:	Manage links on SK-NET Adapters, esp. redundant ones.
  *
  ******************************************************************************/
@@ -37,7 +39,7 @@
 
 #ifndef	lint
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skrlmt.c,v 1.69 2003/04/15 09:39:22 tschilli Exp $ (C) Marvell.";
+	"@(#) $Id: skrlmt.c,v 2.2 2003/11/24 12:27:57 mkarl Exp $ (C) Marvell.";
 #endif	/* !defined(lint) */
 
 #define __SKRLMT_C
@@ -348,7 +350,7 @@
     SK_BOOL		PhysicalAMacAddressSet;
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
-		("RLMT Init level %d.\n", Level))
+		("RLMT Init level %d.\n", Level));
 
 	switch (Level) {
 	case SK_INIT_DATA:	/* Initialize data structures. */
@@ -388,7 +390,7 @@
 
 	case SK_INIT_IO:	/* GIMacsFound first available here. */
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
-			("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound))
+			("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound));
 
 		pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
 
@@ -510,7 +512,7 @@
 	}
 			
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SkRlmtBuildCheckChain.\n"))
+		("SkRlmtBuildCheckChain.\n"));
 
 	NumMacsUp = 0;
 
@@ -556,7 +558,7 @@
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
 			("Port %d checks %d other ports: %2X.\n", i,
 				pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked,
-				pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5]))
+				pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5]));
 	}
 #endif	/* DEBUG */
 
@@ -602,7 +604,7 @@
 	if ((CheckSrc == 0) || (CheckDest == 0)) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR,
 			("SkRlmtBuildPacket: Invalid %s%saddr.\n",
-			 (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : "")))
+			 (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : "")));
 	}
 #endif
 
@@ -794,7 +796,7 @@
 
 			SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
 			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX,
-				("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber))
+				("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber));
 		}
 	}
 	return;
@@ -833,7 +835,7 @@
 		 * Bring it up.
 		 */
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-			("SkRlmtPacketReceive: Received on PortDown.\n"))
+			("SkRlmtPacketReceive: Received on PortDown.\n"));
 
 		pRPort->PortState = SK_RLMT_PS_GOING_UP;
 		pRPort->GuTimeStamp = SkOsGetTime(pAC);
@@ -847,7 +849,7 @@
 	}	/* PortDown && !SuspectTx */
 	else if (pRPort->CheckingState & SK_RLMT_PCS_RX) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-			("SkRlmtPacketReceive: Stop bringing port down.\n"))
+			("SkRlmtPacketReceive: Stop bringing port down.\n"));
 		SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
 		pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
 		/* pAC->Rlmt.CheckSwitch = SK_TRUE; */
@@ -894,7 +896,7 @@
 	pRPort = &pAC->Rlmt.Port[PortNumber];
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-		("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber))
+		("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber));
 
 	pRPacket = (SK_RLMT_PACKET*)pMb->pData;
 	pSPacket = (SK_SPTREE_PACKET*)pRPacket;
@@ -915,7 +917,7 @@
 
 		/* Not sent to current MAC or registered MC address => Trash it. */
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-			("SkRlmtPacketReceive: Not for me.\n"))
+			("SkRlmtPacketReceive: Not for me.\n"));
 
 		SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
 		return;
@@ -953,7 +955,7 @@
 			pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
 			pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
 			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-				("SkRlmtPacketReceive: Duplicate MAC Address.\n"))
+				("SkRlmtPacketReceive: Duplicate MAC Address.\n"));
 
 			/* Error Log entry. */
 			SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E006, SKERR_RLMT_E006_MSG);
@@ -961,7 +963,7 @@
 		else {
 			/* Simply trash it. */
 			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-				("SkRlmtPacketReceive: Sent by me.\n"))
+				("SkRlmtPacketReceive: Sent by me.\n"));
 		}
 
 		SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
@@ -1005,7 +1007,7 @@
 #endif	/* 0 */
 
 			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-				("SkRlmtPacketReceive: Announce.\n"))
+				("SkRlmtPacketReceive: Announce.\n"));
 
 			SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
 			break;
@@ -1013,7 +1015,7 @@
 		case SK_PACKET_ALIVE:
 			if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) {
 				SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-					("SkRlmtPacketReceive: Alive Reply.\n"))
+					("SkRlmtPacketReceive: Alive Reply.\n"));
 
 				if (!(pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_LLC) ||
 					SK_ADDR_EQUAL(
@@ -1044,7 +1046,7 @@
 			}
 			else {	/* Alive Request Packet. */
 				SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-					("SkRlmtPacketReceive: Alive Request.\n"))
+					("SkRlmtPacketReceive: Alive Request.\n"));
 
 				pRPort->RxHelloCts++;
 
@@ -1063,7 +1065,7 @@
 
 		case SK_PACKET_CHECK_TX:
 			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-				("SkRlmtPacketReceive: Check your tx line.\n"))
+				("SkRlmtPacketReceive: Check your tx line.\n"));
 
 			/* A port checking us requests us to check our tx line. */
 			pRPort->CheckingState |= SK_RLMT_PCS_TX;
@@ -1086,7 +1088,7 @@
 
 		case SK_PACKET_ADDR_CHANGED:
 			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-				("SkRlmtPacketReceive: Address Change.\n"))
+				("SkRlmtPacketReceive: Address Change.\n"));
 
 			/* Build the check chain. */
 			SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
@@ -1095,7 +1097,7 @@
 
 		default:
 			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-				("SkRlmtPacketReceive: Unknown RLMT packet.\n"))
+				("SkRlmtPacketReceive: Unknown RLMT packet.\n"));
 
 			/* RA;:;: ??? */
 			SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
@@ -1105,7 +1107,7 @@
 		pSPacket->Ctrl == SK_RLMT_SPT_CTRL &&
 		(pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-			("SkRlmtPacketReceive: BPDU Packet.\n"))
+			("SkRlmtPacketReceive: BPDU Packet.\n"));
 
 		/* Spanning Tree packet. */
 		pRPort->RxSpHelloCts++;
@@ -1137,7 +1139,7 @@
 					pRPort->Root.Id[0], pRPort->Root.Id[1],
 					pRPort->Root.Id[2], pRPort->Root.Id[3],
 					pRPort->Root.Id[4], pRPort->Root.Id[5],
-					pRPort->Root.Id[6], pRPort->Root.Id[7]))
+					pRPort->Root.Id[6], pRPort->Root.Id[7]));
 		}
 
 		SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
@@ -1148,7 +1150,7 @@
 	}
 	else {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
-			("SkRlmtPacketReceive: Unknown Packet Type.\n"))
+			("SkRlmtPacketReceive: Unknown Packet Type.\n"));
 
 		/* Unknown packet. */
 		SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
@@ -1230,7 +1232,7 @@
 	if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
 			("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n",
-				PortNumber, pRPort->PacketsPerTimeSlot))
+				PortNumber, pRPort->PacketsPerTimeSlot));
 
 		/*
 		 * Check segmentation if there was no receive at least twice
@@ -1247,7 +1249,7 @@
 
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
 			("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n",
-				pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX))
+				pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX));
 
 		if (pRPort->PortState != SK_RLMT_PS_DOWN) {
 			NewTimeout = TO_SHORTEN(pAC->Rlmt.Port[PortNumber].Net->TimeoutValue);
@@ -1293,7 +1295,7 @@
 			("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n",
 				PortNumber,
 				pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot,
-				pRPort->PacketsPerTimeSlot))
+				pRPort->PacketsPerTimeSlot));
 		
 		SkRlmtPortReceives(pAC, IoC, PortNumber);
 		if (pAC->Rlmt.CheckSwitch) {
@@ -1343,7 +1345,7 @@
 				i,
    				pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx,
 				*((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32),
-				*((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32)))
+				*((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32)));
 
 		if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) {
 			if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) {
@@ -1356,7 +1358,7 @@
 
 	if (PortFound) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Port %d received the last broadcast.\n", *pSelect))
+			("Port %d received the last broadcast.\n", *pSelect));
 
 		/* Look if another port's time stamp is similar. */
 		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
@@ -1371,7 +1373,7 @@
 				PortFound = SK_FALSE;
 				
 				SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-					("Port %d received a broadcast at a similar time.\n", i))
+					("Port %d received a broadcast at a similar time.\n", i));
 				break;
 			}
 		}
@@ -1383,7 +1385,7 @@
 			("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially "
 			 "latest broadcast (%u).\n",
 				*pSelect,
-				BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp))
+				BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp));
 	}
 #endif	/* DEBUG */
 
@@ -1432,7 +1434,7 @@
 			PortFound = SK_TRUE;
 			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
 				("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n",
-					*pSelect))
+					*pSelect));
 			break;
 		}
 	}
@@ -1481,7 +1483,7 @@
 			}
 			PortFound = SK_TRUE;
 			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-				("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect))
+				("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect));
 			break;
 		}
 	}
@@ -1542,7 +1544,7 @@
 	}
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect))
+		("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect));
 	return (SK_TRUE);
 }	/* SkRlmtSelectGoingUp */
 
@@ -1588,7 +1590,7 @@
 			}
 			PortFound = SK_TRUE;
 			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-				("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect))
+				("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect));
 			break;
 		}
 	}
@@ -1786,7 +1788,7 @@
 
 			if (Para.Para32[1] != Active) {
 				SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-					("Active: %d, Para1: %d.\n", Active, Para.Para32[1]))
+					("Active: %d, Para1: %d.\n", Active, Para.Para32[1]));
 				pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1];
 				Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
 					Port[Para.Para32[0]]->PortNumber;
@@ -1866,7 +1868,7 @@
 				pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1],
 				pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3],
 				pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5],
-				pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7]))
+				pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7]));
 
 		if (!pNet->RootIdSet) {
 			pNet->Root = pNet->Port[i]->Root;
@@ -1961,13 +1963,13 @@
 	SK_U32			i;
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0]))
+		("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0]));
 
 		if (Para.Para32[1] != (SK_U32)-1) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad Parameter.\n"))
+			("Bad Parameter.\n"));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n"))
+			("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n"));
 		return;
 	}
 
@@ -1988,7 +1990,7 @@
 	}
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_PORTSTART_TIMEOUT Event END.\n"))
+		("SK_RLMT_PORTSTART_TIMEOUT Event END.\n"));
 }	/* SkRlmtEvtPortStartTim */
 
 
@@ -2016,21 +2018,21 @@
 	SK_EVPARA		Para2;
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0]))
+		("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0]));
 
 	pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
 	if (!pRPort->PortStarted) {
 		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG);
 
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-				("SK_RLMT_LINK_UP Event EMPTY.\n"))
+				("SK_RLMT_LINK_UP Event EMPTY.\n"));
 		return;
 	}
 
 	if (!pRPort->LinkDown) {
 		/* RA;:;: Any better solution? */
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_LINK_UP Event EMPTY.\n"))
+			("SK_RLMT_LINK_UP Event EMPTY.\n"));
 		return;
 	}
 
@@ -2108,7 +2110,7 @@
 	}
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_LINK_UP Event END.\n"))
+		("SK_RLMT_LINK_UP Event END.\n"));
 }	/* SkRlmtEvtLinkUp */
 
 
@@ -2134,20 +2136,20 @@
 	SK_RLMT_PORT	*pRPort;
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0]))
+		("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0]));
 
 	if (Para.Para32[1] != (SK_U32)-1) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad Parameter.\n"))
+			("Bad Parameter.\n"));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_PORTUP_TIM Event EMPTY.\n"))
+			("SK_RLMT_PORTUP_TIM Event EMPTY.\n"));
 		return;
 	}
 
 	pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
 	if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0]))
+			("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0]));
 		return;
 	}
 
@@ -2162,7 +2164,7 @@
 	}
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_PORTUP_TIM Event END.\n"))
+		("SK_RLMT_PORTUP_TIM Event END.\n"));
 }	/* SkRlmtEvtPortUpTim */
 
 
@@ -2190,13 +2192,13 @@
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
 		("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n",
-			Para.Para32[0], Event))
+			Para.Para32[0], Event));
 
 	if (Para.Para32[1] != (SK_U32)-1) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad Parameter.\n"))
+			("Bad Parameter.\n"));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_PORTDOWN* Event EMPTY.\n"))
+			("SK_RLMT_PORTDOWN* Event EMPTY.\n"));
 		return;
 	}
 
@@ -2204,7 +2206,7 @@
 	if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM &&
 		!(pRPort->CheckingState & SK_RLMT_PCS_TX))) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event))
+			("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event));
 		return;
 	}
 	
@@ -2241,7 +2243,7 @@
 	}
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event))
+		("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event));
 }	/* SkRlmtEvtPortDownX */
 
 
@@ -2268,7 +2270,7 @@
 
 	pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0]))
+		("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0]));
 
 	if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
 		pRPort->Net->LinksUp--;
@@ -2287,7 +2289,7 @@
 	}
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_LINK_DOWN Event END.\n"))
+		("SK_RLMT_LINK_DOWN Event END.\n"));
 }	/* SkRlmtEvtLinkDown */
 
 
@@ -2316,13 +2318,13 @@
 	SK_MAC_ADDR		*pNewMacAddr;
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0]))
+		("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0]));
 
 	if (Para.Para32[1] != (SK_U32)-1) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad Parameter.\n"))
+			("Bad Parameter.\n"));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_PORT_ADDR Event EMPTY.\n"))
+			("SK_RLMT_PORT_ADDR Event EMPTY.\n"));
 		return;
 	}
 
@@ -2346,7 +2348,7 @@
 	}
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_PORT_ADDR Event END.\n"))
+			("SK_RLMT_PORT_ADDR Event END.\n"));
 }	/* SkRlmtEvtPortAddr */
 
 
@@ -2374,35 +2376,35 @@
 	SK_U32		PortNumber;
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0]))
+		("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0]));
 
 	if (Para.Para32[1] != (SK_U32)-1) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad Parameter.\n"))
+			("Bad Parameter.\n"));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_START Event EMPTY.\n"))
+			("SK_RLMT_START Event EMPTY.\n"));
 		return;
 	}
 
 	if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad NetNumber %d.\n", Para.Para32[0]))
+			("Bad NetNumber %d.\n", Para.Para32[0]));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_START Event EMPTY.\n"))
+			("SK_RLMT_START Event EMPTY.\n"));
 		return;
 	}
 
 	if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState != SK_RLMT_RS_INIT) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_START Event EMPTY.\n"))
+			("SK_RLMT_START Event EMPTY.\n"));
 		return;
 	}
 
 	if (pAC->Rlmt.NetsStarted >= pAC->Rlmt.NumNets) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("All nets should have been started.\n"))
+			("All nets should have been started.\n"));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_START Event EMPTY.\n"))
+			("SK_RLMT_START Event EMPTY.\n"));
 		return;
 	}
 
@@ -2436,7 +2438,7 @@
 	pAC->Rlmt.NetsStarted++;
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_START Event END.\n"))
+			("SK_RLMT_START Event END.\n"));
 }	/* SkRlmtEvtStart */
 
 
@@ -2464,35 +2466,35 @@
 	SK_U32		i;
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0]))
+		("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0]));
 
 	if (Para.Para32[1] != (SK_U32)-1) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad Parameter.\n"))
+			("Bad Parameter.\n"));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_STOP Event EMPTY.\n"))
+			("SK_RLMT_STOP Event EMPTY.\n"));
 		return;
 	}
 
 	if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad NetNumber %d.\n", Para.Para32[0]))
+			("Bad NetNumber %d.\n", Para.Para32[0]));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_STOP Event EMPTY.\n"))
+			("SK_RLMT_STOP Event EMPTY.\n"));
 		return;
 	}
 
 	if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState == SK_RLMT_RS_INIT) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_STOP Event EMPTY.\n"))
+			("SK_RLMT_STOP Event EMPTY.\n"));
 		return;
 	}
 
 	if (pAC->Rlmt.NetsStarted == 0) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("All nets are stopped.\n"))
+			("All nets are stopped.\n"));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_STOP Event EMPTY.\n"))
+			("SK_RLMT_STOP Event EMPTY.\n"));
 		return;
 	}
 
@@ -2527,7 +2529,7 @@
 	pAC->Rlmt.NetsStarted--;
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_STOP Event END.\n"))
+		("SK_RLMT_STOP Event END.\n"));
 }	/* SkRlmtEvtStop */
 
 
@@ -2557,13 +2559,13 @@
 	SK_U32			i;
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_TIM Event BEGIN.\n"))
+		("SK_RLMT_TIM Event BEGIN.\n"));
 
 	if (Para.Para32[1] != (SK_U32)-1) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad Parameter.\n"))
+			("Bad Parameter.\n"));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_TIM Event EMPTY.\n"))
+			("SK_RLMT_TIM Event EMPTY.\n"));
 		return;
 	}
 
@@ -2635,7 +2637,7 @@
 	}
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_TIM Event END.\n"))
+			("SK_RLMT_TIM Event END.\n"));
 }	/* SkRlmtEvtTim */
 
 
@@ -2663,13 +2665,13 @@
 #endif	/* DEBUG */
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_SEG_TIM Event BEGIN.\n"))
+		("SK_RLMT_SEG_TIM Event BEGIN.\n"));
 
 	if (Para.Para32[1] != (SK_U32)-1) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad Parameter.\n"))
+			("Bad Parameter.\n"));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_SEG_TIM Event EMPTY.\n"))
+			("SK_RLMT_SEG_TIM Event EMPTY.\n"));
 		return;
 	}
 
@@ -2693,7 +2695,7 @@
 					InAddr8[3], InAddr8[4], InAddr8[5],
 					pAPort->Exact[k].a[0], pAPort->Exact[k].a[1],
 					pAPort->Exact[k].a[2], pAPort->Exact[k].a[3],
-					pAPort->Exact[k].a[4], pAPort->Exact[k].a[5]))
+					pAPort->Exact[k].a[4], pAPort->Exact[k].a[5]));
 		}
 	}
 #endif	/* xDEBUG */
@@ -2701,7 +2703,7 @@
 	SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]);
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_SEG_TIM Event END.\n"))
+			("SK_RLMT_SEG_TIM Event END.\n"));
 }	/* SkRlmtEvtSegTim */
 
 
@@ -2730,18 +2732,18 @@
 
 	
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n"))
+		("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n"));
 
 	/* Should we ignore frames during port switching? */
 
 #ifdef DEBUG
 	pMb = Para.pParaPtr;
 	if (pMb == NULL) {
-		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n"))
+		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n"));
 	}
 	else if (pMb->pNext != NULL) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("More than one mbuf or pMb->pNext not set.\n"))
+			("More than one mbuf or pMb->pNext not set.\n"));
 	}
 #endif	/* DEBUG */
 
@@ -2759,7 +2761,7 @@
 	}
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_PACKET_RECEIVED Event END.\n"))
+		("SK_RLMT_PACKET_RECEIVED Event END.\n"));
 }	/* SkRlmtEvtPacketRx */
 
 
@@ -2786,21 +2788,21 @@
 	SK_RLMT_PORT	*pRPort;
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_STATS_CLEAR Event BEGIN.\n"))
+		("SK_RLMT_STATS_CLEAR Event BEGIN.\n"));
 
 	if (Para.Para32[1] != (SK_U32)-1) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad Parameter.\n"))
+			("Bad Parameter.\n"));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
+			("SK_RLMT_STATS_CLEAR Event EMPTY.\n"));
 		return;
 	}
 
 	if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad NetNumber %d.\n", Para.Para32[0]))
+			("Bad NetNumber %d.\n", Para.Para32[0]));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
+			("SK_RLMT_STATS_CLEAR Event EMPTY.\n"));
 		return;
 	}
 
@@ -2815,7 +2817,7 @@
 	}
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_STATS_CLEAR Event END.\n"))
+		("SK_RLMT_STATS_CLEAR Event END.\n"));
 }	/* SkRlmtEvtStatsClear */
 
 
@@ -2839,28 +2841,28 @@
 SK_EVPARA	Para)	/* SK_U32 NetNumber; SK_U32 -1 */
 {
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_STATS_UPDATE Event BEGIN.\n"))
+		("SK_RLMT_STATS_UPDATE Event BEGIN.\n"));
 
 	if (Para.Para32[1] != (SK_U32)-1) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad Parameter.\n"))
+			("Bad Parameter.\n"));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
+			("SK_RLMT_STATS_UPDATE Event EMPTY.\n"));
 		return;
 	}
 
 	if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad NetNumber %d.\n", Para.Para32[0]))
+			("Bad NetNumber %d.\n", Para.Para32[0]));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
+			("SK_RLMT_STATS_UPDATE Event EMPTY.\n"));
 		return;
 	}
 
 	/* Update statistics - currently always up-to-date. */
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_STATS_UPDATE Event END.\n"))
+		("SK_RLMT_STATS_UPDATE Event END.\n"));
 }	/* SkRlmtEvtStatsUpdate */
 
 
@@ -2884,13 +2886,13 @@
 SK_EVPARA	Para)	/* SK_U32 PortIndex; SK_U32 NetNumber */
 {
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0]))
+		("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0]));
 
 	if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad NetNumber %d.\n", Para.Para32[1]))
+			("Bad NetNumber %d.\n", Para.Para32[1]));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
+			("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"));
 		return;
 	}
 
@@ -2903,7 +2905,7 @@
 			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E010, SKERR_RLMT_E010_MSG);
 
 			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-				("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
+				("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"));
 			return;
 		}
 
@@ -2917,7 +2919,7 @@
 	}
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_PREFPORT_CHANGE Event END.\n"))
+		("SK_RLMT_PREFPORT_CHANGE Event END.\n"));
 }	/* SkRlmtEvtPrefportChange */
 
 
@@ -2943,37 +2945,37 @@
 	int i;
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_SET_NETS Event BEGIN.\n"))
+		("SK_RLMT_SET_NETS Event BEGIN.\n"));
 
 	if (Para.Para32[1] != (SK_U32)-1) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad Parameter.\n"))
+			("Bad Parameter.\n"));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_SET_NETS Event EMPTY.\n"))
+			("SK_RLMT_SET_NETS Event EMPTY.\n"));
 		return;
 	}
 
 	if (Para.Para32[0] == 0 || Para.Para32[0] > SK_MAX_NETS ||
 		Para.Para32[0] > (SK_U32)pAC->GIni.GIMacsFound) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad number of nets: %d.\n", Para.Para32[0]))
+			("Bad number of nets: %d.\n", Para.Para32[0]));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_SET_NETS Event EMPTY.\n"))
+			("SK_RLMT_SET_NETS Event EMPTY.\n"));
 		return;
 	}
 
 	if (Para.Para32[0] == pAC->Rlmt.NumNets) {	/* No change. */
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_SET_NETS Event EMPTY.\n"))
+			("SK_RLMT_SET_NETS Event EMPTY.\n"));
 		return;
 	}
 
 	/* Entering and leaving dual mode only allowed while nets are stopped. */
 	if (pAC->Rlmt.NetsStarted > 0) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Changing dual mode only allowed while all nets are stopped.\n"))
+			("Changing dual mode only allowed while all nets are stopped.\n"));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_SET_NETS Event EMPTY.\n"))
+			("SK_RLMT_SET_NETS Event EMPTY.\n"));
 		return;
 	}
 
@@ -3004,7 +3006,7 @@
 		SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
 
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("RLMT: Changed to one net with two ports.\n"))
+			("RLMT: Changed to one net with two ports.\n"));
 	}
 	else if (Para.Para32[0] == 2) {
 		pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[1];
@@ -3033,19 +3035,19 @@
 		SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
 
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("RLMT: Changed to two nets with one port each.\n"))
+			("RLMT: Changed to two nets with one port each.\n"));
 	}
 	else {
 		/* Not implemented for more than two nets. */
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SetNets not implemented for more than two nets.\n"))
+			("SetNets not implemented for more than two nets.\n"));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_SET_NETS Event EMPTY.\n"))
+			("SK_RLMT_SET_NETS Event EMPTY.\n"));
 		return;
 	}
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_SET_NETS Event END.\n"))
+		("SK_RLMT_SET_NETS Event END.\n"));
 }	/* SkRlmtSetNets */
 
 
@@ -3073,13 +3075,13 @@
 	SK_U32		PrevRlmtMode;
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-		("SK_RLMT_MODE_CHANGE Event BEGIN.\n"))
+		("SK_RLMT_MODE_CHANGE Event BEGIN.\n"));
 
 	if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Bad NetNumber %d.\n", Para.Para32[1]))
+			("Bad NetNumber %d.\n", Para.Para32[1]));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
+			("SK_RLMT_MODE_CHANGE Event EMPTY.\n"));
 		return;
 	}
 
@@ -3089,9 +3091,9 @@
 		Para.Para32[0] != SK_RLMT_MODE_CLS) {
 		pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = SK_RLMT_MODE_CLS;
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Forced RLMT mode to CLS on single port net.\n"))
+			("Forced RLMT mode to CLS on single port net.\n"));
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
+			("SK_RLMT_MODE_CHANGE Event EMPTY.\n"));
 		return;
 	}
 
@@ -3157,7 +3159,7 @@
 	}	/* SK_RLMT_CHECK_SEG bit changed. */
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("SK_RLMT_MODE_CHANGE Event END.\n"))
+			("SK_RLMT_MODE_CHANGE Event END.\n"));
 }	/* SkRlmtEvtModeChange */
 
 
@@ -3243,7 +3245,7 @@
 
 	default:	/* Create error log entry. */
 		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
-			("Unknown RLMT Event %d.\n", Event))
+			("Unknown RLMT Event %d.\n", Event));
 		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E003, SKERR_RLMT_E003_MSG);
 		break;
 	}	/* switch() */
diff -urN linux-2.4.29/drivers/net/sk98lin/sktimer.c linux-2.4.29-uc1/drivers/net/sk98lin/sktimer.c
--- linux-2.4.29/drivers/net/sk98lin/sktimer.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/sktimer.c	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	sktimer.c
  * Project:	Gigabit Ethernet Adapters, Event Scheduler Module
+ * Version:	$Revision: 2.2 $
+ * Date:	$Date: 2004/05/28 13:44:39 $
  * Purpose:	High level timer functions.
  *
  ******************************************************************************/
@@ -9,7 +11,7 @@
 /******************************************************************************
  *
  *	(C)Copyright 1998-2002 SysKonnect GmbH.
- *	(C)Copyright 2002-2003 Marvell.
+ *	(C)Copyright 2002-2004 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -25,7 +27,7 @@
  */
 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
 static const char SysKonnectFileId[] =
-	"@(#) $Id: sktimer.c,v 1.14 2003/09/16 13:46:51 rschmidt Exp $ (C) Marvell.";
+	"@(#) $Id: sktimer.c,v 2.2 2004/05/28 13:44:39 rschmidt Exp $ (C) Marvell.";
 #endif
 
 #include "h/skdrv1st.h"		/* Driver Specific Definitions */
@@ -82,22 +84,20 @@
 	SK_TIMER	**ppTimPrev;
 	SK_TIMER	*pTm;
 
-	/*
-	 * remove timer from queue
-	 */
+	/* remove timer from queue */
 	pTimer->TmActive = SK_FALSE;
-	
+
 	if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) {
 		SkHwtStop(pAC, Ioc);
 	}
-	
+
 	for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
 		ppTimPrev = &pTm->TmNext ) {
-		
+
 		if (pTm == pTimer) {
 			/*
 			 * Timer found in queue
-			 * - dequeue it and
+			 * - dequeue it
 			 * - correct delta of the next timer
 			 */
 			*ppTimPrev = pTm->TmNext;
@@ -118,7 +118,7 @@
 SK_AC		*pAC,		/* Adapters context */
 SK_IOC		Ioc,		/* IoContext */
 SK_TIMER	*pTimer,	/* Timer Pointer to be started */
-SK_U32		Time,		/* Time value */
+SK_U32		Time,		/* Time Value (in microsec.) */
 SK_U32		Class,		/* Event Class for this timer */
 SK_U32		Event,		/* Event Value for this timer */
 SK_EVPARA	Para)		/* Event Parameter for this timer */
@@ -127,11 +127,6 @@
 	SK_TIMER	*pTm;
 	SK_U32		Delta;
 
-	Time /= 16;		/* input is uS, clock ticks are 16uS */
-	
-	if (!Time)
-		Time = 1;
-
 	SkTimerStop(pAC, Ioc, pTimer);
 
 	pTimer->TmClass = Class;
@@ -140,31 +135,26 @@
 	pTimer->TmActive = SK_TRUE;
 
 	if (!pAC->Tim.StQueue) {
-		/* First Timer to be started */
+		/* first Timer to be started */
 		pAC->Tim.StQueue = pTimer;
 		pTimer->TmNext = 0;
 		pTimer->TmDelta = Time;
-		
+
 		SkHwtStart(pAC, Ioc, Time);
-		
+
 		return;
 	}
 
-	/*
-	 * timer correction
-	 */
+	/* timer correction */
 	timer_done(pAC, Ioc, 0);
 
-	/*
-	 * find position in queue
-	 */
+	/* find position in queue */
 	Delta = 0;
 	for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
 		ppTimPrev = &pTm->TmNext ) {
-		
+
 		if (Delta + pTm->TmDelta > Time) {
-			/* Position found */
-			/* Here the timer needs to be inserted. */
+			/* the timer needs to be inserted here */
 			break;
 		}
 		Delta += pTm->TmDelta;
@@ -176,9 +166,7 @@
 	pTimer->TmDelta = Time - Delta;
 
 	if (pTm) {
-		/* There is a next timer
-		 * -> correct its Delta value.
-		 */
+		/* there is a next timer:  correct its Delta value */
 		pTm->TmDelta -= pTimer->TmDelta;
 	}
 
@@ -207,7 +195,7 @@
 	int		Done = 0;
 
 	Delta = SkHwtRead(pAC, Ioc);
-	
+
 	ppLast = &pAC->Tim.StQueue;
 	pTm = pAC->Tim.StQueue;
 	while (pTm && !Done) {
@@ -231,7 +219,7 @@
 	 * StQueue points to the first Timer that run out.
 	 */
 
-	for ( pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) {
+	for (pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) {
 		SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent, pTComp->TmPara);
 	}
 
diff -urN linux-2.4.29/drivers/net/sk98lin/sktwsi.c linux-2.4.29-uc1/drivers/net/sk98lin/sktwsi.c
--- linux-2.4.29/drivers/net/sk98lin/sktwsi.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/sktwsi.c	2005-06-14 02:12:09.000000000 +0100
@@ -0,0 +1,1337 @@
+/******************************************************************************
+ *
+ * Name:	sktwsi.c
+ * Project:	Gigabit Ethernet Adapters, TWSI-Module
+ * Version:	$Revision: 1.2 $
+ * Date:	$Date: 2004/11/17 05:40:48 $
+ * Purpose:	Functions to access Voltage and Temperature Sensor
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *	(C)Copyright 1998-2002 SysKonnect.
+ *	(C)Copyright 2002-2004 Marvell.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2 of the License, or
+ *	(at your option) any later version.
+ *	The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/*
+ *	TWSI Protocol
+ */
+#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+static const char SysKonnectFileId[] =
+	"@(#) $Id: sktwsi.c,v 1.2 2004/11/17 05:40:48 toby Exp $ (C) Marvell.";
+#endif
+
+#include "h/skdrv1st.h"		/* Driver Specific Definitions */
+#include "h/lm80.h"
+#include "h/skdrv2nd.h"		/* Adapter Control- and Driver specific Def. */
+
+#ifdef __C2MAN__
+/*
+	TWSI protocol implementation.
+
+	General Description:
+
+	The TWSI protocol is used for the temperature sensors and for
+	the serial EEPROM which hold the configuration.
+
+	This file covers functions that allow to read write and do
+	some bulk requests a specified TWSI address.
+
+	The Genesis has 2 TWSI buses. One for the EEPROM which holds
+	the VPD Data and one for temperature and voltage sensor.
+	The following picture shows the TWSI buses, TWSI devices and
+	their control registers.
+
+	Note: The VPD functions are in skvpd.c
+.
+.	PCI Config TWSI Bus for VPD Data:
+.
+.		      +------------+
+.		      | VPD EEPROM |
+.		      +------------+
+.			     |
+.			     | <-- TWSI
+.			     |
+.		 +-----------+-----------+
+.		 |			 |
+.	+-----------------+	+-----------------+
+.	| PCI_VPD_ADR_REG |	| PCI_VPD_DAT_REG |
+.	+-----------------+	+-----------------+
+.
+.
+.	TWSI Bus for LM80 sensor:
+.
+.			+-----------------+
+.			| Temperature and |
+.			| Voltage Sensor  |
+.			| 	LM80	  |
+.			+-----------------+
+.				|
+.				|
+.			TWSI --> |
+.				|
+.			     +----+
+.	     +-------------->| OR |<--+
+.	     |		     +----+   |
+.     +------+------+		      |
+.     |		    |		      |
+. +--------+	+--------+	+----------+
+. | B2_I2C |	| B2_I2C |	|  B2_I2C  |
+. | _CTRL  |	| _DATA  |	|   _SW    |
+. +--------+	+--------+	+----------+
+.
+	The TWSI bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL
+	and B2_I2C_DATA registers.
+	For driver software it is recommended to use the TWSI control and
+	data register, because TWSI bus timing is done by the ASIC and
+	an interrupt may be received when the TWSI request is completed.
+
+	Clock Rate Timing:			MIN	MAX	generated by
+		VPD EEPROM:			50 kHz	100 kHz		HW
+		LM80 over TWSI Ctrl/Data reg.	50 kHz	100 kHz		HW
+		LM80 over B2_I2C_SW register	0	400 kHz		SW
+
+	Note:	The clock generated by the hardware is dependend on the
+		PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD
+		clock is 50 kHz.
+ */
+intro()
+{}
+#endif
+
+#ifdef SK_DIAG
+/*
+ * TWSI Fast Mode timing values used by the LM80.
+ * If new devices are added to the TWSI bus the timing values have to be checked.
+ */
+#ifndef I2C_SLOW_TIMING
+#define	T_CLK_LOW			1300L	/* clock low time in ns */
+#define	T_CLK_HIGH			 600L	/* clock high time in ns */
+#define T_DATA_IN_SETUP		 100L	/* data in Set-up Time */
+#define T_START_HOLD		 600L	/* start condition hold time */
+#define T_START_SETUP		 600L	/* start condition Set-up time */
+#define	T_STOP_SETUP		 600L	/* stop condition Set-up time */
+#define T_BUS_IDLE			1300L	/* time the bus must free after Tx */
+#define	T_CLK_2_DATA_OUT	 900L	/* max. clock low to data output valid */
+#else	/* I2C_SLOW_TIMING */
+/* TWSI Standard Mode Timing */
+#define	T_CLK_LOW			4700L	/* clock low time in ns */
+#define	T_CLK_HIGH			4000L	/* clock high time in ns */
+#define T_DATA_IN_SETUP		 250L	/* data in Set-up Time */
+#define T_START_HOLD		4000L	/* start condition hold time */
+#define T_START_SETUP		4700L	/* start condition Set-up time */
+#define	T_STOP_SETUP		4000L	/* stop condition Set-up time */
+#define T_BUS_IDLE			4700L	/* time the bus must free after Tx */
+#endif	/* !I2C_SLOW_TIMING */
+
+#define NS2BCLK(x)	(((x)*125)/10000)
+
+/*
+ * TWSI Wire Operations
+ *
+ * About I2C_CLK_LOW():
+ *
+ * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting
+ * clock to low, to prevent the ASIC and the TWSI data client from driving the
+ * serial data line simultaneously (ASIC: last bit of a byte = '1', TWSI client
+ * send an 'ACK'). See also Concentrator Bugreport No. 10192.
+ */
+#define I2C_DATA_HIGH(IoC)	SK_I2C_SET_BIT(IoC, I2C_DATA)
+#define	I2C_DATA_LOW(IoC)	SK_I2C_CLR_BIT(IoC, I2C_DATA)
+#define	I2C_DATA_OUT(IoC)	SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
+#define	I2C_DATA_IN(IoC)	SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA)
+#define	I2C_CLK_HIGH(IoC)	SK_I2C_SET_BIT(IoC, I2C_CLK)
+#define	I2C_CLK_LOW(IoC)	SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR)
+#define	I2C_START_COND(IoC)	SK_I2C_CLR_BIT(IoC, I2C_CLK)
+
+#define NS2CLKT(x)	((x*125L)/10000)
+
+/*--------------- TWSI Interface Register Functions --------------- */
+
+/*
+ * sending one bit
+ */
+void SkI2cSndBit(
+SK_IOC	IoC,	/* I/O Context */
+SK_U8	Bit)	/* Bit to send */
+{
+	I2C_DATA_OUT(IoC);
+	if (Bit) {
+		I2C_DATA_HIGH(IoC);
+	}
+	else {
+		I2C_DATA_LOW(IoC);
+	}
+	SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
+	I2C_CLK_HIGH(IoC);
+	SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
+	I2C_CLK_LOW(IoC);
+}	/* SkI2cSndBit*/
+
+
+/*
+ * Signal a start to the TWSI Bus.
+ *
+ * A start is signaled when data goes to low in a high clock cycle.
+ *
+ * Ends with Clock Low.
+ *
+ * Status: not tested
+ */
+void SkI2cStart(
+SK_IOC	IoC)	/* I/O Context */
+{
+	/* Init data and Clock to output lines */
+	/* Set Data high */
+	I2C_DATA_OUT(IoC);
+	I2C_DATA_HIGH(IoC);
+	/* Set Clock high */
+	I2C_CLK_HIGH(IoC);
+
+	SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
+
+	/* Set Data Low */
+	I2C_DATA_LOW(IoC);
+
+	SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
+
+	/* Clock low without Data to Input */
+	I2C_START_COND(IoC);
+
+	SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
+}	/* SkI2cStart */
+
+
+void SkI2cStop(
+SK_IOC	IoC)	/* I/O Context */
+{
+	/* Init data and Clock to output lines */
+	/* Set Data low */
+	I2C_DATA_OUT(IoC);
+	I2C_DATA_LOW(IoC);
+
+	SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
+
+	/* Set Clock high */
+	I2C_CLK_HIGH(IoC);
+
+	SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
+
+	/*
+	 * Set Data High:	Do it by setting the Data Line to Input.
+	 *			Because of a pull up resistor the Data Line
+	 *			floods to high.
+	 */
+	I2C_DATA_IN(IoC);
+
+	/*
+	 *	When TWSI activity is stopped
+	 *	 o	DATA should be set to input and
+	 *	 o	CLOCK should be set to high!
+	 */
+	SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
+}	/* SkI2cStop */
+
+
+/*
+ * Receive just one bit via the TWSI bus.
+ *
+ * Note:	Clock must be set to LOW before calling this function.
+ *
+ * Returns The received bit.
+ */
+int SkI2cRcvBit(
+SK_IOC	IoC)	/* I/O Context */
+{
+	int	Bit;
+	SK_U8	I2cSwCtrl;
+
+	/* Init data as input line */
+	I2C_DATA_IN(IoC);
+
+	SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
+
+	I2C_CLK_HIGH(IoC);
+
+	SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
+
+	SK_I2C_GET_SW(IoC, &I2cSwCtrl);
+
+	Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
+
+	I2C_CLK_LOW(IoC);
+	SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
+
+	return(Bit);
+}	/* SkI2cRcvBit */
+
+
+/*
+ * Receive an ACK.
+ *
+ * returns	0 If acknowledged
+ *		1 in case of an error
+ */
+int SkI2cRcvAck(
+SK_IOC	IoC)	/* I/O Context */
+{
+	/*
+	 * Received bit must be zero.
+	 */
+	return(SkI2cRcvBit(IoC) != 0);
+}	/* SkI2cRcvAck */
+
+
+/*
+ * Send an NACK.
+ */
+void SkI2cSndNAck(
+SK_IOC	IoC)	/* I/O Context */
+{
+	/*
+	 * Received bit must be zero.
+	 */
+	SkI2cSndBit(IoC, 1);
+}	/* SkI2cSndNAck */
+
+
+/*
+ * Send an ACK.
+ */
+void SkI2cSndAck(
+SK_IOC IoC)	/* I/O Context */
+{
+	/*
+	 * Received bit must be zero.
+	 */
+	SkI2cSndBit(IoC, 0);
+}	/* SkI2cSndAck */
+
+
+/*
+ * Send one byte to the TWSI device and wait for ACK.
+ *
+ * Return acknowleged status.
+ */
+int SkI2cSndByte(
+SK_IOC	IoC,	/* I/O Context */
+int		Byte)	/* byte to send */
+{
+	int	i;
+
+	for (i = 0; i < 8; i++) {
+		if (Byte & (1<<(7-i))) {
+			SkI2cSndBit(IoC, 1);
+		}
+		else {
+			SkI2cSndBit(IoC, 0);
+		}
+	}
+
+	return(SkI2cRcvAck(IoC));
+}	/* SkI2cSndByte */
+
+
+/*
+ * Receive one byte and ack it.
+ *
+ * Return byte.
+ */
+int SkI2cRcvByte(
+SK_IOC	IoC,	/* I/O Context */
+int		Last)	/* Last Byte Flag */
+{
+	int	i;
+	int	Byte = 0;
+
+	for (i = 0; i < 8; i++) {
+		Byte <<= 1;
+		Byte |= SkI2cRcvBit(IoC);
+	}
+
+	if (Last) {
+		SkI2cSndNAck(IoC);
+	}
+	else {
+		SkI2cSndAck(IoC);
+	}
+
+	return(Byte);
+}	/* SkI2cRcvByte */
+
+
+/*
+ * Start dialog and send device address
+ *
+ * Return 0 if acknowleged, 1 in case of an error
+ */
+int	SkI2cSndDev(
+SK_IOC	IoC,	/* I/O Context */
+int		Addr,	/* Device Address */
+int		Rw)		/* Read / Write Flag */
+{
+	SkI2cStart(IoC);
+	Rw = ~Rw;
+	Rw &= I2C_WRITE;
+	return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
+}	/* SkI2cSndDev */
+
+#endif /* SK_DIAG */
+
+/*----------------- TWSI CTRL Register Functions ----------*/
+
+/*
+ * waits for a completion of an TWSI transfer
+ *
+ * returns	0:	success, transfer completes
+ *			1:	error,	 transfer does not complete, TWSI transfer
+ *						 killed, wait loop terminated.
+ */
+int	SkI2cWait(
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
+int		Event)	/* complete event to wait for (I2C_READ or I2C_WRITE) */
+{
+	SK_U64	StartTime;
+	SK_U64	CurrentTime;
+	SK_U32	I2cCtrl;
+
+	StartTime = SkOsGetTime(pAC);
+
+	do {
+		CurrentTime = SkOsGetTime(pAC);
+
+		if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
+
+			SK_I2C_STOP(IoC);
+#ifndef SK_DIAG
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
+#endif /* !SK_DIAG */
+			return(1);
+		}
+
+		SK_I2C_GET_CTL(IoC, &I2cCtrl);
+
+#ifdef xYUKON_DBG
+		printf("StartTime=%lu, CurrentTime=%lu\n",
+			StartTime, CurrentTime);
+		if (kbhit()) {
+			return(1);
+		}
+#endif /* YUKON_DBG */
+
+	} while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
+
+	return(0);
+}	/* SkI2cWait */
+
+
+/*
+ * waits for a completion of an TWSI transfer
+ *
+ * Returns
+ *	Nothing
+ */
+void SkI2cWaitIrq(
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC)	/* I/O Context */
+{
+	SK_SENSOR	*pSen;
+	SK_U64		StartTime;
+	SK_U32		IrqSrc;
+	SK_U32		IsTwsiReadyBit;
+
+	IsTwsiReadyBit = CHIP_ID_YUKON_2(pAC) ? Y2_IS_TWSI_RDY : IS_I2C_READY;
+
+	pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
+
+	if (pSen->SenState == SK_SEN_IDLE) {
+		return;
+	}
+
+	StartTime = SkOsGetTime(pAC);
+
+	do {
+		if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
+
+			SK_I2C_STOP(IoC);
+#ifndef SK_DIAG
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
+#endif /* !SK_DIAG */
+			return;
+		}
+
+		SK_IN32(IoC, B0_ISRC, &IrqSrc);
+
+	} while ((IrqSrc & IsTwsiReadyBit) == 0);
+
+	pSen->SenState = SK_SEN_IDLE;
+	return;
+}	/* SkI2cWaitIrq */
+
+/*
+ * writes a single byte or 4 bytes into the TWSI device
+ *
+ * returns	0:	success
+ *			1:	error
+ */
+int SkI2cWrite(
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
+SK_U32	I2cData,	/* TWSI Data to write */
+int		I2cDev,		/* TWSI Device Address */
+int		I2cDevSize,	/* TWSI Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
+int		I2cReg,		/* TWSI Device Register Address */
+int		I2cBurst)	/* TWSI Burst Flag */
+{
+	SK_OUT32(IoC, B2_I2C_DATA, I2cData);
+
+	SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst);
+
+	return(SkI2cWait(pAC, IoC, I2C_WRITE));
+}	/* SkI2cWrite*/
+
+
+#ifdef	SK_DIAG
+/*
+ * reads a single byte or 4 bytes from the TWSI device
+ *
+ * returns	the word read
+ */
+SK_U32 SkI2cRead(
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
+int		I2cDev,		/* TWSI Device Address */
+int		I2cDevSize,	/* TWSI Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
+int		I2cReg,		/* TWSI Device Register Address */
+int		I2cBurst)	/* TWSI Burst Flag */
+{
+	SK_U32	Data;
+
+	SK_OUT32(IoC, B2_I2C_DATA, 0);
+	SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst);
+
+	if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
+		w_print("%s\n", SKERR_I2C_E002MSG);
+	}
+
+	SK_IN32(IoC, B2_I2C_DATA, &Data);
+
+	return(Data);
+}	/* SkI2cRead */
+#endif /* SK_DIAG */
+
+
+/*
+ * read a sensor's value
+ *
+ * This function reads a sensor's value from the TWSI sensor chip. The sensor
+ * is defined by its index into the sensors database in the struct pAC points
+ * to.
+ * Returns
+ *		1 if the read is completed
+ *		0 if the read must be continued (TWSI Bus still allocated)
+ */
+int	SkI2cReadSensor(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_SENSOR	*pSen)	/* Sensor to be read */
+{
+	if (pSen->SenRead != NULL) {
+		return((*pSen->SenRead)(pAC, IoC, pSen));
+	}
+
+	return(0); /* no success */
+}	/* SkI2cReadSensor */
+
+/*
+ * Do the Init state 0 initialization
+ */
+static int SkI2cInit0(
+SK_AC	*pAC)	/* Adapter Context */
+{
+	int	i;
+
+	/* Begin with first sensor */
+	pAC->I2c.CurrSens = 0;
+
+	/* Begin with timeout control for state machine */
+	pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
+
+	/* Set sensor number to zero */
+	pAC->I2c.MaxSens = 0;
+
+#ifndef SK_DIAG
+	/* Initialize Number of Dummy Reads */
+	pAC->I2c.DummyReads = SK_MAX_SENSORS;
+#endif /* !SK_DIAG */
+
+	for (i = 0; i < SK_MAX_SENSORS; i++) {
+		pAC->I2c.SenTable[i].SenDesc = "unknown";
+		pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN;
+		pAC->I2c.SenTable[i].SenThreErrHigh = 0;
+		pAC->I2c.SenTable[i].SenThreErrLow = 0;
+		pAC->I2c.SenTable[i].SenThreWarnHigh = 0;
+		pAC->I2c.SenTable[i].SenThreWarnLow = 0;
+		pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
+		pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE;
+		pAC->I2c.SenTable[i].SenValue = 0;
+		pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT;
+		pAC->I2c.SenTable[i].SenErrCts = 0;
+		pAC->I2c.SenTable[i].SenBegErrTS = 0;
+		pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
+		pAC->I2c.SenTable[i].SenRead = NULL;
+		pAC->I2c.SenTable[i].SenDev = 0;
+	}
+
+	/* Now we are "INIT data"ed */
+	pAC->I2c.InitLevel = SK_INIT_DATA;
+	return(0);
+}	/* SkI2cInit0*/
+
+
+/*
+ * Do the init state 1 initialization
+ *
+ * initialize the following register of the LM80:
+ * Configuration register:
+ * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
+ *
+ * Interrupt Mask Register 1:
+ * - all interrupts are Disabled (0xff)
+ *
+ * Interrupt Mask Register 2:
+ * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
+ *
+ * Fan Divisor/RST_OUT register:
+ * - Divisors set to 1 (bits 00), all others 0s.
+ *
+ * OS# Configuration/Temperature resolution Register:
+ * - all 0s
+ *
+ */
+static int SkI2cInit1(
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC)	/* I/O Context */
+{
+	int i;
+	SK_U8 I2cSwCtrl;
+	SK_GEPORT *pPrt;	/* GIni Port struct pointer */
+
+	if (pAC->I2c.InitLevel != SK_INIT_DATA) {
+		/* Re-init not needed in TWSI module */
+		return(0);
+	}
+
+	if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC ||
+		pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
+		/* No sensors on Yukon-EC and Yukon-FE */
+		return(0);
+	}
+
+	/* Set the Direction of TWSI-Data Pin to IN */
+	SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA);
+	/* Check for 32-Bit Yukon with Low at TWSI-Data Pin */
+	SK_I2C_GET_SW(IoC, &I2cSwCtrl);
+
+	if ((I2cSwCtrl & I2C_DATA) == 0) {
+		/* this is a 32-Bit board */
+		pAC->GIni.GIYukon32Bit = SK_TRUE;
+		return(0);
+	}
+
+	/* Check for 64 Bit Yukon without sensors */
+	if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) {
+		return(0);
+	}
+
+	(void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0);
+
+	(void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0);
+
+	(void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0);
+
+	(void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
+
+	(void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV,
+		LM80_CFG, 0);
+
+	/*
+	 * MaxSens has to be updated here, because PhyType is not
+	 * set when performing Init Level 0
+	 */
+	pAC->I2c.MaxSens = 5;
+
+	pPrt = &pAC->GIni.GP[0];
+
+	if (pAC->GIni.GIGenesis) {
+		if (pPrt->PhyType == SK_PHY_BCOM) {
+			if (pAC->GIni.GIMacsFound == 1) {
+				pAC->I2c.MaxSens += 1;
+			}
+			else {
+				pAC->I2c.MaxSens += 3;
+			}
+		}
+	}
+	else {
+		pAC->I2c.MaxSens += 3;
+	}
+
+	for (i = 0; i < pAC->I2c.MaxSens; i++) {
+		switch (i) {
+		case 0:
+			pAC->I2c.SenTable[i].SenDesc = "Temperature";
+			pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP;
+			pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR;
+			pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN;
+			pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN;
+			pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR;
+			pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN;
+			break;
+		case 1:
+			pAC->I2c.SenTable[i].SenDesc = "Voltage PCI";
+			pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+			pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR;
+			pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN;
+			if (pAC->GIni.GIPciBus != SK_PEX_BUS) {
+				pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN;
+				pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR;
+			}
+			else {
+				pAC->I2c.SenTable[i].SenThreWarnLow = 0;
+				pAC->I2c.SenTable[i].SenThreErrLow = 0;
+			}
+			pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN;
+			break;
+		case 2:
+			pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO";
+			pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+			pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR;
+			pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN;
+			if (pAC->GIni.GIPciBus != SK_PEX_BUS) {
+				pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN;
+				pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR;
+			}
+			else {
+				pAC->I2c.SenTable[i].SenThreWarnLow = 0;
+				pAC->I2c.SenTable[i].SenThreErrLow = 0;
+			}
+			pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN;
+			pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO;
+			break;
+		case 3:
+			pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC";
+			pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+			pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR;
+			pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN;
+			pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN;
+			pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR;
+			pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN;
+			break;
+		case 4:
+			if (pAC->GIni.GIGenesis) {
+				if (pPrt->PhyType == SK_PHY_BCOM) {
+					pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL";
+					pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
+					pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
+					pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
+					pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
+				}
+				else {
+					pAC->I2c.SenTable[i].SenDesc = "Voltage PMA";
+					pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
+					pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
+					pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
+					pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
+				}
+			}
+			else {
+				pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX";
+				pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR;
+				pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN;
+				if (pAC->GIni.GIVauxAvail) {
+					pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
+					pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
+				}
+				else {
+					pAC->I2c.SenTable[i].SenThreErrLow = 0;
+					pAC->I2c.SenTable[i].SenThreWarnLow = 0;
+				}
+			}
+			pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+			pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN;
+			break;
+		case 5:
+			if (CHIP_ID_YUKON_2(pAC)) {
+				pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V3";
+				pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V2_HIGH_ERR;
+				pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V2_HIGH_WARN;
+				pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V2_LOW_WARN;
+				pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V2_LOW_ERR;
+			}
+			else {
+				if (pAC->GIni.GIGenesis) {
+					pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
+					pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
+					pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
+					pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
+					pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
+				}
+				else {
+					pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V5";
+					pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
+					pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
+					pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
+					pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
+				}
+			}
+			pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+			pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN;
+			break;
+		case 6:
+			if (CHIP_ID_YUKON_2(pAC)) {
+				pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 1V5";
+				pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
+				pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
+				if (pAC->GIni.GIPciBus == SK_PEX_BUS) {
+					pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
+					pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
+				}
+				else {
+					pAC->I2c.SenTable[i].SenThreWarnLow = 0;
+					pAC->I2c.SenTable[i].SenThreErrLow = 0;
+				}
+			}
+			else {
+				if (pAC->GIni.GIGenesis) {
+					pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL";
+				}
+				else {
+					pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
+				}
+				pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
+				pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
+				pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
+				pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
+			}
+			pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+			pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN;
+			break;
+		case 7:
+			if (pAC->GIni.GIGenesis) {
+				pAC->I2c.SenTable[i].SenDesc = "Speed Fan";
+				pAC->I2c.SenTable[i].SenType = SK_SEN_FAN;
+				pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR;
+				pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN;
+				pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN;
+				pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR;
+				pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
+			}
+			else {
+				pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
+				pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+				pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
+				pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
+				pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
+				pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
+				pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN;
+			}
+			break;
+		default:
+			SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
+				SKERR_I2C_E001, SKERR_I2C_E001MSG);
+			break;
+		}
+
+		pAC->I2c.SenTable[i].SenValue = 0;
+		pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
+		pAC->I2c.SenTable[i].SenErrCts = 0;
+		pAC->I2c.SenTable[i].SenBegErrTS = 0;
+		pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
+		pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor;
+		pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
+	}
+
+#ifndef SK_DIAG
+	pAC->I2c.DummyReads = pAC->I2c.MaxSens;
+#endif /* !SK_DIAG */
+
+	/* Clear TWSI IRQ */
+	SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
+
+	/* Now we are I/O initialized */
+	pAC->I2c.InitLevel = SK_INIT_IO;
+	return(0);
+}	/* SkI2cInit1 */
+
+
+/*
+ * Init level 2: Start first sensor read.
+ */
+static int SkI2cInit2(
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC)	/* I/O Context */
+{
+	int		ReadComplete;
+	SK_SENSOR	*pSen;
+
+	if (pAC->I2c.InitLevel != SK_INIT_IO) {
+		/* ReInit not needed in TWSI module */
+		/* Init0 and Init2 not permitted */
+		return(0);
+	}
+
+	pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
+	ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
+
+	if (ReadComplete) {
+		SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
+	}
+
+	/* Now we are correctly initialized */
+	pAC->I2c.InitLevel = SK_INIT_RUN;
+
+	return(0);
+}	/* SkI2cInit2*/
+
+
+/*
+ * Initialize TWSI devices
+ *
+ * Get the first voltage value and discard it.
+ * Go into temperature read mode. A default pointer is not set.
+ *
+ * The things to be done depend on the init level in the parameter list:
+ * Level 0:
+ *	Initialize only the data structures. Do NOT access hardware.
+ * Level 1:
+ *	Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
+ * Level 2:
+ *	Everything is possible. Interrupts may be used from now on.
+ *
+ * return:
+ *	0 = success
+ *	other = error.
+ */
+int	SkI2cInit(
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context needed in levels 1 and 2 */
+int		Level)	/* Init Level */
+{
+
+	switch (Level) {
+	case SK_INIT_DATA:
+		return(SkI2cInit0(pAC));
+	case SK_INIT_IO:
+		return(SkI2cInit1(pAC, IoC));
+	case SK_INIT_RUN:
+		return(SkI2cInit2(pAC, IoC));
+	default:
+		break;
+	}
+
+	return(0);
+}	/* SkI2cInit */
+
+
+#ifndef SK_DIAG
+/*
+ * Interrupt service function for the TWSI Interface
+ *
+ * Clears the Interrupt source
+ *
+ * Reads the register and check it for sending a trap.
+ *
+ * Starts the timer if necessary.
+ */
+void SkI2cIsr(
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC)	/* I/O Context */
+{
+	SK_EVPARA	Para;
+
+	/* Clear TWSI IRQ */
+	SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
+
+	Para.Para64 = 0;
+	SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
+}	/* SkI2cIsr */
+
+
+/*
+ * Check this sensors Value against the threshold and send events.
+ */
+static void SkI2cCheckSensor(
+SK_AC		*pAC,	/* Adapter Context */
+SK_SENSOR	*pSen)
+{
+	SK_EVPARA	ParaLocal;
+	SK_BOOL		TooHigh;	/* Is sensor too high? */
+	SK_BOOL		TooLow;		/* Is sensor too low? */
+	SK_U64		CurrTime;	/* Current Time */
+	SK_BOOL		DoTrapSend;	/* We need to send a trap */
+	SK_BOOL		DoErrLog;	/* We need to log the error */
+	SK_BOOL		IsError;	/* We need to log the error */
+
+	/* Check Dummy Reads first */
+	if (pAC->I2c.DummyReads > 0) {
+		pAC->I2c.DummyReads--;
+		return;
+	}
+
+	/* Get the current time */
+	CurrTime = SkOsGetTime(pAC);
+
+	/* Set para to the most useful setting: The current sensor. */
+	ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
+
+	/* Check the Value against the thresholds. First: Error Thresholds */
+	TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
+	TooLow = (pSen->SenValue < pSen->SenThreErrLow);
+
+	IsError = SK_FALSE;
+	if (TooHigh || TooLow) {
+		/* Error condition is satisfied */
+		DoTrapSend = SK_TRUE;
+		DoErrLog = SK_TRUE;
+
+		/* Now error condition is satisfied */
+		IsError = SK_TRUE;
+
+		if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
+			/* This state is the former one */
+
+			/* So check first whether we have to send a trap */
+			if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD > CurrTime) {
+				/*
+				 * Do NOT send the Trap. The hold back time
+				 * has to run out first.
+				 */
+				DoTrapSend = SK_FALSE;
+			}
+
+			/* Check now whether we have to log an Error */
+			if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD > CurrTime) {
+				/*
+				 * Do NOT log the error. The hold back time
+				 * has to run out first.
+				 */
+				DoErrLog = SK_FALSE;
+			}
+		}
+		else {
+			/* We came from a different state -> Set Begin Time Stamp */
+			pSen->SenBegErrTS = CurrTime;
+			pSen->SenErrFlag = SK_SEN_ERR_ERR;
+		}
+
+		if (DoTrapSend) {
+			/* Set current Time */
+			pSen->SenLastErrTrapTS = CurrTime;
+			pSen->SenErrCts++;
+
+			/* Queue PNMI Event */
+			SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
+				SK_PNMI_EVT_SEN_ERR_UPP : SK_PNMI_EVT_SEN_ERR_LOW),
+				ParaLocal);
+		}
+
+		if (DoErrLog) {
+			/* Set current Time */
+			pSen->SenLastErrLogTS = CurrTime;
+
+			if (pSen->SenType == SK_SEN_TEMP) {
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG);
+			}
+			else if (pSen->SenType == SK_SEN_VOLT) {
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG);
+			}
+			else {
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG);
+			}
+		}
+	}
+
+	/* Check the Value against the thresholds */
+	/* 2nd: Warning thresholds */
+	TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
+	TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
+
+	if (!IsError && (TooHigh || TooLow)) {
+		/* Error condition is satisfied */
+		DoTrapSend = SK_TRUE;
+		DoErrLog = SK_TRUE;
+
+		if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
+			/* This state is the former one */
+
+			/* So check first whether we have to send a trap */
+			if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) {
+				/*
+				 * Do NOT send the Trap. The hold back time
+				 * has to run out first.
+				 */
+				DoTrapSend = SK_FALSE;
+			}
+
+			/* Check now whether we have to log an Error */
+			if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) {
+				/*
+				 * Do NOT log the error. The hold back time
+				 * has to run out first.
+				 */
+				DoErrLog = SK_FALSE;
+			}
+		}
+		else {
+			/* We came from a different state -> Set Begin Time Stamp */
+			pSen->SenBegWarnTS = CurrTime;
+			pSen->SenErrFlag = SK_SEN_ERR_WARN;
+		}
+
+		if (DoTrapSend) {
+			/* Set current Time */
+			pSen->SenLastWarnTrapTS = CurrTime;
+			pSen->SenWarnCts++;
+
+			/* Queue PNMI Event */
+			SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
+				SK_PNMI_EVT_SEN_WAR_UPP : SK_PNMI_EVT_SEN_WAR_LOW),
+				ParaLocal);
+		}
+
+		if (DoErrLog) {
+			/* Set current Time */
+			pSen->SenLastWarnLogTS = CurrTime;
+
+			if (pSen->SenType == SK_SEN_TEMP) {
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG);
+			}
+			else if (pSen->SenType == SK_SEN_VOLT) {
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG);
+			}
+			else {
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG);
+			}
+		}
+	}
+
+	/* Check for NO error at all */
+	if (!IsError && !TooHigh && !TooLow) {
+		/* Set o.k. Status if no error and no warning condition */
+		pSen->SenErrFlag = SK_SEN_ERR_OK;
+	}
+
+	/* End of check against the thresholds */
+
+	/* Bug fix AF: 16.Aug.2001: Correct the init base
+	 * of LM80 sensor.
+	 */
+	if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
+
+		pSen->SenInit = SK_SEN_DYN_INIT_NONE;
+
+		if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) {
+			/* 5V PCI-IO Voltage */
+			pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN;
+			pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR;
+		}
+		else {
+			/* 3.3V PCI-IO Voltage */
+			pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN;
+			pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR;
+		}
+	}
+	
+#ifdef TEST_ONLY
+	/* Dynamic thresholds also for VAUX of LM80 sensor */
+	if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
+
+		pSen->SenInit = SK_SEN_DYN_INIT_NONE;
+
+		/* 3.3V VAUX Voltage */
+		if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) {
+			pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
+			pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
+		}
+		/* 0V VAUX Voltage */
+		else {
+			pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
+			pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
+		}
+	}
+
+	/*
+	 * Check initialization state:
+	 * The VIO Thresholds need adaption
+	 */
+	if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
+		 pSen->SenValue > SK_SEN_WARNLOW2C &&
+		 pSen->SenValue < SK_SEN_WARNHIGH2) {
+
+		pSen->SenThreErrLow = SK_SEN_ERRLOW2C;
+		pSen->SenThreWarnLow = SK_SEN_WARNLOW2C;
+		pSen->SenInit = SK_TRUE;
+	}
+
+	if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
+		 pSen->SenValue > SK_SEN_WARNLOW2 &&
+		 pSen->SenValue < SK_SEN_WARNHIGH2C) {
+
+		pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C;
+		pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C;
+		pSen->SenInit = SK_TRUE;
+	}
+#endif
+
+	if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
+		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
+	}
+}	/* SkI2cCheckSensor */
+
+
+/*
+ * The only Event to be served is the timeout event
+ *
+ */
+int	SkI2cEvent(
+SK_AC		*pAC,	/* Adapter Context */
+SK_IOC		IoC,	/* I/O Context */
+SK_U32		Event,	/* Module specific Event */
+SK_EVPARA	Para)	/* Event specific Parameter */
+{
+	int			ReadComplete;
+	SK_SENSOR	*pSen;
+	SK_U32		Time;
+	SK_EVPARA	ParaLocal;
+	int			i;
+
+	/* New case: no sensors */
+	if (pAC->I2c.MaxSens == 0) {
+		return(0);
+	}
+
+	switch (Event) {
+	case SK_I2CEV_IRQ:
+		pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
+		ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
+
+		if (ReadComplete) {
+			/* Check sensor against defined thresholds */
+			SkI2cCheckSensor(pAC, pSen);
+
+			/* Increment Current sensor and set appropriate Timeout */
+			pAC->I2c.CurrSens++;
+			if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) {
+				pAC->I2c.CurrSens = 0;
+				Time = SK_I2C_TIM_LONG;
+			}
+			else {
+				Time = SK_I2C_TIM_SHORT;
+			}
+
+			/* Start Timer */
+			ParaLocal.Para64 = (SK_U64)0;
+
+			pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
+
+			SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
+				SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
+		}
+		else {
+			/* Start Timer */
+			ParaLocal.Para64 = (SK_U64)0;
+
+			pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
+
+			SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
+				SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
+		}
+		break;
+	case SK_I2CEV_TIM:
+		if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
+
+			ParaLocal.Para64 = (SK_U64)0;
+			SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
+
+			pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
+			ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
+
+			if (ReadComplete) {
+				/* Check sensor against defined thresholds */
+				SkI2cCheckSensor(pAC, pSen);
+
+				/* Increment Current sensor and set appropriate Timeout */
+				pAC->I2c.CurrSens++;
+				if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
+					pAC->I2c.CurrSens = 0;
+					Time = SK_I2C_TIM_LONG;
+				}
+				else {
+					Time = SK_I2C_TIM_SHORT;
+				}
+
+				/* Start Timer */
+				ParaLocal.Para64 = (SK_U64)0;
+
+				pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
+
+				SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
+					SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
+			}
+		}
+		else {
+			pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
+			pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
+			SK_I2C_STOP(IoC);
+
+			/* Increment Current sensor and set appropriate Timeout */
+			pAC->I2c.CurrSens++;
+			if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
+				pAC->I2c.CurrSens = 0;
+				Time = SK_I2C_TIM_LONG;
+			}
+			else {
+				Time = SK_I2C_TIM_SHORT;
+			}
+
+			/* Start Timer */
+			ParaLocal.Para64 = (SK_U64)0;
+
+			pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
+
+			SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
+				SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
+		}
+		break;
+	case SK_I2CEV_CLEAR:
+		for (i = 0; i < SK_MAX_SENSORS; i++) {
+			pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
+			pAC->I2c.SenTable[i].SenErrCts = 0;
+			pAC->I2c.SenTable[i].SenWarnCts = 0;
+			pAC->I2c.SenTable[i].SenBegErrTS = 0;
+			pAC->I2c.SenTable[i].SenBegWarnTS = 0;
+			pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0;
+			pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0;
+			pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0;
+			pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0;
+		}
+		break;
+	default:
+		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
+	}
+
+	return(0);
+}	/* SkI2cEvent*/
+
+#endif /* !SK_DIAG */
+
diff -urN linux-2.4.29/drivers/net/sk98lin/skvpd.c linux-2.4.29-uc1/drivers/net/sk98lin/skvpd.c
--- linux-2.4.29/drivers/net/sk98lin/skvpd.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/skvpd.c	2005-06-14 02:12:09.000000000 +0100
@@ -1,20 +1,22 @@
 /******************************************************************************
  *
  * Name:	skvpd.c
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Purpose:	Shared software to read and write VPD data
+ * Project:	Gigabit Ethernet Adapters, VPD-Module
+ * Version:	$Revision: 2.4 $
+ * Date:	$Date: 2004/08/11 14:24:49 $
+ * Purpose:	Shared software to read and write VPD
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2003 SysKonnect GmbH.
+ *	(C)Copyright 1998-2002 SysKonnect.
+ *	(C)Copyright 2002-2004 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
  *	the Free Software Foundation; either version 2 of the License, or
  *	(at your option) any later version.
- *
  *	The information in this file is provided "AS IS" without warranty.
  *
  ******************************************************************************/
@@ -23,7 +25,7 @@
 	Please refer skvpd.txt for infomation how to include this module
  */
 static const char SysKonnectFileId[] =
-	"@(#)$Id: skvpd.c,v 1.37 2003/01/13 10:42:45 rschmidt Exp $ (C) SK";
+	"@(#) $Id: skvpd.c,v 2.4 2004/08/11 14:24:49 rschmidt Exp $ (C) Marvell.";
 
 #include "h/skdrv1st.h"
 #include "h/sktypes.h"
@@ -57,7 +59,7 @@
 	SK_U64	start_time;
 	SK_U16	state;
 
-	SK_DBG_MSG(pAC,SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
 		("VPD wait for %s\n", event?"Write":"Read"));
 	start_time = SkOsGetTime(pAC);
 	do {
@@ -79,12 +81,12 @@
 				("ERROR:VPD wait timeout\n"));
 			return(1);
 		}
-		
+
 		VPD_IN16(pAC, IoC, PCI_VPD_ADR_REG, &state);
-		
+
 		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
 			("state = %x, event %x\n",state,event));
-	} while((int)(state & PCI_VPD_FLAG) == event);
+	} while ((int)(state & PCI_VPD_FLAG) == event);
 
 	return(0);
 }
@@ -122,7 +124,7 @@
 	Rtv = 0;
 
 	VPD_IN32(pAC, IoC, PCI_VPD_DAT_REG, &Rtv);
-	
+
 	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
 		("VPD read dword data = 0x%x\n",Rtv));
 	return(Rtv);
@@ -267,9 +269,9 @@
 			}
 
 			for (j = 0; j <= (int)(i%sizeof(SK_U32)); j++, pComp++) {
-				
+
 				VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + j, &Data);
-				
+
 				if (Data != *pComp) {
 					/* Verify Error */
 					SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
@@ -348,14 +350,14 @@
 		return(0);
 
 	vpd_rom_size = pAC->vpd.rom_size;
-	
+
 	if (addr > vpd_rom_size - 4) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
 			("Address error: 0x%x, exp. < 0x%x\n",
 			addr, vpd_rom_size - 4));
 		return(0);
 	}
-	
+
 	if (addr + len > vpd_rom_size) {
 		len = vpd_rom_size - addr;
 		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
@@ -372,7 +374,7 @@
 	return(Rtv);
 }
 
-#ifdef SKDIAG
+#if defined (SKDIAG) || defined (SK_ASF)
 
 /*
  *	Read 'len' bytes of VPD data, starting at 'addr'.
@@ -405,16 +407,24 @@
 }
 #endif	/* SKDIAG */
 
-/*
- * (re)initialize the VPD buffer
+/******************************************************************************
  *
- * Reads the VPD data from the EEPROM into the VPD buffer.
- * Get the remaining read only and read / write space.
+ *	VpdInit() - (re)initialize the VPD buffer
  *
- * return	0:	success
- *		1:	fatal VPD error
+ * Description:
+ *	Reads the VPD data from the EEPROM into the VPD buffer.
+ *	Get the remaining read only and read / write space.
+ *
+ * Note:
+ *	This is a local function and should be used locally only.
+ *	However, the ASF module needs to use this function also.
+ *	Therfore it has been published.
+ *
+ * Returns:
+ *	0:	success
+ *	1:	fatal VPD error
  */
-static int VpdInit(
+int VpdInit(
 SK_AC	*pAC,	/* Adapters context */
 SK_IOC	IoC)	/* IO Context */
 {
@@ -426,13 +436,13 @@
 	SK_U32	our_reg2;
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit .. "));
-	
+
 	VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &dev_id);
-	
+
 	VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2);
-	
+
 	pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14);
-	
+
 	/*
 	 * this function might get used before the hardware is initialized
 	 * therefore we cannot always trust in GIChipId
@@ -463,18 +473,25 @@
 			("Block Read Error\n"));
 		return(1);
 	}
-	
+
 	pAC->vpd.vpd_size = vpd_size;
 
+	/* Asus K8V Se Deluxe bugfix. Correct VPD content */
+	i = 62;
+	if(!strncmp(pAC->vpd.vpd_buf + i, " 8<E", 4)) {
+
+		pAC->vpd.vpd_buf[i + 2] = '8';
+	}
+
 	/* find the end tag of the RO area */
 	if (!(r = vpd_find_para(pAC, VPD_RV, &rp))) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
 			("Encoding Error: RV Tag not found\n"));
 		return(1);
 	}
-	
+
 	if (r->p_val + r->p_len > pAC->vpd.vpd_buf + vpd_size/2) {
-		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+		SK_DBG_MSG(pAC, SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
 			("Encoding Error: Invalid VPD struct size\n"));
 		return(1);
 	}
@@ -484,7 +501,7 @@
 	for (i = 0, x = 0; (unsigned)i <= (unsigned)vpd_size/2 - r->p_len; i++) {
 		x += pAC->vpd.vpd_buf[i];
 	}
-	
+
 	if (x != 0) {
 		/* checksum error */
 		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
@@ -498,7 +515,7 @@
 			("Encoding Error: RV Tag not found\n"));
 		return(1);
 	}
-	
+
 	if (r->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
 			("Encoding Error: Invalid VPD struct size\n"));
@@ -528,7 +545,7 @@
 static SK_VPD_PARA *vpd_find_para(
 SK_AC		*pAC,	/* common data base */
 const char	*key,	/* keyword to find (e.g. "MN") */
-SK_VPD_PARA *p)		/* parameter description struct */
+SK_VPD_PARA	*p)		/* parameter description struct */
 {
 	char *v	;	/* points to VPD buffer */
 	int max;	/* Maximum Number of Iterations */
@@ -556,7 +573,7 @@
 
 	v += 3 + VPD_GET_RES_LEN(v) + 3;
 	for (;; ) {
-		if (SK_MEMCMP(key,v,2) == 0) {
+		if (SK_MEMCMP(key, v, 2) == 0) {
 			p->p_len = VPD_GET_VPD_LEN(v);
 			p->p_val = VPD_GET_VAL(v);
 			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
@@ -566,11 +583,11 @@
 
 		/* exit when reaching the "RW" Tag or the maximum of itera. */
 		max--;
-		if (SK_MEMCMP(VPD_RW,v,2) == 0 || max == 0) {
+		if (SK_MEMCMP(VPD_RW, v, 2) == 0 || max == 0) {
 			break;
 		}
 
-		if (SK_MEMCMP(VPD_RV,v,2) == 0) {
+		if (SK_MEMCMP(VPD_RV, v, 2) == 0) {
 			v += 3 + VPD_GET_VPD_LEN(v) + 3;	/* skip VPD-W */
 		}
 		else {
@@ -669,7 +686,7 @@
 
 	if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) {
 		/* something wrong here, encoding error */
-		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
 			("Encoding Error: invalid end tag\n"));
 		return(1);
 	}
@@ -734,7 +751,7 @@
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
 		("VPD setup para key = %s, val = %s\n",key,buf));
-	
+
 	vpd_size = pAC->vpd.vpd_size;
 
 	rtv = 0;
@@ -873,7 +890,7 @@
 	}
 	else {
 		*len = 0;
-		SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
+		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
 			("buffer overflow\n"));
 		return(2);
 	}
@@ -1069,7 +1086,7 @@
 
 	vpd_size = pAC->vpd.vpd_size;
 
-	SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("VPD delete key %s\n",key));
+	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD delete key %s\n", key));
 	if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
 		if (VpdInit(pAC, IoC) != 0) {
 			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
diff -urN linux-2.4.29/drivers/net/sk98lin/skxmac2.c linux-2.4.29-uc1/drivers/net/sk98lin/skxmac2.c
--- linux-2.4.29/drivers/net/sk98lin/skxmac2.c	2004-04-14 14:05:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/skxmac2.c	2005-06-14 02:12:09.000000000 +0100
@@ -2,6 +2,8 @@
  *
  * Name:	skxmac2.c
  * Project:	Gigabit Ethernet Adapters, Common Modules
+ * Version:	$Revision: 2.25 $
+ * Date:	$Date: 2004/08/13 09:49:09 $
  * Purpose:	Contains functions to initialize the MACs and PHYs
  *
  ******************************************************************************/
@@ -9,13 +11,12 @@
 /******************************************************************************
  *
  *	(C)Copyright 1998-2002 SysKonnect.
- *	(C)Copyright 2002-2003 Marvell.
+ *	(C)Copyright 2002-2004 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
  *	the Free Software Foundation; either version 2 of the License, or
  *	(at your option) any later version.
- *
  *	The information in this file is provided "AS IS" without warranty.
  *
  ******************************************************************************/
@@ -35,7 +36,7 @@
 
 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skxmac2.c,v 1.102 2003/10/02 16:53:58 rschmidt Exp $ (C) Marvell.";
+	"@(#) $Id: skxmac2.c,v 2.25 2004/08/13 09:49:09 rschmidt Exp $ (C) Marvell.";
 #endif
 
 #ifdef GENESIS
@@ -81,7 +82,7 @@
  * Returns:
  *	nothing
  */
-void SkXmPhyRead(
+int SkXmPhyRead(
 SK_AC	*pAC,			/* Adapter Context */
 SK_IOC	IoC,			/* I/O Context */
 int		Port,			/* Port Index (MAC_1 + n) */
@@ -92,13 +93,13 @@
 	SK_GEPORT	*pPrt;
 
 	pPrt = &pAC->GIni.GP[Port];
-	
+
 	/* write the PHY register's address */
 	XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
-	
+
 	/* get the PHY register's value */
 	XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
-	
+
 	if (pPrt->PhyType != SK_PHY_XMAC) {
 		do {
 			XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
@@ -108,6 +109,8 @@
 		/* get the PHY register's value */
 		XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
 	}
+
+	return(0);
 }	/* SkXmPhyRead */
 
 
@@ -120,7 +123,7 @@
  * Returns:
  *	nothing
  */
-void SkXmPhyWrite(
+int SkXmPhyWrite(
 SK_AC	*pAC,		/* Adapter Context */
 SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
@@ -131,26 +134,28 @@
 	SK_GEPORT	*pPrt;
 
 	pPrt = &pAC->GIni.GP[Port];
-	
+
 	if (pPrt->PhyType != SK_PHY_XMAC) {
 		do {
 			XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
 			/* wait until 'Busy' is cleared */
 		} while ((Mmu & XM_MMU_PHY_BUSY) != 0);
 	}
-	
+
 	/* write the PHY register's address */
 	XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
-	
+
 	/* write the PHY register's value */
 	XM_OUT16(IoC, Port, XM_PHY_DATA, Val);
-	
+
 	if (pPrt->PhyType != SK_PHY_XMAC) {
 		do {
 			XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
 			/* wait until 'Busy' is cleared */
 		} while ((Mmu & XM_MMU_PHY_BUSY) != 0);
 	}
+
+	return(0);
 }	/* SkXmPhyWrite */
 #endif /* GENESIS */
 
@@ -165,7 +170,7 @@
  * Returns:
  *	nothing
  */
-void SkGmPhyRead(
+int SkGmPhyRead(
 SK_AC	*pAC,			/* Adapter Context */
 SK_IOC	IoC,			/* I/O Context */
 int		Port,			/* Port Index (MAC_1 + n) */
@@ -174,52 +179,72 @@
 {
 	SK_U16	Ctrl;
 	SK_GEPORT	*pPrt;
-#ifdef VCPU
-	u_long SimCyle;
-	u_long SimLowTime;
-	
-	VCPUgetTime(&SimCyle, &SimLowTime);
-	VCPUprintf(0, "SkGmPhyRead(%u), SimCyle=%u, SimLowTime=%u\n",
-		PhyReg, SimCyle, SimLowTime);
-#endif /* VCPU */
-	
+	SK_U32	StartTime;
+	SK_U32	CurrTime;
+	SK_U32	Delta;
+
 	pPrt = &pAC->GIni.GP[Port];
-	
+
 	/* set PHY-Register offset and 'Read' OpCode (= 1) */
 	*pVal = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) |
 		GM_SMI_CT_REG_AD(PhyReg) | GM_SMI_CT_OP_RD);
 
 	GM_OUT16(IoC, Port, GM_SMI_CTRL, *pVal);
 
-	GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
-	
+#ifdef DEBUG
 	/* additional check for MDC/MDIO activity */
-	if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
+	GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
+
+	if ((Ctrl & GM_SMI_CT_OP_RD) == 0) {
+
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+			("PHY read impossible on Port %d (Ctrl=0x%04x)\n", Port, Ctrl));
+
 		*pVal = 0;
-		return;
+		return(1);
 	}
+#endif /* DEBUG */
 
 	*pVal |= GM_SMI_CT_BUSY;
-	
-	do {
+
+	SK_IN32(IoC, GMAC_TI_ST_VAL, &StartTime);
+
+	do {	/* wait until 'Busy' is cleared and 'ReadValid' is set */
 #ifdef VCPU
 		VCPUwaitTime(1000);
 #endif /* VCPU */
 
+		SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime);
+
+		if (CurrTime >= StartTime) {
+			Delta = CurrTime - StartTime;
+		}
+		else {
+			Delta = CurrTime + ~StartTime + 1;
+		}
+
+		if (Delta > SK_PHY_ACC_TO) {
+
+			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+				("PHY read timeout on Port %d (Ctrl=0x%04x)\n", Port, Ctrl));
+			return(1);
+		}
+
 		GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
 
-	/* wait until 'ReadValid' is set */
-	} while (Ctrl == *pVal);
-	
-	/* get the PHY register's value */
+		/* Error on reading SMI Control Register */
+		if (Ctrl == 0xffff) {
+			return(1);
+		}
+
+	} while ((Ctrl ^ *pVal) != (GM_SMI_CT_RD_VAL | GM_SMI_CT_BUSY));
+
 	GM_IN16(IoC, Port, GM_SMI_DATA, pVal);
 
-#ifdef VCPU
-	VCPUgetTime(&SimCyle, &SimLowTime);
-	VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
-		SimCyle, SimLowTime);
-#endif /* VCPU */
+	/* dummy read after GM_IN16() */
+	SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime);
 
+	return(0);
 }	/* SkGmPhyRead */
 
 
@@ -232,7 +257,7 @@
  * Returns:
  *	nothing
  */
-void SkGmPhyWrite(
+int SkGmPhyWrite(
 SK_AC	*pAC,		/* Adapter Context */
 SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
@@ -241,54 +266,70 @@
 {
 	SK_U16	Ctrl;
 	SK_GEPORT	*pPrt;
-#ifdef VCPU
-	SK_U32	DWord;
-	u_long	SimCyle;
-	u_long	SimLowTime;
-	
-	VCPUgetTime(&SimCyle, &SimLowTime);
-	VCPUprintf(0, "SkGmPhyWrite(Reg=%u, Val=0x%04x), SimCyle=%u, SimLowTime=%u\n",
-		PhyReg, Val, SimCyle, SimLowTime);
-#endif /* VCPU */
-	
+	SK_U32	StartTime;
+	SK_U32	CurrTime;
+	SK_U32	Delta;
+
 	pPrt = &pAC->GIni.GP[Port];
-	
+
 	/* write the PHY register's value */
 	GM_OUT16(IoC, Port, GM_SMI_DATA, Val);
-	
-	/* set PHY-Register offset and 'Write' OpCode (= 0) */
-	Val = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg);
 
-	GM_OUT16(IoC, Port, GM_SMI_CTRL, Val);
-
-	GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
-	
+#ifdef DEBUG
 	/* additional check for MDC/MDIO activity */
-	if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
-		return;
+	GM_IN16(IoC, Port, GM_SMI_DATA, &Ctrl);
+
+	if (Ctrl != Val) {
+
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+			("PHY write impossible on Port %d (Val=0x%04x)\n", Port, Ctrl));
+
+		return(1);
 	}
-	
-	Val |= GM_SMI_CT_BUSY;
+#endif /* DEBUG */
 
-	do {
-#ifdef VCPU
-		/* read Timer value */
-		SK_IN32(IoC, B2_TI_VAL, &DWord);
+	/* set PHY-Register offset and 'Write' OpCode (= 0) */
+	Ctrl = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) |
+		GM_SMI_CT_REG_AD(PhyReg));
+
+	GM_OUT16(IoC, Port, GM_SMI_CTRL, Ctrl);
+
+	SK_IN32(IoC, GMAC_TI_ST_VAL, &StartTime);
 
+	do {	/* wait until 'Busy' is cleared */
+#ifdef VCPU
 		VCPUwaitTime(1000);
 #endif /* VCPU */
 
+		SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime);
+
+		if (CurrTime >= StartTime) {
+			Delta = CurrTime - StartTime;
+		}
+		else {
+			Delta = CurrTime + ~StartTime + 1;
+		}
+
+		if (Delta > SK_PHY_ACC_TO) {
+
+			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+				("PHY write timeout on Port %d (Ctrl=0x%04x)\n", Port, Ctrl));
+			return(1);
+		}
+
 		GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
 
-	/* wait until 'Busy' is cleared */
-	} while (Ctrl == Val);
+		/* Error on reading SMI Control Register */
+		if (Ctrl == 0xffff) {
+			return(1);
+		}
 	
-#ifdef VCPU
-	VCPUgetTime(&SimCyle, &SimLowTime);
-	VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
-		SimCyle, SimLowTime);
-#endif /* VCPU */
+	} while ((Ctrl & GM_SMI_CT_BUSY) != 0);
 
+	/* dummy read after GM_IN16() */
+	SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime);
+
+	return(0);
 }	/* SkGmPhyWrite */
 #endif /* YUKON */
 
@@ -310,16 +351,8 @@
 int		PhyReg,		/* Register Address (Offset) */
 SK_U16	*pVal)		/* Pointer to Value */
 {
-	void (*r_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 *pVal);
 
-	if (pAC->GIni.GIGenesis) {
-		r_func = SkXmPhyRead;
-	}
-	else {
-		r_func = SkGmPhyRead;
-	}
-	
-	r_func(pAC, IoC, Port, PhyReg, pVal);
+	pAC->GIni.GIFunc.pFnMacPhyRead(pAC, IoC, Port, PhyReg, pVal);
 }	/* SkGePhyRead */
 
 
@@ -339,16 +372,8 @@
 int		PhyReg,		/* Register Address (Offset) */
 SK_U16	Val)		/* Value */
 {
-	void (*w_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 Val);
 
-	if (pAC->GIni.GIGenesis) {
-		w_func = SkXmPhyWrite;
-	}
-	else {
-		w_func = SkGmPhyWrite;
-	}
-	
-	w_func(pAC, IoC, Port, PhyReg, Val);
+	pAC->GIni.GIFunc.pFnMacPhyWrite(pAC, IoC, Port, PhyReg, Val);
 }	/* SkGePhyWrite */
 #endif /* SK_DIAG */
 
@@ -359,14 +384,14 @@
  *
  * Description:
  *   enables / disables promiscuous mode by setting Mode Register (XMAC) or
- *   Receive Control Register (GMAC) dep. on board type   	
+ *   Receive Control Register (GMAC) dep. on board type
  *
  * Returns:
  *	nothing
  */
 void SkMacPromiscMode(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
 int		Port,	/* Port Index (MAC_1 + n) */
 SK_BOOL	Enable)	/* Enable / Disable */
 {
@@ -375,11 +400,11 @@
 #endif
 #ifdef GENESIS
 	SK_U32	MdReg;
-#endif	
+#endif
 
 #ifdef GENESIS
 	if (pAC->GIni.GIGenesis) {
-		
+
 		XM_IN32(IoC, Port, XM_MODE, &MdReg);
 		/* enable or disable promiscuous mode */
 		if (Enable) {
@@ -392,12 +417,12 @@
 		XM_OUT32(IoC, Port, XM_MODE, MdReg);
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
-		
+
 		GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
-		
+
 		/* enable or disable unicast and multicast filtering */
 		if (Enable) {
 			RcReg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
@@ -419,27 +444,27 @@
  *
  * Description:
  *   enables / disables hashing by setting Mode Register (XMAC) or
- *   Receive Control Register (GMAC) dep. on board type		
+ *   Receive Control Register (GMAC) dep. on board type
  *
  * Returns:
  *	nothing
  */
 void SkMacHashing(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
 int		Port,	/* Port Index (MAC_1 + n) */
 SK_BOOL	Enable)	/* Enable / Disable */
 {
 #ifdef YUKON
 	SK_U16	RcReg;
-#endif	
+#endif
 #ifdef GENESIS
 	SK_U32	MdReg;
 #endif
 
 #ifdef GENESIS
 	if (pAC->GIni.GIGenesis) {
-		
+
 		XM_IN32(IoC, Port, XM_MODE, &MdReg);
 		/* enable or disable hashing */
 		if (Enable) {
@@ -452,12 +477,12 @@
 		XM_OUT32(IoC, Port, XM_MODE, MdReg);
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
-		
+
 		GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
-		
+
 		/* enable or disable multicast filtering */
 		if (Enable) {
 			RcReg |= GM_RXCR_MCF_ENA;
@@ -497,8 +522,8 @@
  *	nothing
  */
 static void SkXmSetRxCmd(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 int		Mode)		/* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
 					   SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
@@ -509,7 +534,7 @@
 	XM_IN16(IoC, Port, XM_RX_CMD, &OldRxCmd);
 
 	RxCmd = OldRxCmd;
-	
+
 	switch (Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) {
 	case SK_STRIP_FCS_ON:
 		RxCmd |= XM_RX_STRIP_FCS;
@@ -582,20 +607,17 @@
  *	nothing
  */
 static void SkGmSetRxCmd(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 int		Mode)		/* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
 					   SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
 {
-	SK_U16	OldRxCmd;
 	SK_U16	RxCmd;
 
 	if ((Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) != 0) {
-		
-		GM_IN16(IoC, Port, GM_RX_CTRL, &OldRxCmd);
 
-		RxCmd = OldRxCmd;
+		GM_IN16(IoC, Port, GM_RX_CTRL, &RxCmd);
 
 		if ((Mode & SK_STRIP_FCS_ON) != 0) {
 			RxCmd |= GM_RXCR_CRC_DIS;
@@ -603,17 +625,13 @@
 		else {
 			RxCmd &= ~GM_RXCR_CRC_DIS;
 		}
-		/* Write the new mode to the Rx control register if required */
-		if (OldRxCmd != RxCmd) {
-			GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd);
-		}
+		/* Write the new mode to the Rx Control register */
+		GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd);
 	}
 
 	if ((Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) != 0) {
-		
-		GM_IN16(IoC, Port, GM_SERIAL_MODE, &OldRxCmd);
 
-		RxCmd = OldRxCmd;
+		GM_IN16(IoC, Port, GM_SERIAL_MODE, &RxCmd);
 
 		if ((Mode & SK_BIG_PK_OK_ON) != 0) {
 			RxCmd |= GM_SMOD_JUMBO_ENA;
@@ -621,10 +639,8 @@
 		else {
 			RxCmd &= ~GM_SMOD_JUMBO_ENA;
 		}
-		/* Write the new mode to the Rx control register if required */
-		if (OldRxCmd != RxCmd) {
-			GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd);
-		}
+		/* Write the new mode to the Serial Mode register */
+		GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd);
 	}
 }	/* SkGmSetRxCmd */
 
@@ -639,17 +655,17 @@
  *	nothing
  */
 void SkMacSetRxCmd(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 int		Mode)		/* Rx Mode */
 {
 	if (pAC->GIni.GIGenesis) {
-		
+
 		SkXmSetRxCmd(pAC, IoC, Port, Mode);
 	}
 	else {
-		
+
 		SkGmSetRxCmd(pAC, IoC, Port, Mode);
 	}
 
@@ -666,15 +682,15 @@
  *	nothing
  */
 void SkMacCrcGener(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
 int		Port,	/* Port Index (MAC_1 + n) */
 SK_BOOL	Enable)	/* Enable / Disable */
 {
 	SK_U16	Word;
 
 	if (pAC->GIni.GIGenesis) {
-		
+
 		XM_IN16(IoC, Port, XM_TX_CMD, &Word);
 
 		if (Enable) {
@@ -687,9 +703,9 @@
 		XM_OUT16(IoC, Port, XM_TX_CMD, Word);
 	}
 	else {
-		
+
 		GM_IN16(IoC, Port, GM_TX_CTRL, &Word);
-		
+
 		if (Enable) {
 			Word &= ~GM_TXCR_CRC_DIS;
 		}
@@ -719,14 +735,14 @@
  *	nothing
  */
 void SkXmClrExactAddr(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 int		StartNum,	/* Begin with this Address Register Index (0..15) */
 int		StopNum)	/* Stop after finished with this Register Idx (0..15) */
 {
 	int		i;
-	SK_U16	ZeroAddr[3] = {0x0000, 0x0000, 0x0000};
+	SK_U16	ZeroAddr[3] = {0, 0, 0};
 
 	if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 ||
 		StartNum > StopNum) {
@@ -736,7 +752,7 @@
 	}
 
 	for (i = StartNum; i <= StopNum; i++) {
-		XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]);
+		XM_OUTADDR(IoC, Port, XM_EXM(i), ZeroAddr);
 	}
 }	/* SkXmClrExactAddr */
 #endif /* GENESIS */
@@ -753,21 +769,21 @@
  *	nothing
  */
 void SkMacFlushTxFifo(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
 int		Port)	/* Port Index (MAC_1 + n) */
 {
 #ifdef GENESIS
 	SK_U32	MdReg;
 
 	if (pAC->GIni.GIGenesis) {
-		
+
 		XM_IN32(IoC, Port, XM_MODE, &MdReg);
 
 		XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FTF);
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
 		/* no way to flush the FIFO we have to issue a reset */
@@ -789,8 +805,8 @@
  *	nothing
  */
 void SkMacFlushRxFifo(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
 int		Port)	/* Port Index (MAC_1 + n) */
 {
 #ifdef GENESIS
@@ -803,7 +819,7 @@
 		XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FRF);
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
 		/* no way to flush the FIFO we have to issue a reset */
@@ -851,23 +867,23 @@
  *	nothing
  */
 static void SkXmSoftRst(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
 int		Port)	/* Port Index (MAC_1 + n) */
 {
-	SK_U16	ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000};
-	
+	SK_U16	ZeroAddr[4] = {0, 0, 0, 0};
+
 	/* reset the statistics module */
 	XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT);
 
 	/* disable all XMAC IRQs */
 	XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
-	
+
 	XM_OUT32(IoC, Port, XM_MODE, 0);		/* clear Mode Reg */
-	
+
 	XM_OUT16(IoC, Port, XM_TX_CMD, 0);		/* reset TX CMD Reg */
 	XM_OUT16(IoC, Port, XM_RX_CMD, 0);		/* reset RX CMD Reg */
-	
+
 	/* disable all PHY IRQs */
 	switch (pAC->GIni.GP[Port].PhyType) {
 	case SK_PHY_BCOM:
@@ -885,13 +901,13 @@
 	}
 
 	/* clear the Hash Register */
-	XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr);
+	XM_OUTHASH(IoC, Port, XM_HSM, ZeroAddr);
 
 	/* clear the Exact Match Address registers */
 	SkXmClrExactAddr(pAC, IoC, Port, 0, 15);
-	
+
 	/* clear the Source Check Address registers */
-	XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr);
+	XM_OUTHASH(IoC, Port, XM_SRC_CHK, ZeroAddr);
 
 }	/* SkXmSoftRst */
 
@@ -914,8 +930,8 @@
  *	nothing
  */
 static void SkXmHardRst(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
 int		Port)	/* Port Index (MAC_1 + n) */
 {
 	SK_U32	Reg;
@@ -938,17 +954,17 @@
 			}
 
 			SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
-			
+
 			SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &Word);
-		
+
 		} while ((Word & MFF_SET_MAC_RST) == 0);
 	}
 
 	/* For external PHYs there must be special handling */
 	if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
-		
+
 		SK_IN32(IoC, B2_GP_IO, &Reg);
-		
+
 		if (Port == 0) {
 			Reg |= GP_DIR_0; 	/* set to output */
 			Reg &= ~GP_IO_0;	/* set PHY reset (active low) */
@@ -976,12 +992,12 @@
  *	nothing
  */
 static void SkXmClearRst(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
 int		Port)	/* Port Index (MAC_1 + n) */
 {
 	SK_U32	DWord;
-	
+
 	/* clear HW reset */
 	SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
 
@@ -1018,8 +1034,8 @@
  *	nothing
  */
 static void SkGmSoftRst(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
 int		Port)	/* Port Index (MAC_1 + n) */
 {
 	SK_U16	EmptyHash[4] = {0x0000, 0x0000, 0x0000, 0x0000};
@@ -1028,19 +1044,18 @@
 	/* reset the statistics module */
 
 	/* disable all GMAC IRQs */
-	SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
-	
+	SK_OUT8(IoC, MR_ADDR(Port, GMAC_IRQ_MSK), 0);
+
 	/* disable all PHY IRQs */
 	SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
-	
+
 	/* clear the Hash Register */
 	GM_OUTHASH(IoC, Port, GM_MC_ADDR_H1, EmptyHash);
 
 	/* Enable Unicast and Multicast filtering */
 	GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl);
-	
-	GM_OUT16(IoC, Port, GM_RX_CTRL,
-		(SK_U16)(RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA));
+
+	GM_OUT16(IoC, Port, GM_RX_CTRL, RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
 
 }	/* SkGmSoftRst */
 
@@ -1055,16 +1070,16 @@
  *	nothing
  */
 static void SkGmHardRst(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
 int		Port)	/* Port Index (MAC_1 + n) */
 {
 	SK_U32	DWord;
-	
+
 	/* WA code for COMA mode */
 	if (pAC->GIni.GIYukonLite &&
 		pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
-		
+
 		SK_IN32(IoC, B2_GP_IO, &DWord);
 
 		DWord |= (GP_DIR_9 | GP_IO_9);
@@ -1074,10 +1089,10 @@
 	}
 
 	/* set GPHY Control reset */
-	SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
+	SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_SET);
 
 	/* set GMAC Control reset */
-	SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
+	SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_SET);
 
 }	/* SkGmHardRst */
 
@@ -1092,24 +1107,24 @@
  *	nothing
  */
 static void SkGmClearRst(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
 int		Port)	/* Port Index (MAC_1 + n) */
 {
 	SK_U32	DWord;
-	
+
 #ifdef XXX
 		/* clear GMAC Control reset */
-		SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);
+		SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_CLR);
 
 		/* set GMAC Control reset */
-		SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
+		SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_SET);
 #endif /* XXX */
 
 	/* WA code for COMA mode */
 	if (pAC->GIni.GIYukonLite &&
 		pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
-		
+
 		SK_IN32(IoC, B2_GP_IO, &DWord);
 
 		DWord |= GP_DIR_9;		/* set to output */
@@ -1119,30 +1134,52 @@
 		SK_OUT32(IoC, B2_GP_IO, DWord);
 	}
 
-	/* set HWCFG_MODE */
-	DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
-		GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
-		(pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
-		GPC_HWCFG_GMII_FIB);
+#ifdef VCPU
+	/* Set MAC Reset before PHY reset is set */
+	SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_SET);
+#endif /* VCPU */
 
-	/* set GPHY Control reset */
-	SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
+	if (CHIP_ID_YUKON_2(pAC)) {
+		/* set GPHY Control reset */
+		SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_SET);
 
-	/* release GPHY Control reset */
-	SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
+		/* release GPHY Control reset */
+		SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_CLR);
+	}
+	else {
+		/* set HWCFG_MODE */
+		DWord = GPC_INT_POL | GPC_DIS_FC | GPC_DIS_SLEEP |
+			GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
+			(pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
+			GPC_HWCFG_GMII_FIB);
+		
+		/* set GPHY Control reset */
+		SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
 
+		/* release GPHY Control reset */
+		SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
+	}
+	
 #ifdef VCPU
+    /* wait for internal initialization of GPHY */
+    VCPUprintf(0, "Waiting until PHY %d is ready to initialize\n", Port);
+	VCpuWait(10000);
+
+	/* release GMAC reset */
+    SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_CLR);
+
+    /* wait for stable GMAC clk */
 	VCpuWait(9000);
 #endif /* VCPU */
 
 	/* clear GMAC Control reset */
-	SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
+	SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_CLR);
 
 #ifdef VCPU
 	VCpuWait(2000);
-	
+
 	SK_IN32(IoC, MR_ADDR(Port, GPHY_CTRL), &DWord);
-			
+
 	SK_IN32(IoC, B0_ISRC, &DWord);
 #endif /* VCPU */
 
@@ -1160,37 +1197,33 @@
  *	nothing
  */
 void SkMacSoftRst(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
 int		Port)	/* Port Index (MAC_1 + n) */
 {
-	SK_GEPORT	*pPrt;
-
-	pPrt = &pAC->GIni.GP[Port];
-
 	/* disable receiver and transmitter */
 	SkMacRxTxDisable(pAC, IoC, Port);
 
 #ifdef GENESIS
 	if (pAC->GIni.GIGenesis) {
-		
+
 		SkXmSoftRst(pAC, IoC, Port);
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
-		
+
 		SkGmSoftRst(pAC, IoC, Port);
 	}
 #endif /* YUKON */
 
 	/* flush the MAC's Rx and Tx FIFOs */
 	SkMacFlushTxFifo(pAC, IoC, Port);
-	
+
 	SkMacFlushRxFifo(pAC, IoC, Port);
 
-	pPrt->PState = SK_PRT_STOP;
+	pAC->GIni.GP[Port].PState = SK_PRT_STOP;
 
 }	/* SkMacSoftRst */
 
@@ -1205,21 +1238,21 @@
  *	nothing
  */
 void SkMacHardRst(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
 int		Port)	/* Port Index (MAC_1 + n) */
 {
-	
+
 #ifdef GENESIS
 	if (pAC->GIni.GIGenesis) {
-		
+
 		SkXmHardRst(pAC, IoC, Port);
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
-		
+
 		SkGmHardRst(pAC, IoC, Port);
 	}
 #endif /* YUKON */
@@ -1239,21 +1272,21 @@
  *	nothing
  */
 void SkMacClearRst(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
 int		Port)	/* Port Index (MAC_1 + n) */
 {
-	
+
 #ifdef GENESIS
 	if (pAC->GIni.GIGenesis) {
-		
+
 		SkXmClearRst(pAC, IoC, Port);
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
-		
+
 		SkGmClearRst(pAC, IoC, Port);
 	}
 #endif /* YUKON */
@@ -1277,8 +1310,8 @@
  *	nothing
  */
 void SkXmInitMac(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
@@ -1313,7 +1346,7 @@
 			 * Must be done AFTER first access to BCOM chip.
 			 */
 			XM_IN16(IoC, Port, XM_MMU_CMD, &SWord);
-			
+
 			XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE);
 
 			if (pPrt->PhyId1 == PHY_BCOM_ID1_C0) {
@@ -1346,7 +1379,7 @@
 			 * Disable Power Management after reset.
 			 */
 			SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
-			
+
 			SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
 				(SK_U16)(SWord | PHY_B_AC_DIS_PM));
 
@@ -1355,7 +1388,7 @@
 
 		/* Dummy read the Interrupt source register */
 		XM_IN16(IoC, Port, XM_ISRC, &SWord);
-		
+
 		/*
 		 * The auto-negotiation process starts immediately after
 		 * clearing the reset. The auto-negotiation process should be
@@ -1381,7 +1414,7 @@
 		 * independent. Remember this when changing.
 		 */
 		SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
-		
+
 		XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord);
 	}
 
@@ -1434,7 +1467,7 @@
 		 */
 		SWord |= XM_RX_DIS_CEXT;
 	}
-	
+
 	XM_OUT16(IoC, Port, XM_RX_CMD, SWord);
 
 	/*
@@ -1491,8 +1524,8 @@
  *	nothing
  */
 void SkGmInitMac(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
@@ -1506,7 +1539,7 @@
 		/* Port State: SK_PRT_STOP */
 		/* Verify that the reset bit is cleared */
 		SK_IN32(IoC, MR_ADDR(Port, GMAC_CTRL), &DWord);
-		
+
 		if ((DWord & GMC_RST_SET) != 0) {
 			/* PState does not match HW state */
 			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
@@ -1516,11 +1549,11 @@
 	}
 
 	if (pPrt->PState == SK_PRT_RESET) {
-		
+
 		SkGmHardRst(pAC, IoC, Port);
 
 		SkGmClearRst(pAC, IoC, Port);
-		
+
 		/* Auto-negotiation ? */
 		if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
 			/* Auto-negotiation disabled */
@@ -1530,10 +1563,10 @@
 
 			/* disable auto-update for speed, duplex and flow-control */
 			SWord |= GM_GPCR_AU_ALL_DIS;
-			
+
 			/* setup General Purpose Control Register */
 			GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
-			
+
 			SWord = GM_GPCR_AU_ALL_DIS;
 		}
 		else {
@@ -1544,7 +1577,10 @@
 		switch (pPrt->PLinkSpeed) {
 		case SK_LSPEED_AUTO:
 		case SK_LSPEED_1000MBPS:
-			SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100;
+			if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) {
+
+				SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100;
+			}
 			break;
 		case SK_LSPEED_100MBPS:
 			SWord |= GM_GPCR_SPEED_100;
@@ -1562,8 +1598,6 @@
 		/* flow-control settings */
 		switch (pPrt->PFlowCtrlMode) {
 		case SK_FLOW_MODE_NONE:
-			/* set Pause Off */
-			SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_OFF);
 			/* disable Tx & Rx flow-control */
 			SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
 			break;
@@ -1581,24 +1615,24 @@
 		GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
 
 		/* dummy read the Interrupt Source Register */
-		SK_IN16(IoC, GMAC_IRQ_SRC, &SWord);
-		
+		SK_IN16(IoC, MR_ADDR(Port, GMAC_IRQ_SRC), &SWord);
+
 #ifndef VCPU
 		/* read Id from PHY */
 		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1);
-		
+
 		SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
-#endif /* VCPU */
+#endif /* !VCPU */
 	}
 
 	(void)SkGmResetCounter(pAC, IoC, Port);
 
 	/* setup Transmit Control Register */
-	GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres));
+	GM_OUT16(IoC, Port, GM_TX_CTRL, (SK_U16)TX_COL_THR(pPrt->PMacColThres));
 
 	/* setup Receive Control Register */
-	GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA |
-		GM_RXCR_CRC_DIS);
+	GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA |
+		GM_RXCR_MCF_ENA | GM_RXCR_CRC_DIS);
 
 	/* setup Transmit Flow Control Register */
 	GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff);
@@ -1608,18 +1642,16 @@
 	GM_IN16(IoC, Port, GM_TX_PARAM, &SWord);
 #endif /* VCPU */
 
-    SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) |
-			TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) |
-			TX_IPG_JAM_DATA(pPrt->PMacJamIpgData);
-	
+	SWord = (SK_U16)(TX_JAM_LEN_VAL(pPrt->PMacJamLen) |
+		TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) |
+		TX_IPG_JAM_DATA(pPrt->PMacJamIpgData) |
+		TX_BACK_OFF_LIM(pPrt->PMacBackOffLim));
+
 	GM_OUT16(IoC, Port, GM_TX_PARAM, SWord);
 
 	/* configure the Serial Mode Register */
-#ifdef VCPU
-	GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord);
-#endif /* VCPU */
-	
-	SWord = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData);
+	SWord = (SK_U16)(DATA_BLIND_VAL(pPrt->PMacDataBlind) |
+		GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData));
 
 	if (pPrt->PMacLimit4) {
 		/* reset of collision counter after 4 consecutive collisions */
@@ -1630,9 +1662,9 @@
 		/* enable jumbo mode (Max. Frame Length = 9018) */
 		SWord |= GM_SMOD_JUMBO_ENA;
 	}
-	
+
 	GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord);
-	
+
 	/*
 	 * configure the GMACs Station Addresses
 	 * in PROM you can find our addresses at:
@@ -1661,15 +1693,15 @@
 		else {
 			GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
 		}
-#else		
+#else
 		GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
 #endif /* WA_DEV_16 */
-		
+
 		/* virtual address: will be used for data */
 		SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord);
 
 		GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord);
-		
+
 		/* reset Multicast filtering Hash registers 1-3 */
 		GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0);
 	}
@@ -1682,18 +1714,6 @@
 	GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0);
 	GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0);
 
-#if defined(SK_DIAG) || defined(DEBUG)
-	/* read General Purpose Status */
-	GM_IN16(IoC, Port, GM_GP_STAT, &SWord);
-	
-	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-		("MAC Stat Reg.=0x%04X\n", SWord));
-#endif /* SK_DIAG || DEBUG */
-
-#ifdef SK_DIAG
-	c_print("MAC Stat Reg=0x%04X\n", SWord);
-#endif /* SK_DIAG */
-
 }	/* SkGmInitMac */
 #endif /* YUKON */
 
@@ -1712,8 +1732,8 @@
  *	nothing
  */
 void SkXmInitDupMd(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	switch (pAC->GIni.GP[Port].PLinkModeStatus) {
@@ -1760,8 +1780,8 @@
  *	nothing
  */
 void SkXmInitPauseMd(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
@@ -1771,7 +1791,7 @@
 	pPrt = &pAC->GIni.GP[Port];
 
 	XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
-	
+
 	if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE ||
 		pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
 
@@ -1785,8 +1805,8 @@
 		 */
 		/* Enable Pause Frame Reception */
 		Word &= ~XM_MMU_IGN_PF;
-	}	
-	
+	}
+
 	XM_OUT16(IoC, Port, XM_MMU_CMD, Word);
 
 	XM_IN32(IoC, Port, XM_MODE, &DWord);
@@ -1826,7 +1846,7 @@
 		/* Disable Pause Mode in MAC Rx FIFO */
 		SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
 	}
-	
+
 	XM_OUT32(IoC, Port, XM_MODE, DWord);
 }	/* SkXmInitPauseMd*/
 
@@ -1843,8 +1863,8 @@
  *	nothing
  */
 static void SkXmInitPhyXmac(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	DoLoop)		/* Should a Phy LoopBack be set-up? */
 {
@@ -1853,7 +1873,7 @@
 
 	pPrt = &pAC->GIni.GP[Port];
 	Ctrl = 0;
-	
+
 	/* Auto-negotiation ? */
 	if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
@@ -1937,8 +1957,8 @@
  *	nothing
  */
 static void SkXmInitPhyBcom(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	DoLoop)		/* Should a Phy LoopBack be set-up? */
 {
@@ -1960,7 +1980,7 @@
 	/* manually Master/Slave ? */
 	if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
 		Ctrl2 |= PHY_B_1000C_MSE;
-		
+
 		if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
 			Ctrl2 |= PHY_B_1000C_MSC;
 		}
@@ -1995,7 +2015,7 @@
 		 * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
 		 */
 		Ctrl2 |= PHY_B_1000C_RD;
-		
+
 		 /* Set Full/half duplex capabilities */
 		switch (pPrt->PLinkMode) {
 		case SK_LMODE_AUTOHALF:
@@ -2034,21 +2054,21 @@
 		/* Restart Auto-negotiation */
 		Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG;
 	}
-	
+
 	/* Initialize LED register here? */
 	/* No. Please do it in SkDgXmitLed() (if required) and swap
 	   init order of LEDs and XMAC. (MAl) */
-	
+
 	/* Write 1000Base-T Control Register */
 	SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 		("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
-	
+
 	/* Write AutoNeg Advertisement Register */
 	SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 		("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
-	
+
 	if (DoLoop) {
 		/* Set the Phy Loopback bit, too */
 		Ctrl1 |= PHY_CT_LOOP;
@@ -2066,7 +2086,7 @@
 
 	/* Configure LED Traffic Mode and Jumbo Frame usage if specified */
 	SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4);
-	
+
 	/* Write to the Phy control register */
 	SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, Ctrl1);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
@@ -2076,17 +2096,17 @@
 
 
 #ifdef YUKON
-#ifndef SK_SLIM
+#ifdef SK_PHY_LP_MODE
 /******************************************************************************
  *
  *	SkGmEnterLowPowerMode()
  *
- * Description:	
+ * Description:
  *	This function sets the Marvell Alaska PHY to the low power mode
  *	given by parameter mode.
  *	The following low power modes are available:
- *		
- *		- Coma Mode (Deep Sleep):
+ *
+ *		- COMA Mode (Deep Sleep):
  *			Power consumption: ~15 - 30 mW
  *			The PHY cannot wake up on its own.
  *
@@ -2113,114 +2133,162 @@
  *		1: error
  */
 int SkGmEnterLowPowerMode(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (e.g. MAC_1) */
 SK_U8	Mode)		/* low power mode */
 {
 	SK_U16	Word;
 	SK_U32	DWord;
+	SK_U32	PowerDownBit;
 	SK_U8	LastMode;
 	int		Ret = 0;
 
-	if (pAC->GIni.GIYukonLite &&
-	    pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+	if (!(CHIP_ID_YUKON_2(pAC) || (pAC->GIni.GIYukonLite &&
+		pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3))) {
 
-		/* save current power mode */
-		LastMode = pAC->GIni.GP[Port].PPhyPowerState;
-		pAC->GIni.GP[Port].PPhyPowerState = Mode;
-
-		switch (Mode) {
-			/* coma mode (deep sleep) */
-			case PHY_PM_DEEP_SLEEP:
-				/* setup General Purpose Control Register */
-				GM_OUT16(IoC, 0, GM_GP_CTRL, GM_GPCR_FL_PASS |
-					GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS);
-
-				/* apply COMA mode workaround */
-				SkGmPhyWrite(pAC, IoC, Port, 29, 0x001f);
-				SkGmPhyWrite(pAC, IoC, Port, 30, 0xfff3);
-
-				SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord);
-
-				SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-				
-				/* Set PHY to Coma Mode */
-				SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord | PCI_PHY_COMA);
-				
-				SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-
-			break;
-			
-			/* IEEE 22.2.4.1.5 compatible power down mode */
-			case PHY_PM_IEEE_POWER_DOWN:
-				/*
-				 * - disable MAC 125 MHz clock
-				 * - allow MAC power down
-				 */
-				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
-				Word |= PHY_M_PC_DIS_125CLK;
-				Word &=	~PHY_M_PC_MAC_POW_UP;
-				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+		return(1);
+	}
 
-				/*
-				 * register changes must be followed by a software
-				 * reset to take effect
-				 */
-				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
-				Word |= PHY_CT_RESET;
-				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
-
-				/* switch IEEE compatible power down mode on */
-				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
-				Word |= PHY_CT_PDOWN;
-				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
-			break;
+	/* save current power mode */
+	LastMode = pAC->GIni.GP[Port].PPhyPowerState;
+	pAC->GIni.GP[Port].PPhyPowerState = Mode;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_POWM, SK_DBGCAT_CTRL,
+		("SkGmEnterLowPowerMode: %u\n", Mode));
+
+	switch (Mode) {
+	/* COMA mode (deep sleep) */
+	case PHY_PM_DEEP_SLEEP:
+		/* clear PHY & MAC reset first */
+		SkGmClearRst(pAC, IoC, Port);
 
-			/* energy detect and energy detect plus mode */
-			case PHY_PM_ENERGY_DETECT:
-			case PHY_PM_ENERGY_DETECT_PLUS:
-				/*
-				 * - disable MAC 125 MHz clock
-				 */
-				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
-				Word |= PHY_M_PC_DIS_125CLK;
-				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
-				
-				/* activate energy detect mode 1 */
-				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
-
-				/* energy detect mode */
-				if (Mode == PHY_PM_ENERGY_DETECT) {
-					Word |= PHY_M_PC_EN_DET;
-				}
-				/* energy detect plus mode */
-				else {
-					Word |= PHY_M_PC_EN_DET_PLUS;
-				}
+		/* setup General Purpose Control Register */
+		GM_OUT16(IoC, Port, GM_GP_CTRL, GM_GPCR_FL_PASS |
+			GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS);
 
-				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+		SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
 
-				/*
-				 * reinitialize the PHY to force a software reset
-				 * which is necessary after the register settings
-				 * for the energy detect modes.
-				 * Furthermore reinitialisation prevents that the
-				 * PHY is running out of a stable state.
-				 */
-				SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
-			break;
+		if (CHIP_ID_YUKON_2(pAC)) {
+			/* set power down bit */
+			PowerDownBit = (Port == MAC_1) ? PCI_Y2_PHY1_POWD :
+				PCI_Y2_PHY2_POWD;
+
+			/* no COMA mode on Yukon-FE */
+			if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
+				/* set IEEE compatible Power Down Mode */
+				Ret = SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PHY_CT_PDOWN);
 
-			/* don't change current power mode */
-			default:
-				pAC->GIni.GP[Port].PPhyPowerState = LastMode;
-				Ret = 1;
-			break;
+				Word = 0;	/* divide clock by 2 */
+			}
+			else {
+				Word = 1;	/* divide clock by 4 */
+			}
+
+			/* Enable Core Clock Division */
+			SK_OUT32(IoC, B2_Y2_CLK_CTRL, Y2_CLK_DIV_VAL(Word) |
+				Y2_CLK_DIV_ENA);
+
+			/* ASF system clock stopped */
+			SK_OUT32(IoC, B28_Y2_ASF_STAT_CMD, Y2_ASF_CLK_HALT);
 		}
-	}
-	/* low power modes are not supported by this chip */
-	else {
+		else {
+			/* apply COMA mode workaround */
+			(void)SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_ADDR, 0x001f);
+
+			Ret = SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xfff3);
+
+			PowerDownBit = PCI_PHY_COMA;
+		}
+
+		SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &DWord);
+
+		/* Set PHY to PowerDown/COMA Mode */
+		SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), DWord | PowerDownBit);
+
+		SK_IN16(IoC, PCI_C(pAC, PCI_PM_CTL_STS), &Word);
+
+		/* switch to D1 state */
+		SK_OUT16(IoC, PCI_C(pAC, PCI_PM_CTL_STS), Word | PCI_PM_STATE_D1);
+
+		break;
+
+	/* IEEE 22.2.4.1.5 compatible power down mode */
+	case PHY_PM_IEEE_POWER_DOWN:
+		/*
+		 * - disable MAC 125 MHz clock
+		 * - allow MAC power down
+		 */
+		Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+		Word |= PHY_M_PC_DIS_125CLK | PHY_M_PC_POL_R_DIS;
+		Word &=	~PHY_M_PC_MAC_POW_UP;
+		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+
+		/*
+		 * register changes must be followed by a software
+		 * reset to take effect
+		 */
+		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+		Word |= PHY_CT_RESET;
+		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+
+		/* switch IEEE compatible power down mode on */
+		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+		Word |= PHY_CT_PDOWN;
+		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+		
+		break;
+
+	/* energy detect and energy detect plus mode */
+	case PHY_PM_ENERGY_DETECT:
+	case PHY_PM_ENERGY_DETECT_PLUS:
+
+		Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+
+		Word |= PHY_M_PC_POL_R_DIS;
+
+		if (!CHIP_ID_YUKON_2(pAC)) {
+			/* disable MAC 125 MHz clock */
+			Word |= PHY_M_PC_DIS_125CLK | PHY_M_PC_POL_R_DIS;
+		}
+
+		/* energy detect mode */
+		if (Mode == PHY_PM_ENERGY_DETECT) {
+			Word |= PHY_M_PC_EN_DET;
+		}
+		/* energy detect plus mode */
+		else {
+			Word |= PHY_M_PC_EN_DET_PLUS;
+		}
+
+		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+
+		/*
+		 * register changes must be followed by a software
+		 * reset to take effect
+		 */
+		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+		Word |= PHY_CT_RESET;
+		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+
+#ifdef XXX
+		/*
+		 * reinitialize the PHY to force a software reset
+		 * which is necessary after the register settings
+		 * for the energy detect modes.
+		 * Furthermore reinitialisation prevents that the
+		 * PHY is running out of a stable state.
+		 */
+		SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
+#endif /* XXX */
+
+		break;
+
+	/* don't change current power mode */
+	default:
+		pAC->GIni.GP[Port].PPhyPowerState = LastMode;
 		Ret = 1;
+		break;
 	}
 
 	return(Ret);
@@ -2231,7 +2299,7 @@
  *
  *	SkGmLeaveLowPowerMode()
  *
- * Description:	
+ * Description:
  *	Leave the current low power mode and switch to normal mode
  *
  * Note:
@@ -2241,115 +2309,149 @@
  *		1:	error
  */
 int SkGmLeaveLowPowerMode(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (e.g. MAC_1) */
 {
 	SK_U32	DWord;
+	SK_U32	PowerDownBit;
 	SK_U16	Word;
 	SK_U8	LastMode;
 	int		Ret = 0;
 
-	if (pAC->GIni.GIYukonLite &&
-		pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+	if (!(CHIP_ID_YUKON_2(pAC) || (pAC->GIni.GIYukonLite &&
+		pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3))) {
 
-		/* save current power mode */
-		LastMode = pAC->GIni.GP[Port].PPhyPowerState;
-		pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
-
-		switch (LastMode) {
-			/* coma mode (deep sleep) */
-			case PHY_PM_DEEP_SLEEP:
-				SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord);
-
-				SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-				
-				/* Release PHY from Coma Mode */
-				SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord & ~PCI_PHY_COMA);
-				
-				SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-				
-				SK_IN32(IoC, B2_GP_IO, &DWord);
-
-				/* set to output */
-				DWord |= (GP_DIR_9 | GP_IO_9);
-
-				/* set PHY reset */
-				SK_OUT32(IoC, B2_GP_IO, DWord);
-
-				DWord &= ~GP_IO_9; /* clear PHY reset (active high) */
-
-				/* clear PHY reset */
-				SK_OUT32(IoC, B2_GP_IO, DWord);
-			break;
-			
-			/* IEEE 22.2.4.1.5 compatible power down mode */
-			case PHY_PM_IEEE_POWER_DOWN:
-				/*
-				 * - enable MAC 125 MHz clock
-				 * - set MAC power up
-				 */
-				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
-				Word &= ~PHY_M_PC_DIS_125CLK;
-				Word |=	PHY_M_PC_MAC_POW_UP;
-				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+		return(1);
+	}
 
-				/*
-				 * register changes must be followed by a software
-				 * reset to take effect
-				 */
-				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
-				Word |= PHY_CT_RESET;
-				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
-
-				/* switch IEEE compatible power down mode off */
-				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
-				Word &= ~PHY_CT_PDOWN;
-				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
-			break;
+	/* save current power mode */
+	LastMode = pAC->GIni.GP[Port].PPhyPowerState;
+	pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
 
-			/* energy detect and energy detect plus mode */
-			case PHY_PM_ENERGY_DETECT:
-			case PHY_PM_ENERGY_DETECT_PLUS:
-				/*
-				 * - enable MAC 125 MHz clock
-				 */
-				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
-				Word &= ~PHY_M_PC_DIS_125CLK;
-				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
-				
-				/* disable energy detect mode */
-				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
-				Word &= ~PHY_M_PC_EN_DET_MSK;
-				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+	SK_DBG_MSG(pAC, SK_DBGMOD_POWM, SK_DBGCAT_CTRL,
+		("SkGmLeaveLowPowerMode: %u\n", LastMode));
 
-				/*
-				 * reinitialize the PHY to force a software reset
-				 * which is necessary after the register settings
-				 * for the energy detect modes.
-				 * Furthermore reinitialisation prevents that the
-				 * PHY is running out of a stable state.
-				 */
-				SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
-			break;
+	switch (LastMode) {
+	/* COMA mode (deep sleep) */
+	case PHY_PM_DEEP_SLEEP:
 
-			/* don't change current power mode */
-			default:
-				pAC->GIni.GP[Port].PPhyPowerState = LastMode;
-				Ret = 1;
-			break;
+		SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &Word);
+
+		/* reset all DState bits */
+		Word &= ~(PCI_PM_STATE_MSK);
+
+		/* switch to D0 state */
+		SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, Word);
+
+		SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+
+		if (CHIP_ID_YUKON_2(pAC)) {
+			/* Disable Core Clock Division */
+			SK_OUT32(IoC, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS);
+
+			/* set power down bit */
+			PowerDownBit = (Port == MAC_1) ? PCI_Y2_PHY1_POWD :
+				PCI_Y2_PHY2_POWD;
 		}
-	}
-	/* low power modes are not supported by this chip */
-	else {
+		else {
+			PowerDownBit = PCI_PHY_COMA;
+		}
+
+		SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &DWord);
+
+		/* Release PHY from PowerDown/COMA Mode */
+		SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), DWord & ~PowerDownBit);
+
+		SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+		if (CHIP_ID_YUKON_2(pAC)) {
+			/* no COMA mode on Yukon-FE */
+			if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
+				/* release IEEE compatible Power Down Mode */
+				Ret = SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PHY_CT_ANE);
+			}
+		}
+		else {
+			SK_IN32(IoC, B2_GP_IO, &DWord);
+
+			/* set to output */
+			DWord |= (GP_DIR_9 | GP_IO_9);
+
+			/* set PHY reset */
+			SK_OUT32(IoC, B2_GP_IO, DWord);
+
+			DWord &= ~GP_IO_9; /* clear PHY reset (active high) */
+
+			/* clear PHY reset */
+			SK_OUT32(IoC, B2_GP_IO, DWord);
+		}
+
+		break;
+
+	/* IEEE 22.2.4.1.5 compatible power down mode */
+	case PHY_PM_IEEE_POWER_DOWN:
+		/*
+		 * - enable MAC 125 MHz clock
+		 * - set MAC power up
+		 */
+		Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+		Word &= ~PHY_M_PC_DIS_125CLK;
+		Word |=	PHY_M_PC_MAC_POW_UP;
+		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+
+		/*
+		 * register changes must be followed by a software
+		 * reset to take effect
+		 */
+		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+		Word |= PHY_CT_RESET;
+		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+
+		/* switch IEEE compatible power down mode off */
+		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+		Word &= ~PHY_CT_PDOWN;
+		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+
+		break;
+
+	/* energy detect and energy detect plus mode */
+	case PHY_PM_ENERGY_DETECT:
+	case PHY_PM_ENERGY_DETECT_PLUS:
+		/*
+		 * - enable MAC 125 MHz clock
+		 */
+		Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+		Word &= ~PHY_M_PC_DIS_125CLK;
+		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+
+		/* disable energy detect mode */
+		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+		Word &= ~PHY_M_PC_EN_DET_MSK;
+		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+
+		/*
+		 * reinitialize the PHY to force a software reset
+		 * which is necessary after the register settings
+		 * for the energy detect modes.
+		 * Furthermore reinitialisation prevents that the
+		 * PHY is running out of a stable state.
+		 */
+		SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
+
+		break;
+
+	/* don't change current power mode */
+	default:
+		pAC->GIni.GP[Port].PPhyPowerState = LastMode;
 		Ret = 1;
+		break;
 	}
 
 	return(Ret);
 
 }	/* SkGmLeaveLowPowerMode */
-#endif /* !SK_SLIM */
-
+#endif /* SK_PHY_LP_MODE */
 
 /******************************************************************************
  *
@@ -2363,23 +2465,27 @@
  *	nothing
  */
 static void SkGmInitPhyMarv(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	DoLoop)		/* Should a Phy LoopBack be set-up? */
 {
 	SK_GEPORT	*pPrt;
+	SK_BOOL		AutoNeg;
 	SK_U16		PhyCtrl;
 	SK_U16		C1000BaseT;
 	SK_U16		AutoNegAdv;
+	SK_U16		SWord;
+#ifndef VCPU
 	SK_U16		ExtPhyCtrl;
 	SK_U16		LedCtrl;
-	SK_BOOL		AutoNeg;
+	SK_U16		LedOver;
 #if defined(SK_DIAG) || defined(DEBUG)
 	SK_U16		PhyStat;
 	SK_U16		PhyStat1;
 	SK_U16		PhySpecStat;
 #endif /* SK_DIAG || DEBUG */
+#endif /* !VCPU */
 
 	pPrt = &pAC->GIni.GP[Port];
 
@@ -2390,33 +2496,59 @@
 	else {
 		AutoNeg = SK_TRUE;
 	}
-	
+
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 		("InitPhyMarv: Port %d, auto-negotiation %s\n",
 		 Port, AutoNeg ? "ON" : "OFF"));
 
-#ifdef VCPU
-	VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n",
-		Port, DoLoop);
-#else /* VCPU */
-	if (DoLoop) {
-		/* Set 'MAC Power up'-bit, set Manual MDI configuration */
-		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
-			PHY_M_PC_MAC_POW_UP);
+#ifndef VCPU
+	if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) {
+
+		if (DoLoop) {
+			/* Set 'MAC Power up'-bit, set Manual MDI configuration */
+			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
+				PHY_M_PC_MAC_POW_UP);
+		}
+		else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO) {
+			/* Read Ext. PHY Specific Control */
+			SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
+
+			ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
+				PHY_M_EC_MAC_S_MSK);
+
+			ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);
+
+			if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) {
+				/* on PHY 88E1111 there is a change for downshift control */
+				ExtPhyCtrl |= PHY_M_EC_M_DSC_2(0);
+			}
+			else {
+				ExtPhyCtrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
+			}
+
+			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl);
+			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+				("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
+		}
 	}
-	else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO) {
-		/* Read Ext. PHY Specific Control */
-		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
-		
-		ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
-			PHY_M_EC_MAC_S_MSK);
-		
-		ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ) |
-			PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
-	
-		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl);
-		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-			("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
+
+	if (!DoLoop && CHIP_ID_YUKON_2(pAC)) {
+		/* Read PHY Specific Control */
+		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &PhyCtrl);
+
+		if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
+			/* Enable Automatic Crossover (!!! Bits 5..4) */
+			PhyCtrl |= (SK_U16)(PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1);
+		}
+		else {
+			/* Disable Energy Detect Mode */
+			PhyCtrl &= ~PHY_M_PC_EN_DET_MSK;
+
+			/* Enable Automatic Crossover */
+			PhyCtrl |= (SK_U16)PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
+		}
+
+		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PhyCtrl);
 	}
 
 	/* Read PHY Control */
@@ -2430,7 +2562,7 @@
 	PhyCtrl |= PHY_CT_RESET;
 	/* Assert software reset */
 	SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
-#endif /* VCPU */
+#endif /* !VCPU */
 
 	PhyCtrl = 0 /* PHY_CT_COL_TST */;
 	C1000BaseT = 0;
@@ -2440,15 +2572,15 @@
 	if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
 		/* enable Manual Master/Slave */
 		C1000BaseT |= PHY_M_1000C_MSE;
-		
+
 		if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
 			C1000BaseT |= PHY_M_1000C_MSC;	/* set it to Master */
 		}
 	}
-	
+
 	/* Auto-negotiation ? */
 	if (!AutoNeg) {
-		
+
 		if (pPrt->PLinkMode == SK_LMODE_FULL) {
 			/* Set Full Duplex Mode */
 			PhyCtrl |= PHY_CT_DUP_MD;
@@ -2463,7 +2595,8 @@
 		switch (pPrt->PLinkSpeed) {
 		case SK_LSPEED_AUTO:
 		case SK_LSPEED_1000MBPS:
-			PhyCtrl |= PHY_CT_SP1000;
+			PhyCtrl |= (((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) ?
+						PHY_CT_SP1000 : PHY_CT_SP100);
 			break;
 		case SK_LSPEED_100MBPS:
 			PhyCtrl |= PHY_CT_SP100;
@@ -2475,31 +2608,59 @@
 				SKERR_HWI_E019MSG);
 		}
 
+		if ((pPrt->PFlowCtrlMode == SK_FLOW_STAT_NONE) ||
+			/* disable Pause also for 10/100 Mbps in half duplex mode */
+			((pPrt->PLinkMode == SK_LMODE_HALF) &&
+			 ((pPrt->PLinkSpeed == SK_LSPEED_STAT_100MBPS) ||
+			  (pPrt->PLinkSpeed == SK_LSPEED_STAT_10MBPS)))) {
+
+			/* set Pause Off */
+			SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_PAUSE_OFF);
+		}
+		else {
+			/* set Pause On */
+			SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_PAUSE_ON);
+		}
+
 		if (!DoLoop) {
 			PhyCtrl |= PHY_CT_RESET;
 		}
 	}
 	else {
 		/* Set Auto-negotiation advertisement */
-		
+
 		if (pAC->GIni.GICopperType) {
 			/* Set Speed capabilities */
 			switch (pPrt->PLinkSpeed) {
 			case SK_LSPEED_AUTO:
-				C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
+				if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) {
+					C1000BaseT |= PHY_M_1000C_AFD;
+#ifdef xSK_DIAG
+					C1000BaseT |= PHY_M_1000C_AHD;
+#endif /* SK_DIAG */
+				}
 				AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
 					PHY_M_AN_10_FD | PHY_M_AN_10_HD;
 				break;
 			case SK_LSPEED_1000MBPS:
-				C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
+				if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) {
+					C1000BaseT |= PHY_M_1000C_AFD;
+#ifdef xSK_DIAG
+					C1000BaseT |= PHY_M_1000C_AHD;
+#endif /* SK_DIAG */
+				}
 				break;
 			case SK_LSPEED_100MBPS:
-				AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
-					/* advertise 10Base-T also */
-					PHY_M_AN_10_FD | PHY_M_AN_10_HD;
+				if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_100MBPS) != 0) {
+					AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
+						/* advertise 10Base-T also */
+						PHY_M_AN_10_FD | PHY_M_AN_10_HD;
+				}
 				break;
 			case SK_LSPEED_10MBPS:
-				AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD;
+				if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_10MBPS) != 0) {
+					AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD;
+				}
 				break;
 			default:
 				SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
@@ -2522,7 +2683,7 @@
 				SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
 					SKERR_HWI_E015MSG);
 			}
-			
+
 			/* Set Flow-control capabilities */
 			switch (pPrt->PFlowCtrlMode) {
 			case SK_FLOW_MODE_NONE:
@@ -2543,7 +2704,7 @@
 			}
 		}
 		else {	/* special defines for FIBER (88E1011S only) */
-			
+
 			/* Set Full/half duplex capabilities */
 			switch (pPrt->PLinkMode) {
 			case SK_LMODE_AUTOHALF:
@@ -2559,7 +2720,7 @@
 				SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
 					SKERR_HWI_E015MSG);
 			}
-			
+
 			/* Set Flow-control capabilities */
 			switch (pPrt->PFlowCtrlMode) {
 			case SK_FLOW_MODE_NONE:
@@ -2585,30 +2746,32 @@
 			PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
 		}
 	}
-	
+
 #ifdef VCPU
 	/*
 	 * E-mail from Gu Lin (08-03-2002):
 	 */
-	
+
 	/* Program PHY register 30 as 16'h0708 for simulation speed up */
 	SkGmPhyWrite(pAC, IoC, Port, 30, 0x0700 /* 0x0708 */);
-	
+
 	VCpuWait(2000);
 
 #else /* VCPU */
-	
-	/* Write 1000Base-T Control Register */
-	SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT);
-	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-		("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT));
-	
+
+	if (pAC->GIni.GIChipId != CHIP_ID_YUKON_FE) {
+		/* Write 1000Base-T Control Register */
+		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT);
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+			("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT));
+	}
+
 	/* Write AutoNeg Advertisement Register */
 	SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 		("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
 #endif /* VCPU */
-	
+
 	if (DoLoop) {
 		/* Set the PHY Loopback bit */
 		PhyCtrl |= PHY_CT_LOOP;
@@ -2616,21 +2779,18 @@
 #ifdef XXX
 		/* Program PHY register 16 as 16'h0400 to force link good */
 		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD);
-#endif /* XXX */
 
-#ifndef VCPU
 		if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) {
 			/* Write Ext. PHY Specific Control */
 			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL,
 				(SK_U16)((pPrt->PLinkSpeed + 2) << 4));
 		}
-#endif /* VCPU */
+#endif /* XXX */
 	}
 #ifdef TEST_ONLY
 	else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) {
-			/* Write PHY Specific Control */
-			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
-				PHY_M_PC_EN_DET_MSK);
+		/* Write PHY Specific Control */
+		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_EN_DET_MSK);
 	}
 #endif
 
@@ -2643,27 +2803,60 @@
 	VCpuWait(2000);
 #else
 
-	LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS);
+	LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS);
 
-	if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0) {
-		LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL;
+	LedOver = 0;
+
+	if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0)  {
+
+		if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
+			/* on 88E3082 these bits are at 11..9 (shifted left) */
+			LedCtrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1;
+
+			SkGmPhyRead(pAC, IoC, Port, PHY_MARV_FE_LED_PAR, &SWord);
+
+			/* delete ACT LED control bits */
+			SWord &= ~PHY_M_FELP_LED1_MSK;
+			/* change ACT LED control to blink mode */
+			SWord |= PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL);
+
+			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_FE_LED_PAR, SWord);
+		}
+		else {
+			/* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
+			LedCtrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
+
+			/* on PHY 88E1111 there is a change for LED control */
+			if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC &&
+				(pAC->GIni.GILedBlinkCtrl & SK_DUAL_LED_ACT_LNK) != 0)  {
+				/* Yukon-EC needs setting of 2 bits: 0,6=11) */
+				LedCtrl |= PHY_M_LEDC_TX_C_LSB;
+			}
+			/* turn off the Rx LED (LED_RX) */
+			LedOver |= PHY_M_LED_MO_RX(MO_LED_OFF);
+		}
 	}
 
 	if ((pAC->GIni.GILedBlinkCtrl & SK_DUP_LED_NORMAL) != 0) {
+		/* disable blink mode (LED_DUPLEX) on collisions */
 		LedCtrl |= PHY_M_LEDC_DP_CTRL;
 	}
-	
+
 	SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl);
 
 	if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) {
 		/* only in forced 100 Mbps mode */
 		if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) {
-
-			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER,
-				PHY_M_LED_MO_100(MO_LED_ON));
+			/* turn on 100 Mbps LED (LED_LINK100) */
+			LedOver |= PHY_M_LED_MO_100(MO_LED_ON);
 		}
 	}
 
+	if (LedOver != 0) {
+		/* set Manual LED Override */
+		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER, LedOver);
+	}
+
 #ifdef SK_DIAG
 	c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl);
 	c_print("Set 1000 B-T=0x%04X\n", C1000BaseT);
@@ -2676,30 +2869,33 @@
 	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 		("PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
-	
-	/* Read 1000Base-T Control Register */
-	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT);
-	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-		("1000B-T Ctrl =0x%04X\n", C1000BaseT));
-	
+
 	/* Read AutoNeg Advertisement Register */
 	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 		("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
-	
-	/* Read Ext. PHY Specific Control */
-	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
-	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-		("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
-	
+
+	if (pAC->GIni.GIChipId != CHIP_ID_YUKON_FE) {
+		/* Read 1000Base-T Control Register */
+		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT);
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+			("1000B-T Ctrl =0x%04X\n", C1000BaseT));
+
+		/* Read Ext. PHY Specific Control */
+		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+			("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
+	}
+
 	/* Read PHY Status */
 	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 		("PHY Stat Reg.=0x%04X\n", PhyStat));
+
 	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 		("PHY Stat Reg.=0x%04X\n", PhyStat1));
-	
+
 	/* Read PHY Specific Status */
 	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
@@ -2716,6 +2912,9 @@
 	c_print("PHY Spec Reg=0x%04X\n", PhySpecStat);
 #endif /* SK_DIAG */
 
+	/* Enable all PHY interrupts */
+	SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK,
+		(SK_U16)PHY_M_DEF_MSK);
 #endif /* VCPU */
 
 }	/* SkGmInitPhyMarv */
@@ -2735,8 +2934,8 @@
  *	nothing
  */
 static void SkXmInitPhyLone(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	DoLoop)		/* Should a Phy LoopBack be set-up? */
 {
@@ -2754,7 +2953,7 @@
 	/* manually Master/Slave ? */
 	if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
 		Ctrl2 |= PHY_L_1000C_MSE;
-		
+
 		if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
 			Ctrl2 |= PHY_L_1000C_MSC;
 		}
@@ -2776,7 +2975,6 @@
 		if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
 			Ctrl2 |= PHY_L_1000C_MSE;	/* set it to Slave */
 		}
-
 		/*
 		 * Do NOT enable Auto-negotiation here. This would hold
 		 * the link down because no IDLES are transmitted
@@ -2825,12 +3023,12 @@
 		/* Restart Auto-negotiation */
 		Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;
 	}
-	
+
 	/* Write 1000Base-T Control Register */
 	SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 		("1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
-	
+
 	/* Write AutoNeg Advertisement Register */
 	SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
@@ -2860,8 +3058,8 @@
  *	nothing
  */
 static void SkXmInitPhyNat(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	DoLoop)		/* Should a Phy LoopBack be set-up? */
 {
@@ -2882,8 +3080,8 @@
  *	nothing
  */
 void SkMacInitPhy(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	DoLoop)		/* Should a Phy LoopBack be set-up? */
 {
@@ -2893,7 +3091,7 @@
 
 #ifdef GENESIS
 	if (pAC->GIni.GIGenesis) {
-		
+
 		switch (pPrt->PhyType) {
 		case SK_PHY_XMAC:
 			SkXmInitPhyXmac(pAC, IoC, Port, DoLoop);
@@ -2912,10 +3110,10 @@
 		}
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
-		
+
 		SkGmInitPhyMarv(pAC, IoC, Port, DoLoop);
 	}
 #endif /* YUKON */
@@ -2937,8 +3135,8 @@
  *	SK_AND_OTHER 	Other error happened
  */
 static int SkXmAutoNegDoneXmac(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
@@ -2956,10 +3154,10 @@
 
 	if ((LPAb & PHY_X_AN_RFB) != 0) {
 		/* At least one of the remote fault bit is set */
-		/* Error */
-		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 			("AutoNegFail: Remote fault bit set Port %d\n", Port));
 		pPrt->PAutoNegFail = SK_TRUE;
+
 		return(SK_AND_OTHER);
 	}
 
@@ -2972,7 +3170,7 @@
 	}
 	else {
 		/* Error */
-		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 			("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
 		pPrt->PAutoNegFail = SK_TRUE;
 		return(SK_AND_DUP_CAP);
@@ -2988,12 +3186,12 @@
 		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
 	}
 	else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM &&
-		   (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) {
+		     (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) {
 		/* Enable PAUSE receive, disable PAUSE transmit */
 		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
 	}
 	else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND &&
-		   (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) {
+		     (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) {
 		/* Disable PAUSE receive, enable PAUSE transmit */
 		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
 	}
@@ -3020,8 +3218,8 @@
  *	SK_AND_OTHER 	Other error happened
  */
 static int SkXmAutoNegDoneBcom(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
@@ -3043,12 +3241,12 @@
 01-Sep-2000 RA;:;:
 	SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
 #endif	/* 0 */
-	
+
 	SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &AuxStat);
 
 	if ((LPAb & PHY_B_AN_RF) != 0) {
 		/* Remote fault bit is set: Error */
-		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 			("AutoNegFail: Remote fault bit set Port %d\n", Port));
 		pPrt->PAutoNegFail = SK_TRUE;
 		return(SK_AND_OTHER);
@@ -3063,23 +3261,23 @@
 	}
 	else {
 		/* Error */
-		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 			("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
 		pPrt->PAutoNegFail = SK_TRUE;
 		return(SK_AND_DUP_CAP);
 	}
-	
+
 #ifdef TEST_ONLY
 01-Sep-2000 RA;:;:
 	/* Check Master/Slave resolution */
 	if ((ResAb & PHY_B_1000S_MSF) != 0) {
-		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 			("Master/Slave Fault Port %d\n", Port));
 		pPrt->PAutoNegFail = SK_TRUE;
 		pPrt->PMSStatus = SK_MS_STAT_FAULT;
 		return(SK_AND_OTHER);
 	}
-	
+
 	pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
 		SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
 #endif	/* 0 */
@@ -3123,8 +3321,8 @@
  *	SK_AND_OTHER 	Other error happened
  */
 static int SkGmAutoNegDoneMarv(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
@@ -3140,76 +3338,102 @@
 	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 		("Link P.Abil.=0x%04X\n", LPAb));
-	
+
 	if ((LPAb & PHY_M_AN_RF) != 0) {
-		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 			("AutoNegFail: Remote fault bit set Port %d\n", Port));
 		pPrt->PAutoNegFail = SK_TRUE;
 		return(SK_AND_OTHER);
 	}
 
-	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
-	
-	/* Check Master/Slave resolution */
-	if ((ResAb & PHY_B_1000S_MSF) != 0) {
-		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-			("Master/Slave Fault Port %d\n", Port));
-		pPrt->PAutoNegFail = SK_TRUE;
-		pPrt->PMSStatus = SK_MS_STAT_FAULT;
-		return(SK_AND_OTHER);
+	if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) {
+
+		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
+
+		/* Check Master/Slave resolution */
+		if ((ResAb & PHY_B_1000S_MSF) != 0) {
+			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+				("Master/Slave Fault Port %d\n", Port));
+			pPrt->PAutoNegFail = SK_TRUE;
+			pPrt->PMSStatus = SK_MS_STAT_FAULT;
+			return(SK_AND_OTHER);
+		}
 	}
-	
+
 	pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
 		(SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE;
-	
+
 	/* Read PHY Specific Status */
 	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &AuxStat);
-	
+
 	/* Check Speed & Duplex resolved */
 	if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) {
-		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 			("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port));
 		pPrt->PAutoNegFail = SK_TRUE;
 		pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
 		return(SK_AND_DUP_CAP);
 	}
-	
+
 	if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) {
 		pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
 	}
 	else {
 		pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
 	}
-	
-	/* Check PAUSE mismatch ??? */
-	/* We are using IEEE 802.3z/D5.0 Table 37-4 */
-	if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) {
-		/* Symmetric PAUSE */
-		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
+
+	if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
+		/* set used link speed */
+		pPrt->PLinkSpeedUsed = ((AuxStat & PHY_M_PS_SPEED_100) != 0) ?
+			(SK_U8)SK_LSPEED_STAT_100MBPS : (SK_U8)SK_LSPEED_STAT_10MBPS;
 	}
-	else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_RX_P_EN) {
-		/* Enable PAUSE receive, disable PAUSE transmit */
-		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
+	else {
+		/* set used link speed */
+		switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) {
+		case (unsigned)PHY_M_PS_SPEED_1000:
+			pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
+			break;
+		case PHY_M_PS_SPEED_100:
+			pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
+			break;
+		default:
+			pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
+		}
+
+		if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) {
+			/* Tx & Rx Pause Enabled bits are at 9..8 */
+			AuxStat >>= 6;
+		}
+
+		/* We are using IEEE 802.3z/D5.0 Table 37-4 */
+		if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) {
+			/* Symmetric PAUSE */
+			pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
+		}
+		else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_RX_P_EN) {
+			/* Enable PAUSE receive, disable PAUSE transmit */
+			pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
+		}
+		else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_TX_P_EN) {
+			/* Disable PAUSE receive, enable PAUSE transmit */
+			pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
+		}
+		else {
+			/* PAUSE mismatch -> no PAUSE */
+			pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
+		}
 	}
-	else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_TX_P_EN) {
-		/* Disable PAUSE receive, enable PAUSE transmit */
-		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
+
+	if ((pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE) ||
+		/* disable Pause also for 10/100 Mbps in half duplex mode */
+		((pPrt->PLinkSpeedUsed < (SK_U8)SK_LSPEED_STAT_1000MBPS) &&
+		 pPrt->PLinkModeStatus == (SK_U8)SK_LMODE_STAT_AUTOHALF)) {
+		/* set Pause Off */
+		SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_PAUSE_OFF);
 	}
 	else {
-		/* PAUSE mismatch -> no PAUSE */
-		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
-	}
-	
-	/* set used link speed */
-	switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) {
-	case (unsigned)PHY_M_PS_SPEED_1000:
-		pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
-		break;
-	case PHY_M_PS_SPEED_100:
-		pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
-		break;
-	default:
-		pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
+		/* set Pause On */
+		SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_PAUSE_ON);
 	}
 
 	return(SK_AND_OK);
@@ -3231,8 +3455,8 @@
  *	SK_AND_OTHER 	Other error happened
  */
 static int SkXmAutoNegDoneLone(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
@@ -3251,8 +3475,7 @@
 
 	if ((LPAb & PHY_L_AN_RF) != 0) {
 		/* Remote fault bit is set */
-		/* Error */
-		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 			("AutoNegFail: Remote fault bit set Port %d\n", Port));
 		pPrt->PAutoNegFail = SK_TRUE;
 		return(SK_AND_OTHER);
@@ -3265,11 +3488,11 @@
 	else {
 		pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
 	}
-	
+
 	/* Check Master/Slave resolution */
 	if ((ResAb & PHY_L_1000S_MSF) != 0) {
 		/* Error */
-		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 			("Master/Slave Fault Port %d\n", Port));
 		pPrt->PAutoNegFail = SK_TRUE;
 		pPrt->PMSStatus = SK_MS_STAT_FAULT;
@@ -3286,7 +3509,7 @@
 	/* We are using IEEE 802.3z/D5.0 Table 37-4 */
 	/* we must manually resolve the abilities here */
 	pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
-	
+
 	switch (pPrt->PFlowCtrlMode) {
 	case SK_FLOW_MODE_NONE:
 		/* default */
@@ -3319,7 +3542,7 @@
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
 			SKERR_HWI_E016MSG);
 	}
-	
+
 	return(SK_AND_OK);
 }	/* SkXmAutoNegDoneLone */
 
@@ -3337,8 +3560,8 @@
  *	SK_AND_OTHER 	Other error happened
  */
 static int SkXmAutoNegDoneNat(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 /* todo: National */
@@ -3359,8 +3582,8 @@
  *	SK_AND_OTHER 	Other error happened
  */
 int	SkMacAutoNegDone(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
@@ -3372,9 +3595,9 @@
 
 #ifdef GENESIS
 	if (pAC->GIni.GIGenesis) {
-		
+
 		switch (pPrt->PhyType) {
-		
+
 		case SK_PHY_XMAC:
 			Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port);
 			break;
@@ -3394,26 +3617,26 @@
 		}
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
-		
+
 		Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port);
 	}
 #endif /* YUKON */
-	
+
 	if (Rtv != SK_AND_OK) {
 		return(Rtv);
 	}
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 		("AutoNeg done Port %d\n", Port));
-	
+
 	/* We checked everything and may now enable the link */
 	pPrt->PAutoNegFail = SK_FALSE;
 
 	SkMacRxTxEnable(pAC, IoC, Port);
-	
+
 	return(SK_AND_OK);
 }	/* SkMacAutoNegDone */
 
@@ -3431,7 +3654,7 @@
  */
 static void SkXmSetRxTxEn(
 SK_AC	*pAC,		/* Adapter Context */
-SK_IOC	IoC,		/* IO context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 int		Para)		/* Parameter to set: MAC or PHY LoopBack, Duplex Mode */
 {
@@ -3456,7 +3679,7 @@
 		Word &= ~XM_MMU_GMII_LOOP;
 		break;
 	}
-	
+
 	switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) {
 	case SK_PHY_FULLD_ON:
 		Word |= XM_MMU_GMII_FD;
@@ -3465,7 +3688,7 @@
 		Word &= ~XM_MMU_GMII_FD;
 		break;
 	}
-	
+
 	XM_OUT16(IoC, Port, XM_MMU_CMD, Word | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
 
 	/* dummy read to ensure writing */
@@ -3488,12 +3711,12 @@
  */
 static void SkGmSetRxTxEn(
 SK_AC	*pAC,		/* Adapter Context */
-SK_IOC	IoC,		/* IO context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 int		Para)		/* Parameter to set: MAC LoopBack, Duplex Mode */
 {
 	SK_U16	Ctrl;
-	
+
 	GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl);
 
 	switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) {
@@ -3513,12 +3736,13 @@
 		Ctrl &= ~GM_GPCR_DUP_FULL;
 		break;
 	}
-	
-    GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Ctrl | GM_GPCR_RX_ENA |
-		GM_GPCR_TX_ENA));
 
+	GM_OUT16(IoC, Port, GM_GP_CTRL, Ctrl | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
+
+#ifdef XXX
 	/* dummy read to ensure writing */
 	GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl);
+#endif /* XXX */
 
 }	/* SkGmSetRxTxEn */
 #endif /* YUKON */
@@ -3535,20 +3759,20 @@
  */
 void SkMacSetRxTxEn(
 SK_AC	*pAC,		/* Adapter Context */
-SK_IOC	IoC,		/* IO context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 int		Para)
 {
 #ifdef GENESIS
 	if (pAC->GIni.GIGenesis) {
-		
+
 		SkXmSetRxTxEn(pAC, IoC, Port, Para);
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
-		
+
 		SkGmSetRxTxEn(pAC, IoC, Port, Para);
 	}
 #endif /* YUKON */
@@ -3568,8 +3792,8 @@
  *	!= 0	Error happened
  */
 int SkMacRxTxEnable(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
@@ -3587,9 +3811,9 @@
 	}
 
 	if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF ||
-	     pPrt->PLinkMode == SK_LMODE_AUTOFULL ||
-	     pPrt->PLinkMode == SK_LMODE_AUTOBOTH) &&
-	     pPrt->PAutoNegFail) {
+		 pPrt->PLinkMode == SK_LMODE_AUTOFULL ||
+		 pPrt->PLinkMode == SK_LMODE_AUTOBOTH) &&
+		 pPrt->PAutoNegFail) {
 		/* Auto-negotiation is not done or failed */
 		return(0);
 	}
@@ -3598,9 +3822,9 @@
 	if (pAC->GIni.GIGenesis) {
 		/* set Duplex Mode and Pause Mode */
 		SkXmInitDupMd(pAC, IoC, Port);
-		
+
 		SkXmInitPauseMd(pAC, IoC, Port);
-	
+
 		/*
 		 * Initialize the Interrupt Mask Register. Default IRQs are...
 		 *	- Link Asynchronous Event
@@ -3616,23 +3840,23 @@
 		/* add IRQ for Receive FIFO Overflow */
 		IntMask &= ~XM_IS_RXF_OV;
 #endif /* DEBUG */
-		
+
 		if (pPrt->PhyType != SK_PHY_XMAC) {
 			/* disable GP0 interrupt bit */
 			IntMask |= XM_IS_INP_ASS;
 		}
 		XM_OUT16(IoC, Port, XM_IMSK, IntMask);
-	
+
 		/* get MMU Command Reg. */
 		XM_IN16(IoC, Port, XM_MMU_CMD, &Reg);
-		
+
 		if (pPrt->PhyType != SK_PHY_XMAC &&
 			(pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
 			 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) {
 			/* set to Full Duplex */
 			Reg |= XM_MMU_GMII_FD;
 		}
-		
+
 		switch (pPrt->PhyType) {
 		case SK_PHY_BCOM:
 			/*
@@ -3642,7 +3866,7 @@
 			SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
 			SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
 				(SK_U16)(SWord & ~PHY_B_AC_DIS_PM));
-            SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK,
+			SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK,
 				(SK_U16)PHY_B_DEF_MSK);
 			break;
 #ifdef OTHER_PHY
@@ -3656,12 +3880,12 @@
 			break;
 #endif /* OTHER_PHY */
 		}
-		
+
 		/* enable Rx/Tx */
 		XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
 		/*
@@ -3676,30 +3900,28 @@
 		/* add IRQ for Receive FIFO Overrun */
 		IntMask |= GM_IS_RX_FF_OR;
 #endif /* DEBUG */
-		
-		SK_OUT8(IoC, GMAC_IRQ_MSK, (SK_U8)IntMask);
-		
+
+		SK_OUT8(IoC, MR_ADDR(Port, GMAC_IRQ_MSK), (SK_U8)IntMask);
+
 		/* get General Purpose Control */
 		GM_IN16(IoC, Port, GM_GP_CTRL, &Reg);
-		
+
 		if (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
 			pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) {
 			/* set to Full Duplex */
 			Reg |= GM_GPCR_DUP_FULL;
 		}
-		
+
 		/* enable Rx/Tx */
-        GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Reg | GM_GPCR_RX_ENA |
-			GM_GPCR_TX_ENA));
+		GM_OUT16(IoC, Port, GM_GP_CTRL, Reg | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
 
-#ifndef VCPU
-		/* Enable all PHY interrupts */
-        SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK,
-			(SK_U16)PHY_M_DEF_MSK);
-#endif /* VCPU */
+#ifdef XXX
+		/* dummy read to ensure writing */
+		GM_IN16(IoC, Port, GM_GP_CTRL, &Reg);
+#endif /* XXX */
 	}
 #endif /* YUKON */
-					
+
 	return(0);
 
 }	/* SkMacRxTxEnable */
@@ -3715,33 +3937,38 @@
  */
 void SkMacRxTxDisable(
 SK_AC	*pAC,		/* Adapter Context */
-SK_IOC	IoC,		/* IO context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_U16	Word;
 
 #ifdef GENESIS
 	if (pAC->GIni.GIGenesis) {
-		
+
 		XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
-		
-		XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
-	
+
+		Word &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
+
+		XM_OUT16(IoC, Port, XM_MMU_CMD, Word);
+
 		/* dummy read to ensure writing */
 		XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
-		
+
 		GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
 
-        GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Word & ~(GM_GPCR_RX_ENA |
-			GM_GPCR_TX_ENA)));
+		Word &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
+
+		GM_OUT16(IoC, Port, GM_GP_CTRL, Word);
 
+#ifdef XXX
 		/* dummy read to ensure writing */
 		GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
+#endif /* XXX */
 	}
 #endif /* YUKON */
 
@@ -3758,7 +3985,7 @@
  */
 void SkMacIrqDisable(
 SK_AC	*pAC,		/* Adapter Context */
-SK_IOC	IoC,		/* IO context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
@@ -3770,10 +3997,10 @@
 
 #ifdef GENESIS
 	if (pAC->GIni.GIGenesis) {
-		
+
 		/* disable all XMAC IRQs */
-		XM_OUT16(IoC, Port, XM_IMSK, 0xffff);	
-		
+		XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
+
 		/* Disable all PHY interrupts */
 		switch (pPrt->PhyType) {
 			case SK_PHY_BCOM:
@@ -3800,16 +4027,16 @@
 		}
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
 		/* disable all GMAC IRQs */
-		SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
-		
+		SK_OUT8(IoC, MR_ADDR(Port, GMAC_IRQ_MSK), 0);
+
 #ifndef VCPU
 		/* Disable all PHY interrupts */
 		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
-#endif /* VCPU */
+#endif /* !VCPU */
 	}
 #endif /* YUKON */
 
@@ -3827,8 +4054,8 @@
  *	nothing
  */
 void SkXmSendCont(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
 int		Port,	/* Port Index (MAC_1 + n) */
 SK_BOOL	Enable)	/* Enable / Disable */
 {
@@ -3858,8 +4085,8 @@
  *	nothing
  */
 void SkMacTimeStamp(
-SK_AC	*pAC,	/* adapter context */
-SK_IOC	IoC,	/* IO context */
+SK_AC	*pAC,	/* Adapter Context */
+SK_IOC	IoC,	/* I/O Context */
 int		Port,	/* Port Index (MAC_1 + n) */
 SK_BOOL	Enable)	/* Enable / Disable */
 {
@@ -3904,8 +4131,8 @@
  *	is set true.
  */
 void SkXmAutoNegLipaXmac(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 SK_U16	IStatus)	/* Interrupt Status word to analyse */
 {
@@ -3934,8 +4161,8 @@
  *	is set true.
  */
 void SkMacAutoNegLipaPhy(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 SK_U16	PhyStat)	/* PHY Status word to analyse */
 {
@@ -3975,8 +4202,8 @@
  *	nothing
  */
 void SkXmIrq(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
@@ -3985,12 +4212,12 @@
 	SK_U16		IStatus2;
 #ifdef SK_SLIM
     SK_U64      OverflowStatus;
-#endif	
+#endif
 
 	pPrt = &pAC->GIni.GP[Port];
-	
+
 	XM_IN16(IoC, Port, XM_ISRC, &IStatus);
-	
+
 	/* LinkPartner Auto-negable? */
 	if (pPrt->PhyType == SK_PHY_XMAC) {
 		SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus);
@@ -4001,7 +4228,7 @@
 			XM_IS_RX_PAGE | XM_IS_TX_PAGE |
 			XM_IS_AND | XM_IS_INP_ASS);
 	}
-	
+
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
 		("XmacIrq Port %d Isr 0x%04X\n", Port, IStatus));
 
@@ -4111,40 +4338,40 @@
  *	nothing
  */
 void SkGmIrq(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
 	SK_U8		IStatus;	/* Interrupt status */
 #ifdef SK_SLIM
-    SK_U64      OverflowStatus;
+	SK_U64		OverflowStatus;
 #else
 	SK_EVPARA	Para;
-#endif	
+#endif
 
 	pPrt = &pAC->GIni.GP[Port];
-	
-	SK_IN8(IoC, GMAC_IRQ_SRC, &IStatus);
-	
+
+	SK_IN8(IoC, MR_ADDR(Port, GMAC_IRQ_SRC), &IStatus);
+
 #ifdef XXX
 	/* LinkPartner Auto-negable? */
 	SkMacAutoNegLipaPhy(pAC, IoC, Port, IStatus);
 #endif /* XXX */
-	
+
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
-		("GmacIrq Port %d Isr 0x%04X\n", Port, IStatus));
+		("GmacIrq Port %d Isr 0x%02X\n", Port, IStatus));
 
 	/* Combined Tx & Rx Counter Overflow SIRQ Event */
 	if (IStatus & (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV)) {
 		/* these IRQs will be cleared by reading GMACs register */
 #ifdef SK_SLIM
-        SkGmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus);
+		SkGmOverflowStatus(pAC, IoC, Port, (SK_U16)IStatus, &OverflowStatus);
 #else
 		Para.Para32[0] = (SK_U32)Port;
 		Para.Para32[1] = (SK_U32)IStatus;
 		SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
-#endif		
+#endif
 	}
 
 	if (IStatus & GM_IS_RX_FF_OR) {
@@ -4183,8 +4410,8 @@
  *	nothing
  */
 void SkMacIrq(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 #ifdef GENESIS
@@ -4193,7 +4420,7 @@
 		SkXmIrq(pAC, IoC, Port);
 	}
 #endif /* GENESIS */
-	
+
 #ifdef YUKON
 	if (pAC->GIni.GIYukon) {
 		/* IRQ from GMAC */
@@ -4220,8 +4447,8 @@
  *	1:  something went wrong
  */
 int SkXmUpdateStats(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 unsigned int Port)	/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
@@ -4243,7 +4470,7 @@
 	do {
 
 		XM_IN16(IoC, Port, XM_STAT_CMD, &StatReg);
-		
+
 		if (++WaitIndex > 10) {
 
 			SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E021, SKERR_HWI_E021MSG);
@@ -4251,7 +4478,7 @@
 			return(1);
 		}
 	} while ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) != 0);
-	
+
 	return(0);
 }	/* SkXmUpdateStats */
 
@@ -4270,19 +4497,19 @@
  *	1:  something went wrong
  */
 int SkXmMacStatistic(
-SK_AC	*pAC,			/* adapter context */
-SK_IOC	IoC,			/* IO context */
+SK_AC	*pAC,			/* Adapter Context */
+SK_IOC	IoC,			/* I/O Context */
 unsigned int Port,		/* Port Index (MAC_1 + n) */
 SK_U16	StatAddr,		/* MIB counter base address */
-SK_U32	SK_FAR *pVal)	/* ptr to return statistic value */
+SK_U32	SK_FAR *pVal)	/* Pointer to return statistic value */
 {
 	if ((StatAddr < XM_TXF_OK) || (StatAddr > XM_RXF_MAX_SZ)) {
-		
+
 		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
-		
+
 		return(1);
 	}
-	
+
 	XM_IN32(IoC, Port, StatAddr, pVal);
 
 	return(0);
@@ -4301,12 +4528,12 @@
  *	1:  something went wrong
  */
 int SkXmResetCounter(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 unsigned int Port)	/* Port Index (MAC_1 + n) */
 {
 	XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
-	/* Clear two times according to Errata #3 */
+	/* Clear two times according to XMAC Errata #3 */
 	XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
 
 	return(0);
@@ -4333,11 +4560,11 @@
  *	1:  something went wrong
  */
 int SkXmOverflowStatus(
-SK_AC	*pAC,				/* adapter context */
-SK_IOC	IoC,				/* IO context */
+SK_AC	*pAC,				/* Adapter Context */
+SK_IOC	IoC,				/* I/O Context */
 unsigned int Port,			/* Port Index (MAC_1 + n) */
-SK_U16	IStatus,			/* Interupt Status from MAC */
-SK_U64	SK_FAR *pStatus)	/* ptr for return overflow status value */
+SK_U16	IStatus,			/* Interrupt Status from MAC */
+SK_U64	SK_FAR *pStatus)	/* Pointer for return overflow status value */
 {
 	SK_U64	Status;	/* Overflow status */
 	SK_U32	RegVal;
@@ -4349,7 +4576,7 @@
 		XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal);
 		Status |= (SK_U64)RegVal << 32;
 	}
-	
+
 	if ((IStatus & XM_IS_TXC_OV) != 0) {
 
 		XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal);
@@ -4376,8 +4603,8 @@
  *	1:  something went wrong
  */
 int SkGmUpdateStats(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 unsigned int Port)	/* Port Index (MAC_1 + n) */
 {
 	return(0);
@@ -4398,24 +4625,27 @@
  *	1:  something went wrong
  */
 int SkGmMacStatistic(
-SK_AC	*pAC,			/* adapter context */
-SK_IOC	IoC,			/* IO context */
+SK_AC	*pAC,			/* Adapter Context */
+SK_IOC	IoC,			/* I/O Context */
 unsigned int Port,		/* Port Index (MAC_1 + n) */
 SK_U16	StatAddr,		/* MIB counter base address */
-SK_U32	SK_FAR *pVal)	/* ptr to return statistic value */
+SK_U32	SK_FAR *pVal)	/* Pointer to return statistic value */
 {
 
 	if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) {
-		
+
 		SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
-		
-		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
 			("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr));
 		return(1);
 	}
-		
+
 	GM_IN32(IoC, Port, StatAddr, pVal);
 
+	/* dummy read */
+	SK_IN16(IoC, B0_RAP, &StatAddr);
+
 	return(0);
 }	/* SkGmMacStatistic */
 
@@ -4432,8 +4662,8 @@
  *	1:  something went wrong
  */
 int SkGmResetCounter(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,		/* I/O Context */
 unsigned int Port)	/* Port Index (MAC_1 + n) */
 {
 	SK_U16	Reg;	/* Phy Address Register */
@@ -4444,16 +4674,16 @@
 
 	/* set MIB Clear Counter Mode */
 	GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg | GM_PAR_MIB_CLR);
-	
+
 	/* read all MIB Counters with Clear Mode set */
 	for (i = 0; i < GM_MIB_CNT_SIZE; i++) {
 		/* the reset is performed only when the lower 16 bits are read */
 		GM_IN16(IoC, Port, GM_MIB_CNT_BASE + 8*i, &Word);
 	}
-	
+
 	/* clear MIB Clear Counter Mode */
 	GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg);
-	
+
 	return(0);
 }	/* SkGmResetCounter */
 
@@ -4467,48 +4697,62 @@
  *	resulting counter overflow status is written to <pStatus>, whereas the
  *	the following bit coding is used:
  *	63:56 - unused
- *	55:48 - TxRx interrupt register bit7:0
- *	32:47 - Rx interrupt register
+ *	55:48 - TxRx interrupt register bit 7:0
+ *	47:32 - Rx interrupt register
  *	31:24 - unused
- *	23:16 - TxRx interrupt register bit15:8
- *	15:0  - Tx interrupt register
+ *	23:16 - TxRx interrupt register bit 15:8
+ *	15: 0 - Tx interrupt register
  *
  * Returns:
  *	0:  success
  *	1:  something went wrong
  */
 int SkGmOverflowStatus(
-SK_AC	*pAC,				/* adapter context */
-SK_IOC	IoC,				/* IO context */
+SK_AC	*pAC,				/* Adapter Context */
+SK_IOC	IoC,				/* I/O Context */
 unsigned int Port,			/* Port Index (MAC_1 + n) */
-SK_U16	IStatus,			/* Interupt Status from MAC */
-SK_U64	SK_FAR *pStatus)	/* ptr for return overflow status value */
+SK_U16	IStatus,			/* Interrupt Status from MAC */
+SK_U64	SK_FAR *pStatus)	/* Pointer for return overflow status value */
 {
-	SK_U64	Status;		/* Overflow status */
 	SK_U16	RegVal;
+#ifndef SK_SLIM
+	SK_U64	Status;		/* Overflow status */
 
 	Status = 0;
+#endif /* !SK_SLIM */
 
 	if ((IStatus & GM_IS_RX_CO_OV) != 0) {
 		/* this register is self-clearing after read */
 		GM_IN16(IoC, Port, GM_RX_IRQ_SRC, &RegVal);
+
+#ifndef SK_SLIM
 		Status |= (SK_U64)RegVal << 32;
+#endif /* !SK_SLIM */
 	}
-	
+
 	if ((IStatus & GM_IS_TX_CO_OV) != 0) {
 		/* this register is self-clearing after read */
 		GM_IN16(IoC, Port, GM_TX_IRQ_SRC, &RegVal);
+
+#ifndef SK_SLIM
 		Status |= (SK_U64)RegVal;
+#endif /* !SK_SLIM */
 	}
-	
+
 	/* this register is self-clearing after read */
 	GM_IN16(IoC, Port, GM_TR_IRQ_SRC, &RegVal);
+
+#ifndef SK_SLIM
 	/* Rx overflow interrupt register bits (LoByte)*/
 	Status |= (SK_U64)((SK_U8)RegVal) << 48;
 	/* Tx overflow interrupt register bits (HiByte)*/
 	Status |= (SK_U64)(RegVal >> 8) << 16;
 
 	*pStatus = Status;
+#endif /* !SK_SLIM */
+
+	/* dummy read */
+	SK_IN16(IoC, B0_RAP, &RegVal);
 
 	return(0);
 }	/* SkGmOverflowStatus */
@@ -4524,57 +4768,88 @@
  *  gets the results if 'StartTest' is true
  *
  * NOTE:	this test is meaningful only when link is down
- *	
+ *
  * Returns:
  *	0:  success
  *	1:	no YUKON copper
  *	2:	test in progress
  */
 int SkGmCableDiagStatus(
-SK_AC	*pAC,		/* adapter context */
-SK_IOC	IoC,   		/* IO context */
+SK_AC	*pAC,		/* Adapter Context */
+SK_IOC	IoC,   		/* I/O Context */
 int		Port,		/* Port Index (MAC_1 + n) */
 SK_BOOL	StartTest)	/* flag for start / get result */
 {
 	int		i;
+	int		CableDiagOffs;
+	int		MdiPairs;
+	SK_BOOL	FastEthernet;
 	SK_U16	RegVal;
 	SK_GEPORT	*pPrt;
 
 	pPrt = &pAC->GIni.GP[Port];
 
 	if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
-		
+
 		return(1);
 	}
 
+	if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
+
+		CableDiagOffs = PHY_MARV_FE_VCT_TX;
+		FastEthernet = SK_TRUE;
+		MdiPairs = 2;
+	}
+	else {
+		CableDiagOffs = PHY_MARV_CABLE_DIAG;
+		FastEthernet = SK_FALSE;
+		MdiPairs = 4;
+	}
+
 	if (StartTest) {
 		/* only start the cable test */
-		if ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4) {
-			/* apply TDR workaround from Marvell */
-			SkGmPhyWrite(pAC, IoC, Port, 29, 0x001e);
-			
-			SkGmPhyWrite(pAC, IoC, Port, 30, 0xcc00);
-			SkGmPhyWrite(pAC, IoC, Port, 30, 0xc800);
-			SkGmPhyWrite(pAC, IoC, Port, 30, 0xc400);
-			SkGmPhyWrite(pAC, IoC, Port, 30, 0xc000);
-			SkGmPhyWrite(pAC, IoC, Port, 30, 0xc100);
-		}
+		if (!FastEthernet) {
 
-		/* set address to 0 for MDI[0] */
-		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0);
+			if ((((pPrt->PhyId1 & PHY_I1_MOD_NUM) >> 4) == 2) &&
+				 ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4)) {
+				/* apply TDR workaround for model 2, rev. < 4 */
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_ADDR, 0x001e);
+
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xcc00);
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xc800);
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xc400);
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xc000);
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xc100);
+			}
+
+			if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) {
+				/* set address to 1 for Page 1 */
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 1);
+	
+				/* disable waiting period */
+				SkGmPhyWrite(pAC, IoC, Port, CableDiagOffs,
+					PHY_M_CABD_DIS_WAIT);
+			}
+	
+			/* set address to 0 for MDI[0] (Page 0) */
+			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0);
+		}
+		else {
+			SkGmPhyRead(pAC, IoC, Port, PHY_MARV_FE_SPEC_2, &RegVal);
+			/* disable waiting period */
+			RegVal |= PHY_M_FESC_DIS_WAIT;
 
-		/* Read Cable Diagnostic Reg */
-		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
+			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_FE_SPEC_2, RegVal);
+		}
 
 		/* start Cable Diagnostic Test */
-		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CABLE_DIAG,
-			(SK_U16)(RegVal | PHY_M_CABD_ENA_TEST));
-	
+		SkGmPhyWrite(pAC, IoC, Port, CableDiagOffs, PHY_M_CABD_ENA_TEST);
+
 		return(0);
 	}
-	
+
 	/* Read Cable Diagnostic Reg */
-	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
+	SkGmPhyRead(pAC, IoC, Port, CableDiagOffs, &RegVal);
 
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 		("PHY Cable Diag.=0x%04X\n", RegVal));
@@ -4585,16 +4860,24 @@
 	}
 
 	/* get the test results */
-	for (i = 0; i < 4; i++)  {
-		/* set address to i for MDI[i] */
-		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i);
+	for (i = 0; i < MdiPairs; i++)  {
+
+		if (!FastEthernet) {
+			/* set address to i for MDI[i] */
+			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i);
+		}
 
 		/* get Cable Diagnostic values */
-		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
+		SkGmPhyRead(pAC, IoC, Port, CableDiagOffs, &RegVal);
 
 		pPrt->PMdiPairLen[i] = (SK_U8)(RegVal & PHY_M_CABD_DIST_MSK);
 
 		pPrt->PMdiPairSts[i] = (SK_U8)((RegVal & PHY_M_CABD_STAT_MSK) >> 13);
+
+		if (FastEthernet) {
+			/* get next register */
+			CableDiagOffs++;
+		}
 	}
 
 	return(0);
@@ -4603,3 +4886,4 @@
 #endif /* YUKON */
 
 /* End of file */
+
diff -urN linux-2.4.29/drivers/net/sk98lin/sky2.c linux-2.4.29-uc1/drivers/net/sk98lin/sky2.c
--- linux-2.4.29/drivers/net/sk98lin/sky2.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/sky2.c	2005-06-14 02:12:09.000000000 +0100
@@ -0,0 +1,2428 @@
+/******************************************************************************
+ *
+ * Name:        sky2.c
+ * Project:     Yukon2 specific functions and implementations
+ * Version:     $Revision: 1.2 $
+ * Date:        $Date: 2004/11/17 05:40:48 $
+ * Purpose:     The main driver source module
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ *	(C)Copyright 1998-2002 SysKonnect GmbH.
+ *	(C)Copyright 2002-2004 Marvell.
+ *
+ *	Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet 
+ *      Server Adapters.
+ *
+ *	Author: Ralph Roesler (rroesler@syskonnect.de)
+ *	        Mirko Lindner (mlindner@syskonnect.de)
+ *
+ *	Address all question to: linux@syskonnect.de
+ *
+ *	The technical manual for the adapters is available from SysKonnect's
+ *	web pages: www.syskonnect.com
+ *	
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2 of the License, or
+ *	(at your option) any later version.
+ *
+ *	The information in this file is provided "AS IS" without warranty.
+ *
+ *****************************************************************************/
+
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+#include <linux/tcp.h>
+
+/******************************************************************************
+ *
+ * Local Function Prototypes
+ *
+ *****************************************************************************/
+
+static void InitPacketQueues(SK_AC *pAC,int Port);
+static void GiveTxBufferToHw(SK_AC *pAC,SK_IOC IoC,int Port);
+static void GiveRxBufferToHw(SK_AC *pAC,SK_IOC IoC,int Port,SK_PACKET *pPacket);
+static void FillReceiveTableYukon2(SK_AC *pAC,SK_IOC IoC,int Port);
+static SK_BOOL HandleReceives(SK_AC *pAC,int Port,SK_U16 Len,SK_U32 FrameStatus,SK_U16 Tcp1,SK_U16 Tcp2,SK_U32 Tist,SK_U16 Vlan);
+static void CheckForSendComplete(SK_AC *pAC,SK_IOC IoC,int Port,SK_PKT_QUEUE *pPQ,SK_LE_TABLE *pLETab,unsigned int Done);
+static void UnmapAndFreeTxPktBuffer(SK_AC *pAC,SK_PACKET *pSkPacket,int TxPort);
+static SK_BOOL AllocateAndInitLETables(SK_AC *pAC);
+static SK_BOOL AllocatePacketBuffersYukon2(SK_AC *pAC);
+static void FreeLETables(SK_AC *pAC);
+static void FreePacketBuffers(SK_AC *pAC);
+static SK_BOOL AllocAndMapRxBuffer(SK_AC *pAC,SK_PACKET *pSkPacket,int Port);
+#ifdef CONFIG_SK98LIN_NAPI
+static SK_BOOL HandleStatusLEs(SK_AC *pAC,int *WorkDone,int WorkToDo);
+#else
+static SK_BOOL HandleStatusLEs(SK_AC *pAC);
+#endif
+
+/******************************************************************************
+ *
+ * Local Variables
+ *
+ *****************************************************************************/
+
+#define MAX_NBR_RX_BUFFERS_IN_HW	0x15
+static SK_U8 NbrRxBuffersInHW;
+
+#if defined(__i386__) || defined(__x86_64__)
+// Investigate faster method, because using 'wbinvd' costs too much time...
+// #define FLUSH_OPC(le)   asm volatile ("wbinvd":::"memory");
+#define FLUSH_OPC(le)
+#else
+#define FLUSH_OPC(le) 
+#endif
+
+/******************************************************************************
+ *
+ * Global Functions
+ *
+ *****************************************************************************/
+
+int SkY2Xmit( struct sk_buff *skb, struct SK_NET_DEVICE *dev); 
+
+/*****************************************************************************
+ *
+ * 	SkY2RestartStatusUnit - restarts teh status unit
+ *
+ * Description:
+ *	Reenables the status unit after any De-Init (e.g. when altering 
+ *	the sie of the MTU via 'ifconfig a.b.c.d mtu xxx')
+ *
+ * Returns:	N/A
+ */
+void SkY2RestartStatusUnit(
+SK_AC  *pAC)  /* pointer to adapter control context */
+{
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("==> SkY2RestartStatusUnit\n"));
+
+	/*
+	** It might be that the TX timer is not started. Therefore
+	** it is initialized here -> to be more investigated!
+	*/
+	SK_OUT32(pAC->IoBase, STAT_TX_TIMER_INI, HW_MS_TO_TICKS(pAC,10));
+
+	pAC->StatusLETable.Done  = 0;
+	pAC->StatusLETable.Put   = 0;
+	pAC->StatusLETable.HwPut = 0;
+	SkGeY2InitStatBmu(pAC, pAC->IoBase, &pAC->StatusLETable);
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("<== SkY2RestartStatusUnit\n"));
+}
+
+/*****************************************************************************
+ *
+ * 	SkY2RlmtSend - sends out a single RLMT notification
+ *
+ * Description:
+ *	This function sends out an RLMT frame
+ *
+ * Returns:	
+ *	> 0 - on succes: the number of bytes in the message
+ *	= 0 - on resource shortage: this frame sent or dropped, now
+ *	      the ring is full ( -> set tbusy)
+ *	< 0 - on failure: other problems ( -> return failure to upper layers)
+ */
+int SkY2RlmtSend (
+SK_AC          *pAC,       /* pointer to adapter control context           */
+int             PortNr,    /* index of port the packet(s) shall be send to */
+struct sk_buff *pMessage)  /* pointer to send-message                      */
+{
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("=== SkY2RlmtSend\n"));
+	return -1;   // temporarily do not send out RLMT frames
+#if 0
+	return(SkY2Xmit(pMessage, pAC->dev[PortNr])); SkY2Xmit needs device
+#endif
+}
+
+/*****************************************************************************
+ *
+ * 	SkY2AllocateResources - Allocates all required resources for Yukon2
+ *
+ * Description:
+ *	This function allocates all memory needed for the Yukon2. 
+ *	It maps also RX buffers to the LETables and initializes the
+ *	status list element table.
+ *
+ * Returns:	
+ *	SK_TRUE, if all resources could be allocated and setup succeeded
+ *	SK_FALSE, if an error 
+ */
+SK_BOOL SkY2AllocateResources (
+SK_AC  *pAC)  /* pointer to adapter control context */
+{
+	int CurrMac;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
+		("==> SkY2AllocateResources\n"));
+
+	/*
+	** Initialize the packet queue variables first
+	*/
+	for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) {
+		InitPacketQueues(pAC, CurrMac);
+	}
+
+	/* 
+	** Get sufficient memory for the LETables
+	*/
+	if (!AllocateAndInitLETables(pAC)) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
+			SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR,
+			("No memory for LETable.\n"));
+		return(SK_FALSE);
+	}
+
+	/*
+	** Allocate and intialize memory for both RX and TX 
+	** packet and fragment buffers. On an error, free 
+	** previously allocated LETable memory and quit.
+	*/
+	if (!AllocatePacketBuffersYukon2(pAC)) {
+		FreeLETables(pAC);
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
+			SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR,
+			("No memory for Packetbuffers.\n"));
+		return(SK_FALSE);
+	}
+
+	/* 
+	** Rx and Tx LE tables will be initialized in SkGeOpen() 
+	**
+	** It might be that the TX timer is not started. Therefore
+	** it is initialized here -> to be more investigated!
+	*/
+	SK_OUT32(pAC->IoBase, STAT_TX_TIMER_INI, HW_MS_TO_TICKS(pAC,10));
+	SkGeY2InitStatBmu(pAC, pAC->IoBase, &pAC->StatusLETable);
+
+	pAC->MaxUnusedRxLeWorking = MAX_UNUSED_RX_LE_WORKING;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
+		("<== SkY2AllocateResources\n"));
+
+	return (SK_TRUE);
+}
+
+/*****************************************************************************
+ *
+ * 	SkY2FreeResources - Frees previously allocated resources of Yukon2
+ *
+ * Description:
+ *	This function frees all previously allocated memory of the Yukon2. 
+ *
+ * Returns: N/A
+ */
+void SkY2FreeResources (
+SK_AC  *pAC)  /* pointer to adapter control context */
+{
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("==> SkY2FreeResources\n"));
+
+	FreeLETables(pAC);
+	FreePacketBuffers(pAC);
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("<== SkY2FreeResources\n"));
+}
+
+/*****************************************************************************
+ *
+ * 	SkY2AllocateRxBuffers - Allocates the receive buffers for a port
+ *
+ * Description:
+ *	This function allocated all the RX buffers of the Yukon2. 
+ *
+ * Returns: N/A
+ */
+void SkY2AllocateRxBuffers (
+SK_AC    *pAC,   /* pointer to adapter control context */
+SK_IOC    IoC,	 /* I/O control context                */
+int       Port)	 /* port index of RX                   */
+{
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
+		("==> SkY2AllocateRxBuffers (Port %c)\n", Port));
+
+	FillReceiveTableYukon2(pAC, IoC, Port);
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
+		("<== SkY2AllocateRxBuffers\n"));
+}
+
+/*****************************************************************************
+ *
+ * 	SkY2FreeRxBuffers - Free's all allocates RX buffers of
+ *
+ * Description:
+ *	This function frees all RX buffers of the Yukon2 for a single port
+ *
+ * Returns: N/A
+ */
+void SkY2FreeRxBuffers (
+SK_AC    *pAC,   /* pointer to adapter control context */
+SK_IOC    IoC,	 /* I/O control context                */
+int       Port)	 /* port index of RX                   */
+{
+	SK_PACKET     *pSkPacket;
+	unsigned long  Flags;   /* for POP/PUSH macros */
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("==> SkY2FreeRxBuffers (Port %c)\n", Port));
+
+	if (pAC->RxPort[Port].ReceivePacketTable   != NULL) {
+		POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket);
+		while (pSkPacket != NULL) {
+			if ((pSkPacket->pFrag) != NULL) {
+				pci_unmap_page(pAC->PciDev,
+				(dma_addr_t) pSkPacket->pFrag->pPhys,
+				pSkPacket->pFrag->FragLen - 2,
+				PCI_DMA_FROMDEVICE);
+
+				DEV_KFREE_SKB_ANY(pSkPacket->pMBuf);
+				pSkPacket->pMBuf        = NULL;
+				pSkPacket->pFrag->pPhys = (SK_U64) 0;
+				pSkPacket->pFrag->pVirt = NULL;
+			}
+			PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket);
+			POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket);
+		}
+	}
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("<== SkY2FreeRxBuffers\n"));
+}
+
+/*****************************************************************************
+ *
+ * 	SkY2FreeTxBuffers - Free's any currently maintained Tx buffer
+ *
+ * Description:
+ *	This function frees the TX buffers of the Yukon2 for a single port
+ *	which might be in use by a transmit action
+ *
+ * Returns: N/A
+ */
+void SkY2FreeTxBuffers (
+SK_AC    *pAC,   /* pointer to adapter control context */
+SK_IOC    IoC,	 /* I/O control context                */
+int       Port)	 /* port index of TX                   */
+{
+	SK_PACKET      *pSkPacket;
+	SK_FRAG        *pSkFrag;
+	unsigned long   Flags;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("==> SkY2FreeTxBuffers (Port %c)\n", Port));
+ 
+	if (pAC->TxPort[Port][0].TransmitPacketTable != NULL) {
+		POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxAQ_working, pSkPacket);
+		while (pSkPacket != NULL) {
+			if ((pSkFrag = pSkPacket->pFrag) != NULL) {
+				UnmapAndFreeTxPktBuffer(pAC, pSkPacket, Port);
+			}
+			PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->TxPort[Port][0].TxAQ_waiting, pSkPacket);
+			POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxAQ_working, pSkPacket);
+		}
+#if USE_SYNC_TX_QUEUE
+		POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxSQ_working, pSkPacket);
+		while (pSkPacket != NULL) {
+			if ((pSkFrag = pSkPacket->pFrag) != NULL) {
+				UnmapAndFreeTxPktBuffer(pAC, pSkPacket, Port);
+			}
+			PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->TxPort[Port][0].TxSQ_waiting, pSkPacket);
+			POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxSQ_working, pSkPacket);
+		}
+#endif
+	}
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("<== SkY2FreeTxBuffers\n"));
+}
+
+/*****************************************************************************
+ *
+ * 	SkY2Isr - handle a receive IRQ for all yukon2 cards
+ *
+ * Description:
+ *	This function is called when a receive IRQ is set. (only for yukon2)
+ *	HandleReceives does the deferred processing of all outstanding
+ *	interrupt operations.
+ *
+ * Returns:	N/A
+ */
+SkIsrRetVar SkY2Isr (
+int              irq,     /* the irq we have received (might be shared!) */
+void            *dev_id,  /* current device id                           */
+struct  pt_regs *ptregs)  /* not used by our driver                      */
+{
+	struct SK_NET_DEVICE  *dev  = (struct SK_NET_DEVICE *)dev_id;
+	DEV_NET               *pNet = (DEV_NET*) dev->priv;
+	SK_AC                 *pAC  = pNet->pAC;
+	SK_U32                 IntSrc;
+	unsigned long          Flags;
+#ifndef CONFIG_SK98LIN_NAPI
+	SK_BOOL                handledStatLE = SK_FALSE;
+#endif
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+		("==> SkY2Isr\n"));
+
+	SK_IN32(pAC->IoBase, B0_Y2_SP_ISRC2, &IntSrc);
+
+	if (IntSrc == 0) {
+		SK_OUT32(pAC->IoBase, B0_Y2_SP_ICR, 2);
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+			("No Interrupt\n ==> SkY2Isr\n"));
+		return;
+
+	}
+
+#ifdef CONFIG_SK98LIN_NAPI
+	if (netif_rx_schedule_prep(dev)) {
+		pAC->GIni.GIValIrqMask &= ~(Y2_IS_STAT_BMU);
+		SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
+		__netif_rx_schedule(dev);
+	}
+#else
+	handledStatLE = HandleStatusLEs(pAC);
+#endif
+
+	/* 
+	** Check for Special Interrupts 
+	*/
+	if (IntSrc & ~Y2_IS_STAT_BMU) {
+		spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+		SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
+		SkEventDispatcher(pAC, pAC->IoBase);
+		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+	}
+
+	/* Speed enhancement for a2 chipsets */
+	if (HW_FEATURE(pAC, HWF_WA_DEV_42)) {
+		spin_lock_irqsave(&pAC->SetPutIndexLock, Flags);
+		SkGeY2SetPutIndex(pAC, pAC->IoBase, Y2_PREF_Q_ADDR(Q_XA1,0), &pAC->TxPort[0][0].TxALET);
+		SkGeY2SetPutIndex(pAC, pAC->IoBase, Y2_PREF_Q_ADDR(Q_R1,0), &pAC->RxPort[0].RxLET);
+		spin_unlock_irqrestore(&pAC->SetPutIndexLock, Flags);
+	} 
+
+	/* 
+	** Reenable interrupts and signal end of ISR 
+	*/
+	SK_OUT32(pAC->IoBase, B0_Y2_SP_ICR, 2);
+			
+	/*
+	** Stop and restart TX timer in case a Status LE was handled
+	*/
+#ifndef CONFIG_SK98LIN_NAPI
+	if ((HW_FEATURE(pAC, HWF_WA_DEV_43_418)) && (handledStatLE)) {
+		SK_OUT8(pAC->IoBase, STAT_TX_TIMER_CTRL, TIM_STOP);
+		SK_OUT8(pAC->IoBase, STAT_TX_TIMER_CTRL, TIM_START);
+	}
+#endif
+
+	if (!(IS_Q_EMPTY(&(pAC->TxPort[0][TX_PRIO_LOW].TxAQ_waiting)))) {
+		GiveTxBufferToHw(pAC, pAC->IoBase, 0);
+	}
+	if (!(IS_Q_EMPTY(&(pAC->TxPort[1][TX_PRIO_LOW].TxAQ_waiting)))) {
+		GiveTxBufferToHw(pAC, pAC->IoBase, 1);
+	}
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+		("<== SkY2Isr\n"));
+
+	return;
+}	/* SkY2Isr */
+
+/*****************************************************************************
+ *
+ *	SkY2Xmit - Linux frame transmit function for Yukon2
+ *
+ * Description:
+ *	The system calls this function to send frames onto the wire.
+ *	It puts the frame in the tx descriptor ring. If the ring is
+ *	full then, the 'tbusy' flag is set.
+ *
+ * Returns:
+ *	0, if everything is ok
+ *	!=0, on error
+ *
+ * WARNING: 
+ *	returning 1 in 'tbusy' case caused system crashes (double
+ *	allocated skb's) !!!
+ */
+int SkY2Xmit(
+struct sk_buff       *skb,  /* socket buffer to be sent */
+struct SK_NET_DEVICE *dev)  /* via which device?        */
+{
+	DEV_NET         *pNet    = (DEV_NET*) dev->priv;
+	SK_AC           *pAC     = pNet->pAC;
+	SK_U8            FragIdx = 0;
+	SK_PACKET       *pSkPacket;
+	SK_FRAG         *PrevFrag;
+	SK_FRAG         *CurrFrag;
+	SK_PKT_QUEUE    *pWorkQueue;  /* corresponding TX queue */
+	SK_PKT_QUEUE    *pWaitQueue; 
+	SK_PKT_QUEUE    *pFreeQueue; 
+	SK_LE_TABLE     *pLETab;      /* corresponding LETable  */ 
+	skb_frag_t      *sk_frag;
+	SK_U64           PhysAddr;
+	unsigned long    Flags;
+	unsigned int     Port;
+	int              CurrFragCtr;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+		("==> SkY2Xmit\n"));
+
+	/*
+	** Get port and return if no free packet is available 
+	*/
+	Port = (pAC->RlmtNets == 2) ? pNet->PortNr : pAC->ActivePort;
+	if (IS_Q_EMPTY(&(pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free))) {
+		return 1; /* zero bytes sent! */
+	}
+
+	/*
+	** Put any new packet to be sent in the waiting queue and 
+	** handle also any possible fragment of that packet.
+	*/
+	pWorkQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working);
+	pWaitQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting);
+	pFreeQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free);
+	pLETab     = &(pAC->TxPort[Port][TX_PRIO_LOW].TxALET);
+
+	/*
+	** Normal send operations require only one fragment, because 
+	** only one sk_buff data area is passed. 
+	** In contradiction to this, scatter-gather (zerocopy) send
+	** operations might pass one or more additional fragments 
+	** where each fragment needs a separate fragment info packet.
+	*/
+	if (((skb_shinfo(skb)->nr_frags + 1) * MAX_FRAG_OVERHEAD) > 
+					NUM_FREE_LE_IN_TABLE(pLETab)) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
+			SK_DBGCAT_DRV_TX_PROGRESS | SK_DBGCAT_DRV_ERROR,
+			("Not enough LE available for send\n"));
+		return 1; /* zero bytes sent! */
+	}
+	
+	if ((skb_shinfo(skb)->nr_frags + 1) > MAX_NUM_FRAGS) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
+			SK_DBGCAT_DRV_TX_PROGRESS | SK_DBGCAT_DRV_ERROR,
+			("Not even one fragment available for send\n"));
+		return 1; /* zero bytes sent! */
+	}
+
+	/*
+	** Get first packet from free packet queue
+	*/
+	POP_FIRST_PKT_FROM_QUEUE(pFreeQueue, pSkPacket);
+	if(pSkPacket == NULL) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
+			SK_DBGCAT_DRV_TX_PROGRESS | SK_DBGCAT_DRV_ERROR,
+			("Could not obtain free packet used for xmit\n"));
+		return 1; /* zero bytes sent! */
+	}
+
+	pSkPacket->pFrag = &(pSkPacket->FragArray[FragIdx]);
+
+	/* 
+	** map the sk_buff to be available for the adapter 
+	*/
+	PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
+			virt_to_page(skb->data),
+			((unsigned long) skb->data & ~PAGE_MASK),
+			skb_headlen(skb),
+			PCI_DMA_TODEVICE);
+	pSkPacket->pMBuf	  = skb;
+	pSkPacket->pFrag->pPhys   = PhysAddr;
+	pSkPacket->pFrag->FragLen = skb_headlen(skb);
+	pSkPacket->pFrag->pNext   = NULL; /* initial has no next default */
+	pSkPacket->NumFrags	  = skb_shinfo(skb)->nr_frags + 1;
+
+	PrevFrag = pSkPacket->pFrag;
+
+	/*
+	** Each scatter-gather fragment need to be mapped...
+	*/
+        for (	CurrFragCtr = 0; 
+		CurrFragCtr < skb_shinfo(skb)->nr_frags;
+		CurrFragCtr++) {
+		FragIdx++;
+		sk_frag = &skb_shinfo(skb)->frags[CurrFragCtr];
+		CurrFrag = &(pSkPacket->FragArray[FragIdx]);
+
+                /* 
+		** map the sk_buff to be available for the adapter 
+		*/
+		PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
+				sk_frag->page,
+		 		sk_frag->page_offset,
+		 		sk_frag->size,
+		 		PCI_DMA_TODEVICE);
+
+		CurrFrag->pPhys   = PhysAddr;
+ 		CurrFrag->FragLen = sk_frag->size;
+ 		CurrFrag->pNext   = NULL;
+
+		/*
+		** Add the new fragment to the list of fragments
+		*/
+		PrevFrag->pNext = CurrFrag;
+		PrevFrag = CurrFrag;
+	}
+
+	/* 
+	** Add packet to waiting packets queue 
+	*/
+	PUSH_PKT_AS_LAST_IN_QUEUE(pWaitQueue, pSkPacket);
+	GiveTxBufferToHw(pAC, pAC->IoBase, Port);
+	dev->trans_start = jiffies;
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+		("<== SkY2Xmit(return 0)\n"));
+	return (0);
+}	/* SkY2Xmit */
+
+#ifdef CONFIG_SK98LIN_NAPI
+/*****************************************************************************
+ *
+ *	SkY2Poll - NAPI Rx polling callback for Yukon2 chipsets
+ *
+ * Description:
+ *	Called by the Linux system in case NAPI polling is activated
+ *
+ * Returns
+ *	The number of work data still to be handled
+ */
+int SkY2Poll(
+struct net_device *dev,     /* device that needs to be polled */
+int               *budget)  /* how many budget do we have?    */
+{
+	SK_AC	*pAC           = ((DEV_NET*)(dev->priv))->pAC;
+	int	 WorkToDo      = min(*budget, dev->quota);
+	int	 WorkDone      = 0;
+	SK_BOOL  handledStatLE = SK_FALSE;
+
+	handledStatLE = HandleStatusLEs(pAC, &WorkDone, WorkToDo);
+
+	*budget -= WorkDone;
+	dev->quota -= WorkDone;
+
+	if(WorkDone < WorkToDo) {
+		netif_rx_complete(dev);
+		pAC->GIni.GIValIrqMask |= (Y2_IS_STAT_BMU);
+		SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
+		if ((HW_FEATURE(pAC, HWF_WA_DEV_43_418)) && (handledStatLE)) {
+			SK_OUT8(pAC->IoBase, STAT_TX_TIMER_CTRL, TIM_STOP);
+			SK_OUT8(pAC->IoBase, STAT_TX_TIMER_CTRL, TIM_START);
+		}
+	}
+	return (WorkDone >= WorkToDo);
+}	/* SkY2Poll */
+#endif
+
+/******************************************************************************
+ *
+ *	SkY2PortStop - stop a port on Yukon2
+ *
+ * Description:
+ *	This function stops a port of the Yukon2 chip. This stop 
+ *	stop needs to be performed in a specific order:
+ * 
+ *	a) Stop the Prefetch unit
+ *	b) Stop the Port (MAC, PHY etc.)
+ *
+ * Returns: N/A
+ */
+void SkY2PortStop(
+SK_AC   *pAC,      /* adapter control context                             */
+SK_IOC   IoC,      /* I/O control context (address of adapter registers)  */
+int      Port,     /* port to stop (MAC_1 + n)                            */
+int      Dir,      /* StopDirection (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */
+int      RstMode)  /* Reset Mode (SK_SOFT_RST, SK_HARD_RST)               */
+{
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("==> SkY2PortStop (Port %c)\n", 'A' + Port));
+
+	/*
+	** Stop the HW
+	*/
+	SkGeStopPort(pAC, IoC, Port, Dir, RstMode);
+
+	/*
+	** Move any TX packet from work queues into the free queue again
+	*/
+	SkY2FreeTxBuffers(pAC, pAC->IoBase, Port);
+
+	/*
+	** Move any RX packet from work queue into the waiting queue
+	*/
+	SkY2FreeRxBuffers(pAC, pAC->IoBase, Port);
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("<== SkY2PortStop()\n"));
+}
+
+/******************************************************************************
+ *
+ *	SkY2PortStart - start a port on Yukon2
+ *
+ * Description:
+ *	This function starts a port of the Yukon2 chip. This start 
+ *	action needs to be performed in a specific order:
+ * 
+ *	a) Initialize the LET indices (PUT/GET to 0)
+ *	b) Initialize the LET in HW (enables also prefetch unit)
+ *	c) Move all RX buffers from waiting queue to working queue
+ *	   which involves also setting up of RX list elements
+ *	d) Initialize the FIFO settings of Yukon2 (Watermark etc.)
+ *	e) Initialize the Port (MAC, PHY etc.)
+ *	f) Initialize the MC addresses
+ *
+ * Returns:	N/A
+ */
+void SkY2PortStart(
+SK_AC   *pAC,   /* adapter control context                            */
+SK_IOC   IoC,   /* I/O control context (address of adapter registers) */
+int      Port)  /* port to start                                      */
+{
+	SK_HWLE  *pLE;
+	SK_U32    DWord;
+	SK_U32    PrefetchReg; /* register for Put index */
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("==> SkY2PortStart (Port %c)\n", 'A' + Port));
+
+	/*
+	** Initialize the LET indices
+	*/
+	pAC->RxPort[Port].RxLET.Done                = 0; 
+	pAC->RxPort[Port].RxLET.Put                 = 0;
+	pAC->RxPort[Port].RxLET.HwPut               = 0;
+	pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Done  = 0;    
+	pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Put   = 0;
+	pAC->TxPort[Port][TX_PRIO_LOW].TxALET.HwPut = 0;
+	if (HW_SYNC_TX_SUPPORTED(pAC)) {
+		pAC->TxPort[Port][TX_PRIO_LOW].TxSLET.Done  = 0;    
+		pAC->TxPort[Port][TX_PRIO_LOW].TxSLET.Put   = 0;
+		pAC->TxPort[Port][TX_PRIO_LOW].TxSLET.HwPut = 0;
+	}
+	
+	if (HW_FEATURE(pAC, HWF_WA_DEV_420)) {
+		/*
+		** It might be that we have to limit the RX buffers 
+		** effectively passed to HW. Initialize the start
+		** value in that case...
+		*/
+		NbrRxBuffersInHW = 0;
+	}
+
+	/*
+	** TODO on dual net adapters we need to check if
+	** StatusLETable need to be set...
+	** 
+	** pAC->StatusLETable.Done  = 0;
+	** pAC->StatusLETable.Put   = 0;
+	** pAC->StatusLETable.HwPut = 0;
+	** SkGeY2InitPrefetchUnit(pAC, pAC->IoBase, Q_ST, &pAC->StatusLETable);
+	*/
+
+	/*
+	** Initialize the LET in HW (enables also prefetch unit)
+	*/
+	SkGeY2InitPrefetchUnit(pAC, IoC,(Port == 0) ? Q_R1 : Q_R2,
+			&pAC->RxPort[Port].RxLET);
+	SkGeY2InitPrefetchUnit( pAC, IoC,(Port == 0) ? Q_XA1 : Q_XA2, 
+			&pAC->TxPort[Port][TX_PRIO_LOW].TxALET);
+	if (HW_SYNC_TX_SUPPORTED(pAC)) {
+		SkGeY2InitPrefetchUnit( pAC, IoC, (Port == 0) ? Q_XS1 : Q_XS2,
+				&pAC->TxPort[Port][TX_PRIO_HIGH].TxSLET);
+	}
+
+	/*
+	** Initialize the Port (MAC, PHY etc.)
+	*/
+	if (SkGeInitPort(pAC, IoC, Port)) {
+		if (Port == 0) {
+			printk("%s: SkGeInitPort A failed.\n",pAC->dev[0]->name);
+		} else {
+			printk("%s: SkGeInitPort B failed.\n",pAC->dev[1]->name);
+		}
+	}
+	
+	if (IS_GMAC(pAC)) {
+		/* disable Rx GMAC FIFO Flush Mode */
+		SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8) GMF_RX_F_FL_OFF);
+	}
+
+	/*
+	** Initialize the MC addresses
+	*/
+	SkAddrMcUpdate(pAC,IoC, Port);
+
+	SkMacRxTxEnable(pAC, IoC,Port);
+				
+	if (pAC->RxPort[Port].UseRxCsum) {
+		SkGeRxCsum(pAC, IoC, Port, SK_TRUE);
+	
+		GET_RX_LE(pLE, &pAC->RxPort[Port].RxLET);
+		RXLE_SET_STACS1(pLE, pAC->CsOfs1);
+		RXLE_SET_STACS2(pLE, pAC->CsOfs2);
+		RXLE_SET_CTRL(pLE, 0);
+
+		RXLE_SET_OPC(pLE, OP_TCPSTART | HW_OWNER);
+		FLUSH_OPC(pLE);
+		if (Port == 0) {
+			PrefetchReg=Y2_PREF_Q_ADDR(Q_R1,PREF_UNIT_PUT_IDX_REG);
+		} else {
+			PrefetchReg=Y2_PREF_Q_ADDR(Q_R2,PREF_UNIT_PUT_IDX_REG);
+		}
+		DWord = GET_PUT_IDX(&pAC->RxPort[Port].RxLET);
+		SK_OUT32(IoC, PrefetchReg, DWord);
+		UPDATE_HWPUT_IDX(&pAC->RxPort[Port].RxLET);
+	}
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("<== SkY2PortStart()\n"));
+}
+
+/******************************************************************************
+ *
+ * Local Functions
+ *
+ *****************************************************************************/
+
+/*****************************************************************************
+ *
+ *	InitPacketQueues - initialize SW settings of packet queues
+ *
+ * Description:
+ *	This function will initialize the packet queues for a port.
+ *
+ * Returns: N/A
+ */
+static void InitPacketQueues(
+SK_AC  *pAC,   /* pointer to adapter control context */
+int     Port)  /* index of port to be initialized    */
+{
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
+		("==> InitPacketQueues(Port %c)\n", 'A' + Port));
+	
+	pAC->RxPort[Port].RxQ_working.pHead = NULL;
+	pAC->RxPort[Port].RxQ_working.pTail = NULL;
+	spin_lock_init(&pAC->RxPort[Port].RxQ_working.QueueLock);
+	
+	pAC->RxPort[Port].RxQ_waiting.pHead = NULL;
+	pAC->RxPort[Port].RxQ_waiting.pTail = NULL;
+	spin_lock_init(&pAC->RxPort[Port].RxQ_waiting.QueueLock);
+	
+	pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free.pHead = NULL;
+	pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free.pTail = NULL;
+	spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free.QueueLock);
+
+	pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working.pHead = NULL;
+	pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working.pTail = NULL;
+	spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working.QueueLock);
+	
+	pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting.pHead = NULL;
+	pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting.pTail = NULL;
+	spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting.QueueLock);
+	
+#if USE_SYNC_TX_QUEUE
+	pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_working.pHead = NULL;
+	pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_working.pTail = NULL;
+	spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_working.QueueLock);
+
+	pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_waiting.pHead = NULL;
+	pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_waiting.pTail = NULL;
+	spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_waiting.QueueLock);
+#endif
+	
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
+		("<== InitPacketQueues(Port %c)\n", 'A' + Port));
+}	/* InitPacketQueues */
+
+/*****************************************************************************
+ *
+ *	GiveTxBufferToHw - commits a previously allocated DMA area to HW
+ *
+ * Description:
+ *	This functions gives transmit buffers to HW. If no list elements
+ *	are available the buffers will be queued. 
+ *
+ * Notes:
+ *       This function can run only once in a system at one time.
+ *
+ * Returns: N/A
+ */
+static void GiveTxBufferToHw(
+SK_AC   *pAC,   /* pointer to adapter control context         */
+SK_IOC   IoC,   /* I/O control context (address of registers) */
+int      Port)  /* port index for which the buffer is used    */
+{
+	SK_HWLE         *pLE;
+	SK_PACKET       *pSkPacket;
+	SK_FRAG         *pFrag;
+	SK_PKT_QUEUE    *pWorkQueue;   /* corresponding TX queue */
+	SK_PKT_QUEUE    *pWaitQueue; 
+	SK_LE_TABLE     *pLETab;       /* corresponding LETable  */ 
+	SK_BOOL          SetOpcodePacketFlag;
+	SK_U32           HighAddress;
+	SK_U32           LowAddress;
+	SK_U16           TcpSumStart; 
+	SK_U16           TcpSumWrite;
+	SK_U8            OpCode;
+	SK_U8            Ctrl;
+	unsigned long    Flags;
+	int              Protocol;
+#ifdef NETIF_F_TSO
+	SK_U16           Mss;
+	int              TcpOptLen;
+	int              IpTcpLen;
+#endif
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+		("==> GiveTxBufferToHw\n"));
+
+	if (IS_Q_EMPTY(&(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting))) {
+		return;
+	}
+
+	/*
+	** Initialize queue settings
+	*/
+	pWorkQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working);
+	pWaitQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting);
+	pLETab     = &(pAC->TxPort[Port][TX_PRIO_LOW].TxALET);
+
+	POP_FIRST_PKT_FROM_QUEUE(pWaitQueue, pSkPacket);
+	while (pSkPacket != NULL) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+			("\tWe have a packet to send %p\n", pSkPacket));
+
+		/* 
+		** the first frag of a packet gets opcode OP_PACKET 
+		*/
+		SetOpcodePacketFlag	= SK_TRUE;
+		pFrag			= pSkPacket->pFrag;
+
+		/* 
+		** fill list elements with data from fragments 
+		*/
+		while (pFrag != NULL) {
+			SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+				("\tGet LE\n"));
+#ifdef NETIF_F_TSO
+			Mss = skb_shinfo(pSkPacket->pMBuf)->tso_size;
+			if (Mss) {
+				TcpOptLen = ((pSkPacket->pMBuf->h.th->doff - 5) * 4);
+				IpTcpLen  = ((pSkPacket->pMBuf->nh.iph->ihl * 4) + 
+						sizeof(struct tcphdr));
+				Mss += (TcpOptLen + IpTcpLen + C_LEN_ETHERMAC_HEADER);
+			}
+			if (pLETab->Bmu.RxTx.MssValue != Mss) {
+				pLETab->Bmu.RxTx.MssValue = Mss;
+				/* Take a new LE for TSO from the table */
+				GET_TX_LE(pLE, pLETab);
+
+#if 0
+				if(pSkPacket->VlanId) {
+					TXLE_SET_OPC(pLE, OP_LRGLENVLAN | HW_OWNER);
+					TXLE_SET_VLAN(pLE, pSkPacket->VlanId);
+					pSkPacket->VlanId = 0;
+					Ctrl |= INS_VLAN;
+				} else {
+#endif
+					TXLE_SET_OPC(pLE, OP_LRGLEN | HW_OWNER);
+#if 0
+				}
+#endif
+				/* set maximum segment size for new packet */
+				TXLE_SET_LSLEN(pLE, pLETab->Bmu.RxTx.MssValue);
+				FLUSH_OPC(pLE) ;
+			}
+#endif
+			GET_TX_LE(pLE, pLETab);
+			Ctrl	= 0;
+
+			SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+				("\tGot empty LE %p idx %d\n", pLE, GET_PUT_IDX(pLETab)));
+
+			SK_DBG_DUMP_TX_LE(pLE);
+
+			LowAddress  = (SK_U32) (pFrag->pPhys & 0xffffffff);
+			HighAddress = (SK_U32) (pFrag->pPhys >> 32);
+			if (HighAddress != pLETab->BufHighAddr) {
+				/* set opcode high part of the address in one LE */
+				OpCode = OP_ADDR64 | HW_OWNER;
+	
+				/* Set now the 32 high bits of the address */
+				TXLE_SET_ADDR( pLE, HighAddress);
+	
+				/* Set the opcode into the LE */
+				TXLE_SET_OPC(pLE, OpCode);
+	
+				/* Flush the LE to memory */
+				FLUSH_OPC(pLE);
+	
+				/* remember the HighAddress we gave to the Hardware */
+				pLETab->BufHighAddr = HighAddress;
+				
+				/* get a new LE because we filled one with high address */
+				GET_TX_LE(pLE, pLETab);
+			}
+	
+			/*
+			** TCP checksum offload
+			*/
+			if ((pSkPacket->pMBuf->ip_summed == CHECKSUM_HW) && 
+			    (SetOpcodePacketFlag         == SK_TRUE)) {
+				Protocol = ((SK_U8)pSkPacket->pMBuf->data[C_OFFSET_IPPROTO] & 0xff);
+				/* if (Protocol & C_PROTO_ID_IP) { Ctrl = 0; } */ 
+				if (Protocol & C_PROTO_ID_TCP) {
+					Ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
+					/* TCP Checksum Calculation Start Position */
+					TcpSumStart = C_LEN_ETHERMAC_HEADER + IP_HDR_LEN;
+					/* TCP Checksum Write Position */
+					TcpSumWrite = TcpSumStart + TCP_CSUM_OFFS;
+				} else {
+					Ctrl = UDPTCP | CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
+					/* TCP Checksum Calculation Start Position */
+					TcpSumStart = ETHER_MAC_HDR_LEN + IP_HDR_LEN;
+					/* UDP Checksum Write Position */
+					TcpSumWrite = TcpSumStart + UDP_CSUM_OFFS;
+				}
+	
+				if ((Ctrl) && (pLETab->Bmu.RxTx.TcpWp != TcpSumWrite)) {
+					/* Update the last value of the write position */
+					pLETab->Bmu.RxTx.TcpWp = TcpSumWrite;
+	
+					/* Set the Lock field for this LE: */
+					/* Checksum calculation for one packet only */
+					TXLE_SET_LCKCS(pLE, 1);
+	
+					/* Set the start position for checksum. */
+					TXLE_SET_STACS(pLE, TcpSumStart);
+	
+					/* Set the position where the checksum will be writen */
+					TXLE_SET_WRICS(pLE, TcpSumWrite);
+	
+					/* Set the initial value for checksum */
+					/* PseudoHeader CS passed from Linux -> 0! */
+					TXLE_SET_INICS(pLE, 0);
+	
+					/* Set the opcode for tcp checksum */
+					TXLE_SET_OPC(pLE, OP_TCPLISW | HW_OWNER);
+	
+					/* Flush the LE to memory */
+					FLUSH_OPC(pLE);
+	
+					/* get a new LE because we filled one with data for checksum */
+					GET_TX_LE(pLE, pLETab);
+				}
+			} /* end TCP offload handling */
+	
+			TXLE_SET_ADDR(pLE, LowAddress);
+			TXLE_SET_LEN(pLE, pFrag->FragLen);
+	
+			if (SetOpcodePacketFlag){
+#ifdef NETIF_F_TSO
+				if (Mss) {
+					OpCode = OP_LARGESEND | HW_OWNER;
+				} else {
+#endif
+					OpCode = OP_PACKET| HW_OWNER;
+#ifdef NETIF_F_TSO
+				}
+#endif
+				SetOpcodePacketFlag = SK_FALSE;
+			} else {
+				/* Follow packet in a sequence has always OP_BUFFER */
+				OpCode = OP_BUFFER | HW_OWNER;
+			}
+	
+			pFrag = pFrag->pNext;
+			if (pFrag == NULL) {
+				/* mark last fragment */
+				Ctrl |= EOP;
+			}
+			TXLE_SET_CTRL(pLE, Ctrl);
+			TXLE_SET_OPC(pLE, OpCode);
+			FLUSH_OPC(pLE);
+			SK_DBG_DUMP_TX_LE(pLE);
+		}
+	
+		/* 
+		** Remember next LE for tx complete 
+		*/
+		pSkPacket->NextLE = GET_PUT_IDX(pLETab);
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+			("\tNext LE for pkt %p is %d\n", pSkPacket, pSkPacket->NextLE));
+
+		/* 
+		** Add packet to working packets queue 
+		*/
+		PUSH_PKT_AS_LAST_IN_QUEUE(pWorkQueue, pSkPacket);
+
+		/* 
+		** give transmit start command
+		*/
+		if (HW_FEATURE(pAC, HWF_WA_DEV_42)) {
+			spin_lock(&pAC->SetPutIndexLock);
+			SkGeY2SetPutIndex(pAC, pAC->IoBase, Y2_PREF_Q_ADDR(Q_XA1,0), &pAC->TxPort[0][0].TxALET);
+			spin_unlock(&pAC->SetPutIndexLock);
+		} else {
+			/* write put index */
+			if (Port == 0) { 
+				SK_OUT32(pAC->IoBase, 
+					Y2_PREF_Q_ADDR(Q_XA1,PREF_UNIT_PUT_IDX_REG), 
+					GET_PUT_IDX(&pAC->TxPort[0][0].TxALET)); 
+				UPDATE_HWPUT_IDX(&pAC->TxPort[0][0].TxALET);
+			} else {
+				SK_OUT32(pAC->IoBase, 
+					Y2_PREF_Q_ADDR(Q_XA2, PREF_UNIT_PUT_IDX_REG), 
+					GET_PUT_IDX(&pAC->TxPort[1][0].TxALET)); 
+				UPDATE_HWPUT_IDX(&pAC->TxPort[1][0].TxALET);
+			}
+		}
+	
+		if (IS_Q_EMPTY(&(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting))) {
+			break; /* get out of while */
+		}
+		POP_FIRST_PKT_FROM_QUEUE(pWaitQueue, pSkPacket);
+	} /* while (pSkPacket != NULL) */
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+		("<== GiveTxBufferToHw\n"));
+	return;
+}	/* GiveTxBufferToHw */
+
+/***********************************************************************
+ *
+ *	GiveRxBufferToHw - commits a previously allocated DMA area to HW
+ *
+ * Description:
+ *	This functions gives receive buffers to HW. If no list elements
+ *	are available the buffers will be queued. 
+ *
+ * Notes:
+ *       This function can run only once in a system at one time.
+ *
+ * Returns: N/A
+ */
+static void GiveRxBufferToHw(
+SK_AC      *pAC,      /* pointer to adapter control context         */
+SK_IOC      IoC,      /* I/O control context (address of registers) */
+int         Port,     /* port index for which the buffer is used    */
+SK_PACKET  *pPacket)  /* receive buffer(s)                          */
+{
+	SK_HWLE         *pLE;
+	SK_LE_TABLE     *pLETab;
+	SK_BOOL         Done = SK_FALSE;  /* at least on LE changed? */
+	SK_U32          LowAddress;
+	SK_U32          HighAddress;
+	SK_U32          PrefetchReg;      /* register for Put index  */
+	SK_U8           OpCode;
+	SK_U8           Ctrl;
+	unsigned        NumFree;
+	unsigned        Required;
+	unsigned long   Flags;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+	("==> GiveRxBufferToHw(Port %c, Packet %p)\n", 'A' + Port, pPacket));
+
+	pLETab	= &pAC->RxPort[Port].RxLET;
+
+	if (Port == 0) {
+		PrefetchReg = Y2_PREF_Q_ADDR(Q_R1, PREF_UNIT_PUT_IDX_REG);
+	} else {
+		PrefetchReg = Y2_PREF_Q_ADDR(Q_R2, PREF_UNIT_PUT_IDX_REG);
+	} 
+
+	if (pPacket != NULL) {
+		/*
+		** For the time being, we have only one packet passed
+		** to this function which might be changed in future!
+		*/
+		PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket);
+	}
+
+	/* 
+	** now pPacket contains the very first waiting packet
+	*/
+	POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket);
+	while (pPacket != NULL) {
+		if (HW_FEATURE(pAC, HWF_WA_DEV_420)) {
+			if (NbrRxBuffersInHW >= MAX_NBR_RX_BUFFERS_IN_HW) {
+				PUSH_PKT_AS_FIRST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket);
+				SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+					("<== GiveRxBufferToHw()\n"));
+				return;
+			} 
+			NbrRxBuffersInHW++;
+		}
+
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+			("Try to add packet %p\n", pPacket));
+
+		/* 
+		** Check whether we have enough listelements:
+		**
+		** we have to take into account that each fragment 
+		** may need an additional list element for the high 
+		** part of the address here I simplified it by 
+		** using MAX_FRAG_OVERHEAD maybe it's worth to split 
+		** this constant for Rx and Tx or to calculate the
+		** real number of needed LE's
+		*/
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+			("\tNum %d Put %d Done %d Free %d %d\n",
+			pLETab->Num, pLETab->Put, pLETab->Done,
+			NUM_FREE_LE_IN_TABLE(pLETab),
+			(NUM_FREE_LE_IN_TABLE(pLETab))));
+
+		Required = pPacket->NumFrags + MAX_FRAG_OVERHEAD;
+		NumFree = NUM_FREE_LE_IN_TABLE(pLETab);
+		if (NumFree) {
+			NumFree--;
+		}
+
+		if (Required > NumFree ) {
+			SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
+				SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR,
+				("\tOut of LEs have %d need %d\n",
+				NumFree, Required));
+
+			SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+				("\tWaitQueue starts with packet %p\n", pPacket));
+			PUSH_PKT_AS_FIRST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket);
+			if (Done) {
+				/*
+				** write Put index to BMU or Polling Unit and make the LE's
+				** available for the hardware
+				*/
+				SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+					("\tWrite new Put Idx\n"));
+
+				SK_OUT32(IoC, PrefetchReg, GET_PUT_IDX(pLETab));
+				UPDATE_HWPUT_IDX(pLETab);
+			}
+			SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+				("<== GiveRxBufferToHw()\n"));
+			return;
+		} else {
+			if (!AllocAndMapRxBuffer(pAC, pPacket, Port)) {
+				/*
+				** Failure while allocating sk_buff might
+				** be due to temporary short of resources
+				** Maybe next time buffers are available.
+				** Until this, the packet remains in the 
+				** RX waiting queue...
+				*/
+				SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
+					SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR,
+					("Failed to allocate Rx buffer\n"));
+
+				SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+					("WaitQueue starts with packet %p\n", pPacket));
+				PUSH_PKT_AS_FIRST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket);
+				if (Done) {
+					/*
+					** write Put index to BMU or Polling 
+					** Unit and make the LE's
+					** available for the hardware
+					*/
+					SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+						("\tWrite new Put Idx\n"));
+	
+					SK_OUT32(IoC, PrefetchReg, GET_PUT_IDX(pLETab));
+					UPDATE_HWPUT_IDX(pLETab);
+				}
+				SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+					("<== GiveRxBufferToHw()\n"));
+				return;
+			}
+		}
+		Done = SK_TRUE;
+
+		/*
+		** :;:; TODO
+		** here we have to check for the 64 bit part of the address first
+		** and use a ADDR64-LE in case of change
+		**
+		** so this is simplified model without csum offload and with
+		** 32 bit phys addresses
+		*/
+		OpCode = OP_PACKET | HW_OWNER;
+		Ctrl = 0;
+
+		/*
+		** Begin fragment processing: On the receive side we always have 
+		** one fragment belonging to one packet.
+		*/
+		GET_RX_LE(pLE, pLETab);
+
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+			("=== LE empty\n"));
+
+		SK_DBG_DUMP_RX_LE(pLE);
+
+		/* 
+		** Fill data into listelement 
+		*/
+		LowAddress = (SK_U32) (pPacket->pFrag->pPhys & 0xffffffff);
+		HighAddress = (SK_U32) (pPacket->pFrag->pPhys >> 32);
+
+		RXLE_SET_ADDR(pLE, LowAddress);
+		RXLE_SET_LEN(pLE, pPacket->pFrag->FragLen);
+		RXLE_SET_CTRL(pLE, Ctrl);
+		RXLE_SET_OPC(pLE, OpCode);
+		FLUSH_OPC(pLE);
+
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+			("=== LE filled\n"));
+
+		SK_DBG_DUMP_RX_LE(pLE);
+
+		/* 
+		** Change OpCode for the following fragments 
+		** of a receive buffer. End of fragment processing.
+		*/
+		OpCode = OP_BUFFER | HW_OWNER;
+
+		/* 
+		** Remember next LE for rx complete 
+		*/
+		pPacket->NextLE = GET_PUT_IDX(pLETab);
+
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+			("\tPackets Next LE is %d\n", pPacket->NextLE));
+
+		/* 
+		** Add packet to working receive buffer queue and get
+		** any next packet out of the waiting queue
+		*/
+		PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_working, pPacket);
+		if (IS_Q_EMPTY(&(pAC->RxPort[Port].RxQ_waiting))) {
+			break; /* get out of while processing */
+		}
+		POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket);
+	}
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+		("\tWaitQueue is empty\n"));
+
+	if (Done) {
+		/*
+		** write Put index to BMU or Polling Unit and make the LE's
+		** available for the hardware
+		*/
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+			("\tWrite new Put Idx\n"));
+
+		/* Speed enhancement for a2 chipsets */
+		if (HW_FEATURE(pAC, HWF_WA_DEV_42)) {
+			spin_lock_irqsave(&pAC->SetPutIndexLock, Flags);
+			SkGeY2SetPutIndex(pAC, pAC->IoBase, Y2_PREF_Q_ADDR(Q_R1,0), pLETab);
+			spin_unlock_irqrestore(&pAC->SetPutIndexLock, Flags);
+		} else {
+			/* write put index */
+			if (Port == 0) { 
+				SK_OUT32(IoC, 
+					Y2_PREF_Q_ADDR(Q_R1, PREF_UNIT_PUT_IDX_REG), 
+					GET_PUT_IDX(pLETab)); 
+			} else {
+				SK_OUT32(IoC, 
+					Y2_PREF_Q_ADDR(Q_R2, PREF_UNIT_PUT_IDX_REG), 
+					GET_PUT_IDX(pLETab)); 
+			}
+
+			/* Update put index */
+			UPDATE_HWPUT_IDX(pLETab);
+		}
+	}
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+		("<== GiveRxBufferToHw()\n"));
+}       /* GiveRxBufferToHw */
+
+/***********************************************************************
+ *
+ *	FillReceiveTableYukon2 - map any waiting RX buffers to HW
+ *
+ * Description:
+ *	If the list element table contains more empty elements than 
+ *	specified this function tries to refill them.
+ *
+ * Notes:
+ *       This function can run only once per port in a system at one time.
+ *
+ * Returns: N/A
+ */
+static void FillReceiveTableYukon2(
+SK_AC   *pAC,   /* pointer to adapter control context */
+SK_IOC   IoC,   /* I/O control context                */
+int      Port)  /* port index of RX                   */
+{
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+		("==> FillReceiveTableYukon2 (Port %c)\n", 'A' + Port));
+
+	if (NUM_FREE_LE_IN_TABLE(&pAC->RxPort[Port].RxLET) >
+		pAC->MaxUnusedRxLeWorking) {
+
+		/* 
+		** Give alle waiting receive buffers down 
+		** The queue holds all RX packets that
+		** need a fresh allocation of the sk_buff.
+		*/
+		if (pAC->RxPort[Port].RxQ_waiting.pHead != NULL) {
+			SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+			("Waiting queue is not empty -> give it to HW"));
+			GiveRxBufferToHw(pAC, IoC, Port, NULL);
+		}
+	}
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+		("<== FillReceiveTableYukon2 ()\n"));
+}	/* FillReceiveTableYukon2 */
+
+/******************************************************************************
+ *
+ *
+ *	HandleReceives - will pass any ready RX packet to kernel
+ *
+ * Description:
+ *	This functions handles a received packet. It checks wether it is
+ *	valid, updates the receive list element table and gives the receive
+ *	buffer to Linux
+ *
+ * Notes:
+ *	This function can run only once per port at one time in the system.
+ *
+ * Returns: N/A
+ */
+static SK_BOOL HandleReceives(
+SK_AC  *pAC,          /* adapter control context                     */
+int     Port,         /* port on which a packet has been received    */
+SK_U16  Len,          /* number of bytes which was actually received */
+SK_U32  FrameStatus,  /* MAC frame status word                       */
+SK_U16  Tcp1,         /* first hw checksum                           */
+SK_U16  Tcp2,         /* second hw checksum                          */
+SK_U32  Tist,         /* timestamp                                   */
+SK_U16  Vlan)         /* Vlan Id                                     */
+{
+
+	SK_PACKET       *pSkPacket;
+	SK_LE_TABLE     *pLETab;
+	SK_MBUF         *pRlmtMbuf;  /* buffer for giving RLMT frame */
+	struct sk_buff  *pMsg;       /* ptr to message holding frame */
+
+	SK_BOOL         SlowPathLock = SK_TRUE;
+	SK_BOOL         IsGoodPkt;
+	SK_BOOL         IsBc;
+	SK_BOOL         IsMc;
+	SK_EVPARA       EvPara;      /* an event parameter union     */
+	SK_I16          LenToFree;   /* must be signed integer       */
+
+	unsigned long   Flags;       /* for spin lock                */
+	unsigned int    RlmtNotifier;
+	unsigned short  Type;
+	int             IpFrameLength;
+	int             FrameLength; /* total length of recvd frame  */
+	int             NumBytes; 
+	int             Result;
+	int             Offset = 0; 
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+		("==> HandleReceives (Port %c)\n", 'A' + Port));
+
+	/* 
+	** initialize vars for selected port 
+	*/
+	pLETab = &pAC->RxPort[Port].RxLET;
+
+	/* 
+	** check whether we want to receive this packet 
+	*/
+	SK_Y2_RXSTAT_CHECK_PKT(Len, FrameStatus, IsGoodPkt);
+
+	/*
+	** Remember length to free (in case of RxBuffer overruns;
+	** unlikely, but might happen once in a while)
+	*/
+	LenToFree = (SK_I16) Len;
+
+	/* 
+	** maybe we put these two checks into the SK_RXDESC_CHECK_PKT macro too 
+	*/
+	if (Len > pAC->RxBufSize) {
+		IsGoodPkt = SK_FALSE;
+	}
+
+	/*
+	** take first receive buffer out of working queue 
+	*/
+	POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket);
+	if (HW_FEATURE(pAC, HWF_WA_DEV_420)) {
+		NbrRxBuffersInHW--;
+	}
+
+	/* 
+	** Verify the received length of the frame! Note that having 
+	** multiple RxBuffers being aware of one single receive packet
+	** (one packet spread over multiple RxBuffers) is not supported 
+	** by this driver!
+	*/
+	if ((Len > pAC->RxBufSize) || (Len > (SK_U16) pSkPacket->PacketLen)) {
+		IsGoodPkt = SK_FALSE;
+	}
+
+	/* 
+	** Reset own bit in LE's between old and new Done index
+	** This is not really necessary but makes debugging easier 
+	*/
+	CLEAR_LE_OWN_FROM_DONE_TO(pLETab, pSkPacket->NextLE);
+
+	/* 
+	** Free the list elements for new Rx buffers 
+	*/
+	SET_DONE_INDEX(pLETab, pSkPacket->NextLE);
+	pMsg = pSkPacket->pMBuf;
+	FrameLength = Len;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+		("Received frame of length %d on port %d\n",FrameLength, Port));
+
+	if (!IsGoodPkt) {
+		/* 
+		** release the DMA mapping 
+		*/
+		pci_dma_sync_single(pAC->PciDev,
+				(dma_addr_t) pSkPacket->pFrag->pPhys,
+				pSkPacket->pFrag->FragLen,
+				PCI_DMA_FROMDEVICE); 
+
+		DEV_KFREE_SKB_ANY(pSkPacket->pMBuf);
+		PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket);
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+			("<== HandleReceives (Port %c)\n", 'A' + Port));
+
+		/*
+		** Sanity check for RxBuffer overruns...
+		*/
+		LenToFree = LenToFree - (pSkPacket->pFrag->FragLen);
+		while (LenToFree > 0) {
+			POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket);
+			if (HW_FEATURE(pAC, HWF_WA_DEV_420)) {
+				NbrRxBuffersInHW--;
+			}
+			CLEAR_LE_OWN_FROM_DONE_TO(pLETab, pSkPacket->NextLE);
+			SET_DONE_INDEX(pLETab, pSkPacket->NextLE);
+			pci_dma_sync_single(pAC->PciDev,
+					(dma_addr_t) pSkPacket->pFrag->pPhys,
+					pSkPacket->pFrag->FragLen,
+					PCI_DMA_FROMDEVICE); 
+
+			DEV_KFREE_SKB_ANY(pSkPacket->pMBuf);
+			PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket);
+			LenToFree = LenToFree - ((SK_I16)(pSkPacket->pFrag->FragLen));
+			
+			SK_DBG_MSG(pAC, SK_DBGMOD_DRV,
+				SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR,
+				("<==HandleReceives (Port %c) drop faulty len pkt(2)\n",'A'+Port));
+		}
+		return(SK_TRUE);
+	} else {
+		/* 
+		** Release the DMA mapping 
+		*/
+		pci_unmap_single(pAC->PciDev,
+				 pSkPacket->pFrag->pPhys,
+				 pAC->RxBufSize - 2,
+				 PCI_DMA_FROMDEVICE);
+
+		skb_put(pMsg, FrameLength); /* set message len */
+		pMsg->ip_summed = CHECKSUM_NONE; /* initial default */
+		if (pAC->RxPort[Port].UseRxCsum) {
+			Type = ntohs(*((short*)&pMsg->data[12]));
+			if (Type == 0x800) {
+				*((char *)&(IpFrameLength)) = pMsg->data[16];
+				*(((char *)&(IpFrameLength))+1) = pMsg->data[17];
+				IpFrameLength = ntohs(IpFrameLength);
+				if ((FrameLength - IpFrameLength) == 0xe) {
+					/* Frame not padded => TCP offload! */
+					if ((((Tcp1 & 0xfffe) && (Tcp2 & 0xfffe)) &&
+						(pAC->GIni.GIChipId == CHIP_ID_GENESIS)) ||
+						(pAC->ChipsetType)) {
+						Result = SkCsGetReceiveInfo(pAC,&pMsg->data[14],
+										Tcp1, Tcp2, Port);
+						if ((Result == SKCS_STATUS_IP_FRAGMENT) ||
+						    (Result == SKCS_STATUS_IP_CSUM_OK)  ||
+						    (Result == SKCS_STATUS_TCP_CSUM_OK) ||
+						    (Result == SKCS_STATUS_UDP_CSUM_OK)) {
+							pMsg->ip_summed = CHECKSUM_UNNECESSARY;
+						} else if ((Result == SKCS_STATUS_TCP_CSUM_ERROR)    ||
+						           (Result == SKCS_STATUS_UDP_CSUM_ERROR)    ||
+						           (Result == SKCS_STATUS_IP_CSUM_ERROR_UDP) ||
+						           (Result == SKCS_STATUS_IP_CSUM_ERROR_TCP) ||
+						           (Result == SKCS_STATUS_IP_CSUM_ERROR)) {
+							SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+								SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR,
+								("skge: CRC error. Frame dropped!\n"));
+							DEV_KFREE_SKB_ANY(pMsg);
+							PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket);
+							SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_RX_PROGRESS,
+								("<==HandleReceives(Port %c)\n",'A'+Port));
+							return(SK_TRUE);
+						} else {
+							pMsg->ip_summed = CHECKSUM_NONE;
+						}
+					}/* checksumControl calculation valid */
+				} /* Frame length check */
+			} /* IP frame */
+		} /* end if (pRxPort->UseRxCsum) */
+		
+		SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+			SK_DBGCAT_DRV_RX_PROGRESS,("V"));
+		RlmtNotifier = SK_RLMT_RX_PROTOCOL;
+
+		IsBc = (FrameStatus & GMR_FS_BC) ? SK_TRUE : SK_FALSE;
+		SK_RLMT_PRE_LOOKAHEAD(pAC,Port,FrameLength,
+					IsBc,&Offset,&NumBytes);
+		if (NumBytes != 0) {
+			IsMc = (FrameStatus & GMR_FS_MC) ? SK_TRUE : SK_FALSE;
+			SK_RLMT_LOOKAHEAD(pAC,Port,&pMsg->data[Offset],
+						IsBc,IsMc,&RlmtNotifier);
+		}
+
+		if (RlmtNotifier == SK_RLMT_RX_PROTOCOL) {
+			SK_DBG_MSG(NULL,SK_DBGMOD_DRV,
+				SK_DBGCAT_DRV_RX_PROGRESS,("W"));
+			if ((Port == pAC->ActivePort)||(pAC->RlmtNets == 2)) {
+				/* send up only frames from active port */
+				SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+					SK_DBGCAT_DRV_RX_PROGRESS,("U"));
+#ifdef xDEBUG
+				DumpMsg(pMsg, "Rx");
+#endif
+				SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
+					FrameLength, Port);
+
+				pMsg->dev = pAC->dev[Port];
+				pMsg->protocol = eth_type_trans(pMsg,
+					pAC->dev[Port]);
+				netif_rx(pMsg);
+				pAC->dev[Port]->last_rx = jiffies;
+			} else { /* drop frame */
+				SK_DBG_MSG(NULL,SK_DBGMOD_DRV,
+					SK_DBGCAT_DRV_RX_PROGRESS,("D"));
+				DEV_KFREE_SKB_ANY(pMsg);
+			}
+		} else { /* This is an RLMT-packet! */
+			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+				SK_DBGCAT_DRV_RX_PROGRESS,("R"));
+			pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
+				pAC->IoBase, FrameLength);
+			if (pRlmtMbuf != NULL) {
+				pRlmtMbuf->pNext = NULL;
+				pRlmtMbuf->Length = FrameLength;
+				pRlmtMbuf->PortIdx = Port;
+				EvPara.pParaPtr = pRlmtMbuf;
+				SK_MEMCPY((char*)(pRlmtMbuf->pData),
+				          (char*)(pMsg->data),FrameLength);
+
+				if (SlowPathLock == SK_TRUE) {
+					spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+					SkEventQueue(pAC, SKGE_RLMT,
+						SK_RLMT_PACKET_RECEIVED,
+						EvPara);
+					pAC->CheckQueue = SK_TRUE;
+					spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+				} else {
+					SkEventQueue(pAC, SKGE_RLMT,
+						SK_RLMT_PACKET_RECEIVED,
+						EvPara);
+					pAC->CheckQueue = SK_TRUE;
+				}
+
+				SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+					SK_DBGCAT_DRV_RX_PROGRESS,("Q"));
+			}
+			if (pAC->dev[Port]->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
+				pMsg->dev = pAC->dev[Port];
+				pMsg->protocol = eth_type_trans(pMsg,pAC->dev[Port]);
+				netif_rx(pMsg);
+				pAC->dev[Port]->last_rx = jiffies;
+			} else {
+				DEV_KFREE_SKB_ANY(pMsg);
+			}
+		} /* if packet for rlmt */
+		PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket);
+	} /* end if-else (IsGoodPkt) */
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+		("<== HandleReceives (Port %c)\n", 'A' + Port));
+	return(SK_TRUE);
+
+}	/* HandleReceives */
+
+/***********************************************************************
+ *
+ * 	CheckForSendComplete - Frees any freeable Tx bufffer 
+ *
+ * Description:
+ *	This function checks the queues of a port for completed send
+ *	packets and returns these packets back to the OS.
+ *
+ * Notes:
+ *	This function can run simultaneously for both ports if
+ *	the OS function OSReturnPacket() can handle this,
+ *
+ *	Such a send complete does not mean, that the packet is really
+ *	out on the wire. We just know that the adapter has copied it
+ *	into its internal memory and the buffer in the systems memory
+ *	is no longer needed.
+ *
+ * Returns: N/A
+ */
+static void CheckForSendComplete(
+SK_AC         *pAC,     /* pointer to adapter control context  */
+SK_IOC         IoC,     /* I/O control context                 */
+int            Port,    /* port index                          */
+SK_PKT_QUEUE  *pPQ,     /* tx working packet queue to check    */
+SK_LE_TABLE   *pLETab,  /* corresponding list element table    */
+unsigned int   Done)    /* done index reported for this LET    */
+{
+	SK_PACKET       *pSkPacket;
+	SK_PKT_QUEUE     SendCmplPktQ = { NULL, NULL, SPIN_LOCK_UNLOCKED };
+	SK_BOOL          DoWakeQueue  = SK_FALSE;
+	unsigned long    Flags;
+	unsigned         Put;
+	
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+		("==> CheckForSendComplete(Port %c)\n", 'A' + Port));
+
+	/* 
+	** Reset own bit in LE's between old and new Done index
+	** This is not really necessairy but makes debugging easier 
+	*/
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+		("Clear Own Bits in TxTable from %d to %d\n",
+		pLETab->Done, (Done == 0) ?
+		NUM_LE_IN_TABLE(pLETab) :
+		(Done - 1)));
+
+	spin_lock_irqsave(&(pPQ->QueueLock), Flags);
+
+	CLEAR_LE_OWN_FROM_DONE_TO(pLETab, Done);
+
+	Put = GET_PUT_IDX(pLETab);
+
+	/* 
+	** Check whether some packets have been completed 
+	*/
+	PLAIN_POP_FIRST_PKT_FROM_QUEUE(pPQ, pSkPacket);
+	while (pSkPacket != NULL) {
+		
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+			("Check Completion of Tx packet %p\n", pSkPacket));
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+			("Put %d NewDone %d NextLe of Packet %d\n", Put, Done,
+			pSkPacket->NextLE));
+
+		if ((Put > Done) &&
+			((pSkPacket->NextLE > Put) || (pSkPacket->NextLE <= Done))) {
+			PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(&SendCmplPktQ, pSkPacket);
+			SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+				("Packet finished (a)\n"));
+		} else if ((Done > Put) &&
+			(pSkPacket->NextLE > Put) && (pSkPacket->NextLE <= Done)) {
+			PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(&SendCmplPktQ, pSkPacket);
+			SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+				("Packet finished (b)\n"));
+		} else if ((Done == TXA_MAX_LE-1) && (Put == 0) && (pSkPacket->NextLE == 0)) {
+			PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(&SendCmplPktQ, pSkPacket);
+			SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+				("Packet finished (b)\n"));
+			DoWakeQueue = SK_TRUE;
+		} else if (Done == Put) {
+			/* all packets have been sent */
+			PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(&SendCmplPktQ, pSkPacket);
+			SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+				("Packet finished (c)\n"));
+		} else {
+			SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+				("Packet not yet finished\n"));
+			PLAIN_PUSH_PKT_AS_FIRST_IN_QUEUE(pPQ, pSkPacket);
+			break;
+		}
+		PLAIN_POP_FIRST_PKT_FROM_QUEUE(pPQ, pSkPacket);
+	}
+	spin_unlock_irqrestore(&(pPQ->QueueLock), Flags);
+
+	/* 
+	** Set new done index in list element table
+	*/
+	SET_DONE_INDEX(pLETab, Done);
+	 
+	/*
+	** All TX packets that are send complete should be added to
+	** the free queue again for new sents to come
+	*/
+	pSkPacket = SendCmplPktQ.pHead;
+	while (pSkPacket != NULL) {
+		while (pSkPacket->pFrag != NULL) {
+			pci_unmap_page(pAC->PciDev,
+					(dma_addr_t) pSkPacket->pFrag->pPhys,
+					pSkPacket->pFrag->FragLen,
+					PCI_DMA_FROMDEVICE);
+			pSkPacket->pFrag = pSkPacket->pFrag->pNext;
+		}
+
+		DEV_KFREE_SKB_ANY(pSkPacket->pMBuf);
+		pSkPacket->pMBuf	= NULL;
+		pSkPacket = pSkPacket->pNext; /* get next packet */
+	}
+
+	/*
+	** Append the available TX packets back to free queue
+	*/
+	if (SendCmplPktQ.pHead != NULL) { 
+		spin_lock_irqsave(&(pAC->TxPort[Port][0].TxQ_free.QueueLock), Flags);
+		if (pAC->TxPort[Port][0].TxQ_free.pTail != NULL) {
+			pAC->TxPort[Port][0].TxQ_free.pTail->pNext = SendCmplPktQ.pHead;
+			pAC->TxPort[Port][0].TxQ_free.pTail        = SendCmplPktQ.pTail;
+			if (pAC->TxPort[Port][0].TxQ_free.pHead->pNext == NULL) {
+                                netif_wake_queue(pAC->dev[Port]);
+                        }
+		} else {
+			pAC->TxPort[Port][0].TxQ_free.pHead = SendCmplPktQ.pHead;
+			pAC->TxPort[Port][0].TxQ_free.pTail = SendCmplPktQ.pTail; 
+			netif_wake_queue(pAC->dev[Port]);
+		}
+		if (Done == Put) {
+                        netif_wake_queue(pAC->dev[Port]);
+                }
+                if (DoWakeQueue) {
+                        netif_wake_queue(pAC->dev[Port]);
+                        DoWakeQueue = SK_FALSE;
+                }
+		spin_unlock_irqrestore(&pAC->TxPort[Port][0].TxQ_free.QueueLock, Flags);
+	}
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+		("<== CheckForSendComplete()\n"));
+
+	return;
+}	/* CheckForSendComplete */
+
+/*****************************************************************************
+ *
+ *	UnmapAndFreeTxPktBuffer
+ *
+ * Description:
+ *      This function free any allocated space of receive buffers
+ *
+ * Arguments:
+ *      pAC - A pointer to the adapter context struct.
+ *
+ */
+static void UnmapAndFreeTxPktBuffer(
+SK_AC       *pAC,       /* pointer to adapter context             */
+SK_PACKET   *pSkPacket,	/* pointer to port struct of ring to fill */
+int          TxPort)    /* TX port index                          */
+{
+	SK_FRAG	 *pFrag = pSkPacket->pFrag;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+		("--> UnmapAndFreeTxPktBuffer\n"));
+
+	while (pFrag != NULL) {
+		pci_unmap_page(pAC->PciDev,
+				(dma_addr_t) pFrag->pPhys,
+				pFrag->FragLen,
+				PCI_DMA_FROMDEVICE);
+		pFrag = pFrag->pNext;
+	}
+
+	DEV_KFREE_SKB_ANY(pSkPacket->pMBuf);
+	pSkPacket->pMBuf	= NULL;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+		("<-- UnmapAndFreeTxPktBuffer\n"));
+}
+
+/*****************************************************************************
+ *
+ * 	HandleStatusLEs
+ *
+ * Description:
+ *	This function checks for any new status LEs that may have been 
+  *	received. Those status LEs may either be Rx or Tx ones.
+ *
+ * Returns:	N/A
+ */
+static SK_BOOL HandleStatusLEs(
+#ifdef CONFIG_SK98LIN_NAPI
+SK_AC *pAC,       /* pointer to adapter context   */
+int   *WorkDone,  /* Done counter needed for NAPI */
+int    WorkToDo)  /* ToDo counter for NAPI        */
+#else
+SK_AC *pAC)       /* pointer to adapter context   */
+#endif
+{
+	int       DoneTxA[SK_MAX_MACS];
+	int       DoneTxS[SK_MAX_MACS];
+	int       Port;
+	SK_BOOL   handledStatLE = SK_FALSE;
+	SK_BOOL   NewDone       = SK_FALSE;
+	SK_HWLE  *pLE;
+	SK_U16    HighVal;
+	SK_U32    LowVal;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+		("==> HandleStatusLEs\n"));
+
+	do {
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+			("Check next Own Bit of ST-LE[%d]: 0x%li \n",
+			(pAC->StatusLETable.Done + 1) % NUM_LE_IN_TABLE(&pAC->StatusLETable),
+			 OWN_OF_FIRST_LE(&pAC->StatusLETable)));
+
+		while (OWN_OF_FIRST_LE(&pAC->StatusLETable) == HW_OWNER) {
+			GET_ST_LE(pLE, &pAC->StatusLETable);
+			SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+				("Working on finished status LE[%d]:\n",
+				GET_DONE_INDEX(&pAC->StatusLETable)));
+			SK_DBG_DUMP_ST_LE(pLE);
+			handledStatLE = SK_TRUE;
+			switch (STLE_GET_OPC(pLE) & ~HW_OWNER) {
+			case OP_RXSTAT:
+				if (pAC->StatusLETable.private) {
+					/* 
+					** This is always the last Status LE belonging
+					** to a received packet -> handle it...
+					*/
+					HandleReceives(
+						pAC,
+						STLE_GET_LINK(pLE),
+						STLE_GET_LEN(pLE),
+						STLE_GET_FRSTATUS(pLE),
+						pAC->StatusLETable.Bmu.Stat.TcpSum1,
+						pAC->StatusLETable.Bmu.Stat.TcpSum2,
+						pAC->StatusLETable.Bmu.Stat.RxTimeStamp,
+						pAC->StatusLETable.Bmu.Stat.VlanId);
+					pAC->StatusLETable.private = SK_FALSE;
+#ifdef CONFIG_SK98LIN_NAPI
+					if (*WorkDone >= WorkToDo) {
+						break;
+					}
+					(*WorkDone)++;
+#endif
+				} else {
+					pAC->StatusLETable.Bmu.Stat.TcpSum1 = STLE_GET_TCP1(pLE);
+					pAC->StatusLETable.Bmu.Stat.TcpSum2 = STLE_GET_TCP2(pLE);
+					pAC->StatusLETable.private = SK_TRUE;
+				}
+				break;
+			case OP_RXVLAN:
+				/* this value will be used for next RXSTAT */
+				pAC->StatusLETable.Bmu.Stat.VlanId = STLE_GET_VLAN(pLE);
+				break;
+			case OP_RXTIMEVLAN:
+				/* this value will be used for next RXSTAT */
+				pAC->StatusLETable.Bmu.Stat.VlanId = STLE_GET_VLAN(pLE);
+				/* fall through */
+			case OP_RXTIMESTAMP:
+				/* this value will be used for next RXSTAT */
+				pAC->StatusLETable.Bmu.Stat.RxTimeStamp = STLE_GET_TIST(pLE);
+				break;
+			case OP_RXCHKSVLAN:
+				/* this value will be used for next RXSTAT */
+				pAC->StatusLETable.Bmu.Stat.VlanId = STLE_GET_VLAN(pLE);
+				/* fall through */
+			case OP_RXCHKS:
+				/* this value will be used for next RXSTAT */
+				pAC->StatusLETable.Bmu.Stat.TcpSum1 = STLE_GET_TCP1(pLE);
+				pAC->StatusLETable.Bmu.Stat.TcpSum2 = STLE_GET_TCP2(pLE);
+				pAC->StatusLETable.private = SK_TRUE;
+				break;
+			case OP_RSS_HASH:
+				/* this value will be used for next RXSTAT */
+#if 0
+				pAC->StatusLETable.Bmu.Stat.RssHashValue = STLE_GET_RSS(pLE);
+#endif
+				break;
+			case OP_TXINDEXLE:
+				/*
+				** :;:; TODO
+				** it would be possible to check for which queues
+				** the index has been changed and call 
+				** CheckForSendComplete() only for such queues
+				*/
+				STLE_GET_DONE_IDX(pLE,LowVal,HighVal);
+				SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+					("LowVal: 0x%x HighVal: 0x%x\n", LowVal, HighVal));
+
+				/*
+				** It would be possible to check whether we really
+				** need the values for second port or sync queue, 
+				** but I think checking whether we need them is 
+				** more expensive than the calculation
+				*/
+				DoneTxA[0] = STLE_GET_DONE_IDX_TXA1(LowVal,HighVal);
+				DoneTxS[0] = STLE_GET_DONE_IDX_TXS1(LowVal,HighVal);
+				DoneTxA[1] = STLE_GET_DONE_IDX_TXA2(LowVal,HighVal);
+				DoneTxS[1] = STLE_GET_DONE_IDX_TXS2(LowVal,HighVal);
+
+				SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+					("DoneTxa1 0x%x DoneTxS1: 0x%x DoneTxa2 0x%x DoneTxS2: 0x%x\n",
+					DoneTxA[0], DoneTxS[0], DoneTxA[1], DoneTxS[1]));
+
+				NewDone = SK_TRUE;
+				break;
+			default:
+				/* 
+				** Have to handle the illegal Opcode in Status LE 
+				*/
+				SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+					("Unexpected OpCode\n"));
+				break;
+			}
+
+			/* 
+			** Reset own bit we have to do this in order to detect a overflow 
+			*/
+			STLE_SET_OPC(pLE, SW_OWNER);
+		}
+
+		/* 
+		** Now handle any new transmit complete 
+		*/
+		if (NewDone) {
+			SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+				("Done Index for Tx BMU has been changed\n"));
+			for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) {
+				/* 
+				** Do we have a new Done idx ? 
+				*/
+				if (DoneTxA[Port] != GET_DONE_INDEX(&pAC->TxPort[Port][0].TxALET)) {
+					SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+						("Check TxA%d\n", Port + 1));
+					CheckForSendComplete(pAC, pAC->IoBase, Port,
+						&(pAC->TxPort[Port][0].TxAQ_working),
+						&pAC->TxPort[Port][0].TxALET,
+						DoneTxA[Port]);
+				} else {
+					SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+						("No changes for TxA%d\n", Port + 1));
+				}
+#if USE_SYNC_TX_QUEUE
+				if (HW_SYNC_TX_SUPPORTED(pAC)) {
+					/* 
+					** Do we have a new Done idx ? 
+					*/
+					if (DoneTxS[Port] !=
+						GET_DONE_INDEX(&pAC->TxPort[Port][0].TxSLET)) {
+						SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
+							SK_DBGCAT_DRV_INT_SRC,
+							("Check TxS%d\n", Port));
+						CheckForSendComplete(pAC, pAC->IoBase, Port,
+							&(pAC->TxPort[Port][0].TxSQ_working),
+							&pAC->TxPort[Port][0].TxSLET,
+							DoneTxS[Port]);
+					} else {
+						SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
+							SK_DBGCAT_DRV_INT_SRC,
+							("No changes for TxS%d\n", Port));
+					}
+				}
+#endif
+			}
+		}
+		NewDone = SK_FALSE;
+
+		/* 
+		** Check whether we have to refill our RX table  
+		*/
+		if (HW_FEATURE(pAC, HWF_WA_DEV_420)) {
+			if (NbrRxBuffersInHW < MAX_NBR_RX_BUFFERS_IN_HW) {
+				for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) {
+					SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+						("Check for refill of RxBuffers on Port %c\n", 'A' + Port));
+					FillReceiveTableYukon2(pAC, pAC->IoBase, Port);
+				}
+			}
+		} else {
+			for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) {
+				SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+					("Check for refill of RxBuffers on Port %c\n", 'A' + Port));
+				if (NUM_FREE_LE_IN_TABLE(&pAC->RxPort[Port].RxLET) >= 64) {
+					FillReceiveTableYukon2(pAC, pAC->IoBase, Port);
+				}
+			}
+		}
+#ifdef CONFIG_SK98LIN_NAPI
+		if (*WorkDone >= WorkToDo) {
+			break;
+		}
+#endif
+	} while (OWN_OF_FIRST_LE(&pAC->StatusLETable) == HW_OWNER);
+
+	/* 
+	** Clear status BMU 
+	*/
+	SK_OUT32(pAC->IoBase, STAT_CTRL, SC_STAT_CLR_IRQ);
+
+	return(handledStatLE);
+}	/* HandleStatusLEs */
+
+/*****************************************************************************
+ *
+ *	AllocateAndInitLETables - allocate memory for the LETable and init
+ *
+ * Description:
+ *	This function will allocate space for the LETable and will also  
+ *	initialize them. The size of the tables must have been specified 
+ *	before.
+ *
+ * Arguments:
+ *	pAC - A pointer to the adapter context struct.
+ *
+ * Returns:
+ *	SK_TRUE  - all LETables initialized
+ *	SK_FALSE - failed
+ */
+static SK_BOOL AllocateAndInitLETables(
+SK_AC *pAC)  /* pointer to adapter context */
+{
+	char           *pVirtMemAddr;
+	dma_addr_t     pPhysMemAddr;
+	SK_U32         CurrMac;
+	unsigned       Size;
+	unsigned       Aligned;
+	unsigned       Alignment;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
+		("==> AllocateAndInitLETables()\n"));
+
+	/*
+	** Determine how much memory we need with respect to alignment
+	*/
+	Alignment = MAX_LEN_OF_LE_TAB;
+	Size = 0;
+	for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) {
+		SK_ALIGN_SIZE(LE_TAB_SIZE(RX_MAX_LE), Alignment, Aligned);
+		Size += Aligned;
+		SK_ALIGN_SIZE(LE_TAB_SIZE(TXA_MAX_LE), Alignment, Aligned);
+		Size += Aligned;
+		SK_ALIGN_SIZE(LE_TAB_SIZE(TXS_MAX_LE), Alignment, Aligned);
+		Size += Aligned;
+	}
+	SK_ALIGN_SIZE(LE_TAB_SIZE(ST_MAX_LE), Alignment, Aligned);
+	Size += Aligned;
+	Size += Alignment;
+	pAC->SizeOfAlignedLETables = Size;
+	
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, 
+			("Need %08x bytes in total\n", Size));
+	
+	/*
+	** Allocate the memory
+	*/
+	pVirtMemAddr = pci_alloc_consistent(pAC->PciDev, Size, &pPhysMemAddr);
+	if (pVirtMemAddr == NULL) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
+			SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR,
+			("AllocateAndInitLETables: kernel malloc failed!\n"));
+		return (SK_FALSE); 
+	}
+
+	/* 
+	** Initialize the memory
+	*/
+	SK_MEMSET(pVirtMemAddr, 0, Size);
+	ALIGN_ADDR(pVirtMemAddr, Alignment); /* Macro defined in skgew.h */
+	
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
+		("Virtual address of LETab is %8p!\n", pVirtMemAddr));
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
+		("Phys address of LETab is %8p!\n", (void *) pPhysMemAddr));
+
+	for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
+			("RxLeTable for Port %c", 'A' + CurrMac));
+		SkGeY2InitSingleLETable(
+			pAC,
+			&pAC->RxPort[CurrMac].RxLET,
+			RX_MAX_LE,
+			pVirtMemAddr,
+			(SK_U32) (pPhysMemAddr & 0xffffffff),
+			(SK_U32) (((SK_U64) pPhysMemAddr) >> 32));
+
+		SK_ALIGN_SIZE(LE_TAB_SIZE(RX_MAX_LE), Alignment, Aligned);
+		pVirtMemAddr += Aligned;
+		pPhysMemAddr += Aligned;
+
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
+			("TxALeTable for Port %c", 'A' + CurrMac));
+		SkGeY2InitSingleLETable(
+			pAC,
+			&pAC->TxPort[CurrMac][0].TxALET,
+			TXA_MAX_LE,
+			pVirtMemAddr,
+			(SK_U32) (pPhysMemAddr & 0xffffffff),
+			(SK_U32) (((SK_U64) pPhysMemAddr) >> 32));
+
+		SK_ALIGN_SIZE(LE_TAB_SIZE(TXA_MAX_LE), Alignment, Aligned);
+		pVirtMemAddr += Aligned;
+		pPhysMemAddr += Aligned;
+
+		SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
+			("TxSLeTable for Port %c", 'A' + CurrMac));
+		SkGeY2InitSingleLETable(
+			pAC,
+			&pAC->TxPort[CurrMac][0].TxSLET,
+			TXS_MAX_LE,
+			pVirtMemAddr,
+			(SK_U32) (pPhysMemAddr & 0xffffffff),
+			(SK_U32) (((SK_U64) pPhysMemAddr) >> 32));
+
+		SK_ALIGN_SIZE(LE_TAB_SIZE(TXS_MAX_LE), Alignment, Aligned);
+		pVirtMemAddr += Aligned;
+		pPhysMemAddr += Aligned;
+	}
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,("StLeTable"));
+
+	SkGeY2InitSingleLETable(
+		pAC,
+		&pAC->StatusLETable,
+		ST_MAX_LE,
+		pVirtMemAddr,
+		(SK_U32) (pPhysMemAddr & 0xffffffff),
+		(SK_U32) (((SK_U64) pPhysMemAddr) >> 32));
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, 
+		("<== AllocateAndInitLETables(OK)\n"));
+	return(SK_TRUE);
+}	/* AllocateAndInitLETables */
+
+/*****************************************************************************
+ *
+ *	AllocatePacketBuffersYukon2 - allocate packet and fragment buffers
+ *
+ * Description:
+ *      This function will allocate space for the packets and fragments
+ *
+ * Arguments:
+ *      pAC - A pointer to the adapter context struct.
+ *
+ * Returns:
+ *      SK_TRUE  - Memory was allocated correctly
+ *      SK_FALSE - An error occured
+ */
+static SK_BOOL AllocatePacketBuffersYukon2(
+SK_AC *pAC)  /* pointer to adapter context */
+{
+	SK_PACKET       *pRxPacket;
+	SK_PACKET       *pTxPacket;
+	SK_U32           CurrBuff;
+	SK_U32           CurrMac;
+	unsigned long    Flags; /* needed for POP/PUSH functions */
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
+		("==> AllocatePacketBuffersYukon2()"));
+
+	for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) {
+		/* 
+		** Allocate RX packet space, initialize the packets and
+		** add them to the RX waiting queue. Waiting queue means 
+		** that packet and fragment are initialized, but no sk_buff
+		** has been assigned to it yet.
+		*/
+		pAC->RxPort[CurrMac].ReceivePacketTable = 
+			kmalloc((RX_MAX_NBR_BUFFERS * sizeof(SK_PACKET)), GFP_KERNEL);
+
+		if (pAC->RxPort[CurrMac].ReceivePacketTable == NULL) {
+			SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR,
+				("AllocatePacketBuffersYukon2: no mem RxPkts (port %i)",CurrMac));
+			break;
+		} else {
+			SK_MEMSET(pAC->RxPort[CurrMac].ReceivePacketTable, 0, 
+				(RX_MAX_NBR_BUFFERS * sizeof(SK_PACKET)));
+
+			pRxPacket = pAC->RxPort[CurrMac].ReceivePacketTable;
+
+			for (CurrBuff=0;CurrBuff<RX_MAX_NBR_BUFFERS;CurrBuff++) {
+				pRxPacket->pFrag = &(pRxPacket->FragArray[0]);
+				pRxPacket->NumFrags = 1;
+				PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[CurrMac].RxQ_waiting, pRxPacket);
+				pRxPacket++;
+			}
+		}
+
+		/*
+		** Allocate TX packet space, initialize the packets and
+		** add them to the TX free queue. Free queue means that
+		** packet is available and initialized, but no fragment
+		** has been assigned to it. (Must be done at TX side)
+		*/
+		pAC->TxPort[CurrMac][0].TransmitPacketTable = 
+			kmalloc((TX_MAX_NBR_BUFFERS * sizeof(SK_PACKET)), GFP_KERNEL);
+
+		if (pAC->TxPort[CurrMac][0].TransmitPacketTable == NULL) {
+			SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR,
+				("AllocatePacketBuffersYukon2: no mem TxPkts (port %i)",CurrMac));
+			kfree(pAC->RxPort[CurrMac].ReceivePacketTable);
+			return(SK_FALSE);
+		} else {
+			SK_MEMSET(pAC->TxPort[CurrMac][0].TransmitPacketTable, 0, 
+				(TX_MAX_NBR_BUFFERS * sizeof(SK_PACKET)));
+		
+			pTxPacket = pAC->TxPort[CurrMac][0].TransmitPacketTable;
+
+			for (CurrBuff=0;CurrBuff<TX_MAX_NBR_BUFFERS;CurrBuff++) {
+				PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->TxPort[CurrMac][0].TxQ_free, pTxPacket);
+				pTxPacket++;
+			}
+		}
+	} /* end for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) */
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
+		("<== AllocatePacketBuffersYukon2 (OK)\n"));
+	return(SK_TRUE);
+
+}	/* AllocatePacketBuffersYukon2 */
+
+/*****************************************************************************
+ *
+ *	FreeLETables - release allocated memory of LETables
+ *
+ * Description:
+ *      This function will free all resources of the LETables
+ *
+ * Arguments:
+ *      pAC - A pointer to the adapter context struct.
+ *
+ * Returns: N/A
+ */
+static void FreeLETables(
+SK_AC *pAC)  /* pointer to adapter control context */
+{
+	dma_addr_t  pPhysMemAddr;
+	char       *pVirtMemAddr;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("==> FreeLETables()\n"));
+	
+	/*
+	** The RxLETable is the first of all LET. 
+	** Therefore we can use its address for the input 
+	** of the free function.
+	*/
+	pVirtMemAddr = (char *) pAC->RxPort[0].RxLET.pLETab;
+	pPhysMemAddr = (((SK_U64) pAC->RxPort[0].RxLET.pPhyLETABHigh << (SK_U64) 32) | 
+			((SK_U64) pAC->RxPort[0].RxLET.pPhyLETABLow));
+
+	/* free continuous memory */
+	pci_free_consistent(pAC->PciDev, pAC->SizeOfAlignedLETables,
+			    pVirtMemAddr, pPhysMemAddr);
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("<== FreeLETables()\n"));
+}	/* FreeLETables */
+
+/*****************************************************************************
+ *
+ *	FreePacketBuffers - free's all packet buffers of an adapter
+ *
+ * Description:
+ *      This function will free all previously allocated memory of the 
+ *	packet buffers.
+ *
+ * Arguments:
+ *      pAC - A pointer to the adapter context struct.
+ *
+ * Returns: N/A
+ */
+static void FreePacketBuffers(
+SK_AC *pAC)  /* pointer to adapter control context */
+{
+	int Port;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("==> FreePacketBuffers()\n"));
+	
+	for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) {
+		kfree(pAC->RxPort[Port].ReceivePacketTable);
+		kfree(pAC->TxPort[Port][0].TransmitPacketTable);
+	}
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
+		("<== FreePacketBuffers()\n"));
+}	/* FreePacketBuffers */
+
+/*****************************************************************************
+ *
+ * 	AllocAndMapRxBuffer - fill one buffer into the receive packet/fragment
+ *
+ * Description:
+ *	The function allocates a new receive buffer and assigns it to the
+ *	the passsed receive packet/fragment
+ *
+ * Returns:
+ *	SK_TRUE - a buffer was allocated and assigned
+ *	SK_FALSE - a buffer could not be added
+ */
+static SK_BOOL AllocAndMapRxBuffer(
+SK_AC      *pAC,        /* pointer to the adapter control context */
+SK_PACKET  *pSkPacket,  /* pointer to packet that is to fill      */
+int         Port)       /* port the packet belongs to             */
+{
+	struct sk_buff *pMsgBlock;  /* pointer to a new message block  */
+	SK_U64          PhysAddr;   /* physical address of a rx buffer */
+
+	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+		("--> AllocAndMapRxBuffer (Port: %i)\n", Port));
+
+	pMsgBlock = alloc_skb(pAC->RxBufSize, GFP_ATOMIC);
+	if (pMsgBlock == NULL) {
+		SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+			SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR,
+			("%s: Allocation of rx buffer failed !\n",
+			pAC->dev[Port]->name));
+		SK_PNMI_CNT_NO_RX_BUF(pAC, pAC->RxPort[Port].PortIndex);
+		return(SK_FALSE);
+	} 
+
+	PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
+		virt_to_page(pMsgBlock->data),
+		((unsigned long) pMsgBlock->data &
+		~PAGE_MASK),
+		pAC->RxBufSize - 2,
+		PCI_DMA_FROMDEVICE);
+
+	pSkPacket->pFrag->pVirt   = pMsgBlock->data;
+	pSkPacket->pFrag->pPhys   = PhysAddr;
+	pSkPacket->pFrag->FragLen = pAC->RxBufSize - 2; /* for correct unmap */
+	pSkPacket->pMBuf          = pMsgBlock;	
+	pSkPacket->PacketLen      = pAC->RxBufSize - 2;
+
+	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
+		("<-- AllocAndMapRxBuffer\n"));
+
+	return (SK_TRUE);
+}	/* AllocAndMapRxBuffer */
+
+/*******************************************************************************
+ *
+ * End of file
+ *
+ ******************************************************************************/
diff -urN linux-2.4.29/drivers/net/sk98lin/sky2le.c linux-2.4.29-uc1/drivers/net/sk98lin/sky2le.c
--- linux-2.4.29/drivers/net/sk98lin/sky2le.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/sk98lin/sky2le.c	2005-06-14 02:12:09.000000000 +0100
@@ -0,0 +1,470 @@
+/*****************************************************************************
+ *
+ *	Name:		sky2le.c
+ *	Project:	Gigabit Ethernet Adapters, Common Modules
+ *	Version:	$Revision: 1.2 $
+ *	Date:		$Date: 2004/11/17 05:40:48 $
+ *	Purpose: 	Functions for handling List Element Tables
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ *	(C)Copyright 2002-2004 Marvell.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2 of the License, or
+ *	(at your option) any later version.
+ *	The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+static const char SysKonnectFileId[] = "@(#)"
+	"$Id: sky2le.c,v 1.2 2004/11/17 05:40:48 toby Exp $ (C) Marvell.";
+#endif /* DEBUG || (!LINT && !SK_SLIM) */
+
+/*****************************************************************************
+ *
+ * Description:
+ *
+ * This module contains the code necessary for handling List Elements.
+ *
+ * Supported Gigabit Ethernet Chipsets:
+ *	Yukon-2 (PCI, PCI-X, PCI-Express)
+ *
+ * Include File Hierarchy:
+ *
+ *
+ *****************************************************************************/
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+
+/* defines *******************************************************************/
+/* typedefs ******************************************************************/
+/* global variables **********************************************************/
+/* local variables ***********************************************************/
+/* function prototypes *******************************************************/
+
+/*****************************************************************************
+ *
+ * SkGeY2InitSingleLETable() - initializes a list element table
+ *
+ * Description:
+ *	This function will initialize the selected list element table.
+ *	Should be called once during DriverInit. No InitLevel required.
+ *
+ * Arguments:
+ *	pAC			- pointer to the adapter context struct.
+ *	pLETab		- pointer to list element table structure
+ *	NumLE		- number of list elements in this table
+ *	pVMem		- virtual address of memory allocated for this LE table
+ *	PMemLowAddr - physical address of memory to be used for the LE table
+ *	PMemHighAddr
+ *
+ * Returns:
+ *	nothing
+ */
+void SkGeY2InitSingleLETable(
+SK_AC	*pAC,			/* pointer to adapter context */
+SK_LE_TABLE	*pLETab,	/* pointer to list element table to be initialized */
+unsigned int NumLE,		/* number of list elements to be filled in tab */
+void	*pVMem,			/* virtual address of memory used for list elements */
+SK_U32	PMemLowAddr,	/* physical addr of mem used for LE */
+SK_U32	PMemHighAddr)
+{
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("==> SkGeY2InitSingleLETable()\n"));
+
+#ifdef DEBUG
+	if (NumLE != 2) {	/* not table for polling unit */
+		if ((NumLE % MIN_LEN_OF_LE_TAB) != 0 || NumLE > MAX_LEN_OF_LE_TAB) {
+			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+				("ERROR: Illegal number of list elements %d\n", NumLE));
+		}
+	}
+#endif /* DEBUG */
+
+	/* special case: unused list element table */
+	if (NumLE == 0) {
+		PMemLowAddr = 0;
+		PMemHighAddr = 0;
+		pVMem = 0;
+	}
+
+	/* set addresses */
+	pLETab->pPhyLETABLow = PMemLowAddr;
+	pLETab->pPhyLETABHigh = PMemHighAddr;
+	pLETab->pLETab = (void *)pVMem;
+	
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("contains %d LEs", NumLE));
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		(" and starts at virt %08p and phys %08lx:%08lx\n",
+		pVMem, PMemHighAddr, PMemLowAddr));
+
+	/* initialize indexes */
+	pLETab->Done = 0;
+	pLETab->Put = 0;
+	pLETab->HwPut = 0;
+	/* initialize size */
+	pLETab->Num = NumLE;
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("<== SkGeY2InitSingleLETable()\n"));
+}	/* SkGeY2InitSingleLETable */
+
+/*****************************************************************************
+ *
+ * SkGeY2InitPrefetchUnit() - Initialize a Prefetch Unit
+ *
+ * Description:
+ *	Calling this function requires an already configured list element
+ *	table. The prefetch unit to be configured is specified in the parameter
+ *	'Queue'. The function is able to initialze the prefetch units of
+ *	the following queues: Q_R1, Q_R2, Q_XS1, Q_XS2, Q_XA1, Q_XA2.
+ *	The funcution should be called before SkGeInitPort().
+ *
+ * Arguments:
+ *	pAC - pointer to the adapter context struct.
+ *	IoC - I/O context.
+ *	Queue - I/O offset of queue e.g. Q_XA1.
+ *	pLETab - pointer to list element table to be initialized
+ *
+ * Returns: N/A
+ */
+void SkGeY2InitPrefetchUnit(
+SK_AC	*pAC,			/* pointer to adapter context */
+SK_IOC	IoC,			/* I/O context */
+unsigned int Queue,		/* Queue offset for finding the right registers */
+SK_LE_TABLE	*pLETab)	/* pointer to list element table to be initialized */
+{
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("==> SkGeY2InitPrefetchUnit()\n"));
+
+#ifdef DEBUG
+	if (Queue != Q_R1 && Queue != Q_R2 && Queue != Q_XS1 &&
+		Queue != Q_XS2 && Queue != Q_XA1 && Queue != Q_XA2) {
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+			("ERROR: Illegal queue identifier %x\n", Queue));
+	}
+#endif /* DEBUG */
+
+	/* disable the prefetch unit */
+	SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_CTRL_REG), PREF_UNIT_RST_SET);
+	SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_CTRL_REG), PREF_UNIT_RST_CLR);
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("Base address: %08lx:%08lx\n", pLETab->pPhyLETABHigh,
+		pLETab->pPhyLETABLow));
+
+	/* Set the list base address  high part*/
+	SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_ADDR_HI_REG),
+		pLETab->pPhyLETABHigh);
+
+	/* Set the list base address low part */
+	SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_ADDR_LOW_REG),
+		pLETab->pPhyLETABLow);
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("Last index: %d\n", pLETab->Num-1));
+
+	/* Set the list last index */
+	SK_OUT16(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_LAST_IDX_REG),
+		(SK_U16)(pLETab->Num - 1));
+
+	/* turn on prefetch unit */
+	SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_CTRL_REG), PREF_UNIT_OP_ON);
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("<== SkGeY2InitPrefetchUnit()\n"));
+}	/* SkGeY2InitPrefetchUnit */
+
+
+/*****************************************************************************
+ *
+ * SkGeY2InitStatBmu() -	Initialize the Status BMU
+ *
+ * Description:
+ *	Calling this function requires an already configured list element
+ *	table. Ensure the status BMU is only initialized once during
+ *  DriverInit - InitLevel2 required.
+ *
+ * Arguments:
+ *	pAC - pointer to the adapter context struct.
+ *	IoC - I/O context.
+ *	pLETab - pointer to status LE table to be initialized
+ *
+ * Returns: N/A
+ */
+void SkGeY2InitStatBmu(
+SK_AC	*pAC,			/* pointer to adapter context */
+SK_IOC	IoC,			/* I/O context */
+SK_LE_TABLE	*pLETab)	/* pointer to status LE table */
+{
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("==> SkGeY2InitStatBmu()\n"));
+
+	/* disable the prefetch unit */
+	SK_OUT32(IoC, STAT_CTRL, SC_STAT_RST_SET);
+	SK_OUT32(IoC, STAT_CTRL, SC_STAT_RST_CLR);
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("Base address Low: %08lX\n", pLETab->pPhyLETABLow));
+
+	/* Set the list base address */
+	SK_OUT32(IoC, STAT_LIST_ADDR_LO, pLETab->pPhyLETABLow);
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("Base address High: %08lX\n", pLETab->pPhyLETABHigh));
+
+	SK_OUT32(IoC, STAT_LIST_ADDR_HI, pLETab->pPhyLETABHigh);
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("Last index: %d\n", pLETab->Num - 1));
+
+	/* Set the list last index */
+	SK_OUT16(IoC, STAT_LAST_IDX, (SK_U16)(pLETab->Num - 1));
+
+	if (HW_FEATURE(pAC, HWF_WA_DEV_43_418)) {
+
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+			("Set Tx index threshold\n"));
+		/* WA for dev. #4.3 */
+		SK_OUT16(IoC, STAT_TX_IDX_TH, ST_TXTH_IDX_MASK);
+
+		/* set Status-FIFO watermark */
+		SK_OUT8(IoC, STAT_FIFO_WM, 0x21);		/* WA for dev. #4.18 */
+
+		/* set Status-FIFO ISR watermark */
+		SK_OUT8(IoC, STAT_FIFO_ISR_WM, 0x07);	/* WA for dev. #4.18 */
+
+		/* WA for dev. #4.3 and #4.18 */
+		/* set Status-FIFO Tx timer init value */
+		SK_OUT32(IoC, STAT_TX_TIMER_INI, HW_MS_TO_TICKS(pAC, 10));
+	}
+	else {
+		/*
+		 * Further settings may be added if required...
+		 * 1) Status-FIFO watermark (STAT_FIFO_WM, STAT_FIFO_ISR_WM)
+		 * 2) Status-FIFO timer values (STAT_TX_TIMER_INI,
+		 *		STAT_LEV_TIMER_INI and STAT_ISR_TIMER_INI)
+		 * but tests shows that the default values give the best results,
+		 * therefore the defaults are used.
+		 */
+
+		/*
+		 * Theses settings should avoid the
+		 * temporary hanging of the status BMU.
+		 * May be not all required... still under investigation...
+		 */
+		SK_OUT16(IoC, STAT_TX_IDX_TH, 0x000a);
+
+		/* set Status-FIFO watermark */
+		SK_OUT8(IoC, STAT_FIFO_WM, 0x10);
+		/* set Status-FIFO ISR watermark */
+		SK_OUT8(IoC, STAT_FIFO_ISR_WM, 0x04);
+																
+		SK_OUT32(IoC, STAT_ISR_TIMER_INI, 0x0190);
+	}
+
+	/* start Status-FIFO timer */
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("Start Status FiFo timer\n"));
+
+	/* enable the prefetch unit */
+	/* operational bit not functional for Yukon-EC, but fixed in Yukon-2 */
+	SK_OUT32(IoC, STAT_CTRL, SC_STAT_OP_ON);
+
+	/* start Status-FIFO timer */
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("Start Status FiFo timer\n"));
+
+	SK_OUT8(IoC, STAT_TX_TIMER_CTRL, TIM_START);
+	SK_OUT8(IoC, STAT_LEV_TIMER_CTRL, TIM_START);
+	SK_OUT8(IoC, STAT_ISR_TIMER_CTRL, TIM_START);
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("<== SkGeY2InitStatBmu()\n"));
+}	/* SkGeY2InitStatBmu */
+
+#ifdef USE_POLLING_UNIT
+/*****************************************************************************
+ *
+ * SkGeY2InitPollUnit() -	Initialize the Polling Unit
+ *
+ * Description:
+ *	This function will write the data of one polling LE table into the
+ *  adapter.
+ *
+ * Arguments:
+ *	pAC - pointer to the adapter context struct.
+ *	IoC - I/O context.
+ *	pLETab - pointer to polling LE table to be initialized
+ *
+ * Returns: N/A
+ */
+void SkGeY2InitPollUnit(
+SK_AC	*pAC,			/* pointer to adapter context */
+SK_IOC	IoC,			/* I/O context */
+SK_LE_TABLE	*pLETab)	/* pointer to polling LE table */
+{
+	SK_HWLE	*pLE;
+	int	i;
+#ifdef VCPU
+	VCPU_VARS();
+#endif /* VCPU */
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("==> SkGeY2InitPollUnit()\n"));
+
+#ifdef VCPU
+	for (i = 0; i < SK_MAX_MACS; i++) {
+		GET_PO_LE(pLE, pLETab, i);
+		VCPU_START_AND_COPY_LE();
+		/* initialize polling LE but leave indexes invalid */
+		POLE_SET_OPC(pLE, OP_PUTIDX | HW_OWNER);
+		POLE_SET_LINK(pLE, i);
+		POLE_SET_RXIDX(pLE, 0);
+		POLE_SET_TXAIDX(pLE, 0);
+		POLE_SET_TXSIDX(pLE, 0);
+		VCPU_WRITE_LE();
+		SK_DBG_DUMP_PO_LE(pLE);
+	}
+#endif	/* VCPU */
+
+	/* disable the polling unit */
+	SK_OUT32(IoC, POLL_CTRL, PC_POLL_RST_SET);
+	SK_OUT32(IoC, POLL_CTRL, PC_POLL_RST_CLR);
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("Base address Low: %08lX\n", pLETab->pPhyLETABLow));
+
+	/* Set the list base address */
+	SK_OUT32(IoC, POLL_LIST_ADDR_LO, pLETab->pPhyLETABLow);
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("Base address High: %08lX\n", pLETab->pPhyLETABHigh));
+
+	SK_OUT32(IoC, POLL_LIST_ADDR_HI, pLETab->pPhyLETABHigh);
+
+	/* we don't need to write the last index - it is hardwired to 1 */
+
+	/* enable the prefetch unit */
+	SK_OUT32(IoC, POLL_CTRL, PC_POLL_OP_ON);
+
+	/*
+	 * now we have to start the descriptor poll timer because it triggers
+	 * the polling unit
+	 */
+
+	/*
+	 * ;:;:
+	 * still playing with the value (timer runs at 125 MHz)
+	 * descriptor poll timer is enabled by GeInit
+	 */
+	SK_OUT32(IoC, B28_DPT_INI,
+		(SK_DPOLL_DEF_Y2 * (SK_U32)pAC->GIni.GIHstClkFact / 100));
+
+	SK_OUT8(IoC, B28_DPT_CTRL, TIM_START);
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+		("<== SkGeY2InitPollUnit()\n"));
+}	/* SkGeY2InitPollUnit */
+#endif	/* USE_POLLING_UNIT */
+
+
+/******************************************************************************
+ *
+ * SkGeY2SetPutIndex
+ *
+ * Description:
+ *   This function is writing the Done index of a transmit
+ *   list element table.
+ *
+ * Notes:
+ *	Dev. Issue 4.2
+ *
+ * Returns: N/A
+ */
+void SkGeY2SetPutIndex(
+SK_AC	*pAC,					/* pointer to adapter context */
+SK_IOC	IoC,					/* pointer to the IO context */
+SK_U32	StartAddrPrefetchUnit,	/* start address of the prefetch unit */
+SK_LE_TABLE	*pLETab)			/* list element table to work with */
+{
+	unsigned int Put;
+	SK_U16 EndOfListIndex;
+	SK_U16 HwGetIndex;
+	SK_U16 HwPutIndex;
+
+	/* set put index we would like to write */
+	Put = GET_PUT_IDX(pLETab);
+
+	/*
+	 * in this case we wrap around
+	 * new put is lower than last put given to hw
+	 */
+	if (Put < pLETab->HwPut) {
+
+		/* set put index = last index of list */
+		EndOfListIndex = (NUM_LE_IN_TABLE(pLETab)-1);
+
+		/* read get index of hw prefetch unit */
+		SK_IN16(IoC, (StartAddrPrefetchUnit + PREF_UNIT_GET_IDX_REG),
+			&HwGetIndex);
+
+		/* read put index of hw prefetch unit */
+		SK_IN16(IoC, (StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG),
+			&HwPutIndex);
+
+		/* prefetch unit reached end of list */
+		/* prefetch unit reached first list element */
+		if (HwGetIndex == 0) {
+			/* restore watermark */
+			SK_OUT8(IoC, StartAddrPrefetchUnit + PREF_UNIT_FIFO_WM_REG, 0xe0U);
+			/* write put index */
+			SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG,
+				(SK_U16)Put);
+
+			/* remember put index  we wrote to hw */
+			pLETab->HwPut = Put;
+		}
+		else if (HwGetIndex == EndOfListIndex) {
+			/* set watermark to one list element */
+			SK_OUT8(IoC, StartAddrPrefetchUnit + PREF_UNIT_FIFO_WM_REG, 8);
+			/* set put index to first list element */
+			SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG, 0);
+		}
+		/* prefetch unit did not reach end of list yet */
+		/* and we did not write put index to end of list yet */
+		else if ((HwPutIndex != EndOfListIndex) &&
+				 (HwGetIndex != EndOfListIndex)) {
+			/* write put index */
+			SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG,
+				EndOfListIndex);
+		}
+		else {
+			/* do nothing */
+		}
+	}
+	else {
+#ifdef XXX		/* leads in to problems in the Windows Driver */
+		if (Put != pLETab->HwPut) {
+			/* write put index */
+			SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG,
+				(SK_U16)Put);
+			/* update put index */
+			UPDATE_HWPUT_IDX(pLETab);
+		}
+#else
+		/* write put index */
+		SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG,
+			(SK_U16)Put);
+		/* update put index */
+		UPDATE_HWPUT_IDX(pLETab);
+#endif
+	}
+}	/* SkGeY2SetPutIndex */
+
diff -urN linux-2.4.29/drivers/net/skyeyene2k.c linux-2.4.29-uc1/drivers/net/skyeyene2k.c
--- linux-2.4.29/drivers/net/skyeyene2k.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/skyeyene2k.c	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,594 @@
+/*
+ * linux/deriver/net/skyeye_ne2k.c
+ * Ethernet driver for SkyEye NE2k
+ * Copyright (C) 2003 Yu Chen &Souyi Ying 
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>       // printk()
+#include <linux/slab.h>		// kmalloc()
+#include <linux/errno.h>	// error codes
+#include <linux/types.h>	// size_t
+#include <linux/interrupt.h>	// mark_bh
+
+#include <linux/in.h>
+#include <linux/netdevice.h>    // net_device
+#include <linux/etherdevice.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+
+#include <asm/irq.h>
+#include "skyeyene2k.h"
+
+//chy 2003-02-17 the read* write* define is in /arch/armnommu/mach-atmel/io.[ch]
+/*
+#define __arch_getb(a)		(*(volatile unsigned char *)(a))
+#define __arch_getl(a)		(*(volatile unsigned int  *)(a))
+#define __arch_putb(v,a)	(*(volatile unsigned char *)(a) = (v))
+#define __arch_putl(v,a)	(*(volatile unsigned int  *)(a) = (v))
+*/
+
+#define inb(a) (*(volatile unsigned char *)(a))
+#define inw(a) (*(volatile unsigned int  *)(a))
+#define inl(a) (*(volatile unsigned int  *)(a))
+#define outb(v,a) (*(volatile unsigned char *)(a) = (v))
+#define outw(v,a) (*(volatile unsigned int  *)(a) = (v))
+#define outl(v,a) (*(volatile unsigned int  *)(a) = (v))
+
+void insb(volatile unsigned char * p,volatile unsigned char *d,unsigned int l) 
+{
+   while(l--) { 
+   	*(volatile unsigned char *)d++ = inb((p)); 
+   }
+}
+
+void outsb(volatile unsigned char * p,volatile unsigned char *d,unsigned int l) 
+{
+   while(l--) { 
+         outb(*(volatile unsigned char *)d++,p);
+   }
+}
+
+
+
+#undef DEBUG
+#ifdef	DEBUG
+#define TRACE(str, args...)	printk("skyeye ne2k eth: " str, ## args)
+#else
+#define TRACE(str, args...)
+#endif
+
+void sene2k_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+static int timeout = 100;	// tx watchdog ticks 100 = 1s
+static char *version = "SkyEye NE2k Ethernet driver version 0.2 (2003-04-27) \n";
+
+/*
+ * This structure is private to each device. It is used to pass
+ * packets in and out, so there is place for a packet
+ */
+struct sene2k_priv {
+	struct net_device_stats stats;
+	
+	spinlock_t lock;
+
+	struct sk_buff *skb;
+};
+
+
+
+/*
+ * Pull the specified number of bytes from the device DMA port,
+ * and throw them away.
+ */
+static void sene2k_discard(u16 count)
+{
+  u8 tmp;
+	while(count--) {
+		tmp = inb(NE_DMA);
+	}
+}
+					
+
+/*
+ * rx 
+ */
+u8 ethpkt[1600];
+//void sene2k_rx(struct net_device *dev_id
+void sene2k_rx(void *dev_id)
+{
+//	int i;
+	
+	int len, packetLength;
+
+	//unsigned char *data;
+	struct sk_buff *skb;
+	u8 PDHeader[4];
+
+
+
+	struct net_device *dev = (struct net_device *) dev_id;
+	struct sene2k_priv *priv = (struct sene2k_priv *) dev->priv;
+	TRACE("rx\n");
+
+	spin_lock(&priv->lock);
+
+	outb(ISR_RDC, NE_ISR);
+	outb(0x0f, NE_RBCR1); 	/* See controller manual , use send packet command */
+	outb(CMD_PAGE0 | CMD_SEND | CMD_RUN, NE_CR);
+	
+	insb(NE_DMA, PDHeader, 4);
+
+	packetLength = ((unsigned) PDHeader[2] | (PDHeader[3] << 8 )); // real length of ethernet packet
+	len = packetLength + 4;  // length of 8019as frame,size of e8390_pkt_hdr is 4
+	
+	//chy 2003-05-25
+        //verify if the packet is an IP packet or ARP packet
+	if(PDHeader[3]>0x06)
+	{
+	     sene2k_discard(packetLength);
+	     priv->stats.rx_dropped++;
+	     spin_unlock(&priv->lock);
+	     return ;
+	}  
+	//---------------------------------------
+	// the status octet handler should be added in the future
+	//chy 2003-02-18
+	//memcpy(ethpkt, PDHeader + 4, 14);
+	//insb(NE_DMA, ethpkt+14, packetLength-14);  // ethpkt is the 8019as frame
+	
+	skb = dev_alloc_skb(packetLength + 2);
+	if (skb != NULL) 
+	{
+		skb->dev = dev;
+		skb_reserve(skb, 2);     /* Align IP on 16 byte */
+	        skb_put(skb,packetLength);
+		insb(NE_DMA, skb->data,packetLength);
+		//eth_copy_and_sum(skb, ethpkt, packetLength, 0);
+		
+		skb->protocol = eth_type_trans(skb,dev);
+		priv->stats.rx_packets++;
+		priv->stats.rx_bytes += packetLength;
+		netif_rx(skb);
+		
+	}else{  //chy 2003-02-18
+		//sene2k_discard(packetLength-14);
+		//chy 2003-05-25
+		sene2k_discard(packetLength);
+	        priv->stats.rx_dropped++;
+	}
+	
+	spin_unlock(&priv->lock);
+	return;
+}
+
+/*
+ * tx *** not completed, it is not necessary 
+ */
+
+//void sene2k_tx(struct net_device *dev)
+void sene2k_tx(void *dev_id)
+{
+	//struct FrameDesc *FD_ptr;
+	//unsigned long CFD_ptr;
+	//unsigned long *FB_ptr;
+	//unsigned long status;
+	struct net_device *dev = (struct net_device *) dev_id;
+	struct sene2k_priv *priv = (struct sene2k_priv *) dev->priv;
+	TRACE("tx\n");
+
+	spin_lock(&priv->lock);
+
+	
+	spin_unlock(&priv->lock);
+	return;
+}
+
+/*
+ * Open and Close
+ */
+int sene2k_open(struct net_device *dev)
+{
+	int i;
+	unsigned char tmpb;
+	//unsigned long status;
+	MOD_INC_USE_COUNT;
+
+	TRACE("open\n");
+
+	// Disable net irq
+	disable_irq(AT91_NET_IRQNUM);
+	
+
+	// register net isr
+	if(request_irq(AT91_NET_IRQNUM, &sene2k_interrupt, SA_INTERRUPT, "sene2k isr", dev)) {
+		printk(KERN_ERR "sene2k: Can't get irq %d\n", AT91_NET_IRQNUM);
+		return -EAGAIN;
+	}
+
+	//setup the hardware
+	
+	outb(0x22,NE_CR);
+	/*
+	 * Initialize physical device
+	 */
+	//write and read 0x1f to reset the nic
+	outb(0, NE_RESET);
+	tmpb=inb(NE_RESET);            
+	for(i=0; i < 20; i++);		//delay at least 10ms
+
+
+	//in PAGE0
+	outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
+	/* FIFO threshold = 8 bytes, normal operation, 8-bit byte write DMA, BOS=0 */
+	outb(DCR_LS | DCR_FIFO8, NE_DCR);
+	
+	outb(0, NE_RBCR0);
+	outb(0, NE_RBCR1);
+
+/*
+ * Allow broadcast packets, in addition to packets unicast to us.
+ * Multicast packets that match MAR filter bits will also be
+ * allowed in.
+ */
+	outb(RCR_AB, NE_RCR);
+
+	//Place the SNIC in LOOPBACK mode 1 or 2 (Transmit Configuration Register e 02H or 04H)
+	outb(TCR_LOOP_INT, NE_TCR);
+
+	outb(XMIT_START >> 8, NE_TPSR);
+	outb(RECV_START >> 8, NE_PSTART);
+	outb(RECV_START >> 8, NE_BNRY);
+	outb(RECV_STOP >> 8, NE_PSTOP);
+	//in PAGE1
+	outb(CMD_PAGE1 | CMD_NODMA | CMD_STOP, NE_CR);
+	outb(RECV_START >> 8, NE_CURR);
+
+      
+/*
+ * Set physical address here.(not use 93c46)
+ */
+        /*
+	outb(dev->dev_addr[0], NE_PAR0);
+	outb(dev->dev_addr[1], NE_PAR1);
+	outb(dev->dev_addr[2], NE_PAR2);
+	outb(dev->dev_addr[3], NE_PAR3);
+	outb(dev->dev_addr[4], NE_PAR4);
+	outb(dev->dev_addr[5], NE_PAR5);
+        */
+	
+	//chy 2003-04-27: get physical address from skyeye
+	outb(CMD_PAGE1 | CMD_NODMA | CMD_STOP, NE_CR);
+	dev->dev_addr[0]=inb(NE_PAR0);
+	dev->dev_addr[1]=inb(NE_PAR1);
+	dev->dev_addr[2]=inb(NE_PAR2);
+	dev->dev_addr[3]=inb(NE_PAR3);
+	dev->dev_addr[4]=inb(NE_PAR4);
+	dev->dev_addr[5]=inb(NE_PAR5);
+        /* for test
+        printk("sene2k open: ");
+	for(i = 0; i < 6; i++)
+		printk("%2.2x%c", dev->dev_addr[i], (i==5) ? ' ' : ':');
+	printk("\n");
+	*/
+	
+	//chy 2003-02-18: 
+        //select PAGE0 and start the nic
+		outb(CMD_PAGE0 | CMD_NODMA | CMD_RUN, NE_CR);
+	//set Interrupt mask reg
+	outb(ISR_OVW | ISR_TXE | ISR_PTX | ISR_PRX, NE_IMR);
+	
+	outb(TCR_LOOP_NONE, NE_TCR);
+	
+    // Enable net irq
+	enable_irq(AT91_NET_IRQNUM);
+	// Start the transmit queue
+	netif_start_queue(dev);
+	
+	return 0;
+}
+
+int sene2k_stop(struct net_device *dev)
+{
+	TRACE("stop\n");
+	
+	free_irq(AT91_NET_IRQNUM, dev);
+	
+	netif_stop_queue(dev);
+	MOD_DEC_USE_COUNT;
+	
+	return 0;
+}
+
+
+// skyeye net interrupt handler
+
+void sene2k_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct sene2k_priv *priv = (struct sene2k_priv *) dev->priv;
+	u8 isr, curr, bnry;
+
+	if (dev == NULL) {
+		printk ("sene2k_interrupt(): irq %d for unknown device.\n", irq);
+		return;
+	}
+	
+	//chy 2003-02-16
+	/*
+	if (dev->interrupt)
+		printk("%s: Re-entering the interrupt handler.\n", dev->name);
+	dev->interrupt = 1;
+	*/
+
+	//close nic
+	outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP,NE_CR);
+	
+	//in PAGE0
+	isr = inb(NE_ISR);
+
+	// ram overflow interrupt
+	if (isr & ISR_OVW) {
+		outb(ISR_OVW,NE_ISR);		// clear interrupt
+	//	ne2k_overflowProcess();              //yangye :no overflow now 
+	// chy 2003-05-27: // set BNRY=CURR
+		outb(CMD_PAGE1 | CMD_NODMA | CMD_STOP,NE_CR);
+		curr = inb(NE_CURR);
+		outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP,NE_CR);
+		outb(curr, NE_BNRY);
+		priv->stats.rx_over_errors++;
+		priv->stats.rx_errors++;
+		//printk(KERN_ERR "sene2k overflow !\n");
+	}
+	
+	// error transfer interrupt ,NIC abort tx due to excessive collisions	
+	if (isr & ISR_TXE) {
+		outb(ISR_TXE,NE_ISR);		// clear interrupt
+		priv->stats.tx_errors++;
+	 	//temporarily do nothing
+	}
+
+	// Rx error , reset BNRY pointer to CURR (use SEND PACKET mode)
+	if (isr & ISR_RXE) {
+		outb(ISR_RXE,NE_ISR);		// clear interrupt
+		
+		outb(CMD_PAGE1 | CMD_NODMA | CMD_STOP,NE_CR);
+		curr = inb(NE_CURR);
+		outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP,NE_CR);
+		outb(curr, NE_BNRY);
+		priv->stats.rx_errors++;
+	}	
+
+	//got packet with no errors
+	if (isr & ISR_PRX) {
+		outb(ISR_PRX, NE_ISR);		// clear interrupt
+
+		outb(CMD_PAGE1 | CMD_NODMA | CMD_STOP, NE_CR);
+		curr  =  inb(NE_CURR);
+		outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
+		bnry = inb(NE_BNRY);
+		//yangye 2003-1-21
+		//get more than one packet until receive buffer is empty
+		while(curr != bnry){
+			sene2k_rx(dev);
+			outb(CMD_PAGE1 | CMD_NODMA | CMD_STOP, NE_CR);
+			curr =  inb(NE_CURR);
+			outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
+			bnry = 	inb(NE_BNRY);			
+			}
+	}
+		
+	//Transfer complelte, do nothing here
+	if( isr & ISR_PTX){
+		//printk("ne2k_isr: is ISR_PTX\n");
+		outb(ISR_PTX, NE_ISR);          // clear interrupt
+	}
+		
+	outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
+	outb(0xff, NE_ISR);			// clear ISR	
+	
+	//open nic for next packet
+	outb(CMD_PAGE0 | CMD_NODMA | CMD_RUN, NE_CR);
+
+	//chy 2003-2-17
+	//dev->interrupt = 0;
+	return;
+}
+
+
+// hard_start_xmit 
+
+int sene2k_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	int i;
+	int len;
+	char *data;
+	struct sene2k_priv *priv = (struct sene2k_priv *) dev->priv;
+	u8 isr;
+
+	TRACE("start_xmit\n");
+	//chy 2003-02-21: debug the net data
+	/*
+	printk("sk_buff->len: %d\n", skb->len);
+	printk("sk_buff->data_len: %d\n", skb->data_len);
+	for(i = 0; i < skb->len; i++) {
+		printk("%4x", skb->data[i]);
+		if((i+1)%16 ==0)
+			printk("\n");
+	}
+	printk("\n");
+	*/
+	
+	len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+	data = skb->data;
+	dev->trans_start = jiffies;
+	
+	
+	//don't close nic,just close receive interrupt	
+	outb(CMD_PAGE2 | CMD_NODMA | CMD_RUN, NE_CR);
+	isr = inb(NE_IMR);
+	isr &= ~ISR_PRX;
+      	outb(CMD_PAGE0 | CMD_NODMA | CMD_RUN, NE_CR);
+	outb(isr, NE_IMR);
+	
+	outb(ISR_RDC, NE_ISR);	
+	
+	// Amount to send
+	outb(len & 0xff, NE_RBCR0);
+	outb(len >> 8, NE_RBCR1);
+
+    // Address on NIC to store
+	outb(XMIT_START & 0xff, NE_RSAR0);
+	outb(XMIT_START >> 8, NE_RSAR1);
+	// Write command to start
+	outb(CMD_PAGE0 | CMD_WRITE | CMD_RUN, NE_CR);    
+
+	//write data to remote dma
+	outsb(NE_DMA, skb->data, len);
+
+	//  Wait for remote dma to complete - ISR Bit 6 clear if busy
+	while((u8)(inb(NE_ISR) & ISR_RDC) == 0 );
+	
+	outb(ISR_RDC, NE_ISR);     //clear RDC
+
+	/*
+	 * Issue the transmit command.(start local dma)
+	 */
+ 	outb(XMIT_START >> 8, NE_TPSR);
+	outb(len & 0xff, NE_TBCR0);
+	outb(len >> 8, NE_TBCR1);	
+	//  Start transmission (and shut off remote dma)
+	//  and reopen nic(CMD_RUN)
+	outb(CMD_PAGE0 | CMD_NODMA | CMD_XMIT | CMD_RUN, NE_CR);
+		
+	
+	//reopen receive interrupt
+	outb(CMD_PAGE2 | CMD_NODMA | CMD_RUN, NE_CR);
+	isr = inb(NE_IMR);
+	isr |= ISR_PRX;
+        outb(CMD_PAGE0 | CMD_NODMA | CMD_RUN, NE_CR);
+	outb(isr, NE_IMR);
+
+
+	dev_kfree_skb(skb);
+
+	//chy: stats tx info
+	priv->stats.tx_packets++;
+	priv->stats.tx_bytes+=len;
+	
+	return 0;
+}
+
+struct net_device_stats *sene2k_get_stats(struct net_device *dev)
+{
+	struct sene2k_priv *priv = (struct sene2k_priv *) dev->priv;
+	TRACE("get_stats\n");
+	return &priv->stats;
+}
+
+/*
+ * The init function, invoked by register_netdev()
+ */
+int sene2k_init(struct net_device *dev)
+{
+	int i;
+	//unsigned char tmpb;
+	TRACE("init\n");
+	//ether_setup in linux-2.4.x/driver/net
+	ether_setup(dev);	// Assign some of the fields
+
+	// set net_device methods
+	dev->open = sene2k_open;
+	dev->stop = sene2k_stop;
+//	dev->ioctl = sene2k_ioctl;
+	dev->get_stats = sene2k_get_stats;
+//	dev->tx_timeout = sene2k_tx_timeout;
+	dev->hard_start_xmit = sene2k_start_xmit;
+	// set net_device data members
+	dev->watchdog_timeo = timeout;
+	dev->irq =AT91_NET_IRQNUM ;  //the ext int number is 16
+	dev->dma = 0;
+	dev->base_addr=AT91_NET_BASE; //the net registers base addr (0xfffa0000)
+
+	//2003-02-25: walimi find a bug, if addr[0]&1==1 then, this addr is a multicast addr,
+	//so the mac addr[0]&1 should be 0. 
+	//when tcp_v4_rcv function do command: if (skb->pkt_type!=PACKET_HOST), 
+	//if  addr[0]&1==1 then it will discard this packet
+
+	// set MAC address manually
+	//chy 2003-04-27: the mac addr is got from skyeye, which get from skyeye.conf
+	
+	/*
+	dev->dev_addr[0] = 0x0;
+	dev->dev_addr[1] = 0x1;
+	dev->dev_addr[2] = 0x2;
+	dev->dev_addr[3] = 0x3;
+	dev->dev_addr[4] = 0x4;
+	dev->dev_addr[5] = 0x5;
+        */
+
+        
+	
+	printk(KERN_INFO "sene2k dev name: %s: ", dev->name);
+	
+	/*
+	for(i = 0; i < 6; i++)
+		printk("%2.2x%c", dev->dev_addr[i], (i==5) ? ' ' : ':');
+	printk("\n");
+        */
+	
+	SET_MODULE_OWNER(dev);
+
+	dev->priv = kmalloc(sizeof(struct sene2k_priv), GFP_KERNEL);
+	if(dev->priv == NULL){
+	    printk(KERN_ERR "sene2k: nomem for sene2k_priv struct\n"); 	
+     	return -ENOMEM;
+	}
+	memset(dev->priv, 0, sizeof(struct sene2k_priv));
+	spin_lock_init(&((struct sene2k_priv *) dev->priv)->lock);
+	
+
+	
+	return 0;
+}
+
+struct net_device sene2k_netdevs = {
+	init: sene2k_init,
+};
+
+/*
+ * Finally, the module stuff
+ */
+int sene2k_init_module(void)
+{
+	int result;
+	TRACE("init_module\n");
+
+	//Print version information
+	printk(KERN_INFO "%s", version);
+
+	//register_netdev will call sene2k_init()
+	if((result = register_netdev(&sene2k_netdevs)))
+		printk("sene2k eth: Error %i registering device \"%s\"\n", result, sene2k_netdevs.name);
+	return result ? 0 : -ENODEV;
+}
+
+void sene2k_cleanup(void)
+{
+	TRACE("cleanup\n");
+	kfree(sene2k_netdevs.priv);
+	unregister_netdev(&sene2k_netdevs);
+	return;
+}
+
+module_init(sene2k_init_module);
+module_exit(sene2k_cleanup);
+
+MODULE_DESCRIPTION("SkyEye NE2k ethernet driver");
+MODULE_AUTHOR("Yu Chen & Souyi Ying");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/drivers/net/skyeyene2k.h linux-2.4.29-uc1/drivers/net/skyeyene2k.h
--- linux-2.4.29/drivers/net/skyeyene2k.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/skyeyene2k.h	2005-06-14 02:12:13.000000000 +0100
@@ -0,0 +1,142 @@
+#ifndef SKYEYE_NE2K_H
+#define SKYEYE_NE2K_H
+
+struct ethframe {
+	unsigned char dst[ETH_ALEN];
+	unsigned char src[ETH_ALEN];
+	unsigned short proto;
+	unsigned char data[ETH_DATA_LEN+22];
+};
+
+//#ifndef SKYEYE_NE2K_H
+//#define SKYEYE_NE2K_H
+
+#define AT91_NET_BASE    (0xfffa0000)
+#define NE_BASE           AT91_NET_BASE   
+#define AT91_NET_SIZE	 255
+#define AT91_NET_IRQNUM	 16
+
+
+
+//yangye 2003-1-20
+//all addr[1,0] must be 00
+#define NE_CR              (NE_BASE+0)             //R/W£¬¶Ô²»Í¬µÄÒ³£¬CR¶¼ÊÇÍ¬Ò»¸ö
+#define	NE_DMA		   (NE_BASE+64)	     //0x10-0x10 ÊÇDMA¶Ë¿Ú,ÖØ¸´£¬Ö»ÓÃ0x10.
+#define	NE_RESET	   (NE_BASE+124)	     //0x18£­0x1f ÊÇÍø¿¨¸´Î»¶Ë¿Ú£¬ÖØ¸´£¬Ö»ÓÃ0x1f£¬¶ÁÐ´Ëü½«¸´Î»Íø¿¨
+
+//page0 registers
+#define NE_PSTART          (NE_BASE+4)            //W£¬½ÓÊÕ»º³å»·ÆðÊ¼Ò³
+#define NE_PSTOP           (NE_BASE+8)            //W£¬½ÓÊÕ»º³å»·ÖÕÖ¹Ò³£¨²»°üÀ¨´ËÒ³£©
+#define NE_BNRY            (NE_BASE+12)            //R/W£¬½ÓÊÕ»º³å»·¶ÁÖ¸Õë£¬Ö¸ÏòÏÂÒ»¸ö°üµ½À´Ê±µÄÆðÊ¼Ò³,Ó¦³õÊ¼»¯³É£½CURR£½PSTART
+#define NE_TPSR            (NE_BASE+16)            //W£¬Local DMA·¢ËÍ»º³åÆðÊ¼Ò³¼Ä´æÆ÷
+#define NE_TBCR0           (NE_BASE+20)            //W£¬Local DMA·¢ËÍ³¤¶ÈµÍÎ»
+#define NE_TBCR1           (NE_BASE+24)            //W£¬Local DMA·¢ËÍ³¤¶È¸ßÎ»
+#define NE_ISR             (NE_BASE+28)            //R/W£¬ÖÐ¶Ï×´Ì¬¼Ä´æÆ÷
+#define NE_RSAR0           (NE_BASE+32)            //W£¬Remote DMAÄ¿µÄÆðÊ¼µØÖ·µÍÎ»
+#define NE_RSAR1           (NE_BASE+36)            //W£¬Remote DMAÄ¿µÄÆðÊ¼µØÖ·¸ßÎ»
+//ÕâÁ½¸öÊÇCPUÏòÍø¿¨Ð´Èë»ò¶Á³öÊý¾Ý°üµÄÊµ¼Ê³¤¶È£¬Ö´ÐÐRemote DMAÃüÁîÇ°ÉèÖÃ
+#define NE_RBCR0           (NE_BASE+40)            //W£¬Remote DMAÊý¾Ý³¤¶ÈµÍÎ»
+#define NE_RBCR1           (NE_BASE+44)            //W£¬Remote DMAÊý¾Ý³¤¶È¸ßÎ»
+#define NE_RCR             (NE_BASE+48)            //W£¬½ÓÊÕÅäÖÃ¼Ä´æÆ÷,³õÊ¼»¯Ê±Ð´Èë0x04,±íÊ¾Ö»½ÓÊÕ·¢¸ø±¾Íø¿¨MACµØÖ·µÄ,´óÓÚ64×Ö½ÚµÄÒÔÌ«Íø°ü»ò¹ã²¥°ü
+#define NE_TCR             (NE_BASE+52)            //·¢ËÍÅäÖÃ¼Ä´æÆ÷,³õÊ¼»¯¿ªÊ¼Ê±Ð´Èë0x02£¬ÖÃÍø¿¨ÎªLoop BackÄ£Ê½£¬Í£Ö¹·¢ËÍÊý¾Ý°ü,³õÊ¼»¯½áÊøÐ´Èë0x00¡£Õý³£·¢ËÍÊý¾Ý°ü²¢¼ÓÉÏCRC
+#define NE_DCR             (NE_BASE+56)            //W£¬Êý¾ÝÅäÖÃ¼Ä´æÆ÷,³õÊ¼»¯Ê±Ð´Èë0x48£¬8Î»Ä£Ê½£¬FIFOÉî¶È8×Ö½Ú£¬DMA·½Ê½
+#define NE_IMR             (NE_BASE+60)            //W£¬ÖÐ¶ÏÆÁ±Î¼Ä´æÆ÷ËüµÄ¸÷Î»ºÍISRÖÐµÄ¸÷Î»Ïà¶ÔÓ¦£¬ÏòIMRÐ´ÈëÖµ¼´Îª´ò¿ªÏàÓ¦ÖÐ¶Ï
+//page1 registers
+#define NE_PAR0            (NE_BASE+4)            //R/W£¬Íø¿¨MACµØÖ·×î¸ßÎ»
+#define NE_PAR1            (NE_BASE+8)            //R/W£¬Íø¿¨MACµØÖ·
+#define NE_PAR2            (NE_BASE+12)            //R/W£¬Íø¿¨MACµØÖ·
+#define NE_PAR3            (NE_BASE+16)            //R/W£¬Íø¿¨MACµØÖ·
+#define NE_PAR4            (NE_BASE+20)            //R/W£¬Íø¿¨MACµØÖ·
+#define NE_PAR5            (NE_BASE+24)            //R/W£¬Íø¿¨MACµØÖ·×îµÍÎ»
+#define NE_CURR            (NE_BASE+28)            //R/W£¬½ÓÊÕ»º³å»·Ð´Ö¸Õë
+#define NE_MAR0            (NE_BASE+32)            //R/W£¬×é²¥¼Ä´æÆ÷ 
+#define NE_MAR1            (NE_BASE+36)            //R/W£¬×é²¥¼Ä´æÆ÷ 
+#define NE_MAR2            (NE_BASE+40)            //R/W£¬×é²¥¼Ä´æÆ÷ 
+#define NE_MAR3            (NE_BASE+44)            //R/W£¬×é²¥¼Ä´æÆ÷ 
+#define NE_MAR4            (NE_BASE+48)            //R/W£¬×é²¥¼Ä´æÆ÷ 
+#define NE_MAR5            (NE_BASE+52)            //R/W£¬×é²¥¼Ä´æÆ÷ 
+#define NE_MAR6            (NE_BASE+56)            //R/W£¬×é²¥¼Ä´æÆ÷ 
+#define NE_MAR7            (NE_BASE+60)            //R/W£¬×é²¥¼Ä´æÆ÷ 
+ 
+//page2 registers (read only in 8019as)
+//#define NE_PSTART          0x01            //R£¬½ÓÊÕ»º³å»·ÆðÊ¼Ò³
+//#define NE_PSTOP           0x02            //R£¬½ÓÊÕ»º³å»·ÖÕÖ¹Ò³£¨²»°üÀ¨´ËÒ³£©
+//#define NE_TPSR            0x04            //R£¬Local DMA·¢ËÍ»º³åÆðÊ¼Ò³¼Ä´æÆ÷
+//#define NE_RCR             0x0c            //R£¬½ÓÊÕÅäÖÃ¼Ä´æÆ÷
+//#define NE_TCR             0x0d            //R,·¢ËÍÅäÖÃ¼Ä´æÆ÷
+//#define NE_DCR             0x0e            //R£¬Êý¾ÝÅäÖÃ¼Ä´æÆ÷
+//#define NE_IMR             0x0f            //R£¬ÓÃÀ´¶ÁÖÐ¶ÏÆÁ±Î¼Ä´æÆ÷IMR×´Ì¬
+
+
+//CRÃüÁî¼Ä´æÆ÷µÄÃüÁî 
+#define	CMD_STOP	0x01       //Íø¿¨Í£Ö¹ÊÕ·¢Êý¾Ý
+#define	CMD_RUN	    	0x02       //Íø¿¨Ö´ÐÐÃüÁî²¢¿ªÊ¼ÊÕ·¢Êý¾Ý°ü£¨ÃüÁîÎªÏÂÃæËÄÖÖ£©
+#define	CMD_XMIT	0x04       //Local DMA SEND£¨Íø¿¨¨D¨D>ÒÔÌ«Íø £©
+#define	CMD_READ	0x08       //Remote DMA READ£¬ÓÃÓÚÊÖ¶¯½ÓÊÕÊý¾Ý£¨Íø¿¨¨D¨D>CPU£©
+#define	CMD_WRITE	0x10       //Remote DMA WRITE £¨Íø¿¨<¨D¨DCPU£©
+#define	CMD_SEND	0x18       //SEND COMMANDÃüÁî£¬ÓÃÓÚ×Ô¶¯½ÓÊÕÊý¾Ý°ü                                      £¨Íø¿¨¨D¨D>CPU£©
+#define	CMD_NODMA	0x20       //Í£Ö¹DMA²Ù×÷
+#define	CMD_PAGE0	0x00       //   Ñ¡ÔñµÚ0Ò³£¨ÒªÏÈÑ¡Ò³£¬ÔÙ¶ÁÐ´¸ÃÒ³¼Ä´æÆ÷£©
+#define	CMD_PAGE1	0x40       //   Ñ¡ÔñµÚ1Ò³
+#define	CMD_PAGE2	0x80       //   Ñ¡ÔñµÚ2Ò³
+
+//Ð´ÈëTPSRµÄÖµ 
+#define	XMIT_START	 0x4000       //·¢ËÍ»º³åÆðÊ¼µØÖ·£¨Ð´ÈëÊ±ÒªÓÒÒÆ8Î»µÃµ½Ò³ºÅ£©
+//Ð´ÈëPSTARTµÄÖµ 
+#define	RECV_START	 0x4600       //½ÓÊÕ»º³åÆðÊ¼µØÖ·£¨Ð´ÈëÊ±ÒªÓÒÒÆ8Î»µÃµ½Ò³ºÅ£©
+//Ð´ÈëPSTOPµÄÖµ 
+#define	RECV_STOP	 0x6000       //½ÓÊÕ»º³å½áÊøµØÖ·£¨Ð´ÈëÊ±ÒªÓÒÒÆ8Î»µÃµ½Ò³ºÅ£©
+
+//ÖÐ¶Ï×´Ì¬¼Ä´æÆ÷µÄÖµ 
+#define	ISR_PRX	    	0x01       //ÕýÈ·½ÓÊÕÊý¾Ý°üÖÐ¶Ï¡£×ö½ÓÊÕ´¦Àí
+#define	ISR_PTX		0x02       //ÕýÈ··¢ËÍÊý¾Ý°üÖÐ¶Ï¡£×ö²»×ö´¦ÀíÒª¿´ÉÏ²ãÈí¼þÁË¡£
+#define	ISR_RXE	    	0x04       //½ÓÊÕÊý¾Ý°ü³ö´í¡£×öÖØÐÂÉèÖÃBNRY£½CURR´¦Àí¡£ 
+#define	ISR_TXE	    	0x08       //ÓÉÓÚ³åÍ»´ÎÊý¹ý¶à£¬·¢ËÍ³ö´í¡£×öÖØ·¢´¦Àí
+#define	ISR_OVW	    	0x10       //Íø¿¨ÄÚ´æÒç³ö¡£×öÈí¼þÖØÆôÍø¿¨´¦Àí¡£¼ûÊÖ²á¡£
+#define	ISR_CNT	    	0x20       //³ö´í¼ÆÊýÆ÷ÖÐ¶Ï£¬ÆÁ±Îµô£¨ÆÁ±ÎÓÃIMR¼Ä´æÆ÷£©¡£
+#define	ISR_RDC	    	0x40       //Remote DMA½áÊø ¡£ÆÁ±Îµô¡£ÂÖÑ¯µÈ´ýDMA½áÊø¡£
+#define	ISR_RST		0x80       //Íø¿¨Reset£¬ÆÁ±Îµô¡£
+
+//ÖÐ¶ÏÆÁ±Î¼Ä´æÆ÷µÄÖµ 
+#define	ISR_PRX	    	0x01
+#define	ISR_PTX		0x02
+#define	ISR_RXE	    	0x04
+#define	ISR_TXE	    	0x08
+#define	ISR_OVW	    	0x10
+#define	ISR_CNT 	0x20
+#define	ISR_RDC	    	0x40
+#define	ISR_RST		0x80
+
+//Êý¾Ý¿ØÖÆ¼Ä´æÆ÷
+//³õÊ¼»¯Ê±Ð´Èë0x48£¬8Î»Ä£Ê½£¬FIFOÉî¶È8×Ö½Ú£¬DMA·½Ê½¡£
+#define	DCR_WTS		0x01
+#define	DCR_BOS		0x02
+#define	DCR_LAS		0x04
+#define	DCR_LS		0x08
+#define	DCR_ARM		0x10
+#define	DCR_FIFO2	0x00
+#define	DCR_FIFO4	0x20
+#define	DCR_FIFO8	0x40
+#define	DCR_FIFO12	0x60
+
+//TCR·¢ËÍÅäÖÃ¼Ä´æÆ÷
+//³õÊ¼»¯¿ªÊ¼Ê±Ð´Èë0x02£¬ÖÃÍø¿¨ÎªLoop BackÄ£Ê½£¬Í£Ö¹·¢ËÍÊý¾Ý°ü£¬
+//³õÊ¼»¯½áÊøÐ´Èë0x00¡£Õý³£·¢ËÍÊý¾Ý°ü²¢¼ÓÉÏCRC¡£
+#define	TCR_CRC		0x01
+#define	TCR_LOOP_NONE	0x00
+#define	TCR_LOOP_INT	0x02
+#define	TCR_LOOP_EXT	0x06
+#define	TCR_ATD		0x08
+#define	TCR_OFST	0x10
+
+//RCR½ÓÊÕÅäÖÃ¼Ä´æÆ÷
+//³õÊ¼»¯Ê±Ð´Èë0x04¡£Ö»½ÓÊÕ·¢¸ø±¾Íø¿¨MACµØÖ·´óÓÚ64×Ö½ÚµÄÒÔÌ«Íø°ü»ò¹ã²¥°ü
+#define	RCR_SEP		0x01
+#define	RCR_AR		0x02
+#define	RCR_AB		0x04
+#define	RCR_AM		0x08
+#define	RCR_PRO		0x10
+#define	RCR_MON		0x20
+
+
+#endif /* SKYEYE_NE2K_H */
diff -urN linux-2.4.29/drivers/net/smc91111.c linux-2.4.29-uc1/drivers/net/smc91111.c
--- linux-2.4.29/drivers/net/smc91111.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/smc91111.c	2005-06-14 02:12:09.000000000 +0100
@@ -0,0 +1,4032 @@
+//#define SMC_DEBUG 2 // Must be defined in makefile
+/*------------------------------------------------------------------------
+ . smc91111.c
+ . This is a driver for SMSC's 91C111 single-chip Ethernet device.
+ .
+ . Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
+ .       Developed by Simple Network Magic Corporation (SNMC)
+ . Copyright (C) 1996 by Erik Stahlman (ES)
+ .
+ . This program is free software; you can redistribute it and/or modify
+ . it under the terms of the GNU General Public License as published by
+ . the Free Software Foundation; either version 2 of the License, or
+ . (at your option) any later version.
+ .
+ . 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
+ .
+ . Information contained in this file was obtained from the LAN91C111
+ . manual from SMC.  To get a copy, if you really want one, you can find 
+ . information under www.smsc.com.
+ . 
+ .
+ . "Features" of the SMC chip:
+ .   Integrated PHY/MAC for 10/100BaseT Operation
+ .   Supports internal and external MII
+ .   Integrated 8K packet memory
+ .   EEPROM interface for configuration
+ .
+ . Arguments:
+ . 	io	= for the base address
+ .	irq	= for the IRQ
+ .	nowait	= 0 for normal wait states, 1 eliminates additional wait states
+ .
+ . author:
+ . 	Erik Stahlman				( erik@vt.edu )
+ . 	Daris A Nevil				( dnevil@snmc.com )
+ .  	Pramod B Bhardwaj   			(pramod.bhardwaj@smsc.com)
+ .
+ .
+ . Hardware multicast code from Peter Cammaert ( pc@denkart.be )
+ .
+ . Sources:
+ .    o   SMSC LAN91C111 databook (www.smsc.com)
+ .    o   smc9194.c by Erik Stahlman
+ .    o   skeleton.c by Donald Becker ( becker@cesdis.gsfc.nasa.gov )
+ .
+ . History:
+ .	01/15/03  Greg Ungerer, add support for GILBARCONAP board
+ .	06/03/02  Greg Ungerer, added support for M5249C3 board
+ .	09/24/01  Pramod B Bhardwaj, Added the changes for Kernel 2.4
+ .	08/21/01  Pramod B Bhardwaj Added support for RevB of LAN91C111
+ .	04/25/01  Daris A Nevil  Initial public release through SMSC
+ .	03/16/01  Daris A Nevil  Modified smc9194.c for use with LAN91C111
+ ----------------------------------------------------------------------------*/
+
+// Use power-down feature of the chip
+#define POWER_DOWN	1
+
+
+static const char version[] =
+	"SMSC LAN91C111 Driver (v2.0), (Linux Kernel 2.4 + Support for Odd Byte) 09/24/01 -      by Pramod Bhardwaj (pramod.bhardwaj@smsc.com)\n";
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <asm/bitops.h>
+
+#if defined(CONFIG_M5249C3) || defined(CONFIG_GILBARCONAP)
+#define CONFIG_SMC16BITONLY     1
+#include <asm/mcfsmc.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#elif defined(CONFIG_SUZAKU)
+#define CONFIG_SMC16BITONLY     1
+#include <asm/suzaku_smc.h>
+#else
+#include <asm/io.h>
+#endif
+
+#include <linux/errno.h>
+#include <linux/delay.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+//#include <linux/kcomp.h>
+
+#ifdef CONFIG_SYSCTL
+#include <linux/proc_fs.h>
+#include <linux/sysctl.h>
+#endif
+
+#include "smc91111.h"
+/*------------------------------------------------------------------------
+ .
+ . Configuration options, for the experienced user to change.
+ .
+ -------------------------------------------------------------------------*/
+
+/*
+ . Do you want to use 32 bit xfers?  This should work on all chips, as
+ . the chipset is designed to accommodate them. ... but not on the RTE_ME2_CB
+*/
+
+#if !defined(CONFIG_RTE_CB_ME2) && !defined(CONFIG_SUZAKU)
+# define USE_32_BIT 1
+#endif 
+
+
+/*
+ .the LAN91C111 can be at any of the following port addresses.  To change,
+ .for a slightly different card, you can add it to the array.  Keep in
+ .mind that the array must end in zero.
+*/
+#if defined(CONFIG_M5249C3)
+static unsigned int smc_portlist[] = { 0xe0000300, 0 };
+static unsigned int smc_irqlist[]  = { 166, 0 };
+#elif defined(CONFIG_GILBARCONAP)
+static unsigned int smc_portlist[] = { 0x30600300, 0 };
+static unsigned int smc_irqlist[]  = { 68, 0 };
+unsigned char smc_defethaddr[] = { 0x00, 0xd0, 0xcf, 0x00, 0x01, 0x21 };
+#elif defined(CONFIG_SUZAKU)
+static unsigned int smc_portlist[] = { 0xffe00300, 0 };
+static unsigned int smc_irqlist[]  = { 2, 0 };
+#else
+static unsigned int smc_portlist[] __initdata =
+   { 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
+	 0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, 0};
+#endif
+
+
+/*
+ . Wait time for memory to be free.  This probably shouldn't be
+ . tuned that much, as waiting for this means nothing else happens
+ . in the system
+*/
+#define MEMORY_WAIT_TIME 16
+
+/*
+ . DEBUGGING LEVELS
+ .
+ . 0 for normal operation
+ . 1 for slightly more details
+ . >2 for various levels of increasingly useless information
+ .    2 for interrupt tracking, status flags
+ .    3 for packet info
+ .    4 for complete packet dumps
+*/
+//#define SMC_DEBUG 3 // Must be defined in makefile
+
+#if (SMC_DEBUG > 2 )
+#define PRINTK3(args...) printk(args)
+#else
+#define PRINTK3(args...)
+#endif
+
+#if SMC_DEBUG > 1
+#define PRINTK2(args...) printk(args)
+#else
+#define PRINTK2(args...)
+#endif
+
+#ifdef SMC_DEBUG
+#define PRINTK(args...) printk(args)
+#else
+#define PRINTK(args...)
+#endif
+
+
+/*------------------------------------------------------------------------
+ .
+ . The internal workings of the driver.  If you are changing anything
+ . here with the SMC stuff, you should have the datasheet and know
+ . what you are doing.
+ .
+ -------------------------------------------------------------------------*/
+#define CARDNAME "LAN91C111"
+
+// Memory sizing constant
+#define LAN91C111_MEMORY_MULTIPLIER	(1024*2)
+
+/* store this information for the driver.. */
+struct smc_local {
+
+ 	// these are things that the kernel wants me to keep, so users
+	// can find out semi-useless statistics of how well the card is
+	// performing
+	struct net_device_stats stats;
+
+	// If I have to wait until memory is available to send
+	// a packet, I will store the skbuff here, until I get the
+	// desired memory.  Then, I'll send it out and free it.
+	struct sk_buff * saved_skb;
+
+ 	// This keeps track of how many packets that I have
+ 	// sent out.  When an TX_EMPTY interrupt comes, I know
+	// that all of these have been sent.
+	int	packets_waiting;
+
+	// Set to true during the auto-negotiation sequence
+	int	autoneg_active;
+
+	// Address of our PHY port
+	word	phyaddr;
+
+	// Type of PHY
+	word	phytype;
+
+	// Last contents of PHY Register 18
+	word	lastPhy18;
+
+	// Contains the current active transmission mode
+	word	tcr_cur_mode;
+
+	// Contains the current active receive mode
+	word	rcr_cur_mode;
+
+	// Contains the current active receive/phy mode
+	word	rpc_cur_mode;
+
+	/* => Pramod, Odd Byte issue */
+	// Contains the Current ChipID
+	unsigned short ChipID;
+
+	//Contains the Current ChipRevision
+	unsigned short ChipRev;
+	/* <= Pramod, Odd Byte issue */
+
+
+#ifdef CONFIG_SYSCTL
+
+	// Root directory /proc/sys/dev
+	// Second entry must be null to terminate the table
+	ctl_table root_table[2];
+
+	// Directory for this device /proc/sys/dev/ethX
+	// Again the second entry must be zero to terminate
+	ctl_table eth_table[2];
+
+	// This is the parameters (file) table
+	ctl_table param_table[CTL_SMC_LAST_ENTRY];
+
+	// Saves the sysctl header returned by register_sysctl_table()
+	// we send this to unregister_sysctl_table()
+	struct ctl_table_header *sysctl_header;
+
+	// Parameter variables (files) go here
+	char ctl_info[1024];
+	int ctl_swfdup;
+	int ctl_ephloop;
+	int ctl_miiop;
+	int ctl_autoneg;
+	int ctl_rfduplx;
+	int ctl_rspeed;
+	int ctl_afduplx;
+	int ctl_aspeed;
+	int ctl_lnkfail;
+	int ctl_forcol;
+	int ctl_filtcar;
+	int ctl_freemem;
+	int ctl_totmem;
+	int ctl_leda;
+	int ctl_ledb;
+	int ctl_chiprev;
+#ifdef SMC_DEBUG
+	int ctl_reg_bsr;
+	int ctl_reg_tcr;
+	int ctl_reg_esr;
+	int ctl_reg_rcr;
+	int ctl_reg_ctrr;
+	int ctl_reg_mir;
+	int ctl_reg_rpcr;
+	int ctl_reg_cfgr;
+	int ctl_reg_bar;
+	int ctl_reg_iar0;
+	int ctl_reg_iar1;
+	int ctl_reg_iar2;
+	int ctl_reg_gpr;
+	int ctl_reg_ctlr;
+	int ctl_reg_mcr;
+	int ctl_reg_pnr;
+	int ctl_reg_fpr;
+	int ctl_reg_ptr;
+	int ctl_reg_dr;
+	int ctl_reg_isr;
+	int ctl_reg_mtr1;
+	int ctl_reg_mtr2;
+	int ctl_reg_mtr3;
+	int ctl_reg_mtr4;
+	int ctl_reg_miir;
+	int ctl_reg_revr;
+	int ctl_reg_ercvr;
+	int ctl_reg_extr;
+	int ctl_phy_ctrl;
+	int ctl_phy_stat;
+	int ctl_phy_id1;
+	int ctl_phy_id2;
+	int ctl_phy_adc;
+	int ctl_phy_remc;
+	int ctl_phy_cfg1;
+	int ctl_phy_cfg2;
+	int ctl_phy_int;
+	int ctl_phy_mask;
+#endif // SMC_DEBUG
+
+
+#endif // CONFIG_SYSCTL
+
+};
+
+
+/*-----------------------------------------------------------------
+ .
+ .  The driver can be entered at any of the following entry points.
+ .
+ .------------------------------------------------------------------  */
+
+/*
+ . This is called by  register_netdev().  It is responsible for
+ . checking the portlist for the SMC9000 series chipset.  If it finds
+ . one, then it will initialize the device, find the hardware information,
+ . and sets up the appropriate device parameters.
+ . NOTE: Interrupts are *OFF* when this procedure is called.
+ .
+ . NB:This shouldn't be static since it is referred to externally.
+*/
+int smc_init(struct net_device *dev);
+
+/*
+ . This is called by  unregister_netdev().  It is responsible for
+ . cleaning up before the driver is finally unregistered and discarded.
+*/
+void smc_destructor(struct net_device *dev);
+
+/*
+ . The kernel calls this function when someone wants to use the net_device,
+ . typically 'ifconfig ethX up'.
+*/
+static int smc_open(struct net_device *dev);
+
+/*
+ . This is called by the kernel to send a packet out into the net.  it's
+ . responsible for doing a best-effort send, but if it's simply not possible
+ . to send it, the packet gets dropped.
+*/
+static void smc_timeout (struct net_device *dev);
+/*
+ . This is called by the kernel in response to 'ifconfig ethX down'.  It
+ . is responsible for cleaning up everything that the open routine
+ . does, and maybe putting the card into a powerdown state.
+*/
+static int smc_close(struct net_device *dev);
+
+/*
+ . This routine allows the proc file system to query the driver's
+ . statistics.
+*/
+static struct net_device_stats * smc_query_statistics( struct net_device *dev);
+
+/*
+ . Finally, a call to set promiscuous mode ( for TCPDUMP and related
+ . programs ) and multicast modes.
+*/
+static void smc_set_multicast_list(struct net_device *dev);
+
+/*
+ . Configures the PHY through the MII Management interface
+*/
+static void smc_phy_configure(struct net_device* dev);
+
+/*---------------------------------------------------------------
+ .
+ . Interrupt level calls..
+ .
+ ----------------------------------------------------------------*/
+
+/*
+ . Handles the actual interrupt
+*/
+static void smc_interrupt(int irq, void *, struct pt_regs *regs);
+/*
+ . This is a separate procedure to handle the receipt of a packet, to
+ . leave the interrupt code looking slightly cleaner
+*/
+inline static void smc_rcv( struct net_device *dev );
+/*
+ . This handles a TX interrupt, which is only called when an error
+ . relating to a packet is sent.
+*/
+inline static void smc_tx( struct net_device * dev );
+
+/*
+ . This handles interrupts generated from PHY register 18
+*/
+static void smc_phy_interrupt(struct net_device* dev);
+
+/*
+ ------------------------------------------------------------
+ .
+ . Internal routines
+ .
+ ------------------------------------------------------------
+*/
+
+/*
+ . Test if a given location contains a chip, trying to cause as
+ . little damage as possible if it's not a SMC chip.
+*/
+static int smc_probe(struct net_device *dev, unsigned int ioaddr);
+
+/*
+ . A rather simple routine to print out a packet for debugging purposes.
+*/
+#if SMC_DEBUG > 2
+static void print_packet( byte *, int );
+#endif
+
+#define tx_done(dev) 1
+
+/* this is called to actually send the packet to the chip */
+static void smc_hardware_send_packet( struct net_device * dev );
+
+/* Since I am not sure if I will have enough room in the chip's ram
+ . to store the packet, I call this routine, which either sends it
+ . now, or generates an interrupt when the card is ready for the
+ . packet */
+static int  smc_wait_to_send_packet( struct sk_buff * skb, struct net_device *dev );
+
+/* this does a soft reset on the device */
+static void smc_reset( struct net_device* dev );
+
+/* Enable Interrupts, Receive, and Transmit */
+static void smc_enable( struct net_device *dev );
+
+/* this puts the device in an inactive state */
+static void smc_shutdown( unsigned int ioaddr );
+
+#ifndef NO_AUTOPROBE
+/* This routine will find the IRQ of the driver if one is not
+ . specified in the input to the device.  */
+static int smc_findirq( unsigned int ioaddr );
+#endif
+
+/*
+  this routine will set the hardware multicast table to the specified
+  values given it by the higher level routines
+*/
+static void smc_setmulticast( unsigned int ioaddr, int count, struct dev_mc_list *  );
+static int crc32( char *, int );
+
+/* Routines to Read and Write the PHY Registers across the
+   MII Management Interface
+*/
+
+static word smc_read_phy_register(unsigned int ioaddr, byte phyaddr, byte phyreg);
+static void smc_write_phy_register(unsigned int ioaddr, byte phyaddr, byte phyreg, word phydata);
+
+/* Initilizes our device's sysctl proc filesystem */
+
+#ifdef CONFIG_SYSCTL
+static void smc_sysctl_register(struct net_device *);
+static void smc_sysctl_unregister(struct net_device *);
+#endif /* CONFIG_SYSCTL */ 
+
+/*
+ . Function: smc_reset( struct device* dev )
+ . Purpose:
+ .  	This sets the SMC91111 chip to its normal state, hopefully from whatever
+ . 	mess that any other DOS driver has put it in.
+ .
+ . Maybe I should reset more registers to defaults in here?  SOFTRST  should
+ . do that for me.
+ .
+ . Method:
+ .	1.  send a SOFT RESET
+ .	2.  wait for it to finish
+ .	3.  enable autorelease mode
+ .	4.  reset the memory management unit
+ .	5.  clear all interrupts
+ .
+*/
+static void smc_reset( struct net_device* dev )
+{
+	//struct smc_local *lp 	= (struct smc_local *)dev->priv;
+	unsigned int	ioaddr = dev->base_addr;
+
+	PRINTK2("%s:smc_reset\n", dev->name);
+
+	/* This resets the registers mostly to defaults, but doesn't
+	   affect EEPROM.  That seems unnecessary */
+	SMC_SELECT_BANK( 0 );
+	outw( RCR_SOFTRST, ioaddr + RCR_REG );
+
+	/* Setup the Configuration Register */
+	/* This is necessary because the CONFIG_REG is not affected */
+	/* by a soft reset */
+
+	SMC_SELECT_BANK( 1 );
+#ifdef CONFIG_GILBARCONAP
+	outw( CONFIG_DEFAULT | CONFIG_NO_WAIT, ioaddr + CONFIG_REG);
+#else
+	outw( CONFIG_DEFAULT, ioaddr + CONFIG_REG);
+#endif
+
+	/* Setup for fast accesses if requested */
+	/* If the card/system can't handle it then there will */
+	/* be no recovery except for a hard reset or power cycle */
+
+	if (dev->dma)
+		outw( inw( ioaddr + CONFIG_REG ) | CONFIG_NO_WAIT,
+			ioaddr + CONFIG_REG );
+
+#ifdef POWER_DOWN
+	/* Release from possible power-down state */
+	/* Configuration register is not affected by Soft Reset */
+	SMC_SELECT_BANK( 1 );
+	outw( inw( ioaddr + CONFIG_REG ) | CONFIG_EPH_POWER_EN,
+		ioaddr + CONFIG_REG  );
+#endif
+
+	SMC_SELECT_BANK( 0 );
+
+	/* this should pause enough for the chip to be happy */
+	mdelay(10);
+
+	/* Disable transmit and receive functionality */
+	outw( RCR_CLEAR, ioaddr + RCR_REG );
+	outw( TCR_CLEAR, ioaddr + TCR_REG );
+
+	/* set the control register to automatically
+	   release successfully transmitted packets, to make the best
+	   use out of our limited memory */
+	SMC_SELECT_BANK( 1 );
+	outw( inw( ioaddr + CTL_REG ) | CTL_AUTO_RELEASE , ioaddr + CTL_REG );
+
+	/* Reset the MMU */
+	SMC_SELECT_BANK( 2 );
+	outw( MC_RESET, ioaddr + MMU_CMD_REG );
+
+	/* Note:  It doesn't seem that waiting for the MMU busy is needed here,
+	   but this is a place where future chipsets _COULD_ break.  Be wary
+ 	   of issuing another MMU command right after this */
+
+	/* Disable all interrupts */
+#if defined(CONFIG_SMC16BITONLY)
+	outw( 0, ioaddr + INT_REG );
+#else
+	outb( 0, ioaddr + IM_REG );
+#endif
+}
+
+/*
+ . Function: smc_enable
+ . Purpose: let the chip talk to the outside work
+ . Method:
+ .	1.  Enable the transmitter
+ .	2.  Enable the receiver
+ .	3.  Enable interrupts
+*/
+static void smc_enable( struct net_device *dev )
+{
+	unsigned int ioaddr 	= dev->base_addr;
+	struct smc_local *lp 	= (struct smc_local *)dev->priv;
+
+	PRINTK2("%s:smc_enable\n", dev->name);
+
+	SMC_SELECT_BANK( 0 );
+	/* see the header file for options in TCR/RCR DEFAULT*/
+	outw( lp->tcr_cur_mode, ioaddr + TCR_REG );
+	outw( lp->rcr_cur_mode, ioaddr + RCR_REG );
+
+	/* now, enable interrupts */
+	SMC_SELECT_BANK( 2 );
+#if defined(CONFIG_SMC16BITONLY)
+	outw( (SMC_INTERRUPT_MASK << 8), ioaddr + INT_REG );
+#else
+	outb( SMC_INTERRUPT_MASK, ioaddr + IM_REG );
+#endif
+}
+
+/*
+ . Function: smc_shutdown
+ . Purpose:  closes down the SMC91xxx chip.
+ . Method:
+ .	1. zero the interrupt mask
+ .	2. clear the enable receive flag
+ .	3. clear the enable xmit flags
+ .
+ . TODO:
+ .   (1) maybe utilize power down mode.
+ .	Why not yet?  Because while the chip will go into power down mode,
+ .	the manual says that it will wake up in response to any I/O requests
+ .	in the register space.   Empirical results do not show this working.
+*/
+static void smc_shutdown( unsigned int ioaddr )
+{
+	PRINTK2("CARDNAME:smc_shutdown\n");
+
+	/* no more interrupts for me */
+	SMC_SELECT_BANK( 2 );
+#if defined(CONFIG_SMC16BITONLY)
+	outw( 0, ioaddr + INT_REG );
+#else
+	outb( 0, ioaddr + IM_REG );
+#endif
+
+	/* and tell the card to stay away from that nasty outside world */
+	SMC_SELECT_BANK( 0 );
+#if defined(CONFIG_SMC16BITONLY)
+	outw( RCR_CLEAR, ioaddr + RCR_REG );
+	outw( TCR_CLEAR, ioaddr + TCR_REG );
+#else
+	outb( RCR_CLEAR, ioaddr + RCR_REG );
+	outb( TCR_CLEAR, ioaddr + TCR_REG );
+#endif
+
+#ifdef POWER_DOWN
+	/* finally, shut the chip down */
+	SMC_SELECT_BANK( 1 );
+	outw( inw( ioaddr + CONFIG_REG ) & ~CONFIG_EPH_POWER_EN,
+		ioaddr + CONFIG_REG  );
+#endif
+}
+
+
+/*
+ . Function: smc_setmulticast( unsigned int ioaddr, int count, dev_mc_list * adds )
+ . Purpose:
+ .    This sets the internal hardware table to filter out unwanted multicast
+ .    packets before they take up memory.
+ .
+ .    The SMC chip uses a hash table where the high 6 bits of the CRC of
+ .    address are the offset into the table.  If that bit is 1, then the
+ .    multicast packet is accepted.  Otherwise, it's dropped silently.
+ .
+ .    To use the 6 bits as an offset into the table, the high 3 bits are the
+ .    number of the 8 bit register, while the low 3 bits are the bit within
+ .    that register.
+ .
+ . This routine is based very heavily on the one provided by Peter Cammaert.
+*/
+
+
+static void smc_setmulticast( unsigned int ioaddr, int count, struct dev_mc_list * addrs ) {
+	int			i;
+	unsigned char		multicast_table[ 8 ];
+	struct dev_mc_list	* cur_addr;
+	/* table for flipping the order of 3 bits */
+	unsigned char invert3[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+	PRINTK2("CARDNAME:smc_setmulticast\n");
+
+	/* start with a table of all zeros: reject all */
+	memset( multicast_table, 0, sizeof( multicast_table ) );
+
+	cur_addr = addrs;
+	for ( i = 0; i < count ; i ++, cur_addr = cur_addr->next  ) {
+		int position;
+
+		/* do we have a pointer here? */
+		if ( !cur_addr )
+			break;
+		/* make sure this is a multicast address - shouldn't this
+		   be a given if we have it here ? */
+		if ( !( *cur_addr->dmi_addr & 1 ) )
+			continue;
+
+		/* only use the low order bits */
+		position = crc32( cur_addr->dmi_addr, 6 ) & 0x3f;
+
+		/* do some messy swapping to put the bit in the right spot */
+		multicast_table[invert3[position&7]] |=
+					(1<<invert3[(position>>3)&7]);
+
+	}
+	/* now, the table can be loaded into the chipset */
+	SMC_SELECT_BANK( 3 );
+
+#if defined(CONFIG_SMC16BITONLY)
+	for ( i = 0; i < 8 ; i += 2 ) {
+		outw( ((multicast_table[i+1]<<8) | (multicast_table[i])),
+			ioaddr + MCAST_REG1 + i );
+	}
+#else
+	for ( i = 0; i < 8 ; i++ ) {
+		outb( multicast_table[i], ioaddr + MCAST_REG1 + i );
+	}
+#endif
+}
+
+/*
+  Finds the CRC32 of a set of bytes.
+  Again, from Peter Cammaert's code.
+*/
+static int crc32( char * s, int length ) {
+	/* indices */
+	int perByte;
+	int perBit;
+	/* crc polynomial for Ethernet */
+	const unsigned long poly = 0xedb88320;
+	/* crc value - preinitialized to all 1's */
+	unsigned long crc_value = 0xffffffff;
+
+	for ( perByte = 0; perByte < length; perByte ++ ) {
+		unsigned char	c;
+
+		c = *(s++);
+		for ( perBit = 0; perBit < 8; perBit++ ) {
+			crc_value = (crc_value>>1)^
+				(((crc_value^c)&0x01)?poly:0);
+			c >>= 1;
+		}
+	}
+	return	crc_value;
+}
+
+
+/*
+ . Function: smc_wait_to_send_packet( struct sk_buff * skb, struct device * )
+ . Purpose:
+ .    Attempt to allocate memory for a packet, if chip-memory is not
+ .    available, then tell the card to generate an interrupt when it
+ .    is available.
+ .
+ . Algorithm:
+ .
+ . o	if the saved_skb is not currently null, then drop this packet
+ .	on the floor.  This should never happen, because of TBUSY.
+ . o	if the saved_skb is null, then replace it with the current packet,
+ . o	See if I can sending it now.
+ . o 	(NO): Enable interrupts and let the interrupt handler deal with it.
+ . o	(YES):Send it now.
+*/
+static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * dev )
+{
+	struct smc_local *lp 	= (struct smc_local *)dev->priv;
+	unsigned int ioaddr 	= dev->base_addr;
+	word 			length;
+	unsigned short 		numPages;
+	word			time_out;
+	word			status;
+
+	PRINTK3("%s:smc_wait_to_send_packet\n", dev->name);
+
+	if ( lp->saved_skb) {
+		/* THIS SHOULD NEVER HAPPEN. */
+		lp->stats.tx_aborted_errors++;
+		printk("%s: Bad Craziness - sent packet while busy.\n",
+			dev->name);
+		return 1;
+	}
+	lp->saved_skb = skb;
+
+	length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+
+		
+	/*
+	** The MMU wants the number of pages to be the number of 256 bytes
+	** 'pages', minus 1 ( since a packet can't ever have 0 pages :) )
+	**
+	** The 91C111 ignores the size bits, but the code is left intact
+	** for backwards and future compatibility.
+	**
+	** Pkt size for allocating is data length +6 (for additional status
+	** words, length and ctl!)
+	**
+	** If odd size then last byte is included in this header.
+	*/
+	numPages =   ((length & 0xfffe) + 6);
+	numPages >>= 8; // Divide by 256
+
+	if (numPages > 7 ) {
+		printk("%s: Far too big packet error. \n", dev->name);
+		/* freeing the packet is a good thing here... but should
+		 . any packets of this size get down here?   */
+		dev_kfree_skb (skb);
+		lp->saved_skb = NULL;
+		/* this IS an error, but, i don't want the skb saved */
+		netif_wake_queue(dev);
+		return 0;
+	}
+	/* either way, a packet is waiting now */
+	lp->packets_waiting++;
+
+	/* now, try to allocate the memory */
+	SMC_SELECT_BANK( 2 );
+	outw( MC_ALLOC | numPages, ioaddr + MMU_CMD_REG );
+	/*
+ 	. Performance Hack
+	.
+ 	. wait a short amount of time.. if I can send a packet now, I send
+	. it now.  Otherwise, I enable an interrupt and wait for one to be
+	. available.
+	.
+	. I could have handled this a slightly different way, by checking to
+	. see if any memory was available in the FREE MEMORY register.  However,
+	. either way, I need to generate an allocation, and the allocation works
+	. no matter what, so I saw no point in checking free memory.
+	*/
+	time_out = MEMORY_WAIT_TIME;
+	do {
+		status = inb( ioaddr + INT_REG );
+		if ( status & IM_ALLOC_INT ) {
+			/* acknowledge the interrupt */
+#if defined(CONFIG_SMC16BITONLY)
+			outw( IM_ALLOC_INT | (inb(ioaddr + IM_REG) << 8),
+				ioaddr + INT_REG );
+#else
+			outb( IM_ALLOC_INT, ioaddr + INT_REG );
+#endif
+  			break;
+		}
+   	} while ( -- time_out );
+
+   	if ( !time_out ) {
+		/* oh well, wait until the chip finds memory later */
+		SMC_ENABLE_INT( IM_ALLOC_INT );
+
+		/* Check the status bit one more time just in case */
+		/* it snuk in between the time we last checked it */
+		/* and when we set the interrupt bit */
+		status = inb( ioaddr + INT_REG );
+		if ( !(status & IM_ALLOC_INT) ) {
+      			PRINTK2("%s: memory allocation deferred. \n",
+				dev->name);
+			netif_stop_queue(dev);			
+
+			/* it's deferred, but I'll handle it later */
+      			return 0;
+			}
+
+		/* Looks like it did sneak in, so disable */
+		/* the interrupt */
+		SMC_DISABLE_INT( IM_ALLOC_INT );
+   	}
+	/* or YES! I can send the packet now.. */
+	smc_hardware_send_packet(dev);
+	netif_wake_queue(dev);
+	return 0;
+}
+
+/*
+ . Function:  smc_hardware_send_packet(struct device * )
+ . Purpose:
+ .	This sends the actual packet to the SMC9xxx chip.
+ .
+ . Algorithm:
+ . 	First, see if a saved_skb is available.
+ .		( this should NOT be called if there is no 'saved_skb'
+ .	Now, find the packet number that the chip allocated
+ .	Point the data pointers at it in memory
+ .	Set the length word in the chip's memory
+ .	Dump the packet to chip memory
+ .	Check if a last byte is needed ( odd length packet )
+ .		if so, set the control flag right
+ . 	Tell the card to send it
+ .	Enable the transmit interrupt, so I know if it failed
+ . 	Free the kernel data if I actually sent it.
+*/
+static void smc_hardware_send_packet( struct net_device * dev )
+{
+	struct smc_local *lp = (struct smc_local *)dev->priv;
+	byte	 		packet_no;
+	struct sk_buff * 	skb = lp->saved_skb;
+	word			length;
+	unsigned int		ioaddr;
+	byte			* buf;
+
+	PRINTK3("%s:smc_hardware_send_packet\n", dev->name);
+
+	ioaddr = dev->base_addr;
+
+	if ( !skb ) {
+		PRINTK("%s: In XMIT with no packet to send \n", dev->name);
+		return;
+	}
+	length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+	buf = skb->data;
+
+	/* If I get here, I _know_ there is a packet slot waiting for me */
+	packet_no = inb( ioaddr + AR_REG );
+	if ( packet_no & AR_FAILED ) {
+		/* or isn't there?  BAD CHIP! */
+		printk(KERN_DEBUG "%s: Memory allocation failed. \n",
+			dev->name);
+		dev_kfree_skb_any (skb);
+		lp->saved_skb = NULL;
+		netif_wake_queue(dev);
+		return;
+	}
+
+	/* we have a packet address, so tell the card to use it */
+#if defined(CONFIG_SMC16BITONLY)
+	outw( packet_no, ioaddr + PN_REG );
+#else
+	outb( packet_no, ioaddr + PN_REG );
+#endif
+
+	/* point to the beginning of the packet */
+	outw( PTR_AUTOINC , ioaddr + PTR_REG );
+
+   	PRINTK3("%s: Trying to xmit packet of length %x\n",
+		dev->name, length);
+
+#if SMC_DEBUG > 2
+	printk("Transmitting Packet\n");
+	print_packet( buf, length );
+#endif
+
+	/* send the packet length ( +6 for status, length and ctl byte )
+ 	   and the status word ( set to zeros ) */
+#ifdef USE_32_BIT
+#if defined(CONFIG_SMC16BITONLY)
+	outl(  (length +6 ) , ioaddr + DATA_REG );
+#else
+	outl(  (length +6 ) << 16 , ioaddr + DATA_REG );
+#endif
+#else
+	outw( 0, ioaddr + DATA_REG );
+	/* send the packet length ( +6 for status words, length, and ctl*/
+#if defined(CONFIG_SMC16BITONLY)
+	outw( (length+6) & 0xFFFF,ioaddr + DATA_REG );
+#else
+	outb( (length+6) & 0xFF,ioaddr + DATA_REG );
+	outb( (length+6) >> 8 , ioaddr + DATA_REG );
+#endif
+#endif
+
+	/* send the actual data
+	 . I _think_ it's faster to send the longs first, and then
+	 . mop up by sending the last word.  It depends heavily
+ 	 . on alignment, at least on the 486.  Maybe it would be
+ 	 . a good idea to check which is optimal?  But that could take
+	 . almost as much time as is saved?
+	*/
+#ifdef USE_32_BIT
+	outsl(ioaddr + DATA_REG, buf,  length >> 2 );
+	if ( length & 0x2  )
+#if defined(CONFIG_SMC16BITONLY)
+		outwd(*((word *)(buf + (length & 0xFFFFFFFC))),ioaddr+DATA_REG);
+#else
+		outw(*((word *)(buf + (length & 0xFFFFFFFC))),ioaddr+DATA_REG);
+#endif
+#else
+	outsw(ioaddr + DATA_REG , buf, (length ) >> 1);
+#endif // USE_32_BIT
+
+	/* Send the last byte, if there is one.   */
+	if ( (length & 1) == 0 ) {
+		outw( 0, ioaddr + DATA_REG );
+	} else {
+#if defined(CONFIG_SMC16BITONLY)
+		outw( buf[length -1 ] | 0x2000, ioaddr + DATA_REG );
+#else
+		outb( buf[length -1 ], ioaddr + DATA_REG );
+		outb( 0x20, ioaddr + DATA_REG); // Set odd bit in CONTROL BYTE
+#endif
+	}
+
+	/* enable the interrupts */
+	SMC_ENABLE_INT( (IM_TX_INT | IM_TX_EMPTY_INT) );
+
+	/* and let the chipset deal with it */
+	outw( MC_ENQUEUE , ioaddr + MMU_CMD_REG );
+
+	PRINTK2("%s: Sent packet of length %d \n", dev->name, length);
+
+	lp->saved_skb = NULL;
+	dev_kfree_skb_any (skb);
+
+	dev->trans_start = jiffies;
+
+	/* we can send another packet */
+	netif_wake_queue(dev);
+
+
+	return;
+}
+
+/*-------------------------------------------------------------------------
+ |
+ | smc_init( struct device * dev )
+ |   Input parameters:
+ |	dev->base_addr == 0, try to find all possible locations
+ |	dev->base_addr == 1, return failure code
+ |	dev->base_addr == 2, always allocate space,  and return success
+ |	dev->base_addr == <anything else>   this is the address to check
+ |
+ |   Output:
+ |	0 --> there is a device
+ |	anything else, error
+ |
+ ---------------------------------------------------------------------------
+*/
+int __init smc_init(struct net_device *dev)
+{
+	PRINTK2("CARDNAME:smc_init\n");
+
+	SET_MODULE_OWNER (dev);
+
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_SUZAKU)
+{
+	static int index = 0;
+
+	/* check every ethernet address */
+	while (smc_portlist[index]) {
+		dev->irq = smc_irqlist[index];
+		if ( smc_probe(dev,smc_portlist[index++]) == 0 )
+			return 0;
+	}
+}
+#else
+{
+	int i;
+	int base_addr = dev ? dev->base_addr : 0;
+
+	/*  try a specific location */
+	if (base_addr > 0x1ff)
+		return smc_probe(dev, base_addr);
+	else if ( 0 != base_addr ) 
+		return -ENXIO;
+		
+	/* check every ethernet address */
+	for (i = 0; smc_portlist[i]; i++) {
+		if ( smc_probe(dev,smc_portlist[i]) ==0)
+			return 0;
+	}
+}
+#endif
+		
+	/* couldn't find anything */
+	return -ENODEV;
+}
+
+
+/*-------------------------------------------------------------------------
+ |
+ | smc_destructor( struct device * dev )
+ |   Input parameters:
+ |	dev, pointer to the device structure
+ |
+ |   Output:
+ |	None.
+ |
+ ---------------------------------------------------------------------------
+*/
+void smc_destructor(struct net_device *dev)
+{
+	PRINTK2("CARDNAME:smc_destructor\n");
+}
+
+
+#ifndef NO_AUTOPROBE
+/*----------------------------------------------------------------------
+ . smc_findirq
+ .
+ . This routine has a simple purpose -- make the SMC chip generate an
+ . interrupt, so an auto-detect routine can detect it, and find the IRQ,
+ ------------------------------------------------------------------------
+*/
+int __init smc_findirq( unsigned int ioaddr )
+{
+	int	timeout = 20;
+	unsigned long cookie;
+
+	PRINTK2("CARDNAME:smc_findirq\n");
+
+	/* I have to do a STI() here, because this is called from
+	   a routine that does an CLI during this process, making it
+	   rather difficult to get interrupts for auto detection */
+	sti();
+
+	cookie = probe_irq_on();
+
+	/*
+	 * What I try to do here is trigger an ALLOC_INT. This is done
+	 * by allocating a small chunk of memory, which will give an interrupt
+	 * when done.
+	 */
+
+
+	SMC_SELECT_BANK(2);
+	/* enable ALLOCation interrupts ONLY */
+#if defined(CONFIG_SMC16BITONLY)
+	outw( IM_ALLOC_INT | (inb(ioaddr + IM_REG) << 8), ioaddr + INT_REG );
+#else
+	outb( IM_ALLOC_INT, ioaddr + IM_REG );
+#endif
+
+	/*
+ 	 . Allocate 512 bytes of memory.  Note that the chip was just
+	 . reset so all the memory is available
+	*/
+	outw( MC_ALLOC | 1, ioaddr + MMU_CMD_REG );
+
+	/*
+	 . Wait until positive that the interrupt has been generated
+	*/
+	while ( timeout ) {
+		byte	int_status;
+
+		int_status = inb( ioaddr + INT_REG );
+
+		if ( int_status & IM_ALLOC_INT )
+			break;		/* got the interrupt */
+		timeout--;
+	}
+
+	/* there is really nothing that I can do here if timeout fails,
+	   as autoirq_report will return a 0 anyway, which is what I
+	   want in this case.   Plus, the clean up is needed in both
+	   cases.  */
+
+	/* DELAY HERE!
+	   On a fast machine, the status might change before the interrupt
+	   is given to the processor.  This means that the interrupt was
+	   never detected, and autoirq_report fails to report anything.
+	   This should fix autoirq_* problems.
+	*/
+	mdelay(10);
+
+	/* and disable all interrupts again */
+#if defined(CONFIG_SMC16BITONLY)
+	outw( 0, ioaddr + INT_REG );
+#else
+	outb( 0, ioaddr + IM_REG );
+#endif
+
+	/* clear hardware interrupts again, because that's how it
+	   was when I was called... */
+	cli();
+
+	/* and return what I found */
+	return probe_irq_off(cookie);
+}
+#endif
+
+/*----------------------------------------------------------------------
+ . Function: smc_probe( unsigned int ioaddr )
+ .
+ . Purpose:
+ .	Tests to see if a given ioaddr points to an SMC91111 chip.
+ .	Returns a 0 on success
+ .
+ . Algorithm:
+ .	(1) see if the high byte of BANK_SELECT is 0x33
+ . 	(2) compare the ioaddr with the base register's address
+ .	(3) see if I recognize the chip ID in the appropriate register
+ .
+ .---------------------------------------------------------------------
+ */
+/*---------------------------------------------------------------
+ . Here I do typical initialization tasks.
+ .
+ . o  Initialize the structure if needed
+ . o  print out my vanity message if not done so already
+ . o  print out what type of hardware is detected
+ . o  print out the ethernet address
+ . o  find the IRQ
+ . o  set up my private data
+ . o  configure the dev structure with my subroutines
+ . o  actually GRAB the irq.
+ . o  GRAB the region
+ .-----------------------------------------------------------------*/
+
+static int __init smc_probe(struct net_device *dev, unsigned int ioaddr )
+{
+	int i, memory, retval;
+	static unsigned version_printed = 0;
+	unsigned int	bank;
+
+        const char *version_string;
+
+	/*registers */
+	word	revision_register;
+	word	base_address_register;
+	word  	memory_info_register;
+	/*=> Pramod */
+	struct smc_local *lp;
+	/*<= Pramod */
+
+	PRINTK2("CARDNAME:smc_probe\n");
+
+#if !defined(CONFIG_M5249C3) && !defined(CONFIG_GILBARCONAP)
+	/* Grab the region so that no one else tries to probe our ioports. */
+	if (!request_region(ioaddr, SMC_IO_EXTENT, dev->name)) return -EBUSY;
+#endif
+
+	/* First, see if the high byte is 0x33 */
+	bank = inw( ioaddr + BANK_SELECT );
+	if ( (bank & 0xFF00) != 0x3300 ) return -ENODEV;
+
+	/* The above MIGHT indicate a device, but I need to write to further test this.  */
+	outw( 0x0, ioaddr + BANK_SELECT );
+	bank = inw( ioaddr + BANK_SELECT );
+	if ( (bank & 0xFF00 ) != 0x3300 )
+	{
+		retval = -ENODEV;
+		goto err_out;
+	}
+
+	/* well, we've already written once, so hopefully another time won't
+ 	   hurt.  This time, I need to switch the bank register to bank 1,
+	   so I can access the base address register */
+	SMC_SELECT_BANK(1);
+	base_address_register = inw( ioaddr + BASE_REG );
+#if defined(CONFIG_M5249C3) || defined(CONFIG_GILBARCONAP) || defined(CONFIG_RTE_CB_ME2) || defined(CONFIG_SUZAKU)
+	if ((ioaddr & 0xfff) != (base_address_register >> 3 & 0x3E0))
+#else
+	if ( ioaddr != ( base_address_register >> 3 & 0x3E0 ) )
+#endif
+	{
+		printk("CARDNAME: IOADDR %x doesn't match configuration (%x)."
+			"Probably not a SMC chip\n",
+			ioaddr, base_address_register >> 3 & 0x3E0 );
+		/* well, the base address register didn't match.  Must not have
+		   been a SMC chip after all. */
+		retval = -ENODEV;
+		goto err_out;
+	}
+
+	/*  check if the revision register is something that I recognize.
+	    These might need to be added to later, as future revisions
+	    could be added.  */
+	SMC_SELECT_BANK(3);
+	revision_register  = inw( ioaddr + REV_REG );
+	if ( !chip_ids[ ( revision_register  >> 4 ) & 0xF  ] )
+	{
+		/* I don't recognize this chip, so... */
+		printk("CARDNAME: IO %x: Unrecognized revision register:"
+			" %x, Contact author. \n",
+			ioaddr, revision_register );
+		retval =  -ENODEV;
+		goto err_out;
+	}
+
+	/* at this point I'll assume that the chip is an SMC9xxx.
+	   It might be prudent to check a listing of MAC addresses
+	   against the hardware address, or do some other tests. */
+
+	if (version_printed++ == 0)
+		printk("%s", version);
+
+	/* fill in some of the fields */
+	dev->base_addr = ioaddr;
+
+#if defined(CONFIG_M5249C3)
+	/* Program MAC address if not set... */
+	SMC_SELECT_BANK( 1 );
+	for (i = 0; (i < 6); i += 2) {
+		word address;
+		address = inw( ioaddr + ADDR0_REG + i ) ;
+		if ((address != 0x0000) && (address != 0xffff))
+			break;
+	}
+	if (i >= 6) {
+		/* Set a default MAC address */
+		outw(0xCF00, ioaddr + ADDR0_REG);
+		outw(0x4952, ioaddr + ADDR0_REG + 2);
+		outw(0x01C3, ioaddr + ADDR0_REG + 4);
+	}
+#endif
+#if defined(CONFIG_GILBARCONAP)
+{
+	unsigned char *ep;
+
+	/* Pull MAC address from FLASH */
+	ep = (unsigned char *) 0xf0006006;
+	if ((ep[0] == 0xff) && (ep[1] == 0xff) && (ep[2] == 0xff) &&
+	    (ep[3] == 0xff) && (ep[4] == 0xff) && (ep[5] == 0xff))
+		ep = (unsigned char *) &smc_defethaddr[0];
+	else if ((ep[0] == 0) && (ep[1] == 0) && (ep[2] == 0) &&
+	    (ep[3] == 0) && (ep[4] == 0) && (ep[5] == 0))
+		ep = (unsigned char *) &smc_defethaddr[0];
+
+	SMC_SELECT_BANK( 1 );
+	for (i = 0; i < 6; i += 2) {
+		word address;
+		address = (((word) ep[i+1]) << 8) | ep[i];
+		outw(address, ioaddr + ADDR0_REG + i);
+	}
+}
+#endif
+
+	/*
+ 	 . Get the MAC address ( bank 1, regs 4 - 9 )
+	*/
+	SMC_SELECT_BANK( 1 );
+	for ( i = 0; i < 6; i += 2 )
+	{
+		word	address;
+
+		address = inw( ioaddr + ADDR0_REG + i  );
+		dev->dev_addr[ i + 1] = address >> 8;
+		dev->dev_addr[ i ] = address & 0xFF;
+	}
+
+	/* get the memory information */
+
+	SMC_SELECT_BANK( 0 );
+	memory_info_register = inw( ioaddr + MIR_REG );
+	memory = memory_info_register & (word)0x00ff;
+	memory *= LAN91C111_MEMORY_MULTIPLIER;
+
+	/*
+	 Now, I want to find out more about the chip.  This is sort of
+ 	 redundant, but it's cleaner to have it in both, rather than having
+ 	 one VERY long probe procedure.
+	*/
+	SMC_SELECT_BANK(3);
+	revision_register  = inw( ioaddr + REV_REG );
+	version_string = chip_ids[ ( revision_register  >> 4 ) & 0xF  ];
+	if ( !version_string )
+	{
+		/* I shouldn't get here because this call was done before.... */
+		retval =  -ENODEV;
+		goto err_out;
+	}
+
+	/* now, reset the chip, and put it into a known state */
+	smc_reset( dev );
+
+#if !defined(CONFIG_SUZAKU)
+	/*
+	 . If dev->irq is 0, then the device has to be banged on to see
+	 . what the IRQ is.
+ 	 .
+	 . This banging doesn't always detect the IRQ, for unknown reasons.
+	 . a workaround is to reset the chip and try again.
+	 .
+	 . Interestingly, the DOS packet driver *SETS* the IRQ on the card to
+	 . be what is requested on the command line.   I don't do that, mostly
+	 . because the card that I have uses a non-standard method of accessing
+	 . the IRQs, and because this _should_ work in most configurations.
+	 .
+	 . Specifying an IRQ is done with the assumption that the user knows
+	 . what (s)he is doing.  No checking is done!!!!
+ 	 .
+	*/
+	if ( dev->irq < 2 ) {
+		int	trials;
+
+		trials = 3;
+		while ( trials-- ) {
+			dev->irq = smc_findirq( ioaddr );
+			if ( dev->irq )
+				break;
+			/* kick the card and try again */
+			smc_reset( dev );
+		}
+	}
+	if (dev->irq == 0 ) {
+		printk("%s: Couldn't autodetect your IRQ. Use irq=xx.\n",
+			dev->name);
+		retval =  -ENODEV;
+		goto err_out;
+	}
+
+	if (dev->irq == 2) {
+		/* Fixup for users that don't know that IRQ 2 is really IRQ 9,
+		 * or don't know which one to set.
+		 */
+		dev->irq = 9;
+	}
+#endif
+
+	/* now, print out the card info, in a short format.. */
+
+	printk("%s: %s(rev:%d) at %#3x IRQ:%d MEMSIZE:%db NOWAIT:%d ",
+		dev->name,
+		version_string, revision_register & 0xF, ioaddr, dev->irq,
+		memory, dev->dma);
+	/*
+	 . Print the Ethernet address
+	*/
+	printk("ADDR: ");
+	for (i = 0; i < 5; i++)
+		printk("%2.2x:", dev->dev_addr[i] );
+	printk("%2.2x \n", dev->dev_addr[5] );
+
+
+	/* Initialize the private structure. */
+	if (dev->priv == NULL) {
+		dev->priv = kmalloc(sizeof(struct smc_local), GFP_KERNEL);
+		if (dev->priv == NULL) {
+			retval = -ENOMEM;
+			goto err_out;
+		}
+	}
+	/* set the private data to zero by default */
+	memset(dev->priv, 0, sizeof(struct smc_local));
+
+	/* Fill in the fields of the device structure with ethernet values. */
+	ether_setup(dev);
+
+	/* Grab the IRQ */
+	retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev);
+	if (retval) {
+       	  printk("%s: unable to get IRQ %d (irqval=%d).\n",
+		dev->name, dev->irq, retval);
+		  kfree (dev->priv);
+		  dev->priv = NULL;
+		  goto err_out;
+      	}
+
+#if defined(CONFIG_M5249C3)
+	/* Enable interrupts for GPIO6 */
+	*((volatile unsigned long *) (MCF_MBAR2+MCFSIM2_GPIOINTENABLE)) |=
+		0x00000040;
+	/* Enable interrupt level for GPIO6 - VEC38 */
+	*((volatile unsigned long *) (MCF_MBAR2+MCFSIM2_INTLEVEL5)) |=
+		0x04000000;
+#endif
+#if defined(CONFIG_GILBARCONAP)
+{
+	/* Enable INT4 function on multi-purpose pin PD5 */
+	*((volatile unsigned long *) (MCF_MBAR+MCFSIM_PDCNT)) |= 0x00000c00;
+
+	/* Enable interrupts on external INT4  */
+	*((volatile unsigned long *) (MCF_MBAR+MCFSIM_ICR1)) |= 0x000d0000;
+	/**((volatile unsigned long *) (MCF_MBAR+MCFSIM_PITR)) |= 0x10000000;*/
+}
+#endif
+
+	dev->open	        = smc_open;
+	dev->stop	        = smc_close;
+	dev->hard_start_xmit   	= smc_wait_to_send_packet;
+	dev->tx_timeout		= smc_timeout;
+	dev->get_stats		= smc_query_statistics;
+#ifdef	HAVE_MULTICAST
+	dev->set_multicast_list = &smc_set_multicast_list;
+#endif
+
+	/* => Store the ChipRevision and ChipID, to be used in resolving the Odd-Byte issue in RevB of LAN91C111; Pramod */
+	SMC_SELECT_BANK(3);
+	revision_register  = inw( ioaddr + REV_REG );
+	lp = (struct smc_local *)dev->priv;
+	lp->ChipID = (revision_register >> 4) & 0xF;
+	lp->ChipRev = revision_register & 0xF;
+
+	return 0;
+
+err_out:
+	release_region (ioaddr, SMC_IO_EXTENT);
+	return retval;
+}
+
+#if SMC_DEBUG > 2
+static void print_packet( byte * buf, int length )
+{
+#if 1
+#if SMC_DEBUG > 3
+	int i;
+	int remainder;
+	int lines;
+#endif
+
+	printk("Packet of length %d \n", length );
+
+#if SMC_DEBUG > 3
+	lines = length / 16;
+	remainder = length % 16;
+
+	for ( i = 0; i < lines ; i ++ ) {
+		int cur;
+
+		for ( cur = 0; cur < 8; cur ++ ) {
+			byte a, b;
+
+			a = *(buf ++ );
+			b = *(buf ++ );
+			printk("%02x%02x ", a, b );
+		}
+		printk("\n");
+	}
+	for ( i = 0; i < remainder/2 ; i++ ) {
+		byte a, b;
+
+		a = *(buf ++ );
+		b = *(buf ++ );
+		printk("%02x%02x ", a, b );
+	}
+	printk("\n");
+#endif
+#endif
+}
+#endif
+
+
+/*
+ * Open and Initialize the board
+ *
+ * Set up everything, reset the card, etc ..
+ *
+ */
+static int smc_open(struct net_device *dev)
+{
+	struct smc_local *lp 	= (struct smc_local *)dev->priv;
+	unsigned int	ioaddr = dev->base_addr;
+	int	i;	/* used to set hw ethernet address */
+
+	PRINTK2("%s:smc_open\n", dev->name);
+
+	/* clear out all the junk that was put here before... */
+	memset(dev->priv, 0, sizeof(struct smc_local));
+
+	netif_start_queue(dev);
+#ifdef MODULE
+	MOD_INC_USE_COUNT;
+#endif
+
+	// Setup the default Register Modes
+	lp->tcr_cur_mode = TCR_DEFAULT;
+	lp->rcr_cur_mode = RCR_DEFAULT;
+	lp->rpc_cur_mode = RPC_DEFAULT;
+
+#ifdef CONFIG_SYSCTL
+	// Set default parameters (files)
+	lp->ctl_swfdup = 0;
+	lp->ctl_ephloop = 0;
+	lp->ctl_miiop = 0;
+	lp->ctl_autoneg = 1;
+	lp->ctl_rfduplx = 1;
+	lp->ctl_rspeed = 100;
+	lp->ctl_afduplx = 1;
+	lp->ctl_aspeed = 100;
+	lp->ctl_lnkfail = 1;
+	lp->ctl_forcol = 0;
+	lp->ctl_filtcar = 0;
+#endif
+
+	/* reset the hardware */
+
+	smc_reset( dev );
+	smc_enable( dev );
+
+	/* Configure the PHY */
+	smc_phy_configure(dev);
+
+	/*
+  		According to Becker, I have to set the hardware address
+		at this point, because the (l)user can set it with an
+		ioctl.  Easily done...
+	*/
+	SMC_SELECT_BANK( 1 );
+	for ( i = 0; i < 6; i += 2 ) {
+		word	address;
+
+		address = dev->dev_addr[ i + 1 ] << 8 ;
+		address  |= dev->dev_addr[ i ];
+		outw( address, ioaddr + ADDR0_REG + i );
+	}
+
+#ifdef CONFIG_SYSCTL
+	smc_sysctl_register(dev);
+#endif /* CONFIG_SYSCTL */ 
+
+	netif_start_queue(dev);
+	return 0;
+}
+
+/*--------------------------------------------------------
+ . Called by the kernel to send a packet out into the void
+ . of the net.  This routine is largely based on
+ . skeleton.c, from Becker.
+ .--------------------------------------------------------
+*/
+static void smc_timeout (struct net_device *dev)
+{
+
+	PRINTK3("%s:smc_send_packet\n", dev->name);
+
+	/* If we get here, some higher level has decided we are broken.
+	There should really be a "kick me" function call instead. */
+	printk(KERN_WARNING "%s: transmit timed out, %s?\n",dev->name, tx_done(dev) ? "IRQ conflict" :"network cable problem");
+	/* "kick" the adaptor */
+	smc_reset( dev );
+	smc_enable( dev );
+
+	/* Reconfigure the PHY */
+	smc_phy_configure(dev);
+
+	netif_wake_queue(dev);
+	dev->trans_start = jiffies;
+	/* clear anything saved */
+	((struct smc_local *)dev->priv)->saved_skb = NULL;
+}
+
+/*--------------------------------------------------------------------
+ .
+ . This is the main routine of the driver, to handle the net_device when
+ . it needs some attention.
+ .
+ . So:
+ .   first, save state of the chipset
+ .   branch off into routines to handle each case, and acknowledge
+ .	    each to the interrupt register
+ .   and finally restore state.
+ .
+ ---------------------------------------------------------------------*/
+static void smc_interrupt(int irq, void * dev_id,  struct pt_regs * regs)
+{
+	struct net_device *dev 	= dev_id;
+	unsigned int ioaddr 	= dev->base_addr;
+	struct smc_local *lp 	= (struct smc_local *)dev->priv;
+
+	byte	status;
+	word	card_stats;
+	byte	mask;
+	int	timeout;
+	/* state registers */
+	word	saved_bank;
+	word	saved_pointer;
+
+
+
+	PRINTK3("%s: SMC interrupt started \n", dev->name);
+
+	if (dev == NULL) {
+		printk(KERN_WARNING "%s: irq %d for unknown device.\n",
+			dev->name, irq);
+		return;
+	}
+
+	/* will Linux let this happen ??  If not, this costs some speed
+	if ( dev->interrupt ) {
+		printk(KERN_WARNING "%s: interrupt inside interrupt.\n",
+			dev->name);
+		return;
+	}
+
+	dev->interrupt = 1; */
+
+#if defined(CONFIG_M5249C3)
+	/* Clear interrupts for GPIO6 */
+	*((volatile unsigned long *) (MCF_MBAR2+MCFSIM2_GPIOINTCLEAR)) =
+		0x00000040;
+#endif
+#if defined(CONFIG_GILBARCONAP)
+	*((volatile unsigned long *) (MCF_MBAR+MCFSIM_ICR1)) =
+		(*((volatile unsigned long *) (MCF_MBAR+MCFSIM_ICR1)) &
+		0x77777777) | 0x00080000;
+#endif
+
+	saved_bank = inw( ioaddr + BANK_SELECT );
+
+	SMC_SELECT_BANK(2);
+	saved_pointer = inw( ioaddr + PTR_REG );
+
+	/* read the interrupt status register */
+	mask = inb( ioaddr + IM_REG );
+
+	/* disable all interrupts */
+#if defined(CONFIG_SMC16BITONLY)
+	outw( 0, ioaddr + INT_REG );
+#else
+	outb( 0, ioaddr + IM_REG );
+#endif
+
+
+	/* set a timeout value, so I don't stay here forever */
+	timeout = 4;
+
+	PRINTK2(KERN_WARNING "%s: MASK IS %x \n", dev->name, mask);
+	do {
+		/* read the status flag, and mask it */
+		status = inb( ioaddr + INT_REG ) & mask;
+		if (!status )
+			break;
+
+		PRINTK3(KERN_WARNING "%s: Handling interrupt status %x \n",
+			dev->name, status);
+
+		if (status & IM_RCV_INT) {
+			/* Got a packet(s). */
+			PRINTK2(KERN_WARNING
+				"%s: Receive Interrupt\n", dev->name);
+			smc_rcv(dev);
+		} else if (status & IM_TX_INT ) {
+			PRINTK2(KERN_WARNING "%s: TX ERROR handled\n",
+				dev->name);
+			smc_tx(dev);
+			// Acknowledge the interrupt
+#if defined(CONFIG_SMC16BITONLY)
+			// MASK is 0 here, so 16bit write is safe
+			outw(IM_TX_INT, ioaddr + INT_REG );
+#else
+			outb(IM_TX_INT, ioaddr + INT_REG );
+#endif
+		} else if (status & IM_TX_EMPTY_INT ) {
+			/* update stats */
+			SMC_SELECT_BANK( 0 );
+			card_stats = inw( ioaddr + COUNTER_REG );
+			/* single collisions */
+			lp->stats.collisions += card_stats & 0xF;
+			card_stats >>= 4;
+			/* multiple collisions */
+			lp->stats.collisions += card_stats & 0xF;
+
+			/* these are for when linux supports these statistics */
+#if 0
+			card_stats >>= 4;
+			/* deferred */
+			card_stats >>= 4;
+			/* excess deferred */
+#endif
+			SMC_SELECT_BANK( 2 );
+			PRINTK2(KERN_WARNING "%s: TX_BUFFER_EMPTY handled\n",
+				dev->name);
+			// Acknowledge the interrupt
+#if defined(CONFIG_SMC16BITONLY)
+			// MASK is 0 here, so 16bit write is safe
+			outw( IM_TX_EMPTY_INT, ioaddr + INT_REG );
+#else
+			outb( IM_TX_EMPTY_INT, ioaddr + INT_REG );
+#endif
+			mask &= ~IM_TX_EMPTY_INT;
+			lp->stats.tx_packets += lp->packets_waiting;
+			lp->packets_waiting = 0;
+
+		} else if (status & IM_ALLOC_INT ) {
+			PRINTK2(KERN_DEBUG "%s: Allocation interrupt \n",
+				dev->name);
+			/* clear this interrupt so it doesn't happen again */
+			mask &= ~IM_ALLOC_INT;
+
+			smc_hardware_send_packet( dev );
+
+			/* enable xmit interrupts based on this */
+			mask |= ( IM_TX_EMPTY_INT | IM_TX_INT );
+
+			/* and let the card send more packets to me */
+			netif_wake_queue(dev);
+
+			PRINTK2("%s: Handoff done successfully.\n",
+				dev->name);
+		} else if (status & IM_RX_OVRN_INT ) {
+			lp->stats.rx_errors++;
+			lp->stats.rx_fifo_errors++;
+			// Acknowledge the interrupt
+#if defined(CONFIG_SMC16BITONLY)
+			// MASK is 0 here, so 16bit write is safe
+			outw( IM_RX_OVRN_INT, ioaddr + INT_REG );
+#else
+			outb( IM_RX_OVRN_INT, ioaddr + INT_REG );
+#endif
+		} else if (status & IM_EPH_INT ) {
+			PRINTK("%s: UNSUPPORTED: EPH INTERRUPT \n",
+				dev->name);
+		} else if (status & IM_MDINT ) {
+			smc_phy_interrupt(dev);
+			// Acknowledge the interrupt
+#if defined(CONFIG_SMC16BITONLY)
+			// MASK is 0 here, so 16bit write is safe
+			outw(IM_MDINT, ioaddr + INT_REG );
+#else
+			outb(IM_MDINT, ioaddr + INT_REG );
+#endif
+		} else if (status & IM_ERCV_INT ) {
+			PRINTK("%s: UNSUPPORTED: ERCV INTERRUPT \n",
+				dev->name);
+			// Acknowledge the interrupt
+#if defined(CONFIG_SMC16BITONLY)
+			// MASK is 0 here, so 16bit write is safe
+			outw( IM_ERCV_INT, ioaddr + INT_REG );
+#else
+			outb( IM_ERCV_INT, ioaddr + INT_REG );
+#endif
+		}
+	} while ( timeout -- );
+
+
+	/* restore register states */
+
+	SMC_SELECT_BANK( 2 );
+
+#if defined(CONFIG_SMC16BITONLY)
+	outw( mask << 8, ioaddr + INT_REG );
+#else
+	outb( mask, ioaddr + IM_REG );
+#endif
+
+	PRINTK3( KERN_WARNING "%s: MASK is now %x \n", dev->name, mask);
+	outw( saved_pointer, ioaddr + PTR_REG );
+
+	SMC_SELECT_BANK( saved_bank );
+
+	//dev->interrupt = 0;
+	PRINTK3("%s: Interrupt done\n", dev->name);
+	return;
+}
+
+/*-------------------------------------------------------------
+ .
+ . smc_rcv -  receive a packet from the card
+ .
+ . There is ( at least ) a packet waiting to be read from
+ . chip-memory.
+ .
+ . o Read the status
+ . o If an error, record it
+ . o otherwise, read in the packet
+ --------------------------------------------------------------
+*/
+static void smc_rcv(struct net_device *dev)
+{
+	struct smc_local *lp = (struct smc_local *)dev->priv;
+	unsigned int  ioaddr = dev->base_addr;
+	int 	packet_number;
+	word	status;
+	word	packet_length;
+
+	PRINTK3("%s:smc_rcv\n", dev->name);
+
+	/* assume bank 2 */
+
+	packet_number = inw( ioaddr + RXFIFO_REG );
+
+	if ( packet_number & RXFIFO_REMPTY ) {
+
+		/* we got called , but nothing was on the FIFO */
+		PRINTK("%s: WARNING: smc_rcv with nothing on FIFO. \n",
+			dev->name);
+		/* don't need to restore anything */
+		return;
+	}
+
+	/*  start reading from the start of the packet */
+	outw( PTR_READ | PTR_RCV | PTR_AUTOINC, ioaddr + PTR_REG );
+
+	/* First two words are status and packet_length */
+	status 		= inw( ioaddr + DATA_REG );
+	packet_length 	= inw( ioaddr + DATA_REG );
+
+	packet_length &= 0x07ff;  /* mask off top bits */
+
+	PRINTK2("RCV: STATUS %4x LENGTH %4x\n", status, packet_length );
+
+	if ( !(status & RS_ERRORS ) ){
+		/* do stuff to make a new packet */
+		struct sk_buff  * skb;
+		byte		* data;
+
+		/* set multicast stats */
+		if ( status & RS_MULTICAST )
+			lp->stats.multicast++;
+
+		// Allocate enough memory for entire receive frame, to be safe
+		skb = dev_alloc_skb( packet_length );
+
+		/* Adjust for having already read the first two words */
+		packet_length -= 4;
+
+		if ( skb == NULL ) {
+			printk(KERN_NOTICE "%s: Low memory, packet dropped.\n",
+				dev->name);
+			lp->stats.rx_dropped++;
+			goto done;
+		}
+
+		/*
+		 ! This should work without alignment, but it could be
+		 ! in the worse case
+		*/
+		/* TODO: Should I use 32bit alignment here ? */
+		skb_reserve( skb, 2 );   /* 16 bit alignment */
+
+		skb->dev = dev;
+
+		/* The odd byte flag in the status is never set for
+		 * LAN91C111 Rev A, so we'll ignore it and use the
+		 * odd byte flag in the control byte to fix the packet
+		 * length later. */
+		data = skb_put(skb, packet_length);
+
+#ifdef USE_32_BIT
+		PRINTK3(" Reading %d dwords (and %d bytes) \n",
+			packet_length >> 2, packet_length & 3 );
+		/* QUESTION:  Like in the TX routine, do I want
+		   to send the DWORDs or the bytes first, or some
+		   mixture.  A mixture might improve already slow PIO
+		   performance  */
+		insl(ioaddr + DATA_REG , data, packet_length >> 2 );
+		/* read the left over bytes */
+		insb( ioaddr + DATA_REG, data + (packet_length & 0xFFFFFC),
+			packet_length & 0x3  );
+#else
+		PRINTK3(" Reading %d words and %d byte(s) \n",
+			(packet_length >> 1 ), packet_length & 1 );
+		insw(ioaddr + DATA_REG , data, packet_length >> 1);
+
+#endif // USE_32_BIT
+
+		/*
+		 * For broken Revision A LAN91c111 leave the trailing
+		 * data in place, let IP layer clear it out.
+		 */
+		if ((9 != lp->ChipID) && (0 != lp->ChipRev)) {
+			/* Trim the control byte and odd byte if needed */
+			packet_length--;
+			if (!(data[packet_length] & 0x20))
+				packet_length--;
+			skb_trim(skb, packet_length);
+		}
+
+#if	SMC_DEBUG > 2
+		printk("Receiving Packet\n");
+		print_packet( data, packet_length );
+#endif
+
+		skb->protocol = eth_type_trans(skb, dev );
+		netif_rx(skb);
+		lp->stats.rx_packets++;
+	} else {
+		/* error ... */
+		lp->stats.rx_errors++;
+
+		if ( status & RS_ALGNERR )  lp->stats.rx_frame_errors++;
+		if ( status & (RS_TOOSHORT | RS_TOOLONG ) )
+			lp->stats.rx_length_errors++;
+		if ( status & RS_BADCRC)	lp->stats.rx_crc_errors++;
+	}
+
+	while ( inw( ioaddr + MMU_CMD_REG ) & MC_BUSY )
+		udelay(1); // Wait until not busy
+done:
+	/*  error or good, tell the card to get rid of this packet */
+	outw( MC_RELEASE, ioaddr + MMU_CMD_REG );
+
+
+	return;
+}
+
+
+/*************************************************************************
+ . smc_tx
+ .
+ . Purpose:  Handle a transmit error message.   This will only be called
+ .   when an error, because of the AUTO_RELEASE mode.
+ .
+ . Algorithm:
+ .	Save pointer and packet no
+ .	Get the packet no from the top of the queue
+ .	check if it's valid ( if not, is this an error??? )
+ .	read the status word
+ .	record the error
+ .	( resend?  Not really, since we don't want old packets around )
+ .	Restore saved values
+ ************************************************************************/
+static void smc_tx( struct net_device * dev )
+{
+	unsigned int  ioaddr = dev->base_addr;
+	struct smc_local *lp = (struct smc_local *)dev->priv;
+	byte saved_packet;
+	byte packet_no;
+	word tx_status;
+
+
+	PRINTK3("%s:smc_tx\n", dev->name);
+
+	/* assume bank 2  */
+
+	saved_packet = inb( ioaddr + PN_REG );
+	packet_no = inw( ioaddr + RXFIFO_REG );
+	packet_no &= 0x7F;
+
+	/* If the TX FIFO is empty then nothing to do */
+	if ( packet_no & TXFIFO_TEMPTY )
+		return;
+
+	/* select this as the packet to read from */
+#if defined(CONFIG_SMC16BITONLY)
+	outw( packet_no, ioaddr + PN_REG );
+#else
+	outb( packet_no, ioaddr + PN_REG );
+#endif
+
+	/* read the first word (status word) from this packet */
+	outw( PTR_AUTOINC | PTR_READ, ioaddr + PTR_REG );
+
+	tx_status = inw( ioaddr + DATA_REG );
+	PRINTK3("%s: TX DONE STATUS: %4x \n", dev->name, tx_status);
+
+	lp->stats.tx_errors++;
+	if ( tx_status & TS_LOSTCAR ) lp->stats.tx_carrier_errors++;
+	if ( tx_status & TS_LATCOL  ) {
+		printk(KERN_DEBUG
+			"%s: Late collision occurred on last xmit.\n",
+			dev->name);
+		lp->stats.tx_window_errors++;
+#ifdef CONFIG_SYSCTL
+		lp->ctl_forcol = 0; // Reset forced collsion
+#endif
+	}
+#if 0
+	if ( tx_status & TS_16COL ) { ... }
+#endif
+
+	if ( tx_status & TS_SUCCESS ) {
+		printk("%s: Successful packet caused interrupt \n", dev->name);
+	}
+	/* re-enable transmit */
+	SMC_SELECT_BANK( 0 );
+	outw( inw( ioaddr + TCR_REG ) | TCR_ENABLE, ioaddr + TCR_REG );
+
+	/* kill the packet */
+	SMC_SELECT_BANK( 2 );
+	outw( MC_FREEPKT, ioaddr + MMU_CMD_REG );
+
+	/* one less packet waiting for me */
+	lp->packets_waiting--;
+
+	/* Don't change Packet Number Reg until busy bit is cleared */
+	/* Per LAN91C111 Spec, Page 50 */
+	while ( inw( ioaddr + MMU_CMD_REG ) & MC_BUSY );
+
+#if defined(CONFIG_SMC16BITONLY)
+	outw( saved_packet, ioaddr + PN_REG );
+#else
+	outb( saved_packet, ioaddr + PN_REG );
+#endif
+	return;
+}
+
+
+/*----------------------------------------------------
+ . smc_close
+ .
+ . this makes the board clean up everything that it can
+ . and not talk to the outside world.   Caused by
+ . an 'ifconfig ethX down'
+ .
+ -----------------------------------------------------*/
+static int smc_close(struct net_device *dev)
+{
+	netif_stop_queue(dev);
+	//dev->start = 0;
+
+	PRINTK2("%s:smc_close\n", dev->name);
+
+#ifdef CONFIG_SYSCTL
+	smc_sysctl_unregister(dev);
+#endif /* CONFIG_SYSCTL */ 
+
+	/* clear everything */
+	smc_shutdown( dev->base_addr );
+
+	/* Update the statistics here. */
+#ifdef MODULE
+	MOD_DEC_USE_COUNT;
+#endif
+
+	return 0;
+}
+
+/*------------------------------------------------------------
+ . Get the current statistics.
+ . This may be called with the card open or closed.
+ .-------------------------------------------------------------*/
+static struct net_device_stats* smc_query_statistics(struct net_device *dev) {
+	struct smc_local *lp = (struct smc_local *)dev->priv;
+
+	PRINTK2("%s:smc_query_statistics\n", dev->name);
+
+	return &lp->stats;
+}
+
+/*-----------------------------------------------------------
+ . smc_set_multicast_list
+ .
+ . This routine will, depending on the values passed to it,
+ . either make it accept multicast packets, go into
+ . promiscuous mode ( for TCPDUMP and cousins ) or accept
+ . a select set of multicast packets
+*/
+static void smc_set_multicast_list(struct net_device *dev)
+{
+	unsigned int ioaddr = dev->base_addr;
+
+	PRINTK2("%s:smc_set_multicast_list\n", dev->name);
+
+	SMC_SELECT_BANK(0);
+	if ( dev->flags & IFF_PROMISC )
+		{
+		PRINTK2("%s:smc_set_multicast_list:RCR_PRMS\n", dev->name);
+		outw( inw(ioaddr + RCR_REG ) | RCR_PRMS, ioaddr + RCR_REG );
+		}
+
+/* BUG?  I never disable promiscuous mode if multicasting was turned on.
+   Now, I turn off promiscuous mode, but I don't do anything to multicasting
+   when promiscuous mode is turned on.
+*/
+
+	/* Here, I am setting this to accept all multicast packets.
+	   I don't need to zero the multicast table, because the flag is
+	   checked before the table is
+	*/
+	else if (dev->flags & IFF_ALLMULTI)
+		{
+		outw( inw(ioaddr + RCR_REG ) | RCR_ALMUL, ioaddr + RCR_REG );
+		PRINTK2("%s:smc_set_multicast_list:RCR_ALMUL\n", dev->name);
+		}
+
+	/* We just get all multicast packets even if we only want them
+	 . from one source.  This will be changed at some future
+	 . point. */
+	else if (dev->mc_count )  {
+		/* support hardware multicasting */
+
+		/* be sure I get rid of flags I might have set */
+		outw( inw( ioaddr + RCR_REG ) & ~(RCR_PRMS | RCR_ALMUL),
+			ioaddr + RCR_REG );
+		/* NOTE: this has to set the bank, so make sure it is the
+		   last thing called.  The bank is set to zero at the top */
+		smc_setmulticast( ioaddr, dev->mc_count, dev->mc_list );
+	} else  {
+		PRINTK2("%s:smc_set_multicast_list:~(RCR_PRMS|RCR_ALMUL)\n",
+			dev->name);
+		outw( inw( ioaddr + RCR_REG ) & ~(RCR_PRMS | RCR_ALMUL),
+			ioaddr + RCR_REG );
+
+		/*
+		  since I'm disabling all multicast entirely, I need to
+		  clear the multicast list
+		*/
+		SMC_SELECT_BANK( 3 );
+		outw( 0, ioaddr + MCAST_REG1 );
+		outw( 0, ioaddr + MCAST_REG2 );
+		outw( 0, ioaddr + MCAST_REG3 );
+		outw( 0, ioaddr + MCAST_REG4 );
+	}
+}
+
+#ifdef MODULE
+
+static struct net_device devSMC91111;
+int io = 0;
+int irq = 0;
+int nowait = 0;
+
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(nowait, "i");
+
+/*------------------------------------------------------------
+ . Module initialization function
+ .-------------------------------------------------------------*/
+int init_module(void)
+{
+	int result;
+
+	PRINTK2("CARDNAME:init_module\n");
+	if (io == 0)
+		printk(KERN_WARNING
+		CARDNAME": You shouldn't use auto-probing with insmod!\n" );
+
+	/* copy the parameters from insmod into the device structure */
+	devSMC91111.base_addr	= io;
+	devSMC91111.irq		= irq;
+	devSMC91111.dma		= nowait; // Use DMA field for nowait		
+	devSMC91111.init	= smc_init;/* Kernel 2.4 Changes - Pramod */
+	if ((result = register_netdev(&devSMC91111)) != 0)
+		return result;
+	
+	return 0;
+}
+
+/*------------------------------------------------------------
+ . Cleanup when module is removed with rmmod
+ .-------------------------------------------------------------*/
+void cleanup_module(void)
+{
+	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+	unregister_netdev(&devSMC91111);
+
+	free_irq(devSMC91111.irq, &devSMC91111);
+	release_region(devSMC91111.base_addr, SMC_IO_EXTENT);
+
+	if (devSMC91111.priv)
+		kfree(devSMC91111.priv); /* Kernel 2.4 Changes - Pramod */
+}
+
+#endif /* MODULE */
+
+
+#ifdef CONFIG_SYSCTL
+
+
+/*------------------------------------------------------------
+ . Modify a bit in the LAN91C111 register set
+ .-------------------------------------------------------------*/
+static word smc_modify_regbit(int bank, unsigned int ioaddr, int reg,
+	unsigned int bit, int val)
+{
+	word regval;
+
+	SMC_SELECT_BANK( bank );
+
+	regval = inw( ioaddr+reg );
+	if (val)
+		regval |= bit;
+	else
+		regval &= ~bit;
+
+	outw( regval, ioaddr );
+	return(regval);
+}
+
+
+/*------------------------------------------------------------
+ . Retrieve a bit in the LAN91C111 register set
+ .-------------------------------------------------------------*/
+static int smc_get_regbit(int bank, unsigned int ioaddr, int reg, unsigned int bit)
+{
+	SMC_SELECT_BANK( bank );
+	if ( inw( ioaddr+reg ) & bit)
+		return(1);
+	else
+		return(0);
+}
+
+
+/*------------------------------------------------------------
+ . Modify a LAN91C111 register (word access only)
+ .-------------------------------------------------------------*/
+static void smc_modify_reg(int bank, unsigned int ioaddr, int reg, word val)
+{
+	SMC_SELECT_BANK( bank );
+	outw( val, ioaddr+reg );
+}
+
+
+/*------------------------------------------------------------
+ . Retrieve a LAN91C111 register (word access only)
+ .-------------------------------------------------------------*/
+static int smc_get_reg(int bank, unsigned int ioaddr, int reg)
+{
+	SMC_SELECT_BANK( bank );
+	return(inw( ioaddr+reg ));
+}
+
+
+static const char smc_info_string[] =
+"\n"
+"info           Provides this information blurb\n"
+"swver          Prints the software version information of this driver\n"
+"autoneg        Auto-negotiate Mode = 1\n"
+"rspeed         Requested Speed, 100=100Mbps, 10=10Mpbs\n"
+"rfduplx        Requested Full Duplex Operation\n"
+"aspeed         Actual Speed, 100=100Mbps, 10=10Mpbs\n"
+"afduplx        Actual Full Duplex Operation\n"
+"lnkfail        PHY Link Failure when 1\n"
+"miiop          External MII when 1, Internal PHY when 0\n"
+"swfdup         Switched Full Duplex Mode (allowed only in MII operation)\n"
+"ephloop        EPH Block Loopback\n"
+"forcol         Force a collision\n"
+"filtcar        Filter leading edge of carrier sense for 12 bit times\n"
+"freemem        Free buffer memory in bytes\n"
+"totmem         Total buffer memory in bytes\n"
+"leda           Output of LED-A (green)\n"
+"ledb           Output of LED-B (yellow)\n"
+"chiprev        Revision ID of the LAN91C111 chip\n"
+"";
+
+/*------------------------------------------------------------
+ . Sysctl handler for all integer parameters
+ .-------------------------------------------------------------*/
+static int smc_sysctl_handler(ctl_table *ctl, int write, struct file * filp,
+				void *buffer, size_t *lenp)
+{
+	struct net_device *dev = (struct net_device*)ctl->extra1;
+	struct smc_local *lp = (struct smc_local *)ctl->extra2;
+	unsigned int ioaddr = dev->base_addr;
+	int *valp = ctl->data;
+	int val;
+	int ret;
+
+	// Update parameters from the real registers
+	switch (ctl->ctl_name)
+	{
+	case CTL_SMC_FORCOL:
+		*valp = smc_get_regbit(0, ioaddr, TCR_REG, TCR_FORCOL);
+		break;
+
+	case CTL_SMC_FREEMEM:
+		*valp = ( (word)smc_get_reg(0, ioaddr, MIR_REG) >> 8 )
+			* LAN91C111_MEMORY_MULTIPLIER;
+		break;
+
+
+	case CTL_SMC_TOTMEM:
+		*valp = ( smc_get_reg(0, ioaddr, MIR_REG) & (word)0x00ff )
+			* LAN91C111_MEMORY_MULTIPLIER;
+		break;
+
+	case CTL_SMC_CHIPREV:
+		*valp = smc_get_reg(3, ioaddr, REV_REG);
+		break;
+
+	case CTL_SMC_AFDUPLX:
+		*valp = (lp->lastPhy18 & PHY_INT_DPLXDET) ? 1 : 0;
+		break;
+
+	case CTL_SMC_ASPEED:
+		*valp = (lp->lastPhy18 & PHY_INT_SPDDET) ? 100 : 10;
+		break;
+
+	case CTL_SMC_LNKFAIL:
+		*valp = (lp->lastPhy18 & PHY_INT_LNKFAIL) ? 1 : 0;
+		break;
+
+	case CTL_SMC_LEDA:
+		*valp = (lp->rpc_cur_mode >> RPC_LSXA_SHFT) & (word)0x0007;
+		break;
+
+	case CTL_SMC_LEDB:
+		*valp = (lp->rpc_cur_mode >> RPC_LSXB_SHFT) & (word)0x0007;
+		break;
+
+	case CTL_SMC_MIIOP:
+		*valp = smc_get_regbit(1, ioaddr, CONFIG_REG, CONFIG_EXT_PHY);
+		break;
+
+#ifdef SMC_DEBUG
+	case CTL_SMC_REG_BSR:	// Bank Select
+		*valp = smc_get_reg(0, ioaddr, BSR_REG);
+		break;
+
+	case CTL_SMC_REG_TCR:	// Transmit Control
+		*valp = smc_get_reg(0, ioaddr, TCR_REG);
+		break;
+
+	case CTL_SMC_REG_ESR:	// EPH Status
+		*valp = smc_get_reg(0, ioaddr, EPH_STATUS_REG);
+		break;
+
+	case CTL_SMC_REG_RCR:	// Receive Control
+		*valp = smc_get_reg(0, ioaddr, RCR_REG);
+		break;
+
+	case CTL_SMC_REG_CTRR:	// Counter
+		*valp = smc_get_reg(0, ioaddr, COUNTER_REG);
+		break;
+
+	case CTL_SMC_REG_MIR:	// Memory Information
+		*valp = smc_get_reg(0, ioaddr, MIR_REG);
+		break;
+
+	case CTL_SMC_REG_RPCR:	// Receive/Phy Control
+		*valp = smc_get_reg(0, ioaddr, RPC_REG);
+		break;
+
+	case CTL_SMC_REG_CFGR:	// Configuration
+		*valp = smc_get_reg(1, ioaddr, CONFIG_REG);
+		break;
+
+	case CTL_SMC_REG_BAR:	// Base Address
+		*valp = smc_get_reg(1, ioaddr, BASE_REG);
+		break;
+
+	case CTL_SMC_REG_IAR0:	// Individual Address
+		*valp = smc_get_reg(1, ioaddr, ADDR0_REG);
+		break;
+
+	case CTL_SMC_REG_IAR1:	// Individual Address
+		*valp = smc_get_reg(1, ioaddr, ADDR1_REG);
+		break;
+
+	case CTL_SMC_REG_IAR2:	// Individual Address
+		*valp = smc_get_reg(1, ioaddr, ADDR2_REG);
+		break;
+
+	case CTL_SMC_REG_GPR:	// General Purpose
+		*valp = smc_get_reg(1, ioaddr, GP_REG);
+		break;
+
+	case CTL_SMC_REG_CTLR:	// Control
+		*valp = smc_get_reg(1, ioaddr, CTL_REG);
+		break;
+
+	case CTL_SMC_REG_MCR:	// MMU Command
+		*valp = smc_get_reg(2, ioaddr, MMU_CMD_REG);
+		break;
+
+	case CTL_SMC_REG_PNR:	// Packet Number
+		*valp = smc_get_reg(2, ioaddr, PN_REG);
+		break;
+
+	case CTL_SMC_REG_FPR:	// Allocation Result/FIFO Ports
+		*valp = smc_get_reg(2, ioaddr, RXFIFO_REG);
+		break;
+
+	case CTL_SMC_REG_PTR:	// Pointer
+		*valp = smc_get_reg(2, ioaddr, PTR_REG);
+		break;
+
+	case CTL_SMC_REG_DR:	// Data 
+		*valp = smc_get_reg(2, ioaddr, DATA_REG);
+		break;
+
+	case CTL_SMC_REG_ISR:	// Interrupt Status/Mask
+		*valp = smc_get_reg(2, ioaddr, INT_REG);
+		break;
+
+	case CTL_SMC_REG_MTR1:	// Multicast Table Entry 1
+		*valp = smc_get_reg(3, ioaddr, MCAST_REG1);
+		break;
+
+	case CTL_SMC_REG_MTR2:	// Multicast Table Entry 2
+		*valp = smc_get_reg(3, ioaddr, MCAST_REG2);
+		break;
+
+	case CTL_SMC_REG_MTR3:	// Multicast Table Entry 3
+		*valp = smc_get_reg(3, ioaddr, MCAST_REG3);
+		break;
+
+	case CTL_SMC_REG_MTR4:	// Multicast Table Entry 4
+		*valp = smc_get_reg(3, ioaddr, MCAST_REG4);
+		break;
+
+	case CTL_SMC_REG_MIIR:	// Management Interface
+		*valp = smc_get_reg(3, ioaddr, MII_REG);
+		break;
+
+	case CTL_SMC_REG_REVR:	// Revision
+		*valp = smc_get_reg(3, ioaddr, REV_REG);
+		break;
+
+	case CTL_SMC_REG_ERCVR:	// Early RCV
+		*valp = smc_get_reg(3, ioaddr, ERCV_REG);
+		break;
+
+	case CTL_SMC_REG_EXTR:	// External
+		*valp = smc_get_reg(7, ioaddr, EXT_REG);
+		break;
+
+	case CTL_SMC_PHY_CTRL:
+		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,
+			PHY_CNTL_REG);
+		break;
+
+	case CTL_SMC_PHY_STAT:
+		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,
+			PHY_STAT_REG);
+		break;
+
+	case CTL_SMC_PHY_ID1:
+		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,
+			PHY_ID1_REG);
+		break;
+
+	case CTL_SMC_PHY_ID2:
+		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,
+			PHY_ID2_REG);
+		break;
+
+	case CTL_SMC_PHY_ADC:
+		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,
+			PHY_AD_REG);
+		break;
+
+	case CTL_SMC_PHY_REMC:
+		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,
+			PHY_RMT_REG);
+		break;
+
+	case CTL_SMC_PHY_CFG1:
+		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,
+			PHY_CFG1_REG);
+		break;
+
+	case CTL_SMC_PHY_CFG2:
+		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,
+			PHY_CFG2_REG);
+		break;
+
+	case CTL_SMC_PHY_INT:
+		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,
+			PHY_INT_REG);
+		break;
+
+	case CTL_SMC_PHY_MASK:
+		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,
+			PHY_MASK_REG);
+		break;
+
+#endif // SMC_DEBUG
+
+	default:
+		// Just ignore unsupported parameters
+		break;
+	}
+
+	// Save old state
+	val = *valp;
+
+	// Perform the generic integer operation	
+	if ((ret = proc_dointvec(ctl, write, filp, buffer, lenp)) != 0)
+		return(ret);
+
+	// Write changes out to the registers
+	if (write && *valp != val) {
+
+		val = *valp;
+		switch (ctl->ctl_name) {
+
+		case CTL_SMC_SWFDUP:
+			if (val)
+				lp->tcr_cur_mode |= TCR_SWFDUP;
+			else
+				lp->tcr_cur_mode &= ~TCR_SWFDUP;
+
+			smc_modify_regbit(0, ioaddr, TCR_REG, TCR_SWFDUP, val);
+			break;
+
+		case CTL_SMC_EPHLOOP:
+			if (val)
+				lp->tcr_cur_mode |= TCR_EPH_LOOP;
+			else
+				lp->tcr_cur_mode &= ~TCR_EPH_LOOP;
+
+			smc_modify_regbit(0, ioaddr, TCR_REG, TCR_EPH_LOOP, val);
+			break;
+
+		case CTL_SMC_FORCOL:
+			if (val)
+				lp->tcr_cur_mode |= TCR_FORCOL;
+			else
+				lp->tcr_cur_mode &= ~TCR_FORCOL;
+
+			// Update the EPH block
+			smc_modify_regbit(0, ioaddr, TCR_REG, TCR_FORCOL, val);
+			break;
+
+		case CTL_SMC_FILTCAR:
+			if (val)
+				lp->rcr_cur_mode |= RCR_FILT_CAR;
+			else
+				lp->rcr_cur_mode &= ~RCR_FILT_CAR;
+
+			// Update the EPH block
+			smc_modify_regbit(0, ioaddr, RCR_REG, RCR_FILT_CAR, val);
+			break;
+
+		case CTL_SMC_RFDUPLX:
+			// Disallow changes if in auto-negotiation mode
+			if (lp->ctl_autoneg)
+				break;
+
+			if (val)
+				{
+				lp->rpc_cur_mode |= RPC_DPLX;
+				}
+			else
+				{
+				lp->rpc_cur_mode &= ~RPC_DPLX;
+				}
+
+			// Reconfigure the PHY
+			smc_phy_configure(dev);
+
+			break;
+
+		case CTL_SMC_RSPEED:
+			// Disallow changes if in auto-negotiation mode
+			if (lp->ctl_autoneg)
+				break;
+
+			if (val > 10)
+				lp->rpc_cur_mode |= RPC_SPEED;
+			else
+				lp->rpc_cur_mode &= ~RPC_SPEED;
+
+			// Reconfigure the PHY
+			smc_phy_configure(dev);
+
+			break;
+
+		case CTL_SMC_AUTONEG:
+			if (val)
+				lp->rpc_cur_mode |= RPC_ANEG;
+			else
+				lp->rpc_cur_mode &= ~RPC_ANEG;
+
+			// Reconfigure the PHY
+			smc_phy_configure(dev);
+
+			break;
+
+		case CTL_SMC_LEDA:
+			val &= 0x07; // Restrict to 3 ls bits
+			lp->rpc_cur_mode &= ~(word)(0x07<<RPC_LSXA_SHFT);
+			lp->rpc_cur_mode |= (word)(val<<RPC_LSXA_SHFT);
+
+			// Update the Internal PHY block
+			smc_modify_reg(0, ioaddr, RPC_REG, lp->rpc_cur_mode);
+			break;
+
+		case CTL_SMC_LEDB:
+			val &= 0x07; // Restrict to 3 ls bits
+			lp->rpc_cur_mode &= ~(word)(0x07<<RPC_LSXB_SHFT);
+			lp->rpc_cur_mode |= (word)(val<<RPC_LSXB_SHFT);
+
+			// Update the Internal PHY block
+			smc_modify_reg(0, ioaddr, RPC_REG, lp->rpc_cur_mode);
+			break;
+
+		case CTL_SMC_MIIOP:
+			// Update the Internal PHY block
+			smc_modify_regbit(1, ioaddr, CONFIG_REG,
+				CONFIG_EXT_PHY, val);
+			break;
+
+#ifdef SMC_DEBUG
+		case CTL_SMC_REG_BSR:	// Bank Select
+			smc_modify_reg(0, ioaddr, BSR_REG, val);
+			break;
+
+		case CTL_SMC_REG_TCR:	// Transmit Control
+			smc_modify_reg(0, ioaddr, TCR_REG, val);
+			break;
+
+		case CTL_SMC_REG_ESR:	// EPH Status
+			smc_modify_reg(0, ioaddr, EPH_STATUS_REG, val);
+			break;
+
+		case CTL_SMC_REG_RCR:	// Receive Control
+			smc_modify_reg(0, ioaddr, RCR_REG, val);
+			break;
+
+		case CTL_SMC_REG_CTRR:	// Counter
+			smc_modify_reg(0, ioaddr, COUNTER_REG, val);
+			break;
+
+		case CTL_SMC_REG_MIR:	// Memory Information
+			smc_modify_reg(0, ioaddr, MIR_REG, val);
+			break;
+
+		case CTL_SMC_REG_RPCR:	// Receive/Phy Control
+			smc_modify_reg(0, ioaddr, RPC_REG, val);
+			break;
+
+		case CTL_SMC_REG_CFGR:	// Configuration
+			smc_modify_reg(1, ioaddr, CONFIG_REG, val);
+			break;
+
+		case CTL_SMC_REG_BAR:	// Base Address
+			smc_modify_reg(1, ioaddr, BASE_REG, val);
+			break;
+
+		case CTL_SMC_REG_IAR0:	// Individual Address
+			smc_modify_reg(1, ioaddr, ADDR0_REG, val);
+			break;
+
+		case CTL_SMC_REG_IAR1:	// Individual Address
+			smc_modify_reg(1, ioaddr, ADDR1_REG, val);
+			break;
+
+		case CTL_SMC_REG_IAR2:	// Individual Address
+			smc_modify_reg(1, ioaddr, ADDR2_REG, val);
+			break;
+
+		case CTL_SMC_REG_GPR:	// General Purpose
+			smc_modify_reg(1, ioaddr, GP_REG, val);
+			break;
+
+		case CTL_SMC_REG_CTLR:	// Control
+			smc_modify_reg(1, ioaddr, CTL_REG, val);
+			break;
+
+		case CTL_SMC_REG_MCR:	// MMU Command
+			smc_modify_reg(2, ioaddr, MMU_CMD_REG, val);
+			break;
+
+		case CTL_SMC_REG_PNR:	// Packet Number
+			smc_modify_reg(2, ioaddr, PN_REG, val);
+			break;
+
+		case CTL_SMC_REG_FPR:	// Allocation Result/FIFO Ports
+			smc_modify_reg(2, ioaddr, RXFIFO_REG, val);
+			break;
+
+		case CTL_SMC_REG_PTR:	// Pointer
+			smc_modify_reg(2, ioaddr, PTR_REG, val);
+			break;
+
+		case CTL_SMC_REG_DR:	// Data 
+			smc_modify_reg(2, ioaddr, DATA_REG, val);
+			break;
+
+		case CTL_SMC_REG_ISR:	// Interrupt Status/Mask
+			smc_modify_reg(2, ioaddr, INT_REG, val);
+			break;
+
+		case CTL_SMC_REG_MTR1:	// Multicast Table Entry 1
+			smc_modify_reg(3, ioaddr, MCAST_REG1, val);
+			break;
+
+		case CTL_SMC_REG_MTR2:	// Multicast Table Entry 2
+			smc_modify_reg(3, ioaddr, MCAST_REG2, val);
+			break;
+
+		case CTL_SMC_REG_MTR3:	// Multicast Table Entry 3
+			smc_modify_reg(3, ioaddr, MCAST_REG3, val);
+			break;
+
+		case CTL_SMC_REG_MTR4:	// Multicast Table Entry 4
+			smc_modify_reg(3, ioaddr, MCAST_REG4, val);
+			break;
+
+		case CTL_SMC_REG_MIIR:	// Management Interface
+			smc_modify_reg(3, ioaddr, MII_REG, val);
+			break;
+
+		case CTL_SMC_REG_REVR:	// Revision
+			smc_modify_reg(3, ioaddr, REV_REG, val);
+			break;
+
+		case CTL_SMC_REG_ERCVR:	// Early RCV
+			smc_modify_reg(3, ioaddr, ERCV_REG, val);
+			break;
+
+		case CTL_SMC_REG_EXTR:	// External
+			smc_modify_reg(7, ioaddr, EXT_REG, val);
+			break;
+
+		case CTL_SMC_PHY_CTRL:
+			smc_write_phy_register(ioaddr, lp->phyaddr,
+				PHY_CNTL_REG, val);
+			break;
+
+		case CTL_SMC_PHY_STAT:
+			smc_write_phy_register(ioaddr, lp->phyaddr,
+				PHY_STAT_REG, val);
+			break;
+
+		case CTL_SMC_PHY_ID1:
+			smc_write_phy_register(ioaddr, lp->phyaddr,
+				PHY_ID1_REG, val);
+			break;
+
+		case CTL_SMC_PHY_ID2:
+			smc_write_phy_register(ioaddr, lp->phyaddr,
+				PHY_ID2_REG, val);
+			break;
+
+		case CTL_SMC_PHY_ADC:
+			smc_write_phy_register(ioaddr, lp->phyaddr,
+				PHY_AD_REG, val);
+			break;
+
+		case CTL_SMC_PHY_REMC:
+			smc_write_phy_register(ioaddr, lp->phyaddr,
+				PHY_RMT_REG, val);
+			break;
+
+		case CTL_SMC_PHY_CFG1:
+			smc_write_phy_register(ioaddr, lp->phyaddr,
+				PHY_CFG1_REG, val);
+			break;
+
+		case CTL_SMC_PHY_CFG2:
+			smc_write_phy_register(ioaddr, lp->phyaddr,
+				PHY_CFG2_REG, val);
+			break;
+
+		case CTL_SMC_PHY_INT:
+			smc_write_phy_register(ioaddr, lp->phyaddr,
+				PHY_INT_REG, val);
+			break;
+
+		case CTL_SMC_PHY_MASK:
+			smc_write_phy_register(ioaddr, lp->phyaddr,
+				PHY_MASK_REG, val);
+			break;
+
+#endif // SMC_DEBUG
+
+		default:
+			// Just ignore unsupported parameters
+			break;
+		} // end switch
+
+	} // end if
+
+        return ret;
+}
+
+/*------------------------------------------------------------
+ . Sysctl registration function for all parameters (files)
+ .-------------------------------------------------------------*/
+static void smc_sysctl_register(struct net_device *dev)
+{
+	struct smc_local *lp = (struct smc_local *)dev->priv;
+	static int ctl_name = CTL_SMC;
+	ctl_table* ct;
+	int i;
+
+	// Make sure the ctl_tables start out as all zeros
+	memset(lp->root_table, 0, sizeof lp->root_table);
+	memset(lp->eth_table, 0, sizeof lp->eth_table);
+	memset(lp->param_table, 0, sizeof lp->param_table);
+
+	// Initialize the root table
+	ct = lp->root_table;
+	ct->ctl_name = CTL_DEV;
+	ct->procname = "dev";
+	ct->maxlen = 0;
+	ct->mode = 0555;
+	ct->child = lp->eth_table;
+	// remaining fields are zero
+
+	// Initialize the ethX table (this device's table)
+	ct = lp->eth_table;
+	ct->ctl_name = ctl_name++; // Must be unique
+	ct->procname = dev->name;
+	ct->maxlen = 0;
+	ct->mode = 0555;
+	ct->child = lp->param_table;
+	// remaining fields are zero
+
+	// Initialize the parameter (files) table
+	// Make sure the last entry remains null
+	ct = lp->param_table;
+	for (i = 0; i < (CTL_SMC_LAST_ENTRY-1); ++i)
+		{
+		// Initialize fields common to all table entries
+		ct[i].proc_handler = smc_sysctl_handler;
+		ct[i].extra1 = (void*)dev; // Save our device pointer
+		ct[i].extra2 = (void*)lp;  // Save our smc_local data pointer
+		}
+
+	// INFO - this is our only string parameter
+	i = 0;
+	ct[i].proc_handler = proc_dostring; // use default handler
+	ct[i].ctl_name = CTL_SMC_INFO;
+	ct[i].procname = "info";
+	ct[i].data = (void*)smc_info_string;
+	ct[i].maxlen = sizeof smc_info_string;
+	ct[i].mode = 0444; // Read only
+
+	// SWVER
+	++i;
+	ct[i].proc_handler = proc_dostring; // use default handler
+	ct[i].ctl_name = CTL_SMC_SWVER;
+	ct[i].procname = "swver";
+	ct[i].data = (void*)version;
+	ct[i].maxlen = sizeof version;
+	ct[i].mode = 0444; // Read only
+
+	// SWFDUP
+	++i;
+	ct[i].ctl_name = CTL_SMC_SWFDUP;
+	ct[i].procname = "swfdup";
+	ct[i].data = (void*)&(lp->ctl_swfdup);
+	ct[i].maxlen = sizeof lp->ctl_swfdup;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// EPHLOOP
+	++i;
+	ct[i].ctl_name = CTL_SMC_EPHLOOP;
+	ct[i].procname = "ephloop";
+	ct[i].data = (void*)&(lp->ctl_ephloop);
+	ct[i].maxlen = sizeof lp->ctl_ephloop;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// MIIOP
+	++i;
+	ct[i].ctl_name = CTL_SMC_MIIOP;
+	ct[i].procname = "miiop";
+	ct[i].data = (void*)&(lp->ctl_miiop);
+	ct[i].maxlen = sizeof lp->ctl_miiop;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// AUTONEG
+	++i;
+	ct[i].ctl_name = CTL_SMC_AUTONEG;
+	ct[i].procname = "autoneg";
+	ct[i].data = (void*)&(lp->ctl_autoneg);
+	ct[i].maxlen = sizeof lp->ctl_autoneg;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// RFDUPLX
+	++i;
+	ct[i].ctl_name = CTL_SMC_RFDUPLX;
+	ct[i].procname = "rfduplx";
+	ct[i].data = (void*)&(lp->ctl_rfduplx);
+	ct[i].maxlen = sizeof lp->ctl_rfduplx;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// RSPEED
+	++i;
+	ct[i].ctl_name = CTL_SMC_RSPEED;
+	ct[i].procname = "rspeed";
+	ct[i].data = (void*)&(lp->ctl_rspeed);
+	ct[i].maxlen = sizeof lp->ctl_rspeed;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// AFDUPLX
+	++i;
+	ct[i].ctl_name = CTL_SMC_AFDUPLX;
+	ct[i].procname = "afduplx";
+	ct[i].data = (void*)&(lp->ctl_afduplx);
+	ct[i].maxlen = sizeof lp->ctl_afduplx;
+	ct[i].mode = 0444; // Read only
+
+	// ASPEED
+	++i;
+	ct[i].ctl_name = CTL_SMC_ASPEED;
+	ct[i].procname = "aspeed";
+	ct[i].data = (void*)&(lp->ctl_aspeed);
+	ct[i].maxlen = sizeof lp->ctl_aspeed;
+	ct[i].mode = 0444; // Read only
+
+	// LNKFAIL
+	++i;
+	ct[i].ctl_name = CTL_SMC_LNKFAIL;
+	ct[i].procname = "lnkfail";
+	ct[i].data = (void*)&(lp->ctl_lnkfail);
+	ct[i].maxlen = sizeof lp->ctl_lnkfail;
+	ct[i].mode = 0444; // Read only
+
+	// FORCOL
+	++i;
+	ct[i].ctl_name = CTL_SMC_FORCOL;
+	ct[i].procname = "forcol";
+	ct[i].data = (void*)&(lp->ctl_forcol);
+	ct[i].maxlen = sizeof lp->ctl_forcol;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// FILTCAR
+	++i;
+	ct[i].ctl_name = CTL_SMC_FILTCAR;
+	ct[i].procname = "filtcar";
+	ct[i].data = (void*)&(lp->ctl_filtcar);
+	ct[i].maxlen = sizeof lp->ctl_filtcar;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// FREEMEM
+	++i;
+	ct[i].ctl_name = CTL_SMC_FREEMEM;
+	ct[i].procname = "freemem";
+	ct[i].data = (void*)&(lp->ctl_freemem);
+	ct[i].maxlen = sizeof lp->ctl_freemem;
+	ct[i].mode = 0444; // Read only
+
+	// TOTMEM
+	++i;
+	ct[i].ctl_name = CTL_SMC_TOTMEM;
+	ct[i].procname = "totmem";
+	ct[i].data = (void*)&(lp->ctl_totmem);
+	ct[i].maxlen = sizeof lp->ctl_totmem;
+	ct[i].mode = 0444; // Read only
+
+	// LEDA
+	++i;
+	ct[i].ctl_name = CTL_SMC_LEDA;
+	ct[i].procname = "leda";
+	ct[i].data = (void*)&(lp->ctl_leda);
+	ct[i].maxlen = sizeof lp->ctl_leda;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// LEDB
+	++i;
+	ct[i].ctl_name = CTL_SMC_LEDB;
+	ct[i].procname = "ledb";
+	ct[i].data = (void*)&(lp->ctl_ledb);
+	ct[i].maxlen = sizeof lp->ctl_ledb;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// CHIPREV
+	++i;
+	ct[i].ctl_name = CTL_SMC_CHIPREV;
+	ct[i].procname = "chiprev";
+	ct[i].data = (void*)&(lp->ctl_chiprev);
+	ct[i].maxlen = sizeof lp->ctl_chiprev;
+	ct[i].mode = 0444; // Read only
+
+#ifdef SMC_DEBUG
+	// REG_BSR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_BSR;
+	ct[i].procname = "reg_bsr";
+	ct[i].data = (void*)&(lp->ctl_reg_bsr);
+	ct[i].maxlen = sizeof lp->ctl_reg_bsr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_TCR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_TCR;
+	ct[i].procname = "reg_tcr";
+	ct[i].data = (void*)&(lp->ctl_reg_tcr);
+	ct[i].maxlen = sizeof lp->ctl_reg_tcr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_ESR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_ESR;
+	ct[i].procname = "reg_esr";
+	ct[i].data = (void*)&(lp->ctl_reg_esr);
+	ct[i].maxlen = sizeof lp->ctl_reg_esr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_RCR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_RCR;
+	ct[i].procname = "reg_rcr";
+	ct[i].data = (void*)&(lp->ctl_reg_rcr);
+	ct[i].maxlen = sizeof lp->ctl_reg_rcr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_CTRR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_CTRR;
+	ct[i].procname = "reg_ctrr";
+	ct[i].data = (void*)&(lp->ctl_reg_ctrr);
+	ct[i].maxlen = sizeof lp->ctl_reg_ctrr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_MIR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_MIR;
+	ct[i].procname = "reg_mir";
+	ct[i].data = (void*)&(lp->ctl_reg_mir);
+	ct[i].maxlen = sizeof lp->ctl_reg_mir;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_RPCR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_RPCR;
+	ct[i].procname = "reg_rpcr";
+	ct[i].data = (void*)&(lp->ctl_reg_rpcr);
+	ct[i].maxlen = sizeof lp->ctl_reg_rpcr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_CFGR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_CFGR;
+	ct[i].procname = "reg_cfgr";
+	ct[i].data = (void*)&(lp->ctl_reg_cfgr);
+	ct[i].maxlen = sizeof lp->ctl_reg_cfgr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_BAR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_BAR;
+	ct[i].procname = "reg_bar";
+	ct[i].data = (void*)&(lp->ctl_reg_bar);
+	ct[i].maxlen = sizeof lp->ctl_reg_bar;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_IAR0
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_IAR0;
+	ct[i].procname = "reg_iar0";
+	ct[i].data = (void*)&(lp->ctl_reg_iar0);
+	ct[i].maxlen = sizeof lp->ctl_reg_iar0;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_IAR1
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_IAR1;
+	ct[i].procname = "reg_iar1";
+	ct[i].data = (void*)&(lp->ctl_reg_iar1);
+	ct[i].maxlen = sizeof lp->ctl_reg_iar1;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_IAR2
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_IAR2;
+	ct[i].procname = "reg_iar2";
+	ct[i].data = (void*)&(lp->ctl_reg_iar2);
+	ct[i].maxlen = sizeof lp->ctl_reg_iar2;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_GPR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_GPR;
+	ct[i].procname = "reg_gpr";
+	ct[i].data = (void*)&(lp->ctl_reg_gpr);
+	ct[i].maxlen = sizeof lp->ctl_reg_gpr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_CTLR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_CTLR;
+	ct[i].procname = "reg_ctlr";
+	ct[i].data = (void*)&(lp->ctl_reg_ctlr);
+	ct[i].maxlen = sizeof lp->ctl_reg_ctlr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_MCR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_MCR;
+	ct[i].procname = "reg_mcr";
+	ct[i].data = (void*)&(lp->ctl_reg_mcr);
+	ct[i].maxlen = sizeof lp->ctl_reg_mcr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_PNR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_PNR;
+	ct[i].procname = "reg_pnr";
+	ct[i].data = (void*)&(lp->ctl_reg_pnr);
+	ct[i].maxlen = sizeof lp->ctl_reg_pnr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_FPR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_FPR;
+	ct[i].procname = "reg_fpr";
+	ct[i].data = (void*)&(lp->ctl_reg_fpr);
+	ct[i].maxlen = sizeof lp->ctl_reg_fpr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_PTR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_PTR;
+	ct[i].procname = "reg_ptr";
+	ct[i].data = (void*)&(lp->ctl_reg_ptr);
+	ct[i].maxlen = sizeof lp->ctl_reg_ptr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_DR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_DR;
+	ct[i].procname = "reg_dr";
+	ct[i].data = (void*)&(lp->ctl_reg_dr);
+	ct[i].maxlen = sizeof lp->ctl_reg_dr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_ISR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_ISR;
+	ct[i].procname = "reg_isr";
+	ct[i].data = (void*)&(lp->ctl_reg_isr);
+	ct[i].maxlen = sizeof lp->ctl_reg_isr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_MTR1
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_MTR1;
+	ct[i].procname = "reg_mtr1";
+	ct[i].data = (void*)&(lp->ctl_reg_mtr1);
+	ct[i].maxlen = sizeof lp->ctl_reg_mtr1;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_MTR2
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_MTR2;
+	ct[i].procname = "reg_mtr2";
+	ct[i].data = (void*)&(lp->ctl_reg_mtr2);
+	ct[i].maxlen = sizeof lp->ctl_reg_mtr2;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_MTR3
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_MTR3;
+	ct[i].procname = "reg_mtr3";
+	ct[i].data = (void*)&(lp->ctl_reg_mtr3);
+	ct[i].maxlen = sizeof lp->ctl_reg_mtr3;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_MTR4
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_MTR4;
+	ct[i].procname = "reg_mtr4";
+	ct[i].data = (void*)&(lp->ctl_reg_mtr4);
+	ct[i].maxlen = sizeof lp->ctl_reg_mtr4;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_MIIR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_MIIR;
+	ct[i].procname = "reg_miir";
+	ct[i].data = (void*)&(lp->ctl_reg_miir);
+	ct[i].maxlen = sizeof lp->ctl_reg_miir;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_REVR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_REVR;
+	ct[i].procname = "reg_revr";
+	ct[i].data = (void*)&(lp->ctl_reg_revr);
+	ct[i].maxlen = sizeof lp->ctl_reg_revr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_ERCVR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_ERCVR;
+	ct[i].procname = "reg_ercvr";
+	ct[i].data = (void*)&(lp->ctl_reg_ercvr);
+	ct[i].maxlen = sizeof lp->ctl_reg_ercvr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// REG_EXTR
+	++i;
+	ct[i].ctl_name = CTL_SMC_REG_EXTR;
+	ct[i].procname = "reg_extr";
+	ct[i].data = (void*)&(lp->ctl_reg_extr);
+	ct[i].maxlen = sizeof lp->ctl_reg_extr;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// PHY Control
+	++i;
+	ct[i].ctl_name = CTL_SMC_PHY_CTRL;
+	ct[i].procname = "phy_ctrl";
+	ct[i].data = (void*)&(lp->ctl_phy_ctrl);
+	ct[i].maxlen = sizeof lp->ctl_phy_ctrl;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// PHY Status
+	++i;
+	ct[i].ctl_name = CTL_SMC_PHY_STAT;
+	ct[i].procname = "phy_stat";
+	ct[i].data = (void*)&(lp->ctl_phy_stat);
+	ct[i].maxlen = sizeof lp->ctl_phy_stat;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// PHY ID1
+	++i;
+	ct[i].ctl_name = CTL_SMC_PHY_ID1;
+	ct[i].procname = "phy_id1";
+	ct[i].data = (void*)&(lp->ctl_phy_id1);
+	ct[i].maxlen = sizeof lp->ctl_phy_id1;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// PHY ID2
+	++i;
+	ct[i].ctl_name = CTL_SMC_PHY_ID2;
+	ct[i].procname = "phy_id2";
+	ct[i].data = (void*)&(lp->ctl_phy_id2);
+	ct[i].maxlen = sizeof lp->ctl_phy_id2;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// PHY Advertise Capabilities
+	++i;
+	ct[i].ctl_name = CTL_SMC_PHY_ADC;
+	ct[i].procname = "phy_adc";
+	ct[i].data = (void*)&(lp->ctl_phy_adc);
+	ct[i].maxlen = sizeof lp->ctl_phy_adc;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// PHY Remote Capabilities
+	++i;
+	ct[i].ctl_name = CTL_SMC_PHY_REMC;
+	ct[i].procname = "phy_remc";
+	ct[i].data = (void*)&(lp->ctl_phy_remc);
+	ct[i].maxlen = sizeof lp->ctl_phy_remc;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// PHY Configuration 1
+	++i;
+	ct[i].ctl_name = CTL_SMC_PHY_CFG1;
+	ct[i].procname = "phy_cfg1";
+	ct[i].data = (void*)&(lp->ctl_phy_cfg1);
+	ct[i].maxlen = sizeof lp->ctl_phy_cfg1;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// PHY Configuration 2
+	++i;
+	ct[i].ctl_name = CTL_SMC_PHY_CFG2;
+	ct[i].procname = "phy_cfg2";
+	ct[i].data = (void*)&(lp->ctl_phy_cfg2);
+	ct[i].maxlen = sizeof lp->ctl_phy_cfg2;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// PHY Interrupt/Status Output
+	++i;
+	ct[i].ctl_name = CTL_SMC_PHY_INT;
+	ct[i].procname = "phy_int";
+	ct[i].data = (void*)&(lp->ctl_phy_int);
+	ct[i].maxlen = sizeof lp->ctl_phy_int;
+	ct[i].mode = 0644; // Read by all, write by root
+
+	// PHY Interrupt/Status Mask
+	++i;
+	ct[i].ctl_name = CTL_SMC_PHY_MASK;
+	ct[i].procname = "phy_mask";
+	ct[i].data = (void*)&(lp->ctl_phy_mask);
+	ct[i].maxlen = sizeof lp->ctl_phy_mask;
+	ct[i].mode = 0644; // Read by all, write by root
+
+#endif // SMC_DEBUG
+
+	// Register /proc/sys/dev/ethX
+	lp->sysctl_header = register_sysctl_table(lp->root_table, 1);
+}
+
+
+/*------------------------------------------------------------
+ . Sysctl unregistration when driver is closed
+ .-------------------------------------------------------------*/
+static void smc_sysctl_unregister(struct net_device *dev)
+{
+	struct smc_local *lp = (struct smc_local *)dev->priv;
+
+	unregister_sysctl_table(lp->sysctl_header);
+}
+
+#endif /* endif CONFIG_SYSCTL */
+
+
+//---PHY CONTROL AND CONFIGURATION-----------------------------------------
+
+#if (SMC_DEBUG > 2 )
+
+/*------------------------------------------------------------
+ . Debugging function for viewing MII Management serial bitstream
+ .-------------------------------------------------------------*/
+static void smc_dump_mii_stream(byte* bits, int size)
+{
+	int i;
+
+	printk("BIT#:");
+	for (i = 0; i < size; ++i)
+		{
+		printk("%d", i%10);
+		}
+
+	printk("\nMDOE:");
+	for (i = 0; i < size; ++i)
+		{
+		if (bits[i] & MII_MDOE)
+			printk("1");
+		else
+			printk("0");
+		}
+
+	printk("\nMDO :");
+	for (i = 0; i < size; ++i)
+		{
+		if (bits[i] & MII_MDO)
+			printk("1");
+		else
+			printk("0");
+		}
+
+	printk("\nMDI :");
+	for (i = 0; i < size; ++i)
+		{
+		if (bits[i] & MII_MDI)
+			printk("1");
+		else
+			printk("0");
+		}
+
+	printk("\n");
+}
+#endif
+
+/*------------------------------------------------------------
+ . Reads a register from the MII Management serial interface
+ .-------------------------------------------------------------*/
+static word smc_read_phy_register(unsigned int ioaddr, byte phyaddr, byte phyreg)
+{
+	int oldBank;
+	int i;
+	byte mask;
+	word mii_reg;
+	byte bits[64];
+	int clk_idx = 0;
+	int input_idx;
+	word phydata;
+
+	// 32 consecutive ones on MDO to establish sync
+	for (i = 0; i < 32; ++i)
+		bits[clk_idx++] = MII_MDOE | MII_MDO;
+
+	// Start code <01>
+	bits[clk_idx++] = MII_MDOE;
+	bits[clk_idx++] = MII_MDOE | MII_MDO;
+
+	// Read command <10>
+	bits[clk_idx++] = MII_MDOE | MII_MDO;
+	bits[clk_idx++] = MII_MDOE;
+
+	// Output the PHY address, msb first
+	mask = (byte)0x10;
+	for (i = 0; i < 5; ++i)
+		{
+		if (phyaddr & mask)
+			bits[clk_idx++] = MII_MDOE | MII_MDO;
+		else
+			bits[clk_idx++] = MII_MDOE;
+
+		// Shift to next lowest bit
+		mask >>= 1;
+		}
+
+	// Output the phy register number, msb first
+	mask = (byte)0x10;
+	for (i = 0; i < 5; ++i)
+		{
+		if (phyreg & mask)
+			bits[clk_idx++] = MII_MDOE | MII_MDO;
+		else
+			bits[clk_idx++] = MII_MDOE;
+
+		// Shift to next lowest bit
+		mask >>= 1;
+		}
+
+	// Tristate and turnaround (2 bit times)
+	bits[clk_idx++] = 0;
+	//bits[clk_idx++] = 0;
+
+	// Input starts at this bit time
+	input_idx = clk_idx;
+
+	// Will input 16 bits
+	for (i = 0; i < 16; ++i)
+		bits[clk_idx++] = 0;
+
+	// Final clock bit
+	bits[clk_idx++] = 0;
+
+	// Save the current bank
+	oldBank = inw( ioaddr+BANK_SELECT );
+
+	// Select bank 3
+	SMC_SELECT_BANK( 3 );
+
+	// Get the current MII register value
+	mii_reg = inw( ioaddr+MII_REG );
+
+	// Turn off all MII Interface bits
+	mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO);
+
+	// Clock all 64 cycles
+	for (i = 0; i < sizeof bits; ++i)
+		{
+		// Clock Low - output data
+		outw( mii_reg | bits[i], ioaddr+MII_REG );
+		udelay(50);
+
+
+		// Clock Hi - input data
+		outw( mii_reg | bits[i] | MII_MCLK, ioaddr+MII_REG );
+		udelay(50);
+		bits[i] |= inw( ioaddr+MII_REG ) & MII_MDI;
+		}
+
+	// Return to idle state
+	// Set clock to low, data to low, and output tristated
+	outw( mii_reg, ioaddr+MII_REG );
+	udelay(50);
+
+	// Restore original bank select
+	SMC_SELECT_BANK( oldBank );
+
+	// Recover input data
+	phydata = 0;
+	for (i = 0; i < 16; ++i)
+		{
+		phydata <<= 1;
+
+		if (bits[input_idx++] & MII_MDI)
+			phydata |= 0x0001;
+		}
+
+#if (SMC_DEBUG > 2 )
+	printk("smc_read_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n",
+		phyaddr, phyreg, phydata);
+	smc_dump_mii_stream(bits, sizeof bits);
+#endif
+
+	return(phydata);	
+}
+
+
+/*------------------------------------------------------------
+ . Writes a register to the MII Management serial interface
+ .-------------------------------------------------------------*/
+static void smc_write_phy_register(unsigned int ioaddr,
+	byte phyaddr, byte phyreg, word phydata)
+{
+	int oldBank;
+	int i;
+	word mask;
+	word mii_reg;
+	byte bits[65];
+	int clk_idx = 0;
+
+	// 32 consecutive ones on MDO to establish sync
+	for (i = 0; i < 32; ++i)
+		bits[clk_idx++] = MII_MDOE | MII_MDO;
+
+	// Start code <01>
+	bits[clk_idx++] = MII_MDOE;
+	bits[clk_idx++] = MII_MDOE | MII_MDO;
+
+	// Write command <01>
+	bits[clk_idx++] = MII_MDOE;
+	bits[clk_idx++] = MII_MDOE | MII_MDO;
+
+	// Output the PHY address, msb first
+	mask = (byte)0x10;
+	for (i = 0; i < 5; ++i)
+		{
+		if (phyaddr & mask)
+			bits[clk_idx++] = MII_MDOE | MII_MDO;
+		else
+			bits[clk_idx++] = MII_MDOE;
+
+		// Shift to next lowest bit
+		mask >>= 1;
+		}
+
+	// Output the phy register number, msb first
+	mask = (byte)0x10;
+	for (i = 0; i < 5; ++i)
+		{
+		if (phyreg & mask)
+			bits[clk_idx++] = MII_MDOE | MII_MDO;
+		else
+			bits[clk_idx++] = MII_MDOE;
+
+		// Shift to next lowest bit
+		mask >>= 1;
+		}
+
+	// Tristate and turnaround (2 bit times)
+	bits[clk_idx++] = 0;
+	bits[clk_idx++] = 0;
+
+	// Write out 16 bits of data, msb first
+	mask = 0x8000;
+	for (i = 0; i < 16; ++i)
+		{
+		if (phydata & mask)
+			bits[clk_idx++] = MII_MDOE | MII_MDO;
+		else
+			bits[clk_idx++] = MII_MDOE;
+
+		// Shift to next lowest bit
+		mask >>= 1;
+		}
+
+	// Final clock bit (tristate)
+	bits[clk_idx++] = 0;
+
+	// Save the current bank
+	oldBank = inw( ioaddr+BANK_SELECT );
+
+	// Select bank 3
+	SMC_SELECT_BANK( 3 );
+
+	// Get the current MII register value
+	mii_reg = inw( ioaddr+MII_REG );
+
+	// Turn off all MII Interface bits
+	mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO);
+
+	// Clock all cycles
+	for (i = 0; i < sizeof bits; ++i)
+		{
+		// Clock Low - output data
+		outw( mii_reg | bits[i], ioaddr+MII_REG );
+		udelay(50);
+
+
+		// Clock Hi - input data
+		outw( mii_reg | bits[i] | MII_MCLK, ioaddr+MII_REG );
+		udelay(50);
+		bits[i] |= inw( ioaddr+MII_REG ) & MII_MDI;
+		}
+
+	// Return to idle state
+	// Set clock to low, data to low, and output tristated
+	outw( mii_reg, ioaddr+MII_REG );
+	udelay(50);
+
+	// Restore original bank select
+	SMC_SELECT_BANK( oldBank );
+
+#if (SMC_DEBUG > 2 )
+	printk("smc_write_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n",
+		phyaddr, phyreg, phydata);
+	smc_dump_mii_stream(bits, sizeof bits);
+#endif
+}
+
+
+/*------------------------------------------------------------
+ . Finds and reports the PHY address
+ .-------------------------------------------------------------*/
+static int smc_detect_phy(struct net_device* dev)
+{
+	struct smc_local *lp = (struct smc_local *)dev->priv;
+	unsigned int ioaddr = dev->base_addr;
+	word phy_id1;
+	word phy_id2;
+	int phyaddr;
+	int found = 0;
+
+	PRINTK3("%s:smc_detect_phy()\n", dev->name);
+
+	// Scan all 32 PHY addresses if necessary
+	for (phyaddr = 0; phyaddr < 32; ++phyaddr)
+		{
+		// Read the PHY identifiers
+		phy_id1  = smc_read_phy_register(ioaddr, phyaddr, PHY_ID1_REG);
+		phy_id2  = smc_read_phy_register(ioaddr, phyaddr, PHY_ID2_REG);
+
+		PRINTK3("%s: phy_id1=%x, phy_id2=%x\n",
+			dev->name, phy_id1, phy_id2);
+
+		// Make sure it is a valid identifier	
+		if ((phy_id2 > 0x0000) && (phy_id2 < 0xffff) &&
+		    (phy_id1 > 0x0000) && (phy_id1 < 0xffff))
+			{
+			if ((phy_id1 != 0x8000) && (phy_id2 != 0x8000))
+				{
+				// Save the PHY's address
+				lp->phyaddr = phyaddr;
+				found = 1;
+				break;
+				}
+			}
+		}
+
+	if (!found)
+		{
+		PRINTK("%s: No PHY found\n", dev->name);
+		return(0);
+		}
+
+	// Set the PHY type
+	if ( (phy_id1 == 0x0016) && ((phy_id2 & 0xFFF0) == 0xF840 ) )
+		{
+		lp->phytype = PHY_LAN83C183;
+		PRINTK("%s: PHY=LAN83C183 (LAN91C111 Internal)\n", dev->name);
+		}
+
+	if ( (phy_id1 == 0x0282) && ((phy_id2 & 0xFFF0) == 0x1C50) )
+		{
+		lp->phytype = PHY_LAN83C180;
+		PRINTK("%s: PHY=LAN83C180\n", dev->name);
+		}
+
+	return(1);
+}
+
+/*------------------------------------------------------------
+ . Waits the specified number of milliseconds - kernel friendly
+ .-------------------------------------------------------------*/
+static void smc_wait_ms(unsigned int ms)
+{
+
+	if (!in_interrupt())
+		{
+		current->state = TASK_UNINTERRUPTIBLE;
+		schedule_timeout(1 + ms * HZ / 1000);
+		}
+	else
+		{
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(1 + ms * HZ / 1000);
+		current->state = TASK_RUNNING;
+		}
+}
+
+#ifdef CONFIG_SYSCTL
+/*------------------------------------------------------------
+ . Sets the PHY to a configuration as determined by the user
+ .-------------------------------------------------------------*/
+static int smc_phy_fixed(struct net_device* dev)
+{
+	unsigned int ioaddr = dev->base_addr;
+	struct smc_local *lp = (struct smc_local *)dev->priv;
+	byte phyaddr = lp->phyaddr;
+	word my_fixed_caps;
+	word cfg1;
+
+	PRINTK3("%s:smc_phy_fixed()\n", dev->name);
+
+	// Enter Link Disable state
+	cfg1 = smc_read_phy_register(ioaddr, phyaddr, PHY_CFG1_REG);
+	cfg1 |= PHY_CFG1_LNKDIS;
+	smc_write_phy_register(ioaddr, phyaddr, PHY_CFG1_REG, cfg1);
+
+	// Set our fixed capabilities
+	// Disable auto-negotiation
+	my_fixed_caps = 0;
+
+#ifdef CONFIG_SYSCTL
+	if (lp->ctl_rfduplx)
+		my_fixed_caps |= PHY_CNTL_DPLX;
+
+	if (lp->ctl_rspeed == 100)
+		my_fixed_caps |= PHY_CNTL_SPEED;
+#endif
+
+	// Write our capabilities to the phy control register
+	smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, my_fixed_caps);
+
+	// Re-Configure the Receive/Phy Control register
+	outw( lp->rpc_cur_mode, ioaddr + RPC_REG );
+
+	// Success
+	return(1);
+}
+#endif
+
+
+/*------------------------------------------------------------
+ . Configures the specified PHY using Autonegotiation. Calls
+ . smc_phy_fixed() if the user has requested a certain config.
+ .-------------------------------------------------------------*/
+static void smc_phy_configure(struct net_device* dev)
+{
+	unsigned int ioaddr = dev->base_addr;
+	struct smc_local *lp = (struct smc_local *)dev->priv;
+	int timeout;
+	byte phyaddr;
+	word my_phy_caps; // My PHY capabilities
+	word my_ad_caps; // My Advertised capabilities
+	word status = 0;
+	int failed = 0;
+
+	PRINTK3("%s:smc_program_phy()\n", dev->name);
+
+	// Set the blocking flag
+	lp->autoneg_active = 1;
+
+	// Find the address and type of our phy
+	if (!smc_detect_phy(dev))
+		{
+		goto smc_phy_configure_exit;
+		}
+
+	// Get the detected phy address
+	phyaddr = lp->phyaddr;
+
+	// Reset the PHY, setting all other bits to zero
+	smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, PHY_CNTL_RST);
+
+	smc_wait_ms(50);
+
+	// Wait for the reset to complete, or time out
+	timeout = 6; // Wait up to 3 seconds
+	while (timeout--)
+		{
+		if (!(smc_read_phy_register(ioaddr, phyaddr, PHY_CNTL_REG)
+		    & PHY_CNTL_RST))
+			{
+			// reset complete
+			break;
+			}
+
+		smc_wait_ms(500); // wait 500 millisecs
+		if (signal_pending(current)) // Exit anyway if signaled
+			{
+			PRINTK2("%s:PHY reset interrupted by signal\n",
+				dev->name);
+			timeout = 0;
+			break;
+			}
+		}
+
+	if (timeout < 1)
+		{
+		PRINTK2("%s:PHY reset timed out\n", dev->name);
+		goto smc_phy_configure_exit;
+		}
+
+#ifndef CONFIG_RTE_CB_ME2
+	// Read PHY Register 18, Status Output
+	lp->lastPhy18 = smc_read_phy_register(ioaddr, phyaddr, PHY_INT_REG);
+
+	// Enable PHY Interrupts (for register 18)
+	// Interrupts listed here are disabled
+	smc_write_phy_register(ioaddr, phyaddr, PHY_MASK_REG, 
+		PHY_INT_LOSSSYNC | PHY_INT_CWRD | PHY_INT_SSD |
+		PHY_INT_ESD | PHY_INT_RPOL | PHY_INT_JAB |
+		PHY_INT_SPDDET | PHY_INT_DPLXDET);
+#endif
+
+	/* Configure the Receive/Phy Control register */
+	SMC_SELECT_BANK( 0 );
+	outw( lp->rpc_cur_mode, ioaddr + RPC_REG );
+
+	// Copy our capabilities from PHY_STAT_REG to PHY_AD_REG
+	my_phy_caps = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG);
+	my_ad_caps  = PHY_AD_CSMA; // I am CSMA capable
+
+	if (my_phy_caps & PHY_STAT_CAP_T4)
+		my_ad_caps |= PHY_AD_T4;
+
+	if (my_phy_caps & PHY_STAT_CAP_TXF)
+		my_ad_caps |= PHY_AD_TX_FDX;
+
+	if (my_phy_caps & PHY_STAT_CAP_TXH)
+		my_ad_caps |= PHY_AD_TX_HDX;
+
+	if (my_phy_caps & PHY_STAT_CAP_TF)
+		my_ad_caps |= PHY_AD_10_FDX;
+
+	if (my_phy_caps & PHY_STAT_CAP_TH)
+		my_ad_caps |= PHY_AD_10_HDX;
+
+#ifdef CONFIG_SYSCTL
+	// Disable capabilities not selected by our user
+	if (lp->ctl_rspeed != 100)
+		{
+		my_ad_caps &= ~(PHY_AD_T4|PHY_AD_TX_FDX|PHY_AD_TX_HDX);
+		}
+
+	if (!lp->ctl_rfduplx)
+		{
+		my_ad_caps &= ~(PHY_AD_TX_FDX|PHY_AD_10_FDX);
+		}
+#endif
+
+	// Update our Auto-Neg Advertisement Register
+	smc_write_phy_register(ioaddr, phyaddr, PHY_AD_REG, my_ad_caps);
+
+	PRINTK2("%s:phy caps=%x\n", dev->name, my_phy_caps);
+	PRINTK2("%s:phy advertised caps=%x\n", dev->name, my_ad_caps);
+
+#ifdef CONFIG_SYSCTL
+	// If the user requested no auto neg, then go set his request
+	if (!(lp->ctl_autoneg))
+		{
+		smc_phy_fixed(dev);
+		goto smc_phy_configure_exit;
+		}
+#endif
+
+	// Restart auto-negotiation process in order to advertise my caps
+	smc_write_phy_register( ioaddr, phyaddr, PHY_CNTL_REG,
+		PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST );
+
+	// Wait for the auto-negotiation to complete.  This may take from
+	// 2 to 3 seconds.
+	// Wait for the reset to complete, or time out
+	timeout = 20; // Wait up to 10 seconds
+	while (timeout--)
+		{
+		status = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG);
+		if (status & PHY_STAT_ANEG_ACK)
+			{
+			// auto-negotiate complete
+			break;
+			}
+
+		smc_wait_ms(500); // wait 500 millisecs
+		if (signal_pending(current)) // Exit anyway if signaled
+			{
+			printk(KERN_DEBUG
+				"%s:PHY auto-negotiate interrupted by signal\n",
+				dev->name);
+			timeout = 0;
+			break;
+			}
+
+		// Restart auto-negotiation if remote fault
+		if (status & PHY_STAT_REM_FLT)
+			{
+			PRINTK2("%s:PHY remote fault detected\n", dev->name);
+
+			// Restart auto-negotiation
+			PRINTK2("%s:PHY restarting auto-negotiation\n",
+				dev->name);
+			smc_write_phy_register( ioaddr, phyaddr, PHY_CNTL_REG,
+				PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST |
+				PHY_CNTL_SPEED | PHY_CNTL_DPLX);
+			}
+		}
+
+	if (timeout < 1)
+		{
+		printk(KERN_DEBUG "%s:PHY auto-negotiate timed out\n",
+			dev->name);
+		PRINTK2("%s:PHY auto-negotiate timed out\n", dev->name);
+		failed = 1;
+		}
+
+	// Fail if we detected an auto-negotiate remote fault
+	if (status & PHY_STAT_REM_FLT)
+		{
+		printk(KERN_DEBUG "%s:PHY remote fault detected\n", dev->name);
+		PRINTK2("%s:PHY remote fault detected\n", dev->name);
+		failed = 1;
+		}
+
+	// The smc_phy_interrupt() routine will be called to update lastPhy18
+
+	// Set our sysctl parameters to match auto-negotiation results
+	if ( lp->lastPhy18 & PHY_INT_SPDDET )
+		{
+		PRINTK2("%s:PHY 100BaseT\n", dev->name);
+		lp->rpc_cur_mode |= RPC_SPEED;
+		}
+	else
+		{
+		PRINTK2("%s:PHY 10BaseT\n", dev->name);
+		lp->rpc_cur_mode &= ~RPC_SPEED;
+		}
+
+	if ( lp->lastPhy18 & PHY_INT_DPLXDET )
+		{
+		PRINTK2("%s:PHY Full Duplex\n", dev->name);
+		lp->rpc_cur_mode |= RPC_DPLX;
+		}
+	else
+		{
+		PRINTK2("%s:PHY Half Duplex\n", dev->name);
+		lp->rpc_cur_mode &= ~RPC_DPLX;
+		}
+
+	// Re-Configure the Receive/Phy Control register
+	outw( lp->rpc_cur_mode, ioaddr + RPC_REG );
+
+  smc_phy_configure_exit:
+
+	// Exit auto-negotiation
+	lp->autoneg_active = 0;
+}
+
+
+
+/*************************************************************************
+ . smc_phy_interrupt
+ .
+ . Purpose:  Handle interrupts relating to PHY register 18. This is
+ .  called from the "hard" interrupt handler.
+ .
+ ************************************************************************/
+static void smc_phy_interrupt(struct net_device* dev)
+{
+	unsigned int ioaddr	= dev->base_addr;
+	struct smc_local *lp 	= (struct smc_local *)dev->priv;
+	byte phyaddr = lp->phyaddr;
+	word phy18;
+
+	PRINTK2("%s: smc_phy_interrupt\n", dev->name);
+
+  while (1)
+	{ 
+	// Read PHY Register 18, Status Output
+	phy18 = smc_read_phy_register(ioaddr, phyaddr, PHY_INT_REG);
+
+	// Exit if not more changes
+	if (phy18 == lp->lastPhy18)
+		break;
+
+#if (SMC_DEBUG > 1 )
+
+	PRINTK2("%s:     phy18=0x%x\n", dev->name, phy18);
+	PRINTK2("%s: lastPhy18=0x%x\n", dev->name, lp->lastPhy18);
+
+	// Handle events
+	if ((phy18 & PHY_INT_LNKFAIL) != (lp->lastPhy18 & PHY_INT_LNKFAIL))
+		{
+		PRINTK2("%s: PHY Link Fail=%x\n", dev->name,
+			phy18 & PHY_INT_LNKFAIL);
+		}
+
+	if ((phy18 & PHY_INT_LOSSSYNC) != (lp->lastPhy18 & PHY_INT_LOSSSYNC))
+		{
+		PRINTK2("%s: PHY LOSS SYNC=%x\n", dev->name,
+			phy18 & PHY_INT_LOSSSYNC);
+		}
+
+	if ((phy18 & PHY_INT_CWRD) != (lp->lastPhy18 & PHY_INT_CWRD))
+		{
+		PRINTK2("%s: PHY INVALID 4B5B code=%x\n", dev->name,
+			phy18 & PHY_INT_CWRD);
+		}
+
+	if ((phy18 & PHY_INT_SSD) != (lp->lastPhy18 & PHY_INT_SSD))
+		{
+		PRINTK2("%s: PHY No Start Of Stream=%x\n", dev->name,
+			phy18 & PHY_INT_SSD);
+		}
+
+	if ((phy18 & PHY_INT_ESD) != (lp->lastPhy18 & PHY_INT_ESD))
+		{
+		PRINTK2("%s: PHY No End Of Stream=%x\n", dev->name,
+			phy18 & PHY_INT_ESD);
+		}
+
+	if ((phy18 & PHY_INT_RPOL) != (lp->lastPhy18 & PHY_INT_RPOL))
+		{
+		PRINTK2("%s: PHY Reverse Polarity Detected=%x\n", dev->name,
+			phy18 & PHY_INT_RPOL);
+		}
+
+	if ((phy18 & PHY_INT_JAB) != (lp->lastPhy18 & PHY_INT_JAB))
+		{
+		PRINTK2("%s: PHY Jabber Detected=%x\n", dev->name,
+			phy18 & PHY_INT_JAB);
+		}
+
+	if ((phy18 & PHY_INT_SPDDET) != (lp->lastPhy18 & PHY_INT_SPDDET))
+		{
+		PRINTK2("%s: PHY Speed Detect=%x\n", dev->name,
+			phy18 & PHY_INT_SPDDET);
+		}
+
+	if ((phy18 & PHY_INT_DPLXDET) != (lp->lastPhy18 & PHY_INT_DPLXDET))
+		{
+		PRINTK2("%s: PHY Duplex Detect=%x\n", dev->name,
+			phy18 & PHY_INT_DPLXDET);
+		}
+#endif
+
+	// Update the last phy 18 variable
+	lp->lastPhy18 = phy18;
+
+	} // end while
+}
+
+
diff -urN linux-2.4.29/drivers/net/smc91111.h linux-2.4.29-uc1/drivers/net/smc91111.h
--- linux-2.4.29/drivers/net/smc91111.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/smc91111.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,597 @@
+/*------------------------------------------------------------------------
+ . smc91111.h - macros for the LAN91C111 Ethernet Driver
+ .
+ . Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
+ .       Developed by Simple Network Magic Corporation (SNMC)
+ . Copyright (C) 1996 by Erik Stahlman (ES)
+ .
+ . This program is free software; you can redistribute it and/or modify
+ . it under the terms of the GNU General Public License as published by
+ . the Free Software Foundation; either version 2 of the License, or
+ . (at your option) any later version.
+ .
+ . 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
+ .
+ . This file contains register information and access macros for 
+ . the LAN91C111 single chip ethernet controller.  It is a modified
+ . version of the smc9194.h file.
+ . 
+ . Information contained in this file was obtained from the LAN91C111
+ . manual from SMC.  To get a copy, if you really want one, you can find 
+ . information under www.smsc.com.
+ . 
+ . Authors
+ . 	Erik Stahlman				( erik@vt.edu )
+ .	Daris A Nevil				( dnevil@snmc.com )
+ .
+ . History
+ . 03/16/01		Daris A Nevil	Modified for use with LAN91C111 device
+ .
+ ---------------------------------------------------------------------------*/
+#ifndef _SMC91111_H_
+#define _SMC91111_H_
+
+/* I want some simple types */
+
+typedef unsigned char			byte;
+typedef unsigned short			word;
+typedef unsigned long int 		dword;
+
+
+/* Because of bank switching, the LAN91xxx uses only 16 I/O ports */
+
+#define SMC_IO_EXTENT	16
+
+
+/*---------------------------------------------------------------
+ .  
+ . A description of the SMSC registers is probably in order here,
+ . although for details, the SMC datasheet is invaluable.  
+ . 
+ . Basically, the chip has 4 banks of registers ( 0 to 3 ), which
+ . are accessed by writing a number into the BANK_SELECT register
+ . ( I also use a SMC_SELECT_BANK macro for this ).
+ . 
+ . The banks are configured so that for most purposes, bank 2 is all
+ . that is needed for simple run time tasks.  
+ -----------------------------------------------------------------------*/
+
+/*
+ . Bank Select Register: 
+ .
+ .		yyyy yyyy 0000 00xx  
+ .		xx 		= bank number
+ .		yyyy yyyy	= 0x33, for identification purposes.
+*/
+#define	BANK_SELECT		14
+
+// Transmit Control Register
+/* BANK 0  */
+#define	TCR_REG 	0x0000 	// transmit control register 
+#define TCR_ENABLE	0x0001	// When 1 we can transmit
+#define TCR_LOOP	0x0002	// Controls output pin LBK
+#define TCR_FORCOL	0x0004	// When 1 will force a collision
+#define TCR_PAD_EN	0x0080	// When 1 will pad tx frames < 64 bytes w/0
+#define TCR_NOCRC	0x0100	// When 1 will not append CRC to tx frames
+#define TCR_MON_CSN	0x0400	// When 1 tx monitors carrier
+#define TCR_FDUPLX    	0x0800  // When 1 enables full duplex operation
+#define TCR_STP_SQET	0x1000	// When 1 stops tx if Signal Quality Error
+#define	TCR_EPH_LOOP	0x2000	// When 1 enables EPH block loopback
+#define	TCR_SWFDUP	0x8000	// When 1 enables Switched Full Duplex mode
+
+#define	TCR_CLEAR	0	/* do NOTHING */
+/* the default settings for the TCR register : */ 
+/* QUESTION: do I want to enable padding of short packets ? */
+#define	TCR_DEFAULT  	TCR_ENABLE 
+
+
+// EPH Status Register
+/* BANK 0  */
+#define EPH_STATUS_REG	0x0002
+#define ES_TX_SUC	0x0001	// Last TX was successful
+#define ES_SNGL_COL	0x0002	// Single collision detected for last tx
+#define ES_MUL_COL	0x0004	// Multiple collisions detected for last tx
+#define ES_LTX_MULT	0x0008	// Last tx was a multicast
+#define ES_16COL	0x0010	// 16 Collisions Reached
+#define ES_SQET		0x0020	// Signal Quality Error Test
+#define ES_LTXBRD	0x0040	// Last tx was a broadcast
+#define ES_TXDEFR	0x0080	// Transmit Deferred
+#define ES_LATCOL	0x0200	// Late collision detected on last tx
+#define ES_LOSTCARR	0x0400	// Lost Carrier Sense
+#define ES_EXC_DEF	0x0800	// Excessive Deferral
+#define ES_CTR_ROL	0x1000	// Counter Roll Over indication
+#define ES_LINK_OK	0x4000	// Driven by inverted value of nLNK pin
+#define ES_TXUNRN	0x8000	// Tx Underrun
+
+
+// Receive Control Register
+/* BANK 0  */
+#define	RCR_REG		0x0004
+#define	RCR_RX_ABORT	0x0001	// Set if a rx frame was aborted
+#define	RCR_PRMS	0x0002	// Enable promiscuous mode
+#define	RCR_ALMUL	0x0004	// When set accepts all multicast frames
+#define RCR_RXEN	0x0100	// IFF this is set, we can receive packets
+#define	RCR_STRIP_CRC	0x0200	// When set strips CRC from rx packets
+#define	RCR_ABORT_ENB	0x0200	// When set will abort rx on collision 
+#define	RCR_FILT_CAR	0x0400	// When set filters leading 12 bit s of carrier
+#define RCR_SOFTRST	0x8000 	// resets the chip
+
+/* the normal settings for the RCR register : */
+#define	RCR_DEFAULT	(RCR_STRIP_CRC | RCR_RXEN)
+#define RCR_CLEAR	0x0	// set it to a base state
+
+// Counter Register
+/* BANK 0  */
+#define	COUNTER_REG	0x0006
+
+// Memory Information Register
+/* BANK 0  */
+#define	MIR_REG		0x0008
+
+// Receive/Phy Control Register
+/* BANK 0  */
+#define	RPC_REG		0x000A
+#define	RPC_SPEED	0x2000	// When 1 PHY is in 100Mbps mode.
+#define	RPC_DPLX	0x1000	// When 1 PHY is in Full-Duplex Mode
+#define	RPC_ANEG	0x0800	// When 1 PHY is in Auto-Negotiate Mode
+#define	RPC_LSXA_SHFT	5	// Bits to shift LS2A,LS1A,LS0A to lsb
+#define	RPC_LSXB_SHFT	2	// Bits to get LS2B,LS1B,LS0B to lsb
+#define RPC_LED_100_10	(0x00)	// LED = 100Mbps OR's with 10Mbps link detect
+#define RPC_LED_RES	(0x01)	// LED = Reserved
+#define RPC_LED_10	(0x02)	// LED = 10Mbps link detect
+#define RPC_LED_FD	(0x03)	// LED = Full Duplex Mode
+#define RPC_LED_TX_RX	(0x04)	// LED = TX or RX packet occurred
+#define RPC_LED_100	(0x05)	// LED = 100Mbps link dectect
+#define RPC_LED_TX	(0x06)	// LED = TX packet occurred
+#define RPC_LED_RX	(0x07)	// LED = RX packet occurred
+#define RPC_DEFAULT (RPC_ANEG | (RPC_LED_100_10 << RPC_LSXA_SHFT) | (RPC_LED_TX_RX << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX)
+
+/* Bank 0 0x000C is reserved */
+
+// Bank Select Register
+/* All Banks */
+#define BSR_REG	0x000E
+
+
+// Configuration Reg
+/* BANK 1 */
+#define CONFIG_REG	0x0000
+#define CONFIG_EXT_PHY	0x0200	// 1=external MII, 0=internal Phy
+#define CONFIG_GPCNTRL	0x0400	// Inverse value drives pin nCNTRL
+#define CONFIG_NO_WAIT	0x1000	// When 1 no extra wait states on ISA bus
+#define CONFIG_EPH_POWER_EN 0x8000 // When 0 EPH is placed into low power mode.
+
+// Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low
+#define CONFIG_DEFAULT	(CONFIG_EPH_POWER_EN)
+
+
+// Base Address Register
+/* BANK 1 */
+#define	BASE_REG	0x0002
+
+
+// Individual Address Registers
+/* BANK 1 */
+#define	ADDR0_REG	0x0004
+#define	ADDR1_REG	0x0006
+#define	ADDR2_REG	0x0008
+
+
+// General Purpose Register
+/* BANK 1 */
+#define	GP_REG		0x000A
+
+
+// Control Register
+/* BANK 1 */
+#define	CTL_REG		0x000C
+#define CTL_RCV_BAD	0x4000 // When 1 bad CRC packets are received
+#define CTL_AUTO_RELEASE 0x0800 // When 1 tx pages are released automatically
+#define	CTL_LE_ENABLE	0x0080 // When 1 enables Link Error interrupt
+#define	CTL_CR_ENABLE	0x0040 // When 1 enables Counter Rollover interrupt
+#define	CTL_TE_ENABLE	0x0020 // When 1 enables Transmit Error interrupt
+#define	CTL_EEPROM_SELECT 0x0004 // Controls EEPROM reload & store
+#define	CTL_RELOAD	0x0002 // When set reads EEPROM into registers
+#define	CTL_STORE	0x0001 // When set stores registers into EEPROM
+
+
+// MMU Command Register
+/* BANK 2 */
+#define MMU_CMD_REG	0x0000
+#define MC_BUSY		1	// When 1 the last release has not completed
+#define MC_NOP		(0<<5)	// No Op
+#define	MC_ALLOC	(1<<5) 	// OR with number of 256 byte packets
+#define	MC_RESET	(2<<5)	// Reset MMU to initial state
+#define	MC_REMOVE	(3<<5) 	// Remove the current rx packet
+#define MC_RELEASE  	(4<<5) 	// Remove and release the current rx packet
+#define MC_FREEPKT  	(5<<5) 	// Release packet in PNR register
+#define MC_ENQUEUE	(6<<5)	// Enqueue the packet for transmit
+#define MC_RSTTXFIFO	(7<<5)	// Reset the TX FIFOs
+
+
+// Packet Number Register
+/* BANK 2 */
+#define	PN_REG		0x0002
+
+
+// Allocation Result Register
+/* BANK 2 */
+#define	AR_REG		0x0003
+#define AR_FAILED	0x80	// Alocation Failed
+
+
+// RX FIFO Ports Register
+/* BANK 2 */
+#define RXFIFO_REG	0x0004	// Must be read as a word
+#define RXFIFO_REMPTY	0x8000	// RX FIFO Empty
+
+
+// TX FIFO Ports Register
+/* BANK 2 */
+#define TXFIFO_REG	RXFIFO_REG	// Must be read as a word
+#define TXFIFO_TEMPTY	0x80	// TX FIFO Empty
+
+
+// Pointer Register
+/* BANK 2 */
+#define PTR_REG		0x0006
+#define	PTR_RCV		0x8000 // 1=Receive area, 0=Transmit area
+#define	PTR_AUTOINC 	0x4000 // Auto increment the pointer on each access
+#define PTR_READ	0x2000 // When 1 the operation is a read
+
+
+// Data Register
+/* BANK 2 */
+#define	DATA_REG	0x0008
+
+
+// Interrupt Status/Acknowledge Register
+/* BANK 2 */
+#define	INT_REG		0x000C
+
+
+// Interrupt Mask Register
+/* BANK 2 */
+#define IM_REG		0x000D
+#define	IM_MDINT	0x80 // PHY MI Register 18 Interrupt
+#define	IM_ERCV_INT	0x40 // Early Receive Interrupt
+#define	IM_EPH_INT	0x20 // Set by Etheret Protocol Handler section
+#define	IM_RX_OVRN_INT	0x10 // Set by Receiver Overruns
+#define	IM_ALLOC_INT	0x08 // Set when allocation request is completed
+#define	IM_TX_EMPTY_INT	0x04 // Set if the TX FIFO goes empty
+#define	IM_TX_INT	0x02 // Transmit Interrrupt
+#define IM_RCV_INT	0x01 // Receive Interrupt
+
+
+// Multicast Table Registers
+/* BANK 3 */
+#define	MCAST_REG1	0x0000
+#define	MCAST_REG2	0x0002
+#define	MCAST_REG3	0x0004
+#define	MCAST_REG4	0x0006
+
+
+// Management Interface Register (MII)
+/* BANK 3 */
+#define	MII_REG		0x0008
+#define MII_MSK_CRS100	0x4000 // Disables CRS100 detection during tx half dup
+#define MII_MDOE	0x0008 // MII Output Enable
+#define MII_MCLK	0x0004 // MII Clock, pin MDCLK
+#define MII_MDI		0x0002 // MII Input, pin MDI
+#define MII_MDO		0x0001 // MII Output, pin MDO
+
+
+// Revision Register
+/* BANK 3 */
+#define	REV_REG		0x000A /* ( hi: chip id   low: rev # ) */
+
+
+// Early RCV Register
+/* BANK 3 */
+/* this is NOT on SMC9192 */
+#define	ERCV_REG	0x000C
+#define ERCV_RCV_DISCRD	0x0080 // When 1 discards a packet being received
+#define ERCV_THRESHOLD	0x001F // ERCV Threshold Mask
+
+// External Register
+/* BANK 7 */
+#define	EXT_REG		0x0000
+
+
+#define CHIP_9192	3
+#define CHIP_9194	4
+#define CHIP_9195	5
+#define CHIP_9196	6
+#define CHIP_91100	7
+#define CHIP_91100FD	8
+#define CHIP_91111FD	9
+
+static const char * chip_ids[ 15 ] =  { 
+	NULL, NULL, NULL, 
+	/* 3 */ "SMC91C90/91C92",
+	/* 4 */ "SMC91C94",
+	/* 5 */ "SMC91C95",
+	/* 6 */ "SMC91C96",
+	/* 7 */ "SMC91C100", 
+	/* 8 */ "SMC91C100FD", 
+	/* 9 */ "SMC91C11xFD", 
+	NULL, NULL, 
+	NULL, NULL, NULL};  
+
+/* 
+ . Transmit status bits 
+*/
+#define TS_SUCCESS 0x0001
+#define TS_LOSTCAR 0x0400
+#define TS_LATCOL  0x0200
+#define TS_16COL   0x0010
+
+/*
+ . Receive status bits
+*/
+#define RS_ALGNERR	0x8000
+#define RS_BRODCAST	0x4000
+#define RS_BADCRC	0x2000
+#define RS_ODDFRAME	0x1000	// bug: the LAN91C111 never sets this on receive
+#define RS_TOOLONG	0x0800
+#define RS_TOOSHORT	0x0400
+#define RS_MULTICAST	0x0001
+#define RS_ERRORS	(RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT) 
+
+
+// PHY Types
+enum {
+	PHY_LAN83C183 = 1,	// LAN91C111 Internal PHY
+	PHY_LAN83C180
+};
+
+
+// PHY Register Addresses (LAN91C111 Internal PHY)
+
+// PHY Control Register
+#define PHY_CNTL_REG		0x00
+#define PHY_CNTL_RST		0x8000	// 1=PHY Reset
+#define PHY_CNTL_LPBK		0x4000	// 1=PHY Loopback
+#define PHY_CNTL_SPEED		0x2000	// 1=100Mbps, 0=10Mpbs
+#define PHY_CNTL_ANEG_EN	0x1000 // 1=Enable Auto negotiation
+#define PHY_CNTL_PDN		0x0800	// 1=PHY Power Down mode
+#define PHY_CNTL_MII_DIS	0x0400	// 1=MII 4 bit interface disabled
+#define PHY_CNTL_ANEG_RST	0x0200 // 1=Reset Auto negotiate
+#define PHY_CNTL_DPLX		0x0100	// 1=Full Duplex, 0=Half Duplex
+#define PHY_CNTL_COLTST		0x0080	// 1= MII Colision Test
+
+// PHY Status Register
+#define PHY_STAT_REG		0x01
+#define PHY_STAT_CAP_T4		0x8000	// 1=100Base-T4 capable
+#define PHY_STAT_CAP_TXF	0x4000	// 1=100Base-X full duplex capable
+#define PHY_STAT_CAP_TXH	0x2000	// 1=100Base-X half duplex capable
+#define PHY_STAT_CAP_TF		0x1000	// 1=10Mbps full duplex capable
+#define PHY_STAT_CAP_TH		0x0800	// 1=10Mbps half duplex capable
+#define PHY_STAT_CAP_SUPR	0x0040	// 1=recv mgmt frames with not preamble
+#define PHY_STAT_ANEG_ACK	0x0020	// 1=ANEG has completed
+#define PHY_STAT_REM_FLT	0x0010	// 1=Remote Fault detected
+#define PHY_STAT_CAP_ANEG	0x0008	// 1=Auto negotiate capable
+#define PHY_STAT_LINK		0x0004	// 1=valid link
+#define PHY_STAT_JAB		0x0002	// 1=10Mbps jabber condition
+#define PHY_STAT_EXREG		0x0001	// 1=extended registers implemented
+
+// PHY Identifier Registers
+#define PHY_ID1_REG		0x02	// PHY Identifier 1
+#define PHY_ID2_REG		0x03	// PHY Identifier 2
+
+// PHY Auto-Negotiation Advertisement Register
+#define PHY_AD_REG		0x04
+#define PHY_AD_NP		0x8000	// 1=PHY requests exchange of Next Page
+#define PHY_AD_ACK		0x4000	// 1=got link code word from remote
+#define PHY_AD_RF		0x2000	// 1=advertise remote fault
+#define PHY_AD_T4		0x0200	// 1=PHY is capable of 100Base-T4
+#define PHY_AD_TX_FDX		0x0100	// 1=PHY is capable of 100Base-TX FDPLX
+#define PHY_AD_TX_HDX		0x0080	// 1=PHY is capable of 100Base-TX HDPLX
+#define PHY_AD_10_FDX		0x0040	// 1=PHY is capable of 10Base-T FDPLX
+#define PHY_AD_10_HDX		0x0020	// 1=PHY is capable of 10Base-T HDPLX
+#define PHY_AD_CSMA		0x0001	// 1=PHY is capable of 802.3 CMSA
+
+// PHY Auto-negotiation Remote End Capability Register
+#define PHY_RMT_REG		0x05
+// Uses same bit definitions as PHY_AD_REG
+
+// PHY Configuration Register 1
+#define PHY_CFG1_REG		0x10
+#define PHY_CFG1_LNKDIS		0x8000	// 1=Rx Link Detect Function disabled
+#define PHY_CFG1_XMTDIS		0x4000	// 1=TP Transmitter Disabled
+#define PHY_CFG1_XMTPDN		0x2000	// 1=TP Transmitter Powered Down
+#define PHY_CFG1_BYPSCR		0x0400	// 1=Bypass scrambler/descrambler
+#define PHY_CFG1_UNSCDS		0x0200	// 1=Unscramble Idle Reception Disable
+#define PHY_CFG1_EQLZR		0x0100	// 1=Rx Equalizer Disabled
+#define PHY_CFG1_CABLE		0x0080	// 1=STP(150ohm), 0=UTP(100ohm)
+#define PHY_CFG1_RLVL0		0x0040	// 1=Rx Squelch level reduced by 4.5db
+#define PHY_CFG1_TLVL_SHIFT	2	// Transmit Output Level Adjust
+#define PHY_CFG1_TLVL_MASK	0x003C
+#define PHY_CFG1_TRF_MASK	0x0003	// Transmitter Rise/Fall time
+
+
+// PHY Configuration Register 2
+#define PHY_CFG2_REG		0x11
+#define PHY_CFG2_APOLDIS	0x0020	// 1=Auto Polarity Correction disabled
+#define PHY_CFG2_JABDIS		0x0010	// 1=Jabber disabled
+#define PHY_CFG2_MREG		0x0008	// 1=Multiple register access (MII mgt)
+#define PHY_CFG2_INTMDIO	0x0004	// 1=Interrupt signaled with MDIO pulseo
+
+// PHY Status Output (and Interrupt status) Register
+#define PHY_INT_REG		0x12	// Status Output (Interrupt Status)
+#define PHY_INT_INT		0x8000	// 1=bits have changed since last read
+#define	PHY_INT_LNKFAIL		0x4000	// 1=Link Not detected
+#define PHY_INT_LOSSSYNC	0x2000	// 1=Descrambler has lost sync
+#define PHY_INT_CWRD		0x1000	// 1=Invalid 4B5B code detected on rx
+#define PHY_INT_SSD		0x0800	// 1=No Start Of Stream detected on rx
+#define PHY_INT_ESD		0x0400	// 1=No End Of Stream detected on rx
+#define PHY_INT_RPOL		0x0200	// 1=Reverse Polarity detected
+#define PHY_INT_JAB		0x0100	// 1=Jabber detected
+#define PHY_INT_SPDDET		0x0080	// 1=100Base-TX mode, 0=10Base-T mode
+#define PHY_INT_DPLXDET		0x0040	// 1=Device in Full Duplex
+
+// PHY Interrupt/Status Mask Register
+#define PHY_MASK_REG		0x13	// Interrupt Mask
+// Uses the same bit definitions as PHY_INT_REG
+
+
+
+/*-------------------------------------------------------------------------
+ .  I define some macros to make it easier to do somewhat common
+ . or slightly complicated, repeated tasks. 
+ --------------------------------------------------------------------------*/
+
+/* select a register bank, 0 to 3  */
+
+#define SMC_SELECT_BANK(x)  { outw( x, ioaddr + BANK_SELECT ); } 
+
+
+/*
+ *	Some boards have the SMC91c111 connected in such a way thay
+ *	they can only be used with 16bit reads and writes. This is
+ *	not really a problem (and certainly has no performance impact).
+ */
+#if defined(CONFIG_SMC16BITONLY)
+
+/* this enables an interrupt in the interrupt mask register */
+#define SMC_ENABLE_INT(x) {\
+		unsigned short mask;\
+		SMC_SELECT_BANK(2);\
+		mask = inb( ioaddr + IM_REG );\
+		mask |= (x);\
+		outw( mask << 8, ioaddr + INT_REG ); \
+}
+
+/* this disables an interrupt from the interrupt mask register */
+#define SMC_DISABLE_INT(x) {\
+		unsigned short mask;\
+		SMC_SELECT_BANK(2);\
+		mask = inb( ioaddr + IM_REG );\
+		mask &= ~(x);\
+		outw( mask << 8, ioaddr + IM_REG ); \
+}
+
+#else
+
+/* this enables an interrupt in the interrupt mask register */
+#define SMC_ENABLE_INT(x) {\
+		unsigned char mask;\
+		SMC_SELECT_BANK(2);\
+		mask = inb( ioaddr + IM_REG );\
+		mask |= (x);\
+		outb( mask, ioaddr + IM_REG ); \
+}
+
+/* this disables an interrupt from the interrupt mask register */
+
+#define SMC_DISABLE_INT(x) {\
+		unsigned char mask;\
+		SMC_SELECT_BANK(2);\
+		mask = inb( ioaddr + IM_REG );\
+		mask &= ~(x);\
+		outb( mask, ioaddr + IM_REG ); \
+}
+
+#endif	/* CONFIG_SMC16BITONLY */
+
+
+/*----------------------------------------------------------------------
+ . Define the interrupts that I want to receive from the card
+ . 
+ . I want: 
+ .  IM_EPH_INT, for nasty errors
+ .  IM_RCV_INT, for happy received packets
+ .  IM_RX_OVRN_INT, because I have to kick the receiver
+ .  IM_MDINT, for PHY Register 18 Status Changes
+ --------------------------------------------------------------------------*/
+#define SMC_INTERRUPT_MASK   (IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | \
+	IM_MDINT) 
+
+
+#ifdef CONFIG_SYSCTL
+
+
+/*
+ * Declarations for the sysctl interface, which allows users the ability to
+ * control the finer aspects of the LAN91C111 chip.  Since the smc
+ * module currently registers its sysctl table dynamically, the sysctl path
+ * for module FOO is /proc/sys/dev/ethX/FOO
+ */
+#define CTL_SMC         (CTL_BUS+1389)      // arbitrary and hopefully unused
+
+enum {
+	CTL_SMC_INFO = 1,	// Sysctl files information
+	CTL_SMC_SWVER,		// Driver Software Version Info
+	CTL_SMC_SWFDUP,		// Switched Full Duplex Mode
+	CTL_SMC_EPHLOOP,	// EPH Block Internal Loopback
+	CTL_SMC_MIIOP,		// MII Operation
+	CTL_SMC_AUTONEG,	// Auto-negotiate Mode
+	CTL_SMC_RFDUPLX,	// Request Full Duplex Mode
+	CTL_SMC_RSPEED,		// Request Speed Selection
+	CTL_SMC_AFDUPLX,	// Actual Full Duplex Mode
+	CTL_SMC_ASPEED,		// Actual Speed Selection
+	CTL_SMC_LNKFAIL,	// Link Failed
+	CTL_SMC_FORCOL,		// Force a Collision
+	CTL_SMC_FILTCAR,	// Filter Carrier
+	CTL_SMC_FREEMEM,	// Free Buffer Memory
+	CTL_SMC_TOTMEM,		// Total Buffer Memory
+	CTL_SMC_LEDA,		// Output of LED-A
+	CTL_SMC_LEDB,		// Output of LED-B
+	CTL_SMC_CHIPREV,	// LAN91C111 Chip Revision ID
+#ifdef SMC_DEBUG
+	// Register access for debugging
+	CTL_SMC_REG_BSR,	// Bank Select
+	CTL_SMC_REG_TCR,	// Transmit Control
+	CTL_SMC_REG_ESR,	// EPH Status
+	CTL_SMC_REG_RCR,	// Receive Control
+	CTL_SMC_REG_CTRR,	// Counter
+	CTL_SMC_REG_MIR,	// Memory Information
+	CTL_SMC_REG_RPCR,	// Receive/Phy Control
+	CTL_SMC_REG_CFGR,	// Configuration
+	CTL_SMC_REG_BAR,	// Base Address
+	CTL_SMC_REG_IAR0,	// Individual Address 0
+	CTL_SMC_REG_IAR1,	// Individual Address 1 
+	CTL_SMC_REG_IAR2,	// Individual Address 2
+	CTL_SMC_REG_GPR,	// General Purpose
+	CTL_SMC_REG_CTLR,	// Control
+	CTL_SMC_REG_MCR,	// MMU Command
+	CTL_SMC_REG_PNR,	// Packet Number
+	CTL_SMC_REG_FPR,	// FIFO Ports
+	CTL_SMC_REG_PTR,	// Pointer
+	CTL_SMC_REG_DR,		// Data 
+	CTL_SMC_REG_ISR,	// Interrupt Status
+	CTL_SMC_REG_MTR1,	// Multicast Table Entry 1
+	CTL_SMC_REG_MTR2,	// Multicast Table Entry 2
+	CTL_SMC_REG_MTR3,	// Multicast Table Entry 3
+	CTL_SMC_REG_MTR4,	// Multicast Table Entry 4
+	CTL_SMC_REG_MIIR,	// Management Interface
+	CTL_SMC_REG_REVR,	// Revision
+	CTL_SMC_REG_ERCVR,	// Early RCV
+	CTL_SMC_REG_EXTR,	// External
+	CTL_SMC_PHY_CTRL,	// PHY Control
+	CTL_SMC_PHY_STAT,	// PHY Status
+	CTL_SMC_PHY_ID1,	// PHY ID1
+	CTL_SMC_PHY_ID2,	// PHY ID2
+	CTL_SMC_PHY_ADC,	// PHY Advertise Capability
+	CTL_SMC_PHY_REMC,	// PHY Advertise Capability
+	CTL_SMC_PHY_CFG1,	// PHY Configuration 1
+	CTL_SMC_PHY_CFG2,	// PHY Configuration 2
+	CTL_SMC_PHY_INT,	// PHY Interrupt/Status Output
+	CTL_SMC_PHY_MASK,	// PHY Interrupt/Status Mask
+#endif
+	// ---------------------------------------------------
+	CTL_SMC_LAST_ENTRY	// Add new entries above the line
+};
+
+#endif // CONFIG_SYSCTL
+ 
+#endif  /* _SMC_91111_H_ */
+
+
diff -urN linux-2.4.29/drivers/net/smc9194.c linux-2.4.29-uc1/drivers/net/smc9194.c
--- linux-2.4.29/drivers/net/smc9194.c	2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/smc9194.c	2005-06-14 02:12:10.000000000 +0100
@@ -51,7 +51,6 @@
  .				 allocation
  .      08/20/00  Arnaldo Melo   fix kfree(skb) in smc_hardware_send_packet
  .      12/15/00  Christian Jullien fix "Warning: kfree_skb on hard IRQ"
- .      11/08/01 Matt Domsch     Use common crc32 function
  ----------------------------------------------------------------------------*/
 
 static const char version[] =
@@ -74,12 +73,46 @@
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <linux/errno.h>
-
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/delay.h>
 
 #include "smc9194.h"
+
+#ifdef CONFIG_M68EZ328
+#include <asm/MC68EZ328.h>
+#include <asm/irq.h>
+#include <asm/mcfsmc.h>
+unsigned char	smc_defethaddr[] = { 0x00, 0x10, 0x8b, 0xf1, 0xda, 0x01 };
+#define NO_AUTOPROBE
+#endif
+
+#ifdef CONFIG_COLDFIRE
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfsmc.h>
+
+unsigned char	smc_defethaddr[] = { 0x00, 0xd0, 0xcf, 0x00, 0x00, 0x01 };
+
+#define NO_AUTOPROBE
+#endif
+
+#ifdef CONFIG_SH_KEYWEST
+#include <asm/keywest.h>
+#define NO_AUTOPROBE
+#define PHY_SETUP
+#endif
+
+#ifdef CONFIG_LEDMAN
+#include <linux/ledman.h>
+#endif
+
+#if defined(CONFIG_CPU_H8300H) || defined(CONFIG_CPU_H8S)
+#include <asm/h8300_smsc.h>
+#define NO_AUTOPROBE
+#endif
+
 /*------------------------------------------------------------------------
  .
  . Configuration options, for the experienced user to change.
@@ -90,22 +123,59 @@
  . Do you want to use 32 bit xfers?  This should work on all chips, as
  . the chipset is designed to accommodate them.
 */
-#ifdef __sh__
+#if (defined(__sh__) && !defined(CONFIG_SH_KEYWEST)) || \
+    defined(__H8300H__) || defined(__H8300S__)
 #undef USE_32_BIT
 #else
 #define USE_32_BIT 1
 #endif
 
 /*
+ .A typedef so we can change what IO looks like easily
+*/
+typedef unsigned int smcio_t;
+
+/*
  .the SMC9194 can be at any of the following port addresses.  To change,
  .for a slightly different card, you can add it to the array.  Keep in
  .mind that the array must end in zero.
 */
+
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68EZ328) || \
+	defined(CONFIG_SH_KEYWEST)
+
+#ifdef CONFIG_NETtel
+static smcio_t smc_portlist[]      = { 0x30600300, 0x30600000, 0 };
+static unsigned int smc_irqlist[]  = {         29,         27, 0 };
+#elif defined(CONFIG_SH_KEYWEST)
+static smcio_t smc_portlist[]      = { KEYWEST_ETHR, 0 };
+static unsigned int smc_irqlist[]  = { IRQ4_IRQ,     0 };
+#elif defined(CONFIG_M68EZ328)
+/* make sure that you program Port D selects to allow the interrupts! */
+static smcio_t smc_portlist[]      = { 0x2000300,    0x2000320,    0 };
+static unsigned int smc_irqlist[]  = { IRQ1_IRQ_NUM, IRQ2_IRQ_NUM, 0 };
+#elif defined(CONFIG_CLEOPATRA)
+static unsigned int smc_portlist[] = { 0x30600300, 0 };
+static unsigned int smc_irqlist[]  = {         29, 0 };
+#else
+static smcio_t smc_portlist[]      = { 0x30600300, 0 };
+static unsigned int smc_irqlist[]  = {         27, 0 };
+#endif
+
+#elif defined(CONFIG_BOARD_EDOSK2674)
+static smcio_t smc_portlist[]      = { SMSC_BASE, 0 };
+static unsigned int smc_irqlist[]  = { SMSC_IRQ, 0 };
+#else
+
 static unsigned int smc_portlist[] __initdata = { 
 	0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
 	0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, 0
 };
 
+#endif
+
+static unsigned int smc_found[]    = {          0,          0, 0 };
+
 /*
  . Wait time for memory to be free.  This probably shouldn't be
  . tuned that much, as waiting for this means nothing else happens
@@ -259,7 +329,7 @@
  . Test if a given location contains a chip, trying to cause as
  . little damage as possible if it's not a SMC chip.
 */
-static int smc_probe(struct net_device *dev, int ioaddr);
+static int smc_probe(struct net_device *dev, smcio_t ioaddr);
 
 /*
  . A rather simple routine to print out a packet for debugging purposes.
@@ -280,20 +350,31 @@
 static int  smc_wait_to_send_packet( struct sk_buff * skb, struct net_device *dev );
 
 /* this does a soft reset on the device */
-static void smc_reset( int ioaddr );
+static void smc_reset( smcio_t ioaddr );
 
 /* Enable Interrupts, Receive, and Transmit */
-static void smc_enable( int ioaddr );
+static void smc_enable( smcio_t ioaddr );
 
 /* this puts the device in an inactive state */
-static void smc_shutdown( int ioaddr );
+static void smc_shutdown( smcio_t ioaddr );
 
+#ifndef NO_AUTOPROBE
 /* This routine will find the IRQ of the driver if one is not
  . specified in the input to the device.  */
-static int smc_findirq( int ioaddr );
+static int smc_findirq( smcio_t ioaddr );
+#endif
+
+#ifdef PHY_SETUP
+static void clkmdio(smcio_t ioaddr, unsigned int MGMTData);
+static unsigned PHYAccess(smcio_t ioaddr, unsigned char PHYAdd,
+				unsigned char RegAdd, unsigned char OPCode, unsigned wData);
+static unsigned char DetectPHY(smcio_t ioaddr, unsigned long *OUI,
+						unsigned char *Model, unsigned char *Revision);
+static int setup_phy(smcio_t ioaddr);
+#endif
 
 /*
- . Function: smc_reset( int ioaddr )
+ . Function: smc_reset( smcio_t ioaddr )
  . Purpose:
  .  	This sets the SMC91xx chip to its normal state, hopefully from whatever
  . 	mess that any other DOS driver has put it in.
@@ -309,7 +390,7 @@
  .	5.  clear all interrupts
  .
 */
-static void smc_reset( int ioaddr )
+static void smc_reset( smcio_t ioaddr )
 {
 	/* This resets the registers mostly to defaults, but doesn't
 	   affect EEPROM.  That seems unnecessary */
@@ -330,6 +411,10 @@
 	SMC_SELECT_BANK( 1 );
 	outw( inw( ioaddr + CONTROL ) | CTL_AUTO_RELEASE , ioaddr + CONTROL );
 
+#if defined(CONFIG_LEDMAN) && defined(CONFIG_SNAPGEAR)
+	outw( inw( ioaddr + CONTROL ) | CTL_LE_ENABLE , ioaddr + CONTROL );	
+#endif
+
 	/* Reset the MMU */
 	SMC_SELECT_BANK( 2 );
 	outw( MC_RESET, ioaddr + MMU_CMD );
@@ -338,7 +423,7 @@
 	   but this is a place where future chipsets _COULD_ break.  Be wary
  	   of issuing another MMU command right after this */
 
-	outb( 0, ioaddr + INT_MASK );
+	SMC_SET_INT( 0 );
 }
 
 /*
@@ -349,7 +434,7 @@
  .	2.  Enable the receiver
  .	3.  Enable interrupts
 */
-static void smc_enable( int ioaddr )
+static void smc_enable( smcio_t ioaddr )
 {
 	SMC_SELECT_BANK( 0 );
 	/* see the header file for options in TCR/RCR NORMAL*/
@@ -358,7 +443,7 @@
 
 	/* now, enable interrupts */
 	SMC_SELECT_BANK( 2 );
-	outb( SMC_INTERRUPT_MASK, ioaddr + INT_MASK );
+	SMC_SET_INT( SMC_INTERRUPT_MASK );
 }
 
 /*
@@ -375,16 +460,21 @@
  .	the manual says that it will wake up in response to any I/O requests
  .	in the register space.   Empirical results do not show this working.
 */
-static void smc_shutdown( int ioaddr )
+static void smc_shutdown( smcio_t ioaddr )
 {
 	/* no more interrupts for me */
 	SMC_SELECT_BANK( 2 );
-	outb( 0, ioaddr + INT_MASK );
+	SMC_SET_INT( 0 );
 
 	/* and tell the card to stay away from that nasty outside world */
 	SMC_SELECT_BANK( 0 );
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68EZ328)
+	outw( RCR_CLEAR, ioaddr + RCR );
+	outw( TCR_CLEAR, ioaddr + TCR );
+#else
 	outb( RCR_CLEAR, ioaddr + RCR );
 	outb( TCR_CLEAR, ioaddr + TCR );
+#endif /* CONFIG_COLDFIRE */
 #if 0
 	/* finally, shut the chip down */
 	SMC_SELECT_BANK( 1 );
@@ -394,7 +484,7 @@
 
 
 /*
- . Function: smc_setmulticast( int ioaddr, int count, dev_mc_list * adds )
+ . Function: smc_setmulticast( smcio_t ioaddr, int count, dev_mc_list * adds )
  . Purpose:
  .    This sets the internal hardware table to filter out unwanted multicast
  .    packets before they take up memory.
@@ -411,7 +501,7 @@
 */
 
 
-static void smc_setmulticast( int ioaddr, int count, struct dev_mc_list * addrs ) {
+static void smc_setmulticast( smcio_t ioaddr, int count, struct dev_mc_list * addrs ) {
 	int			i;
 	unsigned char		multicast_table[ 8 ];
 	struct dev_mc_list	* cur_addr;
@@ -444,11 +534,18 @@
 	/* now, the table can be loaded into the chipset */
 	SMC_SELECT_BANK( 3 );
 
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68EZ328)
+	for ( i = 0; i < 8 ; i += 2 ) {
+		outw(((multicast_table[i+1]<<8)+(multicast_table[i])), ioaddr+MULTICAST1+i );
+	}
+#else
 	for ( i = 0; i < 8 ; i++ ) {
 		outb( multicast_table[i], ioaddr + MULTICAST1 + i );
 	}
+#endif
 }
 
+
 /*
  . Function: smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * )
  . Purpose:
@@ -468,7 +565,7 @@
 static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * dev )
 {
 	struct smc_local *lp 	= (struct smc_local *)dev->priv;
-	unsigned short ioaddr 	= dev->base_addr;
+	smcio_t ioaddr		= dev->base_addr;
 	word 			length;
 	unsigned short 		numPages;
 	word			time_out;
@@ -542,7 +639,7 @@
 		status = inb( ioaddr + INTERRUPT );
 		if ( status & IM_ALLOC_INT ) {
 			/* acknowledge the interrupt */
-			outb( IM_ALLOC_INT, ioaddr + INTERRUPT );
+			SMC_ACK_INT( IM_ALLOC_INT );
   			break;
 		}
    	} while ( -- time_out );
@@ -584,7 +681,7 @@
 	byte	 		packet_no;
 	struct sk_buff * 	skb = lp->saved_skb;
 	word			length;
-	unsigned short		ioaddr;
+	smcio_t			ioaddr;
 	byte			* buf;
 
 	ioaddr = dev->base_addr;
@@ -608,7 +705,11 @@
 	}
 
 	/* we have a packet address, so tell the card to use it */
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68EZ328)
+	outw( packet_no, ioaddr + PNR_ARR );
+#else
 	outb( packet_no, ioaddr + PNR_ARR );
+#endif
 
 	/* point to the beginning of the packet */
 	outw( PTR_AUTOINC , ioaddr + POINTER );
@@ -620,14 +721,23 @@
 
 	/* send the packet length ( +6 for status, length and ctl byte )
  	   and the status word ( set to zeros ) */
+
 #ifdef USE_32_BIT
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68EZ328)
+	outl(  (length +6 ) , ioaddr + DATA_1 );
+#else
 	outl(  (length +6 ) << 16 , ioaddr + DATA_1 );
+#endif
 #else
 	outw( 0, ioaddr + DATA_1 );
 	/* send the packet length ( +6 for status words, length, and ctl*/
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68EZ328) || defined(CONFIG_CPU_H8S)
+	outw( (length+6) & 0xFFFF, ioaddr + DATA_1 );
+#else
 	outb( (length+6) & 0xFF,ioaddr + DATA_1 );
 	outb( (length+6) >> 8 , ioaddr + DATA_1 );
 #endif
+#endif
 
 	/* send the actual data
 	 . I _think_ it's faster to send the longs first, and then
@@ -639,7 +749,11 @@
 #ifdef USE_32_BIT
 	if ( length & 0x2  ) {
 		outsl(ioaddr + DATA_1, buf,  length >> 2 );
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68EZ328)
+		outwd( *((word *)(buf + (length & 0xFFFFFFFC))),ioaddr +DATA_1);
+#else
 		outw( *((word *)(buf + (length & 0xFFFFFFFC))),ioaddr +DATA_1);
+#endif
 	}
 	else
 		outsl(ioaddr + DATA_1, buf,  length >> 2 );
@@ -651,8 +765,12 @@
 	if ( (length & 1) == 0 ) {
 		outw( 0, ioaddr + DATA_1 );
 	} else {
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68EZ328)
+		outw( buf[length -1 ] | (0x20 << 8), ioaddr + DATA_1);
+#else
 		outb( buf[length -1 ], ioaddr + DATA_1 );
 		outb( 0x20, ioaddr + DATA_1);
+#endif
 	}
 
 	/* enable the interrupts */
@@ -692,7 +810,8 @@
 int __init smc_init(struct net_device *dev)
 {
 	int i;
-	int base_addr = dev->base_addr;
+	/*  check for special auto-probe address */
+	int base_addr = (dev && dev->base_addr != 0xffe0) ? dev->base_addr : 0;
 
 	SET_MODULE_OWNER(dev);
 
@@ -703,9 +822,22 @@
 		return -ENXIO;
 
 	/* check every ethernet address */
-	for (i = 0; smc_portlist[i]; i++)
-		if (smc_probe(dev, smc_portlist[i]) == 0)
+	for (i = 0; smc_portlist[i]; i++) {
+#ifdef CONFIG_NETtel
+		smc_remap(smc_portlist[i]);
+#endif
+#if defined(NO_AUTOPROBE)
+		dev->irq = smc_irqlist[i];
+		if (smc_found[i])
+			continue;
+#endif
+		if (smc_probe(dev, smc_portlist[i]) == 0) {
+#if defined(NO_AUTOPROBE)
+			smc_found[i] = 1;
+#endif
 			return 0;
+		}
+	}
 
 	/* couldn't find anything */
 	return -ENODEV;
@@ -718,7 +850,8 @@
  . interrupt, so an auto-detect routine can detect it, and find the IRQ,
  ------------------------------------------------------------------------
 */
-int __init smc_findirq( int ioaddr )
+#ifndef NO_AUTOPROBE
+int __init smc_findirq( smcio_t ioaddr )
 {
 	int	timeout = 20;
 	unsigned long cookie;
@@ -740,7 +873,7 @@
 
 	SMC_SELECT_BANK(2);
 	/* enable ALLOCation interrupts ONLY */
-	outb( IM_ALLOC_INT, ioaddr + INT_MASK );
+	SMC_SET_INT( IM_ALLOC_INT );
 
 	/*
  	 . Allocate 512 bytes of memory.  Note that the chip was just
@@ -775,7 +908,7 @@
 	SMC_DELAY();
 
 	/* and disable all interrupts again */
-	outb( 0, ioaddr + INT_MASK );
+	SMC_SET_INT( 0 );
 
 	/* clear hardware interrupts again, because that's how it
 	   was when I was called... */
@@ -784,9 +917,10 @@
 	/* and return what I found */
 	return probe_irq_off(cookie);
 }
+#endif /* NO_AUTOPROBE */
 
 /*----------------------------------------------------------------------
- . Function: smc_probe( int ioaddr )
+ . Function: smc_probe( smcio_t ioaddr )
  .
  . Purpose:
  .	Tests to see if a given ioaddr points to an SMC9xxx chip.
@@ -814,11 +948,17 @@
  . o  GRAB the region
  .-----------------------------------------------------------------
 */
-static int __init smc_probe(struct net_device *dev, int ioaddr)
+static int __init smc_probe(struct net_device *dev, smcio_t ioaddr)
 {
 	int i, memory, retval;
 	static unsigned version_printed;
 	unsigned int bank;
+#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || defined(CONFIG_DISKtel) || defined(CONFIG_CLEOPATRA)
+	static int nr = 0;
+#endif
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68EZ328)
+	unsigned char *ep;
+#endif
 
 	const char *version_string;
 	const char *if_string;
@@ -830,9 +970,18 @@
 	word memory_info_register;
 	word memory_cfg_register;
 
+#if !defined(CONFIG_COLDFIRE) && !defined(CONFIG_M68EZ328) && \
+    !defined(CONFIG_CPU_H8300H) && !defined(CONFIG_CPU_H8S)
 	/* Grab the region so that no one else tries to probe our ioports. */
 	if (!request_region(ioaddr, SMC_IO_EXTENT, dev->name))
 		return -EBUSY;
+#elif defined(CONFIG_COLDFIRE)
+	/*
+	 *	We need to put the SMC into 68k mode.
+	 *	Do a write before anything else.
+	 */
+	outw(0, ioaddr + BANK_SELECT);
+#endif
 
 	/* First, see if the high byte is 0x33 */
 	bank = inw( ioaddr + BANK_SELECT );
@@ -848,12 +997,14 @@
 		retval = -ENODEV;
 		goto err_out;
 	}
+
 	/* well, we've already written once, so hopefully another time won't
  	   hurt.  This time, I need to switch the bank register to bank 1,
 	   so I can access the base address register */
+#if !defined(CONFIG_CPU_H8300H) && !defined(CONFIG_CPU_H8S)
 	SMC_SELECT_BANK(1);
 	base_address_register = inw( ioaddr + BASE );
-	if ( ioaddr != ( base_address_register >> 3 & 0x3E0 ) )  {
+	if ( (ioaddr & 0x3E0) != ( base_address_register >> 3 & 0x3E0 ) )  {
 		printk(CARDNAME ": IOADDR %x doesn't match configuration (%x)."
 			"Probably not a SMC chip\n",
 			ioaddr, base_address_register >> 3 & 0x3E0 );
@@ -862,6 +1013,7 @@
 		retval = -ENODEV;
 		goto err_out;
 	}
+#endif
 
 	/*  check if the revision register is something that I recognize.
 	    These might need to be added to later, as future revisions
@@ -880,13 +1032,30 @@
 	/* at this point I'll assume that the chip is an SMC9xxx.
 	   It might be prudent to check a listing of MAC addresses
 	   against the hardware address, or do some other tests. */
-
 	if (version_printed++ == 0)
 		printk("%s", version);
 
 	/* fill in some of the fields */
 	dev->base_addr = ioaddr;
 
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68EZ328)
+#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || defined(CONFIG_DISKtel) || defined(CONFIG_CLEOPATRA)
+	/*
+	 . MAC address should be in FLASH, check that it is valid.
+	 . If good use it, otherwise use the default.
+	*/
+	ep = (unsigned char *) (0xf0006000 + (nr++ * 6));
+	if ((ep[0] == 0xff) && (ep[1] == 0xff) && (ep[2] == 0xff) &&
+	    (ep[3] == 0xff) && (ep[4] == 0xff) && (ep[5] == 0xff))
+		ep = (unsigned char *) &smc_defethaddr[0];
+	else if ((ep[0] == 0) && (ep[1] == 0) && (ep[2] == 0) &&
+	    (ep[3] == 0) && (ep[4] == 0) && (ep[5] == 0))
+		ep = (unsigned char *) &smc_defethaddr[0];
+#else
+	ep = (unsigned char *) &smc_defethaddr[0];
+#endif
+#endif
+
 	/*
  	 . Get the MAC address ( bank 1, regs 4 - 9 )
 	*/
@@ -894,11 +1063,23 @@
 	for ( i = 0; i < 6; i += 2 ) {
 		word	address;
 
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68EZ328)
+		dev->dev_addr[ i ] = ep[ i ];
+		dev->dev_addr[ i + 1 ] = ep[ i + 1 ];
+		address = (((word) ep[ i ]) << 8) | ep[ i + 1 ];
+		outw( address, ioaddr + ADDR0 + i);
+#else
 		address = inw( ioaddr + ADDR0 + i  );
 		dev->dev_addr[ i + 1] = address >> 8;
-		dev->dev_addr[ i ] = address & 0xFF;
+		dev->dev_addr[ i ] = address & 0xFF;	
+#endif
 	}
 
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68EZ328)
+	/* HACK: to support 2 ethernets when using default address! */
+	smc_defethaddr[5]++;
+#endif
+
 	/* get the memory information */
 
 	SMC_SELECT_BANK( 0 );
@@ -951,6 +1132,7 @@
 	 . what (s)he is doing.  No checking is done!!!!
  	 .
 	*/
+#ifndef NO_AUTOPROBE
 	if ( dev->irq < 2 ) {
 		int	trials;
 
@@ -968,6 +1150,13 @@
 		retval = -ENODEV;
 		goto err_out;
 	}
+#else
+	if (dev->irq == 0 ) {
+		printk(CARDNAME
+		": Autoprobing IRQs is not supported for this configuration.\n");
+		return -ENODEV;
+	}
+#endif
 
 	/* now, print out the card info, in a short format.. */
 
@@ -998,14 +1187,23 @@
 	ether_setup(dev);
 
 	/* Grab the IRQ */
-      	retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev);
-      	if (retval) {
+#ifdef CONFIG_COLDFIRE
+	mcf_autovector(dev->irq);
+    retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev);
+#elif defined(CONFIG_M68EZ328) && !defined(CONFIG_CWEZ328) && !defined(CONFIG_CWVZ328)
+	retval = request_irq(IRQ_MACHSPEC | dev->irq, &smc_interrupt,
+			IRQ_FLG_STD, dev->name, dev);
+	if (retval) panic("Unable to attach Lan91C96 intr\n");
+#else
+	retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev);
+#endif
+	if (retval) {
 		printk("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
 			dev->irq, retval);
 		kfree(dev->priv);
 		dev->priv = NULL;
   	  	goto err_out;
-      	}
+	}
 
 	dev->open		        = smc_open;
 	dev->stop		        = smc_close;
@@ -1015,6 +1213,9 @@
 	dev->get_stats			= smc_query_statistics;
 	dev->set_multicast_list 	= smc_set_multicast_list;
 
+#ifdef PHY_SETUP
+	setup_phy( ioaddr );
+#endif
 	return 0;
 
 err_out:
@@ -1067,7 +1268,7 @@
  */
 static int smc_open(struct net_device *dev)
 {
-	int	ioaddr = dev->base_addr;
+	smcio_t	ioaddr = dev->base_addr;
 
 	int	i;	/* used to set hw ethernet address */
 
@@ -1082,6 +1283,11 @@
 	/* Select which interface to use */
 
 	SMC_SELECT_BANK( 1 );
+#if defined(CONFIG_DISKtel) || defined(CONFIG_SH_KEYWEST)
+	/* Setup to use external PHY on smc91c110 */
+	outw( inw( ioaddr + CONFIG ) | CFG_NO_WAIT | CFG_MII_SELECT,
+		(ioaddr + CONFIG ));
+#else
 	if ( dev->if_port == 1 ) {
 		outw( inw( ioaddr + CONFIG ) & ~CFG_AUI_SELECT,
 			ioaddr + CONFIG );
@@ -1090,6 +1296,7 @@
 		outw( inw( ioaddr + CONFIG ) | CFG_AUI_SELECT,
 			ioaddr + CONFIG );
 	}
+#endif
 
 	/*
   		According to Becker, I have to set the hardware address
@@ -1106,6 +1313,18 @@
 	}
 	
 	netif_start_queue(dev);
+
+#if defined(CONFIG_LEDMAN) && defined(CONFIG_SNAPGEAR)
+	/*
+	 *	fix the link status LED's
+	 */
+	SMC_SELECT_BANK( 0 );
+	ledman_cmd((inw(ioaddr + EPH_STATUS) & ES_LINK_OK) == ES_LINK_OK ?
+			LEDMAN_CMD_ON : LEDMAN_CMD_OFF,
+			strcmp(dev->name, "eth0") ?
+					LEDMAN_LAN2_LINK : LEDMAN_LAN1_LINK);
+#endif
+
 	return 0;
 }
 
@@ -1147,7 +1366,7 @@
 static void smc_rcv(struct net_device *dev)
 {
 	struct smc_local *lp = (struct smc_local *)dev->priv;
-	int 	ioaddr = dev->base_addr;
+	smcio_t ioaddr = dev->base_addr;
 	int 	packet_number;
 	word	status;
 	word	packet_length;
@@ -1167,8 +1386,16 @@
 	outw( PTR_READ | PTR_RCV | PTR_AUTOINC, ioaddr + POINTER );
 
 	/* First two words are status and packet_length */
+#ifndef CONFIG_SH_KEYWEST
 	status 		= inw( ioaddr + DATA_1 );
 	packet_length 	= inw( ioaddr + DATA_1 );
+#else
+	{
+		unsigned int l = inl( ioaddr + DATA_1 );
+		status         = l & 0xffff;
+		packet_length  = l >> 16;
+	}
+#endif
 
 	packet_length &= 0x07ff;  /* mask off top bits */
 
@@ -1219,9 +1446,17 @@
 			packet_length >> 2, packet_length & 3 ));
 		insl(ioaddr + DATA_1 , data, packet_length >> 2 );
 		/* read the left over bytes */
+#ifndef CONFIG_SH_KEYWEST
 		insb( ioaddr + DATA_1, data + (packet_length & 0xFFFFFC),
 			packet_length & 0x3  );
 #else
+		if (packet_length & 3) {
+			union { unsigned int l; char data[4]; } l;
+			l.l = inl(ioaddr + DATA_1);
+			memcpy(data + (packet_length & ~0x3), l.data, packet_length & 0x3);
+		}
+#endif
+#else
 		PRINTK3((" Reading %d words and %d byte(s) \n",
 			(packet_length >> 1 ), packet_length & 1 ));
 		insw(ioaddr + DATA_1 , data, packet_length >> 1);
@@ -1272,7 +1507,7 @@
  ************************************************************************/
 static void smc_tx( struct net_device * dev )
 {
-	int	ioaddr = dev->base_addr;
+	smcio_t	ioaddr = dev->base_addr;
 	struct smc_local *lp = (struct smc_local *)dev->priv;
 	byte saved_packet;
 	byte packet_no;
@@ -1286,7 +1521,12 @@
 	packet_no &= 0x7F;
 
 	/* select this as the packet to read from */
-	outb( packet_no, ioaddr + PNR_ARR );
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68EZ328)
+	outw( packet_no, ioaddr + PNR_ARR ); 
+#else
+	outb( packet_no, ioaddr + PNR_ARR ); 
+#endif
+	
 
 	/* read the first word from this packet */
 	outw( PTR_AUTOINC | PTR_READ, ioaddr + POINTER );
@@ -1297,8 +1537,10 @@
 	lp->stats.tx_errors++;
 	if ( tx_status & TS_LOSTCAR ) lp->stats.tx_carrier_errors++;
 	if ( tx_status & TS_LATCOL  ) {
+#if 0
 		printk(KERN_DEBUG CARDNAME
 			": Late collision occurred on last xmit.\n");
+#endif
 		lp->stats.tx_window_errors++;
 	}
 #if 0
@@ -1319,7 +1561,11 @@
 	/* one less packet waiting for me */
 	lp->packets_waiting--;
 
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68EZ328)
+	outw( saved_packet, ioaddr + PNR_ARR );
+#else
 	outb( saved_packet, ioaddr + PNR_ARR );
+#endif
 	return;
 }
 
@@ -1339,13 +1585,16 @@
 static void smc_interrupt(int irq, void * dev_id,  struct pt_regs * regs)
 {
 	struct net_device *dev 	= dev_id;
-	int ioaddr 		= dev->base_addr;
+	smcio_t ioaddr 		= dev->base_addr;
 	struct smc_local *lp 	= (struct smc_local *)dev->priv;
 
 	byte	status;
 	word	card_stats;
 	byte	mask;
 	int	timeout;
+#ifdef CONFIG_LEDMAN
+	int tx;
+#endif
 	/* state registers */
 	word	saved_bank;
 	word	saved_pointer;
@@ -1361,7 +1610,7 @@
 
 	mask = inb( ioaddr + INT_MASK );
 	/* clear all interrupts */
-	outb( 0, ioaddr + INT_MASK );
+	SMC_SET_INT( 0 );
 
 
 	/* set a timeout value, so I don't stay here forever */
@@ -1374,6 +1623,10 @@
 		if (!status )
 			break;
 
+#ifdef CONFIG_LEDMAN
+		tx = 0;
+#endif
+
 		PRINTK3((KERN_WARNING CARDNAME
 			": Handling interrupt status %x \n", status ));
 
@@ -1386,7 +1639,10 @@
 			PRINTK2((KERN_WARNING CARDNAME
 				": TX ERROR handled\n"));
 			smc_tx(dev);
-			outb(IM_TX_INT, ioaddr + INTERRUPT );
+			SMC_ACK_INT( IM_TX_INT );
+#ifdef CONFIG_LEDMAN
+			tx = 1;
+#endif
 		} else if (status & IM_TX_EMPTY_INT ) {
 			/* update stats */
 			SMC_SELECT_BANK( 0 );
@@ -1402,11 +1658,14 @@
 			SMC_SELECT_BANK( 2 );
 			PRINTK2((KERN_WARNING CARDNAME
 				": TX_BUFFER_EMPTY handled\n"));
-			outb( IM_TX_EMPTY_INT, ioaddr + INTERRUPT );
+			SMC_ACK_INT( IM_TX_EMPTY_INT );
 			mask &= ~IM_TX_EMPTY_INT;
 			lp->stats.tx_packets += lp->packets_waiting;
+			lp->stats.tx_bytes += lp->saved_skb->len;
 			lp->packets_waiting = 0;
-
+#ifdef CONFIG_LEDMAN
+			tx = 1;
+#endif
 		} else if (status & IM_ALLOC_INT ) {
 			PRINTK2((KERN_DEBUG CARDNAME
 				": Allocation interrupt \n"));
@@ -1422,22 +1681,50 @@
 			netif_wake_queue(dev);
 			
 			PRINTK2((CARDNAME": Handoff done successfully.\n"));
+#ifdef CONFIG_LEDMAN
+			tx = 1;
+#endif
 		} else if (status & IM_RX_OVRN_INT ) {
 			lp->stats.rx_errors++;
 			lp->stats.rx_fifo_errors++;
-			outb( IM_RX_OVRN_INT, ioaddr + INTERRUPT );
+			SMC_ACK_INT( IM_RX_OVRN_INT );
 		} else if (status & IM_EPH_INT ) {
+#if defined(CONFIG_LEDMAN) && defined(CONFIG_SNAPGEAR)
+			SMC_SELECT_BANK( 0 );
+			ledman_cmd((inw(ioaddr + EPH_STATUS) & ES_LINK_OK) == ES_LINK_OK ?
+					LEDMAN_CMD_ON : LEDMAN_CMD_OFF,
+					strcmp(dev->name, "eth0")?LEDMAN_LAN2_LINK:LEDMAN_LAN1_LINK);
+			SMC_SELECT_BANK( 1 );
+			/* ACK it */
+			outw(inw(ioaddr + CONTROL) & ~CTL_LE_ENABLE, ioaddr + CONTROL);	
+			outw(inw(ioaddr + CONTROL) | CTL_LE_ENABLE, ioaddr + CONTROL);	
+			SMC_SELECT_BANK( 2 );
+			SMC_ACK_INT( IM_EPH_INT );
+			continue; /* do not turn the TX/RX leds on */
+#else
 			PRINTK((CARDNAME ": UNSUPPORTED: EPH INTERRUPT \n"));
+#endif
 		} else if (status & IM_ERCV_INT ) {
 			PRINTK((CARDNAME ": UNSUPPORTED: ERCV INTERRUPT \n"));
-			outb( IM_ERCV_INT, ioaddr + INTERRUPT );
+			SMC_ACK_INT( IM_ERCV_INT );
 		}
+#ifdef CONFIG_LEDMAN
+		if (tx) {
+			ledman_cmd(LEDMAN_CMD_SET,
+					strcmp(dev->name, "eth0") == 0 ? LEDMAN_LAN1_TX :
+						LEDMAN_LAN2_TX);
+		} else {
+			ledman_cmd(LEDMAN_CMD_SET,
+					strcmp(dev->name, "eth0") == 0 ? LEDMAN_LAN1_RX :
+						LEDMAN_LAN2_RX);
+		}
+#endif
 	} while ( timeout -- );
 
 
 	/* restore state register */
 	SMC_SELECT_BANK( 2 );
-	outb( mask, ioaddr + INT_MASK );
+	SMC_SET_INT( mask );
 
 	PRINTK3(( KERN_WARNING CARDNAME ": MASK is now %x \n", mask ));
 	outw( saved_pointer, ioaddr + POINTER );
@@ -1462,6 +1749,11 @@
 	/* clear everything */
 	smc_shutdown( dev->base_addr );
 
+#if defined(CONFIG_LEDMAN) && defined(CONFIG_SNAPGEAR)
+	ledman_cmd(LEDMAN_CMD_OFF,
+		strcmp(dev->name, "eth0")?LEDMAN_LAN2_LINK : LEDMAN_LAN1_LINK);
+#endif
+
 	/* Update the statistics here. */
 	return 0;
 }
@@ -1486,7 +1778,7 @@
 */
 static void smc_set_multicast_list(struct net_device *dev)
 {
-	short ioaddr = dev->base_addr;
+	smcio_t ioaddr = dev->base_addr;
 
 	SMC_SELECT_BANK(0);
 	if ( dev->flags & IFF_PROMISC )
@@ -1533,6 +1825,12 @@
 	}
 }
 
+#ifdef PHY_SETUP
+static int phy_delay1 = 4;
+static int phy_delay2 = 1;
+static int phy_delay3 = 100;
+#endif
+
 #ifdef MODULE
 
 static struct net_device devSMC9194;
@@ -1548,6 +1846,15 @@
 MODULE_PARM_DESC(irq, "SMC 99194 IRQ number");
 MODULE_PARM_DESC(ifport, "SMC 99194 interface port (0-default, 1-TP, 2-AUI)");
 
+#ifdef PHY_SETUP
+MODULE_PARM(phy_delay1, "i");
+MODULE_PARM(phy_delay2, "i");
+MODULE_PARM(phy_delay3, "i");
+MODULE_PARM_DESC(phy_delay1, "Per MII clock delay [4]");
+MODULE_PARM_DESC(phy_delay2, "General delay [1]");
+MODULE_PARM_DESC(phy_delay3, "pre probe delay [100]");
+#endif
+
 int init_module(void)
 {
 	int result;
@@ -1556,6 +1863,10 @@
 		printk(KERN_WARNING
 		CARDNAME": You shouldn't use auto-probing with insmod!\n" );
 
+#ifdef PHY_SETUP
+	printk(CARDNAME ": phy_delays %d %d %d\n", phy_delay1, phy_delay2,
+			phy_delay3);
+#endif
 	/* copy the parameters from insmod into the device structure */
 	devSMC9194.base_addr = io;
 	devSMC9194.irq       = irq;
@@ -1580,3 +1891,437 @@
 }
 
 #endif /* MODULE */
+
+
+#ifdef PHY_SETUP
+/*-----------------------------------------------------------
+ . PHY/MII setup routines
+ .
+*/
+
+#define phy_delay(x) ({ int d; for (d = 0; d < 100; d++) udelay((x) * 10); })
+
+/*
+ *	Ports for talking to the PHY/MII
+ */
+
+#define NV_CONTROL	0x10
+#define MIICTRL		0x30
+#define MIIDATA		0x34
+#define MIICFG		0x38
+
+#define MIIREAD		0x0001
+#define MIIWRITE	0x0002
+
+#define	MDO			0x01		/* MII Register bits */
+#define	MDI			0x02
+#define	MCLK		0x04
+#define	MDOE		0x08
+#define	MALL 		0x0F
+#define	OPWrite		0x01
+#define	OPRead		0x02
+
+
+#define PHY_CR			0		/* PHY Registers and bits */
+#define PHY_CR_Reset	0x8000
+#define PHY_CR_Speed	0x2000
+#define PHY_CR_Duplex	0x0100
+
+#define PHY_SR	1
+#define PHY_ID1	2
+#define PHY_ID2	3
+
+/*
+ *	PHY propietary registers
+ */
+
+#define PHY_NATIONAL_PAR			0x19
+#define PHY_NATIONAL_PAR_DUPLEX		0x0080
+#define PHY_NATIONAL_PAR_SPEED_10	0x0040
+
+#define PHY_TDK_DIAG				0x12
+#define PHY_TDK_DIAG_DUPLEX			0x0800
+#define PHY_TDK_DIAG_RATE			0x0400
+
+#define PHY_QSI_BASETX				0x1F
+#define PHY_QSI_BASETX_OPMODE_MASK	0x001c
+#define PHY_QSI_BASETX_OPMODE_10HD	(2<<0x1)
+#define PHY_QSI_BASETX_OPMODE_100HD	(2<<0x2)
+#define PHY_QSI_BASETX_OPMODE_10FD	(2<<0x5)
+#define PHY_QSI_BASETX_OPMODE_100FD	(2<<0x6)
+
+#define PHY_SEEQ_STATUS_OUTPUT		0x12
+#define PHY_SEEQ_SPD_DET			0x80
+#define PHY_SEEQ_DPLX_DET			0x40
+
+#define PHY_OUI_QSI			0x006051
+#define PHY_OUI_TDK			0x00C039
+#define PHY_OUI_MITELSMSC	0x00A087
+#define PHY_OUI_NATIONAL	0x080017
+#define PHY_OUI_SEEQSMSC	0x0005BE
+
+#define NWAY_TIMEOUT	10
+
+#define MAC_IS_FEAST()	(1)
+#define MAC_IS_EPIC()	(0)
+
+static void
+clkmdio(smcio_t ioaddr, unsigned int MGMTData)
+{
+	outw(MGMTData, ioaddr + MGMT);
+	udelay(phy_delay1);
+	outw(MGMTData | MCLK, ioaddr + MGMT);
+	udelay(phy_delay1);
+}
+
+
+static unsigned
+PHYAccess(
+	smcio_t ioaddr,
+	unsigned char PHYAdd,
+	unsigned char RegAdd,
+	unsigned char OPCode,
+	unsigned wData)
+{
+	int i;
+	unsigned MGMTval;
+
+	// Filter unused bits from input variables.
+
+	PHYAdd &= 0x1F;
+	RegAdd &= 0x1F;
+	OPCode &= 0x03;
+
+	if (MAC_IS_FEAST()) {
+		MGMTval = inw(ioaddr + MGMT) & (MALL ^ 0xFFFF);
+
+		// Output Preamble (32 '1's)
+
+		for (i = 0; i < 32; i++)
+			clkmdio(ioaddr, MGMTval | MDOE | MDO);
+
+		// Output Start of Frame ('01')
+
+		for (i = 0; i < 2; i++)
+			clkmdio(ioaddr, MGMTval | MDOE | i);
+
+		// Output OPCode ('01' for write or '10' for Read)
+
+		for (i = 1; i >= 0; i--)
+			clkmdio(ioaddr, MGMTval | MDOE | ((OPCode>>i) & 0x01) );
+
+		// Output PHY Address
+
+		for (i = 4; i >= 0; i--)
+			clkmdio(ioaddr, MGMTval | MDOE | ((PHYAdd>>i) & 0x01) );
+
+		// Output Register Address
+
+		for (i = 4; i >= 0; i--)
+			clkmdio(ioaddr, MGMTval | MDOE | ((RegAdd>>i) & 0x01) );
+
+		if (OPCode == OPRead) {
+			// Read Operation
+
+			// Implement Turnaround ('Z0')
+
+			clkmdio(ioaddr, MGMTval);
+			// clkmdio(ioaddr, MGMTval | MDOE);
+
+			// Read Data
+
+			wData = 0;
+
+			for (i = 15; i >= 0; i--) {
+				clkmdio(ioaddr, MGMTval);
+				wData |= (((inw(ioaddr + MGMT) & MDI) >> 1) << i);
+			}
+
+			// Add Idle state
+
+			clkmdio(ioaddr, MGMTval);
+
+			return (wData);
+		} else {
+			// Write Operation
+
+			// Implement Turnaround ('10')
+
+			for (i = 1; i >= 0; i--)
+				clkmdio(ioaddr, MGMTval | MDOE | ((2>>i) & 0x01));
+
+			// Write Data
+
+			for (i = 15; i >= 0; i--)
+				clkmdio(ioaddr, MGMTval | MDOE | ((wData>>i) & 0x01));
+
+			// Add Idle state
+
+			clkmdio(ioaddr, MGMTval);
+
+			return (1);
+		}
+	}
+
+	if (MAC_IS_EPIC()) {
+		if (OPCode == OPRead) {
+			// Read Operation
+			outw((((unsigned)PHYAdd)<<9) | (((unsigned)RegAdd)<<4) | MIIREAD,
+					ioaddr + MIICTRL);
+			phy_delay(phy_delay2);
+			wData = inw(MIIDATA);
+			return(wData);
+		} else {
+			// Write Operation
+			outw(wData, ioaddr + MIIDATA);
+			outw((((unsigned)PHYAdd)<<9) | (((unsigned)RegAdd)<<4) | MIIWRITE,
+					ioaddr + MIICTRL);
+			phy_delay(phy_delay2);
+			return(1);
+		}
+	}
+
+	return(1);
+
+}
+
+
+static unsigned char
+DetectPHY(
+	smcio_t ioaddr,
+	unsigned long *OUI,
+	unsigned char *Model,
+	unsigned char *Revision)
+{
+    unsigned int PhyId1, PhyId2;
+    unsigned char PhyAdd=0xff;
+    int Count;
+
+    for (Count=31; Count >= 0; Count--) {
+		PhyId1 = PHYAccess(ioaddr, Count, PHY_ID1, OPRead, 0);
+		PhyId1 = PHYAccess(ioaddr, Count, PHY_ID1, OPRead, 0);
+		PhyId2 = PHYAccess(ioaddr, Count, PHY_ID2, OPRead, 0);
+		PhyId2 = PHYAccess(ioaddr, Count, PHY_ID2, OPRead, 0);
+
+		if (PhyId1 > 0x0000 && PhyId1 < 0xffff && PhyId2 > 0x0000 &&
+			PhyId2 < 0xffff && PhyId1 != 0x8000 && PhyId2 != 0x8000) {
+			PhyAdd = (unsigned char) Count;
+			break;
+		}
+		phy_delay(phy_delay2);
+    }
+
+    *OUI =		(((unsigned long) PhyId1) << 6) | ((PhyId2 & 0xfc00) >> 10);
+    *Model =	(unsigned char) ((PhyId2 & 0x03f0) >> 4);
+    *Revision =	(unsigned char) (PhyId2 & 0x000f);
+
+    return(PhyAdd);
+}
+
+
+static int
+setup_phy(smcio_t ioaddr)
+{
+    int duplex = 0; /* 0 = Half,   !0 = Full */
+    int speed = 0;  /* 0 = 10Mbps, !0 = 100Mbps */
+    char *report = "";
+	unsigned long OUI;
+	unsigned char Model, Revision;
+
+    unsigned int i, PHYConfig, PHYConfig2, data;
+    unsigned char PHYAdd, ositech = 0;
+
+	printk("SMCPHY: ");
+#if 0
+	ositech = 1;
+#endif
+
+	//Setting the AUI Select Bit for 91C110 PCMCIA Design. 11/23/99 PG
+	if (ositech) {
+		SMC_SELECT_BANK( 1 );
+		data = inw(ioaddr + BANK_SELECT);
+		outw(data | 0x0100, ioaddr);
+	}
+
+    if (MAC_IS_FEAST())
+		SMC_SELECT_BANK ( 3 );
+
+	PHYAdd = DetectPHY(ioaddr, &OUI, &Model, &Revision);
+
+	if (PHYAdd > 31) {
+	    printk("UNRECOVERABLE ERROR: PHY is not present or not supported\n");
+	    return(-1);
+	}
+
+	//Setup NV_CONTROL for the cardbus card.
+	if (OUI == PHY_OUI_TDK)
+		outw(0x7c03, ioaddr + NV_CONTROL);
+
+	// Save Register 0.
+
+	if (OUI == PHY_OUI_TDK)
+		PHYAccess(ioaddr, PHYAdd, PHY_CR, OPRead, 0);
+	PHYConfig = PHYAccess(ioaddr, PHYAdd,PHY_CR,OPRead,0);
+
+	if (OUI == PHY_OUI_TDK) {
+		outw(0x0012, ioaddr + MIICFG);	/* Set ENABLE_694 */
+		/* if using EPIC, Hardware Reset the PHY from the MAC */
+		outw(inw(ioaddr + CONTROL) | 0x4000, ioaddr + CONTROL);
+		phy_delay(phy_delay2);
+		outw(inw(ioaddr + CONTROL) & (~0x4000), ioaddr + CONTROL);
+		phy_delay(phy_delay2);
+	}
+
+	/* Reset PHY */
+	PHYAccess(ioaddr, PHYAdd, PHY_CR, OPWrite, PHY_CR_Reset);
+	if (OUI == PHY_OUI_TDK)
+		PHYAccess(ioaddr, PHYAdd, PHY_CR, OPWrite, PHY_CR_Reset);
+
+	for (i = 0; i < 500; i++) {
+		if (OUI == PHY_OUI_TDK)
+			PHYAccess(ioaddr, PHYAdd, PHY_CR, OPRead, 0);
+
+		if (PHYAccess(ioaddr, PHYAdd, PHY_CR, OPRead, 0) & PHY_CR_Reset)
+			phy_delay(phy_delay2);
+		else
+			break;
+	}
+
+	if (i == 500) {
+		printk("UNRECOVERABLE ERROR: Could not reset PHY\n");
+		return(-1);
+	}
+
+	/* Write selected configuration to the PHY and verify it by reading back */
+	/* Set Advertising Register for all 10/100 and Half/Full combinations */
+
+	if (OUI == PHY_OUI_TDK)
+		PHYConfig = PHYAccess(ioaddr, PHYAdd, 4, OPRead, 0);
+	PHYConfig = PHYAccess(ioaddr, PHYAdd, 4, OPRead, 0);
+	PHYConfig |= 0x01e0;
+	PHYAccess(ioaddr, PHYAdd, 4, OPWrite, PHYConfig);
+	if (OUI == PHY_OUI_TDK)
+		PHYAccess(ioaddr, PHYAdd, 4, OPWrite, PHYConfig);
+
+	/* Start 1 */
+
+	/* National PHY requires clear before set 1 enable. */
+	PHYAccess(ioaddr, PHYAdd, 0, OPWrite, 0x0000);
+	PHYAccess(ioaddr, PHYAdd, 0, OPWrite, 0x1200);
+	if (OUI == PHY_OUI_TDK)
+		PHYAccess(ioaddr, PHYAdd, 0, OPWrite, 0x1200);
+
+	/* Wait for completion */
+	for (i = 0; i < NWAY_TIMEOUT * 10; i++) {
+		printk("%c\b", "|/-\\"[i&3]);
+
+		phy_delay(phy_delay3);
+
+		PHYConfig = PHYAccess(ioaddr, PHYAdd, 1, OPRead, 0);
+		PHYConfig2 = PHYAccess(ioaddr, PHYAdd, 1, OPRead, 0);
+
+		if (PHYConfig != PHYConfig2) /* Value is not stable */
+			continue;
+		if (PHYConfig & 0x0010) /* Remote Fault */
+			continue;
+		if ((PHYConfig == 0x0000) || (PHYConfig == 0xffff)) /* invalid value */
+			continue;
+		if (PHYConfig & 0x0020)
+			break;
+	}
+
+	/* Now read the results of the NWAY. */
+
+	if (OUI == PHY_OUI_TDK)
+		PHYConfig = PHYAccess(ioaddr, PHYAdd, 5, OPRead, 0);
+	PHYConfig = PHYAccess(ioaddr, PHYAdd, 5, OPRead, 0);
+
+	if (PHYConfig != 0) {
+		/* Got real NWAY information here */
+		report = "ANLPA";
+		speed = (PHYConfig & 0x0180);
+		duplex = (PHYConfig & 0x0140);
+	} else {
+		/*
+		 * ANLPA was 0 so NWAY did not complete or is not reported fine.
+		 * Get the info from propietary regs or from the control register.
+		 */
+		report = "Prop."; /* Proprietary Status */
+
+		switch (OUI) {
+		case PHY_OUI_NATIONAL:
+			PHYConfig = PHYAccess(ioaddr, PHYAdd, PHY_NATIONAL_PAR, OPRead, 0);
+			duplex = (PHYConfig & PHY_NATIONAL_PAR_DUPLEX);
+			speed = ! (PHYConfig & PHY_NATIONAL_PAR_SPEED_10);
+			break;
+
+		case PHY_OUI_TDK:
+			PHYConfig = PHYAccess(ioaddr, PHYAdd, PHY_TDK_DIAG, OPRead, 0);
+			PHYConfig = PHYAccess(ioaddr, PHYAdd, PHY_TDK_DIAG, OPRead, 0);
+			speed = ((Revision < 7) && ((PHYConfig & 0x300) == 0x300)) ||
+					((Revision >= 7) && (PHYConfig & PHY_TDK_DIAG_RATE));
+			duplex = ((Revision >= 7) && (PHYConfig & PHY_TDK_DIAG_DUPLEX));
+			break;
+
+		case PHY_OUI_QSI:
+			PHYConfig = PHYAccess(ioaddr, PHYAdd, PHY_QSI_BASETX, OPRead, 0);
+			PHYConfig &= PHY_QSI_BASETX_OPMODE_MASK;
+			duplex = (PHYConfig & PHY_QSI_BASETX_OPMODE_10FD) ||
+				(PHYConfig & PHY_QSI_BASETX_OPMODE_100FD);
+			speed = (PHYConfig & PHY_QSI_BASETX_OPMODE_100HD) ||
+				(PHYConfig & PHY_QSI_BASETX_OPMODE_100FD);
+			break;
+
+		case PHY_OUI_SEEQSMSC:
+			PHYConfig=PHYAccess(ioaddr,PHYAdd,PHY_SEEQ_STATUS_OUTPUT,OPRead,0);
+			duplex = (PHYConfig & PHY_SEEQ_DPLX_DET);
+			speed = (PHYConfig & PHY_SEEQ_SPD_DET);
+			break;
+
+		default:
+			report = "Command";
+			PHYConfig = PHYAccess(ioaddr, PHYAdd, 0, OPRead, 0);
+			speed = (PHYConfig & 0x2000);
+			duplex = (PHYConfig & 0x0100);
+			break;
+		}
+	}
+
+	/* Do we need to adjust the Carrier sense on full duplex FEAST issue ?  */
+
+	if (duplex && MAC_IS_FEAST() && (OUI == PHY_OUI_MITELSMSC))
+		PHYAccess(ioaddr, PHYAdd, 0x18, OPWrite,
+				0x0020 | PHYAccess(ioaddr, PHYAdd, 0x18, OPRead, 0));
+
+	/* Display what we learned */
+
+    printk(" %s-duplex %d Mbps ", duplex ? "Full" : "Half", speed ? 100 : 10);
+
+	if (MAC_IS_FEAST())
+		printk("FEAST ");
+	if (MAC_IS_EPIC())
+		printk("EPIC ");
+
+	switch (OUI) {
+	case PHY_OUI_QSI:       printk("QSI");                break;
+	case PHY_OUI_TDK:       printk("TDK");                break;
+	case PHY_OUI_MITELSMSC: printk("MITEL/SMSC180");      break;
+	case PHY_OUI_NATIONAL:  printk("NATIONAL");           break;
+	case PHY_OUI_SEEQSMSC:  printk("SEEQ/SMSC183");       break;
+	default:                printk("%06lX(UNKNOWN)",OUI); break;
+	}
+
+	printk(" Model=%02X Rev=%02X ", Model, Revision);
+#if DEBUG
+	printk("Addr=%02X ", PHYAdd);
+	printk("Conf=%s ", report);
+#endif
+	if (i == NWAY_TIMEOUT)
+		printk("TIMEOUT!\n");
+	else
+		printk("Done.\n");
+	return(0);
+}
+
+/*----------------------------------------------------------- */
+#endif /* PHY_SETUP */
diff -urN linux-2.4.29/drivers/net/smc9194.h linux-2.4.29-uc1/drivers/net/smc9194.h
--- linux-2.4.29/drivers/net/smc9194.h	2001-09-08 20:13:55.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/smc9194.h	2005-06-14 02:12:08.000000000 +0100
@@ -96,6 +96,8 @@
 /* BANK 1 */
 #define CONFIG			0
 #define CFG_AUI_SELECT	 	0x100
+#define	CFG_NO_WAIT		0x1000
+#define	CFG_MII_SELECT		0x8000
 #define	BASE			2
 #define	ADDR0			4
 #define	ADDR1			6
@@ -208,6 +210,44 @@
 			inw( ioaddr + RCR );\
 			inw( ioaddr + RCR );  }
 
+#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68EZ328)
+
+/* this enables an interrupt in the interrupt mask register */
+#define SMC_ENABLE_INT(x) {\
+		unsigned char mask;\
+		SMC_SELECT_BANK(2);\
+		mask = inb( ioaddr + INT_MASK );\
+		mask |= (x);\
+		outw( mask << 8, ioaddr + INTERRUPT ); \
+}
+
+/* this disables an interrupt from the interrupt mask register */
+
+#define SMC_DISABLE_INT(x) {\
+		unsigned char mask;\
+		SMC_SELECT_BANK(2);\
+		mask = inb( ioaddr + INT_MASK );\
+		mask &= ~(x);\
+		outw( mask << 8, ioaddr + INTERRUPT ); \
+}
+
+/* set the interrupt mask register */
+#define	SMC_SET_INT(x) {\
+		SMC_SELECT_BANK(2);\
+		outw( ((unsigned short) (x)) << 8, ioaddr + INTERRUPT );\
+}
+
+/* acknowledge an interrupt */
+#define	SMC_ACK_INT(x) {\
+		unsigned short val;\
+		/* assume BANK 2 selected */\
+		val = inb( ioaddr + INT_MASK );\
+		val = (val << 8) | (x);\
+		outw( val, ioaddr + INTERRUPT );\
+}
+
+#else
+
 /* this enables an interrupt in the interrupt mask register */
 #define SMC_ENABLE_INT(x) {\
 		unsigned char mask;\
@@ -227,6 +267,17 @@
 		outb( mask, ioaddr + INT_MASK ); \
 }
 
+/* set the interrupt mask register */
+#define	SMC_SET_INT(x) {\
+		SMC_SELECT_BANK(2);\
+		outb( (x), ioaddr + INT_MASK );\
+}
+
+/* acknowledge an interrupt */
+#define	SMC_ACK_INT(x)	outb( (x), ioaddr + INTERRUPT )
+
+#endif
+
 /*----------------------------------------------------------------------
  . Define the interrupts that I want to receive from the card
  . 
diff -urN linux-2.4.29/drivers/net/Space.c linux-2.4.29-uc1/drivers/net/Space.c
--- linux-2.4.29/drivers/net/Space.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/Space.c	2005-06-14 02:12:13.000000000 +0100
@@ -83,6 +83,8 @@
 extern int SK_init(struct net_device *);
 extern int seeq8005_probe(struct net_device *);
 extern int smc_init( struct net_device * );
+extern int fec_enet_init( struct net_device * );
+extern int sgiseeq_probe(struct net_device *);
 extern int atarilance_probe(struct net_device *);
 extern int sun3lance_probe(struct net_device *);
 extern int sun3_82586_probe(struct net_device *);
@@ -90,6 +92,8 @@
 extern int bionet_probe(struct net_device *);
 extern int pamsnet_probe(struct net_device *);
 extern int cs89x0_probe(struct net_device *dev);
+extern int emac_probe(struct net_device *dev);
+extern int ep93xxEth_probe(struct net_device *dev);
 extern int ethertap_probe(struct net_device *dev);
 extern int hplance_probe(struct net_device *dev);
 extern int bagetlance_probe(struct net_device *);
@@ -101,6 +105,11 @@
 extern int mac8390_probe(struct net_device *dev);
 extern int mac89x0_probe(struct net_device *dev);
 extern int mc32_probe(struct net_device *dev);
+
+/* uClinux devices */
+extern int s3c_probe(struct net_device *);
+extern int s3c2500_probe( struct net_device *dev);
+extern int c5471_net_probe(struct net_device *);
   
 /* Detachable devices ("pocket adaptors") */
 extern int de600_probe(struct net_device *);
@@ -246,7 +255,7 @@
 #ifdef CONFIG_LANCE		/* ISA/VLB (use pcnet32 for PCI cards) */
 	{lance_probe, 0},
 #endif
-#ifdef CONFIG_SMC9194
+#if defined(CONFIG_SMC9194) || defined(CONFIG_SMC91111)
 	{smc_init, 0},
 #endif
 #ifdef CONFIG_SEEQ8005 
@@ -258,6 +267,9 @@
 #ifdef CONFIG_CS89x0
  	{cs89x0_probe, 0},
 #endif
+#ifdef CONFIG_EP93XX_ETHERNET
+	{ep93xxEth_probe, 0},
+#endif
 #ifdef CONFIG_AT1700
 	{at1700_probe, 0},
 #endif
@@ -326,6 +338,15 @@
 };
 
 static struct devprobe m68k_probes[] __initdata = {
+#if defined(CONFIG_COLDFIRE) && defined(CONFIG_FEC)
+	{fec_enet_init, 0},	/* here so that we probe for multiple devices */
+#endif
+#if defined(CONFIG_COLDFIRE) && (defined(CONFIG_SMC9194) || defined(CONFIG_SMC91111))
+	{smc_init, 0},		/* here so that we probe for multiple devices */
+#endif
+#if defined(CONFIG_COLDFIRE) && defined(CONFIG_NE2000)
+	{ne_probe, 0},		/* here so that we probe for multiple devices */
+#endif
 #ifdef CONFIG_ATARILANCE	/* Lance-based Atari ethernet boards */
 	{atarilance_probe, 0},
 #endif
@@ -375,6 +396,31 @@
 	{NULL, 0},
 };
 
+static struct devprobe arm_probes[] __initdata = {
+#ifdef	CONFIG_ETH_S3C2500
+	{s3c2500_probe, 0},			/* S3C2500	*/
+#endif	
+#ifdef  CONFIG_ETH_S3C4530
+        {s3c_probe, 0},                         /* S3C4530      */
+#endif
+#ifdef CONFIG_UCCS8900                  	/* CS8900A      */
+        {cs89x0_probe, 0},
+#endif
+#ifndef CONFIG_HYPERSTONE
+#ifdef CONFIG_CS89x0
+        {cs89x0_probe, 0},
+#endif
+#endif
+#ifdef CONFIG_C5471_NET
+	{c5471_net_probe, 0},
+#endif
+#ifdef CONFIG_CNXT_EMAC				/* CX821xx      */
+	{emac_probe, 0},
+#endif
+
+        {NULL, 0},
+};
+
 /*
  * Unified ethernet device probe, segmented per architecture and
  * per bus interface. This drives the legacy devices only for now.
@@ -399,6 +445,8 @@
 		return 0;
 	if (probe_list(dev, mips_probes) == 0)
 		return 0;
+	if (probe_list(dev, arm_probes) == 0)
+		return 0;
 	if (probe_list(dev, eisa_probes) == 0)
 		return 0;
 	if (probe_list(dev, mca_probes) == 0)
diff -urN linux-2.4.29/drivers/net/uCcs8900.c linux-2.4.29-uc1/drivers/net/uCcs8900.c
--- linux-2.4.29/drivers/net/uCcs8900.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/uCcs8900.c	2005-06-14 02:12:15.000000000 +0100
@@ -0,0 +1,926 @@
+/* uCcs89x0.c: A Crystal Semiconductor CS89[02]0 driver for linux. */
+/* 
+
+	Port for uCsimm 1999 D. Jeff Dionne, Rt-Control Inc.(Arcturus Networks Inc.)
+	Port for arm7 platforms 2001 Oleksandr Zhadan, Arcturus Networks Inc.
+
+	Written 1996 by Russell Nelson, with reference to skeleton.c
+	written 1993-1994 by Donald Becker.
+
+	This software may be used and distributed according to the terms
+	of the GNU Public License, incorporated herein by reference.
+
+	The author may be reached at nelson@crynwr.com, Crynwr
+	Software, 11 Grant St., Potsdam, NY 13676
+
+  Changelog:
+
+  Mike Cruse        : mcruse@cti-ltd.com
+                    : Changes for Linux 2.0 compatibility. 
+                    : Added dev_id parameter in net_interrupt(),
+                    : request_irq() and free_irq(). Just NULL for now.
+
+  Mike Cruse        : Added MOD_INC_USE_COUNT and MOD_DEC_USE_COUNT macros
+                    : in net_open() and net_close() so kerneld would know
+                    : that the module is in use and wouldn't eject the 
+                    : driver prematurely.
+
+  Mike Cruse        : Rewrote init_module() and cleanup_module using 8390.c
+                    : as an example. Disabled autoprobing in init_module(),
+                    : not a good thing to do to other devices while Linux
+                    : is running from all accounts.
+
+  Chee Tim Loh      : cheetim_loh@innomedia.com.sg
+                    : Added support for TI TMS320DM270.
+
+*/
+
+
+/* ======================= configure the driver here ======================= */
+
+/* use 0 for production, 1 for verification, >2 for debug */
+#ifndef NET_DEBUG
+#define NET_DEBUG 1
+//#define NET_DEBUG 77
+#endif
+
+/* ======================= end of configuration ======================= */
+
+
+/* Always include 'config.h' first in case the user wants to turn on
+   or override something. */
+#include <linux/config.h>
+
+#define PRINTK(x) printk x
+
+/*
+  Sources:
+
+	Crynwr packet driver epktisa.
+
+	Crystal Semiconductor data sheets.
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#ifndef CONFIG_UCCS89x0_HW_SWAP
+#include <asm/io.h>
+#else
+#include <asm/io_hw_swap.h>
+#endif
+
+#include <asm/irq.h>
+#include <linux/errno.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include "uCcs8900.h"
+
+#ifdef CONFIG_M68328
+#include <asm/MC68328.h>
+#endif
+
+#ifdef CONFIG_M68EZ328
+#include <asm/MC68EZ328.h>
+#endif
+
+#ifdef CONFIG_M68VZ328
+#include <asm/MC68VZ328.h>
+#endif
+
+#ifdef CONFIG_M5272
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#endif
+
+#if defined(CONFIG_UCBOOTSTRAP)
+extern unsigned char cs8900a_hwaddr[6];
+#endif
+
+static char version[] __initdata=
+"cs89x0.c:v1.02 11/26/96 Russell Nelson <nelson@crynwr.com>
+cs89x0.c:68EZ328 support D. Jeff Dionne <jeff@arcturusnetworks.com> 1999
+cs89x0.c:S3C4530 support O. Zhadan <oleks@arcturusnetworks.com> 2001
+";
+
+static unsigned int net_debug = NET_DEBUG;
+
+#if defined(CONFIG_UCSIMM) || defined(CONFIG_UCDIMM)
+static unsigned int netcard_portlist[] __initdata = { 0x10000300,0,0,0,0,0,0,0};
+#elif defined (CONFIG_ARCH_DM270)
+static unsigned int netcard_portlist[] __initdata = { 0x07c00300,0,0,0,0,0,0,0};
+#elif defined (CONFIG_BOARD_EVS3C4530HEI)
+static unsigned int netcard_portlist[] __initdata = { 0x05400000,0,0,0,0,0,0,0};
+#elif defined(CONFIG_BOARD_UC5272)
+static unsigned int netcard_portlist[] __initdata = { 0x30000000, 0 };
+#else
+static unsigned int netcard_portlist[] __initdata =
+   { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
+static unsigned int cs8900_irq_map[] = {10,11,12,5};
+#endif
+
+
+/* The number of low I/O ports used by the ethercard. */
+#define NETCARD_IO_EXTENT	16
+
+/* void *irq2dev_map[1];  FIXME:  This does NOT go here */
+
+/* Information that need to be kept for each board. */
+struct net_local {
+	struct net_device_stats stats;
+	int chip_type;		/* one of: CS8900, CS8920, CS8920M */
+	char chip_revision;	/* revision letter of the chip ('A'...) */
+	int send_cmd;		/* the propercommand used to send a packet. */
+	int auto_neg_cnf;
+	int adapter_cnf;
+	int isa_config;
+	int irq_map;
+	int rx_mode;
+	int curr_rx_cfg;
+        int linectl;
+	int force;		/* force various values; see FORCE* above. */
+	spinlock_t lock;
+        int send_underrun;      /* keep track of how many underruns in a row we get */
+};
+
+
+/* Index to functions, as function prototypes. */
+
+unsigned char *get_MAC_address(char *devname);
+extern int cs89x0_probe(struct net_device *dev);
+
+static int cs89x0_probe1(struct net_device *dev, int ioaddr);
+static int net_open(struct net_device *dev);
+static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
+static void cs8900_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void set_multicast_list(struct net_device *dev);
+static void net_rx(struct net_device *dev);
+static int net_close(struct net_device *dev);
+static struct net_device_stats *net_get_stats(struct net_device *dev);
+static void reset_chip(struct net_device *dev);
+
+static int set_mac_address(struct net_device *dev, void *addr);
+
+
+/* Example routines you must write ;->. */
+#define tx_done(dev) 1
+
+
+/* Check for a network adaptor of this type, and return '0' iff one exists.
+   If dev->base_addr == 0, probe all likely locations.
+   If dev->base_addr == 1, always return failure.
+   If dev->base_addr == 2, allocate space for the device and return success
+   (detachable devices only).
+   */
+
+int __init cs89x0_probe(struct net_device *dev)
+{
+    static int i = 0; /* don't probe twice */
+    if	 ( netcard_portlist[i] )
+	 return(cs89x0_probe1(dev, netcard_portlist[i++]));
+
+    else return -ENXIO;
+}
+
+int inline
+readreg(struct net_device *dev, int portno)
+{
+	outw(portno, dev->base_addr + ADD_PORT);
+	return inw(dev->base_addr + DATA_PORT);
+}
+
+void inline
+writereg(struct net_device *dev, int portno, int value)
+{
+	outw(portno, dev->base_addr + ADD_PORT);
+	outw(value,  dev->base_addr + DATA_PORT);
+}
+
+int inline
+readword(struct net_device *dev, int portno)
+{
+	return inw(dev->base_addr + portno);
+}
+
+void inline
+writeword(struct net_device *dev, int portno, int value)
+{
+	outw(value, dev->base_addr + portno);
+}
+
+/* This is the real probe routine.  */
+
+static int __init 
+cs89x0_probe1(struct net_device *dev, int ioaddr)
+{
+	struct net_local *lp;
+	static unsigned version_printed = 0;
+	int i;
+	unsigned rev_type = 0;
+
+/*	irq2dev_map[0] = dev;  */
+
+#if defined(CONFIG_UCSIMM) || defined(CONFIG_UCDIMM)
+	/* set up the chip select */
+	*(volatile unsigned  char *)PFSEL_ADDR |=   0x01;  /* output /sleep */
+	*(volatile unsigned short *)PFDIR_ADDR |= 0x0101;  /* not sleeping */
+
+	*(volatile unsigned  char *)PFSEL_ADDR &=   ~0x02; /* input irq5 */
+	*(volatile unsigned short *)PFDIR_ADDR &= ~0x0202; /* irq5 fcn on */
+	
+	*(volatile unsigned short *)CSGBB_ADDR  = 0x8000;  /* 0x10000000 */
+	*(volatile unsigned short *)CSB_ADDR    = 0x01e1;  /* 128k, 2ws, FLASH, en */
+#endif
+
+#ifdef CONFIG_ARCH_ATMEL
+	*(volatile unsigned int *) AIC_IDCR = AIC_IRQ1; /* disable interrupt IRQ1 */
+#ifdef	CONFIG_EB40LS	 
+	*(volatile unsigned int *) PIO_DISABLE_REGISTER = (1 << 10); /* disable PIO for IRQ1 */
+#endif	
+	*(volatile unsigned int *) AIC_ICCR = AIC_IRQ1; /* clear interrupt IRQ1 */
+	*(volatile unsigned int *) AIC_IECR = AIC_IRQ1; /* enable interrupt IRQ1 */
+#endif
+
+#ifdef CONFIG_ARCH_DM270
+	printk("uCcs89x0: Setting up TI TMS320DM270 CS8900A IRQ ioaddr = 0x%X\n",ioaddr);
+	/* Set GIO port to input */
+	outw(inw(DM270_GIO_DIR(DM270_INTERRUPT_EXT4)) | (1<<DM270_GIO_DIR_SHIFT(DM270_INTERRUPT_EXT4)),
+			DM270_GIO_DIR(DM270_INTERRUPT_EXT4));
+
+	/* Set GIO as interrupt port */
+	outw(inw(DM270_GIO_IRQPORT) | (1<<DM270_GIO_IRQPORT_SHIFT(DM270_INTERRUPT_EXT4)),
+			DM270_GIO_IRQPORT);
+
+	/*
+	 * CS8900A INTRQ goes high when an enabled interrupt is triggered
+	 * and goes low after ISQ is read as all 0's
+	 */
+
+	/* Trigger on rising edge */
+	outw(inw(DM270_GIO_INV(DM270_INTERRUPT_EXT4)) | (1<<DM270_GIO_INV_SHIFT(DM270_INTERRUPT_EXT4)),
+			DM270_GIO_INV(DM270_INTERRUPT_EXT4));
+
+	/* Use single-sided edge interrupts */
+	outw(inw(DM270_GIO_IRQEDGE) & ~(1<<DM270_GIO_IRQEDGE_SHIFT(DM270_INTERRUPT_EXT4)), DM270_GIO_IRQEDGE);
+#endif
+
+#ifdef CONFIG_ALMA_ANS
+        /* 
+         * Make sure the chip select (CSA1) is enabled 
+	 * Note, that we don't have to program the base address, since
+         * it is programmed once for both CSA0 and CSA1 in *-head.S
+	 */
+        PFSEL &= ~PF_CSA1;
+        PFDIR |= PF_CSA1;
+ 
+        /* Make sure that interrupt line (irq3) is enabled too */
+        PDSEL  &= ~PD_IRQ3;
+        PDDIR  &= ~PD_IRQ3;
+        PDKBEN |= PD_IRQ3;                                                       
+#endif
+
+	/* Initialize the device structure. */
+	if (dev->priv == NULL) {
+		dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+                memset(dev->priv, 0, sizeof(struct net_local));
+        }
+	dev->base_addr = ioaddr;
+	lp = (struct net_local *)dev->priv;
+
+	if (readreg(dev, PP_ChipID) != CHIP_EISA_ID_SIG) {
+	  printk("cs89x0.c: No CrystalLan device found.\n");
+		return ENODEV;
+	}
+
+	/* get the chip type */
+	printk ("CrystalLAN EISA ID: 0x%04x\n", readreg(dev, 0));
+
+	rev_type = readreg(dev, PRODUCT_ID_ADD);
+	lp->chip_type = rev_type &~ REVISON_BITS;
+	lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
+
+	/* Check the chip type and revision in order to set the correct send command
+	CS8920 revision C and CS8900 revision F can use the faster send. */
+	lp->send_cmd = TX_AFTER_ALL;
+#if 0
+	if (lp->chip_type == CS8900 && lp->chip_revision >= 'F')
+		lp->send_cmd = TX_NOW;
+	if (lp->chip_type != CS8900 && lp->chip_revision >= 'C')
+		lp->send_cmd = TX_NOW;
+#endif
+	if (net_debug  &&  version_printed++ == 0)
+		printk(version);
+
+	printk("%s: cs89%c0%s rev %c found at 0x%.8lx %s",
+	       dev->name,
+	       lp->chip_type==CS8900?'0':'2',
+	       lp->chip_type==CS8920M?"M":"",
+	       lp->chip_revision,
+	       dev->base_addr,
+	       readreg(dev, PP_SelfST) & ACTIVE_33V ? "3.3Volts" : "5Volts");
+
+	reset_chip(dev);
+
+	/* Fill this in, we don't have an EEPROM */
+	lp->adapter_cnf = A_CNF_10B_T | A_CNF_MEDIA_10B_T;
+	lp->auto_neg_cnf = EE_AUTO_NEG_ENABLE | IMM_BIT;
+
+	printk(" media %s%s%s",
+	       (lp->adapter_cnf & A_CNF_10B_T)?"RJ-45,":"",
+	       (lp->adapter_cnf & A_CNF_AUI)?"AUI,":"",
+	       (lp->adapter_cnf & A_CNF_10B_2)?"BNC,":"");
+
+	lp->irq_map = 0xffff;
+
+	/* dev->dev_addr[0] through dev->dev_addr[6] holds the mac address
+	 * of this ethernet device.  This can be set to anything we want it
+	 * to be.  But care should be taken to make this number unique... */
+
+#if   defined(CONFIG_UCSIMM) || defined(CONFIG_EB40LS) || \
+      defined(CONFIG_BLIP)   || defined(CONFIG_UCLINKII) || \
+      defined(CONFIG_UCDIMM)
+ 		memcpy(dev->dev_addr, cs8900a_hwaddr, 6);
+	
+#elif defined (CONFIG_BOARD_UCLINKII) || \
+      defined (CONFIG_ARCH_DM270) || \
+      defined (CONFIG_BOARD_EVS3C4530LII) || \
+      defined (CONFIG_BOARD_EVS3C4530HEI)
+      memcpy(dev->dev_addr, get_MAC_address("dev1"), 6);
+#else
+#error	    MAC address is not defined
+#endif
+
+	/* print the ethernet address. */
+	for (i = 0; i < ETH_ALEN; i++)
+		printk(" %2.2x", dev->dev_addr[i]);
+
+#ifdef FIXME
+	/* Grab the region so we can find another board if autoIRQ fails. */
+	request_region(ioaddr, NETCARD_IO_EXTENT,"cs89x0");
+#endif
+
+	dev->open		= net_open;
+	dev->stop		= net_close;
+	dev->hard_start_xmit 	= net_send_packet;
+	dev->get_stats		= net_get_stats;
+	dev->set_multicast_list = &set_multicast_list;
+	dev->set_mac_address 	= &set_mac_address;
+
+	/* Fill in the fields of the device structure with ethernet values. */
+	ether_setup(dev);
+
+	printk("\n");
+	return 0;
+}
+
+
+
+void __init
+reset_chip(struct net_device *dev)
+{
+	int reset_start_time;
+
+	writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET);
+
+	current->state = TASK_INTERRUPTIBLE;
+	/* wait 30 ms */
+	schedule_timeout(30*HZ/1000);
+	
+	/* Wait until the chip is reset */
+	reset_start_time = jiffies;
+	while( (readreg(dev, PP_SelfST) & INIT_DONE) == 0 && jiffies - reset_start_time < 2)
+		;
+}
+
+static int
+detect_tp(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *)dev->priv;
+	int timenow = jiffies;
+
+	if (net_debug > 1) printk("%s: Attempting TP\n", dev->name);
+
+        /* If connected to another full duplex capable 10-Base-T card the link pulses
+           seem to be lost when the auto detect bit in the LineCTL is set.
+           To overcome this the auto detect bit will be cleared whilst testing the
+           10-Base-T interface.  This would not be necessary for the sparrow chip but
+           is simpler to do it anyway. */
+	writereg(dev, PP_LineCTL, lp->linectl &~ AUI_ONLY);
+
+        /* Delay for the hardware to work out if the TP cable is present - 150ms */
+	for (timenow = jiffies; jiffies - timenow < 15; )
+                ;
+	if ((readreg(dev, PP_LineST) & LINK_OK) == 0)
+		return 0;
+
+	return A_CNF_MEDIA_10B_T;
+}
+
+/* send a test packet - return true if carrier bits are ok */
+int
+send_test_pkt(struct net_device *dev)
+{
+	int ioaddr = dev->base_addr;
+	char test_packet[] = { 0,0,0,0,0,0, 0,0,0,0,0,0,
+				 0, 46, /* A 46 in network order */
+				 0, 0, /* DSAP=0 & SSAP=0 fields */
+				 0xf3, 0 /* Control (Test Req + P bit set) */ };
+	long timenow = jiffies;
+	unsigned short event;
+
+	writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_TX_ON);
+
+	memcpy(test_packet,          dev->dev_addr, ETH_ALEN);
+	memcpy(test_packet+ETH_ALEN, dev->dev_addr, ETH_ALEN);
+        outw(TX_AFTER_ALL, ioaddr + TX_CMD_PORT);
+        outw(ETH_ZLEN, ioaddr + TX_LEN_PORT);
+
+	/* Test to see if the chip has allocated memory for the packet */
+	while (jiffies - timenow < 5)
+		if (readreg(dev, PP_BusST) & READY_FOR_TX_NOW)
+			break;
+	if (jiffies - timenow >= 5)
+		return 0;	/* this shouldn't happen */
+
+	/* Write the contents of the packet */
+	outsw(ioaddr + TX_FRAME_PORT,test_packet,(ETH_ZLEN+1) >>1);
+
+	if (net_debug > 1) printk("Sending test packet ");
+	/* wait a couple of jiffies for packet to be received */
+	for (timenow = jiffies; jiffies - timenow < 60; )
+                ;
+        if (((event = readreg(dev, PP_TxEvent)) & TX_SEND_OK_BITS) == TX_OK) {
+                if (net_debug > 1) printk("succeeded\n");
+                return 1;
+        }
+	if (net_debug > 1) printk("failed TxEvent 0x%.4x\n",event);
+	return 0;
+}
+
+
+void
+write_irq(struct net_device *dev, int chip_type, int irq)
+{
+  /* we only hooked up 0 :-) */
+	writereg(dev, PP_CS8900_ISAINT, 0);
+}
+
+/* Open/initialize the board.  This is called (in the current kernel)
+   sometime after booting when the 'ifconfig' program is run.
+
+   This routine should set everything up anew at each open, even
+   registers that "should" only need to be set once at boot, so that
+   there is non-reboot way to recover if something goes wrong.
+   */
+static int
+net_open(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *)dev->priv;
+	int result = 0;
+
+	write_irq(dev, lp->chip_type, 0);
+
+/*	irq2dev_map[0] = dev;   */
+	writereg(dev, PP_BusCTL, 0); /* ints off! */
+
+#if defined(CONFIG_UCSIMM) || defined(CONFIG_UCDIMM)
+	*(volatile unsigned short *)0xfffff302 |= 0x0080; /* +ve pol irq */
+	dev->irq = IRQ5_IRQ_NUM;
+        if (request_irq(dev->irq, cs8900_interrupt, IRQ_FLG_STD,
+                        "CrystalLAN_cs8900a", dev))
+                panic("Unable to attach cs8900 intr\n");
+#endif
+
+#ifdef CONFIG_ARCH_ATMEL
+	/* Set IRQ1 with high level sensitive & priority level 6. */
+	*(volatile unsigned int *) AIC_SMR(IRQ_IRQ1) = 0x46;
+
+	/* We use IRQ_IRQ1 for the network interrupt */
+	dev->irq = IRQ_IRQ1;
+        if (request_irq(dev->irq,
+                        cs8900_interrupt,
+                        IRQ_FLG_STD,
+                        "CrystalLAN_cs8900a", NULL))
+                panic("Unable to attach cs8900 intr\n");                        
+#endif
+
+#ifdef CONFIG_ARCH_DM270
+	/* We use IRQ4 for the network interrupt */
+	dev->irq = DM270_INTERRUPT_EXT4;
+	if (request_irq(dev->irq,
+			cs8900_interrupt,
+			IRQ_FLG_STD,
+			"CrystalLAN_cs8900a", NULL))
+		panic("Unable to attach cs8900a intr\n");                        
+#endif
+
+#if defined (CONFIG_BOARD_UCLINKII)     || \
+    defined (CONFIG_BOARD_EVS3C4530LII) || \
+    defined (CONFIG_BOARD_EVS3C4530HEI)
+	
+	*(volatile unsigned int *)IOPCON0 |= (xINTREQ0_ENABLE | xINTREQ0_ACT_HI);
+	dev->irq = _IRQ0;
+	if (request_irq (dev->irq, cs8900_interrupt, 0,
+			 "Crystal_CS8900", dev))
+ 	  panic("Unable to attach cs8900 intr\n");
+#endif
+
+#ifdef CONFIG_ALMA_ANS
+	/* We use positive polarity IRQ3 as a network interrupt */
+	ICR |= ICR_POL3;
+	dev->irq = IRQ3_IRQ_NUM;
+	if (request_irq(dev->irq, cs8900_interrupt,
+                        IRQ_FLG_STD,
+                        "CrystalLAN_cs8900a", NULL))
+                panic("Unable to attach cs8900 intr\n");                        
+#endif
+
+#if defined (CONFIG_BOARD_UC5272)
+	dev->irq = 65; /* FIXME: These should be enumerated! */
+	/* do some nonsense that should be taken care of by
+	 * request_irq:
+	 * enable INT1 and give it priority 4 */
+
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x07777777) | 0xC0000000;
+
+	*(volatile unsigned long *) (MCF_MBAR + MCFSIM_PITR) |= 0x80000000;
+
+        if (request_irq(dev->irq, cs8900_interrupt, 0, "cs8900a", dev))
+	  panic("Unable to attach cs8900 intr\n");
+#endif
+
+	/* set the Ethernet address */
+	set_mac_address(dev, dev->dev_addr);
+
+	/* Set the LineCTL */
+	lp->linectl = 0;
+
+        /* check to make sure that they have the "right" hardware available */
+	switch(lp->adapter_cnf & A_CNF_MEDIA_TYPE) {
+	case A_CNF_MEDIA_10B_T:
+		result = lp->adapter_cnf & A_CNF_10B_T;
+		break;
+	case A_CNF_MEDIA_AUI:
+		result = lp->adapter_cnf & A_CNF_AUI;
+		break;
+	case A_CNF_MEDIA_10B_2:
+		result = lp->adapter_cnf & A_CNF_10B_2;
+		break;
+        default:
+		result = lp->adapter_cnf & 
+		         (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2);
+        }
+        if (!result) {
+                printk("%s: EEPROM is configured for unavailable media\n", dev->name);
+        release_irq:
+                writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON));
+		/* so subsequent opens don't fail we release the IRQ ...MaTed--- */
+		free_irq( dev->irq, dev);
+/*                irq2dev_map[dev->irq] = 0;    */
+		return -EAGAIN;
+	}
+
+        /* set the hardware to the configured choice */
+	switch(lp->adapter_cnf & A_CNF_MEDIA_TYPE) {
+	case A_CNF_MEDIA_10B_T:
+                result = detect_tp(dev);
+                if (!result) { 
+		  printk("%s: 10Base-T (RJ-45) has no cable\n", dev->name);
+		  if (lp->auto_neg_cnf & IMM_BIT) { /* check "ignore missing media" bit */
+		    printk("%s: but ignore the fact.\n", dev->name);
+		    result = A_CNF_MEDIA_10B_T; /* Yes! I don't care if I see a link pulse */
+		  }
+                }
+		break;
+	case A_CNF_MEDIA_AUI:
+	  printk("AUI is not supported by uCcs8900\n");
+		break;
+	case A_CNF_MEDIA_10B_2:
+	  printk("10Base2 is not supported by uCcs8900\n");
+		break;
+	case A_CNF_MEDIA_AUTO:
+		writereg(dev, PP_LineCTL, lp->linectl | AUTO_AUI_10BASET);
+		if (lp->adapter_cnf & A_CNF_10B_T)
+			if ((result = detect_tp(dev)) != 0)
+				break;
+
+		printk("%s: no media detected\n", dev->name);
+                goto release_irq;
+	}
+	switch(result) {
+	case 0: printk("%s: no network cable attached to configured media\n", dev->name);
+                goto release_irq;
+	case A_CNF_MEDIA_10B_T: printk("%s: using 10Base-T (RJ-45)\n", dev->name);break;
+	case A_CNF_MEDIA_AUI:   printk("%s: using 10Base-5 (AUI)\n", dev->name);break;
+	case A_CNF_MEDIA_10B_2: printk("%s: using 10Base-2 (BNC)\n", dev->name);break;
+	default: printk("%s: unexpected result was %x\n", dev->name, result); goto release_irq;
+	}
+
+	/* Turn on both receive and transmit operations */
+	writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);
+
+	/* Receive only error free packets addressed to this card */
+	lp->rx_mode = 0;
+	writereg(dev, PP_RxCTL, DEF_RX_ACCEPT);
+
+	lp->curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL;
+	if (lp->isa_config & STREAM_TRANSFER)
+		lp->curr_rx_cfg |= RX_STREAM_ENBL;
+
+	writereg(dev, PP_RxCFG, lp->curr_rx_cfg);
+
+	writereg(dev, PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL |
+	       TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL);
+
+	writereg(dev, PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL |
+		 TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL);
+
+	/* now that we've got our act together, enable everything */
+	writereg(dev, PP_BusCTL, ENABLE_IRQ );
+	
+	netif_start_queue(dev);
+	
+	return 0;
+}
+
+
+static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *)dev->priv;
+
+#if 1
+	if (net_debug > 3) {  /*OZH*/
+		printk("%s: sent %d byte packet of type %x\n",
+			dev->name, skb->len,
+			(skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]);
+	}
+#endif
+	/* keep the upload from being interrupted, since we
+                  ask the chip to start transmitting before the
+                  whole packet has been completely uploaded. */
+
+	spin_lock_irq(&lp->lock);
+	netif_stop_queue(dev);
+
+	/* initiate a transmit sequence */
+	writeword(dev, TX_CMD_PORT, lp->send_cmd);
+	writeword(dev, TX_LEN_PORT, skb->len);
+
+	/* Test to see if the chip has allocated memory for the packet */
+	if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
+		/*
+		 * Gasp!  It hasn't.  But that shouldn't happen since
+		 * we're waiting for TxOk, so return 1 and requeue this packet.
+		 */
+		
+		spin_unlock_irq(&lp->lock);
+		if (net_debug) printk("cs89x0: Tx buffer not free!\n");
+		return 1;
+	}
+	/* Write the contents of the packet */
+	outsw(dev->base_addr + TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
+	spin_unlock_irq(&lp->lock);
+	dev->trans_start = jiffies;
+	dev_kfree_skb (skb);
+
+	/*
+	 * We DO NOT call netif_wake_queue() here.
+	 * We also DO NOT call netif_start_queue().
+	 *
+	 * Either of these would cause another bottom half run through
+	 * net_send_packet() before this packet has fully gone out.  That causes
+	 * us to hit the "Gasp!" above and the send is rescheduled.  it runs like
+	 * a dog.  We just return and wait for the Tx completion interrupt handler
+	 * to restart the netdevice layer
+	 */
+
+	return 0;
+}
+
+
+/* The typical workload of the driver:
+   Handle the network interface interrupts. */
+void
+cs8900_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+        struct net_device *dev = dev_id;
+	struct net_local *lp;
+	int ioaddr, status;
+	volatile unsigned long  *icrp;
+
+#if defined (CONFIG_BOARD_UC5272)
+	/* clear INT1  */
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x77777777) | 0x80000000;
+#endif
+
+	ioaddr = dev->base_addr;
+	lp = (struct net_local *)dev->priv;
+
+	/* we MUST read all the events out of the ISQ, otherwise we'll never
+           get interrupted again.  As a consequence, we can't have any limit
+           on the number of times we loop in the interrupt handler.  The
+           hardware guarantees that eventually we'll run out of events.  Of
+           course, if you're on a slow machine, and packets are arriving
+           faster than you can read them off, you're screwed.  Hasta la
+           vista, baby!  */
+	while ((status = readword(dev, ISQ_PORT))) {
+#if 1
+		/* OZH */	
+		if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status);
+#endif
+		switch(status & ISQ_EVENT_MASK) {
+		case ISQ_RECEIVER_EVENT:
+			/* Got a packet(s). */
+			net_rx(dev);
+			break;
+		case ISQ_TRANSMITTER_EVENT:
+			lp->stats.tx_packets++;
+
+			netif_wake_queue(dev);
+			
+			if ((status & TX_OK) == 0)	lp->stats.tx_errors++;
+			if (status & TX_LOST_CRS) 	lp->stats.tx_carrier_errors++;
+			if (status & TX_SQE_ERROR) 	lp->stats.tx_heartbeat_errors++;
+			if (status & TX_LATE_COL) 	lp->stats.tx_window_errors++;
+			if (status & TX_16_COL) 	lp->stats.tx_aborted_errors++;
+			break;
+		case ISQ_BUFFER_EVENT:
+			if (status & READY_FOR_TX) {
+				/* we tried to transmit a packet earlier,
+                                   but inexplicably ran out of buffers.
+                                   That shouldn't happen since we only ever
+                                   load one packet.  Shrug.  Do the right
+                                   thing anyway. */
+				netif_wake_queue(dev);   
+			}
+			if (status & TX_UNDERRUN) {
+				if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
+                                lp->send_underrun++;
+                                if (lp->send_underrun > 3) lp->send_cmd = TX_AFTER_ALL;
+                        }
+			break;
+		case ISQ_RX_MISS_EVENT:
+			lp->stats.rx_missed_errors += (status >>6);
+			break;
+		case ISQ_TX_COL_EVENT:
+			lp->stats.collisions += (status >>6);
+			break;
+		}
+	}
+}
+
+/* We have a good packet(s), get it/them out of the buffers. */
+static void
+net_rx(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *)dev->priv;
+	struct sk_buff *skb;
+	int status, length;
+
+	int ioaddr = dev->base_addr;
+	status = inw(ioaddr + RX_FRAME_PORT);
+	length = inw(ioaddr + RX_FRAME_PORT);
+
+	if ((status & RX_OK) == 0) {
+		lp->stats.rx_errors++;
+		if (status & RX_RUNT) 		lp->stats.rx_length_errors++;
+		if (status & RX_EXTRA_DATA) 	lp->stats.rx_length_errors++;
+		if (status & RX_CRC_ERROR) if (!(status & (RX_EXTRA_DATA|RX_RUNT)))
+			/* per str 172 */
+			lp->stats.rx_crc_errors++;
+		if (status & RX_DRIBBLE) 	lp->stats.rx_frame_errors++;
+		return;
+	}
+
+	/* Malloc up new buffer. */
+	skb = alloc_skb(length+2, GFP_ATOMIC);	/* Fixed 32bit alignment problem. OZH */
+	if (skb == NULL) {
+		lp->stats.rx_dropped++;
+		return;
+	}
+	skb_reserve(skb, 2);	/* longword align L3 header */
+
+	skb->dev = dev;
+	insw(ioaddr + RX_FRAME_PORT, skb_put(skb, length), length >> 1);
+	if (length & 1)
+		skb->data[length-1] = inw(ioaddr + RX_FRAME_PORT);
+#if 1
+	if (net_debug > 3) {	/* OZH */
+		printk(	"%s: received %d byte packet of type %x\n",
+			dev->name, length,
+			(skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]);
+	}
+	if (net_debug == 77) {
+	    int i;
+	    for (i=0; i< length; i++)
+	        printk ("%2.2x:", skb->data[i]);
+    	    printk("\n");
+	    }
+#endif
+        skb->protocol=eth_type_trans(skb,dev);
+	netif_rx(skb);
+	dev->last_rx = jiffies;
+	lp->stats.rx_packets++;
+	lp->stats.rx_bytes += length;
+	return;
+}
+
+/* The inverse routine to net_open(). */
+static int
+net_close(struct net_device *dev)
+{
+	netif_stop_queue (dev);
+	
+	writereg(dev, PP_RxCFG, 0);
+	writereg(dev, PP_TxCFG, 0);
+	writereg(dev, PP_BufCFG, 0);
+	writereg(dev, PP_BusCTL, 0);
+
+	free_irq(dev->irq, dev);
+
+	return 0;
+}
+
+/* Get the current statistics.	This may be called with the card open or
+   closed. */
+   
+   
+static  struct net_device_stats *
+net_get_stats(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *)dev->priv;
+
+	cli();
+	/* Update the statistics from the device registers. */
+	lp->stats.rx_missed_errors += (readreg(dev, PP_RxMiss) >> 6);
+	lp->stats.collisions += (readreg(dev, PP_TxCol) >> 6);
+	sti();
+
+	return &lp->stats;
+}
+
+static void set_multicast_list(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *)dev->priv;
+
+	if(dev->flags&IFF_PROMISC)
+	{
+		lp->rx_mode = RX_ALL_ACCEPT;
+	}
+	else if((dev->flags&IFF_ALLMULTI)||dev->mc_list)
+	{
+		/* The multicast-accept list is initialized to accept-all, and we
+		   rely on higher-level filtering for now. */
+		lp->rx_mode = RX_MULTCAST_ACCEPT;
+	} 
+	else
+		lp->rx_mode = 0;
+
+	writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp->rx_mode);
+
+	/* in promiscuous mode, we accept errored packets, so we have to enable interrupts on them also */
+	writereg(dev, PP_RxCFG, lp->curr_rx_cfg |
+	     (lp->rx_mode == RX_ALL_ACCEPT? (RX_CRC_ERROR_ENBL|RX_RUNT_ENBL|RX_EXTRA_DATA_ENBL) : 0));
+}
+
+static int
+set_mac_address(struct net_device *dev, void *addr)
+{
+	int i;
+/* 	if (netif_running(dev)) */
+/* 		return -EBUSY; */
+	printk("%s: Setting MAC address to ", dev->name);
+	for (i = 0; i < 6; i++)
+		printk(" %2.2x", dev->dev_addr[i] = ((unsigned char *)addr)[i]);
+	printk(".\n");
+	/* set the Ethernet address */
+	for (i=0; i < ETH_ALEN/2; i++)
+		writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
+
+	return 0;
+}
+
+/*
+ * Local variables:
+ *  version-control: t
+ *  kept-new-versions: 5
+ *  c-indent-level: 4
+ *  tab-width: 4
+ * End:
+ */
diff -urN linux-2.4.29/drivers/net/uCcs8900.h linux-2.4.29-uc1/drivers/net/uCcs8900.h
--- linux-2.4.29/drivers/net/uCcs8900.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/uCcs8900.h	2005-06-14 02:12:09.000000000 +0100
@@ -0,0 +1,456 @@
+/*  Copyright, 1988-1992, Russell Nelson, Crynwr Software
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, version 1.
+
+   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., 675 Mass Ave, Cambridge, MA 02139, USA.
+   */
+
+#define PP_ChipID 0x0000	/* offset   0h -> Corp -ID              */
+				/* offset   2h -> Model/Product Number  */
+				/* offset   3h -> Chip Revision Number  */
+
+#define PP_ISAIOB 0x0020	/*  IO base address */
+#define PP_CS8900_ISAINT 0x0022	/*  ISA interrupt select */
+#define PP_CS8920_ISAINT 0x0370	/*  ISA interrupt select */
+#define PP_CS8900_ISADMA 0x0024	/*  ISA Rec DMA channel */
+#define PP_CS8920_ISADMA 0x0374	/*  ISA Rec DMA channel */
+#define PP_ISASOF 0x0026	/*  ISA DMA offset */
+#define PP_DmaFrameCnt 0x0028	/*  ISA DMA Frame count */
+#define PP_DmaByteCnt 0x002A	/*  ISA DMA Byte count */
+#define PP_CS8900_ISAMemB 0x002C	/*  Memory base */
+#define PP_CS8920_ISAMemB 0x0348 /*  */
+
+#define PP_ISABootBase 0x0030	/*  Boot Prom base  */
+#define PP_ISABootMask 0x0034	/*  Boot Prom Mask */
+
+/* EEPROM data and command registers */
+#define PP_EECMD 0x0040		/*  NVR Interface Command register */
+#define PP_EEData 0x0042	/*  NVR Interface Data Register */
+#define PP_DebugReg 0x0044	/*  Debug Register */
+
+#define PP_RxCFG 0x0102		/*  Rx Bus config */
+#define PP_RxCTL 0x0104		/*  Receive Control Register */
+#define PP_TxCFG 0x0106		/*  Transmit Config Register */
+#define PP_TxCMD 0x0108		/*  Transmit Command Register */
+#define PP_BufCFG 0x010A	/*  Bus configuration Register */
+#define PP_LineCTL 0x0112	/*  Line Config Register */
+#define PP_SelfCTL 0x0114	/*  Self Command Register */
+#define PP_BusCTL 0x0116	/*  ISA bus control Register */
+#define PP_TestCTL 0x0118	/*  Test Register */
+#define PP_AutoNegCTL 0x011C	/*  Auto Negotiation Ctrl */
+
+#define PP_ISQ 0x0120		/*  Interrupt Status */
+#define PP_RxEvent 0x0124	/*  Rx Event Register */
+#define PP_TxEvent 0x0128	/*  Tx Event Register */
+#define PP_BufEvent 0x012C	/*  Bus Event Register */
+#define PP_RxMiss 0x0130	/*  Receive Miss Count */
+#define PP_TxCol 0x0132		/*  Transmit Collision Count */
+#define PP_LineST 0x0134	/*  Line State Register */
+#define PP_SelfST 0x0136	/*  Self State register */
+#define PP_BusST 0x0138		/*  Bus Status */
+#define PP_TDR 0x013C		/*  Time Domain Reflectometry */
+#define PP_AutoNegST 0x013E	/*  Auto Neg Status */
+#define PP_TxCommand 0x0144	/*  Tx Command */
+#define PP_TxLength 0x0146	/*  Tx Length */
+#define PP_LAF 0x0150		/*  Hash Table */
+#define PP_IA 0x0158		/*  Physical Address Register */
+
+#define PP_RxStatus 0x0400	/*  Receive start of frame */
+#define PP_RxLength 0x0402	/*  Receive Length of frame */
+#define PP_RxFrame 0x0404	/*  Receive frame pointer */
+#define PP_TxFrame 0x0A00	/*  Transmit frame pointer */
+
+/*  Primary I/O Base Address. If no I/O base is supplied by the user, then this */
+/*  can be used as the default I/O base to access the PacketPage Area. */
+#define DEFAULTIOBASE 0x0300
+#define FIRST_IO 0x020C		/*  First I/O port to check */
+#define LAST_IO 0x037C		/*  Last I/O port to check (+10h) */
+#define ADD_MASK 0x3000		/*  Mask it use of the ADD_PORT register */
+#define ADD_SIG 0x3000		/*  Expected ID signature */
+
+#define CHIP_EISA_ID_SIG 0x630E   /*  Product ID Code for Crystal Chip (CS8900 spec 4.3) */
+
+#ifdef IBMEIPKT
+#define EISA_ID_SIG 0x4D24	/*  IBM */
+#define PART_NO_SIG 0x1010	/*  IBM */
+#define MONGOOSE_BIT 0x0000	/*  IBM */
+#else
+#define EISA_ID_SIG 0x630E	/*  PnP Vendor ID (same as chip id for Crystal board) */
+#define PART_NO_SIG 0x4000	/*  ID code CS8920 board (PnP Vendor Product code) */
+#define MONGOOSE_BIT 0x2000	/*  PART_NO_SIG + MONGOOSE_BUT => ID of mongoose */
+#endif
+
+#define PRODUCT_ID_ADD 0x0002   /*  Address of product ID */
+
+/*  Mask to find out the types of  registers */
+#define REG_TYPE_MASK 0x001F
+
+/*  Eeprom Commands */
+#define ERSE_WR_ENBL 0x00F0
+#define ERSE_WR_DISABLE 0x0000
+
+/*  Defines Control/Config register quintuplet numbers */
+#define RX_BUF_CFG 0x0003
+#define RX_CONTROL 0x0005
+#define TX_CFG 0x0007
+#define TX_COMMAND 0x0009
+#define BUF_CFG 0x000B
+#define LINE_CONTROL 0x0013
+#define SELF_CONTROL 0x0015
+#define BUS_CONTROL 0x0017
+#define TEST_CONTROL 0x0019
+
+/*  Defines Status/Count registers quintuplet numbers */
+#define RX_EVENT 0x0004
+#define TX_EVENT 0x0008
+#define BUF_EVENT 0x000C
+#define RX_MISS_COUNT 0x0010
+#define TX_COL_COUNT 0x0012
+#define LINE_STATUS 0x0014
+#define SELF_STATUS 0x0016
+#define BUS_STATUS 0x0018
+#define TDR 0x001C
+
+/* PP_RxCFG - Receive  Configuration and Interrupt Mask bit definition -  Read/write */
+#define SKIP_1 0x0040
+#define RX_STREAM_ENBL 0x0080
+#define RX_OK_ENBL 0x0100
+#define RX_DMA_ONLY 0x0200
+#define AUTO_RX_DMA 0x0400
+#define BUFFER_CRC 0x0800
+#define RX_CRC_ERROR_ENBL 0x1000
+#define RX_RUNT_ENBL 0x2000
+#define RX_EXTRA_DATA_ENBL 0x4000
+
+/* PP_RxCTL - Receive Control bit definition - Read/write */
+#define RX_IA_HASH_ACCEPT 0x0040
+#define RX_PROM_ACCEPT 0x0080
+#define RX_OK_ACCEPT 0x0100
+#define RX_MULTCAST_ACCEPT 0x0200
+#define RX_IA_ACCEPT 0x0400
+#define RX_BROADCAST_ACCEPT 0x0800
+#define RX_BAD_CRC_ACCEPT 0x1000
+#define RX_RUNT_ACCEPT 0x2000
+#define RX_EXTRA_DATA_ACCEPT 0x4000
+#define RX_ALL_ACCEPT (RX_PROM_ACCEPT|RX_BAD_CRC_ACCEPT|RX_RUNT_ACCEPT|RX_EXTRA_DATA_ACCEPT)
+/*  Default receive mode - individually addressed, broadcast, and error free */
+#define DEF_RX_ACCEPT (RX_IA_ACCEPT | RX_BROADCAST_ACCEPT | RX_OK_ACCEPT)
+
+/* PP_TxCFG - Transmit Configuration Interrupt Mask bit definition - Read/write */
+#define TX_LOST_CRS_ENBL 0x0040
+#define TX_SQE_ERROR_ENBL 0x0080
+#define TX_OK_ENBL 0x0100
+#define TX_LATE_COL_ENBL 0x0200
+#define TX_JBR_ENBL 0x0400
+#define TX_ANY_COL_ENBL 0x0800
+#define TX_16_COL_ENBL 0x8000
+
+/* PP_TxCMD - Transmit Command bit definition - Read-only */
+#define TX_START_4_BYTES 0x0000
+#define TX_START_64_BYTES 0x0040
+#define TX_START_128_BYTES 0x0080
+#define TX_START_ALL_BYTES 0x00C0
+#define TX_FORCE 0x0100
+#define TX_ONE_COL 0x0200
+#define TX_TWO_PART_DEFF_DISABLE 0x0400
+#define TX_NO_CRC 0x1000
+#define TX_RUNT 0x2000
+
+/* PP_BufCFG - Buffer Configuration Interrupt Mask bit definition - Read/write */
+#define GENERATE_SW_INTERRUPT 0x0040
+#define RX_DMA_ENBL 0x0080
+#define READY_FOR_TX_ENBL 0x0100
+#define TX_UNDERRUN_ENBL 0x0200
+#define RX_MISS_ENBL 0x0400
+#define RX_128_BYTE_ENBL 0x0800
+#define TX_COL_COUNT_OVRFLOW_ENBL 0x1000
+#define RX_MISS_COUNT_OVRFLOW_ENBL 0x2000
+#define RX_DEST_MATCH_ENBL 0x8000
+
+/* PP_LineCTL - Line Control bit definition - Read/write */
+#define SERIAL_RX_ON 0x0040
+#define SERIAL_TX_ON 0x0080
+#define AUI_ONLY 0x0100
+#define AUTO_AUI_10BASET 0x0200
+#define MODIFIED_BACKOFF 0x0800
+#define NO_AUTO_POLARITY 0x1000
+#define TWO_PART_DEFDIS 0x2000
+#define LOW_RX_SQUELCH 0x4000
+
+/* PP_SelfCTL - Software Self Control bit definition - Read/write */
+#define POWER_ON_RESET 0x0040
+#define SW_STOP 0x0100
+#define SLEEP_ON 0x0200
+#define AUTO_WAKEUP 0x0400
+#define HCB0_ENBL 0x1000
+#define HCB1_ENBL 0x2000
+#define HCB0 0x4000
+#define HCB1 0x8000
+
+/* PP_BusCTL - ISA Bus Control bit definition - Read/write */
+#define RESET_RX_DMA 0x0040
+#define MEMORY_ON 0x0400
+#define DMA_BURST_MODE 0x0800
+#define IO_CHANNEL_READY_ON 0x1000
+#define RX_DMA_SIZE_64K 0x2000
+#define ENABLE_IRQ 0x8000
+
+/* PP_TestCTL - Test Control bit definition - Read/write */
+#define LINK_OFF 0x0080
+#define ENDEC_LOOPBACK 0x0200
+#define AUI_LOOPBACK 0x0400
+#define BACKOFF_OFF 0x0800
+#define FAST_TEST 0x8000
+
+/* PP_RxEvent - Receive Event Bit definition - Read-only */
+#define RX_IA_HASHED 0x0040
+#define RX_DRIBBLE 0x0080
+#define RX_OK 0x0100
+#define RX_HASHED 0x0200
+#define RX_IA 0x0400
+#define RX_BROADCAST 0x0800
+#define RX_CRC_ERROR 0x1000
+#define RX_RUNT 0x2000
+#define RX_EXTRA_DATA 0x4000
+
+#define HASH_INDEX_MASK 0x0FC00
+
+/* PP_TxEvent - Transmit Event Bit definition - Read-only */
+#define TX_LOST_CRS 0x0040
+#define TX_SQE_ERROR 0x0080
+#define TX_OK 0x0100
+#define TX_LATE_COL 0x0200
+#define TX_JBR 0x0400
+#define TX_16_COL 0x8000
+#define TX_SEND_OK_BITS (TX_OK|TX_LOST_CRS)
+#define TX_COL_COUNT_MASK 0x7800
+
+/* PP_BufEvent - Buffer Event Bit definition - Read-only */
+#define SW_INTERRUPT 0x0040
+#define RX_DMA 0x0080
+#define READY_FOR_TX 0x0100
+#define TX_UNDERRUN 0x0200
+#define RX_MISS 0x0400
+#define RX_128_BYTE 0x0800
+#define TX_COL_OVRFLW 0x1000
+#define RX_MISS_OVRFLW 0x2000
+#define RX_DEST_MATCH 0x8000
+
+/* PP_LineST - Ethernet Line Status bit definition - Read-only */
+#define LINK_OK 0x0080
+#define AUI_ON 0x0100
+#define TENBASET_ON 0x0200
+#define POLARITY_OK 0x1000
+#define CRS_OK 0x4000
+
+/* PP_SelfST - Chip Software Status bit definition */
+#define ACTIVE_33V 0x0040
+#define INIT_DONE 0x0080
+#define SI_BUSY 0x0100
+#define EEPROM_PRESENT 0x0200
+#define EEPROM_OK 0x0400
+#define EL_PRESENT 0x0800
+#define EE_SIZE_64 0x1000
+
+/* PP_BusST - ISA Bus Status bit definition */
+#define TX_BID_ERROR 0x0080
+#define READY_FOR_TX_NOW 0x0100
+
+/* PP_AutoNegCTL - Auto Negotiation Control bit definition */
+#define RE_NEG_NOW 0x0040
+#define ALLOW_FDX 0x0080
+#define AUTO_NEG_ENABLE 0x0100
+#define NLP_ENABLE 0x0200
+#define FORCE_FDX 0x8000
+#define AUTO_NEG_BITS (FORCE_FDX|NLP_ENABLE|AUTO_NEG_ENABLE)
+#define AUTO_NEG_MASK (FORCE_FDX|NLP_ENABLE|AUTO_NEG_ENABLE|ALLOW_FDX|RE_NEG_NOW)
+
+/* PP_AutoNegST - Auto Negotiation Status bit definition */
+#define AUTO_NEG_BUSY 0x0080
+#define FLP_LINK 0x0100
+#define FLP_LINK_GOOD 0x0800
+#define LINK_FAULT 0x1000
+#define HDX_ACTIVE 0x4000
+#define FDX_ACTIVE 0x8000
+
+/*  The following block defines the ISQ event types */
+#define ISQ_RECEIVER_EVENT 0x04
+#define ISQ_TRANSMITTER_EVENT 0x08
+#define ISQ_BUFFER_EVENT 0x0c
+#define ISQ_RX_MISS_EVENT 0x10
+#define ISQ_TX_COL_EVENT 0x12
+
+#define ISQ_EVENT_MASK 0x003F   /*  ISQ mask to find out type of event */
+#define ISQ_HIST 16		/*  small history buffer */
+#define AUTOINCREMENT 0x8000	/*  Bit mask to set bit-15 for autoincrement */
+
+#define TXRXBUFSIZE 0x0600
+#define RXDMABUFSIZE 0x8000
+#define RXDMASIZE 0x4000
+#define TXRX_LENGTH_MASK 0x07FF
+
+/*  rx options bits */
+#define RCV_WITH_RXON	1       /*  Set SerRx ON */
+#define RCV_COUNTS	2       /*  Use Framecnt1 */
+#define RCV_PONG	4       /*  Pong respondent */
+#define RCV_DONG	8       /*  Dong operation */
+#define RCV_POLLING	0x10	/*  Poll RxEvent */
+#define RCV_ISQ		0x20	/*  Use ISQ, int */
+#define RCV_AUTO_DMA	0x100	/*  Set AutoRxDMAE */
+#define RCV_DMA		0x200	/*  Set RxDMA only */
+#define RCV_DMA_ALL	0x400	/*  Copy all DMA'ed */
+#define RCV_FIXED_DATA	0x800	/*  Every frame same */
+#define RCV_IO		0x1000	/*  Use ISA IO only */
+#define RCV_MEMORY	0x2000	/*  Use ISA Memory */
+
+#define RAM_SIZE	0x1000       /*  The card has 4k bytes or RAM */
+#define PKT_START PP_TxFrame  /*  Start of packet RAM */
+
+#define RX_FRAME_PORT	0x0000
+#define TX_FRAME_PORT RX_FRAME_PORT
+#define TX_CMD_PORT	0x0004
+#define TX_NOW		0x0000       /*  Tx packet after   5 bytes copied */
+#define TX_AFTER_381	0x0040       /*  Tx packet after 381 bytes copied */
+#define TX_AFTER_ALL	0x00C0       /*  Tx packet after all bytes copied */
+#define TX_LEN_PORT	0x0006
+#define ISQ_PORT	0x0008
+#define ADD_PORT	0x000A
+#define DATA_PORT	0x000C
+
+#define EEPROM_WRITE_EN		0x00F0
+#define EEPROM_WRITE_DIS	0x0000
+#define EEPROM_WRITE_CMD	0x0100
+#define EEPROM_READ_CMD		0x0200
+
+/*  Receive Header */
+/*  Description of header of each packet in receive area of memory */
+#define RBUF_EVENT_LOW	0   /*  Low byte of RxEvent - status of received frame */
+#define RBUF_EVENT_HIGH	1   /*  High byte of RxEvent - status of received frame */
+#define RBUF_LEN_LOW	2   /*  Length of received data - low byte */
+#define RBUF_LEN_HI	3   /*  Length of received data - high byte */
+#define RBUF_HEAD_LEN	4   /*  Length of this header */
+
+#define CHIP_READ 0x1   /*  Used to mark state of the repins code (chip or dma) */
+#define DMA_READ 0x2   /*  Used to mark state of the repins code (chip or dma) */
+
+/*  for bios scan */
+/*  */
+#ifdef CSDEBUG
+/*  use these values for debugging bios scan */
+#define BIOS_START_SEG 0x00000
+#define BIOS_OFFSET_INC 0x0010
+#else
+#define BIOS_START_SEG 0x0c000
+#define BIOS_OFFSET_INC 0x0200
+#endif
+
+#define BIOS_LAST_OFFSET 0x0fc00
+
+/*  Byte offsets into the EEPROM configuration buffer */
+#define ISA_CNF_OFFSET 0x6
+#define TX_CTL_OFFSET (ISA_CNF_OFFSET + 8)			/*  8900 eeprom */
+#define AUTO_NEG_CNF_OFFSET (ISA_CNF_OFFSET + 8)		/*  8920 eeprom */
+
+  /*  the assumption here is that the bits in the eeprom are generally  */
+  /*  in the same position as those in the autonegctl register. */
+  /*  Of course the IMM bit is not in that register so it must be  */
+  /*  masked out */
+#define EE_FORCE_FDX  0x8000
+#define EE_NLP_ENABLE 0x0200
+#define EE_AUTO_NEG_ENABLE 0x0100
+#define EE_ALLOW_FDX 0x0080
+#define EE_AUTO_NEG_CNF_MASK (EE_FORCE_FDX|EE_NLP_ENABLE|EE_AUTO_NEG_ENABLE|EE_ALLOW_FDX)
+
+#define IMM_BIT 0x0040		/*  ignore missing media	 */
+
+#define ADAPTER_CNF_OFFSET (AUTO_NEG_CNF_OFFSET + 2)
+#define A_CNF_10B_T 0x0001
+#define A_CNF_AUI 0x0002
+#define A_CNF_10B_2 0x0004
+#define A_CNF_MEDIA_TYPE 0x0060
+#define A_CNF_MEDIA_AUTO 0x0000
+#define A_CNF_MEDIA_10B_T 0x0020
+#define A_CNF_MEDIA_AUI 0x0040
+#define A_CNF_MEDIA_10B_2 0x0060
+#define A_CNF_DC_DC_POLARITY 0x0080
+#define A_CNF_NO_AUTO_POLARITY 0x2000
+#define A_CNF_LOW_RX_SQUELCH 0x4000
+#define A_CNF_EXTND_10B_2 0x8000
+
+#define PACKET_PAGE_OFFSET 0x8
+
+/*  Bit definitions for the ISA configuration word from the EEPROM */
+#define INT_NO_MASK 0x000F
+#define DMA_NO_MASK 0x0070
+#define ISA_DMA_SIZE 0x0200
+#define ISA_AUTO_RxDMA 0x0400
+#define ISA_RxDMA 0x0800
+#define DMA_BURST 0x1000
+#define STREAM_TRANSFER 0x2000
+#define ANY_ISA_DMA (ISA_AUTO_RxDMA | ISA_RxDMA)
+
+/*  DMA controller registers */
+#define DMA_BASE 0x00     /*  DMA controller base */
+#define DMA_BASE_2 0x0C0    /*  DMA controller base */
+
+#define DMA_STAT 0x0D0    /*  DMA controller status register */
+#define DMA_MASK 0x0D4    /*  DMA controller mask register */
+#define DMA_MODE 0x0D6    /*  DMA controller mode register */
+#define DMA_RESETFF 0x0D8    /*  DMA controller first/last flip flop */
+
+/*  DMA data */
+#define DMA_DISABLE 0x04     /*  Disable channel n */
+#define DMA_ENABLE 0x00     /*  Enable channel n */
+/*  Demand transfers, incr. address, auto init, writes, ch. n */
+#define DMA_RX_MODE 0x14
+/*  Demand transfers, incr. address, auto init, reads, ch. n */
+#define DMA_TX_MODE 0x18
+
+#define DMA_SIZE (16*1024) /*  Size of dma buffer - 16k */
+
+#define CS8900 0x0000
+#define CS8920 0x4000   
+#define CS8920M 0x6000   
+#define REVISON_BITS 0x1F00
+#define EEVER_NUMBER 0x12
+#define CHKSUM_LEN 0x14
+#define CHKSUM_VAL 0x0000
+#define START_EEPROM_DATA 0x001c /*  Offset into eeprom for start of data */
+#define IRQ_MAP_EEPROM_DATA 0x0046 /*  Offset into eeprom for the IRQ map */
+#define IRQ_MAP_LEN 0x0004 /*  No of bytes to read for the IRQ map */
+#define PNP_IRQ_FRMT 0x0022 /*  PNP small item IRQ format */
+#define CS8900_IRQ_MAP 0x1c20 /*  This IRQ map is fixed */
+
+#define CS8920_NO_INTS 0x0F   /*  Max CS8920 interrupt select # */
+
+#define PNP_ADD_PORT 0x0279
+#define PNP_WRITE_PORT 0x0A79
+
+#define GET_PNP_ISA_STRUCT 0x40
+#define PNP_ISA_STRUCT_LEN 0x06
+#define PNP_CSN_CNT_OFF 0x01
+#define PNP_RD_PORT_OFF 0x02
+#define PNP_FUNCTION_OK 0x00
+#define PNP_WAKE 0x03
+#define PNP_RSRC_DATA 0x04
+#define PNP_RSRC_READY 0x01
+#define PNP_STATUS 0x05
+#define PNP_ACTIVATE 0x30
+#define PNP_CNF_IO_H 0x60
+#define PNP_CNF_IO_L 0x61
+#define PNP_CNF_INT 0x70
+#define PNP_CNF_DMA 0x74
+#define PNP_CNF_MEM 0x48
+
+#define BIT0 1
+#define BIT15 0x8000
+
diff -urN linux-2.4.29/drivers/net/wan/chinook.c linux-2.4.29-uc1/drivers/net/wan/chinook.c
--- linux-2.4.29/drivers/net/wan/chinook.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/wan/chinook.c	2005-06-14 02:12:15.000000000 +0100
@@ -0,0 +1,587 @@
+/*
+ * Chinook synchronous serial driver for Linux
+ *
+ * Copyright (C) 2002 SnapGear Inc (www.snapgear.com)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Note: integrated CSU/DSU/DDS are not supported by this driver
+ *
+ * Based on N2 driver by Krzysztof Halasa <khc@pm.waw.pl>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/in.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/netdevice.h>
+#include <linux/hdlc.h>
+#include <asm/io.h>
+#include "hd64570.h"
+
+#define DEBUG_RINGS
+/*#define DEBUG_PKT*/
+
+static const char* version = "Chinook/HD64570 driver for Linux 2.4";
+static const char* devname = "Chinook/HD64570";
+
+#define CLOCK_BASE 16500000	/* 16.5 MHz */
+
+#define CHINOOK_IOPORTS 0x100
+#define CHINOOK_SRAM_SIZE	0x20000
+
+#define PIO_DATA31_16	0xc32
+#define PIO_LTEST		0x1000	/* PIO28 */
+#define PIO_EXCLK_EN	0x0010	/* PIO20, aka TTEN */
+#define PIO_SCTEN		0x0004	/* PIO18 */
+#define PIO_DTR			0x0002	/* PIO17 */
+#define PIO_DSR			0x0001	/* PIO16 */
+
+static char *hw = NULL;	/* pointer to hw=xxx command line string */
+
+
+typedef struct port_s {
+	hdlc_device hdlc;	/* HDLC device struct - must be first */
+	struct card_s *card;
+	spinlock_t lock;	/* TX lock */
+	int clkmode;		/* clock mode */
+	int clkrate;		/* clock rate */
+	int line;		/* loopback only */
+	u8 rxs, txs, tmc;	/* SCA registers */
+	u8 valid;		/* port enabled */
+	u8 phy_node;		/* physical port # - 0 or 1 */
+	u8 log_node;		/* logical port # */
+	u8 rxin;		/* rx ring buffer 'in' pointer */
+	u8 txin;		/* tx ring buffer 'in' and 'last' pointers */
+	u8 txlast;
+	u8 rxpart;		/* partial frame received, next frame invalid*/
+}port_t;
+
+typedef struct card_s {
+	u8 *base;		/* ISA base address */
+	u32 phy_base;	/* ISA physical base address */
+	u32 ram_size;		/* number of bytes */
+	u16 io;			/* IO Base address */
+	u16 buff_offset;	/* offset of first buffer of first channel */
+	u8 irq;			/* IRQ (3-15) */
+	u8 ring_buffers;	/* number of buffers in a ring */
+	u8 *mmcr_base;
+	u16 sp504_io;
+	u8 sp504_irq;
+
+	port_t ports[2];
+	struct card_s *next_card;
+}card_t;
+
+
+#define ALL_PAGES_ALWAYS_MAPPED
+
+#define sca_reg(reg, card)		((card)->io | (reg))
+#define sca_in(reg, card)		inb(sca_reg(reg, card))
+#define sca_out(value, reg, card)	outb(value, sca_reg(reg, card))
+#define sca_inw(reg, card)		inw(sca_reg(reg, card))
+#define sca_outw(value, reg, card)	outw(value, sca_reg(reg, card))
+
+#define port_to_card(port)		((port)->card)
+#define log_node(port)			((port)->log_node)
+#define phy_node(port)			((port)->phy_node)
+#define winbase(card)      	     	((card)->base)
+#define get_port(card, port)		((card)->ports[port].valid ? \
+					 &(card)->ports[port] : NULL)
+
+
+#include "hd6457x.c"
+
+
+struct cable_mode {
+	u8	sp504;
+	int hdlc;
+};
+
+static struct cable_mode cable_mode[] = {
+									/* PIO 31/30/29 */
+	{ 0x0, 0 /* Invalid */ },		/* 000 */
+	{ 0xee, LINE_V35 },				/* 001 */
+	{ 0x0, 0 /* Invalid */ },		/* 010 */
+	{ 0x22, LINE_RS232 },			/* 011 */
+	{ 0xdd, 0, /* EIA530 */ },		/* 100 */
+	{ 0xcc, 0 /* EIA449 */ },		/* 101 */
+	{ 0x44, LINE_X21 },				/* 110 */
+	{ 0x0, 0 /* No cable */ }		/* 111 */
+};
+
+
+static int chinook_get_line(port_t *port)
+{
+	card_t *card = port->card;
+	u16 mode;
+
+	mode = *(u16 *)(card->mmcr_base + PIO_DATA31_16);
+	mode >>= 13;
+
+	return cable_mode[mode].hdlc;
+}
+
+
+
+#define SC520_INTPINPOL		0xd10	/* Offset in the SC520 MMCR */
+#define SC520_GPINT6_POL		0x0004
+
+static void chinook_set_sp504(card_t *card)
+{
+	u16 mode;
+	unsigned long flags;
+
+	mode = *(u16 *)(card->mmcr_base + PIO_DATA31_16);
+	mode >>= 13;
+
+	save_flags(flags); cli();
+	if (mode == 7)
+		*(u16 *)(card->mmcr_base + SC520_INTPINPOL) |= SC520_GPINT6_POL;
+	else
+		*(u16 *)(card->mmcr_base + SC520_INTPINPOL) &= ~SC520_GPINT6_POL;
+	restore_flags(flags);
+
+	outb(cable_mode[mode].sp504, card->sp504_io);
+}
+
+
+
+static void chinook_sp504_intr(int irq, void* dev_id, struct pt_regs *regs)
+{
+	card_t *card = dev_id;
+
+	chinook_set_sp504(card);
+}
+
+
+
+static int chinook_set_clock(port_t *port, int value)
+{
+	card_t *card = port->card;
+	u8 msci = get_msci(port);
+	u8 rxs = port->rxs & CLK_BRG_MASK;
+	u8 txs = port->txs & CLK_BRG_MASK;
+	u16 *pio = (u16 *)(card->mmcr_base + PIO_DATA31_16);
+
+	switch(value) {
+	case CLOCK_EXT:
+		*pio |= PIO_EXCLK_EN | PIO_SCTEN;
+		rxs |= CLK_LINE_RX; /* RXC input */
+		txs |= CLK_LINE_TX; /* TXC input */
+		break;
+
+	case CLOCK_TXINT:
+		*pio &= ~(PIO_EXCLK_EN | PIO_SCTEN);
+		rxs |= CLK_LINE_RX; /* RXC input */
+		txs |= CLK_BRG_TX; /* BRG output */
+		break;
+
+	case CLOCK_TXFROMRX:
+		*pio |= PIO_EXCLK_EN | PIO_SCTEN;
+		rxs |= CLK_LINE_RX; /* RXC input */
+		txs |= CLK_RXCLK_TX; /* RX clock */
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	port->rxs = rxs;
+	port->txs = txs;
+	sca_out(rxs, msci + RXS, card);
+	sca_out(txs, msci + TXS, card);
+	port->clkmode = value;
+
+	return 0;
+}
+
+
+
+static int chinook_open(hdlc_device *hdlc)
+{
+	port_t *port = hdlc_to_port(hdlc);
+
+	MOD_INC_USE_COUNT;
+
+	/* set DTR ON */
+	*(u16 *)(port->card->mmcr_base + PIO_DATA31_16) &= ~PIO_DTR;
+
+	sca_open(hdlc);
+	chinook_set_clock(port, port->clkmode);
+	chinook_set_sp504(port->card);
+	return 0;
+}
+
+
+
+static void chinook_close(hdlc_device *hdlc)
+{
+	port_t *port = hdlc_to_port(hdlc);
+
+	sca_close(hdlc);
+
+	/* set DTR OFF */
+	*(u16 *)(port->card->mmcr_base + PIO_DATA31_16) |= PIO_DTR;
+
+	MOD_DEC_USE_COUNT;
+}
+
+
+
+static int chinook_ioctl(hdlc_device *hdlc, struct ifreq *ifr, int cmd)
+{
+	int value = ifr->ifr_ifru.ifru_ivalue;
+	int result = 0;
+	port_t *port = hdlc_to_port(hdlc);
+
+	if(!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	switch(cmd) {
+	case HDLCSCLOCK:
+		result = chinook_set_clock(port, value);
+	case HDLCGCLOCK:
+		value = port->clkmode;
+		break;
+
+	case HDLCSCLOCKRATE:
+		port->clkrate = value;
+		sca_set_clock(port);
+	case HDLCGCLOCKRATE:
+		value = port->clkrate;
+		break;
+
+	case HDLCSLINE:
+		result = sca_set_loopback(port, value);
+	case HDLCGLINE:
+		value = port->line | chinook_get_line(port);
+		break;
+
+#ifdef DEBUG_RINGS
+	case HDLCRUN:
+		sca_dump_rings(hdlc);
+		return 0;
+#endif /* DEBUG_RINGS */
+
+	default:
+		return -EINVAL;
+	}
+
+	ifr->ifr_ifru.ifru_ivalue = value;
+	return result;
+}
+
+
+#define CHINOOK_SRAM_TESTSIZE		0x1000
+
+static u32 chinook_test_sram(card_t *card)
+{
+	u8 page;
+	int i, bcount = CHINOOK_SRAM_TESTSIZE, wcount = CHINOOK_SRAM_TESTSIZE/2;
+	u16 *dp0 = (u16*)card->base;
+
+	for (page = 0; page < CHINOOK_SRAM_SIZE / CHINOOK_SRAM_TESTSIZE; page++) {
+		u16 *dp = (u16*)(card->base + page * CHINOOK_SRAM_TESTSIZE);
+		u8 *bp = (u8*)(card->base + page * CHINOOK_SRAM_TESTSIZE);
+
+		writeb(page, dp);
+		if (readb(dp) != page)
+			return 0;	/* If can't read back, no good memory */
+
+		if (readb(dp0))
+			return 0;	/* If page 0 changed, then address line bad */
+
+		/*  first do byte tests */
+		for (i = 0; i < bcount; i++)
+			writeb(i, bp + i);
+		for (i = 0; i < bcount; i++)
+			if (readb(bp + i) != (i & 0xff))
+				return 0;
+
+		for (i = 0; i < bcount; i++)
+			writeb(~i, bp + i);
+		for (i = 0; i < bcount; i++)
+			if (readb(bp + i) != (~i & 0xff))
+				return 0;
+
+		/* next do 16-bit tests */
+		for (i = 0; i < wcount; i++)
+			writew(i, dp + i);
+		for (i = 0; i < wcount; i++)
+			if (readw(dp + i) != (i & 0xffff))
+				return 0;
+
+		for (i = 0; i < wcount; i++)
+			writew(0x55AA, dp + i);
+		for (i = 0; i < wcount; i++)
+			if (readw(dp + i) != 0x55AA)
+				return 0;
+
+		for (i = 0; i < wcount; i++)
+			writew(0xAA55, dp + i);
+		for (i = 0; i < wcount; i++)
+			if (readw(dp + i) != 0xAA55)
+				return 0;
+
+		for (i = 0; i < wcount; i++)
+			writew(page, dp + i);
+	}
+
+	return CHINOOK_SRAM_SIZE;
+}
+
+
+
+static void chinook_destroy_card(card_t *card)
+{
+	if (card->ports[0].card)
+		unregister_hdlc_device(&card->ports[0].hdlc);
+
+	if (card->irq)
+		free_irq(card->irq, card);
+
+	if (card->base) {
+		iounmap(card->base);
+		release_mem_region(card->phy_base, CHINOOK_SRAM_SIZE);
+	}
+
+	if (card->io)
+		release_region(card->io, CHINOOK_IOPORTS);
+	kfree(card);
+}
+
+
+
+static int chinook_run(unsigned long io, unsigned long irq, unsigned long base)
+{
+	card_t *card;
+	u32 cnt;
+	u16 tmp;
+
+	if (io < 0x200 || io > 0x4FF || (io % CHINOOK_IOPORTS) != 0) {
+		printk(KERN_ERR "chinook: invalid I/O port value\n");
+		return -ENODEV;
+	}
+
+	if (irq != 7) {
+		printk(KERN_ERR "chinook: invalid IRQ value\n");
+		return -ENODEV;
+	}
+
+	if (base < 0xA0000 || (base & 0xFFF) != 0) {
+		printk(KERN_ERR "chinook: invalid RAM value\n");
+		return -ENODEV;
+	}
+
+	card = kmalloc(sizeof(card_t), GFP_KERNEL);
+	if (card == NULL) {
+		printk(KERN_ERR "chinook: unable to allocate memory\n");
+		return -ENOBUFS;
+	}
+	memset(card, 0, sizeof(card_t));
+
+	card->mmcr_base = ioremap_nocache(0xfffef000, 4096);
+	if (card->mmcr_base == NULL) {
+		printk(KERN_ERR "chinook: unable to disable MMCR cache\n");
+		return -EIO;
+	}
+
+	if (!request_region(io, CHINOOK_IOPORTS, devname)) {
+		printk(KERN_ERR "chinook: I/O port region in use\n");
+		chinook_destroy_card(card);
+		return -EBUSY;
+	}
+	card->io = io;
+
+	if (request_irq(irq, &sca_intr, 0, devname, card)) {
+		printk(KERN_ERR "chinook: could not allocate IRQ\n");
+		chinook_destroy_card(card);
+		return(-EBUSY);
+	}
+	card->irq = irq;
+
+	if (!request_mem_region(base, CHINOOK_SRAM_SIZE, devname)) {
+		printk(KERN_ERR "chinook: could not request SRAM\n");
+		chinook_destroy_card(card);
+		return(-EBUSY);
+	}
+	card->phy_base = base;
+	card->base = ioremap(base, CHINOOK_SRAM_SIZE);
+
+	if (!request_region(0x300, 1, devname)) {
+		printk(KERN_ERR "chinook: SP504 I/O port region in use\n");
+		chinook_destroy_card(card);
+		return -EBUSY;
+	}
+	card->sp504_io = 0x300;
+
+	if (request_irq(6, &chinook_sp504_intr, 0, devname, card)) {
+		printk(KERN_ERR "chinook: could not allocate SP504 IRQ\n");
+		chinook_destroy_card(card);
+		return(-EBUSY);
+	}
+	card->sp504_irq = 6;
+
+	/* Test 8 and 16 bit IO to the SCA */
+	sca_out(0, MSCI0_OFFSET + TMC, card);
+	tmp = sca_in(MSCI0_OFFSET + TMC, card);
+	if (tmp != 0) {
+		printk(KERN_ERR "chinook: error reading SCA TMC=%x, expected 0\n",
+				tmp);
+		chinook_destroy_card(card);
+		return(-EIO);
+	}
+
+	sca_out(0x5a, MSCI0_OFFSET + TMC, card);
+	tmp = sca_in(MSCI0_OFFSET + TMC, card);
+	if (tmp != 0x5a) {
+		printk(KERN_ERR "chinook: error reading SCA TMC=%x, expected 5a\n",
+				tmp);
+		chinook_destroy_card(card);
+		return(-EIO);
+	}
+
+	sca_outw(0x55aa, DMAC0RX_OFFSET + CDAL, card);
+	tmp = sca_inw(DMAC0RX_OFFSET + CDAL, card);
+	if (tmp != 0x55aa) {
+		printk(KERN_ERR "chinook: error reading SCA CDA=%x, expected 55aa\n",
+				tmp);
+		chinook_destroy_card(card);
+		return(-EIO);
+	}
+
+	cnt = chinook_test_sram(card);
+	if (!cnt) {
+		printk(KERN_ERR "chinook: memory test failed.\n");
+		chinook_destroy_card(card);
+		return -EIO;
+	}
+
+	card->ram_size = cnt;
+
+	/* Turn LTEST off */
+	*(u16 *)(card->mmcr_base + PIO_DATA31_16) |= PIO_LTEST;
+
+	/* 2 rings for one port */
+	card->ring_buffers = card->ram_size /
+		(2 * (sizeof(pkt_desc) + HDLC_MAX_MRU));
+
+	card->buff_offset = 2 * (sizeof(pkt_desc)) * card->ring_buffers;
+
+	printk(KERN_DEBUG "chinook: HD64570 %u KB RAM, IRQ%u, "
+	       "using %u packets rings\n", card->ram_size / 1024, card->irq,
+	       card->ring_buffers);
+
+	sca_init(card, 0);
+	{
+		port_t *port = &card->ports[0];
+
+		port->phy_node = 0;
+		port->valid = 1;
+		port->log_node = 0;
+		spin_lock_init(&port->lock);
+		hdlc_to_dev(&port->hdlc)->irq = irq;
+		hdlc_to_dev(&port->hdlc)->mem_start = base;
+		hdlc_to_dev(&port->hdlc)->mem_end = base + CHINOOK_SRAM_SIZE-1;
+		hdlc_to_dev(&port->hdlc)->tx_queue_len = 50;
+		port->hdlc.ioctl = chinook_ioctl;
+		port->hdlc.open = chinook_open;
+		port->hdlc.close = chinook_close;
+		port->hdlc.xmit = sca_xmit;
+
+		if (register_hdlc_device(&port->hdlc)) {
+			printk(KERN_WARNING "chinook: unable to register hdlc "
+			       "device\n");
+			chinook_destroy_card(card);
+			return -ENOBUFS;
+		}
+		port->card = card;
+		sca_init_sync_port(port); /* Set up SCA memory */
+
+		printk(KERN_INFO "%s: Chinook node %d\n",
+		       hdlc_to_name(&port->hdlc), port->phy_node);
+	}
+
+	*new_card = card;
+	new_card = &card->next_card;
+
+	return 0;
+}
+
+
+
+static int __init chinook_init(void)
+{
+	if (hw==NULL) {
+		hw = "0x400,7,0x30000000";
+	}
+
+	printk(KERN_INFO "%s\n", version);
+
+	do {
+		unsigned long io, irq, ram;
+
+		io = simple_strtoul(hw, &hw, 0);
+
+		if (*hw++ != ',')
+			break;
+		irq = simple_strtoul(hw, &hw, 0);
+
+		if (*hw++ != ',')
+			break;
+		ram = simple_strtoul(hw, &hw, 0);
+
+		if (*hw == ':' || *hw == '\x0')
+			chinook_run(io, irq, ram);
+
+		if (*hw == '\x0')
+			return 0;
+	}while(*hw++ == ':');
+
+	printk(KERN_ERR "chinook: invalid hardware parameters\n");
+	return first_card ? 0 : -ENOSYS;
+}
+
+
+#ifndef MODULE
+static int __init chinook_setup(char *str)
+{
+	hw = str;
+	return 1;
+}
+
+__setup("chinook=", chinook_setup);
+#endif
+
+
+static void __exit chinook_cleanup(void)
+{
+	card_t *card = first_card;
+
+	while (card) {
+		card_t *ptr = card;
+		card = card->next_card;
+		chinook_destroy_card(ptr);
+	}
+}
+
+
+module_init(chinook_init);
+module_exit(chinook_cleanup);
+
+MODULE_AUTHOR("Philip Craig <philipc@snapgear.com>");
+MODULE_DESCRIPTION("Chinook HD64570 serial port driver");
+MODULE_LICENSE("GPL");
+MODULE_PARM(hw, "s");		/* hw=io,irq,ram:io,irq,... */
+EXPORT_NO_SYMBOLS;
diff -urN linux-2.4.29/drivers/net/wan/Config.in linux-2.4.29-uc1/drivers/net/wan/Config.in
--- linux-2.4.29/drivers/net/wan/Config.in	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/wan/Config.in	2005-06-14 02:12:15.000000000 +0100
@@ -90,6 +90,7 @@
          fi
 	 dep_tristate '    FarSync T-Series support' CONFIG_FARSYNC $CONFIG_HDLC
       fi
+      dep_tristate '    6WIND Chinook support' CONFIG_CHINOOK $CONFIG_HDLC
       if [ "$CONFIG_ISA" != "n" ]; then
 	 dep_tristate '    SDL RISCom/N2 support' CONFIG_N2 $CONFIG_HDLC
 	 dep_tristate '    Moxa C101 support' CONFIG_C101 $CONFIG_HDLC
diff -urN linux-2.4.29/drivers/net/wan/Makefile linux-2.4.29-uc1/drivers/net/wan/Makefile
--- linux-2.4.29/drivers/net/wan/Makefile	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/net/wan/Makefile	2005-06-14 02:12:15.000000000 +0100
@@ -80,6 +80,7 @@
 endif
 obj-$(CONFIG_N2)		+= n2.o
 obj-$(CONFIG_C101)		+= c101.o
+obj-$(CONFIG_CHINOOK)		+= chinook.o
 obj-$(CONFIG_PCI200SYN)		+= pci200syn.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/net/wireless/orinoco.c linux-2.4.29-uc1/drivers/net/wireless/orinoco.c
--- linux-2.4.29/drivers/net/wireless/orinoco.c	2003-08-25 12:44:42.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/wireless/orinoco.c	2005-06-14 02:12:12.000000000 +0100
@@ -433,6 +433,10 @@
 #include "orinoco.h"
 #include "ieee802_11.h"
 
+#if defined(CONFIG_LEDMAN)
+#include <linux/ledman.h>
+#endif
+
 /********************************************************************/
 /* Module information                                               */
 /********************************************************************/
@@ -1532,6 +1536,17 @@
 {
 	char * s;
 
+#if defined(CONFIG_LEDMAN)
+	if ((status == HERMES_LINKSTATUS_NOT_CONNECTED) ||
+	    (status == HERMES_LINKSTATUS_DISCONNECTED) ||
+	    (status == HERMES_LINKSTATUS_AP_OUT_OF_RANGE) ||
+	    (status == HERMES_LINKSTATUS_ASSOC_FAILED))
+		ledman_cmd(LEDMAN_CMD_OFF, LEDMAN_LAN3_LINK);
+	else if ((status == HERMES_LINKSTATUS_CONNECTED) ||
+	    (status == HERMES_LINKSTATUS_AP_IN_RANGE))
+		ledman_cmd(LEDMAN_CMD_ON, LEDMAN_LAN3_LINK);
+#endif
+
 	switch (status) {
 	case HERMES_LINKSTATUS_NOT_CONNECTED:
 		s = "Not Connected";
@@ -1677,6 +1692,10 @@
 	struct ethhdr *eh;
 	int err;
 
+#if defined(CONFIG_LEDMAN)
+	ledman_cmd(LEDMAN_CMD_SET, LEDMAN_LAN3_RX);
+#endif
+
 	rxfid = hermes_read_regn(hw, RXFID);
 
 	err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc),
@@ -1827,6 +1846,10 @@
 	if (fid == DUMMY_FID)
 		return; /* Nothing's really happened */
 
+#if defined(CONFIG_LEDMAN)
+	ledman_cmd(LEDMAN_CMD_SET, LEDMAN_LAN3_TX);
+#endif
+
 	err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc), fid, 0);
 	if (err) {
 		printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
@@ -1847,6 +1870,10 @@
 	struct orinoco_private *priv = dev->priv;
 	struct net_device_stats *stats = &priv->stats;
 
+#if defined(CONFIG_LEDMAN)
+	ledman_cmd(LEDMAN_CMD_SET, LEDMAN_LAN3_TX);
+#endif
+
 	stats->tx_packets++;
 
 	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
diff -urN linux-2.4.29/drivers/net/xilinx_enet/adapter.c linux-2.4.29-uc1/drivers/net/xilinx_enet/adapter.c
--- linux-2.4.29/drivers/net/xilinx_enet/adapter.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/xilinx_enet/adapter.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,2025 @@
+/*
+ * adapter.c
+ *
+ * Xilinx Ethernet Adapter component to interface XEmac component to Linux
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under the terms
+ * of the GNU General Public License version 2.1.  This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+/*
+ * This driver is a bit unusual in that it is composed of two logical
+ * parts where one part is the OS independent code and the other part is
+ * the OS dependent code.  Xilinx provides their drivers split in this
+ * fashion.  This file represents the Linux OS dependent part known as
+ * the Linux adapter.  The other files in this directory are the OS
+ * independent files as provided by Xilinx with no changes made to them.
+ * The names exported by those files begin with XEmac_.  All functions
+ * in this file that are called by Linux have names that begin with
+ * xenet_.  The functions in this file that have Handler in their name
+ * are registered as callbacks with the underlying Xilinx OS independent
+ * layer.  Any other functions are static helper functions.
+ */
+
+#include <linux/module.h>
+#include <asm/uaccess.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/mii.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/atomic.h>
+#include <asm/pgalloc.h>
+#include <linux/ethtool.h>
+
+#include <xbasic_types.h>
+#include "xemac.h"
+#include "xemac_i.h"
+#include "xipif_v1_23_b.h"
+
+#undef XEM_DFT_SEND_DESC
+#define XEM_DFT_SEND_DESC    64
+#undef XEM_DFT_RECV_DESC
+#define XEM_DFT_RECV_DESC   256
+
+#define DRIVER_NAME "Xilinx Eth MAC driver"
+#define DRIVER_VERSION "1.0"
+
+MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
+MODULE_DESCRIPTION(DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+/* FIXME hardcoded MAC addresses */
+#define CONFIG_XILINX_ETHERNET_0_MACADDR {0x00, 0x00, 0xC0, 0xA3, 0xE5, 0x44}
+#define CONFIG_XILINX_ETHERNET_1_MACADDR {0x00, 0x00, 0xC0, 0xA3, 0xE5, 0x45}
+#define CONFIG_XILINX_ETHERNET_2_MACADDR {0x00, 0x00, 0xC0, 0xA3, 0xE5, 0x46}
+
+#define TX_TIMEOUT   (60*HZ)	/* Transmission timeout is 60 seconds. */
+
+struct ethernet_desc {
+	unsigned baseaddr;
+	unsigned irq;
+	unsigned char macaddr[6];
+};
+
+static struct ethernet_desc ether_table[] = {
+#ifdef CONFIG_XILINX_ETHERNET_0_INSTANCE
+	{CONFIG_XILINX_ETHERNET_0_BASEADDR, CONFIG_XILINX_ETHERNET_0_IRQ,
+		CONFIG_XILINX_ETHERNET_0_MACADDR },
+#endif
+#ifdef CONFIG_XILINX_ETHERNET_1_INSTANCE
+	{CONFIG_XILINX_ETHERNET_1_BASEADDR, CONFIG_XILINX_ETHERNET_1_IRQ,
+		CONFIG_XILINX_ETHERNET_1_MACADDR },
+#endif
+#ifdef CONFIG_XILINX_ETHERNET_2_INSTANCE
+	{CONFIG_XILINX_ETHERNET_2_BASEADDR, CONFIG_XILINX_ETHERNET_2_IRQ,
+		CONFIG_XILINX_ETHERNET_2_MACADDR },
+#endif
+};
+
+static int num_ether_devices = sizeof(ether_table)/sizeof(struct ethernet_desc);
+
+/* On the OPB, the 10/100 EMAC requires data to be aligned to 4 bytes.
+ * On the PLB, the 10/100 EMAC requires data to be aligned to 8 bytes.
+ * For simplicity, we always align to 8 bytes.
+ */
+#define ALIGNMENT         8
+
+/* BUFFER_ALIGN(adr) calculates the number of bytes to the next alignment. */
+#define BUFFER_ALIGN(adr) ((ALIGNMENT - ((u32) adr)) % ALIGNMENT)
+
+/* physical to virtual pointer conversion */
+#define P_TO_V(InstancePtr, p) \
+	((p) ? \
+	 ((InstancePtr)->VirtPtr + ((u32)(p) - (u32)(InstancePtr)->PhyPtr)) : \
+	 0)
+
+int bh_entry = 0;
+
+/*
+ * Our private per device data.  When a net_device is allocated we will
+ * ask for enough extra space for this.
+ */
+struct net_local {
+	struct list_head rcv;
+	XBufDescriptor * rcvBdPtr;
+	int rcvBds;
+	struct list_head xmit;
+	XBufDescriptor * xmitBdPtr;
+	int xmitBds;
+
+	struct net_device_stats stats;	/* Statistics for this device */
+	struct net_device *next_dev;	/* The next device in dev_list */
+	struct net_device *dev;		/* this device */
+	struct timer_list phy_timer;	/* PHY monitoring timer */
+	u32 index;		/* Which interface is this */
+	XInterruptHandler Isr;	/* Pointer to the XEmac ISR routine */
+	u8 mii_addr;		/* The MII address of the PHY */
+	/*
+	 * The underlying OS independent code needs space as well.  A
+	 * pointer to the following XEmac structure will be passed to
+	 * any XEmac_ function that requires it.  However, we treat the
+	 * data as an opaque object in this file (meaning that we never
+	 * reference any of the fields inside of the structure).
+	 */
+	XEmac Emac;
+
+	void *desc_space;
+	dma_addr_t desc_space_handle;
+	int desc_space_size;
+    
+        u8 *ddrVirtPtr;
+        u32 ddrOffset;
+        u32 ddrSize;
+
+	struct sk_buff* deferred_skb;
+
+        atomic_t availSendBds;
+};
+
+/* List of devices we're handling and a lock to give us atomic access. */
+static struct net_device *dev_list = NULL;
+static spinlock_t dev_lock = SPIN_LOCK_UNLOCKED;
+
+/* for exclusion of all program flows (processes, ISRs and BHs) possible to share data with current one */
+static spinlock_t reset_lock = SPIN_LOCK_UNLOCKED;
+
+/* Helper function to determine if a given XEmac error warrants a reset. */
+extern inline int
+status_requires_reset(XStatus s)
+{
+	return (s == XST_DMA_ERROR || s == XST_FIFO_ERROR ||
+		s == XST_RESET_ERROR || s == XST_DMA_SG_NO_LIST ||
+		s == XST_DMA_SG_LIST_EMPTY);
+}
+
+/* BH statics */
+LIST_HEAD(receivedQueue);
+static spinlock_t rcvSpin = SPIN_LOCK_UNLOCKED;
+LIST_HEAD(sentQueue);
+static spinlock_t xmitSpin = SPIN_LOCK_UNLOCKED;
+
+/* SAATODO: This function will be moved into the Xilinx code. */
+/*****************************************************************************/
+/**
+*
+* Lookup the device configuration based on the emac instance.  The table
+* EmacConfigTable contains the configuration info for each device in the system.
+*
+* @param Instance is the index of the emac being looked up.
+*
+* @return
+*
+* A pointer to the configuration table entry corresponding to the given
+* device ID, or NULL if no match is found.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XEmac_Config *
+XEmac_GetConfig(int Instance)
+{
+	if (Instance < 0 || Instance >= CONFIG_XILINX_ETHERNET_NUM_INSTANCES) {
+		return NULL;
+	}
+
+	return &XEmac_ConfigTable[Instance];
+}
+
+/*
+ * The following are notes regarding the critical sections in this
+ * driver and how they are protected.
+ *
+ * dev_list
+ * There is a spinlock protecting the device list.  It isn't really
+ * necessary yet because the list is only manipulated at init and
+ * cleanup, but it's there because it is basically free and if we start
+ * doing hot add and removal of ethernet devices when the FPGA is
+ * reprogrammed while the system is up, we'll need to protect the list.
+ *
+ * XEmac_Start, XEmac_Stop and XEmac_SetOptions are not thread safe.
+ * These functions are called from xenet_open(), xenet_close(), reset(),
+ * and xenet_set_multicast_list().  xenet_open() and xenet_close()
+ * should be safe because when they do start and stop, they don't have
+ * interrupts or timers enabled.  The other side is that they won't be
+ * called while a timer or interrupt is being handled.
+ *
+ * XEmac_PhyRead and XEmac_PhyWrite are not thread safe.
+ * These functions are called from get_phy_status(), xenet_ioctl() and
+ * probe().  probe() is only called from xenet_init() so it is not an
+ * issue (nothing is really up and running yet).  get_phy_status() is
+ * called from both poll_mii() (a timer bottom half) and xenet_open().
+ * These shouldn't interfere with each other because xenet_open() is
+ * what starts the poll_mii() timer.  xenet_open() and xenet_ioctl()
+ * should be safe as well because they will be sequential.  That leaves
+ * the interaction between poll_mii() and xenet_ioctl().  While the
+ * timer bottom half is executing, a new ioctl won't come in so that is
+ * taken care of.  That leaves the one case of the poll_mii timer
+ * popping while handling an ioctl.  To take care of that case, the
+ * timer is deleted when the ioctl comes in and then added back in after
+ * the ioctl is finished.
+ */
+
+typedef enum DUPLEX { UNKNOWN_DUPLEX, HALF_DUPLEX, FULL_DUPLEX } DUPLEX;
+static void
+reset(struct net_device *dev, DUPLEX duplex)
+{
+	struct net_local *lp = (struct net_local *) dev->priv;
+	u32 Options;
+	u8 IfgPart1;
+	u8 IfgPart2;
+	u8 SendThreshold;
+	u32 SendWaitBound;
+	u8 RecvThreshold;
+	u32 RecvWaitBound;
+	int dma_works;
+	int i;
+	XBufDescriptor* BdPtr;
+
+	/* Shouldn't really be necessary, but shouldn't hurt. */
+	netif_stop_queue(dev);
+
+	/*
+	 * XEmac_Reset puts the device back to the default state.  We need
+	 * to save all the settings we don't already know, reset, restore
+	 * the settings, and then restart the emac.
+	 */
+	XEmac_GetInterframeGap(&lp->Emac, &IfgPart1, &IfgPart2);
+	Options = XEmac_GetOptions(&lp->Emac);
+	switch (duplex) {
+	case HALF_DUPLEX:
+		Options &= ~XEM_FDUPLEX_OPTION;
+		break;
+	case FULL_DUPLEX:
+		Options |= XEM_FDUPLEX_OPTION;
+		break;
+	case UNKNOWN_DUPLEX:
+		break;
+	}
+
+	if (XEmac_mIsSgDma(&lp->Emac)) {
+		/*
+		 * The following four functions will return an error if we are
+		 * not doing scatter-gather DMA.  We just checked that so we
+		 * can safely ignore the return values.  We cast them to void
+		 * to make that explicit.
+		 */
+		dma_works = 1;
+		(void) XEmac_GetPktThreshold(&lp->Emac, XEM_SEND,
+					     &SendThreshold);
+		(void) XEmac_GetPktWaitBound(&lp->Emac, XEM_SEND,
+					     &SendWaitBound);
+		(void) XEmac_GetPktThreshold(&lp->Emac, XEM_RECV,
+					     &RecvThreshold);
+		(void) XEmac_GetPktWaitBound(&lp->Emac, XEM_RECV,
+					     &RecvWaitBound);
+	} else
+		dma_works = 0;
+
+	XEmac_Reset(&lp->Emac);
+
+	/*
+	 * The following three functions will return an error if the
+	 * EMAC is already started.  We just stopped it by calling
+	 * XEmac_Reset() so we can safely ignore the return values.
+	 * We cast them to void to make that explicit.
+	 */
+	(void) XEmac_SetMacAddress(&lp->Emac, dev->dev_addr);
+	(void) XEmac_SetInterframeGap(&lp->Emac, IfgPart1, IfgPart2);
+	(void) XEmac_SetOptions(&lp->Emac, Options);
+	if (XEmac_mIsSgDma(&lp->Emac)) {
+		/*
+		 * The following four functions will return an error if
+		 * we are not doing scatter-gather DMA or if the EMAC is
+		 * already started.  We just checked that we are indeed
+		 * doing scatter-gather and we just stopped the EMAC so
+		 * we can safely ignore the return values.  We cast them
+		 * to void to make that explicit.
+		 */
+		(void) XEmac_SetPktThreshold(&lp->Emac, XEM_SEND,
+					     SendThreshold);
+		(void) XEmac_SetPktWaitBound(&lp->Emac, XEM_SEND,
+					     SendWaitBound);
+		(void) XEmac_SetPktThreshold(&lp->Emac, XEM_RECV,
+					     RecvThreshold);
+		(void) XEmac_SetPktWaitBound(&lp->Emac, XEM_RECV,
+					     RecvWaitBound);
+	}
+
+	/*
+	 * XEmac_Start returns an error when: it is already started, the send
+	 * and receive handlers are not set, or a scatter-gather DMA list is
+	 * missing.  None of these can happen at this point, so we cast the
+	 * return to void to make that explicit.
+	 */
+
+	if (dma_works) {
+		int avail_plus = 0;
+		while (!(XDmaChannel_IsSgListEmpty(&(lp->Emac.SendChannel)))) {	/* list isn't empty, has to be cleared */
+			XStatus ret;
+			XBufDescriptor* BdPtr;
+
+			if ((ret = XDmaChannel_GetDescriptor (&(lp->Emac.SendChannel), &BdPtr)) != XST_SUCCESS) {
+				printk (KERN_ERR "SgDma ring structure ERROR %d\n", ret);
+				break;
+			}
+			avail_plus++;
+			XBufDescriptor_Unlock(BdPtr);
+			/* Microblaze requires no explicit bus mapping/unmapping */
+		#if 0
+			pci_unmap_single(NULL,
+				(u32) XBufDescriptor_GetSrcAddress(BdPtr),
+				 XBufDescriptor_GetLength(BdPtr), PCI_DMA_TODEVICE);
+		#endif
+			lp->stats.tx_errors++;
+		}
+        	atomic_add(avail_plus,&lp->availSendBds);
+	} else {
+		if (lp->deferred_skb) {
+			dev_kfree_skb(lp->deferred_skb);
+			lp->deferred_skb = NULL;
+			lp->stats.tx_errors++;
+		}
+	}
+
+	dev->trans_start = 0xffffffff - TX_TIMEOUT - TX_TIMEOUT;	/* to exclude tx timeout */
+	(void) XEmac_Start(&lp->Emac);
+	/* We're all ready to go.  Start the queue in case it was stopped. */
+	if (!bh_entry)
+		netif_wake_queue(dev);
+}
+
+static int
+get_phy_status(struct net_device *dev, DUPLEX * duplex, int *linkup)
+{
+	struct net_local *lp = (struct net_local *) dev->priv;
+	u16 reg;
+	XStatus xs;
+
+	xs = XEmac_PhyRead(&lp->Emac, lp->mii_addr, MII_BMCR, &reg);
+	if (xs != XST_SUCCESS) {
+		printk(KERN_ERR
+		       "%s: Could not read PHY control register; error %d\n",
+		       dev->name, xs);
+		return -1;
+	}
+
+	if (!(reg & BMCR_ANENABLE)) {
+		/*
+		 * Auto-negotiation is disabled so the full duplex bit in
+		 * the control register tells us if the PHY is running
+		 * half or full duplex.
+		 */
+		*duplex = (reg & BMCR_FULLDPLX) ? FULL_DUPLEX : HALF_DUPLEX;
+	} else {
+		/*
+		 * Auto-negotiation is enabled.  Figure out what was
+		 * negotiated by looking for the best mode in the union
+		 * of what we and our partner advertise.
+		 */
+		u16 advertise, partner, negotiated;
+
+		xs = XEmac_PhyRead(&lp->Emac, lp->mii_addr,
+				   MII_ADVERTISE, &advertise);
+		if (xs != XST_SUCCESS) {
+			printk(KERN_ERR
+			       "%s: Could not read PHY advertisement; error %d\n",
+			       dev->name, xs);
+			return -1;
+		}
+		xs = XEmac_PhyRead(&lp->Emac, lp->mii_addr, MII_LPA, &partner);
+		if (xs != XST_SUCCESS) {
+			printk(KERN_ERR
+			       "%s: Could not read PHY LPA; error %d\n",
+			       dev->name, xs);
+			return -1;
+		}
+
+		negotiated = advertise & partner & ADVERTISE_ALL;
+		if (negotiated & ADVERTISE_100FULL)
+			*duplex = FULL_DUPLEX;
+		else if (negotiated & ADVERTISE_100HALF)
+			*duplex = HALF_DUPLEX;
+		else if (negotiated & ADVERTISE_10FULL)
+			*duplex = FULL_DUPLEX;
+		else
+			*duplex = HALF_DUPLEX;
+	}
+
+	xs = XEmac_PhyRead(&lp->Emac, lp->mii_addr, MII_BMSR, &reg);
+	if (xs != XST_SUCCESS) {
+		printk(KERN_ERR
+		       "%s: Could not read PHY status register; error %d\n",
+		       dev->name, xs);
+		return -1;
+	}
+
+	*linkup = (reg & BMSR_LSTATUS) != 0;
+
+	return 0;
+}
+
+/*
+ * This routine is used for two purposes.  The first is to keep the
+ * EMAC's duplex setting in sync with the PHY's.  The second is to keep
+ * the system apprised of the state of the link.  Note that this driver
+ * does not configure the PHY.  Either the PHY should be configured for
+ * auto-negotiation or it should be handled by something like mii-tool.
+ */
+static void
+poll_mii(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *) data;
+	struct net_local *lp = (struct net_local *) dev->priv;
+	u32 Options;
+	DUPLEX phy_duplex, mac_duplex;
+	int phy_carrier, netif_carrier;
+	unsigned long flags;
+
+	/* First, find out what's going on with the PHY. */
+	if (get_phy_status(dev, &phy_duplex, &phy_carrier)) {
+		printk(KERN_ERR "%s: Terminating link monitoring.\n",
+		       dev->name);
+		return;
+	}
+
+	/* Second, figure out if we have the EMAC in half or full duplex. */
+	Options = XEmac_GetOptions(&lp->Emac);
+	mac_duplex = (Options & XEM_FDUPLEX_OPTION) ? FULL_DUPLEX : HALF_DUPLEX;
+
+	/* Now see if there is a mismatch. */
+	if (mac_duplex != phy_duplex) {
+		/*
+		 * Make sure that no interrupts come in that could cause
+		 * reentrancy problems in reset.
+		 */
+		spin_lock_irqsave(reset_lock, flags);
+		reset(dev, phy_duplex);		/* the function sets Emac options to match the PHY */
+		spin_unlock_irqrestore(reset_lock, flags);
+		if (mac_duplex == FULL_DUPLEX)
+			printk(KERN_INFO "%s: Duplex has been changed: now %s\n",
+				dev->name, "HALF_DUPLEX");
+		else
+			printk(KERN_INFO "%s: Duplex has been changed: now %s\n",
+				dev->name, "FULL_DUPLEX");
+	}
+	netif_carrier = netif_carrier_ok(dev) != 0;
+
+	if (phy_carrier != netif_carrier) {
+		if (phy_carrier) {
+			printk(KERN_INFO "%s: Link carrier restored.\n",
+			       dev->name);
+			netif_carrier_on(dev);
+		} else {
+			printk(KERN_INFO "%s: Link carrier lost.\n", dev->name);
+			netif_carrier_off(dev);
+		}
+	}
+
+	/* Set up the timer so we'll get called again in 2 seconds. */
+	lp->phy_timer.expires = jiffies + 2 * HZ;
+	add_timer(&lp->phy_timer);
+}
+
+/*
+ * This routine is registered with the OS as the function to call when
+ * the EMAC interrupts.  It in turn, calls the Xilinx OS independent
+ * interrupt function.  There are different interrupt functions for FIFO
+ * and scatter-gather so we just set a pointer (Isr) into our private
+ * data so we don't have to figure it out here.  The Xilinx OS
+ * independent interrupt function will in turn call any callbacks that
+ * we have registered for various conditions.
+ */
+static void
+xenet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = dev_id;
+	struct net_local *lp = (struct net_local *) dev->priv;
+
+	/* Call it. */
+	(*(lp->Isr)) (&lp->Emac);
+}
+
+static int
+xenet_open(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) dev->priv;
+	u32 Options;
+	DUPLEX phy_duplex, mac_duplex;
+	int phy_carrier;
+
+	/*
+	 * Just to be safe, stop the device first.  If the device is already
+	 * stopped, an error will be returned.  In this case, we don't really
+	 * care, so cast it to void to make it explicit.
+	 */
+	(void) XEmac_Stop(&lp->Emac);
+	/* Set the MAC address each time opened. */
+	if (XEmac_SetMacAddress(&lp->Emac, dev->dev_addr) != XST_SUCCESS) {
+		printk(KERN_ERR "%s: Could not set MAC address.\n", dev->name);
+		return -EIO;
+	}
+
+	/*
+	 * If the device is not configured for polled mode, connect to the
+	 * interrupt controller and enable interrupts.  Currently, there
+	 * isn't any code to set polled mode, so this check is probably
+	 * superfluous.
+	 */
+	Options = XEmac_GetOptions(&lp->Emac);
+	if ((Options & XEM_POLLED_OPTION) == 0) {
+		int retval;
+		/* Grab the IRQ */
+		retval =
+		    request_irq(dev->irq, &xenet_interrupt, 0, dev->name, dev);
+		if (retval) {
+			printk(KERN_ERR
+			       "%s: Could not allocate interrupt %d.\n",
+			       dev->name, dev->irq);
+			return retval;
+		}
+	}
+
+	/* Set the EMAC's duplex setting based upon what the PHY says. */
+	if (!get_phy_status(dev, &phy_duplex, &phy_carrier)) {
+		/* We successfully got the PHY status. */
+		mac_duplex = ((Options & XEM_FDUPLEX_OPTION)
+			      ? FULL_DUPLEX : HALF_DUPLEX);
+		if (mac_duplex != phy_duplex) {
+			switch (phy_duplex) {
+			case HALF_DUPLEX:
+				Options &= ~XEM_FDUPLEX_OPTION;
+				break;
+			case FULL_DUPLEX:
+				Options |= XEM_FDUPLEX_OPTION;
+				break;
+			case UNKNOWN_DUPLEX:
+				break;
+			}
+			/*
+			 * The following function will return an error
+			 * if the EMAC is already started.  We know it
+			 * isn't started so we can safely ignore the
+			 * return value.  We cast it to void to make
+			 * that explicit.
+			 */
+		}
+	}
+	Options |= XEM_FLOW_CONTROL_OPTION;
+	(void) XEmac_SetOptions(&lp->Emac, Options);
+
+	INIT_LIST_HEAD(&(lp->rcv));
+	lp->rcvBds = 0;
+	INIT_LIST_HEAD(&(lp->xmit));
+	lp->xmitBds = 0;
+
+	if (XEmac_Start(&lp->Emac) != XST_SUCCESS) {
+		printk(KERN_ERR "%s: Could not start device.\n", dev->name);
+		free_irq(dev->irq, dev);
+		return -EBUSY;
+	}
+
+	/* We're ready to go. */
+	MOD_INC_USE_COUNT;
+	netif_start_queue(dev);
+
+	/* Set up the PHY monitoring timer. */
+	lp->phy_timer.expires = jiffies + 2 * HZ;
+	lp->phy_timer.data = (unsigned long) dev;
+	lp->phy_timer.function = &poll_mii;
+	add_timer(&lp->phy_timer);
+	return 0;
+}
+static int
+xenet_close(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) dev->priv;
+	unsigned long flags;
+
+	/* Shut down the PHY monitoring timer. */
+	del_timer_sync(&lp->phy_timer);
+
+	netif_stop_queue(dev);
+
+	/*
+	 * If not in polled mode, free the interrupt.  Currently, there
+	 * isn't any code to set polled mode, so this check is probably
+	 * superfluous.
+	 */
+	if ((XEmac_GetOptions(&lp->Emac) & XEM_POLLED_OPTION) == 0)
+		free_irq(dev->irq, dev);
+
+	spin_lock_irqsave(rcvSpin, flags);
+	list_del(&(lp->rcv));
+	spin_unlock_irqrestore(rcvSpin, flags);
+	spin_lock_irqsave(xmitSpin, flags);
+	list_del(&(lp->xmit));
+	spin_unlock_irqrestore(xmitSpin, flags);
+
+	if (XEmac_Stop(&lp->Emac) != XST_SUCCESS) {
+		printk(KERN_ERR "%s: Could not stop device.\n", dev->name);
+		return -EBUSY;
+	}
+
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+static struct net_device_stats *
+xenet_get_stats(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) dev->priv;
+	return &lp->stats;
+}
+
+static int
+xenet_FifoSend(struct sk_buff *orig_skb, struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) dev->priv;
+	struct sk_buff *new_skb;
+	unsigned int len, align;
+	unsigned long flags;
+
+	len = orig_skb->len;
+
+#if 1
+        /* PR FIXME: what follows can be removed if the asserts in the Xilinx
+         * independent drivers change. There is really no need to align the
+         * buffers in FIFO mode. The story is different for simple DMA.
+         */
+
+        /*
+	 * The packet FIFO requires the buffers to be 32/64 bit aligned.
+	 * The sk_buff data is not 32/64 bit aligned, so we have to do this
+	 * copy.  As you probably well know, this is not optimal.
+	 */
+	if (!(new_skb = /*dev_ */ alloc_skb(len + ALIGNMENT, GFP_ATOMIC))) {
+		/* We couldn't get another skb. */
+		dev_kfree_skb(orig_skb);
+		lp->stats.tx_dropped++;
+		printk(KERN_ERR "%s: Could not allocate transmit buffer.\n",
+		       dev->name);
+		netif_wake_queue(dev);
+		return -EBUSY;
+	}
+	/*
+	 * A new skb should have the data word aligned, but this code is
+	 * here just in case that isn't true...  Calculate how many
+	 * bytes we should reserve to get the data to start on a word
+	 * boundary.  */
+	align = BUFFER_ALIGN(new_skb->data);
+	if (align)
+		skb_reserve(new_skb, align);
+
+	/* Copy the data from the original skb to the new one. */
+	skb_put(new_skb, len);
+	memcpy(new_skb->data, orig_skb->data, len);
+        
+	/* Get rid of the original skb. */
+	dev_kfree_skb(orig_skb);
+#else    
+        new_skb = orig_skb;
+#endif
+        spin_lock_irqsave(reset_lock, flags);
+	if (XEmac_FifoSend(&lp->Emac, (u8 *) new_skb->data, len) != XST_SUCCESS) {
+		netif_stop_queue(dev);
+		lp->deferred_skb = new_skb;
+		spin_unlock_irqrestore(reset_lock, flags);
+		return 0;
+	}
+	spin_unlock_irqrestore(reset_lock, flags);
+
+	lp->stats.tx_bytes += len;
+        dev_kfree_skb(new_skb);
+	dev->trans_start = jiffies;
+
+	return 0;
+}
+
+/* The callback function for completed frames sent in FIFO mode. */
+static void
+FifoSendHandler(void *CallbackRef)
+{
+	struct net_device *dev = (struct net_device *) CallbackRef;
+	struct net_local *lp = (struct net_local *) dev->priv;
+
+	if (lp->deferred_skb) {
+		if (XEmac_FifoSend(&lp->Emac, (u8 *) lp->deferred_skb->data, lp->deferred_skb->len) != XST_SUCCESS) {
+			return;
+		} else {
+			dev_kfree_skb(lp->deferred_skb);
+			lp->deferred_skb = NULL;
+			netif_wake_queue(dev);
+		}
+	}
+	lp->stats.tx_packets++;
+}
+
+/* The send function for frames sent in DMA mode. */
+/* Uses the lp->ddrVirtPtr buffer as a staging area for packets.
+   They are copied in there, from where the DMA controller grabs them.
+   This allows the send function to return more quickly, but it seems like 
+   double copying to me.  Might be more efficient to do the DMA xfer from 
+   the incoming sk_buff, and just wait till the transfer completes...
+   If we implement that optimisation, must beware alignment of skb->data,
+   
+*/
+static int
+xenet_SgSend(struct sk_buff *skb, struct net_device *dev)
+{
+        struct net_local *lp = (struct net_local *) dev->priv;
+	unsigned int len;
+	XBufDescriptor bd;
+	int result;
+        u32 physAddr;
+        u8 *virtAddr;
+	unsigned long flags;
+
+        len = skb->len;
+        virtAddr = lp->ddrVirtPtr + lp->ddrOffset;
+
+        if (skb->ip_summed == CHECKSUM_NONE)
+          /*cacheable_*/memcpy(virtAddr, skb->data, len);
+        else
+          skb_copy_and_csum_dev(skb, virtAddr);
+        
+        dev_kfree_skb(skb);
+#if 1
+	/* 
+	 * Microblaze requires no bus mapping, just do 
+	 * a (dummy) virt to phys conversion.
+	 */
+	physAddr = virt_to_phys(virtAddr);
+#else
+	physAddr = (u32) pci_map_single(NULL, virtAddr, len, PCI_DMA_TODEVICE);
+#endif
+
+	/*
+	 * lock the buffer descriptor to prevent lower layers from reusing
+	 * it before the adapter has a chance to deallocate the buffer
+	 * attached to it. The adapter will unlock it in the callback function
+	 * that handles confirmation of transmits
+	 */
+	XBufDescriptor_Initialize(&bd);
+	XBufDescriptor_Lock(&bd);
+	XBufDescriptor_SetSrcAddress(&bd, physAddr);
+	XBufDescriptor_SetLength(&bd, len);
+	XBufDescriptor_SetLast(&bd);
+
+        lp->ddrOffset += len + BUFFER_ALIGN(len);
+        if (lp->ddrOffset + XEM_MAX_FRAME_SIZE > lp->ddrSize)
+          lp->ddrOffset = 0;
+
+	spin_lock_irqsave(reset_lock, flags);
+        result = XEmac_SgSend(&lp->Emac, &bd, XEM_SGDMA_NODELAY);
+
+	if (result != XST_SUCCESS) {
+		lp->stats.tx_dropped++;
+		printk(KERN_ERR "%s: ERROR, Could not send transmit buffer (%d).\n",
+		       dev->name, result);
+                /* we should never get here in the first place, but
+                 * for some reason the kernel doesn't like -EBUSY here,
+                 * so just return 0 and let the stack handle dropped packets.
+                 */
+		spin_unlock_irqrestore(reset_lock, flags);
+                return 0; /* do not return -EBUSY */
+	}
+        
+        if (atomic_dec_and_test(&lp->availSendBds)) {
+		netif_stop_queue(dev);
+        }
+
+	/* If we remove the ddrVirtPtr staging copy, then we must wait
+	   here until the callback function executes.   Doing the DMA transfer
+	   directly from the original sk_buff will save bus action, but
+	   the kernel expects to re-use that sk_buff once the send completes.
+	   A spinlock would probably do the trick */
+
+	dev->trans_start = jiffies;
+	spin_unlock_irqrestore(reset_lock, flags);
+	return 0;
+}
+
+/* The callback function for completed frames sent in DMA mode. */
+static void SgSendHandlerBH (unsigned long p);
+static void SgRecvHandlerBH (unsigned long p);
+
+DECLARE_TASKLET (SgSendBH, SgSendHandlerBH, 0);
+DECLARE_TASKLET (SgRecvBH, SgRecvHandlerBH, 0);
+
+static void
+SgSendHandlerBH (unsigned long p)
+{
+	struct net_device *dev;
+	struct net_local *lp;
+	XBufDescriptor * BdPtr;
+	u32 NumBds;
+	u32 len;
+	XBufDescriptor *curbd;
+	unsigned long flags;
+
+	while (1) {
+		spin_lock_irqsave(xmitSpin,flags);
+		if (list_empty(&sentQueue)) {
+			spin_unlock_irqrestore(xmitSpin,flags);
+			break;
+		}
+		lp = list_entry(sentQueue.next, struct net_local, xmit);
+		list_del_init(&(lp->xmit));
+		NumBds = lp->xmitBds;
+		bh_entry--;
+		BdPtr = lp->xmitBdPtr;
+		dev = lp->dev;
+		atomic_add(NumBds, &lp->availSendBds);
+		while(NumBds != 0) {
+			NumBds--;
+
+			len = XBufDescriptor_GetLength(BdPtr);
+			/* Microblaze requires no explicit bus mapping/unmapping */
+		#if 0
+			pci_unmap_single(NULL,
+				(u32) XBufDescriptor_GetSrcAddress(BdPtr),
+				 len, PCI_DMA_TODEVICE);
+		#endif
+
+			lp->stats.tx_bytes += len;
+			lp->stats.tx_packets++;
+
+			curbd = BdPtr;
+			BdPtr = P_TO_V(&lp->Emac.SendChannel,
+				XBufDescriptor_GetNextPtr(BdPtr));
+			XBufDescriptor_Unlock(curbd);
+		}
+		spin_unlock_irqrestore(xmitSpin,flags);
+		netif_wake_queue(dev);
+	}
+}
+
+static void
+SgSendHandler(void *CallBackRef, XBufDescriptor * BdPtr, u32 NumBds)
+{
+	struct net_device *dev = (struct net_device *) CallBackRef;
+	struct net_local *lp = (struct net_local *) dev->priv;
+	struct list_head* cur_lp = NULL;
+
+	spin_lock(xmitSpin);
+	list_for_each (cur_lp, &sentQueue) {
+		if (cur_lp == &(lp->xmit)) {
+			lp->xmitBds += NumBds;
+			break;
+		}
+	}
+	if (cur_lp != &(lp->xmit)) {
+		lp->xmitBds = NumBds;
+		lp->xmitBdPtr = BdPtr;
+		list_add_tail(&lp->xmit,&sentQueue);
+		bh_entry++;
+		tasklet_schedule (&SgSendBH);
+	}
+	spin_unlock(xmitSpin);
+}
+
+static void
+SgRecvHandlerBH (unsigned long p)
+{
+	struct net_device *dev;
+	struct net_local *lp;
+	XBufDescriptor* BdPtr;
+	int NumBds;
+	struct sk_buff *skb, *new_skb;
+	u32 len, new_skb_vaddr;
+	dma_addr_t skb_vaddr;
+	u32 align;
+	XStatus result;
+	XBufDescriptor *curbd;
+	unsigned long flags;
+
+	while (1) {
+		spin_lock_irqsave(rcvSpin,flags);
+		if (list_empty(&receivedQueue)) {
+			spin_unlock_irqrestore(rcvSpin,flags);
+			break;
+		}
+		lp = list_entry(receivedQueue.next, struct net_local, rcv);
+		list_del_init(&(lp->rcv));
+		NumBds = lp->rcvBds;
+		BdPtr = lp->rcvBdPtr;
+		dev = lp->dev;
+		spin_unlock_irqrestore(rcvSpin,flags);
+		while (NumBds != 0) {
+			NumBds--;
+
+			/* get ptr to skb */
+			skb = (struct sk_buff *) XBufDescriptor_GetId(BdPtr);
+			len = XBufDescriptor_GetLength(BdPtr);
+
+			/* Flush the cache */
+			flush_dcache_range((unsigned)skb,(unsigned)skb+len);
+
+			/* we have all the information we need - move on */
+			curbd = BdPtr;
+			BdPtr = P_TO_V(&lp->Emac.RecvChannel,
+				XBufDescriptor_GetNextPtr(curbd));
+
+			skb_vaddr = (dma_addr_t)XBufDescriptor_GetDestAddress(curbd);
+		#if 0
+			pci_unmap_single(NULL, skb_vaddr, len, PCI_DMA_FROMDEVICE);
+		#endif
+
+			/* replace skb with a new one */
+			new_skb = alloc_skb(XEM_MAX_FRAME_SIZE + ALIGNMENT, GFP_ATOMIC);
+			if (new_skb == 0) {
+				printk("SgRecvHandler: no mem for new_skb\n");
+				return;
+			}
+
+			/* make sure we're long-word aligned */
+			align = BUFFER_ALIGN(new_skb->data);
+			if (align) {
+				skb_reserve(new_skb, align);
+			}
+
+		#if 1
+			/* 
+			 * Microblaze requires no bus mapping
+			 */
+			new_skb_vaddr = (unsigned) (new_skb->data);
+		#else
+			new_skb_vaddr = (u32) pci_map_single(NULL, new_skb->data,
+						     XEM_MAX_FRAME_SIZE,
+						     PCI_DMA_FROMDEVICE);
+		#endif
+
+			XBufDescriptor_SetDestAddress(curbd, new_skb_vaddr);
+			XBufDescriptor_SetLength(curbd, XEM_MAX_FRAME_SIZE);
+			XBufDescriptor_SetId(curbd, new_skb);
+			XBufDescriptor_Unlock(curbd);
+
+			/* give the descriptor back to the driver */
+			result = XEmac_SgRecv(&lp->Emac, curbd);
+			if (result != XST_SUCCESS) {
+				printk("SgRecvHandler: SgRecv unsuccessful\n");
+				return;
+			}
+
+			/* back to the original skb */
+			skb->len = len;
+			skb->dev = dev;
+
+			/* Adjust alignment of ethernet frame to be half-word
+			   so that tcp/ip header will be full-word aligned */
+			memmove(skb->head+2, skb->data, skb->len); 
+
+			/* Fix up skbuff ptrs */
+			skb->tail -= (skb->data-(skb->head+2));
+			skb->data=skb->head+2;
+
+			skb->protocol = eth_type_trans(skb, dev);
+			skb->ip_summed = CHECKSUM_NONE;
+
+			lp->stats.rx_packets++;
+			lp->stats.rx_bytes += len;
+
+			netif_rx(skb);          /* Send the packet upstream. */
+		}
+	}
+}
+
+static void
+SgRecvHandler(void *CallBackRef, XBufDescriptor * BdPtr, u32 NumBds)
+{
+	struct net_device *dev = (struct net_device *) CallBackRef;
+	struct net_local *lp = (struct net_local *) dev->priv;
+	struct list_head* cur_lp = NULL;
+
+	spin_lock(rcvSpin);
+	list_for_each (cur_lp, &receivedQueue) {
+		if (cur_lp == &(lp->rcv)) {
+			lp->rcvBds += NumBds;
+			break;
+		}
+	}
+	if (cur_lp != &(lp->rcv)) {
+		lp->rcvBds = NumBds;
+		lp->rcvBdPtr = BdPtr;
+		list_add_tail(&lp->rcv, &receivedQueue);
+		tasklet_schedule (&SgRecvBH);
+	}
+	spin_unlock(rcvSpin);
+}
+
+static void
+xenet_tx_timeout(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) dev->priv;
+	unsigned long flags;
+
+	printk("%s: Exceeded transmit timeout of %lu ms.\n",
+	       dev->name, TX_TIMEOUT * 1000UL / HZ);
+
+	lp->stats.tx_errors++;
+	spin_lock_irqsave(reset_lock, flags);
+	reset(dev, UNKNOWN_DUPLEX);
+	spin_unlock_irqrestore(reset_lock, flags);
+}
+
+/* The callback function for frames received when in FIFO mode. */
+static void
+FifoRecvHandler(void *CallbackRef)
+{
+	struct net_device *dev = (struct net_device *) CallbackRef;
+	struct net_local *lp = (struct net_local *) dev->priv;
+	struct sk_buff *skb;
+	unsigned int align;
+	u32 len;
+	XStatus Result;
+
+	/*
+	 * The OS independent Xilinx EMAC code does not provide a
+	 * function to get the length of an incoming packet and a
+	 * separate call to actually get the packet data.  It does this
+	 * because they didn't add any code to keep the hardware's
+	 * receive length and data FIFOs in sync.  Instead, they require
+	 * that you send a maximal length buffer so that they can read
+	 * the length and data FIFOs in a single chunk of code so that
+	 * they can't get out of sync.  So, we need to allocate an skb
+	 * that can hold a maximal sized packet.  The OS independent
+	 * code needs to see the data 32/64-bit aligned, so we tack on an
+	 * extra four just in case we need to do an skb_reserve to get
+	 * it that way.
+	 */
+	len = XEM_MAX_FRAME_SIZE;
+	if (!(skb = /*dev_ */ alloc_skb(len + ALIGNMENT, GFP_ATOMIC))) {
+		/* Couldn't get memory. */
+		lp->stats.rx_dropped++;
+		printk(KERN_ERR "%s: Could not allocate receive buffer.\n",
+		       dev->name);
+		return;
+	}
+
+	/*
+	 * A new skb should have the data word aligned, but this code is
+	 * here just in case that isn't true...  Calculate how many
+	 * bytes we should reserve to get the data to start on a word
+	 * boundary.  */
+	align = BUFFER_ALIGN(skb->data);
+	if (align)
+		skb_reserve(skb, align);
+
+	Result = XEmac_FifoRecv(&lp->Emac, (u8 *) skb->data, &len);
+	if (Result != XST_SUCCESS) {
+		int need_reset = status_requires_reset(Result);
+
+		lp->stats.rx_errors++;
+		dev_kfree_skb(skb);
+		printk(KERN_ERR "%s: Could not receive buffer, error=%d%s.\n",
+		       dev->name, Result,
+			need_reset ? ", resetting device." : "");
+		if (need_reset) {
+			spin_lock(reset_lock);
+			reset(dev, UNKNOWN_DUPLEX);
+			spin_unlock(reset_lock);
+		}
+
+		return;
+	}
+
+	skb_put(skb, len);	/* Tell the skb how much data we got. */
+	skb->dev = dev;		/* Fill out required meta-data. */
+
+	/* Microblaze can't do unaligned struct accesses, meaning that the
+	   IP headers must reside on a word-boundary.  However, we must also
+	   keep the ethernet header intact, for the packet_socket interface to
+	   work.  The ethernet header is 22 bytes long...
+
+	   The solution?  Move the packet contents so that the ethernet
+	   header is halfword aligned, thus the IP header is word aligned.
+	   It's not pretty, but it works.  JW
+	*/
+
+	/* Move the packet data.  Earlier code ensured that skb->head
+	   is word aligned, so skb->head+2 will always be halfword aligned */
+	memmove(skb->head+2, skb->data, skb->len);
+
+	/* fix up skbuff ptrs */
+	skb->tail -= (skb->data-(skb->head+2));
+	skb->data=skb->head+2;
+
+	skb->protocol = eth_type_trans(skb, dev);
+        skb->ip_summed = CHECKSUM_NONE;
+
+	lp->stats.rx_packets++;
+	lp->stats.rx_bytes += len;
+
+	netif_rx(skb);		/* Send the packet upstream. */
+}
+
+/* The callback function for errors. */
+static void
+ErrorHandler(void *CallbackRef, XStatus Code)
+{
+	struct net_device *dev = (struct net_device *) CallbackRef;
+	int need_reset = status_requires_reset(Code);
+	unsigned long flags;
+
+        /* ignore some errors */
+        if (Code == XST_DMA_ERROR)
+          return;
+	printk(KERN_ERR "%s: device error %d%s\n",
+	       dev->name, Code,need_reset ? ", resetting device." : "");
+	if (need_reset) {
+		spin_lock_irqsave(reset_lock, flags);
+		reset(dev, UNKNOWN_DUPLEX);
+		spin_unlock_irqrestore(reset_lock, flags);
+	}
+}
+
+static int
+descriptor_init(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) dev->priv;
+	int i, recvsize, sendsize;
+	int dftsize;
+	u32 *recvpoolptr, *sendpoolptr;
+	void *recvpoolphy, *sendpoolphy;
+
+	/* calc size of descriptor space pool; alloc from non-cached memory */
+	dftsize = (XEM_DFT_RECV_DESC + XEM_DFT_SEND_DESC) *
+	    sizeof (XBufDescriptor);
+        
+	lp->desc_space = consistent_alloc(GFP_ATOMIC, dftsize,
+					  &lp->desc_space_handle);
+	if (lp->desc_space == 0) {
+		return -1;
+	}
+	lp->desc_space_size = dftsize;
+
+        lp->ddrSize = XEM_DFT_SEND_DESC * (XEM_MAX_FRAME_SIZE + ALIGNMENT);
+        lp->ddrOffset = 0;
+        lp->ddrVirtPtr = kmalloc(lp->ddrSize, GFP_ATOMIC);
+        
+        if (lp->ddrVirtPtr == 0)
+          return -1;
+
+        atomic_set(&lp->availSendBds, XEM_DFT_SEND_DESC);
+
+	/* calc size of send and recv descriptor space */
+	recvsize = XEM_DFT_RECV_DESC * sizeof (XBufDescriptor);
+	sendsize = XEM_DFT_SEND_DESC * sizeof (XBufDescriptor);
+
+	recvpoolptr = lp->desc_space;
+	sendpoolptr = (void *) ((u32) lp->desc_space + recvsize);
+
+	recvpoolphy = (void *) lp->desc_space_handle;
+	sendpoolphy = (void *) ((u32) lp->desc_space_handle + recvsize);
+
+	/* add ptr to descriptor space to the driver */
+	XEmac_SetSgRecvSpace(&lp->Emac, recvpoolptr, recvsize, recvpoolphy);
+	XEmac_SetSgSendSpace(&lp->Emac, sendpoolptr, sendsize, sendpoolphy);
+
+	/* allocate skb's and give them to the dma engine */
+	for (i = 0; i < XEM_DFT_RECV_DESC; i++) {
+		struct sk_buff *skb;
+		XBufDescriptor bd;
+		int result;
+		u32 skb_vaddr, align;
+
+		skb = alloc_skb(XEM_MAX_FRAME_SIZE + ALIGNMENT, GFP_ATOMIC);
+		if (skb == 0) {
+			return -1;
+		}
+
+		align = BUFFER_ALIGN(skb->data);
+		if (align)
+			skb_reserve(skb, align);
+
+	#if 1
+		/* 
+		 * Microblaze requires no bus mapping
+		 */
+		skb_vaddr = (unsigned) (skb->data);
+	#else
+		skb_vaddr = (u32) pci_map_single(NULL, skb->data,
+						 XEM_MAX_FRAME_SIZE,
+						 PCI_DMA_FROMDEVICE);
+	#endif
+		/*
+		 * initialize descriptors and set buffer address
+		 * buffer length gets max frame size
+		 */
+		XBufDescriptor_Initialize(&bd);
+		XBufDescriptor_Lock(&bd);
+		XBufDescriptor_SetDestAddress(&bd, skb_vaddr);
+		XBufDescriptor_SetLength(&bd, XEM_MAX_FRAME_SIZE);
+		XBufDescriptor_SetId(&bd, skb);
+
+		/*
+		 * descriptor with attached buffer to the driver and
+		 * let it make it ready for frame reception
+		 */
+		result = XEmac_SgRecv(&lp->Emac, &bd);
+		if (result != XST_SUCCESS) {
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+void
+free_descriptor_skb (struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) dev->priv;
+	int i;
+	XBufDescriptor* BdPtr;
+	struct sk_buff* skb;
+
+	BdPtr = (XBufDescriptor*)lp->Emac.RecvChannel.VirtPtr;
+	for (i=0; i<XEM_DFT_RECV_DESC; i++) {
+		skb = (struct sk_buff*)XBufDescriptor_GetId(BdPtr);
+		/* Microblaze requires no explicit bus mapping/unmapping */
+	#if 0
+		pci_unmap_single(NULL, virt_to_bus(skb->data), XBufDescriptor_GetLength(BdPtr), PCI_DMA_FROMDEVICE);
+	#endif
+		dev_kfree_skb(skb);
+		BdPtr = P_TO_V(&lp->Emac.RecvChannel,XBufDescriptor_GetNextPtr(BdPtr));
+	}
+}
+
+static int
+xenet_ethtool_get_settings (struct net_device *dev, struct ethtool_cmd* ecmd)
+{
+	int ret;
+	struct net_local *lp = (struct net_local *) dev->priv;
+	u32 mac_options;
+	u8 threshold;
+	u16 mii_cmd;
+	u16 mii_status;
+	u16 mii_advControl;
+	XStatus xs;
+
+	memset (ecmd, 0, sizeof(struct ethtool_cmd));
+	mac_options = XEmac_GetOptions (&(lp->Emac));
+	xs = XEmac_PhyRead(&lp->Emac, lp->mii_addr, MII_BMCR, &mii_cmd);
+	if (xs != XST_SUCCESS) {
+		printk(KERN_ERR
+		       "%s: Could not read mii command register; error %d\n",
+		       dev->name, xs);
+		return -1;
+	}
+	xs = XEmac_PhyRead(&lp->Emac, lp->mii_addr, MII_BMSR, &mii_status);
+	if (xs != XST_SUCCESS) {
+		printk(KERN_ERR
+		       "%s: Could not read mii status register; error %d\n",
+		       dev->name, xs);
+		return -1;
+	}
+	xs = XEmac_PhyRead(&lp->Emac, lp->mii_addr, MII_ADVERTISE, &mii_advControl);
+	if (xs != XST_SUCCESS) {
+		printk(KERN_ERR
+		       "%s: Could not read mii advertisement control register; error %d\n",
+		       dev->name, xs);
+		return -1;
+	}
+
+	if (mac_options & XEM_FDUPLEX_OPTION)
+		ecmd->duplex = DUPLEX_FULL;
+	else
+		ecmd->duplex = DUPLEX_HALF;
+	if (mii_status & BMSR_100FULL)
+		ecmd->supported |= SUPPORTED_100baseT_Full;
+	if (mii_status & BMSR_100HALF)
+		ecmd->supported |= SUPPORTED_100baseT_Half;
+	if (mii_status & BMSR_10FULL)
+		ecmd->supported |= SUPPORTED_10baseT_Full;
+	if (mii_status & BMSR_10HALF)
+		ecmd->supported |= SUPPORTED_10baseT_Half;
+	if (lp->Emac.HasMii)
+		ecmd->supported |= SUPPORTED_MII;
+	else
+		ecmd->supported &= (~SUPPORTED_MII);
+	if (mii_status & BMSR_ANEGCAPABLE)
+		ecmd->supported |= SUPPORTED_Autoneg;
+	if (mii_status & BMSR_ANEGCOMPLETE) {
+		ecmd->autoneg = AUTONEG_ENABLE;
+		ecmd->advertising |= ADVERTISED_Autoneg;
+		if ((mii_advControl & ADVERTISE_100FULL) || (mii_advControl & ADVERTISE_100HALF))
+			ecmd->speed = SPEED_100;
+		else
+			ecmd->speed = SPEED_10;
+	} else {
+		ecmd->autoneg = AUTONEG_DISABLE;
+		if (mii_cmd & BMCR_SPEED100)
+			ecmd->speed = SPEED_100;
+		else
+			ecmd->speed = SPEED_10;
+	}
+	if (mii_advControl & ADVERTISE_10FULL)
+		ecmd->advertising |= ADVERTISED_10baseT_Full;
+	if (mii_advControl & ADVERTISE_10HALF)
+		ecmd->advertising |= ADVERTISED_10baseT_Half;
+	if (mii_advControl & ADVERTISE_100FULL)
+		ecmd->advertising |= ADVERTISED_100baseT_Full;
+	if (mii_advControl & ADVERTISE_100HALF)
+		ecmd->advertising |= ADVERTISED_100baseT_Half;
+	ecmd->advertising |= ADVERTISED_MII;
+	ecmd->port = PORT_MII;
+	ecmd->phy_address = lp->Emac.PhysAddress;
+	ecmd->transceiver = XCVR_INTERNAL;
+	if (XEmac_mIsSgDma(&lp->Emac)) {
+		if ((ret = XEmac_GetPktThreshold(&lp->Emac, XEM_SEND, &threshold)) == XST_SUCCESS) {
+			ecmd->maxtxpkt = threshold;
+		} else
+			return -EIO;
+		if ((ret = XEmac_GetPktThreshold(&lp->Emac, XEM_RECV, &threshold)) == XST_SUCCESS) {
+			ecmd->maxrxpkt = threshold;
+		} else
+			return -EIO;
+	}
+	return 0;
+}
+
+static int
+xenet_ethtool_get_coalesce (struct net_device *dev, struct ethtool_coalesce* ec)
+{
+	int ret;
+	struct net_local *lp = (struct net_local *) dev->priv;
+	u8 threshold;
+
+	memset (ec, 0, sizeof(struct ethtool_coalesce));
+	if ((ret = XEmac_GetPktThreshold(&lp->Emac, XEM_RECV, &threshold)) != XST_SUCCESS) {
+		printk(KERN_INFO "XEmac_GetPktThreshold error %d\n", ret);
+		return -EIO;
+	}
+	ec->rx_max_coalesced_frames = threshold;
+	if ((ret = XEmac_GetPktWaitBound (&lp->Emac, XEM_RECV, &(ec->rx_coalesce_usecs))) != XST_SUCCESS) {
+		printk (KERN_INFO "XEmac_GetPktWaitBound error %d\n", ret);
+		return -EIO;
+	}
+	if ((ret = XEmac_GetPktThreshold(&lp->Emac, XEM_SEND, &threshold)) != XST_SUCCESS) {
+		printk (KERN_INFO "XEmac_GetPktThreshold send error %d\n", ret);
+		return -EIO;
+	}
+	ec->tx_max_coalesced_frames = threshold; 
+	if ((ret = XEmac_GetPktWaitBound (&lp->Emac, XEM_SEND, &(ec->tx_coalesce_usecs))) != XST_SUCCESS) {
+		printk (KERN_INFO "XEmac_GetPktWaitBound send error %d\n", ret);
+		return -EIO;
+	}
+	return 0;
+}
+
+static int
+xenet_ethtool_set_coalesce (struct net_device *dev, struct ethtool_coalesce* ec)
+{
+	int ret;
+	struct net_local *lp = (struct net_local *) dev->priv;
+	unsigned long flags;
+
+	spin_lock_irqsave(reset_lock, flags);
+	if ((ret = XEmac_Stop(&lp->Emac)) != XST_SUCCESS)
+		return -EIO;
+	if ((ret = XEmac_SetPktThreshold(&lp->Emac, XEM_RECV, ec->rx_max_coalesced_frames)) != XST_SUCCESS) {
+		printk (KERN_INFO "XEmac_SetPktThreshold error %d\n", ret);
+		return -EIO;
+	} 
+	if ((ret = XEmac_SetPktWaitBound (&lp->Emac, XEM_RECV, ec->rx_coalesce_usecs)) != XST_SUCCESS) {
+		printk (KERN_INFO "XEmac_SetPktWaitBound error %d\n", ret);
+		return -EIO;
+	}
+	if ((ret = XEmac_SetPktThreshold(&lp->Emac, XEM_SEND, ec->tx_max_coalesced_frames)) != XST_SUCCESS) {
+		printk (KERN_INFO "XEmac_SetPktThreshold send error %d\n", ret);
+		return -EIO;
+	} 
+	if ((ret = XEmac_SetPktWaitBound (&lp->Emac, XEM_SEND, ec->tx_coalesce_usecs)) != XST_SUCCESS) {
+		printk (KERN_INFO "XEmac_SetPktWaitBound send error %d\n", ret);
+		return -EIO;
+	}
+	if ((ret = XEmac_Start(&lp->Emac)) != XST_SUCCESS)
+		return -EIO;
+	spin_unlock_irqrestore(reset_lock, flags);
+	return 0;
+}
+
+static int
+xenet_ethtool_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo* ed)
+{
+	memset (ed, 0, sizeof(struct ethtool_drvinfo));
+	strcpy (ed->driver, DRIVER_NAME);
+	strcpy (ed->version, DRIVER_VERSION);
+	return 0; 
+}
+
+static int
+xenet_ethtool_get_ringparam (struct net_device *dev, struct ethtool_ringparam* erp)
+{
+	memset (erp, 0, sizeof(struct ethtool_ringparam));
+	erp->rx_max_pending = XEM_DFT_RECV_DESC;
+	erp->tx_max_pending = XEM_DFT_SEND_DESC;
+	erp->rx_pending = XEM_DFT_RECV_DESC;
+	erp->tx_pending = XEM_DFT_SEND_DESC;
+	return 0;
+}
+
+#define EMAG_REGS_N	32
+struct mac_regsDump {
+	struct ethtool_regs hd;
+	u16 data[EMAG_REGS_N];
+};
+
+static void
+xenet_ethtool_get_regs (struct net_device *dev, struct ethtool_regs* regs, void* ret)
+{
+	struct net_local *lp = (struct net_local *) dev->priv;
+	struct mac_regsDump* dump = (struct mac_regsDump*)regs;
+	int i;
+	XStatus r;
+
+	dump->hd.version = 0;
+	dump->hd.len = EMAG_REGS_N * sizeof(dump->data);
+	for (i=0; i<EMAG_REGS_N; i++) {
+		if ((r = XEmac_PhyRead (&(lp->Emac), lp->mii_addr, i, &(dump->data[i]))) != XST_SUCCESS) {
+			printk (KERN_INFO "PhyRead ERROR %d\n", r);
+			*(int*)ret = -EIO;
+			return;
+		}
+	}
+	*(int*)ret = 0;
+}
+
+static int
+xenet_do_ethtool_ioctl (struct net_device *dev, struct ifreq *rq)
+{
+	struct net_local *lp = (struct net_local *) dev->priv;
+	struct ethtool_cmd ecmd;
+	struct ethtool_coalesce eco;
+	struct ethtool_drvinfo edrv;
+	struct ethtool_ringparam erp;
+	struct ethtool_pauseparam epp;
+	struct mac_regsDump regs;
+	int ret = -EOPNOTSUPP;
+	XStatus result;
+	u32 Options;
+	u16 mii_reg_sset;
+	u16 mii_reg_spause;
+	u16 mii_reg_autoneg;
+	u32 flags;
+
+	if (copy_from_user(&ecmd, rq->ifr_data, sizeof (ecmd.cmd)))
+		return -EFAULT;
+	switch (ecmd.cmd) {
+	case ETHTOOL_GSET:
+		ret = xenet_ethtool_get_settings(dev, &ecmd);
+		if (ret >= 0) {
+			if (copy_to_user(rq->ifr_data, &ecmd, sizeof (ecmd)))
+				ret = -EFAULT;
+		}
+		break;
+	case ETHTOOL_SSET:
+		if (copy_from_user(&ecmd, rq->ifr_data, sizeof (struct ethtool_cmd)))
+			return -EFAULT;
+		mii_reg_sset = 0;
+		if (ecmd.speed == SPEED_100)
+			mii_reg_sset |= BMCR_SPEED100;
+		if (ecmd.duplex == DUPLEX_FULL)
+			mii_reg_sset |= BMCR_FULLDPLX;
+		if (ecmd.autoneg == AUTONEG_ENABLE) {
+			mii_reg_sset |= (BMCR_ANENABLE | BMCR_ANRESTART);
+			spin_lock_irqsave(reset_lock, flags);
+			result = XEmac_PhyWrite(&lp->Emac, lp->mii_addr,
+						MII_BMCR, mii_reg_sset);
+			if (result != XST_SUCCESS) {
+				spin_unlock_irqrestore(reset_lock, flags);
+				ret = -EIO;
+				break;
+			}
+			result = XEmac_PhyRead(&lp->Emac, lp->mii_addr, MII_ADVERTISE, &mii_reg_sset);
+			if (result != XST_SUCCESS) {
+				spin_unlock_irqrestore(reset_lock, flags);
+				ret = -EIO;
+				break;
+			}
+			if (ecmd.speed == SPEED_100) {
+				if (ecmd.duplex == DUPLEX_FULL) {
+					mii_reg_sset |= (ADVERTISE_10FULL | ADVERTISE_100FULL |
+						ADVERTISE_10HALF | ADVERTISE_100HALF);
+				} else {
+					mii_reg_sset |= (ADVERTISE_10HALF | ADVERTISE_100HALF);
+					mii_reg_sset &= ~(ADVERTISE_10FULL | ADVERTISE_100FULL);
+				}
+			} else {
+				if (ecmd.duplex == DUPLEX_FULL) {
+					mii_reg_sset |= (ADVERTISE_10FULL | ADVERTISE_10HALF);
+					mii_reg_sset &= ~(ADVERTISE_100FULL| ADVERTISE_100HALF);
+				} else {
+					mii_reg_sset |= (ADVERTISE_10HALF);
+					mii_reg_sset &= ~(ADVERTISE_100FULL| ADVERTISE_100HALF | ADVERTISE_10FULL);
+				}
+			}
+			result = XEmac_PhyWrite(&lp->Emac, lp->mii_addr, MII_ADVERTISE, mii_reg_sset);
+			spin_unlock_irqrestore(reset_lock, flags);
+			if (result != XST_SUCCESS) {
+				ret = -EIO;
+				break;
+			}
+		} else {
+			mii_reg_sset &= ~(BMCR_ANENABLE | BMCR_ANRESTART);
+			if (ecmd.duplex == DUPLEX_FULL) {
+				mii_reg_sset |= BMCR_FULLDPLX;
+			} else {
+				mii_reg_sset &= ~BMCR_FULLDPLX;
+			}
+			if (ecmd.speed == SPEED_100) {
+				mii_reg_sset |= BMCR_SPEED100;
+			} else {
+				mii_reg_sset &= ~BMCR_SPEED100;
+			}
+			spin_lock_irqsave(reset_lock, flags);
+			result = XEmac_PhyWrite(&lp->Emac, lp->mii_addr,
+						MII_BMCR, mii_reg_sset);
+			spin_unlock_irqrestore(reset_lock, flags);
+			if (result != XST_SUCCESS) {
+				ret = -EIO;
+				break;
+			}
+		}
+		ret = 0;
+		break;
+	case ETHTOOL_GPAUSEPARAM:
+		ret = xenet_ethtool_get_settings(dev, &ecmd);
+		if (ret < 0) {
+			break;
+		}
+		epp.cmd = ecmd.cmd;
+		epp.autoneg = ecmd.autoneg;
+		Options = XEmac_GetOptions(&lp->Emac);
+		if (Options & XEM_INSERT_PAD_OPTION) {
+			epp.rx_pause = 1;
+			epp.tx_pause = 1;
+		} else {
+			epp.rx_pause = 0;
+			epp.tx_pause = 0;
+		}
+		if (copy_to_user(rq->ifr_data, &epp, sizeof(struct ethtool_pauseparam)))
+			ret = -EFAULT;
+		else
+			ret = 0;
+		break;
+	case ETHTOOL_SPAUSEPARAM:
+		if (copy_from_user(&epp, rq->ifr_data, sizeof (struct ethtool_pauseparam)))
+			return -EFAULT;
+		ret = xenet_ethtool_get_settings(dev, &ecmd);
+		if (ret < 0) {
+			break;
+		}
+		epp.cmd = ecmd.cmd;
+		mii_reg_spause = 0;
+		if (epp.autoneg == AUTONEG_ENABLE) {
+			mii_reg_spause |= (BMCR_ANENABLE | BMCR_ANRESTART);
+		} else {
+			if (ecmd.speed == SPEED_100)
+				mii_reg_spause |= BMCR_SPEED100;
+			if (ecmd.duplex == DUPLEX_FULL)
+				mii_reg_spause |= BMCR_FULLDPLX;
+		}
+		spin_lock_irqsave(reset_lock, flags);
+		result = XEmac_PhyWrite(&lp->Emac, lp->mii_addr,
+					MII_BMCR, mii_reg_spause);
+		spin_unlock_irqrestore(reset_lock, flags);
+		if (result != XST_SUCCESS) {
+			ret = -EIO;
+			break;
+		}
+		if (epp.rx_pause != epp.tx_pause) {
+			ret = 0;
+			break;
+		} else {
+			spin_lock_irqsave(reset_lock, flags);
+			(void)XEmac_Stop(&(lp->Emac));
+			Options = XEmac_GetOptions(&lp->Emac);
+			if (epp.rx_pause)
+				Options |= XEM_INSERT_PAD_OPTION;
+			else
+				Options &= ~XEM_INSERT_PAD_OPTION;
+			(void)XEmac_SetOptions(&lp->Emac,Options);
+			(void)XEmac_Start(&(lp->Emac));
+			spin_unlock_irqrestore(reset_lock, flags);
+		}
+		ret = 0;
+		break;
+	case ETHTOOL_GCOALESCE:
+		eco.cmd = ecmd.cmd;
+		ret = xenet_ethtool_get_coalesce(dev, &eco);
+		if (ret >= 0) {
+			if (copy_to_user(rq->ifr_data, &eco, sizeof (struct ethtool_coalesce)))
+				ret = -EFAULT;
+		}
+		break;
+	case ETHTOOL_SCOALESCE:
+		if (copy_from_user(&eco, rq->ifr_data, sizeof (struct ethtool_coalesce)))
+			return -EFAULT;
+		ret = xenet_ethtool_set_coalesce(dev, &eco);
+		break;
+	case ETHTOOL_GDRVINFO:
+		edrv.cmd = edrv.cmd;
+		ret = xenet_ethtool_get_drvinfo(dev, &edrv);
+		if (ret >= 0) {
+			if (copy_to_user(rq->ifr_data, &edrv, sizeof (struct ethtool_drvinfo)))
+				ret = -EFAULT;
+		}
+		break;
+	case ETHTOOL_GREGS:
+		regs.hd.cmd = edrv.cmd;
+		xenet_ethtool_get_regs (dev, &(regs.hd), &ret);
+		if (ret >= 0) {
+			if (copy_to_user(rq->ifr_data, &regs, sizeof (struct mac_regsDump)))
+				ret = -EFAULT;
+		}
+		break;
+	case ETHTOOL_GRINGPARAM:
+		erp.cmd = edrv.cmd;
+		ret = xenet_ethtool_get_ringparam (dev, &(erp));
+		if (ret >= 0) {
+			if (copy_to_user(rq->ifr_data, &erp, sizeof (struct ethtool_ringparam)))
+				ret = -EFAULT;
+		}
+		break;
+	case ETHTOOL_NWAY_RST:
+		epp.cmd = ecmd.cmd;
+		mii_reg_autoneg = 0;
+		mii_reg_autoneg |= (BMCR_ANENABLE | BMCR_ANRESTART);
+		spin_lock_irqsave(reset_lock, flags);
+		result = XEmac_PhyWrite(&lp->Emac, lp->mii_addr,
+					MII_BMCR, mii_reg_autoneg);
+		spin_unlock_irqrestore(reset_lock, flags);
+		if (result != XST_SUCCESS) {
+			ret = -EIO;
+			break;
+		}
+		ret = 0;
+		break;
+	default:
+		break;
+	}
+	return ret;
+}
+
+static int
+xenet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct net_local *lp = (struct net_local *) dev->priv;
+	/* mii_ioctl_data has 4 u16 fields: phy_id, reg_num, val_in & val_out */
+	struct mii_ioctl_data *data = (struct mii_ioctl_data *) &rq->ifr_data;
+	struct {
+		__u8 threshold;
+		__u32 direction;
+	} thr_arg;
+	struct {
+		__u32 waitbound;
+		__u32 direction;
+	} wbnd_arg ;
+	XStatus ret;
+	unsigned long flags;
+
+	XStatus Result;
+
+	switch (cmd) {
+	case SIOCETHTOOL:
+		return xenet_do_ethtool_ioctl(dev, rq);
+	case SIOCGMIIPHY:	/* Get address of MII PHY in use. */
+	case SIOCDEVPRIVATE:	/* for binary compat, remove in 2.5 */
+		data->phy_id = lp->mii_addr;
+		/* Fall Through */
+
+	case SIOCGMIIREG:	/* Read MII PHY register. */
+	case SIOCDEVPRIVATE + 1:	/* for binary compat, remove in 2.5 */
+		if (data->phy_id > 31 || data->reg_num > 31)
+			return -ENXIO;
+
+		/* Stop the PHY timer to prevent reentrancy. */
+		del_timer_sync(&lp->phy_timer);
+		spin_lock_irqsave(reset_lock, flags);
+		Result = XEmac_PhyRead(&lp->Emac, data->phy_id,
+				       data->reg_num, &data->val_out);
+		/* Start the PHY timer up again. */
+		spin_unlock_irqrestore(reset_lock, flags);
+		lp->phy_timer.expires = jiffies + 2 * HZ;
+		add_timer(&lp->phy_timer);
+
+		if (Result != XST_SUCCESS) {
+			printk(KERN_ERR
+			       "%s: Could not read from PHY, error=%d.\n",
+			       dev->name, Result);
+			return (Result == XST_EMAC_MII_BUSY) ? -EBUSY : -EIO;
+		}
+		return 0;
+
+	case SIOCSMIIREG:	/* Write MII PHY register. */
+	case SIOCDEVPRIVATE + 2:	/* for binary compat, remove in 2.5 */
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+
+		if (data->phy_id > 31 || data->reg_num > 31)
+			return -ENXIO;
+
+		/* Stop the PHY timer to prevent reentrancy. */
+		del_timer_sync(&lp->phy_timer);
+		spin_lock_irqsave(reset_lock, flags);
+		Result = XEmac_PhyWrite(&lp->Emac, data->phy_id,
+					data->reg_num, data->val_in);
+		spin_unlock_irqrestore(reset_lock, flags);
+		/* Start the PHY timer up again. */
+		lp->phy_timer.expires = jiffies + 2 * HZ;
+		add_timer(&lp->phy_timer);
+
+		if (Result != XST_SUCCESS) {
+			printk(KERN_ERR
+			       "%s: Could not write to PHY, error=%d.\n",
+			       dev->name, Result);
+			return (Result == XST_EMAC_MII_BUSY) ? -EBUSY : -EIO;
+		}
+		return 0;
+
+	case SIOCDEVPRIVATE + 3:		/* set THRESHOLD */
+		if (copy_from_user(&thr_arg, rq->ifr_data, sizeof(thr_arg))) {
+			return -EFAULT;
+		}
+		spin_lock_irqsave(reset_lock, flags);
+		if ((ret = XEmac_Stop(&lp->Emac)) != XST_SUCCESS) {
+			return -EIO;
+		}
+		if ((ret = XEmac_SetPktThreshold(&lp->Emac, thr_arg.direction, thr_arg.threshold)) != XST_SUCCESS) {
+			return -EIO;
+		}
+		if ((ret = XEmac_Start(&lp->Emac)) != XST_SUCCESS) {
+			return -EIO;
+		}
+		spin_unlock_irqrestore(reset_lock, flags);
+		return 0;
+
+	case SIOCDEVPRIVATE + 4:		/* set WAITBOUND */
+		if (copy_from_user(&wbnd_arg, rq->ifr_data, sizeof(wbnd_arg))) {
+			return -EFAULT;
+		}
+		spin_lock_irqsave(reset_lock, flags);
+		if ((ret = XEmac_Stop(&lp->Emac)) != XST_SUCCESS) {
+			return -EIO;
+		}
+		if ((ret = XEmac_SetPktWaitBound(&lp->Emac, wbnd_arg.direction, wbnd_arg.waitbound)) != XST_SUCCESS) {
+			return -EIO;
+		}
+		if ((ret = XEmac_Start(&lp->Emac)) != XST_SUCCESS) {
+			return -EIO;
+		}
+		spin_unlock_irqrestore(reset_lock, flags);
+		return 0;
+
+	case SIOCDEVPRIVATE + 5:		/* get THRESHOLD */
+		if (copy_from_user(&thr_arg, rq->ifr_data, sizeof(thr_arg))) {
+			return -EFAULT;
+		}
+		if ((ret = XEmac_GetPktThreshold(&lp->Emac, thr_arg.direction, &(thr_arg.threshold))) != XST_SUCCESS) {
+			return -EIO;
+		}
+		if (copy_to_user(rq->ifr_data, &thr_arg, sizeof(thr_arg))) {
+			return -EFAULT;
+		}
+		return 0;
+
+
+	case SIOCDEVPRIVATE + 6:		/* get WAITBOUND */
+		if (copy_from_user(&wbnd_arg, rq->ifr_data, sizeof(wbnd_arg))) {
+			return -EFAULT;
+		}
+		if ((ret = XEmac_GetPktWaitBound(&lp->Emac, wbnd_arg.direction, &(wbnd_arg.waitbound))) != XST_SUCCESS) {
+			return -EIO;
+		}
+		if (copy_to_user(rq->ifr_data, &wbnd_arg, sizeof(wbnd_arg))) {
+			return -EFAULT;
+		}
+		return 0;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static void
+remove_head_dev(void)
+{
+	struct net_local *lp;
+	struct net_device *dev;
+	XEmac_Config *cfg;
+
+	/* Pull the head off of dev_list. */
+	spin_lock(&dev_lock);
+	dev = dev_list;
+	lp = (struct net_local *) dev->priv;
+	dev_list = lp->next_dev;
+	spin_unlock(&dev_lock);
+
+	/* Put the physical address back */
+	cfg = XEmac_GetConfig(lp->index);
+	iounmap((void *) cfg->BaseAddress);
+	cfg->BaseAddress = cfg->PhysAddress;
+
+	/* Free up the memory. */
+	if (lp->desc_space)
+        {
+		free_descriptor_skb(dev);
+		consistent_free(lp->desc_space);
+        }
+
+        if (lp->ddrVirtPtr) {
+	 	kfree (lp->ddrVirtPtr);
+	}
+
+	unregister_netdev(dev);
+	kfree(dev);
+}
+
+static int __init
+probe(int index)
+{
+	static const unsigned long remap_size
+	    = CONFIG_XILINX_ETHERNET_0_HIGHADDR - 
+		CONFIG_XILINX_ETHERNET_0_BASEADDR + 1;
+	struct net_device *dev;
+	struct net_local *lp;
+	XEmac_Config *cfg;
+	unsigned int irq;
+	u32 maddr;
+
+	if(index>=num_ether_devices)
+		return -ENODEV;
+	else
+		irq=ether_table[index].irq;
+
+	/* Find the config for our device. */
+	cfg = XEmac_GetConfig(index);
+	if (!cfg)
+		return -ENODEV;
+
+	dev = init_etherdev(0, sizeof (struct net_local));
+	if (!dev) {
+		printk(KERN_ERR "Could not allocate Xilinx enet device %d.\n",
+		       index);
+		return -ENOMEM;
+	}
+	SET_MODULE_OWNER(dev);
+
+	ether_setup(dev);
+	dev->irq = irq;
+
+	/* Initialize our private data. */
+	lp = (struct net_local *) dev->priv;
+	memset(lp, 0, sizeof (struct net_local));
+	lp->index = index;
+	lp->dev = dev;
+
+	/* Make it the head of dev_list. */
+	spin_lock(&dev_lock);
+	lp->next_dev = dev_list;
+	dev_list = dev;
+	spin_unlock(&dev_lock);
+
+	/* Change the addresses to be virtual */
+	cfg->PhysAddress = ether_table[index].baseaddr;
+	cfg->BaseAddress = (u32) ioremap(cfg->PhysAddress, remap_size);
+
+	if (XEmac_Initialize(&lp->Emac, cfg->DeviceId) != XST_SUCCESS) {
+		printk(KERN_ERR "%s: Could not initialize device.\n",
+		       dev->name);
+		remove_head_dev();
+		return -ENODEV;
+	}
+
+	/* Copy MAC address in from descriptor table */
+        memcpy(dev->dev_addr, ether_table[index].macaddr,6);
+
+	if (XEmac_SetMacAddress(&lp->Emac, dev->dev_addr) != XST_SUCCESS) {
+		/* should not fail right after an initialize */
+		printk(KERN_ERR "%s: Could not set MAC address.\n", dev->name);
+		remove_head_dev();
+		return -EIO;
+	}
+
+	if (XEmac_mIsSgDma(&lp->Emac)) {
+		int result;
+
+		printk(KERN_ERR "%s: using sgDMA mode.\n", dev->name);
+		XEmac_SetSgRecvHandler(&lp->Emac, dev, SgRecvHandler);
+		XEmac_SetSgSendHandler(&lp->Emac, dev, SgSendHandler);
+		dev->hard_start_xmit = xenet_SgSend;
+		lp->Isr = XEmac_IntrHandlerDma;
+
+		result = descriptor_init(dev);
+		if (result) {
+			remove_head_dev();
+			return -EIO;
+		}
+
+                /* set the packet threshold and waitbound*/
+                XEmac_SetPktThreshold(&lp->Emac, XEM_SEND, 31);
+                XEmac_SetPktThreshold(&lp->Emac, XEM_RECV, 31);
+                (void) XEmac_SetPktWaitBound(&lp->Emac, XEM_SEND, 5);
+                (void) XEmac_SetPktWaitBound(&lp->Emac, XEM_RECV, 5);
+
+                /* disable SGEND interrupt */
+                XEmac_SetOptions(&lp->Emac, XEmac_GetOptions(&lp->Emac) |
+                                 XEM_NO_SGEND_INT_OPTION);
+	} else {
+		printk(KERN_ERR "%s: using fifo mode.\n", dev->name);
+		XEmac_SetFifoRecvHandler(&lp->Emac, dev, FifoRecvHandler);
+		XEmac_SetFifoSendHandler(&lp->Emac, dev, FifoSendHandler);
+		dev->hard_start_xmit = xenet_FifoSend;
+		lp->Isr = XEmac_IntrHandlerFifo;
+	}
+	XEmac_SetErrorHandler(&lp->Emac, dev, ErrorHandler);
+
+	/* Scan to find the PHY. */
+	lp->mii_addr = 0xFF;
+	for (maddr = 0; maddr < 31; maddr++) {
+		XStatus Result;
+		u16 reg;
+
+                /* Attempt to read the MII Status Register (MBSR).  This should
+                   be non-zero for the correct MII address. Previously we
+                   tested the Control Register, but this occasionally gave
+                   a false detect - JW*/
+                   
+                Result = XEmac_PhyRead(&lp->Emac, maddr, MII_BMSR, &reg);
+
+		/*
+		 * XEmac_PhyRead is currently returning XST_SUCCESS even
+		 * when reading from non-existent addresses.  Work
+		 * around this by doing a primitive validation on the
+		 * control word we get back.
+		 */
+		if (Result == XST_SUCCESS && reg) {
+			lp->mii_addr = maddr;
+			break;
+		}
+	}
+	if (lp->mii_addr == 0xFF) {
+		lp->mii_addr = 0;
+		printk(KERN_WARNING
+		       "%s: No PHY detected.  Assuming a PHY at address %d.\n",
+		       dev->name, lp->mii_addr);
+	}
+
+	dev->open = xenet_open;
+	dev->stop = xenet_close;
+	dev->get_stats = xenet_get_stats;
+	dev->flags &= ~IFF_MULTICAST;
+	dev->do_ioctl = xenet_ioctl;
+	dev->tx_timeout = xenet_tx_timeout;
+	dev->watchdog_timeo = TX_TIMEOUT;
+
+        dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HW_CSUM;
+
+	printk(KERN_INFO
+	       "%s: Xilinx EMAC #%d at 0x%08X mapped to 0x%08X, irq=%d\n",
+	       dev->name, index, cfg->PhysAddress, 
+		ether_table[index].baseaddr, dev->irq); 
+	/* print h/w id  */
+	{
+		u32 id = XIo_In32(cfg->BaseAddress + XIIF_V123B_RESETR_OFFSET);
+
+		printk("%s: id %d.%d%c; block id %d, type %d\n",
+		       dev->name, (id >> 28) & 0xf, (id >> 21) & 0x7f,
+		       ((id >> 16) & 0x1f) + 'a',
+		       (id >> 16) & 0xff, (id >> 0) & 0xff);
+	}
+
+	return 0;
+}
+
+static int __init
+xenet_init(void)
+{
+	int index = 0;
+
+	while (probe(index++) == 0) ;
+	/* If we found at least one, report success. */
+	return (index > 1) ? 0 : -ENODEV;
+}
+
+static void __exit
+xenet_cleanup(void)
+{
+	while (dev_list)
+		remove_head_dev();
+}
+
+EXPORT_NO_SYMBOLS;
+
+module_init(xenet_init);
+module_exit(xenet_cleanup);
diff -urN linux-2.4.29/drivers/net/xilinx_enet/Makefile linux-2.4.29-uc1/drivers/net/xilinx_enet/Makefile
--- linux-2.4.29/drivers/net/xilinx_enet/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/xilinx_enet/Makefile	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,21 @@
+#
+# Makefile for the Xilinx ethernet driver
+#
+
+EXTRA_CFLAGS		+= -I$(TOPDIR)/arch/microblaze/xilinx_ocp
+
+list-multi		:= xilinx_enet.o
+
+# The Linux adapter for the Xilinx driver code.
+xilinx_enet-objs	+= adapter.o
+
+# The Xilinx OS independent code.
+xilinx_enet-objs	+= xemac.o xemac_g.o xemac_intr.o xemac_intr_dma.o \
+			   xemac_intr_fifo.o xemac_options.o xemac_phy.o
+
+obj-$(CONFIG_XILINX_ENET) := xilinx_enet.o
+
+xilinx_enet.o: $(xilinx_enet-objs)
+	$(LD) -r -o $@ $(xilinx_enet-objs)
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/net/xilinx_enet/xemac.c linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac.c
--- linux-2.4.29/drivers/net/xilinx_enet/xemac.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,843 @@
+/* $Id: xemac.c,v 1.1 2004/04/06 16:49:36 robertm Exp $ */
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xemac.c
+*
+* The XEmac driver. Functions in this file are the minimum required functions
+* for this driver. See xemac.h for a detailed description of the driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a rpm  07/31/01 First release
+* 1.00b rpm  02/20/02 Repartitioned files and functions
+* 1.00b rpm  07/23/02 Removed the PHY reset from Initialize()
+* 1.00b rmm  09/23/02 Removed commented code in Initialize(). Recycled as
+*                     XEmac_mPhyReset macro in xemac_l.h.
+* 1.00c rpm  12/05/02 New version includes support for simple DMA
+* 1.00c rpm  12/12/02 Changed location of IsStarted assignment in XEmac_Start
+*                     to be sure the flag is set before the device and
+*                     interrupts are enabled.
+* 1.00c rpm  02/03/03 SelfTest was not clearing polled mode. Take driver out
+*                     of polled mode in XEmac_Reset() to fix this problem.
+* 1.00c rmm  05/13/03 Fixed diab compiler warnings relating to asserts.
+* 1.00d rpm  09/26/03 New version includes support PLB Ethernet and v2.00a of
+*                     the packet fifo driver.
+* 1.00e rmm  04/06/04 Changed XEmac_Initialize() to clear the instance data.
+*                     Added XEM_NO_SGEND_INT_OPTION processing to XEmac_Start().
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xemac_i.h"
+#include "xio.h"
+#include "xipif_v1_23_b.h"	/* Uses v1.23b of the IPIF */
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static XStatus ConfigureDma(XEmac * InstancePtr);
+static XStatus ConfigureFifo(XEmac * InstancePtr);
+static void StubFifoHandler(void *CallBackRef);
+static void StubErrorHandler(void *CallBackRef, XStatus ErrorCode);
+static void StubSgHandler(void *CallBackRef, XBufDescriptor * BdPtr,
+			  u32 NumBds);
+
+/************************** Variable Definitions *****************************/
+
+/*****************************************************************************/
+/**
+*
+* Initialize a specific XEmac instance/driver.  The initialization entails:
+* - Initialize fields of the XEmac structure
+* - Clear the Ethernet statistics for this device
+* - Initialize the IPIF component with its register base address
+* - Configure the FIFO components with their register base addresses.
+* - If the device is configured with DMA, configure the DMA channel components
+*   with their register base addresses. At some later time, memory pools for
+*   the scatter-gather descriptor lists may be passed to the driver.
+* - Reset the Ethernet MAC
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param DeviceId is the unique id of the device controlled by this XEmac
+*        instance.  Passing in a device id associates the generic XEmac
+*        instance to a specific device, as chosen by the caller or application
+*        developer.
+*
+* @return
+*
+* - XST_SUCCESS if initialization was successful
+* - XST_DEVICE_NOT_FOUND if device configuration information was not found for
+*   a device with the supplied device ID.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XEmac_Initialize(XEmac * InstancePtr, u16 DeviceId)
+{
+	XStatus Result;
+	XEmac_Config *ConfigPtr;	/* configuration information */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+
+	/* Clear instance memory */
+	memset(InstancePtr, 0, sizeof (XEmac));
+
+	/*
+	 * Lookup the device configuration in the temporary CROM table. Use this
+	 * configuration info down below when initializing this component.
+	 */
+	ConfigPtr = XEmac_LookupConfig(DeviceId);
+	if (ConfigPtr == NULL) {
+		return XST_DEVICE_NOT_FOUND;
+	}
+
+	/*
+	 * Set some default values
+	 */
+	InstancePtr->IsReady = 0;
+	InstancePtr->IsStarted = 0;
+	InstancePtr->IpIfDmaConfig = ConfigPtr->IpIfDmaConfig;
+	InstancePtr->HasMii = ConfigPtr->HasMii;
+	InstancePtr->HasMulticastHash = FALSE;
+
+	/* Always default polled to false, let user configure this mode */
+	InstancePtr->IsPolled = FALSE;
+	InstancePtr->FifoRecvHandler = StubFifoHandler;
+	InstancePtr->FifoSendHandler = StubFifoHandler;
+	InstancePtr->ErrorHandler = StubErrorHandler;
+	InstancePtr->SgRecvHandler = StubSgHandler;
+	InstancePtr->SgSendHandler = StubSgHandler;
+
+	/*
+	 * Initialize the device register base addresses
+	 */
+	InstancePtr->BaseAddress = ConfigPtr->BaseAddress;
+	InstancePtr->PhysAddress = ConfigPtr->PhysAddress;
+
+	/*
+	 * Configure the send and receive FIFOs in the MAC
+	 */
+	Result = ConfigureFifo(InstancePtr);
+	if (Result != XST_SUCCESS) {
+		return Result;
+	}
+
+	/*
+	 * If the device is configured for DMA, configure the send and receive DMA
+	 * channels in the MAC.
+	 */
+	if (XEmac_mIsDma(InstancePtr)) {
+		Result = ConfigureDma(InstancePtr);
+		if (Result != XST_SUCCESS) {
+			return Result;
+		}
+	}
+
+	/*
+	 * Indicate the component is now ready to use. Note that this is done before
+	 * we reset the device and the PHY below, which may seem a bit odd. The
+	 * choice was made to move it here rather than remove the asserts in various
+	 * functions (e.g., Reset() and all functions that it calls).  Applications
+	 * that use multiple threads, one to initialize the XEmac driver and one
+	 * waiting on the IsReady condition could have a problem with this sequence.
+	 */
+	InstancePtr->IsReady = XCOMPONENT_IS_READY;
+
+	/*
+	 * Reset the MAC to get it into its initial state. It is expected that
+	 * device configuration by the user will take place after this
+	 * initialization is done, but before the device is started.
+	 */
+	XEmac_Reset(InstancePtr);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Start the Ethernet controller as follows:
+*   - If not in polled mode
+*       - Set the internal interrupt enable registers appropriately
+*       - Enable interrupts within the device itself. Note that connection of
+*         the driver's interrupt handler to the interrupt source (typically
+*         done using the interrupt controller component) is done by the higher
+*         layer software.
+*       - If the device is configured with scatter-gather DMA, start the DMA 
+*         channels if the descriptor lists are not empty
+*   - Enable the transmitter
+*   - Enable the receiver
+*
+* The PHY is enabled after driver initialization. We assume the upper layer
+* software has configured it and the EMAC appropriately before this function
+* is called.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* - XST_SUCCESS if the device was started successfully
+* - XST_NO_CALLBACK if a callback function has not yet been registered using
+*   the SetxxxHandler function. This is required if in interrupt mode.
+* - XST_DEVICE_IS_STARTED if the device is already started
+* - XST_DMA_SG_NO_LIST if configured for scatter-gather DMA and a descriptor
+*   list has not yet been created for the send or receive channel.
+*
+* @note
+*
+* The driver tries to match the hardware configuration. So if the hardware
+* is configured with scatter-gather DMA, the driver expects to start the
+* scatter-gather channels and expects that the user has set up the buffer
+* descriptor lists already. If the user expects to use the driver in a mode
+* different than how the hardware is configured, the user should modify the
+* configuration table to reflect the mode to be used. Modifying the config
+* table is a workaround for now until we get some experience with how users
+* are intending to use the hardware in its different configurations. For
+* example, if the hardware is built with scatter-gather DMA but the user is
+* intending to use only simple DMA, the user either needs to modify the config
+* table as a workaround or rebuild the hardware with only simple DMA.
+*
+* This function makes use of internal resources that are shared between the
+* Start, Stop, and SetOptions functions. So if one task might be setting device
+* options while another is trying to start the device, the user is required to
+* provide protection of this shared data (typically using a semaphore).
+*
+******************************************************************************/
+XStatus
+XEmac_Start(XEmac * InstancePtr)
+{
+	u32 ControlReg;
+	XStatus Result;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/*
+	 * If it is already started, return a status indicating so
+	 */
+	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+		return XST_DEVICE_IS_STARTED;
+	}
+
+	/*
+	 * If not polled, enable interrupts
+	 */
+	if (!InstancePtr->IsPolled) {
+		/*
+		 * Verify that the callbacks have been registered, then enable
+		 * interrupts
+		 */
+		if (XEmac_mIsSgDma(InstancePtr)) {
+			if ((InstancePtr->SgRecvHandler == StubSgHandler) ||
+			    (InstancePtr->SgSendHandler == StubSgHandler)) {
+				return XST_NO_CALLBACK;
+			}
+
+			/* Enable IPIF interrupts */
+			XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
+					      XEM_IPIF_DMA_DFT_MASK |
+					      XIIF_V123B_ERROR_MASK);
+			XIIF_V123B_WRITE_IIER(InstancePtr->BaseAddress,
+					      XEM_EIR_DFT_SG_MASK);
+
+			/* Enable scatter-gather DMA interrupts */
+			ControlReg = XEM_DMA_SG_INTR_MASK;	/* Default mask */
+			if (InstancePtr->IsSgEndDisable) {
+				ControlReg &= ~XDC_IXR_SG_END_MASK;	/* Don't enable SGEND */
+			}
+
+			XDmaChannel_SetIntrEnable(&InstancePtr->RecvChannel,
+						  ControlReg);
+			XDmaChannel_SetIntrEnable(&InstancePtr->SendChannel,
+						  ControlReg);
+		} else {
+			if ((InstancePtr->FifoRecvHandler == StubFifoHandler) ||
+			    (InstancePtr->FifoSendHandler == StubFifoHandler)) {
+				return XST_NO_CALLBACK;
+			}
+
+			/* Enable IPIF interrupts (used by simple DMA also) */
+			XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
+					      XEM_IPIF_FIFO_DFT_MASK |
+					      XIIF_V123B_ERROR_MASK);
+			XIIF_V123B_WRITE_IIER(InstancePtr->BaseAddress,
+					      XEM_EIR_DFT_FIFO_MASK);
+		}
+
+		/* Enable the global IPIF interrupt output */
+		XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+	}
+
+	/*
+	 * Indicate that the device is started before we enable the transmitter
+	 * or receiver. This needs to be done before because as soon as the
+	 * receiver is enabled we may get an interrupt, and there are functions
+	 * in the interrupt handling path that rely on the IsStarted flag.
+	 */
+	InstancePtr->IsStarted = XCOMPONENT_IS_STARTED;
+
+	/*
+	 * Enable the transmitter, and receiver (do a read/modify/write to preserve
+	 * current settings). There is no critical section here since this register
+	 * is not modified during interrupt context.
+	 */
+	ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
+	ControlReg &= ~(XEM_ECR_XMIT_RESET_MASK | XEM_ECR_RECV_RESET_MASK);
+	ControlReg |= (XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK);
+
+	XIo_Out32(InstancePtr->BaseAddress + XEM_ECR_OFFSET, ControlReg);
+
+	/*
+	 * If configured with scatter-gather DMA and not polled, restart the
+	 * DMA channels in case there are buffers ready to be sent or received into.
+	 * The DMA SgStart function uses data that can be modified during interrupt
+	 * context, so a critical section is required here.
+	 */
+	if ((XEmac_mIsSgDma(InstancePtr)) && (!InstancePtr->IsPolled)) {
+		XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
+
+		/*
+		 * The only error we care about is if the list has not yet been
+		 * created, or on receive, if no buffer descriptors have been
+		 * added yet (the list is empty). Other errors are benign at this point.
+		 */
+		Result = XDmaChannel_SgStart(&InstancePtr->RecvChannel);
+		if ((Result == XST_DMA_SG_NO_LIST)
+		    || (Result == XST_DMA_SG_LIST_EMPTY)) {
+			XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+			return Result;
+		}
+
+		Result = XDmaChannel_SgStart(&InstancePtr->SendChannel);
+		if (Result == XST_DMA_SG_NO_LIST) {
+			XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+			return Result;
+		}
+
+		XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+	}
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Stop the Ethernet MAC as follows:
+*   - If the device is configured with scatter-gather DMA, stop the DMA
+*     channels (wait for acknowledgment of stop)
+*   - Disable the transmitter and receiver
+*   - Disable interrupts if not in polled mode (the higher layer software is
+*     responsible for disabling interrupts at the interrupt controller)
+*
+* The PHY is left enabled after a Stop is called.
+*
+* If the device is configured for scatter-gather DMA, the DMA engine stops at
+* the next buffer descriptor in its list. The remaining descriptors in the list
+* are not removed, so anything in the list will be transmitted or received when
+* the device is restarted. The side effect of doing this is that the last
+* buffer descriptor processed by the DMA engine before stopping may not be the
+* last descriptor in the Ethernet frame. So when the device is restarted, a
+* partial frame (i.e., a bad frame) may be transmitted/received. This is only a
+* concern if a frame can span multiple buffer descriptors, which is dependent
+* on the size of the network buffers.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* - XST_SUCCESS if the device was stopped successfully
+* - XST_DEVICE_IS_STOPPED if the device is already stopped
+*
+* @note
+*
+* This function makes use of internal resources that are shared between the
+* Start, Stop, and SetOptions functions. So if one task might be setting device
+* options while another is trying to start the device, the user is required to
+* provide protection of this shared data (typically using a semaphore).
+*
+******************************************************************************/
+XStatus
+XEmac_Stop(XEmac * InstancePtr)
+{
+	u32 ControlReg;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/*
+	 * If the device is already stopped, do nothing but return a status
+	 * indicating so
+	 */
+	if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
+		return XST_DEVICE_IS_STOPPED;
+	}
+
+	/*
+	 * If configured for scatter-gather DMA, stop the DMA channels. Ignore
+	 * the XST_DMA_SG_IS_STOPPED return code. There is a critical section
+	 * here between SgStart and SgStop, and SgStart can be called in interrupt
+	 * context, so disable interrupts while calling SgStop.
+	 */
+	if (XEmac_mIsSgDma(InstancePtr)) {
+		XBufDescriptor *BdTemp;	/* temporary descriptor pointer */
+
+		XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
+
+		(void) XDmaChannel_SgStop(&InstancePtr->SendChannel, &BdTemp);
+		(void) XDmaChannel_SgStop(&InstancePtr->RecvChannel, &BdTemp);
+
+		XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+	}
+
+	/*
+	 * Disable the transmitter and receiver. There is no critical section
+	 * here since this register is not modified during interrupt context.
+	 */
+	ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
+	ControlReg &= ~(XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK);
+	XIo_Out32(InstancePtr->BaseAddress + XEM_ECR_OFFSET, ControlReg);
+
+	/*
+	 * If not in polled mode, disable interrupts for IPIF (includes MAC and
+	 * DMAs)
+	 */
+	if (!InstancePtr->IsPolled) {
+		XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
+	}
+
+	InstancePtr->IsStarted = 0;
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Reset the Ethernet MAC. This is a graceful reset in that the device is stopped
+* first. Resets the DMA channels, the FIFOs, the transmitter, and the receiver.
+* The PHY is not reset. Any frames in the scatter-gather descriptor lists will
+* remain in the lists. The side effect of doing this is that after a reset and
+* following a restart of the device, frames that were in the list before the
+* reset may be transmitted or received. Reset must only be called after the
+* driver has been initialized.
+*
+* The driver is also taken out of polled mode if polled mode was set. The user
+* is responsbile for re-configuring the driver into polled mode after the
+* reset if desired.
+*
+* The configuration after this reset is as follows:
+*   - Half duplex
+*   - Disabled transmitter and receiver
+*   - Enabled PHY (the PHY is not reset)
+*   - MAC transmitter does pad insertion, FCS insertion, and source address
+*     overwrite.
+*   - MAC receiver does not strip padding or FCS
+*   - Interframe Gap as recommended by IEEE Std. 802.3 (96 bit times)
+*   - Unicast addressing enabled
+*   - Broadcast addressing enabled
+*   - Multicast addressing disabled (addresses are preserved)
+*   - Promiscuous addressing disabled
+*   - Default packet threshold and packet wait bound register values for
+*     scatter-gather DMA operation
+*   - MAC address of all zeros
+*   - Non-polled mode
+*
+* The upper layer software is responsible for re-configuring (if necessary)
+* and restarting the MAC after the reset. Note that the PHY is not reset. PHY
+* control is left to the upper layer software. Note also that driver statistics
+* are not cleared on reset. It is up to the upper layer software to clear the
+* statistics if needed.
+*
+* When a reset is required due to an internal error, the driver notifies the
+* upper layer software of this need through the ErrorHandler callback and
+* specific status codes.  The upper layer software is responsible for calling
+* this Reset function and then re-configuring the device.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+* @internal
+*
+* The reset is accomplished by setting the IPIF reset register.  This takes
+* care of resetting all hardware blocks, including the MAC.
+*
+******************************************************************************/
+void
+XEmac_Reset(XEmac * InstancePtr)
+{
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/*
+	 * Stop the device first
+	 */
+	(void) XEmac_Stop(InstancePtr);
+
+	/*
+	 * Take the driver out of polled mode
+	 */
+	InstancePtr->IsPolled = FALSE;
+
+	/*
+	 * Reset the entire IPIF at once.  If we choose someday to reset each
+	 * hardware block separately, the reset should occur in the direction of
+	 * data flow. For example, for the send direction the reset order is DMA
+	 * first, then FIFO, then the MAC transmitter.
+	 */
+	XIIF_V123B_RESET(InstancePtr->BaseAddress);
+
+	if (XEmac_mIsSgDma(InstancePtr)) {
+		/*
+		 * After reset, configure the scatter-gather DMA packet threshold and
+		 * packet wait bound registers to default values. Ignore the return
+		 * values of these functions since they only return error if the device
+		 * is not stopped.
+		 */
+		(void) XEmac_SetPktThreshold(InstancePtr, XEM_SEND,
+					     XEM_SGDMA_DFT_THRESHOLD);
+		(void) XEmac_SetPktThreshold(InstancePtr, XEM_RECV,
+					     XEM_SGDMA_DFT_THRESHOLD);
+		(void) XEmac_SetPktWaitBound(InstancePtr, XEM_SEND,
+					     XEM_SGDMA_DFT_WAITBOUND);
+		(void) XEmac_SetPktWaitBound(InstancePtr, XEM_RECV,
+					     XEM_SGDMA_DFT_WAITBOUND);
+	}
+}
+
+/*****************************************************************************/
+/**
+*
+* Set the MAC address for this driver/device.  The address is a 48-bit value.
+* The device must be stopped before calling this function.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param AddressPtr is a pointer to a 6-byte MAC address.
+*
+* @return
+*
+* - XST_SUCCESS if the MAC address was set successfully
+* - XST_DEVICE_IS_STARTED if the device has not yet been stopped
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XEmac_SetMacAddress(XEmac * InstancePtr, u8 * AddressPtr)
+{
+	u32 MacAddr = 0;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(AddressPtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/*
+	 * The device must be stopped before setting the MAC address
+	 */
+	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+		return XST_DEVICE_IS_STARTED;
+	}
+
+	/*
+	 * Set the device station address high and low registers
+	 */
+	MacAddr = (AddressPtr[0] << 8) | AddressPtr[1];
+	XIo_Out32(InstancePtr->BaseAddress + XEM_SAH_OFFSET, MacAddr);
+
+	MacAddr = (AddressPtr[2] << 24) | (AddressPtr[3] << 16) |
+	    (AddressPtr[4] << 8) | AddressPtr[5];
+
+	XIo_Out32(InstancePtr->BaseAddress + XEM_SAL_OFFSET, MacAddr);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Get the MAC address for this driver/device.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param BufferPtr is an output parameter, and is a pointer to a buffer into
+*        which the current MAC address will be copied. The buffer must be at
+*        least 6 bytes.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XEmac_GetMacAddress(XEmac * InstancePtr, u8 * BufferPtr)
+{
+	u32 MacAddrHi;
+	u32 MacAddrLo;
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(BufferPtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	MacAddrHi = XIo_In32(InstancePtr->BaseAddress + XEM_SAH_OFFSET);
+	MacAddrLo = XIo_In32(InstancePtr->BaseAddress + XEM_SAL_OFFSET);
+
+	BufferPtr[0] = (u8) (MacAddrHi >> 8);
+	BufferPtr[1] = (u8) MacAddrHi;
+	BufferPtr[2] = (u8) (MacAddrLo >> 24);
+	BufferPtr[3] = (u8) (MacAddrLo >> 16);
+	BufferPtr[4] = (u8) (MacAddrLo >> 8);
+	BufferPtr[5] = (u8) MacAddrLo;
+}
+
+/******************************************************************************/
+/**
+*
+* Configure DMA capabilities.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* - XST_SUCCESS  if successful initialization of DMA
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static XStatus
+ConfigureDma(XEmac * InstancePtr)
+{
+	XStatus Result;
+
+	/*
+	 * Initialize the DMA channels with their base addresses. We assume
+	 * scatter-gather DMA is the only possible configuration. Descriptor space
+	 * will need to be set later by the upper layer.
+	 */
+	Result = XDmaChannel_Initialize(&InstancePtr->RecvChannel,
+					InstancePtr->BaseAddress +
+					XEM_DMA_RECV_OFFSET);
+	if (Result != XST_SUCCESS) {
+		return Result;
+	}
+
+	Result = XDmaChannel_Initialize(&InstancePtr->SendChannel,
+					InstancePtr->BaseAddress +
+					XEM_DMA_SEND_OFFSET);
+
+	return Result;
+}
+
+/******************************************************************************/
+/**
+*
+* Configure the send and receive FIFO components with their base addresses
+* and interrupt masks.  Currently the base addresses are defined constants.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* XST_SUCCESS if successful initialization of the packet FIFOs
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static XStatus
+ConfigureFifo(XEmac * InstancePtr)
+{
+	XStatus Result;
+
+	/*
+	 * Return status from the packet FIFOs initialization is ignored since
+	 * they always return success.
+	 */
+	Result = XPacketFifoV200a_Initialize(&InstancePtr->RecvFifo,
+					     InstancePtr->BaseAddress +
+					     XEM_PFIFO_RXREG_OFFSET,
+					     InstancePtr->BaseAddress +
+					     XEM_PFIFO_RXDATA_OFFSET);
+	if (Result != XST_SUCCESS) {
+		return Result;
+	}
+
+	Result = XPacketFifoV200a_Initialize(&InstancePtr->SendFifo,
+					     InstancePtr->BaseAddress +
+					     XEM_PFIFO_TXREG_OFFSET,
+					     InstancePtr->BaseAddress +
+					     XEM_PFIFO_TXDATA_OFFSET);
+	return Result;
+}
+
+/******************************************************************************/
+/**
+*
+* This is a stub for the scatter-gather send and recv callbacks. The stub
+* is here in case the upper layers forget to set the handlers.
+*
+* @param CallBackRef is a pointer to the upper layer callback reference
+* @param BdPtr is a pointer to the first buffer descriptor in a list
+* @param NumBds is the number of descriptors in the list.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+StubSgHandler(void *CallBackRef, XBufDescriptor * BdPtr, u32 NumBds)
+{
+	XASSERT_VOID_ALWAYS();
+}
+
+/******************************************************************************/
+/**
+*
+* This is a stub for the non-DMA send and recv callbacks.  The stub is here in
+* case the upper layers forget to set the handlers.
+*
+* @param CallBackRef is a pointer to the upper layer callback reference
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+StubFifoHandler(void *CallBackRef)
+{
+	XASSERT_VOID_ALWAYS();
+}
+
+/******************************************************************************/
+/**
+*
+* This is a stub for the asynchronous error callback.  The stub is here in
+* case the upper layers forget to set the handler.
+*
+* @param CallBackRef is a pointer to the upper layer callback reference
+* @param ErrorCode is the Xilinx error code, indicating the cause of the error
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+StubErrorHandler(void *CallBackRef, XStatus ErrorCode)
+{
+	XASSERT_VOID_ALWAYS();
+}
+
+/*****************************************************************************/
+/**
+*
+* Lookup the device configuration based on the unique device ID.  The table
+* EmacConfigTable contains the configuration info for each device in the system.
+*
+* @param DeviceId is the unique device ID of the device being looked up.
+*
+* @return
+*
+* A pointer to the configuration table entry corresponding to the given
+* device ID, or NULL if no match is found.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XEmac_Config *
+XEmac_LookupConfig(u16 DeviceId)
+{
+	XEmac_Config *CfgPtr = NULL;
+	int i;
+
+	for (i = 0; i < CONFIG_XILINX_ETHERNET_NUM_INSTANCES; i++) {
+		if (XEmac_ConfigTable[i].DeviceId == DeviceId) {
+			CfgPtr = &XEmac_ConfigTable[i];
+			break;
+		}
+	}
+
+	return CfgPtr;
+}
diff -urN linux-2.4.29/drivers/net/xilinx_enet/xemac_g.c linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac_g.c
--- linux-2.4.29/drivers/net/xilinx_enet/xemac_g.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac_g.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,57 @@
+/*******************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+* 
+* Description: Driver configuration
+*
+*******************************************************************/
+
+#include <asm/autoconfig.h>
+#include "xemac.h"
+
+/*
+* The configuration table for devices
+*/
+
+XEmac_Config XEmac_ConfigTable[] = {
+	{
+	 0,
+	 CONFIG_XILINX_ETHERNET_0_BASEADDR,
+	 CONFIG_XILINX_ETHERNET_0_BASEADDR,
+	 CONFIG_XILINX_ETHERNET_0_ERR_COUNT_EXIST,
+	 CONFIG_XILINX_ETHERNET_0_DMA_PRESENT,
+	 CONFIG_XILINX_ETHERNET_0_MII_EXIST}
+};
diff -urN linux-2.4.29/drivers/net/xilinx_enet/xemac.h linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac.h
--- linux-2.4.29/drivers/net/xilinx_enet/xemac.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,693 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xemac.h
+*
+* The Xilinx Ethernet driver component.  This component supports the Xilinx
+* Ethernet 10/100 MAC (EMAC).
+*
+* The Xilinx Ethernet 10/100 MAC supports the following features:
+*   - Simple and scatter-gather DMA operations, as well as simple memory
+*     mapped direct I/O interface (FIFOs).
+*   - Media Independent Interface (MII) for connection to external
+*     10/100 Mbps PHY transceivers.
+*   - MII management control reads and writes with MII PHYs
+*   - Independent internal transmit and receive FIFOs
+*   - CSMA/CD compliant operations for half-duplex modes
+*   - Programmable PHY reset signal
+*   - Unicast, broadcast, and promiscuous address filtering
+*   - Reception of all multicast addresses (no multicast filtering yet)
+*     (NOTE: EMAC core may not support this - check the specification)
+*   - Internal loopback
+*   - Automatic source address insertion or overwrite (programmable)
+*   - Automatic FCS insertion and stripping (programmable)
+*   - Automatic pad insertion and stripping (programmable)
+*   - Pause frame (flow control) detection in full-duplex mode
+*   - Programmable interframe gap
+*   - VLAN frame support.
+*   - Pause frame support
+*
+* The device driver supports all the features listed above.
+*
+* <b>Driver Description</b>
+*
+* The device driver enables higher layer software (e.g., an application) to
+* communicate to the EMAC. The driver handles transmission and reception of
+* Ethernet frames, as well as configuration of the controller. It does not
+* handle protocol stack functionality such as Link Layer Control (LLC) or the
+* Address Resolution Protocol (ARP). The protocol stack that makes use of the
+* driver handles this functionality. This implies that the driver is simply a
+* pass-through mechanism between a protocol stack and the EMAC. A single device
+* driver can support multiple EMACs.
+*
+* The driver is designed for a zero-copy buffer scheme. That is, the driver will
+* not copy buffers. This avoids potential throughput bottlenecks within the
+* driver.
+*
+* Since the driver is a simple pass-through mechanism between a protocol stack
+* and the EMAC, no assembly or disassembly of Ethernet frames is done at the
+* driver-level. This assumes that the protocol stack passes a correctly
+* formatted Ethernet frame to the driver for transmission, and that the driver
+* does not validate the contents of an incoming frame
+*
+* <b>Buffer Alignment</b>
+*
+* It is important to note that when using direct FIFO communication (either
+* polled or interrupt-driven), packet buffers must be 32-bit aligned. When
+* using DMA and the OPB 10/100 Ethernet core, packet buffers must be 32-bit
+* aligned. When using DMA and the PLB 10/100 Ethernet core, packet buffers
+* must be 64-bit aligned.  When using scatter-gather DMA, the buffer
+* descriptors must be 32-bit aligned (for either the OPB or the PLB core).
+* The driver may not enforce this alignment and it is up to the user to
+* guarantee the proper alignment.
+*
+* <b>PHY Communication</b>
+*
+* The driver provides rudimentary read and write functions to allow the higher
+* layer software to access the PHY. The EMAC provides MII registers for the
+* driver to access. This management interface can be parameterized away in the
+* FPGA implementation process. If this is the case, the PHY read and write
+* functions of the driver return XST_NO_FEATURE.
+*
+* External loopback is usually supported at the PHY. It is up to the user to
+* turn external loopback on or off at the PHY. The driver simply provides pass-
+* through functions for configuring the PHY. The driver does not read, write,
+* or reset the PHY on its own. All control of the PHY must be done by the user.
+*
+* <b>Asynchronous Callbacks</b>
+*
+* The driver services interrupts and passes Ethernet frames to the higher layer
+* software through asynchronous callback functions. When using the driver
+* directly (i.e., not with the RTOS protocol stack), the higher layer
+* software must register its callback functions during initialization. The
+* driver requires callback functions for received frames, for confirmation of
+* transmitted frames, and for asynchronous errors.
+*
+* <b>Interrupts</b>
+*
+* The driver has no dependencies on the interrupt controller. The driver
+* provides two interrupt handlers.  XEmac_IntrHandlerDma() handles interrupts
+* when the EMAC is configured with scatter-gather DMA.  XEmac_IntrHandlerFifo()
+* handles interrupts when the EMAC is configured for direct FIFO I/O or simple
+* DMA.  Either of these routines can be connected to the system interrupt
+* controller by the user.
+*
+* <b>Interrupt Frequency</b>
+*
+* When the EMAC is configured with scatter-gather DMA, the frequency of
+* interrupts can be controlled with the interrupt coalescing features of the
+* scatter-gather DMA engine. The frequency of interrupts can be adjusted using
+* the driver API functions for setting the packet count threshold and the packet
+* wait bound values.
+*
+* The scatter-gather DMA engine only interrupts when the packet count threshold
+* is reached, instead of interrupting for each packet. A packet is a generic
+* term used by the scatter-gather DMA engine, and is equivalent to an Ethernet
+* frame in our case.
+*
+* The packet wait bound is a timer value used during interrupt coalescing to
+* trigger an interrupt when not enough packets have been received to reach the
+* packet count threshold.
+*
+* These values can be tuned by the user to meet their needs. If there appear to
+* be interrupt latency problems or delays in packet arrival that are longer than
+* might be expected, the user should verify that the packet count threshold is
+* set low enough to receive interrupts before the wait bound timer goes off.
+*
+* <b>Device Reset</b>
+*
+* Some errors that can occur in the device require a device reset. These errors
+* are listed in the XEmac_SetErrorHandler() function header. The user's error
+* handler is responsible for resetting the device and re-configuring it based on
+* its needs (the driver does not save the current configuration). When
+* integrating into an RTOS, these reset and re-configure obligations are
+* taken care of by the Xilinx adapter software if it exists for that RTOS.
+*
+* <b>Device Configuration</b>
+*
+* The device can be configured in various ways during the FPGA implementation
+* process.  Configuration parameters are stored in the xemac_g.c files.
+* A table is defined where each entry contains configuration information
+* for an EMAC device.  This information includes such things as the base address
+* of the memory-mapped device, the base addresses of IPIF, DMA, and FIFO modules
+* within the device, and whether the device has DMA, counter registers,
+* multicast support, MII support, and flow control.
+*
+* The driver tries to use the features built into the device. So if, for
+* example, the hardware is configured with scatter-gather DMA, the driver
+* expects to start the scatter-gather channels and expects that the user has set
+* up the buffer descriptor lists already. If the user expects to use the driver
+* in a mode different than how the hardware is configured, the user should
+* modify the configuration table to reflect the mode to be used. Modifying the
+* configuration table is a workaround for now until we get some experience with
+* how users are intending to use the hardware in its different configurations.
+* For example, if the hardware is built with scatter-gather DMA but the user is
+* intending to use only simple DMA, the user either needs to modify the config
+* table as a workaround or rebuild the hardware with only simple DMA. The
+* recommendation at this point is to build the hardware with the features you
+* intend to use. If you're inclined to modify the table, do so before the call
+* to XEmac_Initialize().  Here is a snippet of code that changes a device to
+* simple DMA (the hardware needs to have DMA for this to work of course):
+* <pre>
+*        XEmac_Config *ConfigPtr;
+*
+*        ConfigPtr = XEmac_LookupConfig(DeviceId);
+*        ConfigPtr->IpIfDmaConfig = XEM_CFG_SIMPLE_DMA;
+* </pre>
+*
+* <b>Simple DMA</b>
+*
+* Simple DMA is supported through the FIFO functions, FifoSend and FifoRecv, of
+* the driver (i.e., there is no separate interface for it). The driver makes use
+* of the DMA engine for a simple DMA transfer if the device is configured with
+* DMA, otherwise it uses the FIFOs directly. While the simple DMA interface is
+* therefore transparent to the user, the caching of network buffers is not.
+* If the device is configured with DMA and the FIFO interface is used, the user
+* must ensure that the network buffers are not cached or are cache coherent,
+* since DMA will be used to transfer to and from the Emac device. If the device
+* is configured with DMA and the user really wants to use the FIFOs directly,
+* the user should rebuild the hardware without DMA. If unable to do this, there
+* is a workaround (described above in Device Configuration) to modify the
+* configuration table of the driver to fake the driver into thinking the device
+* has no DMA. A code snippet follows:
+* <pre>
+*        XEmac_Config *ConfigPtr;
+*
+*        ConfigPtr = XEmac_LookupConfig(DeviceId);
+*        ConfigPtr->IpIfDmaConfig = XEM_CFG_NO_DMA;
+* </pre>
+*
+* <b>Asserts</b>
+*
+* Asserts are used within all Xilinx drivers to enforce constraints on argument
+* values. Asserts can be turned off on a system-wide basis by defining, at
+* compile time, the NDEBUG identifier. By default, asserts are turned on and it
+* is recommended that users leave asserts on during development.
+*
+* <b>Building the driver</b>
+*
+* The XEmac driver is composed of several source files. Why so many?  This
+* allows the user to build and link only those parts of the driver that are
+* necessary. Since the EMAC hardware can be configured in various ways (e.g.,
+* with or without DMA), the driver too can be built with varying features.
+* For the most part, this means that besides always linking in xemac.c, you
+* link in only the driver functionality you want. Some of the choices you have
+* are polled vs. interrupt, interrupt with FIFOs only vs. interrupt with DMA,
+* self-test diagnostics, and driver statistics. Note that currently the DMA code
+* must be linked in, even if you don't have DMA in the device.
+*
+* @note
+*
+* Xilinx drivers are typically composed of two components, one is the driver
+* and the other is the adapter.  The driver is independent of OS and processor
+* and is intended to be highly portable.  The adapter is OS-specific and
+* facilitates communication between the driver and an OS.
+* <br><br>
+* This driver is intended to be RTOS and processor independent.  It works
+* with physical addresses only.  Any needs for dynamic memory management,
+* threads or thread mutual exclusion, virtual memory, or cache control must
+* be satisfied by the layer above this driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a rpm  07/31/01 First release
+* 1.00b rpm  02/20/02 Repartitioned files and functions
+* 1.00b rpm  10/08/02 Replaced HasSgDma boolean with IpifDmaConfig enumerated
+*                     configuration parameter
+* 1.00c rpm  12/05/02 New version includes support for simple DMA and the delay
+*                     argument to SgSend
+* 1.00c rpm  02/03/03 The XST_DMA_SG_COUNT_EXCEEDED return code was removed
+*                     from SetPktThreshold in the internal DMA driver. Also
+*                     avoided compiler warnings by initializing Result in the
+*                     DMA interrupt service routines.
+* 1.00d rpm  09/26/03 New version includes support PLB Ethernet and v2.00a of
+*                     the packet fifo driver. Also supports multicast option.
+* 1.00e rmm  04/06/04 SGEND option added, Zero instance memory on init. Changed
+*                     SG DMA callback invokation from once per packet to once
+*                     for all packets received for an interrupt event. Added
+*                     XEmac_GetSgRecvFreeDesc() and GetSgSendFreeDesc()
+*                     functions. Moved some IFG and PHY constants to xemac_l.h.
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XEMAC_H			/* prevent circular inclusions */
+#define XEMAC_H			/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xpacket_fifo_v2_00_a.h"	/* Uses v2.00a of Packet Fifo */
+#include "xdma_channel.h"
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * Device information
+ */
+#define XEM_DEVICE_NAME     "xemac"
+#define XEM_DEVICE_DESC     "Xilinx Ethernet 10/100 MAC"
+
+/** @name Configuration options
+ *
+ * Device configuration options (see the XEmac_SetOptions() and
+ * XEmac_GetOptions() for information on how to use these options)
+ * @{
+ */
+#define XEM_UNICAST_OPTION        0x00000001UL /**< Unicast addressing
+                                                    (defaults on) */
+#define XEM_BROADCAST_OPTION      0x00000002UL /**< Broadcast addressing
+                                                    (defaults on) */
+#define XEM_PROMISC_OPTION        0x00000004UL /**< Promiscuous addressing
+                                                    (defaults off) */
+#define XEM_FDUPLEX_OPTION        0x00000008UL /**< Full duplex mode
+                                                    (defaults off) */
+#define XEM_POLLED_OPTION         0x00000010UL /**< Polled mode (defaults off) */
+#define XEM_LOOPBACK_OPTION       0x00000020UL /**< Internal loopback mode
+                                                    (defaults off) */
+#define XEM_MULTICAST_OPTION      0x00000040UL /**< Multicast address reception
+                                                    (defaults off) */
+#define XEM_FLOW_CONTROL_OPTION   0x00000080UL /**< Interpret pause frames in
+                                                    full duplex mode (defaults
+                                                    off) */
+#define XEM_INSERT_PAD_OPTION     0x00000100UL /**< Pad short frames on transmit
+                                                    (defaults on) */
+#define XEM_INSERT_FCS_OPTION     0x00000200UL /**< Insert FCS (CRC) on transmit
+                                                    (defaults on) */
+#define XEM_INSERT_ADDR_OPTION    0x00000400UL /**< Insert source address on
+                                                    transmit (defaults on) */
+#define XEM_OVWRT_ADDR_OPTION     0x00000800UL /**< Overwrite source address on
+                                                    transmit. This is only used
+                                                    only used if source address
+                                                    insertion is on (defaults on) */
+#define XEM_STRIP_PAD_FCS_OPTION  0x00002000UL /**< Strip FCS and padding from
+                                                    received frames (defaults off) */
+
+/** Disables the SGEND interrupt with SG DMA. Setting this option to ON may
+ * help bulk data transfer performance when utilizing higher packet threshold
+ * counts on slower systems (default is off) */
+#define XEM_NO_SGEND_INT_OPTION   0x00001000UL
+
+/*@}*/
+
+/*
+ * Some default values for interrupt coalescing within the scatter-gather
+ * DMA engine.
+ */
+#define XEM_SGDMA_DFT_THRESHOLD     1	/* Default pkt threshold */
+#define XEM_SGDMA_MAX_THRESHOLD     255	/* Maximum pkt theshold */
+#define XEM_SGDMA_DFT_WAITBOUND     5	/* Default pkt wait bound (msec) */
+#define XEM_SGDMA_MAX_WAITBOUND     1023	/* Maximum pkt wait bound (msec) */
+
+/*
+ * Direction identifiers. These are used for setting values like packet
+ * thresholds and wait bound for specific channels
+ */
+#define XEM_SEND    1
+#define XEM_RECV    2
+
+/*
+ * Arguments to SgSend function to indicate whether to hold off starting
+ * the scatter-gather engine.
+ */
+#define XEM_SGDMA_NODELAY     0	/* start SG DMA immediately */
+#define XEM_SGDMA_DELAY       1	/* do not start SG DMA */
+
+/*
+ * Constants to determine the configuration of the hardware device. They are
+ * used to allow the driver to verify it can operate with the hardware.
+ */
+#define XEM_CFG_NO_IPIF             0	/* Not supported by the driver */
+#define XEM_CFG_NO_DMA              1	/* No DMA */
+#define XEM_CFG_SIMPLE_DMA          2	/* Simple DMA */
+#define XEM_CFG_DMA_SG              3	/* DMA scatter gather */
+
+/*
+ * The next few constants help upper layers determine the size of memory
+ * pools used for Ethernet buffers and descriptor lists.
+ */
+#define XEM_MAC_ADDR_SIZE   6	/* six-byte MAC address */
+#define XEM_MTU             1500	/* max size of Ethernet frame */
+#define XEM_HDR_SIZE        14	/* size of Ethernet header */
+#define XEM_HDR_VLAN_SIZE   18	/* size of Ethernet header with VLAN */
+#define XEM_TRL_SIZE        4	/* size of Ethernet trailer (FCS) */
+#define XEM_MAX_FRAME_SIZE  (XEM_MTU + XEM_HDR_SIZE + XEM_TRL_SIZE)
+#define XEM_MAX_VLAN_FRAME_SIZE  (XEM_MTU + XEM_HDR_VLAN_SIZE + XEM_TRL_SIZE)
+
+/*
+ * Define a default number of send and receive buffers
+ */
+#define XEM_MIN_RECV_BUFS   32	/* minimum # of recv buffers */
+#define XEM_DFT_RECV_BUFS   64	/* default # of recv buffers */
+
+#define XEM_MIN_SEND_BUFS   16	/* minimum # of send buffers */
+#define XEM_DFT_SEND_BUFS   32	/* default # of send buffers */
+
+#define XEM_MIN_BUFFERS     (XEM_MIN_RECV_BUFS + XEM_MIN_SEND_BUFS)
+#define XEM_DFT_BUFFERS     (XEM_DFT_RECV_BUFS + XEM_DFT_SEND_BUFS)
+
+/*
+ * Define the number of send and receive buffer descriptors, used for
+ * scatter-gather DMA
+ */
+#define XEM_MIN_RECV_DESC   16	/* minimum # of recv descriptors */
+#define XEM_DFT_RECV_DESC   32	/* default # of recv descriptors */
+
+#define XEM_MIN_SEND_DESC   8	/* minimum # of send descriptors */
+#define XEM_DFT_SEND_DESC   16	/* default # of send descriptors */
+
+/**************************** Type Definitions *******************************/
+
+/**
+ * Ethernet statistics (see XEmac_GetStats() and XEmac_ClearStats())
+ */
+typedef struct {
+	u32 XmitFrames;		 /**< Number of frames transmitted */
+	u32 XmitBytes;		 /**< Number of bytes transmitted */
+	u32 XmitLateCollisionErrors;
+				 /**< Number of transmission failures
+                                          due to late collisions */
+	u32 XmitExcessDeferral;	 /**< Number of transmission failures
+                                          due o excess collision deferrals */
+	u32 XmitOverrunErrors;	 /**< Number of transmit overrun errors */
+	u32 XmitUnderrunErrors;	 /**< Number of transmit underrun errors */
+	u32 RecvFrames;		 /**< Number of frames received */
+	u32 RecvBytes;		 /**< Number of bytes received */
+	u32 RecvFcsErrors;	 /**< Number of frames discarded due
+                                          to FCS errors */
+	u32 RecvAlignmentErrors; /**< Number of frames received with
+                                          alignment errors */
+	u32 RecvOverrunErrors;	 /**< Number of frames discarded due
+                                          to overrun errors */
+	u32 RecvUnderrunErrors;	 /**< Number of recv underrun errors */
+	u32 RecvMissedFrameErrors;
+				 /**< Number of frames missed by MAC */
+	u32 RecvCollisionErrors; /**< Number of frames discarded due
+                                          to collisions */
+	u32 RecvLengthFieldErrors;
+				 /**< Number of frames discarded with
+                                          invalid length field */
+	u32 RecvShortErrors;	 /**< Number of short frames discarded */
+	u32 RecvLongErrors;	 /**< Number of long frames discarded */
+	u32 DmaErrors;		 /**< Number of DMA errors since init */
+	u32 FifoErrors;		 /**< Number of FIFO errors since init */
+	u32 RecvInterrupts;	 /**< Number of receive interrupts */
+	u32 XmitInterrupts;	 /**< Number of transmit interrupts */
+	u32 EmacInterrupts;	 /**< Number of MAC (device) interrupts */
+	u32 TotalIntrs;		 /**< Total interrupts */
+} XEmac_Stats;
+
+/**
+ * This typedef contains configuration information for a device.
+ */
+typedef struct {
+	u16 DeviceId;	    /**< Unique ID  of device */
+	u32 BaseAddress;    /**< Register base address */
+	u32 PhysAddress;    /**< Physical Base address */
+	u32 HasCounters;   /**< Does device have counters? */
+	u8 IpIfDmaConfig;   /**< IPIF/DMA hardware configuration */
+	u32 HasMii;	   /**< Does device support MII? */
+
+} XEmac_Config;
+
+/** @name Typedefs for callbacks
+ * Callback functions.
+ * @{
+ */
+/**
+ * Callback when data is sent or received with scatter-gather DMA.
+ *
+ * @param CallBackRef is a callback reference passed in by the upper layer
+ *        when setting the callback functions, and passed back to the upper
+ *        layer when the callback is invoked.
+ * @param BdPtr is a pointer to the first buffer descriptor in a list of
+ *        buffer descriptors.
+ * @param NumBds is the number of buffer descriptors in the list pointed
+ *        to by BdPtr.
+ */
+typedef void (*XEmac_SgHandler) (void *CallBackRef, XBufDescriptor * BdPtr,
+				 u32 NumBds);
+
+/**
+ * Callback when data is sent or received with direct FIFO communication or
+ * simple DMA. The user typically defines two callacks, one for send and one
+ * for receive.
+ *
+ * @param CallBackRef is a callback reference passed in by the upper layer
+ *        when setting the callback functions, and passed back to the upper
+ *        layer when the callback is invoked.
+ */
+typedef void (*XEmac_FifoHandler) (void *CallBackRef);
+
+/**
+ * Callback when an asynchronous error occurs.
+ *
+ * @param CallBackRef is a callback reference passed in by the upper layer
+ *        when setting the callback functions, and passed back to the upper
+ *        layer when the callback is invoked.
+ * @param ErrorCode is a Xilinx error code defined in xstatus.h.  Also see
+ *        XEmac_SetErrorHandler() for a description of possible errors.
+ */
+typedef void (*XEmac_ErrorHandler) (void *CallBackRef, XStatus ErrorCode);
+/*@}*/
+
+/**
+ * The XEmac driver instance data. The user is required to allocate a
+ * variable of this type for every EMAC device in the system. A pointer
+ * to a variable of this type is then passed to the driver API functions.
+ */
+typedef struct {
+	u32 BaseAddress;	/* Base address, virtual (of IPIF) */
+	u32 PhysAddress;	/* Base address, physical  (of IPIF) */
+	u32 IsStarted;		/* Device is currently started */
+	u32 IsReady;		/* Device is initialized and ready */
+	u32 IsPolled;		/* Device is in polled mode */
+	u8 IpIfDmaConfig;	/* IPIF/DMA hardware configuration */
+	u32 HasMii;		/* Does device support MII? */
+	u32 HasMulticastHash;	/* Does device support multicast hash table? */
+
+	XEmac_Stats Stats;
+	XPacketFifoV200a RecvFifo;	/* FIFO used to receive frames */
+	XPacketFifoV200a SendFifo;	/* FIFO used to send frames */
+
+	/*
+	 * Callbacks
+	 */
+	XEmac_FifoHandler FifoRecvHandler;	/* for non-DMA/simple DMA interrupts */
+	void *FifoRecvRef;
+	XEmac_FifoHandler FifoSendHandler;	/* for non-DMA/simple DMA interrupts */
+	void *FifoSendRef;
+	XEmac_ErrorHandler ErrorHandler;	/* for asynchronous errors */
+	void *ErrorRef;
+
+	XDmaChannel RecvChannel;	/* DMA receive channel driver */
+	XDmaChannel SendChannel;	/* DMA send channel driver */
+	u32 IsSgEndDisable;		/* Does SG DMA enable SGEND interrupt */
+
+	XEmac_SgHandler SgRecvHandler;	/* callback for scatter-gather DMA */
+	void *SgRecvRef;
+	XEmac_SgHandler SgSendHandler;	/* callback for scatter-gather DMA */
+	void *SgSendRef;
+} XEmac;
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/**
+*
+* This macro determines if the device is currently configured for
+* scatter-gather DMA.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Boolean TRUE if the device is configured for scatter-gather DMA, or FALSE
+* if it is not.
+*
+* @note
+*
+* Signature: u32 XEmac_mIsSgDma(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mIsSgDma(InstancePtr) \
+            ((InstancePtr)->IpIfDmaConfig == XEM_CFG_DMA_SG)
+
+/*****************************************************************************/
+/**
+*
+* This macro determines if the device is currently configured for simple DMA.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Boolean TRUE if the device is configured for simple DMA, or FALSE otherwise
+*
+* @note
+*
+* Signature: u32 XEmac_mIsSimpleDma(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mIsSimpleDma(InstancePtr) \
+            ((InstancePtr)->IpIfDmaConfig == XEM_CFG_SIMPLE_DMA)
+
+/*****************************************************************************/
+/**
+*
+* This macro determines if the device is currently configured with DMA (either
+* simple DMA or scatter-gather DMA)
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Boolean TRUE if the device is configured with DMA, or FALSE otherwise
+*
+* @note
+*
+* Signature: u32 XEmac_mIsDma(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mIsDma(InstancePtr) \
+            (XEmac_mIsSimpleDma(InstancePtr) || XEmac_mIsSgDma(InstancePtr))
+
+/************************** Function Prototypes ******************************/
+
+/*
+ * Initialization functions in xemac.c
+ */
+XStatus XEmac_Initialize(XEmac * InstancePtr, u16 DeviceId);
+XStatus XEmac_Start(XEmac * InstancePtr);
+XStatus XEmac_Stop(XEmac * InstancePtr);
+void XEmac_Reset(XEmac * InstancePtr);
+XEmac_Config *XEmac_LookupConfig(u16 DeviceId);
+
+/*
+ * Diagnostic functions in xemac_selftest.c
+ */
+XStatus XEmac_SelfTest(XEmac * InstancePtr);
+
+/*
+ * Polled functions in xemac_polled.c
+ */
+XStatus XEmac_PollSend(XEmac * InstancePtr, u8 * BufPtr, u32 ByteCount);
+XStatus XEmac_PollRecv(XEmac * InstancePtr, u8 * BufPtr, u32 * ByteCountPtr);
+
+/*
+ * Interrupts with scatter-gather DMA functions in xemac_intr_dma.c
+ */
+XStatus XEmac_SgSend(XEmac * InstancePtr, XBufDescriptor * BdPtr, int Delay);
+XStatus XEmac_SgRecv(XEmac * InstancePtr, XBufDescriptor * BdPtr);
+XStatus XEmac_SetPktThreshold(XEmac * InstancePtr, u32 Direction, u8 Threshold);
+XStatus XEmac_GetPktThreshold(XEmac * InstancePtr, u32 Direction,
+			      u8 * ThreshPtr);
+XStatus XEmac_SetPktWaitBound(XEmac * InstancePtr, u32 Direction,
+			      u32 TimerValue);
+XStatus XEmac_GetPktWaitBound(XEmac * InstancePtr, u32 Direction,
+			      u32 * WaitPtr);
+XStatus XEmac_SetSgRecvSpace(XEmac * InstancePtr, u32 * MemoryPtr,
+			     u32 ByteCount, void *PhyPtr);
+XStatus XEmac_SetSgSendSpace(XEmac * InstancePtr, u32 * MemoryPtr,
+			     u32 ByteCount, void *PhyPtr);
+void XEmac_SetSgRecvHandler(XEmac * InstancePtr, void *CallBackRef,
+			    XEmac_SgHandler FuncPtr);
+void XEmac_SetSgSendHandler(XEmac * InstancePtr, void *CallBackRef,
+			    XEmac_SgHandler FuncPtr);
+unsigned XEmac_GetSgSendFreeDesc(XEmac * InstancePtr);
+unsigned XEmac_GetSgRecvFreeDesc(XEmac * InstancePtr);
+
+void XEmac_IntrHandlerDma(void *InstancePtr);	/* interrupt handler */
+
+/*
+ * Interrupts with direct FIFO functions in xemac_intr_fifo.c. Also used
+ * for simple DMA.
+ */
+XStatus XEmac_FifoSend(XEmac * InstancePtr, u8 * BufPtr, u32 ByteCount);
+XStatus XEmac_FifoRecv(XEmac * InstancePtr, u8 * BufPtr, u32 * ByteCountPtr);
+void XEmac_SetFifoRecvHandler(XEmac * InstancePtr, void *CallBackRef,
+			      XEmac_FifoHandler FuncPtr);
+void XEmac_SetFifoSendHandler(XEmac * InstancePtr, void *CallBackRef,
+			      XEmac_FifoHandler FuncPtr);
+
+void XEmac_IntrHandlerFifo(void *InstancePtr);	/* interrupt handler */
+
+/*
+ * General interrupt-related functions in xemac_intr.c
+ */
+void XEmac_SetErrorHandler(XEmac * InstancePtr, void *CallBackRef,
+			   XEmac_ErrorHandler FuncPtr);
+
+/*
+ * MAC configuration in xemac_options.c
+ */
+XStatus XEmac_SetOptions(XEmac * InstancePtr, u32 OptionFlag);
+u32 XEmac_GetOptions(XEmac * InstancePtr);
+XStatus XEmac_SetMacAddress(XEmac * InstancePtr, u8 * AddressPtr);
+void XEmac_GetMacAddress(XEmac * InstancePtr, u8 * BufferPtr);
+XStatus XEmac_SetInterframeGap(XEmac * InstancePtr, u8 Part1, u8 Part2);
+void XEmac_GetInterframeGap(XEmac * InstancePtr, u8 * Part1Ptr, u8 * Part2Ptr);
+
+/*
+ * Multicast functions in xemac_multicast.c (not supported by EMAC yet)
+ */
+XStatus XEmac_MulticastAdd(XEmac * InstancePtr, u8 * AddressPtr);
+XStatus XEmac_MulticastClear(XEmac * InstancePtr);
+
+/*
+ * PHY configuration in xemac_phy.c
+ */
+XStatus XEmac_PhyRead(XEmac * InstancePtr, u32 PhyAddress,
+		      u32 RegisterNum, u16 * PhyDataPtr);
+XStatus XEmac_PhyWrite(XEmac * InstancePtr, u32 PhyAddress,
+		       u32 RegisterNum, u16 PhyData);
+
+/*
+ * Statistics in xemac_stats.c
+ */
+void XEmac_GetStats(XEmac * InstancePtr, XEmac_Stats * StatsPtr);
+void XEmac_ClearStats(XEmac * InstancePtr);
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/drivers/net/xilinx_enet/xemac_i.h linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac_i.h
--- linux-2.4.29/drivers/net/xilinx_enet/xemac_i.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac_i.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,209 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xemac_i.h
+*
+* This header file contains internal identifiers, which are those shared
+* between XEmac components.  The identifiers in this file are not intended for
+* use external to the driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  07/31/01 First release
+* 1.00b rpm  02/20/02 Repartitioned files and functions
+* 1.00b rpm  04/29/02 Moved register definitions to xemac_l.h
+* 1.00c rpm  12/05/02 New version includes support for simple DMA
+* 1.00d rpm  09/26/03 New version includes support PLB Ethernet and v2.00a of
+*                     the packet fifo driver.
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XEMAC_I_H		/* prevent circular inclusions */
+#define XEMAC_I_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xemac.h"
+#include "xemac_l.h"
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * Default buffer descriptor control word masks. The default send BD control
+ * is set for incrementing the source address by one for each byte transferred,
+ * and specify that the destination address (FIFO) is local to the device. The
+ * default receive BD control is set for incrementing the destination address
+ * by one for each byte transferred, and specify that the source address is
+ * local to the device.
+ */
+#define XEM_DFT_SEND_BD_MASK    (XDC_DMACR_SOURCE_INCR_MASK | \
+                                 XDC_DMACR_DEST_LOCAL_MASK)
+#define XEM_DFT_RECV_BD_MASK    (XDC_DMACR_DEST_INCR_MASK |  \
+                                 XDC_DMACR_SOURCE_LOCAL_MASK)
+
+/*
+ * Masks for the IPIF Device Interrupt enable and status registers.
+ */
+#define XEM_IPIF_EMAC_MASK      0x00000004UL	/* MAC interrupt */
+#define XEM_IPIF_SEND_DMA_MASK  0x00000008UL	/* Send DMA interrupt */
+#define XEM_IPIF_RECV_DMA_MASK  0x00000010UL	/* Receive DMA interrupt */
+#define XEM_IPIF_RECV_FIFO_MASK 0x00000020UL	/* Receive FIFO interrupt */
+#define XEM_IPIF_SEND_FIFO_MASK 0x00000040UL	/* Send FIFO interrupt */
+
+/*
+ * Default IPIF Device Interrupt mask when configured for DMA
+ */
+#define XEM_IPIF_DMA_DFT_MASK   (XEM_IPIF_SEND_DMA_MASK |   \
+                                 XEM_IPIF_RECV_DMA_MASK |   \
+                                 XEM_IPIF_EMAC_MASK |       \
+                                 XEM_IPIF_SEND_FIFO_MASK |  \
+                                 XEM_IPIF_RECV_FIFO_MASK)
+
+/*
+ * Default IPIF Device Interrupt mask when configured without DMA
+ */
+#define XEM_IPIF_FIFO_DFT_MASK  (XEM_IPIF_EMAC_MASK |       \
+                                 XEM_IPIF_SEND_FIFO_MASK |  \
+                                 XEM_IPIF_RECV_FIFO_MASK)
+
+#define XEM_IPIF_DMA_DEV_INTR_COUNT   7	/* Number of interrupt sources */
+#define XEM_IPIF_FIFO_DEV_INTR_COUNT  5	/* Number of interrupt sources */
+#define XEM_IPIF_DEVICE_INTR_COUNT  7	/* Number of interrupt sources */
+#define XEM_IPIF_IP_INTR_COUNT      22	/* Number of MAC interrupts */
+
+/* a mask for all transmit interrupts, used in polled mode */
+#define XEM_EIR_XMIT_ALL_MASK   (XEM_EIR_XMIT_DONE_MASK |           \
+                                 XEM_EIR_XMIT_ERROR_MASK |          \
+                                 XEM_EIR_XMIT_SFIFO_EMPTY_MASK |    \
+                                 XEM_EIR_XMIT_LFIFO_FULL_MASK)
+
+/* a mask for all receive interrupts, used in polled mode */
+#define XEM_EIR_RECV_ALL_MASK   (XEM_EIR_RECV_DONE_MASK |           \
+                                 XEM_EIR_RECV_ERROR_MASK |          \
+                                 XEM_EIR_RECV_LFIFO_EMPTY_MASK |    \
+                                 XEM_EIR_RECV_LFIFO_OVER_MASK |     \
+                                 XEM_EIR_RECV_LFIFO_UNDER_MASK |    \
+                                 XEM_EIR_RECV_DFIFO_OVER_MASK |     \
+                                 XEM_EIR_RECV_MISSED_FRAME_MASK |   \
+                                 XEM_EIR_RECV_COLLISION_MASK |      \
+                                 XEM_EIR_RECV_FCS_ERROR_MASK |      \
+                                 XEM_EIR_RECV_LEN_ERROR_MASK |      \
+                                 XEM_EIR_RECV_SHORT_ERROR_MASK |    \
+                                 XEM_EIR_RECV_LONG_ERROR_MASK |     \
+                                 XEM_EIR_RECV_ALIGN_ERROR_MASK)
+
+/* a default interrupt mask for scatter-gather DMA operation */
+#define XEM_EIR_DFT_SG_MASK    (XEM_EIR_RECV_ERROR_MASK |           \
+                                XEM_EIR_RECV_LFIFO_OVER_MASK |      \
+                                XEM_EIR_RECV_LFIFO_UNDER_MASK |     \
+                                XEM_EIR_XMIT_SFIFO_OVER_MASK |      \
+                                XEM_EIR_XMIT_SFIFO_UNDER_MASK |     \
+                                XEM_EIR_XMIT_LFIFO_OVER_MASK |      \
+                                XEM_EIR_XMIT_LFIFO_UNDER_MASK |     \
+                                XEM_EIR_RECV_DFIFO_OVER_MASK |      \
+                                XEM_EIR_RECV_MISSED_FRAME_MASK |    \
+                                XEM_EIR_RECV_COLLISION_MASK |       \
+                                XEM_EIR_RECV_FCS_ERROR_MASK |       \
+                                XEM_EIR_RECV_LEN_ERROR_MASK |       \
+                                XEM_EIR_RECV_SHORT_ERROR_MASK |     \
+                                XEM_EIR_RECV_LONG_ERROR_MASK |      \
+                                XEM_EIR_RECV_ALIGN_ERROR_MASK)
+
+/* a default interrupt mask for non-DMA operation (direct FIFOs) */
+#define XEM_EIR_DFT_FIFO_MASK  (XEM_EIR_XMIT_DONE_MASK |            \
+                                XEM_EIR_RECV_DONE_MASK |            \
+                                XEM_EIR_DFT_SG_MASK)
+
+/*
+ * Mask for the DMA interrupt enable and status registers when configured
+ * for scatter-gather DMA.
+ */
+#define XEM_DMA_SG_INTR_MASK    (XDC_IXR_DMA_ERROR_MASK  |      \
+                                 XDC_IXR_PKT_THRESHOLD_MASK |   \
+                                 XDC_IXR_PKT_WAIT_BOUND_MASK |  \
+                                 XDC_IXR_SG_END_MASK)
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/*
+*
+* Clears a structure of given size, in bytes, by setting each byte to 0.
+*
+* @param StructPtr is a pointer to the structure to be cleared.
+* @param NumBytes is the number of bytes in the structure.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XEmac_mClearStruct(u8 *StructPtr, unsigned int NumBytes)
+*
+******************************************************************************/
+#define XEmac_mClearStruct(StructPtr, NumBytes)     \
+{                                                   \
+    int i;                                          \
+    u8 *BytePtr = (u8 *)(StructPtr);        \
+    for (i=0; i < (unsigned int)(NumBytes); i++)    \
+    {                                               \
+        *BytePtr++ = 0;                             \
+    }                                               \
+}
+
+/************************** Variable Definitions *****************************/
+
+extern XEmac_Config XEmac_ConfigTable[];
+
+/************************** Function Prototypes ******************************/
+
+void XEmac_CheckEmacError(XEmac * InstancePtr, u32 IntrStatus);
+void XEmac_CheckFifoRecvError(XEmac * InstancePtr);
+void XEmac_CheckFifoSendError(XEmac * InstancePtr);
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/drivers/net/xilinx_enet/xemac_intr.c linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac_intr.c
--- linux-2.4.29/drivers/net/xilinx_enet/xemac_intr.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac_intr.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,404 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xemac_intr.c
+*
+* This file contains general interrupt-related functions of the XEmac driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  07/31/01 First release
+* 1.00b rpm  02/20/02 Repartitioned files and functions
+* 1.00c rpm  12/05/02 New version includes support for simple DMA
+* 1.00c rpm  03/31/03 Added comment to indicate that no Receive Length FIFO
+*                     overrun interrupts occur in v1.00l and later of the EMAC
+*                     device. This avoids the need to reset the device on
+*                     receive overruns.
+* 1.00d rpm  09/26/03 New version includes support PLB Ethernet and v2.00a of
+*                     the packet fifo driver.
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xemac_i.h"
+#include "xio.h"
+#include "xipif_v1_23_b.h"	/* Uses v1.23b of the IPIF */
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Variable Definitions *****************************/
+
+/************************** Function Prototypes ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Set the callback function for handling asynchronous errors.  The upper layer
+* software should call this function during initialization.
+*
+* The error callback is invoked by the driver within interrupt context, so it
+* needs to do its job quickly. If there are potentially slow operations within
+* the callback, these should be done at task-level.
+*
+* The Xilinx errors that must be handled by the callback are:
+* - XST_DMA_ERROR indicates an unrecoverable DMA error occurred. This is
+*   typically a bus error or bus timeout. The handler must reset and
+*   re-configure the device.
+* - XST_FIFO_ERROR indicates an unrecoverable FIFO error occurred. This is a
+*   deadlock condition in the packet FIFO. The handler must reset and
+*   re-configure the device.
+* - XST_RESET_ERROR indicates an unrecoverable MAC error occurred, usually an
+*   overrun or underrun. The handler must reset and re-configure the device.
+* - XST_DMA_SG_NO_LIST indicates an attempt was made to access a scatter-gather
+*   DMA list that has not yet been created.
+* - XST_DMA_SG_LIST_EMPTY indicates the driver tried to get a descriptor from
+*   the receive descriptor list, but the list was empty.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param CallBackRef is a reference pointer to be passed back to the adapter in
+*        the callback. This helps the adapter correlate the callback to a
+*        particular driver.
+* @param FuncPtr is the pointer to the callback function.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XEmac_SetErrorHandler(XEmac * InstancePtr, void *CallBackRef,
+		      XEmac_ErrorHandler FuncPtr)
+{
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(FuncPtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	InstancePtr->ErrorHandler = FuncPtr;
+	InstancePtr->ErrorRef = CallBackRef;
+}
+
+/****************************************************************************/
+/*
+*
+* Check the interrupt status bits of the Ethernet MAC for errors. Errors
+* currently handled are:
+* - Receive length FIFO overrun. Indicates data was lost due to the receive
+*   length FIFO becoming full during the reception of a packet. Only a device
+*   reset clears this condition.
+* - Receive length FIFO underrun. An attempt to read an empty FIFO. Only a
+*   device reset clears this condition.
+* - Transmit status FIFO overrun. Indicates data was lost due to the transmit
+*   status FIFO becoming full following the transmission of a packet. Only a
+*   device reset clears this condition.
+* - Transmit status FIFO underrun. An attempt to read an empty FIFO. Only a
+*   device reset clears this condition.
+* - Transmit length FIFO overrun. Indicates data was lost due to the transmit
+*   length FIFO becoming full following the transmission of a packet. Only a
+*   device reset clears this condition.
+* - Transmit length FIFO underrun. An attempt to read an empty FIFO. Only a
+*   device reset clears this condition.
+* - Receive data FIFO overrun. Indicates data was lost due to the receive data
+*   FIFO becoming full during the reception of a packet.
+* - Receive data errors:
+*   - Receive missed frame error. Valid data was lost by the MAC.
+*   - Receive collision error. Data was lost by the MAC due to a collision.
+*   - Receive FCS error.  Data was dicarded by the MAC due to FCS error.
+*   - Receive length field error. Data was dicarded by the MAC due to an invalid
+*     length field in the packet.
+*   - Receive short error. Data was dicarded by the MAC because a packet was
+*     shorter than allowed.
+*   - Receive long error. Data was dicarded by the MAC because a packet was
+*     longer than allowed.
+*   - Receive alignment error. Data was truncated by the MAC because its length
+*     was not byte-aligned.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param IntrStatus is the contents of the interrupt status register to be checked
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* This function is intended for internal use only.
+*
+******************************************************************************/
+void
+XEmac_CheckEmacError(XEmac * InstancePtr, u32 IntrStatus)
+{
+	u32 ResetError = FALSE;
+
+	/*
+	 * First check for receive fifo overrun/underrun errors. Most require a
+	 * reset by the user to clear, but the data FIFO overrun error does not.
+	 */
+	if (IntrStatus & XEM_EIR_RECV_DFIFO_OVER_MASK) {
+		InstancePtr->Stats.RecvOverrunErrors++;
+		InstancePtr->Stats.FifoErrors++;
+	}
+
+	if (IntrStatus & XEM_EIR_RECV_LFIFO_OVER_MASK) {
+		/*
+		 * Receive Length FIFO overrun interrupts no longer occur in v1.00l
+		 * and later of the EMAC device. Frames are just dropped by the EMAC
+		 * if the length FIFO is full. The user would notice the Receive Missed
+		 * Frame count incrementing without any other errors being reported.
+		 * This code is left here for backward compatibility with v1.00k and
+		 * older EMAC devices.
+		 */
+		InstancePtr->Stats.RecvOverrunErrors++;
+		InstancePtr->Stats.FifoErrors++;
+		ResetError = TRUE;	/* requires a reset */
+	}
+
+	if (IntrStatus & XEM_EIR_RECV_LFIFO_UNDER_MASK) {
+		InstancePtr->Stats.RecvUnderrunErrors++;
+		InstancePtr->Stats.FifoErrors++;
+		ResetError = TRUE;	/* requires a reset */
+	}
+
+	/*
+	 * Now check for general receive errors. Get the latest count where
+	 * available, otherwise just bump the statistic so we know the interrupt
+	 * occurred.
+	 */
+	if (IntrStatus & XEM_EIR_RECV_ERROR_MASK) {
+		if (IntrStatus & XEM_EIR_RECV_MISSED_FRAME_MASK) {
+			/*
+			 * Caused by length FIFO or data FIFO overruns on receive side
+			 */
+			InstancePtr->Stats.RecvMissedFrameErrors =
+			    XIo_In32(InstancePtr->BaseAddress +
+				     XEM_RMFC_OFFSET);
+		}
+
+		if (IntrStatus & XEM_EIR_RECV_COLLISION_MASK) {
+			InstancePtr->Stats.RecvCollisionErrors =
+			    XIo_In32(InstancePtr->BaseAddress + XEM_RCC_OFFSET);
+		}
+
+		if (IntrStatus & XEM_EIR_RECV_FCS_ERROR_MASK) {
+			InstancePtr->Stats.RecvFcsErrors =
+			    XIo_In32(InstancePtr->BaseAddress +
+				     XEM_RFCSEC_OFFSET);
+		}
+
+		if (IntrStatus & XEM_EIR_RECV_LEN_ERROR_MASK) {
+			InstancePtr->Stats.RecvLengthFieldErrors++;
+		}
+
+		if (IntrStatus & XEM_EIR_RECV_SHORT_ERROR_MASK) {
+			InstancePtr->Stats.RecvShortErrors++;
+		}
+
+		if (IntrStatus & XEM_EIR_RECV_LONG_ERROR_MASK) {
+			InstancePtr->Stats.RecvLongErrors++;
+		}
+
+		if (IntrStatus & XEM_EIR_RECV_ALIGN_ERROR_MASK) {
+			InstancePtr->Stats.RecvAlignmentErrors =
+			    XIo_In32(InstancePtr->BaseAddress +
+				     XEM_RAEC_OFFSET);
+		}
+
+		/*
+		 * Bump recv interrupts stats only if not scatter-gather DMA (this
+		 * stat gets bumped elsewhere in that case)
+		 */
+		if (!XEmac_mIsSgDma(InstancePtr)) {
+			InstancePtr->Stats.RecvInterrupts++;	/* TODO: double bump? */
+		}
+
+	}
+
+	/*
+	 * Check for transmit errors. These apply to both DMA and non-DMA modes
+	 * of operation. The entire device should be reset after overruns or
+	 * underruns.
+	 */
+	if (IntrStatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
+			  XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
+		InstancePtr->Stats.XmitOverrunErrors++;
+		InstancePtr->Stats.FifoErrors++;
+		ResetError = TRUE;
+	}
+
+	if (IntrStatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
+			  XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
+		InstancePtr->Stats.XmitUnderrunErrors++;
+		InstancePtr->Stats.FifoErrors++;
+		ResetError = TRUE;
+	}
+
+	if (ResetError) {
+		/*
+		 * If a reset error occurred, disable the EMAC interrupts since the
+		 * reset-causing interrupt(s) is latched in the EMAC - meaning it will
+		 * keep occurring until the device is reset. In order to give the higher
+		 * layer software time to reset the device, we have to disable the
+		 * overrun/underrun interrupts until that happens. We trust that the
+		 * higher layer resets the device. We are able to get away with disabling
+		 * all EMAC interrupts since the only interrupts it generates are for
+		 * error conditions, and we don't care about any more errors right now.
+		 */
+		XIIF_V123B_WRITE_IIER(InstancePtr->BaseAddress, 0);
+
+		/*
+		 * Invoke the error handler callback, which should result in a reset
+		 * of the device by the upper layer software.
+		 */
+		InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
+					  XST_RESET_ERROR);
+	}
+}
+
+/*****************************************************************************/
+/*
+*
+* Check the receive packet FIFO for errors. FIFO error interrupts are:
+* - Deadlock.  See the XPacketFifo component for a description of deadlock on a
+*   FIFO.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Although the function returns void, it can return an asynchronous error to the
+* application through the error handler.  It can return XST_FIFO_ERROR if a FIFO
+* error occurred.
+*
+* @note
+*
+* This function is intended for internal use only.
+*
+******************************************************************************/
+void
+XEmac_CheckFifoRecvError(XEmac * InstancePtr)
+{
+	/*
+	 * Although the deadlock is currently the only interrupt from a packet
+	 * FIFO, make sure it is deadlocked before taking action. There is no
+	 * need to clear this interrupt since it requires a reset of the device.
+	 */
+	if (XPF_V200A_IS_DEADLOCKED(&InstancePtr->RecvFifo)) {
+		u32 IntrEnable;
+
+		InstancePtr->Stats.FifoErrors++;
+
+		/*
+		 * Invoke the error callback function, which should result in a reset
+		 * of the device by the upper layer software. We first need to disable
+		 * the FIFO interrupt, since otherwise the upper layer thread that
+		 * handles the reset may never run because this interrupt condition
+		 * doesn't go away until a reset occurs (there is no way to ack it).
+		 */
+		IntrEnable = XIIF_V123B_READ_DIER(InstancePtr->BaseAddress);
+		XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
+				      IntrEnable & ~XEM_IPIF_RECV_FIFO_MASK);
+
+		InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
+					  XST_FIFO_ERROR);
+	}
+}
+
+/*****************************************************************************/
+/*
+*
+* Check the send packet FIFO for errors. FIFO error interrupts are:
+* - Deadlock. See the XPacketFifo component for a description of deadlock on a
+*   FIFO.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Although the function returns void, it can return an asynchronous error to the
+* application through the error handler.  It can return XST_FIFO_ERROR if a FIFO
+* error occurred.
+*
+* @note
+*
+* This function is intended for internal use only.
+*
+******************************************************************************/
+void
+XEmac_CheckFifoSendError(XEmac * InstancePtr)
+{
+	/*
+	 * Although the deadlock is currently the only interrupt from a packet
+	 * FIFO, make sure it is deadlocked before taking action. There is no
+	 * need to clear this interrupt since it requires a reset of the device.
+	 */
+	if (XPF_V200A_IS_DEADLOCKED(&InstancePtr->SendFifo)) {
+		u32 IntrEnable;
+
+		InstancePtr->Stats.FifoErrors++;
+
+		/*
+		 * Invoke the error callback function, which should result in a reset
+		 * of the device by the upper layer software. We first need to disable
+		 * the FIFO interrupt, since otherwise the upper layer thread that
+		 * handles the reset may never run because this interrupt condition
+		 * doesn't go away until a reset occurs (there is no way to ack it).
+		 */
+		IntrEnable = XIIF_V123B_READ_DIER(InstancePtr->BaseAddress);
+		XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
+				      IntrEnable & ~XEM_IPIF_SEND_FIFO_MASK);
+
+		InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
+					  XST_FIFO_ERROR);
+	}
+}
diff -urN linux-2.4.29/drivers/net/xilinx_enet/xemac_intr_dma.c linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac_intr_dma.c
--- linux-2.4.29/drivers/net/xilinx_enet/xemac_intr_dma.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac_intr_dma.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,1407 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xemac_intr_dma.c
+*
+* Contains functions used in interrupt mode when configured with scatter-gather
+* DMA.
+*
+* The interrupt handler, XEmac_IntrHandlerDma(), must be connected by the user
+* to the interrupt controller.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------------
+* 1.00a rpm  07/31/01 First release
+* 1.00b rpm  02/20/02 Repartitioned files and functions
+* 1.00c rpm  12/05/02 New version includes support for simple DMA and the delay
+*                     argument to SgSend
+* 1.00c rpm  02/03/03 The XST_DMA_SG_COUNT_EXCEEDED return code was removed
+*                     from SetPktThreshold in the internal DMA driver. Also
+*                     avoided compiler warnings by initializing Result in the
+*                     interrupt service routines.
+* 1.00c rpm  03/26/03 Fixed a problem in the interrupt service routines where
+*                     the interrupt status was toggled clear after a call to
+*                     ErrorHandler, but if ErrorHandler reset the device the
+*                     toggle actually asserted the interrupt because the
+*                     reset had cleared it.
+* 1.00d rpm  09/26/03 New version includes support PLB Ethernet and v2.00a of
+*                     the packet fifo driver.
+* 1.00e rmm  04/06/04 Instead of invoking once for each packet received, 
+*                     send/recv callbacks are invoked once for all packets.
+*                     Added functions XEmac_GetSgRecvFreeDesc() and XEmac_Get-
+*                     SgSendFreeDesc().
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xemac_i.h"
+#include "xio.h"
+#include "xbuf_descriptor.h"
+#include "xdma_channel.h"
+#include "xipif_v1_23_b.h"	/* Uses v1.23b of the IPIF */
+#include <linux/config.h>	/* Get CONFIG_XILINX_.... */
+#include <asm/pgalloc.h>	/* Cache flush routines */
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Variable Definitions *****************************/
+
+/************************** Function Prototypes ******************************/
+
+static void HandleDmaRecvIntr(XEmac * InstancePtr);
+static void HandleDmaSendIntr(XEmac * InstancePtr);
+static void HandleEmacDmaIntr(XEmac * InstancePtr);
+
+/*****************************************************************************/
+/**
+*
+* Send an Ethernet frame using scatter-gather DMA. The caller attaches the
+* frame to one or more buffer descriptors, then calls this function once for
+* each descriptor. The caller is responsible for allocating and setting up the
+* descriptor. An entire Ethernet frame may or may not be contained within one
+* descriptor.  This function simply inserts the descriptor into the scatter-
+* gather engine's transmit list. The caller is responsible for providing mutual
+* exclusion to guarantee that a frame is contiguous in the transmit list. The
+* buffer attached to the descriptor must be 32-bit aligned if using the OPB
+* Ethernet core and 64-bit aligned if using the PLB Ethernet core.
+*
+* The driver updates the descriptor with the device control register before
+* being inserted into the transmit list.  If this is the last descriptor in
+* the frame, the inserts are committed, which means the descriptors for this
+* frame are now available for transmission.
+*
+* It is assumed that the upper layer software supplies a correctly formatted
+* Ethernet frame, including the destination and source addresses, the
+* type/length field, and the data field.  It is also assumed that upper layer
+* software does not append FCS at the end of the frame.
+*
+* This call is non-blocking.  Notification of error or successful transmission
+* is done asynchronously through the send or error callback function.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param BdPtr is the address of a descriptor to be inserted into the transmit
+*        ring.
+* @param Delay indicates whether to start the scatter-gather DMA channel
+*        immediately, or whether to wait. This allows the user to build up a
+*        list of more than one descriptor before starting the transmission of
+*        the packets, which allows the application to keep up with DMA and have
+*        a constant stream of frames being transmitted. Use XEM_SGDMA_NODELAY or
+*        XEM_SGDMA_DELAY, defined in xemac.h, as the value of this argument. If
+*        the user chooses to delay and build a list, the user must call this
+*        function with the XEM_SGDMA_NODELAY option or call XEmac_Start() to
+*        kick off the tranmissions.
+*
+* @return
+*
+* - XST_SUCCESS if the buffer was successfull sent
+* - XST_DEVICE_IS_STOPPED if the Ethernet MAC has not been started yet
+* - XST_NOT_SGDMA if the device is not in scatter-gather DMA mode
+* - XST_DMA_SG_LIST_FULL if the descriptor list for the DMA channel is full
+* - XST_DMA_SG_BD_LOCKED if the DMA channel cannot insert the descriptor into
+*   the list because a locked descriptor exists at the insert point
+* - XST_DMA_SG_NOTHING_TO_COMMIT if even after inserting a descriptor into the
+*   list, the DMA channel believes there are no new descriptors to commit. If
+*   this is ever encountered, there is likely a thread mutual exclusion problem
+*   on transmit.
+*
+* @note
+*
+* This function is not thread-safe. The user must provide mutually exclusive
+* access to this function if there are to be multiple threads that can call it.
+*
+* @internal
+*
+* A status that should never be returned from this function, although
+* the code is set up to handle it, is XST_DMA_SG_NO_LIST. Starting the device
+* requires a list to be created, and this function requires the device to be
+* started.
+*
+******************************************************************************/
+XStatus
+XEmac_SgSend(XEmac * InstancePtr, XBufDescriptor * BdPtr, int Delay)
+{
+	XStatus Result;
+	u32 BdControl;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BdPtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/*
+	 * Be sure the device is configured for scatter-gather DMA, then be sure
+	 * it is started.
+	 */
+	if (!XEmac_mIsSgDma(InstancePtr)) {
+		return XST_NOT_SGDMA;
+	}
+
+	/*
+	 * Set some descriptor control word defaults (source address increment
+	 * and local destination address) and the destination address
+	 * (the FIFO).  These are the same for every transmit descriptor.
+	 */
+	BdControl = XBufDescriptor_GetControl(BdPtr);
+	XBufDescriptor_SetControl(BdPtr, BdControl | XEM_DFT_SEND_BD_MASK);
+
+	XBufDescriptor_SetDestAddress(BdPtr,
+				      InstancePtr->PhysAddress +
+				      XEM_PFIFO_TXDATA_OFFSET);
+
+	/*
+	 * Put the descriptor in the send list. The DMA component accesses data
+	 * here that can also be modified in interrupt context, so a critical
+	 * section is required.
+	 */
+	XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
+
+	Result = XDmaChannel_PutDescriptor(&InstancePtr->SendChannel, BdPtr);
+	if (Result != XST_SUCCESS) {
+		XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+		return Result;
+	}
+
+	/*
+	 * If this is the last buffer in the frame, commit the inserts and start
+	 * the DMA engine if necessary
+	 */
+	if (XBufDescriptor_IsLastControl(BdPtr)) {
+		Result = XDmaChannel_CommitPuts(&InstancePtr->SendChannel);
+		if (Result != XST_SUCCESS) {
+			XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+			return Result;
+		}
+
+		if (Delay == XEM_SGDMA_NODELAY) {
+			/*
+			 * Start the DMA channel. Ignore the return status since we know the
+			 * list exists and has at least one entry and we don't care if the
+			 * channel is already started.  The DMA component accesses data here
+			 * that can be modified at interrupt or task levels, so a critical
+			 * section is required.
+			 */
+			(void) XDmaChannel_SgStart(&InstancePtr->SendChannel);
+		}
+	}
+
+	XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Add a descriptor, with an attached empty buffer, into the receive descriptor
+* list. The buffer attached to the descriptor must be 32-bit aligned if using
+* the OPB Ethernet core and 64-bit aligned if using the PLB Ethernet core.
+* This function is used by the upper layer software during initialization when
+* first setting up the receive descriptors, and also during reception of frames
+* to replace filled buffers with empty buffers. This function can be called
+* when the device is started or stopped. Note that it does start the scatter-
+* gather DMA engine.  Although this is not necessary during initialization, it
+* is not a problem during initialization because the MAC receiver is not yet
+* started.
+*
+* The buffer attached to the descriptor must be aligned on both the front end
+* and the back end.
+*
+* Notification of received frames are done asynchronously through the receive
+* callback function.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param BdPtr is a pointer to the buffer descriptor that will be added to the
+*        descriptor list.
+*
+* @return
+*
+* - XST_SUCCESS if a descriptor was successfully returned to the driver
+* - XST_NOT_SGDMA if the device is not in scatter-gather DMA mode
+* - XST_DMA_SG_LIST_FULL if the receive descriptor list is full
+* - XST_DMA_SG_BD_LOCKED if the DMA channel cannot insert the descriptor into
+*   the list because a locked descriptor exists at the insert point.
+* - XST_DMA_SG_NOTHING_TO_COMMIT if even after inserting a descriptor into the
+*   list, the DMA channel believes there are no new descriptors to commit.
+*
+* @internal
+*
+* A status that should never be returned from this function, although
+* the code is set up to handle it, is XST_DMA_SG_NO_LIST. Starting the device
+* requires a list to be created, and this function requires the device to be
+* started.
+*
+******************************************************************************/
+XStatus
+XEmac_SgRecv(XEmac * InstancePtr, XBufDescriptor * BdPtr)
+{
+	XStatus Result;
+	u32 BdControl;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BdPtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/*
+	 * Be sure the device is configured for scatter-gather DMA
+	 */
+	if (!XEmac_mIsSgDma(InstancePtr)) {
+		return XST_NOT_SGDMA;
+	}
+
+	/*
+	 * Set some descriptor control word defaults (destination address increment
+	 * and local source address) and the source address (the FIFO). These are
+	 * the same for every receive descriptor.
+	 */
+	BdControl = XBufDescriptor_GetControl(BdPtr);
+	XBufDescriptor_SetControl(BdPtr, BdControl | XEM_DFT_RECV_BD_MASK);
+	XBufDescriptor_SetSrcAddress(BdPtr,
+				     InstancePtr->PhysAddress +
+				     XEM_PFIFO_RXDATA_OFFSET);
+
+	/*
+	 * Put the descriptor into the channel's descriptor list and commit.
+	 * Although this function is likely called within interrupt context, there
+	 * is the possibility that the upper layer software queues it to a task.
+	 * In this case, a critical section is needed here to protect shared data
+	 * in the DMA component.
+	 */
+	XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
+
+	Result = XDmaChannel_PutDescriptor(&InstancePtr->RecvChannel, BdPtr);
+	if (Result != XST_SUCCESS) {
+		XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+		return Result;
+	}
+
+	Result = XDmaChannel_CommitPuts(&InstancePtr->RecvChannel);
+	if (Result != XST_SUCCESS) {
+		XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+		return Result;
+	}
+
+	/*
+	 * Start the DMA channel. Ignore the return status since we know the list
+	 * exists and has at least one entry and we don't care if the channel is
+	 * already started. The DMA component accesses data here that can be
+	 * modified at interrupt or task levels, so a critical section is required.
+	 */
+	(void) XDmaChannel_SgStart(&InstancePtr->RecvChannel);
+
+	XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* The interrupt handler for the Ethernet driver when configured with scatter-
+* gather DMA.
+*
+* Get the interrupt status from the IpIf to determine the source of the
+* interrupt.  The source can be: MAC, Recv Packet FIFO, Send Packet FIFO, Recv
+* DMA channel, or Send DMA channel. The packet FIFOs only interrupt during
+* "deadlock" conditions.
+*
+* @param InstancePtr is a pointer to the XEmac instance that just interrupted.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XEmac_IntrHandlerDma(void *InstancePtr)
+{
+	u32 IntrStatus;
+	XEmac *EmacPtr = (XEmac *) InstancePtr;
+
+	EmacPtr->Stats.TotalIntrs++;
+
+	/*
+	 * Get the interrupt status from the IPIF. There is no clearing of
+	 * interrupts in the IPIF. Interrupts must be cleared at the source.
+	 */
+	IntrStatus = XIIF_V123B_READ_DIPR(EmacPtr->BaseAddress);
+
+	/*
+	 * See which type of interrupt is being requested, and service it
+	 */
+	if (IntrStatus & XEM_IPIF_RECV_DMA_MASK) {	/* Receive DMA interrupt */
+		EmacPtr->Stats.RecvInterrupts++;
+		HandleDmaRecvIntr(EmacPtr);
+	}
+
+	if (IntrStatus & XEM_IPIF_SEND_DMA_MASK) {	/* Send DMA interrupt */
+		EmacPtr->Stats.XmitInterrupts++;
+		HandleDmaSendIntr(EmacPtr);
+	}
+
+	if (IntrStatus & XEM_IPIF_EMAC_MASK) {	/* MAC interrupt */
+		EmacPtr->Stats.EmacInterrupts++;
+		HandleEmacDmaIntr(EmacPtr);
+	}
+
+	if (IntrStatus & XEM_IPIF_RECV_FIFO_MASK) {	/* Receive FIFO interrupt */
+		EmacPtr->Stats.RecvInterrupts++;
+		XEmac_CheckFifoRecvError(EmacPtr);
+	}
+
+	if (IntrStatus & XEM_IPIF_SEND_FIFO_MASK) {	/* Send FIFO interrupt */
+		EmacPtr->Stats.XmitInterrupts++;
+		XEmac_CheckFifoSendError(EmacPtr);
+	}
+
+	if (IntrStatus & XIIF_V123B_ERROR_MASK) {
+		/*
+		 * An error occurred internal to the IPIF. This is more of a debug and
+		 * integration issue rather than a production error. Don't do anything
+		 * other than clear it, which provides a spot for software to trap
+		 * on the interrupt and begin debugging.
+		 */
+		XIIF_V123B_WRITE_DISR(EmacPtr->BaseAddress,
+				      XIIF_V123B_ERROR_MASK);
+	}
+}
+
+/*****************************************************************************/
+/**
+*
+* Set the packet count threshold for this device. The device must be stopped
+* before setting the threshold. The packet count threshold is used for interrupt
+* coalescing, which reduces the frequency of interrupts from the device to the
+* processor. In this case, the scatter-gather DMA engine only interrupts when
+* the packet count threshold is reached, instead of interrupting for each packet.
+* A packet is a generic term used by the scatter-gather DMA engine, and is
+* equivalent to an Ethernet frame in our case.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param Direction indicates the channel, send or receive, from which the
+*        threshold register is read.
+* @param Threshold is the value of the packet threshold count used during
+*        interrupt coalescing. A value of 0 disables the use of packet threshold
+*        by the hardware.
+*
+* @return
+*
+* - XST_SUCCESS if the threshold was successfully set
+* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA
+* - XST_DEVICE_IS_STARTED if the device has not been stopped
+* - XST_INVALID_PARAM if the Direction parameter is invalid. Turning on
+*   asserts would also catch this error.
+*
+* @note
+*
+* The packet threshold could be set to larger than the number of descriptors
+* allocated to the DMA channel. In this case, the wait bound will take over
+* and always indicate data arrival. There was a check in this function that
+* returned an error if the treshold was larger than the number of descriptors,
+* but that was removed because users would then have to set the threshold
+* only after they set descriptor space, which is an order dependency that
+* caused confustion.
+*
+******************************************************************************/
+XStatus
+XEmac_SetPktThreshold(XEmac * InstancePtr, u32 Direction, u8 Threshold)
+{
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/*
+	 * Be sure device is configured for scatter-gather DMA and has been stopped
+	 */
+	if (!XEmac_mIsSgDma(InstancePtr)) {
+		return XST_NOT_SGDMA;
+	}
+
+	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+		return XST_DEVICE_IS_STARTED;
+	}
+
+	/*
+	 * Based on the direction, set the packet threshold in the
+	 * corresponding DMA channel component.  Default to the receive
+	 * channel threshold register (if an invalid Direction is passed).
+	 */
+	switch (Direction) {
+	case XEM_SEND:
+		return XDmaChannel_SetPktThreshold(&InstancePtr->SendChannel,
+						   Threshold);
+
+	case XEM_RECV:
+		return XDmaChannel_SetPktThreshold(&InstancePtr->RecvChannel,
+						   Threshold);
+
+	default:
+		return XST_INVALID_PARAM;
+	}
+}
+
+/*****************************************************************************/
+/**
+*
+* Get the value of the packet count threshold for this driver/device. The packet
+* count threshold is used for interrupt coalescing, which reduces the frequency
+* of interrupts from the device to the processor. In this case, the
+* scatter-gather DMA engine only interrupts when the packet count threshold is
+* reached, instead of interrupting for each packet. A packet is a generic term
+* used by the scatter-gather DMA engine, and is equivalent to an Ethernet frame
+* in our case.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param Direction indicates the channel, send or receive, from which the
+*        threshold register is read.
+* @param ThreshPtr is a pointer to the byte into which the current value of the
+*        packet threshold register will be copied. An output parameter. A value
+*        of 0 indicates the use of packet threshold by the hardware is disabled.
+*
+* @return
+*
+* - XST_SUCCESS if the packet threshold was retrieved successfully
+* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA
+* - XST_INVALID_PARAM if the Direction parameter is invalid. Turning on
+*   asserts would also catch this error.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XEmac_GetPktThreshold(XEmac * InstancePtr, u32 Direction, u8 * ThreshPtr)
+{
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
+	XASSERT_NONVOID(ThreshPtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	if (!XEmac_mIsSgDma(InstancePtr)) {
+		return XST_NOT_SGDMA;
+	}
+
+	/*
+	 * Based on the direction, return the packet threshold set in the
+	 * corresponding DMA channel component.  Default to the value in
+	 * the receive channel threshold register (if an invalid Direction
+	 * is passed).
+	 */
+	switch (Direction) {
+	case XEM_SEND:
+		*ThreshPtr =
+		    XDmaChannel_GetPktThreshold(&InstancePtr->SendChannel);
+		break;
+
+	case XEM_RECV:
+		*ThreshPtr =
+		    XDmaChannel_GetPktThreshold(&InstancePtr->RecvChannel);
+		break;
+
+	default:
+		return XST_INVALID_PARAM;
+	}
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Set the packet wait bound timer for this driver/device. The device must be
+* stopped before setting the timer value. The packet wait bound is used during
+* interrupt coalescing to trigger an interrupt when not enough packets have been
+* received to reach the packet count threshold. A packet is a generic term used
+* by the scatter-gather DMA engine, and is equivalent to an Ethernet frame in
+* our case. The timer is in milliseconds.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param Direction indicates the channel, send or receive, from which the
+*        threshold register is read.
+* @param TimerValue is the value of the packet wait bound used during interrupt
+*        coalescing. It is in milliseconds in the range 0  - 1023. A value of 0
+*        disables the packet wait bound timer.
+*
+* @return
+*
+* - XST_SUCCESS if the packet wait bound was set successfully
+* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA
+* - XST_DEVICE_IS_STARTED if the device has not been stopped
+* - XST_INVALID_PARAM if the Direction parameter is invalid. Turning on
+*   asserts would also catch this error.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XEmac_SetPktWaitBound(XEmac * InstancePtr, u32 Direction, u32 TimerValue)
+{
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
+	XASSERT_NONVOID(TimerValue <= XEM_SGDMA_MAX_WAITBOUND);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/*
+	 * Be sure device is configured for scatter-gather DMA and has been stopped
+	 */
+	if (!XEmac_mIsSgDma(InstancePtr)) {
+		return XST_NOT_SGDMA;
+	}
+
+	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+		return XST_DEVICE_IS_STARTED;
+	}
+
+	/*
+	 * Based on the direction, set the packet wait bound in the
+	 * corresponding DMA channel component.  Default to the receive
+	 * channel wait bound register (if an invalid Direction is passed).
+	 */
+	switch (Direction) {
+	case XEM_SEND:
+		XDmaChannel_SetPktWaitBound(&InstancePtr->SendChannel,
+					    TimerValue);
+		break;
+
+	case XEM_RECV:
+		XDmaChannel_SetPktWaitBound(&InstancePtr->RecvChannel,
+					    TimerValue);
+		break;
+
+	default:
+		return XST_INVALID_PARAM;
+	}
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Get the packet wait bound timer for this driver/device. The packet wait bound
+* is used during interrupt coalescing to trigger an interrupt when not enough
+* packets have been received to reach the packet count threshold. A packet is a
+* generic term used by the scatter-gather DMA engine, and is equivalent to an
+* Ethernet frame in our case. The timer is in milliseconds.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param Direction indicates the channel, send or receive, from which the
+*        threshold register is read.
+* @param WaitPtr is a pointer to the byte into which the current value of the
+*        packet wait bound register will be copied. An output parameter. Units
+*        are in milliseconds in the range 0  - 1023. A value of 0 indicates the
+*        packet wait bound timer is disabled.
+*
+* @return
+*
+* - XST_SUCCESS if the packet wait bound was retrieved successfully
+* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA
+* - XST_INVALID_PARAM if the Direction parameter is invalid. Turning on
+*   asserts would also catch this error.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XEmac_GetPktWaitBound(XEmac * InstancePtr, u32 Direction, u32 * WaitPtr)
+{
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
+	XASSERT_NONVOID(WaitPtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	if (!XEmac_mIsSgDma(InstancePtr)) {
+		return XST_NOT_SGDMA;
+	}
+
+	/*
+	 * Based on the direction, return the packet wait bound set in the
+	 * corresponding DMA channel component.  Default to the value in
+	 * the receive channel wait bound register (if an invalid Direction
+	 * is passed).
+	 */
+	switch (Direction) {
+	case XEM_SEND:
+		*WaitPtr =
+		    XDmaChannel_GetPktWaitBound(&InstancePtr->SendChannel);
+		break;
+
+	case XEM_RECV:
+		*WaitPtr =
+		    XDmaChannel_GetPktWaitBound(&InstancePtr->RecvChannel);
+		break;
+
+	default:
+		return XST_INVALID_PARAM;
+	}
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Give the driver the memory space to be used for the scatter-gather DMA
+* receive descriptor list. This function should only be called once, during
+* initialization of the Ethernet driver. The memory space must be big enough
+* to hold some number of descriptors, depending on the needs of the system.
+* The xemac.h file defines minimum and default numbers of descriptors
+* which can be used to allocate this memory space.
+*
+* The memory space must be 32-bit aligned. An assert will occur if asserts
+* are turned on and the memory is not aligned.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param MemoryPtr is a pointer to the aligned memory.
+* @param ByteCount is the length, in bytes, of the memory space.
+*
+* @return
+*
+* - XST_SUCCESS if the space was initialized successfully
+* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA
+* - XST_DMA_SG_LIST_EXISTS if this list space has already been created
+*
+* @note
+*
+* If the device is configured for scatter-gather DMA, this function must be
+* called AFTER the XEmac_Initialize() function because the DMA channel
+* components must be initialized before the memory space is set.
+*
+******************************************************************************/
+XStatus
+XEmac_SetSgRecvSpace(XEmac * InstancePtr, u32 * MemoryPtr,
+		     u32 ByteCount, void *PhyPtr)
+{
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(MemoryPtr != NULL);
+	XASSERT_NONVOID(ByteCount != 0);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	if (!XEmac_mIsSgDma(InstancePtr)) {
+		return XST_NOT_SGDMA;
+	}
+
+	return XDmaChannel_CreateSgList(&InstancePtr->RecvChannel, MemoryPtr,
+					ByteCount, PhyPtr);
+}
+
+/*****************************************************************************/
+/**
+*
+* Give the driver the memory space to be used for the scatter-gather DMA
+* transmit descriptor list. This function should only be called once, during
+* initialization of the Ethernet driver. The memory space must be big enough
+* to hold some number of descriptors, depending on the needs of the system.
+* The xemac.h file defines minimum and default numbers of descriptors
+* which can be used to allocate this memory space.
+*
+* The memory space must be 32-bit aligned. An assert will occur if asserts
+* are turned on and the memory is not aligned.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param MemoryPtr is a pointer to the aligned memory.
+* @param ByteCount is the length, in bytes, of the memory space.
+*
+* @return
+*
+* - XST_SUCCESS if the space was initialized successfully
+* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA
+* - XST_DMA_SG_LIST_EXISTS if this list space has already been created
+*
+* @note
+*
+* If the device is configured for scatter-gather DMA, this function must be
+* called AFTER the XEmac_Initialize() function because the DMA channel
+* components must be initialized before the memory space is set.
+*
+******************************************************************************/
+XStatus
+XEmac_SetSgSendSpace(XEmac * InstancePtr, u32 * MemoryPtr,
+		     u32 ByteCount, void *PhyPtr)
+{
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(MemoryPtr != NULL);
+	XASSERT_NONVOID(ByteCount != 0);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	if (!XEmac_mIsSgDma(InstancePtr)) {
+		return XST_NOT_SGDMA;
+	}
+
+	return XDmaChannel_CreateSgList(&InstancePtr->SendChannel, MemoryPtr,
+					ByteCount, PhyPtr);
+}
+
+/*****************************************************************************/
+/**
+* Return the number of free buffer descriptor slots that can be added to the 
+* send descriptor ring with XEmac_SgSend() before filling it up.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* - The number of descriptors that can be given to the HW with XEmac_SgSend()
+* - 0 if no room is left or the device is not configured for SG DMA
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+unsigned
+XEmac_GetSgSendFreeDesc(XEmac * InstancePtr)
+{
+	unsigned Slots;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	Slots = InstancePtr->SendChannel.TotalDescriptorCount -
+	    InstancePtr->SendChannel.ActiveDescriptorCount;
+
+	return Slots;
+}
+
+/*****************************************************************************/
+/**
+*
+* Return the number of free buffer descriptor slots that can be added to the 
+* receive descriptor ring with XEmac_SgRecv() before filling it up.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* - The number of descriptors that can be given to the HW with XEmac_SgRecv()
+* - 0 if no room is left or the device is not configured for SG DMA
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+unsigned
+XEmac_GetSgRecvFreeDesc(XEmac * InstancePtr)
+{
+	unsigned Slots;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	Slots = InstancePtr->RecvChannel.TotalDescriptorCount -
+	    InstancePtr->RecvChannel.ActiveDescriptorCount;
+
+	return Slots;
+}
+
+/*****************************************************************************/
+/**
+*
+*
+* Set the callback function for handling received frames in scatter-gather DMA
+* mode.  The upper layer software should call this function during
+* initialization.  The callback is called once per frame received. The head of
+* a descriptor list is passed in along with the number of descriptors in the
+* list. Before leaving the callback, the upper layer software should attach a
+* new buffer to each descriptor in the list.
+*
+* The callback is invoked by the driver within interrupt context, so it needs
+* to do its job quickly. Sending the received frame up the protocol stack
+* should be done at task-level. If there are other potentially slow operations
+* within the callback, these too should be done at task-level.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param CallBackRef is a reference pointer to be passed back to the adapter in
+*        the callback. This helps the adapter correlate the callback to a
+*        particular driver.
+* @param FuncPtr is the pointer to the callback function.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XEmac_SetSgRecvHandler(XEmac * InstancePtr, void *CallBackRef,
+		       XEmac_SgHandler FuncPtr)
+{
+	/*
+	 * Asserted IsDmaSg here instead of run-time check because there is really
+	 * no ill-effects of setting these when not configured for scatter-gather.
+	 */
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(FuncPtr != NULL);
+	XASSERT_VOID(XEmac_mIsSgDma(InstancePtr));
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	InstancePtr->SgRecvHandler = FuncPtr;
+	InstancePtr->SgRecvRef = CallBackRef;
+}
+
+/*****************************************************************************/
+/**
+*
+* Set the callback function for handling confirmation of transmitted frames in
+* scatter-gather DMA mode.  The upper layer software should call this function
+* during initialization.  The callback is called once per frame sent. The head
+* of a descriptor list is passed in along with the number of descriptors in
+* the list. The callback is responsible for freeing buffers attached to these
+* descriptors.
+*
+* The callback is invoked by the driver within interrupt context, so it needs
+* to do its job quickly. If there are potentially slow operations within the
+* callback, these should be done at task-level.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param CallBackRef is a reference pointer to be passed back to the adapter in
+*        the callback. This helps the adapter correlate the callback to a
+*        particular driver.
+* @param FuncPtr is the pointer to the callback function.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XEmac_SetSgSendHandler(XEmac * InstancePtr, void *CallBackRef,
+		       XEmac_SgHandler FuncPtr)
+{
+	/*
+	 * Asserted IsDmaSg here instead of run-time check because there is really
+	 * no ill-effects of setting these when not configured for scatter-gather.
+	 */
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(FuncPtr != NULL);
+	XASSERT_VOID(XEmac_mIsSgDma(InstancePtr));
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	InstancePtr->SgSendHandler = FuncPtr;
+	InstancePtr->SgSendRef = CallBackRef;
+}
+
+/*****************************************************************************/
+/*
+*
+* Handle an interrupt from the DMA receive channel. DMA interrupts are:
+*
+* - DMA error. DMA encountered a bus error or timeout. This is a fatal error
+*   that requires reset of the channel.  The driver calls the error handler
+*   of the upper layer software with an error code indicating the device should
+*   be reset.
+* - Packet count threshold reached.  For scatter-gather operations, indicates
+*   the threshold for the number of packets not serviced by software has been
+*   reached. The driver behaves as follows:
+*       - Get the value of the packet counter, which tells us how many packets
+*         are ready to be serviced
+*       - For each packet
+*           - For each descriptor, remove it from the scatter-gather list
+*           - Check for the last descriptor in the frame, and if set
+*               - Bump frame statistics
+*               - Decrement the packet counter by one
+*           - Call the scatter-gather receive callback function
+*       Note that there are no receive errors reported in the status word of
+*       the buffer descriptor.  If receive errors occur, the MAC drops the
+*       packet, and we only find out about the errors through various error
+*       count registers.
+* - Packet wait bound reached.  For scatter-gather, indicates the time to wait
+*   for the next packet has expired.  The driver follows the same logic as when
+*   the packet count threshold interrupt is received.
+* - Scatter-gather end acknowledge.  Hardware has reached the end of the
+*   descriptor list.  The driver follows the same logic as when the packet count
+*   threshold interrupt is received. In addition, the driver restarts the DMA
+*   scatter-gather channel in case there are newly inserted descriptors.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Although the function returns void, there are asynchronous errors that can
+* be generated (by calling the ErrorHandler) from this function.  These are:
+* - XST_DMA_SG_LIST_EMPTY indicates we tried to get a buffer descriptor from the
+*   DMA channel, but there was not one ready for software.
+* - XST_DMA_ERROR indicates a DMA bus error or timeout occurred. This is a fatal
+*   error that requires reset.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+HandleDmaRecvIntr(XEmac * InstancePtr)
+{
+	XStatus Result;
+	u32 IntrStatus;
+	u32 NumBds;
+	u32 PacketsLeft;
+	XBufDescriptor *BdHeadPtr;
+	XBufDescriptor *BdPtr;
+
+	/*
+	 * Read the interrupt status
+	 */
+	IntrStatus = XDmaChannel_GetIntrStatus(&InstancePtr->RecvChannel);
+
+	/*
+	 * For packet threshold or wait bound interrupts, process desciptors. Also
+	 * process descriptors on a SG end acknowledgement, which means the end of
+	 * the descriptor list has been reached by the hardware. For receive, this
+	 * is potentially trouble since it means the descriptor list is full,
+	 * unless software can process enough packets quickly enough so the
+	 * hardware has room to put new packets.
+	 */
+	if (IntrStatus & (XDC_IXR_PKT_THRESHOLD_MASK |
+			  XDC_IXR_PKT_WAIT_BOUND_MASK | XDC_IXR_SG_END_MASK)) {
+		/* Get the number of packets that need processing */
+		PacketsLeft =
+		    XDmaChannel_GetPktCount(&InstancePtr->RecvChannel);
+
+		if (PacketsLeft) {
+			/* Get the buffer descriptor at the head of the list */
+			Result =
+			    XDmaChannel_GetDescriptor(&InstancePtr->RecvChannel,
+						      &BdHeadPtr);
+			BdPtr = BdHeadPtr;
+			NumBds = 0;
+
+			/* Loop until all packets have been pulled or an error occurs */
+			while (1) {
+				char *buf_start;
+				int buf_len;
+
+				NumBds++;
+			
+				/* flush buffer descriptor, if we aren't using 
+				   real uncached memory */
+			#if !CONFIG_XILINX_UNCACHED_SHADOW
+				flush_dcache_range((unsigned)BdPtr,
+							(unsigned)(BdPtr+1));
+			#endif
+				/*
+				 * An error getting a buffer descriptor from the list.
+				 * This should not happen, but if it does, report it to
+				 * the error callback and break out of the loop to service
+				 * other interrupts.
+				 */
+				if (Result != XST_SUCCESS) {
+					InstancePtr->ErrorHandler(InstancePtr->
+								  ErrorRef,
+								  Result);
+					break;
+				}
+				/* Bump statistics */
+				InstancePtr->Stats.RecvBytes +=
+				    XBufDescriptor_GetLength(BdPtr);
+
+				/* Have all BDs been read for this packet */
+				if (XBufDescriptor_IsLastStatus(BdPtr)) {
+					/*
+					 * Decrement the packet count register to reflect the fact
+					 * we just processed a packet
+					 */
+					XDmaChannel_DecrementPktCount
+					    (&InstancePtr->RecvChannel);
+
+					/* Bump statistics */
+					InstancePtr->Stats.RecvFrames++;
+
+					/* Test loop exit condition */
+					if (--PacketsLeft == 0) {
+						break;
+					}
+				}
+
+				/* Get the next buffer descriptor in the list */
+				Result =
+				    XDmaChannel_GetDescriptor(&InstancePtr->
+							      RecvChannel,
+							      &BdPtr);
+			}	/* while */
+
+			/*
+			 * Check for error that occurred inside the while loop, and break
+			 * out of the for loop if there was one so other interrupts can
+			 * be serviced.
+			 */
+			if (Result == XST_SUCCESS) {
+				/*
+				 * Make the callback to the upper layers, passing it the first
+				 * descriptor in the first packet and the number of descriptors
+				 * in the list.
+				 */
+				InstancePtr->SgRecvHandler(InstancePtr->
+							   SgRecvRef, BdHeadPtr,
+							   NumBds);
+			}
+		}
+
+		/* if (PacketsLeft) */
+		/*
+		   * If the interrupt was an end-ack, check the descriptor list again to
+		   * see if it is empty. If not, go ahead and restart the scatter-gather
+		   * channel. This is to fix a possible race condition where, on receive,
+		   * the driver attempted to start a scatter-gather channel that was
+		   * already started, which resulted in no action from the XDmaChannel
+		   * component. But, just after the XDmaChannel component saw that the
+		   * hardware was already started, the hardware stopped because it
+		   * reached the end of the list.  In that case, this interrupt is
+		   * generated and we can restart the hardware here.
+		 */
+		if (IntrStatus & XDC_IXR_SG_END_MASK) {
+			/*
+			 * Ignore the return status since we know the list exists and we
+			 * don't care if the list is empty or the channel is already started.
+			 */
+			(void) XDmaChannel_SgStart(&InstancePtr->RecvChannel);
+		}
+	}
+
+	/*
+	 * All interrupts are handled (except the error below) so acknowledge
+	 * (clear) the interrupts by writing the value read above back to the status
+	 * register. The packet count interrupt must be acknowledged after the
+	 * decrement, otherwise it will come right back. We clear the interrupts
+	 * before we handle the error interrupt because the ErrorHandler should
+	 * result in a reset, which clears the interrupt status register. So we
+	 * don't want to toggle the interrupt back on by writing the interrupt
+	 * status register with an old value after a reset.
+	 */
+	XDmaChannel_SetIntrStatus(&InstancePtr->RecvChannel, IntrStatus);
+
+	/*
+	 * Check for DMA errors and call the error callback function if an error
+	 * occurred (DMA bus or timeout error), which should result in a reset of
+	 * the device by the upper layer software.
+	 */
+	if (IntrStatus & XDC_IXR_DMA_ERROR_MASK) {
+		InstancePtr->Stats.DmaErrors++;
+		InstancePtr->ErrorHandler(InstancePtr->ErrorRef, XST_DMA_ERROR);
+	}
+}
+
+/*****************************************************************************/
+/*
+*
+* Handle an interrupt from the DMA send channel. DMA interrupts are:
+*
+* - DMA error. DMA encountered a bus error or timeout. This is a fatal error
+*   that requires reset of the channel.  The driver calls the error handler
+*   of the upper layer software with an error code indicating the device should
+*   be reset.
+* - Packet count threshold reached.  For scatter-gather operations, indicates
+*   the threshold for the number of packets not serviced by software has been
+*   reached. The driver behaves as follows:
+*       - Get the value of the packet counter, which tells us how many packets
+*         are ready to be serviced
+*       - For each packet
+*           - For each descriptor, remove it from the scatter-gather list
+*           - Check for the last descriptor in the frame, and if set
+*               - Bump frame statistics
+*               - Decrement the packet counter by one
+*               - Call the scatter-gather receive callback function
+*       Note that there are no receive errors reported in the status word of
+*       the buffer descriptor.  If receive errors occur, the MAC drops the
+*       packet, and we only find out about the errors through various error
+*       count registers.
+* - Packet wait bound reached.  For scatter-gather, indicates the time to wait
+*   for the next packet has expired.  The driver follows the same logic as when
+*   the packet count threshold interrupt is received.
+* - Scatter-gather end acknowledge.  Hardware has reached the end of the
+*   descriptor list.  The driver follows the same logic as when the packet count
+*   threshold interrupt is received. In addition, the driver restarts the DMA
+*   scatter-gather channel in case there are newly inserted descriptors.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Although the function returns void, there are asynchronous errors
+* that can be generated from this function.  These are:
+* - XST_DMA_SG_LIST_EMPTY indicates we tried to get a buffer descriptor from
+*   the DMA channel, but there was not one ready for software.
+* - XST_DMA_ERROR indicates a DMA bus error or timeout occurred. This is a
+*   fatal error that requires reset.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+HandleDmaSendIntr(XEmac * InstancePtr)
+{
+	XStatus Result;
+	u32 IntrStatus;
+	u32 NumBds;
+	u32 PacketsLeft;
+	u32 XmitStatus;
+	int PacketStart;
+	XBufDescriptor *BdHeadPtr;
+	XBufDescriptor *BdPtr;
+
+	/*
+	 * Read the interrupt status
+	 */
+	IntrStatus = XDmaChannel_GetIntrStatus(&InstancePtr->SendChannel);
+
+	/*
+	 * For packet threshold or wait bound interrupt, process descriptors. Also
+	 * process descriptors on a SG end acknowledgement, which means the end of
+	 * the descriptor list has been reached by the hardware. For transmit,
+	 * this is a normal condition during times of light traffic.  In fact, the
+	 * wait bound interrupt may be masked for transmit since the end-ack would
+	 * always occur before the wait bound expires.
+	 */
+	if (IntrStatus & (XDC_IXR_PKT_THRESHOLD_MASK |
+			  XDC_IXR_PKT_WAIT_BOUND_MASK | XDC_IXR_SG_END_MASK)) {
+		/* Get the number of packets that need processing */
+		PacketsLeft =
+		    XDmaChannel_GetPktCount(&InstancePtr->SendChannel);
+
+		if (PacketsLeft) {
+			/* Get the buffer descriptor at the head of the list */
+			Result =
+			    XDmaChannel_GetDescriptor(&InstancePtr->SendChannel,
+						      &BdHeadPtr);
+			BdPtr = BdHeadPtr;
+			NumBds = 0;
+			PacketStart = 1;
+
+			/* Loop until all packets have been pulled or an error occurs */
+			while (1) {
+				NumBds++;
+
+				/* flush buffer descriptor, if we aren't using 
+				   real uncached memory */
+			#if !CONFIG_XILINX_UNCACHED_SHADOW
+				flush_dcache_range((unsigned)BdPtr,
+						(unsigned)(BdPtr+1));
+			#endif
+
+				/*
+				 * An error getting a buffer descriptor from the list.
+				 * This should not happen, but if it does, report it to
+				 * the error callback and break out of the loop to service
+				 * other interrupts.
+				 */
+				if (Result != XST_SUCCESS) {
+					InstancePtr->ErrorHandler(InstancePtr->
+								  ErrorRef,
+								  Result);
+					break;
+				}
+
+				/* Bump statistics */
+				InstancePtr->Stats.XmitBytes +=
+				    XBufDescriptor_GetLength(BdPtr);
+ 
+				/* If 1st BD in a packet, then check xmit status */
+				if (PacketStart) {
+					XmitStatus =
+					    XBufDescriptor_GetDeviceStatus
+					    (BdPtr);
+					if (XmitStatus &
+					    XEM_TSR_EXCESS_DEFERRAL_MASK) {
+						InstancePtr->Stats.
+						    XmitExcessDeferral++;
+					}
+
+					if (XmitStatus &
+					    XEM_TSR_LATE_COLLISION_MASK) {
+						InstancePtr->Stats.
+						    XmitLateCollisionErrors++;
+					}
+
+					PacketStart = 0;
+				}
+
+				/* Have all BDs been read for this packet */
+				if (XBufDescriptor_IsLastStatus(BdPtr)) {
+					/*
+					 * Decrement the packet count register to reflect the fact
+					 * we just processed a packet
+					 */
+					XDmaChannel_DecrementPktCount
+					    (&InstancePtr->SendChannel);
+
+					/* Bump statistics */
+					InstancePtr->Stats.XmitFrames++;
+
+					/* Test loop exit condition */
+					if (--PacketsLeft == 0) {
+						break;
+					}
+
+					/* Next BD will mark the beginning of a new packet */
+					PacketStart = 1;
+				}
+
+				/* Get the next buffer descriptor in the list */
+				Result =
+				    XDmaChannel_GetDescriptor(&InstancePtr->
+							      SendChannel,
+							      &BdPtr);
+			}	/* while */
+
+			/*
+			 * Check for error that occurred inside the while loop, and break
+			 * out of the for loop if there was one so other interrupts can
+			 * be serviced.
+			 */
+			if (Result == XST_SUCCESS) {
+				/*
+				 * Make the callback to the upper layers, passing it the first
+				 * descriptor in the first packet and the number of descriptors
+				 * in the list.
+				 */
+				InstancePtr->SgSendHandler(InstancePtr->
+							   SgSendRef, BdHeadPtr,
+							   NumBds);
+			}
+		}
+
+		/* if (PacketsLeft) */
+		/*
+		   * If the interrupt was an end-ack, check the descriptor list again to
+		   * see if it is empty. If not, go ahead and restart the scatter-gather
+		   * channel. This is to fix a possible race condition where, on transmit,
+		   * the driver attempted to start a scatter-gather channel that was
+		   * already started, which resulted in no action from the XDmaChannel
+		   * component. But, just after the XDmaChannel component saw that the
+		   * hardware was already started, the hardware stopped because it
+		   * reached the end of the list.  In that case, this interrupt is
+		   * generated and we can restart the hardware here.
+		 */
+		if (IntrStatus & XDC_IXR_SG_END_MASK) {
+			/*
+			 * Ignore the return status since we know the list exists and we
+			 * don't care if the list is empty or the channel is already started.
+			 */
+			(void) XDmaChannel_SgStart(&InstancePtr->SendChannel);
+		}
+	}
+
+	/*
+	 * All interrupts are handled (except the error below) so acknowledge
+	 * (clear) the interrupts by writing the value read above back to the status
+	 * register. The packet count interrupt must be acknowledged after the
+	 * decrement, otherwise it will come right back. We clear the interrupts
+	 * before we handle the error interrupt because the ErrorHandler should
+	 * result in a reset, which clears the interrupt status register. So we
+	 * don't want to toggle the interrupt back on by writing the interrupt
+	 * status register with an old value after a reset.
+	 */
+	XDmaChannel_SetIntrStatus(&InstancePtr->SendChannel, IntrStatus);
+
+	/*
+	 * Check for DMA errors and call the error callback function if an error
+	 * occurred (DMA bus or timeout error), which should result in a reset of
+	 * the device by the upper layer software.
+	 */
+	if (IntrStatus & XDC_IXR_DMA_ERROR_MASK) {
+		InstancePtr->Stats.DmaErrors++;
+		InstancePtr->ErrorHandler(InstancePtr->ErrorRef, XST_DMA_ERROR);
+	}
+}
+
+/*****************************************************************************/
+/*
+*
+* Handle an interrupt from the Ethernet MAC when configured with scatter-gather
+* DMA. The only interrupts handled in this case are errors.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+HandleEmacDmaIntr(XEmac * InstancePtr)
+{
+	u32 IntrStatus;
+
+	/*
+	 * When configured with DMA, the EMAC generates interrupts only when errors
+	 * occur. We clear the interrupts immediately so that any latched status
+	 * interrupt bits will reflect the true status of the device, and so any
+	 * pulsed interrupts (non-status) generated during the Isr will not be lost.
+	 */
+	IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
+	XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress, IntrStatus);
+
+	/*
+	 * Check the MAC for errors
+	 */
+	XEmac_CheckEmacError(InstancePtr, IntrStatus);
+}
diff -urN linux-2.4.29/drivers/net/xilinx_enet/xemac_intr_fifo.c linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac_intr_fifo.c
--- linux-2.4.29/drivers/net/xilinx_enet/xemac_intr_fifo.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac_intr_fifo.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,685 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xemac_intr_fifo.c
+*
+* Contains functions related to interrupt mode using direct FIFO I/O or simple
+* DMA. The driver uses simple DMA if the device is configured with DMA,
+* otherwise it uses direct FIFO access.
+*
+* The interrupt handler, XEmac_IntrHandlerFifo(), must be connected by the user
+* to the interrupt controller.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  07/31/01 First release
+* 1.00b rpm  02/20/02 Repartitioned files and functions
+* 1.00c rpm  12/05/02 New version includes support for simple DMA
+* 1.00c rpm  04/01/03 Added check in FifoSend for room in the data FIFO
+*                     before starting a simple DMA transfer.
+* 1.00d rpm  09/26/03 New version includes support PLB Ethernet and v2.00a of
+*                     the packet fifo driver.
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xemac_i.h"
+#include "xio.h"
+#include "xipif_v1_23_b.h"	/* Uses v1.23b of the IPIF */
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Variable Definitions *****************************/
+
+/************************** Function Prototypes ******************************/
+
+static void HandleEmacFifoIntr(XEmac * InstancePtr);
+
+/*****************************************************************************/
+/**
+*
+* Send an Ethernet frame using direct FIFO I/O or simple DMA with interrupts.
+* The caller provides a contiguous-memory buffer and its length. The buffer
+* must be 32-bit aligned. If using simple DMA and the PLB 10/100 Ethernet core,
+* the buffer must be 64-bit aligned. The callback function set by using
+* SetFifoSendHandler is invoked when the transmission is complete.
+*
+* It is assumed that the upper layer software supplies a correctly formatted
+* Ethernet frame, including the destination and source addresses, the
+* type/length field, and the data field.
+*
+* If the device is configured with DMA, simple DMA will be used to transfer
+* the buffer from memory to the Emac. This means that this buffer should not
+* be cached.  See the comment section "Simple DMA" in xemac.h for more
+* information.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param BufPtr is a pointer to a aligned buffer containing the Ethernet
+*        frame to be sent.
+* @param ByteCount is the size of the Ethernet frame.
+*
+* @return
+*
+* - XST_SUCCESS if the frame was successfully sent. An interrupt is generated
+*   when the EMAC transmits the frame and the driver calls the callback set
+*   with XEmac_SetFifoSendHandler()
+* - XST_DEVICE_IS_STOPPED  if the device has not yet been started
+* - XST_NOT_INTERRUPT if the device is not in interrupt mode
+* - XST_FIFO_NO_ROOM if there is no room in the FIFO for this frame
+* - XST_DEVICE_BUSY if configured for simple DMA and the DMA engine is busy
+* - XST_DMA_ERROR if an error occurred during the DMA transfer (simple DMA).
+*   The user should treat this as a fatal error that requires a reset of the
+*   EMAC device.
+*
+* @note
+*
+* This function is not thread-safe. The user must provide mutually exclusive
+* access to this function if there are to be multiple threads that can call it.
+*
+* @internal
+*
+* The Ethernet MAC uses FIFOs behind its length and status registers. For this
+* reason, it is important to keep the length, status, and data FIFOs in sync
+* when reading or writing to them.
+*
+******************************************************************************/
+XStatus
+XEmac_FifoSend(XEmac * InstancePtr, u8 * BufPtr, u32 ByteCount)
+{
+	XStatus Result;
+	volatile u32 StatusReg;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufPtr != NULL);
+	XASSERT_NONVOID(ByteCount > XEM_HDR_SIZE);	/* send at least 1 byte */
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/*
+	 * Be sure the device is configured for interrupt mode and it is started
+	 */
+	if (InstancePtr->IsPolled) {
+		return XST_NOT_INTERRUPT;
+	}
+
+	if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
+		return XST_DEVICE_IS_STOPPED;
+	}
+
+	/*
+	 * Before writing to the data FIFO, make sure the length FIFO is not
+	 * full.  The data FIFO might not be full yet even though the length FIFO
+	 * is. This avoids an overrun condition on the length FIFO and keeps the
+	 * FIFOs in sync.
+	 */
+	StatusReg = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
+	if (StatusReg & XEM_EIR_XMIT_LFIFO_FULL_MASK) {
+		return XST_FIFO_NO_ROOM;
+	}
+
+	/*
+	 * Send either by directly writing to the FIFOs or using the DMA engine
+	 */
+	if (!XEmac_mIsDma(InstancePtr)) {
+		/*
+		 * This is a non-blocking write. The packet FIFO returns an error if there
+		 * is not enough room in the FIFO for this frame.
+		 */
+		Result =
+		    XPacketFifoV200a_Write(&InstancePtr->SendFifo, BufPtr,
+					   ByteCount);
+		if (Result != XST_SUCCESS) {
+			return Result;
+		}
+	} else {
+		u32 Vacancy;
+
+		/*
+		 * Need to make sure there is room in the data FIFO for the packet
+		 * before trying to DMA into it. Get the vacancy count (in words)
+		 * and make sure the packet will fit.
+		 */
+		Vacancy = XPF_V200A_GET_COUNT(&InstancePtr->SendFifo);
+		if ((Vacancy * sizeof (u32)) < ByteCount) {
+			return XST_FIFO_NO_ROOM;
+		}
+
+		/*
+		 * Check the DMA engine to make sure it is not already busy
+		 */
+		if (XDmaChannel_GetStatus(&InstancePtr->SendChannel) &
+		    XDC_DMASR_BUSY_MASK) {
+			return XST_DEVICE_BUSY;
+		}
+
+		/*
+		 * Set the DMA control register up properly
+		 */
+		XDmaChannel_SetControl(&InstancePtr->SendChannel,
+				       XDC_DMACR_SOURCE_INCR_MASK |
+				       XDC_DMACR_DEST_LOCAL_MASK |
+				       XDC_DMACR_SG_DISABLE_MASK);
+
+		/*
+		 * Now transfer the data from the buffer to the FIFO
+		 */
+		XDmaChannel_Transfer(&InstancePtr->SendChannel, (u32 *) BufPtr,
+				     (u32 *) (InstancePtr->BaseAddress +
+					      XEM_PFIFO_TXDATA_OFFSET),
+				     ByteCount);
+
+		/*
+		 * Poll here waiting for DMA to be not busy. We think this will
+		 * typically be a single read since DMA should be ahead of the SW.
+		 */
+		do {
+			StatusReg =
+			    XDmaChannel_GetStatus(&InstancePtr->SendChannel);
+		}
+		while (StatusReg & XDC_DMASR_BUSY_MASK);
+
+		/* Return an error if there was a problem with DMA */
+		if ((StatusReg & XDC_DMASR_BUS_ERROR_MASK) ||
+		    (StatusReg & XDC_DMASR_BUS_TIMEOUT_MASK)) {
+			InstancePtr->Stats.DmaErrors++;
+			return XST_DMA_ERROR;
+		}
+	}
+
+	/*
+	 * Set the MAC's transmit packet length register to tell it to transmit
+	 */
+	XIo_Out32(InstancePtr->BaseAddress + XEM_TPLR_OFFSET, ByteCount);
+
+	/*
+	 * Bump stats here instead of the Isr since we know the byte count
+	 * here but would have to save it in the instance in order to know the
+	 * byte count at interrupt time.
+	 */
+	InstancePtr->Stats.XmitFrames++;
+	InstancePtr->Stats.XmitBytes += ByteCount;
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Receive an Ethernet frame into the buffer passed as an argument. This
+* function is called in response to the callback function for received frames
+* being called by the driver. The callback function is set up using
+* SetFifoRecvHandler, and is invoked when the driver receives an interrupt
+* indicating a received frame. The driver expects the upper layer software to
+* call this function, FifoRecv, to receive the frame. The buffer supplied
+* should be large enough to hold a maximum-size Ethernet frame.
+*
+* The buffer into which the frame will be received must be 32-bit aligned. If
+* using simple DMA and the PLB 10/100 Ethernet core, the buffer must be 64-bit
+* aligned.
+*
+* If the device is configured with DMA, simple DMA will be used to transfer
+* the buffer from the Emac to memory. This means that this buffer should not
+* be cached. See the comment section "Simple DMA" in xemac.h for more
+* information.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param BufPtr is a pointer to a aligned buffer into which the received
+*        Ethernet frame will be copied.
+* @param ByteCountPtr is both an input and an output parameter. It is a pointer
+*        to a 32-bit word that contains the size of the buffer on entry into
+*        the function and the size the received frame on return from the
+*        function.
+*
+* @return
+*
+* - XST_SUCCESS if the frame was sent successfully
+* - XST_DEVICE_IS_STOPPED if the device has not yet been started
+* - XST_NOT_INTERRUPT if the device is not in interrupt mode
+* - XST_NO_DATA if there is no frame to be received from the FIFO
+* - XST_BUFFER_TOO_SMALL if the buffer to receive the frame is too small for
+*   the frame waiting in the FIFO.
+* - XST_DEVICE_BUSY if configured for simple DMA and the DMA engine is busy
+* - XST_DMA_ERROR if an error occurred during the DMA transfer (simple DMA).
+*   The user should treat this as a fatal error that requires a reset of the
+*   EMAC device.
+*
+* @note
+*
+* The input buffer must be big enough to hold the largest Ethernet frame.
+*
+* @internal
+*
+* The Ethernet MAC uses FIFOs behind its length and status registers. For this
+* reason, it is important to keep the length, status, and data FIFOs in sync
+* when reading or writing to them.
+*
+******************************************************************************/
+XStatus
+XEmac_FifoRecv(XEmac * InstancePtr, u8 * BufPtr, u32 * ByteCountPtr)
+{
+	XStatus Result;
+	u32 PktLength;
+	u32 StatusReg;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufPtr != NULL);
+	XASSERT_NONVOID(ByteCountPtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/*
+	 * Be sure the device is not configured for polled mode and it is started
+	 */
+	if (InstancePtr->IsPolled) {
+		return XST_NOT_INTERRUPT;
+	}
+
+	if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
+		return XST_DEVICE_IS_STOPPED;
+	}
+
+	/*
+	 * Make sure the buffer is big enough to hold the maximum frame size.
+	 * We need to do this because as soon as we read the MAC's packet length
+	 * register, which is actually a FIFO, we remove that length from the
+	 * FIFO.  We do not want to read the length FIFO without also reading the
+	 * data FIFO since this would get the FIFOs out of sync.  So we have to
+	 * make this restriction.
+	 */
+	if (*ByteCountPtr < XEM_MAX_FRAME_SIZE) {
+		return XST_BUFFER_TOO_SMALL;
+	}
+
+	/*
+	 * Before reading from the length FIFO, make sure the length FIFO is not
+	 * empty. We could cause an underrun error if we try to read from an
+	 * empty FIFO.
+	 */
+	StatusReg = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
+	if (StatusReg & XEM_EIR_RECV_LFIFO_EMPTY_MASK) {
+		/*
+		 * Clear the empty status so the next time through the current status
+		 * of the hardware is reflected (we have to do this because the status
+		 * is level in the device but latched in the interrupt status register).
+		 */
+		XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
+				      XEM_EIR_RECV_LFIFO_EMPTY_MASK);
+		return XST_NO_DATA;
+	}
+
+	/*
+	 * If configured with DMA, make sure the DMA engine is not busy
+	 */
+	if (XEmac_mIsDma(InstancePtr)) {
+		if (XDmaChannel_GetStatus(&InstancePtr->RecvChannel) &
+		    XDC_DMASR_BUSY_MASK) {
+			return XST_DEVICE_BUSY;
+		}
+	}
+
+	/*
+	 * Determine, from the MAC, the length of the next packet available
+	 * in the data FIFO (there should be a non-zero length here)
+	 */
+	PktLength = XIo_In32(InstancePtr->BaseAddress + XEM_RPLR_OFFSET);
+	if (PktLength == 0) {
+		return XST_NO_DATA;
+	}
+
+	/*
+	 * We assume that the MAC never has a length bigger than the largest
+	 * Ethernet frame, so no need to make another check here.
+	 *
+	 * Receive either by directly reading the FIFO or using the DMA engine
+	 */
+	if (!XEmac_mIsDma(InstancePtr)) {
+		/*
+		 * This is a non-blocking read. The FIFO returns an error if there is
+		 * not at least the requested amount of data in the FIFO.
+		 */
+		Result =
+		    XPacketFifoV200a_Read(&InstancePtr->RecvFifo, BufPtr,
+					  PktLength);
+		if (Result != XST_SUCCESS) {
+			return Result;
+		}
+	} else {
+		/*
+		 * Call on DMA to transfer from the FIFO to the buffer. First set up
+		 * the DMA control register.
+		 */
+		XDmaChannel_SetControl(&InstancePtr->RecvChannel,
+				       XDC_DMACR_DEST_INCR_MASK |
+				       XDC_DMACR_SOURCE_LOCAL_MASK |
+				       XDC_DMACR_SG_DISABLE_MASK);
+
+		/*
+		 * Now transfer the data
+		 */
+		XDmaChannel_Transfer(&InstancePtr->RecvChannel,
+				     (u32 *) (InstancePtr->BaseAddress +
+					      XEM_PFIFO_RXDATA_OFFSET),
+				     (u32 *) BufPtr, PktLength);
+
+		/*
+		 * Poll here waiting for DMA to be not busy. We think this will
+		 * typically be a single read since DMA should be ahead of the SW.
+		 */
+		do {
+			StatusReg =
+			    XDmaChannel_GetStatus(&InstancePtr->RecvChannel);
+		}
+		while (StatusReg & XDC_DMASR_BUSY_MASK);
+
+		/* Return an error if there was a problem with DMA */
+		if ((StatusReg & XDC_DMASR_BUS_ERROR_MASK) ||
+		    (StatusReg & XDC_DMASR_BUS_TIMEOUT_MASK)) {
+			InstancePtr->Stats.DmaErrors++;
+			return XST_DMA_ERROR;
+		}
+	}
+
+	*ByteCountPtr = PktLength;
+
+	InstancePtr->Stats.RecvFrames++;
+	InstancePtr->Stats.RecvBytes += PktLength;
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* The interrupt handler for the Ethernet driver when configured for direct FIFO
+* communication or simple DMA.
+*
+* Get the interrupt status from the IpIf to determine the source of the
+* interrupt.  The source can be: MAC, Recv Packet FIFO, or Send Packet FIFO.
+* The packet FIFOs only interrupt during "deadlock" conditions.  All other
+* FIFO-related interrupts are generated by the MAC.
+*
+* @param InstancePtr is a pointer to the XEmac instance that just interrupted.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XEmac_IntrHandlerFifo(void *InstancePtr)
+{
+	u32 IntrStatus;
+	XEmac *EmacPtr = (XEmac *) InstancePtr;
+
+	EmacPtr->Stats.TotalIntrs++;
+
+	/*
+	 * Get the interrupt status from the IPIF. There is no clearing of
+	 * interrupts in the IPIF. Interrupts must be cleared at the source.
+	 */
+	IntrStatus = XIIF_V123B_READ_DIPR(EmacPtr->BaseAddress);
+
+	if (IntrStatus & XEM_IPIF_EMAC_MASK) {	/* MAC interrupt */
+		EmacPtr->Stats.EmacInterrupts++;
+		HandleEmacFifoIntr(EmacPtr);
+	}
+
+	if (IntrStatus & XEM_IPIF_RECV_FIFO_MASK) {	/* Receive FIFO interrupt */
+		EmacPtr->Stats.RecvInterrupts++;
+		XEmac_CheckFifoRecvError(EmacPtr);
+	}
+
+	if (IntrStatus & XEM_IPIF_SEND_FIFO_MASK) {	/* Send FIFO interrupt */
+		EmacPtr->Stats.XmitInterrupts++;
+		XEmac_CheckFifoSendError(EmacPtr);
+	}
+
+	if (IntrStatus & XIIF_V123B_ERROR_MASK) {
+		/*
+		 * An error occurred internal to the IPIF. This is more of a debug and
+		 * integration issue rather than a production error. Don't do anything
+		 * other than clear it, which provides a spot for software to trap
+		 * on the interrupt and begin debugging.
+		 */
+		XIIF_V123B_WRITE_DISR(EmacPtr->BaseAddress,
+				      XIIF_V123B_ERROR_MASK);
+	}
+}
+
+/*****************************************************************************/
+/**
+*
+* Set the callback function for handling confirmation of transmitted frames when
+* configured for direct memory-mapped I/O using FIFOs. The upper layer software
+* should call this function during initialization. The callback is called by the
+* driver once per frame sent. The callback is responsible for freeing the
+* transmitted buffer if necessary.
+*
+* The callback is invoked by the driver within interrupt context, so it needs
+* to do its job quickly. If there are potentially slow operations within the
+* callback, these should be done at task-level.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param CallBackRef is a reference pointer to be passed back to the adapter in
+*        the callback. This helps the adapter correlate the callback to a
+*        particular driver.
+* @param FuncPtr is the pointer to the callback function.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XEmac_SetFifoRecvHandler(XEmac * InstancePtr, void *CallBackRef,
+			 XEmac_FifoHandler FuncPtr)
+{
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(FuncPtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	InstancePtr->FifoRecvHandler = FuncPtr;
+	InstancePtr->FifoRecvRef = CallBackRef;
+}
+
+/*****************************************************************************/
+/**
+*
+* Set the callback function for handling received frames when configured for
+* direct memory-mapped I/O using FIFOs. The upper layer software should call
+* this function during initialization. The callback is called once per frame
+* received. During the callback, the upper layer software should call FifoRecv
+* to retrieve the received frame.
+*
+* The callback is invoked by the driver within interrupt context, so it needs
+* to do its job quickly. Sending the received frame up the protocol stack
+* should be done at task-level. If there are other potentially slow operations
+* within the callback, these too should be done at task-level.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param CallBackRef is a reference pointer to be passed back to the adapter in
+*        the callback. This helps the adapter correlate the callback to a
+*        particular driver.
+* @param FuncPtr is the pointer to the callback function.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XEmac_SetFifoSendHandler(XEmac * InstancePtr, void *CallBackRef,
+			 XEmac_FifoHandler FuncPtr)
+{
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(FuncPtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	InstancePtr->FifoSendHandler = FuncPtr;
+	InstancePtr->FifoSendRef = CallBackRef;
+}
+
+/******************************************************************************
+*
+* Handle an interrupt from the Ethernet MAC when configured for direct FIFO
+* communication.  The interrupts handled are:
+* - Transmit done (transmit status FIFO is non-empty). Used to determine when
+*   a transmission has been completed.
+* - Receive done (receive length FIFO is non-empty). Used to determine when a
+*   valid frame has been received.
+*
+* In addition, the interrupt status is checked for errors.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+HandleEmacFifoIntr(XEmac * InstancePtr)
+{
+	u32 IntrStatus;
+
+	/*
+	 * The EMAC generates interrupts for errors and generates the transmit
+	 * and receive done interrupts for data. We clear the interrupts
+	 * immediately so that any latched status interrupt bits will reflect the
+	 * true status of the device, and so any pulsed interrupts (non-status)
+	 * generated during the Isr will not be lost.
+	 */
+	IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
+	XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress, IntrStatus);
+
+	if (IntrStatus & XEM_EIR_RECV_DONE_MASK) {
+		/*
+		 * Configured for direct memory-mapped I/O using FIFO with interrupts.
+		 * This interrupt means the RPLR is non-empty, indicating a frame has
+		 * arrived.
+		 */
+		InstancePtr->Stats.RecvInterrupts++;
+
+		InstancePtr->FifoRecvHandler(InstancePtr->FifoRecvRef);
+
+		/*
+		 * The upper layer has removed as many frames as it wants to, so we
+		 * need to clear the RECV_DONE bit before leaving the ISR so that it
+		 * reflects the current state of the hardware (because it's a level
+		 * interrupt that is latched in the IPIF interrupt status register).
+		 * Note that if we've reached this point the bit is guaranteed to be
+		 * set because it was cleared at the top of this ISR before any frames
+		 * were serviced, so the bit was set again immediately by hardware
+		 * because the RPLR was not yet emptied by software.
+		 */
+		XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
+				      XEM_EIR_RECV_DONE_MASK);
+	}
+
+	/*
+	 * If configured for direct memory-mapped I/O using FIFO, the xmit status
+	 * FIFO must be read and the callback invoked regardless of success or not.
+	 */
+	if (IntrStatus & XEM_EIR_XMIT_DONE_MASK) {
+		u32 XmitStatus;
+
+		InstancePtr->Stats.XmitInterrupts++;
+
+		XmitStatus =
+		    XIo_In32(InstancePtr->BaseAddress + XEM_TSR_OFFSET);
+
+		/*
+		 * Collision errors are stored in the transmit status register
+		 * instead of the interrupt status register
+		 */
+		if (XmitStatus & XEM_TSR_EXCESS_DEFERRAL_MASK) {
+			InstancePtr->Stats.XmitExcessDeferral++;
+		}
+
+		if (XmitStatus & XEM_TSR_LATE_COLLISION_MASK) {
+			InstancePtr->Stats.XmitLateCollisionErrors++;
+		}
+
+		InstancePtr->FifoSendHandler(InstancePtr->FifoSendRef);
+
+		/*
+		 * Only one status is retrieved per interrupt. We need to clear the
+		 * XMIT_DONE bit before leaving the ISR so that it reflects the current
+		 * state of the hardware (because it's a level interrupt that is latched
+		 * in the IPIF interrupt status register). Note that if we've reached
+		 * this point the bit is guaranteed to be set because it was cleared at
+		 * the top of this ISR before any statuses were serviced, so the bit was
+		 * set again immediately by hardware because the TSR was not yet emptied
+		 * by software.
+		 */
+		XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
+				      XEM_EIR_XMIT_DONE_MASK);
+	}
+
+	/*
+	 * Check the MAC for errors
+	 */
+	XEmac_CheckEmacError(InstancePtr, IntrStatus);
+}
diff -urN linux-2.4.29/drivers/net/xilinx_enet/xemac_l.h linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac_l.h
--- linux-2.4.29/drivers/net/xilinx_enet/xemac_l.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac_l.h	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,470 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xemac_l.h
+*
+* This header file contains identifiers and low-level driver functions (or
+* macros) that can be used to access the device.  High-level driver functions
+* are defined in xemac.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00b rpm  04/26/02 First release
+* 1.00b rmm  09/23/02 Added XEmac_mPhyReset macro
+* 1.00c rpm  12/05/02 New version includes support for simple DMA
+* 1.00d rpm  09/26/03 New version includes support PLB Ethernet and v2.00a of
+*                     the packet fifo driver.
+* 1.00e rmm  04/06/04 Relocated IFG and MGT max values from 'c' files to this
+*                     one.
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XEMAC_L_H		/* prevent circular inclusions */
+#define XEMAC_L_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+
+/************************** Constant Definitions *****************************/
+
+/* Offset of the MAC registers from the IPIF base address */
+#define XEM_REG_OFFSET     0x1100UL
+
+/*
+ * Register offsets for the Ethernet MAC. Each register is 32 bits.
+ */
+#define XEM_EMIR_OFFSET   (XEM_REG_OFFSET + 0x0)	/* EMAC Module ID */
+#define XEM_ECR_OFFSET    (XEM_REG_OFFSET + 0x4)	/* MAC Control */
+#define XEM_IFGP_OFFSET   (XEM_REG_OFFSET + 0x8)	/* Interframe Gap */
+#define XEM_SAH_OFFSET    (XEM_REG_OFFSET + 0xC)	/* Station addr, high */
+#define XEM_SAL_OFFSET    (XEM_REG_OFFSET + 0x10)	/* Station addr, low */
+#define XEM_MGTCR_OFFSET  (XEM_REG_OFFSET + 0x14)	/* MII mgmt control */
+#define XEM_MGTDR_OFFSET  (XEM_REG_OFFSET + 0x18)	/* MII mgmt data */
+#define XEM_RPLR_OFFSET   (XEM_REG_OFFSET + 0x1C)	/* Rx packet length */
+#define XEM_TPLR_OFFSET   (XEM_REG_OFFSET + 0x20)	/* Tx packet length */
+#define XEM_TSR_OFFSET    (XEM_REG_OFFSET + 0x24)	/* Tx status */
+#define XEM_RMFC_OFFSET   (XEM_REG_OFFSET + 0x28)	/* Rx missed frames */
+#define XEM_RCC_OFFSET    (XEM_REG_OFFSET + 0x2C)	/* Rx collisions */
+#define XEM_RFCSEC_OFFSET (XEM_REG_OFFSET + 0x30)	/* Rx FCS errors */
+#define XEM_RAEC_OFFSET   (XEM_REG_OFFSET + 0x34)	/* Rx alignment errors */
+#define XEM_TEDC_OFFSET   (XEM_REG_OFFSET + 0x38)	/* Transmit excess
+							 * deferral cnt */
+
+/*
+ * Register offsets for the IPIF components
+ */
+#define XEM_ISR_OFFSET           0x20UL	/* Interrupt status */
+
+#define XEM_DMA_OFFSET           0x2300UL
+#define XEM_DMA_SEND_OFFSET      (XEM_DMA_OFFSET + 0x0)	/* DMA send channel */
+#define XEM_DMA_RECV_OFFSET      (XEM_DMA_OFFSET + 0x40)	/* DMA recv channel */
+
+#define XEM_PFIFO_OFFSET         0x2000UL
+#define XEM_PFIFO_TXREG_OFFSET   (XEM_PFIFO_OFFSET + 0x0)	/* Tx registers */
+#define XEM_PFIFO_RXREG_OFFSET   (XEM_PFIFO_OFFSET + 0x10)	/* Rx registers */
+#define XEM_PFIFO_TXDATA_OFFSET  (XEM_PFIFO_OFFSET + 0x100)	/* Tx keyhole */
+#define XEM_PFIFO_RXDATA_OFFSET  (XEM_PFIFO_OFFSET + 0x200)	/* Rx keyhole */
+
+/*
+ * EMAC Module Identification Register (EMIR)
+ */
+#define XEM_EMIR_VERSION_MASK    0xFFFF0000UL	/* Device version */
+#define XEM_EMIR_TYPE_MASK       0x0000FF00UL	/* Device type */
+
+/*
+ * EMAC Control Register (ECR)
+ */
+#define XEM_ECR_FULL_DUPLEX_MASK         0x80000000UL	/* Full duplex mode */
+#define XEM_ECR_XMIT_RESET_MASK          0x40000000UL	/* Reset transmitter */
+#define XEM_ECR_XMIT_ENABLE_MASK         0x20000000UL	/* Enable transmitter */
+#define XEM_ECR_RECV_RESET_MASK          0x10000000UL	/* Reset receiver */
+#define XEM_ECR_RECV_ENABLE_MASK         0x08000000UL	/* Enable receiver */
+#define XEM_ECR_PHY_ENABLE_MASK          0x04000000UL	/* Enable PHY */
+#define XEM_ECR_XMIT_PAD_ENABLE_MASK     0x02000000UL	/* Enable xmit pad insert */
+#define XEM_ECR_XMIT_FCS_ENABLE_MASK     0x01000000UL	/* Enable xmit FCS insert */
+#define XEM_ECR_XMIT_ADDR_INSERT_MASK    0x00800000UL	/* Enable xmit source addr
+							 * insertion */
+#define XEM_ECR_XMIT_ERROR_INSERT_MASK   0x00400000UL	/* Insert xmit error */
+#define XEM_ECR_XMIT_ADDR_OVWRT_MASK     0x00200000UL	/* Enable xmit source addr
+							 * overwrite */
+#define XEM_ECR_LOOPBACK_MASK            0x00100000UL	/* Enable internal
+							 * loopback */
+#define XEM_ECR_RECV_STRIP_ENABLE_MASK   0x00080000UL	/* Enable recv pad/fcs strip */
+#define XEM_ECR_UNICAST_ENABLE_MASK      0x00020000UL	/* Enable unicast addr */
+#define XEM_ECR_MULTI_ENABLE_MASK        0x00010000UL	/* Enable multicast addr */
+#define XEM_ECR_BROAD_ENABLE_MASK        0x00008000UL	/* Enable broadcast addr */
+#define XEM_ECR_PROMISC_ENABLE_MASK      0x00004000UL	/* Enable promiscuous mode */
+#define XEM_ECR_RECV_ALL_MASK            0x00002000UL	/* Receive all frames */
+#define XEM_ECR_RESERVED2_MASK           0x00001000UL	/* Reserved */
+#define XEM_ECR_MULTI_HASH_ENABLE_MASK   0x00000800UL	/* Enable multicast hash */
+#define XEM_ECR_PAUSE_FRAME_MASK         0x00000400UL	/* Interpret pause frames */
+#define XEM_ECR_CLEAR_HASH_MASK          0x00000200UL	/* Clear hash table */
+#define XEM_ECR_ADD_HASH_ADDR_MASK       0x00000100UL	/* Add hash table address */
+
+/*
+ * Interframe Gap Register (IFGR)
+ */
+#define XEM_IFGP_PART1_MASK         0xF8000000UL	/* Interframe Gap Part1 */
+#define XEM_IFGP_PART1_SHIFT        27
+#define XEM_IFGP_PART2_MASK         0x07C00000UL	/* Interframe Gap Part2 */
+#define XEM_IFGP_PART2_SHIFT        22
+#define XEM_IFGP_PART1_MAX          31	/* Max IFG 1 value */
+#define XEM_IFGP_PART2_MAX          31	/* Max IFG 2 value */
+
+/*
+ * Station Address High Register (SAH)
+ */
+#define XEM_SAH_ADDR_MASK           0x0000FFFFUL	/* Station address high bytes */
+
+/*
+ * Station Address Low Register (SAL)
+ */
+#define XEM_SAL_ADDR_MASK           0xFFFFFFFFUL	/* Station address low bytes */
+
+/*
+ * MII Management Control Register (MGTCR)
+ */
+#define XEM_MGTCR_START_MASK        0x80000000UL	/* Start/Busy */
+#define XEM_MGTCR_RW_NOT_MASK       0x40000000UL	/* Read/Write Not (direction) */
+#define XEM_MGTCR_PHY_ADDR_MASK     0x3E000000UL	/* PHY address */
+#define XEM_MGTCR_PHY_ADDR_SHIFT    25	/* PHY address shift */
+#define XEM_MGTCR_REG_ADDR_MASK     0x01F00000UL	/* Register address */
+#define XEM_MGTCR_REG_ADDR_SHIFT    20	/* Register addr shift */
+#define XEM_MGTCR_MII_ENABLE_MASK   0x00080000UL	/* Enable MII from EMAC */
+#define XEM_MGTCR_RD_ERROR_MASK     0x00040000UL	/* MII mgmt read error */
+#define XEM_MGTCR_MAX_PHY_ADDR      31	/* Maximum PHY address */
+#define XEM_MGTCR_MAX_PHY_REG       31	/* Maximum PHY register number */
+
+/*
+ * MII Management Data Register (MGTDR)
+ */
+#define XEM_MGTDR_DATA_MASK         0x0000FFFFUL	/* MII data */
+
+/*
+ * Receive Packet Length Register (RPLR)
+ */
+#define XEM_RPLR_LENGTH_MASK        0x0000FFFFUL	/* Receive packet length */
+
+/*
+ * Transmit Packet Length Register (TPLR)
+ */
+#define XEM_TPLR_LENGTH_MASK        0x0000FFFFUL	/* Transmit packet length */
+
+/*
+ * Transmit Status Register (TSR)
+ */
+#define XEM_TSR_EXCESS_DEFERRAL_MASK 0x80000000UL	/* Transmit excess deferral */
+#define XEM_TSR_FIFO_UNDERRUN_MASK   0x40000000UL	/* Packet FIFO underrun */
+#define XEM_TSR_ATTEMPTS_MASK        0x3E000000UL	/* Transmission attempts */
+#define XEM_TSR_LATE_COLLISION_MASK  0x01000000UL	/* Transmit late collision */
+
+/*
+ * Receive Missed Frame Count (RMFC)
+ */
+#define XEM_RMFC_DATA_MASK          0x0000FFFFUL
+
+/*
+ * Receive Collision Count (RCC)
+ */
+#define XEM_RCC_DATA_MASK           0x0000FFFFUL
+
+/*
+ * Receive FCS Error Count (RFCSEC)
+ */
+#define XEM_RFCSEC_DATA_MASK        0x0000FFFFUL
+
+/*
+ * Receive Alignment Error Count (RALN)
+ */
+#define XEM_RAEC_DATA_MASK          0x0000FFFFUL
+
+/*
+ * Transmit Excess Deferral Count (TEDC)
+ */
+#define XEM_TEDC_DATA_MASK          0x0000FFFFUL
+
+/*
+ * EMAC Interrupt Registers (Status and Enable) masks. These registers are
+ * part of the IPIF IP Interrupt registers
+ */
+#define XEM_EIR_XMIT_DONE_MASK         0x00000001UL	/* Xmit complete */
+#define XEM_EIR_RECV_DONE_MASK         0x00000002UL	/* Recv complete */
+#define XEM_EIR_XMIT_ERROR_MASK        0x00000004UL	/* Xmit error */
+#define XEM_EIR_RECV_ERROR_MASK        0x00000008UL	/* Recv error */
+#define XEM_EIR_XMIT_SFIFO_EMPTY_MASK  0x00000010UL	/* Xmit status fifo empty */
+#define XEM_EIR_RECV_LFIFO_EMPTY_MASK  0x00000020UL	/* Recv length fifo empty */
+#define XEM_EIR_XMIT_LFIFO_FULL_MASK   0x00000040UL	/* Xmit length fifo full */
+#define XEM_EIR_RECV_LFIFO_OVER_MASK   0x00000080UL	/* Recv length fifo
+							 * overrun */
+#define XEM_EIR_RECV_LFIFO_UNDER_MASK  0x00000100UL	/* Recv length fifo
+							 * underrun */
+#define XEM_EIR_XMIT_SFIFO_OVER_MASK   0x00000200UL	/* Xmit status fifo
+							 * overrun */
+#define XEM_EIR_XMIT_SFIFO_UNDER_MASK  0x00000400UL	/* Transmit status fifo
+							 * underrun */
+#define XEM_EIR_XMIT_LFIFO_OVER_MASK   0x00000800UL	/* Transmit length fifo
+							 * overrun */
+#define XEM_EIR_XMIT_LFIFO_UNDER_MASK  0x00001000UL	/* Transmit length fifo
+							 * underrun */
+#define XEM_EIR_XMIT_PAUSE_MASK        0x00002000UL	/* Transmit pause pkt
+							 * received */
+#define XEM_EIR_RECV_DFIFO_OVER_MASK   0x00004000UL	/* Receive data fifo
+							 * overrun */
+#define XEM_EIR_RECV_MISSED_FRAME_MASK 0x00008000UL	/* Receive missed frame
+							 * error */
+#define XEM_EIR_RECV_COLLISION_MASK    0x00010000UL	/* Receive collision
+							 * error */
+#define XEM_EIR_RECV_FCS_ERROR_MASK    0x00020000UL	/* Receive FCS error */
+#define XEM_EIR_RECV_LEN_ERROR_MASK    0x00040000UL	/* Receive length field
+							 * error */
+#define XEM_EIR_RECV_SHORT_ERROR_MASK  0x00080000UL	/* Receive short frame
+							 * error */
+#define XEM_EIR_RECV_LONG_ERROR_MASK   0x00100000UL	/* Receive long frame
+							 * error */
+#define XEM_EIR_RECV_ALIGN_ERROR_MASK  0x00200000UL	/* Receive alignment
+							 * error */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************
+*
+* Low-level driver macros and functions. The list below provides signatures
+* to help the user use the macros.
+*
+* u32 XEmac_mReadReg(u32 BaseAddress, int RegOffset)
+* void XEmac_mWriteReg(u32 BaseAddress, int RegOffset, u32 Mask)
+*
+* void XEmac_mSetControlReg(u32 BaseAddress, u32 Mask)
+* void XEmac_mSetMacAddress(u32 BaseAddress, u8 *AddressPtr)
+*
+* void XEmac_mEnable(u32 BaseAddress)
+* void XEmac_mDisable(u32 BaseAddress)
+*
+* u32 XEmac_mIsTxDone(u32 BaseAddress)
+* u32 XEmac_mIsRxEmpty(u32 BaseAddress)
+*
+* void XEmac_SendFrame(u32 BaseAddress, u8 *FramePtr, int Size)
+* int XEmac_RecvFrame(u32 BaseAddress, u8 *FramePtr)
+*
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*
+* Read the given register.
+*
+* @param    BaseAddress is the base address of the device
+* @param    RegOffset is the register offset to be read
+*
+* @return   The 32-bit value of the register
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XEmac_mReadReg(BaseAddress, RegOffset) \
+                    XIo_In32((BaseAddress) + (RegOffset))
+
+/****************************************************************************/
+/**
+*
+* Write the given register.
+*
+* @param    BaseAddress is the base address of the device
+* @param    RegOffset is the register offset to be written
+* @param    Data is the 32-bit value to write to the register
+*
+* @return   None.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XEmac_mWriteReg(BaseAddress, RegOffset, Data) \
+                    XIo_Out32((BaseAddress) + (RegOffset), (Data))
+
+/****************************************************************************/
+/**
+*
+* Set the contents of the control register. Use the XEM_ECR_* constants
+* defined above to create the bit-mask to be written to the register.
+*
+* @param    BaseAddress is the base address of the device
+* @param    Mask is the 16-bit value to write to the control register
+*
+* @return   None.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XEmac_mSetControlReg(BaseAddress, Mask) \
+                    XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, (Mask))
+
+/****************************************************************************/
+/**
+*
+* Set the station address of the EMAC device.
+*
+* @param    BaseAddress is the base address of the device
+* @param    AddressPtr is a pointer to a 6-byte MAC address
+*
+* @return   None.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XEmac_mSetMacAddress(BaseAddress, AddressPtr)               \
+{                                                                   \
+    u32 MacAddr;                                                \
+                                                                    \
+    MacAddr = ((AddressPtr)[0] << 8) | (AddressPtr)[1];             \
+    XIo_Out32((BaseAddress) + XEM_SAH_OFFSET, MacAddr);             \
+                                                                    \
+    MacAddr = ((AddressPtr)[2] << 24) | ((AddressPtr)[3] << 16) |   \
+              ((AddressPtr)[4] << 8) | (AddressPtr)[5];             \
+                                                                    \
+    XIo_Out32((BaseAddress) + XEM_SAL_OFFSET, MacAddr);             \
+}
+
+/****************************************************************************/
+/**
+*
+* Enable the transmitter and receiver. Preserve the contents of the control
+* register.
+*
+* @param    BaseAddress is the base address of the device
+*
+* @return   None.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XEmac_mEnable(BaseAddress) \
+{ \
+    u32 Control; \
+    Control = XIo_In32((BaseAddress) + XEM_ECR_OFFSET); \
+    Control &= ~(XEM_ECR_XMIT_RESET_MASK | XEM_ECR_RECV_RESET_MASK); \
+    Control |= (XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK); \
+    XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, Control); \
+}
+
+/****************************************************************************/
+/**
+*
+* Disable the transmitter and receiver. Preserve the contents of the control
+* register.
+*
+* @param    BaseAddress is the base address of the device
+*
+* @return   None.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XEmac_mDisable(BaseAddress) \
+                XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, \
+                    XIo_In32((BaseAddress) + XEM_ECR_OFFSET) & \
+                    ~(XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK))
+
+/****************************************************************************/
+/**
+*
+* Check to see if the transmission is complete.
+*
+* @param    BaseAddress is the base address of the device
+*
+* @return   TRUE if it is done, or FALSE if it is not.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XEmac_mIsTxDone(BaseAddress) \
+             (XIo_In32((BaseAddress) + XEM_ISR_OFFSET) & XEM_EIR_XMIT_DONE_MASK)
+
+/****************************************************************************/
+/**
+*
+* Check to see if the receive FIFO is empty.
+*
+* @param    BaseAddress is the base address of the device
+*
+* @return   TRUE if it is empty, or FALSE if it is not.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XEmac_mIsRxEmpty(BaseAddress) \
+          (!(XIo_In32((BaseAddress) + XEM_ISR_OFFSET) & XEM_EIR_RECV_DONE_MASK))
+
+/****************************************************************************/
+/**
+*
+* Reset MII compliant PHY
+*
+* @param    BaseAddress is the base address of the device
+*
+* @return   None.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XEmac_mPhyReset(BaseAddress) \
+{ \
+    u32 Control;                                    \
+    Control = XIo_In32((BaseAddress) + XEM_ECR_OFFSET); \
+    Control &= ~XEM_ECR_PHY_ENABLE_MASK;                \
+    XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, Control); \
+    Control |= XEM_ECR_PHY_ENABLE_MASK;                 \
+    XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, Control); \
+}
+
+/************************** Function Prototypes ******************************/
+
+void XEmac_SendFrame(u32 BaseAddress, u8 * FramePtr, int Size);
+int XEmac_RecvFrame(u32 BaseAddress, u8 * FramePtr);
+
+#endif				/* end of protection macro */
diff -urN linux-2.4.29/drivers/net/xilinx_enet/xemac_options.c linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac_options.c
--- linux-2.4.29/drivers/net/xilinx_enet/xemac_options.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac_options.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,334 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xemac_options.c
+*
+* Functions in this file handle configuration of the XEmac driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  07/31/01 First release
+* 1.00b rpm  02/20/02 Repartitioned files and functions
+* 1.00c rpm  12/05/02 New version includes support for simple DMA
+* 1.00d rpm  09/26/03 New version includes support PLB Ethernet and v2.00a of
+*                     the packet fifo driver.
+* 1.00e rmm  04/06/04 Added XEM_NO_SGEND_INT_OPTION processing. Relocated
+*                     XEM_MAX_IFG definition from here to xemac_l.h as XEM_IFGP_
+*                     PART1_MAX and XEM_IFGP_PART2_MAX.
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xemac_i.h"
+#include "xio.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+/************************** Variable Definitions *****************************/
+
+/*
+ * A table of options and masks. This table maps the user-visible options with
+ * the control register masks. It is used in Set/GetOptions as an alternative
+ * to a series of if/else pairs. Note that the polled options does not have a
+ * corresponding entry in the control register, so it does not exist in the
+ * table.
+ */
+typedef struct {
+	u32 Option;
+	u32 Mask;
+} OptionMap;
+
+static OptionMap OptionsTable[] = {
+	{XEM_UNICAST_OPTION, XEM_ECR_UNICAST_ENABLE_MASK},
+	{XEM_BROADCAST_OPTION, XEM_ECR_BROAD_ENABLE_MASK},
+	{XEM_PROMISC_OPTION, XEM_ECR_PROMISC_ENABLE_MASK},
+	{XEM_FDUPLEX_OPTION, XEM_ECR_FULL_DUPLEX_MASK},
+	{XEM_LOOPBACK_OPTION, XEM_ECR_LOOPBACK_MASK},
+	{XEM_MULTICAST_OPTION, XEM_ECR_MULTI_ENABLE_MASK},
+	{XEM_FLOW_CONTROL_OPTION, XEM_ECR_PAUSE_FRAME_MASK},
+	{XEM_INSERT_PAD_OPTION, XEM_ECR_XMIT_PAD_ENABLE_MASK},
+	{XEM_INSERT_FCS_OPTION, XEM_ECR_XMIT_FCS_ENABLE_MASK},
+	{XEM_INSERT_ADDR_OPTION, XEM_ECR_XMIT_ADDR_INSERT_MASK},
+	{XEM_OVWRT_ADDR_OPTION, XEM_ECR_XMIT_ADDR_OVWRT_MASK},
+	{XEM_STRIP_PAD_FCS_OPTION, XEM_ECR_RECV_STRIP_ENABLE_MASK}
+};
+
+#define XEM_NUM_OPTIONS     (sizeof(OptionsTable) / sizeof(OptionMap))
+
+/*****************************************************************************/
+/**
+*
+* Set Ethernet driver/device options.  The device must be stopped before
+* calling this function.  The options are contained within a bit-mask with each
+* bit representing an option (i.e., you can OR the options together). A one (1)
+* in the bit-mask turns an option on, and a zero (0) turns the option off.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param OptionsFlag is a bit-mask representing the Ethernet options to turn on
+*        or off. See xemac.h for a description of the available options.
+*
+* @return
+*
+* - XST_SUCCESS if the options were set successfully
+* - XST_DEVICE_IS_STARTED if the device has not yet been stopped
+*
+* @note
+*
+* This function is not thread-safe and makes use of internal resources that are
+* shared between the Start, Stop, and SetOptions functions, so if one task
+* might be setting device options while another is trying to start the device,
+* protection of this shared data (typically using a semaphore) is required.
+*
+******************************************************************************/
+XStatus
+XEmac_SetOptions(XEmac * InstancePtr, u32 OptionsFlag)
+{
+	u32 ControlReg;
+	int Index;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+		return XST_DEVICE_IS_STARTED;
+	}
+
+	ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
+
+	/*
+	 * Loop through the options table, turning the option on or off
+	 * depending on whether the bit is set in the incoming options flag.
+	 */
+	for (Index = 0; Index < XEM_NUM_OPTIONS; Index++) {
+		if (OptionsFlag & OptionsTable[Index].Option) {
+			ControlReg |= OptionsTable[Index].Mask;	/* turn it on */
+		} else {
+			ControlReg &= ~OptionsTable[Index].Mask;	/* turn it off */
+		}
+	}
+
+	/*
+	 * TODO: need to validate addr-overwrite only if addr-insert?
+	 */
+
+	/*
+	 * Now write the control register. Leave it to the upper layers
+	 * to restart the device.
+	 */
+	XIo_Out32(InstancePtr->BaseAddress + XEM_ECR_OFFSET, ControlReg);
+
+	/*
+	 * Check the polled option
+	 */
+	if (OptionsFlag & XEM_POLLED_OPTION) {
+		InstancePtr->IsPolled = TRUE;
+	} else {
+		InstancePtr->IsPolled = FALSE;
+	}
+
+	/*
+	 * Check the No SGEND option
+	 */
+	if (OptionsFlag & XEM_NO_SGEND_INT_OPTION) {
+		InstancePtr->IsSgEndDisable = TRUE;
+	} else {
+		InstancePtr->IsSgEndDisable = FALSE;
+	}
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Get Ethernet driver/device options. The 32-bit value returned is a bit-mask
+* representing the options.  A one (1) in the bit-mask means the option is on,
+* and a zero (0) means the option is off.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* The 32-bit value of the Ethernet options. The value is a bit-mask
+* representing all options that are currently enabled. See xemac.h for a
+* description of the available options.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32
+XEmac_GetOptions(XEmac * InstancePtr)
+{
+	u32 OptionsFlag = 0;
+	u32 ControlReg;
+	int Index;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/*
+	 * Get the control register to determine which options are currently set.
+	 */
+	ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
+
+	/*
+	 * Loop through the options table to determine which options are set
+	 */
+	for (Index = 0; Index < XEM_NUM_OPTIONS; Index++) {
+		if (ControlReg & OptionsTable[Index].Mask) {
+			OptionsFlag |= OptionsTable[Index].Option;
+		}
+	}
+
+	if (InstancePtr->IsPolled) {
+		OptionsFlag |= XEM_POLLED_OPTION;
+	}
+
+	if (InstancePtr->IsSgEndDisable) {
+		OptionsFlag |= XEM_NO_SGEND_INT_OPTION;
+	}
+
+	return OptionsFlag;
+}
+
+/*****************************************************************************/
+/**
+*
+* Set the Interframe Gap (IFG), which is the time the MAC delays between
+* transmitting frames.  There are two parts required.  The total interframe gap
+* is the total of the two parts.  The values provided for the Part1 and Part2
+* parameters are multiplied by 4 to obtain the bit-time interval. The first
+* part should be the first 2/3 of the total interframe gap. The MAC will reset
+* the interframe gap timer if carrier sense becomes true during the period
+* defined by interframe gap Part1. Part1 may be shorter than 2/3 the total and
+* can be as small as zero. The second part should be the last 1/3 of the total
+* interframe gap, but can be as large as the total interframe gap. The MAC
+* will not reset the interframe gap timer if carrier sense becomes true during
+* the period defined by interframe gap Part2.
+*
+* The device must be stopped before setting the interframe gap.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param Part1 is the interframe gap part 1 (which will be multiplied by 4 to
+*        get the bit-time interval).
+* @param Part2 is the interframe gap part 2 (which will be multiplied by 4 to
+*        get the bit-time interval).
+*
+* @return
+*
+* - XST_SUCCESS if the interframe gap was set successfully
+* - XST_DEVICE_IS_STARTED if the device has not been stopped
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XEmac_SetInterframeGap(XEmac * InstancePtr, u8 Part1, u8 Part2)
+{
+	u32 Ifg;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(Part1 <= XEM_IFGP_PART1_MAX);
+	XASSERT_NONVOID(Part2 <= XEM_IFGP_PART2_MAX);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/*
+	 * Be sure device has been stopped
+	 */
+	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+		return XST_DEVICE_IS_STARTED;
+	}
+
+	Ifg = Part1 << XEM_IFGP_PART1_SHIFT;
+	Ifg |= (Part2 << XEM_IFGP_PART2_SHIFT);
+	XIo_Out32(InstancePtr->BaseAddress + XEM_IFGP_OFFSET, Ifg);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Get the interframe gap, parts 1 and 2. See the description of interframe gap
+* above in XEmac_SetInterframeGap().
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param Part1Ptr is a pointer to an 8-bit buffer into which the interframe gap
+*        part 1 value will be copied.
+* @param Part2Ptr is a pointer to an 8-bit buffer into which the interframe gap
+*        part 2 value will be copied.
+*
+* @return
+*
+* None. The values of the interframe gap parts are copied into the
+* output parameters.
+*
+******************************************************************************/
+void
+XEmac_GetInterframeGap(XEmac * InstancePtr, u8 * Part1Ptr, u8 * Part2Ptr)
+{
+	u32 Ifg;
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(Part1Ptr != NULL);
+	XASSERT_VOID(Part2Ptr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	Ifg = XIo_In32(InstancePtr->BaseAddress + XEM_IFGP_OFFSET);
+	*Part1Ptr = (Ifg & XEM_IFGP_PART1_MASK) >> XEM_IFGP_PART1_SHIFT;
+	*Part2Ptr = (Ifg & XEM_IFGP_PART2_MASK) >> XEM_IFGP_PART2_SHIFT;
+}
diff -urN linux-2.4.29/drivers/net/xilinx_enet/xemac_phy.c linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac_phy.c
--- linux-2.4.29/drivers/net/xilinx_enet/xemac_phy.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/net/xilinx_enet/xemac_phy.c	2005-06-14 02:12:12.000000000 +0100
@@ -0,0 +1,281 @@
+/******************************************************************************
+*
+*     Author: Xilinx, Inc.
+*     
+*     
+*     This program is free software; you can redistribute it and/or modify it
+*     under the terms of the GNU General Public License as published by the
+*     Free Software Foundation; either version 2 of the License, or (at your
+*     option) any later version.
+*     
+*     
+*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
+*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
+*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
+*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
+*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+*     FITNESS FOR A PARTICULAR PURPOSE.
+*     
+*     
+*     Xilinx hardware products are not intended for use in life support
+*     appliances, devices, or systems. Use in such applications is
+*     expressly prohibited.
+*     
+*     
+*     (c) Copyright 2002-2004 Xilinx Inc.
+*     All rights reserved.
+*     
+*     
+*     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.,
+*     675 Mass Ave, Cambridge, MA 02139, USA.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xemac_phy.c
+*
+* Contains functions to read and write the PHY through the Ethernet MAC MII
+* registers.  These assume an MII-compliant PHY.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  07/31/01 First release
+* 1.00b rpm  02/20/02 Repartitioned files and functions
+* 1.00c rpm  12/05/02 New version includes support for simple DMA
+* 1.00d rpm  09/26/03 New version includes support PLB Ethernet and v2.00a of
+*                     the packet fifo driver.
+* 1.00e rmm  04/06/04 Moved XEM_MAX_PHY constants to xemac_l.h
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xemac_i.h"
+#include "xio.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+/************************** Variable Definitions *****************************/
+
+/*****************************************************************************/
+/**
+*
+* Read the current value of the PHY register indicated by the PhyAddress and
+* the RegisterNum parameters. The MAC provides the driver with the ability to
+* talk to a PHY that adheres to the Media Independent Interface (MII) as
+* defined in the IEEE 802.3 standard.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param PhyAddress is the address of the PHY to be read (supports multiple
+*        PHYs)
+* @param RegisterNum is the register number, 0-31, of the specific PHY register
+*        to read
+* @param PhyDataPtr is an output parameter, and points to a 16-bit buffer into
+*        which the current value of the register will be copied.
+*
+* @return
+*
+* - XST_SUCCESS if the PHY was read from successfully
+* - XST_NO_FEATURE if the device is not configured with MII support
+* - XST_EMAC_MII_BUSY if there is another PHY operation in progress
+* - XST_EMAC_MII_READ_ERROR if a read error occurred between the MAC and the PHY
+*
+* @note
+*
+* This function is not thread-safe. The user must provide mutually exclusive
+* access to this function if there are to be multiple threads that can call it.
+* <br><br>
+* There is the possibility that this function will not return if the hardware
+* is broken (i.e., it never sets the status bit indicating that the read is
+* done). If this is of concern to the user, the user should provide protection
+* from this problem - perhaps by using a different timer thread to monitor the
+* PhyRead thread.
+*
+******************************************************************************/
+XStatus
+XEmac_PhyRead(XEmac * InstancePtr, u32 PhyAddress,
+	      u32 RegisterNum, u16 * PhyDataPtr)
+{
+	u32 MiiControl;
+	u32 MiiData;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(PhyAddress <= XEM_MGTCR_MAX_PHY_ADDR);
+	XASSERT_NONVOID(RegisterNum <= XEM_MGTCR_MAX_PHY_REG);
+	XASSERT_NONVOID(PhyDataPtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/*
+	 * Make sure the device has the management interface
+	 */
+	if (!InstancePtr->HasMii) {
+		return XST_NO_FEATURE;
+	}
+
+	/*
+	 * Verify that there is no operation in progress already
+	 */
+	MiiControl = XIo_In32(InstancePtr->BaseAddress + XEM_MGTCR_OFFSET);
+	if (MiiControl & XEM_MGTCR_START_MASK) {
+		/* operation in progress */
+		return XST_EMAC_MII_BUSY;
+	}
+
+	/*
+	 * Set up the MII control register first.  We set up a control word with
+	 * the PHY address and register number, then indicate the direction (read),
+	 * then start the operation.
+	 */
+	MiiControl = PhyAddress << XEM_MGTCR_PHY_ADDR_SHIFT;
+	MiiControl |= (RegisterNum << XEM_MGTCR_REG_ADDR_SHIFT);
+	MiiControl |= (XEM_MGTCR_RW_NOT_MASK | XEM_MGTCR_START_MASK |
+		       XEM_MGTCR_MII_ENABLE_MASK);
+
+	XIo_Out32(InstancePtr->BaseAddress + XEM_MGTCR_OFFSET, MiiControl);
+
+	/*
+	 * Wait for the operation to complete
+	 */
+	do {
+		MiiControl =
+		    XIo_In32(InstancePtr->BaseAddress + XEM_MGTCR_OFFSET);
+	}
+	while (MiiControl & XEM_MGTCR_START_MASK);
+
+	/*
+	 * Now read the resulting MII data register.  First check to see if
+	 * an error occurred before reading and returning the value in
+	 * the MII data register.
+	 */
+	if (MiiControl & XEM_MGTCR_RD_ERROR_MASK) {
+		/*
+		 * MII read error occurred.  Upper layer will need to retry.
+		 */
+		return XST_EMAC_MII_READ_ERROR;
+	}
+
+	/*
+	 * Retrieve the data from the 32-bit register, then copy it to
+	 * the 16-bit output parameter.
+	 */
+	MiiData = XIo_In32(InstancePtr->BaseAddress + XEM_MGTDR_OFFSET);
+
+	*PhyDataPtr = (u16) MiiData;
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Write data to the specified PHY register. The Ethernet driver does not
+* require the device to be stopped before writing to the PHY.  Although it is
+* probably a good idea to stop the device, it is the responsibility of the
+* application to deem this necessary. The MAC provides the driver with the
+* ability to talk to a PHY that adheres to the Media Independent Interface
+* (MII) as defined in the IEEE 802.3 standard.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param PhyAddress is the address of the PHY to be written (supports multiple
+*        PHYs)
+* @param RegisterNum is the register number, 0-31, of the specific PHY register
+*        to write
+* @param PhyData is the 16-bit value that will be written to the register
+*
+* @return
+*
+* - XST_SUCCESS if the PHY was written to successfully. Since there is no error
+*   status from the MAC on a write, the user should read the PHY to verify the
+*   write was successful.
+* - XST_NO_FEATURE if the device is not configured with MII support
+* - XST_EMAC_MII_BUSY if there is another PHY operation in progress
+*
+* @note
+*
+* This function is not thread-safe. The user must provide mutually exclusive
+* access to this function if there are to be multiple threads that can call it.
+* <br><br>
+* There is the possibility that this function will not return if the hardware
+* is broken (i.e., it never sets the status bit indicating that the write is
+* done). If this is of concern to the user, the user should provide protection
+* from this problem - perhaps by using a different timer thread to monitor the
+* PhyWrite thread.
+*
+******************************************************************************/
+XStatus
+XEmac_PhyWrite(XEmac * InstancePtr, u32 PhyAddress,
+	       u32 RegisterNum, u16 PhyData)
+{
+	u32 MiiControl;
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(PhyAddress <= XEM_MGTCR_MAX_PHY_ADDR);
+	XASSERT_NONVOID(RegisterNum <= XEM_MGTCR_MAX_PHY_REG);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/*
+	 * Make sure the device has the management interface
+	 */
+	if (!InstancePtr->HasMii) {
+		return XST_NO_FEATURE;
+	}
+
+	/*
+	 * Verify that there is no operation in progress already
+	 */
+	MiiControl = XIo_In32(InstancePtr->BaseAddress + XEM_MGTCR_OFFSET);
+	if (MiiControl & XEM_MGTCR_START_MASK) {
+		/* operation in progress */
+		return XST_EMAC_MII_BUSY;
+	}
+
+	/*
+	 * Set up the MII data register first.  Write the 16-bit input
+	 * value to the 32-bit data register.
+	 */
+	XIo_Out32(InstancePtr->BaseAddress + XEM_MGTDR_OFFSET, (u32) PhyData);
+
+	/*
+	 * Now set up the MII control register.  We set up a control
+	 * word with the PHY address and register number, then indicate
+	 * the direction (write), then start the operation.
+	 */
+	MiiControl = PhyAddress << XEM_MGTCR_PHY_ADDR_SHIFT;
+	MiiControl |= (RegisterNum << XEM_MGTCR_REG_ADDR_SHIFT);
+	MiiControl |= (XEM_MGTCR_START_MASK | XEM_MGTCR_MII_ENABLE_MASK);
+
+	XIo_Out32(InstancePtr->BaseAddress + XEM_MGTCR_OFFSET, MiiControl);
+
+	/*
+	 * Wait for the operation to complete
+	 */
+	do {
+		MiiControl =
+		    XIo_In32(InstancePtr->BaseAddress + XEM_MGTCR_OFFSET);
+	}
+	while (MiiControl & XEM_MGTCR_START_MASK);
+
+	/*
+	 * There is no status indicating whether the operation was
+	 * successful or not.
+	 */
+	return XST_SUCCESS;
+}
diff -urN linux-2.4.29/drivers/parport/Config.in linux-2.4.29-uc1/drivers/parport/Config.in
--- linux-2.4.29/drivers/parport/Config.in	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/parport/Config.in	2005-06-14 02:11:58.000000000 +0100
@@ -26,6 +26,9 @@
       fi
       dep_tristate '    Support for PCMCIA management for PC-style ports' CONFIG_PARPORT_PC_PCMCIA $CONFIG_PCMCIA $CONFIG_PARPORT_PC $CONFIG_HOTPLUG
    fi
+   if [ "$CONFIG_DRAGONIXVZ" = "y" ]; then
+      dep_tristate '  Dragonix parallel port add-on board' CONFIG_PARPORT_DRAGONIX $CONFIG_PARPORT
+   fi
    if [ "$CONFIG_ARM" = "y" ]; then
       dep_tristate '  Archimedes hardware' CONFIG_PARPORT_ARC $CONFIG_PARPORT
    fi
@@ -66,6 +69,10 @@
    bool '  Support foreign hardware' CONFIG_PARPORT_OTHER
 
    bool '  IEEE 1284 transfer modes' CONFIG_PARPORT_1284
+
+   if [ "$CONFIG_SH_HD64465" != "n" ]; then
+      bool '  HD64465 hardware' CONFIG_PARPORT_HD64465
+   fi
 fi
 
 endmenu
diff -urN linux-2.4.29/drivers/parport/init.c linux-2.4.29-uc1/drivers/parport/init.c
--- linux-2.4.29/drivers/parport/init.c	2002-11-28 23:53:14.000000000 +0000
+++ linux-2.4.29-uc1/drivers/parport/init.c	2005-06-14 02:11:59.000000000 +0100
@@ -31,6 +31,7 @@
 extern int parport_sunbpp_init(void);
 extern int parport_amiga_init(void);
 extern int parport_mfc3_init(void);
+extern int parport_hd64465_init(void);
 extern int parport_atari_init(void);
 
 static int parport_setup_ptr __initdata = 0;
@@ -149,6 +150,9 @@
 #ifdef CONFIG_PARPORT_PC
 	parport_pc_init(io, io_hi, irq, dma);
 #endif
+#ifdef CONFIG_PARPORT_DRAGONIX
+	parport_dragonix_init();
+#endif
 #ifdef CONFIG_PARPORT_AMIGA
 	parport_amiga_init();
 #endif
@@ -164,6 +168,9 @@
 #ifdef CONFIG_PARPORT_SUNBPP
 	parport_sunbpp_init();
 #endif
+#ifdef CONFIG_PARPORT_HD64465
+	parport_hd64465_init();
+#endif
 	return 0;
 }
 
diff -urN linux-2.4.29/drivers/parport/Makefile linux-2.4.29-uc1/drivers/parport/Makefile
--- linux-2.4.29/drivers/parport/Makefile	2004-08-08 00:26:05.000000000 +0100
+++ linux-2.4.29-uc1/drivers/parport/Makefile	2005-06-14 02:11:58.000000000 +0100
@@ -28,6 +28,8 @@
 obj-$(CONFIG_PARPORT_ATARI)	+= parport_atari.o
 obj-$(CONFIG_PARPORT_SUNBPP)	+= parport_sunbpp.o
 obj-$(CONFIG_PARPORT_GSC)	+= parport_gsc.o
+obj-$(CONFIG_PARPORT_HD64465)	+= parport_hd64465.o
+obj-$(CONFIG_PARPORT_DRAGONIX)	+= parport_dragonix.o
 obj-$(CONFIG_PARPORT_IP22)	+= parport_ip22.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/parport/parport_dragonix.c linux-2.4.29-uc1/drivers/parport/parport_dragonix.c
--- linux-2.4.29/drivers/parport/parport_dragonix.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/parport/parport_dragonix.c	2005-06-14 02:11:58.000000000 +0100
@@ -0,0 +1,440 @@
+/* Low-level parallel port routines for the Dragonix VZ add on board
+ *
+ * Author: Daniel Haensse <daniel.haensse@dragonix.net>
+ *
+ * Parallel port is emulated by the general purpose io pins
+ *
+ * DIRECTION    : PJ0
+ *
+ * nSTB (1)  -> : PK2
+ * DB0  (2)  <->: PE0
+ * DB1  (3)  <->: PE1
+ * DB2  (4)  <->: PE2
+ * DB3  (5)  <->: PE3
+ * DB4  (6)  <->: PK4
+ * DB5  (7)  <->: PK5
+ * DB6  (8)  <->: PK6
+ * DB7  (9)  <->: PK7
+ * nACK (10) <- : PD4
+ * BSY  (11) <- : PD5
+ * PE   (12) <- : PD6
+ * SEL  (13) <- : PF1
+ * nAF  (14)  ->: PJ1
+ * nER  (15) <- : PD2
+ * nPI  (16)  ->: PJ2
+ * nSEL (17)  ->: PJ3
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/parport.h>
+#include <linux/ioport.h>
+#include <asm/setup.h>
+#include <asm-m68knommu/MC68VZ328.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+
+static struct parport *this_port = NULL;
+static unsigned char ctr_copy;
+
+static void dragonix_write_data(struct parport *p, unsigned char data)
+{
+	//printk(KERN_INFO  "write_data %c\n",data);
+        PEDATA=(PEDATA&~0x0f)|(data&0x0f);
+        PKDATA=(PKDATA&~0xf0)|(data&0xf0);
+}
+
+static unsigned char dragonix_read_data(struct parport *p)
+{
+	return( (PEDATA&0x0f) | (PKDATA&0xf0) );
+}
+
+static __inline__ unsigned char __dragonix_ioport_frob_control (struct parport *p,
+							   unsigned char mask,
+							   unsigned char val)
+{
+        unsigned long flags;
+        unsigned char ctr = ctr_copy;
+	ctr = (ctr & ~mask) ^ val;
+        ctr_copy = ctr;	/* Update soft copy */
+
+        save_flags(flags);
+	cli();
+        PJDATA=(PJDATA&~0x0e) | ((ctr_copy^0x0a)&0x0e); // invert nAF and nSEL, leave DIR untouched
+        PKDATA=(PKDATA&~0x04) | ( (ctr_copy&0x01) ? 0x00 : 0x04 );
+
+        if(ctr_copy&0x20)
+        { // input
+          PEDIR&=~0x0f;
+          PKDIR&=~0xf0;
+          PJDATA&=~0x01;
+        }
+        else
+        { // output
+          PJDATA|=0x01;
+          PEDIR|=0x0f;
+          PKDIR|=0xf0;
+        }
+
+        restore_flags(flags);
+
+        if(ctr_copy&0x10)
+        {
+          enable_irq(IRQ2_IRQ_NUM);
+        }
+        else
+        {
+          disable_irq(IRQ2_IRQ_NUM);
+        }
+
+        return ctr;
+}
+
+static void dragonix_write_control(struct parport *p, unsigned char d)
+{
+	const unsigned char wm = (PARPORT_CONTROL_STROBE |
+				  PARPORT_CONTROL_AUTOFD |
+				  PARPORT_CONTROL_INIT |
+				  PARPORT_CONTROL_SELECT);
+
+	/* Take this out when drivers have adapted to the newer interface. */
+	if (d & 0x20) {
+		/*printk (KERN_INFO "%s (%s): use data_reverse for this!\n",
+			p->name, p->cad->name);*/
+		dragonix_data_reverse (p);
+	}
+
+	__dragonix_ioport_frob_control (p, wm, d & wm);
+}
+
+static unsigned char dragonix_read_control( struct parport *p)
+{
+       	const unsigned char wm = (PARPORT_CONTROL_STROBE |
+				  PARPORT_CONTROL_AUTOFD |
+				  PARPORT_CONTROL_INIT |
+				  PARPORT_CONTROL_SELECT);
+       	//printk(KERN_INFO  "read_control \n");
+	return ctr_copy & wm; /* Use soft copy */
+}
+
+static unsigned char dragonix_frob_control( struct parport *p, unsigned char mask, unsigned char val)
+{
+        /*
+        * DIRECTION    : PJ0, 1
+        * nSTB (1)  -> : PK2, 1
+        * nAF  (14)  ->: PJ1  0
+        * nPI  (16)  ->: PJ2  0
+        * nSEL (17)  -> : PJ3  1
+        */
+        	const unsigned char wm = (PARPORT_CONTROL_STROBE |
+				  PARPORT_CONTROL_AUTOFD |
+				  PARPORT_CONTROL_INIT |
+				  PARPORT_CONTROL_SELECT);
+
+	/* Take this out when drivers have adapted to the newer interface. */
+	if (mask & 0x20) {
+		/*printk (KERN_INFO "%s (%s): use data_%s for this!\n",
+			p->name, p->cad->name,
+			(val & 0x20) ? "reverse" : "forward");*/
+		if (val & 0x20)
+			dragonix_data_reverse (p);
+		else
+			dragonix_data_forward (p);
+	}
+
+	/* Restrict mask and val to control lines. */
+	mask &= wm;
+	val &= wm;
+
+	return __dragonix_ioport_frob_control (p, mask, val);
+}
+
+
+static unsigned char dragonix_read_status(struct parport *p)
+{
+	unsigned char status;
+        unsigned long flags;
+        /*
+        * nACK (10) <- : PD4, I
+        * BSY  (11) <- : PD5  I
+        * PE   (12) <- : PD6  I
+        * SEL  (13) <- : PF1  I
+        * nER  (15) <- : PD2  I
+        */
+       	save_flags(flags);
+	cli();
+        status=(((PDDATA<<2)&0x80) ^ 0x80 ) /*BSY*/
+                | ((PFDATA<<3)&0x10) /* SEL */| ((PDDATA>>1)&0x20) /* PE */
+                | ((PDDATA<<1)&0x08) /* nER */
+                | (((PDDATA<<2)&0x40)^0x40) /* nACK */
+                |0x07;
+        restore_flags(flags);
+	//printk(KERN_INFO  "read_status %02x\n", status);
+	return status;
+}
+
+/* as this ports irq handling is already done, we use a generic funktion */
+static void dragonix_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+        //printk(KERN_INFO "irq\n");
+        ISR|=ISR_IRQ2; // Clear IRQ2
+        parport_generic_irq(irq, (struct parport *) dev_id, regs);
+}
+
+static void dragonix_enable_irq(struct parport *p)
+{
+        __dragonix_ioport_frob_control(p, 0x10, 0x10);
+}
+
+static void dragonix_disable_irq(struct parport *p)
+{
+        __dragonix_ioport_frob_control (p, 0x10, 0);
+}
+
+static void dragonix_data_forward(struct parport *p)
+{
+	//printk(KERN_INFO  "forward\n");
+	__dragonix_ioport_frob_control (p, 0x20, 0); // output
+}
+
+static void dragonix_data_reverse(struct parport *p)
+{
+	//printk(KERN_INFO  "reverse\n");
+        __dragonix_ioport_frob_control (p, 0x20, 0x20); // input
+}
+
+static void dragonix_init_state(struct pardevice *dev, struct parport_state *s)
+{
+        //printk(KERN_INFO "state\n");
+        s->u.pc.ctr = 0xc | (dev->irq_func ? 0x10 : 0x00);
+}
+
+static void dragonix_save_state(struct parport *p, struct parport_state *s)
+{
+        s->u.pc.ctr=ctr_copy;
+}
+
+static void dragonix_restore_state(struct parport *p, struct parport_state *s)
+{
+
+        /*
+        * DIRECTION    : PJ0, 1
+        *
+        * nSTB (1)  -> : PK2, 1
+        * nAF  (14)  ->: PJ1  0
+        * nPI  (16)  ->: PJ2  0
+        * nSEL (17)  -> : PJ3  1
+        */
+        unsigned long flags;
+
+        ctr_copy=s->u.pc.ctr;
+	save_flags(flags);
+	cli();
+        PJDATA=(PJDATA&~0x0e) | ((ctr_copy^0x0a)&0x0e); // invert nAF and nSEL, leave DIR untouched
+        PKDATA=(PKDATA&~0x04) | ( (ctr_copy&0x01) ? 0x00 : 0x04 );
+        if(ctr_copy&0x20)
+        { // input
+          PEDIR&=~0x0f;
+          PKDIR&=~0xf0;
+          PJDATA&=~0x01;
+        }
+        else
+        { // output
+          PJDATA|=0x01;
+          PEDIR|=0x0f;
+          PKDIR|=0xf0;
+        }
+        restore_flags(flags);
+
+        if(ctr_copy&0x10)
+        {
+          enable_irq(IRQ2_IRQ_NUM);
+        }
+        else
+        {
+          disable_irq(IRQ2_IRQ_NUM);
+        }
+}
+
+static void dragonix_inc_use_count(void)
+{
+#ifdef MODULE
+        MOD_INC_USE_COUNT;
+#endif
+}
+
+static void dragonix_dec_use_count(void)
+{
+#ifdef MODULE
+	MOD_DEC_USE_COUNT;
+#endif
+}
+
+static struct parport_operations pp_dragonix_ops = {
+	dragonix_write_data,
+	dragonix_read_data,
+
+	dragonix_write_control,
+	dragonix_read_control,
+	dragonix_frob_control,
+
+	dragonix_read_status,
+
+	dragonix_enable_irq,
+	dragonix_disable_irq,
+
+	dragonix_data_forward,
+	dragonix_data_reverse,
+
+	dragonix_init_state,
+	dragonix_save_state,
+	dragonix_restore_state,
+
+	dragonix_inc_use_count,
+	dragonix_dec_use_count,
+
+	parport_ieee1284_epp_write_data,
+	parport_ieee1284_epp_read_data,
+	parport_ieee1284_epp_write_addr,
+	parport_ieee1284_epp_read_addr,
+
+	parport_ieee1284_ecp_write_data,
+	parport_ieee1284_ecp_read_data,
+	parport_ieee1284_ecp_write_addr,
+
+	parport_ieee1284_write_compat,
+	parport_ieee1284_read_nibble,
+	parport_ieee1284_read_byte,
+};
+
+/* ----------- Initialisation code --------------------------------- */
+
+int __init parport_dragonix_init(void)
+{
+	struct parport *p;
+        int err;
+        unsigned long flags;
+
+        if(this_port!=NULL) return(-ENODEV);
+        /* With the current implementation just initialize IO port*/
+        /*
+        * DIRECTION    : PJ0, 1
+        *
+        * nSTB (1)  -> : PK2, 1
+        * DB0  (2)  <->: PE0, 0
+        * DB1  (3)  <->: PE1, 0
+        * DB2  (4)  <->: PE2, 0
+        * DB3  (5)  <->: PE3, 0
+        * DB4  (6)  <->: PK4, 0
+        * DB5  (7)  <->: PK5, 0
+        * DB6  (8)  <->: PK6, 0
+        * DB7  (9)  <->: PK7, 0
+        * nACK (10) <- : PD4, I
+        * BSY  (11) <- : PD5  I
+        * PE   (12) <- : PD6  I
+        * SEL  (13)  <-: PF1  I
+        * nAF  (14)  ->: PJ1  0
+        * nER  (15) <- : PD2  I
+        * nPI  (16)  ->: PJ2  0
+        * nSEL (17)  -> : PJ3  1
+        */
+
+        /* PJ0=DIR, PJ1=nAF, PJ2=nPI, PJ3=nSEL */
+        PJSEL|=0x0f;
+        PJDATA=(PJDATA&~0x0f)|0x0b;
+        PJDIR|=0x0f;
+        PJPUEN&=~0x0f; // we don't need pull-ups
+
+        /* PF1=SEL */
+        PFSEL|=0x02;
+        PFDIR&=~0x02;
+        PFPUEN&=~0x02; // we don't need pull-ups
+
+        /* PD2=nER PD4=nACK PD5=BSY PD6=PE */
+        PDSEL|=0x74;
+        PDDIR&=~0x74;
+        PDPUEN&=~0x74; // we don't need pull-ups
+
+        /* PK2=nSTB PK4=DB4 PK5=DB5 PK6=DB6 PK7=DB7 */
+        PKSEL|=0xf4;
+        PKDIR|=0xf4;
+        PKDATA=(PKDATA&~0xf4)|0x04;
+        PKPUEN&=~0xf4;
+
+        /* PE0=DB0 PE1=DB1 PE2=DB2 PE3=DB3 */
+        PESEL|=0x0f;
+        PEDIR|=0x0f;
+        PEDATA&=~0x0f;
+        PEPUEN&=~0x0f;
+
+	err = -EBUSY;
+
+        p = parport_register_port(PADIR_ADDR, IRQ2_IRQ_NUM,PARPORT_DMA_NONE, &pp_dragonix_ops);
+        p->modes = PARPORT_MODE_PCSPP|PARPORT_MODE_TRISTATE;
+	p->size = 1;
+	if (!p)
+		goto out_port;
+	err = request_irq(IRQ2_IRQ_NUM, &dragonix_interrupt, IRQ_FLG_STD, p->name, p);
+        if (err)
+		goto out_irq;
+
+
+
+        /* Set irq port we go for falling edge of irq2
+           a spurious int may be created */
+	save_flags(flags);
+	cli();
+        ICR|=ICR_ET2;
+        ICR&=~ICR_POL2;
+        //*(volatile unsigned short *)0xfffff302 &= ~0x1100;
+        ISR|=ISR_IRQ2; // Clear IRQ2
+        PDSEL&=~0x20;
+        restore_flags(flags);
+
+	this_port = p;
+	printk(KERN_INFO "%s: Dragonix VZ add-on parallel port using irq %d\n", p->name,IRQ2_IRQ_NUM);
+	/* XXX: set operating mode */
+	parport_proc_register(p);
+
+	parport_announce_port(p);
+
+
+	return 0;
+
+out_irq:
+	parport_unregister_port(p);
+out_port:
+	return err;
+}
+
+void __exit parport_dragonix_exit(void)
+{
+	if (this_port->irq != PARPORT_IRQ_NONE)
+		free_irq(IRQ2_IRQ_NUM, this_port);
+	parport_proc_unregister(this_port);
+	parport_unregister_port(this_port);
+}
+
+
+
+//module_init(parport_dragonix_init)
+//module_exit(parport_dragonix_exit)
+
+#ifdef MODULE
+MODULE_AUTHOR("Daniel Haensse <daniel.haensse@dragonix.net>");
+MODULE_DESCRIPTION("Parport Driver for Dragonix Add-on Port");
+MODULE_SUPPORTED_DEVICE("Dragonix Parallel Port");
+MODULE_LICENSE("GPL");
+
+int init_module(void)
+{
+ parport_dragonix_init()
+
+}
+
+void cleanup_module(void)
+{
+        parport_dragonix_exit();
+}
+#endif
diff -urN linux-2.4.29/drivers/parport/parport_hd64465.c linux-2.4.29-uc1/drivers/parport/parport_hd64465.c
--- linux-2.4.29/drivers/parport/parport_hd64465.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/parport/parport_hd64465.c	2005-06-14 02:11:58.000000000 +0100
@@ -0,0 +1,649 @@
+/*
+ * Low-level parallel-port routines for Hitachi HD64465 hardware.
+ *
+ * Author: Tomoyoshi ASANO <asa@lineo.com>
+ *
+ * based on work by:
+ *          Eddie C. Dost <ecd@skynet.be>
+ *          Phil Blundell <Philip.Blundell@pobox.com>
+ *          Tim Waugh <tim@cyberelk.demon.co.uk>
+ *         Jose Renau <renau@acm.org>
+ *          David Campbell <campbell@tirian.che.curtin.edu.au>
+ *          Grant Guenther <grant@torque.net>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/init.h>
+
+#include <linux/parport.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#ifdef CONFIG_SH_KEYWEST
+#include <asm/hitachi_keywest.h>
+#endif
+#ifdef CONFIG_SH_HD64465
+#include <asm/hd64465.h>
+#endif
+
+#define DATA     0x00
+#define STATUS   0x02
+#define CONTROL  0x04
+#define EPPADDR  0x06
+#define EPPDATA  0x08
+#define CFIFO    0x10
+#define DFIFO    0x10
+#define TFIFO    0x10
+#define CONFIGA  0x10
+#define CONFIGB  0x12
+#define ECONTROL 0x14
+
+static void
+parport_hd64465_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+  parport_generic_irq(irq, (struct parport *) dev_id, regs);
+}
+
+void
+parport_hd64465_write_epp(struct parport *p, unsigned char d)
+{
+  outb(d, p->base + EPPDATA);
+}
+
+unsigned char
+parport_hd64465_read_epp(struct parport *p)
+{
+  return inb(p->base + EPPDATA);
+}
+
+void
+parport_hd64465_write_epp_addr(struct parport *p, unsigned char d)
+{
+  outb(d, p->base + EPPADDR);
+}
+
+unsigned char
+parport_hd64465_read_epp_addr(struct parport *p)
+{
+ return inb(p->base + EPPADDR);
+}
+
+int parport_hd64465_epp_clear_timeout(struct parport *pb);
+
+int
+parport_hd64465_check_epp_timeout(struct parport *p)
+{
+  if (!(inb(p->base+STATUS) & 1))
+    return 0;
+  parport_hd64465_epp_clear_timeout(p);
+  return 1;
+}
+
+unsigned char
+parport_hd64465_read_configb(struct parport *p)
+{
+  return inb(p->base + CONFIGB);
+}
+
+void
+parport_hd64465_write_data(struct parport *p, unsigned char d)
+{
+  outb(d, p->base + DATA);
+}
+
+unsigned char
+parport_hd64465_read_data(struct parport *p)
+{
+  return inb(p->base + DATA);
+}
+
+void
+parport_hd64465_write_control(struct parport *p, unsigned char d)
+{
+  outb(d, p->base + CONTROL);
+}
+
+unsigned char
+parport_hd64465_read_control(struct parport *p)
+{
+  return inb(p->base + CONTROL);
+}
+
+unsigned char
+parport_hd64465_frob_control(struct parport *p, unsigned char mask, unsigned char val)
+{
+  unsigned char old = inb(p->base + CONTROL);
+  outb(((old & ~mask) ^ val), p->base + CONTROL);
+  return old;
+}
+
+void
+parport_hd64465_write_status(struct parport *p, unsigned char d)
+{
+  outb(d, p->base + STATUS);
+}
+
+unsigned char
+parport_hd64465_read_status(struct parport *p)
+{
+  return inb(p->base + STATUS);
+}
+
+void
+parport_hd64465_write_econtrol(struct parport *p, unsigned char d)
+{
+  outb(d, p->base + ECONTROL);
+}
+
+unsigned char
+parport_hd64465_read_econtrol(struct parport *p)
+{
+  return inb(p->base + ECONTROL);
+}
+
+unsigned char
+parport_hd64465_frob_econtrol(struct parport *p, unsigned char mask, unsigned char val)
+{
+  unsigned char old = inb(p->base + ECONTROL);
+  outb(((old & ~mask) ^ val), p->base + ECONTROL);
+  return old;
+}
+
+void
+parport_hd64465_change_mode(struct parport *p, int m)
+{
+  parport_hd64465_frob_econtrol(p, 0xe0, m << 5);
+}
+
+void
+parport_hd64465_write_fifo(struct parport *p, unsigned char v)
+{
+  outb(v, p->base + DFIFO);
+}
+
+unsigned char
+parport_hd64465_read_fifo(struct parport *p)
+{
+  return inb(p->base + DFIFO);
+}
+
+void
+parport_hd64465_disable_irq(struct parport *p)
+{
+}
+
+void
+parport_hd64465_enable_irq(struct parport *p)
+{
+}
+
+void
+parport_hd64465_release_resources(struct parport *p)
+{
+  if (p->irq != PARPORT_IRQ_NONE) {
+    parport_hd64465_disable_irq(p);
+    free_irq(p->irq, p);
+  }
+}
+
+int
+parport_hd64465_claim_resources(struct parport *p)
+{
+  int err;
+  if (p->irq != PARPORT_IRQ_NONE) {
+    if ((err = request_irq(p->irq, parport_hd64465_interrupt,
+                          0, p->name, p)) != 0)
+      return err;
+    else
+      parport_hd64465_enable_irq(p);
+  }
+  return 0;
+}
+
+void
+parport_hd64465_init_state(struct parport_state *s)
+{
+  s->u.pc.ctr = 0xc;
+  s->u.pc.ecr = 0x0;
+}
+
+void
+parport_hd64465_save_state(struct parport *p, struct parport_state *s)
+{
+  s->u.pc.ctr = parport_hd64465_read_control(p);
+  s->u.pc.ecr = parport_hd64465_read_econtrol(p);
+}
+
+void
+parport_hd64465_restore_state(struct parport *p, struct parport_state *s)
+{
+  parport_hd64465_write_control(p, s->u.pc.ctr);
+  parport_hd64465_write_econtrol(p, s->u.pc.ecr);
+}
+
+size_t
+parport_hd64465_epp_read_block(struct parport *p, void *buf, size_t length)
+{
+  return 0;
+}
+
+size_t
+parport_hd64465_epp_write_block(struct parport *p, void *buf, size_t length)
+{
+  return 0;
+}
+
+int
+parport_hd64465_ecp_read_block(struct parport *p, void *buf, size_t length,
+                              void (*fn)(struct parport *, void *, size_t),
+                              void *handle)
+{
+  return 0;
+}
+
+int
+parport_hd64465_ecp_write_block(struct parport *p, void *buf, size_t length,
+                               void (*fn)(struct parport *, void *, size_t),
+                               void *handle)
+{
+  return 0;
+}
+
+void
+parport_hd64465_inc_use_count(void)
+{
+#ifdef MODULE
+  MOD_INC_USE_COUNT;
+#endif
+}
+
+void
+parport_hd64465_dec_use_count(void)
+{
+#ifdef MODULE
+  MOD_DEC_USE_COUNT;
+#endif
+}
+
+static void parport_hd64465_fill_inode(struct inode *inode, int fill)
+{
+#ifdef MODULE
+  if (fill)
+    MOD_INC_USE_COUNT;
+  else
+    MOD_DEC_USE_COUNT;
+#endif
+}
+#if 0
+static struct parport_operations parport_hd64465_ops =
+{
+  parport_hd64465_write_data,
+  parport_hd64465_read_data,
+
+  parport_hd64465_write_control,
+  parport_hd64465_read_control,
+  parport_hd64465_frob_control,
+
+  parport_hd64465_write_econtrol,
+  parport_hd64465_read_econtrol,
+  parport_hd64465_frob_econtrol,
+
+  parport_hd64465_write_status,
+  parport_hd64465_read_status,
+
+  parport_hd64465_write_fifo,
+  parport_hd64465_read_fifo,
+
+  parport_hd64465_change_mode,
+
+  parport_hd64465_release_resources,
+  parport_hd64465_claim_resources,
+
+  parport_hd64465_write_epp,
+  parport_hd64465_read_epp,
+  parport_hd64465_write_epp_addr,
+  parport_hd64465_read_epp_addr,
+  parport_hd64465_check_epp_timeout,
+
+  parport_hd64465_epp_write_block,
+  parport_hd64465_epp_read_block,
+
+  parport_hd64465_ecp_write_block,
+  parport_hd64465_ecp_read_block,
+
+  parport_hd64465_init_state,
+  parport_hd64465_save_state,
+  parport_hd64465_restore_state,
+
+  parport_hd64465_enable_irq,
+  parport_hd64465_disable_irq,
+  parport_hd64465_interrupt,
+
+  parport_hd64465_inc_use_count,
+  parport_hd64465_dec_use_count,
+  parport_hd64465_fill_inode
+};
+#endif
+static struct parport_operations parport_hd64465_ops =
+{
+  parport_hd64465_write_data,
+  parport_hd64465_read_data,
+
+  parport_hd64465_write_control,
+  parport_hd64465_read_control,
+  parport_hd64465_frob_control,
+
+  //parport_hd64465_write_econtrol,
+  //parport_hd64465_read_econtrol,
+  //parport_hd64465_frob_econtrol,
+
+  parport_hd64465_read_status,
+
+  parport_hd64465_enable_irq,
+  parport_hd64465_disable_irq,
+
+          //parport_pc_data_forward,
+	  //parport_pc_data_reverse,
+  
+  parport_hd64465_init_state,
+  parport_hd64465_save_state,
+  parport_hd64465_restore_state,
+
+  parport_hd64465_inc_use_count,
+  parport_hd64465_dec_use_count,
+/* kasu
+  parport_hd64465_write_epp,
+  parport_hd64465_read_epp,
+  parport_hd64465_write_epp_addr,
+  parport_hd64465_read_epp_addr,
+*/ 
+  parport_ieee1284_epp_write_data,
+  parport_ieee1284_epp_read_data,
+  parport_ieee1284_epp_write_addr,
+  parport_ieee1284_epp_read_addr,
+
+  parport_ieee1284_ecp_write_data,
+  parport_ieee1284_ecp_read_data,
+  parport_ieee1284_ecp_write_addr,
+
+  parport_ieee1284_write_compat,
+  parport_ieee1284_read_nibble,
+  parport_ieee1284_read_byte,	
+
+ /* 
+  parport_hd64465_write_fifo,
+  parport_hd64465_read_fifo,
+
+  parport_hd64465_change_mode,
+
+  parport_hd64465_release_resources,
+  parport_hd64465_claim_resources,
+
+  parport_hd64465_check_epp_timeout,
+
+  parport_hd64465_epp_write_block,
+  parport_hd64465_epp_read_block,
+
+  parport_hd64465_ecp_write_block,
+  parport_hd64465_ecp_read_block,
+
+
+  parport_hd64465_interrupt,
+
+  parport_hd64465_fill_inode
+
+  parport_hd64465_write_status,
+  */
+};
+
+
+/*
+ * Clear TIMEOUT BIT in EPP MODE
+ */
+int parport_hd64465_epp_clear_timeout(struct parport *pb)
+{
+  unsigned char r;
+
+  if (!(parport_hd64465_read_status(pb) & 0x01))
+    return 1;
+
+  /* To clear timeout some chips require double read */
+  parport_hd64465_read_status(pb);
+  r = parport_hd64465_read_status(pb);
+  parport_hd64465_write_status(pb, r | 0x01); /* Some reset by writing 1 */
+  parport_hd64465_write_status(pb, r & 0xfe); /* Others by writing 0 */
+  r = parport_hd64465_read_status(pb);
+
+  return !(r & 0x01);
+}
+
+/* Check for ECP
+ *
+ * Old style XT ports alias io ports every 0x400, hence accessing ECONTROL
+ * on these cards actually accesses the CTR.
+ *
+ * Modern cards don't do this but reading from ECONTROL will return 0xff
+ * regardless of what is written here if the card does NOT support
+ * ECP.
+ *
+ * We will write 0x2c to ECONTROL and 0xcc to CTR since both of these
+ * values are "safe" on the CTR since bits 6-7 of CTR are unused.
+ */
+static int parport_ECR_present(struct parport *pb)
+{
+  unsigned int r;
+  unsigned char octr = pb->ops->read_control(pb),
+    oecr = pb->ops->read_econtrol(pb);
+
+  r = pb->ops->read_control(pb);
+  if ((pb->ops->read_econtrol(pb) & 0x3) == (r & 0x3)) {
+    pb->ops->write_control(pb, r ^ 0x2 ); /* Toggle bit 1 */
+
+    r = pb->ops->read_control(pb);
+    if ((pb->ops->read_econtrol(pb) & 0x2) == (r & 0x2)) {
+      pb->ops->write_control(pb, octr);
+      return 0; /* Sure that no ECONTROL register exists */
+    }
+  }
+
+  if ((pb->ops->read_econtrol(pb) & 0x3 ) != 0x1)
+    return 0;
+
+  pb->ops->write_econtrol(pb, 0x34);
+  if (pb->ops->read_econtrol(pb) != 0x35)
+    return 0;
+
+  pb->ops->write_econtrol(pb, oecr);
+  pb->ops->write_control(pb, octr);
+
+/* yagi modified next 2 lines */
+/*  return PARPORT_MODE_PCECR; */
+  return PARPORT_MODE_DMA;
+}
+
+static int parport_ECP_supported(struct parport *pb)
+{
+  int i;
+  unsigned char oecr = pb->ops->read_econtrol(pb);
+
+  /* If there is no ECONTROL, we have no hope of supporting ECP. */
+/* yagi modified next 2 lines */
+/*  if (!(pb->modes & PARPORT_MODE_PCECR)) */
+  if (!(pb->modes & PARPORT_MODE_DMA))
+    return 0;
+
+  /*
+   * Using LGS chipset it uses ECONTROL register, but
+   * it doesn't support ECP or FIFO MODE
+   */
+
+  pb->ops->write_econtrol(pb, 0xc0); /* TEST FIFO */
+  for (i=0; i < 1024 && (pb->ops->read_econtrol(pb) & 0x01); i++)
+    pb->ops->write_fifo(pb, 0xaa);
+
+  pb->ops->write_econtrol(pb, oecr);
+/* yagi modified next 2 lines */
+/*  return (i == 1024) ? 0 : PARPORT_MODE_PCECP; */
+  return (i == 1024) ? 0 : PARPORT_MODE_ECP;
+}
+
+static int parport_PS2_supported(struct parport *pb)
+{
+  int ok = 0;
+  unsigned char octr = pb->ops->read_control(pb);
+
+  pb->ops->write_control(pb, octr | 0x20);
+
+  pb->ops->write_data(pb, 0x55);
+  if (pb->ops->read_data(pb) != 0x55) ok++;
+
+  pb->ops->write_data(pb, 0xaa);
+  if (pb->ops->read_data(pb) != 0xaa) ok++;
+
+  pb->ops->write_control(pb, octr);
+
+/* yagi modified next 2 lines */
+/*  return ok ? PARPORT_MODE_PCPS2 : 0; */
+  return ok ? PARPORT_MODE_TRISTATE : 0;
+}
+
+static int parport_ECPPS2_supported(struct parport *pb)
+{
+  int mode;
+  unsigned char oecr = pb->ops->read_econtrol(pb);
+
+/* yagi modified next 2 lines */
+/*  if (!(pb->modes & PARPORT_MODE_PCECR)) */
+  if (!(pb->modes & PARPORT_MODE_DMA))
+    return 0;
+
+  pb->ops->write_econtrol(pb, 0x20);
+
+  mode = parport_PS2_supported(pb);
+
+  pb->ops->write_econtrol(pb, oecr);
+
+/* yagi modified next 2 lines */
+/*  return mode ? PARPORT_MODE_PCECPPS2 : 0; */
+  return mode ? PARPORT_MODE_SAFEININT : 0;
+}
+
+/* yagi modified next 14 lines */
+/* #define printmode(x) \
+{ \
+  if (p->modes & PARPORT_MODE_PC##x) { \
+    printk("%s%s", f ? "," : "", #x); \
+    f++; \
+  } \
+} */
+#define printmode(x) \
+{ \
+  if (p->modes & PARPORT_MODE_##x) { \
+    printk("%s%s", f ? "," : "", #x); \
+    f++; \
+  } \
+}
+
+/* yagi added next 1 lines */
+void (*parport_probe_hook)(struct parport *port);
+
+int
+init_one_port(void)
+{
+  struct parport *p;
+  unsigned long base;
+  int irq, dma;
+
+/* yagi modified next 4 lines */
+/*  base = HD64465_IOBASE + 0xA000; */
+  base = CONFIG_HD64465_IOBASE + 0xA000;
+/*  irq  = HD64465_IRQBASE + 3; */
+  irq  = HD64465_IRQ_BASE + 3;
+  dma  = PARPORT_DMA_NONE;
+
+  if (!(p = parport_register_port(base, irq, dma, &parport_hd64465_ops)))
+    return 0;
+
+  p->modes = PARPORT_MODE_PCSPP | parport_PS2_supported(p);
+  p->modes |= parport_ECR_present(p);
+  p->modes |= parport_ECP_supported(p);
+  p->modes |= parport_ECPPS2_supported(p);
+  p->size = 3;
+
+  p->dma = PARPORT_DMA_NONE;
+
+  printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base);
+  if (p->irq != PARPORT_IRQ_NONE)
+    printk(", irq %d", p->irq);
+  printk(" [");
+  {
+    int f = 0;
+/* yagi modified next 8 lines */
+/*    printmode(SPP);
+    printmode(PS2);
+    printmode(ECP);
+    printmode(ECPPS2); */
+    printmode(PCSPP);
+    printmode(TRISTATE);
+    printmode(ECP);
+    printmode(SAFEININT);
+  }
+  printk("]\n");
+  parport_proc_register(p);
+
+/* yagi added next 1 line */
+  printk("yagi***init_one_port:1");
+  
+  p->flags |= PARPORT_FLAG_COMA;
+
+  p->ops->write_control(p, 0x0c);
+  p->ops->write_data(p, 0);
+
+  if (parport_probe_hook)
+    (*parport_probe_hook)(p);
+
+  return 1;
+}
+
+EXPORT_NO_SYMBOLS;
+
+#ifdef MODULE
+int init_module(void)
+#else
+/* yagi modified next 2 lines */
+/* __initfunc(int parport_hd64465_init(void)) */
+int __init parport_hd64465_init(void)
+#endif
+{
+  int count = 0;
+  count += init_one_port();
+
+/* yagi added next 1 line */
+  printk("yagi***parport_hd64465_init:init_one_port()=%d, count=%d\n",init_one_port(),count);
+
+  return count ? 0 : -ENODEV;
+}
+
+#ifdef MODULE
+void
+cleanup_module(void)
+{
+  struct parport *p = parport_enumerate(), *tmp;
+  while (p) {
+    tmp = p->next;
+    if (p->modes & PARPORT_MODE_PCSPP) {
+      if (!(p->flags & PARPORT_FLAG_COMA))
+       parport_quiesce(p);
+      parport_proc_unregister(p);
+      parport_unregister_port(p);
+    }
+    p = tmp;
+  }
+}
+#endif
diff -urN linux-2.4.29/drivers/pci/pci.ids linux-2.4.29-uc1/drivers/pci/pci.ids
--- linux-2.4.29/drivers/pci/pci.ids	2004-08-08 00:26:05.000000000 +0100
+++ linux-2.4.29-uc1/drivers/pci/pci.ids	2005-06-14 02:12:06.000000000 +0100
@@ -6109,6 +6109,8 @@
 1681  Hercules
 16ab  Global Sun Technology Inc
 	1102  PCMCIA-to-PCI Wireless Network Bridge
+16ae  Safenet Inc
+	1141  SafeXcel-1141
 16be  Creatix Polymedia GmbH
 16ca  CENATEK Inc
 	0001  Rocket Drive DL
diff -urN linux-2.4.29/drivers/pci/setup-bus.c linux-2.4.29-uc1/drivers/pci/setup-bus.c
--- linux-2.4.29/drivers/pci/setup-bus.c	2003-06-13 15:51:35.000000000 +0100
+++ linux-2.4.29-uc1/drivers/pci/setup-bus.c	2005-06-14 02:12:06.000000000 +0100
@@ -58,7 +58,8 @@
 		if (class == PCI_CLASS_DISPLAY_VGA
 				|| class == PCI_CLASS_NOT_DEFINED_VGA)
 			found_vga = 1;
-		else if (class >> 8 != PCI_BASE_CLASS_BRIDGE) {
+		else if (class >> 8 != PCI_BASE_CLASS_BRIDGE &&
+			 class >> 8 != PCI_BASE_CLASS_PROCESSOR) {
 			pci_read_config_word(dev, PCI_COMMAND, &cmd);
 			cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY
 						| PCI_COMMAND_MASTER);
diff -urN linux-2.4.29/drivers/pcmcia/Config.in linux-2.4.29-uc1/drivers/pcmcia/Config.in
--- linux-2.4.29/drivers/pcmcia/Config.in	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/pcmcia/Config.in	2005-06-14 02:12:20.000000000 +0100
@@ -43,6 +43,10 @@
    if [ "$CONFIG_VRC4173" = "y" -o "$CONFIG_VRC4173" = "m" ]; then
       dep_tristate '  NEC VRC4173 CARDU support' CONFIG_PCMCIA_VRC4173 $CONFIG_PCMCIA
    fi
+   if [ "$CONFIG_MACH_IVPN" = "y" ]; then
+      tristate '  Snapgear/IVPN IXP4xx socket services support' CONFIG_PCMCIA_IVPN
+      define_bool CONFIG_VIRTUAL_BUS y
+   fi
 fi
 
 endmenu
diff -urN linux-2.4.29/drivers/pcmcia/hd64465_ss.c linux-2.4.29-uc1/drivers/pcmcia/hd64465_ss.c
--- linux-2.4.29/drivers/pcmcia/hd64465_ss.c	2001-07-11 04:16:30.000000000 +0100
+++ linux-2.4.29-uc1/drivers/pcmcia/hd64465_ss.c	2005-06-14 02:12:20.000000000 +0100
@@ -262,6 +262,14 @@
 	/* insert ourselves as the irq controller */
 	hs_mapped_irq[irq].old_handler = irq_desc[irq].handler;
 	irq_desc[irq].handler = &hd64465_ss_irq_type;
+	/*
+	 * some drivers may not ever mess with there interrupts, so
+	 * we must make sure the interrupt for the slot is in the right state
+	 */
+	if (irq_desc[irq].status & IRQ_DISABLED)
+		hs_socket_disable_ireq(hs_mapped_irq[irq].sock);
+	else if ((irq_desc[irq].status & IRQ_INPROGRESS) == 0)
+		hs_socket_enable_ireq(hs_mapped_irq[irq].sock);
 }
 
 
@@ -660,6 +668,7 @@
 	    unsigned long pstart, psize, paddrbase, vaddrbase;
 	    
 	    paddrbase = virt_to_phys((void*)(sp->mem_base + 2 * HD64465_PCC_WINDOW));
+#ifndef CONFIG_SH_KEYWEST
 	    vaddrbase = (unsigned long)sp->io_vma->addr;
 	    pstart = io->start & PAGE_MASK;
 	    psize = ((io->stop + PAGE_SIZE) & PAGE_MASK) - pstart;
@@ -674,18 +683,17 @@
 	    DPRINTK("remap_page_range(vaddr=0x%08lx, paddr=0x%08lx, size=0x%08lxx)\n",
 	    	vaddrbase + pstart, paddrbase + pstart, psize);
 	    remap_page_range(vaddrbase + pstart, paddrbase + pstart, psize, prot);
+#else
+	    vaddrbase = paddrbase | 0xa0000000;
+#endif
 	    
 	    /*
 	     * Change the mapping used by inb() outb() etc
 	     */
-	    hd64465_port_map(
-	    	io->start,
-		io->stop - io->start + 1,
-	    	vaddrbase + io->start,0);
+	    mach_port_map(io->start, io->stop - io->start + 1,
+				vaddrbase + io->start, 0);
 	} else {
-	    hd64465_port_unmap(
-	    	sio->start,
-		sio->stop - sio->start + 1);
+	    mach_port_unmap(sio->start, sio->stop - sio->start + 1);
 	    /* TODO: remap_page_range() to mark pages not present ? */
 	}
 	
diff -urN linux-2.4.29/drivers/pcmcia/ivpnss.c linux-2.4.29-uc1/drivers/pcmcia/ivpnss.c
--- linux-2.4.29/drivers/pcmcia/ivpnss.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/pcmcia/ivpnss.c	2005-06-14 02:12:20.000000000 +0100
@@ -0,0 +1,836 @@
+/****************************************************************************/
+
+/*
+ *	ivpnss.c -- PCMCIA socket services for IXP4xx/iVPN board.
+ *
+ *	(C) Copyright 2004, Greg Ungerer <gerg@snapgear.com>
+ */
+
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/hardware.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/bus_ops.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/ss.h>
+
+#include <asm/arch/ivpnss.h>
+
+/****************************************************************************/
+
+#define	IVPNSS_NAME	"ivpnss"
+
+MODULE_DESCRIPTION("SnapGear/iVPN (IXP4xx) socket service driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.org>");
+
+/****************************************************************************/
+
+static void *ivpnss_map8bit;
+static unsigned int ivpnss_8bit;
+static void *ivpnss_map16bit;
+static unsigned int ivpnss_16bit;
+
+/*
+ *	Set the maximum region size to be 1MB, should be plenty.
+ */
+#define	IVPNSS_MEM_SIZE	0x00010000
+#define	IVPNSS_IO_OFFSET 0x10000
+
+/****************************************************************************/
+
+/*
+ *	Code to enablde the memory map to access different regions of
+ *	the PCMCIA/CF address space. We can only look into one region
+ *	at a time from the CPU address space.
+ */
+#define	MODE_UNKNOWN	0
+#define	MODE_ATTRIBUTE	1
+#define	MODE_IO		2
+#define	MODE_MEM	3
+
+static int ivpnss_mem_mode;
+
+static void __inline__ ivpnss_enable_attribute(void)
+{
+	gpio_line_set(IXP425_GPIO_PIN_10, 0);	/*REG*/
+	gpio_line_set(IXP425_GPIO_PIN_8, 0);	/*IO/MEM*/
+}
+
+static void __inline__ ivpnss_enable_io(void)
+{
+	gpio_line_set(IXP425_GPIO_PIN_10, 0);	/*REG*/
+	gpio_line_set(IXP425_GPIO_PIN_8, 1);	/*IO/MEM*/
+}
+
+static void __inline__ ivpnss_enable_mem(void)
+{
+	gpio_line_set(IXP425_GPIO_PIN_10, 1);	/*REG*/
+	gpio_line_set(IXP425_GPIO_PIN_8, 0);	/*IO/MEM*/
+}
+
+static void ivpnss_enable_mode(int mode)
+{
+	switch (mode) {
+	case MODE_ATTRIBUTE:
+		ivpnss_enable_attribute();
+		break;
+	case MODE_IO:
+		ivpnss_enable_io();
+		break;
+	default:
+		ivpnss_enable_mem();
+		break;
+	}
+}
+
+/****************************************************************************/
+
+static int ivpnss_hwinited;
+
+void ivpnss_hwsetup(void)
+{
+	int i;
+
+	if (ivpnss_hwinited)
+		return;
+
+	/* Setup IXP4xx chip selects, CS1 is for 8bit, CS2 is 16bit */
+	*IXP425_EXP_CS1 = 0x97d10c03;
+	*IXP425_EXP_CS2 = 0x97d10c02;
+
+	/* expansion bus speeds */
+//	*IXP425_GPIO_GPCLKR = (*IXP425_GPIO_GPCLKR & 0x0000ffff) | 0x01420000;
+
+	/* Setup IRQ line, we use GPIO7 which maps tp IRQ 24 */
+	gpio_line_config(IXP425_GPIO_PIN_7,
+		(IXP425_GPIO_IN | IXP425_GPIO_FALLING_EDGE));
+	gpio_line_isr_clear(IXP425_GPIO_PIN_7);
+
+	/* Setup PCMCIA/CF REG line (for accessing attribute space) */
+	gpio_line_config(IXP425_GPIO_PIN_10, IXP425_GPIO_OUT);
+	gpio_line_set(IXP425_GPIO_PIN_10, 1);
+
+	/* Setup PCMCIA/CF IO/MEM (confusingly called RD/WR) select */
+	gpio_line_config(IXP425_GPIO_PIN_8, IXP425_GPIO_OUT);
+	gpio_line_set(IXP425_GPIO_PIN_10, 1);
+
+	/* Setup PCMCIA/CF RESET line, and issue a short reset */
+	gpio_line_set(IXP425_GPIO_PIN_6, 0);
+	gpio_line_config(IXP425_GPIO_PIN_6, IXP425_GPIO_OUT);
+	/*
+	for (i = 0; (i < 100); i++)
+		udelay(1000);
+	gpio_line_set(IXP425_GPIO_PIN_6, 1);
+	*/
+
+	/* Leave the region idling in "attribute" mode */
+	ivpnss_mem_mode = MODE_ATTRIBUTE;
+	ivpnss_enable_attribute();
+
+	ivpnss_hwinited = 1;
+}
+
+/****************************************************************************/
+
+u32 ivpnss_in(void *bus, u32 port, s32 sz)
+{
+	unsigned long flags;
+	u32 val = 0;
+
+	if (port >= IVPNSS_IO_OFFSET)
+		port -= IVPNSS_IO_OFFSET;
+
+	save_flags(flags); cli();
+	ivpnss_enable_io();
+	if (sz == 0)
+		val = readb(ivpnss_8bit + port);
+	else if (sz == 1)
+		val = readw(ivpnss_16bit + port);
+	else if (sz == 2)
+		val = readl(ivpnss_16bit + port);
+	else
+		printk("%s(%d): bad size, sz=%x\n", __FILE__, __LINE__, sz);
+	restore_flags(flags);
+
+#ifdef DEBUG
+	printk("ivpnss_in(bus=%x,port=%x,sz=%x)=0x%04x\n", (int)bus, port, sz, val);
+#endif
+	return val;
+}
+
+/****************************************************************************/
+
+void ivpnss_ins(void *bus, u32 port, void *buf, u32 count, s32 sz)
+{
+	u8 *bbuf = (u8 *) buf;
+	u16 *wbuf = (u16 *) buf;
+	u32 *lbuf = (u32 *) buf;
+	unsigned long flags;
+
+#ifdef DEBUG
+	printk("ivpnss_ins(bus=%x,port=%x,buf=%x,count=%d,sz=%x)\n",
+		(int)bus, port, (int)buf, count, sz);
+#endif
+
+	if (port >= IVPNSS_IO_OFFSET)
+		port -= IVPNSS_IO_OFFSET;
+
+	if ((sz != 0) && (sz != 1) && (sz != 2)) {
+		printk("%s(%d): bad size, sz=%x\n", __FILE__, __LINE__, sz);
+		return;
+	}
+
+	save_flags(flags); cli();
+	ivpnss_enable_io();
+	for (; (count); count--) {
+		if (sz == 0)
+			*bbuf++ = readb(ivpnss_8bit + port);
+		else if (sz == 1)
+			*wbuf++ = cpu_to_le16(readw(ivpnss_16bit + port));
+		else if (sz == 2)
+			*lbuf++ = cpu_to_le32(readl(ivpnss_16bit + port));
+	}
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+
+void ivpnss_out(void *bus, u32 val, u32 port, s32 sz)
+{
+	unsigned long flags;
+
+#ifdef DEBUG
+	printk("ivpnss_out(bus=%x,val=%x,port=%x,sz=%x)\n",
+		(int)bus, val, port, sz);
+#endif
+
+	if (port >= IVPNSS_IO_OFFSET)
+		port -= IVPNSS_IO_OFFSET;
+
+	save_flags(flags); cli();
+	ivpnss_enable_io();
+	if (sz == 0)
+		writeb(val, ivpnss_8bit + port);
+	else if (sz == 1)
+		writew(val, ivpnss_16bit + port);
+	else if (sz == 2)
+		writel(val, ivpnss_16bit + port);
+	else
+		printk("%s(%d): bad size, sz=%x\n", __FILE__, __LINE__, sz);
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+
+void ivpnss_outs(void *bus, u32 port, void *buf, u32 count, s32 sz)
+{
+	unsigned long flags;
+	u8 *bbuf = (u8 *) buf;
+	u16 *wbuf = (u16 *) buf;
+	u32 *lbuf = (u32 *) buf;
+
+#ifdef DEBUG
+	printk("ivpnss_outs(bus=%x,port=%x,buf=%x,count=%d,sz=%x)\n",
+		(int)bus, port, (int)buf, count, sz);
+#endif
+
+	if (port >= IVPNSS_IO_OFFSET)
+		port -= IVPNSS_IO_OFFSET;
+
+	if ((sz != 0) && (sz != 1) && (sz != 2)) {
+		printk("%s(%d): bad size, sz=%x\n", __FILE__, __LINE__, sz);
+		return;
+	}
+
+	save_flags(flags); cli();
+	ivpnss_enable_io();
+	for (; (count); count--) {
+		if (sz == 0)
+			writeb(*bbuf++, ivpnss_8bit + port);
+		else if (sz == 1)
+			writew(cpu_to_le16(*wbuf++), ivpnss_16bit + port);
+		else if (sz == 2)
+			writel(cpu_to_le32(*lbuf++), ivpnss_16bit + port);
+	}
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+
+static void *ivpnss_ioremap(void *bus, u_long ofs, u_long sz)
+{
+#ifdef DEBUG
+	printk("ivpnss_ioremap(bus=%x,ofs=%x,sz=%x)\n",
+		(int)bus, (int)ofs, (int)sz);
+#endif
+
+	return NULL;
+}
+
+/****************************************************************************/
+
+static void ivpnss_iounmap(void *bus, void *addr)
+{
+#ifdef DEBUG
+	printk("ivpnss_iounmap(bus=%x,addr=%x)\n", (int)bus, (int)addr);
+#endif
+}
+
+/****************************************************************************/
+
+static u32 ivpnss_readmem(void *bus, void *addr, s32 sz)
+{
+	unsigned long flags;
+	u32 val = 0;
+	u32 ofs = (u32) addr;
+
+	save_flags(flags); cli();
+	ivpnss_enable_mode(ivpnss_mem_mode);
+	if (sz == 0)
+		val = readb(ivpnss_8bit + ofs);
+	else if (sz == 1)
+		val = readw(ivpnss_16bit + ofs);
+	else if (sz == 2)
+		val = readl(ivpnss_16bit + ofs);
+	else
+		printk("%s(%d): bad size, sz=%x\n", __FILE__, __LINE__, sz);
+	restore_flags(flags);
+
+#ifdef DEBUG
+	printk("ivpnss_readmem(bus=%x,addr=%x,sz=%x)[mode=%d]=0x%04x\n",
+		(int)bus, (int)addr, sz, ivpnss_mem_mode, val);
+#endif
+
+	return val;
+}
+
+/****************************************************************************/
+
+static void ivpnss_copy_from(void *bus, void *d, void *s, u32 count)
+{
+	unsigned long flags;
+	u8 *dbuf = d;
+	u32 ofs = (u32) s;
+
+#ifdef DEBUG
+	printk("ivpnss_copy_from(bus=%x,d=%x,s=%x,count=%d)\n",
+		(int)bus, (int)d, (int)s, count);
+#endif
+
+	save_flags(flags); cli();
+	ivpnss_enable_mode(ivpnss_mem_mode);
+	for (; (count); count--)
+		*dbuf++ = readb(ivpnss_8bit + ofs++);
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+
+static void ivpnss_writemem(void *bus, u32 val, void *addr, s32 sz)
+{
+	unsigned long flags;
+	u32 ofs = (u32) addr;
+
+#ifdef DEBUG
+	printk("ivpnss_writemem(bus=%x,val=%x,addr=%x,sz=%x) [mode=%d]\n",
+		(int)bus, val, (int)addr, sz, ivpnss_mem_mode);
+#endif
+
+	save_flags(flags); cli();
+	ivpnss_enable_mode(ivpnss_mem_mode);
+	if (sz == 0)
+		writeb(val, ivpnss_8bit + ofs);
+	else if (sz == 1)
+		writew(val, ivpnss_16bit + ofs);
+	else if (sz == 2)
+		writel(val, ivpnss_16bit + ofs);
+	else
+		printk("%s(%d): bad size, sz=%x\n", __FILE__, __LINE__, sz);
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+
+static void ivpnss_copy_to(void *bus, void *d, void *s, u32 count)
+{
+	unsigned long flags;
+	u8 *sbuf = s;
+	u32 ofs = (u32) d;
+
+#ifdef DEBUG
+	printk("ivpnss_copy_from(bus=%x,d=%x,s=%x,count=%d)\n",
+		(int)bus, (int)d, (int)s, count);
+#endif
+
+	save_flags(flags); cli();
+	ivpnss_enable_mode(ivpnss_mem_mode);
+	for (; (count); count--)
+		writeb(*sbuf++, ivpnss_8bit + ofs++);
+	restore_flags(flags);
+}
+
+/****************************************************************************/
+
+/*
+ *	Wee need to vector through our local handler first, so that
+ *	we can clear the interrupt at the IXP425 GPIO line.
+ */
+static void (*ivpnss_handler)(int, void *, struct pt_regs *);
+
+static void ivpnss_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	gpio_line_isr_clear(IXP425_GPIO_PIN_7);
+
+	if (ivpnss_handler)
+		ivpnss_handler(irq, dev_id, regs);
+}
+
+static int ivpnss_request_irq(void *bus, u_int irq, void (*handler)(int, void *, struct pt_regs *), u_long flags, const char *device, void *dev_id)
+{
+#ifdef DEBUG
+	printk("ivpnss_request_irq(bus=%x,irq=%d,handler=%x,flags=%x,"
+		"device=%x,dev_id=%x)\n", (int)bus, irq, (int)handler,
+		(int)flags, (int)device, (int)dev_id);
+#endif
+
+	ivpnss_handler = handler;
+	if (request_irq(irq, ivpnss_isr, flags, device, dev_id)) {
+		printk("IVPNSS: failed to get interrupt %d?\n", irq);
+		return -EBUSY;
+	}
+	return 0;
+}
+
+/****************************************************************************/
+
+static void ivpnss_free_irq(void *bus, u_int irq, void *dev_id)
+{
+#ifdef DEBUG
+	printk("ivpnss_free_irq(bus=%x,irq=%d,dev_id=%x)\n",
+		(int)bus, irq, (int)dev_id);
+#endif
+	ivpnss_handler = NULL;
+	free_irq(irq, dev_id);
+}
+
+/****************************************************************************/
+
+/*
+ *	When using other drivers as modules we need to export these
+ *	IO access functions.
+ */
+EXPORT_SYMBOL(ivpnss_out);
+EXPORT_SYMBOL(ivpnss_in);
+EXPORT_SYMBOL(ivpnss_outs);
+EXPORT_SYMBOL(ivpnss_ins);
+
+/****************************************************************************/
+
+static struct bus_operations ivpnss_busops = {
+	.b_in = ivpnss_in,
+	.b_ins = ivpnss_ins,
+	.b_out = ivpnss_out,
+	.b_outs = ivpnss_outs,
+	.b_ioremap = ivpnss_ioremap,
+	.b_iounmap = ivpnss_iounmap,
+	.b_read = ivpnss_readmem,
+	.b_write = ivpnss_writemem,
+	.b_copy_from = ivpnss_copy_from,
+	.b_copy_to = ivpnss_copy_to,
+	.b_request_irq = ivpnss_request_irq,
+	.b_free_irq = ivpnss_free_irq,
+};
+
+/****************************************************************************/
+
+static socket_cap_t ivpnss_socket_cap = {
+	.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP | SS_CAP_VIRTUAL_BUS,
+	.irq_mask = 0xffff,
+	.pci_irq = 24,
+	.map_size = 0x1000,
+	.io_offset = IVPNSS_IO_OFFSET,
+	.bus = &ivpnss_busops,
+};
+
+/****************************************************************************/
+
+static int ivpnss_ssinit(unsigned int sock)
+{
+#ifdef DEBUG
+	printk("ivpnss_ssinit(sock=%d)\n", sock);
+#endif
+	return 0;
+}
+
+/****************************************************************************/
+
+static int ivpnss_suspend(unsigned int sock)
+{
+#ifdef DEBUG
+	printk("ivpnss_suspend(sock=%d)\n", sock);
+#endif
+	return 0;
+}
+
+/****************************************************************************/
+
+static int ivpnss_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void *info)
+{
+#ifdef DEBUG
+	printk("ivpnss_callback(sock=%d,handler=%x,info=%x)\n",
+		sock, (int)handler, (int)info);
+#endif
+	return 0;
+}
+
+/****************************************************************************/
+
+static int ivpnss_inquire_socket(unsigned int sock, socket_cap_t *cap)
+{
+#ifdef DEBUG
+	printk("ivpnss_inquire_socket(sock=%d,cap=%x)\n", sock, (int)cap);
+#endif
+	*cap = ivpnss_socket_cap;
+	return 0;
+}
+
+/****************************************************************************/
+
+static int ivpnss_get_status(unsigned int sock, unsigned int *value)
+{
+#ifdef DEBUG
+	printk("ivpnss_get_status(sock=%d,value=%x)\n", sock, (int)value);
+#endif
+	*value = SS_DETECT | SS_READY | SS_3VCARD;
+	return 0;
+}
+
+/****************************************************************************/
+
+static int ivpnss_get_socket(unsigned int sock, socket_state_t *state)
+{
+#ifdef DEBUG
+	printk("ivpnss_get_socket(sock=%d,state=%x)\n", sock, (int)state);
+#endif
+	return 0;
+}
+
+/****************************************************************************/
+
+static int ivpnss_set_socket(unsigned int sock, socket_state_t *state)
+{
+#ifdef DEBUG
+	printk("ivpnss_set_socket(sock=%d,state=%x)\n", sock, (int)state);
+#endif
+	return 0;
+}
+
+/****************************************************************************/
+
+static int ivpnss_get_io_map(unsigned int sock, struct pccard_io_map *io)
+{
+#ifdef DEBUG
+	printk("ivpnss_get_io_map(sock=%d,io=%x)\n", sock, (int)io);
+#endif
+	return 0;
+}
+
+/****************************************************************************/
+
+static int ivpnss_set_io_map(unsigned int sock, struct pccard_io_map *io)
+{
+#ifdef DEBUG
+	printk("ivpnss_set_io_map(sock=%d,io=%x)\n", sock, (int)io);
+#endif
+	return 0;
+}
+
+/****************************************************************************/
+
+static int ivpnss_get_mem_map(unsigned int sock, struct pccard_mem_map *mem)
+{
+#ifdef DEBUG
+	printk("ivpnss_get_mem_map(sock=%d,mem=%x)\n", sock, (int)mem);
+#endif
+	return 0;
+}
+
+/****************************************************************************/
+
+static int ivpnss_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
+{
+#ifdef DEBUG
+	printk("ivpnss_set_mem_map(sock=%d,mem=%x)\n", sock, (int)mem);
+#endif
+
+	ivpnss_mem_mode = (mem->flags & MAP_ATTRIB) ? MODE_ATTRIBUTE : MODE_MEM;
+	return 0;
+}
+
+/****************************************************************************/
+
+static void ivpnss_proc_setup(unsigned int sock, struct proc_dir_entry *base)
+{
+#ifdef DEBUG
+	printk("ivpnss_proc_setup(sock=%d,base=%x)\n", sock, (int)base);
+#endif
+}
+
+/****************************************************************************/
+
+static struct pccard_operations ivpnss_operations = {
+	.init = ivpnss_ssinit,
+	.suspend = ivpnss_suspend,
+	.register_callback = ivpnss_register_callback,
+	.inquire_socket = ivpnss_inquire_socket,
+	.get_status = ivpnss_get_status,
+	.get_socket = ivpnss_get_socket,
+	.set_socket = ivpnss_set_socket,
+	.get_io_map = ivpnss_get_io_map,
+	.set_io_map = ivpnss_set_io_map,
+	.get_mem_map = ivpnss_get_mem_map,
+	.set_mem_map = ivpnss_set_mem_map,
+	.proc_setup = ivpnss_proc_setup,
+};
+
+/****************************************************************************/
+
+/*
+ *	This driver also has a character device interface. Very useful
+ *	for debugging, but we really need it to implement the ioctl
+ *	support for enabling and disabling ethernet and Wifi hardware
+ *	ports.
+ */
+#define	IVPNSS_MAJOR	120
+
+/****************************************************************************/
+
+static ssize_t ivpnss_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
+{
+	unsigned short *wbuf = (unsigned short *) buf;
+	unsigned int addr, mindev;
+	int i, end, width;
+
+#ifdef DEBUG
+	printk("ivpnss_read(filp=%x,buf=%x,count=%d,ppos=%x)\n",
+		(int)filp, (int)buf, count, (int)ppos);
+#endif
+
+	mindev = MINOR(filp->f_dentry->d_inode->i_rdev);
+
+	switch (mindev & 0x6) {
+	case 0x2: ivpnss_enable_mem(); break;
+	case 0x4: ivpnss_enable_attribute(); break;
+	default:  ivpnss_enable_io(); break;
+	}
+
+	width = (mindev & 1) + 1;
+	addr = (unsigned int) ((width == 1) ? ivpnss_8bit : ivpnss_16bit);
+
+	if ((i = *ppos) >= IVPNSS_MEM_SIZE)
+		return 0;
+	if ((i + count) > IVPNSS_MEM_SIZE)
+		count = IVPNSS_MEM_SIZE - i;
+	for (end = i + count; (i < end); i += width) {
+		if (width == 1)
+			put_user(readb(addr+i), buf++);
+		else
+			put_user(readw(addr+i), wbuf++);
+	}
+
+	*ppos = i;
+	return count;
+}
+
+/****************************************************************************/
+
+static ssize_t ivpnss_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
+{
+	unsigned short *wbuf = (unsigned short *) buf;
+	unsigned int addr, mindev;
+	unsigned short wval;
+	unsigned char val = 0;
+	int i, end, width;
+
+#ifdef DEBUG
+	printk("ivpnss_write(filp=%x,buf=%x,count=%d,ppos=%x)\n",
+		(int)filp, (int)buf, count, (int)ppos);
+#endif
+
+	mindev = MINOR(filp->f_dentry->d_inode->i_rdev);
+
+	switch (mindev & 0x6) {
+	case 0x2: ivpnss_enable_mem(); break;
+	case 0x4: ivpnss_enable_attribute(); break;
+	default:  ivpnss_enable_io(); break;
+	}
+
+	width = (mindev & 1) + 1;
+	addr = (unsigned int) ((width == 1) ? ivpnss_8bit : ivpnss_16bit);
+
+	if ((i = *ppos) >= IVPNSS_MEM_SIZE)
+		return 0;
+	if ((i + count) > IVPNSS_MEM_SIZE)
+		count = IVPNSS_MEM_SIZE - i;
+	for (end = i + count; (i < end); i += width) {
+		if (width == 1) {
+			get_user(val, buf++);
+			writeb(val, addr+i);
+		} else {
+			get_user(wval, wbuf++);
+			writew(wval, addr+i);
+		}
+	}
+
+	*ppos = i;
+	return count;
+}
+
+/****************************************************************************/
+
+static loff_t ivpnss_lseek(struct file *file, loff_t offset, int orig)
+{
+	switch (orig) {
+	case 0:
+		file->f_pos = offset;
+		break;
+	case 1:
+		file->f_pos += offset;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return file->f_pos;
+}
+
+/****************************************************************************/
+
+static int ivpnss_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+
+	case ISET_ETH0:
+		printk("%s(%d): cannot disable eth0!\n", __FILE__, __LINE__);
+		break;
+
+	case ISET_ETH1:
+		/* Enable/disable second ethernet port */
+		if (arg)
+			gpio_line_set(IXP425_GPIO_PIN_3, 0);
+		else
+			gpio_line_set(IXP425_GPIO_PIN_3, 1);
+		break;
+
+	case ISET_WIFI0:
+		/* Best I can figure is to hold the device in reset */
+		if (arg)
+			gpio_line_set(IXP425_GPIO_PIN_6, 1);
+		else
+			gpio_line_set(IXP425_GPIO_PIN_6, 0);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
+
+static struct file_operations ivpnss_fops = {
+	.read = ivpnss_read,
+	.write = ivpnss_write,
+	.llseek = ivpnss_lseek,
+	.ioctl = ivpnss_ioctl,
+};
+
+/****************************************************************************/
+
+int ivpnss_memmap(void)
+{
+	/* Check if already initialized */
+	if (ivpnss_map8bit)
+		return 0;
+
+	ivpnss_map8bit = ioremap(IXP425_EXP_BUS_CS1_BASE_PHYS, IVPNSS_MEM_SIZE);
+	if (ivpnss_map8bit == NULL) {
+		printk("iVPNSS: failed to ioremap 8bit memory region?\n");
+		return -ENOMEM;
+	}
+
+	ivpnss_map16bit = ioremap(IXP425_EXP_BUS_CS2_BASE_PHYS, IVPNSS_MEM_SIZE);
+	if (ivpnss_map16bit == NULL) {
+		iounmap(ivpnss_map8bit);
+		ivpnss_map8bit = NULL;
+		printk("iVPNSS: failed to ioremap 16bit memory region?\n");
+		return -ENOMEM;
+	}
+
+	ivpnss_8bit = (unsigned int) ivpnss_map8bit;
+	ivpnss_16bit = (unsigned int) ivpnss_map16bit;
+	return 0;
+}
+
+/****************************************************************************/
+
+static int __init ivpnss_init(void)
+{
+	servinfo_t serv;
+	int rc;
+
+	printk("iVPNSS: IXP4xx/iVPN socket service driver\n" \
+		"(C) Copyright 2004, Greg Ungerer <gerg@snapgear.com>\n");
+
+	ivpnss_hwsetup();
+	if ((rc = ivpnss_memmap()))
+		return rc;
+
+	pcmcia_get_card_services_info(&serv);
+	if (serv.Revision != CS_RELEASE_CODE) {
+		printk("iVPNSS: Card Services version mis-match!\n");
+		return -ENODEV;
+	}
+
+	if (register_ss_entry(1, &ivpnss_operations)) {
+		printk("iVPNSS: failed to register socket service?\n");
+		return -ENODEV;
+	}
+
+	if (register_chrdev(IVPNSS_MAJOR, IVPNSS_NAME, &ivpnss_fops))
+		printk("iVPNSS: failed to register debug char device?\n");
+
+	return 0;
+}
+
+/****************************************************************************/
+
+static void __exit ivpnss_exit(void)
+{
+	unregister_ss_entry(&ivpnss_operations);
+
+	if (ivpnss_map8bit)
+		iounmap(ivpnss_map8bit);
+	if (ivpnss_map16bit)
+		iounmap(ivpnss_map16bit);
+
+	unregister_chrdev(IVPNSS_MAJOR, IVPNSS_NAME);
+}
+
+/****************************************************************************/
+
+module_init(ivpnss_init);
+module_exit(ivpnss_exit);
+
+/****************************************************************************/
diff -urN linux-2.4.29/drivers/pcmcia/Makefile linux-2.4.29-uc1/drivers/pcmcia/Makefile
--- linux-2.4.29/drivers/pcmcia/Makefile	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/pcmcia/Makefile	2005-06-14 02:12:20.000000000 +0100
@@ -10,7 +10,7 @@
 
 O_TARGET := pcmcia.o
 
-export-objs := ds.o cs.o yenta.o pci_socket.o
+export-objs := ds.o cs.o yenta.o pci_socket.o ivpnss.o
 
 list-multi := pcmcia_core.o yenta_socket.o
 
@@ -65,6 +65,7 @@
 au1000_ss-objs-$(CONFIG_PCMCIA_DB1X00)		+= au1000_db1x00.o
 au1000_ss-objs-$(CONFIG_PCMCIA_XXS1500) 	+= au1000_xxs1500.o
 
+obj-$(CONFIG_PCMCIA_EP9315)	+= ep9315_pcmcia.o
 obj-$(CONFIG_PCMCIA_SA1100)	+= sa1100_cs.o
 obj-$(CONFIG_PCMCIA_M8XX)	+= m8xx_pcmcia.o
 obj-$(CONFIG_PCMCIA_SIBYTE)	+= sibyte_generic.o
@@ -90,6 +91,7 @@
 sa1100_cs-objs-$(CONFIG_SA1100_YOPY)		+= sa1100_yopy.o
 
 obj-$(CONFIG_PCMCIA_VRC4173)	+= vrc4173_cardu.o
+obj-$(CONFIG_PCMCIA_IVPN)	+= ivpnss.o
 
 include $(TOPDIR)/Rules.make
 
diff -urN linux-2.4.29/drivers/pcmcia/yenta.c linux-2.4.29-uc1/drivers/pcmcia/yenta.c
--- linux-2.4.29/drivers/pcmcia/yenta.c	2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.29-uc1/drivers/pcmcia/yenta.c	2005-06-14 02:12:20.000000000 +0100
@@ -683,6 +683,13 @@
 			CB_3VCARD | CB_XVCARD | CB_YVCARD)))
 		
 	cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
+
+#ifdef CONFIG_SH_SECUREEDGE5410
+	/* for some reason we have to force the IRQ onto the bridge PCI irq */
+	bridge = config_readw(socket, 0x8c);
+	bridge = (bridge & ~0xf) | 0x2;
+	config_writew(socket, 0x8c, bridge);
+#endif
 }
 
 /* Called at resume and initialization events */
diff -urN linux-2.4.29/drivers/scsi/scsi_dma.c linux-2.4.29-uc1/drivers/scsi/scsi_dma.c
--- linux-2.4.29/drivers/scsi/scsi_dma.c	2002-02-25 19:38:04.000000000 +0000
+++ linux-2.4.29-uc1/drivers/scsi/scsi_dma.c	2005-06-14 02:12:21.000000000 +0100
@@ -30,6 +30,15 @@
 typedef unsigned char FreeSectorBitmap;
 #elif SECTORS_PER_PAGE <= 32
 typedef unsigned int FreeSectorBitmap;
+#elif SECTORS_PER_PAGE <= 64
+#if 0
+typedef unsigned long long FreeSectorBitmap;
+#else
+typedef struct {
+	unsigned long l,h;
+} FreeSectorBitmap;
+#define LARGE_MALLOC
+#endif
 #else
 #error You lose.
 #endif
@@ -69,6 +78,7 @@
  *              to allocate more memory in order to be able to write the
  *              data to disk, you would wedge the system.
  */
+#ifndef LARGE_MALLOC
 void *scsi_malloc(unsigned int len)
 {
 	unsigned int nbits, mask;
@@ -167,6 +177,97 @@
 	panic("scsi_free:Bad offset");
 }
 
+#else
+
+void *scsi_malloc(unsigned int len)
+{
+	unsigned int nbits;
+	unsigned long maskl, maskh, flags;
+	FreeSectorBitmap *fsb;
+	int i;
+
+	if (len % SECTOR_SIZE != 0 || len > PAGE_SIZE)
+		return NULL;
+
+	save_flags_cli (flags);
+	nbits = len >> 9;
+	if (nbits < 32) {
+		maskl = (1 << nbits) - 1;
+		maskh = 0;
+	} else {
+		maskl = (unsigned long)-1;
+		maskh = (1 << (nbits - 32)) - 1;
+	}
+
+	fsb = dma_malloc_freelist;
+
+	for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++) {
+		unsigned long mml, mmh;
+		int j;
+		mml = maskl;
+		mmh = maskh;
+		j = 0;
+		do {
+			if ((fsb->l & mml) == 0 && (fsb->h & mmh) == 0) {
+				fsb->h |= mmh;
+				fsb->l |= mml;
+				restore_flags (flags);
+				scsi_dma_free_sectors -= nbits;
+#ifdef DEBUG
+				printk("SMalloc: %d %p\n",len, dma_malloc_pages[i] + (j << 9));
+#endif
+				return (void *) ((unsigned long) dma_malloc_pages[i] + (j << 9));
+			}
+			mmh = (mmh << 1) | (mml >> 31);
+			mml <<= 1;
+			j++;
+		} while (!(mmh & (1 << 31)));
+		fsb ++;
+	}
+	return NULL;  /* Nope.  No more */
+}
+
+int scsi_free(void *obj, unsigned int len)
+{
+	unsigned int page, sector, nbits;
+	unsigned long maskl, maskh, flags;
+
+#ifdef DEBUG
+	printk("scsi_free %p %d\n",obj, len);
+#endif
+
+	for (page = 0; page < dma_sectors / SECTORS_PER_PAGE; page++) {
+		unsigned long page_addr = (unsigned long) dma_malloc_pages[page];
+		if ((unsigned long) obj >= page_addr &&
+		    (unsigned long) obj < page_addr + PAGE_SIZE) {
+			sector = (((unsigned long) obj) - page_addr) >> 9;
+			nbits = len >> 9;
+			if (nbits < 32) {
+				maskl = (1 << nbits) - 1;
+				maskh = 0;
+			} else {
+				maskl = (unsigned long)-1;
+				maskh = (1 << (nbits - 32)) - 1;
+			}
+			if ((sector + nbits) > SECTORS_PER_PAGE)
+				panic ("scsi_free:Bad memory alignment");
+			maskh = (maskh << sector) | (maskl >> (32 - sector));
+			maskl = maskl << sector;
+			save_flags_cli(flags);
+			if (((dma_malloc_freelist[page].l & maskl) != maskl) ||
+			    ((dma_malloc_freelist[page].h & maskh) != maskh))
+				panic("scsi_free:Trying to free unused memory");
+			scsi_dma_free_sectors += nbits;
+			dma_malloc_freelist[page].l &= ~maskl;
+			dma_malloc_freelist[page].h &= ~maskh;
+			restore_flags(flags);
+			return 0;
+		}
+	}
+	panic("scsi_free:Bad offset");
+}
+#endif
+
 
 /*
  * Function:    scsi_resize_dma_pool
diff -urN linux-2.4.29/drivers/serial/21285.c linux-2.4.29-uc1/drivers/serial/21285.c
--- linux-2.4.29/drivers/serial/21285.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/serial/21285.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,599 @@
+/*
+ * linux/drivers/char/serial_21285.c
+ *
+ * Driver for the serial port on the 21285 StrongArm-110 core logic chip.
+ *
+ * Based on drivers/char/serial.c
+ *
+ *  $Id: 21285.c,v 1.4.2.1 2002/10/24 09:53:23 rmk Exp $
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/major.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/console.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/hardware/dec21285.h>
+#include <asm/hardware.h>
+
+#define BAUD_BASE		(mem_fclk_21285/64)
+
+#ifdef CONFIG_DEVFS_FS
+#define SERIAL_21285_NAME	"tts/FB%d"
+#define SERIAL_21285_AUXNAME	"cua/FB%d"
+#else
+#define SERIAL_21285_NAME	"ttyFB"
+#define SERIAL_21285_AUXNAME	"cuafb"
+#endif
+
+#define SERIAL_21285_MAJOR	204
+#define SERIAL_21285_MINOR	4
+
+#define SERIAL_21285_AUXMAJOR	205
+#define SERIAL_21285_AUXMINOR	4
+
+#ifdef CONFIG_SERIAL_21285_OLD
+#include <asm/mach-types.h>
+/*
+ * Compatability with a mistake made a long time ago.
+ * Note - the use of "ttyI", "/dev/ttyS0" and major/minor 5,64
+ * is HIGHLY DEPRECIATED, and will be removed in the 2.5
+ * kernel series.
+ *					-- rmk 15/04/2000 
+ */
+#define SERIAL_21285_OLD_NAME	"ttyI"
+#define SERIAL_21285_OLD_MAJOR	TTY_MAJOR
+#define SERIAL_21285_OLD_MINOR	64
+
+static struct tty_driver rs285_old_driver;
+#endif
+
+static struct tty_driver rs285_driver, callout_driver;
+static int rs285_refcount;
+static struct tty_struct *rs285_table[1];
+
+static struct termios *rs285_termios[1];
+static struct termios *rs285_termios_locked[1];
+
+static char wbuf[1000], *putp = wbuf, *getp = wbuf, x_char;
+static struct tty_struct *rs285_tty;
+static DECLARE_MUTEX(rs285_sem);
+static int rs285_use_count;
+static unsigned long rs285_irq_enabled;
+
+#define TX_IRQ_BIT	(0)
+#define RX_IRQ_BIT	(1)
+
+static void rs285_stop_tx(void)
+{
+	if (test_and_clear_bit(TX_IRQ_BIT, &rs285_irq_enabled))
+		disable_irq(IRQ_CONTX);
+}
+
+static void rs285_start_tx(void)
+{
+	if (!test_and_set_bit(TX_IRQ_BIT, &rs285_irq_enabled))
+		enable_irq(IRQ_CONTX);
+}
+
+static void rs285_stop_rx(void)
+{
+	if (test_and_clear_bit(RX_IRQ_BIT, &rs285_irq_enabled))
+		disable_irq(IRQ_CONRX);
+}
+
+static void rs285_start_rx(void)
+{
+	if (!test_and_set_bit(RX_IRQ_BIT, &rs285_irq_enabled))
+		enable_irq(IRQ_CONRX);
+}
+
+static int rs285_write_room(struct tty_struct *tty)
+{
+	return putp >= getp ? (sizeof(wbuf) - (long) putp + (long) getp) : ((long) getp - (long) putp - 1);
+}
+
+static void rs285_rx_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	if (!rs285_tty) {
+		rs285_stop_rx();
+		return;
+	}
+	while (!(*CSR_UARTFLG & 0x10)) {
+		int ch, flag;
+		ch = *CSR_UARTDR;
+		flag = *CSR_RXSTAT;
+		if (flag & 4)
+			tty_insert_flip_char(rs285_tty, 0, TTY_OVERRUN);
+		if (flag & 2)
+			flag = TTY_PARITY;
+		else if (flag & 1)
+			flag = TTY_FRAME;
+		tty_insert_flip_char(rs285_tty, ch, flag);
+	}
+	tty_flip_buffer_push(rs285_tty);
+}
+
+static void rs285_send_xchar(struct tty_struct *tty, char ch)
+{
+	x_char = ch;
+	rs285_start_tx();
+}
+
+static void rs285_throttle(struct tty_struct *tty)
+{
+	if (I_IXOFF(tty))
+		rs285_send_xchar(tty, STOP_CHAR(tty));
+}
+
+static void rs285_unthrottle(struct tty_struct *tty)
+{
+	if (I_IXOFF(tty)) {
+		if (x_char)
+			x_char = 0;
+		else
+			rs285_send_xchar(tty, START_CHAR(tty));
+	}
+}
+
+static void rs285_tx_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	while (!(*CSR_UARTFLG & 0x20)) {
+		if (x_char) {
+			*CSR_UARTDR = x_char;
+			x_char = 0;
+			continue;
+		}
+		if (putp == getp) {
+			rs285_stop_tx();
+			break;
+		}
+		*CSR_UARTDR = *getp;
+		if (++getp >= wbuf + sizeof(wbuf))
+			getp = wbuf;
+	}
+	if (rs285_tty)
+		wake_up_interruptible(&rs285_tty->write_wait);
+}
+
+static inline int rs285_xmit(int ch)
+{
+	if (putp + 1 == getp || (putp + 1 == wbuf + sizeof(wbuf) && getp == wbuf))
+		return 0;
+	*putp = ch;
+	if (++putp >= wbuf + sizeof(wbuf))
+		putp = wbuf;
+	rs285_start_tx();
+	return 1;
+}
+
+static int rs285_write(struct tty_struct *tty, int from_user,
+		       const u_char * buf, int count)
+{
+	int i;
+
+	if (from_user && verify_area(VERIFY_READ, buf, count))
+		return -EINVAL;
+
+	for (i = 0; i < count; i++) {
+		char ch;
+		if (from_user)
+			__get_user(ch, buf + i);
+		else
+			ch = buf[i];
+		if (!rs285_xmit(ch))
+			break;
+	}
+	return i;
+}
+
+static void rs285_put_char(struct tty_struct *tty, u_char ch)
+{
+	rs285_xmit(ch);
+}
+
+static int rs285_chars_in_buffer(struct tty_struct *tty)
+{
+	return sizeof(wbuf) - rs285_write_room(tty);
+}
+
+static void rs285_flush_buffer(struct tty_struct *tty)
+{
+	rs285_stop_tx();
+	putp = getp = wbuf;
+	if (x_char)
+		rs285_start_tx();
+}
+
+static inline void rs285_set_cflag(int cflag)
+{
+	int h_lcr, baud, quot;
+
+	switch (cflag & CSIZE) {
+	case CS5:
+		h_lcr = 0x10;
+		break;
+	case CS6:
+		h_lcr = 0x30;
+		break;
+	case CS7:
+		h_lcr = 0x50;
+		break;
+	default: /* CS8 */
+		h_lcr = 0x70;
+		break;
+
+	}
+	if (cflag & CSTOPB)
+		h_lcr |= 0x08;
+	if (cflag & PARENB)
+		h_lcr |= 0x02;
+	if (!(cflag & PARODD))
+		h_lcr |= 0x04;
+
+	switch (cflag & CBAUD) {
+	case B200:	baud = 200;		break;
+	case B300:	baud = 300;		break;
+	case B1200:	baud = 1200;		break;
+	case B1800:	baud = 1800;		break;
+	case B2400:	baud = 2400;		break;
+	case B4800:	baud = 4800;		break;
+	default:
+	case B9600:	baud = 9600;		break;
+	case B19200:	baud = 19200;		break;
+	case B38400:	baud = 38400;		break;
+	case B57600:	baud = 57600;		break;
+	case B115200:	baud = 115200;		break;
+	}
+
+	/*
+	 * The documented expression for selecting the divisor is:
+	 *  BAUD_BASE / baud - 1
+	 * However, typically BAUD_BASE is not divisible by baud, so
+	 * we want to select the divisor that gives us the minimum
+	 * error.  Therefore, we want:
+	 *  int(BAUD_BASE / baud - 0.5) ->
+	 *  int(BAUD_BASE / baud - (baud >> 1) / baud) ->
+	 *  int((BAUD_BASE - (baud >> 1)) / baud)
+	 */
+	quot = (BAUD_BASE - (baud >> 1)) / baud;
+
+	*CSR_UARTCON = 0;
+	*CSR_L_UBRLCR = quot & 0xff;
+	*CSR_M_UBRLCR = (quot >> 8) & 0x0f;
+	*CSR_H_UBRLCR = h_lcr;
+	*CSR_UARTCON = 1;
+}
+
+static void rs285_set_termios(struct tty_struct *tty, struct termios *old)
+{
+	if (old && tty->termios->c_cflag == old->c_cflag)
+		return;
+	rs285_set_cflag(tty->termios->c_cflag);
+}
+
+
+static void rs285_stop(struct tty_struct *tty)
+{
+	rs285_stop_tx();
+}
+
+static void rs285_start(struct tty_struct *tty)
+{
+	rs285_start_tx();
+}
+
+static void rs285_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	int orig_jiffies = jiffies;
+	while (*CSR_UARTFLG & 8) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
+		if (signal_pending(current))
+			break;
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			break;
+	}
+	set_current_state(TASK_RUNNING);
+}
+
+static int rs285_open(struct tty_struct *tty, struct file *filp)
+{
+	int line, ret;
+
+	MOD_INC_USE_COUNT;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	if (line)
+		return -ENODEV;
+
+	ret = down_interruptible(&rs285_sem);
+	if (ret)
+		return ret;
+
+	tty->driver_data = NULL;
+	rs285_tty = tty;
+
+	if (rs285_use_count == 0) {
+		rs285_irq_enabled = 3;
+		ret = request_irq(IRQ_CONRX, rs285_rx_int, 0, "rs285", NULL);
+		if (ret == 0) {
+			ret = request_irq(IRQ_CONTX, rs285_tx_int, 0, "rs285",
+					  NULL);
+			if (ret)
+				free_irq(IRQ_CONRX, NULL);
+		}
+	}
+
+	if (ret == 0)
+		rs285_use_count++;
+
+	up(&rs285_sem);
+
+	return ret;
+}
+
+static void rs285_close(struct tty_struct *tty, struct file *filp)
+{
+	down(&rs285_sem);
+	if (!--rs285_use_count) {
+		rs285_wait_until_sent(tty, 0);
+		rs285_stop_rx();
+		rs285_stop_tx();
+		rs285_tty = NULL;
+		free_irq(IRQ_CONTX, NULL);
+		free_irq(IRQ_CONRX, NULL);
+	}
+	up(&rs285_sem);
+	MOD_DEC_USE_COUNT;
+}
+
+static int __init rs285_init(void)
+{
+	int baud = B9600;
+
+	if (machine_is_personal_server())
+		baud = B57600;
+
+	rs285_driver.magic = TTY_DRIVER_MAGIC;
+	rs285_driver.driver_name = "serial_21285";
+	rs285_driver.name = SERIAL_21285_NAME;
+	rs285_driver.major = SERIAL_21285_MAJOR;
+	rs285_driver.minor_start = SERIAL_21285_MINOR;
+	rs285_driver.num = 1;
+	rs285_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	rs285_driver.subtype = SERIAL_TYPE_NORMAL;
+	rs285_driver.init_termios = tty_std_termios;
+	rs285_driver.init_termios.c_cflag = baud | CS8 | CREAD | HUPCL | CLOCAL;
+	rs285_driver.flags = TTY_DRIVER_REAL_RAW;
+	rs285_driver.refcount = &rs285_refcount;
+	rs285_driver.table = rs285_table;
+	rs285_driver.termios = rs285_termios;
+	rs285_driver.termios_locked = rs285_termios_locked;
+
+	rs285_driver.open = rs285_open;
+	rs285_driver.close = rs285_close;
+	rs285_driver.write = rs285_write;
+	rs285_driver.put_char = rs285_put_char;
+	rs285_driver.write_room = rs285_write_room;
+	rs285_driver.chars_in_buffer = rs285_chars_in_buffer;
+	rs285_driver.flush_buffer = rs285_flush_buffer;
+	rs285_driver.throttle = rs285_throttle;
+	rs285_driver.unthrottle = rs285_unthrottle;
+	rs285_driver.send_xchar = rs285_send_xchar;
+	rs285_driver.set_termios = rs285_set_termios;
+	rs285_driver.stop = rs285_stop;
+	rs285_driver.start = rs285_start;
+	rs285_driver.wait_until_sent = rs285_wait_until_sent;
+
+	callout_driver = rs285_driver;
+	callout_driver.name = SERIAL_21285_AUXNAME;
+	callout_driver.major = SERIAL_21285_AUXMAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+
+#ifdef CONFIG_SERIAL_21285_OLD
+	if (!machine_is_ebsa285() && !machine_is_netwinder()) {
+		rs285_old_driver = rs285_driver;
+		rs285_old_driver.name = SERIAL_21285_OLD_NAME;
+		rs285_old_driver.major = SERIAL_21285_OLD_MAJOR;
+		rs285_old_driver.minor_start = SERIAL_21285_OLD_MINOR;
+
+		if (tty_register_driver(&rs285_old_driver))
+			printk(KERN_ERR "Couldn't register old 21285 serial driver\n");
+	}
+#endif
+
+	if (tty_register_driver(&rs285_driver))
+		printk(KERN_ERR "Couldn't register 21285 serial driver\n");
+	if (tty_register_driver(&callout_driver))
+		printk(KERN_ERR "Couldn't register 21285 callout driver\n");
+
+	return 0;
+}
+
+static void __exit rs285_fini(void)
+{
+	unsigned long flags;
+	int ret;
+
+	save_flags(flags);
+	cli();
+	ret = tty_unregister_driver(&callout_driver);
+	if (ret)
+		printk(KERN_ERR "Unable to unregister 21285 callout driver "
+			"(%d)\n", ret);
+	ret = tty_unregister_driver(&rs285_driver);
+	if (ret)
+		printk(KERN_ERR "Unable to unregister 21285 driver (%d)\n",
+			ret);
+#ifdef CONFIG_SERIAL_21285_OLD
+	if (!machine_is_ebsa285() && !machine_is_netwinder()) {
+		ret = tty_unregister_driver(&rs285_old_driver);
+		if (ret)
+			printk(KERN_ERR "Unable to unregister old 21285 "
+				"driver (%d)\n", ret);
+	}
+#endif
+	free_irq(IRQ_CONTX, NULL);
+	free_irq(IRQ_CONRX, NULL);
+	restore_flags(flags);
+}
+
+module_init(rs285_init);
+module_exit(rs285_fini);
+
+#ifdef CONFIG_SERIAL_21285_CONSOLE
+/************** console driver *****************/
+
+static void rs285_console_write(struct console *co, const char *s, u_int count)
+{
+	int i;
+
+	rs285_stop_tx();
+	for (i = 0; i < count; i++) {
+		while (*CSR_UARTFLG & 0x20);
+		*CSR_UARTDR = s[i];
+		if (s[i] == '\n') {
+			while (*CSR_UARTFLG & 0x20);
+			*CSR_UARTDR = '\r';
+		}
+	}
+	rs285_start_tx();
+}
+
+static kdev_t rs285_console_device(struct console *c)
+{
+	return MKDEV(SERIAL_21285_MAJOR, SERIAL_21285_MINOR);
+}
+
+static int __init rs285_console_setup(struct console *co, char *options)
+{
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int flow;
+	int cflag = CREAD | HUPCL | CLOCAL;
+
+	if (machine_is_personal_server())
+		baud = 57600;
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	/*
+	 *    Now construct a cflag setting.
+	 */
+	switch (baud) {
+	case 1200:
+		cflag |= B1200;
+		break;
+	case 2400:
+		cflag |= B2400;
+		break;
+	case 4800:
+		cflag |= B4800;
+		break;
+	case 9600:
+		cflag |= B9600;
+		break;
+	case 19200:
+		cflag |= B19200;
+		break;
+	case 38400:
+		cflag |= B38400;
+		break;
+	case 57600:
+		cflag |= B57600;
+		break;
+	case 115200:
+		cflag |= B115200;
+		break;
+	default:
+		cflag |= B9600;
+		break;
+	}
+	switch (bits) {
+	case 7:
+		cflag |= CS7;
+		break;
+	default:
+		cflag |= CS8;
+		break;
+	}
+	switch (parity) {
+	case 'o':
+	case 'O':
+		cflag |= PARODD;
+		break;
+	case 'e':
+	case 'E':
+		cflag |= PARENB;
+		break;
+	}
+	co->cflag = cflag;
+	rs285_set_cflag(cflag);
+	rs285_console_write(NULL, "\e[2J\e[Hboot ", 12);
+	if (options)
+		rs285_console_write(NULL, options, strlen(options));
+	else
+		rs285_console_write(NULL, "no options", 10);
+	rs285_console_write(NULL, "\n", 1);
+
+	return 0;
+}
+
+#ifdef CONFIG_SERIAL_21285_OLD
+static struct console rs285_old_cons =
+{
+	SERIAL_21285_OLD_NAME,
+	rs285_console_write,
+	NULL,
+	rs285_console_device,
+	NULL,
+	rs285_console_setup,
+	CON_PRINTBUFFER,
+	-1,
+	0,
+	NULL
+};
+#endif
+
+static struct console rs285_cons =
+{
+	name:		SERIAL_21285_NAME,
+	write:		rs285_console_write,
+	device:		rs285_console_device,
+	setup:		rs285_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+void __init rs285_console_init(void)
+{
+#ifdef CONFIG_SERIAL_21285_OLD
+	if (!machine_is_ebsa285() && !machine_is_netwinder())
+		register_console(&rs285_old_cons);
+#endif
+	register_console(&rs285_cons);
+}
+
+#endif /* CONFIG_SERIAL_21285_CONSOLE */
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Intel Footbridge (21285) serial driver");
diff -urN linux-2.4.29/drivers/serial/8250.c linux-2.4.29-uc1/drivers/serial/8250.c
--- linux-2.4.29/drivers/serial/8250.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/serial/8250.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,2170 @@
+/*
+ *  linux/drivers/serial/8250.c
+ *
+ *  Driver for 8250/16550-type serial ports
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright (C) 2001 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ *  $Id: 8250.c,v 1.14.2.8 2002/10/24 14:31:31 rmk Exp $
+ *
+ * A note about mapbase / membase
+ *
+ *  mapbase is the physical address of the IO port.  Currently, we don't
+ *  support this very well, and it may well be dropped from this driver
+ *  in future.  As such, mapbase should be NULL.
+ *
+ *  membase is an 'ioremapped' cookie.  This is compatible with the old
+ *  serial.c driver, and is currently the preferred form.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/serial_reg.h>
+#include <linux/serialP.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+#include <linux/kmod.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+
+#include "8250.h"
+
+/*
+ * Configuration:
+ *   share_irqs - whether we pass SA_SHIRQ to request_irq().  This option
+ *                is unsafe when used on edge-triggered interrupts.
+ */
+unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
+
+/*
+ * Debugging.
+ */
+#if 0
+#define DEBUG_AUTOCONF(fmt...)	printk(fmt)
+#else
+#define DEBUG_AUTOCONF(fmt...)	do { } while (0)
+#endif
+
+#if 0
+#define DEBUG_INTR(fmt...)	printk(fmt)
+#else
+#define DEBUG_INTR(fmt...)	do { } while (0)
+#endif
+
+#define PASS_LIMIT	256
+
+/*
+ * We default to IRQ0 for the "no irq" hack.   Some
+ * machine types want others as well - they're free
+ * to redefine this in their header file.
+ */
+#define is_real_interrupt(irq)	((irq) != 0)
+
+/*
+ * This converts from our new CONFIG_ symbols to the symbols
+ * that asm/serial.h expects.  You _NEED_ to comment out the
+ * linux/config.h include contained inside asm/serial.h for
+ * this to work.
+ */
+#undef CONFIG_SERIAL_MANY_PORTS
+#undef CONFIG_SERIAL_DETECT_IRQ
+#undef CONFIG_SERIAL_MULTIPORT
+#undef CONFIG_HUB6
+
+#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
+#define CONFIG_SERIAL_DETECT_IRQ 1
+#endif
+#ifdef CONFIG_SERIAL_8250_MULTIPORT
+#define CONFIG_SERIAL_MULTIPORT 1
+#endif
+#ifdef CONFIG_SERIAL_8250_HUB6
+#define CONFIG_HUB6 1
+#endif
+#ifdef CONFIG_SERIAL_8250_MANY_PORTS
+#define CONFIG_SERIAL_MANY_PORTS 1
+#endif
+
+#include <asm/serial.h>
+
+static struct old_serial_port old_serial_port[] = {
+	SERIAL_PORT_DFNS /* defined in asm/serial.h */
+};
+
+#define UART_NR	ARRAY_SIZE(old_serial_port)
+
+static struct tty_driver normal, callout;
+static struct tty_struct *serial8250_table[UART_NR];
+static struct termios *serial8250_termios[UART_NR], *serial8250_termios_locked[UART_NR];
+
+#if defined(CONFIG_SERIAL_8250_RSA) && defined(MODULE)
+
+#define PORT_RSA_MAX 4
+static int probe_rsa[PORT_RSA_MAX];
+static int force_rsa[PORT_RSA_MAX];
+#endif /* CONFIG_SERIAL_8250_RSA  */
+
+struct uart_8250_port {
+	struct uart_port	port;
+	struct timer_list	timer;		/* "no irq" timer */
+	struct list_head	list;		/* ports on this IRQ */
+	unsigned int		capabilities;	/* port capabilities */
+	unsigned char		acr;
+	unsigned char		ier;
+	unsigned short		rev;
+	unsigned char		lcr;
+	unsigned char		mcr;
+	unsigned char		mcr_mask;	/* mask of user bits */
+	unsigned char		mcr_force;	/* mask of forced bits */
+	unsigned char		efr;
+	unsigned int		lsr_break_flag;
+
+	/*
+	 * We provide a per-port pm hook.
+	 */
+	void			(*pm)(struct uart_port *port,
+				      unsigned int state, unsigned int old);
+};
+
+struct irq_info {
+	spinlock_t		lock;
+	struct list_head	*head;
+};
+
+static struct irq_info irq_lists[NR_IRQS];
+
+/*
+ * Here we define the default xmit fifo size used for each type of UART.
+ */
+static const struct serial_uart_config uart_config[PORT_MAX_8250+1] = {
+	{ "unknown",	1,	0 },
+	{ "8250",	1,	0 },
+	{ "16450",	1,	0 },
+	{ "16550",	1,	0 },
+	{ "16550A",	16,	UART_CLEAR_FIFO | UART_USE_FIFO },
+	{ "Cirrus",	1, 	0 },
+	{ "ST16650",	1,	UART_CLEAR_FIFO | UART_STARTECH },
+	{ "ST16650V2",	32,	UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH },
+	{ "TI16750",	64,	UART_CLEAR_FIFO | UART_USE_FIFO },
+	{ "Startech",	1,	0 },
+	{ "16C950/954",	128,	UART_CLEAR_FIFO | UART_USE_FIFO },
+	{ "ST16654",	64,	UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH },
+	{ "XR16850",	128,	UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH },
+	{ "RSA",	2048,	UART_CLEAR_FIFO | UART_USE_FIFO }
+};
+
+static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset)
+{
+	offset <<= up->port.regshift;
+
+	switch (up->port.iotype) {
+#ifdef CONFIG_SERIAL_8250_HUB6
+	case SERIAL_IO_HUB6:
+		outb(up->port.hub6 - 1 + offset, up->port.iobase);
+		return inb(up->port.iobase + 1);
+#endif
+
+	case SERIAL_IO_MEM:
+		return readb(up->port.membase + offset);
+
+	default:
+		return inb(up->port.iobase + offset);
+	}
+}
+
+static _INLINE_ void
+serial_out(struct uart_8250_port *up, int offset, int value)
+{
+	offset <<= up->port.regshift;
+
+	switch (up->port.iotype) {
+#ifdef CONFIG_SERIAL_8250_HUB6
+	case SERIAL_IO_HUB6:
+		outb(up->port.hub6 - 1 + offset, up->port.iobase);
+		outb(value, up->port.iobase + 1);
+		break;
+#endif
+
+	case SERIAL_IO_MEM:
+		writeb(value, up->port.membase + offset);
+		break;
+
+	default:
+		outb(value, up->port.iobase + offset);
+	}
+}
+
+/*
+ * We used to support using pause I/O for certain machines.  We
+ * haven't supported this for a while, but just in case it's badly
+ * needed for certain old 386 machines, I've left these #define's
+ * in....
+ */
+#define serial_inp(up, offset)		serial_in(up, offset)
+#define serial_outp(up, offset, value)	serial_out(up, offset, value)
+
+
+/*
+ * For the 16C950
+ */
+static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
+{
+	serial_out(up, UART_SCR, offset);
+	serial_out(up, UART_ICR, value);
+}
+
+static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
+{
+	unsigned int value;
+
+	serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
+	serial_out(up, UART_SCR, offset);
+	value = serial_in(up, UART_ICR);
+	serial_icr_write(up, UART_ACR, up->acr);
+
+	return value;
+}
+
+#ifdef CONFIG_SERIAL_8250_RSA
+/*
+ * Attempts to turn on the RSA FIFO.  Returns zero on failure.
+ * We set the port uart clock rate if we succeed.
+ */
+static int __enable_rsa(struct uart_8250_port *up)
+{
+	unsigned char mode;
+	int result;
+
+	mode = serial_inp(up, UART_RSA_MSR);
+	result = mode & UART_RSA_MSR_FIFO;
+
+	if (!result) {
+		serial_outp(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
+		mode = serial_inp(up, UART_RSA_MSR);
+		result = mode & UART_RSA_MSR_FIFO;
+	}
+
+	if (result)
+		up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16;
+
+	return result;
+}
+
+static void enable_rsa(struct uart_8250_port *up)
+{
+	if (up->port.type == PORT_RSA) {
+		if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) {
+			spin_lock_irq(&up->port.lock);
+			__enable_rsa(up);
+			spin_unlock_irq(&up->port.lock);
+		}
+		if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16)
+			serial_outp(up, UART_RSA_FRR, 0);
+	}
+}
+
+/*
+ * Attempts to turn off the RSA FIFO.  Returns zero on failure.
+ * It is unknown why interrupts were disabled in here.  However,
+ * the caller is expected to preserve this behaviour by grabbing
+ * the spinlock before calling this function.
+ */
+static void disable_rsa(struct uart_8250_port *up)
+{
+	unsigned char mode;
+	int result;
+
+	if (up->port.type == PORT_RSA &&
+	    up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) {
+		spin_lock_irq(&up->port.lock);
+
+		mode = serial_inp(up, UART_RSA_MSR);
+		result = !(mode & UART_RSA_MSR_FIFO);
+
+		if (!result) {
+			serial_outp(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
+			mode = serial_inp(up, UART_RSA_MSR);
+			result = !(mode & UART_RSA_MSR_FIFO);
+		}
+
+		if (result)
+			up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16;
+		spin_unlock_irq(&up->port.lock);
+	}
+}
+#endif /* CONFIG_SERIAL_8250_RSA */
+
+/*
+ * This is a quickie test to see how big the FIFO is.
+ * It doesn't work at all the time, more's the pity.
+ */
+static int size_fifo(struct uart_8250_port *up)
+{
+	unsigned char old_fcr, old_mcr, old_dll, old_dlm;
+	int count;
+
+	old_fcr = serial_inp(up, UART_FCR);
+	old_mcr = serial_inp(up, UART_MCR);
+	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
+		    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+	serial_outp(up, UART_MCR, UART_MCR_LOOP);
+	serial_outp(up, UART_LCR, UART_LCR_DLAB);
+	old_dll = serial_inp(up, UART_DLL);
+	old_dlm = serial_inp(up, UART_DLM);
+	serial_outp(up, UART_DLL, 0x01);
+	serial_outp(up, UART_DLM, 0x00);
+	serial_outp(up, UART_LCR, 0x03);
+	for (count = 0; count < 256; count++)
+		serial_outp(up, UART_TX, count);
+	mdelay(20);/* FIXME - schedule_timeout */
+	for (count = 0; (serial_inp(up, UART_LSR) & UART_LSR_DR) &&
+	     (count < 256); count++)
+		serial_inp(up, UART_RX);
+	serial_outp(up, UART_FCR, old_fcr);
+	serial_outp(up, UART_MCR, old_mcr);
+	serial_outp(up, UART_LCR, UART_LCR_DLAB);
+	serial_outp(up, UART_DLL, old_dll);
+	serial_outp(up, UART_DLM, old_dlm);
+
+	return count;
+}
+
+/*
+ * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
+ * When this function is called we know it is at least a StarTech
+ * 16650 V2, but it might be one of several StarTech UARTs, or one of
+ * its clones.  (We treat the broken original StarTech 16650 V1 as a
+ * 16550, and why not?  Startech doesn't seem to even acknowledge its
+ * existence.)
+ * 
+ * What evil have men's minds wrought...
+ */
+static void autoconfig_has_efr(struct uart_8250_port *up)
+{
+	unsigned char id1, id2, id3, rev, saved_dll, saved_dlm;
+
+	/*
+	 * First we check to see if it's an Oxford Semiconductor UART.
+	 *
+	 * If we have to do this here because some non-National
+	 * Semiconductor clone chips lock up if you try writing to the
+	 * LSR register (which serial_icr_read does)
+	 */
+
+	/*
+	 * Check for Oxford Semiconductor 16C950.
+	 *
+	 * EFR [4] must be set else this test fails.
+	 *
+	 * This shouldn't be necessary, but Mike Hudson (Exoray@isys.ca)
+	 * claims that it's needed for 952 dual UART's (which are not
+	 * recommended for new designs).
+	 */
+	up->acr = 0;
+	serial_out(up, UART_LCR, 0xBF);
+	serial_out(up, UART_EFR, 0x10);
+	serial_out(up, UART_LCR, 0x00);
+	id1 = serial_icr_read(up, UART_ID1);
+	id2 = serial_icr_read(up, UART_ID2);
+	id3 = serial_icr_read(up, UART_ID3);
+	rev = serial_icr_read(up, UART_REV);
+
+	DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev);
+
+	if (id1 == 0x16 && id2 == 0xC9 &&
+	    (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) {
+		up->port.type = PORT_16C950;
+		up->rev = rev | (id3 << 8);
+		return;
+	}
+	
+	/*
+	 * We check for a XR16C850 by setting DLL and DLM to 0, and then
+	 * reading back DLL and DLM.  The chip type depends on the DLM
+	 * value read back:
+	 *  0x10 - XR16C850 and the DLL contains the chip revision.
+	 *  0x12 - XR16C2850.
+	 *  0x14 - XR16C854.
+	 */
+	serial_outp(up, UART_LCR, UART_LCR_DLAB);
+	saved_dll = serial_inp(up, UART_DLL);
+	saved_dlm = serial_inp(up, UART_DLM);
+	serial_outp(up, UART_DLL, 0);
+	serial_outp(up, UART_DLM, 0);
+	id2 = serial_inp(up, UART_DLL);
+	id1 = serial_inp(up, UART_DLM);
+	serial_outp(up, UART_DLL, saved_dll);
+	serial_outp(up, UART_DLM, saved_dlm);
+
+	DEBUG_AUTOCONF("850id=%02x:%02x ", id1, id2);
+
+	if (id1 == 0x10 || id1 == 0x12 || id1 == 0x14) {
+		if (id1 == 0x10)
+			up->rev = id2;
+		up->port.type = PORT_16850;
+		return;
+	}
+
+	/*
+	 * It wasn't an XR16C850.
+	 *
+	 * We distinguish between the '654 and the '650 by counting
+	 * how many bytes are in the FIFO.  I'm using this for now,
+	 * since that's the technique that was sent to me in the
+	 * serial driver update, but I'm not convinced this works.
+	 * I've had problems doing this in the past.  -TYT
+	 */
+	if (size_fifo(up) == 64)
+		up->port.type = PORT_16654;
+	else
+		up->port.type = PORT_16650V2;
+}
+
+/*
+ * We detected a chip without a FIFO.  Only two fall into
+ * this category - the original 8250 and the 16450.  The
+ * 16450 has a scratch register (accessible with LCR=0)
+ */
+static void autoconfig_8250(struct uart_8250_port *up)
+{
+	unsigned char scratch, status1, status2;
+
+	up->port.type = PORT_8250;
+
+	scratch = serial_in(up, UART_SCR);
+	serial_outp(up, UART_SCR, 0xa5);
+	status1 = serial_in(up, UART_SCR);
+	serial_outp(up, UART_SCR, 0x5a);
+	status2 = serial_in(up, UART_SCR);
+	serial_outp(up, UART_SCR, scratch);
+
+	if (status1 == 0xa5 && status2 == 0x5a)
+		up->port.type = PORT_16450;
+}
+
+/*
+ * We know that the chip has FIFOs.  Does it have an EFR?  The
+ * EFR is located in the same register position as the IIR and
+ * we know the top two bits of the IIR are currently set.  The
+ * EFR should contain zero.  Try to read the EFR.
+ */
+static void autoconfig_16550a(struct uart_8250_port *up)
+{
+	unsigned char status1, status2;
+
+	up->port.type = PORT_16550A;
+
+	/*
+	 * Check for presence of the EFR when DLAB is set.
+	 * Only ST16C650V1 UARTs pass this test.
+	 */
+	serial_outp(up, UART_LCR, UART_LCR_DLAB);
+	if (serial_in(up, UART_EFR) == 0) {
+		DEBUG_AUTOCONF("EFRv1 ");
+		up->port.type = PORT_16650;
+		return;
+	}
+
+	/*
+	 * Maybe it requires 0xbf to be written to the LCR.
+	 * (other ST16C650V2 UARTs, TI16C752A, etc)
+	 */
+	serial_outp(up, UART_LCR, 0xBF);
+	if (serial_in(up, UART_EFR) == 0) {
+		DEBUG_AUTOCONF("EFRv2 ");
+		autoconfig_has_efr(up);
+		return;
+	}
+
+	/*
+	 * Check for a National Semiconductor SuperIO chip.
+	 * Attempt to switch to bank 2, read the value of the LOOP bit
+	 * from EXCR1. Switch back to bank 0, change it in MCR. Then
+	 * switch back to bank 2, read it from EXCR1 again and check
+	 * it's changed. If so, set baud_base in EXCR2 to 921600.
+	 */
+	serial_outp(up, UART_LCR, 0);
+	status1 = serial_in(up, UART_MCR);
+	serial_outp(up, UART_LCR, 0xE0);
+	status2 = serial_in(up, 0x02); /* EXCR1 */
+
+	if (!((status2 ^ status1) & UART_MCR_LOOP)) {
+		serial_outp(up, UART_LCR, 0);
+		serial_outp(up, UART_MCR, status1 ^ UART_MCR_LOOP);
+		serial_outp(up, UART_LCR, 0xE0);
+		status2 = serial_in(up, 0x02); /* EXCR1 */
+		serial_outp(up, UART_LCR, 0);
+		serial_outp(up, UART_MCR, status1);
+
+		if ((status2 ^ status1) & UART_MCR_LOOP) {
+			serial_outp(up, UART_LCR, 0xE0);
+			status1 = serial_in(up, 0x04); /* EXCR1 */
+			status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
+			status1 |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */
+			serial_outp(up, 0x04, status1);
+			serial_outp(up, UART_LCR, 0);
+
+			up->port.type = PORT_NS16550A;
+			up->port.uartclk = 921600*16;
+			return;
+		}
+	}
+
+	/*
+	 * No EFR.  Try to detect a TI16750, which only sets bit 5 of
+	 * the IIR when 64 byte FIFO mode is enabled when DLAB is set.
+	 * Try setting it with and without DLAB set.  Cheap clones
+	 * set bit 5 without DLAB set.
+	 */
+	serial_outp(up, UART_LCR, 0);
+	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
+	status1 = serial_in(up, UART_IIR) >> 5;
+	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+	serial_outp(up, UART_LCR, UART_LCR_DLAB);
+	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
+	status2 = serial_in(up, UART_IIR) >> 5;
+	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+
+	DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2);
+
+	if (status1 == 6 && status2 == 7) {
+		up->port.type = PORT_16750;
+		return;
+	}
+}
+
+/*
+ * This routine is called by rs_init() to initialize a specific serial
+ * port.  It determines what type of UART chip this serial port is
+ * using: 8250, 16450, 16550, 16550A.  The important question is
+ * whether or not this UART is a 16550A or not, since this will
+ * determine whether or not we can use its FIFO features or not.
+ */
+static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
+{
+	unsigned char status1, scratch, scratch2, scratch3;
+	unsigned char save_lcr, save_mcr;
+	unsigned long flags;
+
+	if (!up->port.iobase && !up->port.mapbase && !up->port.membase)
+		return;
+
+	DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%p): ",
+			up->port.line, up->port.iobase, up->port.membase);
+
+	/*
+	 * We really do need global IRQs disabled here - we're going to
+	 * be frobbing the chips IRQ enable register to see if it exists.
+	 */
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	if (!(up->port.flags & UPF_BUGGY_UART)) {
+		/*
+		 * Do a simple existence test first; if we fail this,
+		 * there's no point trying anything else.
+		 * 
+		 * 0x80 is used as a nonsense port to prevent against
+		 * false positives due to ISA bus float.  The
+		 * assumption is that 0x80 is a non-existent port;
+		 * which should be safe since include/asm/io.h also
+		 * makes this assumption.
+		 *
+		 * Note: this is safe as long as MCR bit 4 is clear
+		 * and the device is in "PC" mode.
+		 */
+		scratch = serial_inp(up, UART_IER);
+		serial_outp(up, UART_IER, 0);
+#ifdef __i386__
+		outb(0xff, 0x080);
+#endif
+		scratch2 = serial_inp(up, UART_IER);
+		serial_outp(up, UART_IER, 0x0F);
+#ifdef __i386__
+		outb(0, 0x080);
+#endif
+		scratch3 = serial_inp(up, UART_IER);
+		serial_outp(up, UART_IER, scratch);
+		if (scratch2 != 0 || scratch3 != 0x0F) {
+			/*
+			 * We failed; there's nothing here
+			 */
+			DEBUG_AUTOCONF("IER test failed (%02x, %02x) ",
+				       scratch2, scratch3);
+			goto out;
+		}
+	}
+
+	save_mcr = serial_in(up, UART_MCR);
+	save_lcr = serial_in(up, UART_LCR);
+
+	/* 
+	 * Check to see if a UART is really there.  Certain broken
+	 * internal modems based on the Rockwell chipset fail this
+	 * test, because they apparently don't implement the loopback
+	 * test mode.  So this test is skipped on the COM 1 through
+	 * COM 4 ports.  This *should* be safe, since no board
+	 * manufacturer would be stupid enough to design a board
+	 * that conflicts with COM 1-4 --- we hope!
+	 */
+	if (!(up->port.flags & UPF_SKIP_TEST)) {
+		serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A);
+		status1 = serial_inp(up, UART_MSR) & 0xF0;
+		serial_outp(up, UART_MCR, save_mcr);
+		if (status1 != 0x90) {
+			DEBUG_AUTOCONF("LOOP test failed (%02x) ",
+				       status1);
+			goto out;
+		}
+	}
+
+	/*
+	 * We're pretty sure there's a port here.  Lets find out what
+	 * type of port it is.  The IIR top two bits allows us to find
+	 * out if its 8250 or 16450, 16550, 16550A or later.  This
+	 * determines what we test for next.
+	 *
+	 * We also initialise the EFR (if any) to zero for later.  The
+	 * EFR occupies the same register location as the FCR and IIR.
+	 */
+	serial_outp(up, UART_LCR, 0xBF);
+	serial_outp(up, UART_EFR, 0);
+	serial_outp(up, UART_LCR, 0);
+
+	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+	scratch = serial_in(up, UART_IIR) >> 6;
+
+	DEBUG_AUTOCONF("iir=%d ", scratch);
+
+	switch (scratch) {
+	case 0:
+		autoconfig_8250(up);
+		break;
+	case 1:
+		up->port.type = PORT_UNKNOWN;
+		break;
+	case 2:
+		up->port.type = PORT_16550;
+		break;
+	case 3:
+		autoconfig_16550a(up);
+		break;
+	}
+
+#if defined(CONFIG_SERIAL_8250_RSA) && defined(MODULE)
+	/*
+	 * Only probe for RSA ports if we got the region.
+	 */
+	if (up->port.type == PORT_16550A && probeflags & PROBE_RSA) {
+		int i;
+
+		for (i = 0 ; i < PORT_RSA_MAX ; ++i) {
+			if (!probe_rsa[i] && !force_rsa[i])
+				break;
+			if (((probe_rsa[i] != up->port.iobase) ||
+			     check_region(up->port.iobase + UART_RSA_BASE, 16)) &&
+			    (force_rsa[i] != up->port.iobase))
+				continue;
+			if (__enable_rsa(up)) {
+				up->port.type = PORT_RSA;
+				break;
+			}
+		}
+	}
+#endif
+	serial_outp(up, UART_LCR, save_lcr);
+
+	up->port.fifosize = uart_config[up->port.type].dfl_xmit_fifo_size;
+	up->capabilities = uart_config[up->port.type].flags;
+
+	if (up->port.type == PORT_UNKNOWN)
+		goto out;
+
+	/*
+	 * Reset the UART.
+	 */
+#ifdef CONFIG_SERIAL_8250_RSA
+	if (up->port.type == PORT_RSA)
+		serial_outp(up, UART_RSA_FRR, 0);
+#endif
+	serial_outp(up, UART_MCR, save_mcr);
+	serial_outp(up, UART_FCR, (UART_FCR_ENABLE_FIFO |
+				     UART_FCR_CLEAR_RCVR |
+				     UART_FCR_CLEAR_XMIT));
+	serial_outp(up, UART_FCR, 0);
+	(void)serial_in(up, UART_RX);
+	serial_outp(up, UART_IER, 0);
+
+ out:
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+#ifdef CONFIG_SERIAL_8250_RSA
+	if (up->port.iobase && up->port.type == PORT_RSA) {
+		release_region(up->port.iobase, 8);
+		request_region(up->port.iobase + UART_RSA_BASE, 16,
+			       "serial_rsa");
+	}
+#endif
+	DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
+}
+
+static void autoconfig_irq(struct uart_8250_port *up)
+{
+	unsigned char save_mcr, save_ier;
+	unsigned char save_ICP = 0;
+	unsigned int ICP = 0;
+	unsigned long irqs;
+	int irq;
+
+	if (up->port.flags & UPF_FOURPORT) {
+		ICP = (up->port.iobase & 0xfe0) | 0x1f;
+		save_ICP = inb_p(ICP);
+		outb_p(0x80, ICP);
+		(void) inb_p(ICP);
+	}
+
+	/* forget possible initially masked and pending IRQ */
+	probe_irq_off(probe_irq_on());
+	save_mcr = serial_inp(up, UART_MCR);
+	save_ier = serial_inp(up, UART_IER);
+	serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
+	
+	irqs = probe_irq_on();
+	serial_outp(up, UART_MCR, 0);
+	udelay (10);
+	if (up->port.flags & UPF_FOURPORT)  {
+		serial_outp(up, UART_MCR,
+			    UART_MCR_DTR | UART_MCR_RTS);
+	} else {
+		serial_outp(up, UART_MCR,
+			    UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
+	}
+	serial_outp(up, UART_IER, 0x0f);	/* enable all intrs */
+	(void)serial_inp(up, UART_LSR);
+	(void)serial_inp(up, UART_RX);
+	(void)serial_inp(up, UART_IIR);
+	(void)serial_inp(up, UART_MSR);
+	serial_outp(up, UART_TX, 0xFF);
+	udelay (20);
+	irq = probe_irq_off(irqs);
+
+	serial_outp(up, UART_MCR, save_mcr);
+	serial_outp(up, UART_IER, save_ier);
+
+	if (up->port.flags & UPF_FOURPORT)
+		outb_p(save_ICP, ICP);
+
+	up->port.irq = (irq > 0) ? irq : 0;
+}
+
+static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+
+	if (up->ier & UART_IER_THRI) {
+		up->ier &= ~UART_IER_THRI;
+		serial_out(up, UART_IER, up->ier);
+	}
+	if (up->port.type == PORT_16C950 && tty_stop) {
+		up->acr |= UART_ACR_TXDIS;
+		serial_icr_write(up, UART_ACR, up->acr);
+	}
+}
+
+static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+
+	if (!(up->ier & UART_IER_THRI)) {
+		up->ier |= UART_IER_THRI;
+		serial_out(up, UART_IER, up->ier);
+	}
+	/*
+	 * We only do this from uart_start
+	 */
+	if (tty_start && up->port.type == PORT_16C950) {
+		up->acr &= ~UART_ACR_TXDIS;
+		serial_icr_write(up, UART_ACR, up->acr);
+	}
+}
+
+static void serial8250_stop_rx(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+
+	up->ier &= ~UART_IER_RLSI;
+	up->port.read_status_mask &= ~UART_LSR_DR;
+	serial_out(up, UART_IER, up->ier);
+}
+
+static void serial8250_enable_ms(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+
+	up->ier |= UART_IER_MSI;
+	serial_out(up, UART_IER, up->ier);
+}
+
+static _INLINE_ void
+receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
+{
+	struct tty_struct *tty = up->port.info->tty;
+	unsigned char ch;
+	int max_count = 256;
+
+	do {
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			/*
+			 * FIXME: Deadlock can happen here if we're a
+			 * low-latency port.  We're holding the per-port
+			 * spinlock, and we call flush_to_ldisc->
+			 * n_tty_receive_buf->n_tty_receive_char->
+			 * opost->uart_put_char.
+			 */
+			tty->flip.tqueue.routine((void *)tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+				return; // if TTY_DONT_FLIP is set
+		}
+		ch = serial_inp(up, UART_RX);
+		*tty->flip.char_buf_ptr = ch;
+		*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		up->port.icount.rx++;
+
+		if (*status & (UART_LSR_BI | UART_LSR_PE |
+			       UART_LSR_FE | UART_LSR_OE)) {
+			/*
+			 * For statistics only
+			 */
+			if (*status & UART_LSR_BI) {
+				*status &= ~(UART_LSR_FE | UART_LSR_PE);
+				up->port.icount.brk++;
+				/*
+				 * We do the SysRQ and SAK checking
+				 * here because otherwise the break
+				 * may get masked by ignore_status_mask
+				 * or read_status_mask.
+				 */
+				if (uart_handle_break(&up->port))
+					goto ignore_char;
+			} else if (*status & UART_LSR_PE)
+				up->port.icount.parity++;
+			else if (*status & UART_LSR_FE)
+				up->port.icount.frame++;
+			if (*status & UART_LSR_OE)
+				up->port.icount.overrun++;
+
+			/*
+			 * Mask off conditions which should be ingored.
+			 */
+			*status &= up->port.read_status_mask;
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+			if (up->port.line == up->port.cons->index) {
+				/* Recover the break flag from console xmit */
+				*status |= up->lsr_break_flag;
+				up->lsr_break_flag = 0;
+			}
+#endif
+			if (*status & UART_LSR_BI) {
+				DEBUG_INTR("handling break....");
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			} else if (*status & UART_LSR_PE)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (*status & UART_LSR_FE)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+		}
+		if (uart_handle_sysrq_char(&up->port, ch, regs))
+			goto ignore_char;
+		if ((*status & up->port.ignore_status_mask) == 0) {
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+		if ((*status & UART_LSR_OE) &&
+		    tty->flip.count < TTY_FLIPBUF_SIZE) {
+			/*
+			 * Overrun is special, since it's reported
+			 * immediately, and doesn't affect the current
+			 * character.
+			 */
+			*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+	ignore_char:
+		*status = serial_inp(up, UART_LSR);
+	} while ((*status & UART_LSR_DR) && (max_count-- > 0));
+	tty_flip_buffer_push(tty);
+}
+
+static _INLINE_ void transmit_chars(struct uart_8250_port *up)
+{
+	struct circ_buf *xmit = &up->port.info->xmit;
+	int count;
+
+	if (up->port.x_char) {
+		serial_outp(up, UART_TX, up->port.x_char);
+		up->port.icount.tx++;
+		up->port.x_char = 0;
+		return;
+	}
+	if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
+		serial8250_stop_tx(&up->port, 0);
+		return;
+	}
+
+	count = up->port.fifosize;
+	do {
+		serial_out(up, UART_TX, xmit->buf[xmit->tail]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		up->port.icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	} while (--count > 0);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(&up->port);
+
+	DEBUG_INTR("THRE...");
+
+	if (uart_circ_empty(xmit))
+		serial8250_stop_tx(&up->port, 0);
+}
+
+static _INLINE_ void check_modem_status(struct uart_8250_port *up)
+{
+	int status;
+
+	status = serial_in(up, UART_MSR);
+
+	if ((status & UART_MSR_ANY_DELTA) == 0)
+		return;
+
+	if (status & UART_MSR_TERI)
+		up->port.icount.rng++;
+	if (status & UART_MSR_DDSR)
+		up->port.icount.dsr++;
+	if (status & UART_MSR_DDCD)
+		uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
+	if (status & UART_MSR_DCTS)
+		uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
+
+	wake_up_interruptible(&up->port.info->delta_msr_wait);
+}
+
+/*
+ * This handles the interrupt from one port.
+ */
+static inline void
+serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs)
+{
+	unsigned int status = serial_inp(up, UART_LSR);
+
+	DEBUG_INTR("status = %x...", status);
+
+	if (status & UART_LSR_DR)
+		receive_chars(up, &status, regs);
+	check_modem_status(up);
+	if (status & UART_LSR_THRE)
+		transmit_chars(up);
+}
+
+/*
+ * This is the serial driver's interrupt routine.
+ *
+ * Arjan thinks the old way was overly complex, so it got simplified.
+ * Alan disagrees, saying that need the complexity to handle the weird
+ * nature of ISA shared interrupts.  (This is a special exception.)
+ *
+ * In order to handle ISA shared interrupts properly, we need to check
+ * that all ports have been serviced, and therefore the ISA interrupt
+ * line has been de-asserted.
+ *
+ * This means we need to loop through all ports. checking that they
+ * don't have an interrupt pending.
+ */
+static void serial8250_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct irq_info *i = dev_id;
+	struct list_head *l, *end = NULL;
+	int pass_counter = 0;
+
+	DEBUG_INTR("serial8250_interrupt(%d)...", irq);
+
+	spin_lock(&i->lock);
+
+	l = i->head;
+	do {
+		struct uart_8250_port *up;
+		unsigned int iir;
+
+		up = list_entry(l, struct uart_8250_port, list);
+
+		iir = serial_in(up, UART_IIR);
+		if (!(iir & UART_IIR_NO_INT)) {
+			spin_lock(&up->port.lock);
+			serial8250_handle_port(up, regs);
+			spin_unlock(&up->port.lock);
+
+			end = NULL;
+		} else if (end == NULL)
+			end = l;
+
+		l = l->next;
+
+		if (l == i->head && pass_counter++ > PASS_LIMIT) {
+			/* If we hit this, we're dead. */
+			printk(KERN_ERR "serial8250: too much work for "
+				"irq%d\n", irq);
+			break;
+		}
+	} while (l != end);
+
+	spin_unlock(&i->lock);
+
+	DEBUG_INTR("end.\n");
+}
+
+/*
+ * To support ISA shared interrupts, we need to have one interrupt
+ * handler that ensures that the IRQ line has been deasserted
+ * before returning.  Failing to do this will result in the IRQ
+ * line being stuck active, and, since ISA irqs are edge triggered,
+ * no more IRQs will be seen.
+ */
+static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
+{
+	spin_lock_irq(&i->lock);
+
+	if (!list_empty(i->head)) {
+		if (i->head == &up->list)
+			i->head = i->head->next;
+		list_del(&up->list);
+	} else {
+		BUG_ON(i->head != &up->list);
+		i->head = NULL;
+	}
+
+	spin_unlock_irq(&i->lock);
+}
+
+static int serial_link_irq_chain(struct uart_8250_port *up)
+{
+	struct irq_info *i = irq_lists + up->port.irq;
+	int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? SA_SHIRQ : 0;
+
+	spin_lock_irq(&i->lock);
+
+	if (i->head) {
+		list_add(&up->list, i->head);
+		spin_unlock_irq(&i->lock);
+
+		ret = 0;
+	} else {
+		INIT_LIST_HEAD(&up->list);
+		i->head = &up->list;
+		spin_unlock_irq(&i->lock);
+
+		ret = request_irq(up->port.irq, serial8250_interrupt,
+				  irq_flags, "serial", i);
+		if (ret < 0)
+			serial_do_unlink(i, up);
+	}
+
+	return ret;
+}
+
+static void serial_unlink_irq_chain(struct uart_8250_port *up)
+{
+	struct irq_info *i = irq_lists + up->port.irq;
+
+	BUG_ON(i->head == NULL);
+
+	if (list_empty(i->head))
+		free_irq(up->port.irq, i);
+
+	serial_do_unlink(i, up);
+}
+
+/*
+ * This function is used to handle ports that do not have an
+ * interrupt.  This doesn't work very well for 16450's, but gives
+ * barely passable results for a 16550A.  (Although at the expense
+ * of much CPU overhead).
+ */
+static void serial8250_timeout(unsigned long data)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)data;
+	unsigned int timeout;
+	unsigned int iir;
+
+	iir = serial_in(up, UART_IIR);
+	if (!(iir & UART_IIR_NO_INT)) {
+		spin_lock(&up->port.lock);
+		serial8250_handle_port(up, NULL);
+		spin_unlock(&up->port.lock);
+	}
+
+	timeout = up->port.timeout;
+	timeout = timeout > 6 ? (timeout / 2 - 2) : 1;
+	mod_timer(&up->timer, jiffies + timeout);
+}
+
+static unsigned int serial8250_tx_empty(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned long flags;
+	unsigned int ret;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	return ret;
+}
+
+static unsigned int serial8250_get_mctrl(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned long flags;
+	unsigned char status;
+	unsigned int ret;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	status = serial_in(up, UART_MSR);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	ret = 0;
+	if (status & UART_MSR_DCD)
+		ret |= TIOCM_CAR;
+	if (status & UART_MSR_RI)
+		ret |= TIOCM_RNG;
+	if (status & UART_MSR_DSR)
+		ret |= TIOCM_DSR;
+	if (status & UART_MSR_CTS)
+		ret |= TIOCM_CTS;
+	return ret;
+}
+
+static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned char mcr = 0;
+
+	if (mctrl & TIOCM_RTS)
+		mcr |= UART_MCR_RTS;
+	if (mctrl & TIOCM_DTR)
+		mcr |= UART_MCR_DTR;
+	if (mctrl & TIOCM_OUT1)
+		mcr |= UART_MCR_OUT1;
+	if (mctrl & TIOCM_OUT2)
+		mcr |= UART_MCR_OUT2;
+	if (mctrl & TIOCM_LOOP)
+		mcr |= UART_MCR_LOOP;
+
+	mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;
+
+	serial_out(up, UART_MCR, mcr);
+}
+
+static void serial8250_break_ctl(struct uart_port *port, int break_state)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	if (break_state == -1)
+		up->lcr |= UART_LCR_SBC;
+	else
+		up->lcr &= ~UART_LCR_SBC;
+	serial_out(up, UART_LCR, up->lcr);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static int serial8250_startup(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned long flags;
+	unsigned char lsr, iir;
+	int retval;
+
+	up->capabilities = uart_config[up->port.type].flags;
+	up->mcr = 0;
+	up->efr = 0;
+	up->ier = 0;
+
+	if (up->port.type == PORT_16C950) {
+		/* Wake up and initialize UART */
+		up->acr = 0;
+		serial_outp(up, UART_LCR, 0xBF);
+		serial_outp(up, UART_EFR, UART_EFR_ECB);
+		serial_outp(up, UART_IER, 0);
+		serial_outp(up, UART_LCR, 0);
+		serial_icr_write(up, UART_CSR, 0); /* Reset the UART */
+		serial_outp(up, UART_LCR, 0xBF);
+		serial_outp(up, UART_EFR, UART_EFR_ECB);
+		serial_outp(up, UART_LCR, 0);
+	}
+
+#ifdef CONFIG_SERIAL_8250_RSA
+	/*
+	 * If this is an RSA port, see if we can kick it up to the
+	 * higher speed clock.
+	 */
+	enable_rsa(up);
+#endif
+
+	/*
+	 * Clear the FIFO buffers and disable them.
+	 * (they will be reeanbled in change_speed())
+	 */
+	if (up->capabilities & UART_CLEAR_FIFO) {
+		serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+		serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
+				UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+		serial_outp(up, UART_FCR, 0);
+	}
+
+	/*
+	 * Clear the interrupt registers.
+	 */
+	(void) serial_inp(up, UART_LSR);
+	(void) serial_inp(up, UART_RX);
+	(void) serial_inp(up, UART_IIR);
+	(void) serial_inp(up, UART_MSR);
+
+	/*
+	 * At this point, there's no way the LSR could still be 0xff;
+	 * if it is, then bail out, because there's likely no UART
+	 * here.
+	 */
+	if (!(up->port.flags & UPF_BUGGY_UART) &&
+	    (serial_inp(up, UART_LSR) == 0xff)) {
+		printk("ttyS%d: LSR safety check engaged!\n", up->port.line);
+		return -ENODEV;
+	}
+
+	/*
+	 * If the "interrupt" for this port doesn't correspond with any
+	 * hardware interrupt, we use a timer-based system.  The original
+	 * driver used to do this with IRQ0.
+	 */
+	if (!is_real_interrupt(up->port.irq)) {
+		unsigned int timeout = up->port.timeout;
+
+		timeout = timeout > 6 ? (timeout / 2 - 2) : 1;
+
+		up->timer.data = (unsigned long)up;
+		mod_timer(&up->timer, jiffies + timeout);
+	} else {
+		retval = serial_link_irq_chain(up);
+		if (retval)
+			return retval;
+	}
+
+	/*
+	 * Now, initialize the UART
+	 */
+	serial_outp(up, UART_LCR, UART_LCR_WLEN8);
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	if (up->port.flags & UPF_FOURPORT) {
+		if (!is_real_interrupt(up->port.irq))
+			up->port.mctrl |= TIOCM_OUT1;
+	} else
+		/*
+		 * Most PC uarts need OUT2 raised to enable interrupts.
+		 */
+		if (is_real_interrupt(up->port.irq))
+			up->port.mctrl |= TIOCM_OUT2;
+
+	serial8250_set_mctrl(&up->port, up->port.mctrl);
+
+	/*
+	 * Do a quick test to see if we receive an
+	 * interrupt when we enable the TX irq.
+	 */
+	serial_outp(up, UART_IER, UART_IER_THRI);
+	lsr = serial_in(up, UART_LSR);
+	iir = serial_in(up, UART_IIR);
+	serial_outp(up, UART_IER, 0);
+
+	if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
+		up->capabilities |= UART_BAD_TX_ENABLE;
+		printk("ttyS%d - enabling bad tx status workarounds\n",
+			port->line);
+	}
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	/*
+	 * Finally, enable interrupts.  Note: Modem status interrupts
+	 * are set via change_speed(), which will be occuring imminently
+	 * anyway, so we don't enable them here.
+	 */
+	up->ier = UART_IER_RLSI | UART_IER_RDI;
+	serial_outp(up, UART_IER, up->ier);
+
+	if (up->port.flags & UPF_FOURPORT) {
+		unsigned int icp;
+		/*
+		 * Enable interrupts on the AST Fourport board
+		 */
+		icp = (up->port.iobase & 0xfe0) | 0x01f;
+		outb_p(0x80, icp);
+		(void) inb_p(icp);
+	}
+
+	/*
+	 * And clear the interrupt registers again for luck.
+	 */
+	(void) serial_inp(up, UART_LSR);
+	(void) serial_inp(up, UART_RX);
+	(void) serial_inp(up, UART_IIR);
+	(void) serial_inp(up, UART_MSR);
+
+	return 0;
+}
+
+static void serial8250_shutdown(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned long flags;
+
+	/*
+	 * Disable interrupts from this port
+	 */
+	up->ier = 0;
+	serial_outp(up, UART_IER, 0);
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	if (up->port.flags & UPF_FOURPORT) {
+		/* reset interrupts on the AST Fourport board */
+		inb((up->port.iobase & 0xfe0) | 0x1f);
+		up->port.mctrl |= TIOCM_OUT1;
+	} else
+		up->port.mctrl &= ~TIOCM_OUT2;
+
+	serial8250_set_mctrl(&up->port, up->port.mctrl);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	/*
+	 * Disable break condition and FIFOs
+	 */
+	serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC);
+	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
+				  UART_FCR_CLEAR_RCVR |
+				  UART_FCR_CLEAR_XMIT);
+	serial_outp(up, UART_FCR, 0);
+
+#ifdef CONFIG_SERIAL_8250_RSA
+	/*
+	 * Reset the RSA board back to 115kbps compat mode.
+	 */
+	disable_rsa(up);
+#endif
+
+	/*
+	 * Read data port to reset things, and then unlink from
+	 * the IRQ chain.
+	 */
+	(void) serial_in(up, UART_RX);
+
+	if (!is_real_interrupt(up->port.irq))
+		del_timer_sync(&up->timer);
+	else
+		serial_unlink_irq_chain(up);
+}
+
+static void serial8250_change_speed(struct uart_port *port, unsigned int cflag, unsigned int iflag, unsigned int quot)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned char cval, fcr = 0;
+	unsigned long flags;
+
+	switch (cflag & CSIZE) {
+	case CS5:
+		cval = 0x00;
+		break;
+	case CS6:
+		cval = 0x01;
+		break;
+	case CS7:
+		cval = 0x02;
+		break;
+	default:
+	case CS8:
+		cval = 0x03;
+		break;
+	}
+
+	if (cflag & CSTOPB)
+		cval |= 0x04;
+	if (cflag & PARENB)
+		cval |= UART_LCR_PARITY;
+	if (!(cflag & PARODD))
+		cval |= UART_LCR_EPAR;
+#ifdef CMSPAR
+	if (cflag & CMSPAR)
+		cval |= UART_LCR_SPAR;
+#endif
+
+	/*
+	 * Work around a bug in the Oxford Semiconductor 952 rev B
+	 * chip which causes it to seriously miscalculate baud rates
+	 * when DLL is 0.
+	 */
+	if ((quot & 0xff) == 0 && up->port.type == PORT_16C950 &&
+	    up->rev == 0x5201)
+		quot ++;
+
+	if (up->capabilities & UART_USE_FIFO) {
+		if ((up->port.uartclk / quot) < (2400 * 16))
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
+#ifdef CONFIG_SERIAL_8250_RSA
+		else if (up->port.type == PORT_RSA)
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_14;
+#endif
+		else
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
+	}
+	if (up->port.type == PORT_16750)
+		fcr |= UART_FCR7_64BYTE;
+
+	/*
+	 * Ok, we're now changing the port state.  Do it with
+	 * interrupts disabled.
+	 */
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
+	if (iflag & IGNPAR)
+		up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
+	if (iflag & (BRKINT | PARMRK))
+		up->port.read_status_mask |= UART_LSR_BI;
+
+	/*
+	 * Characteres to ignore
+	 */
+	up->port.ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
+	if (iflag & IGNBRK) {
+		up->port.ignore_status_mask |= UART_LSR_BI;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			up->port.ignore_status_mask |= UART_LSR_OE;
+	}
+
+	/*
+	 * ignore all characters if CREAD is not set
+	 */
+	if ((cflag & CREAD) == 0)
+		up->port.ignore_status_mask |= UART_LSR_DR;
+
+	/*
+	 * CTS flow control flag and modem status interrupts
+	 */
+	up->ier &= ~UART_IER_MSI;
+	if (UART_ENABLE_MS(&up->port, cflag))
+		up->ier |= UART_IER_MSI;
+
+	serial_out(up, UART_IER, up->ier);
+
+	if (up->capabilities & UART_MCRAFE) {
+		/*
+		 * TI16C750 hardware flow control
+		 */
+		up->mcr &= ~UART_MCR_AFE;
+		if (cflag & CRTSCTS)
+			up->mcr |= UART_MCR_AFE;
+	}
+	if (up->capabilities & UART_EFRAFE) {
+		/*
+		 * TI16C752/Startech hardware flow control
+		 * FIXME:
+		 * - TI16C752 requires control thresholds
+		 *   to be set for auto-RTS.
+		 * - We only enable auto-CTS here.
+		 * Note: ST16C654 does not allow MCR bit 1
+		 * to override RTS when UART_EFR_RTS is set.
+		 */
+		up->efr &= ~UART_EFR_CTS;
+		if (cflag & CRTSCTS)
+			up->efr |= UART_EFR_CTS;
+		serial_outp(up, UART_LCR, 0xBF);
+		serial_outp(up, UART_EFR, up->efr);
+	}
+
+	if (up->capabilities & UART_NATSEMI) {
+		/* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
+		serial_outp(up, UART_LCR, 0xe0);
+	} else {
+		serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
+	}
+	serial_outp(up, UART_DLL, quot & 0xff);		/* LS of divisor */
+	serial_outp(up, UART_DLM, quot >> 8);		/* MS of divisor */
+	if (up->port.type == PORT_16750)
+		serial_outp(up, UART_FCR, fcr);		/* set fcr */
+	serial_outp(up, UART_LCR, cval);		/* reset DLAB */
+	up->lcr = cval;					/* Save LCR */
+	if (up->port.type != PORT_16750) {
+		if (fcr & UART_FCR_ENABLE_FIFO) {
+			/* emulated UARTs (Lucent Venus 167x) need two steps */
+			serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+		}
+		serial_outp(up, UART_FCR, fcr);		/* set fcr */
+	}
+	serial8250_set_mctrl(&up->port, up->port.mctrl);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static void
+serial8250_pm(struct uart_port *port, unsigned int state,
+	      unsigned int oldstate)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	if (state) {
+		/* sleep */
+		if (up->capabilities & UART_STARTECH) {
+			/* Arrange to enter sleep mode */
+			serial_outp(up, UART_LCR, 0xBF);
+			serial_outp(up, UART_EFR, UART_EFR_ECB);
+			serial_outp(up, UART_LCR, 0);
+			serial_outp(up, UART_IER, UART_IERX_SLEEP);
+			serial_outp(up, UART_LCR, 0xBF);
+			serial_outp(up, UART_EFR, 0);
+			serial_outp(up, UART_LCR, 0);
+		}
+		if (up->port.type == PORT_16750) {
+			/* Arrange to enter sleep mode */
+			serial_outp(up, UART_IER, UART_IERX_SLEEP);
+		}
+	} else {
+		/* wake */
+		if (up->capabilities & UART_STARTECH) {
+			/* Wake up UART */
+			serial_outp(up, UART_LCR, 0xBF);
+			serial_outp(up, UART_EFR, UART_EFR_ECB);
+			/*
+			 * Turn off LCR == 0xBF so we actually set the IER
+			 * register on the XR16C850
+			 */
+			serial_outp(up, UART_LCR, 0);
+			serial_outp(up, UART_IER, 0);
+			/*
+			 * Now reset LCR so we can turn off the ECB bit
+			 */
+			serial_outp(up, UART_LCR, 0xBF);
+			serial_outp(up, UART_EFR, 0);
+			/*
+			 * For a XR16C850, we need to set the trigger levels
+			 */
+			if (up->port.type == PORT_16850) {
+				unsigned char fctr;
+
+				fctr = serial_inp(up, UART_FCTR) &
+					 ~(UART_FCTR_RX | UART_FCTR_TX);
+				serial_outp(up, UART_FCTR, fctr |
+						UART_FCTR_TRGD |
+						UART_FCTR_RX);
+				serial_outp(up, UART_TRG, UART_TRG_96);
+				serial_outp(up, UART_FCTR, fctr |
+						UART_FCTR_TRGD |
+						UART_FCTR_TX);
+				serial_outp(up, UART_TRG, UART_TRG_96);
+			}
+			serial_outp(up, UART_LCR, 0);
+		}
+
+		if (up->port.type == PORT_16750) {
+			/* Wake up UART */
+			serial_outp(up, UART_IER, 0);
+		}
+	}
+}
+
+/*
+ * Resource handling.  This is complicated by the fact that resources
+ * depend on the port type.  Maybe we should be claiming the standard
+ * 8250 ports, and then trying to get other resources as necessary?
+ */
+static int
+serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res)
+{
+	unsigned int size = 8 << up->port.regshift;
+	int ret = 0;
+
+	switch (up->port.iotype) {
+	case SERIAL_IO_MEM:
+		if (up->port.mapbase) {
+			*res = request_mem_region(up->port.mapbase, size, "serial");
+			if (!*res)
+				ret = -EBUSY;
+		}
+		break;
+
+	case SERIAL_IO_HUB6:
+	case SERIAL_IO_PORT:
+		*res = request_region(up->port.iobase, size, "serial");
+		if (!*res)
+			ret = -EBUSY;
+		break;
+	}
+	return ret;
+}
+
+static int
+serial8250_request_rsa_resource(struct uart_8250_port *up, struct resource **res)
+{
+	unsigned int size = 8 << up->port.regshift;
+	unsigned long start;
+	int ret = 0;
+
+	switch (up->port.iotype) {
+	case SERIAL_IO_MEM:
+		if (up->port.mapbase) {
+			start = up->port.mapbase;
+			start += UART_RSA_BASE << up->port.regshift;
+			*res = request_mem_region(start, size, "serial-rsa");
+			if (!*res)
+				ret = -EBUSY;
+		}
+		break;
+
+	case SERIAL_IO_HUB6:
+	case SERIAL_IO_PORT:
+		start = up->port.iobase;
+		start += UART_RSA_BASE << up->port.regshift;
+		*res = request_region(start, size, "serial-rsa");
+		if (!*res)
+			ret = -EBUSY;
+		break;
+	}
+
+	return ret;
+}
+
+static void serial8250_release_port(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned long start, offset = 0, size = 0;
+
+	if (up->port.type == PORT_RSA) {
+		offset = UART_RSA_BASE << up->port.regshift;
+		size = 8;
+	}
+
+	size <<= up->port.regshift;
+
+	switch (up->port.iotype) {
+	case SERIAL_IO_MEM:
+		if (up->port.mapbase) {
+			/*
+			 * Unmap the area.
+			 */
+			if (up->port.flags & UPF_IOREMAP) {
+				iounmap(up->port.membase);
+				up->port.membase = NULL;
+			}
+
+			start = up->port.mapbase;
+
+			if (size)
+				release_mem_region(start + offset, size);
+			release_mem_region(start, 8 << up->port.regshift);
+		}
+		break;
+
+	case SERIAL_IO_HUB6:
+	case SERIAL_IO_PORT:
+		start = up->port.iobase;
+
+		if (size)
+			release_region(start + offset, size);
+		release_region(start + offset, 8 << up->port.regshift);
+		break;
+
+	default:
+		break;
+	}
+}
+
+static int serial8250_request_port(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	struct resource *res = NULL, *res_rsa = NULL;
+	int ret = 0;
+
+	if (up->port.flags & UPF_RESOURCES) {
+		if (up->port.type == PORT_RSA) {
+			ret = serial8250_request_rsa_resource(up, &res_rsa);
+			if (ret < 0)
+				return ret;
+		}
+
+		ret = serial8250_request_std_resource(up, &res);
+	}
+
+	/*
+	 * If we have a mapbase, then request that as well.
+	 */
+	if (ret == 0 && up->port.flags & UPF_IOREMAP) {
+		int size = res->end - res->start + 1;
+
+		up->port.membase = ioremap(up->port.mapbase, size);
+		if (!up->port.membase)
+			ret = -ENOMEM;
+	}
+
+	if (ret < 0) {
+		if (res_rsa)
+			release_resource(res_rsa);
+		if (res)
+			release_resource(res);
+	}
+	return ret;
+}
+
+static void serial8250_config_port(struct uart_port *port, int flags)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	struct resource *res_std = NULL, *res_rsa = NULL;
+	int probeflags = PROBE_ANY;
+	int ret;
+
+#ifdef CONFIG_MCA
+	/*
+	 * Don't probe for MCA ports on non-MCA machines.
+	 */
+	if (up->port.flags & UPF_BOOT_ONLYMCA && !MCA_bus)
+		return;
+#endif
+
+	/*
+	 * Find the region that we can probe for.  This in turn
+	 * tells us whether we can probe for the type of port.
+	 */
+	if (up->port.flags & UPF_RESOURCES) {
+		ret = serial8250_request_std_resource(up, &res_std);
+		if (ret < 0)
+			return;
+
+		ret = serial8250_request_rsa_resource(up, &res_rsa);
+		if (ret < 0)
+			probeflags &= ~PROBE_RSA;
+	} else {
+		probeflags &= ~PROBE_RSA;
+	}
+
+	if (flags & UART_CONFIG_TYPE)
+		autoconfig(up, probeflags);
+	if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
+		autoconfig_irq(up);
+
+	/*
+	 * If the port wasn't an RSA port, release the resource.
+	 */
+	if (up->port.type != PORT_RSA && res_rsa)
+		release_resource(res_rsa);
+
+	if (up->port.type == PORT_UNKNOWN && res_std)
+		release_resource(res_std);
+}
+
+static int
+serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	if (ser->irq >= NR_IRQS || ser->irq < 0 ||
+	    ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
+	    ser->type > PORT_MAX_8250 || ser->type == PORT_CIRRUS ||
+	    ser->type == PORT_STARTECH)
+		return -EINVAL;
+	return 0;
+}
+
+static const char *
+serial8250_type(struct uart_port *port)
+{
+	int type = port->type;
+
+	if (type >= ARRAY_SIZE(uart_config))
+		type = 0;
+	return uart_config[type].name;
+}
+
+static struct uart_ops serial8250_pops = {
+	.tx_empty	= serial8250_tx_empty,
+	.set_mctrl	= serial8250_set_mctrl,
+	.get_mctrl	= serial8250_get_mctrl,
+	.stop_tx	= serial8250_stop_tx,
+	.start_tx	= serial8250_start_tx,
+	.stop_rx	= serial8250_stop_rx,
+	.enable_ms	= serial8250_enable_ms,
+	.break_ctl	= serial8250_break_ctl,
+	.startup	= serial8250_startup,
+	.shutdown	= serial8250_shutdown,
+	.change_speed	= serial8250_change_speed,
+	.pm		= serial8250_pm,
+	.type		= serial8250_type,
+	.release_port	= serial8250_release_port,
+	.request_port	= serial8250_request_port,
+	.config_port	= serial8250_config_port,
+	.verify_port	= serial8250_verify_port,
+};
+
+static struct uart_8250_port serial8250_ports[UART_NR];
+
+static void __init serial8250_isa_init_ports(void)
+{
+	struct uart_8250_port *up;
+	static int first = 1;
+	int i;
+
+	if (!first)
+		return;
+	first = 0;
+
+	for (i = 0, up = serial8250_ports; i < ARRAY_SIZE(old_serial_port);
+	     i++, up++) {
+		up->port.iobase   = old_serial_port[i].port;
+		up->port.irq      = irq_cannonicalize(old_serial_port[i].irq);
+		up->port.uartclk  = old_serial_port[i].baud_base * 16;
+		up->port.flags    = old_serial_port[i].flags |
+				    UPF_RESOURCES;
+		up->port.hub6     = old_serial_port[i].hub6;
+		up->port.membase  = old_serial_port[i].iomem_base;
+		up->port.iotype   = old_serial_port[i].io_type;
+		up->port.regshift = old_serial_port[i].iomem_reg_shift;
+		up->port.ops      = &serial8250_pops;
+
+		if (up->port.iotype == UPIO_MEM && up->port.mapbase)
+			up->port.flags |= UPF_IOREMAP;
+
+		if (share_irqs)
+			up->port.flags |= UPF_SHARE_IRQ;
+	}
+}
+
+static void __init serial8250_register_ports(struct uart_driver *drv)
+{
+	int i;
+
+	serial8250_isa_init_ports();
+
+	for (i = 0; i < UART_NR; i++) {
+		struct uart_8250_port *up = &serial8250_ports[i];
+
+		up->port.line = i;
+		up->port.ops = &serial8250_pops;
+		init_timer(&up->timer);
+		up->timer.function = serial8250_timeout;
+
+		/*
+		 * ALPHA_KLUDGE_MCR needs to be killed.
+		 */
+		up->mcr_mask = ~ALPHA_KLUDGE_MCR;
+		up->mcr_force = ALPHA_KLUDGE_MCR;
+
+		uart_add_one_port(drv, &up->port);
+	}
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+
+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
+/*
+ *	Wait for transmitter & holding register to empty
+ */
+static inline void wait_for_xmitr(struct uart_8250_port *up)
+{
+	unsigned int status, tmout = 10000;
+
+	/* Wait up to 10ms for the character(s) to be sent. */
+	do {
+		status = serial_in(up, UART_LSR);
+
+		if (status & UART_LSR_BI)
+			up->lsr_break_flag = UART_LSR_BI;
+
+		if (--tmout == 0)
+			break;
+		udelay(1);
+	} while ((status & BOTH_EMPTY) != BOTH_EMPTY);
+
+	/* Wait up to 1s for flow control if necessary */
+	if (up->port.flags & UPF_CONS_FLOW) {
+		tmout = 1000000;
+		while (--tmout &&
+		       ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
+			udelay(1);
+	}
+}
+
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ *
+ *	The console_lock must be held when we get here.
+ */
+static void
+serial8250_console_write(struct console *co, const char *s, unsigned int count)
+{
+	struct uart_8250_port *up = &serial8250_ports[co->index];
+	unsigned int ier;
+	int i;
+
+	/*
+	 *	First save the UER then disable the interrupts
+	 */
+	ier = serial_in(up, UART_IER);
+	serial_out(up, UART_IER, 0);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++, s++) {
+		wait_for_xmitr(up);
+
+		/*
+		 *	Send the character out.
+		 *	If a LF, also do CR...
+		 */
+		serial_out(up, UART_TX, *s);
+		if (*s == 10) {
+			wait_for_xmitr(up);
+			serial_out(up, UART_TX, 13);
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the IER
+	 */
+	wait_for_xmitr(up);
+	serial_out(up, UART_IER, ier);
+}
+
+static kdev_t serial8250_console_device(struct console *co)
+{
+	return MKDEV(TTY_MAJOR, 64 + co->index);
+}
+
+static int __init serial8250_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (co->index >= UART_NR)
+		co->index = 0;
+	port = &serial8250_ports[co->index].port;
+
+	/*
+	 * Temporary fix.
+	 */
+	spin_lock_init(&port->lock);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct console serial8250_console = {
+	.name		= "ttyS",
+	.write		= serial8250_console_write,
+	.device		= serial8250_console_device,
+	.setup		= serial8250_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+};
+
+void __init serial8250_console_init(void)
+{
+	serial8250_isa_init_ports();
+	register_console(&serial8250_console);
+}
+
+#define SERIAL8250_CONSOLE	&serial8250_console
+#else
+#define SERIAL8250_CONSOLE	NULL
+#endif
+
+static struct uart_driver serial8250_reg = {
+	.owner			= THIS_MODULE,
+#ifdef CONFIG_DEVFS_FS
+	.normal_name		= "tts/%d",
+	.callout_name		= "cua/%d",
+#else
+	.normal_name		= "ttyS",
+	.callout_name		= "cua",
+#endif
+	.normal_major		= TTY_MAJOR,
+	.callout_major		= TTYAUX_MAJOR,
+	.normal_driver		= &normal,
+	.callout_driver		= &callout,
+	.table			= serial8250_table,
+	.termios		= serial8250_termios,
+	.termios_locked		= serial8250_termios_locked,
+	.minor			= 64,
+	.nr			= UART_NR,
+	.cons			= SERIAL8250_CONSOLE,
+};
+
+/*
+ * register_serial and unregister_serial allows for 16x50 serial ports to be
+ * configured at run-time, to support PCMCIA modems.
+ */
+
+static int __register_serial(struct serial_struct *req, int line)
+{
+	struct uart_port port;
+
+	port.iobase   = req->port;
+	port.membase  = req->iomem_base;
+	port.irq      = req->irq;
+	port.uartclk  = req->baud_base * 16;
+	port.fifosize = req->xmit_fifo_size;
+	port.regshift = req->iomem_reg_shift;
+	port.iotype   = req->io_type;
+	port.flags    = req->flags | UPF_BOOT_AUTOCONF;
+	port.mapbase  = req->iomap_base;
+	port.line     = line;
+
+	if (share_irqs)
+		port.flags |= UPF_SHARE_IRQ;
+
+	if (HIGH_BITS_OFFSET)
+		port.iobase |= (long) req->port_high << HIGH_BITS_OFFSET;
+
+	/*
+	 * If a clock rate wasn't specified by the low level
+	 * driver, then default to the standard clock rate.
+	 */
+	if (port.uartclk == 0)
+		port.uartclk = BASE_BAUD * 16;
+
+	return uart_register_port(&serial8250_reg, &port);
+}
+
+/**
+ *	register_serial - configure a 16x50 serial port at runtime
+ *	@req: request structure
+ *
+ *	Configure the serial port specified by the request. If the
+ *	port exists and is in use an error is returned. If the port
+ *	is not currently in the table it is added.
+ *
+ *	The port is then probed and if necessary the IRQ is autodetected
+ *	If this fails an error is returned.
+ *
+ *	On success the port is ready to use and the line number is returned.
+ */
+int register_serial(struct serial_struct *req)
+{
+	return __register_serial(req, -1);
+}
+
+/**
+ *	unregister_serial - remove a 16x50 serial port at runtime
+ *	@line: serial line number
+ *
+ *	Remove one serial port.  This may be called from interrupt
+ *	context.
+ */
+void unregister_serial(int line)
+{
+	uart_unregister_port(&serial8250_reg, line);
+}
+
+/*
+ * This is for ISAPNP only.
+ */
+void serial8250_get_irq_map(unsigned int *map)
+{
+	int i;
+
+	for (i = 0; i < UART_NR; i++) {
+		if (serial8250_ports[i].port.type != PORT_UNKNOWN &&
+		    serial8250_ports[i].port.irq < 16)
+			*map |= 1 << serial8250_ports[i].port.irq;
+	}
+}
+
+static int __init serial8250_init(void)
+{
+	int ret, i;
+
+	for (i = 0; i < NR_IRQS; i++)
+		spin_lock_init(&irq_lists[i].lock);
+
+	ret = uart_register_driver(&serial8250_reg);
+	if (ret >= 0)
+		serial8250_register_ports(&serial8250_reg);
+
+	return ret;
+}
+
+static void __exit serial8250_exit(void)
+{
+	int i;
+
+	for (i = 0; i < UART_NR; i++)
+		uart_remove_one_port(&serial8250_reg, &serial8250_ports[i].port);
+
+	uart_unregister_driver(&serial8250_reg);
+}
+
+module_init(serial8250_init);
+module_exit(serial8250_exit);
+
+EXPORT_SYMBOL(register_serial);
+EXPORT_SYMBOL(unregister_serial);
+EXPORT_SYMBOL(serial8250_get_irq_map);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic 8250/16x50 serial driver");
+
+MODULE_PARM(share_irqs, "i");
+MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
+	" (unsafe)");
+
+#if defined(CONFIG_SERIAL_8250_RSA) && defined(MODULE)
+MODULE_PARM(probe_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i");
+MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
+MODULE_PARM(force_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i");
+MODULE_PARM_DESC(force_rsa, "Force I/O ports for RSA");
+#endif /* CONFIG_SERIAL_8250_RSA  */
+
diff -urN linux-2.4.29/drivers/serial/8250.h linux-2.4.29-uc1/drivers/serial/8250.h
--- linux-2.4.29/drivers/serial/8250.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/serial/8250.h	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,88 @@
+/*
+ *  linux/drivers/serial/8250.h
+ *
+ *  Driver for 8250/16550-type serial ports
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright (C) 2001 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ *  $Id: 8250.h,v 1.1.1.1.2.1 2002/10/24 09:53:24 rmk Exp $
+ */
+
+#include <linux/config.h>
+
+struct serial8250_probe {
+	struct module	*owner;
+	int		(*pci_init_one)(struct pci_dev *dev);
+	void		(*pci_remove_one)(struct pci_dev *dev);
+	void		(*pnp_init)(void);
+};
+
+int serial8250_register_probe(struct serial8250_probe *probe);
+void serial8250_unregister_probe(struct serial8250_probe *probe);
+void serial8250_get_irq_map(unsigned int *map);
+
+struct old_serial_port {
+	unsigned int uart;
+	unsigned int baud_base;
+	unsigned int port;
+	unsigned int irq;
+	unsigned int flags;
+	unsigned char hub6;
+	unsigned char io_type;
+	unsigned char *iomem_base;
+	unsigned short iomem_reg_shift;
+};
+
+struct serial8250_config {
+	const char	*name;
+	unsigned int	dfl_xmit_fifo_size;
+	unsigned int	flags;
+};
+
+#define UART_CLEAR_FIFO		0x01
+#define UART_USE_FIFO		0x02
+#define UART_STARTECH		0x04
+#define UART_NATSEMI		0x08
+#define UART_MCRAFE		0x10	/* TI16C750-style auto-flow */
+#define UART_EFRAFE		0x20	/* TI16C752/startech auto-flow */
+
+#define UART_BAD_TX_ENABLE	0x80000000
+
+#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
+#define SERIAL_INLINE
+#endif
+  
+#ifdef SERIAL_INLINE
+#define _INLINE_ inline
+#else
+#define _INLINE_
+#endif
+
+#define PROBE_RSA	(1 << 0)
+#define PROBE_ANY	(~0)
+
+#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
+
+#ifdef CONFIG_SERIAL_8250_SHARE_IRQ
+#define SERIAL8250_SHARE_IRQS 1
+#else
+#define SERIAL8250_SHARE_IRQS 0
+#endif
+
+#if defined(__alpha__) && !defined(CONFIG_PCI)
+/*
+ * Digital did something really horribly wrong with the OUT1 and OUT2
+ * lines on at least some ALPHA's.  The failure mode is that if either
+ * is cleared, the machine locks up with endless interrupts.
+ */
+#define ALPHA_KLUDGE_MCR  (UART_MCR_OUT2 | UART_MCR_OUT1)
+#else
+#define ALPHA_KLUDGE_MCR 0
+#endif
diff -urN linux-2.4.29/drivers/serial/8250_pci.c linux-2.4.29-uc1/drivers/serial/8250_pci.c
--- linux-2.4.29/drivers/serial/8250_pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/serial/8250_pci.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,1080 @@
+/*
+ *  linux/drivers/char/serial_8250_pci.c
+ *
+ *  Probe module for 8250/16550-type PCI serial ports.
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright (C) 2001 Russell King, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ *  $Id: 8250_pci.c,v 1.8.2.1 2002/10/24 09:53:24 rmk Exp $
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/serial.h>
+
+/* 2.4.6 compatibility cruft ;( */
+#define pci_board __pci_board
+#include <linux/serialP.h>
+#undef pci_board
+
+#include <asm/bitops.h>
+#include <asm/byteorder.h>
+#include <asm/serial.h>
+
+#include "8250.h"
+
+#ifndef IS_PCI_REGION_IOPORT
+#define IS_PCI_REGION_IOPORT(dev, r) (pci_resource_flags((dev), (r)) & \
+				      IORESOURCE_IO)
+#endif
+#ifndef IS_PCI_REGION_IOMEM
+#define IS_PCI_REGION_IOMEM(dev, r) (pci_resource_flags((dev), (r)) & \
+				      IORESOURCE_MEM)
+#endif
+#ifndef PCI_IRQ_RESOURCE
+#define PCI_IRQ_RESOURCE(dev, r) ((dev)->irq_resource[r].start)
+#endif
+
+#ifndef pci_get_subvendor
+#define pci_get_subvendor(dev) ((dev)->subsystem_vendor)
+#define pci_get_subdevice(dev)  ((dev)->subsystem_device)
+#endif
+
+struct serial_private {
+	unsigned int nr;
+	struct pci_board *board;
+	int line[0];
+};
+
+struct pci_board {
+	int flags;
+	int num_ports;
+	int base_baud;
+	int uart_offset;
+	int reg_shift;
+	int (*init_fn)(struct pci_dev *dev, struct pci_board *board,
+			int enable);
+	int first_uart_offset;
+};
+
+static int
+get_pci_port(struct pci_dev *dev, struct pci_board *board,
+	     struct serial_struct *req, int idx)
+{
+	unsigned long port;
+	int base_idx;
+	int max_port;
+	int offset;
+
+	base_idx = SPCI_FL_GET_BASE(board->flags);
+	if (board->flags & SPCI_FL_BASE_TABLE)
+		base_idx += idx;
+
+	if (board->flags & SPCI_FL_REGION_SZ_CAP) {
+		max_port = pci_resource_len(dev, base_idx) / 8;
+		if (idx >= max_port)
+			return 1;
+	}
+			
+	offset = board->first_uart_offset;
+
+	/* Timedia/SUNIX uses a mixture of BARs and offsets */
+	/* Ugh, this is ugly as all hell --- TYT */
+	if(dev->vendor == PCI_VENDOR_ID_TIMEDIA )  /* 0x1409 */
+		switch(idx) {
+			case 0: base_idx=0;
+				break;
+			case 1: base_idx=0; offset=8;
+				break;
+			case 2: base_idx=1; 
+				break;
+			case 3: base_idx=1; offset=8;
+				break;
+			case 4: /* BAR 2*/
+			case 5: /* BAR 3 */
+			case 6: /* BAR 4*/
+			case 7: base_idx=idx-2; /* BAR 5*/
+		}
+
+	/* Some Titan cards are also a little weird */
+	if (dev->vendor == PCI_VENDOR_ID_TITAN &&
+	    (dev->device == PCI_DEVICE_ID_TITAN_400L ||
+	     dev->device == PCI_DEVICE_ID_TITAN_800L)) {
+		switch (idx) {
+		case 0: base_idx = 1;
+			break;
+		case 1: base_idx = 2;
+			break;
+		default:
+			base_idx = 4;
+			offset = 8 * (idx - 2);
+		}
+	}
+  
+	port =  pci_resource_start(dev, base_idx) + offset;
+
+	if ((board->flags & SPCI_FL_BASE_TABLE) == 0)
+		port += idx * (board->uart_offset ? board->uart_offset : 8);
+
+	if (IS_PCI_REGION_IOPORT(dev, base_idx)) {
+		req->port = port;
+		if (HIGH_BITS_OFFSET)
+			req->port_high = port >> HIGH_BITS_OFFSET;
+		else
+			req->port_high = 0;
+		return 0;
+	}
+	req->io_type = SERIAL_IO_MEM;
+	req->iomem_base = ioremap(port, board->uart_offset);
+	req->iomem_reg_shift = board->reg_shift;
+	req->port = 0;
+	return 0;
+}
+
+static _INLINE_ int get_pci_irq(struct pci_dev *dev,
+				struct pci_board *board,
+				int idx)
+{
+	int base_idx;
+
+	if ((board->flags & SPCI_FL_IRQRESOURCE) == 0)
+		return dev->irq;
+
+	base_idx = SPCI_FL_GET_IRQBASE(board->flags);
+	if (board->flags & SPCI_FL_IRQ_TABLE)
+		base_idx += idx;
+	
+	return PCI_IRQ_RESOURCE(dev, base_idx);
+}
+
+/*
+ * Some PCI serial cards using the PLX 9050 PCI interface chip require
+ * that the card interrupt be explicitly enabled or disabled.  This
+ * seems to be mainly needed on card using the PLX which also use I/O
+ * mapped memory.
+ */
+static int __devinit
+pci_plx9050_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+{
+	u8 data, *p, irq_config;
+	int pci_config;
+
+	irq_config = 0x41;
+	pci_config = PCI_COMMAND_MEMORY;
+	if (dev->vendor == PCI_VENDOR_ID_PANACOM)
+		irq_config = 0x43;
+	if ((dev->vendor == PCI_VENDOR_ID_PLX) &&
+	    (dev->device == PCI_DEVICE_ID_PLX_ROMULUS)) {
+		/*
+		 * As the megawolf cards have the int pins active
+		 * high, and have 2 UART chips, both ints must be
+		 * enabled on the 9050. Also, the UARTS are set in
+		 * 16450 mode by default, so we have to enable the
+		 * 16C950 'enhanced' mode so that we can use the deep
+		 * FIFOs
+		 */
+		irq_config = 0x5b;
+		pci_config = PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+	}
+	
+	pci_read_config_byte(dev, PCI_COMMAND, &data);
+
+	if (enable)
+		pci_write_config_byte(dev, PCI_COMMAND,
+				      data | pci_config);
+	
+	/* enable/disable interrupts */
+	p = ioremap(pci_resource_start(dev, 0), 0x80);
+	writel(enable ? irq_config : 0x00, (unsigned long)p + 0x4c);
+	iounmap(p);
+
+	if (!enable)
+		pci_write_config_byte(dev, PCI_COMMAND,
+				      data & ~pci_config);
+	return 0;
+}
+
+
+/*
+ * SIIG serial cards have an PCI interface chip which also controls
+ * the UART clocking frequency. Each UART can be clocked independently
+ * (except cards equiped with 4 UARTs) and initial clocking settings
+ * are stored in the EEPROM chip. It can cause problems because this
+ * version of serial driver doesn't support differently clocked UART's
+ * on single PCI card. To prevent this, initialization functions set
+ * high frequency clocking for all UART's on given card. It is safe (I
+ * hope) because it doesn't touch EEPROM settings to prevent conflicts
+ * with other OSes (like M$ DOS).
+ *
+ *  SIIG support added by Andrey Panin <pazke@mail.tp.ru>, 10/1999
+ * 
+ * There is two family of SIIG serial cards with different PCI
+ * interface chip and different configuration methods:
+ *     - 10x cards have control registers in IO and/or memory space;
+ *     - 20x cards have control registers in standard PCI configuration space.
+ */
+
+#define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc)
+#define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8)
+
+static int __devinit
+pci_siig10x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+{
+       u16 data, *p;
+
+       if (!enable) return 0;
+
+       p = ioremap(pci_resource_start(dev, 0), 0x80);
+
+       switch (dev->device & 0xfff8) {
+               case PCI_DEVICE_ID_SIIG_1S_10x:         /* 1S */
+                       data = 0xffdf;
+                       break;
+               case PCI_DEVICE_ID_SIIG_2S_10x:         /* 2S, 2S1P */
+                       data = 0xf7ff;
+                       break;
+               default:                                /* 1S1P, 4S */
+                       data = 0xfffb;
+                       break;
+       }
+
+       writew(readw((unsigned long) p + 0x28) & data, (unsigned long) p + 0x28);
+       iounmap(p);
+       return 0;
+}
+
+#define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc)
+#define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc)
+
+static int __devinit
+pci_siig20x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+{
+       u8 data;
+
+       if (!enable) return 0;
+
+       /* Change clock frequency for the first UART. */
+       pci_read_config_byte(dev, 0x6f, &data);
+       pci_write_config_byte(dev, 0x6f, data & 0xef);
+
+       /* If this card has 2 UART, we have to do the same with second UART. */
+       if (((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S_20x) ||
+           ((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S1P_20x)) {
+               pci_read_config_byte(dev, 0x73, &data);
+               pci_write_config_byte(dev, 0x73, data & 0xef);
+       }
+       return 0;
+}
+
+/* Added for EKF Intel i960 serial boards */
+static int __devinit
+pci_inteli960ni_fn(struct pci_dev *dev,
+		   struct pci_board *board,
+		   int enable)
+{
+	unsigned long oldval;
+	
+	if (!(pci_get_subdevice(dev) & 0x1000))
+		return(-1);
+
+	if (!enable) /* is there something to deinit? */
+		return(0);
+   
+	/* is firmware started? */
+	pci_read_config_dword(dev, 0x44, (void*) &oldval); 
+	if (oldval == 0x00001000L) { /* RESET value */ 
+		printk(KERN_DEBUG "Local i960 firmware missing");
+		return(-1); 
+	}
+	return(0);
+}
+
+/*
+ * Timedia has an explosion of boards, and to avoid the PCI table from
+ * growing *huge*, we use this function to collapse some 70 entries
+ * in the PCI table into one, for sanity's and compactness's sake.
+ */
+static unsigned short timedia_single_port[] = {
+	0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0 };
+static unsigned short timedia_dual_port[] = {
+	0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085,
+	0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079, 
+	0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079, 
+	0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079,
+	0xD079, 0 };
+static unsigned short timedia_quad_port[] = {
+	0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157, 
+	0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159, 
+	0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056,
+	0xB157, 0 };
+static unsigned short timedia_eight_port[] = {
+	0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166, 
+	0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0 };
+static struct timedia_struct {
+	int num;
+	unsigned short *ids;
+} timedia_data[] = {
+	{ 1, timedia_single_port },
+	{ 2, timedia_dual_port },
+	{ 4, timedia_quad_port },
+	{ 8, timedia_eight_port },
+	{ 0, 0 }
+};
+
+static int __devinit
+pci_timedia_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+{
+	int	i, j;
+	unsigned short *ids;
+
+	if (!enable)
+		return 0;
+
+	for (i=0; timedia_data[i].num; i++) {
+		ids = timedia_data[i].ids;
+		for (j=0; ids[j]; j++) {
+			if (pci_get_subdevice(dev) == ids[j]) {
+				board->num_ports = timedia_data[i].num;
+				return 0;
+			}
+		}
+	}
+	return 0;
+}
+
+static int __devinit
+pci_xircom_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+{
+	__set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(HZ/10);
+	return 0;
+}
+
+/*
+ * This is the configuration table for all of the PCI serial boards
+ * which we support.  It is directly indexed by the pci_board_num_t enum
+ * value, which is encoded in the pci_device_id PCI probe table's
+ * driver_data member.
+ */
+enum pci_board_num_t {
+	pbn_b0_1_115200,
+	pbn_default = 0,
+
+	pbn_b0_2_115200,
+	pbn_b0_4_115200,
+
+	pbn_b0_1_921600,
+	pbn_b0_2_921600,
+	pbn_b0_4_921600,
+
+	pbn_b0_bt_1_115200,
+	pbn_b0_bt_2_115200,
+	pbn_b0_bt_1_460800,
+	pbn_b0_bt_2_460800,
+
+	pbn_b1_1_115200,
+	pbn_b1_2_115200,
+	pbn_b1_4_115200,
+	pbn_b1_8_115200,
+
+	pbn_b1_2_921600,
+	pbn_b1_4_921600,
+	pbn_b1_8_921600,
+
+	pbn_b1_2_1382400,
+	pbn_b1_4_1382400,
+	pbn_b1_8_1382400,
+
+	pbn_b2_8_115200,
+	pbn_b2_4_460800,
+	pbn_b2_8_460800,
+	pbn_b2_16_460800,
+	pbn_b2_4_921600,
+	pbn_b2_8_921600,
+
+	pbn_b2_bt_1_115200,
+	pbn_b2_bt_2_115200,
+	pbn_b2_bt_4_115200,
+	pbn_b2_bt_2_921600,
+
+	pbn_panacom,
+	pbn_panacom2,
+	pbn_panacom4,
+	pbn_plx_romulus,
+	pbn_oxsemi,
+	pbn_timedia,
+	pbn_intel_i960,
+	pbn_sgi_ioc3,
+#ifdef CONFIG_DDB5074
+	pbn_nec_nile4,
+#endif
+#if 0
+	pbn_dci_pccom8,
+#endif
+	pbn_xircom_combo,
+
+	pbn_siig10x_0,
+	pbn_siig10x_1,
+	pbn_siig10x_2,
+	pbn_siig10x_4,
+	pbn_siig20x_0,
+	pbn_siig20x_2,
+	pbn_siig20x_4,
+	
+	pbn_computone_4,
+	pbn_computone_6,
+	pbn_computone_8,
+};
+
+static struct pci_board pci_boards[] __devinitdata = {
+	/*
+	 * PCI Flags, Number of Ports, Base (Maximum) Baud Rate,
+	 * Offset to get to next UART's registers,
+	 * Register shift to use for memory-mapped I/O,
+	 * Initialization function, first UART offset
+	 */
+
+	/* Generic serial board, pbn_b0_1_115200, pbn_default */
+	{ SPCI_FL_BASE0, 1, 115200 },		/* pbn_b0_1_115200,
+						   pbn_default */
+
+	{ SPCI_FL_BASE0, 2, 115200 },		/* pbn_b0_2_115200 */
+	{ SPCI_FL_BASE0, 4, 115200 },		/* pbn_b0_4_115200 */
+
+	{ SPCI_FL_BASE0, 1, 921600 },		/* pbn_b0_1_921600 */
+	{ SPCI_FL_BASE0, 2, 921600 },		/* pbn_b0_2_921600 */
+	{ SPCI_FL_BASE0, 4, 921600 },		/* pbn_b0_4_921600 */
+
+	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* pbn_b0_bt_1_115200 */
+	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* pbn_b0_bt_2_115200 */
+	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 460800 }, /* pbn_b0_bt_1_460800 */
+	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 }, /* pbn_b0_bt_2_460800 */
+
+	{ SPCI_FL_BASE1, 1, 115200 },		/* pbn_b1_1_115200 */
+	{ SPCI_FL_BASE1, 2, 115200 },		/* pbn_b1_2_115200 */
+	{ SPCI_FL_BASE1, 4, 115200 },		/* pbn_b1_4_115200 */
+	{ SPCI_FL_BASE1, 8, 115200 },		/* pbn_b1_8_115200 */
+
+	{ SPCI_FL_BASE1, 2, 921600 },		/* pbn_b1_2_921600 */
+	{ SPCI_FL_BASE1, 4, 921600 },		/* pbn_b1_4_921600 */
+	{ SPCI_FL_BASE1, 8, 921600 },		/* pbn_b1_8_921600 */
+
+	{ SPCI_FL_BASE1, 2, 1382400 },		/* pbn_b1_2_1382400 */
+	{ SPCI_FL_BASE1, 4, 1382400 },		/* pbn_b1_4_1382400 */
+	{ SPCI_FL_BASE1, 8, 1382400 },		/* pbn_b1_8_1382400 */
+
+	{ SPCI_FL_BASE2, 8, 115200 },		/* pbn_b2_8_115200 */
+	{ SPCI_FL_BASE2, 4, 460800 },		/* pbn_b2_4_460800 */
+	{ SPCI_FL_BASE2, 8, 460800 },		/* pbn_b2_8_460800 */
+	{ SPCI_FL_BASE2, 16, 460800 },		/* pbn_b2_16_460800 */
+	{ SPCI_FL_BASE2, 4, 921600 },		/* pbn_b2_4_921600 */
+	{ SPCI_FL_BASE2, 8, 921600 },		/* pbn_b2_8_921600 */
+
+	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* pbn_b2_bt_1_115200 */
+	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* pbn_b2_bt_2_115200 */
+	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 115200 }, /* pbn_b2_bt_4_115200 */
+	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600 }, /* pbn_b2_bt_2_921600 */
+
+	{ SPCI_FL_BASE2, 2, 921600, /* IOMEM */		   /* pbn_panacom */
+		0x400, 7, pci_plx9050_fn },
+	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600,   /* pbn_panacom2 */
+		0x400, 7, pci_plx9050_fn },
+	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 921600,   /* pbn_panacom4 */
+		0x400, 7, pci_plx9050_fn },
+	{ SPCI_FL_BASE2, 4, 921600,			   /* pbn_plx_romulus */
+		0x20, 2, pci_plx9050_fn, 0x03 },
+		/* This board uses the size of PCI Base region 0 to
+		 * signal now many ports are available */
+	{ SPCI_FL_BASE0 | SPCI_FL_REGION_SZ_CAP, 32, 115200 }, /* pbn_oxsemi */
+	{ SPCI_FL_BASE_TABLE, 1, 921600,		   /* pbn_timedia */
+		0, 0, pci_timedia_fn },
+	/* EKF addition for i960 Boards form EKF with serial port */
+	{ SPCI_FL_BASE0, 32, 921600, /* max 256 ports */   /* pbn_intel_i960 */
+		8<<2, 2, pci_inteli960ni_fn, 0x10000},
+	{ SPCI_FL_BASE0 | SPCI_FL_IRQRESOURCE,		   /* pbn_sgi_ioc3 */
+		1, 458333, 0, 0, 0, 0x20178 },
+#ifdef CONFIG_DDB5074
+	/*
+	 * NEC Vrc-5074 (Nile 4) builtin UART.
+	 * Conditionally compiled in since this is a motherboard device.
+	 */
+	{ SPCI_FL_BASE0, 1, 520833,			   /* pbn_nec_nile4 */
+		64, 3, NULL, 0x300 },
+#endif
+#if 0	/* PCI_DEVICE_ID_DCI_PCCOM8 ? */		   /* pbn_dci_pccom8 */
+	{ SPCI_FL_BASE3, 8, 115200, 8 },
+#endif
+	{ SPCI_FL_BASE0, 1, 115200,			  /* pbn_xircom_combo */
+		0, 0, pci_xircom_fn },
+
+	{ SPCI_FL_BASE2, 1, 460800,			   /* pbn_siig10x_0 */
+		0, 0, pci_siig10x_fn },
+	{ SPCI_FL_BASE2, 1, 921600,			   /* pbn_siig10x_1 */
+		0, 0, pci_siig10x_fn },
+	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600,   /* pbn_siig10x_2 */
+		0, 0, pci_siig10x_fn },
+	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 921600,   /* pbn_siig10x_4 */
+		0, 0, pci_siig10x_fn },
+	{ SPCI_FL_BASE0, 1, 921600,			   /* pbn_siix20x_0 */
+		0, 0, pci_siig20x_fn },
+	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 921600,   /* pbn_siix20x_2 */
+		0, 0, pci_siig20x_fn },
+	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 4, 921600,   /* pbn_siix20x_4 */
+		0, 0, pci_siig20x_fn },
+
+	{ SPCI_FL_BASE0, 4, 921600, /* IOMEM */		   /* pbn_computone_4 */
+		0x40, 2, NULL, 0x200 },
+	{ SPCI_FL_BASE0, 6, 921600, /* IOMEM */		   /* pbn_computone_6 */
+		0x40, 2, NULL, 0x200 },
+	{ SPCI_FL_BASE0, 8, 921600, /* IOMEM */		   /* pbn_computone_8 */
+		0x40, 2, NULL, 0x200 },
+};
+
+/*
+ * Given a complete unknown PCI device, try to use some heuristics to
+ * guess what the configuration might be, based on the pitiful PCI
+ * serial specs.  Returns 0 on success, 1 on failure.
+ */
+static int __devinit serial_pci_guess_board(struct pci_dev *dev,
+					   struct pci_board *board)
+{
+	int	num_iomem = 0, num_port = 0, first_port = -1;
+	int	i;
+	
+	/*
+	 * If it is not a communications device or the programming
+	 * interface is greater than 6, give up.
+	 *
+	 * (Should we try to make guesses for multiport serial devices
+	 * later?) 
+	 */
+	if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) &&
+	    ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
+	    (dev->class & 0xff) > 6)
+		return 1;
+
+	for (i=0; i < 6; i++) {
+		if (IS_PCI_REGION_IOPORT(dev, i)) {
+			num_port++;
+			if (first_port == -1)
+				first_port = i;
+		}
+		if (IS_PCI_REGION_IOMEM(dev, i))
+			num_iomem++;
+	}
+
+	/*
+	 * If there is 1 or 0 iomem regions, and exactly one port, use
+	 * it.
+	 */
+	if (num_iomem <= 1 && num_port == 1) {
+		board->flags = first_port;
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * return -1 to refuse
+ */
+static int pci_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
+{
+	struct serial_private *priv;
+	struct pci_board *board, tmp;
+	struct serial_struct serial_req;
+	int base_baud, rc, k;
+
+	board = &pci_boards[ent->driver_data];
+
+	rc = pci_enable_device(dev);
+	if (rc)
+		return rc;
+
+	if (ent->driver_data == pbn_default &&
+	    serial_pci_guess_board(dev, board))
+		return -ENODEV;
+	else if (serial_pci_guess_board(dev, &tmp) == 0) {
+		printk(KERN_INFO "Redundant entry in serial pci_table.  "
+		       "Please send the output of\n"
+		       "lspci -vv, this message (%d,%d,%d,%d)\n"
+		       "and the manufacturer and name of "
+		       "serial board or modem board\n"
+		       "to serial-pci-info@lists.sourceforge.net.\n",
+		       dev->vendor, dev->device,
+		       pci_get_subvendor(dev), pci_get_subdevice(dev));
+	}
+
+
+	priv = kmalloc(sizeof(struct serial_private) +
+			      sizeof(unsigned int) * board->num_ports,
+			      GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	/*
+	 * Run the initialization function, if any
+	 */
+	if (board->init_fn && ((board->init_fn)(dev, board, 1) != 0)) {
+		kfree(priv);
+		return -ENODEV;
+	}
+
+	base_baud = board->base_baud;
+	if (!base_baud)
+		base_baud = BASE_BAUD;
+	memset(&serial_req, 0, sizeof(serial_req));
+	for (k=0; k < board->num_ports; k++) {
+		serial_req.irq = get_pci_irq(dev, board, k);
+		if (get_pci_port(dev, board, &serial_req, k))
+			break;
+#ifdef SERIAL_DEBUG_PCI
+		printk("Setup PCI/PNP port: port %x, irq %d, type %d\n",
+		       serial_req.port, serial_req.irq, serial_req.io_type);
+#endif
+		serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE;
+		serial_req.baud_base = base_baud;
+		priv->line[k] = register_serial(&serial_req);
+		if (priv->line[k] < 0)
+			break;
+	}
+
+	priv->board = board;
+	priv->nr = k;
+
+	pci_set_drvdata(dev, priv);
+
+	return 0;
+}
+
+static void pci_remove_one(struct pci_dev *dev)
+{
+	struct serial_private *priv = pci_get_drvdata(dev);
+	int i;
+
+	pci_set_drvdata(dev, NULL);
+
+	for (i = 0; i < priv->nr; i++)
+		unregister_serial(priv->line[i]);
+
+	priv->board->init_fn(dev, priv->board, 0);
+
+	kfree(priv);
+}
+
+static struct pci_device_id serial_pci_tbl[] __devinitdata = {
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
+		pbn_b1_8_1382400 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
+		pbn_b1_4_1382400 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
+		pbn_b1_2_1382400 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
+		pbn_b1_8_1382400 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
+		pbn_b1_4_1382400 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
+		pbn_b1_2_1382400 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485, 0, 0,
+		pbn_b1_8_921600 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4, 0, 0,
+		pbn_b1_8_921600 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485, 0, 0,
+		pbn_b1_4_921600 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2, 0, 0,
+		pbn_b1_4_921600 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485, 0, 0,
+		pbn_b1_2_921600 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6, 0, 0,
+		pbn_b1_8_921600 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1, 0, 0,
+		pbn_b1_8_921600 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1, 0, 0,
+		pbn_b1_4_921600 },
+
+	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b2_bt_1_115200 },
+	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM2,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b2_bt_2_115200 },
+	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM422,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b2_bt_4_115200 },
+	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM232,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b2_bt_2_115200 },
+	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM4,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b2_bt_4_115200 },
+	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM8,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b2_8_115200 },
+
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_GTEK_SERIAL2,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b2_bt_2_115200 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM200,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b2_bt_2_921600 },
+	/* VScom SPCOM800, from sl@s.pl */
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM800, 
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b2_8_921600 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_1077,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b2_4_921600 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+		PCI_SUBVENDOR_ID_KEYSPAN,
+		PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0,
+		pbn_panacom },
+	{	PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_QUADMODEM,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_panacom4 },
+	{	PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_DUALMODEM,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_panacom2 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+		PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+		PCI_SUBDEVICE_ID_CHASE_PCIFAST4, 0, 0, 
+		pbn_b2_4_460800 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+		PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+		PCI_SUBDEVICE_ID_CHASE_PCIFAST8, 0, 0, 
+		pbn_b2_8_460800 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+		PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+		PCI_SUBDEVICE_ID_CHASE_PCIFAST16, 0, 0, 
+		pbn_b2_16_460800 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+		PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+		PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC, 0, 0, 
+		pbn_b2_16_460800 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+		PCI_SUBVENDOR_ID_CHASE_PCIRAS,
+		PCI_SUBDEVICE_ID_CHASE_PCIRAS4, 0, 0, 
+		pbn_b2_4_460800 },
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+		PCI_SUBVENDOR_ID_CHASE_PCIRAS,
+		PCI_SUBDEVICE_ID_CHASE_PCIRAS8, 0, 0, 
+		pbn_b2_8_460800 },
+	/* Megawolf Romulus PCI Serial Card, from Mike Hudson */
+	/* (Exoray@isys.ca) */
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS,
+		0x10b5, 0x106a, 0, 0,
+		pbn_plx_romulus },
+	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b1_4_115200 },
+	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b1_2_115200 },
+	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b1_8_115200 },
+	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b1_8_115200 },
+	{	PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954,
+		PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, 0, 0, 
+		pbn_b0_4_921600 },
+	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b0_4_115200 },
+	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b0_2_115200 },
+
+	/* Digitan DS560-558, from jimd@esoft.com */
+	{	PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_ATT_VENUS_MODEM,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b1_1_115200 },
+
+	/* 3Com US Robotics 56k Voice Internal PCI model 5610 */
+	{	PCI_VENDOR_ID_USR, 0x1008,
+		PCI_ANY_ID, PCI_ANY_ID, },
+
+	/* Titan Electronic cards */
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b0_1_921600 },
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b0_2_921600 },
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b0_4_921600 },
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800B,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
+		pbn_b0_4_921600 },
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100L,
+		PCI_ANY_ID, PCI_ANY_ID,
+		SPCI_FL_BASE1, 1, 921600 },
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200L,
+		PCI_ANY_ID, PCI_ANY_ID,
+		SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 },
+	/* The 400L and 800L have a custom hack in get_pci_port */
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400L,
+		PCI_ANY_ID, PCI_ANY_ID,
+		SPCI_FL_BASE_TABLE, 4, 921600 },
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L,
+		PCI_ANY_ID, PCI_ANY_ID,
+		SPCI_FL_BASE_TABLE, 8, 921600 },
+
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_1 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_1 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_1 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_4 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_4 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig10x_4 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_0 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_2 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_550,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_4 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_4 },
+	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_siig20x_4 },
+
+	/* Computone devices submitted by Doug McNash dmcnash@computone.com */
+	{	PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+		PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG4,
+		0, 0, pbn_computone_4 },
+	{	PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+		PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG8,
+		0, 0, pbn_computone_8 },
+	{	PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+		PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG6,
+		0, 0, pbn_computone_6 },
+
+	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI95N,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_oxsemi },
+	{	PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889,
+		PCI_VENDOR_ID_TIMEDIA, PCI_ANY_ID, 0, 0, pbn_timedia },
+
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DSERIAL,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_2_115200 },
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_A,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_2_115200 },
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_2_115200 },
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_PLUS,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_2_460800 },
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_A,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_2_460800 },
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_2_460800 },
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_SSERIAL,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_1_115200 },
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_650,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_1_460800 },
+
+	/* RAStel 2 port modem, gerg@moreton.com.au */
+	{	PCI_VENDOR_ID_MORETON, PCI_DEVICE_ID_RASTEL_2PORT,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b2_bt_2_115200 },
+
+	/* EKF addition for i960 Boards form EKF with serial port */
+	{	PCI_VENDOR_ID_INTEL, 0x1960,
+		0xE4BF, PCI_ANY_ID, 0, 0,
+		pbn_intel_i960 },
+
+	/* Xircom Cardbus/Ethernet combos */
+	{	PCI_VENDOR_ID_XIRCOM, PCI_DEVICE_ID_XIRCOM_X3201_MDM,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_xircom_combo },
+
+	/*
+	 * Untested PCI modems, sent in from various folks...
+	 */
+
+	/* Elsa Model 56K PCI Modem, from Andreas Rath <arh@01019freenet.de> */
+	{	PCI_VENDOR_ID_ROCKWELL, 0x1004,
+		0x1048, 0x1500, 0, 0,
+		pbn_b1_1_115200 },
+
+	{	PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
+		0xFF00, 0, 0, 0,
+		pbn_sgi_ioc3 },
+
+#ifdef CONFIG_DDB5074
+	/*
+	 * NEC Vrc-5074 (Nile 4) builtin UART.
+	 * Conditionally compiled in since this is a motherboard device.
+	 */
+	{	PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_NILE4,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_nec_nile4 },
+#endif
+
+#if 0	/* PCI_DEVICE_ID_DCI_PCCOM8 ? */
+	{	PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM8,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_dci_pccom8 },
+#endif
+
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xffff00, },
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  PCI_CLASS_COMMUNICATION_MODEM << 8, 0xffff00, },
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00, },
+	{ 0, }
+};
+
+static struct pci_driver serial_pci_driver = {
+	name:		"serial",
+	probe:		pci_init_one,
+	remove:		pci_remove_one,
+	id_table:	serial_pci_tbl,
+};
+
+static int __init serial8250_pci_init(void)
+{
+	return pci_module_init(&serial_pci_driver);
+}
+
+static void __exit serial8250_pci_exit(void)
+{
+	pci_unregister_driver(&serial_pci_driver);
+}
+
+module_init(serial8250_pci_init);
+module_exit(serial8250_pci_exit);
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic 8250/16x50 PCI serial probe module");
+MODULE_GENERIC_TABLE(pci, serial_pci_tbl);
diff -urN linux-2.4.29/drivers/serial/8250_pnp.c linux-2.4.29-uc1/drivers/serial/8250_pnp.c
--- linux-2.4.29/drivers/serial/8250_pnp.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/serial/8250_pnp.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,553 @@
+/*
+ *  linux/drivers/char/serial_8250_pnp.c
+ *
+ *  Probe module for 8250/16550-type ISAPNP serial ports.
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright (C) 2001 Russell King, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ *  $Id: 8250_pnp.c,v 1.3.2.1 2002/10/24 09:53:25 rmk Exp $
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/isapnp.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+
+#include <asm/bitops.h>
+#include <asm/byteorder.h>
+#include <asm/serial.h>
+
+#include "8250.h"
+
+static struct serial_state rs_table[] = { };
+#define NR_PORTS 0
+
+struct pnpbios_device_id
+{
+	char id[8];
+	unsigned long driver_data;
+};
+
+static const struct pnpbios_device_id pnp_dev_table[] = {
+	/* Archtek America Corp. */
+	/* Archtek SmartLink Modem 3334BT Plug & Play */
+	{	"AAC000F",		0	},
+	/* Anchor Datacomm BV */
+	/* SXPro 144 External Data Fax Modem Plug & Play */
+	{	"ADC0001",		0	},
+	/* SXPro 288 External Data Fax Modem Plug & Play */
+	{	"ADC0002",		0	},
+	/* Rockwell 56K ACF II Fax+Data+Voice Modem */
+	{	"AKY1021",		SPCI_FL_NO_SHIRQ	},
+	/* AZT3005 PnP SOUND DEVICE */
+	{	"AZT4001",		0	},
+	/* Best Data Products Inc. Smart One 336F PnP Modem */
+	{	"BDP3336",		0	},
+	/*  Boca Research */
+	/* Boca Complete Ofc Communicator 14.4 Data-FAX */
+	{	"BRI0A49",		0	},
+	/* Boca Research 33,600 ACF Modem */
+	{	"BRI1400",		0	},
+	/* Boca 33.6 Kbps Internal FD34FSVD */
+	{	"BRI3400",		0	},
+	/* Boca 33.6 Kbps Internal FD34FSVD */
+	{	"BRI0A49",		0	},
+	/* Best Data Products Inc. Smart One 336F PnP Modem */
+	{	"BDP3336",		0	},
+	/* Computer Peripherals Inc */
+	/* EuroViVa CommCenter-33.6 SP PnP */
+	{	"CPI4050",		0	},
+	/* Creative Labs */
+	/* Creative Labs Phone Blaster 28.8 DSVD PnP Voice */
+	{	"CTL3001",		0	},
+	/* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */
+	{	"CTL3011",		0	},
+	/* Creative */
+	/* Creative Modem Blaster Flash56 DI5601-1 */
+	{	"DMB1032",		0	},
+	/* Creative Modem Blaster V.90 DI5660 */
+	{	"DMB2001",		0	},
+	/* FUJITSU */
+	/* Fujitsu 33600 PnP-I2 R Plug & Play */
+	{	"FUJ0202",		0	},
+	/* Fujitsu FMV-FX431 Plug & Play */
+	{	"FUJ0205",		0	},
+	/* Fujitsu 33600 PnP-I4 R Plug & Play */
+	{	"FUJ0206",		0	},
+	/* Fujitsu Fax Voice 33600 PNP-I5 R Plug & Play */
+	{	"FUJ0209",		0	},
+	/* Archtek America Corp. */
+	/* Archtek SmartLink Modem 3334BT Plug & Play */
+	{	"GVC000F",		0	},
+	/* Hayes */
+	/* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */
+	{	"HAY0001",		0	},
+	/* Hayes Optima 336 V.34 + FAX + Voice PnP */
+	{	"HAY000C",		0	},
+	/* Hayes Optima 336B V.34 + FAX + Voice PnP */
+	{	"HAY000D",		0	},
+	/* Hayes Accura 56K Ext Fax Modem PnP */
+	{	"HAY5670",		0	},
+	/* Hayes Accura 56K Ext Fax Modem PnP */
+	{	"HAY5674",		0	},
+	/* Hayes Accura 56K Fax Modem PnP */
+	{	"HAY5675",		0	},
+	/* Hayes 288, V.34 + FAX */
+	{	"HAYF000",		0	},
+	/* Hayes Optima 288 V.34 + FAX + Voice, Plug & Play */
+	{	"HAYF001",		0	},
+	/* IBM */
+	/* IBM Thinkpad 701 Internal Modem Voice */
+	{	"IBM0033",		0	},
+	/* Intertex */
+	/* Intertex 28k8 33k6 Voice EXT PnP */
+	{	"IXDC801",		0	},
+	/* Intertex 33k6 56k Voice EXT PnP */
+	{	"IXDC901",		0	},
+	/* Intertex 28k8 33k6 Voice SP EXT PnP */
+	{	"IXDD801",		0	},
+	/* Intertex 33k6 56k Voice SP EXT PnP */
+	{	"IXDD901",		0	},
+	/* Intertex 28k8 33k6 Voice SP INT PnP */
+	{	"IXDF401",		0	},
+	/* Intertex 28k8 33k6 Voice SP EXT PnP */
+	{	"IXDF801",		0	},
+	/* Intertex 33k6 56k Voice SP EXT PnP */
+	{	"IXDF901",		0	},
+	/* Kortex International */
+	/* KORTEX 28800 Externe PnP */
+	{	"KOR4522",		0	},
+	/* KXPro 33.6 Vocal ASVD PnP */
+	{	"KORF661",		0	},
+	/* Lasat */
+	/* LASAT Internet 33600 PnP */
+	{	"LAS4040",		0	},
+	/* Lasat Safire 560 PnP */
+	{	"LAS4540",		0	},
+	/* Lasat Safire 336  PnP */
+	{	"LAS5440",		0	},
+	/* Microcom, Inc. */
+	/* Microcom TravelPorte FAST V.34 Plug & Play */
+	{	"MNP0281",		0	},
+	/* Microcom DeskPorte V.34 FAST or FAST+ Plug & Play */
+	{	"MNP0336",		0	},
+	/* Microcom DeskPorte FAST EP 28.8 Plug & Play */
+	{	"MNP0339",		0	},
+	/* Microcom DeskPorte 28.8P Plug & Play */
+	{	"MNP0342",		0	},
+	/* Microcom DeskPorte FAST ES 28.8 Plug & Play */
+	{	"MNP0500",		0	},
+	/* Microcom DeskPorte FAST ES 28.8 Plug & Play */
+	{	"MNP0501",		0	},
+	/* Microcom DeskPorte 28.8S Internal Plug & Play */
+	{	"MNP0502",		0	},
+	/* Motorola */
+	/* Motorola BitSURFR Plug & Play */
+	{	"MOT1105",		0	},
+	/* Motorola TA210 Plug & Play */
+	{	"MOT1111",		0	},
+	/* Motorola HMTA 200 (ISDN) Plug & Play */
+	{	"MOT1114",		0	},
+	/* Motorola BitSURFR Plug & Play */
+	{	"MOT1115",		0	},
+	/* Motorola Lifestyle 28.8 Internal */
+	{	"MOT1190",		0	},
+	/* Motorola V.3400 Plug & Play */
+	{	"MOT1501",		0	},
+	/* Motorola Lifestyle 28.8 V.34 Plug & Play */
+	{	"MOT1502",		0	},
+	/* Motorola Power 28.8 V.34 Plug & Play */
+	{	"MOT1505",		0	},
+	/* Motorola ModemSURFR External 28.8 Plug & Play */
+	{	"MOT1509",		0	},
+	/* Motorola Premier 33.6 Desktop Plug & Play */
+	{	"MOT150A",		0	},
+	/* Motorola VoiceSURFR 56K External PnP */
+	{	"MOT150F",		0	},
+	/* Motorola ModemSURFR 56K External PnP */
+	{	"MOT1510",		0	},
+	/* Motorola ModemSURFR 56K Internal PnP */
+	{	"MOT1550",		0	},
+	/* Motorola ModemSURFR Internal 28.8 Plug & Play */
+	{	"MOT1560",		0	},
+	/* Motorola Premier 33.6 Internal Plug & Play */
+	{	"MOT1580",		0	},
+	/* Motorola OnlineSURFR 28.8 Internal Plug & Play */
+	{	"MOT15B0",		0	},
+	/* Motorola VoiceSURFR 56K Internal PnP */
+	{	"MOT15F0",		0	},
+	/* Com 1 */
+	/*  Deskline K56 Phone System PnP */
+	{	"MVX00A1",		0	},
+	/* PC Rider K56 Phone System PnP */
+	{	"MVX00F2",		0	},
+	/* Pace 56 Voice Internal Plug & Play Modem */
+	{	"PMC2430",		0	},
+	/* Generic */
+	/* Generic standard PC COM port	 */
+	{	"PNP0500",		0	},
+	/* Generic 16550A-compatible COM port */
+	{	"PNP0501",		0	},
+	/* Compaq 14400 Modem */
+	{	"PNPC000",		0	},
+	/* Compaq 2400/9600 Modem */
+	{	"PNPC001",		0	},
+	/* Dial-Up Networking Serial Cable between 2 PCs */
+	{	"PNPC031",		0	},
+	/* Dial-Up Networking Parallel Cable between 2 PCs */
+	{	"PNPC032",		0	},
+	/* Standard 9600 bps Modem */
+	{	"PNPC100",		0	},
+	/* Standard 14400 bps Modem */
+	{	"PNPC101",		0	},
+	/*  Standard 28800 bps Modem*/
+	{	"PNPC102",		0	},
+	/*  Standard Modem*/
+	{	"PNPC103",		0	},
+	/*  Standard 9600 bps Modem*/
+	{	"PNPC104",		0	},
+	/*  Standard 14400 bps Modem*/
+	{	"PNPC105",		0	},
+	/*  Standard 28800 bps Modem*/
+	{	"PNPC106",		0	},
+	/*  Standard Modem */
+	{	"PNPC107",		0	},
+	/* Standard 9600 bps Modem */
+	{	"PNPC108",		0	},
+	/* Standard 14400 bps Modem */
+	{	"PNPC109",		0	},
+	/* Standard 28800 bps Modem */
+	{	"PNPC10A",		0	},
+	/* Standard Modem */
+	{	"PNPC10B",		0	},
+	/* Standard 9600 bps Modem */
+	{	"PNPC10C",		0	},
+	/* Standard 14400 bps Modem */
+	{	"PNPC10D",		0	},
+	/* Standard 28800 bps Modem */
+	{	"PNPC10E",		0	},
+	/* Standard Modem */
+	{	"PNPC10F",		0	},
+	/* Standard PCMCIA Card Modem */
+	{	"PNP2000",		0	},
+	/* Rockwell */
+	/* Modular Technology */
+	/* Rockwell 33.6 DPF Internal PnP */
+	/* Modular Technology 33.6 Internal PnP */
+	{	"ROK0030",		0	},
+	/* Kortex International */
+	/* KORTEX 14400 Externe PnP */
+	{	"ROK0100",		0	},
+	/* Viking Components, Inc */
+	/* Viking 28.8 INTERNAL Fax+Data+Voice PnP */
+	{	"ROK4920",		0	},
+	/* Rockwell */
+	/* British Telecom */
+	/* Modular Technology */
+	/* Rockwell 33.6 DPF External PnP */
+	/* BT Prologue 33.6 External PnP */
+	/* Modular Technology 33.6 External PnP */
+	{	"RSS00A0",		0	},
+	/* Viking 56K FAX INT */
+	{	"RSS0262",		0	},
+	/* SupraExpress 28.8 Data/Fax PnP modem */
+	{	"SUP1310",		0	},
+	/* SupraExpress 33.6 Data/Fax PnP modem */
+	{	"SUP1421",		0	},
+	/* SupraExpress 33.6 Data/Fax PnP modem */
+	{	"SUP1590",		0	},
+	/* SupraExpress 33.6 Data/Fax PnP modem */
+	{	"SUP1760",		0	},
+	/* Phoebe Micro */
+	/* Phoebe Micro 33.6 Data Fax 1433VQH Plug & Play */
+	{	"TEX0011",		0	},
+	/* Archtek America Corp. */
+	/* Archtek SmartLink Modem 3334BT Plug & Play */
+	{	"UAC000F",		0	},
+	/* 3Com Corp. */
+	/* Gateway Telepath IIvi 33.6 */
+	{	"USR0000",		0	},
+	/*  Sportster Vi 14.4 PnP FAX Voicemail */
+	{	"USR0004",		0	},
+	/* U.S. Robotics 33.6K Voice INT PnP */
+	{	"USR0006",		0	},
+	/* U.S. Robotics 33.6K Voice EXT PnP */
+	{	"USR0007",		0	},
+	/* U.S. Robotics 33.6K Voice INT PnP */
+	{	"USR2002",		0	},
+	/* U.S. Robotics 56K Voice INT PnP */
+	{	"USR2070",		0	},
+	/* U.S. Robotics 56K Voice EXT PnP */
+	{	"USR2080",		0	},
+	/* U.S. Robotics 56K FAX INT */
+	{	"USR3031",		0	},
+	/* U.S. Robotics 56K Voice INT PnP */
+	{	"USR3070",		0	},
+	/* U.S. Robotics 56K Voice EXT PnP */
+	{	"USR3080",		0	},
+	/* U.S. Robotics 56K Voice INT PnP */
+	{	"USR3090",		0	},
+	/* U.S. Robotics 56K Message  */
+	{	"USR9100",		0	},
+	/* U.S. Robotics 56K FAX EXT PnP*/
+	{	"USR9160",		0	},
+	/* U.S. Robotics 56K FAX INT PnP*/
+	{	"USR9170",		0	},
+	/* U.S. Robotics 56K Voice EXT PnP*/
+	{	"USR9180",		0	},
+	/* U.S. Robotics 56K Voice INT PnP*/
+	{	"USR9190",		0	},
+	{	"",			0	}
+};
+
+static void inline avoid_irq_share(struct pci_dev *dev)
+{
+	int i, map = 0x1FF8;
+	struct serial_state *state = rs_table;
+	struct isapnp_irq *irq;
+	struct isapnp_resources *res = dev->sysdata;
+
+	for (i = 0; i < NR_PORTS; i++) {
+		if (state->type != PORT_UNKNOWN)
+			clear_bit(state->irq, &map);
+		state++;
+	}
+
+	for ( ; res; res = res->alt)
+		for(irq = res->irq; irq; irq = irq->next)
+			irq->map = map;
+}
+
+static char *modem_names[] __devinitdata = {
+	"MODEM", "Modem", "modem", "FAX", "Fax", "fax",
+	"56K", "56k", "K56", "33.6", "28.8", "14.4",
+	"33,600", "28,800", "14,400", "33.600", "28.800", "14.400",
+	"33600", "28800", "14400", "V.90", "V.34", "V.32", 0
+};
+
+static int __devinit check_name(char *name)
+{
+	char **tmp;
+
+	for (tmp = modem_names; *tmp; tmp++)
+		if (strstr(name, *tmp))
+			return 1;
+
+	return 0;
+}
+
+static int inline check_compatible_id(struct pci_dev *dev)
+{
+	int i;
+	for (i = 0; i < DEVICE_COUNT_COMPATIBLE; i++)
+		if ((dev->vendor_compatible[i] ==
+		     ISAPNP_VENDOR('P', 'N', 'P')) &&
+		    (swab16(dev->device_compatible[i]) >= 0xc000) &&
+		    (swab16(dev->device_compatible[i]) <= 0xdfff))
+			return 0;
+	return 1;
+}
+
+/*
+ * Given a complete unknown ISA PnP device, try to use some heuristics to
+ * detect modems. Currently use such heuristic set:
+ *     - dev->name or dev->bus->name must contain "modem" substring;
+ *     - device must have only one IO region (8 byte long) with base adress
+ *       0x2e8, 0x3e8, 0x2f8 or 0x3f8.
+ *
+ * Such detection looks very ugly, but can detect at least some of numerous
+ * ISA PnP modems, alternatively we must hardcode all modems in pnp_devices[]
+ * table.
+ */
+static int serial_pnp_guess_board(struct pci_dev *dev, int *flags)
+{
+	struct isapnp_resources *res = (struct isapnp_resources *)dev->sysdata;
+	struct isapnp_resources *resa;
+
+	if (!(check_name(dev->name) || check_name(dev->bus->name)) &&
+	    !(check_compatible_id(dev)))
+		return -ENODEV;
+
+	if (!res || res->next)
+		return -ENODEV;
+
+	for (resa = res->alt; resa; resa = resa->alt) {
+		struct isapnp_port *port;
+		for (port = res->port; port; port = port->next)
+			if ((port->size == 8) &&
+			    ((port->min == 0x2f8) ||
+			     (port->min == 0x3f8) ||
+			     (port->min == 0x2e8) ||
+			     (port->min == 0x3e8)))
+				return 0;
+	}
+
+	return -ENODEV;
+}
+
+static int
+pnp_init_one(struct pci_dev *dev, const struct pnpbios_device_id *ent,
+	     char *slot_name)
+{
+	struct serial_struct serial_req;
+	int ret, line, flags = ent ? ent->driver_data : 0;
+
+	if (!ent) {
+		ret = serial_pnp_guess_board(dev, &flags);
+		if (ret)
+			return ret;
+	}
+
+	if (dev->prepare(dev) < 0) {
+		printk("serial: PNP device '%s' prepare failed\n",
+			slot_name);
+		return -ENODEV;
+	}
+
+	if (dev->active)
+		return -ENODEV;
+
+	if (flags & SPCI_FL_NO_SHIRQ)
+		avoid_irq_share(dev);
+
+	if (dev->activate(dev) < 0) {
+		printk("serial: PNP device '%s' activate failed\n",
+			slot_name);
+		return -ENODEV;
+	}
+
+	memset(&serial_req, 0, sizeof(serial_req));
+	serial_req.irq = dev->irq_resource[0].start;
+	serial_req.port = pci_resource_start(dev, 0);
+	if (HIGH_BITS_OFFSET)
+		serial_req.port = pci_resource_start(dev, 0) >> HIGH_BITS_OFFSET;
+
+#ifdef SERIAL_DEBUG_PCI
+	printk("Setup PCI/PNP port: port %x, irq %d, type %d\n",
+	       serial_req.port, serial_req.irq, serial_req.io_type);
+#endif
+
+	serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE;
+	serial_req.baud_base = 115200;
+	line = register_serial(&serial_req);
+
+	if (line >= 0) {
+		pci_set_drvdata(dev, (void *)(line + 1));
+
+		/*
+		 * Public health warning: remove this once the 2.5
+		 * pnpbios_module_init() stuff is incorporated.
+		 */
+		dev->driver = (void *)pnp_dev_table;
+	} else
+		dev->deactivate(dev);
+
+	return line >= 0 ? 0 : -ENODEV;
+}
+
+static void pnp_remove_one(struct pci_dev *dev)
+{
+	int line = (int)pci_get_drvdata(dev);
+
+	if (line) {
+		pci_set_drvdata(dev, NULL);
+
+		unregister_serial(line - 1);
+
+		dev->deactivate(dev);
+	}
+}
+
+static char hex[] = "0123456789ABCDEF";
+
+/*
+ * This function should vanish when 2.5 comes around and
+ * we have pnpbios_module_init()
+ */
+static void pnp_init(void)
+{
+	const struct pnpbios_device_id *id;
+	struct pci_dev *dev = NULL;
+
+#ifdef SERIAL_DEBUG_PNP
+	printk("Entered probe_serial_pnp()\n");
+#endif
+
+	isapnp_for_each_dev(dev) {
+		char slot_name[8];
+		u32 pnpid;
+
+		if (dev->active)
+			continue;
+
+		pnpid = dev->vendor << 16 | dev->device;
+		pnpid = cpu_to_le32(pnpid);
+
+#define HEX(id,a) hex[((id)>>a) & 15]
+#define CHAR(id,a) (0x40 + (((id)>>a) & 31))
+		slot_name[0] = CHAR(pnpid, 26);
+		slot_name[1] = CHAR(pnpid, 21);
+		slot_name[2] = CHAR(pnpid, 16);
+		slot_name[3] = HEX(pnpid, 12);
+		slot_name[4] = HEX(pnpid, 8);
+		slot_name[5] = HEX(pnpid, 4);
+		slot_name[6] = HEX(pnpid, 0);
+		slot_name[7] = '\0';
+		
+		for (id = pnp_dev_table; id->id[0]; id++)
+			if (memcmp(id->id, slot_name, 7) == 0)
+				break;
+
+		if (id->id[0])
+			pnp_init_one(dev, id, slot_name);
+		else
+			pnp_init_one(dev, NULL, slot_name);
+	}
+
+#ifdef SERIAL_DEBUG_PNP
+	printk("Leaving probe_serial_pnp() (probe finished)\n");
+#endif
+}
+
+static int __init serial8250_pnp_init(void)
+{
+	if (!isapnp_present()) {
+#ifdef SERIAL_DEBUG_PNP
+		printk("Leaving probe_serial_pnp() (no isapnp)\n");
+#endif
+		return -ENODEV;
+	}
+	pnp_init();
+	return 0;
+}
+
+static void __exit serial8250_pnp_exit(void)
+{
+	struct pci_dev *dev = NULL;
+
+	isapnp_for_each_dev(dev) {
+		if (dev->driver != (void *)pnp_dev_table)
+			continue;
+		pnp_remove_one(dev);
+	}
+}
+
+module_init(serial8250_pnp_init);
+module_exit(serial8250_pnp_exit);
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic 8250/16x50 PNPBIOS serial probe module");
+MODULE_GENERIC_TABLE(pnp, pnp_dev_table);
+
diff -urN linux-2.4.29/drivers/serial/amba.c linux-2.4.29-uc1/drivers/serial/amba.c
--- linux-2.4.29/drivers/serial/amba.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/serial/amba.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,778 @@
+/*
+ *  linux/drivers/char/serial_amba.c
+ *
+ *  Driver for AMBA serial ports
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *  $Id: amba.c,v 1.9.2.2 2002/10/24 09:53:25 rmk Exp $
+ *
+ * This is a generic driver for ARM AMBA-type serial ports.  They
+ * have a lot of 16550-like features, but are not register compatable.
+ * Note that although they do have CTS, DCD and DSR inputs, they do
+ * not have an RI input, nor do they have DTR or RTS outputs.  If
+ * required, these have to be supplied via some other means (eg, GPIO)
+ * and hooked into this driver.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#if defined(CONFIG_SERIAL_AMBA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+
+#include <asm/hardware/serial_amba.h>
+
+#define UART_NR		2
+
+#define SERIAL_AMBA_MAJOR	204
+#define SERIAL_AMBA_MINOR	16
+#define SERIAL_AMBA_NR		UART_NR
+
+#define CALLOUT_AMBA_NAME	"cuaam"
+#define CALLOUT_AMBA_MAJOR	205
+#define CALLOUT_AMBA_MINOR	16
+#define CALLOUT_AMBA_NR		UART_NR
+
+static struct tty_driver normal, callout;
+static struct tty_struct *amba_table[UART_NR];
+static struct termios *amba_termios[UART_NR], *amba_termios_locked[UART_NR];
+#ifdef SUPPORT_SYSRQ
+static struct console amba_console;
+#endif
+
+#define AMBA_ISR_PASS_LIMIT	256
+
+/*
+ * Access macros for the AMBA UARTs
+ */
+#define UART_GET_INT_STATUS(p)	readb((p)->membase + AMBA_UARTIIR)
+#define UART_PUT_ICR(p, c)	writel((c), (p)->membase + AMBA_UARTICR)
+#define UART_GET_FR(p)		readb((p)->membase + AMBA_UARTFR)
+#define UART_GET_CHAR(p)	readb((p)->membase + AMBA_UARTDR)
+#define UART_PUT_CHAR(p, c)	writel((c), (p)->membase + AMBA_UARTDR)
+#define UART_GET_RSR(p)		readb((p)->membase + AMBA_UARTRSR)
+#define UART_GET_CR(p)		readb((p)->membase + AMBA_UARTCR)
+#define UART_PUT_CR(p,c)	writel((c), (p)->membase + AMBA_UARTCR)
+#define UART_GET_LCRL(p)	readb((p)->membase + AMBA_UARTLCR_L)
+#define UART_PUT_LCRL(p,c)	writel((c), (p)->membase + AMBA_UARTLCR_L)
+#define UART_GET_LCRM(p)	readb((p)->membase + AMBA_UARTLCR_M)
+#define UART_PUT_LCRM(p,c)	writel((c), (p)->membase + AMBA_UARTLCR_M)
+#define UART_GET_LCRH(p)	readb((p)->membase + AMBA_UARTLCR_H)
+#define UART_PUT_LCRH(p,c)	writel((c), (p)->membase + AMBA_UARTLCR_H)
+#define UART_RX_DATA(s)		(((s) & AMBA_UARTFR_RXFE) == 0)
+#define UART_TX_READY(s)	(((s) & AMBA_UARTFR_TXFF) == 0)
+#define UART_TX_EMPTY(p)	((UART_GET_FR(p) & AMBA_UARTFR_TMSK) == 0)
+
+#define UART_DUMMY_RSR_RX	256
+#define UART_PORT_SIZE		64
+
+/*
+ * On the Integrator platform, the port RTS and DTR are provided by
+ * bits in the following SC_CTRLS register bits:
+ *        RTS  DTR
+ *  UART0  7    6
+ *  UART1  5    4
+ */
+#define SC_CTRLC	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
+#define SC_CTRLS	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
+
+/*
+ * We wrap our port structure around the generic uart_port.
+ */
+struct uart_amba_port {
+	struct uart_port	port;
+	unsigned int		dtr_mask;
+	unsigned int		rts_mask;
+	unsigned int		old_status;
+};
+
+static void ambauart_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	unsigned int cr;
+
+	cr = UART_GET_CR(port);
+	cr &= ~AMBA_UARTCR_TIE;
+	UART_PUT_CR(port, cr);
+}
+
+static void ambauart_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	unsigned int cr;
+
+	cr = UART_GET_CR(port);
+	cr |= AMBA_UARTCR_TIE;
+	UART_PUT_CR(port, cr);
+}
+
+static void ambauart_stop_rx(struct uart_port *port)
+{
+	unsigned int cr;
+
+	cr = UART_GET_CR(port);
+	cr &= ~(AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE);
+	UART_PUT_CR(port, cr);
+}
+
+static void ambauart_enable_ms(struct uart_port *port)
+{
+	unsigned int cr;
+
+	cr = UART_GET_CR(port);
+	cr |= AMBA_UARTCR_MSIE;
+	UART_PUT_CR(port, cr);
+}
+
+static void
+#ifdef SUPPORT_SYSRQ
+ambauart_rx_chars(struct uart_port *port, struct pt_regs *regs)
+#else
+ambauart_rx_chars(struct uart_port *port)
+#endif
+{
+	struct tty_struct *tty = port->info->tty;
+	unsigned int status, ch, rsr, max_count = 256;
+
+	status = UART_GET_FR(port);
+	while (UART_RX_DATA(status) && max_count--) {
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			tty->flip.tqueue.routine((void *)tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+				printk(KERN_WARNING "TTY_DONT_FLIP set\n");
+				return;
+			}
+		}
+
+		ch = UART_GET_CHAR(port);
+
+		*tty->flip.char_buf_ptr = ch;
+		*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		port->icount.rx++;
+
+		/*
+		 * Note that the error handling code is
+		 * out of the main execution path
+		 */
+		rsr = UART_GET_RSR(port) | UART_DUMMY_RSR_RX;
+		if (rsr & AMBA_UARTRSR_ANY) {
+			if (rsr & AMBA_UARTRSR_BE) {
+				rsr &= ~(AMBA_UARTRSR_FE | AMBA_UARTRSR_PE);
+				port->icount.brk++;
+				if (uart_handle_break(port))
+					goto ignore_char;
+			} else if (rsr & AMBA_UARTRSR_PE)
+				port->icount.parity++;
+			else if (rsr & AMBA_UARTRSR_FE)
+				port->icount.frame++;
+			if (rsr & AMBA_UARTRSR_OE)
+				port->icount.overrun++;
+
+			rsr &= port->read_status_mask;
+
+			if (rsr & AMBA_UARTRSR_BE)
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			else if (rsr & AMBA_UARTRSR_PE)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (rsr & AMBA_UARTRSR_FE)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+		}
+
+		if (uart_handle_sysrq_char(port, ch, regs))
+			goto ignore_char;
+
+		if ((rsr & port->ignore_status_mask) == 0) {
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+		if ((rsr & AMBA_UARTRSR_OE) &&
+		    tty->flip.count < TTY_FLIPBUF_SIZE) {
+			/*
+			 * Overrun is special, since it's reported
+			 * immediately, and doesn't affect the current
+			 * character
+			 */
+			*tty->flip.char_buf_ptr++ = 0;
+			*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+			tty->flip.count++;
+		}
+	ignore_char:
+		status = UART_GET_FR(port);
+	}
+	tty_flip_buffer_push(tty);
+	return;
+}
+
+static void ambauart_tx_chars(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->info->xmit;
+	int count;
+
+	if (port->x_char) {
+		UART_PUT_CHAR(port, port->x_char);
+		port->icount.tx++;
+		port->x_char = 0;
+		return;
+	}
+	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+		ambauart_stop_tx(port, 0);
+		return;
+	}
+
+	count = port->fifosize >> 1;
+	do {
+		UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	} while (--count > 0);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+
+	if (uart_circ_empty(xmit))
+		ambauart_stop_tx(port, 0);
+}
+
+static void ambauart_modem_status(struct uart_port *port)
+{
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
+	unsigned int status, delta;
+
+	UART_PUT_ICR(&uap->port, 0);
+
+	status = UART_GET_FR(&uap->port) & AMBA_UARTFR_MODEM_ANY;
+
+	delta = status ^ uap->old_status;
+	uap->old_status = status;
+
+	if (!delta)
+		return;
+
+	if (delta & AMBA_UARTFR_DCD)
+		uart_handle_dcd_change(&uap->port, status & AMBA_UARTFR_DCD);
+
+	if (delta & AMBA_UARTFR_DSR)
+		uap->port.icount.dsr++;
+
+	if (delta & AMBA_UARTFR_CTS)
+		uart_handle_cts_change(&uap->port, status & AMBA_UARTFR_CTS);
+
+	wake_up_interruptible(&uap->port.info->delta_msr_wait);
+}
+
+static void ambauart_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_port *port = dev_id;
+	unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
+
+	status = UART_GET_INT_STATUS(port);
+	do {
+		if (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS))
+#ifdef SUPPORT_SYSRQ
+			ambauart_rx_chars(port, regs);
+#else
+			ambauart_rx_chars(port);
+#endif
+		if (status & AMBA_UARTIIR_TIS)
+			ambauart_tx_chars(port);
+		if (status & AMBA_UARTIIR_MIS)
+			ambauart_modem_status(port);
+
+		if (pass_counter-- == 0)
+			break;
+
+		status = UART_GET_INT_STATUS(port);
+	} while (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS |
+			   AMBA_UARTIIR_TIS));
+}
+
+static unsigned int ambauart_tx_empty(struct uart_port *port)
+{
+	return UART_GET_FR(port) & AMBA_UARTFR_BUSY ? 0 : TIOCSER_TEMT;
+}
+
+static unsigned int ambauart_get_mctrl(struct uart_port *port)
+{
+	unsigned int result = 0;
+	unsigned int status;
+
+	status = UART_GET_FR(port);
+	if (status & AMBA_UARTFR_DCD)
+		result |= TIOCM_CAR;
+	if (status & AMBA_UARTFR_DSR)
+		result |= TIOCM_DSR;
+	if (status & AMBA_UARTFR_CTS)
+		result |= TIOCM_CTS;
+
+	return result;
+}
+
+static void ambauart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
+	unsigned int ctrls = 0, ctrlc = 0;
+
+	if (mctrl & TIOCM_RTS)
+		ctrlc |= uap->rts_mask;
+	else
+		ctrls |= uap->rts_mask;
+
+	if (mctrl & TIOCM_DTR)
+		ctrlc |= uap->dtr_mask;
+	else
+		ctrls |= uap->dtr_mask;
+
+	__raw_writel(ctrls, SC_CTRLS);
+	__raw_writel(ctrlc, SC_CTRLC);
+}
+
+static void ambauart_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned long flags;
+	unsigned int lcr_h;
+
+	spin_lock_irqsave(&port->lock, flags);
+	lcr_h = UART_GET_LCRH(port);
+	if (break_state == -1)
+		lcr_h |= AMBA_UARTLCR_H_BRK;
+	else
+		lcr_h &= ~AMBA_UARTLCR_H_BRK;
+	UART_PUT_LCRH(port, lcr_h);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int ambauart_startup(struct uart_port *port)
+{
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
+	int retval;
+
+	/*
+	 * Allocate the IRQ
+	 */
+	retval = request_irq(port->irq, ambauart_int, 0, "amba", port);
+	if (retval)
+		return retval;
+
+	/*
+	 * initialise the old status of the modem signals
+	 */
+	uap->old_status = UART_GET_FR(port) & AMBA_UARTFR_MODEM_ANY;
+
+	/*
+	 * Finally, enable interrupts
+	 */
+	UART_PUT_CR(port, AMBA_UARTCR_UARTEN | AMBA_UARTCR_RIE |
+			  AMBA_UARTCR_RTIE);
+
+	return 0;
+}
+
+static void ambauart_shutdown(struct uart_port *port)
+{
+	/*
+	 * Free the interrupt
+	 */
+	free_irq(port->irq, port);
+
+	/*
+	 * disable all interrupts, disable the port
+	 */
+	UART_PUT_CR(port, 0);
+
+	/* disable break condition and fifos */
+	UART_PUT_LCRH(port, UART_GET_LCRH(port) &
+		~(AMBA_UARTLCR_H_BRK | AMBA_UARTLCR_H_FEN));
+}
+
+static void ambauart_change_speed(struct uart_port *port, unsigned int cflag, unsigned int iflag, unsigned int quot)
+{
+	unsigned int lcr_h, old_cr;
+	unsigned long flags;
+
+#if DEBUG
+	printk("ambauart_set_cflag(0x%x) called\n", cflag);
+#endif
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	case CS5:
+		lcr_h = AMBA_UARTLCR_H_WLEN_5;
+		break;
+	case CS6:
+		lcr_h = AMBA_UARTLCR_H_WLEN_6;
+		break;
+	case CS7:
+		lcr_h = AMBA_UARTLCR_H_WLEN_7;
+		break;
+	default: // CS8
+		lcr_h = AMBA_UARTLCR_H_WLEN_8;
+		break;
+	}
+	if (cflag & CSTOPB)
+		lcr_h |= AMBA_UARTLCR_H_STP2;
+	if (cflag & PARENB) {
+		lcr_h |= AMBA_UARTLCR_H_PEN;
+		if (!(cflag & PARODD))
+			lcr_h |= AMBA_UARTLCR_H_EPS;
+	}
+	if (port->fifosize > 1)
+		lcr_h |= AMBA_UARTLCR_H_FEN;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	port->read_status_mask = AMBA_UARTRSR_OE;
+	if (iflag & INPCK)
+		port->read_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;
+	if (iflag & (BRKINT | PARMRK))
+		port->read_status_mask |= AMBA_UARTRSR_BE;
+
+	/*
+	 * Characters to ignore
+	 */
+	port->ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		port->ignore_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;
+	if (iflag & IGNBRK) {
+		port->ignore_status_mask |= AMBA_UARTRSR_BE;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			port->ignore_status_mask |= AMBA_UARTRSR_OE;
+	}
+
+	/*
+	 * Ignore all characters if CREAD is not set.
+	 */
+	if ((cflag & CREAD) == 0)
+		port->ignore_status_mask |= UART_DUMMY_RSR_RX;
+
+	old_cr = UART_GET_CR(port) & ~AMBA_UARTCR_MSIE;
+
+	if (UART_ENABLE_MS(port, cflag))
+		old_cr |= AMBA_UARTCR_MSIE;
+
+	UART_PUT_CR(port, 0);
+
+	/* Set baud rate */
+	quot -= 1;
+	UART_PUT_LCRM(port, ((quot & 0xf00) >> 8));
+	UART_PUT_LCRL(port, (quot & 0xff));
+
+	/*
+	 * ----------v----------v----------v----------v-----
+	 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
+	 * ----------^----------^----------^----------^-----
+	 */
+	UART_PUT_LCRH(port, lcr_h);
+	UART_PUT_CR(port, old_cr);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *ambauart_type(struct uart_port *port)
+{
+	return port->type == PORT_AMBA ? "AMBA" : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'
+ */
+static void ambauart_release_port(struct uart_port *port)
+{
+	release_mem_region(port->mapbase, UART_PORT_SIZE);
+}
+
+/*
+ * Request the memory region(s) being used by 'port'
+ */
+static int ambauart_request_port(struct uart_port *port)
+{
+	return request_mem_region(port->mapbase, UART_PORT_SIZE, "serial_amba")
+			!= NULL ? 0 : -EBUSY;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void ambauart_config_port(struct uart_port *port, int flags)
+{
+	if (flags & UART_CONFIG_TYPE) {
+		port->type = PORT_AMBA;
+		ambauart_request_port(port);
+	}
+}
+
+/*
+ * verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int ambauart_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	int ret = 0;
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)
+		ret = -EINVAL;
+	if (ser->irq < 0 || ser->irq >= NR_IRQS)
+		ret = -EINVAL;
+	if (ser->baud_base < 9600)
+		ret = -EINVAL;
+	return ret;
+}
+
+static struct uart_ops amba_pops = {
+	.tx_empty	= ambauart_tx_empty,
+	.set_mctrl	= ambauart_set_mctrl,
+	.get_mctrl	= ambauart_get_mctrl,
+	.stop_tx	= ambauart_stop_tx,
+	.start_tx	= ambauart_start_tx,
+	.stop_rx	= ambauart_stop_rx,
+	.enable_ms	= ambauart_enable_ms,
+	.break_ctl	= ambauart_break_ctl,
+	.startup	= ambauart_startup,
+	.shutdown	= ambauart_shutdown,
+	.change_speed	= ambauart_change_speed,
+	.type		= ambauart_type,
+	.release_port	= ambauart_release_port,
+	.request_port	= ambauart_request_port,
+	.config_port	= ambauart_config_port,
+	.verify_port	= ambauart_verify_port,
+};
+
+static struct uart_amba_port amba_ports[UART_NR] = {
+#if !defined(CONFIG_KGDB_UART0)
+	{
+		.port	= {
+			.membase	= (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE),
+			.mapbase	= INTEGRATOR_UART0_BASE,
+			.iotype		= SERIAL_IO_MEM,
+			.irq		= IRQ_UARTINT0,
+			.uartclk	= 14745600,
+			.fifosize	= 16,
+			.ops		= &amba_pops,
+			.flags		= ASYNC_BOOT_AUTOCONF,
+			.line		= 0,
+		},
+		.dtr_mask	= 1 << 5,
+		.rts_mask	= 1 << 4,
+	},
+#else
+	{ 0 },
+#endif
+#if     !defined(CONFIG_KGDB_UART1)
+	{
+		.port	= {
+			.membase	= (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE),
+			.mapbase	= INTEGRATOR_UART1_BASE,
+			.iotype		= SERIAL_IO_MEM,
+			.irq		= IRQ_UARTINT1,
+			.uartclk	= 14745600,
+			.fifosize	= 16,
+			.ops		= &amba_pops,
+			.flags		= ASYNC_BOOT_AUTOCONF,
+			.line		= 1,
+		},
+		.dtr_mask	= 1 << 7,
+		.rts_mask	= 1 << 6,
+	}
+#else
+	{ 0 }
+#endif
+};
+
+#ifdef CONFIG_SERIAL_AMBA_CONSOLE
+
+static void ambauart_console_write(struct console *co, const char *s, unsigned int count)
+{
+	struct uart_port *port = &amba_ports[co->index].port;
+	unsigned int status, old_cr;
+	int i;
+
+	/*
+	 *	First save the CR then disable the interrupts
+	 */
+	old_cr = UART_GET_CR(port);
+	UART_PUT_CR(port, AMBA_UARTCR_UARTEN);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++) {
+		do {
+			status = UART_GET_FR(port);
+		} while (!UART_TX_READY(status));
+		UART_PUT_CHAR(port, s[i]);
+		if (s[i] == '\n') {
+			do {
+				status = UART_GET_FR(port);
+			} while (!UART_TX_READY(status));
+			UART_PUT_CHAR(port, '\r');
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the TCR
+	 */
+	do {
+		status = UART_GET_FR(port);
+	} while (status & AMBA_UARTFR_BUSY);
+	UART_PUT_CR(port, old_cr);
+}
+
+static kdev_t ambauart_console_device(struct console *co)
+{
+	return MKDEV(SERIAL_AMBA_MAJOR, SERIAL_AMBA_MINOR + co->index);
+}
+
+static void __init
+ambauart_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
+{
+	if (UART_GET_CR(port) & AMBA_UARTCR_UARTEN) {
+		unsigned int lcr_h, quot;
+		lcr_h = UART_GET_LCRH(port);
+
+		*parity = 'n';
+		if (lcr_h & AMBA_UARTLCR_H_PEN) {
+			if (lcr_h & AMBA_UARTLCR_H_EPS)
+				*parity = 'e';
+			else
+				*parity = 'o';
+		}
+
+		if ((lcr_h & 0x60) == AMBA_UARTLCR_H_WLEN_7)
+			*bits = 7;
+		else
+			*bits = 8;
+
+		quot = UART_GET_LCRL(port) | UART_GET_LCRM(port) << 8;
+		*baud = port->uartclk / (16 * (quot + 1));
+	}
+}
+
+static int __init ambauart_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = 38400;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (co->index >= UART_NR)
+		co->index = 0;
+	port = &amba_ports[co->index].port;
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else
+		ambauart_console_get_options(port, &baud, &parity, &bits);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct console amba_console = {
+	.name		= "ttyAM",
+	.write		= ambauart_console_write,
+	.device		= ambauart_console_device,
+	.setup		= ambauart_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+};
+
+void __init ambauart_console_init(void)
+{
+	register_console(&amba_console);
+}
+
+#define AMBA_CONSOLE	&amba_console
+#else
+#define AMBA_CONSOLE	NULL
+#endif
+
+static struct uart_driver amba_reg = {
+	.owner			= THIS_MODULE,
+	.normal_major		= SERIAL_AMBA_MAJOR,
+#ifdef CONFIG_DEVFS_FS
+	.normal_name		= "ttyAM%d",
+	.callout_name		= "cuaam%d",
+#else
+	.normal_name		= "ttyAM",
+	.callout_name		= "cuaam",
+#endif
+	.normal_driver		= &normal,
+	.callout_major		= CALLOUT_AMBA_MAJOR,
+	.callout_driver		= &callout,
+	.table			= amba_table,
+	.termios		= amba_termios,
+	.termios_locked		= amba_termios_locked,
+	.minor			= SERIAL_AMBA_MINOR,
+	.nr			= UART_NR,
+	.cons			= AMBA_CONSOLE,
+};
+
+static int __init ambauart_init(void)
+{
+	int ret;
+
+	ret = uart_register_driver(&amba_reg);
+	if (ret == 0) {
+		int i;
+
+		for (i = 0; i < UART_NR; i++)
+			uart_add_one_port(&amba_reg, &amba_ports[i].port);
+	}
+	return ret;
+}
+
+static void __exit ambauart_exit(void)
+{
+	int i;
+
+	for (i = 0; i < UART_NR; i++)
+		uart_remove_one_port(&amba_reg, &amba_ports[i].port);
+
+	uart_unregister_driver(&amba_reg);
+}
+
+module_init(ambauart_init);
+module_exit(ambauart_exit);
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd");
+MODULE_DESCRIPTION("ARM AMBA serial port driver");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/drivers/serial/anakin.c linux-2.4.29-uc1/drivers/serial/anakin.c
--- linux-2.4.29/drivers/serial/anakin.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/serial/anakin.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,545 @@
+/*
+ *  linux/drivers/char/serial_anakin.c
+ *
+ *  Based on driver for AMBA serial ports, by ARM Limited,
+ *  Deep Blue Solutions Ltd., Linus Torvalds and Theodore Ts'o.
+ *
+ *  Copyright (C) 2001 Aleph One Ltd. for Acunia N.V.
+ *
+ *  Copyright (C) 2001 Blue Mug, Inc. for Acunia N.V.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Changelog:
+ *   20-Apr-2001 TTC	Created
+ *   05-May-2001 W/TTC	Updated for serial_core.c
+ *   27-Jun-2001 jonm	Minor changes; add mctrl support, switch to 
+ *   			SA_INTERRUPT. Works reliably now. No longer requires
+ *   			changes to the serial_core API.
+ *
+ *  $Id: anakin.c,v 1.5.2.2 2002/10/24 09:53:25 rmk Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+
+#include <linux/serial_core.h>
+
+#include <asm/arch/serial_reg.h>
+
+#define UART_NR			5
+
+#define SERIAL_ANAKIN_NAME	"ttyAN"
+#define SERIAL_ANAKIN_MAJOR	204
+#define SERIAL_ANAKIN_MINOR	32
+
+#define CALLOUT_ANAKIN_NAME	"cuaan"
+#define CALLOUT_ANAKIN_MAJOR	205
+#define CALLOUT_ANAKIN_MINOR	32
+
+static struct tty_driver normal, callout;
+static struct tty_struct *anakin_table[UART_NR];
+static struct termios *anakin_termios[UART_NR], *anakin_termios_locked[UART_NR];
+static struct uart_state anakin_state[UART_NR];
+static u_int txenable[NR_IRQS];		/* Software interrupt register */
+
+static inline unsigned int
+anakin_in(struct uart_port *port, u_int offset)
+{
+	return __raw_readl(port->base + offset);
+}
+
+static inline void
+anakin_out(struct uart_port *port, u_int offset, unsigned int value)
+{
+	__raw_writel(value, port->base + offset);
+}
+
+static void
+anakin_stop_tx(struct uart_port *port, u_int from_tty)
+{
+	txenable[port->irq] = 0;
+}
+
+static inline void
+anakin_transmit_buffer(struct uart_info *info)
+{
+	struct uart_port *port = info->port;
+
+	while (!(anakin_in(port, 0x10) & TXEMPTY));
+	anakin_out(port, 0x14, info->xmit.buf[info->xmit.tail]);
+	anakin_out(port, 0x18, anakin_in(port, 0x18) | SENDREQUEST);
+	info->xmit.tail = (info->xmit.tail + 1) & (UART_XMIT_SIZE-1);
+        info->state->icount.tx++;
+
+	if (info->xmit.head == info->xmit.tail)
+		anakin_stop_tx(port, 0); 
+}
+
+static inline void
+anakin_transmit_x_char(struct uart_info *info)
+{
+	struct uart_port *port = info->port;
+
+	anakin_out(port, 0x14, info->x_char);
+	anakin_out(port, 0x18, anakin_in(port, 0x18) | SENDREQUEST);
+	info->state->icount.tx++;
+	info->x_char = 0;
+}
+
+static void
+anakin_start_tx(struct uart_port *port, u_int nonempty, u_int from_tty)
+{
+	unsigned int flags;
+
+	save_flags_cli(flags);
+
+	// is it this... or below: if (nonempty
+	if (!txenable[port->irq]) {
+		txenable[port->irq] = TXENABLE;
+
+		if ((anakin_in(port, 0x10) & TXEMPTY) && nonempty) {
+		    anakin_transmit_buffer((struct uart_info*)port->unused);
+		}
+	}
+
+	restore_flags(flags);
+}
+
+static void
+anakin_stop_rx(struct uart_port *port)
+{
+	unsigned long flags;
+
+	save_flags_cli(flags);
+	while (anakin_in(port, 0x10) & RXRELEASE) 
+	    anakin_in(port, 0x14);
+	anakin_out(port, 0x18, anakin_in(port, 0x18) | BLOCKRX);
+	restore_flags(flags);
+}
+
+static void
+anakin_enable_ms(struct uart_port *port)
+{
+}
+
+static inline void
+anakin_rx_chars(struct uart_info *info)
+{
+	unsigned int ch;
+	struct tty_struct *tty = info->tty;
+
+	if (!(anakin_in(info->port, 0x10) & RXRELEASE))
+		return;
+
+	ch = anakin_in(info->port, 0x14) & 0xff;
+
+	if (tty->flip.count < TTY_FLIPBUF_SIZE) {
+		*tty->flip.char_buf_ptr++ = ch;
+		*tty->flip.flag_buf_ptr++ = TTY_NORMAL;
+		info->state->icount.rx++;
+		tty->flip.count++;
+	} 
+	tty_flip_buffer_push(tty);
+}
+
+static inline void
+anakin_overrun_chars(struct uart_info *info)
+{
+	unsigned int ch;
+
+	ch = anakin_in(info->port, 0x14);
+	info->state->icount.overrun++;
+}
+
+static inline void
+anakin_tx_chars(struct uart_info *info)
+{
+	if (info->x_char) {
+		anakin_transmit_x_char(info);
+		return; 
+	}
+
+	if (info->xmit.head == info->xmit.tail
+	    || info->tty->stopped
+	    || info->tty->hw_stopped) {
+		anakin_stop_tx(info->port, 0);
+		return;
+	}
+
+	anakin_transmit_buffer(info);
+
+	if (CIRC_CNT(info->xmit.head,
+		     info->xmit.tail,
+		     UART_XMIT_SIZE) < WAKEUP_CHARS)
+		uart_event(info, EVT_WRITE_WAKEUP);
+}
+
+static void
+anakin_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int status;
+	struct uart_info *info = dev_id;
+
+	status = anakin_in(info->port, 0x1c);
+
+	if (status & RX) 
+		anakin_rx_chars(info);
+
+	if (status & OVERRUN) 
+		anakin_overrun_chars(info);
+
+	if (txenable[info->port->irq] && (status & TX)) 
+		anakin_tx_chars(info);
+}
+
+static u_int
+anakin_tx_empty(struct uart_port *port)
+{
+	return anakin_in(port, 0x10) & TXEMPTY ? TIOCSER_TEMT : 0;
+}
+
+static u_int
+anakin_get_mctrl(struct uart_port *port)
+{
+	unsigned int status = 0;
+
+	status |= (anakin_in(port, 0x10) & CTS ? TIOCM_CTS : 0);
+	status |= (anakin_in(port, 0x18) & DCD ? TIOCM_CAR : 0);
+	status |= (anakin_in(port, 0x18) & DTR ? TIOCM_DTR : 0);
+	status |= (anakin_in(port, 0x18) & RTS ? TIOCM_RTS : 0);
+	
+	return status;
+}
+
+static void
+anakin_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+	unsigned int status;
+
+	status = anakin_in(port, 0x18);
+
+	if (mctrl & TIOCM_RTS) 
+		status |= RTS;
+	else 
+		status &= ~RTS;
+
+	if (mctrl & TIOCM_CAR)
+		status |= DCD;
+	else 
+		status &= ~DCD;
+
+	anakin_out(port, 0x18, status);
+}
+
+static void
+anakin_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned int status;
+
+	status = anakin_in(port, 0x20);
+
+	if (break_state == -1)
+		status |= SETBREAK;
+	else
+		status &= ~SETBREAK;
+
+	anakin_out(port, 0x20, status);
+}
+
+static int
+anakin_startup(struct uart_port *port, struct uart_info *info)
+{
+	int retval;
+	unsigned int read,write;
+
+	/*
+	 * Allocate the IRQ
+	 */
+	retval = request_irq(port->irq, anakin_int, SA_INTERRUPT, "serial_anakin", info);
+	if (retval)
+		return retval;
+
+	port->ops->set_mctrl(port, info->mctrl);
+
+	/*
+	 * initialise the old status of the modem signals
+	 */
+	port->old_status = 0;
+
+	/*
+	 * Finally, disable IRQ and softIRQs for first byte)
+	 */
+	txenable[port->irq] = 0;
+	read = anakin_in(port, 0x18);
+	write = (read & ~(RTS | DTR | BLOCKRX)) | IRQENABLE;
+	anakin_out(port, 0x18, write);
+
+	/* Store the uart_info pointer so we can reference it in 
+	 * anakin_start_tx() */
+	port->unused = (u_int)info;
+	
+	return 0;
+}
+
+static void
+anakin_shutdown(struct uart_port *port, struct uart_info *info)
+{
+	/*
+	 * Free the interrupt
+	 */
+	free_irq(port->irq, info);
+
+	/*
+	 * disable all interrupts, disable the port
+	 */
+	anakin_out(port, 0x18, anakin_in(port, 0x18) & ~IRQENABLE);
+}
+
+static void
+anakin_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot)
+{
+	unsigned int flags;
+
+	save_flags_cli(flags);
+	while (!(anakin_in(port, 0x10) & TXEMPTY));
+	anakin_out(port, 0x10, (anakin_in(port, 0x10) & ~PRESCALER)
+			| (quot << 3));
+
+	//parity always set to none
+	anakin_out(port, 0x18, anakin_in(port, 0x18) & ~PARITY);
+	restore_flags(flags);
+}
+
+static const char *anakin_type(struct port *port)
+{
+	return port->type == PORT_ANAKIN ? "ANAKIN" : NULL;
+}
+
+static struct uart_ops anakin_pops = {
+	tx_empty:	anakin_tx_empty,
+	set_mctrl:	anakin_set_mctrl,
+	get_mctrl:	anakin_get_mctrl,
+	stop_tx:	anakin_stop_tx,
+	start_tx:	anakin_start_tx,
+	stop_rx:	anakin_stop_rx,
+	enable_ms:	anakin_enable_ms,
+	break_ctl:	anakin_break_ctl,
+	startup:	anakin_startup,
+	shutdown:	anakin_shutdown,
+	change_speed:	anakin_change_speed,
+	type:		anakin_type,
+};
+
+static struct uart_port anakin_ports[UART_NR] = {
+	{
+		base:		IO_BASE + UART0,
+		irq:		IRQ_UART0,
+		uartclk:	3686400,
+		fifosize:	0,
+		ops:		&anakin_pops,
+	},
+	{
+		base:		IO_BASE + UART1,
+		irq:		IRQ_UART1,
+		uartclk:	3686400,
+		fifosize:	0,
+		ops:		&anakin_pops,
+	},
+	{
+		base:		IO_BASE + UART2,
+		irq:		IRQ_UART2,
+		uartclk:	3686400,
+		fifosize:	0,
+		ops:		&anakin_pops,
+	},
+	{
+		base:		IO_BASE + UART3,
+		irq:		IRQ_UART3,
+		uartclk:	3686400,
+		fifosize:	0,
+		ops:		&anakin_pops,
+	},
+	{
+		base:		IO_BASE + UART4,
+		irq:		IRQ_UART4,
+		uartclk:	3686400,
+		fifosize:	0,
+		ops:		&anakin_pops,
+	},
+};
+
+
+#ifdef CONFIG_SERIAL_ANAKIN_CONSOLE
+
+static void
+anakin_console_write(struct console *co, const char *s, u_int count)
+{
+	struct uart_port *port = anakin_ports + co->index;
+	unsigned int flags, status, i;
+
+	/*
+	 *	First save the status then disable the interrupts
+	 */
+	save_flags_cli(flags);
+	status = anakin_in(port, 0x18);
+	anakin_out(port, 0x18, status & ~IRQENABLE);
+	restore_flags(flags);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++, s++) {
+		while (!(anakin_in(port, 0x10) & TXEMPTY));
+
+		/*
+		 *	Send the character out.
+		 *	If a LF, also do CR...
+		 */
+		anakin_out(port, 0x14, *s);
+		anakin_out(port, 0x18, anakin_in(port, 0x18) | SENDREQUEST);
+
+		if (*s == 10) {
+			while (!(anakin_in(port, 0x10) & TXEMPTY));
+			anakin_out(port, 0x14, 13);
+			anakin_out(port, 0x18, anakin_in(port, 0x18)
+					| SENDREQUEST);
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the interrupts
+	 */
+	while (!(anakin_in(port, 0x10) & TXEMPTY));
+
+	if (status & IRQENABLE)
+		save_flags_cli(flags);
+ 		anakin_out(port, 0x18, anakin_in(port, 0x18) | IRQENABLE);
+		restore_flags(flags);
+}
+
+static kdev_t
+anakin_console_device(struct console *co)
+{
+	return MKDEV(SERIAL_ANAKIN_MAJOR, SERIAL_ANAKIN_MINOR + co->index);
+}
+
+/*
+ * Read the current UART setup.
+ */
+static void __init
+anakin_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
+{
+	int paritycode;
+
+	*baud = GETBAUD (anakin_in(port, 0x10) & PRESCALER);
+	paritycode = GETPARITY(anakin_in(port, 0x18) & PARITY);
+	switch (paritycode) {
+	  case NONEPARITY: *parity = 'n'; break;
+	  case ODDPARITY: *parity = 'o'; break;
+	  case EVENPARITY: *parity = 'e'; break;
+	}
+	*bits = 8;
+}
+
+static int __init
+anakin_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = CONFIG_ANAKIN_DEFAULT_BAUDRATE;
+	int bits = 8;
+	int parity = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	port = uart_get_console(anakin_ports, UART_NR, co);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits);
+	else
+		anakin_console_get_options(port, &baud, &parity, &bits);
+
+	return uart_set_options(port, co, baud, parity, bits);
+}
+
+static struct console anakin_console = {
+	name:		SERIAL_ANAKIN_NAME,
+	write:		anakin_console_write,
+	device:		anakin_console_device,
+	setup:		anakin_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+void __init
+anakin_console_init(void)
+{
+	register_console(&anakin_console);
+}
+
+#define ANAKIN_CONSOLE		&anakin_console
+#else
+#define ANAKIN_CONSOLE		NULL
+#endif
+
+static struct uart_register anakin_reg = {
+	normal_major:		SERIAL_ANAKIN_MAJOR,
+	normal_name:		SERIAL_ANAKIN_NAME,
+	normal_driver:		&normal,
+	callout_major:		CALLOUT_ANAKIN_MAJOR,
+	callout_name:		CALLOUT_ANAKIN_NAME,
+	callout_driver:		&callout,
+	table:			anakin_table,
+	termios:		anakin_termios,
+	termios_locked:		anakin_termios_locked,
+	minor:			SERIAL_ANAKIN_MINOR,
+	nr:			UART_NR,
+	state:			anakin_state,
+	port:			anakin_ports,
+	cons:			ANAKIN_CONSOLE,
+};
+
+static int __init
+anakin_init(void)
+{
+	return uart_register_port(&anakin_reg);
+}
+
+__initcall(anakin_init);
+
+MODULE_DESCRIPTION("Anakin serial driver");
+MODULE_AUTHOR("Tak-Shing Chan <chan@aleph1.co.uk>");
+MODULE_SUPPORTED_DEVICE("ttyAN");
+MODULE_LICENSE("GPL");
+
+EXPORT_NO_SYMBOLS;
diff -urN linux-2.4.29/drivers/serial/clps711x.c linux-2.4.29-uc1/drivers/serial/clps711x.c
--- linux-2.4.29/drivers/serial/clps711x.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/serial/clps711x.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,637 @@
+/*
+ *  linux/drivers/char/serial_clps711x.c
+ *
+ *  Driver for CLPS711x serial ports
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *  $Id: clps711x.c,v 1.12.2.2 2002/10/24 09:53:25 rmk Exp $
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+
+#include <asm/bitops.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <linux/serial_core.h>
+
+#include <asm/hardware/clps7111.h>
+
+#define UART_NR		2
+
+#define SERIAL_CLPS711X_NAME	"ttyAM"
+#define SERIAL_CLPS711X_MAJOR	204
+#define SERIAL_CLPS711X_MINOR	16
+#define SERIAL_CLPS711X_NR	UART_NR
+
+#define CALLOUT_CLPS711X_NAME	"cuaam"
+#define CALLOUT_CLPS711X_MAJOR	205
+#define CALLOUT_CLPS711X_MINOR	16
+#define CALLOUT_CLPS711X_NR	UART_NR
+
+static struct tty_driver normal, callout;
+static struct tty_struct *clps711x_table[UART_NR];
+static struct termios *clps711x_termios[UART_NR], *clps711x_termios_locked[UART_NR];
+
+/*
+ * We use the relevant SYSCON register as a base address for these ports.
+ */
+#define UBRLCR(port)		((port)->iobase + UBRLCR1 - SYSCON1)
+#define UARTDR(port)		((port)->iobase + UARTDR1 - SYSCON1)
+#define SYSFLG(port)		((port)->iobase + SYSFLG1 - SYSCON1)
+#define SYSCON(port)		((port)->iobase + SYSCON1 - SYSCON1)
+
+#define TX_IRQ(port)		((port)->irq)
+#define RX_IRQ(port)		((port)->irq + 1)
+
+#define UART_ANY_ERR		(UARTDR_FRMERR | UARTDR_PARERR | UARTDR_OVERR)
+
+#define tx_enabled(port)	((port)->unused[0])
+
+static void
+clps711xuart_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	if (tx_enabled(port)) {
+		disable_irq(TX_IRQ(port));
+		tx_enabled(port) = 0;
+	}
+}
+
+static void
+clps711xuart_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	if (!tx_enabled(port)) {
+		enable_irq(TX_IRQ(port));
+		tx_enabled(port) = 1;
+	}
+}
+
+static void clps711xuart_stop_rx(struct uart_port *port)
+{
+	disable_irq(RX_IRQ(port));
+}
+
+static void clps711xuart_enable_ms(struct uart_port *port)
+{
+}
+
+static void clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_port *port = dev_id;
+	struct tty_struct *tty = port->info->tty;
+	unsigned int status, ch, flg, ignored = 0;
+
+	status = clps_readl(SYSFLG(port));
+	while (!(status & SYSFLG_URXFE)) {
+		ch = clps_readl(UARTDR(port));
+
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			goto ignore_char;
+		port->icount.rx++;
+
+		flg = TTY_NORMAL;
+
+		/*
+		 * Note that the error handling code is
+		 * out of the main execution path
+		 */
+		if (ch & UART_ANY_ERR)
+			goto handle_error;
+
+		if (uart_handle_sysrq_char(port, ch, regs))
+			goto ignore_char;
+
+	error_return:
+		*tty->flip.flag_buf_ptr++ = flg;
+		*tty->flip.char_buf_ptr++ = ch;
+		tty->flip.count++;
+	ignore_char:
+		status = clps_readl(SYSFLG(port));
+	}
+ out:
+	tty_flip_buffer_push(tty);
+	return;
+
+ handle_error:
+	if (ch & UARTDR_PARERR)
+		port->icount.parity++;
+	else if (ch & UARTDR_FRMERR)
+		port->icount.frame++;
+	if (ch & UARTDR_OVERR)
+		port->icount.overrun++;
+
+	if (ch & port->ignore_status_mask) {
+		if (++ignored > 100)
+			goto out;
+		goto ignore_char;
+	}
+	ch &= port->read_status_mask;
+
+	if (ch & UARTDR_PARERR)
+		flg = TTY_PARITY;
+	else if (ch & UARTDR_FRMERR)
+		flg = TTY_FRAME;
+
+	if (ch & UARTDR_OVERR) {
+		/*
+		 * CHECK: does overrun affect the current character?
+		 * ASSUMPTION: it does not.
+		 */
+		*tty->flip.flag_buf_ptr++ = flg;
+		*tty->flip.char_buf_ptr++ = ch;
+		tty->flip.count++;
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			goto ignore_char;
+		ch = 0;
+		flg = TTY_OVERRUN;
+	}
+#ifdef SUPPORT_SYSRQ
+	port->sysrq = 0;
+#endif
+	goto error_return;
+}
+
+static void clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_port *port = dev_id;
+	struct circ_buf *xmit = &port->info->xmit;
+	int count;
+
+	if (port->x_char) {
+		clps_writel(port->x_char, UARTDR(port));
+		port->icount.tx++;
+		port->x_char = 0;
+		return;
+	}
+	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+		clps711xuart_stop_tx(port, 0);
+		return;
+	}
+
+	count = port->fifosize;
+	do {
+		if (clps_readl(SYSFLG(port)) & SYSFLG_UTXFF)
+			break;
+		clps_writel(xmit->buf[xmit->tail], UARTDR(port));
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	} while (--count > 0);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+
+	if (uart_circ_empty(xmit))
+		clps711xuart_stop_tx(port, 0);
+}
+
+static unsigned int clps711xuart_tx_empty(struct uart_port *port)
+{
+	unsigned int status = clps_readl(SYSFLG(port));
+	return status & SYSFLG_UBUSY ? 0 : TIOCSER_TEMT;
+}
+
+static unsigned int clps711xuart_get_mctrl(struct uart_port *port)
+{
+	unsigned int port_addr;
+	unsigned int result = 0;
+	unsigned int status;
+
+	port_addr = SYSFLG(port);
+	if (port_addr == SYSFLG1) {
+		status = clps_readl(SYSFLG1);
+		if (status & SYSFLG1_DCD)
+			result |= TIOCM_CAR;
+		if (status & SYSFLG1_DSR)
+			result |= TIOCM_DSR;
+		if (status & SYSFLG1_CTS)
+			result |= TIOCM_CTS;
+	}
+
+	return result;
+}
+
+static void
+clps711xuart_set_mctrl_null(struct uart_port *port, unsigned int mctrl)
+{
+}
+
+static void clps711xuart_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned long flags;
+	unsigned int ubrlcr;
+
+	spin_lock_irqsave(&port->lock, flags);
+	ubrlcr = clps_readl(UBRLCR(port));
+	if (break_state == -1)
+		ubrlcr |= UBRLCR_BREAK;
+	else
+		ubrlcr &= ~UBRLCR_BREAK;
+	clps_writel(ubrlcr, UBRLCR(port));
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int clps711xuart_startup(struct uart_port *port)
+{
+	unsigned int syscon;
+	int retval;
+
+	tx_enabled(port) = 1;
+
+	/*
+	 * Allocate the IRQs
+	 */
+	retval = request_irq(TX_IRQ(port), clps711xuart_int_tx, 0,
+			     "clps711xuart_tx", port);
+	if (retval)
+		return retval;
+
+	retval = request_irq(RX_IRQ(port), clps711xuart_int_rx, 0,
+			     "clps711xuart_rx", port);
+	if (retval) {
+		free_irq(TX_IRQ(port), port);
+		return retval;
+	}
+
+	/*
+	 * enable the port
+	 */
+	syscon = clps_readl(SYSCON(port));
+	syscon |= SYSCON_UARTEN;
+	clps_writel(syscon, SYSCON(port));
+
+	return 0;
+}
+
+static void clps711xuart_shutdown(struct uart_port *port)
+{
+	unsigned int ubrlcr, syscon;
+
+	/*
+	 * Free the interrupt
+	 */
+	free_irq(TX_IRQ(port), port);	/* TX interrupt */
+	free_irq(RX_IRQ(port), port);	/* RX interrupt */
+
+	/*
+	 * disable the port
+	 */
+	syscon = clps_readl(SYSCON(port));
+	syscon &= ~SYSCON_UARTEN;
+	clps_writel(syscon, SYSCON(port));
+
+	/*
+	 * disable break condition and fifos
+	 */
+	ubrlcr = clps_readl(UBRLCR(port));
+	ubrlcr &= ~(UBRLCR_FIFOEN | UBRLCR_BREAK);
+	clps_writel(ubrlcr, UBRLCR(port));
+}
+
+static void clps711xuart_change_speed(struct uart_port *port, unsigned int cflag, unsigned int iflag, unsigned int quot)
+{
+	unsigned int ubrlcr;
+	unsigned long flags;
+
+#if DEBUG
+	printk("clps711xuart_change_speed(cflag=0x%x, iflag=0x%x, quot=%d) called\n",
+		cflag, iflag, quot);
+#endif
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	case CS5:
+		ubrlcr = UBRLCR_WRDLEN5;
+		break;
+	case CS6:
+		ubrlcr = UBRLCR_WRDLEN6;
+		break;
+	case CS7:
+		ubrlcr = UBRLCR_WRDLEN7;
+		break;
+	default: // CS8
+		ubrlcr = UBRLCR_WRDLEN8;
+		break;
+	}
+	if (cflag & CSTOPB)
+		ubrlcr |= UBRLCR_XSTOP;
+	if (cflag & PARENB) {
+		ubrlcr |= UBRLCR_PRTEN;
+		if (!(cflag & PARODD))
+			ubrlcr |= UBRLCR_EVENPRT;
+	}
+	if (port->fifosize > 1)
+		ubrlcr |= UBRLCR_FIFOEN;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	port->read_status_mask = UARTDR_OVERR;
+	if (iflag & INPCK)
+		port->read_status_mask |= UARTDR_PARERR | UARTDR_FRMERR;
+
+	/*
+	 * Characters to ignore
+	 */
+	port->ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		port->ignore_status_mask |= UARTDR_FRMERR | UARTDR_PARERR;
+	if (iflag & IGNBRK) {
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns to (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			port->ignore_status_mask |= UARTDR_OVERR;
+	}
+
+	quot -= 1;
+
+	clps_writel(ubrlcr | quot, UBRLCR(port));
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *clps711xuart_type(struct uart_port *port)
+{
+	return port->type == PORT_CLPS711X ? "CLPS711x" : NULL;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void clps711xuart_config_port(struct uart_port *port, int flags)
+{
+	if (flags & UART_CONFIG_TYPE)
+		port->type = PORT_CLPS711X;
+}
+
+static void clps711xuart_release_port(struct uart_port *port)
+{
+}
+
+static int clps711xuart_request_port(struct uart_port *port)
+{
+	return 0;
+}
+
+static struct uart_ops clps711x_pops = {
+	.tx_empty	= clps711xuart_tx_empty,
+	.set_mctrl	= clps711xuart_set_mctrl_null,
+	.get_mctrl	= clps711xuart_get_mctrl,
+	.stop_tx	= clps711xuart_stop_tx,
+	.start_tx	= clps711xuart_start_tx,
+	.stop_rx	= clps711xuart_stop_rx,
+	.enable_ms	= clps711xuart_enable_ms,
+	.break_ctl	= clps711xuart_break_ctl,
+	.startup	= clps711xuart_startup,
+	.shutdown	= clps711xuart_shutdown,
+	.change_speed	= clps711xuart_change_speed,
+	.type		= clps711xuart_type,
+	.config_port	= clps711xuart_config_port,
+	.release_port	= clps711xuart_release_port,
+	.request_port	= clps711xuart_request_port,
+};
+
+static struct uart_port clps711x_ports[UART_NR] = {
+	{
+		.iobase		= SYSCON1,
+		.irq		= IRQ_UTXINT1, /* IRQ_URXINT1, IRQ_UMSINT */
+		.uartclk	= 3686400,
+		.fifosize	= 16,
+		.ops		= &clps711x_pops,
+		.line		= 0,
+		.flags		= ASYNC_BOOT_AUTOCONF,
+	},
+	{
+		.iobase		= SYSCON2,
+		.irq		= IRQ_UTXINT2, /* IRQ_URXINT2 */
+		.uartclk	= 3686400,
+		.fifosize	= 16,
+		.ops		= &clps711x_pops,
+		.line		= 1,
+		.flags		= ASYNC_BOOT_AUTOCONF,
+	}
+};
+
+#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ *
+ *	The console_lock must be held when we get here.
+ *
+ *	Note that this is called with interrupts already disabled
+ */
+static void
+clps711xuart_console_write(struct console *co, const char *s,
+			   unsigned int count)
+{
+	struct uart_port *port = clps711x_ports + co->index;
+	unsigned int status, syscon;
+	int i;
+
+	/*
+	 *	Ensure that the port is enabled.
+	 */
+	syscon = clps_readl(SYSCON(port));
+	clps_writel(syscon | SYSCON_UARTEN, SYSCON(port));
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++) {
+		do {
+			status = clps_readl(SYSFLG(port));
+		} while (status & SYSFLG_UTXFF);
+		clps_writel(s[i], UARTDR(port));
+		if (s[i] == '\n') {
+			do {
+				status = clps_readl(SYSFLG(port));
+			} while (status & SYSFLG_UTXFF);
+			clps_writel('\r', UARTDR(port));
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the uart state.
+	 */
+	do {
+		status = clps_readl(SYSFLG(port));
+	} while (status & SYSFLG_UBUSY);
+
+	clps_writel(syscon, SYSCON(port));
+}
+
+static kdev_t clps711xuart_console_device(struct console *co)
+{
+	return MKDEV(SERIAL_CLPS711X_MAJOR, SERIAL_CLPS711X_MINOR + co->index);
+}
+
+static void __init
+clps711xuart_console_get_options(struct uart_port *port, int *baud,
+				 int *parity, int *bits)
+{
+	if (clps_readl(SYSCON(port)) & SYSCON_UARTEN) {
+		unsigned int ubrlcr, quot;
+
+		ubrlcr = clps_readl(UBRLCR(port));
+
+		*parity = 'n';
+		if (ubrlcr & UBRLCR_PRTEN) {
+			if (ubrlcr & UBRLCR_EVENPRT)
+				*parity = 'e';
+			else
+				*parity = 'o';
+		}
+
+		if ((ubrlcr & UBRLCR_WRDLEN_MASK) == UBRLCR_WRDLEN7)
+			*bits = 7;
+		else
+			*bits = 8;
+
+		quot = ubrlcr & UBRLCR_BAUD_MASK;
+		*baud = port->uartclk / (16 * (quot + 1));
+	}
+}
+
+static int __init clps711xuart_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = 38400;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	port = uart_get_console(clps711x_ports, UART_NR, co);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else
+		clps711xuart_console_get_options(port, &baud, &parity, &bits);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct console clps711x_console = {
+	.name		= SERIAL_CLPS711X_NAME,
+	.write		= clps711xuart_console_write,
+	.device		= clps711xuart_console_device,
+	.setup		= clps711xuart_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+};
+
+void __init clps711xuart_console_init(void)
+{
+	register_console(&clps711x_console);
+}
+
+#define CLPS711X_CONSOLE	&clps711x_console
+#else
+#define CLPS711X_CONSOLE	NULL
+#endif
+
+static struct uart_driver clps711x_reg = {
+#ifdef CONFIG_DEVFS_FS
+	.normal_name		= SERIAL_CLPS711X_NAME,
+	.callout_name		= CALLOUT_CLPS711X_NAME,
+#else
+	.normal_name		= SERIAL_CLPS711X_NAME,
+	.callout_name		= CALLOUT_CLPS711X_NAME,
+#endif
+
+	.normal_major		= SERIAL_CLPS711X_MAJOR,
+	.normal_driver		= &normal,
+	.callout_major		= CALLOUT_CLPS711X_MAJOR,
+	.callout_driver		= &callout,
+
+	.table			= clps711x_table,
+	.termios		= clps711x_termios,
+	.termios_locked		= clps711x_termios_locked,
+
+	.minor			= SERIAL_CLPS711X_MINOR,
+	.nr			= UART_NR,
+
+	.cons			= CLPS711X_CONSOLE,
+};
+
+static int __init clps711xuart_init(void)
+{
+	int ret, i;
+
+	printk(KERN_INFO "Serial: CLPS711x driver\n");
+
+	ret = uart_register_driver(&clps711x_reg);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < UART_NR; i++)
+		uart_add_one_port(&clps711x_reg, &clps711x_ports[i]);
+
+	return 0;
+}
+
+static void __exit clps711xuart_exit(void)
+{
+	int i;
+
+	for (i = 0; i < UART_NR; i++)
+		uart_remove_one_port(&clps711x_reg, &clps711x_ports[i]);
+
+	uart_unregister_driver(&clps711x_reg);
+}
+
+module_init(clps711xuart_init);
+module_exit(clps711xuart_exit);
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("Deep Blue Solutions Ltd");
+MODULE_DESCRIPTION("CLPS-711x generic serial driver");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/drivers/serial/Config.in linux-2.4.29-uc1/drivers/serial/Config.in
--- linux-2.4.29/drivers/serial/Config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/serial/Config.in	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,99 @@
+#
+# Serial device configuration
+#
+# $Id: Config.in,v 1.4 2001/10/12 15:46:58 rmk Exp $
+#
+mainmenu_option next_comment
+comment 'Serial drivers'
+
+if [ "$CONFIG_ARM" = "y" ]; then
+  # I don't have this in my tree yet.
+  dep_bool 'Anakin serial port support' CONFIG_SERIAL_ANAKIN $CONFIG_ARCH_ANAKIN
+  dep_bool '  Console on Anakin serial port' CONFIG_SERIAL_ANAKIN_CONSOLE $CONFIG_SERIAL_ANAKIN
+  if [ "$CONFIG_SERIAL_ANAKIN" = "y" ]; then
+     int  '  Default Anakin serial baudrate' CONFIG_ANAKIN_DEFAULT_BAUDRATE 9600
+  fi
+
+  dep_tristate 'ARM AMBA serial port support' CONFIG_SERIAL_AMBA $CONFIG_ARCH_INTEGRATOR
+  dep_bool '  Support for console on AMBA serial port' CONFIG_SERIAL_AMBA_CONSOLE $CONFIG_SERIAL_AMBA
+  if [ "$CONFIG_SERIAL_AMBA" = "y" ]; then
+     define_bool CONFIG_SERIAL_INTEGRATOR y
+  fi
+
+  if [ "$CONFIG_ARCH_EP93XX" = "y" ]; then
+     tristate 'Cirrus EP93xx serial port support' CONFIG_SERIAL_EP93XX
+     dep_bool '  Support for console on EP93xx serial port' CONFIG_SERIAL_EP93XX_CONSOLE $CONFIG_SERIAL_EP93XX
+  fi
+
+  dep_tristate 'CLPS711X serial port support' CONFIG_SERIAL_CLPS711X $CONFIG_ARCH_CLPS711X
+  dep_bool '  Support for console on CLPS711X serial port' CONFIG_SERIAL_CLPS711X_CONSOLE $CONFIG_SERIAL_CLPS711X
+
+  dep_bool 'DC21285 serial port support' CONFIG_SERIAL_21285 $CONFIG_FOOTBRIDGE
+  dep_bool '  Use /dev/ttyS0 device (OBSOLETE)' CONFIG_SERIAL_21285_OLD $CONFIG_SERIAL_21285 $CONFIG_OBSOLETE
+  dep_bool '  Console on DC21285 serial port' CONFIG_SERIAL_21285_CONSOLE $CONFIG_SERIAL_21285
+
+  dep_bool 'Excalibur serial port (uart00) support' CONFIG_SERIAL_UART00 $CONFIG_ARCH_CAMELOT
+  dep_bool '  Support for console on Excalibur serial port' CONFIG_SERIAL_UART00_CONSOLE $CONFIG_SERIAL_UART00
+
+
+  dep_bool 'SA1100 serial port support' CONFIG_SERIAL_SA1100 $CONFIG_ARCH_SA1100
+  dep_bool '  Console on SA1100 serial port' CONFIG_SERIAL_SA1100_CONSOLE $CONFIG_SERIAL_SA1100
+  if [ "$CONFIG_SERIAL_SA1100" = "y" ]; then
+     int  '  Default SA1100 serial baudrate' CONFIG_SA1100_DEFAULT_BAUDRATE 9600
+  fi
+
+  dep_tristate 'ARM Omaha serial port support' CONFIG_SERIAL_OMAHA $CONFIG_ARCH_OMAHA
+  dep_bool '  Support for console on Omaha serial port' CONFIG_SERIAL_OMAHA_CONSOLE $CONFIG_SERIAL_OMAHA
+
+  dep_tristate 'AT91RM9200 serial port support' CONFIG_SERIAL_AT91 $CONFIG_ARCH_AT91RM9200
+  dep_bool '  Console on AT91RM9200 serial port' CONFIG_SERIAL_AT91_CONSOLE $CONFIG_SERIAL_AT91
+
+fi
+#
+# The new 8250/16550 serial drivers
+dep_tristate '8250/16550 and compatible serial support (EXPERIMENTAL)' CONFIG_SERIAL_8250 $CONFIG_EXPERIMENTAL
+dep_bool '  Console on 8250/16550 and compatible serial port (EXPERIMENTAL)' CONFIG_SERIAL_8250_CONSOLE $CONFIG_SERIAL_8250 $CONFIG_EXPERIMENTAL
+
+dep_mbool 'Extended 8250/16550 serial driver options' CONFIG_SERIAL_8250_EXTENDED $CONFIG_SERIAL_8250
+dep_bool '  Support more than 4 serial ports' CONFIG_SERIAL_8250_MANY_PORTS $CONFIG_SERIAL_8250_EXTENDED
+dep_bool '  Support for sharing serial interrupts' CONFIG_SERIAL_8250_SHARE_IRQ $CONFIG_SERIAL_8250_EXTENDED
+dep_bool '  Autodetect IRQ on standard ports (unsafe)' CONFIG_SERIAL_8250_DETECT_IRQ $CONFIG_SERIAL_8250_EXTENDED
+dep_bool '  Support special multiport boards' CONFIG_SERIAL_8250_MULTIPORT $CONFIG_SERIAL_8250_EXTENDED
+dep_bool '  Support Bell Technologies HUB6 card' CONFIG_SERIAL_8250_HUB6 $CONFIG_SERIAL_8250_EXTENDED
+
+if [ "$CONFIG_SERIAL_AMBA" = "y" -o \
+     "$CONFIG_SERIAL_EP93XX" = "y" -o \
+     "$CONFIG_SERIAL_CLPS711X" = "y" -o \
+     "$CONFIG_SERIAL_SA1100" = "y" -o \
+     "$CONFIG_SERIAL_ANAKIN" = "y" -o \
+     "$CONFIG_SERIAL_UART00" = "y" -o \
+     "$CONFIG_SERIAL_8250" = "y"  -o \
+     "$CONFIG_SERIAL_OMAHA" = "y" -o \
+     "$CONFIG_SERIAL_AT91" = "y" ]; then
+   define_bool CONFIG_SERIAL_CORE y
+else
+   if [ "$CONFIG_SERIAL_AMBA" = "m" -o \
+        "$CONFIG_SERIAL_EP93XX" = "m" -o \
+        "$CONFIG_SERIAL_CLPS711X" = "m" -o \
+        "$CONFIG_SERIAL_SA1100" = "m" -o \
+        "$CONFIG_SERIAL_ANAKIN" = "m" -o \
+        "$CONFIG_SERIAL_UART00" = "m" -o \
+        "$CONFIG_SERIAL_8250" = "m"  -o \
+        "$CONFIG_SERIAL_OMAHA" = "m" -o \
+        "$CONFIG_SERIAL_AT91" = "m" ]; then
+      define_bool CONFIG_SERIAL_CORE m
+   fi
+fi
+if [ "$CONFIG_SERIAL_AMBA_CONSOLE" = "y" -o \
+     "$CONFIG_SERIAL_EP93XX_CONSOLE" = "y" -o \
+     "$CONFIG_SERIAL_CLPS711X_CONSOLE" = "y" -o \
+     "$CONFIG_SERIAL_SA1100_CONSOLE" = "y" -o \
+     "$CONFIG_SERIAL_ANAKIN_CONSOLE" = "y" -o \
+     "$CONFIG_SERIAL_UART00_CONSOLE" = "y" -o \
+     "$CONFIG_SERIAL_8250_CONSOLE" = "y" -o \
+     "$CONFIG_SERIAL_OMAHA" = "y" -o \
+     "$CONFIG_SERIAL_AT91_CONSOLE" = "y" ]; then
+   define_bool CONFIG_SERIAL_CORE_CONSOLE y
+fi
+
+endmenu
diff -urN linux-2.4.29/drivers/serial/core.c linux-2.4.29-uc1/drivers/serial/core.c
--- linux-2.4.29/drivers/serial/core.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/serial/core.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,2588 @@
+/*
+ *  linux/drivers/serial/core.c
+ *
+ *  Driver core for serial ports
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright 1999 ARM Limited
+ *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *  $Id: core.c,v 1.20.2.5 2002/03/13 15:22:26 rmk Exp $
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/tty.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/pm.h>
+#include <linux/serial_core.h>
+#include <linux/smp_lock.h>
+
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#undef	DEBUG
+#ifdef DEBUG
+#define DPRINTK(x...)	printk(x)
+#else
+#define DPRINTK(x...)	do { } while (0)
+#endif
+
+#ifndef CONFIG_PM
+#define pm_access(pm)		do { } while (0)
+#define pm_unregister(pm)	do { } while (0)
+#endif
+
+/*
+ * This is used to lock changes in serial line configuration.
+ */
+static DECLARE_MUTEX(port_sem);
+
+#define HIGH_BITS_OFFSET	((sizeof(long)-sizeof(int))*8)
+
+#define uart_users(state)	((state)->count + ((state)->info ? (state)->info->blocked_open : 0))
+
+#ifdef CONFIG_SERIAL_CORE_CONSOLE
+#define uart_console(port)	((port)->cons && (port)->cons->index == (port)->line)
+#else
+#define uart_console(port)	(0)
+#endif
+
+static void uart_change_speed(struct uart_state *state, struct termios *old_termios);
+static void uart_wait_until_sent(struct tty_struct *tty, int timeout);
+static void uart_change_pm(struct uart_state *state, int pm_state);
+
+/*
+ * This routine is used by the interrupt handler to schedule processing in
+ * the software interrupt portion of the driver.
+ */
+void uart_write_wakeup(struct uart_port *port)
+{
+	struct uart_info *info = port->info;
+	tasklet_schedule(&info->tlet);
+}
+
+static void uart_stop(struct tty_struct *tty)
+{
+	struct uart_state *state = tty->driver_data;
+	struct uart_port *port = state->port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	port->ops->stop_tx(port, 1);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void __uart_start(struct tty_struct *tty)
+{
+	struct uart_state *state = tty->driver_data;
+	struct uart_port *port = state->port;
+
+	if (!uart_circ_empty(&state->info->xmit) && state->info->xmit.buf &&
+	    !tty->stopped && !tty->hw_stopped)
+		port->ops->start_tx(port, 1);
+}
+
+static void uart_start(struct tty_struct *tty)
+{
+	struct uart_state *state = tty->driver_data;
+	struct uart_port *port = state->port;
+	unsigned long flags;
+
+	pm_access(state->pm);
+
+	spin_lock_irqsave(&port->lock, flags);
+	__uart_start(tty);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void uart_tasklet_action(unsigned long data)
+{
+	struct uart_state *state = (struct uart_state *)data;
+	struct tty_struct *tty;
+
+	tty = state->info->tty;
+	if (tty) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			tty->ldisc.write_wakeup(tty);
+		wake_up_interruptible(&tty->write_wait);
+	}
+}
+
+static inline void
+uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
+{
+	unsigned long flags;
+	unsigned int old;
+
+	spin_lock_irqsave(&port->lock, flags);
+	old = port->mctrl;
+	port->mctrl = (old & ~clear) | set;
+	if (old != port->mctrl)
+		port->ops->set_mctrl(port, port->mctrl);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+#define uart_set_mctrl(port,set)	uart_update_mctrl(port,set,0)
+#define uart_clear_mctrl(port,clear)	uart_update_mctrl(port,0,clear)
+
+static inline unsigned int uart_get_altspeed(struct uart_port *port)
+{
+	unsigned int flags = port->flags & UPF_SPD_MASK;
+	unsigned int altbaud = 0;
+
+	if (flags == ASYNC_SPD_HI)
+		altbaud = 57600;
+	if (flags == ASYNC_SPD_VHI)
+		altbaud = 115200;
+	if (flags == ASYNC_SPD_SHI)
+		altbaud = 230400;
+	if (flags == ASYNC_SPD_WARP)
+		altbaud = 460800;
+
+	return altbaud;
+}
+
+/*
+ * Startup the port.  This will be called once per open.  All calls
+ * will be serialised by the per-port semaphore.
+ */
+static int uart_startup(struct uart_state *state, int init_hw)
+{
+	struct uart_info *info = state->info;
+	struct uart_port *port = state->port;
+	unsigned long page;
+	int retval = 0;
+
+	if (info->flags & UIF_INITIALIZED)
+		return 0;
+
+	/*
+	 * Set the TTY IO error marker - we will only clear this
+	 * once we have successfully opened the port.  Also set
+	 * up the tty->alt_speed kludge
+	 */
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	if (port->type == PORT_UNKNOWN)
+		return 0;
+
+	/*
+	 * Initialise and allocate the transmit and temporary
+	 * buffer.
+	 */
+	if (!info->xmit.buf) {
+		page = get_zeroed_page(GFP_KERNEL);
+		if (!page)
+			return -ENOMEM;
+
+		info->xmit.buf = (unsigned char *) page;
+		info->tmpbuf = info->xmit.buf + UART_XMIT_SIZE;
+		init_MUTEX(&info->tmpbuf_sem);
+		uart_circ_clear(&info->xmit);
+	}
+
+	port->mctrl = 0;
+
+	retval = port->ops->startup(port);
+	if (retval == 0) {
+		if (init_hw) {
+			/*
+			 * Initialise the hardware port settings.
+			 */
+			uart_change_speed(state, NULL);
+
+			/*
+			 * Setup the RTS and DTR signals once the
+			 * port is open and ready to respond.
+			 */
+			if (info->tty->termios->c_cflag & CBAUD)
+				uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
+		}
+
+		info->flags |= UIF_INITIALIZED;
+
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	}
+
+	if (retval && capable(CAP_SYS_ADMIN))
+		retval = 0;
+
+	return retval;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.  Calls to
+ * uart_shutdown are serialised by the per-port semaphore.
+ */
+static void uart_shutdown(struct uart_state *state)
+{
+	struct uart_info *info = state->info;
+	struct uart_port *port = state->port;
+
+	if (!(info->flags & UIF_INITIALIZED))
+		return;
+
+	/*
+	 * Turn off DTR and RTS early.
+	 */
+	if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+		uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+
+	/*
+	 * clear delta_msr_wait queue to avoid mem leaks: we may free
+	 * the irq here so the queue might never be woken up.  Note
+	 * that we won't end up waiting on delta_msr_wait again since
+	 * any outstanding file descriptors should be pointing at
+	 * hung_up_tty_fops now.
+	 */
+	wake_up_interruptible(&info->delta_msr_wait);
+
+	/*
+	 * Free the IRQ and disable the port.
+	 */
+	port->ops->shutdown(port);
+
+	/*
+	 * Free the transmit buffer page.
+	 */
+	if (info->xmit.buf) {
+		free_page((unsigned long)info->xmit.buf);
+		info->xmit.buf = NULL;
+		info->tmpbuf = NULL;
+	}
+
+	/*
+	 * kill off our tasklet
+	 */
+	tasklet_kill(&info->tlet);
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~UIF_INITIALIZED;
+}
+
+/**
+ *	uart_update_timeout - update per-port FIFO timeout.
+ *	@port: uart_port structure describing the port.
+ *	@cflag: termios cflag value
+ *	@quot: uart clock divisor quotient
+ *
+ *	Set the port FIFO timeout value.  The @cflag value should
+ *	reflect the actual hardware settings.
+ */
+void
+uart_update_timeout(struct uart_port *port, unsigned int cflag,
+		    unsigned int baud)
+{
+	unsigned int bits;
+
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	case CS5:
+		bits = 7;
+		break;
+	case CS6:
+		bits = 8;
+		break;
+	case CS7:
+		bits = 9;
+		break;
+	default:
+		bits = 10;
+		break; // CS8
+	}
+
+	if (cflag & CSTOPB)
+		bits++;
+	if (cflag & PARENB)
+		bits++;
+
+	/*
+	 * The total number of bits to be transmitted in the fifo.
+	 */
+	bits = bits * port->fifosize;
+
+	/*
+	 * Figure the timeout to send the above number of bits.
+	 * Add .02 seconds of slop
+	 */
+	port->timeout = (HZ * bits) / baud + HZ/50;
+}
+
+EXPORT_SYMBOL(uart_update_timeout);
+
+static inline u_int uart_calculate_quot(struct uart_port *port, u_int baud)
+{
+	u_int quot;
+
+	/* Special case: B0 rate */
+	if (!baud)
+		baud = 9600;
+
+	/* Old HI/VHI/custom speed handling */
+	if (baud == 38400 &&
+	    ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+		quot = port->custom_divisor;
+	else
+		quot = port->uartclk / (16 * baud);
+
+	return quot;
+}
+
+static void
+uart_change_speed(struct uart_state *state, struct termios *old_termios)
+{
+	struct tty_struct *tty = state->info->tty;
+	struct uart_port *port = state->port;
+	struct termios *termios;
+	unsigned int quot, baud, cflag, try;
+
+	/*
+	 * If we have no tty, termios, or the port does not exist,
+	 * then we can't set the parameters for this port.
+	 */
+	if (!tty || !tty->termios || port->type == PORT_UNKNOWN)
+		return;
+
+	termios = tty->termios;
+
+	cflag = termios->c_cflag;
+
+	for (try = 0; try < 2; try ++) {
+		/* Determine divisor based on baud rate */
+		baud = tty_get_baud_rate(tty);
+		quot = uart_calculate_quot(port, baud);
+		if (quot)
+			break;
+
+		/*
+		 * Oops, the quotient was zero.  Try again with
+		 * the old baud rate if possible.
+		 */
+		termios->c_cflag &= ~CBAUD;
+		if (old_termios) {
+			termios->c_cflag |=
+				 (old_termios->c_cflag & CBAUD);
+			old_termios = NULL;
+			continue;
+		}
+
+		/*
+		 * As a last resort, if the quotient is zero,
+		 * default to 9600 bps
+		 */
+		termios->c_cflag |= B9600;
+	}
+
+	uart_update_timeout(port, cflag, port->uartclk / (16 * quot));
+
+	if (termios->c_cflag & CRTSCTS)
+		state->info->flags |= UIF_CTS_FLOW;
+	else
+		state->info->flags &= ~UIF_CTS_FLOW;
+	if (termios->c_cflag & CLOCAL)
+		state->info->flags &= ~UIF_CHECK_CD;
+	else
+		state->info->flags |= UIF_CHECK_CD;
+
+	/*
+	 * Set up parity check flag
+	 */
+	pm_access(state->pm);
+
+	port->ops->change_speed(port, cflag, termios->c_iflag, quot);
+}
+
+static inline void
+__uart_put_char(struct uart_port *port, struct circ_buf *circ, unsigned char c)
+{
+	unsigned long flags;
+
+	if (!circ->buf)
+		return;
+
+	spin_lock_irqsave(&port->lock, flags);
+	if (uart_circ_chars_free(circ) != 0) {
+		circ->buf[circ->head] = c;
+		circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1);
+	}
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static inline int
+__uart_user_write(struct uart_port *port, struct circ_buf *circ,
+		  const unsigned char *buf, int count)
+{
+	unsigned long flags;
+	int c, ret = 0;
+
+	if (down_interruptible(&port->info->tmpbuf_sem))
+		return -EINTR;
+
+	while (1) {
+		int c1;
+		c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
+		if (count < c)
+			c = count;
+		if (c <= 0)
+			break;
+
+		c -= copy_from_user(port->info->tmpbuf, buf, c);
+		if (!c) {
+			if (!ret)
+				ret = -EFAULT;
+			break;
+		}
+		spin_lock_irqsave(&port->lock, flags);
+		c1 = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
+		if (c1 < c)
+			c = c1;
+		memcpy(circ->buf + circ->head, port->info->tmpbuf, c);
+		circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
+		spin_unlock_irqrestore(&port->lock, flags);
+		buf += c;
+		count -= c;
+		ret += c;
+	}
+	up(&port->info->tmpbuf_sem);
+
+	return ret;
+}
+
+static inline int
+__uart_kern_write(struct uart_port *port, struct circ_buf *circ,
+		  const unsigned char *buf, int count)
+{
+	unsigned long flags;
+	int c, ret = 0;
+
+	spin_lock_irqsave(&port->lock, flags);
+	while (1) {
+		c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
+		if (count < c)
+			c = count;
+		if (c <= 0)
+			break;
+		memcpy(circ->buf + circ->head, buf, c);
+		circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
+		buf += c;
+		count -= c;
+		ret += c;
+	}
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	return ret;
+}
+
+static void uart_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	struct uart_state *state = tty->driver_data;
+
+	__uart_put_char(state->port, &state->info->xmit, ch);
+}
+
+static void uart_flush_chars(struct tty_struct *tty)
+{
+	uart_start(tty);
+}
+
+static int
+uart_write(struct tty_struct *tty, int from_user, const unsigned char * buf,
+	   int count)
+{
+	struct uart_state *state = tty->driver_data;
+	int ret;
+
+	if (!state->info->xmit.buf)
+		return 0;
+
+	if (from_user)
+		ret = __uart_user_write(state->port, &state->info->xmit, buf, count);
+	else
+		ret = __uart_kern_write(state->port, &state->info->xmit, buf, count);
+
+	uart_start(tty);
+	return ret;
+}
+
+static int uart_write_room(struct tty_struct *tty)
+{
+	struct uart_state *state = tty->driver_data;
+
+	return uart_circ_chars_free(&state->info->xmit);
+}
+
+static int uart_chars_in_buffer(struct tty_struct *tty)
+{
+	struct uart_state *state = tty->driver_data;
+
+	return uart_circ_chars_pending(&state->info->xmit);
+}
+
+static void uart_flush_buffer(struct tty_struct *tty)
+{
+	struct uart_state *state = tty->driver_data;
+	struct uart_port *port = state->port;
+	unsigned long flags;
+
+	DPRINTK("uart_flush_buffer(%d) called\n",
+	        MINOR(tty->device) - tty->driver.minor_start);
+
+	spin_lock_irqsave(&port->lock, flags);
+	uart_circ_clear(&state->info->xmit);
+	spin_unlock_irqrestore(&port->lock, flags);
+	wake_up_interruptible(&tty->write_wait);
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void uart_send_xchar(struct tty_struct *tty, char ch)
+{
+	struct uart_state *state = tty->driver_data;
+	struct uart_port *port = state->port;
+	unsigned long flags;
+
+	if (port->ops->send_xchar)
+		port->ops->send_xchar(port, ch);
+	else {
+		port->x_char = ch;
+		if (ch) {
+			spin_lock_irqsave(&port->lock, flags);
+			port->ops->start_tx(port, 0);
+			spin_unlock_irqrestore(&port->lock, flags);
+		}
+	}
+}
+
+static void uart_throttle(struct tty_struct *tty)
+{
+	struct uart_state *state = tty->driver_data;
+
+	if (I_IXOFF(tty))
+		uart_send_xchar(tty, STOP_CHAR(tty));
+
+	if (tty->termios->c_cflag & CRTSCTS)
+		uart_clear_mctrl(state->port, TIOCM_RTS);
+}
+
+static void uart_unthrottle(struct tty_struct *tty)
+{
+	struct uart_state *state = tty->driver_data;
+	struct uart_port *port = state->port;
+
+	if (I_IXOFF(tty)) {
+		if (port->x_char)
+			port->x_char = 0;
+		else
+			uart_send_xchar(tty, START_CHAR(tty));
+	}
+
+	if (tty->termios->c_cflag & CRTSCTS)
+		uart_set_mctrl(port, TIOCM_RTS);
+}
+
+static int uart_get_info(struct uart_state *state, struct serial_struct *retinfo)
+{
+	struct uart_port *port = state->port;
+	struct serial_struct tmp;
+
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type	    = port->type;
+	tmp.line	    = port->line;
+	tmp.port	    = port->iobase;
+	if (HIGH_BITS_OFFSET)
+		tmp.port_high = (long) port->iobase >> HIGH_BITS_OFFSET;
+	tmp.irq		    = port->irq;
+	tmp.flags	    = port->flags;
+	tmp.xmit_fifo_size  = port->fifosize;
+	tmp.baud_base	    = port->uartclk / 16;
+	tmp.close_delay	    = state->close_delay;
+	tmp.closing_wait    = state->closing_wait;
+	tmp.custom_divisor  = port->custom_divisor;
+	tmp.hub6	    = port->hub6;
+	tmp.io_type         = port->iotype;
+	tmp.iomem_reg_shift = port->regshift;
+	tmp.iomem_base      = (void *)port->mapbase;
+
+	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
+		return -EFAULT;
+	return 0;
+}
+
+static int
+uart_set_info(struct uart_state *state, struct serial_struct *newinfo)
+{
+	struct serial_struct new_serial;
+	struct uart_port *port = state->port;
+	unsigned long new_port;
+	unsigned int change_irq, change_port, old_flags;
+	unsigned int old_custom_divisor;
+	int retval = 0;
+
+	if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
+		return -EFAULT;
+
+	new_port = new_serial.port;
+	if (HIGH_BITS_OFFSET)
+		new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
+
+	new_serial.irq = irq_cannonicalize(new_serial.irq);
+
+	/*
+	 * This semaphore protects state->count.  It is also
+	 * very useful to prevent opens.  Also, take the
+	 * port configuration semaphore to make sure that a
+	 * module insertion/removal doesn't change anything
+	 * under us.
+	 */
+	down(&state->sem);
+
+	change_irq  = new_serial.irq != port->irq;
+
+	/*
+	 * Since changing the 'type' of the port changes its resource
+	 * allocations, we should treat type changes the same as
+	 * IO port changes.
+	 */
+	change_port = new_port != port->iobase ||
+		      (unsigned long)new_serial.iomem_base != port->mapbase ||
+		      new_serial.hub6 != port->hub6 ||
+		      new_serial.io_type != port->iotype ||
+		      new_serial.iomem_reg_shift != port->regshift ||
+		      new_serial.type != port->type;
+
+	old_flags = port->flags;
+	old_custom_divisor = port->custom_divisor;
+
+	if (!capable(CAP_SYS_ADMIN)) {
+		retval = -EPERM;
+		if (change_irq || change_port ||
+		    (new_serial.baud_base != port->uartclk / 16) ||
+		    (new_serial.close_delay != state->close_delay) ||
+		    (new_serial.closing_wait != state->closing_wait) ||
+		    (new_serial.xmit_fifo_size != port->fifosize) ||
+		    (((new_serial.flags ^ old_flags) & ~UPF_USR_MASK) != 0))
+			goto exit;
+		port->flags = ((port->flags & ~UPF_USR_MASK) |
+			       (new_serial.flags & UPF_USR_MASK));
+		port->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	/*
+	 * Ask the low level driver to verify the settings.
+	 */
+	if (port->ops->verify_port)
+		retval = port->ops->verify_port(port, &new_serial);
+
+	if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) ||
+	    (new_serial.baud_base < 9600))
+		retval = -EINVAL;
+
+	if (retval)
+		goto exit;
+
+	if (change_port || change_irq) {
+		retval = -EBUSY;
+
+		/*
+		 * Make sure that we are the sole user of this port.
+		 */
+		if (uart_users(state) > 1)
+			goto exit;
+
+		/*
+		 * We need to shutdown the serial port at the old
+		 * port/type/irq combination.
+		 */
+		uart_shutdown(state);
+	}
+
+	if (change_port) {
+		unsigned long old_iobase, old_mapbase;
+		unsigned int old_type, old_iotype, old_hub6, old_shift;
+
+		old_iobase = port->iobase;
+		old_mapbase = port->mapbase;
+		old_type = port->type;
+		old_hub6 = port->hub6;
+		old_iotype = port->iotype;
+		old_shift = port->regshift;
+
+		/*
+		 * Free and release old regions
+		 */
+		if (old_type != PORT_UNKNOWN)
+			port->ops->release_port(port);
+
+		port->iobase = new_port;
+		port->type = new_serial.type;
+		port->hub6 = new_serial.hub6;
+		port->iotype = new_serial.io_type;
+		port->regshift = new_serial.iomem_reg_shift;
+		port->mapbase = (unsigned long)new_serial.iomem_base;
+
+		/*
+		 * Claim and map the new regions
+		 */
+		if (port->type != PORT_UNKNOWN) {
+			retval = port->ops->request_port(port);
+		} else {
+			/* Always success - Jean II */
+			retval = 0;
+		}
+
+		/*
+		 * If we fail to request resources for the
+		 * new port, try to restore the old settings.
+		 */
+		if (retval && old_type != PORT_UNKNOWN) {
+			port->iobase = old_iobase;
+			port->type = old_type;
+			port->hub6 = old_hub6;
+			port->iotype = old_iotype;
+			port->regshift = old_shift;
+			port->mapbase = old_mapbase;
+			retval = port->ops->request_port(port);
+			/*
+			 * If we failed to restore the old settings,
+			 * we fail like this.
+			 */
+			if (retval)
+				port->type = PORT_UNKNOWN;
+
+			/*
+			 * We failed anyway.
+			 */
+			retval = -EBUSY;
+		}
+	}
+
+	port->irq              = new_serial.irq;
+	port->uartclk          = new_serial.baud_base * 16;
+	port->flags            = (port->flags & ~UPF_CHANGE_MASK) |
+				 (new_serial.flags & UPF_CHANGE_MASK);
+	port->custom_divisor   = new_serial.custom_divisor;
+	state->close_delay     = new_serial.close_delay * HZ / 100;
+	state->closing_wait    = new_serial.closing_wait * HZ / 100;
+	port->fifosize         = new_serial.xmit_fifo_size;
+	if (state->info->tty)
+		state->info->tty->low_latency =
+			(port->flags & UPF_LOW_LATENCY) ? 1 : 0;
+
+ check_and_exit:
+	retval = 0;
+	if (port->type == PORT_UNKNOWN)
+		goto exit;
+	if (state->info->flags & UIF_INITIALIZED) {
+		if (((old_flags ^ port->flags) & UPF_SPD_MASK) ||
+		    old_custom_divisor != port->custom_divisor) {
+			state->info->tty->alt_speed = uart_get_altspeed(port);
+			uart_change_speed(state, NULL);
+		}
+	} else
+		retval = uart_startup(state, 1);
+ exit:
+	up(&state->sem);
+	return retval;
+}
+
+
+/*
+ * uart_get_lsr_info - get line status register info.
+ * Note: uart_ioctl protects us against hangups.
+ */
+static int uart_get_lsr_info(struct uart_state *state, unsigned int *value)
+{
+	struct uart_port *port = state->port;
+	unsigned int result;
+
+	result = port->ops->tx_empty(port);
+
+	/*
+	 * If we're about to load something into the transmit
+	 * register, we'll pretend the transmitter isn't empty to
+	 * avoid a race condition (depending on when the transmit
+	 * interrupt happens).
+	 */
+	if (port->x_char ||
+	    ((uart_circ_chars_pending(&state->info->xmit) > 0) &&
+	     !state->info->tty->stopped && !state->info->tty->hw_stopped))
+		result &= ~TIOCSER_TEMT;
+	
+	return put_user(result, value);
+}
+
+static int uart_tiocmget(struct tty_struct *tty, struct file *file)
+{
+	struct uart_state *state = tty->driver_data;
+	struct uart_port *port = state->port;
+	int result = -EIO;
+
+	down(&state->sem);
+	if ((!file || !tty_hung_up_p(file)) &&
+	    !(tty->flags & (1 << TTY_IO_ERROR))) {
+		result = port->mctrl;
+		result |= port->ops->get_mctrl(port);
+	}
+	up(&state->sem);
+
+	return result;
+}
+
+static int
+uart_tiocmset(struct tty_struct *tty, struct file *file,
+	      unsigned int set, unsigned int clear)
+{
+	struct uart_state *state = tty->driver_data;
+	struct uart_port *port = state->port;
+	int ret = -EIO;
+
+	down(&state->sem);
+	if ((!file || !tty_hung_up_p(file)) &&
+	    !(tty->flags & (1 << TTY_IO_ERROR))) {
+		uart_update_mctrl(port, set, clear);
+		ret = 0;
+	}
+	up(&state->sem);
+	return ret;
+}
+
+static void uart_break_ctl(struct tty_struct *tty, int break_state)
+{
+	struct uart_state *state = tty->driver_data;
+	struct uart_port *port = state->port;
+
+	BUG_ON(!kernel_locked());
+
+	down(&state->sem);
+
+	if (port->type != PORT_UNKNOWN)
+		port->ops->break_ctl(port, break_state);
+
+	up(&state->sem);
+}
+
+static int uart_do_autoconfig(struct uart_state *state)
+{
+	struct uart_port *port = state->port;
+	int flags, ret;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	/*
+	 * Take the per-port semaphore.  This prevents count from
+	 * changing, and hence any extra opens of the port while
+	 * we're auto-configuring.
+	 */
+	if (down_interruptible(&state->sem))
+		return -ERESTARTSYS;
+
+	ret = -EBUSY;
+	if (uart_users(state) == 1) {
+		uart_shutdown(state);
+
+		/*
+		 * If we already have a port type configured,
+		 * we must release its resources.
+		 */
+		if (port->type != PORT_UNKNOWN)
+			port->ops->release_port(port);
+
+		flags = UART_CONFIG_TYPE;
+		if (port->flags & UPF_AUTO_IRQ)
+			flags |= UART_CONFIG_IRQ;
+
+		/*
+		 * This will claim the ports resources if
+		 * a port is found.
+		 */
+		port->ops->config_port(port, flags);
+
+		ret = uart_startup(state, 1);
+	}
+	up(&state->sem);
+	return ret;
+}
+
+/*
+ * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+ * - mask passed in arg for lines of interest
+ *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+ * Caller should use TIOCGICOUNT to see which one it was
+ */
+static int
+uart_wait_modem_status(struct uart_state *state, unsigned long arg)
+{
+	struct uart_port *port = state->port;
+	DECLARE_WAITQUEUE(wait, current);
+	struct uart_icount cprev, cnow;
+	int ret;
+
+	/*
+	 * note the counters on entry
+	 */
+	spin_lock_irq(&port->lock);
+	memcpy(&cprev, &port->icount, sizeof(struct uart_icount));
+
+	/*
+	 * Force modem status interrupts on
+	 */
+	port->ops->enable_ms(port);
+	spin_unlock_irq(&port->lock);
+
+	add_wait_queue(&state->info->delta_msr_wait, &wait);
+	for (;;) {
+		spin_lock_irq(&port->lock);
+		memcpy(&cnow, &port->icount, sizeof(struct uart_icount));
+		spin_unlock_irq(&port->lock);
+
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+		    ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+		    ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
+		    ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
+			ret = 0;
+			break;
+		}
+
+		schedule();
+
+		/* see if a signal did it */
+		if (signal_pending(current)) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+
+		cprev = cnow;
+	}
+
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&state->info->delta_msr_wait, &wait);
+
+	return ret;
+}
+
+/*
+ * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+ * Return: write counters to the user passed counter struct
+ * NB: both 1->0 and 0->1 transitions are counted except for
+ *     RI where only 0->1 is counted.
+ */
+static int
+uart_get_count(struct uart_state *state, struct serial_icounter_struct *icnt)
+{
+	struct serial_icounter_struct icount;
+	struct uart_icount cnow;
+	struct uart_port *port = state->port;
+
+	spin_lock_irq(&port->lock);
+	memcpy(&cnow, &port->icount, sizeof(struct uart_icount));
+	spin_unlock_irq(&port->lock);
+
+	icount.cts         = cnow.cts;
+	icount.dsr         = cnow.dsr;
+	icount.rng         = cnow.rng;
+	icount.dcd         = cnow.dcd;
+	icount.rx          = cnow.rx;
+	icount.tx          = cnow.tx;
+	icount.frame       = cnow.frame;
+	icount.overrun     = cnow.overrun;
+	icount.parity      = cnow.parity;
+	icount.brk         = cnow.brk;
+	icount.buf_overrun = cnow.buf_overrun;
+
+	return copy_to_user(icnt, &icount, sizeof(icount)) ? -EFAULT : 0;
+}
+
+/*
+ * Called via sys_ioctl under the BKL.  We can use spin_lock_irq() here.
+ */
+static int
+uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
+	   unsigned long arg)
+{
+	struct uart_state *state = tty->driver_data;
+	int ret = -ENOIOCTLCMD;
+
+	BUG_ON(!kernel_locked());
+
+	/*
+	 * These ioctls don't rely on the hardware to be present.
+	 */
+	switch (cmd) {
+	case TIOCGSERIAL:
+		ret = uart_get_info(state, (struct serial_struct *)arg);
+		break;
+
+	case TIOCSSERIAL:
+		ret = uart_set_info(state, (struct serial_struct *)arg);
+		break;
+
+	case TIOCSERCONFIG:
+		ret = uart_do_autoconfig(state);
+		break;
+
+	case TIOCSERGWILD: /* obsolete */
+	case TIOCSERSWILD: /* obsolete */
+		ret = 0;
+		break;
+	}
+
+	if (ret != -ENOIOCTLCMD)
+		goto out;
+
+	if (tty->flags & (1 << TTY_IO_ERROR)) {
+		ret = -EIO;
+		goto out;
+	}
+
+	/*
+	 * The following should only be used when hardware is present.
+	 */
+	switch (cmd) {
+	case TIOCMIWAIT:
+		ret = uart_wait_modem_status(state, arg);
+		break;
+
+	case TIOCGICOUNT:
+		ret = uart_get_count(state, (struct serial_icounter_struct *)arg);
+		break;
+
+	case TIOCMGET:
+		{
+			int val;
+			val = uart_tiocmget(tty, filp);
+			if (val >= 0) {
+				ret = put_user(val, (int *)arg);
+			} else {
+				ret = val;
+			}
+		}
+		break;
+
+	case TIOCMBIS:
+	case TIOCMBIC:
+	case TIOCMSET:
+		{
+			int val, set = 0, clear = 0;
+			ret = get_user(val, (int *)arg);
+			if (ret)
+				break;
+
+			switch (cmd) {
+			case TIOCMBIS:
+				set = val;
+				break;
+			case TIOCMBIC:
+				clear = val;
+				break;
+			case TIOCMSET:
+				set = val;
+				clear = ~val;
+				break;
+			}
+
+			set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
+			clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
+
+			ret = uart_tiocmset(tty, filp, set, clear);
+		}
+		break;
+	}
+
+	if (ret != -ENOIOCTLCMD)
+		goto out;
+
+	down(&state->sem);
+
+	if (tty_hung_up_p(filp)) {
+		ret = -EIO;
+		goto out_up;
+	}
+
+	/*
+	 * All these rely on hardware being present and need to be
+	 * protected against the tty being hung up.
+	 */
+	switch (cmd) {
+	case TIOCSERGETLSR: /* Get line status register */
+		ret = uart_get_lsr_info(state, (unsigned int *)arg);
+		break;
+
+	default: {
+		struct uart_port *port = state->port;
+		if (port->ops->ioctl)
+			ret = port->ops->ioctl(port, cmd, arg);
+		break;
+	}
+	}
+ out_up:
+	up(&state->sem);
+ out:
+	return ret;
+}
+
+static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	struct uart_state *state = tty->driver_data;
+	unsigned long flags;
+	unsigned int cflag = tty->termios->c_cflag;
+
+	BUG_ON(!kernel_locked());
+
+	/*
+	 * These are the bits that are used to setup various
+	 * flags in the low level driver.
+	 */
+#define RELEVANT_IFLAG(iflag)	((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+	if ((cflag ^ old_termios->c_cflag) == 0 &&
+	    RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
+		return;
+
+	uart_change_speed(state, old_termios);
+
+	/* Handle transition to B0 status */
+	if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
+		uart_clear_mctrl(state->port, TIOCM_RTS | TIOCM_DTR);
+
+	/* Handle transition away from B0 status */
+	if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
+		unsigned int mask = TIOCM_DTR;
+		if (!(cflag & CRTSCTS) ||
+		    !test_bit(TTY_THROTTLED, &tty->flags))
+			mask |= TIOCM_RTS;
+		uart_set_mctrl(state->port, mask);
+	}
+
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {
+		spin_lock_irqsave(&state->port->lock, flags);
+		tty->hw_stopped = 0;
+		__uart_start(tty);
+		spin_unlock_irqrestore(&state->port->lock, flags);
+	}
+
+#if 0
+	/*
+	 * No need to wake up processes in open wait, since they
+	 * sample the CLOCAL flag once, and don't recheck it.
+	 * XXX  It's not clear whether the current behavior is correct
+	 * or not.  Hence, this may change.....
+	 */
+	if (!(old_termios->c_cflag & CLOCAL) &&
+	    (tty->termios->c_cflag & CLOCAL))
+		wake_up_interruptible(&state->info->open_wait);
+#endif
+}
+
+/*
+ * In 2.4.5, calls to this will be serialized via the BKL in
+ *  linux/drivers/char/tty_io.c:tty_release()
+ *  linux/drivers/char/tty_io.c:do_tty_handup()
+ */
+static void uart_close(struct tty_struct *tty, struct file *filp)
+{
+	struct uart_driver *drv = (struct uart_driver *)tty->driver.driver_state;
+	struct uart_state *state = tty->driver_data;
+	struct uart_port *port;
+
+	BUG_ON(!kernel_locked());
+
+	if (!state || !state->port)
+		return;
+
+	port = state->port;
+
+	DPRINTK("uart_close(%d) called\n", port->line);
+
+	down(&state->sem);
+
+	if (tty_hung_up_p(filp))
+		goto done;
+
+	if ((tty->count == 1) && (state->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  state->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("uart_close: bad serial port count; tty->count is 1, "
+		       "state->count is %d\n", state->count);
+		state->count = 1;
+	}
+	if (--state->count < 0) {
+		printk("rs_close: bad serial port count for %s%d: %d\n",
+		       tty->driver.name, port->line, state->count);
+		state->count = 0;
+	}
+	if (state->count)
+		goto done;
+
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (state->info->flags & UIF_NORMAL_ACTIVE)
+		state->normal_termios = *tty->termios;
+	if (state->info->flags & UIF_CALLOUT_ACTIVE)
+		state->callout_termios = *tty->termios;
+
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify
+	 * the line discipline to only process XON/XOFF characters by
+	 * setting tty->closing.
+	 */
+	tty->closing = 1;
+
+	if (state->closing_wait != USF_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, state->closing_wait);
+
+	/*
+	 * At this point, we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts.
+	 */
+	if (state->info->flags & UIF_INITIALIZED) {
+		unsigned long flags;
+		spin_lock_irqsave(&port->lock, flags);
+		port->ops->stop_rx(port);
+		spin_unlock_irqrestore(&port->lock, flags);
+		/*
+		 * Before we drop DTR, make sure the UART transmitter
+		 * has completely drained; this is especially
+		 * important if there is a transmit FIFO!
+		 */
+		uart_wait_until_sent(tty, port->timeout);
+	}
+
+	uart_shutdown(state);
+	uart_flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	state->info->tty = NULL;
+
+	if (state->info->blocked_open) {
+		if (state->close_delay) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(state->close_delay);
+			set_current_state(TASK_RUNNING);
+		}
+	} else if (!uart_console(port)) {
+		uart_change_pm(state, 3);
+	}
+
+	/*
+	 * Wake up anyone trying to open this port.
+	 */
+	state->info->flags &= ~(UIF_NORMAL_ACTIVE|UIF_CALLOUT_ACTIVE);
+	wake_up_interruptible(&state->info->open_wait);
+
+ done:
+	up(&state->sem);
+	if (drv->owner)
+		__MOD_DEC_USE_COUNT(drv->owner);
+}
+
+static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	struct uart_state *state = tty->driver_data;
+	struct uart_port *port = state->port;
+	unsigned long char_time, expire;
+
+	BUG_ON(!kernel_locked());
+
+	if (port->type == PORT_UNKNOWN || port->fifosize == 0)
+		return;
+
+	/*
+	 * Set the check interval to be 1/5 of the estimated time to
+	 * send a single character, and make it at least 1.  The check
+	 * interval should also be less than the timeout.
+	 *
+	 * Note: we have to use pretty tight timings here to satisfy
+	 * the NIST-PCTS.
+	 */
+	char_time = (port->timeout - HZ/50) / port->fifosize;
+	char_time = char_time / 5;
+	if (char_time == 0)
+		char_time = 1;
+	if (timeout && timeout < char_time)
+		char_time = timeout;
+
+	/*
+	 * If the transmitter hasn't cleared in twice the approximate
+	 * amount of time to send the entire FIFO, it probably won't
+	 * ever clear.  This assumes the UART isn't doing flow
+	 * control, which is currently the case.  Hence, if it ever
+	 * takes longer than port->timeout, this is probably due to a
+	 * UART bug of some kind.  So, we clamp the timeout parameter at
+	 * 2*port->timeout.
+	 */
+	if (timeout == 0 || timeout > 2 * port->timeout)
+		timeout = 2 * port->timeout;
+
+	expire = jiffies + timeout;
+
+	DPRINTK("uart_wait_until_sent(%d), jiffies=%lu, expire=%lu...\n",
+		port->line, jiffies, expire);
+
+	/*
+	 * Check whether the transmitter is empty every 'char_time'.
+	 * 'timeout' / 'expire' give us the maximum amount of time
+	 * we wait.
+	 */
+	while (!port->ops->tx_empty(port)) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(char_time);
+		if (signal_pending(current))
+			break;
+		if (time_after(jiffies, expire))
+			break;
+	}
+	set_current_state(TASK_RUNNING); /* might not be needed */
+}
+
+/*
+ * This is called with the BKL held in
+ *  linux/drivers/char/tty_io.c:do_tty_hangup()
+ * We're called from the eventd thread, so we can sleep for
+ * a _short_ time only.
+ */
+static void uart_hangup(struct tty_struct *tty)
+{
+	struct uart_state *state = tty->driver_data;
+
+	BUG_ON(!kernel_locked());
+	DPRINTK("uart_hangup(%d)\n", state->port->line);
+
+	down(&state->sem);
+	if (state->info && state->info->flags & (UIF_NORMAL_ACTIVE|UIF_CALLOUT_ACTIVE)) {
+		uart_flush_buffer(tty);
+		uart_shutdown(state);
+		state->count = 0;
+		state->info->flags &= ~(UIF_NORMAL_ACTIVE|UIF_CALLOUT_ACTIVE);
+		state->info->tty = NULL;
+		wake_up_interruptible(&state->info->open_wait);
+		wake_up_interruptible(&state->info->delta_msr_wait);
+	}
+	up(&state->sem);
+}
+
+/*
+ * Copy across the serial console cflag setting into the termios settings
+ * for the initial open of the port.  This allows continuity between the
+ * kernel settings, and the settings init adopts when it opens the port
+ * for the first time.
+ */
+static void uart_update_termios(struct uart_state *state)
+{
+	struct tty_struct *tty = state->info->tty;
+	struct uart_port *port = state->port;
+
+	if (uart_console(port) && port->cons->cflag) {
+		tty->termios->c_cflag = port->cons->cflag;
+		port->cons->cflag = 0;
+	}
+
+	/*
+	 * If the device failed to grab its irq resources,
+	 * or some other error occurred, don't try to talk
+	 * to the port hardware.
+	 */
+	if (!(tty->flags & (1 << TTY_IO_ERROR))) {
+		/*
+		 * Make termios settings take effect.
+		 */
+		uart_change_speed(state, NULL);
+
+		/*
+		 * And finally enable the RTS and DTR signals.
+		 */
+		if (tty->termios->c_cflag & CBAUD)
+			uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+	}
+}
+
+/*
+ * Block the open until the port is ready.  We must be called with
+ * the per-port semaphore held.
+ */
+static int
+uart_block_til_ready(struct file *filp, struct uart_state *state)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	struct uart_info *info = state->info;
+	struct uart_port *port = state->port;
+	struct termios *termios;
+
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (info->tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+		if (info->flags & UIF_NORMAL_ACTIVE)
+			return -EBUSY;
+		if ((info->flags & UIF_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
+		    (info->session != current->session))
+			return -EBUSY;
+		if ((info->flags & UIF_CALLOUT_ACTIVE) &&
+		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
+		    (info->pgrp != current->pgrp))
+			return -EBUSY;
+		info->flags |= UIF_CALLOUT_ACTIVE;
+		return 0;
+	}
+
+	if (info->flags & UIF_CALLOUT_ACTIVE) {
+		termios = &state->normal_termios;
+	} else {
+		termios = state->info->tty->termios;
+	}
+
+	info->blocked_open++;
+	state->count--;
+
+	add_wait_queue(&info->open_wait, &wait);
+	while (1) {
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		/*
+		 * If we have been hung up, tell userspace/restart open.
+		 */
+		if (tty_hung_up_p(filp) || info->tty == NULL)
+			break;
+
+		/*
+		 * If the port has been closed, tell userspace/restart open.
+		 */
+		if (!(info->flags & UIF_INITIALIZED))
+			break;
+
+		/*
+		 * If non-blocking mode is set, or CLOCAL mode is set,
+		 * we don't want to wait for the modem status lines to
+		 * indicate that the port is ready.
+		 *
+		 * Also, if the port is not enabled/configured, we want
+		 * to allow the open to succeed here.  Note that we will
+		 * have set TTY_IO_ERROR for a non-existant port.
+		 */
+		if ((filp->f_flags & O_NONBLOCK) ||
+		    (termios->c_cflag & CLOCAL) ||
+		    (info->tty->flags & (1 << TTY_IO_ERROR))) {
+			break;
+		}
+
+		if (!(info->flags & UIF_CALLOUT_ACTIVE)) {
+			/*
+			 * Set DTR to allow modem to know we're waiting.  Do
+			 * not set RTS here - we want to make sure we catch
+			 * the data from the modem.
+			 */
+			if (info->tty->termios->c_cflag & CBAUD)
+				uart_set_mctrl(port, TIOCM_DTR);
+
+			/*
+			 * and wait for the carrier to indicate that the
+			 * modem is ready for us.
+			 */
+			if (port->ops->get_mctrl(port) & TIOCM_CAR)
+	                        break;
+		}
+
+		up(&state->sem);
+		schedule();
+		down(&state->sem);
+
+		if (signal_pending(current))
+			break;
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&info->open_wait, &wait);
+
+	state->count++;
+	info->blocked_open--;
+
+	info->flags |= UIF_NORMAL_ACTIVE;
+
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+
+	if (!info->tty || tty_hung_up_p(filp))
+		return -EAGAIN;
+
+	return 0;
+}
+
+static struct uart_state *uart_get(struct uart_driver *drv, int line)
+{
+	struct uart_state *state;
+
+	down(&port_sem);
+	state = drv->state + line;
+	if (down_interruptible(&state->sem)) {
+		state = ERR_PTR(-ERESTARTSYS);
+		goto out;
+	}
+
+	state->count++;
+	if (!state->port) {
+		state->count--;
+		up(&state->sem);
+		state = ERR_PTR(-ENXIO);
+		goto out;
+	}
+
+	if (!state->info) {
+		state->info = kmalloc(sizeof(struct uart_info), GFP_KERNEL);
+		if (state->info) {
+			memset(state->info, 0, sizeof(struct uart_info));
+			init_waitqueue_head(&state->info->open_wait);
+			init_waitqueue_head(&state->info->delta_msr_wait);
+
+			/*
+			 * Link the info into the other structures.
+			 */
+			state->port->info = state->info;
+
+			tasklet_init(&state->info->tlet, uart_tasklet_action,
+				     (unsigned long)state);
+		} else {
+			state->count--;
+			up(&state->sem);
+			state = ERR_PTR(-ENOMEM);
+		}
+	}
+
+ out:
+	up(&port_sem);
+	return state;
+}
+
+/*
+ * In 2.4.5, calls to uart_open are serialised by the BKL in
+ *   linux/fs/devices.c:chrdev_open()
+ * Note that if this fails, then uart_close() _will_ be called.
+ */
+static int uart_open(struct tty_struct *tty, struct file *filp)
+{
+	struct uart_driver *drv = (struct uart_driver *)tty->driver.driver_state;
+	struct uart_state *state;
+	int retval, line = MINOR(tty->device) - tty->driver.minor_start;
+
+	BUG_ON(!kernel_locked());
+	DPRINTK("uart_open(%d) called\n", line);
+
+	/*
+	 * tty->driver->num won't change, so we won't fail here with
+	 * tty->driver_data set to something non-NULL (and therefore
+	 * we won't get caught by uart_close()).
+	 */
+	retval = -ENODEV;
+	if (line >= tty->driver.num)
+		goto fail;
+
+	if (!try_inc_mod_count(drv->owner))
+		goto fail;
+
+	/*
+	 * We take the semaphore inside uart_get to guarantee that we won't
+	 * be re-entered while allocating the info structure, or while we
+	 * request any IRQs that the driver may need.  This also has the nice
+	 * side-effect that it delays the action of uart_hangup, so we can
+	 * guarantee that info->tty will always contain something reasonable.
+	 */
+	state = uart_get(drv, line);
+	if (IS_ERR(state)) {
+		retval = PTR_ERR(state);
+		if (!tty->driver_data)
+			goto out;
+		else
+			goto fail;
+	}
+
+	/*
+	 * Once we set tty->driver_data here, we are guaranteed that
+	 * uart_close() will decrement the driver module use count.
+	 * Any failures from here onwards should not touch the count.
+	 */
+	tty->driver_data = state;
+	tty->low_latency = (state->port->flags & UPF_LOW_LATENCY) ? 1 : 0;
+	tty->alt_speed = uart_get_altspeed(state->port);
+	state->info->tty = tty;
+
+	/*
+	 * If the port is in the middle of closing, bail out now.
+	 */
+	if (tty_hung_up_p(filp)) {
+		retval = -EAGAIN;
+		state->count--;
+		up(&state->sem);
+		goto fail;
+	}
+
+	/*
+	 * Make sure the device is in D0 state.
+	 */
+	if (state->count == 1)
+		uart_change_pm(state, 0);
+
+	/*
+	 * Start up the serial port.
+	 */
+	retval = uart_startup(state, 0);
+
+	/*
+	 * If we succeeded, wait until the port is ready.
+	 */
+	if (retval == 0)
+		retval = uart_block_til_ready(filp, state);
+
+	/*
+	 * If this is the first open to succeed, adjust things to suit.
+	 */
+	if (retval == 0 && state->count == 1) {
+		if (state->port->flags & UPF_SPLIT_TERMIOS) {
+			if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+				*tty->termios = state->normal_termios;
+			else
+				*tty->termios = state->callout_termios;
+		}
+
+		uart_update_termios(state);
+
+		state->info->session = current->session;
+		state->info->pgrp = current->pgrp;
+	}
+	up(&state->sem);
+
+	return 0;
+
+ out:
+	if (drv->owner)
+		__MOD_DEC_USE_COUNT(drv->owner);
+ fail:
+	return retval;
+}
+
+static const char *uart_type(struct uart_port *port)
+{
+	const char *str = NULL;
+
+	if (port->ops->type)
+		str = port->ops->type(port);
+
+	if (!str)
+		str = "unknown";
+
+	return str;
+}
+
+#ifdef CONFIG_PROC_FS
+
+static int uart_line_info(char *buf, struct uart_driver *drv, int i)
+{
+	struct uart_state *state = drv->state + i;
+	struct uart_port *port = state->port;
+	char stat_buf[32];
+	unsigned int status;
+	int ret;
+
+	if (!port)
+		return 0;
+
+	ret = sprintf(buf, "%d: uart:%s port:%08X irq:%d",
+			port->line, uart_type(port),
+			port->iobase, port->irq);
+
+	if (port->type == PORT_UNKNOWN) {
+		strcat(buf, "\n");
+		return ret + 1;
+	}
+
+	status = port->ops->get_mctrl(port);
+
+	ret += sprintf(buf + ret, " tx:%d rx:%d",
+			port->icount.tx, port->icount.rx);
+	if (port->icount.frame)
+		ret += sprintf(buf + ret, " fe:%d",
+			port->icount.frame);
+	if (port->icount.parity)
+		ret += sprintf(buf + ret, " pe:%d",
+			port->icount.parity);
+	if (port->icount.brk)
+		ret += sprintf(buf + ret, " brk:%d",
+			port->icount.brk);
+	if (port->icount.overrun)
+		ret += sprintf(buf + ret, " oe:%d",
+			port->icount.overrun);
+
+#define INFOBIT(bit,str) \
+	if (port->mctrl & (bit)) \
+		strcat(stat_buf, (str))
+#define STATBIT(bit,str) \
+	if (status & (bit)) \
+		strcat(stat_buf, (str))
+
+	stat_buf[0] = '\0';
+	stat_buf[1] = '\0';
+	INFOBIT(TIOCM_RTS, "|RTS");
+	STATBIT(TIOCM_CTS, "|CTS");
+	INFOBIT(TIOCM_DTR, "|DTR");
+	STATBIT(TIOCM_DSR, "|DSR");
+	STATBIT(TIOCM_CAR, "|CD");
+	STATBIT(TIOCM_RNG, "|RI");
+	if (stat_buf[0])
+		stat_buf[0] = ' ';
+	strcat(stat_buf, "\n");
+
+	ret += sprintf(buf + ret, stat_buf);
+	return ret;
+}
+
+static int uart_read_proc(char *page, char **start, off_t off,
+			  int count, int *eof, void *data)
+{
+	struct tty_driver *ttydrv = data;
+	struct uart_driver *drv = ttydrv->driver_state;
+	int i, len = 0, l;
+	off_t begin = 0;
+
+	len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n",
+			"", "", "");
+	for (i = 0; i < drv->nr && len < PAGE_SIZE - 96; i++) {
+		l = uart_line_info(page + len, drv, i);
+		len += l;
+		if (len + begin > off + count)
+			goto done;
+		if (len + begin < off) {
+			begin += len;
+			len = 0;
+		}
+	}
+	*eof = 1;
+ done:
+	if (off >= len + begin)
+		return 0;
+	*start = page + (off - begin);
+	return (count < begin + len - off) ? count : (begin + len - off);
+}
+#endif
+
+#ifdef CONFIG_SERIAL_CORE_CONSOLE
+/*
+ *	Check whether an invalid uart number has been specified, and
+ *	if so, search for the first available port that does have
+ *	console support.
+ */
+struct uart_port * __init
+uart_get_console(struct uart_port *ports, int nr, struct console *co)
+{
+	int idx = co->index;
+
+	if (idx < 0 || idx >= nr || (ports[idx].iobase == 0 &&
+				     ports[idx].membase == NULL))
+		for (idx = 0; idx < nr; idx++)
+			if (ports[idx].iobase != 0 ||
+			    ports[idx].membase != NULL)
+				break;
+
+	co->index = idx;
+
+	return ports + idx;
+}
+
+/**
+ *	uart_parse_options - Parse serial port baud/parity/bits/flow contro.
+ *	@options: pointer to option string
+ *	@baud: pointer to an 'int' variable for the baud rate.
+ *	@parity: pointer to an 'int' variable for the parity.
+ *	@bits: pointer to an 'int' variable for the number of data bits.
+ *	@flow: pointer to an 'int' variable for the flow control character.
+ *
+ *	uart_parse_options decodes a string containing the serial console
+ *	options.  The format of the string is <baud><parity><bits><flow>,
+ *	eg: 115200n8r
+ */
+void __init
+uart_parse_options(char *options, int *baud, int *parity, int *bits, int *flow)
+{
+	char *s = options;
+
+	*baud = simple_strtoul(s, NULL, 10);
+	while (*s >= '0' && *s <= '9')
+		s++;
+	if (*s)
+		*parity = *s++;
+	if (*s)
+		*bits = *s++ - '0';
+	if (*s)
+		*flow = *s;
+}
+
+struct baud_rates {
+	unsigned int rate;
+	unsigned int cflag;
+};
+
+static struct baud_rates baud_rates[] = {
+	{ 921600, B921600 },
+	{ 460800, B460800 },
+	{ 230400, B230400 },
+	{ 115200, B115200 },
+	{  57600, B57600  },
+	{  38400, B38400  },
+	{  19200, B19200  },
+	{   9600, B9600   },
+	{   4800, B4800   },
+	{   2400, B2400   },
+	{   1200, B1200   },
+	{      0, B38400  }
+};
+
+/**
+ *	uart_set_options - setup the serial console parameters
+ *	@port: pointer to the serial ports uart_port structure
+ *	@co: console pointer
+ *	@baud: baud rate
+ *	@parity: parity character - 'n' (none), 'o' (odd), 'e' (even)
+ *	@bits: number of data bits
+ *	@flow: flow control character - 'r' (rts)
+ */
+int __init
+uart_set_options(struct uart_port *port, struct console *co,
+		 int baud, int parity, int bits, int flow)
+{
+	struct termios termios;
+	unsigned int quot;
+	int i;
+
+	memset(&termios, 0, sizeof(struct termios));
+
+	termios.c_cflag = CREAD | HUPCL | CLOCAL;
+
+	/*
+	 * Construct a cflag setting.
+	 */
+	for (i = 0; baud_rates[i].rate; i++)
+		if (baud_rates[i].rate <= baud)
+			break;
+
+	termios.c_cflag |= baud_rates[i].cflag;
+	baud = baud_rates[i].rate;
+	if (baud == 0)
+		baud = 38400;
+
+	if (bits == 7)
+		termios.c_cflag |= CS7;
+	else
+		termios.c_cflag |= CS8;
+
+	switch (parity) {
+	case 'o': case 'O':
+		termios.c_cflag |= PARODD;
+		/*fall through*/
+	case 'e': case 'E':
+		termios.c_cflag |= PARENB;
+		break;
+	}
+
+	if (flow == 'r')
+		termios.c_cflag |= CRTSCTS;
+
+	quot = (port->uartclk / (16 * baud));
+	port->ops->change_speed(port, termios.c_cflag, 0, quot);
+	co->cflag = termios.c_cflag;
+
+	return 0;
+}
+
+extern void ambauart_console_init(void);
+extern void ep93xxuart_console_init(void);
+extern void anakin_console_init(void);
+extern void clps711xuart_console_init(void);
+extern void sa1100_rs_console_init(void);
+extern void serial8250_console_init(void);
+extern void at91_console_init(void);
+
+/*
+ * Central "initialise all serial consoles" container.  Needs to be killed.
+ */
+void __init uart_console_init(void)
+{
+#ifdef CONFIG_SERIAL_AMBA_CONSOLE
+	ambauart_console_init();
+#endif
+#ifdef CONFIG_SERIAL_EP93XX_CONSOLE
+        ep93xxuart_console_init();
+#endif
+#ifdef CONFIG_SERIAL_ANAKIN_CONSOLE
+	anakin_console_init();
+#endif
+#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE
+	clps711xuart_console_init();
+#endif
+#ifdef CONFIG_SERIAL_SA1100_CONSOLE
+	sa1100_rs_console_init();
+#endif
+#ifdef CONFIG_SERIAL_AT91_CONSOLE
+	at91_console_init();
+#endif
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+	serial8250_console_init();
+#endif
+#ifdef CONFIG_SERIAL_UART00_CONSOLE
+	uart00_console_init();
+#endif
+}
+#endif /* CONFIG_SERIAL_CORE_CONSOLE */
+
+static void uart_change_pm(struct uart_state *state, int pm_state)
+{
+	struct uart_port *port = state->port;
+	if (port->ops->pm)
+		port->ops->pm(port, pm_state, 0);
+}
+
+#ifdef CONFIG_PM
+int uart_suspend_port(struct uart_state *state)
+{
+	struct uart_port *port = state->port;
+
+	down(&state->sem);
+	if (port) {
+		/*
+		 * Disable the console device before suspending.
+		 */
+		if (uart_console(port))
+			port->cons->flags &= ~CON_ENABLED;
+
+		if (state->info && state->info->flags & UIF_INITIALIZED) {
+			struct uart_ops *ops = port->ops;
+
+			spin_lock_irq(&port->lock);
+			ops->stop_tx(port, 0);
+			ops->set_mctrl(port, 0);
+			ops->stop_rx(port);
+			spin_unlock_irq(&port->lock);
+
+			/*
+			 * Wait for the transmitter to empty.
+			 */
+			while (!ops->tx_empty(port)) {
+				set_current_state(TASK_UNINTERRUPTIBLE);
+				schedule_timeout(10*HZ/1000);
+			}
+			set_current_state(TASK_RUNNING);
+
+			ops->shutdown(port);
+		}
+
+		uart_change_pm(state, 3);
+	}
+
+	up(&state->sem);
+
+	return 0;
+}
+
+int uart_resume_port(struct uart_state *state)
+{
+	struct uart_port *port = state->port;
+
+	down(&state->sem);
+	if (port) {
+		uart_change_pm(state, 0);
+
+		/*
+		 * Re-enable the console device after suspending.
+		 */
+		if (uart_console(port)) {
+			uart_change_speed(state, NULL);
+			port->cons->flags |= CON_ENABLED;
+		}
+
+		if (state->info && state->info->flags & UIF_INITIALIZED) {
+			struct uart_ops *ops = port->ops;
+
+			ops->set_mctrl(port, 0);
+			ops->startup(port);
+			uart_change_speed(state, NULL);
+			spin_lock_irq(&port->lock);
+			ops->set_mctrl(port, port->mctrl);
+			ops->start_tx(port, 0);
+			spin_unlock_irq(&port->lock);
+		}
+	}
+
+	up(&state->sem);
+
+	return 0;
+}
+
+/*
+ *  Wakeup support.
+ */
+static int uart_pm_set_wakeup(struct uart_state *state, int data)
+{
+	int err = 0;
+
+	if (state->port->ops->set_wake)
+		err = state->port->ops->set_wake(state->port, data);
+
+	return err;
+}
+
+static int uart_pm(struct pm_dev *dev, pm_request_t rqst, void *data)
+{
+	struct uart_state *state = dev->data;
+	int err = 0;
+
+	if (state->port && state->port->type == PORT_UNKNOWN)
+		return 0;
+
+	switch (rqst) {
+	case PM_SUSPEND:
+		err = uart_suspend_port(state);
+		break;
+
+	case PM_RESUME:
+		err = uart_resume_port(state);
+		break;
+
+	case PM_SET_WAKEUP:
+		err = uart_pm_set_wakeup(state, (int)data);
+		break;
+	}
+	return err;
+}
+#endif
+
+static inline void
+uart_report_port(struct uart_driver *drv, struct uart_port *port)
+{
+	printk("%s%d at ", drv->normal_name, port->line);
+	switch (port->iotype) {
+	case UPIO_PORT:
+		printk("I/O 0x%x", port->iobase);
+		break;
+	case UPIO_HUB6:
+		printk("I/O 0x%x offset 0x%x", port->iobase, port->hub6);
+		break;
+	case UPIO_MEM:
+		printk("MMIO 0x%lx", port->mapbase);
+		break;
+	}
+	printk(" (irq = %d) is a %s\n", port->irq, uart_type(port));
+}
+
+static void
+uart_configure_port(struct uart_driver *drv, struct uart_state *state,
+		    struct uart_port *port)
+{
+	unsigned int flags;
+
+	/*
+	 * If there isn't a port here, don't do anything further.
+	 */
+	if (!port->iobase && !port->mapbase && !port->membase)
+		return;
+
+	/*
+	 * Now do the auto configuration stuff.  Note that config_port
+	 * is expected to claim the resources and map the port for us.
+	 */
+	flags = UART_CONFIG_TYPE;
+	if (port->flags & UPF_AUTO_IRQ)
+		flags |= UART_CONFIG_IRQ;
+	if (port->flags & UPF_BOOT_AUTOCONF) {
+		port->type = PORT_UNKNOWN;
+		port->ops->config_port(port, flags);
+	}
+
+	if (port->type != PORT_UNKNOWN) {
+		unsigned long flags;
+
+		uart_report_port(drv, port);
+
+		/*
+		 * Ensure that the modem control lines are de-activated.
+		 * We probably don't need a spinlock around this, but
+		 */
+		spin_lock_irqsave(&port->lock, flags);
+		port->ops->set_mctrl(port, 0);
+		spin_unlock_irqrestore(&port->lock, flags);
+
+		/*
+		 * Power down all ports by default, except the
+		 * console if we have one.
+		 */
+		if (!uart_console(port))
+			uart_change_pm(state, 3);
+	}
+}
+
+/*
+ * This reverses the effects of uart_configure_port, hanging up the
+ * port before removal.
+ */
+static void
+uart_unconfigure_port(struct uart_driver *drv, struct uart_state *state)
+{
+	struct uart_port *port = state->port;
+	struct uart_info *info = state->info;
+
+	if (info && info->tty)
+		tty_vhangup(info->tty);
+
+	down(&state->sem);
+
+	state->info = NULL;
+
+	/*
+	 * Free the port IO and memory resources, if any.
+	 */
+	if (port->type != PORT_UNKNOWN)
+		port->ops->release_port(port);
+
+	/*
+	 * Indicate that there isn't a port here anymore.
+	 */
+	port->type = PORT_UNKNOWN;
+
+	/*
+	 * Kill the tasklet, and free resources.
+	 */
+	if (info) {
+		tasklet_kill(&info->tlet);
+		kfree(info);
+	}
+
+	up(&state->sem);
+}
+
+/**
+ *	uart_register_driver - register a driver with the uart core layer
+ *	@drv: low level driver structure
+ *
+ *	Register a uart driver with the core driver.  We in turn register
+ *	with the tty layer, and initialise the core driver per-port state.
+ *
+ *	We have a proc file in /proc/tty/driver which is named after the
+ *	normal driver.
+ *
+ *	drv->port should be NULL, and the per-port structures should be
+ *	registered using uart_add_one_port after this call has succeeded.
+ */
+int uart_register_driver(struct uart_driver *drv)
+{
+	struct tty_driver *normal, *callout;
+	int i, retval;
+
+	BUG_ON(drv->state);
+
+	/*
+	 * Maybe we should be using a slab cache for this, especially if
+	 * we have a large number of ports to handle.  Note that we also
+	 * allocate space for an integer for reference counting.
+	 */
+	drv->state = kmalloc(sizeof(struct uart_state) * drv->nr +
+			     sizeof(int), GFP_KERNEL);
+	retval = -ENOMEM;
+	if (!drv->state)
+		goto out;
+
+	memset(drv->state, 0, sizeof(struct uart_state) * drv->nr +
+			sizeof(int));
+
+	normal  = drv->normal_driver;
+	callout = drv->callout_driver;
+
+	normal->magic		= TTY_DRIVER_MAGIC;
+	normal->driver_name	= drv->normal_name;
+	normal->name		= drv->normal_name;
+	normal->major		= drv->normal_major;
+	normal->minor_start	= drv->minor;
+	normal->num		= drv->nr;
+	normal->type		= TTY_DRIVER_TYPE_SERIAL;
+	normal->subtype		= SERIAL_TYPE_NORMAL;
+	normal->init_termios	= tty_std_termios;
+	normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	normal->flags		= TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+	normal->refcount	= (int *)(drv->state + drv->nr);
+	normal->table		= drv->table;
+	normal->termios		= drv->termios;
+	normal->termios_locked	= drv->termios_locked;
+	normal->driver_state    = drv;
+
+	normal->open		= uart_open;
+	normal->close		= uart_close;
+	normal->write		= uart_write;
+	normal->put_char	= uart_put_char;
+	normal->flush_chars	= uart_flush_chars;
+	normal->write_room	= uart_write_room;
+	normal->chars_in_buffer	= uart_chars_in_buffer;
+	normal->flush_buffer	= uart_flush_buffer;
+	normal->ioctl		= uart_ioctl;
+	normal->throttle	= uart_throttle;
+	normal->unthrottle	= uart_unthrottle;
+	normal->send_xchar	= uart_send_xchar;
+	normal->set_termios	= uart_set_termios;
+	normal->stop		= uart_stop;
+	normal->start		= uart_start;
+	normal->hangup		= uart_hangup;
+	normal->break_ctl	= uart_break_ctl;
+	normal->wait_until_sent	= uart_wait_until_sent;
+#ifdef CONFIG_PROC_FS
+	normal->read_proc	= uart_read_proc;
+#endif
+
+	/*
+	 * The callout device is just like the normal device except for
+	 * the major number and the subtype code.
+	 */
+	*callout		= *normal;
+	callout->name		= drv->callout_name;
+	callout->major		= drv->callout_major;
+	callout->subtype	= SERIAL_TYPE_CALLOUT;
+	callout->read_proc	= NULL;
+	callout->proc_entry	= NULL;
+
+	/*
+	 * Initialise the UART state(s).
+	 */
+	for (i = 0; i < drv->nr; i++) {
+		struct uart_state *state = drv->state + i;
+
+		state->callout_termios = callout->init_termios;
+		state->normal_termios  = normal->init_termios;
+		state->close_delay     = 5 * HZ / 10;
+		state->closing_wait    = 30 * HZ;
+
+		init_MUTEX(&state->sem);
+	}
+
+	retval = tty_register_driver(normal);
+	if (retval)
+		goto out;
+
+	retval = tty_register_driver(callout);
+	if (retval)
+		tty_unregister_driver(normal);
+
+ out:
+	if (retval < 0) {
+		kfree(drv->state);
+	}
+	return retval;
+}
+
+/**
+ *	uart_unregister_driver - remove a driver from the uart core layer
+ *	@drv: low level driver structure
+ *
+ *	Remove all references to a driver from the core driver.  The low
+ *	level driver must have removed all its ports via the
+ *	uart_remove_one_port() if it registered them with uart_add_one_port().
+ *	(ie, drv->port == NULL)
+ */
+void uart_unregister_driver(struct uart_driver *drv)
+{
+	tty_unregister_driver(drv->normal_driver);
+	tty_unregister_driver(drv->callout_driver);
+
+	kfree(drv->state);
+	drv->state = NULL;
+}
+
+/**
+ *	uart_add_one_port - attach a driver-defined port structure
+ *	@drv: pointer to the uart low level driver structure for this port
+ *	@port: uart port structure to use for this port.
+ *
+ *	This allows the driver to register its own uart_port structure
+ *	with the core driver.  The main purpose is to allow the low
+ *	level uart drivers to expand uart_port, rather than having yet
+ *	more levels of structures.
+ */
+int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
+{
+	struct uart_state *state;
+	int ret = 0;
+
+	BUG_ON(in_interrupt());
+
+	if (port->line >= drv->nr)
+		return -EINVAL;
+
+	state = drv->state + port->line;
+
+	down(&port_sem);
+	if (state->port) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	state->port = port;
+
+	spin_lock_init(&port->lock);
+	port->cons = drv->cons;
+	port->info = state->info;
+
+	uart_configure_port(drv, state, port);
+
+	/*
+	 * Register the port whether it's detected or not.  This allows
+	 * setserial to be used to alter this ports parameters.
+	 */
+	tty_register_devfs(drv->normal_driver, 0, drv->minor + port->line);
+	tty_register_devfs(drv->callout_driver, 0, drv->minor + port->line);
+
+#ifdef CONFIG_PM
+	port->cons = drv->cons;
+	state->pm = pm_register(PM_SYS_DEV, PM_SYS_COM, uart_pm);
+	if (state->pm)
+		state->pm->data = state;
+#endif
+
+ out:
+	up(&port_sem);
+
+	return ret;
+}
+
+/**
+ *	uart_remove_one_port - detach a driver defined port structure
+ *	@drv: pointer to the uart low level driver structure for this port
+ *	@port: uart port structure for this port
+ *
+ *	This unhooks (and hangs up) the specified port structure from the
+ *	core driver.  No further calls will be made to the low-level code
+ *	for this port.
+ */
+int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
+{
+	struct uart_state *state = drv->state + port->line;
+
+	BUG_ON(in_interrupt());
+
+	if (state->port != port)
+		printk(KERN_ALERT "Removing wrong port: %p != %p\n",
+			state->port, port);
+
+	down(&port_sem);
+
+	pm_unregister(state->pm);
+
+	/*
+	 * Remove the devices from devfs
+	 */
+	tty_unregister_devfs(drv->normal_driver, drv->minor + port->line);
+	tty_unregister_devfs(drv->callout_driver, drv->minor + port->line);
+
+	uart_unconfigure_port(drv, state);
+	state->port = NULL;
+	up(&port_sem);
+
+	return 0;
+}
+
+/*
+ *	Are the two ports equivalent?
+ */
+static int uart_match_port(struct uart_port *port1, struct uart_port *port2)
+{
+	if (port1->iotype != port2->iotype)
+		return 0;
+
+	switch (port1->iotype) {
+	case UPIO_PORT:
+		return (port1->iobase == port2->iobase);
+	case UPIO_HUB6:
+		return (port1->iobase == port2->iobase) &&
+		       (port1->hub6   == port2->hub6);
+	case UPIO_MEM:
+		return (port1->membase == port2->membase);
+	}
+	return 0;
+}
+
+/*
+ *	Try to find an unused uart_state slot for a port.
+ */
+static struct uart_state *
+uart_find_match_or_unused(struct uart_driver *drv, struct uart_port *port)
+{
+	int i;
+
+	/*
+	 * First, find a port entry which matches.  Note: if we do
+	 * find a matching entry, and it has a non-zero use count,
+	 * then we can't register the port.
+	 */
+	for (i = 0; i < drv->nr; i++)
+		if (uart_match_port(drv->state[i].port, port))
+			return &drv->state[i];
+
+	/*
+	 * We didn't find a matching entry, so look for the first
+	 * free entry.  We look for one which hasn't been previously
+	 * used (indicated by zero iobase).
+	 */
+	for (i = 0; i < drv->nr; i++)
+		if (drv->state[i].port->type == PORT_UNKNOWN &&
+		    drv->state[i].port->iobase == 0 &&
+		    drv->state[i].count == 0)
+			return &drv->state[i];
+
+	/*
+	 * That also failed.  Last resort is to find any currently
+	 * entry which doesn't have a real port associated with it.
+	 */
+	for (i = 0; i < drv->nr; i++)
+		if (drv->state[i].port->type == PORT_UNKNOWN &&
+		    drv->state[i].count == 0)
+			return &drv->state[i];
+
+	return NULL;
+}
+
+/**
+ *	uart_register_port: register uart settings with a port
+ *	@drv: pointer to the uart low level driver structure for this port
+ *	@port: uart port structure describing the port
+ *
+ *	Register UART settings with the specified low level driver.  Detect
+ *	the type of the port if UPF_BOOT_AUTOCONF is set, and detect the
+ *	IRQ if UPF_AUTO_IRQ is set.
+ *
+ *	We try to pick the same port for the same IO base address, so that
+ *	when a modem is plugged in, unplugged and plugged back in, it gets
+ *	allocated the same port.
+ *
+ *	Returns negative error, or positive line number.
+ */
+int uart_register_port(struct uart_driver *drv, struct uart_port *port)
+{
+	struct uart_state *state;
+	int ret;
+
+	down(&port_sem);
+
+	state = uart_find_match_or_unused(drv, port);
+
+	if (state) {
+		/*
+		 * Ok, we've found a line that we can use.
+		 *
+		 * If we find a port that matches this one, and it appears
+		 * to be in-use (even if it doesn't have a type) we shouldn't
+		 * alter it underneath itself - the port may be open and
+		 * trying to do useful work.
+		 */
+		if (uart_users(state) != 0) {
+			ret = -EBUSY;
+			goto out;
+		}
+
+		/*
+		 * If the port is already initialised, don't touch it.
+		 */
+		if (state->port->type == PORT_UNKNOWN) {
+			state->port->iobase   = port->iobase;
+			state->port->membase  = port->membase;
+			state->port->irq      = port->irq;
+			state->port->uartclk  = port->uartclk;
+			state->port->fifosize = port->fifosize;
+			state->port->regshift = port->regshift;
+			state->port->iotype   = port->iotype;
+			state->port->flags    = port->flags;
+			state->port->line     = state - drv->state;
+			state->port->mapbase  = port->mapbase;
+
+			uart_configure_port(drv, state, state->port);
+		}
+
+		ret = state->port->line;
+	} else
+		ret = -ENOSPC;
+ out:
+	up(&port_sem);
+	return ret;
+}
+
+/**
+ *	uart_unregister_port - de-allocate a port
+ *	@drv: pointer to the uart low level driver structure for this port
+ *	@line: line index previously returned from uart_register_port()
+ *
+ *	Hang up the specified line associated with the low level driver,
+ *	and mark the port as unused.
+ */
+void uart_unregister_port(struct uart_driver *drv, int line)
+{
+	struct uart_state *state;
+
+	if (line < 0 || line >= drv->nr) {
+		printk(KERN_ERR "Attempt to unregister %s%d\n",
+			drv->normal_name, line);
+		return;
+	}
+
+	state = drv->state + line;
+
+	down(&port_sem);
+	uart_unconfigure_port(drv, state);
+	up(&port_sem);
+}
+
+EXPORT_SYMBOL(uart_write_wakeup);
+EXPORT_SYMBOL(uart_register_driver);
+EXPORT_SYMBOL(uart_unregister_driver);
+EXPORT_SYMBOL(uart_register_port);
+EXPORT_SYMBOL(uart_unregister_port);
+EXPORT_SYMBOL(uart_add_one_port);
+EXPORT_SYMBOL(uart_remove_one_port);
+
+MODULE_DESCRIPTION("Serial driver core");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/drivers/serial/ep93xx_amba.c linux-2.4.29-uc1/drivers/serial/ep93xx_amba.c
--- linux-2.4.29/drivers/serial/ep93xx_amba.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/serial/ep93xx_amba.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,998 @@
+/*
+ *  linux/drivers/serial/cs93xx_amba.c
+ *
+ *  Driver for CS9312 AMBA serial ports
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o,
+ *  Deep Blue Solutions Ltd.
+ *
+ *  Copyright 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *  Copyright (c) 2003 Cirrus Logic, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *  $Id: ep93xx_amba.c,v 1.6 2004/08/13 15:31:28 bkircher Exp $
+ *
+ * The EP9312 serial ports are AMBA, but at different addresses from the
+ * integrator.
+ * This is a generic driver for ARM AMBA-type serial ports.  They
+ * have a lot of 16550-like features, but are not register compatable.
+ * Note that although they do have CTS, DCD and DSR inputs, they do
+ * not have an RI input, nor do they have DTR or RTS outputs.  If
+ * required, these have to be supplied via some other means (eg, GPIO)
+ * and hooked into this driver.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#if defined(CONFIG_SERIAL_EP93XX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+
+#include <asm/hardware/serial_amba.h>
+
+#if defined(CONFIG_ARCH_EP9301) || defined(CONFIG_ARCH_EP9302)
+#ifdef CONFIG_EP93XX_IRDA
+#define UART_NR		1
+#else
+#define UART_NR		2
+#endif
+#else
+#ifdef CONFIG_EP93XX_IRDA
+#define UART_NR		2
+#else
+#define UART_NR		3
+#endif
+#endif
+
+#define SERIAL_AMBA_MAJOR	204
+#define SERIAL_AMBA_MINOR	16
+#define SERIAL_AMBA_NR		UART_NR
+
+#define CALLOUT_AMBA_NAME	"cuaam"
+#define CALLOUT_AMBA_MAJOR	205
+#define CALLOUT_AMBA_MINOR	16
+#define CALLOUT_AMBA_NR		UART_NR
+
+static struct tty_driver normal, callout;
+static struct tty_struct *cs_amba_table[UART_NR];
+static struct termios *cs_amba_termios[UART_NR], *cs_amba_termios_locked[UART_NR];
+#ifdef SUPPORT_SYSRQ
+static struct console cs_amba_console;
+#endif
+
+#define AMBA_ISR_PASS_LIMIT	256
+
+/*
+ * Access macros for the AMBA UARTs
+ */
+#define UART_GET_INT_STATUS(p)	((readl((p)->membase + AMBA_UARTIIR)) & 0xff)
+#define UART_PUT_ICR(p, c)		writel((c), (p)->membase + AMBA_UARTICR)
+#define UART_GET_FR(p)			((readl((p)->membase + AMBA_UARTFR)) & 0xff)
+#define UART_GET_CHAR(p)		((readl((p)->membase + AMBA_UARTDR)) & 0xff)
+#define UART_PUT_CHAR(p, c)		writel((c), (p)->membase + AMBA_UARTDR)
+#define UART_GET_RSR(p)			((readl((p)->membase + AMBA_UARTRSR)) & 0xff)
+#define UART_PUT_RSR(p, c)		writel((c), (p)->membase + AMBA_UARTRSR)
+#define UART_GET_CR(p)			((readl((p)->membase + AMBA_UARTCR)) & 0xff)
+#define UART_PUT_CR(p,c)		writel((c), (p)->membase + AMBA_UARTCR)
+#define UART_GET_LCRL(p)		((readl((p)->membase + AMBA_UARTLCR_L)) & 0xff)
+#define UART_PUT_LCRL(p,c)		writel((c), (p)->membase + AMBA_UARTLCR_L)
+#define UART_GET_LCRM(p)		((readl((p)->membase + AMBA_UARTLCR_M)) & 0xff)
+#define UART_PUT_LCRM(p,c)		writel((c), (p)->membase + AMBA_UARTLCR_M)
+#define UART_GET_LCRH(p)		((readl((p)->membase + AMBA_UARTLCR_H)) & 0xff)
+#define UART_PUT_LCRH(p,c)		writel((c), (p)->membase + AMBA_UARTLCR_H)
+#define UART_RX_DATA(s)			(((s) & AMBA_UARTFR_RXFE) == 0)
+#define UART_TX_READY(s)		(((s) & AMBA_UARTFR_TXFF) == 0)
+#define UART_TX_EMPTY(p)		((UART_GET_FR(p) & AMBA_UARTFR_TMSK) == 0)
+
+#define UART_PUT_MCR(c, p)  writel((c), (p)->membase + ((unsigned int)UART1MCR & 0xffff))
+#define UART_CLEAR_ECR(p)   writel( 0, (p)->membase + AMBA_UARTECR)
+
+#define UART_DUMMY_RSR_RX	256
+#define UART_PORT_SIZE		64
+
+/*
+ * Our private driver data mappings.
+ */
+#define drv_old_status	driver_priv
+
+/*
+ * We wrap our port structure around the generic uart_port.
+ */
+struct uart_amba_port {
+	struct uart_port	port;
+	unsigned int		dtr_mask;
+	unsigned int		rts_mask;
+	unsigned int		old_status;
+};
+
+
+static void csambauart_enable_clocks(struct uart_port *port)
+{
+	unsigned int uiSysDevCfg;
+
+	/*
+	 * Enable the clocks to this UART in CSC_syscon
+	 * - Read DEVCFG
+	 * - OR in the correct uart enable bit
+	 * - Set the lock register
+	 * - Write back to DEVCFG
+	 */
+	uiSysDevCfg = inl(SYSCON_DEVCFG);
+
+	switch( port->mapbase )
+	{
+		case UART1_BASE:
+		    uiSysDevCfg |= SYSCON_DEVCFG_U1EN;
+			break;
+
+		case UART2_BASE:
+		    uiSysDevCfg |= SYSCON_DEVCFG_U2EN;
+			break;
+
+		case UART3_BASE:
+		    uiSysDevCfg |= SYSCON_DEVCFG_U3EN;
+			break;
+	}
+
+	SysconSetLocked( SYSCON_DEVCFG, uiSysDevCfg );
+}
+
+static void csambauart_disable_clocks(struct uart_port *port)
+{
+	unsigned int uiSysDevCfg;
+
+	/*
+	 * Disable the clocks to this UART in CSC_syscon
+	 * - Read DEVCFG
+	 * - AND to clear the correct uart enable bit
+	 * - Set the lock register
+	 * - Write back to DEVCFG
+	 */
+	uiSysDevCfg = inl(SYSCON_DEVCFG);
+
+	switch( port->mapbase ) {
+	case UART1_BASE:
+		uiSysDevCfg &= ~((unsigned int)SYSCON_DEVCFG_U1EN);
+		break;
+
+	case UART2_BASE:
+		uiSysDevCfg &= ~((unsigned int)SYSCON_DEVCFG_U2EN);
+		break;
+
+	case UART3_BASE:
+		uiSysDevCfg &= ~((unsigned int)SYSCON_DEVCFG_U3EN);
+		break;
+	}
+
+	SysconSetLocked( SYSCON_DEVCFG, uiSysDevCfg );
+}
+
+static int csambauart_is_port_enabled(struct uart_port *port)
+{
+	unsigned int uiSysDevCfg;
+
+	uiSysDevCfg = inl(SYSCON_DEVCFG);
+
+	switch( port->mapbase ) {
+	case UART1_BASE:
+		uiSysDevCfg &= (unsigned int)SYSCON_DEVCFG_U1EN;
+		break;
+
+	case UART2_BASE:
+		uiSysDevCfg &= (unsigned int)SYSCON_DEVCFG_U2EN;
+		break;
+
+	case UART3_BASE:
+		uiSysDevCfg &= (unsigned int)SYSCON_DEVCFG_U3EN;
+		break;
+	}
+
+	return( uiSysDevCfg != 0 );
+}
+
+
+
+static void csambauart_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	unsigned int cr;
+
+	cr = UART_GET_CR(port);
+	cr &= ~AMBA_UARTCR_TIE;
+	UART_PUT_CR(port, cr);
+}
+
+static void csambauart_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	unsigned int cr;
+
+	cr = UART_GET_CR(port);
+	cr |= AMBA_UARTCR_TIE;
+	UART_PUT_CR(port, cr);
+}
+
+static void csambauart_stop_rx(struct uart_port *port)
+{
+	unsigned int cr;
+
+	cr = UART_GET_CR(port);
+	cr &= ~(AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE);
+	UART_PUT_CR(port, cr);
+}
+
+static void csambauart_enable_ms(struct uart_port *port)
+{
+	unsigned int cr;
+
+	cr = UART_GET_CR(port);
+	cr |= AMBA_UARTCR_MSIE;
+	UART_PUT_CR(port, cr);
+}
+
+static void
+#ifdef SUPPORT_SYSRQ
+csambauart_rx_chars(struct uart_port *port, struct pt_regs *regs)
+#else
+csambauart_rx_chars(struct uart_port *port)
+#endif
+{
+	struct tty_struct *tty = port->info->tty;
+	unsigned int status, ch, rsr, max_count = 256;
+
+	status = UART_GET_FR(port);
+	while (UART_RX_DATA(status) && max_count--) {
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			tty->flip.tqueue.routine((void *)tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+				printk(KERN_WARNING "TTY_DONT_FLIP set\n");
+				return;
+			}
+		}
+
+		ch = UART_GET_CHAR(port);
+
+		*tty->flip.char_buf_ptr = ch;
+		*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		port->icount.rx++;
+
+		/*
+		 * Note that the error handling code is
+		 * out of the main execution path
+		 */
+		rsr = UART_GET_RSR(port) | UART_DUMMY_RSR_RX;
+		UART_PUT_RSR(port, 0);
+		if (rsr & AMBA_UARTRSR_ANY) {
+			UART_PUT_RSR(port, 0xff); /* clear error */
+			if (rsr & AMBA_UARTRSR_BE) {
+				rsr &= ~(AMBA_UARTRSR_FE | AMBA_UARTRSR_PE);
+				port->icount.brk++;
+				if (uart_handle_break(port))
+					goto ignore_char;
+			} else if (rsr & AMBA_UARTRSR_PE)
+				port->icount.parity++;
+			else if (rsr & AMBA_UARTRSR_FE)
+				port->icount.frame++;
+			if (rsr & AMBA_UARTRSR_OE)
+				port->icount.overrun++;
+
+			rsr &= port->read_status_mask;
+
+			/* According to the EP9315 Users Guide, to clear 
+			 * any overrun, break, parity or framing error, you 
+			 * have to write to the UART RSR register. */
+			if (rsr & AMBA_UARTRSR_BE){
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			}
+			else if (rsr & AMBA_UARTRSR_PE){
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			}
+			else if (rsr & AMBA_UARTRSR_FE){
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+			}
+		}
+
+		if (uart_handle_sysrq_char(port, ch, regs))
+			goto ignore_char;
+
+		if ((rsr & port->ignore_status_mask) == 0) {
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+		if ((rsr & AMBA_UARTRSR_OE) &&
+		    tty->flip.count < TTY_FLIPBUF_SIZE) {
+			/*
+			 * Overrun is special, since it's reported
+			 * immediately, and doesn't affect the current
+			 * character
+			 */
+			*tty->flip.char_buf_ptr++ = 0;
+			*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+			tty->flip.count++;
+		}
+	ignore_char:
+		status = UART_GET_FR(port);
+	}
+	tty_flip_buffer_push(tty);
+	return;
+}
+
+static void csambauart_tx_chars(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->info->xmit;
+	int count;
+
+	if (port->x_char) {
+		UART_PUT_CHAR(port, port->x_char);
+		port->icount.tx++;
+		port->x_char = 0;
+		return;
+	}
+	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+		csambauart_stop_tx(port, 0);
+		return;
+	}
+
+	count = port->fifosize >> 1;
+	do {
+		UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	} while (--count > 0);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+
+	if (uart_circ_empty(xmit))
+		csambauart_stop_tx(port, 0);
+}
+
+static void csambauart_modem_status(struct uart_port *port)
+{
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
+	unsigned int status, delta;
+
+	UART_PUT_ICR(&uap->port, 0);
+
+	status = UART_GET_FR(&uap->port) & AMBA_UARTFR_MODEM_ANY;
+
+	delta = status ^ uap->old_status;
+	uap->old_status = status;
+
+	if (!delta)
+		return;
+
+	if (delta & AMBA_UARTFR_DCD)
+		uart_handle_dcd_change(&uap->port, status & AMBA_UARTFR_DCD);
+
+	if (delta & AMBA_UARTFR_DSR)
+		uap->port.icount.dsr++;
+
+	if (delta & AMBA_UARTFR_CTS)
+		uart_handle_cts_change(&uap->port, status & AMBA_UARTFR_CTS);
+
+	wake_up_interruptible(&uap->port.info->delta_msr_wait);
+}
+
+static void csambauart_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_port *port = dev_id;
+	unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
+
+	status = UART_GET_INT_STATUS(port);
+	do {
+		if (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS))
+#ifdef SUPPORT_SYSRQ
+			csambauart_rx_chars(port, regs);
+#else
+			csambauart_rx_chars(port);
+#endif
+		if (status & AMBA_UARTIIR_TIS)
+			csambauart_tx_chars(port);
+		if (status & AMBA_UARTIIR_MIS)
+			csambauart_modem_status(port);
+
+		if (pass_counter-- == 0)
+			break;
+
+		status = UART_GET_INT_STATUS(port);
+	} while (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS |
+			   AMBA_UARTIIR_TIS));
+}
+
+static unsigned int csambauart_tx_empty(struct uart_port *port)
+{
+	return UART_GET_FR(port) & AMBA_UARTFR_BUSY ? 0 : TIOCSER_TEMT;
+}
+
+static unsigned int csambauart_get_mctrl(struct uart_port *port)
+{
+	unsigned int result = 0;
+	unsigned int status;
+
+	status = UART_GET_FR(port);
+	if (status & AMBA_UARTFR_DCD)
+		result |= TIOCM_CAR;
+	if (status & AMBA_UARTFR_DSR)
+		result |= TIOCM_DSR;
+	if (status & AMBA_UARTFR_CTS)
+		result |= TIOCM_CTS;
+
+	return result;
+}
+
+static void csambauart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
+	unsigned int ctrl = 0;
+	
+	/* If there's no RTS and DTR for this UART, do nothing here */
+	if ((uap->rts_mask == 0) && (uap->dtr_mask == 0) )
+		return;
+
+	if (mctrl & TIOCM_RTS)
+		ctrl |= uap->rts_mask;
+
+	if (mctrl & TIOCM_DTR)
+		ctrl |= uap->dtr_mask;
+
+	UART_PUT_MCR(ctrl, port);
+}
+
+static void csambauart_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned long flags;
+	unsigned int lcr_h;
+
+	spin_lock_irqsave(&port->lock, flags);
+	lcr_h = UART_GET_LCRH(port);
+	if (break_state == -1)
+		lcr_h |= AMBA_UARTLCR_H_BRK;
+	else
+		lcr_h &= ~AMBA_UARTLCR_H_BRK;
+	UART_PUT_LCRH(port, lcr_h);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int csambauart_startup(struct uart_port *port)
+{
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
+	int retval = -EINVAL;
+
+	csambauart_enable_clocks(port);
+
+	/*
+	 * Allocate the IRQ
+	 */
+	switch (port->mapbase) {
+	case UART1_BASE:
+		retval = request_irq(port->irq, csambauart_int, 0, "uart1",
+				     port);
+		break;
+	case UART2_BASE:
+		retval = request_irq(port->irq, csambauart_int, 0, "uart2",
+				     port);
+		break;
+	case UART3_BASE:
+		retval = request_irq(port->irq, csambauart_int, 0, "uart3",
+				     port);
+		break;
+	}
+	if (retval)
+		return retval;
+
+	/*
+	 * initialise the old status of the modem signals
+	 */
+	uap->old_status = UART_GET_FR(port) & AMBA_UARTFR_MODEM_ANY;
+
+	/*
+	 * Finally, enable interrupts
+	 */
+	UART_PUT_CR(port, AMBA_UARTCR_UARTEN | AMBA_UARTCR_RIE |
+			  AMBA_UARTCR_RTIE);
+
+	return 0;
+}
+
+static void csambauart_shutdown(struct uart_port *port)
+{
+	/*
+	 * Free the interrupt
+	 */
+	free_irq(port->irq, port);
+
+	/*
+	 * disable all interrupts, disable the port
+	 */
+	UART_PUT_CR(port, 0);
+
+	/* disable break condition and fifos */
+	UART_PUT_LCRH(port, UART_GET_LCRH(port) &
+		~(AMBA_UARTLCR_H_BRK | AMBA_UARTLCR_H_FEN));
+
+	if (!(port->cons && port->cons->index == port->line))
+		csambauart_disable_clocks( port );
+}
+static void csambauart_change_speed(struct uart_port *port, unsigned int cflag, unsigned int iflag, unsigned int quot)
+{
+	unsigned int lcr_h, old_cr;
+	unsigned long flags;
+
+	/*
+	 * Before we change speed, check to see if this UART is currently in use.
+	 * If it is, wait for the fifo to empty out before changing speed.
+	 */
+	if( csambauart_is_port_enabled( port ) )
+	{
+		do{
+			flags = UART_GET_FR(port);
+		} while( flags & UARTFR_BUSY );
+	}
+	else
+	{
+		csambauart_enable_clocks( port );
+	}
+
+#if DEBUG
+	printk("ambauart_set_cflag(0x%x) called\n", cflag);
+#endif
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	case CS5:
+		lcr_h = AMBA_UARTLCR_H_WLEN_5;
+		break;
+	case CS6:
+		lcr_h = AMBA_UARTLCR_H_WLEN_6;
+		break;
+	case CS7:
+		lcr_h = AMBA_UARTLCR_H_WLEN_7;
+		break;
+	default: // CS8
+		lcr_h = AMBA_UARTLCR_H_WLEN_8;
+		break;
+	}
+	if (cflag & CSTOPB)
+		lcr_h |= AMBA_UARTLCR_H_STP2;
+	if (cflag & PARENB) {
+		lcr_h |= AMBA_UARTLCR_H_PEN;
+		if (!(cflag & PARODD))
+			lcr_h |= AMBA_UARTLCR_H_EPS;
+	}
+	if (port->fifosize > 1)
+		lcr_h |= AMBA_UARTLCR_H_FEN;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	port->read_status_mask = AMBA_UARTRSR_OE;
+	if (iflag & INPCK)
+		port->read_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;
+	if (iflag & (BRKINT | PARMRK))
+		port->read_status_mask |= AMBA_UARTRSR_BE;
+
+	/*
+	 * Characters to ignore
+	 */
+	port->ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		port->ignore_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;
+	if (iflag & IGNBRK) {
+		port->ignore_status_mask |= AMBA_UARTRSR_BE;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			port->ignore_status_mask |= AMBA_UARTRSR_OE;
+	}
+
+	/*
+	 * Ignore all characters if CREAD is not set.
+	 */
+	if ((cflag & CREAD) == 0)
+		port->ignore_status_mask |= UART_DUMMY_RSR_RX;
+
+	old_cr = UART_GET_CR(port) & ~AMBA_UARTCR_MSIE;
+
+	if (UART_ENABLE_MS(port, cflag))
+		old_cr |= AMBA_UARTCR_MSIE;
+
+	UART_PUT_CR(port, 0);
+
+	UART_PUT_LCRM(port, 0 );
+	UART_PUT_LCRL(port, 0 );
+	UART_PUT_LCRH(port, 0 );
+
+	UART_CLEAR_ECR(port);
+
+
+	/* Set baud rate */
+	quot -= 1;
+	UART_PUT_LCRM(port, ((quot & 0xf00) >> 8));
+	UART_PUT_LCRL(port, (quot & 0xff));
+
+	/*
+	 * ----------v----------v----------v----------v-----
+	 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
+	 * ----------^----------^----------^----------^-----
+	 */
+	UART_PUT_LCRH(port, lcr_h);
+	UART_PUT_CR(port, old_cr);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *csambauart_type(struct uart_port *port)
+{
+	return port->type == PORT_AMBA ? "AMBA" : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'
+ */
+static void csambauart_release_port(struct uart_port *port)
+{
+	release_mem_region(port->mapbase, UART_PORT_SIZE);
+}
+
+/*
+ * Request the memory region(s) being used by 'port'
+ */
+static int csambauart_request_port(struct uart_port *port)
+{
+	char *name = 0;
+
+	switch(port->mapbase)
+	{
+		case UART1_BASE:
+			name = "uart1";
+			break;
+		case UART2_BASE:
+			name = "uart2";
+			break;
+		case UART3_BASE:
+			name = "uart3";
+			break;
+	}
+	return request_mem_region(port->mapbase, UART_PORT_SIZE,
+				  name) != NULL ? 0 : -EBUSY;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void csambauart_config_port(struct uart_port *port, int flags)
+{
+	if (flags & UART_CONFIG_TYPE) {
+		port->type = PORT_AMBA;
+		csambauart_request_port(port);
+	}
+}
+
+/*
+ * verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int csambauart_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	int ret = 0;
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)
+		ret = -EINVAL;
+	if (ser->irq < 0 || ser->irq >= NR_IRQS)
+		ret = -EINVAL;
+	if (ser->baud_base < 9600)
+		ret = -EINVAL;
+	return ret;
+}
+
+static struct uart_ops amba_pops = {
+	.tx_empty	= csambauart_tx_empty,
+	.set_mctrl	= csambauart_set_mctrl,
+	.get_mctrl	= csambauart_get_mctrl,
+	.stop_tx	= csambauart_stop_tx,
+	.start_tx	= csambauart_start_tx,
+	.stop_rx	= csambauart_stop_rx,
+	.enable_ms	= csambauart_enable_ms,
+	.break_ctl	= csambauart_break_ctl,
+	.startup	= csambauart_startup,
+	.shutdown	= csambauart_shutdown,
+	.change_speed	= csambauart_change_speed,
+	.type		= csambauart_type,
+	.release_port	= csambauart_release_port,
+	.request_port	= csambauart_request_port,
+	.config_port	= csambauart_config_port,
+	.verify_port	= csambauart_verify_port,
+};
+
+static struct uart_amba_port amba_ports[UART_NR] = {
+	{
+		.port	= {
+			.membase	= (void *)UART1_BASE,
+			.mapbase	= UART1_BASE,
+			.iotype		= SERIAL_IO_MEM,
+			.irq		= IRQ_UART1,
+			.uartclk	= 14745600,
+			.fifosize	= 8,
+			.ops		= &amba_pops,
+			.flags		= ASYNC_BOOT_AUTOCONF,
+			.line		= 0,
+		},
+		.dtr_mask	= 1 << 0,
+		.rts_mask	= 1 << 1,
+	},
+#if !defined(CONFIG_EP93XX_IRDA)
+	{
+		.port	= {
+			.membase	= (void *)UART2_BASE,
+			.mapbase	= UART2_BASE,
+			.iotype		= SERIAL_IO_MEM,
+			.irq		= IRQ_UART2,
+			.uartclk	= 14745600,
+			.fifosize	= 8,
+			.ops		= &amba_pops,
+			.flags		= ASYNC_BOOT_AUTOCONF,
+			.line		= 1,
+		},
+		.dtr_mask	= 0,
+		.rts_mask	= 0,
+	},
+#endif
+#if !defined(CONFIG_ARCH_EP9301) && !defined(CONFIG_ARCH_EP9302)
+	{
+		.port	= {
+			.membase	= (void *)UART3_BASE,
+			.mapbase	= UART3_BASE,
+			.iotype		= SERIAL_IO_MEM,
+			.irq		= IRQ_UART3,
+			.uartclk	= 14745600,
+			.fifosize	= 8,
+			.ops		= &amba_pops,
+			.flags		= ASYNC_BOOT_AUTOCONF,
+#if !defined(CONFIG_EP93XX_IRDA)
+			.line		= 2,
+#else
+			.line		= 1,
+#endif
+		},
+		.dtr_mask	= 0,
+		.rts_mask	= 0,
+	}
+#endif
+};
+
+#ifdef CONFIG_SERIAL_EP93XX_CONSOLE
+
+static void csambauart_console_write(struct console *co, const char *s, unsigned int count)
+{
+	struct uart_port *port = &amba_ports[co->index].port;
+	unsigned int status, old_cr;
+	int i;
+
+	/*
+	 * First save the CR then disable the interrupts
+	 */
+	old_cr = UART_GET_CR(port);
+	UART_PUT_CR(port, AMBA_UARTCR_UARTEN);
+
+	/*
+	 * Now, do each character
+	 */
+	for (i = 0; i < count; i++) {
+		do {
+			status = UART_GET_FR(port);
+		} while (!UART_TX_READY(status));
+		UART_PUT_CHAR(port, s[i]);
+		if (s[i] == '\n') {
+			do {
+				status = UART_GET_FR(port);
+			} while (!UART_TX_READY(status));
+			UART_PUT_CHAR(port, '\r');
+		}
+	}
+
+	/*
+	 * Finally, wait for transmitter to become empty
+	 * and restore the TCR
+	 */
+	do {
+		status = UART_GET_FR(port);
+	} while (status & AMBA_UARTFR_BUSY);
+	UART_PUT_CR(port, old_cr);
+}
+
+static kdev_t csambauart_console_device(struct console *co)
+{
+	return MKDEV(SERIAL_AMBA_MAJOR, SERIAL_AMBA_MINOR + co->index);
+}
+
+/*
+ * csambauart_console_get_options
+ *
+ * Read the current settings of the serial port so that we can call
+ * uart_set_options to set the serial port to be the way it already is.
+ * Make sense?
+ */
+#if 0
+static void __init
+csambauart_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
+{
+	if (UART_GET_CR(port) & AMBA_UARTCR_UARTEN) {
+		unsigned int lcr_h, quot;
+		lcr_h = UART_GET_LCRH(port);
+
+		*parity = 'n';
+		if (lcr_h & AMBA_UARTLCR_H_PEN) {
+			if (lcr_h & AMBA_UARTLCR_H_EPS)
+				*parity = 'e';
+			else
+				*parity = 'o';
+		}
+
+		if ((lcr_h & 0x60) == AMBA_UARTLCR_H_WLEN_7)
+			*bits = 7;
+		else
+			*bits = 8;
+
+		quot = UART_GET_LCRL(port) | UART_GET_LCRM(port) << 8;
+		*baud = port->uartclk / (16 * (quot + 1));
+	}
+}
+#endif
+
+static int __init csambauart_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = 57600;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (co->index >= UART_NR)
+		co->index = 0;
+	port = &amba_ports[co->index].port;
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	/*
+	 * By #if 0-ing this out, we get to set the console baud rate
+	 * right here in csambauart_console_setup.
+	 */
+#if 0
+	else
+		csambauart_console_get_options(port, &baud, &parity, &bits);
+#endif
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+/*
+ * The 'index' element of this field selects which UART to use for
+ * console.  For ep93xx, valid values are 0, 1, and 2.  If you set
+ * it to -1, then uart_get_console will search for the first UART
+ * which is the same as setting it to 0.
+ */
+static struct console cs_amba_console = {
+	.name		= "ttyAM",
+	.write		= csambauart_console_write,
+	.device		= csambauart_console_device,
+	.setup		= csambauart_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+};
+
+void __init ep93xxuart_console_init(void)
+{
+	register_console(&cs_amba_console);
+}
+
+#define AMBA_CONSOLE	&cs_amba_console
+#else
+#define AMBA_CONSOLE	NULL
+#endif
+
+static struct uart_driver amba_reg = {
+	.owner			= THIS_MODULE,
+	.normal_major		= SERIAL_AMBA_MAJOR,
+#ifdef CONFIG_DEVFS_FS
+	.normal_name		= "ttyAM%d",
+	.callout_name		= "cuaam%d",
+#else
+	.normal_name		= "ttyAM",
+	.callout_name		= "cuaam",
+#endif
+	.normal_driver		= &normal,
+	.callout_major		= CALLOUT_AMBA_MAJOR,
+	.callout_driver		= &callout,
+	.table			= cs_amba_table,
+	.termios		= cs_amba_termios,
+	.termios_locked		= cs_amba_termios_locked,
+	.minor			= SERIAL_AMBA_MINOR,
+	.nr			= UART_NR,
+	.cons			= AMBA_CONSOLE,
+};
+
+static int __init csambauart_init(void)
+{
+	int ret;
+
+	ret = uart_register_driver(&amba_reg);
+	if (ret == 0) {
+		int i;
+
+		for (i = 0; i < UART_NR; i++)
+			uart_add_one_port(&amba_reg, &amba_ports[i].port);
+	}
+	return ret;
+}
+
+static void __exit csambauart_exit(void)
+{
+	int i;
+
+	for (i = 0; i < UART_NR; i++)
+		uart_remove_one_port(&amba_reg, &amba_ports[i].port);
+
+	uart_unregister_driver(&amba_reg);
+}
+
+module_init(csambauart_init);
+module_exit(csambauart_exit);
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd/Cirrus Logic, Inc.");
+MODULE_DESCRIPTION("EP9312 ARM AMBA serial port driver");
+MODULE_LICENSE("GPL");
+
+
+void myputchar(char c)
+{
+	unsigned int status;
+#ifdef CONFIG_MACH_IPD
+	static unsigned int membase = UART2_BASE;
+#else
+	static unsigned int membase = UART1_BASE;
+#endif
+
+	do {
+		status = readl(membase+AMBA_UARTFR) & 0xff;
+	} while (!UART_TX_READY(status));
+
+	writel(c, membase+AMBA_UARTDR);
+
+	do {
+		status = readl(membase+AMBA_UARTFR) & 0xff;
+	} while (status & AMBA_UARTFR_BUSY);
+}
diff -urN linux-2.4.29/drivers/serial/Makefile linux-2.4.29-uc1/drivers/serial/Makefile
--- linux-2.4.29/drivers/serial/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/serial/Makefile	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,40 @@
+#
+# Makefile for the kernel serial device drivers.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now inherited from the
+# parent makes..
+#
+#  $Id: Makefile,v 1.2 2001/10/12 15:46:58 rmk Exp $
+#
+
+O_TARGET := serial.o
+
+export-objs	:= core.o 8250.o
+obj-y		:=
+obj-m		:=
+obj-n		:=
+obj-		:=
+
+serial-8250-y :=
+serial-8250-$(CONFIG_PCI) += 8250_pci.o
+serial-8250-$(CONFIG_ISAPNP) += 8250_pnp.o
+obj-$(CONFIG_SERIAL_CORE) += core.o
+obj-$(CONFIG_SERIAL_21285) += 21285.o
+obj-$(CONFIG_SERIAL_8250) += 8250.o $(serial-8250-y)
+obj-$(CONFIG_SERIAL_ANAKIN) += anakin.o
+obj-$(CONFIG_SERIAL_AMBA) += amba.o
+obj-$(CONFIG_SERIAL_EP93XX) += ep93xx_amba.o
+obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
+obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
+obj-$(CONFIG_SERIAL_UART00) += uart00.o
+obj-$(CONFIG_SERIAL_OMAHA) += omaha.o
+obj-$(CONFIG_SERIAL_AT91US3) += at91us3.o
+
+include $(TOPDIR)/Rules.make
+
+fastdep:
+
diff -urN linux-2.4.29/drivers/serial/omaha.c linux-2.4.29-uc1/drivers/serial/omaha.c
--- linux-2.4.29/drivers/serial/omaha.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/serial/omaha.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,584 @@
+/*
+ *  linux/drivers/char/omaha.c
+ *
+ *  Driver for Omaha serial port
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright 1999-2002 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *  $Id: serial_amba.c,v 1.4 2001/07/17 20:34:27 rmk Exp $
+ *
+ * This is a generic driver for ARM AMBA-type serial ports.  They
+ * have a lot of 16550-like features, but are not register compatable.
+ * Note that although they do have CTS, DCD and DSR inputs, they do
+ * not have an RI input, nor do they have DTR or RTS outputs.  If
+ * required, these have to be supplied via some other means (eg, GPIO)
+ * and hooked into this driver.
+ */
+  
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+
+#if defined(CONFIG_SERIAL_OMAHA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+
+#include <asm/hardware/serial_omaha.h>
+
+#define UART_NR		1
+
+#define SERIAL_OMAHA_MAJOR	204
+#define SERIAL_OMAHA_MINOR	32
+#define SERIAL_OMAHA_NR		UART_NR
+
+#define CALLOUT_OMAHA_NAME	"cuaom"
+#define CALLOUT_OMAHA_MAJOR	205
+#define CALLOUT_OMAHA_MINOR	32
+#define CALLOUT_OMAHA_NR	UART_NR
+
+static struct tty_driver normal, callout;
+static struct tty_struct *omaha_table[UART_NR];
+static struct termios *omaha_termios[UART_NR], *omaha_termios_locked[UART_NR];
+#ifdef SUPPORT_SYSRQ
+static struct console omaha_console;
+#endif
+
+#define OMAHA_ISR_PASS_LIMIT	256
+
+/*
+ * Access macros for the Omaha UARTs
+ */
+
+#define UART_GET_FR(p)		readb((p)->membase + OMAHA_UTRSTAT)
+#define UART_GET_CHAR(p)    	readb((p)->membase + OMAHA_URXH)
+#define UART_PUT_CHAR(p, c)	writel((c), (p)->membase + OMAHA_UTXH)
+#define UART_GET_RSR(p)		readb((p)->membase + OMAHA_UERSTAT)
+#define UART_FIFO_STATUS(p)	(readl((p)->membase + OMAHA_UFSTAT))
+#define UART_RX_DATA(s)		(((s) & OMAHA_RXFF_CNT) != 0)
+#define UART_TX_DATA(s)		(!((s) & OMAHA_TXFF))
+#define UART_TX_READY(s)	(((s) & OMAHA_UTX_EMPTY))
+#define UART_TX_EMPTY(p)	((UART_GET_FR(p) & OMAHA_UTXEMPTY) != 0)
+				      
+#define UART_DUMMY_RSR_RX	256
+#define UART_PORT_SIZE		64
+
+#define RX_IRQ(port)		((port)->irq)
+#define TX_IRQ(port)		((port)->irq + 5)
+
+/*
+ * Our private driver data mappings.
+ */
+#define drv_old_status	driver_priv
+
+static void omahauart_stop_tx(struct uart_port *port, u_int from_tty)
+{
+	disable_irq(TX_IRQ(port));
+}
+
+static void omahauart_start_tx(struct uart_port *port, u_int nonempty, u_int from_tty)
+{
+	if (nonempty)
+		enable_irq(TX_IRQ(port));
+}
+
+static void omahauart_stop_rx(struct uart_port *port)
+{
+	disable_irq(RX_IRQ(port));
+}
+
+static void omahauart_enable_ms(struct uart_port *port)
+{
+	// Do nothing...
+}
+
+static void
+#ifdef SUPPORT_SYSRQ
+omahauart_rx_chars(struct uart_info *info, struct pt_regs *regs)
+#else
+omahauart_rx_chars(struct uart_info *info)
+#endif
+{
+	struct tty_struct *tty = info->tty;
+	volatile unsigned int status, data, ch, rsr, max_count = 256;
+	struct uart_port *port = info->port;
+
+	status = UART_FIFO_STATUS(port);
+	while (UART_RX_DATA(status) && max_count--) {
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			tty->flip.tqueue.routine((void *)tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+				printk(KERN_WARNING "TTY_DONT_FLIP set\n");
+				return;
+			}
+		}
+
+		ch = UART_GET_CHAR(port);
+
+		*tty->flip.char_buf_ptr = ch;
+		*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		port->icount.rx++;
+
+		/*
+		 * Note that the error handling code is
+		 * out of the main execution path
+		 */
+		rsr = UART_GET_RSR(port) | UART_DUMMY_RSR_RX;
+		if (rsr & 0xf) {
+			if (rsr & OMAHA_UART_BREAK) {
+				rsr &= ~(OMAHA_UART_FRAME | OMAHA_UART_PARITY);
+				port->icount.brk++;
+				if (uart_handle_break(info, &omaha_console))
+					goto ignore_char;
+			} else if (rsr & OMAHA_UART_PARITY)
+				port->icount.parity++;
+			else if (rsr & OMAHA_UART_FRAME)
+				port->icount.frame++;
+			if (rsr & OMAHA_UART_OVERRUN)
+				port->icount.overrun++;
+
+			rsr &= port->read_status_mask;
+
+			if (rsr & OMAHA_UART_BREAK)
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			else if (rsr & OMAHA_UART_PARITY)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (rsr & OMAHA_UART_FRAME)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+		}
+
+		if (uart_handle_sysrq_char(info, ch, regs))
+			goto ignore_char;
+
+		if ((rsr & port->ignore_status_mask) == 0) {
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+		if ((rsr & OMAHA_UART_OVERRUN) &&
+		    tty->flip.count < TTY_FLIPBUF_SIZE) {
+			/*
+			 * Overrun is special, since it's reported
+			 * immediately, and doesn't affect the current
+			 * character
+			 */
+			*tty->flip.char_buf_ptr++ = 0;
+			*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+			tty->flip.count++;
+		}
+	ignore_char:
+		status = UART_FIFO_STATUS(port);
+	}
+	tty_flip_buffer_push(tty);
+	return;
+}
+
+static void omahauart_tx_chars(struct uart_info *info)
+{
+	struct uart_port *port = info->port;
+	volatile unsigned int status;
+
+	if (port->x_char) {
+		UART_PUT_CHAR(port, port->x_char);
+		port->icount.tx++;
+		port->x_char = 0;
+		return;
+	}
+	if (info->xmit.head == info->xmit.tail
+	    || info->tty->stopped
+	    || info->tty->hw_stopped) {
+		omahauart_stop_tx(port, 0);
+		return;
+	}
+
+	status = UART_FIFO_STATUS(info->port);
+	
+	// FIll FIFO as far as possible
+	while(UART_TX_DATA(UART_FIFO_STATUS(info->port)))
+	{
+		UART_PUT_CHAR(port, info->xmit.buf[info->xmit.tail]);
+		info->xmit.tail = (info->xmit.tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+		if (info->xmit.head == info->xmit.tail)
+			break;
+	}
+
+	if (CIRC_CNT(info->xmit.head, info->xmit.tail, UART_XMIT_SIZE) <
+			WAKEUP_CHARS)
+		uart_event(info, EVT_WRITE_WAKEUP);
+
+	if (info->xmit.head == info->xmit.tail)
+		omahauart_stop_tx(info->port, 0);
+}
+
+static void omahauart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_info *info = dev_id;
+	volatile unsigned int status, pass_counter = OMAHA_ISR_PASS_LIMIT;
+
+	status = UART_FIFO_STATUS(info->port);
+	do {
+		// TX if FIFO not full
+		if (UART_TX_DATA(status))
+			omahauart_tx_chars(info);
+		
+		if (pass_counter-- == 0)
+			break;
+
+		status = UART_FIFO_STATUS(info->port);
+	} while (UART_TX_DATA(status));
+}
+
+static void omahauart_int_rx(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_info *info = dev_id;
+	volatile unsigned int status, pass_counter = OMAHA_ISR_PASS_LIMIT;
+
+	status = UART_FIFO_STATUS(info->port);
+	do {
+		if (UART_RX_DATA(status))
+#ifdef SUPPORT_SYSRQ
+			omahauart_rx_chars(info, regs);
+#else
+			omahauart_rx_chars(info);
+#endif
+		
+		if (pass_counter-- == 0)
+			break;
+
+		status = UART_FIFO_STATUS(info->port);
+	} while (UART_RX_DATA(status));
+}
+
+static u_int omahauart_tx_empty(struct uart_port *port)
+{
+	return UART_FIFO_STATUS(port) ? 0 : TIOCSER_TEMT;
+}
+
+static int omahauart_get_mctrl(struct uart_port *port)
+{
+	// Report no errors.
+
+	return 0;
+}
+
+static void omahauart_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+	// Do nothing.
+}
+
+static void omahauart_break_ctl(struct uart_port *port, int break_state)
+{
+	// Do nothing.
+}
+
+static int omahauart_startup(struct uart_port *port, struct uart_info *info)
+{
+	unsigned int tmp;
+	int retval;
+
+	/*
+	 * Allocate the IRQs
+	 */
+	retval = request_irq(TX_IRQ(port), omahauart_int_tx, 0, "omaha_uart_tx", info);
+	if (retval)
+		return retval;
+
+	retval = request_irq(RX_IRQ(port), omahauart_int_rx, 0, "omaha_uart_rx", info);
+	
+	if (retval)
+	{
+		free_irq(TX_IRQ(port), info);
+		return retval;
+	}
+	
+	/*
+	 * initialise the old status of the modem signals
+	 */
+	info->drv_old_status = 0;
+
+	// Clear all errors
+	writel(0, port->membase + OMAHA_UERSTAT);
+	
+	// Enable FIFO, 16-byte watermark, also do reset (auto-clearing)
+	writel(0xF7, port->membase + OMAHA_UFCON);
+
+	// Level driven TX/RX ints, with rx timeout enabled
+	tmp = readl(port->membase + OMAHA_UCON);
+	tmp |= 0x280; // rx is pulse driven...
+	writel(tmp, port->membase + OMAHA_UCON);
+
+	return 0;
+}
+
+static void omahauart_shutdown(struct uart_port *port, struct uart_info *info)
+{
+	/*
+	 * Free the interrupt
+	 */
+	free_irq(TX_IRQ(port), info);	/* TX interrupt */
+	free_irq(RX_IRQ(port), info);	/* RX interrupt */
+
+}
+
+static void omahauart_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot)
+{
+	// Do nothing.
+}
+
+static const char *omahauart_type(struct uart_port *port)
+{
+	return port->type == PORT_OMAHA ? "OMAHA" : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'
+ */
+static void omahauart_release_port(struct uart_port *port)
+{
+	release_mem_region(port->mapbase, UART_PORT_SIZE);
+}
+
+/*
+ * Request the memory region(s) being used by 'port'
+ */
+static int omahauart_request_port(struct uart_port *port)
+{
+	return request_mem_region(port->mapbase, UART_PORT_SIZE, "serial_omaha")
+			!= NULL ? 0 : -EBUSY;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void omahauart_config_port(struct uart_port *port, int flags)
+{
+	if (flags & UART_CONFIG_TYPE) {
+		port->type = PORT_OMAHA;
+		omahauart_request_port(port);
+	}
+}
+
+/*
+ * verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int omahauart_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	int ret = 0;
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_OMAHA)
+		ret = -EINVAL;
+	if (ser->irq < 0 || ser->irq >= NR_IRQS)
+		ret = -EINVAL;
+	if (ser->baud_base < 9600)
+		ret = -EINVAL;
+	return ret;
+}
+
+static struct uart_ops omaha_pops = {
+	.tx_empty	= omahauart_tx_empty,
+	.set_mctrl	= omahauart_set_mctrl,
+	.get_mctrl	= omahauart_get_mctrl,
+	.stop_tx	= omahauart_stop_tx,
+	.start_tx	= omahauart_start_tx,
+	.stop_rx	= omahauart_stop_rx,
+	.enable_ms	= omahauart_enable_ms,
+	.break_ctl	= omahauart_break_ctl,
+	.startup	= omahauart_startup,
+	.shutdown	= omahauart_shutdown,
+	.change_speed	= omahauart_change_speed,
+	.type		= omahauart_type,
+	.release_port	= omahauart_release_port,
+	.request_port	= omahauart_request_port,
+	.config_port	= omahauart_config_port,
+	.verify_port	= omahauart_verify_port,
+};
+
+static struct uart_port omaha_ports[UART_NR] = {
+	{
+		.membase	= (void *)IO_ADDRESS(OMAHA_UART0_BASE),
+		.mapbase	= OMAHA_UART0_BASE,
+		.iotype		= SERIAL_IO_MEM,
+		.irq		= OMAHA_INT_URXD0,
+		.uartclk	= 10000000,
+		.fifosize	= 8,
+		.unused		= { 4, 5 }, /*Udriver_priv: PORT_CTRLS(5, 4), */
+		.ops		= &omaha_pops,
+		.flags		= ASYNC_BOOT_AUTOCONF,
+	}
+};
+
+#ifdef CONFIG_SERIAL_OMAHA_CONSOLE
+static void omahauart_console_write(struct console *co, const char *s, u_int count)
+{
+	struct uart_port *port = omaha_ports + co->index;
+	unsigned int status;
+	int i;
+
+	/*
+	 *	First save the CR then disable the interrupts
+	 */
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++) {
+		do {
+			status = UART_GET_FR(port);
+		} while ((status & OMAHA_UTX_EMPTY) == 0);
+		UART_PUT_CHAR(port, s[i]);
+		if (s[i] == '\n') {
+			do {
+				status = UART_GET_FR(port);
+			} while ((status & OMAHA_UTX_EMPTY) == 0);
+			UART_PUT_CHAR(port, '\r');
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the TCR
+	 */
+	do {
+		status = UART_GET_FR(port);
+	} while ((status & OMAHA_UTX_EMPTY) == 0);
+}
+
+static kdev_t omahauart_console_device(struct console *co)
+{
+	return MKDEV(SERIAL_OMAHA_MAJOR, SERIAL_OMAHA_MINOR + co->index);
+}
+
+static int omahauart_console_wait_key(struct console *co)
+{
+	struct uart_port *port = omaha_ports + co->index;
+	unsigned int status;
+
+	do {
+		status = UART_FIFO_STATUS(port);
+	} while (!UART_RX_DATA(status));
+	return UART_GET_CHAR(port);
+}
+
+static void __init
+omahauart_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
+{
+	// Do nothing.
+}
+
+static int __init omahauart_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = 38400;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	port = uart_get_console(omaha_ports, UART_NR, co);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else
+		omahauart_console_get_options(port, &baud, &parity, &bits);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct console omaha_console = {
+	.write		= omahauart_console_write,
+	.device		= omahauart_console_device,
+	.wait_key	= omahauart_console_wait_key,
+	.setup		= omahauart_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+};
+
+void __init omahauart_console_init(void)
+{
+	register_console(&omaha_console);
+}
+
+#define OMAHA_CONSOLE	&omaha_console
+#else
+#define OMAHA_CONSOLE	NULL
+#endif
+
+static struct uart_driver omaha_reg = {
+	.owner			= THIS_MODULE,
+	.normal_major		= SERIAL_OMAHA_MAJOR,
+#ifdef CONFIG_DEVFS_FS
+	.normal_name		= "ttyOM%d",
+	.callout_name		= "cuaom%d",
+#else
+	.normal_name		= "ttyOM",
+	.callout_name		= "cuaom",
+#endif
+	.normal_driver		= &normal,
+	.callout_major		= CALLOUT_OMAHA_MAJOR,
+	.callout_driver		= &callout,
+	.table			= omaha_table,
+	.termios		= omaha_termios,
+	.termios_locked		= omaha_termios_locked,
+	.minor			= SERIAL_OMAHA_MINOR,
+	.nr			= UART_NR,
+	.port			= omaha_ports,
+	.cons			= OMAHA_CONSOLE,
+};
+
+static int __init omahauart_init(void)
+{
+	return uart_register_driver(&omaha_reg);
+}
+
+static void __exit omahauart_exit(void)
+{
+	uart_unregister_driver(&omaha_reg);
+}
+
+module_init(omahauart_init);
+module_exit(omahauart_exit);
diff -urN linux-2.4.29/drivers/serial/sa1100.c linux-2.4.29-uc1/drivers/serial/sa1100.c
--- linux-2.4.29/drivers/serial/sa1100.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/serial/sa1100.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,904 @@
+/*
+ *  linux/drivers/char/serial_sa1100.c
+ *
+ *  Driver for SA11x0 serial ports
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *  $Id: sa1100.c,v 1.14.2.4 2002/10/24 09:53:25 rmk Exp $
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach/serial_sa1100.h>
+
+#if defined(CONFIG_SERIAL_SA1100_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+
+/* We've been assigned a range on the "Low-density serial ports" major */
+#define SERIAL_SA1100_MAJOR	204
+#define CALLOUT_SA1100_MAJOR	205
+#define MINOR_START		5
+
+#define NR_PORTS		3
+
+#define SA1100_ISR_PASS_LIMIT	256
+
+/*
+ * Convert from ignore_status_mask or read_status_mask to UTSR[01]
+ */
+#define SM_TO_UTSR0(x)	((x) & 0xff)
+#define SM_TO_UTSR1(x)	((x) >> 8)
+#define UTSR0_TO_SM(x)	((x))
+#define UTSR1_TO_SM(x)	((x) << 8)
+
+#define UART_GET_UTCR0(sport)	__raw_readl((sport)->port.membase + UTCR0)
+#define UART_GET_UTCR1(sport)	__raw_readl((sport)->port.membase + UTCR1)
+#define UART_GET_UTCR2(sport)	__raw_readl((sport)->port.membase + UTCR2)
+#define UART_GET_UTCR3(sport)	__raw_readl((sport)->port.membase + UTCR3)
+#define UART_GET_UTSR0(sport)	__raw_readl((sport)->port.membase + UTSR0)
+#define UART_GET_UTSR1(sport)	__raw_readl((sport)->port.membase + UTSR1)
+#define UART_GET_CHAR(sport)	__raw_readl((sport)->port.membase + UTDR)
+
+#define UART_PUT_UTCR0(sport,v)	__raw_writel((v),(sport)->port.membase + UTCR0)
+#define UART_PUT_UTCR1(sport,v)	__raw_writel((v),(sport)->port.membase + UTCR1)
+#define UART_PUT_UTCR2(sport,v)	__raw_writel((v),(sport)->port.membase + UTCR2)
+#define UART_PUT_UTCR3(sport,v)	__raw_writel((v),(sport)->port.membase + UTCR3)
+#define UART_PUT_UTSR0(sport,v)	__raw_writel((v),(sport)->port.membase + UTSR0)
+#define UART_PUT_UTSR1(sport,v)	__raw_writel((v),(sport)->port.membase + UTSR1)
+#define UART_PUT_CHAR(sport,v)	__raw_writel((v),(sport)->port.membase + UTDR)
+
+/*
+ * This is the size of our serial port register set.
+ */
+#define UART_PORT_SIZE	0x24
+
+static struct tty_driver normal, callout;
+static struct tty_struct *sa1100_table[NR_PORTS];
+static struct termios *sa1100_termios[NR_PORTS], *sa1100_termios_locked[NR_PORTS];
+static int (*sa1100_open)(struct uart_port *);
+static void (*sa1100_close)(struct uart_port *);
+#ifdef SUPPORT_SYSRQ
+static struct console sa1100_console;
+#endif
+
+/*
+ * This determines how often we check the modem status signals
+ * for any change.  They generally aren't connected to an IRQ
+ * so we have to poll them.  We also check immediately before
+ * filling the TX fifo incase CTS has been dropped.
+ */
+#define MCTRL_TIMEOUT	(250*HZ/1000)
+
+struct sa1100_port {
+	struct uart_port	port;
+	struct timer_list	timer;
+	unsigned int		old_status;
+};
+
+/*
+ * Handle any change of modem status signal since we were last called.
+ */
+static void sa1100_mctrl_check(struct sa1100_port *sport)
+{
+	unsigned int status, changed;
+
+	status = sport->port.ops->get_mctrl(&sport->port);
+	changed = status ^ sport->old_status;
+
+	if (changed == 0)
+		return;
+
+	sport->old_status = status;
+
+	if (changed & TIOCM_RI)
+		sport->port.icount.rng++;
+	if (changed & TIOCM_DSR)
+		sport->port.icount.dsr++;
+	if (changed & TIOCM_CAR)
+		uart_handle_dcd_change(&sport->port, status & TIOCM_CAR);
+	if (changed & TIOCM_CTS)
+		uart_handle_cts_change(&sport->port, status & TIOCM_CTS);
+
+	wake_up_interruptible(&sport->port.info->delta_msr_wait);
+}
+
+/*
+ * This is our per-port timeout handler, for checking the
+ * modem status signals.
+ */
+static void sa1100_timeout(unsigned long data)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)data;
+	unsigned long flags;
+
+	if (sport->port.info) {
+		spin_lock_irqsave(&sport->port.lock, flags);
+		sa1100_mctrl_check(sport);
+		spin_unlock_irqrestore(&sport->port.lock, flags);
+
+		mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT);
+	}
+}
+
+/*
+ * interrupts disabled on entry
+ */
+static void sa1100_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+	u32 utcr3;
+
+	utcr3 = UART_GET_UTCR3(sport);
+	UART_PUT_UTCR3(sport, utcr3 & ~UTCR3_TIE);
+	sport->port.read_status_mask &= ~UTSR0_TO_SM(UTSR0_TFS);
+}
+
+/*
+ * interrupts may not be disabled on entry
+ */
+static void sa1100_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+	unsigned long flags;
+	u32 utcr3;
+
+	spin_lock_irqsave(&sport->port.lock, flags);
+	utcr3 = UART_GET_UTCR3(sport);
+	sport->port.read_status_mask |= UTSR0_TO_SM(UTSR0_TFS);
+	UART_PUT_UTCR3(sport, utcr3 | UTCR3_TIE);
+	spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
+/*
+ * Interrupts enabled
+ */
+static void sa1100_stop_rx(struct uart_port *port)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+	u32 utcr3;
+
+	utcr3 = UART_GET_UTCR3(sport);
+	UART_PUT_UTCR3(sport, utcr3 & ~UTCR3_RIE);
+}
+
+/*
+ * Set the modem control timer to fire immediately.
+ */
+static void sa1100_enable_ms(struct uart_port *port)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+
+	mod_timer(&sport->timer, jiffies);
+}
+
+static void
+sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs)
+{
+	struct tty_struct *tty = sport->port.info->tty;
+	unsigned int status, ch, flg, ignored = 0;
+
+	status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
+		 UTSR0_TO_SM(UART_GET_UTSR0(sport));
+	while (status & UTSR1_TO_SM(UTSR1_RNE)) {
+		ch = UART_GET_CHAR(sport);
+
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			goto ignore_char;
+		sport->port.icount.rx++;
+
+		flg = TTY_NORMAL;
+
+		/*
+		 * note that the error handling code is
+		 * out of the main execution path
+		 */
+		if (status & UTSR1_TO_SM(UTSR1_PRE | UTSR1_FRE | UTSR1_ROR))
+			goto handle_error;
+
+		if (uart_handle_sysrq_char(&sport->port, ch, regs))
+			goto ignore_char;
+
+	error_return:
+		*tty->flip.flag_buf_ptr++ = flg;
+		*tty->flip.char_buf_ptr++ = ch;
+		tty->flip.count++;
+	ignore_char:
+		status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
+			 UTSR0_TO_SM(UART_GET_UTSR0(sport));
+	}
+ out:
+	tty_flip_buffer_push(tty);
+	return;
+
+ handle_error:
+	if (status & UTSR1_TO_SM(UTSR1_PRE))
+		sport->port.icount.parity++;
+	else if (status & UTSR1_TO_SM(UTSR1_FRE))
+		sport->port.icount.frame++;
+	if (status & UTSR1_TO_SM(UTSR1_ROR))
+		sport->port.icount.overrun++;
+
+	if (status & sport->port.ignore_status_mask) {
+		if (++ignored > 100)
+			goto out;
+		goto ignore_char;
+	}
+
+	status &= sport->port.read_status_mask;
+
+	if (status & UTSR1_TO_SM(UTSR1_PRE))
+		flg = TTY_PARITY;
+	else if (status & UTSR1_TO_SM(UTSR1_FRE))
+		flg = TTY_FRAME;
+
+	if (status & UTSR1_TO_SM(UTSR1_ROR)) {
+		/*
+		 * overrun does *not* affect the character
+		 * we read from the FIFO
+		 */
+		*tty->flip.flag_buf_ptr++ = flg;
+		*tty->flip.char_buf_ptr++ = ch;
+		tty->flip.count++;
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			goto ignore_char;
+		ch = 0;
+		flg = TTY_OVERRUN;
+	}
+#ifdef SUPPORT_SYSRQ
+	sport->port.sysrq = 0;
+#endif
+	goto error_return;
+}
+
+static void sa1100_tx_chars(struct sa1100_port *sport)
+{
+	struct circ_buf *xmit = &sport->port.info->xmit;
+
+	if (sport->port.x_char) {
+		UART_PUT_CHAR(sport, sport->port.x_char);
+		sport->port.icount.tx++;
+		sport->port.x_char = 0;
+		return;
+	}
+
+	/*
+	 * Check the modem control lines before
+	 * transmitting anything.
+	 */
+	sa1100_mctrl_check(sport);
+
+	if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
+		sa1100_stop_tx(&sport->port, 0);
+		return;
+	}
+
+	/*
+	 * Tried using FIFO (not checking TNF) for fifo fill:
+	 * still had the '4 bytes repeated' problem.
+	 */
+	while (UART_GET_UTSR1(sport) & UTSR1_TNF) {
+		UART_PUT_CHAR(sport, xmit->buf[xmit->tail]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		sport->port.icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	}
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(&sport->port);
+
+	if (uart_circ_empty(xmit))
+		sa1100_stop_tx(&sport->port, 0);
+}
+
+static void sa1100_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct sa1100_port *sport = dev_id;
+	unsigned int status, pass_counter = 0;
+
+	spin_lock(&sport->port.lock);
+	status = UART_GET_UTSR0(sport);
+	status &= SM_TO_UTSR0(sport->port.read_status_mask) | ~UTSR0_TFS;
+	do {
+		if (status & (UTSR0_RFS | UTSR0_RID)) {
+			/* Clear the receiver idle bit, if set */
+			if (status & UTSR0_RID)
+				UART_PUT_UTSR0(sport, UTSR0_RID);
+			sa1100_rx_chars(sport, regs);
+		}
+
+		/* Clear the relevant break bits */
+		if (status & (UTSR0_RBB | UTSR0_REB))
+			UART_PUT_UTSR0(sport, status & (UTSR0_RBB | UTSR0_REB));
+
+		if (status & UTSR0_RBB)
+			sport->port.icount.brk++;
+
+		if (status & UTSR0_REB)
+			uart_handle_break(&sport->port);
+
+		if (status & UTSR0_TFS)
+			sa1100_tx_chars(sport);
+		if (pass_counter++ > SA1100_ISR_PASS_LIMIT)
+			break;
+		status = UART_GET_UTSR0(sport);
+		status &= SM_TO_UTSR0(sport->port.read_status_mask) |
+			  ~UTSR0_TFS;
+	} while (status & (UTSR0_TFS | UTSR0_RFS | UTSR0_RID));
+	spin_unlock(&sport->port.lock);
+}
+
+/*
+ * Return TIOCSER_TEMT when transmitter is not busy.
+ */
+static unsigned int sa1100_tx_empty(struct uart_port *port)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+
+	return UART_GET_UTSR1(sport) & UTSR1_TBY ? 0 : TIOCSER_TEMT;
+}
+
+static unsigned int sa1100_get_mctrl(struct uart_port *port)
+{
+	return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+}
+
+static void sa1100_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+}
+
+/*
+ * Interrupts always disabled.
+ */
+static void sa1100_break_ctl(struct uart_port *port, int break_state)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+	unsigned long flags;
+	unsigned int utcr3;
+
+	spin_lock_irqsave(&sport->port.lock, flags);
+	utcr3 = UART_GET_UTCR3(sport);
+	if (break_state == -1)
+		utcr3 |= UTCR3_BRK;
+	else
+		utcr3 &= ~UTCR3_BRK;
+	UART_PUT_UTCR3(sport, utcr3);
+	spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
+static int sa1100_startup(struct uart_port *port)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+	int retval;
+
+	/*
+	 * Allocate the IRQ
+	 */
+	retval = request_irq(sport->port.irq, sa1100_int, 0,
+			     "sa11x0-uart", sport);
+	if (retval)
+		return retval;
+
+	/*
+	 * If there is a specific "open" function
+	 * (to register control line interrupts)
+	 */
+	if (sa1100_open) {
+		retval = sa1100_open(port);
+		if (retval) {
+			free_irq(sport->port.irq, sport);
+			return retval;
+		}
+	}
+
+	/*
+	 * Finally, clear and enable interrupts
+	 */
+	UART_PUT_UTSR0(sport, -1);
+	UART_PUT_UTCR3(sport, UTCR3_RXE | UTCR3_TXE | UTCR3_RIE);
+
+	return 0;
+}
+
+static void sa1100_shutdown(struct uart_port *port)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+
+	/*
+	 * Stop our timer.
+	 */
+	del_timer_sync(&sport->timer);
+
+	/*
+	 * Free the interrupt
+	 */
+	free_irq(sport->port.irq, sport);
+
+	/*
+	 * If there is a specific "close" function (to unregister
+	 * control line interrupts)
+	 */
+	if (sa1100_close)
+		sa1100_close(port);
+
+	/*
+	 * Disable all interrupts, port and break condition.
+	 */
+	UART_PUT_UTCR3(sport, 0);
+}
+
+static void sa1100_change_speed(struct uart_port *port, unsigned int cflag, unsigned int iflag, unsigned int quot)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+	unsigned long flags;
+	unsigned int utcr0, old_utcr3;
+
+	if ((cflag & CSIZE) == CS8)
+		utcr0 = UTCR0_DSS;
+	else
+		utcr0 = 0;
+
+	if (cflag & CSTOPB)
+		utcr0 |= UTCR0_SBS;
+	if (cflag & PARENB) {
+		utcr0 |= UTCR0_PE;
+		if (!(cflag & PARODD))
+			utcr0 |= UTCR0_OES;
+	}
+
+	spin_lock_irqsave(&sport->port.lock, flags);
+
+	sport->port.read_status_mask &= UTSR0_TO_SM(UTSR0_TFS);
+	sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_ROR);
+	if (iflag & INPCK)
+		sport->port.read_status_mask |=
+				UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE);
+	if (iflag & (BRKINT | PARMRK))
+		sport->port.read_status_mask |=
+				UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB);
+
+	/*
+	 * Characters to ignore
+	 */
+	sport->port.ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		sport->port.ignore_status_mask |=
+				UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE);
+	if (iflag & IGNBRK) {
+		sport->port.ignore_status_mask |=
+				UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB);
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			sport->port.ignore_status_mask |=
+				UTSR1_TO_SM(UTSR1_ROR);
+	}
+
+	del_timer_sync(&sport->timer);
+
+	/*
+	 * disable interrupts and drain transmitter
+	 */
+	old_utcr3 = UART_GET_UTCR3(sport);
+	UART_PUT_UTCR3(sport, old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE));
+
+	while (UART_GET_UTSR1(sport) & UTSR1_TBY)
+		barrier();
+
+	/* then, disable everything */
+	UART_PUT_UTCR3(sport, 0);
+
+	/* set the parity, stop bits and data size */
+	UART_PUT_UTCR0(sport, utcr0);
+
+	/* set the baud rate */
+	quot -= 1;
+	UART_PUT_UTCR1(sport, ((quot & 0xf00) >> 8));
+	UART_PUT_UTCR2(sport, (quot & 0xff));
+
+	UART_PUT_UTSR0(sport, -1);
+
+	UART_PUT_UTCR3(sport, old_utcr3);
+
+	if (UART_ENABLE_MS(&sport->port, cflag))
+		sa1100_enable_ms(&sport->port);
+
+	spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
+static const char *sa1100_type(struct uart_port *port)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+
+	return sport->port.type == PORT_SA1100 ? "SA1100" : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'.
+ */
+static void sa1100_release_port(struct uart_port *port)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+
+	release_mem_region(sport->port.mapbase, UART_PORT_SIZE);
+}
+
+/*
+ * Request the memory region(s) being used by 'port'.
+ */
+static int sa1100_request_port(struct uart_port *port)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+
+	return request_mem_region(sport->port.mapbase, UART_PORT_SIZE,
+			"sa11x0-uart") != NULL ? 0 : -EBUSY;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void sa1100_config_port(struct uart_port *port, int flags)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+
+	if (flags & UART_CONFIG_TYPE &&
+	    sa1100_request_port(&sport->port) == 0)
+		sport->port.type = PORT_SA1100;
+}
+
+/*
+ * Verify the new serial_struct (for TIOCSSERIAL).
+ * The only change we allow are to the flags and type, and
+ * even then only between PORT_SA1100 and PORT_UNKNOWN
+ */
+static int sa1100_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	struct sa1100_port *sport = (struct sa1100_port *)port;
+	int ret = 0;
+
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_SA1100)
+		ret = -EINVAL;
+	if (sport->port.irq != ser->irq)
+		ret = -EINVAL;
+	if (ser->io_type != SERIAL_IO_MEM)
+		ret = -EINVAL;
+	if (sport->port.uartclk / 16 != ser->baud_base)
+		ret = -EINVAL;
+	if ((void *)sport->port.mapbase != ser->iomem_base)
+		ret = -EINVAL;
+	if (sport->port.iobase != ser->port)
+		ret = -EINVAL;
+	if (ser->hub6 != 0)
+		ret = -EINVAL;
+	return ret;
+}
+
+static struct uart_ops sa1100_pops = {
+	.tx_empty	= sa1100_tx_empty,
+	.set_mctrl	= sa1100_set_mctrl,
+	.get_mctrl	= sa1100_get_mctrl,
+	.stop_tx	= sa1100_stop_tx,
+	.start_tx	= sa1100_start_tx,
+	.stop_rx	= sa1100_stop_rx,
+	.enable_ms	= sa1100_enable_ms,
+	.break_ctl	= sa1100_break_ctl,
+	.startup	= sa1100_startup,
+	.shutdown	= sa1100_shutdown,
+	.change_speed	= sa1100_change_speed,
+	.type		= sa1100_type,
+	.release_port	= sa1100_release_port,
+	.request_port	= sa1100_request_port,
+	.config_port	= sa1100_config_port,
+	.verify_port	= sa1100_verify_port,
+};
+
+static struct sa1100_port sa1100_ports[NR_PORTS];
+
+/*
+ * Setup the SA1100 serial ports.  Note that we don't include the IrDA
+ * port here since we have our own SIR/FIR driver (see drivers/net/irda)
+ *
+ * Note also that we support "console=ttySAx" where "x" is either 0 or 1.
+ * Which serial port this ends up being depends on the machine you're
+ * running this kernel on.  I'm not convinced that this is a good idea,
+ * but that's the way it traditionally works.
+ *
+ * Note that NanoEngine UART3 becomes UART2, and UART2 is no longer
+ * used here.
+ */
+static void __init sa1100_init_ports(void)
+{
+	static int first = 1;
+	int i;
+
+	if (!first)
+		return;
+	first = 0;
+
+	for (i = 0; i < NR_PORTS; i++) {
+		sa1100_ports[i].port.uartclk   = 3686400;
+		sa1100_ports[i].port.ops       = &sa1100_pops;
+		sa1100_ports[i].port.fifosize  = 8;
+		sa1100_ports[i].port.line      = i;
+		sa1100_ports[i].port.iotype    = SERIAL_IO_MEM;
+		init_timer(&sa1100_ports[i].timer);
+		sa1100_ports[i].timer.function = sa1100_timeout;
+		sa1100_ports[i].timer.data     = (unsigned long)&sa1100_ports[i];
+	}
+
+	/*
+	 * make transmit lines outputs, so that when the port
+	 * is closed, the output is in the MARK state.
+	 */
+	PPDR |= PPC_TXD1 | PPC_TXD3;
+	PPSR |= PPC_TXD1 | PPC_TXD3;
+}
+
+void __init sa1100_register_uart_fns(struct sa1100_port_fns *fns)
+{
+	if (fns->enable_ms)
+		sa1100_pops.enable_ms = fns->enable_ms;
+	if (fns->get_mctrl)
+		sa1100_pops.get_mctrl = fns->get_mctrl;
+	if (fns->set_mctrl)
+		sa1100_pops.set_mctrl = fns->set_mctrl;
+	sa1100_open          = fns->open;
+	sa1100_close         = fns->close;
+	sa1100_pops.pm       = fns->pm;
+	sa1100_pops.set_wake = fns->set_wake;
+}
+
+void __init sa1100_register_uart(int idx, int port)
+{
+	if (idx >= NR_PORTS) {
+		printk(KERN_ERR "%s: bad index number %d\n", __FUNCTION__, idx);
+		return;
+	}
+
+	switch (port) {
+	case 1:
+		sa1100_ports[idx].port.membase = (void *)&Ser1UTCR0;
+		sa1100_ports[idx].port.mapbase = _Ser1UTCR0;
+		sa1100_ports[idx].port.irq     = IRQ_Ser1UART;
+		sa1100_ports[idx].port.flags   = ASYNC_BOOT_AUTOCONF;
+		break;
+
+	case 2:
+		sa1100_ports[idx].port.membase = (void *)&Ser2UTCR0;
+		sa1100_ports[idx].port.mapbase = _Ser2UTCR0;
+		sa1100_ports[idx].port.irq     = IRQ_Ser2ICP;
+		sa1100_ports[idx].port.flags   = ASYNC_BOOT_AUTOCONF;
+		break;
+
+	case 3:
+		sa1100_ports[idx].port.membase = (void *)&Ser3UTCR0;
+		sa1100_ports[idx].port.mapbase = _Ser3UTCR0;
+		sa1100_ports[idx].port.irq     = IRQ_Ser3UART;
+		sa1100_ports[idx].port.flags   = ASYNC_BOOT_AUTOCONF;
+		break;
+
+	default:
+		printk(KERN_ERR "%s: bad port number %d\n", __FUNCTION__, port);
+	}
+}
+
+
+#ifdef CONFIG_SERIAL_SA1100_CONSOLE
+
+/*
+ * Interrupts are disabled on entering
+ */
+static void
+sa1100_console_write(struct console *co, const char *s, unsigned int count)
+{
+	struct sa1100_port *sport = &sa1100_ports[co->index];
+	unsigned int old_utcr3, status, i;
+
+	/*
+	 *	First, save UTCR3 and then disable interrupts
+	 */
+	old_utcr3 = UART_GET_UTCR3(sport);
+	UART_PUT_UTCR3(sport, (old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE)) |
+				UTCR3_TXE);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++) {
+		do {
+			status = UART_GET_UTSR1(sport);
+		} while (!(status & UTSR1_TNF));
+		UART_PUT_CHAR(sport, s[i]);
+		if (s[i] == '\n') {
+			do {
+				status = UART_GET_UTSR1(sport);
+			} while (!(status & UTSR1_TNF));
+			UART_PUT_CHAR(sport, '\r');
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore UTCR3
+	 */
+	do {
+		status = UART_GET_UTSR1(sport);
+	} while (status & UTSR1_TBY);
+	UART_PUT_UTCR3(sport, old_utcr3);
+}
+
+static kdev_t sa1100_console_device(struct console *co)
+{
+	return MKDEV(SERIAL_SA1100_MAJOR, MINOR_START + co->index);
+}
+
+/*
+ * If the port was already initialised (eg, by a boot loader), try to determine
+ * the current setup.
+ */
+static void __init
+sa1100_console_get_options(struct sa1100_port *sport, int *baud,
+			   int *parity, int *bits)
+{
+	unsigned int utcr3;
+
+	utcr3 = UART_GET_UTCR3(sport) & (UTCR3_RXE | UTCR3_TXE);
+	if (utcr3 == (UTCR3_RXE | UTCR3_TXE)) {
+		/* ok, the port was enabled */
+		unsigned int utcr0, quot;
+
+		utcr0 = UART_GET_UTCR0(sport);
+
+		*parity = 'n';
+		if (utcr0 & UTCR0_PE) {
+			if (utcr0 & UTCR0_OES)
+				*parity = 'e';
+			else
+				*parity = 'o';
+		}
+
+		if (utcr0 & UTCR0_DSS)
+			*bits = 8;
+		else
+			*bits = 7;
+
+		quot = UART_GET_UTCR2(sport) | UART_GET_UTCR1(sport) << 8;
+		quot &= 0xfff;
+		*baud = sport->port.uartclk / (16 * (quot + 1));
+	}
+}
+
+static int __init
+sa1100_console_setup(struct console *co, char *options)
+{
+	struct sa1100_port *sport;
+	int baud = CONFIG_SA1100_DEFAULT_BAUDRATE;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (co->index == -1 || co->index >= NR_PORTS)
+		co->index = 0;
+	sport = &sa1100_ports[co->index];
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else
+		sa1100_console_get_options(sport, &baud, &parity, &bits);
+
+	return uart_set_options(&sport->port, co, baud, parity, bits, flow);
+}
+
+static struct console sa1100_console = {
+	.name		= "ttySA",
+	.write		= sa1100_console_write,
+	.device		= sa1100_console_device,
+	.setup		= sa1100_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+};
+
+void __init sa1100_rs_console_init(void)
+{
+	sa1100_init_ports();
+	register_console(&sa1100_console);
+}
+
+#define SA1100_CONSOLE	&sa1100_console
+#else
+#define SA1100_CONSOLE	NULL
+#endif
+
+static struct uart_driver sa1100_reg = {
+	.owner			= THIS_MODULE,
+	.normal_major		= SERIAL_SA1100_MAJOR,
+#ifdef CONFIG_DEVFS_FS
+	.normal_name		= "ttySA%d",
+	.callout_name		= "cusa%d",
+#else
+	.normal_name		= "ttySA",
+	.callout_name		= "cusa",
+#endif
+	.normal_driver		= &normal,
+	.callout_major		= CALLOUT_SA1100_MAJOR,
+	.callout_driver		= &callout,
+	.table			= sa1100_table,
+	.termios		= sa1100_termios,
+	.termios_locked		= sa1100_termios_locked,
+	.minor			= MINOR_START,
+	.nr			= NR_PORTS,
+	.cons			= SA1100_CONSOLE,
+};
+
+static int __init sa1100_serial_init(void)
+{
+	int i, ret;
+
+	sa1100_init_ports();
+
+	ret = uart_register_driver(&sa1100_reg);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < NR_PORTS; i++)
+		uart_add_one_port(&sa1100_reg, &sa1100_ports[i].port);
+
+	return 0;
+}
+
+static void __exit sa1100_serial_exit(void)
+{
+	int i;
+
+	for (i = 0; i < NR_PORTS; i++)
+		uart_remove_one_port(&sa1100_reg, &sa1100_ports[i].port);
+
+	uart_unregister_driver(&sa1100_reg);
+}
+
+module_init(sa1100_serial_init);
+module_exit(sa1100_serial_exit);
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("Deep Blue Solutions Ltd");
+MODULE_DESCRIPTION("SA1100 generic serial port driver");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/drivers/serial/uart00.c linux-2.4.29-uc1/drivers/serial/uart00.c
--- linux-2.4.29/drivers/serial/uart00.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/serial/uart00.c	2005-06-14 02:12:06.000000000 +0100
@@ -0,0 +1,903 @@
+/*
+ *  linux/drivers/serial/uart00.c
+ *
+ *  Driver for UART00 serial ports
+ *
+ *  Based on drivers/char/serial_amba.c, by ARM Limited & 
+ *                                          Deep Blue Solutions Ltd.
+ *  Copyright 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *  $Id: uart00.c,v 1.3.2.5 2002/10/24 09:53:26 rmk Exp $
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/pld/pld_hotswap.h>
+#include <linux/proc_fs.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <asm/sizes.h>
+
+#if defined(CONFIG_SERIAL_UART00_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+#include <asm/arch/excalibur.h>
+#define UART00_TYPE (volatile unsigned int*)
+#include <asm/arch/uart00.h>
+#include <asm/arch/int_ctrl00.h>
+
+#undef DEBUG
+#define UART_NR		2
+
+#define SERIAL_UART00_NAME	"ttyUA"
+#define SERIAL_UART00_MAJOR	204
+#define SERIAL_UART00_MINOR	16 /* Temporary - will change in future */
+#define SERIAL_UART00_NR	UART_NR
+#define UART_PORT_SIZE 0x50
+
+#define CALLOUT_UART00_NAME	"cuaua"
+#define CALLOUT_UART00_MAJOR	205
+#define CALLOUT_UART00_MINOR	16      /* Temporary - will change in future */
+#define CALLOUT_UART00_NR	UART_NR
+
+static struct tty_driver normal, callout;
+static struct tty_struct *uart00_table[UART_NR];
+static struct termios *uart00_termios[UART_NR], *uart00_termios_locked[UART_NR];
+static struct console uart00_console;
+static struct uart_driver uart00_reg;
+
+
+#define UART00_ISR_PASS_LIMIT	256
+
+/*
+ * Access macros for the UART00 UARTs
+ */
+#define UART_GET_INT_STATUS(p)	inl(UART_ISR((p)->membase))
+#define UART_PUT_IES(p, c)      outl(c,UART_IES((p)->membase))
+#define UART_GET_IES(p)         inl(UART_IES((p)->membase))
+#define UART_PUT_IEC(p, c)      outl(c,UART_IEC((p)->membase))
+#define UART_GET_IEC(p)         inl(UART_IEC((p)->membase))
+#define UART_PUT_CHAR(p, c)     outl(c,UART_TD((p)->membase))
+#define UART_GET_CHAR(p)        inl(UART_RD((p)->membase))
+#define UART_GET_RSR(p)         inl(UART_RSR((p)->membase))
+#define UART_GET_RDS(p)         inl(UART_RDS((p)->membase))
+#define UART_GET_MSR(p)         inl(UART_MSR((p)->membase))
+#define UART_GET_MCR(p)         inl(UART_MCR((p)->membase))
+#define UART_PUT_MCR(p, c)      outl(c,UART_MCR((p)->membase))
+#define UART_GET_MC(p)          inl(UART_MC((p)->membase))
+#define UART_PUT_MC(p, c)       outl(c,UART_MC((p)->membase))
+#define UART_GET_TSR(p)         inl(UART_TSR((p)->membase))
+#define UART_GET_DIV_HI(p)	inl(UART_DIV_HI((p)->membase))
+#define UART_PUT_DIV_HI(p,c)	outl(c,UART_DIV_HI((p)->membase))
+#define UART_GET_DIV_LO(p)	inl(UART_DIV_LO((p)->membase))
+#define UART_PUT_DIV_LO(p,c)	outl(c,UART_DIV_LO((p)->membase))
+#define UART_RX_DATA(s)		((s) & UART_RSR_RX_LEVEL_MSK)
+#define UART_TX_READY(s)	(((s) & UART_TSR_TX_LEVEL_MSK) < 15)
+//#define UART_TX_EMPTY(p)	((UART_GET_FR(p) & UART00_UARTFR_TMSK) == 0)
+
+static void uart00_stop_tx(struct uart_port *port, u_int from_tty)
+{
+
+	UART_PUT_IEC(port, UART_IEC_TIE_MSK);
+}
+
+static void uart00_stop_rx(struct uart_port *port)
+{
+
+	UART_PUT_IEC(port, UART_IEC_RE_MSK);
+}
+
+static void uart00_enable_ms(struct uart_port *port)
+{
+
+	UART_PUT_IES(port, UART_IES_ME_MSK);
+}
+
+static void
+uart00_rx_chars(struct uart_port *port, struct pt_regs *regs)
+{
+	struct uart_info *info = port->info;
+	struct tty_struct *tty = info->tty;
+	unsigned int status, ch, rds, flg, ignored = 0;
+	
+
+	status = UART_GET_RSR(port);
+	while (UART_RX_DATA(status)) {
+
+		/* 
+		 * We need to read rds before reading the 
+		 * character from the fifo
+		 */
+		rds = UART_GET_RDS(port);
+		ch = UART_GET_CHAR(port);
+		port->icount.rx++;
+
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			goto ignore_char;
+
+		flg = TTY_NORMAL;
+
+		/*
+		 * Note that the error handling code is
+		 * out of the main execution path
+		 */
+		if (rds & (UART_RDS_BI_MSK |UART_RDS_FE_MSK|UART_RDS_PE_MSK))
+			goto handle_error;
+		if (uart_handle_sysrq_char(port, ch, regs))
+			goto ignore_char;
+
+	error_return:
+		*tty->flip.flag_buf_ptr++ = flg;
+		*tty->flip.char_buf_ptr++ = ch;
+		tty->flip.count++;
+	ignore_char:
+		status = UART_GET_RSR(port);
+	}
+out:
+	tty_flip_buffer_push(tty);
+	return;
+
+handle_error:
+	if (rds & UART_RDS_BI_MSK) {
+		status &= ~(UART_RDS_FE_MSK | UART_RDS_PE_MSK);
+		port->icount.brk++;
+
+#ifdef SUPPORT_SYSRQ
+		if (uart_handle_break(port))
+			goto ignore_char;
+#endif
+	} else if (rds & UART_RDS_PE_MSK)
+		port->icount.parity++;
+	else if (rds & UART_RDS_FE_MSK)
+		port->icount.frame++;
+	if (rds & UART_RDS_OE_MSK)
+		port->icount.overrun++;
+
+	if (rds & port->ignore_status_mask) {
+		if (++ignored > 100)
+			goto out;
+		goto ignore_char;
+	}
+	rds &= port->read_status_mask;
+
+	if (rds & UART_RDS_BI_MSK)
+		flg = TTY_BREAK;
+	else if (rds & UART_RDS_PE_MSK)
+		flg = TTY_PARITY;
+	else if (rds & UART_RDS_FE_MSK)
+		flg = TTY_FRAME;
+
+	if (rds & UART_RDS_OE_MSK) {
+		/*
+		 * CHECK: does overrun affect the current character?
+		 * ASSUMPTION: it does not.
+		 */
+		*tty->flip.flag_buf_ptr++ = flg;
+		*tty->flip.char_buf_ptr++ = ch;
+		tty->flip.count++;
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			goto ignore_char;
+		ch = 0;
+		flg = TTY_OVERRUN;
+	}
+#ifdef SUPPORT_SYSRQ
+	port->sysrq = 0;
+#endif
+	goto error_return;
+}
+
+static void uart00_tx_chars(struct uart_port *port)
+{
+	int count;
+	struct uart_info *info = port->info;
+
+	if (port->x_char) {
+		while((UART_GET_TSR(port)& UART_TSR_TX_LEVEL_MSK)==15);
+		UART_PUT_CHAR(port, port->x_char);
+		port->icount.tx++;
+		port->x_char = 0;
+		
+		return;
+	}
+	if (info->xmit.head == info->xmit.tail
+	    || info->tty->stopped
+	    || info->tty->hw_stopped) {
+		uart00_stop_tx(port, 0);
+		return;
+	}
+
+	count = port->fifosize >> 1;
+	do {
+		while((UART_GET_TSR(port)& UART_TSR_TX_LEVEL_MSK)==15);
+		UART_PUT_CHAR(port, info->xmit.buf[info->xmit.tail]);
+		info->xmit.tail = (info->xmit.tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+		if (info->xmit.head == info->xmit.tail)
+			break;
+	} while (--count > 0);
+
+	if (CIRC_CNT(info->xmit.head,
+		     info->xmit.tail,
+		     UART_XMIT_SIZE) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+
+	if (info->xmit.head == info->xmit.tail)
+		uart00_stop_tx(port, 0);
+}
+
+static void uart00_start_tx(struct uart_port *port, u_int from_tty)
+{
+	UART_PUT_IES(port,UART_IES_TIE_MSK );		
+	uart00_tx_chars(port);
+}
+
+static void uart00_modem_status(struct uart_port *port)
+{
+	unsigned int status;
+	struct uart_icount *icount = &port->icount;
+	struct uart_info *info = port->info;
+
+	status = UART_GET_MSR(port);
+
+	if (!status & (UART_MSR_DCTS_MSK | UART_MSR_DDSR_MSK | 
+		       UART_MSR_TERI_MSK | UART_MSR_DDCD_MSK))
+		return;
+
+	if (status & UART_MSR_DDCD_MSK) {
+		icount->dcd++;
+#ifdef CONFIG_HARD_PPS
+		if ((port->flags & ASYNC_HARDPPS_CD) &&
+		    (status & UART_MSR_DCD_MSK))
+			hardpps();
+#endif
+		if (info->flags & ASYNC_CHECK_CD) {
+			if (status & UART_MSR_DCD_MSK)
+				wake_up_interruptible(&info->open_wait);
+			else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+				   (port->flags & ASYNC_CALLOUT_NOHUP))) {
+				if (info->tty)
+					tty_hangup(info->tty);
+			}
+		}
+	}
+
+	if (status & UART_MSR_DDSR_MSK)
+		icount->dsr++;
+
+	if (status & UART_MSR_DCTS_MSK) {
+		icount->cts++;
+
+		if (info->flags & ASYNC_CTS_FLOW) {
+			status &= UART_MSR_CTS_MSK;
+
+			if (info->tty->hw_stopped) {
+				if (status) {
+					info->tty->hw_stopped = 0;
+					port->ops->start_tx(port, 0);
+					uart_write_wakeup(port);
+				}
+			} else {
+				if (!status) {
+					info->tty->hw_stopped = 1;
+					port->ops->stop_tx(port, 0);
+				}
+			}
+		}
+	}
+	wake_up_interruptible(&info->delta_msr_wait);
+
+}
+
+static void uart00_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_port *port = dev_id;
+	unsigned int status, pass_counter = 0;
+
+	status = UART_GET_INT_STATUS(port);
+	do {
+
+		if (status & UART_ISR_RI_MSK)
+			uart00_rx_chars(port, regs);
+		if (status & (UART_ISR_TI_MSK | UART_ISR_TII_MSK))
+			uart00_tx_chars(port);
+		if (status & UART_ISR_MI_MSK)
+			uart00_modem_status(port);
+		if (pass_counter++ > UART00_ISR_PASS_LIMIT)
+			break;
+
+		status = UART_GET_INT_STATUS(port);
+	} while (status);
+}
+
+static u_int uart00_tx_empty(struct uart_port *port)
+{
+	return UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK? 0 : TIOCSER_TEMT;
+}
+
+static u_int uart00_get_mctrl(struct uart_port *port)
+{
+	unsigned int result = 0;
+	unsigned int status;
+
+	status = UART_GET_MSR(port);
+	if (status & UART_MSR_DCD_MSK)
+		result |= TIOCM_CAR;
+	if (status & UART_MSR_DSR_MSK)
+		result |= TIOCM_DSR;
+	if (status & UART_MSR_CTS_MSK)
+		result |= TIOCM_CTS;
+	if (status & UART_MCR_RI_MSK)
+		result |= TIOCM_RNG;
+
+	return result;
+}
+
+static void uart00_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+	unsigned char mcr = 0;
+
+	if (mctrl & TIOCM_RTS)
+		mcr |= UART_MCR_RTS_MSK;
+	if (mctrl & TIOCM_DTR)
+		mcr |= UART_MCR_DTR_MSK;
+	if (mctrl & TIOCM_LOOP)
+		mcr |= UART_MCR_LB_MSK;
+
+	UART_PUT_MCR(port, mcr);
+}
+
+static void uart00_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned int mcr;
+
+	mcr = UART_GET_MCR(port);
+	if (break_state == -1)
+		mcr |= UART_MCR_BR_MSK;
+	else
+		mcr &= ~UART_MCR_BR_MSK;
+	UART_PUT_MCR(port, mcr);
+}
+
+static inline u_int uart_calculate_quot(struct uart_port *port, u_int baud)
+{
+	u_int quot;
+
+	/* Special case: B0 rate */
+	if (!baud)
+		baud = 9600;
+
+	quot = (port->uartclk / (16 * baud)-1)  ;
+
+	return quot;
+}
+static void uart00_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot)
+{
+	u_int uart_mc=0, old_ies;
+	unsigned long flags;
+
+#ifdef DEBUG
+	printk("uart00_set_cflag(0x%x) called\n", cflag);
+#endif
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	case CS5: uart_mc = UART_MC_CLS_CHARLEN_5; break;
+	case CS6: uart_mc = UART_MC_CLS_CHARLEN_6; break;
+	case CS7: uart_mc = UART_MC_CLS_CHARLEN_7; break;
+	default:  uart_mc = UART_MC_CLS_CHARLEN_8; break; // CS8
+	}
+	if (cflag & CSTOPB)
+		uart_mc|= UART_MC_ST_TWO;
+	if (cflag & PARENB) {
+		uart_mc |= UART_MC_PE_MSK;
+		if (!(cflag & PARODD))
+			uart_mc |= UART_MC_EP_MSK;
+	}
+
+	port->read_status_mask = UART_RDS_OE_MSK;
+	if (iflag & INPCK)
+		port->read_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;
+	if (iflag & (BRKINT | PARMRK))
+		port->read_status_mask |= UART_RDS_BI_MSK;
+
+	/*
+	 * Characters to ignore
+	 */
+	port->ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		port->ignore_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;
+	if (iflag & IGNBRK) {
+		port->ignore_status_mask |= UART_RDS_BI_MSK;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns to (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			port->ignore_status_mask |= UART_RDS_OE_MSK;
+	}
+
+	/* first, disable everything */
+	save_flags(flags); cli();
+	old_ies = UART_GET_IES(port); 
+
+	if ((port->flags & ASYNC_HARDPPS_CD) ||
+	    (cflag & CRTSCTS) || !(cflag & CLOCAL))
+		old_ies |= UART_IES_ME_MSK;
+
+
+	/* Set baud rate */
+	UART_PUT_DIV_LO(port, (quot & 0xff));
+	UART_PUT_DIV_HI(port, ((quot & 0xf00) >> 8));
+   
+
+	UART_PUT_MC(port, uart_mc);
+	UART_PUT_IES(port, old_ies);
+
+	restore_flags(flags);
+}
+
+static int uart00_startup(struct uart_port *port)
+{
+	int retval;
+
+	/*
+	 * Allocate the IRQ
+	 */
+	retval = request_irq(port->irq, uart00_int, 0, "uart00", port);
+	if (retval)
+		return retval;
+
+	/*
+	 * Finally, enable interrupts. Use the TII interrupt to minimise 
+	 * the number of interrupts generated. If higher performance is 
+	 * needed, consider using the TI interrupt with a suitable FIFO
+	 * threshold
+	 */
+	UART_PUT_IES(port, UART_IES_RE_MSK | UART_IES_TIE_MSK);
+
+	return 0;
+}
+
+static void uart00_shutdown(struct uart_port *port)
+{
+	/*
+	 * disable all interrupts, disable the port
+	 */
+	UART_PUT_IEC(port, 0xff);
+
+	/* disable break condition and fifos */
+	UART_PUT_MCR(port, UART_GET_MCR(port) &~UART_MCR_BR_MSK);
+
+	/*
+	 * Free the interrupt
+	 */
+	free_irq(port->irq, port);
+}
+
+static const char *uart00_type(struct uart_port *port)
+{
+	return port->type == PORT_UART00 ? "Altera UART00" : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'
+ */
+static void uart00_release_port(struct uart_port *port)
+{
+	release_mem_region(port->mapbase, UART_PORT_SIZE);
+
+#ifdef CONFIG_ARCH_CAMELOT
+	if(port->membase!=(void*)IO_ADDRESS(EXC_UART00_BASE)){
+		iounmap(port->membase);
+	}
+#endif
+}
+
+/*
+ * Request the memory region(s) being used by 'port'
+ */
+static int uart00_request_port(struct uart_port *port)
+{
+	int result;
+
+	result = request_mem_region(port->mapbase, UART_PORT_SIZE,
+				    "serial_uart00") != NULL ? 0 : -EBUSY;
+	if (result)
+		return result;
+
+	port->membase = ioremap(port->mapbase, SZ_4K);
+	if (!port->membase) {
+		printk(KERN_ERR "serial00: cannot map io memory\n");
+		release_mem_region(port->mapbase, UART_PORT_SIZE);
+	}
+
+	return port->membase ? 0 : -ENOMEM;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void uart00_config_port(struct uart_port *port, int flags)
+{
+	if (flags & UART_CONFIG_TYPE) {
+		if (uart00_request_port(port) == 0)
+			port->type = PORT_UART00;
+	}
+}
+
+/*
+ * verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int uart00_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	int ret = 0;
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_UART00)
+		ret = -EINVAL;
+	if (ser->irq < 0 || ser->irq >= NR_IRQS)
+		ret = -EINVAL;
+	if (ser->baud_base < 9600)
+		ret = -EINVAL;
+	return ret;
+}
+
+static struct uart_ops uart00_pops = {
+	tx_empty:	uart00_tx_empty,
+	set_mctrl:	uart00_set_mctrl,
+	get_mctrl:	uart00_get_mctrl,
+	stop_tx:	uart00_stop_tx,
+	start_tx:	uart00_start_tx,
+	stop_rx:	uart00_stop_rx,
+	enable_ms:	uart00_enable_ms,
+	break_ctl:	uart00_break_ctl,
+	startup:	uart00_startup,
+	shutdown:	uart00_shutdown,
+	change_speed:	uart00_change_speed,
+	type:		uart00_type,
+	release_port:	uart00_release_port,
+	request_port:	uart00_request_port,
+	config_port:	uart00_config_port,
+	verify_port:	uart00_verify_port,
+};
+
+static struct uart_port uart00_ports[UART_NR] = {
+
+#ifdef CONFIG_ARCH_CAMELOT
+{
+	.membase	= (void*)IO_ADDRESS(EXC_UART00_BASE),
+	.mapbase	=  EXC_UART00_BASE,
+	.iotype		= SERIAL_IO_MEM,
+	.irq		= IRQ_UART,
+	.uartclk	= EXC_AHB2_CLK_FREQUENCY,
+	.fifosize	= 16,
+	.ops		= &uart00_pops,
+	.flags		= ASYNC_BOOT_AUTOCONF,
+}
+#endif
+};
+
+#ifdef CONFIG_SERIAL_UART00_CONSOLE
+static void uart00_console_write(struct console *co, const char *s, unsigned count)
+{
+#ifdef CONFIG_ARCH_CAMELOT
+	struct uart_port *port = &uart00_ports[0];
+	unsigned int status, old_ies;
+	int i;
+
+	/*
+	 *	First save the CR then disable the interrupts
+	 */
+	old_ies = UART_GET_IES(port);
+	UART_PUT_IEC(port,0xff);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++) {
+		do {
+			status = UART_GET_TSR(port);
+		} while (!UART_TX_READY(status));
+		UART_PUT_CHAR(port, s[i]);
+		if (s[i] == '\n') {
+			do {
+				status = UART_GET_TSR(port);
+			} while (!UART_TX_READY(status));
+			UART_PUT_CHAR(port, '\r');
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the IES
+	 */
+	do {
+		status = UART_GET_TSR(port);
+	} while (status & UART_TSR_TX_LEVEL_MSK);
+	UART_PUT_IES(port, old_ies);
+#endif
+}
+
+static kdev_t uart00_console_device(struct console *co)
+{
+	return MKDEV(SERIAL_UART00_MAJOR, SERIAL_UART00_MINOR + co->index);
+}
+
+static void /*__init*/ uart00_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
+{
+	u_int uart_mc, quot;
+	uart_mc= UART_GET_MC(port);
+
+	*parity = 'n';
+	if (uart_mc & UART_MC_PE_MSK) {
+		if (uart_mc & UART_MC_EP_MSK)
+			*parity = 'e';
+		else
+			*parity = 'o';
+	}
+
+	switch (uart_mc & UART_MC_CLS_MSK){
+
+	case UART_MC_CLS_CHARLEN_5:
+		*bits = 5;
+		break;
+	case UART_MC_CLS_CHARLEN_6:
+		*bits = 6;
+		break;
+	case UART_MC_CLS_CHARLEN_7:
+		*bits = 7;
+		break;
+	case UART_MC_CLS_CHARLEN_8:
+		*bits = 8;
+		break;
+	}
+	quot = UART_GET_DIV_LO(port) | (UART_GET_DIV_HI(port) << 8);
+	*baud = port->uartclk / (16 *quot );
+}
+
+static int __init uart00_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = 38400;
+	int bits = 8;
+	int parity = 'n';
+	int flow= 'n';
+
+#ifdef CONFIG_ARCH_CAMELOT
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	port = &uart00_ports[0];
+	co->index = 0;
+#else
+	return -ENODEV;
+#endif
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else
+		uart00_console_get_options(port, &baud, &parity, &bits);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct console uart00_console = {
+	.name	= SERIAL_UART00_NAME,
+	.write	= uart00_console_write,
+	.device	= uart00_console_device,
+	.setup	= uart00_console_setup,
+	.flags	= CON_PRINTBUFFER,
+	.index	= 0,
+};
+
+void __init uart00_console_init(void)
+{
+	register_console(&uart00_console);
+}
+
+#define UART00_CONSOLE	&uart00_console
+#else
+#define UART00_CONSOLE	NULL
+#endif
+
+static struct uart_driver uart00_reg = {
+	.owner		= NULL,
+	.normal_major	= SERIAL_UART00_MAJOR,
+	.normal_name	= SERIAL_UART00_NAME,
+	.normal_driver	= &normal,
+	.callout_major	= CALLOUT_UART00_MAJOR,
+	.callout_name	= CALLOUT_UART00_NAME,
+	.callout_driver	= &callout,
+	.table		= uart00_table,
+	.termios	= uart00_termios,
+	.termios_locked	= uart00_termios_locked,
+	.minor		= SERIAL_UART00_MINOR,
+	.nr		= UART_NR,
+	.state		= NULL,
+	.cons		= UART00_CONSOLE,
+};
+
+struct dev_port_entry{
+	struct uart_port *port;
+};
+
+static struct dev_port_entry dev_port_map[UART_NR];
+
+#ifdef CONFIG_PLD_HOTSWAP
+/*
+ * Keep a mapping of dev_info addresses -> port lines to use when
+ * removing ports dev==NULL indicates unused entry
+ */
+
+struct uart00_ps_data{
+	unsigned int clk;
+	unsigned int fifosize;
+};
+
+int uart00_add_device(struct pldhs_dev_info* dev_info, void* dev_ps_data)
+{
+	struct uart00_ps_data* dev_ps=dev_ps_data;
+	struct uart_port * port;
+	int i,result;
+
+	i=0;
+	while(dev_port_map[i].port)
+		i++;
+
+	if(i==UART_NR){
+		printk(KERN_WARNING "uart00: Maximum number of ports reached\n");
+		return 0;
+	}
+
+	port=&uart00_ports[i];
+
+	printk("clk=%d fifo=%d\n",dev_ps->clk,dev_ps->fifosize);
+	port->membase=0;
+	port->mapbase=dev_info->base_addr;
+	port->iotype=SERIAL_IO_MEM;
+	port->irq=dev_info->irq;
+	port->uartclk=dev_ps->clk;
+	port->fifosize=dev_ps->fifosize;
+	port->ops=&uart00_pops;
+	port->line=i;
+	port->flags=ASYNC_BOOT_AUTOCONF;
+
+	result=uart_register_port(&uart00_reg, port);
+	if(result<0){
+		printk("uart_register_port returned %d\n",result);
+		return result;
+	}
+	dev_port_map[i].port=port;
+	printk("uart00: added device at %lx as ttyUA%d\n",dev_port_map[i].port->mapbase,i);
+	return 0;
+
+}
+
+int uart00_remove_devices(void)
+{
+	int i,result;
+
+
+	result=0;
+	for(i=1;i<UART_NR;i++){
+		if(dev_port_map[i].port){
+			uart_unregister_port(&uart00_reg,i);
+			dev_port_map[i].port=NULL;
+		}
+	}
+	return 0;
+
+}
+
+#ifdef CONFIG_PROC_FS
+
+
+int uart00_proc_read(char* buf,char** start,off_t offset,int count,int *eof,void *data){
+
+	int i,len=0;
+	struct uart_port *port;
+	int limit = count - 80;
+	char ps_data[80];
+	if(*start)
+		buf=*start;
+	for(i=0;(i<UART_NR)&&(len<limit);i++){
+		if(dev_port_map[i].port){
+			port=dev_port_map[i].port;
+			sprintf(ps_data,"clk, %dHz, fifo size, %dbytes",
+				port->uartclk,port->fifosize);
+			len+=PLDHS_READ_PROC_DATA(buf+len,"uart00",i,
+					 port->mapbase,port->irq,ps_data);
+
+		}
+	}
+	*eof=1;
+	return len;
+}
+
+
+
+#endif
+struct pld_hotswap_ops uart00_pldhs_ops={
+	.name		= "uart00",
+	.add_device	= uart00_add_device,
+	.remove_devices	= uart00_remove_devices,
+	.proc_read	= uart00_proc_read
+};
+
+#endif
+
+static int __init uart00_init(void)
+{
+	int ret;
+	int i;
+
+	ret = uart_register_driver(&uart00_reg);
+	if (ret) {
+		printk(KERN_ERR "uart00: Couldn't register driver\n");
+		return ret;
+	}
+
+	unregister_console(&uart00_console);
+
+	for(i=0;i<UART_NR;i++){
+		uart00_ports[i].ops=&uart00_pops;
+	}
+
+	printk(KERN_WARNING "uart00:Using temporary major/minor pairs - these WILL change in the future\n");
+
+#ifdef CONFIG_PLD_HOTSWAP
+	pldhs_register_driver(&uart00_pldhs_ops);
+#endif
+	for (i=0; i<UART_NR; i++)
+		uart_add_one_port(&uart00_reg,&uart00_ports[i]);
+
+	uart00_console.flags = 0;
+	register_console(&uart00_console);
+#ifdef CONFIG_ARCH_CAMELOT
+	dev_port_map[0].port=uart00_ports;
+#endif
+	return ret;
+}
+
+
+__initcall(uart00_init);
+
+
diff -urN linux-2.4.29/drivers/sound/Config.in linux-2.4.29-uc1/drivers/sound/Config.in
--- linux-2.4.29/drivers/sound/Config.in	2005-01-19 14:10:04.000000000 +0000
+++ linux-2.4.29-uc1/drivers/sound/Config.in	2005-06-14 02:12:04.000000000 +0100
@@ -133,6 +133,15 @@
 dep_tristate '  VIA 82C686 Audio Codec' CONFIG_SOUND_VIA82CXXX $CONFIG_PCI
 dep_mbool    '  VIA 82C686 MIDI' CONFIG_MIDI_VIA82CXXX $CONFIG_SOUND_VIA82CXXX
 
+
+if [ "$CONFIG_ARCH_EP7212" = "y" -o "$CONFIG_ARCH_EP7312" = "y" ]; then
+   dep_tristate '  edb7312/7212 DAI audio support' CONFIG_SOUND_7212 $CONFIG_SOUND
+   if [ "$CONFIG_ARCH_EP7212" = "y" ]; then
+      bool '    select external PLL clock (default is internal)' CONFIG_SOUND_EP7312_EXTCLK
+   fi
+fi
+
+
 dep_tristate '  OSS sound modules' CONFIG_SOUND_OSS $CONFIG_SOUND
 
 if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
@@ -147,6 +156,21 @@
    dep_tristate '    Adlib Cards' CONFIG_SOUND_ADLIB $CONFIG_SOUND_OSS
    dep_tristate '    ACI mixer (miroSOUND PCM1-pro/PCM12/PCM20)' CONFIG_SOUND_ACI_MIXER $CONFIG_SOUND_OSS
    dep_tristate '    Crystal CS4232 based (PnP) cards' CONFIG_SOUND_CS4232 $CONFIG_SOUND_OSS
+
+   if [ "$CONFIG_ARCH_EP93XX" = "y" ]; then
+      dep_tristate '    Cirrus EP93xx sound support' CONFIG_SOUND_EP93XX $CONFIG_SOUND_OSS
+      if [ "$CONFIG_SOUND_EP93XX" != "n" ]; then
+         choice '      Cirrus EP93xx sound interface' \
+                "AC97 CONFIG_SOUND_EP93XX_AC97 \
+                 I2S CONFIG_SOUND_EP93XX_I2S" AC97
+         if [ "$CONFIG_SOUND_EP93XX_I2S" = "y" ]; then
+            choice '      Cirrus I2S codec support' \
+                   "CS4271 CONFIG_CODEC_CS4271 \
+                    CS4228A CONFIG_CODEC_CS4228A" CS4228A
+         fi
+      fi
+   fi
+
    dep_tristate '    Ensoniq SoundScape support' CONFIG_SOUND_SSCAPE $CONFIG_SOUND_OSS
    dep_tristate '    Gravis Ultrasound support' CONFIG_SOUND_GUS $CONFIG_SOUND_OSS
    if [ "$CONFIG_SOUND_GUS" != "n" ]; then
diff -urN linux-2.4.29/drivers/sound/cs43l42.c linux-2.4.29-uc1/drivers/sound/cs43l42.c
--- linux-2.4.29/drivers/sound/cs43l42.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/sound/cs43l42.c	2005-06-14 02:12:05.000000000 +0100
@@ -0,0 +1,244 @@
+/*
+ * CS43L42 DAC on the EDB7312 Cogent eval board
+ *
+ * (C) 2003 Heeltoe Consulting, http://www.heeltoe.com
+ * (c) 2003 Nucleus Systems, Petko Manolov <petkan@nucleusys.com>
+ *
+ * linux/drivers/sound/cs43l42.c
+ */
+
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/hardware/ep7312.h>
+#include <asm/hardware/clps7111.h>
+#include <asm/delay.h>
+
+
+#define ADDR_CS43L42	(0x10 << 1)
+#define ADDR_CS53L32	(0x11 << 1)
+#define CS43L42_PWRCTL	0x01
+/* direction and i/o bits have the same offset */
+#define	SCL		(1 << 5)
+#define SDA		(1 << 4)
+
+
+static void reset_cs43l42(void)
+{
+	clps_writel((clps_readl(PEDDR) | (1 << 0)), PEDDR);
+
+	clps_writel((clps_readl(PEDR) & ~(1 << 0)), PEDR);
+	udelay(10);
+	clps_writel((clps_readl(PEDR) | (1 << 0)), PEDR);
+	udelay(10);
+}
+
+static void make_scl_sda_outputs(void)
+{
+	unsigned char tmp;
+	
+	tmp = clps_readb(PDDDR);
+	tmp &= ~(SCL | SDA);
+	clps_writeb(tmp, PDDDR);
+}
+
+static void make_sda_input(void)
+{
+	unsigned char tmp;
+
+	tmp = clps_readb(PDDDR);
+	tmp |= SDA;
+	clps_writeb(tmp, PDDDR);
+}
+
+static void set_scl(int val)
+{
+	unsigned char tmp;
+	
+	tmp = clps_readb(PDDR);
+	if (val)
+		tmp |= SCL;
+	else
+		tmp &= ~SCL;
+	clps_writeb(tmp, PDDR);
+}
+
+static void set_sda(int val)
+{
+	unsigned char tmp;
+	
+	tmp = clps_readb(PDDR);
+	if (val)
+		tmp |= SDA;
+	else
+		tmp &= ~SDA;
+	clps_writeb(tmp, PDDR);
+}
+
+static int get_sda(void)
+{
+	unsigned char tmp;
+	
+	tmp = clps_readb(PDDR);
+	return (tmp & SDA) ? 1 : 0;
+}
+
+static int clock_byte_in(void)
+{
+	int i, b, ack;
+
+	b = 0;
+	make_sda_input();
+	for (i = 0; i < 8; i++) {
+		udelay(3);
+		b = (b << 1) |  get_sda();
+		udelay(3);
+		set_scl(1);
+		udelay(5);
+		set_scl(0);
+	}
+	/* ack bit */
+	udelay(5);
+	set_scl(1);
+	udelay(2);
+	ack = get_sda();
+	udelay(3);
+	set_scl(0);
+	make_scl_sda_outputs();
+
+	return b;
+}
+
+static void clock_byte_out(int b, int set_output)
+{
+	int i, ack;
+
+	for (i = 0; i < 8; i++) {
+		udelay(3);
+		set_sda(b & 0x80);
+		udelay(3);
+		set_scl(1);
+		udelay(5);	/* Tlow == 4.7 uS */
+		set_scl(0);
+		b <<= 1;
+	}
+	/* ack bit */
+	make_sda_input();
+	udelay(5);
+	set_scl(1);
+	udelay(2);
+	ack = get_sda();
+	udelay(3);
+	set_scl(0);
+
+	if (set_output) {
+		make_scl_sda_outputs();
+	}
+}
+
+static int cs43l42_i2c_read(int addr, int reg)
+{
+	int b;
+
+	/*
+	 * start of frame
+	 */
+	set_sda(1);
+	set_scl(1);
+	udelay(5);	/* Tbuf == 4.7 uS */
+	set_sda(0);
+	udelay(4);	/* Thdst == 4 uS */
+	set_scl(0);
+	clock_byte_out(addr | 0x01, 1);
+	clock_byte_out(reg, 0);
+	b = clock_byte_in();
+	/*
+	 * end of frame
+	 */
+	set_sda(1);
+	set_scl(1);
+	udelay(5);
+
+	return b;
+}
+
+static int cs43l42_i2c_write(int addr, int reg, int value)
+{
+	set_sda(1);
+	set_scl(1);
+	udelay(5);
+	set_sda(0);
+	udelay(4);
+	set_scl(0);
+	clock_byte_out(addr, 1);
+	clock_byte_out(reg, 1);
+	clock_byte_out(value, 1);
+	set_sda(1);
+	set_scl(1);
+	udelay(5);
+
+	return 0;
+}
+
+static void cs43l42_dump_regs(void)
+{
+	int i;
+
+	printk("%s: cs43l42 is at %02x\n", __FUNCTION__, ADDR_CS43L42);
+	for (i = 1; i <= 0xb; i++) {
+		printk("reg %02x: %02x\n",i,cs43l42_i2c_read(ADDR_CS43L42, i));
+	}
+}
+
+
+int setup_cs43l42(void)
+{
+	volatile long u;
+	volatile char port_d;
+
+	printk("cs43l42: init dac\n");
+	port_d = clps_readb(PDDR) & ~(SCL | SDA);
+	
+	/* enable codec_en# */
+	reset_cs43l42();
+
+	/* make SDA & SCL outputs */
+	make_scl_sda_outputs();
+
+	/*
+	 * enable the two wire serial interface on the CS43L42
+	 * by setting the CP_EN bit (bit 0) of register 1
+	 */
+	cs43l42_i2c_write(ADDR_CS43L42, CS43L42_PWRCTL, 0xd2);
+
+	/* set the data format to left justified */
+	cs43l42_i2c_write(ADDR_CS43L42, 0x0b, 0x02);
+
+	/* power on the DAC */
+	cs43l42_i2c_write(ADDR_CS43L42, CS43L42_PWRCTL, 0xd0);
+
+	/* delay while the DAC initializes */
+	for(u = 0; u < 15; u++)
+		udelay(5);
+
+	cs43l42_i2c_write(ADDR_CS43L42, 2, 0xf1);
+	cs43l42_i2c_write(ADDR_CS43L42, 3, 0xf1);
+
+#if 0
+	cs43l42_dump_regs();
+	printk("syscon1 %08x\n", clps_readl(SYSCON1));
+	printk("syscon2 %08x\n", clps_readl(SYSCON2));
+	printk("syscon3 %08x\n", clps_readl(SYSCON3));
+#endif
+	/* restore original port D value */
+	port_d |= clps_readb(PDDR);
+	clps_writeb(port_d, PDDR);
+	printk("cs43l42: init dac complete\n");
+
+	return 0;
+}
diff -urN linux-2.4.29/drivers/sound/ep7212_audio.c linux-2.4.29-uc1/drivers/sound/ep7212_audio.c
--- linux-2.4.29/drivers/sound/ep7212_audio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/sound/ep7212_audio.c	2005-06-14 02:12:05.000000000 +0100
@@ -0,0 +1,821 @@
+/*
+ * CL-PS7212/empeg Audio Device Driver
+ *
+ * (C)2000 empeg ltd, http://www.empeg.com
+ *
+ * linux/drivers/sound/ep7212_audio.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *   N.B: This driver requires that it be fed data 4608 bytes at a time.
+ *        See http://www.mock.com/receiver/demo for demo players or better
+ *        yet, fix this!
+ *
+ * Version history:
+ *   Hugo Fiennes <hugo@empeg.com>
+ *
+ *   22-Feb-2000 - First version
+ *   28-Feb-2000 - Now flushes RX fifo to prevent spurious FIQs
+ *   29-Feb-2000 - Buffer needs to be half-full after emptying to start DMA
+ *                 consumption of data. This helps prevent stuttering on
+ *                 startup.
+ *   08-Mar-2000 - Use new save_flags_clif() call to disable FIQs during buffer
+ *                 twiddling.
+ *   02-May-2000 - Added mute control (sets soft mute bit on pcm1716)
+ *   07-May-2000 - Added hard mute control (sets hardware mute bit)
+ *
+ *   Umar Qureshey <uqureshe@cs.ucr.edu>
+ *
+ *   29-Jul-2002 - Ported to Linux v2.4; removed empeg hardware dependent
+ *                 code i.e. mixer and DAC controls.
+ *   04-Aug-2002 - Changed save_flags_clif() calls into successive cli()
+ *                 and clf() calls because they're "standard" ARM Linux.
+ *   05-Aug-2002 - Implemented a new bottom-half code activation in the
+ *                 audio_7212dma.S file because the bottom-half calls kernel
+ *                 queue functions and was run before the FIQ handler code
+ *                 exited.  This crashed the kernel since kernel queue
+ *                 functions are not allowed in FIQ handler code (it would
+ *                 change an FIQ to an IRQ thus nullifying its advantage).
+ *                 Workaround to this issue is activating a normal IRQ in the
+ *                 FIQ handler and attaching the bottom-half code to that IRQ
+ *                 handler so as soon as the FIQ handler exits, the IRQ is
+ *                 executed with the bottom-half functionality.  To generate
+ *                 an IRQ, the TC1 timer is loaded with a value of 1 which
+ *                 effectively activates an IRQ in one clock cycle to be
+ *                 executed after the FIQ code exits.
+ *   22-Aug-2002 - Added GPL notice.  This software was originally
+ *                 distributed under GPL licensing.  Added player notice.
+ *
+ *	Petko Manolov <petkan@nucleusys.com>, http://www.nucleusys.com/
+ *
+ *   29-Jul-2003 - Modularizing the driver and writing exit routine.
+ *   31-Jul-2003 - Now the mono mode conversion is done in the fiq handler and
+ *                 check if it's size is greater than 0x1e4.
+ *                 Code cleanups, driver ported to edb7312.  The DAI clock
+ *                 source is now a config option.
+ *                 
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/major.h>
+#include <linux/errno.h>
+#include <linux/tqueue.h>
+#include <linux/wait.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/soundcard.h>
+#include <linux/delay.h>
+#include <asm/segment.h>
+#include <asm/irq.h>
+#include <asm/fiq.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/uaccess.h>
+#include <asm/hardware/clps7111.h>
+
+
+#define	DRIVER_AUTHOR	"Hugo Fiennes, Umar Qureshey and Petko Manolov"
+#define	DRIVER_DESC	"ep7212/ep7312 audio driver"
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL");
+
+#ifdef	CONFIG_PROC_FS
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+#endif
+
+#define	DSP_PURGE			1
+#undef	MIXER
+
+/*
+ * Debugging
+ */
+#if 0
+#define AUDIO_DEBUG			1
+#define AUDIO_DEBUG_VERBOSE		1
+#define AUDIO_DEBUG_STATS		1 /*AUDIO_DEBUG | AUDIO_DEBUG_VERBOSE*/
+#endif
+
+/*
+ * Constants
+ */
+
+/* Names */
+#define AUDIO_NAME			"audio-ep7212"
+#define AUDIO_NAME_VERBOSE		"empeg clps7212/edb7312 audio driver"
+#define AUDIO_VERSION_STRING		"Revision: 0.03"
+
+/* device numbers */
+#define AUDIO_MAJOR			(245)	//(EMPEG_AUDIO_MAJOR)
+#define AUDIO_NMINOR			(5)
+#define	MIXER_MINOR			(0)
+#define DSP_MINOR			(3)
+#define AUDIO_MINOR			(4)
+
+/* Client parameters */
+#define AUDIO_NOOF_BUFFERS		(32)	/* Number of audio buffers */
+/* NOTE! Need to move this to a header file as audio_7212dma needs this too */
+
+#define AUDIO_BUFFER_SIZE		(4608)	/* Size of user buffer chunks */
+
+/* Only EXTCLK mode works on the EDB7312. */
+#ifdef CONFIG_ARCH_EDB7312
+#define CONFIG_SOUND_EP7312_EXTCLK
+#endif
+
+extern int setup_cs43l42(void);
+
+/*
+ * Types
+ */
+
+/* statistics */
+typedef struct {
+	ulong samples;
+	ulong interrupts;
+	ulong wakeups;
+	ulong fifo_err;
+	ulong buffer_hwm;
+	ulong first_fills;
+	ulong below_halfs;
+} audio_stats;
+
+typedef struct {
+	/* Buffer */
+	unsigned char data[AUDIO_BUFFER_SIZE];
+} audio_buf;
+
+static int resid_size;
+static unsigned char resid_buf[AUDIO_BUFFER_SIZE];
+
+/* NOTE! This struct is accessed directly by audio_7212dma.S, and so the
+   order and type of the first 7 entries are critical and should not be
+   changed without appropriate modifications to the dma code */
+typedef struct {
+	/* Buffers */
+	volatile int used;	/* Do not move */
+	volatile int free;	/* Do not move */
+	volatile int head;	/* Do not move */
+	volatile int tail;	/* Do not move */
+	audio_buf *buffers;	/* Do not move */
+	volatile int mode;	/* Do not move */
+	int state;		/* Do not move: Is DMA enabled? */
+	audio_buf *zero;	/* Do not move */
+	volatile int vbase;
+
+	/* Stack for FIQ routine - not referenced by fiq code */
+	int *fiqstack;		/* now defunct; should be removed UQ */
+
+	/* Buffer management */
+	wait_queue_head_t waitq;
+
+	/* Statistics */
+	audio_stats stats;
+} audio_dev;
+
+/* Devices in the system; just the one channel at the moment */
+static audio_dev audio[1];
+static int sample_rate;
+static struct tq_struct emit_task;
+
+#ifdef CONFIG_PROC_FS
+static struct proc_dir_entry *proc_audio;
+static int audio_read_proc(char *buf, char **start, off_t offset, int length,
+			   int *eof, void *private)
+{
+	audio_dev *dev = &audio[0];
+
+	length = 0;
+	length += sprintf(buf + length, "buffers   : %d\n", AUDIO_NOOF_BUFFERS);
+	length += sprintf(buf + length, "buf size  : %d\n", AUDIO_BUFFER_SIZE);
+	length += sprintf(buf + length, "samples   : %ld\n", dev->stats.samples);
+	length += sprintf(buf + length, "interrupts: %ld\n", dev->stats.interrupts);
+	length += sprintf(buf + length, "wakeups   : %ld\n", dev->stats.wakeups);
+	length += sprintf(buf + length, "fifo errs : %ld\n", dev->stats.fifo_err);
+	length += sprintf(buf + length, "buffer hwm: %ld\n", dev->stats.buffer_hwm);
+	length += sprintf(buf + length, "first fill: %ld\n", dev->stats.first_fills);
+	length += sprintf(buf + length, "below half: %ld\n", dev->stats.below_halfs);
+
+	return (length);
+}
+
+#endif				/* CONFIG_PROC_FS */
+
+/* FIQ stuff */
+static struct fiq_handler fh = { NULL, "audiodma", NULL, NULL };
+extern char audio_7212_fiq, audio_7212_fiqend;
+
+void newbuffer(int irq, void *dev_id, struct pt_regs *regs)
+{
+	queue_task(&emit_task, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+}
+
+static void emit_action(void *p)
+{
+	audio_dev *dev = &audio[0];
+
+	/* If we have just dipped below halfway, note this */
+	if (dev->used == ((AUDIO_NOOF_BUFFERS / 2) - 1))
+		dev->stats.below_halfs++;
+
+	wake_up_interruptible(&audio[0].waitq);
+}
+
+/* ***** arbitrary size buffers ***** */
+static int audio_write(struct file *file, const char *buffer, size_t count,
+		       loff_t * ppos)
+{
+	audio_dev *dev = file->private_data;
+	int total = 0;
+	int local_buffer = 0;
+
+#if AUDIO_DEBUG_VERBOSE
+	printk(AUDIO_NAME
+	       ": audio_write: count=%d, used=%d free=%d head=%d tail=%d\n",
+	       count, dev->used, dev->free, dev->head, dev->tail);
+#endif
+
+	if (count <= 0) {
+		printk("ep7212_audio: %d byte write\n", count);
+		return 0;
+	}
+
+	/* Any space left? (No need to disable IRQs: we're just checking for
+	   a full buffer condition) */
+	if (dev->free == 0) {
+		if (file->f_flags & O_NONBLOCK) {
+			return (-EAGAIN);
+		}
+
+		while (dev->free < 8) {
+			/* next buffer full */
+			interruptible_sleep_on(&dev->waitq);
+		}
+	}
+
+	/* If we're filling an empty buffer, note this */
+	if (dev->used == 0)
+		dev->stats.first_fills++;
+
+	/* if we have a residual buffer, try and use that first */
+	if (resid_size > 0 && (resid_size + count) >= AUDIO_BUFFER_SIZE) {
+		int remaining;
+		unsigned long flags;
+
+		if (0)
+			printk("resid_size %d, count %d\n", resid_size, count);
+
+		/* grab a buffer */
+		save_flags(flags);
+		cli();
+		clf();
+		dev->free--;
+		restore_flags(flags);
+
+		/* use residual first */
+		memcpy(dev->buffers[dev->head].data, resid_buf, resid_size);
+
+		/* if there's space, fill from user's write */
+		if (resid_size < AUDIO_BUFFER_SIZE) {
+			remaining = AUDIO_BUFFER_SIZE - resid_size;
+
+			if (0)
+				printk("remaining %d\n", remaining);
+			if (local_buffer)
+				memcpy(dev->buffers[dev->head].data +
+				       resid_size, buffer, remaining);
+			else
+				copy_from_user(dev->buffers[dev->head].data +
+					       resid_size, buffer, remaining);
+
+			buffer += remaining;
+			count -= remaining;
+			total += remaining;
+		}
+//              fix_buffer(dev->buffers[dev->head].data);
+
+		dev->head++;
+		if (dev->head == AUDIO_NOOF_BUFFERS)
+			dev->head = 0;
+
+		dev->stats.samples += AUDIO_BUFFER_SIZE;
+		resid_size = 0;
+
+		/* buffer is ready, tell the FIQ section there's new data */
+		save_flags(flags);
+		cli();
+		clf();
+		dev->used++;
+		restore_flags(flags);
+	}
+
+	if (0)
+		printk("before loop, count %d\n", count);
+
+	while (dev->free < 8) {
+		/* next buffer full */
+		interruptible_sleep_on(&dev->waitq);
+	}
+
+	/* fill as many buffers as we can */
+	while (count >= AUDIO_BUFFER_SIZE) {
+		unsigned long flags;
+
+		if (dev->free == 0) {
+			if (file->f_flags & O_NONBLOCK) {
+				return total;
+			}
+
+			/* next buffer full */
+			interruptible_sleep_on(&dev->waitq);
+		}
+
+		/* Critical sections kept as short as possible to give good
+		   latency for other tasks: note we disable FIQs here too */
+		save_flags(flags);
+		cli();
+		clf();
+		dev->free--;
+		restore_flags(flags);
+
+		/* Copy chunk of data from user-space. We're safe updating the
+		   head when not in cli() as this is the only place the head gets  twiddled */
+		if (local_buffer)
+			memcpy(dev->buffers[dev->head++].data,
+			       buffer, AUDIO_BUFFER_SIZE);
+		else
+			copy_from_user(dev->buffers[dev->head++].data,
+				       buffer, AUDIO_BUFFER_SIZE);
+
+//              fix_buffer(dev->buffers[dev->head-1].data);
+
+		if (dev->head == AUDIO_NOOF_BUFFERS)
+			dev->head = 0;
+		total += AUDIO_BUFFER_SIZE;
+		dev->stats.samples += AUDIO_BUFFER_SIZE;
+		count -= AUDIO_BUFFER_SIZE;
+		buffer += AUDIO_BUFFER_SIZE;
+
+		/* buffer is ready, tell the FIQ section there's new data */
+		save_flags(flags);
+		cli();
+		clf();
+		dev->used++;
+		restore_flags(flags);
+	}
+
+	/* keep residual in a local buffer */
+	if (count > 0) {
+		if (0)
+			printk("tail count %d\n", count);
+
+		if (resid_size + count > AUDIO_BUFFER_SIZE)
+			count = AUDIO_BUFFER_SIZE - resid_size;
+
+		if (local_buffer)
+			memcpy(&resid_buf[resid_size], buffer, count);
+		else
+			copy_from_user(&resid_buf[resid_size], buffer, count);
+
+		resid_size += count;
+		total += count;
+	}
+
+	/* Update hwm */
+	if (dev->used > dev->stats.buffer_hwm)
+		dev->stats.buffer_hwm = dev->used;
+
+	/* If we were empty before, enable DMA if we have passed the half-full
+	   threshold */
+	if (dev->state == 0 && dev->used >= (AUDIO_NOOF_BUFFERS / 2))
+		dev->state = 1;
+
+	if (0)
+		printk("total %d\n", total);
+
+	/* Write complete */
+	return (total);
+}
+
+/* Throw away all complete blocks waiting to go out to the DAC and return how
+   many bytes that was. */
+static int audio_purge(audio_dev * dev)
+{
+	unsigned long flags;
+	int bytes;
+	struct pt_regs regs;
+
+	/* We don't want DMA to come in here! */
+	save_flags(flags);
+	cli();
+	clf();
+
+	/* Work out how many bytes are left to send to the audio device:
+	   we only worry about full buffers */
+	bytes = dev->used * AUDIO_BUFFER_SIZE;
+
+	/* Empty buffers */
+	dev->head = dev->tail = dev->used = 0;
+	dev->free = AUDIO_NOOF_BUFFERS - 1;
+
+	/* Stop DMA handler */
+	get_fiq_regs(&regs);
+	regs.ARM_fp = 0;	/* r11 */
+	regs.ARM_ip = 0;	/* r12 */
+	set_fiq_regs(&regs);
+
+	/* Let it run again */
+	restore_flags(flags);
+
+	return bytes;
+}
+
+#define DAI64FS		0x2600
+#define I2SF64		(1<<0)
+#define AUDCLKEN	(1<<1)
+#define AUDCLKSRC	(1<<2)
+#define MCLK256EN	(1<<3)
+#define LOOPBACK	(1<<5)
+#define	RATE_48K	(6<<8)
+#define RATE_44K	(2<<8)	/* assumes 11.2896Mhz external clock */
+#define	RATE_32K	(9<<8)
+#define	RATE_24K	(12<<8)
+#define RATE_22K	(4<<8)	/* assumes 11.2896Mhz external clock */
+#define	RATE_16K	(18<<8)
+#define	RATE_12K	(24<<8)
+#define RATE_11K	(8<<8)	/* assumes 11.2896Mhz external clock */
+#define	RATE_8K		(36<<8)
+#define	RATE_MASK	(0x7f<<8)
+
+static int set_sample_rate(int rate)
+{
+	int tmp;
+	
+	tmp = clps_readl(DAI64FS);
+	tmp &= ~RATE_MASK;
+
+	switch (rate) {
+#ifdef CONFIG_SOUND_EP7312_EXTCLK
+	case 44100:
+		clps_writel(tmp | RATE_44K, DAI64FS);
+		sample_rate = rate;
+		break;
+	case 22050:
+		clps_writel(tmp | RATE_22K, DAI64FS);
+		sample_rate = rate;
+		break;
+	case 11025:
+		clps_writel(tmp | RATE_11K, DAI64FS);
+		sample_rate = rate;
+		break;
+#else	
+	case 48000:
+		clps_writel(tmp | RATE_48K, DAI64FS);
+		sample_rate = rate;
+		break;
+	case 32000:
+		clps_writel(tmp | RATE_32K, DAI64FS);
+		sample_rate = rate;
+		break;
+	case 24000:
+		clps_writel(tmp | RATE_24K, DAI64FS);
+		sample_rate = rate;
+		break;
+	case 16000:
+		clps_writel(tmp | RATE_16K, DAI64FS);
+		sample_rate = rate;
+		break;
+	case 12000:
+		clps_writel(tmp | RATE_12K, DAI64FS);
+		sample_rate = rate;
+		break;
+	case 8000:
+		clps_writel(tmp | RATE_8K, DAI64FS);
+		sample_rate = rate;
+		break;
+#endif
+	default:
+		printk("unsupported sampling rate %d\n", rate);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int audio_ioctl(struct inode *inode, struct file *file, uint command,
+		       ulong arg)
+{
+	audio_dev *dev = file->private_data;
+	int val;
+
+	switch (command) {
+	case SNDCTL_DSP_RESET:
+		resid_size = 0;
+#ifdef AUDIO_DEBUG
+		printk("ep7212_audio: reset\n");
+#endif
+		return 0;
+
+	case SNDCTL_DSP_SYNC:
+		resid_size = 0;
+#ifdef AUDIO_DEBUG
+		printk("ep7212_audio: sync\n");
+#endif
+		return 0;
+
+	case SNDCTL_DSP_SPEED:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+#ifdef AUDIO_DEBUG
+		if (val >= 0) {
+			printk("ep7212_audio: set sample rate %d\n", val);
+		}
+#endif
+		if (val != 44100)
+			return 1;
+		else
+			return 0;
+		sample_rate = val;
+		set_sample_rate(sample_rate);
+		return put_user(sample_rate, (int *) arg);
+
+	case SNDCTL_DSP_SETFRAGMENT:
+		if (get_user(val, (long *) arg))
+			return -EFAULT;
+#ifdef AUDIO_DEBUG
+		printk("ep7212_audio: set frag 0x%08x\n", val);
+#endif
+		return 0;
+
+	case SNDCTL_DSP_SETFMT:	/* Selects ONE fmt */
+		if (get_user(val, (long *) arg))
+			return -EFAULT;
+#ifdef AUDIO_DEBUG
+		printk("ep7212_audio: set format 0x%08x\n", val);
+#endif
+		return 0;
+
+	case SNDCTL_DSP_CHANNELS:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val == 1)
+			dev->mode = 0;
+		else
+			dev->mode = 1;
+#ifdef AUDIO_DEBUG
+		printk("ep7212_audio: set channels %d (%d)\n", val, dev->mode);
+#endif
+		return 0;
+
+	case DSP_PURGE:
+		{
+			int bytes = audio_purge(dev);
+			put_user(bytes, (int *) arg);
+			return 0;
+		}
+	default:
+		/* invalid command */
+#ifdef AUDIO_DEBUG
+		printk("ep7212_audio: unhandled ioctl 0x%08x\n", command);
+#endif
+		return -EINVAL;
+	}
+}
+
+/* Open the audio device */
+static int audio_open(struct inode *inode, struct file *file)
+{
+	audio_dev *dev = &audio[0];
+
+#if AUDIO_DEBUG
+	printk(AUDIO_NAME ": audio_open\n");
+#endif
+
+	file->private_data = dev;
+	/* Flush buffer */
+	audio_purge(dev);
+
+	return (0);
+}
+
+/* Release the audio device */
+static int audio_release(struct inode *inode, struct file *file)
+{
+#if AUDIO_DEBUG
+	printk(AUDIO_NAME ": audio_release\n");
+#endif
+	return (0);
+}
+
+static struct file_operations audio_fops = {
+	write:	audio_write,
+	ioctl:	audio_ioctl,
+	open:	audio_open,
+	release:audio_release,
+};
+
+static int mixer_open(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static int mixer_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static int mixer_ioctl(struct inode *inode, struct file *file, uint command,
+		       ulong arg)
+{
+	return 0;
+}
+
+static struct file_operations mixer_fops = {
+	ioctl:	mixer_ioctl,
+	open:	mixer_open,
+	release:mixer_release,
+};
+
+
+static int generic_open_switch(struct inode *inode, struct file *file)
+{
+	/* select based on minor device number */
+	switch (MINOR(inode->i_rdev)) {
+	case AUDIO_MINOR:
+	case DSP_MINOR:
+		file->f_op = &audio_fops;
+		break;
+	case MIXER_MINOR:
+		file->f_op = &mixer_fops;
+		break;
+	default:
+		return (-ENXIO);
+	}
+
+	/* invoke specialized open */
+	return (file->f_op->open(inode, file));
+}
+
+static struct file_operations generic_fops = {
+	open: generic_open_switch,	/* switch for real open */
+};
+
+
+int __init audio_7212_init(void)
+{
+	audio_dev *dev = &audio[0];
+	struct pt_regs regs;
+	int err;
+	int timeout;
+
+	if ((&audio_7212_fiqend - &audio_7212_fiq) > 0x1e4) {
+		printk("the FIQ handler size is 0x%x, can't be greater than 0x%x\n",
+                       &audio_7212_fiqend - &audio_7212_fiq, 0x1e4);
+		return -EINVAL;
+	}
+#if AUDIO_DEBUG_VERBOSE
+	printk(AUDIO_NAME ": audio_7212_init\n");
+#endif
+	/* Blank everything to start with */
+	memset(dev, 0, sizeof (audio_dev));
+
+	init_waitqueue_head(&audio[0].waitq);
+
+	/* Allocate buffers: continuous in virtual memory is fine */
+	if ((dev->buffers =
+	     vmalloc(sizeof (audio_buf) * AUDIO_NOOF_BUFFERS)) == NULL) {
+		printk(KERN_CRIT "audio: can't get memory for buffers");
+	}
+	/*
+	 * We need one buffer which is just zeros, for outputting when
+	 * idle. This mirrors the behaviour of the empeg-car display driver
+	 */
+	if ((dev->zero = vmalloc(sizeof (audio_buf))) == NULL) {
+		printk(KERN_CRIT "audio: can't get memory for buffers");
+	}
+
+	/* Zero it */
+	memset(dev->zero, 0, sizeof (audio_buf));
+
+	/* Set up queue */
+	dev->head = dev->tail = dev->used = 0;
+	dev->free = AUDIO_NOOF_BUFFERS - 1;
+	dev->mode = 1;	/* stereo is the default mode */
+	dev->vbase = CLPS7111_VIRT_BASE;
+
+	/* Allocate fiq stack */
+
+	/* Setup callback */
+	emit_task.routine = emit_action;
+	emit_task.sync = 0;
+	emit_task.data = NULL;
+	if (request_irq(8, newbuffer, SA_INTERRUPT, "audio", NULL)) {
+		printk(KERN_CRIT "Unable to get interrupt 8!\n");
+		return -EBUSY;
+	}
+
+	/* Install DMA handler */
+	regs.ARM_r9 = (int) dev;
+	regs.ARM_r10 = CLPS7111_VIRT_BASE + 0x2000;
+	regs.ARM_fp = 0;	/* r11 */
+	regs.ARM_ip = 0;	/* r12 */
+	regs.ARM_sp = 0;
+	set_fiq_regs(&regs);
+	set_fiq_handler(&audio_7212_fiq, (&audio_7212_fiqend - &audio_7212_fiq));
+	if (claim_fiq(&fh)) {
+		printk(KERN_CRIT "Couldn't claim FIQ.\n");
+		return -1;
+	}
+
+	/* program for 64 F's */
+#ifdef CONFIG_SOUND_EP7312_EXTCLK
+	clps_writel(RATE_44K | I2SF64 | AUDCLKEN | AUDCLKSRC, DAI64FS);
+//      clps_writel(RATE_22K | I2SF64 | AUDCLKEN | AUDCLKSRC, DAI64FS);
+//      clps_writel(RATE_11K | I2SF64 | AUDCLKEN | AUDCLKSRC, DAI64FS);
+#else
+{
+	int tmp = clps_readl(DAI64FS);
+	tmp &= ~(RATE_MASK | 0xc);
+	clps_writel(tmp | RATE_32K | 8 | 2 | 1, DAI64FS);
+}
+#endif
+	/* Enable DAI interface */
+	clps_writel((clps_readl(SYSCON3) | SYSCON3_DAISEL) & ~SYSCON3_DAIEN,
+		    SYSCON3);
+
+	/* Enable I2S output: select external clock input (11.2896Mhz) */
+	clps_writel((0x0404 | DAIR_ECS | DAIR_RCTM), DAIR);
+
+	/* Clear error bits */
+	clps_writel(0xFFFFFFFF, DAISR);
+
+	/* Enable DAI */
+	clps_writel((clps_readl(DAIR) | DAIR_DAIEN), DAIR);
+	clps_writel(0x002b0404, DAIR);
+	/* Enable FIFOs */
+	timeout = jiffies + HZ;
+	while (!(clps_readl(DAISR) & DAISR_FIFO) && (jiffies < timeout));
+	clps_writel(0x000d8000, DAIDR2);
+	while (!(clps_readl(DAISR) & DAISR_FIFO) && (jiffies < timeout));
+	clps_writel(0x00118000, DAIDR2);
+	while (!(clps_readl(DAISR) & DAISR_FIFO) && (jiffies < timeout));
+	/* If this timed out, then there is a problem with the serial clock */
+	if (jiffies >= timeout) {
+		printk("Failed to initialise audio_7212: is SSI_CLK active?\n");
+	}
+	/* Unmask FIQ */
+	clps_writel((clps_readl(INTMR3) | (1 << 0)), INTMR3);
+	/* Register device */
+	if ((err =
+	     register_chrdev(AUDIO_MAJOR, AUDIO_NAME, &generic_fops)) != 0) {
+		/* Log error and fail */
+		printk(AUDIO_NAME ": unable to register major device %d\n",
+		       AUDIO_MAJOR);
+		return (err);
+	}
+	
+	setup_cs43l42();
+	
+#ifdef CONFIG_PROC_FS
+	/* Register procfs devices */
+	proc_audio = create_proc_entry("audio", 0, 0);
+	if (proc_audio)
+		proc_audio->read_proc = audio_read_proc;
+#endif				/* CONFIG_PROC_FS */
+	/* Log device registration */
+	printk(AUDIO_NAME_VERBOSE " initialized\n");
+	/* Everything OK */
+	return (0);
+}
+
+
+void __exit audio_7212_exit(void)
+{
+	audio_dev *dev = &audio[0];
+	
+	/*
+	 * first unmask DAIINT FIQ to avoid spontaneous crashes
+	 */
+	clps_writel((clps_readl(INTMR3) & ~1), INTMR3);
+	release_fiq(&fh);
+	free_irq(8, NULL);
+	vfree(dev->buffers);
+	vfree(dev->zero);
+	unregister_chrdev(AUDIO_MAJOR, AUDIO_NAME);
+}
+
+
+module_init(audio_7212_init);
+module_exit(audio_7212_exit);
diff -urN linux-2.4.29/drivers/sound/ep7212_audiodma.S linux-2.4.29-uc1/drivers/sound/ep7212_audiodma.S
--- linux-2.4.29/drivers/sound/ep7212_audiodma.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/sound/ep7212_audiodma.S	2005-06-14 02:12:05.000000000 +0100
@@ -0,0 +1,229 @@
+/*
+ * CL-PS7212/empeg Audio Device Driver - "DMA" (fiq!) section
+ *
+ * (C)2000 empeg ltd, http://www.empeg.com
+ *
+ * linux/drivers/char/ep7212_audiodma.S
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Authors:
+ *   Hugo Fiennes, <hugo@empeg.com>
+ *   Umar Qureshey, <uqureshey@cs.ucr.edu>
+ *   Petko Manolov, <petkan@nucleusys.com>
+ *
+ * Version history:
+ *   See ep7212_audio.c
+ */
+
+#if !defined (__ASSEMBLY__)
+#define	__ASSEMBLY__
+#endif
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#define	DO_MONO
+
+		.text
+
+.set		BUFFERS_USED,		0
+.set		BUFFERS_FREE,		4
+.set		BUFFERS_HEAD,		8
+.set		BUFFERS_TAIL,		12
+.set		BUFFERS_POINTER,	16
+.set		BUFFERS_MODE,		20
+.set		BUFFERS_STATE,		24
+.set		BUFFERS_ZERO,		28
+.set		BUFFERS_VBASE,		32
+.set		BUFFERS_COUNT,		32
+
+		.global	SYMBOL_NAME(audio_7212_fiqend)
+		.global SYMBOL_NAME(audio_7212_fiq)
+		
+audio_7212_fiq:
+		#   Everything here is designed for the quickest possible
+		#   "normal" fiq service, ie when we are filling from a known
+		#   buffer
+		#   r8  - scratch
+	        #   r9  - pointer to audio control structure
+		#   r10 - pointer to DAI registers (0xd0002000)
+		#   r11 - current player buffer
+		#   r12 - number of samples left in buffer
+		#   r13	- CPU base address (used to be stack pointer)
+
+		# Do we have data in the buffer?
+
+		cmp	r12,#0
+		beq	fiq_nextbuffer
+		
+newbuffers:	# Read four samples from the play buffer and write them to the
+		# DAI FIFO.
+#ifdef DO_MONO
+		ldr	r8, [r9, #BUFFERS_MODE]
+		cmp	r8, #0
+		mov	r13, #0
+		beq	mono
+#endif
+		ldr     r8,[r11],#4
+		str     r8,[r10,#0x0080]
+		mov	r8,r8,lsr#16
+		str     r8,[r10,#0x0040]
+
+		ldr     r8,[r11],#4
+		str     r8,[r10,#0x0080]
+		mov	r8,r8,lsr#16
+		str     r8,[r10,#0x0040]
+
+		ldr     r8,[r11],#4
+		str     r8,[r10,#0x0080]
+		mov	r8,r8,lsr#16
+		str     r8,[r10,#0x0040]
+
+		ldr     r8,[r11],#4
+		str     r8,[r10,#0x0080]
+		mov	r8,r8,lsr#16
+		str     r8,[r10,#0x0040]
+
+		# Decrement bytes left count
+		sub	r12,r12,#16
+mono_out0:
+		# Clear RX fifos (euck!)
+		ldr	r8,[r10,#0x0080]
+		ldr	r8,[r10,#0x0040]
+		ldr	r8,[r10,#0x0080]
+		ldr	r8,[r10,#0x0040]
+		ldr	r8,[r10,#0x0080]
+		ldr	r8,[r10,#0x0040]
+		ldr	r8,[r10,#0x0080]
+		ldr	r8,[r10,#0x0040]
+
+		mvn	r8,#0
+		str	r8,[r10,#0x0100]
+
+		# All done, return
+		subs	pc,lr,#4
+
+fiq_nextbuffer:
+
+		# Are we supposed to be consuming data yet?
+		ldr	r8,[r9,#BUFFERS_STATE]
+		cmp	r8,#0
+		beq	zerofill
+
+		# Check to see if there are any buffers left
+		ldr	r8,[r9,#BUFFERS_USED]
+		cmp	r8,#0
+		bne	fiq_nextbuffer1
+
+		# No buffers left; we are empty. Suspend playing until user
+		# task at least half-fills the audio buffer
+		mov	r8,#0
+		str	r8,[r9,#BUFFERS_STATE]
+
+zerofill:
+		# Load from zero buffer
+		ldr	r11,[r9,#BUFFERS_ZERO]
+		bal	fiq_newbuffer
+
+fiq_nextbuffer1:
+		# Twiddle buffer counts
+		sub	r8,r8,#1
+		str	r8,[r9,#BUFFERS_USED]
+		ldr	r8,[r9,#BUFFERS_FREE]
+		add	r8,r8,#1
+		str	r8,[r9,#BUFFERS_FREE]
+
+		# Get next buffer
+		ldr	r8,[r9,#BUFFERS_TAIL]
+		ldr	r11,[r9,#BUFFERS_POINTER]
+		add	r11,r11,r8,lsl#12	/* x4096 */
+		add	r11,r11,r8,lsl#9	/* x512 = 4608 */
+		add	r8,r8,#1
+		cmp	r8,#BUFFERS_COUNT
+		moveq	r8,#0
+		str	r8,[r9,#BUFFERS_TAIL]
+
+fiq_newbuffer:
+		# Buffer is now full
+		mov	r12,#4608
+#ifdef DO_MONO
+		ldr	r8, [r9, #BUFFERS_MODE]
+		cmp	r8, #0
+		mov	r13, #1
+		beq	mono
+#endif
+		ldr     r8,[r11],#4
+		str     r8,[r10,#0x0080]
+		mov	r8,r8,lsr#16
+		str     r8,[r10,#0x0040]
+
+		ldr     r8,[r11],#4
+		str     r8,[r10,#0x0080]
+		mov	r8,r8,lsr#16
+		str     r8,[r10,#0x0040]
+
+		ldr     r8,[r11],#4
+		str     r8,[r10,#0x0080]
+		mov	r8,r8,lsr#16
+		str     r8,[r10,#0x0040]
+
+		ldr     r8,[r11],#4
+		str     r8,[r10,#0x0080]
+		mov	r8,r8,lsr#16
+		str     r8,[r10,#0x0040]
+
+		sub	r12,r12,#16
+mono_out1:
+		# Clear RX fifos (euck!)
+		ldr	r8,[r10,#0x0080]
+		ldr	r8,[r10,#0x0040]
+		ldr	r8,[r10,#0x0080]
+		ldr	r8,[r10,#0x0040]
+		ldr	r8,[r10,#0x0080]
+		ldr	r8,[r10,#0x0040]
+		ldr	r8,[r10,#0x0080]
+		ldr	r8,[r10,#0x0040]
+
+		mvn	r8,#0
+		str	r8,[r10,#0x0100]
+
+		# Run bottom half (no need to save r4-r11)
+		#stmfd	r13!,{r0-r3,r12,r14}
+		#mov	r0,r9
+		#mov	lr,pc
+		#ldr	pc,[r9,#BUFFERS_CALL]
+		#ldmia	r13!,{r0-r3,r12,r14}
+
+
+		#Generate bottom-half IRQ
+		ldr	r13, [r9, #BUFFERS_VBASE]
+		ldr	r8, [r13, #0x0280]
+		orr	r8, r8, #0x100
+		str	r8, [r13, #0x0280]
+		str	r8, [r13, #0x06C0]
+		mov	r8, #1
+		str	r8, [r13, #0x0300]
+		
+		subs	pc,lr,#4
+		
+mono:
+		ldr	r8, [r11], #4
+		str	r8, [r10, #0x0080]
+		str	r8, [r10, #0x0040]
+		mov	r8, r8, lsr #16
+		str	r8, [r10, #0x0080]
+		str	r8, [r10, #0x0040]
+		ldr	r8, [r11], #4
+		str	r8, [r10, #0x0080]
+		str	r8, [r10, #0x0040]
+		mov	r8, r8, lsr #16
+		str	r8, [r10, #0x0080]
+		str	r8, [r10, #0x0040]
+
+		sub	r12, r12, #8
+		cmp	r13, #0
+		beq	mono_out0
+		b	mono_out1
+
+SYMBOL_NAME(audio_7212_fiqend):
diff -urN linux-2.4.29/drivers/sound/ep93xx-ac97.c linux-2.4.29-uc1/drivers/sound/ep93xx-ac97.c
--- linux-2.4.29/drivers/sound/ep93xx-ac97.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/sound/ep93xx-ac97.c	2005-06-14 02:12:05.000000000 +0100
@@ -0,0 +1,1277 @@
+/*
+ * Glue audio driver for the Cirrus EP93xx Ac97 Controller
+ *
+ * Copyright (c) 2003 Cirrus Logic Corp.
+ * Copyright (c) 2000 Nicolas Pitre <nico@cam.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ *
+ * This file taken from h3600-uda1341.c
+ * The mixer code is from ac97_codec.c
+ *
+ * History:
+ *
+ * 2000-05-21   Nicolas Pitre   Initial UDA1341 driver release.
+ *
+ * 2000-07-??   George France   Bitsy support.
+ *
+ * 2000-12-13   Deborah Wallach Fixed power handling for iPAQ/h3600
+ *
+ * 2001-06-03   Nicolas Pitre   Made this file a separate module, based on
+ *              the former sa1100-uda1341.c driver.
+ *
+ * 2001-07-13   Nicolas Pitre   Fixes for all supported samplerates.
+ *
+ * 2003-04-04   adt				Changes for Cirrus Logic EP93xx I2S
+ *
+ * 2003-04-25   adt				Changes for Cirrus Logic EP93xx Ac97
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/errno.h>
+#include <linux/sound.h>
+#include <linux/soundcard.h>
+#include <linux/bitops.h>
+
+#include <asm/semaphore.h>
+#include <asm/uaccess.h>
+#include <asm/hardware.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+
+#include "ep93xx-audio.h"
+
+
+#undef DEBUG
+//#define DEBUG 1
+#ifdef DEBUG
+#define DPRINTK( fmt, arg... )  printk( fmt, ##arg )
+#else
+#define DPRINTK( fmt, arg... )
+#endif
+
+
+#define AUDIO_NAME      "ep93xx_ac97"
+
+#define AUDIO_SAMPLE_RATE_DEFAULT   44100
+
+/* original check is not good enough in case FOO is greater than
+ * SOUND_MIXER_NRDEVICES because the supported_mixers has exactly
+ * SOUND_MIXER_NRDEVICES elements.
+ * before matching the given mixer against the bitmask in supported_mixers we
+ * check if mixer number exceeds maximum allowed size which is as mentioned
+ * above SOUND_MIXER_NRDEVICES */
+#define supported_mixer(FOO) \
+	( (FOO >= 0) && \
+	(FOO < SOUND_MIXER_NRDEVICES) && \
+	codec_supported_mixers & (1<<FOO) )
+
+/*
+ * Available record sources.  
+ * LINE1 refers to AUX in.  
+ * IGAIN refers to input gain which means stereo mix.
+ */
+#define AC97_RECORD_MASK \
+	(SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_IGAIN | SOUND_MASK_VIDEO |\
+	SOUND_MASK_LINE1 | SOUND_MASK_LINE | SOUND_MASK_PHONEIN)
+
+#define AC97_STEREO_MASK \
+	(SOUND_MASK_VOLUME | SOUND_MASK_PCM | SOUND_MASK_LINE | SOUND_MASK_CD | \
+	SOUND_MASK_ALTPCM | SOUND_MASK_IGAIN | SOUND_MASK_LINE1 | SOUND_MASK_VIDEO)
+
+#define AC97_SUPPORTED_MASK \
+	(AC97_STEREO_MASK | SOUND_MASK_BASS | SOUND_MASK_TREBLE | \
+	SOUND_MASK_SPEAKER | SOUND_MASK_MIC | \
+	SOUND_MASK_PHONEIN | SOUND_MASK_PHONEOUT)
+
+
+/* 
+ * Function prototypes.
+ */
+static int 		peek(unsigned int uiAddress);
+static int 		poke(unsigned int uiAddress, unsigned int uiValue);
+static void 	ep93xx_setup_src(void);
+static void 	ep93xx_set_samplerate( audio_stream_t * stream, long lSampleRate );
+static void 	ep93xx_init_ac97_codec( void );
+static void 	ep93xx_set_hw_format( audio_stream_t * stream, long format );
+static void	 	ep93xx_init_ac97_controller( void );
+static int 		ep93xx_mixer_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg);
+static void 	ep93xx_audio_init(void *dummy);
+static int 		ep93xx_audio_ioctl(struct inode *inode, struct file *file,
+				 uint cmd, ulong arg);
+static int 		ep93xx_audio_open(struct inode *inode, struct file *file);
+static int __init ep93xx_ac97_init(void);
+static void __exit ep93xx_ac97_exit(void);
+static void 	ep93xx_init_mixer(void);
+static void		ep93xx_audio_enable( audio_stream_t * stream );
+static void		ep93xx_audio_disable( audio_stream_t * stream );
+
+/*
+ * Statics
+ */
+static int ac_link_enabled = 0;
+static int codec_supported_mixers;
+
+/* this table has default mixer values for all OSS mixers. */
+typedef struct  {
+	int mixer;
+	unsigned int value;
+} mixer_defaults_t;
+
+/*
+ * Default mixer settings that are set up during boot.
+ *
+ * These values are 16 bit numbers in which the upper byte is right volume
+ * and the lower byte is left volume or mono volume for mono controls.
+ *
+ * OSS Range for each of left and right volumes is 0 to 100 (0x00 to 0x64).
+ * 
+ */
+static mixer_defaults_t mixer_defaults[SOUND_MIXER_NRDEVICES] = 
+{
+	/* Outputs */
+	{SOUND_MIXER_VOLUME,	0x6464},   /* 0 dB */  /* -46.5dB to  0 dB */
+	{SOUND_MIXER_ALTPCM,	0x6464},   /* 0 dB */  /* -46.5dB to  0 dB */
+	{SOUND_MIXER_PHONEOUT,	0x6464},   /* 0 dB */  /* -46.5dB to  0 dB */
+
+	/* PCM playback gain */
+	{SOUND_MIXER_PCM,		0x4b4b},   /* 0 dB */  /* -34.5dB to +12dB */
+
+	/* Record gain */
+	{SOUND_MIXER_IGAIN,		0x0000},   /* 0 dB */  /*    0 to +22.5 dB */
+
+	/* Inputs */
+	{SOUND_MIXER_MIC,		0x0000},   /* mute */  /* -34.5dB to +12dB */
+	{SOUND_MIXER_LINE,		0x4b4b},   /* 0 dB */  /* -34.5dB to +12dB */
+
+	/* Inputs that are not connected. */
+	{SOUND_MIXER_SPEAKER,	0x0000},   /* mute */  /* -45dB   to   0dB */
+	{SOUND_MIXER_PHONEIN,	0x0000},   /* mute */  /* -34.5dB to +12dB */
+	{SOUND_MIXER_CD,		0x0000},   /* mute */  /* -34.5dB to +12dB */
+	{SOUND_MIXER_VIDEO,		0x0000},   /* mute */  /* -34.5dB to +12dB */
+	{SOUND_MIXER_LINE1,		0x0000},   /* mute */  /* -34.5dB to +12dB */
+
+	{-1,0} /* last entry */
+};
+
+static unsigned int guiOSS_Volume[SOUND_MIXER_NRDEVICES];
+
+/* table to scale scale from OSS mixer value to AC97 mixer register value */	
+typedef struct {
+	unsigned int offset;
+	int scale;
+} ac97_mixer_hw_t; 
+
+static ac97_mixer_hw_t ac97_hw[SOUND_MIXER_NRDEVICES] = 
+{
+	[SOUND_MIXER_VOLUME]		=  	{AC97_02_MASTER_VOL,	64},
+	[SOUND_MIXER_BASS]			=	{0, 0},
+	[SOUND_MIXER_TREBLE]		=	{0, 0},
+	[SOUND_MIXER_SYNTH]			=  	{0,	0},
+	[SOUND_MIXER_PCM]			=  	{AC97_18_PCM_OUT_VOL,	32},
+	[SOUND_MIXER_SPEAKER]		=  	{AC97_0A_PC_BEEP_VOL,	32},
+	[SOUND_MIXER_LINE]			=  	{AC97_10_LINE_IN_VOL,	32},
+	[SOUND_MIXER_MIC]			=  	{AC97_0E_MIC_VOL,		32},
+	[SOUND_MIXER_CD]			=  	{AC97_12_CD_VOL,		32},
+	[SOUND_MIXER_IMIX]			=  	{0,	0},
+	[SOUND_MIXER_ALTPCM]		=  	{AC97_04_HEADPHONE_VOL,	64},
+	[SOUND_MIXER_RECLEV]		=  	{0,	0},
+	[SOUND_MIXER_IGAIN]			=  	{AC97_1C_RECORD_GAIN,	16},
+	[SOUND_MIXER_OGAIN]			=  	{0,	0},
+	[SOUND_MIXER_LINE1]			=  	{AC97_16_AUX_VOL,		32},
+	[SOUND_MIXER_LINE2]			=  	{0,	0},
+	[SOUND_MIXER_LINE3]			=  	{0,	0},
+	[SOUND_MIXER_DIGITAL1]		=  	{0,	0},
+	[SOUND_MIXER_DIGITAL2]		=  	{0,	0},
+	[SOUND_MIXER_DIGITAL3]		=  	{0,	0},
+	[SOUND_MIXER_PHONEIN]		=  	{AC97_0C_PHONE_VOL,		32},
+	[SOUND_MIXER_PHONEOUT]		=  	{AC97_06_MONO_VOL,		64},
+	[SOUND_MIXER_VIDEO]			=  	{AC97_14_VIDEO_VOL,		32},
+	[SOUND_MIXER_RADIO]			=  	{0,	0},
+	[SOUND_MIXER_MONITOR]		=  	{0,	0},
+};
+
+
+/* the following tables allow us to go from OSS <-> ac97 quickly. */
+enum ac97_recsettings 
+{
+	AC97_REC_MIC=0,
+	AC97_REC_CD,
+	AC97_REC_VIDEO,
+	AC97_REC_AUX,
+	AC97_REC_LINE,
+	AC97_REC_STEREO, /* combination of all enabled outputs..  */
+	AC97_REC_MONO,	      /*.. or the mono equivalent */
+	AC97_REC_PHONE
+};
+
+static const unsigned int ac97_rm2oss[] = 
+{
+	[AC97_REC_MIC] 	 = SOUND_MIXER_MIC,
+	[AC97_REC_CD] 	 = SOUND_MIXER_CD,
+	[AC97_REC_VIDEO] = SOUND_MIXER_VIDEO,
+	[AC97_REC_AUX] 	 = SOUND_MIXER_LINE1,
+	[AC97_REC_LINE]  = SOUND_MIXER_LINE,
+	[AC97_REC_STEREO]= SOUND_MIXER_IGAIN,
+	[AC97_REC_PHONE] = SOUND_MIXER_PHONEIN
+};
+
+/* indexed by bit position */
+static const unsigned int ac97_oss_rm[] = 
+{
+	[SOUND_MIXER_MIC] 	= AC97_REC_MIC,
+	[SOUND_MIXER_CD] 	= AC97_REC_CD,
+	[SOUND_MIXER_VIDEO] = AC97_REC_VIDEO,
+	[SOUND_MIXER_LINE1] = AC97_REC_AUX,
+	[SOUND_MIXER_LINE] 	= AC97_REC_LINE,
+	[SOUND_MIXER_IGAIN]	= AC97_REC_STEREO,
+	[SOUND_MIXER_PHONEIN] 	= AC97_REC_PHONE
+};
+
+static audio_stream_t ac97_output_stream0 =
+{
+	audio_num_channels: 	EP93XX_DEFAULT_NUM_CHANNELS,
+	audio_format: 			EP93XX_DEFAULT_FORMAT,
+	audio_stream_bitwidth: 	EP93XX_DEFAULT_BIT_WIDTH,
+	devicename:          	"Ac97_out",
+	dmachannel:				{ DMATx_AAC1, UNDEF, UNDEF },
+	sample_rate:			0,
+	hw_bit_width:			16,
+	bCompactMode:			1,
+};
+
+static audio_stream_t ac97_input_stream0 =
+{
+	audio_num_channels: 	EP93XX_DEFAULT_NUM_CHANNELS,
+	audio_format: 			EP93XX_DEFAULT_FORMAT,
+	audio_stream_bitwidth: 	EP93XX_DEFAULT_BIT_WIDTH,
+	devicename:           	"Ac97_in",
+	dmachannel:				{ DMARx_AAC1, UNDEF, UNDEF },
+	sample_rate:			0,
+	hw_bit_width:			16,
+	bCompactMode:			1,
+};
+
+static audio_hw_t ep93xx_ac97_hw =
+{
+	hw_enable:          ep93xx_audio_enable,
+	hw_disable:         ep93xx_audio_disable,
+	hw_clear_fifo:		0,
+	client_ioctl:       ep93xx_audio_ioctl,
+	
+	set_hw_serial_format:	ep93xx_set_hw_format,
+
+	txdmachannels:		{ DMATx_AAC1, DMATx_AAC2, DMATx_AAC3 },
+	rxdmachannels:		{ DMARx_AAC1, DMARx_AAC2, DMARx_AAC3 },
+	
+	MaxTxDmaChannels:	3,
+	MaxRxDmaChannels:	3,
+	
+	modcnt:				0,
+};
+
+static audio_state_t ac97_audio_state0 =
+{
+	output_stream:      &ac97_output_stream0,
+	input_stream:       &ac97_input_stream0,
+	sem:                __MUTEX_INITIALIZER(ac97_audio_state0.sem),
+	hw:					&ep93xx_ac97_hw,
+	wr_ref:				0,
+	rd_ref:				0,
+};
+
+
+/*
+ * peek
+ *
+ * Reads an AC97 codec register.  Returns -1 if there was an error.
+ */
+static int peek(unsigned int uiAddress)
+{
+	unsigned int uiAC97RGIS, uiTemp;
+	
+	if( !ac_link_enabled )
+	{
+		DPRINTK("ep93xx ac97 peek: attempt to peek before enabling ac-link.\n");
+		return -1;
+	}
+	
+	/*
+	 * Check to make sure that the address is aligned on a word boundary 
+	 * and is 7E or less.
+	 */
+	if( ((uiAddress & 0x1)!=0) || (uiAddress > 0x007e))
+	{
+		return -1;
+	}
+
+	/*
+	 * How it is supposed to work is:
+	 *  - The ac97 controller sends out a read addr in slot 1.
+	 *  - In the next frame, the codec will echo that address back in slot 1
+	 *    and send the data in slot 2.  SLOT2RXVALID will be set to 1.
+	 *
+	 * Read until SLOT2RXVALID goes to 1.  Reading the data in AC97S2DATA
+	 * clears SLOT2RXVALID.
+	 */
+
+	/*
+	 * First, delay one frame in case of back to back peeks/pokes.
+	 */
+	mdelay( 1 );
+
+	/*
+	 * Write the address to AC97S1DATA, delay 1 frame, read the flags.
+	 */
+	outl( uiAddress, AC97S1DATA);
+	uiTemp = inl(AC97GCR); /* read to push write out the wrapper */
+
+	udelay( 21 * 4 );
+	uiAC97RGIS = inl( AC97RGIS );
+
+	/*
+	 * Return error if we timed out.
+	 */
+	if( ((uiAC97RGIS & AC97RGIS_SLOT1TXCOMPLETE) == 0 ) &&
+		((uiAC97RGIS & AC97RGIS_SLOT2RXVALID) == 0 ) )
+	{
+		DPRINTK( "ep93xx-ac97 - peek failed reading reg 0x%02x.\n", uiAddress ); 
+		return -1;
+	}
+	
+	return ( inl(AC97S2DATA) & 0x000fffff);
+}
+
+/*
+ * poke
+ *
+ * Writes an AC97 codec Register.  Return -1 if error.
+ */
+static int poke(unsigned int uiAddress, unsigned int uiValue)
+{
+	unsigned int uiAC97RGIS, uiTemp;
+
+	if( !ac_link_enabled )
+	{
+		DPRINTK("ep93xx ac97 poke: attempt to poke before enabling ac-link.\n");
+		return -1;
+	}
+	
+	/*
+	 * Check to make sure that the address is align on a word boundary and
+	 * is 7E or less.  And that the value is a 16 bit value.
+	 */
+	if( ((uiAddress & 0x1)!=0) || (uiAddress > 0x007e))
+	{
+		return -1;
+	}
+	
+	/*
+	 * First, delay one frame in case of back to back peeks/pokes.
+	 */
+	mdelay( 1 );
+
+	/*
+	 * Write the data to AC97S2DATA, then the address to AC97S1DATA.
+	 */
+	outl( uiValue, AC97S2DATA );
+	outl( uiAddress, AC97S1DATA );
+	uiTemp = inl(AC97GCR); /* read to push writes out the wrapper */
+	
+	/*
+	 * Wait for the tx to complete, get status.
+	 */
+	udelay( 30 );
+	uiAC97RGIS = inl(AC97RGIS);
+
+	/*
+	 * Return error if we timed out.
+	 */
+	if( !(inl(AC97RGIS) & AC97RGIS_SLOT1TXCOMPLETE) )
+	{
+		DPRINTK( "ep93xx-ac97: poke failed writing reg 0x%02x  value 0x%02x.\n", uiAddress, uiValue ); 
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * When we get to the multichannel case the pre-fill and enable code
+ * will go to the dma driver's start routine.
+ */
+static void ep93xx_audio_enable( audio_stream_t * stream )
+{
+	unsigned int uiTemp;
+
+	DPRINTK("ep93xx_audio_enable\n");
+
+	/*
+	 * Enable the rx or tx channel
+	 */
+	if( stream->dmachannel[0] == DMATx_AAC1 )
+	{
+		uiTemp = inl(AC97TXCR1);
+		outl( (uiTemp | AC97TXCR_TEN), AC97TXCR1 );
+		uiTemp = inl(AC97TXCR1);
+	}
+	
+	if( stream->dmachannel[0] == DMARx_AAC1 )
+	{
+		uiTemp = inl(AC97RXCR1);
+		outl( (uiTemp | AC97RXCR_REN), AC97RXCR1 );
+		uiTemp = inl(AC97RXCR1);
+	}
+
+	//DPRINTK("ep93xx_audio_enable - EXIT\n");
+}
+
+static void ep93xx_audio_disable( audio_stream_t * stream )
+{
+	unsigned int uiControl, uiStatus;
+
+	DPRINTK("ep93xx_audio_disable\n");
+
+	/*
+	 * Disable the rx or tx channel
+	 */
+	if( stream->dmachannel[0] == DMATx_AAC1 )
+	{
+		uiControl = inl(AC97TXCR1);
+		if( uiControl & AC97TXCR_TEN )
+		{
+			/* 
+			 * Wait for fifo to empty.  We've shut down the dma
+			 * so that should happen soon.
+			 */
+			do {
+				uiStatus = inl( AC97SR1 );
+			} while( ((uiStatus & 0x82)==0) );
+			//} while( ((uiStatus & 0x20)!=0) ;&&
+					 //((uiStatus & 0x82)==0) );
+			
+			outl( (uiControl & ~AC97TXCR_TEN), AC97TXCR1 );
+			uiControl = inl(AC97TXCR1);
+		}
+	}
+
+	if( stream->dmachannel[0] == DMARx_AAC1 )
+	{
+		uiControl = inl(AC97RXCR1);
+		outl( (uiControl & ~AC97RXCR_REN), AC97RXCR1 );
+		uiControl = inl(AC97RXCR1);
+	}
+
+	//DPRINTK("ep93xx_audio_disable - EXIT\n");
+}
+
+/*
+ * ep93xx_setup_src
+ *
+ * Once the ac-link is up and all is good, we want to set the codec to a 
+ * usable mode.
+ */
+static void ep93xx_setup_src(void)
+{
+	int iTemp;
+
+	/*
+	 * Set the VRA bit to enable the SRC.
+	 */
+	iTemp = peek( AC97_2A_EXT_AUDIO_POWER );
+	poke( AC97_2A_EXT_AUDIO_POWER,  (iTemp | 0x1) );
+	
+	/*
+	 * Set the DSRC/ASRC bits to enable the variable rate SRC.
+	 */
+	iTemp = peek( AC97_60_MISC_CRYSTAL_CONTROL  );
+	poke( AC97_60_MISC_CRYSTAL_CONTROL, (iTemp  | 0x0300) );
+}
+
+/*
+ * ep93xx_set_samplerate
+ *
+ *   lFrequency		- Sample Rate in Hz
+ *   bTx			- 1 to set Tx sample rate
+ *   bRx			- 1 to set Rx sample rate
+ */
+static void ep93xx_set_samplerate( audio_stream_t * stream, long lSampleRate )
+{
+	unsigned short usDivider, usPhase;
+
+	DPRINTK( "ep93xx_set_samplerate - Fs = %d\n", (int)lSampleRate );
+
+	if( (lSampleRate <  7200) || (lSampleRate > 48000)  )
+	{
+		DPRINTK( "ep93xx_set_samplerate - invalid Fs = %d\n", 
+				 (int)lSampleRate );
+		return;
+	}
+
+	/*
+	 * Calculate divider and phase increment.
+	 *
+	 * divider = round( 0x1770000 / lSampleRate )
+	 *  Note that usually rounding is done by adding 0.5 to a floating 
+	 *  value and then truncating.  To do this without using floating
+	 *  point, I multiply the fraction by two, do the division, then add one, 
+	 *  then divide the whole by 2 and then truncate.
+	 *  Same effect, no floating point math.
+	 *
+	 * Ph incr = trunc( (0x1000000 / usDivider) + 1 )
+	 */
+
+#ifdef CONFIG_MACH_IPD
+	/* we have a different codec */
+	usPhase = 0;
+	if (stream->dmachannel[0] == DMATx_AAC1)
+		poke(AC97_2C_PCM_FRONT_DAC_RATE, lSampleRate);
+	else
+		poke(AC97_32_PCM_LR_ADC_RATE, lSampleRate);
+#else
+	usDivider = (unsigned short)( ((2 * 0x1770000 / lSampleRate) +  1) / 2 );
+
+	usPhase = (0x1000000 / usDivider) + 1;
+
+	/*
+	 * Write them in the registers.  Spec says divider must be
+	 * written after phase incr.
+	 */
+	if( stream->dmachannel[0] == DMATx_AAC1 )
+	{
+		poke( AC97_2C_PCM_FRONT_DAC_RATE, usDivider);
+		poke( AC97_64_DAC_SRC_PHASE_INCR, usPhase);
+	}
+
+	if( stream->dmachannel[0] == DMARx_AAC1 )
+	{
+		
+		poke( AC97_32_PCM_LR_ADC_RATE,  usDivider);
+		poke( AC97_66_ADC_SRC_PHASE_INCR, usPhase);
+	}
+#endif
+	
+	DPRINTK( "ep93xx_set_samplerate - phase = %d,  divider = %d\n",
+				(unsigned int)usPhase, (unsigned int)usDivider );
+
+	/*
+	 * We sorta should report the actual samplerate back to the calling
+	 * application.  But some applications freak out if they don't get
+	 * exactly what they asked for.  So we fudge and tell them what
+	 * they want to hear.
+	 */
+	stream->sample_rate = lSampleRate;
+
+	DPRINTK( "ep93xx_set_samplerate - EXIT\n" );
+}
+
+/*
+ * ep93xx_set_hw_format
+ *
+ * Sets up whether the controller is expecting 20 bit data in 32 bit words
+ * or 16 bit data compacted to have a stereo sample in each 32 bit word.
+ */
+static void ep93xx_set_hw_format( audio_stream_t * stream, long format )
+{
+	int bCompactMode, uiTemp, iWidth;
+	unsigned long ulRegValue;
+	
+	switch( format )
+	{
+		/*
+		 * Here's all the <=16 bit formats.  We can squeeze both L and R
+		 * into one 32 bit sample so use compact mode.
+		 */
+		case AFMT_U8:		   
+		case AFMT_S8:		   
+		case AFMT_S16_LE:
+		case AFMT_U16_LE:
+			bCompactMode = 1;
+			ulRegValue = 0x00008018;
+			iWidth = 16;
+			break;
+
+		/*
+		 * Add any other >16 bit formats here...
+		 */
+		case AFMT_S32_BLOCKED:
+		default:
+			bCompactMode = 0;
+			ulRegValue = 0x00004018;
+			iWidth = 20;
+			break;
+	}
+	
+	if( stream->dmachannel[0] == DMARx_AAC1 )
+	{
+		uiTemp = inl( AC97RXCR1 );
+		if( ulRegValue != uiTemp )
+		{
+			outl( ulRegValue, AC97RXCR1 );
+			uiTemp = inl( AC97RXCR1 );
+		} 
+		stream->hw_bit_width = iWidth;
+		stream->bCompactMode = bCompactMode;
+	}
+	
+	if( stream->dmachannel[0] == DMATx_AAC1 )
+	{
+		uiTemp = inl( AC97TXCR1 );
+		if( ulRegValue != uiTemp )
+		{
+			outl( ulRegValue, AC97TXCR1 );
+			uiTemp = inl( AC97TXCR1 );
+		}
+		stream->hw_bit_width = iWidth;
+		stream->bCompactMode = bCompactMode;
+	}
+	
+}
+
+/*
+ * ep93xx_init_ac97_controller
+ *
+ * This routine sets up the Ac'97 Controller.
+ */
+static void ep93xx_init_ac97_controller(void)
+{
+	unsigned int uiDEVCFG, uiTemp;
+
+	DPRINTK("ep93xx_init_ac97_controller - enter\n");
+
+	/*
+	 * Configure the multiplexed Ac'97 pins to be Ac97 not I2s.
+	 * Configure the EGPIO4 and EGPIO6 to be GPIOS, not to be  
+	 * SDOUT's for the second and third I2S controller channels.
+	 */
+	uiDEVCFG = inl(SYSCON_DEVCFG);
+	
+	uiDEVCFG &= ~(SYSCON_DEVCFG_I2SonAC97 | 
+				  SYSCON_DEVCFG_A1onG |
+				  SYSCON_DEVCFG_A2onG);
+		
+	SysconSetLocked(SYSCON_DEVCFG, uiDEVCFG);
+
+	/*
+	 * Disable the AC97 controller internal loopback.  
+	 * Disable Override codec ready.
+	 */
+	outl( 0, AC97GCR );
+
+	/*
+	 * Enable the AC97 Link.
+	 */
+	uiTemp = inl(AC97GCR);
+	outl( (uiTemp | AC97GSR_IFE), AC97GCR );
+	uiTemp = inl(AC97GCR); /* read to push write out the wrapper */
+
+	/*
+	 * Set the TIMEDRESET bit.  Will cause a > 1uSec reset of the ac-link.
+	 * This bit is self resetting.
+	 */
+	outl( AC97RESET_TIMEDRESET, AC97RESET );
+	uiTemp = inl(AC97GCR); /* read to push write out the wrapper */
+	
+	/*
+	 *  Delay briefly, but let's not hog the processor.
+	 */
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout( 5 ); /* 50 mSec */
+
+	/*
+	 * Read the AC97 status register to see if we've seen a CODECREADY
+	 * signal from the AC97 codec.
+	 */
+	if( !(inl(AC97RGIS) & AC97RGIS_CODECREADY))
+	{
+		DPRINTK( "ep93xx-ac97 - FAIL: CODECREADY still low!\n");
+		return;
+	}
+
+	/*
+	 *  Delay for a second, not hogging the processor
+	 */
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout( HZ ); /* 1 Sec */
+	
+	/*
+	 * Now the Ac-link is up.  We can read and write codec registers.
+	 */
+	ac_link_enabled = 1;
+
+	/*
+	 * Set up the rx and tx channels
+	 * Set the CM bit, data size=16 bits, enable tx slots 3 & 4.
+	 */
+	ep93xx_set_hw_format( &ac97_output_stream0, EP93XX_DEFAULT_FORMAT );
+	ep93xx_set_hw_format( &ac97_input_stream0, EP93XX_DEFAULT_FORMAT );
+
+	DPRINTK( "ep93xx-ac97 -- AC97RXCR1:  %08x\n", inl(AC97RXCR1) ); 
+	DPRINTK( "ep93xx-ac97 -- AC97TXCR1:  %08x\n", inl(AC97TXCR1) ); 
+
+	DPRINTK("ep93xx_init_ac97_controller - EXIT - success\n");
+
+}
+
+/*
+ * ep93xx_init_ac97_codec
+ *
+ * Program up the external Ac97 codec.
+ *
+ */
+static void ep93xx_init_ac97_codec( void )
+{
+	DPRINTK("ep93xx_init_ac97_codec - enter\n");
+
+	ep93xx_setup_src();
+	ep93xx_set_samplerate( &ac97_output_stream0, AUDIO_SAMPLE_RATE_DEFAULT );
+	ep93xx_set_samplerate( &ac97_input_stream0,  AUDIO_SAMPLE_RATE_DEFAULT );
+	ep93xx_init_mixer();
+
+	DPRINTK("ep93xx_init_ac97_codec - EXIT\n");
+	
+}
+
+#ifdef DEBUG
+static void ep93xx_dump_ac97_regs(void)
+{
+	int i;
+	unsigned int reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7;
+	
+	DPRINTK( "---------------------------------------------\n");
+	DPRINTK( "   :   0    2    4    6    8    A    C    E\n" ); 
+	
+	for( i=0 ; i < 0x80 ; i+=0x10 )
+	{
+		reg0 = 0xffff & (unsigned int)peek( i );
+		reg1 = 0xffff & (unsigned int)peek( i + 0x2 );
+		reg2 = 0xffff & (unsigned int)peek( i + 0x4 );
+		reg3 = 0xffff & (unsigned int)peek( i + 0x6 );
+		reg4 = 0xffff & (unsigned int)peek( i + 0x8 );
+		reg5 = 0xffff & (unsigned int)peek( i + 0xa );
+		reg6 = 0xffff & (unsigned int)peek( i + 0xc );
+		reg7 = 0xffff & (unsigned int)peek( i + 0xe );
+
+		DPRINTK( " %02x : %04x %04x %04x %04x %04x %04x %04x %04x\n", 
+				 i, reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7);
+	}
+}
+#endif
+
+static void ep93xx_set_volume
+(
+	unsigned int oss_channel, 
+	unsigned int oss_val 
+) 
+{
+	unsigned int left,right;
+	u16 val = 0;
+	ac97_mixer_hw_t * mh = &ac97_hw[oss_channel];
+
+	if( !mh->scale )
+	{
+		DPRINTK( "ep93xx-ac97.c: ep93xx_set_volume - not a valid OSS channel\n");
+		return;
+	}
+
+	/* cleanse input a little */
+	right = ((oss_val >> 8)  & 0xff) ;
+	left = (oss_val  & 0xff) ;
+
+	if (right > 100) right = 100;
+	if (left > 100) left = 100;
+
+	DPRINTK("ac97_codec: wrote OSS channel#%2d (ac97 reg 0x%02x), "
+	       "l:%2d, r:%2d:",
+	       oss_channel, mh->offset, left, right);
+
+	if( AC97_STEREO_MASK & (1 << oss_channel) ) 
+	{
+		/* stereo mixers */
+		if (oss_channel == SOUND_MIXER_IGAIN) 
+		{
+			right = ((100 - right) * (mh->scale - 1)) / 100;
+			left =  ((100 - left)  * (mh->scale - 1)) / 100;
+			if (right >= mh->scale)
+				right = mh->scale-1;
+			if (left >= mh->scale)
+				left = mh->scale-1;
+			right = (mh->scale - 1) - right;
+			left  = (mh->scale - 1) - left;
+			val = (left << 8) | right;
+		}
+		else 
+		{
+			if (left == 0 && right == 0) 
+			{
+				val = 0x8000;
+			} 
+			else
+			{
+				right = ((100 - right) * (mh->scale - 1)) / 100;
+				left =  ((100 - left)  * (mh->scale - 1)) / 100;
+				if (right >= mh->scale)
+					right = mh->scale-1;
+				if (left >= mh->scale)
+					left = mh->scale-1;
+				val = (left << 8) | right;
+			}
+		}
+	} 
+	else if(left == 0) 
+	{
+		val = 0x8000;
+	} 
+	else if( (oss_channel == SOUND_MIXER_SPEAKER) ||
+			(oss_channel == SOUND_MIXER_PHONEIN) ||
+			(oss_channel == SOUND_MIXER_PHONEOUT) )
+	{
+		left = ((100 - left) * (mh->scale - 1)) / 100;
+		if (left >= mh->scale)
+			left = mh->scale-1;
+		val = left;
+	} 
+	else if (oss_channel == SOUND_MIXER_MIC) 
+	{
+		val = peek( mh->offset) & ~0x801f;
+		left = ((100 - left) * (mh->scale - 1)) / 100;
+		if (left >= mh->scale)
+			left = mh->scale-1;
+		val |= left;
+	} 
+	/*  
+	 * For bass and treble, the low bit is optional.  Masking it
+	 * lets us avoid the 0xf 'bypass'.
+	 * Do a read, modify, write as we have two contols in one reg. 
+	 */
+	else if (oss_channel == SOUND_MIXER_BASS) 
+	{
+		val = peek( mh->offset) & ~0x0f00;
+		left = ((100 - left) * (mh->scale - 1)) / 100;
+		if (left >= mh->scale)
+			left = mh->scale-1;
+		val |= (left << 8) & 0x0e00;
+	} 
+	else if (oss_channel == SOUND_MIXER_TREBLE) 
+	{
+		val = peek( mh->offset) & ~0x000f;
+		left = ((100 - left) * (mh->scale - 1)) / 100;
+		if (left >= mh->scale)
+			left = mh->scale-1;
+		val |= left & 0x000e;
+	}
+	
+	DPRINTK(" 0x%04x", val);
+
+	poke( mh->offset, val );
+
+#ifdef DEBUG
+	val = peek( mh->offset );
+	DPRINTK(" (read back 0x%04x)\n", val);
+#endif
+
+	guiOSS_Volume[oss_channel] = oss_val;
+}
+
+static void ep93xx_init_mixer(void)
+{
+	u16 cap, oldcap;
+	int i;
+
+	/* mixer masks */
+	codec_supported_mixers 	= AC97_SUPPORTED_MASK;
+	
+	cap = peek( AC97_00_RESET );
+	/* We wait for this setting to stabilise a little */
+	oldcap = cap?0:1;
+	for (i=0; oldcap != cap && i < 10; i++) {
+		oldcap = cap;
+		mdelay( 10 );
+		cap = peek( AC97_00_RESET );
+	}
+	if (i == 10)
+		printk( KERN_INFO "ep93xx_init_mixer cap didn't settle.\n");
+	if( !(cap & 0x04) )
+	{
+		codec_supported_mixers &= ~(SOUND_MASK_BASS|SOUND_MASK_TREBLE);
+	}
+	if( !(cap & 0x10) )
+	{
+		codec_supported_mixers &= ~SOUND_MASK_ALTPCM;
+	}
+
+	/* 
+	 * Detect bit resolution of output volume controls by writing to the
+	 * 6th bit (not unmuting yet)
+	 */
+	poke( AC97_02_MASTER_VOL, 0xa020 );
+	if( peek( AC97_02_MASTER_VOL) != 0xa020 )
+	{
+		ac97_hw[SOUND_MIXER_VOLUME].scale = 32;
+	}
+
+	poke( AC97_04_HEADPHONE_VOL, 0xa020 );
+	if( peek( AC97_04_HEADPHONE_VOL) != 0xa020 )
+	{
+		ac97_hw[AC97_04_HEADPHONE_VOL].scale = 32;
+	}
+
+	poke( AC97_06_MONO_VOL, 0x8020 );
+	if( peek( AC97_06_MONO_VOL) != 0x8020 )
+	{
+		ac97_hw[AC97_06_MONO_VOL].scale = 32;
+	}
+
+	/* initialize mixer channel volumes */
+	for( i = 0; 
+		(i < SOUND_MIXER_NRDEVICES) && (mixer_defaults[i].mixer != -1) ; 
+		i++ ) 
+	{
+		if( !supported_mixer( mixer_defaults[i].mixer) )
+		{ 
+			continue;
+		}
+		
+		ep93xx_set_volume( mixer_defaults[i].mixer, mixer_defaults[i].value);
+	}
+
+}
+
+/*
+ * ac97_recmask_io
+ *
+ * Read or write the record source.
+ */
+static int ep93xx_read_recsource(void) 
+{
+	unsigned int val;
+
+	/* read it from the card */
+	val = peek( AC97_1A_RECORD_SELECT );
+	
+	DPRINTK("ac97_codec: ac97 recmask to set to 0x%04x\n", val);
+	
+	return( 1 << ac97_rm2oss[val & 0x07] );
+}
+
+static int ep93xx_set_recsource( int mask ) 
+{
+	unsigned int val;
+
+	/* Arg contains a bit for each recording source */
+	if( mask == 0 ) 
+	{
+		return 0;
+	}
+	
+	mask &= AC97_RECORD_MASK;
+	
+	if( mask == 0 ) 
+	{
+		return -EINVAL;
+	}
+				
+	/*
+	 * May have more than one bit set.  So clear out currently selected
+	 * record source value first (AC97 supports only 1 input) 
+	 */
+	val = (1 << ac97_rm2oss[peek( AC97_1A_RECORD_SELECT ) & 0x07]);
+	if (mask != val)
+	    mask &= ~val;
+       
+	val = ffs(mask); 
+	val = ac97_oss_rm[val-1];
+	val |= val << 8;  /* set both channels */
+
+	DPRINTK("ac97_codec: setting ac97 recmask to 0x%04x\n", val);
+
+	poke( AC97_1A_RECORD_SELECT, val);
+
+	return 0;
+}
+
+static int 
+ep93xx_mixer_open(struct inode *inode, struct file *file)
+{
+	file->private_data = &ep93xx_ac97_hw;
+	return 0;
+}
+
+static int 
+ep93xx_mixer_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static int
+ep93xx_mixer_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
+{
+	int val, nr;
+
+	audio_hw_t * hw = (audio_hw_t *)file->private_data;
+
+	DPRINTK("ep93xx_mixer_ioctl - enter.  IOC_TYPE is %c \n", _IOC_TYPE(cmd) );
+
+	if (cmd == SOUND_MIXER_INFO) 
+	{
+		mixer_info info;
+		strncpy(info.id, "CS4202", sizeof(info.id));
+		strncpy(info.name, "Cirrus CS4202", sizeof(info.name));
+		info.modify_counter = hw->modcnt;
+		if (copy_to_user((void *)arg, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+	if( cmd == SOUND_OLD_MIXER_INFO ) 
+	{
+		_old_mixer_info info;
+		strncpy(info.id, "CS4202", sizeof(info.id));
+		strncpy(info.name, "Cirrus CS4202", sizeof(info.name));
+		if (copy_to_user((void *)arg, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+
+	if( (_IOC_TYPE(cmd) != 'M') || (_SIOC_SIZE(cmd) != sizeof(int)) )
+		return -EINVAL;
+	
+	if( cmd == OSS_GETVERSION )
+		return put_user(SOUND_VERSION, (int *)arg);
+	
+	nr = _IOC_NR(cmd);
+
+	if( _SIOC_DIR(cmd) == _SIOC_READ ) 
+	{
+		switch( nr ) 
+		{
+			case SOUND_MIXER_RECSRC: 
+				/* Read the current record source */
+				val = ep93xx_read_recsource();
+				break;
+
+			case SOUND_MIXER_DEVMASK: 
+				/* give them the supported mixers */
+				val = codec_supported_mixers;
+				break;
+
+			case SOUND_MIXER_RECMASK: 
+				/* Arg contains a bit for each supported recording source */
+				val = AC97_RECORD_MASK;
+				break;
+
+			case SOUND_MIXER_STEREODEVS: 
+				/* Mixer channels supporting stereo */
+				val = AC97_STEREO_MASK;
+				break;
+
+			case SOUND_MIXER_CAPS:
+				val = SOUND_CAP_EXCL_INPUT;
+				break;
+
+			default: 
+				if( !supported_mixer( nr ) )
+					return -EINVAL;
+				
+			    val = guiOSS_Volume[nr];
+	 			break;
+		
+		} /* switch */
+		
+		return put_user(val, (int *)arg);
+	}
+
+	if( _SIOC_DIR(cmd) == (_SIOC_WRITE|_SIOC_READ) ) 
+	{
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		
+		switch( nr ) 
+		{
+			case SOUND_MIXER_RECSRC: 
+				return ep93xx_set_recsource( val );
+			
+			default: 
+				if( !supported_mixer( nr ) )
+					return -EINVAL;
+				
+				ep93xx_set_volume( nr, val );
+				hw->modcnt++;
+				return 0;
+		}
+	}
+	
+	return -EINVAL;
+}
+
+static struct file_operations h3600_mixer_fops = 
+{
+	owner:		THIS_MODULE,
+	llseek:		no_llseek,
+	ioctl:		ep93xx_mixer_ioctl,
+	open:		ep93xx_mixer_open,
+	release:	ep93xx_mixer_release,
+};
+
+
+/*
+ * Audio interface
+ */
+static void ep93xx_audio_init(void *dummy)
+{
+	DPRINTK("ep93xx_audio_init - enter\n");
+	
+	/*
+	 * Init the controller, enable the ac-link.
+	 * Initialize the codec.
+	 */
+	ep93xx_init_ac97_controller();
+	ep93xx_init_ac97_codec();
+	
+#ifdef DEBUG
+	ep93xx_dump_ac97_regs();
+#endif
+
+	DPRINTK("ep93xx_audio_init - EXIT\n");
+}
+
+static int ep93xx_audio_ioctl(struct inode *inode, struct file *file,
+				 uint cmd, ulong arg)
+{
+	audio_state_t *state = (audio_state_t *)file->private_data;
+	audio_stream_t *os = state->output_stream;
+	audio_stream_t *is = state->input_stream;
+	long val;
+	int ret = 0;
+
+	/*
+	 * These are platform dependent ioctls which are not handled by the
+	 * generic ep93xx-audio module.
+	 */
+	switch (cmd) 
+	{
+		case SNDCTL_DSP_SPEED:
+			
+			DPRINTK("ep93xx_audio_ioctl - SNDCTL_DSP_SPEED\n");
+			
+			if (get_user(val, (int *)arg))
+			{
+				return -EFAULT;
+			}
+			
+			if( (file->f_mode & FMODE_WRITE) &&
+				(val != os->sample_rate) )
+			{
+				ep93xx_set_samplerate( os, val );
+			}
+			if( (file->f_mode & FMODE_READ) &&
+				(val != is->sample_rate) )
+			{
+				ep93xx_set_samplerate( is, val );
+			}
+			
+			return put_user( val, (long *) arg );
+
+		case SOUND_PCM_READ_RATE:
+			DPRINTK("ep93xx_audio_ioctl - SOUND_PCM_READ_RATE\n");
+			if( file->f_mode & FMODE_WRITE )
+			{
+				return put_user( os->sample_rate, (long *) arg);
+			}
+			return put_user( is->sample_rate, (long *) arg);
+
+		default:
+			DPRINTK("ep93xx_audio_ioctl-->ep93xx_mixer_ioctl\n");
+			/* Maybe this is meant for the mixer (As per OSS Docs) */
+			return ep93xx_mixer_ioctl(inode, file, cmd, arg);
+	}
+
+	return ret;
+}
+
+static int ep93xx_audio_open(struct inode *inode, struct file *file)
+{
+	DPRINTK( "ep93xx_audio_open\n" );
+
+#ifdef CONFIG_MACH_IPD
+{
+	static int initted = 0;
+	if (!initted) {
+		/* set GPIO0/1 on to enable audio amp left&right*/
+		poke(0x78, 0xabba);
+		poke(0x74, peek(0x74) & ~0x0001);
+		poke(0x3e, 0x81);
+		poke(0x4c, 0x00);
+		poke(0x4e, 0x00);
+		poke(0x50, 0x03);
+		poke(0x52, 0x00);
+		poke(0x54, 0x03);
+		poke(0x3e, 0x01);
+		initted = 1;
+	}
+}
+#endif
+
+	return ep93xx_audio_attach( inode, file, &ac97_audio_state0 );
+}
+
+/*
+ * Missing fields of this structure will be patched with the call
+ * to ep93xx_audio_attach().
+ */
+static struct file_operations h3600_audio_fops = 
+{
+	open:       ep93xx_audio_open,
+	owner:      THIS_MODULE
+};
+
+
+static int audio_dev_id, mixer_dev_id;
+
+static int __init ep93xx_ac97_init(void)
+{
+	DPRINTK("ep93xx_ac97_init - enter\n");
+	
+	/*
+	 * Enable audio early on, give the DAC time to come up.
+	 */ 
+	ep93xx_audio_init( 0 );
+
+	/* 
+	 * Register devices using sound_core.c's devfs stuff
+	 */
+	audio_dev_id = register_sound_dsp(&h3600_audio_fops, -1);
+	if( audio_dev_id < 0 )
+	{
+		DPRINTK(" ep93xx_ac97_init: register_sound_dsp failed for dsp.\n" );
+		return -ENODEV;
+	}
+	
+	mixer_dev_id = register_sound_mixer(&h3600_mixer_fops, -1);
+	if( mixer_dev_id < 0 )
+	{
+		DPRINTK(" ep93xx_ac97_init: register_sound_dsp failed for mixer.\n" );
+		return -ENODEV;
+	}
+
+	printk( KERN_INFO "EP93xx Ac97 audio support initialized.\n" );
+	return 0;
+}
+
+static void __exit ep93xx_ac97_exit(void)
+{
+	unregister_sound_dsp( audio_dev_id );
+	unregister_sound_mixer( mixer_dev_id );
+}
+
+module_init(ep93xx_ac97_init);
+module_exit(ep93xx_ac97_exit);
+
+MODULE_DESCRIPTION("Audio driver for the Cirrus EP93xx Ac97 controller.");
+
+/* EXPORT_NO_SYMBOLS; */
diff -urN linux-2.4.29/drivers/sound/ep93xx-audio.c linux-2.4.29-uc1/drivers/sound/ep93xx-audio.c
--- linux-2.4.29/drivers/sound/ep93xx-audio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/sound/ep93xx-audio.c	2005-06-14 02:12:04.000000000 +0100
@@ -0,0 +1,2922 @@
+/*
+ * ep93xx-audio.c
+ *
+ * Common audio handling for the Cirrus EP93xx processor.
+ *
+ * Copyright (c) 2003 Cirrus Logic Corp.
+ * Copyright (C) 2000, 2001 Nicolas Pitre <nico@cam.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ *
+ * Taken from sa1100-audio.c
+ *
+ * This module handles the generic buffering/DMA/mmap audio interface for
+ * codecs connected to the EP93xx chip.  All features depending on specific
+ * hardware implementations like supported audio formats or samplerates are
+ * relegated to separate specific modules.
+ *
+ *
+ * History:
+ *
+ * 2000-05-21	Nicolas Pitre	Initial release.
+ *
+ * 2000-06-10	Erik Bunce	Add initial poll support.
+ *
+ * 2000-08-22	Nicolas Pitre	Removed all DMA stuff. Now using the
+ * 				generic SA1100 DMA interface.
+ *
+ * 2000-11-30	Nicolas Pitre	- Validation of opened instances;
+ * 				- Power handling at open/release time instead
+ * 				  of driver load/unload;
+ *
+ * 2001-06-03	Nicolas Pitre	Made this file a separate module, based on
+ * 				the former sa1100-uda1341.c driver.
+ *
+ * 2001-07-22	Nicolas Pitre	- added mmap() and realtime support
+ * 				- corrected many details to better comply
+ * 				  with the OSS API
+ *
+ * 2001-10-19	Nicolas Pitre	- brought DMA registration processing
+ * 				  into this module for better ressource
+ * 				  management.  This also fixes a bug
+ * 				  with the suspend/resume logic.
+ *
+ * 2003-04-04   Adapted for EP93xx I2S/Ac97 audio.
+ *
+ * 2004-04-23	Added support for multiple stereo streams.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/pm.h>
+#include <linux/errno.h>
+#include <linux/sound.h>
+#include <linux/soundcard.h>
+#include <linux/sysrq.h>
+#include <linux/delay.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/semaphore.h>
+#include <asm/arch/dma.h>
+
+#include "ep93xx-audio.h"
+
+#undef DEBUG 
+// #define DEBUG 1
+#ifdef DEBUG
+#define DPRINTK( fmt, arg... )  printk( fmt, ##arg )
+#else
+#define DPRINTK( fmt, arg... )
+#endif
+
+/* Mostly just prints what ioctls got called */
+/* #define DEBUG 1 */
+#ifdef DEBUG
+#define DPRINTK_IOCTL( fmt, arg... )  printk( fmt, ##arg )
+#else
+#define DPRINTK_IOCTL( fmt, arg... )
+#endif
+
+/*
+ * Experiencing gaps in your audio?  Try upping the AUDIO_NBFRAGS_DEFAULT!
+ */
+#ifdef CONFIG_SOUND_EP93XX_AC97
+#ifdef CONFIG_MACH_IPD
+#define AUDIO_NBFRAGS_DEFAULT	64		/* we don't that much memory */
+#else
+#define AUDIO_NBFRAGS_DEFAULT	128
+#endif
+#define AUDIO_FRAGSIZE_DEFAULT	16384	/* max is 65536 */
+#define AUDIO_NBFRAGS_MAX		128	
+#else
+#define AUDIO_NBFRAGS_DEFAULT	32
+#define AUDIO_FRAGSIZE_DEFAULT	65536	/* max is 65536 */
+#define AUDIO_NBFRAGS_MAX		32	
+#endif
+
+/*
+ * NEXT_BUF
+ *
+ * Translates to:
+ * 		stream->dma_buffer_index++;
+ * 		stream->dma_buffer_index %= stream->nbfrags;
+ *		stream->dma_buffer = stream->buffers + stream->dma_buffer_index;
+ *
+ * So stream->dma_buffer always points to the stream->dma_buffer_index-nth element 
+ * of stream->buffers.
+ */
+#define NEXT_BUF(_s_,_b_) { \
+	(_s_)->_b_##_index++; \
+	(_s_)->_b_##_index %= (_s_)->nbfrags; \
+	(_s_)->_b_ = (_s_)->buffers + (_s_)->_b_##_index; }
+
+#define AUDIO_ACTIVE(state)	((state)->rd_ref || (state)->wr_ref)
+
+/* Function prototypes */
+static __inline__ int copy_to_user_with_conversion
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	int toCount 
+);
+static __inline__ int copy_from_user_with_conversion
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	int toCount 
+);
+
+static void audio_dma_start( audio_state_t * state, audio_stream_t * stream );
+static void audio_dma_pause( audio_state_t * state, audio_stream_t * stream );
+static void audio_prime_dma( audio_state_t * state, audio_stream_t * stream );
+
+/*
+ *  calculate_dma2usr_ratio_etc()
+ *
+ *  For audio playback, we convert samples of arbitrary format to be 32 bit 
+ *  for our hardware. We're scaling a user buffer to a dma buffer.  So when
+ *  report byte counts, we scale them acording to the ratio of DMA sample
+ *  size to user buffer sample size.  When we report # of DMA fragments,
+ *  we don't scale that.  So:
+ *   - The fragment size the app sees  = (stream->fragsize/stream->dma2usr_ratio)
+ *   - The # of fragments the app sees = stream->nbfrags
+ *
+ *	User sample type can be stereo/mono/8/16/32 bit.  
+ *  DMA sample type will be either CM (compact mode) where two 16 bit 
+ *  samples together in a 32 bit word become a stereo sample or non-CM 
+ *  where each channel gets a 32 bit word.
+ *
+ *  Any time usr sample type changes, we need to call this function.
+ *
+ *  Also adjust the size and number of dma fragments if sample size changed.
+ *
+ *  Input format       Input sample     Output sample size    ratio (out:in)
+ *  bits   channels    size (bytes)       CM   non-CM          CM   non-CM
+ *   8       mono          1               4      8            4:1   8:1
+ *   8      stereo         2			   4      8            2:1   4:1
+ *   16      mono          2			   4      8            2:1   4:1
+ *   16     stereo         4			   4      8            1:1   2:1
+ *
+ *   24      mono          3			   4      8             X    8:3 not a real case
+ *   24     stereo         6			   4      8             X    8:6 not a real case
+ *   32      mono          4			   4      8             X    2:1
+ *   32     stereo         8			   4      8             X    1:1
+ *
+ */
+static void calculate_dma2usr_ratio_etc( audio_stream_t * stream )
+{
+	unsigned int dma_sample_size, user_sample_size;
+	
+	if( stream->bCompactMode )
+		dma_sample_size = 4;	/* each stereo sample is 2 * 16 bits */
+	else
+		dma_sample_size = 8;	/* each stereo sample is 2 * 32 bits */
+	
+	if( stream->audio_num_channels != 1 )
+	{
+		// If stereo 16 bit, user sample is 4 bytes.
+		// If stereo  8 bit, user sample is 2 bytes.
+		user_sample_size = stream->audio_stream_bitwidth / 4;
+	}
+	else
+	{
+		// If mono 16 bit, user sample is 2 bytes.
+		// If mono  8 bit, user sample is 1 bytes.
+		user_sample_size = stream->audio_stream_bitwidth / 8;
+	}
+
+	/*
+	 * dma2usr_ratio = (4 or 8) / (4, 2, or 1) = 8, 4, 2, or 1
+	 */
+	stream->dma2usr_ratio = dma_sample_size / user_sample_size;
+
+	DPRINTK(" samplesize: dma %d  user %d  dma/usr ratio  %d\n",
+		dma_sample_size, user_sample_size, stream->dma2usr_ratio );
+	DPRINTK(" requested: fragsize %d  num frags %d  total bytes %d  total samples %d\n", 
+		stream->requested_fragsize, stream->requested_nbfrags,
+		stream->requested_fragsize * stream->requested_nbfrags,
+		(stream->requested_fragsize * stream->requested_nbfrags) / user_sample_size );
+	DPRINTK(" usr      : fragsize %d  num frags %d  total bytes %d  total samples %d\n", 
+		(stream->fragsize / stream->dma2usr_ratio),  stream->nbfrags,
+		stream->fragsize * stream->nbfrags / stream->dma2usr_ratio,
+		(stream->fragsize * stream->nbfrags) / (stream->dma2usr_ratio * user_sample_size) );
+	DPRINTK(" dma:       fragsize %d  num frags %d  total bytes %d  total samples %d\n", 
+		stream->fragsize,  stream->nbfrags,
+		stream->fragsize * stream->nbfrags,
+		(stream->fragsize * stream->nbfrags) / dma_sample_size );
+		
+}
+
+/*
+ * audio_deallocate_buffers
+ * 
+ * This function frees all buffers
+ */
+static void audio_deallocate_buffers( audio_state_t * state, audio_stream_t * stream )
+{
+	int frag, i;
+	
+	DPRINTK("EP93xx - audio_deallocate_buffers\n");
+
+	/* ensure DMA won't run anymore */
+	audio_dma_pause( state, stream );
+	stream->active = 0;
+	stream->stopped = 0;
+
+	for( i=0 ; i < stream->NumDmaChannels ; i++ )
+		ep93xx_dma_flush( stream->dmahandles[i] );
+	
+	if (stream->buffers) 
+	{
+		for (frag = 0; frag < stream->nbfrags; frag++) 
+		{
+			if (!stream->buffers[frag].master)
+			{
+				continue;
+			}
+
+			consistent_free(stream->buffers[frag].start,
+					stream->buffers[frag].master,
+					stream->buffers[frag].dma_addr);
+		}
+
+		/*
+		 * Free the space allocated to the array of dma_buffer structs.
+		 */
+		kfree(stream->buffers);
+		stream->buffers = NULL;
+	}
+
+	stream->buffered_bytes_to_play = 0;
+	stream->dma_buffer_index = 0;
+	stream->dma_buffer = NULL;
+	stream->bytecount = 0;
+	stream->getptrCount = 0;
+	stream->fragcount = 0;
+
+	DPRINTK("EP93xx - audio_deallocate_buffers - EXIT\n");
+}
+
+
+/*
+ * audio_allocate_buffers
+ *
+ * This function allocates the buffer structure array and buffer data space
+ * according to the current number of fragments and fragment size.
+ * Note that the output_stream and input_stream structs are allocated
+ * in ep93xx-ac97.c or ep93xx-i2s.c.
+ */
+static int audio_allocate_buffers( audio_state_t * state, audio_stream_t * stream )
+{
+	int frag;
+	int dmasize = 0;
+	char *dmabuf = NULL;
+	dma_addr_t dmaphys = 0;
+	int buf_num = 0;
+
+	if (stream->buffers)
+		return -EBUSY;
+
+	DPRINTK("EP93xx audio_allocate_buffers\n" );
+	
+	/*
+	 * Allocate space for the array of audio_buf_t structs.
+	 */
+	stream->buffers = (audio_buf_t *)
+		kmalloc(sizeof(audio_buf_t) * stream->nbfrags, GFP_KERNEL);
+
+	if (!stream->buffers)
+	{
+		DPRINTK( "ep93xx-audio: unable to allocate audio memory\n ");
+		audio_deallocate_buffers( state, stream );
+		return -ENOMEM;
+	}
+
+	/*
+	 * If the audio app hasn't requested a specific fragsize and nbfrags,
+	 * we stay with our default.
+	 */
+	if ((stream->requested_fragsize!=0) && (stream->requested_nbfrags!=0)) {
+		/*
+		 * Adjust the fragsize to take into account how big actual samples in
+		 * the dma buffer are.	Max dma buf size is 64K.
+		 */
+		stream->fragsize = stream->requested_fragsize * stream->dma2usr_ratio;
+	}
+	
+	if (stream->fragsize > 65536)
+		stream->fragsize = 65536;
+	if (stream->fragsize < 8192)
+		stream->fragsize = 8192;
+
+	/*
+	 * Adjust num of frags so we have as many samples of buffer as were requested
+	 * even if the fragment size changed.
+	 */
+	if ((stream->requested_fragsize!=0) && (stream->requested_nbfrags!=0)) {
+	  	stream->nbfrags = 
+	  		(stream->requested_fragsize * stream->requested_nbfrags * stream->dma2usr_ratio)
+	  		 / stream->fragsize;
+	}
+	
+	if (stream->nbfrags < 2)
+		stream->nbfrags = 2;
+	if (stream->nbfrags > AUDIO_NBFRAGS_MAX)
+		stream->nbfrags = AUDIO_NBFRAGS_MAX;
+
+	memset( stream->buffers, 0, sizeof(audio_buf_t) * stream->nbfrags );
+
+	/*
+	 * Let's allocate non-cached memory for DMA buffers.
+	 * We try to allocate all memory at once.
+	 * If this fails (a common reason is memory fragmentation),
+	 * then we allocate more smaller buffers.
+	 */
+	for (frag = 0; frag < stream->nbfrags; frag++) 
+	{
+		audio_buf_t * dma_buffer = &stream->buffers[frag];
+
+		if (!dmasize) 
+		{
+			/*
+			 * First try to allocate enough for all the frags that
+			 * don't yet have memory allocated.
+			 */
+			dmasize = (stream->nbfrags - frag) * stream->fragsize;
+			do {
+			  	dmabuf = consistent_alloc(GFP_KERNEL|GFP_DMA,
+							  dmasize, &dmaphys);
+				
+				/* 
+				 * If that fails, try to allocate a chunk of memory
+				 * that is one less fragment is size.
+				 */
+				if (!dmabuf)
+					dmasize -= stream->fragsize;
+
+			  /* 
+			   * Keep trying but the minimum we'll attempt is one 
+			   * fragment.  If we can't even get that, give up.
+			   */
+			} while (!dmabuf && dmasize);
+		
+			/*
+			 * If we do fail to allocate enough for all the frags, 
+			 * deallocate whatever we did get and quit.
+			 */
+			if (!dmabuf)
+			{
+				DPRINTK( "ep93xx-audio: unable to allocate audio memory\n ");
+				audio_deallocate_buffers( state, stream );
+				return -ENOMEM;
+			}
+
+			DPRINTK("EP93xx allocated %d bytes:  dmabuf=0x%08x  dmaphys=0x%08x\n",
+					dmasize, (int)dmabuf, (int)dmaphys );
+			
+			/*
+			 * Success!	 Save the size of this chunk to use when we deallocate it.
+			 */
+			dma_buffer->master = dmasize;
+			memzero(dmabuf, dmasize);
+		}
+
+		/*
+		 * Save the start address of the dma_buffer fragment.
+		 * We know the size of the fragment is fragsize.
+		 */
+		dma_buffer->start = dmabuf;
+		dma_buffer->dma_addr = dmaphys;
+		dma_buffer->stream = stream;
+		dma_buffer->size = 0;
+		dma_buffer->sent = 0;
+		dma_buffer->num  = buf_num++;
+
+		sema_init( &dma_buffer->sem, 1 );
+
+		/*
+		 * Now if we only allocated the minimal one frag of space, the
+		 * dmasize will be ==0 after this subtraction so it will allocate more
+		 * for the next frag.  Otherwise, the next time(s) thru this for loop
+		 * will dole out frag sized pieces of this big master chunk.
+		 */
+		dmabuf  += stream->fragsize;
+		dmaphys += stream->fragsize;
+		dmasize -= stream->fragsize;
+	}
+
+	/*
+	 * Initialize the stream.
+	 */
+	stream->buffered_bytes_to_play = 0;
+	stream->dma_buffer_index = 0;	/* Init the current buffer index. 			*/
+	stream->dma_buffer = &stream->buffers[0];	/* Point dma_buffer to the current buffer struct. 	*/
+	stream->bytecount = 0;
+	stream->getptrCount = 0;
+	stream->fragcount = 0;
+
+	DPRINTK("EP93xx audio_allocate_buffers -- exit SUCCESS\n" );
+	return 0;
+
+}
+
+
+/*
+ * audio_reset_buffers
+ *
+ * This function stops and flushes the dma, gets all buffers back
+ * from the DMA driver and resets them ready to be used again.
+ */
+static void audio_reset_buffers( audio_state_t * state, audio_stream_t * stream )
+{
+	int frag, i;
+
+	audio_dma_pause( state, stream );
+	stream->active = 0;
+	stream->stopped = 0;
+
+	for( i=0 ; i < stream->NumDmaChannels ; i++ )
+		ep93xx_dma_flush( stream->dmahandles[i] );
+
+	if (stream->buffers) 
+	{
+		for (frag = 0; frag < stream->nbfrags; frag++) 
+		{
+			audio_buf_t * dma_buffer = &stream->buffers[frag];
+			dma_buffer->size = 0;
+			dma_buffer->sent = 0;
+			sema_init( &dma_buffer->sem, 1 );
+		}
+	}
+
+	stream->buffered_bytes_to_play = 0;
+	stream->bytecount = 0;
+	stream->getptrCount = 0;
+	stream->fragcount = 0;
+}
+
+
+/*
+ * DMA callback functions
+ */
+static void audio_dma_tx_callback
+( 
+	ep93xx_dma_int_t DMAInt,
+	ep93xx_dma_dev_t device, 
+	unsigned int user_data 
+)
+{
+	unsigned int buf_id;
+	int handle, i;
+	
+	audio_state_t * state = (audio_state_t *)user_data;
+	audio_stream_t * stream = state->output_stream;
+	
+ 	/* DPRINTK( "audio_dma_tx_callback - %s\n", stream->devicename ); */
+	
+	/*
+	 * Get the DMA handle that corresponds to the dma channel
+	 * that needs servicing.  A multichannel audio stream will
+	 * have a DMA handle for each stereo pair that it uses.
+	 */
+	for( i=0 ; ( i < stream->NumDmaChannels ) && ( stream->dmachannel[i] != device ) ; i++ );
+	handle = stream->dmahandles[i];
+
+  	if (stream->mapped)
+	{
+		/*
+		 * If we are mapped, get one dma buffer back and recycle it.
+		 */
+		if( ep93xx_dma_remove_buffer( handle, &buf_id ) >= 0 )
+		{
+		   	audio_buf_t * dma_buffer = (audio_buf_t *)buf_id;
+
+	/*	DPRINTK( "audio_dma_tx_callback  - got dma buffer index=%d\n", buf_id); */
+		
+			/* Accounting */
+			stream->buffered_bytes_to_play -= dma_buffer->size;
+			
+			/* bytecount and fragcount will overflow */
+			stream->bytecount += dma_buffer->size;
+			if (stream->bytecount < 0)
+				stream->bytecount = 0;
+			
+			stream->fragcount++;
+			if (stream->fragcount < 0)
+				stream->fragcount = 0;
+				
+			dma_buffer->size = 0;
+		
+			/* Recycle dma buffer */
+		 	dma_buffer->size = stream->fragsize;
+			
+			ep93xx_dma_add_buffer( handle, 				/* dma instance 		*/
+								   (unsigned int)dma_buffer->dma_addr, /* source 		*/
+								   0, 					/* dest 				*/
+								   stream->fragsize,	/* size					*/
+								   0,					/* is the last chunk? 	*/
+								   (unsigned int) dma_buffer ); /* buf id			 	*/	
+	  		
+			dma_buffer->sent = 1;
+		}
+	}
+	else
+	{
+		/*
+		 * Get all buffers that are free'ed back and clear their semephores.
+		 */
+		while( ep93xx_dma_remove_buffer( handle, &buf_id ) >= 0 )
+		{
+		   	audio_buf_t *dma_buffer = (audio_buf_t *)buf_id;
+
+	/*	DPRINTK( "audio_dma_tx_callback  - got dma buffer index=%d\n", buf_id); */
+		
+			/* Accounting */
+			stream->buffered_bytes_to_play -= dma_buffer->size;
+
+			stream->bytecount += dma_buffer->size;
+			if (stream->bytecount < 0)
+				stream->bytecount = 0;
+			
+			stream->fragcount++;
+			if (stream->fragcount < 0)
+				stream->fragcount = 0;
+
+			dma_buffer->size = 0;
+			dma_buffer->sent = 0;
+			
+			/*
+			 * Release the semaphore on this dma_buffer.
+			 * If write is waiting on this dma_buffer then it can go 
+			 * ahead and fill it and send it to the dma.
+			 */
+			up(&dma_buffer->sem);
+		}
+	}
+
+	/* And any process polling on write. */
+	wake_up(&stream->wq);
+}
+
+static void audio_dma_rx_callback
+( 
+	ep93xx_dma_int_t DMAInt,
+	ep93xx_dma_dev_t device, 
+	unsigned int user_data 
+)
+{
+	unsigned int buf_id;
+	int handle, i;
+	
+	audio_state_t * state = (audio_state_t *)user_data;
+	audio_stream_t * stream = state->input_stream;
+
+	//DPRINTK("audio_dma_rx_callback\n");
+	
+	/*
+	 * Get the DMA handle that corresponds to the dma channel
+	 * that needs servicing.  A multichannel audio stream will
+	 * have a DMA handle for each stereo pair that it uses.
+	 */
+	for( i=0 ; ( i < stream->NumDmaChannels ) && ( stream->dmachannel[i] != device ) ; i++ );
+	handle = stream->dmahandles[i];
+	
+	/*
+	 * Keep removing and recycling buffers as long as there are buffers
+	 * to remove.
+	 */
+	while( !ep93xx_dma_remove_buffer( handle, &buf_id ) )
+	{
+	   	audio_buf_t *dma_buffer = (audio_buf_t *) buf_id;
+
+		/* Accounting */
+		stream->bytecount += stream->fragsize;
+		if (stream->bytecount < 0)
+			stream->bytecount = 0;
+
+		stream->fragcount++;
+		if (stream->fragcount < 0)
+			stream->fragcount = 0;
+
+		/* Recycle dma buffer */
+		if( stream->mapped ) 
+		{
+		 	ep93xx_dma_add_buffer( handle,			 	/* dma instance 		*/
+								   (unsigned int) dma_buffer->dma_addr, /* source 		*/
+								   0, 					/* dest 				*/
+								   stream->fragsize,	/* size					*/
+								   0,					/* is the last chunk? 	*/
+								   (unsigned int) dma_buffer ); /* buf id			 	*/	
+		} 
+		else 
+		{
+			dma_buffer->size = stream->fragsize;
+			up(&dma_buffer->sem);
+		}
+
+		/* And any process polling on write. */
+		wake_up(&stream->wq);
+	}
+}
+
+/*
+ * audio_sync
+ *
+ * Wait until the last byte written to this device has been played.
+ */
+static int audio_sync(struct file *file)
+{
+	audio_state_t *state = (audio_state_t *)file->private_data;
+	audio_stream_t * stream = state->output_stream;
+	audio_buf_t * dma_buffer;
+	int buf_wait_index;
+
+	DPRINTK( "audio_sync - enter\n" );
+
+	if (!(file->f_mode & FMODE_WRITE) || !stream->buffers || stream->mapped)
+	{
+		DPRINTK( "audio_sync - exit immediately.\n" );
+		return 0;
+	}
+	
+	/*
+	 * Send current dma buffer if it contains data and hasn't been sent. 
+	 */
+	dma_buffer = stream->dma_buffer;
+	
+	if( dma_buffer->size && !dma_buffer->sent ) 
+	{
+		DPRINTK("audio_sync -- SENDING BUFFER index=%d size=%d\n",
+				stream->dma_buffer_index, dma_buffer->size );
+		
+		down(&dma_buffer->sem);
+	 	ep93xx_dma_add_buffer( stream->dmahandles[0],				/* dma instance 		*/
+							   (unsigned int)dma_buffer->dma_addr, 	/* source 		*/
+							   0, 									/* dest 				*/
+							   dma_buffer->size,					/* size					*/
+							   0,									/* is the last chunk? 	*/
+							   (unsigned int) dma_buffer ); 		/* dma_buffer id			 	*/	
+	 	dma_buffer->sent = 1;
+		NEXT_BUF(stream, dma_buffer);
+	}
+
+	/*
+	 * Let's wait for the last dma buffer we sent i.e. the one before the
+	 * current dma_buffer_index.  When we acquire the semaphore, this means either:
+	 * - DMA on the buffer completed or
+	 * - the buffer was already free thus nothing else to sync.
+	 */
+	buf_wait_index = ((stream->nbfrags + stream->dma_buffer_index - 1) % stream->nbfrags);
+	dma_buffer = stream->buffers + buf_wait_index;
+
+	DPRINTK("audio_sync - waiting on down_interruptible\n");
+	if (down_interruptible(&dma_buffer->sem))
+	{
+		DPRINTK("audio_sync - EXIT - down_interruptible\n");
+		return -EINTR;
+	}
+	
+	up(&dma_buffer->sem);
+	
+	DPRINTK("audio_sync - EXIT\n");
+	return 0;
+}
+
+//static int iWriteCount = 0;
+
+/*
+ * Need to convert to 32 bit stereo format:	  
+ * 16 bit signed
+ * 16 bit unsigned
+ *  8 bit signed
+ *  8 bit unsigned
+ */
+static int audio_write
+(
+	struct file 	*file, 
+	const char 		*user_buffer,
+	size_t 			src_count, 
+	loff_t 			*ppos
+)
+{
+	const char * user_buffer_start = user_buffer;
+	audio_state_t * state = (audio_state_t *)file->private_data;
+	audio_stream_t * stream = state->output_stream;
+	unsigned int dma_xfer_count, src_xfer_count, expanded_count; 
+	int ret = 0;
+//	int i,j;
+	
+ 	/* DPRINTK_IOCTL( "EP93xx - audio_write: count=%d\n", src_count ); */
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+		
+	if (stream->mapped)
+		return -ENXIO;
+		
+	if( !access_ok( VERIFY_READ, user_buffer, src_count ) )
+	{
+		DPRINTK( "access_ok failed for audio_write!!!!\n" );
+		return -EFAULT;
+	}
+
+	/*
+	 * Allocate dma buffers if we haven't already done so.
+	 */
+	if( !stream->buffers && audio_allocate_buffers( state, stream ) )
+		return -ENOMEM;
+
+//	if( iWriteCount > 40 )
+//	{
+//		for( i=0; i<4 ; i++ )
+//		{
+//			for( j=0; j<8 ; j++ )
+//			{
+//				printk("%02x ", user_buffer[(i*8)+j] );
+//			}
+//			printk("\n");
+//		}
+//		iWriteCount = 0;
+//	}
+//	iWriteCount++;
+	
+	/*
+	 * Stay in this loop until we have copied all of the file
+	 * into user memory.
+	 */
+	while( src_count > 0 ) 
+	{
+		audio_buf_t *dma_buffer = stream->dma_buffer;
+
+		/* Wait for a dma buffer to become free */
+		if (file->f_flags & O_NONBLOCK)
+		{
+			ret = -EAGAIN;
+			if (down_trylock(&dma_buffer->sem))
+				break;
+		} 
+		else 
+		{
+			ret = -ERESTARTSYS;
+			if (down_interruptible(&dma_buffer->sem))
+				break;
+		}
+
+		/* 
+		 * Feed the current dma buffer (stream->dma_buffer) 
+		 * This involves expanding sample size from the user_buffer
+		 * to be 32 bit stereo for our dma.
+		 */
+		
+		/*
+		 * How much space is left in the current dma buffer?
+		 *
+		 * dma_xfer_count is # of bytes placed into the dma buffer
+		 * where each sample is 8 bytes (4 bytes left, 4 bytes right)
+		 * because that's what the I2S is set up for - 32 bit samples.
+		 */
+		dma_xfer_count = stream->fragsize - dma_buffer->size;
+		
+		/*
+		 * user_buffer is src_count (bytes) of whatever format.
+		 * How big will src_count be when sample size is expanded
+		 * to 32 bit samples for our hardware?
+		 */
+		expanded_count = src_count * stream->dma2usr_ratio;
+		
+		/*
+		 * See if we can fit all the remaining user_buffer in
+		 * the current dma buffer...
+		 */
+		if (dma_xfer_count > expanded_count)
+			dma_xfer_count = expanded_count;
+		
+		//DPRINTK( "EP93xx - audio_write: %d to dma_buffer # %d\n", dma_xfer_count, stream->dma_buffer_index );
+		
+		src_xfer_count = copy_from_user_with_conversion( state, 
+											dma_buffer->start + dma_buffer->size, 
+											user_buffer,
+											dma_xfer_count);
+		if( src_xfer_count <= 0 ) 
+		{
+			up(&dma_buffer->sem);
+			return -EFAULT;
+		}
+
+		/*
+		 * Increment dma buffer pointer.
+		 */
+		dma_buffer->size += dma_xfer_count;
+
+		/* 
+		 * Increment user_buffer pointer.
+		 * Decrement the user_buffer size count.
+		 */
+		user_buffer += src_xfer_count;
+		src_count  -= src_xfer_count;
+
+		/*
+		 * If the chunk is less than a whole fragment, don't
+		 * send it, wait for more ??? I say, go ahead and send it.
+		 */
+#if 0
+		if (dma_buffer->size < stream->fragsize) 
+		{
+			up(&dma_buffer->sem);
+			break;
+		}	 
+#endif
+
+		/*
+		 * If we haven't already started the DMA start it.
+		 * But don't start it if we are waiting on a trigger.
+		 */
+		if( !stream->active && !stream->stopped )
+		{
+			stream->active = 1;
+			audio_dma_start( state, stream );
+		}
+		
+		/*
+		 * Note that we've 'downed' the semiphore for this buffer.  But the
+		 * dma driver doesn't know about it until we've added it to the DMA
+		 * driver's buffer queue.  So let's do that now.
+		 */
+	 	ep93xx_dma_add_buffer( stream->dmahandles[0], 			/* dma instance 		*/
+							   (unsigned int)dma_buffer->dma_addr, /* source 		*/
+							   0, 							/* dest 				*/
+							   dma_buffer->size,			/* size					*/
+							   0,							/* is the last chunk? 	*/
+							   (unsigned int) dma_buffer ); /* buf id			 	*/	
+
+		/*
+		 * Note that we added a buffer to play for the benefit of calculating
+		 * ODELAY.
+		 */
+		stream->buffered_bytes_to_play += dma_buffer->size;
+		
+		/* 
+		 * Indicate that the dma buffer has been sent.  Not the same as the
+		 * buffer's semiphore.
+		 */
+		dma_buffer->sent = 1;
+		
+		NEXT_BUF(stream, dma_buffer);
+	}
+	
+	/*
+	 * Return the number of bytes transferred.
+	 */
+	if( (int)user_buffer - (int)user_buffer_start )
+		ret = (int)user_buffer - (int)user_buffer_start;
+	
+/*	DPRINTK( "EP93xx - audio_write: return=%d\n", ret );*/
+	return ret;
+}
+
+/*
+ * audio_dma_start
+ *
+ * Our Ac97 has a specific start order that it likes.  Enable the 
+ * Ac97 channel AFTER enabling DMA.  Our I2S is not so picky.
+ */
+void audio_dma_start( audio_state_t * state, audio_stream_t * stream )
+{
+	ep93xx_dma_start( stream->dmahandles[0],
+					  stream->NumDmaChannels, 
+					  stream->dmahandles );
+	
+	if (state->hw->hw_enable)
+		state->hw->hw_enable( stream );
+
+}
+
+/*
+ * audio_dma_pause
+ */
+void audio_dma_pause( audio_state_t * state, audio_stream_t * stream )
+{
+	DPRINTK("audio_dma_pause - enter\n");
+	
+	ep93xx_dma_pause( stream->dmahandles[0],
+					  stream->NumDmaChannels, 
+					  stream->dmahandles );
+
+	if (state->hw->hw_disable)
+		state->hw->hw_disable( stream );
+	
+	if (state->hw->hw_clear_fifo)
+		state->hw->hw_clear_fifo( stream );
+
+	DPRINTK("audio_dma_pause - EXIT\n");
+}
+
+static void audio_prime_dma( audio_state_t * state, audio_stream_t * stream )
+{
+	int i;
+	
+	DPRINTK("audio_prime_dma\n");
+
+	/*
+	 * If we haven't already started the DMA start it.
+	 * But don't start it if we are waiting on a trigger.
+	 */
+	if( !stream->active && !stream->stopped )
+	{
+		stream->active = 1;
+		audio_dma_start( state, stream );
+	}
+
+	for (i = 0; i < stream->nbfrags; i++) 
+	{
+		audio_buf_t *dma_buffer = stream->dma_buffer;
+		down(&dma_buffer->sem);
+	 	ep93xx_dma_add_buffer( stream->dmahandles[0],		/* dma instance 		*/
+							   (unsigned int)dma_buffer->dma_addr, /* source 		*/
+							   0, 							/* dest 				*/
+							   stream->fragsize,			/* size					*/
+							   0,							/* is the last chunk? 	*/
+							   (unsigned int) dma_buffer ); /* buf id			 	*/	
+		NEXT_BUF(stream, dma_buffer);
+	}
+}
+
+/*
+ * audio_read
+ *
+ * Audio capture function.
+ */
+static int audio_read
+(
+	struct file *file, 
+	char * user_buffer,
+	size_t count, 
+	loff_t * ppos
+)
+{
+	char * user_buffer_start = user_buffer;
+	audio_state_t * state = (audio_state_t *)file->private_data;
+	audio_stream_t * stream = state->input_stream;
+	unsigned int user_buffer_xfer_count = 0, dma_buffer_xfer_count = 0; 
+	int ret = 0;
+
+	DPRINTK("EP93xx - audio_read: count=%d\n", count);
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+		
+	if (stream->mapped)
+		return -ENXIO;
+
+	if( !access_ok( VERIFY_WRITE, user_buffer, count ) )
+	{
+		DPRINTK( "access_ok failed for audio_read!!!!\n" );
+		return -EFAULT;
+	}
+
+	if (!stream->active) 
+	{
+		if (!stream->buffers && audio_allocate_buffers( state, stream))
+			return -ENOMEM;
+
+		audio_prime_dma( state, stream );
+	}
+
+	while (count > 0) 
+	{
+		/*
+		 * Get the current buffer.
+		 */
+		audio_buf_t * dma_buffer = stream->dma_buffer;
+
+		/* 
+		 * Wait for a dma buffer to become full 
+		 */
+		if (file->f_flags & O_NONBLOCK) 
+		{
+			//DPRINTK("file->f_flags & O_NONBLOCK\n");
+			ret = -EAGAIN;
+			if (down_trylock(&dma_buffer->sem))
+				break;
+		} 
+		else 
+		{
+			//DPRINTK("NOT file->f_flags & O_NONBLOCK\n");
+			ret = -ERESTARTSYS;
+			if (down_interruptible(&dma_buffer->sem))
+				break;
+		}
+
+		/*
+		 * If this is the first buffer captured,
+		 * dump the first 8 samples of the dma buffer.
+		 */
+		if( stream->bFirstCaptureBuffer )
+		{
+			dma_buffer->size -= 64;
+			stream->bFirstCaptureBuffer = 0;
+		}	
+		
+		/*
+		 * How much user buffer would a whole DMA buffer fill?
+		 */
+		user_buffer_xfer_count = dma_buffer->size / stream->dma2usr_ratio;
+
+		if (user_buffer_xfer_count > count)
+			user_buffer_xfer_count = count;
+		
+		dma_buffer_xfer_count = user_buffer_xfer_count * stream->dma2usr_ratio;
+
+		DPRINTK("dma_buffer: start=0x%08x fragsz=%d size=%d\n",
+				 (int)dma_buffer->start, (int)stream->fragsize, dma_buffer->size);
+		
+		DPRINTK("user_buffer=0x%08x  from=0x%08x  user_count=%d  dma_count=%d\n",
+				 (int)user_buffer,
+				 (int)dma_buffer->start + stream->fragsize - dma_buffer->size,
+				 user_buffer_xfer_count, dma_buffer_xfer_count);
+		
+		
+		if( copy_to_user_with_conversion( state, 
+				 user_buffer,
+				 dma_buffer->start + stream->fragsize - dma_buffer->size,
+				 user_buffer_xfer_count) <= 0 ) 
+		{
+			up(&dma_buffer->sem);
+			return -EFAULT;
+		}
+		
+		dma_buffer->size -= dma_buffer_xfer_count;
+
+		user_buffer += user_buffer_xfer_count;
+		count -= user_buffer_xfer_count;
+		
+		/* 
+		 * Grab data from the current dma buffer 
+		 */
+		//DPRINTK("Read: read %d bytes from %d.  dmabufsize=%d.  count=%d\n", 
+		//			user_buffer_xfer_count, stream->dma_buffer_index,
+		//			dma_buffer->size, count);
+		
+		/*
+		 * If there's still data in this buffer to be read, release
+		 * the semiphore and don't give it back yet.  We may come back
+		 * and read from it in a minute when the app calls for another read.
+		 */
+		if (dma_buffer->size > 0) 
+		{
+		//	DPRINTK("dma_buffer->size > 0 !\n");
+			up(&dma_buffer->sem);
+			break;
+		}
+
+		/* Make current dma buffer available for DMA again */
+	 	ep93xx_dma_add_buffer( stream->dmahandles[0],		/* dma instance  */
+							   (unsigned int)dma_buffer->dma_addr, /* source */
+							   0, 									/* dest  */
+							   stream->fragsize,					/* size	 */
+							   0,				  			/* the last chunk? */
+							   (unsigned int) dma_buffer );        /* buf id */	
+
+		NEXT_BUF(stream, dma_buffer);
+	}
+
+	if( (int)user_buffer - (int)user_buffer_start )
+		ret = (int)user_buffer - (int)user_buffer_start;
+	
+	//DPRINTK("EP93xx - audio_read: return=%d\n", ret);
+	
+	return ret;
+}
+
+
+static int audio_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	audio_state_t *state = (audio_state_t *)file->private_data;
+	audio_stream_t * stream = 0;
+	unsigned long size, vma_addr;
+	int i, ret;
+
+	if (vma->vm_pgoff != 0)
+		return -EINVAL;
+
+	if (vma->vm_flags & VM_WRITE) 
+	{
+		if (!state->wr_ref)
+			return -EINVAL;
+
+		stream = state->output_stream;
+	}
+	else if (vma->vm_flags & VM_READ) 
+	{
+		if (!state->rd_ref)
+			return -EINVAL;
+
+		stream = state->input_stream;
+	} 
+	else 
+	{
+		return -EINVAL;
+	}
+
+	if (stream->mapped)
+		return -EINVAL;
+
+	size = vma->vm_end - vma->vm_start;
+	
+	if (size != stream->fragsize * stream->nbfrags)
+		return -EINVAL;
+	
+	if (!stream->buffers && audio_allocate_buffers( state, stream))
+		return -ENOMEM;
+
+	vma_addr = vma->vm_start;
+
+	for (i = 0; i < stream->nbfrags; i++) 
+	{
+		audio_buf_t *dma_buffer = &stream->buffers[i];
+		
+		if (!dma_buffer->master)
+		{
+			continue;
+		}
+
+		ret = remap_page_range(vma_addr, dma_buffer->dma_addr, dma_buffer->master, vma->vm_page_prot);
+
+		if (ret)
+			return ret;
+
+		vma_addr += dma_buffer->master;
+	}
+
+	stream->mapped = 1;
+
+	return 0;
+}
+
+
+static unsigned int audio_poll(struct file *file,
+			       struct poll_table_struct *wait)
+{
+	audio_state_t *state = (audio_state_t *)file->private_data;
+	audio_stream_t *is = state->input_stream;
+	audio_stream_t *os = state->output_stream;
+	unsigned int mask = 0;
+	int i;
+
+	DPRINTK("EP93xx - audio_poll(): mode=%s%s\n",
+		(file->f_mode & FMODE_READ) ? "r" : "",
+		(file->f_mode & FMODE_WRITE) ? "w" : "");
+
+	if (file->f_mode & FMODE_READ) 
+	{
+		/* Start audio input if not already active */
+		if (!is->active) 
+		{
+			if (!is->buffers && audio_allocate_buffers( state, is))
+				return -ENOMEM;
+
+			audio_prime_dma( state, is);
+		}
+
+		poll_wait(file, &is->wq, wait);
+	}
+
+	if (file->f_mode & FMODE_WRITE) 
+	{
+		if (!os->buffers && audio_allocate_buffers( state, os))
+			return -ENOMEM;
+
+		poll_wait(file, &os->wq, wait);
+	}
+
+	if (file->f_mode & FMODE_READ) 
+	{
+		if (is->mapped) 
+		{
+			/* 
+			 * if the buffer is mapped assume we care that there are 
+			 * more bytes available than when we last asked using 
+			 * SNDCTL_DSP_GETxPTR 
+			 */
+			if (is->bytecount != is->getptrCount)
+				mask |= POLLIN | POLLRDNORM;
+		} 
+		else 
+		{
+			for (i = 0; i < is->nbfrags; i++) 
+			{
+				if (atomic_read(&is->buffers[i].sem.count) > 0) 
+				{
+					mask |= POLLIN | POLLRDNORM;
+					break;
+				}
+			}
+		}
+	}
+	
+	if (file->f_mode & FMODE_WRITE) 
+	{
+		if (os->mapped) 
+		{
+			if (os->bytecount != os->getptrCount)
+				mask |= POLLOUT | POLLWRNORM;
+		} 
+		else 
+		{
+			for (i = 0; i < os->nbfrags; i++) 
+			{
+				if (atomic_read(&os->buffers[i].sem.count) > 0) 
+				{
+					mask |= POLLOUT | POLLWRNORM;
+					break;
+				}
+			}
+		}
+	}
+
+	DPRINTK("EP93xx - audio_poll() returned mask of %s%s\n",
+		(mask & POLLIN) ? "r" : "",
+		(mask & POLLOUT) ? "w" : "");
+
+	return mask;
+}
+
+/*
+ * audio_set_fragments
+ *
+ * Used to process SNDCTL_DSP_SETFRAGMENT.
+ *
+ * Argument is 0xMMMMSSSS where:
+ *		MMMM sets number of fragments.
+ * 		SSSS sets dma fragment (dma_buffer) size.  size = 2^SSSS bytes
+ */
+static int audio_set_fragments( audio_state_t *state, audio_stream_t *stream, int val )
+{
+	if (stream->active)
+		return -EBUSY;
+	
+	stream->requested_fragsize = 1 << (val & 0x000ffff);
+	stream->requested_nbfrags  = (val >> 16) & 0x7FFF;
+	
+	return 0;
+}
+
+static void print_audio_format( long format )
+{
+	switch( format )
+	{
+		case AFMT_U8:		   
+			DPRINTK_IOCTL( "AFMT_U8\n" );		   
+			break;
+
+		case AFMT_S8:
+			DPRINTK_IOCTL( "AFMT_S8\n" );		   
+			break;
+
+		case AFMT_S32_BLOCKED:
+			DPRINTK_IOCTL( "AFMT_S32_BLOCKED\n" );		   
+			break;
+
+		case AFMT_S16_LE:
+			DPRINTK_IOCTL( "AFMT_S16_LE\n" );		   
+			break;
+
+		case AFMT_S16_BE:
+			DPRINTK_IOCTL( "AFMT_S16_BE\n" );		   
+			break;
+
+		case AFMT_U16_LE:
+			DPRINTK_IOCTL( "AFMT_U16_LE\n" );		   
+			break;
+
+		case AFMT_U16_BE:
+		default:
+			DPRINTK_IOCTL( "AFMT_U16_BE\n" );		   
+			break;
+	}
+}
+
+/*
+ * We convert to 24 bit samples that occupy 32 bits each.
+ * Formats we support:
+ *
+ * AFMT_U8		   
+ * AFMT_S16_LE	   	Little endian signed 16
+ * AFMT_S8		   
+ * AFMT_U16_LE	   	Little endian U16
+ * AFMT_S32_BLOCKED	32 bit little endian format, taken from the rme96xx driver.
+ *
+ */
+static long audio_set_format( audio_stream_t * stream, long val )
+{
+	DPRINTK_IOCTL( "audio_set_format enter.  Format requested (%d) ", 
+				(int)val );
+	print_audio_format( val );
+	
+	switch( val )
+	{
+        case AFMT_QUERY:
+            break;
+
+		case AFMT_U8:		   
+			stream->audio_format = val;
+			stream->audio_stream_bitwidth = 8;
+			break;
+
+		case AFMT_S8:
+			stream->audio_format = val;
+			stream->audio_stream_bitwidth = 8;
+			break;
+
+		case AFMT_S32_BLOCKED:
+			stream->audio_format = val;
+			stream->audio_stream_bitwidth = 32;
+			break;
+
+		case AFMT_S16_LE:
+		case AFMT_S16_BE:
+			stream->audio_format = AFMT_S16_LE;
+			stream->audio_stream_bitwidth = 16;
+			break;
+
+		case AFMT_U16_LE:
+		case AFMT_U16_BE:
+		default:
+			stream->audio_format = AFMT_U16_LE;
+			stream->audio_stream_bitwidth = 16;
+			break;
+	}
+
+	DPRINTK_IOCTL( "audio_set_format EXIT format set to be (%d) ", 
+				(int)stream->audio_format );
+	print_audio_format( (long)stream->audio_format );
+	
+	return stream->audio_format;
+}
+
+static __inline__ unsigned long copy_to_user_U16_LE_CM
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	unsigned long to_count
+)
+{
+	int total_to_count = to_count;
+	unsigned short * user_ptr = (unsigned short *)to; /* 16 bit user buffer */
+	short * dma_ptr = (short *)from;
+	short right, left;
+	
+	/*
+	 * Compact mode - left is the lower 16 bits.  right is the upper 16 bits.
+	 */
+
+	if( state->input_stream->audio_num_channels != 1 ) 
+	{
+		while (to_count > 0) 
+		{
+			right = *dma_ptr++;
+			left  = *dma_ptr++;
+			__put_user( left ^ 0x8000, user_ptr++ );
+			__put_user( right^ 0x8000, user_ptr++ );
+			to_count -= 4;
+		}
+	}
+	else
+	{
+		while (to_count > 0) 
+		{
+			dma_ptr++;	/* skip right channel sample */
+			left  = *dma_ptr++;
+			__put_user( left ^ 0x8000, user_ptr++ );
+			to_count -= 2;
+		}
+	}
+	
+	return total_to_count;
+}
+
+static __inline__ unsigned long copy_to_user_U16_LE
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	unsigned long to_count
+)
+{
+	int total_to_count = to_count;
+	short * user_ptr = (short *)to;	/* 16 bit user buffer */
+	int * dma_ptr = (int *)from;	/* 32 bit dma buffer  */
+
+	int shift = state->input_stream->hw_bit_width - 16;
+	
+	if( state->input_stream->audio_num_channels != 1 ) 
+	{
+		while (to_count > 0) 
+		{
+			__put_user( ((short)( (*dma_ptr++) >> shift )) ^ 0x8000, user_ptr++ );
+			__put_user( ((short)( (*dma_ptr++) >> shift )) ^ 0x8000, user_ptr++ );
+			to_count -= 4;
+		}
+	}
+	else
+	{
+		while (to_count > 0) 
+		{
+			__put_user( ((short)( (*dma_ptr++) >> shift )) ^ 0x8000, user_ptr++ );
+			dma_ptr++;	/* skip right channel sample */
+			to_count -= 2;
+		}
+	}
+	
+	return total_to_count;
+}
+
+static __inline__ unsigned long copy_to_user_S16_LE_CM
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	unsigned long to_count
+)
+{
+	int total_to_count = to_count;
+	short * user_ptr = (short *)to;	  /* 16 bit user buffer */
+	short * dma_ptr = (short *)from;
+	short left, right;
+
+	/*
+	 * Compact mode - left is the lower 16 bits.  right is the upper 16 bits.
+	 */
+
+	if( state->input_stream->audio_num_channels != 1 ) 
+	{
+		while (to_count > 0) 
+		{
+			right = *dma_ptr++;
+			left  = *dma_ptr++;
+			__put_user( left,  user_ptr++ );
+			__put_user( right, user_ptr++ );
+			to_count -= 4;
+		}
+	}
+	else
+	{
+		while (to_count > 0) 
+		{
+			dma_ptr++; /* skip right sample */
+			left  = *dma_ptr++;
+			__put_user( left,  user_ptr++ );
+			to_count -= 2;
+		}
+	}
+	
+	return total_to_count;
+}
+
+static __inline__ unsigned long copy_to_user_S16_LE
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	unsigned long to_count
+)
+{
+	int total_to_count = to_count;
+	short * user_ptr = (short *)to;	/* 16 bit user buffer */
+	int * dma_ptr = (int *)from;	/* 32 bit dma buffer  */
+
+	int shift = state->input_stream->hw_bit_width - 16;
+	
+	if( state->input_stream->audio_num_channels != 1 ) 
+	{
+		while (to_count > 0) 
+		{
+			__put_user( (short)( (*dma_ptr++) >> shift ), user_ptr++ );
+			__put_user( (short)( (*dma_ptr++) >> shift ), user_ptr++ );
+			to_count -= 4;
+		}
+	}
+	else
+	{
+		while (to_count > 0) 
+		{
+			__put_user( (short)((*dma_ptr++) >> shift), user_ptr++ );
+			dma_ptr++;	/* skip right channel sample */
+			to_count -= 2;
+		}
+	}
+	
+	return total_to_count;
+}
+
+static __inline__ unsigned long copy_to_user_S8_CM
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	unsigned long to_count
+)
+{
+	int total_to_count = to_count;
+	char * user_ptr = (char *)to;  	/*  8 bit user buffer */
+	unsigned short * dma_ptr = (unsigned short *)from;    /* 16 bit dma buffer  */
+	char right, left;
+
+	if( state->input_stream->audio_num_channels != 1 ) 
+	{
+		while (to_count > 0) 
+		{
+			right = ((char)(*dma_ptr++ >> 8));
+			left  = ((char)(*dma_ptr++ >> 8));
+			__put_user( left,  user_ptr++ );
+			__put_user( right, user_ptr++ );
+			to_count -= 2;
+		}
+	}
+	else
+	{
+		while (to_count > 0) 
+		{
+			dma_ptr++;	/* skip right channel sample */
+			left  = ((char)(*dma_ptr++ >> 8));
+			__put_user( left,  user_ptr++ );
+			to_count--;
+		}
+	}
+	
+	return total_to_count;
+}
+
+static __inline__ unsigned long copy_to_user_S8
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	unsigned long to_count
+)
+{
+	int total_to_count = to_count;
+	char * user_ptr = (char *)to;  /*  8 bit user buffer */
+	int * dma_ptr = (int *)from;    /* 32 bit dma buffer  */
+
+	int shift = state->input_stream->hw_bit_width - 8;
+
+	if( state->input_stream->audio_num_channels != 1 ) 
+	{
+		while (to_count > 0) 
+		{
+			__put_user( (char)( (*dma_ptr++) >> shift ), user_ptr++ );
+			__put_user( (char)( (*dma_ptr++) >> shift ), user_ptr++ );
+			to_count -= 2;
+		}
+	}
+	else
+	{
+		while (to_count > 0) 
+		{
+			__put_user( (char)((*dma_ptr++) >> shift), user_ptr++ );
+			dma_ptr++;	/* skip right channel sample */
+			to_count--;
+		}
+	}
+	
+	return total_to_count;
+}
+
+static __inline__ unsigned long copy_to_user_U8_CM
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	unsigned long to_count
+)
+{
+	int total_to_count = to_count;
+	char * user_ptr = (char *)to;  	/*  8 bit user buffer */
+	unsigned short * dma_ptr = (unsigned short *)from;    /* 16 bit dma buffer  */
+	char right, left;
+
+	if( state->input_stream->audio_num_channels != 1 ) 
+	{
+		while (to_count > 0) 
+		{
+			right = ((char)(*dma_ptr++ >> 8)) ^ 0x80;
+			left  = ((char)(*dma_ptr++ >> 8)) ^ 0x80;
+			__put_user( left,  user_ptr++ );
+			__put_user( right, user_ptr++ );
+			to_count -= 2;
+		}
+	}
+	else
+	{
+		while (to_count > 0) 
+		{
+			dma_ptr++;	/* skip right channel sample */
+			left  = ((char)(*dma_ptr++ >> 8)) ^ 0x80;
+			__put_user( left,  user_ptr++ );
+			to_count--;
+		}
+	}
+	
+	return total_to_count;
+}
+
+static __inline__ unsigned long copy_to_user_U8
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	unsigned long to_count
+)
+{
+	int total_to_count = to_count;
+	char * user_ptr = (char *)to;  /*  8 bit user buffer */
+	int * dma_ptr = (int *)from;    /* 32 bit dma buffer  */
+
+	int shift = state->input_stream->hw_bit_width - 8;
+
+	if( state->input_stream->audio_num_channels != 1 ) 
+	{
+		while (to_count > 0) 
+		{
+			__put_user( ((char)( (*dma_ptr++) >> shift )) ^ 0x80, user_ptr++ );
+			__put_user( ((char)( (*dma_ptr++) >> shift )) ^ 0x80, user_ptr++ );
+			to_count -= 2;
+		}
+	}
+	else
+	{
+		while (to_count > 0) 
+		{
+			__put_user( ((char)( (*dma_ptr++) >> shift )) ^ 0x80, user_ptr++ );
+			dma_ptr++;	/* skip right channel sample */
+			to_count--;
+		}
+	}
+	
+	return total_to_count;
+}
+
+/*
+ * Returns negative for error
+ * Returns # of bytes transferred out of the from buffer
+ * for success.
+ */
+static __inline__ int copy_to_user_with_conversion
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	int toCount
+)
+{
+	int ret=0;
+	
+	if( toCount == 0 )
+	{
+		DPRINTK("copy_to_user_with_conversion - nothing to copy!\n");
+	}
+
+	/*
+	 * Compact Mode means that each 32 bit word has both the
+	 * left and right sample in it.
+	 */
+	if( state->input_stream->bCompactMode )
+	{
+		switch( state->input_stream->audio_format )
+		{
+			case AFMT_U8:
+				ret = copy_to_user_U8_CM( state, to, from, toCount );
+				break;
+
+			case AFMT_S16_LE:
+				ret = copy_to_user_S16_LE_CM( state, to, from, toCount );
+				break;
+		
+			case AFMT_S8:
+				ret = copy_to_user_S8_CM( state, to, from, toCount );
+				break;
+				
+			case AFMT_U16_LE:
+				ret = copy_to_user_U16_LE_CM( state, to, from, toCount );
+				break;
+				
+			case AFMT_S32_BLOCKED:
+			default:
+				break;
+		}
+	}
+	else
+	{
+		switch( state->input_stream->audio_format )
+		{
+			case AFMT_U8:
+				ret = copy_to_user_U8( state, to, from, toCount );
+				break;
+
+			case AFMT_S16_LE:
+				ret = copy_to_user_S16_LE( state, to, from, toCount );
+				break;
+		
+			case AFMT_S8:
+				ret = copy_to_user_S8( state, to, from, toCount );
+				break;
+				
+			case AFMT_U16_LE:
+				ret = copy_to_user_U16_LE( state, to, from, toCount );
+				break;
+				
+			case AFMT_S32_BLOCKED:
+			default:
+				__copy_to_user( (char *)to, from, toCount);
+				ret = toCount;
+				break;
+		}
+	}
+
+	return ret;
+}
+
+static __inline__ int copy_from_user_U16_LE_CM
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	int toCount 
+)
+{
+	unsigned short * dma_buffer = (unsigned short *)to;
+	unsigned short * user_buffer = (unsigned short *)from;
+	unsigned short data;
+	
+	int toCount0 = toCount;
+	int mono = (state->output_stream->audio_num_channels == 1);
+
+	/*
+	 * Compact mode - left is the lower 16 bits.  right is the upper 16 bits.
+	 */
+	 
+	 if( !mono )
+	 {
+		while (toCount > 0) 
+		{
+			__get_user(data, user_buffer++);
+			*dma_buffer++ = data ^ 0x8000;
+			__get_user(data, user_buffer++);
+			*dma_buffer++ = data ^ 0x8000;
+			toCount -= 4;
+		}
+	 }
+	 else
+	 {
+		while (toCount > 0) 
+		{
+			__get_user(data, user_buffer++);
+			data = data ^ 0x8000;
+			*dma_buffer++ = data;
+			*dma_buffer++ = data;
+			toCount -= 4;
+		}
+	 }
+	 
+
+	/*
+	 * Each mono or stereo 16 bit sample going in results
+	 * in one stereo 32 bit sample going out.  So
+	 * mono   = (2 bytes in)/(4 bytes out)
+	 * stereo = (4 bytes in)/(4 bytes out)
+	 */
+	if( mono )
+	{
+		return toCount0 / 2;
+	}
+	
+	return toCount0;
+}
+
+static __inline__ int copy_from_user_U16_LE
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	int toCount 
+)
+{
+	int * dma_buffer = (int *)to;
+	int val;
+	unsigned short * user_buffer = (unsigned short *)from;
+	unsigned short data;
+	
+	int toCount0 = toCount;
+	int mono = (state->output_stream->audio_num_channels == 1);
+	int shift = state->output_stream->hw_bit_width - 16;
+
+	if (!mono) 
+	{
+		while (toCount > 0) 
+		{
+			__get_user(data, user_buffer++);
+			*dma_buffer++ = ((unsigned int)data ^ 0x8000) << shift;
+			__get_user(data, user_buffer++);
+			*dma_buffer++ = ((unsigned int)data ^ 0x8000) << shift;
+			toCount -= 8;
+		}
+	}
+	else
+	{
+		while (toCount > 0) 
+		{
+			__get_user(data, user_buffer++);
+			val = ((unsigned int)data ^ 0x8000) << shift;
+			*dma_buffer++ = val;
+			*dma_buffer++ = val;
+			toCount -= 8;
+		}
+	}
+	
+	/*
+	 * Each mono or stereo 16 bit sample going in results
+	 * in a two 32 bit (left & right) samples going out.  So
+	 * mono   = (2 bytes in)/(8 bytes out)
+	 * stereo = (4 bytes in)/(8 bytes out)
+	 */
+	if( mono )
+		return toCount0 / 4;
+	
+	return toCount0 / 2;
+}
+
+static __inline__ int copy_from_user_S16_LE_CM
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	int toCount 
+)
+{
+	short * dma_buffer = (short *)to;
+	unsigned short * user_buffer = (unsigned short *)from;
+	unsigned short data;
+	
+	int toCount0 = toCount;
+	int mono = (state->output_stream->audio_num_channels == 1);
+
+	/*
+	 * Compact mode - left is the lower 16 bits.  right is the upper 16 bits.
+	 */
+
+	if( !mono )
+	{
+		__copy_from_user( (char *)to, from, toCount);
+	}
+	else
+	{
+		while (toCount > 0) 
+		{
+			__get_user(data, user_buffer++);
+			*dma_buffer++ = data;
+			*dma_buffer++ = data;
+			toCount -= 4;
+		}
+	}
+	
+
+	/*
+	 * Each mono or stereo 16 bit sample going in results
+	 * in one stereo 32 bit sample going out.  So
+	 * mono   = (2 bytes in)/(4 bytes out)
+	 * stereo = (4 bytes in)/(4 bytes out)
+	 */
+	if( mono )
+		return toCount0 / 2;
+	
+	return toCount0;
+}
+
+
+static __inline__ int copy_from_user_S16_LE
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	int toCount 
+)
+{
+	int * dma_buffer = (int *)to;
+	int val;
+	unsigned short * user_buffer = (unsigned short *)from;
+	unsigned short data;
+	
+	int toCount0 = toCount;
+	int mono = (state->output_stream->audio_num_channels == 1);
+	int shift = state->output_stream->hw_bit_width - 16;
+
+	if (!mono)
+	{
+		while (toCount > 0) 
+		{
+			__get_user(data, user_buffer++);
+			*dma_buffer++ = (unsigned int)data << shift;
+			__get_user(data, user_buffer++);
+			*dma_buffer++ = (unsigned int)data << shift;
+			toCount -= 8;
+		}
+	}
+	else
+	{
+		while (toCount > 0) 
+		{
+			__get_user(data, user_buffer++);
+			val = (unsigned int)data << shift;
+			*dma_buffer++ = val;
+			*dma_buffer++ = val;
+			toCount -= 8;
+		}
+	} 
+
+	/*
+	 * Each mono or stereo 16 bit sample going in results
+	 * in a two 32 bit samples (left & right) going out.  So
+	 * mono   = (2 bytes in)/(8 bytes out)
+	 * stereo = (4 bytes in)/(8 bytes out)
+	 */
+	if( mono )
+		return toCount0 / 4;
+	
+	return toCount0 / 2;
+}
+
+static __inline__ int copy_from_user_S8_CM
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	int toCount 
+)
+{
+	short * dma_buffer = (short *)to;
+	short val;
+	unsigned char * user_buffer = (unsigned char *)from;
+	unsigned char data;
+	
+	int toCount0 = toCount;
+	int mono = (state->output_stream->audio_num_channels == 1);
+
+	/*
+	 * Compact mode - left is the lower 16 bits.  right is the upper 16 bits.
+	 */
+
+	if (!mono)
+	{
+		while (toCount > 0) 
+		{
+			__get_user(data, user_buffer++);
+			*dma_buffer++ = (unsigned short)data << 8;
+			__get_user(data, user_buffer++);
+			*dma_buffer++ = (unsigned short)data << 8;
+			toCount -= 4;
+		}
+	}
+	else
+	{
+		while (toCount > 0) 
+		{
+			__get_user(data, user_buffer++);
+			val = (unsigned short)data << 8;
+			*dma_buffer++ = val;
+			*dma_buffer++ = val;
+			toCount -= 4;
+		}
+	}
+	
+
+	/*
+	 * Each mono or stereo 8 bit sample going in results
+	 * in one stereo 32 bit sample going out.  So
+	 * mono   = (1 byte  in)/(4 bytes out)
+	 * stereo = (2 bytes in)/(4 bytes out)
+	 */
+	if( mono )
+		return toCount0 / 4;
+	
+	return toCount0 / 2;
+}
+
+static __inline__ int copy_from_user_S8
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	int toCount 
+)
+{
+	int * dma_buffer = (int *)to;
+	int val;
+	unsigned char * user_buffer = (unsigned char *)from;
+	unsigned char data;
+	
+	int toCount0 = toCount;
+	int mono = (state->output_stream->audio_num_channels == 1);
+	int shift = state->output_stream->hw_bit_width - 8;
+
+	if (!mono) 
+	{
+		while (toCount > 0) 
+		{
+			__get_user(data, user_buffer++);
+			*dma_buffer++ = (unsigned int)data << shift;
+			__get_user(data, user_buffer++);
+			*dma_buffer++ = (unsigned int)data << shift;
+			toCount -= 8;
+		}
+	}
+	else
+	{
+		while (toCount > 0) 
+		{
+			__get_user(data, user_buffer++);
+			val = (unsigned int)data << shift;
+			*dma_buffer++ = val;
+			*dma_buffer++ = val;
+			toCount -= 8;
+		}
+	}
+	
+
+	/*
+	 * Each mono or stereo 8 bit sample going in results
+	 * in a two 32 bit samples (left & right) going out.  So
+	 * mono   = (1 byte  in)/(8 bytes out)
+	 * stereo = (2 bytes in)/(8 bytes out)
+	 */
+	if( mono )
+		return toCount0 / 8;
+	
+	return toCount0 / 4;
+}
+
+static __inline__ int copy_from_user_U8_CM
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	int toCount 
+)
+{
+	unsigned short * dma_buffer = (unsigned short *)to;
+	unsigned short val;
+	unsigned char * user_buffer = (unsigned char *)from;
+	unsigned char data;
+
+	int toCount0 = toCount;
+	int mono = (state->output_stream->audio_num_channels == 1);
+
+	if (!mono)
+	{
+		while (toCount > 0) 
+		{
+			__get_user(data, user_buffer++);
+			*dma_buffer++ = ((unsigned short)data ^ 0x80) << 8;
+			__get_user(data, user_buffer++);
+			*dma_buffer++ = ((unsigned short)data ^ 0x80) << 8;
+			toCount -= 4;
+		}
+	}
+	else
+	{
+		while (toCount > 0) 
+		{
+			__get_user(data, user_buffer++);
+			val = ((unsigned short)data ^ 0x80) << 8;
+			*dma_buffer++ = val;
+			*dma_buffer++ = val;
+			toCount -= 4;
+		}
+	}
+	 
+
+	/*
+	 * Each mono or stereo 8 bit sample going in results
+	 * in one stereo 32 bit sample going out.  So
+	 * mono   = (1 byte  in)/(4 bytes out)
+	 * stereo = (2 bytes in)/(4 bytes out)
+	 */
+	if( mono )
+		return toCount0 / 4;
+	
+	return toCount0 / 2;
+}
+
+static __inline__ int copy_from_user_U8
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	int toCount 
+)
+{
+	unsigned int * dma_buffer = (unsigned int *)to;
+	unsigned int val;
+	unsigned char * user_buffer = (unsigned char *)from;
+	unsigned char data;
+	
+	int toCount0 = toCount;
+	int mono = (state->output_stream->audio_num_channels == 1);
+	int shift = state->output_stream->hw_bit_width - 8;
+
+	if (!mono)
+	{
+		while (toCount > 0) 
+		{
+			__get_user(data, user_buffer++);
+			*dma_buffer++ = ((unsigned int)data ^ 0x80) << shift;
+			__get_user(data, user_buffer++);
+			*dma_buffer++ = ((unsigned int)data ^ 0x80) << shift;
+			toCount -= 8;
+		}
+	}
+	else
+	{
+		while (toCount > 0) 
+		{
+			__get_user(data, user_buffer++);
+			val = ((unsigned int)data ^ 0x80) << shift;
+			*dma_buffer++ = val;
+			*dma_buffer++ = val;
+			toCount -= 8;
+		}
+	}
+	
+
+	/*
+	 * Each mono or stereo 8 bit sample going in results
+	 * in a two 32 bit samples (left & right) going out.  So
+	 * mono   = (1 byte  in)/(8 bytes out)
+	 * stereo = (2 bytes in)/(8 bytes out)
+	 */
+	if( mono )
+		return toCount0 / 8;
+	
+	return toCount0 / 4;
+}
+
+/*
+ * Returns negative for error
+ * Returns # of bytes transferred out of the from buffer
+ * for success.
+ */
+static __inline__ int copy_from_user_with_conversion
+(
+	audio_state_t *state,
+	const char *to, 
+	const char *from, 
+	int toCount 
+)
+{
+	int ret=0;
+	
+	if( toCount == 0 )
+	{
+		DPRINTK("copy_from_user_with_conversion - nothing to copy!\n");
+	}
+
+	/*
+	 * Compact Mode means that each 32 bit word has both the
+	 * left and right sample in it.
+	 */
+	if( state->output_stream->bCompactMode )
+	{
+		switch( state->output_stream->audio_format )
+		{
+			case AFMT_U8:
+				ret = copy_from_user_U8_CM( state, to, from, toCount );
+				break;
+
+			case AFMT_S16_LE:
+				ret = copy_from_user_S16_LE_CM( state, to, from, toCount );
+				break;
+		
+			case AFMT_S8:
+				ret = copy_from_user_S8_CM( state, to, from, toCount );
+				break;
+				
+			case AFMT_U16_LE:
+				ret = copy_from_user_U16_LE_CM( state, to, from, toCount );
+				break;
+				
+			case AFMT_S32_BLOCKED:
+			default:
+				break;
+		}
+	}
+	else
+	{
+		switch( state->output_stream->audio_format )
+		{
+			case AFMT_U8:
+				ret = copy_from_user_U8( state, to, from, toCount );
+				break;
+
+			case AFMT_S16_LE:
+				ret = copy_from_user_S16_LE( state, to, from, toCount );
+				break;
+		
+			case AFMT_S8:
+				ret = copy_from_user_S8( state, to, from, toCount );
+				break;
+				
+			case AFMT_U16_LE:
+				ret = copy_from_user_U16_LE( state, to, from, toCount );
+				break;
+				
+			case AFMT_S32_BLOCKED:
+			default:
+				__copy_from_user( (char *)to, from, toCount);
+				ret = toCount;
+				break;
+		}
+	}
+	
+	return ret;
+}
+
+static int audio_ioctl(struct inode *inode, struct file *file,
+		       uint cmd, ulong arg)
+{
+	audio_state_t *state = (audio_state_t *)file->private_data;
+	audio_stream_t *os = state->output_stream;
+	audio_stream_t *is = state->input_stream;
+	long val=0;
+	
+	switch (cmd) 
+	{
+		case SNDCTL_DSP_STEREO:
+			DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_STEREO\n");
+			if( get_user(val, (int *)arg) || (val > 1) || (val < 0) )
+				return -EFAULT;
+
+			if (file->f_mode & FMODE_WRITE)
+			{
+				if (os->audio_num_channels != (val + 1)) {
+					os->audio_num_channels = val + 1;
+					calculate_dma2usr_ratio_etc( os );
+				}
+			} 
+
+			if (file->f_mode & FMODE_READ) 
+			{
+				if (is->audio_num_channels != (val + 1)) {
+					is->audio_num_channels = val + 1;
+					calculate_dma2usr_ratio_etc( is );
+				}
+			} 
+
+			return put_user( val, (long *) arg);
+
+		case SNDCTL_DSP_CHANNELS:
+			DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_CHANNELS\n");
+			if( get_user(val, (int *)arg) || (val > 2) || (val < 0) )
+				return -EFAULT;
+
+			// Calling with value of 0 is a query.
+			if( val == 0 )
+			{
+				if (file->f_mode & FMODE_WRITE)
+					val = os->audio_num_channels;
+				else
+					val = is->audio_num_channels;
+			}
+			else
+			{
+				if (file->f_mode & FMODE_WRITE)
+				{
+					if (os->audio_num_channels != val) {
+						os->audio_num_channels = val;
+						calculate_dma2usr_ratio_etc( os );
+					} 
+				} 
+				if (file->f_mode & FMODE_READ) 
+				{
+					if (is->audio_num_channels != val) {
+						is->audio_num_channels = val;
+						calculate_dma2usr_ratio_etc( is );
+					} 
+				}
+			}			
+			 
+			return put_user( val, (long *) arg);
+
+		case SOUND_PCM_READ_CHANNELS:
+			DPRINTK_IOCTL("audio_ioctl - SOUND_PCM_READ_CHANNELS\n");
+			if (file->f_mode & FMODE_WRITE)
+				val = os->audio_num_channels;
+			else
+				val = is->audio_num_channels;
+			return put_user( val, (long *) arg);
+
+		case SNDCTL_DSP_SETFMT:
+		{
+			DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_SETFMT\n");
+			
+			if (get_user(val, (int *)arg))
+				return -EFAULT;
+			
+			if( val != AFMT_QUERY )
+			{
+				if( (file->f_mode & FMODE_WRITE) && (val != os->audio_format) )
+				{
+					audio_set_format( os, val );
+					calculate_dma2usr_ratio_etc( os );
+					if( state->hw->set_hw_serial_format )
+						state->hw->set_hw_serial_format( os, val );
+				}
+				if( (file->f_mode & FMODE_READ) && (val != is->audio_format) )
+				{
+					audio_set_format( is, val );
+					calculate_dma2usr_ratio_etc( is );
+					if( state->hw->set_hw_serial_format )
+						state->hw->set_hw_serial_format( is, val );
+				}
+			}
+			
+			if (file->f_mode & FMODE_WRITE)
+				return put_user( os->audio_format, (long *) arg);
+			return put_user( is->audio_format, (long *) arg);
+		}
+		
+		case SNDCTL_DSP_GETFMTS:
+			DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_GETFMTS\n");
+			return put_user( (AFMT_U8 | AFMT_S8 | AFMT_S16_LE | AFMT_U16_LE), 
+							 (long *) arg);
+
+		case OSS_GETVERSION:
+			DPRINTK_IOCTL("audio_ioctl - OSS_GETVERSION\n");
+			return put_user(SOUND_VERSION, (int *)arg);
+
+		case SNDCTL_DSP_GETBLKSIZE:
+			DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_GETBLKSIZE\n");
+			if (file->f_mode & FMODE_WRITE)
+				return put_user(os->fragsize, (int *)arg);
+			return put_user(is->fragsize, (int *)arg);
+			
+		case SNDCTL_DSP_GETCAPS:
+			DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_GETCAPS\n");
+		 	val = DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP;
+			if (is && os)
+				val |= DSP_CAP_DUPLEX;
+			return put_user(val, (int *)arg);
+
+		case SNDCTL_DSP_SETFRAGMENT:
+		{
+			int ret;
+			DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_SETFRAGMENT\n");
+			if (get_user(val, (long *) arg))
+				return -EFAULT;
+			
+			if (file->f_mode & FMODE_READ)
+			{ 
+				ret = audio_set_fragments(state, is, val);
+				if (ret<0)
+					return ret;
+			}
+			
+			if (file->f_mode & FMODE_WRITE) 
+			{ 
+				ret = audio_set_fragments(state, os, val);
+				if (ret<0)
+					return ret;
+			}
+
+			return 0;
+		}
+
+		case SNDCTL_DSP_SYNC:
+			DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_SYNC\n");
+			return audio_sync(file);
+
+		case SNDCTL_DSP_SETDUPLEX:
+			DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_SETDUPLEX\n");
+			return 0;
+
+		case SNDCTL_DSP_POST:
+			DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_POST\n");
+			return 0;
+
+		case SNDCTL_DSP_GETTRIGGER:
+			DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_GETTRIGGER\n");
+			val = 0;
+			
+			if (file->f_mode & FMODE_READ && is->active && !is->stopped)
+				val |= PCM_ENABLE_INPUT;
+				
+			if (file->f_mode & FMODE_WRITE && os->active && !os->stopped)
+				val |= PCM_ENABLE_OUTPUT;
+				
+			return put_user(val, (int *)arg);
+
+		case SNDCTL_DSP_SETTRIGGER:
+			DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_SETTRIGGER\n");
+			if (get_user(val, (int *)arg))
+				return -EFAULT;
+				
+			if (file->f_mode & FMODE_READ) 
+			{
+				if (val & PCM_ENABLE_INPUT) 
+				{
+					if (!is->active) 
+					{
+						if (!is->buffers && audio_allocate_buffers( state, is))
+							return -ENOMEM;
+						audio_prime_dma( state, is);
+					}
+					
+					if (is->stopped) 
+					{
+						is->stopped = 0;
+						os->active = 1;
+						audio_dma_start( state, is );
+					}
+				} 
+				else 
+				{
+					audio_dma_pause( state, is );
+					is->stopped = 1;
+					is->active = 0;
+				}
+			}
+			
+			if (file->f_mode & FMODE_WRITE) 
+			{
+				if (val & PCM_ENABLE_OUTPUT) 
+				{
+					if (!os->active) 
+					{
+						if (!os->buffers && audio_allocate_buffers( state, os))
+							return -ENOMEM;
+							
+						if (os->mapped)
+							audio_prime_dma( state, os );
+					}
+					
+					if (os->stopped) 
+					{
+						os->stopped = 0;
+						os->active = 1;
+						audio_dma_start( state, os );
+					}
+				} 
+				else 
+				{
+					audio_dma_pause( state, os );
+					os->stopped = 1;
+					os->active = 0;
+				}
+			}
+			return 0;
+
+		case SNDCTL_DSP_GETOPTR:
+		case SNDCTL_DSP_GETIPTR:
+		{
+			count_info inf = { 0, };
+			audio_stream_t * stream = (cmd == SNDCTL_DSP_GETOPTR) ? os : is;
+			int bytecount, fragcount, flags, buf_num=0;
+			unsigned int current_frac, buf_id;
+			
+			DPRINTK_IOCTL("audio_ioctl - called SNDCTL_DSP_GETOPTR.\n");
+
+			if ((stream == is && !(file->f_mode & FMODE_READ)) ||
+			    (stream == os && !(file->f_mode & FMODE_WRITE)))
+				return -EINVAL;
+				
+			if( !stream->active ) 
+				return copy_to_user((void *)arg, &inf, sizeof(inf));
+			
+		   	save_flags_cli(flags);
+			
+			ep93xx_dma_get_position( stream->dmahandles[0], &buf_id, 0, 
+			    &current_frac );
+
+			/*
+			 * Out of a set of nbfrags buffers, which one is the current one?
+			 */
+			if (buf_id)
+		   		buf_num = ((audio_buf_t *)buf_id)->num;
+
+			/*
+			 * The ep93xx-audio ISRs keep track of bytecount and fragcount.
+			 * This bytecount isn't cleared except when the driver is opened
+			 * or when it overflows.
+			 */
+			bytecount = stream->bytecount;
+			
+			/* so poll can tell if it changes */
+			stream->getptrCount = stream->bytecount;	
+
+			/*
+			 * Return the number of fragment transitions counted in our dma ISR
+			 * since the previous call to this ioctl, then clear that counter.
+			 */
+			fragcount = stream->fragcount;
+			stream->fragcount = 0;
+			
+			restore_flags(flags);
+
+			/*
+			 * When reporting position to user app, scale byte counts and the
+			 * ptr to reflect the difference in sample size between dma samples
+			 * and user samples.  But don't scale the # of fragments.
+			 */
+			inf.blocks = fragcount;
+			inf.bytes  = (bytecount + current_frac) / stream->dma2usr_ratio;
+			inf.ptr = ((buf_num * stream->fragsize) + current_frac) / stream->dma2usr_ratio;
+
+			return copy_to_user((void *)arg, &inf, sizeof(inf));
+		}
+			
+		case SNDCTL_DSP_GETODELAY:
+		{
+			int flags, buffered_bytes_left, count;
+			unsigned int current_frac;
+
+			if (!(file->f_mode & FMODE_WRITE))
+				return -EINVAL;
+
+			DPRINTK_IOCTL("audio_ioctl - called SNDCTL_DSP_GETODELAY.\n");
+
+		   	save_flags_cli(flags);
+			
+			ep93xx_dma_get_position( os->dmahandles[0], 0, 0, &current_frac );
+
+			buffered_bytes_left = os->buffered_bytes_to_play;
+			
+			restore_flags(flags);
+			
+			count = (buffered_bytes_left - current_frac) / os->dma2usr_ratio;
+
+			return put_user(count, (int *)arg);
+		}
+
+		case SNDCTL_DSP_GETOSPACE:
+		    {
+				/*
+				 * It looks like this code is assuming that nobody
+				 * is writing the device while calling this ioctl
+				 * which may be a reasonable assumption.  I hope.
+				 * Maybe.
+				 */
+				audio_buf_info inf = { 0, };
+				int i;
+
+				DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_GETOSPACE\n");
+
+				if (!(file->f_mode & FMODE_WRITE))
+					return -EINVAL;
+				if (!os->buffers && audio_allocate_buffers( state, os))
+					return -ENOMEM;
+					
+				for (i = 0; i < os->nbfrags; i++) 
+				{
+					/*
+					 * If the semaphore is 1, the buffer is available.
+					 */
+					if (atomic_read(&os->buffers[i].sem.count) > 0) 
+					{
+						if (os->buffers[i].size == 0)
+							inf.fragments++;
+						
+						inf.bytes += os->fragsize - os->buffers[i].size;
+					}
+				}
+				
+				inf.fragsize = os->fragsize / os->dma2usr_ratio;
+				inf.fragstotal = os->nbfrags;
+				inf.bytes = inf.bytes / os->dma2usr_ratio;
+			
+				return copy_to_user((void *)arg, &inf, sizeof(inf));
+		    }
+
+		case SNDCTL_DSP_GETISPACE:
+		    {
+				audio_buf_info inf = { 0, };
+				int i;
+
+			 	DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_GETISPACE\n");
+
+				if (!(file->f_mode & FMODE_READ))
+					return -EINVAL;
+				if (!is->buffers && audio_allocate_buffers( state, is))
+					return -ENOMEM;
+					
+				for (i = 0; i < is->nbfrags; i++) 
+				{
+					if (atomic_read(&is->buffers[i].sem.count) > 0) 
+					{
+						if (is->buffers[i].size == is->fragsize)
+							inf.fragments++;
+						
+						inf.bytes += is->buffers[i].size;
+					}
+				}
+				
+				inf.fragsize = is->fragsize / is->dma2usr_ratio;
+				inf.fragstotal = is->nbfrags;
+				inf.bytes = inf.bytes / is->dma2usr_ratio;
+
+				return copy_to_user((void *)arg, &inf, sizeof(inf));
+		    }
+
+		case SNDCTL_DSP_NONBLOCK:
+			DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_NONBLOCK\n");
+			file->f_flags |= O_NONBLOCK;
+			return 0;
+
+		case SNDCTL_DSP_RESET:
+			DPRINTK_IOCTL("audio_ioctl - SNDCTL_DSP_RESET\n");
+			if (file->f_mode & FMODE_READ) 
+				audio_reset_buffers(state,is);
+			if (file->f_mode & FMODE_WRITE) 
+				audio_reset_buffers(state,os);
+			return 0;
+
+		default:
+			/*
+			 * Let the client of this module handle the
+			 * non generic ioctls
+			 */
+			return state->hw->client_ioctl(inode, file, cmd, arg);
+	}
+
+	return 0;
+}
+
+
+static int audio_release(struct inode *inode, struct file *file)
+{
+	audio_state_t *state = (audio_state_t *)file->private_data;
+	int i;
+
+	DPRINTK("EP93xx - audio_release -- enter.  Write=%d  Read=%d\n",
+			((file->f_mode & FMODE_WRITE) != 0),
+			((file->f_mode & FMODE_READ) != 0)	);
+
+	down(&state->sem);
+
+	if (file->f_mode & FMODE_READ) 
+	{
+		audio_deallocate_buffers(state, state->input_stream);
+		
+		for( i=0 ; i < state->input_stream->NumDmaChannels ; i++ )
+			ep93xx_dma_free( state->input_stream->dmahandles[i] );
+
+		state->rd_ref = 0;
+	}
+
+	if (file->f_mode & FMODE_WRITE) 
+	{
+		/*
+		 * Wait for all our buffers to play.
+		 */
+		audio_sync(file);
+		
+		/*
+		 * audio_deallocate_buffers will pause and flush the dma
+		 * then deallocate the buffers.
+		 */
+		audio_deallocate_buffers(state, state->output_stream);
+		for( i=0 ; i < state->output_stream->NumDmaChannels ; i++ )
+			ep93xx_dma_free( state->output_stream->dmahandles[i] );
+
+		state->wr_ref = 0;
+	}
+
+	up(&state->sem);
+
+	DPRINTK("EP93xx - audio_release -- EXIT\n");
+
+	return 0;
+}
+
+/*
+ *  ep93xx_clear_stream_struct
+ *
+ *  Initialize stuff or at least clear it to zero for a stream structure.
+ */
+static void ep93xx_clear_stream_struct( audio_stream_t * stream )
+{
+	
+	stream->dmahandles[0] 		= 0;	/* handles for dma driver instances */
+	stream->dmahandles[1] 		= 0;	/* handles for dma driver instances */
+	stream->dmahandles[2] 		= 0;	/* handles for dma driver instances */
+	stream->NumDmaChannels		= 0;	/* 1, 2, or 3 DMA channels 			*/
+	stream->TX_dma_ch_bitfield	= 0;	/* which dma channels used for strm */
+	stream->RX_dma_ch_bitfield	= 0;	/* which dma channels used for strm */
+	stream->buffers				= 0;	/* array of audio buffer structures */
+	stream->dma_buffer			= 0;	/* current buffer used by read/write */
+	stream->dma_buffer_index	= 0;	/* index for the pointer above... 	*/
+	stream->fragsize			= AUDIO_FRAGSIZE_DEFAULT;	/* fragment i.e. buffer size 		*/
+	stream->nbfrags				= AUDIO_NBFRAGS_DEFAULT;	/* nbr of fragments i.e. buffers 	*/
+	stream->requested_fragsize	= 0;	/* This is ignored if 0 */
+	stream->requested_nbfrags	= 0;	/* This is ignored if 0 */
+	stream->bytecount			= 0;	/* nbr of processed bytes 			*/
+	stream->getptrCount			= 0;	/* value of bytecount last time 	*/
+	 							  		/* anyone asked via GETxPTR 		*/
+	stream->fragcount			= 0;	/* nbr of fragment transitions 		*/
+	stream->mapped				= 0;	/* mmap()'ed buffers 				*/
+	stream->active				= 0;	/* actually in progress 			*/
+	stream->stopped				= 0;	/* might be active but stopped 		*/
+	stream->bFirstCaptureBuffer = 1;	/* flag meaning there is junk in rx fifo */
+	stream->buffered_bytes_to_play = 0;
+	
+	calculate_dma2usr_ratio_etc( stream );
+}
+
+/*
+ *	ep93xx_audio_attach
+ *
+ *  Initialize the state structure for read or write.  Allocate dma channels.
+ *  Currently each s is a stereo s (one dma channel).
+ *
+ */
+int ep93xx_audio_attach
+(
+	struct inode *inode, 
+	struct file *file,
+	audio_state_t *state
+)
+{
+	int err, i;
+	audio_stream_t *os = state->output_stream;
+	audio_stream_t *is = state->input_stream;
+
+	DPRINTK("ep93xx_audio_attach -- enter.  Write=%d  Read=%d\n",
+			((file->f_mode & FMODE_WRITE) != 0),
+			((file->f_mode & FMODE_READ) != 0)	);
+
+	down(&state->sem);
+
+	/* access control */
+	if( ((file->f_mode & FMODE_WRITE) && !os) ||
+	    ((file->f_mode & FMODE_READ) && !is) )
+	{
+		up(&state->sem);
+		return -ENODEV;
+	}
+
+	if( ((file->f_mode & FMODE_WRITE) && state->wr_ref) ||
+	    ((file->f_mode & FMODE_READ) && state->rd_ref) )
+	{
+		up(&state->sem);
+		return -EBUSY;
+	}
+
+	/* 
+	 * Request DMA channels 
+	 */
+	if( file->f_mode & FMODE_WRITE ) 
+	{
+		DPRINTK("ep93xx_audio_attach -- FMODE_WRITE\n");
+		
+		state->wr_ref = 1;
+
+		ep93xx_clear_stream_struct( os );
+	
+		err = ep93xx_dma_request( 	&os->dmahandles[0], 
+									os->devicename,
+                       				os->dmachannel[0] );
+		if (err)
+		{
+			up(&state->sem);
+			DPRINTK("ep93xx_audio_attach -- EXIT ERROR dma request failed\n");
+			return err;
+		}
+
+		err = ep93xx_dma_config( 	os->dmahandles[0], 
+									IGNORE_CHANNEL_ERROR, 
+									0,
+									audio_dma_tx_callback, 
+									(unsigned int)state );
+		if (err) 
+		{
+			ep93xx_dma_free( os->dmahandles[0] );
+			up(&state->sem);
+			DPRINTK("ep93xx_audio_attach -- EXIT ERROR dma config failed\n");
+			return err;
+		}
+
+		/*
+		 * Assuming each audio stream is mono or stereo.
+		 */
+		os->NumDmaChannels = 1;
+
+		/*
+		 * Automatically set up the bit field of dma channels used for
+		 * this stream.
+		 */
+		for( i=0 ; ( i < state->hw->MaxTxDmaChannels ) ; i++ )
+		{
+			if( os->dmachannel[i] == state->hw->txdmachannels[0] )
+				os->TX_dma_ch_bitfield |= 1;	
+
+			if( os->dmachannel[i] == state->hw->txdmachannels[1] )
+				os->TX_dma_ch_bitfield |= 2;	
+			
+			if( os->dmachannel[i] == state->hw->txdmachannels[2] )
+				os->TX_dma_ch_bitfield |= 4;	
+		}
+		
+		DPRINTK("DMA Tx channel bitfield = %x\n", os->TX_dma_ch_bitfield );
+
+		if (state->hw->hw_clear_fifo)
+			state->hw->hw_clear_fifo( os );
+
+		init_waitqueue_head(&os->wq);
+	}
+	
+	if( file->f_mode & FMODE_READ ) 
+	{
+		state->rd_ref = 1;
+		
+		ep93xx_clear_stream_struct( is );
+
+		err = ep93xx_dma_request( 	&is->dmahandles[0], 
+									is->devicename,
+                       				is->dmachannel[0] );
+		if (err) 
+		{
+			up(&state->sem);
+			DPRINTK("ep93xx_audio_attach -- EXIT ERROR dma request failed\n");
+			return err;
+		}
+
+		err = ep93xx_dma_config( 	is->dmahandles[0], 
+									IGNORE_CHANNEL_ERROR, 
+									0,
+									audio_dma_rx_callback, 
+									(unsigned int)state );
+		if (err) 
+		{
+			ep93xx_dma_free( is->dmahandles[0] );
+			up(&state->sem);
+			DPRINTK("ep93xx_audio_attach -- EXIT ERROR dma config failed\n");
+			return err;
+		}
+
+		is->NumDmaChannels = 1;
+
+		/*
+		 * Automatically set up the bit field of dma channels used for
+		 * this stream.
+		 */
+		for( i=0 ; ( i < state->hw->MaxRxDmaChannels ) ; i++ )
+		{
+			if( is->dmachannel[i] == state->hw->rxdmachannels[0] )
+				is->RX_dma_ch_bitfield |= 1;	
+
+			if( is->dmachannel[i] == state->hw->rxdmachannels[1] )
+				is->RX_dma_ch_bitfield |= 2;	
+
+			if( is->dmachannel[i] == state->hw->rxdmachannels[2] )
+				is->RX_dma_ch_bitfield |= 4;	
+		}
+
+		DPRINTK("DMA Rx channel bitfield = %x\n", is->RX_dma_ch_bitfield );
+
+		init_waitqueue_head(&is->wq);
+	}
+
+	/*
+	 * Fill out the rest of the file_operations struct.
+	 */
+	file->private_data	= state;
+	file->f_op->release	= audio_release;
+	file->f_op->write	= audio_write;
+	file->f_op->read	= audio_read;
+	file->f_op->mmap	= audio_mmap;
+	file->f_op->poll	= audio_poll;
+	file->f_op->ioctl	= audio_ioctl;
+	file->f_op->llseek	= no_llseek;
+
+	up(&state->sem);
+
+	DPRINTK("ep93xx_audio_attach -- EXIT\n");
+
+	return 0;
+}
+
+EXPORT_SYMBOL(ep93xx_audio_attach);
+
+MODULE_DESCRIPTION("Common audio handling for the Cirrus EP93xx processor");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/drivers/sound/ep93xx-audio.h linux-2.4.29-uc1/drivers/sound/ep93xx-audio.h
--- linux-2.4.29/drivers/sound/ep93xx-audio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/sound/ep93xx-audio.h	2005-06-14 02:12:05.000000000 +0100
@@ -0,0 +1,150 @@
+/*
+ * ep93xx-audio.h
+ *
+ * Common audio handling for the Cirrus Logic EP93xx
+ *
+ * Copyright (c) 2003 Cirrus Logic Corp.
+ * Copyright (c) 2000 Nicolas Pitre <nico@cam.org>
+ *
+ * Taken from sa1100-audio.h
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ */
+
+/*
+ *  Getting this from the rme96xx driver.  Has same numerical value
+ *  as AC3.  Hmmmm.
+ */
+#ifndef AFMT_S32_BLOCKED
+#define AFMT_S32_BLOCKED 0x0000400
+#endif
+
+#define EP93XX_DEFAULT_NUM_CHANNELS      2
+#define EP93XX_DEFAULT_FORMAT            AFMT_S16_LE
+#define EP93XX_DEFAULT_BIT_WIDTH         16
+
+/*
+ * Buffer Management
+ */
+
+typedef struct {
+
+	int 				size;			/* buffer size 						*/
+	int 				sent;			/* indicates that dma has the dma_buffer	*/
+	char 				*start;			/* points to actual buffer 			*/
+	dma_addr_t 			dma_addr;		/* physical buffer address 			*/
+	struct semaphore 	sem;			/* down before touching the buffer 	*/
+	int 				master;			/* owner for buffer allocation,    	*/
+										/* contains size when true 			*/
+	int					num;			/* which out of nbfrags buffers is this?  */
+	struct audio_stream_s 	*stream;	/* owning stream 					*/
+
+} audio_buf_t;
+
+#define MAX_DEVICE_NAME 20
+
+typedef struct audio_stream_s {
+
+	/* dma stuff */
+	int				dmahandles[3];		/* handles for dma driver instances */
+	char			devicename[MAX_DEVICE_NAME]; /* string - name of device */
+	int				NumDmaChannels;		/* 1, 2, or 3 DMA channels 			*/
+	ep93xx_dma_dev_t dmachannel[3];		/* dma channel numbers				*/
+	
+	audio_buf_t 	*buffers;			/* array of audio buffer structures */
+	audio_buf_t 	*dma_buffer;		/* current buffer used by read/write */
+	u_int 			dma_buffer_index;	/* index for the pointer above... 	*/
+
+	u_int 			fragsize;			/* fragment i.e. buffer size 		*/
+	u_int 			nbfrags;			/* nbr of fragments i.e. buffers 	*/
+	u_int			requested_fragsize;
+	u_int			requested_nbfrags;
+
+	int 			bytecount;			/* nbr of processed bytes 			*/
+	int 			getptrCount;		/* value of bytecount last time 	*/
+										/* anyone asked via GETxPTR 		*/
+	int 			fragcount;			/* nbr of fragment transitions 		*/
+	wait_queue_head_t 	wq;				/* for poll 						*/
+	int 			mapped:1;			/* mmap()'ed buffers 				*/
+	int 			active:1;			/* actually in progress 			*/
+	int 			stopped:1;			/* might be active but stopped 		*/
+	u_int			TX_dma_ch_bitfield;	/* bit0 = txdma1, bit1= txdma2, etc */
+	u_int			RX_dma_ch_bitfield;	/* bit0 = rxdma1, bit1= rxdma2, etc */
+	int				bFirstCaptureBuffer;/* flag meaning there is junk in rx fifo */
+	
+	/*
+	 * Data about the file format that we are configured to play.
+	 */
+	long 			audio_num_channels;			/* Range: 1 to 6 */
+	long 			audio_format;
+	long 			audio_stream_bitwidth;		/* Range: 8, 16, 24, 32 */
+
+	long			sample_rate;		/* Fs in Hz. */
+
+	/*
+	 * Data about how the audio controller and codec are set up.
+	 */
+	int			    hw_bit_width;		/* width of dac or adc */
+	int			    bCompactMode;		/* set if 32bits == a stereo sample */
+
+	/*
+	 * dma2usr_ratio = dma sample size (8 or 4 bytes) / usr sample size (8,4,2,1)
+	 */
+	int				dma2usr_ratio;
+
+	/*
+	 * This provides a way of determining audio playback position that will not
+	 * overflow.  This is (size of buffers written) - (buffers we've gotten back)
+	 */
+	int				buffered_bytes_to_play;
+
+} audio_stream_t;
+
+
+/*
+ * No matter how many streams are going, we are using one hardware device.
+ * This struct describes that hardware.
+ */
+typedef struct {
+
+	ep93xx_dma_dev_t	txdmachannels[3];	/* all dma channels available for */
+	ep93xx_dma_dev_t	rxdmachannels[3];	/* this audio ctrlr */
+	
+	int					MaxTxDmaChannels;	/* number of tx and rx channels */
+	int					MaxRxDmaChannels;	/* number of tx and rx channels */
+	
+	/*
+	 * Pointers to init, shutdown, and ioctl functions.
+	 */
+	void 				(*hw_enable)( audio_stream_t * stream);
+	void 				(*hw_disable)(audio_stream_t * stream);
+	void				(*hw_clear_fifo)(audio_stream_t * stream);
+	int 				(*client_ioctl)(struct inode *, struct file *, uint, ulong);
+	void				(*set_hw_serial_format)( audio_stream_t *, long );
+
+	unsigned int		modcnt; 			/* count the # of volume writes */
+
+} audio_hw_t;
+
+/*
+ * State structure for one instance
+ */
+typedef struct {
+	audio_stream_t 		*output_stream;
+	audio_stream_t 		*input_stream;
+
+	audio_hw_t			* hw;				/* hw info */
+	
+	int 				rd_ref:1;			/* open reference for recording */
+	int 				wr_ref:1;			/* open reference for playback */
+	
+	struct 				semaphore sem;		/* to protect against races in attach() */
+
+} audio_state_t;
+
+/*
+ * Functions exported by this module
+ */
+extern int ep93xx_audio_attach( struct inode *inode, 
+								struct file *file,
+								audio_state_t *state);
diff -urN linux-2.4.29/drivers/sound/ep93xx-i2s.c linux-2.4.29-uc1/drivers/sound/ep93xx-i2s.c
--- linux-2.4.29/drivers/sound/ep93xx-i2s.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/sound/ep93xx-i2s.c	2005-06-14 02:12:04.000000000 +0100
@@ -0,0 +1,1709 @@
+/*
+ * Glue audio driver for the Cirrus EP93xx I2S Controller
+ *
+ * Copyright (c) 2003 Cirrus Logic Corp.
+ * Copyright (c) 2000 Nicolas Pitre <nico@cam.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ *
+ * This file taken from h3600-uda1341.c
+ *
+ * History:
+ *
+ * 2000-05-21	Nicolas Pitre	Initial UDA1341 driver release.
+ *
+ * 2000-07-??	George France	Bitsy support.
+ *
+ * 2000-12-13	Deborah Wallach Fixed power handling for iPAQ/h3600
+ *
+ * 2001-06-03	Nicolas Pitre	Made this file a separate module, based on
+ *				the former sa1100-uda1341.c driver.
+ *
+ * 2001-07-13	Nicolas Pitre	Fixes for all supported samplerates.
+ *
+ * 2003-04-04   Changes for Cirrus Logic EP93xx
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/errno.h>
+#include <linux/sound.h>
+#include <linux/soundcard.h>
+
+#include <asm/semaphore.h>
+#include <asm/uaccess.h>
+#include <asm/hardware.h>
+#include <asm/dma.h>
+#include <asm/arch/ssp.h>
+#include <asm/io.h>
+
+#include "ep93xx-audio.h"
+
+
+#undef DEBUG
+// #define DEBUG 1
+#ifdef DEBUG
+#define DPRINTK( fmt, arg... )  printk( fmt, ##arg )
+#else
+#define DPRINTK( fmt, arg... )
+#endif
+
+
+#define AUDIO_SAMPLE_RATE_DEFAULT	44100
+
+/*
+ * OSS mixer volume levels are 16 bit with two 8 bit fields for left and right.
+ * Each is in % of full.  So range is 0..100 for each of two channels.
+ */ 
+#define AUDIO_DEFAULT_VOLUME ( (100<<8) | 100 )
+
+/*
+ * Statics
+ */
+static int giOSS_Volume[3] = 
+	{AUDIO_DEFAULT_VOLUME,AUDIO_DEFAULT_VOLUME,AUDIO_DEFAULT_VOLUME};
+static int giDAC_Volume_L[3] = {0,0,0};
+static int giDAC_Volume_R[3] = {0,0,0};
+static int giDAC_Mute = 0;
+
+static int audio_clocks_enabled_in_syscon = 0;
+static int SSP_Handle = -1;
+static int audio_dev_id0, mixer_dev_id;
+#ifdef CONFIG_CODEC_CS4228A
+static int audio_dev_id1, audio_dev_id2;
+#endif
+
+/* prototypes */
+static void ep93xx_audio_enable_all(void);
+static void ep93xx_audio_disable_all(void);
+static void ep93xx_clear_i2s_fifo( audio_stream_t * stream );
+static int ep93xx_calc_closest_freq
+(
+    ulong   ulPLLFreq, 
+    ulong   ulRequestedMClkFreq,
+    ulong * pulActualMClkFreq,
+    ulong * pulI2SDiv
+);
+static void ep93xx_set_samplerate(long lFrequency);
+static void ep93xx_init_i2s_controller( void );
+
+static void ep93xx_init_i2s_codec( void );
+// static void ep93xx_mute_i2s_codec( void );
+static void ep93xx_automute_i2s_codec( void );
+static int ep93xx_set_volume( int channel, int val );
+
+static int ep93xx_mixer_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg);
+
+static void ep93xx_audio_init(void *dummy);
+static int ep93xx_audio_ioctl(struct inode *inode, struct file *file,
+			     uint cmd, ulong arg);
+				 
+static int ep93xx_audio_open0(struct inode *inode, struct file *file);
+#ifdef CONFIG_CODEC_CS4228A
+static int ep93xx_audio_open1(struct inode *inode, struct file *file);
+static int ep93xx_audio_open2(struct inode *inode, struct file *file);
+#endif
+
+static int __init ep93xx_i2s_init(void);
+static void __exit ep93xx_i2s_exit(void);
+
+static audio_stream_t i2s_output_stream0 =
+{
+	audio_num_channels: 	EP93XX_DEFAULT_NUM_CHANNELS,
+	audio_format: 			EP93XX_DEFAULT_FORMAT,
+	audio_stream_bitwidth: 	EP93XX_DEFAULT_BIT_WIDTH,
+	devicename:				"I2S_out_0",
+	dmachannel:				{ DMATx_I2S1, UNDEF, UNDEF },
+	sample_rate:			0,
+	hw_bit_width:			24,
+	bCompactMode:			0,
+};
+
+#if defined(CONFIG_ARCH_EDB9312) || defined(CONFIG_ARCH_EDB9315)
+static audio_stream_t i2s_output_stream1 =
+{
+	audio_num_channels: 	EP93XX_DEFAULT_NUM_CHANNELS,
+	audio_format: 			EP93XX_DEFAULT_FORMAT,
+	audio_stream_bitwidth: 	EP93XX_DEFAULT_BIT_WIDTH,
+	devicename:				"I2S_out_1",
+	dmachannel:				{ DMATx_I2S2, UNDEF, UNDEF },
+	sample_rate:			0,
+	hw_bit_width:			24,
+	bCompactMode:			0,
+};
+static audio_stream_t i2s_output_stream2 =
+{
+	audio_num_channels: 	EP93XX_DEFAULT_NUM_CHANNELS,
+	audio_format: 			EP93XX_DEFAULT_FORMAT,
+	audio_stream_bitwidth: 	EP93XX_DEFAULT_BIT_WIDTH,
+	devicename:				"I2S_out_2",
+	dmachannel:				{ DMATx_I2S3, UNDEF, UNDEF },
+	sample_rate:			0,
+	hw_bit_width:			24,
+	bCompactMode:			0,
+};
+#endif
+
+static audio_stream_t i2s_input_stream0 =
+{
+	audio_num_channels: 	EP93XX_DEFAULT_NUM_CHANNELS,
+	audio_format: 			EP93XX_DEFAULT_FORMAT,
+	audio_stream_bitwidth: 	EP93XX_DEFAULT_BIT_WIDTH,
+	devicename:				"I2S_in_0",
+	dmachannel:				{ DMARx_I2S1, UNDEF, UNDEF },
+	sample_rate:			0,
+	hw_bit_width:			24,
+	bCompactMode:			0,
+};
+
+/*
+ * The EDB9315, EDB9312, and EDB9301 boards all have one I2S input.
+ * If you want more inputs and you have the ADC's for it, enable
+ * this code.
+ */
+#if 0
+static audio_stream_t i2s_input_stream1 =
+{
+	audio_num_channels: 	EP93XX_DEFAULT_NUM_CHANNELS,
+	audio_format: 			EP93XX_DEFAULT_FORMAT,
+	audio_stream_bitwidth: 	EP93XX_DEFAULT_BIT_WIDTH,
+	devicename:				"I2S_in_1",
+	dmachannel:				{ DMARx_I2S2, UNDEF, UNDEF },
+	sample_rate:			0,
+	hw_bit_width:			24,
+	bCompactMode:			0,
+};
+static audio_stream_t i2s_input_stream2 =
+{
+	audio_num_channels: 	EP93XX_DEFAULT_NUM_CHANNELS,
+	audio_format: 			EP93XX_DEFAULT_FORMAT,
+	audio_stream_bitwidth: 	EP93XX_DEFAULT_BIT_WIDTH,
+	devicename:				"I2S_in_2",
+	dmachannel:				{ DMARx_I2S3, UNDEF, UNDEF },
+	sample_rate:			0,
+	hw_bit_width:			24,
+	bCompactMode:			0,
+};
+#endif
+
+static audio_hw_t ep93xx_i2s_hw =
+{
+	client_ioctl:		ep93xx_audio_ioctl,
+	hw_enable:          0,
+	hw_disable:         0,
+	hw_clear_fifo:		ep93xx_clear_i2s_fifo,
+	
+	set_hw_serial_format:  0,
+
+	txdmachannels:		{ DMATx_I2S1, DMATx_I2S2, DMATx_I2S3 },
+	rxdmachannels:		{ DMARx_I2S1, DMARx_I2S2, DMARx_I2S3 },
+	
+	MaxTxDmaChannels:	3,
+	MaxRxDmaChannels:	3,
+
+	modcnt:				0,
+};
+
+/*
+ * Each /dev/dsp* device is a 'state' with one input and one output stream.
+ */
+static audio_state_t audio_state0 =
+{
+	output_stream:		&i2s_output_stream0,
+	input_stream:		&i2s_input_stream0,
+	sem:				__MUTEX_INITIALIZER(audio_state0.sem),
+	hw:					&ep93xx_i2s_hw,
+	wr_ref:				0,
+	rd_ref:				0,
+};
+
+#if CONFIG_CODEC_CS4228A
+static audio_state_t audio_state1 =
+{
+	output_stream:		&i2s_output_stream1,
+	input_stream:		0, /* &i2s_input_stream1, */
+	sem:				__MUTEX_INITIALIZER(audio_state1.sem),
+	hw:					&ep93xx_i2s_hw,
+	wr_ref:				0,
+	rd_ref:				0,
+};
+static audio_state_t audio_state2 =
+{
+	output_stream:		&i2s_output_stream2,
+	input_stream:		0, /* &i2s_input_stream2, */
+	sem:				__MUTEX_INITIALIZER(audio_state2.sem),
+	hw:					&ep93xx_i2s_hw,
+	wr_ref:				0,
+	rd_ref:				0,
+};
+#endif
+
+
+typedef struct {
+    ulong   ulTotalDiv;
+    ulong   ulI2SDiv;
+} DIV_TABLE;
+
+static const DIV_TABLE I2SDivTable[] =
+{
+    {   6, SYSCON_I2SDIV_PDIV_2  | (  2 & SYSCON_I2SDIV_MDIV_MASK) },  /* Fake entry for lower limit. */
+    {   8, SYSCON_I2SDIV_PDIV_2  | (  2 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  10, SYSCON_I2SDIV_PDIV_25 | (  2 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  12, SYSCON_I2SDIV_PDIV_3  | (  2 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  15, SYSCON_I2SDIV_PDIV_25 | (  3 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  16, SYSCON_I2SDIV_PDIV_2  | (  4 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  18, SYSCON_I2SDIV_PDIV_3  | (  3 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  20, SYSCON_I2SDIV_PDIV_25 | (  4 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  24, SYSCON_I2SDIV_PDIV_3  | (  4 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  25, SYSCON_I2SDIV_PDIV_25 | (  5 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  28, SYSCON_I2SDIV_PDIV_2  | (  7 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  30, SYSCON_I2SDIV_PDIV_3  | (  5 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  32, SYSCON_I2SDIV_PDIV_2  | (  8 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  35, SYSCON_I2SDIV_PDIV_25 | (  7 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  36, SYSCON_I2SDIV_PDIV_3  | (  6 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  40, SYSCON_I2SDIV_PDIV_25 | (  8 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  42, SYSCON_I2SDIV_PDIV_3  | (  7 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  44, SYSCON_I2SDIV_PDIV_2  | ( 11 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  45, SYSCON_I2SDIV_PDIV_25 | (  9 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  48, SYSCON_I2SDIV_PDIV_3  | (  8 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  50, SYSCON_I2SDIV_PDIV_25 | ( 10 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  52, SYSCON_I2SDIV_PDIV_2  | ( 13 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  54, SYSCON_I2SDIV_PDIV_3  | (  9 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  55, SYSCON_I2SDIV_PDIV_25 | ( 11 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  56, SYSCON_I2SDIV_PDIV_2  | ( 14 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  60, SYSCON_I2SDIV_PDIV_3  | ( 10 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  64, SYSCON_I2SDIV_PDIV_2  | ( 16 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  65, SYSCON_I2SDIV_PDIV_25 | ( 13 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  66, SYSCON_I2SDIV_PDIV_3  | ( 11 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  68, SYSCON_I2SDIV_PDIV_2  | ( 17 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  70, SYSCON_I2SDIV_PDIV_25 | ( 14 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  72, SYSCON_I2SDIV_PDIV_3  | ( 12 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  75, SYSCON_I2SDIV_PDIV_25 | ( 15 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  76, SYSCON_I2SDIV_PDIV_2  | ( 19 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  78, SYSCON_I2SDIV_PDIV_3  | ( 13 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  80, SYSCON_I2SDIV_PDIV_25 | ( 16 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  84, SYSCON_I2SDIV_PDIV_3  | ( 14 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  85, SYSCON_I2SDIV_PDIV_25 | ( 17 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  88, SYSCON_I2SDIV_PDIV_2  | ( 22 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  90, SYSCON_I2SDIV_PDIV_3  | ( 15 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  92, SYSCON_I2SDIV_PDIV_2  | ( 23 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  95, SYSCON_I2SDIV_PDIV_25 | ( 19 & SYSCON_I2SDIV_MDIV_MASK) },
+    {  96, SYSCON_I2SDIV_PDIV_3  | ( 16 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 100, SYSCON_I2SDIV_PDIV_25 | ( 20 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 102, SYSCON_I2SDIV_PDIV_3  | ( 17 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 104, SYSCON_I2SDIV_PDIV_2  | ( 26 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 105, SYSCON_I2SDIV_PDIV_25 | ( 21 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 108, SYSCON_I2SDIV_PDIV_3  | ( 18 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 110, SYSCON_I2SDIV_PDIV_25 | ( 22 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 112, SYSCON_I2SDIV_PDIV_2  | ( 28 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 114, SYSCON_I2SDIV_PDIV_3  | ( 19 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 115, SYSCON_I2SDIV_PDIV_25 | ( 23 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 116, SYSCON_I2SDIV_PDIV_2  | ( 29 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 120, SYSCON_I2SDIV_PDIV_3  | ( 20 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 124, SYSCON_I2SDIV_PDIV_2  | ( 31 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 125, SYSCON_I2SDIV_PDIV_25 | ( 25 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 126, SYSCON_I2SDIV_PDIV_3  | ( 21 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 128, SYSCON_I2SDIV_PDIV_2  | ( 32 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 130, SYSCON_I2SDIV_PDIV_25 | ( 26 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 132, SYSCON_I2SDIV_PDIV_3  | ( 22 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 135, SYSCON_I2SDIV_PDIV_25 | ( 27 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 136, SYSCON_I2SDIV_PDIV_2  | ( 34 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 138, SYSCON_I2SDIV_PDIV_3  | ( 23 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 140, SYSCON_I2SDIV_PDIV_25 | ( 28 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 144, SYSCON_I2SDIV_PDIV_3  | ( 24 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 145, SYSCON_I2SDIV_PDIV_25 | ( 29 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 148, SYSCON_I2SDIV_PDIV_2  | ( 37 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 150, SYSCON_I2SDIV_PDIV_3  | ( 25 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 152, SYSCON_I2SDIV_PDIV_2  | ( 38 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 155, SYSCON_I2SDIV_PDIV_25 | ( 31 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 156, SYSCON_I2SDIV_PDIV_3  | ( 26 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 160, SYSCON_I2SDIV_PDIV_25 | ( 32 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 162, SYSCON_I2SDIV_PDIV_3  | ( 27 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 164, SYSCON_I2SDIV_PDIV_2  | ( 41 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 165, SYSCON_I2SDIV_PDIV_25 | ( 33 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 168, SYSCON_I2SDIV_PDIV_3  | ( 28 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 170, SYSCON_I2SDIV_PDIV_25 | ( 34 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 172, SYSCON_I2SDIV_PDIV_2  | ( 43 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 174, SYSCON_I2SDIV_PDIV_3  | ( 29 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 175, SYSCON_I2SDIV_PDIV_25 | ( 35 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 176, SYSCON_I2SDIV_PDIV_2  | ( 44 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 180, SYSCON_I2SDIV_PDIV_3  | ( 30 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 184, SYSCON_I2SDIV_PDIV_2  | ( 46 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 185, SYSCON_I2SDIV_PDIV_25 | ( 37 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 186, SYSCON_I2SDIV_PDIV_3  | ( 31 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 188, SYSCON_I2SDIV_PDIV_2  | ( 47 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 190, SYSCON_I2SDIV_PDIV_25 | ( 38 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 192, SYSCON_I2SDIV_PDIV_3  | ( 32 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 195, SYSCON_I2SDIV_PDIV_25 | ( 39 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 196, SYSCON_I2SDIV_PDIV_2  | ( 49 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 198, SYSCON_I2SDIV_PDIV_3  | ( 33 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 200, SYSCON_I2SDIV_PDIV_25 | ( 40 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 204, SYSCON_I2SDIV_PDIV_3  | ( 34 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 205, SYSCON_I2SDIV_PDIV_25 | ( 41 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 208, SYSCON_I2SDIV_PDIV_2  | ( 52 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 210, SYSCON_I2SDIV_PDIV_3  | ( 35 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 212, SYSCON_I2SDIV_PDIV_2  | ( 53 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 215, SYSCON_I2SDIV_PDIV_25 | ( 43 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 216, SYSCON_I2SDIV_PDIV_3  | ( 36 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 220, SYSCON_I2SDIV_PDIV_25 | ( 44 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 222, SYSCON_I2SDIV_PDIV_3  | ( 37 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 224, SYSCON_I2SDIV_PDIV_2  | ( 56 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 225, SYSCON_I2SDIV_PDIV_25 | ( 45 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 228, SYSCON_I2SDIV_PDIV_3  | ( 38 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 230, SYSCON_I2SDIV_PDIV_25 | ( 46 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 232, SYSCON_I2SDIV_PDIV_2  | ( 58 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 234, SYSCON_I2SDIV_PDIV_3  | ( 39 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 235, SYSCON_I2SDIV_PDIV_25 | ( 47 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 236, SYSCON_I2SDIV_PDIV_2  | ( 59 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 240, SYSCON_I2SDIV_PDIV_3  | ( 40 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 244, SYSCON_I2SDIV_PDIV_2  | ( 61 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 245, SYSCON_I2SDIV_PDIV_25 | ( 49 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 246, SYSCON_I2SDIV_PDIV_3  | ( 41 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 248, SYSCON_I2SDIV_PDIV_2  | ( 62 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 250, SYSCON_I2SDIV_PDIV_25 | ( 50 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 252, SYSCON_I2SDIV_PDIV_3  | ( 42 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 255, SYSCON_I2SDIV_PDIV_25 | ( 51 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 256, SYSCON_I2SDIV_PDIV_2  | ( 64 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 258, SYSCON_I2SDIV_PDIV_3  | ( 43 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 260, SYSCON_I2SDIV_PDIV_25 | ( 52 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 264, SYSCON_I2SDIV_PDIV_3  | ( 44 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 265, SYSCON_I2SDIV_PDIV_25 | ( 53 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 268, SYSCON_I2SDIV_PDIV_2  | ( 67 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 270, SYSCON_I2SDIV_PDIV_3  | ( 45 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 272, SYSCON_I2SDIV_PDIV_2  | ( 68 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 275, SYSCON_I2SDIV_PDIV_25 | ( 55 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 276, SYSCON_I2SDIV_PDIV_3  | ( 46 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 280, SYSCON_I2SDIV_PDIV_25 | ( 56 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 282, SYSCON_I2SDIV_PDIV_3  | ( 47 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 284, SYSCON_I2SDIV_PDIV_2  | ( 71 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 285, SYSCON_I2SDIV_PDIV_25 | ( 57 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 288, SYSCON_I2SDIV_PDIV_3  | ( 48 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 290, SYSCON_I2SDIV_PDIV_25 | ( 58 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 292, SYSCON_I2SDIV_PDIV_2  | ( 73 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 294, SYSCON_I2SDIV_PDIV_3  | ( 49 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 295, SYSCON_I2SDIV_PDIV_25 | ( 59 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 296, SYSCON_I2SDIV_PDIV_2  | ( 74 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 300, SYSCON_I2SDIV_PDIV_3  | ( 50 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 304, SYSCON_I2SDIV_PDIV_2  | ( 76 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 305, SYSCON_I2SDIV_PDIV_25 | ( 61 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 306, SYSCON_I2SDIV_PDIV_3  | ( 51 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 308, SYSCON_I2SDIV_PDIV_2  | ( 77 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 310, SYSCON_I2SDIV_PDIV_25 | ( 62 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 312, SYSCON_I2SDIV_PDIV_3  | ( 52 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 315, SYSCON_I2SDIV_PDIV_25 | ( 63 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 316, SYSCON_I2SDIV_PDIV_2  | ( 79 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 318, SYSCON_I2SDIV_PDIV_3  | ( 53 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 320, SYSCON_I2SDIV_PDIV_25 | ( 64 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 324, SYSCON_I2SDIV_PDIV_3  | ( 54 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 325, SYSCON_I2SDIV_PDIV_25 | ( 65 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 328, SYSCON_I2SDIV_PDIV_2  | ( 82 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 330, SYSCON_I2SDIV_PDIV_3  | ( 55 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 332, SYSCON_I2SDIV_PDIV_2  | ( 83 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 335, SYSCON_I2SDIV_PDIV_25 | ( 67 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 336, SYSCON_I2SDIV_PDIV_3  | ( 56 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 340, SYSCON_I2SDIV_PDIV_25 | ( 68 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 342, SYSCON_I2SDIV_PDIV_3  | ( 57 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 344, SYSCON_I2SDIV_PDIV_2  | ( 86 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 345, SYSCON_I2SDIV_PDIV_25 | ( 69 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 348, SYSCON_I2SDIV_PDIV_3  | ( 58 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 350, SYSCON_I2SDIV_PDIV_25 | ( 70 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 352, SYSCON_I2SDIV_PDIV_2  | ( 88 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 354, SYSCON_I2SDIV_PDIV_3  | ( 59 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 355, SYSCON_I2SDIV_PDIV_25 | ( 71 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 356, SYSCON_I2SDIV_PDIV_2  | ( 89 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 360, SYSCON_I2SDIV_PDIV_3  | ( 60 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 364, SYSCON_I2SDIV_PDIV_2  | ( 91 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 365, SYSCON_I2SDIV_PDIV_25 | ( 73 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 366, SYSCON_I2SDIV_PDIV_3  | ( 61 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 368, SYSCON_I2SDIV_PDIV_2  | ( 92 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 370, SYSCON_I2SDIV_PDIV_25 | ( 74 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 372, SYSCON_I2SDIV_PDIV_3  | ( 62 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 375, SYSCON_I2SDIV_PDIV_25 | ( 75 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 376, SYSCON_I2SDIV_PDIV_2  | ( 94 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 378, SYSCON_I2SDIV_PDIV_3  | ( 63 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 380, SYSCON_I2SDIV_PDIV_25 | ( 76 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 384, SYSCON_I2SDIV_PDIV_3  | ( 64 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 385, SYSCON_I2SDIV_PDIV_25 | ( 77 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 388, SYSCON_I2SDIV_PDIV_2  | ( 97 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 390, SYSCON_I2SDIV_PDIV_3  | ( 65 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 392, SYSCON_I2SDIV_PDIV_2  | ( 98 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 395, SYSCON_I2SDIV_PDIV_25 | ( 79 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 396, SYSCON_I2SDIV_PDIV_3  | ( 66 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 400, SYSCON_I2SDIV_PDIV_25 | ( 80 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 402, SYSCON_I2SDIV_PDIV_3  | ( 67 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 404, SYSCON_I2SDIV_PDIV_2  | (101 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 405, SYSCON_I2SDIV_PDIV_25 | ( 81 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 408, SYSCON_I2SDIV_PDIV_3  | ( 68 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 410, SYSCON_I2SDIV_PDIV_25 | ( 82 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 412, SYSCON_I2SDIV_PDIV_2  | (103 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 414, SYSCON_I2SDIV_PDIV_3  | ( 69 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 415, SYSCON_I2SDIV_PDIV_25 | ( 83 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 416, SYSCON_I2SDIV_PDIV_2  | (104 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 420, SYSCON_I2SDIV_PDIV_3  | ( 70 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 424, SYSCON_I2SDIV_PDIV_2  | (106 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 425, SYSCON_I2SDIV_PDIV_25 | ( 85 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 426, SYSCON_I2SDIV_PDIV_3  | ( 71 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 428, SYSCON_I2SDIV_PDIV_2  | (107 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 430, SYSCON_I2SDIV_PDIV_25 | ( 86 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 432, SYSCON_I2SDIV_PDIV_3  | ( 72 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 435, SYSCON_I2SDIV_PDIV_25 | ( 87 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 436, SYSCON_I2SDIV_PDIV_2  | (109 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 438, SYSCON_I2SDIV_PDIV_3  | ( 73 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 440, SYSCON_I2SDIV_PDIV_25 | ( 88 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 444, SYSCON_I2SDIV_PDIV_3  | ( 74 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 445, SYSCON_I2SDIV_PDIV_25 | ( 89 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 448, SYSCON_I2SDIV_PDIV_2  | (112 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 450, SYSCON_I2SDIV_PDIV_3  | ( 75 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 452, SYSCON_I2SDIV_PDIV_2  | (113 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 455, SYSCON_I2SDIV_PDIV_25 | ( 91 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 456, SYSCON_I2SDIV_PDIV_3  | ( 76 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 460, SYSCON_I2SDIV_PDIV_25 | ( 92 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 462, SYSCON_I2SDIV_PDIV_3  | ( 77 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 464, SYSCON_I2SDIV_PDIV_2  | (116 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 465, SYSCON_I2SDIV_PDIV_25 | ( 93 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 468, SYSCON_I2SDIV_PDIV_3  | ( 78 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 470, SYSCON_I2SDIV_PDIV_25 | ( 94 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 472, SYSCON_I2SDIV_PDIV_2  | (118 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 474, SYSCON_I2SDIV_PDIV_3  | ( 79 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 475, SYSCON_I2SDIV_PDIV_25 | ( 95 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 476, SYSCON_I2SDIV_PDIV_2  | (119 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 480, SYSCON_I2SDIV_PDIV_3  | ( 80 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 484, SYSCON_I2SDIV_PDIV_2  | (121 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 485, SYSCON_I2SDIV_PDIV_25 | ( 97 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 486, SYSCON_I2SDIV_PDIV_3  | ( 81 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 488, SYSCON_I2SDIV_PDIV_2  | (122 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 490, SYSCON_I2SDIV_PDIV_25 | ( 98 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 492, SYSCON_I2SDIV_PDIV_3  | ( 82 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 495, SYSCON_I2SDIV_PDIV_25 | ( 99 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 496, SYSCON_I2SDIV_PDIV_2  | (124 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 498, SYSCON_I2SDIV_PDIV_3  | ( 83 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 500, SYSCON_I2SDIV_PDIV_25 | (100 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 504, SYSCON_I2SDIV_PDIV_3  | ( 84 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 505, SYSCON_I2SDIV_PDIV_25 | (101 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 508, SYSCON_I2SDIV_PDIV_2  | (127 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 510, SYSCON_I2SDIV_PDIV_3  | ( 85 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 515, SYSCON_I2SDIV_PDIV_25 | (103 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 516, SYSCON_I2SDIV_PDIV_3  | ( 86 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 520, SYSCON_I2SDIV_PDIV_25 | (104 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 522, SYSCON_I2SDIV_PDIV_3  | ( 87 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 525, SYSCON_I2SDIV_PDIV_25 | (105 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 528, SYSCON_I2SDIV_PDIV_3  | ( 88 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 530, SYSCON_I2SDIV_PDIV_25 | (106 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 534, SYSCON_I2SDIV_PDIV_3  | ( 89 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 535, SYSCON_I2SDIV_PDIV_25 | (107 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 540, SYSCON_I2SDIV_PDIV_3  | ( 90 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 545, SYSCON_I2SDIV_PDIV_25 | (109 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 546, SYSCON_I2SDIV_PDIV_3  | ( 91 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 550, SYSCON_I2SDIV_PDIV_25 | (110 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 552, SYSCON_I2SDIV_PDIV_3  | ( 92 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 555, SYSCON_I2SDIV_PDIV_25 | (111 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 558, SYSCON_I2SDIV_PDIV_3  | ( 93 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 560, SYSCON_I2SDIV_PDIV_25 | (112 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 564, SYSCON_I2SDIV_PDIV_3  | ( 94 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 565, SYSCON_I2SDIV_PDIV_25 | (113 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 570, SYSCON_I2SDIV_PDIV_3  | ( 95 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 575, SYSCON_I2SDIV_PDIV_25 | (115 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 576, SYSCON_I2SDIV_PDIV_3  | ( 96 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 580, SYSCON_I2SDIV_PDIV_25 | (116 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 582, SYSCON_I2SDIV_PDIV_3  | ( 97 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 585, SYSCON_I2SDIV_PDIV_25 | (117 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 588, SYSCON_I2SDIV_PDIV_3  | ( 98 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 590, SYSCON_I2SDIV_PDIV_25 | (118 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 594, SYSCON_I2SDIV_PDIV_3  | ( 99 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 595, SYSCON_I2SDIV_PDIV_25 | (119 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 600, SYSCON_I2SDIV_PDIV_3  | (100 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 605, SYSCON_I2SDIV_PDIV_25 | (121 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 606, SYSCON_I2SDIV_PDIV_3  | (101 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 610, SYSCON_I2SDIV_PDIV_25 | (122 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 612, SYSCON_I2SDIV_PDIV_3  | (102 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 615, SYSCON_I2SDIV_PDIV_25 | (123 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 618, SYSCON_I2SDIV_PDIV_3  | (103 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 620, SYSCON_I2SDIV_PDIV_25 | (124 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 624, SYSCON_I2SDIV_PDIV_3  | (104 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 625, SYSCON_I2SDIV_PDIV_25 | (125 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 630, SYSCON_I2SDIV_PDIV_3  | (105 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 635, SYSCON_I2SDIV_PDIV_25 | (127 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 636, SYSCON_I2SDIV_PDIV_3  | (106 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 642, SYSCON_I2SDIV_PDIV_3  | (107 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 648, SYSCON_I2SDIV_PDIV_3  | (108 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 654, SYSCON_I2SDIV_PDIV_3  | (109 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 660, SYSCON_I2SDIV_PDIV_3  | (110 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 666, SYSCON_I2SDIV_PDIV_3  | (111 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 672, SYSCON_I2SDIV_PDIV_3  | (112 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 678, SYSCON_I2SDIV_PDIV_3  | (113 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 684, SYSCON_I2SDIV_PDIV_3  | (114 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 690, SYSCON_I2SDIV_PDIV_3  | (115 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 696, SYSCON_I2SDIV_PDIV_3  | (116 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 702, SYSCON_I2SDIV_PDIV_3  | (117 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 708, SYSCON_I2SDIV_PDIV_3  | (118 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 714, SYSCON_I2SDIV_PDIV_3  | (119 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 720, SYSCON_I2SDIV_PDIV_3  | (120 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 726, SYSCON_I2SDIV_PDIV_3  | (121 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 732, SYSCON_I2SDIV_PDIV_3  | (122 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 738, SYSCON_I2SDIV_PDIV_3  | (123 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 744, SYSCON_I2SDIV_PDIV_3  | (124 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 750, SYSCON_I2SDIV_PDIV_3  | (125 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 756, SYSCON_I2SDIV_PDIV_3  | (126 & SYSCON_I2SDIV_MDIV_MASK) },
+    { 762, SYSCON_I2SDIV_PDIV_3  | (127 & SYSCON_I2SDIV_MDIV_MASK) }
+};
+
+/*
+ * When we get to the multichannel case the pre-fill and enable code
+ * will go to the dma driver's start routine.
+ */
+static void ep93xx_audio_enable_all(void)
+{
+    int i;
+	unsigned long ulTemp;
+	
+	DPRINTK("ep93xx_audio_enable_all - enter\n");
+
+	/*
+	 * Disable the channels, disable the i2s controller to clear out the 
+	 * fifo.  Disabling the controller will clear the flags	in i2s_csr.
+	 */
+	outl( 0, I2STX0En );
+	outl( 0, I2STX1En );
+	outl( 0, I2STX2En );
+	outl( 0, I2SRX0En );
+	outl( 0, I2SRX1En );
+	outl( 0, I2SRX2En );
+	ulTemp = inl( I2SRX2En ); /* input to push the outl's past the wrapper */
+	
+	/*
+	 * Disable the i2s controller to clear out the fifo and clear
+	 * the flags in i2s_csr.
+	 */
+	outl( 0, I2SGlCtrl );
+	ulTemp = inl( I2SGlCtrl );
+
+	/*
+	 * Enable the i2s controller.  It is important not to just
+	 * leave the i2s controller enabled and skip this step. 
+	 */
+	outl( 1, I2SGlCtrl );
+	ulTemp = inl( I2SGlCtrl );
+
+	/*
+	 * Prefill the tx fifo with zeros.
+	 */
+    for( i = 0 ; i < 8 ; i++ )
+    {
+		outl( 0, I2STX0Lft );
+		outl( 0, I2STX0Rt );
+		outl( 0, I2STX1Lft );
+		outl( 0, I2STX1Rt );
+		outl( 0, I2STX2Lft );
+		outl( 0, I2STX2Rt );
+		ulTemp = inl( I2SRX2En ); /* input to push the outl's past the wrapper */
+    }
+
+    /*
+	 * Enable the tx channels.
+	 */
+	outl( 1, I2STX0En );
+	outl( 1, I2STX1En );
+	outl( 1, I2STX2En );
+	outl( 1, I2SRX0En );
+	outl( 1, I2SRX1En );
+	outl( 1, I2SRX2En );
+	ulTemp = inl( I2SRX2En ); /* input to push the outl's past the wrapper */
+
+	DPRINTK("ep93xx_audio_enable_all - EXIT\n");
+
+}
+
+static void ep93xx_audio_disable_all(void)
+{
+	unsigned long ulTemp;
+	
+	DPRINTK("ep93xx_audio_disable_all - enter\n");
+
+	/*
+	 * Disable the channels, disable the i2s controller to clear out the 
+	 * fifo.  Disabling the controller will clear the flags	in i2s_csr.
+	 */
+	outl( 0, I2STX0En );
+	outl( 0, I2STX1En );
+	outl( 0, I2STX2En );
+	outl( 0, I2SRX0En );
+	outl( 0, I2SRX1En );
+	outl( 0, I2SRX2En );
+	outl( 0, I2SGlCtrl );
+	ulTemp = inl( I2SRX2En ); /* input to push the outl's past the wrapper */
+
+	DPRINTK("ep93xx_audio_disable_all - EXIT\n");
+}
+
+/*
+ * ep93xx_clear_i2s_fifo
+ *
+ * This routine will clear out the transmit fifo of an audio playback stream 
+ * (can be multi-channel) and re-enable it.
+ */
+static void ep93xx_clear_i2s_fifo( audio_stream_t * stream )
+{
+    int i;
+	unsigned long ulTemp;
+	
+	DPRINTK("ep93xx_clear_i2s_fifo - enter\n");
+	
+	/*
+	 * If this is a rx stream, don't need to do this.
+	 */
+	if( (stream->TX_dma_ch_bitfield & 0x7) == 0 )
+		return;
+	
+	/*
+	 * Disable the channel.
+	 */
+	if( stream->TX_dma_ch_bitfield & 0x1 )
+		outl( 0, I2STX0En );
+
+	if( stream->TX_dma_ch_bitfield & 0x2 )
+		outl( 0, I2STX1En );
+
+	if( stream->TX_dma_ch_bitfield & 0x4 )
+		outl( 0, I2STX2En );
+
+	ulTemp = inl( I2SRX2En ); /* input to push the outl's past the wrapper */
+
+	/*
+	 * Prefill the tx fifo with zeros.
+	 */
+    for( i = 0 ; i < 8 ; i++ )
+    {
+		if( stream->TX_dma_ch_bitfield & 0x1 )
+		{
+			outl( 0, I2STX0Lft );
+			outl( 0, I2STX0Rt );
+		}
+
+		if( stream->TX_dma_ch_bitfield & 0x2 )
+		{
+			outl( 0, I2STX1Lft );
+			outl( 0, I2STX1Rt );
+		}
+
+		if( stream->TX_dma_ch_bitfield & 0x4 )
+		{
+			outl( 0, I2STX2Lft );
+			outl( 0, I2STX2Rt );
+		}
+		
+		ulTemp = inl( I2SRX2En ); /* input to push the outl's past the wrapper */
+    }
+
+    /*
+	 * Enable the tx channels.
+	 */
+	if( stream->TX_dma_ch_bitfield & 0x1 )
+		outl( 1, I2STX0En );
+
+	if( stream->TX_dma_ch_bitfield & 0x2 )
+		outl( 1, I2STX1En );
+
+	if( stream->TX_dma_ch_bitfield & 0x4 )
+		outl( 1, I2STX2En );
+
+	ulTemp = inl( I2SRX2En ); /* input to push the outl's past the wrapper */
+
+	DPRINTK("ep93xx_clear_i2s_fifo - EXIT\n");
+}
+
+/*
+ * ep93xx_calc_closest_freq
+ * 
+ *   ulPLLFreq           -  PLL output Frequency (Mhz)
+ *   ulRequestedMClkFreq -  Requested Video Clock Frequency.
+ *   pulActualMClkFreq   -  Returned Actual Video Rate.
+ *   pulI2SDiv           -  Video Divider register.
+ *
+ *   Return            0 - Failure
+ *                     1 - Success
+ */
+static int ep93xx_calc_closest_freq
+(
+    ulong   ulPLLFreq, 
+    ulong   ulRequestedMClkFreq,
+    ulong * pulActualMClkFreq,
+    ulong * pulI2SDiv
+)
+{
+    
+    ulong   ulLower;
+    ulong   ulUpper;
+    ulong   ulDiv;
+    int     x;
+
+    /*
+     * Calculate the closest divisor.
+     */
+    ulDiv =  (ulPLLFreq * 2)/ ulRequestedMClkFreq;
+
+    for(x = 1; x < sizeof(I2SDivTable)/sizeof(DIV_TABLE); x++)
+    {
+        /*
+         * Calculate the next greater and lower value.
+         */
+        ulLower = I2SDivTable[x - 1].ulTotalDiv;     
+        ulUpper = I2SDivTable[x].ulTotalDiv;     
+
+        /*
+         * Check to see if it is in between the two values.
+         */
+        if(ulLower <= ulDiv && ulDiv < ulUpper)
+        {
+            break;
+        }
+    }
+
+    /*
+     * Return if we did not find a divisor.
+     */
+    if(x == sizeof(I2SDivTable)/sizeof(DIV_TABLE))
+    {
+		DPRINTK("couldn't find a divisor.\n");
+
+        *pulActualMClkFreq  = 0;
+        *pulI2SDiv          = 0;
+        return -1;
+    }
+
+    /*
+     * See which is closer, the upper or the lower case.
+     */
+    if(ulUpper * ulRequestedMClkFreq - ulPLLFreq * 2 >  
+      ulPLLFreq * 2 - ulLower * ulRequestedMClkFreq)
+    {
+        x-=1;
+    }
+    *pulActualMClkFreq  = (ulPLLFreq * 2)/ I2SDivTable[x].ulTotalDiv;
+    *pulI2SDiv          = I2SDivTable[x].ulI2SDiv;
+
+    return 0;
+}
+
+/*
+ * ep93xx_get_PLL_frequency
+ *
+ * Given a value for ClkSet1 or ClkSet2, calculate the PLL1 or PLL2 frequency.
+ */
+static ulong ep93xx_get_PLL_frequency( ulong ulCLKSET )
+{
+	ulong ulX1FBD, ulX2FBD, ulX2IPD, ulPS, ulPLL_Freq;
+	
+	ulPS = (ulCLKSET & SYSCON_CLKSET1_PLL1_PS_MASK) >> SYSCON_CLKSET1_PLL1_PS_SHIFT; 	
+	ulX1FBD = (ulCLKSET & SYSCON_CLKSET1_PLL1_X1FBD1_MASK) >> SYSCON_CLKSET1_PLL1_X1FBD1_SHIFT;
+	ulX2FBD = (ulCLKSET & SYSCON_CLKSET1_PLL1_X2FBD2_MASK) >> SYSCON_CLKSET1_PLL1_X2FBD2_SHIFT;
+	ulX2IPD = (ulCLKSET & SYSCON_CLKSET1_PLL1_X2IPD_MASK) >> SYSCON_CLKSET1_PLL1_X2IPD_SHIFT;
+
+	/*
+	 * This may be off by a very small fraction of a percent.
+	 */
+	ulPLL_Freq = (((0x00e10000 * (ulX1FBD+1)) / (ulX2IPD+1)) * (ulX2FBD+1)) >> ulPS;
+
+	return ulPLL_Freq;
+}
+
+/*
+ * SetSampleRate
+ * 		disables i2s channels and sets up i2s divisors
+ * 		in syscon for the requested sample rate.
+ *
+ * lFrequency - Sample Rate in Hz
+ */
+static void ep93xx_set_samplerate(long lFrequency)
+{
+    ulong ulRequestedMClkFreq, ulPLL1_CLOCK, ulPLL2_CLOCK;
+    ulong ulMClkFreq1, ulMClkFreq2, ulClkSet1, ulClkSet2;
+    ulong ulI2SDiv, ulI2SDiv1, ulI2SDiv2, ulI2SDIV, actual_samplerate;
+    
+	/*
+	 * Clock ratios: MCLK to SCLK and SCLK to LRCK
+	 */
+	ulong ulM2SClock  = 4;
+    ulong ulS2LRClock = 64;
+
+	DPRINTK( "ep93xx_set_samplerate = %d Hz.\n", (int)lFrequency );
+
+	/*
+	 * Read CLKSET1 and CLKSET2 in the System Controller and calculate
+	 * the PLL frequencies from that.
+	 */
+	ulClkSet1 =	inl(SYSCON_CLKSET1);
+	ulClkSet2 =	inl(SYSCON_CLKSET2);
+	ulPLL1_CLOCK = ep93xx_get_PLL_frequency( ulClkSet1 );
+	ulPLL2_CLOCK = ep93xx_get_PLL_frequency( ulClkSet2 );
+
+	DPRINTK( "ClkSet1=0x%08x Clkset2=0x%08x  PLL1=%d Hz  PLL2=%d Hz\n", 
+		(int)ulClkSet1, (int)ulClkSet2, (int)ulPLL1_CLOCK, (int)ulPLL2_CLOCK );
+
+    ulRequestedMClkFreq = ( lFrequency * ulM2SClock * ulS2LRClock);
+
+    ep93xx_calc_closest_freq
+    (
+        ulPLL1_CLOCK, 
+        ulRequestedMClkFreq,
+        &ulMClkFreq1,
+        &ulI2SDiv1
+    );
+    ep93xx_calc_closest_freq
+    (
+        ulPLL2_CLOCK, 
+        ulRequestedMClkFreq,
+        &ulMClkFreq2,
+        &ulI2SDiv2
+    );
+
+    /*
+     * See which is closer, MClk rate 1 or MClk rate 2.
+     */
+    if(abs(ulMClkFreq1 - ulRequestedMClkFreq) < abs(ulMClkFreq2 -ulRequestedMClkFreq))
+    {
+        ulI2SDiv    = ulI2SDiv1;
+        actual_samplerate = ulMClkFreq1/ (ulM2SClock * ulS2LRClock);
+		DPRINTK( "ep93xx_set_samplerate - using PLL1\n" );
+    }
+    else
+    {
+        ulI2SDiv = ulI2SDiv2 | SYSCON_I2SDIV_PSEL;
+        actual_samplerate = ulMClkFreq1 / (ulM2SClock * ulS2LRClock);
+		DPRINTK( "ep93xx_set_samplerate - using PLL2\n" );
+    }
+
+    /*
+     * Calculate the new I2SDIV register value and write it out.
+     */
+    ulI2SDIV = ulI2SDiv | SYSCON_I2SDIV_SENA |  SYSCON_I2SDIV_ORIDE | 
+				SYSCON_I2SDIV_SPOL| SYSCON_I2SDIV_LRDIV_64 | 
+				SYSCON_I2SDIV_SDIV | SYSCON_I2SDIV_MENA | SYSCON_I2SDIV_ESEL;
+
+    DPRINTK("I2SDIV set to 0x%08x\n", (unsigned int)ulI2SDIV );
+	
+	/*
+	 * For I2S all channels have same sample rate so we'll save them
+	 * all in i2s_output_stream0.sample_rate.
+	 */
+	i2s_output_stream0.sample_rate = lFrequency;
+
+    DPRINTK( "ep93xx_set_samplerate - requested %d Hz, got %d Hz, reporting %d Hz.\n",
+	        (int)lFrequency, (int)actual_samplerate, (int)i2s_output_stream0.sample_rate );
+			
+	SysconSetLocked(SYSCON_I2SDIV, ulI2SDIV);
+	audio_clocks_enabled_in_syscon = 1;
+
+}
+
+/*
+ * BringUpI2S
+ *
+ * This routine sets up the I2S Controller.
+ */
+static void ep93xx_init_i2s_controller( void )
+{
+	unsigned int uiDEVCFG;
+	
+	DPRINTK("ep93xx_init_i2s_controller - enter\n");
+	
+    /*
+     * Configure the multiplexed Ac'97 pins to be I2S.  Also configure 
+     * EGPIO[4,5,6,13] to be SDIN's and SDOUT's for the second and third
+     * I2S stereo channels if the codec is a 6 channel codec.
+     */
+	uiDEVCFG = inl(SYSCON_DEVCFG);
+	
+#ifdef CONFIG_CODEC_CS4271
+	uiDEVCFG |= SYSCON_DEVCFG_I2SonAC97;
+#else // CONFIG_CODEC_CS4228A
+	uiDEVCFG |= SYSCON_DEVCFG_I2SonAC97 | 
+		        SYSCON_DEVCFG_A1onG |
+		        SYSCON_DEVCFG_A2onG;
+#endif
+	    
+    SysconSetLocked(SYSCON_DEVCFG, uiDEVCFG);
+
+    /* ------------- Configure I2S Tx channel ---------------------*/
+
+    /*
+	 * Justify Left, MSB first	
+     */
+	outl( 0, I2STXLinCtrlData );
+
+	/*
+	 * WL = 24 bits 
+	 */
+	outl( 1, I2STXWrdLen );
+
+	/*
+     * Set the I2S control block to master mode.
+	 * Tx bit clk rate determined by word legnth 
+	 * Do gate off last 8 clks (24 bit samples in a 32 bit field)
+	 * LRclk = I2S timing; LRck = 0 for left
+	 */
+	outl( (i2s_txcc_mstr | i2s_txcc_trel), I2STxClkCfg );
+	
+    /* ------------- Configure I2S rx channel --------------------- */
+    
+    /*
+     * First, clear all config bits.
+     */
+	outl( 0, I2SRXLinCtrlData );
+
+	/*
+	 * WL = 24 bits 
+	 */
+	outl( 1, I2SRXWrdLen );
+
+	/* 
+     * Set the I2S control block to master mode.
+	 * Rx bit clk rate determined by word legnth 
+	 * Do gate off last 8 clks 
+	 * setting i2s_rxcc_rrel gives us I2S timing
+	 * clearing i2s_rlrs gives us LRck = 0 for left, 1 for right
+	 * setting i2s_rxcc_nbcg specifies to not gate off extra 8 clocks 
+	 */
+	outl( (i2s_rxcc_bcr_64x | i2s_rxcc_nbcg |i2s_rxcc_mstr | i2s_rxcc_rrel), I2SRxClkCfg );
+
+	/* 
+	 * Do an input to push the outl's past the wrapper 
+	 */
+	uiDEVCFG = inl(SYSCON_DEVCFG);
+    
+	DPRINTK("ep93xx_init_i2s_controller - EXIT\n");
+}
+
+/*
+ * ep93xx_init_i2s_codec
+ *
+ * Note that codec must be getting i2s clocks for any codec
+ * register writes to work.
+ */
+static void ep93xx_init_i2s_codec( void )
+{
+#if defined(CONFIG_ARCH_EDB9301) || defined(CONFIG_ARCH_EDB9302)
+    unsigned int uiPADR, uiPADDR;
+#endif
+    
+    DPRINTK("ep93xx_init_i2s_codec - enter\n");
+    
+	if( !audio_clocks_enabled_in_syscon )
+	{
+		DPRINTK("ep93xx_init_i2s_codec - EXIT - clocks not enabled\n");
+		return;
+	}
+
+#ifdef CONFIG_CODEC_CS4271
+
+	//
+    // Some EDB9301 boards use EGPIO1 (port 1, bit 1) for the I2S reset.
+    // EGPIO1 has a pulldown so if it isn't configured as an output, it
+    // is low.
+    //
+#if defined(CONFIG_ARCH_EDB9301) || defined(CONFIG_ARCH_EDB9302)
+	uiPADR  = inl(GPIO_PADR);
+    uiPADDR = inl(GPIO_PADDR);
+    
+    // Clear bit 1 of the data register
+    outl( (uiPADR & 0xfd), GPIO_PADR );
+    uiPADR  = inl(GPIO_PADR);
+
+    // Set bit 1 of the DDR to set it to output
+    // Now we are driving the reset pin low.
+    outl( (uiPADDR | 0x02), GPIO_PADDR );
+    uiPADDR = inl(GPIO_PADDR);
+
+    udelay( 2 );  /* plenty of time */
+
+    // Set bit 1 of the data reg.  Now we drive the reset pin high.
+    outl( (uiPADR | 0x02),  GPIO_PADR );
+    uiPADR  = inl(GPIO_PADR);
+#endif
+
+    /*
+     * Write to the control port, setting the enable control port bit
+     * so that we can write to the control port.  OK?
+     */
+	SSPDriver->Write( SSP_Handle, 7, 0x02 );
+
+    /*
+     * Select slave, 24Bit I2S serial mode
+     */
+	SSPDriver->Write( SSP_Handle, 1, 0x01 );
+	SSPDriver->Write( SSP_Handle, 6, 0x10 );
+
+    /*
+     * Set AMUTE (auto-mute) bit.
+     */
+	SSPDriver->Write( SSP_Handle, 2, 0x00 );
+
+    /*
+     * Set SOFT  bit.
+     */
+	//SSPDriver->Write( SSP_Handle, 3, 0x29 );
+
+#else // CONFIG_CODEC_CS4228A
+
+    /*
+     * Nothing needs to happen here
+     */
+
+#endif
+    
+	DPRINTK("ep93xx_init_i2s_codec - EXIT\n");
+}
+
+#if 0
+/*
+ * ep93xx_mute_i2s_codec
+ *
+ * Note that codec must be getting i2s clocks for any codec
+ * register writes to work.
+ */
+static void ep93xx_mute_i2s_codec( void )
+{
+	DPRINTK("ep93xx_mute_i2s_codec - enter\n");
+
+	if( !audio_clocks_enabled_in_syscon )
+	{
+		DPRINTK("ep93xx_mute_i2s_codec - EXIT - clocks not enabled\n");
+		return;
+	}
+
+#ifdef CONFIG_CODEC_CS4271
+
+    /*
+     * Set the driver's mute flag and use the set_volume routine
+     * to write the current volume out with the mute bit set.
+     */
+    giDAC_Mute = 1;
+    ep93xx_set_volume( 0, giOSS_Volume[0] );
+
+#else // CONFIG_CODEC_CS4228A
+
+    /*
+     * Mute the MUTEC pin.
+     */
+	SSPDriver->Write( SSP_Handle, 5, 0x80 );
+
+    /*
+     * Mute the DACs
+     */
+	SSPDriver->Write( SSP_Handle, 4, 0xFC );
+    
+    giDAC_Mute = 1;
+
+#endif
+
+	DPRINTK("ep93xx_mute_i2s_codec - EXIT\n");
+}
+#endif
+
+/*
+ * ep93xx_automute_i2s_codec
+ *
+ * Note that codec must be getting i2s clocks for any codec
+ * register writes to work.
+ */
+static void ep93xx_automute_i2s_codec( void )
+{
+	DPRINTK("ep93xx_automute_i2s_codec - enter\n");
+
+	if( !audio_clocks_enabled_in_syscon )
+	{
+		DPRINTK("ep93xx_automute_i2s_codec - EXIT - clocks not enabled\n");
+		return;
+	}
+
+#ifdef CONFIG_CODEC_CS4271
+
+    /*
+     * The automute bit is set by default for the CS4271.
+     * Clear the driver's mute flag and use the set_volume routine
+     * to write the current volume out with the mute bit cleared.
+     */
+    giDAC_Mute = 0;
+    ep93xx_set_volume( 0, giOSS_Volume[0] );
+
+#else // CONFIG_CODEC_CS4228A
+
+    /*
+     * Unmute the DACs
+     */
+	SSPDriver->Write( SSP_Handle, 4, 0 );
+
+    /*
+     * Unmute the MUTEC pin, turn on automute.
+     */
+	SSPDriver->Write( SSP_Handle, 5, 0x40 );
+    
+    giDAC_Mute = 0;
+    
+#endif
+
+	DPRINTK("ep93xx_automute_i2s_codec - EXIT\n");
+}
+
+/*
+ * Set the volume in the I2S DAC or ADC.
+ * The channel parameter specifies which stereo channel in the
+ * case of a 6 channel codec (channel 0, 1, or 2).
+ */
+static int ep93xx_set_volume( int channel, int iOSS_Volume )
+{
+    int iOSS_Volume_L, iOSS_Volume_R;
+#ifdef CONFIG_CODEC_CS4271
+	int iMute=0;
+#endif
+	
+#ifdef CONFIG_CODEC_CS4271
+	/* only one stereo channel on this codec... */
+	if( channel > 0 )
+		return 0;
+#endif
+    
+	if( !audio_clocks_enabled_in_syscon )
+	{
+		return -EINVAL;
+	}
+    
+	giOSS_Volume[channel] = iOSS_Volume;
+
+    iOSS_Volume_L =  iOSS_Volume & 0x00ff;
+    iOSS_Volume_R = (iOSS_Volume & 0xff00) >> 8;
+
+	if (iOSS_Volume_L > 100)
+		iOSS_Volume_L = 100;
+	if (iOSS_Volume_L < 0)
+		iOSS_Volume_L = 0;
+	if (iOSS_Volume_R > 100)
+		iOSS_Volume_R = 100;
+	if (iOSS_Volume_R < 0)
+		iOSS_Volume_R = 0;
+
+#ifdef CONFIG_CODEC_CS4271
+    /*
+     * CS4271 volume is 0 to -127 dB in 1 dB increments.
+     * So scale the volume so a range of 0 to 100 becomes 127 to 0.
+     */
+    giDAC_Volume_L[0] = 127 - ((iOSS_Volume_L * 127) / 100);
+    giDAC_Volume_R[0] = 127 - ((iOSS_Volume_R * 127) / 100);
+
+    if( giDAC_Mute )
+    {
+        iMute = 0x80;
+    }
+
+    /*
+     * Write the volume for DAC1 and DAC2 (reg 4 and 5)
+     */
+	SSPDriver->Write( SSP_Handle, 4, (giDAC_Volume_L[0] | iMute) );
+	SSPDriver->Write( SSP_Handle, 5, (giDAC_Volume_R[0] | iMute) );
+
+#else // CONFIG_CODEC_CS4228A
+
+	/*
+	 * CS4228A DAC attenuation is 0 to 90.5 dB in 0.5 dB steps so scale
+	 * volume so that a value of 0 to 100 is scaled to 181 to 0
+	 */
+    giDAC_Volume_L[channel] = 181 - ((iOSS_Volume_L * 181) / 100);
+    giDAC_Volume_R[channel] = 181 - ((iOSS_Volume_R * 181) / 100);
+
+    /*
+     * Write the codec volume registers for DAC1 and DAC2 
+	 * (reg 7,8 = ch0; reg 9,A = ch1; reg B,C = ch2)
+     */
+	SSPDriver->Write( SSP_Handle, 7 + (channel<<1), giDAC_Volume_L[channel] );
+	SSPDriver->Write( SSP_Handle, 8 + (channel<<1), giDAC_Volume_R[channel] );
+	
+#endif
+
+	return 0;
+}
+
+static int 
+ep93xx_mixer_open(struct inode *inode, struct file *file)
+{
+	file->private_data = &ep93xx_i2s_hw;
+	return 0;
+}
+
+static int 
+ep93xx_mixer_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+/* 
+ * We can record, but we can't change the record input volume.
+ * So we don't report that we can (we used to report that we can).
+ * change to (SOUND_MASK_LINE) to show a record volume that is not settable
+ * if your app needs this which it shouldn't
+ */
+#define REC_MASK	(0) // change to (SOUND_MASK_LINE) to show non settable record volume
+
+#ifdef CONFIG_CODEC_CS4271
+#define DEV_MASK	(REC_MASK | SOUND_MASK_VOLUME )
+#else
+#define DEV_MASK	(REC_MASK | SOUND_MASK_VOLUME | SOUND_MASK_LINE1 | SOUND_MASK_LINE2)
+#endif
+
+static int
+ep93xx_mixer_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
+{
+	int val, nr, ret = 0;
+	struct mixer_info mi;
+
+	audio_hw_t * hw = (audio_hw_t *)file->private_data;
+
+	DPRINTK("ep93xx_mixer_ioctl - enter.  IOC_TYPE is %c \n", _IOC_TYPE(cmd) );
+
+	/*
+	 * We only accept mixer (type 'M') ioctls.
+	 */
+	if (_IOC_TYPE(cmd) != 'M')
+		return -EINVAL;
+
+	if (cmd == SOUND_MIXER_INFO) 
+	{
+		DPRINTK("ep93xx_mixer_ioctl - SOUND_MIXER_INFO\n" );
+
+#ifdef CONFIG_CODEC_CS4271
+		strncpy(mi.id, "CS4271", sizeof(mi.id));
+		strncpy(mi.name, "Cirrus CS4271", sizeof(mi.name));
+#else // CONFIG_CODEC_CS4228A
+		strncpy(mi.id, "CS4228A", sizeof(mi.id));
+		strncpy(mi.name, "Cirrus CS4228A", sizeof(mi.name));
+#endif
+		mi.modify_counter = hw->modcnt;
+
+		return copy_to_user( (void *)arg, &mi, sizeof(mi));
+	}
+
+	nr = _IOC_NR(cmd);
+
+	if (_IOC_DIR(cmd) & _IOC_WRITE) 
+	{
+		ret = get_user(val, (int *)arg);
+		if (ret)
+			return ret;
+
+		DPRINTK("ep93xx_mixer_ioctl write - nr is %d, val is 0x%04x\n", nr, val );
+		
+		switch (nr) 
+		{
+			case SOUND_MIXER_VOLUME:
+				ret = ep93xx_set_volume( 0, val );
+				hw->modcnt++;
+				break;
+				
+			case SOUND_MIXER_LINE1:
+				ret = ep93xx_set_volume( 1, val );
+				hw->modcnt++;
+				break;
+				
+			case SOUND_MIXER_LINE2:
+				ret = ep93xx_set_volume( 2, val );
+				hw->modcnt++;
+				break;
+
+			/*
+			 * Can't actually set the record volume.  But
+			 * if we return error, that might be bad.
+			 */
+#if REC_MASK
+			case SOUND_MIXER_RECSRC:
+				hw->modcnt++;
+				break;
+#endif
+			default:
+				ret = -EINVAL;
+		}
+	}
+
+	if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) 
+	{
+		int nr = _IOC_NR(cmd);
+		ret = 0;
+
+
+		switch (nr) 
+		{
+			case SOUND_MIXER_VOLUME:     
+        		DPRINTK("ep93xx_mixer_ioctl read - nr is %d (SOUND_MIXER_VOLUME)\n", nr );
+				val = giOSS_Volume[0];
+				break;
+
+			case SOUND_MIXER_LINE1:     
+        		DPRINTK("ep93xx_mixer_ioctl read - nr is %d (SOUND_MIXER_LINE1)\n", nr );
+				val = giOSS_Volume[1];
+				break;
+
+			case SOUND_MIXER_LINE2:     
+        		DPRINTK("ep93xx_mixer_ioctl read - nr is %d (SOUND_MIXER_LINE2)\n", nr );
+				val = giOSS_Volume[2];
+				break;
+				
+#if REC_MASK
+		   	case SOUND_MIXER_LINE:       
+        		DPRINTK("ep93xx_mixer_ioctl read - nr is %d (SOUND_MIXER_LINE)\n", nr );
+				val = ((100<<8) | 100 );	
+				break;
+#endif
+				
+			case SOUND_MIXER_RECSRC:     
+        		DPRINTK("ep93xx_mixer_ioctl read - nr is %d (SOUND_MIXER_RECSRC)\n", nr );
+				val = REC_MASK;	
+				break;
+				
+			case SOUND_MIXER_RECMASK:    
+        		DPRINTK("ep93xx_mixer_ioctl read - nr is %d (SOUND_MIXER_RECMASK)\n", nr );
+				val = REC_MASK;	
+				break;
+			
+			case SOUND_MIXER_DEVMASK:    
+        		DPRINTK("ep93xx_mixer_ioctl read - nr is %d (SOUND_MIXER_DEVMASK)\n", nr );
+				val = DEV_MASK;	
+				break;
+			
+			case SOUND_MIXER_CAPS:
+        		DPRINTK("ep93xx_mixer_ioctl read - nr is %d (SOUND_MIXER_CAPS)\n", nr );
+				val = SOUND_CAP_EXCL_INPUT;		
+				break;
+
+			case SOUND_MIXER_STEREODEVS: 
+        		DPRINTK("ep93xx_mixer_ioctl read - nr is %d (SOUND_MIXER_STEREODEVS)\n", nr );
+				val = 0;		
+				break;
+
+			default:	
+        		DPRINTK("ep93xx_mixer_ioctl read - nr is %d (not handled, return 0)\n", nr );
+				val = 0;     
+				ret = -EINVAL;	
+				break;
+		}
+
+		if (ret == 0)
+			ret = put_user(val, (int *)arg);
+	}
+
+	return ret;
+}
+
+static struct file_operations ep93xx_mixer_fops = {
+	owner:		THIS_MODULE,
+	llseek:		no_llseek,
+	ioctl:		ep93xx_mixer_ioctl,
+	open:		ep93xx_mixer_open,
+	release:	ep93xx_mixer_release,
+};
+
+/*
+ * ep93xx_audio_init
+ * Note that the codec powers up with its DAC's muted and
+ * the serial format set to 24 bit I2S mode.
+ */
+static void ep93xx_audio_init(void *dummy)
+{
+    DPRINTK("ep93xx_audio_init - enter\n");
+	
+    /*
+	 * Mute the DACs. Disable all audio channels.  
+	 * Must do this to change sample rate.
+	 */
+    ep93xx_audio_disable_all();
+
+	/*
+	 * Set up the i2s clocks in syscon.  Enable them.
+	 */ 
+	i2s_output_stream0.sample_rate = AUDIO_SAMPLE_RATE_DEFAULT;
+	ep93xx_set_samplerate( AUDIO_SAMPLE_RATE_DEFAULT );
+
+	/*
+	 * Set i2s' controller serial format, and enable 
+	 * the i2s controller.
+	 */
+	ep93xx_init_i2s_controller();
+	
+    /*
+     * Initialize codec serial format, etc.
+     */
+    ep93xx_init_i2s_codec();
+
+	/*
+	 * Clear the fifo and enable the tx0 channel.
+	 */
+	ep93xx_audio_enable_all();
+
+	/*
+	 * Set the volume for the first time.
+	 */
+	ep93xx_set_volume( 0, AUDIO_DEFAULT_VOLUME );
+	ep93xx_set_volume( 1, AUDIO_DEFAULT_VOLUME );
+	ep93xx_set_volume( 2, AUDIO_DEFAULT_VOLUME );
+
+	
+	/*
+	 * Unmute the DAC and set the mute pin MUTEC to automute.
+	 */
+	ep93xx_automute_i2s_codec();
+	
+	DPRINTK("ep93xx_audio_init - EXIT\n");
+}
+
+/*
+ * any_streams_are_active_or_stopped
+ *
+ * This routine returns 1 if either the input or output	streams is 
+ * active or stopped.  If that is the case we are in the middle
+ * of a transfer and don't want the sample rate to change.
+ */
+static __inline__ int any_streams_are_active_or_stopped( void )
+{
+	if( audio_state0.output_stream && audio_state0.wr_ref )
+	{
+		if( audio_state0.output_stream->active || audio_state0.output_stream->stopped )
+		{
+			return 1;
+		}
+	}
+	if( audio_state0.input_stream && audio_state0.rd_ref )
+	{
+		if( audio_state0.input_stream->active || audio_state0.input_stream->stopped )
+		{
+			return 1;
+		}
+	}
+
+#ifdef CONFIG_CODEC_CS4228A
+	if( audio_state1.output_stream && audio_state1.wr_ref )
+	{
+		if( audio_state1.output_stream->active || audio_state1.output_stream->stopped )
+		{
+			return 1;
+		}
+	}
+	if( audio_state1.input_stream && audio_state1.rd_ref )
+	{
+		if( audio_state1.input_stream->active || audio_state1.input_stream->stopped )
+		{
+			return 1;
+		}
+	}
+
+	if( audio_state2.output_stream && audio_state2.wr_ref )
+	{
+		if( audio_state2.output_stream->active || audio_state2.output_stream->stopped )
+		{
+			return 1;
+		}
+	}
+	if( audio_state2.input_stream && audio_state2.rd_ref )
+	{
+		if( audio_state2.input_stream->active || audio_state2.input_stream->stopped )
+		{
+			return 1;
+		}
+	}
+#endif
+	
+	return 0;
+}
+
+
+
+static int ep93xx_audio_ioctl(struct inode *inode, struct file *file,
+			     uint cmd, ulong arg)
+{
+	long val;
+	int ret = 0;
+
+	/*
+	 * These are platform dependent ioctls which are not handled by the
+	 * generic ep93xx-audio module.
+	 */
+	switch (cmd) 
+	{
+		case SNDCTL_DSP_SPEED:
+			
+			DPRINTK("ep93xx_audio_ioctl - SNDCTL_DSP_SPEED\n");
+			
+			if (get_user(val, (int *)arg))
+			{
+				return -EFAULT;
+			}
+			
+			/*
+			 * For I2S, sample rate is set for all channels, record and playback
+			 * equally.  So we don't check to see if it's doing READ or WRITE.
+			 */
+			/*
+			 * If we are already at this samplerate, don't change it.
+			 */
+			if( i2s_output_stream0.sample_rate == val )
+			{
+				return put_user( val, (long *) arg);
+			}
+
+			/*
+			 * This driver won't allow changing the sample rate if we are 
+			 * playing or recording audio on any channel.  This code saves
+			 * the user from ugly sounds or silences.
+			 */
+			if( any_streams_are_active_or_stopped() )
+			{
+				printk("ep93xx-i2s: Audio driver can't change the sample rate while any\n");
+				printk("other audio record or playback channel is being used.\n");
+				return -EFAULT;
+			}
+
+		    /*
+			 * Disable all audio channels.  Must do this to change sample rate.
+			 */
+		    ep93xx_audio_disable_all();
+			ep93xx_set_samplerate( val );
+			ep93xx_audio_enable_all();
+	        
+            /*
+	         * We sorta should report the actual samplerate back to the calling
+	         * application.  But some applications freak out if they don't get
+	         * exactly what they asked for.  So we fudge and tell them what
+	         * they want to hear.
+	         */
+			return put_user( val, (long *) arg);
+
+		case SOUND_PCM_READ_RATE:
+			DPRINTK("ep93xx_audio_ioctl - SOUND_PCM_READ_RATE\n");
+			return put_user( i2s_output_stream0.sample_rate, (long *) arg);
+
+		default:
+			DPRINTK("ep93xx_audio_ioctl-->ep93xx_mixer_ioctl\n");
+			/* Maybe this is meant for the mixer (As per OSS Docs) */
+			return ep93xx_mixer_ioctl(inode, file, cmd, arg);
+	}
+
+	return ret;
+}
+
+static int ep93xx_audio_open0(struct inode *inode, struct file *file)
+{
+	DPRINTK( "ep93xx_audio_open0\n" );
+	return ep93xx_audio_attach( inode, file, &audio_state0 );
+}
+
+#ifdef CONFIG_CODEC_CS4228A
+static int ep93xx_audio_open1(struct inode *inode, struct file *file)
+{
+	DPRINTK( "ep93xx_audio_open1\n" );
+	return ep93xx_audio_attach( inode, file, &audio_state1 );
+}
+
+static int ep93xx_audio_open2(struct inode *inode, struct file *file)
+{
+	DPRINTK( "ep93xx_audio_open2\n" );
+	return ep93xx_audio_attach( inode, file, &audio_state2 );
+}
+#endif
+
+/*
+ * Missing fields of this structure will be patched with the call
+ * to ep93xx_audio_attach().
+ */
+static struct file_operations ep93xx_audio_fops0 = 
+{
+	open:		ep93xx_audio_open0,
+	owner:		THIS_MODULE
+};
+
+#ifdef CONFIG_CODEC_CS4228A
+static struct file_operations ep93xx_audio_fops1 = 
+{
+	open:		ep93xx_audio_open1,
+	owner:		THIS_MODULE
+};
+static struct file_operations ep93xx_audio_fops2 = 
+{
+	open:		ep93xx_audio_open2,
+	owner:		THIS_MODULE
+};
+#endif
+
+static int __init ep93xx_i2s_init(void)
+{
+	DPRINTK("ep93xx_i2s_init - enter\n");
+	
+    /*
+     * Open an instance of the SSP driver for I2S codec register access.
+     */
+    SSP_Handle = SSPDriver->Open(I2S_CODEC,0);
+    if( SSP_Handle < 1 )
+    {
+	    printk( "/drivers/sound/ep93xx-i2s.c: Couldn't open SSP driver!\n");
+		return -ENODEV;
+    }
+
+	/*
+	 * Enable audio early on, give the DAC time to come up.
+	 */	
+	ep93xx_audio_init( 0 );
+
+	/* 
+	 * Register devices using sound_core.c's devfs stuff
+	*/
+	audio_dev_id0 = register_sound_dsp(&ep93xx_audio_fops0, -1);
+	if( audio_dev_id0 < 0 )
+	{
+		DPRINTK(" ep93xx_i2s_init: register_sound_dsp failed for dsp0.\n" );
+		return -ENODEV;
+	}
+#ifdef CONFIG_CODEC_CS4228A
+	audio_dev_id1 = register_sound_dsp(&ep93xx_audio_fops1, -1);
+	if( audio_dev_id1 < 0 )
+	{
+		DPRINTK(" ep93xx_i2s_init: register_sound_dsp failed for dsp1.\n" );
+		return -ENODEV;
+	}
+	audio_dev_id2 = register_sound_dsp(&ep93xx_audio_fops2, -1);
+	if( audio_dev_id2 < 0 )
+	{
+		DPRINTK(" ep93xx_i2s_init: register_sound_dsp failed for dsp2.\n" );
+		return -ENODEV;
+	}
+#endif
+	
+	mixer_dev_id = register_sound_mixer(&ep93xx_mixer_fops, -1);
+	if( mixer_dev_id < 0 )
+	{
+		DPRINTK(" ep93xx_i2s_init: register_sound_dsp failed for mixer.\n" );
+		return -ENODEV;
+	}
+
+	printk( KERN_INFO "EP93xx I2S audio support initialized.\n" );
+	return 0;
+}
+
+static void __exit ep93xx_i2s_exit(void)
+{
+    SSPDriver->Close(SSP_Handle);
+	
+	unregister_sound_dsp( audio_dev_id0 );
+	
+#ifdef CONFIG_CODEC_CS4228A
+	unregister_sound_dsp( audio_dev_id1 );
+	unregister_sound_dsp( audio_dev_id2 );
+#endif
+
+	unregister_sound_mixer( mixer_dev_id );
+}
+
+module_init(ep93xx_i2s_init);
+module_exit(ep93xx_i2s_exit);
+
+MODULE_DESCRIPTION("Audio driver for the Cirrus EP93xx I2S controller.");
+
+/* EXPORT_NO_SYMBOLS; */
diff -urN linux-2.4.29/drivers/sound/Makefile linux-2.4.29-uc1/drivers/sound/Makefile
--- linux-2.4.29/drivers/sound/Makefile	2005-01-19 14:10:04.000000000 +0000
+++ linux-2.4.29-uc1/drivers/sound/Makefile	2005-06-14 02:12:04.000000000 +0100
@@ -4,13 +4,16 @@
 # Rewritten to use lists instead of if-statements.
 
 
+USE_STANDARD_AS_RULE := true
+
 # All of the (potential) objects that export symbols.
 # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
 
 export-objs	:=  ad1848.o audio_syms.o midi_syms.o mpu401.o \
 		    msnd.o opl3.o sb_common.o sequencer_syms.o \
 		    sound_core.o sound_syms.o uart401.o	\
-		    nm256_audio.o ac97.o ac97_codec.o aci.o
+		    nm256_audio.o ac97.o ac97_codec.o aci.o \
+		    ep93xx-audio.o
 
 # Each configuration option enables a list of files.
 
@@ -78,11 +81,14 @@
 obj-$(CONFIG_SOUND_FORTE)	+= forte.o ac97_codec.o
 obj-$(CONFIG_SOUND_TRIDENT)	+= trident.o ac97_codec.o
 obj-$(CONFIG_SOUND_HARMONY)	+= harmony.o
+obj-$(CONFIG_SOUND_EP93XX_I2S)	+= ep93xx-audio.o ep93xx-i2s.o
+obj-$(CONFIG_SOUND_EP93XX_AC97)	+= ep93xx-audio.o ep93xx-ac97.o
 obj-$(CONFIG_SOUND_EMU10K1)	+= ac97_codec.o
 obj-$(CONFIG_SOUND_BCM_CS4297A)	+= swarm_cs4297a.o
 obj-$(CONFIG_SOUND_RME96XX)     += rme96xx.o
 obj-$(CONFIG_SOUND_BT878)	+= btaudio.o
 obj-$(CONFIG_SOUND_IT8172)	+= ite8172.o ac97_codec.o
+obj-$(CONFIG_SOUND_7212)	+= ep7212_audio.o ep7212_audiodma.o cs43l42.o
 obj-$(CONFIG_SOUND_AD1980)	+= ac97_plugin_ad1980.o
 obj-$(CONFIG_SOUND_WM97XX)	+= ac97_plugin_wm97xx.o
 
diff -urN linux-2.4.29/drivers/sound/.version linux-2.4.29-uc1/drivers/sound/.version
--- linux-2.4.29/drivers/sound/.version	1997-11-10 07:01:54.000000000 +0000
+++ linux-2.4.29-uc1/drivers/sound/.version	1970-01-01 01:00:00.000000000 +0100
@@ -1,2 +0,0 @@
-3.8s
-0x030804
diff -urN linux-2.4.29/drivers/ssi/clps711x_ssi1.c linux-2.4.29-uc1/drivers/ssi/clps711x_ssi1.c
--- linux-2.4.29/drivers/ssi/clps711x_ssi1.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ssi/clps711x_ssi1.c	2005-06-14 02:12:20.000000000 +0100
@@ -0,0 +1,237 @@
+/*
+ *  linux/drivers/ssi/clps711x_ssi1.c
+ *
+ * SSI bus driver for the CLPS711x SSI1 bus.  We support EP7212
+ * extensions as well.
+ *
+ * Frame sizes can be between 4 and 24 bits.
+ * Config sizes can be between 4 and 16 bits.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+
+#include <asm/mach-types.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/hardware/ep7212.h>
+
+#include "ssi_bus.h"
+#include "ssi_dev.h"
+
+#define EP7212
+
+/*
+ * Port E on the P720T is used for the SPI bus chip selects
+ *  0 - Keyboard
+ *  1 - Touch screen
+ *  2 - CS4224 ADC/DAC
+ *  7 - idle
+ */
+
+#if 0
+/*
+ * we place in the transmit buffer:
+ *  <control>
+ * received data (binary):
+ *  0xxxxxxxxxxxx000
+ * where 'x' is the value
+ */
+struct ssi_dev ads7846_dev = {
+	name:		"ADS7846",
+	id:		1,
+	proto:		SSI_SPI,
+	cfglen:		8,
+	framelen:	24,
+	clkpol:		0,
+	clkfreq:	2500000,
+};
+
+/*
+ * we place in the transmit buffer:
+ *  write: <20> <map> <data>...
+ * received data discarded
+ */
+struct ssi_dev cs4224_dev = {
+	name:		"CS4224",
+	id:		2,
+	proto:		SSI_SPI,
+	cfglen:		8,
+	framelen:	8,
+	clkpol:		0,
+	clkfreq:	6000000,
+};
+#endif
+
+/*
+ * Supplement with whatever method your board requires
+ */
+static void ssi1_select_id(int id)
+{
+	if (machine_is_p720t()) {
+		clps_writel(7, PEDDR);
+		clps_writel(id, PEDR);
+	}
+}
+
+/*
+ * Select the specified device.  The upper layers will have already
+ * checked that the bus transmit queue is idle.  We need to make sure
+ * that the interface itself is idle.
+ */
+static int ssi1_select(struct ssi_bus *bus, struct ssi_dev *dev)
+{
+	u_int id = dev ? dev->id : 7;
+	u_int val;
+
+	/*
+	 * Make sure that the interface is idle
+	 */
+	do {
+		val = clps_readl(SYSFLG1);
+	} while (val & SYSFLG1_SSIBUSY);
+
+	ssi1_select_id(7);
+
+	if (dev) {
+		/*
+		 * Select clock frequency.  This is very rough,
+		 * and assumes that we're operating in PLL mode.
+		 */
+		val = clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK;
+//		if (dev->clkfreq <= 16000)		/* <16kHz */
+//			val |= SYSCON1_ADCKSEL(0);
+//		else if (dev->clkfreq < 64000)		/* <64kHz */
+//			val |= SYSCON1_ADCKSEL(1);
+//		else if (dev->clkfreq < 128000)		/* <128kHz */
+			val |= SYSCON1_ADCKSEL(2);
+//		else					/* >= 128kHz */
+//			val |= SYSCON1_ADCKSEL(3);
+		clps_writel(val, SYSCON1);
+
+		bus->cfglen	= dev->cfglen;
+		bus->framelen	= dev->framelen;
+		bus->clkpol	= dev->clkpol;
+		bus->proto	= dev->proto;
+
+#ifdef EP7212
+		/*
+		 * Set the clock edge according to the device.
+		 * (set clkpol if the device reads data on the
+		 * falling edge of the clock signal).
+		 */
+		val = ep_readl(SYSCON3) & ~SYSCON3_ADCCKNSEN;
+		if (bus->clkpol && dev->proto != SSI_USAR)
+			val |= SYSCON3_ADCCKNSEN;
+		ep_writel(val, SYSCON3);
+#endif
+
+		/*
+		 * Select the device
+		 */
+		ssi1_select_id(id);
+
+#ifdef EP7212
+		/*
+		 * If we are doing USAR, wait 30us, then set
+		 * the clock line low.
+		 */
+		if (dev->proto == SSI_USAR) {
+			udelay(150);
+
+			val |= SYSCON3_ADCCKNSEN;
+			ep_writel(val, SYSCON3);
+		}
+#endif
+	}
+
+	return 0;
+}
+
+static void ssi1_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct ssi_bus *bus = (struct ssi_bus *)dev_id;
+
+	/*
+	 * Read the data word and queue it.
+	 */
+	ssi_core_rcv(bus, clps_readl(SYNCIO));
+}
+
+/*
+ * Enable transmission and/or of some bytes
+ */
+static int ssi1_trans(struct ssi_bus *bus, u_int data)
+{
+	u_int syncio;
+
+#ifdef EP7212
+	data <<= 32 - bus->cfglen;
+	syncio = bus->cfglen | bus->framelen << 7 | data;
+#else
+	syncio = data | bus->framelen << 8;
+#endif
+
+	clps_writel(syncio, SYNCIO);
+	clps_writel(syncio | SYNCIO_TXFRMEN, SYNCIO);
+	return 0;
+}
+
+/*
+ * Initialise the SSI bus.
+ */
+static int ssi1_bus_init(struct ssi_bus *bus)
+{
+	int retval, val;
+
+	retval = request_irq(IRQ_SSEOTI, ssi1_int, 0, "ssi1", bus);
+	if (retval)
+		return retval;
+
+#ifdef EP7212
+	/*
+	 * EP7212 only!  Set the configuration command length.
+	 * On the CLPS711x chips, it is fixed at 8 bits.
+	 */
+	val = ep_readl(SYSCON3);
+	val |= SYSCON3_ADCCON;
+	ep_writel(val, SYSCON3);
+#endif
+
+	ssi1_select(bus, NULL);
+
+	PLD_SPI |= PLD_SPI_EN;
+
+	return 0;
+}
+
+static void ssi1_bus_exit(struct ssi_bus *bus)
+{
+	ssi1_select(bus, NULL);
+
+	PLD_SPI &= ~PLD_SPI_EN;
+
+	free_irq(IRQ_SSEOTI, bus);
+}
+
+struct ssi_bus clps711x_ssi1_bus = {
+	name:	"clps711x_ssi1",
+	init:	ssi1_bus_init,
+	exit:	ssi1_bus_exit,
+	select:	ssi1_select,
+	trans:	ssi1_trans,
+};
+
+static int __init clps711x_ssi1_init(void)
+{
+	return ssi_register_bus(&clps711x_ssi1_bus);
+}
+
+static void __exit clps711x_ssi1_exit(void)
+{
+	ssi_unregister_bus(&clps711x_ssi1_bus);
+}
+
+module_init(clps711x_ssi1_init);
+module_exit(clps711x_ssi1_exit);
diff -urN linux-2.4.29/drivers/ssi/Config.in linux-2.4.29-uc1/drivers/ssi/Config.in
--- linux-2.4.29/drivers/ssi/Config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ssi/Config.in	2005-06-14 02:12:20.000000000 +0100
@@ -0,0 +1,11 @@
+
+mainmenu_option next_comment
+comment 'Synchronous Serial Interface'
+tristate 'Synchronous Serial Interface Support' CONFIG_SSI
+
+comment 'SSI Bus Drivers'
+dep_tristate '  CLPS711X SSI support' CONFIG_SSI_CLPS711X $CONFIG_SSI $CONFIG_ARCH_CLPS711X
+
+comment 'SSI Device Drivers'
+dep_tristate '  JUNO keyboard support' CONFIG_SSI_JUNO $CONFIG_SSI
+endmenu
diff -urN linux-2.4.29/drivers/ssi/juno.c linux-2.4.29-uc1/drivers/ssi/juno.c
--- linux-2.4.29/drivers/ssi/juno.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ssi/juno.c	2005-06-14 02:12:20.000000000 +0100
@@ -0,0 +1,131 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/syspld.h>
+
+#include "ssi_bus.h"
+#include "ssi_dev.h"
+
+extern struct ssi_bus clps711x_ssi1_bus;
+
+static u_int recvbuf[16];
+static volatile u_int ptr, rxed;
+
+static inline void juno_enable_irq(void)
+{
+	enable_irq(IRQ_EINT1);
+}
+
+static inline void juno_disable_irq(void)
+{
+	disable_irq(IRQ_EINT1);
+}
+
+static void juno_rcv(struct ssi_dev *dev, u_int data)
+{
+	if (ptr < 16) {
+		recvbuf[ptr] = data;
+		ptr++;
+	} else
+		printk("juno_rcv: %04x\n", data);
+	rxed = 1;
+}
+
+static void juno_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct ssi_dev *dev = dev_id;
+
+	printk("juno_irq\n");
+
+	ssi_select_device(dev->bus, dev);
+
+	ptr = 0;
+	do {
+		rxed = 0;
+		ssi_transmit_data(dev, 0xff);
+		while (rxed == 0);
+		udelay(150);
+	} while (PLD_INT & PLD_INT_KBD_ATN);
+
+	ssi_select_device(dev->bus, NULL);
+
+	{ int i;
+	  printk("juno_rcv: ");
+	  for (i = 0; i < ptr; i++)
+	  	printk("%04x ", recvbuf[i]);
+	  printk("\n");
+	}
+}
+
+static void juno_command(struct ssi_dev *dev, int cmd, int data)
+{
+	ssi_transmit_data(dev, cmd);
+	mdelay(1);
+	ssi_transmit_data(dev, data);
+	mdelay(1);
+	ssi_transmit_data(dev, 0xa0 ^ 0xc0);
+	mdelay(1);
+}
+
+static int juno_dev_init(struct ssi_dev *dev)
+{
+	int retval;
+
+	PLD_KBD |= PLD_KBD_EN;
+	ptr = 16;
+
+	mdelay(20);
+
+	retval = request_irq(IRQ_EINT1, juno_irq, 0, dev->name, dev);
+	if (retval)
+		return retval;
+
+	juno_disable_irq();
+
+	if (ssi_select_device(dev->bus, dev) != 0) {
+		printk("juno: ssi_select_dev failed\n");
+		return -EBUSY;
+	}
+
+	mdelay(1);
+
+	juno_command(dev, 0x80, 0x20);
+
+	ssi_select_device(dev->bus, NULL);
+
+	juno_enable_irq();
+
+	return 0;
+}
+
+static struct ssi_dev juno_dev = {
+	name:		"Juno",
+	id:		0,
+	proto:		SSI_USAR,
+	cfglen:		8,
+	framelen:	8,
+	clkpol:		1,
+	clkfreq:	250000,
+	rcv:		juno_rcv,
+	init:		juno_dev_init,
+};
+
+static int __init juno_init(void)
+{
+	return ssi_register_device(&clps711x_ssi1_bus, &juno_dev);
+}
+
+static void __exit juno_exit(void)
+{
+	ssi_unregister_device(&juno_dev);
+}
+
+module_init(juno_init);
+module_exit(juno_exit);
+
diff -urN linux-2.4.29/drivers/ssi/Makefile linux-2.4.29-uc1/drivers/ssi/Makefile
--- linux-2.4.29/drivers/ssi/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ssi/Makefile	2005-06-14 02:12:20.000000000 +0100
@@ -0,0 +1,50 @@
+#
+# Makefile for the SSI drivers
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now inherited from the
+# parent makefile.
+#
+
+O_TARGET	:= ssi.o
+
+obj-y		:=
+obj-m		:=
+obj-n		:=
+obj-		:=
+
+export-objs	:=
+list-multi	:=
+
+obj-$(CONFIG_SSI)		+= ssi_core.o
+obj-$(CONFIG_SSI_CLPS711X)	+= clps711x_ssi1.o
+obj-y				+= juno.o
+
+# Extract lists of the multi-part drivers.
+# The 'int-*' lists are intermediate files used to build the multi's.
+
+multi-y		:= $(filter $(list-multi), $(obj-y))
+multi-m		:= $(filter $(list-multi), $(obj-m))
+int-y		:= $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs)))
+int-m		:= $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs)))
+
+# Files that are both resident and modular; remove from modular.
+
+obj-m		:= $(filter-out $(obj-y), $(obj-m))
+int-m		:= $(filter-out $(int-y), $(int-m))
+
+# Take multi-part drivers out of obj-y and put components in.
+
+obj-y		:= $(filter-out $(list-multi), $(obj-y)) $(int-y)
+
+# Translate to Rules.make lists.
+
+O_OBJS		:= $(filter-out $(export-objs), $(obj-y))
+OX_OBJS		:= $(filter     $(export-objs), $(obj-y))
+M_OBJS		:= $(sort $(filter-out $(export-objs), $(obj-m)))
+MX_OBJS		:= $(sort $(filter     $(export-objs), $(obj-m)))
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/drivers/ssi/README linux-2.4.29-uc1/drivers/ssi/README
--- linux-2.4.29/drivers/ssi/README	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ssi/README	2005-06-14 02:12:20.000000000 +0100
@@ -0,0 +1,86 @@
+		Synchronous Serial Interface bus driver
+		---------------------------------------
+
+   EEEEE X   X PPPP  EEEEE RRRR  IIIII M   M EEEEE N   N TTTTT  AAA  L
+   E      X X  P   P E     R   R   I   MM MM E     NN  N   T   A   A L
+   EEEE    X   PPPP  EEEE  RRRR    I   M M M EEEE  N N N   T   AAAAA L
+   E      X X  P     E     R R     I   M   M E     N  NN   T   A   A L
+   EEEEE X   X P     EEEEE R  R  IIIII M   M EEEEE N   N   T   A   A LLLLL
+
+This directory holds the SSI bus drivers.  Basically, a SSI bus consists
+of the following signals:
+
+	stxd	Transmit data
+	srxd	Receive data
+	sclk	Clock
+	sfrm	Frame
+		Chip selects (1 - n)
+
+There may be more than one device on a SSI bus, and each device can
+have different timing requirements.  There are several frame formats:
+
+1. Texas Instruments Synchronous Serial Frame format
+
+   sclk ____~_~_~_~_~_~_~_~____
+   sfrm ____~~_________________
+   stxd ------bn..........b0---
+   srxd ------bn..........b0---
+
+   - data latched in on the falling edge of the clock
+   - data shifted out on the rising edge of the clock
+
+2. Motorola SPI frame format
+
+   sclk ______~_~_~_~_~_~_~____
+   sfrm ~~~~________________~~~
+   stxd -----bn..........b0----
+   srxd ----.bn..........b0----
+
+   - data latched in on the rising edge of the clock
+   - data shifted out on the falling edge of the clock, or falling edge
+     of sfrm
+
+3. National Microwire format
+
+   sclk ______~_~_~_~_~_~_~_~_~_~_~_~_~_____
+   sfrm ~~~~_____________________________~~~
+   stxd -----bn......b0---------------------
+   srxd -----------------bn..........b0.----
+
+   - data latched in on the rising edge of the clock
+   - data shifted out on the falling edge of the clock
+   - half duplex, one clock between transmission and reception
+
+Types of devices
+----------------
+
+The following types of devices can be found on a SSP bus:
+
+	Sound chips
+	Keyboard devices
+	Touch screen devices
+
+Keyboard
+--------
+
+TX:
+0. Format: cfglen = 8, framelen = 8, clkpol = 1, clk < 250kHz
+1. select device
+2. keyboard responds asserting key_atn
+3. wait 0.1ms to 5ms
+4. transmit data byte
+5. wait >= 150us
+6. repeat step 4 until all data sent
+7. deselect device
+8. keyboard responds de-asserting key_atn
+9. wait >= 120us
+
+RX:
+0. Format: cfglen = 8, framelen = 8, clkpol = 1, clk < 250kHz
+1. keyboard asserts key_atn
+2. select device after 0.1ms < 5ms
+3. read data byte
+4. wait 150us
+5. if key_atn still asserted, goto 3
+6. deselect device
+7. wait >= 120us
diff -urN linux-2.4.29/drivers/ssi/ssi_bus.h linux-2.4.29-uc1/drivers/ssi/ssi_bus.h
--- linux-2.4.29/drivers/ssi/ssi_bus.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ssi/ssi_bus.h	2005-06-14 02:12:20.000000000 +0100
@@ -0,0 +1,21 @@
+#include <linux/circ_buf.h>
+
+struct ssi_dev;
+
+struct ssi_bus {
+	u_char		cfglen;
+	u_char		framelen;
+	u_char		clkpol;
+	u_char		proto;
+	struct ssi_dev	*dev;		/* current device */
+	int		(*select)(struct ssi_bus *, struct ssi_dev *);
+	int		(*trans)(struct ssi_bus *, u_int data);
+	int		(*init)(struct ssi_bus *);
+	void		(*exit)(struct ssi_bus *);
+	char		*name;
+	u_int		devices;
+};
+
+extern int ssi_core_rcv(struct ssi_bus *bus, u_int data);
+extern int ssi_register_bus(struct ssi_bus *bus);
+extern int ssi_unregister_bus(struct ssi_bus *bus);
diff -urN linux-2.4.29/drivers/ssi/ssi_core.c linux-2.4.29-uc1/drivers/ssi/ssi_core.c
--- linux-2.4.29/drivers/ssi/ssi_core.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ssi/ssi_core.c	2005-06-14 02:12:20.000000000 +0100
@@ -0,0 +1,175 @@
+/*
+ *  linux/drivers/ssi/ssi_core.c
+ *
+ * This file provides a common framework to allow multiple SSI devices
+ * to work together on a single SSI bus.
+ *
+ * You can use this in two ways:
+ *  1. select the device, queue up data, flush the data to the device,
+ *     (optionally) purge the received data, deselect the device.
+ *  2. select the device, queue up one data word, flush to the device
+ *     read data word, queue up next data word, flush to the device...
+ *     deselect the device.
+ */
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/init.h>
+
+#include <asm/errno.h>
+
+#include "ssi_bus.h"
+#include "ssi_dev.h"
+
+#define DEBUG
+
+/**
+ *	ssi_core_rcv - pass received SSI data to the device
+ *	@bus: the bus that the data was received from
+ *	@data: the data word that was received
+ *
+ *	This function is intended to be called by SSI bus device
+ *	drivers to pass received data to the device driver.
+ */
+int ssi_core_rcv(struct ssi_bus *bus, u_int data)
+{
+	struct ssi_dev *dev = bus->dev;
+
+	if (dev && dev->rcv)
+		dev->rcv(dev, data);
+
+	return 0;
+}
+
+/**
+ *	ssi_transmit_data - queue SSI data for later transmission
+ *	@dev: device requesting data to be transmitted
+ *	@data: data word to be transmitted.
+ *
+ *	Queue one data word of SSI data for later transmission.
+ */
+int ssi_transmit_data(struct ssi_dev *dev, u_int data)
+{
+	struct ssi_bus *bus = dev->bus;
+
+	/*
+	 * Make sure that we currently own the bus
+	 */
+	if (bus->dev != dev)
+		BUG();
+
+	bus->trans(bus, data);
+	return 0;
+}
+
+/**
+ *	ssi_select_device - select a SSI device for later transactions
+ *	@dev: device to be selected
+ */
+int ssi_select_device(struct ssi_bus *bus, struct ssi_dev *dev)
+{
+	int retval;
+
+#ifdef DEBUG
+	printk("SSI: selecting device %s on bus %s\n",
+		dev ? dev->name : "<none>", bus->name);
+#endif
+
+	/*
+	 * Select the device if it wasn't already selected.
+	 */
+	retval = 0;
+	if (bus->dev != dev) {
+		retval = bus->select(bus, dev);
+		bus->dev = dev;
+	}
+
+	return retval;
+}
+
+/**
+ *	ssi_register_device - register a SSI device with a SSI bus
+ *	@bus: bus
+ *	@dev: SSI device
+ */
+int ssi_register_device(struct ssi_bus *bus, struct ssi_dev *dev)
+{
+	int retval;
+
+	dev->bus = bus;
+	bus->devices++;
+	retval = dev->init(dev);
+	if (retval != 0) {
+		dev->bus = NULL;
+		bus->devices--;
+	} else {
+#ifdef DEBUG
+		printk("SSI: registered new device %s on bus %s\n", dev->name, bus->name);
+#endif
+	}
+	return retval;
+}
+
+/**
+ *	ssi_unregister_device - unregister a SSI device from a SSI bus
+ *	@dev: SSI device
+ */
+int ssi_unregister_device(struct ssi_dev *dev)
+{
+	struct ssi_bus *bus = dev->bus;
+
+	if (bus->dev == dev)
+		bus->dev = NULL;
+
+	dev->bus = NULL;
+	bus->devices--;
+#ifdef DEBUG
+	printk("SSI: unregistered device %s on bus %s\n", dev->name, bus->name);
+#endif
+	return 0;
+}
+
+/**
+ *	ssi_register_bus - register a SSI bus driver
+ *	@bus: bus
+ */
+int ssi_register_bus(struct ssi_bus *bus)
+{
+	int retval;
+
+	retval = bus->init(bus);
+	if (retval == 0) {
+		bus->devices = 0;
+#ifdef DEBUG
+		printk("SSI: registered new bus %s\n", bus->name);
+#endif
+	}
+
+	return retval;
+}
+
+/**
+ *	ssi_unregister_bus - unregister a SSI bus driver
+ *	@bus: bus
+ */
+int ssi_unregister_bus(struct ssi_bus *bus)
+{
+	int retval = -EBUSY;
+	if (bus->devices == 0) {
+		retval = 0;
+	}
+	return retval;
+}
+
+static int __init ssi_init(void)
+{
+	return 0;
+}
+
+static void __exit ssi_exit(void)
+{
+}
+
+module_init(ssi_init);
+module_exit(ssi_exit);
diff -urN linux-2.4.29/drivers/ssi/ssi_dev.h linux-2.4.29-uc1/drivers/ssi/ssi_dev.h
--- linux-2.4.29/drivers/ssi/ssi_dev.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/ssi/ssi_dev.h	2005-06-14 02:12:20.000000000 +0100
@@ -0,0 +1,21 @@
+struct ssi_bus;
+
+#define SSI_SPI		1
+#define SSI_MICROWIRE	2
+#define SSI_TISSF	3
+#define SSI_USAR	4
+
+struct ssi_dev {
+	char		*name;
+	u_int		id;
+	u_int		clkfreq;
+	u_char		cfglen;
+	u_char		framelen;
+	u_char		clkpol;
+	u_char		proto;
+	void		(*rcv)(struct ssi_dev *, u_int);
+	int		(*init)(struct ssi_dev *);
+	struct ssi_bus	*bus;
+};
+
+
diff -urN linux-2.4.29/drivers/usb/Config.in linux-2.4.29-uc1/drivers/usb/Config.in
--- linux-2.4.29/drivers/usb/Config.in	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/usb/Config.in	2005-06-14 02:12:06.000000000 +0100
@@ -4,7 +4,15 @@
 mainmenu_option next_comment
 comment 'USB support'
 
+if [ "$CONFIG_UCLINUX" = "y" -o \
+	"$CONFIG_SA1111" = "y" -o \
+	"$CONFIG_ARCH_AT91RM9200" = "y" -o \
+	"$CONFIG_ARCH_EP93XX" = "y" ]; then
+tristate 'Support for USB' CONFIG_USB
+else
 dep_tristate 'Support for USB' CONFIG_USB $CONFIG_PCI
+fi
+
 if [ "$CONFIG_USB" = "y" -o  "$CONFIG_USB" = "m" ]; then
    bool '  USB verbose debug messages' CONFIG_USB_DEBUG
 
diff -urN linux-2.4.29/drivers/usb/edb7312-usb.c linux-2.4.29-uc1/drivers/usb/edb7312-usb.c
--- linux-2.4.29/drivers/usb/edb7312-usb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/usb/edb7312-usb.c	2005-06-14 02:12:07.000000000 +0100
@@ -0,0 +1,3055 @@
+/*
+ * EDB7312 support for PDIUSBD12 / mass-storage.
+ *
+ *	(c) Copyright 2003 Petko Manolov <petkan@nucleusys.com>
+ *	(c) Copyright 2003 Vladimir Ivanov <vladitx@nucleusys.com>
+ *
+ * TODO:
+ * 	 - more SCSI commands for various OS needs
+ *       - make this endian-independent with respect to USB structs,
+ * as it is currently LE
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * 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/arch/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/delay.h>
+#include <asm/semaphore.h>
+#include <asm/signal.h>
+#include <asm/system.h>
+#include <asm/types.h>
+
+#include <linux/completion.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+
+#include <linux/blkdev.h>
+#include <linux/fs.h>
+#include <linux/kdev_t.h>
+#include <linux/locks.h>
+
+/*
+ * XXX: Here's a good thing to think about
+ *
+ *   According to USB 1.1, "Set Address" device request is the only one which
+ * should be processed differently and must be completed _after_ successfull
+ * status state ... do you really believe specs? We usually don't, but it
+ * takes some time to find exactly what we won't believe.
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * debug mode
+ */
+
+#undef DBG
+#define ID "usbd12"
+
+/*
+ * hardware description
+ */
+
+#define IRQ_D12		IRQ_EINT1
+
+#define REG_D12_DAT	(EDB7312_VIRT_PDIUSBD12 + 0)
+#define REG_D12_CMD	(EDB7312_VIRT_PDIUSBD12 + 1)
+
+/* 
+ * XXX:
+ *
+ * It seems that different EDB7312 revisions have the SUSPEND signal of
+ * PDIUSBD12 routed to different locations. This is specific to P7 revision.
+ */
+
+#define GPIO_D12_SUSP	((__raw_readb(EP7312_VIRT_CS3 + 0x0004) & 0x04) ? 1 : 0)
+
+#define __delay()	{			\
+	__raw_readb(EP7312_VIRT_CS3 + 0x0004);	\
+	__raw_readb(EP7312_VIRT_CS3 + 0x0004);	\
+}
+
+/*
+ * atomic operations
+ */
+
+#define d12_lock(p)	disable_irq((p)->irq)
+#define	d12_unlock(p)	enable_irq((p)->irq)
+
+/*
+ * PDIUSBD12 commands and data
+ */
+
+/* --- "Select endpoint" --- */
+
+#define CMD_SELECT_ENDP		0x00
+
+#define D_SELECT_ENDP_FULL	0x01
+#define D_SELECT_ENDP_STALL	0x02
+
+/* --- "Set endpoint status" --- */
+
+#define CMD_SET_ENDP_STATUS	0x40
+
+/* --- "Read last transaction status" --- */
+
+#define CMD_READ_LTRNS		0x40
+
+#define D_READ_LTRNS_SUCCESS	0x01
+#define D_READ_LTRNS_ERR_M	0x1E
+#define D_READ_LTRNS_SETUP	0x20
+#define D_READ_LTRNS_DATA1	0x40
+#define D_READ_LTRNS_PREV	0x80
+
+#define D_READ_LTRNS_ERR_NO		(0 << 1)
+#define D_READ_LTRNS_ERR_PID_ENC	(1 << 1)
+#define D_READ_LTRNS_ERR_PID_UNK	(2 << 1)
+#define D_READ_LTRNS_ERR_UNEXP_PK	(3 << 1)
+#define D_READ_LTRNS_ERR_TOKCRC		(4 << 1)
+#define D_READ_LTRNS_ERR_DATACRC	(5 << 1)
+#define D_READ_LTRNS_ERR_TIMEOUT	(6 << 1)
+#define D_READ_LTRNS_ERR_NEVER		(7 << 1)
+#define D_READ_LTRNS_ERR_UNEXP_EOP	(8 << 1)
+#define D_READ_LTRNS_ERR_NAK		(9 << 1)
+#define D_READ_LTRNS_ERR_STALL		(10 << 1)
+#define D_READ_LTRNS_ERR_OVF		(11 << 1)
+#define D_READ_LTRNS_ERR_BITSTUFF	(13 << 1)
+#define D_READ_LTRNS_ERR_WRONG_DPID	(15 << 1)
+
+/* --- "Read endpoint status" --- */
+
+#define CMD_READ_ENDP_STATUS	0x80
+
+#define D_READ_ENDP_STAT_BUF0	0x20
+#define D_READ_ENDP_STAT_BUF1	0x40
+
+/* --- "Set address / enable" --- */
+
+#define CMD_SET_ADDR_EN		0xD0
+
+/* --- "Set endpoint enable" --- */
+
+#define CMD_SET_ENDP_EN		0xD8
+
+/* --- "Read buffer" --- */
+
+#define CMD_READ_BUFFER		0xF0
+
+/* --- "Write buffer" --- */
+
+#define CMD_WRITE_BUFFER	0xF0
+
+/* --- "Acknowledge setup" --- */
+
+#define CMD_ACKNOWLEDGE_SETUP	0xF1
+
+/* --- "Clear buffer" --- */
+
+#define CMD_CLEAR_BUFFER	0xF2
+
+/* --- "Set mode" --- */
+
+#define CMD_MODE		0xF3
+
+#define	D_MODE0_NOLAZYCLK	0x02
+#define	D_MODE0_CLKRUNNING	0x04
+#define D_MODE0_INTMODE		0x08
+#define D_MODE0_SOFTCONNECT	0x10
+#define D_MODE0_EP_NONISO	(0 << 6)
+
+#define D_MODE1_CLK4M		0x0B
+#define D_MODE1_SETTOONE	0x40
+#define D_MODE1_SOFONLY		0x80
+
+/*
+ * default CLKOUT mode is:
+ *	- lazy clock during standby
+ *	- no clock running during standby
+ *	- 4 MHz
+ */
+
+#define D_MODE0_DEFAULT		D_MODE0_EP_NONISO
+#define D_MODE1_DEFAULT		(D_MODE1_SETTOONE | D_MODE1_CLK4M)
+
+/* --- "Read interrupt register" --- */
+
+#define CMD_READ_INT		0xF4
+
+#define D_READ_INT_EP0_O	0x0001
+#define D_READ_INT_EP0_I	0x0002
+#define D_READ_INT_EP1_O	0x0004
+#define D_READ_INT_EP1_I	0x0008
+#define D_READ_INT_EP2_O	0x0010
+#define D_READ_INT_EP2_I	0x0020
+#define D_READ_INT_BUSRESET	0x0040
+#define D_READ_INT_SUSPENDCHG	0x0080
+#define D_READ_INT_DMAEOT	0x0100
+
+/* --- "Read current frame number" --- */
+
+#define CMD_READ_FRAMENUM	0xF5
+
+/* --- "Validate buffer" --- */
+
+#define CMD_VALIDATE_BUFFER	0xFA
+
+/* --- "Set DMA" --- */
+
+#define CMD_DMA			0xFB
+
+#define D_DMA_NODMA		0x00
+#define D_DMA_INTMODE		0x20
+#define D_DMA_EPX4IE		0x40
+#define D_DMA_EPX5IE		0x80
+
+#define D_DMA_DEFAULT		D_DMA_NODMA
+
+/*
+ * general constants
+ */
+
+#define TIME_OUT	(HZ * 5)
+
+#define EP_CTRL		0
+#define EP_FREE		1
+#define EP_BULK		2
+
+#define EPX_CTRL_O	0
+#define EPX_CTRL_I	1
+#define EPX_FREE_O	2
+#define EPX_FREE_I	3
+#define EPX_BULK_O	4
+#define EPX_BULK_I	5
+
+#define EP_CTRL_SIZE	16
+#define EP_FREE_SIZE	16
+#define EP_BULK_SIZE	64
+
+/* --- */
+
+#define CONFIG_VAL	1
+
+#define DEF_LANG	0x0409
+
+/* ------------------------------------------------------------------------- */
+
+/* USB 1.1 */
+
+#define REQTYPE_DIR_M		0x80
+#define REQTYPE_DIR_OUT		(0 << 7)
+#define REQTYPE_DIR_IN		(1 << 7)
+#define REQTYPE_TYPE_M		0x60
+#define REQTYPE_TYPE_STANDARD	(0 << 5)
+#define REQTYPE_TYPE_CLASS	(1 << 5)
+#define REQTYPE_TYPE_VENDOR	(2 << 5)
+#define REQTYPE_RECP_M		0x1F
+#define REQTYPE_RECP_DEVICE	(0 << 0)
+#define REQTYPE_RECP_INTERFACE	(1 << 0)
+#define REQTYPE_RECP_ENDPOINT	(2 << 0)
+
+struct devreq {
+	__u8 bmRequestType;
+	__u8 bRequest;
+	__u16 wValue;
+	__u16 wIndex;
+	__u16 wLength;
+} __attribute__ ((packed));
+
+#define DESC_TYPE_DEVICE	1
+#define DESC_TYPE_CONFIGURATION	2
+#define DESC_TYPE_STRING	3
+#define DESC_TYPE_INTERFACE	4
+#define DESC_TYPE_ENDPOINT	5
+
+#define CLASS_MASS_STORAGE	0x08
+#define SUBCLASS_SCSI		0x06
+#define PROTOCOL_BULK		0x50
+
+#define STATUS_DEVICE_SELF_POWERED	0x01
+#define STATUS_DEVICE_REMOTE_WAKEUP	0x02
+#define STATUS_ENDPOINT_HALT		0x01
+
+#define FEATURE_ENDPOINT_HALT		0
+#define FEATURE_DEVICE_REMOTE_WAKEUP	1
+
+/* mass-storage, bulk-only */
+
+#define CBW_SIGNATURE		0x43425355
+
+#define CBW_FLAGS_DIR_M		0x80
+#define CBW_FLAGS_DIR_OUT	(0 << 7)
+#define CBW_FLAGS_DIR_IN	(1 << 7)
+
+struct cbw {
+	__u32 dCBWSignature;
+	__u32 dCBWTag;
+	__u32 dCBWDataTransferLength;
+	__u8 bmCBWFlags;
+	__u8 bCBWLUN;
+	__u8 bCBWCBLength;
+	__u8 CBWCB[16];
+} __attribute__ ((packed));
+
+#define CSW_SIGNATURE		0x53425355
+
+#define CSW_STAT_OK		0
+#define CSW_STAT_FAILED		1
+#define CSW_STAT_PHASE_ERROR	2
+
+struct csw {
+	__u32 dCSWSignature;
+	__u32 dCSWTag;
+	__u32 dCSWDataResidue;
+	__u8 bCSWStatus;
+} __attribute__ ((packed));
+
+/* ------------------------------------------------------------------------- */
+
+/* SCSI SPC-2 */
+
+#define SCSI_SKEY_NO_SENSE		0
+#define SCSI_SKEY_NOT_READY		2
+#define SCSI_SKEY_MEDIUM_ERROR		3
+#define SCSI_SKEY_ILLEGAL_REQUEST	5
+
+#define SCSI_ASC_NO				0x0000
+#define SCSI_ASC_LOGICAL_UNIT_NOT_READY		0x0400
+#define SCSI_ASC_WRITE_ERROR			0x0C02
+#define SCSI_ASC_UNRECOVERED_READ_ERROR		0x1100
+#define SCSI_ASC_INVALID_CMD			0x2000
+#define SCSI_ASC_LBA_OUT_OF_RANGE		0x2100
+#define SCSI_ASC_INVALID_FIELD_IN_CDB		0x2400
+#define SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED	0x2500
+
+#define MAX_SCSI_DATA_SENSE		18
+#define MAX_SCSI_DATA_INQUIRY		36
+#define MAX_SCSI_DATA_CAPACITY10	8
+#define MAX_SCSI_DATA_CAPACITY16	12
+
+/* ------------------------------------------------------------------------- */
+
+/* device I/O request */
+
+struct dioreq {
+	int cmd;				/* device i/o command */
+	int lun;
+	__u32 lba;
+	__u32 blks;
+	__u32 nblks;
+	void *buf;
+};
+
+/* device context */
+
+#define FSM_DEV_POWERED		0
+#define FSM_DEV_DEFAULT		1
+#define FSM_DEV_ADDRESS		2
+#define FSM_DEV_CONFIGURED	3
+
+#define FSM_CTL_IDLE		0
+#define FSM_CTL_DATA_IN		1
+#define FSM_CTL_STATUS_OUT	2
+#define FSM_CTL_STATUS_IN	3
+
+#define FSM_BULK_IDLE		0
+#define FSM_BULK_DATA_OUT	1
+#define FSM_BULK_DATA_OUT_WAIT	2
+#define FSM_BULK_DATA_IN	3
+#define FSM_BULK_DATA_IN_WAIT	4
+#define FSM_BULK_STALL_TO_CSW	5
+
+#define MAX_DBUF		256
+#define MAX_CHUNKBUF		65536
+
+#define ATD_STAT_READY		(1 << 0)
+#define ATD_STAT_RO		(1 << 1)
+
+#define DIO_CMD_EXIT		1
+#define DIO_CMD_READ		2
+#define DIO_CMD_WRITE		3
+#define DIO_CMD_VERIFY		4
+
+struct d12 {
+	unsigned int reg_cmd;
+	unsigned int reg_dat;
+	unsigned int irq;
+
+	const void *desc_dev;
+	int desc_dev_len;
+
+	const void *desc_cfg;
+	int desc_cfg_len;
+
+	int desc_str_max;
+	const void * const *desc_str;
+	const int *desc_str_len;
+
+	/* --- */
+
+	int max_lun;
+
+	const void *scsi_str_vendor[16];
+	const void *scsi_str_product[16];
+	const void *scsi_str_revision[16];
+
+	kdev_t atd_dev[16];			/* attached device */
+	int atd_blk[16];			/* block size */
+	int atd_chunkblk[16];			/* blocks per chunk */
+	__u32 atd_lba_capacity[16];		/* capacity in blocks */
+	int atd_stat[16];			/* status */
+
+	struct block_device *bdev[16];
+
+	/* --- */
+
+	int suspend;				/* 1- in suspend mode */
+
+	int feat_wakeup;			/* remote wakeup */
+
+	int fsm_dev;				/* device state */
+
+	int fsm_ctl;				/* control endpoint state */
+	int fsm_ctl_lastpkt;			/* last packet sent */
+
+	struct devreq drq;			/* device requests */
+	unsigned char dbuf[MAX_DBUF];		/* data buffer */
+	int dlen, dptr;
+
+	int fsm_bulk;				/* bulk endpoint state */
+
+	unsigned char *bbuf;			/* bulk buffer chunk */
+	int blen, bptr;
+	void (*bhd)(struct d12 *, int, int);	/* chunk handler */
+	int bxferlen, bxferptr;			/* total transfer length */
+
+	struct cbw cbw;				/* CBW request */
+	struct csw csw;				/* CSW answer */
+	int cswdelay;				/* postpone CSW sending */
+	int cswearly;				/* early CSW sending on error */
+
+	unsigned char scsi_sense[MAX_SCSI_DATA_SENSE];	/* should this be per LUN ? */
+
+	__u32 scsi_lba;
+	__u32 scsi_blks;
+
+	struct completion cpl_dio_sync;		/* enter / exit sync */
+	struct semaphore wait_dio_cmd;
+	volatile struct dioreq dio;
+
+	unsigned char tmp[256];			/* template */
+	unsigned char chunkbuf[MAX_CHUNKBUF];
+};
+
+struct d12 d12;
+
+/* ------------------------------------------------------------------------- */
+
+static __u16 get_u16be(const void *p)
+{
+	const unsigned char *b;
+	__u16 r;
+
+	b = (const unsigned char *)p;
+
+	r = (b[0] << 8) |
+	    (b[1] << 0);
+
+	return r;
+}
+
+#if 0
+static void put_16be(void *p, __u16 d)
+{
+	unsigned char *b;
+
+	b = (unsigned char *)p;
+
+	b[0] = (d >> 8) & 0xFF;
+	b[1] = (d >> 0) & 0xFF;
+}
+#endif
+
+static __u32 get_u32be(const void *p)
+{
+	const unsigned char *b;
+	__u32 r;
+
+	b = (const unsigned char *)p;
+
+	r = (b[0] << 24) |
+	    (b[1] << 16) |
+	    (b[2] <<  8) |
+	    (b[3] <<  0);
+
+	return r;
+}
+
+static void put_32be(void *p, __u32 d)
+{
+	unsigned char *b;
+
+	b = (unsigned char *)p;
+
+	b[0] = (d >> 24) & 0xFF;
+	b[1] = (d >> 16) & 0xFF;
+	b[2] = (d >>  8) & 0xFF;
+	b[3] = (d >>  0) & 0xFF;
+}
+
+static __u64 get_u64be(const void *p)
+{
+	const unsigned char *b;
+	__u64 r;
+
+	b = (const unsigned char *)p;
+
+	r = get_u32be(b + 0);
+	r <<= 32;
+	r |= get_u32be(b + 4);
+
+	return r;
+}
+
+static void put_64be(void *p, __u64 d)
+{
+	unsigned char *b;
+
+	b = (unsigned char *)p;
+
+	put_32be(b + 0, d >> 32);
+	put_32be(b + 4, d >>  0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * low-level PDIUSBD12
+ */
+
+static inline void d12_outc(struct d12 *p, int cmd)
+{
+	__delay();
+	__raw_writeb(cmd, p->reg_cmd);
+}
+
+static inline void d12_outd(struct d12 *p, int dat)
+{
+	__delay();
+	__raw_writeb(dat, p->reg_dat);
+}
+
+static inline int d12_ind(struct d12 *p)
+{
+	__delay();
+	return __raw_readb(p->reg_dat);
+}
+
+/* --- */
+
+static inline void d12_out1(struct d12 *p, int cmd, int d0)
+{
+	d12_outc(p, cmd);
+	d12_outd(p, d0);
+}
+
+static inline void d12_out2(struct d12 *p, int cmd, int d0, int d1)
+{
+	d12_outc(p, cmd);
+	d12_outd(p, d0);
+	d12_outd(p, d1);
+}
+
+static inline int d12_in1(struct d12 *p, int cmd)
+{
+	d12_outc(p, cmd);
+	return d12_ind(p);
+}
+
+static inline int d12_in2(struct d12 *p, int cmd)
+{
+	int d0, d1;
+
+	d12_outc(p, cmd);
+	d0 = d12_ind(p);
+	d1 = d12_ind(p);
+	return (d1 << 8) | d0;
+}
+
+/* --- */
+
+/* clear buffer */
+
+static void d12_buf_clear(struct d12 *p)
+{
+	d12_outc(p, CMD_CLEAR_BUFFER);
+}
+
+/* validate buffer */
+
+static void d12_buf_validate(struct d12 *p)
+{
+	d12_outc(p, CMD_VALIDATE_BUFFER);
+}
+
+/* get frame number */
+
+#if 0
+static int d12_frame(struct d12 *p)
+{
+	return d12_in2(p, CMD_READ_FRAMENUM) & 0x7FF;
+}
+#endif
+
+/* read last transaction status and ack interrupt */
+
+static int d12_read_last_trans(struct d12 *p, int epx)
+{
+	return d12_in1(p, CMD_READ_LTRNS + epx);
+}
+
+/* set data pointer to start of internal buffer */
+
+static int d12_select_endpoint(struct d12 *p, int epx)
+{
+	return d12_in1(p, CMD_SELECT_ENDP + epx);
+}
+
+/* set USB address (0x00 .. 0x7F) and enable */
+
+static void d12_set_address_enable(struct d12 *p, int adr, int en)
+{
+	d12_out1(p, CMD_SET_ADDR_EN, adr | (en ? 0x80 : 0x00));
+}
+
+/* enable generic/isochronous endpoints */
+
+static void d12_set_endpoint_enable(struct d12 *p, int en)
+{
+	d12_out1(p, CMD_SET_ENDP_EN, en ? 0x01 : 0x00);
+}
+
+/* get endpoint status */
+
+static int d12_status_get(struct d12 *p, int epx)
+{
+	return d12_in1(p, CMD_READ_ENDP_STATUS + epx);
+}
+
+/* unconditionally initialize / stall endpoint */
+
+static void d12_status_set(struct d12 *p, int epx, int stall)
+{
+	d12_out1(p, CMD_SET_ENDP_STATUS + epx, stall);
+}
+
+/* --- */
+
+/* stall / unstall */
+
+static void d12_stall_ctrl(struct d12 *p, int stall)
+{
+	d12_status_set(p, EPX_CTRL_O, stall);
+	d12_status_set(p, EPX_CTRL_I, stall);
+}
+
+static void d12_stall_free(struct d12 *p, int stall)
+{
+	d12_status_set(p, EPX_FREE_O, stall);
+	d12_status_set(p, EPX_FREE_I, stall);
+}
+
+static void d12_stall_bulk(struct d12 *p, int stall)
+{
+	d12_status_set(p, EPX_BULK_O, stall);
+	d12_status_set(p, EPX_BULK_I, stall);
+}
+
+/* connect / disconnect */
+
+static void d12_connect(struct d12 *p, int on)
+{
+	d12_out2(p, CMD_MODE, D_MODE0_DEFAULT | (on ? D_MODE0_SOFTCONNECT : 0), D_MODE1_DEFAULT);
+}
+
+/* after bus-reset */
+
+static void d12_reset(struct d12 *p)
+{
+	d12_set_address_enable(p, 0, 1);
+	d12_set_endpoint_enable(p, 0);
+
+	d12_stall_ctrl(p, 1);
+	d12_stall_free(p, 1);
+	d12_stall_bulk(p, 1);
+}
+
+/* initialize */
+
+static void d12_init(struct d12 *p)
+{
+	d12_connect(p, 0);
+	d12_out1(p, CMD_DMA, D_DMA_DEFAULT | D_DMA_EPX4IE | D_DMA_EPX5IE);
+
+	d12_reset(p);
+
+	d12_connect(p, 1);
+}
+
+/* acknowledge setup on endpoint #0 */
+
+static void d12_acknowledge_setup(struct d12 *p)
+{
+	d12_select_endpoint(p, EPX_CTRL_O);
+	d12_outc(p, CMD_ACKNOWLEDGE_SETUP);
+	d12_select_endpoint(p, EPX_CTRL_I);
+	d12_outc(p, CMD_ACKNOWLEDGE_SETUP);
+}
+
+/* read buffer */
+
+static int d12_buf_read(struct d12 *p, int epx, void *buf, int max)
+{
+	int i, l, len, stat;
+	unsigned char *b;
+
+	b = (unsigned char *)buf;
+
+	if (epx == EPX_BULK_O) {
+		stat = d12_status_get(p, epx);
+		i = len = 0;
+		if (stat & D_READ_ENDP_STAT_BUF0)
+			i++;
+		if (stat & D_READ_ENDP_STAT_BUF1)
+			i++;
+
+		while (i-- && (max - len)) {
+			d12_select_endpoint(p, epx);
+
+			d12_in1(p, CMD_READ_BUFFER);
+			l = d12_ind(p);
+
+			if (len + l > max)
+				l = max - len;
+			len += l;
+
+			while (l--)
+				*b++ = d12_ind(p);
+			d12_buf_clear(p);
+		}
+	} else {
+		d12_select_endpoint(p, epx);
+
+		d12_in1(p, CMD_READ_BUFFER);
+		l = d12_ind(p);
+
+		if (l > max)
+			l = max;
+		len = l;
+
+		while (l--)
+			*b++ = d12_ind(p);
+		d12_buf_clear(p);
+	}
+
+	return len;
+}
+
+/* write buffer */
+
+static int d12_buf_write(struct d12 *p, int epx, const void *buf, int len)
+{
+	int i, l, l2, stat;
+	const unsigned char *b;
+
+	b = (const unsigned char *)buf;
+
+	if (epx == EPX_BULK_I) {
+		stat = d12_status_get(p, epx);
+		i = 2;
+		if (stat & D_READ_ENDP_STAT_BUF0)
+			i--;
+		if (stat & D_READ_ENDP_STAT_BUF1)
+			i--;
+
+		l2 = 0;
+		while (i-- && len) {
+			d12_select_endpoint(p, epx);
+
+			l = len;
+			if (l > EP_BULK_SIZE)
+				l = EP_BULK_SIZE;
+			d12_out2(p, CMD_WRITE_BUFFER, 0, l);
+
+			l2 += l;
+			len -= l;
+
+			while (l--)
+				d12_outd(p, *b++);
+			d12_buf_validate(p);
+		}
+		len = l2;
+	} else {
+		d12_select_endpoint(p, epx);
+
+		d12_out2(p, CMD_WRITE_BUFFER, 0, len);
+
+		l = len;
+
+		while (l--)
+			d12_outd(p, *b++);
+		d12_buf_validate(p);
+	}
+
+	return len;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * USB 1.1 chapter 9 broken into tiny little pieces plus a little mass-storage
+ */
+
+static void ep_ctrl_ack(struct d12 *p)
+{
+	d12_buf_write(p, EPX_CTRL_I, 0, 0);
+	p->fsm_ctl = FSM_CTL_STATUS_IN;
+}
+
+static void ep_ctrl_write(struct d12 *p, const void *buf, int len)
+{
+	struct devreq *drq;
+
+	drq = &p->drq;
+
+	if (len > drq->wLength)			/* 9.3.5: return <= */
+		len = drq->wLength;
+
+	if (len > MAX_DBUF)
+		len = MAX_DBUF;
+
+	memcpy(p->dbuf, buf, len);
+	p->dlen = len;
+	p->dptr = 0;
+
+	if (len > EP_CTRL_SIZE)
+		len = EP_CTRL_SIZE;
+
+	d12_buf_write(p, EPX_CTRL_I, p->dbuf, len);
+	p->dptr += len;
+
+	p->fsm_ctl = (p->dptr == p->dlen) ? FSM_CTL_STATUS_OUT : FSM_CTL_DATA_IN;
+	p->fsm_ctl_lastpkt = len;
+}
+
+/* --- */
+
+static int std_reserved(struct d12 *p)
+{
+#ifdef DBG
+	printk("%s: unsupported reserved request\n", ID);
+#endif
+	return 1;
+}
+
+static int std_get_status(struct d12 *p)
+{
+	struct devreq *drq;
+	int ep, epx;
+	unsigned char buf[2];
+
+	drq = &p->drq;
+
+	if ((drq->bmRequestType & (REQTYPE_DIR_M | REQTYPE_TYPE_M)) != (REQTYPE_DIR_IN | REQTYPE_TYPE_STANDARD))
+		goto err;
+
+	if (drq->wValue || (drq->wLength != 2))
+		goto err;
+
+	if (p->fsm_dev == FSM_DEV_DEFAULT)
+		goto err;
+
+	buf[0] = buf[1] = 0;
+
+	switch (drq->bmRequestType & REQTYPE_RECP_M) {
+	case REQTYPE_RECP_DEVICE:
+		if (drq->wIndex)
+			goto err;
+
+		buf[0] = STATUS_DEVICE_SELF_POWERED | (p->feat_wakeup ? STATUS_DEVICE_REMOTE_WAKEUP : 0);
+#ifdef DBG
+		printk("%s: get_status device --> 0x%02x 0x%02x\n", ID, buf[0], buf[1]);
+#endif
+		break;
+
+	case REQTYPE_RECP_INTERFACE:
+		if (p->fsm_dev == FSM_DEV_ADDRESS)
+			goto err;
+
+		if (drq->wIndex & 0xFF)		/* only one interface */
+			goto err;		
+#ifdef DBG
+		printk("%s: get_status interface --> 0x%02x 0x%02x\n", ID, buf[0], buf[1]);
+#endif
+		break;
+
+	case REQTYPE_RECP_ENDPOINT:
+		ep = drq->wIndex & 0x0F;
+		if ((ep != EP_CTRL) && (ep != EP_BULK))
+			goto err;
+
+		if (p->fsm_dev == FSM_DEV_ADDRESS)
+			if (ep != EP_CTRL)
+				goto err;
+
+		epx = (ep << 1) | ((drq->wIndex & 0x80) ? 1 : 0);
+		buf[0] = (d12_select_endpoint(p, epx) & D_SELECT_ENDP_STALL) ? STATUS_ENDPOINT_HALT : 0;
+#ifdef DBG
+		printk("%s: get_status endpoint --> 0x%02x 0x%02x\n", ID, buf[0], buf[1]);
+#endif
+		break;
+
+	default:
+		goto err;
+	}
+
+	ep_ctrl_write(p, buf, drq->wLength);
+
+	return 0;
+
+err:
+#ifdef DBG
+	printk("%s: bad get_status request\n", ID);
+#endif
+	return 1;
+}
+
+static int feature(struct d12 *p, int on)
+{
+	struct devreq *drq;
+	int ep, epx;
+
+	drq = &p->drq;
+
+	if ((drq->bmRequestType & (REQTYPE_DIR_M | REQTYPE_TYPE_M)) != (REQTYPE_DIR_OUT | REQTYPE_TYPE_STANDARD))
+		goto err;
+
+	if (drq->wLength)
+		goto err;
+
+	if (p->fsm_dev == FSM_DEV_DEFAULT)
+		goto err;
+
+	switch (drq->bmRequestType & REQTYPE_RECP_M) {
+	case REQTYPE_RECP_DEVICE:
+		if (drq->wIndex)
+			goto err;
+
+		if (drq->wValue == FEATURE_DEVICE_REMOTE_WAKEUP) {
+			p->feat_wakeup = on;
+#ifdef DBG
+			printk("%s: %s_feature device_remote_wakeup\n", ID, on ? "set" : "clear");
+#endif
+		} else
+			goto err;
+		break;
+
+	case REQTYPE_RECP_INTERFACE:
+		goto err;
+
+	case REQTYPE_RECP_ENDPOINT:
+		ep = drq->wIndex & 0x0F;
+		if ((ep != EP_CTRL) && (ep != EP_BULK))
+			goto err;
+
+		if (p->fsm_dev == FSM_DEV_ADDRESS)
+			if (ep != EP_CTRL)
+				goto err;
+
+		epx = (ep << 1) | ((drq->wIndex & 0x80) ? 1 : 0);
+
+		if (drq->wValue == FEATURE_ENDPOINT_HALT) {
+			d12_status_set(p, epx, on);
+
+			if ((epx == EPX_BULK_I) && !on && (p->fsm_bulk == FSM_BULK_STALL_TO_CSW)) {
+				d12_buf_write(p, EPX_BULK_I, &p->csw, sizeof(struct csw));
+				p->fsm_bulk = FSM_BULK_IDLE;
+			}
+#ifdef DBG
+			printk("%s: %s_feature endpoint_halt on epx #%d\n", ID, on ? "set" : "clear", epx);
+#endif
+		} else
+			goto err;
+		break;
+
+	default:
+		goto err;
+	}
+
+	ep_ctrl_ack(p);
+
+	return 0;
+
+err:
+#ifdef DBG
+	printk("%s: bad %s_feature request\n", ID, on ? "set" : "clear");
+#endif
+	return 1;
+}
+
+static int std_clear_feature(struct d12 *p)
+{
+	return feature(p, 0);
+}
+
+static int std_set_feature(struct d12 *p)
+{
+	return feature(p, 1);
+}
+
+static int std_set_address(struct d12 *p)
+{
+	struct devreq *drq;
+
+	drq = &p->drq;
+
+	if (drq->bmRequestType != (REQTYPE_DIR_OUT | REQTYPE_TYPE_STANDARD | REQTYPE_RECP_DEVICE))
+		goto err;
+
+	if ((drq->wValue > 127) || drq->wIndex || drq->wLength)
+		goto err;
+
+	switch (p->fsm_dev) {
+	case FSM_DEV_DEFAULT:
+		if (drq->wValue)
+			p->fsm_dev = FSM_DEV_ADDRESS;
+		break;
+
+	case FSM_DEV_ADDRESS:
+		if (!drq->wValue)
+			p->fsm_dev = FSM_DEV_DEFAULT;
+		break;
+
+	case FSM_DEV_CONFIGURED:
+		goto err;
+	}
+
+	d12_set_address_enable(p, drq->wValue, 1);
+#ifdef DBG
+	printk("%s: set_address %d\n", ID, drq->wValue);
+#endif
+
+	ep_ctrl_ack(p);
+
+	return 0;
+
+err:
+#ifdef DBG
+	printk("%s: bad set_address request\n", ID);
+#endif
+	return 1;
+}
+
+static int std_get_descriptor(struct d12 *p)
+{
+	struct devreq *drq;
+	int type, ndx;
+	const void *buf;
+	int len;
+
+	drq = &p->drq;
+
+	if (drq->bmRequestType != (REQTYPE_DIR_IN | REQTYPE_TYPE_STANDARD | REQTYPE_RECP_DEVICE))
+		goto err;
+
+	type = (drq->wValue >> 8) & 0xFF;
+	ndx = drq->wValue & 0xFF;
+
+	switch (type) {
+	case DESC_TYPE_DEVICE:
+		if (ndx || drq->wIndex)
+			goto err;
+		buf = p->desc_dev;
+		len = p->desc_dev_len;
+#ifdef DBG
+		printk("%s: get_descriptor device\n", ID);
+#endif
+		break;
+
+	case DESC_TYPE_CONFIGURATION:
+		if (ndx || drq->wIndex)		/* only one configuration */
+			goto err;
+		buf = p->desc_cfg;
+		len = p->desc_cfg_len;
+#ifdef DBG
+		printk("%s: get_descriptor configuration %d\n", ID, ndx);
+#endif
+		break;
+
+	case DESC_TYPE_STRING:
+		if (!ndx) {
+			if (drq->wIndex)
+				goto err;
+		} else {
+			if ((ndx >= p->desc_str_max) || (drq->wIndex != DEF_LANG))
+				goto err;
+		}
+
+		buf = p->desc_str[ndx];
+		len = p->desc_str_len[ndx];
+#ifdef DBG
+		printk("%s: get_descriptor string %d\n", ID, ndx);
+#endif
+		break;
+
+	default:
+		goto err;
+	}
+
+	ep_ctrl_write(p, buf, len);
+
+	return 0;
+
+err:
+#ifdef DBG
+	printk("%s: bad get_descriptor request\n", ID);
+#endif
+	return 1;
+}
+
+static int std_set_descriptor(struct d12 *p)
+{
+#ifdef DBG
+	printk("%s: unsupported set_descriptor request\n", ID);
+#endif
+	return 1;
+}
+
+static int std_get_configuration(struct d12 *p)
+{
+	struct devreq *drq;
+	unsigned char buf[1];
+
+	drq = &p->drq;
+
+	if (drq->bmRequestType != (REQTYPE_DIR_IN | REQTYPE_TYPE_STANDARD | REQTYPE_RECP_DEVICE))
+		goto err;
+
+	if (drq->wValue || drq->wIndex || (drq->wLength != 1))
+		goto err;
+
+	switch (p->fsm_dev) {
+	case FSM_DEV_DEFAULT:
+		goto err;
+
+	case FSM_DEV_ADDRESS:
+		buf[0] = 0;
+		break;
+
+	case FSM_DEV_CONFIGURED:
+		buf[0] = CONFIG_VAL;
+		break;
+	}
+
+	ep_ctrl_write(p, buf, drq->wLength);
+#ifdef DBG
+	printk("%s: get_configuration --> %d\n", ID, buf[0]);
+#endif
+
+	return 0;
+
+err:
+#ifdef DBG
+	printk("%s: bad get_configuration request\n", ID);
+#endif
+	return 1;
+}
+
+static int std_set_configuration(struct d12 *p)
+{
+	struct devreq *drq;
+	int cfg;
+
+	drq = &p->drq;
+
+	if (drq->bmRequestType != (REQTYPE_DIR_OUT | REQTYPE_TYPE_STANDARD | REQTYPE_RECP_DEVICE))
+		goto err;
+
+	if ((drq->wValue & 0xFF00) || drq->wIndex || drq->wLength)
+		goto err;
+
+	cfg = drq->wValue & 0xFF;
+
+	switch (p->fsm_dev) {
+	case FSM_DEV_DEFAULT:
+		goto err;
+
+	case FSM_DEV_ADDRESS:
+		if (cfg == CONFIG_VAL) {
+			p->fsm_dev = FSM_DEV_CONFIGURED;
+			p->fsm_bulk = FSM_BULK_IDLE;
+			d12_set_endpoint_enable(p, 1);
+			d12_stall_bulk(p, 0);
+		} else if (cfg)
+			goto err;
+		break;
+
+	case FSM_DEV_CONFIGURED:
+		if (!cfg) {
+			p->fsm_dev = FSM_DEV_ADDRESS;
+			p->fsm_bulk = FSM_BULK_IDLE;
+			d12_stall_bulk(p, 1);
+			d12_set_endpoint_enable(p, 0);
+		} else if (cfg != CONFIG_VAL)
+			goto err;
+		break;
+	}
+
+	ep_ctrl_ack(p);
+#ifdef DBG
+	printk("%s: set_configuration %d\n", ID, cfg);
+#endif
+
+	return 0;
+
+err:
+#ifdef DBG
+	printk("%s: bad set_configuration request\n", ID);
+#endif
+	return 1;
+}
+
+static int std_get_interface(struct d12 *p)
+{
+	struct devreq *drq;
+	unsigned char buf[1];
+
+	drq = &p->drq;
+
+	if (drq->bmRequestType != (REQTYPE_DIR_IN | REQTYPE_TYPE_STANDARD | REQTYPE_RECP_INTERFACE))
+		goto err;
+
+	if (drq->wValue || (drq->wLength != 1))
+		goto err;
+
+	switch (p->fsm_dev) {
+	case FSM_DEV_DEFAULT:
+	case FSM_DEV_ADDRESS:
+		goto err;
+
+	case FSM_DEV_CONFIGURED:
+		if (!(drq->wIndex & 0xFF))	/* only one interface / alternative setting */
+			buf[0] = 0;
+		else
+			goto err;
+		break;
+	}
+
+	ep_ctrl_write(p, buf, drq->wLength);
+#ifdef DBG
+	printk("%s: get_interface --> %d\n", ID, buf[0]);
+#endif
+
+	return 0;
+
+err:
+#ifdef DBG
+	printk("%s: bad get_interface request\n", ID);
+#endif
+	return 1;
+}
+
+static int std_set_interface(struct d12 *p)
+{
+	struct devreq *drq;
+
+	drq = &p->drq;
+
+	if (drq->bmRequestType != (REQTYPE_DIR_OUT | REQTYPE_TYPE_STANDARD | REQTYPE_RECP_INTERFACE))
+		goto err;
+
+	if (drq->wLength)
+		goto err;
+
+	switch (p->fsm_dev) {
+	case FSM_DEV_DEFAULT:
+	case FSM_DEV_ADDRESS:
+		goto err;
+
+	case FSM_DEV_CONFIGURED:
+		if ((drq->wIndex & 0xFF) || drq->wValue)	/* only one interface / alternative setting */
+			goto err;
+
+		d12_stall_bulk(p, 0);
+
+		break;
+	}
+
+	ep_ctrl_ack(p);
+#ifdef DBG
+	printk("%s: set_interface %d\n", ID, drq->wIndex & 0xFF);
+#endif
+
+	return 0;
+
+err:
+#ifdef DBG
+	printk("%s: bad set_interface request\n", ID);
+#endif
+	return 1;
+}
+
+static int std_synch_frame(struct d12 *p)
+{
+#ifdef DBG
+	printk("%s: unsupported synch_frame request\n", ID);
+#endif
+	return 1;
+}
+
+/* --- */
+
+static int cls_mass_storage_reset(struct d12 *p)
+{
+	struct devreq *drq;
+
+	drq = &p->drq;
+
+	if (drq->bmRequestType != (REQTYPE_DIR_OUT | REQTYPE_TYPE_CLASS | REQTYPE_RECP_INTERFACE))
+		goto err;
+
+	if (drq->wValue || drq->wLength)
+		goto err;
+
+	if (drq->wIndex)			/* only one interface */
+		goto err;
+
+	p->fsm_bulk = FSM_BULK_IDLE;
+
+	ep_ctrl_ack(p);
+#ifdef DBG
+	printk("%s: set_interface %d\n", ID, drq->wIndex & 0xFF);
+#endif
+
+	return 0;
+
+err:
+#ifdef DBG
+	printk("%s: bad (class) mass_storage_reset request\n", ID);
+#endif
+	return 1;
+}
+
+static int cls_get_max_lun(struct d12 *p)
+{
+	struct devreq *drq;
+	unsigned char buf[1];
+
+	drq = &p->drq;
+
+	if (drq->bmRequestType != (REQTYPE_DIR_IN | REQTYPE_TYPE_CLASS | REQTYPE_RECP_INTERFACE))
+		goto err;
+
+	if (drq->wValue || (drq->wLength != 1))
+		goto err;
+
+	if (drq->wIndex)			/* only one interface */
+		goto err;
+
+	buf[0] = p->max_lun - 1;
+
+	ep_ctrl_write(p, buf, drq->wLength);
+#ifdef DBG
+	printk("%s: (class) get_max_lun --> %d\n", ID, buf[0]);
+#endif
+
+	return 0;
+
+err:
+#ifdef DBG
+	printk("%s: bad (class) get_max_lun request\n", ID);
+#endif
+	return 1;
+}
+
+/* --- */
+
+#define MAX_REQ_STANDARD 13
+
+static int (* const T_STD_SETUP[MAX_REQ_STANDARD])(struct d12 *) = {
+	std_get_status,
+	std_clear_feature,
+	std_reserved,
+	std_set_feature,
+	std_reserved,
+	std_set_address,
+	std_get_descriptor,
+	std_set_descriptor,
+	std_get_configuration,
+	std_set_configuration,
+	std_get_interface,
+	std_set_interface,
+	std_synch_frame
+};
+
+#define MAX_REQ_CLASS 2
+
+static int (* const T_CLS_SETUP[MAX_REQ_CLASS])(struct d12 *) = {
+	cls_mass_storage_reset,
+	cls_get_max_lun
+};
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * bulk and quazi-SCSI
+ */
+
+#define BULK_NONE		0
+#define BULK_OUT		0
+#define BULK_IN			1
+
+#define SCHD_ERR_PHASE		1
+#define SCHD_ERR_INVALID_CDB	2
+#define SCHD_ERR_INVALID_LBA	3
+
+static void ep_bulk_write(struct d12 *p, const void *buf, int len)
+{
+	if (p->bxferptr + len > p->bxferlen)
+		len = p->bxferlen - p->bxferptr;
+
+	if (len > MAX_CHUNKBUF)
+		len = MAX_CHUNKBUF;
+
+	p->bbuf = (unsigned char *)buf;
+	p->blen = len;
+	p->bptr = 0;
+
+	len = d12_buf_write(p, EPX_BULK_I, p->bbuf, len);
+	p->bptr += len;
+	p->bxferptr += len;
+
+	p->fsm_bulk = FSM_BULK_DATA_IN;
+}
+
+static void ep_bulk_read(struct d12 *p, void *buf, int len)
+{
+	if (p->bxferptr + len > p->bxferlen)
+		len = p->bxferlen - p->bxferptr;
+
+	if (len > MAX_CHUNKBUF)
+		len = MAX_CHUNKBUF;
+
+	p->bbuf = (unsigned char *)buf;
+	p->blen = len;
+	p->bptr = 0;
+
+	if (p->fsm_bulk == FSM_BULK_DATA_OUT_WAIT) {
+		len = d12_buf_read(p, EPX_BULK_O, p->bbuf, len);
+		p->bptr += len;
+		p->bxferptr += len;
+	}
+
+	p->fsm_bulk = FSM_BULK_DATA_OUT;
+}
+
+/* --- */
+
+static int bulk_xfer_chk(struct d12 *p, int dir, int len)
+{
+	struct cbw *cbw;
+	struct csw *csw;
+	int h, hi;
+
+	cbw = &p->cbw;
+	csw = &p->csw;
+
+	h = cbw->dCBWDataTransferLength;
+	hi = cbw->bmCBWFlags & CBW_FLAGS_DIR_IN;
+
+	p->bxferlen = p->bxferptr = 0;
+
+	if (dir == BULK_IN) {			/* Di */
+		if (!h)				/* Hn < Di */
+			goto phaserr;
+		else if (hi) {			/* Hi ? Di */
+			if (h >= len)		/* Hi >= Di */
+				p->bxferlen = len;
+			else 			/* Hi < Di */
+				goto phaserr;
+		} else				/* Ho <> Di */
+			goto phaserr;
+	} else if (len) {			/* Do */
+		if (!h)				/* Hn < Do */
+			goto phaserr;
+		else if (hi)			/* Hi <> Do */
+			goto phaserr;
+		else {				/* Ho ? Do */
+			if (h >= len)		/* Ho >= Do */
+				p->bxferlen = len;
+			else			/* Ho < Do */
+				goto phaserr;
+		}
+	}
+
+	return 0;
+
+phaserr:
+	csw->bCSWStatus = CSW_STAT_PHASE_ERROR;
+	csw->dCSWDataResidue = h;
+	return SCHD_ERR_PHASE;
+}
+
+static int bulk_xfer(struct d12 *p, int dir, const void *buf, int len)
+{
+	int r;
+
+	r = bulk_xfer_chk(p, dir, len);
+	if (!r && len) {
+		if (dir == BULK_IN)
+			ep_bulk_write(p, buf, len);
+		else
+			ep_bulk_read(p, (void *)buf, len);
+	}
+
+	return r;
+}
+
+static void csw_write(struct d12 *p)
+{
+	struct cbw *cbw;
+	struct csw *csw;
+
+	cbw = &p->cbw;
+	csw = &p->csw;
+
+	csw->dCSWDataResidue = cbw->dCBWDataTransferLength - p->bxferptr;
+	if (csw->dCSWDataResidue) {
+		if (cbw->bmCBWFlags & CBW_FLAGS_DIR_IN) {
+			d12_status_set(p, EPX_BULK_I, 1);
+			p->fsm_bulk = FSM_BULK_STALL_TO_CSW;
+			return;
+		} else
+			d12_status_set(p, EPX_BULK_O, 1);
+	}
+	d12_buf_write(p, EPX_BULK_I, &p->csw, sizeof(struct csw));
+	p->fsm_bulk = FSM_BULK_IDLE;
+}
+
+/* --- */
+
+static int lba_chk(struct d12 *p, int lun, __u32 lba, __u32 blks)
+{
+	if (lba >= p->atd_lba_capacity[lun])
+		return 1;
+
+	if (lba + blks > p->atd_lba_capacity[lun])
+		return 1;
+
+	p->scsi_lba = lba;
+	p->scsi_blks = blks;
+
+	return 0;
+}
+
+static void scsi_sense_set(struct d12 *p, int skey, int asc)
+{
+	unsigned char *b;
+
+	b = p->scsi_sense;
+
+	memset (b, 0, MAX_SCSI_DATA_SENSE);
+
+	b[0] = 0x70;				/* current error */
+	b[2] = skey;
+	b[7] = MAX_SCSI_DATA_SENSE - 8;
+	b[12] = (asc >> 8) & 0xFF;
+	b[13] = (asc >> 0) & 0xFF;
+}
+
+static void scsi_sense_lba_set(struct d12 *p, __u32 lba, int asc)
+{
+	unsigned char *b;
+
+	p->csw.bCSWStatus = CSW_STAT_FAILED;
+	scsi_sense_set(p, SCSI_SKEY_MEDIUM_ERROR, asc);
+
+	b = p->scsi_sense;
+
+	b[0] |= 0x80;				/* valid */
+	put_32be(b + 3, lba);			/* information */
+}
+
+static int scsi_cmd_request_sense(struct d12 *p, int lun)
+{
+	int r;
+
+	r = bulk_xfer(p, BULK_IN, p->scsi_sense, MAX_SCSI_DATA_SENSE);
+	scsi_sense_set(p, SCSI_SKEY_NO_SENSE, SCSI_ASC_NO);
+
+	return r;
+}
+
+static int scsi_cmd_test_unit_ready(struct d12 *p, int lun)
+{
+	if (p->atd_stat[lun] & ATD_STAT_READY) {
+		scsi_sense_set(p, SCSI_SKEY_NO_SENSE, SCSI_ASC_NO);
+	} else {
+		p->csw.bCSWStatus = CSW_STAT_FAILED;
+		scsi_sense_set(p, SCSI_SKEY_NOT_READY, SCSI_ASC_LOGICAL_UNIT_NOT_READY);
+	}
+
+	return bulk_xfer(p, BULK_NONE, 0, 0);
+}
+
+static int scsi_cmd_inquiry(struct d12 *p, int lun)
+{
+	unsigned char *b, *t;
+
+	b = p->cbw.CBWCB;
+	t = p->tmp;
+
+	memset(t, 0, MAX_SCSI_DATA_INQUIRY);
+
+	if ((b[1] & 0x03) || b[2])		/* no CmdDT & EVPD support */
+		goto err;
+	else {					/* standard */
+//		t[0] = 0x00;			/* peripheral connected, direct-access device */
+		t[1] = 0x80;			/* RMB = 1 */
+		t[2] = 0x02;
+		t[3] = 0x02;
+		t[4] = MAX_SCSI_DATA_INQUIRY - 5;
+		memcpy(t + 8, p->scsi_str_vendor[lun], 8);
+		memcpy(t + 16, p->scsi_str_product[lun], 16);
+		memcpy(t + 32, p->scsi_str_revision[lun], 4);
+	}
+
+	scsi_sense_set(p, SCSI_SKEY_NO_SENSE, SCSI_ASC_NO);
+
+	return bulk_xfer(p, BULK_IN, t, MAX_SCSI_DATA_INQUIRY);
+
+err:	return SCHD_ERR_INVALID_CDB;
+}
+
+static int scsi_cmd_read_capacity10(struct d12 *p, int lun)
+{
+	unsigned char *b, *t;
+
+	b = p->cbw.CBWCB;
+	t = p->tmp;
+
+	memset(t, 0, MAX_SCSI_DATA_CAPACITY10);
+
+	if ((b[1] & 0x01) || (b[8] & 0x01))	/* RELADR & PMI */
+		goto err;
+
+	put_32be(t + 0, p->atd_lba_capacity[lun] - 1);	/* last LBA */
+	put_32be(t + 4, p->atd_blk[lun]);		/* block size */
+
+	scsi_sense_set(p, SCSI_SKEY_NO_SENSE, SCSI_ASC_NO);
+
+	return bulk_xfer(p, BULK_IN, t, MAX_SCSI_DATA_CAPACITY10);
+
+err:	return SCHD_ERR_INVALID_CDB;
+}
+
+static int scsi_cmd_read_capacity16(struct d12 *p, int lun)
+{
+	unsigned char *b, *t;
+
+	b = p->cbw.CBWCB;
+	t = p->tmp;
+
+	memset(t, 0, MAX_SCSI_DATA_CAPACITY16);
+
+	if (((b[1] & 0x1F) != 0x10) || (b[14] & 0x03))	/* RELADR & PMI */
+		goto err;
+
+	put_64be(t + 0, p->atd_lba_capacity[lun] - 1);	/* last LBA */
+	put_32be(t + 8, p->atd_blk[lun]);		/* block size */
+
+	scsi_sense_set(p, SCSI_SKEY_NO_SENSE, SCSI_ASC_NO);
+
+	return bulk_xfer(p, BULK_IN, t, MAX_SCSI_DATA_CAPACITY16);
+
+err:	return SCHD_ERR_INVALID_CDB;
+}
+
+static void bhd_read(struct d12 *p, int lun, int len)
+{
+	volatile struct dioreq *dio;
+	int blks;
+
+	dio = &p->dio;
+
+	blks = (p->scsi_blks > p->atd_chunkblk[lun]) ? p->atd_chunkblk[lun] : p->scsi_blks;
+
+	if (blks) {
+		dio->cmd = DIO_CMD_READ;
+		dio->lun = lun;
+		dio->lba = p->scsi_lba;
+		dio->blks = blks;
+		dio->buf = p->chunkbuf;
+		up(&p->wait_dio_cmd);
+
+		p->scsi_lba += blks;
+		p->scsi_blks -= blks;
+	}
+}
+
+static int do_read(struct d12 *p, int lun, __u32 lba, __u32 blks)
+{
+	volatile struct dioreq *dio;
+	int r;
+
+	if (lba_chk(p, lun, lba, blks))
+		goto lbaerr;
+
+	scsi_sense_set(p, SCSI_SKEY_NO_SENSE, SCSI_ASC_NO);
+
+	dio = &p->dio;
+
+	r = bulk_xfer_chk(p, BULK_IN, blks * p->atd_blk[lun]);
+	if (!r && blks) {
+		p->bhd = bhd_read;
+
+		if (blks > p->atd_chunkblk[lun])
+			blks = p->atd_chunkblk[lun];
+		dio->cmd = DIO_CMD_READ;
+		dio->lun = lun;
+		dio->lba = lba;
+		dio->blks = blks;
+		dio->buf = p->chunkbuf;
+		up(&p->wait_dio_cmd);
+
+		p->scsi_lba += blks;
+		p->scsi_blks -= blks;
+	}
+
+	return r;
+
+lbaerr:	return SCHD_ERR_INVALID_LBA;
+}
+
+static int scsi_cmd_read6(struct d12 *p, int lun)
+{
+	unsigned char *b;
+	__u32 lba, blks;
+
+	b = p->cbw.CBWCB;
+
+	lba = get_u32be(b + 0) & 0x001FFFFF;
+	blks = b[4];
+	if (!blks)
+		blks = 256;
+
+	return do_read(p, lun, lba, blks);
+}
+
+static int scsi_cmd_read10(struct d12 *p, int lun)
+{
+	unsigned char *b;
+	__u32 lba, blks;
+
+	b = p->cbw.CBWCB;
+
+	if (b[1] & 0x01)			/* RELADR */
+		goto err;
+
+	lba = get_u32be(b + 2);
+	blks = get_u16be(b + 7);
+
+	return do_read(p, lun, lba, blks);
+
+err:	return SCHD_ERR_INVALID_CDB;
+}
+
+static int scsi_cmd_read12(struct d12 *p, int lun)
+{
+	unsigned char *b;
+	__u32 lba, blks;
+
+	b = p->cbw.CBWCB;
+
+	if (b[1] & 0x01)			/* RELADR */
+		goto err;
+
+	lba = get_u32be(b + 2);
+	blks = get_u32be(b + 6);
+
+	return do_read(p, lun, lba, blks);
+
+err:	return SCHD_ERR_INVALID_CDB;
+}
+
+static int scsi_cmd_read16(struct d12 *p, int lun)
+{
+	unsigned char *b;
+	__u32 lba, blks;
+
+	b = p->cbw.CBWCB;
+
+	if (b[1] & 0x01)			/* RELADR */
+		goto err;
+
+	lba = get_u64be(b + 2);
+	blks = get_u32be(b + 10);
+
+	return do_read(p, lun, lba, blks);
+
+err:	return SCHD_ERR_INVALID_CDB;
+}
+
+static void bhd_write(struct d12 *p, int lun, int len)
+{
+	volatile struct dioreq *dio;
+	int blks;
+
+	dio = &p->dio;
+
+	blks = len / p->atd_blk[lun];
+
+	if (blks) {
+		p->scsi_lba += blks;
+		p->scsi_blks -= blks;
+
+		dio->cmd = DIO_CMD_WRITE;
+		dio->lun = lun;
+		dio->lba = p->scsi_lba - blks;
+		dio->blks = blks;
+		dio->nblks = p->scsi_blks;
+		dio->buf = p->chunkbuf;
+		up(&p->wait_dio_cmd);
+	}
+}
+
+static int do_write(struct d12 *p, int lun, __u32 lba, __u32 blks)
+{
+	int r;
+
+	if (lba_chk(p, lun, lba, blks))
+		goto lbaerr;
+
+	scsi_sense_set(p, SCSI_SKEY_NO_SENSE, SCSI_ASC_NO);
+
+	r = bulk_xfer_chk(p, BULK_OUT, blks * p->atd_blk[lun]);
+	if (!r && blks) {
+		p->bhd = bhd_write;
+
+		ep_bulk_read(p, p->chunkbuf, blks * p->atd_blk[lun]);
+	}
+
+	return r;
+
+lbaerr:	return SCHD_ERR_INVALID_LBA;
+}
+
+static int scsi_cmd_write6(struct d12 *p, int lun)
+{
+	unsigned char *b;
+	__u32 lba, blks;
+
+	b = p->cbw.CBWCB;
+
+	lba = get_u32be(b + 0) & 0x001FFFFF;
+	blks = b[4];
+	if (!blks)
+		blks = 256;
+
+	return do_write(p, lun, lba, blks);
+}
+
+static int scsi_cmd_write10(struct d12 *p, int lun)
+{
+	unsigned char *b;
+	__u32 lba, blks;
+
+	b = p->cbw.CBWCB;
+
+	if (b[1] & 0x01)			/* RELADR */
+		goto err;
+
+	lba = get_u32be(b + 2);
+	blks = get_u16be(b + 7);
+
+	return do_write(p, lun, lba, blks);
+
+err:	return SCHD_ERR_INVALID_CDB;
+}
+
+static int scsi_cmd_write12(struct d12 *p, int lun)
+{
+	unsigned char *b;
+	__u32 lba, blks;
+
+	b = p->cbw.CBWCB;
+
+	if (b[1] & 0x01)			/* RELADR */
+		goto err;
+
+	lba = get_u32be(b + 2);
+	blks = get_u32be(b + 6);
+
+	return do_write(p, lun, lba, blks);
+
+err:	return SCHD_ERR_INVALID_CDB;
+}
+
+static int scsi_cmd_write16(struct d12 *p, int lun)
+{
+	unsigned char *b;
+	__u32 lba, blks;
+
+	b = p->cbw.CBWCB;
+
+	if (b[1] & 0x01)			/* RELADR */
+		goto err;
+
+	lba = get_u64be(b + 2);
+	blks = get_u32be(b + 10);
+
+	return do_write(p, lun, lba, blks);
+
+err:	return SCHD_ERR_INVALID_CDB;
+}
+
+static int do_verify(struct d12 *p, int lun, __u32 lba, __u32 blks)
+{
+	volatile struct dioreq *dio;
+	int r;
+
+	if (lba_chk(p, lun, lba, blks))
+		goto lbaerr;
+
+	scsi_sense_set(p, SCSI_SKEY_NO_SENSE, SCSI_ASC_NO);
+
+	dio = &p->dio;
+
+	r = bulk_xfer_chk(p, BULK_NONE, 0);
+	if (!r && blks) {
+		p->cswdelay = 1;
+
+		dio->cmd = DIO_CMD_VERIFY;
+		dio->lun = lun;
+		dio->lba = lba;
+		dio->blks = blks;
+		up(&p->wait_dio_cmd);
+	}
+
+	return r;
+
+lbaerr:	return SCHD_ERR_INVALID_LBA;
+}
+
+static int scsi_cmd_verify10(struct d12 *p, int lun)
+{
+	unsigned char *b;
+	__u32 lba, blks;
+
+	b = p->cbw.CBWCB;
+
+	if (b[1] & 0x07)			/* BLKVFY, BYTCHK & RELADR */
+		goto err;
+
+	lba = get_u32be(b + 2);
+	blks = get_u16be(b + 7);
+
+	return do_verify(p, lun, lba, blks);
+
+err:	return SCHD_ERR_INVALID_CDB;
+}
+
+static int scsi_cmd_verify12(struct d12 *p, int lun)
+{
+	unsigned char *b;
+	__u32 lba, blks;
+
+	b = p->cbw.CBWCB;
+
+	if (b[1] & 0x07)			/* BLKVFY, BYTCHK & RELADR */
+		goto err;
+
+	lba = get_u32be(b + 2);
+	blks = get_u32be(b + 6);
+
+	return do_verify(p, lun, lba, blks);
+
+err:	return SCHD_ERR_INVALID_CDB;
+}
+
+static int scsi_cmd_verify16(struct d12 *p, int lun)
+{
+	unsigned char *b;
+	__u32 lba, blks;
+
+	b = p->cbw.CBWCB;
+
+	if (b[1] & 0x07)			/* BLKVFY, BYTCHK & RELADR */
+		goto err;
+
+	lba = get_u64be(b + 2);
+	blks = get_u32be(b + 10);
+
+	return do_verify(p, lun, lba, blks);
+
+err:	return SCHD_ERR_INVALID_CDB;
+}
+
+/* --- */
+
+struct scsi_cmd_hd {
+	int len;
+	int (*hd)(struct d12 *, int);
+};
+
+static const struct scsi_cmd_hd T_SCSI_HD[256] = {
+	{6,	scsi_cmd_test_unit_ready},	/* 0x00 */
+	{0,	0},				/* 0x01 */
+	{0,	0},				/* 0x02 */
+	{0,	scsi_cmd_request_sense},	/* 0x03 */
+	{0,	0},				/* 0x04 */
+	{0,	0},				/* 0x05 */
+	{0,	0},				/* 0x06 */
+	{0,	0},				/* 0x07 */
+	{6,	scsi_cmd_read6},		/* 0x08 */
+	{0,	0},				/* 0x09 */
+	{6,	scsi_cmd_write6},		/* 0x0A */
+	{0,	0},				/* 0x0B */
+	{0,	0},				/* 0x0C */
+	{0,	0},				/* 0x0D */
+	{0,	0},				/* 0x0E */
+	{0,	0},				/* 0x0F */
+	{0,	0},				/* 0x10 */
+	{0,	0},				/* 0x11 */
+	{6,	scsi_cmd_inquiry},		/* 0x12 */
+	{0,	0},				/* 0x13 */
+	{0,	0},				/* 0x14 */
+	{0,	0},				/* 0x15 */
+	{0,	0},				/* 0x16 */
+	{0,	0},				/* 0x17 */
+	{0,	0},				/* 0x18 */
+	{0,	0},				/* 0x19 */
+	{0,	0},				/* 0x1A */
+	{0,	0},				/* 0x1B */
+	{0,	0},				/* 0x1C */
+	{0,	0},				/* 0x1D */
+	{0,	0},				/* 0x1E */
+	{0,	0},				/* 0x1F */
+	{0,	0},				/* 0x20 */
+	{0,	0},				/* 0x21 */
+	{0,	0},				/* 0x22 */
+	{0,	0},				/* 0x23 */
+	{0,	0},				/* 0x24 */
+	{10,	scsi_cmd_read_capacity10},	/* 0x25 */
+	{0,	0},				/* 0x26 */
+	{0,	0},				/* 0x27 */
+	{10,	scsi_cmd_read10},		/* 0x28 */
+	{0,	0},				/* 0x29 */
+	{10,	scsi_cmd_write10},		/* 0x2A */
+	{0,	0},				/* 0x2B */
+	{0,	0},				/* 0x2C */
+	{0,	0},				/* 0x2D */
+	{0,	0},				/* 0x2E */
+	{10,	scsi_cmd_verify10},		/* 0x2F */
+	{0,	0},				/* 0x30 */
+	{0,	0},				/* 0x31 */
+	{0,	0},				/* 0x32 */
+	{0,	0},				/* 0x33 */
+	{0,	0},				/* 0x34 */
+	{0,	0},				/* 0x35 */
+	{0,	0},				/* 0x36 */
+	{0,	0},				/* 0x37 */
+	{0,	0},				/* 0x38 */
+	{0,	0},				/* 0x39 */
+	{0,	0},				/* 0x3A */
+	{0,	0},				/* 0x3B */
+	{0,	0},				/* 0x3C */
+	{0,	0},				/* 0x3D */
+	{0,	0},				/* 0x3E */
+	{0,	0},				/* 0x3F */
+	{0,	0},				/* 0x40 */
+	{0,	0},				/* 0x41 */
+	{0,	0},				/* 0x42 */
+	{0,	0},				/* 0x43 */
+	{0,	0},				/* 0x44 */
+	{0,	0},				/* 0x45 */
+	{0,	0},				/* 0x46 */
+	{0,	0},				/* 0x47 */
+	{0,	0},				/* 0x48 */
+	{0,	0},				/* 0x49 */
+	{0,	0},				/* 0x4A */
+	{0,	0},				/* 0x4B */
+	{0,	0},				/* 0x4C */
+	{0,	0},				/* 0x4D */
+	{0,	0},				/* 0x4E */
+	{0,	0},				/* 0x4F */
+	{0,	0},				/* 0x50 */
+	{0,	0},				/* 0x51 */
+	{0,	0},				/* 0x52 */
+	{0,	0},				/* 0x53 */
+	{0,	0},				/* 0x54 */
+	{0,	0},				/* 0x55 */
+	{0,	0},				/* 0x56 */
+	{0,	0},				/* 0x57 */
+	{0,	0},				/* 0x58 */
+	{0,	0},				/* 0x59 */
+	{0,	0},				/* 0x5A */
+	{0,	0},				/* 0x5B */
+	{0,	0},				/* 0x5C */
+	{0,	0},				/* 0x5D */
+	{0,	0},				/* 0x5E */
+	{0,	0},				/* 0x5F */
+	{0,	0},				/* 0x60 */
+	{0,	0},				/* 0x61 */
+	{0,	0},				/* 0x62 */
+	{0,	0},				/* 0x63 */
+	{0,	0},				/* 0x64 */
+	{0,	0},				/* 0x65 */
+	{0,	0},				/* 0x66 */
+	{0,	0},				/* 0x67 */
+	{0,	0},				/* 0x68 */
+	{0,	0},				/* 0x69 */
+	{0,	0},				/* 0x6A */
+	{0,	0},				/* 0x6B */
+	{0,	0},				/* 0x6C */
+	{0,	0},				/* 0x6D */
+	{0,	0},				/* 0x6E */
+	{0,	0},				/* 0x6F */
+	{0,	0},				/* 0x70 */
+	{0,	0},				/* 0x71 */
+	{0,	0},				/* 0x72 */
+	{0,	0},				/* 0x73 */
+	{0,	0},				/* 0x74 */
+	{0,	0},				/* 0x75 */
+	{0,	0},				/* 0x76 */
+	{0,	0},				/* 0x77 */
+	{0,	0},				/* 0x78 */
+	{0,	0},				/* 0x79 */
+	{0,	0},				/* 0x7A */
+	{0,	0},				/* 0x7B */
+	{0,	0},				/* 0x7C */
+	{0,	0},				/* 0x7D */
+	{0,	0},				/* 0x7E */
+	{0,	0},				/* 0x7F */
+	{0,	0},				/* 0x80 */
+	{0,	0},				/* 0x81 */
+	{0,	0},				/* 0x82 */
+	{0,	0},				/* 0x83 */
+	{0,	0},				/* 0x84 */
+	{0,	0},				/* 0x85 */
+	{0,	0},				/* 0x86 */
+	{0,	0},				/* 0x87 */
+	{16,	scsi_cmd_read16},		/* 0x88 */
+	{0,	0},				/* 0x89 */
+	{16,	scsi_cmd_write16},		/* 0x8A */
+	{0,	0},				/* 0x8B */
+	{0,	0},				/* 0x8C */
+	{0,	0},				/* 0x8D */
+	{0,	0},				/* 0x8E */
+	{16,	scsi_cmd_verify16},		/* 0x8F */
+	{0,	0},				/* 0x90 */
+	{0,	0},				/* 0x91 */
+	{0,	0},				/* 0x92 */
+	{0,	0},				/* 0x93 */
+	{0,	0},				/* 0x94 */
+	{0,	0},				/* 0x95 */
+	{0,	0},				/* 0x96 */
+	{0,	0},				/* 0x97 */
+	{0,	0},				/* 0x98 */
+	{0,	0},				/* 0x99 */
+	{0,	0},				/* 0x9A */
+	{0,	0},				/* 0x9B */
+	{0,	0},				/* 0x9C */
+	{0,	0},				/* 0x9D */
+	{16,	scsi_cmd_read_capacity16},	/* 0x9E */
+	{0,	0},				/* 0x9F */
+	{0,	0},				/* 0xA0 */
+	{0,	0},				/* 0xA1 */
+	{0,	0},				/* 0xA2 */
+	{0,	0},				/* 0xA3 */
+	{0,	0},				/* 0xA4 */
+	{0,	0},				/* 0xA5 */
+	{0,	0},				/* 0xA6 */
+	{0,	0},				/* 0xA7 */
+	{12,	scsi_cmd_read12},		/* 0xA8 */
+	{0,	0},				/* 0xA9 */
+	{12,	scsi_cmd_write12},		/* 0xAA */
+	{0,	0},				/* 0xAB */
+	{0,	0},				/* 0xAC */
+	{0,	0},				/* 0xAD */
+	{0,	0},				/* 0xAE */
+	{12,	scsi_cmd_verify12},		/* 0xAF */
+	{0,	0},				/* 0xB0 */
+	{0,	0},				/* 0xB1 */
+	{0,	0},				/* 0xB2 */
+	{0,	0},				/* 0xB3 */
+	{0,	0},				/* 0xB4 */
+	{0,	0},				/* 0xB5 */
+	{0,	0},				/* 0xB6 */
+	{0,	0},				/* 0xB7 */
+	{0,	0},				/* 0xB8 */
+	{0,	0},				/* 0xB9 */
+	{0,	0},				/* 0xBA */
+	{0,	0},				/* 0xBB */
+	{0,	0},				/* 0xBC */
+	{0,	0},				/* 0xBD */
+	{0,	0},				/* 0xBE */
+	{0,	0},				/* 0xBF */
+	{0,	0},				/* 0xC0 */
+	{0,	0},				/* 0xC1 */
+	{0,	0},				/* 0xC2 */
+	{0,	0},				/* 0xC3 */
+	{0,	0},				/* 0xC4 */
+	{0,	0},				/* 0xC5 */
+	{0,	0},				/* 0xC6 */
+	{0,	0},				/* 0xC7 */
+	{0,	0},				/* 0xC8 */
+	{0,	0},				/* 0xC9 */
+	{0,	0},				/* 0xCA */
+	{0,	0},				/* 0xCB */
+	{0,	0},				/* 0xCC */
+	{0,	0},				/* 0xCD */
+	{0,	0},				/* 0xCE */
+	{0,	0},				/* 0xCF */
+	{0,	0},				/* 0xD0 */
+	{0,	0},				/* 0xD1 */
+	{0,	0},				/* 0xD2 */
+	{0,	0},				/* 0xD3 */
+	{0,	0},				/* 0xD4 */
+	{0,	0},				/* 0xD5 */
+	{0,	0},				/* 0xD6 */
+	{0,	0},				/* 0xD7 */
+	{0,	0},				/* 0xD8 */
+	{0,	0},				/* 0xD9 */
+	{0,	0},				/* 0xDA */
+	{0,	0},				/* 0xDB */
+	{0,	0},				/* 0xDC */
+	{0,	0},				/* 0xDD */
+	{0,	0},				/* 0xDE */
+	{0,	0},				/* 0xDF */
+	{0,	0},				/* 0xE0 */
+	{0,	0},				/* 0xE1 */
+	{0,	0},				/* 0xE2 */
+	{0,	0},				/* 0xE3 */
+	{0,	0},				/* 0xE4 */
+	{0,	0},				/* 0xE5 */
+	{0,	0},				/* 0xE6 */
+	{0,	0},				/* 0xE7 */
+	{0,	0},				/* 0xE8 */
+	{0,	0},				/* 0xE9 */
+	{0,	0},				/* 0xEA */
+	{0,	0},				/* 0xEB */
+	{0,	0},				/* 0xEC */
+	{0,	0},				/* 0xED */
+	{0,	0},				/* 0xEE */
+	{0,	0},				/* 0xEF */
+	{0,	0},				/* 0xF0 */
+	{0,	0},				/* 0xF1 */
+	{0,	0},				/* 0xF2 */
+	{0,	0},				/* 0xF3 */
+	{0,	0},				/* 0xF4 */
+	{0,	0},				/* 0xF5 */
+	{0,	0},				/* 0xF6 */
+	{0,	0},				/* 0xF7 */
+	{0,	0},				/* 0xF8 */
+	{0,	0},				/* 0xF9 */
+	{0,	0},				/* 0xFA */
+	{0,	0},				/* 0xFB */
+	{0,	0},				/* 0xFC */
+	{0,	0},				/* 0xFD */
+	{0,	0},				/* 0xFE */
+	{0,	0}				/* 0xFF */
+};
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * interrupt handler and supporting functions
+ */
+
+static void ep0_rx(struct d12 *p)
+{
+	struct devreq *drq;
+	int stat, len, req;
+
+	stat = d12_read_last_trans(p, EPX_CTRL_O);
+
+	if (!(stat & D_READ_LTRNS_SUCCESS))
+		return;
+
+	if (p->fsm_dev < FSM_DEV_DEFAULT)
+		goto err;
+
+	drq = &p->drq;
+
+	if (stat & D_READ_LTRNS_SETUP) {	/* new transfer */
+		len = d12_buf_read(p, EPX_CTRL_O, drq, sizeof(struct devreq));
+		if (len != sizeof(struct devreq))
+			goto err;
+
+		d12_acknowledge_setup(p);
+		d12_select_endpoint(p, EPX_CTRL_O);
+		d12_buf_clear(p);
+
+		req = drq->bRequest;
+
+		switch (drq->bmRequestType & REQTYPE_TYPE_M) {
+		case REQTYPE_TYPE_STANDARD:
+			if (req >= MAX_REQ_STANDARD)
+				goto err;
+			if ((T_STD_SETUP[req])(p))
+				goto err;
+			break;
+
+		case REQTYPE_TYPE_CLASS:
+			if (p->fsm_dev != FSM_DEV_CONFIGURED)
+				goto err;
+
+			req = 255 - req;
+			if (req >= MAX_REQ_CLASS)
+				goto err;
+			if ((T_CLS_SETUP[req])(p))
+				goto err;
+			break;
+
+		default:
+			goto err;
+		}
+	} else {				/* host -> d12 data */
+		switch (p->fsm_ctl) {
+		case FSM_CTL_STATUS_OUT:
+			d12_stall_ctrl(p, 1);
+			p->fsm_ctl = FSM_CTL_IDLE;
+			break;
+
+		default:
+			goto err;
+		}
+	}
+
+	return;
+
+err:	d12_stall_ctrl(p, 1);			/* stall EP0 */
+	p->fsm_ctl = FSM_CTL_IDLE;
+}
+
+static void ep0_tx(struct d12 *p)
+{
+	struct devreq *drq;
+	int stat, len;
+
+	stat = d12_read_last_trans(p, EPX_CTRL_I);
+
+	if (!(stat & D_READ_LTRNS_SUCCESS))
+		return;
+
+	if (p->fsm_dev < FSM_DEV_DEFAULT)
+		goto err;
+
+	drq = &p->drq;
+
+	switch (p->fsm_ctl) {
+	case FSM_CTL_DATA_IN:
+		len = p->dlen - p->dptr;
+		if (len > EP_CTRL_SIZE)
+			len = EP_CTRL_SIZE;
+
+		d12_buf_write(p, EPX_CTRL_I, p->dbuf + p->dptr, len);
+		p->dptr += len;
+
+		if (p->dptr == p->dlen)
+			p->fsm_ctl = FSM_CTL_STATUS_OUT;
+		p->fsm_ctl_lastpkt = len;
+		break;
+
+	case FSM_CTL_STATUS_OUT:
+		if (p->fsm_ctl_lastpkt == EP_CTRL_SIZE) {
+			d12_buf_write(p, EPX_CTRL_I, 0, 0);
+			p->fsm_ctl_lastpkt = 0;
+		}
+		break;
+
+	case FSM_CTL_STATUS_IN:
+		d12_stall_ctrl(p, 1);
+		p->fsm_ctl = FSM_CTL_IDLE;
+		break;
+
+	default:
+		goto err;
+	}
+
+	return;
+
+err:	d12_stall_ctrl(p, 1);			/* stall EP0 */
+	p->fsm_ctl = FSM_CTL_IDLE;
+}
+
+static void ep1_rx(struct d12 *p)		/* free endpoint */
+{
+	d12_read_last_trans(p, EPX_FREE_O);
+	d12_stall_free(p, 1);			/* stall EP1 */
+}
+
+static void ep1_tx(struct d12 *p)		/* free endpoint */
+{
+	d12_read_last_trans(p, EPX_FREE_I);
+	d12_stall_free(p, 1);			/* stall EP1 */
+}
+
+static void ep2_rx(struct d12 *p)
+{
+	struct cbw *cbw;
+	struct csw *csw;
+	int stat, len, lun, clen, cmd, r;
+
+	stat = d12_read_last_trans(p, EPX_BULK_O);
+
+	if (!(stat & D_READ_LTRNS_SUCCESS))
+		return;
+
+	if (p->fsm_dev != FSM_DEV_CONFIGURED)
+		goto err;
+
+	cbw = &p->cbw;
+	csw = &p->csw;
+
+	switch (p->fsm_bulk) {
+	case FSM_BULK_IDLE:
+		len = d12_buf_read(p, EPX_BULK_O, cbw, sizeof(struct cbw));
+		if (len != sizeof(struct cbw))
+			goto err;
+
+		lun = cbw->bCBWLUN;
+		clen = cbw->bCBWCBLength;
+		cmd = cbw->CBWCB[0];
+
+		if ((cbw->dCBWSignature != CBW_SIGNATURE) || !clen || (clen > sizeof(cbw->CBWCB)))
+			goto err;
+
+		p->bhd = 0;
+		p->bxferlen = p->bxferptr = 0;
+		p->cswdelay = p->cswearly = 0;
+
+		csw->dCSWSignature = CSW_SIGNATURE;
+		csw->dCSWTag = cbw->dCBWTag;
+		csw->dCSWDataResidue = 0;
+		csw->bCSWStatus = CSW_STAT_OK;
+
+		if (lun >= p->max_lun) {
+			csw->bCSWStatus = CSW_STAT_FAILED;
+			scsi_sense_set(p, SCSI_SKEY_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED);
+			bulk_xfer(p, BULK_NONE, 0, 0);
+		} else if ((!T_SCSI_HD[cmd].len || (T_SCSI_HD[cmd].len == clen)) && T_SCSI_HD[cmd].hd) {
+			r = T_SCSI_HD[cmd].hd(p, lun);
+			if (r && (r != SCHD_ERR_PHASE)) {
+				csw->bCSWStatus = CSW_STAT_FAILED;
+				if (r == SCHD_ERR_INVALID_CDB)
+					scsi_sense_set(p, SCSI_SKEY_ILLEGAL_REQUEST, SCSI_ASC_INVALID_FIELD_IN_CDB);
+				else if (r == SCHD_ERR_INVALID_LBA)
+					scsi_sense_set(p, SCSI_SKEY_ILLEGAL_REQUEST, SCSI_ASC_LBA_OUT_OF_RANGE);
+				bulk_xfer(p, BULK_NONE, 0, 0);
+			}
+		} else {
+			csw->bCSWStatus = CSW_STAT_FAILED;
+			scsi_sense_set(p, SCSI_SKEY_ILLEGAL_REQUEST, SCSI_ASC_INVALID_CMD);
+			bulk_xfer(p, BULK_NONE, 0, 0);
+		}
+
+		if (!p->bxferlen && !p->cswdelay)
+			csw_write(p);
+		break;
+
+	case FSM_BULK_DATA_OUT:
+		len = p->blen - p->bptr;
+		len = d12_buf_read(p, EPX_BULK_O, p->bbuf + p->bptr, len);
+		p->bptr += len;
+		p->bxferptr += len;
+		if (p->bptr == p->blen) {
+			lun = cbw->bCBWLUN;
+			if (p->bhd)
+				p->bhd(p, lun, p->blen);
+			p->fsm_bulk = FSM_BULK_DATA_OUT_WAIT;
+		}
+		break;
+
+	case FSM_BULK_DATA_OUT_WAIT:
+		break;
+
+	default:
+		goto err;
+	}
+
+	return;
+
+err:	d12_stall_bulk(p, 1);			/* stall EP2 */
+	p->fsm_bulk = FSM_BULK_IDLE;
+}
+
+static void ep2_tx(struct d12 *p)
+{
+	struct cbw *cbw;
+	int stat, len, lun;
+
+	stat = d12_read_last_trans(p, EPX_BULK_I);
+
+	if (!(stat & D_READ_LTRNS_SUCCESS))
+		return;
+
+	if (p->fsm_dev != FSM_DEV_CONFIGURED)
+		goto err;
+
+	cbw = &p->cbw;
+
+	switch (p->fsm_bulk) {
+	case FSM_BULK_IDLE:			/* CSW ack */
+		break;
+
+	case FSM_BULK_DATA_IN:
+		len = p->blen - p->bptr;
+		if (len) {
+			len = d12_buf_write(p, EPX_BULK_I, p->bbuf + p->bptr, len);
+			p->bptr += len;
+			p->bxferptr += len;
+		} else {
+			stat = d12_status_get(p, EPX_BULK_I);
+			stat &= D_READ_ENDP_STAT_BUF0 | D_READ_ENDP_STAT_BUF1;
+			if (!stat) {
+				if ((p->bxferptr == p->bxferlen) || p->cswearly)
+					csw_write(p);
+				else {
+					p->fsm_bulk = FSM_BULK_DATA_IN_WAIT;
+					lun = cbw->bCBWLUN;
+					if (p->bhd)
+						p->bhd(p, lun, p->blen);
+				}
+			}
+		}
+		break;
+
+	default:
+		goto err;
+	}
+
+	return;
+
+err:	d12_stall_bulk(p, 1);			/* stall EP2 */
+	p->fsm_bulk = FSM_BULK_IDLE;
+}
+
+static void usbd12_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct d12 *p;
+	int ints;
+
+	p = (struct d12 *)dev_id;
+
+	ints = d12_in2(p, CMD_READ_INT);
+
+	if (ints & D_READ_INT_BUSRESET) {
+		d12_reset(p);
+		p->feat_wakeup = 0;
+		p->fsm_dev = FSM_DEV_DEFAULT;
+		p->fsm_ctl = FSM_CTL_IDLE;
+	}
+
+	if (ints & D_READ_INT_SUSPENDCHG)
+		p->suspend = GPIO_D12_SUSP;
+
+	if (ints & D_READ_INT_EP0_I)		/* host <- d12 ack, control */
+		ep0_tx(p);
+
+	if (ints & D_READ_INT_EP0_O)		/* host -> d12, control */
+		ep0_rx(p);
+
+	if (ints & D_READ_INT_EP1_I)		/* host <- d12 ack, bulk */
+		ep1_tx(p);
+
+	if (ints & D_READ_INT_EP1_O)		/* host -> d12, bulk */
+		ep1_rx(p);
+
+	if (ints & D_READ_INT_EP2_I)		/* host <- d12 ack, bulk */
+		ep2_tx(p);
+
+	if (ints & D_READ_INT_EP2_O)		/* host -> d12, bulk */
+		ep2_rx(p);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * device I/O thread
+ */
+
+static int dio_thread(void *arg)
+{
+	struct d12 *p;
+	volatile struct dioreq *dio;
+	int cmd, lun;
+	__u32 lba, blks, nblks, i;
+	unsigned char *buf;
+	struct buffer_head *bh;
+
+	p = (struct d12 *)arg;
+	dio = &p->dio;
+
+	daemonize();
+	reparent_to_init();
+	strcpy(current->comm, "kusbd12");
+	current->nice = -20;
+#if 0
+	spin_lock_irq(&current->sigmask_lock);
+	sigemptyset(&current->blocked);
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+#endif
+
+	complete(&p->cpl_dio_sync);		/* initialized */
+
+	for ( ; ; ) {
+		down(&p->wait_dio_cmd);
+#if 0
+		if (signal_pending(current)) {
+			spin_lock_irq(&current->sigmask_lock);
+			flush_signals(current);
+			spin_unlock_irq(&current->sigmask_lock);
+		}
+#endif
+		d12_lock(p);
+		cmd = dio->cmd;
+		lun = dio->lun;
+		lba = dio->lba;
+		blks = dio->blks;
+		nblks = dio->nblks;
+		buf = (unsigned char *)dio->buf;
+		d12_unlock(p);
+
+		if (cmd == DIO_CMD_EXIT)
+			break;
+
+		switch (cmd) {
+		case DIO_CMD_READ:
+			for (i = 0 ; i < blks ; i++) {
+				bh = bread(p->atd_dev[lun], lba, p->atd_blk[lun]);
+				if (!bh)
+					break;
+				memcpy(buf + i * p->atd_blk[lun], bh->b_data, p->atd_blk[lun]);
+				brelse(bh);
+				lba++;
+			}
+			
+			d12_lock(p);
+			ep_bulk_write(p, buf, i * p->atd_blk[lun]);
+			if (i != blks) {
+				scsi_sense_lba_set(p, lba, SCSI_ASC_UNRECOVERED_READ_ERROR);
+				p->cswearly = 1;
+			}
+			d12_unlock(p);
+			break;
+
+		case DIO_CMD_WRITE:
+			for (i = 0 ; i < blks ; i++) {
+				bh = getblk(p->atd_dev[lun], lba, p->atd_blk[lun]);
+				if (!bh)
+					break;
+				memcpy(bh->b_data, buf + i * p->atd_blk[lun], p->atd_blk[lun]);
+				mark_buffer_uptodate(bh, 1);
+				mark_buffer_dirty(bh);
+				ll_rw_block(WRITE, 1, &bh);
+				wait_on_buffer(bh);
+				brelse(bh);
+				lba++;
+			}
+
+			d12_lock(p);
+			if (i != blks) {
+				scsi_sense_lba_set(p, lba, SCSI_ASC_WRITE_ERROR);
+				csw_write(p);
+			} else if (nblks)
+				ep_bulk_read(p, buf, nblks * p->atd_blk[lun]);
+			else
+				csw_write(p);
+			d12_unlock(p);
+			break;
+
+		case DIO_CMD_VERIFY:
+			for (i = 0 ; i < blks ; i++) {
+				bh = bread(p->atd_dev[lun], lba, p->atd_blk[lun]);
+				if (!bh)
+					goto vfyerr;
+				brelse(bh);
+				lba++;
+			}
+
+vfyerr:			d12_lock(p);
+			if (i != blks)
+				scsi_sense_lba_set(p, lba, SCSI_ASC_UNRECOVERED_READ_ERROR);
+			csw_write(p);
+			d12_unlock(p);
+			break;
+		}
+	}
+
+	complete_and_exit(&p->cpl_dio_sync, 0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#define w(x) ((x) & 0xFF), (((x) >> 8) & 0xFF)
+#define u(x) (x), 0
+
+#define MAX_DESC_STR		6
+
+#define STR_MANUFACTURER	1
+#define STR_PRODUCT		2
+#define STR_SERIALNUM		3
+#define STR_CONFIG		4
+#define STR_INTERFACE		5
+
+static const unsigned char T_DESC_STR_0[] = {
+	4,				/* bLength */
+	DESC_TYPE_STRING,		/* bDescriptorType */
+	w(DEF_LANG)			/* (english, US) */
+};
+
+static const unsigned char T_DESC_STR_1[] = {
+	26,				/* bLength */
+	DESC_TYPE_STRING,		/* bDescriptorType */
+	u('C'),				/* (manufacturer) */
+	u('i'),
+	u('r'),
+	u('r'),
+	u('u'),
+	u('s'),
+	u(' '),
+	u('L'),
+	u('o'),
+	u('g'),
+	u('i'),
+	u('c')
+};
+
+static const unsigned char T_DESC_STR_2[] = {
+	16,				/* bLength */
+	DESC_TYPE_STRING,		/* bDescriptorType */
+	u('e'),				/* (product) */
+	u('d'),
+	u('b'),
+	u('7'),
+	u('3'),
+	u('1'),
+	u('2')
+};
+
+static const unsigned char T_DESC_STR_3[] = {
+	26,				/* bLength */
+	DESC_TYPE_STRING,		/* bDescriptorType */
+	u('0'),				/* (serial number) */
+	u('0'),
+	u('0'),
+	u('0'),
+	u('0'),
+	u('0'),
+ 	u('0'),
+	u('0'),
+	u('0'),
+	u('0'),
+	u('0'),
+	u('0')
+};
+
+static const unsigned char T_DESC_STR_4[] = {
+	10,				/* bLength */
+	DESC_TYPE_STRING,		/* bDescriptorType */
+	u('c'),				/* (configuration) */
+	u('f'),
+	u('g'),
+	u('0')
+};
+
+static const unsigned char T_DESC_STR_5[] = {
+	8,				/* bLength */
+	DESC_TYPE_STRING,		/* bDescriptorType */
+	u('i'),				/* (interface) */
+	u('f'),
+	u('0')
+};
+
+static const void * const T_DESC_STR[MAX_DESC_STR] = {
+	T_DESC_STR_0,
+	T_DESC_STR_1,
+	T_DESC_STR_2,
+	T_DESC_STR_3,
+	T_DESC_STR_4,
+	T_DESC_STR_5
+};
+
+static const int T_DESC_STR_LEN[MAX_DESC_STR] = {
+	sizeof(T_DESC_STR_0),
+	sizeof(T_DESC_STR_1),
+	sizeof(T_DESC_STR_2),
+	sizeof(T_DESC_STR_3),
+	sizeof(T_DESC_STR_4),
+	sizeof(T_DESC_STR_5)
+};
+
+static const unsigned char T_DESC_DEV[] = {
+	/* --- device descriptor --- */
+
+	18,				/* bLength */
+	DESC_TYPE_DEVICE,		/* bDescriptorType */
+	0x01, 0x01,			/* bcdUSB */
+	0,				/* bDeviceClass */
+	0,				/* bDeviceSubClass */
+	0,				/* bDeviceProtocol */
+	EP_CTRL_SIZE,			/* bMaxPacketSize0 */
+	0xDB, 0xCE,			/* idVendor */
+	0x12, 0x73,			/* idProduct */
+	0x00, 0x01,			/* bcdDevice */
+	STR_MANUFACTURER,		/* iManufacturer */
+	STR_PRODUCT,			/* iProduct */
+	STR_SERIALNUM,			/* iSerialNumber */
+	1				/* bNumConfigurations */
+};
+
+static const unsigned char T_DESC_CFG[] = {
+	/* --- configuration descriptor --- */
+
+	9,				/* bLength */
+	DESC_TYPE_CONFIGURATION,	/* bDescriptorType */
+	w(9 + 9 + 7 + 7),		/* wTotalLength */
+	1,				/* bNumInterfaces */
+	CONFIG_VAL,			/* bConfigurationValue */
+	STR_CONFIG,			/* iConfiguration */
+	0xE0,				/* bmAttributes */
+	0,				/* MaxPower (0 mA) */
+
+	/* --- interface descriptor --- */
+
+	9,				/* bLength */
+	DESC_TYPE_INTERFACE,		/* bDescriptorType */
+	0,				/* bInterfaceNumber */
+	0,				/* bAlternateSetting */
+	2,				/* bNumEndpoints */
+	CLASS_MASS_STORAGE,		/* bInterfaceClass (mass-storage) */
+	SUBCLASS_SCSI,			/* bInterfaceSubClass (scsi) */
+	PROTOCOL_BULK,			/* bInterfaceProtocol (bulk) */
+	STR_INTERFACE,			/* iInterface */
+
+	/* --- out endpoint descriptor --- */
+
+	7,				/* bLength */
+	DESC_TYPE_ENDPOINT,		/* bDescriptorType */
+	EP_BULK | 0x00,			/* bEndpointAddress */
+	0x02,				/* bmAttributes (bulk) */
+	w(EP_BULK_SIZE),		/* wMaxPacketSize */
+	0,				/* bInterval */
+
+	/* --- in endpoint descriptor --- */
+
+	7,				/* bLength */
+	DESC_TYPE_ENDPOINT,		/* bDescriptorType */
+	EP_BULK | 0x80,			/* bEndpointAddress */
+	0x02,				/* bmAttributes (bulk) */
+	w(EP_BULK_SIZE),		/* wMaxPacketSize */
+	0				/* bInterval */
+};
+
+#undef w
+#undef u
+
+static const char T_STR_SCSI_VENDOR[] = "CIRRUSL ";
+static const char T_STR_SCSI_PRODUCT[] = "EDB7312         ";
+static const char T_STR_SCSI_REVISION[] = "0000";
+
+/* --- */
+
+static int thread_init(struct d12 *p)
+{
+	int r;
+
+	init_completion(&p->cpl_dio_sync);
+	sema_init(&p->wait_dio_cmd, 0);
+
+	r = kernel_thread(dio_thread, p, 0);
+	if (r < 0) {
+		printk("%s: couldn't spawn thread\n", __FUNCTION__);
+		return r;
+	}
+
+	wait_for_completion(&p->cpl_dio_sync);	/* wait thread initialize */
+
+	return 0;
+}
+
+static void thread_exit(struct d12 *p)
+{
+	p->dio.cmd = DIO_CMD_EXIT;
+	up(&p->wait_dio_cmd);
+
+	wait_for_completion(&p->cpl_dio_sync);	/* wait thread exit */
+}
+
+static void dev_add(struct d12 *p, kdev_t dev)
+{
+	int lun, maj, min;
+
+	lun = p->max_lun;
+	if (lun == 16) {
+		printk("ignored, limit of 16 reached\n");
+		goto err0;
+	}
+
+	maj = MAJOR(dev);
+	min = MINOR(dev);
+
+	printk("%s: dev %u:%u - ", ID, maj, min);
+
+	if (is_mounted(dev)) {
+		printk("ignored, mounted\n");
+		goto err0;
+	}
+
+	p->bdev[lun] = bdget(dev);
+	if (!p->bdev[lun]) {
+		printk("ignored, no memory\n");
+		goto err0;
+	}
+	if (blkdev_get(p->bdev[lun], FMODE_READ | FMODE_WRITE, 0, BDEV_RAW)) {
+		printk("ignored, blkdev_get() error\n");
+		goto err0;
+	}
+
+	p->scsi_str_vendor[lun] = T_STR_SCSI_VENDOR;
+	p->scsi_str_product[lun] = T_STR_SCSI_PRODUCT;
+	p->scsi_str_revision[lun] = T_STR_SCSI_REVISION;
+
+	p->atd_dev[lun] = dev;
+	p->atd_blk[lun] = get_hardsect_size(dev);
+	if (!p->atd_blk[lun] || (p->atd_blk[lun] > MAX_CHUNKBUF)) {
+		printk("ignored (bogus sector size %u)\n", p->atd_blk[lun]);
+		goto err1;
+	}
+	if (set_blocksize(dev, p->atd_blk[lun])) {
+		printk("ignored, set_blocksize() error\n");
+		goto err1;
+	}
+	p->atd_chunkblk[lun] = MAX_CHUNKBUF / p->atd_blk[lun];
+	p->atd_lba_capacity[lun] = 0;
+	if (blk_size[maj])
+		p->atd_lba_capacity[lun] = blk_size[maj][min];
+	if (!p->atd_lba_capacity[lun]) {
+		printk("ignored (zero size)\n");
+		goto err1;
+	}
+
+	p->atd_stat[lun] = ATD_STAT_READY;
+
+	printk("added %s\n", (p->atd_stat[lun] & ATD_STAT_RO) ? "read-only" : "read-write");
+	p->max_lun++;
+
+	return;
+
+err1:	blkdev_put(p->bdev[lun], BDEV_RAW);
+
+err0:	return;
+}
+
+static void dev_del(struct d12 *p)
+{
+	int lun;
+
+	for (lun = 0 ; lun < p->max_lun ; lun++) {
+		blkdev_put(p->bdev[lun], BDEV_RAW);
+	}
+}
+
+int __init usbd12_init_module(void)
+{
+	struct d12 *p;
+	int r = -EINVAL;
+
+	printk("PDIUSBD12 / mass-storage support for EDB7312\n");
+
+	/* prepare context */
+
+	p = &d12;
+	p->reg_cmd = REG_D12_CMD;
+	p->reg_dat = REG_D12_DAT;
+	p->irq = IRQ_D12;
+
+	p->desc_dev = T_DESC_DEV;
+	p->desc_dev_len = sizeof(T_DESC_DEV);
+
+	p->desc_cfg = T_DESC_CFG;
+	p->desc_cfg_len = sizeof(T_DESC_CFG);
+
+	p->desc_str_max = MAX_DESC_STR;
+	p->desc_str = T_DESC_STR;
+	p->desc_str_len = T_DESC_STR_LEN;
+
+	/* attach devices */
+
+	dev_add(p, MKDEV(1, 1));		/* /dev/ram1 */
+#if 0
+	dev_add(p, MKDEV(3, 1));		/* /dev/hda1 */
+	dev_add(p, MKDEV(3, 65));		/* /dev/hdb1 */
+#endif
+
+	if (!p->max_lun) {
+		printk("%s: no devices attached, skipping driver loading\n", ID);
+		goto err0;
+	}
+
+	r = thread_init(p);
+	if (r)
+		goto err1;
+
+	d12_init(p);
+	p->suspend = GPIO_D12_SUSP;
+
+	r = request_irq(p->irq, usbd12_interrupt, SA_SHIRQ, "pdiusbd12", p);
+	if (r) {
+		printk("%s: couldn't allocate IRQ %u\n", ID, p->irq);
+		goto err2;
+	}
+        edb7312_enable_eint1();
+
+	return 0;
+
+err2:	thread_exit(p);
+err1:	dev_del(p);
+err0:	return r;
+}
+
+static void __exit usbd12_exit_module(void)
+{
+	struct d12 *p;
+
+	p = &d12;
+
+	free_irq(p->irq, p);
+	thread_exit(p);
+	dev_del(p);
+}
+
+module_init(usbd12_init_module);
+module_exit(usbd12_exit_module);
+
+MODULE_AUTHOR("Vladimir Ivanov <vladitx@nucleusys.com>");
+MODULE_DESCRIPTION("PDIUSBD12 / mass-storage support for EDB7312");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/drivers/usb/gadget/Config.in linux-2.4.29-uc1/drivers/usb/gadget/Config.in
--- linux-2.4.29/drivers/usb/gadget/Config.in	2005-01-19 14:10:06.000000000 +0000
+++ linux-2.4.29-uc1/drivers/usb/gadget/Config.in	2005-06-14 02:12:07.000000000 +0100
@@ -16,12 +16,19 @@
   # since they control compile options for gadget drivers.
   #
   choice 'USB Peripheral Controller Driver' "\
+	Intel-PXA2xx/IXP4xx		CONFIG_USB_GADGET_PXA2XX \
 	NetChip-2280			CONFIG_USB_GADGET_NET2280 \
 	Toshiba-TC86C001(Goku-S)	CONFIG_USB_GADGET_GOKU \
 	" NetChip-2280
 
   define_tristate CONFIG_USB_GADGET_CONTROLLER n
 
+  if [ "$CONFIG_ARCH_PXA" = "y" -o "$CONFIG_ARCH_IXP425" = "y" ] ; then
+     if [ "$CONFIG_USB_GADGET_PXA2XX" = "y" ] ; then
+       define_tristate CONFIG_USB_PXA2XX $CONFIG_USB_GADGET
+       define_tristate CONFIG_USB_GADGET_CONTROLLER $CONFIG_USB_PXA2XX
+     fi
+  fi
   if [ "$CONFIG_PCI" = "y" -a "$CONFIG_USB_GADGET_NET2280" = "y" ] ; then
     define_tristate CONFIG_USB_NET2280 $CONFIG_USB_GADGET
     define_tristate CONFIG_USB_GADGET_CONTROLLER $CONFIG_USB_NET2280
diff -urN linux-2.4.29/drivers/usb/gadget/Makefile linux-2.4.29-uc1/drivers/usb/gadget/Makefile
--- linux-2.4.29/drivers/usb/gadget/Makefile	2004-08-08 00:26:05.000000000 +0100
+++ linux-2.4.29-uc1/drivers/usb/gadget/Makefile	2005-06-14 02:12:07.000000000 +0100
@@ -9,10 +9,12 @@
 list-multi			:= g_zero.o g_ether.o g_file_storage.o
 
 obj-$(CONFIG_USB_NET2280)	+= net2280.o
+obj-$(CONFIG_USB_PXA2XX)	+= pxa2xx_udc.o
 obj-$(CONFIG_USB_GOKU)		+= goku_udc.o
 
 # only one of these may be statically linked ...
 controller-$(CONFIG_USB_NET2280)	+= net2280.o
+controller-$(CONFIG_USB_PXA2XX)		+= pxa2xx_udc.o
 controller-$(CONFIG_USB_GOKU)		+= goku_udc.o
 
 # ... and only one of these, too; kbuild/kconfig don't help though.
diff -urN linux-2.4.29/drivers/usb/gadget/pxa2xx_udc.c linux-2.4.29-uc1/drivers/usb/gadget/pxa2xx_udc.c
--- linux-2.4.29/drivers/usb/gadget/pxa2xx_udc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/usb/gadget/pxa2xx_udc.c	2005-06-14 02:12:07.000000000 +0100
@@ -0,0 +1,2485 @@
+/*
+ * linux/drivers/usb/gadget/pxa2xx_udc.c
+ * Intel PXA2xx and IXP4xx on-chip full speed USB device controllers
+ *
+ * Copyright (C) 2002 Intrinsyc, Inc. (Frank Becker)
+ * Copyright (C) 2003 Robert Schwebel, Pengutronix
+ * Copyright (C) 2003 Benedikt Spranger, Pengutronix
+ * Copyright (C) 2003 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ */
+
+#define	DEBUG	1
+// #define	VERBOSE	DBG_VERBOSE
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/mm.h>
+// #include <linux/device.h>
+
+#include <asm/byteorder.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/unaligned.h>
+#include <asm/proc/cache.h>
+
+#include <linux/usb_ch9.h>
+#include <linux/usb_gadget.h>
+
+
+/*
+ * This driver handles the USB Device Controller (UDC) in Intel's PXA 2xx
+ * series processors.  The UDC for the IXP 4xx series is very similar.
+ * There are fifteen endpoints, in addition to ep0.
+ *
+ * Such controller drivers work with a gadget driver.  The gadget driver
+ * returns descriptors, implements configuration and data protocols used
+ * by the host to interact with this device, and allocates endpoints to
+ * the different protocol interfaces.  The controller driver virtualizes
+ * usb hardware so that the gadget drivers will be more portable.
+ * 
+ * This UDC hardware wants to implement a bit too much USB protocol, so
+ * it constrains the sorts of USB configuration change events that work.
+ * The errata for these chips are misleading; some "fixed" bugs from
+ * pxa250 a0/a1 b0/b1/b2 sure act like they're still there.
+ */
+
+/* NOTE:  the 2.6 driver is probably the most current version */
+#define	DRIVER_VERSION	"5-Jan-2004"
+#define	DRIVER_DESC	"PXA 2xx USB Device Controller driver"
+
+static const char driver_name [] = "pxa2xx_udc";
+
+static const char ep0name [] = "ep0";
+
+
+// #define	USE_DMA
+// #define	USE_OUT_DMA
+// #define	DISABLE_TEST_MODE
+
+#ifdef CONFIG_PROC_FS
+#define	UDC_PROC_FILE
+#endif
+
+#ifdef CONFIG_ARCH_IXP425
+#undef USE_DMA
+
+/* cpu-specific register addresses are compiled in to this code */
+#ifdef CONFIG_ARCH_PXA
+#error "Can't configure both IXP and PXA"
+#endif
+
+#endif
+
+#ifdef CONFIG_EMBEDDED
+/* few strings, and little code to use them */
+#undef	DEBUG
+#undef	UDC_PROC_FILE
+#endif
+
+
+#include "pxa2xx_udc.h"
+
+#ifdef	USE_DMA
+static int use_dma = 1;
+MODULE_PARM (use_dma, "i");
+MODULE_PARM_DESC (use_dma, "true to use dma");
+
+static void dma_nodesc_handler (int dmach, void *_ep, struct pt_regs *r);
+static void kick_dma(struct pxa2xx_ep *ep, struct pxa2xx_request *req);
+
+#ifdef USE_OUT_DMA
+#define	DMASTR " (dma support)"
+#else
+#define	DMASTR " (dma in)"
+#endif
+
+#else	/* !USE_DMA */
+#define	DMASTR " (pio only)"
+#undef	USE_OUT_DMA
+#endif
+
+#ifdef	CONFIG_USB_PXA2XX_SMALL
+#define SIZE_STR	" (small)"
+#else
+#define SIZE_STR	""
+#endif
+
+#ifdef DISABLE_TEST_MODE
+/* (mode == 0) == no undocumented chip tweaks
+ * (mode & 1)  == double buffer bulk IN
+ * (mode & 2)  == double buffer bulk OUT
+ * ... so mode = 3 (or 7, 15, etc) does it for both
+ */
+static ushort fifo_mode = 0;
+MODULE_PARM (fifo_mode, "h");
+MODULE_PARM_DESC (fifo_mode, "pxa2xx udc fifo mode");
+#endif
+
+/* ---------------------------------------------------------------------------
+ * 	endpoint related parts of the api to the usb controller hardware,
+ *	used by gadget driver; and the inner talker-to-hardware core.
+ * ---------------------------------------------------------------------------
+ */
+
+static void pxa2xx_ep_fifo_flush (struct usb_ep *ep);
+static void nuke (struct pxa2xx_ep *, int status);
+
+static void pio_irq_enable(int bEndpointAddress)
+{
+        bEndpointAddress &= 0xf;
+        if (bEndpointAddress < 8)
+                UICR0 &= ~(1 << bEndpointAddress);
+        else {
+                bEndpointAddress -= 8;
+                UICR1 &= ~(1 << bEndpointAddress);
+	}
+}
+
+static void pio_irq_disable(int bEndpointAddress)
+{
+        bEndpointAddress &= 0xf;
+        if (bEndpointAddress < 8)
+                UICR0 |= 1 << bEndpointAddress;
+        else {
+                bEndpointAddress -= 8;
+                UICR1 |= 1 << bEndpointAddress;
+        }
+}
+
+/* The UDCCR reg contains mask and interrupt status bits,
+ * so using '|=' isn't safe as it may ack an interrupt.
+ */
+#define UDCCR_MASK_BITS         (UDCCR_REM | UDCCR_SRM | UDCCR_UDE)
+
+static inline void udc_set_mask_UDCCR(int mask)
+{
+	UDCCR = (UDCCR & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS);
+}
+
+static inline void udc_clear_mask_UDCCR(int mask)
+{
+	UDCCR = (UDCCR & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS);
+}
+
+static inline void udc_ack_int_UDCCR(int mask)
+{
+	/* udccr contains the bits we dont want to change */
+	__u32 udccr = UDCCR & UDCCR_MASK_BITS;
+
+	UDCCR = udccr | (mask & ~UDCCR_MASK_BITS);
+}
+
+/*
+ * endpoint enable/disable
+ *
+ * we need to verify the descriptors used to enable endpoints.  since pxa2xx
+ * endpoint configurations are fixed, and are pretty much always enabled,
+ * there's not a lot to manage here.
+ *
+ * because pxa2xx can't selectively initialize bulk (or interrupt) endpoints,
+ * (resetting endpoint halt and toggle), SET_INTERFACE is unusable except
+ * for a single interface (with only the default altsetting) and for gadget
+ * drivers that don't halt endpoints (not reset by set_interface).  that also
+ * means that if you use ISO, you must violate the USB spec rule that all
+ * iso endpoints must be in non-default altsettings.
+ */
+static int pxa2xx_ep_enable (struct usb_ep *_ep,
+		const struct usb_endpoint_descriptor *desc)
+{
+	struct pxa2xx_ep        *ep;
+	struct pxa2xx_udc       *dev;
+
+	ep = container_of (_ep, struct pxa2xx_ep, ep);
+	if (!_ep || !desc || ep->desc || _ep->name == ep0name
+			|| desc->bDescriptorType != USB_DT_ENDPOINT
+			|| ep->bEndpointAddress != desc->bEndpointAddress
+			|| ep->fifo_size < le16_to_cpu
+						(desc->wMaxPacketSize)) {
+		DMSG("%s, bad ep or descriptor\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	/* xfer types must match, except that interrupt ~= bulk */
+	if (ep->bmAttributes != desc->bmAttributes
+			&& ep->bmAttributes != USB_ENDPOINT_XFER_BULK
+			&& desc->bmAttributes != USB_ENDPOINT_XFER_INT) {
+		DMSG("%s, %s type mismatch\n", __FUNCTION__, _ep->name);
+		return -EINVAL;
+	}
+
+	/* hardware _could_ do smaller, but driver doesn't */
+	if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
+				&& le16_to_cpu (desc->wMaxPacketSize)
+						!= BULK_FIFO_SIZE)
+			|| !desc->wMaxPacketSize) {
+		DMSG("%s, bad %s maxpacket\n", __FUNCTION__, _ep->name);
+		return -ERANGE;
+	}
+
+	dev = ep->dev;
+	if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
+		DMSG("%s, bogus device state\n", __FUNCTION__);
+		return -ESHUTDOWN;
+	}
+
+	ep->desc = desc;
+	ep->dma = -1;
+	ep->stopped = 0;
+	ep->pio_irqs = ep->dma_irqs = 0;
+	ep->ep.maxpacket = le16_to_cpu (desc->wMaxPacketSize);
+
+	/* flush fifo (mostly for OUT buffers) */
+	pxa2xx_ep_fifo_flush (_ep);
+
+	/* ... reset halt state too, if we could ... */
+
+#ifdef	USE_DMA
+	/* for (some) bulk and ISO endpoints, try to get a DMA channel and
+	 * bind it to the endpoint.  otherwise use PIO. 
+	 */
+	switch (ep->bmAttributes) {
+	case USB_ENDPOINT_XFER_ISOC:
+		if (le16_to_cpu(desc->wMaxPacketSize) % 32)
+			break;
+		// fall through
+	case USB_ENDPOINT_XFER_BULK:
+		if (!use_dma || !ep->reg_drcmr)
+			break;
+		/* no bulk-out dma yet (pointless w/o descriptors) */
+		if ((ep->bmAttributes == USB_ENDPOINT_XFER_BULK)
+				&& (ep->bEndpointAddress & USB_DIR_IN) == 0) {
+			DMSG("%s dma-out NYI\n", _ep->name);
+			break;
+		}
+		ep->dma = pxa_request_dma ((char *)_ep->name,
+				(le16_to_cpu(desc->wMaxPacketSize) > 64)
+					? DMA_PRIO_MEDIUM /* some iso */
+					: DMA_PRIO_LOW,
+				// FIXME or ep_out_dma .. ..
+				dma_nodesc_handler, ep);
+		if (ep->dma >= 0) {
+			*ep->reg_drcmr = DRCMR_MAPVLD | ep->dma;
+			DMSG("%s using dma%d\n", _ep->name, ep->dma);
+		}
+	}
+#endif
+
+	DBG(DBG_VERBOSE, "enabled %s\n", _ep->name);
+	return 0;
+}
+
+static int pxa2xx_ep_disable (struct usb_ep *_ep)
+{
+	struct pxa2xx_ep	*ep;
+
+	ep = container_of (_ep, struct pxa2xx_ep, ep);
+	if (!_ep || !ep->desc) {
+		DMSG("%s, %s not enabled\n", __FUNCTION__,
+			_ep ? ep->ep.name : NULL);
+		return -EINVAL;
+	}
+	nuke (ep, -ESHUTDOWN);
+
+#ifdef	USE_DMA
+	if (ep->dma >= 0) {
+		*ep->reg_drcmr = 0;
+		pxa_free_dma (ep->dma);
+		ep->dma = -1;
+	}
+#endif
+
+	/* flush fifo (mostly for IN buffers) */
+	pxa2xx_ep_fifo_flush (_ep);
+
+	ep->desc = 0;
+	ep->stopped = 1;
+
+	DBG(DBG_VERBOSE, "%s disabled\n", _ep->name);
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* for the pxa2xx, these can just wrap kmalloc/kfree.  gadget drivers
+ * must still pass correctly initialized endpoints, since other controller
+ * drivers may care about how it's currently set up (dma issues etc).
+ */
+
+/*
+ * 	pxa2xx_ep_alloc_request - allocate a request data structure
+ */
+static struct usb_request *
+pxa2xx_ep_alloc_request (struct usb_ep *_ep, int gfp_flags)
+{
+	struct pxa2xx_request *req;
+
+	/* FIXME for bulk out-dma endpoints, preallocate a frame's worth of
+	 * (aligned) dma descriptors at the end of the request
+	 */
+
+	req = kmalloc (sizeof *req, gfp_flags);
+	if (!req)
+		return 0;
+
+	memset (req, 0, sizeof *req);
+	INIT_LIST_HEAD (&req->queue);
+	return &req->req;
+}
+
+
+/*
+ * 	pxa2xx_ep_free_request - deallocate a request data structure
+ */
+static void
+pxa2xx_ep_free_request (struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct pxa2xx_request	*req;
+
+	req = container_of (_req, struct pxa2xx_request, req);
+	WARN_ON (!list_empty (&req->queue));
+	kfree(req);
+}
+
+
+/* PXA cache needs flushing with DMA I/O (it's dma-incoherent), but there's
+ * no device-affinity and the heap works perfectly well for i/o buffers.
+ */
+static void *
+pxa2xx_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
+	dma_addr_t *dma, int gfp_flags)
+{
+	char			*retval;
+
+	retval = kmalloc (bytes, gfp_flags & ~(__GFP_DMA|__GFP_HIGHMEM));
+	if (retval)
+		*dma = virt_to_bus (retval);
+	return retval;
+}
+
+static void
+pxa2xx_ep_free_buffer(struct usb_ep *_ep, void *buf, dma_addr_t dma,
+		unsigned bytes)
+{
+	kfree (buf);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ *	done - retire a request; caller blocked irqs
+ */
+static void done(struct pxa2xx_ep *ep, struct pxa2xx_request *req, int status)
+{
+	unsigned		stopped = ep->stopped;
+
+	list_del_init(&req->queue);
+
+	if (likely (req->req.status == -EINPROGRESS))
+		req->req.status = status;
+	else
+		status = req->req.status;
+
+	if (status && status != -ESHUTDOWN)
+		DBG(DBG_VERBOSE, "complete %s req %p stat %d len %u/%u\n",
+			ep->ep.name, &req->req, status,
+			req->req.actual, req->req.length);
+
+	/* don't modify queue heads during completion callback */
+	ep->stopped = 1;
+	req->req.complete(&ep->ep, &req->req);
+	ep->stopped = stopped;
+}
+
+
+static inline void ep0_idle (struct pxa2xx_udc *dev)
+{
+	dev->ep0state = EP0_IDLE;
+	LED_EP0_OFF;
+}
+
+static int
+write_packet(volatile u32 *uddr, struct pxa2xx_request *req, unsigned max)
+{
+	u8		*buf;
+	unsigned	length, count;
+
+	buf = req->req.buf + req->req.actual;
+	prefetch(buf);
+
+	/* how big will this packet be? */
+	length = min(req->req.length - req->req.actual, max);
+	req->req.actual += length;
+
+	count = length;
+	while (likely(count--))
+		*uddr = *buf++;
+
+	return length;
+}
+
+/*
+ * write to an IN endpoint fifo, as many packets as possible.
+ * irqs will use this to write the rest later.
+ * caller guarantees at least one packet buffer is ready (or a zlp).
+ */
+static int
+write_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req)
+{
+	unsigned		max;
+
+	max = le16_to_cpu(ep->desc->wMaxPacketSize);
+	do {
+		unsigned	count;
+		int		is_last, is_short;
+
+		count = write_packet(ep->reg_uddr, req, max);
+
+		/* last packet is usually short (or a zlp) */
+		if (unlikely (count != max))
+			is_last = is_short = 1;
+		else {
+			if (likely(req->req.length != req->req.actual)
+					|| req->req.zero)
+				is_last = 0;
+			else
+				is_last = 1;
+			/* interrupt/iso maxpacket may not fill the fifo */
+			is_short = unlikely (max < ep->fifo_size);
+		}
+
+		DBG(DBG_VERY_NOISY, "wrote %s %d bytes%s%s %d left %p\n",
+			ep->ep.name, count,
+			is_last ? "/L" : "", is_short ? "/S" : "",
+			req->req.length - req->req.actual, req);
+
+		/* let loose that packet. maybe try writing another one,
+		 * double buffering might work.  TSP, TPC, and TFS
+		 * bit values are the same for all normal IN endpoints.
+		 */
+		*ep->reg_udccs = UDCCS_BI_TPC;
+		if (is_short)
+			*ep->reg_udccs = UDCCS_BI_TSP;
+
+		/* requests complete when all IN data is in the FIFO */
+		if (is_last) {
+			done (ep, req, 0);
+			if (list_empty(&ep->queue) || unlikely(ep->dma >= 0))
+				pio_irq_disable (ep->bEndpointAddress);
+#ifdef USE_DMA
+			if (unlikely(ep->dma >= 0) && !list_empty(&ep->queue)) {
+DMSG("%s pio2dma\n", ep->ep.name);
+				req = list_entry(ep->queue.next,
+						struct pxa2xx_request, queue);
+				kick_dma(ep,req);
+				return 0;
+			}
+#endif
+			return 1;
+		}
+
+		// TODO experiment: how robust can fifo mode tweaking be?
+		// the double buffering could speed up I/O a bunch.
+
+	} while (*ep->reg_udccs & UDCCS_BI_TFS);
+	return 0;
+}
+
+/* caller asserts req->pending (ep0 irq status nyet cleared); starts
+ * ep0 data stage.  these chips want very simple state transitions.
+ */
+static inline
+void ep0start(struct pxa2xx_udc *dev, u32 flags, const char *tag)
+{
+	UDCCS0 = flags|UDCCS0_SA|UDCCS0_OPR;
+	USIR0 = USIR0_IR0;
+	dev->req_pending = 0;
+	DBG(DBG_VERY_NOISY, "%s %s, %02x/%02x\n",
+		__FUNCTION__, tag, UDCCS0, flags);
+}
+
+static int
+write_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req)
+{
+	unsigned	count;
+	int		is_short;
+
+	count = write_packet(&UDDR0, req, EP0_FIFO_SIZE);
+	ep->dev->stats.write.bytes += count;
+
+	/* last packet "must be" short (or a zlp) */
+	is_short = (count != EP0_FIFO_SIZE);
+
+	DBG(DBG_VERY_NOISY, "ep0in %d bytes %d left %p\n", count,
+		req->req.length - req->req.actual, req);
+
+	if (unlikely (is_short)) {
+		if (ep->dev->req_pending)
+			ep0start(ep->dev, UDCCS0_IPR, "short IN");
+		else
+			UDCCS0 = UDCCS0_IPR;
+
+		count = req->req.length;
+		done (ep, req, 0);
+		ep0_idle(ep->dev);
+#if 1
+		/* This seems to get rid of lost status irqs in some cases:
+		 * host responds quickly, or next request involves config
+		 * change automagic, or should have been hidden, or ...
+		 *
+		 * FIXME get rid of all udelays possible...
+		 */
+		if (count >= EP0_FIFO_SIZE) {
+			count = 100;
+			do {
+				if ((UDCCS0 & UDCCS0_OPR) != 0) {
+					/* clear OPR, generate ack */
+					UDCCS0 = UDCCS0_OPR;
+					break;
+				}
+				count--;
+				udelay(1);
+			} while (count);
+		}
+#endif
+	} else if (ep->dev->req_pending)
+		ep0start(ep->dev, 0, "IN");
+	return is_short;
+}
+
+
+/*
+ * read_fifo -  unload packet(s) from the fifo we use for usb OUT
+ * transfers and put them into the request.  caller should have made
+ * sure there's at least one packet ready.
+ *
+ * returns true if the request completed because of short packet or the
+ * request buffer having filled (and maybe overran till end-of-packet).
+ */
+static int
+read_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req)
+{
+	for (;;) {
+		u32		udccs;
+		u8		*buf;
+		unsigned	bufferspace, count, is_short;
+
+		/* make sure there's a packet in the FIFO.
+		 * UDCCS_{BO,IO}_RPC are all the same bit value.
+		 * UDCCS_{BO,IO}_RNE are all the same bit value.
+		 */
+		udccs = *ep->reg_udccs;
+		if (unlikely ((udccs & UDCCS_BO_RPC) == 0))
+			break;
+		buf = req->req.buf + req->req.actual;
+		prefetchw(buf);
+		bufferspace = req->req.length - req->req.actual;
+
+		/* read all bytes from this packet */
+		if (likely (udccs & UDCCS_BO_RNE)) {
+			count = 1 + (0x0ff & *ep->reg_ubcr);
+			req->req.actual += min (count, bufferspace);
+		} else /* zlp */
+			count = 0;
+		is_short = (count < ep->ep.maxpacket);
+		DBG(DBG_VERY_NOISY, "read %s %02x, %d bytes%s req %p %d/%d\n",
+			ep->ep.name, udccs, count,
+			is_short ? "/S" : "",
+			req, req->req.actual, req->req.length);
+		while (likely (count-- != 0)) {
+			u8	byte = (u8) *ep->reg_uddr;
+
+			if (unlikely (bufferspace == 0)) {
+				/* this happens when the driver's buffer
+				 * is smaller than what the host sent.
+				 * discard the extra data.
+				 */
+				if (req->req.status != -EOVERFLOW)
+					DMSG("%s overflow %d\n",
+						ep->ep.name, count);
+				req->req.status = -EOVERFLOW;
+			} else {
+				*buf++ = byte;
+				bufferspace--;
+			}
+		}
+		*ep->reg_udccs =  UDCCS_BO_RPC;
+		/* RPC/RSP/RNE could now reflect the other packet buffer */
+
+		/* iso is one request per packet */
+		if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
+			if (udccs & UDCCS_IO_ROF)
+				req->req.status = -EHOSTUNREACH;
+			/* more like "is_done" */
+			is_short = 1;
+		}
+
+		/* completion */
+		if (is_short || req->req.actual == req->req.length) {
+			done (ep, req, 0);
+			if (list_empty(&ep->queue))
+				pio_irq_disable (ep->bEndpointAddress);
+			return 1;
+		}
+
+		/* finished that packet.  the next one may be waiting... */
+	}
+	return 0;
+}
+
+/*
+ * special ep0 version of the above.  no UBCR0 or double buffering; status
+ * handshaking is magic.  most device protocols don't need control-OUT.
+ * CDC vendor commands (and RNDIS), mass storage CB/CBI, and some other
+ * protocols do use them.
+ */
+static int
+read_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req)
+{
+	u8		*buf, byte;
+	unsigned	bufferspace;
+
+	buf = req->req.buf + req->req.actual;
+	bufferspace = req->req.length - req->req.actual;
+
+	while (UDCCS0 & UDCCS0_RNE) {
+		byte = (u8) UDDR0;
+
+		if (unlikely (bufferspace == 0)) {
+			/* this happens when the driver's buffer
+			 * is smaller than what the host sent.
+			 * discard the extra data.
+			 */
+			if (req->req.status != -EOVERFLOW)
+				DMSG("%s overflow\n", ep->ep.name);
+			req->req.status = -EOVERFLOW;
+		} else {
+			*buf++ = byte;
+			req->req.actual++;
+			bufferspace--;
+		}
+	}
+	
+	UDCCS0 = UDCCS0_OPR | UDCCS0_IPR;
+	
+	/* completion */
+	if (req->req.actual >= req->req.length)
+		return 1;
+	
+	/* finished that packet.  the next one may be waiting... */
+	return 0;
+}
+
+#ifdef	USE_DMA
+
+static inline void
+start_dma_nodesc(struct pxa2xx_ep *ep, struct pxa2xx_request *req, int is_in)
+{
+	u32	dcmd = req->req.length;
+	u32	buf = virt_to_bus (req->req.buf);
+	u32	fifo = io_v2p ((u32)ep->reg_uddr);
+
+	/* no-descriptor mode can be simple for bulk-in, iso-in, iso-out */
+	DCSR(ep->dma) = DCSR_NODESC;
+	dcmd |= DCMD_BURST32 | DCMD_ENDIRQEN | DCMD_WIDTH1;
+	if (is_in) {
+		DSADR(ep->dma) = buf;
+		DTADR(ep->dma) = fifo;
+		dcmd |= DCMD_FLOWTRG | DCMD_INCSRCADDR;
+	} else {
+		DSADR(ep->dma) = fifo;
+		DTADR(ep->dma) = buf;
+		dcmd |= DCMD_FLOWSRC | DCMD_INCTRGADDR;
+	}
+	DCMD(ep->dma) = dcmd;
+	DCSR(ep->dma) = DCSR_RUN | DCSR_STOPIRQEN | DCSR_NODESC;
+	/* and later the dma handler gets called */
+}
+
+static void kick_dma(struct pxa2xx_ep *ep, struct pxa2xx_request *req)
+{
+	if (ep->bEndpointAddress & USB_DIR_IN) {
+		/* docs imply we can't preload with pio */
+		if ((((u32)req->req.buf) & 0x0f) != 0) {
+// VERBOSE
+			DMSG("%s bad DMA align %p\n",
+				ep->ep.name, req->req.buf);
+pio_in:
+// FIXME PIO fallback doesn't work right yet (recovery?)
+DMSG("%s dma2pio\n", ep->ep.name);
+			pio_irq_enable(ep->bEndpointAddress);
+			if ((*ep->reg_udccs & UDCCS_BI_TFS) != 0)
+				(void) write_fifo(ep, req);
+			return;
+		}
+		/* dmacount 0 means end-of-transfer */
+		if (unlikely((req->req.length - req->req.actual) == 0)) {
+// VERBOSE
+			DMSG("%s zlp dma write...\n", ep->ep.name);
+			goto pio_in;
+		}
+		start_dma_nodesc(ep, req, USB_DIR_IN);
+	} else {
+		// if ISO, use no-descriptor DMA
+		BUG();
+	}
+}
+
+static void cancel_dma(struct pxa2xx_ep *ep)
+{
+	struct pxa2xx_request	*req;
+	u32			tmp;
+
+	if (DCSR(ep->dma) == 0 || list_empty(&ep->queue))
+		return;
+
+	DCSR(ep->dma) = 0;
+	while ((DCSR(ep->dma) & DCSR_STOPSTATE) == 0)
+		cpu_relax();
+
+	req = list_entry(ep->queue.next, struct pxa2xx_request, queue);
+	tmp = DCMD(ep->dma) & DCMD_LENGTH;
+	req->req.actual = req->req.length - (tmp & DCMD_LENGTH);
+
+	/* the last tx packet may be incomplete, so flush the fifo.
+	 * FIXME correct req.actual if we can
+	 */
+	if (ep->bEndpointAddress & USB_DIR_IN)
+		*ep->reg_udccs = UDCCS_BI_FTF;
+}
+
+static void dma_nodesc_handler(int dmach, void *_ep, struct pt_regs *r)
+{
+	struct pxa2xx_ep	*ep = _ep;
+	struct pxa2xx_request	*req;
+	u32			tmp;
+
+	req = list_entry(ep->queue.next, struct pxa2xx_request, queue);
+
+	ep->dev->stats.irqs++;
+	HEX_DISPLAY(ep->dev->stats.irqs);
+
+	/* ack/clear */
+	tmp = DCSR(ep->dma);
+	DCSR(ep->dma) = tmp;
+	if ((tmp & DCSR_STOPSTATE) == 0
+			|| (DDADR(ep->dma) & DDADR_STOP) != 0) {
+		DBG(DBG_VERBOSE, "%s, dcsr %08x ddadr %08x\n",
+			ep->ep.name, DCSR(ep->dma), DDADR(ep->dma));
+		return;
+	}
+	DCSR(ep->dma) = 0;	/* clear DCSR_STOPSTATE */
+
+	/* wrap up the transfer, and collect status */
+	if (unlikely(tmp & DCSR_BUSERR))
+		req->req.status = -EIO;
+	tmp = DCMD(ep->dma);
+	req->req.actual = req->req.length - (tmp & DCMD_LENGTH);
+	tmp = 1;	/* normally this is the last packet */
+
+	if (ep->bEndpointAddress & USB_DIR_IN) {
+		/* maybe validate final short packet */
+		if ((ep->bmAttributes == USB_ENDPOINT_XFER_BULK
+					&& req->req.actual % BULK_FIFO_SIZE)
+				|| (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
+					&& req->req.actual % ISO_FIFO_SIZE))
+			*ep->reg_udccs = UDCCS_BI_TSP /*|UDCCS_BI_TPC*/;
+
+		/* or force a zlp, with pio ... */
+		else if (ep->bmAttributes == USB_ENDPOINT_XFER_BULK
+				&& req->req.zero) {
+			tmp = 0;
+		}
+		// if iso, maybe report underrun (TUR)
+	} else {
+		BUG();
+	}
+
+	if (likely(tmp != 0))
+		done(ep, req, 0);
+
+	/* maybe re-activate after completion */
+	if (ep->stopped || list_empty(&ep->queue))
+		return;
+	req = list_entry(ep->queue.next, struct pxa2xx_request, queue);
+	kick_dma(ep, req);
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+static int
+pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
+{
+	struct pxa2xx_request	*req;
+	struct pxa2xx_ep	*ep;
+	struct pxa2xx_udc	*dev;
+	unsigned long		flags;
+
+	req = container_of(_req, struct pxa2xx_request, req);
+	if (unlikely (!_req || !_req->complete || !_req->buf
+			|| !list_empty(&req->queue))) {
+		DMSG("%s, bad params\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	ep = container_of(_ep, struct pxa2xx_ep, ep);
+	if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) {
+		DMSG("%s, bad ep\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	dev = ep->dev;
+	if (unlikely (!dev->driver
+			|| dev->gadget.speed == USB_SPEED_UNKNOWN)) {
+		DMSG("%s, bogus device state\n", __FUNCTION__);
+		return -ESHUTDOWN;
+	}
+
+	/* iso is always one packet per request, that's the only way
+	 * we can report per-packet status.  that also helps with dma.
+	 */
+	if (unlikely (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
+			&& req->req.length > le16_to_cpu
+						(ep->desc->wMaxPacketSize)))
+		return -EMSGSIZE;
+
+#ifdef	USE_DMA
+	if (ep->dma >= 0) {
+		unsigned long	start = (unsigned long) _req->buf;
+
+		clean_dcache_range(start, start + _req->length);
+		/* or for USB_DIR_OUT, invalidate_dcache_range (...) */
+	}
+#endif
+
+	DBG(DBG_NOISY, "%s queue req %p, len %d buf %p\n",
+	     _ep->name, _req, _req->length, _req->buf);
+
+	local_irq_save(flags);
+
+	_req->status = -EINPROGRESS;
+	_req->actual = 0;
+
+	/* kickstart this i/o queue? */
+	if (list_empty(&ep->queue) && !ep->stopped) {
+		if (ep->desc == 0 /* ep0 */) {
+			unsigned	length = _req->length;
+
+			switch (dev->ep0state) {
+			case EP0_IN_DATA_PHASE:
+				dev->stats.write.ops++;
+				if (write_ep0_fifo(ep, req))
+					req = 0;
+				break;
+
+			case EP0_OUT_DATA_PHASE:
+				dev->stats.read.ops++;
+				/* messy ... */
+				if (dev->req_config) {
+					DBG(DBG_VERBOSE, "ep0 config ack%s\n",
+						dev->has_cfr ?  "" : " raced");
+					if (dev->has_cfr)
+						UDCCFR = UDCCFR_AREN|UDCCFR_ACM;
+					done(ep, req, 0);
+					dev->ep0state = EP0_END_XFER;
+					return 0;
+				}
+				if (dev->req_pending)
+					ep0start(dev, UDCCS0_IPR, "OUT");
+				if (length == 0 || ((UDCCS0 & UDCCS0_RNE) != 0
+						&& read_ep0_fifo(ep, req))) {
+					ep0_idle(dev);
+					done(ep, req, 0);
+					req = 0;
+				}
+				break;
+
+			default:
+				DMSG("ep0 i/o, odd state %d\n", dev->ep0state);
+				local_irq_restore (flags);
+				return -EL2HLT;
+			}
+#ifdef	USE_DMA
+		/* either start dma or prime pio pump */
+		} else if (ep->dma >= 0) {
+			kick_dma(ep, req);
+#endif
+		/* can the FIFO can satisfy the request immediately? */
+		} else if ((ep->bEndpointAddress & USB_DIR_IN) != 0
+				&& (*ep->reg_udccs & UDCCS_BI_TFS) != 0
+				&& write_fifo(ep, req)) {
+			req = 0;
+		} else if ((*ep->reg_udccs & UDCCS_BO_RFS) != 0
+				&& read_fifo(ep, req)) {
+			req = 0;
+		}
+
+		if (likely (req && ep->desc) && ep->dma < 0)
+			pio_irq_enable(ep->bEndpointAddress);
+	}
+
+	/* pio or dma irq handler advances the queue. */
+	if (likely (req != 0))
+		list_add_tail(&req->queue, &ep->queue);
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+
+/*
+ * 	nuke - dequeue ALL requests
+ */
+static void nuke(struct pxa2xx_ep *ep, int status)
+{
+	struct pxa2xx_request *req;
+
+	/* called with irqs blocked */
+#ifdef	USE_DMA
+	if (ep->dma >= 0 && !ep->stopped)
+		cancel_dma(ep);
+#endif
+	while (!list_empty(&ep->queue)) {
+		req = list_entry(ep->queue.next,
+				struct pxa2xx_request,
+				queue);
+		done(ep, req, status);
+	}
+	if (ep->desc)
+		pio_irq_disable (ep->bEndpointAddress);
+}
+
+
+/* dequeue JUST ONE request */
+static int pxa2xx_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct pxa2xx_ep	*ep;
+	struct pxa2xx_request	*req;
+	unsigned long		flags;
+
+	ep = container_of(_ep, struct pxa2xx_ep, ep);
+	if (!_ep || ep->ep.name == ep0name)
+		return -EINVAL;
+
+	local_irq_save(flags);
+
+	/* make sure it's actually queued on this endpoint */
+	list_for_each_entry (req, &ep->queue, queue) {
+		if (&req->req == _req)
+			break;
+	}
+	if (&req->req != _req) {
+		local_irq_restore(flags);
+		return -EINVAL;
+	}
+
+#ifdef	USE_DMA
+	if (ep->dma >= 0 && ep->queue.next == &req->queue && !ep->stopped) {
+		cancel_dma(ep);
+		done(ep, req, -ECONNRESET);
+		/* restart i/o */
+		if (!list_empty(&ep->queue)) {
+			req = list_entry(ep->queue.next,
+					struct pxa2xx_request, queue);
+			kick_dma(ep, req);
+		}
+	} else
+#endif
+		done(ep, req, -ECONNRESET);
+
+	local_irq_restore(flags);
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int pxa2xx_ep_set_halt(struct usb_ep *_ep, int value)
+{
+	struct pxa2xx_ep	*ep;
+	unsigned long		flags;
+
+	ep = container_of(_ep, struct pxa2xx_ep, ep);
+	if (unlikely (!_ep
+			|| (!ep->desc && ep->ep.name != ep0name))
+			|| ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
+		DMSG("%s, bad ep\n", __FUNCTION__);
+		return -EINVAL;
+	}
+	if (value == 0) {
+		/* this path (reset toggle+halt) is needed to implement
+		 * SET_INTERFACE on normal hardware.  but it can't be
+		 * done from software on the PXA UDC, and the hardware
+		 * forgets to do it as part of SET_INTERFACE automagic.
+		 */
+		DMSG("only host can clear %s halt\n", _ep->name);
+		return -EROFS;
+	}
+
+	local_irq_save(flags);
+
+	if ((ep->bEndpointAddress & USB_DIR_IN) != 0
+			&& ((*ep->reg_udccs & UDCCS_BI_TFS) == 0
+			   || !list_empty(&ep->queue))) {
+		local_irq_restore(flags);
+		return -EAGAIN;
+	}
+
+	/* FST bit is the same for control, bulk in, bulk out, interrupt in */
+	*ep->reg_udccs = UDCCS_BI_FST|UDCCS_BI_FTF;
+
+	/* ep0 needs special care */
+	if (!ep->desc) {
+		start_watchdog(ep->dev);
+		ep->dev->req_pending = 0;
+		ep->dev->ep0state = EP0_STALL;
+		LED_EP0_OFF;
+
+ 	/* and bulk/intr endpoints like dropping stalls too */
+ 	} else {
+ 		unsigned i;
+ 		for (i = 0; i < 1000; i += 20) {
+ 			if (*ep->reg_udccs & UDCCS_BI_SST)
+ 				break;
+ 			udelay(20);
+ 		}
+  	}
+ 	local_irq_restore(flags);
+
+	DBG(DBG_VERBOSE, "%s halt\n", _ep->name);
+	return 0;
+}
+
+static int pxa2xx_ep_fifo_status(struct usb_ep *_ep)
+{
+	struct pxa2xx_ep        *ep;
+
+	ep = container_of(_ep, struct pxa2xx_ep, ep);
+	if (!_ep) {
+		DMSG("%s, bad ep\n", __FUNCTION__);
+		return -ENODEV;
+	}
+	/* pxa can't report unclaimed bytes from IN fifos */
+	if ((ep->bEndpointAddress & USB_DIR_IN) != 0)
+		return -EOPNOTSUPP;
+	if (ep->dev->gadget.speed == USB_SPEED_UNKNOWN
+			|| (*ep->reg_udccs & UDCCS_BO_RFS) == 0)
+		return 0;
+	else
+		return (*ep->reg_ubcr & 0xfff) + 1;
+}
+
+static void pxa2xx_ep_fifo_flush(struct usb_ep *_ep)
+{
+	struct pxa2xx_ep        *ep;
+
+	ep = container_of(_ep, struct pxa2xx_ep, ep);
+	if (!_ep || ep->ep.name == ep0name || !list_empty(&ep->queue)) {
+		DMSG("%s, bad ep\n", __FUNCTION__);
+		return;
+	}
+
+	/* toggle and halt bits stay unchanged */
+
+	/* for OUT, just read and discard the FIFO contents. */
+	if ((ep->bEndpointAddress & USB_DIR_IN) == 0) {
+		while (((*ep->reg_udccs) & UDCCS_BO_RNE) != 0)
+			(void) *ep->reg_uddr;
+		return;
+	}
+
+	/* most IN status is the same, but ISO can't stall */
+	*ep->reg_udccs = UDCCS_BI_TPC|UDCCS_BI_FTF|UDCCS_BI_TUR
+		| (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC)
+			? 0 : UDCCS_BI_SST;
+}
+
+
+static struct usb_ep_ops pxa2xx_ep_ops = {
+	.enable		= pxa2xx_ep_enable,
+	.disable	= pxa2xx_ep_disable,
+
+	.alloc_request	= pxa2xx_ep_alloc_request,
+	.free_request	= pxa2xx_ep_free_request,
+
+	.alloc_buffer	= pxa2xx_ep_alloc_buffer,
+	.free_buffer	= pxa2xx_ep_free_buffer,
+
+	.queue		= pxa2xx_ep_queue,
+	.dequeue	= pxa2xx_ep_dequeue,
+
+	.set_halt	= pxa2xx_ep_set_halt,
+	.fifo_status	= pxa2xx_ep_fifo_status,
+	.fifo_flush	= pxa2xx_ep_fifo_flush,
+};
+
+
+/* ---------------------------------------------------------------------------
+ * 	device-scoped parts of the api to the usb controller hardware
+ * ---------------------------------------------------------------------------
+ */
+
+static int pxa2xx_udc_get_frame(struct usb_gadget *_gadget)
+{
+	return ((UFNRH & 0x07) << 8) | (UFNRL & 0xff);
+}
+
+static int pxa2xx_udc_wakeup(struct usb_gadget *_gadget)
+{
+	/* host may not have enabled remote wakeup */
+	if ((UDCCS0 & UDCCS0_DRWF) == 0)
+		return -EHOSTUNREACH;
+	udc_set_mask_UDCCR(UDCCR_RSM);
+	return 0;
+}
+
+static const struct usb_gadget_ops pxa2xx_udc_ops = {
+	.get_frame	 = pxa2xx_udc_get_frame,
+	.wakeup		 = pxa2xx_udc_wakeup,
+	// current versions must always be self-powered
+};
+
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef UDC_PROC_FILE
+
+static const char proc_node_name [] = "driver/udc";
+
+static int
+udc_proc_read(char *page, char **start, off_t off, int count,
+		int *eof, void *_dev)
+{
+	char			*buf = page;
+	struct pxa2xx_udc	*dev = _dev;
+	char			*next = buf;
+	unsigned		size = count;
+	unsigned long		flags;
+	int			i, t;
+	u32			tmp;
+
+	if (off != 0)
+		return 0;
+
+	local_irq_save(flags);
+
+	/* basic device status */
+	t = snprintf(next, size, DRIVER_DESC "\n"
+		"%s version: %s\nGadget driver: %s\nHost %s\n\n",
+		driver_name, DRIVER_VERSION SIZE_STR DMASTR,
+		dev->driver ? dev->driver->driver.name : "(none)",
+		is_usb_connected() ? "full speed" : "disconnected");
+	size -= t;
+	next += t;
+
+	/* registers for device and ep0 */
+	t = snprintf(next, size,
+		"uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n",
+		UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL);
+	size -= t;
+	next += t;
+
+	tmp = UDCCR;
+	t = snprintf(next, size,
+		"udccr %02X =%s%s%s%s%s%s%s%s\n", tmp,
+		(tmp & UDCCR_REM) ? " rem" : "",
+		(tmp & UDCCR_RSTIR) ? " rstir" : "",
+		(tmp & UDCCR_SRM) ? " srm" : "",
+		(tmp & UDCCR_SUSIR) ? " susir" : "",
+		(tmp & UDCCR_RESIR) ? " resir" : "",
+		(tmp & UDCCR_RSM) ? " rsm" : "",
+		(tmp & UDCCR_UDA) ? " uda" : "",
+		(tmp & UDCCR_UDE) ? " ude" : "");
+	size -= t;
+	next += t;
+
+	tmp = UDCCS0;
+	t = snprintf(next, size,
+		"udccs0 %02X =%s%s%s%s%s%s%s%s\n", tmp,
+		(tmp & UDCCS0_SA) ? " sa" : "",
+		(tmp & UDCCS0_RNE) ? " rne" : "",
+		(tmp & UDCCS0_FST) ? " fst" : "",
+		(tmp & UDCCS0_SST) ? " sst" : "",
+		(tmp & UDCCS0_DRWF) ? " dwrf" : "",
+		(tmp & UDCCS0_FTF) ? " ftf" : "",
+		(tmp & UDCCS0_IPR) ? " ipr" : "",
+		(tmp & UDCCS0_OPR) ? " opr" : "");
+	size -= t;
+	next += t;
+
+	if (dev->has_cfr) {
+		tmp = UDCCFR;
+		t = snprintf(next, size,
+			"udccfr %02X =%s%s\n", tmp,
+			(tmp & UDCCFR_AREN) ? " aren" : "",
+			(tmp & UDCCFR_ACM) ? " acm" : "");
+		size -= t;
+		next += t;
+	}
+
+	if (!is_usb_connected() || !dev->driver)
+		goto done;
+
+	t = snprintf(next, size, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n",
+		dev->stats.write.bytes, dev->stats.write.ops,
+		dev->stats.read.bytes, dev->stats.read.ops,
+		dev->stats.irqs);
+	size -= t;
+	next += t;
+
+	/* dump endpoint queues */
+	for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) {
+		struct pxa2xx_ep	*ep = &dev->ep [i];
+		struct pxa2xx_request	*req;
+		int			t;
+
+		if (i != 0) {
+			const struct usb_endpoint_descriptor	*d;
+
+			d = ep->desc;
+			if (!d)
+				continue;
+			tmp = *dev->ep [i].reg_udccs;
+			t = snprintf(next, size,
+				"%s max %d %s udccs %02x irqs %lu/%lu\n",
+				ep->ep.name, le16_to_cpu (d->wMaxPacketSize),
+				(ep->dma >= 0) ? "dma" : "pio", tmp,
+				ep->pio_irqs, ep->dma_irqs);
+			/* TODO translate all five groups of udccs bits! */
+
+		} else /* ep0 should only have one transfer queued */
+			t = snprintf(next, size, "ep0 max 16 pio irqs %lu\n",
+				ep->pio_irqs);
+		if (t <= 0 || t > size)
+			goto done;
+		size -= t;
+		next += t;
+
+		if (list_empty(&ep->queue)) {
+			t = snprintf(next, size, "\t(nothing queued)\n");
+			if (t <= 0 || t > size)
+				goto done;
+			size -= t;
+			next += t;
+			continue;
+		}
+		list_for_each_entry(req, &ep->queue, queue) {
+#ifdef	USE_DMA
+			if (ep->dma >= 0 && req->queue.prev == &ep->queue)
+				t = snprintf(next, size,
+					"\treq %p len %d/%d "
+					"buf %p (dma%d dcmd %08x)\n",
+					&req->req, req->req.actual,
+					req->req.length, req->req.buf,
+					ep->dma, DCMD(ep->dma)
+					// low 13 bits == bytes-to-go
+					);
+			else
+#endif
+				t = snprintf(next, size,
+					"\treq %p len %d/%d buf %p\n",
+					&req->req, req->req.actual,
+					req->req.length, req->req.buf);
+			if (t <= 0 || t > size)
+				goto done;
+			size -= t;
+			next += t;
+		}
+	}
+
+done:
+	local_irq_restore(flags);
+	*eof = 1;
+	return count - size;
+}
+
+#define create_proc_files() \
+	create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev)
+#define remove_proc_files() \
+	remove_proc_entry(proc_node_name, NULL)
+
+#else	/* !UDC_PROC_FILE */
+#define create_proc_files() do {} while (0)
+#define remove_proc_files() do {} while (0)
+
+#endif	/* UDC_PROC_FILE */
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * 	udc_disable - disable USB device controller
+ */
+static void udc_disable(struct pxa2xx_udc *dev)
+{
+	/* block all irqs */
+	udc_set_mask_UDCCR(UDCCR_SRM|UDCCR_REM);
+	UICR0 = UICR1 = 0xff;
+	UFNRH = UFNRH_SIM;
+
+	/* if hardware supports it, disconnect from usb */
+	make_usb_disappear();
+
+	udc_clear_mask_UDCCR(UDCCR_UDE);
+
+#ifdef	CONFIG_ARCH_PXA
+        /* Disable clock for USB device */
+        CKEN &= ~CKEN11_USB;
+#endif
+
+	ep0_idle (dev);
+	dev->gadget.speed = USB_SPEED_UNKNOWN;
+	LED_CONNECTED_OFF;
+}
+
+
+/*
+ * 	udc_reinit - initialize software state
+ */
+static void udc_reinit(struct pxa2xx_udc *dev)
+{
+	u32	i;
+
+	/* device/ep0 records init */
+	INIT_LIST_HEAD (&dev->gadget.ep_list);
+	INIT_LIST_HEAD (&dev->gadget.ep0->ep_list);
+	dev->ep0state = EP0_IDLE;
+
+	/* basic endpoint records init */
+	for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) {
+		struct pxa2xx_ep *ep = &dev->ep[i];
+
+		if (i != 0)
+			list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list);
+
+		ep->desc = 0;
+		ep->stopped = 0;
+		INIT_LIST_HEAD (&ep->queue);
+		ep->pio_irqs = ep->dma_irqs = 0;
+	}
+
+	/* the rest was statically initialized, and is read-only */
+}
+
+/* until it's enabled, this UDC should be completely invisible
+ * to any USB host.
+ */
+static void udc_enable (struct pxa2xx_udc *dev)
+{
+	udc_clear_mask_UDCCR(UDCCR_UDE);
+
+#ifdef	CONFIG_ARCH_PXA
+        /* Enable clock for USB device */
+        CKEN |= CKEN11_USB;
+#endif
+
+	/* try to clear these bits before we enable the udc */
+	udc_ack_int_UDCCR(UDCCR_SUSIR|/*UDCCR_RSTIR|*/UDCCR_RESIR);
+
+	ep0_idle(dev);
+	dev->gadget.speed = USB_SPEED_UNKNOWN;
+	dev->stats.irqs = 0;
+
+	/*
+	 * sequence taken from chapter 12.5.10, PXA250 AppProcDevManual:
+	 * - enable UDC
+	 * - if RESET is already in progress, ack interrupt
+	 * - unmask reset interrupt
+	 */
+	udc_set_mask_UDCCR(UDCCR_UDE);
+	if (!(UDCCR & UDCCR_UDA))
+		udc_ack_int_UDCCR(UDCCR_RSTIR);
+
+	if (dev->has_cfr /* UDC_RES2 is defined */) {
+		/* pxa255 (a0+) can avoid a set_config race that could
+		 * prevent gadget drivers from configuring correctly
+		 */
+		UDCCFR = UDCCFR_ACM;
+	} else {
+		/* "USB test mode" for pxa250 errata 40-42 (stepping a0, a1)
+		 * which could result in missing packets and interrupts.
+		 * supposedly one bit per endpoint, controlling whether it
+		 * double buffers or not; ACM/AREN bits fit into the holes.
+		 * zero bits (like USIR0_IRx) disable double buffering.
+		 */
+		UDC_RES1 = 0x00;
+		UDC_RES2 = 0x00;
+	}
+
+#ifdef	DISABLE_TEST_MODE
+	/* "test mode" seems to have become the default in later chip
+	 * revs, preventing double buffering (and invalidating docs).
+	 * this EXPERIMENT enables it for bulk endpoints by tweaking
+	 * undefined/reserved register bits (that other drivers clear).
+	 * Belcarra code comments noted this usage.
+	 */
+	if (fifo_mode & 1) {	/* IN endpoints */
+		UDC_RES1 |= USIR0_IR1|USIR0_IR6;
+		UDC_RES2 |= USIR1_IR11;
+	}
+	if (fifo_mode & 2) {	/* OUT endpoints */
+		UDC_RES1 |= USIR0_IR2|USIR0_IR7;
+		UDC_RES2 |= USIR1_IR12;
+	}
+#endif
+
+	/* caller must be able to sleep in order to cope
+	 * with startup transients.
+	 */
+	schedule_timeout(HZ/10);
+
+	/* enable suspend/resume and reset irqs */
+	udc_clear_mask_UDCCR(UDCCR_SRM | UDCCR_REM);
+
+	/* enable ep0 irqs */
+	UICR0 &= ~UICR0_IM0;
+
+	/* if hardware supports it, connect to usb and wait for host */
+	let_usb_appear();
+}
+
+
+/* when a driver is successfully registered, it will receive
+ * control requests including set_configuration(), which enables
+ * non-control requests.  then usb traffic follows until a
+ * disconnect is reported.  then a host may connect again, or
+ * the driver might get unbound.
+ */
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+{
+	struct pxa2xx_udc	*dev = the_controller;
+	int			retval;
+
+	if (!driver
+			|| driver->speed != USB_SPEED_FULL
+			|| !driver->bind
+			|| !driver->unbind
+			|| !driver->disconnect
+			|| !driver->setup)
+		return -EINVAL;
+	if (!dev)
+		return -ENODEV;
+	if (dev->driver)
+		return -EBUSY;
+
+	/* first hook up the driver ... */
+	dev->driver = driver;
+
+	retval = driver->bind(&dev->gadget);
+	if (retval) {
+		DMSG("bind to driver %s --> error %d\n",
+				driver->driver.name, retval);
+		dev->driver = 0;
+		return retval;
+	}
+
+	/* ... then enable host detection and ep0; and we're ready
+	 * for set_configuration as well as eventual disconnect.
+	 * NOTE:  this shouldn't power up until later.
+	 */
+	DMSG("registered gadget driver '%s'\n", driver->driver.name);
+	udc_enable(dev);
+	dump_state(dev);
+	return 0;
+}
+EXPORT_SYMBOL(usb_gadget_register_driver);
+
+static void
+stop_activity(struct pxa2xx_udc *dev, struct usb_gadget_driver *driver)
+{
+	int i;
+
+	/* don't disconnect drivers more than once */
+	if (dev->gadget.speed == USB_SPEED_UNKNOWN)
+		driver = 0;
+	dev->gadget.speed = USB_SPEED_UNKNOWN;
+
+	/* prevent new request submissions, kill any outstanding requests  */
+	for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) {
+		struct pxa2xx_ep *ep = &dev->ep[i];
+
+		ep->stopped = 1;
+		nuke(ep, -ESHUTDOWN);
+	}
+	del_timer_sync(&dev->timer);
+
+	/* report disconnect; the driver is already quiesced */
+	LED_CONNECTED_OFF;
+	if (driver)
+		driver->disconnect(&dev->gadget);
+
+	/* re-init driver-visible data structures */
+	udc_reinit(dev);
+}
+
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+	struct pxa2xx_udc	*dev = the_controller;
+
+	if (!dev)
+		return -ENODEV;
+	if (!driver || driver != dev->driver)
+		return -EINVAL;
+
+	local_irq_disable();
+	udc_disable(dev);
+	stop_activity(dev, driver);
+	local_irq_enable();
+
+	driver->unbind(&dev->gadget);
+	dev->driver = 0;
+
+	DMSG("unregistered gadget driver '%s'\n", driver->driver.name);
+	dump_state(dev);
+	return 0;
+}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef CONFIG_ARCH_LUBBOCK
+#ifdef LUBBOCK_USB_DISC_IRQ
+
+/* Lubbock can report connect or disconnect irqs.  Likely more hardware
+ * could support it as a timer callback.
+ *
+ * FIXME for better power management, keep the hardware powered down
+ * until a host is powering the link.  means scheduling work later
+ * in some task that can udc_enable().
+ */
+
+#define	enable_disconnect_irq() \
+	if (machine_is_lubbock()) { enable_irq(LUBBOCK_USB_DISC_IRQ); }
+#define	disable_disconnect_irq() \
+	if (machine_is_lubbock()) { disable_irq(LUBBOCK_USB_DISC_IRQ); }
+
+static irqreturn_t
+usb_connection_irq(int irq, void *_dev, struct pt_regs *r)
+{
+	struct pxa2xx_udc	*dev = _dev;
+
+	dev->stats.irqs++;
+	HEX_DISPLAY(dev->stats.irqs);
+
+	if (!is_usb_connected()) {
+		LED_CONNECTED_OFF;
+		disable_disconnect_irq();
+		/* report disconnect just once */
+		if (dev->gadget.speed != USB_SPEED_UNKNOWN) {
+			DMSG("disconnect %s\n",
+				dev->driver ? dev->driver->driver.name : 0);
+			stop_activity(dev, dev->driver);
+
+			// udc_disable (dev);
+			// no more udc irqs
+			// maybe "ACTION=disconnect /sbin/hotplug gadget".
+		}
+	} else if (dev->gadget.speed == USB_SPEED_UNKNOWN) {
+		LED_CONNECTED_ON;
+
+		DMSG("?? connect irq ??\n");
+
+		// if there's no driver bound, ignore; else
+		// udc_enable (dev);
+		// UDC irqs drive the rest.
+		// maybe "ACTION=connect /sbin/hotplug gadget".
+	}
+	return IRQ_HANDLED;
+}
+
+#endif
+#endif
+
+#ifndef	enable_disconnect_irq
+#warning USB disconnect() is not yet reported.
+#define	enable_disconnect_irq()		do {} while (0)
+#define	disable_disconnect_irq()	do {} while (0)
+#endif
+
+
+/*-------------------------------------------------------------------------*/
+
+static inline void clear_ep_state (struct pxa2xx_udc *dev)
+{
+	unsigned i;
+
+	/* hardware SET_{CONFIGURATION,INTERFACE} automagic resets endpoint
+	 * fifos, and pending transactions mustn't be continued in any case.
+	 */
+	for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++)
+		nuke(&dev->ep[i], -ECONNABORTED);
+}
+
+static void udc_watchdog(unsigned long _dev)
+{
+	struct pxa2xx_udc	*dev = (void *)_dev;
+
+	local_irq_disable();
+	if (dev->ep0state == EP0_STALL
+			&& (UDCCS0 & UDCCS0_FST) == 0
+			&& (UDCCS0 & UDCCS0_SST) == 0) {
+		UDCCS0 = UDCCS0_FST|UDCCS0_FTF;
+		DBG(DBG_VERBOSE, "ep0 re-stall\n");
+		start_watchdog(dev);
+	}
+	local_irq_enable();
+}
+
+static void handle_ep0 (struct pxa2xx_udc *dev)
+{
+	u32			udccs0 = UDCCS0;
+	struct pxa2xx_ep	*ep = &dev->ep [0];
+	struct pxa2xx_request	*req;
+	union {
+		struct usb_ctrlrequest	r;
+		u8			raw [8];
+		u32			word [2];
+	} u;
+
+	if (list_empty(&ep->queue))
+		req = 0;
+	else
+		req = list_entry(ep->queue.next, struct pxa2xx_request, queue);
+
+	/* clear stall status */
+	if (udccs0 & UDCCS0_SST) {
+		nuke(ep, -EPIPE);
+		UDCCS0 = UDCCS0_SST;
+		del_timer(&dev->timer);
+		ep0_idle(dev);
+	}
+
+	/* previous request unfinished?  non-error iff back-to-back ... */
+	if ((udccs0 & UDCCS0_SA) != 0 && dev->ep0state != EP0_IDLE) {
+		nuke(ep, 0);
+		del_timer(&dev->timer);
+		ep0_idle(dev);
+	}
+
+	switch (dev->ep0state) {
+	case EP0_IDLE:
+		/* late-breaking status? */
+		udccs0 = UDCCS0;
+
+		/* start control request? */
+		if (likely((udccs0 & (UDCCS0_OPR|UDCCS0_SA|UDCCS0_RNE))
+				== (UDCCS0_OPR|UDCCS0_SA|UDCCS0_RNE))) {
+			int i;
+
+			nuke (ep, -EPROTO);
+
+			/* read SETUP packet */
+			for (i = 0; i < 8; i++) {
+				if (unlikely(!(UDCCS0 & UDCCS0_RNE))) {
+bad_setup:
+					DMSG("SETUP %d!\n", i);
+					goto stall;
+				}
+				u.raw [i] = (u8) UDDR0;
+			}
+			if (unlikely((UDCCS0 & UDCCS0_RNE) != 0))
+				goto bad_setup;
+
+got_setup:
+			le16_to_cpus (&u.r.wValue);
+			le16_to_cpus (&u.r.wIndex);
+			le16_to_cpus (&u.r.wLength);
+
+			LED_EP0_ON;
+			DBG(DBG_VERBOSE, "SETUP %02x.%02x v%04x i%04x l%04x\n",
+				u.r.bRequestType, u.r.bRequest,
+				u.r.wValue, u.r.wIndex, u.r.wLength);
+
+			/* cope with automagic for some standard requests. */
+			dev->req_std = (u.r.bRequestType & USB_TYPE_MASK)
+						== USB_TYPE_STANDARD;
+			dev->req_config = 0;
+			dev->req_pending = 1;
+			switch (u.r.bRequest) {
+			/* hardware restricts gadget drivers here! */
+			case USB_REQ_SET_CONFIGURATION:
+				if (u.r.bRequestType == USB_RECIP_DEVICE) {
+					/* reflect hardware's automagic
+					 * up to the gadget driver.
+					 */
+config_change:
+					dev->req_config = 1;
+					clear_ep_state(dev);
+					/* if !has_cfr, there's no synch
+					 * else use AREN (later) not SA|OPR
+					 * USIR0_IR0 acts edge sensitive
+					 */
+				}
+				break;
+			/* ... and here, even more ... */
+			case USB_REQ_SET_INTERFACE:
+				if (u.r.bRequestType == USB_RECIP_INTERFACE) {
+					/* udc hardware is broken by design:
+					 *  - altsetting may only be zero;
+					 *  - hw resets all interfaces' eps;
+					 *  - ep reset doesn't include halt(?).
+					 */
+					DMSG("broken set_interface (%d/%d)\n",
+						u.r.wIndex, u.r.wValue);
+					goto config_change;
+				}
+				break;
+			/* hardware was supposed to hide this */
+			case USB_REQ_SET_ADDRESS:
+				if (u.r.bRequestType == USB_RECIP_DEVICE) {
+					ep0start(dev, 0, "address");
+					return;
+				}
+				break;
+			}
+
+			if (u.r.bRequestType & USB_DIR_IN)
+				dev->ep0state = EP0_IN_DATA_PHASE;
+			else
+				dev->ep0state = EP0_OUT_DATA_PHASE;
+
+			i = dev->driver->setup(&dev->gadget, &u.r);
+			if (i < 0) {
+				/* hardware automagic preventing STALL... */
+				if (dev->req_config) {
+					/* hardware sometimes neglects to tell
+					 * tell us about config change events,
+					 * so later ones may fail...
+					 */
+					WARN("config change %02x fail %d?\n",
+						u.r.bRequest, i);
+					return;
+					/* TODO experiment:  if has_cfr,
+					 * hardware didn't ACK; maybe we
+					 * could actually STALL!
+					 */
+				}
+				DBG(DBG_VERBOSE, "protocol STALL, "
+					"%02x err %d\n", UDCCS0, i);
+stall:
+				/* the watchdog timer helps deal with cases
+				 * where udc seems to clear FST wrongly, and
+				 * then NAKs instead of STALLing.
+				 */
+				ep0start(dev, UDCCS0_FST|UDCCS0_FTF, "stall");
+				start_watchdog(dev);
+				dev->ep0state = EP0_STALL;
+				LED_EP0_OFF;
+
+			/* deferred i/o == no response yet */
+			} else if (dev->req_pending) {
+				if (likely(dev->ep0state == EP0_IN_DATA_PHASE
+						|| dev->req_std || u.r.wLength))
+					ep0start(dev, 0, "defer");
+				else
+					ep0start(dev, UDCCS0_IPR, "defer/IPR");
+			}
+
+			/* expect at least one data or status stage irq */
+			return;
+
+		} else if (likely((udccs0 & (UDCCS0_OPR|UDCCS0_SA))
+				== (UDCCS0_OPR|UDCCS0_SA))) {
+			unsigned i;
+
+			/* pxa210/250 erratum 131 for B0/B1 says RNE lies.
+			 * still observed on a pxa255 a0.
+			 */
+			DBG(DBG_VERBOSE, "e131\n");
+			nuke(ep, -EPROTO);
+
+			/* read SETUP data, but don't trust it too much */
+			for (i = 0; i < 8; i++)
+				u.raw [i] = (u8) UDDR0;
+			if ((u.r.bRequestType & USB_RECIP_MASK)
+					> USB_RECIP_OTHER)
+				goto stall;
+			if (u.word [0] == 0 && u.word [1] == 0)
+				goto stall;
+			goto got_setup;
+		} else {
+			/* some random early IRQ:
+			 * - we acked FST
+			 * - IPR cleared
+			 * - OPR got set, without SA (likely status stage)
+			 */
+			UDCCS0 = udccs0 & (UDCCS0_SA|UDCCS0_OPR);
+		}
+		break;
+	case EP0_IN_DATA_PHASE:			/* GET_DESCRIPTOR etc */
+		if (udccs0 & UDCCS0_OPR) {
+			UDCCS0 = UDCCS0_OPR|UDCCS0_FTF;
+			DBG(DBG_VERBOSE, "ep0in premature status\n");
+			if (req)
+				done(ep, req, 0);
+			ep0_idle(dev);
+		} else /* irq was IPR clearing */ {
+			if (req) {
+				/* this IN packet might finish the request */
+				(void) write_ep0_fifo(ep, req);
+			} /* else IN token before response was written */
+		}
+		break;
+	case EP0_OUT_DATA_PHASE:		/* SET_DESCRIPTOR etc */
+		if (udccs0 & UDCCS0_OPR) {
+			if (req) {
+				/* this OUT packet might finish the request */
+				if (read_ep0_fifo(ep, req))
+					done(ep, req, 0);
+				/* else more OUT packets expected */
+			} /* else OUT token before read was issued */
+		} else /* irq was IPR clearing */ {
+			DBG(DBG_VERBOSE, "ep0out premature status\n");
+			if (req)
+				done(ep, req, 0);
+			ep0_idle(dev);
+		}
+		break;
+	case EP0_END_XFER:
+		if (req)
+			done(ep, req, 0);
+		/* ack control-IN status (maybe in-zlp was skipped)
+		 * also appears after some config change events.
+		 */
+		if (udccs0 & UDCCS0_OPR)
+			UDCCS0 = UDCCS0_OPR;
+		ep0_idle(dev);
+		break;
+	case EP0_STALL:
+		UDCCS0 = UDCCS0_FST;
+		break;
+	}
+	USIR0 = USIR0_IR0;
+}
+
+static void handle_ep(struct pxa2xx_ep *ep)
+{
+	struct pxa2xx_request	*req;
+	int			is_in = ep->bEndpointAddress & USB_DIR_IN;
+	int			completed;
+	u32			udccs, tmp;
+
+	do {
+		completed = 0;
+		if (likely (!list_empty(&ep->queue)))
+			req = list_entry(ep->queue.next,
+					struct pxa2xx_request, queue);
+		else
+			req = 0;
+
+		// TODO check FST handling
+
+		udccs = *ep->reg_udccs;
+		if (unlikely(is_in)) {	/* irq from TPC, SST, or (ISO) TUR */
+			tmp = UDCCS_BI_TUR;
+			if (likely(ep->bmAttributes == USB_ENDPOINT_XFER_BULK))
+				tmp |= UDCCS_BI_SST;
+			tmp &= udccs;
+			if (likely (tmp))
+				*ep->reg_udccs = tmp;
+			if (req && likely ((udccs & UDCCS_BI_TFS) != 0))
+				completed = write_fifo(ep, req);
+
+		} else {	/* irq from RPC (or for ISO, ROF) */
+			if (likely(ep->bmAttributes == USB_ENDPOINT_XFER_BULK))
+				tmp = UDCCS_BO_SST | UDCCS_BO_DME;
+			else
+				tmp = UDCCS_IO_ROF | UDCCS_IO_DME;
+			tmp &= udccs;
+			if (likely(tmp))
+				*ep->reg_udccs = tmp;
+
+			/* fifos can hold packets, ready for reading... */
+			if (likely(req != 0)) {
+#ifdef USE_OUT_DMA
+// TODO didn't yet debug out-dma.  this approach assumes
+// the worst about short packets and RPC; it might be better.
+
+				if (likely(ep->dma >= 0)) {
+					if (!(udccs & UDCCS_BO_RSP)) {
+						*ep->reg_udccs = UDCCS_BO_RPC;
+						ep->dma_irqs++;
+						return;
+					}
+				}
+#endif
+				completed = read_fifo(ep, req);
+			} else
+				pio_irq_disable (ep->bEndpointAddress);
+		}
+		ep->pio_irqs++;
+	} while (completed);
+}
+
+/*
+ *	pxa2xx_udc_irq - interrupt handler
+ *
+ * avoid delays in ep0 processing. the control handshaking isn't always
+ * under software control (pxa250c0 and the pxa255 are better), and delays
+ * could cause usb protocol errors.
+ */
+static irqreturn_t
+pxa2xx_udc_irq(int irq, void *_dev, struct pt_regs *r)
+{
+	struct pxa2xx_udc	*dev = _dev;
+	int			handled;
+
+	dev->stats.irqs++;
+	HEX_DISPLAY(dev->stats.irqs);
+	do {
+		u32		udccr = UDCCR;
+
+		handled = 0;
+
+		/* SUSpend Interrupt Request */
+		if (unlikely(udccr & UDCCR_SUSIR)) {
+			udc_ack_int_UDCCR(UDCCR_SUSIR);
+			handled = 1;
+			DBG(DBG_VERBOSE, "USB suspend%s\n", is_usb_connected()
+				? "" : "+disconnect");
+
+			if (!is_usb_connected())
+				stop_activity(dev, dev->driver);
+			else if (dev->gadget.speed != USB_SPEED_UNKNOWN
+					&& dev->driver
+					&& dev->driver->suspend)
+				dev->driver->suspend(&dev->gadget);
+			ep0_idle (dev);
+		}
+
+		/* RESume Interrupt Request */
+		if (unlikely(udccr & UDCCR_RESIR)) {
+			udc_ack_int_UDCCR(UDCCR_RESIR);
+			handled = 1;
+			DBG(DBG_VERBOSE, "USB resume\n");
+
+			if (dev->gadget.speed != USB_SPEED_UNKNOWN
+					&& dev->driver
+					&& dev->driver->resume
+					&& is_usb_connected())
+				dev->driver->resume(&dev->gadget);
+		}
+
+		/* ReSeT Interrupt Request - USB reset */
+		if (unlikely(udccr & UDCCR_RSTIR)) {
+			udc_ack_int_UDCCR(UDCCR_RSTIR);
+			handled = 1;
+
+			if ((UDCCR & UDCCR_UDA) == 0) {
+				DBG(DBG_VERBOSE, "USB reset start\n");
+				if (dev->gadget.speed != USB_SPEED_UNKNOWN)
+					disable_disconnect_irq();
+
+				/* reset driver and endpoints,
+				 * in case that's not yet done
+				 */
+				stop_activity (dev, dev->driver);
+
+			} else {
+				INFO("USB reset\n");
+				dev->gadget.speed = USB_SPEED_FULL;
+				LED_CONNECTED_ON;
+				memset(&dev->stats, 0, sizeof dev->stats);
+				/* driver and endpoints are still reset */
+				enable_disconnect_irq();
+			}
+
+		} else {
+			u32	usir0 = USIR0 & ~UICR0;
+			u32	usir1 = USIR1 & ~UICR1;
+			int	i;
+
+			if (unlikely (!usir0 && !usir1))
+				continue;
+
+			DBG(DBG_VERY_NOISY, "irq %02x.%02x\n", usir1, usir0);
+
+			/* control traffic */
+			if (usir0 & USIR0_IR0) {
+				dev->ep[0].pio_irqs++;
+				handle_ep0(dev);
+				handled = 1;
+			}
+
+			/* endpoint data transfers */
+			for (i = 0; i < 8; i++) {
+				u32	tmp = 1 << i;
+
+				if (i && (usir0 & tmp)) {
+					handle_ep(&dev->ep[i]);
+					USIR0 |= tmp;
+					handled = 1;
+				}
+				if (usir1 & tmp) {
+					handle_ep(&dev->ep[i+8]);
+					USIR1 |= tmp;
+					handled = 1;
+				}
+			}
+		}
+
+		/* we could also ask for 1 msec SOF (SIR) interrupts */
+
+	} while (handled);
+	return IRQ_HANDLED;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ *	cleanup - free resources allocated during init
+ */
+static void /*__exit and */ __init cleanup(void)
+{
+	struct pxa2xx_udc *dev = the_controller;
+
+	if (!dev)
+		return;
+
+	udc_disable(dev);
+	remove_proc_files();
+	usb_gadget_unregister_driver(dev->driver);
+	if (dev->got_irq) {
+		free_irq(IRQ_USB, dev);
+		dev->got_irq = 0;
+	}
+#ifdef	LUBBOCK_USB_DISC_IRQ
+	if (dev->got_disc) {
+		free_irq(LUBBOCK_USB_DISC_IRQ, dev);
+		dev->got_disc = 0;
+	}
+#endif
+	the_controller = 0;
+	release_mem_region(REGISTER_FIRST, REGISTER_LENGTH);
+}
+module_exit (cleanup);
+
+/* this uses load-time allocation and initialization (instead of
+ * doing it at run-time) to save code, eliminate fault paths, and
+ * be more obviously correct.
+ */
+static struct pxa2xx_udc memory = {
+	.gadget = {
+		.ops		= &pxa2xx_udc_ops,
+		.ep0		= &memory.ep[0].ep,
+		.name		= driver_name,
+		.dev = {
+			.bus_id		= "gadget",
+		},
+	},
+
+	/* control endpoint */
+	.ep[0] = {
+		.ep = {
+			.name		= ep0name,
+			.ops		= &pxa2xx_ep_ops,
+			.maxpacket	= EP0_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.reg_udccs	= &UDCCS0,
+		.reg_uddr	= &UDDR0,
+	},
+
+	/* first group of endpoints */
+	.ep[1] = {
+		.ep = {
+			.name		= "ep1in-bulk",
+			.ops		= &pxa2xx_ep_ops,
+			.maxpacket	= BULK_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= BULK_FIFO_SIZE,
+		.bEndpointAddress = USB_DIR_IN | 1,
+		.bmAttributes	= USB_ENDPOINT_XFER_BULK,
+		.reg_udccs	= &UDCCS1,
+		.reg_uddr	= &UDDR1,
+		drcmr (25)
+	},
+	.ep[2] = {
+		.ep = {
+			.name		= "ep2out-bulk",
+			.ops		= &pxa2xx_ep_ops,
+			.maxpacket	= BULK_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= BULK_FIFO_SIZE,
+		.bEndpointAddress = 2,
+		.bmAttributes	= USB_ENDPOINT_XFER_BULK,
+		.reg_udccs	= &UDCCS2,
+		.reg_ubcr	= &UBCR2,
+		.reg_uddr	= &UDDR2,
+		drcmr (26)
+	},
+#ifndef CONFIG_USB_PXA2XX_SMALL
+	.ep[3] = {
+		.ep = {
+			.name		= "ep3in-iso",
+			.ops		= &pxa2xx_ep_ops,
+			.maxpacket	= ISO_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= ISO_FIFO_SIZE,
+		.bEndpointAddress = USB_DIR_IN | 3,
+		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,
+		.reg_udccs	= &UDCCS3,
+		.reg_uddr	= &UDDR3,
+		drcmr (27)
+	},
+	.ep[4] = {
+		.ep = {
+			.name		= "ep4out-iso",
+			.ops		= &pxa2xx_ep_ops,
+			.maxpacket	= ISO_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= ISO_FIFO_SIZE,
+		.bEndpointAddress = 4,
+		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,
+		.reg_udccs	= &UDCCS4,
+		.reg_ubcr	= &UBCR4,
+		.reg_uddr	= &UDDR4,
+		drcmr (28)
+	},
+	.ep[5] = {
+		.ep = {
+			.name		= "ep5in-int",
+			.ops		= &pxa2xx_ep_ops,
+			.maxpacket	= INT_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= INT_FIFO_SIZE,
+		.bEndpointAddress = USB_DIR_IN | 5,
+		.bmAttributes	= USB_ENDPOINT_XFER_INT,
+		.reg_udccs	= &UDCCS5,
+		.reg_uddr	= &UDDR5,
+	},
+
+	/* second group of endpoints */
+	.ep[6] = {
+		.ep = {
+			.name		= "ep6in-bulk",
+			.ops		= &pxa2xx_ep_ops,
+			.maxpacket	= BULK_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= BULK_FIFO_SIZE,
+		.bEndpointAddress = USB_DIR_IN | 6,
+		.bmAttributes	= USB_ENDPOINT_XFER_BULK,
+		.reg_udccs	= &UDCCS6,
+		.reg_uddr	= &UDDR6,
+		drcmr (30)
+	},
+	.ep[7] = {
+		.ep = {
+			.name		= "ep7out-bulk",
+			.ops		= &pxa2xx_ep_ops,
+			.maxpacket	= BULK_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= BULK_FIFO_SIZE,
+		.bEndpointAddress = 7,
+		.bmAttributes	= USB_ENDPOINT_XFER_BULK,
+		.reg_udccs	= &UDCCS7,
+		.reg_ubcr	= &UBCR7,
+		.reg_uddr	= &UDDR7,
+		drcmr (31)
+	},
+	.ep[8] = {
+		.ep = {
+			.name		= "ep8in-iso",
+			.ops		= &pxa2xx_ep_ops,
+			.maxpacket	= ISO_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= ISO_FIFO_SIZE,
+		.bEndpointAddress = USB_DIR_IN | 8,
+		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,
+		.reg_udccs	= &UDCCS8,
+		.reg_uddr	= &UDDR8,
+		drcmr (32)
+	},
+	.ep[9] = {
+		.ep = {
+			.name		= "ep9out-iso",
+			.ops		= &pxa2xx_ep_ops,
+			.maxpacket	= ISO_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= ISO_FIFO_SIZE,
+		.bEndpointAddress = 9,
+		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,
+		.reg_udccs	= &UDCCS9,
+		.reg_ubcr	= &UBCR9,
+		.reg_uddr	= &UDDR9,
+		drcmr (33)
+	},
+	.ep[10] = {
+		.ep = {
+			.name		= "ep10in-int",
+			.ops		= &pxa2xx_ep_ops,
+			.maxpacket	= INT_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= INT_FIFO_SIZE,
+		.bEndpointAddress = USB_DIR_IN | 10,
+		.bmAttributes	= USB_ENDPOINT_XFER_INT,
+		.reg_udccs	= &UDCCS10,
+		.reg_uddr	= &UDDR10,
+	},
+
+	/* third group of endpoints */
+	.ep[11] = {
+		.ep = {
+			.name		= "ep11in-bulk",
+			.ops		= &pxa2xx_ep_ops,
+			.maxpacket	= BULK_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= BULK_FIFO_SIZE,
+		.bEndpointAddress = USB_DIR_IN | 11,
+		.bmAttributes	= USB_ENDPOINT_XFER_BULK,
+		.reg_udccs	= &UDCCS11,
+		.reg_uddr	= &UDDR11,
+		drcmr (35)
+	},
+	.ep[12] = {
+		.ep = {
+			.name		= "ep12out-bulk",
+			.ops		= &pxa2xx_ep_ops,
+			.maxpacket	= BULK_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= BULK_FIFO_SIZE,
+		.bEndpointAddress = 12,
+		.bmAttributes	= USB_ENDPOINT_XFER_BULK,
+		.reg_udccs	= &UDCCS12,
+		.reg_ubcr	= &UBCR12,
+		.reg_uddr	= &UDDR12,
+		drcmr (36)
+	},
+	.ep[13] = {
+		.ep = {
+			.name		= "ep13in-iso",
+			.ops		= &pxa2xx_ep_ops,
+			.maxpacket	= ISO_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= ISO_FIFO_SIZE,
+		.bEndpointAddress = USB_DIR_IN | 13,
+		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,
+		.reg_udccs	= &UDCCS13,
+		.reg_uddr	= &UDDR13,
+		drcmr (37)
+	},
+	.ep[14] = {
+		.ep = {
+			.name		= "ep14out-iso",
+			.ops		= &pxa2xx_ep_ops,
+			.maxpacket	= ISO_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= ISO_FIFO_SIZE,
+		.bEndpointAddress = 14,
+		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,
+		.reg_udccs	= &UDCCS14,
+		.reg_ubcr	= &UBCR14,
+		.reg_uddr	= &UDDR14,
+		drcmr (38)
+	},
+	.ep[15] = {
+		.ep = {
+			.name		= "ep15in-int",
+			.ops		= &pxa2xx_ep_ops,
+			.maxpacket	= INT_FIFO_SIZE,
+		},
+		.dev		= &memory,
+		.fifo_size	= INT_FIFO_SIZE,
+		.bEndpointAddress = USB_DIR_IN | 15,
+		.bmAttributes	= USB_ENDPOINT_XFER_INT,
+		.reg_udccs	= &UDCCS15,
+		.reg_uddr	= &UDDR15,
+	},
+#endif /* !CONFIG_USB_PXA2XX_SMALL */
+};
+
+#define CP15R0_VENDOR_MASK	0xffffe000
+
+#if	defined(CONFIG_ARCH_PXA)
+#define CP15R0_XSCALE_VALUE	0x69052000	/* intel/arm/xscale */
+
+#elif	defined(CONFIG_ARCH_IXP425)
+#define CP15R0_XSCALE_VALUE	0x69054000	/* intel/arm/ixp425 */
+
+#endif
+
+#define CP15R0_PROD_MASK	0x000003f0
+#define PXA25x			0x00000100	/* and PXA26x */
+#define PXA210			0x00000120
+
+#define CP15R0_REV_MASK		0x0000000f
+
+#define CP15R0_PRODREV_MASK	(CP15R0_PROD_MASK | CP15R0_REV_MASK)
+
+#define PXA255_A0		0x00000106	/* or PXA260_B1 */
+#define PXA250_C0		0x00000105	/* or PXA26x_B0 */
+#define PXA250_B2		0x00000104
+#define PXA250_B1		0x00000103	/* or PXA260_A0 */
+#define PXA250_B0		0x00000102
+#define PXA250_A1		0x00000101
+#define PXA250_A0		0x00000100
+
+#define PXA210_C0		0x00000125
+#define PXA210_B2		0x00000124
+#define PXA210_B1		0x00000123
+#define PXA210_B0		0x00000122
+
+#define IXP425_A0		0x000001c1
+
+/*
+ * 	init - allocate resources
+ */
+static int __init init(void)
+{
+	struct pxa2xx_udc *dev;
+	int retval, out_dma = 1;
+	u32 chiprev;
+
+	printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION);
+
+	/* insist on Intel/ARM/XScale */
+	asm("mrc%? p15, 0, %0, c0, c0" : "=r" (chiprev));
+	if ((chiprev & CP15R0_VENDOR_MASK) != CP15R0_XSCALE_VALUE) {
+		printk(KERN_ERR "%s: not XScale!\n", driver_name);
+		return -ENODEV;
+	}
+
+	/* allocate resources */
+	if (!request_mem_region(REGISTER_FIRST, REGISTER_LENGTH, driver_name))
+		return -EBUSY;
+
+	/* initialize data */
+	dev = &memory;
+
+	init_timer(&dev->timer);
+	dev->timer.function = udc_watchdog;
+	dev->timer.data = (unsigned long) dev;
+
+	/* trigger chiprev-specific logic */
+	switch (chiprev & CP15R0_PRODREV_MASK) {
+#if	defined(CONFIG_ARCH_PXA)
+	case PXA255_A0:
+		dev->has_cfr = 1;
+		break;
+	case PXA250_A0:
+	case PXA250_A1:
+		/* A0/A1 "not released"; ep 13, 15 unusable */
+		/* fall through */
+	case PXA250_B2: case PXA210_B2:
+	case PXA250_B1: case PXA210_B1:
+	case PXA250_B0: case PXA210_B0:
+		out_dma = 0;
+		/* fall through */
+	case PXA250_C0: case PXA210_C0:
+		break;
+#elif	defined(CONFIG_ARCH_IXP425)
+	case IXP425_A0:
+		out_dma = 0;
+		break;
+#endif
+	default:
+		out_dma = 0;
+		printk(KERN_ERR "%s: unrecognized processor: %08x\n",
+			driver_name, chiprev);
+		return -ENODEV;
+	}
+
+	pr_debug("%s: IRQ %d%s%s%s\n", driver_name, IRQ_USB,
+		dev->has_cfr ? "" : " (!cfr)",
+		out_dma ? "" : " (broken dma-out)",
+		SIZE_STR DMASTR
+		);
+
+#ifdef	USE_DMA
+#ifndef	USE_OUT_DMA
+	out_dma = 0;
+#endif
+	/* pxa 250 erratum 130 prevents using OUT dma (fixed C0) */
+	if (!out_dma) {
+		DMSG("disabled OUT dma\n");
+		dev->ep[ 2].reg_drcmr = dev->ep[ 4].reg_drcmr = 0;
+		dev->ep[ 7].reg_drcmr = dev->ep[ 9].reg_drcmr = 0;
+		dev->ep[12].reg_drcmr = dev->ep[14].reg_drcmr = 0;
+	}
+#endif
+
+	the_controller = dev;
+	udc_disable(dev);
+	udc_reinit(dev);
+
+	/* irq setup after old hardware state is cleaned up */
+	retval = request_irq(IRQ_USB, pxa2xx_udc_irq,
+			SA_INTERRUPT, driver_name, dev);
+	if (retval != 0) {
+		printk(KERN_ERR "%s: can't get irq %i, err %d\n",
+			driver_name, IRQ_USB, retval);
+		return -EBUSY;
+	}
+	dev->got_irq = 1;
+
+#ifdef LUBBOCK_USB_DISC_IRQ
+	if (machine_is_lubbock()) {
+		disable_irq(LUBBOCK_USB_DISC_IRQ);
+		retval = request_irq(LUBBOCK_USB_DISC_IRQ,
+				usb_connection_irq,
+				SA_INTERRUPT | SA_SAMPLE_RANDOM,
+				driver_name, dev);
+		if (retval != 0) {
+			enable_irq(LUBBOCK_USB_DISC_IRQ);
+			printk(KERN_ERR "%s: can't get irq %i, err %d\n",
+				driver_name, LUBBOCK_USB_DISC_IRQ, retval);
+			cleanup();
+			return retval;
+		}
+		dev->got_disc = 1;
+	}
+#endif
+
+	create_proc_files();
+	return 0;
+}
+module_init (init);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Frank Becker, Robert Schwebel, David Brownell");
+MODULE_LICENSE("GPL");
+
diff -urN linux-2.4.29/drivers/usb/gadget/pxa2xx_udc.h linux-2.4.29-uc1/drivers/usb/gadget/pxa2xx_udc.h
--- linux-2.4.29/drivers/usb/gadget/pxa2xx_udc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/usb/gadget/pxa2xx_udc.h	2005-06-14 02:12:07.000000000 +0100
@@ -0,0 +1,528 @@
+/*
+ * linux/drivers/usb/gadget/pxa2xx_udc.h
+ * Intel PXA2xx on-chip full speed USB device controller
+ * 
+ * Copyright (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
+ * Copyright (C) 2003 David Brownell
+ * Copyright (C) 2003 Joshua Wise
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+#ifndef __LINUX_USB_GADGET_PXA2XX_H
+#define __LINUX_USB_GADGET_PXA2XX_H
+
+#include <linux/types.h>
+
+/*-------------------------------------------------------------------------*/
+
+/* pxa2xx has this (move to include/asm-arm/arch-pxa/pxa-regs.h) */
+#define UFNRH_SIR	(1 << 7)	/* SOF interrupt request */
+#define UFNRH_SIM	(1 << 6)	/* SOF interrupt mask */
+#define UFNRH_IPE14	(1 << 5)	/* ISO packet error, ep14 */
+#define UFNRH_IPE9	(1 << 4)	/* ISO packet error, ep9 */
+#define UFNRH_IPE4	(1 << 3)	/* ISO packet error, ep4 */
+
+/* pxa255 has this (move to include/asm-arm/arch-pxa/pxa-regs.h) */
+#define	UDCCFR		UDC_RES2	/* UDC Control Function Register */
+#define UDCCFR_AREN	(1 << 7)	/* ACK response enable (now) */
+#define UDCCFR_ACM	(1 << 2)	/* ACK control mode (wait for AREN) */
+
+/* for address space reservation */
+#define	REGISTER_FIRST	((unsigned long)(&UDCCR))
+#define	REGISTER_LAST	((unsigned long)(&UDDR14))	/* not UDDR15! */
+#define REGISTER_LENGTH	((REGISTER_LAST - REGISTER_FIRST) + 4)
+
+/*-------------------------------------------------------------------------*/
+
+struct pxa2xx_udc;
+
+struct pxa2xx_ep {
+	struct usb_ep				ep;
+	struct pxa2xx_udc			*dev;
+
+	const struct usb_endpoint_descriptor	*desc;
+	struct list_head			queue;
+	unsigned long				pio_irqs;
+	unsigned long				dma_irqs;
+	short					dma; 
+
+	unsigned short				fifo_size;
+	u8					bEndpointAddress;
+	u8					bmAttributes;
+
+	unsigned				stopped : 1;
+	unsigned				dma_fixup : 1;
+							 
+	/* UDCCS = UDC Control/Status for this EP
+	 * UBCR = UDC Byte Count Remaining (contents of OUT fifo)
+	 * UDDR = UDC Endpoint Data Register (the fifo)
+	 * DRCM = DMA Request Channel Map
+	 */
+	volatile u32				*reg_udccs;
+	volatile u32				*reg_ubcr;
+	volatile u32				*reg_uddr;
+#ifdef USE_DMA
+	volatile u32				*reg_drcmr;
+#define	drcmr(n)  .reg_drcmr = & DRCMR ## n ,
+#else
+#define	drcmr(n)  
+#endif
+};
+
+struct pxa2xx_request {
+	struct usb_request			req;
+	struct list_head			queue;
+};
+
+enum ep0_state { 
+	EP0_IDLE,
+	EP0_IN_DATA_PHASE,
+	EP0_OUT_DATA_PHASE,
+	EP0_END_XFER,
+	EP0_STALL,
+};
+
+#define EP0_FIFO_SIZE	((unsigned)16)
+#define BULK_FIFO_SIZE	((unsigned)64)
+#define ISO_FIFO_SIZE	((unsigned)256)
+#define INT_FIFO_SIZE	((unsigned)8)
+
+struct udc_stats {
+	struct ep0stats {
+		unsigned long		ops;
+		unsigned long		bytes;
+	} read, write;
+	unsigned long			irqs;
+};
+
+#ifdef CONFIG_USB_PXA2XX_SMALL
+/* when memory's tight, SMALL config saves code+data.  */
+#undef	USE_DMA
+#define	PXA_UDC_NUM_ENDPOINTS	3
+#endif
+
+#ifndef	PXA_UDC_NUM_ENDPOINTS
+#define	PXA_UDC_NUM_ENDPOINTS	16
+#endif
+
+struct pxa2xx_udc {
+	struct usb_gadget			gadget;
+	struct usb_gadget_driver		*driver;
+
+	enum ep0_state				ep0state;
+	struct udc_stats			stats;
+	unsigned				got_irq : 1,
+						got_disc : 1,
+						has_cfr : 1,
+						req_pending : 1,
+						req_std : 1,
+						req_config : 1;
+
+#define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200))
+	struct timer_list			timer;
+
+	struct pxa2xx_ep			ep [PXA_UDC_NUM_ENDPOINTS];
+};
+
+/* 2.5 changes ... */
+
+#ifndef container_of
+#define container_of    list_entry
+#endif
+
+#ifndef WARN_ON
+#define WARN_ON BUG_ON
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+/* please keep machine-specific defines in alphabetical order. */
+
+// CONFIG_ARCH_ADI_COYOTE behaves
+
+#ifdef CONFIG_ARCH_E7XX
+#  include <asm/arch/e7xx-gpio.h>
+#endif
+
+#ifdef CONFIG_ARCH_H1900
+#  include <asm/arch/h1900-gpio.h>
+#endif
+
+#ifdef CONFIG_ARCH_H3900
+#  include <asm/arch/h3900-gpio.h>
+#endif
+
+#ifdef CONFIG_ARCH_H5400
+#  include <asm/arch/h5400-gpio.h>
+#endif
+
+#ifdef CONFIG_ARCH_INNOKOM
+#include <asm/arch/innokom.h>
+#endif
+
+#ifdef CONFIG_ARCH_LUBBOCK
+#include <asm/arch/lubbock.h>
+/* lubbock can also report usb connect/disconnect irqs */
+
+#ifdef DEBUG
+#define HEX_DISPLAY(n)	if (machine_is_lubbock()) { LUB_HEXLED = (n); }
+
+#define LED_CONNECTED_ON	if (machine_is_lubbock()) { \
+	DISCRETE_LED_ON(D26); }
+#define LED_CONNECTED_OFF	if(machine_is_lubbock()) { \
+	DISCRETE_LED_OFF(D26); LUB_HEXLED = 0; }
+#define LED_EP0_ON	if (machine_is_lubbock()) { DISCRETE_LED_ON(D25); }
+#define LED_EP0_OFF	if (machine_is_lubbock()) { DISCRETE_LED_OFF(D25); }
+#endif /* DEBUG */
+
+#endif
+
+#ifdef CONFIG_ARCH_PXA_CORGI
+/* Sharp Zaurus C-700, C-750, C-760, C-860 */
+#define	CORGI_CONNECT_GPIO	45
+/* use the ARM-Linux registered symbol, not a Lineo-private one */
+#define CONFIG_MACH_CORGI
+#endif
+
+#ifdef CONFIG_ARCH_PXA_POODLE
+/* Sharp B-500, SL-5600 */
+#define	POODLE_CONNECT_GPIO	20
+/* use the ARM-Linux registered symbol, not a Lineo-private one */
+#define CONFIG_MACH_POODLE
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+/* LEDs are only for debug */
+#ifndef HEX_DISPLAY
+#define HEX_DISPLAY(n)		do {} while(0)
+#endif
+
+#ifndef LED_CONNECTED_ON
+#define LED_CONNECTED_ON	do {} while(0)
+#define LED_CONNECTED_OFF	do {} while(0)
+#endif
+#ifndef LED_EP0_ON
+#define LED_EP0_ON		do {} while (0)
+#define LED_EP0_OFF		do {} while (0)
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+static struct pxa2xx_udc *the_controller;
+
+/* one GPIO should be used to detect host disconnect */
+static int is_usb_connected(void)
+{
+	static int first = 0;
+	
+	// CONFIG_ARCH_ADI_COYOTE cannot detect or force disconnect
+#ifdef CONFIG_ARCH_E7XX
+	if (machine_is_e7xx())
+		return (GPLR(GPIO_E7XX_USB_DISC)
+				& GPIO_bit(GPIO_E7XX_USB_DISC));
+#endif
+#if 0
+#ifdef CONFIG_ARCH_H1900
+	if (machine_is_h1900())
+		return (!(GPLR(GPIO_NR_H1900_USB_DETECT_N)
+				& GPIO_bit(GPIO_NR_H1900_USB_DETECT_N)));
+#endif
+#ifdef CONFIG_ARCH_H3900
+	if (machine_is_h3900())
+		return 1;
+#endif
+#ifdef CONFIG_ARCH_H5400
+	// h5400 ... ?
+#endif
+#endif
+#ifdef CONFIG_ARCH_INNOKOM
+	if (machine_is_innokom())
+		return (GPLR(GPIO_INNOKOM_USB_DISC)
+				& GPIO_bit(GPIO_INNOKOM_USB_DISC));
+#endif
+#ifdef CONFIG_ARCH_LUBBOCK
+	if (machine_is_lubbock())
+		return ((LUB_MISC_RD & (1 << 9)) == 0);
+#endif
+	// Sharp's sources didn't show a corgi or poodle hook
+
+	if (!first) {
+		pr_info("%s: can't check host connect\n", driver_name);
+		first++;
+	}
+	return 1;
+}
+
+static int disc_first = 0;
+
+/* one GPIO should force the host to see this device (or not) */
+static void make_usb_disappear(void)
+{
+	// CONFIG_ARCH_ADI_COYOTE cannot detect or force disconnect
+#ifdef CONFIG_ARCH_E7XX
+	if (machine_is_e7xx()) {
+		GPSR(GPIO_E7XX_USB_PULLUP) = GPIO_bit(GPIO_E7XX_USB_PULLUP);
+		return;
+	}
+#endif
+	// h1900 ... ?
+#ifdef CONFIG_ARCH_H3900
+	if (machine_is_h3900()) {
+		GPDR0 &= ~GPIO_H3900_USBP_PULLUP;
+		return;
+	}
+#endif
+#ifdef CONFIG_ARCH_H5400
+	if (machine_is_h5400()) {
+		GPDR(GPIO_NR_H5400_USB_PULLUP) &=
+					~GPIO_bit(GPIO_NR_H5400_USB_PULLUP);
+		return;
+	}
+#endif
+#ifdef CONFIG_ARCH_INNOKOM
+	if (machine_is_innokom()) {
+		GPSR(GPIO_INNOKOM_USB_ONOFF) = GPIO_bit(GPIO_INNOKOM_USB_ONOFF);
+		printk("innokom: disappear\n");
+		udelay(5);
+		return;
+	}
+#endif
+#ifdef CONFIG_ARCH_CSB226
+	if (machine_is_csb226()) {
+		GPCR0 |= 0x00000080;
+		printk("csb226: disappear\n");
+		udelay(5);
+		return;
+	}
+#endif
+	// lubbock has no D+ pullup
+#ifdef CONFIG_MACH_CORGI
+	if (machine_is_corgi()) {
+		GPDR(CORGI_CONNECT_GPIO) |= GPIO_bit(CORGI_CONNECT_GPIO);
+		GPCR(CORGI_CONNECT_GPIO) = GPIO_bit(CORGI_CONNECT_GPIO);
+	}
+#endif
+#ifdef CONFIG_MACH_POODLE
+	if (machine_is_poodle()) {
+		GPDR(POODLE_CONNECT_GPIO) |= GPIO_bit(POODLE_CONNECT_GPIO);
+		GPCR(POODLE_CONNECT_GPIO) = GPIO_bit(POODLE_CONNECT_GPIO);
+	}
+#endif
+
+	if (!disc_first) {
+		pr_info("%s: can't force usb disconnect\n", driver_name);
+		disc_first++;
+	}
+}
+
+static void let_usb_appear(void)
+{
+	// CONFIG_ARCH_ADI_COYOTE cannot detect or force disconnect
+#ifdef CONFIG_ARCH_E7XX
+	if (machine_is_e7xx()) {
+		GPCR(GPIO_E7XX_USB_PULLUP) = GPIO_bit(GPIO_E7XX_USB_PULLUP);
+		return;
+	}
+#endif
+	// h1900 ... ?
+#ifdef CONFIG_ARCH_H3900
+	if (machine_is_h3900()) {
+		GPDR0 |= GPIO_H3900_USBP_PULLUP;
+		GPSR0 |= GPIO_H3900_USBP_PULLUP;
+		return;
+	}
+#endif
+#ifdef CONFIG_ARCH_H5400
+	if (machine_is_h5400()) {
+		GPDR(GPIO_NR_H5400_USB_PULLUP) |=
+					GPIO_bit(GPIO_NR_H5400_USB_PULLUP);
+		return;
+	}
+#endif
+#ifdef CONFIG_ARCH_INNOKOM
+	if (machine_is_innokom()) {
+		GPCR(GPIO_INNOKOM_USB_ONOFF) = GPIO_bit(GPIO_INNOKOM_USB_ONOFF);
+		printk("innokom: appear\n");
+		udelay(5);
+		return;
+	}
+#endif
+#ifdef CONFIG_ARCH_CSB226
+	if (machine_is_csb226()) {
+		GPDR0 |= 0x00000080;
+		GPSR0 |= 0x00000080;
+		printk("csb226: appear\n");
+		udelay(5);
+		return;
+	}
+#endif
+	// lubbock has no D+ pullup
+#ifdef CONFIG_MACH_CORGI
+	if (machine_is_corgi()) {
+		GPDR(CORGI_CONNECT_GPIO) |= GPIO_bit(CORGI_CONNECT_GPIO);
+		GPSR(CORGI_CONNECT_GPIO) = GPIO_bit(CORGI_CONNECT_GPIO);
+	}
+#endif
+#ifdef CONFIG_MACH_POODLE
+	if (machine_is_poodle()) {
+		GPDR(POODLE_CONNECT_GPIO) |= GPIO_bit(POODLE_CONNECT_GPIO);
+		GPSR(POODLE_CONNECT_GPIO) = GPIO_bit(POODLE_CONNECT_GPIO);
+	}
+#endif
+
+	if (!disc_first) {
+		pr_info("%s: can't force usb disconnect\n", driver_name);
+		disc_first++;
+	}
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* LEDs are only for debug */
+#ifndef LED_CONNECTED_ON
+#define LED_CONNECTED_ON	do {} while(0)
+#define LED_CONNECTED_OFF	do {} while(0)
+#endif
+#ifndef LED_EP0_ON
+#define LED_EP0_ON		do {} while (0)
+#define LED_EP0_OFF		do {} while (0)
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Debugging support vanishes in non-debug builds.  DBG_NORMAL should be
+ * mostly silent during normal use/testing, with no timing side-effects.
+ */
+#define DBG_NORMAL	1	/* error paths, device state transitions */
+#define DBG_VERBOSE	2	/* add some success path trace info */
+#define DBG_NOISY	3	/* ... even more: request level */
+#define DBG_VERY_NOISY	4	/* ... even more: packet level */
+
+#ifdef DEBUG
+
+static const char *state_name[] = {
+	"EP0_IDLE",
+	"EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE",
+	"EP0_END_XFER", "EP0_STALL"
+};
+
+#define DMSG(stuff...) printk(KERN_DEBUG "udc: " stuff)
+
+#ifdef VERBOSE
+#    define UDC_DEBUG DBG_VERBOSE
+#else
+#    define UDC_DEBUG DBG_NORMAL
+#endif
+
+static void __attribute__ ((__unused__))
+dump_udccr(const char *label)
+{
+	u32	udccr = UDCCR;
+	DMSG("%s %02X =%s%s%s%s%s%s%s%s\n",
+		label, udccr,
+		(udccr & UDCCR_REM) ? " rem" : "",
+		(udccr & UDCCR_RSTIR) ? " rstir" : "",
+		(udccr & UDCCR_SRM) ? " srm" : "",
+		(udccr & UDCCR_SUSIR) ? " susir" : "",
+		(udccr & UDCCR_RESIR) ? " resir" : "",
+		(udccr & UDCCR_RSM) ? " rsm" : "",
+		(udccr & UDCCR_UDA) ? " uda" : "",
+		(udccr & UDCCR_UDE) ? " ude" : "");
+}
+
+static void __attribute__ ((__unused__))
+dump_udccs0(const char *label)
+{
+	u32		udccs0 = UDCCS0;
+
+	DMSG("%s %s %02X =%s%s%s%s%s%s%s%s\n",
+		label, state_name[the_controller->ep0state], udccs0,
+		(udccs0 & UDCCS0_SA) ? " sa" : "",
+		(udccs0 & UDCCS0_RNE) ? " rne" : "",
+		(udccs0 & UDCCS0_FST) ? " fst" : "",
+		(udccs0 & UDCCS0_SST) ? " sst" : "",
+		(udccs0 & UDCCS0_DRWF) ? " dwrf" : "",
+		(udccs0 & UDCCS0_FTF) ? " ftf" : "",
+		(udccs0 & UDCCS0_IPR) ? " ipr" : "",
+		(udccs0 & UDCCS0_OPR) ? " opr" : "");
+}
+
+static void __attribute__ ((__unused__))
+dump_state(struct pxa2xx_udc *dev)
+{
+	u32		tmp;
+	unsigned	i;
+
+	DMSG("%s %s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n",
+		is_usb_connected() ? "host " : "disconnected",
+		state_name[dev->ep0state],
+		UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL);
+	dump_udccr("udccr");
+	if (dev->has_cfr) {
+		tmp = UDCCFR;
+		DMSG("udccfr %02X =%s%s\n", tmp,
+			(tmp & UDCCFR_AREN) ? " aren" : "",
+			(tmp & UDCCFR_ACM) ? " acm" : "");
+	}
+
+	if (!dev->driver) {
+		DMSG("no gadget driver bound\n");
+		return;
+	} else
+		DMSG("ep0 driver '%s'\n", dev->driver->driver.name);
+	
+	if (!is_usb_connected())
+		return;
+
+	dump_udccs0 ("udccs0");
+	DMSG("ep0 IN %lu/%lu, OUT %lu/%lu\n",
+		dev->stats.write.bytes, dev->stats.write.ops,
+		dev->stats.read.bytes, dev->stats.read.ops);
+
+	for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++) {
+		if (dev->ep [i].desc == 0)
+			continue;
+		DMSG ("udccs%d = %02x\n", i, *dev->ep->reg_udccs);
+	}
+}
+
+#else
+
+#define DMSG(stuff...)		do{}while(0)
+
+#define	dump_udccr(x)	do{}while(0)
+#define	dump_udccs0(x)	do{}while(0)
+#define	dump_state(x)	do{}while(0)
+
+#define UDC_DEBUG ((unsigned)0)
+
+#endif
+
+#define DBG(lvl, stuff...) do{if ((lvl) <= UDC_DEBUG) DMSG(stuff);}while(0)
+
+#define WARN(stuff...) printk(KERN_WARNING "udc: " stuff)
+#define INFO(stuff...) printk(KERN_INFO "udc: " stuff)
+
+
+/* 2.4 backport support */
+#define irqreturn_t	void
+#define	IRQ_HANDLED
+
+
+#endif /* __LINUX_USB_GADGET_PXA2XX_H */
diff -urN linux-2.4.29/drivers/usb/hcd.c linux-2.4.29-uc1/drivers/usb/hcd.c
--- linux-2.4.29/drivers/usb/hcd.c	2004-04-14 14:05:32.000000000 +0100
+++ linux-2.4.29-uc1/drivers/usb/hcd.c	2005-06-14 02:12:06.000000000 +0100
@@ -49,6 +49,11 @@
 #include <asm/system.h>
 #include <asm/unaligned.h>
 
+#ifdef CONFIG_PCI
+#define HCD_PDEV(hcd) hcd->pdev
+#else
+#define HCD_PDEV(hcd) NULL
+#endif
 
 /*-------------------------------------------------------------------------*/
 
@@ -662,7 +667,9 @@
 	pci_set_drvdata(dev, hcd);
 	hcd->driver = driver;
 	hcd->description = driver->description;
+#ifdef CONFIG_PCI
 	hcd->pdev = dev;
+#endif
 	printk (KERN_INFO "%s %s: %s\n",
 			hcd->description,  dev->slot_name, dev->name);
 
@@ -1208,13 +1215,13 @@
 	} else {
 		if (usb_pipecontrol (urb->pipe))
 			urb->setup_dma = pci_map_single (
-					hcd->pdev,
+					HCD_PDEV(hcd),
 					urb->setup_packet,
 					sizeof (struct usb_ctrlrequest),
 					PCI_DMA_TODEVICE);
 		if (urb->transfer_buffer_length != 0)
 			urb->transfer_dma = pci_map_single (
-					hcd->pdev,
+					HCD_PDEV(hcd),
 					urb->transfer_buffer,
 					urb->transfer_buffer_length,
 					usb_pipein (urb->pipe)
@@ -1490,12 +1497,12 @@
 	
 	/* For 2.4, don't unmap bounce buffer if it's a root hub operation. */
 	if (usb_pipecontrol (urb->pipe) && !is_root_hub_operation)
-		pci_unmap_single (hcd->pdev, urb->setup_dma,
+		pci_unmap_single (HCD_PDEV(hcd), urb->setup_dma,
 				sizeof (struct usb_ctrlrequest),
 				PCI_DMA_TODEVICE);
 
 	if ((urb->transfer_buffer_length != 0) && !is_root_hub_operation)
-		pci_unmap_single (hcd->pdev, urb->transfer_dma,
+		pci_unmap_single (HCD_PDEV(hcd), urb->transfer_dma,
 				urb->transfer_buffer_length,
 				usb_pipein (urb->pipe)
 				    ? PCI_DMA_FROMDEVICE
diff -urN linux-2.4.29/drivers/usb/host/Config.in linux-2.4.29-uc1/drivers/usb/host/Config.in
--- linux-2.4.29/drivers/usb/host/Config.in	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-uc1/drivers/usb/host/Config.in	2005-06-14 02:12:07.000000000 +0100
@@ -12,8 +12,17 @@
    define_bool CONFIG_USB_UHCI_ALT n
 fi
 dep_tristate '  OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB
-if [ "$CONFIG_ARM" = "y" -o "$CONFIG_X86" = "y" -a "$CONFIG_X86_64" != "y" ]; then
-   # Cypress embedded USB controller on StrongARM or on x86 in PC/104
-   dep_tristate '  SL811HS Alternate (x86, StrongARM, isosynchronous mode)' CONFIG_USB_SL811HS_ALT $CONFIG_USB $CONFIG_EXPERIMENTAL
-   dep_tristate '  SL811HS (x86, StrongARM) support, old driver' CONFIG_USB_SL811HS $CONFIG_USB $CONFIG_EXPERIMENTAL
+dep_tristate '  isp1161 (Philips) support' CONFIG_USB_ISP116x $CONFIG_USB
+
+if [ "$CONFIG_ARM" = "y" -o "$CONFIG_COLDFIRE" = "y" -o "$CONFIG_X86" = "y" -a "$CONFIG_X86_64" != "y" ]; then
+   # Cypress embedded USB controller on StrongARM or on Coldfire or on x86 in PC/104
+   dep_tristate '  SL811HS Alternate (x86, Coldfire, StrongARM, isosynchronous mode)' CONFIG_USB_SL811HS_ALT $CONFIG_USB $CONFIG_EXPERIMENTAL
+   dep_tristate '  SL811HS (x86, Coldfire, StrongARM) support, old driver' CONFIG_USB_SL811HS $CONFIG_USB $CONFIG_EXPERIMENTAL
 fi
+if [ "$CONFIG_ARCH_EP93XX" = "y" ]; then
+   dep_tristate '  EP93xx OHCI-compatible host interface support' CONFIG_USB_OHCI_EP93XX $CONFIG_USB
+fi  
+if [ "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
+   dep_tristate '  AT91RM9200 OHCI-compatible host interface support' CONFIG_USB_OHCI_AT91 $CONFIG_USB
+fi
+
diff -urN linux-2.4.29/drivers/usb/host/hc_isp116x.c linux-2.4.29-uc1/drivers/usb/host/hc_isp116x.c
--- linux-2.4.29/drivers/usb/host/hc_isp116x.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/usb/host/hc_isp116x.c	2005-06-14 02:12:07.000000000 +0100
@@ -0,0 +1,659 @@
+/*-------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------*
+ * isp1161 USB HCD for Linux Version 0.8 (9/3/2001)
+ *
+ * requires (includes) hc_simple.[hc] simple generic HCD frontend
+ *
+ * Roman Weissgaerber weissg@vienna.at (C) 2001
+ *
+ *-------------------------------------------------------------------------*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/malloc.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/smp_lock.h>
+#include <linux/list.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+
+#include <linux/usb.h>
+
+#include "hc_isp116x.h"
+#include "hc_simple.h"
+
+static int hc_verbose = 1;
+static int hc_error_verbose = 0;
+static int urb_debug = 0;
+
+#include "hc_simple.c"
+#include "hc_isp116x_rh.c"
+
+#ifdef CONFIG_YAZU
+static int irq = 27;
+static int hcport = 0xd0000000;
+static int wuport = 0xd0000240;
+#else
+static int irq = 10;
+static int hcport = 0x290;
+static int wuport = 0x240;
+#endif
+
+MODULE_PARM(hc_verbose,"i");
+MODULE_PARM_DESC(hc_verbose,"verbose startup messages, default is 1 (yes)");
+MODULE_PARM(hc_error_verbose,"i");
+MODULE_PARM_DESC(hc_error_verbose,"verbose error/warning messages, default is 0 (no)");
+MODULE_PARM(urb_debug,"i");
+MODULE_PARM_DESC(urb_debug,"debug urb messages, default is 0 (no)");
+
+MODULE_PARM(irq,"i");
+MODULE_PARM_DESC(irq,"IRQ 3, 10 (default)");
+MODULE_PARM(hcport,"i");
+MODULE_PARM_DESC(hcport,"ISP116x PORT 0x290");
+MODULE_PARM(wuport,"i");
+MODULE_PARM_DESC(wuport,"WAKEUP PORT 0x240");
+
+static inline int READ_REG32 (hci_t * hci, int regindex)
+{
+	hcipriv_t * hp = &hci->hp;
+	int val16, val;
+
+	outw (regindex, hp->hcport + 2);
+	val16 = inw (hp->hcport);
+	val = val16;
+	val16 = inw (hp->hcport);
+	val += val16 << 16;
+
+	return val;
+}
+
+static inline int READ_REG16 (hci_t * hci, int regindex)
+{
+	hcipriv_t * hp = &hci->hp;
+	int val = 0;
+
+	outw (regindex, hp->hcport + 2);
+	val = inw (hp->hcport);
+
+	return val;
+}
+
+static inline void READ_REGn16 (hci_t * hci, int regindex, int length, __u8 * buffer)
+{
+	hcipriv_t * hp = &hci->hp;
+	int i;
+	int val = 0;
+
+	outw (regindex, hp->hcport + 2);
+
+	for (i = 0; i < length; i += 2) {
+		val = inw (hp->hcport);
+		buffer [i] = val;
+		buffer [i+1] = val >> 8;
+	}
+	if (length & 1) {
+		val = inw (hp->hcport);
+		buffer [length - 1] = val;
+	}
+}
+
+static inline void WRITE_REG32 (hci_t * hci, unsigned int value, int regindex)
+{
+	hcipriv_t * hp = &hci->hp;
+
+	outw (regindex | 0x80, hp->hcport + 2);
+	outw (value, hp->hcport);
+	outw (value >> 16, hp->hcport);
+}
+
+static inline void WRITE_REG16 (hci_t * hci, unsigned int value, int regindex)
+{
+	hcipriv_t * hp = &hci->hp;
+
+	outw (regindex | 0x80, hp->hcport + 2);
+	outw (value, hp->hcport);
+}
+
+static inline void WRITE_REG0 (hci_t * hci, int regindex)
+{
+	hcipriv_t * hp = &hci->hp;
+
+	outw (regindex | 0x80, hp->hcport + 2);
+}
+
+static inline void WRITE_REGn16 (hci_t * hci, int regindex, int length, __u8 * buffer)
+{
+	hcipriv_t * hp = &hci->hp;
+	int i;
+
+	outw (regindex | 0x80, hp->hcport + 2);
+
+	for (i = 0; i < length; i+=2) {
+		outw (buffer [i] + (buffer [i+1] << 8), hp->hcport);
+	}
+	if (length & 1) {
+		outw (buffer [length - 1], hp->hcport);
+	}
+}
+
+/*-------------------------------------------------------------------------*/
+/* tl functions */
+
+static inline void hc_mark_last_trans (hci_t * hci)
+{
+	hcipriv_t * hp = &hci->hp;
+	__u8 * ptd = hp->tl;
+
+	if (hp->tlp > 0)
+		*(ptd + hp->tl_last) |= (1 << 3);
+}
+
+static inline int hc_add_trans (hci_t * hci, int len, void * data,
+		int toggle, int maxps, int slow, int endpoint, int address, int pid, int format)
+{
+	hcipriv_t * hp = &hci->hp;
+	int last = 0;
+	__u8 * ptd = hp->tl;
+
+	/* just send 4 packets of each kind at a frame,
+	 * other URBs also want some bandwitdh, and a NACK is cheaper
+	 * with less packets */
+	if (len > maxps * 1)
+			len = maxps * 1;
+
+	if (hp->units_left < len + 8)
+		return 0;
+	else
+		hp->units_left -= len + 8;
+
+
+	ptd += hp->tlp;
+	hp->tl_last = hp->tlp + 3;
+	ptd [0] = 0;
+	ptd [1] = (toggle << 2) | (1 << 3) | (0xf << 4);
+	ptd [2] = maxps;
+	ptd [3] = ((maxps >> 8) & 0x3) | (slow << 2) | (last << 3) | (endpoint << 4);
+	ptd [4] = len;
+	ptd [5] = ((len >> 8) & 0x3) | (pid << 2);
+	ptd [6] = address | (format << 7);
+    ptd [7] = 0;
+
+	memcpy (ptd + 8, data, len);
+	hp->tlp += ((len + 8 + 3) & ~0x3);
+
+	return 1;
+}
+
+static inline int hc_parse_trans (hci_t * hci, int * actbytes, void ** data,
+			int * cc, int * toggle)
+{
+	hcipriv_t * hp = &hci->hp;
+	int last = 0;
+	int totbytes;
+	__u8 *ptd = hp->tl + hp->tlp;
+
+
+	*cc = (ptd [1] >> 4) & 0xf;
+	last = (ptd [3] >> 3) & 0x1;
+	*actbytes = ((ptd [1] & 0x3) << 8) | ptd [0];
+	totbytes = ((ptd [5] & 0x3) << 8) | ptd [4];
+	*data = ptd + 8;
+
+	*toggle = !(ptd [1] >> 2 & 1);
+/*	*active = (ptd[1] >> 3) & 0x1;
+	*endpoint = ptd [3] >> 4;
+	*address = ptd [6] & 0x7f;
+	*pid = (ptd [5] >> 2) & 0x3;
+*/
+	hp->tlp += ((totbytes + 8 + 3) & ~0x3);
+
+	return !last;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+static void hc_start_list (hci_t * hci, ed_t * ed)
+{
+	hcipriv_t * hp = hci->hcipriv;
+	int units_left = hp->atl_buffer_len;
+
+// printk("hc_start_list atl_buffer_len: %d atl_len: %d\n", hp->atl_buffer_len, hp->atl_len);
+	switch (usb_pipetype (ed->pipe)) {
+	case PIPE_CONTROL:
+	case PIPE_BULK:
+	case PIPE_INTERRUPT:
+		if (hp->atl_len == 0) {
+			hp->tlp = 0;
+			sh_schedule_trans (hci, TR_INTR | TR_CTRL | TR_BULK, &units_left);
+			mark_last_trans (hci);
+			hp->atl_len = hp->tlp;
+			if (hp->atl_len > 0) {
+// printk("hc_start_list: send %d bytes\n", hp->atl_len);
+				WRITE_REG16 (hci, hp->atl_len, HcTransferCounter);
+				WRITE_REGn16 (hci, HcATLBufferPort, hp->atl_len, hp->tl);
+			}
+		}
+	}
+}
+*/
+
+/* an interrupt happens */
+static void hc_interrupt (int irq, void * __hci, struct pt_regs * r)
+{
+	hci_t * hci = __hci;
+	hcipriv_t * hp = &hci->hp;
+	int ints_uP, ints = 0, bstat = 0;
+
+	if ((ints_uP = (READ_REG16 (hci, HcuPInterrupt) & READ_REG16 (hci, HcuPInterruptEnable))) == 0) {
+// printk("int1 %x %x bstat %x\n", ints_uP, ints, bstat);
+		return;
+	}
+	WRITE_REG16 (hci, ints_uP, HcuPInterrupt);
+	if ((ints_uP & OPR_Reg) &&
+ 		(ints = (READ_REG32 (hci, HcInterruptStatus)))) {
+
+		if (ints & OHCI_INTR_SO) {
+			dbg("USB Schedule overrun");
+			WRITE_REG32 (hci, OHCI_INTR_SO, HcInterruptEnable);
+		}
+
+		if (ints & OHCI_INTR_SF) {
+			WRITE_REG32 (hci, OHCI_INTR_SF, HcInterruptEnable);
+		}
+		WRITE_REG32 (hci, ints, HcInterruptStatus);
+		WRITE_REG32 (hci, OHCI_INTR_MIE, HcInterruptEnable);
+	}
+
+	bstat = READ_REG16 (hci, HcBufferStatus);
+	if (ints_uP & SOFITLInt) {
+/*		READ_REGn16 (hci,reg, len, hci->tl);
+		hp->tlp = 0;
+		done_list (hci);
+		schedule_trans (hci, TR_ISO);
+		WRITE_REG16 (hci, hp->tlp, HcTransferCounter);
+		WRITE_REGn16 (hci, HcITLBufferPort, hp->tlp, hp->tl);
+*/	}
+
+	hci->frame_no = GET_FRAME_NUMBER (hci);
+//	if (hci->frame_no == 0)
+//		printk("*** INTERRUPT frame %u intuP %x ints %x bstat %x \n", hci->frame_no, ints_uP, ints, bstat);
+
+	if (ints_uP & ATLInt) {
+// printk("int2 %x %x bstat %x\n", ints_uP, ints, bstat);
+		if ((bstat & ATLBufferFull) && (bstat & ATLBufferDone)) {
+			if (hp->atl_len > 0) {
+				READ_REGn16 (hci, HcATLBufferPort, hp->atl_len, hp->tl);
+				hp->tlp = 0;
+				sh_done_list (hci);
+			}
+			hp->tlp = 0;
+			hci->trans = 0;
+		}
+	}
+	sh_del_list (hci);
+	if (hci->trans == 0 && !(bstat & ATLBufferFull)) {
+		hp->units_left = hp->atl_buffer_len;
+		hp->tlp = 0;
+		sh_schedule_trans (hci);
+		hc_mark_last_trans (hci);
+		hp->atl_len = hp->tlp;
+		if (hp->atl_len > 0) {
+			WRITE_REG16 (hci, hp->atl_len, HcTransferCounter);
+			WRITE_REGn16 (hci, HcATLBufferPort, hp->atl_len, hp->tl);
+		}
+
+	}
+}
+
+
+
+/*-------------------------------------------------------------------------*
+ * HC functions
+ *-------------------------------------------------------------------------*/
+
+/* reset the HC and BUS */
+
+static int hc_reset (hci_t * hci)
+{
+	int timeout = 30;
+
+	/* Disable HC interrupts */
+	WRITE_REG32 (hci, OHCI_INTR_MIE, HcInterruptDisable);
+
+	dbg ("USB HC reset_hc usb-: ctrl = 0x%x ;",
+		READ_REG32 (hci, HcControl));
+
+  	/* Reset USB (needed by some controllers) */
+	WRITE_REG32 (hci, 0, HcControl);
+
+	WRITE_REG0 (hci, HcSoftwareReset);
+
+	/* HC Reset requires max 10 us delay */
+	WRITE_REG32 (hci, OHCI_HCR, HcCommandStatus);
+	while ((READ_REG32 (hci, HcCommandStatus) & OHCI_HCR) != 0) {
+		if (--timeout == 0) {
+			err ("USB HC reset timed out!");
+			return -1;
+		}
+		udelay (1);
+	}
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* Start an host controller, set the BUS operational
+ * enable interrupts
+ * connect the virtual root hub */
+
+static int hc_alloc_trans_buffer (hci_t * hci)
+{
+	hcipriv_t * hp = &hci->hp;
+	int maxlen;
+
+	hp->itl0_len = 0;
+	hp->itl1_len = 0;
+	hp->atl_len = 0;
+
+	hp->itl_buffer_len = 1024;
+	hp->atl_buffer_len = 4096 - 2 * hp->itl_buffer_len; /* 2048 */
+
+	WRITE_REG16 (hci, hp->itl_buffer_len, HcITLBufferLength);
+	WRITE_REG16 (hci, hp->atl_buffer_len, HcATLBufferLength);
+	WRITE_REG16 (hci,
+		InterruptPinEnable |
+		InterruptPinTrigger |
+		InterruptOutputPolarity |
+		DataBusWidth16 |
+		AnalogOCEnable,
+		HcHardwareConfiguration);
+	WRITE_REG16 (hci, 0, HcDMAConfiguration);
+
+	maxlen = (hp->itl_buffer_len > hp->atl_buffer_len) ? hp->itl_buffer_len : hp->atl_buffer_len;
+
+	hp->tl = kmalloc (maxlen, GFP_KERNEL);
+
+	if (!hp->tl)
+		return -ENOMEM;
+
+	memset (hp->tl, 0, maxlen);
+	return 0;
+}
+
+static int hc_start (hci_t * hci)
+{
+	hcipriv_t * hp = &hci->hp;
+  	__u32 mask;
+  	unsigned int fminterval;
+
+  	fminterval = 0x2edf;
+	fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
+	WRITE_REG32 (hci, fminterval, HcFmInterval);
+	WRITE_REG32 (hci, 0x628, HcLSThreshold);
+
+
+ 	/* start controller operations */
+ 	hp->hc_control = OHCI_USB_OPER;
+ 	WRITE_REG32 (hci, hp->hc_control, HcControl);
+
+	/* Choose the interrupts we care about now, others later on demand */
+	mask = OHCI_INTR_MIE |
+//	OHCI_INTR_ATD |
+	OHCI_INTR_SO |
+	OHCI_INTR_SF;
+
+	WRITE_REG32 (hci, mask, HcInterruptEnable);
+	WRITE_REG32 (hci, mask, HcInterruptStatus);
+
+	mask = SOFITLInt | ATLInt | OPR_Reg;
+	WRITE_REG16 (hci, mask, HcuPInterrupt);
+	WRITE_REG16 (hci, mask, HcuPInterruptEnable);
+
+
+#ifdef	OHCI_USE_NPS
+	WRITE_REG32 ((READ_REG32 (hci, HcRhDescriptorA) | RH_A_NPS) & ~RH_A_PSM,
+		HcRhDescriptorA);
+	WRITE_REG32 (hci, RH_HS_LPSC, HcRhStatus);
+#endif	/* OHCI_USE_NPS */
+
+	// POTPGT delay is bits 24-31, in 2 ms units.
+	mdelay ((READ_REG32 (hci, HcRhDescriptorA) >> 23) & 0x1fe);
+
+	rh_connect_rh (hci);
+
+	return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* allocate HCI */
+
+static hci_t * __devinit hc_alloc_hci (void)
+{
+	hci_t * hci;
+	hcipriv_t * hp;
+
+	struct usb_bus * bus;
+
+	hci = (hci_t *) kmalloc (sizeof (hci_t), GFP_KERNEL);
+	if (!hci)
+		return NULL;
+
+	memset (hci, 0, sizeof (hci_t));
+
+	hp = &hci->hp;
+
+	hp->irq = -1;
+	hp->hcport = -1;
+
+	INIT_LIST_HEAD (&hci->hci_hcd_list);
+	list_add (&hci->hci_hcd_list, &hci_hcd_list);
+	init_waitqueue_head (&hci->waitq);
+
+	INIT_LIST_HEAD (&hci->ctrl_list);
+	INIT_LIST_HEAD (&hci->bulk_list);
+	INIT_LIST_HEAD (&hci->iso_list);
+	INIT_LIST_HEAD (&hci->intr_list);
+	INIT_LIST_HEAD (&hci->del_list);
+
+	bus = usb_alloc_bus (&hci_device_operations);
+	if (!bus) {
+		kfree (hci);
+		return NULL;
+	}
+
+	hci->bus = bus;
+	bus->hcpriv = (void *) hci;
+
+	return hci;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* De-allocate all resources.. */
+
+static void hc_release_hci (hci_t * hci)
+{
+	hcipriv_t * hp = &hci->hp;
+	dbg ("USB HC release hci %d", hci->regs);
+
+
+
+	/* disconnect all devices */
+	if (hci->bus->root_hub)
+		usb_disconnect (&hci->bus->root_hub);
+
+	if (hp->hcport > 0) {
+		WRITE_REG16 (hci, 0, HcHardwareConfiguration);
+		WRITE_REG16 (hci, 0, HcDMAConfiguration);
+		WRITE_REG16 (hci, 0, HcuPInterruptEnable);
+	}
+
+//	if (!hci->disabled)
+		hc_reset (hci);
+	if (hp->tl)
+		kfree (hp->tl);
+
+	if (hp->hcport > 0) {
+		release_region (hp->hcport, 4);
+		hp->hcport = 0;
+	}
+
+	if (hp->wuport > 0) {
+		release_region (hp->wuport, 2);
+		hp->wuport = 0;
+	}
+
+	if (hp->irq >= 0) {
+		free_irq (hp->irq, hci);
+		hp->irq = -1;
+	}
+
+	usb_deregister_bus (hci->bus);
+	usb_free_bus (hci->bus);
+
+	list_del (&hci->hci_hcd_list);
+	INIT_LIST_HEAD (&hci->hci_hcd_list);
+
+	kfree (hci);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* Increment the module usage count, start the control thread and
+ * return success. */
+
+
+static int __devinit hc_found_hci (int addr, int wuaddr, int irq, int dma)
+{
+	hci_t * hci;
+	hcipriv_t * hp;
+
+	hci = hc_alloc_hci ();
+	if (!hci) {
+		return -ENOMEM;
+	}
+
+	hp = &hci->hp;
+#ifndef CONFIG_YAZU
+	if (!request_region (addr, 4, "ISP116x USB HOST")) {
+		err ("request address %d-%d failed", addr, addr+4);
+		hc_release_hci (hci);
+		return -EBUSY;
+	}
+#endif
+	hp->hcport = addr;
+
+	if ((READ_REG16(hci, HcChipID) & 0xff00) != 0x6100) {
+		hc_release_hci (hci);
+		return -ENODEV;
+	}
+#ifndef CONFIG_YAZU
+	if (!request_region (wuaddr, 2, "ISP116x USB HOST")) {
+		err ("request address %d-%d failed", wuaddr, wuaddr+2);
+		hc_release_hci (hci);
+		return -EBUSY;
+	}
+#endif
+	hp->wuport = wuaddr;
+
+	if (hc_reset (hci) < 0) {
+		hc_release_hci (hci);
+		return -ENODEV;
+	}
+
+	if (hc_alloc_trans_buffer (hci)) {
+		hc_release_hci (hci);
+		return -ENOMEM;
+	}
+
+	printk(KERN_INFO __FILE__ ": USB ISP116x at %x/%x IRQ %d Rev. %x ChipID: %x\n",
+		addr, wuaddr, irq, READ_REG32(hci, HcRevision), READ_REG16(hci, HcChipID));
+
+	/* FIXME this is a second HC reset; why?? */
+	WRITE_REG32 (hci, hp->hc_control = OHCI_USB_RESET, HcControl);
+	wait_ms (1000);
+
+	usb_register_bus (hci->bus);
+
+	if (request_irq (irq, hc_interrupt, 0,
+			"ISP116x", hci) != 0) {
+		err ("request interrupt %d failed", irq);
+		hc_release_hci (hci);
+		return -EBUSY;
+	}
+	hp->irq = irq;
+#if 0
+	if (dma && !request_dma (dma, "ISP116x USB HOST")) {
+		err ("request dma %d failed", dma);
+		dma = 0;
+	}
+
+	hp->dmahci->dmaci->dma = dma;
+#endif
+	if (hc_start (hci) < 0) {
+		err ("can't start usb-%x", addr);
+		hc_release_hci (hci);
+		return -EBUSY;
+	}
+
+#ifdef	DEBUG
+//	hci_dump (hci, 1);
+#endif
+	return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int __init hci_hcd_init (void)
+{
+	int ret;
+
+	ret = hc_found_hci (hcport, wuport, irq, 0);
+
+	return ret;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void __exit hci_hcd_cleanup (void)
+{
+	struct list_head *  hci_l;
+	hci_t * hci;
+	for (hci_l = hci_hcd_list.next; hci_l != &hci_hcd_list;) {
+		hci = list_entry (hci_l, hci_t, hci_hcd_list);
+		hci_l = hci_l->next;
+		hc_release_hci(hci);
+	}
+}
+
+module_init (hci_hcd_init);
+module_exit (hci_hcd_cleanup);
+
+
+MODULE_AUTHOR ("Roman Weissgaerber <weissg@vienna.at>");
+MODULE_DESCRIPTION ("USB ISP116x Host Controller Driver");
diff -urN linux-2.4.29/drivers/usb/host/hc_isp116x.h linux-2.4.29-uc1/drivers/usb/host/hc_isp116x.h
--- linux-2.4.29/drivers/usb/host/hc_isp116x.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/usb/host/hc_isp116x.h	2005-06-14 02:12:07.000000000 +0100
@@ -0,0 +1,214 @@
+/*
+ * ISP116x HCD (Host Controller Driver) for USB.
+ *
+ * (C) Copyright 2001 Roman Weissgaerber <weissg@vienna.at>
+ *
+ *
+ */
+
+#define GET_FRAME_NUMBER(hci) 	READ_REG32 (hci, HcFmNumber)
+
+/*
+ * Maximum number of root hub ports.
+ */
+#define MAX_ROOT_PORTS	15	/* maximum OHCI root hub ports */
+
+
+/* control and status registers */
+#define HcRevision		0x00
+#define HcControl 		0x01
+#define HcCommandStatus		0x02
+#define HcInterruptStatus	0x03
+#define HcInterruptEnable	0x04
+#define HcInterruptDisable	0x05
+#define HcFmInterval		0x0D
+#define HcFmRemaining		0x0E
+#define HcFmNumber		0x0F
+#define HcLSThreshold		0x11
+#define HcRhDescriptorA		0x12
+#define HcRhDescriptorB		0x13
+#define HcRhStatus		0x14
+#define HcRhPortStatus		0x15
+
+#define HcHardwareConfiguration 0x20
+#define HcDMAConfiguration	0x21
+#define HcTransferCounter	0x22
+#define HcuPInterrupt		0x24
+#define HcuPInterruptEnable	0x25
+#define HcChipID		0x27
+#define HcScratch		0x28
+#define HcSoftwareReset		0x29
+#define HcITLBufferLength	0x2A
+#define HcATLBufferLength	0x2B
+#define HcBufferStatus		0x2C
+#define HcReadBackITL0Length	0x2D
+#define HcReadBackITL1Length	0x2E
+#define HcITLBufferPort		0x40
+#define HcATLBufferPort		0x41
+
+/* OHCI CONTROL AND STATUS REGISTER MASKS */
+
+/*
+ * HcControl (control) register masks
+ */
+#define OHCI_CTRL_HCFS	(3 << 6)	/* BUS state mask */
+#define OHCI_CTRL_RWC	(1 << 9)	/* remote wakeup connected */
+#define OHCI_CTRL_RWE	(1 << 10)	/* remote wakeup enable */
+
+/* pre-shifted values for HCFS */
+#define OHCI_USB_RESET	(0 << 6)
+#define OHCI_USB_RESUME	(1 << 6)
+#define OHCI_USB_OPER	(2 << 6)
+#define OHCI_USB_SUSPEND	(3 << 6)
+
+/*
+ * HcCommandStatus (cmdstatus) register masks
+ */
+#define OHCI_HCR	(1 << 0)	/* host controller reset */
+#define OHCI_SOC  	(3 << 16)	/* scheduling overrun count */
+
+/*
+ * masks used with interrupt registers:
+ * HcInterruptStatus (intrstatus)
+ * HcInterruptEnable (intrenable)
+ * HcInterruptDisable (intrdisable)
+ */
+#define OHCI_INTR_SO	(1 << 0)	/* scheduling overrun */
+
+#define OHCI_INTR_SF	(1 << 2)	/* start frame */
+#define OHCI_INTR_RD	(1 << 3)	/* resume detect */
+#define OHCI_INTR_UE	(1 << 4)	/* unrecoverable error */
+#define OHCI_INTR_FNO	(1 << 5)	/* frame number overflow */
+#define OHCI_INTR_RHSC	(1 << 6)	/* root hub status change */
+#define OHCI_INTR_ATD	(1 << 7)	/* scheduling overrun */
+
+#define OHCI_INTR_MIE	(1 << 31)	/* master interrupt enable */
+
+/*
+ * HcHardwareConfiguration
+ */
+#define InterruptPinEnable 	(1 << 0)
+#define InterruptPinTrigger 	(1 << 1)
+#define InterruptOutputPolarity	(1 << 2)
+#define DataBusWidth16		(1 << 3)
+#define DREQOutputPolarity	(1 << 5)
+#define DACKInputPolarity	(1 << 6)
+#define EOTInputPolarity	(1 << 7)
+#define DACKMode		(1 << 8)
+#define AnalogOCEnable		(1 << 10)
+#define SuspendClkNotStop	(1 << 11)
+#define DownstreamPort15KRSel	(1 << 12)
+
+/*
+ * HcDMAConfiguration
+ */
+#define DMAReadWriteSelect 	(1 << 0)
+#define ITL_ATL_DataSelect	(1 << 1)
+#define DMACounterSelect	(1 << 2)
+#define DMAEnable		(1 << 4)
+#define BurstLen_1		0
+#define BurstLen_4		(1 << 5)
+#define BurstLen_8		(2 << 5)
+
+
+/*
+ * HcuPInterrupt
+ */
+#define SOFITLInt		(1 << 0)
+#define ATLInt			(1 << 1)
+#define AllEOTInterrupt		(1 << 2)
+#define OPR_Reg			(1 << 4)
+#define HCSuspended		(1 << 5)
+#define ClkReady		(1 << 6)
+
+/*
+ * HcBufferStatus
+ */
+#define ITL0BufferFull		(1 << 0)
+#define ITL1BufferFull		(1 << 1)
+#define ATLBufferFull		(1 << 2)
+#define ITL0BufferDone		(1 << 3)
+#define ITL1BufferDone		(1 << 4)
+#define ATLBufferDone		(1 << 5)
+
+
+
+/* OHCI ROOT HUB REGISTER MASKS */
+
+/* roothub.portstatus [i] bits */
+#define RH_PS_CCS            0x00000001   	/* current connect status */
+#define RH_PS_PES            0x00000002   	/* port enable status*/
+#define RH_PS_PSS            0x00000004   	/* port suspend status */
+#define RH_PS_POCI           0x00000008   	/* port over current indicator */
+#define RH_PS_PRS            0x00000010  	/* port reset status */
+#define RH_PS_PPS            0x00000100   	/* port power status */
+#define RH_PS_LSDA           0x00000200    	/* low speed device attached */
+#define RH_PS_CSC            0x00010000 	/* connect status change */
+#define RH_PS_PESC           0x00020000   	/* port enable status change */
+#define RH_PS_PSSC           0x00040000    	/* port suspend status change */
+#define RH_PS_OCIC           0x00080000    	/* over current indicator change */
+#define RH_PS_PRSC           0x00100000   	/* port reset status change */
+
+/* roothub.status bits */
+#define RH_HS_LPS	     0x00000001		/* local power status */
+#define RH_HS_OCI	     0x00000002		/* over current indicator */
+#define RH_HS_DRWE	     0x00008000		/* device remote wakeup enable */
+#define RH_HS_LPSC	     0x00010000		/* local power status change */
+#define RH_HS_OCIC	     0x00020000		/* over current indicator change */
+#define RH_HS_CRWE	     0x80000000		/* clear remote wakeup enable */
+
+/* roothub.b masks */
+#define RH_B_DR		0x0000ffff		/* device removable flags */
+#define RH_B_PPCM	0xffff0000		/* port power control mask */
+
+/* roothub.a masks */
+#define	RH_A_NDP	(0xff << 0)		/* number of downstream ports */
+#define	RH_A_PSM	(1 << 8)		/* power switching mode */
+#define	RH_A_NPS	(1 << 9)		/* no power switching */
+#define	RH_A_DT		(1 << 10)		/* device type (mbz) */
+#define	RH_A_OCPM	(1 << 11)		/* over current protection mode */
+#define	RH_A_NOCP	(1 << 12)		/* no over current protection */
+#define	RH_A_POTPGT	(0xff << 24)		/* power on to power good time */
+
+#define min(a,b) (((a)<(b))?(a):(b))
+
+
+#define URB_DEL 1
+
+
+typedef struct hcipriv {
+	int irq;
+	int disabled;			/* e.g. got a UE, we're hung */
+	atomic_t resume_count;		/* defending against multiple resumes */
+	struct ohci_regs * regs;	/* OHCI controller's memory */
+	int hcport;
+	int wuport;
+
+	int intrstatus;
+	__u32 hc_control;		/* copy of the hc control reg */
+
+	int frame;
+
+	__u8 * tl;
+	int tlp;
+	int atl_len;
+	int atl_buffer_len;
+	int itl0_len;
+	int itl1_len;
+	int itl_buffer_len;
+	int itl_index;
+	int tl_last;
+	int units_left;
+
+} hcipriv_t;
+struct hci;
+
+static inline int READ_REG32 (struct hci * hci, int regindex);
+static inline int READ_REG16 (struct hci * hci, int regindex);
+static inline void READ_REGn16 (struct hci * hci, int regindex, int length, __u8 * buffer);
+static inline void WRITE_REG32 (struct hci * hci, unsigned int value, int regindex);
+static inline void WRITE_REG16 (struct hci * hci, unsigned int value, int regindex);
+static inline void WRITE_REG0 (struct hci * hci, int regindex);
+static inline void WRITE_REGn16 (struct hci * hci, int regindex, int length, __u8 * buffer);
+
+/*-------------------------------------------------------------------------*/
\ No newline at end of file
diff -urN linux-2.4.29/drivers/usb/host/hc_isp116x_rh.c linux-2.4.29-uc1/drivers/usb/host/hc_isp116x_rh.c
--- linux-2.4.29/drivers/usb/host/hc_isp116x_rh.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/usb/host/hc_isp116x_rh.c	2005-06-14 02:12:07.000000000 +0100
@@ -0,0 +1,428 @@
+/*-------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------*
+ * ISP116x virtual root hub
+ * Roman Weissgaerber weissg@vienna.at
+ * based on usb-ohci.c by R. Weissgaerber et al.
+ *-------------------------------------------------------------------------*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *-------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------*
+ * Virtual Root Hub
+ *-------------------------------------------------------------------------*/
+
+/* Device descriptor */
+static __u8 root_hub_dev_des[] =
+{
+	0x12,       /*  __u8  bLength; */
+	0x01,       /*  __u8  bDescriptorType; Device */
+	0x10,	    /*  __u16 bcdUSB; v1.1 */
+	0x01,
+	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
+	0x00,	    /*  __u8  bDeviceSubClass; */
+	0x00,       /*  __u8  bDeviceProtocol; */
+	0x08,       /*  __u8  bMaxPacketSize0; 8 Bytes */
+	0x00,       /*  __u16 idVendor; */
+	0x00,
+	0x00,       /*  __u16 idProduct; */
+ 	0x00,
+	0x00,       /*  __u16 bcdDevice; */
+ 	0x00,
+	0x00,       /*  __u8  iManufacturer; */
+	0x02,       /*  __u8  iProduct; */
+	0x01,       /*  __u8  iSerialNumber; */
+	0x01        /*  __u8  bNumConfigurations; */
+};
+
+
+/* Configuration descriptor */
+static __u8 root_hub_config_des[] =
+{
+	0x09,       /*  __u8  bLength; */
+	0x02,       /*  __u8  bDescriptorType; Configuration */
+	0x19,       /*  __u16 wTotalLength; */
+	0x00,
+	0x01,       /*  __u8  bNumInterfaces; */
+	0x01,       /*  __u8  bConfigurationValue; */
+	0x00,       /*  __u8  iConfiguration; */
+	0x40,       /*  __u8  bmAttributes;
+                 Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
+	0x00,       /*  __u8  MaxPower; */
+
+	/* interface */
+	0x09,       /*  __u8  if_bLength; */
+	0x04,       /*  __u8  if_bDescriptorType; Interface */
+	0x00,       /*  __u8  if_bInterfaceNumber; */
+	0x00,       /*  __u8  if_bAlternateSetting; */
+	0x01,       /*  __u8  if_bNumEndpoints; */
+	0x09,       /*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
+	0x00,       /*  __u8  if_bInterfaceSubClass; */
+	0x00,       /*  __u8  if_bInterfaceProtocol; */
+	0x00,       /*  __u8  if_iInterface; */
+
+	/* endpoint */
+	0x07,       /*  __u8  ep_bLength; */
+	0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
+	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
+ 	0x03,       /*  __u8  ep_bmAttributes; Interrupt */
+ 	0x02,       /*  __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
+ 	0x00,
+	0xff        /*  __u8  ep_bInterval; 255 ms */
+};
+
+/* Hub class-specific descriptor is constructed dynamically */
+
+
+/*-------------------------------------------------------------------------*/
+
+/* prepare Interrupt pipe data; HUB INTERRUPT ENDPOINT */
+
+static int rh_send_irq (hci_t * hci, void * rh_data, int rh_len)
+{
+	int num_ports;
+	int i;
+	int ret;
+	int len;
+
+	__u8 data[8];
+
+	num_ports = READ_REG32 (hci, HcRhDescriptorA) & RH_A_NDP;
+
+	*(__u8 *) data = (READ_REG32 (hci, HcRhStatus) & (RH_HS_LPSC | RH_HS_OCIC))
+		? 1: 0;
+	ret = *(__u8 *) data;
+
+	for ( i = 0; i < num_ports; i++) {
+		*(__u8 *) (data + (i + 1) / 8) |=
+			((READ_REG32 (hci, HcRhPortStatus + i) &
+				(RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC | RH_PS_OCIC | RH_PS_PRSC))
+			    ? 1: 0) << ((i + 1) % 8);
+		ret += *(__u8 *) (data + (i + 1) / 8);
+	}
+	len = i/8 + 1;
+
+	if (ret > 0) {
+		memcpy (rh_data, data, min (len, min (rh_len, sizeof(data))));
+		return len;
+	}
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* Virtual Root Hub INTs are polled by this timer every "interval" ms */
+
+static void rh_int_timer_do (unsigned long ptr)
+{
+	int len;
+
+	urb_t * urb = (urb_t *) ptr;
+	hci_t * hci = urb->dev->bus->hcpriv;
+
+#if 0
+	if (hci->disabled)
+//		return;
+
+	/* ignore timers firing during PM suspend, etc */
+	if ((hci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER)
+		goto out;
+#endif
+
+	if(hci->rh.send) {
+		len = rh_send_irq (hci, urb->transfer_buffer, urb->transfer_buffer_length);
+		if (len > 0) {
+			urb->actual_length = len;
+			if (urb_debug == 2)
+				urb_print (urb, "RET-t(rh)", usb_pipeout (urb->pipe));
+
+			if (urb->complete)
+				urb->complete (urb);
+		}
+	}
+// out:
+	rh_init_int_timer (urb);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* Root Hub INTs are polled by this timer */
+
+static int rh_init_int_timer (urb_t * urb)
+{
+	hci_t * hci = urb->dev->bus->hcpriv;
+
+	hci->rh.interval = urb->interval;
+	init_timer (&hci->rh.rh_int_timer);
+	hci->rh.rh_int_timer.function = rh_int_timer_do;
+	hci->rh.rh_int_timer.data = (unsigned long) urb;
+	hci->rh.rh_int_timer.expires =
+			jiffies + (HZ * (urb->interval < 30? 30: urb->interval)) / 1000;
+	add_timer (&hci->rh.rh_int_timer);
+
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+#define OK(x) 			len = (x); break
+#define WR_RH_STAT(x) 		WRITE_REG32 (hci, (x), HcRhStatus)
+#define WR_RH_PORTSTAT(x) 	WRITE_REG32 (hci, (x), HcRhPortStatus + wIndex - 1)
+#define RD_RH_STAT		READ_REG32 (hci, HcRhStatus)
+#define RD_RH_PORTSTAT		READ_REG32 (hci, HcRhPortStatus + wIndex - 1)
+
+/* request to virtual root hub */
+
+static int rh_submit_urb (urb_t * urb)
+{
+	struct usb_device * usb_dev = urb->dev;
+	hci_t * hci = usb_dev->bus->hcpriv;
+	unsigned int pipe = urb->pipe;
+	devrequest * cmd = (devrequest *) urb->setup_packet;
+	void * data = urb->transfer_buffer;
+	int leni = urb->transfer_buffer_length;
+	int len = 0;
+	int status = TD_CC_NOERROR;
+
+	__u32 datab[4];
+	__u8  * data_buf = (__u8 *) datab;
+
+ 	__u16 bmRType_bReq;
+	__u16 wValue;
+	__u16 wIndex;
+	__u16 wLength;
+
+	if (usb_pipeint(pipe)) {
+		hci->rh.urb =  urb;
+		hci->rh.send = 1;
+		hci->rh.interval = urb->interval;
+		rh_init_int_timer(urb);
+		urb->status = cc_to_error [TD_CC_NOERROR];
+
+		return 0;
+	}
+
+	bmRType_bReq  = cmd->requesttype | (cmd->request << 8);
+	wValue        = le16_to_cpu (cmd->value);
+	wIndex        = le16_to_cpu (cmd->index);
+	wLength       = le16_to_cpu (cmd->length);
+
+	dbg ("rh_submit_urb, req = %d(%x) len=%d", bmRType_bReq,
+		bmRType_bReq, wLength);
+
+	switch (bmRType_bReq) {
+	/* Request Destination:
+	   without flags: Device,
+	   RH_INTERFACE: interface,
+	   RH_ENDPOINT: endpoint,
+	   RH_CLASS means HUB here,
+	   RH_OTHER | RH_CLASS  almost ever means HUB_PORT here
+	*/
+
+		case RH_GET_STATUS:
+				*(__u16 *) data_buf = cpu_to_le16 (1); OK (2);
+		case RH_GET_STATUS | RH_INTERFACE:
+				*(__u16 *) data_buf = cpu_to_le16 (0); OK (2);
+		case RH_GET_STATUS | RH_ENDPOINT:
+				*(__u16 *) data_buf = cpu_to_le16 (0); OK (2);
+		case RH_GET_STATUS | RH_CLASS:
+				*(__u32 *) data_buf = cpu_to_le32 (
+					RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
+				OK (4);
+		case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+				*(__u32 *) data_buf = cpu_to_le32 (RD_RH_PORTSTAT); OK (4);
+
+		case RH_CLEAR_FEATURE | RH_ENDPOINT:
+			switch (wValue) {
+				case (RH_ENDPOINT_STALL): OK (0);
+			}
+			break;
+
+		case RH_CLEAR_FEATURE | RH_CLASS:
+			switch (wValue) {
+				case RH_C_HUB_LOCAL_POWER:
+					OK(0);
+				case (RH_C_HUB_OVER_CURRENT):
+						WR_RH_STAT(RH_HS_OCIC); OK (0);
+			}
+			break;
+
+		case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+			switch (wValue) {
+				case (RH_PORT_ENABLE):
+						WR_RH_PORTSTAT (RH_PS_CCS ); OK (0);
+				case (RH_PORT_SUSPEND):
+						WR_RH_PORTSTAT (RH_PS_POCI); OK (0);
+				case (RH_PORT_POWER):
+						WR_RH_PORTSTAT (RH_PS_LSDA); OK (0);
+				case (RH_C_PORT_CONNECTION):
+						WR_RH_PORTSTAT (RH_PS_CSC ); OK (0);
+				case (RH_C_PORT_ENABLE):
+						WR_RH_PORTSTAT (RH_PS_PESC); OK (0);
+				case (RH_C_PORT_SUSPEND):
+						WR_RH_PORTSTAT (RH_PS_PSSC); OK (0);
+				case (RH_C_PORT_OVER_CURRENT):
+						WR_RH_PORTSTAT (RH_PS_OCIC); OK (0);
+				case (RH_C_PORT_RESET):
+						WR_RH_PORTSTAT (RH_PS_PRSC); OK (0);
+			}
+			break;
+
+		case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+			switch (wValue) {
+				case (RH_PORT_SUSPEND):
+						WR_RH_PORTSTAT (RH_PS_PSS ); OK (0);
+				case (RH_PORT_RESET): /* BUG IN HUB CODE *********/
+						if (RD_RH_PORTSTAT & RH_PS_CCS)
+							WR_RH_PORTSTAT (RH_PS_PRS);
+							OK (0);
+				case (RH_PORT_POWER):
+						WR_RH_PORTSTAT (RH_PS_PPS ); OK (0);
+				case (RH_PORT_ENABLE): /* BUG IN HUB CODE *********/
+						if (RD_RH_PORTSTAT & RH_PS_CCS)
+							WR_RH_PORTSTAT (RH_PS_PES );
+							OK (0);
+			}
+			break;
+
+		case RH_SET_ADDRESS: hci->rh.devnum = wValue; OK(0);
+
+		case RH_GET_DESCRIPTOR:
+			switch ((wValue & 0xff00) >> 8) {
+				case (0x01): /* device descriptor */
+					len = min (leni, min (sizeof (root_hub_dev_des), wLength));
+					data_buf = root_hub_dev_des; OK(len);
+				case (0x02): /* configuration descriptor */
+					len = min (leni, min (sizeof (root_hub_config_des), wLength));
+					data_buf = root_hub_config_des; OK(len);
+				case (0x03): /* string descriptors */
+					len = usb_root_hub_string (wValue & 0xff,
+						(int)(long) 0, "ISP116x",
+						data, wLength);
+					if (len > 0) {
+						data_buf = data;
+						OK (min (leni, len));
+					}
+					// else fallthrough
+				default:
+					status = TD_CC_STALL;
+			}
+			break;
+
+		case RH_GET_DESCRIPTOR | RH_CLASS:
+		    {
+			    __u32 temp = READ_REG32 (hci, HcRhDescriptorA);
+
+			    data_buf [0] = 9;		// min length;
+			    data_buf [1] = 0x29;
+			    data_buf [2] = temp & RH_A_NDP;
+			    data_buf [3] = 0;
+			    if (temp & RH_A_PSM) 	/* per-port power switching? */
+				data_buf [3] |= 0x1;
+			    if (temp & RH_A_NOCP)	/* no overcurrent reporting? */
+				data_buf [3] |= 0x10;
+			    else if (temp & RH_A_OCPM)	/* per-port overcurrent reporting? */
+				data_buf [3] |= 0x8;
+
+			    datab [1] = 0;
+			    data_buf [5] = (temp & RH_A_POTPGT) >> 24;
+			    temp = READ_REG32 (hci, HcRhDescriptorB);
+			    data_buf [7] = temp & RH_B_DR;
+			    if (data_buf [2] < 7) {
+				data_buf [8] = 0xff;
+			    } else {
+				data_buf [0] += 2;
+				data_buf [8] = (temp & RH_B_DR) >> 8;
+				data_buf [10] = data_buf [9] = 0xff;
+			    }
+
+			    len = min (leni, min (data_buf [0], wLength));
+			    OK (len);
+			}
+
+		case RH_GET_CONFIGURATION: 	*(__u8 *) data_buf = 0x01; OK (1);
+
+		case RH_SET_CONFIGURATION: 	WR_RH_STAT (0x10000); OK (0);
+
+		default:
+			dbg ("unsupported root hub command");
+			status = TD_CC_STALL;
+	}
+
+#ifdef	DEBUG
+	// hci_dump_roothub (ohci, 0);
+#endif
+
+	len = min(len, leni);
+	if (data != data_buf)
+	    memcpy (data, data_buf, len);
+  	urb->actual_length = len;
+	urb->status = cc_to_error [status];
+
+	// hci_return_urb (hci, urb, NULL);
+	urb->hcpriv = NULL;
+//	usb_dec_dev_use (usb_dev);
+	urb->dev = NULL;
+	if (urb->complete)
+	    	urb->complete (urb);
+
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int rh_unlink_urb (urb_t * urb)
+{
+	hci_t * hci = urb->dev->bus->hcpriv;
+
+	if (hci->rh.urb == urb) {
+		hci->rh.send = 0;
+		del_timer (&hci->rh.rh_int_timer);
+		hci->rh.urb = NULL;
+
+		urb->hcpriv = NULL;
+		usb_dec_dev_use(urb->dev);
+		urb->dev = NULL;
+		if (urb->transfer_flags & USB_ASYNC_UNLINK) {
+			urb->status = -ECONNRESET;
+			if (urb->complete)
+				urb->complete (urb);
+		} else
+			urb->status = -ENOENT;
+	}
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+/* connect the virtual root hub */
+
+static int rh_connect_rh (hci_t * hci) {
+
+        struct usb_device  * usb_dev;
+
+        hci->rh.devnum = 0;
+        usb_dev = usb_alloc_dev (NULL, hci->bus);
+        if (!usb_dev)
+            return -ENOMEM;
+
+        hci->bus->root_hub = usb_dev;
+        usb_connect (usb_dev);
+        if (usb_new_device (usb_dev) != 0) {
+                usb_free_dev (usb_dev);
+                return -ENODEV;
+        }
+
+        return 0;
+}
\ No newline at end of file
diff -urN linux-2.4.29/drivers/usb/host/hc_sl811.c linux-2.4.29-uc1/drivers/usb/host/hc_sl811.c
--- linux-2.4.29/drivers/usb/host/hc_sl811.c	2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.29-uc1/drivers/usb/host/hc_sl811.c	2005-06-14 02:12:07.000000000 +0100
@@ -6,7 +6,13 @@
  *
  * COPYRIGHT(C) 2001 by CYPRESS SEMICONDUCTOR INC.
  *
- * ! This driver have end of live! Please use hcd/sl811.c instand !
+ * ! This driver have end of live! Please use hcd/sl811.c instead !
+ *
+ * 06.05.2005 DZ,LC
+ *  - Support COLDFIRE architecture now.
+ *  - restore previus "Read back SOF counter HIGH" in hc_add_trans(),
+ *    was correct in the previous version (reading it all 8 bit is significant).
+ *    Significantly highly performance result.
  *
  * 05.06.2003 HNE
  * Support x86 architecture now.
@@ -490,9 +496,8 @@
 
 	jj = SL811Read (hci, SL11H_SOFTMRREG);
 
-	/* Read back SOF counter HIGH (bit0-bit5 only) 26.11.2002 (hne) */
-	// kk = (jj & 0xFF) * 64 - ii;
-	kk = (jj & (64-1)) * 64 - ii;
+	/* Read back SOF counter HIGH */
+	kk = (jj & 0xFF) * 64 - ii;
 
 	if (kk < 0) {
 		DBGVERBOSE
@@ -808,6 +813,16 @@
 	sta2 = (__u8) inb (0x222+1);
 #endif
 
+#if defined(CONFIG_SIGNAL_MCP751)
+	/* Acknowledge interrupt */
+	{
+	volatile unsigned long *icrp;
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR4);
+	*icrp = (*icrp & 0x7777777) | 0x08000000; // INT5
+	}
+#endif
+
+
     do {
 	/* Get value from interrupt status register */
 
@@ -1437,8 +1452,9 @@
 
 #ifdef __arm__
 	ret = hc_found_hci (irq, base_addr, data_reg_addr);
+#elif CONFIG_COLDFIRE
+	ret = hc_found_hci (irq, base_addr, data_reg_addr);
 #else // __arm__
-
 	// registering "another instance"
 	for (io_offset = 0; io_offset < MAX_CONTROLERS * 2; io_offset += 2) {
 
@@ -1447,7 +1463,7 @@
 			return (ret);
 
 	} /* endfor */
-#endif // __arm__
+#endif
 
 	return ret;
 }
diff -urN linux-2.4.29/drivers/usb/host/Makefile linux-2.4.29-uc1/drivers/usb/host/Makefile
--- linux-2.4.29/drivers/usb/host/Makefile	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-uc1/drivers/usb/host/Makefile	2005-06-14 02:12:07.000000000 +0100
@@ -11,6 +11,10 @@
 obj-$(CONFIG_USB_OHCI)				+= usb-ohci.o
 obj-$(CONFIG_USB_SL811HS_ALT)  			+= sl811.o
 obj-$(CONFIG_USB_SL811HS)  			+= hc_sl811.o
+obj-$(CONFIG_USB_ISP116x)			+= hc_isp116x.o
+obj-$(CONFIG_USB_OHCI_SA1111)			+= usb-ohci.o usb-ohci-sa1111.o
+obj-$(CONFIG_USB_OHCI_EP93XX)			+= usb-ohci.o usb-ohci-ep93xx.o
+obj-$(CONFIG_USB_OHCI_AT91)			+= usb-ohci.o
 
 # Extract lists of the multi-part drivers.
 # The 'int-*' lists are the intermediate files used to build the multi's.
diff -urN linux-2.4.29/drivers/usb/host/sl811.c linux-2.4.29-uc1/drivers/usb/host/sl811.c
--- linux-2.4.29/drivers/usb/host/sl811.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/usb/host/sl811.c	2005-06-14 02:12:07.000000000 +0100
@@ -2541,6 +2541,15 @@
 	__u8 status;
 	struct sl811_hc *hc = __hc;
 
+#if defined(CONFIG_SIGNAL_MCP751)
+	/* Acknowledge interrupt */
+	{
+	volatile unsigned long *icrp;
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR4);
+	*icrp = (*icrp & 0x7777777) | 0x08000000; // INT5
+	}
+#endif
+
 	status = sl811_read(hc, SL811_INTRSTS);
 	if (status == 0)
 		return ; /* Not me */
diff -urN linux-2.4.29/drivers/usb/host/usb-ohci.c linux-2.4.29-uc1/drivers/usb/host/usb-ohci.c
--- linux-2.4.29/drivers/usb/host/usb-ohci.c	2005-01-19 14:10:07.000000000 +0000
+++ linux-2.4.29-uc1/drivers/usb/host/usb-ohci.c	2005-06-14 02:12:07.000000000 +0100
@@ -77,6 +77,17 @@
 #define OHCI_USE_NPS		// force NoPowerSwitching mode
 // #define OHCI_VERBOSE_DEBUG	/* not always helpful */
 
+#if defined(CONFIG_ARCH_EP9301) || defined(CONFIG_ARCH_EP9312) || \
+    defined(CONFIG_ARCH_EP9315)
+extern struct pci_pool *pci_pool_create(const char *name, struct pci_dev *dev,
+					size_t size, size_t align,
+					size_t allocation, int flags);
+extern void pci_pool_destroy(struct pci_pool *pool);
+extern void *pci_pool_alloc(struct pci_pool *pool, int flags,
+			    dma_addr_t *handle);
+extern void pci_pool_free(struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+#endif
+
 #include "usb-ohci.h"
 
 #include "../hcd.h"
@@ -2219,9 +2230,20 @@
   	/* Reset USB (needed by some controllers) */
 	writel (0, &ohci->regs->control);
 
-	/* Force a state change from USBRESET to USBOPERATIONAL for ALi */
-	(void) readl (&ohci->regs->control);	/* PCI posting */
-	writel (ohci->hc_control = OHCI_USB_OPER, &ohci->regs->control);
+
+	/*
+	 * The following 2 lines cause the NEC 720101 to write a
+	 * random value at bus address 0x80 and are not necessary on
+	 * that hardware
+	 */
+	if (!((ohci->ohci_dev->vendor == 0x1033) 
+
+			&& (ohci->ohci_dev->device == 0x0035))) {
+
+		/* Force a state change from USBRESET to USBOPERATIONAL for ALi */
+		(void) readl (&ohci->regs->control);	/* PCI posting */
+		writel (ohci->hc_control = OHCI_USB_OPER, &ohci->regs->control);
+	}
 
 	/* HC Reset requires max 10 ms delay */
 	writel (OHCI_HCR,  &ohci->regs->cmdstatus);
@@ -2488,7 +2510,11 @@
 		kfree (ohci);
 		return NULL;
 	}
+#ifdef CONFIG_PCI
 	ohci->bus->bus_name = dev->slot_name;
+#else
+	ohci->bus->bus_name = "not_pci";
+#endif
 	ohci->bus->hcpriv = (void *) ohci;
 
 	return ohci;
@@ -2539,7 +2565,7 @@
 
 static struct pci_driver ohci_pci_driver;
  
-static int __devinit
+int __devinit
 hc_found_ohci (struct pci_dev *dev, int irq,
 	void *mem_base, const struct pci_device_id *id)
 {
@@ -2892,10 +2918,18 @@
 			return -EIO;
 		}
 
-		/* Some chips likes being resumed first */
-		writel (OHCI_USB_OPER, &ohci->regs->control);
-		(void) readl (&ohci->regs->control);
-		mdelay (3);
+		/*
+		 * The following 2 lines cause the NEC 720101 to write a
+		 * random value at bus address 0x80 and are not necessary on
+		 * that hardware
+		 */
+		if (!((ohci->ohci_dev->vendor == 0x1033)
+				&& (ohci->ohci_dev->device == 0x0035))) {
+			/* Some chips likes being resumed first */
+			writel (OHCI_USB_OPER, &ohci->regs->control);
+			(void) readl (&ohci->regs->control);
+			mdelay (3);
+		}
 
 		/* Then re-enable operations */
 		spin_lock_irqsave (&ohci->ohci_lock, flags);
diff -urN linux-2.4.29/drivers/usb/host/usb-ohci-ep93xx.c linux-2.4.29-uc1/drivers/usb/host/usb-ohci-ep93xx.c
--- linux-2.4.29/drivers/usb/host/usb-ohci-ep93xx.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/usb/host/usb-ohci-ep93xx.c	2005-06-14 02:12:07.000000000 +0100
@@ -0,0 +1,108 @@
+
+/*
+ *  linux/drivers/usb/usb-ohci-ep93xx.c
+ *
+ *  The outline of this code was taken from Brad Parkers <brad@heeltoe.com>
+ *  original OHCI driver modifications, and reworked into a cleaner form
+ *  by Russell King <rmk@arm.linux.org.uk>.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+
+#include <linux/pci.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+
+#include "usb-ohci.h"
+
+int __devinit
+hc_found_ohci (struct pci_dev *dev, int irq,
+	void *mem_base, const struct pci_device_id *id);
+
+extern void hc_remove_ohci(ohci_t *ohci);
+
+static ohci_t *ep93xx_ohci;
+
+static void __init ep93xx_ohci_configure(void)
+{
+	unsigned int usb_rst = 0;
+	unsigned int uiPBDR, uiPBDDR;
+	 __u32                   temp;
+     
+	/*
+	 * Configure the power sense and control lines.  Place the USB
+	 * host controller in reset.
+	 */
+#if defined(CONFIG_ARCH_EDB9312) | defined(CONFIG_ARCH_EDB9315)
+	/*
+	 * For EDB9315 boards, turn on USB by clearing EGPIO9.
+	 */
+	uiPBDR = inl(GPIO_PBDR) & 0xfd;
+	outl( uiPBDR, GPIO_PBDR );
+
+	uiPBDDR = inl(GPIO_PBDDR) | 0x02;
+	outl( uiPBDDR, GPIO_PBDDR );
+#endif
+
+	/*
+	 * Now, carefully enable the USB clock, and take
+	 * the USB host controller out of reset.
+	 */
+	writel (readl ((void *)SYSCON_PWRCNT) | (1<< 28),(void *)SYSCON_PWRCNT);
+
+}
+
+static int __init ep93xx_ohci_init(void)
+{
+	static struct pci_dev dev = {
+		.name = "ep93xx",
+	};
+	static struct pci_device_id id = {
+		.driver_data = 0,
+	};
+	int ret;
+
+	/*
+	 * Only support USB on rev D1 and later chips.
+         */
+	if((inl(SYSCON_CHIPID) >> 28) <= 3)
+		return -EBUSY;
+	/*
+	 * Request memory resources.
+	 */
+//	if (!request_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT, "usb-ohci"))
+//		return -EBUSY;
+
+	ep93xx_ohci_configure();
+
+	/*
+	 * Initialise the generic OHCI driver.
+	 */
+	ret = hc_found_ohci(&dev, IRQ_USH, (void *)USB_BASE, &id);
+
+	return ret;
+}
+
+static void __exit ep93xx_ohci_exit(void)
+{
+	hc_remove_ohci(ep93xx_ohci);
+
+	/*
+	 * Put the USB host controller into reset.
+	 */
+
+	/*
+	 * Stop the USB clock.
+	 */
+}
+
+module_init(ep93xx_ohci_init);
+module_exit(ep93xx_ohci_exit);
diff -urN linux-2.4.29/drivers/usb/host/usb-ohci.h linux-2.4.29-uc1/drivers/usb/host/usb-ohci.h
--- linux-2.4.29/drivers/usb/host/usb-ohci.h	2005-01-19 14:10:07.000000000 +0000
+++ linux-2.4.29-uc1/drivers/usb/host/usb-ohci.h	2005-06-14 02:12:07.000000000 +0100
@@ -439,7 +439,11 @@
 
 /*-------------------------------------------------------------------------*/
 
+#if defined(CONFIG_ARCH_EP93XX)
+#define ALLOC_FLAGS (in_interrupt () ? GFP_ATOMIC : GFP_NOIO)
+#else
 #define ALLOC_FLAGS (in_interrupt () || current->state != TASK_RUNNING ? GFP_ATOMIC : GFP_NOIO)
+#endif
 
 #ifdef DEBUG
 #	define OHCI_MEM_FLAGS	SLAB_POISON
@@ -448,9 +452,11 @@
 #endif
  
 #ifndef CONFIG_PCI
+#ifndef CONFIG_ARCH_EP9312
 #	error "usb-ohci currently requires PCI-based controllers"
 	/* to support non-PCI OHCIs, you need custom bus/mem/... glue */
 #endif
+#endif
 
 
 /* Recover a TD/ED using its collision chain */
@@ -642,3 +648,9 @@
 	pci_pool_free (hc->dev_cache, dev, dev->dma);
 }
 
+#ifdef CONFIG_ARCH_EP9312
+/* For initializing controller (mask in an HCFS mode too) */
+#define	OHCI_CONTROL_INIT \
+			(OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
+#endif
+
diff -urN linux-2.4.29/drivers/usb/Makefile linux-2.4.29-uc1/drivers/usb/Makefile
--- linux-2.4.29/drivers/usb/Makefile	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/usb/Makefile	2005-06-14 02:12:06.000000000 +0100
@@ -49,6 +49,7 @@
 
 # Each configuration option enables a list of files.
 
+obj-$(CONFIG_USB_EDB7312)	+= edb7312-usb.o
 obj-$(CONFIG_USB)		+= usbcore.o
 
 # EHCI should initialize/link before the other HCDs
@@ -76,6 +77,20 @@
 ifeq ($(CONFIG_USB_OHCI),y)
 	obj-y += host/usb-ohci.o
 endif
+subdir-$(CONFIG_USB_OHCI_SA1111)+= host
+ifeq ($(CONFIG_USB_OHCI_SA1111),y)
+	obj-y += host/usb-ohci.o host/usb-ohci-sa1111.o
+endif
+subdir-$(CONFIG_USB_OHCI_EP93XX)+= host
+ifeq ($(CONFIG_USB_OHCI_EP93XX),y)
+	obj-y += host/usb-ohci.o host/usb-ohci-ep93xx.o
+endif
+subdir-$(CONFIG_USB_OHCI_AT91)	+= host
+ifeq ($(CONFIG_USB_OHCI_AT91),y)
+  ifneq ($(CONFIG_USB_OHCI),y)
+	obj-y += host/usb-ohci.o
+  endif
+endif
 
 subdir-$(CONFIG_USB_SL811HS_ALT)	+= host
 subdir-$(CONFIG_USB_SL811HS)	+= host
diff -urN linux-2.4.29/drivers/video/Config.in linux-2.4.29-uc1/drivers/video/Config.in
--- linux-2.4.29/drivers/video/Config.in	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/video/Config.in	2005-06-14 02:12:26.000000000 +0100
@@ -8,7 +8,13 @@
 bool 'Support for frame buffer devices (EXPERIMENTAL)' CONFIG_FB
 
 if [ "$CONFIG_FB" = "y" ]; then
-   define_bool CONFIG_DUMMY_CONSOLE y
+   if [ "$CONFIG_SUPERH" = "y" ]; then
+      if [ "$CONFIG_SH_KEYWEST" = "y" ]; then
+         bool '  MediaQ MQ-200 support' CONFIG_FB_MQ200
+      fi
+   else
+	  define_bool CONFIG_DUMMY_CONSOLE y
+   fi
    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
       if [ "$CONFIG_PCI" = "y" ]; then
          tristate '  nVidia Riva support (EXPERIMENTAL)' CONFIG_FB_RIVA
@@ -29,10 +35,16 @@
       if [ "$CONFIG_PCI" = "y" ]; then
          tristate '  Permedia3 support (EXPERIMENTAL)' CONFIG_FB_PM3
       fi
+      if [ "$CONFIG_FB_COBRA5272" = "y" ]; then
+         tristate '  EPSON S1D13706 Support (EXPERIMENTAL)' CONFIG_FB_S1D13706
+         tristate '  EPSON S1D13806 Support (EXPERIMENTAL)' CONFIG_FB_S1D13806
+      fi
    fi
    if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
       bool '  Acorn VIDC support' CONFIG_FB_ACORN
    fi
+   dep_bool '  Acorn VIDC support' CONFIG_FB_ACORN $CONFIG_ARCH_ACORN
+   dep_bool '  CLPS711X LCD support' CONFIG_FB_CLPS711X $CONFIG_ARCH_CLPS711X
    dep_tristate '  Cyber2000 support' CONFIG_FB_CYBER2000 $CONFIG_PCI
    if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
       bool '  SA-1100 LCD support' CONFIG_FB_SA1100
@@ -40,6 +52,29 @@
    if [ "$CONFIG_APOLLO" = "y" ]; then
       define_bool CONFIG_FB_APOLLO y
    fi
+   if [ "$CONFIG_ARCH_EP9312" = "y" -o "$CONFIG_ARCH_EP9315" = "y" ]; then
+      bool '  EP93xx Frame Buffer support' CONFIG_FB_EP93XX
+   else
+      define_bool CONFIG_FB_EP93XX n
+   fi
+   if [ "$CONFIG_FB_EP93XX" = "y" ]; then
+      choice '    EP93xx Frame Buffer Display' \
+             "CRT_Display CONFIG_FB_CRT_EP93XX \
+              LCD_Display CONFIG_FB_LCD_EP93XX \
+              NTSC_Display CONFIG_FB_CX25871" LCD_Display
+      choice '    EP93xx Color Depth' \
+             "8bpp CONFIG_FB_EP93XX_8BPP \
+              16bpp_565 CONFIG_FB_EP93XX_16BPP_565" 16bpp_565
+      dep_bool '    EP93xx NTSC overscan' CONFIG_FB_CX25871_OVERSCAN $CONFIG_FB_CX25871
+   fi
+   dep_bool '  EDB7312 LCD support' CONFIG_FB_EDB7312 $CONFIG_ARCH_EDB7312
+   if [ "$CONFIG_FB_EDB7312" = "y" ]; then
+      bool '    EDB7312 quazi-16bpp support (required for X)' CONFIG_FB_EDB7312_16BPP
+   fi
+   if [ "$CONFIG_ARCH_IPOD" = "y" ]; then
+      tristate '  iPod LCD support' CONFIG_FB_IPOD
+   fi
+
    if [ "$CONFIG_Q40" = "y" ]; then
       define_bool CONFIG_FB_Q40 y
    fi
@@ -184,6 +219,20 @@
 	 fi
       fi
    fi
+   if [ "$ARCH" = "microblaze" ]; then
+      bool '  Xilinx frame buffer' CONFIG_FB_XILINX
+      define_tristate CONFIG_FBCON_CFB32 y
+   fi
+   if [ "$ARCH" = "m68knommu" ]; then
+      bool '  Dragonball frame buffer' CONFIG_FB_MC68X328
+      if [ "$CONFIG_FB_MC68X328" = "y" ]; then
+         choice 'Screen type' "\
+           Monochrome,1=White,0=Black CONFIG_FB_MC68X328_MONO10 \
+           Monochrome,0=White,1=Black CONFIG_FB_MC68X328_MONO01 \
+           Colour CONFIG_FB_MC68X328_COLOUR \
+           " Monochrome,1=White,0=Black
+      fi
+   fi
    if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
       bool '  SBUS and UPA framebuffers' CONFIG_FB_SBUS
       if [ "$CONFIG_FB_SBUS" != "n" ]; then
@@ -232,11 +281,18 @@
    if [ "$CONFIG_NINO" = "y" ]; then
       bool '  TMPTX3912/PR31700 frame buffer support' CONFIG_FB_TX3912
    fi
+   if [ "$CONFIG_CPU_S3C44B0X" = "y" ]; then
+      tristate '  Samsung S3C44B0X built-in LCD controller frame buffer support' CONFIG_FB_S3C44B0X
+   fi
    if [ "$CONFIG_PCI" = "y" -o "$CONFIG_CPU_VR41XX" = "y" ]; then
       tristate '  ITE IT8181E/F support' CONFIG_FB_IT8181
    fi
+   if [ "$CONFIG_UCLINUX" = "y" ]; then
+      bool '  MediaQ 1100 framebuffer' CONFIG_FB_MQ1100
+   fi
    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
       tristate '  Virtual Frame Buffer support (ONLY FOR TESTING!) (EXPERIMENTAL)' CONFIG_FB_VIRTUAL
+      tristate '  Virtual Frame Buffer support (small 1KB VRAM) (ONLY FOR TESTING!) (EXPERIMENTAL)' CONFIG_FB_VIRTUAL_SMALL
    fi
 
    bool '  Advanced low level driver options' CONFIG_FBCON_ADVANCED
@@ -245,6 +301,7 @@
       tristate '    2 bpp packed pixels support' CONFIG_FBCON_CFB2
       tristate '    4 bpp packed pixels support' CONFIG_FBCON_CFB4
       tristate '    8 bpp packed pixels support' CONFIG_FBCON_CFB8
+      tristate '    12 bpp packed pixels support' CONFIG_FBCON_CFB12
       tristate '    16 bpp packed pixels support' CONFIG_FBCON_CFB16
       tristate '    24 bpp packed pixels support' CONFIG_FBCON_CFB24
       tristate '    32 bpp packed pixels support' CONFIG_FBCON_CFB32
@@ -265,6 +322,7 @@
 	   "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_RETINAZ3" = "y" -o \
 	   "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
 	   "$CONFIG_FB_BWTWO" = "y" -o "$CONFIG_FB_CLGEN" = "y"  -o \
+           "$CONFIG_FB_MQ1100" = "y" -o \
 	   "$CONFIG_FB_TX3912" = "y" ]; then
 	 define_tristate CONFIG_FBCON_MFB y
       else
@@ -273,18 +331,21 @@
 	      "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_RETINAZ3" = "m" -o \
 	      "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
 	      "$CONFIG_FB_BWTWO" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
+              "$CONFIG_FB_MQ1100" = "y" -o \
 	      "$CONFIG_FB_TX3912" = "m" ]; then
 	    define_tristate CONFIG_FBCON_MFB m
 	 fi
       fi
       if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
 	   "$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
+           "$CONFIG_FB_MQ1100" = "y" -o \
 	   "$CONFIG_FB_TX3912" = "y" ]; then
 	 define_tristate CONFIG_FBCON_CFB2 y
 	 define_tristate CONFIG_FBCON_CFB4 y
       else
 	 if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
 	      "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
+              "$CONFIG_FB_MQ1100" = "y" -o \
 	      "$CONFIG_FB_TX3912" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB2 m
 	    define_tristate CONFIG_FBCON_CFB4 m
@@ -312,6 +373,8 @@
 	   "$CONFIG_FB_TX3912" = "y" -o \
 	   "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" -o \
 	   "$CONFIG_FB_STI" = "y" -o "$CONFIG_FB_HP300" = "y" -o \
+           "$CONFIG_FB_MQ1100" = "y" -o \
+           "$CONFIG_FB_EP93XX" = "y" -o \
 	   "$CONFIG_FB_INTEL" = "y" ]; then
 	 define_tristate CONFIG_FBCON_CFB8 y
       else
@@ -335,10 +398,19 @@
 	      "$CONFIG_FB_RADEON" = "m" -o "$CONFIG_FB_INTEL" = "m" -o \
 	      "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
 	      "$CONFIG_FB_TX3912" = "m" -o "$CONFIG_FB_NEOMAGIC" = "m" -o \
+              "$CONFIG_FB_MQ1100" = "m" -o \
+              "$CONFIG_FB_EP93XX" = "m" -o \
 	      "$CONFIG_FB_STI" = "m" -o "$CONFIG_FB_INTEL" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB8 m
 	 fi
       fi
+      if [ "$CONFIG_FB_EDB7312" = "y" ]; then
+         if [ "$CONFIG_FB_EDB7312_16BPP" = "y" ]; then
+            define_tristate CONFIG_FBCON_CFB16 y
+         else
+            define_tristate CONFIG_FBCON_CFB12 y
+         fi
+      fi
       if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \
 	   "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VESA" = "y" -o \
 	   "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \
@@ -354,6 +426,8 @@
 	   "$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_3DFX" = "y"  -o \
 	   "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \
 	   "$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_VOODOO1" = "y" -o \
+           "$CONFIG_FB_MQ1100" = "y" -o \
+           "$CONFIG_FB_EP93XX" = "y" -o \
 	   "$CONFIG_FB_NEOMAGIC" = "y" -o "$CONFIG_FB_INTEL" = "y" ]; then
 	 define_tristate CONFIG_FBCON_CFB16 y
       else
@@ -372,6 +446,8 @@
 	      "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
 	      "$CONFIG_FB_INTEL" = "m" -o \
 	      "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" -o \
+              "$CONFIG_FB_MQ1100" = "m" -o \
+              "$CONFIG_FB_EP93XX" = "m" -o \
 	      "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_INTEL" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB16 m
 	 fi
@@ -512,6 +588,13 @@
 	 if [ "$CONFIG_ARM" = "y" -a "$CONFIG_ARCH_ACORN" = "y" ]; then
 	    define_bool CONFIG_FONT_ACORN_8x8 y
 	 fi
+	 if [ "$CONFIG_FB_EP93XX" = "y" ]; then
+	    define_bool CONFIG_FONT_ACORN_8x8 y
+	 fi
+	 if [ "$CONFIG_ARM" = "y" -a "$CONFIG_ARCH_EDB7312" = "y" ]; then
+	    define_bool CONFIG_FONT_VTX_6x8 y
+	    define_bool CONFIG_FONT_VTX_4x8 y
+	 fi
       fi
    fi
 fi
diff -urN linux-2.4.29/drivers/video/dragonfb.c linux-2.4.29-uc1/drivers/video/dragonfb.c
--- linux-2.4.29/drivers/video/dragonfb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/dragonfb.c	2005-06-14 02:12:27.000000000 +0100
@@ -0,0 +1,824 @@
+/*
+ * linux/drivers/video/dragonfb.c -- Frame Buffer driver for the 68EZ328 & 68VZ328
+ *
+ *  (C) 03 Dec 2001 by Khaled Hassounah <khassounah@mediumware.net>
+ *
+ *  Contributors:
+ *
+ *  29 March 2002 by Daniel Haensse <daniel.haensse@alumni.ethz.ch),
+ *  added support for the 68vz328 and some minor changes
+ *
+ *  Following are few comments about this driver, if you fix any of the issues
+ *  please remove them from this list:
+ *
+ *  1) Most of the components to support the standard frame buffer console
+ *     exist, but it hasn't been tested before. So probably you'll need to
+ *     do some debugging before you get working
+ *
+ *  2) The LCD settings (resolution, color depth, etc.) have been dealt with
+ *     as configuration settings as opposed to user settings because we are
+ *     with an LCD in which those settings are mostly constant
+ *
+ *  3) The driver has been tested on a 68EZ328 with a 320X240 monochrome
+ *     LCD.
+ *
+ *  4) No color support yet, I'll try to work on it, if you get this version
+ *     check again later (or check again ;-) and you might find it, otherwise
+ *     maybe you want to make some smiles in the open source community and do
+ *     it yourself ;-)
+ *
+ *  5) This is effort is much less than perfect, so have fun :)
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+
+#include <video/fbcon.h>
+
+#include <video/fbcon-mfb.h>
+
+// include display controller specific stuff, be aware of the differences
+#if defined(CONFIG_M68EZ328)
+#include <asm/MC68EZ328.h>
+#elif defined(CONFIG_M68VZ328)
+#include <asm/MC68VZ328.h>
+#endif
+
+//#define DEBUG
+
+//const int config_xres = 0;
+//const int config_yres = 0;
+//const int config_bpp = 0;
+//const int config_buswidth = 0;
+
+// Define diplay type
+#if defined(CONFIG_UG24U01WGHT3L)
+        // Display driving
+        #define X_RES 240       // X-Size
+        #define Y_RES 320       // Y-Size
+        #define REFRATE 20    // See motorola manual LRRA
+        #define PIXRATE 0    // See motorola manual LPXCD
+        #define ACRATE  0x00    // See motorola manual LACDRC
+        #define GRAYSCALE 0x73  // See motorola manual LGPMR
+        #define POLARITY 0x00   // See motorola manual LPOLCF
+        #define BUSWIDTH_LPICF 0x08 // LPICF: 4 bit interface, 1bit = 0x00, 2bit=0x04,  4bit= 0x08, 8bit= 0x0c (VZ only)
+#elif define(CONFIG_UG24U03WGHT3A)
+        // Display driving
+        #define X_RES 320       // X-Size
+        #define Y_RES 240       // Y-Size
+        #define REFRATE 20    // See motorola manual LRRA
+        #define PIXRATE 0    // See motorola manual LPXCD
+        #define ACRATE  0x00    // See motorola manual LACDRC
+        #define GRAYSCALE 0x73  // See motorola manual LGPMR
+        #define POLARITY 0x00   // See motorola manual LPOLCF
+        #define BUSWIDTH_LPICF 0x08 // LPICF: 4 bit interface, 1bit = 0x00, 2bit=0x04,  4bit= 0x08, 8bit= 0x0c (VZ only)
+#elif define(CONFIG_UG32F24CMGF3A)
+        // Display driving
+        #define X_RES 960       // X-Size 320xRGB
+        #define Y_RES 240       // Y-Size
+        #define REFRATE 20    // See motorola manual LRRA
+        #define PIXRATE 1    // See motorola manual LPXCD
+        #define ACRATE  0x00    // See motorola manual LACDRC
+        #define GRAYSCALE 0x73  // See motorola manual LGPMR
+        #define POLARITY 0x00   // See motorola manual LPOLCF
+        #define BUSWIDTH_LPICF 0x0c // LPICF: 4 bit interface, 1bit = 0x00, 2bit=0x04,  4bit= 0x08, 8bit= 0x0c (VZ only)
+#endif
+
+#if defined(CONFIG_FB_DRAGON_MONO)
+	#define BPP 1
+        #define GRAY_LPICF      0x00
+#elif defined(CONFIG_FB_DRAGON_4GRAY)
+	#define BPP 2
+        #define GRAY_LPICF      0x01
+#elif defined(CONFIG_FB_DRAGON_16GRAY) // Well 16GRAY does not mean that we can use 16 gray scales, we have a better resolution of the pixel density only
+	#define BPP 2
+        #define GRAY_LPICF      0x02
+#endif
+
+
+
+
+
+
+/* few useful macros */
+
+#define LINE_LENGTH(x, bpp) (((x*bpp+31)&-32)>>3)
+#define LENGTH(x, y, bpp) (x * y * bpp / 8)
+
+/* The video ram, which should be declared in the linker script */
+
+extern int __vram_start;
+
+/* few structs holding default or initialization info */
+static struct fb_info fb_info;
+static struct display disp;
+static int display_initialized[MAX_NR_CONSOLES];
+
+static struct fb_var_screeninfo default_var = {
+	xres:		X_RES,	/* until I define the mechanism for passing resolutions */
+	yres:		Y_RES,	/* ditto */
+
+	/* Dragonballs (EZ & VZ) support virtual screen, but I'm in a hurry
+	   to implement it, if you need it, check out the the LVPW register
+	   and add the support, it should be pretty easy, all you need is
+	   to modify the dragon_set_var method to allow it */
+
+	xres_virtual:	X_RES,	/* too early for virtual support */
+	yres_virtual:	Y_RES,	/* ditto */
+	xoffset:	0,		/* ditto */
+	yoffset:	0,		/* ditto */
+	bits_per_pixel:	BPP,	/* see xres */
+	grayscale:	0,		/* now monochrome tomorrow grayscale :-) */
+
+	red:		{0,1,0},	/* only length is needed (not true color) */
+	green:		{0,1,0},	/* ditto */
+	blue:		{0,1,0},	/* ditto */
+	transp:		{0,0,0},	/* we don't support transparency */
+
+	activate:	FB_ACTIVATE_NOW,
+	height:		-1,		/* is this really important? might be */
+	width:		-1,		/* later */
+
+	accel_flags:	FB_ACCEL_NONE,
+
+	vmode:		FB_VMODE_NONINTERLACED,
+};
+
+static struct fb_fix_screeninfo current_fix = {
+	id:		"Dragon",
+	smem_start:	(__u32)&__vram_start, /* initially, we'll fill it later */
+	smem_len:	LENGTH(X_RES, Y_RES, BPP), /* initially, we'll fill it later */
+	type:		FB_TYPE_PACKED_PIXELS, /* this should always be true for dragonballs */
+	visual:		FB_VISUAL_MONO10, /* this should depend on LCD used */
+	line_length:	LINE_LENGTH(X_RES, BPP),
+	accel:		FB_ACCEL_NONE, /* but still like a breeze ;-) */
+};
+
+static int currcon = 0;
+
+/*int dragon_fb_init(void);
+int dragon_fb_setup(char*);*/
+
+/* ------------------- chipset specific functions -------------------------- */
+
+
+static void set_color_bitfields(struct fb_var_screeninfo *var)
+{
+    switch (var->bits_per_pixel) {
+	case 1:
+	    var->red.offset = 0;
+	    var->red.length = 1;
+	    var->green.offset = 0;
+	    var->green.length = 1;
+	    var->blue.offset = 0;
+	    var->blue.length = 1;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 8:
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 0;
+	    var->green.length = 8;
+	    var->blue.offset = 0;
+	    var->blue.length = 8;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 16:	/* RGB 565 */
+	    var->red.offset = 0;
+	    var->red.length = 5;
+	    var->green.offset = 5;
+	    var->green.length = 6;
+	    var->blue.offset = 11;
+	    var->blue.length = 5;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 24:	/* RGB 888 */
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 8;
+	    var->green.length = 8;
+	    var->blue.offset = 16;
+	    var->blue.length = 8;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 32:	/* RGBA 8888 */
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 8;
+	    var->green.length = 8;
+	    var->blue.offset = 16;
+	    var->blue.length = 8;
+	    var->transp.offset = 24;
+	    var->transp.length = 8;
+	    break;
+    }
+    var->red.msb_right = 0;
+    var->green.msb_right = 0;
+    var->blue.msb_right = 0;
+    var->transp.msb_right = 0;
+}
+
+
+static int dragon_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+			 unsigned *blue, unsigned *transp,
+			 struct fb_info *info)
+{
+#if defined(DEBUG)
+	printk(KERN_DEBUG "fb%d: start: dragon_getcolreg\n",
+		GET_FB_IDX(fb_info.node));
+#endif
+
+    /*
+     *  Read a single color register and split it into colors/transparent.
+     *  The return values must have a 16 bit magnitude.
+     *  Return != 0 for invalid regno.
+     */
+
+    /* ... */
+    return 0;
+}
+
+static int dragon_setcolreg(unsigned regno, unsigned red, unsigned green,
+			 unsigned blue, unsigned transp,
+			 struct fb_info *info)
+{
+   /*
+     *  Set a single color register. The values supplied have a 16 bit
+     *  magnitude.
+     *  Return != 0 for invalid regno.
+     */
+#if defined(DEBUG)
+	printk(KERN_DEBUG "fb%d: start: dragon_setcolreg\n",
+		GET_FB_IDX(fb_info.node));
+#endif
+
+#if 0
+    if (regno < 16) {
+	/*
+	 *  Make the first 16 colors of the palette available to fbcon
+	 */
+	if (is_cfb15)		/* RGB 555 */
+	    ...fbcon_cmap.cfb16[regno] = ((red & 0xf800) >> 1) |
+					 ((green & 0xf800) >> 6) |
+					 ((blue & 0xf800) >> 11);
+	if (is_cfb16)		/* RGB 565 */
+	    ...fbcon_cmap.cfb16[regno] = (red & 0xf800) |
+					 ((green & 0xfc00) >> 5) |
+					 ((blue & 0xf800) >> 11);
+	if (is_cfb24)		/* RGB 888 */
+	    ...fbcon_cmap.cfb24[regno] = ((red & 0xff00) << 8) |
+					 (green & 0xff00) |
+					 ((blue & 0xff00) >> 8);
+	if (is_cfb32)		/* RGBA 8888 */
+	    ...fbcon_cmap.cfb32[regno] = ((red & 0xff00) << 16) |
+					 ((green & 0xff00) << 8) |
+					 (blue & 0xff00) |
+					 ((transp & 0xff00) >> 8);
+    }
+#endif
+
+    /* ... */
+    return 0;
+}
+
+    /*
+     *  Get the Colormap
+     */
+
+static int dragon_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info)
+{
+    if (con == currcon) /* current console? */
+	return fb_get_cmap(cmap, kspc, dragon_getcolreg, info);
+    else if (fb_display[con].cmap.len) /* non default colormap? */
+	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+    else
+	fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+		     cmap, kspc ? 0 : 2);
+    return 0;
+}
+
+    /*
+     *  Set the Colormap
+     */
+
+static int dragon_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info)
+{
+    int err;
+
+    if (!fb_display[con].cmap.len) {	/* no colormap allocated? */
+	if ((err = fb_alloc_cmap(&fb_display[con].cmap,
+			      1<<fb_display[con].var.bits_per_pixel, 0)))
+	    return err;
+    }
+    if (con == currcon)			/* current console? */
+	return fb_set_cmap(cmap, kspc, dragon_setcolreg, info);
+    else
+	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+    return 0;
+}
+
+
+static void do_install_cmap(int con, struct fb_info *info)
+{
+/*    if (con != currcon)
+	return;
+    if (fb_display[con].cmap.len)
+	fb_set_cmap(&fb_display[con].cmap, 1, vfb_setcolreg, info);
+    else
+	fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), 1,
+		    vfb_setcolreg, info);*/
+}
+
+/* ------------------- fbcon specific functions -------------------------- */
+
+static int dragoncon_switch(int con, struct fb_info *info)
+{
+    /* Do we have to save the colormap? */
+    /*if (fb_display[currcon].cmap.len)
+	fb_get_cmap(&fb_display[currcon].cmap, 1, dragon_getcolreg, info);*/
+
+    currcon = con;
+    /* Install new colormap */
+    do_install_cmap(con, info);
+    return 0;
+}
+
+
+static int dragoncon_updatevar(int con, struct fb_info *info)
+{
+    /* Nothing */
+    return 0;
+}
+
+static void dragoncon_blank(int blank_mode, struct fb_info *info)
+{
+#if defined(DEBUG)
+	printk(KERN_DEBUG "fb%d: start: dragon_blank\n", 
+		GET_FB_IDX(fb_info.node));
+#endif
+
+    /*
+     *  Blank the screen if blank_mode != 0, else unblank. If blank == NULL
+     *  then the caller blanks by setting the CLUT (Color Look Up Table) to all
+     *  black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due
+     *  to e.g. a video mode which doesn't support it. Implements VESA suspend
+     *  and powerdown modes on hardware that supports disabling hsync/vsync:
+     *    blank_mode == 2: suspend vsync
+     *    blank_mode == 3: suspend hsync
+     *    blank_mode == 4: powerdown
+     */
+
+	/* The display must be driven all the time, otherwise a DC voltage builds up which destroy the crystal
+           put we can disable the display (if it has that function) and switch off the backlight
+         */
+	if (blank_mode == 0)    // Add your code here, for normal operation
+		{
+#if defined(CONFIG_DRAGONIXVZ)
+        PBDATA=(PBDATA&~0x80)|0x40; // Display on, backlight on#endif
+#endif
+                }
+	else                    // add your code here to save power and save the forest
+		{
+#if defined(CONFIG_DRAGONIXVZ)
+        PBDATA=(PBDATA&~0x40)|0x80; // Display on, backlight on#endif
+#endif
+                }
+}
+
+static void dragon_initialize_display(struct display *disp)
+{
+#if defined(DEBUG)
+	printk(KERN_DEBUG "fb: start: dragon_initialize_display\n");
+#endif
+
+	disp->screen_base = fb_info.screen_base;
+
+
+	switch (default_var.bits_per_pixel) { /* maybe I should pass a var and use it here */
+#ifdef FBCON_HAS_MFB
+	case 1:
+                printk(KERN_INFO "Using fbcon_mfb\n");
+		disp->dispsw = &fbcon_mfb;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB2
+	case 2:
+                printk(KERN_INFO "Using fbcon_CFB2\n");
+		disp->dispsw = &fbcon_cfb2;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB4
+	case 4:
+		disp->dispsw = &fbcon_cfb4;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		disp->dispsw = &fbcon_cfb8;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		disp->dispsw = &fbcon_cfb16;
+		disp->dispsw_data = fbcon_cmap.cfb16;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB24
+	case 24:
+		disp->dispsw = &fbcon_cfb24;
+		disp->dispsw_data = fbcon_cmap.cfb24;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB32
+	case 32:
+		disp->dispsw = &fbcon_cfb32;
+		disp->dispsw_data = fbcon_cmap.cfb32;
+		break;
+#endif
+	default:
+		disp->dispsw = &fbcon_dummy;
+		break;
+	}
+
+	//disp->dispsw = &fbcon_dummy;
+
+	disp->visual = current_fix.visual;
+	disp->type = current_fix.type;
+   	disp->type_aux = current_fix.type_aux;
+	disp->type_aux = current_fix.type_aux;
+	disp->ypanstep = current_fix.ypanstep;
+	disp->ywrapstep = current_fix.ywrapstep;
+	disp->line_length = current_fix.line_length;
+	disp->can_soft_blank = 1;
+	disp->inverse = 0;
+
+	memcpy(&disp->var, &default_var, sizeof(struct fb_var_screeninfo));
+}
+
+
+/* ------------ Hardware Independent Functions ------------ */
+
+
+
+
+
+    /*
+     *  Setup
+     */
+
+int __init dragon_fb_setup(char *options)
+{
+#if defined(DEBUG)
+	printk(KERN_DEBUG "fb%d: start: dragon_fb_setup\n",
+		GET_FB_IDX(fb_info.node));
+#endif
+
+    /* Parse user speficied options (`video=dragon_fb:') */
+
+	/* no parsing yet */
+
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+
+    /*
+     *  Frame buffer operations
+     */
+
+/* If all you need is that - just don't define ->fb_open */
+/*static int dragon_fb_open(const struct fb_info *info, int user)
+{
+    return 0;
+}*/
+
+/* If all you need is that - just don't define ->fb_release */
+/*static int dragon_fb_release(const struct fb_info *info, int user)
+{
+    return 0;
+}*/
+
+
+    /*
+     *  Get the Fixed Part of the Display
+     */
+
+static int dragon_get_fix(struct fb_fix_screeninfo *fix, int con,
+		       struct fb_info *info)
+{
+#if defined(DEBUG)
+	printk(KERN_DEBUG "fb%d: start: dragon_get_fix\n",
+		GET_FB_IDX(fb_info.node));
+#endif
+
+    /* we only have one mode, so our fix_screeninfo struct
+       always has the same values, just throw it back to the user
+       current_fix was initialized earlier in init */
+
+#if defined(DEBUG)
+	printk(KERN_DEBUG "fb: info: getting fix for console %d\n", con);
+#endif
+
+    memcpy(fix, &current_fix, sizeof(struct fb_fix_screeninfo));
+
+    return 0;
+}
+
+
+    /*
+     *  Get the User Defined Part of the Display
+     */
+
+static int dragon_get_var(struct fb_var_screeninfo *var, int con,
+		       struct fb_info *info)
+{
+#if defined(DEBUG)
+	printk(KERN_DEBUG "fb%d: start: dragon_get_var\n", 
+		GET_FB_IDX(fb_info.node));
+
+	printk(KERN_DEBUG "fb: info: getting var for console %d\n", con);
+#endif
+
+    if (con == -1)
+	*var = default_var;
+    else
+	*var = fb_display[con].var;
+
+    set_color_bitfields(var);
+
+    return 0;
+}
+
+
+    /*
+     *  Set the User Defined Part of the Display
+     */
+
+static int dragon_set_var(struct fb_var_screeninfo *var, int con,
+		       struct fb_info *info)
+{
+    int activate = var->activate;
+
+    struct display *display;
+
+#if defined(DEBUG)
+	printk(KERN_DEBUG "fb%d: start: dragon_set_var\n",
+		GET_FB_IDX(fb_info.node));
+#endif
+
+    if (con >= 0)
+    {
+	display = &fb_display[con];
+
+	/* this is the mechanism I use to initialize the display
+		structures. You should have noticed that I assume
+		that fbcon will call set_var at least once before
+		using the display, I need to verify that */
+
+        if (!display_initialized[con])
+        {
+            dragon_initialize_display(display);
+            display_initialized[con] = 1;
+        }
+    }
+    else
+	display = &disp;	/* used during initialization */
+
+    /*
+     *  We are working with an LCD, which means that we
+     *  can't allow for modifications of many of the screen's
+     *  usually updateable parameters
+     */
+
+    /** I wonder if the first time a display is initialized, this method
+        is called by fbcon to initialize the display struct, I should
+        test this, VERY SERIOUS my temp solution has been to */
+
+    if (var->xres != display->var.xres ||
+        var->yres != display->var.yres ||
+        var->xres_virtual != var->xres ||  /* virtual is not supported yet */
+        var->yres_virtual != var->yres ||
+        (var->xoffset != 0 && !(var->vmode & FB_VMODE_CONUPDATE)) ||
+        (var->yoffset != 0 && !(var->vmode & FB_VMODE_CONUPDATE)) ||
+        (var->bits_per_pixel != display->var.bits_per_pixel))
+    {
+	return -EINVAL;
+    }
+
+    set_color_bitfields(var); /* I don't really know what this does yet, I'll have to work on it */
+
+     /* Since we don't allow anything to change anyways,
+	there's no need to update the display var, makes 
+	our lifes much easier :-)*/
+
+    return 0;
+}
+
+    /*
+     *  In most cases the `generic' routines (fbgen_*) should be satisfactory.
+     *  However, you're free to fill in your own replacements.
+     */
+
+static struct fb_ops dragonfb_ops = {
+	owner:		THIS_MODULE,
+	fb_get_fix:	dragon_get_fix,
+	fb_get_var:	dragon_get_var,
+	fb_set_var:	dragon_set_var,
+	fb_get_cmap:	dragon_get_cmap,
+	fb_set_cmap:	dragon_set_cmap,
+};
+
+    /*
+     *  Initialization
+     */
+
+void dragon_lcd_init()
+{
+	int i = 0;
+	int translation; /* used to translate some settings to their register values */
+
+#if defined(DEBUG)
+	printk(KERN_DEBUG "fb: start: dragon_lcd_init\n");
+
+	printk(KERN_DEBUG "fb: debug: dragon_lcd_init: Setting LSSA to %08x\n", (int) &__vram_start);
+#endif
+
+// The order the initialisation is performed, is very important. The board may crash!!!
+#if defined(CONFIG_M68EZ328)
+        // Set Controller io pins according to the interface used
+        #if BUSWIDTH_LPICF == 0x00
+                PCSEL&=~0xf1;   //
+                PCPDEN&=~0xf1;  // We don't need pull-ups for those pins
+        #elif BUSWIDTH_LPICF == 0x04
+                PCSEL&=~0xf3;
+                PCPDEN&=~0xf3;  // We don't need pull-ups for those pins
+        #elif BUSWIDTH_LPICF == 0x08
+                PCSEL&=~0xff;
+                PCPDEN&=~0xff;  // We don't need pull-ups for those pins
+        #endif
+
+        LSSA = &__vram_start; /* the LCD Screen Starting Address Register should point at vram */
+	LXMAX = X_RES;
+	LYMAX = Y_RES-1;        // see 8.3.4 of the manual, size is +1
+
+        LVPW = X_RES>>(4-GRAY_LPICF);
+        LPICF = BUSWIDTH_LPICF|GRAY_LPICF;
+        LPOLCF = POLARITY;
+        LACDRC = ACRATE;
+        LPXCD =  PIXRATE;
+        LRRA = REFRATE;
+
+	LCKCON = 0x80; // Fixme change this when you use a dedicated SRAM or ROM
+        LPOSR = 0x00;
+        LGPMR = GRAYSCALE;
+
+#elif defined(CONFIG_M68VZ328)
+        // Set Controller io pins according to the interface used
+        #if BUSWIDTH_LPICF == 0x00
+                PCSEL&=~0xf1;   //
+                PCPDEN&=~0xf1;  // We don't need pull-ups for those pins
+        #elif BUSWIDTH_LPICF == 0x04
+                PCSEL&=~0xf3;
+                PCPDEN&=~0xf3;  // We don't need pull-ups for those pins
+        #elif BUSWIDTH_LPICF == 0x08
+                PCSEL&=~0xff;
+                PCPDEN&=~0xff;  // We don't need pull-ups for those pins
+        #elif BUSWIDTH_LPICF == 0xc0
+                PCSEL&=~0xff;
+                PCPDEN&=~0xff;  // We don't need pull-ups for those pins
+                PKSEL&=~0xf0;
+                PKPUEN&=~0xf0;  // We don't need pull-ups for those pins
+        #endif
+        LSSA = &__vram_start; /* the LCD Screen Starting Address Register should point at vram */
+	LXMAX = X_RES;
+	LYMAX = Y_RES-1;        // see 8.3.4 of the manual, size is +1
+
+        LVPW = X_RES>>(4-GRAY_LPICF);
+        LPICF = BUSWIDTH_LPICF|GRAY_LPICF;
+        LPOLCF = POLARITY;
+        LACDRC = ACRATE;
+        LPXCD =  PIXRATE;
+        LRRA = REFRATE;
+
+	LCKCON = 0x80;
+        LPOSR = 0x00;
+        LGPMR = GRAYSCALE;
+        RMCR=0;
+        DMACR=0x62;
+#endif
+
+#if defined(DEBUG)
+	/* for testing purposes */
+	for (i = 0; i < Y_RES; i+= 10)
+	{
+		memset(((char *)(&__vram_start)) + i       * X_RES * BPP / 8, 0xff, 2 * X_RES * BPP / 8);
+		memset(((char *)(&__vram_start)) + (i + 2) * X_RES * BPP / 8, 0, 8 * X_RES * BPP / 8);
+	}
+#endif
+
+
+        /* Add your custom display initialisation code here */
+#if defined(CONFIG_DRAGONIXVZ)
+        PBSEL|=0xc0;  // TIN/OUT is nDISPEN and PWMO1 is nBLEN
+        PBPUEN|=0xc0; // Enable pullups
+        PBDIR|=0xc0;  // Outputs
+        PBDATA=(PBDATA&~0x80)|0x40; // Display on, backlight on
+#endif
+}
+
+int __init dragon_fb_init(void)
+{
+#if defined(DEBUG)
+	printk(KERN_DEBUG "fb: start: dragon_fb_init\n");
+#endif
+
+	/* then we initialize our lcd */
+	dragon_lcd_init();
+
+	/* then our structures */
+	fb_info.changevar = NULL;
+	fb_info.node = -1;
+	fb_info.fbops = &dragonfb_ops;
+	fb_info.disp = &disp;
+	fb_info.switch_con = &dragoncon_switch;
+	fb_info.updatevar = &dragoncon_updatevar;
+	fb_info.blank = &dragoncon_blank;
+	fb_info.flags = FBINFO_FLAG_DEFAULT;
+
+	fb_info.screen_base = (char *)__vram_start;
+
+	dragon_initialize_display(&disp);
+
+	if (register_framebuffer(&fb_info) < 0) {
+		return -EINVAL;
+	}
+
+	printk(KERN_INFO "fb%d: end: Virtual frame buffer device initialized\n",
+		GET_FB_IDX(fb_info.node));
+        printk(KERN_INFO "(C) 2001 by Khaled Hassounah <khassounah@mediumware.net>\n");
+
+	/* uncomment this if your driver cannot be unloaded */
+	/* MOD_INC_USE_COUNT; */
+	return 0;
+}
+
+
+    /*
+     *  Cleanup
+     */
+
+void dragon_fb_cleanup(struct fb_info *info)
+{
+#if defined(DEBUG)
+	printk(KERN_DEBUG "fb%d: start: dragon_fb_cleanup\n", 
+		GET_FB_IDX(fb_info.node));
+#endif
+    /*
+     *  If your driver supports multiple boards, you should unregister and
+     *  clean up all instances.
+     */
+
+    unregister_framebuffer(&fb_info);
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+
+    /*
+     *  Modularization
+     */
+
+#ifdef MODULE
+MODULE_LICENSE("GPL");
+int init_module(void)
+{
+    return dragon_fb_init();
+}
+
+void cleanup_module(void)
+{
+    dragon_fb_cleanup(void);
+}
+#endif /* MODULE */
+
diff -urN linux-2.4.29/drivers/video/edb7312fb.c linux-2.4.29-uc1/drivers/video/edb7312fb.c
--- linux-2.4.29/drivers/video/edb7312fb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/edb7312fb.c	2005-06-14 02:12:26.000000000 +0100
@@ -0,0 +1,436 @@
+/*
+ * Framebuffer driver for the EDB7312 board
+ * Copyright (C) 2003 Vladimir Ivanov, Nucleus Systems, Ltd.
+ *
+ * based mostly on:
+ *
+ *  linux/drivers/video/anakinfb.c
+ *
+ *  Copyright (C) 2001 Aleph One Ltd. for Acunia N.V.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/fb.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <asm/memory.h>
+
+#include <video/fbcon.h>
+#ifdef CONFIG_FB_EDB7312_16BPP
+#include <video/fbcon-cfb16.h>
+#else
+#include <video/fbcon-cfb12.h>
+#endif
+
+#include <asm/hardware/clps7111.h>
+
+#define VID_X		320
+#define VID_Y		240
+#define	VID_PHYS	PAGE_OFFSET
+#define	VID_VIRT	PAGE_OFFSET
+#define VID_SIZE	0x1D000
+
+#define FB_PHYS		(fb_p)
+#define FB_VIRT		(fb_v)
+#define	FB_SIZE		(fb_size)
+
+static unsigned long fb_p, fb_v, fb_size;
+static u16 colreg[16];
+static int currcon = 0;
+static struct fb_info fb_info;
+static struct display display;
+
+static char default_font_storage[40];
+static char *default_font = "vtx6x8";
+
+#ifdef CONFIG_FB_EDB7312_16BPP
+#define TIME_REFRESH	(HZ / 4)
+static struct timer_list tmrefr;
+
+#define	FB_LLEN		(VID_X << 1)
+#else
+#define	FB_LLEN		((VID_X * 3) >> 1)
+#endif
+
+static void lcd_init(void)
+{
+	clps_writel(0x76543210, PALLSW);
+	clps_writel(0xFEDCBA98, PALMSW);
+	clps_writel((clps_readl(PMPCON) & ~0x0000FF00) | 0x00000800, PMPCON);
+	clps_writel(clps_readl(SYSCON1) & ~SYSCON1_LCDEN, SYSCON1);
+	clps_writel(0xE60F7C1F, LCDCON);
+}
+
+static void lcd_on(void)
+{
+	clps_writel(clps_readl(SYSCON1) | SYSCON1_LCDEN, SYSCON1);
+	clps_writeb(clps_readb(PDDR) | EDB_PD2_LCDEN, PDDR);
+	mdelay(1);
+	clps_writeb(clps_readb(PDDR) | EDB_PD3_LCDBL, PDDR);
+}
+
+static void lcd_off(void)
+{
+	clps_writeb(clps_readb(PDDR) & ~EDB_PD3_LCDBL, PDDR);
+	mdelay(1);
+	clps_writeb(clps_readb(PDDR) & ~EDB_PD2_LCDEN, PDDR);
+	clps_writel(clps_readl(SYSCON1) & ~SYSCON1_LCDEN, SYSCON1);
+}
+
+/*
+ * color format is as follows:
+ *
+ * 12-bpp packed pixel: |BBBB|GGGG|RRRR|
+ *
+ * 16-bpp packed pixel: |RRRRR|GGGGGG|BBBBB|
+ *
+ */
+
+static int
+edb7312fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+			u_int *transp, struct fb_info *info)
+{
+	if (regno > 15)
+		return 1;
+
+#ifdef CONFIG_FB_EDB7312_16BPP
+	*red   = (colreg[regno] & 0xF800) <<  0;
+	*green = (colreg[regno] & 0x07E0) <<  5;
+	*blue  = (colreg[regno] & 0x001F) << 11;
+#else
+	*red   = (colreg[regno] & 0x00F) << 12;
+	*green = (colreg[regno] & 0x0F0) <<  8;
+	*blue  = (colreg[regno] & 0xF00) <<  4;
+#endif
+	*transp = 0;
+	return 0;
+}
+
+static int
+edb7312fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+			u_int transp, struct fb_info *info)
+{
+	if (regno > 15)
+		return 1;
+
+#ifdef CONFIG_FB_EDB7312_16BPP
+	colreg[regno] = ((red   >>  0) & 0xF800) |
+			((green >>  5) & 0x07E0) |
+			((blue  >> 11) & 0x001F);
+#else
+	colreg[regno] = ((red   >> 12) & 0x00F) | 
+			((green >>  8) & 0x0F0) |
+			((blue  >>  4) & 0xF00);
+#endif
+	return 0;
+}
+
+static int
+edb7312fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
+{
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+	strcpy(fix->id, "edb7312fb");
+	fix->smem_start = FB_PHYS;
+	fix->smem_len = FB_SIZE;
+        fix->line_length = FB_LLEN;
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->type_aux = 0;
+	fix->visual = FB_VISUAL_TRUECOLOR;
+	fix->xpanstep = 0;
+	fix->ypanstep = 0;
+	fix->ywrapstep = 0;
+	fix->accel = FB_ACCEL_NONE;
+	return 0;
+}
+        
+static int
+edb7312fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+{
+	memset(var, 0, sizeof(struct fb_var_screeninfo));
+	var->xres = VID_X;
+	var->yres = VID_Y;
+	var->xres_virtual = VID_X;
+	var->yres_virtual = VID_Y;
+	var->xoffset = 0;
+	var->yoffset = 0;
+	var->grayscale = 0;
+#ifdef CONFIG_FB_EDB7312_16BPP
+	var->bits_per_pixel = 16;
+	var->red.offset = 11;
+	var->red.length = 5;
+	var->green.offset = 5;
+	var->green.length = 6;
+	var->blue.offset = 0;
+	var->blue.length = 5;
+#else
+	var->bits_per_pixel = 12;
+	var->red.offset = 0;
+	var->red.length = 4;
+	var->green.offset = 4;
+	var->green.length = 4;
+	var->blue.offset = 8;
+	var->blue.length = 4;
+#endif
+	var->transp.offset = 0;
+	var->transp.length = 0;
+	var->nonstd = 0;
+	var->activate = FB_ACTIVATE_NOW;
+	var->height = -1;
+	var->width = -1;
+	var->pixclock = 0;
+	var->left_margin = 0;
+	var->right_margin = 0;
+	var->upper_margin = 0;
+	var->lower_margin = 0;
+	var->hsync_len = 0;
+	var->vsync_len = 0;
+	var->sync = 0;
+	var->vmode = FB_VMODE_NONINTERLACED;
+	return 0;
+}
+
+static int
+edb7312fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+{
+	return -EINVAL;
+}
+
+static int
+edb7312fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info)
+{
+	if (con == currcon)
+		return fb_get_cmap(cmap, kspc, edb7312fb_getcolreg, info);
+	else if (fb_display[con].cmap.len)
+		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+	else
+		fb_copy_cmap(fb_default_cmap(16), cmap, kspc ? 0 : 2);
+	return 0;
+}
+
+static int
+edb7312fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info)
+{
+	int err;
+
+	if (!fb_display[con].cmap.len) {
+		if ((err = fb_alloc_cmap(&fb_display[con].cmap, 16, 0)))
+			return err;
+	}
+	if (con == currcon)
+		return fb_set_cmap(cmap, kspc, edb7312fb_setcolreg, info);
+	else
+		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+	return 0;
+}
+
+static int
+edb7312fb_switch_con(int con, struct fb_info *info)
+{ 
+	currcon = con;
+	return 0;
+}
+
+static int
+edb7312fb_updatevar(int con, struct fb_info *info)
+{
+	return 0;
+}
+
+static void
+edb7312fb_blank(int blank, struct fb_info *info)
+{
+	if (!blank)
+		lcd_on();
+	else
+		lcd_off();
+}
+
+#ifdef CONFIG_FB_EDB7312_16BPP
+static void refresh_disp (unsigned long dummy)
+{
+	int x, y;
+	u16 *w;
+	u8 *b;
+	unsigned int w0, w1;
+
+	w = (u16 *)FB_VIRT;
+	b = (u8 *)VID_VIRT;
+	for (y = VID_Y ; y ; y--) {
+		for (x = VID_X >> 1 ; x ; x--) {
+			w0 = *w++;
+			w1 = *w++;
+			*b++ = (w0 >> 12) |
+			       ((w0 & 0x0780) >> 3);
+			*b++ = ((w0 & 0x001E) >> 1) |
+			       ((w1 & 0xF000) >> 8);
+			*b++ = ((w1 & 0x0780) >> 7) |
+			       ((w1 & 0x001E) << 3);
+		}
+	}
+
+	tmrefr.expires = jiffies + TIME_REFRESH;
+	add_timer (&tmrefr);
+}
+#endif
+
+static int
+edb7312fb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+{
+	unsigned long off, start;
+	u32 len;
+
+	off = vma->vm_pgoff << PAGE_SHIFT;
+
+	start = fb_p;
+	len = PAGE_ALIGN(start & ~PAGE_MASK) + FB_SIZE;
+	start &= PAGE_MASK;
+	if ((vma->vm_end - vma->vm_start + off) > len)
+		return -EINVAL;
+	off += start;
+	vma->vm_pgoff = off >> PAGE_SHIFT;
+	
+	pgprot_val(vma->vm_page_prot) &= ~L_PTE_CACHEABLE;
+
+	if (io_remap_page_range(vma->vm_start, off, vma->vm_end - vma->vm_start, vma->vm_page_prot))
+		return -EAGAIN;
+
+	return 0;
+}
+
+static struct fb_ops edb7312fb_ops = {
+	owner:		THIS_MODULE,
+	fb_get_fix:	edb7312fb_get_fix,
+	fb_get_var:	edb7312fb_get_var,
+	fb_set_var:	edb7312fb_set_var,
+	fb_get_cmap:	edb7312fb_get_cmap,
+	fb_set_cmap:	edb7312fb_set_cmap,
+	fb_mmap:	edb7312fb_mmap
+};
+
+#ifdef CONFIG_FB_EDB7312_16BPP
+static int __init fbmem_alloc(void)
+{
+	int order = 0;
+	unsigned long page, top;
+
+	fb_size = VID_X * VID_Y * 2;
+	fb_size = PAGE_ALIGN(fb_size);
+
+	while (fb_size > (PAGE_SIZE * (1 << order)))
+		order++;
+	fb_v = __get_free_pages(GFP_KERNEL, order);
+	if (!fb_v) {
+		printk("edb7312fb: unable to allocate screen memory\n");
+		return 1;
+	}
+	top = fb_v + (PAGE_SIZE * (1 << order));
+	for (page = fb_v; page < PAGE_ALIGN(fb_v + fb_size); page += PAGE_SIZE)
+		SetPageReserved(virt_to_page(page));
+	for (page = fb_v + fb_size; page < top; page += PAGE_SIZE)
+		free_page(page);
+	fb_p = virt_to_phys((void *)fb_v);
+
+	return 0;
+}
+#endif
+
+int __init
+edb7312fb_init(void)
+{
+	memset(&fb_info, 0, sizeof(struct fb_info));
+
+#ifdef CONFIG_FB_EDB7312_16BPP
+	if (fbmem_alloc())
+		return -ENOMEM;
+#else
+	fb_p = VID_PHYS;
+	fb_v = VID_VIRT;
+	fb_size = VID_SIZE;
+#endif
+
+	strcpy(fb_info.modename, "edb7312fb");
+	fb_info.node = -1;
+	fb_info.flags = FBINFO_FLAG_DEFAULT;
+	fb_info.fbops = &edb7312fb_ops;
+	fb_info.disp = &display;
+	strcpy(fb_info.fontname, default_font);
+	fb_info.changevar = NULL;
+	fb_info.switch_con = &edb7312fb_switch_con;
+	fb_info.updatevar = &edb7312fb_updatevar;
+	fb_info.blank = &edb7312fb_blank;
+
+	memset(&display, 0, sizeof(struct display));
+	edb7312fb_get_var(&display.var, 0, &fb_info);
+	display.screen_base = (void *)FB_VIRT;
+	display.line_length = FB_LLEN;
+#ifdef CONFIG_FB_EDB7312_16BPP
+	display.dispsw = &fbcon_cfb16;
+#else
+	display.dispsw = &fbcon_cfb12;
+#endif
+	display.dispsw_data = colreg;
+	display.visual = FB_VISUAL_TRUECOLOR;
+	display.type = FB_TYPE_PACKED_PIXELS;
+	display.type_aux = 0;
+	display.ypanstep = 0;
+	display.ywrapstep = 0;
+	display.can_soft_blank = 1;
+	display.inverse = 0;
+
+	memset((void *)VID_VIRT, 0, VID_SIZE);
+#ifdef CONFIG_FB_EDB7312_16BPP
+	memset((void *)FB_VIRT, 0, FB_SIZE);
+#endif
+
+	if (register_framebuffer(&fb_info) < 0)
+		return -EINVAL;
+
+	lcd_init();
+	lcd_on();
+
+#ifdef CONFIG_FB_EDB7312_16BPP
+	init_timer(&tmrefr);
+	tmrefr.function = refresh_disp;
+	tmrefr.data = (unsigned long)NULL;
+	tmrefr.expires = jiffies + TIME_REFRESH;
+	add_timer (&tmrefr);
+#endif
+
+	return 0;
+}
+
+__init int
+edb7312fb_setup(char *options)
+{
+	char *opt;
+
+	if (!options || !*options)
+		return 0;
+
+	while ((opt = strsep(&options, ",")) != NULL) {
+		if (!*opt)
+			continue;
+		if (strncmp(opt, "font=", 5) == 0) {
+			strncpy(default_font_storage, opt + 5, sizeof(default_font_storage));
+			default_font = default_font_storage;
+			continue;
+		}
+
+		printk (KERN_ERR "edb7312fb: unknown parameter: %s\n", opt);
+	}
+
+	return 0;
+}
diff -urN linux-2.4.29/drivers/video/ep93xxfb.c linux-2.4.29-uc1/drivers/video/ep93xxfb.c
--- linux-2.4.29/drivers/video/ep93xxfb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/ep93xxfb.c	2005-06-14 02:12:27.000000000 +0100
@@ -0,0 +1,2229 @@
+/******************************************************************************
+ *
+ *  File:	linux/drivers/video/ep93xxfb.c
+ *
+ *  Purpose: Support CRT output on a EP9312/EP9315 evaluation board.
+ *
+ *  Build:	Define CONFIG_FB, CONFIG_FB_EP93XX
+ *		which will bring in:
+ *			CONFIG_FONT_8x8
+ *			CONFIG_FONT_8x16
+ *			CONFIG_FONT_ACORN_8x8
+ *
+ *		When building as console, define CONFIG_VT, CONFIG_VT_CONSOLE
+ *		and make sure CONFIG_CMDLINE does NOT have "console=" set.
+ *		CONFIG_EP93XX_KBD_SPI or CONFIG_EP93XX_KBD_SCANNED should also
+ *		be specified.
+ *
+ *  History:	010529	Norman Farquhar at LynuxWorks.
+ *
+ *		Initial version supports:
+ *		- crt only
+ *		- fixed frequency monitor timings: 640x480
+ *		- single default video mode supported: 640x480x8
+ *		- no module support because this is core logic
+ *		- never will be SMP
+ *
+ *		Derived from:	arm-linux-2.4.0-test11-rmk1
+ *				linux/drivers/video/sa1100fb.c
+ *				Version 2000/08/29
+ *				Copyright (C) 1999 Eric A. Thomas
+ *				See file for many other contributors.
+ *
+ * (c) Copyright 2001 LynuxWorks, Inc., San Jose, CA.  All rights reserved.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ *=============================================================================
+ *	Overview of Frame Buffer driver
+ *=============================================================================
+ *
+ *	The frame buffer driver supports the core logic display controller
+ *	of the ep93xx family machines.  These machines are embedded systems
+ *	and this driver provides for a few video modes with small code
+ *	footprint.  Both CRT and LCD may be supported in the future.
+ *
+ *	Generic fb driver model (skeletonfb.c, fbgen.c) is a bit whacked
+ *	so this driver has been converted back to simpler older style.
+ *	See below for list of complaints about generic fb model!
+ *
+ *
+ *	Linux color models supported:
+ *
+ *		CFB8 is 8 bit packed pixel format using 256 color LUT
+ *		Believed to be similar to Microsoft Windows:
+ *			16 colors VGA standard
+ *			16 grays
+ *			224 color loadable palette
+ *		Note: Linux Logo uses 6x6x6=216 color space
+ *
+ *	Linux color models NOT supported:
+ *
+ *		CFB4 is 4 bit packed pixel format using 16 color LUT
+ *			16 colors VGA standard
+ *		CFB16 is 16 bit flexible format (ep93xx uses R5:G6:B5)
+ *		CFB24 is 24 bit truecolor R8:G8:B8
+ *		CFB32 is 32 bit truecolor alpha:R8:G8:B8
+ *
+ *	Reminder about setting up /dev device nodes:
+ *
+ *		console	c 5,1		to virtual console driver
+ *					so that Linux bootup is visible
+ *					when fb is console.
+ *
+ *		fb	link /dev/fb0	used by applications
+ *
+ *		fb0	c 29,0		to fbmem device
+ *
+ *		tty	link /dev/console	recommended by BinZ for
+ *		tty0	link /dev/console	older Linux applications
+ *
+ *
+ *=============================================================================
+ *	Hardware Details
+ *=============================================================================
+ *
+ *	1.  Display controller uses system memory, not a dedicated frame buffer
+ *	RAM.  This means that display controller bandwidth to RAM steals from
+ *	CPU bandwidth to RAM.
+ *
+ *		So if bandwidth to memory is about 80MB/s assuming that
+ *		all accesses are 16 byte blocks taking 10 clocks on 50MHz
+ *		system bus.  Then 640x480x8 60Hz is about 19MB/s, or
+ *		1/4 of bus bandwidth which should not impact us badly.
+ *
+ *	2.  Dual hw palettes are a way to avoid sparkle and allow updating at
+ *	anytime, not just during blank period.  Pending hw palette switch
+ *	takes place once per frame during blank.
+ *
+ *	So we keep the master palette copy in memory and update the active hw
+ *	palette by updating the inactive hw palette and then switching.
+ *
+ *	The only complication is writing palette while switch is pending.
+ *	We assume LUTSTAT is updated synchronously with bus clock so that
+ *	writes to LUT complete to either RAM0 or RAM1, even if request to
+ *	switch RAMs comes in asynchronously, in the middle of write to LUT.
+ *
+ *	3.  Some timing registers must be unlocked before access.
+ *
+ *=============================================================================
+ *	Send to www.complaints.linux.com
+ *=============================================================================
+ *
+ *	Generic fb model is too messy IMHO and here is my list of
+ *	problems with it.
+ *
+ *	1.  Note ALL fbgen.c functions really take fb_info_gen, instead of
+ *	fb_info parameters, by casting info instead of changing prototype.
+ *
+ *	2.  Messy stuff in doing encode/decode var.
+ *
+ *	3.  The info structure holds the controlling variables for video.
+ *	But data is passed around and variables tweaked inside routines
+ *	in which you would not expect it.
+ *
+ *	4.  It is not clear that all variables of a structure get inited
+ *	properly because it is not done in one spot.
+ *
+ *	5.  In the driver model fbskeleton.c, initially, both the 'var' and
+ *	'fix' data are derived from 'par'.  This seems backward, and I think
+ *	reflects Linux genesis on a PC with a BIOS which has already set the
+ *	initial video mode.
+ *
+ *	6.  For some reason, there is a local copy of 'par' which is the true
+ *	current mode (Why not use the 'par' field in info??).
+ *
+ *	7.  Consistency checks are device specific, but fb implementation
+ *	is messy:  high level video mode requests are pushed down to low
+ *	level data 'par' and then pulled back out again to high level
+ *	with a consistent, possibly changed mode, changed 'var'
+ *
+ *		decode_var	really checks var consistency and
+ *				translates var to par
+ *
+ *		encode_var	translates par to var
+ *				(one driver just passes back current var
+ *				 which assumes that par set from var)
+ *
+ *****************************************************************************/
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/wrapper.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/uaccess.h>
+#include <asm/proc/pgtable.h>
+
+//TBD some of these may not be needed until full implementation
+
+#include <video/fbcon.h>
+#include <video/fbcon-mfb.h>
+#include <video/fbcon-cfb4.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include "ep93xxfb.h"
+
+#define RasterSetLocked(registername,value) \
+    {                                       \
+        outl( 0xAA, REALITI_SWLOCK );       \
+        outl( value, registername);         \
+    }
+
+/*
+ *  Debug macros
+ */
+#ifdef DEBUG
+#  define DPRINTK(fmt, args...)	printk("%s: " fmt, __FUNCTION__ , ## args)
+#else
+#  define DPRINTK(fmt, args...)
+#endif
+
+// Max palette entries over all video modes
+#define MAX_PALETTE_NUM_ENTRIES		256
+
+// Max X resolution and Y resolution depend on whether LCD is supported,
+// and the monitor type.
+
+#define MAX_CRT_XRES	640
+#define MAX_CRT_YRES	480
+
+// Max bpp is fixed for low resolutions, but fundamentally depends on the
+// memory bandwidth which the system can allocate to the raster engine,
+// and so depends on application.
+//
+//	TBD can create an array which determines max bpp based on passed
+//	TBD in resolutions.
+//
+#ifdef CONFIG_FB_EP93XX_8BPP
+#define MAX_BPP		8
+#elif defined(CONFIG_FB_EP93XX_16BPP_565)
+#define MAX_BPP		16
+#else
+#define MAX_BPP		32
+#endif
+
+// Framebuffer max mem size in bytes over all video modes
+// Note: mypar not valid yet so need hard numbers here.
+#define FB_MAX_MEM_SIZE ((MAX_CRT_XRES * MAX_CRT_YRES * MAX_BPP)/8)
+
+// Framebuffer mapped mem size in bytes
+//	This will be an integral number of pages.
+#define FB_MAPPED_MEM_SIZE (PAGE_ALIGN(FB_MAX_MEM_SIZE + PAGE_SIZE))
+
+/* Minimum X and Y resolutions */
+//TBD how realistic is this for CRT??
+//#define MIN_XRES	64
+//#define MIN_YRES	64
+
+#define EP93XX_NAME	"EP93XX"
+#define NR_MONTYPES	1
+
+/* Local LCD controller parameters */
+/* These can be reduced by making better use of fb_var_screeninfo parameters.*/
+/* Several duplicates exist in the two structures. */
+struct ep93xxfb_par
+{
+	dma_addr_t	p_screen_base;
+	unsigned char	*v_screen_base;
+	unsigned long	screen_size;
+	unsigned int	palette_size;
+	unsigned int	xres;
+	unsigned int	yres;
+	unsigned int	bits_per_pixel;
+	int		montype;
+	unsigned int	currcon;
+	unsigned int	visual;
+	u16		palette[16];	// Funky 16 table lookup used by
+					// "optional" Parameter.
+};
+
+//TBD Linux fbmon.c tries to check monitor support for requested mode.
+//TBD But 2.4.0 test11 has removed this code from the build.
+/* Fake monspecs to fill in fbinfo structure */
+//TBD strict VGA monitor has 60,60 instead of 50,65
+static struct fb_monspecs __initdata monspecs = {
+	 30000, 70000, 50, 65, 0 	/* Generic, not fixed frequency */
+};
+
+static char default_font_storage[40];
+static char *default_font = "Acorn8x8";
+
+#if defined (CONFIG_FB_LCD_EP93XX)
+#define DEFAULT_MODE 1
+#elif defined (CONFIG_FB_CX25871)
+#define DEFAULT_MODE 3
+#elif defined (CONFIG_FB_CRT_EP93XX)
+#define DEFAULT_MODE 0
+#else
+#error What Display Setting was that!!!
+#endif
+
+static int mode = DEFAULT_MODE;
+
+#ifdef CONFIG_FB_CX25871_OVERSCAN
+#define DEFAULT_OVERSCAN 1
+#else
+#define DEFAULT_OVERSCAN 0
+#endif
+
+static int overscan = DEFAULT_OVERSCAN;
+
+typedef struct _DisplayTimingValues
+{
+	const char	*Name;
+	unsigned long	DisplayID;
+	int		(* RasterConfigure)(struct _DisplayTimingValues *pTimingValues);
+	unsigned short	Refresh;
+	unsigned long	VDiv;
+
+	unsigned short	HRes;
+	unsigned short	HFrontPorch;
+	unsigned short	HBackPorch;
+	unsigned short	HSyncWidth;
+	unsigned short	HTotalClocks;
+
+	unsigned short	VRes;
+	unsigned short	VFrontPorch;
+	unsigned short	VBackPorch;
+	unsigned short	VSyncWidth;
+	unsigned short	VTotalClocks;
+} DisplayTimingValues;
+
+typedef int (* fRasterConfigure)(DisplayTimingValues *);
+
+typedef enum
+{
+	CRT_GENERIC,
+	Philips_LB064V02A1,
+	CX25871,
+	Sharp
+} DisplayType;
+
+#define TIMING_VALUES(NAME, DISPID, FUNC, REFRESH, VDIV,                \
+                   HRES, HFP, HBP, HSYNC, VRES, VFP, VBP, VSYNC)        \
+{                                                                       \
+	Name:NAME,                                                      \
+	DISPID, FUNC, REFRESH, VDIV,                                    \
+	HRES, HFP, HBP, HSYNC, (HRES + HFP + HBP + HSYNC),              \
+	VRES, VFP, VBP, VSYNC, (VRES + VFP + VBP + VSYNC)               \
+}
+
+static void InitializeCX25871For640x480NTSC(void);
+static int Conexant_CX25871(DisplayTimingValues *pTimingValues);
+static int PhilipsLCD(DisplayTimingValues *pTimingValues);
+
+DisplayTimingValues static TimingValues[]=
+{
+	//
+	// 640x480 Progressive Scan
+	//
+	TIMING_VALUES("CRT_GENERIC", CRT_GENERIC,
+		      (fRasterConfigure)0,
+		      60, 0x0000c108, 640, 16, 48, 96, 480, 11, 31, 2),
+
+	//
+	// 640x480 Progressive Scan Philips LB064V02A1 on EDB9312 Board.
+	//
+	TIMING_VALUES("Philips LB064V02A1", Philips_LB064V02A1,
+		      PhilipsLCD,
+		      68, 0x0000c107, 640, 16, 48, 96, 480, 11, 31, 2),
+
+	//
+	// Sharp LQ64D343 LCD Panel
+	//
+	TIMING_VALUES("Sharp LQ64d343", CRT_GENERIC,
+		      (fRasterConfigure)0,
+		      60, 0x0000c205, 640, 32, 32, 96, 480, 34, 34, 4),
+
+	//
+	// 640x480 NTSC Support for Conexant CX25871
+	//
+	TIMING_VALUES("Conexant CX25871", CX25871,
+		      Conexant_CX25871,
+		      60, 0x0000c317, 640, 0, 0, 0, 480, 0, 0, 0),
+};
+#define NUM_TIMING_VALUES (sizeof(TimingValues)/sizeof(DisplayTimingValues))
+
+unsigned int master_palette[256];	/* master copy of palette data */
+
+//TBD Before fbcon started, the driver calls set_var with con=-1
+//TBD which initializes global_disp and puts ptr to it in info.
+//TBD Later on display console array keeps track of display settings.
+static struct display global_disp;	/* Initial Display Settings */
+
+static struct fb_info fb_info;		// initialized in init_fbinfo()
+static struct ep93xxfb_par mypar;
+
+static int ep93xxfb_get_fix(struct fb_fix_screeninfo *fix,
+			    int con, struct fb_info *info);
+static int ep93xxfb_get_var(struct fb_var_screeninfo *var,
+			    int con, struct fb_info *info);
+static int ep93xxfb_set_var(struct fb_var_screeninfo *var,
+			    int con, struct fb_info *info);
+static int ep93xxfb_get_cmap(struct fb_cmap *cmap, int kspc,
+			     int con, struct fb_info *info);
+static int ep93xxfb_set_cmap(struct fb_cmap *cmap, int kspc,
+			     int con, struct fb_info *info);
+static int ep93xxfb_ioctl(struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg, int con,
+			  struct fb_info *info);
+
+static int  ep93xxfb_switch(int con, struct fb_info *info);
+static void ep93xxfb_blank(int blank, struct fb_info *info);
+static int  MapFramebuffer(void);
+static int  ConfigureRaster(struct fb_var_screeninfo *var,
+			    DisplayTimingValues *pTimingValues);
+
+static struct fb_ops ep93xxfb_ops = {
+	owner:		THIS_MODULE,
+	fb_get_fix:	ep93xxfb_get_fix,
+	fb_get_var:	ep93xxfb_get_var,
+	fb_set_var:	ep93xxfb_set_var,
+	fb_get_cmap:	ep93xxfb_get_cmap,
+	fb_set_cmap:	ep93xxfb_set_cmap,
+	fb_ioctl:	ep93xxfb_ioctl,
+};
+
+//-----------------------------------------------------------------------------
+//	Local functions
+//-----------------------------------------------------------------------------
+
+/*
+ * ep93xxfb_palette_write:
+ *	Encode palette data to 24bit palette format.
+ *	Write palette data to the master palette and inactive hw palette
+ *	switch palettes.  And handle asynchronous palette switches.
+ */
+static inline void
+ep93xxfb_palette_write(u_int regno, u_int red, u_int green,
+		       u_int blue, u_int trans)
+{
+	unsigned int cont, i, pal;
+
+	// Only supports color LUT, not gray LUT
+	//
+	//	TBD if not in 4 or 8bpp, then does LUT logic operate?
+	//	TBD or do we need to do nothing here?
+
+	// LCD:	TBD RGB mapping may match spec p193.
+	//
+	// CRT: LUT RGB mapping is really R/G/B from high to low bits
+	//	because really determined by wiring to video DAC.
+	//	(disregard spec p 193 showing color LUT B/G/R order)
+	//	Here are the details:
+	//
+	//	Shift mode 1 directs LUT bits 7-2 onto P5-P0,
+	//	LUT bits 15-10 onto P11-P6, and LUT bits 23-16
+	//	onto P17-P12.
+	//
+	//	Board wired P17-12 to video DAC Red inputs,
+	//	P11-P6 wired to video DAC Green inputs, and
+	//	P5-P0 wired to video DAC Blue inputs.
+	//
+	pal = ((red & 0xFF00) << 8) | (green & 0xFF00) | ((blue & 0xFF00) >> 8);
+
+	master_palette[regno] = pal;
+
+	// Two cases here:
+	// 1.  	If LUT switch is pending, then write inactive LUT and when
+	//	switch happens, this new palette entry will be active.
+	// 	Race condition here between LUT switch and this write is okay
+	// 	since we fix it below.
+	//
+	// 2.	If LUT switch is not pending, then write here is incomplete
+	//	and whole palette will be written below.
+
+	outl( pal, (COLOR_LUT+(regno<<2)) );
+
+	cont = inl(LUTCONT);
+
+	if ((cont&LUTCONT_STAT && cont&LUTCONT_RAM1) ||
+	    (!(cont&LUTCONT_STAT) && !(cont&LUTCONT_RAM1))) {
+		// LUT switch is no longer pending
+
+		// We do not know if write to LUT above really went
+		// to currently active LUT.  So need to make sure that
+		// data gets into inactive LUT and switch LUTs.
+		//
+		// But currently inactive LUT may be out of date
+		// in more entries than just last write.
+		// Need to update currently inactive LUT for all writes
+		// which went to currently active LUT.
+		// Fully update the LUT now, which is a simpler policy
+		// than trying to track writes and do partial update of LUT.
+		// (Worstcase impact: we update palette every frame)
+
+		for (i=0; i< 256; i++)	// Update inactive LUT
+			outl( master_palette[i], (COLOR_LUT+(i<<2)) );
+		// Switch active LUTs next frame
+		outl( cont ^ LUTCONT_RAM1, LUTCONT );
+	}
+}
+
+static inline void
+ep93xxfb_palette_read(u_int regno, u_int *red, u_int *green,
+		      u_int *blue, u_int *trans)
+{
+	// Only supports color LUT, not gray LUT
+
+	unsigned int pal;
+
+	// Read only needs to access master palette, not hw palettes.
+	pal = master_palette[regno];
+
+	//TBD LCD mode may change LUT from R/G/B order to B/G/R order
+	*red = (pal >> 8) & 0xFF00;
+	*green = pal & 0xFF00;
+	*blue = (pal << 8) & 0xFF00;
+	*trans  = 0;
+}
+
+//-----------------------------------------------------------------------------
+//	Helper functions for fb driver
+//-----------------------------------------------------------------------------
+
+static int
+ep93xxfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+		   u_int *trans, struct fb_info *info)
+{
+	if (regno >= mypar.palette_size)
+		return 1;
+
+	ep93xxfb_palette_read(regno, red, green, blue, trans);
+
+	return 0;
+}
+
+static inline u_int
+chan_to_field(u_int chan, struct fb_bitfield *bf)
+{
+	chan &= 0xffff;
+	chan >>= 16 - bf->length;
+	return chan << bf->offset;
+}
+
+static int
+ep93xxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+		   u_int trans, struct fb_info *info)
+{
+	u_int val;
+
+	if (regno >= mypar.palette_size)
+		return 1;
+
+	switch (info->disp->visual) {
+	case FB_VISUAL_TRUECOLOR:
+		if (regno < 16) {
+			u16 *pal = info->pseudo_palette;
+			val  = chan_to_field(red, &info->var.red);
+			val |= chan_to_field(green, &info->var.green);
+			val |= chan_to_field(blue, &info->var.blue);
+				pal[regno] = val;
+		}
+		break;
+	case FB_VISUAL_PSEUDOCOLOR:
+		ep93xxfb_palette_write(regno, red, green, blue, trans);
+		break;
+	}
+
+	return 0;
+}
+
+//TBD Warning: fbmem.c ioctl could result in any of the helper functions being
+//TBD called with con=-1, which happens when info->display_fg == NULL,
+//TBD which presumably is only during initialization of fbcon.
+//TBD Is there any other condition under which con=-1?
+//TBD Maybe we do not even need to support it!
+
+static int
+ep93xxfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+		          struct fb_info *info)
+{
+	int err = 0;
+
+	//TBD does not expect call with con=-1 if currcon!=-1
+	if (con == -1)
+		DPRINTK("get_cmap called with con=-1\n");
+
+	DPRINTK("mypar.visual=%d\n", mypar.visual);
+	if (con == mypar.currcon)
+		err = fb_get_cmap(cmap, kspc, ep93xxfb_getcolreg, info);
+	else if (fb_display[con].cmap.len)
+		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+	else
+		fb_copy_cmap(fb_default_cmap(mypar.palette_size),
+			     cmap, kspc ? 0 : 2);
+	return err;
+}
+
+static int
+ep93xxfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+		  struct fb_info *info)
+{
+	int err = 0;
+
+	//
+	// What kind of request is this???
+	//
+	if (con == -1) {
+		DPRINTK("ERROR set_cmap called with con=-1\n");
+		return(-1);
+	}
+
+	DPRINTK("mypar.visual=%d\n", mypar.visual);
+
+	if (!fb_display[con].cmap.len)
+		err = fb_alloc_cmap(&fb_display[con].cmap, mypar.palette_size,
+				    0);
+	if (!err) {
+		if (con == mypar.currcon)
+			err = fb_set_cmap(cmap, kspc, ep93xxfb_setcolreg,
+					  info);
+		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+	}
+	return err;
+}
+
+static unsigned long cursor_data[64][4];
+
+static void
+ep93xxfb_cursor(struct ep93xx_cursor *cursor)
+{
+	unsigned long data[64 * 4];
+	long i, x, y, save;
+
+	if (cursor->flags & CURSOR_OFF)
+		outl(inl(CURSORXYLOC) & ~0x00008000, CURSORXYLOC);
+
+	if (cursor->flags & CURSOR_SETSHAPE) {
+		copy_from_user(data, cursor->data,
+			       cursor->width * cursor->height / 4);
+
+		save = inl(CURSORXYLOC);
+		outl(save & ~0x00008000, CURSORXYLOC);
+
+		for (y = 0, i = 0; y < cursor->height; y++) {
+			for (x = 0; x < cursor->width; x += 16)
+				cursor_data[y][x] = data[i++];
+		}
+
+		outl(virt_to_phys(cursor_data), CURSOR_ADR_START);
+		outl(virt_to_phys(cursor_data), CURSOR_ADR_RESET);
+		outl(0x00000300 | ((cursor->height - 1) << 2) |
+		     ((cursor->width - 1) >> 4), CURSORSIZE);
+		outl(save, CURSORXYLOC);
+	}
+
+	if (cursor->flags & CURSOR_SETCOLOR) {
+		outl(cursor->color1, CURSORCOLOR1);
+		outl(cursor->color2, CURSORCOLOR2);
+		outl(cursor->blinkcolor1, CURSORBLINK1);
+		outl(cursor->blinkcolor2, CURSORBLINK2);
+	}
+
+	if (cursor->flags & CURSOR_BLINK) {
+		if (cursor->blinkrate)
+			outl(0x00000100 | cursor->blinkrate, CURSORBLINK);
+		else
+			outl(0x000000ff, CURSORBLINK);
+	}
+
+	if (cursor->flags & CURSOR_MOVE) {
+		x = (inl(HACTIVESTRTSTOP) & 0x000003ff) - cursor->dx - 2;
+		y = (inl(VACTIVESTRTSTOP) & 0x000003ff) - cursor->dy;
+		outl((inl(CURSORXYLOC) & 0x8000) | (y << 16) | x, CURSORXYLOC);
+	}
+
+	if (cursor->flags & CURSOR_ON)
+		outl(inl(CURSORXYLOC) | 0x00008000, CURSORXYLOC);
+}
+
+#ifdef CONFIG_EP93XX_GRAPHICS
+#ifdef CONFIG_FB_EP93XX_8BPP
+#define BITS_PER_PIXEL 8
+#define BYTES_PER_PIXEL 1
+#define PIXEL_MASK 3
+#define PIXEL_SHIFT 2
+#define PIXEL_FORMAT 0x00040000
+#endif
+#ifdef CONFIG_FB_EP93XX_16BPP_565
+#define BITS_PER_PIXEL 16
+#define BYTES_PER_PIXEL 2
+#define PIXEL_MASK 1
+#define PIXEL_SHIFT 1
+#define PIXEL_FORMAT 0x00080000
+#endif
+#define BYTES_PER_LINE (fb_info.var.xres * BYTES_PER_PIXEL)
+
+static DECLARE_WAIT_QUEUE_HEAD(ep93xxfb_wait_in);
+
+static void
+ep93xxfb_irq_handler(int i, void *blah, struct pt_regs *regs)
+{
+	outl(0x00000000, BLOCKCTRL);
+
+	wake_up_interruptible(&ep93xxfb_wait_in);
+}
+
+static void
+ep93xxfb_wait(void)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	add_wait_queue(&ep93xxfb_wait_in, &wait);
+	current->state = TASK_INTERRUPTIBLE;
+	while (inl(BLOCKCTRL) & 0x00000001) {
+		schedule();
+		current->state = TASK_INTERRUPTIBLE;
+	}
+	remove_wait_queue(&ep93xxfb_wait_in, &wait);
+	current->state = TASK_RUNNING;
+}
+
+static unsigned char pucBlitBuf[4096];
+
+static int
+ep93xxfb_blit(struct ep93xx_blit *blit)
+{
+	unsigned long value = 0, size, dx1, dx2, dy1, sx1, sx2, sy1;
+
+	if ((blit->dx >= fb_info.var.xres) ||
+	    (blit->dy >= fb_info.var.yres) ||
+	    ((blit->dx + blit->width - 1) >= fb_info.var.xres) ||
+	    ((blit->dy + blit->height - 1) >= fb_info.var.yres))
+		return -EFAULT;
+
+	value = blit->flags & (BLIT_TRANSPARENT | BLIT_MASK_MASK |
+			       BLIT_DEST_MASK | BLIT_1BPP_SOURCE);
+
+	if ((blit->flags & BLIT_SOURCE_MASK) == BLIT_SOURCE_MEMORY) {
+		if (blit->flags & BLIT_1BPP_SOURCE) {
+			size = blit->swidth * blit->height / 8;
+			if (size <= 4096)
+				copy_from_user(pucBlitBuf, blit->data, size);
+			else {
+				for (size = blit->height; size; ) {
+					blit->height = 32768 / blit->swidth;
+					if (blit->height > size)
+						blit->height = size;
+					ep93xxfb_blit(blit);
+					blit->dy += blit->height;
+					blit->data += blit->swidth *
+						      blit->height / 8;
+					size -= blit->height;
+				}
+				return 0;
+			}
+			if (blit->flags & BLIT_TRANSPARENT)
+				value ^= 0x00004000;
+			outl(0x00000007, SRCPIXELSTRT);
+			outl(blit->swidth >> 5, SRCLINELENGTH);
+			outl((blit->width - 1) >> 5, BLKSRCWIDTH);
+			outl(blit->bgcolor, BACKGROUND);
+		} else {
+			size = blit->swidth * blit->height * BYTES_PER_PIXEL;
+			if (size <= 4096)
+				copy_from_user(pucBlitBuf, blit->data, size);
+			else {
+				for (size = blit->height; size; ) {
+					blit->height = 4096 / BYTES_PER_PIXEL /
+						       blit->swidth;
+					if (blit->height > size)
+						blit->height = size;
+					ep93xxfb_blit(blit);
+					blit->dy += blit->height;
+					blit->data += blit->swidth *
+						      blit->height *
+						      BYTES_PER_PIXEL;
+					size -= blit->height;
+				}
+				return 0;
+			}
+			outl(0x00000000, SRCPIXELSTRT);
+			outl(blit->swidth >> PIXEL_SHIFT, SRCLINELENGTH);
+			outl((blit->width - 1) >> PIXEL_SHIFT, BLKSRCWIDTH);
+		}
+		outl(virt_to_phys(pucBlitBuf), BLKSRCSTRT);
+		dx1 = blit->dx;
+		dy1 = blit->dy;
+		dx2 = blit->dx + blit->width - 1;
+	} else {
+		if ((blit->sx >= fb_info.var.xres) ||
+		    (blit->sy >= fb_info.var.yres) ||
+		    ((blit->sx + blit->width - 1) >= fb_info.var.xres) ||
+		    ((blit->sy + blit->height - 1) >= fb_info.var.yres))
+			return -EFAULT;
+
+		if ((blit->dy == blit->sy) &&
+		    (blit->dx < blit->sx) &&
+		    ((blit->dx + blit->width - 1) >= blit->sx)) {
+			dx1 = blit->dx + blit->width - 1;
+			dx2 = blit->dx;
+			sx1 = blit->sx + blit->width - 1;
+			sx2 = blit->sx;
+			value |= 0x000000a0;
+		} else {
+			dx1 = blit->dx;
+			dx2 = blit->dx + blit->width - 1;
+			sx1 = blit->sx;
+			sx2 = blit->sx + blit->width - 1;
+		}
+
+		if (blit->dy <= blit->sy) {
+			dy1 = blit->dy;
+			sy1 = blit->sy;
+		} else {
+			dy1 = blit->dy + blit->height - 1;
+			sy1 = blit->sy + blit->height - 1;
+			value |= 0x00000140;
+		}
+
+		outl(((sx1 & PIXEL_MASK) * BITS_PER_PIXEL) |
+		     (((sx2 & PIXEL_MASK) * BITS_PER_PIXEL) << 16),
+		     SRCPIXELSTRT);
+		outl(inl(VIDSCRNPAGE) + (sy1 * BYTES_PER_LINE) +
+		     ((sx1 * BYTES_PER_PIXEL) & ~PIXEL_MASK), BLKSRCSTRT);
+		outl(BYTES_PER_LINE / 4, SRCLINELENGTH);
+		if (sx1 < sx2)
+			outl((sx2 >> PIXEL_SHIFT) - (sx1 >> PIXEL_SHIFT),
+			     BLKSRCWIDTH);
+		else
+			outl((sx1 >> PIXEL_SHIFT) - (sx2 >> PIXEL_SHIFT),
+			     BLKSRCWIDTH);
+	}
+
+	outl(((dx1 & PIXEL_MASK) * BITS_PER_PIXEL) |
+	     (((dx2 & PIXEL_MASK) * BITS_PER_PIXEL) << 16), DESTPIXELSTRT);
+	outl(inl(VIDSCRNPAGE) + (dy1 * BYTES_PER_LINE) +
+	     ((dx1 * BYTES_PER_PIXEL) & ~PIXEL_MASK), BLKDSTSTRT);
+	outl(BYTES_PER_LINE / 4, DESTLINELENGTH);
+	if (dx1 < dx2)
+		outl((dx2 >> PIXEL_SHIFT) - (dx1 >> PIXEL_SHIFT),
+		     BLKDESTWIDTH);
+	else
+		outl((dx1 >> PIXEL_SHIFT) - (dx2 >> PIXEL_SHIFT),
+		     BLKDESTWIDTH);
+	outl(blit->height - 1, BLKDESTHEIGHT);
+	outl(blit->fgcolor, BLOCKMASK);
+	outl(blit->transcolor, TRANSPATTRN);
+	outl(value | PIXEL_FORMAT | 0x00000003, BLOCKCTRL);
+	ep93xxfb_wait();
+
+	return 0;
+}
+
+static int
+ep93xxfb_fill(struct ep93xx_fill *fill)
+{
+	if ((fill->dx >= fb_info.var.xres) ||
+	    (fill->dy >= fb_info.var.yres))
+		return -EFAULT;
+
+	if ((fill->dx + fill->width - 1) >= fb_info.var.xres)
+		fill->width = fb_info.var.xres - fill->dx;
+	if ((fill->dy + fill->height - 1) >= fb_info.var.yres)
+		fill->height = fb_info.var.yres - fill->dy;
+
+	outl(mypar.p_screen_base + (fill->dy * BYTES_PER_LINE) +
+	     ((fill->dx * BYTES_PER_PIXEL) & ~PIXEL_MASK), BLKDSTSTRT);
+	outl(((fill->dx & PIXEL_MASK) * BITS_PER_PIXEL) |
+	     ((((fill->dx + fill->width - 1) & PIXEL_MASK) *
+	       BITS_PER_PIXEL) << 16), DESTPIXELSTRT);
+	outl(BYTES_PER_LINE / 4, DESTLINELENGTH);
+	outl(((fill->dx + fill->width - 1) >> PIXEL_SHIFT) -
+	     (fill->dx >> PIXEL_SHIFT), BLKDESTWIDTH);
+	outl(fill->height - 1, BLKDESTHEIGHT);
+	outl(fill->color, BLOCKMASK);
+	outl(PIXEL_FORMAT | 0x0000000b, BLOCKCTRL);
+	ep93xxfb_wait();
+
+	return 0;
+}
+
+static unsigned long
+isqrt(unsigned long a)
+{
+	unsigned long rem = 0;
+	unsigned long root = 0;
+	int i;
+
+	for (i = 0; i < 16; i++) {
+		root <<= 1;
+		rem = ((rem << 2) + (a >> 30));
+		a <<= 2;
+		root++;
+		if (root <= rem) {
+			rem -= root;
+			root++;
+		} else
+			root--;
+	}
+	return root >> 1;
+}
+
+static int
+ep93xxfb_line(struct ep93xx_line *line)
+{
+	unsigned long value = 0;
+	long dx, dy, count, xinc, yinc, xval, yval, incr;
+
+	if ((line->x1 >= fb_info.var.xres) ||
+	    (line->x2 >= fb_info.var.xres) ||
+	    (line->y1 >= fb_info.var.yres) ||
+	    (line->y2 >= fb_info.var.yres))
+		return -EFAULT;
+
+	dx = line->x2 - line->x1;
+	if (dx < 0) {
+		value |= 0x00000020;
+		dx *= -1;
+	}
+	dy = line->y2 - line->y1;
+	if (dy < 0) {
+		value |= 0x00000040;
+		dy *= -1;
+	}
+	if (line->flags & LINE_PRECISE) {
+		count = isqrt(((dy * dy) + (dx * dx)) * 4096);
+		xinc = (4095 * 64 * dx) / count;
+		yinc = (4095 * 64 * dy) / count;
+		xval = 2048;
+		yval = 2048;
+		count = 0;
+		while (dx || dy) {
+			incr = 0;
+			xval -= xinc;
+			if (xval <= 0) {
+				xval += 4096;
+				dx--;
+				incr = 1;
+			}
+			yval -= yinc;
+			if (yval <= 0) {
+				yval += 4096;
+				dy--;
+				incr = 1;
+			}
+			count += incr;
+		}
+	} else {
+		if (dx == dy) {
+			xinc = 4095;
+			yinc = 4095;
+			count = dx;
+		} else if (dx < dy) {
+			xinc = (dx * 4095) / dy;
+			yinc = 4095;
+			count = dy;
+		} else {
+			xinc = 4095;
+			yinc = (dy * 4095) / dx;
+			count = dx;
+		}
+	}
+
+	outl(0x08000800, LINEINIT);
+	if (line->flags & LINE_PATTERN)
+		outl(line->pattern, LINEPATTRN);
+	else
+		outl(0x000fffff, LINEPATTRN);
+	outl(mypar.p_screen_base + (line->y1 * BYTES_PER_LINE) +
+	     ((line->x1 * BYTES_PER_PIXEL) & ~PIXEL_MASK), BLKDSTSTRT);
+	outl(((line->x1 & PIXEL_MASK) * BITS_PER_PIXEL) |
+	     ((((line->x1 + dx - 1) & PIXEL_MASK) *
+	       BITS_PER_PIXEL) << 16), DESTPIXELSTRT);
+	outl(BYTES_PER_LINE / 4, DESTLINELENGTH);
+	outl(line->fgcolor, BLOCKMASK);
+	outl(line->bgcolor, BACKGROUND);
+	outl((yinc << 16) | xinc, LINEINC);
+	outl(count & 0xfff, BLKDESTWIDTH);
+	outl(0, BLKDESTHEIGHT);
+	value |= (line->flags & LINE_BACKGROUND) ? 0x00004000 : 0;
+	outl(value | PIXEL_FORMAT | 0x00000013, BLOCKCTRL);
+	ep93xxfb_wait();
+
+	return 0;
+}
+#endif
+
+static int
+ep93xxfb_ioctl(struct inode *inode, struct file *file,
+	       unsigned int cmd, unsigned long arg, int con,
+	       struct fb_info *info)
+{
+	struct ep93xx_cursor cursor;
+	struct ep93xx_blit blit;
+	struct ep93xx_fill fill;
+	struct ep93xx_line line;
+	unsigned long caps;
+
+	switch (cmd) {
+	case FBIO_EP93XX_GET_CAPS:
+		caps = EP93XX_CAP_CURSOR;
+#ifdef CONFIG_EP93XX_GRAPHICS
+		caps |= EP93XX_CAP_LINE | EP93XX_CAP_FILL | EP93XX_CAP_BLIT;
+#endif
+		copy_to_user((void *)arg, &caps, sizeof(unsigned long));
+		return 0;
+
+	case FBIO_EP93XX_CURSOR:
+		copy_from_user(&cursor, (void *)arg,
+			       sizeof(struct ep93xx_cursor));
+		ep93xxfb_cursor(&cursor);
+		return 0;
+
+#ifdef CONFIG_EP93XX_GRAPHICS
+	case FBIO_EP93XX_LINE:
+		copy_from_user(&line, (void *)arg, sizeof(struct ep93xx_line));
+		return ep93xxfb_line(&line);
+
+	case FBIO_EP93XX_FILL:
+		copy_from_user(&fill, (void *)arg, sizeof(struct ep93xx_fill));
+		return ep93xxfb_fill(&fill);
+
+	case FBIO_EP93XX_BLIT:
+		copy_from_user(&blit, (void *)arg, sizeof(struct ep93xx_blit));
+		return ep93xxfb_blit(&blit);
+#endif
+
+	default:
+		return -EFAULT;
+	}
+}
+
+//=============================================================================
+// CheckAdjustVar
+//=============================================================================
+// Check and adjust the video params in 'var'. If a value doesn't fit, round it
+// up, if it's too big, return -EINVAL.
+//
+// Suggestion: Round up in the following order: bits_per_pixel, xres, yres,
+// xres_virtual, yres_virtual, xoffset, yoffset, grayscale, bitfields,
+// horizontal timing, vertical timing.
+//
+// Note: This is similar to generic fb call sequence
+//    (decode_var, set_par, decode_var)
+// in that var gets fixed if fixable and error if not.  The translating
+// to parameter settings is handled inside activate_var below.
+//=============================================================================
+static int CheckAdjustVar(struct fb_var_screeninfo *var)
+{
+	DPRINTK("Entering\n");
+
+	//
+	// Just set virtual to actual resolution.
+	//
+	var->xres_virtual = mypar.xres;
+	var->yres_virtual = mypar.yres;
+
+	DPRINTK("check: var->bpp=%d\n", var->bits_per_pixel);
+	switch (var->bits_per_pixel) {
+#ifdef FBCON_HAS_CFB4
+	case 4:					//TBD need to adjust var
+		break;
+#endif
+#ifdef FBCON_HAS_CFB8
+	case 8:		/* through palette */
+		var->red.length	= 4;	//TBD is this used? should be 8?
+		//TBD what about offset?
+		var->green	= var->red;
+		var->blue	= var->red;
+		var->transp.length = 0;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:  	/* RGB 565 */
+		var->red.length    = 5;
+		var->blue.length   = 5;
+		var->green.length  = 6;
+		var->transp.length = 0;
+		var->red.offset    = 11;
+		var->green.offset  = 5;
+		var->blue.offset   = 0;
+		var->transp.offset = 0;
+		break;
+#endif
+	default:
+		DPRINTK("Invalid var->bits_per_pixel = %d\n",var->bits_per_pixel);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+//
+//	Entry:	con	valid console number
+//			or -1 to indicate current console
+//			(note: current console maybe default initially)
+//
+//		var	pointer to var structure already allocated by caller.
+//
+//	Action: Set pointed at var structure to fb_display[con].var or current.
+//
+//	Exit:	none
+//
+//	Note:	This function called by fb_mem.c,
+static int
+ep93xxfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+{
+	//TBD I do not expect call with con=-1
+	//TBD Maybe I do not really need to support this??
+	if (con == -1)
+		DPRINTK("get_var called with con=-1\n");
+
+	DPRINTK("con=%d\n", con);
+	if (con == -1) {
+
+		//TBD need to set var with current settings.
+		//TBD why can't we just take copy it from info??
+		//ep93xxfb_get_par(&par);
+		//ep93xxfb_encode_var(var, &par);
+
+		//TBD for now current settings is always equal to
+		//TBD default display settings
+		//TBD Is this really complete?
+		*var = global_disp.var;		// copies structure
+	} else
+		*var = fb_display[con].var;	// copies structure
+
+	return 0;
+}
+
+/*
+ * ep93xxfb_set_var():
+ *
+ *	Entry:	con 	-1 means set default display
+ *			else set fb_display[con]
+ *
+ *		var	static var structure to define video mode
+ *
+ *	Action:	Settings are tweaked to get a usable display mode.
+ *		Set console display values for specified console,
+ *		if console valid.  Else set default display values.
+ *
+ *	Exit:	Returns error if cannot tweak settings to usable mode.
+ */
+static int
+ep93xxfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+{
+	struct display *display;
+	int err, chgvar = 0;
+
+	if (con == -1)
+		DPRINTK("called with con=-1\n");
+
+	//
+	// Display is not passed in, but we alter as side-effect
+	//
+	if (con >= 0)
+		//
+		// Display settings for console
+		//
+		display = &fb_display[con];
+	else
+		//
+		// Set default display settings
+		//
+		display = &global_disp;
+
+	//
+	// Check and adjust var if need be to get usable display mode, else return
+	// error if impossible to adjust
+	//
+	if ((err = CheckAdjustVar(var)))
+		return err;
+
+	//  Update parameters
+	DPRINTK("check: var->bpp=%d\n", var->bits_per_pixel);
+	switch (var->bits_per_pixel) {
+#ifdef FBCON_HAS_CFB4
+	case 4:
+		mypar.visual = FB_VISUAL_PSEUDOCOLOR;
+		mypar.palette_size = 16;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		mypar.visual = FB_VISUAL_PSEUDOCOLOR;
+		mypar.palette_size = 256;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		mypar.visual = FB_VISUAL_TRUECOLOR;
+		mypar.palette_size = 16;
+		break;
+#endif
+	default:
+		DPRINTK("ERROR! Bad bpp %d\n", var->bits_per_pixel);
+		return -EINVAL;
+	}
+
+	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)
+		return 0;
+	else if (((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) &&
+			 ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NXTOPEN))
+		return -EINVAL;
+
+	if (con >= 0)
+		if ((display->var.xres != var->xres) ||
+		    (display->var.yres != var->yres) ||
+		    (display->var.xres_virtual != var->xres_virtual) ||
+		    (display->var.yres_virtual != var->yres_virtual) ||
+		    (display->var.sync != var->sync) ||
+		    (display->var.bits_per_pixel != var->bits_per_pixel) ||
+		    (memcmp(&display->var.red, &var->red, sizeof(var->red))) ||
+		    (memcmp(&display->var.green, &var->green, sizeof(var->green))) ||
+		    (memcmp(&display->var.blue, &var->blue, sizeof(var->blue))))
+			chgvar = 1;
+
+	DPRINTK("display->var.xres %d\n",display->var.xres);
+	DPRINTK("display->var.yres %d\n",display->var.yres);
+	DPRINTK("display->var.xres_virtual %d\n",display->var.xres_virtual);
+	DPRINTK("display->var.yres_virtual %d\n",display->var.yres_virtual);
+
+	//TBD is this complete?
+
+	display->var = *var;	// copies structure
+	display->screen_base = mypar.v_screen_base;
+	display->visual	= mypar.visual;
+	display->type = FB_TYPE_PACKED_PIXELS;
+	display->type_aux = 0;
+	display->ypanstep = 0;
+	display->ywrapstep = 0;
+	display->line_length = display->next_line =
+		(var->xres * var->bits_per_pixel) / 8;
+
+	display->can_soft_blank	= 1;
+	display->inverse = 0;
+
+	switch (display->var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB4
+	case 4:
+		display->dispsw = &fbcon_cfb4;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		display->dispsw = &fbcon_cfb8;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		display->dispsw = &fbcon_cfb16;
+		display->dispsw_data = info->pseudo_palette;
+		break;
+#endif
+	default:
+		display->dispsw = &fbcon_dummy;
+		break;
+	}
+
+	/* If the console has changed and the console has defined */
+	/* a changevar function, call that function. */
+	if (chgvar && info && info->changevar)
+		info->changevar(con);
+
+	/* If the current console is selected and it's not truecolor,
+	 *  update the palette
+	 */
+	if ((con == mypar.currcon) && (mypar.visual != FB_VISUAL_TRUECOLOR)) {
+		struct fb_cmap *cmap;
+
+		//TBD what is the juggling of par about?
+		//mypar = par;
+		if (display->cmap.len)
+			cmap = &display->cmap;
+		else
+			cmap = fb_default_cmap(mypar.palette_size);
+
+		//TBD when is cmap.len set?
+		fb_set_cmap(cmap, 1, ep93xxfb_setcolreg, info);
+	}
+
+	//
+	// If the current console is selected, activate the new var.
+	//
+	if (con == mypar.currcon)
+		ConfigureRaster(var, info->par);
+
+	return 0;
+}
+
+//TBD why have this if it does nothing?
+
+static int
+ep93xxfb_updatevar(int con, struct fb_info *info)
+{
+	DPRINTK("entered\n");
+	return 0;
+}
+
+//TBD what is relation between fix data in info and getting fix here?
+
+static int
+ep93xxfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
+{
+	struct display *display;
+
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+	strcpy(fix->id, EP93XX_NAME);
+
+	if (con >= 0) {
+		DPRINTK("Using console specific display for con=%d\n",con);
+		display = &fb_display[con];  /* Display settings for console */
+	}
+	else
+		display = &global_disp;	  /* Default display settings */
+	//TBD global_disp is only valid after set_var called with -1
+
+	fix->smem_start	 = (unsigned long)mypar.p_screen_base;
+	fix->smem_len	 = mypar.screen_size;
+	fix->type	 = display->type;
+	fix->type_aux	 = display->type_aux;
+	fix->xpanstep	 = 0;
+	fix->ypanstep	 = display->ypanstep;
+	fix->ywrapstep	 = display->ywrapstep;
+	fix->visual	 = display->visual;
+	fix->line_length = display->line_length;
+	fix->accel	 = FB_ACCEL_NONE;
+
+	return 0;
+}
+
+static void
+__init ep93xxfb_init_fbinfo(void)
+{
+	DPRINTK("Entering.");
+
+	//
+	// Set up the display name and default font.
+	//
+	strcpy(fb_info.modename, TimingValues[mode].Name);
+	strcpy(fb_info.fontname, default_font);
+
+	fb_info.node = -1;
+	fb_info.flags = FBINFO_FLAG_DEFAULT;
+	fb_info.open = 0;
+
+	//
+	// Set up initial parameters
+	//
+	fb_info.var.xres = TimingValues[mode].HRes;
+	fb_info.var.yres = TimingValues[mode].VRes;
+
+	//
+	// Virtual display not supported
+	//
+	fb_info.var.xres_virtual = fb_info.var.xres;
+	fb_info.var.yres_virtual = fb_info.var.yres;
+
+#ifdef CONFIG_FB_EP93XX_8BPP
+	DPRINTK("Default framebuffer is 8bpp.");
+	fb_info.var.bits_per_pixel	= 8;
+	fb_info.var.red.length		= 8;
+	fb_info.var.green.length	= 8;
+	fb_info.var.blue.length		= 8;
+
+	fb_info.fix.visual = FB_VISUAL_PSEUDOCOLOR;
+	mypar.bits_per_pixel		= 8;
+#endif // CONFIG_FB_EP93XX_8BPP
+#ifdef CONFIG_FB_EP93XX_16BPP_565
+	DPRINTK("Default framebuffer is 16bpp 565.");
+	fb_info.var.bits_per_pixel	= 16;
+	fb_info.var.red.length		= 5;
+	fb_info.var.blue.length		= 5;
+	fb_info.var.green.length	= 6;
+	fb_info.var.transp.length	= 0;
+	fb_info.var.red.offset		= 11;
+	fb_info.var.green.offset	= 5;
+	fb_info.var.blue.offset		= 0;
+	fb_info.var.transp.offset	= 0;
+	fb_info.fix.visual		= FB_VISUAL_TRUECOLOR;
+	fb_info.pseudo_palette		= mypar.palette;
+
+	mypar.bits_per_pixel = 16;
+#endif // CONFIG_FB_EP93XX_16BPP
+
+	//TBD wierd to have a flag which has meaning when call set_var
+	//TBD be copied into fb_info? this is more a parameter than
+	//TBD some state to keep track of.
+	fb_info.var.activate		= FB_ACTIVATE_NOW;
+	fb_info.var.height		= 640;			//TBD unknown
+	fb_info.var.width		= 480;			//TBD unknown
+
+	//
+	// Set the default timing information.
+	//
+	fb_info.var.left_margin		= TimingValues[mode].HFrontPorch;
+	fb_info.var.right_margin	= TimingValues[mode].HBackPorch;
+	fb_info.var.upper_margin	= TimingValues[mode].VFrontPorch;
+	fb_info.var.lower_margin	= TimingValues[mode].VBackPorch;
+	fb_info.var.hsync_len		= TimingValues[mode].HSyncWidth;
+	fb_info.var.vsync_len		= TimingValues[mode].VSyncWidth;
+	fb_info.var.sync		= 0;
+	fb_info.var.vmode		= FB_VMODE_NONINTERLACED;
+
+	fb_info.fix.smem_start		= (__u32) mypar.p_screen_base;	// physical
+	fb_info.fix.smem_len		= (__u32) mypar.screen_size;	//TBD in bytes
+	fb_info.fix.type		= FB_TYPE_PACKED_PIXELS;
+	fb_info.fix.line_length		= fb_info.var.xres_virtual *
+					  fb_info.var.bits_per_pixel/8;	// stride in bytes
+
+	fb_info.monspecs		= monspecs; // copies structure
+	fb_info.fbops			= &ep93xxfb_ops;
+	fb_info.screen_base 		= mypar.v_screen_base;
+
+	fb_info.disp			= &global_disp;
+	fb_info.changevar		= NULL;
+	fb_info.switch_con		= ep93xxfb_switch;
+	fb_info.updatevar		= ep93xxfb_updatevar;	//TBD why not NULL?
+	fb_info.blank			= ep93xxfb_blank;
+
+	//
+	// Save the current TimingValues for later use in Configuration routine.
+	//
+	fb_info.par = &TimingValues[mode];
+
+	mypar.screen_size		= FB_MAX_MEM_SIZE; // not a particular mode
+	mypar.palette_size		= MAX_PALETTE_NUM_ENTRIES; // not a particular mode
+	mypar.montype			= 1;	//TBD why not 0 since single entry?
+	mypar.currcon			= 0;		//TBD is this right?
+
+	// these are also set by set_var
+	mypar.visual			= FB_VISUAL_PSEUDOCOLOR;
+}
+
+//=============================================================================
+// MapFramebuffer
+//=============================================================================
+// Allocates the memory for the frame buffer.  This buffer is remapped into a
+// non-cached, non-buffered, memory region to allow pixel writes to occur
+// without flushing the cache.  Once this area is remapped, all virtual memory
+// access to the video memory should occur at the new region.
+//=============================================================================
+static int __init MapFramebuffer(void)
+{
+	//
+	// Make sure that we don't allocate the buffer twice.
+	//
+	if (mypar.p_screen_base != 0)
+		return(-EINVAL);
+
+	//
+	// Allocate the Frame buffer and map it while we are at it.
+	// Save the Physical address of the Frame buffer in p_screen_base.
+	//
+	mypar.v_screen_base = consistent_alloc(GFP_KERNEL, FB_MAPPED_MEM_SIZE,
+		&mypar.p_screen_base);
+
+	if ( mypar.v_screen_base == 0)
+		return(-ENOMEM);
+
+	return 0;
+}
+
+//=============================================================================
+// ConfigureRaster():
+//=============================================================================
+// Configures LCD Controller based on entries in var parameter.
+//
+// Note: palette is setup elsewhere.
+//=============================================================================
+static int
+ConfigureRaster(struct fb_var_screeninfo *var,
+		DisplayTimingValues *pTimingValues)
+{
+	u_long	flags, ulVIDEOATTRIBS;
+	unsigned int total, uiDevCfg;
+	unsigned int uiPADDR, uiPADR;
+
+	DPRINTK("activating\n");
+
+	/* Disable interrupts and save status */
+	local_irq_save(flags);		// disable interrupts and save flags
+
+	DPRINTK("Configuring %dx%dx%dbpp\n",var->xres, var->yres,
+		var->bits_per_pixel);
+
+	// Setup video mode according to var values.
+	// Remember to unlock total, startstop, and linecarry registers.
+
+	// Disable the video and outputs while changing the video mode.
+	outl( 0, VIDEOATTRIBS );
+
+	if (pTimingValues->RasterConfigure)
+		pTimingValues->RasterConfigure(pTimingValues);
+	else {
+		total = var->vsync_len +  var->upper_margin + var->yres +
+		var->lower_margin - 1;
+
+		RasterSetLocked(VLINESTOTAL, total);
+
+		RasterSetLocked(VSYNCSTRTSTOP, total - var->lower_margin +
+				((total - (var->lower_margin + var->vsync_len)) << 16));
+
+		RasterSetLocked(VACTIVESTRTSTOP, var->yres-1 + (total << 16));
+
+		// Reverse start/stop since N_VBLANK output
+		// unblanked same as active
+		RasterSetLocked(VBLANKSTRTSTOP, var->yres-1 + (total << 16));
+
+		RasterSetLocked(VCLKSTRTSTOP, total + (total << 16));
+
+		//
+		// Now configure the Horizontal timings.
+		//
+		total = var->hsync_len + var->left_margin + var->xres +
+			var->right_margin - 1;
+
+		RasterSetLocked(HCLKSTOTAL,total);
+
+		RasterSetLocked(HSYNCSTRTSTOP, total +
+				((total - var->hsync_len) << 16));
+
+		RasterSetLocked(HACTIVESTRTSTOP, total - var->hsync_len -
+				var->left_margin + ((var->right_margin - 1) << 16));
+
+		RasterSetLocked(HBLANKSTRTSTOP, total - var->hsync_len -
+				var->left_margin + ((var->right_margin - 1) << 16));
+
+		RasterSetLocked(HCLKSTRTSTOP, total + (total << 16));
+
+		RasterSetLocked(LINECARRY, 0);
+
+		//
+		// Now that everything else is setup, enable video and outputs
+		//
+		// Invert Clock, enable outputs and VSYNC,HSYNC,BLANK active low
+		// Invert means pixel output data changes on falling edge of clock, to
+		// provide setup time for the video DAC to latch data on rising edge.
+		//
+		RasterSetLocked(VIDEOATTRIBS, VIDEOATTRIBS_INVCLK |
+				VIDEOATTRIBS_PCLKEN | VIDEOATTRIBS_SYNCEN |
+				VIDEOATTRIBS_DATAEN);
+	}
+
+	//
+	// Configure the Frame Buffer size.
+	//
+	outl( (unsigned int)mypar.p_screen_base, VIDSCRNPAGE );
+	outl( var->yres, SCRNLINES );
+
+	//
+	// Set up the Line size.
+	//
+	total = var->xres * var->bits_per_pixel / 32;
+	outl( (total - 1), LINELENGTH );
+	outl( total, VLINESTEP );
+
+	if (var->bits_per_pixel == 8)
+		//
+		// 8bpp framebuffer, color LUT and convert to 18bpp on pixel bus.
+		//
+		outl( (0x8 | PIXELMODE_P_8BPP | PIXELMODE_C_LUT), PIXELMODE );
+	else if (var->bits_per_pixel == 16)
+		//
+		// 16bpp framebuffer and convert to 18bpp on pixel bus.
+		//
+		outl( 0x8 | PIXELMODE_P_16BPP | ((PIXELMODE_C_565)<<(PIXELMODE_C_SHIFT)),
+			  PIXELMODE );
+
+	//
+	// TODO this is more HACKING!
+	// TODO add configurable framebuffer location and side-band option.
+	//
+	uiDevCfg = inl(SYSCON_DEVCFG);
+	SysconSetLocked(SYSCON_DEVCFG, (uiDevCfg | SYSCON_DEVCFG_RasOnP3) );
+
+	//
+	// TODO add code to calculate this not just slam it in there.
+	//
+	SysconSetLocked(SYSCON_VIDDIV, pTimingValues->VDiv);
+
+	//
+	// Enable Raster and make sure that frame buffer chip select is specfied
+	// since this field is not readable.
+	//
+	ulVIDEOATTRIBS = inl(VIDEOATTRIBS);
+	RasterSetLocked(VIDEOATTRIBS, ulVIDEOATTRIBS | VIDEOATTRIBS_EN |
+			(3 << VIDEOATTRIBS_SDSEL_SHIFT));
+
+	//
+	// Turn on the LCD.
+	//
+	if (mode == 1) {
+		uiPADDR = inl(GPIO_PADDR) | 0x2;
+		outl( uiPADDR, GPIO_PADDR );
+
+		uiPADR = inl(GPIO_PADR) | 0x2;
+		outl( uiPADR, GPIO_PADR );
+	}
+
+	//
+	// Restore interrupt status
+	//
+	local_irq_restore(flags);
+	return 0;
+}
+
+/*
+ * ep93xxfb_blank():
+ *	TBD not implemented
+ */
+static void
+ep93xxfb_blank(int blank, struct fb_info *info)
+{
+}
+
+//=============================================================================
+// ep93xxfb_switch():
+//=============================================================================
+// Change to the specified console.  Palette and video mode are changed to the
+// console's stored parameters.
+//
+//=============================================================================
+static int ep93xxfb_switch(int con, struct fb_info *info)
+{
+	DPRINTK("con=%d info->modename=%s\n", con, info->modename);
+	if (mypar.visual != FB_VISUAL_TRUECOLOR) {
+		struct fb_cmap *cmap;
+		if (mypar.currcon >= 0) {
+			// Get the colormap for the selected console
+			cmap = &fb_display[mypar.currcon].cmap;
+
+			if (cmap->len)
+				fb_get_cmap(cmap, 1, ep93xxfb_getcolreg, info);
+		}
+	}
+
+	mypar.currcon = con;
+	fb_display[con].var.activate = FB_ACTIVATE_NOW;
+	DPRINTK("fb_display[%d].var.activate=%x\n", con,
+		fb_display[con].var.activate);
+
+	ep93xxfb_set_var(&fb_display[con].var, con, info);
+
+	return 0;
+}
+
+//=============================================================================
+// ep93xxfb_init(void)
+//=============================================================================
+//=============================================================================
+int __init ep93xxfb_init(void)
+{
+	int ret;
+
+	DPRINTK("Entering: ep93xxfb_init.\n");
+	//
+	// Allocate and map video buffer
+	//
+	if ((ret = MapFramebuffer()) != 0) {
+		DPRINTK("Leaving: ep93xxfb_init FAILED %08x.", ret);
+		return ret;
+	}
+
+	//
+	// Initialize the Framebuffer Info structure.
+	//
+	ep93xxfb_init_fbinfo();
+
+	//
+	// Check and adjust var and set it active.
+	// TBD is this okay to pass in fb_info.var or
+	// TBD does it cause some aliasing problem?
+	// TBD can set var fail?
+	//
+	ep93xxfb_set_var(&fb_info.var, -1, &fb_info);
+
+	register_framebuffer(&fb_info);
+
+#ifdef CONFIG_EP93XX_GRAPHICS
+	outl(0x00000000, BLOCKCTRL);
+	request_irq(IRQ_GRAPHICS, ep93xxfb_irq_handler, SA_INTERRUPT,
+		    "graphics",NULL);
+#endif
+
+	DPRINTK("Leaving: ep93xxfb_init.");
+
+	return 0;
+}
+
+__init int
+ep93xxfb_setup(char *options)
+{
+	char *opt;
+
+	if (!options || !*options)
+		return 0;
+
+	while ((opt = strsep(&options, ",")) != NULL) {
+		if (!*opt)
+			continue;
+		if (strncmp(opt, "font=", 5) == 0) {
+			strncpy(default_font_storage, opt + 5,
+				sizeof(default_font_storage));
+			default_font = default_font_storage;
+			continue;
+		}
+		if (strncmp(opt, "mode=lcd", 8) == 0) {
+			mode = 1;
+			continue;
+		}
+		if (strncmp(opt, "mode=crt", 8) == 0) {
+			mode = 0;
+			continue;
+		}
+		if (strncmp(opt, "mode=tv", 7) == 0) {
+			mode = 3;
+			continue;
+		}
+		if (strncmp(opt, "overscan=on", 11) == 0) {
+			overscan = 1;
+			continue;
+		}
+		if (strncmp(opt, "overscan=off", 12) == 0) {
+			overscan = 0;
+			continue;
+		}
+
+		printk (KERN_ERR "ep93xxfb: unknown parameter: %s\n", opt);
+	}
+
+	return 0;
+}
+
+//=============================================================================
+// Conexant_CX25871
+//=============================================================================
+// Timing and screen configuration for the Conexant CX25871.
+//=============================================================================
+static int Conexant_CX25871(DisplayTimingValues *pTimingValues)
+{
+	unsigned int uiTemp;
+
+	//
+	// By name it Initializes the CX25871 to 640x480 NTSC.
+	//
+	InitializeCX25871For640x480NTSC();
+
+	//
+	// Disable the Raster Engine.
+	//
+	RasterSetLocked(VIDEOATTRIBS, 0);
+
+	//
+	// Configure the Raster to use external clock for pixel clock.
+	//
+	uiTemp = inl(SYSCON_DEVCFG);
+	SysconSetLocked(SYSCON_DEVCFG, (uiTemp | SYSCON_DEVCFG_EXVC) );
+
+	if (overscan) {
+		//
+		// Configure the Vertical Timing.
+		//
+		RasterSetLocked(VLINESTOTAL, 0x20c);
+		RasterSetLocked(VSYNCSTRTSTOP, 0x01ff0204);
+		RasterSetLocked(VBLANKSTRTSTOP, 0x000001E0);
+		RasterSetLocked(VACTIVESTRTSTOP, 0x000001E0);
+		RasterSetLocked(VCLKSTRTSTOP,0x07FF01E0);
+
+		//
+		// Configure the Horizontal Timing.
+		//
+		RasterSetLocked(HCLKSTOTAL, 0x307);
+		RasterSetLocked(HSYNCSTRTSTOP, 0x02c00307);
+		RasterSetLocked(HBLANKSTRTSTOP,0x00100290);
+		RasterSetLocked(HACTIVESTRTSTOP,0x00100290);
+		RasterSetLocked(HCLKSTRTSTOP, 0x07ff0290);
+	} else {
+		//
+		// Configure the Vertical Timing.
+		//
+		RasterSetLocked(VLINESTOTAL, 0x0257);
+		RasterSetLocked(VSYNCSTRTSTOP, 0x01FF022C);
+		RasterSetLocked(VBLANKSTRTSTOP, 0x000001E0);
+		RasterSetLocked(VACTIVESTRTSTOP, 0x000001E0);
+		RasterSetLocked(VCLKSTRTSTOP,0x07FF01E0);
+
+		//
+		// Configure the Horizontal Timing.
+		//
+		RasterSetLocked(HCLKSTOTAL, 0x30F);
+		RasterSetLocked(HSYNCSTRTSTOP, 0x02c0030f);
+		RasterSetLocked(HBLANKSTRTSTOP,0x000f028f);
+		RasterSetLocked(HACTIVESTRTSTOP,0x000f028f);
+		RasterSetLocked(HCLKSTRTSTOP, 0x07ff028f);
+	}
+
+	RasterSetLocked(LINECARRY, 0);
+
+	//
+	// Enable the Data and Sync outputs only.
+	//
+	RasterSetLocked(VIDEOATTRIBS,
+			VIDEOATTRIBS_DATAEN | VIDEOATTRIBS_SYNCEN);
+
+	return(0);
+}
+
+//=============================================================================
+// PhilipsLCD
+//=============================================================================
+// Timing and screen configuration for the Conexant CX25871.
+//=============================================================================
+static int PhilipsLCD(DisplayTimingValues *pTimingValues)
+{
+	//
+	// Disable the Raster Engine.
+	//
+	RasterSetLocked(VIDEOATTRIBS, 0);
+
+	//
+	// Configure the Vertical Timing.
+	//
+	RasterSetLocked(VLINESTOTAL,	 0x0000020b);
+	RasterSetLocked(VSYNCSTRTSTOP,   0x01ea01ec);
+	RasterSetLocked(VBLANKSTRTSTOP,  0x020b01df);
+	RasterSetLocked(VACTIVESTRTSTOP, 0x020b01df);
+	RasterSetLocked(VCLKSTRTSTOP,	0x020b020b);
+
+	//
+	// Configure the Horizontal Timing.
+	//
+	RasterSetLocked(HCLKSTOTAL,	  0x0000031f);
+	RasterSetLocked(HSYNCSTRTSTOP,   0x02bf031f);
+	RasterSetLocked(HBLANKSTRTSTOP,  0x002f02af);
+	RasterSetLocked(HACTIVESTRTSTOP, 0x002f02af);
+	RasterSetLocked(HCLKSTRTSTOP,	0x031f031f);
+
+	RasterSetLocked(LINECARRY, 0);
+
+	//
+	// Enable the Data and Sync outputs only.
+	// According the the LCD spec we should also be setting INVCLK_EN, but
+	// this makes the data on the screen look incorrect.
+	//
+	RasterSetLocked(VIDEOATTRIBS,
+			VIDEOATTRIBS_PCLKEN | VIDEOATTRIBS_SYNCEN |
+			VIDEOATTRIBS_DATAEN);
+
+	return(0);
+}
+
+//
+// Set the EE clock rate to 250kHz.
+//
+#define EE_DELAY_USEC			2
+
+//
+// The number of time we should read the two wire device before giving
+// up.
+//
+#define EE_READ_TIMEOUT			100
+
+//
+// CS25871 Device Address.
+//
+#define CX25871_DEV_ADDRESS		0x88
+
+//
+// Register 0x32
+//
+#define CX25871_REGx32_AUTO_CHK		0x80
+#define CX25871_REGx32_DRVS_MASK	0x60
+#define CX25871_REGx32_DRVS_SHIFT	5
+#define CX25871_REGx32_SETUP_HOLD	0x10
+#define CX25871_REGx32_INMODE_		0x08
+#define CX25871_REGx32_DATDLY_RE	0x04
+#define CX25871_REGx32_OFFSET_RGB	0x02
+#define CX25871_REGx32_CSC_SEL		0x01
+
+//
+// Register 0xBA
+//
+#define CX25871_REGxBA_SRESET		0x80
+#define CX25871_REGxBA_CHECK_STAT	0x40
+#define CX25871_REGxBA_SLAVER		0x20
+#define CX25871_REGxBA_DACOFF		0x10
+#define CX25871_REGxBA_DACDISD		0x08
+#define CX25871_REGxBA_DACDISC		0x04
+#define CX25871_REGxBA_DACDISB		0x02
+#define CX25871_REGxBA_DACDISA		0x01
+
+//
+// Register 0xC4
+//
+#define CX25871_REGxC4_ESTATUS_MASK	0xC0
+#define CX25871_REGxC4_ESTATUS_SHIFT	6
+#define CX25871_REGxC4_ECCF2		0x20
+#define CX25871_REGxC4_ECCF1		0x10
+#define CX25871_REGxC4_ECCGATE		0x08
+#define CX25871_REGxC4_ECBAR		0x04
+#define CX25871_REGxC4_DCHROMA		0x02
+#define CX25871_REGxC4_EN_OUT		0x01
+
+//
+// Register 0xC6
+//
+#define CX25871_REGxC6_EN_BLANKO	0x80
+#define CX25871_REGxC6_EN_DOT		0x40
+#define CX25871_REGxC6_FIELDI		0x20
+#define CX25871_REGxC6_VSYNCI		0x10
+#define CX25871_REGxC6_HSYNCI		0x08
+#define CX25871_REGxC6_INMODE_MASK	0x07
+#define CX25871_REGxC6_INMODE_SHIFT	0
+
+#define GPIOG_EEDAT 2
+#define GPIOG_EECLK 1
+static int WriteCX25871Reg(unsigned char ucRegAddr, unsigned char ucRegValue);
+
+//****************************************************************************
+// InitializeCX25871640x480
+//****************************************************************************
+// Initialize the CX25871 for 640x480 NTSC output.
+//
+//
+void InitializeCX25871For640x480NTSC(void)
+{
+	//
+	// Perform auto-configuration
+	//
+	WriteCX25871Reg(0xB8, 0);
+
+	//
+	// After auto-configuration, setup pseudo-master mode BUT with
+	// EN_BLANKO bit cleared
+	//
+	WriteCX25871Reg(0xBA, CX25871_REGxBA_SLAVER | CX25871_REGxBA_DACOFF);
+
+	//
+	// See if overscan compenstation (the default for this mode) should be
+	// disabled.
+	//
+	if (overscan) {
+		//
+		// Adaptive flicker filter adjustment.
+		//
+		WriteCX25871Reg(0x34, 0x9B);
+		WriteCX25871Reg(0x36, 0xC0);
+
+		//
+		// Standard flicker filter value.
+		//
+		WriteCX25871Reg(0xC8, 0x92);
+
+		//
+		// Brightness and coring for luma.
+		//
+		WriteCX25871Reg(0xCA, 0xd3);
+
+		//
+		// Saturation and coring for chroma.
+		//
+		WriteCX25871Reg(0xCC, 0xd3);
+
+		//
+		// Set luma peaking filter to 2dB gain.
+		//
+		WriteCX25871Reg(0xD8, 0x60);
+
+		//
+		// Set the timing.
+		//
+		WriteCX25871Reg(0x38, 0x00);
+		WriteCX25871Reg(0x76, 0x10);
+		WriteCX25871Reg(0x78, 0x80);
+		WriteCX25871Reg(0x7a, 0x72);
+		WriteCX25871Reg(0x7c, 0x82);
+		WriteCX25871Reg(0x7e, 0x42);
+		WriteCX25871Reg(0x80, 0xF5);
+		WriteCX25871Reg(0x82, 0x13);
+		WriteCX25871Reg(0x84, 0xF2);
+		WriteCX25871Reg(0x86, 0x26);
+		WriteCX25871Reg(0x88, 0x00);
+		WriteCX25871Reg(0x8a, 0x08);
+		WriteCX25871Reg(0x8c, 0x77);
+		WriteCX25871Reg(0x8e, 0x03);
+		WriteCX25871Reg(0x90, 0x0D);
+		WriteCX25871Reg(0x92, 0x24);
+		WriteCX25871Reg(0x94, 0xE0);
+		WriteCX25871Reg(0x96, 0x06);
+		WriteCX25871Reg(0x98, 0x00);
+		WriteCX25871Reg(0x9a, 0x10);
+		WriteCX25871Reg(0x9c, 0x68);
+		WriteCX25871Reg(0x9e, 0xDA);
+		WriteCX25871Reg(0xa0, 0x0A);
+		WriteCX25871Reg(0xa2, 0x0A);
+		WriteCX25871Reg(0xa4, 0xE5);
+		WriteCX25871Reg(0xa6, 0x77);
+		WriteCX25871Reg(0xa8, 0xC2);
+		WriteCX25871Reg(0xaa, 0x8A);
+		WriteCX25871Reg(0xac, 0x9A);
+		WriteCX25871Reg(0xae, 0x12);
+		WriteCX25871Reg(0xb0, 0x99);
+		WriteCX25871Reg(0xb2, 0x86);
+		WriteCX25871Reg(0xb4, 0x25);
+		WriteCX25871Reg(0xb6, 0x00);
+		WriteCX25871Reg(0xbc, 0x00);
+		WriteCX25871Reg(0xbe, 0x00);
+		WriteCX25871Reg(0xc0, 0x00);
+		WriteCX25871Reg(0xc2, 0x00);
+
+		//
+		// Reset the timing.
+		//
+		mdelay(1);
+		WriteCX25871Reg(0x6c, 0xc4);
+	}
+
+	//
+	// Finish pseudo-master mode configuration.
+	//
+	WriteCX25871Reg(0xC6, (CX25871_REGxC6_INMODE_MASK & 0x3));
+	WriteCX25871Reg(0xC4, CX25871_REGxC4_EN_OUT);
+	WriteCX25871Reg(0x32, 0);
+	WriteCX25871Reg(0xBA, CX25871_REGxBA_SLAVER );
+}
+
+//****************************************************************************
+// WriteCX25871Reg
+//****************************************************************************
+// ucRegAddr	- CS4228 Register Address.
+// usRegValue   - CS4228 Register Value.
+//
+// Return	 0 - Success
+//			1 - Failure
+//
+
+static int WriteCX25871Reg(unsigned char ucRegAddr, unsigned char ucRegValue)
+{
+	unsigned long uiVal, uiDDR;
+	unsigned char ucData, ucIdx, ucBit;
+	unsigned long ulTimeout;
+
+	//
+	// Read the current value of the GPIO data and data direction registers.
+	//
+	uiVal = inl(GPIO_PGDR);
+	uiDDR = inl(GPIO_PGDDR);
+
+	//
+	// If the GPIO pins have not been configured since reset, the data
+	// and clock lines will be set as inputs and with data value of 0.
+	// External pullup resisters are pulling them high.
+	// Set them both high before configuring them as outputs.
+	//
+	uiVal |= (GPIOG_EEDAT | GPIOG_EECLK);
+	outl( uiVal, GPIO_PGDR );
+
+	//
+	// Delay to meet the EE Interface timing specification.
+	//
+	udelay( EE_DELAY_USEC );
+
+	//
+	// Configure the EE data and clock lines as outputs.
+	//
+	uiDDR |= (GPIOG_EEDAT | GPIOG_EECLK);
+	outl( uiDDR, GPIO_PGDDR );
+
+	//
+	// Delay to meet the EE Interface timing specification.
+	//
+	udelay( EE_DELAY_USEC );
+
+	//
+	// Drive the EE data line low.  Since the EE clock line is currently
+	// high, this is the start condition.
+	//
+	uiVal &= ~GPIOG_EEDAT;
+	outl( uiVal, GPIO_PGDR );
+
+	//
+	// Delay to meet the EE Interface timing specification.
+	//
+	udelay( EE_DELAY_USEC );
+
+	//
+	// Drive the EE clock line low.
+	//
+	uiVal &= ~GPIOG_EECLK;
+	outl( uiVal, GPIO_PGDR );
+
+	//
+	// Delay to meet the EE Interface timing specification.
+	//
+	udelay( EE_DELAY_USEC );
+
+	//
+	// Loop through the three bytes which we will send.
+	//
+	for (ucIdx = 0; ucIdx < 3; ucIdx++) {
+		//
+		// Get the appropriate byte based on the current loop
+		// iteration.
+		//
+		if (ucIdx == 0)
+			ucData = (unsigned char)CX25871_DEV_ADDRESS;
+		else if (ucIdx == 1)
+			ucData = ucRegAddr;
+		else
+			ucData = ucRegValue;
+
+		//
+		// Loop through the 8 bits in this byte.
+		//
+		for (ucBit = 0; ucBit < 8; ucBit++) {
+			//
+			// Set the EE data line to correspond to the most
+			// significant bit of the data byte.
+			//
+			if (ucData & 0x80)
+				uiVal |= GPIOG_EEDAT;
+			else
+				uiVal &= ~GPIOG_EEDAT;
+			outl( uiVal, GPIO_PGDR );
+
+			//
+			// Delay to meet the EE Interface timing specification.
+			//
+			udelay( EE_DELAY_USEC );
+
+			//
+			// Drive the EE clock line high.
+			//
+			outl( (uiVal | GPIOG_EECLK), GPIO_PGDR );
+
+			//
+			// Delay to meet the EE Interface timing specification.
+			//
+			udelay( EE_DELAY_USEC );
+
+			//
+			// Drive the EE clock line low.
+			//
+			outl( uiVal, GPIO_PGDR );
+
+			//
+			// Delay to meet the EE Interface timing specification.
+			//
+			udelay( EE_DELAY_USEC );
+
+			//
+			// Shift the data byte to the left by one bit.
+			//
+			ucData <<= 1;
+		}
+
+		//
+		// We've sent the eight bits in this data byte, so we need to
+		// wait for the acknowledge from the target.  Reconfigure the
+		// EE data line as an input so we can read the acknowledge from
+		// the device.
+		//
+		uiDDR &= ~GPIOG_EEDAT;
+		outl( uiDDR, GPIO_PGDDR );
+
+		//
+		// Delay to meet the EE Interface timing specification.
+		//
+		udelay( EE_DELAY_USEC );
+
+		//
+		// Drive the EE clock line high.
+		//
+		outl( (uiVal | GPIOG_EECLK), GPIO_PGDR );
+
+		//
+		// Delay to meet the EE Interface timing specification.
+		//
+		udelay( EE_DELAY_USEC );
+
+		//
+		// Wait until the EE data line is pulled low by the target
+		// device.
+		//
+		ulTimeout = 0;
+		while ( inl(GPIO_PGDR) & GPIOG_EEDAT ) {
+			udelay( EE_DELAY_USEC );
+			ulTimeout++;
+			if (ulTimeout > EE_READ_TIMEOUT )
+				return 1;
+		}
+
+		//
+		// Drive the EE clock line low.
+		//
+		outl( uiVal, GPIO_PGDR );
+
+		//
+		// Delay to meet the EE Interface timing specification.
+		//
+		udelay( EE_DELAY_USEC );
+
+		//
+		// Reconfigure the EE data line as an output.
+		//
+		uiDDR |= GPIOG_EEDAT;
+		outl( uiDDR, GPIO_PGDDR );
+
+		//
+		// Delay to meet the EE Interface timing specification.
+		//
+		udelay( EE_DELAY_USEC );
+	}
+
+	//
+	// Drive the EE data line low.
+	//
+	uiVal &= ~GPIOG_EEDAT;
+	outl( uiVal, GPIO_PGDR );
+
+	//
+	// Delay to meet the EE Interface timing specification.
+	//
+	udelay( EE_DELAY_USEC );
+
+	//
+	// Drive the EE clock line high.
+	//
+	uiVal |= GPIOG_EECLK;
+	outl( uiVal, GPIO_PGDR );
+
+	//
+	// Delay to meet the EE Interface timing specification.
+	//
+	udelay( EE_DELAY_USEC );
+
+	//
+	// Drive the EE data line high.  Since the EE clock line is currently
+	// high, this is the stop condition.
+	//
+	uiVal |= GPIOG_EEDAT;
+	outl( uiVal, GPIO_PGDR );
+
+	//
+	// Delay to meet the EE Interface timing specification.
+	//
+	udelay( EE_DELAY_USEC );
+
+	return 0;
+}
diff -urN linux-2.4.29/drivers/video/ep93xxfb.h linux-2.4.29-uc1/drivers/video/ep93xxfb.h
--- linux-2.4.29/drivers/video/ep93xxfb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/ep93xxfb.h	2005-06-14 02:12:27.000000000 +0100
@@ -0,0 +1,217 @@
+/*
+ * drivers/video/ep93xxfb.h -- IOCTLs for the EP93xx graphics accelerator
+ *
+ * Copyright (c) 2004 Cirrus Logic, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+#ifndef __EP93XXFB_H__
+#define __EP93XXFB_H__
+
+/*
+ * The following are the IOCTLs that can be sent to the EP93xx frame buffer
+ * device.
+ */
+#define FBIO_EP93XX_GET_CAPS	0x000046c0
+#define FBIO_EP93XX_CURSOR	0x000046c1
+#define FBIO_EP93XX_LINE	0x000046c2
+#define FBIO_EP93XX_FILL	0x000046c3
+#define FBIO_EP93XX_BLIT	0x000046c4
+
+/*
+ * ioctl(fd, FBIO_EP93XX_GET_CAPS, unsigned long *)
+ *
+ * The unsigned long is filled in with these capabilities flags to indicate
+ * what the frame buffer driver is capable of performing.
+ */
+#define EP93XX_CAP_CURSOR	0x00000001
+#define EP93XX_CAP_LINE		0x00000002
+#define EP93XX_CAP_FILL		0x00000004
+#define EP93XX_CAP_BLIT		0x00000008
+
+/*
+ * The bits in the flags field of ep93xx_cursor.
+ */
+#define CURSOR_BLINK		0x00000001
+#define CURSOR_MOVE		0x00000002
+#define CURSOR_SETSHAPE		0x00000004
+#define CURSOR_SETCOLOR		0x00000008
+#define CURSOR_ON		0x00000010
+#define CURSOR_OFF		0x00000020
+
+/*
+ * ioctl(fd, FBIO_EP93XX_CURSOR, ep93xx_cursor *)
+ *
+ * "data" points to an array of pixels that define the cursor; each row should
+ * be a multiple of 32-bit values (i.e. 16 pixels).  Each pixel is two bits,
+ * where the values are:
+ *
+ *     00 => transparent    01 => invert    10 => color1    11 => color2
+ *
+ * The data is arranged as follows (per word):
+ *
+ *    bits: |31-30|29-28|27-26|25-24|23-22|21-20|19-18|17-16|
+ *   pixel: | 12  | 13  | 14  | 15  |  8  |  9  | 10  | 11  |
+ *    bits: |15-14|13-12|11-10| 9-8 | 7-6 | 5-4 | 3-2 | 1-0 |
+ *   pixel: |  4  |  5  |  6  |  7  |  0  |  1  |  2  |  3  |
+ *
+ * Regardless of the frame buffer color depth, "color1", "color2",
+ * "blinkcolor1", and "blinkcolor2" are 24-bit colors since the cursor is
+ * injected into the data stream right before the video DAC.
+ *
+ * When "blinkrate" is not zero, pixel value 10 will alternate between "color1"
+ * and "blinkcolor1" (similar for pixel value 11 and "color2"/"blinkcolor2").
+ *
+ * "blinkrate" ranges between 0 and 255.  When 0, blinking is disabled.  255 is
+ * the fastest blink rate and 1 is the slowest.
+ *
+ * Both "width" and "height" must be between 1 and 64; it is preferable to have
+ * "width" a multiple of 16.
+ */
+struct ep93xx_cursor {
+    __u32 flags;
+    __u32 dx;		// Only used if CURSOR_MOVE is set
+    __u32 dy;		// Only used if CURSOR_MOVE is set
+    __u32 width;	// Only used if CURSOR_SETSHAPE is set
+    __u32 height;	// Only used if CURSOR_SETSHAPE is set
+    const char *data;	// Only used if CURSOR_SETSHAPE is set
+    __u32 blinkrate;	// Only used if CURSOR_BLINK is set
+    __u32 color1;	// Only used if CURSOR_SETCOLOR is set
+    __u32 color2;	// Only used if CURSOR_SETCOLOR is set
+    __u32 blinkcolor1;	// Only used if CURSOR_SETCOLOR is set
+    __u32 blinkcolor2;	// Only used if CURSOR_SETCOLOR is set
+};
+
+/*
+ * The bits in the flags field of ep93xx_line.
+ */
+#define LINE_PATTERN		0x00000001
+#define LINE_PRECISE		0x00000002
+#define LINE_BACKGROUND		0x00000004
+
+/*
+ * ioctl(fd, FBIO_EP93XX_LINE, ep93xx_line *)
+ *
+ * The line starts at ("x1","y1") and ends at ("x2","y2").  This means that
+ * when using a pattern, the two coordinates are not transitive (i.e. swapping
+ * ("x1","y1") with ("x2","y2") will not necessarily draw the exact same line,
+ * pattern-wise).
+ *
+ * "pattern" is a 2 to 16 bit pattern (since a 1 bit pattern isn't much of a
+ * pattern).  The lower 16 bits define the pattern (1 being foreground, 0 being
+ * background or transparent), and bits 19-16 define the length of the pattern
+ * (as pattern length - 1).  So, for example, "0xf00ff" defines a 16 bit
+ * with the first 8 pixels in the foreground color and the next 8 pixels in the
+ * background color or transparent.
+ *
+ * LINE_PRECISE is used to apply angularly corrected patterns to line.  It
+ * should only be used when LINE_PATTERN is also set.  The pattern will be
+ * applied along the length of the line, instead of along the length of the
+ * major axis.  This may result in the loss of fine details in the pattern, and
+ * will take more time to draw the line in most cases.
+ */
+struct ep93xx_line {
+    __u32 flags;
+    __s32 x1;
+    __s32 y1;
+    __s32 x2;
+    __s32 y2;
+    __u32 fgcolor;
+    __u32 bgcolor;	// Only used if LINE_BACKGROUND is set
+    __u32 pattern;	// Only used if LINE_PATTERN is set
+};
+
+/*
+ * ioctl(fd, FBIO_EP93XX_FILL, ep93xx_fill *)
+ *
+ * Fills from dx to (dx + width - 1), and from dy to (dy + height - 1).
+ */
+struct ep93xx_fill {
+    __u32 dx;
+    __u32 dy;
+    __u32 width;
+    __u32 height;
+    __u32 color;
+};
+
+/*
+ * The bits in the flags field of ep93xx_blit.
+ */
+#define BLIT_SOURCE_MASK	0x00000001
+#define BLIT_SOURCE_MEMORY	0x00000000
+#define BLIT_SOURCE_SCREEN	0x00000001
+#define BLIT_TRANSPARENT	0x00000004
+#define BLIT_MASK_MASK		0x00000600
+#define BLIT_MASK_DISABLE	0x00000000
+#define BLIT_MASK_AND		0x00000200
+#define BLIT_MASK_OR		0x00000400
+#define BLIT_MASK_XOR		0x00000600
+#define BLIT_DEST_MASK		0x00001800
+#define BLIT_DEST_DISABLE	0x00000000
+#define BLIT_DEST_AND		0x00000800
+#define BLIT_DEST_OR		0x00001000
+#define BLIT_DEST_XOR		0x00001800
+#define BLIT_1BPP_SOURCE	0x00006000
+
+/*
+ * ioctl(fd, FBIO_EP93XX_BLIT, ep93xx_blit *)
+ *
+ * When BLIT_SOURCE_MEMORY is set, "data" points to an array of pixels that are
+ * to be blitted to the screen; each row should be a multiple of 32-bit values.
+ * When BLIT_1BPP_SOURCE is set, each pixel is one bit and is arranged as
+ * follows (per word):
+ *
+ *     bit: |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|
+ *   pixel: |24|25|26|27|28|29|30|31|16|17|18|19|20|21|22|23|
+ *     bit: |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+ *   pixel: | 8| 9|10|11|12|13|14|15| 0| 1| 2| 3| 4| 5| 6| 7|
+ *
+ * When the frame buffer is in 8bpp mode, each pixel is one byte and is
+ * arranged as follows (per word):
+ *
+ *    bits: |31-24|23-16|15-8 | 7-0 |
+ *   pixel: |  3  |  2  |  1  |  0  |
+ *
+ * When the frame buffer is in 16bpp mode, each pixel is two bytes and is
+ * arranged as follows (per word):
+ *
+ *    bits: |31-16|15-0 |
+ *   pixel: |  1  |  0  |
+ *
+ * When BLIT_SOURCE_SCREEN is set, BLIT_1BPP_SOURCE is not valid (not for any
+ * hardware imposed reason, but because it simply doesn't make any sense).
+ * When BLIT_SOURCE_MEMORY and BLIT_1BPP_SOURCE are set, BLIT_MASK_DISABLE must
+ * be set.
+ *
+ * BLIT_MASK_MASK applies a masking operation on the source data as it is read.
+ * When not disabled, each pixel is modified by the given operation with the
+ * "fgcolor" value.
+ *
+ * BLIT_DEST_MASK determines how the data is written to the destination
+ * location.  When not disabled, each destination pixel is modified by the
+ * given operation with the current value.  This operation takes place after
+ * the BLIT_MASK_MASK operation.
+ *
+ * BLIT_TRANSPARENT allows a transparency color to be defined for the blit.  If
+ * set, after BLIT_DEST_MASK has been applied, if the resulting pixel matches
+ * "transcolor", the destination pixel is not modified.
+ */
+struct ep93xx_blit {
+    __u32 flags;
+    __u32 dx;
+    __u32 dy;
+    __u32 width;
+    __u32 height;
+    const char *data;	// Only used if BLIT_SOURCE_MEMORY is set
+    __u32 swidth;	// Only used if BLIT_SOURCE_MEMORY is set
+    __u32 sx;		// Only used if BLIT_SOURCE_SCREEN is set
+    __u32 sy;		// Only used if BLIT_SOURCE_SCREEN is set
+    __u32 fgcolor;	// Only used if BLIT_1BPP_SOURCE or BLIT_MASK_?? is set
+    __u32 bgcolor;	// Only used if BLIT_1BPP_SOURCE is set
+    __u32 transcolor;	// Only used if BLIT_TRANSPARENT is set
+};
+
+#endif /* __EP93XXFB_H__ */
diff -urN linux-2.4.29/drivers/video/fbcon.c linux-2.4.29-uc1/drivers/video/fbcon.c
--- linux-2.4.29/drivers/video/fbcon.c	2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.29-uc1/drivers/video/fbcon.c	2005-06-14 02:12:27.000000000 +0100
@@ -98,7 +98,17 @@
 #include <asm/io.h>
 #endif
 #define INCLUDE_LINUX_LOGO_DATA
+/* 
+ * The #include <asm/linux_logo.h> didn't seem to work for us.
+ * so I use #include <linux/linux_logo.h> if compiling for
+ * our board
+ * (20030314 - hede) 
+ */
+#if defined(CONFIG_FB_COBRA5272) || defined (CONFIG_DRAGEN2)
+#include <linux/linux_logo.h>
+#else
 #include <asm/linux_logo.h>
+#endif
 
 #include <video/fbcon.h>
 #include <video/fbcon-mac.h>	/* for 6x11 font on mac */
@@ -572,8 +582,10 @@
     int i, charcnt = 256;
     struct fbcon_font_desc *font;
     
+#ifndef CONFIG_ARCH_IPOD
     if (con != fg_console || (p->fb_info->flags & FBINFO_FLAG_MODULE) ||
         p->type == FB_TYPE_TEXT)
+#endif
     	logo = 0;
 
     p->var.xoffset = p->var.yoffset = p->yscroll = 0;  /* reset wrap/pan */
@@ -2317,6 +2329,28 @@
 	    done = 1;
 	}
 #endif
+#if defined(CONFIG_FBCON_CFB12)
+	if ((depth == 12) && (p->visual == FB_VISUAL_TRUECOLOR)) {
+		unsigned char *d, c0, c1;
+
+		src = logo;
+		dst = fb;
+		for (y1 = LOGO_H ; y1  ; y1--, dst += line) {
+			d = dst;
+			for (x1 = LOGO_W >> 1 ; x1 ; x1--) {
+				c0 = *src++ - 0x20;
+				c1 = *src++ - 0x20;
+				fb_writeb (((linux_logo_red[c0]   >> 4) & 0x0F) |
+				          (linux_logo_green[c0] & 0xF0), d++);
+				fb_writeb (((linux_logo_blue[c0]  >> 4) & 0x0F) |
+				          (linux_logo_red[c1]   & 0xF0), d++);
+				fb_writeb (((linux_logo_green[c1] >> 4) & 0x0F) |
+				          (linux_logo_blue[c1]  & 0xF0), d++);
+			}
+		}
+		done = 1;
+	}
+#endif
 #if defined(CONFIG_FBCON_CFB4)
 	if (depth == 4 && p->type == FB_TYPE_PACKED_PIXELS) {
 		src = logo;
diff -urN linux-2.4.29/drivers/video/fbcon-cfb12.c linux-2.4.29-uc1/drivers/video/fbcon-cfb12.c
--- linux-2.4.29/drivers/video/fbcon-cfb12.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/fbcon-cfb12.c	2005-06-14 02:12:26.000000000 +0100
@@ -0,0 +1,399 @@
+/*
+ * Frame buffer operations for 12 bpp packed pixels
+ * Copyright (C) 2003 Nucleus Systems, Ltd.
+ *
+ * based on:
+ *
+ *  linux/drivers/video/cfb16.c -- Low level frame buffer operations for 16 bpp
+ *				   truecolor packed pixels
+ *
+ *	Created 5 Apr 1997 by Geert Uytterhoeven
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+#include <asm/io.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-cfb12.h>
+
+    /*
+     *  12 bpp packed pixels
+     *
+     * (font is supposed to be with _even_ width...)
+     */
+
+void fbcon_cfb12_setup(struct display *p)
+{
+    p->next_line = p->line_length ? p->line_length : ((p->var.xres_virtual * 3) >> 1);
+    p->next_plane = 0;
+}
+
+void fbcon_cfb12_bmove(struct display *p, int sy, int sx, int dy, int dx,
+		       int height, int width)
+{
+    u8 *src, *dst;
+    int bytes = p->next_line;
+    int linesize = bytes * fontheight(p);
+
+    src = p->screen_base + sy * linesize + ((sx * fontwidth(p) * 3) >> 1);
+    dst = p->screen_base + dy * linesize + ((dx * fontwidth(p) * 3) >> 1);
+
+    if (src < dst) {
+        src += height * linesize - bytes;
+        dst += height * linesize - bytes;
+        bytes = -bytes;
+    } 
+
+    width = (width * fontwidth(p) * 3) >> 1;
+    height *= fontheight(p);
+
+    for ( ; height ; height--, src += bytes, dst += bytes) {
+        fb_memmove (dst, src, width);
+    }
+}
+
+static void rectfill(u8 *dst, int bytes, int h, int w, int val)
+{
+    u8 *d;
+    int i, v0, v1, v2;
+
+    val |= val << 12;
+    v0 = (val >>  0) & 0xFF;
+    v1 = (val >>  8) & 0xFF;
+    v2 = (val >> 12) & 0xFF;
+
+    for ( ; h ; h--,  dst += bytes) {
+        for (i = w, d = dst ; i ; i--) {
+            fb_writeb (v0, d++);
+            fb_writeb (v1, d++);
+            fb_writeb (v2, d++);
+        }
+    }
+}
+
+void fbcon_cfb12_clear(struct vc_data *conp, struct display *p, int dy, int dx,
+		       int height, int width)
+{
+    u8 *dst;
+    int bytes = p->next_line;
+    int linesize = bytes * fontheight(p);
+    int bgx;
+
+    dst = p->screen_base + dy * linesize + ((dx * fontwidth(p) * 3) >> 1);
+
+    width = (width * fontwidth(p)) >> 1;
+    height *= fontheight(p);
+
+    bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
+
+    rectfill (dst, bytes,  height, width, bgx);
+}
+
+void fbcon_cfb12_putc(struct vc_data *conp, struct display *p, int c, int yy,
+		      int xx)
+{
+    u8 *d, *dst, *fnt;
+    int bits, fw = fontwidth(p), fh = fontheight(p), i;
+    int fgx, bgx, f0, f1, f2, b0, b1, b2;
+    u8 bf[4];
+    int bytes = p->next_line;
+    int linesize = bytes * fontheight(p);
+
+    dst = p->screen_base + yy * linesize + ((xx * fw * 3) >> 1);
+
+    fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
+    fgx |= fgx << 12;
+    f0 = (fgx >>  0) & 0xFF;
+    f1 = (fgx >>  8) & 0xFF;
+    f2 = (fgx >> 16) & 0xFF;
+
+    bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
+    bgx |= bgx << 12;
+    b0 = (bgx >>  0) & 0xFF;
+    b1 = (bgx >>  8) & 0xFF;
+    b2 = (bgx >> 16) & 0xFF;
+
+    bf[0] = b1;
+    bf[1] = (b1 & 0x0F) | (f1 & 0xF0);
+    bf[2] = (f1 & 0x0F) | (b1 & 0xF0);
+    bf[3] = f1;
+
+    c &= p->charmask;
+
+    switch (fw) {
+    case 4:
+    case 6:
+    case 8:
+        fnt = p->fontdata + c * fh;
+        for (i = fh ; i ; i--, dst += bytes) {
+            d = dst;
+            bits = *fnt++;
+            fb_writeb ((bits & 0x80) ? f0 : b0, d++);
+            fb_writeb (bf[(bits & 0xC0) >> 6], d++);
+            fb_writeb ((bits & 0x40) ? f2 : b2, d++);
+            fb_writeb ((bits & 0x20) ? f0 : b0, d++);
+            fb_writeb (bf[(bits & 0x30) >> 4], d++);
+            fb_writeb ((bits & 0x10) ? f2 : b2, d++);
+            if (fw >= 6) {
+                fb_writeb ((bits & 0x08) ? f0 : b0, d++);
+                fb_writeb (bf[(bits & 0x0C) >> 2], d++);
+                fb_writeb ((bits & 0x04) ? f2 : b2, d++);
+                if (fw == 8) {
+                    fb_writeb ((bits & 0x02) ? f0 : b0, d++);
+                    fb_writeb (bf[(bits & 0x03) >> 0], d++);
+                    fb_writeb ((bits & 0x01) ? f2 : b2, d++);
+                }
+            }
+        }
+        break;
+            
+    case 10:
+    case 12:
+    case 14:
+    case 16:
+        fnt = p->fontdata + ((c * fh) << 1);
+        for (i = fh ; i ; i--, dst += bytes) {
+            d = dst;
+            bits = *fnt++;
+            fb_writeb ((bits & 0x80) ? f0 : b0, d++);
+            fb_writeb (bf[(bits & 0xC0) >> 6], d++);
+            fb_writeb ((bits & 0x40) ? f2 : b2, d++);
+            fb_writeb ((bits & 0x20) ? f0 : b0, d++);
+            fb_writeb (bf[(bits & 0x30) >> 4], d++);
+            fb_writeb ((bits & 0x10) ? f2 : b2, d++);
+            fb_writeb ((bits & 0x08) ? f0 : b0, d++);
+            fb_writeb (bf[(bits & 0x0C) >> 2], d++);
+            fb_writeb ((bits & 0x04) ? f2 : b2, d++);
+            fb_writeb ((bits & 0x02) ? f0 : b0, d++);
+            fb_writeb (bf[(bits & 0x03) >> 0], d++);
+            fb_writeb ((bits & 0x01) ? f2 : b2, d++);
+            bits = *fnt++;
+            fb_writeb ((bits & 0x80) ? f0 : b0, d++);
+            fb_writeb (bf[(bits & 0xC0) >> 6], d++);
+            fb_writeb ((bits & 0x40) ? f2 : b2, d++);
+            if (fw >= 12) {
+                fb_writeb ((bits & 0x20) ? f0 : b0, d++);
+                fb_writeb (bf[(bits & 0x30) >> 4], d++);
+                fb_writeb ((bits & 0x10) ? f2 : b2, d++);
+                if (fw >= 14) {
+                    fb_writeb ((bits & 0x08) ? f0 : b0, d++);
+                    fb_writeb (bf[(bits & 0x0C) >> 2], d++);
+                    fb_writeb ((bits & 0x04) ? f2 : b2, d++);
+                    if (fw == 16) {
+                        fb_writeb ((bits & 0x02) ? f0 : b0, d++);
+                        fb_writeb (bf[(bits & 0x03) >> 0], d++);
+                        fb_writeb ((bits & 0x01) ? f2 : b2, d++);
+                    }
+                }
+            }
+        }
+        break;
+    }
+}
+
+void fbcon_cfb12_putcs(struct vc_data *conp, struct display *p,
+		       const unsigned short *s, int count, int yy, int xx)
+{
+    u8 *d, *d2, *dst, *fnt;
+    int bits, fw = fontwidth(p), fh = fontheight(p), i, c;
+    int fgx, bgx, f0, f1, f2, b0, b1, b2;
+    u8 bf[4];
+    int bytes = p->next_line;
+    int linesize = bytes * fontheight(p);
+
+    dst = p->screen_base + yy * linesize + ((xx * fw * 3) >> 1);
+
+    c = scr_readw (s);
+
+    fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
+    fgx |= fgx << 12;
+    f0 = (fgx >>  0) & 0xFF;
+    f1 = (fgx >>  8) & 0xFF;
+    f2 = (fgx >> 16) & 0xFF;
+
+    bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
+    bgx |= bgx << 12;
+    b0 = (bgx >>  0) & 0xFF;
+    b1 = (bgx >>  8) & 0xFF;
+    b2 = (bgx >> 16) & 0xFF;
+
+    bf[0] = b1;
+    bf[1] = (b1 & 0x0F) | (f1 & 0xF0);
+    bf[2] = (f1 & 0x0F) | (b1 & 0xF0);
+    bf[3] = f1;
+
+    switch (fw) {
+    case 4:
+    case 6:
+    case 8:
+        while (count-- > 0) {
+            c = scr_readw (s++) & p->charmask;
+            fnt = p->fontdata + c * fh;
+            for (i = fh, d2 = dst ; i ; i--, d2 += bytes) {
+                d = d2;
+                bits = *fnt++;
+                fb_writeb ((bits & 0x80) ? f0 : b0, d++);
+                fb_writeb (bf[(bits & 0xC0) >> 6], d++);
+                fb_writeb ((bits & 0x40) ? f2 : b2, d++);
+                fb_writeb ((bits & 0x20) ? f0 : b0, d++);
+                fb_writeb (bf[(bits & 0x30) >> 4], d++);
+                fb_writeb ((bits & 0x10) ? f2 : b2, d++);
+                if (fw >= 6) {
+                    fb_writeb ((bits & 0x08) ? f0 : b0, d++);
+                    fb_writeb (bf[(bits & 0x0C) >> 2], d++);
+                    fb_writeb ((bits & 0x04) ? f2 : b2, d++);
+                    if (fw == 8) {
+                        fb_writeb ((bits & 0x02) ? f0 : b0, d++);
+                        fb_writeb (bf[(bits & 0x03) >> 0], d++);
+                        fb_writeb ((bits & 0x01) ? f2 : b2, d++);
+                    }
+                }
+            }
+            dst += (fw * 3) >> 1;
+        }
+        break;
+            
+    case 10:
+    case 12:
+    case 14:
+    case 16:
+        while (count-- > 0) {
+            c = scr_readw (s++) & p->charmask;
+            fnt = p->fontdata + ((c * fh) << 1);
+            for (i = fh, d2 = dst ; i ; i--, d2 += bytes) {
+                d = d2;
+                bits = *fnt++;
+                fb_writeb ((bits & 0x80) ? f0 : b0, d++);
+                fb_writeb (bf[(bits & 0xC0) >> 6], d++);
+                fb_writeb ((bits & 0x40) ? f2 : b2, d++);
+                fb_writeb ((bits & 0x20) ? f0 : b0, d++);
+                fb_writeb (bf[(bits & 0x30) >> 4], d++);
+                fb_writeb ((bits & 0x10) ? f2 : b2, d++);
+                fb_writeb ((bits & 0x08) ? f0 : b0, d++);
+                fb_writeb (bf[(bits & 0x0C) >> 2], d++);
+                fb_writeb ((bits & 0x04) ? f2 : b2, d++);
+                fb_writeb ((bits & 0x02) ? f0 : b0, d++);
+                fb_writeb (bf[(bits & 0x03) >> 0], d++);
+                fb_writeb ((bits & 0x01) ? f2 : b2, d++);
+                bits = *fnt++;
+                fb_writeb ((bits & 0x80) ? f0 : b0, d++);
+                fb_writeb (bf[(bits & 0xC0) >> 6], d++);
+                fb_writeb ((bits & 0x40) ? f2 : b2, d++);
+                if (fw >= 12) {
+                    fb_writeb ((bits & 0x20) ? f0 : b0, d++);
+                    fb_writeb (bf[(bits & 0x30) >> 4], d++);
+                    fb_writeb ((bits & 0x10) ? f2 : b2, d++);
+                    if (fw >= 14) {
+                        fb_writeb ((bits & 0x08) ? f0 : b0, d++);
+                        fb_writeb (bf[(bits & 0x0C) >> 2], d++);
+                        fb_writeb ((bits & 0x04) ? f2 : b2, d++);
+                        if (fw == 16) {
+                            fb_writeb ((bits & 0x02) ? f0 : b0, d++);
+                            fb_writeb (bf[(bits & 0x03) >> 0], d++);
+                            fb_writeb ((bits & 0x01) ? f2 : b2, d++);
+                        }
+                    }
+                }
+            }
+            dst += (fw * 3) >> 1;
+        }
+        break;
+    }
+}
+
+void fbcon_cfb12_revc(struct display *p, int xx, int yy)
+{
+    u8 *d, *dst;
+    int w, h, i;
+    int bytes = p->next_line;
+    int linesize = bytes * fontheight(p);
+
+    dst = p->screen_base + yy * linesize + ((xx * fontwidth(p) * 3) >> 1);
+
+    w = (fontwidth(p) * 3) >> 1;
+    h = fontheight(p);
+
+    for ( ; h ; h--,  dst += bytes) {
+        for (i = w, d = dst ; i ; i--, d++) {
+            fb_writeb (~fb_readb (d), d);
+        }
+    }
+}
+
+void fbcon_cfb12_clear_margins(struct vc_data *conp, struct display *p,
+			       int bottom_only)
+{
+    u8 *dst;
+    int rs, bs, rw, bw, bgx;
+    int bytes = p->next_line;
+
+    bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
+    rs = conp->vc_cols * fontwidth(p);
+    rw = p->var.xres - rs;
+    bs = conp->vc_rows * fontheight(p);
+    bw = p->var.yres - bs;
+
+    if (!bottom_only && rw) {
+        dst = p->screen_base + (rs >> 1);
+        rectfill(dst, bytes, p->var.yres_virtual, rw >> 1, bgx);
+    }
+    if (bw) {
+        dst = p->screen_base + (p->var.yoffset + bs) * bytes;
+        rectfill(dst, bytes, bw, rs >> 1, bgx);
+    }
+}
+
+
+    /*
+     *  `switch' for the low level operations
+     */
+
+struct display_switch fbcon_cfb12 = {
+    setup:		fbcon_cfb12_setup,
+    bmove:		fbcon_cfb12_bmove,
+    clear:		fbcon_cfb12_clear,
+    putc:		fbcon_cfb12_putc,
+    putcs:		fbcon_cfb12_putcs,
+    revc:		fbcon_cfb12_revc,
+    clear_margins:	fbcon_cfb12_clear_margins,
+    fontwidthmask:	FONTWIDTH(4) | FONTWIDTH(6) |
+                        FONTWIDTH(8) | FONTWIDTH(10) |
+                        FONTWIDTH(12) | FONTWIDTH(14) |
+                        FONTWIDTH(16)
+};
+
+
+#ifdef MODULE
+MODULE_LICENSE("GPL");
+
+int init_module(void)
+{
+    return 0;
+}
+
+void cleanup_module(void)
+{
+}
+#endif /* MODULE */
+
+
+    /*
+     *  Visible symbols for modules
+     */
+
+EXPORT_SYMBOL(fbcon_cfb12);
+EXPORT_SYMBOL(fbcon_cfb12_setup);
+EXPORT_SYMBOL(fbcon_cfb12_bmove);
+EXPORT_SYMBOL(fbcon_cfb12_clear);
+EXPORT_SYMBOL(fbcon_cfb12_putc);
+EXPORT_SYMBOL(fbcon_cfb12_putcs);
+EXPORT_SYMBOL(fbcon_cfb12_revc);
+EXPORT_SYMBOL(fbcon_cfb12_clear_margins);
diff -urN linux-2.4.29/drivers/video/fbcon-cfb16.c linux-2.4.29-uc1/drivers/video/fbcon-cfb16.c
--- linux-2.4.29/drivers/video/fbcon-cfb16.c	2001-10-15 21:47:13.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/fbcon-cfb16.c	2005-06-14 02:12:27.000000000 +0100
@@ -111,12 +111,19 @@
     dest = p->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p) * 2;
 
     bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
+#ifdef CONFIG_ARCH_EDB7312
+	width = width * fontwidth(p);
+	if (width * 2 == bytes)
+		rectfill(dest, lines * width, 1, bgx, bytes);
+	else
+		rectfill(dest, width, lines, bgx, bytes);
+#else
     width *= fontwidth(p)/4;
     if (width * 8 == bytes)
 	rectfill(dest, lines * width * 4, 1, bgx, bytes);
     else
 	rectfill(dest, width * 4, lines, bgx, bytes);
+#endif
 }
 
 void fbcon_cfb16_putc(struct vc_data *conp, struct display *p, int c, int yy,
@@ -136,14 +143,16 @@
 
     switch (fontwidth(p)) {
     case 4:
+    case 6:
     case 8:
 	cdat = p->fontdata + (c & p->charmask) * fontheight(p);
 	for (rows = fontheight(p); rows--; dest += bytes) {
 	    bits = *cdat++;
 	    fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
 	    fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
-	    if (fontwidth(p) == 8) {
+	    if (fontwidth(p) >= 6) {
 		fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
+		if (fontwidth(p) == 8)
 		fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
 	    }
 	}
@@ -187,6 +196,7 @@
 
     switch (fontwidth(p)) {
     case 4:
+    case 6:
     case 8:
 	while (count--) {
 	    c = scr_readw(s++) & p->charmask;
@@ -195,8 +205,9 @@
 		u8 bits = *cdat++;
 	        fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
 	        fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
-		if (fontwidth(p) == 8) {
+		if (fontwidth(p) >= 6) {
 		    fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
+		    if (fontwidth(p) == 8)
 		    fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
 		}
 	    }
@@ -245,9 +256,11 @@
 	    fb_writel(fb_readl(dest+20) ^ 0xffffffff, dest+20);
 	    /* FALL THROUGH */
 	case 8:
-	    fb_writel(fb_readl(dest+8) ^ 0xffffffff, dest+8);
 	    fb_writel(fb_readl(dest+12) ^ 0xffffffff, dest+12);
 	    /* FALL THROUGH */
+	case 6:
+	    fb_writel(fb_readl(dest+8) ^ 0xffffffff, dest+8);
+	    /* FALL THROUGH */
 	case 4:
 	    fb_writel(fb_readl(dest+0) ^ 0xffffffff, dest+0);
 	    fb_writel(fb_readl(dest+4) ^ 0xffffffff, dest+4);
@@ -288,7 +301,7 @@
     putcs:		fbcon_cfb16_putcs,
     revc:		fbcon_cfb16_revc,
     clear_margins:	fbcon_cfb16_clear_margins,
-    fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+    fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(6)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 
 
diff -urN linux-2.4.29/drivers/video/fbmem.c linux-2.4.29-uc1/drivers/video/fbmem.c
--- linux-2.4.29/drivers/video/fbmem.c	2005-01-19 14:10:09.000000000 +0000
+++ linux-2.4.29-uc1/drivers/video/fbmem.c	2005-06-14 02:12:27.000000000 +0100
@@ -5,10 +5,17 @@
  *
  *	2001 - Documented with DocBook
  *	- Brad Douglas <brad@neruo.com>
- *
+ * changes for _NO_MM_ in fb_mmap by <uclinux@schoeldgen.de> Mar 2002
+ * included support for DragonBall (MC68EZ328) framebuffer initialization
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file COPYING in the main directory of this archive
  * for more details.
+ * CHANGES
+ * 20030312
+ *    - Added support for the EPSON S1D13706 framebuffer driver for
+ *      our COBRA5272 board (the s1d13706fb* stuff).
+ *      ATTENTION! This is _very_ experimental, currently!
+ *    (hede)
  */
 
 #include <linux/config.h>
@@ -53,6 +60,10 @@
 extern int amifb_setup(char*);
 extern int atafb_init(void);
 extern int atafb_setup(char*);
+extern int m68328fb_init(void);
+extern void m68328fb_setup(char*);
+extern int mc68x328fb_init(void);
+extern void mc68x328fb_setup(char*);
 extern int macfb_init(void);
 extern int macfb_setup(char*);
 extern int cyberfb_init(void);
@@ -135,14 +146,40 @@
 extern int intelfb_setup(char*);
 extern int e1355fb_init(void);
 extern int e1355fb_setup(char*);
+extern int mq200fb_init(void);
+extern int mq200fb_setup(char*);
 extern int e1356fb_init(void);
 extern int e1356fb_setup(char*);
+extern int ep93xxfb_init(void);
+extern int ep93xxfb_setup(char*);
 extern int au1100fb_init(void);
 extern int au1100fb_setup(char*);
 extern int pvr2fb_init(void);
 extern int pvr2fb_setup(char*);
 extern int sstfb_init(void);
 extern int sstfb_setup(char*);
+extern int ipodfb_init(void);
+extern int ipodfb_setup(char*);
+extern int mq1100fb_setup(char*);
+extern int mq1100fb_init(char*);
+extern int s3c44b0xfb_init(void);
+extern int s3c44b0xfb_setup(char*);
+#if defined(CONFIG_FB_COBRA5272) && defined(CONFIG_FB_S1D13706)
+/* 
+ * Again: This is _really_ experimental!
+ * Feedback really welcome!
+ */
+extern int s1d13706fb_init(void);
+extern int s1d13706fb_setup(char*);
+#endif
+#if defined(CONFIG_FB_COBRA5272) && defined(CONFIG_FB_S1D13806)
+/* 
+ * Again: This is _really_ experimental!
+ * Feedback really welcome!
+ */
+extern int s1d13806fb_init(void);
+extern int s1d13806fb_setup(char*);
+#endif
 extern int it8181fb_init(void);
 extern int it8181fb_setup(char*);
 
@@ -159,6 +196,10 @@
 	 */
 	{ "sbus", sbusfb_init, sbusfb_setup },
 #endif
+#ifdef CONFIG_FB_IPOD
+#define CONFIG_VT_CONSOLE 1
+	{ "ipod", ipodfb_init, ipodfb_setup },
+#endif
 
 	/*
 	 * Chipset specific drivers that use resource management
@@ -170,6 +211,12 @@
 #ifdef CONFIG_FB_AMIGA
 	{ "amifb", amifb_init, amifb_setup },
 #endif
+#ifdef CONFIG_FB_CLPS711X
+	{ "clps711xfb", clps711xfb_init, NULL },
+#endif
+#ifdef CONFIG_FB_EDB7312
+	{ "edb7312fb", edb7312fb_init, edb7312fb_setup },
+#endif
 #ifdef CONFIG_FB_CYBER
 	{ "cyber", cyberfb_init, cyberfb_setup },
 #endif
@@ -247,7 +294,12 @@
 	 * _after_ all other frame buffer devices that use resource
 	 * management!
 	 */
-
+#ifdef CONFIG_FB_M68328
+	{ "68328fb", m68328fb_init,m68328fb_setup },
+#endif
+#ifdef CONFIG_FB_MC68X328
+	{ "mc68x328fb", mc68x328fb_init, mc68x328fb_setup },
+#endif
 #ifdef CONFIG_FB_OF
 	{ "offb", offb_init, NULL },
 #endif
@@ -328,13 +380,27 @@
 #ifdef CONFIG_FB_MAXINE
 	{ "maxinefb", maxinefb_init, NULL },
 #endif
+#ifdef CONFIG_FB_EP93XX
+	{ "ep93xxfb", ep93xxfb_init, ep93xxfb_setup },
+#endif
 #ifdef CONFIG_FB_AU1100
 	{ "au1100fb", au1100fb_init, au1100fb_setup },
 #endif 
+#ifdef CONFIG_FB_S3C44B0X
+	{ "s3c44b0xfb", s3c44b0xfb_init, s3c44b0xfb_setup },
+#endif 
+#if defined(CONFIG_FB_COBRA5272) && defined(CONFIG_FB_S1D13706)
+	{ "s1d13706fb", s1d13706fb_init, s1d13706fb_setup },
+#endif
+#if defined(CONFIG_FB_COBRA5272) && defined(CONFIG_FB_S1D13806)
+	{ "s1d13806fb", s1d13806fb_init, s1d13806fb_setup },
+#endif
 #ifdef CONFIG_FB_IT8181
 	{ "it8181fb", it8181fb_init, it8181fb_setup },
 #endif
-
+#if defined(CONFIG_FB_MQ1100)
+	{ "MediaQ", mq1100fb_init, mq1100fb_setup },
+#endif
 
 	/*
 	 * Generic drivers that don't use resource management (yet)
@@ -359,6 +425,18 @@
 	 */
 	{ "vfb", vfb_init, vfb_setup },
 #endif
+
+#ifdef CONFIG_FB_VIRUAL_SMALL
+	/*
+	 * Vfb must be last to avoid that it becomes your primary display if
+	 * other display devices are present
+	 */
+	{ "vfb_small", vfb_small_init, vfb_small_setup },
+#endif
+
+#ifdef CONFIG_FB_MQ200
+	{ "mq200fb", mq200fb_init, mq200fb_setup },
+#endif
 };
 
 #define NUM_FB_DRIVERS	(sizeof(fb_drivers)/sizeof(*fb_drivers))
@@ -590,13 +668,18 @@
 	int fbidx = GET_FB_IDX(file->f_dentry->d_inode->i_rdev);
 	struct fb_info *info = registered_fb[fbidx];
 	struct fb_ops *fb = info->fbops;
-	unsigned long off;
+	unsigned long off = 0;
 #if !defined(__sparc__) || defined(__sparc_v9__)
 	struct fb_fix_screeninfo fix;
 	struct fb_var_screeninfo var;
 	unsigned long start;
 	u32 len;
 #endif
+#ifdef NO_MM 
+	fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
+	vma->vm_start = fix.smem_start+ vma->vm_offset;
+	return (0);
+#else /* /NO_MM */   
 
 	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
 		return -EINVAL;
@@ -622,7 +705,6 @@
 
 	lock_kernel();
 	fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
-
 	/* frame buffer memory */
 	start = fix.smem_start;
 	if (info->mapped_vram)
@@ -689,9 +771,11 @@
 	if (io_remap_page_range(vma->vm_start, off,
 			     vma->vm_end - vma->vm_start, vma->vm_page_prot))
 		return -EAGAIN;
+
 #endif /* !__sparc_v9__ */
 	return 0;
 #endif /* !sparc32 */
+#endif
 }
 
 #if 1 /* to go away in 2.5.0 */
@@ -815,7 +899,9 @@
 
 	if (first) {
 		first = 0;
+#ifdef CONFIG_VT_CONSOLE
 		take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default);
+#endif
 	}
 	sprintf (name_buf, "%d", i);
 	fb_info->devfs_handle =
diff -urN linux-2.4.29/drivers/video/fonts.c linux-2.4.29-uc1/drivers/video/fonts.c
--- linux-2.4.29/drivers/video/fonts.c	2001-03-03 02:38:39.000000000 +0000
+++ linux-2.4.29-uc1/drivers/video/fonts.c	2005-06-14 02:12:27.000000000 +0100
@@ -56,6 +56,14 @@
 #undef NO_FONTS
     &font_pearl_8x8,
 #endif
+#ifdef CONFIG_FONT_VTX_6x8
+#undef NO_FONTS
+    &font_vtx_6x8,
+#endif
+#ifdef CONFIG_FONT_VTX_4x8
+#undef NO_FONTS
+    &font_vtx_4x8,
+#endif
 };
 
 #define num_fonts (sizeof(fbcon_fonts)/sizeof(*fbcon_fonts))
diff -urN linux-2.4.29/drivers/video/font_vtx_4x8.c linux-2.4.29-uc1/drivers/video/font_vtx_4x8.c
--- linux-2.4.29/drivers/video/font_vtx_4x8.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/font_vtx_4x8.c	2005-06-14 02:12:26.000000000 +0100
@@ -0,0 +1,147 @@
+/********************/
+/* 4x8 console font */
+/********************/
+
+#include <video/font.h>
+
+#define FONTDATAMAX (8 * 256)
+
+static unsigned char fontdata_4x8[FONTDATAMAX] = {
+    0,0,0,0,0,0,0,0,64,160,224,160,160,224,160,64,
+    64,224,160,224,224,160,224,64,0,160,224,224,224,224,64,0,
+    0,64,64,224,224,64,64,0,0,224,64,224,64,64,224,0,
+    0,64,64,224,224,64,64,0,0,0,96,96,96,96,0,0,
+    240,240,144,144,144,144,240,240,0,96,144,144,144,144,96,0,
+    240,144,96,96,96,96,144,240,112,48,80,64,160,160,64,0,
+    64,160,160,64,64,224,64,0,96,96,96,64,64,64,192,128,
+    224,160,224,160,160,160,160,160,64,224,64,160,160,64,224,64,
+    128,192,192,224,192,192,128,0,32,96,96,224,96,96,32,0,
+    64,64,224,64,64,224,64,64,160,160,160,160,160,0,160,0,
+    112,208,208,80,80,80,80,0,96,144,64,96,96,32,144,96,
+    0,0,0,0,96,96,96,0,64,64,224,64,224,64,64,240,
+    64,64,224,64,64,64,64,0,64,64,64,64,224,64,64,0,
+    0,0,32,240,32,0,0,0,0,0,64,240,64,0,0,0,
+    0,0,128,128,128,224,0,0,0,0,96,240,96,0,0,0,
+    0,0,96,96,240,240,0,0,0,0,240,240,96,96,0,0,
+    0,0,0,0,0,0,0,0,64,64,64,64,64,0,64,0,
+    160,160,160,0,0,0,0,0,160,160,224,160,224,160,160,0,
+    64,96,192,64,96,192,64,0,0,160,32,64,128,160,0,0,
+    64,192,64,224,160,224,64,0,64,64,128,0,0,0,0,0,
+    32,64,128,128,128,64,32,0,128,64,32,32,32,64,128,0,
+    0,160,64,224,64,160,0,0,0,64,64,224,64,64,0,0,
+    0,0,0,0,0,64,64,128,0,0,0,224,0,0,0,0,
+    0,0,0,0,0,64,64,0,0,32,32,64,128,128,0,0,
+    64,160,160,224,160,160,64,0,64,192,64,64,64,64,64,0,
+    64,160,32,32,64,128,224,0,192,32,32,192,32,32,192,0,
+    32,96,160,160,224,32,32,0,224,128,192,32,32,160,64,0,
+    96,128,128,192,160,160,64,0,224,32,32,64,64,64,64,0,
+    64,160,160,64,160,160,64,0,64,160,160,96,32,32,192,0,
+    0,64,64,0,0,64,64,0,0,64,64,0,0,64,64,128,
+    0,32,64,128,64,32,0,0,0,0,224,0,0,224,0,0,
+    0,128,64,32,64,128,0,0,192,32,64,64,64,0,64,0,
+    64,160,160,160,160,128,96,0,64,160,160,224,160,160,160,0,
+    192,160,160,192,160,160,192,0,96,128,128,128,128,128,96,0,
+    192,160,160,160,160,160,192,0,224,128,128,192,128,128,224,0,
+    224,128,128,192,128,128,128,0,96,128,128,128,160,160,64,0,
+    160,160,160,224,160,160,160,0,224,64,64,64,64,64,224,0,
+    32,32,32,32,32,160,64,0,160,160,160,192,160,160,160,0,
+    128,128,128,128,128,128,224,0,160,224,224,160,160,160,160,0,
+    160,160,224,224,224,160,160,0,64,160,160,160,160,160,64,0,
+    192,160,160,192,128,128,128,0,64,160,160,160,160,224,96,0,
+    192,160,160,192,160,160,160,0,64,160,128,64,32,160,64,0,
+    224,64,64,64,64,64,64,0,160,160,160,160,160,160,224,0,
+    160,160,160,160,160,160,64,0,160,160,160,160,224,224,224,0,
+    160,160,160,64,160,160,160,0,160,160,160,64,64,64,64,0,
+    224,32,64,64,64,128,224,0,224,128,128,128,128,128,224,0,
+    0,128,128,64,32,32,0,0,224,32,32,32,32,32,224,0,
+    64,160,0,0,0,0,0,0,0,0,0,0,0,0,0,240,
+    128,64,32,0,0,0,0,0,0,0,192,32,96,160,96,0,
+    128,128,192,160,160,160,192,0,0,0,96,128,128,128,96,0,
+    32,32,96,160,160,160,96,0,0,0,64,160,224,128,96,0,
+    96,128,128,224,128,128,128,0,0,0,64,160,160,96,32,192,
+    128,128,192,160,160,160,160,0,64,0,64,64,64,64,64,0,
+    32,0,32,32,32,32,160,64,128,128,160,160,192,160,160,0,
+    192,64,64,64,64,64,64,0,0,0,64,224,224,160,160,0,
+    0,0,192,160,160,160,160,0,0,0,64,160,160,160,64,0,
+    0,0,192,160,160,192,128,128,0,0,96,160,160,96,32,32,
+    0,0,160,192,128,128,128,0,0,0,96,128,64,32,192,0,
+    128,128,224,128,128,128,96,0,0,0,160,160,160,160,96,0,
+    0,0,160,160,160,160,64,0,0,0,160,160,224,224,64,0,
+    0,0,160,160,64,160,160,0,0,0,160,160,160,96,32,192,
+    0,0,224,32,64,128,224,0,32,64,64,128,64,64,32,0,
+    64,64,64,64,64,64,64,0,128,64,64,32,64,64,128,0,
+    80,160,0,0,0,0,0,0,0,0,64,160,160,160,224,0,
+    64,160,128,128,160,64,64,128,160,0,160,160,160,160,96,0,
+    32,64,64,160,224,128,96,0,64,160,192,32,96,160,96,0,
+    160,0,192,32,96,160,96,0,128,64,192,32,96,160,96,0,
+    64,0,192,32,96,160,96,0,0,0,96,128,128,96,64,128,
+    64,160,64,160,224,128,96,0,160,0,64,160,224,128,96,0,
+    128,64,64,160,224,128,96,0,160,0,192,64,64,64,64,0,
+    64,160,192,64,64,64,64,0,128,64,0,192,64,64,64,0,
+    160,0,64,160,224,160,160,0,64,160,64,160,224,160,160,0,
+    32,64,224,128,192,128,224,0,0,0,224,64,96,192,96,0,
+    96,192,192,224,192,192,224,0,64,160,64,160,160,160,64,0,
+    160,0,64,160,160,160,64,0,128,64,64,160,160,160,64,0,
+    64,160,0,160,160,160,96,0,128,64,160,160,160,160,96,0,
+    160,0,160,160,160,96,32,192,160,0,64,160,160,160,64,0,
+    160,0,160,160,160,160,64,0,64,64,96,128,128,96,64,64,
+    64,160,128,192,128,160,192,0,160,160,160,224,64,224,64,64,
+    128,192,192,160,160,224,160,160,32,64,64,224,64,64,128,0,
+    32,64,64,32,96,160,96,0,32,64,0,192,64,64,64,0,
+    32,64,64,160,160,160,64,0,32,64,160,160,160,160,96,0,
+    80,160,0,192,160,160,160,0,80,160,0,160,224,224,160,0,
+    96,160,160,96,0,224,1,0,64,160,160,64,0,224,0,0,
+    64,0,64,64,64,128,96,0,0,0,0,224,128,128,0,0,
+    0,0,0,224,32,32,0,0,160,32,32,64,128,160,160,0,
+    160,32,32,64,128,224,224,0,64,0,64,64,64,64,64,0,
+    0,0,96,192,96,0,0,0,0,0,192,96,192,0,0,0,
+    0,160,0,160,0,160,0,160,80,160,80,160,80,160,80,160,
+    80,240,80,240,80,240,80,240,64,64,64,64,64,64,64,64,
+    64,64,64,64,192,64,64,64,64,64,192,64,192,64,64,64,
+    96,96,96,96,224,96,96,96,0,0,0,0,224,96,96,96,
+    0,0,192,64,192,64,64,64,96,96,224,32,224,96,96,96,
+    96,96,96,96,96,96,96,96,0,0,224,32,224,96,96,96,
+    96,96,224,32,224,0,0,0,96,96,96,96,224,0,0,0,
+    64,64,192,64,192,0,0,0,0,0,0,0,192,64,64,64,
+    64,64,64,64,112,0,0,0,64,64,64,64,240,0,0,0,
+    0,0,0,0,240,64,64,64,64,64,64,64,112,64,64,64,
+    0,0,0,0,240,0,0,0,64,64,64,64,240,64,64,64,
+    64,64,112,64,112,64,64,64,96,96,96,96,112,96,96,96,
+    96,96,112,64,112,0,0,0,0,0,112,64,112,96,96,96,
+    96,96,240,0,240,0,0,0,0,0,240,0,240,96,96,96,
+    96,96,112,64,112,96,96,96,0,0,240,0,240,0,0,0,
+    96,96,240,0,240,96,96,96,64,64,240,0,240,0,0,0,
+    96,96,96,96,240,0,0,0,0,0,240,0,240,64,64,64,
+    0,0,0,0,240,96,96,96,96,96,96,96,112,0,0,0,
+    64,64,112,64,112,0,0,0,0,0,112,64,112,64,64,64,
+    0,0,0,0,112,96,96,96,96,96,96,96,240,96,96,96,
+    64,64,240,64,240,64,64,64,64,64,64,64,192,0,0,0,
+    0,0,0,0,112,64,64,64,240,240,240,240,240,240,240,240,
+    0,0,0,0,240,240,240,240,192,192,192,192,192,192,192,192,
+    48,48,48,48,48,48,48,48,240,240,240,240,0,0,0,0,
+    0,0,96,160,160,160,96,0,64,160,160,192,160,160,192,0,
+    224,160,128,128,128,128,128,0,0,0,224,160,160,160,160,0,
+    224,160,128,64,128,160,224,0,0,0,96,160,160,160,64,0,
+    0,0,160,160,160,160,192,128,0,80,160,64,64,64,64,0,
+    224,64,64,160,160,64,64,224,64,160,160,224,160,160,64,0,
+    64,160,160,224,64,64,224,0,32,64,64,96,160,160,64,0,
+    0,0,64,224,224,64,0,0,32,64,64,224,224,64,64,128,
+    96,128,128,224,128,128,97,0,0,64,160,160,160,160,160,0,
+    0,224,0,224,0,224,0,0,64,64,224,64,64,0,224,0,
+    128,64,32,64,128,0,224,0,32,64,128,64,32,0,224,0,
+    32,64,64,64,64,64,64,64,64,64,64,64,64,64,64,128,
+    0,64,0,224,0,64,0,0,0,80,160,0,80,160,0,0,
+    64,160,160,64,0,0,0,0,0,0,0,64,64,0,0,0,
+    0,0,0,64,0,0,0,0,48,32,32,32,32,160,96,32,
+    64,160,160,160,160,0,0,0,64,160,32,64,224,0,0,0,
+    0,0,96,96,96,96,0,0,0,0,0,0,0,0,0,0
+};
+
+struct fbcon_font_desc font_vtx_4x8 = {
+    VTX4x8_IDX,
+    "vtx4x8",
+    4,
+    8,
+    fontdata_4x8,
+    0
+};
diff -urN linux-2.4.29/drivers/video/font_vtx_6x8.c linux-2.4.29-uc1/drivers/video/font_vtx_6x8.c
--- linux-2.4.29/drivers/video/font_vtx_6x8.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/font_vtx_6x8.c	2005-06-14 02:12:27.000000000 +0100
@@ -0,0 +1,147 @@
+/********************/
+/* 6x8 console font */
+/********************/
+
+#include <video/font.h>
+
+#define FONTDATAMAX (8 * 256)
+
+static unsigned char fontdata_6x8[FONTDATAMAX] = {
+    0,0,0,0,0,0,0,0,120,132,204,132,132,180,132,120,
+    120,252,180,252,252,204,252,120,0,80,248,248,248,112,32,0,
+    0,32,112,248,248,112,32,0,0,112,32,248,168,32,112,0,
+    0,32,112,248,248,32,112,0,0,0,48,120,120,48,0,0,
+    252,252,204,132,132,204,252,252,0,48,72,72,72,72,48,0,
+    252,204,180,180,180,180,204,252,60,12,20,112,136,136,112,0,
+    112,136,136,112,32,248,32,0,60,36,60,32,32,96,224,192,
+    124,68,124,68,68,68,204,136,32,168,112,216,216,112,168,32,
+    128,224,240,248,240,224,128,0,8,56,120,248,120,56,8,0,
+    32,112,248,32,32,248,112,32,72,72,72,72,72,0,72,0,
+    124,164,164,100,36,36,36,0,120,132,112,72,72,56,132,120,
+    0,0,0,0,120,120,120,0,32,112,248,32,248,112,32,252,
+    32,112,248,32,32,32,32,0,32,32,32,32,248,112,32,0,
+    0,32,16,248,16,32,0,0,0,32,64,248,64,32,0,0,
+    0,0,192,192,192,248,0,0,0,0,72,252,72,0,0,0,
+    0,0,48,120,252,252,0,0,0,0,252,252,120,48,0,0,
+    0,0,0,0,0,0,0,0,32,32,32,32,32,0,32,0,
+    72,72,72,0,0,0,0,0,80,80,248,80,248,80,80,0,
+    32,120,160,112,40,240,32,0,0,136,144,32,72,136,0,0,
+    64,160,64,168,144,168,64,0,32,32,64,0,0,0,0,0,
+    16,32,64,64,64,32,16,0,64,32,16,16,16,32,64,0,
+    0,168,112,248,112,168,0,0,0,32,32,248,32,32,0,0,
+    0,0,0,0,0,32,32,64,0,0,0,120,0,0,0,0,
+    0,0,0,0,0,32,32,0,0,8,16,32,64,128,0,0,
+    112,136,152,168,200,136,112,0,16,48,80,16,16,16,16,0,
+    112,136,8,16,32,64,248,0,112,136,8,48,8,136,112,0,
+    16,48,80,144,248,16,16,0,248,128,240,8,8,136,112,0,
+    56,64,128,240,136,136,112,0,248,8,16,32,32,32,32,0,
+    112,136,136,112,136,136,112,0,112,136,136,120,8,16,224,0,
+    0,32,32,0,0,32,32,0,0,32,32,0,0,32,32,64,
+    8,16,32,64,32,16,8,0,0,0,120,0,0,120,0,0,
+    64,32,16,8,16,32,64,0,112,136,16,32,32,0,32,0,
+    112,136,136,152,152,128,112,0,112,136,136,248,136,136,136,0,
+    240,136,136,240,136,136,240,0,112,136,128,128,128,136,112,0,
+    240,136,136,136,136,136,240,0,248,128,128,240,128,128,248,0,
+    248,128,128,240,128,128,128,0,112,136,128,128,152,136,112,0,
+    136,136,136,248,136,136,136,0,112,32,32,32,32,32,112,0,
+    56,16,16,16,16,144,96,0,136,144,160,192,160,144,136,0,
+    128,128,128,128,128,128,248,0,136,216,168,168,136,136,136,0,
+    136,136,200,168,152,136,136,0,112,136,136,136,136,136,112,0,
+    240,136,136,240,128,128,128,0,112,136,136,136,136,144,104,0,
+    240,136,136,240,160,144,136,0,112,136,128,112,8,136,112,0,
+    248,32,32,32,32,32,32,0,136,136,136,136,136,136,112,0,
+    136,136,136,136,136,80,32,0,136,136,136,136,168,168,80,0,
+    136,136,80,32,80,136,136,0,136,136,80,32,32,32,32,0,
+    248,8,16,32,64,128,248,0,120,64,64,64,64,64,120,0,
+    0,128,64,32,16,8,0,0,120,8,8,8,8,8,120,0,
+    32,80,136,0,0,0,0,0,0,0,0,0,0,0,0,252,
+    64,32,16,0,0,0,0,0,0,0,112,8,120,136,120,0,
+    128,128,240,136,136,136,240,0,0,0,120,128,128,128,120,0,
+    8,8,120,136,136,136,120,0,0,0,112,136,248,128,120,0,
+    56,64,64,248,64,64,64,0,0,0,112,136,136,120,8,240,
+    128,128,240,136,136,136,136,0,32,0,96,32,32,32,32,0,
+    8,0,24,8,8,8,136,112,64,64,72,80,96,80,72,0,
+    96,32,32,32,32,32,32,0,0,0,208,168,168,168,168,0,
+    0,0,240,136,136,136,136,0,0,0,112,136,136,136,112,0,
+    0,0,240,136,136,240,128,128,0,0,120,136,136,120,8,8,
+    0,0,184,192,128,128,128,0,0,0,120,128,112,8,240,0,
+    64,64,248,64,64,64,56,0,0,0,136,136,136,136,120,0,
+    0,0,136,136,136,80,32,0,0,0,136,136,168,168,80,0,
+    0,0,136,80,32,80,136,0,0,0,136,136,136,120,8,240,
+    0,0,248,16,32,64,248,0,24,32,32,64,32,32,24,0,
+    32,32,32,32,32,32,32,0,96,16,16,8,16,16,96,0,
+    100,152,0,0,0,0,0,0,0,0,32,80,136,136,248,0,
+    112,136,128,128,136,112,16,96,136,0,136,136,136,136,120,0,
+    16,32,112,136,248,128,120,0,112,136,112,8,120,136,120,0,
+    80,0,112,8,120,136,120,0,64,32,112,8,120,136,120,0,
+    32,0,112,8,120,136,120,0,0,0,120,128,128,120,16,32,
+    112,136,112,136,248,128,120,0,80,0,112,136,248,128,120,0,
+    64,32,112,136,248,128,120,0,80,0,96,32,32,32,32,0,
+    112,136,96,32,32,32,32,0,64,32,0,96,32,32,32,0,
+    80,0,112,136,248,136,136,0,112,136,112,136,248,136,136,0,
+    16,32,248,128,240,128,248,0,0,0,248,32,120,160,120,0,
+    120,160,160,248,160,160,184,0,112,136,112,136,136,136,112,0,
+    80,0,112,136,136,136,112,0,64,32,112,136,136,136,112,0,
+    112,136,0,136,136,136,120,0,64,32,136,136,136,136,120,0,
+    80,0,136,136,136,120,8,240,80,0,32,80,136,80,32,0,
+    80,0,136,136,136,136,112,0,32,32,120,128,128,120,32,32,
+    32,80,64,224,64,72,240,0,136,136,80,248,32,248,32,32,
+    192,160,160,208,144,184,144,136,16,40,32,112,32,160,64,0,
+    16,32,112,8,120,136,120,0,16,32,0,96,32,32,32,0,
+    16,32,112,136,136,136,112,0,16,32,136,136,136,136,120,0,
+    100,152,0,240,136,136,136,0,100,152,0,200,168,152,136,0,
+    48,80,80,56,0,120,0,0,48,72,72,48,0,120,0,0,
+    32,0,32,32,64,136,112,0,0,0,0,248,128,128,0,0,
+    0,0,0,248,8,8,0,0,64,196,72,88,36,72,156,0,
+    64,196,72,84,44,92,132,0,32,0,32,32,32,32,32,0,
+    0,36,72,144,72,36,0,0,0,144,72,36,72,144,0,0,
+    72,144,72,144,72,144,72,144,84,168,84,168,84,168,84,168,
+    108,216,108,216,108,216,108,216,32,32,32,32,32,32,32,32,
+    32,32,32,32,224,32,32,32,32,32,224,32,224,32,32,32,
+    72,72,72,72,200,72,72,72,0,0,0,0,248,72,72,72,
+    0,0,224,32,224,32,32,32,72,72,200,8,200,72,72,72,
+    72,72,72,72,72,72,72,72,0,0,248,8,200,72,72,72,
+    72,72,200,8,248,0,0,0,72,72,72,72,248,0,0,0,
+    32,32,224,32,224,0,0,0,0,0,0,0,224,32,32,32,
+    32,32,32,32,60,0,0,0,32,32,32,32,252,0,0,0,
+    0,0,0,0,252,32,32,32,32,32,32,32,60,32,32,32,
+    0,0,0,0,252,0,0,0,32,32,32,32,252,32,32,32,
+    32,32,60,32,60,32,32,32,72,72,72,72,76,72,72,72,
+    72,72,76,64,124,0,0,0,0,0,124,64,76,72,72,72,
+    72,72,204,0,252,0,0,0,0,0,252,0,204,72,72,72,
+    72,72,76,64,76,72,72,74,0,0,252,0,252,0,0,0,
+    72,72,204,0,204,72,72,72,32,32,252,0,252,0,0,0,
+    72,72,72,72,252,0,0,0,0,0,252,0,252,32,32,32,
+    0,0,0,0,252,72,72,72,72,72,72,72,124,0,0,0,
+    32,32,60,32,60,0,0,0,0,0,60,32,60,32,32,32,
+    0,0,0,0,124,72,72,72,72,72,72,72,252,72,72,72,
+    32,32,252,32,252,32,32,32,32,32,32,32,224,0,0,0,
+    0,0,0,0,60,32,32,32,252,252,252,252,252,252,252,252,
+    0,0,0,0,252,252,252,252,224,224,224,224,224,224,224,224,
+    28,28,28,28,28,28,28,28,252,252,252,252,0,0,0,0,
+    0,0,104,144,144,144,104,0,96,144,144,160,144,136,144,0,
+    248,136,128,128,128,128,128,0,0,0,248,80,80,80,80,0,
+    248,136,64,32,64,136,248,0,0,0,120,144,144,144,96,0,
+    0,0,72,72,72,72,112,128,0,72,176,32,32,32,32,0,
+    248,32,112,136,136,112,32,248,32,80,136,248,136,80,32,0,
+    112,136,136,216,80,80,216,0,24,32,16,56,72,72,48,0,
+    0,0,80,168,168,80,0,0,8,16,112,168,168,112,64,128,
+    56,64,128,248,128,64,56,0,0,112,136,136,136,136,136,0,
+    0,248,0,248,0,248,0,0,32,32,248,32,32,0,248,0,
+    32,16,8,16,32,0,120,0,8,16,32,16,8,0,120,0,
+    16,40,40,32,32,32,32,32,32,32,32,32,32,160,160,64,
+    0,32,0,248,0,32,0,0,0,100,152,0,100,152,0,0,
+    48,72,72,48,0,0,0,0,0,0,0,32,32,0,0,0,
+    0,0,0,32,0,0,0,0,28,16,16,16,144,80,48,16,
+    176,72,72,72,72,0,0,0,48,72,16,32,120,0,0,0,
+    0,0,120,120,120,120,0,0,0,0,0,0,0,0,0,0
+};
+
+struct fbcon_font_desc font_vtx_6x8 = {
+    VTX6x8_IDX,
+    "vtx6x8",
+    6,
+    8,
+    fontdata_6x8,
+    0
+};
diff -urN linux-2.4.29/drivers/video/Makefile linux-2.4.29-uc1/drivers/video/Makefile
--- linux-2.4.29/drivers/video/Makefile	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/drivers/video/Makefile	2005-06-14 02:12:26.000000000 +0100
@@ -14,7 +14,7 @@
 		  fbcon-vga.o fbcon-iplan2p2.o fbcon-iplan2p4.o \
 		  fbcon-iplan2p8.o fbcon-vga-planes.o fbcon-cfb16.o \
 		  fbcon-cfb2.o fbcon-cfb24.o fbcon-cfb32.o fbcon-cfb4.o \
-		  fbcon-cfb8.o fbcon-mac.o fbcon-mfb.o \
+		  fbcon-cfb8.o fbcon-mac.o fbcon-mfb.o fbcon-cfb12.o \
 		  cyber2000fb.o sa1100fb.o fbcon-hga.o fbgen.o
 
 # Each configuration option enables a list of files.
@@ -32,6 +32,8 @@
 obj-$(CONFIG_FONT_6x11)           += font_6x11.o
 obj-$(CONFIG_FONT_PEARL_8x8)      += font_pearl_8x8.o
 obj-$(CONFIG_FONT_ACORN_8x8)      += font_acorn_8x8.o
+obj-$(CONFIG_FONT_VTX_6x8)        += font_vtx_6x8.o
+obj-$(CONFIG_FONT_VTX_4x8)        += font_vtx_4x8.o
 
 # Add fbmon.o back into obj-$(CONFIG_FB) in 2.5.x
 obj-$(CONFIG_FB)                  += fbmem.o fbcmap.o modedb.o fbcon.o fonts.o
@@ -40,6 +42,8 @@
 obj-$(CONFIG_PPC)                 += macmodes.o
 endif
 
+obj-$(CONFIG_FB_IPOD)             += fbgen.o
+obj-$(CONFIG_FB_EP93XX)           += ep93xxfb.o
 obj-$(CONFIG_FB_ACORN)            += acornfb.o
 obj-$(CONFIG_FB_AMIGA)            += amifb.o
 obj-$(CONFIG_FB_PM2)              += pm2fb.o fbgen.o
@@ -55,6 +59,8 @@
 obj-$(CONFIG_FB_PLATINUM)         += platinumfb.o
 obj-$(CONFIG_FB_VALKYRIE)         += valkyriefb.o
 obj-$(CONFIG_FB_CT65550)          += chipsfb.o
+obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o
+obj-$(CONFIG_FB_EDB7312)          += edb7312fb.o
 obj-$(CONFIG_FB_CYBER)            += cyberfb.o
 obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
 obj-$(CONFIG_FB_SGIVW)            += sgivwfb.o
@@ -85,8 +91,10 @@
 obj-$(CONFIG_FB_PMAG_BA)          += pmag-ba-fb.o
 obj-$(CONFIG_FB_PMAGB_B)          += pmagb-b-fb.o
 obj-$(CONFIG_FB_MAXINE)           += maxinefb.o
+obj-$(CONFIG_FB_EP93XX)		  += ep93xxfb.o
 obj-$(CONFIG_FB_TX3912)           += tx3912fb.o
 obj-$(CONFIG_FB_AU1100)		  += au1100fb.o fbgen.o
+obj-$(CONFIG_FB_S3C44B0X)	  += s3c44b0xfb.o fbgen.o
 obj-$(CONFIG_FB_IT8181)		  += it8181fb.o fbgen.o
 
 subdir-$(CONFIG_STI_CONSOLE)      += sti
@@ -128,12 +136,26 @@
 obj-$(CONFIG_FB_BWTWO)            += bwtwofb.o
 obj-$(CONFIG_FB_HGA)              += hgafb.o  
 obj-$(CONFIG_FB_SA1100)           += sa1100fb.o
+obj-$(CONFIG_FB_DRAGON)           += dragonfb.o
+obj-$(CONFIG_FB_XILINX)           += xilinxfb.o fbgen.o
 obj-$(CONFIG_FB_VIRTUAL)          += vfb.o  
+obj-$(CONFIG_FB_VIRTUAL_SMALL)    += vfb_small.o
 obj-$(CONFIG_FB_HIT)              += hitfb.o fbgen.o
 obj-$(CONFIG_FB_E1355)            += epson1355fb.o fbgen.o
+obj-$(CONFIG_FB_MQ200)            += mq200fb.o fbgen.o
 obj-$(CONFIG_FB_E1356)            += epson1356fb.o
 obj-$(CONFIG_FB_PVR2)             += pvr2fb.o
 obj-$(CONFIG_FB_VOODOO1)          += sstfb.o
+obj-$(CONFIG_FB_MC68X328)         += mc68x328fb.o
+obj-$(CONFIG_FB_MQ1100)           += mq1100.o fbgen.o
+
+# ATTENTION! The implementation of the driver for the EPSON S1D13706
+# on uClinux is _really_ experimental, currently! Be warned!
+ifeq ($(CONFIG_FB_COBRA5272),y)
+obj-$(CONFIG_FB_S1D13706)         += s1d13706fb.o fbgen.o
+obj-$(CONFIG_FB_S1D13806)         += s1d13806fb.o fbgen.o
+endif
+
 
 # Generic Low Level Drivers
 
@@ -141,6 +163,7 @@
 obj-$(CONFIG_FBCON_CFB2)          += fbcon-cfb2.o
 obj-$(CONFIG_FBCON_CFB4)          += fbcon-cfb4.o
 obj-$(CONFIG_FBCON_CFB8)          += fbcon-cfb8.o
+obj-$(CONFIG_FBCON_CFB12)         += fbcon-cfb12.o
 obj-$(CONFIG_FBCON_CFB16)         += fbcon-cfb16.o
 obj-$(CONFIG_FBCON_CFB24)         += fbcon-cfb24.o
 obj-$(CONFIG_FBCON_CFB32)         += fbcon-cfb32.o
diff -urN linux-2.4.29/drivers/video/mc68x328fb.c linux-2.4.29-uc1/drivers/video/mc68x328fb.c
--- linux-2.4.29/drivers/video/mc68x328fb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/mc68x328fb.c	2005-06-14 02:12:26.000000000 +0100
@@ -0,0 +1,634 @@
+/*
+ *  linux/drivers/video/mc68x328fb.c -- DragonBall frame buffer device
+ *
+ *	Copyright (C) 2003 Georges Menie
+ *
+ *  Support for the built in MC68x328 LCD Controller
+ *
+ *  This driver assumes an already configured controller (e.g. from crt0_fixed.s)
+ *  Keep the code clean of board specific initialization.
+ *
+ *  This code has not been tested with colors, colormap management functions
+ *  are minimal (no colormap data written to the 68328 registers...)
+ *
+ *  modified from :
+ *
+ *    linux/drivers/video/vfb.c -- Virtual frame buffer device
+ *	  Copyright (C) 1997 Geert Uytterhoeven
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <asm/uaccess.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-mfb.h>
+#include <video/fbcon-cfb2.h>
+#include <video/fbcon-cfb4.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb24.h>
+#include <video/fbcon-cfb32.h>
+
+#if defined(CONFIG_M68EZ328)
+#include <asm/MC68EZ328.h>
+#elif defined(CONFIG_M68VZ328)
+#include <asm/MC68VZ328.h>
+#else
+#error wrong architecture for the MC68x328 Framebuffer Device
+#endif
+
+#if defined(CONFIG_FB_MC68X328_MONO01)
+#define MC68X328FB_MONO_VISUAL FB_VISUAL_MONO01
+#else
+#define MC68X328FB_MONO_VISUAL FB_VISUAL_MONO10
+#endif
+
+static u_long videomemory, videomemorysize;
+static int currcon = 0;
+static struct display disp;
+static struct fb_info fb_info;
+static struct { u_char red, green, blue, pad; } palette[256];
+static union {
+#ifdef FBCON_HAS_CFB16
+    u16 cfb16[16];
+#endif
+#ifdef FBCON_HAS_CFB24
+    u32 cfb24[16];
+#endif
+#ifdef FBCON_HAS_CFB32
+    u32 cfb32[16];
+#endif
+} fbcon_cmap;
+static char mc68x328fb_name[16] = "DragonBall";
+
+static struct fb_var_screeninfo mc68x328fb_default = {
+    0, 0, 0, 0, 0, 0, 0, 0, /* some value are set by mc68x328fb_init() */
+    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+    0, 0, -1, -1, 0, 20000, 64, 64, 32, 32, 64, 2,
+    0, FB_VMODE_NONINTERLACED
+};
+
+
+    /*
+     *  Interface used by the world
+     */
+
+int mc68x328fb_setup(char*);
+
+static int mc68x328fb_get_fix(struct fb_fix_screeninfo *fix, int con,
+		       struct fb_info *info);
+static int mc68x328fb_get_var(struct fb_var_screeninfo *var, int con,
+		       struct fb_info *info);
+static int mc68x328fb_set_var(struct fb_var_screeninfo *var, int con,
+		       struct fb_info *info);
+static int mc68x328fb_pan_display(struct fb_var_screeninfo *var, int con,
+			   struct fb_info *info);
+static int mc68x328fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info);
+static int mc68x328fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info);
+
+
+    /*
+     *  Interface to the low level console driver
+     */
+
+int mc68x328fb_init(void);
+static int vfbcon_switch(int con, struct fb_info *info);
+static int vfbcon_updatevar(int con, struct fb_info *info);
+static void vfbcon_blank(int blank, struct fb_info *info);
+
+
+    /*
+     *  Internal routines
+     */
+
+static u_long get_line_length(int xres_virtual, int bpp);
+static void mc68x328fb_encode_fix(struct fb_fix_screeninfo *fix,
+			   struct fb_var_screeninfo *var);
+static void set_color_bitfields(struct fb_var_screeninfo *var);
+static int mc68x328fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                         u_int *transp, struct fb_info *info);
+static int mc68x328fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp, struct fb_info *info);
+static void do_install_cmap(int con, struct fb_info *info);
+
+
+static struct fb_ops mc68x328fb_ops = {
+	owner:		THIS_MODULE,
+	fb_get_fix:	mc68x328fb_get_fix,
+	fb_get_var:	mc68x328fb_get_var,
+	fb_set_var:	mc68x328fb_set_var,
+	fb_get_cmap:	mc68x328fb_get_cmap,
+	fb_set_cmap:	mc68x328fb_set_cmap,
+	fb_pan_display:	mc68x328fb_pan_display,
+};
+
+    /*
+     *  Get the Fixed Part of the Display
+     */
+
+static int mc68x328fb_get_fix(struct fb_fix_screeninfo *fix, int con,
+		       struct fb_info *info)
+{
+    struct fb_var_screeninfo *var;
+
+    if (con == -1)
+	var = &mc68x328fb_default;
+    else
+	var = &fb_display[con].var;
+    mc68x328fb_encode_fix(fix, var);
+    return 0;
+}
+
+
+    /*
+     *  Get the User Defined Part of the Display
+     */
+
+static int mc68x328fb_get_var(struct fb_var_screeninfo *var, int con,
+		       struct fb_info *info)
+{
+    if (con == -1)
+	*var = mc68x328fb_default;
+    else
+	*var = fb_display[con].var;
+    set_color_bitfields(var);
+    return 0;
+}
+
+
+    /*
+     *  Set the User Defined Part of the Display
+     */
+
+static int mc68x328fb_set_var(struct fb_var_screeninfo *var, int con,
+		       struct fb_info *info)
+{
+    int err, activate = var->activate;
+    int oldxres, oldyres, oldvxres, oldvyres, oldbpp;
+    u_long line_length;
+
+    struct display *display;
+    if (con >= 0)
+	display = &fb_display[con];
+    else
+	display = &disp;	/* used during initialization */
+
+    /*
+     *  FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
+     *  as FB_VMODE_SMOOTH_XPAN is only used internally
+     */
+
+    if (var->vmode & FB_VMODE_CONUPDATE) {
+	var->vmode |= FB_VMODE_YWRAP;
+	var->xoffset = display->var.xoffset;
+	var->yoffset = display->var.yoffset;
+    }
+
+    /*
+     *  Some very basic checks
+     */
+    if (!var->xres)
+	var->xres = 1;
+    if (!var->yres)
+	var->yres = 1;
+    if (var->xres > var->xres_virtual)
+	var->xres_virtual = var->xres;
+    if (var->yres > var->yres_virtual)
+	var->yres_virtual = var->yres;
+    if (var->bits_per_pixel <= 1)
+	var->bits_per_pixel = 1;
+    else if (var->bits_per_pixel <= 8)
+	var->bits_per_pixel = 8;
+    else if (var->bits_per_pixel <= 16)
+	var->bits_per_pixel = 16;
+#if 0
+    /* fbcon doesn't support this (yet) */
+    else if (var->bits_per_pixel <= 24)
+	var->bits_per_pixel = 24;
+    else if (var->bits_per_pixel <= 32)
+	var->bits_per_pixel = 32;
+#endif
+    else
+	return -EINVAL;
+
+    /*
+     *  Memory limit
+     */
+    line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
+    if (line_length*var->yres_virtual > videomemorysize)
+	return -ENOMEM;
+
+    set_color_bitfields(var);
+
+    if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+	oldxres = display->var.xres;
+	oldyres = display->var.yres;
+	oldvxres = display->var.xres_virtual;
+	oldvyres = display->var.yres_virtual;
+	oldbpp = display->var.bits_per_pixel;
+	display->var = *var;
+	if (oldxres != var->xres || oldyres != var->yres ||
+	    oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
+	    oldbpp != var->bits_per_pixel) {
+	    struct fb_fix_screeninfo fix;
+
+	    mc68x328fb_encode_fix(&fix, var);
+	    display->screen_base = (char *)videomemory;
+	    display->visual = fix.visual;
+	    display->type = fix.type;
+	    display->type_aux = fix.type_aux;
+	    display->ypanstep = fix.ypanstep;
+	    display->ywrapstep = fix.ywrapstep;
+	    display->line_length = fix.line_length;
+	    display->can_soft_blank = 1;
+	    display->inverse = 0;
+	    switch (var->bits_per_pixel) {
+#ifdef FBCON_HAS_MFB
+		case 1:
+		    display->dispsw = &fbcon_mfb;
+		    break;
+#endif
+#ifdef FBCON_HAS_CFB2
+		case 2:
+		    display->dispsw = &fbcon_cfb2;
+		    break;
+#endif
+#ifdef FBCON_HAS_CFB4
+		case 4:
+		    display->dispsw = &fbcon_cfb4;
+		    break;
+#endif
+#ifdef FBCON_HAS_CFB8
+		case 8:
+		    display->dispsw = &fbcon_cfb8;
+		    break;
+#endif
+#ifdef FBCON_HAS_CFB16
+		case 16:
+		    display->dispsw = &fbcon_cfb16;
+		    display->dispsw_data = fbcon_cmap.cfb16;
+		    break;
+#endif
+#ifdef FBCON_HAS_CFB24
+		case 24:
+		    display->dispsw = &fbcon_cfb24;
+		    display->dispsw_data = fbcon_cmap.cfb24;
+		    break;
+#endif
+#ifdef FBCON_HAS_CFB32
+		case 32:
+		    display->dispsw = &fbcon_cfb32;
+		    display->dispsw_data = fbcon_cmap.cfb32;
+		    break;
+#endif
+		default:
+		    display->dispsw = &fbcon_dummy;
+		    break;
+	    }
+	    if (fb_info.changevar)
+		(*fb_info.changevar)(con);
+	}
+	if (oldbpp != var->bits_per_pixel) {
+	    if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+		return err;
+	    do_install_cmap(con, info);
+	}
+    }
+    return 0;
+}
+
+
+    /*
+     *  Pan or Wrap the Display
+     *
+     *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+     */
+
+static int mc68x328fb_pan_display(struct fb_var_screeninfo *var, int con,
+			   struct fb_info *info)
+{
+    if (var->vmode & FB_VMODE_YWRAP) {
+	if (var->yoffset < 0 ||
+	    var->yoffset >= fb_display[con].var.yres_virtual ||
+	    var->xoffset)
+	    return -EINVAL;
+    } else {
+	if (var->xoffset+fb_display[con].var.xres >
+	    fb_display[con].var.xres_virtual ||
+	    var->yoffset+fb_display[con].var.yres >
+	    fb_display[con].var.yres_virtual)
+	    return -EINVAL;
+    }
+    fb_display[con].var.xoffset = var->xoffset;
+    fb_display[con].var.yoffset = var->yoffset;
+    if (var->vmode & FB_VMODE_YWRAP)
+	fb_display[con].var.vmode |= FB_VMODE_YWRAP;
+    else
+	fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
+    return 0;
+}
+
+    /*
+     *  Get the Colormap
+     */
+
+static int mc68x328fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info)
+{
+    if (con == currcon) /* current console? */
+	return fb_get_cmap(cmap, kspc, mc68x328fb_getcolreg, info);
+    else if (fb_display[con].cmap.len) /* non default colormap? */
+	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+    else
+	fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+		     cmap, kspc ? 0 : 2);
+    return 0;
+}
+
+    /*
+     *  Set the Colormap
+     */
+
+static int mc68x328fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info)
+{
+    int err;
+
+    if (!fb_display[con].cmap.len) {	/* no colormap allocated? */
+	if ((err = fb_alloc_cmap(&fb_display[con].cmap,
+			      1<<fb_display[con].var.bits_per_pixel, 0)))
+	    return err;
+    }
+    if (con == currcon)			/* current console? */
+	return fb_set_cmap(cmap, kspc, mc68x328fb_setcolreg, info);
+    else
+	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+    return 0;
+}
+
+
+int __init mc68x328fb_setup(char *options)
+{
+    char *this_opt;
+
+    fb_info.fontname[0] = '\0';
+
+    if (!options || !*options)
+	return 0;
+
+    while ((this_opt = strsep(&options, ",")) != NULL) {
+	if (!strncmp(this_opt, "font:", 5))
+	    strcpy(fb_info.fontname, this_opt+5);
+    }
+    return 0;
+}
+
+
+    /*
+     *  Initialisation
+     */
+
+int __init mc68x328fb_init(void)
+{
+	/*
+	 *  initialize the default mode from the LCD controller registers
+	 */
+	mc68x328fb_default.xres = LXMAX;
+	mc68x328fb_default.yres = LYMAX+1;
+	mc68x328fb_default.xres_virtual = mc68x328fb_default.xres;
+	mc68x328fb_default.yres_virtual = mc68x328fb_default.yres;
+	mc68x328fb_default.bits_per_pixel = 1 + (LPICF & 0x01);
+	videomemory = LSSA;
+	videomemorysize = (mc68x328fb_default.xres+7) / 8 *
+		mc68x328fb_default.yres * mc68x328fb_default.bits_per_pixel;
+
+    strcpy(fb_info.modename, mc68x328fb_name);
+    fb_info.changevar = NULL;
+    fb_info.node = -1;
+    fb_info.fbops = &mc68x328fb_ops;
+    fb_info.disp = &disp;
+    fb_info.switch_con = &vfbcon_switch;
+    fb_info.updatevar = &vfbcon_updatevar;
+    fb_info.blank = &vfbcon_blank;
+    fb_info.flags = FBINFO_FLAG_DEFAULT;
+
+    mc68x328fb_set_var(&mc68x328fb_default, -1, &fb_info);
+
+    if (register_framebuffer(&fb_info) < 0) {
+	return -EINVAL;
+    }
+
+    printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.node),
+		mc68x328fb_name);
+	printk(KERN_INFO "fb%d: %dx%dx%d at 0x%08lx\n", GET_FB_IDX(fb_info.node),
+		mc68x328fb_default.xres, mc68x328fb_default.yres,
+		1 << mc68x328fb_default.bits_per_pixel, videomemory);
+    return 0;
+}
+
+
+static int vfbcon_switch(int con, struct fb_info *info)
+{
+    /* Do we have to save the colormap? */
+    if (fb_display[currcon].cmap.len)
+	fb_get_cmap(&fb_display[currcon].cmap, 1, mc68x328fb_getcolreg, info);
+
+    currcon = con;
+    /* Install new colormap */
+    do_install_cmap(con, info);
+    return 0;
+}
+
+    /*
+     *  Update the `var' structure (called by fbcon.c)
+     */
+
+static int vfbcon_updatevar(int con, struct fb_info *info)
+{
+    /* Nothing */
+    return 0;
+}
+
+    /*
+     *  Blank the display.
+     */
+
+static void vfbcon_blank(int blank, struct fb_info *info)
+{
+    /* Nothing */
+}
+
+static u_long get_line_length(int xres_virtual, int bpp)
+{
+    u_long length;
+    
+    length = xres_virtual*bpp;
+    length = (length+31)&-32;
+    length >>= 3;
+    return(length);
+}
+
+static void mc68x328fb_encode_fix(struct fb_fix_screeninfo *fix,
+			   struct fb_var_screeninfo *var)
+{
+    memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+    strcpy(fix->id, mc68x328fb_name);
+    fix->smem_start = videomemory;
+    fix->smem_len = videomemorysize;
+    fix->type = FB_TYPE_PACKED_PIXELS;
+    fix->type_aux = 0;
+    switch (var->bits_per_pixel) {
+	case 1:
+	    fix->visual = MC68X328FB_MONO_VISUAL;
+	    break;
+	case 2:
+	case 4:
+	case 8:
+	    fix->visual = FB_VISUAL_PSEUDOCOLOR;
+	    break;
+	case 16:
+	case 24:
+	case 32:
+	    fix->visual = FB_VISUAL_TRUECOLOR;
+	    break;
+    }
+    fix->ywrapstep = 1;
+    fix->xpanstep = 1;
+    fix->ypanstep = 1;
+    fix->line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
+}
+
+static void set_color_bitfields(struct fb_var_screeninfo *var)
+{
+    switch (var->bits_per_pixel) {
+	case 1:
+	case 8:
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 0;
+	    var->green.length = 8;
+	    var->blue.offset = 0;
+	    var->blue.length = 8;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 16:	/* RGB 565 */
+	    var->red.offset = 0;
+	    var->red.length = 5;
+	    var->green.offset = 5;
+	    var->green.length = 6;
+	    var->blue.offset = 11;
+	    var->blue.length = 5;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 24:	/* RGB 888 */
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 8;
+	    var->green.length = 8;
+	    var->blue.offset = 16;
+	    var->blue.length = 8;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 32:	/* RGBA 8888 */
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 8;
+	    var->green.length = 8;
+	    var->blue.offset = 16;
+	    var->blue.length = 8;
+	    var->transp.offset = 24;
+	    var->transp.length = 8;
+	    break;
+    }
+    var->red.msb_right = 0;
+    var->green.msb_right = 0;
+    var->blue.msb_right = 0;
+    var->transp.msb_right = 0;
+}
+
+
+    /*
+     *  Read a single color register and split it into
+     *  colors/transparent. Return != 0 for invalid regno.
+     */
+
+static int mc68x328fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                         u_int *transp, struct fb_info *info)
+{
+    if (regno > 255)
+	return 1;
+    *red = (palette[regno].red<<8) | palette[regno].red;
+    *green = (palette[regno].green<<8) | palette[regno].green;
+    *blue = (palette[regno].blue<<8) | palette[regno].blue;
+    *transp = 0;
+    return 0;
+}
+
+
+    /*
+     *  Set a single color register. The values supplied are already
+     *  rounded down to the hardware's capabilities (according to the
+     *  entries in the var structure). Return != 0 for invalid regno.
+     */
+
+static int mc68x328fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp, struct fb_info *info)
+{
+    if (regno > 255)
+	return 1;
+    red >>= 8;
+    green >>= 8;
+    blue >>= 8;
+    palette[regno].red = red;
+    palette[regno].green = green;
+    palette[regno].blue = blue;
+    return 0;
+}
+
+
+static void do_install_cmap(int con, struct fb_info *info)
+{
+    if (con != currcon)
+	return;
+    if (fb_display[con].cmap.len)
+	fb_set_cmap(&fb_display[con].cmap, 1, mc68x328fb_setcolreg, info);
+    else
+	fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), 1,
+		    mc68x328fb_setcolreg, info);
+}
+
+
+#ifdef MODULE
+MODULE_LICENSE("GPL");
+
+int init_module(void)
+{
+    return mc68x328fb_init();
+}
+
+void cleanup_module(void)
+{
+    unregister_framebuffer(&fb_info);
+}
+
+#endif /* MODULE */
diff -urN linux-2.4.29/drivers/video/mq1100.c linux-2.4.29-uc1/drivers/video/mq1100.c
--- linux-2.4.29/drivers/video/mq1100.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/mq1100.c	2005-06-14 02:12:27.000000000 +0100
@@ -0,0 +1,716 @@
+/*
+ * linux/drivers/video/mq1100fb.c -- Framebuffer driver for MediaQ 1100 controller
+ *
+ * The driver will work with Sony Clie (Dragonball-based PalmOS handheld) LCD panel
+ * screen. Initially no hardware cursor support. No support for changing real screen
+ * resolution (no point with LCD). No accelerated features support.
+ *
+ * Created 08/2004 by Anton Solovyev, anton@solovyev.com
+ *
+ * based on:
+ *
+ * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
+ *
+ *  Created 28 Dec 1997 by Geert Uytterhoeven
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-mfb.h>
+#include <video/fbcon-cfb2.h>
+#include <video/fbcon-cfb4.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+ 
+#if defined(CONFIG_M68EZ328)
+#include <asm/MC68EZ328.h>
+#elif defined(CONFIG_M68VZ328)
+#include <asm/MC68VZ328.h>
+#else
+#error Wrong architecture!
+#endif
+
+/* Make noise on the console */
+/* #define MQ1100_DEBUG 1 */
+#undef MQ1100_DEBUG
+#ifdef MQ1100_DEBUG
+#define DPRINTK(fmt, args...) printk(KERN_INFO "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+/* Register addresses */
+#define MQ1100_BASE (0x1F000000)
+#define MQ1100_REG_BASE (MQ1100_BASE + 0x40000)
+#define MQ1100_GC_CONTROL_REG (MQ1100_REG_BASE + 0x180)
+#define MQ1100_GC_WINDOW_START_REG (MQ1100_REG_BASE + 0x1B0)
+#define MQ1100_GC_WINDOW_STRIDE_REG (MQ1100_REG_BASE + 0x1B8)
+#define MQ1100_GC_HOR_WINDOW_CONTROL_REG (MQ1100_REG_BASE + 0x1A0)
+#define MQ1100_GC_VER_WINDOW_CONTROL_REG (MQ1100_REG_BASE + 0x1A4)
+#define MQ1100_GC_PALETTE_REG(x) (MQ1100_REG_BASE + 0x800 + (x) * 4)
+/* The horrible world of bitmasks */
+#define MQ1100_GC_ENABLE_IMAGE_WINDOW_MASK (1 << 3)
+#define MQ1100_GC_COLOR_DEPTH_MASK (0xF << 4)
+#define MQ1100_GC_ENABLE_HW_CURSOR_MASK (1 << 8)
+#define MQ1100_GC_DOUBLE_BUFFER_CONTROL_MASK (3 << 10)
+#define MQ1100_GC_HOR_DOUBLING_MASK (1 << 14)
+#define MQ1100_GC_VER_DOUBLING_MASK (1 << 15)
+#define MQ1100_GC_RED_MASK (0x3F << 2)
+#define MQ1100_GC_GREEN_MASK (0x3F << 10)
+#define MQ1100_GC_BLUE_MASK (0x3F << 18)
+#define MQ1100_GC_GRAY_HI_MASK (3 << 14)
+#define MQ1100_GC_GRAY_LO_MASK (0x3F << 18)
+#define MQ1100_GC_WINDOW_START_MASK (0x3FFFF << 0)
+#define MQ1100_GC_WINDOW_STRIDE_MASK (0xFFFF << 0)
+#define MQ1100_GC_HOR_WINDOW_START_MASK (0x7FF)
+#define MQ1100_GC_HOR_WINDOW_WIDTH_MASK (0x7FF << 16)
+#define MQ1100_GC_VER_WINDOW_START_MASK (0x3FF << 0)
+#define MQ1100_GC_VER_WINDOW_WIDTH_MASK (0x3FF << 16)
+/* Constants */
+#define MQ1100_GC_SINGLE_PIX 0
+#define MQ1100_GC_MAIN_WIN_ACIVE 0
+#define MQ1100_GC_1BPP_COLOR 0
+#define MQ1100_GC_2BPP_COLOR 1
+#define MQ1100_GC_4BPP_COLOR 2
+#define MQ1100_GC_8BPP_COLOR 3
+#define MQ1100_GC_16BPP_COLOR 0x0C
+#define MQ1100_GC_1BPP_GRAY 0x08
+#define MQ1100_GC_2BPP_GRAY 0x09
+#define MQ1100_GC_4BPP_GRAY 0x0A
+#define MQ1100_GC_8BPP_GRAY 0x0B
+/* Misc constants */
+#define MQ1100_GC_VIDEOMEM_BASE (MQ1100_BASE)
+#define MQ1100_GC_VIDEOMEM_SIZE (256 * 1024)
+#define HRES 320
+#define VRES 320
+
+/*
+*    MQ1100 FB Info
+*/
+struct mq1100fb_info
+{
+	struct fb_info_gen	gen;
+};
+
+/*
+ *  The hardware specific data in this structure uniquely defines a video
+ *  mode.
+ */
+struct mq1100fb_par
+{
+	u32	bpp;
+	u32	grayscale;
+	u32	xres_virtual;
+	u32	yres_virtual;
+	u32	xoffset;
+	u32	yoffset;
+};
+
+static struct mq1100fb_info fb_info;
+static struct mq1100fb_par current_par, default_par = {8, 0, HRES, VRES, 0, 0};
+static int current_par_valid = 0;
+static struct display disp;
+static union
+{
+#ifdef FBCON_HAS_CFB16
+	u16 cfb16[16];
+#endif
+} fbcon_cmap;
+
+/* ------------ Hardware Dependent Functions ------------ */
+
+/*
+ * Change byte order
+ */
+static inline u32 swapbytes(u32 val)
+{
+	return (((val & 0xFF000000) >> 24) | ((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8) | ((val & 0x000000FF) << 24));
+}
+
+/*
+ *  Write a GC register. We get a chance to insert a debug printk and swap bytes
+ */
+static inline void writereg(u32 reg, u32 val)
+{
+	DPRINTK("reg: %lX, val: %lX\n", (unsigned long) reg, (unsigned long) val);
+	*((volatile u32*) reg) = swapbytes(val);
+}
+
+/*
+ *  Read a GC register. We get a chance to insert a debug printk and swap bytes
+ */
+static inline u32 readreg(u32 reg)
+{
+	u32 val;
+
+	val = swapbytes(*((volatile u32*) reg));
+	DPRINTK("readreg(): reg: %lX val: %lX\n", (unsigned long) reg, (unsigned long) val);
+	return val;
+}
+
+/*
+ * Count trailing zeros
+ */
+static inline int countz(u32 val)
+{
+	int i;
+	for(i = 0; i < 32; i++)
+                if(val & (1 << i)) break;
+        return i;
+}
+
+/*
+ * Get bits with given mask
+ */
+static inline u32 getbits(u32 value, u32 mask)
+{
+	return (value & mask) >> (countz(mask));
+}
+
+/*
+ * Set bits with given mask
+ */
+static inline u32 setbits(u32 value, u32 mask, u32 setto)
+{
+	return (value & ~mask) | (setto << countz(mask));
+}
+
+/*
+ *  This function should fill in the 'fix' structure based on the values
+ *  in the `par' structure.
+ */
+static int mq1100_encode_fix(struct fb_fix_screeninfo* fix, const void* fb_par, struct fb_info_gen* info)
+{
+	struct mq1100fb_par *par = (struct mq1100fb_par*) fb_par;
+	DPRINTK("enter\n");
+
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+	strcpy(fix->id, "MediaQ 1100");
+	fix->smem_start = MQ1100_GC_VIDEOMEM_BASE;
+	fix->smem_len = MQ1100_GC_VIDEOMEM_SIZE;
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->type_aux = 0;
+	if(par->bpp == 16)
+	{
+		fix->visual = FB_VISUAL_TRUECOLOR;
+	}
+	else
+	{
+		fix->visual = FB_VISUAL_PSEUDOCOLOR;
+	}
+	fix->xpanstep = fix->ypanstep = (par->bpp <= 8) ? (8 / par->bpp) : 1;
+	fix->ywrapstep = 0;
+	fix->line_length = par->bpp * par->xres_virtual / 8;
+	fix->mmio_start = 0;
+	fix->mmio_len = 0;
+        fix->accel = FB_ACCEL_NONE;
+	
+	DPRINTK("exit\n");
+	return 0;
+}
+
+/*
+ *  Get the video params out of 'var'. If a value doesn't fit, round it up,
+ *  if it's too big, return -EINVAL.
+ *
+ *  Suggestion: Round up in the following order: bits_per_pixel, xres,
+ *  yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
+ *  bitfields, horizontal timing, vertical timing.
+ */
+static int mq1100_decode_var(const struct fb_var_screeninfo* var, void* fb_par, struct fb_info_gen* info)
+{
+	struct mq1100fb_par* par = (struct mq1100fb_par*) fb_par;
+	DPRINTK("enter\n");
+
+	/* bpp */
+	if(var->bits_per_pixel != 1 && var->bits_per_pixel != 2 && var->bits_per_pixel != 4 &&
+		var->bits_per_pixel != 8 && var->bits_per_pixel != 16)
+			return -EINVAL;
+	par->bpp = var->bits_per_pixel;
+
+	/* xres, yres */
+	if(var->xres != HRES || var->yres != VRES)
+		return -EINVAL;
+
+	/* xres_virtual, yres_virtual */
+	if(var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 > MQ1100_GC_VIDEOMEM_SIZE ||
+		var->xres_virtual < var->xres || var->yres_virtual < var->yres ||
+			var->xres_virtual * var->bits_per_pixel % 8 || var->yres_virtual * var->bits_per_pixel % 8)
+				return -EINVAL;
+	par->xres_virtual = var->xres_virtual;
+	par->yres_virtual = var->yres_virtual;
+
+	/* xoffset, yoffset */
+	if(var->xoffset > var->xres_virtual - HRES || var->yoffset > var->yres_virtual - VRES)
+		return -EINVAL;
+	par->xoffset = var->xoffset;
+	par->yoffset = var->yoffset;
+
+	/* timings */
+	if(var->pixclock || var->left_margin || var->right_margin || var->upper_margin || var->lower_margin
+		|| var->hsync_len || var->vsync_len || var->sync || var->vmode)
+			return -EINVAL;
+
+	/* grayscale */
+	if(var->bits_per_pixel == 16 && var->grayscale)
+		return -EINVAL;
+	par->grayscale = var->grayscale;
+
+	DPRINTK("exit\n");
+	return 0;
+}
+
+/*
+ *  Fill the 'var' structure based on the values in 'par' and maybe other
+ *  values read out of the hardware.
+ */
+static int mq1100_encode_var(struct fb_var_screeninfo* var, const void* fb_par, struct fb_info_gen* info)
+{
+	struct mq1100fb_par* par = (struct mq1100fb_par*) fb_par;
+	DPRINTK("enter\n");
+
+	memset(var, 0, sizeof(*var));
+	var->xres = HRES;
+	var->yres = VRES;
+	var->xres_virtual = par->xres_virtual;
+	var->yres_virtual = par->yres_virtual;
+	var->xoffset = par->xoffset;
+	var->yoffset = par->yoffset;
+	var->bits_per_pixel = par->bpp;
+	var->grayscale = par->grayscale;
+	if(par->bpp == 16)
+	{
+		var->red.offset = 11;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 6;
+		var->blue.offset = 0;
+		var->blue.length = 5;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+	}
+	else
+	{
+		var->red.length = par->bpp;
+		var->green.length = par->bpp;
+		var->blue.length = par->bpp;
+		var->transp.length = 0;
+	}
+	var->nonstd = 0;
+	var->activate = 0;
+	var->height = 0;
+	var->width = 0;
+	var->accel_flags = 0;
+	var->pixclock = 0;
+	var->left_margin = 0;
+	var->right_margin = 0;
+	var->upper_margin = 0;
+	var->lower_margin = 0;
+	var->hsync_len = 0;
+	var->vsync_len = 0;
+	var->sync = 0;
+	var->vmode = FB_VMODE_NONINTERLACED;
+
+	DPRINTK("exit\n");
+	return 0;
+}
+
+/*
+ *   Fill in par structure. If current par is valid, just copy, otherwise it is an init and copy default
+ */
+static void mq1100_get_par(void* fb_par, struct fb_info_gen* info)
+{
+	struct mq1100fb_par* par = (struct mq1100fb_par *) fb_par;
+	DPRINTK("enter\n");
+
+	if(current_par_valid)
+	{
+		*par = current_par;
+	}
+	else
+	{
+		*par = default_par;
+	}
+	DPRINTK("exit\n");
+}
+
+/*
+ *  Set the hardware according to 'par'.
+ */
+static void mq1100_set_par(const void* fb_par, struct fb_info_gen* info)
+{
+	struct mq1100fb_par* par = (struct mq1100fb_par *) fb_par;
+	u32 window_start, window_stride;
+	u32 reg;
+	DPRINTK("enter\n");
+	
+	/* Set visual */
+	reg = readreg(MQ1100_GC_CONTROL_REG);
+	switch(par->grayscale)
+	{
+		case 0:
+			switch(par->bpp)
+			{
+			case 1:
+				reg = setbits(reg, MQ1100_GC_COLOR_DEPTH_MASK, MQ1100_GC_1BPP_COLOR);
+				break;
+			case 2:
+				reg = setbits(reg, MQ1100_GC_COLOR_DEPTH_MASK, MQ1100_GC_2BPP_COLOR);
+				break;
+			case 4:
+				reg = setbits(reg, MQ1100_GC_COLOR_DEPTH_MASK, MQ1100_GC_4BPP_COLOR);
+				break;
+			case 8:
+				reg = setbits(reg, MQ1100_GC_COLOR_DEPTH_MASK, MQ1100_GC_8BPP_COLOR);
+				break;
+			case 16:
+				reg = setbits(reg, MQ1100_GC_COLOR_DEPTH_MASK, MQ1100_GC_16BPP_COLOR);
+				break;
+			}
+			break;
+		case 1:
+			switch(par->bpp)
+			{
+			case 1:
+				reg = setbits(reg, MQ1100_GC_COLOR_DEPTH_MASK, MQ1100_GC_1BPP_GRAY);
+				break;
+			case 2:
+				reg = setbits(reg, MQ1100_GC_COLOR_DEPTH_MASK, MQ1100_GC_2BPP_GRAY);
+				break;
+			case 4:
+				reg = setbits(reg, MQ1100_GC_COLOR_DEPTH_MASK, MQ1100_GC_4BPP_GRAY);
+				break;
+			case 8:
+				reg = setbits(reg, MQ1100_GC_COLOR_DEPTH_MASK, MQ1100_GC_8BPP_GRAY);
+				break;
+			}
+			break;
+	}
+	writereg(MQ1100_GC_CONTROL_REG, reg);
+
+	/* No pixel doubling */
+	reg = readreg(MQ1100_GC_CONTROL_REG);
+	reg = setbits(reg, MQ1100_GC_HOR_DOUBLING_MASK, MQ1100_GC_SINGLE_PIX);
+	reg = setbits(reg, MQ1100_GC_VER_DOUBLING_MASK, MQ1100_GC_SINGLE_PIX);
+	writereg(MQ1100_GC_CONTROL_REG, reg);
+
+	/* Activate main window */
+	reg = readreg(MQ1100_GC_CONTROL_REG);
+	reg = setbits(reg, MQ1100_GC_DOUBLE_BUFFER_CONTROL_MASK, MQ1100_GC_MAIN_WIN_ACIVE);
+	writereg(MQ1100_GC_CONTROL_REG, reg);
+
+	/* Set window stride */
+	window_stride = par->bpp * par->xres_virtual / 8;
+	reg = readreg(MQ1100_GC_WINDOW_STRIDE_REG);
+	reg = setbits(reg, MQ1100_GC_WINDOW_STRIDE_MASK, window_stride);
+	writereg(MQ1100_GC_WINDOW_STRIDE_REG, reg);
+
+	/* Set window start */
+	window_start = (par->xoffset + (par->yoffset * par->xres_virtual)) * par->bpp / 8;
+	reg = readreg(MQ1100_GC_WINDOW_START_REG);
+	reg = setbits(reg, MQ1100_GC_WINDOW_START_MASK, window_start);
+	writereg(MQ1100_GC_WINDOW_START_REG, reg);
+
+	/* Horizontal and vertical window control */
+	reg = readreg(MQ1100_GC_HOR_WINDOW_CONTROL_REG);
+	reg = setbits(reg, MQ1100_GC_HOR_WINDOW_START_MASK, 0);
+	reg = setbits(reg, MQ1100_GC_HOR_WINDOW_WIDTH_MASK, HRES - 1);
+	writereg(MQ1100_GC_HOR_WINDOW_CONTROL_REG, reg);
+	reg = readreg(MQ1100_GC_VER_WINDOW_CONTROL_REG);
+	reg = setbits(reg, MQ1100_GC_VER_WINDOW_START_MASK, 0);
+	reg = setbits(reg, MQ1100_GC_VER_WINDOW_WIDTH_MASK, VRES - 1);
+	writereg(MQ1100_GC_VER_WINDOW_CONTROL_REG, reg);
+
+	current_par = *par;
+	current_par_valid = 1;
+
+	DPRINTK("exit\n");
+}
+
+/*
+ *  Read a single color register and split it into colors/transparent.
+ *  The return values must have a 16 bit magnitude.
+ *  Return != 0 for invalid regno.
+ */
+static int mq1100_getcolreg(unsigned regno, unsigned* red, unsigned* green, unsigned* blue, unsigned* transp, struct fb_info* info)
+{
+	u32 reg;
+	DPRINTK("enter\n");
+
+	if(regno > 255)
+	{
+		return 1;
+	}
+
+	reg = readreg(MQ1100_GC_PALETTE_REG(regno));
+	if(current_par.grayscale)
+	{
+		*red = *green = *blue = ((getbits(reg, MQ1100_GC_GRAY_HI_MASK) << 6) | getbits(reg, MQ1100_GC_GRAY_LO_MASK)) << 8;
+	}
+	else
+	{
+		*red = getbits(reg, MQ1100_GC_RED_MASK) << 10;
+		*green = getbits(reg, MQ1100_GC_GREEN_MASK) << 10;
+		*blue = getbits(reg, MQ1100_GC_BLUE_MASK) << 10;
+	}
+	*transp = 0;
+	
+	DPRINTK("exit\n");
+	return 0;
+}
+
+/*
+ *  Set a single color register. The values supplied have a 16 bit
+ *  magnitude.
+ *  Return != 0 for invalid regno.
+ */
+static int mq1100_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info* info)
+{
+	u32 reg;
+	DPRINTK("enter\n");
+
+	if(regno > 255)
+	{
+		return -EINVAL;
+	}
+
+	reg = 0;
+	if(current_par.grayscale)
+	{
+		reg = setbits(reg, MQ1100_GC_GRAY_HI_MASK, 0xC0 & (red >> 8));
+		reg = setbits(reg, MQ1100_GC_GRAY_LO_MASK, 0x3F & (red >> 8));
+	}
+	else
+	{
+		reg = setbits(reg, MQ1100_GC_RED_MASK, red >> 10);
+		reg = setbits(reg, MQ1100_GC_GREEN_MASK, green >> 10);
+		reg = setbits(reg, MQ1100_GC_BLUE_MASK, blue >> 10);
+	}
+	writereg(MQ1100_GC_PALETTE_REG(regno), reg);
+
+	if (regno < 16)
+	{
+		/*
+  		 *  Make the first 16 colors of the palette available to fbcon
+		 */
+#ifdef FBCON_HAS_CFB16
+		if(current_par.bpp == 16)
+		{
+			fbcon_cmap.cfb16[regno] = (red & 0xf800) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
+		}
+#endif
+
+	}
+	DPRINTK("exit\n");
+	return 0;
+}
+
+/*
+ *  Pan (or wrap, depending on the `vmode' field) the display using the
+ *  `xoffset' and `yoffset' fields of the `var' structure.
+ *  If the values don't fit, return -EINVAL.
+ */
+static int mq1100_pan_display(const struct fb_var_screeninfo *var, struct fb_info_gen *info)
+{
+	u32 window_start;
+	u32 reg;
+	DPRINTK("enter\n");
+
+	window_start = (var->xoffset + (var->yoffset * var->xres_virtual)) * var->bits_per_pixel / 8;
+	reg = readreg(MQ1100_GC_WINDOW_START_REG);
+	reg = setbits(reg, MQ1100_GC_WINDOW_START_MASK, window_start);
+	writereg(MQ1100_GC_WINDOW_START_REG, reg);
+
+	DPRINTK("exit\n");
+	return 0;
+}
+
+/*
+ *  Blank the screen if blank_mode != 0, else unblank. If blank == NULL
+ *  then the caller blanks by setting the CLUT (Color Look Up Table) to all
+ *  black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due
+ *  to e.g. a video mode which doesn't support it. Implements VESA suspend
+ *  and powerdown modes on hardware that supports disabling hsync/vsync:
+ *    blank_mode == 2: suspend vsync
+ *    blank_mode == 3: suspend hsync
+ *    blank_mode == 4: powerdown
+ */
+static int mq1100_blank(int blank_mode, struct fb_info_gen* info)
+{
+	DPRINTK("enter\n");
+	/* I do not want to mess with flat panel control */
+	DPRINTK("exit\n");
+	return -EINVAL;
+}
+
+/*
+ *  Fill in a pointer with the virtual address of the mapped frame buffer.
+ *  Fill in a pointer to appropriate low level text console operations (and
+ *  optionally a pointer to help data) for the video mode `par' of your
+ *  video hardware. These can be generic software routines, or hardware
+ *  accelerated routines specifically tailored for your hardware.
+ *  If you don't have any appropriate operations, you must fill in a
+ *  pointer to dummy operations, and there will be no text output.
+ */
+static void mq1100_set_disp(const void* fb_par, struct display* disp, struct fb_info_gen* info)
+{
+	struct mq1100fb_par* par = (struct mq1100fb_par*) fb_par;
+	DPRINTK("enter\n");
+
+	disp->screen_base = (void*) MQ1100_GC_VIDEOMEM_BASE;
+	disp->scrollmode = SCROLL_YREDRAW;
+
+	switch(par->bpp)
+	{
+#ifdef FBCON_HAS_MFB
+		case 1:
+			disp->dispsw = &fbcon_mfb;
+			break;
+#endif
+#ifdef FBCON_HAS_CFB2
+		case 2:
+			disp->dispsw = &fbcon_cfb2;
+			break;
+#endif
+#ifdef FBCON_HAS_CFB4
+		case 4:
+			disp->dispsw = &fbcon_cfb4;
+			break;
+#endif
+#ifdef FBCON_HAS_CFB8
+		case 8:
+			disp->dispsw = &fbcon_cfb8;
+			break;
+#endif
+#ifdef FBCON_HAS_CFB16
+		case 16:
+			disp->dispsw = &fbcon_cfb16;
+			disp->dispsw_data = fbcon_cmap.cfb16;
+			break;
+#endif
+		default:
+			disp->dispsw = &fbcon_dummy;
+	}
+
+	DPRINTK("exit\n");
+}
+
+struct fbgen_hwswitch mq1100_switch =
+{
+	NULL,
+	mq1100_encode_fix,
+	mq1100_decode_var,
+	mq1100_encode_var,
+	mq1100_get_par,
+	mq1100_set_par,
+	mq1100_getcolreg,
+	mq1100_setcolreg,
+	mq1100_pan_display,
+	mq1100_blank,
+	mq1100_set_disp
+};
+
+/* ---------------- Frame buffer operations --------------- */
+
+/*
+ *  In most cases the `generic' routines (fbgen_*) should be satisfactory.
+ *  However, you're free to fill in your own replacements.
+ */
+static struct fb_ops mq1100fb_ops =
+{
+	owner:		THIS_MODULE,
+	fb_get_fix:	fbgen_get_fix,
+	fb_get_var:	fbgen_get_var,
+	fb_set_var:	fbgen_set_var,
+	fb_get_cmap:	fbgen_get_cmap,
+	fb_set_cmap:	fbgen_set_cmap,
+	fb_pan_display:	fbgen_pan_display,
+};
+
+/* ------------ Hardware Independent Functions ------------ */
+
+/*
+ *  Initialization
+ */
+int __init mq1100fb_init(void)
+{
+	DPRINTK("enter\n");
+	/* Generic code */
+	fb_info.gen.parsize = sizeof(struct mq1100fb_par);
+	fb_info.gen.fbhw = &mq1100_switch;
+	strcpy(fb_info.gen.info.modename, "MediaQ 1100");
+	fb_info.gen.info.changevar = NULL;
+	fb_info.gen.info.node = -1;
+	fb_info.gen.info.fbops = &mq1100fb_ops;
+	fb_info.gen.info.disp = &disp;
+	fb_info.gen.info.switch_con = &fbgen_switch;
+	fb_info.gen.info.updatevar = &fbgen_update_var;
+	fb_info.gen.info.blank = &fbgen_blank;
+	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
+	/* This should give a reasonable default video mode */
+	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
+	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
+	fbgen_set_disp(-1, &fb_info.gen);
+	fbgen_install_cmap(0, &fb_info.gen);
+	if (register_framebuffer(&fb_info.gen.info) < 0)
+		return -EINVAL;
+	printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.gen.info.node), fb_info.gen.info.modename);
+
+	/* uncomment this if your driver cannot be unloaded */
+	/* MOD_INC_USE_COUNT; */
+	DPRINTK("exit\n");
+	return 0;
+}
+
+/*
+ *  Cleanup
+ */
+void mq1100fb_cleanup(struct fb_info* info)
+{
+	/*
+	 *  If your driver supports multiple boards, you should unregister and
+	 *  clean up all instances.
+	 */
+	DPRINTK("enter\n");
+	unregister_framebuffer(info);
+	DPRINTK("exit\n");
+}
+
+/*
+ *  Setup
+ */
+int __init mq1100fb_setup(char* options)
+{
+	/* Parse user speficied options (`video=xxxfb:') */
+	DPRINTK("enter\n");
+	DPRINTK("exit\n");
+	return 0;
+}
+
+/* ---------------------- Modularization ----------------------- */
+
+#ifdef MODULE
+MODULE_LICENSE("GPL");
+int init_module(void)
+{
+	return mq1100fb_init();
+}
+
+void cleanup_module(void)
+{
+	mq1100fb_cleanup(void);
+}
+#endif /* MODULE */
diff -urN linux-2.4.29/drivers/video/mq200fb.c linux-2.4.29-uc1/drivers/video/mq200fb.c
--- linux-2.4.29/drivers/video/mq200fb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/mq200fb.c	2005-06-14 02:12:27.000000000 +0100
@@ -0,0 +1,2212 @@
+/*
+ * linux/drivers/video/mq200fb.c -- MQ-200 for a frame buffer device
+ * based on linux/driver/video/pm2fb.c
+ *
+ * Copyright (C) 2000 Lineo, Japan
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/selection.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <video/fbcon.h>
+#include <video/fbcon-cfb8.h>
+#include <asm/io.h>
+#include "mq200fb.h"
+
+
+#if 0
+#define PRINTK(args...) printk(args)
+#else
+#define PRINTK(args...)
+#endif
+
+#define WITH_NONE 0
+#define WITH_HSYNC (1 << 0)
+#define WITH_VSYNC (1 << 1)
+
+
+/****************************************************************
+ * type definitions
+ */
+
+/****
+ * PLL parameters
+ */
+struct pll_par {
+    u16 m_par;                 /* M parameter */
+    u16 n_par;                 /* N parameter */
+    u16 p_par;                 /* P parameter */
+};
+
+
+/****
+ * display control values
+ */
+struct disp_par {
+    u16 hdt;                   /* horizontal display total;
+                                * hdt >= hse + 4; val = hdt - 2 */
+    u16 hde;                   /* horizontal display end */
+    u16 vdt;                   /* vertical display total;
+                                * vdt >= vse + 2; val = vdt - 1 */
+    u16 vde;                   /* vertical display end; val = vde - 1 */
+
+    u16 hss;                   /* horizontal sync start; hss >= hde + 4 */
+    u16 hse;                   /* horizontal sync end; hse >= hss + 4 */
+    u16 vss;                   /* vertical sync start; vss >= vde + 1 */
+    u16 vse;                   /* vertical sync end; vse >= vss + 1 */
+};
+
+
+/****
+ * window control values
+ */
+struct win_par {
+    u16 hws;                   /* horizontal window start */
+    u16 hww;                   /* horizontal window width;
+                                * hww >= 8; val = hww - 1 */
+    u16 wald;                  /* window additional line data */
+
+    u16 vws;                   /* vertical window start */
+    u16 vwh;                   /* vertical window height;
+                                * vwh >= 1; val = vwh - 1 */
+    s16 wst;                   /* window stride; do NOT use a negative
+                                  number */
+    unsigned long wsa;         /* window start address */
+};
+
+/****
+ *  The hardware specific data in this structure uniquely defines a video
+ *  mode.
+ *
+ *  If your hardware supports only one video mode, you can leave it empty.
+ */
+struct mq200fb_par {
+    struct pll_par pll[3];     /* PLL 1, 2 and 3 */
+    struct {
+       struct disp_par disp;   /* display control */
+       struct win_par win;     /* window control */
+       struct win_par awin;    /* alternate window control */
+       u16 gcd;                /* graphics color depth */
+       u16 agcd;               /* alternate graphics color depth */
+       u16 v_height;           /* virtual height for main window */
+       u16 v_aheight;          /* virtual height for alternate window */
+       u16 fd;                 /* pixclock = source_clock / fd / sd */
+       u16 sd;
+    } gc[2];                   /* graphics controller 1 and 2 */
+};
+
+
+struct mq200fb_cursor_info {
+    struct {
+       u16 x, y;
+    } size;
+    int enable;
+    struct timer_list timer;
+};
+
+
+struct mq200fb_info {
+    struct fb_info_gen gen;
+    struct mq200fb_par current_par;
+    int current_par_valid;
+    u16 vendor_id;             /* MQ-200 vendor ID */
+    u16 device_id;             /* MQ-200 device ID */
+    struct {
+       u32 fb_size;            /* framebuffer size */
+       unsigned long rg_base;  /* physical register memory base */
+       unsigned long p_fb;     /* physical address of frame buffer */
+       unsigned long v_fb;     /* virtual address of frame buffer */
+       unsigned long p_regs;   /* physical address of rg_base */
+       unsigned long v_regs;   /* virtual address of rg_base */
+    } regions;
+    unsigned long pmu_base;    /* power management unit */
+    unsigned long cpu_base;    /* CPU interface */
+    unsigned long miu_base;    /* memory interface unit */
+    unsigned long in_base;     /* interrupt controller */
+    unsigned long gc_base;     /* graphics controller 1&2 */
+    unsigned long ge_base;     /* graphics engine */
+    unsigned long fpi_base;    /* flat panel interface */
+    unsigned long cp1_base;    /* color palette 1 */
+    unsigned long dc_base;     /* device configuration */
+    unsigned long pci_base;    /* PCI configuration */
+    unsigned long psf_base;    /* ??? */
+
+    struct display disp;
+    struct mq200fb_cursor_info cursor_info;
+    spinlock_t lock;
+};
+
+
+/****************************************************************
+ * function prototype declarations
+ */
+
+static int mq200fb_open(struct fb_info*, int);
+static int mq200fb_release(struct fb_info*, int);
+static void mq200fb_detect(void);
+static int mq200fb_encode_fix(struct fb_fix_screeninfo*, const void*,
+                             struct fb_info_gen*);
+static int mq200fb_decode_var(const struct fb_var_screeninfo*, void*,
+                             struct fb_info_gen*);
+static int mq200fb_encode_var(struct fb_var_screeninfo*, const void*,
+                             struct fb_info_gen*);
+static void mq200fb_get_par(void*, struct fb_info_gen*);
+static void mq200fb_set_par(const void*, struct fb_info_gen*);
+static int mq200fb_getcolreg(unsigned, unsigned*, unsigned*, unsigned*,
+                            unsigned*, struct fb_info*);
+static int mq200fb_setcolreg(unsigned, unsigned, unsigned, unsigned,
+                            unsigned, struct fb_info*);
+static int mq200fb_pan_display(const struct fb_var_screeninfo*,
+                              struct fb_info_gen*);
+static int mq200fb_blank(int, struct fb_info_gen*);
+static void mq200fb_set_disp(const void*, struct display*,
+                            struct fb_info_gen*);
+#ifdef FBCON_HAS_CFB8
+static void mq200fb_cursor(struct display*, int, int, int);
+static int mq200fb_set_font(struct display*, int, int);
+static void mq200fb_clear(struct vc_data*, struct display*, int, int, int,
+                         int);
+static void mq200fb_clear_margins(struct vc_data*, struct display*, int);
+static void mq200fb_putc(struct vc_data*, struct display*, int, int, int);
+static void mq200fb_putcs(struct vc_data*, struct display*,
+                         const unsigned short*, int, int, int);
+#endif
+
+static int is_color_palette_enabled(const struct mq200fb_par*);
+static u32 get_line_length(const struct mq200fb_par*);
+static u32 get_width(const struct mq200fb_par*);
+#if 0
+static void set_v_width(struct mq200fb_par*, int);
+#endif
+static u32 get_v_height(const struct mq200fb_par*);
+static u32 get_height(const struct mq200fb_par*);
+#if 0
+static void set_v_height(struct mq200fb_par*, int);
+#endif
+static int get_bits_per_pixel(const struct mq200fb_par*);
+#if 0
+static void set_bits_per_pixel(struct mq200fb_par*, int);
+#endif
+static u32 get_right_margin(const struct mq200fb_par*);
+static u32 get_left_margin(const struct mq200fb_par*);
+static u32 get_lower_margin(const struct mq200fb_par*);
+static u32 get_upper_margin(const struct mq200fb_par*);
+static u32 get_hsync_len(const struct mq200fb_par*);
+static u32 get_vsync_len(const struct mq200fb_par*);
+static u32 get_xoffset(const struct mq200fb_par*);
+static u32 get_yoffset(const struct mq200fb_par*);
+static u32 get_pixclock(const struct mq200fb_par*);
+static double get_pll_freq(const struct pll_par*);
+static double get_fd_val(const struct mq200fb_par*);
+static double get_sd_val(const struct mq200fb_par*);
+
+static void power_state_transition(const struct mq200fb_info*, int);
+#if 0
+static void vsync(void);
+static void mq200_interrupt(int, void*, struct pt_regs*);
+static void mq200_enable_irq(const struct mq200fb_info*);
+#endif
+static int mq200fb_conf(struct mq200fb_info*);
+static int mq200_probe(struct mq200fb_info*);
+static void mq200_reset(const struct mq200fb_info*);
+static void dc_reset(const struct mq200fb_info*);
+static void miu_reset(const struct mq200fb_info*);
+static void pmu_reset(const struct mq200fb_info*);
+static void gc1_reset(const struct mq200fb_info*);
+static void ge_reset(const struct mq200fb_info*);
+static void cp1_reset(const struct mq200fb_info*);
+static void set_screen(const struct mq200fb_info*,
+                      const struct mq200fb_par*);
+static void set_cursor_shape(const struct mq200fb_info*);
+static void enable_cursor(struct mq200fb_info*);
+static void disable_cursor(struct mq200fb_info*);
+static int set_cursor_pos(const struct mq200fb_info*, unsigned, unsigned);
+static void cursor_timer_handler(unsigned long);
+static void get_color_palette(const struct mq200fb_info*, unsigned,
+                             unsigned*, unsigned*, unsigned*);
+static void set_color_palette(const struct mq200fb_info*, unsigned,
+                             unsigned, unsigned, unsigned);
+static void enable_dac(const struct mq200fb_info*);
+static void disable_dac(const struct mq200fb_info*, unsigned);
+static int __inline__ is_enough_cmd_fifo(const struct mq200fb_info*, int);
+static int __inline__ is_enough_src_fifo(const struct mq200fb_info*, int);
+static void wait_cmd_fifo(const struct mq200fb_info*, int);
+static void wait_src_fifo(const struct mq200fb_info*, int);
+
+static void ge_rect_fill(const struct mq200fb_info*, int, int, int, int,
+                        u32);
+static void ge_bitblt_char(const struct mq200fb_info*, int, int, u8*, int,
+                          int, u32, u32);
+
+static void add_cursor_timer(struct mq200fb_cursor_info*);
+
+
+/****************************************************************
+ * static variables definitions
+ */
+
+/****
+ *  In most cases the `generic' routines (fbgen_*) should be satisfactory.
+ *  However, you're free to fill in your own replacements.
+ */
+static struct fb_ops mq200fb_ops = {
+#if LINUX_VERSION_CODE >= 0x020400
+    owner:             THIS_MODULE,
+#else
+    fb_open:           mq200fb_open,
+    fb_release:                mq200fb_release,
+#endif
+    fb_get_fix:                fbgen_get_fix,
+    fb_get_var:                fbgen_get_var,
+    fb_set_var:                fbgen_set_var,
+    fb_get_cmap:       fbgen_get_cmap,
+    fb_set_cmap:       fbgen_set_cmap,
+    fb_pan_display:    fbgen_pan_display,
+};
+
+
+static struct mq200fb_info mq200fb_info;
+static struct {
+    char font[40];
+    struct mq200fb_par par;
+} mq200fb_options = {
+    font: "",
+    {
+       {
+           { 219, 16, 2 },     /* PLL1 = 12.288MHz * 220 / 17 / 4 = 39.76 */
+           { 242, 16, 2 },     /* PLL2 = 12.288MHz * 243 / 17 / 4 = 43.91 */
+           { 242, 22, 2 },     /* PLL3 = 12.288MHz * 243 / 23 / 4 = 32.46 */
+       },
+       {
+           {                   /* graphics controller 1 */
+               { 1047, 800, 624, 599, 832, 976, 601, 604 }, /* display */
+               { 0, 800, 0, 0, 600, 800, 0 }, /* window */
+               { },            /* alternate window */
+               3,              /* gcd = 8-bpp */
+               3,              /* agcd = 8-bpp */
+               600,            /* virtual height for main window */
+               0,              /* virtual height for alternate window */
+               0,              /* fd = 1 */
+               1               /* sd = 1 */
+           },
+           {                   /* graphics controller 2 */
+           }
+       },
+    }
+};
+
+
+/****
+ * Interfaces to hardware functions
+ */
+static struct fbgen_hwswitch mq200_switch = {
+    detect: mq200fb_detect,
+    encode_fix: mq200fb_encode_fix,
+    decode_var: mq200fb_decode_var,
+    encode_var: mq200fb_encode_var,
+    get_par: mq200fb_get_par,
+    set_par: mq200fb_set_par,
+    getcolreg: mq200fb_getcolreg,
+    setcolreg: mq200fb_setcolreg,
+    pan_display: mq200fb_pan_display,
+    blank: mq200fb_blank,
+    set_disp: mq200fb_set_disp
+};
+
+
+#ifdef FBCON_HAS_CFB8
+static void mq200fb_ds_setup(struct display* disp)
+{
+    fbcon_cfb8_setup(disp);
+}
+
+/****
+ * fbcon switch for the low level operations.
+ */
+static struct display_switch mq200_cfb8 = {
+    setup: mq200fb_ds_setup,
+    bmove: fbcon_cfb8_bmove,
+    clear: mq200fb_clear,
+    putc: mq200fb_putc,
+    putcs: mq200fb_putcs,
+    cursor: mq200fb_cursor,
+    set_font: mq200fb_set_font,
+    clear_margins: mq200fb_clear_margins,
+    fontwidthmask: FONTWIDTH(8) | FONTWIDTH(16)
+};
+#endif
+
+
+/****************************************************************
+ * functions for struct fb_ops member
+ */
+
+#if LINUX_VERSION_CODE < 0x020400
+static int
+mq200fb_open(struct fb_info* info,
+            int user)
+{
+    MOD_INC_USE_COUNT;
+    return 0;
+}
+#endif
+
+
+#if LINUX_VERSION_CODE < 0x020400
+static int
+mq200fb_release(struct fb_info* info,
+               int user)
+{
+    MOD_DEC_USE_COUNT;
+    return 0;
+}
+#endif
+
+
+/****************************************************************
+ * functions for struct fbgen_hwswitch member
+ */
+
+/****
+ *  This function should detect the current video mode settings and store
+ *  it as the default video mode
+ */
+static void
+mq200fb_detect(void)
+{
+}
+
+
+/****
+ *  This function should fill in the 'fix' structure based on the values
+ *  in the `par' structure.
+ */
+static int
+mq200fb_encode_fix(struct fb_fix_screeninfo* fix,
+                  const void* par,
+                  struct fb_info_gen* info)
+{
+    const struct mq200fb_par* mq200fb_par = par;
+    struct mq200fb_info* fb_info = (struct mq200fb_info*)info;
+
+    strcpy(fix->id, CHIPNAME);
+#if LINUX_VERSION_CODE >= 0x020400
+    fix->smem_start = fb_info->regions.p_fb;
+    fix->mmio_start = fb_info->regions.p_regs;
+#else
+    fix->smem_start = (char*)fb_info->regions.p_fb;
+    fix->mmio_start = (char*)fb_info->regions.p_regs;
+#endif
+    fix->smem_len = fb_info->regions.fb_size;
+    fix->mmio_len = MQ200_REGS_SIZE;
+    fix->accel = FB_ACCEL_MEDIAQ_MQ200;
+    fix->type = FB_TYPE_PACKED_PIXELS;
+    fix->visual = is_color_palette_enabled(mq200fb_par)
+       ?  FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+    if (fb_info->current_par_valid)
+       fix->line_length = get_line_length(mq200fb_par);
+    else
+       fix->line_length = 0;
+    fix->xpanstep = 0;         /* $H$j$"$($: */
+    fix->ypanstep = 1;         /* $H$j$"$($: */
+    fix->ywrapstep = 0;
+
+    return 0;
+}
+
+
+/****
+ *  Get the video params out of 'var'. If a value doesn't fit, round it up,
+ *  if it's too big, return -EINVAL.
+ *
+ *  Suggestion: Round up in the following order: bits_per_pixel, xres,
+ *  yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
+ *  bitfields, horizontal timing, vertical timing.
+ */
+static int
+mq200fb_decode_var(const struct fb_var_screeninfo *var,
+                  void* par,
+                  struct fb_info_gen *info)
+{
+    struct mq200fb_info* fb_info = (struct mq200fb_info*)info;
+    struct mq200fb_par* fb_par = (struct mq200fb_par*)par;
+
+    *fb_par = fb_info->current_par;
+    return 0;
+}
+
+
+/****
+ *  Fill the 'var' structure based on the values in 'par' and maybe other
+ *  values read out of the hardware.
+ */
+static int
+mq200fb_encode_var(struct fb_var_screeninfo* var,
+                  const void* par,
+                  struct fb_info_gen* info)
+{
+    const struct mq200fb_par* mq200fb_par = par;
+    struct fb_var_screeninfo new_var;
+
+    memset(&new_var, 0, sizeof new_var);
+
+    new_var.xres_virtual = get_line_length(mq200fb_par) * 8;
+    new_var.yres_virtual = get_v_height(mq200fb_par);
+    new_var.xres = get_width(mq200fb_par);
+    new_var.yres = get_height(mq200fb_par);
+    new_var.right_margin = get_right_margin(mq200fb_par);
+    new_var.hsync_len = get_hsync_len(mq200fb_par);
+    new_var.left_margin = get_left_margin(mq200fb_par);
+    new_var.lower_margin = get_lower_margin(mq200fb_par);
+    new_var.vsync_len = get_vsync_len(mq200fb_par);
+    new_var.upper_margin = get_upper_margin(mq200fb_par);
+    new_var.bits_per_pixel = get_bits_per_pixel(mq200fb_par);
+    switch (get_bits_per_pixel(mq200fb_par)) {
+    case 1:
+    case 2:
+    case 4:
+    case 16:
+    case 24:
+    case 32:
+       PRINTK(CHIPNAME ": %d bpp is not supported depth.\n",
+              get_bits_per_pixel(mq200fb_par));
+       break;
+
+    case 8:
+       new_var.red.length = new_var.green.length = new_var.blue.length = 8;
+       break;
+    }
+    new_var.xoffset = get_xoffset(mq200fb_par);
+    new_var.yoffset = get_yoffset(mq200fb_par);
+    new_var.height = new_var.width = -1;
+    new_var.pixclock = get_pixclock(mq200fb_par);
+    new_var.sync = 0;
+    new_var.vmode = FB_VMODE_NONINTERLACED;
+    new_var.activate = FB_ACTIVATE_NOW;
+
+    *var = new_var;
+
+    return 0;
+}
+
+
+/****
+ *  Fill the hardware's 'par' structure.
+ */
+static void mq200fb_get_par(void* par,
+                           struct fb_info_gen *info)
+{
+    struct mq200fb_info* fb_info = (struct mq200fb_info*)info;
+
+    if (! fb_info->current_par_valid) {
+//     mq200_reset(fb_info);
+       set_screen(fb_info, &fb_info->current_par);
+       fb_info->current_par_valid = 1;
+    }
+    *((struct mq200fb_par*)par) = fb_info->current_par;
+}
+
+
+/****
+ *  Set the hardware according to 'par'.
+ */
+static void mq200fb_set_par(const void* par,
+                           struct fb_info_gen *info)
+{
+    struct mq200fb_info* fb_info = (struct mq200fb_info*)info;
+    struct mq200fb_par* fb_par = (struct mq200fb_par*)par;
+
+    set_screen(fb_info, fb_par);
+    fb_info->current_par = *fb_par;
+    fb_info->current_par_valid = 1;
+}
+
+
+/****
+ *  Read a single color register and split it into colors/transparent.
+ *  The return values must have a 16 bit magnitude.
+ *  Return != 0 for invalid regno.
+ */
+static int mq200fb_getcolreg(unsigned regno,
+                            unsigned* red,
+                            unsigned* green,
+                            unsigned* blue,
+                            unsigned* transp,
+                            struct fb_info* info)
+{
+    struct mq200fb_info* fb_info = (struct mq200fb_info*)info;
+
+    if (regno >= 256)
+       return 1;
+
+    get_color_palette(fb_info, regno, red, green, blue);
+    *red <<= 8;
+    *green <<= 8;
+    *blue <<= 8;
+    *transp = 0;               /* right now, transparency is not
+                                  implemented */
+
+    return 0;
+}
+
+
+/****
+ *  Set a single color register. The values supplied have a 16 bit
+ *  magnitude.
+ *  Return != 0 for invalid regno.
+ */
+static int mq200fb_setcolreg(unsigned regno,
+                            unsigned red,
+                            unsigned green,
+                            unsigned blue,
+                            unsigned transp,
+                            struct fb_info *info)
+{
+    struct mq200fb_info* fb_info = (struct mq200fb_info*)info;
+
+    if (regno >= 256)
+       return 1;
+
+    set_color_palette(fb_info, regno, red >> 8, green >> 8, blue >> 8);
+
+    return 0;
+}
+
+
+/****
+ *  Pan (or wrap, depending on the `vmode' field) the display using the
+ *  `xoffset' and `yoffset' fields of the `var' structure.
+ *  If the values don't fit, return -EINVAL.
+ */
+static int mq200fb_pan_display(const struct fb_var_screeninfo* var,
+                              struct fb_info_gen* info)
+{
+    if (var->xoffset || var->yoffset)
+       return -EINVAL;
+    else
+       return 0;
+
+#if 0
+    if (var->xoffset <= 0 && var->yoffset <= 0) {
+    }
+    else if (var->xoffset > 0 && var->yoffset > 0) {
+    }
+    else if (var->xoffset <= 0 && var->yoffset > 0) {
+    }
+    else {
+    }
+
+    return 0;
+#endif
+}
+
+
+/****
+ *  Blank the screen if blank_mode != 0, else unblank. If blank == NULL
+ *  then the caller blanks by setting the CLUT (Color Look Up Table) to all
+ *  black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due
+ *  to e.g. a video mode which doesn't support it. Implements VESA suspend
+ *  and powerdown modes on hardware that supports disabling hsync/vsync:
+ *    blank_mode == 2: suspend vsync
+ *    blank_mode == 3: suspend hsync
+ *    blank_mode == 4: powerdown
+ */
+static int mq200fb_blank(int blank_mode,
+                        struct fb_info_gen* info)
+{
+    struct mq200fb_info* fb_info = (struct mq200fb_info*)info;
+
+    if (! fb_info->current_par_valid)
+       return 1;
+
+    switch (blank_mode) {
+    case 0:
+       enable_dac(fb_info);
+       enable_cursor(fb_info);
+       return 0;
+
+    case 1:
+       disable_cursor(fb_info);
+       disable_dac(fb_info, WITH_VSYNC | WITH_HSYNC);
+       return 0;
+
+    case 2:
+       disable_cursor(fb_info);
+       disable_dac(fb_info, WITH_HSYNC);
+       return 0;
+
+    case 3:
+       disable_cursor(fb_info);
+       disable_dac(fb_info, WITH_VSYNC);
+       return 0;
+
+    case 4:
+       disable_cursor(fb_info);
+       disable_dac(fb_info, WITH_NONE);
+       return 0;
+
+    default:
+       printk(CHIPNAME ": unknown blank mode (%d).\n", blank_mode);
+       return 1;
+    }
+}
+
+
+/****
+ *  Fill in a pointer with the virtual address of the mapped frame buffer.
+ *  Fill in a pointer to appropriate low level text console operations (and
+ *  optionally a pointer to help data) for the video mode `par' of your
+ *  video hardware. These can be generic software routines, or hardware
+ *  accelerated routines specifically tailored for your hardware.
+ *  If you don't have any appropriate operations, you must fill in a
+ *  pointer to dummy operations, and there will be no text output.
+ */
+static void mq200fb_set_disp(const void *par,
+                            struct display *disp,
+                            struct fb_info_gen *info)
+{
+    struct mq200fb_info* fb_info = (struct mq200fb_info*)info;
+
+    disp->screen_base = (char*)fb_info->regions.v_fb;
+    switch (get_bits_per_pixel((struct mq200fb_par*)par)) {
+#ifdef FBCON_HAS_CFB8
+    case 8:
+       disp->dispsw = &mq200_cfb8;
+       break;
+#endif
+    default:
+       disp->dispsw = &fbcon_dummy;
+    }
+}
+
+
+/****************************************************************
+ * functions for struct display_switch member
+ */
+
+#ifdef FBCON_HAS_CFB8
+static void
+mq200fb_cursor(struct display* disp,
+              int mode,
+              int x,
+              int y)
+{
+    struct mq200fb_info* fb_info = (struct mq200fb_info*)disp->fb_info;
+
+    switch (mode) {
+    case CM_ERASE:
+       disable_cursor(fb_info);
+       break;
+
+    case CM_DRAW:
+    case CM_MOVE:
+       enable_cursor(fb_info);
+       set_cursor_pos(fb_info, x * fontwidth(disp), y * fontheight(disp));
+       break;
+    }
+}
+#endif
+
+
+#ifdef FBCON_HAS_CFB8
+static int
+mq200fb_set_font(struct display* disp,
+                int width,
+                int height)
+{
+    struct mq200fb_info* fb_info = (struct mq200fb_info*)disp->fb_info;
+
+    fb_info->cursor_info.size.x = width;
+    fb_info->cursor_info.size.y = height;
+    set_cursor_shape(fb_info);
+
+    return 1;
+}
+#endif
+
+
+#ifdef FBCON_HAS_CFB8
+static void mq200fb_clear(struct vc_data* conp, struct display* disp,
+                         int sy, int sx, int height, int width)
+{
+    struct mq200fb_info* fb_info = (struct mq200fb_info*)disp->fb_info;
+    u32 bgx;
+
+    bgx = attr_bgcol_ec(disp, conp);
+    ge_rect_fill(fb_info, sx * fontwidth(disp), sy * fontheight(disp),
+                width * fontwidth(disp), height * fontheight(disp), bgx);
+}
+#endif
+
+
+#ifdef FBCON_HAS_CFB8
+static void
+mq200fb_clear_margins(struct vc_data* conp,
+                     struct display* disp,
+                     int bottom_only)
+{
+    const struct mq200fb_info* fb_info = (struct mq200fb_info*)disp->fb_info;
+    unsigned int right_start = conp->vc_cols * fontwidth(disp);
+    unsigned int right_width = disp->var.xres - right_start;
+    unsigned int bottom_start = conp->vc_rows * fontheight(disp);
+    unsigned int bottom_width = disp->var.yres - bottom_start;
+    u32 bgx = attr_bgcol_ec(disp, conp);
+
+    if (! bottom_only && right_width != 0)
+       ge_rect_fill(fb_info, right_start, 0, right_width,
+                    disp->var.yres_virtual, bgx);
+    if (bottom_width != 0)
+       ge_rect_fill(fb_info, 0, disp->var.yoffset + bottom_start,
+                    right_start, bottom_width, bgx);
+}
+#endif
+
+
+#ifdef FBCON_HAS_CFB8
+static void
+mq200fb_putc(struct vc_data* conp,
+            struct display* disp,
+            int ch,
+            int yy,
+            int xx)
+{
+    struct mq200fb_info* fb_info = (struct mq200fb_info*)disp->fb_info;
+    u32 fgx, bgx;
+    u8* chdat;
+
+    fgx = attr_fgcol(disp, ch);
+    bgx = attr_bgcol(disp, ch);
+    xx *= fontwidth(disp);
+    yy *= fontheight(disp);
+    chdat = disp->fontdata + (ch & disp->charmask) * fontheight(disp);
+    ge_bitblt_char(fb_info, xx, yy, chdat, fontwidth(disp),
+                  fontheight(disp), fgx, bgx);
+}
+#endif
+
+
+#ifdef FBCON_HAS_CFB8
+static void
+mq200fb_putcs(struct vc_data* conp,
+             struct display* disp,
+             const unsigned short* str,
+             int count,
+             int yy,
+             int xx)
+{
+    struct mq200fb_info* fb_info = (struct mq200fb_info*)disp->fb_info;
+    u32 fgx, bgx;
+
+    fgx = attr_fgcol(disp, scr_readw(str));
+    bgx = attr_bgcol(disp, scr_readw(str));
+    xx *= fontwidth(disp);
+    yy *= fontheight(disp);
+    while (count-- > 0) {
+       u16 ch = scr_readw(str++) & disp->charmask;
+       u8* chdat = disp->fontdata + ch * fontheight(disp);
+
+       ge_bitblt_char(fb_info, xx, yy, chdat, fontwidth(disp),
+                      fontheight(disp), fgx, bgx);
+       xx += fontwidth(disp);
+    }
+}
+#endif
+
+
+/****************************************************************
+ * functions related to "struct mq200fb_par".
+ */
+
+/****
+ * Is current window using color palette?
+ */
+static int
+is_color_palette_enabled(const struct mq200fb_par* par)
+{
+    switch (par->gc[0].gcd) {
+    case GCD_1_CP: case GCD_2_CP: case GCD_4_CP: case GCD_8_CP:
+    case GCD_16_CP: case GCD_24_CP: case GCD_32_RGB_CP: case GCD_32_BGR_CP:
+       return 1;
+    default:
+       return 0;
+    }
+}
+
+
+/****
+ * Return current window's virtual width in bytes.
+ *
+ * [NOTE]
+ *     This function assumes that struct win_par.wst value is not a
+ *     negative number.
+ */
+static u32
+get_line_length(const struct mq200fb_par* par)
+{
+    return par->gc[0].win.wst;
+}
+
+
+/****
+ * Return current window's width in pixels.
+ */
+static u32
+get_width(const struct mq200fb_par* par)
+{
+    return par->gc[0].win.hww /* + 1 */;
+}
+
+
+#if 0
+/****
+ * set current window's virtual width.
+ *
+ * [NOTE]
+ *     This function assumes that already depth was set.
+ */
+static void
+set_v_width(struct mq200fb_par* par,
+           int width)          /* in pixels */
+{
+    int depth = get_bits_per_pixel(par);
+    par->gc[0].win.wst = (width * depth + 127) / 128 * 16;
+}
+#endif
+
+
+/****
+ * Return current window's virtual height.
+ */
+static u32
+get_v_height(const struct mq200fb_par* par)
+{
+    return par->gc[0].v_height;
+}
+
+
+static u32
+get_height(const struct mq200fb_par* par)
+{
+    return par->gc[0].win.vwh;
+}
+
+
+#if 0
+/****
+ * set current window's virtual height.
+ */
+static void
+set_v_height(struct mq200fb_par* par,
+            int height)
+{
+    par->gc[0].v_height = height;
+}
+#endif
+
+
+/****
+ * get current window's depth (bits / pixcel).
+ */
+static int
+get_bits_per_pixel(const struct mq200fb_par* par)
+{
+    switch (par->gc[0].gcd) {
+    case GCD_1_CP:
+       return 1;
+    case GCD_2_CP:
+       return 2;
+    case GCD_4_CP:
+       return 4;
+    case GCD_8_CP:
+       return 8;
+    case GCD_16_CP: case GCD_16:
+       return 16;
+    case GCD_24_CP: case GCD_24:
+       return 24;
+    default:
+       return 32;
+    }
+}
+
+
+#if 0
+/****
+ * set current window's depth.
+ *
+ * [NOTE]
+ *     we do not use the following:
+ *             GCD_16_CP, GCD_24_CP, GCD_32_RGB_CP, GCD_32_BGR_CP,
+ *             GCD_32_BGR.
+ */
+static void
+set_bits_per_pixel(struct mq200fb_par* par,
+                  int bpp)
+{
+    if (bpp <= 1)
+       par->gc[0].gcd = GCD_1_CP;
+    else if (bpp <= 2)
+       par->gc[0].gcd = GCD_2_CP;
+    else if (bpp <= 4)
+       par->gc[0].gcd = GCD_4_CP;
+    else if (bpp <= 8)
+       par->gc[0].gcd = GCD_8_CP;
+    else if (bpp <= 16)
+       par->gc[0].gcd = GCD_16;
+    else if (bpp <= 24)
+       par->gc[0].gcd = GCD_24;
+    else
+       par->gc[0].gcd = GCD_32_RGB;
+}
+#endif
+
+
+static u32
+get_right_margin(const struct mq200fb_par* par)
+{
+    return par->gc[0].disp.hss;
+}
+
+
+static u32
+get_left_margin(const struct mq200fb_par* par)
+{
+    return par->gc[0].disp.hdt + 2 - par->gc[0].disp.hse;
+}
+
+
+static u32
+get_lower_margin(const struct mq200fb_par* par)
+{
+    return par->gc[0].disp.vss;
+}
+
+
+static u32
+get_upper_margin(const struct mq200fb_par* par)
+{
+    return par->gc[0].disp.vdt + 1 - par->gc[0].disp.vse;
+}
+
+
+static u32
+get_hsync_len(const struct mq200fb_par* par)
+{
+    return par->gc[0].disp.hse - par->gc[0].disp.hss;
+}
+
+
+static u32
+get_vsync_len(const struct mq200fb_par* par)
+{
+    return par->gc[0].disp.vse - par->gc[0].disp.vss;
+}
+
+
+static u32
+get_xoffset(const struct mq200fb_par* par)
+{
+    return (par->gc[0].win.wsa % par->gc[0].win.wst) /
+       ((get_bits_per_pixel(par) + 7) / 8);
+}
+
+
+static u32
+get_yoffset(const struct mq200fb_par* par)
+{
+    return par->gc[0].win.wsa / par->gc[0].win.wst;
+}
+
+
+/****
+ * Return pixel clock in pico seconds.
+ */
+static u32
+get_pixclock(const struct mq200fb_par* par)
+{
+    double freq = get_pll_freq(&par->pll[1]) / get_fd_val(par) / get_sd_val(par);
+    return (u32)(1.0e12 / freq + 0.5);
+}
+
+
+/****
+ * Return specified PLL frequencey in MHz.
+ */
+static double
+get_pll_freq(const struct pll_par* pll)
+{
+    return 12.288e6 * (pll->m_par + 1) / (pll->n_par + 1) / (1 << pll->p_par);
+}
+
+
+/****
+ * Return FD value. FD is a value that is used to generate G1MCLK.
+ */
+static double
+get_fd_val(const struct mq200fb_par* par)
+{
+    switch (par->gc[0].fd) {
+    case 0:
+       return 1.0;
+    default:
+       return par->gc[0].fd + 0.5;
+    }
+}
+
+
+/****
+ * Return SD value. SD is a value that is used to generate G1MCLK.
+ */
+static double
+get_sd_val(const struct mq200fb_par* par)
+{
+    return par->gc[0].sd;
+}
+
+
+/****************************************************************
+ * hardware specific functions.
+ */
+
+/****
+ * power state transition to "state".
+ */
+static void
+power_state_transition(const struct mq200fb_info* fb_info,
+                      int state)
+{
+    int i;
+    writel(state, PMCSR(fb_info));
+    for (i = 1; ; i++) {
+       udelay(100);
+       if ((readl(PMCSR(fb_info)) & 0x3) == state) {
+           PRINTK(CHIPNAME ": transition to D%d state (%d)\n\r", state, i);
+           break;
+       }
+    }
+}
+
+
+#if 0
+/****
+ * vertical sync enable -- falling edge.
+ */
+static void
+vsync()
+{
+}
+
+
+/****
+ * interrupt handler.
+ */
+static void
+mq200_interrupt(int irq,
+               void* dev_id,
+               struct pt_regs* regs)
+{
+    u32 status;
+
+    status = readl(IN02R(&mq200fb_info));
+    writel(status, IN02R(&mq200fb_info));
+    if (status & 0x02)
+       vsync();
+}
+
+
+/****
+ * enable interrupt controller.
+ */
+static void
+mq200_enable_irq(const struct mq200fb_info* fb_info)
+{
+    writel(0x1F02, IN01R(fb_info)); /* unmask */
+    writel(1, IN00R(fb_info)); /* interrupt enable */
+}
+#endif
+
+
+/****
+ * Configure register and framebuffer addresses.
+ * If you need to get virtual addresses using ioremap(), rewrite this
+ * function.
+ *
+ * [RETURN]
+ *     1: success
+ *     0: fail
+ */
+static int __init
+mq200fb_conf(struct mq200fb_info* fb_info)
+{
+    /* set framebuffer related values */
+    fb_info->regions.p_fb = virt_to_phys((void*)MQ200_FB_BASE);
+    fb_info->regions.v_fb = MQ200_FB_BASE;
+    fb_info->regions.p_regs = virt_to_phys((void*)MQ200_REGS_BASE);
+    fb_info->regions.v_regs = MQ200_REGS_BASE;
+    fb_info->regions.fb_size = MQ200_FB_SIZE - CURSOR_IMAGE_SIZE;
+
+    /* set addresses of module register */
+    fb_info->pmu_base = fb_info->regions.v_regs + PMU_OFFSET;
+    fb_info->cpu_base = fb_info->regions.v_regs + CPU_OFFSET;
+    fb_info->miu_base = fb_info->regions.v_regs + MIU_OFFSET;
+    fb_info->in_base = fb_info->regions.v_regs + IN_OFFSET;
+    fb_info->gc_base = fb_info->regions.v_regs + GC_OFFSET;
+    fb_info->ge_base = fb_info->regions.v_regs + GE_OFFSET;
+    fb_info->fpi_base = fb_info->regions.v_regs + FPI_OFFSET;
+    fb_info->pci_base = fb_info->regions.v_regs + PCI_OFFSET;
+    fb_info->dc_base = fb_info->regions.v_regs + DC_OFFSET;
+    fb_info->cp1_base = fb_info->regions.v_regs + CP1_OFFSET;
+    fb_info->psf_base = fb_info->regions.v_regs + PSF_OFFSET;
+
+    if (! mq200_probe(fb_info)) {
+       printk(CHIPNAME ": MQ-200 not found.\n");
+       return 0;
+    }
+    PRINTK(CHIPNAME ": MQ-200 found.\n");
+
+    /* set cursor info */
+    init_timer(&fb_info->cursor_info.timer);
+    fb_info->cursor_info.timer.data = (unsigned long)fb_info;
+    fb_info->cursor_info.timer.function = cursor_timer_handler;
+    add_cursor_timer(&fb_info->cursor_info);
+
+    return 1;
+}
+
+
+/****
+ * [RETURN]
+ *     1: detect
+ *     0: not found
+ */
+static int __init
+mq200_probe(struct mq200fb_info* fb_info)
+{
+    union pc00r pc00r;
+
+    if (readl(PMR(fb_info)) != PMR_VALUE)
+       return 0;
+
+    pc00r.whole = readl(PC00R(fb_info));
+    fb_info->vendor_id = pc00r.part.vendor;
+    fb_info->device_id = pc00r.part.device;
+
+    return 1;
+}
+
+
+/****
+ * mq-200 hardware reset.
+ */
+static void
+mq200_reset(const struct mq200fb_info* fb_info)
+{
+    power_state_transition(fb_info, 0);        /* transition to D0 state */
+
+    dc_reset(fb_info);         /* device configuration */
+    miu_reset(fb_info);                /* memory interface unit */
+    pmu_reset(fb_info);                /* power management unit */
+    gc1_reset(fb_info);                /* graphics controller 1 */
+    ge_reset(fb_info);         /* graphics engine */
+    cp1_reset(fb_info);                /* color palette 1 */
+}
+
+
+/****
+ * device configuration initialization.
+ */
+static void
+dc_reset(const struct mq200fb_info* fb_info)
+{
+    union dc00r dc00r;
+
+    dc00r.whole = 0;
+    dc00r.part.osc_enbl = 1;
+    dc00r.part.pll1_enbl = 1;
+    dc00r.part.pll1_p_par = fb_info->current_par.pll[0].p_par;
+    dc00r.part.pll1_n_par = fb_info->current_par.pll[0].n_par;
+    dc00r.part.pll1_m_par = fb_info->current_par.pll[0].m_par;
+    dc00r.part.fast_pwr = 1;
+    dc00r.part.osc_frq = 3;    /* oscillator frequency is in the range of
+                                  12 MHz to 25 MHz */
+    writel(dc00r.whole, DC00R(fb_info));
+    PRINTK(CHIPNAME ": DC00R = %lx\n", readl(DC00R(fb_info)));
+}
+
+
+/****
+ * initialize memory interface unit.
+ */
+static void
+miu_reset(const struct mq200fb_info* fb_info)
+{
+    union mm00r mm00r;
+    union mm01r mm01r;
+    union mm02r mm02r;
+    union mm03r mm03r;
+    union mm04r mm04r;
+
+    /* MIU interface control 1 */
+    mm00r.whole = 0;
+    mm00r.part.miu_enbl = 1;
+    mm00r.part.mr_dsbl = 1;
+    writel(mm00r.whole, MM00R(fb_info));
+    mdelay(100);
+    writel(0, MM00R(fb_info));
+    mdelay(50);
+
+    /* MIU interface control 2
+     * o PLL 1 output is used as memory clock source.
+     */
+    mm01r.whole = 0;
+    mm01r.part.msr_enbl = 1;
+    mm01r.part.pb_cpu = 1;
+    mm01r.part.pb_ge = 1;
+    mm01r.part.mr_interval = 3744; /* normal memory refresh time interval */
+    writel(mm01r.whole, MM01R(fb_info));
+
+    /* memory interface control 3 */
+    mm02r.whole = 0;
+    mm02r.part.bs_stnr = 1;    /* burst count for STN read is four */
+    mm02r.part.bs_ge = 3;      /* burst count for graphics engine is eight */
+    mm02r.part.fifo_gc1 = 2;
+    mm02r.part.fifo_gc2 = 1;
+    mm02r.part.fifo_stnr = 2;
+    mm02r.part.fifo_stnw = 1;
+    mm02r.part.fifo_ge_src = 3;
+    mm02r.part.fifo_ge_dst = 3;
+    writel(mm02r.whole, MM02R(fb_info));
+
+    /* memory interface control 5 */
+    mm04r.whole = 0;
+    mm04r.part.latency = 1;    /* EDRAM latency 1 */
+    mm04r.part.dmm_cyc = 1;
+    mm04r.part.bnk_act_cls = 1;
+    writel(mm04r.whole, MM04R(fb_info));
+
+    /* memory interface control 4 */
+    mm03r.whole = 0;
+    mm03r.part.rd_late_req = 1;
+    mm03r.part.reserved_1 = 134; /* ? */
+    writel(mm03r.whole, MM03R(fb_info));
+    mdelay(10);
+
+    /* MIU interface control 1 */
+    writel(mm00r.whole, MM00R(fb_info));
+    mdelay(50);
+
+    PRINTK(CHIPNAME ": MIU reset.\n");
+}
+
+
+/****
+ * initialize power management unit.
+ */
+static void
+pmu_reset(const struct mq200fb_info* fb_info)
+{
+    union pm00r pm00r;
+    union pm01r pm01r;
+    union pm02r pm02r;
+    union pm06r pm06r;
+    union pm07r pm07r;
+
+    /* power management miscellaneous control
+     * o GE is driven by PLL 1 clock.
+     */
+    pm00r.whole = 0;
+    pm00r.part.pll2_enbl = 1;
+    pm00r.part.pll3_enbl = 1;
+    pm00r.part.ge_enbl = 1;
+    pm00r.part.ge_bsy_gl = 1;
+    pm00r.part.ge_bsy_lcl = 1;
+    pm00r.part.ge_clock = 1;   /* GE is driven by PLL 1 clock */
+    pm00r.part.d3_mem_rfsh = 1;
+    writel(pm00r.whole, PM00R(fb_info));
+    mdelay(1);
+    writel(pm00r.whole & 0x6000, PM00R(fb_info));
+    mdelay(1);
+
+    /* D1 state control */
+    pm01r.whole = 0;
+    pm01r.part.osc_enbl = 1;
+    pm01r.part.pll1_enbl = 1;
+    pm01r.part.pll2_enbl = 1;
+    pm01r.part.miu_enbl = 1;
+    pm01r.part.mem_rfsh = 1;
+    pm01r.part.ge_enbl = 1;
+    pm01r.part.fpd_enbl = 1;
+    pm01r.part.ctl1_enbl = 1;
+    pm01r.part.awin1_enbl = 1;
+    writel(pm01r.whole, PM01R(fb_info));
+
+    /* D2 state control */
+    pm02r.whole = 0;
+    pm02r.part.osc_enbl = 1;
+    pm02r.part.pll1_enbl = 1;
+    pm02r.part.pll2_enbl = 1;
+    pm02r.part.miu_enbl = 1;
+    pm02r.part.mem_rfsh = 1;
+    pm02r.part.ge_enbl = 1;
+    writel(pm02r.whole, PM02R(fb_info));
+
+    /* PLL 2 programming */
+    pm06r.whole = 0;
+    pm06r.part.p_par = fb_info->current_par.pll[1].p_par;
+    pm06r.part.n_par = fb_info->current_par.pll[1].n_par;
+    pm06r.part.m_par = fb_info->current_par.pll[1].m_par;
+    writel(pm06r.whole, PM06R(fb_info));
+
+    /* PLL 3 programming */
+    pm07r.whole = 0;
+    pm07r.part.p_par = fb_info->current_par.pll[2].p_par;
+    pm07r.part.n_par = fb_info->current_par.pll[2].n_par;
+    pm07r.part.m_par = fb_info->current_par.pll[2].m_par;
+    writel(pm07r.whole, PM07R(fb_info));
+
+    writel(pm00r.whole, PM00R(fb_info));
+
+    PRINTK(CHIPNAME ": PMU reset.\n");
+}
+
+
+/****
+ * initialize graphics controller 1.
+ */
+static void
+gc1_reset(const struct mq200fb_info* fb_info)
+{
+    unsigned long flags;
+    union gc00r gc00r;
+    union gc01r gc01r;
+    union gc02r gc02r;
+    union gc03r gc03r;
+    union gc04r gc04r;
+    union gc05r gc05r;
+    union gc08r gc08r;
+    union gc09r gc09r;
+    union gc0er gc0er;
+    union gc11r gc11r;
+
+    spin_lock_irqsave(&fb_info->lock, flags);
+
+    /* graphics controller CRT control */
+    gc01r.whole = 0;
+    gc01r.part.dac_enbl = 1;
+    gc01r.part.hsync_out = 1;
+    gc01r.part.vsync_out = 1;
+    writel(gc01r.whole, GC01R(fb_info));
+
+    /* horizontal display 1 control */
+    gc02r.whole = 0;
+    gc02r.part.hd1t = fb_info->current_par.gc[0].disp.hdt;
+    gc02r.part.hd1e = fb_info->current_par.gc[0].disp.hde;
+    writel(gc02r.whole, GC02R(fb_info));
+
+    /* vertical display 1 control */
+    gc03r.whole = 0;
+    gc03r.part.vd1t = fb_info->current_par.gc[0].disp.vdt;
+    gc03r.part.vd1e = fb_info->current_par.gc[0].disp.vde;
+    writel(gc03r.whole, GC03R(fb_info));
+
+    /* horizontal sync 1 control */
+    gc04r.whole = 0;
+    gc04r.part.hs1s = fb_info->current_par.gc[0].disp.hss;
+    gc04r.part.hs1e = fb_info->current_par.gc[0].disp.hse;
+    writel(gc04r.whole, GC04R(fb_info));
+
+    /* vertical sync 1 control */
+    gc05r.whole = 0;
+    gc05r.part.vs1s = fb_info->current_par.gc[0].disp.vss;
+    gc05r.part.vs1e = fb_info->current_par.gc[0].disp.vse;
+    writel(gc05r.whole, GC05R(fb_info));
+
+    /* horizontal window 1 control */
+    gc08r.whole = 0;
+    gc08r.part.hw1s = fb_info->current_par.gc[0].win.hws;
+    gc08r.part.hw1w = fb_info->current_par.gc[0].win.hww;
+    gc08r.part.w1ald = fb_info->current_par.gc[0].win.wald;
+    writel(gc08r.whole, GC08R(fb_info));
+
+    /* vertical window 1 control */
+    gc09r.whole = 0;
+    gc09r.part.vw1s = fb_info->current_par.gc[0].win.vws;
+    gc09r.part.vw1h = fb_info->current_par.gc[0].win.vwh;
+    writel(gc09r.whole, GC09R(fb_info));
+
+    /* alternate horizontal window 1 control */
+    writel(0, GC0AR(fb_info));
+
+    /* alternate vertical window 1 control */
+    writel(0, GC0BR(fb_info));
+
+    /* window 1 start address */
+    writel(fb_info->current_par.gc[0].win.wsa, GC0CR(fb_info));
+
+    /* alternate window 1 start address */
+    writel(0, GC0DR(fb_info));
+
+    /* window 1 stride */
+    gc0er.whole = 0;
+    gc0er.part.w1st = fb_info->current_par.gc[0].win.wst;
+    gc0er.part.aw1st = fb_info->current_par.gc[0].awin.wst;
+    writel(gc0er.whole, GC0ER(fb_info));
+
+    /* reserved register - ??? - */
+    writel(0x31f, GC0FR(fb_info));
+
+    /* hardware cursor 1 position */
+    writel(0, GC10R(fb_info));
+
+    /* hardware cursor 1 start address and offset */
+    gc11r.whole = 0;
+    gc11r.part.hc1sa = CURSOR_OFFSET >> 10;
+    writel(gc11r.whole, GC11R(fb_info));
+
+    /* hardware cursor 1 foreground color */
+    writel(0x00ffffff, GC12R(fb_info));
+
+    /* hardware cursor 1 background color */
+    writel(0x00000000, GC13R(fb_info));
+
+    /* graphics controller 1 register
+     * o GC1 clock source is PLL 2.
+     * o hardware cursor is enabled.
+     */
+    gc00r.whole = 0;
+    gc00r.part.ctl_enbl = 1;
+    gc00r.part.iwin_enbl = 1;
+    gc00r.part.gcd = fb_info->current_par.gc[0].gcd;
+    gc00r.part.hc_enbl = 1;
+   gc00r.part.agcd = fb_info->current_par.gc[0].agcd;
+    gc00r.part.g1rclk_src = 2; /* PLL 2 */
+    gc00r.part.fd = 0;         /* FD = 1 */
+    gc00r.part.sd = 1;         /* SD = 1 */
+    writel(gc00r.whole, GC00R(fb_info));
+
+    spin_unlock_irqrestore(&fb_info->lock, flags);
+
+    PRINTK(CHIPNAME ": GC1 reset.\n");
+}
+
+
+/****
+ * initialize graphics engine.
+ */
+static void
+ge_reset(const struct mq200fb_info* fb_info)
+{
+    /* drawing command register */
+    writel(0, GE00R(fb_info));
+
+    /* promary width and height register */
+    writel(0, GE01R(fb_info));
+
+    /* primary destination address register */
+    writel(0, GE02R(fb_info));
+
+    /* primary source XY register */
+    writel(0, GE03R(fb_info));
+
+    /* primary color compare register */
+    writel(0, GE04R(fb_info));
+
+    /* primary clip left/top register */
+    writel(0, GE05R(fb_info));
+
+    /* primary clip right/bottom register */
+    writel(0, GE06R(fb_info));
+
+    /* primary source and pattern offset register */
+    writel(0, GE07R(fb_info));
+
+    /* primary foreground color register/rectangle fill color depth */
+    writel(0, GE08R(fb_info));
+
+    /* source stride/offset register */
+    writel(0, GE09R(fb_info));
+
+    /* destination stride register and color depth */
+    writel(0, GE0AR(fb_info));
+
+    /* image base address register */
+    writel(0, GE0BR(fb_info));
+
+    PRINTK(CHIPNAME ": GE reset.\n");
+}
+
+
+/****
+ * initialize Color Palette 1.
+ */
+static void
+cp1_reset(const struct mq200fb_info* fb_info)
+{
+    int i;
+
+    for (i = 0; i < 256; i++)
+       writel(0, C1xxR(fb_info, i));
+}
+
+
+/****
+ * change screen size and depth, and so on.
+ * Right now, screen attributes modification is not implemeted.
+ */
+static void
+set_screen(const struct mq200fb_info* fb_info,
+          const struct mq200fb_par* par)
+{
+    unsigned long flags;
+    union ge0ar ge0ar;
+
+    /* set destination stride and color depth for GE */
+    ge0ar.whole = 0;
+    ge0ar.part.dst_strid = get_line_length(par);
+    switch (get_bits_per_pixel(par)) {
+    case 8:
+       ge0ar.part.col_dpth = 0;
+       break;
+    case 16:
+       ge0ar.part.col_dpth = 1;
+       break;
+    case 32:
+       ge0ar.part.col_dpth = 3;
+       break;
+    default:
+       printk(CHIPNAME ": unexpected %d bits/pixel\n",
+              get_bits_per_pixel(par));
+       break;
+    }
+    spin_lock_irqsave(&fb_info->lock, flags);
+    writel(ge0ar.whole, GE0AR(fb_info));
+    spin_unlock_irqrestore(&fb_info->lock, flags);
+}
+
+
+/****
+ * set hardware cursor shape.
+ *
+ * [NOTE]
+ *     This function assume that cursor width is less than or equal to 64
+ *     pixels.
+ */
+static void
+set_cursor_shape(const struct mq200fb_info* fb_info)
+{
+    static int already_created;
+    static u32 cursor_images[2][256];
+    unsigned long flags;
+    u32 image;
+
+    if (! already_created) {
+       u16 and_bits[4], xor_bits[4];
+       u32 transparent = 0x0000FFFF;
+       int line, i;
+
+       /*
+        * set "CM_DRAW" cursor shape
+        */
+       image = fb_info->regions.v_fb + CURSOR_OFFSET;
+
+       /* inverse transparency */
+       for (i = 0; i < fb_info->cursor_info.size.x / 16; i++)
+           and_bits[i] = xor_bits[i] = ~0;
+       /* partially inverse transparency */
+       and_bits[i] = ~0;
+       xor_bits[i] = (u16)~0 >> (16 - fb_info->cursor_info.size.x % 16);
+       /* rest is transparent */
+       while (++i < 4) {
+           and_bits[i] = ~0;
+           xor_bits[i] = 0;
+       }
+
+       spin_lock_irqsave(&fb_info->lock, flags);
+       for (line = 0; line < fb_info->cursor_info.size.y; line++)
+           for (i = 0; i < 4; i++) {
+               writel(((u32)xor_bits[i] << 16) | (u32)and_bits[i], image);
+               image += 4;
+           }
+
+       while (line++ < 64)
+           for (i = 0; i < 4; i++) {
+               writel(transparent, image);
+               image += 4;
+           }
+
+       /*
+        * set "CM_ERASE" cursor shape
+        */
+       image = fb_info->regions.v_fb + CURSOR_OFFSET + 1024;
+       for (line = 0; line < 64; line++)
+           for (i = 0; i < 4; i++) {
+               writel(transparent, image);
+               image += 4;
+           }
+
+       /* save cursor images */
+       image = fb_info->regions.v_fb + CURSOR_OFFSET;
+       for (i = 0; i < 2; i++) {
+           int j;
+
+           for (j = 0; j < 256; j++, image += 4)
+               cursor_images[i][j] = readl(image);
+       }
+       spin_unlock_irqrestore(&fb_info->lock, flags);
+
+       already_created = 1;
+    }
+    else {
+       int i;
+
+       /* restore cursor images */
+       image = fb_info->regions.v_fb + CURSOR_OFFSET;
+
+       spin_lock_irqsave(&fb_info->lock, flags);
+       for (i = 0; i < 2; i++) {
+           int j;
+
+           for (j = 0; j < 256; j++, image += 4)
+               writel(cursor_images[i][j], image);
+       }
+       spin_unlock_irqrestore(&fb_info->lock, flags);
+    }
+}
+
+
+/****
+ * turn on hardware cursor.
+ */
+static void
+enable_cursor(struct mq200fb_info* fb_info)
+{
+    unsigned long flags;
+    union gc00r gc00r;
+
+    spin_lock_irqsave(&fb_info->lock, flags);
+    gc00r.whole = readl(GC00R(fb_info));
+    if (gc00r.part.hc_enbl == 0) {
+       set_cursor_shape(fb_info);
+
+       gc00r.part.hc_enbl = 1;
+       writel(gc00r.whole, GC00R(fb_info));
+    }
+    spin_unlock_irqrestore(&fb_info->lock, flags);
+}
+
+
+/****
+ * turn off hardware cursor.
+ */
+static void
+disable_cursor(struct mq200fb_info* fb_info)
+{
+    unsigned long flags;
+    union gc00r gc00r;
+
+    spin_lock_irqsave(&fb_info->lock, flags);
+    gc00r.whole = readl(GC00R(fb_info));
+    if (gc00r.part.hc_enbl == 1) {
+       gc00r.part.hc_enbl = 0;
+       writel(gc00r.whole, GC00R(fb_info));
+    }
+    spin_unlock_irqrestore(&fb_info->lock, flags);
+}
+
+
+/****
+ * Set current window's cursor position.
+ *
+ * [RETURN]
+ *     1: when cursor position has been moved.
+ */
+static int
+set_cursor_pos(const struct mq200fb_info* fb_info,
+              unsigned x,      /* horizontal pos in pixels */
+              unsigned y)      /* vertical pos in pixels */
+{
+    int ret;
+    unsigned long flags;
+    union gc10r gc10r;
+
+    spin_lock_irqsave(&fb_info->lock, flags);
+    gc10r.whole = readl(GC10R(fb_info));
+    if (gc10r.part.hc1s == x && gc10r.part.vc1s == y)
+       ret = 0;
+    else {
+       gc10r.whole = 0;
+       gc10r.part.hc1s = x;
+       gc10r.part.vc1s = y;
+       writel(gc10r.whole, GC10R(fb_info));
+
+       ret = 1;
+    }
+    spin_unlock_irqrestore(&fb_info->lock, flags);
+
+    return ret;
+}
+
+
+/****
+ * blink cursor.
+ */
+static void
+cursor_timer_handler(unsigned long data)
+{
+    unsigned long flags;
+    struct mq200fb_info* fb_info = (struct mq200fb_info*)data;
+    union gc11r gc11r;
+
+    spin_lock_irqsave(&fb_info->lock, flags);
+    gc11r.whole = readl(GC11R(fb_info));
+    if (gc11r.part.hc1sa == CURSOR_OFFSET >> 10)
+       gc11r.part.hc1sa += 1;
+    else
+       gc11r.part.hc1sa = CURSOR_OFFSET >> 10;
+    writel(gc11r.whole, GC11R(fb_info));
+    spin_unlock_irqrestore(&fb_info->lock, flags);
+
+    add_cursor_timer(&fb_info->cursor_info);
+}
+
+
+static void
+get_color_palette(const struct mq200fb_info* fb_info,
+                 unsigned indx,
+                 unsigned* red,
+                 unsigned* green,
+                 unsigned* blue)
+{
+    unsigned long flags;
+    union c1xxr c1xxr;
+
+    spin_lock_irqsave(&fb_info->lock, flags);
+    c1xxr.whole = readl(C1xxR(fb_info, indx));
+    spin_unlock_irqrestore(&fb_info->lock, flags);
+
+    *red = c1xxr.part.red;
+    *green = c1xxr.part.green;
+    *blue = c1xxr.part.blue;
+}
+
+
+static void
+set_color_palette(const struct mq200fb_info* fb_info,
+                 unsigned indx,
+                 unsigned red,
+                 unsigned green,
+                 unsigned blue)
+{
+    unsigned long flags;
+    union c1xxr c1xxr;
+
+    c1xxr.whole = 0;
+    c1xxr.part.red = red;
+    c1xxr.part.green = green;
+    c1xxr.part.blue = blue;
+
+    spin_lock_irqsave(&fb_info->lock, flags);
+    writel(c1xxr.whole, C1xxR(fb_info, indx));
+    spin_unlock_irqrestore(&fb_info->lock, flags);
+}
+
+
+/****
+ * enable CRT DAC.
+ */
+static void
+enable_dac(const struct mq200fb_info* fb_info)
+{
+    unsigned long flags;
+    union gc01r gc01r;
+
+    spin_lock_irqsave(&fb_info->lock, flags);
+    gc01r.whole = readl(GC01R(fb_info));
+    gc01r.part.dac_enbl = 1;
+    writel(gc01r.whole, GC01R(fb_info));
+    spin_unlock_irqrestore(&fb_info->lock, flags);
+}
+
+
+/****
+ * disable CRT DAC.
+ */
+static void
+disable_dac(const struct mq200fb_info* fb_info,
+           unsigned sync_mode) /* specify SYNC that output while DAC is
+                                  disabled */
+{
+    unsigned long flags;
+    union gc01r gc01r;
+
+    spin_lock_irqsave(&fb_info->lock, flags);
+    gc01r.whole = readl(GC01R(fb_info));
+    gc01r.part.dac_enbl = 0;
+    gc01r.part.hsync_out = (sync_mode & WITH_HSYNC) != 0;
+    gc01r.part.vsync_out = (sync_mode & WITH_VSYNC) != 0;
+    writel(gc01r.whole, GC01R(fb_info));
+    spin_unlock_irqrestore(&fb_info->lock, flags);
+}
+
+
+/****
+ * Return true if command FIFO .
+ */
+static int __inline__
+is_enough_cmd_fifo(const struct mq200fb_info* fb_info,
+                  int num)
+{
+    union cc01r cc01r;
+
+    cc01r.whole = readl(CC01R(fb_info));
+    return cc01r.part.cmd_fifo >= num;
+}
+
+
+/****
+ *
+ */
+static int __inline__
+is_enough_src_fifo(const struct mq200fb_info* fb_info,
+                  int num)
+{
+    union cc01r cc01r;
+
+    cc01r.whole = readl(CC01R(fb_info));
+    return cc01r.part.src_fifo >= num;
+}
+
+
+/****
+ * wait until command FIFO space is enough.
+ */
+static void
+wait_cmd_fifo(const struct mq200fb_info* fb_info,
+             int num)
+{
+    int i;
+
+    for (i = 0; i < 0x00100000; i++)
+       if (is_enough_cmd_fifo(fb_info, num))
+           return;
+    printk(CHIPNAME ": Command FIFO is full.\n");
+}
+
+
+/****
+ *
+ */
+static void
+wait_src_fifo(const struct mq200fb_info* fb_info,
+             int num)
+{
+    int i;
+
+    for (i = 0; i < 0x00100000; i++)
+       if (is_enough_src_fifo(fb_info, num))
+           return;
+    printk(CHIPNAME ": Source FIFO is full.\n");
+}
+
+
+/****************************************************************
+ *  Frame buffer operations
+ */
+
+/****
+ * rectangle fill (solid fill)
+ */
+static void
+ge_rect_fill(const struct mq200fb_info* fb_info,
+            int x,
+            int y,
+            int width,
+            int height,
+            u32 bgcol)
+{
+    unsigned long flags;
+    union ge01r ge01r;
+    union ge02r ge02r;
+    union ge00r ge00r;
+
+    ge01r.whole = 0;
+    ge01r.bitblt.width = width;
+    ge01r.bitblt.height = height;
+
+    ge02r.whole = 0;
+    ge02r.window.dst_x = x;
+    ge02r.window.dst_y = y;
+
+    ge00r.whole = 0;
+    ge00r.part.rop = ROP_PATCOPY;
+    ge00r.part.cmd_typ = 2;    /* BitBLT */
+    ge00r.part.mon_ptn = 1;
+    ge00r.part.sol_col = 1;
+
+    wait_cmd_fifo(fb_info, 4);
+    spin_lock_irqsave(&fb_info->lock, flags);
+    writel(ge01r.whole, GE01R(fb_info));
+    writel(ge02r.whole, GE02R(fb_info));
+    writel(bgcol, GE42R(fb_info));
+    writel(ge00r.whole, GE00R(fb_info));
+    spin_unlock_irqrestore(&fb_info->lock, flags);
+}
+
+
+#if 0
+/****
+ * bitblt screen to screen.
+ */
+static void
+ge_bitblt_scr_to_scr(const struct mq200fb_info* fb_info,
+                    int src_x,
+                    int src_y,
+                    int dst_x,
+                    int dst_y,
+                    int width,
+                    int height)
+{
+    unsigned long flags;
+    union ge00r ge00r;
+    union ge01r ge01r;
+    union ge02r ge02r;
+    union ge03r ge03r;
+
+    ge01r.whole = 0;
+    ge01r.bitblt.width = width;
+    ge01r.bitblt.height = height;
+
+    ge02r.whole = 0;
+    ge02r.window.dst_x = dst_x;
+    ge02r.window.dst_y = dst_y;
+
+    ge03r.whole = 0;
+    ge03r.window.src_x = src_x;
+    ge03r.window.src_y = src_y;
+
+    ge00r.whole = 0;
+    ge00r.part.rop = ROP_SRCCOPY;
+    ge00r.part.cmd_typ = 2;    /* BitBLT */
+    if (src_x >= dst_x) {
+       if (src_y < dst_y)
+           ge00r.part.y_dir = 1;
+    }
+    else if (src_y >= dst_y)
+       ge00r.part.x_dir = 1;
+    else {
+       ge00r.part.x_dir = 1;
+       ge00r.part.y_dir = 1;
+    }
+
+    wait_cmd_fifo(fb_info, 4);
+    spin_lock_irqsave(&fb_info->lock, flags);
+    writel(ge01r.whole, GE01R(fb_info));
+    writel(ge02r.whole, GE02R(fb_info));
+    writel(ge03r.whole, GE03R(fb_info));
+    writel(ge00r.whole, GE00R(fb_info));
+    spin_unlock_irqrestore(&fb_info->lock, flags);
+}
+#endif
+
+
+/****
+ * draw mono text image.
+ */
+static void
+ge_bitblt_char(const struct mq200fb_info* fb_info,
+              int dst_x, int dst_y,
+              u8* image,
+              int width, int height,
+              u32 fgcol, u32 bgcol) /* foreground and background color */
+{
+    unsigned long flags;
+    int i;
+    union ge00r ge00r;
+    union ge01r ge01r;
+    union ge02r ge02r;
+    union ge09r ge09r;
+    int offset = ((u32)image & 0x3) * 8;
+
+    ge01r.whole = 0;
+    ge01r.bitblt.width = width;
+    ge01r.bitblt.height = height;
+
+    ge02r.whole = 0;
+    ge02r.window.dst_x = dst_x;
+    ge02r.window.dst_y = dst_y;
+
+    ge09r.whole = 0;
+    ge09r.pack_mono.strt_bit = offset;
+    ge09r.pack_mono.amount = 0;
+    ge09r.pack_mono.bit_spc = 0;
+
+    ge00r.whole = 0;
+    ge00r.part.rop = ROP_SRCCOPY;
+    ge00r.part.cmd_typ = 2;    /* bitblt */
+    ge00r.part.src_mem = 1;
+    ge00r.part.mon_src = 1;
+    ge00r.part.mod_sel = 1;    /* packed mode */
+
+    wait_cmd_fifo(fb_info, 6);
+    spin_lock_irqsave(&fb_info->lock, flags);
+    writel(ge01r.whole, GE01R(fb_info));
+    writel(ge02r.whole, GE02R(fb_info));
+    writel(fgcol, GE07R(fb_info));
+   writel(bgcol, GE08R(fb_info));
+    writel(ge09r.whole, GE09R(fb_info));
+    writel(ge00r.whole, GE00R(fb_info));
+
+    /* ---- */
+    for (i = 0; i < height; i += 4) {
+       u32 src_data = *(u32*)(image + i);
+
+       wait_src_fifo(fb_info, 8);
+       writel(src_data, PSF(fb_info));
+    }
+    spin_unlock_irqrestore(&fb_info->lock, flags);
+}
+
+
+/****************************************************************
+ * Hardware Independent Functions.
+ */
+
+/****
+ *  Initialization
+ *
+ * [RETURN]
+ *         0: success
+ *     minus: fail
+ */
+int __init
+mq200fb_init(void)
+{
+#if 0
+    int irqval;
+#endif
+    memset(&mq200fb_info, 0, sizeof mq200fb_info);
+    mq200fb_info.current_par = mq200fb_options.par;
+    if (! mq200fb_conf(&mq200fb_info))
+       return -ENXIO;
+    mq200_reset(&mq200fb_info);
+
+    mq200fb_info.disp.scrollmode = SCROLL_YNOMOVE;
+    mq200fb_info.gen.parsize = sizeof(struct mq200fb_par);
+    mq200fb_info.gen.fbhw = &mq200_switch;
+    strcpy(mq200fb_info.gen.info.modename, CHIPNAME);
+    mq200fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
+    mq200fb_info.gen.info.fbops = &mq200fb_ops;
+    mq200fb_info.gen.info.disp = &mq200fb_info.disp;
+    strcpy(mq200fb_info.gen.info.fontname, mq200fb_options.font);
+    mq200fb_info.gen.info.switch_con = &fbgen_switch;
+    mq200fb_info.gen.info.updatevar = &fbgen_update_var;
+    mq200fb_info.gen.info.blank = &fbgen_blank;
+    spin_lock_init(&mq200fb_info.lock);
+
+    fbgen_get_var(&mq200fb_info.disp.var, -1, &mq200fb_info.gen.info);
+    fbgen_do_set_var(&mq200fb_info.disp.var, 1, &mq200fb_info.gen);
+    fbgen_set_disp(-1, &mq200fb_info.gen);
+    fbgen_install_cmap(0, &mq200fb_info.gen);
+    if (register_framebuffer(&mq200fb_info.gen.info) < 0) {
+       printk(KERN_ERR DEVICE_DRIVER_NAME ": unable to register.\n");
+       return -EINVAL;
+    }
+    printk(
+       KERN_INFO "fb%d: %s, using %uK of video memory.\n",
+       GET_FB_IDX(mq200fb_info.gen.info.node),
+       CHIPNAME,
+       (u32)(mq200fb_info.regions.fb_size >> 10)
+    );
+
+#if 0
+    if ((irqval = request_irq(MQ200_IRQ, mq200_interrupt, 0, CHIPNAME,
+                             NULL)) != 0) {
+       printk(CHIPNAME ": unable to get IRQ %d (irqval=%d).\n",
+              MQ200_IRQ, irqval);
+       return -EAGAIN;
+    }
+    mq200_enable_irq(&mq200fb_info);
+#endif
+
+    return 0;
+}
+
+
+/****
+ *  Cleanup
+ */
+void mq200fb_cleanup(struct fb_info *info)
+{
+    /*
+     *  If your driver supports multiple boards, you should unregister and
+     *  clean up all instances.
+     */
+
+    unregister_framebuffer(info);
+    /* ... */
+}
+
+
+/****
+ *  Setup
+ */
+int __init mq200fb_setup(char *options)
+{
+    /* Parse user speficied options (`video=mq200fb:') */
+    return 0;
+}
+
+
+/****
+ * add cursor timer to timer_list.
+ */
+static void
+add_cursor_timer(struct mq200fb_cursor_info* cursor_info)
+{
+    cursor_info->timer.expires = jiffies + CURSOR_BLINK_RATE;
+    add_timer(&cursor_info->timer);
+}
+
+
+/****************************************************************
+ *  Modularization
+ */
+
+#ifdef MODULE
+
+int
+init_module(void)
+{
+    return mq200fb_init();
+}
+
+
+void cleanup_module(void)
+{
+    mq200fb_cleanup(void);
+}
+#endif /* MODULE */
+
+
+/*
+ * Local variables:
+ *  c-basic-offset: 4
+ * End:
+ */
+
diff -urN linux-2.4.29/drivers/video/mq200fb.h linux-2.4.29-uc1/drivers/video/mq200fb.h
--- linux-2.4.29/drivers/video/mq200fb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/mq200fb.h	2005-06-14 02:12:27.000000000 +0100
@@ -0,0 +1,861 @@
+#ifndef __MQ200_FB_H__
+#define __MQ200_FB_H__
+
+#ifdef CONFIG_SH_KEYWEST
+#include <asm/hitachi_keywest.h>
+#endif
+
+
+/****
+ * Addresses of Module
+ */
+#define MQ200_FB_BASE  (MQ200_IOBASE + 0x1800000) /* framebuffer */
+#define MQ200_FB_SIZE 0x200000 /* framebuffer size in bytes */
+#define MQ200_REGS_BASE (MQ200_IOBASE + 0x1e00000) /* start of registers area */
+#define MQ200_REGS_SIZE 0x200000 /* registers area size */
+#define PMU_OFFSET 0x00000     /* power management */
+#define CPU_OFFSET 0x02000     /* CPU interface */
+#define MIU_OFFSET 0x04000     /* memory controller */
+#define IN_OFFSET  0x08000     /* interrupt controller */
+#define GC_OFFSET  0x0a000     /* graphics controller 1&2 */
+#define GE_OFFSET  0x0c000     /* graphics engine */
+#define FPI_OFFSET 0x0e000     /* flat panel controller */
+#define CP1_OFFSET 0x10000     /* color palette 1 */
+#define DC_OFFSET  0x14000     /* device configuration */
+#define PCI_OFFSET 0x16000     /* PCI configuration */
+#define PSF_OFFSET 0x18000     /* ??? */
+#define CURSOR_IMAGE_SIZE 2048 /* cursor image size */
+#define CURSOR_OFFSET (MQ200_FB_SIZE - CURSOR_IMAGE_SIZE) /* cursor image
+                                                            offset */
+
+
+/****
+ * Registers
+ */
+
+/* power management unit */
+#define PMR(fb_info) ((fb_info)->pci_base + 0x40)/* power management
+                                                   register */
+#define PMR_VALUE 0x06210001   /* expected read value of PMR register */
+#define PMCSR(fb_info) ((fb_info)->pci_base + 0x44) /* power management
+                                                      control/status
+                                                      register */
+#define PM00R(fb_info) ((fb_info)->pmu_base + 0x00) /* power management unit
+                                                      configuration
+                                                      register */
+#define PM01R(fb_info) ((fb_info)->pmu_base + 0x04) /* D1 state control */
+#define PM02R(fb_info) ((fb_info)->pmu_base + 0x08) /* d2 state control */
+#define PM06R(fb_info) ((fb_info)->pmu_base + 0x18) /* PLL 2 programming */
+#define PM07R(fb_info) ((fb_info)->pmu_base + 0x1c) /* PLL 3 programming */
+
+/* CPU interface */
+#define CC01R(fb_info) ((fb_info)->cpu_base + 0x04)/* source FIFO/command
+                                                     FIFO/GE status
+                                                     register */
+
+/* memory interface unit */
+#define MM00R(fb_info) ((fb_info)->miu_base + 0x00)/* MIU interface control
+                                                     1 */
+#define MM01R(fb_info) ((fb_info)->miu_base + 0x04) /* MIU interface control
+                                                      2 */
+#define MM02R(fb_info) ((fb_info)->miu_base + 0x08) /* memory itnerface
+                                                      control 3 */
+#define MM03R(fb_info) ((fb_info)->miu_base + 0x0c) /* memory interface
+                                                      control 4 */
+#define MM04R(fb_info) ((fb_info)->miu_base + 0x10) /* memory interface
+                                                      control 5 */
+
+/* interrupt controller */
+#define IN00R(fb_info) ((fb_info)->in_base + 0x00)/* global interrupt
+                                                    control register */
+#define IN01R(fb_info) ((fb_info)->in_base + 0x04) /* interrupt mask
+                                                     register */
+#define IN02R(fb_info) ((fb_info)->in_base + 0x08) /* interrupt status
+                                                     register */
+#define IN03R(fb_info) ((fb_info)->in_base + 0x0c) /* interrupt pin raw
+                                                     status */
+
+/* graphics controller 1 module */
+#define GC00R(fb_info) ((fb_info)->gc_base + 00)/* graphics controller 1
+                                                  control */
+enum {
+    /* color palette enabled */
+    GCD_1_CP, GCD_2_CP, GCD_4_CP, GCD_8_CP,
+    GCD_16_CP, GCD_24_CP, GCD_32_RGB_CP, GCD_32_BGR_CP,
+    /* coloer palette bypassed */
+    GCD_16 = 12, GCD_24, GCD_32_RGB, GCD_32_BGR
+};
+
+#define GC01R(fb_info) ((fb_info)->gc_base + 0x04) /* graphics controller
+                                                     CRT control */
+#define GC02R(fb_info) ((fb_info)->gc_base + 0x08) /* horizontal display 1
+                                                     control */
+#define GC03R(fb_info) ((fb_info)->gc_base + 0x0c) /* vertical display 1
+                                                     control */
+#define GC04R(fb_info) ((fb_info)->gc_base + 0x10) /* horizontal sync 1
+                                                     control */
+#define GC05R(fb_info) ((fb_info)->gc_base + 0x14) /* vertical sync 1
+                                                     control */
+#define GC07R(fb_info) ((fb_info)->gc_base + 0x1c) /* vertical display 1
+                                                     count */
+#define GC08R(fb_info) ((fb_info)->gc_base + 0x20) /* horizontal window 1
+                                                     control */
+#define GC09R(fb_info) ((fb_info)->gc_base + 0x24) /* vertical window 1
+                                                     control */
+#define GC0AR(fb_info) ((fb_info)->gc_base + 0x28) /* alternate horizontal
+                                                     window 1 control */
+#define GC0BR(fb_info) ((fb_info)->gc_base + 0x2c) /* alternate vertical
+                                                     window 1 control */
+#define GC0CR(fb_info) ((fb_info)->gc_base + 0x30) /* window 1 start address
+                                                   */
+#define GC0DR(fb_info) ((fb_info)->gc_base + 0x34) /* alternate window 1
+                                                     start address */
+#define GC0ER(fb_info) ((fb_info)->gc_base + 0x38) /* window 1 stride */
+#define GC0FR(fb_info) ((fb_info)->gc_base + 0x3c) /* reserved */
+#define GC10R(fb_info) ((fb_info)->gc_base + 0x40) /* hardware cursor 1
+                                                     position */
+#define GC11R(fb_info) ((fb_info)->gc_base + 0x44) /* hardware cursor 1
+                                                     start address and
+                                                     offset */
+#define GC12R(fb_info) ((fb_info)->gc_base + 0x48) /* hardware cursor 1
+                                                     foreground color */
+#define GC13R(fb_info) ((fb_info)->gc_base + 0x4c) /* hardware cursor 1
+                                                     background color */
+
+/* graphics engine */
+#define GE00R(fb_info) ((fb_info)->ge_base + 0x00)/* primary drawing command
+                                                    register */
+#define ROP_SRCCOPY    0xCC    /* dest = source */
+#define ROP_SRCPAINT   0xEE    /* dest = source OR dest */
+#define ROP_SRCAND     0x88    /* dest = source AND dest */
+#define ROP_SRCINVERT  0x66    /* dest = source XOR dest */
+#define ROP_SRCERASE   0x44    /* dest = source AND (NOT dest) */
+#define ROP_NOTSRCCOPY 0x33    /* dest = NOT source */
+#define ROP_NOTSRCERASE        0x11    /* dest = (NOT source) AND (NOT dest) */
+#define ROP_MERGECOPY  0xC0    /* dest = source AND pattern */
+#define ROP_MERGEPAINT 0xBB    /* dest = (NOT source) OR dest */
+#define ROP_PATCOPY    0xF0    /* dest = pattern */
+#define ROP_PATPAINT   0xFB    /* dest = DPSnoo */
+#define ROP_PATINVERT  0x5A    /* dest = pattern XOR dest */
+#define ROP_DSTINVERT  0x55    /* dest = NOT dest */
+#define ROP_BLACKNESS  0x00    /* dest = BLACK */
+#define ROP_WHITENESS  0xFF    /* dest = WHITE */
+#define GE01R(fb_info) ((fb_info)->ge_base + 0x04) /* primary width and
+                                                     height register */
+#define GE02R(fb_info) ((fb_info)->ge_base + 0x08) /* primary destination
+                                                     address register */
+#define GE03R(fb_info) ((fb_info)->ge_base + 0x0c) /* primary source XY
+                                                     register */
+#define GE04R(fb_info) ((fb_info)->ge_base + 0x10) /* primary color compare
+                                                     register */
+#define GE05R(fb_info) ((fb_info)->ge_base + 0x14) /* primary clip left/top
+                                                     register */
+#define GE06R(fb_info) ((fb_info)->ge_base + 0x18) /* primary clip
+                                                     right/bottom register
+                                                  */
+#define GE07R(fb_info) ((fb_info)->ge_base + 0x1c) /* primary source and
+                                                     pattern offset
+                                                     register */
+#define GE08R(fb_info) ((fb_info)->ge_base + 0x20) /* primary foreground
+                                                     color
+                                                     register/rectangle
+                                                     fill register */
+#define GE09R(fb_info) ((fb_info)->ge_base + 0x24) /* source stride/offset
+                                                     register */
+#define GE0AR(fb_info) ((fb_info)->ge_base + 0x28) /* destination stride
+                                                     register and color
+                                                     depth */
+#define GE0BR(fb_info) ((fb_info)->ge_base + 0x2c) /* image base address
+                                                     register */
+#define GE40R(fb_info) ((fb_info)->ge_base + 0x100) /* mono pattern register
+                                                      0 */
+#define GE41R(fb_info) ((fb_info)->ge_base + 0x104) /* mono pattern register
+                                                      1 */
+#define GE42R(fb_info) ((fb_info)->ge_base + 0x108) /* foreground color
+                                                      register */
+#define GE43R(fb_info) ((fb_info)->ge_base + 0x10c) /* background color
+                                                      register */
+
+/* color palette */
+#define C1xxR(fb_info, regno) \
+       ((fb_info)->cp1_base + (regno) * 4) /* graphics controller color
+                                              palette 1 */
+
+/* device configuration */
+#define DC00R(fb_info) ((fb_info)->dc_base + 0x00)/* device configuration
+                                                    register 0 */
+
+/* PCI configuration space */
+#define PC00R(fb_info) ((fb_info)->pci_base + 0x00)/* device ID/vendor ID
+                                                     register */
+#define PC00R_VALUE 0x02004d51
+#define PC04R(fb_info) ((fb_info)->pci_base + 0x04) /* command/status
+                                                      register */
+
+/* ??? */
+#define PSF(fb_info) ((fb_info)->psf_base + 0x00)
+
+
+/****
+ * structure declarations
+ */
+
+
+/* power management miscellaneous control */
+union pm00r {
+    struct {
+       u32 pll1_n_b5   :1;     /* PLL 1 N parameter bit 5 is 0 */
+       u32 reserved_1  :1;
+       u32 pll2_enbl   :1;     /* PLL 2 enable */
+       u32 pll3_enbl   :1;     /* PLL 3 enable */
+       u32 reserved_2  :1;
+       u32 pwr_st_ctrl :1;     /* power state status control */
+       u32 reserved_3  :2;
+
+       u32 ge_enbl     :1;     /* graphics engine enable */
+       u32 ge_bsy_gl   :1;     /* graphics engine force busy (global) */
+       u32 ge_bsy_lcl  :1;     /* graphics engine force busy (local) */
+       u32 ge_clock    :2;     /* graphics engine clock select */
+       u32 ge_cmd_fifo :1;     /* graphics engine command FIFO reset */
+       u32 ge_src_fifo :1;     /* graphics engine CPU source FIFO reset */
+       u32 miu_pwr_seq :1;     /* memory interface unit power sequencing
+                                  enable */
+
+       u32 d3_mem_rfsh :1;     /* D3 memory refresh */
+       u32 d4_mem_rfsh :1;     /* D4 memory refresh */
+       u32 gpwr_intrvl :2;     /* general power sequencing interval */
+       u32 fppwr_intrvl:2;     /* flat panel power sequencing interval */
+       u32 gpwr_seq_ctr:1;     /* general power sequencing interval control */
+       u32 pmu_tm      :1;     /* PMU test mode */
+
+       u32 pwr_state   :2;     /* power state (read only) */
+       u32 pwr_seq_st  :1;     /* power sequencing active status (read
+                                  only) */
+       u32 reserved_4  :5;
+    }  part;
+    u32 whole;
+};
+
+/* D1 state control */
+union pm01r {
+    struct {
+       u32 osc_enbl    :1;     /* D1 oscillator enable */
+       u32 pll1_enbl   :1;     /* D1 PLL 1 enable */
+       u32 pll2_enbl   :1;     /* D1 PLL 2 enable */
+       u32 pll3_enbl   :1;     /* D1 PLL 3 enable */
+       u32 miu_enbl    :1;     /* D1 Memory Interface Unit (MIU) enable */
+       u32 mem_rfsh    :1;     /* D1 memory refresh enable */
+       u32 ge_enbl     :1;     /* D1 Graphics Engine (GE) enable */
+       u32 reserved_1  :1;
+
+       u32 crt_enbl    :1;     /* D1 CRT enable */
+       u32 fpd_enbl    :1;     /* D1 Flat Panel enable */
+       u32 reserved_2  :6;
+
+       u32 ctl1_enbl   :1;     /* D1 controller 1 enable */
+       u32 win1_enbl   :1;     /* D1 window 1 enable */
+       u32 awin1_enbl  :1;     /* D1 alternate window 1 enable */
+       u32 cur1_enbl   :1;     /* D1 cursor 1 enable */
+      u32 reserved_3  :4;
+
+       u32 ctl2_enbl   :1;     /* D1 controller 2 enable */
+       u32 win2_enbl   :1;     /* D1 window 2 enable */
+       u32 awin2_enbl  :1;     /* D1 alternate window 2 enable */
+       u32 cur2_enbl   :1;     /* D1 cursor 2 enable */
+       u32 reserved_4  :4;
+    }  part;
+    u32 whole;
+};
+
+/* D2 state control */
+union pm02r {
+    struct {
+       u32 osc_enbl    :1;     /* D2 oscillator enable */
+       u32 pll1_enbl   :1;     /* D2 PLL 1 enable */
+       u32 pll2_enbl   :1;     /* D2 PLL 2 enable */
+       u32 pll3_enbl   :1;     /* D2 PLL 3 enable */
+       u32 miu_enbl    :1;     /* D2 Memory Interface Unit (MIU) enable */
+       u32 mem_rfsh    :1;     /* D2 memory refresh enable */
+       u32 ge_enbl     :1;     /* D2 Graphics Engine (GE) enable */
+       u32 reserved_1  :1;
+
+       u32 crt_enbl    :1;     /* D2 CRT enable */
+       u32 fpd_enbl    :1;     /* D2 Flat Panel enable */
+       u32 reserved_2  :6;
+
+       u32 ctl1_enbl   :1;     /* D2 controller 1 enable */
+       u32 win1_enbl   :1;     /* D2 window 1 enable */
+       u32 awin1_enbl  :1;     /* D2 alternate window 1 enable */
+       u32 cur1_enbl   :1;     /* D2 cursor 1 enable */
+       u32 reserved_3  :4;
+
+       u32 ctl2_enbl   :1;     /* D2 controller 2 enable */
+       u32 win2_enbl   :1;     /* D2 window 2 enable */
+       u32 awin2_enbl  :1;     /* D2 alternate window 2 enable */
+       u32 cur2_enbl   :1;     /* D2 cursor 2 enable */
+       u32 reserved_4  :4;
+    }  part;
+    u32 whole;
+};
+
+/* PLL 2 programming */
+union pm06r {
+    struct {
+       u32 clk_src     :1;     /* PLL 2 reference clock source */
+       u32 bypass      :1;     /* PLL 2 bypass */
+       u32 reserved_1  :2;
+       u32 p_par       :3;     /* PLL 2 P parameter */
+       u32 reserved_2  :1;
+
+       u32 n_par       :5;     /* PLL 2 N parameter */
+       u32 reserved_3  :3;
+
+       u32 m_par       :8;     /* PLL 2 M parameter */
+
+       u32 reserved_4  :4;
+       u32 trim        :4;     /* PLL 2 trim value */
+    }  part;
+    u32 whole;
+};
+
+/* PLL 3 programming */
+union pm07r {
+    struct {
+       u32 clk_src     :1;     /* PLL 3 reference clock source */
+       u32 bypass      :1;     /* PLL 3 bypass */
+       u32 reserved_1  :2;
+       u32 p_par       :3;     /* PLL 3 P parameter */
+       u32 reserved_2  :1;
+
+       u32 n_par       :5;     /* PLL 3 N parameter */
+       u32 reserved_3  :3;
+
+       u32 m_par       :8;     /* PLL 3 M parameter */
+
+       u32 reserved_4  :4;
+       u32 trim        :4;     /* PLL 3 trim value */
+    }  part;
+    u32 whole;
+};
+
+/* source FIFO/command FIFO/GE status register */
+union cc01r {
+    struct {
+       u32 cmd_fifo    :5;     /* command FIFO status register */
+       u32 reserved_1  :3;
+
+       u32 src_fifo    :4;     /* source FIFO status register */
+       u32 reserved_2  :4;
+
+       u32 ge_busy     :1;     /* GE is busy */
+       u32 reserved_3  :7;
+
+       u32 reserved_4  :8;
+    }  part;
+    u32 whole;
+};
+
+/* MIU interface control 1 */
+union mm00r {
+    struct {
+       u32 miu_enbl    :1;     /* MIU enable bit */
+       u32 mr_dsbl     :1;     /* MIU reset disable bit */
+       u32 edr_dsbl    :1;     /* embedded DRAM reset disable bit */
+       u32 reserved_1  :29;
+    }  part;
+    u32 whole;
+};
+
+/* MIU interface control 2 */
+union mm01r {
+    struct {
+       u32 mc_src      :1;     /* memory clock source */
+       u32 msr_enbl    :1;     /* memory slow refresh enable bit */
+       u32 pb_cpu      :1;     /* page break enable for CPU */
+       u32 pb_gc1      :1;     /* page break enable for GC1 */
+       u32 pb_gc2      :1;     /* page break enable for GC2 */
+       u32 pb_stn_r    :1;     /* page break enable for STN read */
+       u32 pb_stn_w    :1;     /* page break enable for STN write */
+       u32 pb_ge       :1;     /* page break enable for GE */
+       u32 reserved_1  :4;
+       u32 mr_interval :14;    /* normal memory refresh time interval */
+       u32 reserved_2  :4;
+       u32 edarm_enbl  :1;     /* embedded DRAM auto-refresh mode enable */
+       u32 eds_enbl    :1;     /* EDRAM standby enable for EDRAM normal
+                                  mode operation */
+    }  part;
+    u32 whole;
+};
+
+/* memory interface control 3 */
+union mm02r {
+    struct {
+       u32 bs_         :2;
+       u32 bs_stnr     :2;     /* burst count for STN read memory cycles */
+       u32 bs_stnw     :2;     /* burst count for STN write memroy cycles */
+       u32 bs_ge       :2;     /* burst count for graphics engine
+                                  read/write memroy cycles */
+       u32 bs_cpuw     :2;     /* burst count for CPU write memory cycles */
+       u32 fifo_gc1    :4;     /* GC1 display refresh FIFO threshold */
+       u32 fifo_gc2    :4;     /* GC2 display refresh FIFO threshold */
+       u32 fifo_stnr   :4;     /* STN read FIFO threshold */
+       u32 fifo_stnw   :4;     /* STN write FIFO threshold */
+       u32 fifo_ge_src :3;     /* GE source read FIFO threshold */
+       u32 fifo_ge_dst :3;     /* GE destination read FIFO threshold */
+    }  part;
+    u32 whole;
+};
+
+/* memory interface control 4 */
+union mm03r {
+    struct {
+       u32 rd_late_req :1;     /* read latency request */
+       u32 reserved_1  :31;
+    }  part;
+    u32 whole;
+};
+
+/* memory interface control 5 */
+union mm04r {
+    struct {
+       u32 latency     :3;     /* EDRAM latency */
+       u32 dmm_cyc     :1;     /* enable for the dummy cycle insertion
+                                  between read and write cycles */
+       u32 pre_dmm_cyc :1;     /* enable for the dummy cycle insertion
+                                  between read/write and precharge cycles
+                                  for the same bank */
+       u32 reserved_1  :3;
+       u32 bnk_act_cls :2;     /* bank activate command to bank close
+                                  command timing interval control */
+       u32 bnk_act_rw  :1;     /* bank activate command to read/wirte
+                                  command timing interval control */
+       u32 bnk_cls_act :1;     /* bank close command to bank activate
+                                  command timing interval control */
+       u32 trc         :1;     /* row cycle time */
+       u32 reserved_2  :3;
+       u32 delay_r     :2;     /* programmable delay for read clock */
+       u32 delay_m     :2;     /* programmable delay for internal memory
+                                  clock */
+    }  part;
+    u32 whole;
+};
+
+/* graphics controller 1 register */
+union gc00r {
+    struct {
+       u32 ctl_enbl    :1;     /* Controller 1 Enable */
+       u32 hc_reset    :1;     /* Horizontal Counter 1 Reset */
+       u32 vc_reset    :1;     /* Vertical Counter 1 Reset */
+       u32 iwin_enbl   :1;     /* Image Window 1 Enable */
+       u32 gcd         :4;     /* Graphics Color Depth (GCD) */
+
+       u32 hc_enbl     :1;     /* Hardware Cursor 1 Enable */
+       u32 reserved_1  :2;
+       u32 aiwin_enbl  :1;     /* Alternate Image Window Enable */
+       u32 agcd        :4;     /* Alternate Graphics Color Depth (AGCD) */
+
+       u32 g1rclk_src  :2;     /* G1RCLK Source */
+       u32 tm0         :1;     /* Test Mode 0 */
+       u32 tm1         :1;     /* Test Mode 1 */
+       u32 fd          :3;     /* G1MCLK First Clock Divisor (FD1) */
+       u32 reserved_2  :1;
+
+       u32 sd          :8;     /* G1MCLK Second Clock Divisor (SD1) */
+    }  part;
+    u32 whole;
+};
+
+/* graphics controller CRT control */
+union gc01r {
+    struct {
+       u32 dac_enbl    :2;     /* CRT DAC enable */
+       u32 hsync_out   :1;     /* CRT HSYNC output during power down mode */
+       u32 vsync_out   :1;     /* CRT VSYNC output during power down mode */
+       u32 hsync_ctl   :2;     /* CRT HSYNC control */
+       u32 vsync_ctl   :2;     /* CRT VSYNC control */
+       /**/
+       u32 hsync_pol   :1;     /* CRT HSYNC polarity */
+       u32 vsync_pol   :1;     /* CRT VSYNC polarity */
+       u32 sync_p_enbl :1;     /* sync pedestal enable */
+       u32 blnk_p_enbl :1;     /* blank pedestal enable */
+       u32 c_sync_enbl :1;     /* composite sync enable */
+       u32 vref_sel    :1;     /* VREF select */
+       u32 mn_sns_enbl :1;     /* monitor sense enable */
+       u32 ct_out_enbl :1;     /* constant output enable */
+       /**/
+       u32 dac_out_lvl :8;     /* monitor sense DAC output level */
+       /**/
+       u32 blue_dac_r  :1;     /* blue DAC sense result */
+       u32 green_dac_r :1;     /* green DAC sense result */
+       u32 red_dac_r   :1;     /* red DAC sense result */
+       u32 reserved_1  :1;
+       u32 mon_col_sel :1;     /* mono/color monitor select */
+       u32 reserved_2  :3;
+    }  part;
+    u32 whole;
+};
+
+/* horizontal display 1 control */
+union gc02r {
+    struct {
+       u32 hd1t        :12;    /* horizontal display 1 total */
+       u32 reserved_1  :4;
+
+       u32 hd1e        :12;    /* horizontal display 1 end */
+       u32 reserved_2  :4;
+    }  part;
+    u32 whole;
+};
+
+/* vertical display 1 control */
+union gc03r {
+    struct {
+       u32 vd1t        :12;    /* vertical display 1 total */
+       u32 reserved_1  :4;
+
+       u32 vd1e        :12;    /* vertical display 1 end */
+       u32 reserved_2  :4;
+    }  part;
+    u32 whole;
+};
+
+/* horizontal sync 1 control */
+union gc04r {
+    struct {
+       u32 hs1s        :12;    /* horizontal sync 1 start */
+       u32 reserved_1  :4;
+
+       u32 hs1e        :12;    /* horizontal sync 1 end */
+       u32 reserved_2  :4;
+    }  part;
+    u32 whole;
+};
+
+/* vertical sync 1 control */
+union gc05r {
+    struct {
+       u32 vs1s        :12;    /* vertical sync 1 start */
+       u32 reserved_1  :4;
+
+       u32 vs1e        :12;    /* vertical sync 1 end */
+       u32 reserved_2  :4;
+    }  part;
+    u32 whole;
+};
+
+/* vertical display 1 count */
+union gc07r {
+    struct {
+       u32 vd_cnt      :12;    /* vertical display 1 count */
+       u32 reverved_1  :20;
+    }  part;
+    u32 whole;
+};
+
+/* horizontal window 1 control */
+union gc08r {
+    struct {
+       u32 hw1s        :12;    /* horizontal window 1 start (HW1S) */
+       u32 reserved_1  :4;
+
+       u32 hw1w        :12;    /* horizontal window 1 width (HW1W) */
+       u32 w1ald       :4;     /* window 1 additional line data */
+    }  part;
+    u32 whole;
+};
+
+/* vertical window 1 control */
+union gc09r {
+    struct {
+       u32 vw1s        :12;    /* vertical window 1 start */
+       u32 reserved_1  :4;
+       u32 vw1h        :12;    /* vertical window 1 height */
+       u32 reserved_2  :4;
+    }  part;
+    u32 whole;
+};
+
+/* window 1 start address */
+union gc0cr {
+    struct {
+       u32 w1sa        :21;    /* window 1 start address */
+       u32 reserved_1  :11;
+    }  part;
+    u32 whole;
+};
+
+/* window 1 stride */
+union gc0er {
+    struct {
+       s16 w1st;               /* window 1 stride */
+       s16 aw1st;              /* alternate window 1 stride */
+    }  part;
+    u32 whole;
+};
+
+/* hardware cursor 1 position */
+union gc10r {
+    struct {
+       u32 hc1s        :12;    /* horizontal cursor 1 start */
+       u32 reserved_1  :4;
+       u32 vc1s        :12;    /* vertical cursor 1 start */
+       u32 reserved_2  :4;
+    }  part;
+    u32 whole;
+};
+
+/* hardware cursor 1 start address and offset */
+union gc11r {
+    struct {
+       u32 hc1sa       :11;    /* hardware cursor 1 start address */
+       u32 reserved_1  :5;
+       u32 hc1o        :6;     /* horizontal cursor 1 offset */
+       u32 reserved_2  :2;
+       u32 vc1o        :6;     /* vertical cursor 1 offset */
+       u32 reserved_3  :2;
+    }  part;
+    u32 whole;
+};
+
+/* hardware cursor 1 foreground color */
+union gc12r {
+    struct {
+       u32 hc1fc       :24;    /* hardware cursor 1 foreground color */
+       u32 reserved_1  :8;
+    }  part;
+    u32 whole;
+};
+
+/* hardware cursor 1 background color */
+union gc13r {
+    struct {
+       u32 hc1bc       :24;    /* hardware cursor 1 background color */
+       u32 reserved_1  :8;
+    }  part;
+    u32 whole;
+};
+
+/* graphics controller color pallete */
+union c1xxr {
+    struct {
+       u8 red;                 /* red color pallete */
+       u8 green;               /* green/gray color pallete */
+       u8 blue;                /* blue color palette */
+       u8 reserved_1;
+    }  part;
+    u32 whole;
+};
+
+/* devicee configuration register 0 */
+union dc00r {
+    struct {
+       u32 osc_bypass  :1;     /* oscillator bypass */
+       u32 osc_enbl    :1;     /* oscillator enable */
+       u32 pll1_bypass :1;     /* PLL1 bypass */
+       u32 pll1_enbl   :1;     /* PLL1 enable */
+       u32 pll1_p_par  :3;     /* PLL1 P parameter */
+       u32 cpu_div     :1;     /* CPU interface clock divisor */
+       u32 pll1_n_par  :5;     /* PLL1 N parameter */
+       u32 saisc       :1;     /* StrongARM interface synchronizer control */
+       u32 s_chp_reset :1;     /* software chip reset */
+       u32 mem_enbl    :1;     /* memory standby enable */
+       u32 pll1_m_par  :8;     /* PLL 1 M parameter */
+       u32 osc_shaper  :1;     /* oscillator shaper disable */
+       u32 fast_pwr    :1;     /* fast power sequencing */
+       u32 osc_frq     :2;     /* oscillator frequency select */
+       u32 pll1_trim   :4;     /* PLL 1 trim value */
+    }  part;
+    u32 whole;
+};
+
+/* primary drawing command register */
+union ge00r {
+    struct {
+       u32 rop         :8;     /* raster operation */
+       /**/
+       u32 cmd_typ     :3;     /* command type */
+       u32 x_dir       :1;     /* x direction */
+       u32 y_dir       :1;     /* y direction */
+       u32 src_mem     :1;     /* source memory */
+       u32 mon_src     :1;     /* mono source */
+       u32 mon_ptn     :1;     /* mono pattern */
+       /**/
+       u32 dst_trns_e  :1;     /* destination transparency enable */
+       u32 dst_trns_p  :1;     /* destination transparency polarity */
+       u32 mon_trns_e  :1;     /* mono source or mono pattern transparency
+                                  enable */
+       u32 mon_trns_p  :1;     /* mono transparency polarity */
+       u32 mod_sel     :1;     /* memory to screen or off screen to screen
+                                  mode select */
+       u32 alpha_sel   :2;     /* Alpha byte mask selection */
+       u32 sol_col     :1;     /* solid color */
+       /**/
+       u32 stride_eq   :1;     /* source stride is equal to destination
+                                  stride */
+       u32 rop2_sel    :1;     /* ROP2 code selection */
+       u32 clipping    :1;     /* enable clipping */
+       u32 auto_exec   :1;     /* auto execute */
+       u32 reserved_1  :4;
+    }  part;
+    u32 whole;
+};
+
+/* primary width and height register */
+union ge01r {
+    struct {
+       u32 width       :12;    /* source/destination window width */
+       u32 reserved_1  :4;
+
+       u32 height      :12;    /* source/destination window height */
+       u32 reserved_2  :1;
+       u32 reserved_3  :3;
+    }  bitblt;
+    struct {
+       u32 dm          :17;
+       u32 axis_major  :12;
+       u32 x_y         :1;     /* x-major or y-major */
+       u32 last_pix    :1;     /* decision to draw or not to draw the last
+                                  pixel of the line */
+       u32 reserved_1  :1;
+    }  bresenham;
+    u32 whole;
+};
+
+/* primary destination address register */
+union ge02r {
+    struct {
+       u32 dst_x       :12;    /* destination x position */
+       u32 reserved_1  :1;
+       u32 h_offset    :3;     /* mono/color pattern horizontal offset */
+
+       u32 dst_y       :12;    /* destination y position */
+       u32 reserved_2  :1;
+       u32 v_offset    :3;     /* mono/color pattern vertical offset */
+    }  window;
+    struct {
+       u32 x           :12;    /* starting x coordinate */
+       u32 dm          :17;    /* 17 bits major-axis delta */
+       u32 reserved_1  :3;
+    }  line;
+    u32 whole;
+};
+
+/* source XY register/line draw starting Y coordinate and mintor axis delta */
+union ge03r {
+    struct {
+       u32 src_x       :12;    /* source X position */
+       u32 reserved_1  :4;
+
+       u32 src_y       :12;    /* source Y position */
+       u32 reserved_2  :4;
+    }  window;
+    struct {
+       u32 start_y     :12;    /* starting Y coordinate */
+       u32 dn          :17;    /* 17 bits minor-axis delta */
+       u32 reserved_1  :3;
+    }  line;
+    u32 whole;
+};
+
+/* clip left/top register */
+union ge05r {
+    struct {
+       u32 left        :12;    /* left edge of clipping rectangle */
+       u32 reserved_1  :4;
+
+       u32 top         :12;    /* top edge of clipping rectangle */
+       u32 reserved_2  :4;
+    }  part;
+    u32 whole;
+};
+
+/* source stride/offset register */
+union ge09r {
+    struct {
+       u32 src_strid   :12;    /* source line stride */
+       u32 reserved_1  :13;
+       u32 strt_bit    :3;     /* initial mono source bit offset */
+       u32 strt_byte   :3;     /* initial mono/color source byte offset */
+       u32 reserved_2  :1;
+    }  line;
+    struct {
+       u32 strt_bit    :5;     /* initial mono source bit offset */
+       u32 reserved_1  :1;
+       u32 amount      :10;    /* number of 16 bytes amount that MIU need
+                                  to fetch from frame buffer */
+
+       u32 reserved_2  :9;
+       u32 bit_spc     :7;     /* bit space between lines */
+    }  pack_mono;
+    struct {
+       u32 strt_bit    :3;     /* initial mono source bit offset */
+       u32 strt_byte   :3;     /* initial mono/color source byte offset */
+       u32 amount      :10;    /* number of 16 bytes amount that MIU need
+                                  to fetch from frame buffer */
+
+       u32 reserved_1  :9;
+       u32 bit_spc     :3;     /* bit space between lines */
+       u32 byt_spc     :4;     /* byte space between lines */
+    }  pack_color;
+    u32 whole;
+};
+
+/* destination stride register and color depth */
+union ge0ar {
+    struct {
+       u32 dst_strid   :12;    /* destination line stride and color depth */
+       u32 reserved_1  :18;
+       u32 col_dpth    :2;     /* color depth */
+    }  part;
+    u32 whole;
+};
+
+/* device ID/vendor ID register */
+union pc00r {
+    struct {
+       u16 device;             /* device ID */
+       u16 vendor;             /* vendor ID */
+    }  part;
+    u32 whole;
+};
+
+/* command/status register */
+union pc04r {
+    struct {
+       /* command register */
+       u32 io_spc      :1;     /* IO space control */
+       u32 mem_spc     :1;     /* memory space control */
+       u32 bus_master  :1;     /* bus master control */
+       u32 special_cyc :1;     /* special cycle */
+       u32 mem_w_invld :1;     /* memory write and invalidate */
+       u32 vga_palette :1;     /* VGA palette snoop */
+       u32 parity_chk  :1;     /* parity error checking enable */
+       u32 adr_dat_stp :1;     /* address/data stepping */
+       u32 serr_enbl   :1;     /* SERR# enable */
+       u32 reserved_1  :7;
+       /* status register */
+       u32 reserved_2  :5;
+       u32 mhz_66      :1;     /* 66 MHz capability */
+       u32 usr_def     :1;     /* user definable features supported */
+       u32 fast_b_b    :1;     /* fast back-to-back capability */
+       u32 reserved_3  :1;
+       u32 devsel_tim  :2;     /* DEVSEL timing */
+       u32 sig_tgt_abt :1;     /* signaled target abort */
+       u32 reserved_4  :2;
+       u32 serr_assert :1;     /* SERR# assertion */
+       u32 parity_dtct :1;     /* parity error detect */
+    }  part;
+    u32 whole;
+};
+
+
+/****
+ * Others
+ */
+
+#define CHIPNAME "MQ-200"
+#define DEVICE_DRIVER_NAME "mq200fb"
+#define CURSOR_BLINK_RATE (HZ * 20 / 100)
+
+
+#endif
diff -urN linux-2.4.29/drivers/video/s1d13706fb.c linux-2.4.29-uc1/drivers/video/s1d13706fb.c
--- linux-2.4.29/drivers/video/s1d13706fb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/s1d13706fb.c	2005-06-14 02:12:26.000000000 +0100
@@ -0,0 +1,964 @@
+/*
+ * linux/drivers/video/s1d13706fb.c
+ *	-- Support for the Epson S1D13706 LCD/CRT controller
+ *
+ * Copyright (C) 2003 Heiko Degenhardt <linux@sentec-elektronik.de>
+ *                    Michael Huhn <michael.huhn@sentec-elektronik.de>
+ *  
+ * based on linux/drivers/video/skeletonfb.c, which was
+ *  Created 28 Dec 1997 by Geert Uytterhoeven
+ *
+ * Some ideas were "stolen" from 
+ *    linux/drivers/video/epson1355fb.c
+ *    that is "Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>"
+ * and from s1d13xxxfb.c and a file called "s1d13706.h" that was
+ *    generated by S1D13706CFG.EXE both are
+ *    "Copyright(c) 2000, 2001 Epson Research and Development, Inc"
+ *
+ * HINT: If someone feels that we used his code but didn't give him
+ * credits here, please email us! It was a quite complicated thing to
+ * get all that working, so may be we just forgot someone! Thanks!
+ *  
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ * 
+ */
+
+/*
+ * CHANGES
+ *
+ * 20030312 
+ *    Creation
+ *    (mihu, hede)
+ */
+
+/*
+ * 
+ * ATTENTION!
+ * This stuff is _really_ experimental, currently!
+ * Feedback is really welcome!
+ *
+ */
+
+/* define DBUG below if you want to get more verbose output of the
+   driver */
+/*#define DBUG*/
+
+#include <asm/io.h>
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-mfb.h>
+#include <video/fbcon.h>
+
+#include <asm/coldfire.h>
+
+/*
+ -----------------------------------------------------------------------------
+
+   Sanity checks
+
+ -----------------------------------------------------------------------------
+*/
+
+/* Are you compiling for our board?
+ * If not I think you know how to solve the error. ;) 
+ */
+#ifdef CONFIG_COBRA5272
+
+/* S1D13706 supports 4Bpp, 8Bpp, 16Bpp */
+#ifdef CONFIG_FB_S1D13706
+    #if defined (FBCON_HAS_CFB4) && defined (FBCON_HAS_CFB8)
+        #error More than one colordepth specified
+    #endif
+    #if defined (FBCON_HAS_CFB4) && defined (FBCON_HAS_CFB16)
+        #error More than one colordepth specified
+    #endif
+    #if defined (FBCON_HAS_CFB8) && defined (FBCON_HAS_CFB16)
+        #error More than one colordepth specified
+    #endif
+#include "s1d13706fb.h"
+#else
+	#error lcd controller not supported
+#endif
+
+
+/* Check if at least one supported colordepth was configured */
+#if !defined (FBCON_HAS_CFB4) && !defined (FBCON_HAS_CFB8) && \
+    !defined (FBCON_HAS_CFB16)
+    #error No colordepth specified
+#endif
+
+
+static inline u8 s1d13706_read_reg(int index)
+{
+	return readb(S1D13706_REG_OFFSET + index);
+}
+
+static inline void s1d13706_write_reg(u8 data, int index)
+{
+	writeb(data, S1D13706_REG_OFFSET + index);
+}
+
+static inline u16 s1d13706_read_reg16(int index)
+{
+	return s1d13706_read_reg(index) + (s1d13706_read_reg(index+1) << 8);
+}
+
+static inline void s1d13706_write_reg16(u16 data, int index)
+{
+	s1d13706_write_reg((data&0xff), index);
+	s1d13706_write_reg(((data>>8)&0xff), index + 1);
+}
+#else /* not on the COBRA5272 board */
+#error unknown architecture
+#endif
+
+
+static int current_par_valid = 0;
+
+static struct display disp;
+static struct fb_var_screeninfo default_var;
+static struct fb_fix_screeninfo current_fix = {
+   id:      "S1D13706",
+   smem_start: (__u32)S1D13706_FB_BASE, /* initially, we'll fill it later */
+   smem_len:   320*240, /* initially, we'll fill it later */
+   type:    FB_TYPE_PACKED_PIXELS, /* this should always be true for dragonballs */
+   visual:     FB_VISUAL_PSEUDOCOLOR, /* this should depend on LCD used */
+   line_length:   320,
+   accel:      FB_ACCEL_NONE, /* but still like a breeze ;-) */
+};
+
+static int currcon = 0;
+
+
+
+/* ------------------- chipset specific functions -------------------------- */
+
+
+static void s1d13706_detect(void)
+{
+	u8 rev;
+
+	rev = s1d13706_read_reg(S1D13706_REVISION_CODE_REG);
+
+	if ((rev & 0xfc) != 0x28) {
+		printk(KERN_WARNING "Epson 13706 not detected\n");
+	}
+
+		s1d13706_encode_var(&default_var, NULL, NULL);
+
+
+#ifdef DBUG
+	printk("s1d13706_detect done\n");
+#endif
+
+
+}
+
+
+static int s1d13706_encode_fix(struct fb_fix_screeninfo *fix,
+			    const void *raw_par,
+			    struct fb_info_gen *info)
+{
+	const struct s1d13706_par *par = raw_par;
+
+	memset(fix, 0, sizeof *fix);
+
+	fix->type= FB_TYPE_PACKED_PIXELS;
+
+	if (!par)
+		BUG();
+
+	if (par->bpp == 1) {
+		fix->visual = FB_VISUAL_MONO10;
+	} else if (par->bpp <= 8) {
+		fix->visual = FB_VISUAL_PSEUDOCOLOR;
+	} else {
+		fix->visual = FB_VISUAL_TRUECOLOR;
+	}
+
+	fix->line_length = par->xres;
+
+	fix->mmio_start = S1D13706_FB_BASE;
+	fix->smem_start = S1D13706_FB_BASE;
+	fix->mmio_len = S1D13706_SRAM_SIZE;
+	fix->smem_len = S1D13706_SRAM_SIZE;
+
+
+
+#ifdef DBUG
+	printk("s1d13706_encode_fix done\n");
+#endif
+
+	return 0;
+}
+
+
+static int s1d13706_set_bpp(struct s1d13706_par *par, int bpp)
+{
+	int code;
+	u8 disp;
+	u16 bytes_per_line;
+
+	switch(bpp) {
+	case 1:
+		code = 0; break;
+	case 2:
+		code = 1; break;
+	case 4:
+		code = 2; break;
+	case 8:
+		code = 3; break;
+	case 16:
+		code = 4; break;
+	default:
+		return -EINVAL; break;
+	}
+
+	disp = s1d13706_read_reg(S1D13706_DISPLAY_MODE_REG);
+	disp &= ~0x07;       /* Bits 2:0 */
+	disp |= code;
+	s1d13706_write_reg(disp, S1D13706_DISPLAY_MODE_REG);
+
+	bytes_per_line = ((par->xres * bpp) >> 3) - 1;
+
+   /* horizontal displ. period reg */
+	s1d13706_write_reg16(bytes_per_line, S1D13706_HOR_DISPLAY_MODE_REG);
+	par->bpp = bpp;
+
+
+#ifdef DBUG
+	printk("s1d13706_set_bpp started\n");
+#endif
+
+
+	return 0;
+}
+
+static int s1d13706_decode_var(const struct fb_var_screeninfo *var,
+			    void *raw_par,
+			    struct fb_info_gen *info)
+{
+	struct s1d13706_par *par = raw_par;
+	int ret;
+
+
+#ifdef DBUG
+	printk("s1d13706_decode_var started\n");
+#endif
+
+
+	if (!par)
+		BUG();
+
+	/*
+	 * Don't allow setting any of these yet: xres and yres don't
+	 * make sense for LCD panels; xres_virtual and yres_virtual
+	 * should be supported fine by our hardware though.
+	 */
+	if (var->xres != par->xres ||
+	    var->yres != par->yres ||
+	    var->xres != var->xres_virtual ||
+	    var->yres != var->yres_virtual ||
+	    var->xoffset != 0 ||
+	    var->yoffset != 0){
+
+#ifdef DBUG
+	printk("s1d13706_decode_var returned -EINVAL\n");
+#endif
+
+		return -EINVAL;
+	}
+
+	if(var->bits_per_pixel != par->bpp) {
+		ret = s1d13706_set_bpp(par, var->bits_per_pixel);
+
+		if (ret)
+			goto out_err;
+	}
+
+
+#ifdef DBUG
+	printk("s1d13706_decode_var returned 0\n");
+#endif
+
+	return 0;
+
+	out_err:
+
+#ifdef DBUG
+	printk("s1d13706_decode_var returned %i\n", ret);
+#endif
+
+	return ret;
+}
+
+
+static void dump_panel_data(void)
+{
+	u8 panel = s1d13706_read_reg(S1D13706_PANEL_TYPE_REG);
+	int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } };
+   char *type[] = {"STN", "TFT", "HR-TFT", "D-DFT"};
+
+	printk("%s %s panel, width %d bits\n",
+	       panel & 0x40 ? "color" : "mono",
+	       *(type[panel & 0x03]),
+	       (width[panel&1][(panel>>4)&3]));
+
+	printk("resolution %d x %d\n",
+          /* hor. display period reg.: */
+	       (s1d13706_read_reg(S1D13706_HOR_DISPLAY_MODE_REG) + 1) * 8,
+          /* vert. displ. period reg.: */
+	       ((s1d13706_read_reg16(S1D13706_VERT_DISPLAY_MODE_REG0)+ 1) ));
+
+
+#ifdef DBUG
+	printk("dump_panel_data done\n");
+#endif
+
+
+}
+
+static int s1d13706_bpp_to_var(int bpp, struct fb_var_screeninfo *var)
+{
+	switch(bpp) {
+	case 1:
+	case 2:
+	case 4:
+	case 8:
+		var->bits_per_pixel = bpp;
+		var->red.offset = var->green.offset = var->blue.offset = 0;
+		var->red.length = var->green.length = var->blue.length = bpp;
+		break;
+	case 16:
+		var->bits_per_pixel = 16;
+		var->red.offset = 11;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 6;
+		var->blue.offset = 0;
+		var->blue.length = 5;
+		break;
+	}
+
+#ifdef DBUG
+	printk("s1d13706_bpp_to_var done\n");
+#endif
+
+
+
+	return 0;
+}
+
+
+static int s1d13706_encode_var(struct fb_var_screeninfo *var, const void *raw_par,
+			    struct fb_info_gen *info)
+{
+	u8 panel, display;
+	u32 xres, xres_virtual, yres, yres_virtual;
+	static int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 18, -1 } };
+	static int bpp_tab[8] = { 1, 2, 4, 8, 16, -1 };
+	int bpp, hw_bpp;
+	int is_color, is_tft;
+	int lcd_enabled;
+   int xoffset, yoffset;
+
+	display = s1d13706_read_reg(S1D13706_DISPLAY_MODE_REG);
+	panel = s1d13706_read_reg(S1D13706_PANEL_TYPE_REG);
+
+	is_color = (panel & 0x40) != 0;
+	is_tft   = (panel & 0x03) == 0x01;
+
+	bpp = bpp_tab[(display) & 0x07];/* BPP is in Bits 2:0 */
+	s1d13706_bpp_to_var(bpp, var);
+
+	lcd_enabled = (display & 0x80) == 0;/* when disabled, data outputs are zero*/
+
+	hw_bpp = width[is_tft][(panel>>4)&0x03];
+
+   /* Horizontal display period register: */
+	xres = s1d13706_read_reg(S1D13706_HOR_DISPLAY_MODE_REG) + 1;
+   /* Vertical display period register: */
+	yres = s1d13706_read_reg16(S1D13706_VERT_DISPLAY_MODE_REG0) + 1;
+	xres *= 8;
+
+   /* horizontal total resolution: */
+   xres_virtual = s1d13706_read_reg(S1D13706_HOR_TOTAL_REG);	xres_virtual *= 8;
+   /* vertical total resolution: */
+   yres_virtual = s1d13706_read_reg16(S1D13706_VERT_TOTAL_REG0);
+   /* hor. display period start pos. reg. */
+   xoffset = s1d13706_read_reg16(S1D13706_HOR_DISP_PERIOD_START_POS_REG0);
+
+	yoffset = s1d13706_read_reg16(S1D13706_VERT_DISP_PERIOD_START_POS_REG0);
+
+	var->xres = xres;
+	var->yres = yres;
+	var->xres_virtual = xres_virtual;
+	var->yres_virtual = yres_virtual;
+
+	var->xoffset = xoffset;
+   var->yoffset = yoffset;
+
+	var->bits_per_pixel = bpp;
+	var->grayscale = !is_color;
+
+
+#ifdef DBUG
+	printk("s1d13706_encode_var done\n");
+#endif
+
+
+	return 0;
+}
+
+
+static void get_panel_data(struct s1d13706_par *par)
+{
+	u8 panel;
+	u8 display;
+	int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } };
+	int bpp_tab[8] = { 1, 2, 4, 8, 16, -1 };
+
+	panel = s1d13706_read_reg(S1D13706_PANEL_TYPE_REG) & 0x3F;
+	display = s1d13706_read_reg(S1D13706_DISPLAY_MODE_REG);
+
+
+	par->panel_width = width[panel&1][(panel>>4)&3];
+
+   /* horiz. display period reg.: */
+	par->panel_xres = (s1d13706_read_reg(S1D13706_HOR_DISPLAY_MODE_REG) + 1) * 8;
+   /* vert. displ. period reg.: */
+   par->panel_yres = (s1d13706_read_reg16(S1D13706_VERT_DISPLAY_MODE_REG0) + 1);
+	par->bpp = bpp_tab[(display) & 0x07]; /* BPP is in Bits 2:0 */
+
+
+	par->mem_bpp = par->bpp;
+	par->xres =	par->panel_xres;
+	par->yres = par->panel_yres;;
+
+
+#ifdef DBUG
+	printk("get_panel_data done\n");
+#endif
+
+}
+
+
+static void s1d13706_get_par(void *raw_par, struct fb_info_gen *info)
+{
+	struct s1d13706_par *par = raw_par;
+
+	get_panel_data(par);
+
+#ifdef DBUG
+	printk("s1d13706_get_par done\n");
+#endif
+
+}
+
+static void s1d13706_set_par(const void *par, struct fb_info_gen *info)
+{
+
+#ifdef DBUG
+	printk("s1d13706_set_par done\n");
+#endif
+
+}
+
+static int s1d13706_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+			   unsigned *blue, unsigned *transp,
+			   struct fb_info *info)
+{
+	u8 r, g, b;
+
+	s1d13706_write_reg(regno, S1D13706_LUT_RD_ADDR_REG);
+	r = s1d13706_read_reg(S1D13706_LUT_R_RD_DATA_REG);
+	g = s1d13706_read_reg(S1D13706_LUT_G_RD_DATA_REG);
+	b = s1d13706_read_reg(S1D13706_LUT_B_RD_DATA_REG);
+
+	*red = r << 8;
+	*green = g << 8;
+	*blue = b << 8;
+
+#ifdef DBUG
+	printk("s1d13706_getcolreg done\n");
+#endif
+
+
+	return 0;
+}
+
+
+/*
+ * Changes: 2002/12/13 adapted to s1d13706
+ */
+static int s1d13706_setcolreg(unsigned regno, unsigned red, unsigned green,
+			   unsigned blue, unsigned transp,
+			   struct fb_info *info)
+{
+	u8 r = (red >> 8) & 0xfc;
+	u8 g = (green>>8) & 0xfc;
+	u8 b = (blue>> 8) & 0xfc;
+
+	s1d13706_write_reg(r, S1D13706_LUT_R_WR_DATA_REG);
+	s1d13706_write_reg(g, S1D13706_LUT_G_WR_DATA_REG);
+	s1d13706_write_reg(b, S1D13706_LUT_B_WR_DATA_REG);
+	s1d13706_write_reg(regno, S1D13706_LUT_WR_ADDR_REG);
+
+#ifdef DBUG
+	printk("s1d13706_setcolreg done\n");
+#endif
+
+	return 0;
+}
+
+static int s1d13706_pan_display(const struct fb_var_screeninfo *var,
+			     struct fb_info_gen *info)
+{
+
+#ifdef DBUG
+	printk("s1d13706_pan_display done\n");
+#endif
+
+	BUG();
+
+	return -EINVAL;
+}
+
+#undef AERO_HACKS
+
+static int s1d13706_blank(int blank_mode, struct fb_info_gen *info)
+{
+	u8 disp;
+
+	switch (blank_mode) {
+	case VESA_NO_BLANKING:
+		disp = s1d13706_read_reg(S1D13706_DISPLAY_MODE_REG);
+		disp |= 1;
+		s1d13706_write_reg(disp, S1D13706_DISPLAY_MODE_REG);
+		break;
+
+	case VESA_VSYNC_SUSPEND:
+	case VESA_HSYNC_SUSPEND:
+	case VESA_POWERDOWN:
+		disp = s1d13706_read_reg(S1D13706_DISPLAY_MODE_REG);
+		disp &= ~1;
+		s1d13706_write_reg(disp, S1D13706_DISPLAY_MODE_REG);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+#ifdef DBUG
+	printk("s1d13706_blank done\n");
+#endif
+
+	return 0;
+}
+
+static struct display_switch s1d13706_dispsw;
+
+static void s1d13706_set_disp(const void *unused, struct display *disp,
+			   struct fb_info_gen *info)
+{
+	struct display_switch *d;
+
+	disp->screen_base = (void *)S1D13706_FB_BASE;
+	disp->dispsw = &s1d13706_dispsw;
+
+	switch(disp->var.bits_per_pixel) {
+#ifdef FBCON_HAS_MFB
+	case 1:
+		d = &fbcon_mfb; break;
+#endif
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		d = &fbcon_cfb8; break;
+#endif
+	default:
+		BUG(); break;
+	}
+
+	memcpy(&s1d13706_dispsw, d, sizeof *d);
+
+#ifdef DBUG
+	printk("s1d13706_set_disp done\n");
+#endif
+
+}
+
+
+int __init s1d13706fb_setup(char *str)
+{
+
+#ifdef DBUG
+	printk("s1d13706fb_setup done\n");
+#endif
+	return 0;
+}
+
+int __init s1d13706fb_init(void)
+{
+
+  u8 * pRegs = (u8 *)S1D_PHYSICAL_REG_ADDR;
+  unsigned int idx=0;
+  unsigned int tmp, tmp1;
+
+
+#ifdef DBUG
+	printk("s1d13706fb_init started\n");
+#endif
+
+  /*
+   * all according to s1d13xxxfb.c
+   * 
+  ** Initialize the chip according to the following steps:
+  ** 1. Blank display (REG[70h] bit 7 = 1)
+  **    (This is not necessary if the chip powers up for the first time)
+  ** 2. If the system implementation uses a clock chip instead of a fixed
+  **    oscillator, program the clock chip.
+  ** 3. Write to all S1D13706 registers
+  ** 4. Update LookUp Table
+  ** 5. Power Up LCD:
+  **   a. If s/w power save mode is on (REG[A0h] bit 0 = 1), turn off s/w
+  **      power save mode.
+  **   b. If LCD power is off (REG[ADh] bit 7=0), delay for xx milli-seconds
+  **     (depending on panel specifications).
+  **   c. Turn on LCD power (REG[ADh] bit 7=1).
+  ** 6. Disable "blanking" display  (set REG[70h] bit 7 to 0)
+  */
+
+  /* Step 1 -> blank display*/
+	s1d13706_write_reg((s1d13706_read_reg(S1D13706_DISPLAY_MODE_REG) | 0x80), S1D13706_DISPLAY_MODE_REG);
+
+	/* Step 2 -> there is no clock chip, so here's nothing to do*/
+
+	/* Step 3 -> Write to all S1D13706 registers*/
+	while (1)
+	{
+		if ( (aS1DRegs[idx].Index==0xff) && (aS1DRegs[idx].Value==0xff) )
+         break;
+
+      *(pRegs + aS1DRegs[idx].Index) = (u8)(aS1DRegs[idx].Value);
+      idx++;
+  }
+
+
+  /* Step 4: Update LookUp Table
+  ** Note that the data can be arranged such that one dword write will
+  ** initialize red, green, blue, and also set the LUT address at the
+  ** same time. However, some systems may reverse the bytes (big versus
+  ** little-endian systems), so the code below is designed to work for
+  ** both big and little-endian systems.
+  */
+  for (idx = 0; idx < 256; idx++)
+  {
+
+		s1d13706_write_reg(LUT8_Color[3*idx], S1D13706_LUT_R_WR_DATA_REG);
+		s1d13706_write_reg(LUT8_Color[3*idx+1], S1D13706_LUT_G_WR_DATA_REG);
+		s1d13706_write_reg(LUT8_Color[3*idx+2], S1D13706_LUT_B_WR_DATA_REG);
+		s1d13706_write_reg(LUT8_Color[idx], S1D13706_LUT_WR_ADDR_REG);
+
+  }
+
+
+  /* Step 5: Power Up LCD
+  **   a. If s/w power save mode is on (REG[A0h] bit 0 = 1), turn off
+  **      s/w power save mode.
+  **   b. If LCD power is off (REG[ADh] bit 7 = 0), delay for xx 
+  **      milli-seconds (depending on panel specification).
+  **   c. Turn on LCD power (REG[ADh] bit 7 = 1).
+  */
+	tmp = s1d13706_read_reg(S1D13706_POWER_SAVE_CONFIG_REG);
+	if ( tmp & 0x01 ){
+		s1d13706_write_reg((u8)(tmp & ~0x01), S1D13706_POWER_SAVE_CONFIG_REG);
+	}
+
+  if ( !( s1d13706_read_reg(S1D13706_GPIO_CTL1_REG) & 0x80) )
+  {   /* delay at least 2 vertical periods for this panel */
+		tmp1 = s1d13706_read_reg(S1D13706_POWER_SAVE_CONFIG_REG) & 0x80;
+      for ( idx=0; idx<5; idx++)
+      {
+         tmp = tmp1;
+         while (1)
+         {
+				tmp1 = s1d13706_read_reg(S1D13706_POWER_SAVE_CONFIG_REG) & 0x80;
+            if ( tmp1 != tmp )
+               break;
+			}
+		}
+	}
+
+	s1d13706_write_reg(s1d13706_read_reg(S1D13706_GPIO_CTL1_REG) | 0x80, S1D13706_GPIO_CTL1_REG);
+
+
+  /* Step 6: Disable "blanking" display  (set REG[70h] bit 7 to 0) */
+	tmp = s1d13706_read_reg(S1D13706_DISPLAY_MODE_REG);
+	s1d13706_write_reg((u8) (tmp & ~0x80), S1D13706_DISPLAY_MODE_REG);
+
+	/* End of initializing the s1d13706 controller chip*/
+
+	fb_info.gen.fbhw = &s1d13706_switch;
+	fb_info.gen.fbhw->detect();
+	strcpy(fb_info.gen.info.modename, "S1D13706");
+	fb_info.gen.info.changevar = NULL;
+	fb_info.gen.info.node = -1;
+	fb_info.gen.info.fbops = &s1d13706fb_ops;
+	fb_info.gen.info.disp = &disp;
+	fb_info.gen.parsize = sizeof(struct s1d13706_par);
+	fb_info.gen.info.switch_con = &fbgen_switch;
+	fb_info.gen.info.updatevar = &fbgen_update_var;
+	fb_info.gen.info.blank = &fbgen_blank;
+	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
+	/* This should give a reasonable default video mode */
+	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
+	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
+	fbgen_set_disp(-1, &fb_info.gen);
+	if (disp.var.bits_per_pixel > 1)
+		fbgen_install_cmap(0, &fb_info.gen);
+	if (register_framebuffer(&fb_info.gen.info) < 0)
+		return -EINVAL;
+	printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.gen.info.node),
+	       fb_info.gen.info.modename);
+
+	return 0;
+}
+
+
+    /*
+     *  Cleanup
+     */
+
+void s1d13706fb_cleanup(struct fb_info *info)
+{
+	/*
+	 *  If your driver supports multiple boards, you should unregister and
+	 *  clean up all instances.
+	 */
+#ifdef DBUG
+	printk("s1d13706fb_cleanup done\n");
+#endif
+
+	unregister_framebuffer(info);
+	/* ... */
+
+
+}
+
+
+
+static void set_color_bitfields(struct fb_var_screeninfo *var)
+{
+    switch (var->bits_per_pixel) {
+	case 1:
+	    var->red.offset = 0;
+	    var->red.length = 1;
+	    var->green.offset = 0;
+	    var->green.length = 1;
+	    var->blue.offset = 0;
+	    var->blue.length = 1;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 8:
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 0;
+	    var->green.length = 8;
+	    var->blue.offset = 0;
+	    var->blue.length = 8;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 16:	/* RGB 565 */
+	    var->red.offset = 0;
+	    var->red.length = 5;
+	    var->green.offset = 5;
+	    var->green.length = 6;
+	    var->blue.offset = 11;
+	    var->blue.length = 5;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 24:	/* RGB 888 */
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 8;
+	    var->green.length = 8;
+	    var->blue.offset = 16;
+	    var->blue.length = 8;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 32:	/* RGBA 8888 */
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 8;
+	    var->green.length = 8;
+	    var->blue.offset = 16;
+	    var->blue.length = 8;
+	    var->transp.offset = 24;
+	    var->transp.length = 8;
+	    break;
+    }
+    var->red.msb_right = 0;
+    var->green.msb_right = 0;
+    var->blue.msb_right = 0;
+    var->transp.msb_right = 0;
+}
+
+
+static int s1d13706_get_fix(struct fb_fix_screeninfo *fix, int con,
+		       struct fb_info *info)
+{
+
+#ifdef DBUG
+	printk(KERN_DEBUG "fb%d: start: s1d13706_get_fix\n",
+		GET_FB_IDX(fb_info.gen.info.node));
+#endif
+
+    /* we only have one mode, so our fix_screeninfo struct
+       always has the same values, just throw it back to the user
+       current_fix was initialized earlier in init */
+
+#ifdef DBUG
+	printk(KERN_DEBUG "fb: info: getting fix for console %d\n", con);
+#endif
+
+    memcpy(fix, &current_fix, sizeof(struct fb_fix_screeninfo));
+
+    return 0;
+}
+
+
+    /*
+     *  Get the User Defined Part of the Display
+     */
+
+static int s1d13706_get_var(struct fb_var_screeninfo *var, int con,
+		       struct fb_info *info)
+{
+
+#ifdef DBUG
+	printk(KERN_DEBUG "fb%d: start: s1d13706_get_var\n",
+		GET_FB_IDX(fb_info.gen.info.node));
+
+	printk(KERN_DEBUG "fb: info: getting var for console %d\n", con);
+#endif
+
+    if (con == -1)
+	*var = default_var;
+    else
+	*var = fb_display[con].var;
+
+    set_color_bitfields(var);
+
+    return 0;
+}
+
+
+    /*
+     *  Set the User Defined Part of the Display
+     */
+
+static int s1d13706_set_var(struct fb_var_screeninfo *var, int con,
+		       struct fb_info *info)
+{
+    int activate = var->activate;
+
+    struct display *display;
+
+#ifdef DBUG
+	printk(KERN_DEBUG "fb%d: start: s1d13706_set_var\n",
+		GET_FB_IDX(fb_info.gen.info.node));
+#endif
+
+    if (con >= 0)
+    {
+		display = &fb_display[con];
+
+    }
+    else
+		display = &disp;	/* used during initialization */
+
+    /*
+     *  We are working with an LCD, which means that we
+     *  can't allow for modifications of many of the screen's
+     *  usually updateable parameters
+     */
+
+    if (var->xres != display->var.xres ||
+        var->yres != display->var.yres ||
+        var->xres_virtual != var->xres ||  /* virtual is not supported yet */
+        var->yres_virtual != var->yres ||
+        (var->xoffset != 0 && !(var->vmode & FB_VMODE_CONUPDATE)) ||
+        (var->yoffset != 0 && !(var->vmode & FB_VMODE_CONUPDATE)) ||
+        (var->bits_per_pixel != display->var.bits_per_pixel))
+    {
+	return -EINVAL;
+    }
+
+    set_color_bitfields(var); 
+
+ /* Since we don't allow anything to change anyways,
+	there's no need to update the display var, makes
+	our lifes much easier :-)*/
+
+    return 0;
+}
+
+
+
+    /*
+     *  Get the Colormap
+     */
+
+static int s1d13706_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info)
+{
+    if (con == currcon) /* current console? */
+	return fb_get_cmap(cmap, kspc, s1d13706_getcolreg, info);
+    else if (fb_display[con].cmap.len) /* non default colormap? */
+	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+    else
+	fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+		     cmap, kspc ? 0 : 2);
+    return 0;
+}
+
+    /*
+     *  Set the Colormap
+     */
+
+static int s1d13706_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info)
+{
+    int err;
+
+    if (!fb_display[con].cmap.len) {	/* no colormap allocated? */
+	if ((err = fb_alloc_cmap(&fb_display[con].cmap,
+			      1<<fb_display[con].var.bits_per_pixel, 0)))
+	    return err;
+    }
+    if (con == currcon)			/* current console? */
+	return fb_set_cmap(cmap, kspc, s1d13706_setcolreg, info);
+    else
+	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+    return 0;
+}
+
+
+MODULE_LICENSE("GPL");
+
diff -urN linux-2.4.29/drivers/video/s1d13706fb.h linux-2.4.29-uc1/drivers/video/s1d13706fb.h
--- linux-2.4.29/drivers/video/s1d13706fb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/s1d13706fb.h	2005-06-14 02:12:27.000000000 +0100
@@ -0,0 +1,362 @@
+/*
+ * linux/drivers/video/s1d13706fb.h
+ *	-- Support for the Epson SED13706 LCD/CRT controller
+ *
+ * Copyright (C) 2003 Heiko Degenhardt <linux@sentec-elektronik.de>
+ *                    Michael Huhn <michael.huhn@sentec-elektronik.de>
+ *
+ * Some ideas were "stolen" from 
+ *    linux/drivers/video/epson1355fb.c
+ *    that is "Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>"
+ * and from s1d13xxxfb.c and a file called "s1d13706.h" that was
+ *    generated by S1D13706CFG.EXE both are
+ *    "Copyright(c) 2000, 2001 Epson Research and Development, Inc"
+ *
+ * HINT: If someone feels that we used his code but didn't give him
+ * credits here, please email us! It was a quite complicated thing to
+ * get all that working, so may be we just forgot someone! Thanks!
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * CHANGES
+ *
+ * 20030312 
+ *    Creation
+ *    (mihu, hede)
+ */
+
+/*
+ * 
+ * ATTENTION!
+ * This stuff is _really_ experimental, currently!
+ * Feedback is really welcome!
+ *
+ */
+
+/* Register defines. */
+
+#define S1D13706_REVISION_CODE_REG		0x00
+
+/* LUT */
+#define S1D13706_LUT_B_WR_DATA_REG	0x08
+#define S1D13706_LUT_G_WR_DATA_REG	0x09
+#define S1D13706_LUT_R_WR_DATA_REG	0x0A
+#define S1D13706_LUT_WR_ADDR_REG		0x0B
+#define S1D13706_LUT_B_RD_DATA_REG		0x0C
+#define S1D13706_LUT_G_RD_DATA_REG		0x0D
+#define S1D13706_LUT_R_RD_DATA_REG		0x0E
+#define S1D13706_LUT_RD_ADDR_REG		0x0F
+
+#define S1D13706_PANEL_TYPE_REG		0x10
+
+#define S1D13706_HOR_TOTAL_REG	0x12
+#define S1D13706_HOR_DISPLAY_MODE_REG	0x14
+#define S1D13706_HOR_DISP_PERIOD_START_POS_REG0	0x16
+#define S1D13706_HOR_DISP_PERIOD_START_POS_REG1	0x17
+
+#define S1D13706_VERT_TOTAL_REG0	0x18
+#define S1D13706_VERT_TOTAL_REG1	0x19
+#define S1D13706_VERT_DISPLAY_MODE_REG0	0x1C
+#define S1D13706_VERT_DISPLAY_MODE_REG1	0x1D
+#define S1D13706_VERT_DISP_PERIOD_START_POS_REG0	0x1E
+#define S1D13706_VERT_DISP_PERIOD_START_POS_REG1	0x1F
+
+#define S1D13706_DISPLAY_MODE_REG		0x70
+#define S1D13706_DISPLAY_SP_EFFECTS_REG	0x71
+#define S1D13706_POWER_SAVE_CONFIG_REG	0xA0
+#define S1D13706_GPIO_REG	0xA8
+#define S1D13706_GPIO_CTL1_REG	0xAD
+
+
+/* The following defines are specific for our board layout! */
+
+#ifdef CONFIG_COBRA5272
+#define S1D13706_REG_OFFSET   0x40000000
+#define S1D13706_FB_OFFSET    0x20000
+#define S1D13706_SRAM_SIZE		0x14000
+
+#define S1D13706_REG_BASE	MCF_MBAR + S1D13706_REG_OFFSET
+#define S1D13706_FB_BASE	S1D13706_REG_OFFSET + S1D13706_FB_OFFSET
+
+#define S1D_PHYSICAL_REG_ADDR       S1D13706_REG_OFFSET
+#define S1D_PHYSICAL_VMEM_ADDR      S1D13706_FB_BASE
+#define S1D_PHYSICAL_VMEM_SIZE      0x14000L
+
+
+#else
+#error unknown architecture
+#endif
+
+struct s1d13706fb_info {
+   struct fb_info_gen gen;
+};
+
+struct s1d13706_par {
+	u32 xres;
+	u32 yres;
+
+	int bpp;
+	int mem_bpp;
+
+	u32 panel_xres;
+	u32 panel_yres;
+
+	int panel_width;
+};
+
+
+/* Prototypes */
+static void s1d13706_detect(void);
+int s1d13706fb_init(void);
+int s1d13706fb_setup(char*);
+static int s1d13706_encode_fix(struct fb_fix_screeninfo *fix,
+				const void *raw_par,
+				struct fb_info_gen *info);
+static int s1d13706_set_bpp(struct s1d13706_par *par, int bpp);
+static int s1d13706_decode_var(const struct fb_var_screeninfo *var,
+				void *raw_par,
+				struct fb_info_gen *info);
+static void dump_panel_data(void);
+static int s1d13706_bpp_to_var(int bpp, struct fb_var_screeninfo *var);
+static int s1d13706_encode_var(struct fb_var_screeninfo *var,
+				const void *raw_par,
+				struct fb_info_gen *info);
+static void get_panel_data(struct s1d13706_par *par);
+static void s1d13706_get_par(void *raw_par, struct fb_info_gen *info);
+static void s1d13706_set_par(const void *par, struct fb_info_gen *info);
+static int s1d13706_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+				unsigned *blue, unsigned *transp,
+				struct fb_info *info);
+static int s1d13706_setcolreg(unsigned regno, unsigned red, unsigned green,
+				unsigned blue, unsigned transp,
+				struct fb_info *info);
+static int s1d13706_pan_display(const struct fb_var_screeninfo *var,
+				struct fb_info_gen *info);
+static int s1d13706_blank(int blank_mode, struct fb_info_gen *info);
+static void s1d13706_set_disp(const void *unused, struct display *disp,
+				struct fb_info_gen *info);
+static struct s1d13706fb_info fb_info;
+int __init s1d13706fb_setup(char *str);
+int __init s1d13706fb_init(void);
+void s1d13706fb_cleanup(struct fb_info *info);
+
+
+static void set_color_bitfields(struct fb_var_screeninfo *var);
+static int s1d13706_get_fix(struct fb_fix_screeninfo *fix, int con,
+				struct fb_info *info);
+static int s1d13706_get_var(struct fb_var_screeninfo *var, int con,
+				struct fb_info *info);
+static int s1d13706_set_var(struct fb_var_screeninfo *var, int con,
+				struct fb_info *info);
+static int s1d13706_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+				struct fb_info *info);
+static int s1d13706_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+				struct fb_info *info);
+
+
+/* ------------ Interfaces to hardware functions ------------ */
+
+struct fbgen_hwswitch s1d13706_switch = {
+	detect:		s1d13706_detect,
+	encode_fix:	s1d13706_encode_fix,
+	decode_var:	s1d13706_decode_var,
+	encode_var:	s1d13706_encode_var,
+	get_par:	s1d13706_get_par,
+	set_par:	s1d13706_set_par,
+	getcolreg:	s1d13706_getcolreg,
+	setcolreg:	s1d13706_setcolreg,
+	pan_display:	s1d13706_pan_display,
+	blank:		s1d13706_blank,
+	set_disp:	s1d13706_set_disp,
+};
+
+
+/* ------------ Hardware Independent Functions ------------ */
+
+static struct fb_ops s1d13706fb_ops = {
+	owner:		THIS_MODULE,
+	fb_get_fix:	s1d13706_get_fix,
+	fb_get_var:	s1d13706_get_var,
+	fb_set_var:	s1d13706_set_var,
+	fb_get_cmap:	s1d13706_get_cmap,
+	fb_set_cmap:	s1d13706_set_cmap,
+	fb_pan_display:	fbgen_pan_display,
+};
+
+
+/* The following lines are for the initialization of the controller */
+
+typedef unsigned short S1D_INDEX;
+typedef unsigned short S1D_VALUE;
+
+typedef struct
+{
+    S1D_INDEX Index;
+    S1D_VALUE Value;
+} S1D_REGS;
+
+static S1D_REGS aS1DRegs[] =
+{
+    {0x04,0x30},   // BUSCLK MEMCLK Config Register
+    {0x05,0x31},   // PCLK Config  Register
+    {0x10,0xD0},   // PANEL Type Register
+    {0x11,0x00},   // MOD Rate Register
+    {0x12,0x34},   // Horizontal Total Register
+    {0x14,0x27},   // Horizontal Display Period Register
+    {0x16,0x00},   // Horizontal Display Period Start Pos Register 0
+    {0x17,0x00},   // Horizontal Display Period Start Pos Register 1
+    {0x18,0xFF},   // Vertical Total Register 0
+    {0x19,0x00},   // Vertical Total Register 1
+    {0x1C,0xEF},   // Vertical Display Period Register 0
+    {0x1D,0x00},   // Vertical Display Period Register 1
+    {0x1E,0x00},   // Vertical Display Period Start Pos Register 0
+    {0x1F,0x00},   // Vertical Display Period Start Pos Register 1
+    {0x20,0x87},   // Horizontal Sync Pulse Width Register
+    {0x22,0x00},   // Horizontal Sync Pulse Start Pos Register 0
+    {0x23,0x00},   // Horizontal Sync Pulse Start Pos Register 1
+    {0x24,0x80},   // Vertical Sync Pulse Width Register
+    {0x26,0x01},   // Vertical Sync Pulse Start Pos Register 0
+    {0x27,0x00},   // Vertical Sync Pulse Start Pos Register 1
+    {0x70,0x03},   // Display Mode Register
+    {0x71,0x00},   // Special Effects Register
+    {0x74,0x00},   // Main Window Display Start Address Register 0
+    {0x75,0x00},   // Main Window Display Start Address Register 1
+    {0x76,0x00},   // Main Window Display Start Address Register 2
+    {0x78,0x50},   // Main Window Address Offset Register 0
+    {0x79,0x00},   // Main Window Address Offset Register 1
+    {0x7C,0x00},   // Sub Window Display Start Address Register 0
+    {0x7D,0x00},   // Sub Window Display Start Address Register 1
+    {0x7E,0x00},   // Sub Window Display Start Address Register 2
+    {0x80,0x50},   // Sub Window Address Offset Register 0
+    {0x81,0x00},   // Sub Window Address Offset Register 1
+    {0x84,0x00},   // Sub Window X Start Pos Register 0
+    {0x85,0x00},   // Sub Window X Start Pos Register 1
+    {0x88,0x00},   // Sub Window Y Start Pos Register 0
+    {0x89,0x00},   // Sub Window Y Start Pos Register 1
+    {0x8C,0x4F},   // Sub Window X End Pos Register 0
+    {0x8D,0x00},   // Sub Window X End Pos Register 1
+    {0x90,0xEF},   // Sub Window Y End Pos Register 0
+    {0x91,0x00},   // Sub Window Y End Pos Register 1
+    {0xA0,0x00},   // Power Save Config Register
+    {0xA1,0x00},   // CPU Access Control Register
+    {0xA2,0x00},   // Software Reset Register
+    {0xA3,0x00},   // BIG Endian Support Register
+    {0xA4,0x00},   // Scratch Pad Register 0
+    {0xA5,0x00},   // Scratch Pad Register 1
+    {0xA8,0x00},   // GPIO Config Register 0
+    {0xA9,0x80},   // GPIO Config Register 1
+    {0xAC,0x00},   // GPIO Status Control Register 0
+    {0xAD,0x00},   // GPIO Status Control Register 1
+    {0xB0,0x00},   // PWM CV Clock Control Register
+    {0xB1,0x00},   // PWM CV Clock Config Register
+    {0xB2,0x00},   // CV Clock Burst Length Register
+    {0xB3,0x00},   // PWM Clock Duty Cycle Register
+    {0xFF,0xFF},   // END
+};
+
+
+u8 LUT8_Color[256*3] =
+{
+/* Primary and secondary colors */
+0x00, 0x00, 0x00,  0x00, 0x00, 0xAA,  0x00, 0xAA, 0x00,  0x00, 0xAA, 0xAA,
+0xAA, 0x00, 0x00,  0xAA, 0x00, 0xAA,  0xAA, 0xAA, 0x00,  0xAA, 0xAA, 0xAA,
+0x55, 0x55, 0x55,  0x00, 0x00, 0xFF,  0x00, 0xFF, 0x00,  0x00, 0xFF, 0xFF,
+0xFF, 0x00, 0x00,  0xFF, 0x00, 0xFF,  0xFF, 0xFF, 0x00,  0xFF, 0xFF, 0xFF,
+
+/* Gray shades */
+0x00, 0x00, 0x00,  0x10, 0x10, 0x10,  0x20, 0x20, 0x20,  0x30, 0x30, 0x30,
+0x40, 0x40, 0x40,  0x50, 0x50, 0x50,  0x60, 0x60, 0x60,  0x70, 0x70, 0x70,
+0x80, 0x80, 0x80,  0x90, 0x90, 0x90,  0xA0, 0xA0, 0xA0,  0xB0, 0xB0, 0xB0,
+0xC0, 0xC0, 0xC0,  0xD0, 0xD0, 0xD0,  0xE0, 0xE0, 0xE0,  0xFF, 0xFF, 0xFF,
+
+/* Black to red */
+0x00, 0x00, 0x00,  0x10, 0x00, 0x00,  0x20, 0x00, 0x00,  0x30, 0x00, 0x00,
+0x40, 0x00, 0x00,  0x50, 0x00, 0x00,  0x60, 0x00, 0x00,  0x70, 0x00, 0x00,
+0x80, 0x00, 0x00,  0x90, 0x00, 0x00,  0xA0, 0x00, 0x00,  0xB0, 0x00, 0x00,
+0xC0, 0x00, 0x00,  0xD0, 0x00, 0x00,  0xE0, 0x00, 0x00,  0xFF, 0x00, 0x00,
+
+/* Black to green */
+0x00, 0x00, 0x00,  0x00, 0x10, 0x00,  0x00, 0x20, 0x00,  0x00, 0x30, 0x00,
+0x00, 0x40, 0x00,  0x00, 0x50, 0x00,  0x00, 0x60, 0x00,  0x00, 0x70, 0x00,
+0x00, 0x80, 0x00,  0x00, 0x90, 0x00,  0x00, 0xA0, 0x00,  0x00, 0xB0, 0x00,
+0x00, 0xC0, 0x00,  0x00, 0xD0, 0x00,  0x00, 0xE0, 0x00,  0x00, 0xFF, 0x00,
+
+/* Black to blue */
+0x00, 0x00, 0x00,  0x00, 0x00, 0x10,  0x00, 0x00, 0x20,  0x00, 0x00, 0x30,
+0x00, 0x00, 0x40,  0x00, 0x00, 0x50,  0x00, 0x00, 0x60,  0x00, 0x00, 0x70,
+0x00, 0x00, 0x80,  0x00, 0x00, 0x90,  0x00, 0x00, 0xA0,  0x00, 0x00, 0xB0,
+0x00, 0x00, 0xC0,  0x00, 0x00, 0xD0,  0x00, 0x00, 0xE0,  0x00, 0x00, 0xFF,
+
+/* Blue to cyan (blue and green) */
+0x00, 0x00, 0xFF,  0x00, 0x10, 0xFF,  0x00, 0x20, 0xFF,  0x00, 0x30, 0xFF,
+0x00, 0x40, 0xFF,  0x00, 0x50, 0xFF,  0x00, 0x60, 0xFF,  0x00, 0x70, 0xFF,
+0x00, 0x80, 0xFF,  0x00, 0x90, 0xFF,  0x00, 0xA0, 0xFF,  0x00, 0xB0, 0xFF,
+0x00, 0xC0, 0xFF,  0x00, 0xD0, 0xFF,  0x00, 0xE0, 0xFF,  0x00, 0xFF, 0xFF,
+
+/* Cyan (blue and green) to green */
+0x00, 0xFF, 0xFF,  0x00, 0xFF, 0xE0,  0x00, 0xFF, 0xD0,  0x00, 0xFF, 0xC0,
+0x00, 0xFF, 0xB0,  0x00, 0xFF, 0xA0,  0x00, 0xFF, 0x90,  0x00, 0xFF, 0x80,
+0x00, 0xFF, 0x70,  0x00, 0xFF, 0x60,  0x00, 0xFF, 0x50,  0x00, 0xFF, 0x40,
+0x00, 0xFF, 0x30,  0x00, 0xFF, 0x20,  0x00, 0xFF, 0x10,  0x00, 0xFF, 0x00,
+
+/* Green to yellow (red and green) */
+0x00, 0xFF, 0x00,  0x10, 0xFF, 0x00,  0x20, 0xFF, 0x00,  0x30, 0xFF, 0x00,
+0x40, 0xFF, 0x00,  0x50, 0xFF, 0x00,  0x60, 0xFF, 0x00,  0x70, 0xFF, 0x00,
+0x80, 0xFF, 0x00,  0x90, 0xFF, 0x00,  0xA0, 0xFF, 0x00,  0xB0, 0xFF, 0x00,
+0xC0, 0xFF, 0x00,  0xD0, 0xFF, 0x00,  0xE0, 0xFF, 0x00,  0xFF, 0xFF, 0x00,
+
+/* Yellow (red and green) to red */
+0xFF, 0xFF, 0x00,  0xFF, 0xE0, 0x00,  0xFF, 0xD0, 0x00,  0xFF, 0xC0, 0x00,
+0xFF, 0xB0, 0x00,  0xFF, 0xA0, 0x00,  0xFF, 0x90, 0x00,  0xFF, 0x80, 0x00,
+0xFF, 0x70, 0x00,  0xFF, 0x60, 0x00,  0xFF, 0x50, 0x00,  0xFF, 0x40, 0x00,
+0xFF, 0x30, 0x00,  0xFF, 0x20, 0x00,  0xFF, 0x10, 0x00,  0xFF, 0x00, 0x00,
+
+/* Red to magenta (blue and red) */
+0xFF, 0x00, 0x00,  0xFF, 0x00, 0x10,  0xFF, 0x00, 0x20,  0xFF, 0x00, 0x30,
+0xFF, 0x00, 0x40,  0xFF, 0x00, 0x50,  0xFF, 0x00, 0x60,  0xFF, 0x00, 0x70,
+0xFF, 0x00, 0x80,  0xFF, 0x00, 0x90,  0xFF, 0x00, 0xA0,  0xFF, 0x00, 0xB0,
+0xFF, 0x00, 0xC0,  0xFF, 0x00, 0xD0,  0xFF, 0x00, 0xE0,  0xFF, 0x00, 0xFF,
+
+/* Magenta (blue and red) to blue */
+0xFF, 0x00, 0xFF,  0xE0, 0x00, 0xFF,  0xD0, 0x00, 0xFF,  0xC0, 0x00, 0xFF,
+0xB0, 0x00, 0xFF,  0xA0, 0x00, 0xFF,  0x90, 0x00, 0xFF,  0x80, 0x00, 0xFF,
+0x70, 0x00, 0xFF,  0x60, 0x00, 0xFF,  0x50, 0x00, 0xFF,  0x40, 0x00, 0xFF,
+0x30, 0x00, 0xFF,  0x20, 0x00, 0xFF,  0x10, 0x00, 0xFF,  0x00, 0x00, 0xFF,
+
+/* Black to magenta (blue and red) */
+0x00, 0x00, 0x00,  0x10, 0x00, 0x10,  0x20, 0x00, 0x20,  0x30, 0x00, 0x30,
+0x40, 0x00, 0x40,  0x50, 0x00, 0x50,  0x60, 0x00, 0x60,  0x70, 0x00, 0x70,
+0x80, 0x00, 0x80,  0x90, 0x00, 0x90,  0xA0, 0x00, 0xA0,  0xB0, 0x00, 0xB0,
+0xC0, 0x00, 0xC0,  0xD0, 0x00, 0xD0,  0xE0, 0x00, 0xE0,  0xFF, 0x00, 0xFF,
+
+/* Black to cyan (blue and green) */
+0x00, 0x00, 0x00,  0x00, 0x10, 0x10,  0x00, 0x20, 0x20,  0x00, 0x30, 0x30,
+0x00, 0x40, 0x40,  0x00, 0x50, 0x50,  0x00, 0x60, 0x60,  0x00, 0x70, 0x70,
+0x00, 0x80, 0x80,  0x00, 0x90, 0x90,  0x00, 0xA0, 0xA0,  0x00, 0xB0, 0xB0,
+0x00, 0xC0, 0xC0,  0x00, 0xD0, 0xD0,  0x00, 0xE0, 0xE0,  0x00, 0xFF, 0xFF,
+
+/* Red to white */
+0xFF, 0x00, 0x00,  0xFF, 0x10, 0x10,  0xFF, 0x20, 0x20,  0xFF, 0x30, 0x30,
+0xFF, 0x40, 0x40,  0xFF, 0x50, 0x50,  0xFF, 0x60, 0x60,  0xFF, 0x70, 0x70,
+0xFF, 0x80, 0x80,  0xFF, 0x90, 0x90,  0xFF, 0xA0, 0xA0,  0xFF, 0xB0, 0xB0,
+0xFF, 0xC0, 0xC0,  0xFF, 0xD0, 0xD0,  0xFF, 0xE0, 0xE0,  0xFF, 0xFF, 0xFF,
+
+/* Green to white */
+0x00, 0xFF, 0x00,  0x10, 0xFF, 0x10,  0x20, 0xFF, 0x20,  0x30, 0xFF, 0x30,
+0x40, 0xFF, 0x40,  0x50, 0xFF, 0x50,  0x60, 0xFF, 0x60,  0x70, 0xFF, 0x70,
+0x80, 0xFF, 0x80,  0x90, 0xFF, 0x90,  0xA0, 0xFF, 0xA0,  0xB0, 0xFF, 0xB0,
+0xC0, 0xFF, 0xC0,  0xD0, 0xFF, 0xD0,  0xE0, 0xFF, 0xE0,  0xFF, 0xFF, 0xFF,
+
+/* Blue to white */
+0x00, 0x00, 0xFF,  0x10, 0x10, 0xFF,  0x20, 0x20, 0xFF,  0x30, 0x30, 0xFF,
+0x40, 0x40, 0xFF,  0x50, 0x50, 0xFF,  0x60, 0x60, 0xFF,  0x70, 0x70, 0xFF,
+0x80, 0x80, 0xFF,  0x90, 0x90, 0xFF,  0xA0, 0xA0, 0xFF,  0xB0, 0xB0, 0xFF,
+0xC0, 0xC0, 0xFF,  0xD0, 0xD0, 0xFF,  0xE0, 0xE0, 0xFF,  0xFF, 0xFF, 0xFF
+};
+
+/*==========================================================================*/
+
diff -urN linux-2.4.29/drivers/video/s1d13806fb.c linux-2.4.29-uc1/drivers/video/s1d13806fb.c
--- linux-2.4.29/drivers/video/s1d13806fb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/s1d13806fb.c	2005-06-14 02:12:26.000000000 +0100
@@ -0,0 +1,936 @@
+ /*
+ * linux/drivers/video/s1d13806fb.c
+ *	-- Support for the Epson S1D13806 LCD/CRT controller
+ *
+ * Copyright (C) 2003 Heiko Degenhardt <linux@sentec-elektronik.de>
+ *                    Michael Huhn <michael.huhn@sentec-elektronik.de>
+ *
+ * based on linux/drivers/video/skeletonfb.c, which was
+ *  Created 28 Dec 1997 by Geert Uytterhoeven
+ *
+ * Some ideas were "stolen" from
+ *    linux/drivers/video/epson1355fb.c
+ *    that is "Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>"
+ * and from s1d13xxxfb.c and a file called "s1d13806.h" that was
+ *    generated by S1D13806CFG.EXE both are
+ *    "Copyright(c) 2000, 2001 Epson Research and Development, Inc"
+ *
+ * HINT: If someone feels that we used his code but didn't give him
+ * credits here, please email us! It was a quite complicated thing to
+ * get all that working, so may be we just forgot someone! Thanks!
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ */
+
+/*
+ * CHANGES
+ * 
+ * 20040205
+ * - Changed memory size (thanks to Matthias Babylon)
+ * - Added S1D13806_GPIO_CONFIG1_REG (needed for startup)
+ * - Changed S1D13806_GPIO_CTL1_REG to 0x09 (for startup)
+ * (woel, hede)
+ *
+ * 20030312
+ *    Creation
+ *    (woel, mihu)
+ */
+
+/*
+ *
+ * ATTENTION!
+ * This stuff is _really_ experimental, currently!
+ * Feedback is really welcome!
+ *
+ */
+
+/* define DBUG below if you want to get more verbose output of the
+   driver */
+//#define DBUG
+
+#include <asm/io.h>
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-mfb.h>
+#include <video/fbcon.h>
+
+#include <asm/coldfire.h>
+
+/*
+ -----------------------------------------------------------------------------
+
+   Sanity checks
+
+ -----------------------------------------------------------------------------
+*/
+
+/* Are you compiling for our board?
+ * If not I think you know how to solve the error. ;)
+ */
+#ifdef CONFIG_COBRA5272
+
+/* S1D13806 supports 4Bpp, 8Bpp, 16Bpp */
+#ifdef CONFIG_FB_S1D13806
+    #if defined (FBCON_HAS_CFB4) && defined (FBCON_HAS_CFB8)
+        #error More than one colordepth specified
+    #endif
+    #if defined (FBCON_HAS_CFB4) && defined (FBCON_HAS_CFB16)
+        #error More than one colordepth specified
+    #endif
+    #if defined (FBCON_HAS_CFB8) && defined (FBCON_HAS_CFB16)
+        #error More than one colordepth specified
+    #endif
+#include "s1d13806fb.h"
+#else
+	#error lcd controller not supported
+#endif
+
+
+/* Check if at least one supported colordepth was configured */
+#if !defined (FBCON_HAS_CFB4) && !defined (FBCON_HAS_CFB8) && \
+    !defined (FBCON_HAS_CFB16)
+    #error No colordepth specified
+#endif
+
+
+static inline u8 s1d13806_read_reg(int index)
+{
+	return readb(S1D13806_REG_OFFSET + index);
+}
+
+static inline void s1d13806_write_reg(u8 data, int index)
+{
+	writeb(data, S1D13806_REG_OFFSET + index);
+}
+
+static inline u16 s1d13806_read_reg16(int index)
+{
+	return s1d13806_read_reg(index) + (s1d13806_read_reg(index+1) << 8);
+}
+
+static inline void s1d13806_write_reg16(u16 data, int index)
+{
+	s1d13806_write_reg((data&0xff), index);
+	s1d13806_write_reg(((data>>8)&0xff), index + 1);
+}
+#else /* not on the COBRA5272 board */
+#error unknown architecture
+#endif
+
+
+static int current_par_valid = 0;
+
+static struct display disp;
+static struct fb_var_screeninfo default_var;
+static struct fb_fix_screeninfo current_fix = {
+   id:      "S1D13806",
+   smem_start: (__u32)S1D13806_FB_BASE, /* initially, we'll fill it later */
+   smem_len:   320*240, /* initially, we'll fill it later */
+   type:    FB_TYPE_PACKED_PIXELS, /* this should always be true for dragonballs */
+   visual:     FB_VISUAL_PSEUDOCOLOR, /* this should depend on LCD used */
+   line_length:   320,
+   accel:      FB_ACCEL_NONE, /* but still like a breeze ;-) */
+};
+
+static int currcon = 0;
+
+
+
+/* ------------------- chipset specific functions -------------------------- */
+
+
+static void s1d13806_detect(void)
+{
+	u8 rev;
+
+	rev = s1d13806_read_reg(S1D13806_REVISION_CODE_REG);
+
+	if ((rev & 0xFc) != 0x1c) {
+		printk(KERN_WARNING "Epson 13806 not detected\n");
+	}
+
+		s1d13806_encode_var(&default_var, NULL, NULL);
+
+
+#ifdef DBUG
+	printk("s1d13806_detect done\n");
+#endif
+
+
+}
+
+
+static int s1d13806_encode_fix(struct fb_fix_screeninfo *fix,
+			    const void *raw_par,
+			    struct fb_info_gen *info)
+{
+	const struct s1d13806_par *par = raw_par;
+
+	memset(fix, 0, sizeof *fix);
+
+	fix->type= FB_TYPE_PACKED_PIXELS;
+
+	if (!par)
+		BUG();
+
+	if (par->bpp == 1) {
+		fix->visual = FB_VISUAL_MONO10;
+	} else if (par->bpp <= 8) {
+		fix->visual = FB_VISUAL_PSEUDOCOLOR;
+	} else {
+		fix->visual = FB_VISUAL_TRUECOLOR;
+	}
+
+	fix->line_length = par->xres;
+
+	fix->mmio_start = S1D13806_FB_BASE;
+	fix->smem_start = S1D13806_FB_BASE;
+	fix->mmio_len = S1D13806_SRAM_SIZE;
+	fix->smem_len = S1D13806_SRAM_SIZE;
+
+
+
+#ifdef DBUG
+	printk("s1d13806_encode_fix done\n");
+#endif
+
+	return 0;
+}
+
+
+static int s1d13806_set_bpp(struct s1d13806_par *par, int bpp)
+{
+	int code;
+	u8 disp;
+	u16 bytes_per_line;
+
+	switch(bpp) {
+	case 4:
+		code = 2; break;
+	case 8:
+		code = 3; break;
+	case 16:
+		code = 5; break;
+	default:
+		return -EINVAL; break;
+	}
+
+	disp = s1d13806_read_reg(S1D13806_DISPLAY_MODE_REG);
+	disp &= ~0x07;       /* Bits 2:0 */
+	disp |= code;
+	s1d13806_write_reg(disp, S1D13806_DISPLAY_MODE_REG);
+
+	bytes_per_line = ((par->xres * bpp) >> 3) - 1;
+
+   /* horizontal displ. period reg */
+	s1d13806_write_reg16(bytes_per_line, S1D13806_HOR_DISPLAY_WIDTH_REG);
+	par->bpp = bpp;
+
+
+#ifdef DBUG
+	printk("s1d13806_set_bpp started\n");
+#endif
+
+
+	return 0;
+}
+
+static int s1d13806_decode_var(const struct fb_var_screeninfo *var,
+			    void *raw_par,
+			    struct fb_info_gen *info)
+{
+	struct s1d13806_par *par = raw_par;
+	int ret;
+
+
+#ifdef DBUG
+	printk("s1d13806_decode_var started\n");
+#endif
+
+
+	if (!par)
+		BUG();
+
+	/*
+	 * Don't allow setting any of these yet: xres and yres don't
+	 * make sense for LCD panels; xres_virtual and yres_virtual
+	 * should be supported fine by our hardware though.
+	 */
+	if (var->xres != par->xres ||
+	    var->yres != par->yres ||
+	    var->xres != var->xres_virtual ||
+	    var->yres != var->yres_virtual ||
+	    var->xoffset != 0 ||
+	    var->yoffset != 0){
+
+#ifdef DBUG
+	printk("s1d13806_decode_var returned -EINVAL\n");
+#endif
+
+		return -EINVAL;
+	}
+
+	if(var->bits_per_pixel != par->bpp) {
+		ret = s1d13806_set_bpp(par, var->bits_per_pixel);
+
+		if (ret)
+			goto out_err;
+	}
+
+
+#ifdef DBUG
+	printk("s1d13806_decode_var returned 0\n");
+#endif
+
+	return 0;
+
+	out_err:
+
+#ifdef DBUG
+	printk("s1d13806_decode_var returned %i\n", ret);
+#endif
+
+	return ret;
+}
+
+
+static void dump_panel_data(void)
+{
+	u8 panel = s1d13806_read_reg(S1D13806_PANEL_TYPE_REG);
+	int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 18, -1 } };
+   char *type[] = {"1", "2"};
+	char *singledoube[] = {"single","double"};
+
+	printk("%s %s %sx DataFormat panel, width %d bits\n",
+	       panel & 0x04 ? "color" : "mono", singledoube[panel & 0x02],
+	       *(type[panel & 0x40]),
+	       (width[panel&1][(panel>>4)&3]));
+
+	printk("resolution %d x %d\n",
+          /* hor. display width reg.: */
+	       (s1d13806_read_reg(S1D13806_HOR_DISPLAY_WIDTH_REG) + 1) * 8,
+          /* vert. displ. height reg.: */
+	       ((s1d13806_read_reg16(S1D13806_VERT_DISPLAY_HEIGHT_REG)+ 1) ));
+
+
+#ifdef DBUG
+	printk("dump_panel_data done\n");
+#endif
+
+
+}
+
+static int s1d13806_bpp_to_var(int bpp, struct fb_var_screeninfo *var)
+{
+	switch(bpp) {
+	case 1:
+	case 2:
+	case 4:
+	case 8:
+		var->bits_per_pixel = bpp;
+		var->red.offset = var->green.offset = var->blue.offset = 0;
+		var->red.length = var->green.length = var->blue.length = bpp;
+		break;
+	case 16:
+		var->bits_per_pixel = 16;
+		var->red.offset = 11;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 6;
+		var->blue.offset = 0;
+		var->blue.length = 5;
+		break;
+	}
+
+#ifdef DBUG
+	printk("s1d13806_bpp_to_var done\n");
+#endif
+
+
+
+	return 0;
+}
+
+
+static int s1d13806_encode_var(struct fb_var_screeninfo *var, const void *raw_par,
+			    struct fb_info_gen *info)
+{
+	u8 panel, display;
+	u32 xres, xres_virtual, yres, yres_virtual;
+	static int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 18, -1 } };
+	static int bpp_tab[8] = { -1, -1, 4, 8, -1, 16, -1 };
+	int bpp, hw_bpp;
+	int is_color, is_tft;
+	int lcd_enabled;
+   int xoffset, yoffset;
+
+	display = s1d13806_read_reg(S1D13806_DISPLAY_MODE_REG);
+	panel = s1d13806_read_reg(S1D13806_PANEL_TYPE_REG);
+
+	is_color = (panel & 0x04) != 0;
+	is_tft   = (panel & 0x01) == 0x01;
+
+	bpp = bpp_tab[(display) & 0x07];/* BPP is in Bits 2:0 */
+	s1d13806_bpp_to_var(bpp, var);
+
+	lcd_enabled = (display & 0x80) == 0;/* when disabled, data outputs are zero*/
+
+	hw_bpp = width[is_tft][(panel>>4)&0x03];
+
+   /* Horizontal display period register: */
+	xres = s1d13806_read_reg(S1D13806_HOR_DISPLAY_WIDTH_REG) + 1;
+	xres *= 8;
+   /* Vertical display period register: */
+	yres = s1d13806_read_reg16(S1D13806_VERT_DISPLAY_HEIGHT_REG) + 1;
+
+   /* horizontal total resolution: */
+   xres_virtual = s1d13806_read_reg(S1D13806_VERT_NONDISPLAY_PERIOD_REG);
+	xres_virtual *= 8;
+	xres_virtual += xres;
+
+   /* vertical total resolution: */
+   yres_virtual = s1d13806_read_reg16(S1D13806_HOR_NONDISPLAY_PERIOD_REG) & 0x3F;
+	yres_virtual+=1;
+	yres_virtual+=yres;
+
+   /* there is no offset */
+	xoffset = 0;
+	yoffset = 0;
+
+	var->xres = xres;
+	var->yres = yres;
+	var->xres_virtual = xres_virtual;
+	var->yres_virtual = yres_virtual;
+
+	var->xoffset = xoffset;
+   var->yoffset = yoffset;
+
+	var->bits_per_pixel = bpp;
+	var->grayscale = !is_color;
+
+
+#ifdef DBUG
+	printk("s1d13806_encode_var done\n");
+#endif
+
+
+	return 0;
+}
+
+
+static void get_panel_data(struct s1d13806_par *par)
+{
+	u8 panel;
+	u8 display;
+	int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } };
+	int bpp_tab[8] = { -1, -1, 4, 8, -1, 16, -1, -1  };
+
+	panel = s1d13806_read_reg(S1D13806_PANEL_TYPE_REG) & 0x3F;
+	display = s1d13806_read_reg(S1D13806_DISPLAY_MODE_REG);
+
+
+	par->panel_width = width[panel&1][(panel>>4)&3];
+
+   /* horiz. display period reg.: */
+	par->panel_xres = (s1d13806_read_reg(S1D13806_HOR_DISPLAY_WIDTH_REG) + 1) * 8;
+   /* vert. displ. period reg.: */
+   par->panel_yres = (s1d13806_read_reg16(S1D13806_VERT_DISPLAY_HEIGHT_REG) + 1);
+	par->bpp = bpp_tab[(display) & 0x07]; /* BPP is in Bits 2:0 */
+
+
+	par->mem_bpp = par->bpp;
+	par->xres =	par->panel_xres;
+	par->yres = par->panel_yres;;
+
+
+#ifdef DBUG
+	printk("get_panel_data done\n");
+#endif
+
+}
+
+
+static void s1d13806_get_par(void *raw_par, struct fb_info_gen *info)
+{
+	struct s1d13806_par *par = raw_par;
+
+	get_panel_data(par);
+
+#ifdef DBUG
+	printk("s1d13806_get_par done\n");
+#endif
+
+}
+
+static void s1d13806_set_par(const void *par, struct fb_info_gen *info)
+{
+
+#ifdef DBUG
+	printk("s1d13806_set_par done\n");
+#endif
+
+}
+
+static int s1d13806_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+			   unsigned *blue, unsigned *transp,
+			   struct fb_info *info)
+{
+	u8 r, g, b;
+
+	s1d13806_write_reg(regno, S1D13806_LUT_ADDR_REG);
+	r = s1d13806_read_reg(S1D13806_LUT_DATA_REG);
+	g = s1d13806_read_reg(S1D13806_LUT_DATA_REG);
+	b = s1d13806_read_reg(S1D13806_LUT_DATA_REG);
+
+	*red = r << 8;
+	*green = g << 8;
+	*blue = b << 8;
+
+#ifdef DBUG
+	printk("s1d13806_getcolreg done\n");
+#endif
+
+
+	return 0;
+}
+
+
+/*
+ * Changes: 2002/12/13 adapted to s1d13806
+ */
+static int s1d13806_setcolreg(unsigned regno, unsigned red, unsigned green,
+			   unsigned blue, unsigned transp,
+			   struct fb_info *info)
+{
+	u8 r = (red >> 8) & 0xf0;
+	u8 g = (green>>8) & 0xf0;
+	u8 b = (blue>> 8) & 0xf0;
+
+	s1d13806_write_reg(regno, S1D13806_LUT_ADDR_REG);
+	s1d13806_write_reg(r, S1D13806_LUT_DATA_REG);
+	s1d13806_write_reg(g, S1D13806_LUT_DATA_REG);
+	s1d13806_write_reg(b, S1D13806_LUT_DATA_REG);
+
+#ifdef DBUG
+	printk("s1d13806_setcolreg done\n");
+#endif
+
+	return 0;
+}
+
+static int s1d13806_pan_display(const struct fb_var_screeninfo *var,
+			     struct fb_info_gen *info)
+{
+
+#ifdef DBUG
+	printk("s1d13806_pan_display done\n");
+#endif
+
+	BUG();
+
+	return -EINVAL;
+}
+
+#undef AERO_HACKS
+
+static int s1d13806_blank(int blank_mode, struct fb_info_gen *info)
+{
+	u8 disp;
+	u8 is_dual;
+
+
+
+	switch (blank_mode) {
+	case VESA_NO_BLANKING:
+		disp = s1d13806_read_reg(S1D13806_DISPLAY_MODE_REG);
+		disp |= 0x80;
+		s1d13806_write_reg(disp, S1D13806_DISPLAY_MODE_REG);
+		break;
+
+	case VESA_VSYNC_SUSPEND:
+	case VESA_HSYNC_SUSPEND:
+	case VESA_POWERDOWN:
+	default:
+
+		is_dual = s1d13806_read_reg(S1D13806_PANEL_TYPE_REG) & 0x02;
+		if(is_dual){
+			s1d13806_write_reg((s1d13806_read_reg(S1D13806_LCD_MISC_REG) | 0x01), S1D13806_LCD_MISC_REG);
+		}
+		disp = s1d13806_read_reg(S1D13806_DISPLAY_MODE_REG);
+		disp |= 0x80;
+		s1d13806_write_reg(disp, S1D13806_DISPLAY_MODE_REG);
+		break;
+
+	}
+#ifdef DBUG
+	printk("s1d13806_blank done\n");
+#endif
+
+	return 0;
+}
+
+static struct display_switch s1d13806_dispsw;
+
+static void s1d13806_set_disp(const void *unused, struct display *disp,
+			   struct fb_info_gen *info)
+{
+	struct display_switch *d;
+
+	disp->screen_base = (void *)S1D13806_FB_BASE;
+	disp->dispsw = &s1d13806_dispsw;
+
+	switch(disp->var.bits_per_pixel) {
+#ifdef FBCON_HAS_MFB
+	case 1:
+		d = &fbcon_mfb; break;
+#endif
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		d = &fbcon_cfb8; break;
+#endif
+	default:
+		BUG(); break;
+	}
+
+	memcpy(&s1d13806_dispsw, d, sizeof *d);
+
+#ifdef DBUG
+	printk("s1d13806_set_disp done\n");
+#endif
+
+}
+
+
+int __init s1d13806fb_setup(char *str)
+{
+
+#ifdef DBUG
+	printk("s1d13806fb_setup done\n");
+#endif
+	return 0;
+}
+
+int __init s1d13806fb_init(void)
+{
+
+  u8 * pRegs = (u8 *)S1D_PHYSICAL_REG_ADDR;
+  unsigned int idx=0;
+  unsigned int rgb;
+  unsigned int tmp, tmp1;
+
+
+#ifdef DBUG
+	printk("s1d13806fb_init started\n");
+#endif
+
+
+
+  /* Step 1 -> disable bus driver to display */
+//	s1d13806_write_reg(0, S1D13806_GPIO_CTL1_REG);
+
+	/* Step 2 -> there is no clock chip, so here's nothing to do*/
+
+
+	/* Step 3 -> Write to all S1D13806 registers*/
+	while (1)
+	{
+		if ( (aS1DRegs[idx].Index==0xffff) && (aS1DRegs[idx].Value==0xffff) )
+         break;
+
+      *(pRegs + aS1DRegs[idx].Index) = (u8)(aS1DRegs[idx].Value);
+      idx++;
+  }
+
+
+  /* Step 4: Update LookUp Table */
+
+	s1d13806_write_reg(0x01, S1D13806_LUT_MODE_REG);	// set to LCD LUT
+
+	// Enable the LCD LUT for read/write.
+	s1d13806_write_reg(0, S1D13806_LUT_ADDR_REG);	// Reset the LUT address.
+
+
+	for (idx = 0; idx < 256; idx++)
+	{
+		for (rgb = 0; rgb < 3; rgb++)
+		{
+			s1d13806_write_reg(LUT8_Color[3*idx+rgb], S1D13806_LUT_DATA_REG);
+		}
+	}
+
+
+  /* Step 5: Power Up LCD  */
+  /* Step 1 -> enable bus driver to display */
+	//s1d13806_write_reg(0x10, S1D13806_GPIO_CTL1_REG);
+	s1d13806_write_reg(0x18, S1D13806_GPIO_CONFIG1_REG);
+	s1d13806_write_reg(0x08, S1D13806_GPIO_CTL1_REG);
+
+
+	/* End of initializing the s1d13806 controller chip*/
+
+	fb_info.gen.fbhw = &s1d13806_switch;
+	fb_info.gen.fbhw->detect();
+	strcpy(fb_info.gen.info.modename, "S1D13806");
+	fb_info.gen.info.changevar = NULL;
+	fb_info.gen.info.node = -1;
+	fb_info.gen.info.fbops = &s1d13806fb_ops;
+	fb_info.gen.info.disp = &disp;
+	fb_info.gen.parsize = sizeof(struct s1d13806_par);
+	fb_info.gen.info.switch_con = &fbgen_switch;
+	fb_info.gen.info.updatevar = &fbgen_update_var;
+	fb_info.gen.info.blank = &fbgen_blank;
+	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
+	/* This should give a reasonable default video mode */
+	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
+	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
+	fbgen_set_disp(-1, &fb_info.gen);
+	if (disp.var.bits_per_pixel > 1)
+		fbgen_install_cmap(0, &fb_info.gen);
+	if (register_framebuffer(&fb_info.gen.info) < 0)
+		return -EINVAL;
+	printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.gen.info.node),
+	       fb_info.gen.info.modename);
+
+	return 0;
+}
+
+
+    /*
+     *  Cleanup
+     */
+
+void s1d13806fb_cleanup(struct fb_info *info)
+{
+	/*
+	 *  If your driver supports multiple boards, you should unregister and
+	 *  clean up all instances.
+	 */
+#ifdef DBUG
+	printk("s1d13806fb_cleanup done\n");
+#endif
+
+	unregister_framebuffer(info);
+	/* ... */
+
+
+}
+
+
+
+static void set_color_bitfields(struct fb_var_screeninfo *var)
+{
+    switch (var->bits_per_pixel) {
+	case 1:
+	    var->red.offset = 0;
+	    var->red.length = 1;
+	    var->green.offset = 0;
+	    var->green.length = 1;
+	    var->blue.offset = 0;
+	    var->blue.length = 1;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 8:
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 0;
+	    var->green.length = 8;
+	    var->blue.offset = 0;
+	    var->blue.length = 8;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 16:	/* RGB 565 */
+	    var->red.offset = 0;
+	    var->red.length = 5;
+	    var->green.offset = 5;
+	    var->green.length = 6;
+	    var->blue.offset = 11;
+	    var->blue.length = 5;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 24:	/* RGB 888 */
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 8;
+	    var->green.length = 8;
+	    var->blue.offset = 16;
+	    var->blue.length = 8;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 32:	/* RGBA 8888 */
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 8;
+	    var->green.length = 8;
+	    var->blue.offset = 16;
+	    var->blue.length = 8;
+	    var->transp.offset = 24;
+	    var->transp.length = 8;
+	    break;
+    }
+    var->red.msb_right = 0;
+    var->green.msb_right = 0;
+    var->blue.msb_right = 0;
+    var->transp.msb_right = 0;
+}
+
+
+static int s1d13806_get_fix(struct fb_fix_screeninfo *fix, int con,
+		       struct fb_info *info)
+{
+
+#ifdef DBUG
+	printk(KERN_DEBUG "fb%d: start: s1d13806_get_fix\n",
+		GET_FB_IDX(fb_info.gen.info.node));
+#endif
+
+    /* we only have one mode, so our fix_screeninfo struct
+       always has the same values, just throw it back to the user
+       current_fix was initialized earlier in init */
+
+#ifdef DBUG
+	printk(KERN_DEBUG "fb: info: getting fix for console %d\n", con);
+#endif
+
+    memcpy(fix, &current_fix, sizeof(struct fb_fix_screeninfo));
+
+    return 0;
+}
+
+
+    /*
+     *  Get the User Defined Part of the Display
+     */
+
+static int s1d13806_get_var(struct fb_var_screeninfo *var, int con,
+		       struct fb_info *info)
+{
+
+#ifdef DBUG
+	printk(KERN_DEBUG "fb%d: start: s1d13806_get_var\n",
+		GET_FB_IDX(fb_info.gen.info.node));
+
+	printk(KERN_DEBUG "fb: info: getting var for console %d\n", con);
+#endif
+
+    if (con == -1)
+	*var = default_var;
+    else
+	*var = fb_display[con].var;
+
+    set_color_bitfields(var);
+
+    return 0;
+}
+
+
+    /*
+     *  Set the User Defined Part of the Display
+     */
+
+static int s1d13806_set_var(struct fb_var_screeninfo *var, int con,
+		       struct fb_info *info)
+{
+    int activate = var->activate;
+
+    struct display *display;
+
+#ifdef DBUG
+	printk(KERN_DEBUG "fb%d: start: s1d13806_set_var\n",
+		GET_FB_IDX(fb_info.gen.info.node));
+#endif
+
+    if (con >= 0)
+    {
+		display = &fb_display[con];
+
+    }
+    else
+		display = &disp;	/* used during initialization */
+
+    /*
+     *  We are working with an LCD, which means that we
+     *  can't allow for modifications of many of the screen's
+     *  usually updateable parameters
+     */
+
+    if (var->xres != display->var.xres ||
+        var->yres != display->var.yres ||
+        var->xres_virtual != var->xres ||  /* virtual is not supported yet */
+        var->yres_virtual != var->yres ||
+        (var->xoffset != 0 && !(var->vmode & FB_VMODE_CONUPDATE)) ||
+        (var->yoffset != 0 && !(var->vmode & FB_VMODE_CONUPDATE)) ||
+        (var->bits_per_pixel != display->var.bits_per_pixel))
+    {
+	return -EINVAL;
+    }
+
+    set_color_bitfields(var);
+
+ /* Since we don't allow anything to change anyways,
+	there's no need to update the display var, makes
+	our lifes much easier :-)*/
+
+    return 0;
+}
+
+
+
+    /*
+     *  Get the Colormap
+     */
+
+static int s1d13806_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info)
+{
+    if (con == currcon) /* current console? */
+	return fb_get_cmap(cmap, kspc, s1d13806_getcolreg, info);
+    else if (fb_display[con].cmap.len) /* non default colormap? */
+	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+    else
+	fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+		     cmap, kspc ? 0 : 2);
+    return 0;
+}
+
+    /*
+     *  Set the Colormap
+     */
+
+static int s1d13806_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info)
+{
+    int err;
+
+    if (!fb_display[con].cmap.len) {	/* no colormap allocated? */
+	if ((err = fb_alloc_cmap(&fb_display[con].cmap,
+			      1<<fb_display[con].var.bits_per_pixel, 0)))
+	    return err;
+    }
+    if (con == currcon)			/* current console? */
+	return fb_set_cmap(cmap, kspc, s1d13806_setcolreg, info);
+    else
+	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+    return 0;
+}
+
+
+MODULE_LICENSE("GPL");
+
diff -urN linux-2.4.29/drivers/video/s1d13806fb.h linux-2.4.29-uc1/drivers/video/s1d13806fb.h
--- linux-2.4.29/drivers/video/s1d13806fb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/s1d13806fb.h	2005-06-14 02:12:27.000000000 +0100
@@ -0,0 +1,410 @@
+/*
+ * linux/drivers/video/s1d13806fb.h
+ *	-- Support for the Epson SED13806 LCD/CRT controller
+ *
+ * Copyright (C) 2003 Heiko Degenhardt <linux@sentec-elektronik.de>
+ *                    Michael Huhn <michael.huhn@sentec-elektronik.de>
+ *
+ * Some ideas were "stolen" from
+ *    linux/drivers/video/epson1355fb.c
+ *    that is "Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>"
+ * and from s1d13xxxfb.c and a file called "s1d13806.h" that was
+ *    generated by S1D13806CFG.EXE both are
+ *    "Copyright(c) 2000, 2001 Epson Research and Development, Inc"
+ *
+ * HINT: If someone feels that we used his code but didn't give him
+ * credits here, please email us! It was a quite complicated thing to
+ * get all that working, so may be we just forgot someone! Thanks!
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * CHANGES
+ *
+ * 20040205
+ * - Changed memory size (thanks to Matthias Babylon)
+ * - Added S1D13806_GPIO_CONFIG1_REG (needed for startup)
+ * - Changed S1D13806_GPIO_CTL1_REG to 0x09 (for startup)
+ * (woel, hede)
+ *
+ * 20030408
+ *    Creation
+ *    (woel, mihu)
+ */
+
+/*
+ *
+ * ATTENTION!
+ * This stuff is _really_ experimental, currently!
+ * Feedback is really welcome!
+ *
+ */
+
+/* Register defines. */
+
+#define S1D13806_REVISION_CODE_REG		0x00
+
+/* LUT */
+#define S1D13806_LUT_MODE_REG	0x01E0
+#define S1D13806_LUT_ADDR_REG	0x01E2
+#define S1D13806_LUT_DATA_REG	0x01E4
+
+
+#define S1D13806_GPIO_CONFIG1_REG	0x05
+#define S1D13806_GPIO_CTL1_REG	0x09
+#define S1D13806_PANEL_TYPE_REG		0x30
+#define S1D13806_DISPLAY_MODE_REG		0x40
+#define S1D13806_HOR_DISPLAY_WIDTH_REG	0x32
+#define S1D13806_VERT_DISPLAY_HEIGHT_REG	0x38
+
+#define S1D13806_VERT_NONDISPLAY_PERIOD_REG	0x34
+#define S1D13806_HOR_NONDISPLAY_PERIOD_REG	0x3A
+#define S1D13806_TFT_LINE_START_POS_REG	0x35
+#define S1D13806_LCD_MISC_REG	0x41
+
+
+/* The following defines are specific for our board layout! */
+
+#ifdef CONFIG_COBRA5272
+#define S1D13806_REG_OFFSET   0x40000000
+#define S1D13806_FB_OFFSET    0x200000
+#define S1D13806_SRAM_SIZE		0x140000
+
+#define S1D13806_REG_BASE	MCF_MBAR + S1D13806_REG_OFFSET
+#define S1D13806_FB_BASE	S1D13806_REG_OFFSET + S1D13806_FB_OFFSET
+
+#define S1D_PHYSICAL_REG_ADDR       S1D13806_REG_OFFSET
+#define S1D_PHYSICAL_VMEM_ADDR      S1D13806_FB_BASE
+#define S1D_PHYSICAL_VMEM_SIZE      0x140000L
+
+
+#else
+#error unknown architecture
+#endif
+
+struct s1d13806fb_info {
+   struct fb_info_gen gen;
+};
+
+struct s1d13806_par {
+	u32 xres;
+	u32 yres;
+
+	int bpp;
+	int mem_bpp;
+
+	u32 panel_xres;
+	u32 panel_yres;
+
+	int panel_width;
+};
+
+
+/* Prototypes */
+static void s1d13806_detect(void);
+int s1d13806fb_init(void);
+int s1d13806fb_setup(char*);
+static int s1d13806_encode_fix(struct fb_fix_screeninfo *fix,
+				const void *raw_par,
+				struct fb_info_gen *info);
+static int s1d13806_set_bpp(struct s1d13806_par *par, int bpp);
+static int s1d13806_decode_var(const struct fb_var_screeninfo *var,
+				void *raw_par,
+				struct fb_info_gen *info);
+static void dump_panel_data(void);
+static int s1d13806_bpp_to_var(int bpp, struct fb_var_screeninfo *var);
+static int s1d13806_encode_var(struct fb_var_screeninfo *var,
+				const void *raw_par,
+				struct fb_info_gen *info);
+static void get_panel_data(struct s1d13806_par *par);
+static void s1d13806_get_par(void *raw_par, struct fb_info_gen *info);
+static void s1d13806_set_par(const void *par, struct fb_info_gen *info);
+static int s1d13806_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+				unsigned *blue, unsigned *transp,
+				struct fb_info *info);
+static int s1d13806_setcolreg(unsigned regno, unsigned red, unsigned green,
+				unsigned blue, unsigned transp,
+				struct fb_info *info);
+static int s1d13806_pan_display(const struct fb_var_screeninfo *var,
+				struct fb_info_gen *info);
+static int s1d13806_blank(int blank_mode, struct fb_info_gen *info);
+static void s1d13806_set_disp(const void *unused, struct display *disp,
+				struct fb_info_gen *info);
+static struct s1d13806fb_info fb_info;
+int __init s1d13806fb_setup(char *str);
+int __init s1d13806fb_init(void);
+void s1d13806fb_cleanup(struct fb_info *info);
+
+
+static void set_color_bitfields(struct fb_var_screeninfo *var);
+static int s1d13806_get_fix(struct fb_fix_screeninfo *fix, int con,
+				struct fb_info *info);
+static int s1d13806_get_var(struct fb_var_screeninfo *var, int con,
+				struct fb_info *info);
+static int s1d13806_set_var(struct fb_var_screeninfo *var, int con,
+				struct fb_info *info);
+static int s1d13806_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+				struct fb_info *info);
+static int s1d13806_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+				struct fb_info *info);
+
+
+/* ------------ Interfaces to hardware functions ------------ */
+
+struct fbgen_hwswitch s1d13806_switch = {
+	detect:		s1d13806_detect,
+	encode_fix:	s1d13806_encode_fix,
+	decode_var:	s1d13806_decode_var,
+	encode_var:	s1d13806_encode_var,
+	get_par:	s1d13806_get_par,
+	set_par:	s1d13806_set_par,
+	getcolreg:	s1d13806_getcolreg,
+	setcolreg:	s1d13806_setcolreg,
+	pan_display:	s1d13806_pan_display,
+	blank:		s1d13806_blank,
+	set_disp:	s1d13806_set_disp,
+};
+
+
+/* ------------ Hardware Independent Functions ------------ */
+
+static struct fb_ops s1d13806fb_ops = {
+	owner:		THIS_MODULE,
+	fb_get_fix:	s1d13806_get_fix,
+	fb_get_var:	s1d13806_get_var,
+	fb_set_var:	s1d13806_set_var,
+	fb_get_cmap:	s1d13806_get_cmap,
+	fb_set_cmap:	s1d13806_set_cmap,
+	fb_pan_display:	fbgen_pan_display,
+};
+
+
+/* The following lines are for the initialization of the controller */
+
+typedef unsigned short S1D_INDEX;
+typedef unsigned short S1D_VALUE;
+
+typedef struct
+{
+    S1D_INDEX Index;
+    S1D_VALUE Value;
+} S1D_REGS;
+
+static S1D_REGS aS1DRegs[] =
+{
+   {0x0001,    0x00},   // Miscellaneous Register
+   {0x01FC,    0x00},   // Display Mode Register
+   {0x0004,    0x00},   // General IO Pins Configuration Register 0
+   {0x0005,    0x08},   // General IO Pins Configuration Register 1
+   {0x0008,    0x00},   // General IO Pins Control Register 0
+   {0x0009,    0x00},   // General IO Pins Control Register 1
+   {0x0010,    0x11},   // Memory Clock Configuration Register
+   {0x0014,    0x33},   // LCD Pixel Clock Configuration Register
+   {0x0018,    0x01},   // CRT/TV Pixel Clock Configuration Register
+   {0x001C,    0x01},   // MediaPlug Clock Configuration Register
+   {0x001E,    0x00},   // CPU To Memory Wait State Select Register
+   {0x0020,    0x80},   // Memory Configuration Register
+   {0x0021,    0x03},   // DRAM Refresh Rate Register
+   {0x002A,    0x00},   // DRAM Timings Control Register 0
+   {0x002B,    0x12},   // DRAM Timings Control Register 1
+   {0x0030,    0x1C},   // Panel Type Register
+   {0x0031,    0x00},   // MOD Rate Register
+   {0x0032,    0x27},   // LCD Horizontal Display Width Register
+   {0x0034,    0x0D},   // LCD Horizontal Non-Display Period Register
+   {0x0035,    0x00},   // TFT FPLINE Start Position Register
+   {0x0036,    0x00},   // TFT FPLINE Pulse Width Register
+   {0x0038,    0xEF},   // LCD Vertical Display Height Register 0
+   {0x0039,    0x00},   // LCD Vertical Display Height Register 1
+   {0x003A,    0x0A},   // LCD Vertical Non-Display Period Register
+   {0x003B,    0x00},   // TFT FPFRAME Start Position Register
+   {0x003C,    0x00},   // TFT FPFRAME Pulse Width Register
+   {0x0040,    0x03},   // LCD Display Mode Register
+   {0x0041,    0x00},   // LCD Miscellaneous Register
+   {0x0042,    0x00},   // LCD Display Start Address Register 0
+   {0x0043,    0x00},   // LCD Display Start Address Register 1
+   {0x0044,    0x00},   // LCD Display Start Address Register 2
+   {0x0046,    0xA0},   // LCD Memory Address Offset Register 0
+   {0x0047,    0x00},   // LCD Memory Address Offset Register 1
+   {0x0048,    0x00},   // LCD Pixel Panning Register
+   {0x004A,    0x00},   // LCD Display FIFO High Threshold Control Register
+   {0x004B,    0x00},   // LCD Display FIFO Low Threshold Control Register
+   {0x0050,    0x00},   // CRT/TV Horizontal Display Width Register
+   {0x0052,    0x00},   // CRT/TV Horizontal Non-Display Period Register
+   {0x0053,    0x00},   // CRT/TV HRTC Start Position Register
+   {0x0054,    0x00},   // CRT/TV HRTC Pulse Width Register
+   {0x0056,    0x00},   // CRT/TV Vertical Display Height Register 0
+   {0x0057,    0x00},   // CRT/TV Vertical Display Height Register 1
+   {0x0058,    0x00},   // CRT/TV Vertical Non-Display Period Register
+   {0x0059,    0x00},   // CRT/TV VRTC Start Position Register
+   {0x005A,    0x00},   // CRT/TV VRTC Pulse Width Register
+   {0x005B,    0x00},   // TV Output Control Register
+   {0x0060,    0x00},   // CRT/TV Display Mode Register
+   {0x0062,    0x00},   // CRT/TV Display Start Address Register 0
+   {0x0063,    0x00},   // CRT/TV Display Start Address Register 1
+   {0x0064,    0x00},   // CRT/TV Display Start Address Register 2
+   {0x0066,    0x00},   // CRT/TV Memory Address Offset Register 0
+   {0x0067,    0x00},   // CRT/TV Memory Address Offset Register 1
+   {0x0068,    0x00},   // CRT/TV Pixel Panning Register
+   {0x006A,    0x00},   // CRT/TV Display FIFO High Threshold Control Register
+   {0x006B,    0x00},   // CRT/TV Display FIFO Low Threshold Control Register
+   {0x0070,    0x00},   // LCD Ink/Cursor Control Register
+   {0x0071,    0x00},   // LCD Ink/Cursor Start Address Register
+   {0x0072,    0x00},   // LCD Cursor X Position Register 0
+   {0x0073,    0x00},   // LCD Cursor X Position Register 1
+   {0x0074,    0x00},   // LCD Cursor Y Position Register 0
+   {0x0075,    0x00},   // LCD Cursor Y Position Register 1
+   {0x0076,    0x00},   // LCD Ink/Cursor Blue Color 0 Register
+   {0x0077,    0x00},   // LCD Ink/Cursor Green Color 0 Register
+   {0x0078,    0x00},   // LCD Ink/Cursor Red Color 0 Register
+   {0x007A,    0x00},   // LCD Ink/Cursor Blue Color 1 Register
+   {0x007B,    0x00},   // LCD Ink/Cursor Green Color 1 Register
+   {0x007C,    0x00},   // LCD Ink/Cursor Red Color 1 Register
+   {0x007E,    0x00},   // LCD Ink/Cursor FIFO Threshold Register
+   {0x0080,    0x00},   // CRT/TV Ink/Cursor Control Register
+   {0x0081,    0x00},   // CRT/TV Ink/Cursor Start Address Register
+   {0x0082,    0x00},   // CRT/TV Cursor X Position Register 0
+   {0x0083,    0x00},   // CRT/TV Cursor X Position Register 1
+   {0x0084,    0x00},   // CRT/TV Cursor Y Position Register 0
+   {0x0085,    0x00},   // CRT/TV Cursor Y Position Register 1
+   {0x0086,    0x00},   // CRT/TV Ink/Cursor Blue Color 0 Register
+   {0x0087,    0x00},   // CRT/TV Ink/Cursor Green Color 0 Register
+   {0x0088,    0x00},   // CRT/TV Ink/Cursor Red Color 0 Register
+   {0x008A,    0x00},   // CRT/TV Ink/Cursor Blue Color 1 Register
+   {0x008B,    0x00},   // CRT/TV Ink/Cursor Green Color 1 Register
+   {0x008C,    0x00},   // CRT/TV Ink/Cursor Red Color 1 Register
+   {0x008E,    0x00},   // CRT/TV Ink/Cursor FIFO Threshold Register
+   {0x0100,    0x00},   // BitBlt Control Register 0
+   {0x0101,    0x00},   // BitBlt Control Register 1
+   {0x0102,    0x00},   // BitBlt ROP Code/Color Expansion Register
+   {0x0103,    0x00},   // BitBlt Operation Register
+   {0x0104,    0x00},   // BitBlt Source Start Address Register 0
+   {0x0105,    0x00},   // BitBlt Source Start Address Register 1
+   {0x0106,    0x00},   // BitBlt Source Start Address Register 2
+   {0x0108,    0x00},   // BitBlt Destination Start Address Register 0
+   {0x0109,    0x00},   // BitBlt Destination Start Address Register 1
+   {0x010A,    0x00},   // BitBlt Destination Start Address Register 2
+   {0x010C,    0x00},   // BitBlt Memory Address Offset Register 0
+   {0x010D,    0x00},   // BitBlt Memory Address Offset Register 1
+   {0x0110,    0x00},   // BitBlt Width Register 0
+   {0x0111,    0x00},   // BitBlt Width Register 1
+   {0x0112,    0x00},   // BitBlt Height Register 0
+   {0x0113,    0x00},   // BitBlt Height Register 1
+   {0x0114,    0x00},   // BitBlt Background Color Register 0
+   {0x0115,    0x00},   // BitBlt Background Color Register 1
+   {0x0118,    0x00},   // BitBlt Foreground Color Register 0
+   {0x0119,    0x00},   // BitBlt Foreground Color Register 1
+   {0x01E0,    0x00},   // Look-Up Table Mode Register
+   {0x01E2,    0x00},   // Look-Up Table Address Register
+   {0x01F0,    0x10},   // Power Save Configuration Register
+   {0x01F1,    0x00},   // Power Save Status Register
+   {0x01F4,    0x00},   // CPU-to-Memory Access Watchdog Timer Register
+   {0x01FC,    0x01},   // Display Mode Register
+
+   {0xffff,0xffff},   //end of the table
+};
+
+
+u8 LUT8_Color[256*3] =
+{
+/* Primary and secondary colors */
+0x00, 0x00, 0x00,  0x00, 0x00, 0xA0,  0x00, 0xA0, 0x00,  0x00, 0xA0, 0xA0,
+0xA0, 0x00, 0x00,  0xA0, 0x00, 0xA0,  0xA0, 0xA0, 0x00,  0xA0, 0xA0, 0xA0,
+0x50, 0x50, 0x50,  0x00, 0x00, 0xF0,  0x00, 0xF0, 0x00,  0x00, 0xF0, 0xF0,
+0xF0, 0x00, 0x00,  0xF0, 0x00, 0xF0,  0xF0, 0xF0, 0x00,  0xF0, 0xF0, 0xF0,
+
+/* Gray shades */
+0x00, 0x00, 0x00,  0x10, 0x10, 0x10,  0x20, 0x20, 0x20,  0x30, 0x30, 0x30,
+0x40, 0x40, 0x40,  0x50, 0x50, 0x50,  0x60, 0x60, 0x60,  0x70, 0x70, 0x70,
+0x80, 0x80, 0x80,  0x90, 0x90, 0x90,  0xA0, 0xA0, 0xA0,  0xB0, 0xB0, 0xB0,
+0xC0, 0xC0, 0xC0,  0xD0, 0xD0, 0xD0,  0xE0, 0xE0, 0xE0,  0xF0, 0xF0, 0xF0,
+
+/* Black to red */
+0x00, 0x00, 0x00,  0x10, 0x00, 0x00,  0x20, 0x00, 0x00,  0x30, 0x00, 0x00,
+0x40, 0x00, 0x00,  0x50, 0x00, 0x00,  0x60, 0x00, 0x00,  0x70, 0x00, 0x00,
+0x80, 0x00, 0x00,  0x90, 0x00, 0x00,  0xA0, 0x00, 0x00,  0xB0, 0x00, 0x00,
+0xC0, 0x00, 0x00,  0xD0, 0x00, 0x00,  0xE0, 0x00, 0x00,  0xF0, 0x00, 0x00,
+
+/* Black to green */
+0x00, 0x00, 0x00,  0x00, 0x10, 0x00,  0x00, 0x20, 0x00,  0x00, 0x30, 0x00,
+0x00, 0x40, 0x00,  0x00, 0x50, 0x00,  0x00, 0x60, 0x00,  0x00, 0x70, 0x00,
+0x00, 0x80, 0x00,  0x00, 0x90, 0x00,  0x00, 0xA0, 0x00,  0x00, 0xB0, 0x00,
+0x00, 0xC0, 0x00,  0x00, 0xD0, 0x00,  0x00, 0xE0, 0x00,  0x00, 0xF0, 0x00,
+
+/* Black to blue */
+0x00, 0x00, 0x00,  0x00, 0x00, 0x10,  0x00, 0x00, 0x20,  0x00, 0x00, 0x30,
+0x00, 0x00, 0x40,  0x00, 0x00, 0x50,  0x00, 0x00, 0x60,  0x00, 0x00, 0x70,
+0x00, 0x00, 0x80,  0x00, 0x00, 0x90,  0x00, 0x00, 0xA0,  0x00, 0x00, 0xB0,
+0x00, 0x00, 0xC0,  0x00, 0x00, 0xD0,  0x00, 0x00, 0xE0,  0x00, 0x00, 0xF0,
+
+/* Blue to cyan (blue and green) */
+0x00, 0x00, 0xF0,  0x00, 0x10, 0xF0,  0x00, 0x20, 0xF0,  0x00, 0x30, 0xF0,
+0x00, 0x40, 0xF0,  0x00, 0x50, 0xF0,  0x00, 0x60, 0xF0,  0x00, 0x70, 0xF0,
+0x00, 0x80, 0xF0,  0x00, 0x90, 0xF0,  0x00, 0xA0, 0xF0,  0x00, 0xB0, 0xF0,
+0x00, 0xC0, 0xF0,  0x00, 0xD0, 0xF0,  0x00, 0xE0, 0xF0,  0x00, 0xF0, 0xF0,
+
+/* Cyan (blue and green) to green */
+0x00, 0xF0, 0xF0,  0x00, 0xF0, 0xE0,  0x00, 0xF0, 0xD0,  0x00, 0xF0, 0xC0,
+0x00, 0xF0, 0xB0,  0x00, 0xF0, 0xA0,  0x00, 0xF0, 0x90,  0x00, 0xF0, 0x80,
+0x00, 0xF0, 0x70,  0x00, 0xF0, 0x60,  0x00, 0xF0, 0x50,  0x00, 0xF0, 0x40,
+0x00, 0xF0, 0x30,  0x00, 0xF0, 0x20,  0x00, 0xF0, 0x10,  0x00, 0xF0, 0x00,
+
+/* Green to yellow (red and green) */
+0x00, 0xF0, 0x00,  0x10, 0xF0, 0x00,  0x20, 0xF0, 0x00,  0x30, 0xF0, 0x00,
+0x40, 0xF0, 0x00,  0x50, 0xF0, 0x00,  0x60, 0xF0, 0x00,  0x70, 0xF0, 0x00,
+0x80, 0xF0, 0x00,  0x90, 0xF0, 0x00,  0xA0, 0xF0, 0x00,  0xB0, 0xF0, 0x00,
+0xC0, 0xF0, 0x00,  0xD0, 0xF0, 0x00,  0xE0, 0xF0, 0x00,  0xF0, 0xF0, 0x00,
+
+/* Yellow (red and green) to red */
+0xF0, 0xF0, 0x00,  0xF0, 0xE0, 0x00,  0xF0, 0xD0, 0x00,  0xF0, 0xC0, 0x00,
+0xF0, 0xB0, 0x00,  0xF0, 0xA0, 0x00,  0xF0, 0x90, 0x00,  0xF0, 0x80, 0x00,
+0xF0, 0x70, 0x00,  0xF0, 0x60, 0x00,  0xF0, 0x50, 0x00,  0xF0, 0x40, 0x00,
+0xF0, 0x30, 0x00,  0xF0, 0x20, 0x00,  0xF0, 0x10, 0x00,  0xF0, 0x00, 0x00,
+
+/* Red to magenta (blue and red) */
+0xF0, 0x00, 0x00,  0xF0, 0x00, 0x10,  0xF0, 0x00, 0x20,  0xF0, 0x00, 0x30,
+0xF0, 0x00, 0x40,  0xF0, 0x00, 0x50,  0xF0, 0x00, 0x60,  0xF0, 0x00, 0x70,
+0xF0, 0x00, 0x80,  0xF0, 0x00, 0x90,  0xF0, 0x00, 0xA0,  0xF0, 0x00, 0xB0,
+0xF0, 0x00, 0xC0,  0xF0, 0x00, 0xD0,  0xF0, 0x00, 0xE0,  0xF0, 0x00, 0xF0,
+
+/* Magenta (blue and red) to blue */
+0xF0, 0x00, 0xF0,  0xE0, 0x00, 0xF0,  0xD0, 0x00, 0xF0,  0xC0, 0x00, 0xF0,
+0xB0, 0x00, 0xF0,  0xA0, 0x00, 0xF0,  0x90, 0x00, 0xF0,  0x80, 0x00, 0xF0,
+0x70, 0x00, 0xF0,  0x60, 0x00, 0xF0,  0x50, 0x00, 0xF0,  0x40, 0x00, 0xF0,
+0x30, 0x00, 0xF0,  0x20, 0x00, 0xF0,  0x10, 0x00, 0xF0,  0x00, 0x00, 0xF0,
+
+/* Black to magenta (blue and red) */
+0x00, 0x00, 0x00,  0x10, 0x00, 0x10,  0x20, 0x00, 0x20,  0x30, 0x00, 0x30,
+0x40, 0x00, 0x40,  0x50, 0x00, 0x50,  0x60, 0x00, 0x60,  0x70, 0x00, 0x70,
+0x80, 0x00, 0x80,  0x90, 0x00, 0x90,  0xA0, 0x00, 0xA0,  0xB0, 0x00, 0xB0,
+0xC0, 0x00, 0xC0,  0xD0, 0x00, 0xD0,  0xE0, 0x00, 0xE0,  0xF0, 0x00, 0xF0,
+
+/* Black to cyan (blue and green) */
+0x00, 0x00, 0x00,  0x00, 0x10, 0x10,  0x00, 0x20, 0x20,  0x00, 0x30, 0x30,
+0x00, 0x40, 0x40,  0x00, 0x50, 0x50,  0x00, 0x60, 0x60,  0x00, 0x70, 0x70,
+0x00, 0x80, 0x80,  0x00, 0x90, 0x90,  0x00, 0xA0, 0xA0,  0x00, 0xB0, 0xB0,
+0x00, 0xC0, 0xC0,  0x00, 0xD0, 0xD0,  0x00, 0xE0, 0xE0,  0x00, 0xF0, 0xF0,
+
+/* Red to white */
+0xF0, 0x00, 0x00,  0xF0, 0x10, 0x10,  0xF0, 0x20, 0x20,  0xF0, 0x30, 0x30,
+0xF0, 0x40, 0x40,  0xF0, 0x50, 0x50,  0xF0, 0x60, 0x60,  0xF0, 0x70, 0x70,
+0xF0, 0x80, 0x80,  0xF0, 0x90, 0x90,  0xF0, 0xA0, 0xA0,  0xF0, 0xB0, 0xB0,
+0xF0, 0xC0, 0xC0,  0xF0, 0xD0, 0xD0,  0xF0, 0xE0, 0xE0,  0xF0, 0xF0, 0xF0,
+
+/* Green to white */
+0x00, 0xF0, 0x00,  0x10, 0xF0, 0x10,  0x20, 0xF0, 0x20,  0x30, 0xF0, 0x30,
+0x40, 0xF0, 0x40,  0x50, 0xF0, 0x50,  0x60, 0xF0, 0x60,  0x70, 0xF0, 0x70,
+0x80, 0xF0, 0x80,  0x90, 0xF0, 0x90,  0xA0, 0xF0, 0xA0,  0xB0, 0xF0, 0xB0,
+0xC0, 0xF0, 0xC0,  0xD0, 0xF0, 0xD0,  0xE0, 0xF0, 0xE0,  0xF0, 0xF0, 0xF0,
+
+/* Blue to white */
+0x00, 0x00, 0xF0,  0x10, 0x10, 0xF0,  0x20, 0x20, 0xF0,  0x30, 0x30, 0xF0,
+0x40, 0x40, 0xF0,  0x50, 0x50, 0xF0,  0x60, 0x60, 0xF0,  0x70, 0x70, 0xF0,
+0x80, 0x80, 0xF0,  0x90, 0x90, 0xF0,  0xA0, 0xA0, 0xF0,  0xB0, 0xB0, 0xF0,
+0xC0, 0xC0, 0xF0,  0xD0, 0xD0, 0xF0,  0xE0, 0xE0, 0xF0,  0xF0, 0xF0, 0xF0
+};
+
+/*==========================================================================*/
+
diff -urN linux-2.4.29/drivers/video/s3c44b0xfb.c linux-2.4.29-uc1/drivers/video/s3c44b0xfb.c
--- linux-2.4.29/drivers/video/s3c44b0xfb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/s3c44b0xfb.c	2005-06-14 02:12:26.000000000 +0100
@@ -0,0 +1,761 @@
+/*
+ * linux/drivers/video/s3c44b0xfb.c 
+ *
+ * Copyright (C) 2003 Stefan Macher <macher@sympat.de>
+ *                    Alexander Assel <assel@sympat.de>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/* TODO (roughly in order of priority):
+ * color gray / (monochrom) 2 bpp (8 bpp color)
+ * configuration via modul parameters and i/o control 
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include "linux/config.h"
+
+#include <video/fbcon.h>
+
+#include "s3c44b0xfb.h"
+#include "asm-armnommu/arch-S3C44B0X/s3c44b0x.h"
+
+/*---------------------------------*/
+/* global parameters               */
+/*---------------------------------*/
+static int s3c44b0x_lcd_index; /*!< index within panels; will be set according to panel_name */
+#if MODULE /* in case of module the panel name is set as module parameter */
+static u8 panel_valid = 0;
+static unsigned char *panel_name = NULL;
+#else /* FIXME this should be similar to module but as linux boot line parameter */
+static u8 panel_valid = 1;
+static unsigned char *panel_name = "LCDBA7T11M4_320x240x8";
+#endif
+static u8 bootloader = 0; /* use bootloader settings for LCD controller setup */
+static struct fb_ops s3c44b0xfb_ops;
+struct fbgen_hwswitch s3c44b0xfb_switch;
+
+
+/*---------------------------------*/
+/* parameter decleration           */
+/*---------------------------------*/
+
+#if MODULE
+MODULE_PARM(panel_name, "s");
+MODULE_PARM_DESC(panel_name, "Name of the connected panel\nknown panels are: LCDBA7T11M4_320x240x8");
+MODULE_PARM(bootloader, "b");
+MODULE_PARM_DESC(bootloader, "Set it to 1 if you want the device driver to use the parameters that has the bootloader configured\n");
+MODULE_AUTHOR("Alexander Assel  <asselv@sympat.de> Stefan Macher <macher@sympat.de>");
+MODULE_DESCRIPTION("S3C44B0X LCD framebuffer device driver");
+#endif
+/*--------------------------------*/
+
+
+
+/**************************************
+ * definition of the known displays
+ **************************************/
+/* if you add some new panels in the struct bellow change also the
+   module description on the end of this file
+*/
+struct known_lcd_panels panels[] = { {
+	/* holds the lcd panel name */
+	"LCDBA7T11M4_320x240x8",
+	/* clkval */
+	15, /* FIXME this is based on a cpu clock of 60,75 MHz */
+	/* Determine the VLINE pulses high level width [clocks] valid values 4, 8, 12 and 16 */
+	16,
+	/* Determine the delay between VLINE and VCLOCK [clocks] valid values 4, 8, 12 and 16 */
+	16,
+	/* Determine toggle rate of VM 0 -> each frame 1 -> defined by MVAL */
+	0,
+	/* display mode is 8 bit single scan */
+	2,
+       /* controls the poloarity of VCLOCK active edge 0 -> falling edge 1 -> rising edge */
+	0,
+	/* indicate the line pulse polarity 0 -> normal 1 -> inverted */
+	0,
+	/* indicate the frame pulse polarity 0 -> normal 1 -> inverted */
+	0,
+	/* indicates the video data polarity 0 -> normal 1 -> inverted */
+	0,
+	/* indicates the blank time in one horizontal line duration */
+	10,
+	/* LCD self refrash mode enable */
+	0,
+	/* byte swap control */
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	0,
+#else	
+	1,
+#endif
+  /* defines the rate at which the vm signal will toggle */
+	0x0D, 
+  /* display width in pixels */
+	320,
+  /* display height in pixels */
+	240,
+  /* bits per pixel valid is 1 (mono), 2 (gray), 4 (gray) and 8 (color) */
+	8,
+	119, /* hozval */
+	239, /* lineval */
+	S3C44B0X_PDATC, /* port register for enabling the display */
+	(1<<8), /* mask port c pin 8 */
+	(1<<8), /* set port c pin 8 to high */
+	S3C44B0X_PCONC, /* port control register for setting PORTC.8 to output */
+	(3<<16), /* mask port c pin8 control */
+	(1<<16) /* set port c pin 8 control to output */
+}
+};
+ 
+
+static struct s3c44b0xfb_info fb_info;
+static struct s3c44b0xfb_par current_par;
+static int current_par_valid = 0;
+
+int s3c44b0xfb_init(void);
+int s3c44b0xfb_setup(char*);
+
+/* ------------------- chipset specific functions -------------------------- */
+
+
+static void s3c44b0xfb_detect(void)
+{
+        /*
+	 * Yeh, well, we're not going to change any settings so we're
+	 * always stuck with the default ...
+	 */
+}
+
+static int s3c44b0xfb_encode_fix(struct fb_fix_screeninfo *fix, const void *_par,
+			       struct fb_info_gen *_info)
+{
+    /*
+     *  This function should fill in the 'fix' structure based on the values
+     *  in the `par' structure.
+     */
+	struct s3c44b0xfb_info *info = (struct s3c44b0xfb_info *) _info;
+        struct s3c44b0xfb_par *par = (struct s3c44b0xfb_par *) _par;
+	struct fb_var_screeninfo *var = &par->var;
+
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+
+	fix->smem_start = info->fb_phys;
+	fix->smem_len = info->fb_size;
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->type_aux = 0;
+        fix->visual = (var->bits_per_pixel == 1) ?
+	       	FB_VISUAL_MONO01 : FB_VISUAL_TRUECOLOR;
+	fix->ywrapstep = 0;
+	fix->xpanstep = 0;
+	fix->ypanstep = 0;
+	fix->line_length = current_par.line_length;
+	return 0;
+
+}
+
+static int s3c44b0xfb_decode_var(const struct fb_var_screeninfo *var, void *par,
+			       struct fb_info_gen *info)
+{
+    /*
+     *  Get the video params out of 'var'. If a value doesn't fit, round it up,
+     *  if it's too big, return -EINVAL.
+     *
+     *  Suggestion: Round up in the following order: bits_per_pixel, xres,
+     *  yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
+     *  bitfields, horizontal timing, vertical timing.
+     */
+	struct known_lcd_panels *p_lcd = &panels[s3c44b0x_lcd_index];
+	if (var->xres != p_lcd->width ||
+	    var->yres != p_lcd->height)
+	{
+		return -EINVAL;
+	}
+
+	if(var->bits_per_pixel != p_lcd->bpp) 
+	{
+		return -EINVAL;
+	}
+	return 0;
+
+}
+
+static int s3c44b0xfb_encode_var(struct fb_var_screeninfo *var, const void *_par,
+			       struct fb_info_gen *info)
+{
+    /*
+     *  Fill the 'var' structure based on the values in 'par' and maybe other
+     *  values read out of the hardware.
+     */
+	struct s3c44b0xfb_par *par = (struct s3c44b0xfb_par*)_par;
+
+	memcpy(var, &par->var, sizeof(struct fb_var_screeninfo));
+   
+	return 0;
+}
+
+static void s3c44b0xfb_get_par(void *_par, struct fb_info_gen *info)
+{
+	/*
+	 *  Fill the hardware's 'par' structure.
+	 */
+	
+	struct s3c44b0xfb_par *par = (struct s3c44b0xfb_par*)_par;
+	if (current_par_valid)
+		memcpy(par, &current_par, sizeof(struct s3c44b0xfb_par));
+}
+
+static void s3c44b0xfb_set_par(const void *par, struct fb_info_gen *info)
+{
+    /*
+     *  Set the hardware according to 'par'.
+     */
+    /* nothing to do: we don't change any settings */
+  
+}
+
+static int s3c44b0xfb_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+			 unsigned *blue, unsigned *transp,
+			 struct fb_info *_info)
+{
+    /*
+     *  Read a single color register and split it into colors/transparent.
+     *  The return values must have a 16 bit magnitude.
+     *  Return != 0 for invalid regno.
+     */
+	struct s3c44b0xfb_info *info = (struct s3c44b0xfb_info *) _info;
+	u32 blueval, redval, greenval;
+	u8 helpvalue;
+	blueval = inw(S3C44B0X_BLUELUT);
+	redval = inw(S3C44B0X_REDLUT);
+	greenval = inw(S3C44B0X_GREENLUT);
+	switch(info->gen.info.var.bits_per_pixel)
+	{
+	case 1:
+		if(regno > 1)
+			return 1; /* error */
+		if(regno == 0)
+			*red = *green = *blue = 0;
+		else
+			*red = *green = *blue = 0xFFFF;
+		break;
+	case 2:
+		if(regno > 4)
+			return 1; /* error */
+	
+		blueval = (blueval >> (regno<<2)) & 0xF;
+		*red = *green = *blue = 0x1111 * blueval; /* 0xFFFF / 0xF = 0x1111 */
+		break;
+	case 4:
+		if(regno > 16)
+			return 1; /* error */
+		*red = *green = *blue = 0x1111 * regno; /* 0xFFFF / 0xF = 0x1111 */
+		break;
+	case 8:
+		if(regno > 256)
+			return 1;
+		helpvalue = regno >> 5;
+		redval = (redval >> (helpvalue<<2)) & 0xF;
+		*red = redval * 0x1111;
+		helpvalue = (regno >> 2) & 0x7;
+		greenval = (greenval >> (helpvalue<<2)) & 0xF;
+		*green = greenval * 0x1111;
+		helpvalue = regno & 0x03;
+		blueval = (blueval >> (helpvalue<<2)) & 0xF;
+		*blue = blueval * 0x1111;
+		break;
+	default:
+		return 1; 
+	}
+	return 0;
+}
+
+static int s3c44b0xfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			      unsigned blue, unsigned transp,
+			      struct fb_info *_info)
+{
+    /*
+     *  Set a single color register. The values supplied have a 16 bit
+     *  magnitude.
+     *  Return != 0 for invalid regno.
+     */
+	struct s3c44b0xfb_info *info = (struct s3c44b0xfb_info *) _info;
+	unsigned int helpvalue;
+	u32 blueval, redval, greenval;
+	blueval = inw(S3C44B0X_BLUELUT);
+	redval = inw(S3C44B0X_REDLUT);
+	greenval = inw(S3C44B0X_GREENLUT);
+	switch(info->gen.info.var.bits_per_pixel)
+	{
+	case 1:
+		return -EINVAL;
+		break;
+	case 2:
+		if((regno > 4) || (red != green) || (red != blue)) /* FIXME: maybe wrong */
+			return 1;
+		helpvalue = (unsigned int)(blue / 0x1111) & 0xF;
+		blueval &= ~(0xF << (regno<<2));
+		blueval |= (helpvalue << (regno<<2));
+		outl(blueval, S3C44B0X_BLUELUT);
+		break;
+	case 4:
+		return -EINVAL;
+		break;
+	case 8:
+		if(regno > 256)
+			return 1;
+		helpvalue = (unsigned int)(blue / 0x1111) & 0xF;
+		blueval &= ~(0xF << ((regno&0x03)<<2));
+		blueval |= (helpvalue << ((regno&0x03)<<2));
+		outl(blueval, S3C44B0X_BLUELUT);
+		helpvalue = (unsigned int)(red / 0x1111) & 0xF;
+		redval &= ~(0xF << (((regno>>5)&0x7)<<2));
+		redval |= (helpvalue << (((regno>>5)&0x7)<<2));
+		outl(redval, S3C44B0X_BLUELUT);
+		helpvalue = (unsigned int)(green / 0x1111) & 0xF;
+		greenval &= ~(0xF << (((regno>>2)&0x7)<<2));
+		greenval |= (helpvalue << (((regno>>2)&0x7)<<2));
+		outl(greenval, S3C44B0X_BLUELUT);
+		break;
+	default:
+		return 1;
+	}
+		
+		
+    return 0;
+}
+
+static int s3c44b0xfb_pan_display(const struct fb_var_screeninfo *var,
+				struct fb_info_gen *info)
+{
+    /*
+     *  Pan (or wrap, depending on the `vmode' field) the display using the
+     *  `xoffset' and `yoffset' fields of the `var' structure.
+     *  If the values don't fit, return -EINVAL.
+     */
+	return -EINVAL;
+
+}
+
+static int s3c44b0xfb_blank(int blank_mode, struct fb_info_gen *info)
+{
+    /*
+     *  Blank the screen if blank_mode != 0, else unblank. If blank == NULL
+     *  then the caller blanks by setting the CLUT (Color Look Up Table) to all
+     *  black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due
+     *  to e.g. a video mode which doesn't support it. Implements VESA suspend
+     *  and powerdown modes on hardware that supports disabling hsync/vsync:
+     *    blank_mode == 2: suspend vsync
+     *    blank_mode == 3: suspend hsync
+     *    blank_mode == 4: powerdown
+     */
+	u32 helpvalue;
+	switch(blank_mode)
+	{
+	case 2:
+		return -EINVAL;
+	case 3:
+		return -EINVAL;
+	case 4:
+		helpvalue = inw(S3C44B0X_LCDCON1);
+		outl(helpvalue&~S3C44B0X_LCDCON1_ENVID, S3C44B0X_LCDCON1); /* disable video output */
+		break;
+	default:
+		return -EINVAL;
+	}
+
+    /* ... */
+    return 0;
+}
+
+static void s3c44b0xfb_gen_blank(int blank_mode, struct fb_info *info)
+{
+	s3c44b0xfb_blank(blank_mode, &fb_info.gen);
+	return;
+}
+
+#if 0
+static void s3c44b0xfb_set_disp(const void *par, struct display *disp,
+			      struct fb_info_gen *info)
+{
+    /*
+     *  Fill in a pointer with the virtual address of the mapped frame buffer.
+     *  Fill in a pointer to appropriate low level text console operations (and
+     *  optionally a pointer to help data) for the video mode `par' of your
+     *  video hardware. These can be generic software routines, or hardware
+     *  accelerated routines specifically tailored for your hardware.
+     *  If you don't have any appropriate operations, you must fill in a
+     *  pointer to dummy operations, and there will be no text output.
+     */
+	return;
+}
+#endif
+
+static void s3c44b0xfb_init_lcd_controller( struct known_lcd_panels *p_lcd)
+{
+	u32 helpvalue = 0, pagewidth=0, offsize = 0;
+	u16 hozval = 0;
+	u8 modesel = 0;
+	/*---------------------------------*/
+	/* set LCDSADDR1 to zero to disable the LCD controller */
+	/*---------------------------------*/
+	outl(helpvalue, S3C44B0X_LCDCON1);
+
+	/*---------------------------------*/
+	/* set LCDSADDR1                   */
+	/*---------------------------------*/
+	helpvalue = 0;
+	switch(p_lcd->bpp)
+	{
+	case 1:
+		modesel = 0;
+		break;
+	case 2:
+		modesel = 1;
+		break;
+	case 4:
+		modesel = 2;
+		break;
+	case 8:
+		modesel = 3;
+		break;
+	default:
+		modesel = 0;
+	}
+	helpvalue |=  (modesel & 0x03)<<27; /* MODESEL value */
+	helpvalue |= ((fb_info.fb_phys & 0x0FC00000) >> 1); /* LCDBANK addr. */
+	helpvalue |= ((fb_info.gen.info.var.xoffset + 
+		       (fb_info.gen.info.var.yoffset*fb_info.gen.info.var.xres_virtual)) & 0xFFFFF) >> 1;
+	outl(helpvalue, S3C44B0X_LCDSADDR1);
+	/*---------------------------------*/
+	/* set LCDSADDR2                   */
+	/*---------------------------------*/
+	helpvalue = 0;
+	helpvalue |= (p_lcd->bswp &0x1) << 29; /* BSWP */
+	helpvalue |= (p_lcd->mval) << 21; /* MVAL */
+	pagewidth = (p_lcd->width * p_lcd->bpp) >> 4;
+	offsize = ((fb_info.gen.info.var.xres_virtual * p_lcd->bpp) >> 4) - pagewidth;
+	helpvalue |= (((((fb_info.gen.info.var.xoffset + 
+		       (fb_info.gen.info.var.yoffset*fb_info.gen.info.var.xres_virtual)) & 0xFFFFF) >> 1) +
+		       (pagewidth + offsize) * (p_lcd->lineval +1)) & 0xFFFFF); /* LCDBASEL */
+	outl(helpvalue, S3C44B0X_LCDSADDR2);
+	/*---------------------------------*/
+	/* set LCDSADDR3                   */
+	/*---------------------------------*/
+	helpvalue = 0;
+	helpvalue |= (pagewidth & 0x1FF);
+	helpvalue |= (offsize & 0x7FF) << 9;
+	outl(helpvalue, S3C44B0X_LCDSADDR3);
+
+	/*---------------------------------*/
+	/* set LCDCON2                     */
+	/*---------------------------------*/
+	helpvalue = 0;
+	helpvalue |= (p_lcd->lineblank & 0x3FF) << 21;
+	helpvalue |= (p_lcd->hozval & 0x3FF) << 10;
+	helpvalue |= (p_lcd->lineval & 0x3FF);
+	outl(helpvalue, S3C44B0X_LCDCON2);
+	/*---------------------------------*/
+	/* set LCDCON3                     */
+	/*---------------------------------*/
+	outb((p_lcd->selfref & 0x1), S3C44B0X_LCDCON3);
+       
+	/*---------------------------------*/
+	/* set REDLUT                      */
+	/*---------------------------------*/
+	outl(0xECA86420, S3C44B0X_REDLUT);
+       /*---------------------------------*/
+	/* set GREENLUT                    */
+	/*---------------------------------*/
+	outl(0xECA86420, S3C44B0X_GREENLUT);
+	/*---------------------------------*/
+	/* set BLUELUT                     */
+	/*---------------------------------*/
+	outl(0x0000F840, S3C44B0X_BLUELUT);
+
+	/*---------------------------------*/
+	/* set LCDCON1 (also enables the LCD controller) */
+	/*---------------------------------*/
+	helpvalue = ((p_lcd->clkval&0x3FF) << 12);
+	helpvalue |= ((((p_lcd->wlh >> 2)-1) & 0x03) << 10); /* map the  wlh value and shift 10 left */
+	helpvalue |= ((((p_lcd->wdly >> 2)-1) & 0x03) << 8); /* map the wdly value and shift 8 left */
+	helpvalue |= ((p_lcd->mmode & 0x01) << 7);
+	helpvalue |= (p_lcd->dismode << 5); /* DISMODE */
+	helpvalue |= ((p_lcd->invclk&0x01) << 4);
+	helpvalue |= ((p_lcd->invline&0x01) << 3);
+	helpvalue |= ((p_lcd->invframe&0x01) << 2);
+	helpvalue |= ((p_lcd->invvd&0x01) << 1);
+	helpvalue |= 1; /* enables the display */
+	outl(helpvalue, S3C44B0X_LCDCON1);
+
+	/* switch display on by setting special port */
+	if(p_lcd->disp_on_ctrl_reg) {
+		helpvalue = inl(p_lcd->disp_on_ctrl_reg);
+		helpvalue &= ~p_lcd->disp_on_ctrl_reg_mask;
+		helpvalue |= p_lcd->disp_on_ctrl_reg_value;
+		outl(helpvalue, p_lcd->disp_on_ctrl_reg); /* set disp_on port to enable */
+	}
+	if(p_lcd->disp_on_port) {
+		helpvalue = inl(p_lcd->disp_on_port);
+		helpvalue &= ~p_lcd->disp_on_mask;
+		helpvalue |= p_lcd->disp_on_val;
+		outl(helpvalue, p_lcd->disp_on_port); /* enable display */
+	}
+}
+
+
+/* ------------ Interfaces to hardware functions ------------ */
+
+
+struct fbgen_hwswitch s3c44b0xfb_switch = {
+	s3c44b0xfb_detect, 
+	s3c44b0xfb_encode_fix, 
+	s3c44b0xfb_decode_var, 
+	s3c44b0xfb_encode_var, 
+	s3c44b0xfb_get_par,
+	s3c44b0xfb_set_par, 
+	s3c44b0xfb_getcolreg, 
+	s3c44b0xfb_setcolreg,
+	s3c44b0xfb_pan_display,
+	s3c44b0xfb_blank,
+	NULL
+};
+
+
+
+/* ------------ Hardware Independent Functions ------------ */
+
+
+    /*
+     *  Initialization
+     */
+
+int __init s3c44b0xfb_init(void)
+{
+	struct known_lcd_panels *p_lcd;
+	int num_panels; /* number of known LCD panels */
+	int i;
+
+	printk("S3C44B0X framebuffer init\n");
+
+	if( (bootloader == 0) && (panel_name == NULL) )
+	{
+		printk("S3C44B0X framebuffer driver error: No panel name specified and bootloader settings shall not be used\n");
+		return -EINVAL;
+	}
+
+	if(bootloader)
+	{
+		printk("S3C44B0X framebuffer driver error: Using of bootloader settings not yet implemented\n");
+		return 0; /* FIXME read out the parms from the controller and store them into the structs */
+	}
+
+	num_panels = sizeof(panels)/sizeof(struct known_lcd_panels);
+	/* Get the panel name, everything else is fixed */
+	for (i=0; i<num_panels; i++) 
+	{
+		if (!strcmp(panel_name, panels[i].lcd_panel_name)) 
+		{
+			s3c44b0x_lcd_index = i;
+			panel_valid = 1;
+			break;
+		}
+	}
+
+	if(!panel_valid)
+	{
+		printk("S3C44B0X framebuffer driver error: Invalid panel name selected\n");
+		return -EINVAL;
+	}
+
+	p_lcd = &panels[s3c44b0x_lcd_index];
+
+	memset(&fb_info.gen, 0, sizeof(fb_info.gen));
+	fb_info.gen.fbhw = &s3c44b0xfb_switch;
+	sprintf(fb_info.gen.info.modename, "%dx%dx%d",p_lcd->width,p_lcd->height,p_lcd->bpp);
+	fb_info.gen.parsize = sizeof(struct s3c44b0xfb_par);
+	fb_info.gen.info.changevar = NULL;
+	fb_info.gen.info.node = -1;
+	fb_info.gen.info.fbops = &s3c44b0xfb_ops;
+	fb_info.gen.info.disp = NULL; /* not needed ?? */
+	fb_info.gen.info.switch_con = NULL;
+	fb_info.gen.info.updatevar = NULL;
+	fb_info.gen.info.blank = &s3c44b0xfb_gen_blank;
+	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
+	/* This should give a reasonable default video mode */
+	/* fbgen_get_var(&disp.var, -1, &fb_info.gen.info); */
+	/* fbgen_do_set_var(&disp.var, 1, &fb_info.gen); */
+	/* fbgen_set_disp(-1, &fb_info.gen); */
+	/* fbgen_install_cmap(0, &fb_info.gen); */
+
+	/**********************************************
+	 * file the var struct inside the current_par struct
+	 **********************************************/
+	memset(&current_par.var, 0, sizeof(current_par.var));
+	current_par.var.xres = p_lcd->width;
+	current_par.var.yres = p_lcd->height;
+	current_par.var.xres_virtual = p_lcd->width;
+	current_par.var.yres_virtual = p_lcd->height;
+	current_par.var.bits_per_pixel = p_lcd->bpp;
+	current_par.var.grayscale = (p_lcd->bpp == 8)? 0 : 1;
+	if(p_lcd->bpp == 1)
+	{
+		current_par.var.blue.length = 1;
+	}
+	else if(p_lcd->bpp == 2)
+	{
+		current_par.var.blue.length = 2;
+	}
+	else if(p_lcd->bpp == 4)
+	{
+		current_par.var.blue.length = 4;
+	}
+	else if(p_lcd->bpp == 8)
+	{
+		current_par.var.red.offset = 5;
+		current_par.var.red.length = 3;
+		current_par.var.green.offset = 2;
+		current_par.var.green.length = 3;
+		current_par.var.blue.length = 2;
+	}
+
+	current_par_valid = 1;
+
+	/*
+	 * Allocate LCD framebuffer from system memory
+	 */
+	fb_info.fb_size = (p_lcd->width * p_lcd->height * p_lcd->bpp) >> 3;
+	/* FIXME align it to 4 MB */
+	fb_info.fb_phys = S3C44B0X_FB_ADDRESS;
+	fb_info.fb_virt_start = fb_info.fb_phys;
+	current_par.line_length = (p_lcd->width * p_lcd->bpp) >> 3;
+
+	/* fill the var element of fb_info.gen.info */
+	memcpy(&fb_info.gen.info.var, &current_par.var, sizeof(struct fb_var_screeninfo));
+
+	/* fill the fix element of fb_info.gen.info */
+	s3c44b0xfb_encode_fix(&fb_info.gen.info.fix, &current_par, &fb_info.gen);
+
+	if (register_framebuffer(&fb_info.gen.info) < 0)
+		return -EINVAL;
+	printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.gen.info.node),
+	       fb_info.gen.info.modename);
+
+	/*********************************************
+         *  set framebuffer memory to zero
+	 *********************************************/
+	memset((void*)fb_info.fb_phys, 0, fb_info.fb_size);
+
+
+	/*********************************************
+	 * init the lcd controller
+	 *********************************************/
+	
+	s3c44b0xfb_init_lcd_controller(p_lcd);
+	
+	
+
+
+
+    /* uncomment this if your driver cannot be unloaded */
+    /* MOD_INC_USE_COUNT; */
+	printk("S3C44B0X framebuffer driver: Init ready\n");
+	return 0;
+}
+
+
+
+
+    /*
+     *  Cleanup
+     */
+
+void s3c44b0xfb_cleanup(struct fb_info *info)
+{
+	/*
+	 *  If your driver supports multiple boards, you should unregister and
+	 *  clean up all instances.
+	 */
+	unregister_framebuffer(info);
+}
+
+
+    /*
+     *  Setup
+     */
+
+int __init s3c44b0xfb_setup(char *options)
+{
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+
+    /*
+     *  Frame buffer operations
+     */
+
+/* If all you need is that - just don't define ->fb_open */
+static int s3c44b0xfb_open(struct fb_info *info, int user)
+{
+    return 0;
+}
+
+/* If all you need is that - just don't define ->fb_release */
+static int s3c44b0xfb_release(struct fb_info *info, int user)
+{
+    return 0;
+}
+
+
+    /*
+     *  In most cases the `generic' routines (fbgen_*) should be satisfactory.
+     *  However, you're free to fill in your own replacements.
+     */
+
+static struct fb_ops s3c44b0xfb_ops = {
+	owner:		THIS_MODULE,
+	fb_open:	s3c44b0xfb_open,    /* only if you need it to do something */
+	fb_release:	s3c44b0xfb_release, /* only if you need it to do something */
+	fb_get_fix:	fbgen_get_fix,
+	fb_get_var:	fbgen_get_var,
+	fb_set_var:	fbgen_set_var,
+	fb_get_cmap:	fbgen_get_cmap,
+	fb_set_cmap:	fbgen_set_cmap,
+	fb_pan_display:	fbgen_pan_display,
+	fb_ioctl:	NULL,   /* optional */
+};
+
+
+/* ------------------------------------------------------------------------- */
+
+
+    /*
+     *  Modularization
+     */
+
+#ifdef MODULE
+MODULE_LICENSE("GPL");
+int init_module(void)
+{
+    return s3c44b0xfb_init();
+}
+
+void cleanup_module(void)
+{
+    s3c44b0xfb_cleanup(&fb_info.gen.info);
+}
+#endif /* MODULE */
diff -urN linux-2.4.29/drivers/video/s3c44b0xfb.h linux-2.4.29-uc1/drivers/video/s3c44b0xfb.h
--- linux-2.4.29/drivers/video/s3c44b0xfb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/s3c44b0xfb.h	2005-06-14 02:12:27.000000000 +0100
@@ -0,0 +1,71 @@
+/*
+ * linux/drivers/video/s3c44b0xfb.c
+ *	-- Support for the S3C44B0X LCD/CRT controller as framebuffer device
+ *
+ * Copyright (C) 2003 Stefan Macher <macher@sympat.de>
+ *                    Alexander Assel <assel@sympat.de>
+ *
+*/
+#ifndef __INCLUDE_S3C44B0XFB__
+#define __INCLUDE_S3C44B0XFB__
+
+#define S3C44B0X_FB_ADDRESS 0x0C400000 /* FIXME should be done with malloc */
+
+
+/********************************************************************/
+/*! \brief Holds all needed LCD panel configuration values
+ *
+ *  The driver holds a set of these configuration tables that can be
+ *  referenced by giving the LCD panel name as defined in lcd_panel_name
+ *  to the driver. For further informations see also the S3C44B0X datasheet.
+ *
+ *  The six disp_on_... attributes give the possiblity to define a port
+ *  that has to be set to enable the display.
+ */
+struct known_lcd_panels
+{
+  unsigned char lcd_panel_name[64];   /*!< Holds the lcd panel name */
+  u16 clkval; /*!< Determine the rate of CLKVAL. This could also be solved with VCLK and MCLK */
+  u8 wlh; /*!< Determine the VLINE pulses high level width [clocks] valid values 4, 8, 12 and 16 */
+  u8 wdly; /*!< Determine the delay between VLINE and VCLOCK [clocks] valid values 4, 8, 12 and 16 */
+  u8 mmode; /*!< Determine toggle rate of VM 0 -> each frame 1 -> defined by MVAL */
+  u8 dismode; /*!< Controls the display mode 0->4-bit dual-scan display, 1->4-bit single scan display, 2->8-bit single-scan display */
+  u8 invclk; /*!< Controls the polarity of VCLOCK active edge 0 -> falling edge 1 -> rising edge  */
+  u8 invline; /*!< Indicates the line pulse polarity 0 -> normal 1 -> inverted */
+  u8 invframe; /*!< Indicates the frame pulse polarity 0 -> normal 1 -> inverted */
+  u8 invvd; /*!< Indicates the video data polarity 0 -> normal 1 -> inverted */
+  u16 lineblank; /*!< Indicates the blank time in one horizontal line duration */
+  u8 selfref; /*!< LCD self refrash mode enable */
+  u8 bswp; /*!< Byte swap control */
+  u8 mval; /*!< Defines the rate at which the vm signal will toggle */
+  u16 width; /*!< display width in pixels */
+  u16 height; /*!< Display height in pixels */
+  u8 bpp; /*!< Bits per pixel; valid values are 1 (mono), 2 (gray), 4 (gray) and 8 (color) */
+  u16 hozval; /*!< hozval */
+  u16 lineval; /*!< linevalue */
+  u32 *disp_on_port; /*!< disp on port register; set to zero if you do not need it */
+  u32 disp_on_mask; /*!< disp on mask; defines the mask of the port bits */
+  u32 disp_on_val; /*!< disp on value; defines the value to write to disp_on_port to enable the display */
+  u32 *disp_on_ctrl_reg; /*!< disp_on control register; set to zero if you do not need it; the register to control the port (input / output / ...) */
+  u32 disp_on_ctrl_reg_mask; /*!< disp_on control register mask to mask port/pin control */
+  u32 disp_on_ctrl_reg_value /*!< disp on ctrl reg value */
+};	
+
+struct s3c44b0xfb_info {
+       
+	struct fb_info_gen gen;
+	unsigned long fb_virt_start;
+	unsigned long fb_size;
+	unsigned long fb_phys;
+	
+};
+
+
+struct s3c44b0xfb_par {
+  
+	struct fb_var_screeninfo var;
+	int line_length;  /* in bytes */
+};
+
+
+#endif
diff -urN linux-2.4.29/drivers/video/vfb_small.c linux-2.4.29-uc1/drivers/video/vfb_small.c
--- linux-2.4.29/drivers/video/vfb_small.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/vfb_small.c	2005-06-14 02:12:27.000000000 +0100
@@ -0,0 +1,618 @@
+/*
+ *  linux/drivers/video/vfb_small.c -- Virtual frame buffer device
+ *  The only difference to vfb.c is that it only uses 1 kByte 
+ *  RAM for the screen
+ *
+ *	Copyright (C) 1997 Geert Uytterhoeven
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <asm/uaccess.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-mfb.h>
+#include <video/fbcon-cfb2.h>
+#include <video/fbcon-cfb4.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb24.h>
+#include <video/fbcon-cfb32.h>
+
+
+    /*
+     *  RAM we reserve for the frame buffer. This defines the maximum screen
+     *  size
+     *
+     *  The default can be overridden if the driver is compiled as a module
+     */
+
+#define VIDEOMEMSIZE	(1*1024)	/* 1 KB */
+
+static u_long videomemory, videomemorysize = VIDEOMEMSIZE;
+MODULE_PARM(videomemorysize, "l");
+static int currcon = 0;
+static struct display disp;
+static struct fb_info fb_info;
+static struct { u_char red, green, blue, pad; } palette[256];
+static union {
+#ifdef FBCON_HAS_CFB16
+    u16 cfb16[16];
+#endif
+#ifdef FBCON_HAS_CFB24
+    u32 cfb24[16];
+#endif
+#ifdef FBCON_HAS_CFB32
+    u32 cfb32[16];
+#endif
+} fbcon_cmap;
+static char vfb_small_name[16] = "Virtual FB";
+
+static struct fb_var_screeninfo vfb_small_default = {
+    /* 640x480, 8 bpp */
+    640, 480, 640, 480, 0, 0, 8, 0,
+    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+    0, 0, -1, -1, 0, 20000, 64, 64, 32, 32, 64, 2,
+    0, FB_VMODE_NONINTERLACED
+};
+
+static int vfb_small_enable = 0;	/* disabled by default */
+
+
+    /*
+     *  Interface used by the world
+     */
+
+int vfb_small_setup(char*);
+
+static int vfb_small_get_fix(struct fb_fix_screeninfo *fix, int con,
+		       struct fb_info *info);
+static int vfb_small_get_var(struct fb_var_screeninfo *var, int con,
+		       struct fb_info *info);
+static int vfb_small_set_var(struct fb_var_screeninfo *var, int con,
+		       struct fb_info *info);
+static int vfb_small_pan_display(struct fb_var_screeninfo *var, int con,
+			   struct fb_info *info);
+static int vfb_small_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info);
+static int vfb_small_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info);
+
+
+    /*
+     *  Interface to the low level console driver
+     */
+
+int vfb_small_init(void);
+static int vfb_smallcon_switch(int con, struct fb_info *info);
+static int vfb_smallcon_updatevar(int con, struct fb_info *info);
+static void vfb_smallcon_blank(int blank, struct fb_info *info);
+
+
+    /*
+     *  Internal routines
+     */
+
+static u_long get_line_length(int xres_virtual, int bpp);
+static void vfb_small_encode_fix(struct fb_fix_screeninfo *fix,
+			   struct fb_var_screeninfo *var);
+static void set_color_bitfields(struct fb_var_screeninfo *var);
+static int vfb_small_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                         u_int *transp, struct fb_info *info);
+static int vfb_small_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp, struct fb_info *info);
+static void do_install_cmap(int con, struct fb_info *info);
+
+
+static struct fb_ops vfb_small_ops = {
+	owner:		THIS_MODULE,
+	fb_get_fix:	vfb_small_get_fix,
+	fb_get_var:	vfb_small_get_var,
+	fb_set_var:	vfb_small_set_var,
+	fb_get_cmap:	vfb_small_get_cmap,
+	fb_set_cmap:	vfb_small_set_cmap,
+	fb_pan_display:	vfb_small_pan_display,
+};
+
+    /*
+     *  Get the Fixed Part of the Display
+     */
+
+static int vfb_small_get_fix(struct fb_fix_screeninfo *fix, int con,
+		       struct fb_info *info)
+{
+    struct fb_var_screeninfo *var;
+
+    if (con == -1)
+	var = &vfb_small_default;
+    else
+	var = &fb_display[con].var;
+    vfb_small_encode_fix(fix, var);
+    return 0;
+}
+
+
+    /*
+     *  Get the User Defined Part of the Display
+     */
+
+static int vfb_small_get_var(struct fb_var_screeninfo *var, int con,
+		       struct fb_info *info)
+{
+    if (con == -1)
+	*var = vfb_small_default;
+    else
+	*var = fb_display[con].var;
+    set_color_bitfields(var);
+    return 0;
+}
+
+
+    /*
+     *  Set the User Defined Part of the Display
+     */
+
+static int vfb_small_set_var(struct fb_var_screeninfo *var, int con,
+		       struct fb_info *info)
+{
+    int err, activate = var->activate;
+    int oldxres, oldyres, oldvxres, oldvyres, oldbpp;
+    u_long line_length;
+
+    struct display *display;
+    if (con >= 0)
+	display = &fb_display[con];
+    else
+	display = &disp;	/* used during initialization */
+
+    /*
+     *  FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
+     *  as FB_VMODE_SMOOTH_XPAN is only used internally
+     */
+
+    if (var->vmode & FB_VMODE_CONUPDATE) {
+	var->vmode |= FB_VMODE_YWRAP;
+	var->xoffset = display->var.xoffset;
+	var->yoffset = display->var.yoffset;
+    }
+
+    /*
+     *  Some very basic checks
+     */
+    if (!var->xres)
+	var->xres = 1;
+    if (!var->yres)
+	var->yres = 1;
+    if (var->xres > var->xres_virtual)
+	var->xres_virtual = var->xres;
+    if (var->yres > var->yres_virtual)
+	var->yres_virtual = var->yres;
+    if (var->bits_per_pixel <= 1)
+	var->bits_per_pixel = 1;
+    else if (var->bits_per_pixel <= 8)
+	var->bits_per_pixel = 8;
+    else if (var->bits_per_pixel <= 16)
+	var->bits_per_pixel = 16;
+#if 0
+    /* fbcon doesn't support this (yet) */
+    else if (var->bits_per_pixel <= 24)
+	var->bits_per_pixel = 24;
+    else if (var->bits_per_pixel <= 32)
+	var->bits_per_pixel = 32;
+#endif
+    else
+	return -EINVAL;
+
+    /*
+     *  Memory limit
+     */
+    line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
+    if (line_length*var->yres_virtual > videomemorysize)
+	return -ENOMEM;
+
+    set_color_bitfields(var);
+
+    if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+	oldxres = display->var.xres;
+	oldyres = display->var.yres;
+	oldvxres = display->var.xres_virtual;
+	oldvyres = display->var.yres_virtual;
+	oldbpp = display->var.bits_per_pixel;
+	display->var = *var;
+	if (oldxres != var->xres || oldyres != var->yres ||
+	    oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
+	    oldbpp != var->bits_per_pixel) {
+	    struct fb_fix_screeninfo fix;
+
+	    vfb_small_encode_fix(&fix, var);
+	    display->screen_base = (char *)videomemory;
+	    display->visual = fix.visual;
+	    display->type = fix.type;
+	    display->type_aux = fix.type_aux;
+	    display->ypanstep = fix.ypanstep;
+	    display->ywrapstep = fix.ywrapstep;
+	    display->line_length = fix.line_length;
+	    display->can_soft_blank = 1;
+	    display->inverse = 0;
+	    switch (var->bits_per_pixel) {
+#ifdef FBCON_HAS_MFB
+		case 1:
+		    display->dispsw = &fbcon_mfb;
+		    break;
+#endif
+#ifdef FBCON_HAS_CFB2
+		case 2:
+		    display->dispsw = &fbcon_cfb2;
+		    break;
+#endif
+#ifdef FBCON_HAS_CFB4
+		case 4:
+		    display->dispsw = &fbcon_cfb4;
+		    break;
+#endif
+#ifdef FBCON_HAS_CFB8
+		case 8:
+		    display->dispsw = &fbcon_cfb8;
+		    break;
+#endif
+#ifdef FBCON_HAS_CFB16
+		case 16:
+		    display->dispsw = &fbcon_cfb16;
+		    display->dispsw_data = fbcon_cmap.cfb16;
+		    break;
+#endif
+#ifdef FBCON_HAS_CFB24
+		case 24:
+		    display->dispsw = &fbcon_cfb24;
+		    display->dispsw_data = fbcon_cmap.cfb24;
+		    break;
+#endif
+#ifdef FBCON_HAS_CFB32
+		case 32:
+		    display->dispsw = &fbcon_cfb32;
+		    display->dispsw_data = fbcon_cmap.cfb32;
+		    break;
+#endif
+		default:
+		    display->dispsw = &fbcon_dummy;
+		    break;
+	    }
+	    if (fb_info.changevar)
+		(*fb_info.changevar)(con);
+	}
+	if (oldbpp != var->bits_per_pixel) {
+	    if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+		return err;
+	    do_install_cmap(con, info);
+	}
+    }
+    return 0;
+}
+
+
+    /*
+     *  Pan or Wrap the Display
+     *
+     *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+     */
+
+static int vfb_small_pan_display(struct fb_var_screeninfo *var, int con,
+			   struct fb_info *info)
+{
+    if (var->vmode & FB_VMODE_YWRAP) {
+	if (var->yoffset < 0 ||
+	    var->yoffset >= fb_display[con].var.yres_virtual ||
+	    var->xoffset)
+	    return -EINVAL;
+    } else {
+	if (var->xoffset+fb_display[con].var.xres >
+	    fb_display[con].var.xres_virtual ||
+	    var->yoffset+fb_display[con].var.yres >
+	    fb_display[con].var.yres_virtual)
+	    return -EINVAL;
+    }
+    fb_display[con].var.xoffset = var->xoffset;
+    fb_display[con].var.yoffset = var->yoffset;
+    if (var->vmode & FB_VMODE_YWRAP)
+	fb_display[con].var.vmode |= FB_VMODE_YWRAP;
+    else
+	fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
+    return 0;
+}
+
+    /*
+     *  Get the Colormap
+     */
+
+static int vfb_small_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info)
+{
+    if (con == currcon) /* current console? */
+	return fb_get_cmap(cmap, kspc, vfb_small_getcolreg, info);
+    else if (fb_display[con].cmap.len) /* non default colormap? */
+	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+    else
+	fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+		     cmap, kspc ? 0 : 2);
+    return 0;
+}
+
+    /*
+     *  Set the Colormap
+     */
+
+static int vfb_small_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info)
+{
+    int err;
+
+    if (!fb_display[con].cmap.len) {	/* no colormap allocated? */
+	if ((err = fb_alloc_cmap(&fb_display[con].cmap,
+			      1<<fb_display[con].var.bits_per_pixel, 0)))
+	    return err;
+    }
+    if (con == currcon)			/* current console? */
+	return fb_set_cmap(cmap, kspc, vfb_small_setcolreg, info);
+    else
+	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+    return 0;
+}
+
+
+int __init vfb_small_setup(char *options)
+{
+    char *this_opt;
+
+    fb_info.fontname[0] = '\0';
+
+    vfb_small_enable = 1;
+
+    if (!options || !*options)
+	return 0;
+
+    while ((this_opt = strsep(&options, ",")) != NULL) {
+	if (!strncmp(this_opt, "font:", 5))
+	    strcpy(fb_info.fontname, this_opt+5);
+    }
+    return 0;
+}
+
+
+    /*
+     *  Initialisation
+     */
+
+int __init vfb_small_init(void)
+{
+    if (!vfb_small_enable)
+	return -ENXIO;
+
+    if (!(videomemory = (u_long)vmalloc(videomemorysize)))
+	return -ENOMEM;
+
+    strcpy(fb_info.modename, vfb_small_name);
+    fb_info.changevar = NULL;
+    fb_info.node = -1;
+    fb_info.fbops = &vfb_small_ops;
+    fb_info.disp = &disp;
+    fb_info.switch_con = &vfb_smallcon_switch;
+    fb_info.updatevar = &vfb_smallcon_updatevar;
+    fb_info.blank = &vfb_smallcon_blank;
+    fb_info.flags = FBINFO_FLAG_DEFAULT;
+
+    vfb_small_set_var(&vfb_small_default, -1, &fb_info);
+
+    if (register_framebuffer(&fb_info) < 0) {
+	vfree((void *)videomemory);
+	return -EINVAL;
+    }
+
+    printk(KERN_INFO "fb%d: Virtual frame buffer device, using %ldK of video memory\n",
+	   GET_FB_IDX(fb_info.node), videomemorysize>>10);
+    return 0;
+}
+
+
+static int vfb_smallcon_switch(int con, struct fb_info *info)
+{
+    /* Do we have to save the colormap? */
+    if (fb_display[currcon].cmap.len)
+	fb_get_cmap(&fb_display[currcon].cmap, 1, vfb_small_getcolreg, info);
+
+    currcon = con;
+    /* Install new colormap */
+    do_install_cmap(con, info);
+    return 0;
+}
+
+    /*
+     *  Update the `var' structure (called by fbcon.c)
+     */
+
+static int vfb_smallcon_updatevar(int con, struct fb_info *info)
+{
+    /* Nothing */
+    return 0;
+}
+
+    /*
+     *  Blank the display.
+     */
+
+static void vfb_smallcon_blank(int blank, struct fb_info *info)
+{
+    /* Nothing */
+}
+
+static u_long get_line_length(int xres_virtual, int bpp)
+{
+    u_long length;
+    
+    length = xres_virtual*bpp;
+    length = (length+31)&-32;
+    length >>= 3;
+    return(length);
+}
+
+static void vfb_small_encode_fix(struct fb_fix_screeninfo *fix,
+			   struct fb_var_screeninfo *var)
+{
+    memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+    strcpy(fix->id, vfb_small_name);
+    fix->smem_start = videomemory;
+    fix->smem_len = videomemorysize;
+    fix->type = FB_TYPE_PACKED_PIXELS;
+    fix->type_aux = 0;
+    switch (var->bits_per_pixel) {
+	case 1:
+	    fix->visual = FB_VISUAL_MONO01;
+	    break;
+	case 2:
+	case 4:
+	case 8:
+	    fix->visual = FB_VISUAL_PSEUDOCOLOR;
+	    break;
+	case 16:
+	case 24:
+	case 32:
+	    fix->visual = FB_VISUAL_TRUECOLOR;
+	    break;
+    }
+    fix->ywrapstep = 1;
+    fix->xpanstep = 1;
+    fix->ypanstep = 1;
+    fix->line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
+}
+
+static void set_color_bitfields(struct fb_var_screeninfo *var)
+{
+    switch (var->bits_per_pixel) {
+	case 1:
+	case 8:
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 0;
+	    var->green.length = 8;
+	    var->blue.offset = 0;
+	    var->blue.length = 8;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 16:	/* RGB 565 */
+	    var->red.offset = 0;
+	    var->red.length = 5;
+	    var->green.offset = 5;
+	    var->green.length = 6;
+	    var->blue.offset = 11;
+	    var->blue.length = 5;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 24:	/* RGB 888 */
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 8;
+	    var->green.length = 8;
+	    var->blue.offset = 16;
+	    var->blue.length = 8;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case 32:	/* RGBA 8888 */
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 8;
+	    var->green.length = 8;
+	    var->blue.offset = 16;
+	    var->blue.length = 8;
+	    var->transp.offset = 24;
+	    var->transp.length = 8;
+	    break;
+    }
+    var->red.msb_right = 0;
+    var->green.msb_right = 0;
+    var->blue.msb_right = 0;
+    var->transp.msb_right = 0;
+}
+
+
+    /*
+     *  Read a single color register and split it into
+     *  colors/transparent. Return != 0 for invalid regno.
+     */
+
+static int vfb_small_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                         u_int *transp, struct fb_info *info)
+{
+    if (regno > 255)
+	return 1;
+    *red = (palette[regno].red<<8) | palette[regno].red;
+    *green = (palette[regno].green<<8) | palette[regno].green;
+    *blue = (palette[regno].blue<<8) | palette[regno].blue;
+    *transp = 0;
+    return 0;
+}
+
+
+    /*
+     *  Set a single color register. The values supplied are already
+     *  rounded down to the hardware's capabilities (according to the
+     *  entries in the var structure). Return != 0 for invalid regno.
+     */
+
+static int vfb_small_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp, struct fb_info *info)
+{
+    if (regno > 255)
+	return 1;
+    red >>= 8;
+    green >>= 8;
+    blue >>= 8;
+    palette[regno].red = red;
+    palette[regno].green = green;
+    palette[regno].blue = blue;
+    return 0;
+}
+
+
+static void do_install_cmap(int con, struct fb_info *info)
+{
+    if (con != currcon)
+	return;
+    if (fb_display[con].cmap.len)
+	fb_set_cmap(&fb_display[con].cmap, 1, vfb_small_setcolreg, info);
+    else
+	fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), 1,
+		    vfb_small_setcolreg, info);
+}
+
+
+#ifdef MODULE
+MODULE_LICENSE("GPL");
+
+int init_module(void)
+{
+    return vfb_small_init();
+}
+
+void cleanup_module(void)
+{
+    unregister_framebuffer(&fb_info);
+    vfree((void *)videomemory);
+}
+
+#endif /* MODULE */
diff -urN linux-2.4.29/drivers/video/xilinxfb.c linux-2.4.29-uc1/drivers/video/xilinxfb.c
--- linux-2.4.29/drivers/video/xilinxfb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/drivers/video/xilinxfb.c	2005-06-14 02:12:26.000000000 +0100
@@ -0,0 +1,506 @@
+/*
+ * xilinxfb.c
+ *
+ * Xilinx TFT LCD frame buffer driver
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under the terms
+ * of the GNU General Public License version 2.  This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+/*
+ * This driver was based off of au1100fb.c by MontaVista, which in turn
+ * was based off of skeletonfb.c, Skeleton for a frame buffer device by
+ * Geert Uytterhoeven.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/wrapper.h> /* mem_map_(un)reserve */
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <video/fbcon.h>
+#include <video/fbcon-cfb32.h>
+
+MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
+MODULE_DESCRIPTION("Xilinx TFT LCD frame buffer driver");
+MODULE_LICENSE("GPL");
+
+/*
+ * The interface to the framebuffer is nice and simple.  There are two
+ * control registers.  The first tells the LCD interface where in memory
+ * the frame buffer is (only the 11 most significant bits are used, so
+ * don't start thinking about scrolling).  The second allows the LCD to
+ * be turned on or off as well as rotated 180 degrees.
+ */
+#define NUM_REGS	2
+#define REG_FB_ADDR	0
+#define REG_CTRL	1
+#define REG_CTRL_ENABLE	 0x0001
+#define REG_CTRL_ROTATE	 0x0002
+#if defined(CONFIG_FB_XILINX_ROTATE)
+#define REG_CTRL_DEFAULT (REG_CTRL_ENABLE | REG_CTRL_ROTATE)
+#else
+#define REG_CTRL_DEFAULT (REG_CTRL_ENABLE)
+#endif				/* CONFIG_FB_XILINX_ROTATE */
+
+/*
+ * The hardware only handles a single mode: 640x480 24 bit true
+ * color. Each pixel gets a word (32 bits) of memory.  Within each word,
+ * the 8 most significant bits are ignored, the next 8 bits are the red
+ * level, the next 8 bits are the green level and the 8 least
+ * significant bits are the blue level.  Each row of the LCD uses 1024
+ * words, but only the first 640 pixels are displayed with the other 384
+ * words being ignored.  There are 480 rows.
+ */
+#define BYTES_PER_PIXEL	4
+#define BITS_PER_PIXEL	(BYTES_PER_PIXEL * 8)
+#define XRES		640
+#define YRES		480
+#define XRES_VIRTUAL	1024
+#define YRES_VIRTUAL	YRES
+#define LINE_LENGTH	(XRES_VIRTUAL * BYTES_PER_PIXEL)
+#define FB_SIZE		(YRES_VIRTUAL * LINE_LENGTH)
+
+/*
+ * Here's the definition of the information needed per frame buffer.  We
+ * start off with the generic structure and then follow that with our private
+ * data.
+ */
+struct xilinxfb_info {
+	struct fb_info_gen gen;
+	struct xilinxfb_info *next;	/* The next node in info_list */
+	u32 *regs;		/* Virtual address of our control registers */
+	unsigned long fb_virt_start;	/* Virtual address of our frame buffer */
+	dma_addr_t fb_phys;	/* Physical address of our frame buffer */
+	u32 fbcon_cmap32[16];	/* Colormap */
+	struct display disp;
+};
+
+struct xilinxfb_par {
+	struct fb_var_screeninfo var;
+};
+
+/*
+ * So we can handle multiple frame buffers with this one driver, we need
+ * a list of xilinxfb_info's.
+ */
+static struct xilinxfb_info *info_list = NULL;
+static spinlock_t info_lock = SPIN_LOCK_UNLOCKED;
+
+/* Our parameters are unchangeable, so we only need one parameters struct. */
+static struct xilinxfb_par current_par;
+
+/*
+ * Free the head of our info_list and remove it from the list.  Note
+ * that this function does *not* unregister_framebuffer().  That is up
+ * to the caller to do if it is appropriate.
+ */
+static void
+remove_head_info(void)
+{
+	struct xilinxfb_info *i;
+
+	/* Pull the head off of info_list. */
+	spin_lock(&info_lock);
+	i = info_list;
+	info_list = i->next;
+	spin_unlock(&info_lock);
+
+	if (i->regs) {
+		/* Turn off the display; the frame buffer is going away. */
+		out_be32(i->regs + REG_CTRL, 0);
+		iounmap(i->regs);
+	}
+
+	if (i->fb_virt_start)
+		consistent_free((void *)i->fb_virt_start);
+
+	kfree(i);
+}
+
+static int
+xilinxfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+	       u_long arg, int con, struct fb_info *info)
+{
+	/* nothing to do yet */
+	return -EINVAL;
+}
+
+static struct fb_ops xilinxfb_ops = {
+	owner:THIS_MODULE,
+	fb_get_fix:fbgen_get_fix,
+	fb_get_var:fbgen_get_var,
+	fb_set_var:fbgen_set_var,
+	fb_get_cmap:fbgen_get_cmap,
+	fb_set_cmap:fbgen_set_cmap,
+	fb_pan_display:fbgen_pan_display,
+	fb_ioctl:xilinxfb_ioctl,
+};
+
+static void
+xilinx_detect(void)
+{
+	/*
+	 *  This function should detect the current video mode settings 
+	 *  and store it as the default video mode
+	 */
+
+	/*
+	 * Yeh, well, we're not going to change any settings so we're
+	 * always stuck with the default ...
+	 */
+
+}
+
+static int
+xilinx_encode_fix(struct fb_fix_screeninfo *fix, const void *par,
+		  struct fb_info_gen *info)
+{
+	struct xilinxfb_info *i = (struct xilinxfb_info *) info;
+
+	memset(fix, 0, sizeof (struct fb_fix_screeninfo));
+
+	strcpy(fix->id, "Xilinx");
+	fix->smem_start = i->fb_phys;
+	fix->smem_len = FB_SIZE;
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->visual = FB_VISUAL_TRUECOLOR;
+	fix->line_length = LINE_LENGTH;
+	return 0;
+}
+
+static int
+xilinx_decode_var(const struct fb_var_screeninfo *var, void *par,
+		  struct fb_info_gen *info)
+{
+	struct xilinxfb_par *p = (struct xilinxfb_par *) par;
+
+	if (var->xres != XRES
+	    || var->yres != YRES
+	    || var->xres_virtual != XRES_VIRTUAL
+	    || var->yres_virtual != YRES_VIRTUAL
+	    || var->bits_per_pixel != BITS_PER_PIXEL
+	    || var->xoffset != 0
+	    || var->yoffset != 0
+	    || var->grayscale != 0
+	    || var->nonstd != 0
+	    || var->pixclock != 0
+	    || var->left_margin != 0
+	    || var->right_margin != 0
+	    || var->hsync_len != 0
+	    || var->vsync_len != 0
+	    || var->sync != 0 || var->vmode != FB_VMODE_NONINTERLACED) {
+		return -EINVAL;
+	}
+
+	memset(p, 0, sizeof (struct xilinxfb_par));
+	p->var = *var;
+	p->var.red.offset = 16;
+	p->var.red.length = 8;
+	p->var.green.offset = 8;
+	p->var.green.length = 8;
+	p->var.blue.offset = 0;
+	p->var.blue.length = 8;
+	p->var.transp.offset = 0;
+	p->var.transp.length = 0;
+	p->var.red.msb_right = 0;
+	p->var.green.msb_right = 0;
+	p->var.blue.msb_right = 0;
+	p->var.transp.msb_right = 0;
+	p->var.height = 99;	/* in mm of NEC NL6448BC20-08 on ML300 */
+	p->var.width = 132;	/* in mm of NEC NL6448BC20-08 on ML300 */
+
+	return 0;
+}
+
+static int
+xilinx_encode_var(struct fb_var_screeninfo *var, const void *par,
+		  struct fb_info_gen *info)
+{
+	struct xilinxfb_par *p = (struct xilinxfb_par *) par;
+
+	*var = p->var;
+	return 0;
+}
+
+static void
+xilinx_get_par(void *par, struct fb_info_gen *info)
+{
+	struct xilinxfb_par *p = (struct xilinxfb_par *) par;
+
+	*p = current_par;
+}
+
+static void
+xilinx_set_par(const void *par, struct fb_info_gen *info)
+{
+	/* nothing to do: we don't change any settings */
+}
+
+static int
+xilinx_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+		 unsigned *blue, unsigned *transp, struct fb_info *info)
+{
+	struct xilinxfb_info *i = (struct xilinxfb_info *) info;
+	unsigned r, g, b;
+
+	if (regno >= 16)
+		return 1;
+
+	r = (i->fbcon_cmap32[regno] & 0xFF0000) >> 16;
+	g = (i->fbcon_cmap32[regno] & 0x00FF00) >> 8;
+	b = (i->fbcon_cmap32[regno] & 0x0000FF);
+
+	*red = r << 8;
+	*green = g << 8;
+	*blue = b << 8;
+	*transp = 0;
+
+	return 0;
+}
+
+static int
+xilinx_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
+		 unsigned transp, struct fb_info *info)
+{
+	struct xilinxfb_info *i = (struct xilinxfb_info *) info;
+
+	if (regno >= 16)
+		return 1;
+
+	/* We only handle 8 bits of each color. */
+	red >>= 8;
+	green >>= 8;
+	blue >>= 8;
+	i->fbcon_cmap32[regno] = ((unsigned long) red << 16
+				  | (unsigned long) green << 8
+				  | (unsigned long) blue);
+	return 0;
+}
+
+static int
+xilinx_pan_display(const struct fb_var_screeninfo *var,
+		   struct fb_info_gen *info)
+{
+	if (var->xoffset != 0 || var->yoffset != 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+xilinx_blank(int blank_mode, struct fb_info_gen *info)
+{
+	struct xilinxfb_info *i = (struct xilinxfb_info *) info;
+
+	switch (blank_mode) {
+	case VESA_NO_BLANKING:
+		/* turn on panel */
+		out_be32(i->regs + REG_CTRL, REG_CTRL_DEFAULT);
+		break;
+
+	case VESA_VSYNC_SUSPEND:
+	case VESA_HSYNC_SUSPEND:
+	case VESA_POWERDOWN:
+		/* turn off panel */
+		out_be32(i->regs + REG_CTRL, 0);
+	default:
+		break;
+
+	}
+	return 0;
+}
+
+static void
+xilinx_set_disp(const void *unused, struct display *disp,
+		struct fb_info_gen *info)
+{
+	struct xilinxfb_info *i = (struct xilinxfb_info *) info;
+
+	disp->screen_base = (char *) i->fb_virt_start;
+
+	disp->dispsw = &fbcon_cfb32;
+	disp->dispsw_data = i->fbcon_cmap32;
+}
+
+static struct fbgen_hwswitch xilinx_switch = {
+	xilinx_detect,
+	xilinx_encode_fix,
+	xilinx_decode_var,
+	xilinx_encode_var,
+	xilinx_get_par,
+	xilinx_set_par,
+	xilinx_getcolreg,
+	xilinx_setcolreg,
+	xilinx_pan_display,
+	xilinx_blank,
+	xilinx_set_disp
+};
+
+static int __init
+probe(int index)
+{
+	u32 *phys_reg_addr;
+	struct xilinxfb_info *i;
+	struct page *page, *end_page;
+
+	switch (index) {
+#if defined(CONFIG_XILINX_TFT_CNTLR_REF_0_INSTANCE)
+	case 0:
+		phys_reg_addr = 
+			(u32 *) CONFIG_XILINX_TFT_CNTLR_REF_0_DCR_BASEADDR;
+		break;
+#if defined(CONFIG_XILINX_TFT_CNTRLR_REF_1_INSTANCE)
+	case 1:
+		phys_reg_addr = 
+			(u32 *) CONFIG_XILINX_TFT_CNTLR_REF_1_DCR_BASEADDR;
+		break;
+#if defined(CONFIG_XILINX_TFT_CNTRLR_REF_2_INSTANCE)
+	case 2:
+		phys_reg_addr = 
+			(u32 *) CONFIG_XILINX_TFT_CNTLR_REF_2_DCR_BASEADDR;
+		break;
+#if defined(CONFIG_XILINX_TFT_CNTLR_REF_3_INSTANCE)
+#error Edit this file to add more devices.
+#endif				/* 3 */
+#endif				/* 2 */
+#endif				/* 1 */
+#endif				/* 0 */
+	default:
+		return -ENODEV;
+	}
+
+	/* Convert DCR register address to OPB address */
+	phys_reg_addr = (unsigned *)(((unsigned)phys_reg_addr*4)+0xd0000000);
+
+	/* Allocate the info and zero it out. */
+	i = (struct xilinxfb_info *) kmalloc(sizeof (struct xilinxfb_info),
+					     GFP_KERNEL);
+	if (!i) {
+		printk(KERN_ERR "Could not allocate Xilinx "
+		       "frame buffer #%d information.\n", index);
+		return -ENOMEM;
+	}
+	memset(i, 0, sizeof (struct xilinxfb_info));
+
+	/* Make it the head of info_list. */
+	spin_lock(&info_lock);
+	i->next = info_list;
+	info_list = i;
+	spin_unlock(&info_lock);
+
+	/*
+	 * At this point, things are ok for us to call remove_head_info() to
+	 * clean up if we run into any problems; i is on info_list and
+	 * all the pointers are zeroed because of the memset above.
+	 */
+
+	i->fb_virt_start = (unsigned long) consistent_alloc(GFP_KERNEL|GFP_DMA,
+							    FB_SIZE,
+							    &i->fb_phys);
+	if (!i->fb_virt_start) {
+		printk(KERN_ERR "Could not allocate frame buffer memory "
+		       "for Xilinx device #%d.\n", index);
+		remove_head_info();
+		return -ENOMEM;
+	}
+
+	/*
+	 * The 2.4 PPC version of consistent_alloc does not set the
+	 * pages reserved.  The pages need to be reserved so that mmap
+	 * will work.  This means that we need the following code.  When
+	 * consistent_alloc gets fixed, this will no longer be needed.
+	 * Note that in 2.4, consistent_alloc doesn't free up the extra
+	 * pages either.  This is already fixed in 2.5.
+	 */
+	page = virt_to_page(__va(i->fb_phys));
+	end_page = page + ((FB_SIZE+PAGE_SIZE-1)/PAGE_SIZE);
+	while (page < end_page)
+		mem_map_reserve(page++);
+
+	/* Clear the frame buffer. */
+	memset((void *) i->fb_virt_start, 0, FB_SIZE);
+
+	/* Map the control registers in. */
+	i->regs = (u32 *) ioremap((unsigned long) phys_reg_addr, NUM_REGS);
+
+	/* Tell the hardware where the frame buffer is. */
+	out_be32(i->regs + REG_FB_ADDR, i->fb_phys);
+
+	/* Turn on the display. */
+	out_be32(i->regs + REG_CTRL, REG_CTRL_DEFAULT);
+
+	current_par.var.xres = XRES;
+	current_par.var.xres_virtual = XRES_VIRTUAL;
+	current_par.var.yres = YRES;
+	current_par.var.yres_virtual = YRES_VIRTUAL;
+	current_par.var.bits_per_pixel = BITS_PER_PIXEL;
+
+	i->gen.parsize = sizeof (struct xilinxfb_par);
+	i->gen.fbhw = &xilinx_switch;
+
+	strcpy(i->gen.info.modename, "Xilinx LCD");
+	i->gen.info.changevar = NULL;
+	i->gen.info.node = -1;
+
+	i->gen.info.fbops = &xilinxfb_ops;
+	i->gen.info.disp = &i->disp;
+	i->gen.info.switch_con = &fbgen_switch;
+	i->gen.info.updatevar = &fbgen_update_var;
+	i->gen.info.blank = &fbgen_blank;
+	i->gen.info.flags = FBINFO_FLAG_DEFAULT;
+
+	/* This should give a reasonable default video mode */
+	fbgen_get_var(&i->disp.var, -1, &i->gen.info);
+	fbgen_do_set_var(&i->disp.var, 1, &i->gen);
+	fbgen_set_disp(-1, &i->gen);
+	fbgen_install_cmap(0, &i->gen);
+	if (register_framebuffer(&i->gen.info) < 0) {
+		printk(KERN_ERR "Could not register frame buffer "
+		       "for Xilinx device #%d.\n", index);
+		remove_head_info();
+		return -EINVAL;
+	}
+	printk(KERN_INFO "fb%d: %s frame buffer at 0x%08X mapped to 0x%08lX\n",
+	       GET_FB_IDX(i->gen.info.node), i->gen.info.modename,
+	       i->fb_phys, i->fb_virt_start);
+
+	return 0;
+}
+
+static int __init
+xilinxfb_init(void)
+{
+	int index = 0;
+
+	while (probe(index++) == 0) ;
+
+	/* If we found at least one, report success. */
+	return (index > 1) ? 0 : -ENODEV;
+}
+
+static void __exit
+xilinxfb_cleanup(void)
+{
+	while (info_list) {
+		unregister_framebuffer((struct fb_info *) info_list);
+		remove_head_info();
+	}
+}
+
+EXPORT_NO_SYMBOLS;
+
+module_init(xilinxfb_init);
+module_exit(xilinxfb_cleanup);
diff -urN linux-2.4.29/fs/adfs/dir.c linux-2.4.29-uc1/fs/adfs/dir.c
--- linux-2.4.29/fs/adfs/dir.c	2000-09-18 23:14:06.000000000 +0100
+++ linux-2.4.29-uc1/fs/adfs/dir.c	2005-06-14 02:11:47.000000000 +0100
@@ -286,10 +286,21 @@
 	return ERR_PTR(error);
 }
 
+#ifdef CONFIG_ADFS_FS_RW
+static int
+adfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+	    struct inode *new_dir, struct dentry *new_dentry)
+{
+}
+#endif
+
 /*
  * directories can handle most operations...
  */
 struct inode_operations adfs_dir_inode_operations = {
 	lookup:		adfs_lookup,
+#ifdef CONFIG_ADFS_FS_RW
+	rename:		adfs_rename,
+#endif
 	setattr:	adfs_notify_change,
 };
diff -urN linux-2.4.29/fs/binfmt_aout.c linux-2.4.29-uc1/fs/binfmt_aout.c
--- linux-2.4.29/fs/binfmt_aout.c	2005-01-19 14:10:10.000000000 +0000
+++ linux-2.4.29-uc1/fs/binfmt_aout.c	2005-06-14 02:11:47.000000000 +0100
@@ -313,6 +313,11 @@
 
 	current->mm->rss = 0;
 	current->mm->mmap = NULL;
+
+#ifdef CONFIG_ARM_FASS
+	arch_new_mm(current, current->mm);
+#endif
+
 	compute_creds(bprm);
  	current->flags &= ~PF_FORKNOEXEC;
 #ifdef __sparc__
@@ -441,7 +446,11 @@
 	start_thread(regs, ex.a_entry, current->mm->start_stack);
 	if (current->ptrace & PT_PTRACED)
 		send_sig(SIGTRAP, current, 0);
+#ifndef __arm__
 	return 0;
+#else
+	return regs->ARM_r0;
+#endif
 }
 
 static int load_aout_library(struct file *file)
@@ -471,8 +480,11 @@
 
 	/* For  QMAGIC, the starting address is 0x20 into the page.  We mask
 	   this off to get the starting address for the page */
-
+#ifndef __arm__
 	start_addr =  ex.a_entry & 0xfffff000;
+#else
+	start_addr = ex.a_entry & 0xffff8000;
+#endif
 
 	if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) {
 		static unsigned long error_time;
diff -urN linux-2.4.29/fs/binfmt_elf.c linux-2.4.29-uc1/fs/binfmt_elf.c
--- linux-2.4.29/fs/binfmt_elf.c	2005-01-19 14:10:10.000000000 +0000
+++ linux-2.4.29-uc1/fs/binfmt_elf.c	2005-06-14 02:11:47.000000000 +0100
@@ -679,6 +679,11 @@
 	current->mm->end_data = 0;
 	current->mm->end_code = 0;
 	current->mm->mmap = NULL;
+
+#ifdef CONFIG_ARM_FASS
+	arch_new_mm(current, current->mm);
+#endif
+
 	current->flags &= ~PF_FORKNOEXEC;
 	elf_entry = (unsigned long) elf_ex.e_entry;
 
diff -urN linux-2.4.29/fs/binfmt_flat.c linux-2.4.29-uc1/fs/binfmt_flat.c
--- linux-2.4.29/fs/binfmt_flat.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/fs/binfmt_flat.c	2005-06-14 02:11:44.000000000 +0100
@@ -0,0 +1,1174 @@
+/****************************************************************************/
+/*
+ *  linux/fs/binfmt_flat.c
+ *
+ *	Copyright (C) 2000-2003 David McCullough <davidm@snapgear.com>
+ *	Copyright (C) 2002 Greg Ungerer <gerg@snapgear.com>
+ *	Copyright (C) 2002 SnapGear, by Paul Dale <pauli@snapgear.com>
+ *	Copyright (C) 2000, 2001 Lineo, by David McCullough <davidm@lineo.com>
+ *  based heavily on:
+ *
+ *  linux/fs/binfmt_aout.c:
+ *      Copyright (C) 1991, 1992, 1996  Linus Torvalds
+ *  linux/fs/binfmt_flat.c for 2.0 kernel
+ *	    Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>
+ *	JAN/99 -- coded full program relocation (gerg@snapgear.com)
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/a.out.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/slab.h>
+#include <linux/binfmts.h>
+#include <linux/personality.h>
+#include <linux/init.h>
+#include <linux/flat.h>
+
+#include <asm/byteorder.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+#include <asm/unaligned.h>
+
+/****************************************************************************/
+
+#if 0
+#define DEBUG 1
+#endif
+
+#ifdef DEBUG
+#define	DBG_FLT(a...)	printk(a)
+#else
+#define	DBG_FLT(a...)
+#endif
+
+#define RELOC_FAILED 0xff00ff01		/* Relocation incorrect somewhere */
+#define UNLOADED_LIB 0x7ff000ff		/* Placeholder for unused library */
+
+struct lib_info {
+	struct {
+		unsigned long start_code;		/* Start of text segment */
+		unsigned long start_data;		/* Start of data segment */
+		unsigned long start_brk;		/* End of data segment */
+		unsigned long text_len;			/* Length of text segment */
+		unsigned long entry;			/* Start address for this module */
+		unsigned long build_date;		/* When this one was compiled */
+		short loaded;				/* Has this library been loaded? */
+	} lib_list[MAX_SHARED_LIBS];
+};
+
+#ifdef CONFIG_BINFMT_SHARED_FLAT
+static int load_flat_shared_library(int id, struct lib_info *p);
+#endif
+
+static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs);
+static int flat_core_dump(long signr, struct pt_regs * regs, struct file *file);
+
+extern void dump_thread(struct pt_regs *, struct user *);
+
+static struct linux_binfmt flat_format = {
+	.module		= THIS_MODULE,
+	.load_binary	= load_flat_binary,
+	.core_dump	= flat_core_dump,
+	.min_coredump	= PAGE_SIZE
+};
+
+/****************************************************************************/
+/*
+ * Routine writes a core dump image in the current directory.
+ * Currently only a stub-function.
+ */
+
+static int flat_core_dump(long signr, struct pt_regs * regs, struct file *file)
+{
+	printk("Process %s:%d received signr %d and should have core dumped\n",
+			current->comm, current->pid, (int) signr);
+	return(1);
+}
+
+/****************************************************************************/
+/*
+ * create_flat_tables() parses the env- and arg-strings in new user
+ * memory and creates the pointer tables from them, and puts their
+ * addresses on the "stack", returning the new stack pointer value.
+ */
+
+static unsigned long create_flat_tables(
+	unsigned long pp,
+	struct linux_binprm * bprm)
+{
+	unsigned long *argv,*envp;
+	unsigned long * sp;
+	char * p = (char*)pp;
+	int argc = bprm->argc;
+	int envc = bprm->envc;
+	char dummy;
+
+	sp = (unsigned long *) ((-(unsigned long)sizeof(char *))&(unsigned long) p);
+
+	sp -= envc+1;
+	envp = sp;
+	sp -= argc+1;
+	argv = sp;
+
+	flat_stack_align(sp);
+	if (flat_argvp_envp_on_stack()) {
+		--sp; put_user((unsigned long) envp, sp);
+		--sp; put_user((unsigned long) argv, sp);
+	}
+
+	put_user(argc,--sp);
+	current->mm->arg_start = (unsigned long) p;
+	while (argc-->0) {
+		put_user((unsigned long) p, argv++);
+		do {
+			get_user(dummy, p); p++;
+		} while (dummy);
+	}
+	put_user((unsigned long) NULL, argv);
+	current->mm->arg_end = current->mm->env_start = (unsigned long) p;
+	while (envc-->0) {
+		put_user((unsigned long)p, envp); envp++;
+		do {
+			get_user(dummy, p); p++;
+		} while (dummy);
+	}
+	put_user((unsigned long) NULL, envp);
+	current->mm->env_end = (unsigned long) p;
+	return (unsigned long)sp;
+}
+
+/****************************************************************************/
+
+#ifdef CONFIG_BINFMT_ZFLAT
+
+#include <linux/zlib.h>
+
+#define LBUFSIZE	4000
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ASCII text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
+#define RESERVED     0xC0 /* bit 6,7:   reserved */
+
+static int decompress_exec(
+	struct linux_binprm *bprm,
+	unsigned long offset,
+	char *dst,
+	long len,
+	int fd)
+{
+	unsigned char *buf;
+	z_stream strm;
+	loff_t fpos;
+	int ret, retval;
+
+	DBG_FLT("decompress_exec(offset=%x,buf=%x,len=%x)\n",(int)offset, (int)dst, (int)len);
+
+	memset(&strm, 0, sizeof(strm));
+	strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
+	if (strm.workspace == NULL) {
+		DBG_FLT("binfmt_flat: no memory for decompress workspace\n");
+		return -ENOMEM;
+	}
+	buf = kmalloc(LBUFSIZE, GFP_KERNEL);
+	if (buf == NULL) {
+		DBG_FLT("binfmt_flat: no memory for read buffer\n");
+		retval = -ENOMEM;
+		goto out_free;
+	}
+
+	/* Read in first chunk of data and parse gzip header. */
+	fpos = offset;
+	ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos);
+
+	strm.next_in = buf;
+	strm.avail_in = ret;
+	strm.total_in = 0;
+
+	retval = -ENOEXEC;
+
+	/* Check minimum size -- gzip header */
+	if (ret < 10) {
+		DBG_FLT("binfmt_flat: file too small?\n");
+		goto out_free_buf;
+	}
+
+	/* Check gzip magic number */
+	if ((buf[0] != 037) || ((buf[1] != 0213) && (buf[1] != 0236))) {
+		DBG_FLT("binfmt_flat: unknown compression magic?\n");
+		goto out_free_buf;
+	}
+
+	/* Check gzip method */
+	if (buf[2] != 8) {
+		DBG_FLT("binfmt_flat: unknown compression method?\n");
+		goto out_free_buf;
+	}
+	/* Check gzip flags */
+	if ((buf[3] & ENCRYPTED) || (buf[3] & CONTINUATION) ||
+	    (buf[3] & RESERVED)) {
+		DBG_FLT("binfmt_flat: unknown flags?\n");
+		goto out_free_buf;
+	}
+
+	ret = 10;
+	if (buf[3] & EXTRA_FIELD) {
+		ret += 2 + buf[10] + (buf[11] << 8);
+		if (unlikely(LBUFSIZE == ret)) {
+			DBG_FLT("binfmt_flat: buffer overflow (EXTRA)?\n");
+			goto out_free_buf;
+		}
+	}
+	if (buf[3] & ORIG_NAME) {
+		for (; ret < LBUFSIZE && (buf[ret] != 0); ret++)
+			;
+		if (unlikely(LBUFSIZE == ret)) {
+			DBG_FLT("binfmt_flat: buffer overflow (ORIG_NAME)?\n");
+			goto out_free_buf;
+		}
+	}
+	if (buf[3] & COMMENT) {
+		for (;  ret < LBUFSIZE && (buf[ret] != 0); ret++)
+			;
+		if (unlikely(LBUFSIZE == ret)) {
+			DBG_FLT("binfmt_flat: buffer overflow (COMMENT)?\n");
+			goto out_free_buf;
+		}
+	}
+
+	strm.next_in += ret;
+	strm.avail_in -= ret;
+
+	strm.next_out = dst;
+	strm.avail_out = len;
+	strm.total_out = 0;
+
+	if (zlib_inflateInit2(&strm, -MAX_WBITS) != Z_OK) {
+		DBG_FLT("binfmt_flat: zlib init failed?\n");
+		goto out_free_buf;
+	}
+
+	while ((ret = zlib_inflate(&strm, Z_NO_FLUSH)) == Z_OK) {
+		ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos);
+		if (ret <= 0)
+			break;
+		if (ret >= (unsigned long) -4096)
+			break;
+		len -= ret;
+
+		strm.next_in = buf;
+		strm.avail_in = ret;
+		strm.total_in = 0;
+	}
+
+	if (ret < 0) {
+		DBG_FLT("binfmt_flat: decompression failed (%d), %s\n",
+			ret, strm.msg);
+		goto out_free_buf;
+	}
+
+	zlib_inflateEnd(&strm);
+	retval = 0;
+out_free_buf:
+	kfree(buf);
+out_free:
+	kfree(strm.workspace);
+out:
+	return retval;
+}
+
+#endif /* CONFIG_BINFMT_ZFLAT */
+
+/****************************************************************************/
+
+static unsigned long
+calc_reloc(unsigned long r, struct lib_info *p, int curid, int internalp)
+{
+	unsigned long addr;
+	int id;
+	unsigned long start_brk;
+	unsigned long start_data;
+	unsigned long text_len;
+	unsigned long start_code;
+
+#ifdef CONFIG_BINFMT_SHARED_FLAT
+	if (r == 0)
+		id = curid;	/* Relocs of 0 are always self referring */
+	else {
+		id = (r >> 24) & 0xff;	/* Find ID for this reloc */
+		r &= 0x00ffffff;	/* Trim ID off here */
+	}
+	if (id >= MAX_SHARED_LIBS) {
+		printk("BINFMT_FLAT: reference 0x%x to shared library %d",
+				(unsigned) r, id);
+		goto failed;
+	}
+	if (curid != id) {
+		if (internalp) {
+			printk("BINFMT_FLAT: reloc address 0x%x not in same module "
+					"(%d != %d)", (unsigned) r, curid, id);
+			goto failed;
+		} else if ( ! p->lib_list[id].loaded &&
+				load_flat_shared_library(id, p) > (unsigned long) -4096) {
+			printk("BINFMT_FLAT: failed to load library %d", id);
+			goto failed;
+		}
+		/* Check versioning information (i.e. time stamps) */
+		if (p->lib_list[id].build_date && p->lib_list[curid].build_date &&
+				p->lib_list[curid].build_date < p->lib_list[id].build_date) {
+			printk("BINFMT_FLAT: library %d is younger than %d", id, curid);
+			goto failed;
+		}
+	}
+#else
+	id = 0;
+#endif
+
+	start_brk = p->lib_list[id].start_brk;
+	start_data = p->lib_list[id].start_data;
+	start_code = p->lib_list[id].start_code;
+	text_len = p->lib_list[id].text_len;
+
+	if (!flat_reloc_valid(r, start_brk - start_data + text_len)) {
+		printk("BINFMT_FLAT: reloc outside program 0x%x (0 - 0x%x/0x%x)",
+		       (int) r,(int)(start_brk-start_code),(int)text_len);
+		goto failed;
+	}
+
+	if (r < text_len)			/* In text segment */
+		addr = r + start_code;
+	else					/* In data segment */
+		addr = r - text_len + start_data;
+
+	/* Range checked already above so doing the range tests is redundant...*/
+	return(addr);
+
+failed:
+	printk(", killing %s!\n", current->comm);
+	send_sig(SIGSEGV, current, 0);
+
+	return RELOC_FAILED;
+}
+
+/****************************************************************************/
+#ifdef CONFIG_MIPS
+typedef struct {
+	unsigned long flags;
+	unsigned long opcode;
+	unsigned long *ptr;
+} mips_save_hi_reloc;
+#endif
+
+void calc_v5_reloc(int i, unsigned long rl)
+{
+	flat_v5_reloc_t r;
+	unsigned long *ptr;
+	unsigned short *usptr;
+	unsigned long offset, opcode;
+#ifdef CONFIG_MIPS
+	mips_save_hi_reloc hi_reloc;
+#endif
+#ifdef CONFIG_BLACKFIN
+	static int save_carry;
+#endif
+
+	r.value = rl;
+	ptr = (unsigned long *)(current->mm->start_code + r.reloc.offset);
+
+	switch (r.reloc.sp)
+	{
+#ifdef CONFIG_MIPS
+	case FLAT_MIPS_RELOC_SP(FLAT_MIPS_RELOC_SP_TYPE_16_BIT, FLAT_MIPS_RELOC_SP_NO_CARRY):
+		offset = (*ptr) & 0x0000FFFFL;
+		if (r.reloc.hi_lo)
+			offset <<= 16;
+
+		opcode = (*ptr) & 0xFFFF0000L;
+
+		switch (r.reloc.type)
+		{
+		case FLAT_V5_RELOC_TYPE_TEXT:
+			offset += current->mm->start_code;
+			break;
+		case FLAT_V5_RELOC_TYPE_DATA:
+			offset += current->mm->start_data;
+			break;
+		case  FLAT_V5_RELOC_TYPE_BSS:
+			offset += current->mm->end_data;
+			break;
+		default:
+			printk("BINFMT_FLAT: Unknown relocation type=%x\n",
+					r.reloc.type);
+			break;
+		}
+
+		if (r.reloc.hi_lo)
+			offset >>= 16;
+
+		(*ptr) = opcode | (offset & 0x0000FFFFL);
+
+		if (r.reloc.hi_lo)
+		{
+			hi_reloc.flags = 1;
+			hi_reloc.opcode = (*ptr);
+			hi_reloc.ptr = ptr;
+		}
+		break;
+	case FLAT_MIPS_RELOC_SP(FLAT_MIPS_RELOC_SP_TYPE_16_BIT, FLAT_MIPS_RELOC_SP_CARRY):
+		offset = (*ptr) & 0x0000FFFFL;
+		if (r.reloc.hi_lo)
+			offset <<= 16;
+
+		opcode = (*ptr) & 0xFFFF0000L;
+
+		switch (r.reloc.type)
+		{
+		case FLAT_V5_RELOC_TYPE_TEXT:
+			offset += current->mm->start_code;
+			break;
+		case FLAT_V5_RELOC_TYPE_DATA:
+			offset += current->mm->start_data;
+			break;
+		case FLAT_V5_RELOC_TYPE_BSS:
+			offset += current->mm->end_data;
+			break;
+		default:
+			printk("BINFMT_FLAT: Unknown relocation type=%x\n",
+					r.reloc.type);
+			break;
+		}
+
+		if (r.reloc.hi_lo)
+			offset >>= 16;
+
+		(*ptr) = opcode | (offset & 0x0000FFFFL);
+
+		if (r.reloc.hi_lo)
+		{
+			hi_reloc.flags = 1;
+			hi_reloc.opcode = (*ptr);
+			hi_reloc.ptr = ptr;
+		} else {
+			unsigned long temp;
+			if (hi_reloc.flags == 1)
+			{
+				if ((*ptr) & 0x00008000L)
+				{
+					temp = hi_reloc.opcode & 0x0000FFFFL;
+					temp += 1;
+					hi_reloc.opcode = 
+					    ((hi_reloc.opcode & 0xFFFF0000L) |
+					     (temp & 0x0000FFFFL));
+					*(hi_reloc.ptr) = hi_reloc.opcode;
+					hi_reloc.flags = 0;
+				}
+			}
+		}
+		break;
+	case FLAT_MIPS_RELOC_SP(FLAT_MIPS_RELOC_SP_TYPE_26_BIT, FLAT_MIPS_RELOC_SP_NO_CARRY):
+		if (hi_reloc.flags)
+			hi_reloc.flags = 0;
+
+		offset = (*ptr) & 0x03FFFFFFL;
+		offset <<= 2;
+
+		opcode = (*ptr) & 0xFC000000L;
+
+		switch (r.reloc.type)
+		{
+		case FLAT_V5_RELOC_TYPE_TEXT:
+			offset += current->mm->start_code;
+			break;
+		case FLAT_V5_RELOC_TYPE_DATA:
+			offset += current->mm->start_data;
+			break;
+		case FLAT_V5_RELOC_TYPE_BSS:
+			offset += current->mm->end_data;
+			break;
+		default:
+			printk("BINFMT_FLAT: Unknown relocation type=%x\n",
+					r.reloc.type);
+			break;
+		}
+		offset >>= 2;
+
+		(*ptr) = opcode | (offset & 0x03FFFFFFL);
+		break;
+	case FLAT_MIPS_RELOC_SP(FLAT_MIPS_RELOC_SP_TYPE_32_BIT, FLAT_MIPS_RELOC_SP_NO_CARRY):
+		offset = *ptr;
+
+		switch (r.reloc.type)
+		{
+		case FLAT_V5_RELOC_TYPE_TEXT:
+			offset += current->mm->start_code;
+			break;
+		case FLAT_V5_RELOC_TYPE_DATA:
+			offset += current->mm->start_data;
+			break;
+		case FLAT_V5_RELOC_TYPE_BSS:
+			offset += current->mm->end_data;
+			break;
+		default:
+			printk("BINFMT_FLAT: offset = %x, Unknown relocation type = %x",
+					r.reloc.offset, r.reloc.type);
+			break;
+		}
+		*ptr = offset;
+		break;
+#endif /* CONFIG_MIPS */
+#ifdef CONFIG_BLACKFIN
+	case FLAT_BLACKFIN_RELOC_SP_TYPE_16_BIT:
+		usptr = (unsigned short *)ptr;
+
+		switch (r.reloc.type)
+		{
+		case FLAT_V5_RELOC_TYPE_TEXT:
+			offset = current->mm->start_code;
+			break;
+		case FLAT_V5_RELOC_TYPE_DATA:
+			offset = current->mm->start_data;
+			break;
+		case FLAT_V5_RELOC_TYPE_BSS:
+			offset = current->mm->end_data;
+			break;
+		default:
+			printk("BINFMT_FLAT: Unknown relocation type = %x\n",
+					r.reloc.type);
+			break;
+		}
+
+		if (r.reloc.hi_lo) 
+		{
+			offset >>= 16;
+			offset += *usptr;
+			offset += save_carry;
+		} else {
+			offset &= 0xffff;
+			offset += *usptr;
+			save_carry = (offset >> 16) & 1;
+		}
+		*usptr = offset;
+		break;
+	case FLAT_BLACKFIN_RELOC_SP_TYPE_32_BIT:
+		offset = *ptr;
+
+		switch (r.reloc.type)
+		{
+		case FLAT_V5_RELOC_TYPE_TEXT:
+			offset += current->mm->start_code;
+			break;
+		case FLAT_V5_RELOC_TYPE_DATA:
+			offset += current->mm->start_data;
+			break;
+		case FLAT_V5_RELOC_TYPE_BSS:
+			offset += current->mm->end_data;
+			break;
+		default:
+			printk("BINFMT_FLAT: offset = %x, Unknown relocation type = %x",
+					r.reloc.offset, r.reloc.type);
+			break;
+		}
+		*ptr = offset;
+		break;
+#endif /* CONFIG_BLACKFIN */	
+	default:
+		printk("BINFMT_FLAT: Unknown relocation type %x\n", r.reloc.sp);
+		break;
+	}
+}
+
+/****************************************************************************/
+
+void old_reloc(unsigned long rl)
+{
+#ifdef DEBUG
+	char *segment[] = { "TEXT", "DATA", "BSS", "*UNKNOWN*" };
+#endif
+#if !defined(__H8300H__) && !defined(__H8300S__)
+	flat_v2_reloc_t	r;
+#endif
+	unsigned long *ptr;
+
+#if !defined(__H8300H__) && !defined(__H8300S__)
+	r.value = rl;
+#if defined(CONFIG_COLDFIRE)
+	ptr = (unsigned long *) (current->mm->start_code + r.reloc.offset);
+#else
+	ptr = (unsigned long *) (current->mm->start_data + r.reloc.offset);
+#endif
+
+#ifdef DEBUG
+	printk("Relocation of variable at DATASEG+%x "
+		"(address %p, currently %x) into segment %s\n",
+		r.reloc.offset, ptr, (int)*ptr, segment[r.reloc.type]);
+#endif
+	
+	switch (r.reloc.type) {
+	case OLD_FLAT_RELOC_TYPE_TEXT:
+		*ptr += current->mm->start_code;
+		break;
+	case OLD_FLAT_RELOC_TYPE_DATA:
+		*ptr += current->mm->start_data;
+		break;
+	case OLD_FLAT_RELOC_TYPE_BSS:
+		*ptr += current->mm->end_data;
+		break;
+	default:
+		printk("BINFMT_FLAT: Unknown relocation type=%x\n", r.reloc.type);
+		break;
+	}
+
+#ifdef DEBUG
+	printk("Relocation became %x\n", (int)*ptr);
+#endif
+#else
+	ptr = (unsigned long *)(current->mm->start_code+rl);
+	if (ptr >= current->mm->end_code)
+		ptr += sizeof(MAX_SHARED_LIBS) / sizeof (*ptr);
+	*ptr += current->mm->start_code;
+	if ((*ptr & 0x00ffffff) >= current->mm->end_code)
+		*ptr += MAX_SHARED_LIBS * sizeof(unsigned long);
+#endif
+}		
+
+/****************************************************************************/
+
+static int load_flat_file(struct linux_binprm * bprm,
+		struct lib_info *libinfo, int id, unsigned long *extra_stack)
+{
+	struct flat_hdr * hdr;
+	unsigned long textpos = 0, datapos = 0, result;
+	unsigned long realdatastart = 0;
+	unsigned long text_len, data_len, bss_len, stack_len, flags;
+	unsigned long memp = 0; /* for finding the brk area */
+	unsigned long extra, rlim;
+	unsigned long *reloc = 0, *rp;
+	struct inode *inode;
+	int i, rev, relocs = 0;
+	loff_t fpos;
+	unsigned long start_code, end_code;
+
+	hdr = ((struct flat_hdr *) bprm->buf);		/* exec-header */
+	inode = bprm->file->f_dentry->d_inode;
+
+	text_len  = ntohl(hdr->data_start);
+	data_len  = ntohl(hdr->data_end) - ntohl(hdr->data_start);
+	bss_len   = ntohl(hdr->bss_end) - ntohl(hdr->data_end);
+	stack_len = ntohl(hdr->stack_size);
+	if (extra_stack) {
+		stack_len += *extra_stack;
+		*extra_stack = stack_len;
+	}
+	relocs    = ntohl(hdr->reloc_count);
+	flags     = ntohl(hdr->flags);
+	rev       = ntohl(hdr->rev);
+
+	if (flags & FLAT_FLAG_KTRACE)
+		printk("BINFMT_FLAT: Loading file: %s\n", bprm->filename);
+
+	if (strncmp(hdr->magic, "bFLT", 4) ||
+			(rev != FLAT_VERSION && rev != OLD_FLAT_VERSION &&
+			 rev != V5_FLAT_VERSION)) {
+		/*
+		 * because a lot of people do not manage to produce good
+		 * flat binaries,  we leave this printk to help them realise
+		 * the problem.  We only print the error if its not a script file
+		 */
+		if (strncmp(hdr->magic, "#!", 2))
+			printk("BINFMT_FLAT: bad magic/rev (0x%x, need 0x%x)\n",
+					rev, (int) FLAT_VERSION);
+		return -ENOEXEC;
+	}
+	
+	/* Don't allow old format executables to use shared libraries */
+	if (rev == OLD_FLAT_VERSION && id != 0) {
+		printk("BINFMT_FLAT: shared libraries are not available before rev 0x%x\n",
+				(int) FLAT_VERSION);
+		return -ENOEXEC;
+	}
+
+	/*
+	 * fix up the flags for the older format,  there were all kinds
+	 * of endian hacks,  this only works for the simple cases
+	 */
+	if (rev == OLD_FLAT_VERSION && flat_old_ram_flag(flags))
+		flags = FLAT_FLAG_RAM;
+
+#ifndef CONFIG_BINFMT_ZFLAT
+	if (flags & (FLAT_FLAG_GZIP|FLAT_FLAG_GZDATA)) {
+		printk("Support for ZFLAT executables is not enabled.\n");
+		return -ENOEXEC;
+	}
+#endif
+
+	/*
+	 * Check initial limits. This avoids letting people circumvent
+	 * size limits imposed on them by creating programs with large
+	 * arrays in the data or bss.
+	 */
+	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+	if (rlim >= RLIM_INFINITY)
+		rlim = ~0;
+	if (data_len + bss_len > rlim)
+		return -ENOMEM;
+
+	/* Flush all traces of the currently running executable */
+	if (id == 0) {
+		result = flush_old_exec(bprm);
+		if (result)
+			return result;
+
+		/* OK, This is the point of no return */
+		set_personality(PER_LINUX);
+	}
+
+	/*
+	 * calculate the extra space we need to map in
+	 */
+	extra = max(bss_len + stack_len, (long)relocs * sizeof(unsigned long));
+
+	/*
+	 * there are a couple of cases here,  the seperate code/data
+	 * case,  and then the fully copied to RAM case which lumps
+	 * it all together.
+	 */
+	if ((flags & (FLAT_FLAG_RAM|FLAT_FLAG_GZIP)) == 0) {
+		/*
+		 * this should give us a ROM ptr,  but if it doesn't we don't
+		 * really care
+		 */
+		DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");
+
+		down_write(&current->mm->mmap_sem);
+		textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, 0, 0);
+		up_write(&current->mm->mmap_sem);
+		if (!textpos  || textpos >= (unsigned long) -4096) {
+			if (!textpos)
+				textpos = (unsigned long) -ENOMEM;
+			printk("Unable to mmap process text, errno %d\n", (int)-textpos);
+			return(textpos);
+		}
+
+		down_write(&current->mm->mmap_sem);
+		realdatastart = do_mmap(0, 0, data_len + extra +
+				MAX_SHARED_LIBS * sizeof(unsigned long),
+				PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0);
+		up_write(&current->mm->mmap_sem);
+
+		if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) {
+			if (!realdatastart)
+				realdatastart = (unsigned long) -ENOMEM;
+			printk("Unable to allocate RAM for process data, errno %d\n",
+					(int)-datapos);
+			do_munmap(current->mm, textpos, text_len);
+			return realdatastart;
+		}
+		datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
+
+		DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n",
+				(int)(data_len + bss_len + stack_len), (int)datapos);
+
+		fpos = ntohl(hdr->data_start);
+#ifdef CONFIG_BINFMT_ZFLAT
+		if (flags & FLAT_FLAG_GZDATA) {
+			result = decompress_exec(bprm, fpos, (char *) datapos, 
+						 data_len + (relocs * sizeof(unsigned long)), 0);
+		} else
+#endif
+		{
+			result = bprm->file->f_op->read(bprm->file, (char *) datapos,
+					data_len + (relocs * sizeof(unsigned long)), &fpos);
+		}
+		if (result >= (unsigned long)-4096) {
+			printk("Unable to read data+bss, errno %d\n", (int)-result);
+			do_munmap(current->mm, textpos, text_len);
+			do_munmap(current->mm, realdatastart, data_len + extra);
+			return result;
+		}
+
+		reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len));
+		memp = realdatastart;
+
+	} else {
+
+		down_write(&current->mm->mmap_sem);
+		textpos = do_mmap(0, 0, text_len + data_len + extra +
+					MAX_SHARED_LIBS * sizeof(unsigned long),
+				PROT_READ | PROT_EXEC | PROT_WRITE, 0, 0);
+		up_write(&current->mm->mmap_sem);
+		if (!textpos  || textpos >= (unsigned long) -4096) {
+			if (!textpos)
+				textpos = (unsigned long) -ENOMEM;
+			printk("Unable to allocate RAM for process text/data, errno %d\n",
+					(int)-textpos);
+			return(textpos);
+		}
+
+		realdatastart = textpos + ntohl(hdr->data_start);
+		datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
+		reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start) +
+				MAX_SHARED_LIBS * sizeof(unsigned long));
+		memp = textpos;
+
+#ifdef CONFIG_BINFMT_ZFLAT
+		/*
+		 * load it all in and treat it like a RAM load from now on
+		 */
+		if (flags & FLAT_FLAG_GZIP) {
+			result = decompress_exec(bprm, sizeof (struct flat_hdr),
+					 (((char *) textpos) + sizeof (struct flat_hdr)),
+					 (text_len + data_len + (relocs * sizeof(unsigned long))
+						  - sizeof (struct flat_hdr)),
+					 0);
+			memmove((void *) datapos, (void *) realdatastart,
+					data_len + (relocs * sizeof(unsigned long)));
+		} else if (flags & FLAT_FLAG_GZDATA) {
+			fpos = 0;
+			result = bprm->file->f_op->read(bprm->file,
+					(char *) textpos, text_len, &fpos);
+			if (result < (unsigned long) -4096)
+				result = decompress_exec(bprm, text_len, (char *) datapos,
+						 data_len + (relocs * sizeof(unsigned long)), 0);
+		}
+		else
+#endif
+		{
+			fpos = 0;
+			result = bprm->file->f_op->read(bprm->file,
+					(char *) textpos, text_len, &fpos);
+			if (result < (unsigned long) -4096) {
+				fpos = ntohl(hdr->data_start);
+				result = bprm->file->f_op->read(bprm->file, (char *) datapos,
+					data_len + (relocs * sizeof(unsigned long)), &fpos);
+			}
+		}
+		if (result >= (unsigned long)-4096) {
+			printk("Unable to read code+data+bss, errno %d\n",(int)-result);
+			do_munmap(current->mm, textpos, text_len + data_len + extra +
+				MAX_SHARED_LIBS * sizeof(unsigned long));
+			return result;
+		}
+	}
+
+	if (flags & FLAT_FLAG_KTRACE)
+		printk("Mapping is %x, Entry point is %x, data_start is %x\n",
+			(int)textpos, 0x00ffffff&ntohl(hdr->entry), ntohl(hdr->data_start));
+
+	/* The main program needs a little extra setup in the task structure */
+	start_code = textpos + sizeof (struct flat_hdr);
+	end_code = textpos + text_len;
+	if (id == 0) {
+		current->mm->start_code = start_code;
+		current->mm->end_code = end_code;
+		current->mm->start_data = datapos;
+		current->mm->end_data = datapos + data_len;
+		/*
+		 * set up the brk stuff, uses any slack left in data/bss/stack
+		 * allocation.  We put the brk after the bss (between the bss
+		 * and stack) like other platforms.
+		 */
+		current->mm->start_brk = datapos + data_len + bss_len;
+		current->mm->brk = (current->mm->start_brk + 3) & ~3;
+		current->mm->end_brk = memp + ksize((void *) memp) - stack_len;
+		current->mm->rss = 0;
+	}
+
+	if (flags & FLAT_FLAG_KTRACE)
+		printk("%s %s: TEXT=%x-%x DATA=%x-%x BSS=%x-%x\n",
+			id ? "Lib" : "Load", bprm->filename,
+			(int) start_code, (int) end_code,
+			(int) datapos,
+			(int) (datapos + data_len),
+			(int) (datapos + data_len),
+			(int) (((datapos + data_len + bss_len) + 3) & ~3));
+
+	text_len -= sizeof(struct flat_hdr); /* the real code len */
+
+	/* Store the current module values into the global library structure */
+	libinfo->lib_list[id].start_code = start_code;
+	libinfo->lib_list[id].start_data = datapos;
+	libinfo->lib_list[id].start_brk = datapos + data_len + bss_len;
+	libinfo->lib_list[id].text_len = text_len;
+	libinfo->lib_list[id].loaded = 1;
+	libinfo->lib_list[id].entry = (0x00ffffff & ntohl(hdr->entry)) + textpos;
+	libinfo->lib_list[id].build_date = ntohl(hdr->build_date);
+	
+	/*
+	 * We just load the allocations into some temporary memory to
+	 * help simplify all this mumbo jumbo
+	 *
+	 * We've got two different sections of relocation entries.
+	 * The first is the GOT which resides at the begining of the data segment
+	 * and is terminated with a -1.  This one can be relocated in place.
+	 * The second is the extra relocation entries tacked after the image's
+	 * data segment. These require a little more processing as the entry is
+	 * really an offset into the image which contains an offset into the
+	 * image.
+	 */
+
+	/*
+	 * XXX: Don't perform any GOTPIC relocations for version 5 flats
+	 * for now.
+	 *
+	 * Faisal Akber
+	 */
+	if ((flags & FLAT_FLAG_GOTPIC) && (rev != 5)) {
+		for (rp = (unsigned long *)datapos; *rp != 0xffffffff; rp++) {
+			unsigned long addr;
+			if (*rp) {
+				addr = calc_reloc(*rp, libinfo, id, 0);
+				if (addr == RELOC_FAILED)
+					return -ENOEXEC;
+				*rp = addr;
+			}
+		}
+	}
+
+	/*
+	 * Now run through the relocation entries.
+	 * We've got to be careful here as C++ produces relocatable zero
+	 * entries in the constructor and destructor tables which are then
+	 * tested for being not zero (which will always occur unless we're
+	 * based from address zero).  This causes an endless loop as __start
+	 * is at zero.  The solution used is to not relocate zero addresses.
+	 * This has the negative side effect of not allowing a global data
+	 * reference to be statically initialised to _stext (I've moved
+	 * __start to address 4 so that is okay).
+	 */
+	switch (rev)
+	{
+	case 5:
+		{
+			for (i = 0; i < relocs; i++)
+			{
+				/* Calculate each relocation, and replace
+				 * whatever necessary.
+				 */
+				calc_v5_reloc(i, reloc[i]);
+			}
+		}
+		break;
+	case 4:
+	case 3:
+		{
+			for (i=0; i < relocs; i++) 
+			{
+				unsigned long addr, relval;
+
+				/* Get the address of the pointer to be
+				   relocated (of course, the address has to be
+				   relocated first).  */
+				relval = ntohl(reloc[i]);
+				addr = flat_get_relocate_addr(relval);
+				rp = (unsigned long *) calc_reloc(addr, libinfo, id, 1);
+				if (rp == (unsigned long *)RELOC_FAILED)
+					return -ENOEXEC;
+
+				/* Get the pointer's value.  */
+				addr = flat_get_addr_from_rp(rp, relval, flags);
+				if (addr != 0) 
+				{
+					/*
+					 * Do the relocation.  PIC relocs in 
+					 * the data section are already in 
+					 * target order
+					 */
+					if ((flags & FLAT_FLAG_GOTPIC) == 0)
+						addr = ntohl(addr);
+					addr = calc_reloc(addr, libinfo, id, 0);
+					if (addr == RELOC_FAILED)
+						return -ENOEXEC;
+
+					/* Write back the relocated pointer.  */
+					flat_put_addr_at_rp(rp, addr, relval);
+				}
+			}
+		}
+		break;
+	case 2:
+	case 1:
+		{
+			for (i=0; i < relocs; i++)
+				old_reloc(ntohl(reloc[i]));
+		}
+		break;
+	default:
+		printk("Invalid binary version number.\n");
+	}
+	
+	flush_icache_range(start_code, end_code);
+
+	/* zero the BSS,  BRK and stack areas */
+	memset((void*)(datapos + data_len), 0, bss_len + 
+			(memp + ksize((void *) memp) - stack_len -	/* end brk */
+			libinfo->lib_list[id].start_brk) +		/* start brk */
+			stack_len);
+
+	return 0;
+}
+
+
+/****************************************************************************/
+#ifdef CONFIG_BINFMT_SHARED_FLAT
+
+/*
+ * Load a shared library into memory.  The library gets its own data
+ * segment (including bss) but not argv/argc/environ.
+ */
+
+static int load_flat_shared_library(int id, struct lib_info *libs)
+{
+	struct linux_binprm bprm;
+	int res;
+	char buf[16];
+
+	/* Create the file name */
+	sprintf(buf, "/lib/lib%d.so", id);
+
+	/* Open the file up */
+	bprm.filename = buf;
+	bprm.file = open_exec(bprm.filename);
+	res = PTR_ERR(bprm.file);
+	if (IS_ERR(bprm.file))
+		return res;
+
+	res = prepare_binprm(&bprm);
+
+	if (res <= (unsigned long)-4096)
+		res = load_flat_file(&bprm, libs, id, NULL);
+	if (bprm.file) {
+		allow_write_access(bprm.file);
+		fput(bprm.file);
+		bprm.file = NULL;
+	}
+	return(res);
+}
+
+#endif /* CONFIG_BINFMT_SHARED_FLAT */
+/****************************************************************************/
+
+/*
+ * These are the functions used to load flat style executables and shared
+ * libraries.  There is no binary dependent code anywhere else.
+ */
+
+static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
+{
+	struct lib_info libinfo;
+	unsigned long p = bprm->p;
+	unsigned long stack_len;
+	unsigned long start_addr;
+	unsigned long *sp;
+	int res;
+	int i, j;
+
+	memset(&libinfo, 0, sizeof(libinfo));
+	/*
+	 * We have to add the size of our arguments to our stack size
+	 * otherwise it's too easy for users to create stack overflows
+	 * by passing in a huge argument list.  And yes,  we have to be
+	 * pedantic and include space for the argv/envp array as it may have
+	 * a lot of entries.
+	 */
+#define TOP_OF_ARGS (PAGE_SIZE * MAX_ARG_PAGES - sizeof(void *))
+	stack_len = TOP_OF_ARGS - bprm->p;             /* the strings */
+	stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */
+	stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */
+
+	
+	res = load_flat_file(bprm, &libinfo, 0, &stack_len);
+	if (res > (unsigned long)-4096)
+		return res;
+	
+	/* Update data segment pointers for all libraries */
+	for (i=0; i<MAX_SHARED_LIBS; i++)
+		if (libinfo.lib_list[i].loaded)
+			for (j=0; j<MAX_SHARED_LIBS; j++)
+				(-(j+1))[(unsigned long *)(libinfo.lib_list[i].start_data)] =
+					(libinfo.lib_list[j].loaded)?
+						libinfo.lib_list[j].start_data:UNLOADED_LIB;
+
+	compute_creds(bprm);
+ 	current->flags &= ~PF_FORKNOEXEC;
+
+	set_binfmt(&flat_format);
+
+	p = ((current->mm->end_brk + stack_len + 3) & ~3) - 4;
+	DBG_FLT("p=%x\n", (int)p);
+
+	/* copy the arg pages onto the stack, this could be more efficient :-) */
+	for (i = TOP_OF_ARGS - 1; i >= bprm->p; i--)
+		* (char *) --p =
+			((char *) page_address(bprm->page[i/PAGE_SIZE]))[i % PAGE_SIZE];
+
+	sp = (unsigned long *) create_flat_tables(p, bprm);
+	
+	/* Fake some return addresses to ensure the call chain will
+	 * initialise library in order for us.  We are required to call
+	 * lib 1 first, then 2, ... and finally the main program (id 0).
+	 */
+	start_addr = libinfo.lib_list[0].entry;
+
+#ifdef CONFIG_BINFMT_SHARED_FLAT
+	for (i = MAX_SHARED_LIBS-1; i>0; i--) {
+		if (libinfo.lib_list[i].loaded) {
+			/* Push previos first to call address */
+			--sp;	put_user(start_addr, sp);
+			start_addr = libinfo.lib_list[i].entry;
+		}
+	}
+#endif
+	
+	/* Stash our initial stack pointer into the mm structure */
+	current->mm->start_stack = (unsigned long )sp;
+
+	
+	DBG_FLT("start_thread(regs=0x%x, entry=0x%x, start_stack=0x%x)\n",
+		(int)regs, (int)start_addr, (int)current->mm->start_stack);
+	
+	start_thread(regs, start_addr, current->mm->start_stack);
+
+	if (current->ptrace & PT_PTRACED)
+		send_sig(SIGTRAP, current, 0);
+
+	return 0;
+}
+
+/****************************************************************************/
+
+static int __init init_flat_binfmt(void)
+{
+	return register_binfmt(&flat_format);
+}
+
+static void __exit exit_flat_binfmt(void)
+{
+	unregister_binfmt(&flat_format);
+}
+
+/****************************************************************************/
+
+EXPORT_NO_SYMBOLS;
+
+module_init(init_flat_binfmt);
+module_exit(exit_flat_binfmt);
+
+/****************************************************************************/
diff -urN linux-2.4.29/fs/buffer.c linux-2.4.29-uc1/fs/buffer.c
--- linux-2.4.29/fs/buffer.c	2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.29-uc1/fs/buffer.c	2005-06-14 02:11:42.000000000 +0100
@@ -3144,3 +3144,17 @@
 
 module_init(bdflush_init)
 
+#ifdef MAGIC_ROM_PTR
+int bromptr(kdev_t dev, struct vm_area_struct * vma)
+{
+	extern const struct block_device_operations *get_blkfops(unsigned int);
+
+	if (get_blkfops(MAJOR(dev))->romptr!=NULL)
+	{
+		return get_blkfops(MAJOR(dev))->romptr(dev, vma);
+	}
+	return -ENOSYS;
+}
+#endif /* MAGIC_ROM_PTR */
+
+
diff -urN linux-2.4.29/fs/Config.in linux-2.4.29-uc1/fs/Config.in
--- linux-2.4.29/fs/Config.in	2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.29-uc1/fs/Config.in	2005-06-14 02:11:43.000000000 +0100
@@ -171,6 +171,8 @@
    define_tristate CONFIG_ZISOFS_FS n
 fi
 
+bool 'Crazy printk coredump support' CONFIG_COREDUMP_PRINTK
+
 mainmenu_option next_comment
 comment 'Partition Types'
 source fs/partitions/Config.in
diff -urN linux-2.4.29/fs/cramfs/inode.c linux-2.4.29-uc1/fs/cramfs/inode.c
--- linux-2.4.29/fs/cramfs/inode.c	2004-08-08 00:26:05.000000000 +0100
+++ linux-2.4.29-uc1/fs/cramfs/inode.c	2005-06-14 02:11:47.000000000 +0100
@@ -1,13 +1,18 @@
 /*
- * Compressed rom filesystem for Linux.
+ * inode.c
  *
- * Copyright (C) 1999 Linus Torvalds.
+ * Copyright (C) 1999 Linus Torvalds
+ * Copyright (C) 2000-2002 Transmeta Corporation
  *
- * This file is released under the GPL.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * Compressed ROM filesystem for Linux.
  */
 
 /*
- * These are the VFS interfaces to the compressed rom filesystem.
+ * These are the VFS interfaces to the compressed ROM filesystem.
  * The actual compression is based on zlib, see the other files.
  */
 
@@ -39,7 +44,7 @@
 
 /* These two macros may change in future, to provide better st_ino
    semantics. */
-#define CRAMINO(x)	((x)->offset?(x)->offset<<2:1)
+#define CRAMINO(x)	(CRAMFS_GET_OFFSET(x) ? CRAMFS_GET_OFFSET(x)<<2 : 1)
 #define OFFSET(x)	((x)->i_ino)
 
 static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inode * cramfs_inode)
@@ -47,16 +52,16 @@
 	struct inode * inode = new_inode(sb);
 
 	if (inode) {
-		inode->i_mode = cramfs_inode->mode;
-		inode->i_uid = cramfs_inode->uid;
-		inode->i_size = cramfs_inode->size;
-		inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1;
+		inode->i_mode = CRAMFS_16(cramfs_inode->mode);
+		inode->i_uid = CRAMFS_16(cramfs_inode->uid);
+		inode->i_size = CRAMFS_24(cramfs_inode->size);
+		inode->i_blocks = (CRAMFS_24(cramfs_inode->size) - 1)/512 + 1;
 		inode->i_blksize = PAGE_CACHE_SIZE;
 		inode->i_gid = cramfs_inode->gid;
 		inode->i_ino = CRAMINO(cramfs_inode);
 		/* inode->i_nlink is left 1 - arguably wrong for directories,
 		   but it's the best we can do without reading the directory
-	           contents.  1 yields the right result in GNU find, even
+		   contents.  1 yields the right result in GNU find, even
 		   without -noleaf option. */
 		insert_inode_hash(inode);
 		if (S_ISREG(inode->i_mode)) {
@@ -70,7 +75,7 @@
 			inode->i_data.a_ops = &cramfs_aops;
 		} else {
 			inode->i_size = 0;
-			init_special_inode(inode, inode->i_mode, cramfs_inode->size);
+			init_special_inode(inode, inode->i_mode, CRAMFS_24(cramfs_inode->size));
 		}
 	}
 	return inode;
@@ -78,7 +83,7 @@
 
 /*
  * We have our own block cache: don't fill up the buffer cache
- * with the rom-image, because the way the filesystem is set
+ * with the ROM image, because the way the filesystem is set
  * up the accesses should be fairly regular and cached in the
  * page cache and dentry tree anyway..
  *
@@ -211,15 +216,18 @@
 	up(&read_mutex);
 
 	/* Do sanity checks on the superblock */
-	if (super.magic != CRAMFS_MAGIC) {
+	if (super.magic != CRAMFS_32(CRAMFS_MAGIC)) {
 		/* check at 512 byte offset */
 		memcpy(&super, cramfs_read(sb, 512, sizeof(super)), sizeof(super));
-		if (super.magic != CRAMFS_MAGIC) {
+		if (super.magic != CRAMFS_32(CRAMFS_MAGIC)) {
 			printk(KERN_ERR "cramfs: wrong magic\n");
 			goto out;
 		}
 	}
 
+	/* flags is reused several times, so swab it once */
+	super.flags = CRAMFS_32(super.flags);
+
 	/* get feature flags first */
 	if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) {
 		printk(KERN_ERR "cramfs: unsupported filesystem features\n");
@@ -227,22 +235,22 @@
 	}
 
 	/* Check that the root inode is in a sane state */
-	if (!S_ISDIR(super.root.mode)) {
+	if (!S_ISDIR(CRAMFS_16(super.root.mode))) {
 		printk(KERN_ERR "cramfs: root is not a directory\n");
 		goto out;
 	}
-	root_offset = super.root.offset << 2;
+	root_offset = CRAMFS_GET_OFFSET(&(super.root)) << 2;
 	if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) {
-		sb->CRAMFS_SB_SIZE=super.size;
-		sb->CRAMFS_SB_BLOCKS=super.fsid.blocks;
-		sb->CRAMFS_SB_FILES=super.fsid.files;
+		sb->CRAMFS_SB_SIZE = CRAMFS_32(super.size);
+		sb->CRAMFS_SB_BLOCKS = CRAMFS_32(super.fsid.blocks);
+		sb->CRAMFS_SB_FILES = CRAMFS_32(super.fsid.files);
 	} else {
-		sb->CRAMFS_SB_SIZE=1<<28;
-		sb->CRAMFS_SB_BLOCKS=0;
-		sb->CRAMFS_SB_FILES=0;
+		sb->CRAMFS_SB_SIZE = 1 << 28;
+		sb->CRAMFS_SB_BLOCKS = 0;
+		sb->CRAMFS_SB_FILES = 0;
 	}
-	sb->CRAMFS_SB_MAGIC=super.magic;
-	sb->CRAMFS_SB_FLAGS=super.flags;
+	sb->CRAMFS_SB_MAGIC = CRAMFS_MAGIC;
+	sb->CRAMFS_SB_FLAGS = super.flags;
 	if (root_offset == 0)
 		printk(KERN_INFO "cramfs: empty filesystem");
 	else if (!(super.flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) &&
@@ -309,7 +317,7 @@
 		 * and the name padded out to 4-byte boundaries
 		 * with zeroes.
 		 */
-		namelen = de->namelen << 2;
+		namelen = CRAMFS_GET_NAMELEN(de) << 2;
 		nextoffset = offset + sizeof(*de) + namelen;
 		for (;;) {
 			if (!namelen)
@@ -318,7 +326,7 @@
 				break;
 			namelen--;
 		}
-		error = filldir(dirent, name, namelen, offset, CRAMINO(de), de->mode >> 12);
+		error = filldir(dirent, name, namelen, offset, CRAMINO(de), CRAMFS_16(de->mode) >> 12);
 		if (error)
 			break;
 
@@ -351,7 +359,7 @@
 		if (sorted && (dentry->d_name.name[0] < name[0]))
 			break;
 
-		namelen = de->namelen << 2;
+		namelen = CRAMFS_GET_NAMELEN(de) << 2;
 		offset += sizeof(*de) + namelen;
 
 		/* Quick check that the name is roughly the right length */
@@ -398,8 +406,8 @@
 		start_offset = OFFSET(inode) + maxblock*4;
 		down(&read_mutex);
 		if (page->index)
-			start_offset = *(u32 *) cramfs_read(sb, blkptr_offset-4, 4);
-		compr_len = (*(u32 *) cramfs_read(sb, blkptr_offset, 4) - start_offset);
+			start_offset = CRAMFS_32(*(u32 *) cramfs_read(sb, blkptr_offset-4, 4));
+		compr_len = CRAMFS_32(*(u32 *) cramfs_read(sb, blkptr_offset, 4)) - start_offset;
 		up(&read_mutex);
 		pgdata = kmap(page);
 		if (compr_len == 0)
diff -urN linux-2.4.29/fs/cramfs/README linux-2.4.29-uc1/fs/cramfs/README
--- linux-2.4.29/fs/cramfs/README	2002-08-03 01:39:45.000000000 +0100
+++ linux-2.4.29-uc1/fs/cramfs/README	2005-06-14 02:11:47.000000000 +0100
@@ -6,8 +6,8 @@
 swapped around (though it does care that directory entries (inodes) in
 a given directory are contiguous, as this is used by readdir).
 
-All data is currently in host-endian format; neither mkcramfs nor the
-kernel ever do swabbing.  (See section `Block Size' below.)
+All data is in little-endian format; user-space tools and the kernel do
+swabbing on big-endian systems.  (See section `Byte Order' below.)
 
 <filesystem>:
 	<superblock>
@@ -71,6 +71,27 @@
 with -z if you want it to create files that can have holes in them.
 
 
+Byte Order
+----------
+
+When defining the cramfs filesystem, the two options for byte order were
+`always use little-endian' (like ext2fs) or `writer chooses endianness;
+kernel adapts at runtime'.  Little-endian wins because of code
+simplicity and little CPU overhead even on big-endian machines.
+
+While cramfs has always been defined to be little-endian, this
+implementation originally required that cramfs filesystems be written
+and read with architectures of the same endianness; big-endian machines
+would write and read cramfs filesystems with big-endian byte order (the
+"incorrect" byte order for cramfs filesystems).
+
+Now, only little-endian cramfs filesystems are supported for both
+little-endian and big-endian machines.  If you need to support
+big-endian cramfs filesystems for a legacy application on a big-endian
+machine, you could remove the byte-swapping, but it would probably be
+better to write a one-time byte order conversion program.
+
+
 Tools
 -----
 
@@ -108,17 +129,8 @@
 PAGE_CACHE_SIZE is subject to change between kernel versions
 (currently possible with arm and ia64).
 
-The remaining options try to make cramfs more sharable.
-
-One part of that is addressing endianness.  The two options here are
-`always use little-endian' (like ext2fs) or `writer chooses
-endianness; kernel adapts at runtime'.  Little-endian wins because of
-code simplicity and little CPU overhead even on big-endian machines.
-
-The cost of swabbing is changing the code to use the le32_to_cpu
-etc. macros as used by ext2fs.  We don't need to swab the compressed
-data, only the superblock, inodes and block pointers.
-
+The remaining options try to make cramfs more sharable by choosing a
+block size.  The options are:
 
 The other part of making cramfs more sharable is choosing a block
 size.  The options are:
@@ -153,7 +165,6 @@
 will disagree.  (If it is implemented, then I'll re-use that code in
 e2compr.)
 
-
 Another cost of 2 and 3 over 1 is making mkcramfs use a different
 block size, but that just means adding and parsing a -b option.
 
diff -urN linux-2.4.29/fs/cramfs/uncompress.c linux-2.4.29-uc1/fs/cramfs/uncompress.c
--- linux-2.4.29/fs/cramfs/uncompress.c	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-uc1/fs/cramfs/uncompress.c	2005-06-14 02:11:47.000000000 +0100
@@ -1,7 +1,12 @@
 /*
  * uncompress.c
  *
- * (C) Copyright 1999 Linus Torvalds
+ * Copyright (C) 1999 Linus Torvalds
+ * Copyright (C) 2000-2002 Transmeta Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
  *
  * cramfs interfaces to the uncompression library. There's really just
  * three entrypoints:
diff -urN linux-2.4.29/fs/exec.c linux-2.4.29-uc1/fs/exec.c
--- linux-2.4.29/fs/exec.c	2005-01-19 14:10:10.000000000 +0000
+++ linux-2.4.29-uc1/fs/exec.c	2005-06-14 02:11:48.000000000 +0100
@@ -22,6 +22,13 @@
  * formats. 
  */
 
+/*
+ * uClinux revisions for NO_MM
+ *   Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *   Support for 2.4 (C) 2000 Lineo by David McCullough <davidm@lineo.com>
+ *                   (C) 2000-2003 David McCullough <davidm@snapgear.com>
+ */
+
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/file.h>
@@ -43,6 +50,7 @@
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
+#include <asm/page.h>
 
 #ifdef CONFIG_KMOD
 #include <linux/kmod.h>
@@ -284,14 +292,17 @@
  */
 void put_dirty_page(struct task_struct * tsk, struct page *page, unsigned long address)
 {
+#ifndef NO_MM
 	pgd_t * pgd;
 	pmd_t * pmd;
 	pte_t * pte;
 	struct vm_area_struct *vma; 
 	pgprot_t prot = PAGE_COPY; 
+#endif /* NO_MM */
 
 	if (page_count(page) != 1)
 		printk(KERN_ERR "mem_map disagrees with %p at %08lx\n", page, address);
+#ifndef NO_MM
 	pgd = pgd_offset(tsk->mm, address);
 
 	spin_lock(&tsk->mm->page_table_lock);
@@ -320,11 +331,14 @@
 	spin_unlock(&tsk->mm->page_table_lock);
 	__free_page(page);
 	force_sig(SIGKILL, tsk);
+#endif /* NO_MM */
 	return;
 }
 
+
 int setup_arg_pages(struct linux_binprm *bprm)
 {
+#ifndef NO_MM
 	unsigned long stack_base;
 	struct vm_area_struct *mpnt;
 	int i, ret;
@@ -351,6 +365,7 @@
 		mpnt->vm_pgoff = 0;
 		mpnt->vm_file = NULL;
 		mpnt->vm_private_data = (void *) 0;
+		mpnt->vm_sharing_data = NULL;
 		if ((ret = insert_vm_struct(current->mm, mpnt))) {
 			up_write(&current->mm->mmap_sem);
 			kmem_cache_free(vm_area_cachep, mpnt);
@@ -369,6 +384,7 @@
 	}
 	up_write(&current->mm->mmap_sem);
 	
+#endif /* NO_MM */
 	return 0;
 }
 
@@ -449,11 +465,13 @@
 			return -ENOMEM;
 		}
 
+#ifndef NO_MM
 		/* Add it to the list of mm's */
 		spin_lock(&mmlist_lock);
 		list_add(&mm->mmlist, &init_mm.mmlist);
 		mmlist_nr++;
 		spin_unlock(&mmlist_lock);
+#endif /* NO_MM */
 
 		task_lock(current);
 		active_mm = current->active_mm;
@@ -831,6 +849,7 @@
 	}
 }
 
+
 /*
  * cycle the list of binary formats handler, until one recognizes the image
  */
@@ -979,9 +998,13 @@
 		goto out; 
 
 	retval = search_binary_handler(&bprm,regs);
-	if (retval >= 0)
-		/* execve success */
-		return retval;
+	if (retval >= 0) {
+#ifdef NO_MM
+		goto out_ok;
+#else
+		return(retval);
+#endif
+	}
 
 out:
 	/* Something went wrong, return the inode and free the argument pages*/
@@ -989,6 +1012,9 @@
 	if (bprm.file)
 		fput(bprm.file);
 
+#ifdef NO_MM
+out_ok: /* NO_MM needs to free the arg pages always */
+#endif
 	for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
 		struct page * page = bprm.page[i];
 		if (page)
@@ -1124,6 +1150,16 @@
 	*out_ptr = 0;
 }
 
+
+/* for systems with sizeof(void*) == 4: */
+#define MAPS_LINE_FORMAT4	  KERN_ERR "%08lx-%08lx %s %08lx %s %lu %s\n"
+
+/* for systems with sizeof(void*) == 8: */
+#define MAPS_LINE_FORMAT8	  KERN_ERR "%016lx-%016lx %s %016lx %s %lu %s\n"
+
+#define MAPS_LINE_FORMAT	(sizeof(void*) == 4 ? MAPS_LINE_FORMAT4 : MAPS_LINE_FORMAT8)
+
+
 int do_coredump(long signr, struct pt_regs * regs)
 {
 	struct linux_binfmt * binfmt;
@@ -1133,6 +1169,103 @@
 	int retval = 0;
 	int fsuid = current->fsuid;
 
+#if defined(CONFIG_COREDUMP_PRINTK)
+	int32_t *stack=NULL;
+	int lines=0;
+	char output_buf[80];
+	char *output = output_buf;
+	int32_t value = 0;
+
+	printk(KERN_ERR "%s[%d] killed because of sig - %ld", current->comm, 
+			current->pid, signr);
+	/* TODO
+	 * print out mmaps.
+	 */
+
+	/*
+	 * We print out the stack.  We start by pointing the stack before the
+	 * call to do_coredump.  Note that we are assuming the kernel stack is 
+	 * the same as the user stack when we are calling do_coredump.
+	 */
+	printk("\n");
+	printk(KERN_ERR"STACK DUMP:\n");
+	for (lines=0,stack=(int32_t *)user_stack(regs);(lines < 10) && 
+			(stack <= (int32_t *)current->mm->start_stack);lines++) {
+		/* print out the address */
+		output+=snprintf(output, 79-(output-output_buf), "0x%08x: ", 
+				(unsigned)stack);
+		/* now print out the stack contents */
+		for (;(stack <= (int32_t*)current->mm->start_stack) && 
+				(79-(output-output_buf) > sizeof("FFFF0000 "));stack++) {
+			copy_from_user(&value, stack, sizeof(int32_t));
+			output += snprintf(output, 79-(output-output_buf),
+					"%08x ", value);
+		}
+		output--;
+		*output++ = '\n';
+		*output = '\0';
+		printk(KERN_ERR "%s", output_buf);
+		output = output_buf;
+	}
+	show_regs(regs);
+#ifndef NO_MM
+	{
+	struct mm_struct *mm=NULL;
+	struct vm_area_struct *map;
+	char buf[PAGE_SIZE]={0};
+	int flags=0;
+	char *line;
+	kdev_t dev = 0;
+	unsigned long ino = 0;
+
+	mm = current->mm;
+	if (mm) 
+		atomic_inc(&mm->mm_users);
+	if (!mm)
+		goto finished;
+
+	down_read(&mm->mmap_sem);
+	map = mm->mmap;
+
+	while (map) {
+		char str[5];
+
+		if (map->vm_file != NULL) {
+			dev = map->vm_file->f_dentry->d_inode->i_dev;
+			ino = map->vm_file->f_dentry->d_inode->i_ino;
+			line = d_path(map->vm_file->f_dentry,
+			      map->vm_file->f_vfsmnt,
+			      buf, sizeof(buf));
+		} else {
+			line=NULL;
+		}
+
+		flags = map->vm_flags;
+
+		str[0] = flags & VM_READ ? 'r' : '-';
+		str[1] = flags & VM_WRITE ? 'w' : '-';
+		str[2] = flags & VM_EXEC ? 'x' : '-';
+		str[3] = flags & VM_MAYSHARE ? 's' : 'p';
+		str[4] = 0;
+
+		printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end,
+				str,
+				map->vm_pgoff << PAGE_SHIFT,
+				kdevname(dev), ino, line?line:"");
+		map = map->vm_next;
+	}
+	up_read(&mm->mmap_sem);
+	mmput(mm);
+	}
+#else
+	/*
+	 * How do we find base address of shared libs??
+	 */
+#endif
+
+finished:
+#endif
+
 	lock_kernel();
 	binfmt = current->binfmt;
 	if (!binfmt || !binfmt->core_dump)
diff -urN linux-2.4.29/fs/jffs/inode-v23.c linux-2.4.29-uc1/fs/jffs/inode-v23.c
--- linux-2.4.29/fs/jffs/inode-v23.c	2001-10-04 23:14:35.000000000 +0100
+++ linux-2.4.29-uc1/fs/jffs/inode-v23.c	2005-06-14 02:11:43.000000000 +0100
@@ -1722,6 +1722,7 @@
 	struct jffs_control *c = (struct jffs_control *)sb->u.generic_sbp;
 
 	jffs_garbage_collect_trigger(c);
+	sb->s_dirt = 0;
 }
 
 static struct super_operations jffs_ops =
diff -urN linux-2.4.29/fs/jffs/intrep.c linux-2.4.29-uc1/fs/jffs/intrep.c
--- linux-2.4.29/fs/jffs/intrep.c	2003-06-13 15:51:37.000000000 +0100
+++ linux-2.4.29-uc1/fs/jffs/intrep.c	2005-06-14 02:11:43.000000000 +0100
@@ -456,6 +456,7 @@
 	}
 	c->next_ino = JFFS_MIN_INO + 1;
 	c->delete_list = (struct jffs_delete_list *) 0;
+	c->gc_background = 0;
 	return c;
 
 fail_fminit:
@@ -3326,7 +3327,7 @@
 	 * Otherwise, the gc_task could go away between the check
 	 * and the wake_up_process()
 	 */
-	if (c->gc_task && thread_should_wake(c))
+	if (!c->gc_background && c->gc_task && thread_should_wake(c))
 		send_sig(SIGHUP, c->gc_task, 1);
 }
   
@@ -3396,6 +3397,13 @@
 				D1(printk("jffs_garbage_collect_thread(): SIGKILL received.\n"));
 				c->gc_task = NULL;
 				complete_and_exit(&c->gc_thread_comp, 0);
+
+			case SIGHUP:
+				/* Only GC if idle 2 seconds without a trigger */
+				D1(printk("jffs_garbage_collect_thread(): SIGHUP received.\n"));
+				set_current_state(TASK_INTERRUPTIBLE);
+				schedule_timeout(2*HZ);
+				break;
 			}
 		}
 
@@ -3404,6 +3412,7 @@
 
 		D3(printk (KERN_NOTICE "g_c_thread(): down biglock\n"));
 		down(&fmc->biglock);
+		c->gc_background = 1;
 		
 		D1(printk("***jffs_garbage_collect_thread(): round #%u, "
 			  "fmc->dirty_size = %u\n", i++, fmc->dirty_size));
@@ -3433,6 +3442,7 @@
 		}
 		
 	gc_end:
+		c->gc_background = 0;
 		D3(printk (KERN_NOTICE "g_c_thread(): up biglock\n"));
 		up(&fmc->biglock);
 	} /* for (;;) */
diff -urN linux-2.4.29/fs/jffs2/dir.c linux-2.4.29-uc1/fs/jffs2/dir.c
--- linux-2.4.29/fs/jffs2/dir.c	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/fs/jffs2/dir.c	2005-06-14 02:11:44.000000000 +0100
@@ -972,6 +972,11 @@
 	   then getting -ENOSPC, is quite bad :)
 	*/
 
+    if ( new_dentry->d_inode )
+    {
+	  jffs2_unlink(new_dir_i, new_dentry);
+    }
+
 	/* Make a hard link */
 	ret = jffs2_do_link(old_dentry, new_dir_i, new_dentry, 1);
 	if (ret)
diff -urN linux-2.4.29/fs/jffs2/fs.c linux-2.4.29-uc1/fs/jffs2/fs.c
--- linux-2.4.29/fs/jffs2/fs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/fs/jffs2/fs.c	2005-06-14 02:11:44.000000000 +0100
@@ -0,0 +1,351 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2001, 2002 Red Hat, Inc.
+ *
+ * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
+ *
+ * For licensing information, see the file 'LICENCE' in this directory.
+ *
+ * $Id: fs.c,v 1.17 2002/08/21 10:42:12 dwmw2 Exp $
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/mtd.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include "nodelist.h"
+
+int jffs2_statfs(struct super_block *sb, struct statfs *buf)
+{
+	struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
+	unsigned long avail;
+
+	buf->f_type = JFFS2_SUPER_MAGIC;
+	buf->f_bsize = 1 << PAGE_SHIFT;
+	buf->f_blocks = c->flash_size >> PAGE_SHIFT;
+	buf->f_files = 0;
+	buf->f_ffree = 0;
+	buf->f_namelen = JFFS2_MAX_NAME_LEN;
+
+	spin_lock_bh(&c->erase_completion_lock);
+
+	avail = c->dirty_size + c->free_size;
+	if (avail > c->sector_size * JFFS2_RESERVED_BLOCKS_WRITE)
+		avail -= c->sector_size * JFFS2_RESERVED_BLOCKS_WRITE;
+	else
+		avail = 0;
+
+	buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT;
+
+	D1(jffs2_dump_block_lists(c));
+
+	spin_unlock_bh(&c->erase_completion_lock);
+
+	return 0;
+}
+
+
+void jffs2_clear_inode (struct inode *inode)
+{
+	/* We can forget about this inode for now - drop all 
+	 *  the nodelists associated with it, etc.
+	 */
+	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+	
+	D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
+
+	jffs2_do_clear_inode(c, f);
+}
+
+void jffs2_read_inode (struct inode *inode)
+{
+	struct jffs2_inode_info *f;
+	struct jffs2_sb_info *c;
+	struct jffs2_raw_inode latest_node;
+	int ret;
+
+	D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino));
+
+	f = JFFS2_INODE_INFO(inode);
+	c = JFFS2_SB_INFO(inode->i_sb);
+
+	jffs2_init_inode_info(f);
+	
+	ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
+
+	if (ret) {
+		make_bad_inode(inode);
+		up(&f->sem);
+		return;
+	}
+	inode->i_mode = je32_to_cpu(latest_node.mode);
+	inode->i_uid = je16_to_cpu(latest_node.uid);
+	inode->i_gid = je16_to_cpu(latest_node.gid);
+	inode->i_size = je32_to_cpu(latest_node.isize);
+	inode->i_atime = je32_to_cpu(latest_node.atime);
+	inode->i_mtime = je32_to_cpu(latest_node.mtime);
+	inode->i_ctime = je32_to_cpu(latest_node.ctime);
+
+	inode->i_nlink = f->inocache->nlink;
+
+	inode->i_blksize = PAGE_SIZE;
+	inode->i_blocks = (inode->i_size + 511) >> 9;
+	
+	switch (inode->i_mode & S_IFMT) {
+		unsigned short rdev;
+
+	case S_IFLNK:
+		inode->i_op = &jffs2_symlink_inode_operations;
+		break;
+		
+	case S_IFDIR:
+	{
+		struct jffs2_full_dirent *fd;
+
+		for (fd=f->dents; fd; fd = fd->next) {
+			if (fd->type == DT_DIR && fd->ino)
+				inode->i_nlink++;
+		}
+		/* and '..' */
+		inode->i_nlink++;
+		/* Root dir gets i_nlink 3 for some reason */
+		if (inode->i_ino == 1)
+			inode->i_nlink++;
+
+		inode->i_op = &jffs2_dir_inode_operations;
+		inode->i_fop = &jffs2_dir_operations;
+		break;
+	}
+	case S_IFREG:
+		inode->i_op = &jffs2_file_inode_operations;
+		inode->i_fop = &jffs2_file_operations;
+		inode->i_mapping->a_ops = &jffs2_file_address_operations;
+		inode->i_mapping->nrpages = 0;
+		break;
+
+	case S_IFBLK:
+	case S_IFCHR:
+		/* Read the device numbers from the media */
+		D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));
+		if (jffs2_read_dnode(c, f->metadata, (char *)&rdev, 0, sizeof(rdev)) < 0) {
+			/* Eep */
+			printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino);
+			up(&f->sem);
+			jffs2_do_clear_inode(c, f);
+			make_bad_inode(inode);
+			return;
+		}			
+
+	case S_IFSOCK:
+	case S_IFIFO:
+		inode->i_op = &jffs2_file_inode_operations;
+		init_special_inode(inode, inode->i_mode, kdev_t_to_nr(mk_kdev(rdev>>8, rdev&0xff)));
+		break;
+
+	default:
+		printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino);
+	}
+
+	up(&f->sem);
+
+	D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
+}
+
+
+int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
+{
+	struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
+
+	if (c->flags & JFFS2_SB_FLAG_RO && !(sb->s_flags & MS_RDONLY))
+		return -EROFS;
+
+	/* We stop if it was running, then restart if it needs to.
+	   This also catches the case where it was stopped and this
+	   is just a remount to restart it */
+	if (!(sb->s_flags & MS_RDONLY))
+		jffs2_stop_garbage_collect_thread(c);
+
+	if (!(*flags & MS_RDONLY))
+		jffs2_start_garbage_collect_thread(c);
+	
+	sb->s_flags = (sb->s_flags & ~MS_RDONLY)|(*flags & MS_RDONLY);
+
+	return 0;
+}
+
+void jffs2_write_super (struct super_block *sb)
+{
+	struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
+	sb->s_dirt = 0;
+
+	if (sb->s_flags & MS_RDONLY)
+		return;
+
+	D1(printk(KERN_DEBUG "jffs2_write_super()\n"));
+	jffs2_garbage_collect_trigger(c);
+	jffs2_erase_pending_blocks(c);
+	jffs2_mark_erased_blocks(c);
+}
+
+
+/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
+   fill in the raw_inode while you're at it. */
+struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri)
+{
+	struct inode *inode;
+	struct super_block *sb = dir_i->i_sb;
+	struct jffs2_sb_info *c;
+	struct jffs2_inode_info *f;
+	int ret;
+
+	D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode));
+
+	c = JFFS2_SB_INFO(sb);
+	
+	inode = new_inode(sb);
+	
+	if (!inode)
+		return ERR_PTR(-ENOMEM);
+
+	f = JFFS2_INODE_INFO(inode);
+	jffs2_init_inode_info(f);
+
+	memset(ri, 0, sizeof(*ri));
+	/* Set OS-specific defaults for new inodes */
+	ri->uid = cpu_to_je16(current->fsuid);
+
+	if (dir_i->i_mode & S_ISGID) {
+		ri->gid = cpu_to_je16(dir_i->i_gid);
+		if (S_ISDIR(mode))
+			mode |= S_ISGID;
+	} else {
+		ri->gid = cpu_to_je16(current->fsgid);
+	}
+	ri->mode =  cpu_to_je32(mode);
+	ret = jffs2_do_new_inode (c, f, mode, ri);
+	if (ret) {
+		make_bad_inode(inode);
+		iput(inode);
+		return ERR_PTR(ret);
+	}
+	inode->i_nlink = 1;
+	inode->i_ino = je32_to_cpu(ri->ino);
+	inode->i_mode = je32_to_cpu(ri->mode);
+	inode->i_gid = je16_to_cpu(ri->gid);
+	inode->i_uid = je16_to_cpu(ri->uid);
+	inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	ri->atime = ri->mtime = ri->ctime = cpu_to_je32(inode->i_mtime);
+
+	inode->i_blksize = PAGE_SIZE;
+	inode->i_blocks = 0;
+	inode->i_size = 0;
+
+	insert_inode_hash(inode);
+
+	return inode;
+}
+
+
+int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
+{
+	struct jffs2_sb_info *c;
+	struct inode *root_i;
+	int ret;
+
+	c = JFFS2_SB_INFO(sb);
+
+	c->sector_size = c->mtd->erasesize;
+	c->flash_size = c->mtd->size;
+
+#if 0
+	if (c->sector_size < 0x10000) {
+		printk(KERN_INFO "jffs2: Erase block size too small (%dKiB). Using 64KiB instead\n",
+		       c->sector_size / 1024);
+		c->sector_size = 0x10000;
+	}
+#endif
+	if (c->flash_size < 5*c->sector_size) {
+		printk(KERN_ERR "jffs2: Too few erase blocks (%d)\n",
+		       c->flash_size / c->sector_size);
+		return -EINVAL;
+	}
+
+	c->cleanmarker_size = sizeof(struct jffs2_unknown_node);
+	/* Jörn -- stick alignment for weird 8-byte-page flash here */
+
+	if (jffs2_cleanmarker_oob(c)) {
+		/* Cleanmarker is out-of-band, so inline size zero */
+		c->cleanmarker_size = 0;
+	}
+
+	if (c->mtd->type == MTD_NANDFLASH) {
+		/* Initialise write buffer */
+		c->wbuf_pagesize = c->mtd->oobblock;
+		c->wbuf_ofs = 0xFFFFFFFF;
+		c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
+		if (!c->wbuf)
+			return -ENOMEM;
+
+		/* Initialize process for timed wbuf flush */
+		INIT_TQUEUE(&c->wbuf_task,(void*) jffs2_wbuf_process, (void *)c);
+		/* Initialize timer for timed wbuf flush */
+		init_timer(&c->wbuf_timer);
+		c->wbuf_timer.function = jffs2_wbuf_timeout;
+		c->wbuf_timer.data = (unsigned long) c;
+	}
+
+	c->inocache_list = kmalloc(INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *), GFP_KERNEL);
+	if (!c->inocache_list) {
+		ret = -ENOMEM;
+		goto out_wbuf;
+	}
+	memset(c->inocache_list, 0, INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *));
+
+	if ((ret = jffs2_do_mount_fs(c)))
+		goto out_inohash;
+
+	ret = -EINVAL;
+
+	D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n"));
+	root_i = iget(sb, 1);
+	if (is_bad_inode(root_i)) {
+		D1(printk(KERN_WARNING "get root inode failed\n"));
+		goto out_nodes;
+	}
+
+	D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n"));
+	sb->s_root = d_alloc_root(root_i);
+	if (!sb->s_root)
+		goto out_root_i;
+
+#if LINUX_VERSION_CODE >= 0x20403
+	sb->s_maxbytes = 0xFFFFFFFF;
+#endif
+	sb->s_blocksize = PAGE_CACHE_SIZE;
+	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+	sb->s_magic = JFFS2_SUPER_MAGIC;
+	if (!(sb->s_flags & MS_RDONLY))
+		jffs2_start_garbage_collect_thread(c);
+	return 0;
+
+ out_root_i:
+	iput(root_i);
+ out_nodes:
+	jffs2_free_ino_caches(c);
+	jffs2_free_raw_node_refs(c);
+	kfree(c->blocks);
+ out_inohash:
+	kfree(c->inocache_list);
+ out_wbuf:
+	if (c->wbuf)
+		kfree(c->wbuf);
+	return ret;
+}
diff -urN linux-2.4.29/fs/jffs2/GNUmakefile linux-2.4.29-uc1/fs/jffs2/GNUmakefile
--- linux-2.4.29/fs/jffs2/GNUmakefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/fs/jffs2/GNUmakefile	2005-06-14 02:11:44.000000000 +0100
@@ -0,0 +1,49 @@
+# GNUmakefile for JFFS2 build outside kernel tree
+# $Id: GNUmakefile,v 1.1 2002/09/12 00:23:22 davidm Exp $
+
+LINUXDIR=/lib/modules/$(shell uname -r)/build
+
+ifndef VERSION
+# Someone just typed 'make' in this directory.
+# Invoke a kernel build process, with only this dir in SUBDIRS.
+
+modules:
+	$(MAKE) -C $(LINUXDIR) CONFIG_JFFS2_FS_NAND=y SUBDIRS=`pwd` modules
+
+nonand:
+	make -C $(LINUXDIR) SUBDIRS=`pwd` modules
+
+dep:
+	make -C $(LINUXDIR) SUBDIRS=`pwd` dep
+
+clean:
+	rm -f *.o
+
+else
+
+ifndef CONFIG_JFFS2_FS
+# Invoked from a kernel build tree, but CONFIG_JFFS2_FS isn't set. 
+# That means we must have got here from the hack above - pretend
+# CONFIG_JFFS2_FS _was_ set so that we actually build it, and also
+# pull in the local MTD include files in case they're also newer than
+# the ones in the kernel tree. And turn on debugging. 
+
+CC += -I$(shell pwd)/../../include
+
+CONFIG_JFFS2_FS := m
+EXTRA_CFLAGS += -DCONFIG_JFFS2_FS_DEBUG=1 -g -Werror
+
+ifeq ($(CONFIG_JFFS2_FS_NAND),y)
+EXTRA_CFLAGS += -DCONFIG_JFFS2_FS_NAND=1
+endif
+endif
+
+# Check whether we've put the JFFS2 stuff in the superblock and inode unions
+OUT_OF_KERNEL_CFLAGS := $(shell grep -q jffs2 $(TOPDIR)/include/linux/fs.h || echo "-DJFFS2_OUT_OF_KERNEL")
+EXTRA_CFLAGS += $(OUT_OF_KERNEL_CFLAGS)
+
+
+include Makefile
+
+
+endif
diff -urN linux-2.4.29/fs/jffs2/LICENCE linux-2.4.29-uc1/fs/jffs2/LICENCE
--- linux-2.4.29/fs/jffs2/LICENCE	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/fs/jffs2/LICENCE	2005-06-14 02:11:44.000000000 +0100
@@ -0,0 +1,35 @@
+The files in this directory and elsewhere which refer to this LICENCE
+file are part of JFFS2, the Journalling Flash File System v2.
+
+	Copyright (C) 2001, 2002 Red Hat, Inc.
+
+JFFS2 is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 or (at your option) any later 
+version.
+
+JFFS2 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 JFFS2; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+As a special exception, if other files instantiate templates or use
+macros or inline functions from these files, or you compile these
+files and link them with other works to produce a work based on these
+files, these files do not by themselves cause the resulting work to be
+covered by the GNU General Public License. However the source code for
+these files must still be made available in accordance with section (3)
+of the GNU General Public License.
+
+This exception does not invalidate any other reasons why a work based on
+this file might be covered by the GNU General Public License.
+
+For information on obtaining alternative licences for JFFS2, see 
+http://sources.redhat.com/jffs2/jffs2-licence.html
+
+
+	$Id: LICENCE,v 1.1 2002/05/20 14:56:37 dwmw2 Exp $
diff -urN linux-2.4.29/fs/jffs2/os-linux.h linux-2.4.29-uc1/fs/jffs2/os-linux.h
--- linux-2.4.29/fs/jffs2/os-linux.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/fs/jffs2/os-linux.h	2005-06-14 02:11:44.000000000 +0100
@@ -0,0 +1,150 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2002 Red Hat, Inc.
+ *
+ * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
+ *
+ * For licensing information, see the file 'LICENCE' in this directory.
+ *
+ * $Id: os-linux.h,v 1.19 2002/05/20 14:56:38 dwmw2 Exp $
+ *
+ */
+
+#ifndef __JFFS2_OS_LINUX_H__
+#define __JFFS2_OS_LINUX_H__
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
+#define JFFS2_INODE_INFO(i) (list_entry(i, struct jffs2_inode_info, vfs_inode))
+#define OFNI_EDONI_2SFFJ(f)  (&(f)->vfs_inode)
+#define JFFS2_SB_INFO(sb) (sb->u.generic_sbp)
+#define OFNI_BS_2SFFJ(c)  ((struct super_block *)c->os_priv)
+#elif defined(JFFS2_OUT_OF_KERNEL)
+#define JFFS2_INODE_INFO(i) ((struct jffs2_inode_info *) &(i)->u)
+#define OFNI_EDONI_2SFFJ(f)  ((struct inode *) ( ((char *)f) - ((char *)(&((struct inode *)NULL)->u)) ) )
+#define JFFS2_SB_INFO(sb) ((struct jffs2_sb_info *) &(sb)->u)
+#define OFNI_BS_2SFFJ(c)  ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) )
+#else
+#define JFFS2_INODE_INFO(i) (&i->u.jffs2_i)
+#define OFNI_EDONI_2SFFJ(f)  ((struct inode *) ( ((char *)f) - ((char *)(&((struct inode *)NULL)->u)) ) )
+#define JFFS2_SB_INFO(sb) (&sb->u.jffs2_sb)
+#define OFNI_BS_2SFFJ(c)  ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) )
+#endif
+
+
+#define JFFS2_F_I_SIZE(f) (OFNI_EDONI_2SFFJ(f)->i_size)
+#define JFFS2_F_I_MODE(f) (OFNI_EDONI_2SFFJ(f)->i_mode)
+#define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid)
+#define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid)
+#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime)
+#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime)
+#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime)
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,1)
+#define JFFS2_F_I_RDEV_MIN(f) (minor(OFNI_EDONI_2SFFJ(f)->i_rdev))
+#define JFFS2_F_I_RDEV_MAJ(f) (major(OFNI_EDONI_2SFFJ(f)->i_rdev))
+#else
+#define JFFS2_F_I_RDEV_MIN(f) (MINOR(to_kdev_t(OFNI_EDONI_2SFFJ(f)->i_rdev)))
+#define JFFS2_F_I_RDEV_MAJ(f) (MAJOR(to_kdev_t(OFNI_EDONI_2SFFJ(f)->i_rdev)))
+#endif
+
+static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
+	f->highest_version = 0;
+	f->fraglist = NULL;
+	f->metadata = NULL;
+	f->dents = NULL;
+	f->flags = 0;
+	f->usercompr = 0;
+#else
+	memset(f, 0, sizeof(*f));
+	init_MUTEX_LOCKED(&f->sem);
+#endif
+}
+
+#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
+
+#ifndef CONFIG_JFFS2_FS_NAND
+#define jffs2_can_mark_obsolete(c) (1)
+#define jffs2_cleanmarker_oob(c) (0)
+#define jffs2_write_nand_cleanmarker(c,jeb) (-EIO)
+
+#define jffs2_flash_write(c, ofs, len, retlen, buf) ((c)->mtd->write((c)->mtd, ofs, len, retlen, buf))
+#define jffs2_flash_read(c, ofs, len, retlen, buf) ((c)->mtd->read((c)->mtd, ofs, len, retlen, buf))
+#define jffs2_flush_wbuf(c, flag) do { ; } while(0)
+#define jffs2_nand_read_failcnt(c,jeb) do { ; } while(0)
+#define jffs2_write_nand_badblock(c,jeb) do { ; } while(0)
+#define jffs2_flash_writev jffs2_flash_direct_writev
+#define jffs2_wbuf_timeout NULL
+#define jffs2_wbuf_process NULL
+
+#else /* NAND support present */
+
+#define jffs2_can_mark_obsolete(c) (c->mtd->type == MTD_NORFLASH || c->mtd->type == MTD_RAM)
+#define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH)
+
+#define jffs2_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf))
+#define jffs2_flash_read_oob(c, ofs, len, retlen, buf) ((c)->mtd->read_oob((c)->mtd, ofs, len, retlen, buf))
+
+
+/* wbuf.c */
+int jffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen);
+int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, const u_char *buf);
+int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, u_char *buf);
+int jffs2_check_oob_empty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,int mode);
+int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
+int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
+int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
+void jffs2_wbuf_timeout(unsigned long data);
+void jffs2_wbuf_process(void *data);
+#endif /* NAND */
+
+/* background.c */
+int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c);
+void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c);
+void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c);
+
+/* dir.c */
+extern struct file_operations jffs2_dir_operations;
+extern struct inode_operations jffs2_dir_inode_operations;
+
+/* file.c */
+extern struct file_operations jffs2_file_operations;
+extern struct inode_operations jffs2_file_inode_operations;
+extern struct address_space_operations jffs2_file_address_operations;
+int jffs2_fsync(struct file *, struct dentry *, int);
+int jffs2_setattr (struct dentry *dentry, struct iattr *iattr);
+int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg);
+int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg);
+int jffs2_readpage (struct file *, struct page *);
+int jffs2_prepare_write (struct file *, struct page *, unsigned, unsigned);
+int jffs2_commit_write (struct file *, struct page *, unsigned, unsigned);
+
+/* ioctl.c */
+int jffs2_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+
+/* symlink.c */
+extern struct inode_operations jffs2_symlink_inode_operations;
+
+/* fs.c */
+void jffs2_read_inode (struct inode *);
+void jffs2_clear_inode (struct inode *);
+struct inode *jffs2_new_inode (struct inode *dir_i, int mode,
+			       struct jffs2_raw_inode *ri);
+int jffs2_statfs (struct super_block *, struct statfs *);
+void jffs2_write_super (struct super_block *);
+int jffs2_remount_fs (struct super_block *, int *, char *);
+int jffs2_do_fill_super(struct super_block *sb, void *data, int silent);
+
+/* writev.c */
+int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct iovec *vecs, 
+		       unsigned long count, loff_t to, size_t *retlen);
+
+/* super.c */
+
+
+#endif /* __JFFS2_OS_LINUX_H__ */
+
+
diff -urN linux-2.4.29/fs/jffs2/README.Locking linux-2.4.29-uc1/fs/jffs2/README.Locking
--- linux-2.4.29/fs/jffs2/README.Locking	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/fs/jffs2/README.Locking	2005-06-14 02:11:44.000000000 +0100
@@ -0,0 +1,116 @@
+	$Id: README.Locking,v 1.4 2002/03/08 16:20:06 dwmw2 Exp $
+
+	JFFS2 LOCKING DOCUMENTATION
+	---------------------------
+
+At least theoretically, JFFS2 does not require the Big Kernel Lock
+(BKL), which was always helpfully obtained for it by Linux 2.4 VFS
+code. It has its own locking, as described below.
+
+This document attempts to describe the existing locking rules for
+JFFS2. It is not expected to remain perfectly up to date, but ought to
+be fairly close.
+
+
+	alloc_sem
+	---------
+
+The alloc_sem is a per-filesystem semaphore, used primarily to ensure
+contiguous allocation of space on the medium. It is automatically
+obtained during space allocations (jffs2_reserve_space()) and freed
+upon write completion (jffs2_complete_reservation()). Note that
+the garbage collector will obtain this right at the beginning of
+jffs2_garbage_collect_pass() and release it at the end, thereby
+preventing any other write activity on the file system during a
+garbage collect pass.
+
+When writing new nodes, the alloc_sem must be held until the new nodes
+have been properly linked into the data structures for the inode to
+which they belong. This is for the benefit of NAND flash - adding new
+nodes to an inode may obsolete old ones, and by holding the alloc_sem
+until this happens we ensure that any data in the write-buffer at the
+time this happens are part of the new node, not just something that
+was written afterwards. Hence, we can ensure the newly-obsoleted nodes
+don't actually get erased until the write-buffer has been flushed to
+the medium.
+
+With the introduction of NAND flash support and the write-buffer, 
+the alloc_sem is also used to protect the wbuf-related members of the
+jffs2_sb_info structure. Atomically reading the wbuf_len member to see
+if the wbuf is currently holding any data is permitted, though.
+
+Ordering constraints: See f->sem.
+
+
+	File Semaphore f->sem
+	---------------------
+
+This is the JFFS2-internal equivalent of the inode semaphore i->i_sem.
+It protects the contents of the jffs2_inode_info private inode data,
+including the linked list of node fragments (but see the notes below on
+erase_completion_lock), etc.
+
+The reason that the i_sem itself isn't used for this purpose is to
+avoid deadlocks with garbage collection -- the VFS will lock the i_sem
+before calling a function which may need to allocate space. The
+allocation may trigger garbage-collection, which may need to move a
+node belonging to the inode which was locked in the first place by the
+VFS. If the garbage collection code were to attempt to lock the i_sem
+of the inode from which it's garbage-collecting a physical node, this
+lead to deadlock, unless we played games with unlocking the i_sem
+before calling the space allocation functions.
+
+Instead of playing such games, we just have an extra internal
+semaphore, which is obtained by the garbage collection code and also
+by the normal file system code _after_ allocation of space.
+
+Ordering constraints: 
+
+	1. Never attempt to allocate space or lock alloc_sem with 
+	   any f->sem held.
+	2. Never attempt to lock two file semaphores in one thread.
+	   No ordering rules have been made for doing so.
+
+
+	erase_completion_lock spinlock
+	------------------------------
+
+This is used to serialise access to the eraseblock lists, to the
+per-eraseblock lists of physical jffs2_raw_node_ref structures, and
+(NB) the per-inode list of physical nodes. The latter is a special
+case - see below.
+
+As the MTD API permits erase-completion callback functions to be
+called from bottom-half (timer) context, and these functions access
+the data structures protected by this lock, it must be locked with
+spin_lock_bh().
+
+Note that the per-inode list of physical nodes (f->nodes) is a special
+case. Any changes to _valid_ nodes (i.e. ->flash_offset & 1 == 0) in
+the list are protected by the file semaphore f->sem. But the erase
+code may remove _obsolete_ nodes from the list while holding only the
+erase_completion_lock. So you can walk the list only while holding the
+erase_completion_lock, and can drop the lock temporarily mid-walk as
+long as the pointer you're holding is to a _valid_ node, not an
+obsolete one.
+
+The erase_completion_lock is also used to protect the c->gc_task
+pointer when the garbage collection thread exits. The code to kill the
+GC thread locks it, sends the signal, then unlocks it - while the GC
+thread itself locks it, zeroes c->gc_task, then unlocks on the exit path.
+
+	node_free_sem
+	-------------
+
+This semaphore is only used by the erase code which frees obsolete
+node references and the jffs2_garbage_collect_deletion_dirent()
+function. The latter function on NAND flash must read _obsolete_ nodes
+to determine whether the 'deletion dirent' under consideration can be
+discarded or whether it is still required to show that an inode has
+been unlinked. Because reading from the flash may sleep, the
+erase_completion_lock cannot be held, so an alternative, more
+heavyweight lock was required to prevent the erase code from freeing
+the jffs2_raw_node_ref structures in question while the garbage
+collection code is looking at them.
+
+Suggestions for alternative solutions to this problem would be welcomed.
diff -urN linux-2.4.29/fs/jffs2/super-v24.c linux-2.4.29-uc1/fs/jffs2/super-v24.c
--- linux-2.4.29/fs/jffs2/super-v24.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/fs/jffs2/super-v24.c	2005-06-14 02:11:44.000000000 +0100
@@ -0,0 +1,161 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2001, 2002 Red Hat, Inc.
+ *
+ * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
+ *
+ * For licensing information, see the file 'LICENCE' in this directory.
+ *
+ * $Id: super-v24.c,v 1.63 2002/05/20 14:56:39 dwmw2 Exp $
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/fs.h>
+#include <linux/jffs2.h>
+#include <linux/pagemap.h>
+#include <linux/mtd/mtd.h>
+#include <linux/interrupt.h>
+#include "nodelist.h"
+
+#ifndef MTD_BLOCK_MAJOR
+#define MTD_BLOCK_MAJOR 31
+#endif
+
+void jffs2_put_super (struct super_block *);
+
+static struct super_operations jffs2_super_operations =
+{
+	read_inode:	jffs2_read_inode,
+	put_super:	jffs2_put_super,
+	write_super:	jffs2_write_super,
+	statfs:		jffs2_statfs,
+	remount_fs:	jffs2_remount_fs,
+	clear_inode:	jffs2_clear_inode
+};
+
+
+static struct super_block *jffs2_read_super(struct super_block *sb, void *data, int silent)
+{
+	struct jffs2_sb_info *c;
+	int ret;
+
+	D1(printk(KERN_DEBUG "jffs2: read_super for device %s\n", kdevname(sb->s_dev)));
+
+	if (major(sb->s_dev) != MTD_BLOCK_MAJOR) {
+		if (!silent)
+			printk(KERN_DEBUG "jffs2: attempt to mount non-MTD device %s\n", kdevname(sb->s_dev));
+		return NULL;
+	}
+
+	c = JFFS2_SB_INFO(sb);
+	memset(c, 0, sizeof(*c));
+
+	sb->s_op = &jffs2_super_operations;
+
+	c->mtd = get_mtd_device(NULL, minor(sb->s_dev));
+	if (!c->mtd) {
+		D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", minor(sb->s_dev)));
+		return NULL;
+	}
+
+	ret = jffs2_do_fill_super(sb, data, silent);
+	if (ret) {
+		put_mtd_device(c->mtd);
+		return NULL;
+	}
+
+	return sb;
+}
+
+void jffs2_put_super (struct super_block *sb)
+{
+	struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
+
+	D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n"));
+
+
+	if (!(sb->s_flags & MS_RDONLY))
+		jffs2_stop_garbage_collect_thread(c);
+	down(&c->alloc_sem);
+	jffs2_flush_wbuf(c, 1);
+	up(&c->alloc_sem);
+	jffs2_free_ino_caches(c);
+	jffs2_free_raw_node_refs(c);
+	kfree(c->blocks);
+	if (c->mtd->sync)
+		c->mtd->sync(c->mtd);
+	put_mtd_device(c->mtd);
+	
+	D1(printk(KERN_DEBUG "jffs2_put_super returning\n"));
+}
+
+static DECLARE_FSTYPE_DEV(jffs2_fs_type, "jffs2", jffs2_read_super);
+
+static int __init init_jffs2_fs(void)
+{
+	int ret;
+
+	printk(KERN_NOTICE "JFFS2 version 2.1. (C) 2001, 2002 Red Hat, Inc., designed by Axis Communications AB.\n");
+
+#ifdef JFFS2_OUT_OF_KERNEL
+	/* sanity checks. Could we do these at compile time? */
+	if (sizeof(struct jffs2_sb_info) > sizeof (((struct super_block *)NULL)->u)) {
+		printk(KERN_ERR "JFFS2 error: struct jffs2_sb_info (%d bytes) doesn't fit in the super_block union (%d bytes)\n", 
+		       sizeof(struct jffs2_sb_info), sizeof (((struct super_block *)NULL)->u));
+		return -EIO;
+	}
+
+	if (sizeof(struct jffs2_inode_info) > sizeof (((struct inode *)NULL)->u)) {
+		printk(KERN_ERR "JFFS2 error: struct jffs2_inode_info (%d bytes) doesn't fit in the inode union (%d bytes)\n", 
+		       sizeof(struct jffs2_inode_info), sizeof (((struct inode *)NULL)->u));
+		return -EIO;
+	}
+#endif
+	ret = jffs2_zlib_init();
+	if (ret) {
+		printk(KERN_ERR "JFFS2 error: Failed to initialise zlib workspaces\n");
+		goto out;
+	}
+	ret = jffs2_create_slab_caches();
+	if (ret) {
+		printk(KERN_ERR "JFFS2 error: Failed to initialise slab caches\n");
+		goto out_zlib;
+	}
+	ret = register_filesystem(&jffs2_fs_type);
+	if (ret) {
+		printk(KERN_ERR "JFFS2 error: Failed to register filesystem\n");
+		goto out_slab;
+	}
+	return 0;
+
+ out_slab:
+	jffs2_destroy_slab_caches();
+ out_zlib:
+	jffs2_zlib_exit();
+ out:
+
+	return ret;
+}
+
+static void __exit exit_jffs2_fs(void)
+{
+	jffs2_destroy_slab_caches();
+	jffs2_zlib_exit();
+	unregister_filesystem(&jffs2_fs_type);
+}
+
+module_init(init_jffs2_fs);
+module_exit(exit_jffs2_fs);
+
+MODULE_DESCRIPTION("The Journalling Flash File System, v2");
+MODULE_AUTHOR("Red Hat, Inc.");
+MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for 
+		       // the sake of this tag. It's Free Software.
diff -urN linux-2.4.29/fs/jffs2/wbuf.c linux-2.4.29-uc1/fs/jffs2/wbuf.c
--- linux-2.4.29/fs/jffs2/wbuf.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/fs/jffs2/wbuf.c	2005-06-14 02:11:44.000000000 +0100
@@ -0,0 +1,755 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2001, 2002 Red Hat, Inc.
+ *
+ * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
+ *
+ * For licensing information, see the file 'LICENCE' in this directory.
+ *
+ * $Id: wbuf.c,v 1.18 2002/09/10 06:35:48 gleixner Exp $
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mtd/mtd.h>
+#include <linux/interrupt.h>
+#include <linux/crc32.h>
+#include <linux/mtd/nand.h>
+#include "nodelist.h"
+
+/* max. erase failures before we mark a block bad */
+#define MAX_ERASE_FAILURES 	5
+
+/* two seconds timeout for timed wbuf-flushing */
+#define WBUF_FLUSH_TIMEOUT	2 * HZ
+
+static inline void jffs2_refile_wbuf_blocks(struct jffs2_sb_info *c)
+{
+	struct list_head *this, *next;
+	static int n;
+
+	if (list_empty(&c->erasable_pending_wbuf_list))
+		return;
+
+	list_for_each_safe(this, next, &c->erasable_pending_wbuf_list) {
+		struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
+
+		D1(printk(KERN_DEBUG "Removing eraseblock at 0x%08x from erasable_pending_wbuf_list...\n", jeb->offset));
+		list_del(this);
+		if ((jiffies + (n++)) & 127) {
+			/* Most of the time, we just erase it immediately. Otherwise we
+			   spend ages scanning it on mount, etc. */
+			D1(printk(KERN_DEBUG "...and adding to erase_pending_list\n"));
+			list_add_tail(&jeb->list, &c->erase_pending_list);
+			c->nr_erasing_blocks++;
+			jffs2_erase_pending_trigger(c);
+		} else {
+			/* Sometimes, however, we leave it elsewhere so it doesn't get
+			   immediately reused, and we spread the load a bit. */
+			D1(printk(KERN_DEBUG "...and adding to erasable_list\n"));
+			list_add_tail(&jeb->list, &c->erasable_list);
+		}
+	}
+}
+
+/* 
+*	Timed flushing of wbuf. If we have no consecutive write to wbuf, within	
+*	the specified time, we flush the contents with padding !
+*/
+void jffs2_wbuf_timeout (unsigned long data)
+{
+	struct jffs2_sb_info *c = (struct jffs2_sb_info *) data;
+	/* 
+	* Wake up the flush process, we need process context to have the right 
+	* to sleep on flash write
+	*/
+	D1(printk(KERN_DEBUG "jffs2_wbuf_timeout(): timer expired\n"));
+	schedule_task(&c->wbuf_task);
+}
+
+/*
+*	Process for timed wbuf flush
+*
+*	FIXME What happens, if we have a write failure there ????
+*/
+void jffs2_wbuf_process (void *data)
+{
+	struct jffs2_sb_info *c = (struct jffs2_sb_info *) data;	
+	
+	D1(printk(KERN_DEBUG "jffs2_wbuf_process() entered\n"));
+	
+	/* Check, if the timer is active again */
+	if (timer_pending (&c->wbuf_timer)) {
+		D1(printk (KERN_DEBUG "Nothing to do, timer is active again\n"));
+		return;
+	}
+
+	if (down_trylock(&c->alloc_sem)) {
+		/* If someone else has the alloc_sem, they're about to
+		   write anyway. So no need to waste space by
+		   padding */
+		D1(printk (KERN_DEBUG "jffs2_wbuf_process() alloc_sem already occupied\n"));
+		return;
+	}	
+
+	D1(printk (KERN_DEBUG "jffs2_wbuf_process() alloc_sem got\n"));
+
+	if (!c->nextblock) {
+		D1(printk(KERN_DEBUG "jffs2_wbuf_process(): nextblock NULL, nothing to do\n"));
+		if (c->wbuf_len) {
+			printk(KERN_WARNING "jffs2_wbuf_process(): c->wbuf_len is 0x%03x but nextblock is NULL!\n", c->wbuf_len);
+			up(&c->alloc_sem);
+			BUG();
+		}
+		return;
+	}
+	
+	
+	/* if !c->nextblock then the tail will have got flushed from
+	   jffs2_do_reserve_space() anyway. */
+	if(c->nextblock)
+		jffs2_flush_wbuf(c, 2); /* pad and adjust nextblock */
+
+	up(&c->alloc_sem);
+}
+
+
+/* Meaning of pad argument:
+   0: Do not pad. Probably pointless - we only ever use this when we can't pad anyway.
+   1: Pad, do not adjust nextblock free_size
+   2: Pad, adjust nextblock free_size
+*/
+int jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
+{
+	int ret;
+	size_t retlen;
+	
+	if (!down_trylock(&c->alloc_sem)) {
+		up(&c->alloc_sem);
+		printk(KERN_CRIT "jffs2_flush_wbuf() called with alloc_sem not locked!\n");
+		BUG();
+	}
+
+	/* delete a eventually started timed wbuf flush */
+	del_timer_sync(&c->wbuf_timer);
+
+	if(!c->wbuf || !c->wbuf_len)
+		return 0;
+
+	/* claim remaining space on the page
+	   this happens, if we have a change to a new block,
+	   or if fsync forces us to flush the writebuffer.
+	   if we have a switch to next page, we will not have
+	   enough remaining space for this. 
+	*/
+	if (pad) {
+		c->wbuf_len = PAD(c->wbuf_len);
+		
+		if ( c->wbuf_len + sizeof(struct jffs2_unknown_node) < c->wbuf_pagesize) {
+			struct jffs2_unknown_node *padnode = (void *)(c->wbuf + c->wbuf_len);
+			padnode->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
+			padnode->nodetype = cpu_to_je16(JFFS2_NODETYPE_PADDING);
+			padnode->totlen = cpu_to_je32(c->wbuf_pagesize - c->wbuf_len);
+			padnode->hdr_crc = cpu_to_je32(crc32(0, padnode, sizeof(*padnode)-4));
+		}
+	}
+	/* else jffs2_flash_writev has actually filled in the rest of the
+	   buffer for us, and will deal with the node refs etc. later. */
+	
+	ret = c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf, NULL, NAND_JFFS2_OOB);
+	
+	if (ret || retlen != c->wbuf_pagesize) {
+		if (ret)
+			printk(KERN_CRIT "jffs2_flush_wbuf(): Write failed with %d\n",ret);
+		else
+			printk(KERN_CRIT "jffs2_flush_wbuf(): Write was short %d instead of %d\n",retlen,c->wbuf_pagesize);
+			
+		ret = -EIO;		
+		/* CHECKME NAND 
+		   So that the caller knows what happened. If
+		   we were called from jffs2_flash_writev(), it'll
+		   know to return failure and _its_ caller will
+		   try again. writev gives back to jffs2_write_xxx 
+		   in write.c. There are the real fixme's
+		 */
+
+		/*  FIXME NAND
+		   If we were called from GC or fsync, there's no repair kit yet
+		*/
+		    
+		return ret; 
+	}
+
+	/* Adjusting free size of next block only, if it's called from fsync ! */
+	if (pad == 2) {
+		D1(printk(KERN_DEBUG "jffs2_flush_wbuf() adjusting free_size of c->nextblock\n"));
+		spin_lock_bh(&c->erase_completion_lock);
+		if (!c->nextblock)
+			BUG();
+		/* wbuf_pagesize - wbuf_len is the amount of space that's to be 
+		   padded. If there is less free space in the block than that,
+		   something screwed up */
+		if (c->nextblock->free_size < (c->wbuf_pagesize - c->wbuf_len)) {
+			printk(KERN_CRIT "jffs2_flush_wbuf(): Accounting error. wbuf at 0x%08x has 0x%03x bytes, 0x%03x left.\n",
+			       c->wbuf_ofs, c->wbuf_len, c->wbuf_pagesize-c->wbuf_len);
+			printk(KERN_CRIT "jffs2_flush_wbuf(): But free_size for block at 0x%08x is only 0x%08x\n",
+			       c->nextblock->offset, c->nextblock->free_size);
+			BUG();
+		}
+		c->nextblock->free_size -= (c->wbuf_pagesize - c->wbuf_len);
+		c->free_size -= (c->wbuf_pagesize - c->wbuf_len);
+		c->nextblock->wasted_size += (c->wbuf_pagesize - c->wbuf_len);
+		c->wasted_size += (c->wbuf_pagesize - c->wbuf_len);
+		spin_unlock_bh(&c->erase_completion_lock);
+	}
+
+	/* Stick any now-obsoleted blocks on the erase_pending_list */
+	spin_lock_bh(&c->erase_completion_lock);
+	jffs2_refile_wbuf_blocks(c);
+	spin_unlock_bh(&c->erase_completion_lock);
+
+	memset(c->wbuf,0xff,c->wbuf_pagesize);
+	/* adjust write buffer offset, else we get a non contigous write bug */
+	c->wbuf_ofs+= c->wbuf_pagesize;
+	c->wbuf_len = 0;
+	return 0;
+}
+
+#define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) )
+#define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) )
+int jffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *invecs, unsigned long count, loff_t to, size_t *retlen)
+{
+	struct iovec outvecs[3];
+	uint32_t totlen = 0;
+	uint32_t split_ofs = 0;
+	uint32_t old_totlen;
+	int ret, splitvec = -1;
+	int invec, outvec;
+	size_t wbuf_retlen;
+	unsigned char *wbuf_ptr;
+	size_t donelen = 0;
+	uint32_t outvec_to = to;
+
+	/* If not NAND flash, don't bother */
+	if (!c->wbuf)
+		return jffs2_flash_direct_writev(c, invecs, count, to, retlen);
+	
+	/* If wbuf_ofs is not initialized, set it to target adress */
+	if (c->wbuf_ofs == 0xFFFFFFFF) {
+		c->wbuf_ofs = PAGE_DIV(to);
+		c->wbuf_len = PAGE_MOD(to);			
+		memset(c->wbuf,0xff,c->wbuf_pagesize);
+	}
+
+	/* Sanity checks on target address. 
+	   It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs), 
+	   and it's permitted to write at the beginning of a new 
+	   erase block. Anything else, and you die.
+	   New block starts at xxx000c (0-b = block header)
+	*/
+	if ( (to & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) {
+		/* It's a write to a new block */
+		if (c->wbuf_len) {
+			D1(printk(KERN_DEBUG "jffs2_flash_writev() to 0x%lx causes flush of wbuf at 0x%08x\n", (unsigned long)to, c->wbuf_ofs));
+			ret = jffs2_flush_wbuf(c, 1);
+			if (ret) {
+				/* the underlying layer has to check wbuf_len to do the cleanup */
+				D1(printk(KERN_WARNING "jffs2_flush_wbuf() called from jffs2_flash_writev() failed %d\n", ret));
+				*retlen = 0;
+				return ret;
+			}
+		}
+		/* set pointer to new block */
+		c->wbuf_ofs = PAGE_DIV(to);
+		c->wbuf_len = PAGE_MOD(to);			
+	} 
+
+	if (to != PAD(c->wbuf_ofs + c->wbuf_len)) {
+		/* We're not writing immediately after the writebuffer. Bad. */
+		printk(KERN_CRIT "jffs2_flash_writev(): Non-contiguous write to %08lx\n", (unsigned long)to);
+		if (c->wbuf_len)
+			printk(KERN_CRIT "wbuf was previously %08x-%08x\n",
+					  c->wbuf_ofs, c->wbuf_ofs+c->wbuf_len);
+		BUG();
+	}
+
+	/* Note outvecs[3] above. We know count is never greater than 2 */
+	if (count > 2) {
+		printk(KERN_CRIT "jffs2_flash_writev(): count is %ld\n", count);
+		BUG();
+	}
+
+	invec = 0;
+	outvec = 0;
+
+
+	/* Fill writebuffer first, if already in use */	
+	if (c->wbuf_len) {
+		uint32_t invec_ofs = 0;
+
+		/* adjust alignment offset */ 
+		if (c->wbuf_len != PAGE_MOD(to)) {
+			c->wbuf_len = PAGE_MOD(to);
+			/* take care of alignment to next page */
+			if (!c->wbuf_len)
+				c->wbuf_len = c->wbuf_pagesize;
+		}
+		
+		while(c->wbuf_len < c->wbuf_pagesize) {
+			uint32_t thislen;
+			
+			if (invec == count)
+				goto alldone;
+
+			thislen = c->wbuf_pagesize - c->wbuf_len;
+
+			if (thislen >= invecs[invec].iov_len)
+				thislen = invecs[invec].iov_len;
+	
+			invec_ofs = thislen;
+
+			memcpy(c->wbuf + c->wbuf_len, invecs[invec].iov_base, thislen);
+			c->wbuf_len += thislen;
+			donelen += thislen;
+			/* Get next invec, if actual did not fill the buffer */
+			if (c->wbuf_len < c->wbuf_pagesize) 
+				invec++;
+		}			
+		
+		/* write buffer is full, flush buffer */
+		ret = jffs2_flush_wbuf(c, 0);
+		if (ret) {
+			/* the underlying layer has to check wbuf_len to do the cleanup */
+			D1(printk(KERN_WARNING "jffs2_flush_wbuf() called from jffs2_flash_writev() failed %d\n", ret));
+			*retlen = 0;
+			return ret;
+		}
+		outvec_to += donelen;
+		c->wbuf_ofs = outvec_to;
+		
+		/* All invecs done ? */
+		if (invec == count)
+			goto alldone;
+
+		/* Set up the first outvec, containing the remainder of the
+		   invec we partially used */
+		if (invecs[invec].iov_len > invec_ofs) {
+			outvecs[0].iov_base = invecs[invec].iov_base+invec_ofs;
+			totlen = outvecs[0].iov_len = invecs[invec].iov_len-invec_ofs;
+			if (totlen > c->wbuf_pagesize) {
+				splitvec = outvec;
+				split_ofs = outvecs[0].iov_len - PAGE_MOD(totlen);
+			}
+			outvec++;
+		}
+		invec++;
+	}
+
+	/* OK, now we've flushed the wbuf and the start of the bits
+	   we have been asked to write, now to write the rest.... */
+
+	/* totlen holds the amount of data still to be written */
+	old_totlen = totlen;
+	for ( ; invec < count; invec++,outvec++ ) {
+		outvecs[outvec].iov_base = invecs[invec].iov_base;
+		totlen += outvecs[outvec].iov_len = invecs[invec].iov_len;
+		if (PAGE_DIV(totlen) != PAGE_DIV(old_totlen)) {
+			splitvec = outvec;
+			split_ofs = outvecs[outvec].iov_len - PAGE_MOD(totlen);
+			old_totlen = totlen;
+		}
+	}
+
+	/* Now the outvecs array holds all the remaining data to write */
+	/* Up to splitvec,split_ofs is to be written immediately. The rest
+	   goes into the (now-empty) wbuf */
+
+	if (splitvec != -1) {
+		uint32_t remainder;
+		int ret;
+
+		remainder = outvecs[splitvec].iov_len - split_ofs;
+		outvecs[splitvec].iov_len = split_ofs;
+
+		/* We did cross a page boundary, so we write some now */
+		ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, NAND_JFFS2_OOB); 
+		if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) {
+			/* At this point we have no problem,
+			   c->wbuf is empty. 
+			*/
+			*retlen = donelen;
+			return ret;
+		}
+		
+		donelen += wbuf_retlen;
+		c->wbuf_ofs = PAGE_DIV(outvec_to) + PAGE_DIV(totlen);
+
+		if (remainder) {
+			outvecs[splitvec].iov_base += split_ofs;
+			outvecs[splitvec].iov_len = remainder;
+		} else {
+			splitvec++;
+		}
+
+	} else {
+		splitvec = 0;
+	}
+
+	/* Now splitvec points to the start of the bits we have to copy
+	   into the wbuf */
+	wbuf_ptr = c->wbuf;
+
+	for ( ; splitvec < outvec; splitvec++) {
+		/* Don't copy the wbuf into itself */
+		if (outvecs[splitvec].iov_base == c->wbuf)
+			continue;
+		memcpy(wbuf_ptr, outvecs[splitvec].iov_base, outvecs[splitvec].iov_len);
+		wbuf_ptr += outvecs[splitvec].iov_len;
+		donelen += outvecs[splitvec].iov_len;
+	}
+	c->wbuf_len = wbuf_ptr - c->wbuf;
+
+alldone:	
+	*retlen = donelen;
+	/* Setup timed wbuf flush, if buffer len != 0 */
+	if (c->wbuf_len) {
+		D1(printk (KERN_DEBUG "jffs2_flash_writev: mod wbuf_timer\n"));	
+		mod_timer(&c->wbuf_timer, jiffies + WBUF_FLUSH_TIMEOUT);
+	}
+	return 0;
+}
+
+/*
+	This is the entry for NOR-Flash. We use it also for NAND to flush wbuf
+*/
+int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, const u_char *buf)
+{
+	return c->mtd->write(c->mtd, ofs, len, retlen, buf);
+}
+
+/*
+	Handle readback from writebuffer and ECC failure return
+*/
+int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, u_char *buf)
+{
+	loff_t	orbf = 0, owbf = 0, lwbf = 0;
+	int	ret;
+
+	/* Read flash */
+	if (!jffs2_can_mark_obsolete(c)) {
+		ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, NAND_JFFS2_OOB);
+
+		if ( (ret == -EIO) && (*retlen == len) ) {
+			printk(KERN_WARNING "mtd->read(0x%x bytes from 0x%llx) returned ECC error\n", len, ofs);
+			/* 
+			 * We have the raw data without ECC correction in the buffer, maybe 
+			 * we are lucky and all data or parts are correct. We check the node.
+			 * If data are corrupted node check will sort it out.
+			 * We keep this block, it will fail on write or erase and the we
+			 * mark it bad. Or should we do that now? But we should give him a chance.
+			 * Maybe we had a system crash or power loss before the ecc write or  
+			 * a erase was completed.
+			 * So we return success. :)
+			 */
+		 	ret = 0;
+		 }	
+	} else
+		return c->mtd->read(c->mtd, ofs, len, retlen, buf);
+
+	/* if no writebuffer available or write buffer empty, return */
+	if (!c->wbuf_pagesize || !c->wbuf_len)
+		return ret;
+
+	/* if we read in a different block, return */
+	if ( (ofs & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) 
+		return ret;	
+
+	if (ofs >= c->wbuf_ofs) {
+		owbf = (ofs - c->wbuf_ofs);	/* offset in write buffer */
+		if (owbf > c->wbuf_len)		/* is read beyond write buffer ? */
+			return ret;
+		lwbf = c->wbuf_len - owbf;	/* number of bytes to copy */
+		if (lwbf > len)	
+			lwbf = len;
+	} else {	
+		orbf = (c->wbuf_ofs - ofs);	/* offset in read buffer */
+		if (orbf > len)			/* is write beyond write buffer ? */
+			return ret;
+		lwbf = len - orbf; 		/* number of bytes to copy */
+		if (lwbf > c->wbuf_len)	
+			lwbf = c->wbuf_len;
+	}	
+	if (lwbf > 0)
+		memcpy(buf+orbf,c->wbuf+owbf,lwbf);
+
+	return ret;
+}
+
+/*
+ *	Check, if the out of band area is empty
+ */
+int jffs2_check_oob_empty( struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, int mode)
+{
+	unsigned char *buf;
+	int 	ret = 0;
+	int	i,len,cnt,page;
+	size_t  retlen;
+	int	fsdata_pos,badblock_pos,oob_size;
+
+	oob_size = c->mtd->oobsize;
+
+	switch(c->mtd->ecctype) {
+	case MTD_ECC_SW:		
+		fsdata_pos = (c->wbuf_pagesize == 256) ? NAND_JFFS2_OOB8_FSDAPOS : NAND_JFFS2_OOB16_FSDAPOS;
+		badblock_pos = NAND_BADBLOCK_POS;
+		break;
+	default:
+		D1(printk(KERN_WARNING "jffs2_write_oob_empty(): Invalid ECC type\n"));
+		return -EINVAL;
+	}	
+
+	/* allocate a buffer for all oob data in this sector */
+	len = 4 * oob_size;
+	buf = kmalloc(len, GFP_KERNEL);
+	if (!buf) {
+		printk(KERN_NOTICE "jffs2_check_oob_empty(): allocation of temporary data buffer for oob check failed\n");
+		return -ENOMEM;
+	}
+	/* 
+	 * if mode = 0, we scan for a total empty oob area, else we have
+	 * to take care of the cleanmarker in the first page of the block
+	*/
+	ret = jffs2_flash_read_oob(c, jeb->offset, len , &retlen, buf);
+	if (ret) {
+		D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB failed %d for block at %08x\n", ret, jeb->offset));
+		goto out;
+	}
+	
+	if (retlen < len) {
+		D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB return short read "
+			  "(%d bytes not %d) for block at %08x\n", retlen, len, jeb->offset));
+		ret = -EIO;
+		goto out;
+	}
+	
+	/* Special check for first two pages */
+	for (page = 0; page < 2 * oob_size; page += oob_size) {
+		/* Check for bad block marker */
+		if (buf[page+badblock_pos] != 0xff) {
+			D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Bad or failed block at %08x\n",jeb->offset));
+			/* Return 2 for bad and 3 for failed block 
+			   bad goes to list_bad and failed to list_erase */
+			ret = (!page) ? 2 : 3;
+			goto out;
+		}
+		cnt = oob_size;
+		if (mode)
+			cnt -= fsdata_pos;
+		for(i = 0; i < cnt ; i+=sizeof(unsigned short)) {
+			unsigned short dat = *(unsigned short *)(&buf[page+i]);
+			if(dat != 0xffff) {
+				ret = 1; 
+				goto out;
+			}
+		}
+		/* only the first page can contain a cleanmarker !*/
+		mode = 0;
+	}	
+
+	/* we know, we are aligned :) */	
+	for (; page < len; page += sizeof(long)) {
+		unsigned long dat = *(unsigned long *)(&buf[page]);
+		if(dat != -1) {
+			ret = 1; 
+			goto out;
+		}
+	}
+
+out:
+	kfree(buf);	
+	
+	return ret;
+}
+
+int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
+{
+	struct jffs2_unknown_node n;
+	unsigned char buf[32];
+	unsigned char *p;
+	int ret,i;
+	size_t retlen;
+	int	fsdata_pos,fsdata_len, oob_size, badblock_pos;
+
+	oob_size = c->mtd->oobsize;
+
+	switch(c->mtd->ecctype) {
+	case MTD_ECC_SW:	
+		fsdata_pos = (c->wbuf_pagesize == 256) ? NAND_JFFS2_OOB8_FSDAPOS : NAND_JFFS2_OOB16_FSDAPOS;
+		fsdata_len = (c->wbuf_pagesize == 256) ? NAND_JFFS2_OOB8_FSDALEN : NAND_JFFS2_OOB16_FSDALEN;
+		badblock_pos = NAND_BADBLOCK_POS;
+		break;
+	default:
+		D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Invalid ECC type\n"));
+		return -EINVAL;
+	}	
+
+	/*
+	*	We read oob data from page 0 and 1 of the block.
+	*	page 0 contains cleanmarker and badblock info
+	*	page 2 contains failure count of this block
+	*/
+	ret = c->mtd->read_oob(c->mtd, jeb->offset, oob_size << 1 , &retlen, buf);
+	
+	if (ret) {
+		D1(printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB failed %d for block at %08x\n", ret, jeb->offset));
+		return ret;
+	}
+	if (retlen < (oob_size << 1) ) {
+		D1(printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB return short read (%d bytes not %d) for block at %08x\n", retlen, oob_size << 1 , jeb->offset));
+		return -EIO;
+	}
+
+	/* Check for bad block marker */
+	if (buf[badblock_pos] != 0xff) {
+		D1(printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Bad block at %08x\n",jeb->offset));
+		return 2;
+	}
+
+	/* Check for failure counter in the second page */
+	if (buf[badblock_pos+oob_size] != 0xff) {
+		D1(printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Block marked as failed at %08x, fail count:%d\n",jeb->offset,buf[badblock_pos+oob_size]));
+		return 3;
+	}
+
+	n.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
+	n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
+	n.totlen = cpu_to_je32(8);
+	p = (unsigned char *) &n;
+	
+	for (i = 0; i < fsdata_len; i++) {
+		if (buf[fsdata_pos+i] != p[i]) {
+			D2(printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Cleanmarker node not detected in block at %08x\n", jeb->offset));
+			return 1;
+		}
+	}
+	
+	return 0;
+}
+
+int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
+{
+	struct 	jffs2_unknown_node n;
+	int 	ret;
+	int	fsdata_pos,fsdata_len;
+	size_t 	retlen;
+
+	switch(c->mtd->ecctype) {
+	case MTD_ECC_SW:	
+		fsdata_pos = (c->wbuf_pagesize == 256) ? NAND_JFFS2_OOB8_FSDAPOS : NAND_JFFS2_OOB16_FSDAPOS;
+		fsdata_len = (c->wbuf_pagesize == 256) ? NAND_JFFS2_OOB8_FSDALEN : NAND_JFFS2_OOB16_FSDALEN;
+		break;
+	default:
+		D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Invalid ECC type\n"));
+		return -EINVAL;
+	}	
+	
+	n.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
+	n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
+	n.totlen = cpu_to_je32(8);
+
+	ret = jffs2_flash_write_oob(c, jeb->offset + fsdata_pos, fsdata_len, &retlen, (unsigned char *)&n);
+	
+	if (ret) {
+		D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Write failed for block at %08x: error %d\n", jeb->offset, ret));
+		return ret;
+	}
+	if (retlen != fsdata_len) {
+		D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Short write for block at %08x: %d not %d\n", jeb->offset, retlen, fsdata_len));
+		return ret;
+	}
+	return 0;
+}
+
+/* 
+ * We try to get the failure count of this block.
+ */
+int jffs2_nand_read_failcnt(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) {
+
+	unsigned char buf[16];
+	int	ret;
+	size_t 	retlen;
+	int	oob_size, badblock_pos;
+
+	oob_size = c->mtd->oobsize;
+
+	switch(c->mtd->ecctype) {
+	case MTD_ECC_SW:	
+		badblock_pos = NAND_BADBLOCK_POS;
+		break;
+	default:
+		D1(printk(KERN_WARNING "jffs2_nand_read_failcnt(): Invalid ECC type\n"));
+		return -EINVAL;
+	}	
+	
+	ret = c->mtd->read_oob(c->mtd, jeb->offset + c->mtd->oobblock, oob_size , &retlen, buf);
+	
+	if (ret) {
+		D1(printk(KERN_WARNING "jffs2_nand_read_failcnt(): Read OOB failed %d for block at %08x\n", ret, jeb->offset));
+		return ret;
+	}
+
+	if (retlen < oob_size) {
+		D1(printk(KERN_WARNING "jffs2_nand_read_failcnt(): Read OOB return short read (%d bytes not %d) for block at %08x\n", retlen, oob_size, jeb->offset));
+		return -EIO;
+	}
+
+	jeb->bad_count =  buf[badblock_pos];	
+	return 0;
+}
+
+/* 
+ * On NAND we try to mark this block bad. We try to write how often
+ * the block was erased and mark it finaly bad, if the count
+ * is > MAX_ERASE_FAILURES. We read this information on mount !
+ * jeb->bad_count contains the count before this erase.
+ * Don't care about failures. This block remains on the erase-pending
+ * or badblock list as long as nobody manipulates the flash with
+ * a bootloader or something like that.
+ */
+
+int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
+{
+	unsigned char buf = 0x0;
+	int 	ret,pos;
+	size_t 	retlen;
+
+	switch(c->mtd->ecctype) {
+	case MTD_ECC_SW:	
+		pos = NAND_BADBLOCK_POS;
+		break;
+	default:
+		D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Invalid ECC type\n"));
+		return -EINVAL;
+	}	
+
+	/* if the count is < max, we try to write the counter to the 2nd page oob area */
+	if( ++jeb->bad_count < MAX_ERASE_FAILURES) {
+		buf = (unsigned char)jeb->bad_count;
+		pos += c->mtd->oobblock;
+	}
+	
+	ret = jffs2_flash_write_oob(c, jeb->offset + pos, 1, &retlen, &buf);
+	
+	if (ret) {
+		D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Write failed for block at %08x: error %d\n", jeb->offset, ret));
+		return ret;
+	}
+	if (retlen != 1) {
+		D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Short write for block at %08x: %d not 1\n", jeb->offset, retlen));
+		return ret;
+	}
+	return 0;
+}
+
diff -urN linux-2.4.29/fs/jffs2/writev.c linux-2.4.29-uc1/fs/jffs2/writev.c
--- linux-2.4.29/fs/jffs2/writev.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/fs/jffs2/writev.c	2005-06-14 02:11:44.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2001, 2002 Red Hat, Inc.
+ *
+ * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
+ *
+ * For licensing information, see the file 'LICENCE' in this directory.
+ *
+ * $Id: writev.c,v 1.3 2002/08/08 08:35:21 dwmw2 Exp $
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/mtd/mtd.h>
+#include "nodelist.h"
+
+/* This ought to be in core MTD code. All registered MTD devices
+   without writev should have this put in place. Bug the MTD
+   maintainer */
+static inline int mtd_fake_writev(struct mtd_info *mtd, const struct iovec *vecs,
+				  unsigned long count, loff_t to, size_t *retlen)
+{
+	unsigned long i;
+	size_t totlen = 0, thislen;
+	int ret = 0;
+
+	for (i=0; i<count; i++) {
+		if (!vecs[i].iov_len)
+			continue;
+		ret = mtd->write(mtd, to, vecs[i].iov_len, &thislen, vecs[i].iov_base);
+		totlen += thislen;
+		if (ret || thislen != vecs[i].iov_len)
+			break;
+		to += vecs[i].iov_len;
+	}
+	if (retlen)
+		*retlen = totlen;
+	return ret;
+}
+
+int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct iovec *vecs,
+			      unsigned long count, loff_t to, size_t *retlen)
+{
+	if (c->mtd->writev)
+		return c->mtd->writev(c->mtd, vecs, count, to, retlen);
+	else
+		return mtd_fake_writev(c->mtd, vecs, count, to, retlen);
+}
+
diff -urN linux-2.4.29/fs/locks.c linux-2.4.29-uc1/fs/locks.c
--- linux-2.4.29/fs/locks.c	2004-04-14 14:05:40.000000000 +0100
+++ linux-2.4.29-uc1/fs/locks.c	2005-06-14 02:11:43.000000000 +0100
@@ -115,6 +115,11 @@
  *  Stephen Rothwell <sfr@canb.auug.org.au>, June, 2000.
  */
 
+/*
+ * uClinux revisions for NO_MM
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ */
+
 #include <linux/slab.h>
 #include <linux/file.h>
 #include <linux/smp_lock.h>
@@ -1507,6 +1512,7 @@
 	error = -EINVAL;
 	inode = filp->f_dentry->d_inode;
 
+#ifndef NO_MM
 	/* Don't allow mandatory locks on files that may be memory mapped
 	 * and shared.
 	 */
@@ -1519,6 +1525,7 @@
 			goto out_putf;
 		}
 	}
+#endif /* !NO_MM */
 
 	error = flock_to_posix_lock(filp, file_lock, &flock);
 	if (error)
@@ -1663,6 +1670,7 @@
 	error = -EINVAL;
 	inode = filp->f_dentry->d_inode;
 
+#ifndef NO_MM
 	/* Don't allow mandatory locks on files that may be memory mapped
 	 * and shared.
 	 */
@@ -1675,6 +1683,7 @@
 			goto out_putf;
 		}
 	}
+#endif /* NO_MM */
 
 	error = flock64_to_posix_lock(filp, file_lock, &flock);
 	if (error)
diff -urN linux-2.4.29/fs/Makefile linux-2.4.29-uc1/fs/Makefile
--- linux-2.4.29/fs/Makefile	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/fs/Makefile	2005-06-14 02:11:44.000000000 +0100
@@ -76,6 +76,7 @@
 obj-y				+= binfmt_script.o
 
 obj-$(CONFIG_BINFMT_ELF)	+= binfmt_elf.o
+obj-$(CONFIG_BINFMT_FLAT)	+= binfmt_flat.o
 
 # persistent filesystems
 obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
diff -urN linux-2.4.29/fs/namei.c linux-2.4.29-uc1/fs/namei.c
--- linux-2.4.29/fs/namei.c	2005-01-19 14:10:11.000000000 +0000
+++ linux-2.4.29-uc1/fs/namei.c	2005-06-14 02:11:44.000000000 +0100
@@ -104,13 +104,15 @@
 static inline int do_getname(const char *filename, char *page)
 {
 	int retval;
-	unsigned long len = PATH_MAX;
+	volatile unsigned long len = PATH_MAX;
 
+#ifndef NO_MM
 	if ((unsigned long) filename >= TASK_SIZE) {
 		if (!segment_eq(get_fs(), KERNEL_DS))
 			return -EFAULT;
 	} else if (TASK_SIZE - (unsigned long) filename < PATH_MAX)
 		len = TASK_SIZE - (unsigned long) filename;
+#endif
 
 	retval = strncpy_from_user((char *)page, filename, len);
 	if (retval > 0) {
diff -urN linux-2.4.29/fs/nfs/nfs2xdr.c linux-2.4.29-uc1/fs/nfs/nfs2xdr.c
--- linux-2.4.29/fs/nfs/nfs2xdr.c	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-uc1/fs/nfs/nfs2xdr.c	2005-06-14 02:11:46.000000000 +0100
@@ -454,6 +454,8 @@
 u32 *
 nfs_decode_dirent(u32 *p, struct nfs_entry *entry, int plus)
 {
+	volatile u64 tmp; /* bug in m68k-elf requires this tmp : DAVIDM */
+
 	if (!*p++) {
 		if (!*p)
 			return ERR_PTR(-EAGAIN);
@@ -466,7 +468,8 @@
 	entry->name	  = (const char *) p;
 	p		 += XDR_QUADLEN(entry->len);
 	entry->prev_cookie	  = entry->cookie;
-	entry->cookie	  = ntohl(*p++);
+	tmp		  = ntohl(*p++); /* m68k-elf bug avoidance : DAVIDM */
+	entry->cookie	  = tmp;
 	entry->eof	  = !p[0] && p[1];
 
 	return p;
diff -urN linux-2.4.29/fs/partitions/check.c linux-2.4.29-uc1/fs/partitions/check.c
--- linux-2.4.29/fs/partitions/check.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-uc1/fs/partitions/check.c	2005-06-14 02:11:47.000000000 +0100
@@ -124,6 +124,8 @@
 	 * IDE devices use multiple major numbers, but the drives
 	 * are named as:  {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}..
 	 * This requires special handling here.
+	 *
+	 * MD devices are named md0, md1, ... md15, fix it up here.
 	 */
 	switch (hd->major) {
 		case IDE9_MAJOR:
@@ -207,7 +209,7 @@
 void add_gd_partition(struct gendisk *hd, int minor, int start, int size)
 {
 #ifndef CONFIG_DEVFS_FS
-	char buf[40];
+	char buf[MAX_DISKNAME_LEN];
 #endif
 
 	hd->part[minor].start_sect = start;
@@ -229,7 +231,7 @@
 	static int first_time = 1;
 	unsigned long first_sector;
 	struct block_device *bdev;
-	char buf[64];
+	char buf[MAX_DISKNAME_LEN];
 	int i;
 
 	if (first_time)
diff -urN linux-2.4.29/fs/partitions/Config.in linux-2.4.29-uc1/fs/partitions/Config.in
--- linux-2.4.29/fs/partitions/Config.in	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-uc1/fs/partitions/Config.in	2005-06-14 02:11:47.000000000 +0100
@@ -39,6 +39,7 @@
    fi
    if [ "$CONFIG_AMIGA" != "y" -a "$CONFIG_ATARI" != "y" -a \
         "$CONFIG_MAC" != "y" -a "$CONFIG_SGI_IP22" != "y" -a \
+        "$CONFIG_UCLINUX" != "y" -a "$CONFIG_SH_SNAPGEAR" != "y" -a \
 	"$CONFIG_SGI_IP27" != "y" ]; then
       define_bool CONFIG_MSDOS_PARTITION y
    fi
diff -urN linux-2.4.29/fs/proc/array.c linux-2.4.29-uc1/fs/proc/array.c
--- linux-2.4.29/fs/proc/array.c	2005-01-19 14:10:11.000000000 +0000
+++ linux-2.4.29-uc1/fs/proc/array.c	2005-06-14 02:11:46.000000000 +0100
@@ -50,6 +50,8 @@
  * Al Viro & Jeff Garzik :  moved most of the thing into base.c and
  *			 :  proc_misc.c. The rest may eventually go into
  *			 :  base.c too.
+ *
+ * David McCullough  :  added NO_MM support <davidm@snapgear.com>
  */
 
 #include <linux/config.h>
@@ -182,6 +184,7 @@
 
 static inline char * task_mem(struct mm_struct *mm, char *buffer)
 {
+#ifndef NO_MM
 	struct vm_area_struct * vma;
 	unsigned long data = 0, stack = 0;
 	unsigned long exec = 0, lib = 0;
@@ -218,6 +221,54 @@
 		data - stack, stack,
 		exec - lib, lib);
 	up_read(&mm->mmap_sem);
+#else
+	unsigned long bytes = 0, sbytes = 0, slack = 0;
+	struct mm_tblock_struct * tblock;
+        
+	/* Logic: we've got two memory sums for each process, "shared", and
+	 * "non-shared". Shared memory may get counted more then once, for
+	 * each process that owns it. Non-shared memory is counted
+	 * accurately.
+	 *
+	 *	-- Kenneth Albanowski
+	 */
+
+	down_read(&mm->mmap_sem);
+	for (tblock = &mm->tblock; tblock; tblock = tblock->next) {
+		if (tblock->rblock) {
+			bytes += ksize(tblock);
+			if (atomic_read(&mm->mm_count) > 1 ||
+					tblock->rblock->refcount > 1) {
+				sbytes += ksize(tblock->rblock->kblock);
+				sbytes += ksize(tblock->rblock) ;
+			} else {
+				bytes += ksize(tblock->rblock->kblock);
+				bytes += ksize(tblock->rblock) ;
+				slack += ksize(tblock->rblock->kblock) - tblock->rblock->size;
+			}
+		}
+	}
+	
+	((atomic_read(&mm->mm_count) > 1) ? sbytes : bytes)
+			+= ksize(mm);
+	(current->fs && atomic_read(&current->fs->count) > 1 ? sbytes : bytes)
+			+= ksize(current->fs);
+	(current->files && atomic_read(&current->files->count) > 1 ? sbytes : bytes)
+			+= ksize(current->files);
+	(current->sig && atomic_read(&current->sig->count) > 1 ? sbytes : bytes)
+			+= ksize(current->sig);
+	bytes += ksize(current); /* includes kernel stack */
+
+	buffer += sprintf(buffer,
+		"Mem:\t%8lu bytes\n"
+		"Slack:\t%8lu bytes\n"
+		"Shared:\t%8lu bytes\n",
+		bytes,
+		slack,
+		sbytes);
+
+	up_read(&mm->mmap_sem);
+#endif
 	return buffer;
 }
 
@@ -325,13 +376,28 @@
 	}
 	task_unlock(task);
 	if (mm) {
+#ifndef NO_MM
 		struct vm_area_struct *vma;
+#endif
 		down_read(&mm->mmap_sem);
+#ifndef NO_MM
 		vma = mm->mmap;
 		while (vma) {
 			vsize += vma->vm_end - vma->vm_start;
 			vma = vma->vm_next;
 		}
+#else /* !NO_MM */
+		vsize = 0;
+		{
+			struct mm_tblock_struct *tbp = &mm->tblock;
+
+			while (tbp) {
+				if (tbp->rblock)
+					vsize += ksize(tbp->rblock->kblock);
+				tbp = tbp->next;
+			}
+		}
+#endif /* !NO_MM */
 		eip = KSTK_EIP(task);
 		esp = KSTK_ESP(task);
 		up_read(&mm->mmap_sem);
@@ -403,6 +469,8 @@
 	return res;
 }
 		
+#ifndef NO_MM
+
 static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned long size,
 	int * pages, int * shared, int * dirty, int * total)
 {
@@ -478,6 +546,8 @@
 	}
 }
 
+#endif /* !NO_MM */
+
 int proc_pid_statm(struct task_struct *task, char * buffer)
 {
 	struct mm_struct *mm;
@@ -489,8 +559,11 @@
 		atomic_inc(&mm->mm_users);
 	task_unlock(task);
 	if (mm) {
+#ifndef NO_MM
 		struct vm_area_struct * vma;
+#endif
 		down_read(&mm->mmap_sem);
+#ifndef NO_MM
 		vma = mm->mmap;
 		while (vma) {
 			pgd_t *pgd = pgd_offset(mm, vma->vm_start);
@@ -511,6 +584,39 @@
 				drs += pages;
 			vma = vma->vm_next;
 		}
+#else /* !NO_MM */
+		/* DAVIDM - may be able to clean this up a bit */
+		{
+			struct mm_tblock_struct *tbp = &mm->tblock;
+
+			size += ksize(mm);
+			while (tbp) {
+				if (tbp->next)
+					size += ksize(tbp->next);
+				if (tbp->rblock) {
+					size += ksize(tbp->rblock);
+					size += ksize(tbp->rblock->kblock);
+					if (atomic_read(&mm->mm_count) > 1 ||
+							(tbp->rblock->refcount > 1))
+						share += tbp->rblock->size;
+				}
+				tbp = tbp->next;
+			}
+
+			size += (trs = mm->end_code - mm->start_code);
+			size += (drs = mm->start_stack - mm->start_data);
+			dt  = 0;
+			lrs = 0;
+			resident = size;
+
+			/* User programs expect the units to be pages. */
+			size = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+			resident = (resident + PAGE_SIZE - 1) >> PAGE_SHIFT;
+			share = (share + PAGE_SIZE - 1) >> PAGE_SHIFT;
+			trs = (trs + PAGE_SIZE - 1) >> PAGE_SHIFT;
+			drs = (drs + PAGE_SIZE - 1) >> PAGE_SHIFT;
+		}
+#endif /* !NO_MM */
 		up_read(&mm->mmap_sem);
 		mmput(mm);
 	}
@@ -520,6 +626,7 @@
 
 static int show_map(struct seq_file *m, void *v)
 {
+#ifndef NO_MM
 	struct vm_area_struct *map = v;
 	struct file *file = map->vm_file;
 	int flags = map->vm_flags;
@@ -551,11 +658,13 @@
 		seq_path(m, file->f_vfsmnt, file->f_dentry, "");
 	}
 	seq_putc(m, '\n');
+#endif /* NO_MM */
 	return 0;
 }
 
 static void *m_start(struct seq_file *m, loff_t *pos)
 {
+#ifndef NO_MM
 	struct task_struct *task = m->private;
 	struct mm_struct *mm;
 	struct vm_area_struct * map;
@@ -579,25 +688,32 @@
 		mmput(mm);
 	}
 	return map;
+#else
+	return NULL; /* DAVIDM - can we do this */
+#endif
 }
 
 static void m_stop(struct seq_file *m, void *v)
 {
+#ifndef NO_MM
 	struct vm_area_struct *map = v;
 	if (map) {
 		struct mm_struct *mm = map->vm_mm;
 		up_read(&mm->mmap_sem);
 		mmput(mm);
 	}
+#endif
 }
 
 static void *m_next(struct seq_file *m, void *v, loff_t *pos)
 {
+#ifndef NO_MM
 	struct vm_area_struct *map = v;
 	(*pos)++;
 	if (map->vm_next)
 		return map->vm_next;
 	m_stop(m, v);
+#endif
 	return NULL;
 }
 
diff -urN linux-2.4.29/fs/proc/base.c linux-2.4.29-uc1/fs/proc/base.c
--- linux-2.4.29/fs/proc/base.c	2005-01-19 14:10:11.000000000 +0000
+++ linux-2.4.29-uc1/fs/proc/base.c	2005-06-14 02:11:46.000000000 +0100
@@ -53,9 +53,10 @@
 
 static int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
 {
+	int result = -ENOENT;
+#ifndef NO_MM /* DAVIDM - Some other time */
 	struct mm_struct * mm;
 	struct vm_area_struct * vma;
-	int result = -ENOENT;
 	struct task_struct *task = inode->u.proc_i.task;
 
 	task_lock(task);
@@ -80,6 +81,7 @@
 	up_read(&mm->mmap_sem);
 	mmput(mm);
 out:
+#endif /* !NO_MM */
 	return result;
 }
 
diff -urN linux-2.4.29/fs/proc/kcore.c linux-2.4.29-uc1/fs/proc/kcore.c
--- linux-2.4.29/fs/proc/kcore.c	2004-08-08 00:26:06.000000000 +0100
+++ linux-2.4.29-uc1/fs/proc/kcore.c	2005-06-14 02:11:46.000000000 +0100
@@ -118,11 +118,19 @@
 
 static unsigned long get_kcore_size(int *num_vma, size_t *elf_buflen)
 {
-	unsigned long try, size;
+	unsigned long size;
+#ifndef NO_MM
+	unsigned long try;
 	struct vm_struct *m;
+#endif
 
 	*num_vma = 0;
 	size = ((size_t)high_memory - PAGE_OFFSET + PAGE_SIZE);
+#ifdef NO_MM
+	/* vmlist is not available then */
+	*elf_buflen = PAGE_SIZE;
+	return size;
+#else
 	if (!vmlist) {
 		*elf_buflen = PAGE_SIZE;
 		return (size);
@@ -139,6 +147,7 @@
 			3 * sizeof(struct memelfnote);
 	*elf_buflen = PAGE_ALIGN(*elf_buflen);
 	return (size - PAGE_OFFSET + *elf_buflen);
+#endif
 }
 
 
@@ -196,7 +205,9 @@
 	struct elfhdr *elf;
 	struct memelfnote notes[3];
 	off_t offset = 0;
+#ifndef NO_MM
 	struct vm_struct *m;
+#endif
 
 	/* setup ELF header */
 	elf = (struct elfhdr *) bufp;
@@ -247,6 +258,7 @@
 	phdr->p_filesz	= phdr->p_memsz = ((unsigned long)high_memory - PAGE_OFFSET);
 	phdr->p_align	= PAGE_SIZE;
 
+#ifndef NO_MM
 	/* setup ELF PT_LOAD program header for every vmalloc'd area */
 	for (m=vmlist; m; m=m->next) {
 		if (m->flags & VM_IOREMAP) /* don't dump ioremap'd stuff! (TA) */
@@ -264,6 +276,7 @@
 		phdr->p_filesz	= phdr->p_memsz	= m->size;
 		phdr->p_align	= PAGE_SIZE;
 	}
+#endif /* NO_MM */
 
 	/*
 	 * Set up the notes in similar form to SVR4 core dumps made
@@ -322,12 +335,16 @@
 	int num_vma;
 	unsigned long start;
 
+#ifdef NO_MM
+	proc_root_kcore->size = size = get_kcore_size(&num_vma, &elf_buflen);
+#else
 	read_lock(&vmlist_lock);
 	proc_root_kcore->size = size = get_kcore_size(&num_vma, &elf_buflen);
 	if (buflen == 0 || (unsigned long long)*fpos >= size) {
 		read_unlock(&vmlist_lock);
 		return 0;
 	}
+#endif /* NO_MM */
 
 	/* trim buflen to not go beyond EOF */
 	if (buflen > size - *fpos)
@@ -404,6 +421,7 @@
 				err = clear_user(buffer, tsz);
 			}
 		} else {
+#ifndef NO_MM
 			char * elf_buf;
 			struct vm_struct *m;
 			unsigned long curstart = start;
@@ -445,6 +463,7 @@
 			read_unlock(&vmlist_lock);
 			err = copy_to_user(buffer, elf_buf, tsz); 
 				kfree(elf_buf);
+#endif /* NO_MM */
 			}
 		if (err)
 					return -EFAULT;
diff -urN linux-2.4.29/fs/proc/proc_misc.c linux-2.4.29-uc1/fs/proc/proc_misc.c
--- linux-2.4.29/fs/proc/proc_misc.c	2004-08-08 00:26:06.000000000 +0100
+++ linux-2.4.29-uc1/fs/proc/proc_misc.c	2005-06-14 02:11:46.000000000 +0100
@@ -185,8 +185,10 @@
 		"MemFree:      %8lu kB\n"
 		"MemShared:    %8lu kB\n"
 		"Buffers:      %8lu kB\n"
+#ifndef NO_MM
 		"Cached:       %8lu kB\n"
 		"SwapCached:   %8lu kB\n"
+#endif /* NO_MM */
 		"Active:       %8u kB\n"
 		"Inactive:     %8u kB\n"
 		"HighTotal:    %8lu kB\n"
@@ -199,8 +201,10 @@
 		K(i.freeram),
 		K(i.sharedram),
 		K(i.bufferram),
+#ifndef NO_MM
 		K(pg_size - swapper_space.nrpages),
 		K(swapper_space.nrpages),
+#endif /* NO_MM */
 		K(nr_active_pages),
 		K(nr_inactive_pages),
 		K(i.totalhigh),
diff -urN linux-2.4.29/fs/romfs/inode.c linux-2.4.29-uc1/fs/romfs/inode.c
--- linux-2.4.29/fs/romfs/inode.c	2002-02-25 19:38:09.000000000 +0000
+++ linux-2.4.29-uc1/fs/romfs/inode.c	2005-06-14 02:11:47.000000000 +0100
@@ -433,6 +433,20 @@
 	return result;
 }
 
+#ifdef MAGIC_ROM_PTR
+static int
+romfs_romptr(struct file * filp, struct vm_area_struct * vma)
+{
+	struct inode * inode = filp->f_dentry->d_inode;
+	vma->vm_offset += inode->u.romfs_i.i_dataoffset;
+
+	if ((vma->vm_flags & VM_WRITE) || bromptr(inode->i_dev, vma))
+		return -ENOSYS;
+
+	return 0;
+}
+#endif
+
 /* Mapping from our types to the kernel */
 
 static struct address_space_operations romfs_aops = {
@@ -444,6 +458,14 @@
 	readdir:	romfs_readdir,
 };
 
+struct file_operations romfs_file_operations = {
+	read:		generic_file_read,
+	mmap:		generic_file_mmap,
+#ifdef MAGIC_ROM_PTR
+	romptr:		romfs_romptr,
+#endif
+};
+
 static struct inode_operations romfs_dir_inode_operations = {
 	lookup:		romfs_lookup,
 };
@@ -462,7 +484,6 @@
 
 	ino = i->i_ino & ROMFH_MASK;
 	i->i_mode = 0;
-
 	/* Loop for finding the real hard link */
 	for(;;) {
 		if (romfs_copyfrom(i, &ri, ino, ROMFH_SIZE) <= 0) {
@@ -506,7 +527,7 @@
 			i->i_mode = ino;
 			break;
 		case 2:
-			i->i_fop = &generic_ro_fops;
+			i->i_fop = &romfs_file_operations;
 			i->i_data.a_ops = &romfs_aops;
 			if (nextfh & ROMFH_EXEC)
 				ino |= S_IXUGO;
diff -urN linux-2.4.29/fs/stat.c linux-2.4.29-uc1/fs/stat.c
--- linux-2.4.29/fs/stat.c	2004-08-08 00:26:06.000000000 +0100
+++ linux-2.4.29-uc1/fs/stat.c	2005-06-14 02:11:47.000000000 +0100
@@ -26,7 +26,7 @@
 }
 
 
-#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) && !defined(__mips__)
+#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) && !defined(__arm__) && !defined(__mips__) && !defined(CONFIG_V850) && !defined(CONFIG_MICROBLAZE) 
 
 /*
  * For backward compatibility?  Maybe this should be moved
@@ -133,7 +133,7 @@
 }
 
 
-#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) && !defined(__mips__)
+#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) && !defined(__arm__) && !defined(__mips__) && !defined(CONFIG_V850) && !defined(CONFIG_MICROBLAZE)
 /*
  * For backward compatibility?  Maybe this should be moved
  * into arch/i386 instead?
@@ -169,7 +169,7 @@
 	return error;
 }
 
-#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) && !defined(__mips__)
+#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) && !defined(__arm__) && !defined(__mips__) && !defined(CONFIG_V850) && !defined(CONFIG_MICROBLAZE)
 
 /*
  * For backward compatibility?  Maybe this should be moved
@@ -207,7 +207,7 @@
 	return error;
 }
 
-#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) && !defined(__mips__)
+#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) && !defined(__arm__) && !defined(__mips__) && !defined(CONFIG_V850) && !defined(CONFIG_MICROBLAZE)
 
 /*
  * For backward compatibility?  Maybe this should be moved
diff -urN linux-2.4.29/include/asm-alpha/div64.h linux-2.4.29-uc1/include/asm-alpha/div64.h
--- linux-2.4.29/include/asm-alpha/div64.h	1999-11-23 18:10:38.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-alpha/div64.h	2005-06-14 02:11:38.000000000 +0100
@@ -1,14 +1 @@
-#ifndef __ALPHA_DIV64
-#define __ALPHA_DIV64
-
-/*
- * Hey, we're already 64-bit, no
- * need to play games..
- */
-#define do_div(n,base) ({ \
-	int __res; \
-	__res = ((unsigned long) (n)) % (unsigned) (base); \
-	(n) = ((unsigned long) (n)) / (unsigned) (base); \
-	__res; })
-
-#endif
+#include <asm-generic/div64.h>
diff -urN linux-2.4.29/include/asm-arm/a.out.h linux-2.4.29-uc1/include/asm-arm/a.out.h
--- linux-2.4.29/include/asm-arm/a.out.h	2001-10-11 17:04:57.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/a.out.h	2005-06-14 02:11:23.000000000 +0100
@@ -28,8 +28,20 @@
 #define M_ARM 103
 
 #ifdef __KERNEL__
+
+#ifdef CONFIG_ARM_FASS
+/* FASS sets STACK_TOP to top of PID relocated memory, ie 32MB. In all reality
+ *   there should be some heuristic for selecting of the old STACK_TOP or
+ *   32MB should be set or not. This basically boils down to if a non-zero PID
+ *   is going to be used. Unfortunately when the stack is set in exec() that is
+ *   too difficult to work out.
+ */
+#define STACK_TOP ARMPID_TASK_SIZE
+#else
 #define STACK_TOP	((current->personality == PER_LINUX_32BIT) ? \
 			 TASK_SIZE : TASK_SIZE_26)
+#endif /* CONFIG_ARM_FASS */
+
 #endif
 
 #ifndef LIBRARY_START_TEXT
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/adi_evb.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/adi_evb.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/adi_evb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/adi_evb.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,20 @@
+/*
+ * linux/include/asm/arch-80200fcc/adi_evb.h
+ * 
+ * ADI 80200EVB evaluation board register/hardware definitions
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#define ADI_EVB_RAMBASE		0xa0000000
+#define ADI_EVB_UART		0x00400000    /* UART */
+#define ADI_EVB_7SEG_1		0x00500000    /* 7-Segment */
+
+#define PCIO_BASE		0
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/brh.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/brh.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/brh.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/brh.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,172 @@
+/*
+ * inclue/asm-arm/arch-adifcc/brh.h
+ *
+ * Register and other defines for BRH board
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2000-2001 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#ifndef _BRH_H_
+#define _BRH_H_
+
+/*
+ * Registers @ 0x04000000 phys, 0xff400000 virt)
+ */
+#define BRH_REG_BASE			0xff400000
+#define BRH_REG(reg)			(volatile u32 *)(BRH_REG_BASE | reg)
+
+#define BRH_SWITCH			BRH_REG(0x0500)
+#define BRH_PCI_SLAVE_INT		BRH_REG(0x0000)
+#define BRH_PCI_MEM0_XLATE		BRH_REG(0x0010)
+#define BRH_PCI_MEM1_XLATE		BRH_REG(0x0018)
+#define BRH_PCI_MEM2_XLATE		BRH_REG(0x0020)
+#define BRH_PCI_MAST_INT		BRH_REG(0x0100)
+#define BRH_PCI_MEM_ATU1		BRH_REG(0x0110)
+#define BRH_PCI_MEM_ATU2		BRH_REG(0x0114)
+#define BRH_PCI_IO_ATU			BRH_REG(0x0118)
+#define	BRH_PCI_CONFIG_CTRL		BRH_REG(0x0120)
+#define BRH_DMA0_CTRL			BRH_REG(0x0200)
+#define BRH_DMA1_CTRL			BRH_REG(0x0240)
+#define BRH_DMA0_STATUS			BRH_REG(0x0204)
+#define BRH_DMA1_STATUS			BRH_REG(0x0244)
+#define BRH_DMA0_BYTES			BRH_REG(0x0220)
+#define BRH_DMA1_BYTES			BRH_REG(0x0260)
+#define BRH_DMA0_PADDR			BRH_REG(0x0214)
+#define BRH_DMA1_PADDR			BRH_REG(0x0254)
+#define BRH_DMA0_LADDR			BRH_REG(0x021C)
+#define BRH_DMA1_LADDR			BRH_REG(0x025C)
+#define BRH_DMA0_DCR			BRH_REG(0x0224)
+#define BRH_DMA1_DCR			BRH_REG(0x0264)
+#define BRH_TIMERA_CTRL			BRH_REG(0x0300)
+#define BRH_TIMERB_CTRL			BRH_REG(0x0320)
+#define BRH_TIMERA_PRELOAD		BRH_REG(0x0304)
+#define BRH_TIMERB_PRELOAD		BRH_REG(0x0324)
+#define BRH_TIMERA_VALUE		BRH_REG(0x0308)
+#define BRH_TIMERB_VALUE		BRH_REG(0x0328)
+#define BRH_INT_STAT			BRH_REG(0x0400)
+#define BRH_INT_MASK			BRH_REG(0x0404)
+#define BRH_INT_STEERING		BRH_REG(0x0408)
+
+
+/*
+ * Interrupts
+ */
+#define BRH_INT_SWI			0x00000001
+#define	BRH_INT_TIMERA			0x00000002
+#define BRH_INT_TIMERB			0x00000004
+#define BRH_INT_DIAG			0x00000080
+#define	BRH_INT_DMA0_EOT		0x00000100
+#define	BRH_INT_DMA1_EOT		0x000001
+
+
+/*
+ * Rotary Switch Status Register
+ */
+#define	BRH_BIG_ENDIAN_FLASH		0x00000020
+#define BRH_SWITCH_POS_MASK		0x00000007
+
+/*
+ * PCI Slave Interrupt Status Register
+ */
+#define BRH_PCI_SLAVE_SERR		0x00000010
+#define BRH_PCI_SLAVE_PERR		0x00000100
+#define BRH_PCI_SLAVE_IFIFO_UNDER	0x00010000
+#define BRH_PCI_SLAVE_IFIFO_OVER	0x00020000
+#define BRH_PCI_SLAVE_OFIFO_UNDER	0x00040000
+#define BRH_PCI_SLAVE_OFIFO_OVER	0x00080000
+
+/*
+ * PCI Slave Translation Register (Inbound ATU)
+ */
+#define	BRH_PCI_SLAVE_ENDIAN_SWAP	0x00000001
+
+#define BRH_PCI_SLAVE_SDRAM_MASK	0x06000000
+
+/*
+ * PCI Master Interrupt Status Register
+ */
+#define BRH_PCI_MASTER_PERR		0x00000001
+#define BRH_PCI_MASTER_TABORT		0x00000004
+#define BRH_PCI_MASTER_MABORT		0x00000008
+#define BRH_PCI_MASTER_IFIFO_UNDER	0x00010000
+#define BRH_PCI_MASTER_IFIFO_OVER	0x00020000
+#define BRH_PCI_MASTER_OFIFO_UNDER	0x00040000
+#define BRH_PCI_MASTER_OFIFO_OVER	0x00080000
+
+/*
+ * PCI Outbound Memory ATU Register
+ */
+#define BRH_PCI_ATU_BURST_LINEAR	0x00000000
+#define BRH_PCI_ATU_ENDIAN_SWAP		0x00000004
+#define BRH_PCI_ATU_FORCE_32BIT		0x00000008
+
+#define BRH_PCI_ATU_ADDR_MASK		0x87000000
+
+/*
+ * PCI Outbound I/O ATU Register
+ */
+#define BRH_PCI_IO_ATU_ADDR_MASK	0x87000000
+
+/*
+ * DMA Control Register
+ */
+#define BRH_DMA_ENABLE			0x00000001
+
+/*
+ * DMA Status Register
+ */
+#define BRH_DMA_PERR			0x00000001
+#define BRH_DMA_TABORT			0x00000004
+#define BRH_DMA_MABORT			0x00000008
+#define BRH_DMA_EOT			0x00000100
+#define BRH_DMA_ACTIVE			0x00000400
+#define BRH_DMA_IFIFO_UNDER		0x00010000
+#define BRH_DMA_IFIFO_OVER		0x00020000
+#define BRH_DMA_OFIFO_UNDER		0x00040000
+#define BRH_DMA_OFIFO_OVER		0x00080000
+
+/*
+ * DMA Byte Count Register
+ */
+#define BRH_DMA_MAX_BYTES		(1 << 24)
+
+/*
+ * DMA Local Address Register
+ */
+#define BRH_MAX_DMA_ADDR		(1 << 26)
+
+/*
+ * Timer Control/Status Register
+ */
+#define BRH_TIMER_ENABLE		0x00000001
+#define BRH_TIMER_CONTINOUS		0x00000002
+#define BRH_TIMER_INTERRUPT		0x00000200
+
+/*
+ * On board devices
+ */
+
+#define	BRH_UART0_BASE			0xff000000
+#define BRH_UART1_BASE			0xff100000
+#define BRH_LED_BASE			0xff200000
+
+/*
+ * PCI I/O bits
+ */
+#define	BRH_PCI_IO_VIRT			0xfd000000
+#define BRH_PCI_IO_PHYS			0x0a000000
+#define	PCIO_BASE			((BRH_PCI_IO_VIRT - BRH_PCI_IO_PHYS))
+
+#define PCIBIOS_MIN_IO			0x0a000000
+#define	PCIBIOS_MIN_MEM			0x0c000000
+
+#define pcibios_assign_all_busses()	1
+
+#endif // _BRH_H_
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/dma.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/dma.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/dma.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,18 @@
+/*
+ * linux/include/asm-arm/arch-80200fcc/dma.h
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_ADDRESS		0xffffffff
+
+/* No DMA */
+#define MAX_DMA_CHANNELS	0
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/hardware.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/hardware.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/hardware.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,29 @@
+/*
+ * linux/include/asm-arm/arch-adifcc/hardware.h
+ *
+ * Hardware definitions for ADI based systems
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (C) 2000-2001 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <linux/config.h>
+
+#if defined(CONFIG_ARCH_ADI_EVB)
+#include "adi_evb.h"
+#elif defined(CONFIG_ARCH_BRH)
+#include "brh.h"
+#else
+#error "No ADI Implementation Selected"
+#endif
+
+#endif  /* _ASM_ARCH_HARDWARE_H */
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/io.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/io.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/io.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,53 @@
+/*
+ * linux/include/asm-arm/arch-adifcc/io.h
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (C) 2001  MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io_pci(a)		(PCIO_BASE + (a))
+#define __mem_pci(a)		((unsigned long)(a))
+#define __mem_isa(a)		((unsigned long)(a))
+
+#define __ioaddr(p)		__io_pci(p)
+#define __io(p)			__io_pci(p)
+
+/*
+ * Generic virtual read/write
+ */
+#define __arch_getb(a)		(*(volatile unsigned char *)(a))
+#define __arch_getl(a)		(*(volatile unsigned int  *)(a))
+
+extern __inline__ unsigned int __arch_getw(unsigned long a)
+{
+	unsigned int value;
+	__asm__ __volatile__("ldr%?h	%0, [%1, #0]	@ getw"
+		: "=&r" (value)
+		: "r" (a));
+	return value;
+}
+
+
+#define __arch_putb(v,a)	(*(volatile unsigned char *)(a) = (v))
+#define __arch_putl(v,a)	(*(volatile unsigned int  *)(a) = (v))
+
+extern __inline__ void __arch_putw(unsigned int value, unsigned long a)
+{
+	__asm__ __volatile__("str%?h	%0, [%1, #0]	@ putw"
+		: : "r" (value), "r" (a));
+}
+
+#define __arch_ioremap		__ioremap
+#define __arch_iounmap		__iounmap
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/irq.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/irq.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/irq.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,13 @@
+/*
+ *  linux/include/asm-arm/arch-adifcc/irq.h
+ *
+ *  Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define fixup_irq(irq)  (irq)
+
+
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/irqs.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/irqs.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/irqs.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,55 @@
+/*
+ * linux/include/asm-arm/arch-adifcc/irqs.h
+ *
+ * Author:	Deepak Saxena <dsaxena@mvista.com>
+ * Copyright:	(C) 2001 MontaVista Software Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define IRQ_XS80200_BCU		0	/* Bus Control Unit */
+#define IRQ_XS80200_PMU		1	/* Performance Monitoring Unit */
+#define IRQ_XS80200_EXTIRQ	2	/* external IRQ signal */
+#define IRQ_XS80200_EXTFIQ	3	/* external IRQ signal */
+
+#define XSCALE_PMU_IRQ		IRQ_XS80200_PMU
+
+#define NR_XS80200_IRQS		4
+#define NR_IRQS			NR_XS80200_IRQS
+
+#define	IRQ_XSCALE_PMU		IRQ_XS80200_PMU
+
+#ifdef CONFIG_ARCH_BRH
+
+/* Interrupts available on the BRH */
+#define	IRQ_BRH(x)		(NR_XS80200_IRQS + (x))
+
+#define IRQ_BRH_SWI		IRQ_BRH(0)
+#define	IRQ_BRH_TIMERA		IRQ_BRH(1)
+#define IRQ_BRH_TIMERB		IRQ_BRH(2)
+#define IRQ_BRH_ERROR		IRQ_BRH(7)
+#define IRQ_BRH_DMA_EOT		IRQ_BRH(8)
+#define IRQ_BRH_DMA_PARITY	IRQ_BRH(9)
+#define IRQ_BRH_DMA_TABORT	IRQ_BRH(10)
+#define IRQ_BRH_DMA_MABORT	IRQ_BRH(11)
+#define IRQ_BRH_PCI_PERR	IRQ_BRH(16)
+#define IRQ_BRH_PCI_SERR	IRQ_BRH(19)
+#define IRQ_BRH_ATU_PERR	IRQ_BRH(20)
+#define IRQ_BRH_ATU_TABORT	IRQ_BRH(21)
+#define IRQ_BRH_ATU_MABORT	IRQ_BRH(22)
+#define IRQ_BRH_UART_A		IRQ_BRH(24)
+#define IRQ_BRH_UART_B		IRQ_BRH(25)
+#define IRQ_BRH_PCI_INT_A	IRQ_BRH(26)
+#define IRQ_BRH_PCI_INT_B	IRQ_BRH(27)
+#define IRQ_BRH_PCI_INT_C	IRQ_BRH(28)
+#define IRQ_BRH_PCI_INT_D	IRQ_BRH(29)
+#define IRQ_BRH_SOFT_RESET	IRQ_BRH(30)
+
+#undef NR_IRQS
+#define NR_IRQS ((IRQ_BRH_SOFT_RESET)+1)
+
+#endif
+
+
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/memory.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/memory.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/memory.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,49 @@
+/*
+ * linux/include/asm-arm/arch-adifcc/memory.h
+ *
+ * Copyright (c) 2001 MontaVista Software, Inc.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define TASK_SIZE	((unsigned long)(CONFIG_KERNEL_START & 0xffc00000))
+#define TASK_SIZE_26	(0x04000000UL)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+
+#define PAGE_OFFSET	((unsigned long)(CONFIG_KERNEL_START & 0xffc00000))
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET	(0xC0000000UL)
+
+/*
+ * physical vs virtual ram conversion
+ */
+#define __virt_to_phys__is_a_macro
+#define __phys_to_virt__is_a_macro
+#define __virt_to_phys(x)	((x) - PAGE_OFFSET + PHYS_OFFSET)
+#define __phys_to_virt(x)	((x) - PHYS_OFFSET + PAGE_OFFSET)
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *		address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *		to an address that the kernel can use.
+ *
+ * These are dummies for now.
+ */
+#define __virt_to_bus__is_a_macro
+#define __bus_to_virt__is_a_macro
+#define __virt_to_bus(x)	 __virt_to_phys(x)
+#define __bus_to_virt(x)	 __phys_to_virt(x)
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/param.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/param.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/param.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,3 @@
+/*
+ * linux/include/asm-arm/arch-adifcc/param.h
+ */
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/pci_auto.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/pci_auto.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/pci_auto.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/pci_auto.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-iop310/pci_auto.h
+ * 
+ * PCI autoconfiguration library definitions
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef _ARM_MACH_XSCALE_PCI_AUTO_H
+#define _ARM_MACH_XSCALE_PCI_AUTO_H
+
+#include "pci-bridge.h"
+
+extern int pciauto_bus_scan(struct pci_controller *, int);
+
+#define	PCIAUTO_IDE_MODE_MASK		0x05
+
+#endif /* _ARM_MACH_XSCALE_PCI_AUTO_H */
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/pci-bridge.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/pci-bridge.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/pci-bridge.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/pci-bridge.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,65 @@
+/*
+ * include/asm-arm/arch-iop310/pci-bridge.h
+ * 
+ * Generic PCI hose support for Xscale/ARM.  To eventually be
+ * moved to a more generic location.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifdef __KERNEL__
+#ifndef _ASM_PCI_BRIDGE_H
+#define _ASM_PCI_BRIDGE_H
+
+struct device_node;
+struct pci_controller;
+
+/* Get the PCI host controller for a bus */
+extern struct pci_controller* pci_bus_to_hose(int bus);
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct pci_controller {
+	int index;
+	struct pci_controller *next;
+        struct pci_bus *bus;
+	void *arch_data;
+
+	int first_busno;
+	int last_busno;
+        
+	struct pci_ops *ops;
+	volatile unsigned int *cfg_addr;
+	volatile unsigned char *cfg_data;
+
+	/* Currently, we limit ourselves to 1 IO range and 3 mem
+	 * ranges since the common pci_bus structure can't handle more
+	 */
+	struct resource	io_resource;
+	struct resource mem_resources[3];
+	int mem_resource_count;
+
+	/* Host bridge I/O and Memory space
+	 * Used for BAR placement algorithms
+	 */
+	struct resource io_space;
+	struct resource mem_space;
+};
+
+/* These are used for config access before all the PCI probing
+   has been done. */
+int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn, int where, u8 *val);
+int early_read_config_word(struct pci_controller *hose, int bus, int dev_fn, int where, u16 *val);
+int early_read_config_dword(struct pci_controller *hose, int bus, int dev_fn, int where, u32 *val);
+int early_write_config_byte(struct pci_controller *hose, int bus, int dev_fn, int where, u8 val);
+int early_write_config_word(struct pci_controller *hose, int bus, int dev_fn, int where, u16 val);
+int early_write_config_dword(struct pci_controller *hose, int bus, int dev_fn, int where, u32 val);
+#endif
+#endif /* __KERNEL__ */
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/pci.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/pci.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/pci.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,36 @@
+/*
+ * include/asm-arm/arch-xscale/pci.h
+ * 
+ * Generic PCI support for Xscale/ARM.  To eventually be moved to a
+ * more generic location.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef _ASM_ARCH_PCI_H
+#define _ASM_ARCH_PCI_H
+
+extern struct pci_controller* pcibios_alloc_controller(void);
+extern void pcibios_allocate_resources(void);
+extern void pci_exclude_device(unsigned char, unsigned char);
+extern struct pci_dev * fake_pci_dev(struct pci_controller *, int, int);
+extern u8 common_swizzle(struct pci_dev *, u8 *);
+
+/*
+ * The following macro is used to lookup irqs in a standard table
+ * format for those systems that do not already have PCI
+ * interrupts properly routed.
+ */
+#define PCI_IRQ_TABLE_LOOKUP                                            \
+({ long _ctl_ = -1;                                                     \
+   if (idsel >= min_idsel && idsel <= max_idsel && pin <= irqs_per_slot) \
+	 _ctl_ = pci_irq_table[idsel - min_idsel][pin-1]; \
+   _ctl_; })
+
+#endif /* _ASM_ARCH_PCI_H */
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/serial.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/serial.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/serial.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,69 @@
+/*
+ * include/asm-arm/arch-adifcc/serial.h
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (c) 2001 MontaVista Software, Inc.
+ */
+
+#ifndef _ARCH_SERIAL_H_
+#define _ARCH_SERIAL_H_
+
+/* Standard COM flags */
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+/*
+ * We use SERIAL_IO_MEM type since these are memory mapped UARTs,
+ * not ISA style I/O ports.
+ */
+ 
+#ifdef CONFIG_ARCH_ADI_EVB
+
+#define BASE_BAUD ( 1852000 / 16 )
+
+#define RS_TABLE_SIZE 1
+
+/*
+ * One serial port, int goes to FIQ, so we run in polled mode
+ */
+#define STD_SERIAL_PORT_DEFNS				\
+	{						\
+	  magic: 0,					\
+	  baud_base: BASE_BAUD,				\
+	  irq: 0,					\
+	  flags: STD_COM_FLAGS,				\
+	  iomem_base: 0xff400000,			\
+	  io_type: SERIAL_IO_MEM			\
+	} /* ttyS0 */
+
+#elif defined(CONFIG_ARCH_BRH)
+
+/*
+ * BRH uses 33MHz clock for uart
+ */
+#define BASE_BAUD ( 33000000 / 16 )
+
+#define	RS_TABLE_SIZE	2
+
+#define STD_SERIAL_PORT_DEFNS				\
+	{						\
+	  magic: 0,					\
+	  baud_base: BASE_BAUD,				\
+	  irq: IRQ_BRH_UART_A,				\
+	  flags: STD_COM_FLAGS,				\
+	  iomem_base: BRH_UART0_BASE,			\
+	  io_type: SERIAL_IO_MEM			\
+	}, /* ttyS0 */					\
+	{						\
+	  magic: 0,					\
+	  baud_base: BASE_BAUD,				\
+	  irq: IRQ_BRH_UART_B,				\
+	  flags: STD_COM_FLAGS,				\
+	  iomem_base: BRH_UART1_BASE,			\
+	  io_type: SERIAL_IO_MEM			\
+	} /* ttyS1 */
+#endif
+
+#define EXTRA_SERIAL_PORT_DEFNS
+
+#endif // _ARCH_SERIAL_H_
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/system.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/system.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/system.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,29 @@
+/*
+ * linux/include/asm-arm/arch-adifcc/system.h
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+static inline void arch_idle(void)
+{
+#if 0
+	if (!hlt_counter)
+		cpu_do_idle(0);
+#endif
+}
+
+
+static inline void arch_reset(char mode)
+{
+	if ( 1 && mode == 's') {
+		/* Jump into ROM at address 0 */
+		cpu_reset(0);
+	} else {
+		/* Use on-chip reset capability */
+	}
+}
+
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/time.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/time.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/time.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * linux/include/asm-arm/arch-adifcc/time.h
+ *
+ */
+
+
+/*
+ * No on board timer on 80200EVB, implemenation @ 
+ * 	arch/arm/kernel/xscale-time.c
+ * On the BRH, we use the onboard timer and it's implemented in
+ * 	arch/arm/mach-adifcc/brh-time.c
+ */
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/timex.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/timex.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/timex.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-arm/arch-adifcc/timex.h
+ *
+ * XScale architecture timex specifications
+ */
+
+#ifdef CONFIG_XSCALE_PMU_TIMER
+/* 
+ * This is for a timer based on the XS80200's PMU counter 
+ */
+#define CLOCK_TICK_RATE 400000000 
+
+#else
+
+#define CLOCK_TICK_RATE 33000000
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/uncompress.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/uncompress.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/uncompress.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,114 @@
+/*
+ * linux/include/asm-arm/arch-adifcc/uncompress.h
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (c) 2001 MontaVista Software, Inc.
+ *
+ */
+
+#ifndef _ARCH_UNCOMPRESS_H_
+#define _ARCH_UNCOMPRESS_H_
+
+#ifdef CONFIG_ARCH_ADI_EVB
+#define UART_BASE    ((volatile unsigned char *)0x00400000)
+#elif defined(CONFIG_ARCH_BRH)
+#define UART_BASE    ((volatile unsigned char *)0x03000000)
+#define UART_BASE2    ((volatile unsigned char *)0x03100000)
+#endif
+
+static __inline__ void putc(char c)
+{
+	/*
+	 * Boards have peripherals wired in LE mode, so need to
+	 * fiddle with the address to get the proper byte lane
+	 * enabled. :)
+	 */
+#if defined(__ARMEB__) && defined(_FOOBAR_)
+	while ((UART_BASE[6] & 0x60) != 0x60);
+	UART_BASE[3] = c;
+#else
+
+	while ((UART_BASE[5] & 0x60) != 0x60);
+	UART_BASE[0] = c;
+#endif
+}
+
+/*
+ * This does not append a newline
+ */
+static void puts(const char *s)
+{
+	while (*s) {
+		putc(*s);
+		if (*s == '\n')
+			putc('\r');
+		s++;
+	}
+}
+
+#ifdef CONFIG_ARCH_BRH
+
+/*
+ * We need to determine what rev board we're running so that we
+ * can tell the system how much RAM there is.  Can't do this in
+ * the board fixup function b/c the revision of the board can
+ * only be found through PCI config cycles, which would require
+ * the PCI registers to be mapped very early on.
+ */
+
+#include <linux/pci.h>
+#include <asm/setup.h>
+
+static u32 get_mem_size(void)
+{
+	u32 where = PCI_CLASS_REVISION & ~3;
+	u32 *paddress = (u32*)(0x08000000 | ( 1 << PCI_SLOT(0) + 11) | (PCI_FUNC(0) << 8) | where);
+	u8 rev_id;
+
+	rev_id = (u8)(*paddress & 0xff);
+
+	/*
+	 * Old revision board, only 32 MB usable
+	 */
+	if(!rev_id)
+		return 0x02000000;
+	else
+		return 0x08000000;
+}
+
+#define PARAM_ADDR 0xC0000100
+
+static void setup_params(void)
+{
+	volatile struct tag *params = (struct tag*)PARAM_ADDR;
+
+	params->hdr.tag = ATAG_CORE;
+	params->hdr.size = tag_size(tag_core);
+	params->u.core.flags = 0;
+	params->u.core.pagesize = PAGE_SIZE;
+	params->u.core.rootdev = 0;
+
+	params = (volatile struct tag*)tag_next(params);
+
+	params->hdr.tag = ATAG_MEM;
+	params->hdr.size = tag_size(tag_mem32);
+	params->u.mem.start = 0xc0000000;
+	params->u.mem.size = get_mem_size();
+
+	params = (volatile struct tag*)tag_next(params);
+
+	params->hdr.tag = ATAG_NONE;
+	params->hdr.size = 0;
+}
+
+#define arch_decomp_setup()	setup_params()
+
+#else
+#define arch_decomp_setup()
+#endif
+
+#define arch_decomp_wdog()
+
+
+#endif // _ARCH_UNCOMPRESS_H_
diff -urN linux-2.4.29/include/asm-arm/arch-adifcc/vmalloc.h linux-2.4.29-uc1/include/asm-arm/arch-adifcc/vmalloc.h
--- linux-2.4.29/include/asm-arm/arch-adifcc/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-adifcc/vmalloc.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,16 @@
+/*
+ * linux/include/asm-arm/arch-adifcc/vmalloc.h
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (0xe8000000)
diff -urN linux-2.4.29/include/asm-arm/arch-at91rm9200/at91rm9200dk.h linux-2.4.29-uc1/include/asm-arm/arch-at91rm9200/at91rm9200dk.h
--- linux-2.4.29/include/asm-arm/arch-at91rm9200/at91rm9200dk.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-at91rm9200/at91rm9200dk.h	2005-06-14 02:11:23.000000000 +0100
@@ -68,6 +68,7 @@
 #define AT91_SMR_IRQ5	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (IRQ5)
 #define AT91_SMR_IRQ6	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (IRQ6)
 
+#define AT91C_CONSOLE_DEFAULT_BAUDRATE 115200	/* default serial console baud-rate */
 
 /*
  * Serial port configuration.
diff -urN linux-2.4.29/include/asm-arm/arch-at91rm9200/AT91RM9200_MCI.h linux-2.4.29-uc1/include/asm-arm/arch-at91rm9200/AT91RM9200_MCI.h
--- linux-2.4.29/include/asm-arm/arch-at91rm9200/AT91RM9200_MCI.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-at91rm9200/AT91RM9200_MCI.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,127 @@
+// ----------------------------------------------------------------------------
+//          ATMEL Microcontroller Software Support  -  ROUSSET  -
+// ----------------------------------------------------------------------------
+//  The software is delivered "AS IS" without warranty or condition of any
+//  kind, either express, implied or statutory. This includes without
+//  limitation any warranty or condition with respect to merchantability or
+//  fitness for any particular purpose, or against the infringements of
+//  intellectual property rights of others.
+// ----------------------------------------------------------------------------
+// File Name           : AT91RM9200.h
+// Object              : AT91RM9200 / MCI definitions
+// Generated           : AT91 SW Application Group  12/03/2002 (10:48:02)
+// 
+// ----------------------------------------------------------------------------
+
+#ifndef AT91RM9200_MCI_H
+#define AT91RM9200_MCI_H
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Multimedia Card Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+
+typedef struct _AT91S_MCI {
+	AT91_REG	 MCI_CR; 	// MCI Control Register
+	AT91_REG	 MCI_MR; 	// MCI Mode Register
+	AT91_REG	 MCI_DTOR; 	// MCI Data Timeout Register
+	AT91_REG	 MCI_SDCR; 	// MCI SD Card Register
+	AT91_REG	 MCI_ARGR; 	// MCI Argument Register
+	AT91_REG	 MCI_CMDR; 	// MCI Command Register
+	AT91_REG	 Reserved0[2]; 	// 
+	AT91_REG	 MCI_RSPR[4]; 	// MCI Response Register
+	AT91_REG	 MCI_RDR; 	// MCI Receive Data Register
+	AT91_REG	 MCI_TDR; 	// MCI Transmit Data Register
+	AT91_REG	 Reserved1[2]; 	// 
+	AT91_REG	 MCI_SR; 	// MCI Status Register
+	AT91_REG	 MCI_IER; 	// MCI Interrupt Enable Register
+	AT91_REG	 MCI_IDR; 	// MCI Interrupt Disable Register
+	AT91_REG	 MCI_IMR; 	// MCI Interrupt Mask Register
+	AT91_REG	 Reserved2[44]; 	// 
+	AT91_REG	 MCI_RPR; 	// Receive Pointer Register
+	AT91_REG	 MCI_RCR; 	// Receive Counter Register
+	AT91_REG	 MCI_TPR; 	// Transmit Pointer Register
+	AT91_REG	 MCI_TCR; 	// Transmit Counter Register
+	AT91_REG	 MCI_RNPR; 	// Receive Next Pointer Register
+	AT91_REG	 MCI_RNCR; 	// Receive Next Counter Register
+	AT91_REG	 MCI_TNPR; 	// Transmit Next Pointer Register
+	AT91_REG	 MCI_TNCR; 	// Transmit Next Counter Register
+	AT91_REG	 MCI_PTCR; 	// PDC Transfer Control Register
+	AT91_REG	 MCI_PTSR; 	// PDC Transfer Status Register
+} AT91S_MCI, *AT91PS_MCI;
+
+#endif
+
+// -------- MCI_CR : (MCI Offset: 0x0) MCI Control Register -------- 
+#define AT91C_MCI_MCIEN       ((unsigned int) 0x1 <<  0) // (MCI) Multimedia Interface Enable
+#define AT91C_MCI_MCIDIS      ((unsigned int) 0x1 <<  1) // (MCI) Multimedia Interface Disable
+#define AT91C_MCI_PWSEN       ((unsigned int) 0x1 <<  2) // (MCI) Power Save Mode Enable
+#define AT91C_MCI_PWSDIS      ((unsigned int) 0x1 <<  3) // (MCI) Power Save Mode Disable
+// -------- MCI_MR : (MCI Offset: 0x4) MCI Mode Register -------- 
+#define AT91C_MCI_CLKDIV      ((unsigned int) 0x1 <<  0) // (MCI) Clock Divider
+#define AT91C_MCI_PWSDIV      ((unsigned int) 0x1 <<  8) // (MCI) Power Saving Divider
+#define AT91C_MCI_PDCPADV     ((unsigned int) 0x1 << 14) // (MCI) PDC Padding Value
+#define AT91C_MCI_PDCMODE     ((unsigned int) 0x1 << 15) // (MCI) PDC Oriented Mode
+#define AT91C_MCI_BLKLEN      ((unsigned int) 0x1 << 18) // (MCI) Data Block Length
+// -------- MCI_DTOR : (MCI Offset: 0x8) MCI Data Timeout Register -------- 
+#define AT91C_MCI_DTOCYC      ((unsigned int) 0x1 <<  0) // (MCI) Data Timeout Cycle Number
+#define AT91C_MCI_DTOMUL      ((unsigned int) 0x7 <<  4) // (MCI) Data Timeout Multiplier
+#define 	AT91C_MCI_DTOMUL_1                    ((unsigned int) 0x0 <<  4) // (MCI) DTOCYC x 1
+#define 	AT91C_MCI_DTOMUL_16                   ((unsigned int) 0x1 <<  4) // (MCI) DTOCYC x 16
+#define 	AT91C_MCI_DTOMUL_128                  ((unsigned int) 0x2 <<  4) // (MCI) DTOCYC x 128
+#define 	AT91C_MCI_DTOMUL_256                  ((unsigned int) 0x3 <<  4) // (MCI) DTOCYC x 256
+#define 	AT91C_MCI_DTOMUL_1024                 ((unsigned int) 0x4 <<  4) // (MCI) DTOCYC x 1024
+#define 	AT91C_MCI_DTOMUL_4096                 ((unsigned int) 0x5 <<  4) // (MCI) DTOCYC x 4096
+#define 	AT91C_MCI_DTOMUL_65536                ((unsigned int) 0x6 <<  4) // (MCI) DTOCYC x 65536
+#define 	AT91C_MCI_DTOMUL_1048576              ((unsigned int) 0x7 <<  4) // (MCI) DTOCYC x 1048576
+// -------- MCI_SDCR : (MCI Offset: 0xc) MCI SD Card Register -------- 
+#define AT91C_MCI_SCDSEL      ((unsigned int) 0x1 <<  0) // (MCI) SD Card Selector
+#define AT91C_MCI_SCDBUS      ((unsigned int) 0x1 <<  7) // (MCI) SD Card Bus Width
+// -------- MCI_CMDR : (MCI Offset: 0x14) MCI Command Register -------- 
+#define AT91C_MCI_CMDNB       ((unsigned int) 0x1F <<  0) // (MCI) Command Number
+#define AT91C_MCI_RSPTYP      ((unsigned int) 0x3 <<  6) // (MCI) Response Type
+#define 	AT91C_MCI_RSPTYP_NO                   ((unsigned int) 0x0 <<  6) // (MCI) No response
+#define 	AT91C_MCI_RSPTYP_48                   ((unsigned int) 0x1 <<  6) // (MCI) 48-bit response
+#define 	AT91C_MCI_RSPTYP_136                  ((unsigned int) 0x2 <<  6) // (MCI) 136-bit response
+#define AT91C_MCI_SPCMD       ((unsigned int) 0x7 <<  8) // (MCI) Special CMD
+#define 	AT91C_MCI_SPCMD_NONE                 ((unsigned int) 0x0 <<  8) // (MCI) Not a special CMD
+#define 	AT91C_MCI_SPCMD_INIT                 ((unsigned int) 0x1 <<  8) // (MCI) Initialization CMD
+#define 	AT91C_MCI_SPCMD_SYNC                 ((unsigned int) 0x2 <<  8) // (MCI) Synchronized CMD
+#define 	AT91C_MCI_SPCMD_IT_CMD               ((unsigned int) 0x4 <<  8) // (MCI) Interrupt command
+#define 	AT91C_MCI_SPCMD_IT_REP               ((unsigned int) 0x5 <<  8) // (MCI) Interrupt response
+#define AT91C_MCI_OPDCMD      ((unsigned int) 0x1 << 11) // (MCI) Open Drain Command
+#define AT91C_MCI_MAXLAT      ((unsigned int) 0x1 << 12) // (MCI) Maximum Latency for Command to respond
+#define AT91C_MCI_TRCMD       ((unsigned int) 0x3 << 16) // (MCI) Transfer CMD
+#define 	AT91C_MCI_TRCMD_NO                   ((unsigned int) 0x0 << 16) // (MCI) No transfer
+#define 	AT91C_MCI_TRCMD_START                ((unsigned int) 0x1 << 16) // (MCI) Start transfer
+#define 	AT91C_MCI_TRCMD_STOP                 ((unsigned int) 0x2 << 16) // (MCI) Stop transfer
+#define AT91C_MCI_TRDIR       ((unsigned int) 0x1 << 18) // (MCI) Transfer Direction
+#define AT91C_MCI_TRTYP       ((unsigned int) 0x3 << 19) // (MCI) Transfer Type
+#define 	AT91C_MCI_TRTYP_BLOCK                ((unsigned int) 0x0 << 19) // (MCI) Block Transfer type
+#define 	AT91C_MCI_TRTYP_MULTIPLE             ((unsigned int) 0x1 << 19) // (MCI) Multiple Block transfer type
+#define 	AT91C_MCI_TRTYP_STREAM               ((unsigned int) 0x2 << 19) // (MCI) Stream transfer type
+// -------- MCI_SR : (MCI Offset: 0x40) MCI Status Register -------- 
+#define AT91C_MCI_CMDRDY      ((unsigned int) 0x1 <<  0) // (MCI) Command Ready flag
+#define AT91C_MCI_RXRDY       ((unsigned int) 0x1 <<  1) // (MCI) RX Ready flag
+#define AT91C_MCI_TXRDY       ((unsigned int) 0x1 <<  2) // (MCI) TX Ready flag
+#define AT91C_MCI_BLKE        ((unsigned int) 0x1 <<  3) // (MCI) Data Block Transfer Ended flag
+#define AT91C_MCI_DTIP        ((unsigned int) 0x1 <<  4) // (MCI) Data Transfer in Progress flag
+#define AT91C_MCI_NOTBUSY     ((unsigned int) 0x1 <<  5) // (MCI) Data Line Not Busy flag
+#define AT91C_MCI_ENDRX       ((unsigned int) 0x1 <<  6) // (MCI) End of RX Buffer flag
+#define AT91C_MCI_ENDTX       ((unsigned int) 0x1 <<  7) // (MCI) End of TX Buffer flag
+#define AT91C_MCI_RXBUFF      ((unsigned int) 0x1 << 14) // (MCI) RX Buffer Full flag
+#define AT91C_MCI_TXBUFE      ((unsigned int) 0x1 << 15) // (MCI) TX Buffer Empty flag
+#define AT91C_MCI_RINDE       ((unsigned int) 0x1 << 16) // (MCI) Response Index Error flag
+#define AT91C_MCI_RDIRE       ((unsigned int) 0x1 << 17) // (MCI) Response Direction Error flag
+#define AT91C_MCI_RCRCE       ((unsigned int) 0x1 << 18) // (MCI) Response CRC Error flag
+#define AT91C_MCI_RENDE       ((unsigned int) 0x1 << 19) // (MCI) Response End Bit Error flag
+#define AT91C_MCI_RTOE        ((unsigned int) 0x1 << 20) // (MCI) Response Time-out Error flag
+#define AT91C_MCI_DCRCE       ((unsigned int) 0x1 << 21) // (MCI) data CRC Error flag
+#define AT91C_MCI_DTOE        ((unsigned int) 0x1 << 22) // (MCI) Data timeout Error flag
+#define AT91C_MCI_OVRE        ((unsigned int) 0x1 << 30) // (MCI) Overrun flag
+#define AT91C_MCI_UNRE        ((unsigned int) 0x1 << 31) // (MCI) Underrun flag
+// -------- MCI_IER : (MCI Offset: 0x44) MCI Interrupt Enable Register -------- 
+// -------- MCI_IDR : (MCI Offset: 0x48) MCI Interrupt Disable Register -------- 
+// -------- MCI_IMR : (MCI Offset: 0x4c) MCI Interrupt Mask Register -------- 
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-at91rm9200/AT91RM9200_SSC.h linux-2.4.29-uc1/include/asm-arm/arch-at91rm9200/AT91RM9200_SSC.h
--- linux-2.4.29/include/asm-arm/arch-at91rm9200/AT91RM9200_SSC.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-at91rm9200/AT91RM9200_SSC.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,129 @@
+// ----------------------------------------------------------------------------
+//          ATMEL Microcontroller Software Support  -  ROUSSET  -
+// ----------------------------------------------------------------------------
+//  The software is delivered "AS IS" without warranty or condition of any
+//  kind, either express, implied or statutory. This includes without
+//  limitation any warranty or condition with respect to merchantability or
+//  fitness for any particular purpose, or against the infringements of
+//  intellectual property rights of others.
+// ----------------------------------------------------------------------------
+// File Name           : AT91RM9200.h
+// Object              : AT91RM9200 / SSC definitions
+// Generated           : AT91 SW Application Group  12/03/2002 (10:48:02)
+// 
+// ----------------------------------------------------------------------------
+
+#ifndef AT91RM9200_SSC_H
+#define AT91RM9200_SSC_H
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Synchronous Serial Controller Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+
+typedef struct _AT91S_SSC {
+	AT91_REG	 SSC_CR; 	// Control Register
+	AT91_REG	 SSC_CMR; 	// Clock Mode Register
+	AT91_REG	 Reserved0[2]; 	// 
+	AT91_REG	 SSC_RCMR; 	// Receive Clock ModeRegister
+	AT91_REG	 SSC_RFMR; 	// Receive Frame Mode Register
+	AT91_REG	 SSC_TCMR; 	// Transmit Clock Mode Register
+	AT91_REG	 SSC_TFMR; 	// Transmit Frame Mode Register
+	AT91_REG	 SSC_RHR; 	// Receive Holding Register
+	AT91_REG	 SSC_THR; 	// Transmit Holding Register
+	AT91_REG	 Reserved1[2]; 	// 
+	AT91_REG	 SSC_RSHR; 	// Receive Sync Holding Register
+	AT91_REG	 SSC_TSHR; 	// Transmit Sync Holding Register
+	AT91_REG	 SSC_RC0R; 	// Receive Compare 0 Register
+	AT91_REG	 SSC_RC1R; 	// Receive Compare 1 Register
+	AT91_REG	 SSC_SR; 	// Status Register
+	AT91_REG	 SSC_IER; 	// Interrupt Enable Register
+	AT91_REG	 SSC_IDR; 	// Interrupt Disable Register
+	AT91_REG	 SSC_IMR; 	// Interrupt Mask Register
+	AT91_REG	 Reserved2[44]; 	// 
+	AT91_REG	 SSC_RPR; 	// Receive Pointer Register
+	AT91_REG	 SSC_RCR; 	// Receive Counter Register
+	AT91_REG	 SSC_TPR; 	// Transmit Pointer Register
+	AT91_REG	 SSC_TCR; 	// Transmit Counter Register
+	AT91_REG	 SSC_RNPR; 	// Receive Next Pointer Register
+	AT91_REG	 SSC_RNCR; 	// Receive Next Counter Register
+	AT91_REG	 SSC_TNPR; 	// Transmit Next Pointer Register
+	AT91_REG	 SSC_TNCR; 	// Transmit Next Counter Register
+	AT91_REG	 SSC_PTCR; 	// PDC Transfer Control Register
+	AT91_REG	 SSC_PTSR; 	// PDC Transfer Status Register
+} AT91S_SSC, *AT91PS_SSC;
+
+#endif
+
+// -------- SSC_CR : (SSC Offset: 0x0) SSC Control Register -------- 
+#define AT91C_SSC_RXEN        ( 0x1 <<  0) // (SSC) Receive Enable
+#define AT91C_SSC_RXDIS       ( 0x1 <<  1) // (SSC) Receive Disable
+#define AT91C_SSC_TXEN        ( 0x1 <<  8) // (SSC) Transmit Enable
+#define AT91C_SSC_TXDIS       ( 0x1 <<  9) // (SSC) Transmit Disable
+#define AT91C_SSC_SWRST       ( 0x1 << 15) // (SSC) Software Reset
+// -------- SSC_RCMR : (SSC Offset: 0x10) SSC Receive Clock Mode Register -------- 
+#define AT91C_SSC_CKS         ( 0x3 <<  0) // (SSC) Receive/Transmit Clock Selection
+#define 	AT91C_SSC_CKS_DIV                  ( 0x0) // (SSC) Divided Clock
+#define 	AT91C_SSC_CKS_TK                   ( 0x1) // (SSC) TK Clock signal
+#define 	AT91C_SSC_CKS_RK                   ( 0x2) // (SSC) RK pin
+#define AT91C_SSC_CKO         ( 0x7 <<  2) // (SSC) Receive/Transmit Clock Output Mode Selection
+#define 	AT91C_SSC_CKO_NONE                 ( 0x0 <<  2) // (SSC) Receive/Transmit Clock Output Mode: None RK pin: Input-only
+#define 	AT91C_SSC_CKO_CONTINOUS            ( 0x1 <<  2) // (SSC) Continuous Receive/Transmit Clock RK pin: Output
+#define 	AT91C_SSC_CKO_DATA_TX              ( 0x2 <<  2) // (SSC) Receive/Transmit Clock only during data transfers RK pin: Output
+#define AT91C_SSC_CKI         ( 0x1 <<  5) // (SSC) Receive/Transmit Clock Inversion
+#define AT91C_SSC_CKG         ( 0x3 <<  6) // (SSC) Receive/Transmit Clock Gating Selection
+#define 	AT91C_SSC_CKG_NONE                 ( 0x0 <<  6) // (SSC) Receive/Transmit Clock Gating: None, continuous clock
+#define 	AT91C_SSC_CKG_LOW                  ( 0x1 <<  6) // (SSC) Receive/Transmit Clock enabled only if RF Low
+#define 	AT91C_SSC_CKG_HIGH                 ( 0x2 <<  6) // (SSC) Receive/Transmit Clock enabled only if RF High
+#define AT91C_SSC_START       ( 0xF <<  8) // (SSC) Receive/Transmit Start Selection
+#define 	AT91C_SSC_START_CONTINOUS            ( 0x0 <<  8) // (SSC) Continuous, as soon as the receiver is enabled, and immediately after the end of transfer of the previous data.
+#define 	AT91C_SSC_START_TX                   ( 0x1 <<  8) // (SSC) Transmit/Receive start
+#define 	AT91C_SSC_START_LOW_RF               ( 0x2 <<  8) // (SSC) Detection of a low level on RF input
+#define 	AT91C_SSC_START_HIGH_RF              ( 0x3 <<  8) // (SSC) Detection of a high level on RF input
+#define 	AT91C_SSC_START_FALL_RF              ( 0x4 <<  8) // (SSC) Detection of a falling edge on RF input
+#define 	AT91C_SSC_START_RISE_RF              ( 0x5 <<  8) // (SSC) Detection of a rising edge on RF input
+#define 	AT91C_SSC_START_LEVEL_RF             ( 0x6 <<  8) // (SSC) Detection of any level change on RF input
+#define 	AT91C_SSC_START_EDGE_RF              ( 0x7 <<  8) // (SSC) Detection of any edge on RF input
+#define 	AT91C_SSC_START_0                    ( 0x8 <<  8) // (SSC) Compare 0
+#define AT91C_SSC_STOP        ( 0x1 << 12) // (SSC) Receive Stop Selection
+#define AT91C_SSC_STTOUT      ( 0x1 << 15) // (SSC) Receive/Transmit Start Output Selection
+#define AT91C_SSC_STTDLY      ( 0xFF << 16) // (SSC) Receive/Transmit Start Delay
+#define AT91C_SSC_PERIOD      ( 0xFF << 24) // (SSC) Receive/Transmit Period Divider Selection
+// -------- SSC_RFMR : (SSC Offset: 0x14) SSC Receive Frame Mode Register -------- 
+#define AT91C_SSC_DATLEN      ( 0x1F <<  0) // (SSC) Data Length
+#define AT91C_SSC_LOOP        ( 0x1 <<  5) // (SSC) Loop Mode
+#define AT91C_SSC_MSBF        ( 0x1 <<  7) // (SSC) Most Significant Bit First
+#define AT91C_SSC_DATNB       ( 0xF <<  8) // (SSC) Data Number per Frame
+#define AT91C_SSC_FSLEN       ( 0xF << 16) // (SSC) Receive/Transmit Frame Sync length
+#define AT91C_SSC_FSOS        ( 0x7 << 20) // (SSC) Receive/Transmit Frame Sync Output Selection
+#define 	AT91C_SSC_FSOS_NONE                 ( 0x0 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: None RK pin Input-only
+#define 	AT91C_SSC_FSOS_NEGATIVE             ( 0x1 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Negative Pulse
+#define 	AT91C_SSC_FSOS_POSITIVE             ( 0x2 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Positive Pulse
+#define 	AT91C_SSC_FSOS_LOW                  ( 0x3 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver Low during data transfer
+#define 	AT91C_SSC_FSOS_HIGH                 ( 0x4 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver High during data transfer
+#define 	AT91C_SSC_FSOS_TOGGLE               ( 0x5 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Toggling at each start of data transfer
+#define AT91C_SSC_FSEDGE      ( 0x1 << 24) // (SSC) Frame Sync Edge Detection
+// -------- SSC_TCMR : (SSC Offset: 0x18) SSC Transmit Clock Mode Register -------- 
+// -------- SSC_TFMR : (SSC Offset: 0x1c) SSC Transmit Frame Mode Register -------- 
+#define AT91C_SSC_DATDEF      ( 0x1 <<  5) // (SSC) Data Default Value
+#define AT91C_SSC_FSDEN       ( 0x1 << 23) // (SSC) Frame Sync Data Enable
+// -------- SSC_SR : (SSC Offset: 0x40) SSC Status Register -------- 
+#define AT91C_SSC_TXRDY       ( 0x1 <<  0) // (SSC) Transmit Ready
+#define AT91C_SSC_TXEMPTY     ( 0x1 <<  1) // (SSC) Transmit Empty
+#define AT91C_SSC_ENDTX       ( 0x1 <<  2) // (SSC) End Of Transmission
+#define AT91C_SSC_TXBUFE      ( 0x1 <<  3) // (SSC) Transmit Buffer Empty
+#define AT91C_SSC_RXRDY       ( 0x1 <<  4) // (SSC) Receive Ready
+#define AT91C_SSC_OVRUN       ( 0x1 <<  5) // (SSC) Receive Overrun
+#define AT91C_SSC_ENDRX       ( 0x1 <<  6) // (SSC) End of Reception
+#define AT91C_SSC_RXBUFF      ( 0x1 <<  7) // (SSC) Receive Buffer Full
+#define AT91C_SSC_CP0         ( 0x1 <<  8) // (SSC) Compare 0
+#define AT91C_SSC_CP1         ( 0x1 <<  9) // (SSC) Compare 1
+#define AT91C_SSC_TXSYN       ( 0x1 << 10) // (SSC) Transmit Sync
+#define AT91C_SSC_RXSYN       ( 0x1 << 11) // (SSC) Receive Sync
+#define AT91C_SSC_TXENA       ( 0x1 << 16) // (SSC) Transmit Enable
+#define AT91C_SSC_RXENA       ( 0x1 << 17) // (SSC) Receive Enable
+// -------- SSC_IER : (SSC Offset: 0x44) SSC Interrupt Enable Register -------- 
+// -------- SSC_IDR : (SSC Offset: 0x48) SSC Interrupt Disable Register -------- 
+// -------- SSC_IMR : (SSC Offset: 0x4c) SSC Interrupt Mask Register -------- 
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-at91rm9200/AT91RM9200_TC.h linux-2.4.29-uc1/include/asm-arm/arch-at91rm9200/AT91RM9200_TC.h
--- linux-2.4.29/include/asm-arm/arch-at91rm9200/AT91RM9200_TC.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-at91rm9200/AT91RM9200_TC.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,165 @@
+// ----------------------------------------------------------------------------
+//          ATMEL Microcontroller Software Support  -  ROUSSET  -
+// ----------------------------------------------------------------------------
+//  The software is delivered "AS IS" without warranty or condition of any
+//  kind, either express, implied or statutory. This includes without
+//  limitation any warranty or condition with respect to merchantability or
+//  fitness for any particular purpose, or against the infringements of
+//  intellectual property rights of others.
+// ----------------------------------------------------------------------------
+// File Name           : AT91RM9200.h
+// Object              : AT91RM9200 definitions
+// Generated           : AT91 SW Application Group  12/03/2002 (10:48:02)
+// 
+// ----------------------------------------------------------------------------
+
+#ifndef AT91RM9200_TC_H
+#define AT91RM9200_TC_H
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Timer Counter Channel Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+
+typedef struct _AT91S_TC {
+	AT91_REG	 TC_CCR; 	// Channel Control Register
+	AT91_REG	 TC_CMR; 	// Channel Mode Register
+	AT91_REG	 Reserved0[2]; 	// 
+	AT91_REG	 TC_CV; 	// Counter Value
+	AT91_REG	 TC_RA; 	// Register A
+	AT91_REG	 TC_RB; 	// Register B
+	AT91_REG	 TC_RC; 	// Register C
+	AT91_REG	 TC_SR; 	// Status Register
+	AT91_REG	 TC_IER; 	// Interrupt Enable Register
+	AT91_REG	 TC_IDR; 	// Interrupt Disable Register
+	AT91_REG	 TC_IMR; 	// Interrupt Mask Register
+} AT91S_TC, *AT91PS_TC;
+
+typedef struct _AT91S_TCB {
+	AT91S_TC	 TCB_TC0; 	// TC Channel 0
+	AT91_REG	 Reserved0[4]; 	// 
+	AT91S_TC	 TCB_TC1; 	// TC Channel 1
+	AT91_REG	 Reserved1[4]; 	// 
+	AT91S_TC	 TCB_TC2; 	// TC Channel 2
+	AT91_REG	 Reserved2[4]; 	// 
+	AT91_REG	 TCB_BCR; 	// TC Block Control Register
+	AT91_REG	 TCB_BMR; 	// TC Block Mode Register
+} AT91S_TCB, *AT91PS_TCB;
+
+#endif
+
+// -------- TC_CCR : (TC Offset: 0x0) TC Channel Control Register -------- 
+#define AT91C_TC_CLKEN        ( 0x1 <<  0) // (TC) Counter Clock Enable Command
+#define AT91C_TC_CLKDIS       ( 0x1 <<  1) // (TC) Counter Clock Disable Command
+#define AT91C_TC_SWTRG        ( 0x1 <<  2) // (TC) Software Trigger Command
+// -------- TC_CMR : (TC Offset: 0x4) TC Channel Mode Register: Capture Mode / Waveform Mode -------- 
+#define AT91C_TC_TCCLKS       ( 0x7 <<  0) // (TC) Clock Selection
+#define		AT91C_TC_TIMER_DIV1_CLOCK             ( 0x0 <<  0) // (TC) MCK/2
+#define		AT91C_TC_TIMER_DIV2_CLOCK             ( 0x1 <<  0) // (TC) MCK/8
+#define		AT91C_TC_TIMER_DIV3_CLOCK             ( 0x2 <<  0) // (TC) MCK/32
+#define		AT91C_TC_TIMER_DIV4_CLOCK             ( 0x3 <<  0) // (TC) MCK/128
+#define		AT91C_TC_TIMER_DIV5_CLOCK             ( 0x4 <<  0) // (TC) MCK/256 = SLOW CLOCK
+#define		AT91C_TC_TIMER_XC0                    ( 0x5 <<  0) // (TC) XC0
+#define		AT91C_TC_TIMER_XC1                    ( 0x6 <<  0) // (TC) XC1
+#define		AT91C_TC_TIMER_XC2                    ( 0x7 <<  0) // (TC) XC2
+#define	AT91C_TC_CLKI         ( 0x1 <<  3) // (TC) Clock Invert
+#define AT91C_TC_BURST        ( 0x3 <<  4) // (TC) Burst Signal Selection
+#define AT91C_TC_CPCSTOP      ( 0x1 <<  6) // (TC) Counter Clock Stopped with RC Compare
+#define AT91C_TC_CPCDIS       ( 0x1 <<  7) // (TC) Counter Clock Disable with RC Compare
+#define AT91C_TC_EEVTEDG      ( 0x3 <<  8) // (TC) External Event Edge Selection
+#define 	AT91C_TC_EEVTEDG_NONE                 ( 0x0 <<  8) // (TC) Edge: None
+#define 	AT91C_TC_EEVTEDG_RISING               ( 0x1 <<  8) // (TC) Edge: rising edge
+#define 	AT91C_TC_EEVTEDG_FALLING              ( 0x2 <<  8) // (TC) Edge: falling edge
+#define 	AT91C_TC_EEVTEDG_BOTH                 ( 0x3 <<  8) // (TC) Edge: each edge
+#define AT91C_TC_EEVT         ( 0x3 << 10) // (TC) External Event  Selection
+#define 	AT91C_TC_EEVT_NONE                 ( 0x0 << 10) // (TC) Signal selected as external event: TIOB TIOB direction: input
+#define 	AT91C_TC_EEVT_RISING               ( 0x1 << 10) // (TC) Signal selected as external event: XC0 TIOB direction: output
+#define 	AT91C_TC_EEVT_FALLING              ( 0x2 << 10) // (TC) Signal selected as external event: XC1 TIOB direction: output
+#define 	AT91C_TC_EEVT_BOTH                 ( 0x3 << 10) // (TC) Signal selected as external event: XC2 TIOB direction: output
+#define AT91C_TC_ENETRG       ( 0x1 << 12) // (TC) External Event Trigger enable
+#define AT91C_TC_WAVESEL      ( 0x3 << 13) // (TC) Waveform  Selection
+#define 	AT91C_TC_WAVESEL_UP                   ( 0x0 << 13) // (TC) UP mode without atomatic trigger on RC Compare
+#define 	AT91C_TC_WAVESEL_UP_AUTO              ( 0x1 << 13) // (TC) UP mode with automatic trigger on RC Compare
+#define 	AT91C_TC_WAVESEL_UPDOWN               ( 0x2 << 13) // (TC) UPDOWN mode without automatic trigger on RC Compare
+#define 	AT91C_TC_WAVESEL_UPDOWN_AUTO          ( 0x3 << 13) // (TC) UPDOWN mode with automatic trigger on RC Compare
+#define AT91C_TC_CPCTRG       ( 0x1 << 14) // (TC) RC Compare Trigger Enable
+#define AT91C_TC_WAVE         ( 0x1 << 15) // (TC) 
+#define AT91C_TC_ACPA         ( 0x3 << 16) // (TC) RA Compare Effect on TIOA
+#define 	AT91C_TC_ACPA_NONE                 ( 0x0 << 16) // (TC) Effect: none
+#define 	AT91C_TC_ACPA_SET                  ( 0x1 << 16) // (TC) Effect: set
+#define 	AT91C_TC_ACPA_CLEAR                ( 0x2 << 16) // (TC) Effect: clear
+#define 	AT91C_TC_ACPA_TOGGLE               ( 0x3 << 16) // (TC) Effect: toggle
+#define AT91C_TC_ACPC         ( 0x3 << 18) // (TC) RC Compare Effect on TIOA
+#define 	AT91C_TC_ACPC_NONE                 ( 0x0 << 18) // (TC) Effect: none
+#define 	AT91C_TC_ACPC_SET                  ( 0x1 << 18) // (TC) Effect: set
+#define 	AT91C_TC_ACPC_CLEAR                ( 0x2 << 18) // (TC) Effect: clear
+#define 	AT91C_TC_ACPC_TOGGLE               ( 0x3 << 18) // (TC) Effect: toggle
+#define AT91C_TC_AEEVT        ( 0x3 << 20) // (TC) External Event Effect on TIOA
+#define 	AT91C_TC_AEEVT_NONE                 ( 0x0 << 20) // (TC) Effect: none
+#define 	AT91C_TC_AEEVT_SET                  ( 0x1 << 20) // (TC) Effect: set
+#define 	AT91C_TC_AEEVT_CLEAR                ( 0x2 << 20) // (TC) Effect: clear
+#define 	AT91C_TC_AEEVT_TOGGLE               ( 0x3 << 20) // (TC) Effect: toggle
+#define AT91C_TC_ASWTRG       ( 0x3 << 22) // (TC) Software Trigger Effect on TIOA
+#define 	AT91C_TC_ASWTRG_NONE                 ( 0x0 << 22) // (TC) Effect: none
+#define 	AT91C_TC_ASWTRG_SET                  ( 0x1 << 22) // (TC) Effect: set
+#define 	AT91C_TC_ASWTRG_CLEAR                ( 0x2 << 22) // (TC) Effect: clear
+#define 	AT91C_TC_ASWTRG_TOGGLE               ( 0x3 << 22) // (TC) Effect: toggle
+#define AT91C_TC_BCPB         ( 0x3 << 24) // (TC) RB Compare Effect on TIOB
+#define 	AT91C_TC_BCPB_NONE                 ( 0x0 << 24) // (TC) Effect: none
+#define 	AT91C_TC_BCPB_SET                  ( 0x1 << 24) // (TC) Effect: set
+#define 	AT91C_TC_BCPB_CLEAR                ( 0x2 << 24) // (TC) Effect: clear
+#define 	AT91C_TC_BCPB_TOGGLE               ( 0x3 << 24) // (TC) Effect: toggle
+#define AT91C_TC_BCPC         ( 0x3 << 26) // (TC) RC Compare Effect on TIOB
+#define 	AT91C_TC_BCPC_NONE                 ( 0x0 << 26) // (TC) Effect: none
+#define 	AT91C_TC_BCPC_SET                  ( 0x1 << 26) // (TC) Effect: set
+#define 	AT91C_TC_BCPC_CLEAR                ( 0x2 << 26) // (TC) Effect: clear
+#define 	AT91C_TC_BCPC_TOGGLE               ( 0x3 << 26) // (TC) Effect: toggle
+#define AT91C_TC_BEEVT        ( 0x3 << 28) // (TC) External Event Effect on TIOB
+#define 	AT91C_TC_BEEVT_NONE                 ( 0x0 << 28) // (TC) Effect: none
+#define 	AT91C_TC_BEEVT_SET                  ( 0x1 << 28) // (TC) Effect: set
+#define 	AT91C_TC_BEEVT_CLEAR                ( 0x2 << 28) // (TC) Effect: clear
+#define 	AT91C_TC_BEEVT_TOGGLE               ( 0x3 << 28) // (TC) Effect: toggle
+#define AT91C_TC_BSWTRG       ( 0x3 << 30) // (TC) Software Trigger Effect on TIOB
+#define 	AT91C_TC_BSWTRG_NONE                 ( 0x0 << 30) // (TC) Effect: none
+#define 	AT91C_TC_BSWTRG_SET                  ( 0x1 << 30) // (TC) Effect: set
+#define 	AT91C_TC_BSWTRG_CLEAR                ( 0x2 << 30) // (TC) Effect: clear
+#define 	AT91C_TC_BSWTRG_TOGGLE               ( 0x3 << 30) // (TC) Effect: toggle
+// -------- TC_SR : (TC Offset: 0x20) TC Channel Status Register -------- 
+#define AT91C_TC_COVFS        ( 0x1 <<  0) // (TC) Counter Overflow
+#define AT91C_TC_LOVRS        ( 0x1 <<  1) // (TC) Load Overrun
+#define AT91C_TC_CPAS         ( 0x1 <<  2) // (TC) RA Compare
+#define AT91C_TC_CPBS         ( 0x1 <<  3) // (TC) RB Compare
+#define AT91C_TC_CPCS         ( 0x1 <<  4) // (TC) RC Compare
+#define AT91C_TC_LDRAS        ( 0x1 <<  5) // (TC) RA Loading
+#define AT91C_TC_LDRBS        ( 0x1 <<  6) // (TC) RB Loading
+#define AT91C_TC_ETRCS        ( 0x1 <<  7) // (TC) External Trigger
+#define AT91C_TC_ETRGS        ( 0x1 << 16) // (TC) Clock Enabling
+#define AT91C_TC_MTIOA        ( 0x1 << 17) // (TC) TIOA Mirror
+#define AT91C_TC_MTIOB        ( 0x1 << 18) // (TC) TIOA Mirror
+// -------- TC_IER : (TC Offset: 0x24) TC Channel Interrupt Enable Register -------- 
+// -------- TC_IDR : (TC Offset: 0x28) TC Channel Interrupt Disable Register -------- 
+// -------- TC_IMR : (TC Offset: 0x2c) TC Channel Interrupt Mask Register -------- 
+
+// *****************************************************************************
+//              SOFTWARE API DEFINITION  FOR Timer Counter Interface
+// *****************************************************************************
+// -------- TCB_BCR : (TCB Offset: 0xc0) TC Block Control Register -------- 
+#define AT91C_TCB_SYNC        ( 0x1 <<  0) // (TCB) Synchro Command
+// -------- TCB_BMR : (TCB Offset: 0xc4) TC Block Mode Register -------- 
+#define AT91C_TCB_TC0XC0S     ( 0x1 <<  0) // (TCB) External Clock Signal 0 Selection
+#define 	AT91C_TCB_TC0XC0S_TCLK0                ( 0x0) // (TCB) TCLK0 connected to XC0
+#define 	AT91C_TCB_TC0XC0S_NONE                 ( 0x1) // (TCB) None signal connected to XC0
+#define 	AT91C_TCB_TC0XC0S_TIOA1                ( 0x2) // (TCB) TIOA1 connected to XC0
+#define 	AT91C_TCB_TC0XC0S_TIOA2                ( 0x3) // (TCB) TIOA2 connected to XC0
+#define AT91C_TCB_TC1XC1S     ( 0x1 <<  2) // (TCB) External Clock Signal 1 Selection
+#define 	AT91C_TCB_TC1XC1S_TCLK1                ( 0x0 <<  2) // (TCB) TCLK1 connected to XC1
+#define 	AT91C_TCB_TC1XC1S_NONE                 ( 0x1 <<  2) // (TCB) None signal connected to XC1
+#define 	AT91C_TCB_TC1XC1S_TIOA0                ( 0x2 <<  2) // (TCB) TIOA0 connected to XC1
+#define 	AT91C_TCB_TC1XC1S_TIOA2                ( 0x3 <<  2) // (TCB) TIOA2 connected to XC1
+#define AT91C_TCB_TC2XC2S     ( 0x1 <<  4) // (TCB) External Clock Signal 2 Selection
+#define 	AT91C_TCB_TC2XC2S_TCLK2                ( 0x0 <<  4) // (TCB) TCLK2 connected to XC2
+#define 	AT91C_TCB_TC2XC2S_NONE                 ( 0x1 <<  4) // (TCB) None signal connected to XC2
+#define 	AT91C_TCB_TC2XC2S_TIOA0                ( 0x2 <<  4) // (TCB) TIOA0 connected to XC2
+#define 	AT91C_TCB_TC2XC2S_TIOA2                ( 0x3 <<  4) // (TCB) TIOA2 connected to XC2
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-at91rm9200/csb337.h linux-2.4.29-uc1/include/asm-arm/arch-at91rm9200/csb337.h
--- linux-2.4.29/include/asm-arm/arch-at91rm9200/csb337.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-at91rm9200/csb337.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,82 @@
+/*
+ * linux/include/asm-arm/arch-at91rm9200/csb337.h
+ *
+ *  Copyright (c) 2003 Christopher Bahns & David Knickerbocker
+ *                     Polaroid Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_CSB337_H
+#define __ASM_ARCH_HARDWARE_CSB337_H
+
+
+/* AT91RM92000 clocks on CSB337 */
+#define AT91C_MAIN_CLOCK	184320000
+#define AT91C_MASTER_CLOCK	46080000	/* peripheral clock (AT91C_MAIN_CLOCK / 4) */
+#define AT91C_SLOW_CLOCK	32768		/* slow clock */
+
+
+/* FLASH */
+#define AT91_FLASH_BASE		0x10000000	// NCS0: Flash physical base address
+
+/* SDRAM */
+#define AT91_SDRAM_BASE		0x20000000	// NCS1: SDRAM physical base address
+
+/* SmartMedia */
+#define AT91_SMARTMEDIA_BASE	0x40000000	// NCS3: Smartmedia physical base address
+
+/* Multi-Master Memory controller */
+#define AT91_UHP_BASE		0x00300000	// USB Host controller
+
+
+/* Peripheral interrupt configuration */
+#define AT91_SMR_FIQ	(AT91C_AIC_PRIOR_HIGHEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (FIQ)
+#define AT91_SMR_SYS	(AT91C_AIC_PRIOR_HIGHEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// System Peripheral
+#define AT91_SMR_PIOA	(AT91C_AIC_PRIOR_LOWEST	 | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Parallel IO Controller A
+#define AT91_SMR_PIOB	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Parallel IO Controller B
+#define AT91_SMR_PIOC	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Parallel IO Controller C
+#define AT91_SMR_PIOD	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Parallel IO Controller D
+#define AT91_SMR_US0	(AT91C_AIC_PRIOR_6       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// USART 0
+#define AT91_SMR_US1	(AT91C_AIC_PRIOR_6       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// USART 1
+#define AT91_SMR_US2	(AT91C_AIC_PRIOR_6       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// USART 2
+#define AT91_SMR_US3	(AT91C_AIC_PRIOR_6       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// USART 3
+#define AT91_SMR_MCI	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Multimedia Card Interface
+#define AT91_SMR_UDP	(AT91C_AIC_PRIOR_4       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// USB Device Port
+#define AT91_SMR_TWI	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Two-Wire Interface
+#define AT91_SMR_SPI	(AT91C_AIC_PRIOR_6       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Serial Peripheral Interface
+#define AT91_SMR_SSC0	(AT91C_AIC_PRIOR_5       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Serial Synchronous Controller 0
+#define AT91_SMR_SSC1	(AT91C_AIC_PRIOR_5       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Serial Synchronous Controller 1
+#define AT91_SMR_SSC2	(AT91C_AIC_PRIOR_5       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Serial Synchronous Controller 2
+#define AT91_SMR_TC0	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Timer Counter 0
+#define AT91_SMR_TC1	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Timer Counter 1
+#define AT91_SMR_TC2	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Timer Counter 2
+#define AT91_SMR_TC3	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Timer Counter 3
+#define AT91_SMR_TC4	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Timer Counter 4
+#define AT91_SMR_TC5	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Timer Counter 5
+#define AT91_SMR_UHP	(AT91C_AIC_PRIOR_3       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// USB Host port
+#define AT91_SMR_EMAC	(AT91C_AIC_PRIOR_3       | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Ethernet MAC
+#define AT91_SMR_IRQ0	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (IRQ0)
+#define AT91_SMR_IRQ1	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (IRQ1)
+#define AT91_SMR_IRQ2	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (IRQ2)
+#define AT91_SMR_IRQ3	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (IRQ3)
+#define AT91_SMR_IRQ4	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (IRQ4)
+#define AT91_SMR_IRQ5	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (IRQ5)
+#define AT91_SMR_IRQ6	(AT91C_AIC_PRIOR_LOWEST  | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE)	// Advanced Interrupt Controller (IRQ6)
+
+
+#define AT91C_CONSOLE_DEFAULT_BAUDRATE 38400
+
+/*
+ * Serial port configuration.
+ *    0 .. 3 = USART0 .. USART3
+ *    4      = DBGU
+ */
+#define AT91C_UART_MAP		{ 4, 1, -1, -1, -1 }	/* ttyS0, ..., ttyS4 */
+#define AT91C_CONSOLE		0			/* ttyS0 */
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-at91rm9200/hardware.h linux-2.4.29-uc1/include/asm-arm/arch-at91rm9200/hardware.h
--- linux-2.4.29/include/asm-arm/arch-at91rm9200/hardware.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-at91rm9200/hardware.h	2005-06-14 02:11:23.000000000 +0100
@@ -60,6 +60,7 @@
 
 
 #define AT91C_BASE_SRAM		0x00200000	/* Internal SRAM base address */
+#define AT91C_SRAM_SIZE		0x00004000	/* Internal SRAM SIZE (16Kb) */
 
 #define AT91C_NR_UART		5		/* 4 USART3's and one DBGU port */
 
@@ -82,5 +83,8 @@
 #include <asm/arch/at91rm9200dk.h>
 #endif
 
+#ifdef CONFIG_MACH_CSB337
+#include <asm/arch/csb337.h>
+#endif
 
 #endif
diff -urN linux-2.4.29/include/asm-arm/arch-at91rm9200/pio.h linux-2.4.29-uc1/include/asm-arm/arch-at91rm9200/pio.h
--- linux-2.4.29/include/asm-arm/arch-at91rm9200/pio.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-at91rm9200/pio.h	2005-06-14 02:11:23.000000000 +0100
@@ -66,6 +66,18 @@
 }
 
 /*
+ * Configure interrupt from Ethernet PHY.
+ */
+static inline void AT91_CfgPIO_EMAC_PHY(void) {
+	AT91_SYS->PMC_PCER = 1 << AT91C_ID_PIOC;	/* enable peripheral clock */
+#ifdef CONFIG_MACH_CSB337
+	AT91_SYS->PIOC_ODR = AT91C_PIO_PC2;
+#else
+	AT91_SYS->PIOC_ODR = AT91C_PIO_PC4;
+#endif
+}
+
+/*
  * Enable the Two-Wire interface.
  */
 static inline void AT91_CfgPIO_TWI(void) {
diff -urN linux-2.4.29/include/asm-arm/arch-at91rm9200/time.h linux-2.4.29-uc1/include/asm-arm/arch-at91rm9200/time.h
--- linux-2.4.29/include/asm-arm/arch-at91rm9200/time.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-at91rm9200/time.h	2005-06-14 02:11:23.000000000 +0100
@@ -27,6 +27,21 @@
 extern unsigned long (*gettimeoffset)(void);
 
 /*
+ * The ST_CRTR is updated asynchronously to the master clock.  It is therefore
+ *  necessary to read it twice (with the same value) to ensure accuracy.
+ */ 
+static inline unsigned long read_CRTR(void) {
+	unsigned long x1, x2;
+
+	do {
+		x1 = AT91_SYS->ST_CRTR;
+		x2 = AT91_SYS->ST_CRTR;
+	} while (x1 != x2);
+
+	return x1;
+}
+
+/*
  * Returns number of microseconds since last timer interrupt.  Note that interrupts
  * will have been disabled by do_gettimeofday()
  *  'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy.
@@ -36,7 +51,7 @@
 {
 	unsigned long elapsed;
 
-	elapsed = (AT91_SYS->ST_CRTR - AT91_SYS->ST_RTAR) & AT91C_ST_ALMV;
+	elapsed = (read_CRTR() - AT91_SYS->ST_RTAR) & AT91C_ST_ALMV;
 
 	return (unsigned long)(elapsed * tick) / LATCH;
 }
@@ -48,11 +63,12 @@
 {
 	if (AT91_SYS->ST_SR & AT91C_ST_PITS) {	/* This is a shared interrupt */
 		do {
+			do_leds();
 			do_timer(regs);
 
 			AT91_SYS->ST_RTAR = (AT91_SYS->ST_RTAR + LATCH) & AT91C_ST_ALMV;
 
-		} while (((AT91_SYS->ST_CRTR - AT91_SYS->ST_RTAR) & AT91C_ST_ALMV) >= LATCH);
+		} while (((read_CRTR() - AT91_SYS->ST_RTAR) & AT91C_ST_ALMV) >= LATCH);
 
 		do_profile(regs);
 	}
diff -urN linux-2.4.29/include/asm-arm/arch-cl7500/io.h linux-2.4.29-uc1/include/asm-arm/arch-cl7500/io.h
--- linux-2.4.29/include/asm-arm/arch-cl7500/io.h	2001-08-12 19:14:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-cl7500/io.h	2005-06-14 02:11:23.000000000 +0100
@@ -239,4 +239,13 @@
 /* the following macro is depreciated */
 #define ioaddr(port)			__ioaddr((port))
 
+#define insw(p,d,l)			__raw_readsw(__ioaddr((p)),d,l)
+#define outsw(p,d,l)			__raw_writesw(__ioaddr((p)),d,l)
+
+#define __mem_pci(a)			((unsigned long)(a))
+#define __mem_isa(a)			((unsigned long)(a))
+
+#define iomem_valid_addr(iomem,size)	(1)
+#define iomem_to_phys(iomem)		(iomem)
+
 #endif
diff -urN linux-2.4.29/include/asm-arm/arch-cl7500/system.h linux-2.4.29-uc1/include/asm-arm/arch-cl7500/system.h
--- linux-2.4.29/include/asm-arm/arch-cl7500/system.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-cl7500/system.h	2005-06-14 02:11:23.000000000 +0100
@@ -6,6 +6,7 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
+#include <asm/io.h>
 #include <asm/hardware/iomd.h>
 
 static inline void arch_idle(void)
diff -urN linux-2.4.29/include/asm-arm/arch-cl7500/time.h linux-2.4.29-uc1/include/asm-arm/arch-cl7500/time.h
--- linux-2.4.29/include/asm-arm/arch-cl7500/time.h	2001-08-12 19:14:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-cl7500/time.h	2005-06-14 02:11:23.000000000 +0100
@@ -17,7 +17,7 @@
 
 	{
 		/* Twinkle the lights. */
-		static int count, state = 0xff00;
+		static int count = 1, state = 0xff00;
 		if (count-- == 0) {
 			state ^= 0x100;
 			count = 25;
diff -urN linux-2.4.29/include/asm-arm/arch-cl7500/uncompress.h linux-2.4.29-uc1/include/asm-arm/arch-cl7500/uncompress.h
--- linux-2.4.29/include/asm-arm/arch-cl7500/uncompress.h	2002-08-03 01:39:45.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-cl7500/uncompress.h	2005-06-14 02:11:23.000000000 +0100
@@ -5,7 +5,7 @@
  */
 
 #define BASE 0x03010000
-#define SERBASE (BASE + (0x2f8 << 2))
+#define SERBASE (BASE + (0x3f8 << 2))
 
 static __inline__ void putc(char c)
 {
diff -urN linux-2.4.29/include/asm-arm/arch-clps711x/hardware.h linux-2.4.29-uc1/include/asm-arm/arch-clps711x/hardware.h
--- linux-2.4.29/include/asm-arm/arch-clps711x/hardware.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-clps711x/hardware.h	2005-06-14 02:11:26.000000000 +0100
@@ -65,6 +65,11 @@
 #define EP7212_BASE		CLPS7111_VIRT_BASE
 #include <asm/hardware/ep7212.h>
 
+#elif defined (CONFIG_ARCH_EP7312)
+
+#define EP7312_VIRT_BASE        CLPS7111_VIRT_BASE
+#define EP7312_BASE             CLPS7111_VIRT_BASE
+#include <asm/hardware/ep7312.h>
 
 #endif
 
@@ -176,6 +181,29 @@
 
 #endif /* CONFIG_ARCH_EDB7211 */
 
+#if defined (CONFIG_ARCH_EDB7312)
+
+/*
+ * nCS0..nCS7
+ */
+#define EP7312_VIRT_CS0		0xfe000000
+#define EP7312_VIRT_CS1		0xfd000000
+#define EP7312_VIRT_CS2		0xfc000000
+#define EP7312_VIRT_CS3		0xfb000000
+#define	EP7312_VIRT_CS4		0xfa000000
+#define EP7312_VIRT_CS5		0xf9000000
+#define	EP7312_VIRT_CS6		0xf8000000
+#define EP7312_VIRT_CS7		0xf7000000
+
+/*
+ * devices
+ */
+#define EDB7312_VIRT_CS8900A	EP7312_VIRT_CS2
+#define EDB7312_VIRT_PDIUSBD12	EP7312_VIRT_CS4
+#define EDB7312_VIRT_8042	(EP7312_VIRT_CS4 + 0x10000)
+#define EDB7312_VIRT_IDE	EP7312_VIRT_CS5
+
+#endif /* CONFIG_ARCH_EDB7312 */
 
 /*
  * Relevant bits in port D, which controls power to the various parts of
diff -urN linux-2.4.29/include/asm-arm/arch-clps711x/ide.h linux-2.4.29-uc1/include/asm-arm/arch-clps711x/ide.h
--- linux-2.4.29/include/asm-arm/arch-clps711x/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-clps711x/ide.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,57 @@
+/*
+ *  EDB7312 IDE support
+ *  based on:
+ *
+ *  linux/include/asm-arm/arch-sa1100/ide.h
+ *  Copyright (c) 1998 Hugo Fiennes & Nicolas Pitre
+ *
+ *  Copyright (c) 2003 Vladimir Ivanov <vladitx@nucleusys.com>
+ */
+
+#include <linux/config.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+/*
+ * Set up a hw structure for a specified data port, control port and IRQ.
+ * This should follow whatever the default interface uses.
+ */
+static __inline__ void
+ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int *irq)
+{
+	ide_ioreg_t reg;
+	int i;
+	int regincr = 1;
+	
+	memset(hw, 0, sizeof(*hw));
+
+	reg = (ide_ioreg_t)data_port;
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = reg;
+		reg += regincr;
+	}
+	
+	hw->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t) ctrl_port;
+	
+	if (irq)
+		*irq = 0;
+}
+
+/*
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ */
+static __inline__ void
+ide_init_default_hwifs(void)
+{
+    if( machine_is_edb7312() ){
+	hw_regs_t hw;
+	
+	ide_init_hwif_ports(&hw, EDB7312_VIRT_IDE + 0x0, EDB7312_VIRT_IDE + 0xE, NULL);
+	hw.irq = IRQ_EINT2;
+	ide_register_hw(&hw, NULL);
+    }
+}
+
diff -urN linux-2.4.29/include/asm-arm/arch-clps711x/irqs.h linux-2.4.29-uc1/include/asm-arm/arch-clps711x/irqs.h
--- linux-2.4.29/include/asm-arm/arch-clps711x/irqs.h	2002-08-03 01:39:45.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-clps711x/irqs.h	2005-06-14 02:11:26.000000000 +0100
@@ -51,3 +51,4 @@
 
 #define NR_IRQS                         30
 
+#define	FIQ_START			64
diff -urN linux-2.4.29/include/asm-arm/arch-clps711x/system.h linux-2.4.29-uc1/include/asm-arm/arch-clps711x/system.h
--- linux-2.4.29/include/asm-arm/arch-clps711x/system.h	2003-06-13 15:51:38.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-clps711x/system.h	2005-06-14 02:11:26.000000000 +0100
@@ -28,8 +28,8 @@
 {
 	clps_writel(1, HALT);
 	__asm__ __volatile__(
-	"mov	r0, r0
-	mov	r0, r0");
+	"mov	r0, r0\n\t"
+	"mov	r0, r0");
 }
 
 static inline void arch_reset(char mode)
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/a.out.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/a.out.h
--- linux-2.4.29/include/asm-arm/arch-dm270/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/a.out.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * uclinux/include/asm-armnommu/arch-dm270/a.out.h
+ *
+ */
+#ifndef __ASM_ARCH_A_OUT_H
+#define __ASM_ARCH_A_OUT_H
+
+#ifdef __KERNEL__
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/blkmem.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/blkmem.h
--- linux-2.4.29/include/asm-arm/arch-dm270/blkmem.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/blkmem.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,41 @@
+/***********************************************************************
+ * linux/include/asm-arm/arch-dm270/blkmem.h
+ *
+ *   Contains configuration settings for the blkmem driver
+ *
+ *   Derived from asm/arch-armnommu/arch-ta7s/blkmem.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#ifndef __ASM_ARCH_BLKMEM_H
+#define __ASM_ARCH_BLKMEM_H
+
+extern char _ebss;
+
+#define FIXUP_ARENAS \
+	arena[0].address = (unsigned long) &_ebss;
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/dma.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/dma.h
--- linux-2.4.29/include/asm-arm/arch-dm270/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/dma.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,62 @@
+/***********************************************************************
+ * asm/arch-armnommu/arch-dm270/dma.h:
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/dma.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#include "linux/config.h"
+
+/* type dmamode_t is declared in include/asm-armnommu along with values.
+ * Some additional DMA mode values are declared here.
+ */
+
+#define DMA_MODE_CARD_TO_SDRAM  0x08
+#define DMA_MODE_SDRAM_TO_CARD  0x0c
+#define DMA_MODE_FLASH_TO_SDRAM 0x10
+#define DMA_MODE_SDRAM_TO_FLASH 0x14
+
+/* MAX_DMA_ADDRESS -- max address we can program into the DMA address
+ * registers? Not sure. Various drivers use this value as a test before
+ * setting up a DMA. Also, the macros in linux/bootmem.h use this value
+ * as a goal for many of the bootmem allocations.
+ */
+
+/* Configured memory is specified during configuration. */
+
+#define MAX_DMA_ADDRESS (DRAM_BASE + DRAM_SIZE - 1)
+
+/* MAX_DMA_CHANNELS -- # of DMA control register sets we possess.
+ * We have one that can run in either direction and between two different
+ * destinations.
+ */
+
+#define MAX_DMA_CHANNELS 1
+
+#endif /* __ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/gio_ioctl.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/gio_ioctl.h
--- linux-2.4.29/include/asm-arm/arch-dm270/gio_ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/gio_ioctl.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,90 @@
+/************************************************************************
+ * include/asm-armnommu/arch-dm270/gio_ioctl.h
+ *
+ * Definitions of the General Purpose I/O (GIO) for the TI TMS320DM270.
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/gio_ioctl.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ************************************************************************/
+
+#ifndef __ASM_ARCH_GIO_IOCTL_H
+#define __ASM_ARCH_GIO_IOCTL_H
+ 
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <asm/ioctl.h>
+ 
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+#define GIO_MAGIC_NUMBER 'g'
+
+/* Major numbers, (from Documentation/devices.txt local/experimental list)  */
+ 
+#define GIO_MAJOR     125
+ 
+/************************************************************************
+ * GIO_DIRECTION: The GIO_DIRECTION can be either input (GIO_INPUT) or
+ * output (GIO_OUTPUT).  If unspecified, the GIO will default to input.
+ */
+
+#define GIO_OUTPUT 0
+#define GIO_INPUT 1
+
+#define GIO_DIRECTION _IO(GIO_MAGIC_NUMBER, 0)
+ 
+/************************************************************************
+ * GIO_BITSET: If the direction is set to output, this ioctl will set the
+ * output.  If the direction is input, this ioctl will return the value
+ * of the GIO pin (0, 1, or -1 on error).
+ */
+
+#define GIO_BITSET _IO(GIO_MAGIC_NUMBER, 1)
+
+/************************************************************************
+ * GIO_BITCLR: If the direction is set to output, this ioctl will clear the
+ * output.  If the direction is input, this ioctl will return the value
+ * of the GIO pin (0, 1, or -1 on error).
+ */
+
+#define GIO_BITCLR _IO(GIO_MAGIC_NUMBER, 2)
+
+/************************************************************************
+ * GIO_IRQPORT: Configure a GIO as an interrupt.  Only GIO0-GIO3 can
+ * be configured as an interrupting source.
+ */
+
+#define GIO_NOINTERRUPT 0
+#define GIO_INTERRUPT 1
+
+#define GIO_IRQPORT _IO(GIO_MAGIC_NUMBER, 3)
+
+#define GIO_IOC_MAXNR 3
+ 
+#endif /* __ASM_ARCH_GIO_IOCTL_H */
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/hardware.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/hardware.h
--- linux-2.4.29/include/asm-arm/arch-dm270/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/hardware.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,889 @@
+/***********************************************************************
+ * linux/include/asm-armnommu/arch-dm270/hardware.h
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/irq.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <linux/config.h>
+#include <asm/mach-types.h>
+
+/* HARD_RESET_N0W: This is used in drivers/block/block.c.
+ */
+
+#define HARD_RESET_NOW()
+
+/* TI TMS320DM270 Peripheral Registers ------------------------------------- */
+
+#define DM270_REG_BASE                  0x00030000
+
+/* Clock Controller -------------------------------------------------------- */
+
+#define DM270_CLKC_BASE                 (DM270_REG_BASE + 0x0880)
+
+#define DM270_CLKC_OFFSET_PLLA          0x0000
+#define DM270_CLKC_OFFSET_PLLB          0x0002
+#define DM270_CLKC_OFFSET_CLKC          0x0004
+#define DM270_CLKC_OFFSET_SEL           0x0006
+#define DM270_CLKC_OFFSET_DIV           0x0008
+#define DM270_CLKC_OFFSET_BYP           0x000a
+#define DM270_CLKC_OFFSET_MMCCLK        0x000c
+#define DM270_CLKC_OFFSET_MSCLK         0x000e
+#define DM270_CLKC_OFFSET_MOD0          0x0010
+#define DM270_CLKC_OFFSET_MOD1          0x0012
+#define DM270_CLKC_OFFSET_MOD2          0x0014
+#define DM270_CLKC_OFFSET_LPCTL0        0x0016
+#define DM270_CLKC_OFFSET_LPCTL1        0x0018
+#define DM270_CLKC_OFFSET_OSEL          0x001a
+#define DM270_CLKC_OFFSET_O0DIV         0x001c
+#define DM270_CLKC_OFFSET_O1DIV         0x001e
+#define DM270_CLKC_OFFSET_O2DIV         0x0020
+#define DM270_CLKC_OFFSET_PWM0C         0x0022
+#define DM270_CLKC_OFFSET_PWM0H         0x0024
+#define DM270_CLKC_OFFSET_PWM1C         0x0026
+#define DM270_CLKC_OFFSET_PWM1H         0x0028
+
+#define DM270_CLKC_PLLA                 (DM270_CLKC_BASE + DM270_CLKC_OFFSET_PLLA)
+#define DM270_CLKC_PLLB                 (DM270_CLKC_BASE + DM270_CLKC_OFFSET_PLLB)
+#define DM270_CLKC_CLKC                 (DM270_CLKC_BASE + DM270_CLKC_OFFSET_CLKC)
+#define DM270_CLKC_SEL                  (DM270_CLKC_BASE + DM270_CLKC_OFFSET_SEL)
+#define DM270_CLKC_DIV                  (DM270_CLKC_BASE + DM270_CLKC_OFFSET_DIV)
+#define DM270_CLKC_BYP                  (DM270_CLKC_BASE + DM270_CLKC_OFFSET_BYP)
+#define DM270_CLKC_MMCCLK               (DM270_CLKC_BASE + DM270_CLKC_OFFSET_MMCCLK)
+#define DM270_CLKC_MSCLK                (DM270_CLKC_BASE + DM270_CLKC_OFFSET_MSCLK)
+#define DM270_CLKC_MOD0                 (DM270_CLKC_BASE + DM270_CLKC_OFFSET_MOD0)
+#define DM270_CLKC_MOD1                 (DM270_CLKC_BASE + DM270_CLKC_OFFSET_MOD1)
+#define DM270_CLKC_MOD2                 (DM270_CLKC_BASE + DM270_CLKC_OFFSET_MOD2)
+#define DM270_CLKC_LPCTL0               (DM270_CLKC_BASE + DM270_CLKC_OFFSET_LPCTL0)
+#define DM270_CLKC_LPCTL1               (DM270_CLKC_BASE + DM270_CLKC_OFFSET_LPCTL1)
+#define DM270_CLKC_OSEL                 (DM270_CLKC_BASE + DM270_CLKC_OFFSET_OSEL)
+#define DM270_CLKC_O0DIV                (DM270_CLKC_BASE + DM270_CLKC_OFFSET_O0DIV)
+#define DM270_CLKC_O1DIV                (DM270_CLKC_BASE + DM270_CLKC_OFFSET_O1DIV)
+#define DM270_CLKC_O2DIV                (DM270_CLKC_BASE + DM270_CLKC_OFFSET_O2DIV)
+#define DM270_CLKC_PWM0C                (DM270_CLKC_BASE + DM270_CLKC_OFFSET_PWM0C)
+#define DM270_CLKC_PWM0H                (DM270_CLKC_BASE + DM270_CLKC_OFFSET_PWM0H)
+#define DM270_CLKC_PWM1C                (DM270_CLKC_BASE + DM270_CLKC_OFFSET_PWM1C)
+#define DM270_CLKC_PWM1H                (DM270_CLKC_BASE + DM270_CLKC_OFFSET_PWM1H)
+
+#define DM270_CLKC_CLKC_CTM0S           0x0020
+#define DM270_CLKC_CLKC_CTM3S           0x0100
+#define DM270_CLKC_CLKC_CUAS0           0x0200
+#define DM270_CLKC_CLKC_CMSS            0x0800
+#define DM270_CLKC_CLKC_CMCIV           0x4000
+#define DM270_CLKC_BYP_CAB              0x0001
+#define DM270_CLKC_BYP_CDB              0x0010
+#define DM270_CLKC_BYP_CSB              0x0100
+#define DM270_CLKC_BYP_CMB              0x1000
+#define DM270_CLKC_MOD0_CACORE          0x0001
+#define DM270_CLKC_MOD0_CBUSC           0x0002
+#define DM270_CLKC_MOD0_CICA            0x0004
+#define DM270_CLKC_MOD0_CADMAC          0x0008
+#define DM270_CLKC_MOD0_CATM            0x0010
+#define DM270_CLKC_MOD0_CINTC           0x0020
+#define DM270_CLKC_MOD0_CEMIF           0x0040
+#define DM270_CLKC_MOD0_CSDRC           0x0080
+#define DM270_CLKC_MOD0_CEHIF           0x0100
+#define DM270_CLKC_MOD0_C5409           0x0200
+#define DM270_CLKC_MOD0_CHPIB           0x0400
+#define DM270_CLKC_MOD0_TEST            0x8000
+#define DM270_CLKC_MOD0_RSV_MASK        0x7800
+#define DM270_CLKC_MOD2_CTMR0           0x0002
+#define DM270_CLKC_MOD2_CTMR3           0x0010
+#define DM270_CLKC_MOD2_CGIO            0x0020
+#define DM270_CLKC_MOD2_CUAS0           0x0200
+#define DM270_CLKC_MOD2_CUAT0           0x0080
+#define DM270_CLKC_MOD2_RSV_MASK        0xc000
+
+#define DM270_CLKC_CLKC_CUAS            DM270_CLKC_CLKC_CUAS0
+#define DM270_CLKC_MOD2_CUAS            DM270_CLKC_MOD2_CUAS0
+#define DM270_CLKC_MOD2_CUAT            DM270_CLKC_MOD2_CUAT0
+
+/* Watch Dog Timer --------------------------------------------------------- */
+
+#define DM270_WDT_BASE                  (DM270_REG_BASE + 0x0400)
+
+#define DM270_WDT_OFFSET_WDTMD          0x0000
+#define DM270_WDT_OFFSET_WDTRST         0x0002
+#define DM270_WDT_OFFSET_WDTPRSCL       0x0004
+#define DM270_WDT_OFFSET_WDTVAL         0x0006
+#define DM270_WDT_OFFSET_WDTEXRST       0x0008
+
+#define DM270_WDT_WDTMD                 (DM270_WDT_BASE + DM270_WDT_OFFSET_WDTMD)
+#define DM270_WDT_WDTRST                (DM270_WDT_BASE + DM270_WDT_OFFSET_WDTRST)
+#define DM270_WDT_WDTPRSCL              (DM270_WDT_BASE + DM270_WDT_OFFSET_WDTPRSCL)
+#define DM270_WDT_WDTVAL                (DM270_WDT_BASE + DM270_WDT_OFFSET_WDTVAL)
+#define DM270_WDT_WDTEXRST              (DM270_WDT_BASE + DM270_WDT_OFFSET_WDTEXRST)
+
+/* External Memory Interface ----------------------------------------------- */
+
+#define DM270_EMIF_BASE                 (DM270_REG_BASE + 0x0a00)
+
+#define DM270_EMIF_OFFSET_CS3CTRL2      0x0010
+#define DM270_EMIF_OFFSET_CS4CTRL1      0x0012
+#define DM270_EMIF_OFFSET_CS4CTRL2      0x0014
+
+#define DM270_EMIF_CS0CTRL1             (DM270_EMIF_BASE + 0x0000)
+#define DM270_EMIF_CS0CTRL2             (DM270_EMIF_BASE + 0x0002)
+#define DM270_EMIF_CS1CTRL1A            (DM270_EMIF_BASE + 0x0004)
+#define DM270_EMIF_CS1CTRL1B            (DM270_EMIF_BASE + 0x0006)
+#define DM270_EMIF_CS1CTRL2             (DM270_EMIF_BASE + 0x0008)
+#define DM270_EMIF_CS2CTRL1             (DM270_EMIF_BASE + 0x000a)
+#define DM270_EMIF_CS2CTRL2             (DM270_EMIF_BASE + 0x000c)
+#define DM270_EMIF_CS3CTRL1             (DM270_EMIF_BASE + 0x000e)
+#define DM270_EMIF_CS3CTRL2             (DM270_EMIF_BASE + DM270_EMIF_OFFSET_CS3CTRL2)
+#define DM270_EMIF_CS4CTRL1             (DM270_EMIF_BASE + DM270_EMIF_OFFSET_CS4CTRL1)
+#define DM270_EMIF_CS4CTRL2             (DM270_EMIF_BASE + DM270_EMIF_OFFSET_CS4CTRL2)
+#define DM270_EMIF_BUSCTRL              (DM270_EMIF_BASE + 0x0016)
+#define DM270_EMIF_BUSRLS               (DM270_EMIF_BASE + 0x0018)
+#define DM270_EMIF_CFCTRL1              (DM270_EMIF_BASE + 0x001a)
+#define DM270_EMIF_CFCTRL2              (DM270_EMIF_BASE + 0x001c)
+#define DM270_EMIF_SMCTRL               (DM270_EMIF_BASE + 0x001e)
+#define DM270_EMIF_BUSINTEN             (DM270_EMIF_BASE + 0x0020)
+#define DM270_EMIF_BUSSTS               (DM270_EMIF_BASE + 0x0024)
+#define DM270_EMIF_BUSWAITMD            (DM270_EMIF_BASE + 0x0026)
+#define DM270_EMIF_ECC1CP               (DM270_EMIF_BASE + 0x0028)
+#define DM270_EMIF_ECC1LP               (DM270_EMIF_BASE + 0x002a)
+#define DM270_EMIF_ECC2CP               (DM270_EMIF_BASE + 0x002c)
+#define DM270_EMIF_ECC2LP               (DM270_EMIF_BASE + 0x002e)
+#define DM270_EMIF_ECCCLR               (DM270_EMIF_BASE + 0x0030)
+#define DM270_EMIF_PAGESZ               (DM270_EMIF_BASE + 0x0032)
+#define DM270_EMIF_IMGDSPDEST           (DM270_EMIF_BASE + 0x0034)
+#define DM270_EMIF_PRIOCTL              (DM270_EMIF_BASE + 0x0036)
+#define DM270_EMIF_SOURCEADDH           (DM270_EMIF_BASE + 0x0038)
+#define DM270_EMIF_SOURCEADDL           (DM270_EMIF_BASE + 0x003a)
+#define DM270_EMIF_DESTADDH             (DM270_EMIF_BASE + 0x003c)
+#define DM270_EMIF_DESTADDL             (DM270_EMIF_BASE + 0x003e)
+#define DM270_EMIF_DMASIZE              (DM270_EMIF_BASE + 0x0040)
+#define DM270_EMIF_DMADEVSEL            (DM270_EMIF_BASE + 0x0042)
+#define DM270_EMIF_DMACTL               (DM270_EMIF_BASE + 0x0044)
+#define DM270_EMIF_IMGDSPADDH           (DM270_EMIF_BASE + 0x0046)
+#define DM270_EMIF_IMGDSPADDL           (DM270_EMIF_BASE + 0x0048)
+#define DM270_EMIF_DPSTR0               (DM270_EMIF_BASE + 0x004a)
+#define DM270_EMIF_DPSTR1               (DM270_EMIF_BASE + 0x004c)
+#define DM270_EMIF_DPSTR2               (DM270_EMIF_BASE + 0x004e)
+#define DM270_EMIF_DPSTR3               (DM270_EMIF_BASE + 0x0050)
+#define DM270_EMIF_DPSTR4               (DM270_EMIF_BASE + 0x0052)
+#define DM270_EMIF_DPSTR5               (DM270_EMIF_BASE + 0x0054)
+
+#define DM270_EMIF_CS0CTRL1_CYCL_MASK   0x000f
+#define DM270_EMIF_CS0CTRL1_CEC_MASK    0x00f0
+#define DM270_EMIF_CS0CTRL1_WEC_MASK    0x0f00
+#define DM270_EMIF_CS0CTRL1_OEC_MASK    0xf000
+
+#define DM270_EMIF_CS2CTRL1_RSV_MASK    0x00f0
+
+#define DM270_EMIF_CS0CTRL2_CESU_MASK   0x000f
+#define DM270_EMIF_CS0CTRL2_WESU_MASK   0x00f0
+#define DM270_EMIF_CS0CTRL2_OESU_MASK   0x0f00
+#define DM270_EMIF_CS0CTRL2_IDLE_MASK   0x3000
+#define DM270_EMIF_CS0CTRL2_RSV_MASK    0xc000
+
+#define DM270_EMIF_CS1CTRL1A_CYCL_MASK  0x001f
+#define DM270_EMIF_CS1CTRL1A_CEC_MASK   0x1f00
+#define DM270_EMIF_CS1CTRL1A_RSV_MASK   0xe0e0
+
+#define DM270_EMIF_CS1CTRL1B_WEC_MASK   0x001f
+#define DM270_EMIF_CS1CTRL1B_OEC_MASK   0x1f00
+#define DM270_EMIF_CS1CTRL1B_RSV_MASK   0xe0e0
+
+#define DM270_EMIF_CS1CTRL2_CESU_MASK   0x000f
+#define DM270_EMIF_CS1CTRL2_WESU_MASK   0x00f0
+#define DM270_EMIF_CS1CTRL2_OESU_MASK   0x0f00
+#define DM270_EMIF_CS1CTRL2_IDLE_MASK   0x3000
+#define DM270_EMIF_CS1CTRL2_RSV_MASK    0xc000
+
+#define DM270_EMIF_CS2CTRL1_CYCL_MASK   0x000f
+#define DM270_EMIF_CS2CTRL1_WEC_MASK    0x0f00
+#define DM270_EMIF_CS2CTRL1_OEC_MASK    0xf000
+#define DM270_EMIF_CS2CTRL1_RSV_MASK    0x00f0
+
+#define DM270_EMIF_CS2CTRL2_RESU_MASK   0x000f
+#define DM270_EMIF_CS2CTRL2_WESU_MASK   0x00f0
+#define DM270_EMIF_CS2CTRL2_OESU_MASK   0x0f00
+#define DM270_EMIF_CS2CTRL2_IDLE_MASK   0x3000
+#define DM270_EMIF_CS2CTRL2_RSV_MASK    0xc000
+
+#define DM270_EMIF_CS3CTRL1_CYCL_MASK   0x000f
+#define DM270_EMIF_CS3CTRL1_CEC_MASK    0x00f0
+#define DM270_EMIF_CS3CTRL1_WEC_MASK    0x0f00
+#define DM270_EMIF_CS3CTRL1_OEC_MASK    0xf000
+
+#define DM270_EMIF_CS3CTRL2_BUSW        0x4000
+#define DM270_EMIF_CS3CTRL2_CESU_MASK   0x000f
+#define DM270_EMIF_CS3CTRL2_WESU_MASK   0x00f0
+#define DM270_EMIF_CS3CTRL2_OESU_MASK   0x0f00
+#define DM270_EMIF_CS3CTRL2_IDLE_MASK   0x3000
+#define DM270_EMIF_CS3CTRL2_RSV_MASK    0x8000
+#define DM270_EMIF_CS3CTRL2_WESU1       0x0010
+#define DM270_EMIF_CS3CTRL2_OESU1       0x0100
+#define DM270_EMIF_CS3CTRL2_IDLE1       0x1000
+#define DM270_EMIF_CS3CTRL2_BUSW16      (DM270_EMIF_CS3CTRL2_BUSW)
+
+#define DM270_EMIF_CS4CTRL1_CYCL_MASK   0x000f
+#define DM270_EMIF_CS4CTRL1_CEC_MASK    0x00f0
+#define DM270_EMIF_CS4CTRL1_WEC_MASK    0x0f00
+#define DM270_EMIF_CS4CTRL1_OEC_MASK    0xf000
+#define DM270_EMIF_CS4CTRL1_CYCL16      0x000f
+#define DM270_EMIF_CS4CTRL1_CEC16       0x00f0
+#define DM270_EMIF_CS4CTRL1_WEC10       0x0900
+#define DM270_EMIF_CS4CTRL1_OEC13       0xc000
+
+#define DM270_EMIF_CS4CTRL2_BUSW        0x4000
+#define DM270_EMIF_CS4CTRL2_CESL        0x8000
+#define DM270_EMIF_CS4CTRL2_CESU_MASK   0x000f
+#define DM270_EMIF_CS4CTRL2_WESU_MASK   0x00f0
+#define DM270_EMIF_CS4CTRL2_OESU_MASK   0x0f00
+#define DM270_EMIF_CS4CTRL2_IDLE_MASK   0x3000
+#define DM270_EMIF_CS4CTRL2_WESU2       0x0020
+#define DM270_EMIF_CS4CTRL2_OESU2       0x0200
+#define DM270_EMIF_CS4CTRL2_IDLE3       0x3000
+#define DM270_EMIF_CS4CTRL2_BUSW16      (DM270_EMIF_CS4CTRL2_BUSW)
+
+#define DM270_EMIF_BUSCTRL_EMWE3        0x0001
+#define DM270_EMIF_BUSCTRL_EMWE4        0x0002
+#define DM270_EMIF_BUSCTRL_RSV_MASK     0xfffc
+
+#define DM270_EMIF_BUSRLS_EMREL         0x0001
+#define DM270_EMIF_BUSRLS_SDREL         0x0002
+#define DM270_EMIF_BUSRLS_BUSSEL        0x0004
+#define DM270_EMIF_BUSRLS_RSV_MASK      0xfff8
+
+#define DM270_EMIF_CFCTRL1_CFSEL        0x0001
+#define DM270_EMIF_CFCTRL1_RSV_MASK     0xfffe
+
+#define DM270_EMIF_CFCTRL2_CFMOD        0x0001
+#define DM270_EMIF_CFCTRL2_BUSSZ        0x0010
+#define DM270_EMIF_CFCTRL2_RSV_MASK     0xffee
+
+#define DM270_EMIF_SMCTRL_SCEH          0x0001
+#define DM270_EMIF_SMCTRL_RSV_MASK      0xfffe
+
+#define DM270_EMIF_BUSINTEN_CBIEN       0x0001
+#define DM270_EMIF_BUSINTEN_CBCND       0x0002
+#define DM270_EMIF_BUSINTEN_RSV_MASK    0xfffc
+
+#define DM270_EMIF_BUSSTS_CFRDY         0x0001
+#define DM270_EMIF_BUSSTS_CFWAIT        0x0002
+#define DM270_EMIF_BUSSTS_IOIS16        0x0004
+#define DM270_EMIF_BUSSTS_EMWAIT        0x0008
+#define DM270_EMIF_BUSSTS_RSV_MASK      0xfff0
+
+#define DM270_EMIF_BUSWAITMD_CFRW       0x0001
+#define DM270_EMIF_BUSWAITMD_CFRSL      0x0002
+#define DM270_EMIF_BUSWAITMD_RSV_MASK   0xfffc
+
+#define DM270_EMIF_ECCCP_RD1_MASK       0x0003
+#define DM270_EMIF_ECCCP_CP_MASK        0x00fc
+#define DM270_EMIF_ECCCP_RSV_MASK       0xff00
+
+#define DM270_EMIF_ECCCLR_ECLR          0x0001
+#define DM270_EMIF_ECCCLR_RSV_MASK      0xfffe
+
+#define DM270_EMIF_PAGESZ_PAGESZ        0x0001
+#define DM270_EMIF_PAGESZ_RSV_MASK      0xfffe
+
+#define DM270_EMIF_IMGDSPDEST_DDST_MASK 0x0007
+#define DM270_EMIF_IMGDSPDEST_IDST_MASK 0x0070
+#define DM270_EMIF_IMGDSPDEST_RSV_MASK  0xff88
+
+#define DM270_EMIF_PRIOCTL_PRY4_MASK    0x0003
+#define DM270_EMIF_PRIOCTL_PRY3_MASK    0x000c
+#define DM270_EMIF_PRIOCTL_PRY2_MASK    0x0030
+#define DM270_EMIF_PRIOCTL_PRY1_MASK    0x00c0
+#define DM270_EMIF_PRIOCTL_RSV_MASK     0xff00
+
+#define DM270_EMIF_SOURCEADDH_SAH_MASK  0x03ff
+#define DM270_EMIF_SOURCEADDH_SAFIX     0x1000
+#define DM270_EMIF_SOURCEADDH_RSV_MASK  0xec00
+
+#define DM270_EMIF_DESTADDH_DAH_MASK    0x03ff
+#define DM270_EMIF_DESTADDH_DAFIX       0x1000
+#define DM270_EMIF_DESTADDH_RSV_MASK    0xec00
+
+#define DM270_EMIF_DMADEVSEL_DDV_MASK   0x0007
+#define DM270_EMIF_DMADEVSEL_SDV_MASK   0x0070
+#define DM270_EMIF_DMADEVSEL_RSV_MASK   0xff88
+
+#define DM270_EMIF_DMACTL_GO            0x0001
+#define DM270_EMIF_DMACTL_ENDI_MASK     0x0300
+#define DM270_EMIF_DMACTL_RSV_MASK      0xfcfe
+
+#define DM270_EMIF_IMGDSPADDH_CDAH_MASK 0x007f
+#define DM270_EMIF_IMGDSPADDH_RSV_MASK  0xff80
+
+#define DM270_EMIF_DPSTR_DST_MASK       0x00ff
+#define DM270_EMIF_DPSTR_RSV_MASK       0xff00
+
+/* SDRAM Controller -------------------------------------------------------- */
+
+#define DM270_SDRC_BASE                 (DM270_REG_BASE + 0x0980)
+
+#define DM270_SDRC_OFFSET_SDMODE        0x0026
+#define DM270_SDRC_OFFSET_REFCTL        0x0028
+
+#define DM270_SDRC_SDBUFD0L             (DM270_SDRC_BASE + 0x0000)
+#define DM270_SDRC_SDBUFD0H             (DM270_SDRC_BASE + 0x0002)
+#define DM270_SDRC_SDBUFD1L             (DM270_SDRC_BASE + 0x0004)
+#define DM270_SDRC_SDBUFD1H             (DM270_SDRC_BASE + 0x0006)
+#define DM270_SDRC_SDBUFD2L             (DM270_SDRC_BASE + 0x0008)
+#define DM270_SDRC_SDBUFD2H             (DM270_SDRC_BASE + 0x000a)
+#define DM270_SDRC_SDBUFD3L             (DM270_SDRC_BASE + 0x000c)
+#define DM270_SDRC_SDBUFD3H             (DM270_SDRC_BASE + 0x000e)
+#define DM270_SDRC_SDBUFD4L             (DM270_SDRC_BASE + 0x0010)
+#define DM270_SDRC_SDBUFD4H             (DM270_SDRC_BASE + 0x0012)
+#define DM270_SDRC_SDBUFD5L             (DM270_SDRC_BASE + 0x0014)
+#define DM270_SDRC_SDBUFD5H             (DM270_SDRC_BASE + 0x0016)
+#define DM270_SDRC_SDBUFD6L             (DM270_SDRC_BASE + 0x0018)
+#define DM270_SDRC_SDBUFD6H             (DM270_SDRC_BASE + 0x001a)
+#define DM270_SDRC_SDBUFD7L             (DM270_SDRC_BASE + 0x001c)
+#define DM270_SDRC_SDBUFD7H             (DM270_SDRC_BASE + 0x001e)
+#define DM270_SDRC_SDBUFAD1             (DM270_SDRC_BASE + 0x0020)
+#define DM270_SDRC_SDBUFAD2             (DM270_SDRC_BASE + 0x0022)
+#define DM270_SDRC_SDBUFCTL             (DM270_SDRC_BASE + 0x0024)
+#define DM270_SDRC_SDMODE               (DM270_SDRC_BASE + DM270_SDRC_OFFSET_SDMODE)
+#define DM270_SDRC_REFCTL               (DM270_SDRC_BASE + DM270_SDRC_OFFSET_REFCTL)
+#define DM270_SDRC_SDPRTY1              (DM270_SDRC_BASE + 0x002a)
+#define DM270_SDRC_SDPRTY2              (DM270_SDRC_BASE + 0x002c)
+#define DM270_SDRC_SDPRTY3              (DM270_SDRC_BASE + 0x002e)
+#define DM270_SDRC_SDPRTY4              (DM270_SDRC_BASE + 0x0030)
+#define DM270_SDRC_SDPRTY5              (DM270_SDRC_BASE + 0x0032)
+#define DM270_SDRC_SDPRTY6              (DM270_SDRC_BASE + 0x0034)
+#define DM270_SDRC_SDPRTY7              (DM270_SDRC_BASE + 0x0036)
+#define DM270_SDRC_SDPRTY8              (DM270_SDRC_BASE + 0x0038)
+#define DM270_SDRC_SDPRTY9              (DM270_SDRC_BASE + 0x003a)
+#define DM270_SDRC_SDPRTY10             (DM270_SDRC_BASE + 0x003c)
+#define DM270_SDRC_PRTYON               (DM270_SDRC_BASE + 0x003e)
+#define DM270_SDRC_SDRCTEST             (DM270_SDRC_BASE + 0x0040)
+
+#define DM270_SDRC_SDBUFAD1_SDAH_MASK   0x003f
+#define DM270_SDRC_SDBUFAD1_AAI         0x0100
+#define DM270_SDRC_SDBUFAD1_RSV_MASK    0xfec0
+
+#define DM270_SDRC_SDBUFCTL_RSD         0x0001
+#define DM270_SDRC_SDBUFCTL_WA          0x0002
+#define DM270_SDRC_SDBUFCTL_WM          0x0004
+#define DM270_SDRC_SDBUFCTL_BUFC        0x0008
+#define DM270_SDRC_SDBUFCTL_PTSEL_MASK  0x0030
+#define DM270_SDRC_SDBUFCTL_RSV_MASK    0xffc0
+
+#define DM270_SDRC_SDMODE_SDCTL_MASK    0x003f
+#define DM270_SDRC_SDMODE_SDCTL_NOP     0x0000 /* NOP:   No operation */
+#define DM270_SDRC_SDMODE_SDCTL_MSR     0x0001 /* MSR:   Sets mode */
+#define DM270_SDRC_SDMODE_SDCTL_PREA    0x0002 /* PREA:  Precharges all banks */
+#define DM270_SDRC_SDMODE_SDCTL_REF     0x0004 /* REF:   Issues auto refresh command */
+#define DM270_SDRC_SDMODE_SDCTL_SELF    0x0008 /* SELF:  Enters self refresh mode */
+#define DM270_SDRC_SDMODE_SDCTL_SELFC   0x0010 /* SELFC: Cancels self refresh/power down mode */
+#define DM270_SDRC_SDMODE_SDCTL_PDN     0x0020 /* PDN:   Enters power down mode */
+/* Added in ES1.1 for mobile SDRAM support */
+#define DM270_SDRC_SDMODE_SDCTL_DPDN    0x0030 /* DPDN:  Deep powerdown mode */
+#define DM270_SDRC_SDMODE_SDCTL_EMSR    0x0011 /* EMSR:  Set extended mode register */
+#define DM270_SDRC_SDMODE_APO           0x0040
+#define DM270_SDRC_SDMODE_DQMC          0x0080
+#define DM270_SDRC_SDMODE_MEMT_MASK     0x0300
+#define DM270_SDRC_SDMODE_CASL          0x0400
+#define DM270_SDRC_SDMODE_BNS           0x1000
+#define DM270_SDRC_SDMODE_TRCD          0x2000
+#define DM270_SDRC_SDMODE_SDBW          0x4000
+#define DM270_SDRC_SDMODE_TRDL          0x8000
+#define DM270_SDRC_SDMODE_RSV_MASK      0x0800
+
+#define DM270_SDRC_REFCTL_REFC_MASK     0x00ff
+#define DM270_SDRC_REFCTL_REFEN         0x0100
+#define DM270_SDRC_REFCTL_SDMA2_MASK    0x1c00
+#define DM270_SDRC_REFCTL_SDMA2_EMIF    0x0000
+#define DM270_SDRC_REFCTL_SDMA2_SERIAL  0x0400
+#define DM270_SDRC_REFCTL_SDMA2_USB     0x0800
+#define DM270_SDRC_REFCTL_SDMA2_MMCSD   0x0c00
+#define DM270_SDRC_REFCTL_SDMA2_HPIB    0x1000
+#define DM270_SDRC_REFCTL_SDMA1_MASK    0xe000
+#define DM270_SDRC_REFCTL_SDMA1_EMIF    0x0000
+#define DM270_SDRC_REFCTL_SDMA1_SERIAL  0x2000
+#define DM270_SDRC_REFCTL_SDMA1_USB     0x4000
+#define DM270_SDRC_REFCTL_SDMA1_MMCSD   0x6000
+#define DM270_SDRC_REFCTL_SDMA1_HPIB    0x8000
+#define DM270_SDRC_REFCTL_RSV_MASK      0x0200
+
+#define DM270_SDRC_SDPRTY_PRTY_MASK     0x03ff
+#define DM270_SDRC_SDPRTY_RSV_MASK      0xfc00
+
+#define DM270_SDRC_PRTYON_PTYON         0x0001
+#define DM270_SDRC_PRTYON_RSV_MASK      0xfffe
+
+#define DM270_SDRC_SDRCTEST_TEST        0x0001
+#define DM270_SDRC_SDRCTEST_RSV_MASK    0xfffe
+
+#define DM270_SDRC_SDMODE_8K512         0x0300
+#define DM270_SDRC_SDMODE_CL3           0x0400
+#define DM270_SDRC_SDMODE_4BANK         0x1000
+#define DM270_SDRC_SDMODE_32BIT         0x0000
+#define DM270_SDRC_SDMODE_TRDL2         0x8000
+
+/* Interrupt Controller ---------------------------------------------------- */
+
+#define DM270_INTC_BASE                 (DM270_REG_BASE + 0x0500)
+
+#define DM270_INTC_OFFSET_EINT0         0x0028
+#define DM270_INTC_OFFSET_EINT1         0x002a
+#define DM270_INTC_OFFSET_EINT2         0x002c
+
+#define DM270_INTC_FIQ0                 (DM270_INTC_BASE + 0x0000)
+#define DM270_INTC_FIQ1                 (DM270_INTC_BASE + 0x0002)
+#define DM270_INTC_FIQ2                 (DM270_INTC_BASE + 0x0004)
+#define DM270_INTC_IRQ0                 (DM270_INTC_BASE + 0x0008)
+#define DM270_INTC_IRQ1                 (DM270_INTC_BASE + 0x000a)
+#define DM270_INTC_IRQ2                 (DM270_INTC_BASE + 0x000c)
+#define DM270_INTC_FIQENTRY0            (DM270_INTC_BASE + 0x0010)
+#define DM270_INTC_FIQENTRY1            (DM270_INTC_BASE + 0x0012)
+#define DM270_INTC_IRQENTRY0            (DM270_INTC_BASE + 0x0018)
+#define DM270_INTC_IRQENTRY1            (DM270_INTC_BASE + 0x001a)
+#define DM270_INTC_FISEL0               (DM270_INTC_BASE + 0x0020)
+#define DM270_INTC_FISEL1               (DM270_INTC_BASE + 0x0022)
+#define DM270_INTC_FISEL2               (DM270_INTC_BASE + 0x0024)
+#define DM270_INTC_EINT0                (DM270_INTC_BASE + DM270_INTC_OFFSET_EINT0)
+#define DM270_INTC_EINT1                (DM270_INTC_BASE + DM270_INTC_OFFSET_EINT1)
+#define DM270_INTC_EINT2                (DM270_INTC_BASE + DM270_INTC_OFFSET_EINT2)
+#define DM270_INTC_INTRAW               (DM270_INTC_BASE + 0x0030)
+#define DM270_INTC_EABASE0              (DM270_INTC_BASE + 0x0038)
+#define DM270_INTC_EABASE1              (DM270_INTC_BASE + 0x003a)
+#define DM270_INTC_INTPRI00             (DM270_INTC_BASE + 0x0040)
+#define DM270_INTC_INTPRI01             (DM270_INTC_BASE + 0x0042)
+#define DM270_INTC_INTPRI02             (DM270_INTC_BASE + 0x0044)
+#define DM270_INTC_INTPRI03             (DM270_INTC_BASE + 0x0046)
+#define DM270_INTC_INTPRI04             (DM270_INTC_BASE + 0x0048)
+#define DM270_INTC_INTPRI05             (DM270_INTC_BASE + 0x004a)
+#define DM270_INTC_INTPRI06             (DM270_INTC_BASE + 0x004c)
+#define DM270_INTC_INTPRI07             (DM270_INTC_BASE + 0x004e)
+#define DM270_INTC_INTPRI08             (DM270_INTC_BASE + 0x0050)
+#define DM270_INTC_INTPRI09             (DM270_INTC_BASE + 0x0052)
+#define DM270_INTC_INTPRI10             (DM270_INTC_BASE + 0x0054)
+#define DM270_INTC_INTPRI11             (DM270_INTC_BASE + 0x0056)
+#define DM270_INTC_INTPRI12             (DM270_INTC_BASE + 0x0058)
+#define DM270_INTC_INTPRI13             (DM270_INTC_BASE + 0x005a)
+#define DM270_INTC_INTPRI14             (DM270_INTC_BASE + 0x005c)
+#define DM270_INTC_INTPRI15             (DM270_INTC_BASE + 0x005e)
+#define DM270_INTC_INTPRI16             (DM270_INTC_BASE + 0x0060)
+#define DM270_INTC_INTPRI17             (DM270_INTC_BASE + 0x0062)
+#define DM270_INTC_INTPRI18             (DM270_INTC_BASE + 0x0064)
+#define DM270_INTC_INTPRI19             (DM270_INTC_BASE + 0x0066)
+
+#define DM270_INTC_EINT(vector)         ((vector < 16) ? DM270_INTC_EINT0 : \
+                                            ((vector < 32) ? DM270_INTC_EINT1 : DM270_INTC_EINT2))
+#define DM270_INTC_FIQ(vector)          ((vector < 16) ? DM270_INTC_FIQ0 : \
+                                            ((vector < 32) ? DM270_INTC_FIQ1 : DM270_INTC_FIQ2))
+#define DM270_INTC_IRQ(vector)          ((vector < 16) ? DM270_INTC_IRQ0 : \
+                                            ((vector < 32) ? DM270_INTC_IRQ1 : DM270_INTC_IRQ2))
+#define DM270_INTC_EINT_SHIFT(vector)   ((vector < 16) ? vector : \
+                                            ((vector < 32) ? (vector - 16) : (vector - 32)))
+#define DM270_INTC_FIQ_SHIFT(vector)    DM270_INTC_EINT_SHIFT(vector)
+#define DM270_INTC_IRQ_SHIFT(vector)    DM270_INTC_EINT_SHIFT(vector)
+
+#define DM270_INTC_TMR0_BIT             0x0001
+#define DM270_INTC_TMR1_BIT             0x0002
+#define DM270_INTC_TMR2_BIT             0x0004
+#define DM270_INTC_TMR3_BIT             0x0008
+#define DM270_INTC_CCDVD0_BIT           0x0010
+#define DM270_INTC_CCDVD1_BIT           0x0020
+#define DM270_INTC_CCDVD2_BIT           0x0040
+#define DM270_INTC_OSD_BIT              0x0080
+#define DM270_INTC_SP0_BIT              0x0100
+#define DM270_INTC_SP1_BIT              0x0200
+#define DM270_INTC_EXTHOST_BIT          0x0400
+#define DM270_INTC_DSPHINT_BIT          0x0800
+#define DM270_INTC_UART0_BIT            0x1000
+#define DM270_INTC_UART1_BIT            0x2000
+#define DM270_INTC_USB_BIT              0x4000
+#define DM270_INTC_MTC0_BIT             0x8000
+
+#define DM270_INTC_MTC1_BIT             0x0001
+#define DM270_INTC_MMCSD0_BIT           0x0002
+#define DM270_INTC_MMCSD1_BIT           0x0004
+#define DM270_INTC_RSVINT0_BIT          0x0008
+#define DM270_INTC_EXT1_BIT             0x0010
+#define DM270_INTC_EXT2_BIT             0x0020
+#define DM270_INTC_EXT3_BIT             0x0040
+#define DM270_INTC_EXT4_BIT             0x0080
+#define DM270_INTC_EXT5_BIT             0x0100
+#define DM270_INTC_EXT6_BIT             0x0200
+#define DM270_INTC_EXT7_BIT             0x0400
+#define DM270_INTC_EXT8_BIT             0x0800
+#define DM270_INTC_EXT9_BIT             0x1000
+#define DM270_INTC_EXT10_BIT            0x2000
+#define DM270_INTC_EXT11_BIT            0x4000
+#define DM270_INTC_EXT12_BIT            0x8000
+
+#define DM270_INTC_EXT13_BIT            0x0001
+#define DM270_INTC_EXT14_BIT            0x0002
+#define DM270_INTC_EXT15_BIT            0x0004
+#define DM270_INTC_PREV_BIT             0x0008
+#define DM270_INTC_WDT_BIT              0x0010
+#define DM270_INTC_I2C_BIT              0x0020
+#define DM270_INTC_CLKC_BIT             0x0040
+#define DM270_INTC_RSVINT1_BIT          0x0080
+#define DM270_INTC_RSV_MASK             0xff00
+
+#define DM270_INTC_FIQENTRY1_RSV_MASK   0xe000
+
+#define DM270_INTC_IRQENTRY1_RSV_MASK   0xe000
+
+#define DM270_INTC_INTRAW_FIQ           0x0001
+#define DM270_INTC_INTRAW_IRQ           0x0002
+#define DM270_INTC_INTRAW_RSV_MASK      0xfffc
+
+#define DM270_INTC_EABASE0_TSIZE_MASK   0x0003
+#define DM270_INTC_EABASE0_EABL_MASK    0xfff8
+#define DM270_INTC_EABASE0_RSV_MASK     0x0004
+
+#define DM270_INTC_EABASE1_EABH_MASK    0x1fff
+#define DM270_INTC_EABASE1_RSV_MASK     0xe000
+
+#define DM270_INTC_INTPRI_PRIOL_MASK    0x003f
+#define DM270_INTC_INTPRI_PRIOH_MASK    0x3f00
+#define DM270_INTC_INTPRI_RSV_MASK      0xc0c0
+
+/* GIO --------------------------------------------------------------------- */
+
+#define DM270_GIO_BASE                  (DM270_REG_BASE + 0x0580)
+
+#define DM270_GIO_OFFSET_DIR0           0x0000
+#define DM270_GIO_OFFSET_DIR1           0x0002
+#define DM270_GIO_OFFSET_DIR2           0x0004
+#define DM270_GIO_OFFSET_INV0           0x0006
+#define DM270_GIO_OFFSET_INV1           0x0008
+#define DM270_GIO_OFFSET_INV2           0x000a
+#define DM270_GIO_OFFSET_BITSET0        0x000c
+#define DM270_GIO_OFFSET_BITSET1        0x000e
+#define DM270_GIO_OFFSET_BITSET2        0x0010
+#define DM270_GIO_OFFSET_BITCLR0        0x0012
+#define DM270_GIO_OFFSET_BITCLR1        0x0014
+#define DM270_GIO_OFFSET_BITCLR2        0x0016
+#define DM270_GIO_OFFSET_IRQPORT        0x0018
+#define DM270_GIO_OFFSET_IRQEDGE        0x001a
+#define DM270_GIO_OFFSET_CHAT0          0x001c
+#define DM270_GIO_OFFSET_CHAT1          0x001e
+#define DM270_GIO_OFFSET_CHAT2          0x0020
+#define DM270_GIO_OFFSET_NCHAT          0x0022
+#define DM270_GIO_OFFSET_FSEL0          0x0024
+#define DM270_GIO_OFFSET_FSEL1          0x0026
+
+#define DM270_GIO_DIR0                  (DM270_GIO_BASE + DM270_GIO_OFFSET_DIR0)
+#define DM270_GIO_DIR1                  (DM270_GIO_BASE + DM270_GIO_OFFSET_DIR1)
+#define DM270_GIO_DIR2                  (DM270_GIO_BASE + DM270_GIO_OFFSET_DIR2)
+#define DM270_GIO_INV0                  (DM270_GIO_BASE + DM270_GIO_OFFSET_INV0)
+#define DM270_GIO_INV1                  (DM270_GIO_BASE + DM270_GIO_OFFSET_INV1)
+#define DM270_GIO_INV2                  (DM270_GIO_BASE + DM270_GIO_OFFSET_INV2)
+#define DM270_GIO_BITSET0               (DM270_GIO_BASE + DM270_GIO_OFFSET_BITSET0)
+#define DM270_GIO_BITSET1               (DM270_GIO_BASE + DM270_GIO_OFFSET_BITSET1)
+#define DM270_GIO_BITSET2               (DM270_GIO_BASE + DM270_GIO_OFFSET_BITSET2)
+#define DM270_GIO_BITCLR0               (DM270_GIO_BASE + DM270_GIO_OFFSET_BITCLR0)
+#define DM270_GIO_BITCLR1               (DM270_GIO_BASE + DM270_GIO_OFFSET_BITCLR1)
+#define DM270_GIO_BITCLR2               (DM270_GIO_BASE + DM270_GIO_OFFSET_BITCLR2)
+#define DM270_GIO_IRQPORT               (DM270_GIO_BASE + DM270_GIO_OFFSET_IRQPORT)
+#define DM270_GIO_IRQEDGE               (DM270_GIO_BASE + DM270_GIO_OFFSET_IRQEDGE)
+#define DM270_GIO_CHAT0                 (DM270_GIO_BASE + DM270_GIO_OFFSET_CHAT0)
+#define DM270_GIO_CHAT1                 (DM270_GIO_BASE + DM270_GIO_OFFSET_CHAT1)
+#define DM270_GIO_CHAT2                 (DM270_GIO_BASE + DM270_GIO_OFFSET_CHAT2)
+#define DM270_GIO_NCHAT                 (DM270_GIO_BASE + DM270_GIO_OFFSET_NCHAT)
+#define DM270_GIO_FSEL0                 (DM270_GIO_BASE + DM270_GIO_OFFSET_FSEL0)
+#define DM270_GIO_FSEL1                 (DM270_GIO_BASE + DM270_GIO_OFFSET_FSEL1)
+
+#define DM270_GIO_DIR(vector)           (((vector - DM270_INTERRUPT_RSVINT0) < 16) ? DM270_GIO_DIR0 : \
+                                            (((vector - DM270_INTERRUPT_RSVINT0) < 32) ? DM270_GIO_DIR1 : DM270_GIO_DIR2))
+#define DM270_GIO_INV(vector)           (((vector - DM270_INTERRUPT_RSVINT0) < 16) ? DM270_GIO_INV0 : \
+                                            (((vector - DM270_INTERRUPT_RSVINT0) < 32) ? DM270_GIO_INV1 : DM270_GIO_INV2))
+#define DM270_GIO_DIR_SHIFT(vector)     (((vector - DM270_INTERRUPT_RSVINT0) < 16) ? (vector - DM270_INTERRUPT_RSVINT0) : \
+                                            (((vector - DM270_INTERRUPT_RSVINT0) < 32) ? (vector - DM270_INTERRUPT_RSVINT0 - 16) : \
+                                            (vector - DM270_INTERRUPT_RSVINT0 - 32)))
+#define DM270_GIO_IRQPORT_SHIFT(vector) DM270_GIO_DIR_SHIFT(vector)
+#define DM270_GIO_INV_SHIFT(vector)     DM270_GIO_DIR_SHIFT(vector)
+#define DM270_GIO_IRQEDGE_SHIFT(vector) DM270_GIO_DIR_SHIFT(vector)
+
+#define DM270_GIO_RSV_BIT               0x0001
+#define DM270_GIO_GIO01_BIT             0x0002
+#define DM270_GIO_GIO02_BIT             0x0004
+#define DM270_GIO_GIO03_BIT             0x0008
+#define DM270_GIO_GIO04_BIT             0x0010
+#define DM270_GIO_GIO05_BIT             0x0020
+#define DM270_GIO_GIO06_BIT             0x0040
+#define DM270_GIO_GIO07_BIT             0x0080
+#define DM270_GIO_GIO08_BIT             0x0100
+#define DM270_GIO_GIO09_BIT             0x0200
+#define DM270_GIO_GIO10_BIT             0x0400
+#define DM270_GIO_GIO11_BIT             0x0800
+#define DM270_GIO_GIO12_BIT             0x1000
+#define DM270_GIO_GIO13_BIT             0x2000
+#define DM270_GIO_GIO14_BIT             0x4000
+#define DM270_GIO_GIO15_BIT             0x8000
+
+#define DM270_GIO_GIO16_BIT             0x0001
+#define DM270_GIO_GIO17_BIT             0x0002
+#define DM270_GIO_GIO18_BIT             0x0004
+#define DM270_GIO_GIO19_BIT             0x0008
+#define DM270_GIO_GIO20_BIT             0x0010
+#define DM270_GIO_GIO21_BIT             0x0020
+#define DM270_GIO_GIO22_BIT             0x0040
+#define DM270_GIO_GIO23_BIT             0x0080
+#define DM270_GIO_GIO24_BIT             0x0100
+#define DM270_GIO_GIO25_BIT             0x0200
+#define DM270_GIO_GIO26_BIT             0x0400
+#define DM270_GIO_GIO27_BIT             0x0800
+#define DM270_GIO_GIO28_BIT             0x1000
+#define DM270_GIO_GIO29_BIT             0x2000
+#define DM270_GIO_GIO30_BIT             0x4000
+#define DM270_GIO_GIO31_BIT             0x8000
+
+#define DM270_GIO_GIO32_BIT             0x0001
+#define DM270_GIO_GIO33_BIT             0x0002
+#define DM270_GIO_RSV_MASK              0xfffc
+
+#define DM270_GIO_NCHAT_NCH_MASK        0x000f
+#define DM270_GIO_NCHAT_RSV_MASK        0xfff0
+
+#define DM270_GIO_FSEL0_GIO08SEL_BIT    0x0001
+#define DM270_GIO_FSEL0_GIO09SEL_BIT    0x0002
+#define DM270_GIO_FSEL0_GIO10SEL_BIT    0x0004
+#define DM270_GIO_FSEL0_GIO11SEL_BIT    0x0008
+#define DM270_GIO_FSEL0_GIO12SEL_BIT    0x0010
+#define DM270_GIO_FSEL0_GIO13SEL_BIT    0x0020
+#define DM270_GIO_FSEL0_GIO14SEL_BIT    0x0040
+#define DM270_GIO_FSEL0_GIO15SEL_BIT    0x0080
+#define DM270_GIO_FSEL0_GIO16SEL_BIT    0x0100
+#define DM270_GIO_FSEL0_GIO17SEL_BIT    0x0200
+#define DM270_GIO_FSEL0_GIO18SEL_BIT    0x0400
+#define DM270_GIO_FSEL0_GIO19SEL_BIT    0x0800
+#define DM270_GIO_FSEL0_GIO20SEL_BIT    0x1000
+#define DM270_GIO_FSEL0_GIO21SEL_BIT    0x2000
+
+#define DM270_GIO_FSEL0_GIO23SEL_BIT    0x8000
+
+#define DM270_GIO_FSEL1_GIO24SEL_BIT    0x0001
+#define DM270_GIO_FSEL1_GIO25SEL_MASK   0x0006
+#define DM270_GIO_FSEL1_GIO26SEL_BIT    0x0008
+#define DM270_GIO_FSEL1_GIO27SEL_BIT    0x0010
+#define DM270_GIO_FSEL1_GIO28SEL_BIT    0x0020
+#define DM270_GIO_FSEL1_GIO29SEL_BIT    0x0040
+#define DM270_GIO_FSEL1_GIO30SEL_BIT    0x0080
+#define DM270_GIO_FSEL1_GIO31SEL_BIT    0x0100
+#define DM270_GIO_FSEL1_GIO32SEL_BIT    0x0200
+#define DM270_GIO_FSEL1_GIO33SEL_BIT    0x0400
+#define DM270_GIO_FSEL1_HDVDSEL_BIT     0x2000
+#define DM270_GIO_FSEL1_RGB666SEL_BIT   0x4000
+#define DM270_GIO_FSEL1_RSV_MASK        0x9800
+
+#define DM270_GIO_FSEL_DSP_BFSR1        DM270_GIO_FSEL0_GIO08SEL_BIT
+#define DM270_GIO_FSEL_DSP_BCLKR1       DM270_GIO_FSEL0_GIO09SEL_BIT
+#define DM270_GIO_FSEL_DSP_BDR1         DM270_GIO_FSEL0_GIO10SEL_BIT
+#define DM270_GIO_FSEL_DSP_BFSX1        DM270_GIO_FSEL0_GIO11SEL_BIT
+#define DM270_GIO_FSEL_DSP_BCLKX1       DM270_GIO_FSEL0_GIO12SEL_BIT
+#define DM270_GIO_FSEL_DSP_BDX1         DM270_GIO_FSEL0_GIO13SEL_BIT
+#define DM270_GIO_FSEL_DSP_CLKS1        DM270_GIO_FSEL0_GIO14SEL_BIT
+#define DM270_GIO_FSEL_DSP_XF           DM270_GIO_FSEL0_GIO15SEL_BIT
+#define DM270_GIO_FSEL_CLKOUT0          DM270_GIO_FSEL0_GIO16SEL_BIT
+#define DM270_GIO_FSEL_CLKOUT1          DM270_GIO_FSEL0_GIO17SEL_BIT
+#define DM270_GIO_FSEL_CLKOUT2          DM270_GIO_FSEL0_GIO18SEL_BIT
+#define DM270_GIO_FSEL_SDO1             DM270_GIO_FSEL0_GIO19SEL_BIT
+#define DM270_GIO_FSEL_SDI1             DM270_GIO_FSEL0_GIO20SEL_BIT
+#define DM270_GIO_FSEL_SCLK1            DM270_GIO_FSEL0_GIO21SEL_BIT
+#define DM270_GIO_FSEL_SDEN1            DM270_GIO_FSEL0_GIO22SEL_BIT
+#define DM270_GIO_FSEL_RXD1             DM270_GIO_FSEL0_GIO23SEL_BIT
+#define DM270_GIO_FSEL_TXD1             DM270_GIO_FSEL1_GIO24SEL_BIT
+#define DM270_GIO_FSEL_MIRQ             0x0002
+#define DM270_GIO_FSEL_MRST             0x0004
+#define DM270_GIO_FSEL_C_WEN            DM270_GIO_FSEL1_GIO26SEL_BIT
+#define DM270_GIO_FSEL_CCDC_SHUT        DM270_GIO_FSEL1_GIO27SEL_BIT
+#define DM270_GIO_FSEL_LCD_OE           DM270_GIO_FSEL1_GIO28SEL_BIT
+#define DM270_GIO_FSEL_VENC_EXT_FIELD   DM270_GIO_FSEL1_GIO28SEL_BIT
+#define DM270_GIO_FSEL_PWM0             DM270_GIO_FSEL1_GIO29SEL_BIT
+#define DM270_GIO_FSEL_PWM1             DM270_GIO_FSEL1_GIO30SEL_BIT
+#define DM270_GIO_FSEL_VENC_EXT_HD      DM270_GIO_FSEL1_GIO30SEL_BIT
+#define DM270_GIO_FSEL_SCL              DM270_GIO_FSEL1_GIO31SEL_BIT
+#define DM270_GIO_FSEL_SDA              DM270_GIO_FSEL1_GIO32SEL_BIT
+#define DM270_GIO_FSEL_EXT_LINE_ID      DM270_GIO_FSEL1_GIO33SEL_BIT
+#define DM270_GIO_FSEL_VENC_EXT_VD      DM270_GIO_FSEL1_GIO33SEL_BIT
+
+/* Timer 0 - 3 ------------------------------------------------------------- */
+
+#define DM270_TMR0_BASE                 (DM270_REG_BASE + 0x0000)
+#define DM270_TMR1_BASE                 (DM270_REG_BASE + 0x0080)
+#define DM270_TMR2_BASE                 (DM270_REG_BASE + 0x0100)
+#define DM270_TMR3_BASE                 (DM270_REG_BASE + 0x0180)
+
+#define DM270_TMR_TMMD                  0x0000
+#define DM270_TMR_TMRSV                 0x0002
+#define DM270_TMR_TMPRSCL               0x0004
+#define DM270_TMR_TMVAL                 0x0006
+#define DM270_TMR_TMTRG                 0x0008
+#define DM270_TMR_TMCNT                 0x000a
+
+#define DM270_TMR0_TMMD                 (DM270_TMR0_BASE + 0x0000)
+#define DM270_TMR0_TMRSV                (DM270_TMR0_BASE + 0x0002)
+#define DM270_TMR0_TMPRSCL              (DM270_TMR0_BASE + 0x0004)
+#define DM270_TMR0_TMVAL                (DM270_TMR0_BASE + 0x0006)
+#define DM270_TMR0_TMTRG                (DM270_TMR0_BASE + 0x0008)
+#define DM270_TMR0_TMCNT                (DM270_TMR0_BASE + 0x000a)
+
+#define DM270_TMR1_TMMD                 (DM270_TMR1_BASE + 0x0000)
+#define DM270_TMR1_TMRSV                (DM270_TMR1_BASE + 0x0002)
+#define DM270_TMR1_TMPRSCL              (DM270_TMR1_BASE + 0x0004)
+#define DM270_TMR1_TMVAL                (DM270_TMR1_BASE + 0x0006)
+#define DM270_TMR1_TMTRG                (DM270_TMR1_BASE + 0x0008)
+#define DM270_TMR1_TMCNT                (DM270_TMR1_BASE + 0x000a)
+
+#define DM270_TMR2_TMMD                 (DM270_TMR2_BASE + 0x0000)
+#define DM270_TMR2_TMRSV                (DM270_TMR2_BASE + 0x0002)
+#define DM270_TMR2_TMPRSCL              (DM270_TMR2_BASE + 0x0004)
+#define DM270_TMR2_TMVAL                (DM270_TMR2_BASE + 0x0006)
+#define DM270_TMR2_TMTRG                (DM270_TMR2_BASE + 0x0008)
+#define DM270_TMR2_TMCNT                (DM270_TMR2_BASE + 0x000a)
+
+#define DM270_TMR3_TMMD                 (DM270_TMR3_BASE + 0x0000)
+#define DM270_TMR3_TMRSV                (DM270_TMR3_BASE + 0x0002)
+#define DM270_TMR3_TMPRSCL              (DM270_TMR3_BASE + 0x0004)
+#define DM270_TMR3_TMVAL                (DM270_TMR3_BASE + 0x0006)
+#define DM270_TMR3_TMTRG                (DM270_TMR3_BASE + 0x0008)
+#define DM270_TMR3_TMCNT                (DM270_TMR3_BASE + 0x000a)
+
+#define DM270_TMR_TMMD_MODE_STOP        0x0000
+#define DM270_TMR_TMMD_MODE_ONESHOT     0x0001
+#define DM270_TMR_TMMD_MODE_FREERUN     0x0002
+#define DM270_TMR_TMMD_MODE_MASK        0x0003
+#define DM270_TMR_TMMD_TEST_MASK        0x00fc
+#define DM270_TMR_TMMD_RSV_MASK         0xff00
+
+#define DM270_TMR_TMPRSCL_PRSCL_MASK    0x03ff
+#define DM270_TMR_TMPRSCL_RSV_MASK      0xfc00
+
+#define DM270_TMR_TMTRG_TRG             0x0001
+#define DM270_TMR_TMTRG_RSV_MASK        0xfffe
+
+/* UART 0, 1 --------------------------------------------------------------- */
+
+#define DM270_UART0_BASE                (DM270_REG_BASE + 0x0300)
+#define DM270_UART1_BASE                (DM270_REG_BASE + 0x0380)
+
+#define DM270_UART_DTRR                 0x0000
+#define DM270_UART_BRSR                 0x0002
+#define DM270_UART_MSR                  0x0004
+#define DM270_UART_RFCR                 0x0006
+#define DM270_UART_TFCR                 0x0008
+#define DM270_UART_LCR                  0x000a
+#define DM270_UART_SR                   0x000c
+
+#define DM270_UART_DTRR_DTR_MASK        0x00ff
+#define DM270_UART_DTRR_PEF             0x0100
+#define DM270_UART_DTRR_ORF             0x0200
+#define DM270_UART_DTRR_FE              0x0400
+#define DM270_UART_DTRR_BF              0x0800
+#define DM270_UART_DTRR_RVF             0x1000
+#define DM270_UART_DTRR_RSV_MASK        0xe000
+
+#define DM270_UART_BRSR_VAL(baud)       ((CONFIG_ARM_CLK/(16*(baud))) - 1)
+
+#define DM270_UART_MSR_CLS              0x0001
+#define DM270_UART_MSR_SBLS             0x0004
+#define DM270_UART_MSR_PSB              0x0008
+#define DM270_UART_MSR_PEB              0x0010
+#define DM270_UART_MSR_TOIC_MASK        0x0c00
+#define DM270_UART_MSR_REIE             0x2000
+#define DM270_UART_MSR_TFTIE            0x4000
+#define DM270_UART_MSR_RFTIE            0x8000
+#define DM270_UART_MSR_RSV_MASK         0x13e2
+
+#define DM270_UART_RFCR_RWC_MASK        0x003f
+#define DM270_UART_RFCR_RTL_MASK        0x0700
+#define DM270_UART_RFCR_RDEF            0x4000
+#define DM270_UART_RFCR_RFCB            0x8000
+#define DM270_UART_RFCR_RSV_MASK        0x38c0
+
+#define DM270_UART_TFCR_TWC_MASK        0x003f
+#define DM270_UART_TFCR_TTL_MASK        0x0700
+#define DM270_UART_TFCR_TFCB            0x8000
+#define DM270_UART_TFCR_RSV_MASK        0x78c0
+
+#define DM270_UART_LCR_BOC              0x0100
+#define DM270_UART_LCR_UTST             0x4000
+#define DM270_UART_LCR_RSV_MASK         0xbeff
+
+#define DM270_UART_SR_TREF              0x0001
+#define DM270_UART_SR_TFEF              0x0002
+#define DM270_UART_SR_RFNEF             0x0004
+#define DM270_UART_SR_TOIF              0x0100
+#define DM270_UART_SR_RFER              0x0200
+#define DM270_UART_SR_TFTI              0x0400
+#define DM270_UART_SR_RFTI              0x0800
+#define DM270_UART_SR_RSV_MASK          0xf0f8
+
+#define DM270_UART_DTRR_VALID           (DM270_UART_DTRR_RVF)
+
+#define DM270_UART_MSR_8_DBITS          0x0000
+#define DM270_UART_MSR_7_DBITS          (DM270_UART_MSR_CLS)
+#define DM270_UART_MSR_1_SBITS          0x0000
+#define DM270_UART_MSR_2_SBITS          (DM270_UART_MSR_SBLS)
+#define DM270_UART_MSR_PARITY_MASK      (DM270_UART_MSR_PSB|DM270_UART_MSR_PEB)
+#define DM270_UART_MSR_NO_PARITY        0x0000
+#define DM270_UART_MSR_EVEN_PARITY      (DM270_UART_MSR_PEB)
+#define DM270_UART_MSR_ODD_PARITY       (DM270_UART_MSR_PSB|DM270_UART_MSR_PEB)
+#define DM270_UART_MSR_TIMEOUT_DISABLED 0x0000
+#define DM270_UART_MSR_TIMEOUT_3        0x0400
+#define DM270_UART_MSR_TIMEOUT_7        0x0800
+#define DM270_UART_MSR_TIMEOUT_15       0x0c00
+
+#define DM270_UART_RFCR_TRG_1           0x0000
+#define DM270_UART_RFCR_TRG_4           0x0100
+#define DM270_UART_RFCR_TRG_8           0x0200
+#define DM270_UART_RFCR_TRG_16          0x0300
+#define DM270_UART_RFCR_TRG_24          0x0400
+#define DM270_UART_RFCR_TRG_32          0x0500
+#define DM270_UART_RFCR_RESET           DM270_UART_RFCR_RDEF
+#define DM270_UART_RFCR_CLEAR           DM270_UART_RFCR_RFCB
+
+#define DM270_UART_TFCR_TRG_1           0x0000
+#define DM270_UART_TFCR_TRG_4           0x0100
+#define DM270_UART_TFCR_TRG_8           0x0200
+#define DM270_UART_TFCR_TRG_16          0x0300
+#define DM270_UART_TFCR_TRG_24          0x0400
+#define DM270_UART_TFCR_TRG_32          0x0500
+#define DM270_UART_TFCR_CLEAR           DM270_UART_TFCR_TFCB
+
+#define DM270_UART_RXFIFO_BYTESIZE      32
+#define DM270_UART_TXFIFO_BYTESIZE      32
+
+/* Instruction Cache ------------------------------------------------------- */
+
+#define DM270_ICACHE_BASE               (DM270_REG_BASE + 0x0e00)
+
+#define DM270_ICACHE_OFFSET_ICAMODE     0x0000
+
+#define DM270_ICACHE_ICAMODE            (DM270_ICACHE_BASE + DM270_ICACHE_OFFSET_ICAMODE)
+
+#define DM270_ICACHE_ICAMODE_ICAENB     0x0001
+#define DM270_ICACHE_ICAMODE_ICACLR     0x0002
+#define DM270_ICACHE_ICAMODE_REQ4W      0x0100
+#define DM270_ICACHE_ICAMODE_RSV_MASK   0xfefc
+
+#endif  /* __ASM_ARCH_HARDWARE_H */
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/io.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/io.h
--- linux-2.4.29/include/asm-arm/arch-dm270/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/io.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,42 @@
+/*
+ * linux/include/asm-armnommu/arch-dm270/io.h
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ */
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* If we define __io then asm/io.h will take care of most of the inb & friends
+ * macros. It still leaves us some 16bit macros to deal with ourselves, though.
+ * We don't have PCI or ISA, no  __mem_pci & __mem_isa.
+ */
+
+#define PCIO_BASE 0
+#define __io(a) (PCIO_BASE + (a))
+
+/* Some compiler options will convert short loads and stores into byte loads
+ * and stores.  We don't want this to happen for IO reads and writes!
+ */
+
+static inline unsigned short __arch_getw(unsigned int addr)
+{
+  unsigned short retval;
+ __asm__ __volatile__("\tldrh %0, [%1]\n\t" : "=r"(retval) : "r"(addr));
+  return retval;
+}
+static inline void __arch_putw(unsigned short val, unsigned int addr)
+{
+ __asm__ __volatile__("\tstrh %0, [%1]\n\t": : "r"(val), "r"(addr));
+}
+
+/* Defining these two gives us ioremap for free. See asm/io.h. */
+
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/irq.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/irq.h
--- linux-2.4.29/include/asm-arm/arch-dm270/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/irq.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,61 @@
+/*
+ * linux/include/asm-armnommu/arch-dm270/irq.h
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/irq.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _ASM_ARCH_IRQ_H_
+#define _ASM_ARCH_IRQ_H_
+
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irqs.h>
+
+extern void dm270_init_irq(void);
+extern void dm270_mask_irq(unsigned int irq);
+extern void dm270_unmask_irq(unsigned int irq);
+extern void dm270_mask_ack_irq(unsigned int irq);
+
+#define fixup_irq(x) (x)
+
+static __inline__ void irq_init_irq(void)
+{
+	int irq;
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= dm270_mask_ack_irq;
+		irq_desc[irq].mask	= dm270_mask_irq;
+		irq_desc[irq].unmask	= dm270_unmask_irq;
+	}
+
+	dm270_init_irq();
+}
+
+#endif /* _ASM_ARCH_IRQ_H_ */
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/irqs.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/irqs.h
--- linux-2.4.29/include/asm-arm/arch-dm270/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/irqs.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,88 @@
+/***********************************************************************
+ * include/asm-armnommu/arch-dm270/irqs.h
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/irqs.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+
+#include <linux/config.h>
+
+#define DM270_INTERRUPT_TMR0           0
+#define DM270_INTERRUPT_TMR1           1
+#define DM270_INTERRUPT_TMR2           2
+#define DM270_INTERRUPT_TMR3           3
+#define DM270_INTERRUPT_CCDVD0         4
+#define DM270_INTERRUPT_CCDVD1         5
+#define DM270_INTERRUPT_CCDVD2         6
+#define DM270_INTERRUPT_OSD            7
+#define DM270_INTERRUPT_SP0            8
+#define DM270_INTERRUPT_SP1            9
+#define DM270_INTERRUPT_EXTHOST       10
+#define DM270_INTERRUPT_DSPHINT       11
+#define DM270_INTERRUPT_UART0         12
+#define DM270_INTERRUPT_UART1         13
+#define DM270_INTERRUPT_USB           14
+#define DM270_INTERRUPT_MTC0          15
+#define DM270_INTERRUPT_MTC1          16
+#define DM270_INTERRUPT_MMCSD0        17
+#define DM270_INTERRUPT_MMCSD1        18
+#define DM270_INTERRUPT_RSVINT0       19
+#define DM270_INTERRUPT_EXT1          20
+#define DM270_INTERRUPT_EXT2          21
+#define DM270_INTERRUPT_EXT3          22
+#define DM270_INTERRUPT_EXT4          23
+#define DM270_INTERRUPT_EXT5          24
+#define DM270_INTERRUPT_EXT6          25
+#define DM270_INTERRUPT_EXT7          26
+#define DM270_INTERRUPT_EXT8          27
+#define DM270_INTERRUPT_EXT9          28
+#define DM270_INTERRUPT_EXT10         29
+#define DM270_INTERRUPT_EXT11         30
+#define DM270_INTERRUPT_EXT12         31
+#define DM270_INTERRUPT_EXT13         32
+#define DM270_INTERRUPT_EXT14         33
+#define DM270_INTERRUPT_EXT15         34
+#define DM270_INTERRUPT_PREV          35
+#define DM270_INTERRUPT_WDT           36
+#define DM270_INTERRUPT_I2C           37
+#define DM270_INTERRUPT_CLKC          38
+/*#define DM270_INTERRUPT_RSVINT1       39*/
+
+#define IRQ_TIMER                     (DM270_INTERRUPT_TMR0)
+#define NR_IRQS                       (DM270_INTERRUPT_CLKC + 1)
+
+/* flags for request_irq().  IRQ_FLG_STD is apparently a uClinux-ism,
+ * so I'll keep it around even though it is just a mapping for the
+ * real SA_INTERRUPT. -- skj 
+ */
+
+#define IRQ_FLG_STD                   (SA_INTERRUPT)
+
+#endif /* __ASM_ARCH_IRQS_H__ */
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/keyboard.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/keyboard.h
--- linux-2.4.29/include/asm-arm/arch-dm270/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/keyboard.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ *  linux/include/asm-armnommu/arch-dm270/keyboard.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef __ASM_ARM_ARCH_DM270_KEYBOARD_H
+#define __ASM_ARM_ARCH_DM270_KEYBOARD_H
+
+/*
+ * Required by drivers/char/keyboard.c.
+ */
+
+#define kbd_setkeycode(sc,kc) (-EINVAL)
+#define kbd_getkeycode(sc) (-EINVAL)
+#define kbd_translate(sc,kcp,rm) ({ *(kcp) = (sc); 1; })
+#define kbd_unexpected_up(kc) (0200)
+#define kbd_leds(leds)
+#define kbd_init_hw()
+#define kbd_enable_irq() 
+#define kbd_disable_irq()
+
+#endif /* __ASM_ARM_ARCH_DM270_KEYBOARD_H */
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/memory.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/memory.h
--- linux-2.4.29/include/asm-arm/arch-dm270/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/memory.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,59 @@
+/*
+ * linux/include/asm-armnommu/arch-dm270/memory.h
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <linux/config.h>
+
+#define __virt_to_bus(x) ((unsigned long) (x))
+#define __bus_to_virt(x) ((void *) (x))
+#define __virt_to_phys(x) ((unsigned long) (x))
+#define __phys_to_virt(x) ((void *) (x))
+
+#define END_MEM		(DRAM_BASE + DRAM_SIZE)
+
+/* These are used in the fault handling code (even for nommu) and various other
+ * macros.
+ */
+
+#define TASK_SIZE	(0x01a00000UL)
+#define TASK_SIZE_26	(TASK_SIZE)
+
+/* The alignment requirement of the memory management system
+ * this is ~(1 << (PAGE_OFFSET+(MAX_ORDER-1)))-1.
+ */
+
+#define PHYS_OFFSET_MASK 0x001fffff
+
+/* The start of physical memory.  This is the first SDRAM address.
+ * This value is used in the arch-specific bootup code like setup_arch &
+ * bootmem_init.
+ *
+ * NOTE the alignment requirement of the memory management system
+ * this is given by PHYS_OFFSET_MASK.
+ *
+ * Boot from flash -  kernel .text and .rodata are in rom/flash and only
+ * .data lies in SDRAM.  So the mem_map tables can begin near the
+ * beginning of physical SDRAM.  The value _end_kernel provides
+ * SDRAM address after the memory used by the kernel .data section.
+ * There can still be a significant loss of memory due to the alignment
+ * requirement.
+ */
+
+#define PHYS_OFFSET \
+  ((((unsigned long)DRAM_BASE) + PHYS_OFFSET_MASK) & ~PHYS_OFFSET_MASK)
+
+#define UNALIGNED_PHYS_OFFSET ((unsigned long)&_end_kernel)
+
+#define LOST_MEMORY_SIZE (PHYS_OFFSET - UNALIGNED_PHYS_OFFSET)
+
+/* PAGE_OFFSET -- the first address of the first page of memory. For archs with
+ * no MMU this corresponds to the first free page in physical memory (aligned
+ * on a page boundary).
+ */
+
+#define PAGE_OFFSET (PHYS_OFFSET)
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/mmu.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/mmu.h
--- linux-2.4.29/include/asm-arm/arch-dm270/mmu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/mmu.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,23 @@
+/*
+ * linux/include/asm-arm/arch-dm270/mmu.h
+ *
+ * Copyright (c) 1996 Russell King.
+ *
+ * Changelog:
+ *  22-11-1996	RMK	Created
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((unsigned long) (vpage))
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((void *) (ppage))
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(vpage) ((unsigned long) (vpage))
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(ppage) ((void *) (ppage))
+
+#define __flush_entry_to_
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/param.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/param.h
--- linux-2.4.29/include/asm-arm/arch-dm270/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/param.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,8 @@
+/* include/asm-armnommu/arch-dm270/param.h */
+
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/processor.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/processor.h
--- linux-2.4.29/include/asm-arm/arch-dm270/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/processor.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-armnommu/arch-dm270/processor.h
+ * Derived from linux/include/asm-armnommu/arch-c5471/mmu.h
+ *
+ */
+
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+#define EISA_bus 0
+#define EISA_bus__is_a_macro
+#define MCA_bus 0
+#define MCA_bus__is_a_macro
+
+#define TASK_SIZE (0x01a00000UL)
+
+#endif /* __ASM_ARCH_PROCESSOR_H */
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/serial.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/serial.h
--- linux-2.4.29/include/asm-arm/arch-dm270/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/serial.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,177 @@
+/***********************************************************************
+ * linux/include/asm-arm/arch-dm270/serial.h
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/serial.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <linux/config.h>
+#include <linux/termios.h>
+#include <linux/tqueue.h>
+#include <linux/circ_buf.h>
+#include <linux/wait.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/irqs.h>
+
+#define BASE_BAUD     38400
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+/* This defines the initializer for a struct serial_state describing the
+ * TI TMS320DM270 serial port 0.
+ */
+
+#define DM270_SERIAL_PORT0_DEFN \
+  {  \
+    magic:          0, \
+    port:           0, \
+    flags:          STD_COM_FLAGS, \
+    xmit_fifo_size: DM270_UART_TXFIFO_BYTESIZE, \
+    baud_base:      BASE_BAUD, \
+    irq:            DM270_INTERRUPT_UART0, \
+    type:           PORT_UNKNOWN, \
+    line:           0, \
+    iomem_base:     DM270_UART0_BASE, \
+    io_type:        SERIAL_IO_MEM \
+  }
+
+/* This defines the initializer for a struct serial_state describing the
+ * TI TMS320DM270 serial port 1.
+ */
+
+#define DM270_SERIAL_PORT1_DEFN \
+  {  \
+    magic:          0, \
+    port:           0, \
+    flags:          STD_COM_FLAGS, \
+    xmit_fifo_size: DM270_UART_TXFIFO_BYTESIZE, \
+    baud_base:      BASE_BAUD, \
+    irq:            DM270_INTERRUPT_UART1, \
+    type:           PORT_UNKNOWN, \
+    line:           1, \
+    iomem_base:     DM270_UART1_BASE, \
+    io_type:        SERIAL_IO_MEM \
+  }
+
+/* There will always be two serial ports. */
+
+#define RS_TABLE_SIZE 2
+
+/* STD_SERIAL_PORT_DEFNS (plus EXTRA_SERIAL_PORT_DEFNS, see
+ * include/asm/serial.h) define an array of struct serial_state
+ * instance initializers.  These array initilizers are used
+ * in drivers/char/serial_dm270.c to describe the serial
+ * ports that will be supported.
+ */
+
+# define STD_SERIAL_PORT_DEFNS \
+  DM270_SERIAL_PORT0_DEFN,  /* ttyS0 */ \
+  DM270_SERIAL_PORT1_DEFN   /* ttyS1 */
+
+#define EXTRA_SERIAL_PORT_DEFNS
+
+/* Events are used to schedule things to happen at timer-interrupt
+ * time, instead of at rs interrupt time.
+ */
+
+#define RS_EVENT_WRITE_WAKEUP	0
+
+#define CONFIGURED_SERIAL_PORT(info) ((info)->state)
+
+#define SERIAL_MAGIC 0x5301
+#define SSTATE_MAGIC 0x5302
+
+/* This is the internal structure for each serial port's state.
+ *
+ * For definitions of the flags field, see tty.h
+ */
+
+struct dm270_serial_state_s
+{
+	int			magic;
+	int			port;
+	int			baud_base;
+	int			irq;
+	int			flags;
+	int			type;
+	int			line;
+	int			xmit_fifo_size;
+	int			custom_divisor;
+	int			count;
+	int			io_type;
+	unsigned long		iomem_base;
+	unsigned short		close_delay;
+	unsigned short		closing_wait;	/* time to wait before closing */
+	struct async_icount	icount;	
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+	struct dm270_async_s	*info;
+};
+typedef struct dm270_serial_state_s dm270_serial_state_t;
+
+struct dm270_async_s
+{
+	int			magic;
+	int			port;
+	int			flags;
+	int			xmit_fifo_size;
+	dm270_serial_state_t	*state;
+	struct tty_struct	*tty;
+	unsigned short		closing_wait;
+	int			line;
+	unsigned short		read_status_mask;
+	unsigned short		ignore_status_mask;
+	int			timeout;
+	int			baud;
+	int			x_char;		/* xon/xoff character */
+	int			close_delay;
+	unsigned short		msr;		/* Cached UART Mode Setup Register */
+	int			blocked_open;	/* # of blocked opens */
+	unsigned long		event;
+	unsigned long		last_active;
+	long			session;	/* Session of opening process */
+	long			pgrp;		/* pgrp of opening process */
+	struct circ_buf		xmit;
+	unsigned long		iomem_base;
+	struct tq_struct	tqueue;
+#ifdef DECLARE_WAITQUEUE
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+	wait_queue_head_t	delta_msr_wait;
+#else	
+	struct wait_queue	*open_wait;
+	struct wait_queue	*close_wait;
+	struct wait_queue	*delta_msr_wait;
+#endif	
+	struct dm270_async_s	*next_port;	/* For the linked list */
+	struct dm270_async_s	*prev_port;
+};
+typedef struct dm270_async_s dm270_async_t;
+
+#endif /* __ASM_ARCH_SERIAL_H */
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/shmparam.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/shmparam.h
--- linux-2.4.29/include/asm-arm/arch-dm270/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/shmparam.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-dm270/shmparam.h
+ *
+ * Copyright (c) 1996 Russell King.
+ */
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/system.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/system.h
--- linux-2.4.29/include/asm-arm/arch-dm270/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/system.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,14 @@
+/*
+ * linux/include/asm-armnommu/arch-dm270/system.h
+ */
+
+static inline void arch_idle(void)
+{
+  while (!current->need_resched && !hlt_counter);
+}
+
+extern inline void arch_reset(char mode)
+{
+	/* Jump into ROM at 0x00100000 */
+	cpu_reset(FLASH_MEM_BASE);
+}
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/time.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/time.h
--- linux-2.4.29/include/asm-arm/arch-dm270/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/time.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,53 @@
+/***********************************************************************
+ * linux/include/asm-arm/arch-dm270/time.h
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/time.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#ifndef __ASM_ARCH_TIME_H__
+#define __ASM_ARCH_TIME_H__
+
+/* The actual timer initialization is performed in the file
+ * arch/armnommu/mach-dm270/time.c.  This inline function is
+ * just a thin candy coating to get to that function.
+ */
+
+extern void dm270_setup_timer(struct irqaction *timer_irq);
+
+/* setup_timer() is "called" from arch/armnommu/kernel/time.c
+ * In the context where setup_timer runs (in this context, timer_irq
+ * is declared as a static intialized variable.  Provided that
+ * the asm/arch/time.h is included AFTER this declaration, the
+ * following should be quite happy:
+ */
+
+void __inline__ setup_timer(void)
+{
+  dm270_setup_timer(&timer_irq);
+}
+
+#endif /* __ASM_ARCH_TIME_H__ */
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/timex.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/timex.h
--- linux-2.4.29/include/asm-arm/arch-dm270/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/timex.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,42 @@
+/* include/asm-armnommu/arch-dm270/timex.h:
+ *
+ * System clock frequency.
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/timex.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+/* CLOCK_TICK_RATE -- frequency fed to the timer. In our case, 87.75MHz/351.
+ * Used to compute LATCH. LATCH is the number of clock ticks per timer interrupt.
+ * (See linux/timex.h, armnommu/mach-dm270/time.c).
+ */
+
+#define CLOCK_TICK_RATE	   250000
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/uncompress.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/uncompress.h
--- linux-2.4.29/include/asm-arm/arch-dm270/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/uncompress.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,122 @@
+/*
+ * include/asm/arch/uncompress.h:
+ *         Optional routines to aid in debugging the decompression phase
+ *         of kernel boot.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/* This is used by arch/armnommu/boot/compressed/misc.c to write progress info
+ * out the serial port so that the user can see debug messages up to the point
+ * where the kernel is decompressed. The STANDALONE_DEBUG macro chooses between
+ * this and the standard printf. Punt.
+ * --gmcnutt
+ */
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_DEBUG_DM270_UART1
+# define DM270_UART_BASE	DM270_UART1_BASE
+# define DM270_CLKC_UART_SHIFT	1
+#else
+# define DM270_UART_BASE	DM270_UART0_BASE
+# define DM270_CLKC_UART_SHIFT	0
+#endif
+
+static inline void
+putc(char c)
+{
+    while (!(__arch_readw(DM270_UART_BASE+DM270_UART_SR) & DM270_UART_SR_TREF));
+
+    __arch_writew(c, DM270_UART_BASE+DM270_UART_DTRR);
+}
+
+/* Hardware-specific routine to put a string to the debug UART, converting
+ * "\n" to "\n\r" on the way */
+
+static void
+puts(const char *s)
+{
+	while (*s) {
+		putc(*s);
+		if (*s == '\n')
+			putc('\r');
+		s++;
+	}
+}
+
+/* If we need to do some setup prior to decompression (like initializing the
+ * UART if we want to use puts() above) then we define it here. Punt.
+ */
+
+static inline void
+arch_decomp_setup(void)
+{
+	/* Disable clock to UART. */
+	__arch_writew((__arch_readw(DM270_CLKC_MOD2) &
+			~(DM270_CLKC_MOD2_CUAT << DM270_CLKC_UART_SHIFT)),
+			DM270_CLKC_MOD2);
+
+	/* Select CLK_ARM as UART clock source */
+	__arch_writew((__arch_readw(DM270_CLKC_CLKC) &
+			~(DM270_CLKC_CLKC_CUAS << DM270_CLKC_UART_SHIFT)),
+			DM270_CLKC_CLKC);
+
+	/* Enable clock to UART. */
+	__arch_writew((__arch_readw(DM270_CLKC_MOD2) |
+			(DM270_CLKC_MOD2_CUAT << DM270_CLKC_UART_SHIFT)),
+			DM270_CLKC_MOD2);
+
+#ifdef CONFIG_DEBUG_DM270_UART1
+	/* Configure GIO23 & GIO24 as RXD1 & TXD1 respectively */
+	__arch_writew((__arch_readw(DM270_GIO_FSEL0) | DM270_GIO_FSEL_RXD1),
+			DM270_GIO_FSEL0);
+	__arch_writew((__arch_readw(DM270_GIO_FSEL1) | DM270_GIO_FSEL_TXD1),
+			DM270_GIO_FSEL1);
+#endif
+
+	/* 8-1-no parity. Enable receive interrupts. */
+	__arch_writew((DM270_UART_MSR_8_DBITS | DM270_UART_MSR_1_SBITS |
+			DM270_UART_MSR_NO_PARITY | DM270_UART_MSR_TIMEOUT_DISABLED |
+			DM270_UART_MSR_REIE | DM270_UART_MSR_RFTIE),
+			DM270_UART_BASE+DM270_UART_MSR);
+
+	/* Set bit rate. */
+	__arch_writew(DM270_UART_BRSR_VAL(_DEFAULT_BAUD),
+			DM270_UART_BASE+DM270_UART_BRSR);
+
+	/* Clear & enable FIFO. */
+	/* Set interrupt trigger level to be 1 byte. */
+	__arch_writew((DM270_UART_TFCR_TRG_1 | DM270_UART_TFCR_CLEAR),
+			DM270_UART_BASE+DM270_UART_TFCR);
+	__arch_writew((DM270_UART_RFCR_TRG_1 | DM270_UART_RFCR_RESET |
+			DM270_UART_RFCR_CLEAR), DM270_UART_BASE+DM270_UART_RFCR);
+}
+
+/* Not sure what this is for. Probably an optional watchdog to check if the
+ * decompress got hung so we can warn the user. Punt.
+ */
+#define arch_decomp_wdog()
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/vmalloc.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/vmalloc.h
--- linux-2.4.29/include/asm-arm/arch-dm270/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/vmalloc.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,36 @@
+/*
+ * linux/include/asm-arm/arch-dm270/vmalloc.h
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/vmalloc.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/* Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+
diff -urN linux-2.4.29/include/asm-arm/arch-dm270/wdt_ioctl.h linux-2.4.29-uc1/include/asm-arm/arch-dm270/wdt_ioctl.h
--- linux-2.4.29/include/asm-arm/arch-dm270/wdt_ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-dm270/wdt_ioctl.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,48 @@
+/*
+ *	Generic watchdog defines. Derived from..
+ *
+ * Berkshire PC Watchdog Defines
+ * by Ken Hollis <khollis@bitgate.com>
+ *
+ */
+
+#ifndef _LINUX_WATCHDOG_H
+#define _LINUX_WATCHDOG_H
+
+#include <linux/ioctl.h>
+
+#define	WATCHDOG_IOCTL_BASE	'W'
+
+struct watchdog_info {
+	__u32 options;		/* Options the card/driver supports */
+	__u32 firmware_version;	/* Firmware version of the card */
+	__u8  identity[32];	/* Identity of the board */
+};
+
+#define	WDIOC_GETSUPPORT	_IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info)
+#define	WDIOC_GETSTATUS		_IOR(WATCHDOG_IOCTL_BASE, 1, int)
+#define	WDIOC_GETBOOTSTATUS	_IOR(WATCHDOG_IOCTL_BASE, 2, int)
+#define	WDIOC_GETTEMP		_IOR(WATCHDOG_IOCTL_BASE, 3, int)
+#define	WDIOC_SETOPTIONS	_IOR(WATCHDOG_IOCTL_BASE, 4, int)
+#define	WDIOC_KEEPALIVE		_IOR(WATCHDOG_IOCTL_BASE, 5, int)
+#define	WDIOC_SETTIMEOUT        _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
+#define	WDIOC_GETTIMEOUT        _IOR(WATCHDOG_IOCTL_BASE, 7, int)
+
+#define	WDIOF_UNKNOWN		-1	/* Unknown flag error */
+#define	WDIOS_UNKNOWN		-1	/* Unknown status error */
+
+#define	WDIOF_OVERHEAT		0x0001	/* Reset due to CPU overheat */
+#define	WDIOF_FANFAULT		0x0002	/* Fan failed */
+#define	WDIOF_EXTERN1		0x0004	/* External relay 1 */
+#define	WDIOF_EXTERN2		0x0008	/* External relay 2 */
+#define	WDIOF_POWERUNDER	0x0010	/* Power bad/power fault */
+#define	WDIOF_CARDRESET		0x0020	/* Card previously reset the CPU */
+#define WDIOF_POWEROVER		0x0040	/* Power over voltage */
+#define WDIOF_SETTIMEOUT	0x0080  /* Set timeout (in seconds) */
+#define	WDIOF_KEEPALIVEPING	0x8000	/* Keep alive ping reply */
+
+#define	WDIOS_DISABLECARD	0x0001	/* Turn off the watchdog timer */
+#define	WDIOS_ENABLECARD	0x0002	/* Turn on the watchdog timer */
+#define	WDIOS_TEMPPANIC		0x0004	/* Kernel panic on temperature trip */
+
+#endif  /* ifndef _LINUX_WATCHDOG_H */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/bits.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/bits.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/bits.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/bits.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,61 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+/* DO NOT EDIT!! - this file automatically generated
+ *                 from .s file by awk -f s2h.awk
+ */
+/*  Bit field defintions
+ *  Copyright (C) ARM Limited 1998. All rights reserved.
+ */
+
+#ifndef __bits_h
+#define __bits_h                        1
+
+#define BIT0                            0x00000001
+#define BIT1                            0x00000002
+#define BIT2                            0x00000004
+#define BIT3                            0x00000008
+#define BIT4                            0x00000010
+#define BIT5                            0x00000020
+#define BIT6                            0x00000040
+#define BIT7                            0x00000080
+#define BIT8                            0x00000100
+#define BIT9                            0x00000200
+#define BIT10                           0x00000400
+#define BIT11                           0x00000800
+#define BIT12                           0x00001000
+#define BIT13                           0x00002000
+#define BIT14                           0x00004000
+#define BIT15                           0x00008000
+#define BIT16                           0x00010000
+#define BIT17                           0x00020000
+#define BIT18                           0x00040000
+#define BIT19                           0x00080000
+#define BIT20                           0x00100000
+#define BIT21                           0x00200000
+#define BIT22                           0x00400000
+#define BIT23                           0x00800000
+#define BIT24                           0x01000000
+#define BIT25                           0x02000000
+#define BIT26                           0x04000000
+#define BIT27                           0x08000000
+#define BIT28                           0x10000000
+#define BIT29                           0x20000000
+#define BIT30                           0x40000000
+#define BIT31                           0x80000000
+
+#endif
+
+/*         END */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/clocks.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/clocks.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/clocks.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/clocks.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,133 @@
+/*
+ *
+ * Filename: clocks.h 
+ *
+ * Description: Header file for the clocks.
+ *
+ * Copyright(c) Cirrus Logic Corporation 2003, All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/hardware.h>
+#ifndef _H_CLOCKS
+#define _H_CLOCKS
+
+//
+// How this file works:
+// Choose your FCLOCK value this causes FDIV, HDIV, PDIV values to be set
+//
+// The Real FDIV, HDIV, and PDIV are set according to the following table.
+// Processor runs at (PLL1 speed/PLL Divide specified by FDIV)
+// AHB runs at (PLL1 speed/PLL Divide specified by HDIV)
+// APB runs at AHB/(2^PDIV)
+// ------------------------------------------------------------------
+// HDIV   PLL Divide    FDIV    PLL Divide 
+// 0      1             0       1
+// 1      2             1       2
+// 2      4             2       4
+// 3      5             3       8
+// 4      6             4       16
+// 5      8
+// 6      16
+// 7      32
+//
+//
+#ifdef CONFIG_ARCH_EP9301
+#define FCLOCK 166
+#endif
+
+#if defined(CONFIG_ARCH_EP9312) || defined(CONFIG_ARCH_EP9315)
+#define FCLOCK 200
+#endif
+
+/*
+ * PLL1 Clock =442  Mhz
+ *
+ * FClock    = 221  Mhz
+ * HCLock    = 73   Mhz
+ * PClock    = 46   Mhz
+ */
+#if (FCLOCK == 221)
+#define FDIV                        1
+#define HDIV                        5
+#define PDIV                        1
+#define PRE_CLKSET1_VALUE           0x0080b3b6
+#define PLL1_CLOCK                  442368000
+#endif /* (FCLOCK == 221) */
+
+/*
+ * PLL1 Clock =400  Mhz
+ *
+ * FClock    = 200  Mhz
+ * HCLock    = 100  Mhz
+ * PClock    = 50   Mhz
+ *
+ */
+#if (FCLOCK == 200)
+#define FDIV                        1
+#define HDIV                        2
+#define PDIV                        1
+#define PRE_CLKSET1_VALUE           0x0080a3d7
+#define PLL1_CLOCK                  399974400
+#endif /* (FCLOCK == 200) */
+
+/*
+ * PLL1 Clock =368  Mhz
+ *
+ * FClock    = 184  Mhz
+ * HCLock    = 73   Mhz
+ * PClock    = 46   Mhz             
+ *
+ */
+#if (FCLOCK == 183)
+#define FDIV                        1
+#define HDIV                        4
+#define PDIV                        1
+#define PRE_CLKSET1_VALUE           0x0080ab15
+#define PLL1_CLOCK                  368640000
+#endif /* (FCLOCK == 183) */
+
+/*
+ * PLL1 Clock =332  Mhz
+ *
+ * FClock    = 166  Mhz
+ * HCLock    = 66   Mhz
+ * PClock    = 33   Mhz             
+ *
+ */
+#if (FCLOCK == 166)
+#define FDIV                        1
+#define HDIV                        3
+#define PDIV                        1
+#define PRE_CLKSET1_VALUE           0x0080fa5a
+#define PLL1_CLOCK                  332049067
+#endif /* (FCLOCK == 166) */
+
+
+#define CLKSET1_VALUE   ( PRE_CLKSET1_VALUE | \
+                        ( PDIV << SYSCON_CLKSET1_PCLK_DIV_SHIFT ) | \
+                        ( HDIV << SYSCON_CLKSET1_HCLK_DIV_SHIFT ) | \
+                        ( FDIV << SYSCON_CLKSET1_FCLK_DIV_SHIFT ) )
+
+
+
+/*
+ * Value for the PLL 2 register.
+ */ 
+#define CLKSET2_VALUE           0x300dc317
+#define PLL2_CLOCK              192000000
+
+#endif /*  _H_CLOCKS  */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/crunch.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/crunch.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/crunch.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/crunch.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,56 @@
+#ifndef	__asm_crunch_h__
+#define	__asm_crunch_h__
+
+#include "asm/arch/regmap.h"
+
+#define	CRUNCH_INIT	0x00900000
+#define	CRUNCH_IRQ	58
+
+#ifndef	__ASSEMBLY__
+
+/* enable the MaverickCrunch clock */
+static inline void crunch_enable(void)
+{
+	int tmp, aa = 0xAA;
+	int *lock = (int *)SYSCON_SWLOCK;
+	int *syscfg = (int *)SYSCON_DEVCFG;
+
+	asm volatile (
+	"str    %3, [%1]\n\t"
+	"ldr    %0, [%2]\n\t"
+	"orr    %0, %0, #(1 << 23)\n\t"
+	"str    %0, [%2]"
+	:"=r" (tmp)
+	:"r" (lock), "r" (syscfg), "r" (aa)
+	:"memory" );
+}
+
+
+/* disable the MaverickCrunch clock */
+static inline void crunch_disable(void)
+{
+	int tmp, aa = 0xAA;
+	int *lock = (int *)SYSCON_SWLOCK;
+	int *syscfg = (int *)SYSCON_DEVCFG;
+
+	asm volatile (
+	"str    %3, [%1]\n\t"
+	"ldr    %0, [%2]\n\t"
+	"bic    %0, %0, #(1 << 23)\n\t"
+	"str    %0, [%2]"
+	:"=r" (tmp)
+	:"r" (lock), "r" (syscfg), "r" (aa)
+	:"memory" );
+}
+
+
+unsigned int read_dspsc_low(void);
+unsigned int read_dspsc_high(void);
+void write_dspsc(unsigned int);
+void save_crunch(struct task_struct *);
+void restore_crunch(struct task_struct *);
+int setup_crunch(void);
+void crunch_init(void);
+#endif
+
+#endif	/* __asm_crunch_h__ */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/cx25871.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/cx25871.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/cx25871.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/cx25871.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,80 @@
+/*
+ * Filename: cx25871.h
+ *                                                                     
+ * Description: Regisister Definitions and function prototypes for
+ *             CX25871 NTSC/PAL encoder.
+ *
+ * Copyright(c) Cirrus Logic Corporation 2003, All Rights Reserved                       
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+#ifndef _H_CX25871
+#define _H_CX25871
+
+//
+// CS25871 Device Address.
+//
+#define CX25871_DEV_ADDRESS                     0x88
+
+//
+// Register 0x32
+//
+#define CX25871_REGx32_AUTO_CHK                 0x80
+#define CX25871_REGx32_DRVS_MASK                0x60
+#define CX25871_REGx32_DRVS_SHIFT               5
+#define CX25871_REGx32_SETUP_HOLD               0x10
+#define CX25871_REGx32_INMODE_                  0x08
+#define CX25871_REGx32_DATDLY_RE                0x04
+#define CX25871_REGx32_OFFSET_RGB               0x02
+#define CX25871_REGx32_CSC_SEL                  0x01
+
+//
+// Register 0xBA
+//
+#define CX25871_REGxBA_SRESET                   0x80
+#define CX25871_REGxBA_CHECK_STAT               0x40
+#define CX25871_REGxBA_SLAVER                   0x20
+#define CX25871_REGxBA_DACOFF                   0x10
+#define CX25871_REGxBA_DACDISD                  0x08
+#define CX25871_REGxBA_DACDISC                  0x04
+#define CX25871_REGxBA_DACDISB                  0x02
+#define CX25871_REGxBA_DACDISA                  0x01
+
+//
+// Register 0xC4
+//
+#define CX25871_REGxC4_ESTATUS_MASK             0xC0
+#define CX25871_REGxC4_ESTATUS_SHIFT            6
+#define CX25871_REGxC4_ECCF2                    0x20
+#define CX25871_REGxC4_ECCF1                    0x10
+#define CX25871_REGxC4_ECCGATE                  0x08
+#define CX25871_REGxC4_ECBAR                    0x04
+#define CX25871_REGxC4_DCHROMA                  0x02
+#define CX25871_REGxC4_EN_OUT                   0x01
+                                                
+
+//
+// Register 0xC6
+//
+#define CX25871_REGxC6_EN_BLANKO                0x80
+#define CX25871_REGxC6_EN_DOT                   0x40
+#define CX25871_REGxC6_FIELDI                   0x20
+#define CX25871_REGxC6_VSYNCI                   0x10
+#define CX25871_REGxC6_HSYNCI                   0x08
+#define CX25871_REGxC6_INMODE_MASK              0x07
+#define CX25871_REGxC6_INMODE_SHIFT             0
+
+#endif // _H_CX25871
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/dma.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/dma.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/dma.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,246 @@
+/*****************************************************************************
+ *  linux/include/asm-arm/arch-ep93xx/dma.h
+ *
+ *  Copyright (C) 2003 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ ****************************************************************************/
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_ADDRESS     0xffffffff
+
+/*
+ *  Not using the regular generic DMA interface for ep93xx.
+ */
+#define MAX_DMA_CHANNELS   0
+
+/*
+ * The ep93xx dma controller has 5 memory to peripheral (TX) channels, 5
+ * peripheral to memory (RX) channels and 2 memory to memory channels.
+ */
+#define MAX_EP93XX_DMA_M2P_CHANNELS 10
+#define MAX_EP93XX_DMA_M2M_CHANNELS 2
+
+/*
+ * The generic arm linux api does not support the ep93xx dma model, therefore
+ * we use a set of dma support functions written specifically for this dma
+ * controller.
+ */
+#define MAX_EP93XX_DMA_CHANNELS (MAX_EP93XX_DMA_M2P_CHANNELS + MAX_EP93XX_DMA_M2M_CHANNELS)
+
+/*****************************************************************************
+ *
+ * Max DMA buffer size
+ *
+ ****************************************************************************/
+#define DMA_MAX_BUFFER_BYTES    0xFFFF
+
+/*****************************************************************************
+ *
+ * typedefs
+ *
+ ****************************************************************************/
+
+/*****************************************************************************
+ *
+ * All devices which can use a DMA channel
+ *
+ * NOTE: There exist two types of DMA channels, those that transfer
+ *       between an internal peripheral and memory (M2P/P2M), and
+ *       those that transfer between an external peripheral and memory (M2M).
+ *       This becomes a bit confusing when you take into account the fact
+ *       that the M2M channels can also transfer between two specific
+ *       internal peripherals and memory.
+ *       The first 20 enumerated devices use the first type of channel (M2P/
+ *       P2M).  The last six enumerations are specific to the M2M channels.
+ *
+ ****************************************************************************/
+typedef enum
+{
+    /*
+     *  Hardware device options for the 10 M2P/P2M DMA channels.
+     */
+    DMATx_I2S1 = 0x00000000,    /* TX peripheral ports can be allocated an  */
+    DMATx_I2S2 = 0x00000001,    /* even numbered DMA channel.               */
+    DMATx_AAC1 = 0x00000002,
+    DMATx_AAC2 = 0x00000003,
+    DMATx_AAC3 = 0x00000004,
+    DMATx_I2S3 = 0x00000005,
+    DMATx_UART1 = 0x00000006,
+    DMATx_UART2 = 0x00000007,
+    DMATx_UART3 = 0x00000008,
+    DMATx_IRDA = 0x00000009,
+    DMARx_I2S1 = 0x0000000A,    /* RX perhipheral ports can be allocated an */
+    DMARx_I2S2 = 0x0000000B,    /* odd numbered DMA channel.                */
+    DMARx_AAC1 = 0x0000000C,
+    DMARx_AAC2 = 0x0000000D,
+    DMARx_AAC3 = 0x0000000E,
+    DMARx_I2S3 = 0x0000000F,
+    DMARx_UART1 = 0x00000010,
+    DMARx_UART2 = 0x00000011,
+    DMARx_UART3 = 0x00000012,
+    DMARx_IRDA = 0x00000013,
+
+    /*
+     *  Device options for the 2 M2M DMA channels
+     */
+    DMA_MEMORY = 0x00000014,
+    DMA_IDE = 0x00000015,
+    DMARx_SSP = 0x00000016,
+    DMATx_SSP = 0x00000017,
+    DMATx_EXT_DREQ = 0x00000018,
+    DMARx_EXT_DREQ = 0x00000019,
+    UNDEF = 0x0000001A
+} ep93xx_dma_dev_t;
+
+/*****************************************************************************
+ *
+ * Enumerated type used as a parameter for a callback function.
+ * Indicates the type of interrupt.
+ *
+ ****************************************************************************/
+typedef enum
+{
+    /*
+     *  Common interrupts
+     */
+    STALL,
+    NFB,
+
+    /*
+     *  Specific to M2P channels
+     */
+    CHERROR,
+
+    /*
+     *  Specific to M2M channels
+     */
+    DONE,
+    UNDEF_INT
+} ep93xx_dma_int_t;
+
+/*****************************************************************************
+ *
+ * Init flag bit defintions for M2P/P2M flags.
+ *
+ ****************************************************************************/
+
+/*
+ *  Channel error interrupt enable.
+ */
+#define CHANNEL_ERROR_INT_ENABLE    0x00000001
+
+/*
+ *  Determines how the channel state machine behaves in the NEXT state and
+ *  in receipt of a peripheral error.
+ *  0 -> NEXT -> ON (ignore the peripheral error.)
+ *  1 -> NEXT -> STALL (effectively disable the channel.)
+ */
+#define CHANNEL_ABORT               0x00000002
+
+/*
+ *  Ignore channel error interrupt.
+ */
+#define IGNORE_CHANNEL_ERROR        0x00000004
+
+/*****************************************************************************
+ *
+ * Init flag bit defintions for M2M flags.
+ *
+ ****************************************************************************/
+
+/*
+ *  Destination address hold.  This should be set for IDE write transfers
+ */
+#define DESTINATION_HOLD            0x0000001
+
+/*
+ *  Source Address hold. This should be set for IDE read transfers
+ */
+#define SOURCE_HOLD                 0x0000002
+
+/*
+ *  Transfer mode.
+ *  00 - s/w initiated M2M transfer
+ *  01 - h/w initiated external peripheral transfer - memory to external
+ *       peripheral/IDE/SSP.
+ *  10 - h/w initiated external peripheral transfer - external
+ *        peripheral/IDE/SSP to memory.
+ *  11 - not used.
+ */
+#define TRANSFER_MODE_MASK          0x000000C
+#define TRANSFER_MODE_SHIFT         2
+#define TRANSFER_MODE_SW            0x0000000
+#define TRANSFER_MODE_HW_M2P        0x0000004
+#define TRANSFER_MODE_HW_P2M        0x0000008
+
+/*
+ *  Peripheral wait states count. Latency in HCLK cycles needed by the
+ *  peripheral to de-assert its request line once the transfer is
+ *  finished.
+ *
+ *  IDE Operation           Wait States
+ *  --------------          ------------
+ *  IDE MDMA read               0
+ *  IDE MDMA write              3
+ *  IDE UDMA read               1
+ *  IDE UDMA write              2
+ */
+#define WAIT_STATES_MASK            0x00007F0
+#define WAIT_STATES_SHIFT           4
+#define WS_IDE_MDMA_READ            0
+#define WS_IDE_MDMA_WRITE           3
+#define WS_IDE_UDMA_READ            1
+#define WS_IDE_UDMA_WRITE           2
+
+/*****************************************************************************
+ *
+ * Type definition for the callback function
+ *
+ ****************************************************************************/
+typedef void (* dma_callback)(ep93xx_dma_int_t dma_int,
+                              ep93xx_dma_dev_t device,
+                              unsigned int user_data);
+
+/*****************************************************************************
+ *
+ * API function prototypes
+ *
+ ****************************************************************************/
+extern int ep93xx_dma_request(int * handle, const char *device_id,
+                              ep93xx_dma_dev_t device);
+extern int ep93xx_dma_free(int handle);
+extern int ep93xx_dma_config(int handle, unsigned int flags_m2p,
+                             unsigned int flags_m2m,
+                             dma_callback callback, unsigned int user_data);
+extern int ep93xx_dma_add_buffer(int handle, unsigned int source,
+                                 unsigned int dest, unsigned int size,
+                                 unsigned int last, unsigned int buf_id);
+extern int ep93xx_dma_remove_buffer(int handle, unsigned int * buf_id);
+extern int ep93xx_dma_start(int handle, unsigned int channels,
+                            unsigned int * handles);
+extern int ep93xx_dma_pause(int handle, unsigned int channels,
+                            unsigned int * handles);
+extern int ep93xx_dma_flush(int handle);
+extern int ep93xx_dma_queue_full(int handle);
+extern int ep93xx_dma_get_position(int handle, unsigned int * buf_id,
+                    unsigned int * total, unsigned int * current_frac);
+extern int ep93xx_dma_get_total(int handle);
+extern int ep93xx_dma_is_done(int handle);
+
+#endif /* _ASM_ARCH_DMA_H */
+
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/ee.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/ee.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/ee.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/ee.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+/*
+ *  header file for linux/arch/arm/mach-ep93xx/ee.c
+ *
+ *  Copyright (C) 2003 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+ 
+/* This file intentionally left blank */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/hardware.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/hardware.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/hardware.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,59 @@
+/*
+ *  File:   linux/include/asm-arm/arch-ep93xx/hardware.h
+ *
+ *  Copyright (C) 2003 Cirrus Logic, Inc
+ *  
+ *  Copyright (C) 1999 ARM Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/arch/memory.h>
+#include <asm/arch/regmap.h>
+
+/*
+ * When adding your regs-*.h file here, please be careful to not have any
+ * macros being doubly defined.  You may need to comment out a section of
+ * regmap.h to prevent that.
+ */
+#include <asm/arch/regs_ac97.h>
+#include <asm/arch/regs_dma.h>
+#include <asm/arch/regs_gpio.h>
+#include <asm/arch/regs_ide.h>
+#include <asm/arch/regs_i2s.h>
+#include <asm/arch/regs_irda.h>
+#include <asm/arch/regs_raster.h>
+#include <asm/arch/regs_smc.h>
+#include <asm/arch/regs_spi.h>
+#include <asm/arch/regs_syscon.h>
+#include <asm/arch/regs_touch.h>
+#include <asm/arch/regs_uart.h>
+
+
+#include <asm/arch/cx25871.h>
+
+/*
+ * Here's a safe way for calculating jiffies that won't break if the
+ * value of HZ changes.
+ */
+#ifndef	MSECS_TO_JIFFIES
+#define MSECS_TO_JIFFIES(ms) (((ms)*HZ+999)/1000)
+#endif
+
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/ide.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/ide.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/ide.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,65 @@
+/*****************************************************************************
+ *  linux/include/asm-arm/arch-ep93xx/ide.h
+ *
+ *  IDE definitions for the EP93XX architecture
+ *
+ *  Copyright (c) 2003 Cirrus Logic, Inc., All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ ****************************************************************************/
+#ifndef ASM_ARCH_IDE_H
+#define ASM_ARCH_IDE_H
+
+/*****************************************************************************
+ *
+ * Set up a hw structure for a specified data port, control port and IRQ.
+ * This should follow whatever the default interface uses.
+ *
+ ****************************************************************************/
+static __inline__ void
+ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int *irq)
+{
+	ide_ioreg_t reg;
+	int i;
+
+	memset(hw, 0, sizeof(*hw));
+
+	reg = (ide_ioreg_t)data_port;
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = reg;
+		reg += 1;
+	}
+
+	hw->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t)ctrl_port;
+
+	if(irq)
+		*irq = 0;
+}
+
+/*****************************************************************************
+ *
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ *
+ ****************************************************************************/
+#ifdef CONFIG_BLK_DEV_IDE_EP93XX
+extern void ep93xx_ide_init(void);
+#define ide_init_default_hwifs ep93xx_ide_init
+#else
+#define ide_init_default_hwifs()
+#endif
+
+#endif /* ASM_ARCH_IDE_H */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/io.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/io.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/io.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,60 @@
+/*
+ *  File:	linux/include/asm-arm/arch-ep93xx/io.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a)			((unsigned long)(a))
+#define __mem_pci(a)		((unsigned long)(a))
+#define __mem_isa(a)		((unsigned long)(a))
+
+/*
+ * Generic virtual read/write
+ */
+#define __arch_getw(a)		(*(volatile unsigned short *)(a))
+#define __arch_putw(v,a)	(*(volatile unsigned short *)(a) = (v))
+
+/*
+ * Validate the pci memory address for ioremap.
+ */
+#define iomem_valid_addr(iomem,size)	(1)
+
+/*
+ * Convert PCI memory space to a CPU physical address.  This is only used
+ * by ioremap().  We will feed ioremap with yummy physical addresses and
+ * it will do its magical mystical thing and remap them to some random
+ * virtual address that it will give us.
+ */
+#define iomem_to_phys(iomem)	(iomem)
+
+/*
+ * These routines are used to hack the default ide i/o routines in
+ * drivers/ide/ide-iops.h so they work with PCMCIA IDE.  Sad, but
+ * necessary.	They are fleshed out in arch/arm/mach-ep93xx/pcmcia_io.c.
+ */
+inline u8 ep93xx_pcmcia_ide_inb (unsigned long port);
+inline u16 ep93xx_pcmcia_ide_inw (unsigned long port);
+inline void ep93xx_pcmcia_ide_insw (unsigned long port, void *addr, u32 count);
+inline void ep93xx_pcmcia_ide_outb (u8 addr, unsigned long port);
+inline void ep93xx_pcmcia_ide_outw (u16 addr, unsigned long port);
+inline void ep93xx_pcmcia_ide_outsw (unsigned long port, void *addr, u32 count);
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/irq.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/irq.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/irq.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,20 @@
+/*
+ *  linux/include/asm-arm/arch-ep93xx/irq.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#define fixup_irq(i)	(i)
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/irqs.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/irqs.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/irqs.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,105 @@
+/*
+ *  File:	linux/include/asm-arm/arch-ep93xx/irqs.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/* 
+ *  Linux IRQ interrupts definitions here.
+ *	TBD not worth the effort to put duplicate bit defines in platform.h
+ *
+ *	Current IRQ implementation
+ *
+ *	1.  Current implementation does not support vectored 
+ *          interrupts.  support for this feature may be 
+ *          added later.
+ *	2.  FIQs are ignored.  None are assigned.
+ *	3.  All interrupts are assigned to IRQs.
+ *	5.  IRQ numbers are same as interrupt bit numbers.
+ *
+ */
+
+#define IRQ_RFU0	0
+#define IRQ_RFU1	1
+#define IRQ_COMMRX	2
+#define IRQ_COMMTX	3
+#define IRQ_TIMER1	4
+#define IRQ_TIMER2	5
+#define IRQ_AAC         6
+#define IRQ_DMAM2P0	7
+#define IRQ_DMAM2P1	8
+#define IRQ_DMAM2P2     9
+#define IRQ_DMAM2P3	10
+#define IRQ_DMAM2P4	11
+#define IRQ_DMAM2P5	12
+#define IRQ_DMAM2P6	13
+#define IRQ_DMAM2P7	14
+#define IRQ_DMAM2P8	15
+#define IRQ_DMAM2P9     16
+#define IRQ_DMAM2M0	17
+#define IRQ_DMAM2M1	18
+#define IRQ_GPIO0	19
+#define IRQ_GPIO1	20
+#define IRQ_GPIO2	21
+#define IRQ_GPIO3	22
+#define IRQ_UARTRX1	23
+#define IRQ_UARTTX1	24
+#define IRQ_UARTRX2	25
+#define IRQ_UARTTX2	26
+#define IRQ_UARTRX3	27
+#define IRQ_UARTTX3	28
+#define IRQ_KEY	        29
+#define IRQ_TOUCH	30
+#define IRQ_GRAPHICS	31
+
+#define INT1_IRQS       0xfffffffc
+
+#define IRQ_EXT0	32
+#define IRQ_EXT1	33
+#define IRQ_EXT2	34
+#define IRQ_64HZ	35
+#define IRQ_WEINT	36
+#define IRQ_RTC 	37
+#define IRQ_IRDA	38
+#define IRQ_MAC 	39
+#define IRQ_EXT3	40
+#define IRQ_EIDE	IRQ_EXT3
+#define IRQ_PROG	41
+#define IRQ_1HZ 	42
+#define IRQ_VSYNC	43
+#define IRQ_VIDEOFIFO	44
+#define IRQ_SSPRX	45
+#define IRQ_SSPTX	46
+#define IRQ_GPIO4	47
+#define IRQ_GPIO5	48
+#define IRQ_GPIO6	49
+#define IRQ_GPIO7	50
+#define IRQ_TIMER3	51
+#define IRQ_UART1	52
+#define IRQ_SSP 	53
+#define IRQ_UART2	54
+#define IRQ_UART3	55
+#define IRQ_USH 	56
+#define IRQ_PME 	57
+#define IRQ_DSP 	58
+#define IRQ_GPIO	59
+#define IRQ_SAI		60
+#define IRQ_RFU61	61
+#define IRQ_RFU62	62
+#define IRQ_RFU63	63
+
+#define INT2_IRQS       0x1fffffff
+
+#define NR_IRQS         61
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/keyboard.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/keyboard.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/keyboard.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ *  linux/include/asm-arm/arch-integrator/keyboard.h
+ *
+ *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it 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
+ *
+ *  Keyboard driver definitions for the Integrator architecture
+ */
+#include <asm/irq.h>
+
+// Scancode mapping is as follows:
+//
+//	Scancode = keycode if key down event
+//	Scancode = keycode|KBUP if key up event
+//
+//	Valid keycodes are 1..0x7F and are defined by the table
+//	in keymap_dave.map.  Keycode 0 is reserved to mean invalid.
+//
+//	Keycodes are computed from scanned key matrix as follows:
+
+#define	KEYCODE( row, col)	( ((row)<<4) + (col) + 1)
+#define KBUP	0x80
+#define NR_SCANCODES 128	//TBD used?
+
+
+#ifdef CONFIG_EP93XX_KBD_SCANNED
+void __init ep93xx_scan_kbd_hw_init(void);
+#define kbd_init_hw()			ep93xx_scan_kbd_hw_init()			
+#elif defined CONFIG_EP93XX_KBD_SPI
+void __init EP93XXSpiKbdInit(void);
+#define kbd_init_hw()			EP93XXSpiKbdInit()
+#elif defined CONFIG_EP93XX_KBD_USB
+void __init EP93XXUSBKbdInit(void);
+#define kbd_init_hw()			EP93XXUSBKbdInit()
+#endif
+
+#define kbd_disable_irq()		disable_irq( IRQ_KEY)
+#define kbd_enable_irq()		enable_irq( IRQ_KEY)
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/memory.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/memory.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/memory.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,79 @@
+/*
+ *  linux/include/asm-arm/arch-ep93xx/memory.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2002-2003 Cirrus Logic Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_MACH_IPD
+#define SDRAM_START                         0xc0000000
+#define PHYS_OFFSET                         (0xc0000000UL)
+#define SDRAM_NUMBER_OF_BLOCKS              1
+#define SDRAM_BLOCK_SIZE                    0x01000000
+#define SDRAM_BLOCK_START_BOUNDARY          0x00000000
+#endif
+
+/*
+ * Task size: 2GB (from 0 to base of IO in virtual space)
+ */
+#define TASK_SIZE	(0xc0000000UL)
+#define TASK_SIZE_26	(0x04000000UL)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+/*
+ * Page offset: 3GB (start of kernel memory in virtual space)
+ * Phys offset: 0   (start of kernel memory in physical space)
+ */
+#define PAGE_OFFSET	(0xc0000000UL)
+#ifndef PHYS_OFFSET
+#define PHYS_OFFSET	(0x00000000UL)
+#endif
+
+/*
+ * We take advantage of the fact that physical and virtual address can be the
+ * same.  The NUMA code is handling the large holes that might exist between
+ * all memory banks.
+ */
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET + PHYS_OFFSET)
+
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET - PHYS_OFFSET) 
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *              address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *              to an address that the kernel can use.
+ */
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x)	 __virt_to_phys(x)
+
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x)	 __phys_to_virt(x)
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/param.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/param.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/param.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,21 @@
+/*
+ *  linux/include/asm-arm/arch-integrator/param.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+#define HZ 100
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/platform.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/platform.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/platform.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/platform.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ *  linux/include/asm-arm/arch-ep93xx/platform.h
+ *
+ *  Copyright (C) 2002-2003 Cirrus Logic, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef PLATFORM_H
+#define PLATFORM_H
+
+
+ 
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/regmap.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regmap.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/regmap.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regmap.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,1290 @@
+/*
+ *  File:   linux/include/asm-arm/arch-ep93xx/regmap.h
+ *
+ *  Copyright (C) 2003 Cirrus Logic, Inc
+ *  
+ *  Copyright (C) 1999 ARM Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/sizes.h> 
+
+#ifndef __ASM_ARCH_REGMAP_H
+#define __ASM_ARCH_REGMAP_H
+
+/*
+ * Where in virtual memory the IO devices (timers, system controllers
+ * and so on).  This gets used in arch/arm/mach-ep93xx/mm.c.
+ */
+#define IO_BASE_VIRT        0xFF000000     // Virtual address of IO 
+#define IO_BASE_PHYS        0x80000000     // Physical address of IO
+#define IO_SIZE             0x00A00000     // How much?
+
+/*
+ * We don't map the PCMCIA initially.  The PCMCIA driver will use ioremap
+ * to be able to see it.  But besides that PCMCIA will not exist in the
+ * memory map.
+ */
+#define PCMCIA_BASE_VIRT    0xD0000000     // Virtual address of PCMCIA
+#define PCMCIA_BASE_PHYS    0x40000000     // Physical address of PCMCIA
+#define PCMCIA_SIZE         0x10000000     // How much?
+
+/*
+ * The memory maps and register lists below show physical addresses, while the
+ * corresponding #defines use virtual addresses.
+ */
+
+/******************************************************************/
+/*         EP93xx Memory Map and Register list                    */
+/******************************************************************/
+/*                                                                */
+/* 0000_0000 - 0000_03ff: Internal ROM Memory  (Remap Low)        */
+/* 0000_0400 - 1fff_ffff: External DRAM Memory (Remap Low)        */
+/* 0000_0000 - 1fff_ffff: External DRAM Memory (Remap High)       */
+/* 2000_0000 - 7fff_ffff: External SRAM Memory                    */
+/* 8800_0000 - 8fff_ffff: Expansion Device Memory and Registers   */
+/* 9000_0000 - 9fff_ffff: Expansion memory                        */
+/* A000_0000 - Afff_ffff: PCMCIA Memory, I/O, and Attribute space */
+/* B000_0000 - ffff_ffff: External SRAM memory                    */
+
+/******************************************************************/
+/*           EP93xx AHB Blocks Base Address                       */
+/******************************************************************/
+/*                                                                */
+/* The AHB device address map is:                                 */
+/* Start     End        Size Usage                                */
+/* 8000_0000 8000_FFFF: 64 K DMA control registers                */
+/* 8001_0000 8001_FFFF: 64 K Ethernet MAC control registers       */
+/* 8002_0000 8002_FFFF: 64 K USB Host control registers           */
+/* 8003_0000 8003_FFFF: 64 K Raster control registers             */
+/* 8004_0000 8004_FFFF: 64 K Graphics control registers           */
+/* 8005_0000 8005_FFFF: 64 K Reserved                             */
+/* 8006_0000 8006_FFFF: 64 K SDRAM control registes               */
+/* 8007_0000 8007_FFFF: 64 K ARM920T slave                        */
+/* 8008_0000 8008_FFFF: 64 K SMC_PCMCIA control registers         */
+/* 8009_0000 8009_FFFF: 64 K Boot ROM physical address            */
+/* 800A_0000 800A_FFFF: 64 K IDE control registers                */
+/* 800B_0000 800B_FFFF: 64 K VIC1 control registers               */
+/* 800C_0000 800C_FFFF: 64 K VIC2 control registers               */
+/* TAG: literal */
+#define EP93XX_AHB_BASE (IO_BASE_VIRT)
+
+/* ARM920T Address Description                             */
+/*                                                         */
+/* 0x8000.0000 -> 0x8000.003C M2P Channel 0 Registers (Tx) */
+/* 0x8000.0040 -> 0x8000.007C M2P Channel 1 Registers (Rx) */
+/* 0x8000.0080 -> 0x8000.00BC M2P Channel 2 Registers (Tx) */ 
+/* 0x8000.00C0 -> 0x8000.00FC M2P Channel 3 Registers (Rx) */
+/* 0x8000.0100 -> 0x8000.013C M2M Channel 0 Registers      */
+/* 0x8000.0140 -> 0x8000.017C M2M Channel 1 Registers      */
+/* 0x8000.0180 -> 0x8000.01BC Not Used                     */
+/* 0x8000.01C0 -> 0x8000.01FC Not Used                     */
+/* 0x8000.0200 -> 0x8000.023C M2P Channel 5 Registers (Rx) */
+/* 0x8000.0240 -> 0x8000.027C M2P Channel 4 Registers (Tx) */
+/* 0x8000.0280 -> 0x8000.02BC M2P Channel 7 Registers (Rx) */
+/* 0x8000.02C0 -> 0x8000.02FC M2P Channel 6 Registers (Tx) */
+/* 0x8000.0300 -> 0x8000.033C M2P Channel 9 Registers (Rx) */
+/* 0x8000.0340 -> 0x8000.037C M2P Channel 8 Registers (Tx) */
+/* 0x8000.0380 DMA Channel Arbitration register            */
+/* 0x8000.03C0 DMA Global Interrupt register               */
+/* 0x8000.03C4 -> 0x8000.03FC Not Used                     */
+
+
+/* Internal M2P/P2M Channel Register Map                   */
+
+/* Offset Name      Access  Bits Reset Value               */
+/* 0x00   CONTROL   R/W     6    0                         */
+/* 0x04   INTERRUPT R/W TC* 3    0                         */
+/* 0x08   PPALLOC   R/W     4    channel dependant         */
+/*                               (see reg description)     */
+/* 0x0C   STATUS    RO      8    0                         */
+/* 0x10   reserved                                         */
+/* 0x14   REMAIN    RO      16   0                         */
+/* 0X18   Reserved                                         */
+/* 0X1C   Reserved                                         */
+/* 0x20   MAXCNT0   R/W     16   0                         */
+/* 0x24   BASE0     R/W     32   0                         */
+/* 0x28   CURRENT0  RO      32   0                         */
+/* 0x2C   Reserved                                         */
+/* 0x30   MAXCNT1   R/W     16   0                         */
+/* 0x34   BASE1     R/W     32   0                         */
+/* 0X38   CURRENT1  RO      32   0                         */
+/* 0X3C   Reserved                                         */
+/*                                                         */
+/* M2M Channel Register Map                                */
+/* Offset Name         Access   Bits Reset Value           */
+/*                                                         */
+/* 0x00   CONTROL      R/W      22   0                     */
+/* 0x04   INTERRUPT    R/W TC*  3    0                     */
+/* 0x08   Reserved                                         */
+/* 0x0C   STATUS       R/W TC*  14   0                     */
+/* 0x10   BCR0         R/W      16   0                     */
+/* 0x14   BCR1         R/W      16   0                     */
+/* 0x18   SAR_BASE0    R/W      32   0                     */
+/* 0x1C   SAR_BASE1    R/W      32   0                     */
+/* 0x20   Reserved                                         */
+/* 0x24   SAR_CURRENT0 RO       32   0                     */
+/* 0x28   SAR_CURRENT1 RO       32   0                     */
+/* 0x2C   DAR_BASE0    R/W      32   0                     */
+/* 0x30   DAR_BASE1    R/W      32   0                     */
+/* 0x34   DAR_CURRENT0 RO       32   0                     */
+/* 0X38   Reserved                                         */
+/* 0X3C   DAR_CURRENT1 RO       32   0                     */     
+/* * Write this location once to clear the bit (see        */
+/* Interrupt/Status register description for which bits    */
+/* this rule applies to).                                  */
+
+/* 8000_0000 - 8000_ffff: DMA  */
+#define DMA_OFFSET              0x000000
+#define DMA_BASE                (EP93XX_AHB_BASE|DMA_OFFSET)
+#define DMAMP_TX_0_CONTROL      (DMA_BASE+0x0000)
+#define DMAMP_TX_0_INTERRUPT    (DMA_BASE+0x0004)
+#define DMAMP_TX_0_PPALLOC      (DMA_BASE+0x0008)
+#define DMAMP_TX_0_STATUS       (DMA_BASE+0x000C)       
+#define DMAMP_TX_0_REMAIN       (DMA_BASE+0x0014)
+#define DMAMP_TX_0_MAXCNT0      (DMA_BASE+0x0020)
+#define DMAMP_TX_0_BASE0        (DMA_BASE+0x0024)
+#define DMAMP_TX_0_CURRENT0     (DMA_BASE+0x0028)
+#define DMAMP_TX_0_MAXCNT1      (DMA_BASE+0x0030)
+#define DMAMP_TX_0_BASE1        (DMA_BASE+0x0034)
+#define DMAMP_TX_0_CURRENT1     (DMA_BASE+0x0038)
+
+#define DMAMP_RX_1_CONTROL      (DMA_BASE+0x0040)
+#define DMAMP_RX_1_INTERRUPT    (DMA_BASE+0x0044)
+#define DMAMP_RX_1_PPALLOC      (DMA_BASE+0x0048)
+#define DMAMP_RX_1_STATUS       (DMA_BASE+0x004C)       
+#define DMAMP_RX_1_REMAIN       (DMA_BASE+0x0054)
+#define DMAMP_RX_1_MAXCNT0      (DMA_BASE+0x0060)
+#define DMAMP_RX_1_BASE0        (DMA_BASE+0x0064)
+#define DMAMP_RX_1_CURRENT0     (DMA_BASE+0x0068)
+#define DMAMP_RX_1_MAXCNT1      (DMA_BASE+0x0070)
+#define DMAMP_RX_1_BASE1        (DMA_BASE+0x0074)
+#define DMAMP_RX_1_CURRENT1     (DMA_BASE+0x0078)
+
+#define DMAMP_TX_2_CONTROL      (DMA_BASE+0x0080)
+#define DMAMP_TX_2_INTERRUPT    (DMA_BASE+0x0084)
+#define DMAMP_TX_2_PPALLOC      (DMA_BASE+0x0088)
+#define DMAMP_TX_2_STATUS       (DMA_BASE+0x008C)       
+#define DMAMP_TX_2_REMAIN       (DMA_BASE+0x0094)
+#define DMAMP_TX_2_MAXCNT0      (DMA_BASE+0x00A0)
+#define DMAMP_TX_2_BASE0        (DMA_BASE+0x00A4)
+#define DMAMP_TX_2_CURRENT0     (DMA_BASE+0x00A8)
+#define DMAMP_TX_2_MAXCNT1      (DMA_BASE+0x00B0)
+#define DMAMP_TX_2_BASE1        (DMA_BASE+0x00B4)
+#define DMAMP_TX_2_CURRENT1     (DMA_BASE+0x00B8)
+
+#define DMAMP_RX_3_CONTROL      (DMA_BASE+0x00C0)
+#define DMAMP_RX_3_INTERRUPT    (DMA_BASE+0x00C4)
+#define DMAMP_RX_3_PPALLOC      (DMA_BASE+0x00C8)
+#define DMAMP_RX_3_STATUS       (DMA_BASE+0x00CC)       
+#define DMAMP_RX_3_REMAIN       (DMA_BASE+0x00D4)
+#define DMAMP_RX_3_MAXCNT0      (DMA_BASE+0x00E0)
+#define DMAMP_RX_3_BASE0        (DMA_BASE+0x00E4)
+#define DMAMP_RX_3_CURRENT0     (DMA_BASE+0x00E8)
+#define DMAMP_RX_3_MAXCNT1      (DMA_BASE+0x00F0)
+#define DMAMP_RX_3_BASE1        (DMA_BASE+0x00F4)
+#define DMAMP_RX_3_CURRENT1     (DMA_BASE+0x00F8)
+
+#define DMAMM_0_CONTROL         (DMA_BASE+0x0100)
+#define DMAMM_0_INTERRUPT       (DMA_BASE+0x0104)
+#define DMAMM_0_STATUS          (DMA_BASE+0x010C)
+#define DMAMM_0_BCR0            (DMA_BASE+0x0110)
+#define DMAMM_0_BCR1            (DMA_BASE+0x0114)
+#define DMAMM_0_SAR_BASE0       (DMA_BASE+0x0118)
+#define DMAMM_0_SAR_BASE1       (DMA_BASE+0x011C)
+#define DMAMM_0_SAR_CURRENT0    (DMA_BASE+0x0124)
+#define DMAMM_0_SAR_CURRENT1    (DMA_BASE+0x0128)
+#define DMAMM_0_DAR_BASE0       (DMA_BASE+0x012C)
+#define DMAMM_0_DAR_BASE1       (DMA_BASE+0x0130)
+#define DMAMM_0_DAR_CURRENT0    (DMA_BASE+0x0134)
+#define DMAMM_0_DAR_CURRENT1    (DMA_BASE+0x013C)
+
+#define DMAMM_1_CONTROL         (DMA_BASE+0x0140)
+#define DMAMM_1_INTERRUPT       (DMA_BASE+0x0144)
+#define DMAMM_1_STATUS          (DMA_BASE+0x014C)
+#define DMAMM_1_BCR0            (DMA_BASE+0x0150)       
+#define DMAMM_1_BCR1            (DMA_BASE+0x0154)
+#define DMAMM_1_SAR_BASE0       (DMA_BASE+0x0158)
+#define DMAMM_1_SAR_BASE1       (DMA_BASE+0x015C)
+#define DMAMM_1_SAR_CURRENT0    (DMA_BASE+0x0164)
+#define DMAMM_1_SAR_CURRENT1    (DMA_BASE+0x0168)
+#define DMAMM_1_DAR_BASE0       (DMA_BASE+0x016C)
+#define DMAMM_1_DAR_BASE1       (DMA_BASE+0x0170)
+#define DMAMM_1_DAR_CURRENT0    (DMA_BASE+0x0174)
+#define DMAMM_1_DAR_CURRENT1    (DMA_BASE+0x017C)
+
+#define DMAMP_RX_5_CONTROL      (DMA_BASE+0x0200)
+#define DMAMP_RX_5_INTERRUPT    (DMA_BASE+0x0204)
+#define DMAMP_RX_5_PPALLOC      (DMA_BASE+0x0208)
+#define DMAMP_RX_5_STATUS       (DMA_BASE+0x020C)       
+#define DMAMP_RX_5_REMAIN       (DMA_BASE+0x0214)
+#define DMAMP_RX_5_MAXCNT0      (DMA_BASE+0x0220)
+#define DMAMP_RX_5_BASE0        (DMA_BASE+0x0224)
+#define DMAMP_RX_5_CURRENT0     (DMA_BASE+0x0228)
+#define DMAMP_RX_5_MAXCNT1      (DMA_BASE+0x0230)
+#define DMAMP_RX_5_BASE1        (DMA_BASE+0x0234)
+#define DMAMP_RX_5_CURRENT1     (DMA_BASE+0x0238)
+
+#define DMAMP_TX_4_CONTROL      (DMA_BASE+0x0240)
+#define DMAMP_TX_4_INTERRUPT    (DMA_BASE+0x0244)
+#define DMAMP_TX_4_PPALLOC      (DMA_BASE+0x0248)
+#define DMAMP_TX_4_STATUS       (DMA_BASE+0x024C)       
+#define DMAMP_TX_4_REMAIN       (DMA_BASE+0x0254)
+#define DMAMP_TX_4_MAXCNT0      (DMA_BASE+0x0260)
+#define DMAMP_TX_4_BASE0        (DMA_BASE+0x0264)
+#define DMAMP_TX_4_CURRENT0     (DMA_BASE+0x0268)
+#define DMAMP_TX_4_MAXCNT1      (DMA_BASE+0x0270)
+#define DMAMP_TX_4_BASE1        (DMA_BASE+0x0274)
+#define DMAMP_TX_4_CURRENT1     (DMA_BASE+0x0278)
+
+#define DMAMP_RX_7_CONTROL      (DMA_BASE+0x0280)
+#define DMAMP_RX_7_INTERRUPT    (DMA_BASE+0x0284)
+#define DMAMP_RX_7_PPALLOC      (DMA_BASE+0x0288)
+#define DMAMP_RX_7_STATUS       (DMA_BASE+0x028C)       
+#define DMAMP_RX_7_REMAIN       (DMA_BASE+0x0294)
+#define DMAMP_RX_7_MAXCNT0      (DMA_BASE+0x02A0)
+#define DMAMP_RX_7_BASE0        (DMA_BASE+0x02A4)
+#define DMAMP_RX_7_CURRENT0     (DMA_BASE+0x02A8)
+#define DMAMP_RX_7_MAXCNT1      (DMA_BASE+0x02B0)
+#define DMAMP_RX_7_BASE1        (DMA_BASE+0x02B4)
+#define DMAMP_RX_7_CURRENT1     (DMA_BASE+0x02B8)
+
+#define DMAMP_TX_6_CONTROL      (DMA_BASE+0x02C0)
+#define DMAMP_TX_6_INTERRUPT    (DMA_BASE+0x02C4)
+#define DMAMP_TX_6_PPALLOC      (DMA_BASE+0x02C8)
+#define DMAMP_TX_6_STATUS       (DMA_BASE+0x02CC)       
+#define DMAMP_TX_6_REMAIN       (DMA_BASE+0x02D4)
+#define DMAMP_TX_6_MAXCNT0      (DMA_BASE+0x02E0)
+#define DMAMP_TX_6_BASE0        (DMA_BASE+0x02E4)
+#define DMAMP_TX_6_CURRENT0     (DMA_BASE+0x02E8)
+#define DMAMP_TX_6_MAXCNT1      (DMA_BASE+0x02F0)
+#define DMAMP_TX_6_BASE1        (DMA_BASE+0x02F4)
+#define DMAMP_TX_6_CURRENT1     (DMA_BASE+0x02F8)
+
+#define DMAMP_RX_9_CONTROL      (DMA_BASE+0x0300)
+#define DMAMP_RX_9_INTERRUPT    (DMA_BASE+0x0304)
+#define DMAMP_RX_9_PPALLOC      (DMA_BASE+0x0308)
+#define DMAMP_RX_9_STATUS       (DMA_BASE+0x030C)
+#define DMAMP_RX_9_REMAIN       (DMA_BASE+0x0314)
+#define DMAMP_RX_9_MAXCNT0      (DMA_BASE+0x0320)
+#define DMAMP_RX_9_BASE0        (DMA_BASE+0x0324)
+#define DMAMP_RX_9_CURRENT0     (DMA_BASE+0x0328)
+#define DMAMP_RX_9_MAXCNT1      (DMA_BASE+0x0330)
+#define DMAMP_RX_9_BASE1        (DMA_BASE+0x0334)
+#define DMAMP_RX_9_CURRENT1     (DMA_BASE+0x0338)
+
+#define DMAMP_TX_8_CONTROL      (DMA_BASE+0x0340)
+#define DMAMP_TX_8_INTERRUPT    (DMA_BASE+0x0344)
+#define DMAMP_TX_8_PPALLOC      (DMA_BASE+0x0348)
+#define DMAMP_TX_8_STATUS       (DMA_BASE+0x034C)
+#define DMAMP_TX_8_REMAIN       (DMA_BASE+0x0354)
+#define DMAMP_TX_8_MAXCNT0      (DMA_BASE+0x0360)
+#define DMAMP_TX_8_BASE0        (DMA_BASE+0x0364)
+#define DMAMP_TX_8_CURRENT0     (DMA_BASE+0x0368)
+#define DMAMP_TX_8_MAXCNT1      (DMA_BASE+0x0370)
+#define DMAMP_TX_8_BASE1        (DMA_BASE+0x0374)
+#define DMAMP_TX_8_CURRENT1     (DMA_BASE+0x0378)
+
+#define DMA_ARBITRATION         (DMA_BASE+0x0380)
+#define DMA_INTERRUPT           (DMA_BASE+0x03C0)
+
+
+/*
+ * DMA Register Base addresses and Offsets
+ */
+#define DMA_M2P_TX_0_BASE       DMAMP_TX_0_CONTROL
+#define DMA_M2P_RX_1_BASE       DMAMP_RX_1_CONTROL
+#define DMA_M2P_TX_2_BASE       DMAMP_TX_2_CONTROL
+#define DMA_M2P_RX_3_BASE       DMAMP_RX_3_CONTROL
+#define DMA_M2M_0_BASE          DMAMM_0_CONTROL   
+#define DMA_M2M_1_BASE          DMAMM_1_CONTROL   
+#define DMA_M2P_RX_5_BASE       DMAMP_RX_5_CONTROL
+#define DMA_M2P_TX_4_BASE       DMAMP_TX_4_CONTROL
+#define DMA_M2P_RX_7_BASE       DMAMP_RX_7_CONTROL
+#define DMA_M2P_TX_6_BASE       DMAMP_TX_6_CONTROL
+#define DMA_M2P_RX_9_BASE       DMAMP_RX_9_CONTROL
+#define DMA_M2P_TX_8_BASE       DMAMP_TX_8_CONTROL
+
+#define M2P_OFFSET_CONTROL          0x0000
+#define M2P_OFFSET_INTERRUPT        0x0004
+#define M2P_OFFSET_PPALLOC          0x0008
+#define M2P_OFFSET_STATUS           0x000C       
+#define M2P_OFFSET_REMAIN           0x0014
+#define M2P_OFFSET_MAXCNT0          0x0020
+#define M2P_OFFSET_BASE0            0x0024
+#define M2P_OFFSET_CURRENT0         0x0028
+#define M2P_OFFSET_MAXCNT1          0x0030
+#define M2P_OFFSET_BASE1            0x0034
+#define M2P_OFFSET_CURRENT1         0x0038
+
+#define M2M_OFFSET_CONTROL          0x0000
+#define M2M_OFFSET_INTERRUPT        0x0004
+#define M2M_OFFSET_STATUS           0x000C
+#define M2M_OFFSET_BCR0             0x0010
+#define M2M_OFFSET_BCR1             0x0014
+#define M2M_OFFSET_SAR_BASE0        0x0018
+#define M2M_OFFSET_SAR_BASE1        0x001C
+#define M2M_OFFSET_SAR_CURRENT0     0x0024
+#define M2M_OFFSET_SAR_CURRENT1     0x0028
+#define M2M_OFFSET_DAR_BASE0        0x002C
+#define M2M_OFFSET_DAR_BASE1        0x0030
+#define M2M_OFFSET_DAR_CURRENT0     0x0034
+#define M2M_OFFSET_DAR_CURRENT1     0x003C
+
+
+
+/* 8001_0000 - 8001_ffff: Ether MAC */
+#define MAC_OFFSET              0x010000
+#define MAC_BASE                (EP93XX_AHB_BASE|MAC_OFFSET)
+#define MAC_RXCTL               (MAC_BASE+0x00)  /* 2-RW Rx  Control */
+#define MAC_TXCTL               (MAC_BASE+0x04)  /* 1-RW Tx Control */
+#define MAC_TESTCTL             (MAC_BASE+0x08)  /* 1-RW Test Control */
+#define MAC_MIICMD              (MAC_BASE+0x10)  /* 2-RW MII(Media Independent Intf) Command */
+#define MAC_MIIDATA             (MAC_BASE+0x14)  /* 2-RW MII Data */
+#define MAC_MIISTS              (MAC_BASE+0x18)  /* 1-RO MII Status */
+
+#define MAC_SELFCTL             (MAC_BASE+0x20)  /* 1-RW Self Control for LED interface */
+#define MAC_INTEN               (MAC_BASE+0x24)  /* 4-RW Intrrpt Enable */
+#define MAC_INTSTSP             (MAC_BASE+0x28)  /* 4-RW Intrrpt Status Preserve */
+#define MAC_INTSTSC             (MAC_BASE+0x2C)  /* 4-RO Intrrpt Status Clear */
+
+#define MAC_DIAGAD              (MAC_BASE+0x38)  /* 4-RW Diag Addr (debug only) */
+#define MAC_DIAGDATA            (MAC_BASE+0x3C)  /* 4-RW Diag Data (debug only) */
+
+#define MAC_GT                  (MAC_BASE+0x40)  /* 4-RW General Timer */
+#define MAC_FCT                 (MAC_BASE+0x44)  /* 4-RO Flow Control Timer */
+#define MAC_FCF                 (MAC_BASE+0x48)  /* 4-RW Flow Control Format */
+#define MAC_AFP                 (MAC_BASE+0x4C)  /* 1-RW Addr Filter Pointer */
+#define MAC_HASHTB              (MAC_BASE+0x50)  /* 8-RW Logical Addr Filter (Hash Table) */
+#define MAC_INDAD               (MAC_BASE+0x50)  /* 6-RW Individual Addr, IA */
+#define MAC_INDAD_UPPER         (MAC_BASE+0x54)  /* 6-RW Individual Addr, IA */
+
+#define MAC_FER                 (MAC_BASE+0x60)  /* 4-RW Cardbus Functn Event Reg */
+#define MAC_FERMASK             (MAC_BASE+0x64)  /* 4-RW Cardbus Functn Event Mask Reg */
+#define MAC_FPSR                (MAC_BASE+0x68)  /* 4-RO Cardbus Functn Present Status Reg */
+#define MAC_FFER                (MAC_BASE+0x6C)  /* 4-RW Cardbus Functn Force Event Reg */
+#define MAC_TXCOLLCNT           (MAC_BASE+0x70)  /* 2-RW Tx Collision Count */
+#define MAC_RXMISSCNT           (MAC_BASE+0x74)  /* 2-RW Rx Miss Count */
+#define MAC_RXRUNTCNT           (MAC_BASE+0x78)  /* 2-RW Rx Runt Count */
+
+#define MAC_BMCTL               (MAC_BASE+0x80)  /* 1-RW Bus Master Control */
+#define MAC_BMSTS               (MAC_BASE+0x84)  /* 1-RO Bus Master Status */
+#define MAC_RXBCA               (MAC_BASE+0x88)  /* 4-RO Rx buffer current address */
+#define MAC_TXBCA               (MAC_BASE+0x8C)  /* 4-RO Tx buffer current address */
+#define MAC_RXDBA               (MAC_BASE+0x90)  /* 4-RW Rx Descrptr Queue Base Addr */
+#define MAC_RXDBL               (UINT16*)(MAC_BASE+0x94)  /* 2-RW Rx Descrptr Queue Base Length */
+#define MAC_RXDCA               (MAC_BASE+0x98)  /* 4-RW Rx Descrptr Current Addr */
+#define MAC_RXDEQ               (MAC_BASE+0x9C)  /* 2-RW Rx Descrptr Enqueue */ 
+#define MAC_RXSBA               (MAC_BASE+0xA0)  /* 4-RW Rx Status Queue Base Addr */
+#define MAC_RXSBL               (UINT16*)(MAC_BASE+0xA4)  /* 2-RW Rx Status Queue Base Length */
+
+#define MAC_RXSCA               (MAC_BASE+0xA8)  /* 4-RW Rx Status Current Addr */
+#define MAC_RXSEQ               (MAC_BASE+0xAC)  /* 2-RW Rx Status Enqueue */
+#define MAC_TXDBA               (MAC_BASE+0xB0)  /* 4-RW Tx Descrptr Queue Base Addr */
+#define MAC_TXDBL               (MAC_BASE+0xB4)  /* 2-RW Tx Descrptr Queue Base Length */
+#define MAC_TXDCL               (MAC_BASE+0xB6)  /* 2-RW Tx Descrptr Queue Current Length */
+#define MAC_TXDCA               (MAC_BASE+0xB8)  /* 4-RW Tx Descrptr Current Addr */
+#define MAC_TXDEQ               (MAC_BASE+0xBC)  /* 2-RW Tx Descrptr Enqueue */
+
+#define MAC_TXSBA               (MAC_BASE+0xC0)  /* 4-RW Tx status Queue Base Addr */
+#define MAC_TXSBL               (MAC_BASE+0xC4)  /* 2-RW Tx Status Queue Base Length */
+#define MAC_TXSCL               (MAC_BASE+0xC6)  /* 2-RW Tx Status Queue Current Length */
+#define MAC_TXSCA               (MAC_BASE+0xC8)  /* 4-RW Tx Status Current Addr */
+#define MAC_TXSEQ               (MAC_BASE+0xCC)  /* 4-RW Tx Status Current Addr */
+#define MAC_RXBTH               (MAC_BASE+0xD0)  /* 4-RW Rx Buffer Thrshold */
+#define MAC_TXBTH               (MAC_BASE+0xD4)  /* 4-RW Tx Buffer Thrshold */
+#define MAC_RXSTH               (MAC_BASE+0xD8)  /* 4-RW Rx Status Thrshold */
+#define MAC_TXSTH               (MAC_BASE+0xDC)  /* 4-RW Tx Status Thrshold */
+
+#define MAC_RXDTH               (MAC_BASE+0xE0)  /* 4-RW Rx Descrptr Thrshold */
+#define MAC_TXDTH               (MAC_BASE+0xE4)  /* 4-RW Tx Descrptr Thrshold */
+#define MAC_MAXFL               (MAC_BASE+0xE8)  /* 4-RW Maximum Frame Length */
+#define MAC_RXHLEN              (MAC_BASE+0xEC)  /* 2-RW Rx Header Length */
+#define MAC_CFG_REG0            (MAC_BASE+0x100) /* config registers 0-2 */
+#define MAC_CFG_REG1            (MAC_BASE+0x104) /*   */
+#define MAC_CFG_REG2            (MAC_BASE+0x108) /*   */
+
+
+/* 8002_0000 - 8002_ffff: USB */
+#define USB_OFFSET              0x020000
+#define USB_BASE                (EP93XX_AHB_BASE|USB_OFFSET)
+#define HCREVISION              (USB_BASE+0x00)
+#define HCCONTROL               (USB_BASE+0x04)
+#define HCCOMMANDSTATUS         (USB_BASE+0x08)
+#define HCINTERRUPTSTATUS       (USB_BASE+0x0C)
+#define HCINTERRUPTENABLE       (USB_BASE+0x10)
+#define HCINTERRUPTDISABLE      (USB_BASE+0x14)
+#define HCHCCA                  (USB_BASE+0x18)
+#define HCPERIODCURRENTED       (USB_BASE+0x1C)
+#define HCCONTROLHEADED         (USB_BASE+0x20)
+#define HCCONTROLCURRENTED      (USB_BASE+0x24)
+#define HCBULKHEADED            (USB_BASE+0x28)
+#define HCBULKCURRENTED         (USB_BASE+0x2C)
+#define HCDONEHEAD              (USB_BASE+0x30)
+#define HCFMINTERVAL            (USB_BASE+0x34)
+#define HCFMREMAINING           (USB_BASE+0x38)
+#define HCFMNUMBER              (USB_BASE+0x3C)
+#define HCPERIODICSTART         (USB_BASE+0x40)
+#define HCLSTHRESHOLD           (USB_BASE+0x44)
+#define HCRHDESCRIPTORA         (USB_BASE+0x48)
+#define HCRHDESCRIPTORB         (USB_BASE+0x4C)
+#define HCRHSTATUS              (USB_BASE+0x50)
+#define HCRHPORTSTATUS0         (USB_BASE+0x54)
+#define HCRHPORTSTATUS1         (USB_BASE+0x58)
+#define HCRHPORTSTATUS2         (USB_BASE+0x5C)
+/* some tests used these registers names which are typos of original ones */
+#define HCRHPROTSTATUS0         (USB_BASE+0x54)
+#define HCRHPROTSTATUS1         (USB_BASE+0x58)
+#define HCRHPROTSTATUS2         (USB_BASE+0x5C)
+/* additional registers for controlling the AHB-HCI interface */
+#define USBCTRL                 (USB_BASE+0x80)
+#define USBHCI                  (USB_BASE+0x84)
+#define USBTXTEST               (USB_BASE+0x88)
+#define USBRXTEST               (USB_BASE+0x8C)
+
+
+/* 8003_0000 - 8003_ffff: Raster */
+#define RASTER_OFFSET           0x030000
+#define RASTER_BASE             (EP93XX_AHB_BASE|RASTER_OFFSET)
+#define VLINESTOTAL             (RASTER_BASE+0x00)
+#define VSYNCSTRTSTOP           (RASTER_BASE+0x04)
+#define VACTIVESTRTSTOP         (RASTER_BASE+0x08)
+#define VCLKSTRTSTOP            (RASTER_BASE+0x0C)
+#define HCLKSTOTAL              (RASTER_BASE+0x10)
+#define HSYNCSTRTSTOP           (RASTER_BASE+0x14)
+#define HACTIVESTRTSTOP         (RASTER_BASE+0x18)
+#define HCLKSTRTSTOP            (RASTER_BASE+0x1C)
+#define BRIGHTNESS              (RASTER_BASE+0x20)
+#define VIDEOATTRIBS            (RASTER_BASE+0x24)
+#define VIDSCRNPAGE             (RASTER_BASE+0x28)
+#define VIDSCRNHPG              (RASTER_BASE+0x2C)
+#define SCRNLINES               (RASTER_BASE+0x30)
+#define LINELENGTH              (RASTER_BASE+0x34)
+#define VLINESTEP               (RASTER_BASE+0x38)
+#define LINECARRY               (RASTER_BASE+0x3C)
+#define BLINKRATE               (RASTER_BASE+0x40)
+#define BLINKMASK               (RASTER_BASE+0x44)
+#define BLINKPATTRN             (RASTER_BASE+0x48)
+#define PATTRNMASK              (RASTER_BASE+0x4C)
+#define BG_OFFSET               (RASTER_BASE+0x50)
+#define PIXELMODE               (RASTER_BASE+0x54)
+#define PARLLIFOUT              (RASTER_BASE+0x58)
+#define PARLLIFIN               (RASTER_BASE+0x5C)
+#define CURSOR_ADR_START        (RASTER_BASE+0x60)
+#define CURSOR_ADR_RESET        (RASTER_BASE+0x64)
+#define CURSORSIZE              (RASTER_BASE+0x68)
+#define CURSORCOLOR1            (RASTER_BASE+0x6C)
+#define CURSORCOLOR2            (RASTER_BASE+0x70)
+#define CURSORXYLOC             (RASTER_BASE+0x74)
+#define CURSOR_DHSCAN_LH_YLOC   (RASTER_BASE+0x78)
+#define REALITI_SWLOCK          (RASTER_BASE+0x7C)
+#define GS_LUT                  (RASTER_BASE+0x80)
+#define REALITI_TCR             (RASTER_BASE+0x100)
+#define REALITI_TISRA           (RASTER_BASE+0x104)
+#define REALITI_TISRB           (RASTER_BASE+0x108)
+#define CURSOR_TISR             (RASTER_BASE+0x10C)
+#define REALITI_TOCRA           (RASTER_BASE+0x110)
+#define REALITI_TOCRB           (RASTER_BASE+0x114)
+#define FIFO_TOCRA              (RASTER_BASE+0x118)
+#define FIFO_TOCRB              (RASTER_BASE+0x11C)
+#define BLINK_TISR              (RASTER_BASE+0x120)
+#define DAC_TISRA               (RASTER_BASE+0x124)
+#define DAC_TISRB               (RASTER_BASE+0x128)
+#define SHIFT_TISR              (RASTER_BASE+0x12C)
+#define DACMUX_TOCRA            (RASTER_BASE+0x130)
+#define DACMUX_TOCRB            (RASTER_BASE+0x134)
+#define PELMUX_TOCR             (RASTER_BASE+0x138)
+#define VIDEO_TOCRA             (RASTER_BASE+0x13C)
+#define VIDEO_TOCRB             (RASTER_BASE+0x140)
+#define YCRCB_TOCR              (RASTER_BASE+0x144)
+#define CURSOR_TOCR             (RASTER_BASE+0x148)
+#define VIDEO_TOCRC             (RASTER_BASE+0x14C)
+#define SHIFT_TOCR              (RASTER_BASE+0x150)
+#define BLINK_TOCR              (RASTER_BASE+0x154)
+#define REALITI_TCER            (RASTER_BASE+0x180)
+#define SIGVAL                  (RASTER_BASE+0x200)
+#define SIGCTL                  (RASTER_BASE+0x204)
+#define VSIGSTRTSTOP            (RASTER_BASE+0x208)
+#define HSIGSTRTSTOP            (RASTER_BASE+0x20C)
+#define SIGCLR                  (RASTER_BASE+0x210)
+#define ACRATE                  (RASTER_BASE+0x214)
+#define LUTCONT                 (RASTER_BASE+0x218)
+#define VBLANKSTRTSTOP          (RASTER_BASE+0x228)
+#define HBLANKSTRTSTOP          (RASTER_BASE+0x22C)
+#define LUT                     (RASTER_BASE+0x400)
+#define CURSORBLINK1            (RASTER_BASE+0x21C)
+#define CURSORBLINK2            (RASTER_BASE+0x220)
+#define CURSORBLINK             (RASTER_BASE+0x224)
+#define EOLOFFSET               (RASTER_BASE+0x230)
+#define FIFOLEVEL               (RASTER_BASE+0x234)
+#define GS_LUT2                 (RASTER_BASE+0x280)
+#define GS_LUT3                 (RASTER_BASE+0x300)
+#define COLOR_LUT               (RASTER_BASE+0x400)
+ 
+/* 8004_0000 - 8004_ffff: Graphics */
+#define GRAPHICS_OFFSET         0x040000
+#define GRAPHICS_BASE           (EP93XX_AHB_BASE|GRAPHICS_OFFSET)
+#define SRCPIXELSTRT            (GRAPHICS_BASE+0x00)
+#define DESTPIXELSTRT           (GRAPHICS_BASE+0x04)
+#define BLKSRCSTRT              (GRAPHICS_BASE+0x08)
+#define BLKDSTSTRT              (GRAPHICS_BASE+0x0C)
+#define BLKSRCWIDTH             (GRAPHICS_BASE+0x10)
+#define SRCLINELENGTH           (GRAPHICS_BASE+0x14)
+#define BLKDESTWIDTH            (GRAPHICS_BASE+0x18)
+#define BLKDESTHEIGHT           (GRAPHICS_BASE+0x1C)
+#define DESTLINELENGTH          (GRAPHICS_BASE+0x20)
+#define BLOCKCTRL               (GRAPHICS_BASE+0x24)
+#define TRANSPATTRN             (GRAPHICS_BASE+0x28)
+#define BLOCKMASK               (GRAPHICS_BASE+0x2C)
+#define BACKGROUND              (GRAPHICS_BASE+0x30)
+#define LINEINC                 (GRAPHICS_BASE+0x34)
+#define LINEINIT                (GRAPHICS_BASE+0x38)
+#define LINEPATTRN              (GRAPHICS_BASE+0x3C)
+
+
+
+/* 8005_0000 - 8005_ffff: Reserved  */
+
+
+
+/*8006_0000 - 8006_ffff: SDRAM  */
+#define SDRAM_OFFSET            0x060000
+#define SDRAM_BASE              (EP93XX_AHB_BASE|SDRAM_OFFSET)
+//#define SDRAMRESERVED         (SDRAM_BASE+0x00) /* Reserved */
+#define SDRAMGLOBALCFG          (SDRAM_BASE+0x04)
+#define SDRAMREFRESHTIME        (SDRAM_BASE+0x08) /* Refresh Timer */
+#define SDRAMBOOTSTATUS         (SDRAM_BASE+0x0C)
+#define SDRAMCFG0               (SDRAM_BASE+0x10) /* Configuration Register 0 (nSDCS0) */
+#define SDRAMCFG1               (SDRAM_BASE+0x14) /* Configuration Register 1 (nSDCS1) */
+#define SDRAMCFG2               (SDRAM_BASE+0x18) /* Configuration Register 2 (nSDCS2) */
+#define SDRAMCFG3               (SDRAM_BASE+0x1C) /* Configuration Register 3 (nSDCS3) */
+
+
+/* 8007_0000 - 8007_ffff: ARM920T Slave  */
+
+
+/* 8008_0000 - 8008_ffff: SRAM CS */
+
+
+/* SMC register map                                                            */
+/* Address     Read Location                   Write Location                  */
+/* 0x8000.2000 SMCBCR0(Bank config register 0) SMCBCR0(Bank config register 0) */
+/* 0x8000.2004 SMCBCR1(Bank config register 1) SMCBCR1(Bank config register 1) */
+/* 0x8000.2008 SMCBCR2(Bank config register 2) SMCBCR2(Bank config register 2) */
+/* 0x8000.200C SMCBCR3(Bank config register 3) SMCBCR3(Bank config register 3) */
+/* 0x8000.2010 Reserved, RAZ                   Reserved, RAZ                   */
+/* 0x8000.2014 Reserved, RAZ                   Reserved, RAZ                   */
+/* 0x8000.2018 SMCBCR6(Bank config register 6) SMCBCR6(Bank config register 6) */
+/* 0x8000.201C SMCBCR7(Bank config register 7) SMCBCR7(Bank config register 7) */
+/* 0x8000.2020 PCAttribute Register            PCAttribute Register            */
+/* 0x8000.2024 PCCommon Register               PCCommon Register               */
+/* 0x8000.2028 PCIO Register                   PCIO Register                   */
+/* 0x8000.202C Reserved, RAZ                   Reserved, RAZ                   */
+/* 0x8000.2030 Reserved, RAZ                   Reserved, RAZ                   */
+/* 0x8000.2034 Reserved, RAZ                   Reserved, RAZ                   */
+/* 0x8000.2038 Reserved, RAZ                   Reserved, RAZ                   */
+/* 0x8000.203C Reserved, RAZ                   Reserved, RAZ                   */
+/* 0x8000.2040 PCMCIACtrl Register             PCMCIACtrl Register             */
+
+#define SRAM_OFFSET             0x080000
+#define SRAM_BASE               (EP93XX_AHB_BASE|SRAM_OFFSET)
+#define SMCBCR0                 (SRAM_BASE+0x00) /* 0x8000.2000  Bank config register 0 */
+#define SMCBCR1                 (SRAM_BASE+0x04) /* 0x8000.2004  Bank config register 1 */
+#define SMCBCR2                 (SRAM_BASE+0x08) /* 0x8000.2008  Bank config register 2 */
+#define SMCBCR3                 (SRAM_BASE+0x0C) /* 0x8000.200C  Bank config register 3 */
+                                                 /* 0x8000.2010  Reserved, RAZ          */
+                                                 /* 0x8000.2014  Reserved, RAZ          */
+#define SMCBCR6                 (SRAM_BASE+0x18) /* 0x8000.2018  Bank config register 6 */
+#define SMCBCR7                 (SRAM_BASE+0x1C) /* 0x8000.201C  Bank config register 7 */
+
+#define SMC_PCAttribute         (SRAM_BASE+0x20) /* 0x8000.2020  PCMCIA Attribute Register */
+#define SMC_PCCommon            (SRAM_BASE+0x24) /* 0x8000.2024  PCMCIA Common Register    */
+#define SMC_PCIO                (SRAM_BASE+0x28) /* 0x8000.2028  PCMCIA IO Register        */
+                                                 /* 0x8000.202C  Reserved, RAZ           */
+											   	 /* 0x8000.2030  Reserved, RAZ           */
+												 /* 0x8000.2034  Reserved, RAZ           */
+												 /* 0x8000.2038  Reserved, RAZ           */
+                                                 /* 0x8000.203C  Reserved, RAZ           */
+#define SMC_PCMCIACtrl          (SRAM_BASE+0x40) /* 0x8000.2040  PCMCIA control register */
+
+
+/* 8009_0000 - 8009_ffff: Boot ROM (Remap low or high) */
+/*   0000 - 8009_0FFF - Boot ROM code                  */
+/*   0FFF - 8009_FFFF - Reserved                       */
+#define BOOT_OFFSET             0x090000
+#define BOOT_BASE               (EP93XX_AHB_BASE|BOOT_OFFSET)
+#define BOOT                    (BOOT_BASE+0x00)
+
+
+/* 800A_0000 - 800A_ffff: IDE Interface  */
+#define IDE_OFFSET              0x0a0000
+#define IDE_BASE                (EP93XX_AHB_BASE|IDE_OFFSET)
+#define IDECR                   (IDE_BASE+0x00)
+#define IDECFG                  (IDE_BASE+0x04)
+#define IDEMDMAOP               (IDE_BASE+0x08)
+#define IDEUDMAOP               (IDE_BASE+0x0C)
+#define IDEDATAOUT              (IDE_BASE+0x10)
+#define IDEDATAIN               (IDE_BASE+0x14)
+#define IDEMDMADATAOUT          (IDE_BASE+0x18)
+#define IDEMDMADATAIN           (IDE_BASE+0x1C)
+#define IDEUDMADATAOUT          (IDE_BASE+0x20)
+#define IDEUDMADATAIN           (IDE_BASE+0x24)
+#define IDEUDMASTATUS           (IDE_BASE+0x28)
+#define IDEUDMADEBUG            (IDE_BASE+0x2C)
+#define IDEUDMAWFST             (IDE_BASE+0x30)
+#define IDEUDMARFST             (IDE_BASE+0x34)
+
+
+
+/* 800B_0000 - 800B_FFFF: VIC 0 */
+#define VIC0_OFFSET              0x0B0000
+#define VIC0_BASE                (EP93XX_AHB_BASE|VIC0_OFFSET)
+#define VIC0                     (VIC0_BASE+0x000) 
+#define VIC0IRQSTATUS            (VIC0_BASE+0x000) /* R   IRQ status register               */
+#define VIC0FIQSTATUS            (VIC0_BASE+0x004) /* R   FIQ status register               */
+#define VIC0RAWINTR              (VIC0_BASE+0x008) /* R   Raw interrupt status register     */
+#define VIC0INTSELECT            (VIC0_BASE+0x00C) /* R/W Interrupt select register         */
+#define VIC0INTENABLE            (VIC0_BASE+0x010) /* R/W Interrupt enable register         */
+#define VIC0INTENCLEAR           (VIC0_BASE+0x014) /* W   Interrupt enable clear register   */
+#define VIC0SOFTINT              (VIC0_BASE+0x018) /* R/W Software interrupt register       */
+#define VIC0SOFTINTCLEAR         (VIC0_BASE+0x01C) /* R/W Software interrupt clear register */
+#define VIC0PROTECTION           (VIC0_BASE+0x020) /* R/W Protection enable register        */
+#define VIC0VECTADDR             (VIC0_BASE+0x030) /* R/W Vector address register           */
+#define VIC0DEFVECTADDR          (VIC0_BASE+0x034) /* R/W Default vector address register   */
+#define VIC0VECTADDR00           (VIC0_BASE+0x100) /* R/W Vector address 00 register        */
+#define VIC0VECTADDR01           (VIC0_BASE+0x104) /* R/W Vector address 01 register        */
+#define VIC0VECTADDR02           (VIC0_BASE+0x108) /* R/W Vector address 02 register        */
+#define VIC0VECTADDR03           (VIC0_BASE+0x10C) /* R/W Vector address 03 register        */
+#define VIC0VECTADDR04           (VIC0_BASE+0x110) /* R/W Vector address 04 register        */
+#define VIC0VECTADDR05           (VIC0_BASE+0x114) /* R/W Vector address 05 register        */
+#define VIC0VECTADDR06           (VIC0_BASE+0x118) /* R/W Vector address 06 register        */
+#define VIC0VECTADDR07           (VIC0_BASE+0x11C) /* R/W Vector address 07 register        */
+#define VIC0VECTADDR08           (VIC0_BASE+0x120) /* R/W Vector address 08 register        */
+#define VIC0VECTADDR09           (VIC0_BASE+0x124) /* R/W Vector address 09 register        */
+#define VIC0VECTADDR10           (VIC0_BASE+0x128) /* R/W Vector address 10 register        */
+#define VIC0VECTADDR11           (VIC0_BASE+0x12C) /* R/W Vector address 11 register        */
+#define VIC0VECTADDR12           (VIC0_BASE+0x130) /* R/W Vector address 12 register        */
+#define VIC0VECTADDR13           (VIC0_BASE+0x134) /* R/W Vector address 13 register        */
+#define VIC0VECTADDR14           (VIC0_BASE+0x138) /* R/W Vector address 14 register        */
+#define VIC0VECTADDR15           (VIC0_BASE+0x13C) /* R/W Vector address 15 register        */
+#define VIC0VECTCNTL00           (VIC0_BASE+0x200) /* R/W Vector control 00 register        */
+#define VIC0VECTCNTL01           (VIC0_BASE+0x204) /* R/W Vector control 01 register        */
+#define VIC0VECTCNTL02           (VIC0_BASE+0x208) /* R/W Vector control 02 register        */
+#define VIC0VECTCNTL03           (VIC0_BASE+0x20C) /* R/W Vector control 03 register        */
+#define VIC0VECTCNTL04           (VIC0_BASE+0x210) /* R/W Vector control 04 register        */
+#define VIC0VECTCNTL05           (VIC0_BASE+0x214) /* R/W Vector control 05 register        */
+#define VIC0VECTCNTL06           (VIC0_BASE+0x218) /* R/W Vector control 06 register        */
+#define VIC0VECTCNTL07           (VIC0_BASE+0x21C) /* R/W Vector control 07 register        */
+#define VIC0VECTCNTL08           (VIC0_BASE+0x220) /* R/W Vector control 08 register        */
+#define VIC0VECTCNTL09           (VIC0_BASE+0x224) /* R/W Vector control 09 register        */
+#define VIC0VECTCNTL10           (VIC0_BASE+0x228) /* R/W Vector control 10 register        */
+#define VIC0VECTCNTL11           (VIC0_BASE+0x22C) /* R/W Vector control 11 register        */
+#define VIC0VECTCNTL12           (VIC0_BASE+0x230) /* R/W Vector control 12 register        */
+#define VIC0VECTCNTL13           (VIC0_BASE+0x234) /* R/W Vector control 13 register        */
+#define VIC0VECTCNTL14           (VIC0_BASE+0x238) /* R/W Vector control 14 register        */
+#define VIC0VECTCNTL15           (VIC0_BASE+0x23C) /* R/W Vector control 15 register        */
+#define VIC0ITCR                 (VIC0_BASE+0x300) /* R/W Test control register             */
+#define VIC0ITIP1                (VIC0_BASE+0x304) /* R   Test input register (nVICIRQIN/nVICFIQIN)*/
+#define VIC0ITIP2                (VIC0_BASE+0x308) /* R   Test input register (VICVECTADDRIN)      */
+#define VIC0ITOP1                (VIC0_BASE+0x30C) /* R   Test output register (nVICIRQ/nVICFIQ)   */
+#define VIC0ITOP2                (VIC0_BASE+0x310) /* R   Test output register (VICVECTADDROUT)    */
+#define VIC0PERIPHID0            (VIC0_BASE+0xFE0) /* R   Peripheral ID register bits 7:0   */
+#define VIC0PERIPHID1            (VIC0_BASE+0xFE4) /* R   Peripheral ID register bits 15:8  */
+#define VIC0PERIPHID2            (VIC0_BASE+0xFE8) /* R   Peripheral ID register bits 23:16 */
+#define VIC0PERIPHID3            (VIC0_BASE+0xFEC) /* R   Peripheral ID register bits 31:24 */
+
+
+/* 800C_0000 - 800C_FFFF: VIC 0 */
+#define VIC1_OFFSET              0x0C0000
+#define VIC1_BASE                (EP93XX_AHB_BASE|VIC1_OFFSET)
+#define VIC1                     (VIC1_BASE+0x000) 
+#define VIC1IRQSTATUS            (VIC1_BASE+0x000) /* R   IRQ status register               */
+#define VIC1FIQSTATUS            (VIC1_BASE+0x004) /* R   FIQ status register               */
+#define VIC1RAWINTR              (VIC1_BASE+0x008) /* R   Raw interrupt status register     */
+#define VIC1INTSELECT            (VIC1_BASE+0x00C) /* R/W Interrupt select register         */
+#define VIC1INTENABLE            (VIC1_BASE+0x010) /* R/W Interrupt enable register         */
+#define VIC1INTENCLEAR           (VIC1_BASE+0x014) /* W   Interrupt enable clear register   */
+#define VIC1SOFTINT              (VIC1_BASE+0x018) /* R/W Software interrupt register       */
+#define VIC1SOFTINTCLEAR         (VIC1_BASE+0x01C) /* R/W Software interrupt clear register */
+#define VIC1PROTECTION           (VIC1_BASE+0x020) /* R/W Protection enable register        */
+#define VIC1VECTADDR             (VIC1_BASE+0x030) /* R/W Vector address register           */
+#define VIC1DEFVECTADDR          (VIC1_BASE+0x034) /* R/W Default vector address register   */
+#define VIC1VECTADDR00           (VIC1_BASE+0x100) /* R/W Vector address 00 register        */
+#define VIC1VECTADDR01           (VIC1_BASE+0x104) /* R/W Vector address 01 register        */
+#define VIC1VECTADDR02           (VIC1_BASE+0x108) /* R/W Vector address 02 register        */
+#define VIC1VECTADDR03           (VIC1_BASE+0x10C) /* R/W Vector address 03 register        */
+#define VIC1VECTADDR04           (VIC1_BASE+0x110) /* R/W Vector address 04 register        */
+#define VIC1VECTADDR05           (VIC1_BASE+0x114) /* R/W Vector address 05 register        */
+#define VIC1VECTADDR06           (VIC1_BASE+0x118) /* R/W Vector address 06 register        */
+#define VIC1VECTADDR07           (VIC1_BASE+0x11C) /* R/W Vector address 07 register        */
+#define VIC1VECTADDR08           (VIC1_BASE+0x120) /* R/W Vector address 08 register        */
+#define VIC1VECTADDR09           (VIC1_BASE+0x124) /* R/W Vector address 09 register        */
+#define VIC1VECTADDR10           (VIC1_BASE+0x128) /* R/W Vector address 10 register        */
+#define VIC1VECTADDR11           (VIC1_BASE+0x12C) /* R/W Vector address 11 register        */
+#define VIC1VECTADDR12           (VIC1_BASE+0x130) /* R/W Vector address 12 register        */
+#define VIC1VECTADDR13           (VIC1_BASE+0x134) /* R/W Vector address 13 register        */
+#define VIC1VECTADDR14           (VIC1_BASE+0x138) /* R/W Vector address 14 register        */
+#define VIC1VECTADDR15           (VIC1_BASE+0x13C) /* R/W Vector address 15 register        */
+#define VIC1VECTCNTL00           (VIC1_BASE+0x200) /* R/W Vector control 00 register        */
+#define VIC1VECTCNTL01           (VIC1_BASE+0x204) /* R/W Vector control 01 register        */
+#define VIC1VECTCNTL02           (VIC1_BASE+0x208) /* R/W Vector control 02 register        */
+#define VIC1VECTCNTL03           (VIC1_BASE+0x20C) /* R/W Vector control 03 register        */
+#define VIC1VECTCNTL04           (VIC1_BASE+0x210) /* R/W Vector control 04 register        */
+#define VIC1VECTCNTL05           (VIC1_BASE+0x214) /* R/W Vector control 05 register        */
+#define VIC1VECTCNTL06           (VIC1_BASE+0x218) /* R/W Vector control 06 register        */
+#define VIC1VECTCNTL07           (VIC1_BASE+0x21C) /* R/W Vector control 07 register        */
+#define VIC1VECTCNTL08           (VIC1_BASE+0x220) /* R/W Vector control 08 register        */
+#define VIC1VECTCNTL09           (VIC1_BASE+0x224) /* R/W Vector control 09 register        */
+#define VIC1VECTCNTL10           (VIC1_BASE+0x228) /* R/W Vector control 10 register        */
+#define VIC1VECTCNTL11           (VIC1_BASE+0x22C) /* R/W Vector control 11 register        */
+#define VIC1VECTCNTL12           (VIC1_BASE+0x230) /* R/W Vector control 12 register        */
+#define VIC1VECTCNTL13           (VIC1_BASE+0x234) /* R/W Vector control 13 register        */
+#define VIC1VECTCNTL14           (VIC1_BASE+0x238) /* R/W Vector control 14 register        */
+#define VIC1VECTCNTL15           (VIC1_BASE+0x23C) /* R/W Vector control 15 register        */
+#define VIC1ITCR                 (VIC1_BASE+0x300) /* R/W Test control register             */
+#define VIC1ITIP1                (VIC1_BASE+0x304) /* R   Test input register (nVICIRQIN/nVICFIQIN)*/
+#define VIC1ITIP2                (VIC1_BASE+0x308) /* R   Test input register (VICVECTADDRIN)      */
+#define VIC1ITOP1                (VIC1_BASE+0x30C) /* R   Test output register (nVICIRQ/nVICFIQ)   */
+#define VIC1ITOP2                (VIC1_BASE+0x310) /* R   Test output register (VICVECTADDROUT)    */
+#define VIC1PERIPHID0            (VIC1_BASE+0xFE0) /* R   Peripheral ID register bits 7:0   */
+#define VIC1PERIPHID1            (VIC1_BASE+0xFE4) /* R   Peripheral ID register bits 15:8  */
+#define VIC1PERIPHID2            (VIC1_BASE+0xFE8) /* R   Peripheral ID register bits 23:16 */
+#define VIC1PERIPHID3            (VIC1_BASE+0xFEC) /* R   Peripheral ID register bits 31:24 */
+
+
+/*800D_0000 - 807F_FFFF: Reserved AHB space  */
+  
+/******************************************************************/
+/******************************************************************/
+/* EP93xx APB Blocks Base Addrs                                   */
+/* The APB address map is:                                        */
+/* Start     End        Size Usage                                */
+/* 8080_0000 8080_FFFF: 64 K Reserved                             */
+/* 8081_0000 8081_FFFF: 64 K Timer control registers              */
+/* 8082_0000 8082_FFFF: 64 K I2S control registers                */
+/* 8083_0000 8083_FFFF: 64 K Reserved                             */
+/* 8084_0000 8084_FFFF: 64 K GPIO control registers               */
+/* 8085_0000 8085_FFFF: 64 K Reserved                             */
+/* 8086_0000 8086_FFFF: 64 K Reserved                             */
+/* 8087_0000 8087_FFFF: 64 K Reserved                             */
+/* 8088_0000 8088_FFFF: 64 K AC97 control registers                */
+/* 8089_0000 8089_FFFF: 64 K Reserved                             */
+/* 808A_0000 808A_FFFF: 64 K SPI1 control registers               */
+/* 808B_0000 808B_FFFF: 64 K IrDA control registers               */
+/* 808C_0000 808C_FFFF: 64 K UART1 control registers              */
+/* 808D_0000 808D_FFFF: 64 K UART2 control registers              */
+/* 808E_0000 808E_FFFF: 64 K UART3 control registers              */
+/* 808F_0000 808F_FFFF: 64 K Key Matrix control registers         */
+/* 8090_0000 8090_FFFF: 64 K Touch Screen control registers       */
+/* 8091_0000 8091_FFFF: 64 K PWM control registers                */
+/* 8092_0000 8092_FFFF: 64 K Real Time Clock control registers    */
+/* 8093_0000 8093_1FFF: 64 K Syscon control registers             */
+/* 8093_2000 8093_FFFF: 64 K Security control registers           */
+/* 8094_0000 8094_FFFF: 64 K Watchdog control registers           */
+/* 8095_0000 8FFF_FFFF: 128M Reserved                             */
+
+
+#define EP93XX_APB_BASE (IO_BASE_VIRT | 0x00800000)
+
+
+/* 8080_0000 - 8080_ffff: Reserved  */
+
+ 
+
+/* 8081_0000 - 8081_ffff: Timers */
+#define TIMERS_OFFSET           0x010000
+#define TIMERS_BASE             (EP93XX_APB_BASE|TIMERS_OFFSET)
+
+#define TIMER1LOAD              (TIMERS_BASE+0x00)
+#define TIMER1VALUE             (TIMERS_BASE+0x04)
+#define TIMER1CONTROL           (TIMERS_BASE+0x08)
+#define TIMER1CLEAR             (TIMERS_BASE+0x0C)
+#define TIMER1TEST              (TIMERS_BASE+0x10)
+
+#define TIMER2LOAD              (TIMERS_BASE+0x20)
+#define TIMER2VALUE             (TIMERS_BASE+0x24)
+#define TIMER2CONTROL           (TIMERS_BASE+0x28)
+#define TIMER2CLEAR             (TIMERS_BASE+0x2C)
+#define TIMER2TEST              (TIMERS_BASE+0x30)
+
+#define TIMER3LOAD              (TIMERS_BASE+0x80)
+#define TIMER3VALUE             (TIMERS_BASE+0x84)
+#define TIMER3CONTROL           (TIMERS_BASE+0x88)
+#define TIMER3CLEAR             (TIMERS_BASE+0x8C)
+#define TIMER3TEST              (TIMERS_BASE+0x90)
+
+#define TTIMERBZCONT            (TIMERS_BASE+0x40)
+
+#define TIMER4VALUELOW          (TIMERS_BASE+0x60)
+#define TIMER4VALUEHIGH         (TIMERS_BASE+0x64)
+
+
+
+/* 8082_0000 - 8082_ffff: I2S */
+#define I2S_OFFSET            0x020000
+#define I2S_BASE              (EP93XX_APB_BASE|I2S_OFFSET)
+
+#define I2STxClkCfg           (I2S_BASE+0x00) /* 8082.0000 R/W Transmitter clock config register  */
+#define I2SRxClkCfg           (I2S_BASE+0x04) /* 8082.0004 R/W Receiver clock config register     */
+#define I2SGlSts              (I2S_BASE+0x08) /* 8082.0008 R/W SAI Global Status register.        */
+#define I2SGlCtrl             (I2S_BASE+0x0C) /* 8082.000C R/W SAI Global Control register        */
+
+#define I2STX0Lft             (I2S_BASE+0x10) /* 8082.0010 R/W Left  TX data reg for channel 0    */
+#define I2STX0Rt              (I2S_BASE+0x14) /* 8082.0014 R/W Right TX data reg for channel 0    */
+#define I2STX1Lft             (I2S_BASE+0x18) /* 8082.0018 R/W Left  TX data reg for channel 1    */
+#define I2STX1Rt              (I2S_BASE+0x1C) /* 8082.001C R/W Right TX data reg for channel 1    */
+#define I2STX2Lft             (I2S_BASE+0x20) /* 8082.0020 R/W Left  TX data reg for channel 2    */
+#define I2STX2Rt              (I2S_BASE+0x24) /* 8082.0024 R/W Right TX data reg for channel 2    */
+
+#define I2STXLinCtrlData      (I2S_BASE+0x28) /* 8082.0028 R/W TX Line Control data register      */
+#define I2STXCtrl             (I2S_BASE+0x2C) /* 8082.002C R/W TX Control register                */
+#define I2STXWrdLen           (I2S_BASE+0x30) /* 8082.0030 R/W TX Word Length                     */
+#define I2STX0En              (I2S_BASE+0x34) /* 8082.0034 R/W TX0 Channel Enable                 */
+#define I2STX1En              (I2S_BASE+0x38) /* 8082.0038 R/W TX1 Channel Enable                 */
+#define I2STX2En              (I2S_BASE+0x3C) /* 8082.003C R/W TX2 Channel Enable                 */
+
+#define I2SRX0Lft             (I2S_BASE+0x40) /* 8082.0040 R   Left  RX data reg for channel 0    */
+#define I2SRX0Rt              (I2S_BASE+0x44) /* 8082.0044 R   Right RX data reg for channel 0    */
+#define I2SRX1Lft             (I2S_BASE+0x48) /* 8082.0048 R   Left  RX data reg for channel 1    */
+#define I2SRX1Rt              (I2S_BASE+0x4C) /* 8082.004c R   Right RX data reg for channel 1    */
+#define I2SRX2Lft             (I2S_BASE+0x50) /* 8082.0050 R   Left  RX data reg for channel 2    */
+#define I2SRX2Rt              (I2S_BASE+0x54) /* 8082.0054 R   Right RX data reg for channel 2    */
+
+#define I2SRXLinCtrlData      (I2S_BASE+0x58) /* 8082.0058 R/W RX Line Control data register      */
+#define I2SRXCtrl             (I2S_BASE+0x5C) /* 8082.005C R/W RX Control register                */
+#define I2SRXWrdLen           (I2S_BASE+0x60) /* 8082.0060 R/W RX Word Length                     */
+#define I2SRX0En              (I2S_BASE+0x64) /* 8082.0064 R/W RX0 Channel Enable                 */
+#define I2SRX1En              (I2S_BASE+0x68) /* 8082.0068 R/W RX1 Channel Enable                 */
+#define I2SRX2En              (I2S_BASE+0x6C) /* 8082.006C R/W RX2 Channel Enable                 */
+
+
+/* 8083_0000 - 8083_ffff: Security Block */
+#define SECURITY_OFFSET         0x030000
+#define SECURITY_BASE           (EP93XX_APB_BASE|SECURITY_OFFSET)
+#define SECFLG                  (SECURITY_BASE+0x2400)
+#define SECEN                   (SECURITY_BASE+0x2410)
+#define UNIQID                  (SECURITY_BASE+0x2440)
+#define UNIQCHK                 (SECURITY_BASE+0x2450)
+#define UNIQVAL                 (SECURITY_BASE+0x2460)
+#define CLINBOOT                (SECURITY_BASE+0x2480)
+#define CLINVADDR               (SECURITY_BASE+0x2484)
+#define CLSETSKRNL              (SECURITY_BASE+0x2488)
+#define CLSKRNL                 (SECURITY_BASE+0x248C)
+#define ITTMP                   (SECURITY_BASE+0x2490)
+#define ETBL1                   (SECURITY_BASE+0x24A0)
+#define ETCL1                   (SECURITY_BASE+0x24A4)
+#define ETAPL1                  (SECURITY_BASE+0x24A8)
+#define ETSPTREG1               (SECURITY_BASE+0x24B0)
+#define ETSPTREG2               (SECURITY_BASE+0x24B4)
+#define ETSPTREG3               (SECURITY_BASE+0x24B8)
+
+#define SECID1                  (SECURITY_BASE+0x2500)
+#define SECID2                  (SECURITY_BASE+0x2504)
+#define SECCHK1                 (SECURITY_BASE+0x2520)
+#define SECCHK2                 (SECURITY_BASE+0x2524)
+#define SECVAL1                 (SECURITY_BASE+0x2540)
+#define SECVAL2                 (SECURITY_BASE+0x2544)
+
+#define UNIQID2                 (SECURITY_BASE+0x2700)
+#define UNIQID3                 (SECURITY_BASE+0x2704)
+#define UNIQID4                 (SECURITY_BASE+0x2708)
+#define UNIQID5                 (SECURITY_BASE+0x270C)
+#define UNIQCHK2                (SECURITY_BASE+0x2710)
+#define USRFLG                  (SECURITY_BASE+0x2714)
+#define UNIQVAL2                (SECURITY_BASE+0x2720)
+#define UNIQVAL3                (SECURITY_BASE+0x2724)
+#define UNIQVAL4                (SECURITY_BASE+0x2728)
+#define TESTVAL                 (SECURITY_BASE+0x2744)
+#define TESTCHK                 (SECURITY_BASE+0x2754)
+#define ACHK1                   (SECURITY_BASE+0x27A0)
+#define ACHK2                   (SECURITY_BASE+0x27A4)
+#define PROCRESET               (SECURITY_BASE+0x27A8)
+#define TESTIDR                 (SECURITY_BASE+0x27AC)
+#define AVAL1                   (SECURITY_BASE+0x27B0)
+#define AVAL2                   (SECURITY_BASE+0x27B4)
+#define AID1                    (SECURITY_BASE+0x27C4)
+#define AID2                    (SECURITY_BASE+0x27C8)
+#define ADYNREMAP               (SECURITY_BASE+0x27D0)
+#define ALTTMP                  (SECURITY_BASE+0x27D4)
+#define PROCSIGN                (SECURITY_BASE+0x27F0)
+
+#define ECLIDX                  (SECURITY_BASE+0x2800)
+#define ECLINE0                 (SECURITY_BASE+0x2810)
+#define ECLINE1                 (SECURITY_BASE+0x2814)
+#define ECLINE2                 (SECURITY_BASE+0x2818)
+#define ECLINE3                 (SECURITY_BASE+0x281C)
+#define ECLINE4                 (SECURITY_BASE+0x2820)
+#define ECLINE5                 (SECURITY_BASE+0x2824)
+#define ECLINE6                 (SECURITY_BASE+0x2828)
+#define ECLINE7                 (SECURITY_BASE+0x282C)
+#define ETWIDX1                 (SECURITY_BASE+0x2840)
+#define ETWL1                   (SECURITY_BASE+0x2844)
+#define ETWIDX2                 (SECURITY_BASE+0x2848)
+#define ETWL2                   (SECURITY_BASE+0x284C)
+
+#define ETSPT10                 (SECURITY_BASE+0x4000)
+#define ETSPT11                 (SECURITY_BASE+0x4004)
+#define ETSPT12                 (SECURITY_BASE+0x4008)
+#define ETSPT13                 (SECURITY_BASE+0x400C)
+
+#define ETSPT2000               (SECURITY_BASE+0x6000)
+#define ETSPT2020               (SECURITY_BASE+0x6020)
+#define ETSPT2024               (SECURITY_BASE+0x6024)
+
+
+
+/* 8084_0000 - 8084_ffff: GPIO */
+#define GPIO_OFFSET              0x040000
+#define GPIO_BASE                (EP93XX_APB_BASE|GPIO_OFFSET)
+#define GPIO_PADR                (GPIO_BASE+0x00)
+#define GPIO_PBDR                (GPIO_BASE+0x04)
+#define GPIO_PCDR                (GPIO_BASE+0x08)
+#define GPIO_PDDR                (GPIO_BASE+0x0C)
+#define GPIO_PADDR               (GPIO_BASE+0x10)
+#define GPIO_PBDDR               (GPIO_BASE+0x14)
+#define GPIO_PCDDR               (GPIO_BASE+0x18)
+#define GPIO_PDDDR               (GPIO_BASE+0x1C)
+#define GPIO_PEDR                (GPIO_BASE+0x20)
+#define GPIO_PEDDR               (GPIO_BASE+0x24)
+// #define 0x8084.0028 Reserved
+// #define 0x8084.002C Reserved
+#define GPIO_PFDR                (GPIO_BASE+0x30) 
+#define GPIO_PFDDR               (GPIO_BASE+0x34)
+#define GPIO_PGDR                (GPIO_BASE+0x38)
+#define GPIO_PGDDR               (GPIO_BASE+0x3C)
+#define GPIO_PHDR                (GPIO_BASE+0x40)
+#define GPIO_PHDDR               (GPIO_BASE+0x44)
+// #define 0x8084.0048 RAZ RAZ                            
+#define GPIO_FINTTYPE1           (GPIO_BASE+0x4C)
+#define GPIO_FINTTYPE2           (GPIO_BASE+0x50)
+#define GPIO_FEOI                (GPIO_BASE+0x54) /* WRITE ONLY - READ UNDEFINED */
+#define GPIO_FINTEN              (GPIO_BASE+0x58)
+#define GPIO_INTSTATUSF          (GPIO_BASE+0x5C)
+#define GPIO_RAWINTSTASUSF       (GPIO_BASE+0x60) 
+#define GPIO_FDB                 (GPIO_BASE+0x64)
+#define GPIO_PAPINDR             (GPIO_BASE+0x68)
+#define GPIO_PBPINDR             (GPIO_BASE+0x6C)
+#define GPIO_PCPINDR             (GPIO_BASE+0x70)
+#define GPIO_PDPINDR             (GPIO_BASE+0x74)
+#define GPIO_PEPINDR             (GPIO_BASE+0x78)
+#define GPIO_PFPINDR             (GPIO_BASE+0x7C)
+#define GPIO_PGPINDR             (GPIO_BASE+0x80)
+#define GPIO_PHPINDR             (GPIO_BASE+0x84)
+#define GPIO_AINTTYPE1           (GPIO_BASE+0x90)
+#define GPIO_AINTTYPE2           (GPIO_BASE+0x94)
+#define GPIO_AEOI                (GPIO_BASE+0x98) /* WRITE ONLY - READ UNDEFINED */
+#define GPIO_AINTEN              (GPIO_BASE+0x9C)
+#define GPIO_INTSTATUSA          (GPIO_BASE+0xA0)
+#define GPIO_RAWINTSTSTISA       (GPIO_BASE+0xA4)
+#define GPIO_ADB                 (GPIO_BASE+0xA8)
+#define GPIO_BINTTYPE1           (GPIO_BASE+0xAC)
+#define GPIO_BINTTYPE2           (GPIO_BASE+0xB0)
+#define GPIO_BEOI                (GPIO_BASE+0xB4) /* WRITE ONLY - READ UNDEFINED */
+#define GPIO_BINTEN              (GPIO_BASE+0xB8)
+#define GPIO_INTSTATUSB          (GPIO_BASE+0xBC)
+#define GPIO_RAWINTSTSTISB       (GPIO_BASE+0xC0)
+#define GPIO_BDB                 (GPIO_BASE+0xC4)
+#define GPIO_EEDRIVE             (GPIO_BASE+0xC8)
+//#define Reserved               (GPIO_BASE+0xCC)
+#define GPIO_TCR                 (GPIO_BASE+0xD0) /* Test Registers */
+#define GPIO_TISRA               (GPIO_BASE+0xD4) /* Test Registers */
+#define GPIO_TISRB               (GPIO_BASE+0xD8) /* Test Registers */
+#define GPIO_TISRC               (GPIO_BASE+0xDC) /* Test Registers */
+#define GPIO_TISRD               (GPIO_BASE+0xE0) /* Test Registers */
+#define GPIO_TISRE               (GPIO_BASE+0xE4) /* Test Registers */
+#define GPIO_TISRF               (GPIO_BASE+0xE8) /* Test Registers */
+#define GPIO_TISRG               (GPIO_BASE+0xEC) /* Test Registers */
+#define GPIO_TISRH               (GPIO_BASE+0xF0) /* Test Registers */
+#define GPIO_TCER                (GPIO_BASE+0xF4) /* Test Registers */
+
+
+
+/* 8085_0000 - 8085_ffff: Reserved  */
+
+
+
+/* 8086_0000 - 8086_ffff: Reserved  */
+
+
+
+/* 8087_0000 - 8087_ffff: Reserved  */
+
+
+/* 8088_0000 - 8088_ffff: Ac97 Controller (AAC) */
+#define AC97_OFFSET             0x080000
+#define AC97_BASE               (EP93XX_APB_BASE|AC97_OFFSET)
+#define AC97DR1                 (AC97_BASE+0x00) /* 8088.0000 R/W Data read or written from/to FIFO1  */
+#define AC97RXCR1               (AC97_BASE+0x04) /* 8088.0004 R/W Control register for receive        */
+#define AC97TXCR1               (AC97_BASE+0x08) /* 8088.0008 R/W Control register for transmit       */
+#define AC97SR1                 (AC97_BASE+0x0C) /* 8088.000C R   Status register                     */
+#define AC97RISR1               (AC97_BASE+0x10) /* 8088.0010 R   Raw interrupt status register       */
+#define AC97ISR1                (AC97_BASE+0x14) /* 8088.0014 R   Interrupt Status                    */
+#define AC97IE1                 (AC97_BASE+0x18) /* 8088.0018 R/W Interrupt Enable                    */
+                                                               /* 8088.001C Reserved - RAZ                          */
+#define AC97DR2                 (AC97_BASE+0x20) /* 8088.0020 R/W Data read or written from/to FIFO2  */
+#define AC97RXCR2               (AC97_BASE+0x24) /* 8088.0024 R/W Control register for receive        */
+#define AC97TXCR2               (AC97_BASE+0x28) /* 8088.0028 R/W Control register for transmit       */
+#define AC97SR2                 (AC97_BASE+0x2C) /* 8088.002C R   Status register                     */
+#define AC97RISR2               (AC97_BASE+0x30) /* 8088.0030 R   Raw interrupt status register       */
+#define AC97ISR2                (AC97_BASE+0x34) /* 8088.0034 R   Interrupt Status                    */
+#define AC97IE2                 (AC97_BASE+0x38) /* 8088.0038 R/W Interrupt Enable                    */
+                                                               /* 8088.003C Reserved - RAZ                          */
+#define AC97DR3                 (AC97_BASE+0x40) /* 8088.0040 R/W Data read or written from/to FIFO3. */
+#define AC97RXCR3               (AC97_BASE+0x44) /* 8088.0044 R/W Control register for receive        */
+#define AC97TXCR3               (AC97_BASE+0x48) /* 8088.0048 R/W Control register for transmit       */
+#define AC97SR3                 (AC97_BASE+0x4C) /* 8088.004C R   Status register                     */
+#define AC97RISR3               (AC97_BASE+0x50) /* 8088.0050 R   Raw interrupt status register       */
+#define AC97ISR3                (AC97_BASE+0x54) /* 8088.0054 R   Interrupt Status                    */
+#define AC97IE3                 (AC97_BASE+0x58) /* 8088.0058 R/W Interrupt Enable                    */
+                                                               /* 8088.005C Reserved - RAZ                          */
+#define AC97DR4                 (AC97_BASE+0x60) /* 8088.0060 R/W Data read or written from/to FIFO4. */
+#define AC97RXCR4               (AC97_BASE+0x64) /* 8088.0064 R/W Control register for receive        */
+#define AC97TXCR4               (AC97_BASE+0x68) /* 8088.0068 R/W Control register for transmit       */
+#define AC97SR4                 (AC97_BASE+0x6C) /* 8088.006C R   Status register                     */
+#define AC97RISR4               (AC97_BASE+0x70) /* 8088.0070 R   Raw interrupt status register       */
+#define AC97ISR4                (AC97_BASE+0x74) /* 8088.0074 R   Interrupt Status                    */
+#define AC97IE4                 (AC97_BASE+0x78) /* 8088.0078 R/W Interrupt Enable                    */
+                                                               /* 8088.007C Reserved - RAZ                          */
+#define AC97S1DATA              (AC97_BASE+0x80) /* 8088.0080 R/W Data received/transmitted on SLOT1  */
+#define AC97S2DATA              (AC97_BASE+0x84) /* 8088.0084 R/W Data received/transmitted on SLOT2  */
+#define AC97S12DATA             (AC97_BASE+0x88) /* 8088.0088 R/W Data received/transmitted on SLOT12 */
+#define AC97RGIS                (AC97_BASE+0x8C) /* 8088.008C R/W Raw Global interrupt status register*/
+#define AC97GIS                 (AC97_BASE+0x90) /* 8088.0090 R   Global interrupt status register    */
+#define AC97IM                  (AC97_BASE+0x94) /* 8088.0094 R/W Interrupt mask register             */
+#define AC97EOI                 (AC97_BASE+0x98) /* 8088.0098 W   Interrupt clear register            */
+#define AC97GCR                 (AC97_BASE+0x9C) /* 8088.009C R/W Main Control register               */
+#define AC97RESET               (AC97_BASE+0xA0) /* 8088.00A0 R/W RESET control register.             */
+#define AC97SYNC                (AC97_BASE+0xA4) /* 8088.00A4 R/W SYNC control register.              */
+#define AC97GCIS                (AC97_BASE+0xA8) /* 8088.00A8 R  Global chan FIFO int status register */
+
+
+/* 8089_0000 - 8089_ffff: Reserved */
+
+/* 808A_0000 - 808A_ffff: SSP - (SPI) */
+#define SSP_OFFSET             0x0A0000
+#define SSP_BASE               (EP93XX_APB_BASE|SSP_OFFSET)
+#define SSPCR0                 (SSP_BASE+0x00)
+#define SSPCR1                 (SSP_BASE+0x04)
+#define SSPDR                  (SSP_BASE+0x08)
+#define SSPSR                  (SSP_BASE+0x0c)
+#define SSPCPSR                (SSP_BASE+0x10)
+#define SSPIIR                 (SSP_BASE+0x14)
+
+/*808B_0000 - 808B_ffff: IrDA */
+#define IRDA_OFFSET             0x0B0000
+#define IRDA_BASE               (EP93XX_APB_BASE|IRDA_OFFSET)
+#define IrEnable                (IRDA_BASE+0x00)
+#define IrCtrl                  (IRDA_BASE+0x04)
+#define IrAdrMatchVal           (IRDA_BASE+0x08)
+#define IrFlag                  (IRDA_BASE+0x0C)
+#define IrData                  (IRDA_BASE+0x10)
+#define IrDataTail1             (IRDA_BASE+0x14)
+#define IrDataTail2             (IRDA_BASE+0x18)
+#define IrDataTail3             (IRDA_BASE+0x1c)
+#define IrRIB                   (IRDA_BASE+0x20)
+#define IrTR0                   (IRDA_BASE+0x24)
+#define IrDMACR                 (IRDA_BASE+0x28)
+#define SIRTR0                  (IRDA_BASE+0x30)
+#define MISR                    (IRDA_BASE+0x80)
+#define MIMR                    (IRDA_BASE+0x84)
+#define MIIR                    (IRDA_BASE+0x88)
+#define FISR                    (IRDA_BASE+0x180)
+#define FIMR                    (IRDA_BASE+0x184)
+#define FIIR                    (IRDA_BASE+0x188)
+
+
+/* 808C_0000 - 808C_ffff: UART1 */
+#define UART1_OFFSET            0x0C0000
+#define UART1_BASE              (EP93XX_APB_BASE|UART1_OFFSET)
+#define UART1DR                 (UART1_BASE+0x000)
+#define UART1RSR                (UART1_BASE+0x004)
+#define UART1ECR                (UART1_BASE+0x004)
+#define UART1CR_H               (UART1_BASE+0x008)
+#define UART1CR_M               (UART1_BASE+0x00C)
+#define UART1CR_L               (UART1_BASE+0x010)
+#define UART1CR                 (UART1_BASE+0x014)
+#define UART1FR                 (UART1_BASE+0x018)
+#define UART1IIR                (UART1_BASE+0x01C)
+#define UART1ICR                (UART1_BASE+0x01C)
+#define UART1ILPR               (UART1_BASE+0x020)
+#define UART1DMACR              (UART1_BASE+0x028)
+#define UART1TMR                (UART1_BASE+0x084)
+#define UART1MCR                (UART1_BASE+0x100)
+#define UART1MSR                (UART1_BASE+0x104)
+#define UART1TCR                (UART1_BASE+0x108)
+#define UART1TISR               (UART1_BASE+0x10C)
+#define UART1TOCR               (UART1_BASE+0x110)
+#define HDLC1CR                 (UART1_BASE+0x20c)
+#define HDLC1AMV                (UART1_BASE+0x210)
+#define HDLC1AMSK               (UART1_BASE+0x214)
+#define HDLC1RIB                (UART1_BASE+0x218)
+#define HDLC1SR                 (UART1_BASE+0x21c)
+
+
+/* 808d_0000 - 808d_ffff: UART2 */
+#define UART2_OFFSET            0x0D0000
+#define UART2_BASE              (EP93XX_APB_BASE|UART2_OFFSET)
+#define UART2DR                 (UART2_BASE+0x00)
+#define UART2RSR                (UART2_BASE+0x04) /* Read */
+#define UART2ECR                (UART2_BASE+0x04) /* Write */
+#define UART2CR_H               (UART2_BASE+0x08)
+#define UART2CR_M               (UART2_BASE+0x0C)
+#define UART2CR_L               (UART2_BASE+0x10)
+#define UART2CR                 (UART2_BASE+0x14)
+#define UART2FR                 (UART2_BASE+0x18)
+#define UART2IIR                (UART2_BASE+0x1C) /* Read */
+#define UART2ICR                (UART2_BASE+0x1C) /* Write */
+#define UART2ILPR               (UART2_BASE+0x20)
+#define UART2DMACR              (UART2_BASE+0x28)
+#define UART2TMR                (UART2_BASE+0x84)
+
+
+/* 808e_0000 - 808e_ffff: UART3 */
+#define UART3_OFFSET            0x0E0000
+#define UART3_BASE              (EP93XX_APB_BASE|UART3_OFFSET)
+#define UART3DR                 (UART3_BASE+0x00)
+#define UART3RSR                (UART3_BASE+0x04) /* Read */
+#define UART3ECR                (UART3_BASE+0x04) /* Write */
+#define UART3CR_H               (UART3_BASE+0x08)
+#define UART3CR_M               (UART3_BASE+0x0C)
+#define UART3CR_L               (UART3_BASE+0x10)
+#define UART3CR                 (UART3_BASE+0x14)
+#define UART3FR                 (UART3_BASE+0x18)
+#define UART3IIR                (UART3_BASE+0x1C) /* Read */
+#define UART3ICR                (UART3_BASE+0x1C) /* Write */
+#define UART3ILPR               (UART3_BASE+0x20)
+#define UART3DMACR              (UART3_BASE+0x28)
+#define UART3TCR                (UART3_BASE+0x80)
+#define UART3TISR               (UART3_BASE+0x88)
+#define UART3TOCR               (UART3_BASE+0x8C)
+#define UART3TMR                (UART3_BASE+0x84)
+#define UART3MCR                (UART3_BASE+0x100) /* Modem Control Reg */
+#define UART3MSR                (UART3_BASE+0x104) /* Modem Status Reg */
+
+#define UART3HDLCCR             (UART3_BASE+0x20C) /* HDLC Registers */
+#define UART3HDLCAMV            (UART3_BASE+0x210) /* HDLC Registers */
+#define UART3HDLCAMSK           (UART3_BASE+0x214) /* HDLC Registers */
+#define UART3HDLCCRIB           (UART3_BASE+0x218) /* HDLC Registers */
+#define UART3HDLCSR             (UART3_BASE+0x21C) /* HDLC Registers */
+           
+
+/* 808f_0000 - 808f_ffff: KEY Matrix */
+#define KEY_OFFSET              0x0F0000
+#define KEY_BASE                (EP93XX_APB_BASE|KEY_OFFSET)
+#define SCANINIT                (KEY_BASE+0x00)
+#define KEY_DIAG                (KEY_BASE+0x04)
+#define KEY_REG                 (KEY_BASE+0x08)
+#define KEY_TCR                 (KEY_BASE+0x10)
+#define KEY_TISR                (KEY_BASE+0x14)
+#define KEY_TOCR                (KEY_BASE+0x18)
+
+/* 8090_0000 - 8090_ffff: Analog Resistive Touchscreen  */
+#define TOUCH_OFFSET            0x100000
+#define TOUCH_BASE              (EP93XX_APB_BASE|TOUCH_OFFSET)
+#define TSSetup                 (TOUCH_BASE+0x00) /* R/W touchscreen controller setup control register.     */
+#define TSXYMaxMin              (TOUCH_BASE+0x04) /* R/W touchscreen controller max/min register.           */
+#define TSXYResult              (TOUCH_BASE+0x08) /* R   touchscreen controller result register.            */
+#define TSDischarge             (TOUCH_BASE+0x0C) /* LOCKED R/W touchscreen Switch Matrix control register. */
+#define TSXSample               (TOUCH_BASE+0x10) /* LOCKED R/W touchscreen Switch Matrix control register. */
+#define TSYSample               (TOUCH_BASE+0x14) /* LOCKED R/W touchscreen Switch Matrix control register. */
+#define TSDirect                (TOUCH_BASE+0x18) /* LOCKED R/W touchscreen Switch Matrix control register. */
+#define TSDetect                (TOUCH_BASE+0x1C) /* LOCKED R/W touchscreen Switch Matrix control register. */
+#define TSSWLock                (TOUCH_BASE+0x20) /*  NA    R/W touchscreen software lock register.         */
+#define TSSetup2                (TOUCH_BASE+0x24) /* R/W touchscreen setup control register #2.             */
+
+
+/* 8091_0000 - 8091_ffff: PWM */
+#define PWM_OFFSET              0x110000
+#define PWM_BASE                (EP93XX_APB_BASE|PWM_OFFSET)
+#define PWM0_TC                 (PWM_BASE+0x00) /* 80910000 R/W PWM_0 Terminal Count */
+#define PWM0_DC                 (PWM_BASE+0x04) /* 80910004 R/W PWM_0 Duty Cycle     */
+#define PWM0_EN                 (PWM_BASE+0x08) /* 80910008 R/W PWM_0 Enable         */
+#define PWM0_INV                (PWM_BASE+0x0C) /* 8091000C R/W PWM_0 Invert         */
+#define PWM0_SYNC               (PWM_BASE+0x10) /* 80910010 R/W PWM_0 Synchronous    */
+#define PWM1_TC                 (PWM_BASE+0x20) /* 80910020 R/W PWM_1 Terminal Count */
+#define PWM1_DC                 (PWM_BASE+0x24) /* 80910024 R/W PWM_1 Duty Cycle     */
+#define PWM1_EN                 (PWM_BASE+0x28) /* 80910028 R/W PWM_1 Enable         */
+#define PWM1_INV                (PWM_BASE+0x2C) /* 8091002C R/W PWM_1 Invert         */
+#define PWM1_SYNC               (PWM_BASE+0x30) /* 80910030 R/W PWM_1 Synchronous    */
+
+
+/* 8092_0000 - 8092_ffff: RTC */
+#define RTC_OFFSET              0x120000
+#define RTC_BASE                (EP93XX_APB_BASE|RTC_OFFSET)
+#define RTCDR                   (RTC_BASE+0x00)
+#define RTCMR                   (RTC_BASE+0x04)
+#define RTCSTAT                 (RTC_BASE+0x08) /* Read */
+#define RTCEOI                  (RTC_BASE+0x08) /* Write */
+#define RTCLR                   (RTC_BASE+0x0C)
+#define RTCCR                   (RTC_BASE+0x10)
+#define RTCSCOMP                (RTC_BASE+0x108)
+
+
+/* 8093_0000 - 8093_ffff: CSC/Syscon  PLL, clock control, & misc. stuff */
+#define SYSCON_OFFSET           0x130000
+#define SYSCON_BASE             (EP93XX_APB_BASE|SYSCON_OFFSET)
+#define SYSCON_PWRSR            (SYSCON_BASE+0x0000)
+#define SYSCON_PWRCNT           (SYSCON_BASE+0x0004)
+#define SYSCON_HALT             (SYSCON_BASE+0x0008)
+#define SYSCON_STBY             (SYSCON_BASE+0x000c)
+#define SYSCON_BLEOI            (SYSCON_BASE+0x0010)
+#define SYSCON_MCEOI            (SYSCON_BASE+0x0014)
+#define SYSCON_TEOI             (SYSCON_BASE+0x0018)
+#define SYSCON_STFCLR           (SYSCON_BASE+0x001c)
+#define SYSCON_CLKSET1          (SYSCON_BASE+0x0020)
+#define SYSCON_CLKSET2          (SYSCON_BASE+0x0024)
+#define SYSCON_RESV00           (SYSCON_BASE+0x0028)
+#define SYSCON_RESV01           (SYSCON_BASE+0x002c)
+#define SYSCON_RESV02           (SYSCON_BASE+0x0030)
+#define SYSCON_RESV03           (SYSCON_BASE+0x0034)
+#define SYSCON_RESV04           (SYSCON_BASE+0x0038)
+#define SYSCON_RESV05           (SYSCON_BASE+0x003c)
+#define SYSCON_SCRREG0          (SYSCON_BASE+0x0040)
+#define SYSCON_SCRREG1          (SYSCON_BASE+0x0044)
+#define SYSCON_CLKTEST          (SYSCON_BASE+0x0048)
+#define SYSCON_USBRESET         (SYSCON_BASE+0x004c)
+#define SYSCON_APBWAIT          (SYSCON_BASE+0x0050)
+#define SYSCON_BMAR             (SYSCON_BASE+0x0054)
+#define SYSCON_BOOTCLR          (SYSCON_BASE+0x0058)
+#define SYSCON_DEVCFG           (SYSCON_BASE+0x0080)
+#define SYSCON_VIDDIV           (SYSCON_BASE+0x0084)
+#define SYSCON_MIRDIV           (SYSCON_BASE+0x0088)
+#define SYSCON_I2SDIV           (SYSCON_BASE+0x008C)
+#define SYSCON_KTDIV            (SYSCON_BASE+0x0090)
+#define SYSCON_CHIPID           (SYSCON_BASE+0x0094)
+#define SYSCON_TSTCR            (SYSCON_BASE+0x0098)
+#define SYSCON_SYSCFG           (SYSCON_BASE+0x009C)
+#define SYSCON_SWLOCK           (SYSCON_BASE+0x00C0)
+
+#define SYSCON_DEVCFG_KEYS      0x00000002
+#define SYSCON_DEVCFG_RasOnP3   0x00000010
+#define SYSCON_DEVCFG_GONK      0x08000000
+
+#define SYSCON_KTDIV_KEN        0x00008000
+
+
+/* 8094_0000 - 8094_ffff: Watchdog */
+#define WATCHDOG_OFFSET         0x140000
+#define WATCHDOG_BASE           (EP93XX_APB_BASE|WATCHDOG_OFFSET)
+#define WATCHDOG                (WATCHDOG_BASE+0x00)
+#define WDSTATUS                (WATCHDOG_BASE+0x04)
+#define WD_TCR                  (WATCHDOG_BASE+0x08)
+#define WD_TISR                 (WATCHDOG_BASE+0x0C)
+#define WDTOCR                  (WATCHDOG_BASE+0x10)
+
+
+/* 8095_0000 - 87ff_ffff: Reserved APB space */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/regs_ac97.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_ac97.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/regs_ac97.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_ac97.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,180 @@
+/*=============================================================================
+ *  FILE:           regs_ac97.h
+ *
+ *  DESCRIPTION:    Ac'97 Register Definition
+ *
+ *  Copyright Cirrus Logic, 2001-2003
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *=============================================================================
+ */
+#ifndef _REGS_AC97_H_
+#define _REGS_AC97_H_
+
+//-----------------------------------------------------------------------------
+// Bit definitionses
+//-----------------------------------------------------------------------------
+#define AC97ISR_RIS                     8
+#define AC97ISR_TIS                     4
+#define AC97ISR_RTIS                    2
+#define AC97ISR_TCIS                    1
+
+#define AC97RGIS_SLOT1TXCOMPLETE     0x01
+#define AC97RGIS_SLOT2RXVALID        0x02
+#define AC97RGIS_GPIOTXCOMPLETE      0x04
+#define AC97RGIS_GPIOINTRX           0x08
+#define AC97RGIS_RWIS                0x10
+#define AC97RGIS_CODECREADY          0x20
+#define AC97RGIS_SLOT2TXCOMPLETE     0x40
+
+#define AC97SR_RXFE                 0x0001
+#define AC97SR_TXFE                 0x0002      
+#define AC97SR_RXFF                 0x0004
+#define AC97SR_TXFF                 0x0008
+#define AC97SR_TXBUSY               0x0010
+#define AC97SR_RXOE                 0x0020
+#define AC97SR_TXUE                 0x0040
+
+#define AC97GSR_IFE                     0x1
+#define AC97GSR_LOOP                    0x2
+#define AC97GSR_OVERRIDECODECREADY      0x4
+
+#define AC97RESET_TIMEDRESET            0x1
+#define AC97RESET_FORCEDRESET           0x2
+#define AC97RESET_EFORCER               0x4
+
+#define AC97RXCR_REN                    0x1
+
+#define AC97TXCR_TEN                    0x1
+
+
+//****************************************************************************
+//
+// The Ac97 Codec registers, accessable through the Ac-link.
+// These are not controller registers and are not memory mapped.
+// Includes registers specific to CS4202 (Beavis).
+//
+//****************************************************************************
+#define AC97_REG_OFFSET_MASK                0x0000007E
+
+#define AC97_00_RESET                          0x00000000
+#define AC97_02_MASTER_VOL                     0x00000002
+#define AC97_04_HEADPHONE_VOL                  0x00000004
+#define AC97_06_MONO_VOL                       0x00000006
+#define AC97_08_TONE                           0x00000008
+#define AC97_0A_PC_BEEP_VOL                    0x0000000A
+#define AC97_0C_PHONE_VOL                      0x0000000C
+#define AC97_0E_MIC_VOL                        0x0000000E
+#define AC97_10_LINE_IN_VOL                    0x00000010
+#define AC97_12_CD_VOL                         0x00000012
+#define AC97_14_VIDEO_VOL                      0x00000014
+#define AC97_16_AUX_VOL                        0x00000016
+#define AC97_18_PCM_OUT_VOL                    0x00000018
+#define AC97_1A_RECORD_SELECT                  0x0000001A
+#define AC97_1C_RECORD_GAIN                    0x0000001C
+#define AC97_1E_RESERVED_1E                    0x0000001E
+#define AC97_20_GENERAL_PURPOSE                0x00000020
+#define AC97_22_3D_CONTROL                     0x00000022
+#define AC97_24_MODEM_RATE                     0x00000024
+#define AC97_26_POWERDOWN                      0x00000026
+#define AC97_28_EXT_AUDIO_ID                   0x00000028
+#define AC97_2A_EXT_AUDIO_POWER                0x0000002A
+#define AC97_2C_PCM_FRONT_DAC_RATE             0x0000002C
+#define AC97_2E_PCM_SURR_DAC_RATE              0x0000002E
+#define AC97_30_PCM_LFE_DAC_RATE               0x00000030
+#define AC97_32_PCM_LR_ADC_RATE                0x00000032
+#define AC97_34_MIC_ADC_RATE                   0x00000034
+#define AC97_36_6CH_VOL_C_LFE                  0x00000036
+#define AC97_38_6CH_VOL_SURROUND               0x00000038
+#define AC97_3A_SPDIF_CONTROL                  0x0000003A
+#define AC97_3C_EXT_MODEM_ID                   0x0000003C
+#define AC97_3E_EXT_MODEM_POWER                0x0000003E
+#define AC97_40_LINE1_CODEC_RATE               0x00000040
+#define AC97_42_LINE2_CODEC_RATE               0x00000042
+#define AC97_44_HANDSET_CODEC_RATE             0x00000044
+#define AC97_46_LINE1_CODEC_LEVEL              0x00000046
+#define AC97_48_LINE2_CODEC_LEVEL              0x00000048
+#define AC97_4A_HANDSET_CODEC_LEVEL            0x0000004A
+#define AC97_4C_GPIO_PIN_CONFIG                0x0000004C
+#define AC97_4E_GPIO_PIN_TYPE                  0x0000004E
+#define AC97_50_GPIO_PIN_STICKY                0x00000050
+#define AC97_52_GPIO_PIN_WAKEUP                0x00000052
+#define AC97_54_GPIO_PIN_STATUS                0x00000054
+#define AC97_56_RESERVED                       0x00000056
+#define AC97_58_RESERVED                       0x00000058
+#define AC97_5A_CRYSTAL_REV_N_FAB_ID           0x0000005A
+#define AC97_5C_TEST_AND_MISC_CTRL             0x0000005C
+#define AC97_5E_AC_MODE                        0x0000005E
+#define AC97_60_MISC_CRYSTAL_CONTROL           0x00000060
+#define AC97_62_VENDOR_RESERVED                0x00000062
+#define AC97_64_DAC_SRC_PHASE_INCR             0x00000064
+#define AC97_66_ADC_SRC_PHASE_INCR             0x00000066
+#define AC97_68_RESERVED_68                    0x00000068
+#define AC97_6A_SERIAL_PORT_CONTROL            0x0000006A
+#define AC97_6C_VENDOR_RESERVED                0x0000006C
+#define AC97_6E_VENDOR_RESERVED                0x0000006E
+#define AC97_70_BDI_CONFIG                     0x00000070
+#define AC97_72_BDI_WAKEUP                     0x00000072
+#define AC97_74_VENDOR_RESERVED                0x00000074
+#define AC97_76_CAL_ADDRESS                    0x00000076
+#define AC97_78_CAL_DATA                       0x00000078
+#define AC97_7A_VENDOR_RESERVED                0x0000007A
+#define AC97_7C_VENDOR_ID1                     0x0000007C
+#define AC97_7E_VENDOR_ID2                     0x0000007E
+
+
+#ifndef __ASSEMBLY__
+
+//
+// enum type for use with reg AC97_RECORD_SELECT
+//
+typedef enum{
+    RECORD_MIC          = 0x0000,
+    RECORD_CD           = 0x0101,
+    RECORD_VIDEO_IN     = 0x0202,
+    RECORD_AUX_IN       = 0x0303,
+    RECORD_LINE_IN      = 0x0404,
+    RECORD_STEREO_MIX   = 0x0505,
+    RECORD_MONO_MIX     = 0x0606,
+    RECORD_PHONE_IN     = 0x0707
+} Ac97RecordSources;
+
+#endif /* __ASSEMBLY__ */
+
+//
+// Sample rates supported directly in AC97_PCM_FRONT_DAC_RATE and 
+// AC97_PCM_LR_ADC_RATE.
+//
+#define Ac97_Fs_8000        0x1f40
+#define Ac97_Fs_11025       0x2b11
+#define Ac97_Fs_16000       0x3e80
+#define Ac97_Fs_22050       0x5622
+#define Ac97_Fs_32000       0x7d00
+#define Ac97_Fs_44100       0xac44
+#define Ac97_Fs_48000       0xbb80
+
+//
+// RSIZE and TSIZE in AC97RXCR and AC97TXCR
+//
+#define Ac97_SIZE_20            2
+#define Ac97_SIZE_18            1
+#define Ac97_SIZE_16            0
+#define Ac97_SIZE_12            3
+
+//=============================================================================
+//=============================================================================
+
+
+#endif /* _REGS_AC97_H_ */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/regs_dma.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_dma.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/regs_dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_dma.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,276 @@
+/*****************************************************************************
+ *  
+ * linux/include/asm-arm/arch-ep93xx/regs_dma.h
+ *
+ *  Register definitions for the ep93xx dma channel registers.
+ *
+ *  Copyright (C) 2003 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ ****************************************************************************/
+#ifndef _REGS_DMA_H_
+#define _REGS_DMA_H_
+
+/*****************************************************************************
+ * 0x8000.0000 -> 0x8000.003C M2P Channel 0 Registers (Tx) 
+ * 0x8000.0040 -> 0x8000.007C M2P Channel 1 Registers (Rx) 
+ * 0x8000.0080 -> 0x8000.00BC M2P Channel 2 Registers (Tx)  
+ * 0x8000.00C0 -> 0x8000.00FC M2P Channel 3 Registers (Rx) 
+ * 0x8000.0100 -> 0x8000.013C M2M Channel 0 Registers      
+ * 0x8000.0140 -> 0x8000.017C M2M Channel 1 Registers      
+ * 0x8000.0180 -> 0x8000.01BC Not Used                     
+ * 0x8000.01C0 -> 0x8000.01FC Not Used                     
+ * 0x8000.0200 -> 0x8000.023C M2P Channel 5 Registers (Rx) 
+ * 0x8000.0240 -> 0x8000.027C M2P Channel 4 Registers (Tx) 
+ * 0x8000.0280 -> 0x8000.02BC M2P Channel 7 Registers (Rx) 
+ * 0x8000.02C0 -> 0x8000.02FC M2P Channel 6 Registers (Tx) 
+ * 0x8000.0300 -> 0x8000.033C M2P Channel 9 Registers (Rx) 
+ * 0x8000.0340 -> 0x8000.037C M2P Channel 8 Registers (Tx) 
+ * 0x8000.0380 DMA Channel Arbitration register            
+ * 0x8000.03C0 DMA Global Interrupt register               
+ * 0x8000.03C4 -> 0x8000.03FC Not Used                     
+ *
+ *
+ * Internal M2P/P2M Channel Register Map                   
+ *
+ * Offset Name      Access  Bits Reset Value               
+ * 0x00   CONTROL   R/W     6    0                         
+ * 0x04   INTERRUPT R/W TC* 3    0                         
+ * 0x08   PPALLOC   R/W     4    channel dependant         
+ *                               (see reg description)     
+ * 0x0C   STATUS    RO      8    0                         
+ * 0x10   reserved                                         
+ * 0x14   REMAIN    RO      16   0                         
+ * 0X18   Reserved                                         
+ * 0X1C   Reserved                                         
+ * 0x20   MAXCNT0   R/W     16   0                         
+ * 0x24   BASE0     R/W     32   0                         
+ * 0x28   CURRENT0  RO      32   0                         
+ * 0x2C   Reserved                                         
+ * 0x30   MAXCNT1   R/W     16   0                         
+ * 0x34   BASE1     R/W     32   0                         
+ * 0X38   CURRENT1  RO      32   0                         
+ * 0X3C   Reserved                                         
+ *                                                         
+ * M2M Channel Register Map                                
+ * Offset Name         Access   Bits Reset Value           
+ *                                                         
+ * 0x00   CONTROL      R/W      22   0                     
+ * 0x04   INTERRUPT    R/W TC*  3    0                     
+ * 0x08   Reserved                                         
+ * 0x0C   STATUS       R/W TC*  14   0                     
+ * 0x10   BCR0         R/W      16   0                     
+ * 0x14   BCR1         R/W      16   0                     
+ * 0x18   SAR_BASE0    R/W      32   0                     
+ * 0x1C   SAR_BASE1    R/W      32   0                     
+ * 0x20   Reserved                                         
+ * 0x24   SAR_CURRENT0 RO       32   0                     
+ * 0x28   SAR_CURRENT1 RO       32   0                     
+ * 0x2C   DAR_BASE0    R/W      32   0                     
+ * 0x30   DAR_BASE1    R/W      32   0                     
+ * 0x34   DAR_CURRENT0 RO       32   0                     
+ * 0X38   Reserved                                         
+ * 0X3C   DAR_CURRENT1 RO       32   0                          
+ * * Write this location once to clear the bit (see        
+ * Interrupt/Status register description for which bits    
+ * this rule applies to).
+ *                                  
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__ 
+/*
+ * DMA Register Base addresses
+ */
+static unsigned int const DMAM2PChannelBase[10] =
+{
+    DMA_M2P_TX_0_BASE,
+    DMA_M2P_RX_1_BASE,
+    DMA_M2P_TX_2_BASE,
+    DMA_M2P_RX_3_BASE,
+    DMA_M2P_TX_4_BASE,
+    DMA_M2P_RX_5_BASE,
+    DMA_M2P_TX_6_BASE,
+    DMA_M2P_RX_7_BASE,
+    DMA_M2P_TX_8_BASE,
+    DMA_M2P_RX_9_BASE
+};
+
+static unsigned int const DMAM2MChannelBase[2] = 
+{
+    DMA_M2M_0_BASE,
+    DMA_M2M_1_BASE
+};
+
+#endif /* __ASSEMBLY__ */
+
+/*----------------------------------------------------------------------------------*/
+/* M2P Registers                                                                    */
+/*----------------------------------------------------------------------------------*/
+/*
+ * M2P CONTROL register bit defines 
+ */
+#define CONTROL_M2P_STALLINTEN      0x00000001	    /* Enables the STALL interrupt  */
+#define CONTROL_M2P_NFBINTEN        0x00000002	    /* Enables the NFB interrupt    */
+#define CONTROL_M2P_CHERRORINTEN    0x00000008      /* Enables the ChError interrupt*/
+#define CONTROL_M2P_ENABLE		    0x00000010      /* Enables the channel          */
+#define CONTROL_M2P_ABRT		    0x00000020      /* Determines how DMA behaves in*/ 
+			                                        /* NEXT state with peripheral   */
+                                                    /* error                        */
+			                                        /* 0: NEXT -> ON, ignore error  */
+			                                        /* 1: NEXT -> STALL, disable ch.*/ 
+#define CONTROL_M2P_ICE			    0x00000040      /* Ignore Channel Error         */
+
+/*
+ * M2P INTERRUPT register bit defines
+ */
+#define INTERRUPT_M2P_STALLINT      0x00000001	    /* Indicates channel stalled.   */
+#define INTERRUPT_M2P_NFBINT        0x00000002		/* Indicates channel is hungry. */
+#define INTERRUPT_M2P_CHERRORINT    0x00000008	    /* Peripheral detects error     */
+
+
+/*
+ * STATUS register bit defines
+ */
+#define STATUS_M2P_STALL            0x00000001		/* A '1' indicates channel is       */
+                                                    /* stalled                          */
+#define STATUS_M2P_NFB			    0x00000002      /* A '1' indicates channel has moved*/
+			                                        /* from NEXT state to ON state, but */
+			                                        /* waiting for next buffer to be    */
+                                                    /* programmed.                      */
+#define STATUS_M2P_CHERROR		    0x00000008      /* Enables the ChError interrupt    */
+#define STATUS_M2P_CURRENT_MASK     0x00000030      /* Current state of the FSM         */
+#define STATUS_M2P_CURRENT_SHIFT    4
+#define STATUS_M2P_NEXTBUFFER	    0x00000040      /* Informs the int handler after an */
+			                                        /* NFB int which pair of maxcnt and */
+                                                    /* base regs to update.             */
+#define STATUS_M2P_BYTES_MASK       0x0000f800 		/* number of valid DMA data         */
+#define STATUS_M2P_BYTES_SHIFT      7               /* currently in                     */
+								        		    /* packer/unpacker                  */
+
+#define STATUS_M2P_DMA_NO_BUF		0x00000000
+#define STATUS_M2P_DMA_BUF_ON		0x00000010
+#define STATUS_M2P_DMA_BUF_NEXT		0x00000020
+
+/*
+ * Register masks to mask off reserved bits after reading register.
+ */
+#define M2P_MASK_PPALLOC            0x0000000f
+#define M2P_MASK_REMAIN             0x0000ffff
+#define M2P_MASK_MAXCNT0            0x0000ffff
+#define M2P_MASK_BASE0              0xffffffff
+#define M2P_MASK_CURRENT0           0xffffffff
+#define M2P_MASK_MAXCNT1            0x0000ffff
+#define M2P_MASK_BASE1              0xffffffff
+#define M2P_MASK_CURRENT1           0xffffffff
+
+
+/*----------------------------------------------------------------------------------*/
+/* M2M Registers                                                                    */
+/*----------------------------------------------------------------------------------*/
+
+#define CONTROL_M2M_STALLINTEN	0x00000001  /* Enables the STALL interrupt                     */
+#define CONTROL_M2M_SCT			0x00000002  /* Source Copy Transfer. Setup a                   */
+										    /* block transfer from 1 memory source             */
+										    /* location.                                       */
+#define CONTROL_M2M_DONEINTEN	0x00000004  /* Enables the DONE interrupt which                */
+										    /* indicates if the xfer completed                 */
+										    /* successfully                                    */
+#define CONTROL_M2M_ENABLE		0x00000008  /* Enables the channel                             */
+#define CONTROL_M2M_START		0x00000010  /* Initiates the xfer. 'software trigger'          */
+#define CONTROL_M2M_BWC_MASK	0x000001e0  /* Bandwidth control. Indicate number of           */
+#define CONTROL_M2M_BWC_SHIFT   5			/* bytes in a transfer.                            */
+#define CONTROL_M2M_PW_MASK		0x00000600  /* Peripheral width. Used for xfers                */
+#define CONTROL_M2M_PW_SHIFT    9			/* between memory and external peripheral.         */
+										    /* 00: byte, 01: halfword, 10: word.               */
+#define CONTROL_M2M_DAH			0x00000800  /* Destination Address Hold                        */
+#define CONTROL_M2M_SAH			0x00001000  /* Source Address Hold                             */
+#define CONTROL_M2M_TM_MASK     0x00006000  /* Transfer Mode. 00: sw triggered,                */
+#define CONTROL_M2M_TM_SHIFT    13			/* 01: hw initiated M2P, 01: hw initiated P2M      */
+#define CONTROL_M2M_ETDP_MASK	0x00018000  /* End-of-Transfer/Terminal Count pin              */
+#define CONTROL_M2M_ETDP_SHIFT  15		    /* direction and polarity.                         */
+#define CONTROL_M2M_DACKP		0x00020000  /* DMA acknowledge pin polarity                    */
+
+#define CONTROL_M2M_DREQP_MASK  0x00180000	/* DMA request pin polarity. must be set           */
+#define CONTROL_M2M_DREQP_SHIFT 19			/* before enable bit.                              */
+#define CONTROL_M2M_NFBINTEN	0x00200000  /* Enables generation of the NFB interrupt.        */
+#define CONTROL_M2M_RSS_MASK    0x00c00000	/* Request source selection:                       */
+#define CONTROL_M2M_RSS_SHIFT	22			/*		000 - External DReq[0]                     */
+										    /*		001 - External DReq[1]                     */
+										    /*		01X - Internal SSPRx                       */
+										    /*		10X - Internal SSPTx                       */
+										    /*		11X - Internal IDE                         */
+#define CONTROL_M2M_NO_HDSK		0x01000000  /* No handshake.  When set the peripheral doesn't  */
+										    /* require the regular handshake protocal. Must    */
+									    	/* be set for SSP and IDE operations, optional     */
+										    /* for external peripherals.                       */
+#define CONTROL_M2M_PWSC_MASK   0xfe000000	/* Peripheral wait states count. Gives the latency */
+#define CONTROL_M2M_PWSC_SHIFT	25			/* (in PCLK cycles) needed by the peripheral to    */
+								    		/* deassert its' request once the M2M xfer w/ DMA  */
+									    	/* is complete.                                    */
+
+/*
+ * M2M INTERRUPT register bit defines
+ */
+#define INTERRUPT_M2M_STALLINT	0x00000001	/* Stall interrupt indicates channel stalled. */
+#define INTERRUPT_M2M_DONEINT	0x00000002	/* Transaction done.                          */
+#define INTERRUPT_M2M_NFBINT	0x00000004	/* Next frame buffer interrupt indicates      */
+											/* channel requires a new buffer              */
+
+
+
+/*
+ * M2M STATUS register bit defines
+ */
+#define STATUS_M2M_STALL		0x00000001  /* A '1' indicates channel is stalled           */
+#define STATUS_M2M_CURRENTSTATE_MASK  0x0000003e  /* Indicates state of M2M Channel control       */
+#define STATUS_M2M_CURRENTSTATE_SHIFT 1		/* FSM (0-2):                                   */
+										    /*	000 - IDLE, 001 - STALL, 010 - MEM_RD,      */
+										    /*  011 - MEM_WR, 100 - BWC_WAIT                */
+										    /* and M2M buffer FSM (3-2):                    */
+										    /* 	00 - NO_BUF, 01 - BUF_ON, 10 - BUF_NEXT     */
+#define STATUS_M2M_DONE		    0x00000040  /* Transfer completed successfully if 1.        */
+#define STATUS_M2M_TCS_MASK		0x00000180  /* Terminal Count status. Indicates whether or  */
+#define STATUS_M2M_TCS_SHIFT    7			/* or not the actual byte count reached         */
+								    		/* programmed limit for buffer descriptor       */
+#define STATUS_M2M_EOTS_MASK    0x00000600  /* End-of-Transfer status for buffer            */
+#define STATUS_M2M_EOTS_SHIFT   9
+#define STATUS_M2M_NFB			0x00000800  /* A '1' indicates channel has moved            */
+										    /* from NEXT state to ON state, but	the next    */
+										    /* byte count reg for next buffer has not been  */
+										    /* programmed yet.                              */
+#define STATUS_M2M_NB			0x00001000  /* NextBuffer status. Informs NFB service       */
+										    /* routine, after NFB int, which pair of buffer */
+										    /* descriptor registers is free to update.      */
+#define STATUS_M2M_DREQS		0x00002000  /* DREQ status.  Reflects the status of the     */
+										    /* synchronized external peripherals DMA        */
+										    /* request signal.                              */
+
+/*
+ * Register masks to mask off reserved bits after reading register.
+ */
+#define M2M_MASK_BCR0             0x0000ffff
+#define M2M_MASK_BCR1             0x0000ffff
+#define M2M_MASK_SAR_BASE0        0xffffffff
+#define M2M_MASK_SAR_BASE1        0xffffffff
+#define M2M_MASK_SAR_CURRENT0     0xffffffff
+#define M2M_MASK_SAR_CURRENT1     0xffffffff
+#define M2M_MASK_DAR_BASE0        0xffffffff
+#define M2M_MASK_DAR_BASE1        0xffffffff
+#define M2M_MASK_DAR_CURRENT0     0xffffffff
+#define M2M_MASK_DAR_CURRENT1     0xffffffff
+
+
+#endif /* _REGS_DMA_H_ */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/regs_gpio.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_gpio.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/regs_gpio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_gpio.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,31 @@
+/*=======================================================================
+ *
+ *  FILE:       regs_gpio.h
+ *
+ *  DESCRIPTION:    GPIO Register Definition
+ *
+ *  Copyright Cirrus Logic, 2001-2003
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *=======================================================================
+ */
+#ifndef _REGS_GPIO_H_
+#define _REGS_GPIO_H_
+
+/*
+ * This file intentionally blank.
+ */
+ 
+#endif /* _REGS_GPIO_H_ */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/regs_i2s.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_i2s.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/regs_i2s.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_i2s.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,97 @@
+/*=============================================================================
+ *
+ *  FILE:       	reg_i2s.h
+ *
+ *  DESCRIPTION:    ep93xx I2S Register Definition
+ *
+ *  Copyright Cirrus Logic, 2001-2003
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *=============================================================================
+ */
+#ifndef _REG_I2S_H_
+#define _REG_I2S_H_
+
+//
+// I2STXClkCfg bits
+//
+#define i2s_txcc_trls           0x00000001
+#define i2s_txcc_tckp           0x00000002
+#define i2s_txcc_trel           0x00000004
+#define i2s_txcc_mstr           0x00000008
+#define i2s_txcc_nbcg           0x00000010
+
+#define i2s_txcc_bcr_32x        0x00000020
+#define i2s_txcc_bcr_64x        0x00000040
+#define i2s_txcc_bcr_128x       0x00000060
+
+//
+// I2SRxClkCfg bits
+//
+#define i2s_rxcc_rrls           0x00000001
+#define i2s_rxcc_rckp           0x00000002
+#define i2s_rxcc_rrel           0x00000004
+#define i2s_rxcc_mstr           0x00000008
+#define i2s_rxcc_nbcg           0x00000010
+
+#define i2s_rxcc_bcr_32x        0x00000020
+#define i2s_rxcc_bcr_64x        0x00000040
+#define i2s_rxcc_bcr_128x       0x00000060
+
+//
+// I2SGlSts bits
+//
+#define TX0_UNDERFLOW           0x00000001
+#define TX1_UNDERFLOW           0x00000002
+#define TX2_UNDERFLOW           0x00000004
+
+#define RX0_OVERFLOW            0x00000008
+#define RX1_OVERFLOW            0x00000010
+#define RX2_OVERFLOW            0x00000020
+
+#define TX0_OVERFLOW            0x00000040
+#define TX1_OVERFLOW            0x00000080
+#define TX2_OVERFLOW            0x00000100
+
+#define RX0_UNDERFLOW           0x00000200
+#define RX1_UNDERFLOW           0x00000400
+#define RX2_UNDERFLOW           0x00000800
+
+#define TX0_FIFO_FULL           0x00001000
+#define TX0_FIFO_EMPTY          0x00002000
+#define TX0_FIFO_HALF_EMPTY     0x00004000
+
+#define RX0_FIFO_FULL           0x00008000
+#define RX0_FIFO_EMPTY          0x00010000
+#define RX0_FIFO_HALF_FULL      0x00020000
+
+#define TX1_FIFO_FULL           0x00040000
+#define TX1_FIFO_EMPTY          0x00080000
+#define TX1_FIFO_HALF_EMPTY     0x00100000
+
+#define RX1_FIFO_FULL           0x00200000
+#define RX1_FIFO_EMPTY          0x00400000
+#define RX1_FIFO_HALF_FULL      0x00800000
+
+#define TX2_FIFO_FULL           0x01000000
+#define TX2_FIFO_EMPTY          0x02000000
+#define TX2_FIFO_HALF_EMPTY     0x04000000
+
+#define RX2_FIFO_FULL           0x08000000
+#define RX2_FIFO_EMPTY          0x10000000
+#define RX2_FIFO_HALF_FULL      0x20000000
+
+#endif // _REG_I2S_H_
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/regs_ide.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_ide.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/regs_ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_ide.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,105 @@
+/*****************************************************************************
+ *
+ *  linux/include/asm-arm/arch-ep93xx/regs_ide.h
+ *
+ *  Register definitions for the ep93xx ide registers.
+ *
+ *  Copyright (C) 2003 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ 
+ *
+ ****************************************************************************/
+#ifndef _REGS_IDE_H_
+#define _REGS_IDE_H_
+
+/*****************************************************************************
+ *
+ *  Bit definitions for use with assembly code for the ide control register.
+ *
+ ****************************************************************************/
+#define IDECtrl_CS0n			0x00000001
+#define IDECtrl_CS1n			0x00000002
+#define IDECtrl_DA_MASK			0x0000001c
+#define IDECtrl_DA_SHIFT		2
+#define IDECtrl_DIORn			0x00000020
+#define IDECtrl_DIOWn			0x00000040
+#define IDECtrl_DASPn			0x00000080
+#define IDECtrl_DMARQ			0x00000100
+#define IDECtrl_INTRQ			0x00000200
+#define IDECtrl_IORDY			0x00000400
+
+#define IDECfg_IDEEN			0x00000001
+#define IDECfg_PIO			0x00000002
+#define IDECfg_MDMA			0x00000004
+#define IDECfg_UDMA			0x00000008
+#define IDECfg_MODE_MASK		0x000000f0
+#define IDECfg_MODE_SHIFT		4
+#define IDECfg_WST_MASK			0x00000300
+#define IDECfg_WST_SHIFT		8
+
+#define IDEMDMAOp_MEN			0x00000001
+#define IDEMDMAOp_RWOP			0x00000002
+
+#define IDEUDMAOp_UEN			0x00000001
+#define IDEUDMAOp_RWOP			0x00000002
+
+#define IDEUDMASts_CS0n			0x00000001
+#define IDEUDMASts_CS1n			0x00000002
+#define IDEUDMASts_DA_MASK		0x0000001c
+#define IDEUDMASts_DA_SHIFT		2
+#define IDEUDMASts_HSHD			0x00000020
+#define IDEUDMASts_STOP			0x00000040
+#define IDEUDMASts_DM			0x00000080
+#define IDEUDMASts_DDOE			0x00000100
+#define IDEUDMASts_DMARQ		0x00000200
+#define IDEUDMASts_DSDD			0x00000400
+#define IDEUDMASts_DMAide		0x00010000
+#define IDEUDMASts_INTide		0x00020000
+#define IDEUDMASts_SBUSY		0x00040000
+#define IDEUDMASts_NDO			0x01000000
+#define IDEUDMASts_NDI			0x02000000
+#define IDEUDMASts_N4X			0x04000000
+
+#define IDEUDMADebug_RWOE		0x00000001
+#define IDEUDMADebug_RWPTR		0x00000002
+#define IDEUDMADebug_RWDR		0x00000004
+#define IDEUDMADebug_RROE		0x00000008
+#define IDEUDMADebug_RRPTR		0x00000010
+#define IDEUDMADebug_RRDR		0x00000020
+
+#define IDEUDMAWrBufSts_HPTR_MASK	0x0000000f
+#define IDEUDMAWrBufSts_HPTR_SHIFT	0
+#define IDEUDMAWrBufSts_TPTR_MASK	0x000000f0
+#define IDEUDMAWrBufSts_TPTR_SHIFT	4
+#define IDEUDMAWrBufSts_EMPTY		0x00000100
+#define IDEUDMAWrBufSts_HOM		0x00000200
+#define IDEUDMAWrBufSts_NFULL		0x00000400
+#define IDEUDMAWrBufSts_FULL		0x00000800
+#define IDEUDMAWrBufSts_CRC_MASK	0xffff0000
+#define IDEUDMAWrBufSts_CRC_SHIFT	16
+
+#define IDEUDMARdBufSts_HPTR_MASK	0x0000000f
+#define IDEUDMARdBufSts_HPTR_SHIFT	0
+#define IDEUDMARdBufSts_TPTR_MASK	0x000000f0
+#define IDEUDMARdBufSts_TPTR_SHIFT	4
+#define IDEUDMARdBufSts_EMPTY		0x00000100
+#define IDEUDMARdBufSts_HOM		0x00000200
+#define IDEUDMARdBufSts_NFULL		0x00000400
+#define IDEUDMARdBufSts_FULL		0x00000800
+#define IDEUDMARdBufSts_CRC_MASK	0xffff0000
+#define IDEUDMARdBufSts_CRC_SHIFT	16
+
+#endif /* _REGS_IDE_H_ */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/regs_irda.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_irda.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/regs_irda.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_irda.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,24 @@
+/*=======================================================================
+ *
+ *  FILE:       regs_irda.h
+ *
+ *  DESCRIPTION:    IrDA Register Definition
+ *
+ *  Copyright Cirrus Logic, 2001-2003
+ *
+ *=======================================================================
+ */
+#ifndef _REGS_IRDA_H_
+#define _REGS_IRDA_H_
+
+/* Bit definitions */
+
+#define IrEnable_EN_NONE	0x00
+#define IrEnable_EN_SIR		0x01
+#define IrEnable_EN_MIR		0x02
+#define IrEnable_EN_FIR		0x03
+#define IrEnable_LBM		0x04
+#define IrEnable_MD			0x08
+#define IrEnable_FD			0x10
+
+#endif /* _REGS_IRDA_H_ */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/regs_raster.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_raster.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/regs_raster.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_raster.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,353 @@
+/*=============================================================================
+ *
+ *  FILE:       	regs_raster.h
+ *
+ *  DESCRIPTION:    ep93xx Raster Engine Register Definition
+ *
+ *  Copyright Cirrus Logic, 2001-2003
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *=============================================================================
+ */
+#ifndef _REGS_RASTER_H_
+#define _REGS_RASTER_H_
+
+//-----------------------------------------------------------------------------
+// VLINESTOTAL Register Definitions
+//-----------------------------------------------------------------------------
+#define VLINESTOTAL_MASK            0x000007ff
+
+//-----------------------------------------------------------------------------
+// VSYNCSTRTSTOP Register Definitions
+//-----------------------------------------------------------------------------
+#define VSYNCSTRTSTOP_STRT_MASK     0x07ff0000 
+#define VSYNCSTRTSTOP_STRT_SHIFT    0 
+#define VSYNCSTRTSTOP_STOP_MASK     0x000007ff
+#define VSYNCSTRTSTOP_STOP_SHIFT    16 
+
+//-----------------------------------------------------------------------------
+// VACTIVESTRTSTOP Register Definitions
+//-----------------------------------------------------------------------------
+#define VACTIVESTRTSTOP_STRT_MASK   0x07ff0000
+#define VACTIVESTRTSTOP_STRT_SHIFT  0 
+#define VACTIVESTRTSTOP_STOP_MASK   0x000007ff
+#define VACTIVESTRTSTOP_STOP_SHIFT  16 
+
+//-----------------------------------------------------------------------------
+// VCLKSTRTSTOP Register Definitions
+//-----------------------------------------------------------------------------
+#define VCLKSTRTSTOP_STRT_MASK      0x07ff0000
+#define VCLKSTRTSTOP_STRT_SHIFT     0 
+#define VCLKSTRTSTOP_STOP_MASK      0x000007ff
+#define VCLKSTRTSTOP_STOP_SHIFT     16 
+
+//-----------------------------------------------------------------------------
+// VBLANKSTRTSTOP Register Definitions
+//-----------------------------------------------------------------------------
+#define VBLANKSTRTSTOP_STRT_MASK  0x07ff0000
+#define VBLANKSTRTSTOP_STRT_SHIFT 0 
+#define VBLANKSTRTSTOP_STOP_MASK  0x000007ff
+#define VBLANKSTRTSTOP_STOP_SHIFT 16 
+
+//-----------------------------------------------------------------------------
+// HSYNCSTRTSTOP Register Definitions
+//-----------------------------------------------------------------------------
+#define HSYNCSTRTSTOP_STRT_MASK      0x07ff0000
+#define HSYNCSTRTSTOP_STRT_SHIFT     0 
+#define HSYNCSTRTSTOP_STOP_MASK      0x000007ff
+#define HSYNCSTRTSTOP_STOP_SHIFT     16 
+
+//-----------------------------------------------------------------------------
+// HACTIVESTRTSTOP Register Definitions
+//-----------------------------------------------------------------------------
+#define HACTIVESTRTSTOP_STRT_MASK    0x07ff0000
+#define HACTIVESTRTSTOP_STRT_SHIFT   0 
+#define HACTIVESTRTSTOP_STOP_MASK    0x000007ff
+#define HACTIVESTRTSTOP_STOP_SHIFT   16 
+
+//-----------------------------------------------------------------------------
+// HCLKSTRTSTOP Register Definitions
+//-----------------------------------------------------------------------------
+#define HCLKSTRTSTOP_STRT_MASK      0x07ff0000
+#define HCLKSTRTSTOP_STRT_SHIFT     0 
+#define HCLKSTRTSTOP_STOP_MASK      0x000007ff
+#define HCLKSTRTSTOP_STOP_SHIFT     16 
+
+//-----------------------------------------------------------------------------
+// BRIGHTNESS Register Definitions
+//-----------------------------------------------------------------------------
+#define BRIGHTNESS_MASK             0x0000ffff
+#define BRIGHTNESS_CNT_MASK         0x000000ff
+#define BRIGHTNESS_CNT_SHIFT        0
+#define BRIGHTNESS_CMP_MASK         0x0000ff00
+#define BRIGHTNESS_CMP_SHIFT        8
+
+//-----------------------------------------------------------------------------
+// VIDEOATTRIBS Register Definitions
+//-----------------------------------------------------------------------------
+#define VIDEOATTRIBS_MASK           0x001fffff
+#define VIDEOATTRIBS_EN             0x00000001
+#define VIDEOATTRIBS_PCLKEN         0x00000002
+#define VIDEOATTRIBS_SYNCEN         0x00000004
+#define VIDEOATTRIBS_DATAEN         0x00000008
+#define VIDEOATTRIBS_CSYNC          0x00000010
+#define VIDEOATTRIBS_VCPOL          0x00000020
+#define VIDEOATTRIBS_HSPOL          0x00000040
+#define VIDEOATTRIBS_BLKPOL         0x00000080
+#define VIDEOATTRIBS_INVCLK         0x00000100
+#define VIDEOATTRIBS_ACEN           0x00000200
+#define VIDEOATTRIBS_LCDEN          0x00000400
+#define VIDEOATTRIBS_RGBEN          0x00000800
+#define VIDEOATTRIBS_CCIREN         0x00001000
+#define VIDEOATTRIBS_PIFEN          0x00002000
+#define VIDEOATTRIBS_INTEN          0x00004000
+#define VIDEOATTRIBS_INT            0x00008000
+#define VIDEOATTRIBS_INTRLC         0x00010000
+#define VIDEOATTRIBS_EQUSER         0x00020000
+#define VIDEOATTRIBS_DHORZ          0x00040000
+#define VIDEOATTRIBS_DVERT          0x00080000
+#define VIDEOATTRIBS_BKPXD          0x00100000
+
+#define VIDEOATTRIBS_SDSEL_MASK     0x00600000
+#define VIDEOATTRIBS_SDSEL_SHIFT    21
+
+//-----------------------------------------------------------------------------
+// HBLANKSTRTSTOP Register Definitions
+//-----------------------------------------------------------------------------
+#define HBLANKSTRTSTOP_STRT_MASK    0x07ff0000
+#define HBLANKSTRTSTOP_STRT_SHIFT   0 
+#define HBLANKSTRTSTOP_STOP_MASK    0x000007ff
+#define HBLANKSTRTSTOP_STOP_SHIFT   16 
+
+//-----------------------------------------------------------------------------
+// LINECARRY Register Definitions
+//-----------------------------------------------------------------------------
+#define LINECARRY_LCARY_MASK        0x000007ff
+#define LINECARRY_LCARY_SHIFT       0
+
+//-----------------------------------------------------------------------------
+// BLINKRATE Register Definitons
+//-----------------------------------------------------------------------------
+#define BLINKRATE_MASK              0x000000ff
+
+//-----------------------------------------------------------------------------
+// BLINKMASK Register Definitons
+//-----------------------------------------------------------------------------
+#define BLINKMASK_MASK              0x00ffffff
+
+//-----------------------------------------------------------------------------
+// VIDSCRNPAGE Register Definitons
+//-----------------------------------------------------------------------------
+#define VIDSCRNPAGE_PAGE_MASK       0x0ffffffc
+
+//-----------------------------------------------------------------------------
+// VIDSCRNHPG Register Definitons
+//-----------------------------------------------------------------------------
+#define VIDSCRNHPG_MASK             0x0ffffffc
+
+//-----------------------------------------------------------------------------
+// SCRNLINES Register Definitons
+//-----------------------------------------------------------------------------
+#define SCRNLINES_MASK              0x000007ff
+
+//-----------------------------------------------------------------------------
+// LINELENGTH Register Definitons
+//-----------------------------------------------------------------------------
+#define LINELENGTH_MASK             0x000007ff
+
+//-----------------------------------------------------------------------------
+// VLINESTEP Register Definitons
+//-----------------------------------------------------------------------------
+#define VLINESTEP_MASK              0x00000fff
+
+//-----------------------------------------------------------------------------
+// REALITI_SWLOCK Register Definitons
+//-----------------------------------------------------------------------------
+#define REALITI_SWLOCK_MASK_WR      0xff
+#define REALITI_SWLOCK_MASK_R       0x1
+#define REALITI_SWLOCK_VALUE        0xaa
+
+//-----------------------------------------------------------------------------
+// LUTCONT Register Definitions
+//-----------------------------------------------------------------------------
+#define LUTCONT_MASK                0x00000003
+#define LUTCONT_SWTCH               0x00000001
+#define LUTCONT_STAT                0x00000002
+#define LUTCONT_RAM0                0
+#define LUTCONT_RAM1                1
+
+//-----------------------------------------------------------------------------
+// CURSORBLINK1 Register Definitions
+//-----------------------------------------------------------------------------
+#define CURSORBLINK1_MASK           0x00ffffff
+//-----------------------------------------------------------------------------
+// CURSORBLINK2 Register Definitions
+//-----------------------------------------------------------------------------
+#define CURSORBLINK2_MASK           0x00ffffff
+
+//-----------------------------------------------------------------------------
+// CURSORBLINK Register Definitions
+//-----------------------------------------------------------------------------
+#define CURSORBLINK_MASK            0x000001ff
+#define CURSORBLINK_RATE_MASK       0x000000ff
+#define CURSORBLINK_RATE_SHIFT      0
+#define CURSORBLINK_EN              0x00000100    
+
+//-----------------------------------------------------------------------------
+// BLINKPATRN Register Definitions
+//-----------------------------------------------------------------------------
+#define BLINKPATRN_MASK             0x00ffffff
+
+//-----------------------------------------------------------------------------
+// PATRNMASK Register Definitions
+//-----------------------------------------------------------------------------
+#define PATRNMASK_MASK              0x00ffffff
+
+//-----------------------------------------------------------------------------
+// BG_OFFSET Register Definitions
+//-----------------------------------------------------------------------------
+#define BG_OFFSET_MASK              0x00ffffff
+
+//-----------------------------------------------------------------------------
+// PIXELMODE Register Definitions
+//-----------------------------------------------------------------------------
+#define PIXELMODE_P_MASK            0x00000007
+#define PIXELMODE_P_MUX_DISABLE     0x00000000            
+#define PIXELMODE_P_4BPP            0x00000001            
+#define PIXELMODE_P_8BPP            0x00000002            
+#define PIXELMODE_P_16BPP           0x00000004            
+#define PIXELMODE_P_24BPP           0x00000006            
+#define PIXELMODE_P_32BPP           0x00000007            
+#define PIXELMODE_P_SHIFT           0
+
+#define PIXELMODE_S_MASK            0x00000038
+#define PIXELMODE_S_SHIFT           3
+#define PIXELMODE_S_1PPC            0x0
+#define PIXELMODE_S_1PPCMAPPED      0x1
+#define PIXELMODE_S_2PPC            0x2
+#define PIXELMODE_S_4PPC            0x3
+#define PIXELMODE_S_8PPC            0x4
+#define PIXELMODE_S_223PPC          0x5
+#define PIXELMODE_S_DS223PPC        0x6
+#define PIXELMODE_S_UNDEF           0x7
+
+#define PIXELMODE_M_MASK            0x000003c0
+#define PIXELMODE_M_SHIFT           6
+#define PIXELMODE_M_NOBLINK         0
+#define PIXELMODE_M_ANDBLINK        1
+#define PIXELMODE_M_ORBLINK         2
+#define PIXELMODE_M_XORBLINK        3
+#define PIXELMODE_M_BGBLINK         4
+#define PIXELMODE_M_OFFSINGBLINK    5
+#define PIXELMODE_M_OFF888BLINK     6
+#define PIXELMODE_M_DIMBLINK        0xc
+#define PIXELMODE_M_BRTBLINK        0xd
+#define PIXELMODE_M_DIM888BLINK     0xe
+#define PIXELMODE_M_BRT888BLINK     0xf
+
+#define PIXELMODE_C_MASK            0x00003c00
+#define PIXELMODE_C_SHIFT           10
+#define PIXELMODE_C_LUT             0
+#define PIXELMODE_C_888             4
+#define PIXELMODE_C_565             5
+#define PIXELMODE_C_555             6
+#define PIXELMODE_C_GSLUT           8
+
+#define PIXELMODE_DSCAN             0x00004000
+#define PIXELMODE_TRBSW             0x00008000
+#define PIXELMODE_P13951            0x00010000
+
+//-----------------------------------------------------------------------------
+//PARLLIFOUT Register Defintions
+//-----------------------------------------------------------------------------
+#define PARLLIFOUT_DAT_MASK         0x0000000f
+#define PARLLIFOUT_DAT_SHIFT        0
+#define PARLLIFOUT_RD               0x00000010
+
+//-----------------------------------------------------------------------------
+//PARLLIFIN Register Defintions
+//-----------------------------------------------------------------------------
+#define PARLLIFIN_DAT_MASK          0x0000000f
+#define PARLLIFIN_DAT_SHIFT         0
+#define PARLLIFIN_CNT_MASK          0x000f0000
+#define PARLLIFIN_CNT_SHIFT         16
+#define PARLLIFIN_ESTRT_MASK        0x00f00000
+#define PARLLIFIN_ESTRT_SHIFT       20
+
+//-----------------------------------------------------------------------------
+// CURSORADRSTART Register Defintions
+//-----------------------------------------------------------------------------
+#define CURSOR_ADR_START_MASK         0xfffffffc
+
+//-----------------------------------------------------------------------------
+// CURSORADRSTART Register Defintions
+//-----------------------------------------------------------------------------
+#define CURSOR_ADR_RESET_MASK         0xfffffffc
+
+//-----------------------------------------------------------------------------
+// CURSORCOLOR1 Register Definitions
+//-----------------------------------------------------------------------------
+#define CURSORCOLOR1_MASK               0x00ffffff
+//-----------------------------------------------------------------------------
+// CURSORCOLOR2 Register Definitions
+//-----------------------------------------------------------------------------
+#define CURSORCOLOR2_MASK               0x00ffffff
+
+//-----------------------------------------------------------------------------
+// CURSORXYLOC Register Definitions
+//-----------------------------------------------------------------------------
+#define CURSORXYLOC_MASK                0x07ff87ff
+#define CURSORXYLOC_XLOC_MASK           0x000007ff
+#define CURSORXYLOC_XLOC_SHIFT          0
+#define CURSORXYLOC_CEN                 0x00008000
+#define CURSORXYLOC_YLOC_MASK           0x07ff0000
+#define CURSORXYLOC_YLOC_SHIFT          16
+
+//-----------------------------------------------------------------------------
+// CURSOR_DSCAN_LH_YLOC Register Definitions
+//-----------------------------------------------------------------------------
+#define CURSOR_DSCAN_LH_YLOC_MASK       0x000087ff
+
+#define CURSOR_DSCAN_LH_YLOC_YLOC_MASK  0x000007ff
+#define CURSOR_DSCAN_LH_YLOC_YLOC_SHIFT 0
+#define CURSOR_DSCAN_LH_YLOC_CLHEN      0x00008000
+
+//-----------------------------------------------------------------------------
+// CURSORSIZE Register Definitions
+//-----------------------------------------------------------------------------
+#define CURSORSIZE_MASK                 0x0000ffff
+
+#define CURSORSIZE_CWID_MASK            0x00000003
+#define CURSORSIZE_CWID_SHIFT           0
+#define CURSORSIZE_CWID_1_WORD          0
+#define CURSORSIZE_CWID_2_WORD          1
+#define CURSORSIZE_CWID_3_WORD          2
+#define CURSORSIZE_CWID_4_WORD          3
+
+#define CURSORSIZE_CLINS_MASK           0x000000fc
+#define CURSORSIZE_CLINS_SHIFT          2
+
+#define CURSORSIZE_CSTEP_MASK           0x00000300
+#define CURSORSIZE_CSTEP_SHIFT          8
+#define CURSORSIZE_CSTEP_1_WORD         0
+#define CURSORSIZE_CSTEP_2_WORD         1
+#define CURSORSIZE_CSTEP_3_WORD         2
+#define CURSORSIZE_CSTEP_4_WORD         3
+
+#define CURSORSIZE_DLNS_MASK            0x0000fc00
+#define CURSORSIZE_DLNS_SHIFT           10
+
+#endif /* _REGS_RASTER_H_ */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/regs_smc.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_smc.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/regs_smc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_smc.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,37 @@
+/*=======================================================================
+ *
+ *  FILE:       regs_smc.h
+ *
+ *  DESCRIPTION:    Static Memory Controller/PCMCIA Register Definition
+ *
+ *  Copyright Cirrus Logic, 2001-2004
+ *
+ *=======================================================================
+ */
+#ifndef _REGS_SMC_H_
+#define _REGS_SMC_H_
+
+/* Bit definitions */
+
+//
+// Bit field for SMC_PCAttribute, SMC_PCCommon, and SMC_PCIO
+//      
+#define PCCONFIG_ADDRESSTIME_MASK   0x000000FF
+#define PCCONFIG_HOLDTIME_MASK      0x00000F00
+#define PCCONFIG_ACCESSTIME_MASK    0x00FF0000
+#define PCCONFIG_MW_8BIT            0x00000000
+#define PCCONFIG_MW_16BIT           0x80000000
+#define PCCONFIG_ADDRESSTIME_SHIFT  0
+#define PCCONFIG_HOLDTIME_SHIFT     8
+#define PCCONFIG_ACCESSTIME_SHIFT   16
+
+//
+// Bit field for SMC_PCMCIACtrl
+//
+#define PCCONT_PC1EN                0x00000001
+#define PCCONT_PC2EN                0x00000002
+#define PCCONT_PC1RST               0x00000004
+#define PCCONT_WEN                  0x00000010
+
+
+#endif /* _REGS_SMC_H_ */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/regs_spi.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_spi.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/regs_spi.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_spi.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,87 @@
+/*=======================================================================
+ *
+ *  FILE:       regs_spi.h
+ *
+ *  DESCRIPTION:    SSP Register Definition
+ *
+ *  Copyright Cirrus Logic, 2001-2003
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *=======================================================================
+ */
+ 
+#ifndef _REGS_SSP_H_
+#define _REGS_SSP_H_
+
+//-----------------------------------------------------------------------------
+// Bits in SSPCR0
+//-----------------------------------------------------------------------------
+#define SSPCR0_DSS_MASK             0x0000000f
+#define SSPCR0_DSS_4BIT             0x00000003
+#define SSPCR0_DSS_5BIT             0x00000004
+#define SSPCR0_DSS_6BIT             0x00000005
+#define SSPCR0_DSS_7BIT             0x00000006
+#define SSPCR0_DSS_8BIT             0x00000007
+#define SSPCR0_DSS_9BIT             0x00000008
+#define SSPCR0_DSS_10BIT            0x00000009
+#define SSPCR0_DSS_11BIT            0x0000000a
+#define SSPCR0_DSS_12BIT            0x0000000b
+#define SSPCR0_DSS_13BIT            0x0000000c
+#define SSPCR0_DSS_14BIT            0x0000000d
+#define SSPCR0_DSS_15BIT            0x0000000e
+#define SSPCR0_DSS_16BIT            0x0000000f
+
+//-----------------------------------------------------------------------------
+// Bits in SSPCR1
+//-----------------------------------------------------------------------------
+#define SSPC1_RIE                   0x00000001
+#define SSPC1_TIE                   0x00000002
+#define SSPC1_RORIE		            0x00000004
+#define SSPC1_LBM                   0x00000008
+#define SSPC1_SSE                   0x00000010
+#define SSPC1_MS                    0x00000020
+#define SSPC1_SOD                   0x00000040
+
+#define SSPCR0_DSS_SHIFT            0
+#define SSPCR0_FRF_MASK             0x00000030
+#define SSPCR0_FRF_SHIFT            4
+#define SSPCR0_FRF_MOTOROLA         (0 << SSPCR0_FRF_SHIFT)
+#define SSPCR0_FRF_TI               (1 << SSPCR0_FRF_SHIFT)
+#define SSPCR0_FRF_NI               (2 << SSPCR0_FRF_SHIFT)
+#define SSPCR0_SPO                  0x00000040
+#define SSPCR0_SPH                  0x00000080
+#define SSPCR0_SCR_MASK             0x0000ff00
+#define SSPCR0_SCR_SHIFT            8
+
+//-----------------------------------------------------------------------------
+// Bits in SSPSR
+//-----------------------------------------------------------------------------
+#define SSPSR_TFE		    0x00000001      // TX FIFO is empty
+#define SSPSR_TNF    		0x00000002      // TX FIFO is not full
+#define SSPSR_RNE        	0x00000004      // RX FIFO is not empty
+#define SSPSR_RFF   		0x00000008      // RX FIFO is full
+#define SSPSR_BSY			0x00000010      // SSP is busy
+
+//-----------------------------------------------------------------------------
+// Bits in SSPIIR
+//-----------------------------------------------------------------------------
+#define SSPIIR_RIS			0x00000001      // RX FIFO IRQ status
+#define SSPIIR_TIS			0x00000002      // TX FIFO is not full
+#define SSPIIR_RORIS		0x00000004      // RX FIFO is full
+
+//=============================================================================
+//=============================================================================
+
+#endif /* _REGS_SSP_H_ */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/regs_syscon.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_syscon.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/regs_syscon.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_syscon.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,284 @@
+/*=============================================================================
+ *
+ *  FILE:       	reg_syscon.h
+ *
+ *  DESCRIPTION:    ep93xx Syscon Register Definition
+ *
+ *  Copyright Cirrus Logic, 2001-2003
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *=============================================================================
+ */
+#ifndef _REGS_SYSCON_H_
+#define _REGS_SYSCON_H_
+
+//=============================================================================
+#ifndef __ASSEMBLY__
+
+#define SysconSetLocked(registername,value)     \
+    {                                           \
+        outl( 0xAA, SYSCON_SWLOCK);             \
+        outl( value, registername);             \
+    }
+
+#endif /* Not __ASSEMBLY__ */
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// SYSCON_CLKSET1
+//-----------------------------------------------------------------------------
+#define SYSCON_CLKSET1_PLL1_X2IPD_SHIFT     0
+#define SYSCON_CLKSET1_PLL1_X2IPD_MASK      0x0000001f
+#define SYSCON_CLKSET1_PLL1_X2FBD2_SHIFT    5
+#define SYSCON_CLKSET1_PLL1_X2FBD2_MASK     0x000007e0
+#define SYSCON_CLKSET1_PLL1_X1FBD1_SHIFT    11
+#define SYSCON_CLKSET1_PLL1_X1FBD1_MASK     0x0000f800
+#define SYSCON_CLKSET1_PLL1_PS_SHIFT        16
+#define SYSCON_CLKSET1_PLL1_PS_MASK         0x00030000
+#define SYSCON_CLKSET1_PCLKDIV_SHIFT        18
+#define SYSCON_CLKSET1_PCLKDIV_MASK         0x000c0000
+#define SYSCON_CLKSET1_HCLKDIV_SHIFT        20
+#define SYSCON_CLKSET1_HCLKDIV_MASK         0x00700000
+#define SYSCON_CLKSET1_nBYP1                0x00800000
+#define SYSCON_CLKSET1_SMCROM               0x01000000
+#define SYSCON_CLKSET1_FCLKDIV_SHIFT        25
+#define SYSCON_CLKSET1_FCLKDIV_MASK         0x0e000000
+
+#define SYSCON_CLKSET1_HSEL                 0x00000001
+#define SYSCON_CLKSET1_PLL1_EXCLKSEL        0x00000002
+
+#define SYSCON_CLKSET1_PLL1_P_MASK          0x0000007C
+#define SYSCON_CLKSET1_PLL1_P_SHIFT         2
+
+#define SYSCON_CLKSET1_PLL1_M1_MASK         0x00000780
+#define SYSCON_CLKSET1_PLL1_M1_SHIFT        7
+#define SYSCON_CLKSET1_PLL1_M2_MASK         0x0000F800
+#define SYSCON_CLKSET1_PLL1_M2_SHIFT        11
+#define SYSCON_CLKSET1_PLL1_PS_MASK         0x00030000
+#define SYSCON_CLKSET1_PLL1_PS_SHIFT        16
+#define SYSCON_CLKSET1_PCLK_DIV_MASK        0x000C0000
+#define SYSCON_CLKSET1_PCLK_DIV_SHIFT       18
+#define SYSCON_CLKSET1_HCLK_DIV_MASK        0x00700000
+#define SYSCON_CLKSET1_HCLK_DIV_SHIFT       20
+#define SYSCON_CLKSET1_SMCROM               0x01000000
+#define SYSCON_CLKSET1_FCLK_DIV_MASK        0x0E000000
+#define SYSCON_CLKSET1_FCLK_DIV_SHIFT       25
+
+#define SYSCON_CLKSET2_PLL2_EN              0x00000001
+#define SYSCON_CLKSET2_PLL2EXCLKSEL         0x00000002
+#define SYSCON_CLKSET2_PLL2_P_MASK          0x0000007C
+#define SYSCON_CLKSET2_PLL2_P_SHIFT         2
+#define SYSCON_CLKSET2_PLL2_M2_MASK         0x00000F80
+#define SYSCON_CLKSET2_PLL2_M2_SHIFT        7
+#define SYSCON_CLKSET2_PLL2_M1_MASK         0x0001F000
+#define SYSCON_CLKSET2_PLL2_M1              12
+#define SYSCON_CLKSET2_PLL2_PS_MASK         0x000C0000
+#define SYSCON_CLKSET2_PLL2_PS_SHIFT        18
+#define SYSCON_CLKSET2_USBDIV_MASK          0xF0000000
+#define SYSCON_CLKSET2_USBDIV_SHIFT         28
+
+//-----------------------------------------------------------------------------
+// DEV_CFG Register Defines
+//-----------------------------------------------------------------------------
+#define SYSCON_DEVCFG_SHena            0x00000001
+#define SYSCON_DEVCFG_KEYS             0x00000002
+#define SYSCON_DEVCFG_ADCPD            0x00000004
+#define SYSCON_DEVCFG_RAS              0x00000008
+#define SYSCON_DEVCFG_RASonP3          0x00000010
+#define SYSCON_DEVCFG_TTIC             0x00000020
+#define SYSCON_DEVCFG_I2SonAC97        0x00000040
+#define SYSCON_DEVCFG_I2SonSSP         0x00000080
+#define SYSCON_DEVCFG_EonIDE           0x00000100
+#define SYSCON_DEVCFG_PonG             0x00000200
+#define SYSCON_DEVCFG_GonIDE           0x00000400
+#define SYSCON_DEVCFG_HonIDE           0x00000800
+#define SYSCON_DEVCFG_HC1CEN           0x00001000
+#define SYSCON_DEVCFG_HC1IN            0x00002000
+#define SYSCON_DEVCFG_HC3CEN           0x00004000
+#define SYSCON_DEVCFG_HC3IN            0x00008000
+#define SYSCON_DEVCFG_TIN              0x00020000
+#define SYSCON_DEVCFG_U1EN             0x00040000
+#define SYSCON_DEVCFG_EXVC             0x00080000
+#define SYSCON_DEVCFG_U2EN             0x00100000
+#define SYSCON_DEVCFG_A1onG            0x00200000
+#define SYSCON_DEVCFG_A2onG            0x00400000
+#define SYSCON_DEVCFG_CPENA            0x00800000
+#define SYSCON_DEVCFG_U3EN             0x01000000
+#define SYSCON_DEVCFG_MonG             0x02000000
+#define SYSCON_DEVCFG_TonG             0x04000000
+#define SYSCON_DEVCFG_GonK             0x08000000
+#define SYSCON_DEVCFG_IonU2            0x10000000
+#define SYSCON_DEVCFG_D0onG            0x20000000
+#define SYSCON_DEVCFG_D1onG            0x40000000
+#define SYSCON_DEVCFG_SWRST            0x80000000
+
+//-----------------------------------------------------------------------------
+// VIDDIV Register Defines
+//-----------------------------------------------------------------------------
+#define SYSCON_VIDDIV_VDIV_MASK         0x0000007f              
+#define SYSCON_VIDDIV_VDIV_SHIFT        0
+#define SYSCON_VIDDIV_PDIV_MASK         0x00000300
+#define SYSCON_VIDDIV_PDIV_SHIFT        8
+#define SYSCON_VIDDIV_PSEL              0x00002000
+#define SYSCON_VIDDIV_ESEL              0x00004000
+#define SYSCON_VIDDIV_VENA              0x00008000
+
+//-----------------------------------------------------------------------------
+// MIRDIV Register Defines
+//-----------------------------------------------------------------------------
+#define SYSCON_MIRDIV_MDIV_MASK         0x0000003f
+#define SYSCON_MIRDIV_MDIV_SHIFT        0
+#define SYSCON_MIRDIV_PDIV_MASK         0x00000300
+#define SYSCON_MIRDIV_PDIV_SHIFT        8
+#define SYSCON_MIRDIV_PSEL              0x00002000              
+#define SYSCON_MIRDIV_ESEL              0x00004000
+#define SYSCON_MIRDIV_MENA              0x00008000
+
+//-----------------------------------------------------------------------------
+// I2SDIV Register Defines
+//-----------------------------------------------------------------------------
+#define SYSCON_I2SDIV_MDIV_MASK         0x0000007f
+#define SYSCON_I2SDIV_MDIV_SHIFT        0
+#define SYSCON_I2SDIV_PDIV_MASK         0x00000300
+#define SYSCON_I2SDIV_PDIV_SHIFT        8
+#define SYSCON_I2SDIV_PSEL              0x00002000
+#define SYSCON_I2SDIV_ESEL              0x00004000
+#define SYSCON_I2SDIV_MENA              0x00008000
+#define SYSCON_I2SDIV_SDIV              0x00010000
+#define SYSCON_I2SDIV_LRDIV_MASK        0x00060000
+#define SYSCON_I2SDIV_LRDIV_SHIFT       17
+#define SYSCON_I2SDIV_SPOL              0x00080000
+#define SYSCON_I2SDIV_DROP              0x00100000
+#define SYSCON_I2SDIV_ORIDE             0x20000000
+#define SYSCON_I2SDIV_SLAVE             0x40000000
+#define SYSCON_I2SDIV_SENA              0x80000000
+
+#define SYSCON_I2SDIV_PDIV_OFF          0x00000000
+#define SYSCON_I2SDIV_PDIV_2            0x00000100
+#define SYSCON_I2SDIV_PDIV_25           0x00000200
+#define SYSCON_I2SDIV_PDIV_3            0x00000300
+
+#define SYSCON_I2SDIV_LRDIV_32          0x00000000
+#define SYSCON_I2SDIV_LRDIV_64          0x00020000
+#define SYSCON_I2SDIV_LRDIV_128         0x00040000
+
+//-----------------------------------------------------------------------------
+// KTDIV Register Defines
+//-----------------------------------------------------------------------------
+#define SYSCON_KTDIV_KDIV               0x00000001
+#define SYSCON_KTDIV_KEN                0x00008000
+#define SYSCON_KTDIV_ADIV               0x00010000
+#define SYSCON_KTDIV_TSEN               0x80000000
+
+//-----------------------------------------------------------------------------
+// CHIPID Register Defines
+//-----------------------------------------------------------------------------
+#define SYSCON_CHIPID_ID_MASK           0x0000ffff
+#define SYSCON_CHIPID_ID_SHIFT          0
+#define SYSCON_CHIPID_PKID              0x00010000
+#define SYSCON_CHIPID_BND               0x00040000
+#define SYSCON_CHIPID_FAB_MASK          0x0e000000
+#define SYSCON_CHIPID_FAB_SHIFT         25
+#define SYSCON_CHIPID_REV_MASK          0xf0000000
+#define SYSCON_CHIPID_REV_SHIFT         28
+
+//-----------------------------------------------------------------------------
+// TESTCR Register Defines
+//-----------------------------------------------------------------------------
+#define SYSCON_TESTCR_TMODE_MASK        0x000000ff
+#define SYSCON_TESTCR_TMODE_SHIFT       0
+#define SYSCON_TESTCR_BONDO             0x00000100
+#define SYSCON_TESTCR_PACKO             0x00000800
+#define SYSCON_TESTCR_ETOM              0x00002000
+#define SYSCON_TESTCR_TOM               0x00004000
+#define SYSCON_TESTCR_OVR               0x00008000
+#define SYSCON_TESTCR_TonIDE            0x00010000
+#define SYSCON_TESTCR_RonG              0x00020000
+
+//-----------------------------------------------------------------------------
+// SYSCFG Register Defines
+//-----------------------------------------------------------------------------
+#define SYSCON_SYSCFG_LCSn1             0x00000001
+#define SYSCON_SYSCFG_LCSn2             0x00000002
+#define SYSCON_SYSCFG_LCSn3             0x00000004
+#define SYSCON_SYSCFG_LEECK             0x00000008
+#define SYSCON_SYSCFG_LEEDA             0x00000010
+#define SYSCON_SYSCFG_LASDO             0x00000020
+#define SYSCON_SYSCFG_LCSn6             0x00000040
+#define SYSCON_SYSCFG_LCSn7             0x00000080
+#define SYSCON_SYSCFG_SBOOT             0x00000100
+#define SYSCON_SYSCFG_FAB_MASK          0x0e000000
+#define SYSCON_SYSCFG_FAB_SHIFT         25
+#define SYSCON_SYSCFG_REV_MASK          0xf0000000
+#define SYSCON_SYSCFG_REV_SHIFT         28
+
+
+//-----------------------------------------------------------------------------
+// PWRSR Register Defines
+//-----------------------------------------------------------------------------
+#define SYSCON_PWRSR_CHIPMAN_MASK       0xFF000000
+#define SYSCON_PWRSR_CHIPMAN_SHIFT      24
+#define SYSCON_PWRSR_CHIPID_MASK        0x00FF0000
+#define SYSCON_PWRSR_CHIPID_SHIFT       16
+#define SYSCON_PWRSR_WDTFLG             0x00008000
+#define SYSCON_PWRSR_CLDFLG             0x00002000
+#define SYSCON_PWRSR_TEST_RESET         0x00001000
+#define SYSCON_PWRSR_RSTFLG             0x00000800
+#define SYSCON_PWRSR_SWRESET            0x00000400
+#define SYSCON_PWRSR_PLL2_LOCKREG       0x00000200
+#define SYSCON_PWRSR_PLL2_LOCK          0x00000100
+#define SYSCON_PWRSR_PLL1_LOCKREG       0x00000080    
+#define SYSCON_PWRSR_PLL1_LOCK          0x00000040    
+#define SYSCON_PWRSR_RTCDIV             0x0000003F
+
+//-----------------------------------------------------------------------------
+// PWRCNT Register Defines
+//-----------------------------------------------------------------------------
+#define SYSCON_PWRCNT_FIREN             0x80000000
+#define SYSCON_PWRCNT_UARTBAUD          0x20000000
+#define SYSCON_PWRCNT_USHEN             0x10000000
+#define SYSCON_PWRCNT_DMA_M2MCH1        0x08000000
+#define SYSCON_PWRCNT_DMA_M2MCH0        0x04000000
+#define SYSCON_PWRCNT_DMA_M2PCH8        0x02000000
+#define SYSCON_PWRCNT_DMA_M2PCH9        0x01000000
+#define SYSCON_PWRCNT_DMA_M2PCH6        0x00800000
+#define SYSCON_PWRCNT_DMA_M2PCH7        0x00400000
+#define SYSCON_PWRCNT_DMA_M2PCH4        0x00200000
+#define SYSCON_PWRCNT_DMA_M2PCH5        0x00100000
+#define SYSCON_PWRCNT_DMA_M2PCH2        0x00080000
+#define SYSCON_PWRCNT_DMA_M2PCH3        0x00040000
+#define SYSCON_PWRCNT_DMA_M2PCH0        0x00020000
+#define SYSCON_PWRCNT_DMA_M2PCH1        0x00010000
+
+//-----------------------------------------------------------------------------
+// BMAR Register Defines
+//-----------------------------------------------------------------------------
+#define BMAR_PRIORD_00              0x00000000
+#define BMAR_PRIORD_01              0x00000001
+#define BMAR_PRIORD_02              0x00000002
+#define BMAR_PRIORD_03              0x00000003
+#define BMAR_PRI_CORE               0x00000008
+#define BMAR_DMA_ENIRQ              0x00000010
+#define BMAR_DMA_ENFIQ              0x00000020
+#define BMAR_USB_ENIRQ              0x00000040
+#define BMAR_USB_ENFIQ              0x00000080
+#define BMAR_MAC_ENIRQ              0x00000100
+#define BMAR_MAC_ENFIQ              0x00000200
+#define BMAR_GRAPHICS_ENIRQ         0x00000400
+#define BMAR_GRAPHICS_ENFIQ         0x00000800
+
+
+#endif // _REGS_SYSCON_H_
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/regs_touch.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_touch.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/regs_touch.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_touch.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,95 @@
+/*=============================================================================
+ *
+ *  FILE:       regs_touch.h
+ *
+ *  DESCRIPTION:    Analog Touchscreen Register Definition
+ *
+ *  Copyright Cirrus Logic, 2001-2003
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *=============================================================================
+ */
+#ifndef _REGS_TOUCH_H_
+#define _REGS_TOUCH_H_
+
+/*
+ *-----------------------------------------------------------------------------
+ * Individual bit #defines
+ *-----------------------------------------------------------------------------
+ */
+#define TSSETUP_SDLY_MASK           0x000003FF 
+#define TSSETUP_SDLY_SHIFT          0
+#define TSSETUP_NSMP_4              0x00000000
+#define TSSETUP_NSMP_8              0x00000400
+#define TSSETUP_NSMP_16             0x00000800
+#define TSSETUP_NSMP_32             0x00000C00
+#define TSSETUP_NSMP_MASK           0x00000C00
+#define TSSETUP_DEV_4               0x00000000
+#define TSSETUP_DEV_8               0x00001000
+#define TSSETUP_DEV_12              0x00002000
+#define TSSETUP_DEV_16              0x00003000
+#define TSSETUP_DEV_24              0x00004000
+#define TSSETUP_DEV_32              0x00005000
+#define TSSETUP_DEV_64              0x00006000
+#define TSSETUP_DEV_128             0x00007000
+#define TSSETUP_ENABLE              0x00008000
+#define TSSETUP_DLY_MASK            0x03FF0000
+#define TSSETUP_DLY_SHIFT           16
+#define TSSETUP_TDTCT               0x80000000
+
+#define TSMAXMIN_XMIN_MASK          0x000000FF
+#define TSMAXMIN_XMIN_SHIFT         0
+#define TSMAXMIN_YMIN_MASK          0x0000FF00
+#define TSMAXMIN_YMIN_SHIFT         8
+#define TSMAXMIN_XMAX_MASK          0x00FF0000
+#define TSMAXMIN_XMAX_SHIFT         16
+#define TSMAXMIN_YMAX_MASK          0xFF000000
+#define TSMAXMIN_YMAX_SHIFT         24
+
+#define TSXYRESULT_X_MASK           0x00000FFF
+#define TSXYRESULT_X_SHIFT          0
+#define TSXYRESULT_AD_MASK          0x0000FFFF
+#define TSXYRESULT_AD_SHIFT         0
+#define TSXYRESULT_Y_MASK           0x0FFF0000
+#define TSXYRESULT_Y_SHIFT          16
+#define TSXYRESULT_SDR              0x80000000
+
+#define TSX_SAMPLE_MASK             0x00003FFF
+#define TSX_SAMPLE_SHIFT            0x00
+#define TSY_SAMPLE_MASK             0x3FFF0000
+#define TSY_SAMPLE_SHIFT            0x10
+
+#define TSSETUP2_TINT               0x00000001
+#define TSSETUP2_NICOR              0x00000002
+#define TSSETUP2_PINT               0x00000004
+#define TSSETUP2_PENSTS             0x00000008
+#define TSSETUP2_PINTEN             0x00000010
+#define TSSETUP2_DEVINT             0x00000020
+#define TSSETUP2_DINTEN             0x00000040
+#define TSSETUP2_DTMEN              0x00000080
+#define TSSETUP2_DISDEV             0x00000100
+#define TSSETUP2_NSIGND             0x00000200
+#define TSSETUP2_S28EN              0x00000400
+#define TSSETUP2_RINTEN             0x00000800
+
+#define TSXYRESULT_SDR     			0x80000000
+
+/*
+ *-----------------------------------------------------------------------------
+ *-----------------------------------------------------------------------------
+ */
+
+
+#endif /* _REGS_TOUCH_H_ */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/regs_uart.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_uart.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/regs_uart.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/regs_uart.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,79 @@
+/*
+ *  File:   linux/include/asm-arm/arch-ep93xx/regs_uart.h
+ *
+ *  Copyright (C) 2003 Cirrus Logic, Inc
+ *  
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+#ifndef _REGS_UART_H_
+#define _REGS_UART_H_
+
+//-----------------------------------------------------------------------------
+// Bits in UARTRSR
+//-----------------------------------------------------------------------------
+#define UARTRSR_FE              0x00000001      // Framing error
+#define UARTRSR_PE              0x00000002      // Parity error
+#define UARTRSR_BE              0x00000004      // Break error
+#define UARTRSR_OE              0x00000008      // Overrun error
+
+//-----------------------------------------------------------------------------
+// Bits in UARTCR - UART1CR, UART2CR, or UART3CR
+//-----------------------------------------------------------------------------
+#define UARTLCR_H_BRK           0x00000001
+#define UARTLCR_H_PEN           0x00000002
+#define UARTLCR_H_EPS           0x00000004
+#define UARTLCR_H_STP2          0x00000008
+#define UARTLCR_H_FEN           0x00000010
+#define UARTLCR_H_WLEN          0x00000060
+#define UARTLCR_H_WLEN_8_DATA   0x00000060
+#define UARTLCR_H_WLEN_7_DATA   0x00000040
+#define UARTLCR_H_WLEN_6_DATA   0x00000020
+#define UARTLCR_H_WLEN_5_DATA   0x00000000
+
+//-----------------------------------------------------------------------------
+// Bits in UARTFR - UART1FR, UART2FR, or UART3FR
+//-----------------------------------------------------------------------------
+#define UARTFR_RSR_ERRORS       0x0000000F
+#define UARTFR_CTS              0x00000001
+#define UARTFR_DSR              0x00000002
+#define UARTFR_DCD              0x00000004
+#define UARTFR_BUSY             0x00000008
+#define UARTFR_RXFE             0x00000010
+#define UARTFR_TXFF             0x00000020
+#define UARTFR_RXFF             0x00000040
+#define UARTFR_TXFE             0x00000080
+
+//-----------------------------------------------------------------------------
+// Bits in UARTIIR
+//-----------------------------------------------------------------------------
+#define UARTIIR_MIS             0x00000001
+#define UARTIIR_RIS             0x00000002
+#define UARTIIR_TIS             0x00000004
+#define UARTIIR_RTIS            0x00000008
+
+//-----------------------------------------------------------------------------
+// Bits in UARTCR
+//-----------------------------------------------------------------------------
+#define UARTCR_UARTE            0x00000001
+#define UARTCR_MSIE             0x00000008
+#define UARTCR_RIE              0x00000010
+#define UARTCR_TIE              0x00000020
+#define UARTCR_RTIE             0x00000040
+#define UARTCR_LBE              0x00000080
+
+//=============================================================================
+//=============================================================================
+#endif /* _REGS_UART_H_ */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/serial.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/serial.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/serial.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,49 @@
+/*
+ *  linux/include/asm-arm/arch-integrator/serial.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <asm/arch/platform.h>
+#include <asm/irq.h>
+
+/*
+ * This assumes you have a 1.8432 MHz clock for your UART.
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ */
+#define BASE_BAUD (1843200 / 16)
+
+#define _SER_IRQ0	IRQ_UARTINT0
+#define _SER_IRQ1	IRQ_UARTINT1
+
+#define RS_TABLE_SIZE	2
+
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+     /* UART CLK        PORT  IRQ     FLAGS        */
+#define STD_SERIAL_PORT_DEFNS \
+	{ 0, BASE_BAUD, 0x3F8, _SER_IRQ0, STD_COM_FLAGS },	/* ttyS0 */	\
+	{ 0, BASE_BAUD, 0x2F8, _SER_IRQ1, STD_COM_FLAGS },	/* ttyS1 */
+
+#define EXTRA_SERIAL_PORT_DEFNS
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/ssp.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/ssp.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/ssp.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/ssp.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ * 
+ *  FILE:           ssp.h
+ *
+ *  DESCRIPTION:    SSP Interface Driver Module implementation
+ *
+ *  Copyright Cirrus Logic Corporation, 2001-2003.  All rights reserved
+ *
+ */
+#ifndef _SSP_DRV_H_
+#define _SSP_DRV_H_
+
+typedef enum 
+{
+	PS2_KEYBOARD = 0,
+	I2S_CODEC    = 1,
+	SERIAL_FLASH = 2
+} SSPDeviceType;
+
+typedef void (*SSPDataCallback)(unsigned int Data);
+
+typedef struct _SSP_DRIVER_API
+{
+    int (*Open)(SSPDeviceType Device, SSPDataCallback Callback);
+    int (*Read)(int Handle, unsigned int Addr, unsigned int *pValue);
+    int (*Write)(int Handle, unsigned int Addr, unsigned int Value);
+    int (*Close)(int Handle);
+} SSP_DRIVER_API;
+
+extern SSP_DRIVER_API *SSPDriver;
+
+#endif /* _SSP_DRV_H_ */
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/system.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/system.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/system.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,131 @@
+/*
+ *  linux/include/asm-arm/arch-ep93xx/system.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <asm/arch/platform.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+static void arch_idle(void)
+{
+	unsigned long ulTemp;
+
+	ulTemp = inl(SYSCON_HALT);
+}
+
+extern __inline__ void arch_reset(char mode)
+{
+	//
+	// Disable the peripherals.
+	//
+	outl(0xffffffff, VIC0INTENCLEAR);
+	outl(0xffffffff, VIC1INTENCLEAR);
+	outl(0, DMAMP_TX_0_CONTROL);
+	outl(0, DMAMP_RX_1_CONTROL);
+	outl(0, DMAMP_TX_2_CONTROL);
+	outl(0, DMAMP_RX_3_CONTROL);
+	outl(0, DMAMM_0_CONTROL);
+	outl(0, DMAMM_1_CONTROL);
+	outl(0, DMAMP_TX_4_CONTROL);
+	outl(0, DMAMP_RX_5_CONTROL);
+	outl(0, DMAMP_TX_6_CONTROL);
+	outl(0, DMAMP_RX_7_CONTROL);
+	outl(0, DMAMP_TX_8_CONTROL);
+	outl(0, DMAMP_RX_9_CONTROL);
+	outl(1, MAC_SELFCTL);
+	while(inl(MAC_SELFCTL) & 1)
+		barrier();
+	outl(1, HCCOMMANDSTATUS);
+	while(inl(HCCOMMANDSTATUS) & 1)
+		barrier();
+	outl(0, IrEnable);
+	outl(0, UART1CR);
+	outl(0, UART2CR);
+	outl(0, I2STX0En);
+	outl(0, I2SRX0En);
+	outl(0, AC97GCR);
+	outl(0, SSPCR1);
+#ifdef CONFIG_ARCH_EP9315
+	outl(0, SMC_PCMCIACtrl);
+	outl(0, BLOCKCTRL);
+#endif
+#if defined(CONFIG_ARCH_EP9312) || defined(CONFIG_ARCH_EP9315)
+	outl(0, VIDEOATTRIBS);
+	outl(0, UART3CR);
+	outl(0, I2STX1En);
+	outl(0, I2SRX1En);
+	outl(0, I2STX2En);
+	outl(0, I2SRX2En);
+	outl(0, TSSetup);
+	outl(0, IDECFG);
+	outl(0xaa, SYSCON_SWLOCK);
+	outl(0, SYSCON_VIDDIV);
+	outl(0xaa, SYSCON_SWLOCK);
+	outl(0, SYSCON_KTDIV);
+#endif
+	outl(0xaa, SYSCON_SWLOCK);
+	outl(0, SYSCON_MIRDIV);
+	outl(0xaa, SYSCON_SWLOCK);
+	outl(0, SYSCON_I2SDIV);
+	outl(0, SYSCON_PWRCNT);
+	outl(0xaa, SYSCON_SWLOCK);
+	outl(0, SYSCON_DEVCFG);
+	outl(0x000398e7, SYSCON_CLKSET1);
+	inl(SYSCON_CLKSET1);
+	__asm__ __volatile__("nop");
+	__asm__ __volatile__("nop");
+	__asm__ __volatile__("nop");
+	__asm__ __volatile__("nop");
+	__asm__ __volatile__("nop");
+	outl(0x0003c317, SYSCON_CLKSET2);
+	__asm__ __volatile__("nop");
+	__asm__ __volatile__("nop");
+	__asm__ __volatile__("nop");
+	__asm__ __volatile__("nop");
+	__asm__ __volatile__("nop");
+	outl(0, GPIO_PADDR);
+	outl(0, GPIO_PBDDR);
+	outl(0, GPIO_PCDDR);
+#if defined(CONFIG_ARCH_EP9312) || defined(CONFIG_ARCH_EP9315)
+	outl(0, GPIO_PDDDR);
+#endif
+	outl(0x3, GPIO_PEDR);
+	outl(0x3, GPIO_PEDDR);
+	outl(0, GPIO_PFDDR);
+	outl(0, GPIO_PGDR);
+	outl(0xc, GPIO_PGDDR);
+	outl(0, GPIO_PHDDR);
+	outl(0, GPIO_PDDDR);
+	outl(0, GPIO_PDDDR);
+	outl(0, GPIO_AINTEN);
+	outl(0, GPIO_BINTEN);
+	outl(0, GPIO_FINTEN);
+	outl(0, GPIO_EEDRIVE);
+
+	//
+	// Reset the CPU, branching to the appropriate location based on the
+	// boot mode.
+	//
+	cpu_reset((inl(SYSCON_SYSCFG) & SYSCON_SYSCFG_LEECK) ?
+		  0x80090000 : 0x0);
+}
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/time.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/time.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/time.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,48 @@
+/*
+ *  linux/include/asm-arm/arch-ep93xx/time.h
+ *
+ * (c) Copyright 2001 LynuxWorks, Inc., San Jose, CA.  All rights reserved.
+ *
+ * Copyright (C) 2002-2003 Cirrus Logic, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/system.h>
+#include <asm/leds.h>
+#include <asm/arch/hardware.h>
+
+extern void ep93xx_setup_timer(void);
+
+/*
+ * IRQ handler for the timer
+ */
+static void ep93xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	outl( 1, TIMER1CLEAR );
+	do_leds();
+	do_timer(regs);
+	do_profile(regs);
+}
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+static inline void setup_timer(void)
+{
+	ep93xx_setup_timer();
+	timer_irq.handler = ep93xx_timer_interrupt;
+	setup_arm_irq(IRQ_TIMER1, &timer_irq);
+}
+
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/timex.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/timex.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/timex.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,23 @@
+/*
+ *  linux/include/asm-arm/arch-integrator/timex.h
+ *
+ *  Integrator architecture timex specifications
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+#define CLOCK_TICK_RATE 508000
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/uncompress.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/uncompress.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/uncompress.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,69 @@
+/*
+ *  linux/include/asm-arm/arch-ep93xx/uncompress.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <asm/hardware.h>
+
+#undef EP93XX_APB_BASE
+#define EP93XX_APB_BASE (IO_BASE_PHYS | 0x00800000)
+
+#ifdef CONFIG_MACH_IPD
+#define _BAUDRATE 115200
+#define UART(reg)	UART2##reg
+#endif
+
+#ifndef UART
+#define UART(reg)	UART1##reg
+#endif
+
+#ifndef _BAUDRATE
+#define _BAUDRATE 57600
+#endif
+
+#define BAUDRATE ((14745600 / (16 * _BAUDRATE)) - 1)
+
+static void puts(const char *s)
+{
+	while (*s)
+	{
+		while (inl(UART(FR)) & UARTFR_TXFF)
+			barrier();
+
+		outl(*s, UART(DR));
+        
+		if (*s == '\n') {
+			while (inl(UART(FR)) & UARTFR_TXFF)
+				barrier();
+	    
+			outl('\r', UART(DR));
+		}
+		s++;
+	}
+	while(inl(UART(FR)) & UARTFR_BUSY)
+		barrier();
+}
+
+#define arch_decomp_setup()
+
+#ifdef CONFIG_MACH_IPD
+#define arch_decomp_wdog() (* (volatile unsigned char *) 0x20000000)
+#else
+#define arch_decomp_wdog()
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ep93xx/vmalloc.h linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/vmalloc.h
--- linux-2.4.29/include/asm-arm/arch-ep93xx/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ep93xx/vmalloc.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ *  linux/include/asm-arm/arch-integrator/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff -urN linux-2.4.29/include/asm-arm/arch-epxa/excalibur.h linux-2.4.29-uc1/include/asm-arm/arch-epxa/excalibur.h
--- linux-2.4.29/include/asm-arm/arch-epxa/excalibur.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-epxa/excalibur.h	2005-06-14 02:11:23.000000000 +0100
@@ -1,10 +1,8 @@
 #include <linux/config.h>
-#ifdef CONFIG_EPXA10DB_R2
-#include "exc-epxa10dbr2.h"
-#elif defined CONFIG_EPXA10DB_R3
-#include "exc-epxa10dbr3.h"
+#ifdef CONFIG_EPXA10DB
+#include "exc-epxa10db.h"
 #elif defined CONFIG_EPXA1DB
 #include "exc-epxa1db.h"
 #else
-#error "must select an EPXA development board"
+#error "must define epxa10db or epxa1db"
 #endif
diff -urN linux-2.4.29/include/asm-arm/arch-epxa/exc-epxa10db.h linux-2.4.29-uc1/include/asm-arm/arch-epxa/exc-epxa10db.h
--- linux-2.4.29/include/asm-arm/arch-epxa/exc-epxa10db.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-epxa/exc-epxa10db.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,85 @@
+/* megafunction wizard: %ARM-Based Excalibur%
+   GENERATION: STANDARD
+   VERSION: WM1.0
+   MODULE: ARM-Based Excalibur
+   PROJECT: excalibur
+   ============================================================
+   File Name: v:\embedded\linux\bootldr\excalibur.h
+   Megafunction Name(s): ARM-Based Excalibur
+   ============================================================
+
+   ************************************************************
+   THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+   ************************************************************/
+
+#ifndef	EXCALIBUR_H_INCLUDED
+#define	EXCALIBUR_H_INCLUDED
+
+#define EXC_DEFINE_PROCESSOR_LITTLE_ENDIAN
+#define EXC_DEFINE_BOOT_FROM_FLASH
+
+#define	EXC_INPUT_CLK_FREQUENCY (50000000)
+#define	EXC_AHB1_CLK_FREQUENCY (150000000)
+#define	EXC_AHB2_CLK_FREQUENCY (75000000)
+#define	EXC_SDRAM_CLK_FREQUENCY (75000000)
+
+/* Registers Block */
+#define	EXC_REGISTERS_BASE (0x7fffc000)
+#define	EXC_MODE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x000)
+#define	EXC_IO_CTRL00_BASE (EXC_REGISTERS_BASE + 0x040)
+#define	EXC_MMAP00_BASE (EXC_REGISTERS_BASE + 0x080)
+#define	EXC_PLD_CONFIG00_BASE (EXC_REGISTERS_BASE + 0x140)
+#define	EXC_TIMER00_BASE (EXC_REGISTERS_BASE + 0x200)
+#define	EXC_INT_CTRL00_BASE (EXC_REGISTERS_BASE + 0xc00)
+#define	EXC_CLOCK_CTRL00_BASE (EXC_REGISTERS_BASE + 0x300)
+#define	EXC_WATCHDOG00_BASE (EXC_REGISTERS_BASE + 0xa00)
+#define	EXC_UART00_BASE (EXC_REGISTERS_BASE + 0x280)
+#define	EXC_EBI00_BASE (EXC_REGISTERS_BASE + 0x380)
+#define	EXC_SDRAM00_BASE (EXC_REGISTERS_BASE + 0x400)
+#define	EXC_AHB12_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x800)
+#define	EXC_PLD_STRIPE_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x100)
+#define	EXC_STRIPE_PLD_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x100)
+
+#define	EXC_REGISTERS_SIZE (0x00004000)
+
+/* EBI Block(s) */
+#define	EXC_EBI_BLOCK0_BASE (0x40000000)
+#define	EXC_EBI_BLOCK0_SIZE (0x00400000)
+#define	EXC_EBI_BLOCK0_WIDTH (8)
+#define	EXC_EBI_BLOCK0_NON_CACHEABLE
+#define	EXC_EBI_BLOCK1_BASE (0x40400000)
+#define	EXC_EBI_BLOCK1_SIZE (0x00400000)
+#define	EXC_EBI_BLOCK1_WIDTH (16)
+#define	EXC_EBI_BLOCK1_NON_CACHEABLE
+#define	EXC_EBI_BLOCK2_BASE (0x40800000)
+#define	EXC_EBI_BLOCK2_SIZE (0x00400000)
+#define	EXC_EBI_BLOCK2_WIDTH (16)
+#define	EXC_EBI_BLOCK2_NON_CACHEABLE
+#define	EXC_EBI_BLOCK3_BASE (0x40c00000)
+#define	EXC_EBI_BLOCK3_SIZE (0x00400000)
+#define	EXC_EBI_BLOCK3_WIDTH (16)
+#define	EXC_EBI_BLOCK3_NON_CACHEABLE
+
+/* SDRAM Block(s) */
+#define	EXC_SDRAM_BLOCK0_BASE (0x00000000)
+#define	EXC_SDRAM_BLOCK0_SIZE (0x04000000)
+#define	EXC_SDRAM_BLOCK0_WIDTH (32)
+#define	EXC_SDRAM_BLOCK1_BASE (0x04000000)
+#define	EXC_SDRAM_BLOCK1_SIZE (0x04000000)
+#define	EXC_SDRAM_BLOCK1_WIDTH (32)
+
+/* Single Port SRAM Block(s) */
+#define	EXC_SPSRAM_BLOCK0_BASE (0x20000000)
+#define	EXC_SPSRAM_BLOCK0_SIZE (0x00020000)
+#define	EXC_SPSRAM_BLOCK1_BASE (0x20020000)
+#define	EXC_SPSRAM_BLOCK1_SIZE (0x00020000)
+
+/* PLD Block(s) */
+#define	EXC_PLD_BLOCK0_BASE (0x80000000)
+#define	EXC_PLD_BLOCK0_SIZE (0x80000000)
+#define	EXC_PLD_BLOCK0_NON_CACHEABLE
+#define	EXC_PLD_BLOCK1_BASE (0x60000000)
+#define	EXC_PLD_BLOCK1_SIZE (0x10000000)
+#define	EXC_PLD_BLOCK1_NON_CACHEABLE
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/aau.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/aau.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/aau.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/aau.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,104 @@
+/*
+ * Definitions for IOP310 AAU 
+ *
+ * Author: Dave Jiang (dave.jiang@intel.com)
+ * Copyright (C) 2001 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _IOP310_AAU_H_
+#define _IOP310_AAU_H_
+
+
+#define DEFAULT_AAU_IRQ_THRESH  10
+
+#define MAX_AAU_DESC    1024	/*64 */
+#define AAU_SAR_GROUP   	4
+
+
+#define AAU_DESC_DONE   	 0x0010
+#define AAU_INCOMPLETE  	 0x0020
+#define AAU_HOLD			 0x0040
+#define AAU_END_CHAIN		 0x0080
+#define AAU_COMPLETE		 0x0100
+#define AAU_NOTIFY			 0x0200
+#define AAU_NEW_HEAD		 0x0400
+
+#define AAU_USER_MASK	(AAU_NOTIFY | AAU_INCOMPLETE | \
+						 AAU_HOLD | AAU_COMPLETE)
+
+#define DESC_HEAD           0x0010
+#define DESC_TAIL           0x0020
+
+/* result writeback */
+#define AAU_DCR_WRITE           	0x80000000
+/* source block extension */
+#define AAU_DCR_BLK_EXT         	0x02000000
+#define AAU_DCR_BLKCTRL_8_XOR       0x00400000
+#define AAU_DCR_BLKCTRL_7_XOR       0x00080000
+#define AAU_DCR_BLKCTRL_6_XOR       0x00010000
+#define AAU_DCR_BLKCTRL_5_XOR       0x00002000
+#define AAU_DCR_BLKCTRL_4_XOR       0x00000400
+#define AAU_DCR_BLKCTRL_3_XOR       0x00000080
+#define AAU_DCR_BLKCTRL_2_XOR       0x00000010
+#define AAU_DCR_BLKCTRL_1_XOR       0x00000002
+/* first block direct fill instead of XOR to buffer */
+#define AAU_DCR_BLKCTRL_1_DF		0x0000000E
+/* interrupt enable */
+#define AAU_DCR_IE              	0x00000001
+
+#define DCR_BLKCTRL_OFFSET      3
+
+
+/* AAU callback */
+typedef void (*aau_callback_t) (void *buf_id);
+
+/* hardware descriptor */
+typedef struct _aau_desc
+{
+	u32 NDA;					/* next descriptor address */
+	u32 SAR[AAU_SAR_GROUP];		/* src addrs */
+	u32 DAR;					/* destination addr */
+	u32 BC;						/* byte count */
+	u32 DC;						/* descriptor control */
+	u32 SARE[AAU_SAR_GROUP];	/* extended src addrs */
+} aau_desc_t;
+
+/* user SGL format */
+typedef struct _aau_sgl
+{
+	aau_desc_t aau_desc;		/* AAU HW Desc */
+	u32 status;
+	struct _aau_sgl *next;		/* pointer to next SG */
+	void *dest;					/* destination addr */
+	void *src[AAU_SAR_GROUP];	/* source addr[4] */
+	void *ext_src[AAU_SAR_GROUP];	/* ext src addr[4] */
+	u32 total_src;				/* total number of source */
+} aau_sgl_t;
+
+/* header for user SGL */
+typedef struct _aau_head
+{
+	u32 total;
+	u32 status;					/* SGL status */
+	aau_sgl_t *list;			/* ptr to head of list */
+	aau_callback_t callback;	/* callback func ptr */
+} aau_head_t;
+
+/* prototypes */
+int aau_request(u32 *, const char *);
+int aau_queue_buffer(u32, aau_head_t *);
+void aau_suspend(u32);
+void aau_resume(u32);
+void aau_free(u32);
+void aau_set_irq_threshold(u32, int);
+void aau_return_buffer(u32, aau_sgl_t *);
+aau_sgl_t *aau_get_buffer(u32, int);
+int aau_memcpy(void *, void *, u32);
+
+#endif
+/* EOF */
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/dma.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/dma.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/dma.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,109 @@
+/*
+ * linux/include/asm-arm/arch-iop80310/dma.h
+ *
+ *  Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _IOP310_DMA_H_
+#define _IOP310_DMA_H_
+
+/* 2 DMA on primary PCI and 1 on secondary for 80310 */
+#define MAX_IOP310_DMA_CHANNEL   3
+#define MAX_DMA_DESC        	64	/*128 */
+
+/*
+ * Make the generic DMA bits go away since we don't use it
+ */
+#define MAX_DMA_CHANNELS	0
+
+#define MAX_DMA_ADDRESS		0xffffffff
+
+#define IOP310_DMA_P0      	0
+#define IOP310_DMA_P1		1
+#define IOP310_DMA_S0      	2
+
+#define DMA_MOD_READ        	0x0001
+#define DMA_MOD_WRITE		0x0002
+#define DMA_MOD_CACHED		0x0004
+#define DMA_MOD_NONCACHED	0x0008
+
+
+#define DMA_DESC_DONE   	0x0010
+#define DMA_INCOMPLETE  	0x0020
+#define DMA_HOLD		0x0040
+#define DMA_END_CHAIN		0x0080
+#define DMA_COMPLETE		0x0100
+#define DMA_NOTIFY		0x0200
+#define DMA_NEW_HEAD		0x0400
+
+#define DMA_USER_MASK	(DMA_NOTIFY | DMA_INCOMPLETE | \
+						 DMA_HOLD | DMA_COMPLETE)
+
+#define DMA_DCR_DAC		0x00000020	/* Dual Addr Cycle Enab */
+#define DMA_DCR_IE		0x00000010	/* Interrupt Enable */
+#define DMA_DCR_PCI_IOR		0x00000002	/* I/O Read */
+#define DMA_DCR_PCI_IOW		0x00000003	/* I/O Write */
+#define DMA_DCR_PCI_MR		0x00000006	/* Memory Read */
+#define DMA_DCR_PCI_MW		0x00000007	/* Memory Write */
+#define DMA_DCR_PCI_CR		0x0000000A	/* Configuration Read */
+#define DMA_DCR_PCI_CW		0x0000000B	/* Configuration Write */
+#define DMA_DCR_PCI_MRM		0x0000000C	/* Memory Read Multiple */
+#define DMA_DCR_PCI_MRL		0x0000000E	/* Memory Read Line */
+#define DMA_DCR_PCI_MWI		0x0000000F	/* Mem Write and Inval */
+
+#define DMA_USER_CMD_IE		0x00000001	/* user request int */
+#define DMA_USER_END_CHAIN	0x00000002	/* end of sgl chain flag */
+
+/* ATU defines */
+#define     IOP310_ATUCR_PRIM_OUT_ENAB  /* Configuration   */      0x00000002
+#define     IOP310_ATUCR_DIR_ADDR_ENAB  /* Configuration   */      0x00000080
+
+
+typedef void (*dma_callback_t) (void *buf_context);
+/*
+ * DMA Descriptor
+ */
+typedef struct _dma_desc
+{
+	u32 NDAR;					/* next descriptor adress */
+	u32 PDAR;					/* PCI address */
+	u32 PUADR;					/* upper PCI address */
+	u32 LADR;					/* local address */
+	u32 BC;						/* byte count */
+	u32 DC;						/* descriptor control */
+} dma_desc_t;
+
+typedef struct _dma_sgl
+{
+	dma_desc_t dma_desc;		/* DMA descriptor pointer */
+	u32 status;					/* descriptor status */
+	void *data;					/* local virt */
+	struct _dma_sgl *next;		/* next descriptor */
+} dma_sgl_t;
+
+/* dma sgl head */
+typedef struct _dma_head
+{
+	u32 total;					/* total elements in SGL */
+	u32 status;					/* status of sgl */
+	u32 mode;					/* read or write mode */
+	dma_sgl_t *list;			/* pointer to list */
+	dma_callback_t callback;	/* callback function */
+} dma_head_t;
+
+/* function prototypes */
+int dma_request(dmach_t, const char *);
+int dma_queue_buffer(dmach_t, dma_head_t *);
+int dma_suspend(dmach_t);
+int dma_resume(dmach_t);
+int dma_flush_all(dmach_t);
+void dma_free(dmach_t);
+void dma_set_irq_threshold(dmach_t, int);
+dma_sgl_t *dma_get_buffer(dmach_t, int);
+void dma_return_buffer(dmach_t, dma_sgl_t *);
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/hardware.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/hardware.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/hardware.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,46 @@
+/*
+ * linux/include/asm-arm/arch-iop80310/hardware.h
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <linux/config.h>
+
+#define PCIO_BASE	0x6e000000
+
+#define pcibios_assign_all_busses() 1
+
+#ifdef CONFIG_ARCH_IOP310
+/*
+ * these are the values for the secondary PCI bus on the 80312 chip.  I will
+ * have to do some fixup in the bus/dev fixup code
+ */ 
+#define PCIBIOS_MIN_IO		0x90010000
+#define PCIBIOS_MIN_MEM		0x88000000
+
+// Generic chipset bits
+#include "iop310.h"
+
+// Board specific
+#if defined(CONFIG_ARCH_IQ80310)
+#include "iq80310.h"
+#endif
+#endif
+
+#ifdef CONFIG_ARCH_IOP321
+
+#define PCIBIOS_MIN_IO		0x90000000
+#define PCIBIOS_MIN_MEM		0x80000000
+
+#include "iop321.h"
+
+#ifdef CONFIG_ARCH_IQ80321
+#include "iq80321.h"
+#endif
+#endif
+
+
+
+
+#endif  /* _ASM_ARCH_HARDWARE_H */
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/ide.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/ide.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/ide.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,51 @@
+/*
+ * include/asm-arm/arch-iop310/ide.h
+ *
+ * Generic IDE functions for IOP310 systems
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * 09/26/2001 - Sharon Baartmans
+ * 	Fixed so it actually works.
+ */
+
+#ifndef _ASM_ARCH_IDE_H_
+#define _ASM_ARCH_IDE_H_
+
+/*
+ * Set up a hw structure for a specified data port, control port and IRQ.
+ * This should follow whatever the default interface uses.
+ */
+static __inline__ void
+ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int *irq)
+{
+	ide_ioreg_t reg;
+	int i;
+	int regincr = 1;
+	
+	memset(hw, 0, sizeof(*hw));
+
+	reg = (ide_ioreg_t)data_port;
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = reg;
+		reg += regincr;
+	}
+	
+	hw->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t) ctrl_port;
+	
+	if (irq) *irq = 0;
+}
+
+/*
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ */
+static __inline__ void ide_init_default_hwifs(void)
+{
+	/* There are no standard ports */
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/io.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/io.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/io.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,100 @@
+/*
+ * linux/include/asm-arm/arch-iop310/io.h
+ *
+ *  Copyright (C) 2001  MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io_pci(a)		(PCIO_BASE + (a))
+#define __mem_pci(a)		((unsigned long)(a))
+#define __mem_isa(a)		((unsigned long)(a))
+
+#define __ioaddr(p)		__io_pci(p)
+#define __io(p)			__io_pci(p)
+
+/*
+ * We have to define our own here b/c XScale has some sideaffects
+ * dealing with data aborts that we have to workaround here.
+ * Basically after each I/O access, we do a NOP to protect
+ * the access from imprecise aborts.  See section 2.3.4.4 of the
+ * XScale developer's manual for more info.
+ *
+ */
+
+/*
+#undef __arch_getb
+#undef __arch_getl
+
+extern __inline__ unsigned char __arch_getb(unsigned long a)
+{
+	unsigned int value;
+	__asm__ __volatile__(
+		"ldr%?b	%0, [%1, #0]	@ getw"
+		"mov	r0, r0"
+		: "=&r" (value) : "r" (a));
+	return (unsigned char)value;
+}
+
+extern __inline__ unsigned int __arch_getl(unsigned long a)
+{
+	unsigned int value;
+	__asm__ __volatile__(
+		"ldr%?	%0, [%1, #0]	@ getw"
+		"mov	r0, r0"
+		: "=&r" (value) : "r" (a));
+	return value;
+}
+*/
+
+extern __inline__ unsigned int __arch_getw(unsigned long a)
+{
+	unsigned int value;
+	__asm__ __volatile__(
+		"ldr%?h	%0, [%1, #0]	@ getw"
+		"mov	r0, r0"
+		: "=&r" (value) : "r" (a));
+	return value;
+}
+
+
+/*
+#undef __arch_putb(v,a)	
+#undef __arch_putl(v,a)	
+
+extern __inline__ void __arch_putb(unsigned int value, unsigned long a)
+{
+	__asm__ __volatile__(
+		"str%?b	%0, [%1, #0]	@ putw"
+		"mov	r0, r0"
+		: : "r" (value), "r" (a));
+}
+
+extern __inline__ void __arch_putl(unsigned int value, unsigned long a)
+{
+	__asm__ __volatile__(
+		"str%?	%0, [%1, #0]	@ putw"
+		"mov	r0, r0"
+		: : "r" (value), "r" (a));
+}
+*/
+
+extern __inline__ void __arch_putw(unsigned int value, unsigned long a)
+{
+	__asm__ __volatile__(
+		"str%?h	%0, [%1, #0]	@ putw"
+		"mov	r0, r0"
+		: : "r" (value), "r" (a));
+}
+
+#define __arch_ioremap		__ioremap
+#define __arch_iounmap		__iounmap
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/iop310.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/iop310.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/iop310.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/iop310.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,247 @@
+/*
+ * linux/include/asm/arch-iop310/iop310.h
+ * 
+ * Intel IOP310 Compainion Chip definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _IOP310_HW_H_
+#define _IOP310_HW_H_
+
+/*
+ * IOP310 I/O and Mem space regions for PCI autoconfiguration
+ */
+#define	IOP310_PCISEC_LOWER_IO		0x90010000
+#define	IOP310_PCISEC_UPPER_IO		0x9001ffff
+#define IOP310_PCISEC_LOWER_MEM		0x88000000
+#define IOP310_PCISEC_UPPER_MEM		0x8bffffff
+
+#define	IOP310_PCIPRI_LOWER_IO		0x90000000
+#define	IOP310_PCIPRI_UPPER_IO		0x9000ffff
+#define IOP310_PCIPRI_LOWER_MEM		0x80000000
+#define IOP310_PCIPRI_UPPER_MEM		0x83ffffff
+
+#define IOP310_PCI_WINDOW_SIZE		64 * 0x100000
+
+/*
+ * IOP310 chipset registers
+ */
+#define IOP310_VIRT_MEM_BASE 0xe8001000  /* chip virtual mem address*/
+#define IOP310_PHY_MEM_BASE  0x00001000  /* chip physical memory address */
+#define IOP310_REG_ADDR(reg) (IOP310_VIRT_MEM_BASE | IOP310_PHY_MEM_BASE | (reg))
+
+/* PCI-to-PCI Bridge Unit 0x00001000 through 0x000010FF */
+#define IOP310_VIDR    (volatile u16 *)IOP310_REG_ADDR(0x00001000)
+#define IOP310_DIDR    (volatile u16 *)IOP310_REG_ADDR(0x00001002)
+#define IOP310_PCR     (volatile u16 *)IOP310_REG_ADDR(0x00001004)
+#define IOP310_PSR     (volatile u16 *)IOP310_REG_ADDR(0x00001006)
+#define IOP310_RIDR    (volatile u8  *)IOP310_REG_ADDR(0x00001008)
+#define IOP310_CCR     (volatile u32 *)IOP310_REG_ADDR(0x00001009)
+#define IOP310_CLSR    (volatile u8  *)IOP310_REG_ADDR(0x0000100C)
+#define IOP310_PLTR    (volatile u8  *)IOP310_REG_ADDR(0x0000100D)
+#define IOP310_HTR     (volatile u8  *)IOP310_REG_ADDR(0x0000100E)
+/* Reserved 0x0000100F through  0x00001017 */
+#define IOP310_PBNR    (volatile u8  *)IOP310_REG_ADDR(0x00001018)
+#define IOP310_SBNR    (volatile u8  *)IOP310_REG_ADDR(0x00001019)
+#define IOP310_SUBBNR  (volatile u8  *)IOP310_REG_ADDR(0x0000101A)
+#define IOP310_SLTR    (volatile u8  *)IOP310_REG_ADDR(0x0000101B)
+#define IOP310_IOBR    (volatile u8  *)IOP310_REG_ADDR(0x0000101C)
+#define IOP310_IOLR    (volatile u8  *)IOP310_REG_ADDR(0x0000101D)
+#define IOP310_SSR     (volatile u16 *)IOP310_REG_ADDR(0x0000101E)
+#define IOP310_MBR     (volatile u16 *)IOP310_REG_ADDR(0x00001020)
+#define IOP310_MLR     (volatile u16 *)IOP310_REG_ADDR(0x00001022)
+#define IOP310_PMBR    (volatile u16 *)IOP310_REG_ADDR(0x00001024)
+#define IOP310_PMLR    (volatile u16 *)IOP310_REG_ADDR(0x00001026)
+/* Reserved 0x00001028 through 0x00001033 */
+#define IOP310_CAPR    (volatile u8  *)IOP310_REG_ADDR(0x00001034)
+/* Reserved 0x00001035 through 0x0000103D */
+#define IOP310_BCR     (volatile u16 *)IOP310_REG_ADDR(0x0000103E)
+#define IOP310_EBCR    (volatile u16 *)IOP310_REG_ADDR(0x00001040)
+#define IOP310_SISR    (volatile u16 *)IOP310_REG_ADDR(0x00001042)
+#define IOP310_PBISR   (volatile u32 *)IOP310_REG_ADDR(0x00001044)
+#define IOP310_SBISR   (volatile u32 *)IOP310_REG_ADDR(0x00001048)
+#define IOP310_SACR    (volatile u32 *)IOP310_REG_ADDR(0x0000104C)
+#define IOP310_PIRSR   (volatile u32 *)IOP310_REG_ADDR(0x00001050)
+#define IOP310_SIOBR   (volatile u8  *)IOP310_REG_ADDR(0x00001054)
+#define IOP310_SIOLR   (volatile u8  *)IOP310_REG_ADDR(0x00001055)
+#define IOP310_SCDR    (volatile u8  *)IOP310_REG_ADDR(0x00001056) 
+
+#define IOP310_SMBR    (volatile u16 *)IOP310_REG_ADDR(0x00001058)
+#define IOP310_SMLR    (volatile u16 *)IOP310_REG_ADDR(0x0000105A)
+#define IOP310_SDER    (volatile u16 *)IOP310_REG_ADDR(0x0000105C)
+#define IOP310_QCR     (volatile u16 *)IOP310_REG_ADDR(0x0000105E)
+#define IOP310_CAPID   (volatile u8  *)IOP310_REG_ADDR(0x00001068)
+#define IOP310_NIPTR   (volatile u8  *)IOP310_REG_ADDR(0x00001069)
+#define IOP310_PMCR    (volatile u16 *)IOP310_REG_ADDR(0x0000106A)
+#define IOP310_PMCSR   (volatile u16 *)IOP310_REG_ADDR(0x0000106C)
+#define IOP310_PMCSRBSE (volatile u8 *)IOP310_REG_ADDR(0x0000106E)
+/* Reserved 0x00001064 through 0x000010FFH */
+
+/* Performance monitoring unit  0x00001100 through 0x000011FF*/
+#define IOP310_PMONGTMR    (volatile u32 *)IOP310_REG_ADDR(0x00001100)
+#define IOP310_PMONESR     (volatile u32 *)IOP310_REG_ADDR(0x00001104)
+#define IOP310_PMONEMISR   (volatile u32 *)IOP310_REG_ADDR(0x00001108)
+#define IOP310_PMONGTSR    (volatile u32 *)IOP310_REG_ADDR(0x00001110)
+#define IOP310_PMONPECR1   (volatile u32 *)IOP310_REG_ADDR(0x00001114)
+#define IOP310_PMONPECR2   (volatile u32 *)IOP310_REG_ADDR(0x00001118)
+#define IOP310_PMONPECR3   (volatile u32 *)IOP310_REG_ADDR(0x0000111C)
+#define IOP310_PMONPECR4   (volatile u32 *)IOP310_REG_ADDR(0x00001120)
+#define IOP310_PMONPECR5   (volatile u32 *)IOP310_REG_ADDR(0x00001124)
+#define IOP310_PMONPECR6   (volatile u32 *)IOP310_REG_ADDR(0x00001128)
+#define IOP310_PMONPECR7   (volatile u32 *)IOP310_REG_ADDR(0x0000112C)
+#define IOP310_PMONPECR8   (volatile u32 *)IOP310_REG_ADDR(0x00001130)
+#define IOP310_PMONPECR9   (volatile u32 *)IOP310_REG_ADDR(0x00001134)
+#define IOP310_PMONPECR10  (volatile u32 *)IOP310_REG_ADDR(0x00001138)
+#define IOP310_PMONPECR11  (volatile u32 *)IOP310_REG_ADDR(0x0000113C)
+#define IOP310_PMONPECR12  (volatile u32 *)IOP310_REG_ADDR(0x00001140)
+#define IOP310_PMONPECR13  (volatile u32 *)IOP310_REG_ADDR(0x00001144)
+#define IOP310_PMONPECR14  (volatile u32 *)IOP310_REG_ADDR(0x00001148)
+
+/* Address Translation Unit 0x00001200 through 0x000012FF */
+#define IOP310_ATUVID     (volatile u16 *)IOP310_REG_ADDR(0x00001200)
+#define IOP310_ATUDID     (volatile u16 *)IOP310_REG_ADDR(0x00001202)
+#define IOP310_PATUCMD    (volatile u16 *)IOP310_REG_ADDR(0x00001204)
+#define IOP310_PATUSR     (volatile u16 *)IOP310_REG_ADDR(0x00001206)
+#define IOP310_ATURID     (volatile u8  *)IOP310_REG_ADDR(0x00001208)
+#define IOP310_ATUCCR     (volatile u32 *)IOP310_REG_ADDR(0x00001209)
+#define IOP310_ATUCLSR    (volatile u8  *)IOP310_REG_ADDR(0x0000120C)
+#define IOP310_ATULT      (volatile u8  *)IOP310_REG_ADDR(0x0000120D)
+#define IOP310_ATUHTR     (volatile u8  *)IOP310_REG_ADDR(0x0000120E)
+
+#define IOP310_PIABAR     (volatile u32 *)IOP310_REG_ADDR(0x00001210)
+/* Reserved 0x00001214 through 0x0000122B */
+#define IOP310_ASVIR      (volatile u16 *)IOP310_REG_ADDR(0x0000122C)
+#define IOP310_ASIR       (volatile u16 *)IOP310_REG_ADDR(0x0000122E)
+#define IOP310_ERBAR      (volatile u32 *)IOP310_REG_ADDR(0x00001230)
+#define IOP310_ATUCAPPTR  (volatile u8  *)IOP310_REG_ADDR(0x00001234)
+/* Reserved 0x00001235 through 0x0000123B */
+#define IOP310_ATUILR     (volatile u8  *)IOP310_REG_ADDR(0x0000123C)
+#define IOP310_ATUIPR     (volatile u8  *)IOP310_REG_ADDR(0x0000123D)
+#define IOP310_ATUMGNT    (volatile u8  *)IOP310_REG_ADDR(0x0000123E)
+#define IOP310_ATUMLAT    (volatile u8  *)IOP310_REG_ADDR(0x0000123F)
+#define IOP310_PIALR      (volatile u32 *)IOP310_REG_ADDR(0x00001240)
+#define IOP310_PIATVR     (volatile u32 *)IOP310_REG_ADDR(0x00001244)
+#define IOP310_SIABAR     (volatile u32 *)IOP310_REG_ADDR(0x00001248)
+#define IOP310_SIALR      (volatile u32 *)IOP310_REG_ADDR(0x0000124C)
+#define IOP310_SIATVR     (volatile u32 *)IOP310_REG_ADDR(0x00001250)
+#define IOP310_POMWVR     (volatile u32 *)IOP310_REG_ADDR(0x00001254)
+/* Reserved 0x00001258 through 0x0000125B */
+#define IOP310_POIOWVR    (volatile u32 *)IOP310_REG_ADDR(0x0000125C)
+#define IOP310_PODWVR     (volatile u32 *)IOP310_REG_ADDR(0x00001260)
+#define IOP310_POUDR      (volatile u32 *)IOP310_REG_ADDR(0x00001264)
+#define IOP310_SOMWVR     (volatile u32 *)IOP310_REG_ADDR(0x00001268)
+#define IOP310_SOIOWVR    (volatile u32 *)IOP310_REG_ADDR(0x0000126C)
+/* Reserved 0x00001270 through 0x00001273*/
+#define IOP310_ERLR       (volatile u32 *)IOP310_REG_ADDR(0x00001274)
+#define IOP310_ERTVR      (volatile u32 *)IOP310_REG_ADDR(0x00001278)
+/* Reserved 0x00001279 through 0x0000127C*/
+#define IOP310_ATUCAPID   (volatile u8  *)IOP310_REG_ADDR(0x00001280)
+#define IOP310_ATUNIPTR   (volatile u8  *)IOP310_REG_ADDR(0x00001281)
+#define IOP310_APMCR      (volatile u16 *)IOP310_REG_ADDR(0x00001282)
+#define IOP310_APMCSR     (volatile u16 *)IOP310_REG_ADDR(0x00001284)
+/* Reserved 0x00001286 through 0x00001287 */
+#define IOP310_ATUCR      (volatile u32 *)IOP310_REG_ADDR(0x00001288)
+/* Reserved 0x00001289  through 0x0000128C*/
+#define IOP310_PATUISR    (volatile u32 *)IOP310_REG_ADDR(0x00001290)
+#define IOP310_SATUISR    (volatile u32 *)IOP310_REG_ADDR(0x00001294)
+#define IOP310_SATUCMD    (volatile u16 *)IOP310_REG_ADDR(0x00001298)
+#define IOP310_SATUSR     (volatile u16 *)IOP310_REG_ADDR(0x0000129A)
+#define IOP310_SODWVR     (volatile u32 *)IOP310_REG_ADDR(0x0000129C)
+#define IOP310_SOUDR      (volatile u32 *)IOP310_REG_ADDR(0x000012A0)
+#define IOP310_POCCAR     (volatile u32 *)IOP310_REG_ADDR(0x000012A4)
+#define IOP310_SOCCAR     (volatile u32 *)IOP310_REG_ADDR(0x000012A8)
+#define IOP310_POCCDR     (volatile u32 *)IOP310_REG_ADDR(0x000012AC)
+#define IOP310_SOCCDR     (volatile u32 *)IOP310_REG_ADDR(0x000012B0)
+#define IOP310_PAQCR      (volatile u32 *)IOP310_REG_ADDR(0x000012B4)
+#define IOP310_SAQCR      (volatile u32 *)IOP310_REG_ADDR(0x000012B8)
+#define IOP310_PATUIMR    (volatile u32 *)IOP310_REG_ADDR(0x000012BC)
+#define IOP310_SATUIMR    (volatile u32 *)IOP310_REG_ADDR(0x000012C0)
+/* Reserved 0x000012C4 through 0x000012FF */
+/* Messaging Unit 0x00001300 through 0x000013FF */
+#define IOP310_MUIMR0       (volatile u32 *)IOP310_REG_ADDR(0x00001310)
+#define IOP310_MUIMR1       (volatile u32 *)IOP310_REG_ADDR(0x00001314)
+#define IOP310_MUOMR0       (volatile u32 *)IOP310_REG_ADDR(0x00001318)
+#define IOP310_MUOMR1       (volatile u32 *)IOP310_REG_ADDR(0x0000131C)
+#define IOP310_MUIDR        (volatile u32 *)IOP310_REG_ADDR(0x00001320)
+#define IOP310_MUIISR       (volatile u32 *)IOP310_REG_ADDR(0x00001324)
+#define IOP310_MUIIMR       (volatile u32 *)IOP310_REG_ADDR(0x00001328)
+#define IOP310_MUODR        (volatile u32 *)IOP310_REG_ADDR(0x0000132C)
+#define IOP310_MUOISR       (volatile u32 *)IOP310_REG_ADDR(0x00001330)
+#define IOP310_MUOIMR       (volatile u32 *)IOP310_REG_ADDR(0x00001334)
+#define IOP310_MUMUCR       (volatile u32 *)IOP310_REG_ADDR(0x00001350)
+#define IOP310_MUQBAR       (volatile u32 *)IOP310_REG_ADDR(0x00001354)
+#define IOP310_MUIFHPR      (volatile u32 *)IOP310_REG_ADDR(0x00001360)
+#define IOP310_MUIFTPR      (volatile u32 *)IOP310_REG_ADDR(0x00001364)
+#define IOP310_MUIPHPR      (volatile u32 *)IOP310_REG_ADDR(0x00001368)
+#define IOP310_MUIPTPR      (volatile u32 *)IOP310_REG_ADDR(0x0000136C)
+#define IOP310_MUOFHPR      (volatile u32 *)IOP310_REG_ADDR(0x00001370)
+#define IOP310_MUOFTPR      (volatile u32 *)IOP310_REG_ADDR(0x00001374)
+#define IOP310_MUOPHPR      (volatile u32 *)IOP310_REG_ADDR(0x00001378)
+#define IOP310_MUOPTPR      (volatile u32 *)IOP310_REG_ADDR(0x0000137C)
+#define IOP310_MUIAR        (volatile u32 *)IOP310_REG_ADDR(0x00001380)
+/* DMA Controller 0x00001400 through 0x000014FF */
+#define IOP310_DMA0CCR     (volatile u32 *)IOP310_REG_ADDR(0x00001400)
+#define IOP310_DMA0CSR     (volatile u32 *)IOP310_REG_ADDR(0x00001404)
+/* Reserved 0x001408 through 0x00140B */
+#define IOP310_DMA0DAR     (volatile u32 *)IOP310_REG_ADDR(0x0000140C)
+#define IOP310_DMA0NDAR    (volatile u32 *)IOP310_REG_ADDR(0x00001410)
+#define IOP310_DMA0PADR    (volatile u32 *)IOP310_REG_ADDR(0x00001414)
+#define IOP310_DMA0PUADR   (volatile u32 *)IOP310_REG_ADDR(0x00001418)
+#define IOP310_DMA0LADR    (volatile u32 *)IOP310_REG_ADDR(0x0000141C)
+#define IOP310_DMA0BCR     (volatile u32 *)IOP310_REG_ADDR(0x00001420)
+#define IOP310_DMA0DCR     (volatile u32 *)IOP310_REG_ADDR(0x00001424)
+/* Reserved 0x00001428 through 0x0000143F */
+#define IOP310_DMA1CCR     (volatile u32 *)IOP310_REG_ADDR(0x00001440)
+#define IOP310_DMA1CSR     (volatile u32 *)IOP310_REG_ADDR(0x00001444)
+/* Reserved 0x00001448 through 0x0000144B */
+#define IOP310_DMA1DAR     (volatile u32 *)IOP310_REG_ADDR(0x0000144C)
+#define IOP310_DMA1NDAR    (volatile u32 *)IOP310_REG_ADDR(0x00001450)
+#define IOP310_DMA1PADR    (volatile u32 *)IOP310_REG_ADDR(0x00001454)
+#define IOP310_DMA1PUADR   (volatile u32 *)IOP310_REG_ADDR(0x00001458)
+#define IOP310_DMA1LADR    (volatile u32 *)IOP310_REG_ADDR(0x0000145C)
+#define IOP310_DMA1BCR     (volatile u32 *)IOP310_REG_ADDR(0x00001460)
+#define IOP310_DMA1DCR     (volatile u32 *)IOP310_REG_ADDR(0x00001464)
+/* Reserved 0x00001468 through 0x0000147F */
+#define IOP310_DMA2CCR     (volatile u32 *)IOP310_REG_ADDR(0x00001480)
+#define IOP310_DMA2CSR     (volatile u32 *)IOP310_REG_ADDR(0x00001484)
+/* Reserved 0x00001488 through 0x0000148B */
+#define IOP310_DMA2DAR     (volatile u32 *)IOP310_REG_ADDR(0x0000148C)
+#define IOP310_DMA2NDAR    (volatile u32 *)IOP310_REG_ADDR(0x00001490)
+#define IOP310_DMA2PADR    (volatile u32 *)IOP310_REG_ADDR(0x00001494)
+#define IOP310_DMA2PUADR   (volatile u32 *)IOP310_REG_ADDR(0x00001498)
+#define IOP310_DMA2LADR    (volatile u32 *)IOP310_REG_ADDR(0x0000149C)
+#define IOP310_DMA2BCR     (volatile u32 *)IOP310_REG_ADDR(0x000014A0)
+#define IOP310_DMA2DCR     (volatile u32 *)IOP310_REG_ADDR(0x000014A4)
+
+/* Memory controller 0x00001500 through 0x0015FF */
+
+/* core interface unit 0x00001640 - 0x0000167F */
+#define IOP310_CIUISR     (volatile u32 *)IOP310_REG_ADDR(0x00001644)
+
+/* PCI and Peripheral Interrupt Controller 0x00001700 - 0x0000171B */
+#define IOP310_IRQISR     (volatile u32 *)IOP310_REG_ADDR(0x00001700)
+#define IOP310_FIQ2ISR    (volatile u32 *)IOP310_REG_ADDR(0x00001704)
+#define IOP310_FIQ1ISR    (volatile u32 *)IOP310_REG_ADDR(0x00001708)
+#define IOP310_PDIDR      (volatile u32 *)IOP310_REG_ADDR(0x00001710)
+
+/* AAU registers. DJ 0x00001800 - 0x00001838 */
+#define IOP310_AAUACR    (volatile u32 *)IOP310_REG_ADDR(0x00001800)
+#define IOP310_AAUASR    (volatile u32 *)IOP310_REG_ADDR(0x00001804)
+#define IOP310_AAUADAR   (volatile u32 *)IOP310_REG_ADDR(0x00001808)
+#define IOP310_AAUANDAR  (volatile u32 *)IOP310_REG_ADDR(0x0000180C)
+#define IOP310_AAUSAR1   (volatile u32 *)IOP310_REG_ADDR(0x00001810)
+#define IOP310_AAUSAR2   (volatile u32 *)IOP310_REG_ADDR(0x00001814)
+#define IOP310_AAUSAR3   (volatile u32 *)IOP310_REG_ADDR(0x00001818)
+#define IOP310_AAUSAR4   (volatile u32 *)IOP310_REG_ADDR(0x0000181C)
+#define IOP310_AAUDAR    (volatile u32 *)IOP310_REG_ADDR(0x00001820)
+#define IOP310_AAUABCR   (volatile u32 *)IOP310_REG_ADDR(0x00001824)
+#define IOP310_AAUADCR   (volatile u32 *)IOP310_REG_ADDR(0x00001828)
+#define IOP310_AAUSAR5   (volatile u32 *)IOP310_REG_ADDR(0x0000182C)
+#define IOP310_AAUSAR6   (volatile u32 *)IOP310_REG_ADDR(0x00001830)
+#define IOP310_AAUSAR7   (volatile u32 *)IOP310_REG_ADDR(0x00001834)
+#define IOP310_AAUSAR8   (volatile u32 *)IOP310_REG_ADDR(0x00001838)
+
+#endif // _IOP310_HW_H_
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/iop310-irqs.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/iop310-irqs.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/iop310-irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/iop310-irqs.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,80 @@
+/*
+ * linux/include/asm-arm/arch-iop310/irqs.h
+ *
+ * Author:	Nicolas Pitre
+ * Copyright:	(C) 2001 MontaVista Software Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 06/13/01: Added 80310 on-chip interrupt sources <dsaxena@mvista.com>
+ *
+ */
+
+
+/*
+ * XS80200 specific IRQs
+ */
+#define IRQ_XS80200_BCU		0	/* Bus Control Unit */
+#define IRQ_XS80200_PMU		1	/* Performance Monitoring Unit */
+#define IRQ_XS80200_EXTIRQ	2	/* external IRQ signal */
+#define IRQ_XS80200_EXTFIQ	3	/* external IRQ signal */
+
+#define NR_XS80200_IRQS		4
+
+#define XSCALE_PMU_IRQ		IRQ_XS80200_PMU
+
+/*
+ * IOP80310 chipset interrupts
+ */
+#define IOP310_IRQ_OFS		NR_XS80200_IRQS
+#define IOP310_IRQ(x)		(IOP310_IRQ_OFS + (x))
+
+/*
+ * On FIQ1ISR register
+ */
+#define IRQ_IOP310_DMA0		IOP310_IRQ(0)	/* DMA Channel 0 */
+#define IRQ_IOP310_DMA1		IOP310_IRQ(1)	/* DMA Channel 1 */
+#define IRQ_IOP310_DMA2		IOP310_IRQ(2)	/* DMA Channel 2 */
+#define IRQ_IOP310_PMON		IOP310_IRQ(3)	/* Bus performance Unit */
+#define IRQ_IOP310_AAU		IOP310_IRQ(4)	/* Application Accelator Unit */
+
+/*
+ * On FIQ2ISR register
+ */
+#define IRQ_IOP310_I2C		IOP310_IRQ(5)	/* I2C unit */
+#define IRQ_IOP310_MU		IOP310_IRQ(6)	/* messaging unit */
+
+#define NR_IOP310_IRQS		(IOP310_IRQ(6) + 1)
+
+#define NR_IRQS			NR_IOP310_IRQS
+
+
+/* 
+ * Interrupts available on the Cyclone IQ80310 board 
+ */
+#ifdef CONFIG_ARCH_IQ80310
+
+#define IQ80310_IRQ_OFS		NR_IOP310_IRQS
+#define IQ80310_IRQ(y)		((IQ80310_IRQ_OFS) + (y))
+
+#define IRQ_IQ80310_TIMER	IQ80310_IRQ(0)	/* Timer Interrupt */
+#define IRQ_IQ80310_I82559	IQ80310_IRQ(1)	/* I82559 Ethernet Interrupt */
+#define IRQ_IQ80310_UART1	IQ80310_IRQ(2)	/* UART1 Interrupt */
+#define IRQ_IQ80310_UART2	IQ80310_IRQ(3)	/* UART2 Interrupt */
+#define IRQ_IQ80310_INTD	IQ80310_IRQ(4)	/* PCI INTD */
+
+
+/*
+ * ONLY AVAILABLE ON REV F OR NEWER BOARDS!
+ */
+#define	IRQ_IQ80310_INTA	IQ80310_IRQ(5)	/* PCI INTA */
+#define	IRQ_IQ80310_INTB	IQ80310_IRQ(6)	/* PCI INTB */
+#define	IRQ_IQ80310_INTC	IQ80310_IRQ(7)	/* PCI INTC */
+
+#undef	NR_IRQS
+#define NR_IRQS			(IQ80310_IRQ(7) + 1)
+
+#endif // CONFIG_ARCH_IQ80310
+
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/iop321.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/iop321.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/iop321.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/iop321.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,153 @@
+/*
+ * linux/include/asm/arch-iop3xx/iop321.h
+ * 
+ * Intel IOP321 Chip definitions
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _IOP321_HW_H_
+#define _IOP321_HW_H_
+
+/*
+ * IOP321 I/O and Mem space regions for PCI autoconfiguration
+ */
+#define	IOP321_PCI_LOWER_IO		0x90000000
+#define	IOP321_PCI_UPPER_IO		0x9000ffff
+#define IOP321_PCI_LOWER_MEM		0x80000000
+#define IOP321_PCI_UPPER_MEM		0x83ffffff
+
+#define IOP321_PCI_WINDOW_SIZE		64 * 0x100000
+
+/*
+ * IOP321 chipset registers
+ */
+#define IOP321_VIRT_MEM_BASE 0xfff00000  /* chip virtual mem address*/
+#define IOP321_PHY_MEM_BASE  0xffffe000  /* chip physical memory address */
+#define IOP321_REG_ADDR(reg) (IOP321_VIRT_MEM_BASE | (reg))
+
+/* Reserved 0x00000000 through 0x000000FF */
+
+/* Address Translation Unit 0x00000100 through 0x000001FF */
+#define IOP321_ATUVID     (volatile u16 *)IOP321_REG_ADDR(0x00000100)
+#define IOP321_ATUDID     (volatile u16 *)IOP321_REG_ADDR(0x00000102)
+#define IOP321_ATUCMD     (volatile u16 *)IOP321_REG_ADDR(0x00000104)
+#define IOP321_ATUSR      (volatile u16 *)IOP321_REG_ADDR(0x00000106)
+#define IOP321_ATURID     (volatile u8  *)IOP321_REG_ADDR(0x00000108)
+#define IOP321_ATUCCR     (volatile u32 *)IOP321_REG_ADDR(0x00000109)
+#define IOP321_ATUCLSR    (volatile u8  *)IOP321_REG_ADDR(0x0000010C)
+#define IOP321_ATULT      (volatile u8  *)IOP321_REG_ADDR(0x0000010D)
+#define IOP321_ATUHTR     (volatile u8  *)IOP321_REG_ADDR(0x0000010E)
+#define IOP321_ATUBIST    (volatile u8  *)IOP321_REG_ADDR(0x0000010F)
+#define IOP321_IABAR0     (volatile u32 *)IOP321_REG_ADDR(0x00000110)
+#define IOP321_IAUBAR0    (volatile u32 *)IOP321_REG_ADDR(0x00000114)
+#define IOP321_IABAR1     (volatile u32 *)IOP321_REG_ADDR(0x00000118)
+#define IOP321_IAUBAR1    (volatile u32 *)IOP321_REG_ADDR(0x0000011C)
+#define IOP321_IABAR2     (volatile u32 *)IOP321_REG_ADDR(0x00000120)
+#define IOP321_IAUBAR2    (volatile u32 *)IOP321_REG_ADDR(0x00000124)
+#define IOP321_ASVIR      (volatile u16 *)IOP321_REG_ADDR(0x0000012C)
+#define IOP321_ASIR       (volatile u16 *)IOP321_REG_ADDR(0x0000012E)
+#define IOP321_ERBAR      (volatile u32 *)IOP321_REG_ADDR(0x00000130)
+/* Reserved 0x00000134 through 0x0000013B */
+#define IOP321_ATUILR     (volatile u8  *)IOP321_REG_ADDR(0x0000013C)
+#define IOP321_ATUIPR     (volatile u8  *)IOP321_REG_ADDR(0x0000013D)
+#define IOP321_ATUMGNT    (volatile u8  *)IOP321_REG_ADDR(0x0000013E)
+#define IOP321_ATUMLAT    (volatile u8  *)IOP321_REG_ADDR(0x0000013F)
+#define IOP321_IALR0      (volatile u32 *)IOP321_REG_ADDR(0x00000140)
+#define IOP321_IATVR0     (volatile u32 *)IOP321_REG_ADDR(0x00000144)
+#define IOP321_ERLR       (volatile u32 *)IOP321_REG_ADDR(0x00000148)
+#define IOP321_ERTVR      (volatile u32 *)IOP321_REG_ADDR(0x0000014C)
+#define IOP321_IALR1      (volatile u32 *)IOP321_REG_ADDR(0x00000150)
+#define IOP321_IALR2      (volatile u32 *)IOP321_REG_ADDR(0x00000154)
+#define IOP321_IATVR2     (volatile u32 *)IOP321_REG_ADDR(0x00000158)
+#define IOP321_OIOWTVR    (volatile u32 *)IOP321_REG_ADDR(0x0000015C)
+#define IOP321_OMWTVR0    (volatile u32 *)IOP321_REG_ADDR(0x00000160)
+#define IOP321_OUMWTVR0   (volatile u32 *)IOP321_REG_ADDR(0x00000164)
+#define IOP321_OMWTVR1    (volatile u32 *)IOP321_REG_ADDR(0x00000168)
+#define IOP321_OUMWTVR1   (volatile u32 *)IOP321_REG_ADDR(0x0000016C)
+/* Reserved 0x00000170 through 0x00000177*/
+#define IOP321_OUDWTVR    (volatile u32 *)IOP321_REG_ADDR(0x00000178)
+/* Reserved 0x0000017C through 0x0000017F*/
+#define IOP321_ATUCR      (volatile u32 *)IOP321_REG_ADDR(0x00000180)
+#define IOP321_PCSR       (volatile u32 *)IOP321_REG_ADDR(0x00000184)
+#define IOP321_ATUISR     (volatile u32 *)IOP321_REG_ADDR(0x00000188)
+#define IOP321_ATUIMR     (volatile u32 *)IOP321_REG_ADDR(0x0000018C)
+#define IOP321_IABAR3     (volatile u32 *)IOP321_REG_ADDR(0x00000190)
+#define IOP321_IAUBAR3    (volatile u32 *)IOP321_REG_ADDR(0x00000194)
+#define IOP321_IALR3      (volatile u32 *)IOP321_REG_ADDR(0x00000198)
+#define IOP321_IATVR3     (volatile u32 *)IOP321_REG_ADDR(0x0000019C)
+/* Reserved 0x000001A0 through 0x000001A3*/
+#define IOP321_OCCAR      (volatile u32 *)IOP321_REG_ADDR(0x000001A4)
+/* Reserved 0x000001A8 through 0x000001AB*/
+#define IOP321_OCCDR      (volatile u32 *)IOP321_REG_ADDR(0x000001AC)
+/* Reserved 0x000001B0 through 0x000001BB*/
+#define IOP321_PDSCR      (volatile u32 *)IOP321_REG_ADDR(0x000001BC)
+#define IOP321_PMCAPID    (volatile u8  *)IOP321_REG_ADDR(0x000001C0)
+#define IOP321_PMNEXT     (volatile u8  *)IOP321_REG_ADDR(0x000001C1)
+#define IOP321_APMCR      (volatile u16 *)IOP321_REG_ADDR(0x000001C2)
+#define IOP321_APMCSR     (volatile u16 *)IOP321_REG_ADDR(0x000001C4)
+/* Reserved 0x000001C6 through 0x000001DF */
+#define IOP321_PCIXCAPID  (volatile u8  *)IOP321_REG_ADDR(0x000001E0)
+#define IOP321_PCIXNEXT   (volatile u8  *)IOP321_REG_ADDR(0x000001E1)
+#define IOP321_PCIXCMD    (volatile u16 *)IOP321_REG_ADDR(0x000001E2)
+#define IOP321_PCIXSR     (volatile u32 *)IOP321_REG_ADDR(0x000001E4)
+#define IOP321_PCIIRSR    (volatile u32 *)IOP321_REG_ADDR(0x000001EC)
+
+/* Messaging Unit 0x00000300 through 0x000003FF */
+/* DMA Controller 0x00000400 through 0x000004FF */
+/* Memory controller 0x00000500 through 0x0005FF */
+/* Peripheral bus interface unit 0x00000680 through 0x0006FF */
+/* Peripheral performance monitoring unit 0x00000700 through 0x00077F */
+/* Internal arbitration unit 0x00000780 through 0x0007BF */
+
+/* Interrupt Controller */
+#define IOP321_INTCTL     (volatile u32 *)IOP321_REG_ADDR(0x000007D0)
+#define IOP321_INTSTR     (volatile u32 *)IOP321_REG_ADDR(0x000007D4)
+#define IOP321_IINTSRC    (volatile u32 *)IOP321_REG_ADDR(0x000007D8)
+#define IOP321_FINTSRC    (volatile u32 *)IOP321_REG_ADDR(0x000007DC)
+
+/* Timers */
+
+#define IOP321_TU_TMR0		(volatile u32 *)IOP321_REG_ADDR(0x000007E0)
+#define IOP321_TU_TMR1		(volatile u32 *)IOP321_REG_ADDR(0x000007E4)
+
+#define IOP321_TMR_TC		0x01
+#define	IOP321_TMR_EN		0x02
+#define IOP321_TMR_RELOAD	0x04
+#define	IOP321_TMR_PRIVILEGED	0x09
+
+#define	IOP321_TMR_RATIO_1_1	0x00
+#define	IOP321_TMR_RATIO_4_1	0x10
+#define	IOP321_TMR_RATIO_8_1	0x20
+#define	IOP321_TMR_RATIO_16_1	0x30
+
+#define IOP321_TU_TCR0    (volatile u32 *)IOP321_REG_ADDR(0x000007E8)
+#define IOP321_TU_TCR1    (volatile u32 *)IOP321_REG_ADDR(0x000007EC)
+#define IOP321_TU_TRR0    (volatile u32 *)IOP321_REG_ADDR(0x000007F0)
+#define IOP321_TU_TRR1    (volatile u32 *)IOP321_REG_ADDR(0x000007F4)
+#define IOP321_TU_TISR    (volatile u32 *)IOP321_REG_ADDR(0x000007F8)
+#define IOP321_TU_WDTCR   (volatile u32 *)IOP321_REG_ADDR(0x000007FC)
+
+#ifndef __ASSEMBLY__
+#define intctl_read(val) asm volatile("mrc p6,0,%0,c0,c0,0":"=r" (val))
+#define _intctl_write(val) asm volatile("mcr p6,0,%0,c0,c0,0"::"r" (val))
+#define intstr_read(val) asm volatile("mrc p6,0,%0,c4,c0,0":"=r" (val))
+#define _intstr_write(val) asm volatile("mcr p6,0,%0,c4,c0,0"::"r" (val))
+
+static inline void intctl_write(u32 val) { _intctl_write(val); }
+static inline void intstr_write(u32 val) { _intstr_write(val); }
+#endif
+
+/* Application accelerator unit 0x00000800 - 0x000008FF */
+#define IOP321_AAUACR     (volatile u32 *)IOP321_REG_ADDR(0x00000800)
+#define IOP321_AAUASR     (volatile u32 *)IOP321_REG_ADDR(0x00000804)
+#define IOP321_AAUANDAR   (volatile u32 *)IOP321_REG_ADDR(0x0000080C)
+
+/* SSP serial port unit 0x00001600 - 0x0000167F */
+/* I2C bus interface unit 0x00001680 - 0x000016FF */
+#endif // _IOP321_HW_H_
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/iop321-irqs.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/iop321-irqs.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/iop321-irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/iop321-irqs.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,83 @@
+/*
+ * linux/include/asm-arm/arch-iop3xx/irqs.h
+ *
+ * Author:	Rory Bolt <rorybolt@pacbell.net>
+ * Copyright:	(C) 2002 Rory Bolt
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+
+/*
+ * IOP80321 chipset interrupts
+ */
+#define IOP321_IRQ_OFS		0
+#define IOP321_IRQ(x)		(IOP321_IRQ_OFS + (x))
+
+/*
+ * On IRQ or FIQ register
+ */
+#define IRQ_IOP321_DMA0_EOT	IOP321_IRQ(0)
+#define IRQ_IOP321_DMA0_EOC	IOP321_IRQ(1)
+#define IRQ_IOP321_DMA1_EOT	IOP321_IRQ(2)
+#define IRQ_IOP321_DMA1_EOC	IOP321_IRQ(3)
+#define IRQ_IOP321_RSVD_4	IOP321_IRQ(4)
+#define IRQ_IOP321_RSVD_5	IOP321_IRQ(5)
+#define IRQ_IOP321_AA_EOT	IOP321_IRQ(6)
+#define IRQ_IOP321_AA_EOC	IOP321_IRQ(7)
+#define IRQ_IOP321_CORE_PMON	IOP321_IRQ(8)
+#define IRQ_IOP321_TIMER0	IOP321_IRQ(9)
+#define IRQ_IOP321_TIMER1	IOP321_IRQ(10)
+#define IRQ_IOP321_I2C_0	IOP321_IRQ(11)
+#define IRQ_IOP321_I2C_1	IOP321_IRQ(12)
+#define IRQ_IOP321_MESSAGING	IOP321_IRQ(13)
+#define IRQ_IOP321_ATU_BIST	IOP321_IRQ(14)
+#define IRQ_IOP321_PERFMON	IOP321_IRQ(15)
+#define IRQ_IOP321_CORE_PMU	IOP321_IRQ(16)
+#define IRQ_IOP321_BIU_ERR	IOP321_IRQ(17)
+#define IRQ_IOP321_ATU_ERR	IOP321_IRQ(18)
+#define IRQ_IOP321_MCU_ERR	IOP321_IRQ(19)
+#define IRQ_IOP321_DMA0_ERR	IOP321_IRQ(20)
+#define IRQ_IOP321_DMA1_ERR	IOP321_IRQ(21)
+#define IRQ_IOP321_RSVD_22	IOP321_IRQ(22)
+#define IRQ_IOP321_AA_ERR	IOP321_IRQ(23)
+#define IRQ_IOP321_MSG_ERR	IOP321_IRQ(24)
+#define IRQ_IOP321_SSP		IOP321_IRQ(25)
+#define IRQ_IOP321_RSVD_26	IOP321_IRQ(26)
+#define IRQ_IOP321_XINT0	IOP321_IRQ(27)
+#define IRQ_IOP321_XINT1	IOP321_IRQ(28)
+#define IRQ_IOP321_XINT2	IOP321_IRQ(29)
+#define IRQ_IOP321_XINT3	IOP321_IRQ(30)
+#define IRQ_IOP321_HPI		IOP321_IRQ(31)
+
+#define NR_IOP321_IRQS		(IOP321_IRQ(31) + 1)
+
+#define NR_IRQS			NR_IOP321_IRQS
+
+
+/* 
+ * Interrupts available on the IQ80321 board 
+ */
+#ifdef CONFIG_ARCH_IQ80321
+
+/*
+ * On board devices
+ */
+#define	IRQ_IQ80321_I82544	IRQ_IOP321_XINT0
+#define IRQ_IQ80321_UART	IRQ_IOP321_XINT1
+
+/*
+ * PCI interrupts
+ */
+#define	IRQ_IQ80321_INTA	IRQ_IOP321_XINT0
+#define	IRQ_IQ80321_INTB	IRQ_IOP321_XINT1
+#define	IRQ_IQ80321_INTC	IRQ_IOP321_XINT2
+#define	IRQ_IQ80321_INTD	IRQ_IOP321_XINT3
+
+#endif // CONFIG_ARCH_IQ80321
+
+#define XSCALE_PMU_IRQ	IRQ_IOP321_CORE_PMU
+
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/iq80310.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/iq80310.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/iq80310.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/iq80310.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ * linux/include/asm/arch-iop80310/iq80310.h
+ * 
+ * Intel IQ-80310 evaluation board registers
+ */
+
+#ifndef _IQ80310_H_
+#define _IQ80310_H_
+
+#define IQ80310_RAMBASE      0xa0000000
+#define IQ80310_UART1        0xfe800000    /* UART #1 */
+#define IQ80310_UART2        0xfe810000    /* UART #2 */
+#define IQ80310_INT_STAT     0xfe820000    /* Interrupt (XINT3#) Status */
+#define IQ80310_BOARD_REV    0xfe830000    /* Board revision register */
+#define IQ80310_CPLD_REV     0xfe840000    /* CPLD revision register */
+#define IQ80310_7SEG_1       0xfe840000    /* 7-Segment MSB */
+#define IQ80310_7SEG_0       0xfe850000    /* 7-Segment LSB (WO) */
+#define IQ80310_PCI_INT_STAT 0xfe850000    /* PCI Interrupt  Status */
+#define IQ80310_INT_MASK     0xfe860000    /* Interrupt (XINT3#) Mask */
+#define IQ80310_BACKPLANE    0xfe870000    /* Backplane Detect */
+#define IQ80310_TIMER_LA0    0xfe880000    /* Timer LA0 */
+#define IQ80310_TIMER_LA1    0xfe890000    /* Timer LA1 */
+#define IQ80310_TIMER_LA2    0xfe8a0000    /* Timer LA2 */
+#define IQ80310_TIMER_LA3    0xfe8b0000    /* Timer LA3 */
+#define IQ80310_TIMER_EN     0xfe8c0000    /* Timer Enable */
+#define IQ80310_ROTARY_SW    0xfe8d0000    /* Rotary Switch */
+#define IQ80310_JTAG         0xfe8e0000    /* JTAG Port Access */
+#define IQ80310_BATT_STAT    0xfe8f0000    /* Battery Status */
+
+#endif	// _IQ80310_H_
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/iq80321.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/iq80321.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/iq80321.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/iq80321.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm/arch-iop321/iq80321.h
+ * 
+ * Intel IQ-80321 evaluation board registers
+ */
+
+#ifndef _IQ80321_H_
+#define _IQ80321_H_
+
+#define IQ80321_RAMBASE      0xa0000000
+#define IQ80321_UART1        0xfe800000    /* UART #1 */
+#define IQ80321_7SEG_1       0xfe840000    /* 7-Segment MSB */
+#define IQ80321_7SEG_0       0xfe850000    /* 7-Segment LSB (WO) */
+#define IQ80321_ROTARY_SW    0xfe8d0000    /* Rotary Switch */
+#define IQ80321_BATT_STAT    0xfe8f0000    /* Battery Status */
+
+#endif	// _IQ80321_H_
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/irq.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/irq.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/irq.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,13 @@
+/*
+ *  linux/include/asm-arm/arch-iop80310/irq.h
+ *
+ *  Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define fixup_irq(irq)  (irq)
+
+
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/irqs.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/irqs.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/irqs.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ * linux/include/asm-arm/arch-iop310/irqs.h
+ *
+ * Copyright:	(C) 2001 MontaVista Software Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *
+ */
+
+/*
+ * Whic iop3xx implementation is this?
+ */
+#ifdef CONFIG_ARCH_IOP310
+
+#include "iop310-irqs.h"
+
+#else
+
+#include "iop321-irqs.h"
+
+#endif
+
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/memory.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/memory.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/memory.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,62 @@
+/*
+ * linux/include/asm-arm/arch-iop80310/memory.h
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+
+#define TASK_SIZE	((unsigned long)(CONFIG_KERNEL_START & 0xffc00000))
+#define TASK_SIZE_26	(0x04000000UL)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+#define PAGE_OFFSET	((unsigned long)(CONFIG_KERNEL_START & 0xffc00000))
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET	(0xa0000000UL)
+
+/*
+ * physical vs virtual ram conversion
+ */
+#define __virt_to_phys__is_a_macro
+#define __phys_to_virt__is_a_macro
+#define __virt_to_phys(x)	((x) - PAGE_OFFSET + PHYS_OFFSET)
+#define __phys_to_virt(x)	((x) - PHYS_OFFSET + PAGE_OFFSET)
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *		address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *		to an address that the kernel can use.
+ */
+#define __virt_to_bus__is_a_macro
+#define __bus_to_virt__is_a_macro
+
+#ifdef CONFIG_ARCH_IOP310
+
+#define __virt_to_bus(x)	(((__virt_to_phys(x)) & ~(*IOP310_SIATVR)) | ((*IOP310_SIABAR) & 0xfffffff0))
+
+#define __bus_to_virt(x)    (__phys_to_virt(((x) & ~(*IOP310_SIALR)) | ( *IOP310_SIATVR)))
+
+#elif defined(CONFIG_ARCH_IOP321)
+
+#define __virt_to_bus(x)	(((__virt_to_phys(x)) & ~(*IOP321_IATVR2)) | ((*IOP321_IABAR2) & 0xfffffff0))
+
+#define __bus_to_virt(x)    (__phys_to_virt(((x) & ~(*IOP321_IALR2)) | ( *IOP321_IATVR2)))
+
+#endif
+
+/* boot mem allocate global pointer for MU circular queues QBAR */
+#ifdef CONFIG_IOP3XX_MU 
+extern void *mu_mem;
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/message.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/message.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/message.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/message.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,118 @@
+/*
+ * Definitions for IQ80310 messageing unit
+ *
+ * Author: Dave Jiang (dave.jiang@intel.com)
+ * Copyright (C) 2001 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _IOP310_MU_H_
+#define _IOP310_MU_H_
+
+#define MUDB_PCI_INTD           0x80000000
+#define MUDB_PCI_INTC           0x40000000
+#define MUDB_PCI_INTB           0x20000000
+#define MUDB_PCI_INTA           0x10000000
+#define MUDB_PCI_SOFT27         0x08000000
+#define MUDB_PCI_SOFT26         0x04000000
+#define MUDB_PCI_SOFT25         0x02000000
+#define MUDB_PCI_SOFT24         0x01000000
+#define MUDB_PCI_SOFT23         0x00800000
+#define MUDB_PCI_SOFT22         0x00400000
+#define MUDB_PCI_SOFT21         0x00200000
+#define MUDB_PCI_SOFT20         0x00100000
+#define MUDB_PCI_SOFT19         0x00080000
+#define MUDB_PCI_SOFT18         0x00040000
+#define MUDB_PCI_SOFT17         0x00020000
+#define MUDB_PCI_SOFT16         0x00010000
+#define MUDB_PCI_SOFT15         0x00008000
+#define MUDB_PCI_SOFT14         0x00004000
+#define MUDB_PCI_SOFT13         0x00002000
+#define MUDB_PCI_SOFT12         0x00001000
+#define MUDB_PCI_SOFT11         0x00000800
+#define MUDB_PCI_SOFT10         0x00000400
+#define MUDB_PCI_SOFT9          0x00000200
+#define MUDB_PCI_SOFT8          0x00000100
+#define MUDB_PCI_SOFT7          0x00000080
+#define MUDB_PCI_SOFT6          0x00000040
+#define MUDB_PCI_SOFT5          0x00000020
+#define MUDB_PCI_SOFT4          0x00000010
+#define MUDB_PCI_SOFT3          0x00000008
+#define MUDB_PCI_SOFT2          0x00000004
+#define MUDB_PCI_SOFT1          0x00000002
+#define MUDB_PCI_SOFT0          0x00000001
+
+#define MUCR_QUEUE_ENABLE       0x0001
+#define MUCR_QUEUE_4K           0x0002
+#define MUCR_QUEUE_8K           0x0004
+#define MUCR_QUEUE_16K          0x0008
+#define MUCR_QUEUE_32K          0x0010
+#define MUCR_QUEUE_64K          0x0020
+
+#define QUEUE_16K               0x04000
+#define QUEUE_32K               0x08000
+#define QUEUE_64K               0x10000
+#define QUEUE_128K              0x20000
+#define QUEUE_256K              0x40000
+
+#define ENTRY_4K                4000
+#define ENTRY_8K                8000
+#define ENTRY_16K              16000
+#define ENTRY_32K              32000
+#define ENTRY_64K              64000
+
+/* MU Message Descriptors */
+typedef struct _mu_msg_desc
+{
+	struct list_head link;		/* queue entry */
+	u8 reg_num;					/* register number */
+	u32 message;				/* Message content */
+} mu_msg_desc_t;
+
+/* MU msg callback type */
+typedef void (*mu_msg_cb_t) (mu_msg_desc_t *);
+
+/* MU Doorbell callback type*/
+typedef void (*mu_db_cb_t) (u32);
+
+
+/* message frame list descriptor */
+typedef struct _mfa_list
+{
+	u32 mfa;					/* message frame address */
+	struct _mfa_list *next_list;	/* pointer to next list element */
+} mfa_list_t;
+
+/* MU CQ callback type */
+typedef void (*mu_cq_cb_t) (u32);
+
+/* MU IR callback type */
+typedef void (*mu_ir_cb_t) (u32);
+
+
+/* prototypes */
+int mu_msg_request(u32 *);
+int mu_msg_set_callback(u32, u8, mu_msg_cb_t);
+int mu_msg_post(u32, u32, u8);
+int mu_msg_free(u32, u8);
+int mu_db_request(u32 *);
+int mu_db_set_callback(u32, mu_db_cb_t);
+void mu_db_ring(u32, u32);
+int mu_db_free(u32);
+int mu_cq_request(u32 *, u32);
+int mu_cq_inbound_init(u32, mfa_list_t *, u32, mu_cq_cb_t);
+int mu_cq_enable(u32);
+u32 mu_cq_get_frame(u32);
+int mu_cq_post_frame(u32, u32);
+int mu_cq_free(u32);
+int mu_ir_request(u32 *);
+int mu_ir_set_callback(u32, mu_ir_cb_t);
+int mu_ir_free(u32);
+void mu_set_irq_threshold(u32, int);
+
+#endif
+/* EOF */
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/param.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/param.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/param.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,3 @@
+/*
+ * linux/include/asm-arm/arch-iop80310/param.h
+ */
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/pci_auto.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/pci_auto.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/pci_auto.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/pci_auto.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-iop310/pci_auto.h
+ * 
+ * PCI autoconfiguration library definitions
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef _ARM_MACH_XSCALE_PCI_AUTO_H
+#define _ARM_MACH_XSCALE_PCI_AUTO_H
+
+#include "pci-bridge.h"
+
+extern int pciauto_bus_scan(struct pci_controller *, int);
+
+#define	PCIAUTO_IDE_MODE_MASK		0x05
+
+#endif /* _ARM_MACH_XSCALE_PCI_AUTO_H */
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/pci-bridge.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/pci-bridge.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/pci-bridge.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/pci-bridge.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,65 @@
+/*
+ * include/asm-arm/arch-iop310/pci-bridge.h
+ * 
+ * Generic PCI hose support for Xscale/ARM.  To eventually be
+ * moved to a more generic location.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifdef __KERNEL__
+#ifndef _ASM_PCI_BRIDGE_H
+#define _ASM_PCI_BRIDGE_H
+
+struct device_node;
+struct pci_controller;
+
+/* Get the PCI host controller for a bus */
+extern struct pci_controller* pci_bus_to_hose(int bus);
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct pci_controller {
+	int index;
+	struct pci_controller *next;
+        struct pci_bus *bus;
+	void *arch_data;
+
+	int first_busno;
+	int last_busno;
+        
+	struct pci_ops *ops;
+	volatile unsigned int *cfg_addr;
+	volatile unsigned char *cfg_data;
+
+	/* Currently, we limit ourselves to 1 IO range and 3 mem
+	 * ranges since the common pci_bus structure can't handle more
+	 */
+	struct resource	io_resource;
+	struct resource mem_resources[3];
+	int mem_resource_count;
+
+	/* Host bridge I/O and Memory space
+	 * Used for BAR placement algorithms
+	 */
+	struct resource io_space;
+	struct resource mem_space;
+};
+
+/* These are used for config access before all the PCI probing
+   has been done. */
+int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn, int where, u8 *val);
+int early_read_config_word(struct pci_controller *hose, int bus, int dev_fn, int where, u16 *val);
+int early_read_config_dword(struct pci_controller *hose, int bus, int dev_fn, int where, u32 *val);
+int early_write_config_byte(struct pci_controller *hose, int bus, int dev_fn, int where, u8 val);
+int early_write_config_word(struct pci_controller *hose, int bus, int dev_fn, int where, u16 val);
+int early_write_config_dword(struct pci_controller *hose, int bus, int dev_fn, int where, u32 val);
+#endif
+#endif /* __KERNEL__ */
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/pci.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/pci.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/pci.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,36 @@
+/*
+ * include/asm-arm/arch-xscale/pci.h
+ * 
+ * Generic PCI support for Xscale/ARM.  To eventually be moved to a
+ * more generic location.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef _ASM_ARCH_PCI_H
+#define _ASM_ARCH_PCI_H
+
+extern struct pci_controller* pcibios_alloc_controller(void);
+extern void pcibios_allocate_resources(void);
+extern void pci_exclude_device(unsigned char, unsigned char);
+extern struct pci_dev * fake_pci_dev(struct pci_controller *, int, int);
+extern u8 common_swizzle(struct pci_dev *, u8 *);
+
+/*
+ * The following macro is used to lookup irqs in a standard table
+ * format for those systems that do not already have PCI
+ * interrupts properly routed.
+ */
+#define PCI_IRQ_TABLE_LOOKUP                                            \
+({ long _ctl_ = -1;                                                     \
+   if (idsel >= min_idsel && idsel <= max_idsel && pin <= irqs_per_slot) \
+	 _ctl_ = pci_irq_table[idsel - min_idsel][pin-1]; \
+   _ctl_; })
+
+#endif /* _ASM_ARCH_PCI_H */
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/pci_iop310.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/pci_iop310.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/pci_iop310.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/pci_iop310.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,21 @@
+/*
+ * include/asm-arm/arch-iop310/pci_iop310.h
+ * 
+ * IOP310 PCI support.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef _PCI_IOP310_H
+#define _PCI_IOP310_H
+
+extern struct pci_ops iop310_ops;
+extern void iop310_init(void);
+
+#endif /* _PCI_IOP310_H */
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/pci_iop321.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/pci_iop321.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/pci_iop321.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/pci_iop321.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,20 @@
+/*
+ * include/asm-arm/arch-iop3xx/pci_iop321.h
+ * 
+ * IOP321 PCI support.
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef _PCI_IOP321_H
+#define _PCI_IOP321_H
+
+extern struct pci_ops iop321_ops;
+extern void iop321_init(void);
+
+#endif /* _PCI_IOP321_H */
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/pmon.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/pmon.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/pmon.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/pmon.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ * Definitions for XScale 80312 PMON
+ * (C) 2001 Intel Corporation
+ * Author: Chen Chen(chen.chen@intel.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _IOP310_PMON_H_
+#define _IOP310_PMON_H_
+
+/*
+ *  Different modes for Event Select Register for intel 80312
+ */
+
+#define IOP310_PMON_MODE0                0x00000000
+#define IOP310_PMON_MODE1                0x00000001
+#define IOP310_PMON_MODE2                0x00000002
+#define IOP310_PMON_MODE3                0x00000003
+#define IOP310_PMON_MODE4                0x00000004
+#define IOP310_PMON_MODE5                0x00000005
+#define IOP310_PMON_MODE6                0x00000006
+#define IOP310_PMON_MODE7                0x00000007
+
+typedef struct _iop310_pmon_result
+{
+	u32 timestamp;			/* Global Time Stamp Register */
+	u32 timestamp_overflow;		/* Time Stamp overflow count */
+	u32 event_count[14];		/* Programmable Event Counter 
+					   Registers 1-14 */
+	u32 event_overflow[14];		/* Overflow counter for PECR1-14 */
+} iop310_pmon_res_t;
+
+/* function prototypes */
+
+/* Claim IQ80312 PMON for usage */
+int iop310_pmon_claim(void);
+
+/* Start IQ80312 PMON */
+int iop310_pmon_start(int, int);
+
+/* Stop Performance Monitor Unit */
+int iop310_pmon_stop(iop310_pmon_res_t *);
+
+/* Release IQ80312 PMON */
+int iop310_pmon_release(int);
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/serial.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/serial.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/serial.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,62 @@
+/*
+ * include/asm-arm/arch-iop310/serial.h
+ */
+
+
+/*
+ * This assumes you have a 1.8432 MHz clock for your UART.
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ */
+#define BASE_BAUD ( 1843200 / 16 )
+
+/* Standard COM flags */
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+#ifdef CONFIG_ARCH_IQ80310
+
+#define IRQ_UART1	IRQ_IQ80310_UART1
+#define IRQ_UART2	IRQ_IQ80310_UART2
+
+#define RS_TABLE_SIZE 2
+
+#define STD_SERIAL_PORT_DEFNS			\
+	{ 					\
+	 magic: 0, 				\
+	 baud_base: BASE_BAUD, 			\
+	 irq: IRQ_UART2, 			\
+         flags: STD_COM_FLAGS,  		\
+	 iomem_base: 0xfe810000, 		\
+	 io_type: SERIAL_IO_MEM			\
+	}, /* ttyS0 */				\
+	{ 					\
+	 magic: 0, 				\
+	 baud_base: BASE_BAUD, 			\
+	 irq: IRQ_UART1, 			\
+         flags: STD_COM_FLAGS,  		\
+	 iomem_base: 0xfe800000, 		\
+	 io_type: SERIAL_IO_MEM			\
+	} /* ttyS0 */
+
+#endif // CONFIG_ARCH_IQ80310
+
+#ifdef CONFIG_ARCH_IQ80321
+
+#define RS_TABLE_SIZE 1
+
+#define STD_SERIAL_PORT_DEFNS			\
+	{					\
+		magic: 0,			\
+		baud_base: BASE_BAUD,		\
+		irq: IRQ_IQ80321_UART,		\
+		flags: STD_COM_FLAGS,		\
+		iomem_base: 0xfe800000,		\
+		io_type: SERIAL_IO_MEM		\
+	} /* ttyS0 */
+#endif
+
+
+#define EXTRA_SERIAL_PORT_DEFNS
+
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/system.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/system.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/system.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,27 @@
+/*
+ * linux/include/asm-arm/arch-iop80310/system.h
+ *
+ *  Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+
+static inline void arch_reset(char mode)
+{
+	if ( 1 && mode == 's') {
+		/* Jump into ROM at address 0 */
+		cpu_reset(0);
+	} else {
+		/* No on-chip reset capability */
+		cpu_reset(0);
+	}
+}
+
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/time.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/time.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/time.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * linux/include/asm-arm/arch-iop80310/time.h
+ * 
+ * Author:  Nicolas Pitre
+ * Copyright:   (C) 2001 MontaVista Software Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/timex.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/timex.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/timex.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ * linux/include/asm-arm/arch-iop3xx/timex.h
+ *
+ * IOP310 architecture timex specifications
+ */
+
+
+
+#ifdef CONFIG_ARCH_IQ80310
+
+#ifndef CONFIG_XSCALE_PMU_TIMER
+
+/* This is for the on-board timer */
+#define CLOCK_TICK_RATE 33000000 /* Underlying HZ */
+
+#else
+
+/* This is for the underlying xs80200 PMU clock. We run the core @ 733MHz */
+#define CLOCK_TICK_RATE	733000000
+
+#endif // IQ80310
+
+#elif defined(CONFIG_ARCH_IQ80321)
+
+#define CLOCK_TICK_RATE 200000000
+
+
+#else
+
+#error "No IOP3xx timex information for this architecture"
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/uncompress.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/uncompress.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/uncompress.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ *  linux/include/asm-arm/arch-iop80310/uncompress.h
+ */
+
+#include <linux/serial_reg.h>
+
+#ifdef CONFIG_ARCH_IQ80310
+#define UART1_BASE    ((volatile unsigned char *)0xfe800000)
+#define UART2_BASE    ((volatile unsigned char *)0xfe810000)
+#elif defined(CONFIG_ARCH_IQ80321)
+#define UART2_BASE    ((volatile unsigned char *)0xfe800000)
+#endif
+
+static __inline__ void putc(char c)
+{
+	while ((UART2_BASE[5] & 0x60) != 0x60);
+	UART2_BASE[0] = c;
+}
+
+/*
+ * This does not append a newline
+ */
+static void puts(const char *s)
+{
+	while (*s) {
+		putc(*s);
+		if (*s == '\n')
+			putc('\r');
+		s++;
+	}
+}
+
+#if 0
+static void arch_decomp_setup()
+{
+	UART2_BASE[UART_LCR] = 0x36;
+	UART2_BASE[UART_DLL] = 2;
+	UART2_BASE[UART_DLM] = 0;
+	UART2_BASE[UART_LCR] = 0x3;
+	UART2_BASE[UART_MCR] = 0;
+	UART2_BASE[UART_FCR] = 0x6;
+	UART2_BASE[UART_IER] = 0;
+}
+#endif
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff -urN linux-2.4.29/include/asm-arm/arch-iop3xx/vmalloc.h linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/vmalloc.h
--- linux-2.4.29/include/asm-arm/arch-iop3xx/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-iop3xx/vmalloc.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,16 @@
+/*
+ * linux/include/asm-arm/arch-iop310/vmalloc.h
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (0xe8000000)
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/dma.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/dma.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/dma.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,20 @@
+/*
+ * linux/include/asm-arm/arch-ixp1200/dma.h
+ *
+ */
+
+#ifndef _ARCH_DMA_H_
+#define _ARCH_DMA_H_
+
+/*
+ * This is the maximum DMA address that can be DMAd to.
+ */
+#define MAX_DMA_ADDRESS		0xffffffff
+
+/*
+ * None supported at the moment
+ */
+
+#define MAX_DMA_CHANNELS	0
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/hardware.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/hardware.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/hardware.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,36 @@
+/*
+ * linux/include/asm-arm/arch-ixp1200/hardware.h
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ * Copyright (C) 1998-1999 Russell King.
+ *
+ *
+ * IXP1200 hardware definitions. Based on original 2.3.99-pre3 Intel code
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <linux/config.h>
+#include <asm/arch/memory.h>
+
+/*
+ * Generic IXP1200 support
+ */
+
+#include "ixp1200.h"
+
+
+#define UNCACHEABLE_ADDR	(ARMCSR_BASE+0x180)
+
+#define	PCIBIOS_MIN_IO		0x54000000
+#define PCIBIOS_MIN_MEM		0x60000000
+
+#define PCIO_BASE		0x9c700000
+
+#define pcibios_assign_all_busses() 1
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/ide.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/ide.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/ide.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,2 @@
+
+/* No IDE support */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/io.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/io.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/io.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,44 @@
+/*
+ * linux/include/asm-arm/arch-ixp1200/io.h
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+// #define IO_SPACE_LIMIT 0x5400ffff
+
+/*
+ * Translation of various region addresses to virtual addresses
+ */
+#define __io_pci(a)		(PCIO_BASE + (a))
+#define __mem_pci(a)		((unsigned long)(a))
+
+#define __ioaddr(p)		__io_pci(p)
+#define __io(p)			__io_pci(p)
+
+extern __inline__ unsigned int __arch_getw(unsigned long a)
+{
+	unsigned int value;
+	__asm__ __volatile__("ldr%?h	%0, [%1, #0]	@ getw"
+		: "=&r" (value)
+		: "r" (a));
+	return value;
+}
+
+extern __inline__ void __arch_putw(unsigned int value, unsigned long a)
+{
+	__asm__ __volatile__("str%?h	%0, [%1, #0]	@ putw"
+		: : "r" (value), "r" (a));
+}
+
+#define __arch_ioremap          __ioremap
+#define __arch_iounmap          __iounmap
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/irq.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/irq.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/irq.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,13 @@
+/*
+ *  linux/include/asm-arm/arch-ixp1200/irq.h
+ *
+ *  Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define fixup_irq(irq)  (irq)
+
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/irqs.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/irqs.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/irqs.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,51 @@
+/*
+ * linux/include/asm-arm/arch-ixp1200/irqs.h
+ *
+ * Copyright (C) 2000, Intel Corporation, Inc.
+ * Copyright (C) 2001-2002, MontaVista Software, Inc.
+ *
+ * Changelog:
+ *  17-mar-2000 Uday Naik      Created
+ *  25-sep-2001 dsaxena
+ *  	Moved to 2.4.x kernel & cleanup
+ *  01-Mar-2002 dsaxena
+ *  	Support for all interrupt sources
+ *
+ */
+
+#ifndef __IXP1200_IRQ_H_
+#define __IXP1200_IRQ_H_
+
+#define NR_IRQS			21
+
+/*
+ * Interrupts on the IRQ Register
+ */
+#define	IXP1200_IRQ_CINT	0
+#define	IXP1200_IRQ_UENG	1 
+#define	IXP1200_IRQ_SRAM	2
+#define	IXP1200_IRQ_UART	3
+#define	IXP1200_IRQ_RTC		4
+#define	IXP1200_IRQ_SDRAM	5     
+
+/*
+ * Interrupts on the PCI Interrupt Register
+ */
+#define	IXP1200_IRQ_SWI		6
+#define	IXP1200_IRQ_TIMER1	7
+#define	IXP1200_IRQ_TIMER2	8
+#define	IXP1200_IRQ_TIMER3	9
+#define	IXP1200_IRQ_TIMER4	10
+#define	IXP1200_IRQ_DOORBELL	11
+#define	IXP1200_IRQ_DMA1	12
+#define	IXP1200_IRQ_DMA2	13
+#define	IXP1200_IRQ_PCI		14
+#define	IXP1200_IRQ_DMA1NB	15
+#define	IXP1200_IRQ_DMA2NB	16
+#define	IXP1200_IRQ_BIST	17
+#define	IXP1200_IRQ_I2O		18
+#define	IXP1200_IRQ_PWRM	19
+#define	IXP1200_IRQ_PCI_ERR	20
+
+#endif
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/ixp1200.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/ixp1200.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/ixp1200.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/ixp1200.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,295 @@
+/*
+ * include/asm-arm/arch-ixp1200/
+ *
+ * Copyright (C) 2000 Intel Corporation, Inc.
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * Generic IXP1200 hardware/register definitions
+ * Based on original 2.3.99-pre3 Intel kernel
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * April 2, 2000   Created : Uday Naik
+ *  Nov 11, 2001   Massive cleanup/rewrite: Deepak Saxena
+ *
+ */
+
+#ifndef _IXP1200_H_
+#define _IXP1200_H_
+
+/*
+ * Constants to make it easy to access various registers
+ */
+#define SRAM_PUSH_POPQ_BASE		0xd0000000
+#define SRAM_PUSH_POPQ_SIZE		0x08000000
+
+#define PCIMEM_BASE			0xe0000000
+#define PCIMEM_SIZE			0x10000000
+
+#define ARMCSR_BASE			0xf0000000
+#define ARMCSR_SIZE			0x00100000
+
+#define PCI_CSR_BASE			0xf0100000
+#define PCI_CSR_SIZE			0x00100000
+
+#define SRAM_CSR_BASE			0xf0200000
+#define SRAM_CSR_SIZE			0x00100000
+
+#define SDRAM_CSR_BASE			0xf0300000
+#define SDRAM_CSR_SIZE			0x00100000
+
+#define FLUSH_BASE			0xf0400000
+#define CACHE_FLUSH_SIZE		0x00100000
+
+#define FLUSH_BASE_MINICACHE		0xf0500000
+#define MINI_CACHE_FLUSH_SIZE		0x00100000
+
+#define MICROENGINE_FBI_BASE		0xf0600000
+#define MICROENGINE_FBI_SIZE		0x00010000
+
+#define PCIIO_BASE			0xf0700000
+#define PCIIO_SIZE			0x00100000
+
+#define SRAM_SLOW_PORT_BASE		0xf0800000
+#define SRAM_SLOW_PORT_SIZE		0x00300000
+
+#define PCICFG0_BASE			0xf1000000
+#define PCICFG0_SIZE			0x01000000
+
+#define PCICFG1_BASE			0xf2000000
+#define PCICFG1_SIZE			0x01000000
+
+#define SRAM_BASE			0xf4000000
+#define SRAM_SIZE			0x00800000
+
+#define SRAM_READ_LOCK			0xf5000000
+#define SRAM_READ_LOCK_SIZE		0x00800000
+
+#define SRAM_WRITE_UNLOCK		0xf5800000
+#define SRAM_WRITE_UNLOCK_SIZE		0x00800000
+
+#define SRAM_CAM_UNLOCK			0xf6000000
+#define SRAM_CAM_UNLOCK_SIZE		0x00800000
+
+#define SRAM_CLEAR_BITS			0xf6800000
+#define SRAM_CLEAR_BITS_SIZE		0x00800000
+
+#define SRAM_SET_BITS			0xf7000000
+#define SRAM_SET_BITS_SIZE		0x00800000
+
+#define SRAM_TEST_CLEAR_BITS		0xf7800000
+#define SRAM_TEST_CLEAR_BITS_SIZE	0x00800000
+
+#define SRAM_TEST_SET_BITS		0xf8000000
+#define SRAM_TEST_SET_BITS_SIZE		0x00800000
+
+
+/* define FLUSH BASE PHYS to be same as SA1100 for now */
+#define FLUSH_BASE_PHYS			0xa0000000
+
+/* 
+ * Locaion and max size of compressed initrd. Initrd is expected
+ * to be at sdram_base + 8Mb unless otherwise specified in the 
+ * command line
+ */
+#define INITRD_LOCATION              (CONFIG_IXP1200_SDRAM_BASE + 0x00800000)
+#define INITRD_SIZE                  (0x00800000)
+
+#ifndef __ASSEMBLY__
+
+#define IXP1200_PCI_CSR(x)	((volatile unsigned long *)(PCI_CSR_BASE+(x)))
+#define IXP1200_CSR(x)		((volatile unsigned long *)(ARMCSR_BASE+(x)))
+#define IXP1200_REG(x)		((volatile unsigned long *)(x))
+
+#else
+
+#define IXP1200_PCI_CSR(x)		(x)
+#define IXP1200_CSR(x)		        (x)
+
+#endif
+
+/*
+ * PCI Control/Status Registers
+ */
+#define CSR_PCI_VEN_DEV_ID	IXP1200_PCI_CSR(0x0000)
+#define CSR_PCICMD		IXP1200_PCI_CSR(0x0004)
+#define CSR_CLASSREV		IXP1200_PCI_CSR(0x0008)
+#define CSR_PCICACHELINESIZE	IXP1200_PCI_CSR(0x000c)
+#define CSR_PCICSRBASE		IXP1200_PCI_CSR(0x0010)
+#define CSR_PCICSRIOBASE	IXP1200_PCI_CSR(0x0014)
+#define CSR_PCISDRAMBASE	IXP1200_PCI_CSR(0x0018)
+#define CSR_PCISUBSYS		IXP1200_PCI_CSR(0x002c)
+#define CSR_PCIOUTBINTMASK	IXP1200_PCI_CSR(0x0034)
+#define CSR_PCIINTLAT		IXP1200_PCI_CSR(0x003c)
+#define CSR_MBOX0               IXP1200_PCI_CSR(0x0050)
+#define CSR_MBOX1               IXP1200_PCI_CSR(0x0054)
+#define CSR_MBOX2               IXP1200_PCI_CSR(0x0058)
+#define CSR_MBOX3               IXP1200_PCI_CSR(0x005c)
+#define CSR_DOORBELL            IXP1200_PCI_CSR(0x0060)
+#define CSR_DOORBELL_SETUP      IXP1200_PCI_CSR(0x0064)
+#define CSR_CAPPTREXT		IXP1200_PCI_CSR(0x0070)
+#define CSR_PWRMGMT		IXP1200_PCI_CSR(0x0074)
+#define CSR_IXPRESET		IXP1200_PCI_CSR(0x007c)
+#define CSR_CSRBASEMASK		IXP1200_PCI_CSR(0x00f8)
+#define CSR_SDRAMBASEMASK	IXP1200_PCI_CSR(0x0100)
+#define CSR_SDRAMBASEOFFSET	IXP1200_PCI_CSR(0x0104)
+#define CSR_I2O_INFREEHEAD	IXP1200_PCI_CSR(0x0120)
+#define CSR_I2O_INPOSTTAIL	IXP1200_PCI_CSR(0x0124)
+#define CSR_I2O_OUTPOSTHEAD	IXP1200_PCI_CSR(0x0128)
+#define CSR_I2O_OUTFREETAIL	IXP1200_PCI_CSR(0x012c)
+#define CSR_I2O_INFREECOUNT	IXP1200_PCI_CSR(0x0130)
+#define CSR_I2O_OUTPOSTCOUNT	IXP1200_PCI_CSR(0x0134)
+#define CSR_I2O_INPOSTCOUNT	IXP1200_PCI_CSR(0x0138)
+#define CSR_SA_CONTROL		IXP1200_PCI_CSR(0x013c)
+
+/*
+ * SA Control Register Values
+ */
+#define SA_CNTL_INITCMPLETE		(1 << 0)
+#define SA_CNTL_ASSERTSERR		(1 << 1)
+#define SA_CNTL_RXSERR		        (1 << 3)
+#define SA_CNTL_DISCARDTIMER		(1 << 8)
+#define SA_CNTL_PCINRESET		(1 << 9)
+#define SA_CNTL_I2O_256		        (0 << 10)
+#define SA_CNTL_I20_512		        (1 << 10)
+#define SA_CNTL_I2O_1024		(2 << 10)
+#define SA_CNTL_I2O_2048		(3 << 10)
+#define SA_CNTL_I2O_4096		(4 << 10)
+#define SA_CNTL_I2O_8192		(5 << 10)
+#define SA_CNTL_I2O_16384		(6 << 10)
+#define SA_CNTL_I2O_32768		(7 << 10)
+#define SA_CNTL_WATCHDOG		(1 << 13)
+#define SA_CNTL_BE_BEO			(1 << 15)
+#define SA_CNTL_BE_DEO			(1 << 16)
+#define SA_CNTL_BE_BEI			(1 << 17)
+#define SA_CNTL_BE_DEI			(1 << 18)
+#define SA_CNTL_PCICFN1		        (1 << 30)
+#define SA_CNTL_PCICFN0		        (1 << 31)
+
+#define CSR_PCIADDR_EXTN		IXP1200_PCI_CSR(0x0140)
+#define CSR_DOORBELL_PCI		IXP1200_PCI_CSR(0x0150)
+#define CSR_DOORBELL_SA  		IXP1200_PCI_CSR(0x0154)
+#define CSR_IRQ_STATUS			IXP1200_PCI_CSR(0x0180)
+#define CSR_IRQ_RAWSTATUS		IXP1200_PCI_CSR(0x0184)
+#define CSR_IRQ_ENABLE			IXP1200_PCI_CSR(0x0188)
+#define CSR_IRQ_DISABLE			IXP1200_PCI_CSR(0x018c)
+#define CSR_IRQ_SOFT			IXP1200_PCI_CSR(0x0190)
+#define CSR_FIQ_STATUS			IXP1200_PCI_CSR(0x0280)
+#define CSR_FIQ_RAWSTATUS		IXP1200_PCI_CSR(0x0284)
+#define CSR_FIQ_ENABLE			IXP1200_PCI_CSR(0x0288)
+#define CSR_FIQ_DISABLE			IXP1200_PCI_CSR(0x028c)
+#define CSR_FIQ_SOFT			IXP1200_PCI_CSR(0x0290)
+#define CSR_TIMER1_LOAD			IXP1200_PCI_CSR(0x0300)
+#define CSR_TIMER1_VALUE		IXP1200_PCI_CSR(0x0304)
+#define CSR_TIMER1_CNTL			IXP1200_PCI_CSR(0x0308)
+#define CSR_TIMER1_CLR			IXP1200_PCI_CSR(0x030c)
+#define CSR_TIMER2_LOAD			IXP1200_PCI_CSR(0x0320)
+#define CSR_TIMER2_VALUE		IXP1200_PCI_CSR(0x0324)
+#define CSR_TIMER2_CNTL			IXP1200_PCI_CSR(0x0328)
+#define CSR_TIMER2_CLR			IXP1200_PCI_CSR(0x032c)
+#define CSR_TIMER3_LOAD			IXP1200_PCI_CSR(0x0340)
+#define CSR_TIMER3_VALUE		IXP1200_PCI_CSR(0x0344)
+#define CSR_TIMER3_CNTL			IXP1200_PCI_CSR(0x0348)
+#define CSR_TIMER3_CLR			IXP1200_PCI_CSR(0x034c)
+#define CSR_TIMER4_LOAD			IXP1200_PCI_CSR(0x0360)
+#define CSR_TIMER4_VALUE		IXP1200_PCI_CSR(0x0364)
+#define CSR_TIMER4_CNTL			IXP1200_PCI_CSR(0x0368)
+#define CSR_TIMER4_CLR			IXP1200_PCI_CSR(0x036c)
+
+/*
+ * Timer Control Register Values
+ */
+#define TIMER_CNTL_ENABLE		(1 << 7)
+#define TIMER_CNTL_AUTORELOAD		(1 << 6)
+#define TIMER_CNTL_DIV1			(0)
+#define TIMER_CNTL_DIV16		(1 << 2)
+#define TIMER_CNTL_DIV256		(2 << 2)
+#define TIMER_CNTL_CNTEXT		(3 << 2)
+	
+	
+/*
+ * UART Access Registers
+ */
+#define CSR_UARTSR			IXP1200_CSR(0x3400)
+#define CSR_UARTCR			IXP1200_CSR(0x3800)
+#define CSR_UARTDR			IXP1200_CSR(0x3c00)
+
+/* 
+ * Miscalleneous stuff like CSR for SDRAM, SRAM, LED etc 
+ */
+
+#define CSR_SDRAM		IXP1200_REG(SDRAM_CSR_BASE)
+#define CSR_SRAM		IXP1200_REG(SRAM_CSR_BASE)
+#define CSR_IREG		IXP1200_REG(MICROENGINE_FBI_BASE+0x401e0)
+
+/* 
+ * IRQ Status
+ */
+#define CSR_ARM_IRQ			IXP1200_CSR(0x1400)
+
+/* 
+ * RTC
+ */
+#define CSR_RTC_DIV			IXP1200_CSR(0x2000)
+#define CSR_RTC_TINT			IXP1200_CSR(0x2400)
+#define CSR_RTC_TVAL			IXP1200_CSR(0x2800)
+#define CSR_RTC_CNTR			IXP1200_CSR(0x2c00)
+#define	CSR_RTC_ALM			IXP1200_CSR(0x3000)
+
+/*
+ * PLL Config
+ */
+#define CSR_PLL_CFG			IXP1200_CSR(0x0c00)
+
+/* 
+ * Below is a mask of all interrupts set in the IRQ register of the core 
+ *
+ * UART | SDRAM | SRAM | UENG | CINT | PCI | RTC 
+ */
+
+#define IXP1200_IRQS          (IRQ_MASK_UART | IRQ_MASK_SDRAM | IRQ_MASK_SRAM | IRQ_MASK_UENG | IRQ_MASK_CINT | IRQ_MASK_PCI_INTS | IRQ_MASK_RTC)
+
+/* These are masks from the IRQ register in the SA core */
+
+#define IRQ_MASK_CINT           (1 << 3)
+#define IRQ_MASK_PCI_INTS       (1 << 2)
+#define IRQ_MASK_UENG           (1 << 4)
+#define IRQ_MASK_SRAM           (1 << 5)
+#define IRQ_MASK_RTC            (1 << 6)
+#define IRQ_MASK_SDRAM          (1 << 7)
+#define IRQ_MASK_UART           (1 << 8)
+
+/* These are from the IRQ register in the PCI ISR register */
+
+#define	IRQ_MASK_SWI		(1 << 1)
+#define IRQ_MASK_TIMER1		(1 << 4)
+#define IRQ_MASK_TIMER2		(1 << 5)
+#define IRQ_MASK_TIMER3		(1 << 6)
+#define	IRQ_MASK_TIMER4		(1 << 7)
+#define IRQ_MASK_DOORBELL	(1 << 15)
+#define IRQ_MASK_DMA1		(1 << 16)
+#define IRQ_MASK_DMA2		(1 << 17)
+#define IRQ_MASK_PCI		(1 << 18)
+#define	IRQ_MASK_DMA1NB		(1 << 20)
+#define	IRQ_MASK_DMA2NB		(1 << 21)
+#define	IRQ_MASK_BIST		(1 << 22)
+#define	IRQ_MASK_RSERR		(1 << 23)
+#define IRQ_MASK_I2O		(1 << 25)
+#define	IRQ_MASK_PWRM		(1 << 26)
+#define	IRQ_MASK_DTE		(1 << 27)
+#define	IRQ_MASK_DPED		(1 << 28)
+#define	IRQ_MASK_RMA		(1 << 29)
+#define	IRQ_MASK_RTA		(1 << 30)
+#define	IRQ_MASK_DPE		(1 << 31)
+
+#define	IRQ_MASK_PCI_ERR	(IRQ_MASK_RSERR | \
+				 IRQ_MASK_DTE   | \
+				 IRQ_MASK_DPED  | \
+				 IRQ_MASK_RMA   | \
+				 IRQ_MASK_RTA   | \
+				 IRQ_MASK_DPE)
+
+#define IXP1200_SA_CONTROL_PNR   (1<<9)  /*PCI not Reset bit of SA_CONTROL*/
+#define IXP1200_SA_CONTROL_PCF   (1<<31) /*PCI Centrolfunction bit*/
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/memory.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/memory.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/memory.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,55 @@
+/*
+ * linux/include/asm-arm/arch-ixp1200/memory.h
+ *
+ * Copyright (C) 1996-1999 Russell King.
+ * Copyright (C) 2000 Intel Corporation, Inc.
+ * Copyright (C) 2001-2002 MontaVista Software, Inc.
+ *
+ * 20-Mar-2000 Uday Naik 
+ * 	Created for IXP1200
+ * 26-Sep-2001 dsaxena 
+ * 	Cleanup/port to 2.4.x kernel
+ * 	virt_to_bus/bus_to_virt are now the same in host and agent mode
+ * 	by reading the PCI Inbound XLation window.
+ */
+
+#ifndef __IXP1200_MEMORY_H_
+#define __IXP1200_MEMORY_H_
+
+#define TASK_SIZE	((unsigned long)(CONFIG_KERNEL_START & 0xffc00000))
+#define TASK_SIZE_26	(0x04000000UL)
+
+/*
+ *  * This decides where the kernel will search for a free chunk of vm
+ *   * space during mmap's.
+ *    */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+
+#define PAGE_OFFSET	((unsigned long)(CONFIG_KERNEL_START & 0xffc00000))
+
+
+/*
+ * Physical offset
+ */
+#define PHYS_OFFSET	(CONFIG_IXP1200_SDRAM_BASE)
+
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(x) (((x - PAGE_OFFSET) + PHYS_OFFSET))
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(x) (((x - PHYS_OFFSET) + PAGE_OFFSET))
+
+/*
+ * Bus addresses are based on the PCI inbound window which
+ * is configured either by the external host or by us 
+ * if we're running as the system controller
+ */
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(v)	\
+	((__virt_to_phys(v) - 0xc0000000) + (*CSR_PCISDRAMBASE & 0xfffffff0))
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(b)	\
+	__phys_to_virt((((b - (*CSR_PCISDRAMBASE & 0xfffffff0)) + 0xc0000000)))
+
+#endif
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/param.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/param.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/param.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-ixp1200/param.h
+ *
+ */
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/pci-auto.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/pci-auto.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/pci-auto.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/pci-auto.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-iop310/pci_auto.h
+ * 
+ * PCI autoconfiguration library definitions
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef _ARM_MACH_XSCALE_PCI_AUTO_H
+#define _ARM_MACH_XSCALE_PCI_AUTO_H
+
+#include "pci-bridge.h"
+
+extern int pciauto_bus_scan(struct pci_controller *, int);
+
+#define	PCIAUTO_IDE_MODE_MASK		0x05
+
+#endif /* _ARM_MACH_XSCALE_PCI_AUTO_H */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/pci-bridge.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/pci-bridge.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/pci-bridge.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/pci-bridge.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,65 @@
+/*
+ * include/asm-arm/arch-iop310/pci-bridge.h
+ * 
+ * Generic PCI hose support for Xscale/ARM.  To eventually be
+ * moved to a more generic location.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifdef __KERNEL__
+#ifndef _ASM_PCI_BRIDGE_H
+#define _ASM_PCI_BRIDGE_H
+
+struct device_node;
+struct pci_controller;
+
+/* Get the PCI host controller for a bus */
+extern struct pci_controller* pci_bus_to_hose(int bus);
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct pci_controller {
+	int index;
+	struct pci_controller *next;
+        struct pci_bus *bus;
+	void *arch_data;
+
+	int first_busno;
+	int last_busno;
+        
+	struct pci_ops *ops;
+	volatile unsigned int *cfg_addr;
+	volatile unsigned char *cfg_data;
+
+	/* Currently, we limit ourselves to 1 IO range and 3 mem
+	 * ranges since the common pci_bus structure can't handle more
+	 */
+	struct resource	io_resource;
+	struct resource mem_resources[3];
+	int mem_resource_count;
+
+	/* Host bridge I/O and Memory space
+	 * Used for BAR placement algorithms
+	 */
+	struct resource io_space;
+	struct resource mem_space;
+};
+
+/* These are used for config access before all the PCI probing
+   has been done. */
+int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn, int where, u8 *val);
+int early_read_config_word(struct pci_controller *hose, int bus, int dev_fn, int where, u16 *val);
+int early_read_config_dword(struct pci_controller *hose, int bus, int dev_fn, int where, u32 *val);
+int early_write_config_byte(struct pci_controller *hose, int bus, int dev_fn, int where, u8 val);
+int early_write_config_word(struct pci_controller *hose, int bus, int dev_fn, int where, u16 val);
+int early_write_config_dword(struct pci_controller *hose, int bus, int dev_fn, int where, u32 val);
+#endif
+#endif /* __KERNEL__ */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/pci.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/pci.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/pci.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ * include/asm-arm/arch-xscale/pci.h
+ * 
+ * Generic PCI support for Xscale/ARM.  To eventually be moved to a
+ * more generic location.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef _ASM_ARCH_PCI_H
+#define _ASM_ARCH_PCI_H
+
+extern struct pci_controller* pcibios_alloc_controller(void);
+extern void pci_exclude_device(unsigned char, unsigned char);
+extern struct pci_dev * fake_pci_dev(struct pci_controller *, int, int);
+extern u8 common_swizzle(struct pci_dev *, u8 *);
+
+/*
+ * The following macro is used to lookup irqs in a standard table
+ * format for those systems that do not already have PCI
+ * interrupts properly routed.
+ */
+#define PCI_IRQ_TABLE_LOOKUP                                            \
+({ long _ctl_ = -1;                                                     \
+   if (idsel >= min_idsel && idsel <= max_idsel && pin <= irqs_per_slot) \
+	 _ctl_ = pci_irq_table[idsel - min_idsel][pin-1]; \
+   _ctl_; })
+
+#endif /* _ASM_ARCH_PCI_H */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/serial.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/serial.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/serial.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+ * linux/include/asm-arm/arch-ixp1200/serial.h
+ *
+ * This is empty since the IXP1200 has no 16550 serial ports.  If
+ * someone builds an IXP1200 board with an off-chip port, this
+ * needs to be filled in appropriately.
+ */
+
+#ifndef _ARCH_SERIAL_H_
+#define _ARCH_SERIAL_H_
+
+#define BASE_BAUD (3686400 / 16)
+
+/* Base port for UART */
+#define UART_PORT CSR_UARTSR
+
+/* serial port flags */
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+#define SERIAL_PORT_DFNS \
+	{ 0, BASE_BAUD, 0, 0, STD_COM_FLAGS } /* ttyS0 */	
+
+#endif
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/serial_reg.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/serial_reg.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/serial_reg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/serial_reg.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,71 @@
+/*
+ * include/asm/arch/serial_reg.h
+ *
+ * Redistribution of this file is permitted under the terms of the GNU 
+ * Public License (GPL)
+ * 
+ * These are the IXP1200 UART port assignments, expressed as long index 
+ * of the base address.
+ */
+
+#ifndef _IXP1200_SERIAL_REG_H_
+#define _IXP1200_SERIAL_REG_H_
+
+#define UART_CR        CSR_UARTCR
+#define UART_SR        CSR_UARTSR
+#define UART_DR        CSR_UARTDR
+
+/*
+ * Register index. Since we will be using unsigned long* to access
+ * registers, all byte offsets from the base must be divided by 4 
+ */
+#define UTSR 		0	        /* Status register */
+#define UTCR 		(0x400/4)	/* Control register */
+#define UTDR 		(0x800/4)	/* Data register */
+
+#define UART_RX 	UTDR	/* Receive port, read only */
+#define UART_TX 	UTDR	/* transmit port, write only */
+
+#define UTCR_XIE        (1 << 8)     /* Xmit interrupt enable */
+#define UTCR_RIE        (1 << 4)     /* Rcv interrupt enable */
+#define UTCR_EN         (1 << 7)     /* Enable uart */
+
+#define UTCR_9600_BAUD   (0x17 << 16) 
+#define UTCR_19200_BAUD  (0xB  << 16) 
+#define UTCR_38400_BAUD  (0x5  << 16) 
+#define UTCR_57600_BAUD  (0x3  << 16) 
+#define UTCR_115200_BAUD (0x1  << 16)
+
+#define UTCR_BRK	(0x1)
+
+#define UTCR_8_BIT      (0x3 << 5)   /* 8 bit */
+#define UTCR_7_BIT      (0x2 << 5)   /* 7 bit */
+#define UTCR_6_BIT      (0x1 << 5)   /* 7 bit */
+#define UTCR_5_BIT      (0x0 << 5)   /* 7 bit */
+
+#define UTCR_1_STOP_BIT (0 << 3)     /* 1 stop bit */
+#define UTCR_2_STOP_BIT (1 << 3)     /* 2 stop bits  */
+
+#define UTCR_PARENB     (1 << 1)     /* Parity Enable */
+#define UTCR_ODD_PARITY (1 << 2)     /* Odd parity    */
+
+#define UTCR_DSS_MASK   (0x3 << 5)    /* data size mask */
+#define UTCR_SBS_MASK   (0x1 << 3)    /* stop bit select mask */
+#define UTCR_BRD_MASK   (0x3ff << 16) /* Baud rate mask */
+
+// #define CONFIG_A3_SILICON
+#ifdef CONFIG_A3_SILICON
+#define UTCR_INT_CLEAR  (1 << 9)      /* The !@#$ docs have a bug. This bit */
+#endif
+
+#define UTSR_RPE        (1 << 0) /* Parity error */
+#define UTSR_RFE        (1 << 1) /* Framing error */
+#define UTSR_ROR        (1 << 3) /* receiver overrun */
+#define UTSR_RXR        (1 << 4) /* receiver not empty */
+#define UTSR_TXR        (1 << 2) /* Transmit Fifo not full */
+#define UTSR_TXE        (1 << 5) /* xmit fifo empty */
+#define UTSR_RXF        (1 << 6) /* receive fifo full */
+#define UTSR_TXF        (1 << 7) /* xmit fifo full */
+
+#endif /* ASM_ARCH_SERIAL_REG_H */
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/system.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/system.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/system.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ * linux/include/asm-arm/arch-ixp1200/system.h
+ *
+ * Copyright (c) 1996,1997,1998 Russell King.
+ * Copyright (c) 2000, Intel Coporation
+ *
+ * Added IXP1200 support - Uday Naik
+ */
+
+#include <linux/config.h>
+#include "ixp1200.h"
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+extern __inline__ void arch_reset(char mode)
+{
+	
+	cli();
+
+	/* To do a reboot, we set the IXP1200 reset register */
+
+	*CSR_IXPRESET = 0xffffffff;
+
+}
+
+#define arch_power_off()	do { } while (0)
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/time.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/time.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/time.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,82 @@
+/*
+ * linux/include/asm-arm/arch-ixp1200/time.h
+ *
+ * Copyright (C) 1998 Deborah Wallach.
+ * Twiddles   (C) 1999 	Hugo Fiennes <hugo@empeg.com>
+ * 			Nicolas Pitre <nico@cam.org>
+ *
+ * Modified for IXP1200 Uday Naik
+ *
+ * Todo: Base LATCH on PLL register
+ */
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/irqs.h>
+
+
+static unsigned long ixp1200_latch = 0;
+
+/* IRQs are disabled before entering here from do_gettimeofday() */
+
+static unsigned long ixp1200_gettimeoffset (void)
+{
+
+	unsigned long offset, usec;
+
+	/* Get ticks since last timer service */
+
+	offset = ixp1200_latch - *CSR_TIMER1_VALUE;
+	
+	usec = (unsigned long)(offset*tick)/ixp1200_latch;
+
+	return usec;
+}
+
+static void ixp1200_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* clear timer 1 IRQ */
+	
+	*CSR_TIMER1_CLR = 1;
+
+	do_timer(regs);
+
+}
+
+/*
+ * We read the PLL_CFG register to determine the clock tick rate.
+ * Theoretically, we could just change PLL_CFG so it always runs at
+ * 232MHz, but certain models of IXP can't do that, and also, some 
+ * people may want to run at slower speed due to heat/power concerns,
+ * which often come up in cPCI designs.
+ */
+extern inline void setup_timer (void)
+{
+	unsigned int pll_cfg;
+	unsigned int speeds[] =
+		{ 29491000, 36865000, 44237000, 51610000, 58982000,
+		  66355000, 73728000, 81101000, 88474000, 95846000,
+		  103219000, 110592000, 132710000, 147456000, 154829000,
+		  162202000, 165890000, 176947000, 191693000, 199066000 ,
+		  0, 0, 232000000 };
+
+
+	gettimeoffset = ixp1200_gettimeoffset;
+	timer_irq.handler = ixp1200_timer_interrupt;
+
+	pll_cfg = *((unsigned int *)CSR_PLL_CFG);
+
+	printk("IXP1200 Running @ %dMHz\n", speeds[pll_cfg] / 1000000);
+
+	ixp1200_latch = (speeds[pll_cfg] + HZ/2) / HZ;
+
+	*CSR_TIMER1_CLR = 0;
+
+	*CSR_TIMER1_LOAD	 = ixp1200_latch;  
+
+	*CSR_TIMER1_CNTL = (1 << 7) | (1 << 6);
+
+	setup_arm_irq(IXP1200_IRQ_TIMER1, &timer_irq);
+}
+
+
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/timex.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/timex.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/timex.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,15 @@
+/*
+ * linux/include/asm-arm/arch-ixp1200/timex.h
+ *
+ * IXP1200-based architecture timex specifications
+ *
+ * Copyright (c) 2002 MontaVista Sofware, Inc.
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ */
+
+/*
+ * We don't really use this to determine the bogomips since
+ * we read the CPU speed from the PLL_CFG register.
+ */
+#define CLOCK_TICK_RATE		232*1000*1000
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/uncompress.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/uncompress.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/uncompress.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,52 @@
+/*
+ * linux/include/asm-arm/arch-ixp1200/uncompress.h
+ *
+ * Copyright (C) 1996,1997,1998 Russell King
+ * Copyright (C) 2000 Intel Corporation, Inc.
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ *
+ * March 26 2000  Uday Naik     Created
+ *   Feb 15 2002  Deepak Saxena Massive cleanup/rewrite
+ */
+
+#include "serial_reg.h"
+
+
+#define UARTDR		(volatile unsigned long*)(0x90003c00)
+#define UARTSR		(volatile unsigned long*)(0x90003400)
+
+/*
+ * nothing to do
+ */
+
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
+
+/*
+ * This code assumes that the serial port has already been configured
+ * by a bootloader.
+ */
+static void puts( const char *s )
+{
+	int i;
+    
+	for (i = 0; *s; i++, s++) {
+
+		/* wait for space in the UART's transmiter */
+		while (*UARTSR & UTSR_TXF); 
+		/* send the character out. */
+		*UARTDR = *s;
+
+		/* if a LF, also do CR... */
+		if (*s == 10) { 
+			/* wait for space in the UART's transmiter */
+			while (*UARTSR & UTSR_TXF);
+
+			/* send the CR character out. */
+			*UARTDR = 13;
+		}
+	}
+}
+
+
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp1200/vmalloc.h linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/vmalloc.h
--- linux-2.4.29/include/asm-arm/arch-ixp1200/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp1200/vmalloc.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,16 @@
+/*
+ * linux/include/asm-arm/arch-ixp1200/vmalloc.h
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/dma.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/dma.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/dma.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,18 @@
+/*
+ * linux/include/asm-arm/arch-ixdp2400/dma.h
+ *
+ * Copyright (C) 2002 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_ADDRESS		0xffffffff
+
+/* No DMA */
+#define MAX_DMA_CHANNELS	0
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/gpio.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/gpio.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/gpio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/gpio.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,55 @@
+/*
+ * include/asm-arm/arch-ixp2000/ixp2000-gpio.h
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * This program is free software, you can redistribute it and/or modify 
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * IXP2000 GPIO in/out, edge/level detection for IRQs:
+ * IRQs are generated on Falling-edge, Rising-Edge, Level-low, Level-High
+ * or both Falling-edge and Rising-edge.  
+ * This must be called *before* the corresponding IRQ is registerd.
+ * Use this instead of directly setting the GPIO registers.
+ * GPIOs may also be used as GPIOs (e.g. for emulating i2c/smb)
+ */
+#ifndef _ASM_ARCH_IXP2000_GPIO_H_
+#define _ASM_ARCH_IXP2000_GPIO_H_
+
+#ifndef __ASSEMBLY__
+#define GPIO_OUT			0x0
+#define GPIO_IN				0x80
+
+#define IXP2000_GPIO_LOW		0
+#define IXP2000_GPIO_HIGH		1
+
+#define GPIO_NO_EDGES           	0
+#define GPIO_FALLING_EDGE       	1
+#define GPIO_RISING_EDGE        	2
+#define GPIO_BOTH_EDGES         	3
+#define GPIO_LEVEL_LOW          	4
+#define GPIO_LEVEL_HIGH         	8
+
+extern void set_GPIO_IRQ_edge(int gpio_nr, int edge);
+extern void set_GPIO_IRQ_level(int gpio_nr, int level);
+extern void gpio_line_config(int line, int style);
+
+static inline int gpio_line_get(int line)
+{
+	return (((*IXP2000_GPIO_PLR) >> line) & 1);
+}
+
+static inline void gpio_line_set(int line, int value)
+{
+	if (value == IXP2000_GPIO_HIGH) {
+		ixp_reg_write(IXP2000_GPIO_POSR, BIT(line));
+	} else if (value == IXP2000_GPIO_LOW)
+		ixp_reg_write(IXP2000_GPIO_POCR, BIT(line));
+}
+
+#endif /* !__ASSEMBLY__ */
+#endif /* ASM_ARCH_IXP2000_GPIO_H_ */
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/hardware.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/hardware.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/hardware.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,44 @@
+/*
+ * linux/include/asm-arm/arch-ixdp2400/hardware.h
+ *
+ * Hardware definitions for IXP2000 based systems
+ *
+ * Author: Naeem M Afzal <naeem.m.afzal@intel.com>
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (C) 2001-2002 Intel Corp.
+ * Copyright (C) 2003 MontaVista Software, Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H__
+#define __ASM_ARCH_HARDWARE_H__
+
+/*
+ * Generic chipset bits
+ */
+#include "ixp2000.h"
+#include "gpio.h"
+
+/* PCI IO info */
+//#define PCIO_BASE    (VIRT_PCI_IO - PHY_PCI_IO)
+#define PCIO_BASE      PCI_IO_VIRT_BASE
+
+#define PCIBIOS_MIN_IO          0x00000000
+#define PCIBIOS_MIN_MEM         0x00000000
+
+#define pcibios_assign_all_busses() 0
+
+/*
+ * board specific definitions
+ */
+#include "ixdp2400.h"
+
+#include "ixdp2800.h"
+
+#endif  /* _ASM_ARCH_HARDWARE_H__ */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/io-ds.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/io-ds.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/io-ds.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/io-ds.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,80 @@
+/*
+ * linux/include/asm-arm/arch-ixdp2000/io.h
+ *
+ * Author: Naeem M Afzal <naeem.m.afzal@intel.com>
+ *
+ * Copyright (C) 2002  Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __ixp_io_pci(a)		(PCIO_BASE + (a))
+#define __mem_pci(a)		((unsigned long)(a))
+#define __mem_isa(a)		((unsigned long)(a))
+
+static inline unsigned __ixp_io(unsigned long p)
+{
+	unsigned long ext = *IXP2000_PCI_ADDR_EXT & 0xffff;
+
+	ext |= p & 0xffff0000;
+
+	*IXP2000_PCI_ADDR_EXT = ext;
+
+	return __ixp_io_pci(p);
+}
+
+/*
+ * Generic virtual read/write
+ */
+
+extern __inline__ unsigned int __arch_getw(unsigned long a)
+{
+	unsigned int value;
+	__asm__ __volatile__("ldr%?h	%0, [%1, #0]	@ getw"
+		: "=&r" (value)
+		: "r" (a));
+	return value;
+}
+
+extern __inline__ void __arch_putw(unsigned int value, unsigned long a)
+{
+	__asm__ __volatile__("str%?h	%0, [%1, #0]	@ putw"
+		: : "r" (value), "r" (a));
+}
+
+/*
+ * IXP2400 has a broken IO unit that does not do bytelane swapping.
+ * For this reason, we need to override the default IO functions 
+ * so that we just do raw access...
+ */
+#define __ixp_ioaddr(p) __ixp_io(p)
+
+#define outb(v,p)			__raw_writeb(v,__ixp_io(p))
+#define outw(v,p)			__raw_writew(v,__ixp_io(p))
+#define outl(v,p)			__raw_writel(v,__ixp_io(p))
+
+#define inb(p)		({ unsigned int __v = __raw_readb(__ixp_io(p)); __v; })
+#define inw(p)		\
+	({ unsigned int __v = (__raw_readw(__ixp_io(p))); __v; })
+#define inl(p)		\
+	({ unsigned int __v = (__raw_readl(__ixp_io(p))); __v; })
+
+#define outsb(p,d,l)			__raw_writesb(__ixp_io(p),d,l)
+#define outsw(p,d,l)			__raw_writesw(__ixp_io(p),d,l)
+#define outsl(p,d,l)			__raw_writesl(__ixp_io(p),d,l)
+
+#define insb(p,d,l)			__raw_readsb(__ixp_io(p),d,l)
+#define insw(p,d,l)			__raw_readsw(__ixp_io(p),d,l)
+#define insl(p,d,l)			__raw_readsl(__ixp_io(p),d,l)
+
+#define __arch_ioremap	__ioremap
+#define __arch_iounmap	__iounmap
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/io.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/io.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/io.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,89 @@
+/*
+ * linux/include/asm-arm/arch-ixdp2000/io.h
+ *
+ * Author: Naeem M Afzal <naeem.m.afzal@intel.com>
+ *
+ * Copyright (C) 2002  Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io_pci(a)		(PCIO_BASE + (a))
+#define __mem_pci(a)		((unsigned long)(a))
+#define __mem_isa(a)		((unsigned long)(a))
+
+/*
+ * We don't need this for now. If we get to the point where
+ * we need to have > 64K I/O access, we need to fix this so
+ * that it saves/restores the previous I/O window setting.
+ */
+#if 0
+static inline unsigned __ixp_io(unsigned long p)
+{
+	unsigned long ext = *IXP2000_PCI_ADDR_EXT & 0xffff;
+
+	ext |= p & 0xffff0000;
+
+	*IXP2000_PCI_ADDR_EXT = ext;
+
+	return __io_pci(p);
+}
+#endif
+
+/*
+ * Generic virtual read/write
+ */
+
+extern __inline__ unsigned int __arch_getw(unsigned long a)
+{
+	unsigned int value;
+	__asm__ __volatile__("ldr%?h	%0, [%1, #0]	@ getw"
+		: "=&r" (value)
+		: "r" (a));
+	return value;
+}
+
+extern __inline__ void __arch_putw(unsigned int value, unsigned long a)
+{
+	__asm__ __volatile__("str%?h	%0, [%1, #0]	@ putw"
+		: : "r" (value), "r" (a));
+}
+
+/*
+ * IXP2000 currently does not do bytelane or data swapping on
+ * PCI I/O cycles, so we need to override the default functions.
+ *
+ * Will retest once we have "working" silicon.
+ */
+#define alignb(addr) ((addr & ~3) + (3 - (addr & 3)))
+#define alignw(addr) ((addr & ~2) + (2 - (addr & 2)))
+
+#define outb(v,p)			__raw_writeb(v,alignb(__io_pci(p)))
+#define outw(v,p)			__raw_writew((v),alignw(__io_pci(p)))
+#define outl(v,p)			__raw_writel((v),__io_pci(p))
+
+#define inb(p)		({ unsigned int __v = __raw_readb(alignb(__io_pci(p))); __v; })
+#define inw(p)		\
+	({ unsigned int __v = (__raw_readw(alignw(__io_pci(p)))); __v; })
+#define inl(p)		\
+	({ unsigned int __v = (__raw_readl(__io_pci(p))); __v; })
+
+#define outsb(p,d,l)			__raw_writesb(alignb(__io_pci(p)),d,l)
+#define outsw(p,d,l)			__raw_writesw(alignw(__io_pci(p)),d,l)
+#define outsl(p,d,l)			__raw_writesl(__io_pci(p),d,l)
+
+#define insb(p,d,l)			__raw_readsb(alignb(__io_pci(p)),d,l)
+#define insw(p,d,l)			__raw_readsw(alignw(__io_pci(p)),d,l)
+#define insl(p,d,l)			__raw_readsl(__io_pci(p),d,l)
+
+#define __arch_ioremap	__ioremap
+#define __arch_iounmap	__iounmap
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/irq.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/irq.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/irq.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,13 @@
+/*
+ *  linux/include/asm-arm/arch-ixp2000/irq.h
+ *
+ *  Copyright (C) 2002 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define fixup_irq(irq)  (irq)
+
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/irqs.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/irqs.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/irqs.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,118 @@
+/*
+ * linux/include/asm-arm/arch-ixp2000/irqs.h
+ *
+ * Original Author:	Naeem Afzal <naeem.m.afzal@intel.com>
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright:	(C) 2002 Intel Corp.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _IRQS_H
+#define _IRQS_H
+
+/*
+ * Some interrupt numbers go unused b/c the IRQ mask/ummask/status
+ * register has those bit reserved. We just mark those interrupts
+ * as invalid and this allows us to do mask/unmask with a single
+ * shit operation instead of having to map the IRQ number to
+ * a HW IRQ number.
+ */
+#define	IRQ_IXP2000_SWI			0 /* soft interrupt */
+#define	IRQ_IXP2000_ERRSUM		1 /* OR of all bits in ErrorStatus reg*/
+#define	IRQ_IXP2000_UART		2
+#define	IRQ_IXP2000_GPIO		3
+#define	IRQ_IXP2000_TIMER1     		4
+#define	IRQ_IXP2000_TIMER2     		5
+#define	IRQ_IXP2000_TIMER3     		6
+#define	IRQ_IXP2000_TIMER4     		7
+#define	IRQ_IXP2000_PMU        		8               
+#define	IRQ_IXP2000_SPF        		9  /* Slow port framer IRQ */
+#define	IRQ_IXP2000_DMA1      		10
+#define	IRQ_IXP2000_DMA2      		11
+#define	IRQ_IXP2000_DMA3      		12
+#define	IRQ_IXP2000_PCI_DOORBELL	13
+#define	IRQ_IXP2000_ME_ATTN       	14
+#define IRQ_IXP2000_PCI			15
+#define IRQ_IXP2000_THDA0		16
+#define IRQ_IXP2000_THDA1		17
+#define IRQ_IXP2000_THDA2		18
+#define IRQ_IXP2000_THDA3		19
+#define IRQ_IXP2000_THDB0		24
+#define IRQ_IXP2000_THDB1		25
+#define IRQ_IXP2000_THDB2		26
+#define IRQ_IXP2000_THDB3		27
+
+/* define generic GPIOs */
+#define IRQ_IXP2000_GPIO0               32
+#define IRQ_IXP2000_GPIO1               33
+#define IRQ_IXP2000_GPIO2               34
+#define IRQ_IXP2000_GPIO3               35
+#define IRQ_IXP2000_GPIO4               36
+#define IRQ_IXP2000_GPIO5               37
+#define IRQ_IXP2000_GPIO6               38
+#define IRQ_IXP2000_GPIO7               39
+
+/* split off the 2 PCI sources */
+#define IRQ_IXP2000_PCIA                40
+#define IRQ_IXP2000_PCIB                41
+
+/* Int sources from IRQ_ERROR_STATUS */
+#define IRQ_IXP2000_DRAM0_MIN_ERR       42
+#define IRQ_IXP2000_DRAM0_MAJ_ERR       43
+#define IRQ_IXP2000_DRAM1_MIN_ERR       44
+#define IRQ_IXP2000_DRAM1_MAJ_ERR       45
+#define IRQ_IXP2000_DRAM2_MIN_ERR       46
+#define IRQ_IXP2000_DRAM2_MAJ_ERR       47
+#define IRQ_IXP2000_SRAM0_ERR           48
+#define IRQ_IXP2000_SRAM1_ERR           49
+#define IRQ_IXP2000_SRAM2_ERR           50
+#define IRQ_IXP2000_SRAM3_ERR           51
+#define IRQ_IXP2000_MEDIA_ERR           52
+#define IRQ_IXP2000_PCI_ERR             53
+#define IRQ_IXP2000_SP_INT              54
+
+#define NR_IXP2000_IRQS                 55
+
+#define XSCALE_PMU_IRQ			IRQ_IXP2000_PMU
+
+#if defined(CONFIG_ARCH_IXDP2400)
+/* 
+ * IXDP2400 specific IRQs
+ */
+#define	IRQ_IXDP2400(x)			(NR_IXP2000_IRQS + (x))
+
+//#define	IRQ_IXDP2400_SETHERNET		IRQ_IXDP2400(0) /* Slave NPU NIC irq */
+#define	IRQ_IXDP2400_INGRESS_NPU	IRQ_IXDP2400(0) /* Slave NPU irq */
+#define	IRQ_IXDP2400_METHERNET		IRQ_IXDP2400(1) /* Master NPU NIC irq */
+#define	IRQ_IXDP2400_MEDIA_PCI		IRQ_IXDP2400(2) /* Media on PCI irq */
+#define	IRQ_IXDP2400_MEDIA_SP		IRQ_IXDP2400(3) /* Media on SlowPort */
+#define	IRQ_IXDP2400_SF_PCI		IRQ_IXDP2400(4) /* Sw Fab. on PCI */
+#define	IRQ_IXDP2400_SF_SP		IRQ_IXDP2400(5) /* Switch Fab on SP */
+#define	IRQ_IXDP2400_PMC		IRQ_IXDP2400(6) /* PMC slot ineterrupt*/
+#define	IRQ_IXDP2400_TVM		IRQ_IXDP2400(7) /* Temp & Voltage */
+
+#define	IRQ_IXP2000_INTERRUPT   ((IRQ_IXDP2400_TVM)+1)  
+#define NR_IXDP2400_IRQS	(IRQ_IXDP2400_TVM+1)
+
+#elif defined(CONFIG_ARCH_IXDP2800)
+/* IXDP2800 specific IRQs */
+#define IRQ_IXDP2800(x)			(NR_IXP2000_IRQS + (x))
+#define IRQ_IXDP2800_EGRESS_NIC		IRQ_IXDP2800(0)
+#define IRQ_IXDP2800_INGRESS_NPU	IRQ_IXDP2800(1)
+#define IRQ_IXDP2800_PMC_PCI		IRQ_IXDP2800(2)
+#define IRQ_IXDP2800_FABRIC_PCI		IRQ_IXDP2800(3)
+#define IRQ_IXDP2800_FABRIC		IRQ_IXDP2800(4)
+#define IRQ_IXDP2800_MEDIA		IRQ_IXDP2800(5)
+
+#define IRQ_IXP2000_INTERRUPT	(IRQ_IXDP2800_MEDIA)
+#define NR_IXDP2800_IRQS	(IRQ_IXDP2800_MEDIA+1)
+#endif /* CONFIG_ARCH_XXX */
+
+#undef NR_IRQS
+#define NR_IRQS ((IRQ_IXP2000_INTERRUPT)+1)
+
+#endif /*_IRQS_H*/
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/ixdp2400.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/ixdp2400.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/ixdp2400.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/ixdp2400.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,54 @@
+/*
+ * inclue/asm-arm/arch-ixp2000/ixmb2400.h
+ *
+ * Register and other defines for IXDP2400
+ *
+ * Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ *
+ * Copyright 2002 Intel Corp.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+#ifndef _IXDP2400_H_
+#define _IXDP2400_H_
+
+
+/*
+ * On board CPLD memory map
+ */
+#define IXDP2400_PHY_CPLD_BASE	0xc7000000
+#define IXDP2400_VIRT_CPLD_BASE	0xd4000000
+#define IXDP2400_CPLD_SIZE	0x01000000
+
+
+#define IXDP2400_CPLD_REG(reg)  	(volatile unsigned long *)(IXDP2400_VIRT_CPLD_BASE | reg)
+
+#define IXDP2400_CPLD_SYSLED   		IXDP2400_CPLD_REG(0x0)  
+#define IXDP2400_CPLD_DISP_DATA        	IXDP2400_CPLD_REG(0x4)
+#define IXDP2400_CPLD_CLOCK_SPEED      	IXDP2400_CPLD_REG(0x8)
+#define IXDP2400_CPLD_INT              	IXDP2400_CPLD_REG(0xc)
+#define IXDP2400_CPLD_REV              	IXDP2400_CPLD_REG(0x10)
+#define IXDP2400_CPLD_SYS_CLK_M        	IXDP2400_CPLD_REG(0x14)
+#define IXDP2400_CPLD_SYS_CLK_N        	IXDP2400_CPLD_REG(0x18)
+#define IXDP2400_CPLD_INT_MASK         	IXDP2400_CPLD_REG(0x48)
+
+/* 
+ * Interrupt register mask bits on CPLD register 
+ */
+#define IXDP2400_MASK_INGRESS		(1<<0)
+#define IXDP2400_MASK_EGRESS_NIC	(1<<1)   /*Master Ethernet */
+#define IXDP2400_MASK_MEDIA_PCI		(1<<2) 	 /* media PCI interrupt */
+#define IXDP2400_MASK_MEDIA_SP		(1<<3)   /* media slow port interrupt*/
+#define IXDP2400_MASK_SF_PCI		(1<<4)   /* Sw Fabric PCI intrpt */
+#define IXDP2400_MASK_SF_SP		(1<<5)   /* SW Fabric SlowPort intrpt */
+#define IXDP2400_MASK_PMC		(1<<6)
+#define IXDP2400_MASK_TVM		(1<<7)
+
+#define	IXDP2400_GPIO_I2C_ENABLE	0x02
+#define	IXDP2400_GPIO_SCL		0x07
+#define	IXDP2400_GPIO_SDA		0x06
+
+#endif /*_IXDP2400_H_ */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/ixdp2800.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/ixdp2800.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/ixdp2800.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/ixdp2800.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ * inclue/asm-arm/arch-ixp2000/ixdp2800.h
+ *
+ * Register and other defines for IXDP2800
+ *
+ * Author: Jeff Daly <jeffrey.daly@intel.com>
+ *
+ * Copyright 2002-2003 Intel Corp.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+#ifndef _IXDP2800_H_
+#define _IXDP2800_H_
+
+/* CPLD interrupt register definition */
+#define IXDP2800_PHY_CPLD_BASE		0xc7000000
+#define IXDP2800_VIRT_CPLD_BASE		0xd4000000
+#define IXDP2800_CPLD_SIZE		0x01000000
+
+#define IXDP2800_CPLD			IXDP2800_VIRT_CPLD_BASE
+
+#define IXDP2800_CPLD_REG(reg)		(volatile u32 *)(IXDP2800_CPLD | reg)
+
+#define IXDP2800_CPLD_INT		IXDP2800_CPLD_REG(0x0)
+#define IXDP2800_CPLD_INT_MASK		IXDP2800_CPLD_REG(0x140)
+
+/* 
+ *  * Interrupt register mask bits on CPLD register 
+ *   */
+#define IXDP2800_MASK_EGRESS_NIC	(1<<0)	/*Master Ethernet */
+#define IXDP2800_MASK_INGRESS		(1<<1)
+#define IXDP2800_MASK_PMC		(1<<2)
+#define IXDP2800_MASK_FABRIC_PCI	(1<<3)	/* Sw Fabric PCI intrpt */
+#define IXDP2800_MASK_FABRIC_SP		(1<<4)	/* SW Fabric SlowPort intrpt */
+#define IXDP2800_MASK_MEDIA		(1<<5)	/* media slow port interrupt */
+
+/* LED defines */
+#define IXDP2800_LED0_REG		IXDP2800_CPLD_REG(0x10c)
+#define IXDP2800_LED1_REG		IXDP2800_CPLD_REG(0x108)
+#define IXDP2800_LED2_REG		IXDP2800_CPLD_REG(0x104)
+#define IXDP2800_LED3_REG		IXDP2800_CPLD_REG(0x100)
+
+#define IXDP2800_GPIO_I2C_ENABLE	0x05
+#define IXDP2800_GPIO_SCL		0x07
+#define IXDP2800_GPIO_SDA		0x06
+
+#endif /*_IXDP2800_H_ */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/ixp2000.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/ixp2000.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/ixp2000.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/ixp2000.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,535 @@
+/*
+ * include/asm-arm/arch-ixp2000/ixp2000.h
+ *
+ * Generic register definitions for IXP2000 based systems.
+ *
+ * Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2002 Intel Corp.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+#ifndef _IXP2000_H_
+#define _IXP2000_H_
+
+#ifndef __ASM_ARCH_HARDWARE_H__
+#error "Do not include this file directly. Instead include <asm/hardware.h>"
+#endif
+
+#ifndef BIT
+#define BIT(bit)	(1 << (bit))
+#endif
+
+#define PHYS_SDRAM_BASE		0x1c000000 /* start for upper 64M */
+#define INITRD_LOCATION		0x1c600000 
+#define INITRD_SIZE		0x00400000 
+#define PHYS_SDRAM_SIZE		(64*1024*1024)
+
+#define FLASH_BASE	0xc4000000
+#define MAX_FLASH_SIZE	0x04000000
+
+/* 
+ * Static I/O regions. The manual defines each region as being several
+ * MB in size, but all the registers are within the first 4K, so there's
+ * no purpose in mapping the whole region in.
+ */
+
+#define PMU_PHYS_BASE		0xc0050000
+#define PMU_VIRT_BASE		0xfaff7000
+#define PMU_SIZE		0x1000
+
+#define	GLOBAL_REG_PHYS_BASE	0xc0004000
+#define	GLOBAL_REG_VIRT_BASE	0xfaff8000
+#define	GLOBAL_REG_SIZE		0x1000
+
+#define	GPIO_PHYS_BASE		0xc0010000
+#define	GPIO_VIRT_BASE		0xfaff9000
+#define	GPIO_SIZE		0x1000
+
+#define	TIMER_PHYS_BASE		0xc0020000
+#define	TIMER_VIRT_BASE		0xfaffa000
+#define	TIMER_SIZE		0x1000
+
+#define	UART_PHYS_BASE		0xc0030000
+#define	UART_VIRT_BASE		0xfaffb000
+#define UART_SIZE		0x1000
+
+#define	SLOWPORT_CSR_PHYS_BASE	0xc0080000
+#define	SLOWPORT_CSR_VIRT_BASE	0xfaffc000
+#define	SLOWPORT_CSR_SIZE	0x1000
+
+#define INTCTL_PHYS_BASE	0xd6000000
+#define	INTCTL_VIRT_BASE	0xfaffd000
+#define	INTCTL_SIZE		0x01000
+
+#define PCI_CREG_PHYS_BASE	0xde000000
+#define	PCI_CREG_VIRT_BASE	0xfaffe000
+#define	PCI_CREG_SIZE		0x1000
+
+#define PCI_CSR_PHYS_BASE	0xdf000000
+#define	PCI_CSR_VIRT_BASE	0xfafff000
+#define	PCI_CSR_SIZE		0x1000
+
+#define PCI_CFG0_PHYS_BASE	0xda000000
+#define PCI_CFG0_VIRT_BASE	0xfb000000
+#define PCI_CFG0_SIZE   	0x01000000
+
+#define PCI_CFG1_PHYS_BASE	0xdb000000
+#define PCI_CFG1_VIRT_BASE	0xfc000000
+#define PCI_CFG1_SIZE		0x01000000
+
+#define PCI_IO_PHYS_BASE	0xd8000000
+#define	PCI_IO_VIRT_BASE	0xfd000000
+#define PCI_IO_SIZE     	0x02000000
+
+/*
+ * This is needed for all I/O (CB=00) due to an errata in IXP2400:
+ *
+ * We block interrupts b/c this must be atomic.
+ *
+ */
+#if 0
+#ifndef __ASSEMBLY__
+#if defined(CONFIG_ARCH_IXDP2400) || defined(CONFIG_ARCH_IXDP2401) 
+static inline void ixp_reg_write(volatile unsigned long *reg, unsigned long val)
+{
+	volatile unsigned long dummy;
+	unsigned long flags;
+
+
+	local_irq_save(flags);
+	*reg = val;
+	mb();
+	dummy = *reg;
+	local_irq_restore(flags);
+}
+#else
+#define	ixp2000_reg_write(reg, val) (*reg = val);
+#endif	// IXP2400
+#endif	// __ASSEMBLY__
+#endif
+
+#define	ixp_reg_write(reg, val) (*reg = val)
+
+/* 
+ * Timers
+ */
+#define	IXP2000_TIMER_REG(x)   ((volatile unsigned long*)(TIMER_VIRT_BASE+(x)))
+/* Timer control */
+#define	IXP2000_T1_CTL    	IXP2000_TIMER_REG(0x00)    
+#define	IXP2000_T2_CTL		IXP2000_TIMER_REG(0x04)
+#define	IXP2000_T3_CTL		IXP2000_TIMER_REG(0x08)
+#define	IXP2000_T4_CTL		IXP2000_TIMER_REG(0x0c)
+/* Store initial value */
+#define	IXP2000_T1_CLD    	IXP2000_TIMER_REG(0x10)    
+#define	IXP2000_T2_CLD    	IXP2000_TIMER_REG(0x14)    
+#define	IXP2000_T3_CLD    	IXP2000_TIMER_REG(0x18)    
+#define	IXP2000_T4_CLD    	IXP2000_TIMER_REG(0x1c)    
+/* Read current value */
+#define	IXP2000_T1_CSR    	IXP2000_TIMER_REG(0x20)    
+#define	IXP2000_T2_CSR    	IXP2000_TIMER_REG(0x24)    
+#define	IXP2000_T3_CSR    	IXP2000_TIMER_REG(0x28)    
+#define	IXP2000_T4_CSR    	IXP2000_TIMER_REG(0x2c)    
+/* Clear associated timer interrupt */
+#define	IXP2000_T1_CLR		IXP2000_TIMER_REG(0x30)    
+#define	IXP2000_T2_CLR		IXP2000_TIMER_REG(0x34)    
+#define	IXP2000_T3_CLR		IXP2000_TIMER_REG(0x38)    
+#define	IXP2000_T4_CLR		IXP2000_TIMER_REG(0x3c)    
+/* Timer watchdog enable for T4 */
+#define  IXP2000_TWDE		IXP2000_TIMER_REG(0x40)   
+
+
+/*
+ * Interrupt controller registers
+ */
+#define IXP2000_INTCTL_REG(reg) (volatile unsigned long*)(INTCTL_VIRT_BASE | reg)
+#define IXP2000_IRQ_STATUS   	IXP2000_INTCTL_REG(0x08)
+#define IXP2000_IRQ_ENABLE     	IXP2000_INTCTL_REG(0x10)
+#define IXP2000_IRQ_ENABLE_SET 	IXP2000_INTCTL_REG(0x10)
+#define IXP2000_IRQ_ENABLE_CLR 	IXP2000_INTCTL_REG(0x18)
+#define IXP2000_FIQ_ENABLE_CLR 	IXP2000_INTCTL_REG(0x14)
+#define IXP2000_IRQ_ERR_STATUS 	IXP2000_INTCTL_REG(0x24)
+#define IXP2000_IRQ_ERR_ENABLE_SET	IXP2000_INTCTL_REG(0x2c)
+#define IXP2000_FIQ_ERR_ENABLE_CLR	IXP2000_INTCTL_REG(0x30)
+#define IXP2000_IRQ_ERR_ENABLE_CLR	IXP2000_INTCTL_REG(0x34)
+
+/* 
+ * IRQ mask/unmask bits. These map 1:1 to IRQ number
+ */
+#define IRQ_MASK_SOFT           (1 << 0)
+#define IRQ_MASK_ERRSUM         (1 << 1)
+#define IRQ_MASK_UART           (1 << 2)
+#define IRQ_MASK_GPIO           (1 << 3)
+#define IRQ_MASK_TIMER1         (1 << 4)
+#define IRQ_MASK_TIMER2         (1 << 5)
+#define IRQ_MASK_TIMER3         (1 << 6)
+#define IRQ_MASK_TIMER4         (1 << 7)
+#define IRQ_MASK_PMU            (1 << 8)
+#define IRQ_MASK_SPF            (1 << 9) /* Slowport Framer */
+#define IRQ_MASK_DMA1_DONE      (1 << 10)
+#define IRQ_MASK_DMA2_DONE      (1 << 11)
+#define IRQ_MASK_DMA3_DONE      (1 << 12)
+#define IRQ_MASK_DOORBELL	(1 << 13) /* PCI Doorbell */
+#define IRQ_MASK_UENG           (1 << 14) /* ME attention */
+#define IRQ_MASK_PCI            (1 << 15) /* OR of INTA or INTB */
+#define IRQ_MASK_THDA0          (1 << 16) /* ThreadA 0-31 */
+#define IRQ_MASK_THDA1          (1 << 17) /* ThreadA 32-63 */
+#define IRQ_MASK_THDA2          (1 << 18) /* ThreadA 64-95 */
+#define IRQ_MASK_THDA3          (1 << 19) /* ThreadA 96-127 */
+#define IRQ_MASK_THDB0          (1 << 24) /* ThreadB 0-31 */
+#define IRQ_MASK_THDB1          (1 << 25) /* ThreadB 32-63 */
+#define IRQ_MASK_THDB2          (1 << 26) /* ThreadB 64-95 */
+#define IRQ_MASK_THDB3          (1 << 27) /* ThreadB 96-127 */
+
+/*
+ * Mask of valid IRQs in the 32-bit IRQ register. We use
+ * this to mark certain IRQs as being in-valid.
+ */
+#define	IXP2000_VALID_IRQ_MASK	0x0f0f8fff
+
+/*
+ * 16550 UART
+ */
+#define IXP2000_UART_BASE 	UART_VIRT_BASE
+
+/*
+ * PCI config register access from core
+ */
+#define IXP2000_PCI_CREG(reg)	(volatile unsigned long*)(PCI_CREG_VIRT_BASE | reg)
+#define IXP2000_PCI_CMDSTAT 	IXP2000_PCI_CREG(0x04)
+#define IXP2000_PCI_CSR_BAR	IXP2000_PCI_CREG(0x10)
+#define IXP2000_PCI_SRAM_BAR	IXP2000_PCI_CREG(0x14)
+#define IXP2000_PCI_SDRAM_BAR	IXP2000_PCI_CREG(0x18)
+
+/*
+ * PCI CSRs
+ */
+#define IXP2000_PCI_CSR(reg)	(volatile unsigned long*)(PCI_CSR_VIRT_BASE | reg)
+
+/*
+ * PCI outbound interrupts
+ */
+#define IXP2000_PCI_OUT_INT_STATUS   	IXP2000_PCI_CSR(0x30)
+#define IXP2000_PCI_OUT_INT_MASK        IXP2000_PCI_CSR(0x34)
+/*
+ * PCI communications
+ */
+#define IXP2000_PCI_MAILBOX0            IXP2000_PCI_CSR(0x50)
+#define IXP2000_PCI_MAILBOX1            IXP2000_PCI_CSR(0x54)
+#define IXP2000_PCI_MAILBOX2            IXP2000_PCI_CSR(0x58)
+#define IXP2000_PCI_MAILBOX3            IXP2000_PCI_CSR(0x5C)
+#define IXP2000_XSCALE_DOORBELL         IXP2000_PCI_CSR(0x60)
+#define IXP2000_XSCALE_DOORBELL_SETUP   IXP2000_PCI_CSR(0x64)
+#define IXP2000_PCI_DOORBELL            IXP2000_PCI_CSR(0x70)
+#define IXP2000_PCI_DOORBELL_SETUP  	IXP2000_PCI_CSR(0x74)
+
+/*
+ * DMA engines
+ */
+#define IXP2000_PCI_CH1_BYTE_CNT        IXP2000_PCI_CSR(0x80)
+#define IXP2000_PCI_CH1_ADDR            IXP2000_PCI_CSR(0x84)
+#define IXP2000_PCI_CH1_DRAM_ADDR    	IXP2000_PCI_CSR(0x88)
+#define IXP2000_PCI_CH1_DESC_PTR        IXP2000_PCI_CSR(0x8C)
+#define IXP2000_PCI_CH1_CNTRL           IXP2000_PCI_CSR(0x90)
+#define IXP2000_PCI_CH1_ME_PARAM        IXP2000_PCI_CSR(0x94)
+#define IXP2000_PCI_CH2_BYTE_CNT        IXP2000_PCI_CSR(0xA0)
+#define IXP2000_PCI_CH2_ADDR            IXP2000_PCI_CSR(0xA4)
+#define IXP2000_PCI_CH2_DRAM_ADDR    	IXP2000_PCI_CSR(0xA8)
+#define IXP2000_PCI_CH2_DESC_PTR        IXP2000_PCI_CSR(0xAC)
+#define IXP2000_PCI_CH2_CNTRL           IXP2000_PCI_CSR(0xB0)
+#define IXP2000_PCI_CH2_ME_PARAM        IXP2000_PCI_CSR(0xB4)
+#define IXP2000_PCI_CH3_BYTE_CNT        IXP2000_PCI_CSR(0xC0)
+#define IXP2000_PCI_CH3_ADDR            IXP2000_PCI_CSR(0xC4)
+#define IXP2000_PCI_CH3_DRAM_ADDR    	IXP2000_PCI_CSR(0xC8)
+#define IXP2000_PCI_CH3_DESC_PTR        IXP2000_PCI_CSR(0xCC)
+#define IXP2000_PCI_CH3_CNTRL           IXP2000_PCI_CSR(0xD0)
+#define IXP2000_PCI_CH3_ME_PARAM        IXP2000_PCI_CSR(0xD4)
+#define IXP2000_DMA_INF_MODE         	IXP2000_PCI_CSR(0xE0)
+/*
+ * Size masks for BARs
+ */
+#define IXP2000_PCI_SRAM_BASE_ADDR_MASK IXP2000_PCI_CSR(0xFC)
+#define IXP2000_PCI_DRAM_BASE_ADDR_MASK IXP2000_PCI_CSR(0x100)
+/*
+ * Control and uEngine related
+ */
+#define IXP2000_PCI_CONTROL             IXP2000_PCI_CSR(0x13C)
+#define IXP2000_PCI_ADDR_EXT            IXP2000_PCI_CSR(0x140)
+#define IXP2000_PCI_ME_PUSH_STATUS   	IXP2000_PCI_CSR(0x148)
+#define IXP2000_PCI_ME_PUSH_EN          IXP2000_PCI_CSR(0x14C)
+#define IXP2000_PCI_ERR_STATUS          IXP2000_PCI_CSR(0x150)
+#define IXP2000_PCI_ERR_ENABLE          IXP2000_PCI_CSR(0x154)
+/*
+ * Inbound PCI interrupt control
+ */
+#define IXP2000_PCI_XSCALE_INT_STATUS   IXP2000_PCI_CSR(0x158)
+#define IXP2000_PCI_XSCALE_INT_ENABLE   IXP2000_PCI_CSR(0x15C)
+
+#define IXP2000_PCICNTL_PNR	(1<<17)	/* PCI not Reset bit of PCI_CONTROL */
+#define IXP2000_PCICNTL_PCF	(1<<28)	/* PCI Centrolfunction bit */
+#define IXP2000_XSCALE_INT	(1<<1)	/* Interrupt from  XScale to PCI */
+
+/* These are from the IRQ register in the PCI ISR register */
+#define PCI_CONTROL_BE_DEO      (1 << 22) /* Big Endian Data Enable Out */
+#define PCI_CONTROL_BE_DEI      (1 << 21) /* Big Endian Data Enable In  */
+#define PCI_CONTROL_BE_BEO      (1 << 20) /* Big Endian Byte Enable Out */
+#define PCI_CONTROL_BE_BEI      (1 << 19) /* Big Endian Byte Enable In  */
+#define PCI_CONTROL_PNR         (1 << 17) /* PCI Not Reset bit of SA_CONTROL */
+
+
+#define IXP2000_PCI_RST_REL  	(1 << 2) 
+#define CFG_RST_DIR  		(*IXP2000_PCI_CONTROL & IXP2000_PCICNTL_PCF) 
+#define CFG_PCI_BOOT_HOST       (1 << 2)
+#define CFG_BOOT_PROM           (1 << 1)
+
+
+/*
+ * SlowPort CSRs
+ *
+ * The slowport is used to access things like flash, SONET framer control
+ * ports, slave microprocessors, CPLDs, and others of chip memory mapped
+ * peripherals.
+ */
+#define	SLOWPORT_CSR(reg)	(volatile unsigned long*)(SLOWPORT_CSR_VIRT_BASE | reg)
+
+#define	IXP2000_SLOWPORT_CCR		SLOWPORT_CSR(0x00)
+#define	IXP2000_SLOWPORT_WTC1		SLOWPORT_CSR(0x04)
+#define	IXP2000_SLOWPORT_WTC2		SLOWPORT_CSR(0x08)
+#define	IXP2000_SLOWPORT_RTC1		SLOWPORT_CSR(0x0c)
+#define	IXP2000_SLOWPORT_RTC2		SLOWPORT_CSR(0x10)
+#define	IXP2000_SLOWPORT_FSR		SLOWPORT_CSR(0x14)
+#define	IXP2000_SLOWPORT_PCR		SLOWPORT_CSR(0x18)
+#define	IXP2000_SLOWPORT_ADC		SLOWPORT_CSR(0x1C)
+#define	IXP2000_SLOWPORT_FAC		SLOWPORT_CSR(0x20)
+#define	IXP2000_SLOWPORT_FRM		SLOWPORT_CSR(0x24)
+#define	IXP2000_SLOWPORT_FIN		SLOWPORT_CSR(0x28)
+
+/*
+ * CCR values.  
+ * The CCR configures the clock division for the slowport interface.
+ */
+#define	SLOWPORT_CCR_DIV_1	0x00
+#define	SLOWPORT_CCR_DIV_2	0x01
+#define	SLOWPORT_CCR_DIV_4	0x02
+#define	SLOWPORT_CCR_DIV_6	0x03
+#define	SLOWPORT_CCR_DIV_8	0x04
+#define	SLOWPORT_CCR_DIV_10	0x05
+#define	SLOWPORT_CCR_DIV_12	0x06
+#define	SLOWPORT_CCR_DIV_14	0x07
+#define	SLOWPORT_CCR_DIV_16	0x08
+#define	SLOWPORT_CCR_DIV_18	0x09
+#define	SLOWPORT_CCR_DIV_20	0x0a
+#define	SLOWPORT_CCR_DIV_22	0x0b
+#define	SLOWPORT_CCR_DIV_24	0x0c
+#define	SLOWPORT_CCR_DIV_26	0x0d
+#define	SLOWPORT_CCR_DIV_28	0x0e
+#define	SLOWPORT_CCR_DIV_30	0x0f
+
+/*
+ * PCR values.  PCR configure the mode of the interfac3
+ */
+#define	SLOWPORT_MODE_FLASH		0x00	
+#define	SLOWPORT_MODE_LUCENT		0x01
+#define	SLOWPORT_MODE_PMC_SIERRA	0x02
+#define	SLOWPORT_MODE_INTEL_UP		0x03
+#define	SLOWPORT_MODE_MOTOROLA_UP	0x04
+
+/*
+ * ADC values.  Defines data and address bus widths
+ */
+#define	SLOWPORT_ADDR_WIDTH_8		0x0000
+#define	SLOWPORT_ADDR_WIDTH_16		0x0001
+#define	SLOWPORT_ADDR_WIDTH_24		0x0002
+#define	SLOWPORT_ADDR_WIDTH_32		0x0003
+#define	SLOWPORT_DATA_WIDTH_8		0x0000
+#define	SLOWPORT_DATA_WIDTH_16		0x0100
+#define	SLOWPORT_DATA_WIDTH_24		0x0200
+#define	SLOWPORT_DATA_WIDTH_32		0x0300
+
+/*
+ * Masks and shifts for various fields in the WTC and RTC registers
+ */
+#define	SLOWPORT_WRTC_MASK_HD		0x0003
+#define	SLOWPORT_WRTC_MASK_SU		0x003c
+#define	SLOWPORT_WRTC_MASK_PW		0x03c0
+
+#define	SLOWPORT_WRTC_SHIFT_HD		0x00
+#define	SLOWPORT_WRTC_SHIFT_SU		0x02
+#define	SLOWPORT_WRTC_SHFIT_PW		0x06
+
+
+/*
+ * Boards may multiplex different devices on the 2nd channel of 
+ * the slowport interface that each need different configuration 
+ * settings.  For example, the IXDP2400 uses channel 2 on the interface 
+ * to access the CPLD, the switch fabric card, and te media card.  Each 
+ * one needs a different mode so drivers must save/restore the mode 
+ * before and after each operation.  
+ *
+ * acquire_slowport(&your_config);
+ * ...
+ * do slowport operations
+ * ...
+ * release_slowport();
+ *
+ * Note that while you have the slowport, you are holding a spinlock,
+ * so do not do anything you would not normally do if you had explicitly
+ * acquired any lock.  
+ *
+ * The configuration only affects device 2 on the slowport, so the
+ * MTD map driver does not acquire/release the slowport.  
+ */
+#ifndef __ASSEMBLY__
+struct slowport_cfg {
+	unsigned long	CCR;		/* Clock divide */
+	unsigned long 	WTC;		/* Write Timing Control */
+	unsigned long	RTC;		/* Read Timing Control */
+	unsigned long	PCR;		/* Protocol Control Register */	
+	unsigned long	ADC;		/* Address/Data Width Control */
+};
+
+void acquire_slowport(struct slowport_cfg *);
+void release_slowport(void);
+#endif
+
+/*
+ * GPIO registers & GPIO interface
+ */
+#define IXP2000_GPIO_REG(x)   ((volatile unsigned long*)(GPIO_VIRT_BASE+(x))) 
+#define IXP2000_GPIO_PLR        IXP2000_GPIO_REG(0x00)
+#define IXP2000_GPIO_PDPR       IXP2000_GPIO_REG(0x04)
+#define IXP2000_GPIO_PDSR       IXP2000_GPIO_REG(0x08)
+#define IXP2000_GPIO_PDCR       IXP2000_GPIO_REG(0x0c)
+#define IXP2000_GPIO_POPR       IXP2000_GPIO_REG(0x10)
+#define IXP2000_GPIO_POSR       IXP2000_GPIO_REG(0x14)
+#define IXP2000_GPIO_POCR       IXP2000_GPIO_REG(0x18)
+#define IXP2000_GPIO_REDR       IXP2000_GPIO_REG(0x1c)
+#define IXP2000_GPIO_FEDR       IXP2000_GPIO_REG(0x20)
+#define IXP2000_GPIO_EDSR       IXP2000_GPIO_REG(0x24)
+#define IXP2000_GPIO_LSHR       IXP2000_GPIO_REG(0x28)
+#define IXP2000_GPIO_LSLR       IXP2000_GPIO_REG(0x2c)
+#define IXP2000_GPIO_LDSR       IXP2000_GPIO_REG(0x30)
+#define IXP2000_GPIO_INER       IXP2000_GPIO_REG(0x34)
+#define IXP2000_GPIO_INSR       IXP2000_GPIO_REG(0x38)
+#define IXP2000_GPIO_INCR       IXP2000_GPIO_REG(0x3c)
+#define IXP2000_GPIO_INST       IXP2000_GPIO_REG(0x40)
+
+/*
+ * PMU (performance monitoring)
+ */
+#define IXP2000_PMU_REG(x)	((volatile unsigned long*)(PMU_VIRT_BASE+(x)))
+#define IXP2000_PMU_CHAPCMD0    IXP2000_PMU_REG(0x000)
+#define IXP2000_PMU_CHAPEVN0    IXP2000_PMU_REG(0x004)
+#define IXP2000_PMU_CHAPSTAT0   IXP2000_PMU_REG(0x008)
+#define IXP2000_PMU_CHAPDATA0   IXP2000_PMU_REG(0x00c)
+#define IXP2000_PMU_CHAPCMD1    IXP2000_PMU_REG(0x010)
+#define IXP2000_PMU_CHAPEVN1    IXP2000_PMU_REG(0x014)
+#define IXP2000_PMU_CHAPSTAT1   IXP2000_PMU_REG(0x018)
+#define IXP2000_PMU_CHAPDATA1   IXP2000_PMU_REG(0x01c)
+#define IXP2000_PMU_CHAPCMD2    IXP2000_PMU_REG(0x020)
+#define IXP2000_PMU_CHAPEVN2    IXP2000_PMU_REG(0x024)
+#define IXP2000_PMU_CHAPSTAT2   IXP2000_PMU_REG(0x028)
+#define IXP2000_PMU_CHAPCMD3    IXP2000_PMU_REG(0x030)
+#define IXP2000_PMU_CHAPEVN3    IXP2000_PMU_REG(0x034)
+#define IXP2000_PMU_CHAPSTAT3   IXP2000_PMU_REG(0x038)
+#define IXP2000_PMU_CHAPCMD4    IXP2000_PMU_REG(0x040)
+#define IXP2000_PMU_CHAPEVN4    IXP2000_PMU_REG(0x044)
+#define IXP2000_PMU_CHAPSTAT4   IXP2000_PMU_REG(0x048)
+#define IXP2000_PMU_CHAPCMD5    IXP2000_PMU_REG(0x050)
+#define IXP2000_PMU_CHAPEVN5    IXP2000_PMU_REG(0x054)
+#define IXP2000_PMU_CHAPSTAT5   IXP2000_PMU_REG(0x058)
+#define IXP2000_PMU_PMUINTEN    IXP2000_PMU_REG(0xc00)
+#define IXP2000_PMU_PMUINTMSK   IXP2000_PMU_REG(0xd00)
+#define IXP2000_PMU_PMUINTSTAT  IXP2000_PMU_REG(0xe00)
+#define IXP2000_PMU_PMUCFG      IXP2000_PMU_REG(0xf00)
+
+/* PMU CHAP Event bits */
+#define PMU_CHAPEVN_DDBS(x)     ((x) << 16)     /* Dec Design BlockSel */
+#define PMU_CHAPEVN_DDBS_PMU    (PMU_CHAPEVN_DDBS(1))   /* Design Block PMU */
+#define PMU_CHAPEVN_DEC0_MUX(x) ((x) << 23)             /* Dec0 Mux Select */
+#define PMU_CHAPEVN_DEC0_MUX_NULL (PMU_CHAPEVN_DEC0_MUX(7)) /* Dec every cycle */
+
+/* PMU CHAP Command bits */
+#define PMU_CHAPCMD_ACTIVATE    (1 << 0)
+#define PMU_CHAPCMD_OP(x)       ((x) << 16)
+#define PMU_CHAPCMD_STOP        (PMU_CHAPCMD_OP(0))
+#define PMU_CHAPCMD_START       (PMU_CHAPCMD_OP(1))
+#define PMU_CHAPCMD_SAMPLE      (PMU_CHAPCMD_OP(2))
+#define PMU_CHAPCMD_RESET       (PMU_CHAPCMD_OP(4))
+#define PMU_CHAPCMD_RESTART     (PMU_CHAPCMD_OP(5))
+#define PMU_CHAPCMD_SAMPLERESTART       (PMU_CHAPCMD_OP(6))
+#define PMU_CHAPCMD_PRELOAD     (PMU_CHAPCMD_OP(15))
+#define PMU_CHAPCMD_SAC         (1 << 20)
+#define PMU_CHAPCMD_CC(x)       ((x) << 21)             /* condition codes */
+#define PMU_CHAPCMD_FALSE       (PMU_CHAPCMD_CC(0))
+#define PMU_CHAPCMD_GT          (PMU_CHAPCMD_CC(1))
+#define PMU_CHAPCMD_EQ          (PMU_CHAPCMD_CC(2))
+#define PMU_CHAPCMD_GTE         (PMU_CHAPCMD_CC(3))
+#define PMU_CHAPCMD_LT          (PMU_CHAPCMD_CC(4))
+#define PMU_CHAPCMD_NE          (PMU_CHAPCMD_CC(5))
+#define PMU_CHAPCMD_LTE         (PMU_CHAPCMD_CC(6))
+#define PMU_CHAPCMD_TRUE        (PMU_CHAPCMD_CC(7))
+#define PMU_CHAPCMD_THIE        (1 << 24)               /* Threshold */
+#define PMU_CHAPCMD_CTIE        (1 << 25)               /* Cmd trigger */
+#define PMU_CHAPCMD_OUIE        (1 << 26)               /* Over/underflow */
+
+/* PMU CFG */
+#define PMU_PMUCFG_AUTOCFG      (1 << 18)               /* Reinit(?) the PMU */
+/* PMU INTSTAT */
+#define PMU_PMUINTSTAT_TCD      (1 << 31)               /* Init complete */
+
+/*
+ * "Global" registers...whatever that's supposed to mean.
+ */
+#define GLOBAL_REG_BASE		(GLOBAL_REG_VIRT_BASE + 0x0a00)
+#define GLOBAL_REG(reg)		(volatile unsigned long*)(GLOBAL_REG_BASE | reg)
+#define IXP2000_RESET0      	GLOBAL_REG(0x0c)
+#define IXP2000_RESET1      	GLOBAL_REG(0x10)
+#define IXP2000_CCR            	GLOBAL_REG(0x14)
+#define	IXP2000_STRAP_OPTIONS  	GLOBAL_REG(0x18)
+
+#define	IXP2400_CPU_ID		0x69054190
+#define	IXP2400_CPU_MASK	0xfffffff0
+
+#define	IXP2800_CPU_ID		0x690541a0
+#define	IXP2800_CPU_MASK	0xfffffff0
+
+#define RSTALL           	(1 << 16)
+
+#ifndef __ASSEMBLY__
+static inline unsigned int npu_has_flash(void)
+{
+        return  ((*IXP2000_STRAP_OPTIONS) & (CFG_BOOT_PROM));
+}
+
+static inline unsigned int npu_is_pcimaster(void)
+{
+        return ((*IXP2000_STRAP_OPTIONS) & (CFG_PCI_BOOT_HOST));
+}
+
+static inline unsigned int npu_is_master(void)
+{
+        return ((npu_has_flash()) && (npu_is_pcimaster()) );
+}
+
+/*
+ * IXP2400 A0/A1 and all IXP2800 have broken slowport
+ */
+static inline unsigned npu_has_broken_slowport(void)
+{
+	extern unsigned int processor_id;
+
+	return (((processor_id & IXP2800_CPU_MASK) == IXP2800_CPU_ID) || 
+		(((processor_id & IXP2400_CPU_MASK) == IXP2400_CPU_ID)
+		 && !(processor_id & 0xf)));
+}
+
+
+#endif
+
+#endif /* _IXP2000_H_ */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/leds.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/leds.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/leds.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/leds.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,77 @@
+/*
+ * inclue/asm-arm/arch-ixp2000/leds.h
+ *
+ * Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ *
+ * Copyright 2002 Intel Corp.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+*/
+
+#ifndef _LEDS_H_
+#define _LEDS_H_
+// encodings for the 4 char alphanum display
+#define DISPLAY_NULL				0x20
+#define DISPLAY_0					0x30
+#define DISPLAY_1					0x31
+#define DISPLAY_2					0x32
+#define DISPLAY_3					0x33
+#define DISPLAY_4					0x34
+#define DISPLAY_5					0x35
+#define DISPLAY_6					0x36
+#define YISPLAY_7					0x37
+#define	DISPLAY_8					0x38
+#define DISPLAY_9					0x39
+#define DISPLAY_A					0x41
+#define DISPLAY_B					0x42
+#define DISPLAY_C					0x43
+#define DISPLAY_D					0x44
+#define DISPLAY_E					0x45
+#define DISPLAY_F					0x46
+#define DISPLAY_G					0x47
+#define DISPLAY_H					0x48
+#define DISPLAY_I					0x49
+#define DISPLAY_J					0x4A
+#define DISPLAY_K					0x4B
+#define DISPLAY_L					0x4C
+#define DISPLAY_M					0x4D
+#define DISPLAY_N					0x4E
+#define DISPLAY_O					0x4F
+#define DISPLAY_P					0x50
+#define DISPLAY_Q					0x51
+#define DISPLAY_R					0x52
+#define DISPLAY_S					0x53
+#define DISPLAY_T					0x54
+#define DISPLAY_U					0x55
+#define DISPLAY_V					0x56
+#define DISPLAY_W					0x57
+#define DISPLAY_X					0x58
+#define DISPLAY_Y					0x59
+#define DISPLAY_Z					0x5A
+
+#define LEDDATA0         (VIRT_CPLD_CSR + 0x04)
+#define LEDDATA1         (VIRT_CPLD_CSR + 0x05)
+#define LEDDATA2         (VIRT_CPLD_CSR + 0x06)
+#define LEDDATA3         (VIRT_CPLD_CSR + 0x07)
+
+
+/* Set the a char to LED */
+#ifdef __ARMEB__
+#define SETLED3(p)     {  *(volatile unsigned char *)LEDDATA3=p; };
+#define SETLED2(p)     {  *(volatile unsigned char *)LEDDATA2=p; };
+#define SETLED1(p)     {  *(volatile unsigned char *)LEDDATA1=p; };
+#define SETLED0(p)     {  *(volatile unsigned char *)LEDDATA0=p; };
+#else
+#define SETLED0(p)     {  *(volatile unsigned char *)LEDDATA3=p; };
+#define SETLED1(p)     {  *(volatile unsigned char *)LEDDATA2=p; };
+#define SETLED2(p)     {  *(volatile unsigned char *)LEDDATA1=p; };
+#define SETLED3(p)     {  *(volatile unsigned char *)LEDDATA0=p; };
+#endif
+
+#define DISPLAY_LEDS(a,b,c,d) {SETLED0(a);SETLED1(b);SETLED2(c);SETLED3(d); }
+
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/memory.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/memory.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/memory.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,66 @@
+/*
+ * linux/include/asm-arm/arch-ixdp2400/memory.h
+ *
+ * Copyright (c) 2002 Intel Corp.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <asm/hardware.h>
+
+/*
+ * Task size: 1GB
+ */
+#define TASK_SIZE	((unsigned long)(CONFIG_KERNEL_START & 0xffc00000))
+#define TASK_SIZE_26	(0x04000000UL)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+#define PAGE_OFFSET	((unsigned long)(CONFIG_KERNEL_START & 0xffc00000))
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET	(0x1c000000UL)
+
+/*
+ * physical vs virtual ram conversion
+ */
+#define __virt_to_phys__is_a_macro
+#define __phys_to_virt__is_a_macro
+
+
+#define __virt_to_phys(x)	((x) - PAGE_OFFSET + PHYS_OFFSET)
+#define __phys_to_virt(x)	((x) - PHYS_OFFSET + PAGE_OFFSET)
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *		address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *		to an address that the kernel can use.
+ */
+
+// #define __virt_to_bus__is_a_macro
+//#define __virt_to_bus(v)        
+
+static inline unsigned int __virt_to_bus(unsigned v)
+{
+        return ((__virt_to_phys(v) - 0x0) + (*IXP2000_PCI_SDRAM_BAR & 0xfffffff0));
+}
+
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(b)        \
+        __phys_to_virt((((b - (*IXP2000_PCI_SDRAM_BAR & 0xfffffff0)) + 0x0)))
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/param.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/param.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/param.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,3 @@
+/*
+ * linux/include/asm-arm/arch-ixdp2400/param.h
+ */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/pci_auto.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/pci_auto.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/pci_auto.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/pci_auto.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-iop310/pci_auto.h
+ * 
+ * PCI autoconfiguration library definitions
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef _ARM_MACH_XSCALE_PCI_AUTO_H
+#define _ARM_MACH_XSCALE_PCI_AUTO_H
+
+#include "pci-bridge.h"
+
+extern int pciauto_bus_scan(struct pci_controller *, int);
+
+#define	PCIAUTO_IDE_MODE_MASK		0x05
+
+#endif /* _ARM_MACH_XSCALE_PCI_AUTO_H */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/pci-bridge.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/pci-bridge.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/pci-bridge.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/pci-bridge.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,65 @@
+/*
+ * include/asm-arm/arch-ixdp2400/pci-bridge.h
+ * 
+ * Generic PCI hose support for Xscale/ARM.  To eventually be
+ * moved to a more generic location.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifdef __KERNEL__
+#ifndef _ASM_PCI_BRIDGE_H
+#define _ASM_PCI_BRIDGE_H
+
+struct device_node;
+struct pci_controller;
+
+/* Get the PCI host controller for a bus */
+extern struct pci_controller* pci_bus_to_hose(int bus);
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct pci_controller {
+	int index;
+	struct pci_controller *next;
+        struct pci_bus *bus;
+	void *arch_data;
+
+	int first_busno;
+	int last_busno;
+        
+	struct pci_ops *ops;
+	volatile unsigned int *cfg_addr;
+	volatile unsigned char *cfg_data;
+
+	/* Currently, we limit ourselves to 1 IO range and 3 mem
+	 * ranges since the common pci_bus structure can't handle more
+	 */
+	struct resource	io_resource;
+	struct resource mem_resources[3];
+	int mem_resource_count;
+
+	/* Host bridge I/O and Memory space
+	 * Used for BAR placement algorithms
+	 */
+	struct resource io_space;
+	struct resource mem_space;
+};
+
+/* These are used for config access before all the PCI probing
+   has been done. */
+int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn, int where, u8 *val);
+int early_read_config_word(struct pci_controller *hose, int bus, int dev_fn, int where, u16 *val);
+int early_read_config_dword(struct pci_controller *hose, int bus, int dev_fn, int where, u32 *val);
+int early_write_config_byte(struct pci_controller *hose, int bus, int dev_fn, int where, u8 val);
+int early_write_config_word(struct pci_controller *hose, int bus, int dev_fn, int where, u16 val);
+int early_write_config_dword(struct pci_controller *hose, int bus, int dev_fn, int where, u32 val);
+#endif
+#endif /* __KERNEL__ */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/pci.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/pci.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/pci.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,37 @@
+/*
+ * include/asm-arm/arch-ixdp2400/pci.h
+ * 
+ * Generic PCI support for Xscale/ARM.  To eventually be moved to a
+ * more generic location.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef _ASM_ARCH_PCI_H
+#define _ASM_ARCH_PCI_H
+
+extern struct pci_controller* pcibios_alloc_controller(void);
+extern void pcibios_allocate_resources(void);
+extern void pci_exclude_device(unsigned char, unsigned char);
+extern struct pci_dev * fake_pci_dev(struct pci_controller *, int, int);
+extern u8 common_swizzle(struct pci_dev *, u8 *);
+
+/*
+ * The following macro is used to lookup irqs in a standard table
+ * format for those systems that do not already have PCI
+ * interrupts properly routed.
+ */
+#define PCI_IRQ_TABLE_LOOKUP                                            \
+({ long _ctl_ = -1;                                                     \
+   if (idsel >= min_idsel && idsel <= max_idsel && pin <= irqs_per_slot) \
+	 _ctl_ = pci_irq_table[idsel - min_idsel][pin-1]; \
+   _ctl_; })
+
+
+#endif /* _ASM_ARCH_PCI_H */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/serial.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/serial.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/serial.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ * include/asm-arm/arch-ixp2000/serial.h
+ *
+ * Serial port defn for ixp2000 based systems
+ *
+ * Author: Deepak Saxena <dsaxena@mvsita.com>
+ *
+ * Copyright (c) 2002 MontaVista Software, Inc.
+ */
+
+
+#define BASE_BAUD 50000000 / 16 // IS THIS ALWAYS TRUE?
+
+#define STD_COM_FLAGS	(ASYNC_SKIP_TEST)
+
+#define RS_TABLE_SIZE	1
+
+#define	STD_SERIAL_PORT_DEFNS			\
+	{					\
+		type: PORT_XSCALE,		\
+		xmit_fifo_size: 16,		\
+		baud_base: BASE_BAUD,		\
+		irq: IRQ_IXP2000_UART,		\
+		flags: STD_COM_FLAGS,		\
+		iomem_base: IXP2000_UART_BASE+3,\
+		io_type: SERIAL_IO_MEM,		\
+		iomem_reg_shift: 2		\
+	}
+
+#define EXTRA_SERIAL_PORT_DEFNS
+
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/serial_reg.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/serial_reg.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/serial_reg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/serial_reg.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,95 @@
+/*
+ * include/asm-arm/arch-ixp2000/serial_reg.h
+ *
+ * Author: Naeem M Afzal <naeem.m.afzal@intel.com>
+ *
+ * Copyright (c) 2002 Intel Corp.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#ifndef _ARCH_SERIAL_H_
+#define _ARCH_SERIAL_H_
+
+#define IXP2000_CSR(x)	(volatile unsinged long *)(IXP2000_UART_BASE + (x))
+#define CSR_UARTCR     IXP2000_CSR(0x0c)
+#define CSR_UARTSR     IXP2000_CSR(0x14)
+#define CSR_UARTDR     IXP2000_CSR(0x00)
+#define CSR_UARTIER    IXP2000_CSR(0x04)
+#define CSR_UARTIIR    IXP2000_CSR(0x04)
+#define CSR_UARTFCR    IXP2000_CSR(0x08)
+
+#define UART_CR        CSR_UARTCR
+#define UART_SR        CSR_UARTSR
+#define UART_DR        CSR_UARTDR
+#define UART_IER       CSR_UARTIER
+#define UART_IIR       CSR_UARTIIR
+#define UART_FCR       CSR_UARTFCR
+
+#define UTDR        0x00  /* DLAB = 0 */
+#define UTDLL       0x00  /* DLAB = 1 */
+#define UTIER       0x04  /* DLAB = 0 */
+#define UTDLM       0x04  /* DLAB = 1 */
+#define UTFCR       0x08
+#define UTIIR       0x08
+#define UTCR        0x0c
+#define UTSR        0x14
+
+#define UART_RX     UTDR	/* Receive port, read only */
+#define UART_TX     UTDR	/* transmit port, write only */
+
+/* bit definition on IER */
+#define UTCR_XIE    (1 << 1)     /* Xmit interrupt enable */
+#define UTCR_TIE    UTCR_XIE     /* Xmit interrupt enable */
+#define UTCR_RIE    (1 << 0)     /* Rcv interrupt enable */
+#define UTCR_RLSE   (1 << 2)     /* Rcv line status interrupt enable */
+#define UTCR_RTOIE  (1 << 4)     /* Rcv timeout status interrupt enable */
+#define UTCR_EN     (1 << 6)     /* Enable uart */
+
+/* dont need these below */
+#define UTCR_9600_BAUD   (0x17 << 16) 
+#define UTCR_19200_BAUD  (0xB  << 16) 
+#define UTCR_38400_BAUD  (0x5  << 16) 
+#define UTCR_57600_BAUD  (0x3  << 16) 
+#define UTCR_115200_BAUD (0x1  << 16)
+
+/* LCR def */
+#define UTCR_PARENB     (1 << 3)     /* Parity Enable */
+#define UTCR_EVNEN_PARITY (1 << 4)   /* Even parity    */
+
+#define UTCR_8_BIT      (0x3 << 0)   /* 8 bit */
+#define UTCR_7_BIT      (0x2 << 0)   /* 7 bit */
+#define UTCR_6_BIT      (0x1 << 0)   /* 6 bit */
+#define UTCR_5_BIT      (0x0 << 0)   /* 5 bit */
+
+#define UTCR_1_STOP_BIT (0 << 2)     /* 1 stop bit */
+#define UTCR_2_STOP_BIT (1 << 2)     /* 2 stop bits  */
+#define UTCR_BRK	(1<<6)
+#define UTCR_DLAB	(1<<7)
+
+
+#define UTCR_DSS_MASK   (0x3 << 0)    /* data size mask */
+#define UTCR_SBS_MASK   (0x1 << 2)    /* stop bit select mask */
+
+#define UTCR_INT_CLEAR  (1 << 2)      /* UART_INT_MASK */
+
+/* LSR */
+#define UTSR_RPE        (1<<2)  /* Parity error */
+#define UTSR_RFE        (1<<3) /* Framing error */
+#define UTSR_ROR        (1<<1) /* receiver overrun */
+#define UTSR_RXR        (1<<0)  /* receiver not empty */
+#define UTSR_TXR        (1<<5) /* Transmit Fifo not full */
+#define UTSR_TXE        (1<<6) /* xmit fifo empty */
+#define UTSR_RXF        (0<<0) /* receive fifo full */
+#define UTSR_TXF        (0<<5) /* xmit fifo full */
+
+#define UART_LCR_DLAB	(1<<7)  /* DLAB bit */
+#define UART_FCR_ENABLE_FIFO  (1<<0)  /* FIFOs enable */
+#define UART_FCR_RESET  (3<<1)  /* RSET FIFOs */
+#define UART_FCR_TRIGGER_8  (1<<7) /* 6:7=01 trigger on 8bits*/
+
+#endif /* _ARCH_SERIAL_H */
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/slave.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/slave.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/slave.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/slave.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,152 @@
+/*
+ * inclue/asm-arm/arch-ixp2000/slave.h
+ *
+ * Register and other defines for IXMB2400 for slave NPU board
+ *
+ * Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ *
+ * Copyright 2002 Intel Corp.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+#ifndef _SLAVE_H
+#define _SLAVE_H
+
+#define MISC_CONTROL_OFF    	0x04
+#define IXP_RESET0_OFF      	0x0C
+#define CCR_OFF          	0x14
+#define STRAP_OPTIONS_OFF    	0x18
+
+/* slave's csr as seen from master PCI*/
+#define GLOBAL_CONTROL_BASE_FRM_PCI       0x4A00
+#define IXP_RESET0_FRM_PCI     (GLOBAL_CONTROL_BASE_FRM_PCI + IXP_RESET0_OFF)
+#define CCR_FRM_PCI            (GLOBAL_CONTROL_BASE_FRM_PCI + CCR_OFF)
+#define STRAP_OPTIONS_FRM_PCI  (GLOBAL_CONTROL_BASE_FRM_PCI + STRAP_OPTIONS_OFF)
+#define MISC_CONTROL_FRM_PCI   (GLOBAL_CONTROL_BASE_FRM_PCI + MISC_CONTROL_OFF)
+
+#define SLOW_PORT_CSR_BASE_FRM_PCI      0x80000
+#define SCRATCH_BASE_FRM_PCI            0xF0000
+
+#define DDR_RX_DLL_VAL                  0x11
+#define DDR_RX_DESKEW_VAL               0x11
+#define DDR_RDDLYSEL_RECEN_VAL          0x11
+
+#define SRAM_CH1_BASE_FRM_PCI   	0xF9800
+#define SRAM_CH0_BASE_FRM_PCI   	0xF9C00
+#define SRAM_CH_BASE_FRM_PCI   		0xF9000
+
+#define DU_CONTROL_OFF        		0x0
+#define DU_ECC_TEST_OFF       		0x18
+#define DU_INIT_OFF           		0x20
+#define DU_CONTROL2_OFF       		0x28
+#define DDR_RCOMP_IO_CONFIG_OFF      	0x3c0
+#define DDR_RDDLYSEL_RECEN_OFF       	0x3c8
+#define DDR_RX_DLL_OFF       		0x650
+#define DDR_RX_DESKEW_OFF      		0x688
+
+#define CR0_FRCSMRCOMP_OFF              0x100
+#define CR0_DSTRENGTHSEL_OFF            0x130
+#define CR0_DDQRCOMP_OFF                0x148
+#define CR0_DCTLRCOMP_OFF               0x190
+#define CR0_DRCVRCOMP_OFF               0x1D8
+#define CR0_DCKERCOMP_OFF               0x228
+#define CR0_DCSRCOMP_OFF                0x2B0
+#define CR0_DCKRCOMP_OFF                0x338
+#define CR0_DX8X16CKECSCKSEL_OFF        0x220
+#define CR0_RCOMPPRD_OFF                0x108
+#define CR0_DIGFIL_OFF                  0x118
+
+#define CR0_SLEWPROGRAMMED_OFF          0x128
+#define CR0_OVRRIDEH_OFF                0x138
+#define CR0_OVRRIDEV_OFF                0x140
+#define CR0_JT_CONFIG_OFF               0x3C0
+
+#define CR0_FRCSMRCOMP_FRM_PCI          (DRAM_CH0_BASE_FRM_PCI + CR0_FRCSMRCOMP_OFF)
+#define CR0_DSTRENGTHSEL_FRM_PCI        (DRAM_CH0_BASE_FRM_PCI + CR0_DSTRENGTHSEL_OFF)
+#define CR0_DDQRCOMP_FRM_PCI            (DRAM_CH0_BASE_FRM_PCI + CR0_DDQRCOMP_OFF)
+#define CR0_DCTLRCOMP_FRM_PCI           (DRAM_CH0_BASE_FRM_PCI + CR0_DCTLRCOMP_OFF)
+#define CR0_DRCVRCOMP_FRM_PCI           (DRAM_CH0_BASE_FRM_PCI + CR0_DRCVRCOMP_OFF)
+#define CR0_DCKERCOMP_FRM_PCI           (DRAM_CH0_BASE_FRM_PCI + CR0_DCKERCOMP_OFF)
+#define CR0_DCSRCOMP_FRM_PCI            (DRAM_CH0_BASE_FRM_PCI + CR0_DCSRCOMP_OFF)
+#define CR0_DCKRCOMP_FRM_PCI            (DRAM_CH0_BASE_FRM_PCI + CR0_DCKRCOMP_OFF)
+#define CR0_DX8X16CKECSCKSEL_FRM_PCI    (DRAM_CH0_BASE_FRM_PCI + CR0_DX8X16CKECSCKSEL_OFF)
+#define CR0_RCOMPPRD_FRM_PCI            (DRAM_CH0_BASE_FRM_PCI + CR0_RCOMPPRD_OFF)
+#define CR0_DIGFIL_FRM_PCI              (DRAM_CH0_BASE_FRM_PCI + CR0_DIGFIL_OFF)
+
+#define CR0_SLEWPROGRAMMED_FRM_PCI      (DRAM_CH0_BASE_FRM_PCI + CR0_SLEWPROGRAMMED_OFF)
+#define CR0_OVRRIDEH_FRM_PCI            (DRAM_CH0_BASE_FRM_PCI + CR0_OVRRIDEH_OFF)
+#define CR0_OVRRIDEV_FRM_PCI            (DRAM_CH0_BASE_FRM_PCI + CR0_OVRRIDEV_OFF)
+#define CR0_JT_CONFIG_FRM_PCI           (DRAM_CH0_BASE_FRM_PCI + CR0_JT_CONFIG_OFF)
+
+#define DRAM_CH0_BASE_FRM_PCI   0xFD800
+
+#define DU_CONTROL_FRM_PCI    	(DRAM_CH0_BASE_FRM_PCI + DU_CONTROL_OFF)
+#define DU_ECC_TEST_FRM_PCI   	(DRAM_CH0_BASE_FRM_PCI + DU_ECC_TEST_OFF)
+#define DU_INIT_FRM_PCI       	(DRAM_CH0_BASE_FRM_PCI + DU_INIT_OFF)
+#define DU_CONTROL2_FRM_PCI    	(DRAM_CH0_BASE_FRM_PCI + DU_CONTROL2_OFF)
+#define DDR_RCOMP_IO_CONFIG_FRM_PCI  (DRAM_CH0_BASE_FRM_PCI + DDR_RCOMP_IO_CONFIG_OFF)
+#define DDR_RDDLYSEL_RECEN_FRM_PCI  (DRAM_CH0_BASE_FRM_PCI + DDR_RDDLYSEL_RECEN_OFF)
+#define DDR_RX_DLL_FRM_PCI     (DRAM_CH0_BASE_FRM_PCI + DDR_RX_DLL_OFF)
+#define DDR_RX_DESKEW_FRM_PCI  (DRAM_CH0_BASE_FRM_PCI + DDR_RX_DESKEW_OFF)
+
+#define PCI_OUT_INT_MASK_OFF    0x34
+#define MAILBOX_1_OFF       	0x54
+#define PCI_CONTROL_OFF       	0x13C
+#define PCI_ADDR_EXT_OFF      	0x140
+#define XSCALE_INT_STATUS_OFF   0x158
+#define XSCALE_INT_ENABLE_OFF   0x15C
+
+#define PCI_CSR_BASE_FRM_PCI   0xFE000
+
+#define PCI_OUT_INT_MASK_FRM_PCI (PCI_CSR_BASE_FRM_PCI + PCI_OUT_INT_MASK_OFF)
+#define PCI_CONTROL_FRM_PCI      (PCI_CSR_BASE_FRM_PCI + PCI_CONTROL_OFF)
+#define PCI_ADDR_EXT_FRM_PCI     (PCI_CSR_BASE_FRM_PCI + PCI_ADDR_EXT_OFF)
+
+#define SLAVE_PCI_CMD_STAT_VAL (PCI_COMMAND_INVALIDATE \
+				| PCI_COMMAND_MEMORY  \
+				| PCI_COMMAND_IO)
+
+#define CFG_PCI_BOOT_HOST   	(1 << 2)
+#define PCI_OUT_INT_MASK_VAL   	(1<<1)
+#define XSCALE_RESET_BIT 	0x00000001
+
+#define FLASH_WRITE_ENABLE      (1 << 9)
+#define FLASH_ALIAS_DISABLE     (1 << 8)
+
+#define IXP_TYPE_2400   	0
+#define IXP_TYPE_2800   	1
+
+#define IXP_IOC_QUERY_INFO      0x1
+#define IXP_IOC_RELEASE_RST     0x2
+
+#define IXP_FLAG_ROM_BOOT       (1<<0x0)
+#define IXP_FLAG_PCI_HOST       (1<<0x1)
+#define IXP_FLAG_PCI_ARB        (1<<0x2)
+#define IXP_FLAG_NPU_UP         (1<<0x3) /* Slave NPU is running after reset */
+#define IXP_FLAG_NO_FLASH       (1<<0x4) /* Slave NPU does not have flash*/
+
+
+struct ixp_info {
+        char name[32];
+        unsigned short ixp_type;
+        unsigned short ixp_rev;
+
+        unsigned long sdram_size;
+        unsigned long sram_size;
+
+        unsigned long flags;
+
+        unsigned long csr_bar;
+        unsigned long sram_bar;
+        unsigned long sdram_bar;
+
+        unsigned long csr_ioaddr;
+        unsigned long sram_ioaddr;
+        unsigned long sdram_ioaddr;
+	struct ixp_info *next;
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/system.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/system.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/system.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,31 @@
+/*
+ * linux/include/asm-arm/arch-ixp2400/system.h
+ *
+ * Copyright (C) 2002 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+static inline void arch_idle(void)
+{
+#if 0
+	while (!current->need_resched && !hlt_counter) {
+		cpu_do_idle(IDLE_CLOCK_SLOW);
+		cpu_do_idle(IDLE_WAIT_FAST);
+		cpu_do_idle(IDLE_CLOCK_FAST);
+	}
+#endif
+}
+
+
+static inline void arch_reset(char mode)
+{
+	cli();
+	/* Use on-chip reset capability */
+	if (*IXP2000_STRAP_OPTIONS & CFG_PCI_BOOT_HOST) {
+		*(IXP2000_RESET0) |= (RSTALL);
+		udelay(1000);
+	}
+}
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/time.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/time.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/time.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,3 @@
+/*
+ * Place keeper so arch/arm/kernel/time.c builds
+ */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/timex.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/timex.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/timex.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,13 @@
+/*
+ * linux/include/asm-arm/arch-ix2000/timex.h
+ *
+ * IXP2000 architecture timex specifications
+ */
+
+
+/*
+ * This is somewhat bogus, but we need something to make <linux/timex.h>
+ * happy. Each board can have a different timer tick rate, so we 
+ * determine the _real_ latch at run time.
+ */
+#define CLOCK_TICK_RATE (50000000)	/* 50MHz APB clock - OK for most */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/tvm.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/tvm.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/tvm.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/tvm.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,157 @@
+/*
+ * inclue/asm-arm/arch-ixp2000/tvm.h
+ *
+ * Register and other defines for ADuC812 device
+ *
+ * Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ *
+ * Copyright 2002 Intel Corp.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+#ifndef TVM_H
+#define TVM_H
+
+#define IXP2400_CAP_BASE        CAP_BASE
+#define IXP2400_GPIO_BASE       (IXP2400_CAP_BASE  + 0x10000)
+
+
+/*---------------------------------------------------
+ * IXDP2400 GPIO...
+ * --------------------------------------------------*/
+#define IXP2400_GPIO_BASE       (IXP2400_CAP_BASE  + 0x10000)
+#define IXP2400_GPIO_PLR        (IXP2400_GPIO_BASE + 0x0)  /*Read only register to read the level/data on the pins irrespective of input or output*/
+#define IXP2400_GPIO_PDSR       (IXP2400_GPIO_BASE + 0x08) /*write a one to this register's bit to configure the corressponding pin as output*/
+#define IXP2400_GPIO_POPR   (IXP2400_GPIO_BASE + 0x10)
+#define IXP2400_GPIO_PDCR       (IXP2400_GPIO_BASE + 0x0c) /*write a one to this register's bit to configure corressponding bit as input*/
+#define IXP2400_GPIO_POSR       (IXP2400_GPIO_BASE + 0x14) /*write to this register's bit to set data high*/
+#define IXP2400_GPIO_POCR       (IXP2400_GPIO_BASE + 0x18) /*write to this register's bit to set data low*/
+
+
+#define LOW 0
+#define HIGH 1
+
+/*write this to POSR to drive the clock pin (GPIO pin 7)High and POCR for LOW*/
+#define CLOCK   0x80
+/*write this to POSR to drive the data pin (gpio pin 6)High and POCR for LOW*/
+#define DATA    0x40
+
+/*This GPIO bit 2 has to be configured as output and
+ *drive a high to cause a pull up on the SDA line.
+ */
+#define I2C_INIT_BIT 0x04
+
+
+/* from vxworks include */
+typedef enum volt_id {
+        ADUC_3_3V_M_ID  = 1,
+        ADUC_2_5V_M_ID,
+        ADUC_3_3V_ID,
+        ADUC_2_5V_ID,
+        ADUC_1_8V_ID,
+        ADUC_1_5V_ID,
+        ADUC_1_3V_ID,
+        ADUC_1_2_5V_ID
+} volt_id;
+
+typedef enum temp_id {
+        M_NPU_ID        = 1,
+        S_NPU_ID
+} temp_id;
+
+typedef enum which_limit {
+        MONITOR         = 0,
+        HIGH_LIMIT,
+        LOW_LIMIT
+} which_limit;
+
+typedef struct  tvm_read {
+        int identifier;
+        int limit;
+        int value;
+} tvm_read_t;
+
+typedef struct  tvm_write {
+        int identifier;
+        int value;
+        int limit;
+} tvm_write_t;
+
+
+/* these resolutions are in uV */
+#define ADUC_2_5V_REF_RES       610
+#define ADUC_5V_REF_RES         1221
+
+#define ADUC812_DEV_ID_OFF      0x0
+#define TEMP_DEV_ID_OFF         0x29
+#define INT_OFF                 0x30
+#define ADUC812_COMMAND         0x34
+
+#define ADUC812_DEV_ID          0x8C
+#define TEMP_DEV_ID              0x31
+
+#define SHUTDOWN_COMMAND        1
+#define CLEAR_INT               2
+
+#define VOLT_A_TO_D_BITS        12
+#define TEMP_A_TO_D_BITS        8
+
+/* aduc interrupt defines */
+#define ADUC_3_3V_M_HIGH                (1 << 0)
+#define ADUC_3_3V_M_LOW                 (1 << 1)
+#define ADUC_3_3V_HIGH                  (1 << 2)
+#define ADUC_3_3V_LOW                   (1 << 3)
+#define ADUC_2_5V_M_HIGH                (1 << 4)
+#define ADUC_2_5V_M_LOW                 (1 << 5)
+#define ADUC_2_5V_HIGH                  (1 << 6)
+#define ADUC_2_5V_LOW                   (1 << 7)
+#define ADUC_1_8V_HIGH                  (1 << 8)
+#define ADUC_1_8V_LOW                   (1 << 9)
+#define ADUC_1_5V_HIGH                  (1 << 10)
+#define ADUC_1_5V_LOW                   (1 << 11)
+#define ADUC_1_3V_HIGH                  (1 << 12)
+#define ADUC_1_3V_LOW                   (1 << 13)
+#define ADUC_1_2_5V_HIGH                (1 << 14)
+#define ADUC_1_2_5V_LOW                 (1 << 15)
+#define ADUC_MASTER_TEMP_HIGH   (1 << 16)
+#define ADUC_MASTER_TEMP_LOW    (1 << 17)
+#define ADUC_SLAVE_TEMP_HIGH    (1 << 18)
+#define ADUC_SLAVE_TEMP_LOW             (1 << 19)
+
+/* from vxworks */
+
+#define SWAP32(x)               \
+  (((x) << 24) |                \
+  (((x) & 0x0000FF00) << 8) |   \
+  (((x) & 0x00FF0000) >> 8) |   \
+  (((unsigned int)(x)) >> 24))
+
+#define SWAP16(x) ((((x) << 8) | ((x) >> 8)) & 0xFFFF)
+
+#define TVM_MINOR       201 /* for now */
+
+#define	TVM_VOLT_RD		0   
+#define	TVM_VOLT_WR		1  
+#define	TVM_TEMP_RD		2   
+#define	TVM_TEMP_WR		3  
+
+static int tvm_open(struct inode *, struct file *);
+static int tvm_release(struct inode *, struct file *);
+static int tvm_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+static void tvm_isr(int, void *, struct pt_regs *);
+extern int i2c_master_send(struct i2c_client *,const char* ,int);
+extern int i2c_master_recv(struct i2c_client *,char* ,int);
+
+static void config_ixmb2400(void);
+static int tvm_init(void);
+//static int ixmb2400_init(void);
+static void ixmb2400_inc(struct i2c_adapter *adapter);
+static void ixmb2400_dec(struct i2c_adapter *adapter);
+static int volt_limit_set(volt_id identifier, int value, which_limit limit);
+static int temp_limit_set(temp_id identifier, int value, which_limit limit);
+
+
+#endif /* TVM_H */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/uncompress.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/uncompress.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/uncompress.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,65 @@
+/*
+ * linux/include/asm-arm/arch-ixp2000/uncompress.h
+ * Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ *
+ * 3/27/03: Jeff Daly <jeffrey.daly@intel.com> 
+ *	Modified to support multiple machine types
+ *
+ * Copyright 2002 Intel Corp.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+/* At this point, the MMU is not on, so use physical addresses */
+
+
+#define UART_BASE	0xc0030000
+
+#ifdef __ARMEB__
+#define PHYS(x)          ((volatile unsigned char *)(UART_BASE + x + 3))
+#else
+#define PHYS(x)          ((volatile unsigned char *)(UART_BASE + x))
+#endif
+
+#define UARTDR          PHYS(0x00)      /* Transmit reg dlab=0 */
+#define UARTDLL         PHYS(0x00)      /* Divisor Latch reg dlab=1*/
+#define UARTDLM         PHYS(0x04)      /* Divisor Latch reg dlab=1*/
+#define UARTIER         PHYS(0x04)      /* Interrupt enable reg */
+#define UARTFCR         PHYS(0x08)      /* FIFO control reg dlab =0*/
+#define UARTLCR         PHYS(0x0c)      /* Control reg */
+#define UARTSR          PHYS(0x14)      /* Status reg */
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader or such...
+ */
+
+#define THRE 0x20 /* bit5=1, means transmit holding reg empty */
+
+static void puts( const char *s )
+{
+	int i,j;
+
+	for (i = 0; *s; i++, s++) {
+		/* wait for space in the UART's transmiter */
+		j = 0x1000;
+		while (--j && !(*UARTSR & THRE));
+		/* if a LF, also do CR... */
+		if (*s == '\n') {
+			/* send the CR character out. */
+			*UARTDR = '\r';
+			/* wait for space in the UART's transmiter */
+			j = 0x1000;
+			while (--j && !(*UARTSR & THRE));
+		}
+		/* send the character out. */
+		*UARTDR = *s;
+	}
+}
+
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff -urN linux-2.4.29/include/asm-arm/arch-ixp2000/vmalloc.h linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/vmalloc.h
--- linux-2.4.29/include/asm-arm/arch-ixp2000/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp2000/vmalloc.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+ * linux/include/asm-arm/arch-ixp2000/vmalloc.h
+ *
+ * Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ *
+ * Copyright 2002 Intel Corp.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define FIRST_STATIC_ENTRY  VIRT_CPLD_CSR
+#define VMALLOC_OFFSET	    (8*1024*1024)
+#define VMALLOC_START	    (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x)   ((unsigned long)(x))
+#define VMALLOC_END	    0xd4000000
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/dma.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/dma.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/dma.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,52 @@
+/*
+ * linux/include/asm-arm/arch-80200fcc/dma.h
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 2002: Modified for IXP425 by Intel Corporation.
+ *
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#include <linux/config.h>
+#include <asm/page.h>
+#include <asm/sizes.h>
+#include <asm/arch/hardware.h>
+
+#define MAX_DMA_ADDRESS		(PAGE_OFFSET + SZ_64M)
+
+/* No DMA */
+#define MAX_DMA_CHANNELS	0
+
+/*
+ * Only first 64MB of memory can be accessed via PCI.
+ * We use GFP_DMA to allocate safe buffers to do map/unmap.
+ * This is really ugly and we need a better way of specifying
+ * DMA-capable regions of memory.
+ */
+static inline void __arch_adjust_zones(int node, unsigned long *zone_size, 
+	unsigned long *zhole_size) 
+{
+	unsigned int sz = SZ_64M >> PAGE_SHIFT;
+
+	/*
+	 * Only adjust if > 64M on current system
+	 */
+	if (node || (zone_size[0] <= sz))
+		return;
+
+	zone_size[1] = zone_size[0] - sz;
+	zone_size[0] = sz;
+	zhole_size[1] = zhole_size[0];
+	zhole_size[0] = 0;
+}
+
+#define arch_adjust_zones(node, size, holes) \
+	__arch_adjust_zones(node, size, holes)
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/fast_timer.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/fast_timer.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/fast_timer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/fast_timer.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,50 @@
+#ifndef __ASM_ARM_MACH_FAST_TIMER_H
+#define __ASM_ARM_MACH_FAST_TIMER_H
+
+#include <linux/sched.h>
+#include <linux/timex.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+static void fast_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* Clear Pending Interrupt by writing '1' to it */
+	*IXP425_OSST = IXP425_OSST_TIMER_2_PEND;
+
+	do_fast_timer();
+}
+
+static void fast_timer_set(void)
+{
+	unsigned long interval;
+
+	/* Setup the Timer counter value */
+	interval = (CLOCK_TICK_RATE + fast_timer_rate/2) / fast_timer_rate;
+	*IXP425_OSRT2 = (interval & ~IXP425_OST_RELOAD_MASK) | IXP425_OST_ENABLE;
+}
+
+static int __init fast_timer_setup(void)
+{
+	/* Clear Pending Interrupt by writing '1' to it */
+	*IXP425_OSST = IXP425_OSST_TIMER_2_PEND;
+
+	/* Connect the interrupt handler and enable the interrupt */
+	if (request_irq(IRQ_IXP425_TIMER2, fast_timer_interrupt, SA_INTERRUPT,
+			"fast timer", NULL))
+		return -EBUSY;
+
+	fast_timer_rate = 5000;
+	fast_timer_set();
+
+	printk("fast timer: %d Hz, IRQ %d\n", fast_timer_rate,
+			IRQ_IXP425_TIMER2);
+	return 0;
+}
+
+static void __exit fast_timer_cleanup(void)
+{
+	*IXP425_OSRT2 = IXP425_OST_DISABLED;
+	free_irq(IRQ_IXP425_TIMER2, NULL);
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/gpio.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/gpio.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/gpio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/gpio.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,93 @@
+/*
+ * arch/arm/mach-ixp425/gpio.h 
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _ASM_ARCH_GPIO_H_
+#define _ASM_ARCH_GPIO_H_
+
+#ifndef __ASSEMBLY__
+
+#include <asm/types.h>
+
+/* GPIO pin mappings */
+#define IXP425_GPIO_PIN_15 		15
+#define IXP425_GPIO_PIN_14 		14
+#define IXP425_GPIO_PIN_13 		13
+#define IXP425_GPIO_PIN_12 		12
+#define IXP425_GPIO_PIN_11 		11
+#define IXP425_GPIO_PIN_10 		10
+#define IXP425_GPIO_PIN_9 		9
+#define IXP425_GPIO_PIN_8  		8
+#define IXP425_GPIO_PIN_7  		7
+#define IXP425_GPIO_PIN_6  		6
+#define IXP425_GPIO_PIN_5  		5
+#define IXP425_GPIO_PIN_4  		4
+#define IXP425_GPIO_PIN_3  		3
+#define IXP425_GPIO_PIN_2  		2
+#define IXP425_GPIO_PIN_1  		1
+#define IXP425_GPIO_PIN_0  		0
+
+#define IXP425_GPIO_PIN_MAX		IXP425_GPIO_PIN_15
+
+/* GPIO pin types */
+#define IXP425_GPIO_OUT 		1
+#define IXP425_GPIO_IN  		2
+
+/* GPIO interrupt types */
+#define IXP425_GPIO_ACTIVE_HIGH		0x4 /* Default */
+#define IXP425_GPIO_ACTIVE_LOW		0x8
+#define IXP425_GPIO_RISING_EDGE		0x10
+#define IXP425_GPIO_FALLING_EDGE 	0x20
+#define IXP425_GPIO_TRANSITIONAL 	0x40
+
+/* GPIO signal types */
+#define IXP425_GPIO_LOW			0
+#define IXP425_GPIO_HIGH		1
+
+/* GPIO Clocks */
+#define IXP425_GPIO_CLK_0		14
+#define IXP425_GPIO_CLK_1		15
+
+/*
+ * GPIO clock frequencies. These correspond to fractions of the
+ * 66 MHz APB clock.
+ */
+#define IXP425_GPIO_33_MHZ		0x1	/* Default */
+#define IXP425_GPIO_22_MHZ		0x2
+#define IXP425_GPIO_16_5_MHZ		0x3
+#define IXP425_GPIO_13_2_MHZ		0x4
+#define IXP425_GPIO_11_MHZ		0x5
+#define IXP425_GPIO_9_4_MHZ		0x6
+#define IXP425_GPIO_8_3_MHZ		0x7
+#define IXP425_GPIO_7_3_MHZ		0x8
+#define IXP425_GPIO_6_6_MHZ		0x9
+#define IXP425_GPIO_6_MHZ		0xa
+#define IXP425_GPIO_5_5_MHZ		0xb
+#define IXP425_GPIO_5_1_MHZ		0xc
+#define IXP425_GPIO_4_7_MHZ		0xd
+#define IXP425_GPIO_4_4_MHZ		0xf
+    
+#define IXP425_GPIO_CLK0_ENABLE 	0x100
+#define IXP425_GPIO_CLK1_ENABLE 	0x1000000
+
+/* Left shift values to set clock terminal count (TC) and duty cycle (DC)*/
+#define IXP425_GPIO_CLK0TC_LSH		4
+#define IXP425_GPIO_CLK1TC_LSH		20
+#define IXP425_GPIO_CLK0DC_LSH		0
+#define IXP425_GPIO_CLK1DC_LSH		16
+
+extern void gpio_line_get(u8 line, int *value);
+extern void gpio_line_set(u8 line, int value);
+extern void gpio_line_config(u8 line, u32 style);
+extern void gpio_line_isr_clear(u8 line);
+
+#endif // __ASSEMBLY__
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/hardware.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/hardware.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/hardware.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ * hardware.h 
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/*
+ * Hardware definitions for IXP425 based systems
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H__
+#define __ASM_ARCH_HARDWARE_H__
+
+/* common definitions for all boards */
+#include "ixp425.h"
+#include "gpio.h"
+
+#define PCIO_BASE              		0
+#define PCIBIOS_MIN_IO			0x0
+#define	PCIBIOS_MIN_MEM			0x0
+
+#define pcibios_assign_all_busses()	1
+
+#endif  /* _ASM_ARCH_HARDWARE_H */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/ide.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/ide.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/ide.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,68 @@
+/*
+ * linux/include/asm-arm/arch-ixp425/ide.h
+ *
+ * Copyright (c) 1998 Russell King
+ *
+ * Modifications:
+ *  29-07-1998	RMK	Major re-work of IDE architecture specific code
+ */
+
+#include <asm/irq.h>
+
+/*
+ * Set up a hw structure for a specified data port, control port and IRQ.
+ * This should follow whatever the default interface uses.
+ */
+static __inline__ void
+ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int *irq)
+{
+	ide_ioreg_t reg = (ide_ioreg_t) data_port;
+	int i;
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = reg;
+		reg += 1;
+	}
+	hw->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t) ctrl_port;
+	if (irq)
+		*irq = 0;
+}
+
+/*
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ */
+static __inline__ void ide_init_default_hwifs(void)
+{
+	/* There are no standard ports */
+}
+
+/*
+ *	We need to swap the raw data stream, since for the programmed
+ *	I/O case it is swap by the PCI bus unit. For registers this is
+ *	no problem (since we are running big-endian, we need to swap),
+ *	no good for raw data streams though, they are now backwords.
+ *	For the IDE case we need only swap 16bit reads/writes, sinec
+ *	they are the data channel reads/writes.
+ */
+#undef insw
+#undef outsw
+
+static __inline__ u16 swap16(u16 val)
+{
+	return ((val << 8) | (val >> 8));
+}
+
+static __inline__ void insw(u32 port, void *addr, u32 count)
+{
+	u16 *wp = addr;
+	while (count--)
+		*wp++ = swap16(inw(port));
+}
+
+static __inline__ void outsw(u32 port, void *addr, u32 count)
+{
+	u16 *wp = addr;
+	while (count--)
+		outw(swap16(*wp++), port);
+}
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/io.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/io.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/io.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,257 @@
+/*
+ * linux/include/asm-arm/arch-ixp425/io.h
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (C) 2001  MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * Needed for VMALLOC_STARt
+ */
+#include <linux/mm.h>
+#include <asm/arch/vmalloc.h>
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __mem_isa(a)		((unsigned long)(a))
+
+/*
+ * IXP425 does not have a transparent cpu -> PCI I/O translation
+ * window.  Instead, it has a set of registers that must be tweaked
+ * with the proper byte lanes, command types, and address for the
+ * transaction.  This means that we need to override the default
+ * I/O functions.
+ */
+
+
+#if CONFIG_PCMCIA_IVPN
+
+extern void ivpnss_out(void *bus, u32 val, u32 port, s32 sz);
+extern u32 ivpnss_in(void *bus, u32 port, s32 sz);
+extern void ivpnss_outs(void *bus, u32 port, void *buf, u32 count, s32 sz);
+extern void ivpnss_ins(void *bus, u32 port, void *buf, u32 count, s32 sz);
+
+#define	outb(v, p)	ivpnss_out(NULL, v, p, 0)
+#define	outw(v, p)	ivpnss_out(NULL, v, p, 1)
+#define	outl(v, p)	ivpnss_out(NULL, v, p, 2)
+#define	inb(p)		ivpnss_in(NULL, p, 0)
+#define	inw(p)		ivpnss_in(NULL, p, 1)
+#define	inl(p)		ivpnss_in(NULL, p, 2)
+#define	outsb(p, a, c)	ivpnss_outs(NULL, p, a, c, 0)
+#define	outsw(p, a, c)	ivpnss_outs(NULL, p, a, c, 1)
+#define	outsl(p, a, c)	ivpnss_outs(NULL, p, a, c, 2)
+#define	insb(p, a, c)	ivpnss_ins(NULL, p, a, c, 0)
+#define	insw(p, a, c)	ivpnss_ins(NULL, p, a, c, 1)
+#define	insl(p, a, c)	ivpnss_ins(NULL, p, a, c, 2)
+
+#else
+
+extern void ixp425_outb(u8 v, u32 p);
+extern void ixp425_outw(u16 v, u32 p);
+extern void ixp425_outl(u32 v, u32 p);
+
+extern u8 ixp425_inb(u32 p);
+extern u16 ixp425_inw(u32 p);
+extern u32 ixp425_inl(u32 p);
+
+extern void ixp425_outsb(u32 p, u8 *addr, u32 count);
+extern void ixp425_outsw(u32 p, u16 *addr, u32 count);
+extern void ixp425_outsl(u32 p, u32 *addr, u32 count);
+
+extern void ixp425_insb(u32 p, u8 *addr, u32 count);
+extern void ixp425_insw(u32 p, u16 *addr, u32 count);
+extern void ixp425_insl(u32 p, u32 *addr, u32 count);
+
+#define	outb(v, p)	ixp425_outb(v, p)
+#define	outw(v, p)	ixp425_outw(v, p)
+#define	outl(v, p)	ixp425_outl(v, p)
+
+#define	inb(p)		ixp425_inb(p)
+#define	inw(p)		ixp425_inw(p)
+#define	inl(p)		ixp425_inl(p)
+
+#define	outsb(p, a, c)	ixp425_outsb(p, a, c)
+#define	outsw(p, a, c)	ixp425_outsw(p, a, c)
+#define	outsl(p, a, c)	ixp425_outsl(p, a, c)
+
+#define	insb(p, a, c)	ixp425_insb(p, a, c)
+#define	insw(p, a, c)	ixp425_insw(p, a, c)
+#define	insl(p, a, c)	ixp425_insl(p, a, c)
+#endif
+
+
+
+/*
+ * Generic virtual read/write
+ */
+#define __arch_getb(a)		(*(volatile unsigned char *)(a))
+#define __arch_getl(a)		(*(volatile unsigned int  *)(a))
+
+extern __inline__ unsigned int __arch_getw(unsigned long a)
+{
+	unsigned int value;
+	__asm__ __volatile__("ldr%?h	%0, [%1, #0]	@ getw"
+		: "=&r" (value)
+		: "r" (a));
+	return value;
+}
+
+
+#define __arch_putb(v,a)	(*(volatile unsigned char *)(a) = (v))
+#define __arch_putl(v,a)	(*(volatile unsigned int  *)(a) = (v))
+
+extern __inline__ void __arch_putw(unsigned int value, unsigned long a)
+{
+	__asm__ __volatile__("str%?h	%0, [%1, #0]	@ putw"
+		: : "r" (value), "r" (a));
+}
+
+
+/*
+ * IXP425 also does not have a transparent PCI MEM translation
+ * window.  For this reason, we have to use the NP registers for
+ * all PCI mem acceses and have to implement custom 
+ * ioremap/unmap/etc functions. :( We need to check and make
+ * sure that the address being accessed is a PCI address and
+ * if not, fall back to the normal code.
+ */
+
+static inline void 
+__writeb(u8 v, u32 p)
+{
+	u32 n, byte_enables, data;
+
+	if(p >= VMALLOC_START) {
+		__raw_writeb(v, p);
+		return;
+	}
+
+	n = p % 4;
+	byte_enables = (0xf & ~BIT(n)) << IXP425_PCI_NP_CBE_BESL;
+	data = v << (8*n);
+	ixp425_pci_write(p, byte_enables | NP_CMD_MEMWRITE, data);
+}
+
+static inline void 
+__writew(u16 v, u32 p)
+{
+	u32 n, byte_enables, data;
+
+	if(p >= VMALLOC_START) {
+		__raw_writew(v, p);
+		return;
+	}
+
+	n = p % 4;
+	byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP425_PCI_NP_CBE_BESL;
+	data = v << (8*n);
+	ixp425_pci_write(p, byte_enables | NP_CMD_MEMWRITE, data);
+}
+
+static inline void 
+__writel(u32 v, u32 p)
+{
+	if(p >= VMALLOC_START) {
+		__raw_writel(v, p);
+		return;
+	}
+
+	ixp425_pci_write(p, NP_CMD_MEMWRITE, v);
+}
+
+static inline unsigned char 
+__readb(u32 p)
+{
+	u32 n, byte_enables, data;
+
+	if(p >= VMALLOC_START)
+		return __raw_readb(p);
+
+	n = p % 4;
+	byte_enables = (0xf & ~BIT(n)) << IXP425_PCI_NP_CBE_BESL;
+	if (ixp425_pci_read(p, byte_enables | NP_CMD_MEMREAD, &data))
+		return 0xff;
+
+	return data >> (8*n);
+}
+
+static inline unsigned short 
+__readw(u32 p)
+{
+	u32 n, byte_enables, data;
+
+	if(p >= VMALLOC_START)
+		return __raw_readw(p);
+
+	n = p % 4;
+	byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP425_PCI_NP_CBE_BESL;
+	if (ixp425_pci_read(p, byte_enables | NP_CMD_MEMREAD, &data))
+		return 0xffff;
+
+	return data>>(8*n);
+}
+
+static inline unsigned long 
+__readl(u32 p)
+{
+	u32 data;
+
+	if(p >= VMALLOC_START)
+		return __raw_readl(p);
+
+	if (ixp425_pci_read(p, NP_CMD_MEMREAD, &data))
+		return 0xffffffff;
+
+	return data;
+}
+
+#define	readb(addr)	__readb(addr)
+#define	readw(addr)	__readw(addr)
+#define	readl(addr)	__readl(addr)
+#define	writeb(v, addr)	__writeb(v, addr)
+#define	writew(v, addr)	__writew(v, addr)
+#define	writel(v, addr)	__writel(v, addr)
+
+/*
+ * We can use the built-in functions b/c they end up calling
+ * our versions of writeb/readb
+ */
+#define memset_io(c,v,l)		_memset_io((c),(v),(l))
+#define memcpy_fromio(a,c,l)		_memcpy_fromio((a),(c),(l))
+#define memcpy_toio(c,a,l)		_memcpy_toio((c),(a),(l))
+
+#define eth_io_copy_and_sum(s,c,l,b) \
+				eth_copy_and_sum((s),(c),(l),(b))
+
+static inline void *
+__arch_ioremap(unsigned long phys_addr, size_t size, unsigned long flags)
+{
+	extern void * __ioremap(unsigned long, size_t, unsigned long);
+
+	if((phys_addr < 0x48000000) || (phys_addr > 0x4bffffff))
+		return __ioremap(phys_addr, size, flags);
+
+	return (void *)phys_addr;
+}
+
+static inline void
+__arch_iounmap(void *addr)
+{
+	extern void __iounmap(void *);
+
+	if(((u32)addr < 0x48000000) || ((u32)addr > 0x4bffffff))
+		__iounmap(addr);
+}
+
+
+
+#endif	//  __ASM_ARM_ARCH_IO_H
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/irq.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/irq.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/irq.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,13 @@
+/*
+ * irq.h 
+ *
+ *  Copyright (C) 2002 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define fixup_irq(irq)  (irq)
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/irqs.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/irqs.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/irqs.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,135 @@
+/*
+ * include/asm-arm/arch-ixp425/irqs.h 
+ *
+ * IRQ definitions for IXP425 based systems
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _ARCH_IXP425_IRQS_H_
+#define _ARCH_IXP425_IRQS_H_
+
+#ifdef CONFIG_MACH_IXDP465
+#define NR_IRQS				64
+#else
+#define NR_IRQS				32
+#endif
+
+#define IRQ_IXP425_NPEA		0
+#define IRQ_IXP425_NPEB		1
+#define IRQ_IXP425_NPEC		2
+#define IRQ_IXP425_QM1		3
+#define IRQ_IXP425_QM2		4
+#define IRQ_IXP425_TIMER1	5
+#define IRQ_IXP425_GPIO0	6
+#define IRQ_IXP425_GPIO1	7
+#define IRQ_IXP425_PCI_INT	8
+#define IRQ_IXP425_PCI_DMA1	9
+#define IRQ_IXP425_PCI_DMA2	10
+#define IRQ_IXP425_TIMER2	11
+#define IRQ_IXP425_USB		12
+#define IRQ_IXP425_UART2	13
+#define IRQ_IXP425_TIMESTAMP	14
+#define IRQ_IXP425_UART1	15
+#define IRQ_IXP425_WDOG		16
+#define IRQ_IXP425_AHB_PMU	17
+#define IRQ_IXP425_XSCALE_PMU	18
+#define IRQ_IXP425_GPIO2	19
+#define IRQ_IXP425_GPIO3	20
+#define IRQ_IXP425_GPIO4	21
+#define IRQ_IXP425_GPIO5	22
+#define IRQ_IXP425_GPIO6	23
+#define IRQ_IXP425_GPIO7	24
+#define IRQ_IXP425_GPIO8	25
+#define IRQ_IXP425_GPIO9	26
+#define IRQ_IXP425_GPIO10	27
+#define IRQ_IXP425_GPIO11	28
+#define IRQ_IXP425_GPIO12	29
+#define IRQ_IXP425_SW_INT1	30
+#define IRQ_IXP425_SW_INT2	31
+
+#ifdef CONFIG_MACH_IXDP465
+#define IRQ_IXP46X_USB_HOST         (32)
+#define IRQ_IXP46X_I2C              (33)
+#define IRQ_IXP46X_SSP              (34)
+#define IRQ_IXP46X_TSYNC            (35)
+#define IRQ_IXP46X_EAU_DONE         (36)
+#define IRQ_IXP46X_SHA_HASHING_DONE (37)
+#define IRQ_IXP46X_RSVD_38          (38)
+#define IRQ_IXP46X_RSVD_39          (39)
+#define IRQ_IXP46X_RSVD_40          (40)
+#define IRQ_IXP46X_RSVD_41          (41)
+#define IRQ_IXP46X_RSVD_42          (42)
+#define IRQ_IXP46X_RSVD_43          (43)
+#define IRQ_IXP46X_RSVD_44          (44)
+#define IRQ_IXP46X_RSVD_45          (45)
+#define IRQ_IXP46X_RSVD_46          (46)
+#define IRQ_IXP46X_RSVD_47          (47)
+#define IRQ_IXP46X_RSVD_48          (48)
+#define IRQ_IXP46X_RSVD_49          (49)
+#define IRQ_IXP46X_RSVD_50          (50)
+#define IRQ_IXP46X_RSVD_51          (51)
+#define IRQ_IXP46X_RSVD_52          (52)
+#define IRQ_IXP46X_RSVD_53          (53)
+#define IRQ_IXP46X_RSVD_54          (54)
+#define IRQ_IXP46X_RSVD_55          (55)
+#define IRQ_IXP46X_RSVD_56          (56)
+#define IRQ_IXP46X_RSVD_57          (57)
+#define IRQ_IXP46X_SWCP             (58)
+#define IRQ_IXP46X_RSVD_59          (59)
+#define IRQ_IXP46X_AQM              (60)
+#define IRQ_IXP46X_MCU              (61)
+#define IRQ_IXP46X_EBC              (62)
+#define IRQ_IXP46X_RSVD_63          (63)
+#endif
+
+#define IRQ_USB			(IRQ_IXP425_USB)
+#define	XSCALE_PMU_IRQ		(IRQ_IXP425_XSCALE_PMU)
+
+/*
+ * IXDP425 Board IRQs
+ */
+#define	IRQ_IXDP425_PCI_INTA	IRQ_IXP425_GPIO11
+#define	IRQ_IXDP425_PCI_INTB	IRQ_IXP425_GPIO10
+#define	IRQ_IXDP425_PCI_INTC	IRQ_IXP425_GPIO9
+#define	IRQ_IXDP425_PCI_INTD	IRQ_IXP425_GPIO8
+
+/*
+ * PrPMC1100 Board IRQs
+ */
+#define	IRQ_PRPMC1100_PCI_INTA	IRQ_IXP425_GPIO11
+#define	IRQ_PRPMC1100_PCI_INTB	IRQ_IXP425_GPIO10
+#define	IRQ_PRPMC1100_PCI_INTC	IRQ_IXP425_GPIO9
+#define	IRQ_PRPMC1100_PCI_INTD	IRQ_IXP425_GPIO8
+
+/*
+ * ADI Coyote Board IRQs
+ */
+#define IRQ_COYOTE_PCI_INTA	IRQ_IXP425_GPIO11
+#define IRQ_COYOTE_PCI_INTB	IRQ_IXP425_GPIO6
+
+/*
+ * SnapGear ESS710 IRQs
+ */
+#define IRQ_ESS710_PCI_INTA	IRQ_IXP425_GPIO6
+#define IRQ_ESS710_PCI_INTB	IRQ_IXP425_GPIO7
+#define IRQ_ESS710_PCI_INTC	IRQ_IXP425_GPIO8
+
+/*
+ * CyberGuard SG580 Board IRQs
+ */
+#define IRQ_SG580_PCI_INTA	IRQ_IXP425_GPIO8
+
+/*
+ * Intel IXP425 Montejade demonstration platform
+ */
+#define IRQ_MONTEJADE_PCI_INTA	IRQ_IXP425_GPIO6
+#define IRQ_MONTEJADE_PCI_INTB	IRQ_IXP425_GPIO7
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/ivpnss.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/ivpnss.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/ivpnss.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/ivpnss.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,30 @@
+/****************************************************************************/
+
+/*
+ *	ivpnss.h -- ioctl support for the iVPN hardware platform.
+ *
+ *	(C) Copyright 2004,  Greg Ungerer <gerg@snapgear.com>
+ */
+
+/****************************************************************************/
+#ifndef IVPNSS_H
+#define	IVPNSS_H 1
+/****************************************************************************/
+
+#include <linux/ioctl.h>
+
+/*
+ *	Ioctl to support enabling ports on the iVPN hardware.
+ *	Any of the 2 ethernet ports or the WiFi port can be
+ *	enabled or disabled using these.
+ *
+ *	Note: I wouldn't recommend disabling an interface while it was
+ *	still operational, that would be bad :-)
+ */
+#define	ISET_ETH0	_IO('v',0x1)		/* Enable/Disabe eth0 */
+#define	ISET_ETH1	_IO('v',0x2)		/* Enable/Disabe eth1 */
+#define	ISET_WIFI0	_IO('v',0x3)		/* Enable/Disabe WiFi */
+
+/****************************************************************************/
+#endif /* IVPNSS_H */
+/****************************************************************************/
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/ixp425.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/ixp425.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/ixp425.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/ixp425.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,661 @@
+/*
+ * include/asm-arm/arch-ixp425/ixp425.h 
+ *
+ * Register definitions for IXP425 
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H__
+#error "Do not include this directly, please #include <asm/hardware.h>"
+#endif
+
+#ifndef _ASM_ARM_IXP425_H_
+#define _ASM_ARM_IXP425_H_
+
+#ifndef BIT    
+#define BIT(bit)	(1 << (bit))
+#endif
+
+
+/*
+ * 
+ * IXP425 Memory map:
+ *
+ * Phy		Phy Size	Map Size	Virt		Description
+ * =========================================================================
+ *
+ * 0x00000000	0x10000000					SDRAM 1 
+ *
+ * 0x10000000	0x10000000					SDRAM 2
+ *
+ * 0x20000000	0x10000000					SDRAM 3
+ *
+ * 0x30000000	0x10000000					SDRAM 4 
+ *
+ * The above four are aliases to the same memory location  (0x00000000)
+ *
+ * 0x48000000	 0x4000000					PCI Memory
+ *
+ * 0x50000000	0x10000000			Not Mapped	EXP BUS
+ *
+ * 0x6000000	0x00004000	    0x4000	0xFFFEB000	QMgr
+ *
+ * 0xC0000000	     0x100   	    0x1000	0xFFFDD000	PCI CFG 
+ *
+ * 0xC4000000	     0x100          0x1000	0xFFFDE000	EXP CFG 
+ *
+ * 0xC8000000	    0xC000          0xC000	0xFFFDF000	PERIPHERAL
+ *
+ * 0xCC000000	     0x100   	    0x1000	Not Mapped	SDRAM CFG 
+ */
+
+
+/*
+ * PCI Configuration space
+ */
+#define IXP425_PCI_CFG_BASE_PHYS	(0xC0000000)
+#define IXP425_PCI_CFG_BASE_VIRT	(0xFF00C000)
+#define IXP425_PCI_CFG_REGION_SIZE	(0x00001000)
+
+/*
+ * Expansion BUS Configuration registers
+ */
+#define IXP425_EXP_CFG_BASE_PHYS	(0xC4000000)
+#define IXP425_EXP_CFG_BASE_VIRT	(0xFF00D000)
+#define IXP425_EXP_CFG_REGION_SIZE	(0x00001000)
+
+/*
+ * Peripheral space
+ */
+#define IXP425_PERIPHERAL_BASE_PHYS	(0xC8000000)
+#define IXP425_PERIPHERAL_BASE_VIRT	(0xFF000000)
+#define IXP425_PERIPHERAL_REGION_SIZE	(0x0000C000)
+
+/* 
+ * Q Manager space .. not static mapped
+ */
+#define IXP425_QMGR_BASE_PHYS		(0x60000000)
+#define IXP425_QMGR_BASE_VIRT		(0xFF00F000)
+#define IXP425_QMGR_REGION_SIZE		(0x00004000)
+
+/*
+ * Expansion BUS
+ *
+ * Expansion Bus 'lives' at either base1 or base 2 depending on the value of
+ * Exp Bus config registers:
+ *
+ * Setting bit 31 of IXP425_EXP_CFG0 puts SDRAM at zero,
+ * and The expansion bus to IXP425_EXP_BUS_BASE2
+ */
+#define IXP425_EXP_BUS_BASE1_PHYS	(0x00000000)
+#define IXP425_EXP_BUS_BASE2_PHYS	(0x50000000)
+#define IXP425_EXP_BUS_BASE2_VIRT	(0xF0000000)
+
+#define IXP425_EXP_BUS_BASE_PHYS	IXP425_EXP_BUS_BASE2_PHYS
+#define IXP425_EXP_BUS_BASE_VIRT	IXP425_EXP_BUS_BASE2_VIRT
+
+#define IXP425_EXP_BUS_REGION_SIZE	(0x08000000)
+#define IXP425_EXP_BUS_CSX_REGION_SIZE	(0x01000000)
+
+#define IXP425_EXP_BUS_CS0_BASE_PHYS	(IXP425_EXP_BUS_BASE2_PHYS + 0x00000000)
+#define IXP425_EXP_BUS_CS1_BASE_PHYS	(IXP425_EXP_BUS_BASE2_PHYS + 0x01000000)
+#define IXP425_EXP_BUS_CS2_BASE_PHYS	(IXP425_EXP_BUS_BASE2_PHYS + 0x02000000)
+#define IXP425_EXP_BUS_CS3_BASE_PHYS	(IXP425_EXP_BUS_BASE2_PHYS + 0x03000000)
+#define IXP425_EXP_BUS_CS4_BASE_PHYS	(IXP425_EXP_BUS_BASE2_PHYS + 0x04000000)
+#define IXP425_EXP_BUS_CS5_BASE_PHYS	(IXP425_EXP_BUS_BASE2_PHYS + 0x05000000)
+#define IXP425_EXP_BUS_CS6_BASE_PHYS	(IXP425_EXP_BUS_BASE2_PHYS + 0x06000000)
+#define IXP425_EXP_BUS_CS7_BASE_PHYS	(IXP425_EXP_BUS_BASE2_PHYS + 0x07000000)
+
+#define IXP425_EXP_BUS_CS0_BASE_VIRT	(IXP425_EXP_BUS_BASE2_VIRT + 0x00000000)
+#define IXP425_EXP_BUS_CS1_BASE_VIRT	(IXP425_EXP_BUS_BASE2_VIRT + 0x01000000)
+#define IXP425_EXP_BUS_CS2_BASE_VIRT	(IXP425_EXP_BUS_BASE2_VIRT + 0x02000000)
+#define IXP425_EXP_BUS_CS3_BASE_VIRT	(IXP425_EXP_BUS_BASE2_VIRT + 0x03000000)
+#define IXP425_EXP_BUS_CS4_BASE_VIRT	(IXP425_EXP_BUS_BASE2_VIRT + 0x04000000)
+#define IXP425_EXP_BUS_CS5_BASE_VIRT	(IXP425_EXP_BUS_BASE2_VIRT + 0x05000000)
+#define IXP425_EXP_BUS_CS6_BASE_VIRT	(IXP425_EXP_BUS_BASE2_VIRT + 0x06000000)
+#define IXP425_EXP_BUS_CS7_BASE_VIRT	(IXP425_EXP_BUS_BASE2_VIRT + 0x07000000)
+
+#define IXP425_FLASH_WRITABLE	(0x2)
+#define IXP425_FLASH_DEFAULT	(0xbcd23c40)
+#define IXP425_FLASH_WRITE	(0xbcd23c42)
+
+
+#define IXP425_EXP_CS0_OFFSET	0x00
+#define IXP425_EXP_CS1_OFFSET   0x04
+#define IXP425_EXP_CS2_OFFSET   0x08
+#define IXP425_EXP_CS3_OFFSET   0x0C
+#define IXP425_EXP_CS4_OFFSET   0x10
+#define IXP425_EXP_CS5_OFFSET   0x14
+#define IXP425_EXP_CS6_OFFSET   0x18
+#define IXP425_EXP_CS7_OFFSET   0x1C
+#define IXP425_EXP_CFG0_OFFSET	0x20
+#define IXP425_EXP_CFG1_OFFSET	0x24
+#define IXP425_EXP_CFG2_OFFSET	0x28
+#define IXP425_EXP_CFG3_OFFSET	0x2C
+
+/*
+ * Expansion Bus Controller registers.
+ */
+#define IXP425_EXP_REG(x) ((volatile u32 *)(IXP425_EXP_CFG_BASE_VIRT+(x)))
+
+#define IXP425_EXP_CS0      IXP425_EXP_REG(IXP425_EXP_CS0_OFFSET)
+#define IXP425_EXP_CS1      IXP425_EXP_REG(IXP425_EXP_CS1_OFFSET)
+#define IXP425_EXP_CS2      IXP425_EXP_REG(IXP425_EXP_CS2_OFFSET) 
+#define IXP425_EXP_CS3      IXP425_EXP_REG(IXP425_EXP_CS3_OFFSET)
+#define IXP425_EXP_CS4      IXP425_EXP_REG(IXP425_EXP_CS4_OFFSET)
+#define IXP425_EXP_CS5      IXP425_EXP_REG(IXP425_EXP_CS5_OFFSET)
+#define IXP425_EXP_CS6      IXP425_EXP_REG(IXP425_EXP_CS6_OFFSET)     
+#define IXP425_EXP_CS7      IXP425_EXP_REG(IXP425_EXP_CS7_OFFSET)
+
+#define IXP425_EXP_CFG0     IXP425_EXP_REG(IXP425_EXP_CFG0_OFFSET) 
+#define IXP425_EXP_CFG1     IXP425_EXP_REG(IXP425_EXP_CFG1_OFFSET) 
+#define IXP425_EXP_CFG2     IXP425_EXP_REG(IXP425_EXP_CFG2_OFFSET) 
+#define IXP425_EXP_CFG3     IXP425_EXP_REG(IXP425_EXP_CFG3_OFFSET)
+
+
+/*
+ * Peripheral Space Registers 
+ */
+#define IXP425_UART1_BASE_PHYS	(IXP425_PERIPHERAL_BASE_PHYS + 0x0000)
+#define IXP425_UART2_BASE_PHYS	(IXP425_PERIPHERAL_BASE_PHYS + 0x1000)
+#define IXP425_PMU_BASE_PHYS	(IXP425_PERIPHERAL_BASE_PHYS + 0x2000)
+#define IXP425_INTC_BASE_PHYS	(IXP425_PERIPHERAL_BASE_PHYS + 0x3000)
+#define IXP425_GPIO_BASE_PHYS	(IXP425_PERIPHERAL_BASE_PHYS + 0x4000)
+#define IXP425_TIMER_BASE_PHYS	(IXP425_PERIPHERAL_BASE_PHYS + 0x5000)
+#define IXP425_NPEA_BASE_PHYS	(IXP425_PERIPHERAL_BASE_PHYS + 0x6000)
+#define IXP425_NPEB_BASE_PHYS	(IXP425_PERIPHERAL_BASE_PHYS + 0x7000)
+#define IXP425_NPEC_BASE_PHYS	(IXP425_PERIPHERAL_BASE_PHYS + 0x8000)
+#define IXP425_EthA_BASE_PHYS	(IXP425_PERIPHERAL_BASE_PHYS + 0x9000)
+#define IXP425_EthB_BASE_PHYS	(IXP425_PERIPHERAL_BASE_PHYS + 0xA000)
+#define IXP425_USB_BASE_PHYS	(IXP425_PERIPHERAL_BASE_PHYS + 0xB000)
+
+#define IXP425_UART1_BASE_VIRT	(IXP425_PERIPHERAL_BASE_VIRT + 0x0000)
+#define IXP425_UART2_BASE_VIRT	(IXP425_PERIPHERAL_BASE_VIRT + 0x1000)
+#define IXP425_PMU_BASE_VIRT	(IXP425_PERIPHERAL_BASE_VIRT + 0x2000)
+#define IXP425_INTC_BASE_VIRT	(IXP425_PERIPHERAL_BASE_VIRT + 0x3000)
+#define IXP425_GPIO_BASE_VIRT	(IXP425_PERIPHERAL_BASE_VIRT + 0x4000)
+#define IXP425_TIMER_BASE_VIRT	(IXP425_PERIPHERAL_BASE_VIRT + 0x5000)
+#define IXP425_NPEA_BASE_VIRT	(IXP425_PERIPHERAL_BASE_VIRT + 0x6000)
+#define IXP425_NPEB_BASE_VIRT	(IXP425_PERIPHERAL_BASE_VIRT + 0x7000)
+#define IXP425_NPEC_BASE_VIRT	(IXP425_PERIPHERAL_BASE_VIRT + 0x8000)
+#define IXP425_EthA_BASE_VIRT	(IXP425_PERIPHERAL_BASE_VIRT + 0x9000)
+#define IXP425_EthB_BASE_VIRT	(IXP425_PERIPHERAL_BASE_VIRT + 0xA000)
+#define IXP425_USB_BASE_VIRT	(IXP425_PERIPHERAL_BASE_VIRT + 0xB000)
+
+
+/* 
+ * UART Register Definitions , Offsets only as there are 2 UARTS.
+ *   IXP425_UART1_BASE , IXP425_UART2_BASE.
+ */
+
+#undef  UART_NO_RX_INTERRUPT
+
+#if defined(CONFIG_IVPN_20MHZ)
+#define IXP425_UART_XTAL        10690559
+#elif defined(CONFIG_MACH_IVPN)
+#define IXP425_UART_XTAL        13271040
+#else
+#define IXP425_UART_XTAL        14745600
+#endif
+
+/*
+ * Constants to make it easy to access  Interrupt Controller registers
+ */
+#define IXP425_ICPR_OFFSET	0x00 /* Interrupt Status */
+#define IXP425_ICMR_OFFSET	0x04 /* Interrupt Enable */
+#define IXP425_ICLR_OFFSET	0x08 /* Interrupt IRQ/FIQ Select */
+#define IXP425_ICIP_OFFSET      0x0C /* IRQ Status */
+#define IXP425_ICFP_OFFSET	0x10 /* FIQ Status */
+#define IXP425_ICHR_OFFSET	0x14 /* Interrupt Priority */
+#define IXP425_ICIH_OFFSET	0x18 /* IRQ Highest Pri Int */
+#define IXP425_ICFH_OFFSET	0x1C /* FIQ Highest Pri Int */
+
+#define IXP425_ICPR2_OFFSET	0x20 /* Interrupt Status */
+#define IXP425_ICMR2_OFFSET	0x24 /* Interrupt Enable */
+#define IXP425_ICLR2_OFFSET	0x28 /* Interrupt IRQ/FIQ Select */
+#define IXP425_ICIP2_OFFSET      0x2C /* IRQ Status */
+#define IXP425_ICFP2_OFFSET	0x30 /* FIQ Status */
+#define IXP425_ICHR2_OFFSET	0x34 /* Interrupt Priority */
+#define IXP425_ICIH2_OFFSET	0x38 /* IRQ Highest Pri Int */
+#define IXP425_ICFH2_OFFSET	0x3C /* FIQ Highest Pri Int */
+
+/*
+ * Interrupt Controller Register Definitions.
+ */
+#define IXP425_INTC_REG(x) ((volatile u32 *)(IXP425_INTC_BASE_VIRT+(x)))
+
+#define IXP425_ICPR     IXP425_INTC_REG(IXP425_ICPR_OFFSET)
+#define IXP425_ICMR     IXP425_INTC_REG(IXP425_ICMR_OFFSET)
+#define IXP425_ICLR     IXP425_INTC_REG(IXP425_ICLR_OFFSET)
+#define IXP425_ICIP     IXP425_INTC_REG(IXP425_ICIP_OFFSET)
+#define IXP425_ICFP     IXP425_INTC_REG(IXP425_ICFP_OFFSET)
+#define IXP425_ICHR     IXP425_INTC_REG(IXP425_ICHR_OFFSET)
+#define IXP425_ICIH     IXP425_INTC_REG(IXP425_ICIH_OFFSET) 
+#define IXP425_ICFH     IXP425_INTC_REG(IXP425_ICFH_OFFSET)
+                                                                                
+#define IXP425_ICPR2    IXP425_INTC_REG(IXP425_ICPR2_OFFSET)
+#define IXP425_ICMR2    IXP425_INTC_REG(IXP425_ICMR2_OFFSET)
+#define IXP425_ICLR2    IXP425_INTC_REG(IXP425_ICLR2_OFFSET)
+#define IXP425_ICIP2    IXP425_INTC_REG(IXP425_ICIP2_OFFSET)
+#define IXP425_ICFP2    IXP425_INTC_REG(IXP425_ICFP2_OFFSET)
+#define IXP425_ICHR2    IXP425_INTC_REG(IXP425_ICHR2_OFFSET)
+#define IXP425_ICIH2    IXP425_INTC_REG(IXP425_ICIH2_OFFSET) 
+#define IXP425_ICFH2    IXP425_INTC_REG(IXP425_ICFH2_OFFSET)
+                                                                                
+/*
+ * Constants to make it easy to access GPIO registers
+ */
+#define IXP425_GPIO_GPOUTR_OFFSET       0x00
+#define IXP425_GPIO_GPOER_OFFSET        0x04
+#define IXP425_GPIO_GPINR_OFFSET        0x08
+#define IXP425_GPIO_GPISR_OFFSET        0x0C
+#define IXP425_GPIO_GPIT1R_OFFSET	0x10
+#define IXP425_GPIO_GPIT2R_OFFSET	0x14
+#define IXP425_GPIO_GPCLKR_OFFSET	0x18
+#define IXP425_GPIO_GPDBSELR_OFFSET	0x1C
+
+/* 
+ * GPIO Register Definitions.
+ * [Only perform 32bit reads/writes]
+ */
+#define IXP425_GPIO_REG(x) ((volatile u32 *)(IXP425_GPIO_BASE_VIRT+(x)))
+
+#define IXP425_GPIO_GPOUTR	IXP425_GPIO_REG(IXP425_GPIO_GPOUTR_OFFSET)
+#define IXP425_GPIO_GPOER       IXP425_GPIO_REG(IXP425_GPIO_GPOER_OFFSET)
+#define IXP425_GPIO_GPINR       IXP425_GPIO_REG(IXP425_GPIO_GPINR_OFFSET)
+#define IXP425_GPIO_GPISR       IXP425_GPIO_REG(IXP425_GPIO_GPISR_OFFSET)
+#define IXP425_GPIO_GPIT1R      IXP425_GPIO_REG(IXP425_GPIO_GPIT1R_OFFSET)
+#define IXP425_GPIO_GPIT2R      IXP425_GPIO_REG(IXP425_GPIO_GPIT2R_OFFSET)
+#define IXP425_GPIO_GPCLKR      IXP425_GPIO_REG(IXP425_GPIO_GPCLKR_OFFSET)
+#define IXP425_GPIO_GPDBSELR    IXP425_GPIO_REG(IXP425_GPIO_GPDBSELR_OFFSET)
+
+/*
+ * Constants to make it easy to access Timer Control/Status registers
+ */
+#define IXP425_OSTS_OFFSET	0x00  /* Continious TimeStamp */
+#define IXP425_OST1_OFFSET	0x04  /* Timer 1 Timestamp */
+#define IXP425_OSRT1_OFFSET	0x08  /* Timer 1 Reload */
+#define IXP425_OST2_OFFSET	0x0C  /* Timer 2 Timestamp */
+#define IXP425_OSRT2_OFFSET	0x10  /* Timer 2 Reload */
+#define IXP425_OSWT_OFFSET	0x14  /* Watchdog Timer */
+#define IXP425_OSWE_OFFSET	0x18  /* Watchdog Enable */
+#define IXP425_OSWK_OFFSET	0x1C  /* Watchdog Key */
+#define IXP425_OSST_OFFSET	0x20  /* Timer Status */
+
+/*
+ * Operating System Timer Register Definitions.
+ */
+
+#define IXP425_TIMER_REG(x) ((volatile u32 *)(IXP425_TIMER_BASE_VIRT+(x)))
+
+#define IXP425_OSTS	IXP425_TIMER_REG(IXP425_OSTS_OFFSET)
+#define IXP425_OST1	IXP425_TIMER_REG(IXP425_OST1_OFFSET)
+#define IXP425_OSRT1	IXP425_TIMER_REG(IXP425_OSRT1_OFFSET)
+#define IXP425_OST2	IXP425_TIMER_REG(IXP425_OST2_OFFSET)
+#define IXP425_OSRT2	IXP425_TIMER_REG(IXP425_OSRT2_OFFSET)
+#define IXP425_OSWT	IXP425_TIMER_REG(IXP425_OSWT_OFFSET)
+#define IXP425_OSWE	IXP425_TIMER_REG(IXP425_OSWE_OFFSET)
+#define IXP425_OSWK	IXP425_TIMER_REG(IXP425_OSWK_OFFSET)
+#define IXP425_OSST	IXP425_TIMER_REG(IXP425_OSST_OFFSET)
+
+/*
+ * Timer register values and bit definitions 
+ */
+#define IXP425_OST_ENABLE              BIT(0)
+#define IXP425_OST_ONE_SHOT            BIT(1)
+/* Low order bits of reload value ignored */
+#define IXP425_OST_RELOAD_MASK         (0x3)    
+#define IXP425_OST_DISABLED            (0x0)
+#define IXP425_OSST_TIMER_1_PEND       BIT(0)
+#define IXP425_OSST_TIMER_2_PEND       BIT(1)
+#define IXP425_OSST_TIMER_TS_PEND      BIT(2)
+#define IXP425_OSST_TIMER_WDOG_PEND    BIT(3)
+#define IXP425_OSST_TIMER_WARM_RESET   BIT(4)
+
+/*
+ * Constants to make it easy to access PCI Control/Status registers
+ */
+#define PCI_NP_AD_OFFSET            0x00
+#define PCI_NP_CBE_OFFSET           0x04
+#define PCI_NP_WDATA_OFFSET         0x08
+#define PCI_NP_RDATA_OFFSET         0x0c
+#define PCI_CRP_AD_CBE_OFFSET       0x10
+#define PCI_CRP_WDATA_OFFSET        0x14
+#define PCI_CRP_RDATA_OFFSET        0x18
+#define PCI_CSR_OFFSET              0x1c
+#define PCI_ISR_OFFSET              0x20
+#define PCI_INTEN_OFFSET            0x24
+#define PCI_DMACTRL_OFFSET          0x28
+#define PCI_AHBMEMBASE_OFFSET       0x2c
+#define PCI_AHBIOBASE_OFFSET        0x30
+#define PCI_PCIMEMBASE_OFFSET       0x34
+#define PCI_AHBDOORBELL_OFFSET      0x38
+#define PCI_PCIDOORBELL_OFFSET      0x3C
+#define PCI_ATPDMA0_AHBADDR_OFFSET  0x40
+#define PCI_ATPDMA0_PCIADDR_OFFSET  0x44
+#define PCI_ATPDMA0_LENADDR_OFFSET  0x48
+#define PCI_ATPDMA1_AHBADDR_OFFSET  0x4C
+#define PCI_ATPDMA1_PCIADDR_OFFSET  0x50
+#define PCI_ATPDMA1_LENADDR_OFFSET	0x54
+
+/*
+ * PCI Control/Status Registers
+ */
+#define IXP425_PCI_CSR(x) ((volatile u32 *)(IXP425_PCI_CFG_BASE_VIRT+(x)))
+
+#define PCI_NP_AD               IXP425_PCI_CSR(PCI_NP_AD_OFFSET)
+#define PCI_NP_CBE              IXP425_PCI_CSR(PCI_NP_CBE_OFFSET)
+#define PCI_NP_WDATA            IXP425_PCI_CSR(PCI_NP_WDATA_OFFSET)
+#define PCI_NP_RDATA            IXP425_PCI_CSR(PCI_NP_RDATA_OFFSET)
+#define PCI_CRP_AD_CBE          IXP425_PCI_CSR(PCI_CRP_AD_CBE_OFFSET)
+#define PCI_CRP_WDATA           IXP425_PCI_CSR(PCI_CRP_WDATA_OFFSET)
+#define PCI_CRP_RDATA           IXP425_PCI_CSR(PCI_CRP_RDATA_OFFSET)
+#define PCI_CSR                 IXP425_PCI_CSR(PCI_CSR_OFFSET) 
+#define PCI_ISR                 IXP425_PCI_CSR(PCI_ISR_OFFSET)
+#define PCI_INTEN               IXP425_PCI_CSR(PCI_INTEN_OFFSET)
+#define PCI_DMACTRL             IXP425_PCI_CSR(PCI_DMACTRL_OFFSET)
+#define PCI_AHBMEMBASE          IXP425_PCI_CSR(PCI_AHBMEMBASE_OFFSET)
+#define PCI_AHBIOBASE           IXP425_PCI_CSR(PCI_AHBIOBASE_OFFSET)
+#define PCI_PCIMEMBASE          IXP425_PCI_CSR(PCI_PCIMEMBASE_OFFSET)
+#define PCI_AHBDOORBELL         IXP425_PCI_CSR(PCI_AHBDOORBELL_OFFSET)
+#define PCI_PCIDOORBELL         IXP425_PCI_CSR(PCI_PCIDOORBELL_OFFSET)
+#define PCI_ATPDMA0_AHBADDR     IXP425_PCI_CSR(PCI_ATPDMA0_AHBADDR_OFFSET)
+#define PCI_ATPDMA0_PCIADDR     IXP425_PCI_CSR(PCI_ATPDMA0_PCIADDR_OFFSET)
+#define PCI_ATPDMA0_LENADDR     IXP425_PCI_CSR(PCI_ATPDMA0_LENADDR_OFFSET)
+#define PCI_ATPDMA1_AHBADDR     IXP425_PCI_CSR(PCI_ATPDMA1_AHBADDR_OFFSET)
+#define PCI_ATPDMA1_PCIADDR     IXP425_PCI_CSR(PCI_ATPDMA1_PCIADDR_OFFSET)
+#define PCI_ATPDMA1_LENADDR     IXP425_PCI_CSR(PCI_ATPDMA1_LENADDR_OFFSET)
+
+/*
+ * PCI register values and bit definitions 
+ */
+
+/* CSR bit definitions */
+#define PCI_CSR_HOST    	BIT(0)
+#define PCI_CSR_ARBEN   	BIT(1)
+#define PCI_CSR_ADS     	BIT(2)
+#define PCI_CSR_PDS     	BIT(3)
+#define PCI_CSR_ABE     	BIT(4)
+#define PCI_CSR_DBT     	BIT(5)
+#define PCI_CSR_ASE     	BIT(8)
+#define PCI_CSR_IC      	BIT(15)
+
+/* ISR (Interrupt status) Register bit definitions */
+#define PCI_ISR_PSE     	BIT(0)
+#define PCI_ISR_PFE     	BIT(1)
+#define PCI_ISR_PPE     	BIT(2)
+#define PCI_ISR_AHBE    	BIT(3)
+#define PCI_ISR_APDC    	BIT(4)
+#define PCI_ISR_PADC    	BIT(5)
+#define PCI_ISR_ADB     	BIT(6)
+#define PCI_ISR_PDB     	BIT(7)
+
+/* INTEN (Interrupt Enable) Register bit definitions */
+#define PCI_INTEN_PSE   	BIT(0)
+#define PCI_INTEN_PFE   	BIT(1)
+#define PCI_INTEN_PPE   	BIT(2)
+#define PCI_INTEN_AHBE  	BIT(3)
+#define PCI_INTEN_APDC  	BIT(4)
+#define PCI_INTEN_PADC  	BIT(5)
+#define PCI_INTEN_ADB   	BIT(6)
+#define PCI_INTEN_PDB   	BIT(7)
+
+/*
+ * Shift value for byte enable on NP cmd/byte enable register
+ */
+#define IXP425_PCI_NP_CBE_BESL		4
+
+/*
+ * PCI commands supported by NP access unit
+ */
+#define NP_CMD_IOREAD			0x2
+#define NP_CMD_IOWRITE			0x3
+#define NP_CMD_CONFIGREAD		0xa
+#define NP_CMD_CONFIGWRITE		0xb
+#define NP_CMD_MEMREAD			0x6
+#define	NP_CMD_MEMWRITE			0x7
+
+#ifndef __ASSEMBLY__
+extern int (*ixp425_pci_read)(u32 addr, u32 cmd, u32* data);
+extern int ixp425_pci_write(u32 addr, u32 cmd, u32 data);
+extern void ixp425_pci_init(void *);
+#endif
+
+/*
+ * Constants for CRP access into local config space
+ */
+#define CRP_AD_CBE_BESL         20
+#define CRP_AD_CBE_WRITE        BIT(16)
+
+/*
+ * Clock Speed Definitions. The CyberGuard iVPN has a 30MHz base clock
+ * (to reduce power consumption).
+ */
+#if CONFIG_MACH_IVPN
+#define IXP425_PERIPHERAL_BUS_CLOCK (60) /* 60Mhzi APB BUS   */ 
+#else
+#define IXP425_PERIPHERAL_BUS_CLOCK (66) /* 66Mhzi APB BUS   */ 
+#endif
+
+#ifndef NO_LINUX_IXP425_USB
+/*
+ * USB Device Controller
+ *
+ * These are used by the USB gadget driver, so they don't follow the
+ * IXP425_ naming convetions.
+ *
+ */
+# define IXP425_USB_REG(x)       (*((volatile u32 *)(x)))
+
+/* UDC Undocumented - Reserved1 */
+#define UDC_RES1	IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0004)  
+/* UDC Undocumented - Reserved2 */
+#define UDC_RES2	IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0008)  
+/* UDC Undocumented - Reserved3 */
+#define UDC_RES3	IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x000C)  
+/* UDC Control Register */
+#define UDCCR		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0000)  
+/* UDC Endpoint 0 Control/Status Register */
+#define UDCCS0		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0010)  
+/* UDC Endpoint 1 (IN) Control/Status Register */
+#define UDCCS1		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0014)  
+/* UDC Endpoint 2 (OUT) Control/Status Register */
+#define UDCCS2		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0018)  
+/* UDC Endpoint 3 (IN) Control/Status Register */
+#define UDCCS3		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x001C)  
+/* UDC Endpoint 4 (OUT) Control/Status Register */
+#define UDCCS4		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0020)  
+/* UDC Endpoint 5 (Interrupt) Control/Status Register */
+#define UDCCS5		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0024)  
+/* UDC Endpoint 6 (IN) Control/Status Register */
+#define UDCCS6		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0028)  
+/* UDC Endpoint 7 (OUT) Control/Status Register */
+#define UDCCS7		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x002C)  
+/* UDC Endpoint 8 (IN) Control/Status Register */
+#define UDCCS8		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0030)  
+/* UDC Endpoint 9 (OUT) Control/Status Register */
+#define UDCCS9		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0034)  
+/* UDC Endpoint 10 (Interrupt) Control/Status Register */
+#define UDCCS10		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0038)  
+/* UDC Endpoint 11 (IN) Control/Status Register */
+#define UDCCS11		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x003C)  
+/* UDC Endpoint 12 (OUT) Control/Status Register */
+#define UDCCS12		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0040)  
+/* UDC Endpoint 13 (IN) Control/Status Register */
+#define UDCCS13		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0044)  
+/* UDC Endpoint 14 (OUT) Control/Status Register */
+#define UDCCS14		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0048)  
+/* UDC Endpoint 15 (Interrupt) Control/Status Register */
+#define UDCCS15		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x004C)  
+/* UDC Frame Number Register High */
+#define UFNRH		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0060)  
+/* UDC Frame Number Register Low */
+#define UFNRL		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0064)  
+/* UDC Byte Count Reg 2 */
+#define UBCR2		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0068)  
+/* UDC Byte Count Reg 4 */
+#define UBCR4		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x006c)  
+/* UDC Byte Count Reg 7 */
+#define UBCR7		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0070)  
+/* UDC Byte Count Reg 9 */
+#define UBCR9		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0074)  
+/* UDC Byte Count Reg 12 */
+#define UBCR12		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0078)  
+/* UDC Byte Count Reg 14 */
+#define UBCR14		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x007c)  
+/* UDC Endpoint 0 Data Register */
+#define UDDR0		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0080)  
+/* UDC Endpoint 1 Data Register */
+#define UDDR1		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0100)  
+/* UDC Endpoint 2 Data Register */
+#define UDDR2		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0180)  
+/* UDC Endpoint 3 Data Register */
+#define UDDR3		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0200)  
+/* UDC Endpoint 4 Data Register */
+#define UDDR4		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0400)  
+/* UDC Endpoint 5 Data Register */
+#define UDDR5		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x00A0)  
+/* UDC Endpoint 6 Data Register */
+#define UDDR6		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0600)  
+/* UDC Endpoint 7 Data Register */
+#define UDDR7		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0680)  
+/* UDC Endpoint 8 Data Register */
+#define UDDR8		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0700)  
+/* UDC Endpoint 9 Data Register */
+#define UDDR9		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0900)  
+/* UDC Endpoint 10 Data Register */
+#define UDDR10		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x00C0)  
+/* UDC Endpoint 11 Data Register */
+#define UDDR11		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0B00)  
+/* UDC Endpoint 12 Data Register */
+#define UDDR12		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0B80)  
+/* UDC Endpoint 13 Data Register */
+#define UDDR13		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0C00)  
+/* UDC Endpoint 14 Data Register */
+#define UDDR14		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0E00)  
+/* UDC Endpoint 15 Data Register */
+#define UDDR15		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x00E0)  
+/* UDC Interrupt Control Register 0 */
+#define UICR0		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0050)  
+/* UDC Interrupt Control Register 1 */
+#define UICR1		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0054)  
+/* UDC Status Interrupt Register 0 */
+#define USIR0		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x0058)  
+/* UDC Status Interrupt Register 1 */
+#define USIR1		IXP425_USB_REG(IXP425_USB_BASE_VIRT+0x005C)  
+
+#define UDCCR_UDE	(1 << 0)	/* UDC enable */
+#define UDCCR_UDA	(1 << 1)	/* UDC active */
+#define UDCCR_RSM	(1 << 2)	/* Device resume */
+#define UDCCR_RESIR	(1 << 3)	/* Resume interrupt request */
+#define UDCCR_SUSIR	(1 << 4)	/* Suspend interrupt request */
+#define UDCCR_SRM	(1 << 5)	/* Suspend/resume interrupt mask */
+#define UDCCR_RSTIR	(1 << 6)	/* Reset interrupt request */
+#define UDCCR_REM	(1 << 7)	/* Reset interrupt mask */
+
+#define UDCCS0_OPR	(1 << 0)	/* OUT packet ready */
+#define UDCCS0_IPR	(1 << 1)	/* IN packet ready */
+#define UDCCS0_FTF	(1 << 2)	/* Flush Tx FIFO */
+#define UDCCS0_DRWF	(1 << 3)	/* Device remote wakeup feature */
+#define UDCCS0_SST	(1 << 4)	/* Sent stall */
+#define UDCCS0_FST	(1 << 5)	/* Force stall */
+#define UDCCS0_RNE	(1 << 6)	/* Receive FIFO no empty */
+#define UDCCS0_SA	(1 << 7)	/* Setup active */
+
+#define UDCCS_BI_TFS	(1 << 0)	/* Transmit FIFO service */
+#define UDCCS_BI_TPC	(1 << 1)	/* Transmit packet complete */
+#define UDCCS_BI_FTF	(1 << 2)	/* Flush Tx FIFO */
+#define UDCCS_BI_TUR	(1 << 3)	/* Transmit FIFO underrun */
+#define UDCCS_BI_SST	(1 << 4)	/* Sent stall */
+#define UDCCS_BI_FST	(1 << 5)	/* Force stall */
+#define UDCCS_BI_TSP	(1 << 7)	/* Transmit short packet */
+
+#define UDCCS_BO_RFS	(1 << 0)	/* Receive FIFO service */
+#define UDCCS_BO_RPC	(1 << 1)	/* Receive packet complete */
+#define UDCCS_BO_DME	(1 << 3)	/* DMA enable */
+#define UDCCS_BO_SST	(1 << 4)	/* Sent stall */
+#define UDCCS_BO_FST	(1 << 5)	/* Force stall */
+#define UDCCS_BO_RNE	(1 << 6)	/* Receive FIFO not empty */
+#define UDCCS_BO_RSP	(1 << 7)	/* Receive short packet */
+
+#define UDCCS_II_TFS	(1 << 0)	/* Transmit FIFO service */
+#define UDCCS_II_TPC	(1 << 1)	/* Transmit packet complete */
+#define UDCCS_II_FTF	(1 << 2)	/* Flush Tx FIFO */
+#define UDCCS_II_TUR	(1 << 3)	/* Transmit FIFO underrun */
+#define UDCCS_II_TSP	(1 << 7)	/* Transmit short packet */
+
+#define UDCCS_IO_RFS	(1 << 0)	/* Receive FIFO service */
+#define UDCCS_IO_RPC	(1 << 1)	/* Receive packet complete */
+#define UDCCS_IO_ROF	(1 << 3)	/* Receive overflow */
+#define UDCCS_IO_DME	(1 << 3)	/* DMA enable */
+#define UDCCS_IO_RNE	(1 << 6)	/* Receive FIFO not empty */
+#define UDCCS_IO_RSP	(1 << 7)	/* Receive short packet */
+
+#define UDCCS_INT_TFS	(1 << 0)	/* Transmit FIFO service */
+#define UDCCS_INT_TPC	(1 << 1)	/* Transmit packet complete */
+#define UDCCS_INT_FTF	(1 << 2)	/* Flush Tx FIFO */
+#define UDCCS_INT_TUR	(1 << 3)	/* Transmit FIFO underrun */
+#define UDCCS_INT_SST	(1 << 4)	/* Sent stall */
+#define UDCCS_INT_FST	(1 << 5)	/* Force stall */
+#define UDCCS_INT_TSP	(1 << 7)	/* Transmit short packet */
+
+#define UICR0_IM0	(1 << 0)	/* Interrupt mask ep 0 */
+#define UICR0_IM1	(1 << 1)	/* Interrupt mask ep 1 */
+#define UICR0_IM2	(1 << 2)	/* Interrupt mask ep 2 */
+#define UICR0_IM3	(1 << 3)	/* Interrupt mask ep 3 */
+#define UICR0_IM4	(1 << 4)	/* Interrupt mask ep 4 */
+#define UICR0_IM5	(1 << 5)	/* Interrupt mask ep 5 */
+#define UICR0_IM6	(1 << 6)	/* Interrupt mask ep 6 */
+#define UICR0_IM7	(1 << 7)	/* Interrupt mask ep 7 */
+
+#define UICR1_IM8	(1 << 0)	/* Interrupt mask ep 8 */
+#define UICR1_IM9	(1 << 1)	/* Interrupt mask ep 9 */
+#define UICR1_IM10	(1 << 2)	/* Interrupt mask ep 10 */
+#define UICR1_IM11	(1 << 3)	/* Interrupt mask ep 11 */
+#define UICR1_IM12	(1 << 4)	/* Interrupt mask ep 12 */
+#define UICR1_IM13	(1 << 5)	/* Interrupt mask ep 13 */
+#define UICR1_IM14	(1 << 6)	/* Interrupt mask ep 14 */
+#define UICR1_IM15	(1 << 7)	/* Interrupt mask ep 15 */
+
+#define USIR0_IR0	(1 << 0)	/* Interrup request ep 0 */
+#define USIR0_IR1	(1 << 1)	/* Interrup request ep 1 */
+#define USIR0_IR2	(1 << 2)	/* Interrup request ep 2 */
+#define USIR0_IR3	(1 << 3)	/* Interrup request ep 3 */
+#define USIR0_IR4	(1 << 4)	/* Interrup request ep 4 */
+#define USIR0_IR5	(1 << 5)	/* Interrup request ep 5 */
+#define USIR0_IR6	(1 << 6)	/* Interrup request ep 6 */
+#define USIR0_IR7	(1 << 7)	/* Interrup request ep 7 */
+
+#define USIR1_IR8	(1 << 0)	/* Interrup request ep 8 */
+#define USIR1_IR9	(1 << 1)	/* Interrup request ep 9 */
+#define USIR1_IR10	(1 << 2)	/* Interrup request ep 10 */
+#define USIR1_IR11	(1 << 3)	/* Interrup request ep 11 */
+#define USIR1_IR12	(1 << 4)	/* Interrup request ep 12 */
+#define USIR1_IR13	(1 << 5)	/* Interrup request ep 13 */
+#define USIR1_IR14	(1 << 6)	/* Interrup request ep 14 */
+#define USIR1_IR15	(1 << 7)	/* Interrup request ep 15 */
+
+#define DCMD_LENGTH	0x01fff		/* length mask (max = 8K - 1) */
+
+#endif	/* NO_LINUX_IXP425_USB */
+
+#ifndef __ASSEMBLY__
+static inline int cpu_is_ixp46x(void)
+{
+#ifdef CONFIG_MACH_IXDP465
+	return 1;
+#else
+	return 0;
+#endif
+}
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/memory.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/memory.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/memory.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,49 @@
+/*
+ * linux/include/asm-arm/arch-ixp425/memory.h
+ *
+ * Copyright (c) 2001 MontaVista Software, Inc.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define TASK_SIZE	((unsigned long)(CONFIG_KERNEL_START & 0xffc00000))
+#define TASK_SIZE_26	(0x04000000UL)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+
+#define PAGE_OFFSET	((unsigned long)(CONFIG_KERNEL_START & 0xffc00000))
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET	(0x00000000UL)
+
+/*
+ * physical vs virtual ram conversion
+ */
+#define __virt_to_phys__is_a_macro
+#define __phys_to_virt__is_a_macro
+#define __virt_to_phys(x)	((x) - PAGE_OFFSET + PHYS_OFFSET)
+#define __phys_to_virt(x)	((x) - PHYS_OFFSET + PAGE_OFFSET)
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *		address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *		to an address that the kernel can use.
+ *
+ * These are dummies for now.
+ */
+#define __virt_to_bus__is_a_macro
+#define __bus_to_virt__is_a_macro
+#define __virt_to_bus(x)	 __virt_to_phys(x)
+#define __bus_to_virt(x)	 __phys_to_virt(x)
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/param.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/param.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/param.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,3 @@
+/*
+ * linux/include/asm-arm/arch-ixp425/param.h
+ */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/pci_auto.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/pci_auto.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/pci_auto.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/pci_auto.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-iop310/pci_auto.h
+ * 
+ * PCI autoconfiguration library definitions
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef _ARM_MACH_XSCALE_PCI_AUTO_H
+#define _ARM_MACH_XSCALE_PCI_AUTO_H
+
+#include "pci-bridge.h"
+
+extern int pciauto_bus_scan(struct pci_controller *, int);
+
+#define	PCIAUTO_IDE_MODE_MASK		0x05
+
+#endif /* _ARM_MACH_XSCALE_PCI_AUTO_H */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/pci-bridge.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/pci-bridge.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/pci-bridge.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/pci-bridge.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,65 @@
+/*
+ * include/asm-arm/arch-iop310/pci-bridge.h
+ * 
+ * Generic PCI hose support for Xscale/ARM.  To eventually be
+ * moved to a more generic location.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifdef __KERNEL__
+#ifndef _ASM_PCI_BRIDGE_H
+#define _ASM_PCI_BRIDGE_H
+
+struct device_node;
+struct pci_controller;
+
+/* Get the PCI host controller for a bus */
+extern struct pci_controller* pci_bus_to_hose(int bus);
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct pci_controller {
+	int index;
+	struct pci_controller *next;
+        struct pci_bus *bus;
+	void *arch_data;
+
+	int first_busno;
+	int last_busno;
+        
+	struct pci_ops *ops;
+	volatile unsigned int *cfg_addr;
+	volatile unsigned char *cfg_data;
+
+	/* Currently, we limit ourselves to 1 IO range and 3 mem
+	 * ranges since the common pci_bus structure can't handle more
+	 */
+	struct resource	io_resource;
+	struct resource mem_resources[3];
+	int mem_resource_count;
+
+	/* Host bridge I/O and Memory space
+	 * Used for BAR placement algorithms
+	 */
+	struct resource io_space;
+	struct resource mem_space;
+};
+
+/* These are used for config access before all the PCI probing
+   has been done. */
+int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn, int where, u8 *val);
+int early_read_config_word(struct pci_controller *hose, int bus, int dev_fn, int where, u16 *val);
+int early_read_config_dword(struct pci_controller *hose, int bus, int dev_fn, int where, u32 *val);
+int early_write_config_byte(struct pci_controller *hose, int bus, int dev_fn, int where, u8 val);
+int early_write_config_word(struct pci_controller *hose, int bus, int dev_fn, int where, u16 val);
+int early_write_config_dword(struct pci_controller *hose, int bus, int dev_fn, int where, u32 val);
+#endif
+#endif /* __KERNEL__ */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/pci.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/pci.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/pci.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,36 @@
+/*
+ * include/asm-arm/arch-xscale/pci.h
+ * 
+ * Generic PCI support for Xscale/ARM.  To eventually be moved to a
+ * more generic location.
+ *
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef _ASM_ARCH_PCI_H
+#define _ASM_ARCH_PCI_H
+
+extern struct pci_controller* pcibios_alloc_controller(void);
+extern void pcibios_allocate_resources(void);
+extern void pci_exclude_device(unsigned char, unsigned char);
+extern struct pci_dev * fake_pci_dev(struct pci_controller *, int, int);
+extern u8 common_swizzle(struct pci_dev *, u8 *);
+
+/*
+ * The following macro is used to lookup irqs in a standard table
+ * format for those systems that do not already have PCI
+ * interrupts properly routed.
+ */
+#define PCI_IRQ_TABLE_LOOKUP                                            \
+({ long _ctl_ = -1;                                                     \
+   if (idsel >= min_idsel && idsel <= max_idsel && pin <= irqs_per_slot) \
+	 _ctl_ = pci_irq_table[idsel - min_idsel][pin-1]; \
+   _ctl_; })
+
+#endif /* _ASM_ARCH_PCI_H */
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/serial.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/serial.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/serial.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,55 @@
+/*
+ * include/asm-arm/arch-ixp425/serial.h
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ * Modified for ixp425 offsets pbarry-intel
+ *
+ * Copyright (c) 2001 MontaVista Software, Inc.
+ * 
+ * 2002: Modified for IXP425 by Intel Corporation.
+ *
+ */
+
+#ifndef _ARCH_SERIAL_H_
+#define _ARCH_SERIAL_H_
+
+
+/* Standard COM flags */
+#define STD_COM_FLAGS ( ASYNC_SKIP_TEST)
+
+#undef BASE_BAUD
+
+/*
+ * IXP425 uses 15.6MHz clock for uart
+ */
+#define BASE_BAUD ( IXP425_UART_XTAL / 16 )
+
+#define	RS_TABLE_SIZE	2
+
+#define STD_SERIAL_PORT_DEFNS				\
+	{						\
+	  port: 0,					\
+	  type: PORT_XSCALE,				\
+	  xmit_fifo_size: 32,				\
+	  baud_base: BASE_BAUD,				\
+	  irq: IRQ_IXP425_UART1,	       		\
+	  flags: STD_COM_FLAGS,				\
+	  iomem_base: (IXP425_UART1_BASE_VIRT+3),	\
+	  io_type: SERIAL_IO_MEM,			\
+	  iomem_reg_shift: 2				\
+	}, /* ttyS0 */					\
+	{						\
+	  port: 1,					\
+	  type: PORT_XSCALE,				\
+	  xmit_fifo_size: 32,				\
+	  baud_base: BASE_BAUD,				\
+	  irq: IRQ_IXP425_UART2,		       	\
+	  flags: STD_COM_FLAGS,				\
+	  iomem_base: (IXP425_UART2_BASE_VIRT+3),    	\
+	  io_type: SERIAL_IO_MEM,			\
+	  iomem_reg_shift: 2				\
+	} /* ttyS1 */
+
+#define EXTRA_SERIAL_PORT_DEFNS
+
+#endif // _ARCH_SERIAL_H_
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/system.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/system.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/system.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,43 @@
+/*
+ *  system.h 
+ *
+ *  Copyright (C) 2002 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <asm/hardware.h>
+
+static inline void arch_idle(void)
+{
+#if 0
+	if (!hlt_counter)
+		cpu_do_idle(0);
+#endif
+}
+
+
+static inline void arch_reset(char mode)
+{
+	if ( 1 && mode == 's') {
+		/* Jump into ROM at address 0 */
+		cpu_reset(0);
+	} else {
+		/* Use on-chip reset capability */
+
+		/* set the "key" register to enable access to
+		 * "timer" and "enable" registers
+		 */
+		*IXP425_OSWK = 0x482e; 	    
+
+		/* write 0 to the timer register for an immidiate reset */
+		*IXP425_OSWT = 0;
+
+		/* disable watchdog interrupt, enable reset, enable count */
+		*IXP425_OSWE = 0x3;
+	}
+}
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/time.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/time.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/time.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-ixp425/time.h
+ *
+ */
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/timex.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/timex.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/timex.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,18 @@
+/*
+ * linux/include/asm-arm/arch-ixp425/timex.h
+ *
+ * XScale architecture timex specifications
+ */
+
+/*
+ * We use IXP425 General purpose timer for our timer needs, it runs at 66,666,666 Hz.
+ * The CyberGuard/iVPN hardware has either a 20MHz or 30MHz base clock, to reduce power consumption.
+ */
+#if defined(CONFIG_IVPN_20MHZ)
+#define CLOCK_TICK_RATE (40000000)
+#elif defined(CONFIG_MACH_IVPN)
+#define CLOCK_TICK_RATE (60000000)
+#else
+#define CLOCK_TICK_RATE (66666666)
+#endif
+
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/uncompress.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/uncompress.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/uncompress.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,74 @@
+/*
+ * uncompress.h 
+ *
+ *  Copyright (C) 2002 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _ARCH_UNCOMPRESS_H_
+#define _ARCH_UNCOMPRESS_H_
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <linux/serial_reg.h>
+
+static int console_output;
+static	volatile u32* UART_BASE;
+#define TX_DONE (UART_LSR_TEMT|UART_LSR_THRE)
+
+static __inline__ void putc(char c)
+{
+	/* Check THRE and TEMT bits before we transmit the character.
+	 */
+	if (console_output) {
+		while ((UART_BASE[UART_LSR] & TX_DONE) != TX_DONE); 
+		*UART_BASE = c;
+	}
+#if defined(CONFIG_MACH_SG560) || defined(CONFIG_MACH_SG580) || \
+    defined(CONFIG_MACH_ESS710) || defined(CONFIG_MACH_IVPN)
+	/* Tickle watchdog, we need to keep it happy while decompressing */
+	*((volatile u32 *)(IXP425_GPIO_BASE_PHYS+IXP425_GPIO_GPOUTR_OFFSET)) ^=
+		0x00004000;
+#endif
+#if defined(CONFIG_MACH_SG565) || defined(CONFIG_MACH_SHIVA1100)
+	*((volatile unsigned char *) IXP425_EXP_BUS_CS7_BASE_PHYS) = 0;
+#endif
+}
+
+/*
+ * This does not append a newline
+ */
+static void puts(const char *s)
+{
+	while (*s)
+	{
+		putc(*s);
+		if (*s == '\n')
+			putc('\r');
+		s++;
+	}
+}
+
+static __inline__ void arch_decomp_setup(void)
+{
+        unsigned long mach_type;
+
+        asm("mov %0, r7" : "=r" (mach_type) ); 
+	if(mach_type == MACH_TYPE_ADI_COYOTE)
+		UART_BASE = IXP425_UART2_BASE_PHYS;
+	else
+		UART_BASE = IXP425_UART1_BASE_PHYS;
+	if ((mach_type != MACH_TYPE_ESS710) && (mach_type != MACH_TYPE_IVPN) &&
+	    (mach_type != MACH_TYPE_SG560) && (mach_type != MACH_TYPE_SG565) &&
+	    (mach_type != MACH_TYPE_SG580) && (mach_type != MACH_TYPE_SHIVA1100))
+		console_output++;
+
+}
+
+#define arch_decomp_wdog()
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ixp425/vmalloc.h linux-2.4.29-uc1/include/asm-arm/arch-ixp425/vmalloc.h
--- linux-2.4.29/include/asm-arm/arch-ixp425/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ixp425/vmalloc.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,16 @@
+/*
+ * linux/include/asm-arm/arch-ixp425/vmalloc.h
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (0xFF000000)
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/bits.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/bits.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/bits.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/bits.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,61 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+/* DO NOT EDIT!! - this file automatically generated
+ *                 from .s file by awk -f s2h.awk
+ */
+/*  Bit field defintions
+ *  Copyright (C) ARM Limited 1998. All rights reserved.
+ */
+
+#ifndef __bits_h
+#define __bits_h                        1
+
+#define BIT0                            0x00000001
+#define BIT1                            0x00000002
+#define BIT2                            0x00000004
+#define BIT3                            0x00000008
+#define BIT4                            0x00000010
+#define BIT5                            0x00000020
+#define BIT6                            0x00000040
+#define BIT7                            0x00000080
+#define BIT8                            0x00000100
+#define BIT9                            0x00000200
+#define BIT10                           0x00000400
+#define BIT11                           0x00000800
+#define BIT12                           0x00001000
+#define BIT13                           0x00002000
+#define BIT14                           0x00004000
+#define BIT15                           0x00008000
+#define BIT16                           0x00010000
+#define BIT17                           0x00020000
+#define BIT18                           0x00040000
+#define BIT19                           0x00080000
+#define BIT20                           0x00100000
+#define BIT21                           0x00200000
+#define BIT22                           0x00400000
+#define BIT23                           0x00800000
+#define BIT24                           0x01000000
+#define BIT25                           0x02000000
+#define BIT26                           0x04000000
+#define BIT27                           0x08000000
+#define BIT28                           0x10000000
+#define BIT29                           0x20000000
+#define BIT30                           0x40000000
+#define BIT31                           0x80000000
+
+#endif
+
+/*         END */
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/dma.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/dma.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/dma.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ *  linux/include/asm-arm/arch-integrator/dma.h
+ *
+ *  Copyright (C) 1997,1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_ADDRESS		0xffffffff
+
+#define MAX_DMA_CHANNELS	0
+
+#endif /* _ASM_ARCH_DMA_H */
+
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/fast_timer.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/fast_timer.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/fast_timer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/fast_timer.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,57 @@
+#ifndef __ASM_ARM_MACH_FAST_TIMER_H
+#define __ASM_ARM_MACH_FAST_TIMER_H
+
+#include <linux/sched.h>
+#include <linux/timex.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#define TIMER_VA_BASE  (IO_ADDRESS(KS8695_IO_BASE))
+
+static void fast_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+        __raw_writel(KS8695_INTMASK_TIMERINT0, TIMER_VA_BASE + KS8695_INT_STATUS);
+
+	do_fast_timer();
+}
+
+static void fast_timer_set(void)
+{
+	unsigned long interval, data, pulse, ctrl;
+
+	/* Setup TIMER0 as fast clock */
+	interval = TICKS_PER_uSEC * fast_timer_rate;
+	data = interval >> 1;
+	pulse = interval - data;
+        __raw_writel(data, TIMER_VA_BASE + KS8695_TIMER0);
+        __raw_writel(pulse, TIMER_VA_BASE + KS8695_TIMER0_PCOUNT);
+	ctrl = __raw_readl(TIMER_VA_BASE + KS8695_TIMER_CTRL) | 0x01;
+        __raw_writel(ctrl, TIMER_VA_BASE + KS8695_TIMER_CTRL);
+}
+
+static int __init fast_timer_setup(void)
+{
+	/* Connect the interrupt handler and enable the interrupt */
+	if (request_irq(KS8695_INT_TIMERINT0, fast_timer_interrupt,
+				SA_INTERRUPT, "fast timer", NULL))
+		return -EBUSY;
+
+	fast_timer_rate = 2000;
+	fast_timer_set();
+
+	printk("fast timer: %d Hz, IRQ %d\n", fast_timer_rate,
+			KS8695_INT_TIMERINT0);
+	return 0;
+}
+
+static void __exit fast_timer_cleanup(void)
+{
+	unsigned long ctrl;
+
+	ctrl = __raw_readl(TIMER_VA_BASE + KS8695_TIMER_CTRL) & 0x02;
+        __raw_writel(ctrl, TIMER_VA_BASE + KS8695_TIMER_CTRL);
+	free_irq(KS8695_INT_TIMERINT0, NULL);
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/hardware.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/hardware.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/hardware.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,51 @@
+/*
+ *  linux/include/asm-arm/arch-ks8695/hardware.h
+ *
+ *  This file contains the hardware definitions of the KS8695.
+ *
+ *  Copyright (C) 2002 Micrel Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+#include <asm/arch/platform.h>
+
+/*
+ * Where in virtual memory the IO devices (timers, system controllers
+ * and so on)
+ */
+#define IO_BASE			0xF0000000                 // VA of IO 
+#define IO_SIZE			KS8695_IO_SIZE             // 0x0000 - 0xFFFF
+#define IO_START		KS8695_IO_BASE            // PA of IO
+
+#define  pcibios_assign_all_busses()     1
+#define  PCIBIOS_MIN_IO         0x00000100      /* 256 Bytes bytes */
+#define  PCIBIOS_MIN_MEM        0x00010000      /* 64K */
+#define  PCI_MEMORY_VADDR       KS8695P_PCIBG_MEM_BASE
+#define  PCI_IO_VADDR           KS8695P_PCIBG_IO_BASE
+
+/* macro to get at IO space when running virtually */
+#define IO_ADDRESS(x) (((x) >> 4) + IO_BASE) 
+
+/*
+ * Use SDRAM for memory
+ */
+#define MEM_SIZE		KS8695_MEM_SIZE
+
+#endif
+
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/io.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/io.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/io.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,45 @@
+/*
+ *  linux/include/asm-arm/arch-integrator/io.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a)                 (a)
+#define __mem_pci(a)		((unsigned long)(a))
+#define __mem_isa(a)		((unsigned long)(a))
+
+/*
+ * Generic virtual read/write
+ */
+#define __arch_getw(a)		(*(volatile unsigned short *)(a))
+#define __arch_putw(v,a)	(*(volatile unsigned short *)(a) = (v))
+
+/*
+ * Validate the pci memory address for ioremap.
+ */
+#define iomem_valid_addr(iomem,size)	(1)
+
+/*
+ * Convert PCI memory space to a CPU physical address
+ */
+#define iomem_to_phys(iomem)	(iomem)
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/irq.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/irq.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/irq.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,21 @@
+/*
+ *  linux/include/asm-arm/arch-integrator/irq.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#define fixup_irq(i)	(i)
+
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/irqs.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/irqs.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/irqs.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,26 @@
+/*
+ *  linux/include/asm-arm/arch-integrator/irqs.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/* Use the integrator definitions */
+#include <asm/arch/platform.h>
+
+#define NR_IRQS                         (MAXIRQNUM + 1)
+
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/keyboard.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/keyboard.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/keyboard.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,29 @@
+/*
+ *  linux/include/asm-arm/arch-integrator/keyboard.h
+ *
+ *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it 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
+ *
+ *  Keyboard driver definitions for the Integrator architecture
+ */
+#include <asm/irq.h>
+
+#define NR_SCANCODES 128
+
+extern int kmi_kbd_init(void);
+
+#define kbd_disable_irq()	disable_irq(IRQ_KMIINT0)
+#define kbd_enable_irq()	enable_irq(IRQ_KMIINT0)
+#define kbd_init_hw()		kmi_kbd_init()
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/memory.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/memory.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/memory.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,64 @@
+/*
+ *  linux/include/asm-arm/arch-ks8695/memory.h
+ *
+ *  Copyright (C) 2002 Micrel Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+#include <asm/arch/platform.h>
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE	(0xc0000000UL)
+#define TASK_SIZE_26	(0x04000000UL)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+/*
+ * Page offset: 3GB
+ */
+#define PAGE_OFFSET	(0xc0000000UL)
+#define PHYS_OFFSET	KS8695_MEM_START              
+
+/*
+ * On KS8695, the dram is contiguous
+ */
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET)
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET)
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *              address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *              to an address that the kernel can use.
+ * On KS8695, physical and bus address are same for dram
+ */
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x)   ((x) - PAGE_OFFSET  + KS8695P_PCI_MEM_BASE)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x)   ((x) - KS8695P_PCI_MEM_BASE + PAGE_OFFSET)
+#define PHYS_TO_NID(addr)     (0)
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/param.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/param.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/param.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,21 @@
+/*
+ *  linux/include/asm-arm/arch-integrator/param.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+#define HZ 100
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/platform.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/platform.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/platform.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/platform.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,553 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef __address_h
+#define __address_h                     1
+
+#define KS8695_SDRAM_START	    0x00000000
+#define KS8695_SDRAM_SIZE           0x02000000  /* 32M on board SDRAM the acutal size is passed to kernel by loader */
+#define KS8695_MEM_SIZE             KS8695_SDRAM_SIZE
+#define KS8695_MEM_START            KS8695_SDRAM_START
+
+#define KS8695_IO_BASE              0x03FF0000
+#define KS8695_IO_SIZE              0x00010000
+
+#define KS8695_SYSTEN_CONFIG  	    0x00
+#define KS8695_SYSTEN_BUS_CLOCK     0x04
+
+#define KS8695_FLASH_START          0x02800000
+#define KS8695_FLASH_SIZE           0x00400000
+
+#define KS8695_PCMCIA_IO_BASE       0x03800000  /* for PCMCIA (KS8695 only) */
+#define KS8695_PCMCIA_IO_SIZE       0x00040000
+
+/* PCI memory related defines */
+#define KS8695P_PCIBG_MEM_BASE      0x60000000  /* memory base for bridge*/  
+#define KS8695P_PCI_MEM_BASE	    0x60000000	/* memory base in PCI space */
+#define KS8695P_PCI_MEM_SIZE	    0x20000000	/* 512M, can be extended to 512M */
+#define KS8695P_PCI_MEM_MASK	    0xE0000000  /*512M*/
+
+/* PCI IO related defines */
+#define KS8695P_PCIBG_IO_BASE       0x10000000  /* io base for bridge */
+#define KS8695P_PCI_IO_BASE         0x10000000
+#define KS8695P_PCI_IO_SIZE         0x00010000      /* 64K */
+#define KS8695P_PCI_IO_MASK         0xFF800000      /* 64K range */
+
+/* new registers specific to KS8695P */
+/* PCI related */
+#define	KS8695_CRCFID		0x2000
+#define	KS8695_2000		0x2000
+#define	KS8695_CRCFCS		0x2004
+#define	KS8695_2004		0x2004
+#define	KS8695_CRCFRV		0x2008
+#define	KS8695_2008		0x2008
+#define	KS8695_CRCFLT		0x200c
+#define	KS8695_200C		0x200c
+#define	KS8695_CRCBMA		0x2010
+#define	KS8695_2010		0x2010
+#define	KS8695_CRCBA0		0x2014
+#define	KS8695_2014		0x2014
+
+#define	KS8695_CRCSID		0x202c
+#define	KS8695_202C		0x202c
+
+#define	KS8695_CRCFIT		0x203c
+#define	KS8695_203C		0x203c
+
+/* note that PCI configuration bits are defined in pci.h already */
+
+/* bridge configuration related registers */
+#define	KS8695_PBCA		0x2100
+#define	KS8695_2100		0x2100
+#define	KS8695_PBCD		0x2104
+#define	KS8695_2104		0x2104
+
+/* bridge mode related registers */
+#define	KS8695_PBM		0x2200
+#define	KS8695_2200		0x2200
+#define	KS8695_PBCS		0x2204
+#define	KS8695_2204		0x2204
+#define	KS8695_PMBA		0x2208
+#define	KS8695_2208		0x2208
+#define	KS8695_PMBAC		0x220c
+#define	KS8695_220C		0x220c
+#define	KS8695_PMBAM		0x2210
+#define	KS8695_2210		0x2210
+#define	KS8695_PMBAT		0x2214
+#define	KS8695_2214		0x2214
+#define	KS8695_PIOBA		0x2218
+#define	KS8695_2218		0x2218
+#define	KS8695_PIOBAC		0x221c
+#define	KS8695_221C		0x221c
+#define	KS8695_PIOBAM		0x2220
+#define	KS8695_2220		0x2220
+#define	KS8695_PIOBAT		0x2224
+#define	KS8695_2224		0x2224
+
+/* bits for registers */
+/* 0x2200 */
+#define	PBM_BRIDGE_MODE		0x80000000
+
+/* 0x2204 */
+#define	PBCS_SW_RESET		0x80000000
+
+/* 0x220c */
+#define	PMBAC_TRANS_ENABLE	0x80000000
+
+/*i/o control registers offset difinitions*/
+#define KS8695_IO_CTRL0             0x4000
+#define KS8695_IO_CTRL1             0x4004
+#define KS8695_IO_CTRL2             0x4008
+#define KS8695_IO_CTRL3             0x400C
+
+/*memory control registers offset difinitions*/
+#define KS8695_MEM_CTRL0            0x4010
+#define KS8695_MEM_CTRL1            0x4014
+#define KS8695_MEM_CTRL2            0x4018
+#define KS8695_MEM_CTRL3            0x401C
+#define KS8695_MEM_GENERAL          0x4020
+#define KS8695_SDRAM_CTRL0          0x4030 
+#define KS8695_SDRAM_CTRL1          0x4034
+#define KS8695_SDRAM_GENERAL        0x4038
+#define KS8695_SDRAM_BUFFER         0x403C
+#define KS8695_SDRAM_REFRESH        0x4040    
+
+/*WAN control registers offset difinitions*/
+#define KS8695_WAN_DMA_TX           0x6000
+#define KS8695_WAN_DMA_RX           0x6004
+#define KS8695_WAN_DMA_TX_START     0x6008    
+#define KS8695_WAN_DMA_RX_START     0x600C    
+#define KS8695_WAN_TX_LIST          0x6010
+#define KS8695_WAN_RX_LIST          0x6014
+#define KS8695_WAN_MAC_LOW          0x6018
+#define KS8695_WAN_MAC_HIGH         0x601C
+#define KS8695_WAN_MAC_ELOW         0x6080
+#define KS8695_WAN_MAC_EHIGH        0x6084
+
+/*LAN control registers offset difinitions*/
+#define KS8695_LAN_DMA_TX           0x8000
+#define KS8695_LAN_DMA_RX           0x8004
+#define KS8695_LAN_DMA_TX_START     0x8008    
+#define KS8695_LAN_DMA_RX_START     0x800C    
+#define KS8695_LAN_TX_LIST          0x8010
+#define KS8695_LAN_RX_LIST          0x8014
+#define KS8695_LAN_MAC_LOW          0x8018
+#define KS8695_LAN_MAC_HIGH         0x801C
+#define KS8695_LAN_MAC_ELOW         0X8080
+#define KS8695_LAN_MAC_EHIGH        0X8084
+
+/*HPNA control registers offset difinitions*/
+#define KS8695_HPNA_DMA_TX          0xA000
+#define KS8695_HPNA_DMA_RX          0xA004
+#define KS8695_HPNA_DMA_TX_START    0xA008    
+#define KS8695_HPNA_DMA_RX_START    0xA00C    
+#define KS8695_HPNA_TX_LIST         0xA010
+#define KS8695_HPNA_RX_LIST         0xA014
+#define KS8695_HPNA_MAC_LOW         0xA018
+#define KS8695_HPNA_MAC_HIGH        0xA01C
+#define KS8695_HPNA_MAC_ELOW        0xA080
+#define KS8695_HPNA_MAC_EHIGH       0xA084
+
+/*UART control registers offset difinitions*/
+#define KS8695_UART_RX_BUFFER       0xE000
+#define KS8695_UART_TX_HOLDING      0xE004
+
+#define KS8695_UART_FIFO_CTRL       0xE008
+#define KS8695_UART_FIFO_TRIG01     0x00
+#define KS8695_UART_FIFO_TRIG04     0x80
+#define KS8695_UART_FIFO_TXRST      0x03
+#define KS8695_UART_FIFO_RXRST      0x02
+#define KS8695_UART_FIFO_FEN        0x01
+
+#define KS8695_UART_LINE_CTRL       0xE00C
+#define KS8695_UART_LINEC_BRK       0x40
+#define KS8695_UART_LINEC_EPS       0x10
+#define KS8695_UART_LINEC_PEN       0x08
+#define KS8695_UART_LINEC_STP2      0x04
+#define KS8695_UART_LINEC_WLEN8     0x03
+#define KS8695_UART_LINEC_WLEN7     0x02
+#define KS8695_UART_LINEC_WLEN6     0x01
+#define KS8695_UART_LINEC_WLEN5     0x00
+
+#define KS8695_UART_MODEM_CTRL      0xE010
+#define KS8695_UART_MODEMC_RTS      0x02
+#define KS8695_UART_MODEMC_DTR      0x01
+
+#define KS8695_UART_LINE_STATUS     0xE014
+#define KS8695_UART_LINES_TXFE      0x20
+#define KS8695_UART_LINES_BE        0x10
+#define KS8695_UART_LINES_FE        0x08
+#define KS8695_UART_LINES_PE        0x04
+#define KS8695_UART_LINES_OE        0x02
+#define KS8695_UART_LINES_RXFE      0x01
+#define KS8695_UART_LINES_ANY	    (KS8695_UART_LINES_OE|KS8695_UART_LINES_BE|KS8695_UART_LINES_PE|KS8695_UART_LINES_FE)
+
+#define KS8695_UART_MODEM_STATUS    0xE018
+#define KS8695_UART_MODEM_DCD       0x80
+#define KS8695_UART_MODEM_DSR       0x20
+#define KS8695_UART_MODEM_CTS       0x10
+#define KS8695_UART_MODEM_DDCD      0x08
+#define KS8695_UART_MODEM_DDSR      0x02
+#define KS8695_UART_MODEM_DCTS      0x01
+#define UART8695_MODEM_ANY	    0xFF
+
+#define KS8695_UART_DIVISOR         0xE01C
+#define KS8695_UART_STATUS          0xE020
+
+/*Interrupt controlller registers offset difinitions*/
+#define KS8695_INT_CONTL            0xE200
+#define KS8695_INT_ENABLE           0xE204
+#define KS8695_INT_ENABLE_MODEM     0x0800
+#define KS8695_INT_ENABLE_ERR       0x0400
+#define KS8695_INT_ENABLE_RX        0x0200
+#define KS8695_INT_ENABLE_TX        0x0100
+
+#define KS8695_INT_STATUS           0xE208
+#define KS8695_INT_WAN_PRIORITY     0xE20C
+#define KS8695_INT_HPNA_PRIORITY    0xE210
+#define KS8695_INT_LAN_PRIORITY     0xE214
+#define KS8695_INT_TIMER_PRIORITY   0xE218
+#define KS8695_INT_UART_PRIORITY    0xE21C
+#define KS8695_INT_EXT_PRIORITY     0xE220
+#define KS8695_INT_CHAN_PRIORITY    0xE224
+#define KS8695_INT_BUSERROR_PRO     0xE228
+#define KS8695_INT_MASK_STATUS      0xE22C
+#define KS8695_FIQ_PEND_PRIORITY    0xE230
+#define KS8695_IRQ_PEND_PRIORITY    0xE234
+
+/*timer registers offset difinitions*/
+#define KS8695_TIMER_CTRL           0xE400
+#define KS8695_TIMER1               0xE404
+#define KS8695_TIMER0               0xE408
+#define KS8695_TIMER1_PCOUNT        0xE40C
+#define KS8695_TIMER0_PCOUNT        0xE410
+
+/*GPIO registers offset difinitions*/
+#define KS8695_GPIO_MODE            0xE600
+#define KS8695_GPIO_CTRL            0xE604
+#define KS8695_GPIO_DATA            0xE608
+
+/*SWITCH registers offset difinitions*/
+#define KS8695_SWITCH_CTRL0         0xE800
+#define KS8695_SWITCH_CTRL1         0xE804
+#define KS8695_SWITCH_PORT1         0xE808
+#define KS8695_SWITCH_PORT2         0xE80C
+#define KS8695_SWITCH_PORT3         0xE810
+#define KS8695_SWITCH_PORT4         0xE814
+#define KS8695_SWITCH_PORT5         0xE818
+#define KS8695_SWITCH_AUTO0         0xE81C
+#define KS8695_SWITCH_AUTO1         0xE820
+#define KS8695_SWITCH_LUE_CTRL      0xE824
+#define KS8695_SWITCH_LUE_HIGH      0xE828
+#define KS8695_SWITCH_LUE_LOW       0xE82C
+#define KS8695_SWITCH_ADVANCED      0xE830
+
+/*host communication registers difinitions*/
+#define KS8695_DSCP_HIGH            0xE834
+#define KS8695_DSCP_LOW             0xE838
+#define KS8695_SWITCH_MAC_HIGH      0xE83C
+#define KS8695_SWITCH_MAC_LOW       0xE840
+
+/*miscellaneours registers difinitions*/
+#define KS8695_MANAGE_COUNTER       0xE844
+#define KS8695_MANAGE_DATA          0xE848
+#define KS8695_LAN12_POWERMAGR      0xE84C
+#define KS8695_LAN34_POWERMAGR      0xE850
+
+#define KS8695_DEVICE_ID            0xEA00
+#define KS8695_REVISION_ID          0xEA04
+
+#define KS8695_MISC_CONTROL         0xEA08
+#define KS8695_WAN_CONTROL          0xEA0C
+#define KS8695_WAN_POWERMAGR        0xEA10
+#define KS8695_WAN_PHY_CONTROL      0xEA14
+#define KS8695_WAN_PHY_STATUS       0xEA18
+
+#ifdef	CONFIG_ARCH_KS8695P
+/* most bit definition are same as KS8695, except few new bits */
+#define KS8695_SEC0			0xE800
+#define KS8695_E800			0xE800
+
+/* new bits */
+#define	KS8695_SEC0_BACKOFF_EN		0x80000000	/* new backoff enable for UNH, bit 31 */
+#define	KS8695_SEC0_FRAME_LEN_CHECK	0x00020000	/* frame length field check, bit 17 */
+#define	KS8695_SEC0_DMA_HALF_DUPLEX	0x00000010	/* LAN DMA port 5 half duplex mode bit 4 */
+
+#define KS8695_SEC1			0xE804
+#define KS8695_E804			0xE804
+
+/* new bits */
+#define	KS8695_SEC1_NO_IEEE_AN		0x00000800	/* non IEEE specific auto-nego bit 11 */
+#define	KS8695_SEC1_TPID_MODE		0x00000400	/* Special TPID mode bit 10 */
+#define	KS8695_SEC1_NO_TX_8021X_FLOW_CTRL	0x00000080	/* IEEE 802.1x transmit flow control disable bit 7 */
+#define	KS8695_SEC1_NO_RX_8021X_FLOW_CTRL	0x00000040	/* IEEE 802.1x receive flow control disable bit 6 */
+#define	KS8695_SEC1_HUGE_PACKET		0x00000020	/* huge packet support bit 5 */
+#define	KS8695_SEC1_8021Q_VLAN_EN	0x00000010	/* IEEE 802.1q VLAN enable bit 4 */
+#define	KS8695_SEC1_MII_10BT		0x00000002	/* Switch MII 10BT bit 1 */
+#define	KS8695_SEC1_NULL_VID		0x00000001	/* null VID replacement bit 0 */
+
+/* Port 1-4 and 5 Configuration Register Set 1 */
+/* bit definition is same as KS8695 */
+#define KS8695_SEP1C1			0xE80C
+#define KS8695_E80C			0xE80C
+#define KS8695_SEP2C1			0xE818
+#define KS8695_E818			0xE818
+#define KS8695_SEP3C1			0xE824
+#define KS8695_E824			0xE824
+#define KS8695_SEP4C1			0xE830
+#define KS8695_E830			0xE830
+#define KS8695_SEP5C1			0xE83C
+#define KS8695_E83C			0xE83C
+
+/* Port 1-4 and 5 Configuration Register Set 2 */
+#define KS8695_SEP1C2			0xE810
+#define KS8695_E810			0xE810
+#define KS8695_SEP2C2			0xE81C
+#define KS8695_E81C			0xE81C
+#define KS8695_SEP3C2			0xE828
+#define KS8695_E828			0xE828
+#define KS8695_SEP4C2			0xE834
+#define KS8695_E834			0xE834
+#define KS8695_SEP5C2			0xE840
+#define KS8695_E840			0xE840
+
+#define	KS8695_SEPC2_VLAN_FILTER	0x10000000	/* Ingress VLAN filtering bit 28 */
+#define	KS8695_SEPC2_DISCARD_NON_PVID	0x08000000	/* discard non PVID packets, bit 27 */
+#define	KS8695_SEPC2_FORCE_FLOW_CTRL	0x04000000	/* force flow control, bit 26 */
+#define	KS8695_SEPC2_BACK_PRESSURE_EN	0x02000000	/* back pressure enable, bit 25 */
+
+#define	KS8695_SEPC2_TX_H_RATECTRL_MASK	0x00FFF000	/* Tx high priority rate control bit 23:12 */
+#define	KS8695_SEPC2_TX_L_RATECTRL_MASK	0x00000FFF	/* Tx low priority rate control bit 11:0 */
+
+/* Port 1-4 and 5 Configuration Register Set 3 */
+#define KS8695_SEP1C3			0xE814
+#define KS8695_E814			0xE814
+#define KS8695_SEP2C3			0xE820
+#define KS8695_E820			0xE820
+#define KS8695_SEP3C3			0xE82C
+#define KS8695_E82C			0xE82C
+#define KS8695_SEP4C3			0xE838
+#define KS8695_E838			0xE838
+#define KS8695_SEP5C3			0xE844
+#define KS8695_E844			0xE844
+
+#define	KS8695_SEPC3_RX_H_RATECTRL_MASK	0xFFF00000	/* Rx high priority rate control bit 31:20 */
+#define	KS8695_SEPC3_RX_L_RATECTRL_MASK	0x000FFF00	/* Rx low priority rate control bit 19:8 */
+#define	KS8695_SEPC3_RX_DIF_RATECTRL_EN	0x00000080	/* Rx differential priority rate control enable bit 7 */
+#define	KS8695_SEPC3_RX_L_RATECTRL_EN	0x00000040	/* Rx low priority rate control enable bit 6 */
+#define	KS8695_SEPC3_RX_H_RATECTRL_EN	0x00000020	/* Rx high priority rate control enable bit 5 */
+#define	KS8695_SEPC3_RX_L_RATEFLOW_EN	0x00000010	/* Rx low priority rate flow control enable bit 4 */
+#define	KS8695_SEPC3_RX_H_RATEFLOW_EN	0x00000008	/* Rx high priority rate flow control enable bit 3 */
+#define	KS8695_SEPC3_TX_DIF_RATECTRL_EN	0x00000004	/* Tx low priority rate control enable bit 2 */
+#define	KS8695_SEPC3_TX_L_RATECTRL_EN	0x00000002	/* Tx low priority rate control enable bit 1 */
+#define	KS8695_SEPC3_TX_H_RATECTRL_EN	0x00000001	/* Tx high priority rate control enable bit 0 */
+
+/* Port auto negotiation related registers */
+/* bit definition is same as KS8695 */
+#define KS8695_SEP12AN			0xE848
+#define KS8695_E848			0xE848
+#define KS8695_SEP34AN			0xE84C
+#define KS8695_E84C			0xE84C
+
+/* backward compatible */
+#undef KS8695_SWITCH_AUTO0
+#undef KS8695_SWITCH_AUTO1
+#define KS8695_SWITCH_AUTO0		0xE848
+#define KS8695_SWITCH_AUTO1		0xE84C
+
+/* Indirect Access Control register */
+#define KS8695_SEIAC			0xE850
+#define KS8695_E850			0xE850
+#define KS8695_SEIADH2			0xE854
+#define KS8695_E854			0xE854
+#define KS8695_SEIADH1			0xE858
+#define KS8695_E858			0xE858
+#define KS8695_SEIADL			0xE85C
+#define KS8695_E85C			0xE85C
+
+#define	KS8695_SEIAC_READ		0x00001000	/* bit 12 */
+#define	KS8695_SEIAC_WRITE		0x00000000	/* bit 12 not set*/
+/* table select bit 11:10 */
+#define	KS8695_SEIAC_TAB_STATIC		0x00000000
+#define	KS8695_SEIAC_TAB_VLAN		0x00000400
+#define	KS8695_SEIAC_TAB_DYNAMIC	0x00000800
+#define	KS8695_SEIAC_TAB_MIB		0x00000C00
+#define	KS8695_SEIAC_INDEX_MASK		0x000003FF	/* bit 9:0 */
+
+/* Advanced Feature Control register */
+/* bit definition is same as KS8695 */
+#define KS8695_SEAFC			0xE860
+#define KS8695_SEDSCPH			0xE864
+#define KS8695_SEDSCPL			0xE868
+#define KS8695_SEMAH			0xE86C
+#define KS8695_SEMAL			0xE870
+
+/* backward compatible */
+#undef	KS8695_SWITCH_ADVANCED
+#undef	KS8695_DSCP_HIGH
+#undef	KS8695_DSCP_LOW
+#undef	KS8695_SWITCH_MAC_HIGH
+#undef	KS8695_SWITCH_MAC_LOW
+
+#define KS8695_SWITCH_ADVANCED		0xE860
+#define KS8695_DSCP_HIGH		0xE864
+#define KS8695_DSCP_LOW			0xE868
+#define KS8695_SWITCH_MAC_HIGH		0xE86C
+#define KS8695_SWITCH_MAC_LOW		0xE870
+
+/* LAN PHY power management related registers */
+/* bit definition is same as KS8695, except new bits 30:26 */
+#define KS8695_LPPM12			0xE874
+#define KS8695_LPPM34			0xE878
+
+/* new bits */
+#define	KS8695_LPPM_PHY_LOOPBACK	0x4000	/* phy loopback bit 14 */
+#define	KS8695_LPPM_RMT_LOOPBACK	0x2000	/* remote loopback bit 13 */
+#define	KS8695_LPPM_PHY_ISOLATE		0x1000	/* phy isolate bit 12 */
+#define	KS8695_LPPM_SOFT_RESET		0x0800	/* phy isolate bit 11 */
+#define	KS8695_LPPM_FORCE_LINK		0x0400	/* force link isolationi bit 10 */
+/* shift bit defined already */
+
+/* backward compatible */
+#undef	KS8695_LAN12_POWERMAGR
+#undef	KS8695_LAN34_POWERMAGR
+#define KS8695_LAN12_POWERMAGR		0xE874
+#define KS8695_LAN34_POWERMAGR		0xE878
+
+/* new bits */
+#define	KS8695_LPPM_PHY_LOOPBACK	0x4000	/* phy loopback bit 14 */
+#define	KS8695_LPPM_RMT_LOOPBACK	0x2000	/* remote loopback bit 13 */
+#define	KS8695_LPPM_PHY_ISOLATE		0x1000	/* phy isolate bit 12 */
+#define	KS8695_LPPM_SOFT_RESET		0x0800	/* phy isolate bit 11 */
+#define	KS8695_LPPM_FORCE_LINK		0x0400	/* force link isolationi bit 10 */
+/* shift bit defined already */
+
+/* backward compatible */
+#undef	KS8695_LAN12_POWERMAGR
+#undef	KS8695_LAN34_POWERMAGR
+#define KS8695_LAN12_POWERMAGR		0xE874
+#define KS8695_LAN34_POWERMAGR		0xE878
+
+/* Digital Testing Status and Control Registers */
+#define KS8695_SEDTS			0xE87C		/* Digital Testing status & control register */
+#define KS8695_SEATCS			0xE880		/* Analog Testing status and control register */
+
+/* new bits for WAN PHY Power mangement register */
+#define	KS8695_WPPM_PHY_LOOPBACK	0x00004000	/* phy loopback bit 14 */
+#define	KS8695_WPPM_RMT_LOOPBACK	0x00002000	/* remote loopback bit 13 */
+#define	KS8695_WPPM_PHY_ISOLATION	0x00001000	/* phy isolationi bit 12 */
+#define	KS8695_WPPM_FORCE_LINK		0x00000400	/* force link isolationi bit 10 */
+
+#endif	/*CONFIG_ARCH_KS8695P */
+
+/* bus clock definitions*/
+#define KS8695_BUS_CLOCK_125MHZ     0x0
+#define KS8695_BUS_CLOCK_100MHZ     0x1
+#define KS8695_BUS_CLOCK_62MHZ      0x2
+#define KS8695_BUS_CLOCK_50MHZ      0x3
+#define KS8695_BUS_CLOCK_41MHZ      0x4
+#define KS8695_BUS_CLOCK_33MHZ      0x5
+#define KS8695_BUS_CLOCK_31MHZ      0x6
+#define KS8695_BUS_CLOCK_25MHZ      0x7
+
+/* -------------------------------------------------------------------------------
+ *  definations for IRQ
+ * -------------------------------------------------------------------------------*/
+
+#define KS8695_INT_EXT_INT0                    2
+#define KS8695_INT_EXT_INT1                    3
+#define KS8695_INT_EXT_INT2                    4
+#define KS8695_INT_EXT_INT3                    5
+#define KS8695_INT_TIMERINT0                   6
+#define KS8695_INT_TIMERINT1                   7 
+#define KS8695_INT_UART_TX                     8
+#define KS8695_INT_UART_RX                     9
+#define KS8695_INT_UART_LINE_ERR               10
+#define KS8695_INT_UART_MODEMS                 11
+#define KS8695_INT_LAN_STOP_RX                 12
+#define KS8695_INT_LAN_STOP_TX                 13
+#define KS8695_INT_LAN_BUF_RX_STATUS           14
+#define KS8695_INT_LAN_BUF_TX_STATUS           15
+#define KS8695_INT_LAN_RX_STATUS               16
+#define KS8695_INT_LAN_TX_STATUS               17
+#define KS8695_INT_HPAN_STOP_RX                18
+#define KS8695_INT_HPNA_STOP_TX                19
+#define KS8695_INT_HPNA_BUF_RX_STATUS          20
+#define KS8695_INT_HPNA_BUF_TX_STATUS          21
+#define KS8695_INT_HPNA_RX_STATUS              22
+#define KS8695_INT_HPNA_TX_STATUS              23
+#define KS8695_INT_BUS_ERROR                   24
+#define KS8695_INT_WAN_STOP_RX                 25
+#define KS8695_INT_WAN_STOP_TX                 26
+#define KS8695_INT_WAN_BUF_RX_STATUS           27
+#define KS8695_INT_WAN_BUF_TX_STATUS           28
+#define KS8695_INT_WAN_RX_STATUS               29
+#define KS8695_INT_WAN_TX_STATUS               30
+
+#define KS8695_INT_UART                        KS8695_INT_UART_TX
+
+/* -------------------------------------------------------------------------------
+ *  Interrupt bit positions
+ * 
+ * -------------------------------------------------------------------------------
+ */
+
+#define KS8695_INTMASK_EXT_INT0                ( 1 << KS8695_INT_EXT_INT0 )
+#define KS8695_INTMASK_EXT_INT1                ( 1 << KS8695_INT_EXT_INT1 )
+#define KS8695_INTMASK_EXT_INT2                ( 1 << KS8695_INT_EXT_INT2 )
+#define KS8695_INTMASK_EXT_INT3                ( 1 << KS8695_INT_EXT_INT3 )
+#define KS8695_INTMASK_TIMERINT0               ( 1 << KS8695_INT_TIMERINT0 )
+#define KS8695_INTMASK_TIMERINT1               ( 1 << KS8695_INT_TIMERINT1 )
+#define KS8695_INTMASK_UART_TX                 ( 1 << KS8695_INT_UART_TX  )
+#define KS8695_INTMASK_UART_RX                 ( 1 << KS8695_INT_UART_RX  )
+#define KS8695_INTMASK_UART_LINE_ERR           ( 1 << KS8695_INT_UART_LINE_ERR )
+#define KS8695_INTMASK_UART_MODEMS             ( 1 << KS8695_INT_UART_MODEMS )
+#define KS8695_INTMASK_LAN_STOP_RX             ( 1 << KS8695_INT_LAN_STOP_RX )
+#define KS8695_INTMASK_LAN_STOP_TX             ( 1 << KS8695_INT_LAN_STOP_TX )
+#define KS8695_INTMASK_LAN_BUF_RX_STATUS       ( 1 << KS8695_INT_LAN_BUF_RX_STATUS )
+#define KS8695_INTMASK_LAN_BUF_TX_STATUS       ( 1 << KS8695_INT_LAN_BUF_TX_STATUS )
+#define KS8695_INTMASK_LAN_RX_STATUS           ( 1 << KS8695_INT_LAN_RX_STATUS )
+#define KS8695_INTMASK_LAN_TX_STATUS           ( 1 << KS8695_INT_LAN_RX_STATUS )
+#define KS8695_INTMASK_HPAN_STOP_RX            ( 1 << KS8695_INT_HPAN_STOP_RX )
+#define KS8695_INTMASK_HPNA_STOP_TX            ( 1 << KS8695_INT_HPNA_STOP_TX )
+#define KS8695_INTMASK_HPNA_BUF_RX_STATUS      ( 1 << KS8695_INT_HPNA_BUF_RX_STATUS )
+#define KS8695_INTMAKS_HPNA_BUF_TX_STATUS      ( 1 << KS8695_INT_HPNA_BUF_TX_STATUS
+#define KS8695_INTMASK_HPNA_RX_STATUS          ( 1 << KS8695_INT_HPNA_RX_STATUS )
+#define KS8695_INTMASK_HPNA_TX_STATUS          ( 1 << KS8695_INT_HPNA_TX_STATUS )
+#define KS8695_INTMASK_BUS_ERROR               ( 1 << KS8695_INT_BUS_ERROR )
+#define KS8695_INTMASK_WAN_STOP_RX             ( 1 << KS8695_INT_WAN_STOP_RX )
+#define KS8695_INTMASK_WAN_STOP_TX             ( 1 << KS8695_INT_WAN_STOP_TX )
+#define KS8695_INTMASK_WAN_BUF_RX_STATUS       ( 1 << KS8695_INT_WAN_BUF_RX_STATUS )
+#define KS8695_INTMASK_WAN_BUF_TX_STATUS       ( 1 << KS8695_INT_WAN_BUF_TX_STATUS )
+#define KS8695_INTMASK_WAN_RX_STATUS           ( 1 << KS8695_INT_WAN_RX_STATUS )
+#define KS8695_INTMASK_WAN_TX_STATUS           ( 1 << KS8695_INT_WAN_TX_STATUS )
+
+#define KS8695_SC_VALID_INT                    0xFFFFFFFF
+#define MAXIRQNUM                              31
+
+/* 
+ *  Timer definitions
+ * 
+ *  Use timer 1 & 2
+ *  (both run at 25MHz).
+ *
+ */
+#define TICKS_PER_uSEC                  25
+#define mSEC_1                          1000
+#define mSEC_10                         (mSEC_1 * 10)
+
+#endif
+
+/* 	END */
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/serial.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/serial.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/serial.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,20 @@
+/*
+ * linux/include/asm-arm/arch-ks8695/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+/*
+ *	This setup is used on the OpenGear CM4xxx hardware.
+ */
+#define BASE_BAUD	(1843200 / 16)
+#define RS_TABLE_SIZE	48
+
+#define STD_SERIAL_PORT_DEFNS
+#define EXTRA_SERIAL_PORT_DEFNS
+
+#endif /* __ASM_ARCH_SERIAL_H */
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/system.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/system.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/system.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,52 @@
+/*
+ *  linux/include/asm-arm/arch-ks8695/system.h
+ *
+ *  Copyright (C) 2002 Micrel Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <asm/io.h>
+#include <asm/arch/platform.h>
+
+#define SYSTEM_VA_BASE  (IO_ADDRESS(KS8695_IO_BASE))
+
+static void arch_idle(void)
+{
+	/*
+	 * This should do all the clock switching
+	 * and wait for interrupt tricks
+	 */
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode)
+{
+	unsigned int val;
+
+	/*
+	 * To reset, use the watchdog timer
+	 */
+	val = __raw_readl(SYSTEM_VA_BASE + KS8695_TIMER_CTRL) & 0x02;
+	__raw_writel(val, SYSTEM_VA_BASE + KS8695_TIMER_CTRL);
+	val = (10 << 8) | 0xFF;
+	__raw_writel(val, SYSTEM_VA_BASE + KS8695_TIMER0);
+	val = __raw_readl(SYSTEM_VA_BASE + KS8695_TIMER_CTRL) | 0x01;
+	__raw_writel(val, SYSTEM_VA_BASE + KS8695_TIMER_CTRL);
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/time.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/time.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/time.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,112 @@
+/*
+ *  linux/include/asm-arm/arch-ks8695/time.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/system.h>
+#include <asm/leds.h>
+
+/*
+ * Where is the timer (VA)?
+ */
+#define TIMER_VA_BASE  (IO_ADDRESS(KS8695_IO_BASE))
+
+/*
+ * How long is the timer interval?
+ */
+#define TIMER_INTERVAL	     (TICKS_PER_uSEC * mSEC_10)
+#define TIMER_DATA_VALUE     (TIMER_INTERVAL >> 1)
+#define TIMER_PULSE_VALUE    (TIMER_INTERVAL - TIMER_DATA_VALUE)
+#define TIMER_VALUE          (TIMER_DATA_VALUE + TIMER_PULSE_VALUE)
+#define TICKS2USECS(x)	     ((x) / TICKS_PER_uSEC)
+#define TIMER_GET_VALUE(x)   (__raw_readl(x + KS8695_TIMER1) + __raw_readl(x + KS8695_TIMER1_PCOUNT))
+
+extern unsigned long (*gettimeoffset)(void);
+
+/*
+ * Returns number of ms since last clock interrupt.  Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long ks8695_gettimeoffset(void)
+{
+	unsigned long ticks1, ticks2, status;
+
+	/*
+	 * Get the current number of ticks.  Note that there is a race
+	 * condition between us reading the timer and checking for
+	 * an interrupt.  We get around this by ensuring that the
+	 * counter has not reloaded between our two reads.
+	 */
+	ticks2 = TIMER_GET_VALUE(TIMER_VA_BASE);
+	do {
+		ticks1 = ticks2;
+		status = __raw_readl(TIMER_VA_BASE + KS8695_INT_STATUS);
+		ticks2 = TIMER_GET_VALUE(TIMER_VA_BASE);
+	} while (ticks2 > ticks1);
+
+	/*
+	 * Number of ticks since last interrupt.
+	 */
+	ticks1 = TIMER_VALUE - ticks2;
+
+	/*
+	 * Interrupt pending?  If so, we've reloaded once already.
+	 */
+	if (status & KS8695_INTMASK_TIMERINT1)
+		ticks1 += TIMER_VALUE;
+
+	/*
+	 * Convert the ticks to usecs
+	 */
+	return TICKS2USECS(ticks1);
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static void ks8695_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	// ...clear the interrupt
+        __raw_writel(KS8695_INTMASK_TIMERINT1, TIMER_VA_BASE + KS8695_INT_STATUS);
+
+	do_timer(regs);
+	do_profile(regs);
+}
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+static inline void setup_timer(void)
+{
+	timer_irq.handler = ks8695_timer_interrupt;
+
+	/*
+	 * Initialise to a known state (all timers off)
+	 */
+        __raw_writel(0, TIMER_VA_BASE + KS8695_TIMER_CTRL);
+
+	/* 
+	 * Make irqs happen for the system timer
+	 */
+	setup_arm_irq(KS8695_INT_TIMERINT1, &timer_irq);
+	gettimeoffset = ks8695_gettimeoffset;
+
+	/*
+	 * enable timer 1, timer 0 for watchdog
+	 */
+        __raw_writel(TIMER_DATA_VALUE, TIMER_VA_BASE + KS8695_TIMER1);
+        __raw_writel(TIMER_PULSE_VALUE, TIMER_VA_BASE + KS8695_TIMER1_PCOUNT);
+        __raw_writel(0x02, TIMER_VA_BASE + KS8695_TIMER_CTRL);
+}
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/timex.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/timex.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/timex.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,26 @@
+/*
+ *  linux/include/asm-arm/arch-integrator/timex.h
+ *
+ *  Integrator architecture timex specifications
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * ??
+ */
+#define CLOCK_TICK_RATE		(50000000 / 16)
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/uncompress.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/uncompress.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/uncompress.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,57 @@
+/*
+ *  linux/include/asm-arm/arch-ks8695/uncompress.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/arch/platform.h>
+
+/*
+ * This does not append a newline
+ */
+static void puts(const char *s)
+{
+	char val;
+
+#if !defined(CONFIG_MACH_LITE300) && !defined(CONFIG_MACH_CM4008) && \
+    !defined(CONFIG_MACH_CM41xx)
+	while (*s) {
+		while (!((*(volatile u_int *) (KS8695_IO_BASE + KS8695_UART_LINE_STATUS))
+			 & KS8695_UART_LINES_TXFE));
+		val = *s;
+		(*(volatile u_int *) (KS8695_IO_BASE + KS8695_UART_TX_HOLDING)) = (u_int) val;
+
+		if (*s == '\n') {
+			while (!((*(volatile u_int *) (KS8695_IO_BASE + KS8695_UART_LINE_STATUS))
+				 & KS8695_UART_LINES_TXFE));
+
+			val = '\r';
+			(*(volatile u_int *) (KS8695_IO_BASE + KS8695_UART_TX_HOLDING)) 
+			         = (u_int) val;
+		}
+		s++;
+	}
+	while (!((*(volatile u_int *) (KS8695_IO_BASE + KS8695_UART_LINE_STATUS))
+		 & KS8695_UART_LINES_TXFE));
+#endif
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+
+#define arch_decomp_wdog()
diff -urN linux-2.4.29/include/asm-arm/arch-ks8695/vmalloc.h linux-2.4.29-uc1/include/asm-arm/arch-ks8695/vmalloc.h
--- linux-2.4.29/include/asm-arm/arch-ks8695/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-ks8695/vmalloc.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ *  linux/include/asm-arm/arch-integrator/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff -urN linux-2.4.29/include/asm-arm/arch-omaha/platform.h linux-2.4.29-uc1/include/asm-arm/arch-omaha/platform.h
--- linux-2.4.29/include/asm-arm/arch-omaha/platform.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/arch-omaha/platform.h	2005-06-14 02:11:26.000000000 +0100
@@ -11,8 +11,6 @@
  * 	NOTE: This is a multi-hosted header file for use with uHAL and
  * 	      supported debuggers.
  * 
- * 	$Id: platform.h,v 1.12 2002/08/22 15:49:56 ahaigh Exp $
- * 
  *     Everything is defined in terms of PLAT_* and then the key values
  *     are redefined as required for uHAL.
  * 
diff -urN linux-2.4.29/include/asm-arm/assembler.h linux-2.4.29-uc1/include/asm-arm/assembler.h
--- linux-2.4.29/include/asm-arm/assembler.h	2000-08-13 17:54:15.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/assembler.h	2005-06-14 02:11:22.000000000 +0100
@@ -13,3 +13,17 @@
 
 #include <asm/proc/ptrace.h>
 #include <asm/proc/assembler.h>
+
+/*
+ * Endian independent macros for shifting bytes within registers.
+ */
+#ifndef __ARMEB__
+#define pull		lsr
+#define push		lsl
+#define byte(x)		(x*8)
+#else
+#define pull		lsl
+#define push		lsr
+#define byte(x)		((3-x)*8)
+#endif
+
diff -urN linux-2.4.29/include/asm-arm/bitfield.h linux-2.4.29-uc1/include/asm-arm/bitfield.h
--- linux-2.4.29/include/asm-arm/bitfield.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/bitfield.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,123 @@
+/*
+ *	FILE    	bitfield.h
+ *
+ *	Version 	1.1
+ *	Author  	Copyright (c) Marc A. Viredaz, 1998
+ *	        	DEC Western Research Laboratory, Palo Alto, CA
+ *	Date    	April 1998 (April 1997)
+ *	System  	Advanced RISC Machine (ARM)
+ *	Language	C or ARM Assembly
+ *	Purpose 	Definition of macros to operate on bit fields.
+ */
+
+
+
+#ifndef BITFIELD
+#define BITFIELD
+
+#ifndef LANGUAGE
+#define LANGUAGE	C
+#endif /* !defined (LANGUAGE) */
+
+#define C       	0
+#define Assembly	1
+
+#if LANGUAGE == C
+#define UData(Data)	((unsigned int) (Data))
+#elif LANGUAGE == Assembly
+#define UData(Data)	(Data)
+#endif /* LANGUAGE == C || LANGUAGE == Assembly */
+
+
+/*
+ * MACRO: Fld
+ *
+ * Purpose
+ *    The macro "Fld" encodes a bit field, given its size and its shift value
+ *    with respect to bit 0.
+ *
+ * Note
+ *    A more intuitive way to encode bit fields would have been to use their
+ *    mask. However, extracting size and shift value information from a bit
+ *    field's mask is cumbersome and might break the assembler (255-character
+ *    line-size limit).
+ *
+ * Input
+ *    Size      	Size of the bit field, in number of bits.
+ *    Shft      	Shift value of the bit field with respect to bit 0.
+ *
+ * Output
+ *    Fld       	Encoded bit field.
+ */
+
+#define Fld(Size, Shft)	(((Size) << 16) + (Shft))
+
+
+/*
+ * MACROS: FSize, FShft, FMsk, FAlnMsk, F1stBit
+ *
+ * Purpose
+ *    The macros "FSize", "FShft", "FMsk", "FAlnMsk", and "F1stBit" return
+ *    the size, shift value, mask, aligned mask, and first bit of a
+ *    bit field.
+ *
+ * Input
+ *    Field     	Encoded bit field (using the macro "Fld").
+ *
+ * Output
+ *    FSize     	Size of the bit field, in number of bits.
+ *    FShft     	Shift value of the bit field with respect to bit 0.
+ *    FMsk      	Mask for the bit field.
+ *    FAlnMsk   	Mask for the bit field, aligned on bit 0.
+ *    F1stBit   	First bit of the bit field.
+ */
+
+#define FSize(Field)	((Field) >> 16)
+#define FShft(Field)	((Field) & 0x0000FFFF)
+#define FMsk(Field)	(((UData (1) << FSize (Field)) - 1) << FShft (Field))
+#define FAlnMsk(Field)	((UData (1) << FSize (Field)) - 1)
+#define F1stBit(Field)	(UData (1) << FShft (Field))
+
+
+/*
+ * MACRO: FInsrt
+ *
+ * Purpose
+ *    The macro "FInsrt" inserts a value into a bit field by shifting the
+ *    former appropriately.
+ *
+ * Input
+ *    Value     	Bit-field value.
+ *    Field     	Encoded bit field (using the macro "Fld").
+ *
+ * Output
+ *    FInsrt    	Bit-field value positioned appropriately.
+ */
+
+#define FInsrt(Value, Field) \
+                	(UData (Value) << FShft (Field))
+
+
+/*
+ * MACRO: FExtr
+ *
+ * Purpose
+ *    The macro "FExtr" extracts the value of a bit field by masking and
+ *    shifting it appropriately.
+ *
+ * Input
+ *    Data      	Data containing the bit-field to be extracted.
+ *    Field     	Encoded bit field (using the macro "Fld").
+ *
+ * Output
+ *    FExtr     	Bit-field value.
+ */
+
+#define FExtr(Data, Field) \
+                	((UData (Data) >> FShft (Field)) & FAlnMsk (Field))
+
+
+#undef C
+#undef Assembly
+
+#endif /* !defined (BITFIELD) */
diff -urN linux-2.4.29/include/asm-arm/bitops.h linux-2.4.29-uc1/include/asm-arm/bitops.h
--- linux-2.4.29/include/asm-arm/bitops.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/bitops.h	2005-06-14 02:11:23.000000000 +0100
@@ -23,30 +23,50 @@
 /*
  * Function prototypes to keep gcc -Wall happy.
  */
-extern void set_bit(int nr, volatile void * addr);
+extern void _set_bit_le(int nr, volatile void * addr);
+extern void _set_bit_be(int nr, volatile void * addr);
 
-static inline void __set_bit(int nr, volatile void *addr)
+static inline void ___set_bit_le(int nr, volatile void *addr)
 {
 	((unsigned char *) addr)[nr >> 3] |= (1U << (nr & 7));
 }
 
-extern void clear_bit(int nr, volatile void * addr);
+static inline void ___set_bit_be(int nr, volatile void *addr)
+{
+	((unsigned char *) addr)[(nr ^ 0x18) >> 3] |= (1U << (nr & 7));
+}
 
-static inline void __clear_bit(int nr, volatile void *addr)
+extern void _clear_bit_le(int nr, volatile void * addr);
+extern void _clear_bit_be(int nr, volatile void * addr);
+
+static inline void ___clear_bit_le(int nr, volatile void *addr)
 {
 	((unsigned char *) addr)[nr >> 3] &= ~(1U << (nr & 7));
 }
 
-extern void change_bit(int nr, volatile void * addr);
+static inline void ___clear_bit_be(int nr, volatile void *addr)
+{
+	((unsigned char *) addr)[(nr ^ 0x18) >> 3] &= ~(1U << (nr & 7));
+}
+
+
+extern void _change_bit_le(int nr, volatile void * addr);
+extern void _change_bit_be(int nr, volatile void * addr);
 
-static inline void __change_bit(int nr, volatile void *addr)
+static inline void ___change_bit_le(int nr, volatile void *addr)
 {
 	((unsigned char *) addr)[nr >> 3] ^= (1U << (nr & 7));
 }
 
-extern int test_and_set_bit(int nr, volatile void * addr);
+static inline void ___change_bit_be(int nr, volatile void *addr)
+{
+	((unsigned char *) addr)[(nr ^ 0x18) >> 3] ^= (1U << (nr & 7));
+}
+
+extern int _test_and_set_bit_le(int nr, volatile void * addr);
+extern int _test_and_set_bit_be(int nr, volatile void * addr);
 
-static inline int __test_and_set_bit(int nr, volatile void *addr)
+static inline int ___test_and_set_bit_le(int nr, volatile void *addr)
 {
 	unsigned int mask = 1 << (nr & 7);
 	unsigned int oldval;
@@ -56,9 +76,20 @@
 	return oldval & mask;
 }
 
-extern int test_and_clear_bit(int nr, volatile void * addr);
+static inline int ___test_and_set_bit_be(int nr, volatile void *addr)
+{
+	unsigned int mask = 1 << (nr & 7);
+	unsigned int oldval;
 
-static inline int __test_and_clear_bit(int nr, volatile void *addr)
+	oldval = ((unsigned char *) addr)[(nr ^ 0x18) >> 3];
+	((unsigned char *) addr)[(nr ^ 0x18) >> 3] = oldval | mask;
+	return oldval & mask;
+}
+
+extern int _test_and_clear_bit_le(int nr, volatile void * addr);
+extern int _test_and_clear_bit_be(int nr, volatile void * addr);
+
+static inline int ___test_and_clear_bit_le(int nr, volatile void *addr)
 {
 	unsigned int mask = 1 << (nr & 7);
 	unsigned int oldval;
@@ -68,9 +99,20 @@
 	return oldval & mask;
 }
 
-extern int test_and_change_bit(int nr, volatile void * addr);
+static inline int ___test_and_clear_bit_be(int nr, volatile void *addr)
+{
+	unsigned int mask = 1 << (nr & 7);
+	unsigned int oldval;
+
+	oldval = ((unsigned char *) addr)[(nr ^ 0x18) >> 3];
+	((unsigned char *) addr)[(nr ^ 0x18) >> 3] = oldval & ~mask;
+	return oldval & mask;
+}
+
+extern int _test_and_change_bit_le(int nr, volatile void * addr);
+extern int _test_and_change_bit_be(int nr, volatile void * addr);
 
-static inline int __test_and_change_bit(int nr, volatile void *addr)
+static inline int ___test_and_change_bit_le(int nr, volatile void *addr)
 {
 	unsigned int mask = 1 << (nr & 7);
 	unsigned int oldval;
@@ -80,18 +122,86 @@
 	return oldval & mask;
 }
 
-extern int find_first_zero_bit(void * addr, unsigned size);
-extern int find_next_zero_bit(void * addr, int size, int offset);
+static inline int ___test_and_change_bit_be(int nr, volatile void *addr)
+{
+	unsigned int mask = 1 << (nr & 7);
+	unsigned int oldval;
 
-/*
- * This routine doesn't need to be atomic.
- */
-static inline int test_bit(int nr, const void * addr)
+	oldval = ((unsigned char *) addr)[(nr ^ 0x18) >> 3];
+	((unsigned char *) addr)[(nr ^ 0x18) >> 3] = oldval ^ mask;
+	return oldval & mask;
+}
+
+extern int _find_first_zero_bit_le(void * addr, unsigned size);
+extern int _find_next_zero_bit_le(void * addr, int size, int offset);
+extern int _find_first_zero_bit_be(void * addr, unsigned size);
+extern int _find_next_zero_bit_be(void * addr, int size, int offset);
+  
+  /*
+   * This routine doesn't need to be atomic.
+   */
+extern __inline__ int _test_bit_le(int nr, const void * addr)
+  {
+      return ((unsigned char *) addr)[nr >> 3] & (1U << (nr & 7));
+  }	
+  
+static __inline__ int _test_bit_be(int nr, const void * addr)
 {
-    return (((unsigned char *) addr)[nr >> 3] >> (nr & 7)) & 1;
+    return ((unsigned char *) addr)[(nr ^ 0x18) >> 3] & (1U << (nr & 7));
 }	
 
 /*
+ * Definitions according to our current endianness.
+ */
+
+#ifndef __ARMEB__
+
+#define set_bit				_set_bit_le
+#define clear_bit			_clear_bit_le
+#define change_bit			_change_bit_le
+#define test_bit			_test_bit_le
+
+#define test_and_set_bit		_test_and_set_bit_le
+#define test_and_clear_bit		_test_and_clear_bit_le
+#define test_and_change_bit		_test_and_change_bit_le
+
+#define find_first_zero_bit		_find_first_zero_bit_le
+#define	find_next_zero_bit		_find_next_zero_bit_le
+
+#define __set_bit			___set_bit_le
+#define __clear_bit			___clear_bit_le
+#define __change_bit			___change_bit_le
+
+#define __test_and_set_bit		___test_and_set_bit_le
+#define __test_and_clear_bit		___test_and_clear_bit_le
+#define __test_and_change_bit		___test_and_change_bit_le
+
+#else
+
+#define set_bit				_set_bit_be
+#define clear_bit			_clear_bit_be
+#define change_bit			_change_bit_be
+#define test_bit			_test_bit_be
+
+#define test_and_set_bit		_test_and_set_bit_be
+#define test_and_clear_bit		_test_and_clear_bit_be
+#define test_and_change_bit		_test_and_change_bit_be
+
+#define find_first_zero_bit		_find_first_zero_bit_be
+#define	find_next_zero_bit		_find_next_zero_bit_be
+
+#define __set_bit			___set_bit_be
+#define __clear_bit			___clear_bit_be
+#define __change_bit			___change_bit_be
+
+#define __test_and_set_bit		___test_and_set_bit_be
+#define __test_and_clear_bit		___test_and_clear_bit_be
+#define __test_and_change_bit		___test_and_change_bit_be
+
+#endif
+
+
+/*
  * ffz = Find First Zero in word. Undefined if no zero exists,
  * so code should check against ~0UL first..
  */
@@ -126,18 +236,18 @@
 #define hweight16(x) generic_hweight16(x)
 #define hweight8(x) generic_hweight8(x)
 
-#define ext2_set_bit			test_and_set_bit
-#define ext2_clear_bit			test_and_clear_bit
-#define ext2_test_bit			test_bit
-#define ext2_find_first_zero_bit	find_first_zero_bit
-#define ext2_find_next_zero_bit		find_next_zero_bit
+#define ext2_set_bit			_test_and_set_bit_le
+#define ext2_clear_bit			_test_and_clear_bit_le
+#define ext2_test_bit			_test_bit_le
+#define ext2_find_first_zero_bit	_find_first_zero_bit_le
+#define ext2_find_next_zero_bit		_find_next_zero_bit_le
 
 /* Bitmap functions for the minix filesystem. */
-#define minix_test_and_set_bit(nr,addr)	test_and_set_bit(nr,addr)
-#define minix_set_bit(nr,addr)		set_bit(nr,addr)
-#define minix_test_and_clear_bit(nr,addr)	test_and_clear_bit(nr,addr)
-#define minix_test_bit(nr,addr)		test_bit(nr,addr)
-#define minix_find_first_zero_bit(addr,size)	find_first_zero_bit(addr,size)
+#define minix_test_and_set_bit(nr,addr)	_test_and_set_bit_le(nr,addr)
+#define minix_set_bit(nr,addr)		_set_bit_le(nr,addr)
+#define minix_test_and_clear_bit(nr,addr)	_test_and_clear_bit_le(nr,addr)
+#define minix_test_bit(nr,addr)		_test_bit_le(nr,addr)
+#define minix_find_first_zero_bit(addr,size)	_find_first_zero_bit_le(addr,size)
 
 #endif /* __KERNEL__ */
 
diff -urN linux-2.4.29/include/asm-arm/checksum.h linux-2.4.29-uc1/include/asm-arm/checksum.h
--- linux-2.4.29/include/asm-arm/checksum.h	2002-08-03 01:39:45.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/checksum.h	2005-06-14 02:11:26.000000000 +0100
@@ -105,7 +105,11 @@
 	adcs	%0, %0, %5					\n\
 	adc	%0, %0, #0"
 	: "=&r"(sum)
+#ifndef __ARMEB__
 	: "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len) << 16), "Ir" (proto << 8)
+#else
+	: "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (proto)
+#endif
 	: "cc");
 	return sum;
 }	
@@ -127,7 +131,11 @@
 	addcs	%0, %0, #0x10000				\n\
 	mvn	%0, %0"
 	: "=&r"(sum)
+#ifndef __ARMEB__
 	: "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len)), "Ir" (proto << 8)
+#else
+	: "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (proto)
+#endif
 	: "cc");
 	return sum >> 16;
 }
diff -urN linux-2.4.29/include/asm-arm/cpu-single.h linux-2.4.29-uc1/include/asm-arm/cpu-single.h
--- linux-2.4.29/include/asm-arm/cpu-single.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/cpu-single.h	2005-06-14 02:11:22.000000000 +0100
@@ -45,7 +45,11 @@
 #define cpu_tlb_invalidate_range	cpu_fn(CPU_NAME,_tlb_invalidate_range)
 #define cpu_tlb_invalidate_page		cpu_fn(CPU_NAME,_tlb_invalidate_page)
 
+#if __LINUX_ARM_ARCH__ == 3
+#define cpu_set_pgd(x)			{ g_pgd = x; cpu_fn(CPU_NAME,_set_pgd)(x); }
+#else
 #define cpu_set_pgd			cpu_fn(CPU_NAME,_set_pgd)
+#endif
 #define cpu_set_pmd			cpu_fn(CPU_NAME,_set_pmd)
 #define cpu_set_pte			cpu_fn(CPU_NAME,_set_pte)
 
@@ -80,13 +84,24 @@
 extern void cpu_tlb_invalidate_range(unsigned long address, unsigned long end);
 extern void cpu_tlb_invalidate_page(unsigned long address, int flags);
 
+#if __LINUX_ARM_ARCH__ == 3
+extern unsigned long g_pgd;
+extern void cpu_fn(CPU_NAME,_set_pgd)(unsigned long pgd_phys);
+#else
 extern void cpu_set_pgd(unsigned long pgd_phys);
+#endif
 extern void cpu_set_pmd(pmd_t *pmdp, pmd_t pmd);
 extern void cpu_set_pte(pte_t *ptep, pte_t pte);
 extern volatile void cpu_reset(unsigned long addr);
 
 #define cpu_switch_mm(pgd,tsk) cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)))
 
+#if __LINUX_ARM_ARCH__ == 3
+#define cpu_get_pgd()	\
+	({						\
+		(pgd_t *)phys_to_virt(g_pgd);		\
+	})
+#else
 #define cpu_get_pgd()	\
 	({						\
 		unsigned long pg;			\
@@ -95,5 +110,6 @@
 		pg &= ~0x3fff;				\
 		(pgd_t *)phys_to_virt(pg);		\
 	})
+#endif
 
 #endif
diff -urN linux-2.4.29/include/asm-arm/div64.h linux-2.4.29-uc1/include/asm-arm/div64.h
--- linux-2.4.29/include/asm-arm/div64.h	2000-01-13 21:30:31.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-arm/div64.h	2005-06-14 02:11:22.000000000 +0100
@@ -1,14 +1 @@
-#ifndef __ASM_ARM_DIV64
-#define __ASM_ARM_DIV64
-
-/* We're not 64-bit, but... */
-#define do_div(n,base)						\
-({								\
-	int __res;						\
-	__res = ((unsigned long)n) % (unsigned int)base;	\
-	n = ((unsigned long)n) / (unsigned int)base;		\
-	__res;							\
-})
-
-#endif
-
+#include <asm-generic/div64.h>
diff -urN linux-2.4.29/include/asm-arm/elf.h linux-2.4.29-uc1/include/asm-arm/elf.h
--- linux-2.4.29/include/asm-arm/elf.h	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-arm/elf.h	2005-06-14 02:11:26.000000000 +0100
@@ -43,7 +43,11 @@
    the loader.  We need to make sure that it is out of the way of the program
    that it will "exec", and that there is sufficient room for the brk.  */
 
+#ifdef CONFIG_ARM_FASS
+#define ELF_ET_DYN_BASE	CPD_UNMAPPED_BASE
+#else
 #define ELF_ET_DYN_BASE	(2 * TASK_SIZE / 3)
+#endif
 
 /* When the program starts, a1 contains a pointer to a function to be 
    registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
diff -urN linux-2.4.29/include/asm-arm/fast_timer.h linux-2.4.29-uc1/include/asm-arm/fast_timer.h
--- linux-2.4.29/include/asm-arm/fast_timer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/fast_timer.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1 @@
+#include <asm/arch/fast_timer.h>
diff -urN linux-2.4.29/include/asm-arm/hardware/ep7312.h linux-2.4.29-uc1/include/asm-arm/hardware/ep7312.h
--- linux-2.4.29/include/asm-arm/hardware/ep7312.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/hardware/ep7312.h	2005-06-14 02:11:22.000000000 +0100
@@ -4,7 +4,7 @@
  *  This file contains the hardware definitions of the EP7312 internal
  *  registers.
  *
- *  Copyright (C) 2003 Roland A.I. Rosier <roland.rosier@lycos.co.uk>.
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,29 +26,63 @@
 #include <linux/config.h>
 
 /*
- * Include CLPS7111 and EP7212 register definitions
- */
-
-#include <asm/hardware/clps7111.h>
-#include <asm/hardware/ep7212.h>
-
-/*
  * define EP7312_BASE to be the base address of the region
  * you want to access.
  */
 
 #define EP7312_PHYS_BASE        (0x80000000)
 
-#define SDCONF   0x2300	/* SDRAM Configuration register */
-#define SDRFPR   0x2340	/* SDRAM Refresh period register */
-#define UNIQID   0x2440	/* 32 bit unique ID for the EP73xx device */
-#define DAI64FS  0x2600	/* DAI 64Fs Control Register */
-#define PLLW     0x2610	/* Write Register for PLL Multiplier */
-#define PLLR     0xA5A8	/* Read Register for PLL Multiplier */
-#define RANDID0	 0x2700	/* Bits 31-0 of 128-bit random ID */
-#define RANDID1	 0x2704	/* Bits 63-32 of 128-bit random ID */
-#define RANDID2	 0x2708	/* Bits 95-64 of 128-bit random ID */
-#define RANDID3	 0x270C	/* Bits 127-96 of 128-bit random ID */
+#ifndef __ASSEMBLY__
+#define ep_readl(off)		__raw_readl(EP7312_BASE + (off))
+#define ep_writel(val,off)	__raw_writel(val, EP7312_BASE + (off))
+#endif
+
+/*
+ * These registers are specific to the EP7312 only
+ */
+#define DAIR			0x2000
+#define DAIR0			0x2040
+#define DAIDR1			0x2080
+#define DAIDR2			0x20c0
+#define DAISR			0x2100
+#define SYSCON3			0x2200
+#define INTSR3			0x2240
+#define INTMR3			0x2280
+#define LEDFLSH			0x22c0
+#define SDCONF			0x2300
+#define SDRFPR			0x2340
+
+#define DAIR_DAIEN		(1 << 16)
+#define DAIR_ECS		(1 << 17)
+#define DAIR_LCTM		(1 << 19)
+#define DAIR_LCRM		(1 << 20)
+#define DAIR_RCTM		(1 << 21)
+#define DAIR_RCRM		(1 << 22)
+#define DAIR_LBM		(1 << 23)
+
+#define DAIDR2_FIFOEN		(1 << 15)
+#define DAIDR2_FIFOLEFT		(0x0d << 16)
+#define DAIDR2_FIFORIGHT	(0x11 << 16)
+
+#define DAISR_RCTS		(1 << 0)
+#define DAISR_RCRS		(1 << 1)
+#define DAISR_LCTS		(1 << 2)
+#define DAISR_LCRS		(1 << 3)
+#define DAISR_RCTU		(1 << 4)
+#define DAISR_RCRO		(1 << 5)
+#define DAISR_LCTU		(1 << 6)
+#define DAISR_LCRO		(1 << 7)
+#define DAISR_RCNF		(1 << 8)
+#define DAISR_RCNE		(1 << 9)
+#define DAISR_LCNF		(1 << 10)
+#define DAISR_LCNE		(1 << 11)
+#define DAISR_FIFO		(1 << 12)
+
+#define SYSCON3_ADCCON		(1 << 0)
+#define SYSCON3_DAISEL		(1 << 3)
+#define SYSCON3_ADCCKNSEN	(1 << 4)
+#define SYSCON3_FASTWAKE	(1 << 8)
+#define SYSCON3_DAIEN		(1 << 9)
 
 #define SDCONF_ACTIVE           (1 << 10)
 #define SDCONF_CLKCTL           (1 << 9)
diff -urN linux-2.4.29/include/asm-arm/ide.h linux-2.4.29-uc1/include/asm-arm/ide.h
--- linux-2.4.29/include/asm-arm/ide.h	2003-06-13 15:51:38.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/ide.h	2005-06-14 02:11:23.000000000 +0100
@@ -13,12 +13,55 @@
 
 #ifdef __KERNEL__
 
+#ifdef CONFIG_ARCH_EDB7312
+#define MAX_HWIFS	1
+#endif
+
 #ifndef MAX_HWIFS
 #define MAX_HWIFS	4
 #endif
 
+#define	ide__sti()	__sti()
+
 #include <asm/arch/ide.h>
 
+#ifdef CONFIG_ARCH_EDB7312
+#include <asm/hardware/clps7111.h>
+#include <asm/io.h>
+
+#define ide_request_irq(irq,hand,flg,dev,id)   request_irq((irq),(hand),SA_SHIRQ,(dev),(id))
+#define ide_free_irq(irq,dev_id)               free_irq((irq), (dev_id))
+#define ide_check_region(from,extent)          (0)
+#define ide_request_region(from,extent,name)
+#define ide_release_region(from,extent)
+
+#define HAVE_ARCH_IN_BYTE
+#define HAVE_ARCH_OUT_BYTE
+
+#define OUT_BYTE(b,p)  (clps_writel(clps_readl(MEMCFG2) | 0x0300, MEMCFG2), \
+                       __raw_writeb(b, p), \
+                       clps_writel(clps_readl(MEMCFG2) & ~0x0300, MEMCFG2))
+#define OUT_WORD(w,p)  __raw_writew(w, p)
+#define IN_BYTE(p)     edb7312_ide_in_byte (p)
+#define IN_WORD(p)     __raw_readw(p)
+
+static inline int edb7312_ide_in_byte(int p)
+{
+	int r;
+
+	clps_writel(clps_readl(MEMCFG2) | 0x0300, MEMCFG2);
+	r = __raw_readb(p);
+	clps_writel(clps_readl(MEMCFG2) & ~0x0300, MEMCFG2);
+
+	return (r);
+}
+
+/* convert old to new style ide i/o primitives */
+
+
+
+#endif
+
 /*
  * We always use the new IDE port registering,
  * so these are fixed here.
diff -urN linux-2.4.29/include/asm-arm/io.h linux-2.4.29-uc1/include/asm-arm/io.h
--- linux-2.4.29/include/asm-arm/io.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/io.h	2005-06-14 02:11:23.000000000 +0100
@@ -25,6 +25,7 @@
 #include <linux/types.h>
 #include <asm/byteorder.h>
 #include <asm/memory.h>
+#include <asm/byteorder.h>
 #include <asm/arch/hardware.h>
 
 /*
@@ -289,5 +290,6 @@
 #define isa_check_signature(io,sig,len)	(0)
 
 #endif	/* __mem_isa */
+
 #endif	/* __KERNEL__ */
 #endif	/* __ASM_ARM_IO_H */
diff -urN linux-2.4.29/include/asm-arm/keyboard.h linux-2.4.29-uc1/include/asm-arm/keyboard.h
--- linux-2.4.29/include/asm-arm/keyboard.h	2001-10-25 21:53:55.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/keyboard.h	2005-06-14 02:11:23.000000000 +0100
@@ -24,6 +24,40 @@
  */
 #ifdef __KERNEL__
 
+#ifdef	CONFIG_ARCH_EDB7312
+
+#include <asm/arch/irqs.h>
+
+#undef	mdelay
+#define	mdelay(x)	udelay(2000)
+
+#define kbd_read_input() __raw_readb(EDB7312_VIRT_8042 + 0)
+#define kbd_read_status() __raw_readb(EDB7312_VIRT_8042 + 1)
+#define kbd_write_output(val) __raw_writeb(val, EDB7312_VIRT_8042 + 0)
+#define kbd_write_command(val) __raw_writeb(val, EDB7312_VIRT_8042 + 1)
+
+#define	kbd_request_region()
+#define	kbd_request_irq(handler) request_irq(IRQ_EINT1, handler, SA_SHIRQ, \
+                                             "keyboard", "kbd"); \
+				 edb7312_enable_eint1()
+#define	kbd_disable_irq()
+#define	kbd_enable_irq()
+#define	aux_request_irq(a, b)	0000
+#define	aux_free_irq(a)
+
+extern unsigned char pckbd_sysrq_xlate[];
+
+#define kbd_setkeycode          pckbd_setkeycode
+#define kbd_getkeycode          pckbd_getkeycode
+#define kbd_translate           pckbd_translate
+#define kbd_unexpected_up       pckbd_unexpected_up
+#define kbd_leds                pckbd_leds
+#define kbd_init_hw             pckbd_init_hw
+#define SYSRQ_KEY		0x63
+#define kbd_sysrq_xlate         pckbd_sysrq_xlate
+
+#else
+
 extern int  (*k_setkeycode)(unsigned int, unsigned int);
 extern int  (*k_getkeycode)(unsigned int);
 extern int  (*k_translate)(unsigned char, unsigned char *, char);
@@ -67,6 +101,8 @@
 
 #include <asm/arch/keyboard.h>
 
+#endif	/* CONFIG_ARCH_EDB7312 */
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASM_ARM_KEYBOARD_H */
diff -urN linux-2.4.29/include/asm-arm/kgdb.h linux-2.4.29-uc1/include/asm-arm/kgdb.h
--- linux-2.4.29/include/asm-arm/kgdb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/kgdb.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,97 @@
+/*
+ * include/asm-arm/kgdb.h
+ *
+ * ARM KGDB support 
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (C) 2002 MontaVista Software Inc.
+ *
+ */
+
+#ifndef __ASM_KGDB_H__
+#define __ASM_KGDB_H__
+
+
+#ifdef CONFIG_KGDB
+
+/*
+ * Generic kgdb entry point
+ *
+ * This is called by various trap handlers when all else fails
+ * and a kernel excpetion has occured.
+ */
+void do_kgdb(struct pt_regs *, unsigned char);
+
+
+/*
+ * Determine if KGDB is running or not
+ */
+int kgdb_active(void);
+
+/*
+ * Are we connected to a remote client?
+ */
+int kgdb_connected(void);
+
+/* 
+ * kgdb_handle_bus_error() is used to recover from bus errors
+ * which may occur during kgdb memory read/write operations.
+ * Before performing a memory read/write operation, we set
+ * the kgdb_fault_expected flag, call setjmp to save the
+ * current machine context, and then perform the read/write
+ * operation. If an error occurs, kgdb_handle_bus_error is
+ * invoked from do_page_fault and we call longjmp to restore
+ * the machine state and return to kgdb at the setjmp return
+ * address. Both setjmp and longjmp return a flag which is
+ * tested upon return to determine if all is well. Upon the
+ * initial call to setjmp, the machine context is saved and
+ * a return value of zero indicates all is well. Next, we
+ * perform the read/write operation. Now, if an error occurs,
+ * longjmp will return to the setjmp == 0 test case. But
+ * this time, non-zero status is returned. In which case,
+ * we return an error status message to the gdb host. Else,
+ * if the read/write operation succeeds, we return the usual
+ * status message to the gdb host.
+ */
+extern void kgdb_handle_bus_error(void);                                                                                              
+extern int kgdb_setjmp(int *machine_context);
+extern int kgdb_longjmp(int *machine_context, int flag);
+extern int kgdb_fault_expected;
+ 
+/*
+ * breakpoint() is used by the kernel at initialization to force
+ * a sync with the GDB on the host side.
+ */
+#define breakpoint()	asm (".word	0xe7ffdeff")
+
+extern void kgdb_get_packet(unsigned char *, int);
+extern void kgdb_put_packet(unsigned char *);
+
+extern int kgdb_io_init(void);
+
+#ifdef CONFIG_KGDB_SERIAL
+
+extern unsigned char kgdb_serial_getchar(void);
+extern void kgdb_serial_putchar(unsigned char);
+
+extern void kgdb_serial_init(void);
+
+#endif
+
+#ifdef CONFIG_KGDB_UDP
+
+extern unsigned kgdb_net_rx(unsigned char *);
+extern unsigned kgdb_net_tx(unsigned char *);
+
+#endif
+
+#else // NO KGDB
+
+#define	kgdb_active()	0
+
+#define	breakpoint()
+
+#endif 
+
+#endif // __ASM_KGDB_H__
diff -urN linux-2.4.29/include/asm-arm/kmap_types.h linux-2.4.29-uc1/include/asm-arm/kmap_types.h
--- linux-2.4.29/include/asm-arm/kmap_types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/kmap_types.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,16 @@
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+enum km_type {
+	KM_BOUNCE_READ,
+	KM_SKB_SUNRPC_DATA,
+	KM_SKB_DATA_SOFTIRQ,
+	KM_USER0,
+	KM_USER1,
+	KM_BH_IRQ,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
+	KM_TYPE_NR
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-arm/mach/pci.h linux-2.4.29-uc1/include/asm-arm/mach/pci.h
--- linux-2.4.29/include/asm-arm/mach/pci.h	2001-08-12 19:14:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/mach/pci.h	2005-06-14 02:11:23.000000000 +0100
@@ -27,6 +27,17 @@
 	int		(*map_irq)(struct pci_dev *dev, u8 slot, u8 pin);
 };
 
+struct pci_sys_data {
+    /*
+     * The hardware we are attached to
+     */
+    struct hw_pci   *hw;
+    unsigned long   mem_offset;
+    /*
+     * These are the resources for the root bus.
+     */
+    struct resource *resource[3];
+};
 extern u8 no_swizzle(struct pci_dev *dev, u8 *pin);
 extern void __init dc21285_setup_resources(struct resource **resource);
 extern void __init dc21285_init(void *sysdata);
diff -urN linux-2.4.29/include/asm-arm/mmu_context.h linux-2.4.29-uc1/include/asm-arm/mmu_context.h
--- linux-2.4.29/include/asm-arm/mmu_context.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/mmu_context.h	2005-06-14 02:11:24.000000000 +0100
@@ -9,6 +9,7 @@
  *
  *  Changelog:
  *   27-06-1996	RMK	Created
+ *   20-06-2001 AGW     Defined (destroy/init_new)_context for FASS.
  */
 #ifndef __ASM_ARM_MMU_CONTEXT_H
 #define __ASM_ARM_MMU_CONTEXT_H
@@ -17,9 +18,50 @@
 #include <asm/memory.h>
 #include <asm/proc-fns.h>
 
+#ifdef CONFIG_ARM_FASS
+#include <asm/proc-armv/cpd.h>
+#include <asm/proc-armv/pid.h>
+
+static inline void
+destroy_context(struct mm_struct* mm_p)
+{
+	//printk("** destroy_context: current 0x%x mm_p 0x%x **\n", current, mm_p);
+  
+	cpd_deallocate_region(mm_p->context.region_p);
+
+	if (mm_p->context.pid_p) {
+		arm_pid_unallocate(mm_p->context.pid_p);
+	}
+
+}
+
+/* Do these values need to be zeroed? It seemed not to work if they weren't */
+static inline int
+init_new_context(struct task_struct* task_p, struct mm_struct* mm_p)
+{
+	//printk("** init_new_context: task_p 0x%x  mm_p 0x%x **\n", task_p, mm_p);
+
+	if ((mm_p->context.region_p = cpd_allocate_region()) == NULL) {
+		return -1; /* Is this right? */
+	}
+
+	/* No domain or ARM PID yet allocated */
+	mm_p->context.pid = 0;
+	mm_p->context.pid_p = NULL;
+	mm_p->context.dacr = 0;
+  
+	return 0;
+
+}
+
+#else
+
 #define destroy_context(mm)		do { } while(0)
 #define init_new_context(tsk,mm)	0
 
+#endif /* CONFIG_ARM_FASS */
+
+
 /*
  * This is called when "tsk" is about to enter lazy TLB mode.
  *
@@ -43,7 +85,11 @@
 	  struct task_struct *tsk, unsigned int cpu)
 {
 	if (prev != next)
+#ifdef CONFIG_ARM_FASS
+		cpd_switch_mm(next);
+#else
 		cpu_switch_mm(next->pgd, tsk);
+#endif
 }
 
 #define activate_mm(prev, next) \
diff -urN linux-2.4.29/include/asm-arm/mmu.h linux-2.4.29-uc1/include/asm-arm/mmu.h
--- linux-2.4.29/include/asm-arm/mmu.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/mmu.h	2005-06-14 02:11:23.000000000 +0100
@@ -1,9 +1,63 @@
+/* include/asm-arm/mmu.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  20-Jun-2001         Modified by Adam Wiggins <awiggins@cse.unsw.edu.au>
+ *                      for FASS.
+ *  11-Oct-2001         Added PID field for PID register relocation support.
+ *  26-Apr-2002         Added domain_timestamp field allow lazy clearing of the
+ *                      DACR. This is required to keep track of clean domains
+ *                      and to disable accessed to unallocated domains.
+ *  15-Sep-2003         Modified by John Zaitseff <J.Zaitseff@unsw.edu.au>
+ *                      for Linux kernel 2.4.21-rmk1
+ */
+
 #ifndef __ARM_MMU_H
 #define __ARM_MMU_H
 
+#ifdef CONFIG_ARM_FASS
+
+/***********************
+* Forward declerations *
+***********************/
+
+/* include/asm-arm/proc-armv/cpd.h */
+struct domain_struct;
+
+/* include/asm-arm/proc-armv/pid.h */
+struct pid_struct;
+
+/* Address-space context */
+struct fass_struct{
+  unsigned int pid;                    /* Process ID register */
+  unsigned int dacr;                   /* Domain Access Control Register */
+  unsigned long long domain_timestamp; /* Last DACR clearing to check domains */
+
+  struct pid_struct* pid_p;            /* PID associated with address-space */
+  struct region_struct* region_p;      /* Address-space's private region */
+};
+
+typedef struct fass_struct mm_context_t;
+
+struct task_struct;
+struct mm_struct;
+
+extern void arm_pid_allocate(struct task_struct *, struct mm_struct *);
+static inline void
+arch_new_mm(struct task_struct *tp, struct mm_struct *mm)
+{
+	arm_pid_allocate(tp, mm);
+}
+
+#else
+
 /*
  * The ARM doesn't have a mmu context
  */
 typedef struct { } mm_context_t;
 
-#endif
+#endif /* CONFIG_ARM_FASS */
+
+#endif /* !__ARM_MMU_H */
diff -urN linux-2.4.29/include/asm-arm/pci.h linux-2.4.29-uc1/include/asm-arm/pci.h
--- linux-2.4.29/include/asm-arm/pci.h	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-arm/pci.h	2005-06-14 02:11:23.000000000 +0100
@@ -90,6 +90,10 @@
 static inline dma_addr_t
 pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
 {
+#ifdef CONFIG_ARCH_IXP425
+	extern dma_addr_t ixp425_map_single(void *, size_t, int);
+	return ixp425_map_single(ptr, size, direction);
+#endif
 	if (dev_is_sa1111(hwdev))
 		return sa1111_map_single(ptr, size, direction);
 
@@ -97,6 +101,13 @@
 	return virt_to_bus(ptr);
 }
 
+static inline dma_addr_t
+pci_map_page(struct pci_dev *hwdev, struct page *page, unsigned long offset, size_t size, int dir)
+{
+	void *vaddr = (void*) page_address(page);
+	return pci_map_single(hwdev, vaddr + offset, size, dir);
+}
+
 /* Unmap a single streaming mode DMA translation.  The dma_addr and size
  * must match what was provided for in a previous pci_map_single call.  All
  * other usages are undefined.
@@ -107,12 +118,23 @@
 static inline void
 pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
 {
+#ifdef CONFIG_ARCH_IXP425
+	extern void ixp425_unmap_single(dma_addr_t, size_t, int);
+	ixp425_unmap_single(dma_addr, size, direction);
+#endif
 	if (dev_is_sa1111(hwdev))
 		sa1111_unmap_single(dma_addr, size, direction);
 
 	/* nothing to do */
 }
 
+static inline void
+pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_addr, 
+			size_t size, int direction)
+{
+	pci_unmap_single(hwdev, dma_addr, size, direction);
+}
+
 /* Whether pci_unmap_{single,page} is a nop depends upon the
  * configuration.
  */
@@ -201,6 +223,11 @@
 static inline void
 pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction)
 {
+#ifdef CONFIG_ARCH_IXP425
+	extern void ixp425_sync_single(dma_addr_t, size_t, int);
+	ixp425_sync_single(dma_handle, size, direction);
+	return;
+#endif
 	if (dev_is_sa1111(hwdev)) {
 	  	sa1111_dma_sync_single(dma_handle, size, direction);
 		return;
diff -urN linux-2.4.29/include/asm-arm/pgtable.h linux-2.4.29-uc1/include/asm-arm/pgtable.h
--- linux-2.4.29/include/asm-arm/pgtable.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/pgtable.h	2005-06-14 02:11:22.000000000 +0100
@@ -160,6 +160,11 @@
 
 #include <asm-generic/pgtable.h>
 
+#ifdef CONFIG_ARM_FASS
+/* FASS defines arch_get_unmapped_area */
+#define HAVE_ARCH_UNMAPPED_AREA
+#endif
+
 extern void pgtable_cache_init(void);
 
 /*
diff -urN linux-2.4.29/include/asm-arm/proc-armv/cache.h linux-2.4.29-uc1/include/asm-arm/proc-armv/cache.h
--- linux-2.4.29/include/asm-arm/proc-armv/cache.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/proc-armv/cache.h	2005-06-14 02:11:24.000000000 +0100
@@ -30,6 +30,38 @@
 /*
  * Generic I + D cache
  */
+#ifdef CONFIG_ARM_FASS
+
+#define flush_cache_all()						\
+	do {								\
+		cpd_cache_flush_all();					\
+	} while (0)
+
+/* This is always called for current->mm */
+#define flush_cache_mm(_mm)						\
+	do {								\
+		if ((_mm) == current->active_mm)			\
+			cpd_cache_flush_mm((_mm));			\
+	} while (0)
+
+#define flush_cache_range(_mm,_start,_end)				\
+	do {								\
+		if ((_mm) == current->active_mm)			\
+			cpd_cache_flush_range((_mm), (_start) & PAGE_MASK, \
+					      PAGE_ALIGN(_end)); 	\
+	} while (0)
+
+#define flush_cache_page(_vma,_vmaddr)					\
+	do {								\
+		if ((_vma)->vm_mm == current->active_mm) {		\
+			unsigned long _addr = (_vmaddr) & PAGE_MASK;	\
+			cpd_cache_flush_page((_vma), _addr);		\
+		}							\
+	} while (0)
+
+
+#else
+
 #define flush_cache_all()						\
 	do {								\
 		cpu_cache_clean_invalidate_all();			\
@@ -59,6 +91,8 @@
 		} \
 	} while (0)
 
+#endif /* CONFIG_ARM_FASS */
+
 /*
  * This flushes back any buffered write data.  We have to clean the entries
  * in the cache for this page.  This does not invalidate either I or D caches.
@@ -97,6 +131,9 @@
 
 /*
  * D cache only
+ *
+ * Note: FASS doesn't touch these since they seem to be for keeping kernel memory
+ *       consistent with the caches.
  */
 
 #define invalidate_dcache_range(_s,_e)	cpu_dcache_invalidate_range((_s),(_e))
@@ -186,6 +223,52 @@
  * are really up to date.  It is more efficient to do this here...
  */
 
+#ifdef CONFIG_ARM_FASS
+/*
+ * Notes:
+ *  current->active_mm is the currently active memory description.
+ *  current->mm == NULL iff we are lazy.
+ */
+#define flush_tlb_all()							\
+	do {								\
+		cpd_tlb_flush_all();					\
+	} while (0)
+
+/*
+ * Flush all user virtual address space translations described by `_mm'.
+ *
+ * Currently, this is always called for current->mm, which should be
+ * the same as current->active_mm.  This is currently not be called for
+ * the lazy TLB case.
+ */
+#define flush_tlb_mm(_mm)						\
+	do {								\
+		if ((_mm) == current->active_mm)			\
+			cpd_tlb_flush_mm((_mm));			\
+	} while (0)
+
+/*
+ * Flush the specified range of user virtual address space translations.
+ *
+ * _mm may not be current->active_mm, but may not be NULL.
+ */
+#define flush_tlb_range(_mm,_start,_end)				\
+	do {								\
+		if ((_mm) == current->active_mm)			\
+			cpd_tlb_flush_range((_mm), (_start), (_end));	\
+	} while (0)
+
+/*
+ * Flush the specified user virtual address space translation.
+ */
+#define flush_tlb_page(_vma,_page)					\
+	do {								\
+		if ((_vma)->vm_mm == current->active_mm)		\
+			cpd_tlb_flush_page((_vma), (_page));		\
+	} while (0)
+
+#else
+
 /*
  * Notes:
  *  current->active_mm is the currently active memory description.
@@ -227,9 +310,12 @@
 	do {								\
 		if ((_vma)->vm_mm == current->active_mm)		\
 			cpu_tlb_invalidate_page((_page),		\
-				 ((_vma)->vm_flags & VM_EXEC));		\
+				((_vma)->vm_flags & VM_EXEC));		\
 	} while (0)
 
+
+#endif /* CONFIG_ARM_FASS */
+
 /*
  * if PG_dcache_dirty is set for the page, we need to ensure that any
  * cache entries for the kernels virtual memory range are written
diff -urN linux-2.4.29/include/asm-arm/proc-armv/cpd.h linux-2.4.29-uc1/include/asm-arm/proc-armv/cpd.h
--- linux-2.4.29/include/asm-arm/proc-armv/cpd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/proc-armv/cpd.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,311 @@
+/*
+ * Filename:    include/asm-arm/proc-armv/cpd.h
+ * Description: Caching Page Directory (CPD) includes for Fast Address 
+ *		Space Switching (FASS) in ARM Linux.
+ * Created: 20/06/2001
+ * Changes: 19/02/2002 - Added helper macros.
+ *          22/02/2002 - cpd_struct updated to include doubly linked list
+ *          of cpd_structs allocated to the same domain.
+ *          19/03/2002 - Start of modifications to support shared domains.
+ *          26/04/2002 - Change per address-space domain disabling, via the
+ *          DACR, to be lazy rather then diabling all domains on a context
+ *          switch. Now all domains only diabled if a cache/tlb clean event
+ *          occurred since the address-space last ran or if a domain was
+ *          unallocated.
+ *          28/04/2002 - Added macro's for clock domain recycling algorithm.
+ *
+ * Copyright:   (c) 2001, 2002 Adam Wiggins <awiggins@cse.unsw.edu.au>
+ *		(c) 2004 National ICT Australia
+ *
+ ***************************************************************************
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of teh GNU General Public License version 2 as
+ * published by the Free Software Foundation.                               
+ */
+
+
+#ifndef __ASM_PROC_CPD_H
+#define __ASM_PROC_CPD_H
+#ifdef CONFIG_ARM_FASS
+
+#include <linux/sched.h>
+//#include <asm/pgtable.h>
+
+/******************
+* Benchmark Flags *
+******************/
+
+#define CLOCK_RECYCLE 0 /* Round-robin domain recycling */
+#define PID_ENABLE    1 /* PID relocation enabling/disabling */
+#define LAZY_DISABLE  1 /* Lazy vs strict domain disabling via DACR */
+#define ALWAYS_DIRTY  0 /* Always mark tlb/caches as incoherent */
+
+/**********
+* Defines *
+**********/
+
+//#define HAVE_ARCH_VM_SHARING_DATA
+
+/* Base address for mmap() allocations */
+#define CPD_UNMAPPED_BASE 0x80000000 /* Evilly hardcoded to 2GB */
+
+/*********
+* Macros *
+*********/
+
+/*
+ * Set to enable FASS specific debugging options
+ * yes there is probably a better
+ * way to do this. 
+ */
+#if 1
+#define fassert(expr) BUG_ON(!(expr))
+#else
+#define fassert(expr) 
+#endif
+
+/* Some handy macros */
+
+#define MEGABYTE(n) ((n) << 20)
+#define MASK_MEGABYTE(addr, n) ((addr) & ~(MEGABYTE(n) - 1))
+#define CPD_P_TO_INDEX(cpd_p) (((unsigned long)(cpd_p) >> 2) &              \
+                               ((1 << 12) - 1)) /* I know this is ugly */
+
+#define STATS_P_TO_INDEX(cpd_stats_p) ((((unsigned long)(cpd_stats_p)) -     \
+					((unsigned long)(cpd_stats))) /      \
+				       sizeof(struct cpd_struct))
+
+/* Is a domain/mm dirty with respect to the TLBs/Caches? */
+
+#if ALWAYS_DIRTY
+# define cpd_is_domain_coherent(domain)        0
+# define cpd_is_domain_tlb_coherent(domain)    0
+# define cpd_is_domain_cache_coherent(domain)  0
+# define cpd_is_domain_dcache_coherent(domain) 0
+# define cpd_is_domain_icache_coherent(domain) 0
+
+# define cpd_is_mm_coherent(mm_p)        0
+# define cpd_is_mm_tlb_coherent(mm_p)    0
+# define cpd_is_mm_cache_coherent(mm_p)  0
+# define cpd_is_mm_dcache_coherent(mm_p) 0
+# define cpd_is_mm_icache_coherent(mm_p) 0
+
+#else
+
+# define cpd_is_domain_coherent(domain)                                   \
+          (cpd_is_domain_tlb_coherent(domain) &&                          \
+           cpd_is_domain_cache_coherent(domain))
+#define cpd_is_domain_tlb_coherent(domain)                                \
+          !domain_active(domain_tlb_coherence, (domain))
+#define cpd_is_domain_cache_coherent(domain)                              \
+          (cpd_is_domain_dcache_coherent(domain) &&                       \
+           cpd_is_domain_icache_coherent(domain))
+#define cpd_is_domain_dcache_coherent(domain)                             \
+          !domain_active(domain_dcache_coherence, (domain))
+#define cpd_is_domain_icache_coherent(domain)                             \
+          !domain_active(domain_icache_coherence, (domain))
+
+#define cpd_is_mm_coherent(mm_p)                                          \
+          (cpd_is_mm_tlb_coherent(mm_p) && cpd_is_mm_cache_coherent(mm_p))
+#define cpd_is_mm_tlb_coherent(mm_p)                                      \
+          (!((mm_p)->context.dacr & domain_tlb_coherence &                \
+             SYSTEM_DOMAINS_MASK))
+#define cpd_is_mm_cache_coherent(mm_p)                                    \
+          (cpd_is_mm_dcache_coherent((mm_p)) &&                           \
+           cpd_is_mm_icache_coherent((mm_p)))
+#define cpd_is_mm_dcache_coherent(mm_p)                                   \
+          (!((mm_p)->context.dacr & domain_dcache_coherence &             \
+             SYSTEM_DOMAINS_MASK))
+#define cpd_is_mm_icache_coherent(mm_p)                                   \
+          (!((mm_p)->context.dacr & domain_icache_coherence &             \
+             SYSTEM_DOMAINS_MASK))
+
+#endif
+
+#if CLOCK_RECYCLE
+
+#define cpd_domain_touched(domain)                                        \
+          (domain_active(domain_touched, (domain)))
+#define cpd_set_domain_touched(domain)                                    \
+          (domain_touched |= domain_val((domain), DOMAIN_CLIENT))
+
+#define cpd_clear_domain_touched(domain)                                  \
+          (domain_touched &= ~(domain_val((domain), DOMAIN_MANAGER)))
+
+#endif
+
+/* Clean the TLBs/Caches */
+
+#define cpd_tlb_clean() \
+do {								\
+/*printk("** cpd_tlb_clean() **\n");*/				\
+	cpu_tlb_invalidate_all();				\
+	set_dacr(current->thread.dacr); /* To keep track of dirty domains */\
+	domain_clock++;                 /* as above */\
+	domain_tlb_coherence = 0;\
+} while (0)
+
+#define cpd_cache_clean() \
+do { \
+	/*printk("** cpd_cache_clean() **\n");*/		\
+	cpu_cache_clean_invalidate_all();			\
+	set_dacr(current->thread.dacr); /* To keep track of dirty domains */ \
+	domain_clock++;                 /* as above */\
+	domain_dcache_coherence = 0;\
+	domain_icache_coherence = 0;\
+} while (0)
+
+#define cpd_dcache_clean() \
+do {								\
+	cpu_dcache_clean_invalidate_all();			\
+	set_dacr(current->thread.dacr); /* To keep track of dirty domains */\
+	domain_clock++;                 /* as above */\
+	domain_dcache_coherence = 0;\
+} while(0)
+
+/***********
+* Typedefs *
+***********/
+
+struct domain_struct; /* Dummy prototype */
+
+/* Region context */
+struct region_struct {
+	int mm_count;                   /* Number of address-spaces using region */
+	struct domain_struct* domain_p; /* Domain this region is tagged with */
+	struct region_struct* next;     /* Next region using this domain */
+};
+
+/* Domain context */
+struct domain_struct {
+	unsigned int number;            /* Domain number */
+	unsigned int cpd_count;         /* CPD entries associated with this domain */
+	struct cpd_struct* cpd_head;    /* List of CPD entries with this domain */
+	struct region_struct* region_p; /* Region that owns this domain currently */
+};
+
+/* CPD information
+ * Notes:
+ *   - Number of collisions can be maintained in cpd_load.
+ *   - Number of mm_struct's using this cpd entry, don't know how to calculate.
+ */
+struct cpd_struct {
+	unsigned int collisions;     /* Number collisions on this entry */
+	unsigned int mm_count;       /* Number of mm_struct's using this cpd entry */
+	struct cpd_struct* cpd_next; /* Next CPD entry with the same domain */
+	struct cpd_struct* cpd_prev; /* Previous CPD entry with the same domain */
+};
+
+/**********
+* Externs *
+**********/
+
+extern struct domain_struct domains[DOMAIN_MAX];
+extern struct cpd_struct cpd_stats[USER_PTRS_PER_PGD];
+
+/*******************
+* Inline Functions *
+*******************/
+
+
+static inline void
+cpd_stats_add(struct domain_struct* domain_p, struct cpd_struct* cpd_stats_p)
+{
+	fassert(domain_p);
+	fassert(cpd_stats_p);
+	//printk("** cpd_stats_add: cpd_struct_p 0x%x **\n", (unsigned int)cpd_stats_p);
+	//dump_cpd_stats(domain_p->number);
+	fassert(cpd_stats_p != domain_p->cpd_head);
+
+	cpd_stats_p->cpd_next = domain_p->cpd_head;
+	cpd_stats_p->cpd_prev = NULL;
+
+	if (domain_p->cpd_head) {
+		domain_p->cpd_head->cpd_prev = cpd_stats_p;
+	}
+	domain_p->cpd_head = cpd_stats_p;
+
+	//dump_cpd_stats(domain_p->number);
+
+}
+
+/* cpd_stats_del: Simply removes the cpd_stat from the domain_p's list */
+static inline void
+cpd_stats_del(int domain, struct cpd_struct* cpd_stats_p)
+{
+	fassert(cpd_stats_p);
+	//printk("** cpd_stats_del: cpd_struct_p 0x%x prev 0x%x next 0x%x **\n",
+	//	 (unsigned int)cpd_stats_p, (unsigned int)cpd_stats_p->cpd_prev,
+	//	 (unsigned int)cpd_stats_p->cpd_next);
+
+	if (domains[domain].cpd_head == cpd_stats_p) {
+		domains[domain].cpd_head = cpd_stats_p->cpd_next;
+	}
+
+	/* De-link from list */
+	if (cpd_stats_p->cpd_prev) {
+		cpd_stats_p->cpd_prev->cpd_next = cpd_stats_p->cpd_next;
+	}
+
+	if (cpd_stats_p->cpd_next) {
+		cpd_stats_p->cpd_next->cpd_prev = cpd_stats_p->cpd_prev;
+	}
+
+} /* cpd_stats_del() */
+
+/***********************
+* Function Prototypes *
+***********************/
+
+struct mm_struct;
+void cpd_switch_mm(struct mm_struct* mm_p);
+
+/* CPD Manipulation */
+void cpd_load(pmd_t pmd, unsigned long mv_addr);
+
+/* Region Manipulation */
+struct region_struct* cpd_allocate_region(void);
+void cpd_deallocate_region(struct region_struct* region_p);
+
+/* Domain Manipulation */
+int cpd_get_active_domain(struct mm_struct* mm_p, unsigned int v_addr);
+struct domain_struct* cpd_get_domain(struct mm_struct* mm_p,
+				     unsigned int v_addr);
+struct domain_struct* cpd_allocate_domain(struct region_struct* region_p);
+void cpd_deallocate_domain(struct domain_struct* domain_p);
+
+/* mmap address allocation */
+
+inline unsigned long cpd_next_area(unsigned long given_addr);
+unsigned long cpd_get_shared_area(struct file *file_p, unsigned long addr,
+				  unsigned long len, unsigned long pgoff,
+				  unsigned long flags);
+unsigned long cpd_get_unique_area(struct file *file_p, unsigned long addr,
+				  unsigned long len, unsigned long pgoff,
+				  unsigned long flags);
+unsigned long cpd_get_private_area(struct file *file_p, unsigned long addr,
+				   unsigned long len, unsigned long pgoff,
+				   unsigned long flags);
+unsigned long cpd_get_alloced_area(struct file *file_p, unsigned long addr,
+				   unsigned long len, unsigned long pgoff,
+				   unsigned long flags);
+
+/* TLB/CPD/PageTable Coherence */
+void cpd_set_pmd(pmd_t* pmd_p, pmd_t pmd);
+
+void cpd_tlb_flush_all(void);
+void cpd_tlb_flush_mm(struct mm_struct* mm_p);
+void cpd_tlb_flush_range(struct mm_struct* mm_p,
+                        unsigned long va_start, unsigned long va_end);
+void cpd_tlb_flush_page(struct vm_area_struct* vma_p, unsigned long va_page);
+
+/* Cache Coherence */
+void cpd_cache_flush_all(void);
+void cpd_cache_flush_mm(struct mm_struct* mm_p);
+void cpd_cache_flush_range(struct mm_struct* mm_p,
+                           unsigned long va_start, unsigned long va_end);
+void cpd_cache_flush_page(struct vm_area_struct* vma_p, unsigned long va_page);
+
+
+#endif /* CONFIG_ARM_FASS */
+#endif /* !__ASM_PROC_CPD_H */
diff -urN linux-2.4.29/include/asm-arm/proc-armv/domain.h linux-2.4.29-uc1/include/asm-arm/proc-armv/domain.h
--- linux-2.4.29/include/asm-arm/proc-armv/domain.h	2000-09-18 23:15:24.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/proc-armv/domain.h	2005-06-14 02:11:24.000000000 +0100
@@ -3,6 +3,9 @@
  *
  *  Copyright (C) 1999 Russell King.
  *
+ *  20-Jun-2001        Modified by Adam Wiggins <awiggins@cse.unsw.edu.au>
+ *                     for FASS.
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
@@ -16,12 +19,39 @@
  *  DOMAIN_IO     - domain 2 includes all IO only
  *  DOMAIN_KERNEL - domain 1 includes all kernel memory only
  *  DOMAIN_USER   - domain 0 includes all user memory only
+ *
+ * FASS Changes
+ * 
+ *  To support debugging the zero domain is unallocated and domains 3-15 are
+ *  used for the USER while 1,2 are used by the KERNEL. Really only 0 should be
+ *  used by the KERNEL and 1-15 by USER.
  */
 #define DOMAIN_USER	0
 #define DOMAIN_KERNEL	1
 #define DOMAIN_TABLE	1
 #define DOMAIN_IO	2
 
+#ifdef CONFIG_ARM_FASS
+#define DOMAIN_MAX      16
+#define DOMAIN_END      (DOMAIN_MAX - 1)
+#define DOMAIN_START    3
+
+#define DOMAIN_USER_MASK (domain_val(DOMAIN_IO, DOMAIN_MANAGER) |              \
+                          domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) |          \
+                          domain_val(DOMAIN_USER, DOMAIN_NOACCESS))
+
+/* [JNZ] The following is Adam's original definition:
+#define SYSTEM_DOMAINS_MASK (~(domain_val(DOMAIN_USER, DOMAIN_MANAGER) &&      \
+                               domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) &&    \
+                               domain_val(DOMAIN_IO, DOMAIN_MANAGER)))
+*/
+#define SYSTEM_DOMAINS_MASK (~(domain_val(DOMAIN_USER, DOMAIN_MANAGER) |      \
+                               domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) |    \
+                               domain_val(DOMAIN_IO, DOMAIN_MANAGER)))
+
+#endif /* CONFIG_ARM_FASS */
+
+
 /*
  * Domain types
  */
@@ -29,6 +59,95 @@
 #define DOMAIN_CLIENT	1
 #define DOMAIN_MANAGER	3
 
+#ifdef CONFIG_ARM_FASS
+/*
+ * Domain dirty indicators
+ */
+#define DIRTY 0xFFFFFFFF
+#define CLEAN 0x00000000
+
+extern unsigned long domain_tlb_coherence;
+extern unsigned long domain_dcache_coherence;
+extern unsigned long domain_icache_coherence;
+extern unsigned long domain_touched; /* Used by domain recycling clock algo */
+
+#define domain_val(dom,type)	((type) << 2*(dom))
+
+/* Sets the CPU's Domain Access Control Register DACR */
+static inline void
+set_dacr(unsigned long dacr)
+{
+  domain_tlb_coherence |= dacr;
+  domain_dcache_coherence |= dacr;
+  domain_icache_coherence |= dacr;        
+
+  //printk("** set_dacr: dacr 0x%x **\n", dacr);
+
+  __asm__ __volatile__(
+  "mcr	p15, 0, %0, c3, c0	@ set cpu dacr"
+  : : "r" (dacr));
+
+} /* set_dacr() */
+
+/* Returns the state of the CPU's DACR */
+static inline unsigned long
+get_dacr(void)
+{
+  unsigned long dacr;
+
+  __asm__ __volatile__(
+  "mrc	p15, 0, %0, c3, c0	@ Get domain"
+  : "=&r" (dacr) : );
+
+  return dacr;
+
+} /* get_dacr() */
+
+/* This macro updates the threads DACR context from task_p's mm context */
+
+#if CLOCK_RECYCLE
+
+#define update_dacr(domain)                                                    \
+do{                                                                            \
+  unsigned long dacr;                                                           \
+                                                                               \
+  current->mm->context.dacr |= domain_val(domain, DOMAIN_CLIENT); /* Added */  \
+  dacr = current->thread.dacr | current->mm->context.dacr;                     \
+  domain_touched |= dacr;                                                      \
+  set_dacr(dacr);                                                              \
+} while(0)
+
+#else
+
+#define update_dacr(domain)                                                    \
+do{                                                                            \
+  unsigned long dacr;                                                           \
+                                                                               \
+  current->mm->context.dacr |= domain_val(domain, DOMAIN_CLIENT); /* Added */  \
+  dacr = current->thread.dacr | current->mm->context.dacr;                     \
+  set_dacr(dacr);                                                              \
+} while(0)
+
+
+#endif
+
+/* Return the domain of page middle diretory (really page directory) entry */
+#define pmd_domain(pmd) ((pmd_val(pmd) >> 5) & (DOMAIN_MAX - 1))
+
+/* Tests if a domain is active in the given DACR */
+#define domain_active(dacr, domain) (((dacr) >> (2*(domain))) & DOMAIN_MANAGER)
+
+#define modify_domain(dom,type)				\
+	do {						\
+	unsigned long dacr = current->thread.dacr;	\
+	dacr &= ~domain_val(dom, DOMAIN_MANAGER);	\
+	dacr |= domain_val(dom, type);			\
+	current->thread.dacr = dacr;			\
+	set_dacr(dacr);          			\
+	} while (0)
+
+#else
+
 #define domain_val(dom,type)	((type) << 2*(dom))
 
 #define set_domain(x)					\
@@ -47,4 +166,6 @@
 	set_domain(current->thread.domain);		\
 	} while (0)
 
-#endif
+#endif /* CONFIG_ARM_FASS */
+
+#endif /* !__ASM_PROC_DOMAIN_H */
diff -urN linux-2.4.29/include/asm-arm/proc-armv/pgtable.h linux-2.4.29-uc1/include/asm-arm/proc-armv/pgtable.h
--- linux-2.4.29/include/asm-arm/proc-armv/pgtable.h	2001-08-12 19:14:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/proc-armv/pgtable.h	2005-06-14 02:11:24.000000000 +0100
@@ -11,13 +11,11 @@
  *			now possible to combine ARM6, ARM7 and StrongARM versions.
  *  17-Apr-1999	RMK	Now pass an area size to clean_cache_area and
  *			flush_icache_area.
+ *  03-Oct-2003 JNZ     Modified for FASS, based on Adam Wiggin's patches
  */
 #ifndef __ASM_PROC_PGTABLE_H
 #define __ASM_PROC_PGTABLE_H
 
-#include <asm/proc/domain.h>
-#include <asm/arch/vmalloc.h>
-
 /*
  * entries per page directory level: they are two-level, so
  * we don't really have any PMD directory.
@@ -26,27 +24,97 @@
 #define PTRS_PER_PMD		1
 #define PTRS_PER_PGD		4096
 
-/****************
-* PMD functions *
-****************/
-
-/* PMD types (actually level 1 descriptor) */
-#define PMD_TYPE_MASK		0x0003
-#define PMD_TYPE_FAULT		0x0000
-#define PMD_TYPE_TABLE		0x0001
-#define PMD_TYPE_SECT		0x0002
-#define PMD_UPDATABLE		0x0010
-#define PMD_SECT_CACHEABLE	0x0008
-#define PMD_SECT_BUFFERABLE	0x0004
-#define PMD_SECT_AP_WRITE	0x0400
-#define PMD_SECT_AP_READ	0x0800
+/*
+ * Hardware page table definitions.
+ *
+ * + Level 1 descriptor (PMD)
+ *   - common
+ */
+#define PMD_TYPE_MASK		(3 << 0)
+#define PMD_TYPE_FAULT		(0 << 0)
+#define PMD_TYPE_TABLE		(1 << 0)
+#define PMD_TYPE_SECT		(2 << 0)
+#define PMD_UPDATABLE		(1 << 4)
 #define PMD_DOMAIN(x)		((x) << 5)
+#define PMD_PROTECTION		(1 << 9)	/* v5 */
+/*
+ *   - section
+ */
+#define PMD_SECT_BUFFERABLE	(1 << 2)
+#define PMD_SECT_CACHEABLE	(1 << 3)
+#define PMD_SECT_AP_WRITE	(1 << 10)
+#define PMD_SECT_AP_READ	(1 << 11)
+#define PMD_SECT_TEX(x)		((x) << 12)	/* v5 */
+/*
+ *   - coarse table
+ */
+
+/*
+ * + Level 2 descriptor (PTE)
+ *   - common
+ */
+#define PTE_TYPE_MASK		(3 << 0)
+#define PTE_TYPE_FAULT		(0 << 0)
+#define PTE_TYPE_LARGE		(1 << 0)
+#define PTE_TYPE_SMALL		(2 << 0)
+#define PTE_TYPE_EXT		(3 << 0)	/* v5 */
+#define PTE_BUFFERABLE		(1 << 2)
+#define PTE_CACHEABLE		(1 << 3)
+
+/*
+ *   - extended small page/tiny page
+ */
+#define PTE_EXT_AP_UNO_SRO	(0 << 4)
+#define PTE_EXT_AP_UNO_SRW	(1 << 4)
+#define PTE_EXT_AP_URO_SRW	(2 << 4)
+#define PTE_EXT_AP_URW_SRW	(3 << 4)
+#define PTE_EXT_TEX(x)		((x) << 6)	/* v5 */
+
+/*
+ *   - small page
+ */
+#define PTE_SMALL_AP_UNO_SRO	(0x00 << 4)
+#define PTE_SMALL_AP_UNO_SRW	(0x55 << 4)
+#define PTE_SMALL_AP_URO_SRW	(0xaa << 4)
+#define PTE_SMALL_AP_URW_SRW	(0xff << 4)
+#define PTE_AP_READ		PTE_SMALL_AP_URO_SRW
+#define PTE_AP_WRITE		PTE_SMALL_AP_UNO_SRW
+
+/*
+ * "Linux" PTE definitions.
+ *
+ * We keep two sets of PTEs - the hardware and the linux version.
+ * This allows greater flexibility in the way we map the Linux bits
+ * onto the hardware tables, and allows us to have YOUNG and DIRTY
+ * bits.
+ *
+ * The PTE table pointer refers to the hardware entries; the "Linux"
+ * entries are stored 1024 bytes below.
+ */
+#define L_PTE_PRESENT		(1 << 0)
+#define L_PTE_YOUNG		(1 << 1)
+#define L_PTE_BUFFERABLE	(1 << 2)	/* matches PTE */
+#define L_PTE_CACHEABLE		(1 << 3)	/* matches PTE */
+#define L_PTE_USER		(1 << 4)
+#define L_PTE_WRITE		(1 << 5)
+#define L_PTE_EXEC		(1 << 6)
+#define L_PTE_DIRTY		(1 << 7)
+
+#ifndef __ASSEMBLY__
+
+#include <asm/proc/cpd.h>
+#include <asm/proc/domain.h>
+#include <asm/arch/vmalloc.h>
 
 #define _PAGE_USER_TABLE	(PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_USER))
 #define _PAGE_KERNEL_TABLE	(PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_KERNEL))
 
 #define pmd_bad(pmd)		(pmd_val(pmd) & 2)
-#define set_pmd(pmdp,pmd)	cpu_set_pmd(pmdp,pmd)
+#ifdef CONFIG_ARM_FASS
+#define set_pmd(pmdp,pmd)	cpd_set_pmd(pmdp, pmd)
+#else
+#define set_pmd(pmdp,pmd)	cpu_set_pmd(pmdp, pmd)
+#endif
 
 static inline pmd_t __mk_pmd(pte_t *ptep, unsigned long prot)
 {
@@ -75,49 +143,8 @@
 	return __phys_to_virt(ptr);
 }
 
-/****************
-* PTE functions *
-****************/
-
-/* PTE types (actually level 2 descriptor) */
-#define PTE_TYPE_MASK		0x0003
-#define PTE_TYPE_FAULT		0x0000
-#define PTE_TYPE_LARGE		0x0001
-#define PTE_TYPE_SMALL		0x0002
-#define PTE_AP_READ		0x0aa0
-#define PTE_AP_WRITE		0x0550
-#define PTE_CACHEABLE		0x0008
-#define PTE_BUFFERABLE		0x0004
-
 #define set_pte(ptep, pte)	cpu_set_pte(ptep,pte)
 
-/* We now keep two sets of ptes - the physical and the linux version.
- * This gives us many advantages, and allows us greater flexibility.
- *
- * The Linux pte's contain:
- *  bit   meaning
- *   0    page present
- *   1    young
- *   2    bufferable	- matches physical pte
- *   3    cacheable	- matches physical pte
- *   4    user
- *   5    write
- *   6    execute
- *   7    dirty
- *  8-11  unused
- *  12-31 virtual page address
- *
- * These are stored at the pte pointer; the physical PTE is at -1024bytes
- */
-#define L_PTE_PRESENT		(1 << 0)
-#define L_PTE_YOUNG		(1 << 1)
-#define L_PTE_BUFFERABLE	(1 << 2)
-#define L_PTE_CACHEABLE		(1 << 3)
-#define L_PTE_USER		(1 << 4)
-#define L_PTE_WRITE		(1 << 5)
-#define L_PTE_EXEC		(1 << 6)
-#define L_PTE_DIRTY		(1 << 7)
-
 /*
  * The following macros handle the cache and bufferable bits...
  */
@@ -163,4 +190,6 @@
  */
 #define pgprot_noncached(prot)	__pgprot(pgprot_val(prot) & ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE))
 
+#endif /* __ASSEMBLY__ */
+
 #endif /* __ASM_PROC_PGTABLE_H */
diff -urN linux-2.4.29/include/asm-arm/proc-armv/pid.h linux-2.4.29-uc1/include/asm-arm/proc-armv/pid.h
--- linux-2.4.29/include/asm-arm/proc-armv/pid.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/proc-armv/pid.h	2005-06-14 02:11:24.000000000 +0100
@@ -0,0 +1,145 @@
+/*
+* Filename:    include/asm-arm/proc-armv/pid.h                                 
+* Description: ARM Porcess ID (PID) includes for Fast Address Space Switching
+*              (FASS) in ARM Linux.
+* Created:     14/10/2001
+* Changes:     19/02/2002 - Macros added.
+* Copyright:   (C) 2001, 2002 Adam Wiggins <awiggins@cse.unsw.edu.au>
+********************************************************************************
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of teh GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*******************************************************************************/
+
+#ifndef __ASM_PROC_PID_H
+#define __ASM_PROC_PID_H
+#ifdef CONFIG_ARM_FASS
+
+#include <asm/proc/cpd.h>
+
+/**********
+* Defines *
+**********/
+
+#define ARMPID_SHIFT 25
+
+/* PID to be allocated first */
+#define ARMPID_START 1
+
+/* Only 64 relocation spots on the StrongARM, see notes in arch/arm/mm/pid.c */
+/* (Have more on xscale, need to parameterise this) */
+#define ARMPID_MAX (1U << 6)
+
+/* Size of PID relocation area */
+#define ARMPID_TASK_SIZE (1UL << ARMPID_SHIFT)
+
+/* Start of dummy vm_area to seperate bss and stack */
+#define ARMPID_BRK_LIMIT (ARMPID_TASK_SIZE - MEGABYTE(1)) /* 31MB */
+
+/* Number of CPD entries in the ARM PID relocation area */
+#define ARMPID_PTRS_PER_PGD (ARMPID_TASK_SIZE / PGDIR_SIZE)
+
+/* Mask to get rid of PID from relocated address */
+#define ARMPID_MASK (ARMPID_TASK_SIZE - 1)
+
+
+/* Convert PID number ot address space location */
+#define PIDNUM_TO_PID(pid_num) ((pid_num) << ARMPID_SHIFT)
+
+/* And back again */
+#define PID_TO_PIDNUM(pid) ((pid) >> ARMPID_SHIFT)
+
+/* Gets the ARM PID register value from a Modified Virtual Address (MVA) */
+#define MVA_TO_PID(mva) ((mva) & ~ARMPID_MASK)
+#define MVA_TO_PIDNUM(mva) (PID_TO_PIDNUM(MVA_TO_PID(mva)))
+#define MVA_TO_VA(mva) (mva & ARMPID_MASK)
+#define VA_TO_MVA(va) (va | get_armpid())
+
+/* Find out the CPD index offset due to ARM PID relocation */
+#define ARMPID_CPD_OFFSET(pid) ((pid) >> PGDIR_SHIFT)
+
+
+/* PID context */
+struct pid_struct {
+	unsigned int number;   /* ARM PID number */
+	unsigned int mm_count; /* Number of address-spaces using this ARM PID */
+};
+
+/**********
+* Externs *
+**********/
+
+extern struct pid_struct pids[ARMPID_MAX];
+
+/*******************
+* Inline Functions *
+*******************/
+
+/* Sets the CPU's PID Register */
+static inline void
+set_armpid(unsigned int pid)
+{
+	__asm__ __volatile__(
+		"mcr	p15, 0, %0, c13, c0, 0	@ set cpu dacr"
+		: : "r" (pid));
+
+} /* set_armpid() */
+
+/* Returns the state of the CPU's PID Register */
+static inline int
+get_armpid(void)
+{
+	int pid;
+
+	__asm__ __volatile__(
+		"mrc	p15, 0, %0, c13, c0, 0	@ Get ARM PID"
+		: "=&r" (pid) : );
+
+	return (pid & (~ARMPID_MASK));
+
+} /* get_armpid() */
+
+static inline unsigned long
+mva_to_va(unsigned long mva, struct mm_struct* mm_p)
+{
+	//printk("** mva_to_va: mm_p 0x%x mm_p->ctx.pid 0x%x CPU PID 0x%x **\n",
+	//	 mm_p, mm_p->context.pid, get_armpid());
+	//printk("** mva_to_va: pid_num %d mva 0x%x **\n",
+	//	 PID_TO_PIDNUM(mm_p->context.pid), mva);
+
+	if (get_armpid() && (get_armpid() == MVA_TO_PID(mva))) {
+		//printk("** mva_to_va: represents va 0x%x **\n", MVA_TO_VA(mva));
+
+		return MVA_TO_VA(mva);
+	}
+
+	return mva;
+
+} /* mva_to_va() */
+
+static inline unsigned long
+va_to_mva(unsigned long va, struct mm_struct* mm_p)
+{
+	//printk("** va_to_mva: mm_p 0x%x mm_p->ctx.pid 0x%x CPU PID 0x%x **\n",
+	//	 mm_p, mm_p->context.pid, get_armpid());
+	//printk("** va_to_mva: pid_num %d va 0x%x **\n",
+	//	 PID_TO_PIDNUM(mm_p->context.pid), va);
+
+	if (va < ARMPID_TASK_SIZE) {
+		//printk("** va_to_mva: relocated to mva 0x%x **\n", VA_TO_MVA(va));
+
+		return VA_TO_MVA(va);
+	}
+
+	return va;
+
+} /* va_to_mva() */
+
+
+/* PID Manipulation */
+void arm_pid_allocate(struct task_struct* task_p, struct mm_struct* mm_p);
+void arm_pid_unallocate(struct pid_struct* pid_p);
+
+
+#endif /* CONFIG_ARM_FASS */
+#endif /* !__ASM_PROC_PID_H */
diff -urN linux-2.4.29/include/asm-arm/proc-armv/processor.h linux-2.4.29-uc1/include/asm-arm/proc-armv/processor.h
--- linux-2.4.29/include/asm-arm/proc-armv/processor.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/proc-armv/processor.h	2005-06-14 02:11:24.000000000 +0100
@@ -14,6 +14,7 @@
  *   09-09-1998	PJB	Delete redundant `wp_works_ok'
  *   30-05-1999	PJB	Save sl across context switches
  *   31-07-1999	RMK	Added 'domain' stuff
+ *   09-10-2001 AGW     Renamed thread.domain to thread.dacr to avoid confusion
  */
 #ifndef __ASM_PROC_PROCESSOR_H
 #define __ASM_PROC_PROCESSOR_H
@@ -23,6 +24,9 @@
 #define KERNEL_STACK_SIZE	PAGE_SIZE
 
 struct context_save_struct {
+#ifdef CONFIG_CPU_XSCALE
+	long long acc0;
+#endif
 	unsigned long cpsr;
 	unsigned long r4;
 	unsigned long r5;
@@ -35,16 +39,35 @@
 	unsigned long pc;
 };
 
+#ifdef CONFIG_CPU_XSCALE
+#define INIT_CSS (struct context_save_struct){ 0, SVC_MODE, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+#else
 #define INIT_CSS (struct context_save_struct){ SVC_MODE, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+#endif
+
+#ifdef CONFIG_ARM_FASS
+
+#define EXTRA_THREAD_STRUCT						\
+	unsigned long	dacr;
+
+#define EXTRA_THREAD_STRUCT_INIT					\
+	dacr:	  domain_val(DOMAIN_USER, DOMAIN_CLIENT) |		\
+		  domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) |		\
+		  domain_val(DOMAIN_IO, DOMAIN_CLIENT)
+
+#else
 
 #define EXTRA_THREAD_STRUCT						\
-	unsigned int	domain;
+	unsigned long	domain;
 
 #define EXTRA_THREAD_STRUCT_INIT					\
 	domain:	  domain_val(DOMAIN_USER, DOMAIN_CLIENT) |		\
 		  domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) |		\
 		  domain_val(DOMAIN_IO, DOMAIN_CLIENT)
 
+#endif /* CONFIG_ARM_FASS */
+
+
 #define start_thread(regs,pc,sp)					\
 ({									\
 	unsigned long *stack = (unsigned long *)sp;			\
diff -urN linux-2.4.29/include/asm-arm/proc-armv/ptrace.h linux-2.4.29-uc1/include/asm-arm/proc-armv/ptrace.h
--- linux-2.4.29/include/asm-arm/proc-armv/ptrace.h	2000-11-28 01:07:59.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-arm/proc-armv/ptrace.h	2005-06-14 02:11:24.000000000 +0100
@@ -33,6 +33,16 @@
 #define CC_N_BIT	(1 << 31)
 #define PCMASK		0
 
+/* 2.5 versions */
+#define PSR_T_BIT	0x00000020
+#define PSR_F_BIT	0x00000040
+#define PSR_I_BIT	0x00000080
+#define PSR_J_BIT	0x01000000
+#define PSR_V_BIT	0x10000000
+#define PSR_C_BIT	0x20000000
+#define PSR_Z_BIT	0x40000000
+#define PSR_N_BIT	0x80000000
+
 #ifndef __ASSEMBLY__
 
 /* this struct defines the way the registers are stored on the
diff -urN linux-2.4.29/include/asm-arm/proc-armv/uaccess.h linux-2.4.29-uc1/include/asm-arm/proc-armv/uaccess.h
--- linux-2.4.29/include/asm-arm/proc-armv/uaccess.h	2001-10-25 21:53:55.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/proc-armv/uaccess.h	2005-06-14 02:11:24.000000000 +0100
@@ -54,6 +54,7 @@
 	: "=r" (err)						\
 	: "r" (x), "r" (addr), "i" (-EFAULT), "0" (err))
 
+#ifndef __ARMEB__
 #define __put_user_asm_half(x,addr,err)				\
 ({								\
 	unsigned long __temp = (unsigned long)(x);		\
@@ -61,6 +62,14 @@
 	__put_user_asm_byte(__temp, __ptr, err);		\
 	__put_user_asm_byte(__temp >> 8, __ptr + 1, err);	\
 })
+#else
+#define __put_user_asm_half(x,addr,err)				\
+({								\
+	unsigned long __temp = (unsigned long)(x);		\
+	__put_user_asm_byte(__temp >> 8, addr, err);			\
+	__put_user_asm_byte(__temp, (int)(addr) + 1, err);	\
+})
+#endif
 
 #define __put_user_asm_word(x,addr,err)				\
 	__asm__ __volatile__(					\
@@ -95,6 +104,7 @@
 	: "=r" (err), "=&r" (x)					\
 	: "r" (addr), "i" (-EFAULT), "0" (err))
 
+#ifndef __ARMEB__
 #define __get_user_asm_half(x,addr,err)				\
 ({								\
 	unsigned long __b1, __b2, __ptr = (unsigned long)addr;	\
@@ -102,7 +112,15 @@
 	__get_user_asm_byte(__b2, __ptr + 1, err);		\
 	(x) = __b1 | (__b2 << 8);				\
 })
-
+#else
+#define __get_user_asm_half(x,addr,err)				\
+({								\
+	unsigned long __b1, __b2;				\
+	__get_user_asm_byte(__b1, addr, err);			\
+	__get_user_asm_byte(__b2, (int)(addr) + 1, err);	\
+	(x) = (__b1 << 8) | __b2;				\
+})
+#endif
 
 #define __get_user_asm_word(x,addr,err)				\
 	__asm__ __volatile__(					\
diff -urN linux-2.4.29/include/asm-arm/processor.h linux-2.4.29-uc1/include/asm-arm/processor.h
--- linux-2.4.29/include/asm-arm/processor.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/processor.h	2005-06-14 02:11:22.000000000 +0100
@@ -23,12 +23,26 @@
 	unsigned int save[FP_SIZE];		/* as yet undefined */
 };
 
+#ifdef CONFIG_EP93XX_CRUNCH
+struct fp_crunch_struct {
+	long long regs[16];
+	int acc0[3];
+	int acc1[3];
+	int acc2[3];
+	int acc3[3];
+	unsigned long dspsc;
+};
+#endif
+
 struct fp_soft_struct {
 	unsigned int save[FP_SIZE];		/* undefined information */
 };
 
 union fp_state {
 	struct fp_hard_struct	hard;
+#ifdef CONFIG_EP93XX_CRUNCH
+	struct fp_crunch_struct	crunch;
+#endif
 	struct fp_soft_struct	soft;
 };
 
diff -urN linux-2.4.29/include/asm-arm/proc-fns.h linux-2.4.29-uc1/include/asm-arm/proc-fns.h
--- linux-2.4.29/include/asm-arm/proc-fns.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/proc-fns.h	2005-06-14 02:11:22.000000000 +0100
@@ -100,6 +100,14 @@
 #   define CPU_NAME sa1100
 #  endif
 # endif
+# ifdef CONFIG_CPU_XSCALE
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME xscale
+#  endif
+# endif
 #endif
 
 #ifndef MULTI_CPU
diff -urN linux-2.4.29/include/asm-arm/procinfo.h linux-2.4.29-uc1/include/asm-arm/procinfo.h
--- linux-2.4.29/include/asm-arm/procinfo.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/procinfo.h	2005-06-14 02:11:22.000000000 +0100
@@ -57,5 +57,6 @@
 #define HWCAP_VFP	64
 #define HWCAP_EDSP	128
 #define HWCAP_JAVA	256
+#define HWCAP_CRUNCH	512
 
 #endif
diff -urN linux-2.4.29/include/asm-arm/ptrace.h linux-2.4.29-uc1/include/asm-arm/ptrace.h
--- linux-2.4.29/include/asm-arm/ptrace.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/ptrace.h	2005-06-14 02:11:24.000000000 +0100
@@ -17,6 +17,8 @@
 #define pc_pointer(v) \
 	((v) & ~PCMASK)
 
+#define user_stack(regs) ((regs)->ARM_sp)
+
 #define instruction_pointer(regs) \
 	(pc_pointer((regs)->ARM_pc))
 
diff -urN linux-2.4.29/include/asm-arm/stat.h linux-2.4.29-uc1/include/asm-arm/stat.h
--- linux-2.4.29/include/asm-arm/stat.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/stat.h	2005-06-14 02:11:22.000000000 +0100
@@ -44,8 +44,14 @@
  * in the hope that the kernel has stretched to using larger sizes.
  */
 struct stat64 {
-	unsigned short	st_dev;
-	unsigned char	__pad0[10];
+#if defined(__ARMEB__)
+	unsigned char   __pad0b[6];
+	unsigned short  st_dev;
+#else
+	unsigned short  st_dev;
+	unsigned char   __pad0b[6];
+#endif
+	unsigned char   __pad0[4];
 
 #define STAT64_HAS_BROKEN_ST_INO	1
 	unsigned long	__st_ino;
@@ -55,14 +61,25 @@
 	unsigned long	st_uid;
 	unsigned long	st_gid;
 
-	unsigned short	st_rdev;
-	unsigned char	__pad3[10];
+#if defined(__ARMEB__)
+	unsigned char   __pad3b[6];
+	unsigned short  st_rdev;
+#else /* Must be little */
+	unsigned short  st_rdev;
+	unsigned char   __pad3b[6];
+#endif  
+	unsigned char   __pad3[4];
 
 	long long	st_size;
 	unsigned long	st_blksize;
 
-	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
-	unsigned long	__pad4;		/* future possible st_blocks high bits */
+#if defined(__ARMEB__)
+	unsigned long   __pad4;		/* Future possible st_blocks hi bits */
+	unsigned long   st_blocks;	/* Number 512-byte blocks allocated. */
+#else /* Must be little */
+	unsigned long   st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long   __pad4;		/* Future possible st_blocks hi bits */
+#endif
 
 	unsigned long	st_atime;
 	unsigned long	__pad5;
diff -urN linux-2.4.29/include/asm-arm/system.h linux-2.4.29-uc1/include/asm-arm/system.h
--- linux-2.4.29/include/asm-arm/system.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/system.h	2005-06-14 02:11:22.000000000 +0100
@@ -52,6 +52,21 @@
 
 #define prepare_to_switch()    do { } while(0)
 
+#ifdef CONFIG_EP93XX_CRUNCH
+#include <asm/arch/crunch.h>
+#define crunch_switch(prev, next)			\
+	do {						\
+		if (prev->flags & PF_USEDFPU) {		\
+			save_crunch(prev);		\
+			crunch_disable();		\
+		}					\
+		prev->flags &= ~PF_USEDFPU;		\
+		mb();					\
+	} while (0)
+#else
+#define crunch_switch(prev, next)	do { } while (0);
+#endif
+
 /*
  * switch_to(prev, next) should switch from task `prev' to `next'
  * `prev' will never be the same as `next'.
diff -urN linux-2.4.29/include/asm-arm/uaccess.h linux-2.4.29-uc1/include/asm-arm/uaccess.h
--- linux-2.4.29/include/asm-arm/uaccess.h	2001-10-25 21:53:55.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/uaccess.h	2005-06-14 02:11:24.000000000 +0100
@@ -86,7 +86,7 @@
 			__get_user_x(__r1, __p, __e, 1, "lr");		\
 	       		break;						\
 		case 2:							\
-			__get_user_x(__r1, __p, __e, 2, "r2", "lr");	\
+			__get_user_x(__r1, __p, __e, 2, "ip", "lr");	\
 			break;						\
 		case 4:							\
 	       		__get_user_x(__r1, __p, __e, 4, "lr");		\
@@ -122,13 +122,13 @@
 		register int __e asm("r0");				\
 		switch (sizeof(*(p))) {					\
 		case 1:							\
-			__put_user_x(__r1, __p, __e, 1, "r2", "lr");	\
+			__put_user_x(__r1, __p, __e, 1, "ip", "lr");	\
 			break;						\
 		case 2:							\
-			__put_user_x(__r1, __p, __e, 2, "r2", "lr");	\
+			__put_user_x(__r1, __p, __e, 2, "ip", "lr");	\
 			break;						\
 		case 4:							\
-			__put_user_x(__r1, __p, __e, 4, "r2", "lr");	\
+			__put_user_x(__r1, __p, __e, 4, "ip", "lr");	\
 			break;						\
 		case 8:							\
 			__put_user_x(__r1, __p, __e, 8, "ip", "lr");	\
diff -urN linux-2.4.29/include/asm-arm/unaligned.h linux-2.4.29-uc1/include/asm-arm/unaligned.h
--- linux-2.4.29/include/asm-arm/unaligned.h	2000-08-13 17:54:15.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/unaligned.h	2005-06-14 02:11:24.000000000 +0100
@@ -39,24 +39,30 @@
  * out of long long >> 32, or the low word from long long << 32
  */
 
-#define __get_unaligned_2(__p)					\
+#define __get_unaligned_2_le(__p)					\
 	(__p[0] | __p[1] << 8)
 
-#define __get_unaligned_4(__p)					\
+#define __get_unaligned_2_be(__p)					\
+	(__p[0] << 8 | __p[1])
+
+#define __get_unaligned_4_le(__p)					\
 	(__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24)
 
-#define get_unaligned(ptr)					\
+#define __get_unaligned_4_be(__p)					\
+	(__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3])
+
+#define __get_unaligned_le(ptr)					\
 	({							\
 		__typeof__(*(ptr)) __v;				\
 		__u8 *__p = (__u8 *)(ptr);			\
 		switch (sizeof(*(ptr))) {			\
 		case 1:	__v = *(ptr);			break;	\
-		case 2: __v = __get_unaligned_2(__p);	break;	\
-		case 4: __v = __get_unaligned_4(__p);	break;	\
+		case 2: __v = __get_unaligned_2_le(__p);	break;	\
+		case 4: __v = __get_unaligned_4_le(__p);	break;	\
 		case 8: {					\
 				unsigned int __v1, __v2;	\
-				__v2 = __get_unaligned_4((__p+4)); \
-				__v1 = __get_unaligned_4(__p);	\
+				__v2 = __get_unaligned_4_le((__p+4)); \
+				__v1 = __get_unaligned_4_le(__p);	\
 				__v = ((unsigned long long)__v2 << 32 | __v1);	\
 			}					\
 			break;					\
@@ -65,44 +71,87 @@
 		__v;						\
 	})
 
+#define __get_unaligned_be(ptr)					\
+	({							\
+		__typeof__(*(ptr)) __v;				\
+		__u8 *__p = (__u8 *)(ptr);			\
+		switch (sizeof(*(ptr))) {			\
+		case 1:	__v = *(ptr);			break;	\
+		case 2: __v = __get_unaligned_2_be(__p);	break;	\
+		case 4: __v = __get_unaligned_4_be(__p);	break;	\
+		case 8: {					\
+				unsigned int __v1, __v2;	\
+				__v2 = __get_unaligned_4_be(__p); \
+				__v1 = __get_unaligned_4_be((__p+4));	\
+				__v = ((unsigned long long)__v2 << 32 | __v1);	\
+			}					\
+			break;					\
+		default: __v = __bug_unaligned_x(__p);	break;	\
+		}						\
+		__v;						\
+	})
 
-static inline void __put_unaligned_2(__u32 __v, register __u8 *__p)
+
+static inline void __put_unaligned_2_le(__u32 __v, register __u8 *__p)
 {
 	*__p++ = __v;
 	*__p++ = __v >> 8;
 }
 
-static inline void __put_unaligned_4(__u32 __v, register __u8 *__p)
+static inline void __put_unaligned_2_be(__u32 __v, register __u8 *__p)
+{
+	*__p++ = __v >> 8;
+	*__p++ = __v;
+}
+
+static inline void __put_unaligned_4_le(__u32 __v, register __u8 *__p)
+{
+	__put_unaligned_2_le(__v >> 16, __p + 2);
+	__put_unaligned_2_le(__v, __p);
+}
+
+static inline void __put_unaligned_4_be(__u32 __v, register __u8 *__p)
 {
-	__put_unaligned_2(__v >> 16, __p + 2);
-	__put_unaligned_2(__v, __p);
+	__put_unaligned_2_be(__v >> 16, __p);
+	__put_unaligned_2_be(__v, __p + 2);
 }
 
-static inline void __put_unaligned_8(const unsigned long long __v, register __u8 *__p)
+static inline void __put_unaligned_8_le(const unsigned long long __v, register __u8 *__p)
 {
 	/*
 	 * tradeoff: 8 bytes of stack for all unaligned puts (2
 	 * instructions), or an extra register in the long long
 	 * case - go for the extra register.
 	 */
-	__put_unaligned_4(__v >> 32, __p+4);
-	__put_unaligned_4(__v, __p);
+	__put_unaligned_4_le(__v >> 32, __p+4);
+	__put_unaligned_4_le(__v, __p);
+}
+
+static inline void __put_unaligned_8_be(const unsigned long long __v, register __u8 *__p)
+{
+	/*
+	 * tradeoff: 8 bytes of stack for all unaligned puts (2
+	 * instructions), or an extra register in the long long
+	 * case - go for the extra register.
+	 */
+	__put_unaligned_4_be(__v >> 32, __p);
+	__put_unaligned_4_be(__v, __p+4);
 }
 
 /*
  * Try to store an unaligned value as efficiently as possible.
  */
-#define put_unaligned(val,ptr)					\
+#define __put_unaligned_le(val,ptr)					\
 	({							\
 		switch (sizeof(*(ptr))) {			\
 		case 1:						\
 			*(ptr) = (val);				\
 			break;					\
-		case 2: __put_unaligned_2((val),(__u8 *)(ptr));	\
+		case 2: __put_unaligned_2_le((val),(__u8 *)(ptr));	\
 			break;					\
-		case 4:	__put_unaligned_4((val),(__u8 *)(ptr));	\
+		case 4:	__put_unaligned_4_le((val),(__u8 *)(ptr));	\
 			break;					\
-		case 8:	__put_unaligned_8((val),(__u8 *)(ptr)); \
+		case 8:	__put_unaligned_8_le((val),(__u8 *)(ptr)); \
 			break;					\
 		default: __bug_unaligned_x(ptr);		\
 			break;					\
@@ -110,5 +159,33 @@
 		(void) 0;					\
 	})
 
+#define __put_unaligned_be(val,ptr)					\
+	({							\
+		switch (sizeof(*(ptr))) {			\
+		case 1:						\
+			*(ptr) = (val);				\
+			break;					\
+		case 2: __put_unaligned_2_be((val),(__u8 *)(ptr));	\
+			break;					\
+		case 4:	__put_unaligned_4_be((val),(__u8 *)(ptr));	\
+			break;					\
+		case 8:	__put_unaligned_8_be((val),(__u8 *)(ptr)); \
+			break;					\
+		default: __bug_unaligned_x(ptr);		\
+			break;					\
+		}						\
+		(void) 0;					\
+	})
+
+/*
+ * Select endianness
+ */
+#ifndef __ARMEB__
+#define get_unaligned	__get_unaligned_le
+#define put_unaligned	__put_unaligned_le
+#else
+#define get_unaligned	__get_unaligned_be
+#define put_unaligned	__put_unaligned_be
+#endif
 
 #endif
diff -urN linux-2.4.29/include/asm-arm/unistd.h linux-2.4.29-uc1/include/asm-arm/unistd.h
--- linux-2.4.29/include/asm-arm/unistd.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/unistd.h	2005-06-14 02:11:23.000000000 +0100
@@ -204,8 +204,8 @@
 #define __NR_rt_sigtimedwait		(__NR_SYSCALL_BASE+177)
 #define __NR_rt_sigqueueinfo		(__NR_SYSCALL_BASE+178)
 #define __NR_rt_sigsuspend		(__NR_SYSCALL_BASE+179)
-#define __NR_pread			(__NR_SYSCALL_BASE+180)
-#define __NR_pwrite			(__NR_SYSCALL_BASE+181)
+#define __NR_pread64			(__NR_SYSCALL_BASE+180)
+#define __NR_pwrite64			(__NR_SYSCALL_BASE+181)
 #define __NR_chown			(__NR_SYSCALL_BASE+182)
 #define __NR_getcwd			(__NR_SYSCALL_BASE+183)
 #define __NR_capget			(__NR_SYSCALL_BASE+184)
@@ -250,7 +250,7 @@
 #define __NR_security			(__NR_SYSCALL_BASE+223)
 #define __NR_gettid			(__NR_SYSCALL_BASE+224)
 #define __NR_readahead			(__NR_SYSCALL_BASE+225)
-#if 0 /* allocated in 2.5 */
+#if 0 /* allocated in 2.4 */
 #define __NR_setxattr			(__NR_SYSCALL_BASE+226)
 #define __NR_lsetxattr			(__NR_SYSCALL_BASE+227)
 #define __NR_fsetxattr			(__NR_SYSCALL_BASE+228)
@@ -263,8 +263,8 @@
 #define __NR_removexattr		(__NR_SYSCALL_BASE+235)
 #define __NR_lremovexattr		(__NR_SYSCALL_BASE+236)
 #define __NR_fremovexattr		(__NR_SYSCALL_BASE+237)
-#endif
 #define __NR_tkill			(__NR_SYSCALL_BASE+238)
+#endif
 #if 0 /* allocated in 2.5 */
 #define __NR_sendfile64                 (__NR_SYSCALL_BASE+239)
 #define __NR_futex                      (__NR_SYSCALL_BASE+240)
diff -urN linux-2.4.29/include/asm-arm/xscale-lock.h linux-2.4.29-uc1/include/asm-arm/xscale-lock.h
--- linux-2.4.29/include/asm-arm/xscale-lock.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/xscale-lock.h	2005-06-14 02:11:22.000000000 +0100
@@ -0,0 +1,76 @@
+/*
+ * xscale-lock.h
+ *
+ * Header file for XScale cache and TLB locking API
+ * See Documentation/arm/xscale/cache-lock.txt tlb-lock.txt for API docs
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2000-2001 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _XSCALE_LOCK_H_
+#define _XSCALE_LOCK_H_
+
+#include <linux/types.h>
+
+struct cache_capabilities
+{
+	u32   flags;      /* Flags defining capabilities  */
+	u32   cache_size; /* Cache size in K (1024 bytes) */
+	u32   max_lock;   /* Maximum lockable region in K */
+};
+
+/*
+ * Flags
+ */
+   
+/*
+ * Bit 0: Cache lockability
+ * Bits 1-31: Reserved for future use
+ */
+#define CACHE_LOCKABLE    0x00000001   /* Cache can be locked */
+
+/*
+ * Cache Types
+ */
+#define ICACHE            0x00
+#define DCACHE            0x01
+
+    
+int cache_query(u8, struct cache_capabilities *);
+int cache_lock(void *, u32, u8, const char *);
+int cache_unlock(void *);
+int cache_lock_init(void);
+
+
+/*
+ * TLB Types
+ */
+#define ITLB        0x00
+#define DTLB        0x01
+
+int xscale_tlb_lock(u8, u32);
+int xscale_tlb_unlock(u8, u32);
+
+#endif // _XSCALE_LOCK_H_
diff -urN linux-2.4.29/include/asm-arm/xscale-pmu.h linux-2.4.29-uc1/include/asm-arm/xscale-pmu.h
--- linux-2.4.29/include/asm-arm/xscale-pmu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-arm/xscale-pmu.h	2005-06-14 02:11:23.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ * pmu.h
+ *
+ * This file contains the low level constants needed to access the 
+ * performance monitoring unit on Intel's XScale Microarchitecture
+ * processors.
+ *
+ * For details on how to use the perfmon unit from an application or 
+ * from the kernel, see Documentation/arm/XScale/perfmon.txt
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2000-2001 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _PMU_H_
+#define _PMU_H_
+
+#include <linux/types.h>
+
+/*
+ * Different types of events that can be counted by the XScale PMU
+ */
+
+#define EVT_ICACHE_MISS			0x00
+#define	EVT_ICACHE_NO_DELIVER		0x01
+#define	EVT_DATA_STALL			0x02
+#define	EVT_ITLB_MISS			0x03
+#define	EVT_DTLB_MISS			0x04
+#define	EVT_BRANCH			0x05
+#define	EVT_BRANCH_MISS			0x06
+#define	EVT_INSTRUCTION			0x07
+#define	EVT_DCACHE_FULL_STALL		0x08
+#define	EVT_DCACHE_FULL_STALL_CONTIG	0x09
+#define	EVT_DCACHE_ACCESS		0x0A
+#define	EVT_DCACHE_MISS			0x0B
+#define	EVT_DCACE_WRITE_BACK		0x0C
+#define	EVT_PC_CHANGED			0x0D
+#define	EVT_BCU_REQUEST			0x10
+#define	EVT_BCU_FULL			0x11
+#define	EVT_BCU_DRAIN			0x12
+#define	EVT_BCU_ECC_NO_ELOG		0x14
+#define	EVT_BCU_1_BIT_ERR		0x15
+#define	EVT_RMW				0x16
+
+
+struct pmu_results
+{
+	u32	ccnt_of;
+	u32	ccnt;		/* Clock Counter Register */
+	u32	pmn0_of;
+	u32	pmn0;		/* Performance Counter Register 0 */
+	u32	pmn1_of;
+	u32	pmn1;		/* Performance Counter Register 1 */
+};
+
+extern struct pmu_results results;
+
+int pmu_claim(void);		/* Claim PMU for usage */
+int pmu_start(u32, u32);		/* Start PMU execution */
+int pmu_stop(struct pmu_results *);	/* Stop perfmon unit */
+int pmu_release(int);		/* Release PMU */
+
+#endif _PMU_H_
+
+
diff -urN linux-2.4.29/include/asm-armnommu/a.out.h linux-2.4.29-uc1/include/asm-armnommu/a.out.h
--- linux-2.4.29/include/asm-armnommu/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/a.out.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,38 @@
+#ifndef __ARM_A_OUT_H__
+#define __ARM_A_OUT_H__
+
+#include <asm/types.h>
+
+struct exec
+{
+  __u32 a_info;		/* Use macros N_MAGIC, etc for access */
+  __u32 a_text;		/* length of text, in bytes */
+  __u32 a_data;		/* length of data, in bytes */
+  __u32 a_bss;		/* length of uninitialized data area for file, in bytes */
+  __u32 a_syms;		/* length of symbol table data in file, in bytes */
+  __u32 a_entry;	/* start address */
+  __u32 a_trsize;	/* length of relocation info for text, in bytes */
+  __u32 a_drsize;	/* length of relocation info for data, in bytes */
+};
+
+/*
+ * This is always the same
+ */
+#define N_TXTADDR(a)	(0x00008000)
+
+#define N_TRSIZE(a)	((a).a_trsize)
+#define N_DRSIZE(a)	((a).a_drsize)
+#define N_SYMSIZE(a)	((a).a_syms)
+
+#define M_ARM 103
+
+#ifdef __KERNEL__
+#define STACK_TOP	((current->personality == PER_LINUX_32BIT) ? \
+			 TASK_SIZE : TASK_SIZE_26)
+#endif
+
+#ifndef LIBRARY_START_TEXT
+#define LIBRARY_START_TEXT	(0x00c00000)
+#endif
+
+#endif /* __A_OUT_GNU_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/a.out.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/a.out.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/a.out.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * uclinux/include/asm-armnommu/arch-atmel/a.out.h
+ *
+ */
+#ifndef __ASM_ARCH_A_OUT_H
+#define __ASM_ARCH_A_OUT_H
+
+#ifdef __KERNEL__
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,14 @@
+/*
+ * asm/arch-armnommu/arch-p52/dma.h:
+ * Mindspeed 2001
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+
+#define MAX_DMA_ADDRESS		0x01000000
+#define MAX_DMA_CHANNELS        13
+#define arch_dma_init(dma_chan)
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,364 @@
+/*
+ * linux/include/asm-arm/arch-atmel/hardware.h
+ * for Atmel AT91 series
+ * 2001 Erwin Authried
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/* 0=TC0, 1=TC1, 2=TC2 */
+#define KERNEL_TIMER 1	
+
+#ifdef CONFIG_CPU_AT91X40
+/*
+ ******************* AT91x40xxx ********************
+ */
+
+#define ARM_CLK	CONFIG_ARM_CLK
+
+#define AT91_USART_CNT 2
+#define AT91_USART0_BASE	(0xfffd0000)
+#define AT91_USART1_BASE	(0xfffcc000)
+#define AT91_TC_BASE		(0xfffe0000)
+#define AIC_BASE		(0xfffff000)	
+#define AT91_PIOA_BASE		(0xffff0000)
+#define AT91_SF_CIDR		(0xfff00000)
+
+#define HARD_RESET_NOW()
+
+#define HW_AT91_TIMER_INIT(timer)	/* no PMC */
+
+/* use TC0 as hardware timer to create high resolution timestamps for debugging.
+ *  Timer 0 must be set up as a free running counter, e.g. in the bootloader
+ */
+#define HW_COUNTER  (((struct at91_timers *)AT91_TC_BASE)->chans[0].ch.cv)
+
+/* enable US0,US1 */
+#define HW_AT91_USART_INIT ((volatile struct pio_regs *)AT91_PIOA_BASE)->pdr = \
+				PIOA_RXD0|PIOA_TXD0|PIOA_RXD1|PIOA_TXD1; 
+/* PIOA bit allocation */
+#define PIOA_TCLK0	(1<<0)					
+#define PIOA_TI0A0	(1<<1)					
+#define PIOA_TI0B0	(1<<2)					
+#define PIOA_TCLK1	(1<<3)					
+#define PIOA_TIOA1	(1<<4)				
+#define PIOA_TIOB1	(1<<5)				
+#define PIOA_TCLK2	(1<<6)					
+#define PIOA_TIOA2	(1<<7)				
+#define PIOA_TIOB2	(1<<8)				
+#define PIOA_IRQ0	(1<<9)				
+#define PIOA_IRQ1	(1<<10)				
+#define PIOA_IRQ2	(1<<11)				
+#define PIOA_FIQ	(1<<12)					
+#define PIOA_SCK0	(1<<13)					
+#define PIOA_TXD0	(1<<14)					
+#define PIOA_RXD0	(1<<15)
+
+#define PIOA_SCK1	(1<<20)					
+#define PIOA_TXD1	(1<<21)					
+#define PIOA_RXD1	(1<<22)
+
+#define PIOA_MCK0	(1<<25)	
+#define PIOA_NCS2	(1<<26)
+#define PIOA_NCS3	(1<<27)	
+
+#define PIOA_A20_CS7	(1<<28)
+#define PIOA_A21_CS6	(1<<29)	
+#define PIOA_A22_CS5	(1<<30)
+#define PIOA_A23_CS4	(1<<31)
+
+#elif CONFIG_CPU_AT91X63
+/*
+ ******************* AT91x63xxx ********************
+ */
+
+#define ARM_CLK		CONFIG_ARM_CLK
+
+#define AT91_USART_CNT 2
+#define AT91_USART0_BASE	(0xfffc0000)
+#define AT91_USART1_BASE	(0xfffc4000)
+#define AT91_TC_BASE		(0xfffd0000)
+#define AIC_BASE		(0xfffff000)
+#define AT91_PIOA_BASE 		(0xfffec000)
+#define AT91_PIOB_BASE 		(0xffff0000)
+#define AT91_PMC_BASE		(0xffff4000)
+
+#define HARD_RESET_NOW()
+
+/* enable US0,US1 */
+#define HW_AT91_USART_INIT ((volatile struct pmc_regs *)AT91_PMC_BASE)->pcer = \
+				(1<<2) | (1<<3) | (1<<13); \
+			   ((volatile struct pio_regs *)AT91_PIOA_BASE)->pdr = \
+				PIOA_RXD0|PIOA_TXD0|PIOA_RXD1|PIOA_TXD1; 
+
+#define HW_AT91_TIMER_INIT(timer) ((volatile struct pmc_regs *)AT91_PMC_BASE)->pcer = \
+				1<<(timer+6);
+
+/* PIOA bit allocation */
+#define PIOA_TCLK3	(1<<0)					
+#define PIOA_TI0A3	(1<<1)					
+#define PIOA_TI0B3	(1<<2)					
+#define PIOA_TCLK4	(1<<3)					
+#define PIOA_TI0A4	(1<<4)					
+#define PIOA_TI0B4	(1<<5)					
+#define PIOA_TCLK5	(1<<6)					
+#define PIOA_TI0A5	(1<<7)					
+#define PIOA_TI0B5	(1<<8)					
+#define PIOA_IRQ0	(1<<9)
+#define PIOA_IRQ1	(1<<10)
+#define PIOA_IRQ2	(1<<11)
+#define PIOA_IRQ3	(1<<12)
+#define PIOA_FIQ	(1<<13)
+#define PIOA_SCK0	(1<<14)	
+#define PIOA_TXD0	(1<<15)
+#define PIOA_RXD0	(1<<16)
+#define PIOA_SCK1	(1<<17)	
+#define PIOA_TXD1	(1<<18)
+#define PIOA_RXD1	(1<<19)
+#define PIOA_SCK2	(1<<20)	
+#define PIOA_TXD2	(1<<21)
+#define PIOA_RXD2	(1<<22)
+#define PIOA_SPCK	(1<<23)					
+#define PIOA_MISO	(1<<24)					
+#define PIOA_MOSI	(1<<25)					
+#define PIOA_NPCS0	(1<<26)					
+#define PIOA_NPCS1	(1<<27)					
+#define PIOA_NPCS2	(1<<28)					
+#define PIOA_NPCS3	(1<<29)					
+
+/* PIOB bit allocation */
+#define PIOB_MPI_NOE	(1<<0)					
+#define PIOB_MPI_NLB	(1<<1)				
+#define PIOB_MPI_NUB	(1<<2)				
+
+#define PIOB_MCK0	(1<<17)				
+#define PIOB_BMS	(1<<18)				
+#define PIOB_TCLK0	(1<<19)				
+#define PIOB_TIOA0	(1<<20)				
+#define PIOB_TIOB0	(1<<21)				
+#define PIOB_TCLK1	(1<<22)				
+#define PIOB_TIOA1	(1<<23)				
+#define PIOB_TIOB1	(1<<24)				
+#define PIOB_TCLK2	(1<<25)				
+#define PIOB_TIOA2	(1<<26)				
+#define PIOB_TIOB2	(1<<27)		
+#else 
+  #error "Configuration error: No CPU defined"
+#endif
+
+/*
+ ******************* COMMON PART ********************
+ */
+#define AIC_SMR(i)  (AIC_BASE+i*4)
+#define AIC_IVR	    (AIC_BASE+0x100)
+#define AIC_FVR	    (AIC_BASE+0x104)
+#define AIC_ISR	    (AIC_BASE+0x108)
+#define AIC_IPR	    (AIC_BASE+0x10C)
+#define AIC_IMR	    (AIC_BASE+0x110)
+#define AIC_CISR	(AIC_BASE+0x114)
+#define AIC_IECR	(AIC_BASE+0x120)
+#define AIC_IDCR	(AIC_BASE+0x124)
+#define AIC_ICCR	(AIC_BASE+0x128)
+#define AIC_ISCR	(AIC_BASE+0x12C)
+#define AIC_EOICR   (AIC_BASE+0x130)
+
+
+#ifndef __ASSEMBLER__
+struct at91_timer_channel
+{
+	unsigned long ccr;				// channel control register		(WO)
+	unsigned long cmr;				// channel mode register		(RW)
+	unsigned long reserved[2];		
+	unsigned long cv;				// counter value				(RW)
+	unsigned long ra;				// register A					(RW)
+	unsigned long rb;				// register B					(RW)
+	unsigned long rc;				// register C					(RW)
+	unsigned long sr;				// status register				(RO)
+	unsigned long ier;				// interrupt enable register	(WO)
+	unsigned long idr;				// interrupt disable register	(WO)
+	unsigned long imr;				// interrupt mask register		(RO)
+};
+
+struct at91_timers
+{
+	struct {
+		struct at91_timer_channel ch;
+		unsigned char padding[0x40-sizeof(struct at91_timer_channel)];
+	} chans[3];
+	unsigned  long bcr;				// block control register		(WO)
+	unsigned  long bmr;				// block mode	 register		(RW)
+};
+#endif
+
+/*  TC control register */
+#define TC_SYNC	(1)
+
+/*  TC mode register */
+#define TC2XC2S(x)	(x & 0x3)
+#define TC1XC1S(x)	(x<<2 & 0xc)
+#define TC0XC0S(x)	(x<<4 & 0x30)
+#define TCNXCNS(timer,v) ((v) << (timer<<1))
+
+/* TC channel control */
+#define TC_CLKEN	(1)			
+#define TC_CLKDIS	(1<<1)			
+#define TC_SWTRG	(1<<2)			
+
+/* TC interrupts enable/disable/mask and status registers */
+#define TC_MTIOB	(1<<18)
+#define TC_MTIOA	(1<<17)
+#define TC_CLKSTA	(1<<16)
+
+#define TC_ETRGS	(1<<7)
+#define TC_LDRBS	(1<<6)
+#define TC_LDRAS	(1<<5)
+#define TC_CPCS		(1<<4)
+#define TC_CPBS		(1<<3)
+#define TC_CPAS		(1<<2)
+#define TC_LOVRS	(1<<1)
+#define TC_COVFS	(1)
+
+/*
+ *	USART registers
+ */
+
+
+/*  US control register */
+#define US_SENDA	(1<<12)
+#define US_STTO		(1<<11)
+#define US_STPBRK	(1<<10)
+#define US_STTBRK	(1<<9)
+#define US_RSTSTA	(1<<8)
+#define US_TXDIS	(1<<7)
+#define US_TXEN		(1<<6)
+#define US_RXDIS	(1<<5)
+#define US_RXEN		(1<<4)
+#define US_RSTTX	(1<<3)
+#define US_RSTRX	(1<<2)
+
+/* US mode register */
+#define US_CLK0		(1<<18)
+#define US_MODE9	(1<<17)
+#define US_CHMODE(x)(x<<14 & 0xc000)
+#define US_NBSTOP(x)(x<<12 & 0x3000)
+#define US_PAR(x)	(x<<9 & 0xe00)
+#define US_SYNC		(1<<8)
+#define US_CHRL(x)	(x<<6 & 0xc0)
+#define US_USCLKS(x)(x<<4 & 0x30)
+
+/* US interrupts enable/disable/mask and status register */
+#define US_DMSI		(1<<10)
+#define US_TXEMPTY	(1<<9)
+#define US_TIMEOUT	(1<<8)
+#define US_PARE		(1<<7)
+#define US_FRAME	(1<<6)
+#define US_OVRE		(1<<5)
+#define US_ENDTX	(1<<4)
+#define US_ENDRX	(1<<3)
+#define US_RXBRK	(1<<2)
+#define US_TXRDY	(1<<1)
+#define US_RXRDY	(1)
+
+#define US_ALL_INTS (US_DMSI|US_TXEMPTY|US_TIMEOUT|US_PARE|US_FRAME|US_OVRE|US_ENDTX|US_ENDRX|US_RXBRK|US_TXRDY|US_RXRDY)
+
+#ifndef __ASSEMBLER__
+struct atmel_usart_regs{
+	unsigned long cr;		// control 
+	unsigned long mr;		// mode
+	unsigned long ier;		// interrupt enable
+	unsigned long idr;		// interrupt disable
+	unsigned long imr;		// interrupt mask
+	unsigned long csr;		// channel status
+	unsigned long rhr;		// receive holding 
+	unsigned long thr;		// tramsmit holding		
+	unsigned long brgr;		// baud rate generator		
+	unsigned long rtor;		// rx time-out
+	unsigned long ttgr;		// tx time-guard
+	unsigned long res1;
+	unsigned long rpr;		// rx pointer
+	unsigned long rcr;		// rx counter
+	unsigned long tpr;		// tx pointer
+	unsigned long tcr;		// tx counter
+};
+
+static inline void at91_usart_init(volatile struct atmel_usart_regs *uart, int baudrate)
+{
+
+        uart->cr = US_TXDIS | US_RXDIS | US_RSTTX | US_RSTRX;
+        /* clear Rx receive and Tx sent counters */
+        uart->rcr = 0;
+        uart->tcr = 0;
+
+	uart->idr = US_TXEMPTY;		/* tx disable */
+	uart->idr = US_ENDRX | US_TIMEOUT; /* rx disable */
+	
+        /* Set the serial port into a safe sane state */
+        uart->mr = US_USCLKS(0) | US_CLK0 | US_CHMODE(0) | US_NBSTOP(0) |
+                    US_PAR(4) | US_CHRL(3);
+
+        uart->brgr = ARM_CLK/16/baudrate;
+
+        uart->rtor = 20;                        // timeout = value * 4 *bit period
+        uart->ttgr = 0;                         // no guard time
+        uart->rcr = 0;
+        uart->rpr = 0;
+        uart->tcr = 0;
+        uart->tpr = 0;
+#ifdef US_RTS
+        uart->mc = 0;
+#endif
+}
+
+static inline void at91_usart_putc(volatile struct atmel_usart_regs *uart, unsigned char c)
+{
+       uart->cr=US_TXEN;
+       uart->thr=c;
+       while(1) {
+                if (uart->csr & US_TXEMPTY) break;
+       }
+}
+#endif
+		
+#define PIO(i)		(1<<i)
+
+#ifndef __ASSEMBLER__
+struct pio_regs{
+	unsigned long per;
+	unsigned long pdr;
+	unsigned long psr;
+	unsigned long res1;
+	unsigned long oer;
+	unsigned long odr;
+	unsigned long osr;
+	unsigned long res2;
+	unsigned long ifer;
+	unsigned long ifdr;
+	unsigned long ifsr;
+	unsigned long res3;
+	unsigned long sodr;
+	unsigned long codr;
+	unsigned long odsr;
+	unsigned long pdsr;
+	unsigned long ier;
+	unsigned long idr;
+	unsigned long imr;
+	unsigned long isr;
+};
+#endif
+
+#ifndef __ASSEMBLER__
+struct pmc_regs{
+	unsigned long scer;
+	unsigned long scdr;
+	unsigned long scsr;
+	unsigned long reserved;
+	unsigned long pcer;
+	unsigned long pcdr;
+	unsigned long pcsr;
+};
+#endif
+
+#endif  /* _ASM_ARCH_HARDWARE_H */
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/ide.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/ide.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/ide.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,45 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/ide.h
+ *
+ * Copyright (c) 1998 Hugo Fiennes & Nicolas Pitre
+ *
+ * 18-aug-2000: Cleanup by Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
+ *              Get rid of the special ide_init_hwif_ports() functions
+ *              and make a generalised function that can be used by all
+ *              architectures.
+ */
+
+#include <linux/config.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+
+/*
+ * Set up a hw structure for a specified data port, control port and IRQ.
+ * This should follow whatever the default interface uses.
+ */
+static __inline__ void
+ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int *irq)
+{
+#ifdef CONFIG_REVISIT
+#error Not sure what to do for ide_init_hwif_ports
+#endif
+}
+
+
+
+
+/*
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ */
+static __inline__ void
+ide_init_default_hwifs(void)
+{
+#ifdef CONFIG_REVISIT
+#error Not sure what to do for ide_init_default_hwifs
+#endif
+}
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/io.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,46 @@
+/*
+ * linux/include/asm-armnommu/arch-atmel/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ *  02-19-2001  gjm     Leveraged for armnommu/dsc21
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ * --gmcnutt
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * If we define __io then asm/io.h will take care of most of the inb & friends
+ * macros. It still leaves us some 16bit macros to deal with ourselves, though.
+ * We don't have PCI or ISA on the dsc21 so I dropped __mem_pci & __mem_isa.
+ * --gmcnutt
+ */
+#define __io(a) (CONFIG_IO16_BASE + (a))
+#define __iob(a) (CONFIG_IO8_BASE + (a))	// byte io address
+#define __mem_pci(a)	((unsigned long)(a))	 
+
+#define __arch_getw(a) (*(volatile unsigned short *)(a))
+#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
+
+/*
+ * Defining these two gives us ioremap for free. See asm/io.h.
+ * --gmcnutt
+ */
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define __io_noswap 1
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,43 @@
+/*
+ * asm/arch-atmel/irq.h:
+ * 2001 Erwin Authried
+ */
+
+#ifndef __ASM_ARCH_IRQ_H__
+#define __ASM_ARCH_IRQ_H__
+
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irqs.h>
+
+
+#define fixup_irq(x) (x)
+
+extern void at91_mask_irq(unsigned int irq);
+extern void at91_unmask_irq(unsigned int irq);
+extern void at91_mask_ack_irq(unsigned int irq);
+extern void at91_init_aic(void);
+
+static __inline__ void irq_init_irq(void)
+{
+	int irq;
+
+	at91_init_aic();
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+
+	        if (!VALID_IRQ(irq)) continue;
+
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= at91_mask_ack_irq;
+		irq_desc[irq].mask	= at91_mask_irq;
+		irq_desc[irq].unmask	= at91_unmask_irq;
+	}
+}
+
+
+
+#endif /* __ASM_ARCH_IRQ_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/irqs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,65 @@
+/*
+ * asm/arch-p52/irqs.h:
+ * 2001 Mindspeed
+ */
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+
+
+#ifdef CONFIG_CPU_AT91X40
+/*
+ ******************* AT91x40xxx ********************
+ */
+
+#define NR_IRQS		24
+#define VALID_IRQ(i)	(i<=8 ||(i>=16 && i<NR_IRQS))
+
+
+#define IRQ_FIQ		0
+#define IRQ_SWI		1
+#define IRQ_USART0	2
+#define IRQ_USART1	3
+#define IRQ_TC0		4
+#define IRQ_TC1		5
+#define IRQ_TC2		6
+#define IRQ_WD		7
+#define IRQ_PIOA	8
+
+#define IRQ_EXT0	16
+#define IRQ_EXT1	17
+#define IRQ_EXT2	18
+
+#elif CONFIG_CPU_AT91X63
+/*
+ ******************* AT91x63xxx ********************
+ */
+
+#define NR_IRQS		32
+#define VALID_IRQ(i)	(i<=14 ||(i>=28 && i<NR_IRQS))
+
+#define IRQ_FIQ		0
+#define IRQ_SWI		1
+#define IRQ_USART0	2
+#define IRQ_USART1	3
+#define IRQ_USART2	4
+#define IRQ_SP		5
+#define IRQ_TC0		6
+#define IRQ_TC1		7
+#define IRQ_TC2		8
+#define IRQ_TC3		9
+#define IRQ_TC4		10
+#define IRQ_TC5		11
+#define IRQ_WD		12
+#define IRQ_PIOA	13
+#define IRQ_PIOB	14
+
+#define IRQ_EXT0	31
+#define IRQ_EXT1	30
+#define IRQ_EXT2	29
+#define IRQ_EXT3	28
+
+#else 
+  #error "Configuration error: No CPU defined"
+#endif
+
+#endif /* __ASM_ARCH_IRQS_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/keyboard.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/keyboard.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/keyboard.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ *  linux/include/asm-arm/arch-ti926/keyboard.h
+ *
+ *  Copyright (C) 2000 RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Keyboard driver definitions for ARM
+ */
+#ifndef __ASM_ARM_ARCH_TI925_KEYBOARD_H
+#define __ASM_ARM_ARCH_TI925_KEYBOARD_H
+
+#if 0
+#define kbd_request_region
+#define kbd_write_command
+#define kbd_write_output
+#define kbd_read_status
+#define kbd_read_input
+#define aux_request_irq
+#define aux_free_irq
+#endif
+
+/*
+ * Required by drivers/char/keyboard.c. I took these from arch-arc.
+ * --gmcnutt
+ */
+#define kbd_setkeycode(sc,kc) (-EINVAL)
+#define kbd_getkeycode(sc) (-EINVAL)
+#define kbd_translate(sc,kcp,rm) ({ *(kcp) = (sc); 1; })
+#define kbd_unexpected_up(kc) (0200)
+#define kbd_leds(leds)
+#define kbd_init_hw()
+#define kbd_enable_irq() /* what irq? ;) --gmcnutt */
+#define kbd_disable_irq()
+
+
+#endif /* __ASM_ARM_ARCH_TI925_KEYBOARD_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,23 @@
+/*
+ * linux/include/asm-armnommu/arch-atmel/memory.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * 2001 Mindspeed
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define TASK_SIZE	(0x01a00000UL)
+#define TASK_SIZE_26	TASK_SIZE
+
+#define PHYS_OFFSET	(DRAM_BASE)
+#define PAGE_OFFSET PHYS_OFFSET
+#define END_MEM     (DRAM_BASE + DRAM_SIZE)
+
+#define __virt_to_phys(vpage) ((unsigned long) (vpage))
+#define __phys_to_virt(ppage) ((void *) (ppage))
+#define __virt_to_bus(vpage) ((unsigned long) (vpage))
+#define __bus_to_virt(ppage) ((void *) (ppage))
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/param.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/pcmcia.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/pcmcia.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/pcmcia.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/pcmcia.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,3 @@
+#ifdef CONFIG_REVISIT
+#error Do we need PCMCIA support?
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/processor.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/processor.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/processor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,15 @@
+/*
+ * uclinux/include/asm-armnommu/arch-atmel/mmu.h
+ *
+ */
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+#define EISA_bus 0
+#define EISA_bus__is_a_macro
+#define MCA_bus 0
+#define MCA_bus__is_a_macro
+
+#define TASK_SIZE (0x01a00000UL)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/serial.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/serial.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/serial.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,9 @@
+/*
+ *  linux/include/asm-arm/arch-p52/serial.h
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+/* need to move p52serial.h here */
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/shmparam.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/shmparam.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/shmparam.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-a5k/shmparam.h
+ *
+ * Copyright (c) 1996 Russell King.
+ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/system.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-armnommu/arch-p52/system.h
+ * 2001 Mindspeed
+ */
+
+static inline void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter)
+	  cpu_do_idle(IDLE_WAIT_SLOW);
+}
+
+extern inline void arch_reset(char mode)
+{
+  /* tbd */
+}
+
+ 
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/time.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/time.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,66 @@
+/*
+ * linux/include/asm-armnommu/arch-atmel/time.h
+ *
+ * Copyright (C) 2001/02 Erwin Authried <eauth@softsys.co.at>
+ */
+
+#if (KERNEL_TIMER==0)
+#   define KERNEL_TIMER_IRQ_NUM IRQ_TC0
+#elif (KERNEL_TIMER==1)
+#   define KERNEL_TIMER_IRQ_NUM IRQ_TC1
+#elif (KERNEL_TIMER==2)
+#   define KERNEL_TIMER_IRQ_NUM IRQ_TC2
+#else
+#error Wierd -- KERNEL_TIMER is not defined or something....
+#endif
+
+static unsigned long atmel_gettimeoffset (void)
+{
+	volatile struct at91_timers* tt = (struct at91_timers*) (AT91_TC_BASE);
+	volatile struct at91_timer_channel* tc = &tt->chans[KERNEL_TIMER].ch;
+	return tc->cv * (1000*1000)/(ARM_CLK/128);
+}
+
+static void atmel_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	volatile struct at91_timers* tt = (struct at91_timers*) (AT91_TC_BASE);
+	volatile struct at91_timer_channel* tc = &tt->chans[KERNEL_TIMER].ch;
+	unsigned long v = tc->sr;
+        do_timer(regs);
+        do_profile(regs);
+}
+
+extern inline void setup_timer (void)
+{
+        register volatile struct at91_timers* tt = (struct at91_timers*) (AT91_TC_BASE);
+        register volatile struct at91_timer_channel* tc = &tt->chans[KERNEL_TIMER].ch;
+        unsigned long v;
+
+	/* enable Kernel timer */
+	HW_AT91_TIMER_INIT(KERNEL_TIMER)
+
+        /* No SYNC */
+        tt->bcr = 0;
+        /* program NO signal on XC1 */
+        v = tt->bmr;
+	v &= ~TCNXCNS(KERNEL_TIMER,3);
+	v |= TCNXCNS(KERNEL_TIMER,1);
+        tt->bmr = v;
+
+        tc->ccr = 2;  /* disable the channel */
+
+        /* select ACLK/128 as inupt frequency for TC1 and enable CPCTRG */
+        tc->cmr = 3 | (1 << 14);
+
+        tc->idr = ~0ul;  /* disable all interrupt */
+        tc->rc = ((ARM_CLK/128)/HZ - 1);   /* load the count limit into the CR register */
+        tc->ier = TC_CPCS;  /* enable CPCS interrupt */
+
+        /* enable the channel */
+        tc->ccr = TC_SWTRG|TC_CLKEN;
+
+        gettimeoffset = atmel_gettimeoffset;
+        timer_irq.handler = atmel_timer_interrupt;
+
+        setup_arm_irq(KERNEL_TIMER_IRQ_NUM, &timer_irq);
+}
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+ * timex.h:
+ * 2001 Mindspeed
+ */
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+#define CLOCK_TICK_RATE	   0x270f
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/uncompress.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/uncompress.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/uncompress.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,60 @@
+/*
+ * asm/arch/uncompress.c:
+ *         Optional routines to aid in debugging the decompression phase
+ *         of kernel boot.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * This is used by arch/armnommu/boot/compressed/misc.c to write progress info
+ * out the serial port so that the user can see debug messages up to the point
+ * where the kernel is decompressed. The STANDALONE_DEBUG macro chooses between
+ * this and the standard printf. Punt.
+ * --gmcnutt
+ */
+
+#include <asm/hardware.h>
+
+#ifdef CONFIG_SERIAL_ATMEL_CONSOLE
+#define putc(c) at91_usart_putc((volatile struct atmel_usart_regs *)AT91_USART0_BASE,c)
+/*
+ * If we need to do some setup prior to decompression (like initializing the
+ * UART if we want to use puts() above) then we define it here. Punt.
+ */
+#define arch_decomp_setup() HW_AT91_USART_INIT \
+	at91_usart_init((volatile struct atmel_usart_regs *)AT91_USART0_BASE,9600)
+#else
+#define puts(s)
+#define arch_decomp_setup()
+#endif
+
+/*
+ * Not sure what this is for. Probably an optional watchdog to check if the
+ * decompress got hung so we can warn the user. Punt.
+ */
+#define arch_decomp_wdog()
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-atmel/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-atmel/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-atmel/vmalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ *  linux/include/asm-arm/arch-dsc21/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/a.out.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/a.out.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/a.out.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * uclinux/include/asm-armnommu/arch-atmel/a.out.h
+ *
+ */
+#ifndef __ASM_ARCH_A_OUT_H
+#define __ASM_ARCH_A_OUT_H
+
+#ifdef __KERNEL__
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/bspcfg.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/bspcfg.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/bspcfg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/bspcfg.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,163 @@
+/****************************************************************************
+*
+*	Name:			bspcfg.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 - 2003  Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   lewisrc  $
+*  $Revision:   1.5  $
+*  $Modtime:   Jul 18 2003 14:21:14  $
+****************************************************************************/
+
+#ifndef BSPCFG_H
+#define BSPCFG_H
+
+#include <linux/autoconf.h>
+
+#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE || CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE // Set in autoconf.h
+
+	#define DSL_DMA	1	
+#else
+	#define DSL_DMA	0	
+#endif
+
+/***************************************************************
+ * The main defines below will configure the BSP default builds
+ * appropriately.  If you need to further customize the build per
+ * your own need th1n venture below.
+ **************************************************************/
+
+#define	ZIGGURAT	1
+
+/*#define  ETHERNET_ADSL_MULTIVC 1*/ 	/* Enable Multi PVCs */
+
+// Set to 1 if the sysInit function is to set the
+// RUN_MAP bit and the SDRAM size in the HST_CTRL register.
+#define	HOSTINTERFACE_CONTROL	0
+
+// Set to 1 to have the sysInit function automatically set
+// the PLL_F and PLL_B registers to the maximum frequency 
+// setting of the device as determined by the function
+// reading the device id.
+#define	PLL_CONTROL		1
+
+// Something needed to build the Voice stuff
+#define RAM53FMOD	1
+
+/***************************************************************
+ * CX821XX DEVICE SPECIFIC
+ **************************************************************/
+
+/*------------------------------------*/
+// Enable level interrupts for ADSL and
+// CX821XX critical section
+/*------------------------------------*/
+
+/* Indicate whether to use GPIO edge or level interrupt. */
+#define LEVEL_MODE_ADSL		1
+
+/***************************************************************
+ * SYSTEM FUNCTION SPECIFIC
+ **************************************************************/
+
+/*------------------------------------*/
+// System Memory Map
+/*------------------------------------*/
+/*
+** Warning!
+** SDRAM_SIZE is either 2,4 or 8. Do not choose other values and
+** do not comment SDRAM_SIZE out.
+*/
+#define SDRAM_SIZE 8
+
+/*------------------------------------*/
+// DMA Memory Map
+/*------------------------------------*/
+
+#define  DSL_DMA_IN_SRAM   1
+
+
+/*------------------------------------*/
+// Showtime Defines
+/*------------------------------------*/
+
+#if DSL_DMA
+	/* This assumes that Showtime is linked into the BSP */
+	#define SHOWTIME_AUTO_START		1
+#else
+	#define SHOWTIME_AUTO_START		0
+#endif
+
+
+/*------------------------------------*/
+// Power Management
+/*------------------------------------*/
+
+#define   POWER_CTRL		1
+
+/***************************************************************
+ * MISC DEFINES
+ **************************************************************/
+
+#if DSL_DMA
+	#ifdef   ETHERNET_ADSL_MULTIVC 
+		#define  MAX_VC_PER_LINK 8
+	#endif
+
+	// NOTE: The following two defines need to be set
+	//  to one for the DL10_D325_003 Hasbani board.
+	#define DL10_D325_003	0
+#endif
+
+/*------------------------------------*/
+// Enable EEPROM Write Function
+/*------------------------------------*/
+
+
+/*#define EEPROM_WRITE       1*/
+
+/*------------------------------------*/
+// LED Pattern
+/*------------------------------------*/
+
+#define COMMON_TX_RX_INDICATION   0      /* ADSL TX and RX share same INDICATION */
+
+
+// Use to change console interface hardware from
+// uart 1 to uart 2 for hardware sanity check purposes.
+
+#define DEBUG_CONSOLE_ON_UART_2		0
+
+
+// Used to enable/disable the file operations used in
+// the HAL drivers of the VOP.
+
+#define OS_FILE_SYSTEM_SUPPORTED	0
+
+// This needs to be set to 1 if you are building the
+// code to run on an Oakland board that has this version
+// of the PLD code loaded into the XC95144 device.
+// If you do not the UART will not be addressed properly
+// See the cnxtserial.h file for where the UART is mapped.
+#define PLD_CS4_UART_v100	0
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/bsptypes.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/bsptypes.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/bsptypes.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/bsptypes.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,296 @@
+/****************************************************************************
+*
+*	Name:			BSPTYPES.H
+*
+*	Description:	Application Manager Application routines declaration.
+*
+*	Copyright:		(c) 1999 - 2003  Conexant Systems Inc.
+*
+*****************************************************************************
+*  $Author:   belljl  $
+*  $Revision:   1.1  $
+*  $Modtime:   Jun 30 2003 15:58:08  $
+****************************************************************************/
+
+#ifndef BSPTYPES_H
+#define BSPTYPES_H
+
+#include <linux/autoconf.h>
+
+#include "OsDefs.h"
+
+#ifndef IN
+#define IN
+#endif
+
+#ifndef OUT
+#define OUT
+#endif
+
+#ifndef I_O
+#define I_O
+#endif
+
+
+#ifndef INT32
+#define INT32 int
+#endif
+
+
+
+
+
+
+
+enum {LITTLE_ENDIAN, BIG_ENDIAN};
+
+#ifdef LITTLE_ENDIAN_MEMORY
+	#define BYTE_ORIENTATION  LITTLE_ENDIAN
+#else
+	#define BYTE_ORIENTATION  BIG_ENDIAN
+#endif
+
+
+#define BIT0             0x00000001
+#define BIT1             0x00000002
+#define BIT2             0x00000004
+#define BIT3             0x00000008
+#define BIT4             0x00000010
+#define BIT5             0x00000020
+#define BIT6             0x00000040
+#define BIT7             0x00000080
+#define BIT8             0x00000100
+#define BIT9             0x00000200
+#define BIT10            0x00000400
+#define BIT11            0x00000800
+#define BIT12            0x00001000
+#define BIT13            0x00002000
+#define BIT14            0x00004000
+#define BIT15            0x00008000
+#define BIT15            0x00008000
+#define BIT16            0x00010000
+#define BIT17            0x00020000
+#define BIT18            0x00040000
+#define BIT19            0x00080000
+#define BIT20            0x00100000
+#define BIT21            0x00200000
+#define BIT22            0x00400000
+#define BIT23            0x00800000
+#define BIT24            0x01000000
+#define BIT25            0x02000000
+#define BIT26            0x04000000
+#define BIT27            0x08000000
+#define BIT28            0x10000000
+#define BIT29            0x20000000
+#define BIT30            0x40000000
+#define BIT31            0x80000000
+
+
+
+#ifndef UINT32
+#define UINT32 unsigned long
+#endif
+
+#ifndef SINT32
+#define SINT32 signed long
+#endif
+
+#ifndef UINT16
+#define UINT16 unsigned short int
+#endif
+
+#ifndef SINT16
+#define SINT16 signed short int
+#endif
+
+#ifndef INT16
+#define INT16 short int
+#endif
+
+#ifndef UINT8
+#define UINT8 unsigned char
+#endif
+
+#ifndef INT8
+#define INT8 unsigned char
+#endif
+
+#ifndef SINT8
+#define SINT8 signed char
+#endif
+
+#define uint32_ONE 0x80000000L
+#define uint16_ONE 0x8000
+
+#define sint32_MAX 0x7FFFFFFFL
+#define sint16_MAX 0x7FFF
+
+#define uint32_MAX 0xFFFFFFFFUL
+#define uint16_MAX 0xFFFFU
+
+#define sint32_MIN 0x00000001L
+#define sint16_MIN 0x0001
+
+typedef void (* JOB_TYPE)(void);
+
+typedef struct
+{
+   SINT16 real,imag;
+}SINT16CMPLX;
+
+typedef struct
+{
+   SINT32 real,imag;
+}SINT32CMPLX;
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef FUNCPTR
+//#define FUNCPTR UINT32
+typedef int	(*FUNCPTR)(void);
+#endif
+
+#define FALSE              0
+#define TRUE               1
+
+typedef void * HBM_CHANNEL;
+typedef char * PCHAR;
+
+#define IVEC_TO_INUM(intVec)   ((int) (intVec))
+#define INUM_TO_IVEC(intNum)   ((void *) (intNum))
+
+typedef struct tagHWSTATESTRUCT {
+	UINT32 eDeviceType;
+  	UINT32 HWPowerMode;
+	UINT32 eUSBCurrState;
+	UINT32 eUSBPrevState;
+	#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE || CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE
+		UINT32 eADSLLineState;
+		UINT32 eADSLRequestLineState;
+		UINT32 dwADSLDownRate;
+		UINT32 dwADSLUpRate;
+		UINT32 dwLineStatus;
+	#endif
+	UINT32 bSRAMState;
+	UINT32 bSDRAMState;
+	UINT32 bFLASHState;
+	UINT32 bEEPROMState;
+	UINT32 eUARTState;
+	void   *g_pUARTChan;
+	UINT32 bSelfTestState;
+	UINT32 dwMACAddressLow;
+	UINT32 dwMACAddressHigh;
+
+	// stuff for the performance CP panel
+	#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE || CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE
+		UINT32	Transmit_State;
+		UINT32	Receive_State;
+		UINT32	Process_State;
+		UINT32	Up_SNR_Margin_Cur;
+		UINT32	Up_SNR_Margin_Min;
+		UINT32	Up_SNR_Margin_MinBin;
+		UINT32	Down_SNR_Margin_Cur;
+		UINT32	Down_SNR_Margin_Min;
+		UINT32	Down_SNR_Margin_Min_Bin;
+		UINT32	Up_Attn;
+		UINT32	Down_Attn;
+		UINT32	Tx_Power;
+		UINT32	Up_Bits_Per_Frame;
+		UINT32	Down_Bits_Per_Frame;
+		UINT32	Startup_Attempts;
+		UINT32	Up_CRC_Errors;
+		UINT32	Down_CRC_Errors;
+		UINT32	Up_FEC_Errors;
+		UINT32	Down_FEC_Errors;
+		UINT32	Up_HEC_Errors;
+		UINT32	Down_HEC_Errors;
+		UINT32	Retrain_Attempts;
+	#endif
+
+   UINT32   p_GRP0_INPUT_ENABLE_Image;
+   UINT32   p_GRP1_INPUT_ENABLE_Image;
+   UINT32   p_GRP2_INPUT_ENABLE_Image;
+
+} HWSTATESTRUCT, *PHWSTATESTRUCT;
+
+
+typedef struct tagRXBUFFERSTRUCT
+{
+  volatile UINT32 *pdwRxStart;
+  volatile UINT32 *pdwRxEnd;
+  volatile UINT32 *pdwRxPtr;
+  volatile UINT8 *pcData; 
+  UINT32 		BuffSize;
+} RXBUFFERSTRUCT, *PRXBUFFERSTRUCT;
+
+
+typedef struct tagEPINFOSTRUCT
+{
+  UINT32 bTxEnable;
+  UINT32 bTxSendMode;
+  UINT32 bTXWA;
+  UINT32 TxIRQCount;
+  UINT32 TxUnderrun; 
+  UINT32 TxPacket;
+  UINT32 TxTotalPending;   /* Total Pending count waiting to be sent to USB */
+  UINT32 TxPendingInc;     /* Pending count on attempt to dynamically add to DMA Tx link */
+  UINT32 TxRejectCnt;
+  volatile UINT32 *pTxHead;
+  volatile UINT32 *pTxTail;
+  volatile UINT32 *pTxCurr;
+  UINT32 TxBufferSize;
+  UINT32 bRxEnable;
+  UINT32 RxIRQCount;
+  UINT32 RxIRQThresh;
+  UINT32 RxTimeOut;
+  UINT32 RxPacket;
+  UINT32 RxTotalPending;   /* Total Pending count waiting to be sent from USB */
+  UINT32 RxBadPacket;
+  UINT32 RxOverrun;
+} EPINFOSTRUCT, *PEPINFOSTRUCT;
+
+
+typedef enum
+{
+   DEVICE_P5200X10,
+   DEVICE_P5200X180,
+   DEVICE_P5300,
+   DEVICE_RUSHMORE,
+   DEVICE_RUSHMORE_X45,
+   DEVICE_RUSHMORE_X50,
+   #ifdef DEVICE_YELLOWSTONE
+   DEVICE_OLDFAITHFUL
+   #endif
+} eDeviceType;
+
+
+typedef enum
+{
+   NO_UART,                /* No UART support */
+   HW_UART,                /* HW 16550 UART   */
+   VIRTUAL_UART            /* VIRTUAL UART over USB endpoint 3 */
+} eUARTType;
+
+#if USB_SYNC_EP_INT_STAT
+extern UINT32  USB_IDAT_VALUE;
+#endif
+
+extern UINT32  USB_IDAT_IMAGE;
+
+extern HWSTATESTRUCT HWSTATE;
+
+
+#define NELEMENTS(array) \
+        (sizeof(array) / sizeof((array)[0]))
+
+#ifndef STATUS
+#define STATUS long int
+#endif
+
+#define ERROR (-1)
+#define OK     0
+
+
+#endif	//BSPTYPES_H
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/cardalpub.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cardalpub.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/cardalpub.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cardalpub.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,66 @@
+/****************************************************************************
+*
+*	Name:			CardAlpub.h
+*
+*	Description:	Abstraction Layer routines public declarations.
+*
+*	Copyright:		(c) 2000 Conexant Systems Inc.
+*
+*****************************************************************************
+*	$Author:   davidsdj  $
+*	$Revision:   1.0  $
+*	$Modtime:   Mar 19 2003 12:28:30  $
+****************************************************************************/
+
+#ifndef CARDALPUB_H
+#define CARDALPUB_H
+
+
+#ifndef PCARDAL_CONTEXT_T_DEFINED
+	#define PCARDAL_CONTEXT_T_DEFINED
+	typedef struct _CARDAL_CONTEXT_T *PCARDAL_CONTEXT_T ;
+#endif
+				
+#ifndef _COMMON_DATA_H_
+				typedef struct _TIG_USER_PARAMS_	TIG_USER_PARAMS,	*PTIG_USER_PARAMS;
+#endif
+
+
+PCARDAL_CONTEXT_T cardALCfgInit
+(
+	void								* adapter,
+	PTIG_USER_PARAMS					  pTigParams
+) ;
+
+void cardALChipStartAdslLine
+(
+	PCARDAL_CONTEXT_T				  pCardAl_Context
+);
+
+void cardALChipShutdownAdslLine
+(
+	PCARDAL_CONTEXT_T				  pCardAl_Context
+);
+
+DWORD cardALChipGetLineStatus
+(
+	PCARDAL_CONTEXT_T				  pCardAl_Context
+);
+
+BOOLEAN ChipAlTigrisDpWriteNvram
+(
+	PCARDAL_CONTEXT_T				  pCardal,
+	UINT16							  offset,
+	const UINT8 					* data,
+	UINT16							  size
+) ;
+
+BOOLEAN ChipAlTigrisDpReadNvram
+(
+	PCARDAL_CONTEXT_T				  pCardal,
+	UINT16							  offset,
+	UINT8 							* data,
+	UINT16							  size
+) ;
+
+#endif /* CARDALPUB_H */ 
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/cardinfo.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cardinfo.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/cardinfo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cardinfo.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,192 @@
+/****************************************************************************
+ *
+ *  Name:			CARDINFO.H
+ *
+ *  Description:	Card status informations header file
+ *
+ *  Copyright (c) 1999 Conexant
+ *
+ ****************************************************************************
+ *
+ *  $Author:   davidsdj  $
+ *  $Revision:   1.0  $
+ *  $Modtime:   Mar 19 2003 12:28:30  $
+ *
+ ***************************************************************************/
+#ifndef CARDINFO_H
+#define CARDINFO_H
+
+#define FIRMWARE_VERSION_STRING "$_$"		// TBD
+
+/*
+** ADSL Line State and ADSL Requested Line State uses the following enum.
+** Note that the cardinfo structure does not include this info now, it
+** may in the future.
+*/
+typedef enum
+{
+   ADSL_DISABLE,
+   ADSL_HW_INIT,
+   ADSL_SHOWTIME_UP,
+   ADSL_SHOWTIME_DOWN,
+   ADSL_REQUEST_SHOWTIME_UP,
+   ADSL_REQUEST_SHOWTIME_DOWN
+} eADLSState;
+
+typedef struct cardParamStruct
+{
+	DWORD dwIndex;
+	DWORD dwValue;
+} CARDPARAM, *PCARDPARAM;
+
+#define CARD_PARAM_MAX					(7)
+
+typedef struct cardDataStruct
+{
+	DWORD     dwCount;
+	CARDPARAM Param[CARD_PARAM_MAX];
+} CARDDATA, *PCARDDATA;
+
+/****************************************************************************
+*  Type definitions
+****************************************************************************/
+
+/* This declaration moved here from DevIoCardAL.h, */ 
+/* because it is shared with host driver.          */ 
+//typedef enum BD_ADSL_MODEM_STATUS_E
+//{
+//	BD_MODEM_START					= 0,
+//	BD_MODEM_DOWN					= 0,
+//	BD_MODEM_ACTIVATION,			/* 1 */
+//	BD_MODEM_TRANSCEIVER_TRAINING,
+//	BD_MODEM_CHANNEL_ANALYSIS,
+//	BD_MODEM_EXCHANGE,
+//	BD_MODEM_ACTIVATED,				/* 5 */
+//	BD_MODEM_WAITING_INIT,
+//	BD_MODEM_INITIALIZING,
+//	BD_MODEM_UNKNOWN,
+//	BD_MODEM_END					/* 9 */
+//} BD_ADSL_MODEM_STATUS_T;
+
+/* This declaration moved here from DevIo.h, */ 
+/* because it is shared with host driver.    */ 
+#define UNKNOWN_4BIT_VALUE		0x0000000F
+#define UNKNOWN_8BIT_VALUE		0x000000FF
+#define UNKNOWN_16BIT_VALUE		0x0000FFFF
+#define UNKNOWN_32BIT_VALUE		0xFFFFFFFF
+
+#if 0
+//#ifndef _HWIO_H_
+//
+//	HW_IO_GET_PERFORMANCE		Extracted from Tigris  Hwio.h  8/11/00
+//
+typedef enum HW_IO_MODEM_STATUS_CODES_E
+{
+	HW_IO_MODEM_STATUS_START					= 0,
+
+	HW_IO_MODEM_STATUS_DOWN						= 0,
+	HW_IO_MODEM_STATUS_ACTIVATION,					// 1
+	HW_IO_MODEM_STATUS_TRANSCEIVER_TRAINING,
+	HW_IO_MODEM_STATUS_CHANNEL_ANALYSIS,
+	HW_IO_MODEM_STATUS_EXCHANGE,
+	HW_IO_MODEM_STATUS_ACTIVATED,					// 5
+	HW_IO_MODEM_STATUS_WAITING_INIT,
+	HW_IO_MODEM_STATUS_INITIALIZING,
+	HW_IO_MODEM_STATUS_UNKNOWN,
+
+	HW_IO_MODEM_STATUS_END							// 9
+
+} HW_IO_MODEM_STATUS_CODES_T;
+#endif
+
+//* Persistent Data Elements
+//  From PC to P52 
+typedef enum LC_CFG_PARM_NAMES_E 
+{
+ 	LC_CFG_START = 0,
+ 	LC_CFG_DEBUG_FLAG = LC_CFG_START,
+	LC_ADSLDATAPATHSELECT,
+	LC_ADSLPSDTESTMODE,
+	LC_LINEAUTOACTIVATION,
+	LC_LINEPERSISTENTACT, 
+	LC_CONTROLLERLOGENABLE,
+	LC_CAPABILITIES_G922,
+	LC_CAPABILITIES_G922ANNEX,
+	LC_VENDOR_NEAR_ID,
+	LC_MAC_ADDRESS,
+	LC_AUTO_SENSE_HANDSHAKE,
+	LC_AUTO_SENSE_FOUND_HANDSHAKE,
+	LC_AUTO_SENSE_HANDSHAKE_PREF_FND,
+	LC_AUTO_SENSE_HANDSHAKE_OPTIMZ,
+	LC_AUTO_SENSE_LOOP_MIN,
+	LC_AUTO_SENSE_LOOP_MAX,
+	LC_AUTO_SENSE_INITIAL_TIMEOUT,
+	LC_AUTO_SENSE_LOOP_TIMEOUTS,
+	LC_AUTO_SENSE_LOCK_TIMEOUT,
+	LC_AUTO_SENSE_RESTART_PAUSE,
+	LC_AUTO_SENSE_SEARCH_PAUSE,	
+	LC_AUTO_SENSE_WIRING_SELECTION,
+	LC_AUTO_SENSE_WIRING_NUM_COMBOS,
+	LC_AUTO_SENSE_WIRING_COMBO_GPIO,
+	LC_AUTO_SENSE_WIRING_RELAY_DELAY,
+	LC_AUTO_SENSE_WIRING_RELAY_ENRG,
+	LC_AUTO_SENSE_WIRING_ORDER,
+	LC_ADSL_HEAD_END,
+	LC_ADSL_HEAD_END_ENVIRONMENT,
+	LC_PHYSICAL_DRIVER_TYPE,
+	LC_SOFTWARE_SWITCH_HOOK_STATE,
+	LC_USE_SOFTWARE_SWITCH_HOOK_STATE,
+    LC_ADSL_CRC_PER_SES,    
+    LC_ADSL_SES_TO_RETRAIN,
+	LC_ADSL_TELCO_ID,
+    LC_CFG_MAX
+}LC_CFG_PARM_NAMES_T;
+
+#define EXE_HWIO_COMMAND	0xFFFFFFFF;
+
+//  From P52 to PC 
+typedef enum CC_CFG_STATUS_E 
+{
+ 	CC_CFG_START = 0,
+ 	CC_CFG_DOWNRATE = CC_CFG_START,
+	CC_CFG_UPRATE,
+	CC_CFG_LINKSTATUS,
+	CC_CFG_LINESTATUS,
+	CC_CFG_MACADDRHIGH, 
+	CC_CFG_MACADDRLOW,
+
+	// New enum for layered CP
+	CC_CFG_UP_SNR_MARGIN_CUR,
+	CC_CFG_DOWN_SNR_MARGIN_CUR,
+	CC_CFG_UP_ATTN,
+	CC_CFG_DOWN_ATTN,
+	CC_CFG_TX_POWER,
+	CC_CFG_UP_BITS_PER_FRAME,
+	CC_CFG_DOWN_BITS_PER_FRAME,
+	CC_CFG_STARTUP_ATTEMPTS,
+	CC_CFG_UP_CRC_ERRORS,
+	CC_CFG_DOWN_CRC_ERRORS,
+	CC_CFG_UP_FEC_ERRORS,
+	CC_CFG_DOWN_FEC_ERRORS,
+	CC_CFG_UP_HEC_ERRORS,
+	CC_CFG_DOWN_HEC_ERRORS,
+
+	CC_CFG_HWIO_LINE_STARTABLE, 
+	CC_CFG_HWIO_MODULATION,
+	CC_CFG_ADSL_HEAD_END,
+	CC_CFG_ADSL_HEAD_END_ENVIRONMENT,
+	
+/*	Old enum for non-layered CP
+	CC_CFG_CAPOCCUPATIONDNSTR,
+	CC_CFG_NOISEMARGINDNSTR,
+	CC_CFG_OUTPUTPOWERDNSTR,
+	CC_CFG_ATTENDNSTR,
+	CC_CFG_CAPOCCUPATIONUPSTR,
+	CC_CFG_NOISEMARGINUPSTR,
+	CC_CFG_OUTPUTPOWERUPSTR,
+	CC_CFG_ATTENUPSTR,
+*/
+	CC_CFG_MAX
+} CC_CFG_STATUS_T;
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/cnxtadsl.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cnxtadsl.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/cnxtadsl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cnxtadsl.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,52 @@
+/****************************************************************************
+*
+*	Name:			cnxtadsl.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2001 Conexant Systems Inc.
+*
+*****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:28:30  $
+****************************************************************************/
+
+#ifndef CNXTADSL_H
+#define CNXTADSL_H
+
+#include "bsptypes.h"
+#include "cardinfo.h"
+#include "hwiodmt.h"
+
+/* Showtime rate */
+#define SHOWTIME_SYS_CLK_MS_PERIOD  1000
+/* Buffer manager rate */
+#define BM_SYS_CLK_MS_PERIOD  (1000/2)
+
+void CnxtAdslLEDTask( void *sem );
+
+BOOL ADSL_Init(void);
+UINT32 ADSL_UpdateState
+(
+	BOOL						InShowtime,
+	UINT32						dwADSLDownRate,
+	UINT32						dwADSLUpRate,
+	UINT32						dwLineStatus,
+	PHW_IO_TRANSCEIVER_STATUS_T	pHwIoTransceiverStatus
+);
+
+BOOL ADSL_RequestedLineState(BOOL Up);
+
+UINT32 ADSL_GetRequestedLineState(void);
+UINT32 ADSL_LinkStatus(void);
+UINT32 ADSL_GetDownstreamDataRate(void);
+UINT32 ADSL_GetUpstreamDataRate(void);
+void ADSL_GetShowtimeParm(UINT32 index, UINT32* pdwValue);
+
+void CardGetInfo(PCARDDATA pCardData);
+void CardGetData(PCARDDATA pCardData);
+void CardPutData(PCARDDATA pCardData);
+
+#endif	// CNXTADSL_H
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/cnxtbsp.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cnxtbsp.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/cnxtbsp.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cnxtbsp.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,422 @@
+/****************************************************************************
+*
+*	Name:			cnxtbsp.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:28:30  $
+****************************************************************************/
+
+/*
+This file contains I/O address and related constants for the ARM PID board.
+*/
+
+#ifndef CNXTBSP_H
+#define CNXTBSP_H
+
+#define BULK_MAX_PACKET_SIZE     64
+
+/*******************************************************************
+* MMU Control Register layout.
+* BIT
+*	0 M 0 MMU disabled
+*	1 A 0 Address alignment fault disabled, initially
+*	2 C 0 Data cache disabled
+*	3 W 0/1 Write Buffer disabled (or Should Be One)
+*	4 P 1 PROG32
+*	5 D 1 DATA32
+*	6 L 1 Should Be One (Late abort on earlier CPUs)
+*	7 B ? Endianness (1 => big)
+*	8 S 0 System bit to zero } Modifies MMU protections, not really
+*	9 R 1 ROM bit to one     } relevant until MMU switched on later.
+*  10 F 0 Should Be Zero
+*  11 Z 0 Should Be Zero (Branch prediction control on 810)
+*  12 I 0 Instruction cache control, (or Should Be Zero)
+********************************************************************/
+
+#define MMUCR_M_ENABLE	 (1<<0)  /* MMU enable */
+#define MMUCR_A_ENABLE	 (1<<1)  /* Address alignment fault enable */
+#define MMUCR_C_ENABLE	 (1<<2)  /* (data) cache enable */
+#define MMUCR_W_ENABLE	 (1<<3)  /* write buffer enable */
+#define MMUCR_PROG32	    (1<<4)  /* PROG32 */
+#define MMUCR_DATA32	    (1<<5)  /* DATA32 */
+#define MMUCR_L_ENABLE	 (1<<6)  /* Late abort on earlier CPUs */
+#define MMUCR_BIGEND	    (1<<7)  /* Big-endian (=1), little-endian (=0) */
+#define MMUCR_SYSTEM	    (1<<8)  /* System bit, modifies MMU protections */
+#define MMUCR_ROM		    (1<<9)  /* ROM bit, modifies MMU protections */
+#define MMUCR_F			 (1<<10) /* Should Be Zero */
+#define MMUCR_Z_ENABLE	 (1<<11) /* Branch prediction enable on 810 */
+#define MMUCR_I_ENABLE	 (1<<12) /* Instruction cache enable */
+/* Extra 940T bits */
+#define MMUCR_FB_DISABLE (1<<30) /* nFastBus bit */
+#define MMUCR_ASYNC_BIT	 (1<<31) /* Async bit*/
+#define MMUCR_SYNC		 (1<<30) /* Synchronous mode */
+#define MMUCR_ASYNC		 (3<<30) /* Asynchronous mode */
+#define MMUCR_FB		 0
+/* W bit is Should Be One */
+#define MMU_INIT_VALUE ( MMUCR_PROG32 | MMUCR_DATA32 | MMUCR_L_ENABLE | MMUCR_W_ENABLE)
+
+
+/* Internal memory addresses */
+#define ASB_RAM_ADRS 0x00180000
+
+#define  SRAMSIZE    0x8000
+#if (SDRAM_SIZE == 8)
+	#define SDRAMSIZE  0x00800000
+#else
+	#if (SDRAM_SIZE == 4)
+  		#define SDRAMSIZE  0x00400000
+	#else
+		#define SDRAMSIZE  0x00200000
+	#endif
+#endif
+
+/* Internal SRAM location during Run map */
+#define  SRAMSTART      0x1000
+#define  SRAMEND        0x8000
+#define  HOST_SIGNATURE 0x500
+
+#define  SDRAMSTART     0x800000
+#define  SDRAMEND       SDRAMSTART + SDRAMSIZE
+
+
+/* PLL control bit definitions */
+#define PLL_CR_SLOW     BIT28
+#define PLL_LOCK_STATUS BIT27
+
+/* PLL definitions */
+#define P52_MAX_NUM_BLCK         3
+#define RUSHMORE_MAX_NUM_BLCK    5
+
+/* Define how often USB interface should poll DMA Ready bit */
+#define USB_POLL_125    ((0.0005 * PLL_FAST_125MHZ)/2) & 0x000007FF
+#define USB_POLL_100    ((0.0005 * PLL_FAST_100MHZ)/2) & 0x000007FF
+#define USB_POLL_75     ((0.0005 * PLL_FAST_75MHZ)/2)  & 0x000007FF
+
+
+#define EXT_MEM_CTL     0x350010
+#define EXT_SDRAM_ENA   0x1
+#define EXT_SRAM_ENA    0x2
+
+#define LPMR		      0x350014
+
+/*
+ * interrupt control stuff
+ * Note: FIQ is not handled within VxWorks so this is just IRQ
+ */
+
+#define IC_BASE         0x00350000
+
+#define EXT_MEM_CTL     0x350010
+#define EXT_SDRAM_ENA   0x1
+#define EXT_SRAM_ENA    0x2
+
+/* PLL Registers */
+
+/* ##################################### */
+#define DEVICE_ID_REG		 0x350060
+
+/* This memory location and value determine if it is
+   Rushmore or Rushmore X4	*/
+#define ROM_DEVICE_ID_REG		0x187ffc
+#define RUSH_X45_ROM_VALUE		0x00003354
+#define RUSH_X10_45_DEV_ID		0x08230000
+#define RUSH_X50_DEV_ID			0x08230001
+
+#define P5200X10_DEV_ID		 0x50000000     /* Mask 1st[3:0] and last[31:28] bytes */
+#define P5200X180_DEV_ID     0x50000001     /* Mask 1st[3:0] and last[31:28] bytes */
+#define P5300_DEV_ID		 0x50000002     /* Mask 1st[3:0] and last[31:28] bytes */
+
+/* Interrupt Registers */
+#ifdef DEVICE_YELLOWSTONE
+//************************************************
+// 		Define Offset for I/O and memory map 
+//		Incase of APTIX system with ARM SCM board  
+//************************************************
+
+#ifdef ARM_SCM_USE
+   #define S_OFFSET     0xC0000000
+#else
+   #define S_OFFSET     0x00000000
+#endif
+
+//************************************************
+// 		Interrupt Controller I/O register map
+//************************************************
+
+#define PIC_BASE			            (0x00600800 + S_OFFSET)
+
+#define PIC_INT_ENABLE					(PIC_BASE + 0)						// Not Use 
+#define PIC_TOP_ASSIGN_POLLED			(PIC_BASE + 0x4)		
+#define PIC_TOP_ASSIGN_FIQ				(PIC_BASE + 0x8)		
+#define PIC_TOP_ISR_POLLED				(PIC_BASE + 0xC)		 
+#define PIC_TOP_IMR_FIQ 				(PIC_BASE + 0x10)		  
+#define PIC_TOP_ISR_FIQ					(PIC_BASE + 0x14)		  
+#define PIC_TOP_MISR_FIQ 				(PIC_BASE + 0x18)		  
+#define PIC_TOP_IMR_IRQ					(PIC_BASE + 0x1C)		  
+#define PIC_TOP_ISR_IRQ					(PIC_BASE + 0x20)		  
+#define PIC_TOP_MISR_IRQ				(PIC_BASE + 0x24)		  
+#define PIC_PRIORITY_3_0				(PIC_BASE + 0x28)		  
+#define PIC_PRIORITY_7_4				(PIC_BASE + 0x2C)		  
+#define PIC_PRIORITY_11_8				(PIC_BASE + 0x30)		  
+#define PIC_PRIORITY_15_12			   (PIC_BASE + 0x34)		  
+#define PIC_PRIORITY_19_16			   (PIC_BASE + 0x38)		  
+#define PIC_PRIORITY_23_20			   (PIC_BASE + 0x3C)		  
+#define PIC_PRIORITY_27_24			   (PIC_BASE + 0x40)		  
+#define PIC_PRIORITY_31_28			   (PIC_BASE + 0x44)		  
+#define PIC_CALC_FRM_STAT_WR			(PIC_BASE + 0x48)		  
+#define PIC_CALC_FRM_STAT_RD_INDEX	(PIC_BASE + 0x4C)		  
+#define PIC_CALC_FRM_STAT_RD_MSK		(PIC_BASE + 0x50)		  
+#define PIC_CALC_FRM_INDEX_WR			(PIC_BASE + 0x54)		  
+#define PIC_CALC_FRM_INDEX_RD_MSK	(PIC_BASE + 0x58)		  
+
+#else
+#define PIC_TOP_ISR_IRQ             (IC_BASE+0x44)
+#define INT_SET_STAT                (IC_BASE+0x48)
+#define PIC_TOP_IMR_IRQ             (IC_BASE+0x4C)
+
+#define IRQ_LEVEL       (IC_BASE)       /* Read/Write */
+#define IRQ_STATUS      (IC_BASE+0x44)  /* Read */
+#define IRQ_SET_STATUS  (IC_BASE+0x48)  /* Write */
+#define IRQ_ENABLE      (IC_BASE+0x4C)  /* Read/Write */
+#define IRQ_DISABLE     (IC_BASE+0x4C)  /* Write */
+#define MASK_STATUS     (IC_BASE+0x50)  /* Read */
+
+#define INT_STAT        (IC_BASE+0x44)
+#define INT_SET_STAT    (IC_BASE+0x48)
+#define INT_MASK        (IC_BASE+0x4C)
+#define INT_MSTAT       (IC_BASE+0x90)
+
+#endif
+/*
+ * All ARM 940T BSPs must define a variable sysCacheUncachedAdrs: a
+ * pointer to a word that is uncached and is safe to read (i.e. has no
+ * side effects).  This is used by the cacheLib code to perform a read
+ * (only) to drain the write-buffer. Clearly this address must be present
+ * within one of the regions created within sysPhysMemDesc, where it must
+ * be marked as non-cacheable. There are many such addresses we could use
+ * on the PID board, but we choose to use an address here that will be
+ * mapped in on just about all configurations: a safe address within the
+ * interrupt controller: the IRQ Enabled status register. This saves us
+ * from having to define a region just for this pointer. This constant
+ * defined here is used to initialise sysCacheUncachedAdrs in sysLib.c
+ * and is also used by the startup code in sysALib.s and romInit.s in
+ * draining the write-buffer.
+ */
+
+#define SYSTEM_CACHE_UNCACHED_ADRS	PIC_TOP_ISR_IRQ
+
+#define CNXT_INT_NUM_LEVELS        32
+#define CNXT_INT_CSR_PEND          MASK_STATUS
+#define CNXT_INT_CSR_ENB           IRQ_ENABLE
+#define CNXT_INT_CSR_DIS           IRQ_DISABLE
+#define CNXT_INT_CSR_MASK          0xFFFFFFFF
+
+#define IRQ_OFF         0
+#define IRQ_ON          1
+
+#ifdef DEVICE_YELLOWSTONE
+#define PIC_DISABLE_MASK   0xFFFFFFFF
+#else
+#define PIC_DISABLE_MASK   0x0
+#endif
+
+/* interrupt levels */
+#define INT_LVL_TIMER_1            0       /* Timer 1 interrupt */
+#define INT_LVL_TIMER_2            1       /* Timer 2 interrupt */
+#define INT_LVL_TIMER_3            2       /* Timer 3 interrupt */
+#define INT_LVL_TIMER_4            3       /* Timer 3 interrupt */
+#define INT_LVL_USB                4       /* USB */
+#define INT_LVL_RES0               5       /* */
+#define INT_LVL_HOST               6       /* External Host interrupt */
+#define INT_LVL_HOST_ERR           7       /* Host Bus error detect */
+#define INT_LVL_DMA8               8       /* M2M */
+#define INT_LVL_RES1               9       /* */
+#define INT_LVL_DMA6              10       /* ADSL Rx */
+#define INT_LVL_DMA5              11       /* ADSL Tx */
+#define INT_LVL_DMA4              12       /* EMAC2 Rx */
+#define INT_LVL_DMA3              13       /* EMAC2 Tx */
+#define INT_LVL_DMA2              14       /* EMAC1 Rx */
+#define INT_LVL_DMA1              15       /* EMAC1 Tx*/
+#define INT_LVL_RES2              16       /* */
+#define INT_LVL_RES3              17       /* */
+#define INT_LVL_DMAC_ERR          18       /* DMAC error */
+#define INT_LVL_EMAC2_ERR         19       /* EMAC2 error */
+#define INT_LVL_EMAC1_ERR         20       /* EMAC1 error */
+#define INT_LVL_ADSL_ERR          21       /* ADSL error */
+#define INT_LVL_RES4              22       /* */
+#define INT_LVL_RES5              23       /* */
+#define INT_LVL_GPIO              24       /* GPIO input*/
+#define INT_LVL_RES6              25       /* */
+#define INT_LVL_COMMTX            26       /* ARM9 Comms Xmit */
+#define INT_LVL_COMMRX            27       /* ARM9 Comms Rcv */
+#define INT_LVL_SW0               28       /* Software interrupt 0 */
+#define INT_LVL_SW1               29       /* Software interrupt 1 */
+#define INT_LVL_SW2               30       /* Software interrupt 2 */
+#define INT_LVL_SW3               31       /* Software interrupt 3 */
+
+/* interrupt vectors */
+#define INT_VEC_TIMER_1   IVEC_TO_INUM(INT_LVL_TIMER_1)  /* Timer 1 interrupt */
+#define INT_VEC_TIMER_2   IVEC_TO_INUM(INT_LVL_TIMER_2)  /* Timer 2 interrupt */
+#define INT_VEC_TIMER_3   IVEC_TO_INUM(INT_LVL_TIMER_3)  /* Timer 3 interrupt */
+#define INT_VEC_TIMER_4   IVEC_TO_INUM(INT_LVL_TIMER_4)  /* Timer 4 interrupt */
+#define INT_VEC_USB       IVEC_TO_INUM(INT_LVL_USB)      /* USB */
+#define INT_VEC_RES0      IVEC_TO_INUM(INT_LVL_RES0)     /* */
+#define INT_VEC_HOST      IVEC_TO_INUM(INT_LVL_HOST)     /* External Host interrupt */
+#define INT_VEC_HOST_ERR  IVEC_TO_INUM(INT_LVL_HOST_ERR) /* Host Bus error detect */
+#define INT_VEC_DMA8      IVEC_TO_INUM(INT_LVL_DMA8)     /* M2M */
+#define INT_VEC_RES1      IVEC_TO_INUM(INT_LVL_RES1)     /* */
+#define INT_VEC_DMA6      IVEC_TO_INUM(INT_LVL_DMA6)     /* ADSL Rx */
+#define INT_VEC_DMA5      IVEC_TO_INUM(INT_LVL_DMA5)     /* ADSL Tx */
+#define INT_VEC_DMA4      IVEC_TO_INUM(INT_LVL_DMA4)     /* EMAC2 Rx */
+#define INT_VEC_DMA3      IVEC_TO_INUM(INT_LVL_DMA3)     /* EMAC2 Tx */
+#define INT_VEC_DMA2      IVEC_TO_INUM(INT_LVL_DMA2)     /* EMAC1 Rx */
+#define INT_VEC_DMA1      IVEC_TO_INUM(INT_LVL_DMA1)     /* EMAC1 Tx */
+#define INT_VEC_RES2      IVEC_TO_INUM(INT_LVL_RES2)     /* */
+#define INT_VEC_RES3      IVEC_TO_INUM(INT_LVL_RES3)     /* */
+#define INT_VEC_DMAC_ERR  IVEC_TO_INUM(INT_LVL_DMAC_ERR) /* DMAC BERROR */
+#define INT_VEC_EMAC1_ERR IVEC_TO_INUM(INT_LVL_EMAC1_ERR)/* EMAC1 error */
+#define INT_VEC_EMAC2_ERR IVEC_TO_INUM(INT_LVL_EMAC2_ERR)/* EMAC2 error */
+#define INT_VEC_ADSL_ERR  IVEC_TO_INUM(INT_LVL_ADSL_ERR) /* Upstream CMAC error */
+#define INT_VEC_RES4      IVEC_TO_INUM(INT_LVL_RES4)     /* */
+#define INT_VEC_RES5      IVEC_TO_INUM(INT_LVL_RES5)     /* */
+#define INT_VEC_GPIO      IVEC_TO_INUM(INT_LVL_GPIO)     /* GPIO input */
+#define INT_VEC_RES6      IVEC_TO_INUM(INT_LVL_RES6)     /* */
+#define INT_VEC_COMMTX    IVEC_TO_INUM(INT_LVL_COMMTX)   /* ARM9 Comms Xmit */
+#define INT_VEC_COMMRX    IVEC_TO_INUM(INT_LVL_COMMRX)   /* ARM9 Comms Rcv */
+#define INT_VEC_SW0       IVEC_TO_INUM(INT_LVL_SW0)      /* Software interrupt 0 */
+#define INT_VEC_SW1       IVEC_TO_INUM(INT_LVL_SW1)      /* Software interrupt 1 */
+#define INT_VEC_SW2       IVEC_TO_INUM(INT_LVL_SW2)      /* Software interrupt 2 */
+#define INT_VEC_SW3       IVEC_TO_INUM(INT_LVL_SW3)      /* Software interrupt 3 */
+
+/* definition for UART structure */
+#define UART_REG_ADDR_INTERVAL  2               /* registers 2 bytes apart */
+/*
+ * definitions for the CNXT Timer:
+ * two timers clocked from same source and with the same reload overhead
+ */
+#define CNXT_TIMER_BASE             0x00350020  /* Address of base of timer */
+#define CNXT_TIMER_SYS_TC_DISABLE   0x0         /* 0 Written to TIM_LIM1 shuts off timer    */
+/* Paul: Must revisit */
+#define CNXT_TIMER_SYS_TC_ENABLE    0x411A      /* TIM_LIM1 sets 16.7 ms timer  */
+#define CNXT_TIMER_AUX_TC_DISABLE   0x0         /* 0 Written to TIM_LIM2 shuts off timer    */
+#define CNXT_TIMER_AUX_TC_ENABLE    0x2710      /* TIM_LIM2 sets 10 ms timer  */
+
+#define CNXT_CLK_SPEED   1000000                /* Timer speed is 1 microsecond*/
+#define SYS_TIMER_CLK   (CNXT_CLK_SPEED)        /* Frequency of counter/timer*/
+#define AUX_TIMER_CLK   (CNXT_CLK_SPEED)        /* Frequency of counter/timer*/
+
+#define CNXT_RELOAD_TICKS       3               /* three ticks to reload timer*/
+
+#define SYS_TIMER_CLEAR(x)      (CNXT_TIMER_T1CLEAR(x)) /* sys Clk is timer 1 */
+#define SYS_TIMER_CTRL(x)       (CNXT_TIMER_T1CTRL(x))
+#define SYS_TIMER_LOAD(x)       (CNXT_TIMER_T1LOAD(x))
+#define SYS_TIMER_VALUE(x)      (CNXT_TIMER_T1VALUE(x))
+#define CNXT_TIMER_VALUE_MASK   0xFFFF
+#define AUX_TIMER_CLEAR(x)      (CNXT_TIMER_T2CLEAR(x)) /* aux Clk is timer 2 */
+#define AUX_TIMER_CTRL(x)       (CNXT_TIMER_T2CTRL(x))
+#define AUX_TIMER_LOAD(x)       (CNXT_TIMER_T2LOAD(x))
+#define AUX_TIMER_VALUE(x)      (CNXT_TIMER_T2VALUE(x))
+
+
+/*
+*   Added data defines for CNXT registers
+*/
+
+/*  Bit Defines         */
+#define BIT0             0x00000001
+#define BIT1             0x00000002
+#define BIT2             0x00000004
+#define BIT3             0x00000008
+#define BIT4             0x00000010
+#define BIT5             0x00000020
+#define BIT6             0x00000040
+#define BIT7             0x00000080
+#define BIT8             0x00000100
+#define BIT9             0x00000200
+#define BIT10            0x00000400
+#define BIT11            0x00000800
+#define BIT12            0x00001000
+#define BIT13            0x00002000
+#define BIT14            0x00004000
+#define BIT15            0x00008000
+#define BIT16            0x00010000
+#define BIT17            0x00020000
+#define BIT18            0x00040000
+#define BIT19            0x00080000
+#define BIT20            0x00100000
+#define BIT21            0x00200000
+#define BIT22            0x00400000
+#define BIT23            0x00800000
+#define BIT24            0x01000000
+#define BIT25            0x02000000
+#define BIT26            0x04000000
+#define BIT27            0x08000000
+#define BIT28            0x10000000
+#define BIT29            0x20000000
+#define BIT30            0x40000000
+#define BIT31            0x80000000
+
+/*  Interrupts          */
+#define INT_SW3         BIT31   /*  Software interrupt  */
+#define INT_SW2         BIT30   /*  Software interrupt  */
+#define INT_SW1         BIT29   /*  Software interrupt  */
+#define INT_SW0         BIT28   /*  Software interrupt  */
+#define INT_COMMRX      BIT27   /*  ARM9 Comms Receive buffer contains data  */
+#define INT_COMMTX      BIT26   /*  ARM9 Comms Transmit buffer is empty      */
+#define INT_RES6        BIT25   /* */
+#define INT_GPIO        BIT24   /*  GPIO input interrupt  */
+#define INT_RES5        BIT23   /* */
+#define INT_RES4        BIT22   /* */
+#define INT_ADSL_ERR    BIT21   /*  ADSL error   */
+#define INT_EMAC1_ERR   BIT20   /*  EMAC1 error detected */
+#define INT_EMAC2_ERR   BIT19   /*  EMAC2 error detected */
+#define INT_DMAC_ERR    BIT18   /*  DMAC error detected  */
+#define INT_RES3        BIT17   /* */
+#define INT_RES2        BIT16   /* */
+#define INT_DMA1        BIT15   /*  EMAC2 Tx  */
+#define INT_DMA2        BIT14   /*  EMAC2 Rx  */
+#define INT_DMA3        BIT13   /*  EMAC1 Tx  */
+#define INT_DMA4        BIT12   /*  EMAC1 Rx  */
+#define INT_DMA5        BIT11   /*  ADSL Tx   */
+#define INT_DMA6        BIT10   /*  ADSL Rx   */
+#define INT_RES1        BIT9    /* */
+#define INT_DMA8        BIT8    /*  M2M Dst DMA xfer complete           */
+#define INT_HOST_ERR    BIT7    /*  External host encountered bus error */
+#define INT_HOST        BIT6    /*  External host writes to H_INT       */
+#define INT_RES0        BIT5    /* */
+#define INT_USB         BIT4    /*  USB interrupt */
+
+#define INT_TM4         BIT3    /*  Reserved                            */
+#define INT_TM3         BIT2    /*  Timer 3 interrupt                   */
+#define INT_TM2         BIT1    /*  Timer 2 interrupt                   */
+#define INT_TM1         BIT0    /*  Timer 1 interrupt                   */
+
+#define HW_REG_READ(x,result) \
+ 	     ((result) = *(volatile UINT32 *)(x))
+
+#define HW_REG_WRITE(x,data) \
+	     (*((volatile UINT32 *)(x)) = (data))
+
+#endif  /* CNXTBSP_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/cnxtflash.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cnxtflash.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/cnxtflash.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cnxtflash.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,131 @@
+/****************************************************************************
+ *
+ *  Name:		cnxtflash.h
+ *
+ *  Description:	Flash programmer header file
+ *
+ *  Copyright (c) 1999-2002 Conexant Systems, Inc.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License version 2 as
+ *	published by the Free Software Foundation.
+ *
+ *
+ ***************************************************************************/
+#ifndef _FLASH_H_
+#define _FLASH_H_
+
+#define CNXT_FLASH_MAX_NAME_LEN	20
+
+typedef enum CNXT_FLASH_SEGMENTS 
+{
+	CNXT_FLASH_SEGMENT_1 = 0,
+	CNXT_FLASH_SEGMENT_2 = 1,
+	CNXT_FLASH_SEGMENT_3 = 2,
+	CNXT_FLASH_SEGMENT_4 = 3,
+	CNXT_FLASH_SEGMENT_5 = 4,
+	CNXT_FLASH_SEGMENT_6 = 5,
+	CNXT_FLASH_SEGMENT_7 = 6,
+	CNXT_FLASH_SEGMENT_8 = 7,
+	CNXT_FLASH_SEGMENT_9 = 8,
+	CNXT_FLASH_SEGMENT_10 = 9,
+	CNXT_FLASH_SEGMENT_11 = 10,
+	CNXT_FLASH_SEGMENT_12 = 11,
+	CNXT_FLASH_SEGMENT_13 = 12,
+	CNXT_FLASH_SEGMENT_14 = 13,
+	CNXT_FLASH_SEGMENT_15 = 14,
+	CNXT_FLASH_SEGMENT_16 = 15
+
+} CNXT_FLASH_SEGMENT_E;
+
+typedef enum CNXT_FLASH_OWNERS
+{
+	CNXT_FLASH_OWNER_1 = 0,
+	CNXT_FLASH_OWNER_2 = 1,
+	CNXT_FLASH_OWNER_3 = 2,
+	CNXT_FLASH_OWNER_4 = 3,
+	CNXT_FLASH_OWNER_5 = 4,
+	CNXT_FLASH_OWNER_6 = 5,
+	CNXT_FLASH_OWNER_7 = 6,
+	CNXT_FLASH_OWNER_8 = 7,
+	CNXT_FLASH_OWNER_9 = 8,
+	CNXT_FLASH_OWNER_10 = 9,
+	CNXT_FLASH_OWNER_11 = 10,
+	CNXT_FLASH_OWNER_12 = 11,
+	CNXT_FLASH_OWNER_13 = 12,
+	CNXT_FLASH_OWNER_14 = 13,
+	CNXT_FLASH_OWNER_15 = 14,
+	CNXT_FLASH_UNUSED = 15
+} CNXT_FLASH_OWNER_E;
+
+typedef enum CNXT_FLASH_STATUS
+{
+	CNXT_FLASH_SUCCESS,
+	CNXT_FLASH_DATA_ERROR,
+	CNXT_FLASH_OWNER_ERROR,
+#ifdef CONFIG_BD_TIBURON
+	CNXT_FLASH_DATA_CRC_ERROR,
+	CNXT_FLASH_DATA_SIZE_ERROR
+#endif
+} CNXT_FLASH_STATUS_E;
+
+typedef struct CNXT_FLASH_SEGMENT
+{
+	CNXT_FLASH_SEGMENT_E 	segmentNumber;		
+	DWORD			segmentSize;
+	DWORD			startFlashAddress;
+	DWORD			startDataAddress;
+	CNXT_FLASH_OWNER_E	owner;	
+	DWORD			version;
+	DWORD			reserved1;
+	DWORD			reserved2;
+	DWORD			dataLength;
+	DWORD 			headerCRC;
+	DWORD			dataCRC;
+} CNXT_FLASH_SEGMENT_T, *PCNXT_FLASH_SEGMENT_T;
+
+CNXT_FLASH_STATUS_E CnxtFlashOpen( CNXT_FLASH_SEGMENT_E segment );
+
+BOOL CnxtFlashReadRequest( 
+	CNXT_FLASH_SEGMENT_E segment, 
+	UINT16 * psdramStartAddr, 
+	UINT32 size 
+);
+
+BOOL CnxtFlashWriteRequest( 
+	CNXT_FLASH_SEGMENT_E segment, 
+	UINT16 * psdramStartAddr, 
+	UINT32 size 
+);
+
+
+#define CNXT_BSP_FLASH_SEGMENT	CNXT_FLASH_SEGMENT_1
+
+#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+#define CNXT_ADSL_FLASH_SEGMENT		CNXT_FLASH_SEGMENT_2
+#elif CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE
+#define CNXT_DSL_FLASH_SEGMENT	CNXT_FLASH_SEGMENT_2
+#endif
+
+#if CONFIG_CNXT_VOIP || CONFIG_CNXT_VOIP_MODULE
+#define CNXT_VOIP_FLASH_SEGMENT		CNXT_FLASH_SEGMENT_3
+#endif
+
+#define CNXT_TESLA_FLASH_SEGMENT	CNXT_FLASH_SEGMENT_4
+
+#if CONFIG_CNXT_WLAN || CONFIG_CNXT_MODULE
+#define CNXT_WLAN_FLASH_SEGMENT		CNXT_FLASH_SEGMENT_5
+#endif
+
+#define CNXT_BSPBOOT_FLASH_SEGMENT	CNXT_FLASH_SEGMENT_6
+
+#if CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE
+#define CNXT_GSHDSL_FLASH_SEGMENT	CNXT_FLASH_SEGMENT_7
+#endif
+
+#endif 
+
+
+
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/cnxtirq.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cnxtirq.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/cnxtirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cnxtirq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,44 @@
+/****************************************************************************
+*
+*	Name:			cnxtirq.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:28:30  $
+****************************************************************************/
+
+
+#ifndef CNXTIRQ_H
+#define CNXTIRQ_H
+
+#define INTLOCK() intLock()
+#define INTUNLOCK(a) intUnlock(a)
+
+void intUnlock( int oldlevel );
+UINT32 intLock( void );
+
+void PICClearIntStatus(UINT32 IntSource);
+BOOL intContext( void );
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/cnxt_module.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cnxt_module.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/cnxt_module.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cnxt_module.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,43 @@
+/****************************************************************************
+*
+*	Name:			cnxt_module.h
+*
+*	Description:	Header file for adsl intermodule communication
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+*****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:28:30  $
+****************************************************************************/
+
+#ifndef __CNXT_MODULE_H
+#define __CNXT_MODULE_H
+
+typedef struct _CNXT_ADSL_EXPORTS_T
+{
+	PCARDAL_CONTEXT_T (*pcardALCfgInit)		( void *, PTIG_USER_PARAMS );
+	BOOL				(*pCdalADSLModulation)	( PCARDAL_CONTEXT_T , HW_IO_MODULATION_T * );
+	BOOL				(*pcardALHwIoDpGetAdslTransceiverStatus)( PCARDAL_CONTEXT_T , PHW_IO_TRANSCEIVER_STATUS_T ); 
+
+} CNXT_ADSL_EXPORTS_T, *pCNXT_ADSL_EXPORTS_T;
+
+#define	CNXT_ADSL	"cnxt_adsl"
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/cnxtsio.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cnxtsio.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/cnxtsio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cnxtsio.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,75 @@
+/****************************************************************************
+*
+*	Name:			cnxtsio.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 - 2003 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   belljl  $
+*  $Revision:   1.1  $
+*  $Modtime:   Aug 08 2003 18:05:12  $
+****************************************************************************/
+#ifndef CNXT_SIO_H
+#define CNXT_SIO_H
+
+#include "bspcfg.h"
+
+#if defined (CONFIG_BD_HASBANI)
+	#define SERIALPORT1 0x002C0010
+#elif defined (CONFIG_BD_MACKINAC)
+	#define SERIALPORT1 0x00290000
+#elif defined (CONFIG_BD_RUSHMORE)
+	#define SERIALPORT1 0x002C0010
+#elif defined (CONFIG_BD_STARFIRE)
+	#define SERIALPORT1 0x002C0010
+#else
+	#define 0x00000000
+#endif
+
+
+#define SIZE_OF_UART_FIFO	512
+
+typedef struct
+{
+
+	UINT16	get_idx;
+	UINT16	put_idx;
+	UINT16	entry_cnt;
+	UINT16	fill;		// Dword align the structure
+	BYTE	fifo[ SIZE_OF_UART_FIFO ];
+} UART_FIFO_T;
+
+
+
+
+
+typedef struct CnxtUart
+{
+	UINT32		  regAddr;
+	UINT8		* regs;
+	UART_FIFO_T	  xmtr_uart_fifo;
+	UART_FIFO_T	  rcvr_uart_fifo;
+} CNXT_UART;
+
+eUARTType spUartDevInit( CNXT_UART * pUARTChan);
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/cnxttimer.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cnxttimer.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/cnxttimer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/cnxttimer.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,62 @@
+/****************************************************************************
+*
+*	Name:			cnxttimer.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002, 2004 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   lewisrc  $
+*  $Revision:   1.3  $
+*  $Modtime:   Jul 18 2003 11:01:22  $
+****************************************************************************/
+
+#ifndef CNXTTIMER_H
+#define CNXTTIMER_H
+
+
+// There are 4 hardware timers (at least for most network processors).
+// The first one is dedicated for the Linux system clock and handled by special
+// purpose code elsewhere. That leaves us 3 hardware timers for other purposes.
+typedef enum
+{
+	HW_PROG_TIMER_LINUX,	// Reserved for Linux - note it here - not handled by cnxttimer.c
+	HW_PROG_TIMER_GP,		// Used to generate general purpose timers
+	HW_PROG_TIMER_SPARE_1,	// If you need this timer, rename it to reflect its usage (even if you create your own handlers)
+	HW_PROG_TIMER_SPARE_2,	// If you need this timer, rename it to reflect its usage (even if you create your own handlers)
+
+	NUM_PROG_HW_TIMERS
+} HW_TIMER_T ;
+
+#define ETMRNRDY	1	// Error - Timer: Not Ready
+#define ETMRBUSY	2	// Error - Timer: Busy
+#define ETMRIDLE	2	// Error - Timer: Idle
+
+typedef void (*PTMR_CALLBACK) ( WORD ElapsedTime, void *pContext ) ;
+
+int		CnxtTimerEnable	( HW_TIMER_T TimerIndex, PTMR_CALLBACK pCallback ) ;
+int		CnxtTimerDisable( HW_TIMER_T TimerIndex ) ;
+int		CnxtTimerStart	( HW_TIMER_T TimerIndex, WORD TimerValue, void *pContext ) ;
+int		CnxtTimerStop	( HW_TIMER_T TimerIndex ) ;
+LONG	CnxtTimerRead	( HW_TIMER_T TimerIndex ) ;
+
+
+#endif	/* CNXTTIMER_H */
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/CommonData.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/CommonData.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/CommonData.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/CommonData.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+**	FILE NAME:
+**		CommonData.h
+**
+**	ABSTRACT:
+**		This file contains type definitions and structures that are common
+**		between the application and the driver
+**
+**
+*******************************************************************************
+**
+**  Copyright 1997-2003 Conexant Systems, Inc.
+**
+*******************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+*******************************************************************************
+** KEYWORDS:
+**	$Archive:   S:/Embedded/archives/Linux/BSP_CX821xx/uClinux2.4.6/linux/include/asm-armnommu/arch-cx821xx/CommonData.h-arc  $
+**	$Revision:   1.1  $
+**	$Date:   Jun 30 2003 16:05:06  $
+*******************************************************************************
+******************************************************************************/
+
+#ifndef _COMMON_DATA_H_
+#define  _COMMON_DATA_H_
+
+
+/*******************************************************************************
+	AUTOSENSE
+*******************************************************************************/
+// these must match values in xcvrinfo.h which is a DMT core file which can't
+// on the Linux shared file directory and naming structure
+#define AUTOSENSE_WIRING_COMBO_MAX_NUM_COMBO	4	// maximum number of combinations of relay settings
+#define AUTOSENSE_WIRING_COMBO_MAX_NUM_GPIO		4	// maximum number of GPIOs that must be asserted to select a relay combo
+
+
+/*******************************************************************************
+	PHYSICAL DRIVER TYPE
+*******************************************************************************/
+#define NO_VENDOR_ID				0xFFFF
+#define NO_DEVICE_ID				0xFFFF
+#define NO_PHYSICAL_DRIVER			0
+#define PHYSICAL_DRIVER_TIGRIS		1
+#define PHYSICAL_DRIVER_YUKON		2
+
+#define NUM_ADSL_OPTIONS		20
+
+typedef enum PHYSICAL_DRIVER_TYPE_E
+{
+	DRIVER_TYPE_NONE	= NO_PHYSICAL_DRIVER,
+	DRIVER_TYPE_TIGRIS	= PHYSICAL_DRIVER_TIGRIS,
+	DRIVER_TYPE_YUKON	= PHYSICAL_DRIVER_YUKON
+} PHYSICAL_DRIVER_TYPE_T;
+
+
+
+
+
+/*******************************************************************************
+	IO control commands
+*******************************************************************************/
+
+/* Define generic DSL ioctls */
+#define DSL_MAGIC '%'
+
+#define DSL_SET_PARAMS		_IOW(DSL_MAGIC, 1, struct atmif_sioc)
+#define DSL_GET_PARAMS		_IOW(DSL_MAGIC, 2, struct atmif_sioc)
+#define DSL_OAM_INIT		_IOW(DSL_MAGIC, 3, struct atmif_sioc)
+#define DSL_OAM_RESP		_IOW(DSL_MAGIC, 4, struct atmif_sioc)
+#define DSL_AAL5_VC_STATS	_IOW(DSL_MAGIC, 5, struct atmif_sioc)
+#define DSL_ATM_VC_STATS	_IOW(DSL_MAGIC, 6, struct atmif_sioc)
+
+/* TIG values are here for backwards compatibility */
+#define TIGR_MAGIC 			DSL_MAGIC
+
+#define TIG_SET_PARAMS		DSL_SET_PARAMS	
+#define TIG_GET_PARAMS		DSL_GET_PARAMS	
+#define TIG_OAM_INIT		DSL_OAM_INIT	
+#define TIG_OAM_RESP		DSL_OAM_RESP	
+#define TIG_AAL5_VC_STATS	DSL_AAL5_VC_STATS
+#define TIG_ATM_VC_STATS	DSL_ATM_VC_STATS
+
+
+#define NUM_LOG_PARMS 6
+#define NUM_LOG_ENTRIES (2*1000)
+
+
+/*******************************************************************************
+	TIG_GET_PRINT_BUFF
+*******************************************************************************/
+
+typedef struct
+{
+	char		*pFormat ;	// NULL terminates list
+	DWORD		Data[NUM_LOG_PARMS] ;
+} LOG_ENTRY_T ;
+
+typedef struct
+{
+	BOOLEAN		 Cumulative ;			// Cumulative vs Delta (only those lines since last read)
+	char		*pString_Buffer ;		// holds multiple strings
+	DWORD		 String_Buffer_Size ;	// size in bytes
+
+	LOG_ENTRY_T *pBuff ;
+	DWORD		 Buff_Size ;
+} TIG_PRINT_DESC ;
+
+
+
+/*******************************************************************************
+	TIG_GET_DEBUG_DATA
+*******************************************************************************/
+typedef struct
+{
+	DWORD		 Data[16] ;
+} TIG_DEBUG_DATA_DESC ;
+
+
+
+/*******************************************************************************
+	TIG_LOAD_RECORD
+*******************************************************************************/
+// Intel 32 hex data record definitions
+#define DATA_REC			0
+#define EXT_SEG_ADDR_REC	2
+#define EXT_LIN_ADDR_REC	4
+#define EXT_END_OF_FILE		1
+#define EXT_GOTO_CMD_REC	3
+
+
+// record format for transfer to the driver
+typedef struct TIG_LOAD_RECORD_S
+{
+	DWORD		CommandStatus;
+	USHORT		RecordType; // type field from the record
+	DWORD		RecordAddress;  // store address for the record
+	DWORD		RecordLength;  // byte length not including the header - 4096 max
+	char		RecordData [1]; // first byte of the record data
+} TIG_LOAD_RECORD_T;
+
+
+
+/*******************************************************************************
+	TIG_DEVICE_SPEC
+*******************************************************************************/
+// wrapper for device specific IOCTL
+typedef struct TIG_DEVICE_SPEC_S
+{
+	DWORD		CommandStatus;
+	ULONG		RequiredSize;	// number of bytes required for the response.
+	ULONG		ReturnSize;		// number of bytes returned
+	char		BackDoorBuf [1];	// command specific data area
+} TIG_DEVICE_SPEC_T;
+
+
+
+/*******************************************************************************
+	TIG_SET_PARAMS
+*******************************************************************************/
+//
+// User configurable parameters structure
+//
+typedef struct _TIG_USER_PARAMS_
+{
+#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+	// Chip abstraction layer settings
+	unsigned long	RxMaxLatency;
+	unsigned long	RxMinLatency;
+	unsigned long	TxMaxLatency;
+	unsigned long	TxMinLatency;
+	unsigned long	RxInterruptRate;
+	unsigned long	TxInterruptRate;
+	unsigned long	RxSpeed;
+	unsigned long	TxSpeed;
+
+	unsigned long	AutoSenseHandshake;
+	unsigned long	AutoSenseWiresFirst;
+	unsigned long	AutoWiringSelection;
+	unsigned long	AutoWiringRelayDelay;
+	unsigned long	AutoWiringRelayEnrg;
+	unsigned long	AutoWiringNumCombos;
+	unsigned char	AutoWiringComboGPIO [AUTOSENSE_WIRING_COMBO_MAX_NUM_COMBO][AUTOSENSE_WIRING_COMBO_MAX_NUM_GPIO];
+	unsigned char	AutoWiringOrder[AUTOSENSE_WIRING_COMBO_MAX_NUM_COMBO];
+
+	unsigned long	AdslHeadEnd;
+	unsigned long	AdslHeadEndEnvironment;
+	unsigned long	LineAutoActivation;
+	unsigned long	VendorNearId;
+#endif
+
+	// Buffer management settings
+	unsigned long	RXBufAllocLimit;
+	unsigned long	RXBufRatioLimit;
+	unsigned long	RxMaxFrameSize;
+	unsigned long	TxMaxFrameSize;
+	unsigned long	MaxTransmit;
+
+	// Frame abstraction settings
+	unsigned long	RfcEncapsulationMode;
+	unsigned long	CellBurstSize;
+	unsigned long	PeakCellRate;
+
+	unsigned long	OverrideMacAddress;
+	unsigned char	MACAddress[6];
+
+	unsigned long	SendOAMCell;
+
+#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+	unsigned short	AdslOptions[NUM_ADSL_OPTIONS];
+#endif
+
+}TIG_USER_PARAMS, *PTIG_USER_PARAMS;
+
+
+
+
+#endif //  _COMMONDATA_H_
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/Common.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/Common.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/Common.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/Common.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,188 @@
+/****************************************************************************
+*
+*	Name:			Common.h
+*
+*	Description:	Common types and structures used in the system
+*
+*	Copyright:		(c) 1997 - 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+** $Archive:   S:/Embedded/archives/Linux/BSP_CX821xx/uClinux2.4.6/linux/include/asm-armnommu/arch-cx821xx/Common.h-arc  $
+** $Revision:   1.0  $
+** $Date:   Mar 19 2003 13:48:58  $
+*******************************************************************************
+******************************************************************************/
+#ifndef _COMMON_H_		//	File Wrapper,
+#define _COMMON_H_		//	prevents multiple inclusions
+
+
+/*******************************************************************************
+**                              Keywords
+*******************************************************************************/
+#define LOCAL static					/* Used only in the current file */
+#define MODULAR							/* Used only in the current module */
+#define GLOBAL							/* Used inter module */
+
+#define IN								/* Used to denote input arguments */
+#define OUT								/* Used to denote output arguments */
+#define I_O								/* Used to denote input/output arguments */
+
+
+/*******************************************************************************
+**                              Macros
+*******************************************************************************/
+
+#define NOT_USED(x)  (x) = (x)
+
+
+
+////////////////////////////
+//	
+////////////////////////////
+
+//define OFF						0
+//define ON						1
+#ifdef OS_NONE
+	#include "OsDefs.h"	// OsTools.h includes linux files - we only need OsTools.h types
+	#include <stddef.h>	//size_t
+#else
+	#include <asm/arch/OsTools.h>
+#endif
+
+#if 0
+#ifndef __MODEM_H_
+#if !defined( BOOL)
+typedef BOOLEAN BOOL;
+#endif
+
+typedef enum 
+{
+OFF,
+ON
+} BINARY;
+
+
+typedef unsigned char			BYTE;		/* 8-bit unsigned integer  */
+typedef unsigned short			WORD;		/* 16-bit unsigned integer */
+typedef unsigned long			DWORD;		/* 32-bit unsigned integer */
+
+typedef signed char				CHAR;	    /* 8-bit signed integer  */
+typedef signed short int		SHORT;	    /* 16-bit signed integer */
+typedef signed long int			LONG;	    /* 32-bit signed integer */
+
+#endif
+
+#else
+typedef int BINARY;
+#endif
+
+#ifndef BSPTYPES_H
+	//
+	// Bit mask
+	//
+	#define BIT0			0x01
+	#define BIT1			0x02
+	#define BIT2			0x04
+	#define BIT3			0x08
+	#define BIT4			0x10
+	#define BIT5			0x20
+	#define BIT6			0x40
+	#define BIT7			0x80
+#endif
+
+/* 	The va_names type match the type name after promotion, These can be used with 
+**	the va functions to get the correct size variable off the stack. 
+*/
+
+typedef BOOLEAN VA_BOOL;
+
+typedef BINARY VA_BINARY;
+
+typedef unsigned char			VA_BYTE;		  /* 8-bit unsigned integer  */
+typedef unsigned short			VA_WORD;		  /* 16-bit unsigned integer */
+typedef unsigned long			VA_DWORD;		  /* 32-bit unsigned integer */
+
+typedef signed char				VA_CHAR;		  /* 8-bit signed integer  */
+typedef signed short int		VA_SHORT;		  /* 16-bit signed integer */
+typedef signed long int			VA_LONG;		  /* 32-bit signed integer */
+
+
+//
+// Bit clear mask
+//
+#define BIT0_CLEAR		0xFE
+#define BIT1_CLEAR		0xFD
+#define BIT2_CLEAR		0xFB
+#define BIT3_CLEAR		0xF7
+#define BIT4_CLEAR		0xEF
+#define BIT5_CLEAR		0xDF
+#define BIT6_CLEAR		0xBF
+#define BIT7_CLEAR		0x7F
+
+
+
+// counters to be used for statistics  
+// each counter has a flag to track if the counter has overflowed.
+
+typedef struct
+{
+	BOOL	Overflow ;
+	BYTE	Cnt ;
+} BYTE_CTR_T ;
+
+typedef struct
+{
+	BOOL Overflow ;
+	WORD Cnt ;
+} WORD_CTR_T ;
+
+typedef struct
+{
+	BOOL Overflow ;
+	LONG Cnt ;
+} LONG_CTR_T;
+
+typedef struct
+{
+	BOOL Overflow ;
+	LONGLONG Cnt ;
+} LONGLONG_CTR_T;
+
+
+// Macros used to update statistics counters
+// These macors also check for overflow.
+
+#define ADD_TO_CTR( Ctr, Delta ) \
+	if ( Ctr.Cnt + (Delta) < Ctr.Cnt ) \
+	{ \
+		Ctr.Overflow = TRUE ; \
+	} \
+	Ctr.Cnt += Delta ; 
+
+#define ADD_TO_CTR_IND( CtrPtr, Delta ) \
+	if ( (CtrPtr)->Cnt + (Delta) < (CtrPtr)->Cnt ) \
+	{ \
+		(CtrPtr)->Overflow = TRUE ; \
+	} \
+	(CtrPtr)->Cnt += Delta ;
+
+// Returns size in bytes rounded up to the nearest DWORD
+#define SIZEOF_DWORD_ALIGN(n)	((sizeof(n) + 3) >> 2 << 2)
+//#pragma intrinsic(memcmp)
+#endif		//#ifndef _COMMON_H_
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/ConfigLabels.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/ConfigLabels.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/ConfigLabels.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/ConfigLabels.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,145 @@
+/******************************************************************************
+*******************************************************************************
+**
+**	FILE NAME:
+**		ConfigLabels.h
+**
+**	ABSTRACT:
+**		This file contains definitions for the labels from the config file.
+**
+********************************************************************************
+**	Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Conexant Systems, Inc.
+**	(formerly Rockwell Semiconductor Systems)
+********************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+*******************************************************************************
+*******************************************************************************
+** KEYWORDS:
+**	$Archive:   S:/Embedded/archives/Linux/BSP_CX821xx/uClinux2.4.6/linux/include/asm-armnommu/arch-cx821xx/ConfigLabels.h-arc  $
+**	$Revision:   1.1  $
+**	$Date:   Jun 30 2003 16:10:56  $
+*******************************************************************************
+******************************************************************************/
+
+#define	RX_MAX_LATENCY            "RxMaxLatency"
+#define	RX_MIN_LATENCY            "RxMinLatency"
+#define	TX_MAX_LATENCY            "TxMaxLatency"
+#define	TX_MIN_LATENCY            "TxMinLatency"
+#define	RX_INTERRUPT_RATE         "RxInterruptRate"
+#define	TX_INTERRUPT_RATE         "TxInterruptRate"
+#define	RX_SPEED                  "RxSpeed"
+#define	TX_SPEED                  "TxSpeed"
+#define	RX_FIFO_SIZE              "RxFifoSize"
+#define	TX_FIFO_SIZE              "TxFifoSize"
+#define	RX_CHANNEL_SIZE           "RxChannelSize"
+#define	RX_SEGMENTS               "RxSegments"
+#define	TX_CHANNEL_SIZE           "TxChannelSize"
+#define	TX_SEGMENTS               "TxSegments"
+#define	ADSL_PSD_TEST_MODE        "AdslPsdTestMode"
+#define	LINE_PERSISTENT_ACT       "LinePersistentAct"
+#define	LINE_PERSISTENCE_TMR      "LinePersistenceTmr"
+#define	RX_BUF_ALLOC_LIMIT        "RXBufAllocLimit"
+#define	RX_BUF_RATIO_LIMIT        "RXBufRatioLimit"
+#define	RX_MAX_FRAME_SIZE         "RxMaxFrameSize"
+#define	TX_MAX_FRAME_SIZE         "TxMaxFrameSize"
+#define	MAX_TRANSMIT              "MaxTransmit"
+#define	RFC_ENCAPSULATION_MODE    "RfcEncapsulationMode"
+#define	CELL_BURST_SIZE           "CellBurstSize"
+#define	PEAK_CELL_RATE            "PeakCellRate"
+#define	CONTROLLER_LOG_ENABLE     "ControllerLogEnable"
+#define	CAPABILITIES_G922         "CapabilitiesG922"
+#define	CAPABILITIES_G922_ANNEX   "CapabilitiesG922Annex"
+#define AUTO_SENSE_HANDSHAKE      "AutoSenseHandshake"
+#define AUTO_SENSE_WIRES_FIRST    "AutoSenseWiresFirst"
+#define AUTO_WIRING_SELECTION     "AutoWiringSelection"
+#define AUTO_WIRING_RELAY_DELAY	  "AutoWiringRelayDelay"
+#define AUTO_WIRING_RELAY_ENRG    "AutoWiringRelayEnrg"
+#define AUTO_WIRING_NUM_COMBOS    "AutoWiringNumCombos"
+#define AUTO_WIRING_COMBO_GPIO    "AutoWiringComboGPIO"
+#define AUTO_WIRING_ORDER         "AutoWiringOrder"
+#define	LINE_AUTO_ACTIVATION      "LineAutoActivation"
+#define	ADSL_HEAD_END             "AdslHeadEnd"
+#define	ADSL_HEAD_END_ENVIRONMENT "AdslHeadEndEnvironment"
+#define	VENDOR_NEAR_ID            "VendorNearId"
+#define	DEBUG_FLAG                "DebugFlag"
+#define	API_HWIF_MODE             "ApiHwIfMode"
+#define	OVERRIDE_MAC_ADDRESS      "OverrideMacAddress"
+#define MAC_ADDRESS               "MACAddress"
+#define	AUTOLOG_ENABLED           "AutoLogEnabled"
+#define AUTOLOG_PATH              "AutoLogPath"
+#define	AUTOLOG_MAX_FILE_SIZE     "AutoLogMaxFileSize"
+#define	AUTOLOG_UPDATE_FREQUENCY  "AutoLogUpdateFrequency"
+#define	AUTOLOG_OVERWRITE         "AutoLogOverwrite"
+#define ARM_HW_ID                 "ARMHwId"
+#define ADSL_HW_ID                "ADSLHwId"
+#define ARM_FUNCTION_IDENTIFIER   "ARMFunctionIdentifier"
+#define ADSL_FUNCTION_IDENTIFIER  "ADSLFunctionIdentifier"
+#define HW_DEBUG_FLAG             "HwDebugFlag"
+#define PHYSICAL_DRIVER_TYPE      "PhysicalDriverType"
+#define GPIO_ADSL_FUNCTION_MASK   "GpioADSLFunctionMask"
+#define GPIO_ARM_FUNCTION_MASK    "GpioARMFunctionMask"
+#define GPIO_DIRECTION_MASK       "GpioDirectionMask"
+#define GPIO_EDGE_MASK            "GpioEdgeMask"
+#define FIRMWARE_FILENAME         "FirmwareFilename"
+#define ATM_VPI                   "ATM_VPI"
+#define ATM_VCI                   "ATM_VCI"
+#define SEND_OAM_CELL		  "SendOAMCell"
+#define ADSL_OPTIONS		  "ADSL Options"
+
+#define CONFIGURATION_FILENAME    "cnxadsl.conf"
+#define CONFIGURATION_FILE_PATH   "/etc/Conexant/"
+#define SCRATCH_CONF_NAME         "scrtch$$.conf"
+
+/*
+// G.shdsl related labels
+*/
+#define DOWNLOAD_SOURCE				"DownloadSource"
+#define OPERATIONAL_CODE_FILE 		"OperationalCodeFile"
+
+#define TXSOC_WORKAROUND		 	"TXSOCWorkaround"
+
+#define TERMINAL_TYPE				"TerminalType"
+#define DSL_SYSTEM_STATE		 	"DslSystemState"
+
+#define DSL_CONFIGURATION			"DslConfiguration"
+#define FRAME_STRUCTURE				"FrameStructure"
+
+#define DSL_LINE_CODE				"DslLineCode"
+#define BIT_PUMP_TRAINING_MODE		"BitPumpTrainingMode"
+#define PSD_MASK					"PSDMask"
+
+#define PCM_TIME_SLOTS				"PCMTimeSlots"
+#define DSL_TIME_SLOTS				"DslTimeSlots"
+#define OCUPPIED_PCM_TIME_SLOTS		"OccupiedPCMTimeSlots"
+#define PCM_TIME_SLOT_START_LOCATION	"PCMTimeSlotStartLoc"
+#define IBITS						"IBits"
+#define MAINTAIN_DSL_LINK			"MaintainDslLink"
+#define MAPPING_MODE				"MappingMode"
+#define INTERLEAVE_RATIO			"InterleaveRatio"
+
+#define ATM_ONE_SECOND_MASTER_SLAVE_MODE	"Atm1SecMasterSlaveMode"
+#define ATM_SERIAL_INTERFACE_MODE	"AtmSerialInterfaceMode"
+#define ATM_RX_INTERFACE_MODE		"AtmRxInterfaceMode"
+#define ATM_TX_INTERFACE_MODE		"AtmTxInterfaceMode"
+#define ATM_PHY_TC_MODE				"AtmPhyTcMode"
+#define ATM_BYTE_ALIGNMENT			"AtmByteAlignment"
+
+#define ATM_PHY_UTOPIA_BUS_WIDTH	"AtmPhyUtopiaBusWidth"
+#define ATM_PHY_UTOPIA_MODE			"AtmPhyUtopiaMode"
+
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,111 @@
+/****************************************************************************
+*
+*	Name:			dma.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.1  $
+*  $Modtime:   Jan 07 2003 09:53:46  $
+****************************************************************************/
+
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+
+#define MAX_DMA_ADDRESS			0x0F00000
+
+#define EMAC1_TxD_DMA_CH		1
+
+#define DMAC_1_Ptr1				0x300000
+#define DMAC_1_Ptr2				0x300030
+#define DMAC_1_Cnt1				0x300060
+#define DMAC_1_Cnt2				0x300090
+
+#define EMAC1_RxD_DMA_CH		2
+
+#define DMAC_2_Ptr1				0x300004
+#define DMAC_2_Ptr2				0x300034
+#define DMAC_2_Cnt1				0x300064
+#define DMAC_2_Cnt2				0x300094
+
+#define EMAC2_TxD_DMA_CH		3
+
+#define DMAC_3_Ptr1				0x300008
+#define DMAC_3_Ptr2				0x300038
+#define DMAC_3_Cnt1				0x300068
+#define DMAC_3_Cnt2				0x300098
+
+#define EMAC2_RxD_DMA_CH		4
+
+#define DMAC_4_Ptr1				0x30000c
+#define DMAC_4_Ptr2				0x30003c
+#define DMAC_4_Cnt1				0x30006c
+#define DMAC_4_Cnt2				0x30009c
+
+
+#define MAX_DMA_CHANNELS		13
+
+#define arch_dma_init(dma_chan)
+
+//-----------------------------------------------------------------------------
+
+#define DMA_HW_BASE   0x00300000
+
+#define DMA1_PTR1     ((volatile UINT32 *) DMA_HW_BASE)            /* EMAC1 TX */
+#define DMA1_PTR2     ((volatile UINT32 *) (DMA_HW_BASE + 0x30))
+#define DMA1_CNT1     ((volatile UINT32 *) (DMA_HW_BASE + 0x60))
+#define DMA2_PTR1     ((volatile UINT32 *) (DMA_HW_BASE + 0x04))   /* EMAC1 RX */
+#define DMA2_PTR2     ((volatile UINT32 *) (DMA_HW_BASE + 0x34))
+#define DMA2_CNT1     ((volatile UINT32 *) (DMA_HW_BASE + 0x64))
+
+#define DMA3_PTR1     ((volatile UINT32 *) (DMA_HW_BASE + 0x08))   /* EMAC2 TX */
+#define DMA3_PTR2     ((volatile UINT32 *) (DMA_HW_BASE + 0x38))
+#define DMA3_CNT1     ((volatile UINT32 *) (DMA_HW_BASE + 0x68))
+#define DMA4_PTR1     ((volatile UINT32 *) (DMA_HW_BASE + 0x0C))   /* EMAC2 RX */
+#define DMA4_PTR2     ((volatile UINT32 *) (DMA_HW_BASE + 0x3C))
+#define DMA4_CNT1     ((volatile UINT32 *) (DMA_HW_BASE + 0x6C))
+
+#define DMA5_PTR1     ((volatile UINT32 *) (DMA_HW_BASE + 0x10))   /* DSL TX */
+#define DMA5_CNT1     ((volatile UINT32 *) (DMA_HW_BASE + 0x70))
+#define DMA6_PTR1     ((volatile UINT32 *) (DMA_HW_BASE + 0x14))   /* DSL RX */
+#define DMA6_CNT1     ((volatile UINT32 *) (DMA_HW_BASE + 0x74))
+
+#define DMA7_PTR1     ((volatile UINT32 *) (DMA_HW_BASE + 0x18))   /* M2M In (SRC)   */
+#define DMA7_CNT1     ((volatile UINT32 *) (DMA_HW_BASE + 0x78))
+#define DMA8_PTR1     ((volatile UINT32 *) (DMA_HW_BASE + 0x1C))   /* M2M Out (DEST) */
+#define DMA8_CNT1     ((volatile UINT32 *) (DMA_HW_BASE + 0x7C))
+
+
+#define DMA9_PTR1  	 ((volatile UINT32 *) (DMA_HW_BASE + 0x20))   /* USB EP3 TX */
+#define DMA9_CNT1  	 ((volatile UINT32 *) (DMA_HW_BASE + 0x80))
+#define DMA10_PTR1 	 ((volatile UINT32 *) (DMA_HW_BASE + 0x24))   /* USB EP2 TX */
+#define DMA10_CNT1 	 ((volatile UINT32 *) (DMA_HW_BASE + 0x84))
+#define DMA11_PTR1 	 ((volatile UINT32 *) (DMA_HW_BASE + 0x28))   /* USB EP1 TX */
+#define DMA11_CNT1 	 ((volatile UINT32 *) (DMA_HW_BASE + 0x88))
+#define DMA12_PTR1 	 ((volatile UINT32 *) (DMA_HW_BASE + 0x100))  /* USB RX */
+#define DMA12_CNT1 	 ((volatile UINT32 *) (DMA_HW_BASE + 0x110))
+#define DMA13_PTR1 	 ((volatile UINT32 *) (DMA_HW_BASE + 0x104))  /* USB EP0 TX */
+#define DMA13_CNT1 	 ((volatile UINT32 *) (DMA_HW_BASE + 0x114))
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/dmasrv.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/dmasrv.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/dmasrv.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/dmasrv.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,101 @@
+/****************************************************************************
+*
+*	Name:			dmasrv.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:28:30  $
+****************************************************************************/
+
+#ifndef DMASRV_H
+#define DMASRV_H
+
+#define SIMULATION_ENABLE        (1)
+#define DBG_ENABLE_LOOPBACK      (1 && SIMULATION_ENABLE)
+#define DBG_ENABLE_USB_LOOPBACK  (0 && DBG_ENABLE_LOOPBACK)
+
+#ifdef BM_LOOP
+#define DBG_ENABLE_DSL_LOOPBACK  (1 && DBG_ENABLE_LOOPBACK)
+#else
+#define DBG_ENABLE_DSL_LOOPBACK  (0 && DBG_ENABLE_LOOPBACK)
+#endif
+
+#define DBG_ENABLE_USB_TRANSMISSON_SIMULATION      (1 && SIMULATION_ENABLE)
+
+
+#define DMA_BLK_SIZE 56
+
+#define DMA_OPEN  TRUE
+#define DMA_CLOSED   FALSE
+#define DMA_ENABLED  TRUE
+#define DMA_DISBLED  FALSE
+
+enum DMA_CHANNEL_NUM
+{
+   DMA_CHANNEL_EMAC1_TX = 1,
+   DMA_CHANNEL_EMAC1_RX,
+   DMA_CHANNEL_EMAC2_TX,
+   DMA_CHANNEL_EMAC2_RX,
+   DMA_CHANNEL_DSL_TX,
+   DMA_CHANNEL_DSL_RX,
+   DMA_CHANNEL_M2M_IN,
+   DMA_CHANNEL_M2M_OUT,
+   DMA_CHANNEL_USB_TX_EP3,
+   DMA_CHANNEL_USB_TX_EP2,
+   DMA_CHANNEL_USB_TX_EP1,
+   DMA_CHANNEL_USB_TX_EP0,
+   DMA_CHANNEL_USB_RX_EP3,
+   DMA_CHANNEL_USB_RX_EP2,
+   DMA_CHANNEL_USB_RX_EP1,
+   DMA_CHANNEL_USB_RX_EP0,
+   DMA_CHANNEL_MAX
+};
+
+typedef unsigned char (*PDMACALLBACK)(void* pUserData, UINT32* pBuffAddr, UINT32 uBuffSize);
+
+typedef struct tagDMA_CHANNEL
+{
+   unsigned char bOpen;                /* TRUE = channel open, FALSE = closed */
+   unsigned char bEnabled;             /* TRUE = enabled, FALSE = disabled */
+   UINT32* pBuffAddr;         /* Pointer to DMA buffer */
+   UINT32 uBuffSize;          /* DMA buffer size, in bytes */
+   PDMACALLBACK pDMACallback; /* DMA IRQ callback function pointer */
+   void* pUserData;           /* DMA IRQ callback function parameter */
+} DMA_CHANNEL;
+
+extern DMA_CHANNEL DmaChannelTbl[ DMA_CHANNEL_MAX ];
+
+void DmaInit( void );
+BOOL DmaSendBuffer(UINT32 uDMACh, UINT32* pBuffer, UINT32	uBufferSize);
+BOOL DmaEnableChannel( UINT32 uDMACh );
+BOOL DmaDisableChannel( UINT32 uDMACh );
+BOOL DmaOpenChannel( UINT32 uDMACh);
+BOOL DmaCloseChannel( UINT32 uDMACh );
+
+BOOL DMASetCallback( UINT8 uDMACh, PDMACALLBACK pDMACallback, void* pUserData );
+
+BOOL AddDMABufferList ( UINT32 uDMACh,UINT32* pSBuff,UINT32 uBuffSize);
+BOOL DMAFlushChannelBuff(UINT32 uDMACh);
+
+#endif /* DMASRV_H */ 
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/dslbase.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/dslbase.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/dslbase.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/dslbase.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,65 @@
+/*****************************************************************************
+*	$Author:   lewisrc  $
+*	$Revision:   1.1  $
+*	$Modtime:   Apr 01 2003 14:02:26  $
+****************************************************************************/
+
+
+/******************************************************************************/
+/*  Base addresses for P50 memory-mapped peripherals                          */
+/******************************************************************************/
+
+/* P50 registers bases */
+#define FALCONBase			0x280000
+#define	P50ADSLCSRBase		0x34001c
+#define	P50ADSLAFEBase		0x340030
+
+/* Stuff the BSP needs to know to kill Showtime tasks */
+#define SHOWTIME_TASK1_NAME "tDmtHi"
+#define SHOWTIME_TASK2_NAME "tDmtDt"
+#define SHOWTIME_TASK3_NAME "tDmtLo"
+#define SHOWTIME_TASK4_NAME "tDmtLm"
+#define SHOWTIME_TASK5_NAME "tDmtMed"
+
+void FalconScanEnable		(BOOL State);
+BOOL ReadFalconScanEnable	(void);
+void SetGPIOF2PInt			(BOOL value);
+void SetGPIOF2PCS			(BOOL value);
+void LinedriverPower		(BOOL State);
+BOOL ReadLinedriverPower	(void);
+void AFEReset				(BOOL State);
+BOOL ReadAFEReset			(void);
+void FalconReset			(BOOL State);
+BOOL ReadFalconReset		(void);
+void FalconPowerDown		(BOOL State);
+BOOL ReadFalconPowerDown	(void);
+void SetDslRxDataInd		(BOOL value);
+void SetDslTxDataInd		(BOOL value);
+
+void ADSL_CS_Init			(void);
+void SetF2Interrupts
+(
+							void (*(pIRQ1))(void *),
+							void (*(pIRQ2))(void *),
+							void *
+);
+void ADSL_EnableIRQ1_2		(void);
+void ADSL_DisableIRQ1_2		(void);
+void ADSL_EnableIRQ2		(void);
+void ADSL_DisableIRQ2		(void);
+
+void DpResetWiring			(void);
+void DpSetAFEHybridSelect
+(
+	UINT8					Select_Line, 
+	BOOL					State
+);
+BOOL DpReadAFEHybridSelect
+(
+	UINT8					Select_Line
+);
+BOOL DpQueryAnnexPin		(void);
+void DpResetWiring			(void);
+
+BOOL DpSwitchHookStateEnq	(void);
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/dsl.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/dsl.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/dsl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/dsl.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,151 @@
+/****************************************************************************
+ *
+ *  Name:			DSL.h
+ *
+ *  Description:	DSL routine header file
+ *
+ *  Copyright (c) 2001 Conexant
+ *
+ ****************************************************************************
+ *
+ *  $Author:   davidsdj  $
+ *  $Revision:   1.1  $
+ *  $Modtime:   Jan 07 2003 09:53:46  $
+ *
+ ***************************************************************************/
+#ifndef DSL_H
+#define DSL_H
+
+/*********************************************************/
+/* Define the Base addresses of DSL registers            */
+/*********************************************************/
+/* DMA used for DSL */
+#define pDSL_CTRL_DMA	( volatile UINT32* )0x340010
+#define pDSL_TXCC_DMA	( volatile UINT32* )0x340014
+#define pDSL_RXCC_DMA	( volatile UINT32* )0x340018
+#define pDSL_CTRL			( volatile UINT32* )0x34001c
+#define pDSL_ISR			( volatile UINT32* )0x340020
+#define pDSL_IER			( volatile UINT32* )0x340024
+
+#define pDSL_RXCC_DMA2 	( volatile UINT32* )0x340038
+#define pDSL_RXTIMER	( volatile UINT32* )0x34003C
+
+/*********************************************************/
+/* Define DSL registers bit definitions.                 */
+/*********************************************************/
+
+/* Master DSL interrupt mask bit */
+#define Int_DSL_RX_DMA 0x00000400
+#define Int_DSL_TX_DMA 0x00000800
+#define Int_DSL 	   0x00200000
+
+/* DSL Control DMA Reg bit definitions */
+#define DSLCTRDMA_TX_CLRPEND    BIT0
+#define DSLCTRDMA_TX_CLRQWCNT   BIT1
+#define DSLCTRDMA_RX_CLRPEND	  BIT2
+#define DSLCTRDMA_RX_CLRQWCNT   BIT3
+
+/*  These bit will not work if we decide to clear bit with shift position > 23 ( 24 bits shift ) */
+/*  i.e  u &= ~DEFINE_CONST ==> u &= ~(DEFINE_CONST) */
+
+/* DSL Control/Status Reg bit definitions */
+#define DSLCTR_SRESET            BIT0
+#define DSLCTR_IDLE_INSERT       BIT1
+#define DSLCTR_STREAM            BIT2
+#define DSLCTR_AIE				   BIT3
+#define DSLCTR_UNDERRUN_DIRECT   BIT4
+#define DSLCTR_DMAHEADER         BIT10
+#define DSLCTR_DSL_LPBK  			BIT12
+#define DSLCTR_TXENABLE		   	BIT25
+#define DSLCTR_RXENABLE	   		BIT26
+#define DSLCTR_RX_KICK           BIT27
+#define DSLCTR_TX_IDLE				BIT30
+#define DSLCTR_RX_IDLE				BIT31 
+
+/* DSL Interrupt/Status Reg bit definitions */
+#define DSLINT_RX_PKTXFRDONE	   BIT0
+#define DSLINT_RX_OVERRUN			BIT1
+#define DSLINT_RX_PENDFULL       BIT3
+#define DSLINT_TX_PKTXFRDONE	   BIT4
+#define DSLINT_TX_UNDERRUN       BIT5
+#define DSLINT_TX_PENDZERO       BIT7
+#define DSLINT_RX_THRESHOLD		BIT16		
+#define DSLINT_RX_WATCHDOG			BIT17
+
+#define DSLINT_STATUS_MASK       (DSLINT_RX_OVERRUN | DSLINT_TX_UNDERRUN | DSLINT_RX_THRESHOLD | DSLINT_RX_WATCHDOG)
+
+/*********************************************************/
+/* Define DSL DMA buffers map.                           */
+/*********************************************************/
+
+#define DSL_MAX_PACKET_SIZE      56
+#define DSL_DMA_DATA             53
+#define DSL_DMA_BLOCK_DWORDS     ( DSL_MAX_PACKET_SIZE / 4 )
+#define DSL_DMA_BLOCK_QWORDS     ( DSL_MAX_PACKET_SIZE / 8 )
+
+#define DSL_MAX_TX_BUFF          128
+
+#define DSL_TX_LINK_SIZE         8
+#define DSL_TX_FRAME_SIZE        (DSL_MAX_PACKET_SIZE + DSL_TX_LINK_SIZE)
+#define DSL_TXBUFF_SIZE          (DSL_MAX_TX_BUFF * DSL_TX_FRAME_SIZE)
+
+#define DSL_MAX_RXBUFF_SIZE      (DSL_MAX_PACKET_SIZE * 254)
+
+#define DSL_DMA_RAM_START  SRAMSTART
+#define DSL_DMA_RAM_END    SRAMEND
+
+#define pDSL_DMA_TX_BUFF   (volatile UINT32 *) DSL_DMA_RAM_START
+#define pDSL_DMA_RX_BUFF   (volatile UINT32 *) ((UINT8 *) pDSL_DMA_TX_BUFF + DSL_TXBUFF_SIZE)
+
+#define DSL_MAX_RX_BUFF 254
+//#define DSL_MAX_RX_BUFF 128
+
+#define DSL_RXBUFF_SIZE    (DSL_MAX_RX_BUFF * DSL_MAX_PACKET_SIZE)
+
+#define DSL_TIMEOUT_PACKET_TIME  3
+
+/*********************************************************/
+/* Define DSL variables.                                 */
+/*********************************************************/
+
+extern UINT32 DSL_ISR_img;
+extern UINT32 DSL_IER_img;
+extern UINT32 DSL_CTRL_img;
+
+extern UINT32 DSLByteCount;
+extern RXBUFFERSTRUCT DslTxBuffer;
+
+extern RXBUFFERSTRUCT DslRxBuffer;
+
+typedef struct tagDSL_PACKET_RXBLK {
+	volatile UINT32 * ptr;
+	UINT32 ID;
+} DSL_PACKET_RXBLK, *PDSL_PACKET_RXBLK;
+
+extern DSL_PACKET_RXBLK Dsl_Packet_Rxblk[DSL_MAX_RX_BUFF];
+
+/*********************************************************/
+/* Define DSL functions.                                 */
+/*********************************************************/
+
+void SetDSLInterrupts(void);
+BOOL DSLWriteBuffer(volatile UINT32* RxBuff,UINT32 ByteCount);
+void DSL_init(void);
+void InitDSLTxBuffer(void);
+void InitDSLRxBuffer(void);
+
+void DSL_ClearStatus(UINT8 uDMACh);
+void DSL_EnableInterface(UINT8 uDMACh);
+
+void DSL_Enable_Int(UINT8 uDMACh);
+void DSL_Disable_Int(UINT8 uDMACh);
+void DSL_TX_Int(UINT8 IntState);
+void DSL_TXUnderrun_Int(UINT8 IntState);
+void DSL_RX_Int(UINT8 IntState);
+void DSL_RXOverrun_Int(UINT8 IntState);
+void DSLInitRxTimer(void);
+void DSL_RXTimeout_Int(UINT8 IntState);
+void DSL_RXThresh_Int(UINT8 IntState, UINT32 ThresholdLevel);
+UINT32 DSL_DMAEnable(UINT8 uDMACh);
+UINT32 DSL_DMADisable(UINT8 uDMACh);
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/dslisr.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/dslisr.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/dslisr.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/dslisr.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,38 @@
+/****************************************************************************
+ *
+ *  Name:			DSLISR.h
+ *
+ *  Description:	DSL interrupt routines header file
+ *
+ *  Copyright (c) 2001 Conexant
+ *
+ ****************************************************************************
+ *
+ *  $Author:   davidsdj  $
+ *  $Revision:   1.1  $
+ *  $Modtime:   Jan 07 2003 09:53:46  $
+ *
+ ***************************************************************************/
+#ifndef DSLISR_H
+#define DSLISR_H
+
+#define RX_PENDING_ITEM	128
+
+#define DSL_RX_PENDING_FLD    0x0000FF00
+#define DSL_RX_PENDING_SHIFT  8
+
+#define DSL_RXBUFFSIZE_SHIFT  16
+
+/*---------------------------------------------------------------------------
+ *  Module Function Prototypes
+ *-------------------------------------------------------------------------*/
+
+void DSL_ERR_Handler( void);
+void DSL_RX_Handler( void);
+
+void DSL_RX_Overrun_ISR(void);
+void DSL_TX_DMA_ISR( void );
+void DSL_TX_Underrun_ISR(void);
+void DSLRxBufferUpdate(void);
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/gpio.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/gpio.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/gpio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/gpio.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,488 @@
+/****************************************************************************
+*  $Author:   belljl  $
+*  $Revision:   1.4  $
+*  $Modtime:   Aug 08 2003 17:58:16  $
+****************************************************************************/
+/******************************************************************************
+****	Copyright (c) 1999, 2001, 2002, 2003 Conexant Systems, Inc.
+****
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+********************************************************************************
+*******************************************************************************/
+
+#ifndef GPIO_H
+#define GPIO_H
+
+#include "bspcfg.h"
+#include <linux/ptrace.h>
+
+#define LED_ON		0
+#define LED_OFF	1
+
+#define GPIO0	0    /* GPIO0-15 in Register 1 */
+#define GPIO1	1
+#define GPIO2	2
+#define GPIO3	3
+#define GPIO4	4
+#define GPIO5	5
+#define GPIO6	6
+#define GPIO7	7
+#define GPIO8	8
+#define GPIO9	9
+#define GPIO10	10
+#define GPIO11	11
+#define GPIO12	12
+#define GPIO13	13
+#define GPIO14	14
+#define GPIO15	15
+#define GPIO16	16    /* GPIO16-31 in Register 2 */
+#define GPIO17	17
+#define GPIO18	18
+#define GPIO19	19
+#define GPIO20	20
+#define GPIO21	21
+#define GPIO22	22
+#define GPIO23	23
+#define GPIO24	24
+#define GPIO25	25
+#define GPIO26	26
+#define GPIO27	27
+#define GPIO28	28
+#define GPIO29	29
+#define GPIO30	30
+#define GPIO31	31
+#define GPIO32	32    /* GPIO32-39 in Register 3 */
+#define GPIO33	33
+#define GPIO34	34
+#define GPIO35	35
+#define GPIO36	36
+#define GPIO37	37
+#define GPIO38	38
+#define GPIO39	39
+
+/* For Rushmore run-time support, increase default number of GPIO registers in
+   uGPIODefaultValue[]. to 22. If it is not Rushmore device, then the 3 extra registers
+   GPIO_IE(x) will not be initialized */
+#define RUSHMORE_NUM_GPIODEFAULT	22
+#define NUM_OF_GPIODEFAULT       19
+
+#define NUM_GPIOS_PER_REGISTER   16
+
+//************************************************
+// 		GPIO Controller I/O register map
+//************************************************
+
+#ifdef DEVICE_YELLOWSTONE
+#define NUM_OF_GPIOS	   64
+
+#define GPIO_BASE			0x00600C00
+#define GRP0_OFFSET	   0
+#define GRP1_OFFSET	   0x100
+#define GRP2_OFFSET	   0x200
+#define GRP3_OFFSET	   0x300
+
+#define GRP_REG_OFFSET  0x100
+
+#define p_GRP0_OUTPUT_ENABLE		( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x000 )
+#define p_GRP0_INPUT_ENABLE		( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x004 )
+#define p_GRP0_DATA_OUT				( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x008 )
+#define p_GRP0_DATA_IN				( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x00C )
+#define p_GRP0_INT_EVENT_TYPE		( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x020 )
+#define p_GRP0_INT_ENABLE_POS		( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x024 )
+#define p_GRP0_INT_ENABLE_NEG		( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x028 )
+#define p_GRP0_INT_STAT_POS		( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x02C )
+#define p_GRP0_INT_STAT_NEG		( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x030 )
+#define p_GRP0_INT_STAT				( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x034 )
+#define p_GRP0_INT_MASK				( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x038 )
+#define p_GRP0_INT_STAT_MASKED	( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x03C )
+#define p_GRP0_INT_ASSIGN_A		( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x040 )
+#define p_GRP0_INT_ASSIGN_B		( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x044 )
+#define p_GRP0_INT_ASSIGN_C		( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x048 )
+#define p_GRP0_INT_ASSIGN_D		( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x04C )
+#define p_GRP0_INT_STAT_MASKED_A	( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x050 )
+#define p_GRP0_INT_STAT_MASKED_B	( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x054 )
+#define p_GRP0_INT_STAT_MASKED_C	( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x058 )
+#define p_GRP0_INT_STAT_MASKED_D	( volatile UINT32* )( GPIO_BASE + GRP0_OFFSET + 0x05C )
+
+#define p_GRP1_OUTPUT_ENABLE		( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x000 )
+#define p_GRP1_INPUT_ENABLE		( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x004 )
+#define p_GRP1_DATA_OUT				( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x008 )
+#define p_GRP1_DATA_IN				( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x00C )
+#define p_GRP1_INT_EVENT_TYPE		( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x020 )
+#define p_GRP1_INT_ENABLE_POS		( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x024 )
+#define p_GRP1_INT_ENABLE_NEG		( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x028 )
+#define p_GRP1_INT_STAT_POS		( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x02C )
+#define p_GRP1_INT_STAT_NEG		( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x030 )
+#define p_GRP1_INT_STAT				( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x034 )
+#define p_GRP1_INT_MASK				( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x038 )
+#define p_GRP1_INT_STAT_MASKED	( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x03C )
+#define p_GRP1_INT_ASSIGN_A		( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x040 )
+#define p_GRP1_INT_ASSIGN_B		( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x044 )
+#define p_GRP1_INT_ASSIGN_C		( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x048 )
+#define p_GRP1_INT_ASSIGN_D		( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x04C )
+#define p_GRP1_INT_STAT_MASKED_A	( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x050 )
+#define p_GRP1_INT_STAT_MASKED_B	( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x054 )
+#define p_GRP1_INT_STAT_MASKED_C	( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x058 )
+#define p_GRP1_INT_STAT_MASKED_D	( volatile UINT32* )( GPIO_BASE + GRP1_OFFSET + 0x05C )
+
+#define p_GRP2_OUTPUT_ENABLE		( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x000 )
+#define p_GRP2_INPUT_ENABLE		( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x004 )
+#define p_GRP2_DATA_OUT				( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x008 )
+#define p_GRP2_DATA_IN				( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x00C )
+#define p_GRP2_INT_EVENT_TYPE		( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x020 )
+#define p_GRP2_INT_ENABLE_POS		( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x024 )
+#define p_GRP2_INT_ENABLE_NEG		( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x028 )
+#define p_GRP2_INT_STAT_POS		( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x02C )
+#define p_GRP2_INT_STAT_NEG		( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x030 )
+#define p_GRP2_INT_STAT				( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x034 )
+#define p_GRP2_INT_MASK				( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x038 )
+#define p_GRP2_INT_STAT_MASKED	( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x03C )
+#define p_GRP2_INT_ASSIGN_A		( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x040 )
+#define p_GRP2_INT_ASSIGN_B		( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x044 )
+#define p_GRP2_INT_ASSIGN_C		( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x048 )
+#define p_GRP2_INT_ASSIGN_D		( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x04C )
+#define p_GRP2_INT_STAT_MASKED_A	( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x050 )
+#define p_GRP2_INT_STAT_MASKED_B	( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x054 )
+#define p_GRP2_INT_STAT_MASKED_C	( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x058 )
+#define p_GRP2_INT_STAT_MASKED_D	( volatile UINT32* )( GPIO_BASE + GRP2_OFFSET + 0x05C )
+
+#define p_GRP3_OUTPUT_ENABLE		( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x000 )
+#define p_GRP3_INPUT_ENABLE		( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x004 )
+#define p_GRP3_DATA_OUT				( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x008 )
+#define p_GRP3_DATA_IN				( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x00C )
+#define p_GRP3_INT_EVENT_TYPE		( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x020 )
+#define p_GRP3_INT_ENABLE_POS		( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x024 )
+#define p_GRP3_INT_ENABLE_NEG		( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x028 )
+#define p_GRP3_INT_STAT_POS		( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x02C )
+#define p_GRP3_INT_STAT_NEG		( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x030 )
+#define p_GRP3_INT_STAT				( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x034 )
+#define p_GRP3_INT_MASK				( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x038 )
+#define p_GRP3_INT_STAT_MASKED	( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x03C )
+#define p_GRP3_INT_ASSIGN_A		( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x040 )
+#define p_GRP3_INT_ASSIGN_B		( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x044 )
+#define p_GRP3_INT_ASSIGN_C		( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x048 )
+#define p_GRP3_INT_ASSIGN_D		( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x04C )
+#define p_GRP3_INT_STAT_MASKED_A	( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x050 )
+#define p_GRP3_INT_STAT_MASKED_B	( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x054 )
+#define p_GRP3_INT_STAT_MASKED_C	( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x058 )
+#define p_GRP3_INT_STAT_MASKED_D	( volatile UINT32* )( GPIO_BASE + GRP3_OFFSET + 0x05C )
+
+#else
+#define NUM_OF_GPIOS	   40
+
+#define MISC_BASE       ((UINT32)0x00350000)
+
+#define p_GRP0_ISM0            	((volatile UINT32 *)(MISC_BASE + 0xA0))
+#define p_GRP0_ISM1    	         ((volatile UINT32 *)(MISC_BASE + 0xA4))
+#define p_GRP0_ISM2     	         ((volatile UINT32 *)(MISC_BASE + 0xA8))
+
+#define GPIO_OPT     	((volatile UINT32 *)(MISC_BASE + 0xB0))
+#define p_GRP0_OUTPUT_ENABLE    	((volatile UINT32 *)(MISC_BASE + 0xB4))
+#define p_GRP1_OUTPUT_ENABLE    	((volatile UINT32 *)(MISC_BASE + 0xB8))
+#define p_GRP2_OUTPUT_ENABLE     ((volatile UINT32 *)(MISC_BASE + 0xBC))
+#define p_GRP0_DATA_IN     	   ((volatile UINT32 *)(MISC_BASE + 0xC0))
+#define p_GRP1_DATA_IN  	      ((volatile UINT32 *)(MISC_BASE + 0xC4))
+#define p_GRP2_DATA_IN  	((volatile UINT32 *)(MISC_BASE + 0xC8))
+#define p_GRP0_DATA_OUT	((volatile UINT32 *)(MISC_BASE + 0xCC))
+#define p_GRP1_DATA_OUT	((volatile UINT32 *)(MISC_BASE + 0xD0))
+#define p_GRP2_DATA_OUT	((volatile UINT32 *)(MISC_BASE + 0xD4))
+#define p_GRP0_INT_STAT     		((volatile UINT32 *)(MISC_BASE + 0xD8))
+#define p_GRP1_INT_STAT        	((volatile UINT32 *)(MISC_BASE + 0xDC))
+#define p_GRP2_INT_STAT 		   ((volatile UINT32 *)(MISC_BASE + 0xE0))
+#define p_GRP0_INT_MASK 		   ((volatile UINT32 *)(MISC_BASE + 0xE4))
+#define p_GRP1_INT_MASK 	   	((volatile UINT32 *)(MISC_BASE + 0xE8))
+#define p_GRP2_INT_MASK  		((volatile UINT32 *)(MISC_BASE + 0xEC))
+#define GPIO_IPC1    	((volatile UINT32 *)(MISC_BASE + 0xF0))
+#define GPIO_IPC2    	((volatile UINT32 *)(MISC_BASE + 0xF4))
+#define GPIO_IPC3	      ((volatile UINT32 *)(MISC_BASE + 0xF8))
+
+#define p_GRP0_INPUT_ENABLE     	((volatile UINT32 *)(MISC_BASE + 0xFC))
+#define p_GRP1_INPUT_ENABLE     	((volatile UINT32 *)(MISC_BASE + 0x100))
+#define p_GRP2_INPUT_ENABLE      ((volatile UINT32 *)(MISC_BASE + 0x104))
+
+#define GRP_REG_OFFSET  0x4
+#endif
+
+#define GP_INPUTOFF	         0
+#define GP_INPUTON	         1
+
+#define GP_INPUT	            0
+#define GP_OUTPUT	            1
+
+#define GP_IRQ_MODE_LEVEL	   0
+#define GP_IRQ_MODE_EDGE	   1
+
+#define GP_IRQ_POL_NEGATIVE   0
+#define GP_IRQ_POL_POSITIVE   1
+
+
+#define GPIOINT_V90_DP	GPIO3
+#define GPIOINT_F2_IRQ1	GPIO10
+#define GPIOINT_F2_IRQ2	GPIO11
+#define GPIOINT_USB_PWR GPIO22
+
+#if DEBUG_CONSOLE_ON_UART_2
+	#ifdef CONFIG_BD_RUSHMORE
+		#define GPIOINT_UART1   GPIO14
+	#endif
+	#ifdef CONFIG_BD_HASBANI
+		#define GPIOINT_UART1   GPIO24
+	#endif
+	#ifdef CONFIG_BD_MACKINAC
+		#define GPIOINT_UART1   GPIO30
+	#endif
+#else
+	#define GPIOINT_UART1   GPIO25
+#endif
+
+#ifdef CONFIG_BD_RUSHMORE
+	#define GPIOINT_UART2   GPIO14
+#endif
+#ifdef CONFIG_BD_HASBANI
+	#define GPIOINT_UART2   GPIO24
+#endif
+#ifdef CONFIG_BD_MACKINAC
+	#define GPIOINT_UART2   GPIO30
+#endif
+
+#if !defined(BUILD_BOOTROM) && defined(INCLUDE_SOFTWARE_WLAN)
+
+	#ifdef BOARD_DAFFY_II
+	#define GPIOINT_WLAN    GPIO26
+	#endif  /* End of BOARD_DAFFY_II */
+
+	#ifdef BOARD_BRONX_MACKINAC
+	#define GPIOINT_WLAN    GPIO27
+	#endif  /* End of BOARD_BRONX_MACKINAC  */
+
+#endif  /* End of INCLUDE_SOFTWARE_WLAN */
+
+#if !defined(BUILD_BOOTROM) && defined(INCLUDE_SOFTWARE_PRINTER_SERVER)
+
+	#ifdef BOARD_DAFFY_II
+	#define GPIOINT_PRINTSERVER    GPIO27
+	#endif  /* End of BOARD_DAFFY_II */
+
+	#ifdef BOARD_BRONX_MACKINAC
+	#define GPIOINT_PRINTSERVER    GPIO26
+	#endif  /* End of BOARD_BRONX_MACKINAC  */
+
+#endif  /* End of INCLUDE_SOFTWARE_PRINTER_SERVER */
+
+#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+	#define GPOUT_TXD_LED				GPIO19
+	#define GPOUT_RXD_LED				GPIO20
+	#define GPOUT_F2_SCANEN				GPIO26
+	#define GPOUT_SHOWTIME_LED			GPIO18
+	#define GPOUT_OUTER_PAIR			GPIO31
+	#define GPOUT_INNER_PAIR			GPIO21
+	#define GPOUT_SHORTLOOPSW			GPIO38
+	#define GPOUT_HS_LED				GPIO19
+	#define GPIN_OH_DET					GPIO5		// remote offhook detect
+	
+	/* Falcon control pins */
+	#define GPIOINT_F2_IRQ1				GPIO10
+	#define GPIOINT_F2_IRQ2				GPIO11
+	#define GPIOINT_F2_DYINGGASP_IRQ	GPIO6
+	#define GPOUT_LDRVPWR				GPIO13
+	#define GPOUT_F2PWRDWN				GPIO12
+	#define GPOUT_F2RESET				GPIO9
+	
+	/* AFE POR */
+	#define GPOUT_AFERESET 	   GPIO8
+#else
+	#define GPOUT_TXD_LED				GPIO19
+	#define GPOUT_RXD_LED				GPIO20
+	#define GPOUT_SHOWTIME_LED			GPIO18
+#endif
+
+#if CONFIG_BD_OAKLAND
+	#define	GPOUT_TASKRDY_LED			GPIO19
+#else
+	#ifndef CONFIG_BD_TIBURON
+		#define	GPOUT_TASKRDY_LED			GPIO7
+	#endif
+#endif
+
+#if 0
+	#ifdef ZIGGURAT
+
+		#ifdef DEVICE_YELLOWSTONE
+		#define GPOUT_TASKRDY_LED  GPIO1
+		#else
+		#define GPOUT_TASKRDY_LED  GPIO7
+		#endif
+
+		#define GPOUT_SHOWTIME_LED GPIO18
+		#define GPOUT_TXD_LED      GPIO19
+		#define GPOUT_RXD_LED      GPIO20
+		#define GPOUT_F2_SCANEN    GPIO26
+		#define GPOUT_F2_HRSTB    GPIO26        // Used for Trapper and beyond
+
+		#ifndef DL10_D325_003
+		#define GPOUT_F2_PWR       GPIO6
+		#define GPOUT_OUTER_PAIR   GPIO33
+		#else
+		#define GPIOINT_F2_DYINGGASP_IRQ     	GPIO6
+		#define GPOUT_OUTER_PAIR   GPIO31
+		#endif
+
+		#define GPOUT_INNER_PAIR   GPIO21
+		#define GPOUT_SHORTLOOPSW  GPIO38
+		#define GPOUT_HS_LED	   GPIO19
+		#define GPIN_OH_DET	       GPIO5		// remote offhook detect
+	#else
+
+		#ifdef DEVICE_YELLOWSTONE
+		#define GPOUT_TASKRDY_LED  GPIO1
+		#else
+		#define GPOUT_TASKRDY_LED  GPIO6
+		#endif
+
+		#define GPOUT_SHOWTIME_LED GPIO39
+		#define GPOUT_TXD_LED      GPIO26
+		#define GPOUT_RXD_LED      GPIO27
+		#define GPOUT_F2_SCANEN    GPIO30
+	#endif
+
+	/* Falcon control pins */
+	#define GPOUT_LDRVPWR	GPIO13
+	#define GPOUT_F2PWRDWN	GPIO12
+	#define GPOUT_F2RESET	GPIO9
+
+
+	/* AFE POR */
+	#define GPOUT_AFERESET 	   GPIO8
+#endif
+/* This is current Hasbani and Trident shared HW */
+#ifdef DL10_D325_003
+#define GPOUT_EMACRESET	   GPIO23
+#else
+#define GPOUT_FLASHRESET   GPIO23
+#endif
+
+/* G.shdsl */
+#if CONFIG_CNXT_GSHDSL || CONFIG_CNXT_GSHDSL_MODULE
+
+#undef GPOUT_EMACRESET
+#define GPOUT_EMACRESET				GPIO2     /* ADM6996 Reset - Starfire Mark V Only */
+
+#define GPOUT_GPIO5_TEST_HEADER		GPIO5     /* GPIO5 on the Test Header - Manhattan Daughtercard Only */	
+
+#define GPOUT_GPIO8_TEST_HEADER		GPIO8     /* GPIO8 on the Test Header - Manhattan Daughtercard Only */	
+#define GPOUT_GPIO9_TEST_HEADER		GPIO9     /* GPIO9 on the Test Header - Manhattan Daughtercard Only */	
+
+#define GPIOINT_HP_INT				GPIO10    /* ZipWirePlus Device (8975) Host Port Interrupt (Active Low) */
+
+#define GPOUT_GPIO11_TEST_HEADER	GPIO11    /* GPIO11 on the Test Header - Manhattan Daughtercard Only */	
+
+#define GPIN_BOPT					GPIO14    /* Boot Option */
+
+#undef GPOUT_TASKRDY_LED
+#define GPOUT_TASKRDY_LED			GPIO17    /* Ready LED - Mackinac (CR4) */
+#define GPOUT_SHOWTIME_LED			GPIO18    /* Showtime LED - Mackinac (CR5) */
+#define GPOUT_TXD_LED				GPIO19    /* DSL TX LED - Mackinac (CR6) */
+#define GPOUT_RXD_LED				GPIO20    /* DSL RX LED - Mackinac (Not connected) */
+
+#define GPIOINT_USB_PWR				GPIO22    /* USB Power */
+
+#if DEBUG_CONSOLE_ON_UART2
+#define GPIOINT_UART1				GPIO30    /* UART2 - Mackinac (J12) */
+#else
+#define GPIOINT_UART1				GPIO25    /* UART1 - Mackinac (J11) */
+#endif
+
+#define GPIOINT_UART2				GPIO30    /* UART2 - Mackinac (J12) */
+
+#define GPIOIN_FACTORY_DEFAULT		GPIO27    /* Reset to Factory Deafult */
+
+#define GPOUT_ZIPWIRE_RESET			GPIO31    /* ZipWirePlus Device (8975) Reset */
+
+#endif
+
+typedef enum {
+    GPIO_STATUS_ERROR    = -1,
+    GPIO_STATUS_OK
+} GPIO_STATUS;
+
+extern void (*pF2_IRQ1_ISR)(void *);
+extern void (*pF2_IRQ2_ISR)(void *);
+
+void GPIO_SetGPIOIRQCallback(int gpio,void (*(pISR))(int));
+void *GPIO_GetGPIOIRQCallback(int gpio);
+void GPIO_SetGPIOIRQRoutine(int gpio,void (*(pISR))(int));
+void *GPIO_GetGPIOIRQRoutine(int gpio);
+
+/* Exported Function Prototypes Declaration */
+extern void SetGPIOUsage( UINT8 uGPIOPin, BOOL bOpt );
+extern void SetGPIODir( UINT8 uGPIOPin, BOOL bDir );
+extern void SetGPIOInputEnable( UINT8 uGPIOPin, BOOL bState );
+extern BOOL ReadGPIOData( UINT8 uGPIOPin );
+extern void WriteGPIOData( UINT8 uGPIOPin, BOOL bState );
+extern BOOL ReadGPIOIntStatus( UINT8 uGPIOPin );
+extern void ClearGPIOIntStatus( UINT8 uGPIOPin );
+extern void SetGPIOIntEnable( UINT8 uGPIOPin, BOOL bState );
+extern BOOL ReadGPIOIntEnable( UINT8 uGPIOPin );
+extern void SetGPIOIntPolarity( UINT8 uGPIOPin, BOOL bPolarity );
+extern BOOL ReadGPIOIntStatus( UINT8 uGPIOPin );
+extern BOOL ReadGPIOIntPolarity( UINT8 uGPIOPin );
+extern void SetGPIOIntMode( UINT8 uGPIOPin, BOOL bPolarity );
+
+extern GPIO_STATUS GPIO_Init(void);
+
+extern void GPIOHandler(int irq, void *dev_id, struct pt_regs * regs);
+
+// Temporary until the newer gpioisr.c file is ported over
+
+extern void GPIOB10_Handler(int gpio_num);
+extern void GPIOB11_Handler(int gpio_num);
+extern void GPIOB14_Handler(int gpio_num);
+extern void GPIOB24_Handler(int gpio_num);
+extern void GPIOB25_Handler(int gpio_num);
+extern void GPIOB30_Handler(int gpio_num);
+#ifdef CONFIG_BD_TIBURON
+extern void GPIOB27_Handler(int gpio_num);
+#endif
+
+#define MISC_BASE       ((UINT32)0x00350000)
+
+#define GPIO_ISM1     	((volatile UINT32 *)(MISC_BASE + 0xA0))
+#define GPIO_ISM2     	((volatile UINT32 *)(MISC_BASE + 0xA4))
+#define GPIO_ISM3     	((volatile UINT32 *)(MISC_BASE + 0xA8))
+
+#define GPIO_OPT     	((volatile UINT32 *)(MISC_BASE + 0xB0))
+#define GPIO_OE1     	((volatile UINT32 *)(MISC_BASE + 0xB4))
+#define GPIO_OE2     	((volatile UINT32 *)(MISC_BASE + 0xB8))
+#define GPIO_OE3	      ((volatile UINT32 *)(MISC_BASE + 0xBC))
+#define GPIO_DATA_IN1	((volatile UINT32 *)(MISC_BASE + 0xC0))
+#define GPIO_DATA_IN2	((volatile UINT32 *)(MISC_BASE + 0xC4))
+#define GPIO_DATA_IN3	((volatile UINT32 *)(MISC_BASE + 0xC8))
+#define GPIO_DATA_OUT1	((volatile UINT32 *)(MISC_BASE + 0xCC))
+#define GPIO_DATA_OUT2	((volatile UINT32 *)(MISC_BASE + 0xD0))
+#define GPIO_DATA_OUT3	((volatile UINT32 *)(MISC_BASE + 0xD4))
+#define GPIO_ISR1 		((volatile UINT32 *)(MISC_BASE + 0xD8))
+#define GPIO_ISR2    	((volatile UINT32 *)(MISC_BASE + 0xDC))
+#define GPIO_ISR3		   ((volatile UINT32 *)(MISC_BASE + 0xE0))
+#define GPIO_IER1		   ((volatile UINT32 *)(MISC_BASE + 0xE4))
+#define GPIO_IER2	   	((volatile UINT32 *)(MISC_BASE + 0xE8))
+#define GPIO_IER3 		((volatile UINT32 *)(MISC_BASE + 0xEC))
+#define GPIO_IPC1    	((volatile UINT32 *)(MISC_BASE + 0xF0))
+#define GPIO_IPC2    	((volatile UINT32 *)(MISC_BASE + 0xF4))
+#define GPIO_IPC3	      ((volatile UINT32 *)(MISC_BASE + 0xF8))
+
+#endif /* GPIOVAL_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/gptimer.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/gptimer.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/gptimer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/gptimer.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,82 @@
+/****************************************************************************
+*
+*	Name:			gptimer.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002, 2004 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   lewisrc  $
+*  $Revision:   1.0  $
+*  $Modtime:   Jul 18 2003 14:04:30  $
+****************************************************************************/
+
+#ifndef GPTIMER_H
+#define GPTIMER_H
+
+//#define NUMBER_OF_GP_TIMERS 
+
+typedef enum GP_TIMER_E
+{
+	GP_TIMER_DMT_HI,
+	GP_TIMER_DMT_MED,
+	GP_TIMER_DMT_LO,
+	GP_TIMER_DMT_DT, 
+	GP_TIMER_DMT_LM,
+	GP_TIMER_DMT_LED,
+	GP_TIMER_BSP_LED,
+	GP_TIMER_VOP,
+
+	NUMBER_OF_GP_TIMERS
+} GP_TIMER_E ;
+
+// Callback Function Prototype
+typedef void (*PGPCALLBACK) ( void *pContext ) ;
+
+void GPTimerInit
+(
+	void
+) ;
+
+int GPTimerConnect
+(
+	WORD		TimerIndex,
+	PGPCALLBACK	pCallback,
+	void		*pContext
+) ;
+
+int GPTimerDisconnect
+(
+	WORD		TimerIndex
+) ;
+
+int GPTimerStart
+(
+	WORD		TimerIndex,
+	LONG		Period,
+	BOOLEAN		Repeats
+) ;
+
+int GPTimerStop
+(
+	WORD TimerIndex
+) ;
+
+#endif // GPTIMER_H
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,127 @@
+/****************************************************************************
+*
+*	Name:			hardware.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:28:30  $
+****************************************************************************/
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+
+#define HARD_RESET_NOW()
+
+/*
+ * emac
+ */
+
+#define E_DMA_1			0x310000
+#define E_NA_1			0x310004
+#define E_Stat_1		0x310008
+#define E_IE_1			0x31000c
+#define E_LP_1			0x310010
+#define E_MII_1			0x310018
+#define ET_DMA_1		0x310020
+
+#define E_DMA_2			0x320000
+#define E_NA_2			0x320004
+#define E_Stat_2		0x320008
+#define E_IE_2			0x32000c
+#define E_LP_2			0x320010
+#define E_MII_2			0x320018
+#define ET_DMA_2		0x320020
+
+
+/*
+ * GPIO
+ */
+
+#define CX821xx_GPIO_ISM1  (volatile unsigned long*)0x3500a0
+#define CX821xx_GPIO_ISM2  (volatile unsigned long*)0x3500a4
+#define CX821xx_GPIO_ISM3  (volatile unsigned long*)0x3500a8
+
+#define CX821xx_GPIO_OE1   (volatile unsigned long*)0x3500b4
+#define CX821xx_GPIO_OE2   (volatile unsigned long*)0x3500b8
+#define CX821xx_GPIO_OE3   (volatile unsigned long*)0x3500bc
+
+#define CX821xx_GPIO_DIN1  (volatile unsigned long*)0x3500c0
+#define CX821xx_GPIO_DIN2  (volatile unsigned long*)0x3500c4
+#define CX821xx_GPIO_DIN3  (volatile unsigned long*)0x3500c8
+
+#define CX821xx_GPIO_DOUT1 (volatile unsigned long*)0x3500cc
+#define CX821xx_GPIO_DOUT2 (volatile unsigned long*)0x3500d0
+#define CX821xx_GPIO_DOUT3 (volatile unsigned long*)0x3500d4
+
+#define CX821xx_GPIO_ISR1  (volatile unsigned long*)0x3500d8
+#define CX821xx_GPIO_ISR2  (volatile unsigned long*)0x3500dc
+#define CX821xx_GPIO_ISR3  (volatile unsigned long*)0x3500e0
+
+#define CX821xx_GPIO_IER1  (volatile unsigned long*)0x3500e4
+#define CX821xx_GPIO_IER2  (volatile unsigned long*)0x3500e8
+#define CX821xx_GPIO_IER3  (volatile unsigned long*)0x3500ec
+
+#define CX821xx_GPIO_IPC1  (volatile unsigned long*)0x3500f0
+#define CX821xx_GPIO_IPC2  (volatile unsigned long*)0x3500f4
+#define CX821xx_GPIO_IPC3  (volatile unsigned long*)0x3500f8
+
+/* 
+ * interrupts 
+ */
+#ifdef __ASSEMBLY__
+#define	CNXT_INT_STATUS   0x350044
+#define	CNXT_INT_MASK     0x35004C 
+#define CNXT_INT_STATUS_M 0x350090
+#else
+#define	CNXT_INT_STATUS   (volatile unsigned long*)0x350044
+#define	CNXT_INT_MASK     (volatile unsigned long*)0x35004C 
+#define CNXT_INT_STATUS_M (volatile unsigned long*)0x350090
+#endif
+
+/*
+ * timers
+ */
+
+#define CX821xx_TIMBase_Addr     0x350020
+
+#define TM_Cnt1          0x00
+#define TM_Cnt2          0x04
+#define TM_Cnt3          0x08
+#define TM_Cnt4          0x0C
+
+#define TM_Lmt1          0x10
+#define TM_Lmt2          0x14
+#define TM_Lmt3          0x18
+#define TM_Lmt4          0x1C
+
+#define TIM_SET_RATE(tmr, value) *((volatile unsigned long *)(CX821xx_TIMBase_Addr+tmr)) = value
+
+
+#define ASB_RAM_ADRS      0x00180000
+#define CX821xx_CLK_SPEED     1000000         /* Timer speed is 1 microsecond*/
+
+#endif  /* _ASM_ARCH_HARDWARE_H */
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/hstif.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/hstif.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/hstif.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/hstif.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,207 @@
+/****************************************************************************
+*
+*	Name:			hstif.h
+*
+*	Description:	Host Interface header file
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:28:32  $
+****************************************************************************/
+
+/*  Host Control Reg    */
+#define HST_CTRL        0x002D0000  /* Register used to select host brd options*/
+
+/*  Host Control bit definitions */
+#define HSTCTRL_4MEG    BIT2
+#define HSTCTRL_8MEG    BIT3
+#define HSTCTRL_RUN_MAP BIT4  /* This bit remaps SRAM to blk 0 when set  */
+
+#define pHST_CtrlReg		      ( volatile UINT32* )0x002D0000
+#define pHST_RwstReg		      ( volatile UINT32* )0x002D0004
+#define pHST_WwstReg		      ( volatile UINT32* )0x002D0008
+#define pHST_Xfer_CntlReg	   ( volatile UINT32* )0x002D000C
+#define pHST_Read_Cntl1Reg	   ( volatile UINT32* )0x002D0010
+#define pHST_Read_Cntl2Reg	   ( volatile UINT32* )0x002D0014
+#define pHST_Write_Cntl1Reg	( volatile UINT32* )0x002D0018
+#define pHST_Write_Cntl2Reg	( volatile UINT32* )0x002D001C
+#define pMSTR_Intf_WidthReg	( volatile UINT32* )0x002D0020
+#define pMSTR_HandshakeReg	   ( volatile UINT32* )0x002D0024
+#define pHDMA_Src_AddrReg	   ( volatile UINT32* )0x002D0028
+#define pHDMA_Dst_AddrReg	   ( volatile UINT32* )0x002D002C
+#define pHDMA_BcntReg		   ( volatile UINT32* )0x002D0030
+#define pHDMA_TimersReg		   ( volatile UINT32* )0x002D0034
+
+#define MODE_RW_DS		1	   /* R/W and a DS signal */
+#define MODE_R_W		   0	   /* Seperate Read and Write signals */
+
+/* How far to shift up the wait states for the wait state control registers */
+#define FLASH_WS			0
+#define HCS1_WS			5
+#define FALCON_WS			10
+#define V90_WS				15
+#define UART_WS			20
+
+/* How far to shift up the chip select hold times */
+#define HCS1_TCH			0
+#define FALCON_TCH		4
+#define V90_TCH			8
+#define UART_TCH			12
+
+/* How far to shift up the chip select setup times */
+#define HCS1_TCS			16
+#define FALCON_TCS		20
+#define V90_TCS			24
+#define UART_TCS			28
+
+/* How far to shift up the address hold times */
+#define HCS1_TAH			0
+#define FALCON_TAH		4
+#define V90_TAH			8
+#define UART_TAH			12
+
+/* How far to shift up the address setup times */
+#define HCS1_TAS			16
+#define FALCON_TAS		20
+#define V90_TAS			24
+#define UART_TAS			28
+
+
+#define HST_ASB_ADDR_START	( UINT32* )0x00200000
+#define HST_ASB_ADDR_FINISH	( UINT32* )0x00200FFF
+
+/* Host Interface UART Section */
+/*taken straight from datasheet*/
+
+#define pUreg_RHR	( volatile UINT8* )0x002C0000	/*Receive Holding Register*/
+#define pUreg_THR	( volatile UINT8* )0x002C0000 	/*Receive Holding Register*/
+#define pUreg_IER	( volatile UINT8* )0x002C0002	/*Interrupt Enable Register*/
+#define pUreg_FCR	( volatile UINT8* )0x002C0004	/*FIFO control Register*/
+#define pUreg_ISR	( volatile UINT8* )0x002C0004	/*Interrupt Status Register*/
+#define pUreg_LCR	( volatile UINT8* )0x002C0006	/*Line control Register*/
+#define pUreg_MCR   ( volatile UINT8* )0x002C0008	/*Modem Control Register*/
+#define pUreg_LSR	( volatile UINT8* )0x002C000A	/*Line Status Register*/
+#define pUreg_MSR	( volatile UINT8* )0x002C000C   /*Modem Status Register*/
+#define pUreg_SCR	( volatile UINT8* )0x002C000E	/*Scratch pad Register*/
+
+/* Two offsets used for defining the baud rate*/
+#define DIVLSB		( volatile UINT8* )0x002C0000	/*Divisor LSB latch address */
+#define DIVMSB		( volatile UINT8* )0x002C0002	/*Divisor MSB latch address */
+
+/* Program table for baud rate */
+
+
+/*Baud Rates */
+#define	_COM_300_			0
+#define _COM_1200_			1
+#define	_COM_2400_			2
+#define _COM_9600_			3
+#define	_COM_19K_			4
+#define _COM_38K_			   5
+#define	_COM_56K_			6
+#define _COM_115K_			7
+
+/*Parity*/
+#define	_COM_NOPARITY_		0
+#define _COM_ODDPARITY_		1
+#define _COM_EVENPARITY_	2
+
+/*Stopbits*/
+#define	_COM_STOP1_			0
+#define _COM_STOP2_			1
+#define _COM_STOP1_5_		1
+
+/*word length*/
+#define	_COM_CHR5_			0
+#define _COM_CHR6_			1
+#define _COM_CHR7_			2
+#define _COM_CHR8_			3
+
+/*fifo length*/
+#define _COM_FIFO1_			0
+#define _COM_FIFO4_			1
+#define _COM_FIFO8_			2
+#define _COM_FIFO14_		   3
+
+
+/* Host Interface Flash Section */
+/*taken straight from datasheet*/
+#define pFlashBaseAddr		0x400000	 
+
+#ifndef _ASMLANGUAGE
+void HSTInit(void);
+#endif
+  
+/****************************************************************************
+ *
+ *  $Log:   S:/Embedded/archives/Linux/BSP_CX821xx/uClinux2.4.6/linux/include/asm-armnommu/arch-cx821xx/hstif.h-arc  $
+ * 
+ *    Rev 1.0   Mar 19 2003 13:49:02   davidsdj
+ * Initial revision.
+ * 
+ * 2     2/28/02 8:26a Richarjc
+ * Added Conexant ownership and GPL notices.
+ * 
+ * 1     2/22/02 11:47a Palazzjd
+ * Lineo Beta
+ *  Revision 1.1  2001/12/12 14:26:32  oleks
+ *  OZH: Added Conexant "Golden Gate" support.
+ *
+ * 
+ * 1     6/13/01 8:56a Richarjc
+ * Initial checkin of the Linux kernel and BSP source code for the Golden
+ * Gate development board based upon the CX82100 Home Networking
+ * Processor.
+ * 
+ *    Rev 1.4   15 Nov 2000 18:56:54   dinhtm
+ *  
+ * 
+ *    Rev 1.2   28 Mar 2000 15:33:16   sneedgc
+ * Chris S.: Document cache code, enable
+ * async mode, shink IRQ stack to 0x800/2,
+ * and add code to change to run map.
+ * 
+ *    Rev 1.1   Jan 20 2000 16:32:56   nguyenpa
+ * Add CX82100 support and clean up.
+ * 
+ *    Rev 1.0   31 Oct 1999 16:03:18   nguyenpa
+ *  
+ * 
+ *    Rev 1.3   27 Oct 1999 14:33:04   blackldk
+ * Added symbolic definition for interface timing bits
+ * 
+ *    Rev 1.2   01 Oct 1999 08:06:50   chen2p
+ *  
+ * 
+ *    Rev 1.1   28 Sep 1999 08:16:16   chen2p
+ *  
+ * 
+ *    Rev 1.0   22 Sep 1999 16:59:04   chen2p
+ *  First merge of Host IF, GPIO,Memory, and
+ *  Timer tests.
+ * 
+ *    Rev 1.0   17 Aug 1999 15:00:38   blackldk
+ * DMA control routines
+ * 
+ *
+ ***************************************************************************/
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/hwiodmt.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/hwiodmt.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/hwiodmt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/hwiodmt.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,1061 @@
+/******************************************************************************
+**
+**	MODULE NAME:
+**		HwIo (though global and available to all files)
+**
+**	FILE NAME:
+**		HwIo.h
+**
+**	ABSTRACT:
+**		This file contains defines for accessing the driver
+**		through a device specific function/method (e.g., through
+**		the "OID_TAPI_DEV_SPECIFIC" OID of the driver registered
+**		SetInformationHandler function).
+**		This is the device specific interface through which
+**		applications may access certain driver specific information.
+**
+**	DETAILS:
+**
+**	NOTES:
+**		This device specific hardware input/output (HwIo) interface to the
+**		driver has legacy names (some are listed below).
+**			Bd, BD								now HwIo, HW_IO
+**			BackDoor, MiniBackDoor				now HwIo
+**			pBackDoorBuf, pMiniBackDoorBuf		now pHwIo
+**			BACK_DOOR_T, MINI_BACK_DOOR_T		now HW_IO_CMD_STRUC_T
+**		See the text file "HwIoFromDevIo.txt" for more details.
+**
+*******************************************************************************
+**	Copyright (c) 1997, 1998, 1999, 2000, 2001 Conexant Systems, Inc.
+**	(formerly Rockwell Semiconductor Systems)
+*******************************************************************************
+* 
+*   This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the Free
+* Software Foundation; either version 2 of the License, or (at your option)
+* any later version.
+* 
+*   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
+* 
+*******************************************************************************
+** $Archive:   S:/Embedded/archives/Linux/BSP_CX821xx/uClinux2.4.6/linux/include/asm-armnommu/arch-cx821xx/hwiodmt.h-arc  $
+** $Revision:   1.2  $
+** $Date:   May 14 2003 11:53:20  $
+*******************************************************************************/
+
+
+/**/	//This is a Page Eject character.
+#ifndef _HWIODMT_H_
+#define _HWIODMT_H_
+
+
+
+
+
+//
+//	HW_IO_GET_ALARMS
+//
+
+typedef enum HW_IO_ADSL_ALARM_CODES_E
+{
+	HW_IO_ADSL_ALARM_START		= 0,
+
+	HW_IO_ADSL_ALARM_NO_ALARM	= 0,	// no alarm
+	HW_IO_ADSL_ALARM_LOF,				// lof_alarm
+	HW_IO_ADSL_ALARM_MAR,				// low_snr_margin_alarm
+	HW_IO_ADSL_ALARM_ES,				// es_alarm
+	HW_IO_ADSL_ALARM_SES,				// severe error second
+	HW_IO_ADSL_ALARM_LOS,				// los_alarm
+	HW_IO_ADSL_ALARM_LCD,				// lcd_alarm
+	HW_IO_ADSL_ALARM_SELF,				// self test
+	HW_IO_ADSL_ALARM_FR,				// Fast Retrain						(ALARM NOT SUPPORTED)
+	HW_IO_ADSL_ALARM_ELOF,				// excessive LOF within 15 minute
+	HW_IO_ADSL_ALARM_ESES,				// excessive SES within 15 minute
+	HW_IO_ADSL_ALARM_EUAS,				// excessive UAS within 15 minute
+	HW_IO_ADSL_ALARM_ELOS,				// excessive LOS within 15 minute
+	HW_IO_ADSL_ALARM_ELCD,				// excessive LCD within 15 minute
+	HW_IO_ADSL_ALARM_EFR,				// excessive Fast Retrain within 15 minutes (ALARM NOT SUPPORTED)
+
+	HW_IO_ADSL_ALARM_END
+
+} HW_IO_ADSL_ALARM_CODES_T;
+
+// size of list of alarms
+#define NUM_HW_IO_ADSL_ALARMS 12
+
+typedef struct HW_IO_ADSL_ALARM_LIST_S
+{
+	// if a slot has no alarm, that slot will contain HW_IO_ADSL_ALARM_NO_ALARM (0)
+	HW_IO_ADSL_ALARM_CODES_T		AlarmList [NUM_HW_IO_ADSL_ALARMS];
+
+} HW_IO_ADSL_ALARM_LIST_T,
+  * PHW_IO_ADSL_ALARM_LIST_T;
+
+typedef struct HW_IO_ALARMS_S
+{
+	OUT	HW_IO_ADSL_ALARM_LIST_T		UpStreamAlarms;
+	OUT	HW_IO_ADSL_ALARM_LIST_T		DownStreamAlarms;
+
+} HW_IO_ALARMS_T,
+  * PHW_IO_ALARMS_T;
+
+
+
+//
+//	HW_IO_GET_BIT_ALLOC_TABLE
+//
+
+typedef enum HW_IO_BIT_ALLOC_BIN_STATUS_E
+{
+	BIT_ALLOC_BIN_START,
+
+	UP_STREAM_BIN		= BIT_ALLOC_BIN_START,
+	DOWN_STREAM_BIN,
+	NO_ASSIGNED_BIN,
+
+	BIT_ALLOC_BIN_END
+
+} HW_IO_BIT_ALLOC_BIN_STATUS_T;
+
+typedef struct HW_IO_BIT_ALLOC_BIN_ENTRY_S
+{
+	WORD								BinNumber;
+	HW_IO_BIT_ALLOC_BIN_STATUS_T		BinStatus;
+	WORD								BitsAssigned;
+	WORD								BitCapacity;
+
+} HW_IO_BIT_ALLOC_BIN_ENTRY_T,
+  * PHW_IO_BIT_ALLOC_BIN_ENTRY_T;
+
+// BitCapacity contains an implied decimal point between the upper and lower bytes.
+
+#define NUM_HW_IO_BIT_ALLOC_BINS		16
+
+typedef struct HW_IO_BIT_ALLOC_TABLE_S
+{
+	OUT	WORD							StartingBin;
+	OUT	WORD							EndingBin;
+
+	OUT	HW_IO_BIT_ALLOC_BIN_ENTRY_T		Entry [NUM_HW_IO_BIT_ALLOC_BINS];
+
+} HW_IO_BIT_ALLOC_TABLE_T,
+  * PHW_IO_BIT_ALLOC_TABLE_T;
+
+
+
+//
+//	HW_IO_GET_SNR_TABLE
+//
+
+typedef struct HW_IO_SNR_ENTRY_S
+{
+	WORD					BinNumber;
+	WORD					BinSNR;
+
+} HW_IO_SNR_ENTRY_T,
+  * PHW_IO_SNR_ENTRY_T;
+
+#define NUM_HW_IO_SNR_ENTRIES		16
+
+typedef struct HW_IO_SNR_TABLE_S
+{
+	WORD					StartingBin;
+	WORD					EndingBin;
+	HW_IO_SNR_ENTRY_T		Entry [NUM_HW_IO_SNR_ENTRIES];
+
+} HW_IO_SNR_TABLE_T,
+  * PHW_IO_SNR_TABLE_T;
+
+
+
+//
+//	HW_IO_GET_CONTROLLER_LOG_CLT
+//	HW_IO_SET_CONTROLLER_LOG_CLT
+//
+
+typedef OUT IN	BOOLEAN					HW_IO_CONTROLLER_LOG_CLT_T;		// OUT for HW_IO_GET_CONTROLLER_LOG_CLT
+																		// IN  for HW_IO_SET_CONTROLLER_LOG_CLT
+typedef HW_IO_CONTROLLER_LOG_CLT_T		* PHW_IO_CONTROLLER_LOG_CLT_T;
+
+
+
+//
+//	HW_IO_GET_GHS_CAP
+//
+//				G9221AnnexA.Negotiated		G9222AnnexAB.Negotiated
+//	ANSI				FALSE						FALSE
+//	G.LITE				FALSE						TRUE
+//	G.DMT				TRUE						FALSE
+//	invalid				TRUE						TRUE
+//	
+//				G9221AnnexA.LocalEndpoint	G9222AnnexAB.LocalEndpoint
+//	ANSI				FALSE						FALSE
+//	G.LITE				FALSE						TRUE
+//	G.DMT				TRUE						FALSE
+//	either				TRUE						TRUE
+//
+//
+typedef struct HW_IO_GHS_CAP_ENTRY_S
+{
+	BOOLEAN		LocalEndpoint;
+	BOOLEAN		RemoteEndpoint;
+	BOOLEAN		Negiotiated;
+
+} HW_IO_GHS_CAP_ENTRY_T,
+  * PHW_IO_GHS_CAP_ENTRY_T;
+
+typedef struct HW_IO_GHS_CAP_S
+{
+	OUT	HW_IO_GHS_CAP_ENTRY_T		V8;
+	OUT	HW_IO_GHS_CAP_ENTRY_T		V8bis;
+	OUT	HW_IO_GHS_CAP_ENTRY_T		SilentPeriod;
+	OUT	HW_IO_GHS_CAP_ENTRY_T		GPLOAM;
+	OUT	HW_IO_GHS_CAP_ENTRY_T		G9221AnnexA;
+	OUT	HW_IO_GHS_CAP_ENTRY_T		G9221AnnexB;
+	OUT	HW_IO_GHS_CAP_ENTRY_T		G9221AnnexC;
+	OUT	HW_IO_GHS_CAP_ENTRY_T		G9222AnnexAB;
+	OUT	HW_IO_GHS_CAP_ENTRY_T		G9222AnnexC;
+	OUT	BYTE						RemoteCountry;
+	OUT	BYTE						RemoteVendorID [4];
+	OUT	BYTE						RemoteSpecInfo [2];
+	OUT	BOOLEAN						Valid;		//Indicates whether remaining parms are valid
+
+} HW_IO_GHS_CAP_T,
+  * PHW_IO_GHS_CAP_T;
+
+
+
+//
+//	HW_IO_GET_GHS_LOCAL_CAP
+//	HW_IO_SET_GHS_LOCAL_CAP
+//
+
+// AdslLocalG922Cap
+typedef enum HW_IO_LOCAL_G922_CAP_E			// AdslLocalG922Cap values:
+{
+	HW_IO_GHS_CAPABILITIES_V8				= 1,
+	HW_IO_GHS_CAPABILITIES_V8bis			= 2,
+	HW_IO_GHS_CAPABILITIES_SilentPeriod		= 4,
+	HW_IO_GHS_CAPABILITIES_GPLOAM			= 8
+} HW_IO_LOCAL_G922_CAP_T;
+
+
+// AdslLocalG922AnnexCap
+typedef enum HW_IO_LOCAL_G922_ANNEX_CAP_E		// AdslLocalG922AnnexCap values:
+{
+	HW_IO_GHS_CAPABILITIES_922_1A			= 1,
+	HW_IO_GHS_CAPABILITIES_922_1B			= 2,
+	HW_IO_GHS_CAPABILITIES_922_1C			= 4,
+	HW_IO_GHS_CAPABILITIES_922_2AB			= 8,
+	HW_IO_GHS_CAPABILITIES_922_2C			= 0x10
+} HW_IO_LOCAL_G922_ANNEX_CAP_T;
+
+
+
+typedef struct HW_IO_GHS_LOCAL_CAP_S
+{
+	OUT IN	WORD		AdslLocalG922Cap;		// OUT for HW_IO_GET_GHS_LOCAL_CAP
+												// IN  for HW_IO_SET_GHS_LOCAL_CAP
+	OUT IN	WORD		AdslLocalG922AnnexCap;	// OUT for HW_IO_GET_GHS_LOCAL_CAP
+												// IN  for HW_IO_SET_GHS_LOCAL_CAP
+
+} HW_IO_GHS_LOCAL_CAP_T,
+  * PHW_IO_GHS_LOCAL_CAP_T;
+
+
+
+//
+// HW_IO_GET_MODULATION
+//
+
+typedef enum HW_IO_MODULATION_CODES_E		// AdslModulation values:
+{
+	HW_IO_MODULATION_INVALID,
+	HW_IO_MODULATION_ANSI_T413,
+	HW_IO_MODULATION_GDMT,
+	HW_IO_MODULATION_GLITE
+} HW_IO_MODULATION_CODES_T;
+
+typedef OUT	HW_IO_MODULATION_CODES_T		HW_IO_MODULATION_T;
+typedef		HW_IO_MODULATION_T				* PHW_IO_MODULATION_T;
+
+
+
+//
+//	HW_IO_GET_AUTO_SENSE
+//	HW_IO_SET_AUTO_SENSE
+//	**** THESE MUST REMAIN IN SYNC WITH THE ENUMERATED VALUES IN XCVRINFO.H SYS_HANDSHAKE_TYPE and SYS_WIRING_TYPE
+//
+
+// Use DWORD for compatability with control panel Custom Driver Commands tab
+// AdslSysAutoHandshake
+typedef enum HW_IO_ADSL_DP_RATE_MODE_E		// AdslDpRateMode values:
+{
+	HW_IO_GHS_TONE_MODE			= 0,		// (Auto selection with G.hs preferred - default setting)
+	HW_IO_TONE_GHS_MODE			= 1,		// (Auto selection with T1.413 preferred)
+	HW_IO_G_HANDSHAKE_MODE		= 2,		// (G.hs only)
+	HW_IO_G_TONE_MODE			= 3,		// (T1.413 only)
+	HW_IO_G_DMT_ONLY			= 4, 		// (G.hs, G.dmt Only)
+	HW_IO_G_LITE_ONLY			= 5,		// (G.hs, G.lite Only
+	HW_IO_ADSL_DP_RATE_END
+} HW_IO_ADSL_DP_RATE_MODE_T;
+
+
+typedef enum HW_IO_ADSL_WIRING_SELECTION_E	// AdslSysWiring values:
+{
+	HW_IO_WIRING_COMBO_AUTO		= 0,		// "Automatic"
+	HW_IO_WIRING_COMBO1			= 1,		// "Line Tip/Ring"
+	HW_IO_WIRING_COMBO2			= 2,		// "Line A/A1"
+	HW_IO_WIRING_COMBO3			= 3,		// "Aux Tip/Ring"
+	HW_IO_WIRING_COMBO4			= 4,		// "Aux A/A1"
+	HW_IO_WIRING_COMBO_END					//  Always keep at end of list
+} HW_IO_ADSL_WIRING_SELECTION_T;
+
+
+typedef struct HW_IO_AUTO_SENSE_S
+{
+	IN	HW_IO_ADSL_DP_RATE_MODE_T			AdslSysAutoHandshake;
+	IN	HW_IO_ADSL_WIRING_SELECTION_T		AdslSysAutoWiring;
+	IN	DWORD								AdslSysAutoWiresFirst;
+} HW_IO_AUTO_SENSE_T,
+  * PHW_IO_AUTO_SENSE_T;
+
+
+
+//
+//	HW_IO_GET_AUTO_SENSE_STATUS
+//	**** THESE MUST REMAIN IN SYNC WITH THE ENUMERATED VALUES IN XCVRINFO.H SYS_HANDSHAKE_TYPE and SYS_WIRING_TYPE and SYS_AUTO_SENSING_STATE_TYPE
+//
+
+typedef enum HW_IO_ADSL_DP_AUTO_SENSING_STATE_E
+{
+	HW_IO_AUTO_SENSE_AUTO,
+	HW_IO_AUTO_SENSE_LOCKED,
+	HW_IO_AUTO_SENSE_WIRING_LOCKED
+} HW_IO_ADSL_DP_AUTO_SENSING_STATE_T;
+
+typedef struct HW_IO_AUTO_SENSE_STATUS_S
+{
+	IN	HW_IO_ADSL_DP_RATE_MODE_T			AdslSysAutoHandshake;
+	IN	HW_IO_ADSL_WIRING_SELECTION_T		AdslSysAutoWiring;
+	IN	HW_IO_ADSL_DP_AUTO_SENSING_STATE_T	AdslSysAutoSenseState;
+
+} HW_IO_AUTO_SENSE_STATUS_T,
+  * PHW_IO_AUTO_SENSE_STATUS_T;
+
+
+
+//
+//	HW_IO_USER_ACTIVATE_LINE
+//	HW_IO_USER_DEACTIVATE_LINE
+//
+
+// NO Parameters
+
+
+
+//
+//	HW_IO_GET_CONNECT_STATUS
+//
+
+typedef enum HW_IO_CONNECT_STATUS_CODES_E
+{
+	HW_IO_CONNECT_STATUS_START			= 0,
+
+	HW_IO_CONNECT_STATUS_IDLE			= 0,
+	HW_IO_CONNECT_STATUS_HANDSHAKE,			//1
+	HW_IO_CONNECT_STATUS_TRAINING,			//2
+	HW_IO_CONNECT_STATUS_DATAMODE,			//3
+	HW_IO_CONNECT_STATUS_RETRAIN,			//4
+	HW_IO_CONNECT_STATUS_TESTMODE,			//5
+	HW_IO_CONNECT_STATUS_POWERDOWN,			//6
+	HW_IO_CONNECT_STATUS_FAILURECODE,		//7
+
+	HW_IO_CONNECT_STATUS_END				//8
+
+} HW_IO_CONNECT_STATUS_CODES_T;
+
+typedef OUT	DWORD					HW_IO_CONNECT_STATUS_T;
+typedef HW_IO_CONNECT_STATUS_T		* PHW_IO_CONNECT_STATUS_T;
+
+
+
+
+//
+//	HW_IO_INIT_DATA_PUMP
+//
+
+// NO Parameters
+
+
+
+//
+//	HW_IO_GET_DP_VERSIONS
+//
+
+typedef struct HW_IO_DATA_PUMP_VERSIONS_S
+{
+	OUT	DWORD		AdslVersionNear;		// 0 to 0xFF
+	OUT	DWORD		AdslVersionFar;			// 0 to 0xFF
+	OUT	DWORD		AdslVendorNear;			// 0 to 0xFFFF
+	OUT	DWORD		AdslVendorFar;			// 0 to 0xFFFF
+	OUT	DWORD		AdslDpSwVerMajor;		// 0 to 0xF
+	OUT	DWORD		AdslDpSwVerMinor;		// 0 to 0xF
+	OUT	DWORD		AdslDpSwVerSubMinor;	// 0 to 0xFF
+
+} HW_IO_DATA_PUMP_VERSIONS_T,
+  * PHW_IO_DATA_PUMP_VERSIONS_T;
+
+
+
+//
+//  HW_IO_GET_CONTROLLER_VERSION
+//
+
+#define MAX_DATAPUMP_VERSION_LENGTH 40
+
+typedef struct HW_IO_CONTROLLER_VERSION_S
+{
+	OUT CHAR		AdslDpSwVersion[MAX_DATAPUMP_VERSION_LENGTH];	
+} HW_IO_CONTROLLER_VERSION_T,  * PHW_IO_CONTROLLER_VERSION_T;
+
+
+
+
+
+//
+//  HW_IO_GET_RETRAIN_PARAMETERS
+//  HW_IO_SET_RETRAIN_PARAMETERS
+//
+
+typedef struct _HW_IO_RETRAIN_PARAMETERS_S
+{
+										// Threshold of near-end SNR Margin used 
+										// to detect and accumulate SNR Margin Errors
+										// Valid values: 0 - 63
+	I_O		DWORD	dwAdslSnrThresholdNear;	
+
+										// Defines the threshold of near-end SNR Margin 
+										// Errors detected prior to the initiation of a retrain. 
+										// Valid values: 0 - 100
+	I_O		DWORD	dwAdslSnrMarRetrainThresholdNear;
+	
+										// Defines the number of far-end physical layer CRC 
+										// errors which can occur during a one-second period 
+										// before the far-end CRC Errors accumulator is incremented  
+										// Valid values: 0 - 100
+	I_O		DWORD	dwAdslCrcThresholdFar;	
+
+										// If the far-end CRC Error threshold is crossed, then the 
+										// far-end CRC Errors" accumulator is incremented by this amount  
+										// Valid values: 0 - 100
+	I_O		DWORD	dwAdslCrcIncrementFar;	
+
+										// Defines the threshold of far-end CRC Errored Seconds
+										// detected prior to the initiation of a retrain   
+										// Valid values: 0 - 100
+	I_O		DWORD	dwAdslCrcRetrainThresholdFar;
+	
+										// Defines the number of near-end physical layer CRC errors that 
+										// can occur before the Severely Errored Second accumulator is incremented  
+										// Valid values: 0 - 100
+	I_O		DWORD	dwAdslCrcThresholdNear;	
+	
+										// Defines the threshold of near-end consecutive Severely Errored Seconds 
+										// detected prior to the initiation of a retrain.   
+										// Valid values: 0 - 100
+	I_O		DWORD	dwAdslSesRetrainThresholdNear;	
+
+} HW_IO_RETRAIN_PARAMETERS_S,  * PHW_IO_RETRAIN_PARAMETERS_S;
+
+
+//
+//  HW_IO_GET_CONTROLLER_BUILD
+//
+
+#define MAX_CONTROLLER_BUILD_LENGTH 40
+
+typedef struct HW_IO_CONTROLLER_BUILD_S
+{
+	OUT CHAR		ControllerBuild[MAX_CONTROLLER_BUILD_LENGTH];	
+} HW_IO_CONTROLLER_BUILD_T,  * PHW_IO_CONTROLLER_BUILD_T;
+
+
+
+
+// 
+// HW_IO_GET_G9921_ANNEX_SELECTION
+// HW_IO_SET_G9921_ANNEX_SELECTION
+//
+typedef enum HW_IO_G9921_SETTINGS_
+{
+	G9921_ANNEX_START = 0,
+	G9921_ANNEX_A = 0,
+	G9921_ANNEX_B = 1,
+	G9921_ANNEX_C = 2,
+	G9921_ANNEX_END
+} HW_IO_G9921_SETTINGS_E;
+
+
+typedef struct HW_IO_G9921_ANNEX_
+{
+	HW_IO_G9921_SETTINGS_E	Setting;
+} HW_IO_G9921_ANNEX_T;
+
+
+// 
+// HWIO_GET_COMPATIBLE_ANNEX
+// 
+typedef enum HW_IO_G9921_COMPATIBLE_SETTINGS_
+{
+	G9921_ANNEX_COMPATIBLE_BIT_MASK_START = 1,
+	G9921_ANNEX_A_COMPATIBLE_BIT_MASK = 1<<G9921_ANNEX_A,
+	G9921_ANNEX_B_COMPATIBLE_BIT_MASK = 1<<G9921_ANNEX_B,
+	G9921_ANNEX_C_COMPATIBLE_BIT_MASK = 1<<G9921_ANNEX_C,
+	G9921_ANNEX_COMPATIBLE_END
+} HW_IO_G9921_COMPATIBLE_SETTINGS_E;
+
+typedef OUT	HW_IO_G9921_COMPATIBLE_SETTINGS_E		HW_IO_COMPATIBLE_ANNEX_VALUES_T;
+typedef		HW_IO_COMPATIBLE_ANNEX_VALUES_T			* PHW_IO_COMPATIBLE_ANNEX_VALUES_T;
+
+typedef enum HW_IO_ANNEX_SELECTION_
+{
+	ANNEX_SEL_UNDEF = 0,
+	ANNEX_SEL_A,
+	ANNEX_SEL_B,
+	ANNEX_SEL_C,
+	ANNEX_SEL_AUTO_ABC,
+	ANNEX_SEL_AUTO_ACB,
+	ANNEX_SEL_AUTO_BCA,
+	ANNEX_SEL_AUTO_BAC,
+	ANNEX_SEL_AUTO_CAB,
+	ANNEX_SEL_AUTO_CBA,
+	ANNEX_SEL_AUTO_AB,
+	ANNEX_SEL_AUTO_BA,
+	ANNEX_SEL_AUTO_AC,
+	ANNEX_SEL_AUTO_CA,
+	ANNEX_SEL_AUTO_BC,
+	ANNEX_SEL_AUTO_CB,	
+	REG_ANNEX_END
+} HW_IO_ANNEX_SELECTION_E;
+
+
+//
+//	HW_IO_GET_LATENCY_MODE
+//
+
+typedef enum _HW_IO_LATENCY_MODES_E
+{
+	HW_IO_LATENCY_FAST				= 0,
+	HW_IO_LATENCY_INTERLEAVED,
+	HW_IO_LATENCY_UNKNOWN
+} HW_IO_LATENCY_MODES_E;
+
+
+typedef struct _HW_IO_LATENCY_MODE_S
+{
+	OUT HW_IO_LATENCY_MODES_E UpstreamLatency;
+	OUT HW_IO_LATENCY_MODES_E DownstreamLatency;
+} HW_IO_LATENCY_MODE_S,
+  * PHW_IO_LATENCY_MODE_S;
+
+
+//
+//	HW_IO_GET_INTERLEAVE_DEPTH
+//
+
+typedef struct _HW_IO_INTERLEAVE_DEPTH_S
+{
+	OUT DWORD dwUpstreamDepth;
+	OUT DWORD dwDownstreamDepth;
+} HW_IO_INTERLEAVE_DEPTH_S,
+  * PHW_IO_INTERLEAVE_DEPTH_S;
+
+//
+//	HW_IO_GET_DATA_PATH_SELECTION
+//	HW_IO_SET_DATA_PATH_SELECTION
+//
+
+typedef enum HW_IO_DATA_PATH_CODES_E
+{
+	HW_IO_DATA_PATH_START			= 0,
+
+	HW_IO_DATA_PATH_AUTOMATIC		= 0,
+	HW_IO_DATA_PATH_FAST,				// 1
+	HW_IO_DATA_PATH_INTERLEAVED,		// 2
+	HW_IO_DATA_PATH_UNKNOWN,			// 3
+
+	HW_IO_DATA_PATH_END					// 4
+
+} HW_IO_DATA_PATH_CODES_T;
+#define DEFAULT_HW_IO_DATA_PATH_SELECTION		HW_IO_DATA_PATH_FAST
+
+typedef OUT IN	HW_IO_DATA_PATH_CODES_T		HW_IO_DATA_PATH_SELECTION_T;	// OUT for HW_IO_GET_DATA_PATH_SELECTION
+																			// IN  for HW_IO_SET_DATA_PATH_SELECTION
+typedef HW_IO_DATA_PATH_SELECTION_T			* PHW_IO_DATA_PATH_SELECTION_T;
+
+
+
+//
+//	HW_IO_GET_LINE_STATUS
+//
+
+typedef enum HW_IO_MODEM_STATUS_CODES_E
+{
+	HW_IO_MODEM_STATUS_START					= 0,
+
+	HW_IO_MODEM_STATUS_DOWN						= 0,
+	HW_IO_MODEM_STATUS_ACTIVATION,					// 1
+	HW_IO_MODEM_STATUS_TRANSCEIVER_TRAINING,
+	HW_IO_MODEM_STATUS_CHANNEL_ANALYSIS,
+	HW_IO_MODEM_STATUS_EXCHANGE,
+	HW_IO_MODEM_STATUS_ACTIVATED,					// 5
+	HW_IO_MODEM_STATUS_WAITING_INIT,
+	HW_IO_MODEM_STATUS_INITIALIZING,
+	HW_IO_MODEM_STATUS_UNKNOWN,
+
+	HW_IO_MODEM_STATUS_END							// 9
+
+} HW_IO_MODEM_STATUS_CODES_T;
+
+typedef struct HW_IO_LINE_STATUS_S
+{
+	OUT	DWORD							LineSpeedUpOrFar;
+	OUT	DWORD							LineSpeedDownOrNear;
+	OUT	HW_IO_MODEM_STATUS_CODES_T		LineState;
+
+} HW_IO_LINE_STATUS_T,
+  * PHW_IO_LINE_STATUS_T;
+
+
+
+//
+//	HW_IO_GET_LINE_STATE
+//
+
+typedef OUT	HW_IO_MODEM_STATUS_CODES_T		HW_IO_LINE_STATE_T;
+typedef HW_IO_LINE_STATE_T					* PHW_IO_LINE_STATE_T;
+
+
+
+//
+//	HW_IO_GET_XCEIVER_STATUS
+//
+
+typedef struct			// Matches DATE_TYPE in types.h
+{
+	SHORT	year		:16;
+	WORD	day			: 8;
+	WORD	dayofweek	: 4;
+	WORD	month		: 4;
+} DATE_T,
+  * PDATE_T;
+
+typedef struct			// Matches TIME_TYPE in types.h
+{
+	BYTE		hr;
+	BYTE		min;
+	BYTE		sec;
+} TIME_T,
+  * PTIME_T;
+
+typedef struct
+{						// See DPUUTIL.C: UTIL_Get_ext_int16_str for how to print.
+	SHORT	Mar_Cur;	// Stored as hundredths
+	SHORT	Mar_Min;	// Stored as hundredths
+	WORD	Mar_Min_Bin;
+} SNR_MARGIN_T,
+  * PSNR_MARGIN_T;
+
+typedef struct HW_IO_XCEIVER_STATUS_S
+{
+	OUT	DATE_T				Date;
+	OUT	TIME_T				Time;
+	OUT	BYTE				Transmit_State;
+	OUT	BYTE				Receive_State;
+	OUT	BYTE				Process_State;
+	OUT	SNR_MARGIN_T		Up_SNR_Margin;
+	OUT	SNR_MARGIN_T		Down_SNR_Margin;
+	OUT	SHORT				Up_Attn;			// Stored as hundredths
+	OUT	SHORT				Down_Attn;			// Stored as hundredths
+	OUT	CHAR				Tx_Power;
+	OUT	WORD				Up_Bits_Per_Frame;
+	OUT	WORD				Down_Bits_Per_Frame;
+	OUT	WORD				Startup_Attempts;
+	OUT	DWORD				Up_CRC_Errors;
+	OUT	DWORD				Down_CRC_Errors;
+	OUT	DWORD				Up_FEC_Errors;
+	OUT	DWORD				Down_FEC_Errors;
+	OUT	DWORD				Up_HEC_Errors;
+	OUT	DWORD				Down_HEC_Errors;
+	OUT	DWORD				Retrain_Attempts;
+
+} HW_IO_XCEIVER_STATUS_T,
+  * PHW_IO_XCEIVER_STATUS_T;
+
+
+
+
+
+//
+//	HW_IO_GET_TRANSCEIVER_STATUS
+//
+
+//typedef struct			// Matches DATE_TYPE in types.h
+//{
+//	SHORT	year		:16;
+//	WORD	day			: 8;
+//	WORD	dayofweek	: 4;
+//	WORD	month		: 4;
+//} DATE_T,
+//  * PDATE_T;
+//
+//typedef struct			// Matches TIME_TYPE in types.h
+//{
+//	BYTE		hr;
+//	BYTE		min;
+//	BYTE		sec;
+//} TIME_T,
+//  * PTIME_T;
+//
+//typedef struct
+//{						// See DPUUTIL.C: UTIL_Get_ext_int16_str for how to print.
+//	SHORT	Mar_Cur;	// Stored 8.8 (8 bits integer, 8 bits fraction)
+//	SHORT	Mar_Min;	// Stored 8.8 (8 bits integer, 8 bits fraction)
+//	WORD	Mar_Min_Bin;
+//} SNR_MARGIN_T,
+//  * PSNR_MARGIN_T;
+
+typedef struct HW_IO_TRANSCEIVER_STATUS_S
+{
+	OUT	DATE_T				Date;
+	OUT	TIME_T				Time;
+	OUT	BYTE				Transmit_State;
+	OUT	BYTE				Receive_State;
+	OUT	BYTE				Process_State;
+	OUT	SNR_MARGIN_T		Up_SNR_Margin;
+	OUT	SNR_MARGIN_T		Down_SNR_Margin;
+	OUT	SHORT				Up_Attn;
+	OUT	SHORT				Down_Attn;
+	OUT	CHAR				Tx_Power;
+	OUT	WORD				Up_Bits_Per_Frame;
+	OUT	WORD				Down_Bits_Per_Frame;
+	OUT	WORD				Startup_Attempts;
+	OUT	DWORD				Up_CRC_Errors;
+	OUT	DWORD				Down_CRC_Errors;
+	OUT	DWORD				Up_FEC_Errors;
+	OUT	DWORD				Down_FEC_Errors;
+	OUT	DWORD				Up_HEC_Errors;
+	OUT	DWORD				Down_HEC_Errors;
+	OUT	DWORD				Retrain_Attempts;
+
+} HW_IO_TRANSCEIVER_STATUS_T,
+  * PHW_IO_TRANSCEIVER_STATUS_T;
+
+
+
+
+
+
+//
+//	HW_IO_GET_PERFORMANCE
+//
+
+typedef struct HW_IO_PERFORMANCE_S
+{
+	OUT	DWORD							R_relCapacityOccupationDnstr;
+	OUT	DWORD							R_noiseMarginDnstr;
+	OUT	DWORD							R_outputPowerUpstr;
+	OUT	DWORD							R_attenuationDnstr;
+	OUT	DWORD							R_relCapacityOccupationUpstr;
+	OUT	DWORD							R_noiseMarginUpstr;
+	OUT	DWORD							R_outputPowerDnstr;
+	OUT	DWORD							R_attenuationUpstr;
+	OUT	DWORD							R_ChanDataIntNear;
+	OUT	DWORD							R_ChanDataFastNear;
+	OUT	DWORD							R_ChanDataIntFar;
+	OUT	DWORD							R_ChanDataFastFar;
+	OUT	HW_IO_MODEM_STATUS_CODES_T		M_ModemStatus;
+	OUT	DWORD							M_NsecValidBerFast;
+	OUT	DWORD							M_AccBerFast;
+
+} HW_IO_PERFORMANCE_T,
+  * PHW_IO_PERFORMANCE_T;
+
+
+
+//
+//	HW_IO_SET_TRACE
+//
+
+typedef enum
+{
+	HW_IO_DIAGNOS_WRITE_BUS		= 0x0001,	// Send DiagnosticWrites	to Bus
+	
+	HW_IO_DIAGNOS_LOG_TRACE		= 0x0002,	// Trace Diagnostic log		to debug port
+	HW_IO_DBG_PORT_TRACE		= 0x0004,	// trace RAM Buffer			to debug port
+	
+	HW_IO_AOC_TRACE				= 0x0008,	// trace AOC				to RAM Buffer
+	HW_IO_EOC_TRACE				= 0x0010,	// trace EOC				to RAM Buffer
+	HW_IO_AFE_WRITE_TRACE		= 0x0020,	// trace AFE				to RAM Buffer
+	HW_IO_DMT_FSM_TRACE			= 0x0040,	// trace DMT FSM			to RAM Buffer
+	HW_IO_AUTOSENSE_TRACE		= 0x0080,	// trace Autosense			to RAM Buffer
+	HW_IO_EOC_CLR_TRACE			= 0x0100	// trace EOC Clear Chan		to RAM Buffer
+} HW_IO_TRACE_CODES_T;
+
+typedef IN	DWORD			HW_IO_TRACE_T;
+typedef HW_IO_TRACE_T		* PHW_IO_TRACE_T;
+
+
+
+//
+//	HW_IO_GET_SWITCHHOOK_TYPE
+//	HW_IO_SET_SWITCHHOOK_TYPE
+//
+
+typedef enum HW_IO_SWITCHHOOK_TYPE_S
+{
+	HW_IO_SWITCHHOOK_TYPE_FIRST			= 0,
+	HW_IO_SWITCHHOOK_TYPE_START			= HW_IO_SWITCHHOOK_TYPE_FIRST-1,
+
+	HW_IO_SWITCHHOOK_HARDWARE,
+	HW_IO_SWITCHHOOK_SOFTWARE,
+
+	HW_IO_SWITCHHOOK_TYPE_END,
+	HW_IO_SWITCHHOOK_TYPE_LAST			= HW_IO_SWITCHHOOK_TYPE_END-1
+} HW_IO_SWITCHHOOK_TYPE_T;
+typedef HW_IO_SWITCHHOOK_TYPE_T	* PHW_IO_SWITCHHOOK_TYPE_T;
+#define HW_IO_SWITCHHOOK_TYPE_SIZE	(HW_IO_SWITCHHOOK_TYPE_END-HW_IO_SWITCHHOOK_TYPE_FIRST)
+
+typedef IN DWORD HW_IO_GET_SWITCHHOOK_TYPE_T ;									// HW_IO_SWITCHHOOK_TYPE_T
+typedef HW_IO_GET_SWITCHHOOK_TYPE_T * PHW_IO_GET_SWITCHHOOK_TYPE_T ;
+
+typedef IN DWORD HW_IO_SET_SWITCHHOOK_TYPE_T ;									// HW_IO_SWITCHHOOK_TYPE_T
+typedef HW_IO_SET_SWITCHHOOK_TYPE_T * PHW_IO_SET_SWITCHHOOK_TYPE_T ;
+
+
+
+
+//
+//	HW_IO_GET_SWITCHHOOK_STATUS
+//
+
+typedef enum HW_IO_SWITCHHOOK_STATUS_S
+{
+	HW_IO_SWITCHHOOK_STATUS_FIRST			= 0,
+	HW_IO_SWITCHHOOK_STATUS_START			= HW_IO_SWITCHHOOK_STATUS_FIRST-1,
+
+	HW_IO_SWITCHHOOK_ONHOOK,
+	HW_IO_SWITCHHOOK_OFFHOOK,
+
+	HW_IO_SWITCHHOOK_STATUS_END,
+	HW_IO_SWITCHHOOK_STATUS_LAST			= HW_IO_SWITCHHOOK_STATUS_END-1
+} HW_IO_SWITCHHOOK_STATUS_T;
+typedef HW_IO_SWITCHHOOK_STATUS_T	* PHW_IO_SWITCHHOOK_STATUS_T;
+#define HW_IO_SWITCHHOOK_STATUS_SIZE	(HW_IO_SWITCHHOOK_STATUS_END-HW_IO_SWITCHHOOK_STATUS_FIRST)
+
+typedef OUT DWORD HW_IO_GET_SWITCHHOOK_STATUS_T ;								// HW_IO_SWITCHHOOK_STATUS_T
+typedef HW_IO_GET_SWITCHHOOK_STATUS_T * PHW_IO_GET_SWITCHHOOK_STATUST ;
+
+
+
+//
+//	HW_IO_SET_SOFTWARE_SWITCHHOOK
+//
+
+typedef IN DWORD HW_IO_SET_SOFTWARE_SWITCHHOOK_T ;								// HW_IO_SWITCHHOOK_STATUS_T
+
+
+//
+//	HW_IO_GET_HEAD_END
+//	HW_IO_SET_HEAD_END
+//
+
+										// Vendor codes as listed in 
+										// Annex D,	ANSI T1.413	- 1998
+typedef enum _HW_IO_ADSL_VENDORS_E
+{
+	HW_IO_VENDOR_ID_NONE 					= 0x0000,	// Unknown vendor.
+	HW_IO_VENDOR_ID_WESTELL 				= 0x0002,	// Westell Inc.
+	HW_IO_VENDOR_ID_ECI 					= 0x0003,	// ECI Telecom
+	HW_IO_VENDOR_ID_TEXAS_INSTRUMENTS		= 0x0004,	// Texas Instruments
+	HW_IO_VENDOR_ID_INTEL					= 0x0005,	// Intel
+	HW_IO_VENDOR_ID_AMATI					= 0x0006,	// Amati Communications	Corp.
+	HW_IO_VENDOR_ID_GENERAL_DATA 			= 0x0007,	// General Data	Communication
+	HW_IO_VENDOR_ID_LEVEL_ONE				= 0x0008,	// Level One Communications
+	HW_IO_VENDOR_ID_CRYSTAL 				= 0x0009,	// Crystal Semiconductor
+	HW_IO_VENDOR_ID_ATT_NETWORK 			= 0x000A,	// AT&T	- Network Systems
+	HW_IO_VENDOR_ID_AWARE					= 0x000B,	// Aware, Inc.
+	HW_IO_VENDOR_ID_BROOKTREE				= 0x000C,	// Brooktree
+	HW_IO_VENDOR_ID_NEC 					= 0x000D,	// NEC
+	HW_IO_VENDOR_ID_SAMSUNG					= 0x000E,	// Samsung
+	HW_IO_VENDOR_ID_NORTHERN_TELECOM		= 0x000F,	// Northern	Telecom, Inc.
+	HW_IO_VENDOR_ID_PAIRGAIN				= 0x0010,	// PairGain	Technologies
+	HW_IO_VENDOR_ID_ATT_PAIRGAIN			= 0x0011,	// AT&T	- Paradyne		
+	HW_IO_VENDOR_ID_ADTRAN					= 0x0012,	// Adtran				
+	HW_IO_VENDOR_ID_INC						= 0x0013,	// INC					
+	HW_IO_VENDOR_ID_ADC						= 0x0014,	// ADC Telecommunications
+	HW_IO_VENDOR_ID_MOTOROLA				= 0x0015,	// Motorola
+	HW_IO_VENDOR_ID_IBM						= 0x0016,	// IBM Corp.
+	HW_IO_VENDOR_ID_NEWBRIDGE				= 0x0017,	// Newbridge Networks Corp.
+	HW_IO_VENDOR_ID_DSC						= 0x0018,	// DSC
+	HW_IO_VENDOR_ID_TELTREND				= 0x0019,	// TelTrend
+	HW_IO_VENDOR_ID_EXAR					= 0x001A,	// Exar	Corp.
+	HW_IO_VENDOR_ID_SIEMENS					= 0x001B,	// Siemens Stromberg-Carlson
+	HW_IO_VENDOR_ID_ANALOG_DEVICES			= 0x001C,	// Analog Devices
+	HW_IO_VENDOR_ID_NOKIA					= 0x001D,	// Nokia
+	HW_IO_VENDOR_ID_ERICSSON				= 0x001E,	// Ericsson	Systems
+	HW_IO_VENDOR_ID_TELLABS					= 0x001F,	// Tellabs Operations, Inc.
+	HW_IO_VENDOR_ID_ORCKIT					= 0x0020,	// Orckit Communications, Inc
+	HW_IO_VENDOR_ID_AWA						= 0x0021,	// AWA
+	HW_IO_VENDOR_ID_ALCATEL					= 0x0022,	// Alcatel Network Systems In
+	HW_IO_VENDOR_ID_NATIONAL				= 0x0023,	// National	Semiconductor Sys
+	HW_IO_VENDOR_ID_ITALTEL					= 0x0024,	// Italtel
+	HW_IO_VENDOR_ID_SAT						= 0x0025,	// SAT
+	HW_IO_VENDOR_ID_FUJITSU					= 0x0026,	// Fujitsu Network Transmissi
+	HW_IO_VENDOR_ID_MITEL					= 0x0027,	// MITEL
+	HW_IO_VENDOR_ID_CONKLIN					= 0x0028,	// Conklin Instrument Corp.
+	HW_IO_VENDOR_ID_DIAMOND					= 0x0029,	// Diamond Lane
+	HW_IO_VENDOR_ID_CABLETRON				= 0x002A,	// Cabletron Systems, Inc.
+	HW_IO_VENDOR_ID_DAVICOM					= 0x002B,	// Davicom Semiconductor, Inc
+	HW_IO_VENDOR_ID_METALINK				= 0x002C,	// Metalink
+	HW_IO_VENDOR_ID_PULSECOM				= 0x002D,	// Pulsecom
+	HW_IO_VENDOR_ID_US_ROBOTICS				= 0x002E,	// US Robotics
+	HW_IO_VENDOR_ID_AG_COMMUNICATIONS		= 0x002F,	// AG Communications Systems
+	HW_IO_VENDOR_ID_CONEXANT				= 0x0030,	// Conexant	Systems	Inc.
+	HW_IO_VENDOR_ID_HARRIS					= 0x0031,	// Harris
+	HW_IO_VENDOR_ID_HAYES					= 0x0032,	// Hayes Microcomputer Produc
+	HW_IO_VENDOR_ID_CO_OPTIC				= 0x0033,	// Co-optic
+	HW_IO_VENDOR_ID_NETSPEED				= 0x0034,	// Netspeed	Inc.
+	HW_IO_VENDOR_ID_3COM					= 0x0035,	// 3-Com
+	HW_IO_VENDOR_ID_COPPER_MTN				= 0x0036,	// Copper Mountain Inc.
+	HW_IO_VENDOR_ID_SILICON_AUTO 			= 0x0037,	// Silicon Automation Systems
+	HW_IO_VENDOR_ID_ASCOM					= 0x0038,	// Ascom
+	HW_IO_VENDOR_ID_GLOBESPAN				= 0x0039,	// Globespan Inc.
+	HW_IO_VENDOR_ID_SGS_THOMPSON			= 0x003A,	// ST Microelectronics
+	HW_IO_VENDOR_ID_COPPERCOM				= 0x003B,	// Coppercom"
+	HW_IO_VENDOR_ID_COMPAQ					= 0x003C,	// Compaq Computer Corp."
+	HW_IO_VENDOR_ID_INTEGRATED_TECH			= 0x003D,	// Integrated Technology Expr
+	HW_IO_VENDOR_ID_BAY_NETWORKS			= 0x003E,	// Bay Networks, Inc."
+	HW_IO_VENDOR_ID_NEXT_LEVEL				= 0x003F,	// Next	Level Communications"
+	HW_IO_VENDOR_ID_MULTI_TECH				= 0x0040,	// Multitech Systems, Inc."
+	HW_IO_VENDOR_ID_AMD						= 0x0041,	// AMD"
+	HW_IO_VENDOR_ID_SUMITOMO				= 0x0042,	// Sumitomo Electric"
+	HW_IO_VENDOR_ID_PHILLIPS_M_N			= 0x0043,	// Phillips M&N Electronics"
+	HW_IO_VENDOR_ID_EFFICIENT_NETWORKS		= 0x0044,	// Efficient Networks, Inc."
+	HW_IO_VENDOR_ID_INTERSPEED				= 0x0045,	// Interspeed"
+	HW_IO_VENDOR_ID_CISCO					= 0x0046,	// Cisco Systems"
+	HW_IO_VENDOR_ID_TOLLGRADE				= 0x0047,	// Tollgrade Communciations, 
+	HW_IO_VENDOR_ID_CAYMAN					= 0x0048,	// Cayman Systems"
+	HW_IO_VENDOR_ID_FLOWPOINT				= 0x0049,	// FlowPoint Corp."
+	HW_IO_VENDOR_ID_ICCOM					= 0x004A,	// I.C.COM"
+	HW_IO_VENDOR_ID_MATSUSHITA	 			= 0x004B,	// Matsushita"
+	HW_IO_VENDOR_ID_SIEMENS_SEMICO			= 0x004C,	// Siemens Semiconductor"
+	HW_IO_VENDOR_ID_DIGITAL_LINK			= 0x004D,	// Digital Link"
+	HW_IO_VENDOR_ID_DIGITEL					= 0x004E,	// Digitel"
+	HW_IO_VENDOR_ID_ALCATEL_MICRO			= 0x004F,	// Alcatel Microelectronics"
+	HW_IO_VENDOR_ID_CENTILLIUM				= 0x0050,	// Centillium Corp."
+	HW_IO_VENDOR_ID_APPLIED_DIGITAL			= 0x0051,	// Applied Digital Access, In
+	HW_IO_VENDOR_ID_SMART_LINK   			= 0x0052,	// Smart Link, Ltd."
+	HW_IO_VENDOR_ID_MEDIALINCS				= 0xB6DB,	// Medialincs (Korean)
+	HW_IO_VENDOR_ID_UNKNOWN	   				= 0xFFFF	// Unknown Vendor
+} HW_IO_ADSL_VENDORS_E;
+
+
+
+typedef OUT	DWORD				HW_IO_GET_HEAD_END_T;
+typedef HW_IO_GET_HEAD_END_T		* PHW_IO_GET_HEAD_END_T;
+
+typedef IN	DWORD				HW_IO_SET_HEAD_END_T;
+typedef HW_IO_SET_HEAD_END_T		* PHW_IO_SET_HEAD_END_T;
+
+
+
+
+//
+//	HW_IO_GET_HEAD_END_ENV
+//	HW_IO_SET_HEAD_END_ENV
+//
+
+
+typedef enum _HW_IO_HEAD_END_ENVIRONMENT_E
+{
+	HW_IO_HEAD_END_ENV_NON_SPECIFIC = 0,	// Non-Specific"
+	HW_IO_HEAD_END_ENV_NO_LINE_DRIVER		// No Line Driver (BNA)
+} HW_IO_HEAD_END_ENVIRONMENT_E;
+
+
+typedef OUT	DWORD				HW_IO_GET_HEAD_END_ENV_T;
+typedef HW_IO_GET_HEAD_END_ENV_T		* PHW_IO_GET_HEAD_END_ENV_T;
+
+typedef IN	DWORD				HW_IO_SET_HEAD_END_ENV_T;
+typedef HW_IO_SET_HEAD_END_ENV_T		* PHW_IO_SET_HEAD_END_ENV_T;
+
+
+//
+// HW_IO_EOC_COMMAND
+//
+
+typedef struct HW_IO_EOC_COMMAND_S
+{
+	DWORD		EOCCommandType;
+	DWORD		EOCXcvrNumber;
+	DWORD		EOCState;
+	DWORD		EOCRegister;
+	DWORD		EOCRegSize;
+	BYTE		EOCData;				
+
+} HW_IO_EOC_COMMAND_T,
+  * PHW_IO_EOC_COMMAND_T;
+
+typedef enum _HW_IO_EOC_CODES_E
+{
+	
+	EOC_SUSPEND_POLLING,
+	EOC_SET_HOLD_STATE,
+	EOC_RETURN_NORMAL_STATE,
+	EOC_SEND_SELF_TEST,
+	EOC_REQUEST_CORRUPT_CRC_START,
+	EOC_REQUEST_CORRUPT_CRC_STOP,
+	EOC_NOTIFY_CORRUPT_CRC_START,
+	EOC_NOTIFY_CORRUPT_CRC_STOP,
+	EOC_READ_REG,
+	EOC_WRITE_REG,
+	EOC_POLL_READ_REG,
+	EOC_POLL_DYING_GASP
+
+} HW_IO_EOC_CODES_E;
+
+//
+//	HW_IO_IS_LINE_STARTABLE
+//
+
+typedef OUT DWORD 				HW_IO_LINE_STARTABLE_T;
+typedef HW_IO_LINE_STARTABLE_T		* PHW_IO_LINE_STARTABLE_T;
+
+
+//
+//	HW_IO_AFE_EEPROM
+//	HW_IO_AFE_REV	
+//
+typedef OUT	DWORD				HW_IO_GET_AFE_EEPROM_T;
+typedef OUT	DWORD				HW_IO_GET_AFE_REV_T;
+
+//
+//	HW_IO_GET_SERIAL_DATA_PATH
+//	HW_IO_SET_SERIAL_DATA_PATH
+//
+
+typedef IN OUT	DWORD			HW_IO_SERIAL_DATA_PATH_T;
+
+
+
+#endif		//#ifndef _HWIODMT_H_
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/hwio.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/hwio.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/hwio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/hwio.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,1557 @@
+/******************************************************************************
+*******************************************************************************
+**
+**	MODULE NAME:
+**		HwIo (though global and available to all files)
+**
+**	FILE NAME:
+**		HwIo.h
+**
+**	ABSTRACT:
+**		This file contains defines for accessing the driver
+**		through a device specific function/method (e.g., through
+**		the "OID_TAPI_DEV_SPECIFIC" OID of the driver registered
+**		SetInformationHandler function).
+**		This is the device specific interface through which
+**		applications may access certain driver specific information.
+**
+**	DETAILS:
+**
+**	NOTES:
+**		This device specific hardware input/output (HwIo) interface to the
+**		driver has legacy names (some are listed below).
+**			Bd, BD								now HwIo, HW_IO
+**			BackDoor, MiniBackDoor				now HwIo
+**			pBackDoorBuf, pMiniBackDoorBuf		now pHwIo
+**			BACK_DOOR_T, MINI_BACK_DOOR_T		now HW_IO_CMD_STRUC_T
+**		See the text file "HwIoFromDevIo.txt" for more details.
+**
+**
+*****************************************************************************
+**
+**	Copyright (c) 2000, 2001
+**	Conexant Systems Inc. (formerly Rockwell Semiconductor Systems)
+**
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+*******************************************************************************
+** $Archive:   S:/Embedded/archives/Linux/BSP_CX821xx/uClinux2.4.6/linux/include/asm-armnommu/arch-cx821xx/hwio.h-arc  $
+** $Revision:   1.0  $
+** $Date:   Mar 19 2003 13:49:02  $
+*******************************************************************************
+******************************************************************************/
+/**/	//This is a Page Eject character.
+
+#ifndef _HWIO_H_
+#define _HWIO_H_
+
+
+//* Ioctl Format:
+//*
+//* CTL_CODE( DeviceType, Function, Method, Access ) (
+//*   ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)
+//*
+//* Note: Custom Functions must must have the MSB set i.e., 8xx)
+//*
+#define IOCTL_DEVICE_SPECIFIC		CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_GET_VERSION			CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_CNX_DEV_SPECIFIC		CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_DEVICE_CONFIG			CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_DEVICE_APP    		CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_CNX_NET_DEV_SPECIFIC	CTL_CODE(FILE_DEVICE_NETWORK, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_CNX_NET_DATA			CTL_CODE(FILE_DEVICE_NETWORK, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_CNX_NET_OPEN			CTL_CODE(FILE_DEVICE_NETWORK, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_CNX_NET_CLOSE			CTL_CODE(FILE_DEVICE_NETWORK, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_CNX_NET_ECHO_PARENT	CTL_CODE(FILE_DEVICE_NETWORK, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//	General Definitions (defines)
+//
+///////////////////////////////////////////////////////////////////////////////
+
+
+//	The following define specifies that instead of a particular VC index,
+//	this index value specifies to return statistics for all VCs on the link.
+#define HW_IO_ATM_STATS_INDEX_FOR_LINK			0xFFFF
+
+//	The following define specifies that instead of a particular VC index,
+//	this index value specifies to return statistics for all VCs on the link.
+#define HW_IO_AAL_STATS_INDEX_FOR_LINK			0xFFFF
+
+
+// Mask for determining Message bits
+#define DEBUG_MESSAGE_LEVEL				0x0000001D
+#define DEBUG_MODULE_ID_MASK			0xffff0000
+#define DBG_DISABLED					0x00000000
+#define DBG_ENA_MESSAGES				0x00000001
+#define DBG_ENA_BREAKPOINTS				0x00000002
+#define DBG_ENA_MISC_MSG				0x00000004
+#define DBG_ENA_WARNING_MSG				0x00000008
+#define DBG_ENA_ERROR_MSG				0x00000010
+#define DBG_ENA_MISC_BRK				0x00000020
+#define DBG_ENA_WARNING_BRK				0x00000040
+#define DBG_ENA_ERROR_BRK				0x00000080
+#define DBG_ENA_DRVR_ENTRY_BRK			0x00000100
+									//	0x00000200
+									//	0x00000400
+									//	0x00000800
+									//	0x00001000
+									//	0x00002000
+									//	0x00004000
+									//	0x00008000
+#define DBG_ENABLE_CHIPAL				0x00010000
+#define DBG_ENABLE_CARDAL				0x00020000
+#define DBG_ENABLE_CARDMGMT				0x00040000
+#define DBG_ENABLE_FRAMEAL				0x00080000
+#define DBG_ENABLE_BUFMGMT				0x00100000
+#define DBG_ENABLE_CELLDATATEST			0x00200000
+#define DBG_ENABLE_CONDIS				0x00400000
+									//	0x00800000
+									//	0x01000000
+									//	0x02000000
+									//	0x04000000
+									//	0x08000000
+#define DBG_ENABLE_HW_IO_MSG_DUMP		0x10000000
+									//	0x20000000
+									//	0x40000000
+									//	0x80000000
+// The following are defined for use but are defined here for Appy purposes.
+#define DBG_ENABLE_BIT_0			0x00000001
+#define DBG_ENABLE_BIT_1			0x00000002
+#define DBG_ENABLE_BIT_2			0x00000004
+#define DBG_ENABLE_BIT_3			0x00000008
+#define DBG_ENABLE_BIT_4			0x00000010
+#define DBG_ENABLE_BIT_5			0x00000020
+#define DBG_ENABLE_BIT_6			0x00000040
+#define DBG_ENABLE_BIT_7			0x00000080
+#define DBG_ENABLE_BIT_8			0x00000100
+#define DBG_ENABLE_BIT_9			0x00000200
+#define DBG_ENABLE_BIT_10			0x00000400
+#define DBG_ENABLE_BIT_11			0x00000800
+#define DBG_ENABLE_BIT_12			0x00001000
+#define DBG_ENABLE_BIT_13			0x00002000
+#define DBG_ENABLE_BIT_14			0x00004000
+#define DBG_ENABLE_BIT_15			0x00008000
+#define DBG_ENABLE_BIT_16			0x00010000
+#define DBG_ENABLE_BIT_17			0x00020000
+#define DBG_ENABLE_BIT_18			0x00040000
+#define DBG_ENABLE_BIT_19			0x00080000
+#define DBG_ENABLE_BIT_20			0x00100000
+#define DBG_ENABLE_BIT_21			0x00200000
+#define DBG_ENABLE_BIT_22			0x00400000
+#define DBG_ENABLE_BIT_23			0x00800000
+#define DBG_ENABLE_BIT_24			0x01000000
+#define DBG_ENABLE_BIT_25			0x02000000
+#define DBG_ENABLE_BIT_26			0x04000000
+#define DBG_ENABLE_BIT_27			0x08000000
+#define DBG_ENABLE_BIT_28			0x10000000
+#define DBG_ENABLE_BIT_29			0x20000000
+#define DBG_ENABLE_BIT_30			0x40000000
+#define DBG_ENABLE_BIT_31			0x80000000
+
+
+
+
+/**/	//This is a Page Eject character.
+//////////////////////////////////////////////
+//	HW IO Structure Definition
+//////////////////////////////////////////////
+
+typedef struct DEVIO_HEADER_s
+{
+	IN	DWORD		InstanceId;
+	IN	DWORD		ReqCode;
+	IN	DWORD		TotalSize;
+	OUT	DWORD		NeededSize;
+	OUT	DWORD		ResultCode;
+} DEVIO_HEADER_T,
+  * PDEVIO_HEADER_T;
+
+
+typedef struct HW_IO_CMD_STRUC_S
+{
+	IN	DWORD		InstanceId;
+	IN	DWORD		ReqCode;
+	IN	DWORD		TotalSize;
+	OUT	DWORD		NeededSize;
+	OUT	DWORD		ResultCode;
+	I_O	DWORD		Params;
+} HW_IO_CMD_STRUC_T, * PHW_IO_CMD_STRUC_T;
+
+// The size of the HW_IO header is the size of the structure "HW_IO_CMD_STRUC_T"
+// minus the size of the "Params" element (a DWORD).
+#define HW_IO_HEADER_SIZE		(sizeof(HW_IO_CMD_STRUC_T) - sizeof(DWORD))
+
+//	The following define gives the sizeof the TAPI Dev Specific header
+//	structure, excluding the "Params" element which is overlayed by the
+//	BackDoor structure/data.
+#define TAPI_DEV_SPECIFIC_SIZE	(sizeof( NDIS_TAPI_DEV_SPECIFIC ) - sizeof( UCHAR * ))
+
+
+
+
+/**/	//This is a Page Eject character.
+//////////////////////////////////////////////
+//	HW IO Request Code Definitions
+//////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+// NOTES:
+//	* !!!!!!!!!!!!!!!!!!!!!!!!   C A U T I O N !   !!!!!!!!!!!!!!!!!!!!!!!! *
+//	*	Even though the request codes appear to be grouped logically in the
+//	*	enumeration below DO NOT REMOVE any codes (enumeration elements)
+//	*	from the enumeration list below!
+//	*	Always ADD NEW ELEMENTS TO END OF LIST (before "HW_IO_LAST_CMD_CODE")!
+//	*	The reason for never deleting any elements from the list and always
+//	*	adding new elements to the end of the enumeration list is to maintain
+//	*	backwards compatibility (i.e., allows Appy programs to communicate
+//	*	with older drivers).
+//	* !!!!!!!!!!!!!!!!!!!!!!!!   C A U T I O N !   !!!!!!!!!!!!!!!!!!!!!!!! *
+///////////////////////////////////////////////////////////////////////////////
+
+// these IO CMDS for IOCTL_DEVICE_SPECIFIC	
+typedef enum HW_IO_CMDS_E
+{
+	HW_IO_FIRST_CMD_CODE			= 0,
+
+	HW_IO_GET_BUFMGMT_CONFIG		= 0,
+	HW_IO_SET_BUFMGMT_CONFIG		= 1,
+
+	HW_IO_GET_HW_INTERFACE_STATS	= 2,
+	HW_IO_CLEAR_HW_INTERFACE_STATS	= 3,
+
+	HW_IO_GET_FRAMEAL_STATS			= 4,
+	HW_IO_GET_FRAMEAL_ATM_STATS		= 5,
+	HW_IO_GET_FRAMEAL_AAL_STATS		= 6,
+	HW_IO_GET_FRAMEAL_CONFIG		= 7,
+	HW_IO_SET_FRAMEAL_CONFIG		= 8,
+
+	HW_IO_GET_ALARMS				= 9,
+	HW_IO_GET_BIT_ALLOC_TABLE		= 10,
+	HW_IO_GET_SNR_TABLE				= 11,
+	HW_IO_GET_CONTROLLER_LOG_CLT	= 12,
+	HW_IO_SET_CONTROLLER_LOG_CLT	= 13,
+	HW_IO_GET_GHS_CAP				= 14,
+	HW_IO_GET_GHS_LOCAL_CAP			= 15,
+	HW_IO_SET_GHS_LOCAL_CAP			= 16,
+	HW_IO_SET_AUTO_SENSE			= 17,	// HW_IO_GET_AUTO_SENSE is further down table
+	HW_IO_GET_EEPROM_MAC_ADDR		= 18,
+	HW_IO_SET_EEPROM_MAC_ADDR		= 19,
+
+	HW_IO_USER_ACTIVATE_LINE		= 20,
+	HW_IO_USER_DEACTIVATE_LINE		= 21,
+	HW_IO_GET_CONNECT_STATUS		= 22,
+	HW_IO_GET_DEBUG_FLAG			= 23,
+	HW_IO_SET_DEBUG_FLAG			= 24,
+	HW_IO_GET_PRODUCT_INFO			= 25,
+	HW_IO_SIMULATE_INCOMING			= 26,
+	HW_IO_SIMULATE_REMOTE_DISC		= 27,
+	HW_IO_SIMULATE_CONNECTED		= 28,
+	HW_IO_GET_VC_CONNECT_STATE		= 29,
+	HW_IO_OPEN_HW_IO_INSTANCE		= 30,
+	HW_IO_CLOSE_HW_IO_INSTANCE		= 31,
+	HW_IO_GET_PRODUCT_VERSION		= 32,
+	HW_IO_GET_CURRENT_MAC_ADDR		= 33,
+
+	HW_IO_INIT_DATA_PUMP			= 34,
+	HW_IO_GET_DP_VERSIONS			= 35,
+	HW_IO_GET_CONN_CONFIG			= 36,
+	HW_IO_SET_CONN_CONFIG			= 37,
+	HW_IO_GET_MODEM_DATA			= 38,
+	HW_IO_GET_DATA_PATH_SELECTION	= 39,
+	HW_IO_SET_DATA_PATH_SELECTION	= 40,
+	HW_IO_GET_LINE_STATUS			= 41,
+	HW_IO_GET_LINE_STATE			= 42,
+	HW_IO_GET_REGISTER				= 43,
+	HW_IO_SET_REGISTER				= 44,
+	HW_IO_GET_BUS_CONTROLLER		= 45,
+	HW_IO_GET_PM_POWER_STATE		= 46,
+	HW_IO_SET_PM_POWER_STATE		= 47,
+	HW_IO_GET_TRANSCEIVER_STATUS	= 48,
+	HW_IO_GET_ADSL_CONFIG			= 49,	// ** NOT USED **
+	HW_IO_SET_ADSL_CONFIG			= 50,	// ** NOT USED **
+	HW_IO_GET_PERFORMANCE			= 51,
+	HW_IO_GET_TEXT_LOG				= 52,
+
+	HW_IO_START_DIGITAL_LOOPBACK	= 53,
+	HW_IO_STOP_DIGITAL_LOOPBACK		= 54,
+	HW_IO_START_CELL_VERIFY			= 55,
+	HW_IO_STOP_CELL_VERIFY			= 56,
+	HW_IO_GET_CELL_VERIFY_STATS		= 57,
+	HW_IO_START_ATM_BER				= 58,
+	HW_IO_STOP_ATM_BER				= 59,
+	HW_IO_INJECT_ATM_BER_ERRORS		= 60,
+	HW_IO_GET_ATM_BER_STATUS		= 61,
+	HW_IO_GET_ATM_BER_STATS			= 62,
+	HW_IO_GET_ATM_BER_64BIT_STATS	= 63,
+	HW_IO_CLEAR_ATM_BER_STATS		= 64,
+
+	HW_IO_SET_TRACE					= 65,
+	HW_IO_DEBUG						= 66,
+
+	HW_IO_GET_LOG_START				= 67,
+	HW_IO_GET_BUFMGMT_LOG				= HW_IO_GET_LOG_START,
+	HW_IO_GET_FRAMEAL_LOG			= 68,
+	HW_IO_GET_CHIPAL_LOG			= 69,
+	HW_IO_GET_LOG_RESERVED_01		= 70,
+	HW_IO_GET_LOG_RESERVED_02		= 71,
+	HW_IO_GET_LOG_RESERVED_03		= 72,
+	HW_IO_GET_LOG_RESERVED_04		= 73,
+	HW_IO_GET_LOG_RESERVED_05		= 74,
+	HW_IO_GET_LOG_RESERVED_06		= 75,
+	HW_IO_GET_LOG_RESERVED_07		= 76,
+	HW_IO_GET_LOG_RESERVED_08		= 77,
+	HW_IO_GET_LOG_RESERVED_09		= 78,
+	HW_IO_GET_LOG_RESERVED_10		= 79,
+	HW_IO_GET_LOG_RESERVED_11		= 80,
+	HW_IO_GET_LOG_RESERVED_12		= 81,
+	HW_IO_GET_LOG_RESERVED_13		= 82,
+	HW_IO_GET_LOG_RESERVED_14		= 83,
+	HW_IO_GET_LOG_RESERVED_15		= 84,
+	HW_IO_GET_LOG_RESERVED_16		= 85,
+	HW_IO_GET_LOG_RESERVED_17		= 86,
+	HW_IO_GET_LOG_RESERVED_18		= 87,
+	HW_IO_GET_LOG_RESERVED_19		= 88,
+	HW_IO_GET_LOG_RESERVED_20		= 89,
+	HW_IO_GET_LOG_END					= HW_IO_GET_LOG_RESERVED_20,
+	
+	HW_IO_GET_AUTO_SENSE			= 90,	// HW_IO_SET_AUTO_SENSE is further up table
+	HW_IO_GET_MODULATION			= 91,
+
+	HW_IO_OAM_LOOPBACK_INIT			= 92,  // F5 PING send request
+	HW_IO_OAM_LOOPBACK_RESPONSE		= 93,  // results of F5 PING request
+
+
+	HW_IO_SERIAL_DATA_OPEN			= 94,
+	HW_IO_SERIAL_DATA_CLOSE			= 95,
+	HW_IO_SERIAL_DATA_READ	    	= 96,
+	HW_IO_SERIAL_DATA_WRITE			= 97,
+
+	HW_IO_GET_SWITCHHOOK_TYPE		= 98,
+	HW_IO_SET_SWITCHHOOK_TYPE		= 99,
+	HW_IO_GET_SWITCHHOOK_STATUS		= 100,
+	HW_IO_SET_SOFTWARE_SWITCHHOOK	= 101,
+
+	HW_IO_GET_HEAD_END				= 102,
+	HW_IO_SET_HEAD_END				= 103,
+	HW_IO_GET_HEAD_END_ENV			= 104,
+	HW_IO_SET_HEAD_END_ENV			= 105,
+	
+	HW_IO_IS_LINE_STARTABLE			= 106,
+	
+   	HW_IO_READ_DRIVER_COMMAND_ASYNC	= 107,
+
+	HW_IO_OPEN_CONTROL_CHANNEL			= 108,
+	HW_IO_CLOSE_CONTROL_CHANNEL			= 109,
+	HW_IO_OPEN_COMMUNICATIONS_CHANNEL	= 110,
+	HW_IO_CLOSE_COMMUNICATIONS_CHANNEL	= 111,
+
+	HW_IO_GET_LATENCY_MODE			= 112,
+	HW_IO_GET_INTERLEAVE_DEPTH		= 113,
+	
+	// ALWAYS ADD NEW enumeration elements here!
+
+	HW_IO_LAST_CMD_CODE				// ALWAYS the last enumeration element!
+
+} HW_IO_CMDS_T;
+
+
+
+
+/**/	//This is a Page Eject character.
+//////////////////////////////////////////////
+//	HW IO 'Params' Definitions
+//////////////////////////////////////////////
+
+#include "hwiodmt.h"
+
+//
+//	HW_IO_OPEN_CONTROL_CHANNEL
+//	HW_IO_OPEN_COMMUNICATIONS_CHANNEL
+//
+
+//
+typedef enum HW_IO_CHANNEL_TYPE_E
+{
+	HW_IO_CHANNEL_CONTROL=0,
+	HW_IO_CHANNEL_APPY,
+	HW_IO_CHANNEL_SERIAL_DATA
+} HW_IO_CHANNEL_TYPE_T;
+	
+
+
+typedef struct HW_IO_CONFIG_OPEN_CHANNEL_S
+{
+	IN	HW_IO_CHANNEL_TYPE_T 	ChannelType;
+	OUT DWORD					InstanceId;
+
+} HW_IO_CONFIG_OPEN_CHANNEL_T;
+
+
+	
+
+//
+//	HW_IO_GET_BUFMGMT_CONFIG
+//	HW_IO_SET_BUFMGMT_CONFIG
+//
+
+typedef struct HW_IO_BUFMGMT_CONFIG_S
+{
+	OUT IN	DWORD		RxMaxFrameSize;		// OUT for HW_IO_GET_BUFMGMT_CONFIG
+											// IN  for HW_IO_SET_BUFMGMT_CONFIG
+	OUT IN	DWORD		TxMaxFrameSize;		// OUT for HW_IO_GET_BUFMGMT_CONFIG
+											// IN  for HW_IO_SET_BUFMGMT_CONFIG
+
+} HW_IO_BUFMGMT_CONFIG_T,
+  * PHW_IO_BUFMGMT_CONFIG_T;
+
+
+
+//
+//	HW_IO_GET_HW_INTERFACE_STATS
+//
+
+typedef struct HW_IO_HW_INTERFACE_STATS_S
+{
+	OUT	DWORD		InterruptCountTx;
+	OUT	DWORD		InterruptCountRx;
+	OUT	DWORD		BytesTransmitted;
+	OUT	DWORD		BytesReceived;
+	OUT	DWORD		InterruptsMissedTx;
+	OUT	DWORD		InterruptsMissedRx;
+	OUT	DWORD		UnderRun;
+	OUT	DWORD		OverRun;
+} HW_IO_HW_INTERFACE_STATS_T,
+  * PHW_IO_HW_INTERFACE_STATS_T;
+
+
+
+//
+//	HW_IO_CLEAR_HW_INTERFACE_STATS
+//
+
+// NO Parameters
+
+
+
+//
+//	HW_IO_GET_FRAMEAL_STATS
+//
+
+typedef struct HW_IO_FRAMEAL_STATS_S
+{
+	OUT	DWORD		NumRxBytes;
+	OUT	DWORD		NumRxFrames;
+
+	OUT	DWORD		NumTxBytes;
+	OUT	DWORD		NumTxFrames;
+
+	OUT	DWORD		NumAbortErrs;
+	OUT	DWORD		NumCrcErrs;
+	OUT	DWORD		NumTxUnderrunErrs;
+
+} HW_IO_FRAMEAL_STATS_T,
+  * PHW_IO_FRAMEAL_STATS_T;
+
+
+
+//
+//	HW_IO_GET_FRAMEAL_ATM_STATS
+//
+
+typedef struct HW_IO_FRAMEAL_ATM_STATS_S
+{
+	IN	DWORD		VcIndex;
+
+	OUT	DWORD		NumTxBytes;
+	OUT	DWORD		NumTxCells;
+	OUT	DWORD		NumTxMgmtCells;
+	OUT	DWORD		NumTxClpEqual0Cells;
+	OUT	DWORD		NumTxClpEqual1Cells;
+
+	OUT	DWORD		NumRxBytes;
+	OUT	DWORD		NumRxCells;
+	OUT	DWORD		NumRxMgmtCells;
+	OUT	DWORD		NumRxClpEqual0Cells;
+	OUT	DWORD		NumRxClpEqual1Cells;
+
+	OUT	DWORD		NumRxHecErrs;				//	for Link ONLY!
+	OUT	DWORD		NumRxCellAlignErrs;			//	for Link ONLY!
+	OUT	DWORD		NumRxUnroutCellErrs;		//	for Link ONLY!
+
+} HW_IO_FRAMEAL_ATM_STATS_T,
+  * PHW_IO_FRAMEAL_ATM_STATS_T;
+
+
+
+//
+//	HW_IO_GET_FRAMEAL_AAL_STATS
+//
+
+typedef enum HW_IO_AAL_TYPES_E
+{
+	HW_IO_AAL_TYPE_START	=	0,	// 0
+
+	HW_IO_AAL_TYPE_0		=	0,	// 0	=> AAL_TYPE_AAL0	1
+	HW_IO_AAL_TYPE_1,				// 1	=> AAL_TYPE_AAL1	2
+	HW_IO_AAL_TYPE_34,				// 2	=> AAL_TYPE_AAL34	4
+	HW_IO_AAL_TYPE_5,				// 3	=> AAL_TYPE_AAL5	8
+
+	HW_IO_AAL_TYPE_END				// 4
+
+} HW_IO_AAL_TYPES_T;
+
+typedef struct HW_IO_FRAMEAL_AAL_STATS_S
+{
+	IN	DWORD		VcIndex;
+
+// ????????????
+	OUT	HW_IO_AAL_TYPES_T		AalType;			//	for VC (not Link) ONLY!
+
+	OUT	DWORD		NumTxGoodBytes;
+	OUT	DWORD		NumTxGoodFrames;
+	OUT	DWORD		NumTxDiscardedBytes;
+	OUT	DWORD		NumTxDiscardedFrames;
+
+	OUT	DWORD		NumRxGoodBytes;
+	OUT	DWORD		NumRxGoodFrames;
+	OUT	DWORD		NumRxDiscardedBytes;
+	OUT	DWORD		NumRxDiscardedFrames;
+
+	OUT	DWORD		NumRxCrcErrs;
+	OUT	DWORD		NumRxInvalidLenErrs;
+	OUT	DWORD		NumRxTimeoutErrs;
+
+} HW_IO_FRAMEAL_AAL_STATS_T,
+  * PHW_IO_FRAMEAL_AAL_STATS_T;
+
+
+
+//
+//	HW_IO_GET_FRAMEAL_CONFIG
+//	HW_IO_SET_FRAMEAL_CONFIG
+//
+
+typedef enum HW_IO_ENCAPSULATION_E		// RfcEncapsulationMode values:
+{
+	HW_IO_ENCAPSULATION_START			= 0,
+
+											// NOTE:
+											//		These values are from the
+											//		ADSL Forum 99.102.0 spec.
+											//	These values MUST MATCH the values
+											//	from this document!!
+	HW_IO_ENCAPSULATION_PPPOA_VCMUX		= 0,	// PPP over ATM VXMUX					// was RFC2364_VCMUX
+	HW_IO_ENCAPSULATION_PPPOA_LLC,				// PPP over ATM LLC						// was RFC2364_LLC
+	HW_IO_ENCAPSULATION_BIPOA_LLC,				// Bridged IP over ATM LLCSNAP			// was RFC1483_LLC_BRIDGED
+	HW_IO_ENCAPSULATION_RIPOA_LLC,				// Routed IP over ATM LLCSNAP			// was RFC1483_LLC_ROUTED
+	HW_IO_ENCAPSULATION_BIPOA_VCMUX,			// Bridged IP over ATM VCMUX			// was RFC1483_VCMUX_BRIDGED
+	HW_IO_ENCAPSULATION_RIPOA_VCMUX,			// Routed IP over ATM VCMUX				// was RFC1483_VCMUX_ROUTED
+	HW_IO_ENCAPSULATION_IPOA,					// Classical IP over ATM				// was n/a
+	HW_IO_ENCAPSULATION_NATIVE_ATM,				// Native ATM							// was n/a
+	HW_IO_ENCAPSULATION_PROPRIETARY		= -1,	// Proprietary							// was n/a
+	// The next three enumerations are added for CNXT-defined encapsulations,
+	// they are not found in the ADSL Forum documentation.
+	HW_IO_ENCAPSULATION_PPPOA_NONE		= 0x80,	// PPP over ATM no encapsulation		// was RFC2364_NONE
+	HW_IO_ENCAPSULATION_BIPOA_NONE,				// Bridged IP over ATM no encapsulation	// was RFC1483_NULL
+	HW_IO_ENCAPSULATION_RIPOA_NONE,				// Routed IP over ATM no encapsulation	// was RFC1483_NULL
+	HW_IO_ENCAPSULATION_NONE			= 0xF8,	// Encapsulation performed above driver	// was n/a
+
+	HW_IO_ENCAPSULATION_END
+
+} HW_IO_ENCAPSULATION_T;
+
+typedef OUT IN	HW_IO_ENCAPSULATION_T		HW_IO_FRAMEAL_CONFIG_T;		// OUT for HW_IO_GET_FRAMEAL_CONFIG,
+																		// IN  for HW_IO_SET_FRAMEAL_CONFIG
+typedef HW_IO_FRAMEAL_CONFIG_T				* PHW_IO_FRAMEAL_CONFIG_T;
+
+
+
+
+
+
+//
+//	HW_IO_GET_EEPROM_MAC_ADDR
+//	HW_IO_SET_EEPROM_MAC_ADDR
+//	also same for HW_IO_GET_CURRENT_MAC_ADDR
+//
+#define NUMBER_MAC_ELEMENTS 6
+
+typedef BYTE							HW_IO_MAC_ADDRESS_ELEMENT_T;		// Type of data for each element
+typedef HW_IO_MAC_ADDRESS_ELEMENT_T		HW_IO_MAC_ADDRESS_T [NUMBER_MAC_ELEMENTS];	// OUT for HW_IO_GET_EEPROM_MAC_ADDR
+															// IN  for HW_IO_SET_EEPROM_MAC_ADDR
+															// OUT for HW_IO_GET_CURRENT_MAC_ADDR
+typedef HW_IO_MAC_ADDRESS_T		* PHW_IO_MAC_ADDRESS_T;
+
+
+
+//
+//	HW_IO_GET_DEBUG_FLAG
+//	HW_IO_SET_DEBUG_FLAG
+//
+
+typedef DWORD					HW_IO_DEBUG_FLAG_T;		// OUT for HW_IO_GET_DEBUG_FLAG
+														// IN  for HW_IO_SET_DEBUG_FLAG
+typedef HW_IO_DEBUG_FLAG_T		* PHW_IO_DEBUG_FLAG_T;
+
+
+
+//
+//	HW_IO_GET_PRODUCT_INFO
+//
+
+typedef struct HW_IO_PRODUCT_INFO_S
+{
+	OUT	DWORD		DrvrSwVer;
+	OUT	DWORD		DrvrTapiVer;
+	OUT	DWORD		DrvrNdisVer;
+
+} HW_IO_PRODUCT_INFO_T,
+  * PHW_IO_PRODUCT_INFO_T;
+
+
+
+//
+//	HW_IO_SIMULATE_INCOMING
+//	HW_IO_SIMULATE_REMOTE_DISC
+//	HW_IO_SIMULATE_CONNECTED
+//
+
+typedef IN	DWORD				HW_IO_VC_INDEX_T;
+typedef HW_IO_VC_INDEX_T		* PHW_IO_VC_INDEX_T;
+
+
+
+//
+//	HW_IO_GET_VC_CONNECT_STATE
+//
+
+typedef enum HW_IO_VC_CONNECT_STATE_CODES_E
+{
+	HW_IO_VC_STATE_START			= 0,
+
+	HW_IO_VC_STATE_IDLE				= 0,
+	HW_IO_VC_STATE_DIALTONE,			//1
+	HW_IO_VC_STATE_DIALING,				//2
+	HW_IO_VC_STATE_PROCEEDING,			//3
+	HW_IO_VC_STATE_RINGBACK,			//4
+	HW_IO_VC_STATE_OFFERING,			//5
+	HW_IO_VC_STATE_ACCEPTED,			//6
+	HW_IO_VC_STATE_CONNECTED,			//7
+	HW_IO_VC_STATE_DISCONNECTED,		//8
+	HW_IO_VC_STATE_BUSY,				//9
+
+	HW_IO_VC_STATE_END					//10
+
+} HW_IO_VC_CONNECT_STATE_CODES_T;
+
+typedef struct HW_IO_VC_CONNECT_STATE_S
+{
+	OUT	DWORD								VcSelectIndex;
+	OUT	HW_IO_VC_CONNECT_STATE_CODES_T		VcConnectState;
+
+} HW_IO_VC_CONNECT_STATE_T,
+  * PHW_IO_VC_CONNECT_STATE_T;
+
+
+
+//
+//	HW_IO_OPEN_HW_IO_INSTANCE
+//	HW_IO_CLOSE_HW_IO_INSTANCE
+//
+
+typedef enum HW_IO_INSTANCE_CODES_E
+{
+	HW_IO_INSTANCE_START			= 0,
+
+	HW_IO_INSTANCE_SUCCESS			= 0,
+	HW_IO_INSTANCE_EMPTY,				//1
+	HW_IO_INSTANCE_UNAVAILABLE,			//2
+	HW_IO_INSTANCE_FAILURE,				//3
+
+	HW_IO_INSTANCE_END					//4
+
+} HW_IO_INSTANCE_CODES_T;
+
+typedef IN	DWORD				HW_IO_INSTANCE_T;
+typedef HW_IO_INSTANCE_T		* PHW_IO_INSTANCE_T;
+
+
+
+//
+//	HW_IO_GET_PRODUCT_VERSION
+//
+
+#define MAX_HW_IO_PRODUCT_VERSION_SIZE		40
+
+typedef OUT	CHAR					HW_IO_PRODUCT_VERSION_T [MAX_HW_IO_PRODUCT_VERSION_SIZE];
+typedef HW_IO_PRODUCT_VERSION_T		* PHW_IO_PRODUCT_VERSION_T;
+
+
+
+//
+//	HW_IO_GET_CURRENT_MAC_ADDR
+//
+
+// Use existing define "HW_IO_MAC_ADDRESS_T".
+// See "HW_IO_GET_EEPROM_MAC_ADDR" and "HW_IO_SET_EEPROM_MAC_ADDR"
+//     for define of "HW_IO_MAC_ADDRESS_T".
+
+
+
+//
+//	HW_IO_
+//	HW_IO_
+//
+
+//	This request response will return as many driver text log reference
+//	numbers and parameters (that are queued in the driver) as it can fit
+//	into the response.
+//	Each driver text log will be of type "HW_IO_DRIVER_LOG_T", as defined below.
+//		xxx->FirstDword.Words.Size = ZZZ1 (Text Msg Size, in DWORDs, not including the
+//			 								1st DWORD a combination of Size and Type)
+//		xxx->FirstDword.Words.Type = ZZZ2 (string reference number, type HW_IO_TEXT_MSGS_T)
+//		xxx->DwordArray[0] = XYZ1 (if one or more parameters to log)
+//		...
+//		xxx->DwordArray[n] = XYZn (last parameter to log, if any)
+
+#define NUM_PARAMS_0				0
+#define NUM_PARAMS_1				1
+#define NUM_PARAMS_6				6
+#define MAX_DWORDS_IN_TEXT_LOG_MSG	64
+#define MAX_BYTES_IN_TEXT_LOG_MSG	(sizeof(DWORD) * MAX_DWORDS_IN_TEXT_LOG_MSG)
+#define MAX_NUM_LOG_PARAMS			(MAX_DWORDS_IN_TEXT_LOG_MSG - 2)	// subtract 2 for 64-bit timestamp value
+
+#define BY_1_WORD					16
+
+#define MASK_OFF_MSW				0x0000FFFF
+#define MASK_OFF_LSW				0xFFFF0000
+
+typedef enum HW_IO_TEXT_MSGS_E
+{
+	//	TEXT_MSG  ==>  TM
+
+	HW_IO_TM_ZERO_NOT_USED			= 0,	// value of zero is not used!
+
+	HW_IO_TM_PACKED_STRING,					// NOT USED in string lookup table ("TextLogStrings")
+											//	since there is no predefined string constant.
+
+	HW_IO_TM_ADSL_PSD_TEST_MODE,
+	HW_IO_TM_ADSL_RX_IDLE_CHAR,
+	HW_IO_TM_ADSL_RX_IDLE_TIMER,
+	HW_IO_TM_API_HW_IF_MODE,
+// ???? TO USE OR NOT TO USE, THAT IS THE QUESTION ????
+	HW_IO_TM_ATM_SERVER,					// ???? TO USE OR NOT TO USE, THAT IS THE QUESTION ????
+	HW_IO_TM_ATM_TX_CELL_A_FILE,
+	HW_IO_TM_ATM_TX_CELL_B_FILE,
+	HW_IO_TM_CELL_BURST_SIZE,
+	HW_IO_TM_DP_AUTO_DOWNLOAD,
+	HW_IO_TM_DP_BOOT_FILENAME,
+	HW_IO_TM_DP_BOOT_JUMPADDRESS,
+	HW_IO_TM_DP_FILENAME,
+	HW_IO_TM_DP_JUMP_ADDRESS,
+	HW_IO_TM_FPGA_PROGRAM_ENABLE,
+	HW_IO_TM_FPGA_PROGRAM_FILE,
+	HW_IO_TM_LINE_AUTO_ACTIVATION,
+	HW_IO_TM_LINE_PERSISTENCE_TIMER,
+	HW_IO_TM_LINE_PERSISTENT_ACTIVATION,
+	HW_IO_TM_LT_MODE,
+	HW_IO_TM_MAX_TRANSMIT,
+	HW_IO_TM_NUMBER_OF_LINES,
+	HW_IO_TM_RX_BUF_ALLOC_LIMIT,
+	HW_IO_TM_RX_BUF_RATIO_LIMIT,
+	HW_IO_TM_RX_FIFO_SIZE,
+	HW_IO_TM_RX_INTERRUPT_RATE,
+	HW_IO_TM_RX_MAX_LATENCY,
+	HW_IO_TM_RX_MIN_LATENCY,
+	HW_IO_TM_RX_SPEED,
+	HW_IO_TM_TX_FIFO_SIZE,
+	HW_IO_TM_TX_INTERRUPT_RATE,
+	HW_IO_TM_TX_MAX_LATENCY,
+	HW_IO_TM_TX_MIN_LATENCY,
+	HW_IO_TM_TX_SPEED,
+	HW_IO_TM_INVALID_MAC_ADDR,
+	HW_IO_TM_INVALID_STRING,
+
+	HW_IO_TM_END
+} HW_IO_TEXT_MSGS_T;
+
+//
+//	These enumeration values are to be typed as a DWORD.
+//	Where the most significant word (upper 16 bits) defines how many
+//	parameters (DWORDs) are to follow (to be printed/displayed after
+//	the indicated text string) and the least significant word (lower
+//	16 bits) defines the enumeration value used to indicate the text
+//	string (to be printed/displayed).
+//
+
+typedef enum HW_IO_LOG_MSGS_E
+{
+	//	LOG_MSG  ==>  LM
+
+	HW_IO_LM_ZERO_NOT_USED				= 0,	// value of zero is not used!
+
+	// SPECIAL CASE (for HW_IO_LM_PACKED_STRING):
+	//		The most significant word will be the number of DWORDs that
+	//		follow (a variable number, possibly different each time),
+	//		containing a packed string (sz).
+	//		This enumeration value is NOT USED in string lookup table
+	//		("TextLogStrings") since there is no predefined string constant.
+	HW_IO_LM_PACKED_STRING				= HW_IO_TM_PACKED_STRING,
+
+	HW_IO_LM_ADSL_PSD_TEST_MODE			= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_ADSL_PSD_TEST_MODE,
+	HW_IO_LM_ADSL_RX_IDLE_CHAR			= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_ADSL_RX_IDLE_CHAR,
+	HW_IO_LM_ADSL_RX_IDLE_TIMER			= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_ADSL_RX_IDLE_TIMER,
+	HW_IO_LM_API_HW_IF_MODE				= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_API_HW_IF_MODE,
+// ???? TO USE OR NOT TO USE, THAT IS THE QUESTION ????
+	HW_IO_LM_ATM_SERVER					= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_ATM_SERVER,	// ???? TO USE OR NOT TO USE, THAT IS THE QUESTION ????
+/**/HW_IO_LM_ATM_TX_CELL_A_FILE			= (MAX_NUM_LOG_PARAMS << BY_1_WORD) | HW_IO_TM_ATM_TX_CELL_A_FILE,
+/**/HW_IO_LM_ATM_TX_CELL_B_FILE			= (MAX_NUM_LOG_PARAMS << BY_1_WORD) | HW_IO_TM_ATM_TX_CELL_B_FILE,
+	HW_IO_LM_CELL_BURST_SIZE			= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_CELL_BURST_SIZE,
+	HW_IO_LM_DP_AUTO_DOWNLOAD			= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_DP_AUTO_DOWNLOAD,
+/**/HW_IO_LM_DP_BOOT_FILENAME			= (MAX_NUM_LOG_PARAMS << BY_1_WORD) | HW_IO_TM_DP_BOOT_FILENAME,
+	HW_IO_LM_DP_BOOT_JUMPADDRESS		= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_DP_BOOT_JUMPADDRESS,
+/**/HW_IO_LM_DP_FILENAME				= (MAX_NUM_LOG_PARAMS << BY_1_WORD) | HW_IO_TM_DP_FILENAME,
+	HW_IO_LM_DP_JUMP_ADDRESS			= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_DP_JUMP_ADDRESS,
+	HW_IO_LM_FPGA_PROGRAM_ENABLE		= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_FPGA_PROGRAM_ENABLE,
+/**/HW_IO_LM_FPGA_PROGRAM_FILE			= (MAX_NUM_LOG_PARAMS << BY_1_WORD) | HW_IO_TM_FPGA_PROGRAM_FILE,
+	HW_IO_LM_LINE_AUTO_ACTIVATION		= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_LINE_AUTO_ACTIVATION,
+	HW_IO_LM_LINE_PERSISTENCE_TIMER		= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_LINE_PERSISTENCE_TIMER,
+	HW_IO_LM_LINE_PERSISTENT_ACTIVATION	= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_LINE_PERSISTENT_ACTIVATION,
+	HW_IO_LM_LT_MODE					= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_LT_MODE,
+	HW_IO_LM_MAX_TRANSMIT				= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_MAX_TRANSMIT,
+	HW_IO_LM_NUMBER_OF_LINES			= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_NUMBER_OF_LINES,
+	HW_IO_LM_RX_BUF_ALLOC_LIMIT			= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_RX_BUF_ALLOC_LIMIT,
+	HW_IO_LM_RX_BUF_RATIO_LIMIT			= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_RX_BUF_RATIO_LIMIT,
+	HW_IO_LM_RX_FIFO_SIZE				= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_RX_FIFO_SIZE,
+	HW_IO_LM_RX_INTERRUPT_RATE			= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_RX_INTERRUPT_RATE,
+	HW_IO_LM_RX_MAX_LATENCY				= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_RX_MAX_LATENCY,
+	HW_IO_LM_RX_MIN_LATENCY				= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_RX_MIN_LATENCY,
+	HW_IO_LM_RX_SPEED					= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_RX_SPEED,
+	HW_IO_LM_TX_FIFO_SIZE				= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_TX_FIFO_SIZE,
+	HW_IO_LM_TX_INTERRUPT_RATE			= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_TX_INTERRUPT_RATE,
+	HW_IO_LM_TX_MAX_LATENCY				= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_TX_MAX_LATENCY,
+	HW_IO_LM_TX_MIN_LATENCY				= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_TX_MIN_LATENCY,
+	HW_IO_LM_TX_SPEED					= (NUM_PARAMS_1 << BY_1_WORD) | HW_IO_TM_TX_SPEED,
+	HW_IO_LM_INVALID_MAC_ADDR			= (NUM_PARAMS_6 << BY_1_WORD) | HW_IO_TM_INVALID_MAC_ADDR,
+	HW_IO_LM_INVALID_STRING				= (NUM_PARAMS_0 << BY_1_WORD) | HW_IO_TM_INVALID_STRING,
+
+	HW_IO_LM_END
+} HW_IO_LOG_MSGS_T;
+
+#define HW_IO_TEXT_LOG_ATM_TX_CELL_A_FILE	"Default value for AtmTxCellAFile used "
+#define HW_IO_TEXT_LOG_ATM_TX_CELL_B_FILE	"Default value for AtmTxCellBFile used "
+#define HW_IO_TEXT_LOG_DP_BOOT_FILENAME	"Default value for DpBootFilename used "
+#define HW_IO_TEXT_LOG_DP_FILENAME			"Default value for DpFilename used "
+#define HW_IO_TEXT_LOG_FPGA_PROGRAM_FILE	"Default value for FpgaProgramFile used "
+
+typedef struct HW_IO_LOG_TYPE_SIZE_S
+{
+	WORD		Type;
+	WORD		Size;
+} HW_IO_LOG_TYPE_SIZE_T;
+
+typedef union HW_IO_LOG_1ST_DWORD_U
+{
+	DWORD						Dword;
+	HW_IO_LOG_TYPE_SIZE_T		Words;
+} HW_IO_LOG_1ST_DWORD_T;
+
+typedef struct HW_IO_DRIVER_LOG_S
+{
+	HW_IO_LOG_1ST_DWORD_T		FirstDword;
+	DWORD						DwordArray [MAX_DWORDS_IN_TEXT_LOG_MSG];
+} HW_IO_DRIVER_LOG_T;
+
+typedef struct HW_IO_DRIVER_LOG_WITH_TIME_S
+{
+	HW_IO_LOG_1ST_DWORD_T		FirstDword;
+	LONGLONG					SystemTime;
+	DWORD						DwordArray [MAX_NUM_LOG_PARAMS];
+} HW_IO_DRIVER_LOG_WITH_TIME_T;
+
+
+
+//
+//	HW_IO_GET_CONN_CONFIG
+//	HW_IO_SET_CONN_CONFIG
+//
+
+typedef enum HW_IO_PCR_KBPS_CODES_E
+{
+	HW_IO_PCR_START				= 0,
+
+	HW_IO_PCR_SAME_AS_LINE		= 0,
+
+	HW_IO_PCR_16_KBPS,				// 1
+	HW_IO_PCR_32_KBPS,
+	HW_IO_PCR_48_KBPS,
+	HW_IO_PCR_64_KBPS,				// 4
+	HW_IO_PCR_80_KBPS,
+	HW_IO_PCR_96_KBPS,
+	HW_IO_PCR_112_KBPS,
+	HW_IO_PCR_128_KBPS,				// 8
+	HW_IO_PCR_144_KBPS,
+	HW_IO_PCR_160_KBPS,
+	HW_IO_PCR_176_KBPS,
+	HW_IO_PCR_192_KBPS,				// 12
+	HW_IO_PCR_208_KBPS,
+	HW_IO_PCR_224_KBPS,
+	HW_IO_PCR_240_KBPS,
+	HW_IO_PCR_256_KBPS,				// 16
+	HW_IO_PCR_272_KBPS,
+	HW_IO_PCR_288_KBPS,
+	HW_IO_PCR_304_KBPS,
+	HW_IO_PCR_320_KBPS,				// 20
+	HW_IO_PCR_336_KBPS,
+	HW_IO_PCR_352_KBPS,
+	HW_IO_PCR_368_KBPS,
+	HW_IO_PCR_384_KBPS,				// 24
+	HW_IO_PCR_400_KBPS,
+	HW_IO_PCR_416_KBPS,
+	HW_IO_PCR_432_KBPS,
+	HW_IO_PCR_448_KBPS,				// 28
+	HW_IO_PCR_464_KBPS,
+	HW_IO_PCR_480_KBPS,
+	HW_IO_PCR_496_KBPS,
+	HW_IO_PCR_512_KBPS,				// 32
+	HW_IO_PCR_528_KBPS,
+	HW_IO_PCR_544_KBPS,
+	HW_IO_PCR_560_KBPS,
+	HW_IO_PCR_576_KBPS,				// 36
+	HW_IO_PCR_592_KBPS,
+	HW_IO_PCR_608_KBPS,
+	HW_IO_PCR_624_KBPS,
+	HW_IO_PCR_640_KBPS,				// 40
+	HW_IO_PCR_656_KBPS,
+	HW_IO_PCR_672_KBPS,
+	HW_IO_PCR_688_KBPS,
+	HW_IO_PCR_704_KBPS,				// 44
+	HW_IO_PCR_720_KBPS,
+	HW_IO_PCR_736_KBPS,
+	HW_IO_PCR_752_KBPS,
+	HW_IO_PCR_768_KBPS,				// 48
+	HW_IO_PCR_784_KBPS,
+	HW_IO_PCR_800_KBPS,
+	HW_IO_PCR_816_KBPS,
+	HW_IO_PCR_832_KBPS,				// 52
+
+	HW_IO_PCR_END
+
+} HW_IO_PCR_KBPS_CODES_T;
+
+typedef struct HW_IO_CONN_VPI_VCI_S
+{
+	BYTE						Vpi;		// Virtual Path Identifier
+	WORD						Vci;		// Virtual Channel Identifier
+	HW_IO_PCR_KBPS_CODES_T		Pcr;		// Peak Cell Rate
+
+} HW_IO_CONN_VPI_VCI_T,
+  * PHW_IO_CONN_VPI_VCI_T;
+
+typedef struct HW_IO_CONN_CONFIG_S
+{
+	OUT IN	DWORD						NumOfVc;	// OUT for HW_IO_GET_CONN_CONFIG
+													// IN  for HW_IO_SET_CONN_CONFIG
+//	OUT IN	HW_IO_CONN_VPI_VCI_T		VcArray [DEFAULT_NUMBER_OF_LINES];	// OUT for HW_IO_GET_CONN_CONFIG
+																			// IN  for HW_IO_SET_CONN_CONFIG
+
+} HW_IO_CONN_CONFIG_T,
+  * PHW_IO_CONN_CONFIG_T;
+
+typedef struct HW_IO_LOG_DATA_S
+{
+	OUT IN	DWORD		*BytesUsed;
+	OUT IN	DWORD		BytesMax;
+	OUT IN	DWORD		*Buffer;
+} HW_IO_LOG_DATA_T;
+
+//
+//	HW_IO_GET_MODEM_DATA
+//
+
+#define MAX_HW_IO_MODEM_BLOCK_DWORDS		32
+
+typedef BYTE						HW_IO_MODEM_BLOCK_DATA_T [MAX_HW_IO_MODEM_BLOCK_DWORDS * sizeof( DWORD )];
+typedef HW_IO_MODEM_BLOCK_DATA_T	* PHW_IO_MODEM_BLOCK_DATA_T;
+
+	//	The following definition gives the size (in BYTES) of the
+	//	space left after the elements "ModemBlockStartAddr" and
+	//	"ModemBlockLength" below.
+#define HW_IO_MODEM_BLOCK_DATA_SIZE		sizeof( HW_IO_MODEM_BLOCK_DATA_T )
+
+typedef struct HW_IO_MODEM_DATA_S
+{
+	IN	DWORD							ModemBlockStartAddr;
+	IN	DWORD							ModemBlockLength;
+	OUT	HW_IO_MODEM_BLOCK_DATA_T		ModemBlockData;
+
+} HW_IO_MODEM_DATA_T,
+  * PHW_IO_MODEM_DATA_T;
+
+
+
+//
+//	HW_IO_GET_REGISTER
+//	HW_IO_SET_REGISTER
+//
+
+// RegDataSize
+typedef enum HW_IO_REG_DATA_SIZE_E
+{
+	HW_IO_REG_DATA_SIZE_START		= 0,
+
+	HW_IO_REG_DATA_SIZE_DWORD_4		= 0,
+	HW_IO_REG_DATA_SIZE_WORD_2,			// 1
+	HW_IO_REG_DATA_SIZE_BYTE_1,			// 2
+
+	HW_IO_REG_DATA_SIZE_END				// 3
+
+} HW_IO_REG_DATA_SIZE_T;
+#define DEFAULT_HW_IO_REG_DATA_SIZE		HW_IO_REG_DATA_SIZE_DWORD_4
+
+// RegAccess
+typedef enum HW_IO_REG_ACCESS_E
+{
+	HW_IO_REG_ACCESS_START			= 0,
+
+	HW_IO_REG_ACCESS_MEMORY			= 0,
+	HW_IO_REG_ACCESS_HOBBES,			// 1
+	HW_IO_REG_ACCESS_ALCATEL_ADSL,		// 2
+	HW_IO_REG_ACCESS_BASIC2,			// 3
+	HW_IO_REG_ACCESS_EEPROM,			// 4
+	HW_IO_REG_ACCESS_ARM,				// 5
+	HW_IO_REG_ACCESS_MICROIF,			// 6
+
+	HW_IO_REG_ACCESS_END				// 7
+
+} HW_IO_REG_ACCESS_T;
+#define DEFAULT_HW_IO_REG_ACCESS		HW_IO_REG_ACCESS_MEMORY
+
+#define MAX_HW_IO_REGISTER_BYTES		128
+
+typedef struct HW_IO_REGISTER_S
+{
+	IN		DWORD						RegOffset;
+	IN		DWORD						RegMask;
+// ??????????????  use RegValue  -or-  VarLength and VarBuff  ??????????????????????
+	OUT IN	DWORD						RegValue;	// OUT for HW_IO_GET_REGISTER
+													// IN  for HW_IO_SET_REGISTER
+	IN		HW_IO_REG_DATA_SIZE_T		RegDataSize;
+	IN		HW_IO_REG_ACCESS_T			RegAccess;
+// ??????????????  use RegValue  -or-  VarLength and VarBuff  ??????????????????????
+	IN		DWORD						VarLength;
+	OUT IN	BYTE						VarBuff [MAX_HW_IO_REGISTER_BYTES];	// OUT for HW_IO_GET_REGISTER
+																			// IN  for HW_IO_SET_REGISTER
+
+} HW_IO_REGISTER_T,
+  * PHW_IO_REGISTER_T;
+
+
+
+//
+//	HW_IO_GET_BUS_CONTROLLER
+//
+
+#define	HW_IO_BUS_CTRLR_BASIC_2p1		"BASIC 2.1"
+#define	HW_IO_BUS_CTRLR_BASIC_2p15		"BASIC 2.15"
+#define	HW_IO_BUS_CTRLR_UNKNOWN			"*Unknown!*"
+
+#define MAX_HW_IO_BUS_CONTROLLER_BYTES		40
+
+typedef OUT	CHAR					HW_IO_BUS_CONTROLLER_T [MAX_HW_IO_BUS_CONTROLLER_BYTES];
+typedef HW_IO_BUS_CONTROLLER_T		* PHW_IO_BUS_CONTROLLER_T;
+
+
+
+//
+//	HW_IO_GET_PM_POWER_STATE
+//	HW_IO_SET_PM_POWER_STATE
+//
+
+typedef enum HW_IO_POWER_STATE_CODES_E
+{
+	HW_IO_PM_STATE_START	= 0,
+
+	HW_IO_PM_STATE_D0		= HW_IO_PM_STATE_START,	/* Fully Operational */
+	HW_IO_PM_STATE_D1,								/* PCI Clock Running, Process PME Event*/
+	HW_IO_PM_STATE_D2,								/* PCI Clock Off, Process PME Event */
+	HW_IO_PM_STATE_D3_HOT,							/* Power Off to Devices, Context Maintained*/
+	HW_IO_PM_STATE_D3_COLD,							/* Power Off to Devices, Context lost */
+
+	HW_IO_PM_STATE_END
+
+} HW_IO_PM_POWER_STATE_CODES_T;
+
+typedef DWORD						HW_IO_PM_POWER_STATE_T;		// OUT for HW_IO_GET_PM_POWER_STATE
+																// IN  for HW_IO_SET_PM_POWER_STATE
+typedef HW_IO_PM_POWER_STATE_T		* PHW_IO_PM_POWER_STATE_T;
+
+
+
+//
+//	HW_IO_START_DIGITAL_LOOPBACK
+//
+
+typedef struct HW_IO_DIGITAL_LOOPBACK_S
+{
+	IN	DWORD						TestDigLbVpi;		// Virtual Path Identifier
+	IN	DWORD						TestDigLbVci;		// Virtual Channel Identifier
+	IN	HW_IO_PCR_KBPS_CODES_T		TestDigLbPcr;		// Peak Cell Rate
+
+} HW_IO_DIGITAL_LOOPBACK_T,
+  * PHW_IO_DIGITAL_LOOPBACK_T;
+
+
+
+//
+//	HW_IO_STOP_DIGITAL_LOOPBACK
+//
+
+// NO Parameters
+
+
+
+//
+//	HW_IO_START_CELL_VERIFY
+//
+
+typedef enum HW_IO_CELL_VERIFY_PATTERNS_E
+{
+	HW_IO_CELL_VERIFY_PATTERN_START		= 0,
+
+	HW_IO_CELL_VERIFY_PATTERN_1			= 0,
+
+	HW_IO_CELL_VERIFY_PATTERN_END			// 1
+
+} HW_IO_CELL_VERIFY_PATTERNS_T;
+
+typedef struct HW_IO_CELL_VERIFY_S
+{
+	IN	DWORD								Vpi;		// Virtual Path Identifier
+	IN	DWORD								Vci;		// Virtual Channel Identifier
+	IN	HW_IO_CELL_VERIFY_PATTERNS_T		PatternIndex;
+	IN	HW_IO_PCR_KBPS_CODES_T				Pcr;		// Peak Cell Rate
+
+} HW_IO_CELL_VERIFY_T,
+  * PHW_IO_CELL_VERIFY_T;
+
+
+
+//
+//	HW_IO_STOP_CELL_VERIFY
+//
+
+// NO Parameters
+
+
+
+//
+//	HW_IO_GET_CELL_VERIFY_STATS
+//
+
+typedef struct HW_IO_CELL_VERIFY_STATS_S
+{
+	OUT	DWORD		NumTestFramesTxd;
+	OUT	DWORD		NumGoodTestFramesRxd;
+	OUT	DWORD		NumOutOfOrderTestFramesRxd;
+
+} HW_IO_CELL_VERIFY_STATS_T,
+  * PHW_IO_CELL_VERIFY_STATS_T;
+
+
+
+//
+//	HW_IO_START_ATM_BER
+//	HW_IO_GET_ATM_BER_STATUS
+//
+
+typedef enum HW_IO_ATM_BER_PATTERNS_E
+{
+	HW_IO_ATM_BER_PATTERN_START			= 0,
+
+	HW_IO_ATM_BER_PATTERN_NO_PATTERN	= 0,
+	HW_IO_ATM_BER_PATTERN_15BIT,
+	HW_IO_ATM_BER_PATTERN_20BIT,
+	HW_IO_ATM_BER_PATTERN_23BIT,
+	HW_IO_ATM_BER_PATTERN_USER_SUPPLIED,
+
+	HW_IO_ATM_BER_PATTERN__END
+
+} HW_IO_ATM_BER_PATTERNS_T;
+
+typedef enum HW_IO_ATM_BER_STATUS_CODES_E
+{
+	HW_IO_ATM_BER_START		= 0,
+
+	HW_IO_ATM_BER_IDLE		= 0,
+	HW_IO_ATM_BER_ACTIVE,
+	HW_IO_ATM_BER_RXONLY,
+
+	HW_IO_ATM_BER_END
+
+} HW_IO_ATM_BER_STATUS_CODES_T;
+
+typedef enum HW_IO_ATM_BER_INSERT_ERR_CODES_E
+{
+	HW_IO_ATM_BER_INJECT_START			= 0,
+
+	HW_IO_ATM_BER_INJECT_NO_ERROR		= 0,
+	HW_IO_ATM_BER_INJECT_SINGLE_ERROR,			// insert one error
+	HW_IO_ATM_BER_INJECT_ERROR_M3		= 3,	// insert one error every 10^3 bits
+	HW_IO_ATM_BER_INJECT_ERROR_M4,				// insert one error every 10^4 bits
+	HW_IO_ATM_BER_INJECT_ERROR_M5,				// insert one error every 10^5 bits
+	HW_IO_ATM_BER_INJECT_ERROR_M6,				// insert one error every 10^6 bits
+	HW_IO_ATM_BER_INJECT_ERROR_M7,				// insert one error every 10^7 bits
+
+	HW_IO_ATM_BER_INJECT_END
+
+} HW_IO_ATM_BER_INSERT_ERR_CODES_T;
+
+typedef struct HW_IO_ATM_BER_START_S
+{
+	IN	DWORD									Vpi;		// Virtual Path Identifier
+	IN	DWORD									Vci;		// Virtual Channel Identifier
+	IN	HW_IO_PCR_KBPS_CODES_T					Pcr;		// Peak Cell Rate
+	IN	HW_IO_ATM_BER_PATTERNS_T				Pattern;
+	IN	DWORD									UserPatternMask;
+	IN	BOOLEAN									RXInvert;	// expect receive data to be inverted
+	IN	BOOLEAN									TXInvert;	// Invert transmit data
+	IN	HW_IO_ATM_BER_STATUS_CODES_T			Status;		// On start sets status
+	IN	HW_IO_ATM_BER_INSERT_ERR_CODES_T		ErrInsertion;
+
+} HW_IO_ATM_BER_START_T,
+  * PHW_IO_ATM_BER_START_T,
+  HW_IO_ATM_BER_STATUS_T,
+  * PHW_IO_ATM_BER_STATUS_T;
+
+
+//
+//	HW_IO_STOP_ATM_BER
+//
+
+// NO Parameters
+
+
+
+//
+//	HW_IO_INJECT_ATM_BER_ERRORS
+//
+
+typedef IN	DWORD					HW_IO_ATM_BER_INJECT_T;
+typedef HW_IO_ATM_BER_INJECT_T		* PHW_IO_ATM_BER_INJECT_T;
+
+
+
+//
+//	HW_IO_GET_ATM_BER_STATS
+//
+typedef struct HW_IO_ATM_BER_STATS_S
+{
+	DWORD		RXBits;			// multiply by 10000
+	DWORD		RXErrorBits;
+	DWORD		RXResyncs;
+	DWORD		TXBits;			// multiply by 10000
+
+} HW_IO_ATM_BER_STATS_T,
+  * PHW_IO_ATM_BER_STATS_T;
+
+
+
+//
+//	HW_IO_GET_ATM_BER_64BIT_STATS
+//
+
+typedef struct HW_IO_ATM_BER_64BIT_STATS_S
+{
+	LONGLONG				RXBits;
+	LONGLONG				RXErrorBits;
+	LONGLONG				RXResyncs;
+	LONGLONG				TXBits;
+
+} HW_IO_ATM_BER_64BIT_STATS_T,
+  * PHW_IO_ATM_BER_64BIT_STATS_T;
+
+
+
+//
+//	HW_IO_CLEAR_ATM_BER_STATS
+//
+
+// NO Parameters
+
+
+
+//
+//	HW_IO_DEBUG
+//
+
+// DETAILS:
+//		On the control panel, use [ALT A] to enable the full set of tabs
+//		Click the "Custom Driver Commands"
+//		Enter 60012 for the opcode
+//		Enter desired sub-code(s) in the data field.
+//		The first sub-code will be/land in Buffer[0].
+
+#define MAX_DWORDS_IN_DEBUG_MSG	20
+
+typedef IN	DWORD			HW_IO_DEBUG_T [MAX_DWORDS_IN_DEBUG_MSG];
+typedef HW_IO_DEBUG_T		* PHW_IO_DEBUG_T;
+
+
+
+//
+//	HW_IO_OAM_LOOPBACK_INIT
+// 	HW_IO_OAM_LOOPBACK_RESPONSE
+//
+typedef enum  HW_IO_OAM_LOOPBACK_TYPE_E
+{
+	HW_IO_OAM_LOOPBACK_TYPE_F4_END_TO_END = 0,
+	HW_IO_OAM_LOOPBACK_TYPE_F4_SEGMENT,
+	HW_IO_OAM_LOOPBACK_TYPE_F5_END_TO_END,
+	HW_IO_OAM_LOOPBACK_TYPE_F5_SEGMENT
+
+} HW_IO_OAM_LOOPBACK_TYPE_T;
+	
+#define HW_IO_OAM_LOCATION_ID_LEN 	0x10
+#define HW_IO_OAM_SOURCE_ID_LEN 	0x10
+
+
+typedef enum  HW_IO_OAM_LOOPBACK_STATUS_E
+{
+	HW_IO_OAM_LOOPBACK_STATUS_PENDING = 0,
+	HW_IO_OAM_LOOPBACK_STATUS_SUCCESS,
+	HW_IO_OAM_LOOPBACK_STATUS_FAILURE,
+	HW_IO_OAM_LOOPBACK_STATUS_INVALID_REQ
+} HW_IO_OAM_LOOPBACK_STATUS_T;
+
+typedef struct HW_IO_OAM_LOOPBACK_S
+{
+	WORD						VCI;     // optional value, set to zero, driver selects VCI for 
+	HW_IO_OAM_LOOPBACK_TYPE_T 	Type;    // type of OAM ping requested
+	DWORD						CorrelationTag;  // non-zero value 
+	BYTE						LocationId[HW_IO_OAM_LOCATION_ID_LEN];		 //  optional value, if set to zero, driver will insert
+	BYTE					 	SourceId[HW_IO_OAM_SOURCE_ID_LEN];		 //  optional value, if set to zero, driver will insert
+	HW_IO_OAM_LOOPBACK_STATUS_T Status;  		 // Valid only for HW_IO_OAM_LOOPBACK_RESPONSE 
+} HW_IO_OAM_LOOPBACK_T;
+
+
+//
+//	HW_IO_SERIAL_DATA_OPEN	
+//	HW_IO_SERIAL_DATA_CLOSE
+//	HW_IO_SERIAL_DATA_READ	
+//	HW_IO_SERIAL_DATA_WRITE
+//
+
+#define HW_IO_SERIAL_BUFFER_SIZE 256
+
+typedef struct HW_IO_SERIAL_DATA_S
+{
+	DWORD	BufferUsed;
+	BYTE 	Data [HW_IO_SERIAL_BUFFER_SIZE];
+} HW_IO_SERIAL_DATA_T;
+	
+	
+
+
+
+
+/**/	//This is a Page Eject character.
+//////////////////////////////////////////////
+//	BackDoor Return Codes Definitions
+//////////////////////////////////////////////
+
+
+#define UNKNOWN_STRING			"Unknown!"
+#define UNKNOWN_4BIT_VALUE		0x0000000F
+#define UNKNOWN_8BIT_VALUE		0x000000FF
+#define UNKNOWN_16BIT_VALUE		0x0000FFFF
+#define UNKNOWN_32BIT_VALUE		0xFFFFFFFF
+
+
+//
+//	The BackDoor Return Code is defined using a 32-bit value.
+//	This 32-bit value is broken/divided into four parts.
+//	The four individual parts are:
+//
+//		Field Name			Bit Positions			# of Bits
+//		===============		===================		=========
+//		Error Code			bits  0 through 11		12 bits
+//		Module Instance		bits 12 through 15		 4 bits
+//		Module				bits 16 through 27		12 bits
+//		Error Level			bits 28 through 31		 4 bits
+//
+//	Each individual part named above has its own enumeration/definition
+//	of possible values defined below.
+//
+
+
+
+typedef enum RESULT_CODES_E
+{
+	RESULT_START						= 0,
+
+	RESULT_SUCCESS						= 0,
+	RESULT_FAILURE,
+
+	RESULT_REQ_NOT_SUPPORTED,
+	RESULT_REQ_BUFF_TOO_SMALL,
+
+	RESULT_HW_IO_INSTANCE_UNAVAIL,			//		0x004
+	RESULT_HW_IO_INSTANCE_EMPTY,			// 5
+
+	RESULT_DATA_UNAVAILABLE,
+	RESULT_DATA_UNINITIALIZED,
+	RESULT_DATA_FAILURE,					//		0x008
+
+	RESULT_DEVICE_BUSY,
+	RESULT_DEVICE_UNAVAILABLE,				// 10
+	RESULT_DEVICE_UNINITIALIZED,
+	RESULT_DEVICE_DOWNLOADING,				//		0x00C
+	RESULT_DEVICE_CMD_IN_PROG,
+	RESULT_DEVICE_FAILURE,
+	RESULT_DEVICE_HW_TIMER_FAIL,			// 15
+
+	RESULT_CALL_UNINITIALIZED,				//		0x010
+
+	RESULT_RESOURCE_ALLOC_FAILURE,
+	RESULT_RESOURCE_CONFLICT,
+
+	RESULT_PARAM_OUT_OF_RANGE,
+	RESULT_PARAM_INVALID,					// 20	0x014
+
+	RESULT_MODULE_UNINITIALIZED,
+
+	RESULT_ADAPTER_NOT_FOUND,
+	RESULT_ADAPTER_UNINITIALIZED,
+
+	RESULT_END								// 24	0x018
+
+} RESULT_CODES_T;
+
+#define	RESULT_MASK			0x00000FFF
+
+
+
+//	NOTE:	For the 'Instance' field, each module has its own set of
+//			values and the starting value is the same for every module!
+//			(i.e., the values are overlayed for each module)
+//	NOTE:	The "INSTANCE_END" value MUST be set to be one greater
+//			than the largest value!
+typedef enum INSTANCE_E
+{
+	INSTANCE_SUCCESS				= 0,
+	INSTANCE_START					= 0x1000,
+
+	INSTANCE_UNKNOWN				= 0x1000,
+	INSTANCE_CARDAL					= 0x2000,		//	CardAL Instances
+	INSTANCE_CARDMGMT				= 0x2000,		//	CardMgmt Instances
+	INSTANCE_BASIC2					= 0x2000,		//	ChipAL Instances
+	INSTANCE_P64					= 0x3000,
+	INSTANCE_UTILITY				= 0x2000,		//	Utility Instances
+	INSTANCE_ATM					= 0x2000,		//	FrameAL Instances
+	INSTANCE_HDLC					= 0x3000,
+	INSTANCE_WAN					= 0x2000,		//	BuffMgmt Instances
+	INSTANCE_LAN					= 0x3000,
+	INSTANCE_CO						= 0x4000,
+	INSTANCE_CELLDATATEST			= 0x5000,
+
+	INSTANCE_END					= 0x6000,		// CAUTION:	MUST BE one greater
+													//			than largest instance!!
+
+} INSTANCE_T;
+
+#define	INSTANCE_MASK		0x0000F000
+
+
+typedef enum MODULE_NAME_E
+{
+	MODULE_SUCCESS					= 0,
+	MODULE_START					= 0x00010000,
+
+	MODULE_UNKNOWN					= 0x00010000,
+	MODULE_BUFFMGMT					= 0x00020000,
+	MODULE_CARDAL					= 0x00030000,
+	MODULE_CARDMGMT					= 0x00040000,
+	MODULE_CHIPAL					= 0x00050000,
+	MODULE_FRAMEAL					= 0x00060000,
+	MODULE_UTILITY					= 0x00070000,
+
+	MODULE_END						= 0x00080000
+
+} MODULE_NAME_T;
+
+#define	MODULE_MASK			0x0FFF0000
+
+
+
+typedef enum ERROR_LEVEL_E
+{
+	LEVEL_SUCCESS					= 0,
+	LEVEL_START						= 0x10000000,
+
+	LEVEL_NORMAL					= 0x10000000,
+	LEVEL_WARNING					= 0x20000000,
+	LEVEL_FATAL						= 0x30000000,
+
+	LEVEL_END						= 0x40000000
+
+} ERROR_LEVEL_T;
+
+#define	LEVEL_MASK			0xF0000000
+
+
+
+typedef struct ERROR_FIELDS_S
+{
+	RESULT_CODES_T			Results	:12;		// Error Code			(Enum)
+	BYTE					Instance:4;			// Instance of Module	(Enum)
+	WORD					Module	:12;		// Module Type			(Enum)
+	BYTE					Level	:4;			// Severity Level		(Enum)
+} ERROR_FIELDS_T,
+  * PERROR_FIELDS_T;
+
+typedef union ERROR_CODE_U
+{
+	DWORD				dwValue;		// Complete Error Code In a DWORD Value
+	ERROR_FIELDS_T		Fields;			// Error Code Broken Into 4 Fields
+} ERROR_CODE_T,
+  * PERROR_CODE_T;
+/*
+**
+**	Notes:
+**
+**	To check the complete value
+**
+**	ERROR_CODE_T	Ec;
+**	...
+**	if (Ec.Value == Success)
+**	..
+**
+**	To check an individual Element:
+**
+**	if (Ec.Error.Results == SpecificResult)
+**
+**	...
+**
+*/
+
+
+
+#endif		//#ifndef _HWIO_H_
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/ide.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/ide.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/ide.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,45 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/ide.h
+ *
+ * Copyright (c) 1998 Hugo Fiennes & Nicolas Pitre
+ *
+ * 18-aug-2000: Cleanup by Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
+ *              Get rid of the special ide_init_hwif_ports() functions
+ *              and make a generalised function that can be used by all
+ *              architectures.
+ */
+
+#include <linux/config.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+
+/*
+ * Set up a hw structure for a specified data port, control port and IRQ.
+ * This should follow whatever the default interface uses.
+ */
+static __inline__ void
+ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int *irq)
+{
+#ifdef CONFIG_REVISIT
+#error Not sure what to do for ide_init_hwif_ports
+#endif
+}
+
+
+
+
+/*
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ */
+static __inline__ void
+ide_init_default_hwifs(void)
+{
+#ifdef CONFIG_REVISIT
+#error Not sure what to do for ide_init_default_hwifs
+#endif
+}
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/io.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ * linux/include/asm-armnommu/arch-dsc21/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ *  02-19-2001  gjm     Leveraged for armnommu/dsc21
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ * --gmcnutt
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * If we define __io then asm/io.h will take care of most of the inb & friends
+ * macros. It still leaves us some 16bit macros to deal with ourselves, though.
+ * We don't have PCI or ISA on the dsc21 so I dropped __mem_pci & __mem_isa.
+ * --gmcnutt
+ */
+#define PCIO_BASE 0
+#define __io(a) (PCIO_BASE + (a))
+#define __arch_getw(a) (*(volatile unsigned short *)(a))
+#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
+
+/*
+ * Defining these two gives us ioremap for free. See asm/io.h.
+ * --gmcnutt
+ */
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,66 @@
+/****************************************************************************
+*
+*	Name:			irq.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:28:32  $
+****************************************************************************/
+
+
+#ifndef __ASM_ARCH_IRQ_H__
+#define __ASM_ARCH_IRQ_H__
+
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irqs.h>
+
+
+#define fixup_irq(x) (x)
+
+__inline__ void cnxt_mask_irq(unsigned int irq);
+__inline__ void cnxt_unmask_irq(unsigned int irq);
+__inline__ void cnxt_mask_ack_irq(unsigned int irq);
+
+extern struct irqdesc irq_desc[];
+
+static __inline__ void irq_init_irq(void)
+{
+	int irq;
+
+	/* disable all int sources */
+	*CNXT_INT_MASK = 0x00000000;
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= cnxt_mask_ack_irq;
+		irq_desc[irq].mask	= cnxt_mask_irq;
+		irq_desc[irq].unmask	= cnxt_unmask_irq;
+	}
+}
+
+#endif /* __ASM_ARCH_IRQ_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/irqs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,112 @@
+/****************************************************************************
+*
+*	Name:			irqs.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:28:32  $
+****************************************************************************/
+
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+
+#define CNXT_INT_LVL_TIMER_1            0       /* Timer 0 interrupt */
+#define CNXT_INT_LVL_TIMER_2            1       /* Timer 1 interrupt */
+#define CNXT_INT_LVL_TIMER_3            2       /* Timer 2 interrupt */
+#define CNXT_INT_LVL_TIMER_4            3       /* Timer 3 interrupt */
+#define CNXT_INT_LVL_USB                4       /* USB interrupt */
+#define CNXT_INT_LVL_RSVD1              5       /* Reserved */
+#define CNXT_INT_LVL_HOST               6       /* External Host interrupt */
+#define CNXT_INT_LVL_HOST_ERR           7       /* Host Bus error detect */
+#define CNXT_INT_LVL_DMA8               8       /* M2M */
+#define CNXT_INT_LVL_RSVD2              9       /* Reserved */
+#define CNXT_INT_LVL_DMA6              10       /* DSL Rx */
+#define CNXT_INT_LVL_DMA5              11       /* DSL Tx */
+#define CNXT_INT_LVL_DMA4              12       /* Ethernet 2 Receive */
+#define CNXT_INT_LVL_DMA3              13       /* Ethernet 2 Transmit */
+#define CNXT_INT_LVL_DMA2              14       /* Ethernet 1 Receive */
+#define CNXT_INT_LVL_DMA1              15       /* Ethernet 1 Transmit */
+#define CNXT_INT_LVL_RSVD3             16       /* Reserved */
+#define CNXT_INT_LVL_RSVD4             17       /* Reserved */
+#define CNXT_INT_LVL_DMA_ERR           18       /* DMA Errort */
+#define CNXT_INT_LVL_E1_ERR            19       /* EMAC 1 error */
+#define CNXT_INT_LVL_E2_ERR            20       /* EMAC 2 error */
+#define CNXT_INT_LVL_DSL               21       /* DSL intr*/
+#define CNXT_INT_LVL_RSVD5             22       /* Reserved */
+#define CNXT_INT_LVL_RSVD6             23       /* Reserved */
+#define CNXT_INT_LVL_GPIO              24       /* GPIO interrupts */
+#define CNXT_INT_LVL_RSVD7             25       /* Reserved */
+#define CNXT_INT_LVL_COMMTX            26       /* ARM9 Comms Xmit */
+#define CNXT_INT_LVL_COMMRX            27       /* ARM9 Comms Rcv */
+#define CNXT_INT_LVL_SW1               28       /* Software interrupt 1 */
+#define CNXT_INT_LVL_SW2               29       /* Software interrupt 2 */
+#define CNXT_INT_LVL_SW3               30       /* Software interrupt 3 */
+#define CNXT_INT_LVL_SW4               31       /* Software interrupt 4 */
+
+#define CNXT_INT_MASK_TIMER_1        1
+#define CNXT_INT_MASK_TIMER_2        (1 << 1)
+#define CNXT_INT_MASK_TIMER_3        (1 << 2)
+#define CNXT_INT_MASK_TIMER_4        (1 << 3)
+#define CNXT_INT_MASK_USB            (1 << 4)
+#define CNXT_INT_MASK_RSVD1          (1 << 5)
+#define CNXT_INT_MASK_HOST           (1 << 6)
+#define CNXT_INT_MASK_HOST_ERR       (1 << 7)
+#define CNXT_INT_MASK_DMA8           (1 << 8)
+#define CNXT_INT_MASK_RSVD2          (1 << 9)
+#define CNXT_INT_MASK_DMA6           (1 << 10)
+#define CNXT_INT_MASK_DMA5           (1 << 11)
+#define CNXT_INT_MASK_DMA4           (1 << 12)
+#define CNXT_INT_MASK_DMA3           (1 << 13)
+#define CNXT_INT_MASK_DMA2           (1 << 14)
+#define CNXT_INT_MASK_DMA1           (1 << 15)
+#define CNXT_INT_MASK_RSVD3          (1 << 16)
+#define CNXT_INT_MASK_RSVD4          (1 << 17)
+#define CNXT_INT_MASK_DMA_ERR        (1 << 18)
+#define CNXT_INT_MASK_E1_ERR         (1 << 19)
+#define CNXT_INT_MASK_E2_ERR         (1 << 20)
+#define CNXT_INT_MASK_DSL            (1 << 21)
+#define CNXT_INT_MASK_RSVD5          (1 << 22)
+#define CNXT_INT_MASK_RSVD6          (1 << 23)
+#define CNXT_INT_MASK_GPIO           (1 << 24)
+#define CNXT_INT_MASK_RSVD7          (1 << 25)
+#define CNXT_INT_MASK_COMMTX         (1 << 26)
+#define CNXT_INT_MASK_COMMRX         (1 << 27)
+#define CNXT_INT_MASK_SW1            (1 << 28)
+#define CNXT_INT_MASK_SW2            (1 << 29)
+#define CNXT_INT_MASK_SW3            (1 << 30)
+#define CNXT_INT_MASK_SW4            (1 << 31)
+
+#define NR_IRQS           32
+
+/* alias */
+#define IRQ_TIMER         CNXT_INT_LVL_TIMER_1
+
+/* flags for request_irq() */
+#define IRQ_FLG_LOCK      (0x0001)  /* handler is not replaceable   */
+#define IRQ_FLG_REPLACE   (0x0002)  /* replace existing handler     */
+#define IRQ_FLG_FAST      (0x0004)
+#define IRQ_FLG_SLOW      (0x0008)
+#define IRQ_FLG_STD       (0x8000)  /* internally used              */
+
+#endif /* __ASM_ARCH_IRQS_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/iterate.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/iterate.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/iterate.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/iterate.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,77 @@
+/****************************************************************************
+*
+*	Name:			iterate.c
+*
+*	Description:	Runs iterations through a timeing loop for CPU utilization
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:28:32  $
+****************************************************************************/
+
+
+/****************************************************************************
+	Function		: Iterate
+	Description		: Performs as many iterations as possible in the given time.
+	Abstract:		: This routine is used to measure how busy the CPU is.
+					: It runs for a fixed period (measured by looking at the
+					: timer register and/or jiffies count) and sees how many
+					: iterrations of looping, incrementing a counter and watching
+					: for clock edges it can get done in the fixed period of time.
+					: Thus the returned count is a function of how much it is
+					: preempted and the number of CPU cycles to perform one
+					: iteration. This latter factor is a constant and basically
+					: arbitrary so only use the returned numbers as ratios since
+					: the number is not a MIP or any other standard measure and
+					: could change in the future.
+					: Use this routine by calling once with DisableInts set to get a
+					: maximum. Then call with with DisableInts cleared to see
+					: how many iterations are possible when preemption occurs.
+					: Then divide the latter number by the former to get a ratio
+					: of CPU loading.
+					: Call both times using the same setting for DisableCache
+					: for the ratio to be meaningful.
+					: The ARM940T has 4KB Data and 4KB Instruction cache. Depending
+					: on the task size and behavior under consideration for 
+					: insertion into the spare cycles, you may wish to take your
+					: two measurements with or without cacheing.
+	Notes:			: The time period should not exceed approximately 2 seconds
+					: or the busyness counter may overflow. This time period can
+					: be extended by artificially extending the cycles consumed
+					: in each iteration.
+					: The time period will be converted to the nearest jiffie.
+	Notes:			: Cache enable/disable is not yet supported
+****************************************************************************/
+unsigned long int Iterate ( unsigned short int MSecs, BOOLEAN DisableInts, BOOLEAN DisableCache ) ;
+
+
+/***************************************************************************
+ $Log:   S:/Embedded/archives/Linux/BSP_CX821xx/uClinux2.4.6/linux/include/asm-armnommu/arch-cx821xx/iterate.h-arc  $
+ * 
+ *    Rev 1.0   Mar 19 2003 13:49:04   davidsdj
+ * Initial revision.
+ * 
+ * 1     6/05/02 3:07p Lewisrc
+ * New file containing routine Iterate to perform as many iterations as
+ * possible in the given time.
+****************************************************************************/
+/***** end of file $Workfile:   iterate.h  $ *****/
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/keyboard.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/keyboard.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/keyboard.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ *  linux/include/asm-arm/arch-ti926/keyboard.h
+ *
+ *  Copyright (C) 2000 RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Keyboard driver definitions for ARM
+ */
+#ifndef __ASM_ARM_ARCH_TI925_KEYBOARD_H
+#define __ASM_ARM_ARCH_TI925_KEYBOARD_H
+
+#if 0
+#define kbd_request_region
+#define kbd_write_command
+#define kbd_write_output
+#define kbd_read_status
+#define kbd_read_input
+#define aux_request_irq
+#define aux_free_irq
+#endif
+
+/*
+ * Required by drivers/char/keyboard.c. I took these from arch-arc.
+ * --gmcnutt
+ */
+#define kbd_setkeycode(sc,kc) (-EINVAL)
+#define kbd_getkeycode(sc) (-EINVAL)
+#define kbd_translate(sc,kcp,rm) ({ *(kcp) = (sc); 1; })
+#define kbd_unexpected_up(kc) (0200)
+#define kbd_leds(leds)
+#define kbd_init_hw()
+#define kbd_enable_irq() /* what irq? ;) --gmcnutt */
+#define kbd_disable_irq()
+
+
+#endif /* __ASM_ARM_ARCH_TI925_KEYBOARD_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/list.c linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/list.c
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/list.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/list.c	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,272 @@
+/*******************************************************************************
+****	Copyright (c) 1998
+****	Rockwell Semiconductor Systems
+****	Personal Computing Division
+****	All Rights Reserved
+****
+*******************************************************************************
+**
+**	MODULE NAME:
+**		List Handling
+**
+**	FILE NAME:
+**		list.c
+**
+**	ABSTRACT:
+**		Queues, stacks, travels linked lists.
+**
+**	DETAILS:
+**		Maintains double linked lists. You must declare an ANCHOR of type LIST_LINK_T
+**		to begin a list. Embed a LIST_LINK_T in each object you wish to link into
+**		the list.
+**		An empty list has an anchor that points to itself. This simplifies dealing
+**		with lists by avoiding any problems with dereferncing 0 as might happen
+**		if NULL pointers are used.
+**		To traverse a list, get the next link after the anchor as a beginning
+**		point. Process each item, getting another item, checking for when the
+**		next function returns a pointer to the anchor to terminate the traversal.
+**
+**		Use MS compiler option /Ob1 to make functions inline
+**
+*******************************************************************************/
+#include "list.h"
+#include <stddef.h>
+
+
+/******************************************************************************
+FUNCTION NAME:
+		ListInit
+
+	ABSTRACT:
+		Initializes the list.
+
+	RETURN:
+		void
+
+	DETAILS:
+  		Must be called before any other function
+
+******************************************************************************/
+GLOBAL __inline void 		 ListInit 		( LIST_LINK_T *Anchor )
+{
+	Anchor->FwdPtr =
+	Anchor->BwdPtr = Anchor ;
+}
+
+
+
+/******************************************************************************
+	FUNCTION NAME:
+		ListNext
+
+	ABSTRACT:
+		returns the successive item on the list.
+
+	RETURN:
+		Next Item
+
+	DETAILS:
+
+******************************************************************************/
+GLOBAL __inline LIST_LINK_T	*ListNext		( LIST_LINK_T *Item )
+{
+	return Item->FwdPtr ;
+}
+
+
+
+/******************************************************************************
+	FUNCTION NAME:
+		ListPrev
+
+	ABSTRACT:
+		returns the previous item on the list.
+
+	RETURN:
+		Next Item
+
+	DETAILS:
+
+******************************************************************************/
+GLOBAL __inline LIST_LINK_T	*ListPrev		( LIST_LINK_T *Item )
+{
+	return Item->BwdPtr ;
+}
+
+
+
+/******************************************************************************
+	FUNCTION NAME:
+		ListInsertNext
+
+	ABSTRACT:
+		Inserts the new item AFTER the current item on the list.
+
+	RETURN:
+		void
+
+	DETAILS:
+
+******************************************************************************/
+GLOBAL __inline void		 ListInsertNext	( LIST_LINK_T *List, LIST_LINK_T *Item )
+{
+	Item->BwdPtr = List ;
+	Item->FwdPtr = List->FwdPtr ;
+	List->FwdPtr->BwdPtr = Item ;
+	List->FwdPtr = Item ;
+}
+
+/******************************************************************************
+	FUNCTION NAME:
+		ListInsertPrev
+
+	ABSTRACT:
+		Inserts the new item BEFORE the current item on the list.
+
+	RETURN:
+		void
+
+	DETAILS:
+
+******************************************************************************/
+GLOBAL __inline void		 ListInsertPrev	( LIST_LINK_T *List, LIST_LINK_T *Item )
+{
+	Item->FwdPtr = List  ;
+	Item->BwdPtr = List->BwdPtr ;
+	List->BwdPtr->FwdPtr = Item ;
+	List->BwdPtr = Item ;
+}
+
+
+
+/******************************************************************************
+	FUNCTION NAME:
+		ListRemoveItem
+
+	ABSTRACT:
+		removes and returns the item from the list.
+
+	RETURN:
+		Item
+
+	DETAILS:
+
+******************************************************************************/
+GLOBAL __inline LIST_LINK_T	*ListRemove		( LIST_LINK_T *Item )
+{
+	Item->BwdPtr->FwdPtr = Item->FwdPtr ;
+	Item->FwdPtr->BwdPtr = Item->BwdPtr ;
+	#if DEBUG
+	Item->FwdPtr = NULL ;
+	Item->BwdPtr = NULL ;
+	#endif
+	return Item ;
+}
+
+
+
+/******************************************************************************
+	FUNCTION NAME:
+		ListPush
+
+	ABSTRACT:
+		Pushes the new item on the list.
+
+	RETURN:
+		void
+
+	DETAILS:
+		When used in conjunction with ListPop, items are removed in LIFO order.
+
+******************************************************************************/
+GLOBAL __inline void 		 ListPush		( LIST_LINK_T *Anchor, LIST_LINK_T *Item )
+{
+	ListInsertNext ( Anchor, Item ) ;
+}
+
+
+
+/******************************************************************************
+	FUNCTION NAME:
+		ListPop
+
+	ABSTRACT:
+		removes and returns the last item pushed on the list.
+
+	RETURN:
+		Item
+
+	DETAILS:
+		When used in conjunction with ListPush, items are removed in LIFO order.
+
+******************************************************************************/
+GLOBAL __inline LIST_LINK_T	*ListPop		( LIST_LINK_T *Anchor )
+{
+	return ListRemove ( Anchor->FwdPtr ) ;
+}
+
+
+
+/******************************************************************************
+	FUNCTION NAME:
+		ListEnqueue
+
+	ABSTRACT:
+		Queues the new item on the list.
+
+	RETURN:
+		void
+
+	DETAILS:
+		When used in conjunction with ListDequeue, items are removed in FIFO order.
+
+******************************************************************************/
+GLOBAL __inline void		 ListEnqueue	( LIST_LINK_T *Anchor, LIST_LINK_T *Item )
+{
+	ListInsertPrev ( Anchor, Item ) ;
+}
+
+
+
+/******************************************************************************
+	FUNCTION NAME:
+		ListDequeue
+
+	ABSTRACT:
+		removes and returns the oldest item queued on the list.
+
+	RETURN:
+		Item
+
+	DETAILS:
+		When used in conjunction with ListQueue, items are removed in FIFO order.
+
+******************************************************************************/
+GLOBAL __inline LIST_LINK_T	*ListDequeue	( LIST_LINK_T *Anchor )
+{
+	return ListRemove ( Anchor->FwdPtr ) ;
+}
+
+
+
+/******************************************************************************
+	FUNCTION NAME:
+		ListIsEmpty
+
+	ABSTRACT:
+		Determines if list is empty.
+
+	RETURN:
+		TRUE if empty
+
+	DETAILS:
+		.
+
+******************************************************************************/
+GLOBAL __inline BOOLEAN	ListIsEmpty	( LIST_LINK_T *Anchor )
+{
+	return Anchor->FwdPtr == Anchor ;
+}
+
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/list.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/list.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/list.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/list.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,61 @@
+/*******************************************************************************
+****	Copyright (c) 1998
+****	Rockwell Semiconductor Systems
+****	Personal Computing Division
+****	All Rights Reserved
+****
+*******************************************************************************
+**
+**	MODULE NAME:
+**		List Handling
+**
+**	FILE NAME:
+**		list.h
+**
+**	ABSTRACT:
+**		Queues, stacks, travels linked lists.
+**
+**	DETAILS:
+**		Maintains double linked lists. You must declare an ANCHOR of type LIST_LINK_T
+**		to begin a list. Embed a LIST_LINK_T in each object you wish to link into
+**		the list.
+**		An empty list has an anchor that points to itself. This simplifies dealing
+**		with lists by avoiding any problems with dereferncing 0 as might happen
+**		if NULL pointers are used.
+**		To traverse a list, get the next link after the anchor as a beginning
+**		point. Process each item, getting another item, checking for when the
+**		next function returns a pointer to the anchor to terminate the traversal.
+**
+*******************************************************************************/
+#ifndef _LIST_H
+#define _LIST_H
+
+#ifdef _MSC_VER
+	#define GLOBAL
+	typedef enum {False, True}				BOOLEAN ;
+#else
+#include "Common.h"
+#endif
+
+typedef struct LIST_LINK_S
+{
+	struct LIST_LINK_S *BwdPtr ;
+	struct LIST_LINK_S *FwdPtr ;
+} LIST_LINK_T ;
+
+GLOBAL __inline void 		 ListInit 		( LIST_LINK_T *Anchor ) ;
+GLOBAL __inline LIST_LINK_T	*ListNext		( LIST_LINK_T *Item ) ;
+GLOBAL __inline LIST_LINK_T	*ListPrev		( LIST_LINK_T *Item ) ;
+GLOBAL __inline void		 ListInsertNext	( LIST_LINK_T *List, LIST_LINK_T *Item ) ;
+GLOBAL __inline void		 ListInsertPrev	( LIST_LINK_T *List, LIST_LINK_T *Item ) ;
+GLOBAL __inline LIST_LINK_T *ListRemove		( LIST_LINK_T *Item ) ;
+GLOBAL __inline void 		 ListPush		( LIST_LINK_T *Anchor, LIST_LINK_T *Item ) ;
+GLOBAL __inline LIST_LINK_T	*ListPop		( LIST_LINK_T *Anchor ) ;
+GLOBAL __inline void		 ListEnqueue	( LIST_LINK_T *Anchor, LIST_LINK_T *Item ) ;
+GLOBAL __inline LIST_LINK_T	*ListDequeue	( LIST_LINK_T *Anchor ) ;
+GLOBAL __inline BOOLEAN		 ListIsEmpty	( LIST_LINK_T *Anchor ) ;
+
+// include the function definitions since they are inline
+#include "list.c"
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,23 @@
+/*
+ * linux/include/asm-armnommu/arch-cx821xx/memory.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * 2001 Mindspeed
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define TASK_SIZE	(0x01a00000UL)
+#define TASK_SIZE_26	TASK_SIZE
+
+#define PHYS_OFFSET	(DRAM_BASE)
+#define PAGE_OFFSET PHYS_OFFSET
+#define END_MEM     (DRAM_BASE + DRAM_SIZE)
+
+#define __virt_to_phys(vpage) ((unsigned long) (vpage))
+#define __phys_to_virt(ppage) ((void *) (ppage))
+#define __virt_to_bus(vpage) ((unsigned long) (vpage))
+#define __bus_to_virt(ppage) ((void *) (ppage))
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/mmu.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/mmu.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/mmu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/mmu.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,23 @@
+/*
+ * linux/include/asm-arm/arch-a5k/mmu.h
+ *
+ * Copyright (c) 1996 Russell King.
+ *
+ * Changelog:
+ *  22-11-1996	RMK	Created
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) vpage
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ppage
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(vpage) vpage
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(ppage) ppage
+
+#define __flush_entry_to_
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/OsDefs.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/OsDefs.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/OsDefs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/OsDefs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,137 @@
+/****************************************************************************
+*
+*	Name:			OsDefs.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.2  $
+*  $Modtime:   Apr 01 2003 09:39:58  $
+****************************************************************************/
+
+#ifndef _OSDEFS_H_
+#define _OSDEFS_H_
+
+extern int		errno;
+typedef long int				STATUS;
+
+#ifdef INT
+#undef INT
+#endif
+
+typedef int						INT;
+typedef unsigned int			UINT;
+typedef unsigned char			UCHAR;
+typedef unsigned short			USHORT;
+typedef unsigned long			ULONG;
+typedef unsigned long *			PULONG;
+typedef void					VOID;
+typedef void *					PVOID;
+
+typedef unsigned short			WORD;
+typedef unsigned long			DWORD;
+typedef unsigned char			BYTE;
+typedef signed char				CHAR;
+typedef signed short int		SHORT;
+typedef signed long int			LONG;
+typedef long long int			LONGLONG;
+typedef unsigned long long int	ULONGLONG;
+typedef long long int			LARGE_INTEGER;
+typedef unsigned char *			PUCHAR;
+
+typedef UINT					BOOL;
+typedef UINT					BOOLEAN;
+typedef BOOLEAN *				PBOOLEAN;
+
+typedef void *					PFILE_OBJECT;
+
+typedef struct					sk_buff SK_BUFF_T;
+typedef struct					sk_buff_head SK_BUFF_QUEUE_T;
+typedef	struct					atm_vcc ATM_VCC_T;
+
+
+#define KdPrint( x )		printk x
+
+#define TRUE				1
+#define FALSE				0
+
+// #define LONG_MIN	(-LONG_MAX - 1L)
+#ifndef INT_MIN
+#define INT_MIN				(-INT_MAX - 1)
+#endif
+
+
+#define IN
+#define OUT
+#define INOUT
+#define I_O
+#define GLOBAL
+
+#define ASSERT( X )
+#define ASSERTMSG( X, Y )
+
+enum ConnectStatus
+{
+    MediaNotConnected,
+    MediaConnected
+};
+
+#define TRAP()					asm("int3")
+
+/////////////////////////////////////////////////////////////////////
+// Error Codes
+/////////////////////////////////////////////////////////////////////
+#define EFAIL				1024
+#define ERR_NOFLOAT			-2048
+#define ERR_FORMAT			-2049
+#define ERR_SHUTDOWN		-2050
+
+#define	EALREADYLOADED		(-STATUS_IMAGE_ALREADY_LOADED)				/* device already loaded */
+#define	EINVALIDTYPE		(-STATUS_BAD_MASTER_BOOT_RECORD)			/* invalid record type */
+#define	ETIMEOUT			(-STATUS_IO_TIMEOUT)						/* command timeout */
+#define	ENOTREADY			(-STATUS_DEVICE_NOT_READY)					/* device not ready */
+#define	EBADLENGTH			(-STATUS_INVALID_BLOCK_LENGTH)				/* invalid length */
+#define EDEVICEFAIL			(-STATUS_IO_DEVICE_ERROR)					/* requested IO failed */
+#define ENOINTERRUPT		(-STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT)	/* requested interrupt unavailable */
+#define ESVCINVAL			(-STATUS_INVALID_DEVICE_REQUEST)			/* invalid service */
+#define COMMAND_PENDING		(-STATUS_PENDING)							/* command is pending */
+#define STATUS_UNSUPPORTED	(-STATUS_NOT_SUPPORTED)						/* command is not supported */
+
+#define STATUS_SUCCESS							((STATUS)0x00000000L)	
+#define STATUS_TIMEOUT							((STATUS)0x00000102L)	
+#define STATUS_PENDING							((STATUS)0x00000103L)	
+#define STATUS_UNSUCCESSFUL						((STATUS)0xC0000001L)
+#define STATUS_FAILURE							((STATUS)0xC0000001L)
+#define STATUS_NOT_IMPLEMENTED						((STATUS)0xC0000002L)
+#define STATUS_INVALID_PARAMETER					((STATUS)0xC000000DL)
+
+#endif //ifndef _OSDEFS_H_
+
+
+
+
+
+
+
+
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/ostimer.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/ostimer.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/ostimer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/ostimer.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,42 @@
+/****************************************************************************
+*
+*	Name:			ostimer.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002, 2004 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   lewisrc  $
+*  $Revision:   1.0  $
+*  $Modtime:   Jul 18 2003 09:08:22  $
+****************************************************************************/
+
+#ifndef OSTIMER_H
+#define OSTIMER_H
+
+int		sysClkRateGet	( void ) ;
+DWORD	CnxtGetTime		( void ) ;
+ULONG	tickGet			( void ) ;
+int		sysTimerDelay	( UINT32 uMicroSec ) ;
+int		TaskDelayConnect( WORD TimerIndex ) ;
+int		TaskDelayMsec	( DWORD TimeDuration ) ;
+
+
+#endif // OSTIMER_H
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/OsTools.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/OsTools.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/OsTools.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/OsTools.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,411 @@
+/****************************************************************************
+*
+*	Name:			OsTools.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.2  $
+*  $Modtime:   Apr 01 2003 09:39:42  $
+****************************************************************************/
+
+#ifndef _OSTOOLS_H_
+#define _OSTOOLS_H_
+
+#include "OsDefs.h"
+
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+
+#include <linux/version.h>
+
+#ifndef KERNEL_VERSION
+#define KERNEL_VERSION(a,b,c) (((a) << 16) | ((b) << 8) | (c))
+#endif
+
+#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) ) && ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) )
+	#include <linux/compatmac.h>
+#endif
+///////////////////////////////////////////////////////
+// networking endian macros
+///////////////////////////////////////////////////////
+#define NTOHL(value) 	ntohl(value)
+#define HTONL(value) 	htonl(value)
+
+///////////////////////////////////////////////////////
+// spin locks
+///////////////////////////////////////////////////////
+typedef struct timer_list LINUX_TIMER;
+
+static __inline void  INIT_TIMER( IN LINUX_TIMER* pTimer,
+                                  IN void (*pTimerFunction)(ULONG),
+                                  IN ULONG pUserData )
+{
+	pTimer->data		= pUserData;
+	pTimer->function	= pTimerFunction;
+
+	init_timer( pTimer );
+}
+
+static __inline void CANCEL_TIMER( LINUX_TIMER* Tmr, BOOLEAN* Stat)
+{
+	int TimerStat;
+
+	TimerStat = del_timer(	Tmr );
+
+	if (TimerStat == 0)
+		*Stat = FALSE;
+	else
+		*Stat = TRUE;
+}
+
+static __inline void START_TIMER( LINUX_TIMER* Tmr, ULONG msTime )
+{
+	Tmr->expires = jiffies + ((msTime*HZ) / 1000);
+	add_timer(	Tmr );
+}
+
+///////////////////////////////////////////////////////
+// spin locks
+///////////////////////////////////////////////////////
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+
+	typedef spinlock_t SPIN_LOCK;
+
+	#define INIT_SPIN_LOCK( pLock ) spin_lock_init( pLock )
+
+	#define ACQUIRE_LOCK( pLock, flag ) spin_lock_irqsave( pLock, flag )
+
+	#define RELEASE_LOCK( pLock, flag ) spin_unlock_irqrestore( pLock, flag )
+
+	#define ACQUIRE_LOCK_AT_ISR( pLock ) spin_lock( pLock )
+
+	#define RELEASE_LOCK_AT_ISR( pLock ) spin_unlock( pLock )
+
+	#define FREE_SPIN_LOCK( pLock )
+
+#else  // #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) #else
+	#ifdef LINUX_EMBEDDED
+	
+		#include "cnxtbsp.h"
+		
+		#define INIT_SPIN_LOCK( pLock ) 
+
+		#define ACQUIRE_LOCK( pLock, flag )		disable_irq(INT_LVL_TIMER_1) 
+
+		#define RELEASE_LOCK( pLock, flag ) 	enable_irq(INT_LVL_TIMER_1)
+
+		#define ACQUIRE_LOCK_AT_ISR( pLock ) 
+
+		#define RELEASE_LOCK_AT_ISR( pLock ) 
+
+		#define FREE_SPIN_LOCK( pLock )
+	#endif // #ifdef LINUX_EMBEDDED
+
+#endif  // #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+
+
+
+////////////////////////////////////////////////////////
+// EVENTS
+////////////////////////////////////////////////////////
+//
+//  This implements the manual set/reset event functions.
+//
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0)
+	typedef struct wait_queue *wait_queue_head_t ;
+#endif
+typedef struct _EVENT_HNDL_
+{
+	volatile int		SetFlag;
+	volatile int		WaitCnt;
+	wait_queue_head_t	WaitQue;
+	#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+		spinlock_t			FlagLock;
+	#endif
+} EVENT_HNDL;
+
+void INIT_EVENT( EVENT_HNDL* pEvent );
+int WAIT_EVENT( EVENT_HNDL* pEvent, ULONG msecDelay );
+void SET_EVENT( EVENT_HNDL* pEvent ) ;
+void SET_EVENT_FROM_ISR( EVENT_HNDL* pEvent ) ;
+void RESET_EVENT( EVENT_HNDL* pEvent );
+
+
+///////////////////////////////////////////////////////////
+// Sleep Function
+///////////////////////////////////////////////////////////
+static __inline void SLEEP( ULONG timems )
+{
+	current->state = TASK_INTERRUPTIBLE;
+	#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+		schedule_timeout(timems*HZ/1000);
+	#else
+		current->timeout = jiffies + timems;
+		schedule();
+		current->timeout = 0;
+	#endif
+}
+
+static __inline void MICRO_DELAY( ULONG MicroSecs )
+{
+	udelay( MicroSecs );
+}
+
+/////////////////////////////////////////////////////////
+// Que handling
+/////////////////////////////////////////////////////////
+typedef struct _LIST_ENTRY_
+{
+	struct _LIST_ENTRY_ *pNext;
+	struct _LIST_ENTRY_ *pPrev;
+} LIST_ENTRY, *PLIST_ENTRY;
+
+//
+//  VOID
+//  InitializeListHead(
+//      PLIST_ENTRY ListHead
+//      );
+//
+
+#define InitializeListHead(ListHead) (\
+    (ListHead)->pNext = (ListHead)->pPrev = (ListHead))
+
+//
+//  BOOLEAN
+//  IsListEmpty(
+//      PLIST_ENTRY ListHead
+//      );
+//
+
+#define IsListEmpty(ListHead) \
+    ((ListHead)->pNext == (ListHead))
+
+//
+//  PLIST_ENTRY
+//  RemoveHeadList(
+//      PLIST_ENTRY ListHead
+//      );
+//
+
+#define RemoveHeadList(ListHead) \
+    (ListHead)->pNext;\
+    {RemoveEntryList((ListHead)->pNext)}
+
+//
+//  PLIST_ENTRY
+//  RemoveTailList(
+//      PLIST_ENTRY ListHead
+//      );
+//
+
+#define RemoveTailList(ListHead) \
+    (ListHead)->pPrev;\
+    {RemoveEntryList((ListHead)->pPrev)}
+
+//
+//  VOID
+//  RemoveEntryList(
+//      PLIST_ENTRY Entry
+//      );
+//
+
+#define RemoveEntryList(Entry) {\
+    PLIST_ENTRY _EX_pPrev;\
+    PLIST_ENTRY _EX_pNext;\
+    _EX_pNext = (Entry)->pNext;\
+    _EX_pPrev = (Entry)->pPrev;\
+    _EX_pPrev->pNext = _EX_pNext;\
+    _EX_pNext->pPrev = _EX_pPrev;\
+    }
+
+//
+//  VOID
+//  InsertTailList(
+//      PLIST_ENTRY ListHead,
+//      PLIST_ENTRY Entry
+//      );
+//
+
+#define InsertTailList(ListHead,Entry) {\
+    PLIST_ENTRY _EX_pPrev;\
+    PLIST_ENTRY _EX_ListHead;\
+    _EX_ListHead = (ListHead);\
+    _EX_pPrev = _EX_ListHead->pPrev;\
+    (Entry)->pNext = _EX_ListHead;\
+    (Entry)->pPrev = _EX_pPrev;\
+    _EX_pPrev->pNext = (Entry);\
+    _EX_ListHead->pPrev = (Entry);\
+    }
+
+//
+//  VOID
+//  InsertHeadList(
+//      PLIST_ENTRY ListHead,
+//      PLIST_ENTRY Entry
+//      );
+//
+
+#define InsertHeadList(ListHead,Entry) {\
+    PLIST_ENTRY _EX_pNext;\
+    PLIST_ENTRY _EX_ListHead;\
+    _EX_ListHead = (ListHead);\
+    _EX_pNext = _EX_ListHead->pNext;\
+    (Entry)->pNext = _EX_pNext;\
+    (Entry)->pPrev = _EX_ListHead;\
+    _EX_pNext->pPrev = (Entry);\
+    _EX_ListHead->pNext = (Entry);\
+    }
+
+
+#ifdef SOFTSAR_DRIVER
+////////////////////////////////////////////////////////
+// Kernel memory operations
+////////////////////////////////////////////////////////
+// This flag enables the memory allocation debugger - set it to
+// nonzero to enable it
+#define MEM_ALLOC_DBG 0
+
+extern ULONG gAllocCnt;
+
+#if MEM_ALLOC_DBG
+typedef struct ALLOC_HEAD
+{
+	LIST_ENTRY	List;
+	ULONG	    Magic; // number used to indicate allocated memory
+	ULONG		Tag;
+} ALLOC_HEAD_T, *PALLOC_HEAD_T;
+
+#define ALLOC_MAGIC 0x01216560
+
+extern ALLOC_HEAD_T gAllocList;
+#endif 
+
+static __inline 	STATUS ALLOCATE_MEMORY(	OUT PVOID* pMem,
+        IN  ULONG size,
+        IN  ULONG tag )
+{
+	STATUS Status = STATUS_SUCCESS;
+
+	// if in memory debug keep a list of all allocated memory
+	// blocks to help chase down leaks
+#if MEM_ALLOC_DBG
+	UCHAR 		 *pAll;
+	PALLOC_HEAD_T pAllocEntry;
+
+	pAll= kmalloc (size+sizeof(ALLOC_HEAD_T), GFP_KERNEL);
+
+	if (!pAll)
+	{
+		*pMem = NULL;
+		printk("<1> memory allocation failure\n");
+		Status = -ENOMEM;
+	}
+
+	else
+	{
+		pAllocEntry = (PALLOC_HEAD_T)pAll;
+		pAllocEntry->Magic = ALLOC_MAGIC;
+		InsertTailList(&gAllocList.List, (PLIST_ENTRY)&pAllocEntry->List);
+		pAllocEntry->Tag = tag;
+
+		*pMem = pAll+sizeof(ALLOC_HEAD_T);
+		gAllocCnt++;
+	}
+
+#else
+
+// if not in memory debug then just allocate
+	*pMem = kmalloc (size, GFP_ATOMIC);
+
+	if (!*pMem)
+	{
+		printk("<1> memory allocation failure\n");
+		Status = -ENOMEM;
+	}
+	else
+		gAllocCnt++;
+
+#endif
+
+	return Status;
+}
+
+static __inline VOID FREE_MEMORY( IN PVOID pMem,
+                                  IN ULONG Length,
+                                  IN ULONG Flags )
+{
+	// if in memory debug then validate the block before freeing it
+#if MEM_ALLOC_DBG
+	PALLOC_HEAD_T pAllocEntry=(PALLOC_HEAD_T)((ULONG)pMem-sizeof(ALLOC_HEAD_T));
+
+	// validate that it was allocated memory
+	if ( pAllocEntry->Magic != ALLOC_MAGIC )
+	{
+		printk("<1>CnxADSL attempting to free invalid memory block %lx\n",(DWORD)pMem);
+		return;
+	}
+
+	// clear the magic number to catch extra frees on the same block
+	pAllocEntry->Magic = 0;
+
+	// now take it out of the alloc list
+	RemoveListEntry( &pAllocEntry->List );
+
+	// and free it
+	kfree( pAllocEntry );
+
+#else
+kfree( pMem );
+#endif
+
+	gAllocCnt--;
+}
+
+#define CLEAR_MEMORY( pMem, size ) memset( pMem, 0, size )
+#define MEMORY_SET( pMem, value, size ) memset( pMem, value, size )
+#define COPY_MEMORY( pDest, pSrc, size ) memcpy( pDest, pSrc, size )
+#define COMPARE_MEMORY( pDest, pSrc, size ) memcmp( pDest, pSrc, size )
+
+
+#endif	//#ifdef SOFTSAR_DRIVER
+
+////////////////////////////////////////////////////////
+// ATM support functions
+////////////////////////////////////////////////////////
+#define RELEASE_SKB( pVcc, skb )	\
+{									\
+	if (pVcc->pop)					\
+		pVcc->pop(pVcc,skb);		\
+	else							\
+		dev_kfree_skb(skb);			\
+}
+
+#define CNX_VCC( pVcc ) ((CDSL_VC_T *)(pVcc)->dev_data)
+
+#endif //_OSTOOLS_H_
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/param.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/pcmcia.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/pcmcia.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/pcmcia.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/pcmcia.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,3 @@
+#ifdef CONFIG_REVISIT
+#error Do we need PCMCIA support?
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/processor.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/processor.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/processor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,19 @@
+/*
+ * uclinux/include/asm-armnommu/arch-atmel/mmu.h
+ *
+ */
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+#define EISA_bus 0
+#define EISA_bus__is_a_macro
+#define MCA_bus 0
+#define MCA_bus__is_a_macro
+
+#define TASK_SIZE (0x01a00000UL)
+
+#define INIT_MMAP { \
+  &init_mm, 0, 0x02000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC \
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/pwrmanag.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/pwrmanag.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/pwrmanag.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/pwrmanag.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,68 @@
+/****************************************************************************
+*
+*	Name:			pwrmanag.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 - 2003  Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   belljl  $
+*  $Revision:   1.1  $
+*  $Modtime:   Jun 30 2003 16:16:34  $
+****************************************************************************/
+
+#ifndef PWRMANAG_H
+#define PWRMANAG_H
+
+typedef enum
+{
+   DEVICE_ARMCORE,
+   DEVICE_FLASH,
+   DEVICE_SDRAM,
+   #if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+      DEVICE_FALCON,
+      DEVICE_AFE,
+   #endif
+   DEVICE_EPHY
+} eHWDevice;
+
+
+typedef enum
+{
+   DEVICE_ON,
+   DEVICE_OFF,
+   DEVICE_SLEEP,
+   DEVICE_RESET,
+   DEVICE_SLOW_SPEED,
+   DEVICE_NORMAL_SPEED
+} eHWPowerState;
+
+
+void sysDevicePowerCtl(eHWDevice eDeviceType, eHWPowerState ePowerState);
+void sysARMCOREPwrCtl(eHWPowerState ePowerState);
+void sysSDRAMPwrCtl(eHWPowerState ePowerState);
+#if CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+   void sysFALCONPwrCtl(eHWPowerState ePowerState);
+   void sysAFEPwrCtl(eHWPowerState ePowerState);
+#endif //CONFIG_CNXT_ADSL || CONFIG_CNXT_ADSL_MODULE
+
+void sysEPHYPwrCtl(eHWPowerState ePowerState);
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/serial.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/serial.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/serial.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,9 @@
+/*
+ *  linux/include/asm-arm/arch-cx821XX/serial.h
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+/* need to move p52serial.h here */
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/shmparam.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/shmparam.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/shmparam.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-a5k/shmparam.h
+ *
+ * Copyright (c) 1996 Russell King.
+ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/syslib.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/syslib.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/syslib.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/syslib.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,38 @@
+/****************************************************************************
+*
+*	Name:			syslib.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:28:32  $
+****************************************************************************/
+
+#ifndef SYSLIB_H
+#define SYSLIB_H
+
+void syshwinit (void);
+void sysHwInit2(void);
+BOOL SYS_bDUALEMAC_Support( void );
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/sysmem.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/sysmem.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/sysmem.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/sysmem.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,35 @@
+/****************************************************************************
+* $Header: /cvs/sw/linux-2.4.x/include/asm-armnommu/arch-cx821xx/sysmem.h,v 1.1 2005/02/18 04:21:50 gerg Exp $
+*
+*  Copyright(c)2002  Conexant Systems
+*
+*****************************************************************************/
+#ifndef SYSMEM_H_
+#define SYSMEM_H_
+
+// SYSMEM: Unformatted system (nonCache) memory (SRAM or SDRAM) manager
+// This module provide the services to allocate and free a block of system memory.
+//  The services are slow, the idea is client allocate a block of memory and 
+// manage it by itself.
+// Depend on the implementation it can be OS_DEPENDENT or OS_INDEPENDENT
+// 
+
+
+// Set up memory pool
+void SYSMEM_GeneralInit(void) ;
+
+// Free all allocated memory back to system 
+void SYSMEM_GeneralClose(void) ;
+
+// the allocate memory will be at Hardware required alignment
+// If the memory is in SRAM, set ifSram = 1.
+// Otherwise set ifSram = 0.
+// if alignment =0, set alignment = 16
+unsigned char * SYSMEM_Allocate_BlockMemory( int ifSram, int sysMemSize, int alignment ) ;
+
+int SYSMEM_Release_BlockMemory( int ifSram, unsigned char *sysMemPtr ) ;
+
+// report the biggest continuous memory ( in SRAM or SDRAM)
+unsigned long SYSMEM_QueryMemory( int ifSRAM ) ;
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/system.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/system.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,42 @@
+/****************************************************************************
+*
+*	Name:			system.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:28:32  $
+****************************************************************************/
+
+static inline void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter)
+	  cpu_do_idle(IDLE_WAIT_SLOW);
+}
+
+extern inline void arch_reset(char mode)
+{
+  /* tbd */
+}
+
+ 
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/time.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/time.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,60 @@
+/****************************************************************************
+*
+*	Name:			time.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:28:32  $
+****************************************************************************/
+
+#ifndef __ASM_ARCH_TIME_H__
+#define __ASM_ARCH_TIME_H__
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/timex.h>
+
+extern struct irqaction timer_irq;
+
+extern unsigned long cnxt_gettimeoffset(void);
+extern void cnxt_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+
+void __inline__ setup_timer (void)
+{
+
+	/* disable timer interrupt (should already been disabled) */
+	*CNXT_INT_MASK &= ~(1 << CNXT_INT_LVL_TIMER_1);
+
+	/* Timeout 10ms */
+	TIM_SET_RATE(TM_Lmt1,CLOCK_TICK_RATE);	
+
+	//gettimeoffset = cnxt_gettimeoffset;	
+	timer_irq.handler = cnxt_timer_interrupt;
+	setup_arm_irq(IRQ_TIMER, &timer_irq);
+
+}
+
+#endif /* __ASM_ARCH_TIME_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,50 @@
+/****************************************************************************
+*
+*	Name:			timex.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:28:32  $
+****************************************************************************/
+
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+#define CLOCK_TICK_RATE	   0x270f
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/uncompress.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/uncompress.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/uncompress.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ * asm/arch/uncompress.c:
+ *         Optional routines to aid in debugging the decompression phase
+ *         of kernel boot.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * This is used by arch/armnommu/boot/compressed/misc.c to write progress info
+ * out the serial port so that the user can see debug messages up to the point
+ * where the kernel is decompressed. The STANDALONE_DEBUG macro chooses between
+ * this and the standard printf. Punt.
+ * --gmcnutt
+ */
+#define puts(s)
+
+/*
+ * Not sure what this is for. Probably an optional watchdog to check if the
+ * decompress got hung so we can warn the user. Punt.
+ */
+#define arch_decomp_wdog()
+
+/*
+ * If we need to do some setup prior to decompression (like initializing the
+ * UART if we want to use puts() above) then we define it here. Punt.
+ */
+#define arch_decomp_setup()
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/usbdef.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/usbdef.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/usbdef.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/usbdef.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,681 @@
+/****************************************************************************
+*
+*	Name:			usbdef.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  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
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.1  $
+*  $Modtime:   Jan 07 2003 09:53:48  $
+****************************************************************************/
+
+#ifndef USBDEF_H
+#define USBDEF_H
+
+typedef enum
+{
+   USB_DISABLE,            /* 0: UDC Core not configured */
+   USB_ENABLE,             /* 1: UDC Core configured */
+   USB_ATTACHED,           /* 2: USB cable attached */
+   USB_POWERED,            /* 3: USB powered */
+   USB_DEFAULT,            /* 4: USB has been reset */
+   USB_ADDRESSED,          /* 5: USB assigned unique device address */
+   USB_CONFIGURED,         /* 6: USB assigned valid configuration */
+   USB_SUSPENDED,          /* 7: USB attached, powered but bus idle */
+   USB_RESUME_INITIATE,    /* 8: USB device initiated resume */
+   USB_DETACHED            /* 9: USB cable detached */
+} eUSBState;
+
+
+typedef enum
+{
+   EP_CONTROL,
+   EP_ISO,
+   EP_BULK,
+   EP_INTERRUPT
+} eEPType;
+
+
+typedef enum
+{
+   EP_SETTING0,
+   EP_SETTING1,
+   EP_SETTING2,
+   EP_SETTING3,
+   EP_SETTING4,
+   EP_SETTING5,
+   EP_SETTING6,
+   EP_SETTING7
+} eEPSetting;
+
+
+typedef enum
+{
+   EP_INTERFACE0,
+   EP_INTERFACE1,
+   EP_INTERFACE2,
+   EP_INTERFACE3
+} eEPInterface;
+
+
+typedef enum
+{
+   EP_CONF0,
+   EP_CONF1,
+   EP_CONF2,
+   EP_CONF3
+} eEPConfigure;
+
+
+typedef enum
+{
+   ENDPOINT0,
+   ENDPOINT1,
+   ENDPOINT2,
+   ENDPOINT3,
+   ENDPOINT4,
+	NOT_AVAILABLE
+} eEPNumber;
+
+
+typedef enum
+{
+   ENDPOINT0_IN,
+   ENDPOINT0_OUT,
+   ENDPOINT1_IN,
+   ENDPOINT1_OUT,
+   ENDPOINT2_IN,
+   ENDPOINT2_OUT,
+   ENDPOINT3_IN,
+   ENDPOINT3_OUT,
+   ENDPOINT4_IN,
+   ENDPOINTALL_IN,
+   ENDPOINTALL_OUT,
+   ENDPOINTALL,
+	ENDPOINT_UNKNOWN
+} eEPDirection;
+
+
+typedef enum
+{
+   EP_DISABLE,
+   EP_ENABLE,
+   EP_RESET,
+   EP_CONFIGURE,
+   EP_FLUSH
+} eEPCtl;
+
+
+typedef enum
+{
+   DESC_TYPE_NONE,
+   DESC_TYPE_DEV,
+   DESC_TYPE_CONFIG,
+   DESC_TYPE_STRING,
+   DESC_TYPE_INTER,
+   DESC_TYPE_EP
+} eDESCType;
+
+
+/*	String Descriptor Index Enumeration */
+typedef enum
+{
+   DESC_STRING_LANGUAGEID,												
+   DESC_STRING_MANUFACTURER,
+   DESC_STRING_PRODUCT,
+   DESC_STRING_SERIAL 
+} eDESCSTRINGType;
+
+
+
+#define BUS_POWERED_ATTRIB    0x80
+#define SELF_POWERED_ATTRIB   0x40
+#define REMOTE_WAKEUP_ATTRIB  0x20
+
+/* Defines for Device Descriptor */
+#define NUM_DEV_DESC_FLD   14
+#define DEV_DESC_LENGTH	   18
+#define USB_SPEC_100       0x0100
+#define USB_SPEC_110       0x0110
+#define P50_DEV_CLASS	   0x00
+#define P50_DEV_SUBCLASS   0x00
+#define P50_DEV_PROTOCOL   0x00
+#define CONEXANT_VENDOR_ID	0x0572
+#define P50_PRODUCT_ID	   0xcafe
+#define P50_DEV_ID	     	0001
+
+/* Defines for Configuration Descriptor */
+#define CONFIG_DESC_LENGTH 9
+#define NUM_OF_INTERFACE   1
+#define CONFIG_VALUE       1
+#define CONFIG_STR         0
+/* Self-powered, support Remote Wakeup */
+/*#define CONFIG_ATTRIBUTES  (SELF_POWERED_ATTRIB | REMOTE_WAKEUP_ATTRIB)*/
+/* Bus-powered, support Remote Wakeup */
+#ifdef USB_REMOTE_WAKEUP
+#define CONFIG_ATTRIBUTES  (BUS_POWERED_ATTRIB | REMOTE_WAKEUP_ATTRIB)
+#else
+#define CONFIG_ATTRIBUTES  BUS_POWERED_ATTRIB
+#endif
+#define MAX_POWER_CONSUME  250   /* 2 * 250 = 500mA */
+
+/* Defines for Interface descriptor */
+#define INTER_DESC_LENGTH        9
+#define INTER_NUM                0
+#define ALT_SETTING              0
+#define INTER_CLASS              0
+#define INTER_SUBCLASS           0
+#define INTER_PROTOCOL           0
+#define INTER_STR                0
+
+/* Defines for Language ID */
+#define USB_MS_ENGLISH_ID        0x0409
+
+/* Defines for Endpoint descriptor */
+#define MAX_NUM_ENDPOINT         9
+#define MAX_EP_CFG_LENGTH        (MAX_NUM_ENDPOINT * 5)
+#define MAX_EP_CFG_DWORD         ((MAX_EP_CFG_LENGTH / 4) + 1)
+#define MAX_NUM_CONFIG           1
+
+#define EP_OUT                   0
+#define EP_IN                    1
+
+#define EP_DESC_LENGTH           7
+#define MAX_EP_DESC_LENGTH       (EP_DESC_LENGTH * (MAX_NUM_ENDPOINT - 2))
+#define MAX_CONFIG_DESC_LENGTH   (CONFIG_DESC_LENGTH + INTER_DESC_LENGTH + MAX_EP_DESC_LENGTH)
+#define MAX_CONFIG_DESC_DWORD    ((MAX_CONFIG_DESC_LENGTH/4) + 1)
+
+#define BULK_POLL_INTERVAL       1	/* ms */
+#define INT_POLL_INTERVAL        4	/* ms */
+
+
+/*************************************************************
+* Defines for USB DMA buffers map.
+*************************************************************/
+
+#define USB_MAX_PACKET_SIZE      64
+#define BULK_MAX_PACKET_SIZE     64
+#define INT_MAX_PACKET_SIZE      8
+
+/* If it is not USB ADSL product we just allocate enough buffers to */
+/* support Enumeration and Configuration over USB.  Assume no data  */
+/* transfer. */
+/*#ifdef CONFIG_DATA_OVER_USB*/
+#define USB_EP0_NUM_TX_BUFF      4
+#define USB_EP1_NUM_TX_BUFF      4
+#define USB_EP2_NUM_TX_BUFF      160
+#define USB_EP3_NUM_TX_BUFF      4
+/*#else
+#define USB_EP0_NUM_TX_BUFF      4
+#define USB_EP1_NUM_TX_BUFF      4
+#define USB_EP2_NUM_TX_BUFF      4
+#define USB_EP3_NUM_TX_BUFF      4
+#endif*/
+
+#define USB_TX_DESC_SIZE         8		/* 8 bytes = 1 Qword */
+#define USB_TX_LINK_SIZE         8
+#define USB_TX_FRAME_SIZE        (USB_TX_DESC_SIZE + USB_MAX_PACKET_SIZE + USB_TX_LINK_SIZE)
+#define USB_EP0_TX_BUFF_SIZE    	(USB_TX_FRAME_SIZE * USB_EP0_NUM_TX_BUFF)
+#define USB_EP1_TX_BUFF_SIZE    	(USB_TX_FRAME_SIZE * USB_EP1_NUM_TX_BUFF)
+#define USB_EP2_TX_BUFF_SIZE    	(USB_TX_FRAME_SIZE * USB_EP2_NUM_TX_BUFF)
+#define USB_EP3_TX_BUFF_SIZE    	(USB_TX_FRAME_SIZE * USB_EP3_NUM_TX_BUFF)
+#define USB_TXBUFF_SIZE          (USB_EP0_TX_BUFF_SIZE + USB_EP1_TX_BUFF_SIZE + USB_EP2_TX_BUFF_SIZE + USB_EP3_TX_BUFF_SIZE)
+
+#define USB_RX_DESC_SIZE         8		/* 8 bytes = 1 Qword */
+#define USB_RX_FRAME_SIZE        (USB_RX_DESC_SIZE + USB_MAX_PACKET_SIZE)
+#define USB_MAX_RXBUFF_SIZE      (USB_RX_FRAME_SIZE * 230)
+
+#ifdef USB_DMA_IN_SRAM
+   #define USB_DMA_RAM_START     SRAMSTART
+   #ifndef DSL_DMA_IN_SRAM
+   #define USB_DMA_RAM_END       SRAMEND
+   #endif
+#else
+   #ifdef DSL_DMA_IN_SRAM
+   #define USB_DMA_RAM_START     ( SDRAMEND - (USB_MAX_RXBUFF_SIZE + USB_TXBUFF_SIZE) )
+   #define USB_DMA_RAM_END       SDRAMEND
+   #else
+   #define USB_DMA_RAM_START     ( SDRAMEND - (USB_MAX_RXBUFF_SIZE*4) )
+   #define USB_DMA_RAM_END       ( USB_DMA_RAM_START + (USB_MAX_RXBUFF_SIZE + USB_TXBUFF_SIZE) )
+   #endif
+#endif
+
+#define pEP0TXBUFFER (volatile UINT32 *) USB_DMA_RAM_START
+#define pEP1TXBUFFER (volatile UINT32 *) ((UINT8 *) pEP0TXBUFFER + USB_EP0_TX_BUFF_SIZE)
+#define pEP2TXBUFFER (volatile UINT32 *) ((UINT8 *) pEP1TXBUFFER + USB_EP1_TX_BUFF_SIZE)
+#define pEP3TXBUFFER (volatile UINT32 *) ((UINT8 *) pEP2TXBUFFER + USB_EP2_TX_BUFF_SIZE)
+
+#define pUSB_RXBUFF 	(volatile UINT32 *) ((UINT8 *) pEP3TXBUFFER + USB_EP3_TX_BUFF_SIZE)
+
+
+/* If it is not USB ADSL product we just allocate enough buffers to */
+/* support Enumeration and Configuration over USB.  Assume no data  */
+/* transfer. */
+/*#ifdef CONFIG_DATA_OVER_USB*/
+   #ifdef USB_DMA_IN_SRAM
+      #ifdef DSL_DMA_IN_SRAM
+      #define USB_MAX_RX_BUFF          56
+      #else
+      #define USB_MAX_RX_BUFF          ( ( ((UINT32)USB_DMA_RAM_END - (UINT32)pUSB_RXBUFF) / USB_RX_FRAME_SIZE) - 2 )
+      #endif
+   #else
+      #define USB_MAX_RX_BUFF          ( ( ((UINT32)USB_DMA_RAM_END - (UINT32)pUSB_RXBUFF) / USB_RX_FRAME_SIZE) - 2 )
+   #endif
+/*#else
+   #define USB_MAX_RX_BUFF       16
+#endif*/
+
+#define USB_RXBUFF_SIZE          (USB_RX_FRAME_SIZE * USB_MAX_RX_BUFF)
+
+
+#define USB_RECIPIENT            0x1F
+#define USB_RECIPIENT_DEVICE     0x00
+#define USB_RECIPIENT_INTERFACE  0x01
+#define USB_RECIPIENT_ENDPOINT   0x02
+
+#define USB_MAX_REQ_NUM          13
+#define USB_REQUEST_TYPE_MASK    0x60
+#define USB_STANDARD_REQUEST     0x00
+#define USB_CLASS_REQUEST        0x20
+#define USB_VENDOR_REQUEST       0x40
+#define USB_REQUEST_MASK         0x0F
+
+/* Rx Time Out Range in ms.  We do not use 1 since it could be */
+/* 1ms in between USB packet. */
+#define USB_RX_MIN_TIMEOUT       2000     /* 2ms */
+#define USB_RX_MAX_TIMEOUT       10000    /* 10ms */
+
+#define USB_MONITOR_PERIOD 10  /* 10ms */
+#define USB_CABLE_DEBOUNCE 100 /* 100ms */
+
+
+/*********************************************************/
+/* Define the Base addresses of USB registers            */
+/*********************************************************/
+#define USB_HW_BASE  0x00330000
+
+#define USB_EP0_TX_DMA ((volatile UINT32 *) (USB_HW_BASE + 0x0))
+#define USB_EP1_TX_DMA ((volatile UINT32 *) (USB_HW_BASE + 0x8))
+#define USB_EP2_TX_DMA ((volatile UINT32 *) (USB_HW_BASE + 0x10))
+#define USB_EP3_TX_DMA ((volatile UINT32 *) (USB_HW_BASE + 0x18))
+#define USB_EP0_RX_DMA ((volatile UINT32 *) (USB_HW_BASE + 0x20))
+
+#define USB_CFG	     ((volatile UINT32 *) (USB_HW_BASE + 0x24))
+#define USB_IDAT       ((volatile UINT32 *) (USB_HW_BASE + 0x28))
+#define USB_CTR1       ((volatile UINT32 *) (USB_HW_BASE + 0x2C))
+#define USB_CTR2       ((volatile UINT32 *) (USB_HW_BASE + 0x30))
+#define USB_CTR3       ((volatile UINT32 *) (USB_HW_BASE + 0x34))
+#define USB_STAT       ((volatile UINT32 *) (USB_HW_BASE + 0x38))
+#define USB_IER        ((volatile UINT32 *) (USB_HW_BASE + 0x3C))
+#define USB_STAT2      ((volatile UINT32 *) (USB_HW_BASE + 0x40))
+#define USB_IER2       ((volatile UINT32 *) (USB_HW_BASE + 0x44))
+
+#define USB_EP0_TX_INC     ((volatile UINT32 *) (USB_HW_BASE + 0x48))
+#define USB_EP0_TX_PEND    ((volatile UINT32 *) (USB_HW_BASE + 0x4C))
+#define USB_EP0_TX_QWCNT   ((volatile UINT32 *) (USB_HW_BASE + 0x50))
+#define USB_EP1_TX_INC     ((volatile UINT32 *) (USB_HW_BASE + 0x54))
+#define USB_EP1_TX_PEND    ((volatile UINT32 *) (USB_HW_BASE + 0x58))
+#define USB_EP1_TX_QWCNT   ((volatile UINT32 *) (USB_HW_BASE + 0x5C))
+#define USB_EP2_TX_INC     ((volatile UINT32 *) (USB_HW_BASE + 0x60))
+#define USB_EP2_TX_PEND    ((volatile UINT32 *) (USB_HW_BASE + 0x64))
+#define USB_EP2_TX_QWCNT   ((volatile UINT32 *) (USB_HW_BASE + 0x68))
+#define USB_EP3_TX_INC     ((volatile UINT32 *) (USB_HW_BASE + 0x6C))
+#define USB_EP3_TX_PEND    ((volatile UINT32 *) (USB_HW_BASE + 0x70))
+#define USB_EP3_TX_QWCNT   ((volatile UINT32 *) (USB_HW_BASE + 0x74))
+
+#define USB_RX_DEC         ((volatile UINT32 *) (USB_HW_BASE + 0x78))
+#define USB_RX_PEND        ((volatile UINT32 *) (USB_HW_BASE + 0x7C))
+#define USB_RX_QWCNT       ((volatile UINT32 *) (USB_HW_BASE + 0x80))
+#define USB_RX_BUFFSIZE    ((volatile UINT32 *) (USB_HW_BASE + 0x84))
+
+#define USB_CSR       ((volatile UINT32 *) (USB_HW_BASE + 0x88))
+#define UDC_TSR       ((volatile UINT32 *) (USB_HW_BASE + 0x8C))
+#define UDC_STAT      ((volatile UINT32 *) (USB_HW_BASE + 0x90))
+
+#define USB_RX_TIMER  ((volatile UINT32 *) (USB_HW_BASE + 0x94))
+#define USB_RX_TMRCNT ((volatile UINT32 *) (USB_HW_BASE + 0x98))
+#define USB_RX_THRESH ((volatile UINT32 *) (USB_HW_BASE + 0x9C))
+
+/*********************************************************/
+/* Define USB registers bit definitions                  */
+/*********************************************************/
+
+/* Funny game here.  We use the MSB of the EP_NUM */
+/* field to indicate the direction.  So we will   */
+/* mask it out when we look for physical endpoint */
+
+/*#define RX_EP_NUM_MASK		     	0x0700*/
+#define RX_EP_NUM_MASK		     	0x0F00
+#define RX_EP_NUM_SHIFT		      8
+
+#define RX_GOOD_PACKET_MASK   	0x8000
+#define RX_SETUP_PACKET_MASK	   0x0080
+#define RX_NUM_BYTES_MASK	      0x007F
+
+/* USB_CTR1 bit definitions */
+#define USBCTR1_ENA              BIT0
+#define USBCTR1_CONFIG_ENA       BIT1
+#define USBCTR1_EP0O_ENA         BIT2
+#define USBCTR1_EP1O_ENA         BIT3
+#define USBCTR1_EP2O_ENA         BIT4
+#define USBCTR1_EP3O_ENA         BIT5
+#define USBCTR1_EP0I_ENA         BIT6
+#define USBCTR1_EP1I_ENA         BIT7
+#define USBCTR1_EP2I_ENA         BIT8
+#define USBCTR1_EP3I_ENA         BIT9
+#define USBCTR1_EPINT_ENA        BIT10
+#define USBCTR1_XVER_SLEEP       BIT11
+
+#define USBCTR1_EP0I_DMA_RESET   BIT12
+#define USBCTR1_EP1I_DMA_RESET   BIT13
+#define USBCTR1_EP2I_DMA_RESET   BIT14
+#define USBCTR1_EP3I_DMA_RESET   BIT15
+
+#define USBCTR1_EPIALL_DMA_RESET (USBCTR1_EP0I_DMA_RESET | USBCTR1_EP1I_DMA_RESET | USBCTR1_EP2I_DMA_RESET | USBCTR1_EP3I_DMA_RESET)
+
+#define USBCTR1_RVINIT_ENA       BIT28
+#define USBCTR1_RESUME_INIT      BIT29
+#define USBCTR1_RESET            BIT30
+#define USBCTR1_GBL_IRQ_ENA      BIT31
+
+#define USB_ALL_EPOUT_ENA        (USBCTR1_EP0O_ENA | USBCTR1_EP1O_ENA | USBCTR1_EP2O_ENA | USBCTR1_EP3O_ENA)
+#define USB_ALL_EPIN_ENA         (USBCTR1_EP0I_ENA | USBCTR1_EP1I_ENA | USBCTR1_EP2I_ENA | USBCTR1_EP3I_ENA)
+
+#define USB_TX_BUFF_RDY	         BIT15
+
+#define USB_STAT_CLEAR           0xFFFFFFFF
+
+/* EP IN ready status for Interupt EP indication */
+#define USB_EP0_IN_RDY           0x01010101
+#define USB_EP1_IN_RDY           0x02020202
+/* Repeat bytes across to work around Interrupt endpoint HW problem */
+#define USB_EP2_IN_RDY           0x04040404
+#define USB_EP3_IN_RDY           0x08080808
+
+#define USB_TX_PENDING_MSK       0xFF
+#define USB_RX_PENDING_MSK       0xFF
+
+/* USB Status bit definitions */
+#define USBINT_RX_PEND        BIT28   /*  USB Rx Pending register*/
+#define USBINT_UDC_VALIDINTF  BIT27   /*  UDC SetInterf detected */
+#define USBINT_UDC_VALIDCONF  BIT26   /*  UDC SetConfig detected */
+#define USBINT_UDC_RESET      BIT25   /*  UDC USB Reset detected */
+#define USBINT_UDC_SOF        BIT24   /*  UDC SOF detected       */
+
+#define USBINT_SUSPEND     BIT23   /*  USB Suspend detected   */
+#define USBINT_RESUME      BIT22   /*  USB Resume detected    */
+#define USBINT_EP3_INVLD   BIT21   /*  EP3 IN invalid header  */
+#define USBINT_EP2_INVLD   BIT20   /*  EP2 IN invalid header  */
+#define USBINT_EP1_INVLD   BIT19   /*  EP1 IN invalid header  */
+#define USBINT_EP0_INVLD   BIT18   /*  EP0 IN invalid header  */
+#define USBINT_EPINT_NAK   BIT17   /*  EP INT NAK             */
+#define USBINT_EPINT_ERR   BIT16   /*  EP INT Error count reached */
+#define USBINT_EP3_ERR     BIT15   /*  EP3 Error count reached */
+#define USBINT_EP2_ERR     BIT14   /*  EP2 Error count reached */
+#define USBINT_EP1_ERR     BIT13   /*  EP1 Error count reached */
+#define USBINT_EP0_ERR     BIT12   /*  EP0 Error count reached */
+
+#define USBINT_EPINT_DN    BIT10   /*  EP INT Tx done          */
+#define USBINT_EPINT_NXT   BIT11   /*  EP INT Tx next DWORD    */
+
+#define USBINT_EP3_IN      BIT9    /*  EP3 IN completed  */
+#define USBINT_EP2_IN      BIT8    /*  EP2 IN completed  */
+#define USBINT_EP1_IN      BIT7    /*  EP1 IN completed  */
+#define USBINT_EP0_IN      BIT6    /*  EP0 IN completed  */
+#define USBINT_EP3_OUT     BIT5    /*  EP3 OUT completed */
+#define USBINT_EP2_OUT     BIT4    /*  EP2 OUT completed */
+#define USBINT_EP1_OUT     BIT3    /*  EP1 OUT completed */
+#define USBINT_EP0_OUT     BIT2    /*  EP0 OUT completed */
+#define USBINT_CFG_DN      BIT1    /*  UDC config completed */
+#define USBINT_CFG_NXT     BIT0    /*  UDC next config DWORD */
+
+#define USBINT_EPALL_OUT   (USBINT_EP0_OUT | USBINT_EP1_OUT | USBINT_EP2_OUT | USBINT_EP3_OUT)
+#define USBINT_EPALL_IN    (USBINT_EP0_IN | USBINT_EP1_IN | USBINT_EP2_IN | USBINT_EP3_IN)
+
+/* USB Status2 bit definitions */
+#define USBINT2_EP3_TX_EMPTY 	BIT31   /*  USB EP3 Tx empty          */
+#define USBINT2_EP2_TX_EMPTY 	BIT30   /*  USB EP2 Tx empty          */
+#define USBINT2_EP1_TX_EMPTY 	BIT29   /*  USB EP1 Tx empty          */
+#define USBINT2_EP0_TX_EMPTY 	BIT28   /*  USB EP0 Tx empty          */
+#define USBINT2_RX_TIMEOUT	 	BIT26   /*  USB Rx time out           */
+#define USBINT2_RX_THRESHOLD  BIT25   /*  USB Rx Threshold reached  */
+#define USBINT2_RX_OVERRUN    BIT24   /*  USB Rx Overrun detected   */
+
+#define USB_INT2_EPALL_TX_EMPTY  (USBINT2_EP3_TX_EMPTY | USBINT2_EP2_TX_EMPTY | USBINT2_EP1_TX_EMPTY | USBINT2_EP0_TX_EMPTY)
+
+#define USBINT2_SETCONF       BIT23   /*  USB SetConfig detected    */
+#define USBINT2_SETINTER      BIT22   /*  USB SetInterface detected */
+#define USBINT2_GETCONF       BIT21   /*  USB GetConfig detected    */
+#define USBINT2_GETINTER      BIT20   /*  USB GetInterface detected */
+#define USBINT2_ALTSET        BIT19   /*  USB AltSetting detected   */
+#define USBINT2_SETUP         BIT18   /*  USB Setup command detected*/
+#define USBINT2_EP3OUT_CLR    BIT17   /*  EP3 OUT Stall cleared     */
+#define USBINT2_EP2OUT_CLR    BIT16   /*  EP2 OUT Stall cleared     */
+#define USBINT2_EP1OUT_CLR    BIT15   /*  EP1 OUT Stall cleared     */
+#define USBINT2_EP0OUT_CLR    BIT14   /*  EP0 OUT Stall cleared     */
+#define USBINT2_EP3IN_CLR     BIT13   /*  EP3 IN Stall cleared      */
+#define USBINT2_EP2IN_CLR     BIT12   /*  EP2 IN Stall cleared      */
+#define USBINT2_EP1IN_CLR     BIT11   /*  EP1 IN Stall cleared      */
+#define USBINT2_EP0IN_CLR     BIT10   /*  EP0 IN Stall cleared      */
+#define USBINT2_EPINT_CLR     BIT9    /*  EPINT IN Stall cleared    */
+#define USBINT2_EP3OUT_STALL  BIT8    /*  EP3 OUT Stall */
+#define USBINT2_EP2OUT_STALL  BIT7    /*  EP2 OUT Stall */
+#define USBINT2_EP1OUT_STALL  BIT6    /*  EP1 OUT Stall */
+#define USBINT2_EP0OUT_STALL  BIT5    /*  EP0 OUT Stall */
+#define USBINT2_EP3IN_STALL   BIT4    /*  EP3 IN Stall  */
+#define USBINT2_EP2IN_STALL   BIT3    /*  EP2 IN Stall  */
+#define USBINT2_EP1IN_STALL   BIT2    /*  EP1 IN Stall  */
+#define USBINT2_EP0IN_STALL   BIT1    /*  EP0 IN Stall  */
+#define USBINT2_EPINT_STALL   BIT0    /*  EPINT IN Stall*/
+
+/* USB Control-Status bit definitions */
+#define USBCSR_EP_RX_FULL     BIT14   /*  USB Rx pending reg is full      */
+#define USBCSR_EP3_TX_EMPTY   BIT13   /*  USB EP3 Tx pending reg is empty */
+#define USBCSR_EP2_TX_EMPTY   BIT12   /*  USB EP2 Tx pending reg is empty */
+#define USBCSR_EP1_TX_EMPTY   BIT11   /*  USB EP1 Tx pending reg is empty */
+#define USBCSR_EP0_TX_EMPTY   BIT10   /*  USB EP0 Tx pending reg is empty */
+#define USBCSR_EP_RX_CLRCNT   BIT9    /*  USB clear Rx count reg          */
+#define USBCSR_EP_RX_CLRPEND  BIT8    /*  USB clear Rx pending reg        */
+#define USBCSR_EP3_TX_CLRCNT  BIT7    /*  USB EP3 clear Tx count reg      */
+#define USBCSR_EP3_TX_CLRPEND BIT6    /*  USB EP3 clear Tx pending reg    */
+#define USBCSR_EP2_TX_CLRCNT  BIT5    /*  USB EP2 clear Tx count reg      */
+#define USBCSR_EP2_TX_CLRPEND BIT4    /*  USB EP2 clear Tx pending reg    */
+#define USBCSR_EP1_TX_CLRCNT  BIT3    /*  USB EP1 clear Tx count reg      */
+#define USBCSR_EP1_TX_CLRPEND BIT2    /*  USB EP1 clear Tx pending reg    */
+#define USBCSR_EP0_TX_CLRCNT  BIT1    /*  USB EP0 clear Tx count reg      */
+#define USBCSR_EP0_TX_CLRPEND BIT0    /*  USB EP0 clear Tx pending reg    */
+
+#define USBCSR_EPIALL_TX_CLRPEND  (BIT0 | BIT2 | BIT4 | BIT6 )
+#define USBCSR_EPIALL_TX_CLRCNT   (BIT1 | BIT3 | BIT5 | BIT7 )
+
+#ifdef USB_VCOM_ENDPOINT3
+#define ENDPOINTVCOM_IN       ENDPOINT3_IN
+#define ENDPOINTVCOM_OUT      ENDPOINT3_OUT
+#else
+#define ENDPOINTVCOM_IN       ENDPOINT1_IN
+#define ENDPOINTVCOM_OUT      ENDPOINT1_OUT
+#endif
+
+/*********************************************************/
+/* Define USB data structures                            */
+/*********************************************************/
+
+typedef struct tagUSBCONFIGINFO {
+ UINT32 Config_Total;
+ UINT32 Interface_Total;
+ UINT32 Alt_Interface_Total;
+ UINT32 EndPoint_Total; 					/* Physical endpoints including Enpoint 0 */
+} USBCONFIGINFO, *PUSBCONFIGINFO;
+
+
+typedef struct tagUSBCONFIGSTRUCT {
+ UINT32 dwEPAddr;
+ UINT32 dwEPMaxPacketSize;
+ UINT32 dwEPDirection;
+ UINT32 dwEPType;
+ UINT32 dwEPPoll;
+ UINT32 dwEPAltSetting;
+ UINT32 dwEPInterfaceNum;
+ UINT32 dwEPConfiguration;
+ UINT32 dwEPLogicalNum;
+} USBCONFIGSTRUCT, *PUSBCONFIGSTRUCT;
+
+typedef struct tagDEVICEDESCSTRUCT {
+	UINT8 cDescLength;
+	UINT8 cDescType;
+	UINT16 wUSBSpec;
+	UINT8 cDevClass;
+	UINT8 cDevSubClass;
+	UINT8 cDevProtocol;
+	UINT8 cMaxPacketSize;
+	UINT16 wVendorID;
+	UINT16 wProductID;
+	UINT16 wDevId;
+	UINT8 cManuStr;
+	UINT8 cProductStr;
+	UINT8 cSerialNumStr;
+	UINT8 cNumOfConfig;
+} DEVICEDESCSTRUCT, *PDEVICEDESCSTRUCT;
+
+
+typedef struct tagCONFIGDESCSTRUCT {
+	UINT8 cDescLength;
+	UINT8 cDescType;
+	UINT16  wTotalLength;
+	UINT8 cNumOfInterface;
+	UINT8 cConfigValue;
+	UINT8 cConfigStr;
+	UINT8 cAttribute;
+	UINT8 cMaxPower;
+} CONFIGDESCSTRUCT, *PCONFIGDESCSTRUCT;
+
+
+typedef struct tagINTERFACEDESCSTRUCT {
+	UINT8 cDescLength;
+	UINT8 cDescType;
+	UINT8 cInterfaceNum;
+	UINT8 cAltSetting;
+	UINT8 cNumOfEP;
+	UINT8 cInterClass;
+	UINT8 cInterSubClass;
+	UINT8 InterProtocol;
+	UINT8 InterfaceStr;
+} INTERFACEDESCSTRUCT, *PINTERFACEDESCSTRUCT;
+
+
+typedef struct tagEPDESCSTRUCT {
+	UINT8 cDescLength;
+	UINT8 cDescType;
+	UINT8 cEPAddress;
+	UINT8 cAttribute;
+	UINT16  wEPMaxPacketSize;
+	UINT8 cPollInterval;
+} EPDESCSTRUCT, *PEPDESCSTRUCT;
+
+
+typedef struct tagSETUPDATASTRUCT {
+	UINT8 cRequestType;
+	UINT8 cRequest;
+	UINT16  wValue;
+	UINT16  wIndex;
+	UINT16  wLength;
+} SETUPDATASTRUCT, *PSETUPDATASTRUCT;
+
+
+typedef struct tagCONTROLTRANSFER
+{
+	SETUPDATASTRUCT SetUpData;
+	UINT16 wLength;
+	UINT16 wCount;
+	UINT8  *pData;
+	UINT8  dataBuffer[USB_MAX_PACKET_SIZE];
+} CONTROLTRANSFER, *PCONTROLTRANSFER;
+
+typedef struct tagTXBUFFERSTRUCT
+{
+   UINT32 dwTxDesc;
+   UINT32 dwReserved;
+	UINT32 dwData[USB_MAX_PACKET_SIZE/4];
+	volatile UINT32 *dwpTxLink;
+	UINT32 dwTxLinkCount;
+} TXBUFFERSTRUCT, *PTXBUFFERSTRUCT;
+
+
+/*********************************************************/
+/* Define USB variables.                                 */
+/*********************************************************/
+
+extern void (*VendorDeviceRequest[USB_MAX_REQ_NUM])(void);
+extern void (*StandardDeviceRequest[USB_MAX_REQ_NUM])(SETUPDATASTRUCT * SetUpData);
+extern UINT32 (*USBEPRxHandler_Tbl[MAX_NUM_ENDPOINT])(volatile UINT8 *cData, UINT32 dwNumRxBytes);
+
+extern RXBUFFERSTRUCT RxBuffer;
+
+extern EPINFOSTRUCT EPCommonInfo;
+extern EPINFOSTRUCT EP0Info;
+extern EPINFOSTRUCT EP1Info;
+extern EPINFOSTRUCT EP2Info;
+extern EPINFOSTRUCT EP3Info;
+
+extern BOOL bUSBDebounce;
+extern BOOL bUSBResume;
+
+extern UINT32 PCLKNormalRate_Table[3];
+extern UINT32 PCLKSlowRate_Table[3];
+
+/*********************************************************/
+/* Define USB functions.                                 */
+/*********************************************************/
+
+BOOL sysUSBHwInit(void);
+BOOL UDCConfigure(void);
+BOOL UDCWriteConf( PUSBCONFIGSTRUCT PUsbEPInfo, PUSBCONFIGINFO  PUsbConfInfo );
+
+void USBDMAInit(void);
+INT32 USBWriteBuffer(eEPDirection eEPDir, volatile UINT32 *dwTxBuff, UINT32 dwByteCount);
+INT32 USBWriteDMA(eEPDirection eEPDir, UINT8 *pSrcBuff, UINT32 dwByteCount);
+INT32 USBAddPacketToLink(eEPDirection eEPDir, UINT8* pSBuff, UINT32 dwByteCount);
+
+void USBSetupHandler(SETUPDATASTRUCT * SetUpData);
+
+void GetStatus(SETUPDATASTRUCT * SetUpData);
+void ClearFeature(SETUPDATASTRUCT * SetUpData);     
+void SetFeature(SETUPDATASTRUCT * SetUpData);
+void SetAddress(SETUPDATASTRUCT * SetUpData);      
+void GetDescriptor(SETUPDATASTRUCT * SetUpData);
+void SetDescriptor(SETUPDATASTRUCT * SetUpData);
+void GetConfiguration(SETUPDATASTRUCT * SetUpData);
+void SetConfiguration(SETUPDATASTRUCT * SetUpData);
+void GetInterface(SETUPDATASTRUCT * SetUpData);
+void SetInterface(SETUPDATASTRUCT * SetUpData);
+void SynchFrame(SETUPDATASTRUCT * SetUpData);
+
+void SendDevDescriptor(UINT16 wLength);
+void SendConfigDescriptor(UINT16 wLength);
+BOOL SendStringDescriptor( UINT16 wValue, UINT16 wLength );
+
+void IntEPInit(void);
+
+BOOL EPConfParser(volatile UINT8* P_Dev_Desc_Tbl,volatile UINT8* P_Dev_Cfg_Tbl,PUSBCONFIGSTRUCT PUsbEPInfo, PUSBCONFIGINFO  PUsbConfInfo);
+
+#endif /* USBDEF_H */
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-cx821xx/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-cx821xx/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-cx821xx/vmalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ *  linux/include/asm-arm/arch-dsc21/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/a.out.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/a.out.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/a.out.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * uclinux/include/asm-armnommu/arch-dm270/a.out.h
+ *
+ */
+#ifndef __ASM_ARCH_A_OUT_H
+#define __ASM_ARCH_A_OUT_H
+
+#ifdef __KERNEL__
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/blkmem.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/blkmem.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/blkmem.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/blkmem.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,41 @@
+/***********************************************************************
+ * linux/include/asm-arm/arch-dm270/blkmem.h
+ *
+ *   Contains configuration settings for the blkmem driver
+ *
+ *   Derived from asm/arch-armnommu/arch-ta7s/blkmem.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#ifndef __ASM_ARCH_BLKMEM_H
+#define __ASM_ARCH_BLKMEM_H
+
+extern char _ebss;
+
+#define FIXUP_ARENAS \
+	arena[0].address = (unsigned long) &_ebss;
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/dma.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,62 @@
+/***********************************************************************
+ * asm/arch-armnommu/arch-dm270/dma.h:
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/dma.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#include "linux/config.h"
+
+/* type dmamode_t is declared in include/asm-armnommu along with values.
+ * Some additional DMA mode values are declared here.
+ */
+
+#define DMA_MODE_CARD_TO_SDRAM  0x08
+#define DMA_MODE_SDRAM_TO_CARD  0x0c
+#define DMA_MODE_FLASH_TO_SDRAM 0x10
+#define DMA_MODE_SDRAM_TO_FLASH 0x14
+
+/* MAX_DMA_ADDRESS -- max address we can program into the DMA address
+ * registers? Not sure. Various drivers use this value as a test before
+ * setting up a DMA. Also, the macros in linux/bootmem.h use this value
+ * as a goal for many of the bootmem allocations.
+ */
+
+/* Configured memory is specified during configuration. */
+
+#define MAX_DMA_ADDRESS (DRAM_BASE + DRAM_SIZE - 1)
+
+/* MAX_DMA_CHANNELS -- # of DMA control register sets we possess.
+ * We have one that can run in either direction and between two different
+ * destinations.
+ */
+
+#define MAX_DMA_CHANNELS 1
+
+#endif /* __ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/gio_ioctl.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/gio_ioctl.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/gio_ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/gio_ioctl.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,90 @@
+/************************************************************************
+ * include/asm-armnommu/arch-dm270/gio_ioctl.h
+ *
+ * Definitions of the General Purpose I/O (GIO) for the TI TMS320DM270.
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/gio_ioctl.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ************************************************************************/
+
+#ifndef __ASM_ARCH_GIO_IOCTL_H
+#define __ASM_ARCH_GIO_IOCTL_H
+ 
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <asm/ioctl.h>
+ 
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+#define GIO_MAGIC_NUMBER 'g'
+
+/* Major numbers, (from Documentation/devices.txt local/experimental list)  */
+ 
+#define GIO_MAJOR     125
+ 
+/************************************************************************
+ * GIO_DIRECTION: The GIO_DIRECTION can be either input (GIO_INPUT) or
+ * output (GIO_OUTPUT).  If unspecified, the GIO will default to input.
+ */
+
+#define GIO_OUTPUT 0
+#define GIO_INPUT 1
+
+#define GIO_DIRECTION _IO(GIO_MAGIC_NUMBER, 0)
+ 
+/************************************************************************
+ * GIO_BITSET: If the direction is set to output, this ioctl will set the
+ * output.  If the direction is input, this ioctl will return the value
+ * of the GIO pin (0, 1, or -1 on error).
+ */
+
+#define GIO_BITSET _IO(GIO_MAGIC_NUMBER, 1)
+
+/************************************************************************
+ * GIO_BITCLR: If the direction is set to output, this ioctl will clear the
+ * output.  If the direction is input, this ioctl will return the value
+ * of the GIO pin (0, 1, or -1 on error).
+ */
+
+#define GIO_BITCLR _IO(GIO_MAGIC_NUMBER, 2)
+
+/************************************************************************
+ * GIO_IRQPORT: Configure a GIO as an interrupt.  Only GIO0-GIO3 can
+ * be configured as an interrupting source.
+ */
+
+#define GIO_NOINTERRUPT 0
+#define GIO_INTERRUPT 1
+
+#define GIO_IRQPORT _IO(GIO_MAGIC_NUMBER, 3)
+
+#define GIO_IOC_MAXNR 3
+ 
+#endif /* __ASM_ARCH_GIO_IOCTL_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/hardware.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,889 @@
+/***********************************************************************
+ * linux/include/asm-armnommu/arch-dm270/hardware.h
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/irq.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <linux/config.h>
+#include <asm/mach-types.h>
+
+/* HARD_RESET_N0W: This is used in drivers/block/block.c.
+ */
+
+#define HARD_RESET_NOW()
+
+/* TI TMS320DM270 Peripheral Registers ------------------------------------- */
+
+#define DM270_REG_BASE                  0x00030000
+
+/* Clock Controller -------------------------------------------------------- */
+
+#define DM270_CLKC_BASE                 (DM270_REG_BASE + 0x0880)
+
+#define DM270_CLKC_OFFSET_PLLA          0x0000
+#define DM270_CLKC_OFFSET_PLLB          0x0002
+#define DM270_CLKC_OFFSET_CLKC          0x0004
+#define DM270_CLKC_OFFSET_SEL           0x0006
+#define DM270_CLKC_OFFSET_DIV           0x0008
+#define DM270_CLKC_OFFSET_BYP           0x000a
+#define DM270_CLKC_OFFSET_MMCCLK        0x000c
+#define DM270_CLKC_OFFSET_MSCLK         0x000e
+#define DM270_CLKC_OFFSET_MOD0          0x0010
+#define DM270_CLKC_OFFSET_MOD1          0x0012
+#define DM270_CLKC_OFFSET_MOD2          0x0014
+#define DM270_CLKC_OFFSET_LPCTL0        0x0016
+#define DM270_CLKC_OFFSET_LPCTL1        0x0018
+#define DM270_CLKC_OFFSET_OSEL          0x001a
+#define DM270_CLKC_OFFSET_O0DIV         0x001c
+#define DM270_CLKC_OFFSET_O1DIV         0x001e
+#define DM270_CLKC_OFFSET_O2DIV         0x0020
+#define DM270_CLKC_OFFSET_PWM0C         0x0022
+#define DM270_CLKC_OFFSET_PWM0H         0x0024
+#define DM270_CLKC_OFFSET_PWM1C         0x0026
+#define DM270_CLKC_OFFSET_PWM1H         0x0028
+
+#define DM270_CLKC_PLLA                 (DM270_CLKC_BASE + DM270_CLKC_OFFSET_PLLA)
+#define DM270_CLKC_PLLB                 (DM270_CLKC_BASE + DM270_CLKC_OFFSET_PLLB)
+#define DM270_CLKC_CLKC                 (DM270_CLKC_BASE + DM270_CLKC_OFFSET_CLKC)
+#define DM270_CLKC_SEL                  (DM270_CLKC_BASE + DM270_CLKC_OFFSET_SEL)
+#define DM270_CLKC_DIV                  (DM270_CLKC_BASE + DM270_CLKC_OFFSET_DIV)
+#define DM270_CLKC_BYP                  (DM270_CLKC_BASE + DM270_CLKC_OFFSET_BYP)
+#define DM270_CLKC_MMCCLK               (DM270_CLKC_BASE + DM270_CLKC_OFFSET_MMCCLK)
+#define DM270_CLKC_MSCLK                (DM270_CLKC_BASE + DM270_CLKC_OFFSET_MSCLK)
+#define DM270_CLKC_MOD0                 (DM270_CLKC_BASE + DM270_CLKC_OFFSET_MOD0)
+#define DM270_CLKC_MOD1                 (DM270_CLKC_BASE + DM270_CLKC_OFFSET_MOD1)
+#define DM270_CLKC_MOD2                 (DM270_CLKC_BASE + DM270_CLKC_OFFSET_MOD2)
+#define DM270_CLKC_LPCTL0               (DM270_CLKC_BASE + DM270_CLKC_OFFSET_LPCTL0)
+#define DM270_CLKC_LPCTL1               (DM270_CLKC_BASE + DM270_CLKC_OFFSET_LPCTL1)
+#define DM270_CLKC_OSEL                 (DM270_CLKC_BASE + DM270_CLKC_OFFSET_OSEL)
+#define DM270_CLKC_O0DIV                (DM270_CLKC_BASE + DM270_CLKC_OFFSET_O0DIV)
+#define DM270_CLKC_O1DIV                (DM270_CLKC_BASE + DM270_CLKC_OFFSET_O1DIV)
+#define DM270_CLKC_O2DIV                (DM270_CLKC_BASE + DM270_CLKC_OFFSET_O2DIV)
+#define DM270_CLKC_PWM0C                (DM270_CLKC_BASE + DM270_CLKC_OFFSET_PWM0C)
+#define DM270_CLKC_PWM0H                (DM270_CLKC_BASE + DM270_CLKC_OFFSET_PWM0H)
+#define DM270_CLKC_PWM1C                (DM270_CLKC_BASE + DM270_CLKC_OFFSET_PWM1C)
+#define DM270_CLKC_PWM1H                (DM270_CLKC_BASE + DM270_CLKC_OFFSET_PWM1H)
+
+#define DM270_CLKC_CLKC_CTM0S           0x0020
+#define DM270_CLKC_CLKC_CTM3S           0x0100
+#define DM270_CLKC_CLKC_CUAS0           0x0200
+#define DM270_CLKC_CLKC_CMSS            0x0800
+#define DM270_CLKC_CLKC_CMCIV           0x4000
+#define DM270_CLKC_BYP_CAB              0x0001
+#define DM270_CLKC_BYP_CDB              0x0010
+#define DM270_CLKC_BYP_CSB              0x0100
+#define DM270_CLKC_BYP_CMB              0x1000
+#define DM270_CLKC_MOD0_CACORE          0x0001
+#define DM270_CLKC_MOD0_CBUSC           0x0002
+#define DM270_CLKC_MOD0_CICA            0x0004
+#define DM270_CLKC_MOD0_CADMAC          0x0008
+#define DM270_CLKC_MOD0_CATM            0x0010
+#define DM270_CLKC_MOD0_CINTC           0x0020
+#define DM270_CLKC_MOD0_CEMIF           0x0040
+#define DM270_CLKC_MOD0_CSDRC           0x0080
+#define DM270_CLKC_MOD0_CEHIF           0x0100
+#define DM270_CLKC_MOD0_C5409           0x0200
+#define DM270_CLKC_MOD0_CHPIB           0x0400
+#define DM270_CLKC_MOD0_TEST            0x8000
+#define DM270_CLKC_MOD0_RSV_MASK        0x7800
+#define DM270_CLKC_MOD2_CTMR0           0x0002
+#define DM270_CLKC_MOD2_CTMR3           0x0010
+#define DM270_CLKC_MOD2_CGIO            0x0020
+#define DM270_CLKC_MOD2_CUAS0           0x0200
+#define DM270_CLKC_MOD2_CUAT0           0x0080
+#define DM270_CLKC_MOD2_RSV_MASK        0xc000
+
+#define DM270_CLKC_CLKC_CUAS            DM270_CLKC_CLKC_CUAS0
+#define DM270_CLKC_MOD2_CUAS            DM270_CLKC_MOD2_CUAS0
+#define DM270_CLKC_MOD2_CUAT            DM270_CLKC_MOD2_CUAT0
+
+/* Watch Dog Timer --------------------------------------------------------- */
+
+#define DM270_WDT_BASE                  (DM270_REG_BASE + 0x0400)
+
+#define DM270_WDT_OFFSET_WDTMD          0x0000
+#define DM270_WDT_OFFSET_WDTRST         0x0002
+#define DM270_WDT_OFFSET_WDTPRSCL       0x0004
+#define DM270_WDT_OFFSET_WDTVAL         0x0006
+#define DM270_WDT_OFFSET_WDTEXRST       0x0008
+
+#define DM270_WDT_WDTMD                 (DM270_WDT_BASE + DM270_WDT_OFFSET_WDTMD)
+#define DM270_WDT_WDTRST                (DM270_WDT_BASE + DM270_WDT_OFFSET_WDTRST)
+#define DM270_WDT_WDTPRSCL              (DM270_WDT_BASE + DM270_WDT_OFFSET_WDTPRSCL)
+#define DM270_WDT_WDTVAL                (DM270_WDT_BASE + DM270_WDT_OFFSET_WDTVAL)
+#define DM270_WDT_WDTEXRST              (DM270_WDT_BASE + DM270_WDT_OFFSET_WDTEXRST)
+
+/* External Memory Interface ----------------------------------------------- */
+
+#define DM270_EMIF_BASE                 (DM270_REG_BASE + 0x0a00)
+
+#define DM270_EMIF_OFFSET_CS3CTRL2      0x0010
+#define DM270_EMIF_OFFSET_CS4CTRL1      0x0012
+#define DM270_EMIF_OFFSET_CS4CTRL2      0x0014
+
+#define DM270_EMIF_CS0CTRL1             (DM270_EMIF_BASE + 0x0000)
+#define DM270_EMIF_CS0CTRL2             (DM270_EMIF_BASE + 0x0002)
+#define DM270_EMIF_CS1CTRL1A            (DM270_EMIF_BASE + 0x0004)
+#define DM270_EMIF_CS1CTRL1B            (DM270_EMIF_BASE + 0x0006)
+#define DM270_EMIF_CS1CTRL2             (DM270_EMIF_BASE + 0x0008)
+#define DM270_EMIF_CS2CTRL1             (DM270_EMIF_BASE + 0x000a)
+#define DM270_EMIF_CS2CTRL2             (DM270_EMIF_BASE + 0x000c)
+#define DM270_EMIF_CS3CTRL1             (DM270_EMIF_BASE + 0x000e)
+#define DM270_EMIF_CS3CTRL2             (DM270_EMIF_BASE + DM270_EMIF_OFFSET_CS3CTRL2)
+#define DM270_EMIF_CS4CTRL1             (DM270_EMIF_BASE + DM270_EMIF_OFFSET_CS4CTRL1)
+#define DM270_EMIF_CS4CTRL2             (DM270_EMIF_BASE + DM270_EMIF_OFFSET_CS4CTRL2)
+#define DM270_EMIF_BUSCTRL              (DM270_EMIF_BASE + 0x0016)
+#define DM270_EMIF_BUSRLS               (DM270_EMIF_BASE + 0x0018)
+#define DM270_EMIF_CFCTRL1              (DM270_EMIF_BASE + 0x001a)
+#define DM270_EMIF_CFCTRL2              (DM270_EMIF_BASE + 0x001c)
+#define DM270_EMIF_SMCTRL               (DM270_EMIF_BASE + 0x001e)
+#define DM270_EMIF_BUSINTEN             (DM270_EMIF_BASE + 0x0020)
+#define DM270_EMIF_BUSSTS               (DM270_EMIF_BASE + 0x0024)
+#define DM270_EMIF_BUSWAITMD            (DM270_EMIF_BASE + 0x0026)
+#define DM270_EMIF_ECC1CP               (DM270_EMIF_BASE + 0x0028)
+#define DM270_EMIF_ECC1LP               (DM270_EMIF_BASE + 0x002a)
+#define DM270_EMIF_ECC2CP               (DM270_EMIF_BASE + 0x002c)
+#define DM270_EMIF_ECC2LP               (DM270_EMIF_BASE + 0x002e)
+#define DM270_EMIF_ECCCLR               (DM270_EMIF_BASE + 0x0030)
+#define DM270_EMIF_PAGESZ               (DM270_EMIF_BASE + 0x0032)
+#define DM270_EMIF_IMGDSPDEST           (DM270_EMIF_BASE + 0x0034)
+#define DM270_EMIF_PRIOCTL              (DM270_EMIF_BASE + 0x0036)
+#define DM270_EMIF_SOURCEADDH           (DM270_EMIF_BASE + 0x0038)
+#define DM270_EMIF_SOURCEADDL           (DM270_EMIF_BASE + 0x003a)
+#define DM270_EMIF_DESTADDH             (DM270_EMIF_BASE + 0x003c)
+#define DM270_EMIF_DESTADDL             (DM270_EMIF_BASE + 0x003e)
+#define DM270_EMIF_DMASIZE              (DM270_EMIF_BASE + 0x0040)
+#define DM270_EMIF_DMADEVSEL            (DM270_EMIF_BASE + 0x0042)
+#define DM270_EMIF_DMACTL               (DM270_EMIF_BASE + 0x0044)
+#define DM270_EMIF_IMGDSPADDH           (DM270_EMIF_BASE + 0x0046)
+#define DM270_EMIF_IMGDSPADDL           (DM270_EMIF_BASE + 0x0048)
+#define DM270_EMIF_DPSTR0               (DM270_EMIF_BASE + 0x004a)
+#define DM270_EMIF_DPSTR1               (DM270_EMIF_BASE + 0x004c)
+#define DM270_EMIF_DPSTR2               (DM270_EMIF_BASE + 0x004e)
+#define DM270_EMIF_DPSTR3               (DM270_EMIF_BASE + 0x0050)
+#define DM270_EMIF_DPSTR4               (DM270_EMIF_BASE + 0x0052)
+#define DM270_EMIF_DPSTR5               (DM270_EMIF_BASE + 0x0054)
+
+#define DM270_EMIF_CS0CTRL1_CYCL_MASK   0x000f
+#define DM270_EMIF_CS0CTRL1_CEC_MASK    0x00f0
+#define DM270_EMIF_CS0CTRL1_WEC_MASK    0x0f00
+#define DM270_EMIF_CS0CTRL1_OEC_MASK    0xf000
+
+#define DM270_EMIF_CS2CTRL1_RSV_MASK    0x00f0
+
+#define DM270_EMIF_CS0CTRL2_CESU_MASK   0x000f
+#define DM270_EMIF_CS0CTRL2_WESU_MASK   0x00f0
+#define DM270_EMIF_CS0CTRL2_OESU_MASK   0x0f00
+#define DM270_EMIF_CS0CTRL2_IDLE_MASK   0x3000
+#define DM270_EMIF_CS0CTRL2_RSV_MASK    0xc000
+
+#define DM270_EMIF_CS1CTRL1A_CYCL_MASK  0x001f
+#define DM270_EMIF_CS1CTRL1A_CEC_MASK   0x1f00
+#define DM270_EMIF_CS1CTRL1A_RSV_MASK   0xe0e0
+
+#define DM270_EMIF_CS1CTRL1B_WEC_MASK   0x001f
+#define DM270_EMIF_CS1CTRL1B_OEC_MASK   0x1f00
+#define DM270_EMIF_CS1CTRL1B_RSV_MASK   0xe0e0
+
+#define DM270_EMIF_CS1CTRL2_CESU_MASK   0x000f
+#define DM270_EMIF_CS1CTRL2_WESU_MASK   0x00f0
+#define DM270_EMIF_CS1CTRL2_OESU_MASK   0x0f00
+#define DM270_EMIF_CS1CTRL2_IDLE_MASK   0x3000
+#define DM270_EMIF_CS1CTRL2_RSV_MASK    0xc000
+
+#define DM270_EMIF_CS2CTRL1_CYCL_MASK   0x000f
+#define DM270_EMIF_CS2CTRL1_WEC_MASK    0x0f00
+#define DM270_EMIF_CS2CTRL1_OEC_MASK    0xf000
+#define DM270_EMIF_CS2CTRL1_RSV_MASK    0x00f0
+
+#define DM270_EMIF_CS2CTRL2_RESU_MASK   0x000f
+#define DM270_EMIF_CS2CTRL2_WESU_MASK   0x00f0
+#define DM270_EMIF_CS2CTRL2_OESU_MASK   0x0f00
+#define DM270_EMIF_CS2CTRL2_IDLE_MASK   0x3000
+#define DM270_EMIF_CS2CTRL2_RSV_MASK    0xc000
+
+#define DM270_EMIF_CS3CTRL1_CYCL_MASK   0x000f
+#define DM270_EMIF_CS3CTRL1_CEC_MASK    0x00f0
+#define DM270_EMIF_CS3CTRL1_WEC_MASK    0x0f00
+#define DM270_EMIF_CS3CTRL1_OEC_MASK    0xf000
+
+#define DM270_EMIF_CS3CTRL2_BUSW        0x4000
+#define DM270_EMIF_CS3CTRL2_CESU_MASK   0x000f
+#define DM270_EMIF_CS3CTRL2_WESU_MASK   0x00f0
+#define DM270_EMIF_CS3CTRL2_OESU_MASK   0x0f00
+#define DM270_EMIF_CS3CTRL2_IDLE_MASK   0x3000
+#define DM270_EMIF_CS3CTRL2_RSV_MASK    0x8000
+#define DM270_EMIF_CS3CTRL2_WESU1       0x0010
+#define DM270_EMIF_CS3CTRL2_OESU1       0x0100
+#define DM270_EMIF_CS3CTRL2_IDLE1       0x1000
+#define DM270_EMIF_CS3CTRL2_BUSW16      (DM270_EMIF_CS3CTRL2_BUSW)
+
+#define DM270_EMIF_CS4CTRL1_CYCL_MASK   0x000f
+#define DM270_EMIF_CS4CTRL1_CEC_MASK    0x00f0
+#define DM270_EMIF_CS4CTRL1_WEC_MASK    0x0f00
+#define DM270_EMIF_CS4CTRL1_OEC_MASK    0xf000
+#define DM270_EMIF_CS4CTRL1_CYCL16      0x000f
+#define DM270_EMIF_CS4CTRL1_CEC16       0x00f0
+#define DM270_EMIF_CS4CTRL1_WEC10       0x0900
+#define DM270_EMIF_CS4CTRL1_OEC13       0xc000
+
+#define DM270_EMIF_CS4CTRL2_BUSW        0x4000
+#define DM270_EMIF_CS4CTRL2_CESL        0x8000
+#define DM270_EMIF_CS4CTRL2_CESU_MASK   0x000f
+#define DM270_EMIF_CS4CTRL2_WESU_MASK   0x00f0
+#define DM270_EMIF_CS4CTRL2_OESU_MASK   0x0f00
+#define DM270_EMIF_CS4CTRL2_IDLE_MASK   0x3000
+#define DM270_EMIF_CS4CTRL2_WESU2       0x0020
+#define DM270_EMIF_CS4CTRL2_OESU2       0x0200
+#define DM270_EMIF_CS4CTRL2_IDLE3       0x3000
+#define DM270_EMIF_CS4CTRL2_BUSW16      (DM270_EMIF_CS4CTRL2_BUSW)
+
+#define DM270_EMIF_BUSCTRL_EMWE3        0x0001
+#define DM270_EMIF_BUSCTRL_EMWE4        0x0002
+#define DM270_EMIF_BUSCTRL_RSV_MASK     0xfffc
+
+#define DM270_EMIF_BUSRLS_EMREL         0x0001
+#define DM270_EMIF_BUSRLS_SDREL         0x0002
+#define DM270_EMIF_BUSRLS_BUSSEL        0x0004
+#define DM270_EMIF_BUSRLS_RSV_MASK      0xfff8
+
+#define DM270_EMIF_CFCTRL1_CFSEL        0x0001
+#define DM270_EMIF_CFCTRL1_RSV_MASK     0xfffe
+
+#define DM270_EMIF_CFCTRL2_CFMOD        0x0001
+#define DM270_EMIF_CFCTRL2_BUSSZ        0x0010
+#define DM270_EMIF_CFCTRL2_RSV_MASK     0xffee
+
+#define DM270_EMIF_SMCTRL_SCEH          0x0001
+#define DM270_EMIF_SMCTRL_RSV_MASK      0xfffe
+
+#define DM270_EMIF_BUSINTEN_CBIEN       0x0001
+#define DM270_EMIF_BUSINTEN_CBCND       0x0002
+#define DM270_EMIF_BUSINTEN_RSV_MASK    0xfffc
+
+#define DM270_EMIF_BUSSTS_CFRDY         0x0001
+#define DM270_EMIF_BUSSTS_CFWAIT        0x0002
+#define DM270_EMIF_BUSSTS_IOIS16        0x0004
+#define DM270_EMIF_BUSSTS_EMWAIT        0x0008
+#define DM270_EMIF_BUSSTS_RSV_MASK      0xfff0
+
+#define DM270_EMIF_BUSWAITMD_CFRW       0x0001
+#define DM270_EMIF_BUSWAITMD_CFRSL      0x0002
+#define DM270_EMIF_BUSWAITMD_RSV_MASK   0xfffc
+
+#define DM270_EMIF_ECCCP_RD1_MASK       0x0003
+#define DM270_EMIF_ECCCP_CP_MASK        0x00fc
+#define DM270_EMIF_ECCCP_RSV_MASK       0xff00
+
+#define DM270_EMIF_ECCCLR_ECLR          0x0001
+#define DM270_EMIF_ECCCLR_RSV_MASK      0xfffe
+
+#define DM270_EMIF_PAGESZ_PAGESZ        0x0001
+#define DM270_EMIF_PAGESZ_RSV_MASK      0xfffe
+
+#define DM270_EMIF_IMGDSPDEST_DDST_MASK 0x0007
+#define DM270_EMIF_IMGDSPDEST_IDST_MASK 0x0070
+#define DM270_EMIF_IMGDSPDEST_RSV_MASK  0xff88
+
+#define DM270_EMIF_PRIOCTL_PRY4_MASK    0x0003
+#define DM270_EMIF_PRIOCTL_PRY3_MASK    0x000c
+#define DM270_EMIF_PRIOCTL_PRY2_MASK    0x0030
+#define DM270_EMIF_PRIOCTL_PRY1_MASK    0x00c0
+#define DM270_EMIF_PRIOCTL_RSV_MASK     0xff00
+
+#define DM270_EMIF_SOURCEADDH_SAH_MASK  0x03ff
+#define DM270_EMIF_SOURCEADDH_SAFIX     0x1000
+#define DM270_EMIF_SOURCEADDH_RSV_MASK  0xec00
+
+#define DM270_EMIF_DESTADDH_DAH_MASK    0x03ff
+#define DM270_EMIF_DESTADDH_DAFIX       0x1000
+#define DM270_EMIF_DESTADDH_RSV_MASK    0xec00
+
+#define DM270_EMIF_DMADEVSEL_DDV_MASK   0x0007
+#define DM270_EMIF_DMADEVSEL_SDV_MASK   0x0070
+#define DM270_EMIF_DMADEVSEL_RSV_MASK   0xff88
+
+#define DM270_EMIF_DMACTL_GO            0x0001
+#define DM270_EMIF_DMACTL_ENDI_MASK     0x0300
+#define DM270_EMIF_DMACTL_RSV_MASK      0xfcfe
+
+#define DM270_EMIF_IMGDSPADDH_CDAH_MASK 0x007f
+#define DM270_EMIF_IMGDSPADDH_RSV_MASK  0xff80
+
+#define DM270_EMIF_DPSTR_DST_MASK       0x00ff
+#define DM270_EMIF_DPSTR_RSV_MASK       0xff00
+
+/* SDRAM Controller -------------------------------------------------------- */
+
+#define DM270_SDRC_BASE                 (DM270_REG_BASE + 0x0980)
+
+#define DM270_SDRC_OFFSET_SDMODE        0x0026
+#define DM270_SDRC_OFFSET_REFCTL        0x0028
+
+#define DM270_SDRC_SDBUFD0L             (DM270_SDRC_BASE + 0x0000)
+#define DM270_SDRC_SDBUFD0H             (DM270_SDRC_BASE + 0x0002)
+#define DM270_SDRC_SDBUFD1L             (DM270_SDRC_BASE + 0x0004)
+#define DM270_SDRC_SDBUFD1H             (DM270_SDRC_BASE + 0x0006)
+#define DM270_SDRC_SDBUFD2L             (DM270_SDRC_BASE + 0x0008)
+#define DM270_SDRC_SDBUFD2H             (DM270_SDRC_BASE + 0x000a)
+#define DM270_SDRC_SDBUFD3L             (DM270_SDRC_BASE + 0x000c)
+#define DM270_SDRC_SDBUFD3H             (DM270_SDRC_BASE + 0x000e)
+#define DM270_SDRC_SDBUFD4L             (DM270_SDRC_BASE + 0x0010)
+#define DM270_SDRC_SDBUFD4H             (DM270_SDRC_BASE + 0x0012)
+#define DM270_SDRC_SDBUFD5L             (DM270_SDRC_BASE + 0x0014)
+#define DM270_SDRC_SDBUFD5H             (DM270_SDRC_BASE + 0x0016)
+#define DM270_SDRC_SDBUFD6L             (DM270_SDRC_BASE + 0x0018)
+#define DM270_SDRC_SDBUFD6H             (DM270_SDRC_BASE + 0x001a)
+#define DM270_SDRC_SDBUFD7L             (DM270_SDRC_BASE + 0x001c)
+#define DM270_SDRC_SDBUFD7H             (DM270_SDRC_BASE + 0x001e)
+#define DM270_SDRC_SDBUFAD1             (DM270_SDRC_BASE + 0x0020)
+#define DM270_SDRC_SDBUFAD2             (DM270_SDRC_BASE + 0x0022)
+#define DM270_SDRC_SDBUFCTL             (DM270_SDRC_BASE + 0x0024)
+#define DM270_SDRC_SDMODE               (DM270_SDRC_BASE + DM270_SDRC_OFFSET_SDMODE)
+#define DM270_SDRC_REFCTL               (DM270_SDRC_BASE + DM270_SDRC_OFFSET_REFCTL)
+#define DM270_SDRC_SDPRTY1              (DM270_SDRC_BASE + 0x002a)
+#define DM270_SDRC_SDPRTY2              (DM270_SDRC_BASE + 0x002c)
+#define DM270_SDRC_SDPRTY3              (DM270_SDRC_BASE + 0x002e)
+#define DM270_SDRC_SDPRTY4              (DM270_SDRC_BASE + 0x0030)
+#define DM270_SDRC_SDPRTY5              (DM270_SDRC_BASE + 0x0032)
+#define DM270_SDRC_SDPRTY6              (DM270_SDRC_BASE + 0x0034)
+#define DM270_SDRC_SDPRTY7              (DM270_SDRC_BASE + 0x0036)
+#define DM270_SDRC_SDPRTY8              (DM270_SDRC_BASE + 0x0038)
+#define DM270_SDRC_SDPRTY9              (DM270_SDRC_BASE + 0x003a)
+#define DM270_SDRC_SDPRTY10             (DM270_SDRC_BASE + 0x003c)
+#define DM270_SDRC_PRTYON               (DM270_SDRC_BASE + 0x003e)
+#define DM270_SDRC_SDRCTEST             (DM270_SDRC_BASE + 0x0040)
+
+#define DM270_SDRC_SDBUFAD1_SDAH_MASK   0x003f
+#define DM270_SDRC_SDBUFAD1_AAI         0x0100
+#define DM270_SDRC_SDBUFAD1_RSV_MASK    0xfec0
+
+#define DM270_SDRC_SDBUFCTL_RSD         0x0001
+#define DM270_SDRC_SDBUFCTL_WA          0x0002
+#define DM270_SDRC_SDBUFCTL_WM          0x0004
+#define DM270_SDRC_SDBUFCTL_BUFC        0x0008
+#define DM270_SDRC_SDBUFCTL_PTSEL_MASK  0x0030
+#define DM270_SDRC_SDBUFCTL_RSV_MASK    0xffc0
+
+#define DM270_SDRC_SDMODE_SDCTL_MASK    0x003f
+#define DM270_SDRC_SDMODE_SDCTL_NOP     0x0000 /* NOP:   No operation */
+#define DM270_SDRC_SDMODE_SDCTL_MSR     0x0001 /* MSR:   Sets mode */
+#define DM270_SDRC_SDMODE_SDCTL_PREA    0x0002 /* PREA:  Precharges all banks */
+#define DM270_SDRC_SDMODE_SDCTL_REF     0x0004 /* REF:   Issues auto refresh command */
+#define DM270_SDRC_SDMODE_SDCTL_SELF    0x0008 /* SELF:  Enters self refresh mode */
+#define DM270_SDRC_SDMODE_SDCTL_SELFC   0x0010 /* SELFC: Cancels self refresh/power down mode */
+#define DM270_SDRC_SDMODE_SDCTL_PDN     0x0020 /* PDN:   Enters power down mode */
+/* Added in ES1.1 for mobile SDRAM support */
+#define DM270_SDRC_SDMODE_SDCTL_DPDN    0x0030 /* DPDN:  Deep powerdown mode */
+#define DM270_SDRC_SDMODE_SDCTL_EMSR    0x0011 /* EMSR:  Set extended mode register */
+#define DM270_SDRC_SDMODE_APO           0x0040
+#define DM270_SDRC_SDMODE_DQMC          0x0080
+#define DM270_SDRC_SDMODE_MEMT_MASK     0x0300
+#define DM270_SDRC_SDMODE_CASL          0x0400
+#define DM270_SDRC_SDMODE_BNS           0x1000
+#define DM270_SDRC_SDMODE_TRCD          0x2000
+#define DM270_SDRC_SDMODE_SDBW          0x4000
+#define DM270_SDRC_SDMODE_TRDL          0x8000
+#define DM270_SDRC_SDMODE_RSV_MASK      0x0800
+
+#define DM270_SDRC_REFCTL_REFC_MASK     0x00ff
+#define DM270_SDRC_REFCTL_REFEN         0x0100
+#define DM270_SDRC_REFCTL_SDMA2_MASK    0x1c00
+#define DM270_SDRC_REFCTL_SDMA2_EMIF    0x0000
+#define DM270_SDRC_REFCTL_SDMA2_SERIAL  0x0400
+#define DM270_SDRC_REFCTL_SDMA2_USB     0x0800
+#define DM270_SDRC_REFCTL_SDMA2_MMCSD   0x0c00
+#define DM270_SDRC_REFCTL_SDMA2_HPIB    0x1000
+#define DM270_SDRC_REFCTL_SDMA1_MASK    0xe000
+#define DM270_SDRC_REFCTL_SDMA1_EMIF    0x0000
+#define DM270_SDRC_REFCTL_SDMA1_SERIAL  0x2000
+#define DM270_SDRC_REFCTL_SDMA1_USB     0x4000
+#define DM270_SDRC_REFCTL_SDMA1_MMCSD   0x6000
+#define DM270_SDRC_REFCTL_SDMA1_HPIB    0x8000
+#define DM270_SDRC_REFCTL_RSV_MASK      0x0200
+
+#define DM270_SDRC_SDPRTY_PRTY_MASK     0x03ff
+#define DM270_SDRC_SDPRTY_RSV_MASK      0xfc00
+
+#define DM270_SDRC_PRTYON_PTYON         0x0001
+#define DM270_SDRC_PRTYON_RSV_MASK      0xfffe
+
+#define DM270_SDRC_SDRCTEST_TEST        0x0001
+#define DM270_SDRC_SDRCTEST_RSV_MASK    0xfffe
+
+#define DM270_SDRC_SDMODE_8K512         0x0300
+#define DM270_SDRC_SDMODE_CL3           0x0400
+#define DM270_SDRC_SDMODE_4BANK         0x1000
+#define DM270_SDRC_SDMODE_32BIT         0x0000
+#define DM270_SDRC_SDMODE_TRDL2         0x8000
+
+/* Interrupt Controller ---------------------------------------------------- */
+
+#define DM270_INTC_BASE                 (DM270_REG_BASE + 0x0500)
+
+#define DM270_INTC_OFFSET_EINT0         0x0028
+#define DM270_INTC_OFFSET_EINT1         0x002a
+#define DM270_INTC_OFFSET_EINT2         0x002c
+
+#define DM270_INTC_FIQ0                 (DM270_INTC_BASE + 0x0000)
+#define DM270_INTC_FIQ1                 (DM270_INTC_BASE + 0x0002)
+#define DM270_INTC_FIQ2                 (DM270_INTC_BASE + 0x0004)
+#define DM270_INTC_IRQ0                 (DM270_INTC_BASE + 0x0008)
+#define DM270_INTC_IRQ1                 (DM270_INTC_BASE + 0x000a)
+#define DM270_INTC_IRQ2                 (DM270_INTC_BASE + 0x000c)
+#define DM270_INTC_FIQENTRY0            (DM270_INTC_BASE + 0x0010)
+#define DM270_INTC_FIQENTRY1            (DM270_INTC_BASE + 0x0012)
+#define DM270_INTC_IRQENTRY0            (DM270_INTC_BASE + 0x0018)
+#define DM270_INTC_IRQENTRY1            (DM270_INTC_BASE + 0x001a)
+#define DM270_INTC_FISEL0               (DM270_INTC_BASE + 0x0020)
+#define DM270_INTC_FISEL1               (DM270_INTC_BASE + 0x0022)
+#define DM270_INTC_FISEL2               (DM270_INTC_BASE + 0x0024)
+#define DM270_INTC_EINT0                (DM270_INTC_BASE + DM270_INTC_OFFSET_EINT0)
+#define DM270_INTC_EINT1                (DM270_INTC_BASE + DM270_INTC_OFFSET_EINT1)
+#define DM270_INTC_EINT2                (DM270_INTC_BASE + DM270_INTC_OFFSET_EINT2)
+#define DM270_INTC_INTRAW               (DM270_INTC_BASE + 0x0030)
+#define DM270_INTC_EABASE0              (DM270_INTC_BASE + 0x0038)
+#define DM270_INTC_EABASE1              (DM270_INTC_BASE + 0x003a)
+#define DM270_INTC_INTPRI00             (DM270_INTC_BASE + 0x0040)
+#define DM270_INTC_INTPRI01             (DM270_INTC_BASE + 0x0042)
+#define DM270_INTC_INTPRI02             (DM270_INTC_BASE + 0x0044)
+#define DM270_INTC_INTPRI03             (DM270_INTC_BASE + 0x0046)
+#define DM270_INTC_INTPRI04             (DM270_INTC_BASE + 0x0048)
+#define DM270_INTC_INTPRI05             (DM270_INTC_BASE + 0x004a)
+#define DM270_INTC_INTPRI06             (DM270_INTC_BASE + 0x004c)
+#define DM270_INTC_INTPRI07             (DM270_INTC_BASE + 0x004e)
+#define DM270_INTC_INTPRI08             (DM270_INTC_BASE + 0x0050)
+#define DM270_INTC_INTPRI09             (DM270_INTC_BASE + 0x0052)
+#define DM270_INTC_INTPRI10             (DM270_INTC_BASE + 0x0054)
+#define DM270_INTC_INTPRI11             (DM270_INTC_BASE + 0x0056)
+#define DM270_INTC_INTPRI12             (DM270_INTC_BASE + 0x0058)
+#define DM270_INTC_INTPRI13             (DM270_INTC_BASE + 0x005a)
+#define DM270_INTC_INTPRI14             (DM270_INTC_BASE + 0x005c)
+#define DM270_INTC_INTPRI15             (DM270_INTC_BASE + 0x005e)
+#define DM270_INTC_INTPRI16             (DM270_INTC_BASE + 0x0060)
+#define DM270_INTC_INTPRI17             (DM270_INTC_BASE + 0x0062)
+#define DM270_INTC_INTPRI18             (DM270_INTC_BASE + 0x0064)
+#define DM270_INTC_INTPRI19             (DM270_INTC_BASE + 0x0066)
+
+#define DM270_INTC_EINT(vector)         ((vector < 16) ? DM270_INTC_EINT0 : \
+                                            ((vector < 32) ? DM270_INTC_EINT1 : DM270_INTC_EINT2))
+#define DM270_INTC_FIQ(vector)          ((vector < 16) ? DM270_INTC_FIQ0 : \
+                                            ((vector < 32) ? DM270_INTC_FIQ1 : DM270_INTC_FIQ2))
+#define DM270_INTC_IRQ(vector)          ((vector < 16) ? DM270_INTC_IRQ0 : \
+                                            ((vector < 32) ? DM270_INTC_IRQ1 : DM270_INTC_IRQ2))
+#define DM270_INTC_EINT_SHIFT(vector)   ((vector < 16) ? vector : \
+                                            ((vector < 32) ? (vector - 16) : (vector - 32)))
+#define DM270_INTC_FIQ_SHIFT(vector)    DM270_INTC_EINT_SHIFT(vector)
+#define DM270_INTC_IRQ_SHIFT(vector)    DM270_INTC_EINT_SHIFT(vector)
+
+#define DM270_INTC_TMR0_BIT             0x0001
+#define DM270_INTC_TMR1_BIT             0x0002
+#define DM270_INTC_TMR2_BIT             0x0004
+#define DM270_INTC_TMR3_BIT             0x0008
+#define DM270_INTC_CCDVD0_BIT           0x0010
+#define DM270_INTC_CCDVD1_BIT           0x0020
+#define DM270_INTC_CCDVD2_BIT           0x0040
+#define DM270_INTC_OSD_BIT              0x0080
+#define DM270_INTC_SP0_BIT              0x0100
+#define DM270_INTC_SP1_BIT              0x0200
+#define DM270_INTC_EXTHOST_BIT          0x0400
+#define DM270_INTC_DSPHINT_BIT          0x0800
+#define DM270_INTC_UART0_BIT            0x1000
+#define DM270_INTC_UART1_BIT            0x2000
+#define DM270_INTC_USB_BIT              0x4000
+#define DM270_INTC_MTC0_BIT             0x8000
+
+#define DM270_INTC_MTC1_BIT             0x0001
+#define DM270_INTC_MMCSD0_BIT           0x0002
+#define DM270_INTC_MMCSD1_BIT           0x0004
+#define DM270_INTC_RSVINT0_BIT          0x0008
+#define DM270_INTC_EXT1_BIT             0x0010
+#define DM270_INTC_EXT2_BIT             0x0020
+#define DM270_INTC_EXT3_BIT             0x0040
+#define DM270_INTC_EXT4_BIT             0x0080
+#define DM270_INTC_EXT5_BIT             0x0100
+#define DM270_INTC_EXT6_BIT             0x0200
+#define DM270_INTC_EXT7_BIT             0x0400
+#define DM270_INTC_EXT8_BIT             0x0800
+#define DM270_INTC_EXT9_BIT             0x1000
+#define DM270_INTC_EXT10_BIT            0x2000
+#define DM270_INTC_EXT11_BIT            0x4000
+#define DM270_INTC_EXT12_BIT            0x8000
+
+#define DM270_INTC_EXT13_BIT            0x0001
+#define DM270_INTC_EXT14_BIT            0x0002
+#define DM270_INTC_EXT15_BIT            0x0004
+#define DM270_INTC_PREV_BIT             0x0008
+#define DM270_INTC_WDT_BIT              0x0010
+#define DM270_INTC_I2C_BIT              0x0020
+#define DM270_INTC_CLKC_BIT             0x0040
+#define DM270_INTC_RSVINT1_BIT          0x0080
+#define DM270_INTC_RSV_MASK             0xff00
+
+#define DM270_INTC_FIQENTRY1_RSV_MASK   0xe000
+
+#define DM270_INTC_IRQENTRY1_RSV_MASK   0xe000
+
+#define DM270_INTC_INTRAW_FIQ           0x0001
+#define DM270_INTC_INTRAW_IRQ           0x0002
+#define DM270_INTC_INTRAW_RSV_MASK      0xfffc
+
+#define DM270_INTC_EABASE0_TSIZE_MASK   0x0003
+#define DM270_INTC_EABASE0_EABL_MASK    0xfff8
+#define DM270_INTC_EABASE0_RSV_MASK     0x0004
+
+#define DM270_INTC_EABASE1_EABH_MASK    0x1fff
+#define DM270_INTC_EABASE1_RSV_MASK     0xe000
+
+#define DM270_INTC_INTPRI_PRIOL_MASK    0x003f
+#define DM270_INTC_INTPRI_PRIOH_MASK    0x3f00
+#define DM270_INTC_INTPRI_RSV_MASK      0xc0c0
+
+/* GIO --------------------------------------------------------------------- */
+
+#define DM270_GIO_BASE                  (DM270_REG_BASE + 0x0580)
+
+#define DM270_GIO_OFFSET_DIR0           0x0000
+#define DM270_GIO_OFFSET_DIR1           0x0002
+#define DM270_GIO_OFFSET_DIR2           0x0004
+#define DM270_GIO_OFFSET_INV0           0x0006
+#define DM270_GIO_OFFSET_INV1           0x0008
+#define DM270_GIO_OFFSET_INV2           0x000a
+#define DM270_GIO_OFFSET_BITSET0        0x000c
+#define DM270_GIO_OFFSET_BITSET1        0x000e
+#define DM270_GIO_OFFSET_BITSET2        0x0010
+#define DM270_GIO_OFFSET_BITCLR0        0x0012
+#define DM270_GIO_OFFSET_BITCLR1        0x0014
+#define DM270_GIO_OFFSET_BITCLR2        0x0016
+#define DM270_GIO_OFFSET_IRQPORT        0x0018
+#define DM270_GIO_OFFSET_IRQEDGE        0x001a
+#define DM270_GIO_OFFSET_CHAT0          0x001c
+#define DM270_GIO_OFFSET_CHAT1          0x001e
+#define DM270_GIO_OFFSET_CHAT2          0x0020
+#define DM270_GIO_OFFSET_NCHAT          0x0022
+#define DM270_GIO_OFFSET_FSEL0          0x0024
+#define DM270_GIO_OFFSET_FSEL1          0x0026
+
+#define DM270_GIO_DIR0                  (DM270_GIO_BASE + DM270_GIO_OFFSET_DIR0)
+#define DM270_GIO_DIR1                  (DM270_GIO_BASE + DM270_GIO_OFFSET_DIR1)
+#define DM270_GIO_DIR2                  (DM270_GIO_BASE + DM270_GIO_OFFSET_DIR2)
+#define DM270_GIO_INV0                  (DM270_GIO_BASE + DM270_GIO_OFFSET_INV0)
+#define DM270_GIO_INV1                  (DM270_GIO_BASE + DM270_GIO_OFFSET_INV1)
+#define DM270_GIO_INV2                  (DM270_GIO_BASE + DM270_GIO_OFFSET_INV2)
+#define DM270_GIO_BITSET0               (DM270_GIO_BASE + DM270_GIO_OFFSET_BITSET0)
+#define DM270_GIO_BITSET1               (DM270_GIO_BASE + DM270_GIO_OFFSET_BITSET1)
+#define DM270_GIO_BITSET2               (DM270_GIO_BASE + DM270_GIO_OFFSET_BITSET2)
+#define DM270_GIO_BITCLR0               (DM270_GIO_BASE + DM270_GIO_OFFSET_BITCLR0)
+#define DM270_GIO_BITCLR1               (DM270_GIO_BASE + DM270_GIO_OFFSET_BITCLR1)
+#define DM270_GIO_BITCLR2               (DM270_GIO_BASE + DM270_GIO_OFFSET_BITCLR2)
+#define DM270_GIO_IRQPORT               (DM270_GIO_BASE + DM270_GIO_OFFSET_IRQPORT)
+#define DM270_GIO_IRQEDGE               (DM270_GIO_BASE + DM270_GIO_OFFSET_IRQEDGE)
+#define DM270_GIO_CHAT0                 (DM270_GIO_BASE + DM270_GIO_OFFSET_CHAT0)
+#define DM270_GIO_CHAT1                 (DM270_GIO_BASE + DM270_GIO_OFFSET_CHAT1)
+#define DM270_GIO_CHAT2                 (DM270_GIO_BASE + DM270_GIO_OFFSET_CHAT2)
+#define DM270_GIO_NCHAT                 (DM270_GIO_BASE + DM270_GIO_OFFSET_NCHAT)
+#define DM270_GIO_FSEL0                 (DM270_GIO_BASE + DM270_GIO_OFFSET_FSEL0)
+#define DM270_GIO_FSEL1                 (DM270_GIO_BASE + DM270_GIO_OFFSET_FSEL1)
+
+#define DM270_GIO_DIR(vector)           (((vector - DM270_INTERRUPT_RSVINT0) < 16) ? DM270_GIO_DIR0 : \
+                                            (((vector - DM270_INTERRUPT_RSVINT0) < 32) ? DM270_GIO_DIR1 : DM270_GIO_DIR2))
+#define DM270_GIO_INV(vector)           (((vector - DM270_INTERRUPT_RSVINT0) < 16) ? DM270_GIO_INV0 : \
+                                            (((vector - DM270_INTERRUPT_RSVINT0) < 32) ? DM270_GIO_INV1 : DM270_GIO_INV2))
+#define DM270_GIO_DIR_SHIFT(vector)     (((vector - DM270_INTERRUPT_RSVINT0) < 16) ? (vector - DM270_INTERRUPT_RSVINT0) : \
+                                            (((vector - DM270_INTERRUPT_RSVINT0) < 32) ? (vector - DM270_INTERRUPT_RSVINT0 - 16) : \
+                                            (vector - DM270_INTERRUPT_RSVINT0 - 32)))
+#define DM270_GIO_IRQPORT_SHIFT(vector) DM270_GIO_DIR_SHIFT(vector)
+#define DM270_GIO_INV_SHIFT(vector)     DM270_GIO_DIR_SHIFT(vector)
+#define DM270_GIO_IRQEDGE_SHIFT(vector) DM270_GIO_DIR_SHIFT(vector)
+
+#define DM270_GIO_RSV_BIT               0x0001
+#define DM270_GIO_GIO01_BIT             0x0002
+#define DM270_GIO_GIO02_BIT             0x0004
+#define DM270_GIO_GIO03_BIT             0x0008
+#define DM270_GIO_GIO04_BIT             0x0010
+#define DM270_GIO_GIO05_BIT             0x0020
+#define DM270_GIO_GIO06_BIT             0x0040
+#define DM270_GIO_GIO07_BIT             0x0080
+#define DM270_GIO_GIO08_BIT             0x0100
+#define DM270_GIO_GIO09_BIT             0x0200
+#define DM270_GIO_GIO10_BIT             0x0400
+#define DM270_GIO_GIO11_BIT             0x0800
+#define DM270_GIO_GIO12_BIT             0x1000
+#define DM270_GIO_GIO13_BIT             0x2000
+#define DM270_GIO_GIO14_BIT             0x4000
+#define DM270_GIO_GIO15_BIT             0x8000
+
+#define DM270_GIO_GIO16_BIT             0x0001
+#define DM270_GIO_GIO17_BIT             0x0002
+#define DM270_GIO_GIO18_BIT             0x0004
+#define DM270_GIO_GIO19_BIT             0x0008
+#define DM270_GIO_GIO20_BIT             0x0010
+#define DM270_GIO_GIO21_BIT             0x0020
+#define DM270_GIO_GIO22_BIT             0x0040
+#define DM270_GIO_GIO23_BIT             0x0080
+#define DM270_GIO_GIO24_BIT             0x0100
+#define DM270_GIO_GIO25_BIT             0x0200
+#define DM270_GIO_GIO26_BIT             0x0400
+#define DM270_GIO_GIO27_BIT             0x0800
+#define DM270_GIO_GIO28_BIT             0x1000
+#define DM270_GIO_GIO29_BIT             0x2000
+#define DM270_GIO_GIO30_BIT             0x4000
+#define DM270_GIO_GIO31_BIT             0x8000
+
+#define DM270_GIO_GIO32_BIT             0x0001
+#define DM270_GIO_GIO33_BIT             0x0002
+#define DM270_GIO_RSV_MASK              0xfffc
+
+#define DM270_GIO_NCHAT_NCH_MASK        0x000f
+#define DM270_GIO_NCHAT_RSV_MASK        0xfff0
+
+#define DM270_GIO_FSEL0_GIO08SEL_BIT    0x0001
+#define DM270_GIO_FSEL0_GIO09SEL_BIT    0x0002
+#define DM270_GIO_FSEL0_GIO10SEL_BIT    0x0004
+#define DM270_GIO_FSEL0_GIO11SEL_BIT    0x0008
+#define DM270_GIO_FSEL0_GIO12SEL_BIT    0x0010
+#define DM270_GIO_FSEL0_GIO13SEL_BIT    0x0020
+#define DM270_GIO_FSEL0_GIO14SEL_BIT    0x0040
+#define DM270_GIO_FSEL0_GIO15SEL_BIT    0x0080
+#define DM270_GIO_FSEL0_GIO16SEL_BIT    0x0100
+#define DM270_GIO_FSEL0_GIO17SEL_BIT    0x0200
+#define DM270_GIO_FSEL0_GIO18SEL_BIT    0x0400
+#define DM270_GIO_FSEL0_GIO19SEL_BIT    0x0800
+#define DM270_GIO_FSEL0_GIO20SEL_BIT    0x1000
+#define DM270_GIO_FSEL0_GIO21SEL_BIT    0x2000
+
+#define DM270_GIO_FSEL0_GIO23SEL_BIT    0x8000
+
+#define DM270_GIO_FSEL1_GIO24SEL_BIT    0x0001
+#define DM270_GIO_FSEL1_GIO25SEL_MASK   0x0006
+#define DM270_GIO_FSEL1_GIO26SEL_BIT    0x0008
+#define DM270_GIO_FSEL1_GIO27SEL_BIT    0x0010
+#define DM270_GIO_FSEL1_GIO28SEL_BIT    0x0020
+#define DM270_GIO_FSEL1_GIO29SEL_BIT    0x0040
+#define DM270_GIO_FSEL1_GIO30SEL_BIT    0x0080
+#define DM270_GIO_FSEL1_GIO31SEL_BIT    0x0100
+#define DM270_GIO_FSEL1_GIO32SEL_BIT    0x0200
+#define DM270_GIO_FSEL1_GIO33SEL_BIT    0x0400
+#define DM270_GIO_FSEL1_HDVDSEL_BIT     0x2000
+#define DM270_GIO_FSEL1_RGB666SEL_BIT   0x4000
+#define DM270_GIO_FSEL1_RSV_MASK        0x9800
+
+#define DM270_GIO_FSEL_DSP_BFSR1        DM270_GIO_FSEL0_GIO08SEL_BIT
+#define DM270_GIO_FSEL_DSP_BCLKR1       DM270_GIO_FSEL0_GIO09SEL_BIT
+#define DM270_GIO_FSEL_DSP_BDR1         DM270_GIO_FSEL0_GIO10SEL_BIT
+#define DM270_GIO_FSEL_DSP_BFSX1        DM270_GIO_FSEL0_GIO11SEL_BIT
+#define DM270_GIO_FSEL_DSP_BCLKX1       DM270_GIO_FSEL0_GIO12SEL_BIT
+#define DM270_GIO_FSEL_DSP_BDX1         DM270_GIO_FSEL0_GIO13SEL_BIT
+#define DM270_GIO_FSEL_DSP_CLKS1        DM270_GIO_FSEL0_GIO14SEL_BIT
+#define DM270_GIO_FSEL_DSP_XF           DM270_GIO_FSEL0_GIO15SEL_BIT
+#define DM270_GIO_FSEL_CLKOUT0          DM270_GIO_FSEL0_GIO16SEL_BIT
+#define DM270_GIO_FSEL_CLKOUT1          DM270_GIO_FSEL0_GIO17SEL_BIT
+#define DM270_GIO_FSEL_CLKOUT2          DM270_GIO_FSEL0_GIO18SEL_BIT
+#define DM270_GIO_FSEL_SDO1             DM270_GIO_FSEL0_GIO19SEL_BIT
+#define DM270_GIO_FSEL_SDI1             DM270_GIO_FSEL0_GIO20SEL_BIT
+#define DM270_GIO_FSEL_SCLK1            DM270_GIO_FSEL0_GIO21SEL_BIT
+#define DM270_GIO_FSEL_SDEN1            DM270_GIO_FSEL0_GIO22SEL_BIT
+#define DM270_GIO_FSEL_RXD1             DM270_GIO_FSEL0_GIO23SEL_BIT
+#define DM270_GIO_FSEL_TXD1             DM270_GIO_FSEL1_GIO24SEL_BIT
+#define DM270_GIO_FSEL_MIRQ             0x0002
+#define DM270_GIO_FSEL_MRST             0x0004
+#define DM270_GIO_FSEL_C_WEN            DM270_GIO_FSEL1_GIO26SEL_BIT
+#define DM270_GIO_FSEL_CCDC_SHUT        DM270_GIO_FSEL1_GIO27SEL_BIT
+#define DM270_GIO_FSEL_LCD_OE           DM270_GIO_FSEL1_GIO28SEL_BIT
+#define DM270_GIO_FSEL_VENC_EXT_FIELD   DM270_GIO_FSEL1_GIO28SEL_BIT
+#define DM270_GIO_FSEL_PWM0             DM270_GIO_FSEL1_GIO29SEL_BIT
+#define DM270_GIO_FSEL_PWM1             DM270_GIO_FSEL1_GIO30SEL_BIT
+#define DM270_GIO_FSEL_VENC_EXT_HD      DM270_GIO_FSEL1_GIO30SEL_BIT
+#define DM270_GIO_FSEL_SCL              DM270_GIO_FSEL1_GIO31SEL_BIT
+#define DM270_GIO_FSEL_SDA              DM270_GIO_FSEL1_GIO32SEL_BIT
+#define DM270_GIO_FSEL_EXT_LINE_ID      DM270_GIO_FSEL1_GIO33SEL_BIT
+#define DM270_GIO_FSEL_VENC_EXT_VD      DM270_GIO_FSEL1_GIO33SEL_BIT
+
+/* Timer 0 - 3 ------------------------------------------------------------- */
+
+#define DM270_TMR0_BASE                 (DM270_REG_BASE + 0x0000)
+#define DM270_TMR1_BASE                 (DM270_REG_BASE + 0x0080)
+#define DM270_TMR2_BASE                 (DM270_REG_BASE + 0x0100)
+#define DM270_TMR3_BASE                 (DM270_REG_BASE + 0x0180)
+
+#define DM270_TMR_TMMD                  0x0000
+#define DM270_TMR_TMRSV                 0x0002
+#define DM270_TMR_TMPRSCL               0x0004
+#define DM270_TMR_TMVAL                 0x0006
+#define DM270_TMR_TMTRG                 0x0008
+#define DM270_TMR_TMCNT                 0x000a
+
+#define DM270_TMR0_TMMD                 (DM270_TMR0_BASE + 0x0000)
+#define DM270_TMR0_TMRSV                (DM270_TMR0_BASE + 0x0002)
+#define DM270_TMR0_TMPRSCL              (DM270_TMR0_BASE + 0x0004)
+#define DM270_TMR0_TMVAL                (DM270_TMR0_BASE + 0x0006)
+#define DM270_TMR0_TMTRG                (DM270_TMR0_BASE + 0x0008)
+#define DM270_TMR0_TMCNT                (DM270_TMR0_BASE + 0x000a)
+
+#define DM270_TMR1_TMMD                 (DM270_TMR1_BASE + 0x0000)
+#define DM270_TMR1_TMRSV                (DM270_TMR1_BASE + 0x0002)
+#define DM270_TMR1_TMPRSCL              (DM270_TMR1_BASE + 0x0004)
+#define DM270_TMR1_TMVAL                (DM270_TMR1_BASE + 0x0006)
+#define DM270_TMR1_TMTRG                (DM270_TMR1_BASE + 0x0008)
+#define DM270_TMR1_TMCNT                (DM270_TMR1_BASE + 0x000a)
+
+#define DM270_TMR2_TMMD                 (DM270_TMR2_BASE + 0x0000)
+#define DM270_TMR2_TMRSV                (DM270_TMR2_BASE + 0x0002)
+#define DM270_TMR2_TMPRSCL              (DM270_TMR2_BASE + 0x0004)
+#define DM270_TMR2_TMVAL                (DM270_TMR2_BASE + 0x0006)
+#define DM270_TMR2_TMTRG                (DM270_TMR2_BASE + 0x0008)
+#define DM270_TMR2_TMCNT                (DM270_TMR2_BASE + 0x000a)
+
+#define DM270_TMR3_TMMD                 (DM270_TMR3_BASE + 0x0000)
+#define DM270_TMR3_TMRSV                (DM270_TMR3_BASE + 0x0002)
+#define DM270_TMR3_TMPRSCL              (DM270_TMR3_BASE + 0x0004)
+#define DM270_TMR3_TMVAL                (DM270_TMR3_BASE + 0x0006)
+#define DM270_TMR3_TMTRG                (DM270_TMR3_BASE + 0x0008)
+#define DM270_TMR3_TMCNT                (DM270_TMR3_BASE + 0x000a)
+
+#define DM270_TMR_TMMD_MODE_STOP        0x0000
+#define DM270_TMR_TMMD_MODE_ONESHOT     0x0001
+#define DM270_TMR_TMMD_MODE_FREERUN     0x0002
+#define DM270_TMR_TMMD_MODE_MASK        0x0003
+#define DM270_TMR_TMMD_TEST_MASK        0x00fc
+#define DM270_TMR_TMMD_RSV_MASK         0xff00
+
+#define DM270_TMR_TMPRSCL_PRSCL_MASK    0x03ff
+#define DM270_TMR_TMPRSCL_RSV_MASK      0xfc00
+
+#define DM270_TMR_TMTRG_TRG             0x0001
+#define DM270_TMR_TMTRG_RSV_MASK        0xfffe
+
+/* UART 0, 1 --------------------------------------------------------------- */
+
+#define DM270_UART0_BASE                (DM270_REG_BASE + 0x0300)
+#define DM270_UART1_BASE                (DM270_REG_BASE + 0x0380)
+
+#define DM270_UART_DTRR                 0x0000
+#define DM270_UART_BRSR                 0x0002
+#define DM270_UART_MSR                  0x0004
+#define DM270_UART_RFCR                 0x0006
+#define DM270_UART_TFCR                 0x0008
+#define DM270_UART_LCR                  0x000a
+#define DM270_UART_SR                   0x000c
+
+#define DM270_UART_DTRR_DTR_MASK        0x00ff
+#define DM270_UART_DTRR_PEF             0x0100
+#define DM270_UART_DTRR_ORF             0x0200
+#define DM270_UART_DTRR_FE              0x0400
+#define DM270_UART_DTRR_BF              0x0800
+#define DM270_UART_DTRR_RVF             0x1000
+#define DM270_UART_DTRR_RSV_MASK        0xe000
+
+#define DM270_UART_BRSR_VAL(baud)       ((CONFIG_ARM_CLK/(16*(baud))) - 1)
+
+#define DM270_UART_MSR_CLS              0x0001
+#define DM270_UART_MSR_SBLS             0x0004
+#define DM270_UART_MSR_PSB              0x0008
+#define DM270_UART_MSR_PEB              0x0010
+#define DM270_UART_MSR_TOIC_MASK        0x0c00
+#define DM270_UART_MSR_REIE             0x2000
+#define DM270_UART_MSR_TFTIE            0x4000
+#define DM270_UART_MSR_RFTIE            0x8000
+#define DM270_UART_MSR_RSV_MASK         0x13e2
+
+#define DM270_UART_RFCR_RWC_MASK        0x003f
+#define DM270_UART_RFCR_RTL_MASK        0x0700
+#define DM270_UART_RFCR_RDEF            0x4000
+#define DM270_UART_RFCR_RFCB            0x8000
+#define DM270_UART_RFCR_RSV_MASK        0x38c0
+
+#define DM270_UART_TFCR_TWC_MASK        0x003f
+#define DM270_UART_TFCR_TTL_MASK        0x0700
+#define DM270_UART_TFCR_TFCB            0x8000
+#define DM270_UART_TFCR_RSV_MASK        0x78c0
+
+#define DM270_UART_LCR_BOC              0x0100
+#define DM270_UART_LCR_UTST             0x4000
+#define DM270_UART_LCR_RSV_MASK         0xbeff
+
+#define DM270_UART_SR_TREF              0x0001
+#define DM270_UART_SR_TFEF              0x0002
+#define DM270_UART_SR_RFNEF             0x0004
+#define DM270_UART_SR_TOIF              0x0100
+#define DM270_UART_SR_RFER              0x0200
+#define DM270_UART_SR_TFTI              0x0400
+#define DM270_UART_SR_RFTI              0x0800
+#define DM270_UART_SR_RSV_MASK          0xf0f8
+
+#define DM270_UART_DTRR_VALID           (DM270_UART_DTRR_RVF)
+
+#define DM270_UART_MSR_8_DBITS          0x0000
+#define DM270_UART_MSR_7_DBITS          (DM270_UART_MSR_CLS)
+#define DM270_UART_MSR_1_SBITS          0x0000
+#define DM270_UART_MSR_2_SBITS          (DM270_UART_MSR_SBLS)
+#define DM270_UART_MSR_PARITY_MASK      (DM270_UART_MSR_PSB|DM270_UART_MSR_PEB)
+#define DM270_UART_MSR_NO_PARITY        0x0000
+#define DM270_UART_MSR_EVEN_PARITY      (DM270_UART_MSR_PEB)
+#define DM270_UART_MSR_ODD_PARITY       (DM270_UART_MSR_PSB|DM270_UART_MSR_PEB)
+#define DM270_UART_MSR_TIMEOUT_DISABLED 0x0000
+#define DM270_UART_MSR_TIMEOUT_3        0x0400
+#define DM270_UART_MSR_TIMEOUT_7        0x0800
+#define DM270_UART_MSR_TIMEOUT_15       0x0c00
+
+#define DM270_UART_RFCR_TRG_1           0x0000
+#define DM270_UART_RFCR_TRG_4           0x0100
+#define DM270_UART_RFCR_TRG_8           0x0200
+#define DM270_UART_RFCR_TRG_16          0x0300
+#define DM270_UART_RFCR_TRG_24          0x0400
+#define DM270_UART_RFCR_TRG_32          0x0500
+#define DM270_UART_RFCR_RESET           DM270_UART_RFCR_RDEF
+#define DM270_UART_RFCR_CLEAR           DM270_UART_RFCR_RFCB
+
+#define DM270_UART_TFCR_TRG_1           0x0000
+#define DM270_UART_TFCR_TRG_4           0x0100
+#define DM270_UART_TFCR_TRG_8           0x0200
+#define DM270_UART_TFCR_TRG_16          0x0300
+#define DM270_UART_TFCR_TRG_24          0x0400
+#define DM270_UART_TFCR_TRG_32          0x0500
+#define DM270_UART_TFCR_CLEAR           DM270_UART_TFCR_TFCB
+
+#define DM270_UART_RXFIFO_BYTESIZE      32
+#define DM270_UART_TXFIFO_BYTESIZE      32
+
+/* Instruction Cache ------------------------------------------------------- */
+
+#define DM270_ICACHE_BASE               (DM270_REG_BASE + 0x0e00)
+
+#define DM270_ICACHE_OFFSET_ICAMODE     0x0000
+
+#define DM270_ICACHE_ICAMODE            (DM270_ICACHE_BASE + DM270_ICACHE_OFFSET_ICAMODE)
+
+#define DM270_ICACHE_ICAMODE_ICAENB     0x0001
+#define DM270_ICACHE_ICAMODE_ICACLR     0x0002
+#define DM270_ICACHE_ICAMODE_REQ4W      0x0100
+#define DM270_ICACHE_ICAMODE_RSV_MASK   0xfefc
+
+#endif  /* __ASM_ARCH_HARDWARE_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/io.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/io.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,42 @@
+/*
+ * linux/include/asm-armnommu/arch-dm270/io.h
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ */
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* If we define __io then asm/io.h will take care of most of the inb & friends
+ * macros. It still leaves us some 16bit macros to deal with ourselves, though.
+ * We don't have PCI or ISA, no  __mem_pci & __mem_isa.
+ */
+
+#define PCIO_BASE 0
+#define __io(a) (PCIO_BASE + (a))
+
+/* Some compiler options will convert short loads and stores into byte loads
+ * and stores.  We don't want this to happen for IO reads and writes!
+ */
+
+static inline unsigned short __arch_getw(unsigned int addr)
+{
+  unsigned short retval;
+ __asm__ __volatile__("\tldrh %0, [%1]\n\t" : "=r"(retval) : "r"(addr));
+  return retval;
+}
+static inline void __arch_putw(unsigned short val, unsigned int addr)
+{
+ __asm__ __volatile__("\tstrh %0, [%1]\n\t": : "r"(val), "r"(addr));
+}
+
+/* Defining these two gives us ioremap for free. See asm/io.h. */
+
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/irq.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,61 @@
+/*
+ * linux/include/asm-armnommu/arch-dm270/irq.h
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/irq.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _ASM_ARCH_IRQ_H_
+#define _ASM_ARCH_IRQ_H_
+
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irqs.h>
+
+extern void dm270_init_irq(void);
+extern void dm270_mask_irq(unsigned int irq);
+extern void dm270_unmask_irq(unsigned int irq);
+extern void dm270_mask_ack_irq(unsigned int irq);
+
+#define fixup_irq(x) (x)
+
+static __inline__ void irq_init_irq(void)
+{
+	int irq;
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= dm270_mask_ack_irq;
+		irq_desc[irq].mask	= dm270_mask_irq;
+		irq_desc[irq].unmask	= dm270_unmask_irq;
+	}
+
+	dm270_init_irq();
+}
+
+#endif /* _ASM_ARCH_IRQ_H_ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/irqs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,88 @@
+/***********************************************************************
+ * include/asm-armnommu/arch-dm270/irqs.h
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/irqs.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+
+#include <linux/config.h>
+
+#define DM270_INTERRUPT_TMR0           0
+#define DM270_INTERRUPT_TMR1           1
+#define DM270_INTERRUPT_TMR2           2
+#define DM270_INTERRUPT_TMR3           3
+#define DM270_INTERRUPT_CCDVD0         4
+#define DM270_INTERRUPT_CCDVD1         5
+#define DM270_INTERRUPT_CCDVD2         6
+#define DM270_INTERRUPT_OSD            7
+#define DM270_INTERRUPT_SP0            8
+#define DM270_INTERRUPT_SP1            9
+#define DM270_INTERRUPT_EXTHOST       10
+#define DM270_INTERRUPT_DSPHINT       11
+#define DM270_INTERRUPT_UART0         12
+#define DM270_INTERRUPT_UART1         13
+#define DM270_INTERRUPT_USB           14
+#define DM270_INTERRUPT_MTC0          15
+#define DM270_INTERRUPT_MTC1          16
+#define DM270_INTERRUPT_MMCSD0        17
+#define DM270_INTERRUPT_MMCSD1        18
+#define DM270_INTERRUPT_RSVINT0       19
+#define DM270_INTERRUPT_EXT1          20
+#define DM270_INTERRUPT_EXT2          21
+#define DM270_INTERRUPT_EXT3          22
+#define DM270_INTERRUPT_EXT4          23
+#define DM270_INTERRUPT_EXT5          24
+#define DM270_INTERRUPT_EXT6          25
+#define DM270_INTERRUPT_EXT7          26
+#define DM270_INTERRUPT_EXT8          27
+#define DM270_INTERRUPT_EXT9          28
+#define DM270_INTERRUPT_EXT10         29
+#define DM270_INTERRUPT_EXT11         30
+#define DM270_INTERRUPT_EXT12         31
+#define DM270_INTERRUPT_EXT13         32
+#define DM270_INTERRUPT_EXT14         33
+#define DM270_INTERRUPT_EXT15         34
+#define DM270_INTERRUPT_PREV          35
+#define DM270_INTERRUPT_WDT           36
+#define DM270_INTERRUPT_I2C           37
+#define DM270_INTERRUPT_CLKC          38
+/*#define DM270_INTERRUPT_RSVINT1       39*/
+
+#define IRQ_TIMER                     (DM270_INTERRUPT_TMR0)
+#define NR_IRQS                       (DM270_INTERRUPT_CLKC + 1)
+
+/* flags for request_irq().  IRQ_FLG_STD is apparently a uClinux-ism,
+ * so I'll keep it around even though it is just a mapping for the
+ * real SA_INTERRUPT. -- skj 
+ */
+
+#define IRQ_FLG_STD                   (SA_INTERRUPT)
+
+#endif /* __ASM_ARCH_IRQS_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/keyboard.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/keyboard.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/keyboard.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ *  linux/include/asm-armnommu/arch-dm270/keyboard.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef __ASM_ARM_ARCH_DM270_KEYBOARD_H
+#define __ASM_ARM_ARCH_DM270_KEYBOARD_H
+
+/*
+ * Required by drivers/char/keyboard.c.
+ */
+
+#define kbd_setkeycode(sc,kc) (-EINVAL)
+#define kbd_getkeycode(sc) (-EINVAL)
+#define kbd_translate(sc,kcp,rm) ({ *(kcp) = (sc); 1; })
+#define kbd_unexpected_up(kc) (0200)
+#define kbd_leds(leds)
+#define kbd_init_hw()
+#define kbd_enable_irq() 
+#define kbd_disable_irq()
+
+#endif /* __ASM_ARM_ARCH_DM270_KEYBOARD_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/memory.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,59 @@
+/*
+ * linux/include/asm-armnommu/arch-dm270/memory.h
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <linux/config.h>
+
+#define __virt_to_bus(x) ((unsigned long) (x))
+#define __bus_to_virt(x) ((void *) (x))
+#define __virt_to_phys(x) ((unsigned long) (x))
+#define __phys_to_virt(x) ((void *) (x))
+
+#define END_MEM		(DRAM_BASE + DRAM_SIZE)
+
+/* These are used in the fault handling code (even for nommu) and various other
+ * macros.
+ */
+
+#define TASK_SIZE	(0x01a00000UL)
+#define TASK_SIZE_26	(TASK_SIZE)
+
+/* The alignment requirement of the memory management system
+ * this is ~(1 << (PAGE_OFFSET+(MAX_ORDER-1)))-1.
+ */
+
+#define PHYS_OFFSET_MASK 0x001fffff
+
+/* The start of physical memory.  This is the first SDRAM address.
+ * This value is used in the arch-specific bootup code like setup_arch &
+ * bootmem_init.
+ *
+ * NOTE the alignment requirement of the memory management system
+ * this is given by PHYS_OFFSET_MASK.
+ *
+ * Boot from flash -  kernel .text and .rodata are in rom/flash and only
+ * .data lies in SDRAM.  So the mem_map tables can begin near the
+ * beginning of physical SDRAM.  The value _end_kernel provides
+ * SDRAM address after the memory used by the kernel .data section.
+ * There can still be a significant loss of memory due to the alignment
+ * requirement.
+ */
+
+#define PHYS_OFFSET \
+  ((((unsigned long)DRAM_BASE) + PHYS_OFFSET_MASK) & ~PHYS_OFFSET_MASK)
+
+#define UNALIGNED_PHYS_OFFSET ((unsigned long)&_end_kernel)
+
+#define LOST_MEMORY_SIZE (PHYS_OFFSET - UNALIGNED_PHYS_OFFSET)
+
+/* PAGE_OFFSET -- the first address of the first page of memory. For archs with
+ * no MMU this corresponds to the first free page in physical memory (aligned
+ * on a page boundary).
+ */
+
+#define PAGE_OFFSET (PHYS_OFFSET)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/mmu.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/mmu.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/mmu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/mmu.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,23 @@
+/*
+ * linux/include/asm-arm/arch-dm270/mmu.h
+ *
+ * Copyright (c) 1996 Russell King.
+ *
+ * Changelog:
+ *  22-11-1996	RMK	Created
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((unsigned long) (vpage))
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((void *) (ppage))
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(vpage) ((unsigned long) (vpage))
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(ppage) ((void *) (ppage))
+
+#define __flush_entry_to_
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/param.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/param.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,8 @@
+/* include/asm-armnommu/arch-dm270/param.h */
+
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/processor.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/processor.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/processor.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-armnommu/arch-dm270/processor.h
+ * Derived from linux/include/asm-armnommu/arch-c5471/mmu.h
+ *
+ */
+
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+#define EISA_bus 0
+#define EISA_bus__is_a_macro
+#define MCA_bus 0
+#define MCA_bus__is_a_macro
+
+#define TASK_SIZE (0x01a00000UL)
+
+#endif /* __ASM_ARCH_PROCESSOR_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/serial.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/serial.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/serial.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,177 @@
+/***********************************************************************
+ * linux/include/asm-arm/arch-dm270/serial.h
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/serial.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <linux/config.h>
+#include <linux/termios.h>
+#include <linux/tqueue.h>
+#include <linux/circ_buf.h>
+#include <linux/wait.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/irqs.h>
+
+#define BASE_BAUD     38400
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+/* This defines the initializer for a struct serial_state describing the
+ * TI TMS320DM270 serial port 0.
+ */
+
+#define DM270_SERIAL_PORT0_DEFN \
+  {  \
+    magic:          0, \
+    port:           0, \
+    flags:          STD_COM_FLAGS, \
+    xmit_fifo_size: DM270_UART_TXFIFO_BYTESIZE, \
+    baud_base:      BASE_BAUD, \
+    irq:            DM270_INTERRUPT_UART0, \
+    type:           PORT_UNKNOWN, \
+    line:           0, \
+    iomem_base:     DM270_UART0_BASE, \
+    io_type:        SERIAL_IO_MEM \
+  }
+
+/* This defines the initializer for a struct serial_state describing the
+ * TI TMS320DM270 serial port 1.
+ */
+
+#define DM270_SERIAL_PORT1_DEFN \
+  {  \
+    magic:          0, \
+    port:           0, \
+    flags:          STD_COM_FLAGS, \
+    xmit_fifo_size: DM270_UART_TXFIFO_BYTESIZE, \
+    baud_base:      BASE_BAUD, \
+    irq:            DM270_INTERRUPT_UART1, \
+    type:           PORT_UNKNOWN, \
+    line:           1, \
+    iomem_base:     DM270_UART1_BASE, \
+    io_type:        SERIAL_IO_MEM \
+  }
+
+/* There will always be two serial ports. */
+
+#define RS_TABLE_SIZE 2
+
+/* STD_SERIAL_PORT_DEFNS (plus EXTRA_SERIAL_PORT_DEFNS, see
+ * include/asm/serial.h) define an array of struct serial_state
+ * instance initializers.  These array initilizers are used
+ * in drivers/char/serial_dm270.c to describe the serial
+ * ports that will be supported.
+ */
+
+# define STD_SERIAL_PORT_DEFNS \
+  DM270_SERIAL_PORT0_DEFN,  /* ttyS0 */ \
+  DM270_SERIAL_PORT1_DEFN   /* ttyS1 */
+
+#define EXTRA_SERIAL_PORT_DEFNS
+
+/* Events are used to schedule things to happen at timer-interrupt
+ * time, instead of at rs interrupt time.
+ */
+
+#define RS_EVENT_WRITE_WAKEUP	0
+
+#define CONFIGURED_SERIAL_PORT(info) ((info)->state)
+
+#define SERIAL_MAGIC 0x5301
+#define SSTATE_MAGIC 0x5302
+
+/* This is the internal structure for each serial port's state.
+ *
+ * For definitions of the flags field, see tty.h
+ */
+
+struct dm270_serial_state_s
+{
+	int			magic;
+	int			port;
+	int			baud_base;
+	int			irq;
+	int			flags;
+	int			type;
+	int			line;
+	int			xmit_fifo_size;
+	int			custom_divisor;
+	int			count;
+	int			io_type;
+	unsigned long		iomem_base;
+	unsigned short		close_delay;
+	unsigned short		closing_wait;	/* time to wait before closing */
+	struct async_icount	icount;	
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+	struct dm270_async_s	*info;
+};
+typedef struct dm270_serial_state_s dm270_serial_state_t;
+
+struct dm270_async_s
+{
+	int			magic;
+	int			port;
+	int			flags;
+	int			xmit_fifo_size;
+	dm270_serial_state_t	*state;
+	struct tty_struct	*tty;
+	unsigned short		closing_wait;
+	int			line;
+	unsigned short		read_status_mask;
+	unsigned short		ignore_status_mask;
+	int			timeout;
+	int			baud;
+	int			x_char;		/* xon/xoff character */
+	int			close_delay;
+	unsigned short		msr;		/* Cached UART Mode Setup Register */
+	int			blocked_open;	/* # of blocked opens */
+	unsigned long		event;
+	unsigned long		last_active;
+	long			session;	/* Session of opening process */
+	long			pgrp;		/* pgrp of opening process */
+	struct circ_buf		xmit;
+	unsigned long		iomem_base;
+	struct tq_struct	tqueue;
+#ifdef DECLARE_WAITQUEUE
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+	wait_queue_head_t	delta_msr_wait;
+#else	
+	struct wait_queue	*open_wait;
+	struct wait_queue	*close_wait;
+	struct wait_queue	*delta_msr_wait;
+#endif	
+	struct dm270_async_s	*next_port;	/* For the linked list */
+	struct dm270_async_s	*prev_port;
+};
+typedef struct dm270_async_s dm270_async_t;
+
+#endif /* __ASM_ARCH_SERIAL_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/shmparam.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/shmparam.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/shmparam.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-dm270/shmparam.h
+ *
+ * Copyright (c) 1996 Russell King.
+ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/system.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/system.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,14 @@
+/*
+ * linux/include/asm-armnommu/arch-dm270/system.h
+ */
+
+static inline void arch_idle(void)
+{
+  while (!current->need_resched && !hlt_counter);
+}
+
+extern inline void arch_reset(char mode)
+{
+	/* Jump into ROM at 0x00100000 */
+	cpu_reset(FLASH_MEM_BASE);
+}
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/time.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/time.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,53 @@
+/***********************************************************************
+ * linux/include/asm-arm/arch-dm270/time.h
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/time.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#ifndef __ASM_ARCH_TIME_H__
+#define __ASM_ARCH_TIME_H__
+
+/* The actual timer initialization is performed in the file
+ * arch/armnommu/mach-dm270/time.c.  This inline function is
+ * just a thin candy coating to get to that function.
+ */
+
+extern void dm270_setup_timer(struct irqaction *timer_irq);
+
+/* setup_timer() is "called" from arch/armnommu/kernel/time.c
+ * In the context where setup_timer runs (in this context, timer_irq
+ * is declared as a static intialized variable.  Provided that
+ * the asm/arch/time.h is included AFTER this declaration, the
+ * following should be quite happy:
+ */
+
+void __inline__ setup_timer(void)
+{
+  dm270_setup_timer(&timer_irq);
+}
+
+#endif /* __ASM_ARCH_TIME_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/timex.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,42 @@
+/* include/asm-armnommu/arch-dm270/timex.h:
+ *
+ * System clock frequency.
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/timex.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+/* CLOCK_TICK_RATE -- frequency fed to the timer. In our case, 87.75MHz/351.
+ * Used to compute LATCH. LATCH is the number of clock ticks per timer interrupt.
+ * (See linux/timex.h, armnommu/mach-dm270/time.c).
+ */
+
+#define CLOCK_TICK_RATE	   250000
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/uncompress.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/uncompress.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/uncompress.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,122 @@
+/*
+ * include/asm/arch/uncompress.h:
+ *         Optional routines to aid in debugging the decompression phase
+ *         of kernel boot.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/* This is used by arch/armnommu/boot/compressed/misc.c to write progress info
+ * out the serial port so that the user can see debug messages up to the point
+ * where the kernel is decompressed. The STANDALONE_DEBUG macro chooses between
+ * this and the standard printf. Punt.
+ * --gmcnutt
+ */
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_DEBUG_DM270_UART1
+# define DM270_UART_BASE	DM270_UART1_BASE
+# define DM270_CLKC_UART_SHIFT	1
+#else
+# define DM270_UART_BASE	DM270_UART0_BASE
+# define DM270_CLKC_UART_SHIFT	0
+#endif
+
+static inline void
+putc(char c)
+{
+    while (!(__arch_readw(DM270_UART_BASE+DM270_UART_SR) & DM270_UART_SR_TREF));
+
+    __arch_writew(c, DM270_UART_BASE+DM270_UART_DTRR);
+}
+
+/* Hardware-specific routine to put a string to the debug UART, converting
+ * "\n" to "\n\r" on the way */
+
+static void
+puts(const char *s)
+{
+	while (*s) {
+		putc(*s);
+		if (*s == '\n')
+			putc('\r');
+		s++;
+	}
+}
+
+/* If we need to do some setup prior to decompression (like initializing the
+ * UART if we want to use puts() above) then we define it here. Punt.
+ */
+
+static inline void
+arch_decomp_setup(void)
+{
+	/* Disable clock to UART. */
+	__arch_writew((__arch_readw(DM270_CLKC_MOD2) &
+			~(DM270_CLKC_MOD2_CUAT << DM270_CLKC_UART_SHIFT)),
+			DM270_CLKC_MOD2);
+
+	/* Select CLK_ARM as UART clock source */
+	__arch_writew((__arch_readw(DM270_CLKC_CLKC) &
+			~(DM270_CLKC_CLKC_CUAS << DM270_CLKC_UART_SHIFT)),
+			DM270_CLKC_CLKC);
+
+	/* Enable clock to UART. */
+	__arch_writew((__arch_readw(DM270_CLKC_MOD2) |
+			(DM270_CLKC_MOD2_CUAT << DM270_CLKC_UART_SHIFT)),
+			DM270_CLKC_MOD2);
+
+#ifdef CONFIG_DEBUG_DM270_UART1
+	/* Configure GIO23 & GIO24 as RXD1 & TXD1 respectively */
+	__arch_writew((__arch_readw(DM270_GIO_FSEL0) | DM270_GIO_FSEL_RXD1),
+			DM270_GIO_FSEL0);
+	__arch_writew((__arch_readw(DM270_GIO_FSEL1) | DM270_GIO_FSEL_TXD1),
+			DM270_GIO_FSEL1);
+#endif
+
+	/* 8-1-no parity. Enable receive interrupts. */
+	__arch_writew((DM270_UART_MSR_8_DBITS | DM270_UART_MSR_1_SBITS |
+			DM270_UART_MSR_NO_PARITY | DM270_UART_MSR_TIMEOUT_DISABLED |
+			DM270_UART_MSR_REIE | DM270_UART_MSR_RFTIE),
+			DM270_UART_BASE+DM270_UART_MSR);
+
+	/* Set bit rate. */
+	__arch_writew(DM270_UART_BRSR_VAL(_DEFAULT_BAUD),
+			DM270_UART_BASE+DM270_UART_BRSR);
+
+	/* Clear & enable FIFO. */
+	/* Set interrupt trigger level to be 1 byte. */
+	__arch_writew((DM270_UART_TFCR_TRG_1 | DM270_UART_TFCR_CLEAR),
+			DM270_UART_BASE+DM270_UART_TFCR);
+	__arch_writew((DM270_UART_RFCR_TRG_1 | DM270_UART_RFCR_RESET |
+			DM270_UART_RFCR_CLEAR), DM270_UART_BASE+DM270_UART_RFCR);
+}
+
+/* Not sure what this is for. Probably an optional watchdog to check if the
+ * decompress got hung so we can warn the user. Punt.
+ */
+#define arch_decomp_wdog()
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/vmalloc.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,36 @@
+/*
+ * linux/include/asm-arm/arch-dm270/vmalloc.h
+ *
+ *   Derived from asm/arch-armnommu/arch-c5471/vmalloc.h
+ *
+ *   Copyright (C) 2004 InnoMedia Pte Ltd. All rights reserved.
+ *   cheetim_loh@innomedia.com.sg  <www.innomedia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/* Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-dm270/wdt_ioctl.h linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/wdt_ioctl.h
--- linux-2.4.29/include/asm-armnommu/arch-dm270/wdt_ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dm270/wdt_ioctl.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,48 @@
+/*
+ *	Generic watchdog defines. Derived from..
+ *
+ * Berkshire PC Watchdog Defines
+ * by Ken Hollis <khollis@bitgate.com>
+ *
+ */
+
+#ifndef _LINUX_WATCHDOG_H
+#define _LINUX_WATCHDOG_H
+
+#include <linux/ioctl.h>
+
+#define	WATCHDOG_IOCTL_BASE	'W'
+
+struct watchdog_info {
+	__u32 options;		/* Options the card/driver supports */
+	__u32 firmware_version;	/* Firmware version of the card */
+	__u8  identity[32];	/* Identity of the board */
+};
+
+#define	WDIOC_GETSUPPORT	_IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info)
+#define	WDIOC_GETSTATUS		_IOR(WATCHDOG_IOCTL_BASE, 1, int)
+#define	WDIOC_GETBOOTSTATUS	_IOR(WATCHDOG_IOCTL_BASE, 2, int)
+#define	WDIOC_GETTEMP		_IOR(WATCHDOG_IOCTL_BASE, 3, int)
+#define	WDIOC_SETOPTIONS	_IOR(WATCHDOG_IOCTL_BASE, 4, int)
+#define	WDIOC_KEEPALIVE		_IOR(WATCHDOG_IOCTL_BASE, 5, int)
+#define	WDIOC_SETTIMEOUT        _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
+#define	WDIOC_GETTIMEOUT        _IOR(WATCHDOG_IOCTL_BASE, 7, int)
+
+#define	WDIOF_UNKNOWN		-1	/* Unknown flag error */
+#define	WDIOS_UNKNOWN		-1	/* Unknown status error */
+
+#define	WDIOF_OVERHEAT		0x0001	/* Reset due to CPU overheat */
+#define	WDIOF_FANFAULT		0x0002	/* Fan failed */
+#define	WDIOF_EXTERN1		0x0004	/* External relay 1 */
+#define	WDIOF_EXTERN2		0x0008	/* External relay 2 */
+#define	WDIOF_POWERUNDER	0x0010	/* Power bad/power fault */
+#define	WDIOF_CARDRESET		0x0020	/* Card previously reset the CPU */
+#define WDIOF_POWEROVER		0x0040	/* Power over voltage */
+#define WDIOF_SETTIMEOUT	0x0080  /* Set timeout (in seconds) */
+#define	WDIOF_KEEPALIVEPING	0x8000	/* Keep alive ping reply */
+
+#define	WDIOS_DISABLECARD	0x0001	/* Turn off the watchdog timer */
+#define	WDIOS_ENABLECARD	0x0002	/* Turn on the watchdog timer */
+#define	WDIOS_TEMPPANIC		0x0004	/* Kernel panic on temperature trip */
+
+#endif  /* ifndef _LINUX_WATCHDOG_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/a.out.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/a.out.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/a.out.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * uclinux/include/asm-armnommu/arch-atmel/a.out.h
+ *
+ */
+#ifndef __ASM_ARCH_A_OUT_H
+#define __ASM_ARCH_A_OUT_H
+
+#ifdef __KERNEL__
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,63 @@
+/*
+ * asm/arch-armnommu/arch-dsc21/dma.h:
+ *         dsc21-specific macros for DMA support.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+/*
+ * MAX_DMA_ADDRESS -- max address we can program into the DMA address registers?
+ * Not sure. Various drivers use this value as a test before setting up a DMA.
+ * Also, the macros in linux/bootmem.h use this value as a goal for many of the
+ * bootmem allocations.
+ * Open questions:
+ * a) the DMA address register is only 26 bits -- does this limit us to this
+ *    section of memory, or can we only DMA in certain size chunks?
+ * b) can the ARM processor even directly program the DMA?
+ * I'm going to go out on a limb and assume that the DMA range is the first
+ * addresseable 26 bits.
+ * --gmcnutt
+ */
+#define MAX_DMA_ADDRESS		0x02000000
+
+/*
+ * MAX_DMA_CHANNELS -- # of DMA control register sets we possess. For the dsc21
+ * we have one that can run in either direction and between two different
+ * destinations.
+ * --gmcnutt
+ */
+#define MAX_DMA_CHANNELS        1
+
+/*
+ * arch_dma_init -- called by arch/armnommu/kernel/dma.c init_dma.
+ * Don't know what's needed here (if anything).
+ * --gmcnutt
+ */
+#define arch_dma_init(dma_chan)
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,149 @@
+/*
+ * linux/include/asm-arm/arch-trio/hardware.h
+ *
+ * Copyright (C) 1996 Russell King.
+ *
+ * This file contains the hardware definitions of the TI DSC21 series machines
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/* ARM clock rate (MHz) */
+#define DSC21_CLOCK_RATE     37125000
+
+/* external bus */
+#define DSC21_EXTBUS_RESET    0x00030a00
+#define DSC21_EXTBUS_MODE     0x00030a04
+#define DSC21_EXTBUS_INTEN    0x00030a08
+
+/* uarts (note that the register fields aren't needed by the standard linux
+   serial driver -- we only use them for our initial debugging console) */
+#define DSC21_UART0       0x00030380
+#define DSC21_UART0_DTRR  0x00030380
+#define DSC21_UART0_BRSR  0x00030382
+#define DSC21_UART0_MSR   0x00030384
+#define DSC21_UART0_RFCR  0x00030386
+#define DSC21_UART0_TFCR  0x00030388
+#define DSC21_UART0_LCR	  0x0003038a
+#define DSC21_UART0_SR 	  0x0003038c
+
+#define DSC21_UART1       0x00030400
+#define DSC21_UART1_DTRR  0x00030400
+#define DSC21_UART1_BRSR  0x00030402
+#define DSC21_UART1_MSR   0x00030404
+#define DSC21_UART1_RFCR  0x00030406
+#define DSC21_UART1_TFCR  0x00030408
+#define DSC21_UART1_LCR	  0x0003040a
+#define DSC21_UART1_SR 	  0x0003040c
+
+/* timers */
+#define DSC21_TIMER0_MODE    0x00030000
+#define DSC21_TIMER0_SEL     0x00030002
+#define DSC21_TIMER0_SCAL    0x00030004
+#define DSC21_TIMER0_DIV     0x00030006
+#define DSC21_TIMER0_TRG     0x00030008
+#define DSC21_TIMER0_CNT     0x0003000a
+
+#define DSC21_TIMER1_MODE    0x00030080
+#define DSC21_TIMER1_SEL     0x00030082
+#define DSC21_TIMER1_SCAL    0x00030084
+#define DSC21_TIMER1_DIV     0x00030086
+#define DSC21_TIMER1_TRG     0x00030088
+#define DSC21_TIMER1_CNT     0x0003008a
+
+#define DSC21_TIMER2_MODE    0x00030100
+#define DSC21_TIMER2_SEL     0x00030102
+#define DSC21_TIMER2_SCAL    0x00030104
+#define DSC21_TIMER2_DIV     0x00030106
+#define DSC21_TIMER2_TRG     0x00030108
+#define DSC21_TIMER2_CNT     0x0003010a
+
+#define DSC21_TIMER3_MODE    0x00030180
+#define DSC21_TIMER3_SEL     0x00030182
+#define DSC21_TIMER3_SCAL    0x00030184
+#define DSC21_TIMER3_DIV     0x00030186
+#define DSC21_TIMER3_TRG     0x00030188
+#define DSC21_TIMER3_CNT     0x0003018a
+
+/* interrupt */
+#define DSC21_FIQ_STATUS     0x00030580
+#define DSC21_IRQ0_STATUS    0x00030582
+#define DSC21_IRQ1_STATUS    0x00030584
+#define DSC21_FIQ_ENABLE     0x000305a0
+#define DSC21_IRQ0_ENABLE    0x000305a2
+#define DSC21_IRQ1_ENABLE    0x000305a4
+
+
+/*
+ * HARD_RESET_NOW -- used in blkmem.c. Should call arch_hard_reset(), but I 
+ * don't appear to have one ;).
+ * --gmcnutt
+ */
+#define HARD_RESET_NOW()
+
+
+/* reference */
+/////////////////////////////////////////////////
+//
+//	register and SDRAM map
+//
+//  (c) VSA/TITRDC   06/1999
+//
+/////////////////////////////////////////////////
+
+// memory mapped registers
+#define TIMER0_REGISTER_BASE    0x00030000		// timer0
+#define TIMER1_REGISTER_BASE	0x00030080		// timer1
+#define TIMER2_REGISTER_BASE	0x00030100		// timer2
+#define TIMER3_REGISTER_BASE	0x00030180		// timer3
+#define SERIAL0_REGISTER_BASE	0x00030200		// serial0
+#define SERIAL1_REGISTER_BASE	0x00030280		// serial1
+#define WDT_REGISTER_BASE	0x00030300		// watch dog timer
+#define UART0_REGISTER_BASE	0x00030380		// UART0
+#define UART1_REGISTER_BASE	0x00030400		// UART0
+#define USB_REGISTER_BASE	0x00030480		// USB
+#define IRDA_REGISTER_BASE	0x00030500		// IrDA
+#define INTCTRL_REGISTER_BASE	0x00030580		// INTC
+#define GIO_REGISTER_BASE	0x00030600		// GIO
+#define OSD_REGISTER_BASE	0x00030680		// OSD
+#define DSPC_REGISTER_BASE	0x00030700		// DSP controller
+#define CCDC_REGISTER_BASE	0x00030780		// CCD controller
+#define PREVIEW_REGISTER_BASE	0x00030800		// preview engine
+#define BURSTC_REGISTER_BASE	0x00030880		// burst mode compression
+#define VIDEOENC_REGISTER_BASE	0x00030900		// NTSC/PAL encoder
+#define SDRAMC_REGISTER_BASE	0x00030980		// SDRAM controller
+#define EXBC_REGISTER_BASE	0x00030A00		// external bus controller
+#define CLOCKC_REGISTER_BASE	0x00030A80		// clock controller
+#define BUSC_REGISTER_BASE	0x00030B00		// bus controller
+#define DMAIF_REGISTER_BASE	0x00030B80		// external bus DMA I/F
+
+// DSPRAM
+#define DSPRAM_BASE         0x00100000  // DSPRAM base address
+
+
+// SDRAM address (real byte address)
+#define SDRAM_BASE          0x08000000  // sdram base address
+#define SDRAM_SIZE          0x01000000  // hard-code 16MB for now
+#define SDRAM_PREVIEW       0x00000000  // output from preview engine
+#define SDRAM_RAWDATA       0x00100000  // output from CCDC
+#define SDRAM_WORK1         0x00100000  // WORK area #1 for burst-capture & decoded data
+#define SDRAM_WORK2         0x00500000  // WORK area #2 for burst-capture & decoded data
+#define SDRAM_ENCODED1      0x00900000  // work area #1 for encoded data
+#define SDRAM_ENCODED2      0x00B00000  // work area #2 for encoded data
+#define SDRAM_BURSTDATA     0x00B00000  // BURST-compressed data start address
+#define SDRAM_BURSTDATA_END 0x00EFFFFF  // BURST-compressed data end address
+#define SDRAM_OSD           0x00F00000  // OSD bitmap start address
+
+// CARD map (tentative)
+#define CARD_BASE           0x04000000		// CFC card base address
+#define CARD_ENCODED_START	0x00000800		// encoded image start address
+#define CARD_ENCODED_SLOT_SIZE	0x00044000		// encoded image slot size
+
+// IRQ defines  (Offset listed in register document is in words, so double offset)
+#define IRQ0_STATUS (INTCTRL_REGISTER_BASE + 0x02)
+#define IRQ1_STATUS (INTCTRL_REGISTER_BASE + 0x04)
+#define IRQ0_ENABLE (INTCTRL_REGISTER_BASE + 0x22)
+#define IRQ1_ENABLE (INTCTRL_REGISTER_BASE + 0x24)
+
+#endif  /* _ASM_ARCH_HARDWARE_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/ide.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/ide.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/ide.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,45 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/ide.h
+ *
+ * Copyright (c) 1998 Hugo Fiennes & Nicolas Pitre
+ *
+ * 18-aug-2000: Cleanup by Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
+ *              Get rid of the special ide_init_hwif_ports() functions
+ *              and make a generalised function that can be used by all
+ *              architectures.
+ */
+
+#include <linux/config.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+
+/*
+ * Set up a hw structure for a specified data port, control port and IRQ.
+ * This should follow whatever the default interface uses.
+ */
+static __inline__ void
+ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int *irq)
+{
+#ifdef CONFIG_REVISIT
+#error Not sure what to do for ide_init_hwif_ports
+#endif
+}
+
+
+
+
+/*
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ */
+static __inline__ void
+ide_init_default_hwifs(void)
+{
+#ifdef CONFIG_REVISIT
+#error Not sure what to do for ide_init_default_hwifs
+#endif
+}
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/io.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ * linux/include/asm-armnommu/arch-dsc21/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ *  02-19-2001  gjm     Leveraged for armnommu/dsc21
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ * --gmcnutt
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * If we define __io then asm/io.h will take care of most of the inb & friends
+ * macros. It still leaves us some 16bit macros to deal with ourselves, though.
+ * We don't have PCI or ISA on the dsc21 so I dropped __mem_pci & __mem_isa.
+ * --gmcnutt
+ */
+#define PCIO_BASE 0
+#define __io(a) (PCIO_BASE + (a))
+#define __arch_getw(a) (*(volatile unsigned short *)(a))
+#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
+
+/*
+ * Defining these two gives us ioremap for free. See asm/io.h.
+ * --gmcnutt
+ */
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,66 @@
+/*
+ * irq.h:
+ *         dsc21-specific IRQ setup.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_ARCH_IRQ_H__
+#define __ASM_ARCH_IRQ_H__
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irqs.h>
+
+#define fixup_irq(x) (x)
+
+extern void dsc21_mask_irq(unsigned int irq);
+extern void dsc21_unmask_irq(unsigned int irq);
+extern void dsc21_mask_ack_irq(unsigned int irq);
+
+static __inline__ void irq_init_irq(void)
+{
+	int irq;
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= dsc21_mask_ack_irq;
+		irq_desc[irq].mask	= dsc21_mask_irq;
+		irq_desc[irq].unmask	= dsc21_unmask_irq;
+	}
+
+	/* clear all status */
+	outw(0xffff, DSC21_IRQ0_STATUS);
+	outw(0xffff, DSC21_IRQ1_STATUS);
+    
+	/* disable all */
+	outw(0, DSC21_FIQ_ENABLE);
+	outw(0, DSC21_IRQ0_ENABLE);
+	outw(0, DSC21_IRQ1_ENABLE);
+}
+
+#endif /* __ASM_ARCH_IRQ_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/irqs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,75 @@
+/*
+ * irqs.h:
+ *         IRQ numbers for the dsc21.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+
+/* irq #s */
+#define DSC21_IRQ_EXT0    0x00
+#define DSC21_IRQ_EXT1    0x01
+#define DSC21_IRQ_EXT2    0x02
+#define DSC21_IRQ_EXT3    0x03
+#define DSC21_IRQ_EXT4    0x04
+#define DSC21_IRQ_EXT5    0x05
+#define DSC21_IRQ_EXT6    0x06
+#define DSC21_IRQ_EXT7    0x07
+#define DSC21_IRQ_DMA     0x08
+#define DSC21_IRQ_FLASH   0x09
+#define DSC21_IRQ_IRDA_RX 0x0a
+#define DSC21_IRQ_IRDA_TX 0x0b
+#define DSC21_IRQ_TIMER0  0x10
+#define DSC21_IRQ_TIMER1  0x11
+#define DSC21_IRQ_TIMER2  0x12
+#define DSC21_IRQ_TIMER3  0x13
+#define DSC21_IRQ_CCDVD0  0x14
+#define DSC21_IRQ_CCDVD1  0x15
+#define DSC21_IRQ_CCDVD2  0x16
+#define DSC21_IRQ_ENCVD   0x17
+#define DSC21_IRQ_SERIAL0 0x18
+#define DSC21_IRQ_SERIAL1 0x19
+#define DSC21_IRQ_DSP     0x1a
+#define DSC21_IRQ_UART0   0x1b
+#define DSC21_IRQ_UART1   0x1c
+#define DSC21_IRQ_USB     0x1d
+#define DSC21_IRQ_BURST   0x1e
+#define DSC21_IRQ_CARD    0x1f
+#define DSC21_IRQ_EXB     0x1f /* conflict? */
+
+#define NR_IRQS           (DSC21_IRQ_EXB + 1)
+
+/* alias */
+#define IRQ_TIMER         DSC21_IRQ_TIMER0
+
+/* flags for request_irq() */
+#define IRQ_FLG_LOCK      (0x0001)  /* handler is not replaceable   */
+#define IRQ_FLG_REPLACE   (0x0002)  /* replace existing handler     */
+#define IRQ_FLG_FAST      (0x0004)
+#define IRQ_FLG_SLOW      (0x0008)
+#define IRQ_FLG_STD       (0x8000)  /* internally used              */
+
+#endif /* __ASM_ARCH_IRQS_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/keyboard.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/keyboard.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/keyboard.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ *  linux/include/asm-arm/arch-ti926/keyboard.h
+ *
+ *  Copyright (C) 2000 RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Keyboard driver definitions for ARM
+ */
+#ifndef __ASM_ARM_ARCH_TI925_KEYBOARD_H
+#define __ASM_ARM_ARCH_TI925_KEYBOARD_H
+
+#if 0
+#define kbd_request_region
+#define kbd_write_command
+#define kbd_write_output
+#define kbd_read_status
+#define kbd_read_input
+#define aux_request_irq
+#define aux_free_irq
+#endif
+
+/*
+ * Required by drivers/char/keyboard.c. I took these from arch-arc.
+ * --gmcnutt
+ */
+#define kbd_setkeycode(sc,kc) (-EINVAL)
+#define kbd_getkeycode(sc) (-EINVAL)
+#define kbd_translate(sc,kcp,rm) ({ *(kcp) = (sc); 1; })
+#define kbd_unexpected_up(kc) (0200)
+#define kbd_leds(leds)
+#define kbd_init_hw()
+#define kbd_enable_irq() /* what irq? ;) --gmcnutt */
+#define kbd_disable_irq()
+
+
+#endif /* __ASM_ARM_ARCH_TI925_KEYBOARD_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,57 @@
+/*
+ * linux/include/asm-armnommu/arch-dsc21/memory.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * Copyright (c) 2001 RidgeRun <www.ridgerun.com>
+ *
+ * 02/19/2001  Gordon McNutt  Leveraged for the dsc21.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+
+/*
+ * These are used in the fault handling code (even for nommu) and various other
+ * macros. The current value comes from Steve Johnson's 2.0.38 uClinux port for
+ * the dsc21.
+ * --gmcnutt
+ */
+#define TASK_SIZE	(0x01a00000UL)
+#define TASK_SIZE_26	TASK_SIZE
+
+
+/*
+ * The start of physical memory. For the dsc21 this is the first SDRAM address.
+ * This value is used in the arch-specific bootup code like setup_arch &
+ * bootmem_init. By default we assume that we have one block of contiguous
+ * memory (a node) that starts here and runs MEM_SIZE long (see below). By 
+ * default the ARM bootup code sets MEM_SIZE to be 16MB  which is just right for
+ * us (see arch/armnommu/kernel/setup.c).
+ *
+ * NOTE:   I don't really use the start of SDRAM. Instead I reserve some pages
+ *         of SDRAM for some of the kernel sections (like .data & .bss). The
+ *         linker script has been modified to mark the first unreservered page
+ *         as _end_kernel (see arch/armnommu/vmlinux-armv.lds.in).
+ *         
+ * --gmcnutt
+ */
+extern int _end_kernel;
+#define PHYS_OFFSET	((unsigned long) &_end_kernel)
+//0x08000000
+
+/*
+ * PAGE_OFFSET -- the first address of the first page of memory. For archs with
+ * no MMU this corresponds to the first free page in physical memory (aligned
+ * on a page boundary).
+ * --gmcnutt
+ */
+#define PAGE_OFFSET  PHYS_OFFSET
+
+
+#define __virt_to_phys(vpage) ((unsigned long) (vpage))
+#define __phys_to_virt(ppage) ((void *) (ppage))
+#define __virt_to_bus(vpage) ((unsigned long) (vpage))
+#define __bus_to_virt(ppage) ((void *) (ppage))
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/param.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/pcmcia.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/pcmcia.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/pcmcia.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/pcmcia.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,3 @@
+#ifdef CONFIG_REVISIT
+#error Do we need PCMCIA support?
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/processor.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/processor.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/processor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,15 @@
+/*
+ * uclinux/include/asm-armnommu/arch-atmel/mmu.h
+ *
+ */
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+#define EISA_bus 0
+#define EISA_bus__is_a_macro
+#define MCA_bus 0
+#define MCA_bus__is_a_macro
+
+#define TASK_SIZE (0x01a00000UL)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/serial.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/serial.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/serial.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,135 @@
+/*
+ *  linux/include/asm-arm/arch-arc/serial.h
+ *
+ *  Copyright (C) 1996 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Changelog:
+ *   15-10-1996	RMK	Created
+ *   04-04-1998	PJB	Merged `arc' and `a5k' architectures
+ *   02-28-2001 GJM     Modified for dsc21
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/irqs.h>
+
+/* setup */
+#define BASE_BAUD      (DSC21_CLOCK_RATE / 16)
+#define STD_COM_FLAGS  (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+#define RS_TABLE_SIZE  2
+#define STD_SERIAL_PORT_DEFNS \
+	{  \
+	magic: 0, \
+        baud_base: BASE_BAUD, \
+	port: 0, \
+	irq: DSC21_IRQ_UART0, \
+	flags: STD_COM_FLAGS, \
+	type: PORT_UNKNOWN, \
+	iomem_base: (u8*)DSC21_UART0, \
+	iomem_reg_shift: 1, \
+	io_type: SERIAL_IO_MEM \
+	},	/* ttyS0 */ \
+	{  \
+	magic: 0, \
+        baud_base: BASE_BAUD, \
+	port: 0, \
+	irq: DSC21_IRQ_UART1, \
+	flags: STD_COM_FLAGS, \
+	type: PORT_UNKNOWN, \
+	iomem_base: (u8*)DSC21_UART1, \
+	iomem_reg_shift: 1, \
+	io_type: SERIAL_IO_MEM \
+	}	/* ttyS1 */ 
+#define EXTRA_SERIAL_PORT_DEFNS
+
+
+/* registers */
+#define UART_DTRR  0  /* Data Transmission/Reception Register */
+#define UART_BRSR  1  /* Bit Rate Set Register */
+#define UART_MSR   2  /* Mode Set Register */
+#define UART_RFCR  3  /* Reception FIFO Control Register */
+#define UART_TFCR  4  /* Transmission FIFO Control Register */
+#define UART_LCR   5  /* Line Control Register */
+#define UART_SR    6  /* Status Register */
+
+/* bitmasks */
+#define UART_MSR_CLS    0x0001    // Character length select (1=7bit, 0=8bit)
+#define UART_MSR_RSVD0  0x0002    // Reserved
+#define UART_MSR_SBLD   0x0004    // Stop bit length select (1=2bits, 0=1bit)
+#define UART_MSR_PSB 	0x0008	  // Parity select bit (1=odd, 0=even)
+#define UART_MSR_PEB    0x0010	  // Parity enable bit (1=enable, 0=disable)
+#define UART_MSR_TFTIE  0x4000    // Transmission FIFO trigger interrupt enable
+#define UART_MSR_RFTIE  0x8000    // Reception FIFO trigger interrupt enable
+#define UART_MSR_INTS   0xfc00    // All interrupt bits
+#define UART_MSR_MODE_BITS 0x001f // data length, stop & parity
+
+#define UART_SR_TREF    0x0001    // Transmission register empty flag
+#define UART_SR_TFEF    0x0002    // Transmission FIFO empty flag
+#define UART_SR_RFNEF   0x0004    // Reception FIFO not empty flag
+#define UART_SR_RSVD0   0x00f8    // Reserved
+#define UART_SR_TOIF    0x0100    // Time out interrupt flag
+#define UART_SR_RFER    0x0200    // Reception FIFO error flag
+#define UART_SR_TFTI    0x0400    // Transmission FIFO trigger indicator
+#define UART_SR_RFTI    0x0800    // Reception FIFO trigger indicator
+#define UART_SR_RSVD1   0xf000    // Reserved
+
+#define UART_LCR_BOC    0x0100    // Break output control (1=send break)
+
+#define UART_FCR_FTL1   0x0000    /* FIFO trigger level 1 byte */
+#define UART_FCR_FTL4   0x0100    /* FIFO trigger level 4 bytes */
+#define UART_FCR_FTL8   0x0200    /* FIFO trigger level 8 bytes */
+#define UART_FCR_FTL16  0x0300    /* FIFO trigger level 16 bytes */
+#define UART_FCR_FTL24  0x0400    /* FIFO trigger level 24 bytes */
+#define UART_FCR_FTL32  0x0500    /* FIFO trigger level 32 bytes */
+
+struct dsc21_async_struct {
+	int			magic;
+	unsigned long		port;
+	int			flags;
+	int			xmit_fifo_size;
+	struct serial_state	*state;
+	struct tty_struct 	*tty;
+	int			timeout;
+	int			quot;
+	int			x_char;	/* xon/xoff character */
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	u16			MSR; 	/* Interrupt Enable Register */
+	u16			LCR; 	/* Line control register */
+	u16                     RFCR;
+	u16                     TFCR;
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+ 	struct circ_buf		xmit;
+ 	spinlock_t		xmit_lock;
+	u8			*iomem_base;
+	u16			iomem_reg_shift;
+	int			io_type;
+	struct tq_struct	tqueue;
+#ifdef DECLARE_WAITQUEUE
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+	wait_queue_head_t	delta_msr_wait;
+#else	
+	struct wait_queue	*open_wait;
+	struct wait_queue	*close_wait;
+	struct wait_queue	*delta_msr_wait;
+#endif	
+	struct dsc21_async_struct *next_port;
+	struct dsc21_async_struct *prev_port;
+	
+};
+
+
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/shmparam.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/shmparam.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/shmparam.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-a5k/shmparam.h
+ *
+ * Copyright (c) 1996 Russell King.
+ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/system.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,18 @@
+/*
+ * linux/include/asm-armnommu/arch-dsc21/system.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * Copyright (c) 2001 RidgeRun, Inc (http://www.ridgerun.org)
+ *
+ */
+
+static inline void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter);
+}
+
+extern inline void arch_reset(char mode)
+{
+	/* REVISIT --gmcnutt */
+}
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/time.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/time.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,64 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/time.h
+ *
+ * Copyright (C) 1998 Deborah Wallach.
+ * Twiddles  (C) 1999 	Hugo Fiennes <hugo@empeg.com>
+ * 
+ * 2000/03/29 (C) Nicolas Pitre <nico@cam.org>
+ *	Rewritten: big cleanup, much simpler, better HZ acuracy.
+ *
+ * 2001/02/20 (C) RidgeRun, Inc (http://www.ridgerun.com)
+ *      Leveraged for the dsc21
+ */
+#ifndef __ASM_ARCH_TIME_H__
+#define __ASM_ARCH_TIME_H__
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+extern struct irqaction timer_irq;
+
+extern unsigned long dsc21_gettimeoffset(void);
+extern void dsc21_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+void __inline__ setup_timer (void)
+{
+	/* disable */
+	outw(0, DSC21_TIMER0_MODE);
+	outw(0, DSC21_TIMER1_MODE);
+	outw(0, DSC21_TIMER2_MODE);
+	outw(0, DSC21_TIMER3_MODE);
+
+	/*
+	 * System clock formula:
+	 *         freq = clock / (div * scale)
+	 * Where:
+	 *         clock = 27MHz
+	 *         div   = 27,000
+	 *         scale = 10
+	 *
+	 * Which gives us 100Hz, as desired.
+	 */
+
+	/* 27MHz clock (not ARM clock) */
+	outw(1, DSC21_TIMER0_SEL);
+	
+	/* prescale 10 */
+	outw(9, DSC21_TIMER0_SCAL);
+	
+	/* div 27000 */
+	outw(26999, DSC21_TIMER0_DIV);
+	
+	/* periodic */
+	outw(2, DSC21_TIMER0_MODE);
+
+
+	gettimeoffset = dsc21_gettimeoffset;	
+	timer_irq.handler = dsc21_timer_interrupt;
+	setup_arm_irq(IRQ_TIMER, &timer_irq);
+    
+}
+
+
+#endif /* __ASM_ARCH_TIME_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ * timex.h:
+ *         System clock frequency.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+/*
+ * CLOCK_TICK_RATE -- frequency fed to the timer. In our case, 27MHz. Used to
+ * compute LATCH. LATCH is the number of clock ticks per timer interrupt.
+ * (See linux/timex.h, armnommu/mach-dsc21/time.c).
+ */
+#define CLOCK_TICK_RATE	   27000000
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/uncompress.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/uncompress.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/uncompress.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ * asm/arch/uncompress.c:
+ *         Optional routines to aid in debugging the decompression phase
+ *         of kernel boot.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * This is used by arch/armnommu/boot/compressed/misc.c to write progress info
+ * out the serial port so that the user can see debug messages up to the point
+ * where the kernel is decompressed. The STANDALONE_DEBUG macro chooses between
+ * this and the standard printf. Punt.
+ * --gmcnutt
+ */
+#define puts(s)
+
+/*
+ * Not sure what this is for. Probably an optional watchdog to check if the
+ * decompress got hung so we can warn the user. Punt.
+ */
+#define arch_decomp_wdog()
+
+/*
+ * If we need to do some setup prior to decompression (like initializing the
+ * UART if we want to use puts() above) then we define it here. Punt.
+ */
+#define arch_decomp_setup()
diff -urN linux-2.4.29/include/asm-armnommu/arch-dsc21/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-dsc21/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-dsc21/vmalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ *  linux/include/asm-arm/arch-dsc21/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/a.out.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/a.out.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/a.out.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * include/asm/arch/a.out.h
+ *
+ */
+#ifndef __ASM_ARCH_A_OUT_H
+#define __ASM_ARCH_A_OUT_H
+
+#ifdef __KERNEL__
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/bootstd.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/bootstd.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/bootstd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/bootstd.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,119 @@
+/* bootstd.h:  Bootloader system call interface
+ *
+ * (c) 1999, Rt-Control, Inc.
+ *
+ *  ARM7TDMI support by O.Zhadan,  2001
+ *  ( used undefined instruction trap )
+ */
+
+#ifndef __BOOTSTD_H__
+#define __BOOTSTD_H__
+
+#define NR_BSC 22            	/* last used bootloader system call */
+
+#define __BN_reset        	0  /* reset and start the bootloader */
+#define __BN_test         	1  /* tests the system call interface */
+#define __BN_exec         	2  /* executes a bootloader image */
+#define __BN_exit         	3  /* terminates a bootloader image */
+#define __BN_program      	4  /* program FLASH from a chain */
+#define __BN_erase        	5  /* erase sector(s) of FLASH */
+#define __BN_open         	6
+#define __BN_write        	7
+#define __BN_read         	8
+#define __BN_close        	9
+#define __BN_mmap         	10 /* map a file descriptor into memory */
+#define __BN_munmap       	11 /* remove a file to memory mapping */
+#define __BN_gethwaddr    	12 /* get the hardware address of my interfaces */
+#define __BN_getserialnum 	13 /* get the serial number of this board */
+#define __BN_getbenv      	14 /* get a bootloader envvar */
+#define __BN_setbenv      	15 /* get a bootloader envvar */
+#define __BN_setpmask     	16 /* set the protection mask */
+#define __BN_readbenv      	17 /* read environment variables */
+#define __BN_flash_chattr_range	18
+#define __BN_flash_erase_range	19
+#define __BN_flash_write_range	20
+#define __BN_ramload            21 /* load kernel into RAM and exec */
+
+/* Calling conventions compatible to (uC)linux
+ * We use simmilar macros to call into the bootloader as for uClinux
+ */
+
+#define __bsc_return(type, res) \
+do { \
+   if ((unsigned int)(res) >= (unsigned int)(-64)) { \
+      /* let errno be a function, preserve res in %r0 */ \
+      int __err = -(res); \
+      errno = __err; \
+      res = -1; \
+   } \
+   return (type)(res); \
+} while (0)
+
+#define _bsc0(type,name) \
+type name(void) \
+{ \
+   register unsigned int __res __asm__ ("%sl") = __BN_##name; \
+   __asm__ __volatile__ (".word 0xe65a4f10; mov sl, r0" \
+                         : "=g" (__res) \
+                         : "0"  (__res) \
+                         : "%r0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc1(type,name,atype,a) \
+type name(atype a) \
+{ \
+   register unsigned int __res __asm__ ("%sl") = __BN_##name; \
+   __asm__ __volatile__ (".word 0xe65a4f10; mov sl, r0" \
+                         : "=g" (__res) \
+                         : "0"  (__res) \
+                         : "%r0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc2(type,name,atype,a,btype,b) \
+type name(atype a, btype b) \
+{ \
+   register unsigned int __res __asm__ ("%sl") = __BN_##name; \
+   __asm__ __volatile__ (".word 0xe65a4f10; mov sl, r0" \
+                         : "=g" (__res) \
+                         : "0"  (__res) \
+                         : "%r0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc3(type,name,atype,a,btype,b,ctype,c) \
+type name(atype a, btype b, ctype c) \
+{ \
+   register unsigned int __res __asm__ ("%sl") = __BN_##name; \
+   __asm__ __volatile__ (".word 0xe65a4f10; mov sl, r0" \
+                         : "=g" (__res) \
+                         : "0"  (__res) \
+                         : "%r0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
+type name(atype a, btype b, ctype c, dtype d) \
+{ \
+   register unsigned int __res __asm__ ("%sl") = __BN_##name; \
+   __asm__ __volatile__ (".word 0xe65a4f10; mov sl, r0" \
+                         : "=g" (__res) \
+                         : "0"  (__res) \
+                         : "%r0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
+type name(atype a, btype b, ctype c, dtype d, etype e) \
+{ \
+   register unsigned int __e   __asm__ ("%r4") = e; \
+   register unsigned int __res __asm__ ("%sl") = __BN_##name; \
+   __asm__ __volatile__ (".word 0xe65A4F10; mov sl, r0" \
+                         : "=g" (__res) \
+                         : "0"  (__res) \
+                         : "%r0"); \
+   __bsc_return(type,__res); \
+}
+
+#endif /* __BOOTSTD_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * asm/arch-armnommu/arch-s3c4/dma.h:
+ * OZH, 2001
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_ADDRESS		0x03000000
+#define MAX_DMA_CHANNELS        2
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,527 @@
+/*
+ * uclinux/include/asm-armnommu/arch-evS3C4530HEI/hardware.h
+ *
+ * OZH, 2001 Oleksandr Zhadan.
+ *
+ * This file includes the hardware definitions of EV-S3C4530-HEI board.
+ */
+ 
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <linux/config.h>
+#ifndef __ASSEMBLER__
+typedef unsigned long u_32;
+#define ARM_CLK ((u_32)(CONFIG_ARM_CLK))	/*(50000000))*/
+#else
+#define ARM_CLK CONFIG_ARM_CLK
+#endif
+
+#define MCLK2 (ARM_CLK/2)
+#define Vol32	*(volatile unsigned int *)
+#define Vol16	*(volatile unsigned short *)
+#define Vol08	*(volatile unsigned char *)
+
+#define REG_WRITE(addr,data)	(Vol32(addr)=(data))
+#define REG_READ(addr)		(Vol32(addr))
+
+
+#ifndef __ASSEMBLER__
+
+/**************************************** RAM definitions */
+#define MAPTOPHYS(a)      ((unsigned long)a)
+#define KERNTOPHYS(a)     ((unsigned long)(&a))
+#define GET_MEMORY_END(p) ((p->u1.s.page_size) * (p->u1.s.nr_pages))
+#define PARAMS_BASE       0x7000
+#define HARD_RESET_NOW()  { arch_hard_reset(); }
+#endif
+
+#define IO_BASE		0x00000000
+#define EIO_BASE	0x03600000		/* External I/O banks base address */
+
+#define SRB_BASE 	0x03FF0000
+
+#define BDMA_OWNER 	0x80000000
+#define NON_CACHEABLE	0x04000000
+
+
+/**************************************** System Manager */
+#define SYSCFG 		(SRB_BASE+0x0000)
+#define CLKCON		(SRB_BASE+0x3000)
+#define EXTACON0	(SRB_BASE+0x3008)
+#define EXTACON1	(SRB_BASE+0x300C)
+#define EXTDBWTH	(SRB_BASE+0x300C)
+#define ROMCON0		(SRB_BASE+0x3014)
+#define ROMCON1		(SRB_BASE+0x3018)
+#define ROMCON2		(SRB_BASE+0x301C)
+#define ROMCON3		(SRB_BASE+0x3020)
+#define ROMCON4		(SRB_BASE+0x3024)
+#define ROMCON5		(SRB_BASE+0x3028)
+#define DRAMCON0	(SRB_BASE+0x302C)
+#define DRAMCON1	(SRB_BASE+0x3030)
+#define DRAMCON2	(SRB_BASE+0x3034)
+#define DRAMCON4	(SRB_BASE+0x3038)
+#define REFEXTCON	(SRB_BASE+0x303C)
+
+/**************************************** Interrupt Controller */
+#define INTMOD		(SRB_BASE+0x4000)
+#define INTPND		(SRB_BASE+0x4004)
+#define INTMSK		(SRB_BASE+0x4008)
+#define INTPRI0		(SRB_BASE+0x400C)
+#define INTPRI1		(SRB_BASE+0x4010)
+#define INTPRI2		(SRB_BASE+0x4014)
+#define INTPRI3		(SRB_BASE+0x4018)
+#define INTPRI4		(SRB_BASE+0x401C)
+#define INTPRI5		(SRB_BASE+0x4020)
+#define INTOFFSET	(SRB_BASE+0x4024)
+#define INTOSET_FIQ	(SRB_BASE+0x4030)
+#define INTOSET_IRQ	(SRB_BASE+0x4034)
+
+/**************************************** I/O Ports */
+#define IOPMOD		(SRB_BASE+0x5000)
+#define IOPCON0		(SRB_BASE+0x5004)
+#define IOPDATA		(SRB_BASE+0x5008)
+#define IOPCON1		(SRB_BASE+0x500C)
+
+/**************************************** Timers */
+#define TMOD		(SRB_BASE+0x6000)
+#define TDATA0		(SRB_BASE+0x6004)
+#define TDATA1		(SRB_BASE+0x6008)
+#define TCNT0		(SRB_BASE+0x600C)
+#define TCNT1		(SRB_BASE+0x600C)
+
+/**************************************** HDLC Channel A */
+#define HMODE_A		(SRB_BASE+0x7000)
+#define HCON_A		(SRB_BASE+0x7004)
+#define HSTAT_A		(SRB_BASE+0x7008)
+#define HINTEN_A	(SRB_BASE+0x700C)
+#define HTXFIFOC_A	(SRB_BASE+0x7010)
+#define HTXFIFOT_A	(SRB_BASE+0x7014)
+#define HRXFIFO_A	(SRB_BASE+0x7018)
+#define HBRGTC_A	(SRB_BASE+0x701C)
+#define HTPRMB_A	(SRB_BASE+0x7020)
+#define HSAR0_A		(SRB_BASE+0x7024)
+#define HSAR1_A		(SRB_BASE+0x7028)
+#define HSAR2_A		(SRB_BASE+0x702C)
+#define HSAR3_A		(SRB_BASE+0x7030)
+#define HMASK_A		(SRB_BASE+0x7034)
+#define HDMATxPTR_A	(SRB_BASE+0x7038)
+#define HDMARxPTR_A	(SRB_BASE+0x703C)
+#define HMFLR_A		(SRB_BASE+0x7040)
+#define HRBSR_A		(SRB_BASE+0x7044)
+#define HSYNC_A		(SRB_BASE+0x7048)
+#define TCON_A		(SRB_BASE+0x704C)
+
+/**************************************** HDLC Channel B */
+#define HMODE_B		(SRB_BASE+0x8000)
+#define HCON_B		(SRB_BASE+0x8004)
+#define HSTAT_B		(SRB_BASE+0x8008)
+#define HINTEN_B	(SRB_BASE+0x800C)
+#define HTXFIFOC_B	(SRB_BASE+0x8010)
+#define HTXFIFOT_B	(SRB_BASE+0x8014)
+#define HRXFIFO_B	(SRB_BASE+0x8018)
+#define HBRGTC_B	(SRB_BASE+0x801C)
+#define HTPRMB_B	(SRB_BASE+0x8020)
+#define HSAR0_B		(SRB_BASE+0x8024)
+#define HSAR1_B		(SRB_BASE+0x8028)
+#define HSAR2_B		(SRB_BASE+0x802C)
+#define HSAR3_B		(SRB_BASE+0x8030)
+#define HMASK_B		(SRB_BASE+0x8034)
+#define HDMATxPTR_B	(SRB_BASE+0x8038)
+#define HDMARxPTR_B	(SRB_BASE+0x803C)
+#define HMFLR_B		(SRB_BASE+0x8040)
+#define HRBSR_B		(SRB_BASE+0x8044)
+#define HSYNC_B		(SRB_BASE+0x8048)
+#define TCON_B		(SRB_BASE+0x804C)
+
+/**************************************** Ethernet (BDMA) */
+#define BDMATXCON	(SRB_BASE+0x9000)
+#define BDMARXCON	(SRB_BASE+0x9004)
+#define BDMATXPTR	(SRB_BASE+0x9008)
+#define BDMARXPTR	(SRB_BASE+0x900C)
+#define BDMARXLSZ	(SRB_BASE+0x9010)
+#define BDMASTAT	(SRB_BASE+0x9014)
+#define ETXSTAT		(SRB_BASE+0x9040) 	/* Transmit control frame status */
+#define CAM		(SRB_BASE+0x9100)
+#define BDMATXBUF	(SRB_BASE+0x9200)
+#define BDMARXBUF	(SRB_BASE+0x9800)
+
+/**************************************** Ethernet (MAC) */
+#define MACON		(SRB_BASE+0xA000)  /* MAC control */
+#define CAMCON		(SRB_BASE+0xA004)  /* CAM control */
+#define MATXCON		(SRB_BASE+0xA008)  /* Transmit control */
+#define MATXSTAT	(SRB_BASE+0xA00C)  /* Transmit status */
+#define MARXCON		(SRB_BASE+0xA010)  /* Receive control */
+#define MARXSTAT	(SRB_BASE+0xA014)  /* Receive status */
+#define STADATA		(SRB_BASE+0xA018)  /* Station management data */
+#define STACON		(SRB_BASE+0xA01C)  /* Station management control and address */
+#define CAMEN		(SRB_BASE+0xA028)  /* CAM enable */
+#define EMISSCNT	(SRB_BASE+0xA03C)  /* Missed error count */
+#define EPZCNT		(SRB_BASE+0xA040)  /* Pause count */
+#define ERMPZCNT	(SRB_BASE+0xA044)  /* Remote pause count */
+
+
+/**************************************** Ethernet BDMATXCON register map */
+#define BTxEn           0x00004000         /* BDMA tx enable */
+#define BTxRs           0x00008000         /* BDMA tx reset */
+
+/**************************************** Ethernet BDMARXCON register map */
+#define BRxEn           0x00004000         /* BDMA rx enable */
+#define BRxRs           0x00008000         /* BDMA rx reset */
+
+/**************************************** Ethernet BDMASTAT register map */
+#define BRxRDF          0x00000001         /* BDMA received data frame  */
+#define BRxNL           0x00000002         /* BDMA rx null list */
+#define BRxNO           0x00000004         /* BDMA rx not owner of current frame */
+#define BRxMSO          0x00000008         /* BDMA rx max size over */
+#define BRxEmpty        0x00000010         /* BDMA rx buffer empty */
+#define BRxEarly        0x00000020         /* BDMA rx early length notify */
+/* reserved */
+#define BRxFRF          0x00000080         /* BDMA rx early length notify */
+
+#define BRxNFR_mask     0x0000ff00         /* BDMA no. frames in rx buf (mask) */
+#define BRxNFR_shift             8         /* (shift) */
+
+#define BTxCCP          0x00010000         /* BDMA tx control packet */
+#define BTxNL           0x00020000         /* BDMA tx null list */
+#define BTxNO           0x00040000         /* BDMA tx not owner of current frame */
+/* reserved */
+#define BTxEmpty        0x00100000         /* BDMA tx buffer empty */
+
+
+/**************************************** Ethernet tx frame descriptor bits */
+#define TxCollCnt_mask  0x000f             /* # tx collisions */
+#define TxCollCnt_shift      0
+#define TxExColl        0x0010             /* 16 collisions occured */
+#define TxDefer         0x0020             /* transmission defered */
+#define TxPaused        0x0040             /* transmission paused */
+#define TxInt           0x0080             /* pkt tx caused an interrupt */
+#define TxUnder         0x0100             /* tx underrun */
+#define TxMaxDefer      0x0200             /* tx defered for max_defer */
+#define TxNCarr         0x0400             /* carrier sense not detected */
+#define TxSQErr         0x0800             /* SQE error */
+#define TxLateColl      0x1000             /* tx coll after 512 bit times */
+#define TxPar           0x2000             /* tx FIFO parity error */
+#define TxComp          0x4000             /* tx complete or discarded */
+#define TxHalted        0x8000             /* tx halted OR error */
+
+
+/**************************************** Ethernet MACON register map */
+#define SwRESET         0x00000040         /* MAC reset */
+
+/**************************************** Ethernet CAMCON register map */
+#define StationAcc      0x00000001         /* Accept Station/Unicast addresses */
+#define GroupAcc        0x00000002         /* Accept Group/Multicast addresses */
+#define BroadAcc        0x00000004         /* Accept the Broadcast addresses */
+#define NegCAM          0x00000008         /* Reject, rather than accept
+					    * CAM-recognized entries */
+#define CompEn          0x00000010         /* Enable compare mode */
+
+#define HW_MAX_ADDRS    21                 /* CAM consists of 32 words */
+
+
+/**************************************** GDMA Channel 0 */
+#define GDMACON0	(SRB_BASE+0xB000)
+#define GDMASRC0	(SRB_BASE+0xB004)
+#define GDMADST0	(SRB_BASE+0xB008)
+#define GDMACNT0	(SRB_BASE+0xB00C)
+
+/**************************************** GDMA Channel 1 */
+#define GDMACON1	(SRB_BASE+0xC000)
+#define GDMASRC1	(SRB_BASE+0xC004)
+#define GDMADST1	(SRB_BASE+0xC008)
+#define GDMACNT1	(SRB_BASE+0xC00C)
+
+/**************************************** UART Channel 0 */
+#define UCON0		(SRB_BASE+0xD000)
+#define USTAT0		(SRB_BASE+0xD004)
+#define UINTEN0		(SRB_BASE+0xD008)
+#define UTXBUF0		(SRB_BASE+0xD00C)
+#define URXBUF0		(SRB_BASE+0xD010)
+#define UBRDIV0		(SRB_BASE+0xD014)
+#define UCC1_0		(SRB_BASE+0xD018)
+#define UCC2_0		(SRB_BASE+0xD01C)
+
+/**************************************** UART Channel 1 */
+#define UCON1		(SRB_BASE+0xE000)
+#define USTAT1		(SRB_BASE+0xE004)
+#define UINTEN1		(SRB_BASE+0xE008)
+#define UTXBUF1		(SRB_BASE+0xE00C)
+#define URXBUF1		(SRB_BASE+0xE010)
+#define UBRDIV1		(SRB_BASE+0xE014)
+#define UCC1_1		(SRB_BASE+0xE018)
+#define UCC2_1		(SRB_BASE+0xE01C)
+
+/**************************************** I2C Bus */
+#include <asm/arch/i2c.h>
+
+
+/* FIXME USART0_BASE and USART1_BASE should be set in .config */
+
+   #define USART0_BASE 	UCON0
+   #define USART1_BASE 	UCON1
+
+
+#ifndef __ASSEMBLER__
+/****************************************  S3C4530 Samsung  UART registers */
+struct s3c4530_usart_regs {
+  volatile u_32 cr;		/* control		*/
+  volatile u_32 csr;		/* channel status	*/
+  volatile u_32 ier;		/* interrupt enable	*/
+  volatile u_32 thr;		/* tramsmit holding	*/
+  volatile u_32 rhr;		/* receive holding	*/
+  volatile u_32 brgr;		/* baud rate generator	*/
+  volatile u_32 ucc1;		/* control character 1	*/
+  volatile u_32 ucc2;		/* control character 2	*/
+};
+#endif
+
+#define TX_FIFO_DEPTH 32
+#define RX_FIFO_DEPTH 32
+
+/****************************************  UART control register */
+#define	U_DISABLE_TMODE	0xFFFFFFFC
+#define	U_IRQ_TMODE	0x00000001
+#define	U_DMA0_TMODE	0x00000002
+#define	U_DMA1_TMODE	0x00000003
+#define	U_TMODE		0x00000003
+
+#define	U_DISABLE_RMODE	0xFFFFFFF3
+#define	U_IRQ_RMODE	0x00000004
+#define	U_DMA0_RMODE	0x00000008
+#define	U_DMA1_RMODE	0x0000000C
+#define	U_RMODE		0x0000000C
+
+#define	U_SBR		0x00000010
+#define	U_UCLK		0x00000020
+#define	U_ABRD		0x00000040
+#define	U_LOOPB		0x00000080
+
+#define	U_NO_PMD	0xFFFFF8FF
+#define	U_ODD_PMD	0x00000400
+#define	U_EVEN_PMD	0x00000500
+#define	U_FC1_PMD	0x00000600
+#define	U_FC0_PMD	0x00000700
+#define	U_PMD		0x00000700
+
+#define	U_STB		0x00000800
+
+#define	U_WL5		0xFFFFCFFF
+#define	U_WL6		0x00001000
+#define	U_WL7		0x00002000
+#define	U_WL8		0x00003000
+#define	U_WL		0x00003000
+
+#define	U_IR		0x00004000
+#define	U_TFEN		0x00010000
+#define	U_RFEN		0x00020000
+#define	U_TFRST		0x00040000
+#define	U_RFRST		0x00080000
+
+#define	U_TFTL30	0xFFCFFFFF
+#define	U_TFTL24	0x00100000
+#define	U_TFTL16	0x00200000
+#define	U_TFTL8		0x00300000
+#define	U_TFTL		0x00300000
+
+#define	U_RFTL1		0xFF3FFFFF
+#define	U_RFTL8		0x00400000
+#define	U_RFTL18	0x00800000
+#define	U_RFTL28	0x00C00000
+#define	U_RFTL		0x00C00000
+
+#define	U_DTR		0x01000000
+#define	U_RTS		0x02000000
+#define	U_HFEN		0x10000000
+#define	U_SFEN		0x20000000
+
+/****************************************  UART status register */
+#define	U_TFFUL		(1<<20)
+#define	U_TFEMT		(1<<19)
+#define	U_THE		(1<<18)
+#define	U_TC		(1<<17)
+#define	U_E_CTS		(1<<16)
+#define	U_CTS		(1<<15)
+#define	U_DSR		(1<<14)
+#define	U_E_RxTO	(1<<12)
+#define	U_RIDLE		(1<<11
+#define	U_RFOV		(1<<10)
+#define	U_RFFUL		(1<<9)
+#define	U_RFEMT		(1<<8)
+#define	U_RFREA		(1<<7)
+#define	U_DCD		(1<<6)
+#define	U_CCD		(1<<5)
+#define	U_OER		(1<<4)
+#define	U_PER		(1<<3)
+#define	U_FER		(1<<2)
+#define	U_BSD		(1<<1)
+#define	U_RDV		(1)
+
+/****************************************  UART Interrupt Enable register */
+#define	U_THEIE		(1<<18)
+#define	U_E_CTSIE	(1<<16)
+#define	U_E_RxTOIE	(1<<12)
+#define	U_OVFFIE	(1<<10)
+#define	U_RFREAIE	(1<<7)
+#define	U_DCDLIE	(1<<6)
+#define	U_CCDIE		(1<<5)
+#define	U_OVEIE		(1<<4)
+#define	U_PERIE		(1<<3)
+#define	U_FERIE		(1<<2)
+#define	U_BKDIE		(1<<1)
+#define	U_RDRIE		(1)
+
+#define US_ALL_INTS (U_THEIE|U_E_CTSIE|U_E_RxTOIE|U_OVFFIE|U_RFREAIE|U_DCDLIE|U_CCDIE|U_OERIE|U_PERIE|U_FERIE|U_BSDIE|U_RDVIE)
+
+/****************************************  IO -- IO controller */
+#define PIO_BASE	IOPMOD
+
+
+/**************** Bit definitions for IOPMOD, IOPDATA, IOPCON1 */
+#define DTR1_PIN	(1<<25)
+#define TxD1_PIN	(1<<24)
+#define DSR1_PIN	(1<<23)
+#define RxD1_PIN	(1<<22)
+#define DTR0_PIN	(1<<21)
+#define TxD0_PIN	(1<<20)
+#define DSR0_PIN	(1<<19)
+#define RxD0_PIN	(1<<18)
+#define BZ1_PIN		(1<<17)
+#define TOUT1_PIN	(1<<17)
+#define TOUT0_PIN	(1<<16)
+#define nXDACK1_PIN	(1<<15)
+#define nXDACK0_PIN	(1<<14)
+#define nXDREQ1_PIN	(1<<13)
+#define nXDREQ0_PIN	(1<<12)
+#define xINTREQ3_PIN	(1<<11)
+#define xINTREQ2_PIN	(1<<10)
+#define xINTREQ1_PIN	(1<<9)
+#define xINTREQ0_PIN	(1<<8)
+#define RTS1_PIN	(1<<7)
+#define CTS1_PIN	(1<<6)
+#define DCD1_PIN	(1<<5)
+#define RTS0_PIN	(1<<4)
+#define CTS0_PIN	(1<<3)
+#define DCD0_PIN	(1<<2)
+#define LED_PIN		(1<<1)
+
+/*************************** Bit definitions for IOPCON0 */
+
+#define xINTREQ0_MODE	(3)	/* 0 = level, 1 = rising, 2 = falling, 3 = both */
+#define xINTREQ0_FILTER	(1<<2)	/* assert irq if state holds for 3 clocks */
+#define xINTREQ0_ACT_HI	(1<<3)	/* 1 = irq active high */
+#define xINTREQ0_ENABLE	(1<<4)	/* 1 = enable irq0 on port 8 */
+
+#define xINTREQ1_MODE	(3<<5)
+#define xINTREQ1_FILTER	(1<<7)
+#define xINTREQ1_ACT_HI	(1<<8)
+#define xINTREQ1_ENABLE	(1<<9)	/* 1 = enable irq1 on port 9 */
+
+#define xINTREQ2_MODE	(3<<10)
+#define xINTREQ2_FILTER	(1<<12)
+#define xINTREQ2_ACT_HI	(1<<13)
+#define xINTREQ2_ENABLE	(1<<14)	/* 1 = enable irq2 on port 10 */
+
+#define xINTREQ3_MODE	(3<<15)
+#define xINTREQ3_FILTER	(1<<17)
+#define xINTREQ3_ACT_HI	(1<<18)
+#define xINTREQ3_ENABLE	(1<<19)	/* 1 = enable irq3 on port 11 */
+
+#define nXDREQ0_ACT_HI	(1<<20)	/* 1 = active high */
+#define nXDREQ0_FILTER	(1<<21)	/* 1 = 3 clock filtering */
+#define nXDREQ0_ENABLE	(1<<22)	/* 1 = enable drq0 on port 12 */
+
+#define nXDREQ1_ACT_HI	(1<<23)
+#define nXDREQ1_FILTER	(1<<24)
+#define nXDREQ1_ENABLE	(1<<25)	/* 1 = enable drq1 on port 13 */
+
+#define nXDACK0_ACT_HI	(1<<26)
+#define nXDACK0_ENABLE	(1<<27)	/* 1 = enable dack0 on port 14 */
+
+#define nXDACK1_ACT_HI	(1<<28)
+#define nXDACK1_ENABLE	(1<<29)	/* 1 = enable dack1 on port 15 */
+
+
+
+/****************************************  Timer */
+
+#define TIMER_BASE 	TMOD
+
+/* The  S3C4530A has 2 internel 32-bit timers, TC0 and TC1.
+ * One of these must be used to drive the kernel's internal
+ * timer (the thing that updates jiffies).  Pick a timer channel
+ * here.  */
+ 
+#define	KERNEL_TIMER	0
+
+/*  TC mode register */
+#define TCLR1		(1<<5)
+#define TDM1		(1<<4)
+#define TE1		(1<<3)
+#define TCLR0		(1<<2)
+#define TDM0		(1<<1)
+#define TE0		(1)
+
+#ifndef __ASSEMBLER__
+struct s3c4530_timer
+{
+  unsigned long tmr;        // timers mode register      (RW)
+  unsigned long tdr0;       // timer0 data register      (RW)
+  unsigned long tdr1;       // timer1 data register      (RW)
+  unsigned long tcr0;       // timer0 count register      (RW)
+  unsigned long tcr1;       // timer1 count register      (RW)
+};
+#endif
+
+/****************************************  Interrupt Controller */
+#define IC_BASE		INTMOD
+
+#define IC_xIRQ0  	(1<<0)
+#define IC_xIRQ1  	(1<<1)
+#define IC_xIRQ2  	(1<<2)
+#define IC_xIRQ3  	(1<<3)
+#define IC_UARTTx0  	(1<<4)
+#define IC_UARTRxE0  	(1<<5)
+#define IC_UARTTx1  	(1<<6)
+#define IC_UARTRxE1  	(1<<7)
+#define IC_GDMA0  	(1<<8)
+#define IC_GDMA1  	(1<<9)
+#define IC_TC0  	(1<<10)
+#define IC_TC1  	(1<<11)
+#define IC_HDLCATx  	(1<<12)
+#define IC_HDLCARx  	(1<<13)
+#define IC_HDLCBTx  	(1<<14)
+#define IC_HDLCBRx  	(1<<15)
+#define IC_BDMATx  	(1<<16)
+#define IC_BDMARx  	(1<<17)
+#define IC_MACTx  	(1<<18)
+#define IC_MACRx  	(1<<19)
+#define IC_I2C  	(1<<20)
+#define IC_GLOBAL  	(1<<21)
+
+#define _IRQ0		0
+#define _IRQ1		1
+#define _IRQ2		2
+#define _IRQ3		3
+#define _URTTx0  	4
+#define _URTRx0  	5
+#define _URTTx1  	6
+#define _URTRx1  	7
+#define _GDMA0  	8
+#define _GDMA1  	9
+#define _TC0  		10
+#define _TC1  		11
+#define _HDLCATx  	12
+#define _HDLCARx  	13
+#define _HDLCBTx  	14
+#define _HDLCBRx  	15
+#define _BDMATx  	16
+#define _BDMARx  	17
+#define _MACTx  	18
+#define _MACRx  	19
+#define _I2C  		20
+#define _GLOBAL		21
+
+#define HW_ETHERNET_ADDR 0x1007fd0
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/i2c.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/i2c.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/i2c.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/i2c.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,34 @@
+/*
+ * iic.h
+ *
+ * Copyright (C) 2002 Arcturus Networks Inc.
+ * by Oleksandr Zhadan <oleks@arcturusnetworks.com>
+ *
+ * This file includes the I2C bus controller definitions
+ * of the S3C4530A RISC microcontroller
+ * based on the Samsung's "S3C4530A 32-bit RISC
+ * Microprocessor Revision 1  User's Manual"
+ */
+ 
+#ifndef __ASM_ARCH_IIC_H
+#define __ASM_ARCH_IIC_H
+
+#define IICCON		0x3FFF000	/* Control status R	*/
+#define IICCON_BF	0x01		/* Buffer flag		*/
+#define IICCON_IEN	0x02		/* Interrupt enable	*/
+#define IICCON_LRB	0x04		/* Last received bit 	*/
+#define IICCON_ACK	0x08		/* Acknowlege enable	*/
+#define IICCON_START	0x10		/* Start condition	*/
+#define IICCON_STOP	0x20		/* Stop condition	*/
+#define IICCON_RESTART	0x30		/* Repeat Start(Restart)*/
+#define IICCON_BUSY	0x40		/* Bus busy		*/
+#define IICCON_RESET	0x80		/* Reset		*/
+
+#define IICBUF		0x3FFF004	/* Shift buffer R	*/
+#define IICBUF_WRITE	0x00		/* Slave Addr Write bit	*/
+#define IICBUF_READ	0x01		/* Slave Addr Read bit	*/
+
+#define IICPS		0x3FFF008	/* Prescaler R		*/
+#define IICCNT		0x3FFF00C	/* Prescaler counter R
	*/
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/ide.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/ide.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/ide.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,45 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/ide.h
+ *
+ * Copyright (c) 1998 Hugo Fiennes & Nicolas Pitre
+ *
+ * 18-aug-2000: Cleanup by Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
+ *              Get rid of the special ide_init_hwif_ports() functions
+ *              and make a generalised function that can be used by all
+ *              architectures.
+ */
+
+#include <linux/config.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+
+/*
+ * Set up a hw structure for a specified data port, control port and IRQ.
+ * This should follow whatever the default interface uses.
+ */
+static __inline__ void
+ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int *irq)
+{
+#ifdef CONFIG_REVISIT
+#error Not sure what to do for ide_init_hwif_ports
+#endif
+}
+
+
+
+
+/*
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ */
+static __inline__ void
+ide_init_default_hwifs(void)
+{
+#ifdef CONFIG_REVISIT
+#error Not sure what to do for ide_init_default_hwifs
+#endif
+}
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/io.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ * linux/include/asm-armnommu/arch-dsc21/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ *  02-19-2001  gjm     Leveraged for armnommu/dsc21
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ * --gmcnutt
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * If we define __io then asm/io.h will take care of most of the inb & friends
+ * macros. It still leaves us some 16bit macros to deal with ourselves, though.
+ * We don't have PCI or ISA on the dsc21 so I dropped __mem_pci & __mem_isa.
+ * --gmcnutt
+ */
+#define PCIO_BASE 0
+#define __io(a) (PCIO_BASE + (a))
+#define __arch_getw(a) (*(volatile unsigned short *)(a))
+#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
+
+/*
+ * Defining these two gives us ioremap for free. See asm/io.h.
+ * --gmcnutt
+ */
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,75 @@
+/*
+ * include/asm/arch/irq.h
+ * OZH, 2001 Oleksandr Zhadan
+ */
+
+#ifndef __ASM_ARCH_IRQ_H__
+#define __ASM_ARCH_IRQ_H__
+
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irqs.h>
+
+// #define fixup_irq(x) (x)
+
+extern void s3c4530_mask_irq(unsigned int irq);
+extern void s3c4530_unmask_irq(unsigned int irq);
+extern void s3c4530_mask_ack_irq(unsigned int irq);
+extern void s3c4530_clear_pb(unsigned int irq);
+
+
+static __inline__ unsigned int fixup_irq (unsigned int irq)
+{
+s3c4530_clear_pb(irq);
+return (irq);
+}
+
+static __inline__ void irq_init_irq(void)
+{
+    volatile unsigned char *PtIntPr = (volatile unsigned char *)INTPRI0;
+    int irq;
+/* Current IRQ number by priority */
+    static unsigned char s3c4530_irq_prtable[32] = {
+    _IRQ0,			/* Low */
+    _IRQ1,
+    _IRQ2,
+    _IRQ3,
+    _URTTx0,
+    _URTRx0,
+    _URTTx1,
+    _URTRx1,
+    _GDMA0,
+    _GDMA1,
+    _TC0,
+    _TC1,
+    _HDLCATx,
+    _HDLCARx,
+    _HDLCBTx,
+    _HDLCBRx,
+    _BDMATx,
+    _BDMARx,
+    _MACTx,
+    _MACRx,
+    _I2C,			/* High */
+    0,0,0,0,0,0,0,0,0,0,0
+    };
+    
+    
+    for (irq = 0; irq < NR_IRQS; irq++) {
+	irq_desc[irq].valid	= 1;
+	irq_desc[irq].probe_ok	= 1;
+	irq_desc[irq].mask_ack	= s3c4530_mask_ack_irq;
+	irq_desc[irq].mask	= s3c4530_mask_irq;
+	irq_desc[irq].unmask	= s3c4530_unmask_irq;
+	
+	*PtIntPr++ = s3c4530_irq_prtable[
irq]; 		/* Set up priority 	*/
+	}	
+    outl ( 0,        INTMOD );		/* Set all interrupts
 as IRQ mode	*/
+    outl ( 0x1FFFFF, INTPND );
		/* Clear Intrerrupt pending register	*/
+    outl ( 0x1FFFFF, INTMSK );
		/* Disable all Intrerrupts		*/
+}
+
+
+#endif /* __ASM_ARCH_IRQ_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/irqs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * uClinux/asm-armnommu/arch-uClinkII/irqs.h:
+ * OZH, 2001 Oleksandr Zhadan
+ */
+ 
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+
+#define NR_IRQS		21
+
+
+#endif /* __ASM_ARCH_IRQS_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/keyboard.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/keyboard.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/keyboard.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ *  linux/include/asm-arm/arch-ti926/keyboard.h
+ *
+ *  Copyright (C) 2000 RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Keyboard driver definitions for ARM
+ */
+#ifndef __ASM_ARM_ARCH_TI925_KEYBOARD_H
+#define __ASM_ARM_ARCH_TI925_KEYBOARD_H
+
+#if 0
+#define kbd_request_region
+#define kbd_write_command
+#define kbd_write_output
+#define kbd_read_status
+#define kbd_read_input
+#define aux_request_irq
+#define aux_free_irq
+#endif
+
+/*
+ * Required by drivers/char/keyboard.c. I took these from arch-arc.
+ * --gmcnutt
+ */
+#define kbd_setkeycode(sc,kc) (-EINVAL)
+#define kbd_getkeycode(sc) (-EINVAL)
+#define kbd_translate(sc,kcp,rm) ({ *(kcp) = (sc); 1; })
+#define kbd_unexpected_up(kc) (0200)
+#define kbd_leds(leds)
+#define kbd_init_hw()
+#define kbd_enable_irq() /* what irq? ;) --gmcnutt */
+#define kbd_disable_irq()
+
+
+#endif /* __ASM_ARM_ARCH_TI925_KEYBOARD_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,23 @@
+/*
+ * linux/include/asm-armnommu/arch-evS3C4530HEI/memory.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * 2001 Mindspeed
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define TASK_SIZE	(0x01a00000UL)
+#define TASK_SIZE_26	TASK_SIZE
+
+#define PHYS_OFFSET	(DRAM_BASE)
+#define PAGE_OFFSET 	(PHYS_OFFSET)
+#define END_MEM     	(DRAM_BASE + DRAM_SIZE)
+
+#define __virt_to_phys(vpage) ((unsigned long) (vpage))
+#define __phys_to_virt(ppage) ((void *) (ppage))
+#define __virt_to_bus(vpage) ((unsigned long) (vpage))
+#define __bus_to_virt(ppage) ((void *) (ppage))
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/param.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/pcmcia.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/pcmcia.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/pcmcia.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/pcmcia.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,3 @@
+#ifdef CONFIG_REVISIT
+#error Do we need PCMCIA support?
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/processor.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/processor.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/processor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,19 @@
+/*
+ * uclinux/include/asm-armnommu/arch-atmel/mmu.h
+ *
+ */
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+#define EISA_bus 0
+#define EISA_bus__is_a_macro
+#define MCA_bus 0
+#define MCA_bus__is_a_macro
+
+#define TASK_SIZE (0x01a00000UL)
+
+#define INIT_MMAP { \
+  &init_mm, 0, 0x02000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC \
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/serial.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/serial.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/serial.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,9 @@
+/*
+ *  linux/include/asm-arm/arch-p52/serial.h
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+/* need to move p52serial.h here */
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/shmparam.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/shmparam.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/shmparam.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-a5k/shmparam.h
+ *
+ * Copyright (c) 1996 Russell King.
+ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/system.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-armnommu/arch-p52/system.h
+ * 2001 Mindspeed
+ */
+
+static inline void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter)
+	  cpu_do_idle(IDLE_WAIT_SLOW);
+}
+
+extern inline void arch_reset(char mode)
+{
+  /* tbd */
+}
+
+ 
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/time.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/time.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,52 @@
+/*
+ * include/asm/arch/time.h
+ * OZH, 2001 Oleksandr Zhadan
+ */
+
+#ifndef __ASM_ARCH_TIME_H__
+#define __ASM_ARCH_TIME_H__
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/timex.h>
+
+extern struct irqaction timer_irq;
+
+extern unsigned long s3c4530_gettimeoffset(void);
+extern void s3c4530_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+extern __inline__ void setup_timer (void)
+{
+    volatile struct s3c4530_timer* tt = (struct s3c4530_timer*) (TIMER_BASE);
+    unsigned long v;
+
+    gettimeoffset     = s3c4530_gettimeoffset;
+    timer_irq.handler = s3c4530_timer_interrupt;
+
+#if	(KERNEL_TIMER==0)
+	*(unsigned int *)IOPCON0 = 0x40000000;
+	tt->tdr0 = (unsigned long)(ARM_CLK/HZ-1);
+/*	v = tt->tmr & 0xFFFFFFF8;
+	v |= 0x01; */
+	tt->tmr = 0x07;
+	setup_arm_irq(_TC0, &timer_irq);
+	__sti();
+/*	enable_irq ( _TC0 ); */
+#elif	(KERNEL_TIMER==1)
+	*(unsigned int *)IOPCON0 = 0x80000000;
+	tt->tdr1 = (unsigned long)(ARM_CLK/HZ - 1);
+	/* 0x7a11f;
+	v = tt->tmr & 0xFFFFFFC7; 
+	v = 0x038; */
+
+	tt->tmr = 0x38;
+
+	setup_arm_irq(_TC1, &timer_irq);
+	enable_irq ( _TC1 );
+#else
+#error Weird -- KERNEL_TIMER does not seem to be defined...
+#endif    
+}
+
+#endif /* __ASM_ARCH_TIME_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+ * timex.h:
+ * 2001 Mindspeed
+ */
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+#define CLOCK_TICK_RATE	   0x270f
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/uncompress.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/uncompress.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/uncompress.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ * asm/arch/uncompress.c:
+ *         Optional routines to aid in debugging the decompression phase
+ *         of kernel boot.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * This is used by arch/armnommu/boot/compressed/misc.c to write progress info
+ * out the serial port so that the user can see debug messages up to the point
+ * where the kernel is decompressed. The STANDALONE_DEBUG macro chooses between
+ * this and the standard printf. Punt.
+ * --gmcnutt
+ */
+#define puts(s)
+
+/*
+ * Not sure what this is for. Probably an optional watchdog to check if the
+ * decompress got hung so we can warn the user. Punt.
+ */
+#define arch_decomp_wdog()
+
+/*
+ * If we need to do some setup prior to decompression (like initializing the
+ * UART if we want to use puts() above) then we define it here. Punt.
+ */
+#define arch_decomp_setup()
diff -urN linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-evS3C4530HEI/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-evS3C4530HEI/vmalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ *  linux/include/asm-arm/arch-dsc21/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff -urN linux-2.4.29/include/asm-armnommu/arch-ipod/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-ipod/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/dma.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+/* we don't have any DMA */
+#define MAX_DMA_ADDRESS		0xffffffff
+#define MAX_DMA_CHANNELS	0
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ipod/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-ipod/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/hardware.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2003,2004 Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/* this is called from drivers/block/blkmem.c */
+#define HARD_RESET_NOW() ipod_hard_reset()
+
+#ifndef __ASSEMBLY__
+struct sysinfo_t {
+	unsigned IsyS;  /* == "IsyS" */
+	unsigned len;
+
+	char BoardHwName[16];
+	char pszSerialNumber[32];
+	char pu8FirewireGuid[16];
+
+	unsigned boardHwRev;
+	unsigned bootLoaderImageRev;
+	unsigned diskModeImageRev;
+	unsigned diagImageRev;
+	unsigned osImageRev;
+
+	unsigned iram_perhaps;
+
+	unsigned Flsh;
+	unsigned flash_zero;
+	unsigned flash_base;
+	unsigned flash_size;
+	unsigned flash_zero2;
+								
+	unsigned Sdrm;
+	unsigned sdram_zero;
+	unsigned sdram_base;
+	unsigned sdram_size;
+	unsigned sdram_zero2;
+								
+	unsigned Frwr;
+	unsigned frwr_zero;
+	unsigned frwr_base;
+	unsigned frwr_size;
+	unsigned frwr_zero2;
+								
+	unsigned Iram;
+	unsigned iram_zero;
+	unsigned iram_base;
+	unsigned iram_size;
+	unsigned iram_zero2;
+								
+	char pad7[120];
+
+	unsigned boardHwSwInterfaceRev;
+
+	/* added in V3 */
+	char HddFirmwareRev[10];
+
+	unsigned short RegionCode;
+
+	unsigned PolicyFlags;
+
+	char ModelNumStr[16];
+};
+
+extern unsigned ipod_get_hw_version(void);
+extern struct sysinfo_t *ipod_get_sysinfo(void);
+extern int ipod_i2c_send_bytes(unsigned int addr, unsigned int len, unsigned char *data);
+extern int ipod_i2c_send(unsigned int addr, int data0, int data1);
+extern void ipod_serial_init(void);
+
+typedef void (*ipod_dma_handler_t)(void);
+
+extern void ipod_set_process_dma(ipod_dma_handler_t new_handler);
+
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ipod/ide.h linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/ide.h
--- linux-2.4.29/include/asm-armnommu/arch-ipod/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/ide.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#ifndef __ASM_ARCH_IDE_H
+#define __ASM_ARCH_IDE_H
+
+/* we have one controller */
+#undef MAX_HWIFS
+#define MAX_HWIFS	1
+
+#define IDE_INLINE __inline__
+
+#define IDE_PRIMARY_BASE	0xc00031e0
+#define IDE_PRIMARY_CONTROL	0xc00033f8
+
+static struct ipod_ide_defaults {
+	ide_ioreg_t	base;
+	int		irq;
+} ipod_ide_defaults[MAX_HWIFS] = {
+	{ (ide_ioreg_t)IDE_PRIMARY_BASE, 1 },
+};
+
+static IDE_INLINE int ide_default_irq(ide_ioreg_t base)
+{
+	int i;
+
+	for ( i = 0; i < MAX_HWIFS; i++ )
+		if ( ipod_ide_defaults[i].base == base )
+			return ipod_ide_defaults[i].irq;
+	return 0;
+}
+
+static IDE_INLINE ide_ioreg_t ide_default_io_base(int index)
+{
+	if ( index >= 0 && index < MAX_HWIFS )
+		return ipod_ide_defaults[index].base;
+	return 0;
+}
+
+/*
+ * Set up a hw structure for a specified data port, control port and IRQ.
+ * This should follow whatever the default interface uses.
+ */
+static IDE_INLINE void ide_init_hwif_ports(
+	hw_regs_t *hw,
+	ide_ioreg_t data_port,
+	ide_ioreg_t ctrl_port,
+	int *irq)
+{
+	ide_ioreg_t reg = data_port;
+	int i;
+
+	for ( i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++ ) {
+		hw->io_ports[i] = reg;
+		reg += 4;	/* our registers are on word boundaries */
+	}
+
+	if (ctrl_port) {
+		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+	}
+	else {
+		hw->io_ports[IDE_CONTROL_OFFSET] = data_port + 0x218;
+	}
+}
+
+/*
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ */
+static IDE_INLINE void ide_init_default_hwifs(void)
+{
+	hw_regs_t hw;
+	ide_ioreg_t base;
+	int index;
+
+	outl(inl(0xc0003024) | (1<< 7), 0xc0003024);
+	outl(inl(0xc0003024) & ~(1<<2), 0xc0003024);
+
+	outl(0x10, 0xc0003000);
+	outl(0x80002150, 0xc0003004);
+
+	for (index = 0; index < MAX_HWIFS; index++) {
+
+		base = ide_default_io_base(index);
+		if (!base) continue;
+
+		memset(&hw, 0, sizeof(hw));
+		ide_init_hwif_ports(&hw, base, IDE_PRIMARY_CONTROL, NULL);
+		hw.irq = ide_default_irq(base);
+		ide_register_hw(&hw, NULL);
+	}
+}
+
+#define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
+#define ide_free_irq(irq,dev_id)		free_irq((irq), (dev_id))
+#define ide_check_region(from,extent)		check_region((from), (extent))
+#define ide_request_region(from,extent,name)	request_region((from), (extent), (name))
+#define ide_release_region(from,extent)		release_region((from), (extent))
+
+#define ide_ack_intr(hwif)              (1)
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ipod/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/io.h
--- linux-2.4.29/include/asm-armnommu/arch-ipod/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/io.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+/* kernel/resource.c
+ * used to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(),
+ * allocate_resource(), etc.
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * If we define __io then asm/io.h will take care of most of the
+ * inb & friends macros.
+ */
+#define PCIO_BASE 0
+#define __io(a) (PCIO_BASE + (a))
+
+#define __arch_getw(a) (*(volatile unsigned short *)(a))
+#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
+
+/* These are required by the serial driver */
+#define readb(addr)			__raw_readb(addr)
+#define readw(addr)			__raw_readw(addr)
+#define readl(addr)			__raw_readl(addr)
+#define writeb(val,addr)		__raw_writeb(val,addr)
+#define writew(val,addr)		__raw_writew(val,addr)
+#define writel(val,addr)		__raw_writel(val,addr)
+
+/* hacks to get SCSI to compile */
+#define PCI_DMA_BUS_IS_PHYS (0)
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ipod/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-ipod/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/irq.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#ifndef __ASM_ARCH_IRQ_H__
+#define __ASM_ARCH_IRQ_H__
+
+#define fixup_irq(x) (x)
+
+extern int ipod_init_irq(void);
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ipod/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-ipod/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/irqs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+
+#define IDE_INT0_IRQ	1
+#define SER0_IRQ	4
+#define I2S_IRQ		5
+#define SER1_IRQ	7
+#define TIMER1_IRQ	11
+#define GPIO_IRQ	14
+#define DMA_OUT_IRQ	30
+
+#define NR_IRQS	32
+
+#define VALID_IRQ(x)	(x==IDE_INT0_IRQ||x==SER0_IRQ||x==I2S_IRQ||x==SER1_IRQ||x==TIMER1_IRQ||x==GPIO_IRQ||x==DMA_OUT_IRQ)
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ipod/keyboard.h linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/keyboard.h
--- linux-2.4.29/include/asm-armnommu/arch-ipod/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/keyboard.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#ifndef __ASM_ARCH_KEYBOARD_H__
+#define __ASM_ARCH_KEYBOARD_H__
+
+extern void ipodkb_init_hw(void);
+
+/* drivers/char/keyboard.c */
+#define kbd_setkeycode(sc,kc)		(-EINVAL)
+#define kbd_getkeycode(sc)		(-EINVAL)
+#define kbd_translate(sc,kcp,rm)	({ *(kcp) = (sc); 1; })
+#define kbd_unexpected_up(kc)		(0200)
+#define kbd_leds(leds)
+#define kbd_init_hw()			ipodkb_init_hw()
+#define kbd_enable_irq()
+#define kbd_disable_irq()
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ipod/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-ipod/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/memory.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * These should be the same as the definitions in asm/memory.h
+ * without the '__' at the beginning.
+ */
+#define __virt_to_bus(x) ((unsigned long) (x))
+#define __bus_to_virt(x) ((void *) (x))
+#define __virt_to_phys(x) ((unsigned long) (x))
+#define __phys_to_virt(x) ((void *) (x))
+
+#define PHYS_OFFSET	(DRAM_BASE)
+#define PAGE_OFFSET	PHYS_OFFSET
+
+/* user space process size - 16MB */
+#define TASK_SIZE	(0x01000000UL)
+
+/* arch/armnommu/kernel/setup.c */
+#define END_MEM		(DRAM_BASE + DRAM_SIZE)
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ipod/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/param.h
--- linux-2.4.29/include/asm-armnommu/arch-ipod/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/param.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ipod/serial.h linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/serial.h
--- linux-2.4.29/include/asm-armnommu/arch-ipod/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/serial.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/irqs.h>
+#include <linux/termios.h>
+
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+#undef SERIAL_DEBUG_PCI
+#undef SERIAL_DEBUG_AUTOCONF
+
+
+#define IPOD_SER0_BASE	0xc0006000
+#define IPOD_SER1_BASE	0xc0006040
+
+/* The UART is clocked at 24MHz */
+#define BASE_BAUD	(24576000 / 16)
+
+#define STD_COM_FLAGS	(ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
+#define DEFAULT_CFLAGS (B9600 | CS8 | CREAD | HUPCL | CLOCAL)
+
+#define RS_TABLE_SIZE 2
+
+#define STD_SERIAL_PORT_DEFNS \
+	{  \
+	magic: 0, \
+	baud_base: BASE_BAUD, \
+	irq: SER0_IRQ, \
+	flags: STD_COM_FLAGS, \
+	type: PORT_UNKNOWN, \
+	iomem_base: (u8*)IPOD_SER0_BASE, \
+	iomem_reg_shift: 2, \
+	io_type: SERIAL_IO_MEM \
+	},      /* ttyS0 */ \
+        {  \
+        magic: 0, \
+        baud_base: BASE_BAUD, \
+        irq: SER1_IRQ, \
+        flags: STD_COM_FLAGS, \
+        type: PORT_UNKNOWN, \
+        iomem_base: (u8*)IPOD_SER1_BASE, \
+        iomem_reg_shift: 2, \
+        io_type: SERIAL_IO_MEM \
+	}       /* ttyS1 */
+
+#define EXTRA_SERIAL_PORT_DEFNS
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ipod/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/system.h
--- linux-2.4.29/include/asm-armnommu/arch-ipod/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/system.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2003,2004 Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#ifndef __ARCH_ASM_SYSTEM_H__
+#define __ARCH_ASM_SYSTEM_H__
+
+static __inline__ void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter);
+}
+
+extern __inline__ void arch_reset(char mode)
+{
+	extern void ipod_hard_reset(void);
+	ipod_hard_reset();
+}
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ipod/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/time.h
--- linux-2.4.29/include/asm-armnommu/arch-ipod/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/time.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#ifndef __ARCH_ASM_TIME__
+#define __ARCH_ASM_TIME__
+
+/*
+ * Time(r) routines for kernel/time.c.
+ *
+ * The entry point from the kerenl is setup_timer() whose main
+ * purpose is to start the timer ticking.  It is also used to
+ * supply the kernel with out time(r) functions.
+ */
+
+extern unsigned long ipod_gettimeoffset(void);
+extern int ipod_set_rtc(void);
+extern void ipod_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+/* */
+extern struct irqaction timer_irq;
+
+/*
+ * Set up timer interrupt, and the current time in seconds.
+ *
+ * This function is called from kernel/time.c:time_init.  It
+ * must start the timer ticking.  The RTC can be set later though.
+ *
+ */
+extern __inline__ void setup_timer(void)
+{
+	/* store in kernel's function pointer */
+	gettimeoffset = ipod_gettimeoffset;
+	set_rtc = ipod_set_rtc;
+
+	/* set up the timer interrupt */
+	timer_irq.handler = ipod_timer_interrupt;
+
+	/* clear timer1 */
+	outl(0x0, 0xcf001100);
+	inl(0xcf001104);
+
+	/* enable timer, period, trigger value 0x2710 -> 100Hz */
+	outl(0xc0002710, 0xcf001100);
+
+	setup_arm_irq(TIMER1_IRQ, &timer_irq);
+	enable_irq(TIMER1_IRQ);
+}
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ipod/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-ipod/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/timex.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ipod/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-ipod/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ipod/vmalloc.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) 2003, Bernard Leach (leachbj@bouncycastle.org)
+ */
+
+#ifndef __ASM_ARCH_VMALLOC_H__
+#define __ASM_ARCH_VMALLOC_H__
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/a.out.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/a.out.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/a.out.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * uclinux/include/asm-armnommu/arch-isl3893/a.out.h
+ *
+ */
+#ifndef __ASM_ARCH_A_OUT_H
+#define __ASM_ARCH_A_OUT_H
+
+#ifdef __KERNEL__
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/blobcalls.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/blobcalls.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/blobcalls.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/blobcalls.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,192 @@
+/*  $Header$
+ *
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+#ifndef __ASM_ARCH_BLOBCALLS_H__
+#define __ASM_ARCH_BLOBCALLS_H__
+
+/* Some MVC header files use this define to specify the MVC version 2 interface */
+#define BLOB_V2
+#define MVC2_2
+
+#include <linux/kernel.h>
+#include <blobv2.h>
+#include <bloboid.h>
+#include <blobarch.h>
+
+/* For the boot struct */
+#define CONF_3893
+#include <bootdbg.h>
+
+/*
+ * This header file needs to be included for making calls to the MVC. It
+ * will automatically include the correct MVC header files.
+ *
+ * The macros below specify the coprocessor interface of the MVC. There are
+ * two types of calls: xx_to_mvc and xx_from_mvc. The xx can be _blobcall
+ * for calls to the blobdevice or _devcall for calls to the regular devices
+ * (WLAN, HOSTDS, DEBUG, etcetera).
+ * There are different macros for functions with no arguments (..mvc0) and
+ * one argument (..mvc1). There is also a special case for functions that
+ * have no return value (.._noret).
+ * The actual interface is defined in /arch/armnommu/mach-<machine>/blobcalls.c
+ */
+
+/*
+ * These instructions share a common format, with the following assembly syntax:
+ * 	MRC/MCR{<cond>} p<cp#>>, <opcode_1>, (C)Rd, CRn, CRm, <opcode_2>
+ * The generic usage of the instruction fields is :
+ * <cp#>	MVC co-processor ID (11),
+ * <opcode_1>	Reserved (0),
+ * <Rd>		ARM register with a pointer to a message dependent structure,
+ *		the ARM register argument may be any register (r0 - r14), except for r15.
+ * <CRn>	Device number (0 - 15),
+ * <CRm>	Messager number (0 - 15),
+ * <opcode_2>	Reserved (0).
+ */
+
+
+/*
+ * Some magic to let the preprocessor stringify the coprocessor registers
+ */
+#define __str(x)	#x
+#define __cat( x, y )	__str(x ## y)
+#define __creg( nr )	__cat( c, nr )
+
+#define _blobcall_to_mvc0(type, func, msg)						\
+static inline type func(void)								\
+{											\
+	msg_blob blob;									\
+	__asm__ __volatile__ (								\
+		"mcr	p11, 0, %0, " __creg(DEVICE_BLOB) ", " __creg(msg) ", 0"	\
+		: : "r" (&blob));							\
+	return (type)(blob.error);							\
+}
+
+#define _blobcall_to_mvc1(type, func, msg, type1)					\
+static inline type func(type1 arg1)							\
+{											\
+	__asm__ __volatile__ (								\
+		"mcr	p11, 0, %0, " __creg(DEVICE_BLOB) ", " __creg(msg) ", 0"	\
+		: : "r" (arg1));							\
+	return (type)(arg1->blob.error);						\
+}
+
+#define _blobcall_from_mvc0(type, func, msg)						\
+static inline type func(void)								\
+{											\
+	type __res;									\
+	__asm__ __volatile__ (								\
+		"mrc	p11, 0, %0, " __creg(DEVICE_BLOB) ", " __creg(msg) ", 0"	\
+		: "=r" (__res):);							\
+	return __res;									\
+}
+
+#define _devcall_to_mvc0(type, func, msg)						\
+static inline type func(int device)							\
+{											\
+	msg_blob blob;									\
+											\
+	blob.device = device;								\
+	__asm__ __volatile__ (								\
+		"mcr	p11, 0, %0, " __creg(DEVICE_GENERIC) ", " __creg(msg) ", 0"	\
+		: : "r" (&blob));							\
+											\
+	return (type)(blob.error);							\
+}
+
+#define _devcall_to_mvc1(type, func, msg, type1)					\
+static inline type func(int device, type1 arg1)						\
+{											\
+	arg1->blob.device = device;							\
+	__asm__ __volatile__ (								\
+		"mcr	p11, 0, %0, " __creg(DEVICE_GENERIC) ", " __creg(msg) ", 0"	\
+		: : "r" (arg1));							\
+											\
+	return (type)(arg1->blob.error);						\
+}
+
+
+/*
+ * Definition of the MVC interface calls
+ */
+
+/*
+ * Stubs for the blob
+ */
+_blobcall_to_mvc1(int, blob_init, MSG_INIT, struct msg_init *)
+_blobcall_from_mvc0(int, blob_abort, MSG_ABORT)
+_blobcall_from_mvc0(int, blob_reset, MSG_RESET)
+_blobcall_from_mvc0(int, blob_sleep, MSG_SLEEP)
+_blobcall_to_mvc1(int, blob_conf, MSG_CONF, struct msg_conf *)
+_blobcall_from_mvc0(int, blob_watchdog, MSG_WATCHDOG)
+
+_blobcall_to_mvc0(int, blob_reqs, MSG_REQS)
+_blobcall_to_mvc0(int, blob_service, MSG_SERVICE)
+_blobcall_to_mvc1(int, blob_trap, MSG_TRAP, struct msg_conf *)
+
+
+/*
+ * Stubs for other devices
+ */
+_devcall_to_mvc1(int, dev_start, MSG_START, struct msg_start*)
+_devcall_to_mvc0(int, dev_run, MSG_RUN)
+_devcall_to_mvc0(int, dev_halt, MSG_HALT)
+_devcall_to_mvc0(int, dev_stop, MSG_STOP)
+_devcall_to_mvc1(int, dev_conf, MSG_CONF, struct msg_conf *)
+_devcall_to_mvc1(int, dev_setup, MSG_SETUP, struct msg_setup *)
+
+_devcall_to_mvc1(int, dev_frame_add, MSG_FRAME_ADD, struct msg_frame *)
+_devcall_to_mvc1(int, dev_frame_tx, MSG_FRAME_TX, struct msg_frame *)
+
+_devcall_to_mvc1(int, dev_write, MSG_WRITE, struct msg_data *)
+
+_devcall_to_mvc0(int, dev_state, MSG_STATE)
+_devcall_to_mvc0(int, dev_reqs, MSG_REQS)
+_devcall_to_mvc0(int, dev_service, MSG_SERVICE)
+
+_devcall_to_mvc0(int, dev_watchdog, MSG_WATCHDOG)
+
+/* dev_trap changed between MVCv1 and MVCv2 */
+_devcall_to_mvc1(int, dev_trap, MSG_TRAP, struct msg_conf *)
+
+_devcall_to_mvc0(struct msg_frame *, dev_frame_return, MSG_FRAME_RETURN)
+_devcall_to_mvc0(struct msg_frame *, dev_frame_rx, MSG_FRAME_RX)
+
+_devcall_to_mvc0(struct msg_data *, dev_read, MSG_READ)
+
+extern struct boot_struct *bootstruct;
+
+static inline unsigned char *blobtool_find_element(int id, int skip)
+{
+        unsigned char *p = (unsigned char *)bootstruct->bis;
+
+        while( *((short*)p) != id || skip > 0 )
+        {
+                if( (*((short*)p)) == (short)BIS_END )
+                        return 0L;
+
+                if( *((short*)p) == id )
+                        skip--;
+
+                p += 4 + *((short*)(p+2));
+        }
+
+        return p + 4;
+}
+
+#endif /* __ASM_ARCH_BLOBCALLS_H__ */
\ No newline at end of file
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,147 @@
+/* $Header$
+ *
+ * asm/arch-armnommu/arch-isl3893/dma.h:
+ *         isl3893-specific macros for DMA support.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+/*
+ * MAX_DMA_ADDRESS -- max address we can program into the DMA address registers?
+ * Not sure. Various drivers use this value as a test before setting up a DMA.
+ * Also, the macros in linux/bootmem.h use this value as a goal for many of the
+ * bootmem allocations.
+ * Open questions:
+ * a) the DMA address register is only 26 bits -- does this limit us to this
+ *    section of memory, or can we only DMA in certain size chunks?
+ * b) can the ARM processor even directly program the DMA?
+ * I'm going to go out on a limb and assume that the DMA range is the first
+ * addresseable 26 bits.
+ * --gmcnutt
+ */
+#define MAX_DMA_ADDRESS		0x80000000
+
+/*
+ * MAX_DMA_CHANNELS -- # of DMA control register sets we possess. For the dsc21
+ * we have one that can run in either direction and between two different
+ * destinations.
+ * --gmcnutt
+ */
+#define MAX_DMA_CHANNELS        4
+
+/* Register values */
+
+/* - CONTROL */
+#define	DMACONTROL			(0x0)
+#define	DMACONTROLDRQIntEn		(0x4)
+#define	DMACONTROLBAUIntEn		(0x2)
+#define	DMACONTROLEnable		(0x1)
+#define	DMACONTROLMask			(0x7)
+#define	DMACONTROLTestMask		(0x6)
+#define	DMACONTROLInitialValue		(0x0)
+#define	DMACONTROLAccessType		(RW)
+
+/* - MAXCNT */
+#define	DMAMAXCNT			(0x4)
+#define	DMAMAXCNTMask			(0xffff)
+#define	DMAMAXCNTInitialValue		(0x0)
+#define	DMAMAXCNTTestMask		(0xffff)
+#define	DMAMAXCNTAccessType		(RW)
+
+/* - BASE */
+#define	DMABASE				(0x8)
+#define	DMABASEMask			(0x1fffffff)
+#define	DMABASEInitialValue		(0x0)
+#define	DMABASETestMask			(0x1fffffff)
+#define	DMABASEAccessType		(RW)
+
+/* - STATUS */
+#define	DMASTATUS			(0xc)
+#define	DMASTATUSBytes			(0x1f0)
+#define	DMASTATUSBytesShift		(0x4)
+#define	DMASTATUSTranErr		(0x8)
+#define	DMASTATUSDRQ			(0x4)
+#define	DMASTATUSBAUInt			(0x2)
+#define	DMASTATUSStallInt		(0x1)
+#define	DMASTATUSMask			(0x1ff)
+#define	DMASTATUSAccessType		(RO)
+#define	DMASTATUSTestMask		(0x1fb)
+#define	DMASTATUSInitialValue		(0x0)
+
+/* - CURRENT */
+#define	DMACURRENT			(0x10)
+#define	DMACURRENTMask			(0x1fffffff)
+#define	DMACURRENTAccessType		(RO)
+#define	DMACURRENTInitialValue		(0x0)
+#define	DMACURRENTTestMask		(0x1fffffff)
+
+/* - REMAIN */
+#define	DMAREMAIN			(0x14)
+#define	DMAREMAINMask			(0xffff)
+#define	DMAREMAINAccessType		(RO)
+#define	DMAREMAINInitialValue		(0x0)
+#define	DMAREMAINTestMask		(0xffff)
+
+/* - DATA */
+#define	DMADATA				(0x18)
+#define	DMADATAEnd			(0x100)
+#define	DMADATAData			(0xff)
+#define	DMADATADataShift		(0x0)
+#define	DMADATAMask			(0x1ff)
+// #define	DMADATAAccessType		(NO_TEST)
+#define	DMADATAInitialValue		(0x0)
+#define	DMADATATestMask			(0x1ff)
+
+
+typedef struct s_DMA {
+ unsigned CONTROL; /* @0 */
+ unsigned MAXCNT; /* @4 */
+ unsigned BASE; /* @8 */
+ unsigned STATUS; /* @12 */
+ unsigned CURRENT; /* @16 */
+ unsigned REMAIN; /* @20 */
+ unsigned fill0;
+ unsigned DATA; /* @28 */
+} s_DMA;
+
+#define uHostTxDma     ((volatile struct s_DMA *) 0xc0000f00)
+#define uHostRxDma     ((volatile struct s_DMA *) 0xc0000f20)
+#define uBasebandTxDma ((volatile struct s_DMA *) 0xc0000f40)
+#define uBasebandRxDma ((volatile struct s_DMA *) 0xc0000f60)
+#define uWEPTxDma      ((volatile struct s_DMA *) 0xc0000f80)
+#define uWEPRxDma      ((volatile struct s_DMA *) 0xc0000fa0)
+
+
+/*
+ * arch_dma_init -- called by arch/armnommu/kernel/dma.c init_dma.
+ * Don't know what's needed here (if anything).
+ * --gmcnutt
+ */
+#define arch_dma_init(dma_chan)
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/gpio.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/gpio.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/gpio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/gpio.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,215 @@
+/*
+ * include/asm-armnommu/arch-isl3893/gpio.h
+ */
+/*  $Header$
+ *
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+/* Register values */
+
+/* - DR */
+#define	GPIODR				(0x0)
+#define	GPIODRMask			(0xffff)
+#define	GPIODRAccessType		(INITIAL_TEST)
+#define	GPIODRInitialValue		(0x0)
+#define	GPIODRTestMask			(0xffff)
+
+/* - ST */
+#define	GPIOST				(0x4)
+#define	GPIOSTMask			(0xffff)
+#define	GPIOSTAccessType		(NO_TEST)
+#define	GPIOSTInitialValue		(0x0)
+#define	GPIOSTTestMask			(0xffff)
+
+/* - DDR */
+#define	GPIODDR				(0x8)
+#define	GPIODDRMask			(0xffff)
+#define	GPIODDRAccessType		(INITIAL_TEST)
+#define	GPIODDRInitialValue		(0x0)
+#define	GPIODDRTestMask			(0xffff)
+
+/* - FIQ */
+#define	GPIOFIQ				(0xc)
+#define	GPIOFIQMask			(0xffff)
+#define	GPIOFIQAccessType		(INITIAL_TEST)
+#define	GPIOFIQInitialValue		(0x0)
+#define	GPIOFIQTestMask			(0xffff)
+
+/* - IRQ */
+#define	GPIOIRQ				(0x10)
+#define	GPIOIRQMask			(0xffff)
+#define	GPIOIRQAccessType		(INITIAL_TEST)
+#define	GPIOIRQInitialValue		(0x0)
+#define	GPIOIRQTestMask			(0xffff)
+
+/* - INT */
+#define	GPIOINT				(0x14)
+#define	GPIOINTMask			(0xffff)
+#define	GPIOINTAccessType		(NO_TEST)
+#define	GPIOINTInitialValue		(0x0)
+#define	GPIOINTTestMask			(0xffff)
+
+/* - INTCL */
+#define	GPIOINTCL			(0x18)
+#define	GPIOINTCLMask			(0xffff)
+#define	GPIOINTCLAccessType		(WO)
+#define	GPIOINTCLInitialValue		(0x0)
+#define	GPIOINTCLTestMask		(0xffff)
+
+/* - SNR */
+#define	GPIOSNR				(0x1c)
+#define	GPIOSNRMask			(0xffff)
+#define	GPIOSNRAccessType		(INITIAL_TEST)
+#define	GPIOSNRInitialValue		(0x0)
+#define	GPIOSNRTestMask			(0xffff)
+
+/* - EENR */
+#define	GPIOEENR			(0x20)
+#define	GPIOEENRMask			(0xffff)
+#define	GPIOEENRAccessType		(INITIAL_TEST)
+#define	GPIOEENRInitialValue		(0x0)
+#define	GPIOEENRTestMask		(0xffff)
+
+/* - FSEL */
+#define	GPIOFSEL			(0x24)
+#define	GPIOFSELTxUDC			(0x80)
+#define	GPIOFSELRxUDCp			(0x40)
+#define	GPIOFSELRxUDCm			(0x20)
+#define	GPIOFSELBypass			(0x10)
+#define	GPIOFSELTxUDCp			(0x8)
+#define	GPIOFSELTxUDCm			(0x4)
+#define	GPIOFSELUDCEnable		(0x2)
+#define	GPIOFSELUDCSuspend		(0x1)
+#define	GPIOFSELMask			(0xff)
+#define	GPIOFSELAccessType		(INITIAL_TEST)
+#define	GPIOFSELInitialValue		(0x0)
+#define	GPIOFSELTestMask		(0xff)
+
+/* Instance values */
+#define aGPIO1DR			 0x380
+#define aGPIO1ST			 0x384
+#define aGPIO1DDR			 0x388
+#define aGPIO1FIQ			 0x38c
+#define aGPIO1IRQ			 0x390
+#define aGPIO1INT			 0x394
+#define aGPIO1INTCL			 0x398
+#define aGPIO1SNR			 0x39c
+#define aGPIO1EENR			 0x3a0
+#define aGPIO1FSEL			 0x3a4
+#define aGPIO2DR			 0x400
+#define aGPIO2ST			 0x404
+#define aGPIO2DDR			 0x408
+#define aGPIO2FIQ			 0x40c
+#define aGPIO2IRQ			 0x410
+#define aGPIO2INT			 0x414
+#define aGPIO2INTCL			 0x418
+#define aGPIO2SNR			 0x41c
+#define aGPIO2EENR			 0x420
+#define aGPIO2FSEL			 0x424
+#define aGPIO3DR			 0x480
+#define aGPIO3ST			 0x484
+#define aGPIO3DDR			 0x488
+#define aGPIO3FIQ			 0x48c
+#define aGPIO3IRQ			 0x490
+#define aGPIO3INT			 0x494
+#define aGPIO3INTCL			 0x498
+#define aGPIO3SNR			 0x49c
+#define aGPIO3EENR			 0x4a0
+#define aGPIO3FSEL			 0x4a4
+
+#ifndef __ASSEMBLER__
+
+enum
+{
+    GPIO1_PIN_FACTORY_RESET	= 15,
+    GPIO1_PIN_ANT_SEL		= 14,
+    GPIO1_PIN_PE1		= 13,
+    GPIO1_PIN_TR_SW_BAR		= 12,
+    GPIO1_PIN_ANT_SEL_BAR	= 11,
+    GPIO1_PIN_TR_SW		= 10,
+    GPIO1_PIN_PLL_LD		= 9,
+    GPIO1_PIN_PE2		= 8,
+    GPIO1_PIN_HB_LB		= 7,
+    GPIO1_PIN_SYNTH_DATA	= 6,
+    GPIO1_PIN_SYNTH_CLK		= 5,
+    GPIO1_PIN_CB_CLKRUN		= 2,
+    GPIO1_PIN_SYNTH_LE		= 1,
+
+    GPIO3_PIN_PERIPHERAL_RESET	= 7,
+    GPIO3_PIN_UART_TX		= 6,
+    GPIO3_PIN_UART_RX		= 5,
+    GPIO3_PIN_LED4		= 4,
+    GPIO3_PIN_LED3		= 3,
+    GPIO3_PIN_LED2		= 2,
+    GPIO3_PIN_LED1		= 1,
+    GPIO3_PIN_LED0		= 0
+};
+
+enum
+{
+    GPIO1_MASK_FACTORY_RESET	= (1 << GPIO1_PIN_FACTORY_RESET),
+    GPIO1_MASK_ANT_SEL		= (1 << GPIO1_PIN_ANT_SEL),
+    GPIO1_MASK_PE1		= (1 << GPIO1_PIN_PE1),
+    GPIO1_MASK_TR_SW_BAR	= (1 << GPIO1_PIN_TR_SW_BAR),
+    GPIO1_MASK_ANT_SEL_BAR	= (1 << GPIO1_PIN_ANT_SEL_BAR),
+    GPIO1_MASK_TR_SW		= (1 << GPIO1_PIN_TR_SW),
+    GPIO1_MASK_PLL_LD		= (1 << GPIO1_PIN_PLL_LD),
+    GPIO1_MASK_PE2		= (1 << GPIO1_PIN_PE2),
+    GPIO1_MASK_HB_LB		= (1 << GPIO1_PIN_HB_LB),
+    GPIO1_MASK_SYNTH_DATA	= (1 << GPIO1_PIN_SYNTH_DATA),
+    GPIO1_MASK_SYNTH_CLK	= (1 << GPIO1_PIN_SYNTH_CLK),
+    GPIO1_MASK_CB_CLKRUN	= (1 << GPIO1_PIN_CB_CLKRUN),
+    GPIO1_MASK_SYNTH_LE		= (1 << GPIO1_PIN_SYNTH_LE),
+
+    GPIO3_MASK_PERIPHERAL_RESET	= (1 << GPIO3_PIN_PERIPHERAL_RESET),
+    GPIO3_MASK_UART_TX		= (1 << GPIO3_PIN_UART_TX),
+    GPIO3_MASK_UART_RX		= (1 << GPIO3_PIN_UART_RX),
+    GPIO3_MASK_LED4		= (1 << GPIO3_PIN_LED4),
+    GPIO3_MASK_LED3		= (1 << GPIO3_PIN_LED3),
+    GPIO3_MASK_LED2		= (1 << GPIO3_PIN_LED2),
+    GPIO3_MASK_LED1		= (1 << GPIO3_PIN_LED1),
+    GPIO3_MASK_LED0		= (1 << GPIO3_PIN_LED0)    
+};
+
+#define gpio_set( val )         ( (unsigned int) (val) << 16 | (val) )
+#define gpio_clr( val )         ( (unsigned int) (val) << 16         )
+
+/* C struct view */
+typedef struct s_GPIO {
+ unsigned DR; /* @0 */
+ unsigned ST; /* @4 */
+ unsigned DDR; /* @8 */
+ unsigned FIQ; /* @12 */
+ unsigned IRQ; /* @16 */
+ unsigned INT; /* @20 */
+ unsigned INTCL; /* @24 */
+ unsigned SNR; /* @28 */
+ unsigned EENR; /* @32 */
+ unsigned FSEL; /* @36 */
+} s_GPIO;
+
+#endif /* !__ASSEMBLER__ */
+
+#define uGPIO1 ((volatile struct s_GPIO *) 0xc0000380)
+#define uGPIO2 ((volatile struct s_GPIO *) 0xc0000400)
+#define uGPIO3 ((volatile struct s_GPIO *) 0xc0000480)
+
+#endif /* __ASM_ARCH_GPIO_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,77 @@
+/*
+ * uclinux/include/asm-armnommu/arch-isl3893/hardware.h
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <linux/config.h>
+#include <asm/arch/intctl.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/rtc.h>
+
+#ifndef __ASSEMBLER__
+
+#define HARD_RESET_NOW()  { arch_reset('h'); }
+#define ERROR_RESET_NOW()  { arch_reset('e'); }
+
+typedef unsigned long u_32;
+
+/* ARM asynchronous clock */
+#define ARM_CLK ((u_32)(CONFIG_ARM_CLK))
+
+/* ARM synchronous with OAK clock */
+#define A_O_CLK ((u_32)(CONFIG_A_O_CLK))
+
+#else
+#define ARM_CLK CONFIG_ARM_CLK
+#define A_O_CLK CONFIG_A_O_CLK
+#endif
+
+/*
+ * Memory definitions
+ */
+
+#define MAPTOPHYS(a)      ((unsigned long)a)
+#define KERNTOPHYS(a)     ((unsigned long)(&a))
+
+/*
+ * Base address for all Peripherals
+ */
+
+#define PERIPH_BASE         ( 0xc0000000 )  /* used by entry-armv.S */
+
+#define PCIBIOS_MIN_IO		( 0x1000 )
+#define PCIBIOS_MIN_MEM 	( PERIPH_BASE + 0x980 )
+
+#ifdef ISL3893_SIMSONLY
+/*
+ * TUBE
+ */
+#ifndef __ASSEMBLER__
+
+#define TUBEData                        (0x0)
+#define TUBEDataMask                    (0xf)
+#define TUBEDataAccessType              (NO_TEST)
+#define TUBEDataInitialValue            (0x0)
+#define TUBEDataTestMask                (0xf)
+
+/* Instance values */
+#define asicTUBEData                    (0x7fffffc)
+
+/* C struct view */
+
+typedef struct s_TUBE {
+ unsigned char Data; /* @0 */
+} s_TUBE;
+
+#define uTUBE ((volatile struct s_TUBE *) 0x7fffffc)
+
+#else /* __ASSEMBLER__ */
+#define uTUBEData       0x7fffffc
+#endif /* __ASSEMBLER__ */
+
+#endif /* ISL3893_SIMSONLY */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/intctl.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/intctl.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/intctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/intctl.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,142 @@
+/*
+ * include/asm-armnommu/arch-isl3893/intctl.h
+ */
+/*  $Header$
+ *
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef __ASM_ARCH_INTCTL_H
+#define __ASM_ARCH_INTCTL_H
+
+/* Class values */
+#define	IntCtlINTCTL_TICKINT		(0x1)
+#define	IntCtlINTCTL_SOFINT		(0x2)
+#define	IntCtlINTCTL_SRTCEV		(0x4)
+#define	IntCtlINTCTL_PCIRESETINT	(0x8)
+#define	IntCtlINTCTL_GP1FIQINT		(0x10)
+#define	IntCtlINTCTL_GP2FIQINT		(0x20)
+#define	IntCtlINTCTL_PCIINT		(0x40)
+#define	IntCtlINTCTL_BPINT		(0x80)
+#define	IntCtlINTCTL_UARTINT		(0x100)
+#define	IntCtlINTCTL_HOSTTXDMA		(0x200)
+#define	IntCtlINTCTL_HOSTRXDMA		(0x400)
+#define	IntCtlINTCTL_GP1IRQINT		(0x800)
+#define	IntCtlINTCTL_GP2IRQINT		(0x1000)
+#define	IntCtlINTCTL_BPTXDMA		(0x2000)
+#define	IntCtlINTCTL_BPRXDMA		(0x4000)
+#define	IntCtlINTCTL_M2MTXDMA		(0x8000)
+#define	IntCtlINTCTL_M2MRXDMA		(0x10000)
+#define	IntCtlINTCTL_TIM0INT		(0x20000)
+#define	IntCtlINTCTL_TIM1INT		(0x40000)
+#define	IntCtlINTCTL_TIM2INT		(0x80000)
+#define	IntCtlINTCTL_WEPINT		(0x100000)
+#define	IntCtlINTCTL_COMMRX		(0x200000)
+#define	IntCtlINTCTL_COMMTX		(0x400000)
+#define	IntCtlINTCTL_ETH1		(0x800000)
+#define	IntCtlINTCTL_ETH2		(0x1000000)
+#define	IntCtlINTCTL_GP3FIQINT		(0x2000000)
+#define	IntCtlINTCTL_GP3IRQINT		(0x4000000)
+
+/* Register values */
+
+/* - Status */
+#define	IntCtlStatus			(0x0)
+#define	IntCtlStatusMask		(0x7ffffff)
+#define	IntCtlStatusAccessType		(RO)
+#define	IntCtlStatusInitialValue	(0x0)
+#define	IntCtlStatusTestMask		(0x7ffffff)
+
+/* - RawStatus */
+#define	IntCtlRawStatus			(0x4)
+#define	IntCtlRawStatusMask		(0x1ffffff)
+#define	IntCtlRawStatusTestMask		(0x79fffff)
+#define	IntCtlRawStatusInitialValue	(0x8)
+#define	IntCtlRawStatusAccessType	(WO)
+
+/* - EnableSet */
+#define	IntCtlEnableSet			(0x8)
+#define	IntCtlEnableSetMask		(0x7ffffff)
+#define	IntCtlEnableSetTestMask		(0x7ffffff)
+#define	IntCtlEnableSetAccessType	(NO_TEST)
+#define	IntCtlEnableSetInitialValue	(0x0)
+
+/* - EnableClear */
+#define	IntCtlEnableClear		(0xc)
+#define	IntCtlEnableClearMask		(0x7ffffff)
+#define	IntCtlEnableClearAccessType	(WO)
+#define	IntCtlEnableClearInitialValue	(0x0)
+#define	IntCtlEnableClearTestMask	(0x7ffffff)
+
+/* - Soft */
+#define	IntCtlSoft			(0x10)
+#define	IntCtlSoftGenerate		(0x2)
+#define	IntCtlSoftMask			(0x2)
+#define	IntCtlSoftAccessType		(WO)
+#define	IntCtlSoftInitialValue		(0x0)
+#define	IntCtlSoftTestMask		(0x2)
+
+/* - TestInput */
+#define	IntCtlTestInput			(0x14)
+#define	IntCtlTestInputMask		(0x7fffffd)
+#define	IntCtlTestInputInitialValue	(0x0)
+#define	IntCtlTestInputTestMask		(0x7fffffd)
+#define	IntCtlTestInputAccessType	(RW)
+
+/* - TestSel */
+#define	IntCtlTestSel			(0x18)
+#define	IntCtlTestSelMask		(0x1)
+#define	IntCtlTestSelInitialValue	(0x0)
+#define	IntCtlTestSelTestMask		(0x1)
+#define	IntCtlTestSelAccessType		(RW)
+
+/* Instance values */
+#define aIRQStatus			 0
+#define aIRQRawStatus		 0x4
+#define aIRQEnableSet		 0x8
+#define aIRQEnableClear		 0xc
+#define aIRQSoft			 0x10
+#define aIRQTestInput		 0x14
+#define aIRQTestSel			 0x18
+#define aFIQStatus			 0x100
+#define aFIQRawStatus		 0x104
+#define aFIQEnableSet		 0x108
+#define aFIQEnableClear		 0x10c
+#define aFIQSoft			 0x110
+#define aFIQTestInput		 0x114
+#define aFIQTestSel			 0x118
+
+/* C struct view */
+
+#ifndef __ASSEMBLER__
+
+typedef struct s_IntCtl {
+ unsigned Status; /* @0 */
+ unsigned RawStatus; /* @4 */
+ unsigned EnableSet; /* @8 */
+ unsigned EnableClear; /* @12 */
+ unsigned Soft; /* @16 */
+ unsigned TestInput; /* @20 */
+ unsigned TestSel; /* @24 */
+} s_IntCtl;
+
+#endif /* !__ASSEMBLER__ */
+
+#define uIRQ ((volatile struct s_IntCtl *) 0xc0000000)
+#define uFIQ ((volatile struct s_IntCtl *) 0xc0000100)
+
+#endif /* __ASM_ARCH_INTCTL_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/io.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,71 @@
+/*
+ * linux/include/asm-armnommu/arch-isl3893/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ *  02-19-2001  gjm     Leveraged for armnommu/dsc21
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ * --gmcnutt
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * If we define __io then asm/io.h will take care of most of the inb & friends
+ * macros. It still leaves us some 16bit macros to deal with ourselves, though.
+ */
+#define __mem_pci(a)		((unsigned long)(a))
+
+#define PCIO_BASE           0x10000000
+#define PCIO_SIZE           0x1000
+#define PCIO_MEM	       (PCIO_BASE + PCIO_SIZE)
+#define PCIO_MEM_SIZE       0x1000
+
+#define __io(a) (PCIO_BASE + (a))
+
+#ifdef CONFIG_PCI
+
+u8 pci_read_byte( int where );
+u16 pci_read_word( int where );
+u32 pci_read_dword( int where );
+void pci_write_byte( int where, u8 v8 );
+void pci_write_word(int where, u16 v16);
+void pci_write_dword(int where, u32 v32);
+
+/*** 08000000h Flash, 10000000 PCI; uppper limit not checked intentionally (performance)  ***/
+
+#define __arch_getb(a)	    ( (a>=PCIO_BASE) ? pci_read_byte(a)      : (*(volatile unsigned char *)(a))  )
+#define __arch_getw(a)      ( (a>=PCIO_BASE) ? pci_read_word(a)      : (*(volatile unsigned short *)(a)) )
+#define __arch_getl(a)		( (a>=PCIO_BASE) ? pci_read_dword(a)     : (*(volatile unsigned long *)(a))  )
+
+#define __arch_putb(v,a)	( (a>=PCIO_BASE) ? pci_write_byte(a, v)  : (*(volatile unsigned char *)(a) = (v))  )
+#define __arch_putw(v,a)    ( (a>=PCIO_BASE) ? pci_write_word(a, v)  : (*(volatile unsigned short *)(a) = (v)) )
+#define __arch_putl(v,a)	( (a>=PCIO_BASE) ? pci_write_dword(a, v) : (*(volatile unsigned long *)(a) = (v))  )
+
+#else
+
+#define __arch_getb(a)      (*(volatile unsigned char *)(a))
+#define __arch_putb(v,a)    (*(volatile unsigned char *)(a) = (v))
+#define __arch_getw(a)      (*(volatile unsigned short *)(a))
+#define __arch_putw(v,a)    (*(volatile unsigned short *)(a) = (v))
+#define __arch_getl(a)      (*(volatile unsigned long *)(a))
+#define __arch_putl(v,a)    (*(volatile unsigned long *)(a) = (v))
+
+#endif
+
+/*
+ * Defining these two gives us ioremap for free. See asm/io.h.
+ * --gmcnutt
+ */
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,60 @@
+/* $Header$
+ *
+ * Copyright (C) 2002 Intersil Americas Inc.
+ *
+ * isl3893-specific IRQ setup.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_ARCH_IRQ_H__
+#define __ASM_ARCH_IRQ_H__
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/intctl.h>
+
+#define fixup_irq(x) (x)
+
+extern void isl3893_mask_irq(unsigned int irq);
+extern void isl3893_unmask_irq(unsigned int irq);
+extern void isl3893_mask_ack_irq(unsigned int irq);
+
+static __inline__ void irq_init_irq(void)
+{
+	int irq;
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok = 1;
+		irq_desc[irq].mask_ack = isl3893_mask_ack_irq;
+		irq_desc[irq].mask = isl3893_mask_irq;
+		irq_desc[irq].unmask = isl3893_unmask_irq;
+	}
+
+	uIRQ->EnableClear = ~0;	/* disable all IRQs */
+	uIRQ->Soft = 0;		/* remove soft IRQ */
+}
+
+#endif /* __ASM_ARCH_IRQ_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/irqs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,54 @@
+/*
+ *  include/asm-armnommu/arch-isl3893/irqs.h
+ *
+ *  $Header$
+ *
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define IRQ_STWDOG		0
+#define IRQ_SOFINT		1
+#define IRQ_RTC			2
+#define IRQ_PCIRESETINT		3
+#define IRQ_GP1FIQINT		4
+#define IRQ_GP2FIQINT		5
+#define IRQ_PCIINT		6
+#define IRQ_BPINT		7
+#define IRQ_UART		8
+#define IRQ_HOSTTXDMA		9
+#define IRQ_HOSTRXDMA		10
+#define IRQ_GP1IRQINT		11
+#define IRQ_GP2IRQINT		12
+#define IRQ_BPTXDMA		13
+#define IRQ_BPRXDMA		14
+#define IRQ_M2MTXDMA		15
+#define IRQ_M2MRXDMA		16
+#define IRQ_TIM0INT		17
+#define IRQ_TIM1INT		18
+#define IRQ_TIM2INT		19
+#define IRQ_WEPINT		20
+#define IRQ_COMMRX		21
+#define IRQ_COMMTX		22
+#define IRQ_ETH1		23
+#define IRQ_ETH2		24
+
+#define NR_IRQS			( IRQ_ETH2 + 1)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,49 @@
+/*  $Header$
+ *
+ * linux/include/asm-armnommu/arch-isl3893/memory.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * Copyright (c) 2001 RidgeRun <www.ridgerun.com>
+ * Copyright (C) 2002 Intersil Americas Inc.
+ *
+ * 02/19/2001  Gordon McNutt  Leveraged for the dsc21.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+
+/*
+ * TASK_SIZE is the maximum size of a user process in bytes.
+ * In case of an MMU, user space always starts at zero, so this is
+ * the maximum address that a user process can access+1. Any virtual
+ * address below TASK_SIZE is deemed to be user process	area, and
+ * anything above TASK_SIZE is the kernel segment.
+ * In the NO_MM case, this cannot be said, because kernel and user space
+ * can be anywhere in physical memory. Therefore, we define TASK_SIZE as
+ * the highest possible memory address. It might be better to remove this
+ * check in the source for the NO_MM case.
+ */
+#define TASK_SIZE		0xFFFFFFFF
+#define TASK_SIZE_26	TASK_SIZE
+
+
+/*
+ * The start of physical memory. This is the first SDRAM address.
+ * This value is used in the arch-specific bootup code like setup_arch &
+ * bootmem_init. By default we assume that we have one block of contiguous
+ * memory (a node) that starts here and runs MEM_SIZE long (see below). By
+ * default the ARM bootup code sets MEM_SIZE to be 16MB  which is just right for
+ * us (see arch/armnommu/kernel/setup.c).
+ *
+ */
+#define PHYS_OFFSET	DRAM_BASE
+
+/*
+ * PAGE_OFFSET -- Virtual start address of the first bank of RAM. For archs with
+ * no MMU this corresponds to the first free page in physical memory (aligned
+ * on a page boundary).
+ */
+#define PAGE_OFFSET	PHYS_OFFSET
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/mmu.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/mmu.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/mmu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/mmu.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,20 @@
+/*
+ * uclinux/include/asm-armnommu/arch-isl3893/mmu.h
+ *
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) vpage
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ppage
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(vpage) vpage
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(ppage) ppage
+
+#define __flush_entry_to_
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/mpu.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/mpu.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/mpu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/mpu.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,55 @@
+/*
+ * linux/include/asm-armnommu/arch-isl3893/mpu.h
+ *
+ * ISL3893 (ARM946) Memory Protection Unit support.
+ */
+/*  $Header$
+ *
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef __ASM_ARCH_MPU_H
+#define __ASM_ARCH_MPU_H
+#include <asm/proc-fns.h>
+
+#define MAX_ACTIVE_MPU_AREAS		4	/* We use area 4-7, area 0-3 are for the MVC */
+#define MAX_STATIC_USER_MPU_AREAS	2	/* Static areas for Text and Data/stack/BSS */
+/* Max number of areas we allow. Increasing this value will cost performance, but gives greater
+ * flexibility. This value is chosen such that the mpu_context_t struct is a multiple of
+ * a cacheline (4 words)
+ */
+#define MAX_USER_MPU_AREAS		30
+
+struct mpu_context_t
+{
+   unsigned long mpu_reg[MAX_USER_MPU_AREAS];
+   unsigned long switch_idx;
+   unsigned long reprogram_count;
+};
+
+static inline void program_mpu_areas( struct mpu_context_t *mpu_context )
+{
+	__asm__ __volatile__ ("mcr p15, 0, %0, c6, c4, 0 " : : "r" (mpu_context->mpu_reg[0]));
+	__asm__ __volatile__ ("mcr p15, 0, %0, c6, c5, 0 " : : "r" (mpu_context->mpu_reg[1]));
+	__asm__ __volatile__ ("mcr p15, 0, %0, c6, c6, 0 " : : "r" (mpu_context->mpu_reg[2]));
+	__asm__ __volatile__ ("mcr p15, 0, %0, c6, c7, 0 " : : "r" (mpu_context->mpu_reg[3]));
+
+	/* We have to flush the cache after an MPU switch */
+	cpu_cache_clean_invalidate_all();
+}
+
+#endif /* __ASM_ARCH_MPU_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/param.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/pci.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/pci.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/pci.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,393 @@
+#ifndef __PCI_h
+#define __PCI_h
+
+/* Class values */
+
+/* Register values */
+
+/* - ARMIntReg */
+#define	PCIARMIntReg			(0x0)
+#define	PCIARMIntRegMASTERCOMPLETE	(0x80000000)
+#define	PCIARMIntRegPM_STATUS_CHANGE	(0x40000000)
+#define	PCIARMIntRegPME_CLEAR_EVENT	(0x20000000)
+#define	PCIARMIntRegPME_ENABLE_CHANGE	(0x10000000)
+#define	PCIARMIntRegPCI_FATAL_ERROR	(0x8000000)
+#define	PCIARMIntRegPCI_PARITY_ERROR	(0x4000000)
+#define	PCIARMIntRegARM_ASLEEP		(0x2000000)
+#define	PCIARMIntRegPCI_UNDER_RUN	(0x1000000)
+#define	PCIARMIntRegCLKRUN_CHANGE	(0x800000)
+#define	PCIARMIntRegHOSTMSG		(0xffff)
+#define	PCIARMIntRegHOSTMSGShift	(0x0)
+#define	PCIARMIntRegMask		(0xff80ffff)
+#define	PCIARMIntRegTestMask		(0xefffffff)
+#define	PCIARMIntRegAccessType		(RO)
+#define	PCIARMIntRegInitialValue	(0x0)
+
+/* - ARMIntAckReg */
+#define	PCIARMIntAckReg			(0x4)
+#define	PCIARMIntAckRegMASTERCOMPLETE	(0x80000000)
+#define	PCIARMIntAckRegPM_STATUS_CHANGE	(0x40000000)
+#define	PCIARMIntAckRegPME_CLEAR_EVENT	(0x20000000)
+#define	PCIARMIntAckRegPME_ENABLE_CHANGE	(0x10000000)
+#define	PCIARMIntAckRegPCI_FATAL_ERROR	(0x8000000)
+#define	PCIARMIntAckRegPCI_PARITY_ERROR	(0x4000000)
+#define	PCIARMIntAckRegARM_ASLEEP	(0x2000000)
+#define	PCIARMIntAckRegHOSTMSG		(0xffff)
+#define	PCIARMIntAckRegHOSTMSGShift	(0x0)
+#define	PCIARMIntAckRegMask		(0xfe00ffff)
+#define	PCIARMIntAckRegAccessType	(WO)
+#define	PCIARMIntAckRegInitialValue	(0x0)
+#define	PCIARMIntAckRegTestMask		(0xfe00ffff)
+
+/* - ARMIntEnReg */
+#define	PCIARMIntEnReg			(0x8)
+#define	PCIARMIntEnRegMASTERCOMPLETE	(0x80000000)
+#define	PCIARMIntEnRegPM_STATUS_CHANGE	(0x40000000)
+#define	PCIARMIntEnRegPME_CLEAR_EVENT	(0x20000000)
+#define	PCIARMIntEnRegPME_ENABLE_CHANGE	(0x10000000)
+#define	PCIARMIntEnRegPCI_FATAL_ERROR	(0x8000000)
+#define	PCIARMIntEnRegPCI_PARITY_ERROR	(0x4000000)
+#define	PCIARMIntEnRegARM_ASLEEP	(0x2000000)
+#define	PCIARMIntEnRegHOSTMSG		(0xffff)
+#define	PCIARMIntEnRegHOSTMSGShift	(0x0)
+#define	PCIARMIntEnRegMask		(0xfe00ffff)
+#define	PCIARMIntEnRegTestMask		(0xefffffff)
+#define	PCIARMIntEnRegAccessType	(RW)
+#define	PCIARMIntEnRegInitialValue	(0x0)
+
+/* - Fill0x0C */
+#define	PCIFill0x0C			(0xc)
+#define	PCIFill0x0CAccessType		(NO_TEST)
+#define	PCIFill0x0CInitialValue		(0x0)
+#define	PCIFill0x0CMask			(0xffffffff)
+#define	PCIFill0x0CTestMask		(0xffffffff)
+
+/* - HostIntReg */
+#define	PCIHostIntReg			(0x10)
+#define	PCIHostIntRegMASTERCOMPLETE	(0x80000000)
+#define	PCIHostIntRegSWRESET		(0x40000000)
+#define	PCIHostIntRegTIMERRESET		(0x20000000)
+#define	PCIHostIntRegARM_ASLEEP		(0x10000000)
+#define	PCIHostIntRegASSERT_PME		(0x8000000)
+#define	PCIHostIntRegHOSTMSG		(0xffff)
+#define	PCIHostIntRegHOSTMSGShift	(0x0)
+#define	PCIHostIntRegMask		(0xf800ffff)
+#define	PCIHostIntRegTestMask		(0xffff)
+#define	PCIHostIntRegAccessType		(NO_TEST)
+#define	PCIHostIntRegInitialValue	(0x0)
+
+/* - HostIntAckReg */
+#define	PCIHostIntAckReg		(0x14)
+#define	PCIHostIntAckRegMASTERCOMPLETE	(0x80000000)
+#define	PCIHostIntAckRegSWRESET		(0x40000000)
+#define	PCIHostIntAckRegTIMERRESET	(0x20000000)
+#define	PCIHostIntAckRegARM_ASLEEP	(0x10000000)
+#define	PCIHostIntAckRegASSERT_PME	(0x8000000)
+#define	PCIHostIntAckRegHOSTMSG		(0xffff)
+#define	PCIHostIntAckRegHOSTMSGShift	(0x0)
+#define	PCIHostIntAckRegMask		(0xf800ffff)
+#define	PCIHostIntAckRegAccessType	(NO_TEST)
+#define	PCIHostIntAckRegInitialValue	(0x0)
+#define	PCIHostIntAckRegTestMask	(0xf800ffff)
+
+/* - HostIntEnReg */
+#define	PCIHostIntEnReg			(0x18)
+#define	PCIHostIntEnRegMASTERCOMPLETE	(0x80000000)
+#define	PCIHostIntEnRegSWRESET		(0x40000000)
+#define	PCIHostIntEnRegTIMERRESET	(0x20000000)
+#define	PCIHostIntEnRegARM_ASLEEP	(0x10000000)
+#define	PCIHostIntEnRegASSERT_PME	(0x8000000)
+#define	PCIHostIntEnRegHOSTMSG		(0xffff)
+#define	PCIHostIntEnRegHOSTMSGShift	(0x0)
+#define	PCIHostIntEnRegMask		(0xf800ffff)
+#define	PCIHostIntEnRegAccessType	(RO)
+#define	PCIHostIntEnRegInitialValue	(0x0)
+#define	PCIHostIntEnRegTestMask		(0xf800ffff)
+
+/* - Fill0x1C */
+#define	PCIFill0x1C			(0x1c)
+#define	PCIFill0x1CAccessType		(NO_TEST)
+#define	PCIFill0x1CInitialValue		(0x0)
+#define	PCIFill0x1CMask			(0xffffffff)
+#define	PCIFill0x1CTestMask		(0xffffffff)
+
+/* - GenPurpComReg1 */
+#define	PCIGenPurpComReg1		(0x20)
+#define	PCIGenPurpComReg1InitialValue	(0x12345678)
+#define	PCIGenPurpComReg1AccessType	(RW)
+#define	PCIGenPurpComReg1Mask		(0xffffffff)
+#define	PCIGenPurpComReg1TestMask	(0xffffffff)
+
+/* - GenPurpComReg2 */
+#define	PCIGenPurpComReg2		(0x24)
+#define	PCIGenPurpComReg2AccessType	(RW)
+#define	PCIGenPurpComReg2InitialValue	(0x0)
+#define	PCIGenPurpComReg2Mask		(0xffffffff)
+#define	PCIGenPurpComReg2TestMask	(0xffffffff)
+
+/* - Fill0x28 */
+#define	PCIFill0x28			(0x28)
+#define	PCIFill0x28AccessType		(NO_TEST)
+#define	PCIFill0x28InitialValue		(0x0)
+#define	PCIFill0x28Mask			(0xffffffff)
+#define	PCIFill0x28TestMask		(0xffffffff)
+
+/* - Fill0x2C */
+#define	PCIFill0x2C			(0x2c)
+#define	PCIFill0x2CAccessType		(NO_TEST)
+#define	PCIFill0x2CInitialValue		(0x0)
+#define	PCIFill0x2CMask			(0xffffffff)
+#define	PCIFill0x2CTestMask		(0xffffffff)
+
+/* - DirectMemBase */
+#define	PCIDirectMemBase		(0x30)
+#define	PCIDirectMemBaseAccessType	(RW)
+#define	PCIDirectMemBaseInitialValue	(0x0)
+#define	PCIDirectMemBaseMask		(0xffffffff)
+#define	PCIDirectMemBaseTestMask	(0xffffffff)
+
+/* - DirectMemEn */
+#define	PCIDirectMemEn			(0x34)
+#define	PCIDirectMemEnMask		(0xfff)
+#define	PCIDirectMemEnInitialValue	(0xfff)
+#define	PCIDirectMemEnAccessType	(RW)
+#define	PCIDirectMemEnTestMask		(0xfff)
+
+/* - Fill0x38 */
+#define	PCIFill0x38			(0x38)
+#define	PCIFill0x38AccessType		(NO_TEST)
+#define	PCIFill0x38InitialValue		(0x0)
+#define	PCIFill0x38Mask			(0xffffffff)
+#define	PCIFill0x38TestMask		(0xffffffff)
+
+/* - Fill0x3C */
+#define	PCIFill0x3C			(0x3c)
+#define	PCIFill0x3CAccessType		(NO_TEST)
+#define	PCIFill0x3CInitialValue		(0x0)
+#define	PCIFill0x3CMask			(0xffffffff)
+#define	PCIFill0x3CTestMask		(0xffffffff)
+
+/* - EventReg */
+#define	PCIEventReg			(0x40)
+#define	PCIEventRegAccessType		(RO)
+#define	PCIEventRegInitialValue		(0x0)
+#define	PCIEventRegMask			(0xffffffff)
+#define	PCIEventRegTestMask		(0xffffffff)
+
+/* - EventMask */
+#define	PCIEventMask			(0x44)
+#define	PCIEventMaskAccessType		(RO)
+#define	PCIEventMaskInitialValue	(0x0)
+#define	PCIEventMaskMask		(0xffffffff)
+#define	PCIEventMaskTestMask		(0xffffffff)
+
+/* - PresStateReg */
+#define	PCIPresStateReg			(0x48)
+#define	PCIPresStateRegINTR		(0x8000)
+#define	PCIPresStateRegWKUP		(0x4000)
+#define	PCIPresStateRegPWM		(0x40)
+#define	PCIPresStateRegBAM		(0x20)
+#define	PCIPresStateRegGWAKE		(0x10)
+#define	PCIPresStateRegBVD2		(0x8)
+#define	PCIPresStateRegBVD1		(0x4)
+#define	PCIPresStateRegREADY		(0x2)
+#define	PCIPresStateRegWP		(0x1)
+#define	PCIPresStateRegMask		(0xc07f)
+#define	PCIPresStateRegInitialValue	(0xe)
+#define	PCIPresStateRegAccessType	(RW)
+#define	PCIPresStateRegTestMask		(0xc07f)
+
+/* - Fill0x4C */
+#define	PCIFill0x4C			(0x4c)
+#define	PCIFill0x4CAccessType		(NO_TEST)
+#define	PCIFill0x4CInitialValue		(0x0)
+#define	PCIFill0x4CMask			(0xffffffff)
+#define	PCIFill0x4CTestMask		(0xffffffff)
+
+/* - ConfigLoadReg */
+#define	PCIConfigLoadReg		(0x50)
+#define	PCIConfigLoadRegMask		(0x8000ffff)
+#define	PCIConfigLoadRegAccessType	(WO)
+#define	PCIConfigLoadRegInitialValue	(0x0)
+#define	PCIConfigLoadRegTestMask	(0x8000ffff)
+
+/* - Fill0x54 */
+#define	PCIFill0x54			(0x54)
+#define	PCIFill0x54AccessType		(NO_TEST)
+#define	PCIFill0x54InitialValue		(0x0)
+#define	PCIFill0x54Mask			(0xffffffff)
+#define	PCIFill0x54TestMask		(0xffffffff)
+
+/* - Fill0x58 */
+#define	PCIFill0x58			(0x58)
+#define	PCIFill0x58AccessType		(NO_TEST)
+#define	PCIFill0x58InitialValue		(0x0)
+#define	PCIFill0x58Mask			(0xffffffff)
+#define	PCIFill0x58TestMask		(0xffffffff)
+
+/* - Fill0x5C */
+#define	PCIFill0x5C			(0x5c)
+#define	PCIFill0x5CAccessType		(NO_TEST)
+#define	PCIFill0x5CInitialValue		(0x0)
+#define	PCIFill0x5CMask			(0xffffffff)
+#define	PCIFill0x5CTestMask		(0xffffffff)
+
+/* - MasHostMemAddr */
+#define	PCIMasHostMemAddr		(0x60)
+#define	PCIMasHostMemAddrAccessType	(RW)
+#define	PCIMasHostMemAddrInitialValue	(0x0)
+#define	PCIMasHostMemAddrMask		(0xffffffff)
+#define	PCIMasHostMemAddrTestMask	(0xffffffff)
+
+/* - MasLenReg */
+#define	PCIMasLenReg			(0x64)
+#define	PCIMasLenRegMask		(0xff)
+#define	PCIMasLenRegAccessType		(RW)
+#define	PCIMasLenRegInitialValue	(0x0)
+#define	PCIMasLenRegTestMask		(0xff)
+
+/* - MasControlReg */
+#define	PCIMasControlReg		(0x68)
+#define	PCIMasControlRegPME_ENABLE	(0x40000000)
+#define	PCIMasControlRegPOWER_STAT	(0x30000000)
+#define	PCIMasControlRegPOWER_STATShift	(0x1c)
+#define	PCIMasControlRegPME_CLEAR	(0x8000000)
+#define	PCIMasControlRegIGNORELENGTH	(0x80)
+#define	PCIMasControlRegUSEDATAREG	(0x10)
+#define	PCIMasControlRegTOHOST		(0x8)
+#define	PCIMasControlRegENABLE		(0x4)
+#define	PCIMasControlRegSpecialMode	(0x2)
+#define	PCIMasControlRegNoAddrIncr	(0x1)
+#define	PCIMasControlRegMask		(0x7800009f)
+#define	PCIMasControlRegTestMask	(0x9c)
+#define	PCIMasControlRegAccessType	(RW)
+#define	PCIMasControlRegInitialValue	(0x0)
+
+/* - Fill0x6C */
+#define	PCIFill0x6C			(0x6c)
+#define	PCIFill0x6CAccessType		(NO_TEST)
+#define	PCIFill0x6CInitialValue		(0x0)
+#define	PCIFill0x6CMask			(0xffffffff)
+#define	PCIFill0x6CTestMask		(0xffffffff)
+
+/* - MasDataReg */
+#define	PCIMasDataReg			(0x70)
+#define	PCIMasDataRegAccessType		(RW)
+#define	PCIMasDataRegInitialValue	(0x0)
+#define	PCIMasDataRegMask		(0xffffffff)
+#define	PCIMasDataRegTestMask		(0xffffffff)
+
+/* - MasOptReg */
+#define	PCIMasOptReg			(0x74)
+#define	PCIMasOptRegOPTIONENABLE	(0x80000000)
+#define	PCIMasOptRegBE			(0xf0)
+#define	PCIMasOptRegBEShift		(0x4)
+#define	PCIMasOptRegCMD			(0xf)
+#define	PCIMasOptRegCMDShift		(0x0)
+#define	PCIMasOptRegMask		(0x800000ff)
+#define	PCIMasOptRegAccessType		(RW)
+#define	PCIMasOptRegInitialValue	(0x0)
+#define	PCIMasOptRegTestMask		(0x800000ff)
+
+/* - DevStatReg */
+#define	PCIDevStatReg			(0x78)
+#define	PCIDevStatRegSetHostOverride	(0x80000000)
+#define	PCIDevStatRegSetStartHalted	(0x40000000)
+#define	PCIDevStatRegSetRAMBoot		(0x20000000)
+#define	PCIDevStatRegSetHostReset	(0x10000000)
+#define	PCIDevStatRegSetHostCpuEn	(0x8000000)
+#define	PCIDevStatRegSetBootBank	(0x6000000)
+#define	PCIDevStatRegSetBootBankShift	(0x19)
+#define	PCIDevStatRegSetTargetDMA	(0x1000000)
+#define	PCIDevStatRegSetPCIDriveCLKRUN_N	(0x800000)
+#define	PCIDevStatRegStartHalted	(0x10000)
+#define	PCIDevStatRegRestartAsserted	(0x8000)
+#define	PCIDevStatRegPciResetInterrupt	(0x4000)
+#define	PCIDevStatRegSoftRes		(0x2000)
+#define	PCIDevStatRegRTCRes		(0x1000)
+#define	PCIDevStatRegHardRes		(0x800)
+#define	PCIDevStatRegHostRes		(0x400)
+#define	PCIDevStatRegSleepMode		(0x200)
+#define	PCIDevStatRegClockDivisor	(0x1ff)
+#define	PCIDevStatRegClockDivisorShift	(0x0)
+#define	PCIDevStatRegMask		(0xff81ffff)
+#define	PCIDevStatRegAccessType		(NO_TEST)
+#define	PCIDevStatRegInitialValue	(0x0)
+#define	PCIDevStatRegTestMask		(0xff81ffff)
+
+/* Instance values */
+#define aPCIARMIntReg		 0x980
+#define aPCIARMIntAckReg		 0x984
+#define aPCIARMIntEnReg		 0x988
+#define aPCIFill0x0C			 0x98c
+#define aPCIHostIntReg		 0x990
+#define aPCIHostIntAckReg		 0x994
+#define aPCIHostIntEnReg		 0x998
+#define aPCIFill0x1C			 0x99c
+#define aPCIGenPurpComReg1		 0x9a0
+#define aPCIGenPurpComReg2		 0x9a4
+#define aPCIFill0x28			 0x9a8
+#define aPCIFill0x2C			 0x9ac
+#define aPCIDirectMemBase		 0x9b0
+#define aPCIDirectMemEn		 0x9b4
+#define aPCIFill0x38			 0x9b8
+#define aPCIFill0x3C			 0x9bc
+#define aPCIEventReg			 0x9c0
+#define aPCIEventMask		 0x9c4
+#define aPCIPresStateReg		 0x9c8
+#define aPCIFill0x4C			 0x9cc
+#define aPCIConfigLoadReg		 0x9d0
+#define aPCIFill0x54			 0x9d4
+#define aPCIFill0x58			 0x9d8
+#define aPCIFill0x5C			 0x9dc
+#define aPCIMasHostMemAddr		 0x9e0
+#define aPCIMasLenReg		 0x9e4
+#define aPCIMasControlReg		 0x9e8
+#define aPCIFill0x6C			 0x9ec
+#define aPCIMasDataReg		 0x9f0
+#define aPCIMasOptReg		 0x9f4
+#define aPCIDevStatReg		 0x9f8
+
+/* C struct view */
+
+#ifndef __ASSEMBLER__
+
+typedef struct s_PCI {
+ unsigned ARMIntReg; /* @0 */
+ unsigned ARMIntAckReg; /* @4 */
+ unsigned ARMIntEnReg; /* @8 */
+ unsigned Fill0x0C; /* @12 */
+ unsigned HostIntReg; /* @16 */
+ unsigned HostIntAckReg; /* @20 */
+ unsigned HostIntEnReg; /* @24 */
+ unsigned Fill0x1C; /* @28 */
+ unsigned GenPurpComReg1; /* @32 */
+ unsigned GenPurpComReg2; /* @36 */
+ unsigned Fill0x28; /* @40 */
+ unsigned Fill0x2C; /* @44 */
+ unsigned DirectMemBase; /* @48 */
+ unsigned DirectMemEn; /* @52 */
+ unsigned Fill0x38; /* @56 */
+ unsigned Fill0x3C; /* @60 */
+ unsigned EventReg; /* @64 */
+ unsigned EventMask; /* @68 */
+ unsigned PresStateReg; /* @72 */
+ unsigned Fill0x4C; /* @76 */
+ unsigned ConfigLoadReg; /* @80 */
+ unsigned Fill0x54; /* @84 */
+ unsigned Fill0x58; /* @88 */
+ unsigned Fill0x5C; /* @92 */
+ unsigned MasHostMemAddr; /* @96 */
+ unsigned MasLenReg; /* @100 */
+ unsigned MasControlReg; /* @104 */
+ unsigned Fill0x6C; /* @108 */
+ unsigned MasDataReg; /* @112 */
+ unsigned MasOptReg; /* @116 */
+ unsigned DevStatReg; /* @120 */
+} s_PCI;
+
+#endif /* !__ASSEMBLER__ */
+
+#define uPCI ((volatile struct s_PCI *) 0xc0000980)
+
+#endif /* !defined(__PCI_h) */
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/processor.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/processor.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/processor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,20 @@
+/* $Header$
+ *
+ * uclinux/include/asm-armnommu/arch-isl3893/processor.h
+ *
+ * Copyright (C) 2002 Intersil Americas Inc.
+ *
+ */
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+#define EISA_bus 0
+#define EISA_bus__is_a_macro
+#define MCA_bus 0
+#define MCA_bus__is_a_macro
+
+#define INIT_MMAP { \
+  &init_mm, 0, 0x02000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC \
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/rtc.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/rtc.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/rtc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/rtc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,98 @@
+/*
+ * include/asm-armnommu/arch-isl3893/rtc.h
+ */
+/*  $Header$
+ *
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef __ASM_ARCH_RTC_H
+#define __ASM_ARCH_RTC_H
+
+/* Register values */
+
+/* - Data */
+#define	RTCData				(0x0)
+#define	RTCDataMask			(0xffffffff)
+#define	RTCDataTestMask			(0xfffffff0)
+#define	RTCDataAccessType		(RW)
+#define	RTCDataInitialValue		(0x0)
+
+/* - Match */
+#define	RTCMatch			(0x4)
+#define	RTCMatchMask			(0xffffffff)
+#define	RTCMatchAccessType		(RW)
+#define	RTCMatchInitialValue		(0x0)
+#define	RTCMatchTestMask		(0xffffffff)
+
+/* - IntControl */
+#define	RTCIntControl			(0x8)
+#define	RTCIntControlBypassClkDivider	(0x10)
+#define	RTCIntControlBypass1Mhz		(0x8)
+#define	RTCIntControlSTBARK		(0x4)
+#define	RTCIntControlTICK		(0x2)
+#define	RTCIntControlEVENT		(0x1)
+#define	RTCIntControlMask		(0x1f)
+#define	RTCIntControlTestMask		(0x1b)
+#define	RTCIntControlInitialValue	(0x0)
+#define	RTCIntControlAccessType		(RW)
+
+/* - IntStatus */
+#define	RTCIntStatus			(0xc)
+#define	RTCIntStatusSTBARK		(0x4)
+#define	RTCIntStatusTICK		(0x2)
+#define	RTCIntStatusEVENT		(0x1)
+#define	RTCIntStatusMask		(0x7)
+#define	RTCIntStatusAccessType		(NO_TEST)
+#define	RTCIntStatusInitialValue	(0x0)
+#define	RTCIntStatusTestMask		(0x7)
+
+/* - IntClear */
+#define	RTCIntClear			(0x14)
+#define	RTCIntClearSTBARK		(0x4)
+#define	RTCIntClearTICK			(0x2)
+#define	RTCIntClearEVENT		(0x1)
+#define	RTCIntClearMask			(0x7)
+#define	RTCIntClearAccessType		(WO)
+#define	RTCIntClearInitialValue		(0x0)
+#define	RTCIntClearTestMask		(0x7)
+
+/* Instance values */
+#define aRTCData			 0x280
+#define aRTCMatch			 0x284
+#define aRTCIntControl			 0x288
+#define aRTCIntStatus			 0x290
+#define aRTCIntClear			 0x294
+
+/* C struct view */
+
+#ifndef __ASSEMBLER__
+
+typedef struct s_RTC {
+ unsigned Data; /* @0 */
+ unsigned Match; /* @4 */
+ unsigned IntControl; /* @8 */
+ unsigned fill0;
+ unsigned IntStatus; /* @16 */
+ unsigned IntClear; /* @20 */
+} s_RTC;
+
+#endif /* !__ASSEMBLER__ */
+
+#define uRTC ((volatile struct s_RTC *) 0xc0000280)
+
+#endif /* __ASM_ARCH_RTC_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/serial.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/serial.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/serial.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,147 @@
+/*
+ * uclinux/include/asm-armnommu/arch-isl3893/serial.h
+ */
+/*  $Header$
+ *
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <linux/serial_reg.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/uart.h>
+
+#ifndef __ASSEMBLER__
+
+/*
+ * Definitions used in drivers/char/serial.c
+ */
+
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+#define BASE_BAUD ( 1843200 / 16 )
+
+#define RS_TABLE_SIZE  1
+#define STD_SERIAL_PORT_DEFNS \
+	{  \
+	magic: 0, \
+	baud_base: BASE_BAUD, \
+	port: (unsigned long)uUART, \
+	irq: IRQ_UART, \
+	flags: STD_COM_FLAGS \
+	}       /* ttyS0 */
+#define EXTRA_SERIAL_PORT_DEFNS
+
+static inline void uart_initialize(void)
+{
+	unsigned baud_div = (66000000 / BASE_BAUD + 8) / 16;
+
+	uGPIO3->FSEL = gpio_set( GPIO3_MASK_UART_RX | GPIO3_MASK_UART_TX );
+	/* Load the Divisor Latch. Note that Register0 and InterruptEnable
+	 * are shared registers.
+	 */
+	uUART->LineControl = UARTLineControlDLAB;
+	uUART->Register0 = baud_div;
+	uUART->InterruptEnable = baud_div >> 8;
+	uUART->ModemControl = 0;
+	uUART->LineControl = 3;	// 8 bits, 1 stop, no parity
+}
+
+static inline unsigned char uart_rx(void)
+{
+	return (unsigned char)uUART->Register0;
+}
+
+static inline void uart_tx(unsigned char ch)
+{
+	uUART->Register0 = (unsigned int)(ch & 0xff);
+}
+
+#define UART_IRQSTAT_RX(status)		((status & 0x7) == UARTInterrupIDRBFI)
+#define UART_IRQSTAT_TX(status)		((status & 0x7) == UARTInterrupIDTBEI)
+#define UART_IRQSTAT_ANY(status)	(UART_IRQSTAT_RX(status) || UART_IRQSTAT_TX(status))
+
+static inline unsigned int uart_read_irqstat(void)
+{
+	return(uUART->InterrupID & 0x7);
+}
+
+static inline int uart_read_lsr(void)
+{
+	unsigned char uart_status;
+	int status = 0;
+
+	uart_status = uUART->LineStatus;
+	if (uart_status & UARTLineStatusOE)
+		status |= UART_LSR_OE;
+	if (uart_status & UARTLineStatusBI)
+		status |= UART_LSR_BI;
+	if (uart_status & UARTLineStatusPE)
+		status |= UART_LSR_PE;
+	if (uart_status & UARTLineStatusFE)
+		status |= UART_LSR_FE;
+	if (uart_status & UARTLineStatusTEMT)
+		status |= UART_LSR_TEMT;
+	if (uart_status & UARTLineStatusTHRE)
+		status |= UART_LSR_THRE;
+	if (uart_status & UARTLineStatusDR)
+		status |= UART_LSR_DR;
+
+	return status;
+}
+
+static inline void uart_clear_errors(void)
+{
+	/* Errors need not be cleared */
+}
+
+static inline unsigned int uart_save_ier(void)
+{
+	return(uUART->InterruptEnable);
+}
+
+static inline void uart_restore_ier(unsigned int ier)
+{
+	uUART->InterruptEnable = ier;
+}
+
+static inline void uart_interrupt_enable(int interrupt)
+{
+	if(interrupt == UART_IER_THRI)		/* Transmitter holding register int. */
+		uUART->InterruptEnable |= UARTInterruptEnableTBEI;
+	else if(interrupt == UART_IER_RDI)	/* Enable receiver data interrupt */
+		uUART->InterruptEnable |= UARTInterruptEnableRBFI;
+	else
+		printk("uart_interrupt_enable: Unknown Interrupt %d", interrupt);
+}
+
+static inline void uart_interrupt_disable(int interrupt)
+{
+	if(interrupt == UART_IER_THRI)		/* Transmitter holding register int. */
+		uUART->InterruptEnable &= ~UARTInterruptEnableTBEI;
+	else if(interrupt == UART_IER_RDI)	/* Enable receiver data interrupt */
+		uUART->InterruptEnable &= ~UARTInterruptEnableRBFI;
+	else
+		printk("uart_interrupt_disable: Unknown Interrupt %d", interrupt);
+}
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __ASM_ARCH_SERIAL_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/shmparam.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/shmparam.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/shmparam.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,4 @@
+/*
+ * linux/include/asm-arm/arch-isl3893/shmparam.h 
+ *
+ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/system.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-armnommu/arch-isl3893/system.h
+ *
+ *
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+extern int hlt_counter;
+
+static inline void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter);
+}
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/time.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/time.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,53 @@
+/*
+ * linux/include/asm-arm/arch-isl3893/time.h
+ */
+
+#ifndef __ASM_ARCH_TIME_H__
+#define __ASM_ARCH_TIME_H__
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/irq.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/timex.h>
+#include <linux/interrupt.h>
+
+#define KERNEL_TIMER_IRQ_NUM	IRQ_RTC
+
+extern struct irqaction timer_irq;
+extern unsigned long (*gettimeoffset)(void);
+
+extern unsigned long isl3893_gettimeoffset(void);
+extern void isl3893_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+/*
+ * Reset the timer.
+ */
+extern __inline__ int reset_timer(void)
+{
+	uRTC->Data = 0;
+	uRTC->IntClear = RTCIntClearEVENT;
+	return (1);
+}
+
+extern __inline__ void setup_timer (void)
+{
+	gettimeoffset = isl3893_gettimeoffset;
+	timer_irq.name = "timer";
+	timer_irq.handler = isl3893_timer_interrupt;
+	timer_irq.flags = SA_INTERRUPT;
+	setup_arm_irq(KERNEL_TIMER_IRQ_NUM, &timer_irq);
+
+#ifdef ISL3893_SIMSONLY
+/* For simulations, this is a small value. In real life, set this to 10 */
+	uRTC->Match = 2;
+#else
+	uRTC->Match = 10;
+#endif
+	uRTC->Data = 0;
+	uRTC->IntClear = RTCIntClearEVENT;
+	uRTC->IntControl |= RTCIntControlEVENT;
+}
+
+#endif /* __ASM_ARCH_TIME_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ * timex.h:
+ *         System clock frequency.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+/*
+ * CLOCK_TICK_RATE -- frequency fed to the timer. In our case, 27MHz. Used to
+ * compute LATCH. LATCH is the number of clock ticks per timer interrupt.
+ * (See linux/timex.h, armnommu/mach-dsc21/time.c).
+ */
+#define CLOCK_TICK_RATE	   CONFIG_ARM_CLK
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/uart.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/uart.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/uart.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/uart.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,160 @@
+/*
+ * include/asm-armnommu/arch-isl3893/uart.h
+ */
+/*  $Header$
+ *
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License
+ *
+ *  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
+ *
+ */
+
+#ifndef __ASM_ARCH_UART_H
+#define __ASM_ARCH_UART_H
+
+/* Class values */
+
+/* Register values */
+
+/* - Register0 */
+#define	UARTRegister0			(0x0)
+#define	UARTRegister0AccessType		(NO_TEST)
+#define	UARTRegister0InitialValue	(0x0)
+#define	UARTRegister0Mask		(0xffffffff)
+#define	UARTRegister0TestMask		(0xffffffff)
+
+/* - InterruptEnable */
+#define	UARTInterruptEnable		(0x4)
+#define	UARTInterruptEnableMask		(0xf)
+#define	UARTInterruptEnableDSSI		(0x8)
+#define	UARTInterruptEnableLSI		(0x4)
+#define	UARTInterruptEnableTBEI		(0x2)
+#define	UARTInterruptEnableRBFI		(0x1)
+#define	UARTInterruptEnableMask		(0xf)
+#define	UARTInterruptEnableAccessType	(RW)
+#define	UARTInterruptEnableInitialValue	(0x0)
+#define	UARTInterruptEnableTestMask	(0xf)
+
+/* - InterrupID */
+#define	UARTInterrupID			(0x8)
+#define	UARTInterrupIDMask		(0x7)
+#define	UARTInterrupIDIIR		(0x7)
+#define	UARTInterrupIDIIRShift		(0x0)
+#define	UARTInterrupIDMask		(0x7)
+#define	UARTInterrupIDNoInt		(0x1)
+#define	UARTInterrupIDDSSI		(0x0)
+#define	UARTInterrupIDTBEI		(0x2)
+#define	UARTInterrupIDRBFI		(0x4)
+#define	UARTInterrupIDLSI		(0x6)
+#define	UARTInterrupIDInitialValue	(0x1)
+#define	UARTInterrupIDAccessType	(RO)
+#define	UARTInterrupIDTestMask		(0x7)
+
+/* - LineControl */
+#define	UARTLineControl			(0xc)
+#define	UARTLineControlMask		(0xff)
+#define	UARTLineControlDLAB		(0x80)
+#define	UARTLineControlBREAK		(0x40)
+#define	UARTLineControlSTICK		(0x20)
+#define	UARTLineControlEPS		(0x10)
+#define	UARTLineControlPEN		(0x8)
+#define	UARTLineControlSTOP		(0x4)
+#define	UARTLineControlWLS		(0x3)
+#define	UARTLineControlWLSShift		(0x0)
+#define	UARTLineControlMask		(0xff)
+#define	UARTLineControlAccessType	(RW)
+#define	UARTLineControlInitialValue	(0x0)
+#define	UARTLineControlTestMask		(0xff)
+
+/* - ModemControl */
+#define	UARTModemControl		(0x10)
+#define	UARTModemControlMask		(0x1b)
+#define	UARTModemControlLB		(0x10)
+#define	UARTModemControlOUT2		(0x8)
+#define	UARTModemControlRTS		(0x2)
+#define	UARTModemControlDTR		(0x1)
+#define	UARTModemControlMask		(0x1b)
+#define	UARTModemControlAccessType	(RW)
+#define	UARTModemControlInitialValue	(0x0)
+#define	UARTModemControlTestMask	(0x1b)
+
+/* - LineStatus */
+#define	UARTLineStatus			(0x14)
+#define	UARTLineStatusMask		(0x7f)
+#define	UARTLineStatusTEMT		(0x40)
+#define	UARTLineStatusTHRE		(0x20)
+#define	UARTLineStatusBI		(0x10)
+#define	UARTLineStatusFE		(0x8)
+#define	UARTLineStatusPE		(0x4)
+#define	UARTLineStatusOE		(0x2)
+#define	UARTLineStatusDR		(0x1)
+#define	UARTLineStatusMask		(0x7f)
+#define	UARTLineStatusInitialValue	(0x60)
+#define	UARTLineStatusAccessType	(RO)
+#define	UARTLineStatusTestMask		(0x7f)
+
+/* - ModemStatus */
+#define	UARTModemStatus			(0x18)
+#define	UARTModemStatusMask		(0xbb)
+#define	UARTModemStatusTestMask		(0xb0)
+#define	UARTModemStatusInitialValue	(0x0)
+#define	UARTModemStatusDCD		(0x80)
+#define	UARTModemStatusDSR		(0x20)
+#define	UARTModemStatusCTS		(0x10)
+#define	UARTModemStatusDDCD		(0x8)
+#define	UARTModemStatusDDSR		(0x2)
+#define	UARTModemStatusDCTS		(0x1)
+#define	UARTModemStatusMask		(0xbb)
+#define	UARTModemStatusAccessType	(NO_TEST)
+
+/* - ScratchPad */
+#define	UARTScratchPad			(0x1c)
+#define	UARTScratchPadMask		(0xff)
+#define	UARTScratchPadSRCPAD		(0xff)
+#define	UARTScratchPadSRCPADShift	(0x0)
+#define	UARTScratchPadMask		(0xff)
+#define	UARTScratchPadAccessType	(RW)
+#define	UARTScratchPadInitialValue	(0x0)
+#define	UARTScratchPadTestMask		(0xff)
+
+/* Instance values */
+#define aUARTRegister0		 0x500
+#define aUARTInterruptEnable		 0x504
+#define aUARTInterrupID		 0x508
+#define aUARTLineControl		 0x50c
+#define aUARTModemControl		 0x510
+#define aUARTLineStatus		 0x514
+#define aUARTModemStatus		 0x518
+#define aUARTScratchPad		 0x51c
+
+/* C struct view */
+
+#ifndef __ASSEMBLER__
+
+typedef struct s_UART {
+ unsigned Register0; /* @0 */
+ unsigned InterruptEnable; /* @4 */
+ unsigned InterrupID; /* @8 */
+ unsigned LineControl; /* @12 */
+ unsigned ModemControl; /* @16 */
+ unsigned LineStatus; /* @20 */
+ unsigned ModemStatus; /* @24 */
+ unsigned ScratchPad; /* @28 */
+} s_UART;
+
+#endif /* !__ASSEMBLER__ */
+
+#define uUART ((volatile struct s_UART *) 0xc0000500)
+
+#endif /* __ASM_ARCH_UART_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/uncompress.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/uncompress.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/uncompress.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,74 @@
+/*
+ * asm/arch/uncompress.c:
+ *         Optional routines to aid in debugging the decompression phase
+ *         of kernel boot.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * This is used by arch/armnommu/boot/compressed/misc.c to write progress info
+ * out the serial port so that the user can see debug messages up to the point
+ * where the kernel is decompressed. The STANDALONE_DEBUG macro chooses between
+ * this and the standard printf. Punt.
+ * --gmcnutt
+ */
+extern void printascii(const char* string);
+
+extern void puts(const char* string)
+{
+	printascii(string);
+}
+
+extern void puthex(unsigned long data)
+{
+	char hc[2];
+	int i;
+
+	hc[1] = '\0';
+	for ( i = 7; i >= 0; i--)
+	{
+		hc[0] = (char) ( ( data & (0xF << (i*4)) ) >> (i*4) );
+		if ( hc[0] < 0xA )
+			hc[0] = hc[0] + 0x30;
+		else if ( hc[0] <= 0xF )
+			hc[0] = hc[0] - 0xA + 0x41;
+		else
+			hc[0] = 'i';
+		puts(hc);
+	}
+}
+
+/*
+ * Not sure what this is for. Probably an optional watchdog to check if the
+ * decompress got hung so we can warn the user. Punt.
+ */
+#define arch_decomp_wdog()
+
+/*
+ * If we need to do some setup prior to decompression (like initializing the
+ * UART if we want to use puts() above) then we define it here. Punt.
+ */
+#define arch_decomp_setup()
diff -urN linux-2.4.29/include/asm-armnommu/arch-isl3893/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-isl3893/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-isl3893/vmalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,35 @@
+/* $Header$
+ *  linux/include/asm-arm/arch-isl3893/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *  Copyright (C) 2002 Intersil Americas Inc.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/arm_registers.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/arm_registers.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/arm_registers.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/arm_registers.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ * linux/include/asm-arm/proc-armv/ptrace.h
+ *
+ * Copyright (C) 1996 Russell King
+ */
+
+#ifndef __ARM_REGISTERS_H
+#define __ARM_REGISTERS_H
+
+#define CPSR_USR26_MODE		0x00
+#define CPSR_FIQ26_MODE		0x01
+#define CPSR_IRQ26_MODE		0x02
+#define CPSR_SVC26_MODE		0x03
+#define CPSR_USR_MODE		0x10
+#define CPSR_FIQ_MODE		0x11
+#define CPSR_IRQ_MODE		0x12
+#define CPSR_SVC_MODE		0x13
+#define CPSR_ABT_MODE		0x17
+#define CPSR_UND_MODE		0x1b
+#define CPSR_SYSTEM_MODE	0x1f
+#define CPSR_MODE_MASK		0x1f
+#define CPSR_F_BIT		0x40
+#define CPSR_I_BIT		0x80
+#define CPSR_CC_V_BIT		(1 << 28)
+#define CPSR_CC_C_BIT		(1 << 29)
+#define CPSR_CC_Z_BIT		(1 << 30)
+#define CPSR_CC_N_BIT		(1 << 31)
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+/*
+ * This is the maximum DMA address that can be DMAd to (since there
+ * are only 29 bits in a DMA buffer descriptor source buffer
+ * pointer). 
+ */
+#define MAX_DMA_ADDRESS		0x1fffffff
+
+/*
+ * DMA modes - we have two, IN and OUT
+ */
+
+/* dmamode_t already defined in asm/dma.h, with 4 modes(?) --rp
+typedef enum {
+	DMA_MODE_READ,
+	DMA_MODE_WRITE
+} dmamode_t;
+*/
+
+/*
+ * There are 10 DMA channels in the DMA controller module.  Normally,
+ * this would be channels 0-9.  But on the NET+ARM, there are channels
+ * 1-10.  So, we define MAX_DMA_CHANNELS as 11.  This will allow code
+ * like "if (channel < MAX_DMA_CHANNELS)" to work properly.
+ */
+#define MAX_DMA_CHANNELS	11
+
+/*
+ * arch_dma_init -- called by arch/armnommu/kernel/dma.c init_dma.
+ * Don't know what's needed here (if anything).
+ * --gmcnutt
+ */
+#define arch_dma_init(dma_chan)
+
+
+#endif /* _ASM_ARCH_DMA_H */
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,73 @@
+/*
+ * include/asm-armnommu/arch-netarm/hardware.h
+ *
+ * Copyright (C) 2000 NETsilicon, Inc.
+ * Copyright (C) 2000 WireSpeed Communications Corporation
+ *
+ * This software is copyrighted by WireSpeed. LICENSEE agrees that
+ * it will not delete this copyright notice, trademarks or protective
+ * notices from any copy made by LICENSEE.
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall WireSpeed
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : Joe deBlaquiere
+ */
+
+#ifndef __ASM_ARCH_NETARM_HARDWARE_H
+#define __ASM_ARCH_NETARM_HARDWARE_H
+#include <asm/arch/netarm_registers.h> 
+/*
+ * What hardware must be present
+ */
+#ifndef __ASSEMBLER__
+
+typedef unsigned long u_32;
+
+/*
+ * RAM definitions
+ */
+#define MAPTOPHYS(a)		((unsigned long)a)
+#define KERNTOPHYS(a)		((unsigned long)(&a))
+#define GET_MEMORY_END(p)	((p->u1.s.page_size) * (p->u1.s.nr_pages))
+#define PARAMS_BASE			0x1000
+/*#define KERNEL_BASE		(PAGE_OFFSET + 0x80000)*/
+
+#endif
+
+/*
+ * HARD_RESET_NOW -- used in blkmem.c. Should call arch_hard_reset(), but I 
+ * don't appear to have one ;).
+ * --gmcnutt
+ */
+#if !defined(CONFIG_NETARM_NS7520) 
+#define HARD_RESET_NOW()
+#else  /* This might actually work for other platforms */
+#define HARD_RESET_NOW() {		\
+    cli();				\
+    *(get_gen_reg_addr( NETARM_GEN_PLL_CONTROL )) &= 0x0000ffff; \
+    mdelay( 100 );  \
+    *(get_gen_reg_addr( NETARM_GEN_SYSTEM_CONTROL )) |= \
+            (NETARM_GEN_SYS_CFG_WDOG_EN|NETARM_GEN_SYS_CFG_WDOG_RST| \
+             NETARM_GEN_SYS_CFG_WDOG_24); \
+}
+
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/io.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,71 @@
+/*
+ * linux/include/asm-armnommu/arch-netarm/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ *  02-19-2001  gjm     Leveraged for armnommu/dsc21
+ *  08-10-2001  rwp     Modified for armnommu/netarm
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ * --gmcnutt
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * If we define __io then asm/io.h will take care of most of the inb & friends
+ * macros. It still leaves us some 16bit macros to deal with ourselves, though.
+ * We don't have PCI or ISA on the dsc21 so I dropped __mem_pci & __mem_isa.
+ * --gmcnutt
+ * (should work for NetARM too. --rp)
+ */
+#define PCIO_BASE 0
+#define __io(a) (PCIO_BASE + (a))
+#define __arch_getw(a) (*(volatile unsigned short *)(a))
+#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
+
+/*
+ * Defining these two gives us ioremap for free. See asm/io.h.
+ * --gmcnutt
+ */
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+/*
+ * These functions are needed for mtd/maps/physmap.c
+ * --rp
+ */ 
+#ifndef memset_io
+#define memset_io(a,b,c)		_memset_io((a),(b),(c))
+#endif
+#ifndef memcpy_fromio
+#define memcpy_fromio(a,b,c)		_memcpy_fromio((a),(b),(c))
+#endif
+#ifndef memcpy_toio
+#define memcpy_toio(a,b,c)		_memcpy_toio((a),(b),(c))
+#endif
+
+#ifndef __mem_pci
+/* Implement memory read/write functions (needed for mtd) */
+#define readb(addr)			__arch_getb(addr)
+#define readw(addr)			__arch_getw(addr)
+#define readl(addr)			__arch_getl(addr)
+#define writeb(v,addr)			__arch_putb(v,addr)
+#define writew(v,addr)			__arch_putw(v,addr)
+#define writel(v,addr)			__arch_putl(v,addr)
+
+#define eth_io_copy_and_sum(a,b,c,d)	__readwrite_bug("eth_io_copy_and_sum")
+
+#define check_signature(io,sig,len)	(0)
+
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,67 @@
+/*
+ * irq.h:
+ *         netarm-specific IRQ setup.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * tried to merge some of Joe deBlaquiere's code in here --rp
+ */
+
+#ifndef __ASM_ARCH_IRQ_H__
+#define __ASM_ARCH_IRQ_H__
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/netarm_registers.h>
+
+#define fixup_irq(x) (x)
+
+/* defined in arch/armnommu/mach-netarm/irq.c: */
+extern void netarm_mask_irq(unsigned int irq);
+extern void netarm_unmask_irq(unsigned int irq);
+extern void netarm_mask_ack_irq(unsigned int irq);
+
+/* Mask & Acknowledge function for Timer 1 IRQ: */
+extern void netarm_mask_ack_t1_irq(unsigned int irq);
+
+/* Mask & Acknowledge function for Timer 2 IRQ: */
+extern void netarm_mask_ack_t2_irq(unsigned int irq);
+
+/* Mask & Acknowledge function for Port C Bit 0..3 IRQ */
+extern void netarm_mask_ack_portc_irq(unsigned int irq);
+
+/* Mask & Acknowledge function for DMA channel 1 IRQ */
+extern void netarm_mask_ack_dma1_irq(unsigned int irq);
+
+/* Mask & Acknowledge function for DMA channels 2..10 IRQ */
+extern void netarm_mask_ack_dmax_irq(unsigned int irq);
+
+/* setup IRQ descriptor array */
+extern void irq_init_irq(void);
+
+#endif /* __ASM_ARCH_IRQ_H__ */
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/irqs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,75 @@
+/*
+ * irqs.h:
+ *         IRQ numbers for the netarm.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : Joe deBlaquiere, rp
+ */
+
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+
+#define IRQ_PORTC0	0
+#define IRQ_PORTC1	1
+#define IRQ_PORTC2	2
+#define IRQ_PORTC3	3
+#define IRQ_TIMER2	4
+#define IRQ_TIMER1	5
+#define IRQ_WDOG	6
+#define IRQ_SER2_TX	12
+#define IRQ_SER2_RX	13
+#define IRQ_SER1_TX	14
+#define IRQ_SER1_RX	15
+#define IRQ_ENET_TX	16
+#define IRQ_ENET_RX	17
+#define IRQ_ENIP4	18
+#define IRQ_ENIP3	19
+#define IRQ_ENIP2	20
+#define IRQ_ENIP1	21
+#define IRQ_DMA10	22	
+#define IRQ_DMA09	23	
+#define IRQ_DMA08	24	
+#define IRQ_DMA07	25	
+#define IRQ_DMA06	26	
+#define IRQ_DMA05	27	
+#define IRQ_DMA04	28	
+#define IRQ_DMA03	29	
+#define IRQ_DMA02	30	
+#define IRQ_DMA01	31	
+
+#define NR_IRQS           (IRQ_DMA01 + 1)
+
+/* alias */
+/* #define IRQ_TIMER         DSC21_IRQ_TIMER0 */
+
+/* flags for request_irq() */
+#define IRQ_FLG_LOCK      (0x0001)  /* handler is not replaceable   */
+#define IRQ_FLG_REPLACE   (0x0002)  /* replace existing handler     */
+#define IRQ_FLG_FAST      (0x0004)
+#define IRQ_FLG_SLOW      (0x0008)
+#define IRQ_FLG_STD       (0x8000)  /* internally used              */
+
+#endif /* __ASM_ARCH_IRQS_H__ */
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,62 @@
+/*
+ * linux/include/asm-armnommu/arch-netarm/memory.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * Copyright (c) 2001 RidgeRun <www.ridgerun.com>
+ *
+ * 02/19/2001  Gordon McNutt  Leveraged for the dsc21.
+ * 06/29/2001  Rolf Peukert   A little tweak for the NetARM
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * These are used in the fault handling code (even for nommu) and various other
+ * macros. The current value comes from Steve Johnson's 2.0.38 uClinux port for
+ * the dsc21 (TASK_SIZE = 0x01a00000UL).
+ * --gmcnutt
+ * The NetARM probably needs a value of about 32M --rp
+ */
+#define TASK_SIZE	(0x02000000UL)
+#define TASK_SIZE_26	(0x01a00000UL)
+
+
+/*
+ * The start of physical memory. For the dsc21 this is the first SDRAM address.
+ * This value is used in the arch-specific bootup code like setup_arch &
+ * bootmem_init. By default we assume that we have one block of contiguous
+ * memory (a node) that starts here and runs MEM_SIZE long (see below). By 
+ * default the ARM bootup code sets MEM_SIZE to be 16MB  which is just right for
+ * us (see arch/armnommu/kernel/setup.c).
+ *
+ * NOTE:   I don't really use the start of SDRAM. Instead I reserve some pages
+ *         of SDRAM for some of the kernel sections (like .data & .bss). The
+ *         linker script has been modified to mark the first unreservered page
+ *         as _end_kernel (see arch/armnommu/vmlinux-armv.lds.in).
+ *         
+ * --gmcnutt
+ */
+extern unsigned long _end_kernel;
+#define PHYS_OFFSET	0
+//0x08000000
+//#define PHYS_OFFSET	0
+
+/*
+ * PAGE_OFFSET -- the first address of the first page of memory. For archs with
+ * no MMU this corresponds to the first free page in physical memory (aligned
+ * on a page boundary).
+ * --gmcnutt
+ */
+#define PAGE_OFFSET  PHYS_OFFSET
+
+/* MEM_SIZE for the NetARM board is DRAM_SIZE (32MB) minus kernel space */
+#define MEM_SIZE	(DRAM_SIZE - PHYS_OFFSET)
+#define END_MEM		DRAM_BASE + DRAM_SIZE
+
+#define __virt_to_phys(vpage) ((unsigned long) (vpage))
+#define __phys_to_virt(ppage) ((void *) (ppage))
+#define __virt_to_bus(vpage) ((unsigned long) (vpage))
+#define __bus_to_virt(ppage) ((void *) (ppage))
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_dma_module.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_dma_module.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_dma_module.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_dma_module.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,417 @@
+/*
+ * include/asm-armnommu/arch-netarm/netarm_dma_module.h
+ *
+ * Copyright (C) 2000 NETsilicon, Inc.
+ * Copyright (C) 2000 WireSpeed Communications Corporation
+ *
+ * This software is copyrighted by WireSpeed. LICENSEE agrees that
+ * it will not delete this copyright notice, trademarks or protective
+ * notices from any copy made by LICENSEE.
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall WireSpeed
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : Joe deBlaquiere
+ *             David Smith
+ *
+ * Updated by Arthur Shipkowski <art@videon-central.com>
+ *  to offer the Forth-Systeme method of DMA configuration for their NS7520 
+ *  Ethernet driver. Ideally, I'd like to deprecate the original method of 
+ *  DMA configuration, which isn't quite as elegant as their method.
+ *  
+ */
+
+#ifndef __NETARM_DMA_MODULE_REGISTERS_H
+#define __NETARM_DMA_MODULE_REGISTERS_H
+
+/* GEN unit register offsets */
+
+#define	NETARM_DMA_MODULE_BASE		(0xFF900000)
+
+#ifdef OLD_STYLE_NETARM_DMA_CONFIGURATION
+#define get_dma_reg_addr(c) ((volatile unsigned int *)(NETARM_DMA_MODULE_BASE + (c)))
+
+#define	NETARM_DMA1A_BFR_DESCRPTOR_PTR	(0x00)
+#define	NETARM_DMA1A_CONTROL		(0x10)
+#define	NETARM_DMA1A_STATUS		(0x14)
+#define	NETARM_DMA1B_BFR_DESCRPTOR_PTR	(0x20)
+#define	NETARM_DMA1B_CONTROL		(0x30)
+#define	NETARM_DMA1B_STATUS		(0x34)
+#define	NETARM_DMA1C_BFR_DESCRPTOR_PTR	(0x40)
+#define	NETARM_DMA1C_CONTROL		(0x50)
+#define	NETARM_DMA1C_STATUS		(0x54)
+#define	NETARM_DMA1D_BFR_DESCRPTOR_PTR	(0x60)
+#define	NETARM_DMA1D_CONTROL		(0x70)
+#define	NETARM_DMA1D_STATUS		(0x74)
+
+#define	NETARM_DMA2_BFR_DESCRPTOR_PTR	(0x80)
+#define	NETARM_DMA2_CONTROL		(0x90)
+#define	NETARM_DMA2_STATUS		(0x94)
+
+#define	NETARM_DMA3_BFR_DESCRPTOR_PTR	(0xA0)
+#define	NETARM_DMA3_CONTROL		(0xB0)
+#define	NETARM_DMA3_STATUS		(0xB4)
+
+#define	NETARM_DMA4_BFR_DESCRPTOR_PTR	(0xC0)
+#define	NETARM_DMA4_CONTROL		(0xD0)
+#define	NETARM_DMA4_STATUS		(0xD4)
+
+#define	NETARM_DMA5_BFR_DESCRPTOR_PTR	(0xE0)
+#define	NETARM_DMA5_CONTROL		(0xF0)
+#define	NETARM_DMA5_STATUS		(0xF4)
+
+#define	NETARM_DMA6_BFR_DESCRPTOR_PTR	(0x100)
+#define	NETARM_DMA6_CONTROL		(0x110)
+#define	NETARM_DMA6_STATUS		(0x114)
+
+#define	NETARM_DMA7_BFR_DESCRPTOR_PTR	(0x120)
+#define	NETARM_DMA7_CONTROL		(0x130)
+#define	NETARM_DMA7_STATUS		(0x134)
+
+#define	NETARM_DMA8_BFR_DESCRPTOR_PTR	(0x140)
+#define	NETARM_DMA8_CONTROL		(0x150)
+#define	NETARM_DMA8_STATUS		(0x154)
+
+#define	NETARM_DMA9_BFR_DESCRPTOR_PTR	(0x160)
+#define	NETARM_DMA9_CONTROL		(0x170)
+#define	NETARM_DMA9_STATUS		(0x174)
+
+#define	NETARM_DMA10_BFR_DESCRPTOR_PTR	(0x180)
+#define	NETARM_DMA10_CONTROL		(0x190)
+#define	NETARM_DMA10_STATUS		(0x194)
+
+/* select bitfield defintions */
+
+/* DMA Control Register ( 0xFF90_0XX0 ) */
+
+#define NETARM_DMA_CTL_ENABLE		(0x80000000)
+
+#define NETARM_DMA_CTL_ABORT		(0x40000000)
+
+#define NETARM_DMA_CTL_BUS_100_PERCENT	(0x00000000)
+#define NETARM_DMA_CTL_BUS_75_PERCENT	(0x10000000)
+#define NETARM_DMA_CTL_BUS_50_PERCENT	(0x20000000)
+#define NETARM_DMA_CTL_BUS_25_PERCENT	(0x30000000)
+
+#define NETARM_DMA_CTL_BUS_MASK		(0x30000000)
+
+#define NETARM_DMA_CTL_MODE_FB_TO_MEM	(0x00000000)
+#define NETARM_DMA_CTL_MODE_FB_FROM_MEM	(0x04000000)
+#define NETARM_DMA_CTL_MODE_MEM_TO_MEM	(0x08000000)
+
+#define NETARM_DMA_CTL_BURST_NONE	(0x00000000)
+#define NETARM_DMA_CTL_BURST_8_BYTE	(0x01000000)
+#define NETARM_DMA_CTL_BURST_16_BYTE	(0x02000000)
+
+#define NETARM_DMA_CTL_BURST_MASK	(0x03000000)
+
+#define NETARM_DMA_CTL_SRC_INCREMENT	(0x00200000)
+
+#define NETARM_DMA_CTL_DST_INCREMENT	(0x00100000)
+
+/* these apply only to ext xfers on DMA 3 or 4 */
+
+#define NETARM_DMA_CTL_CH_3_4_REQ_EXT	(0x00800000)
+
+#define NETARM_DMA_CTL_CH_3_4_DATA_32	(0x00000000)
+#define NETARM_DMA_CTL_CH_3_4_DATA_16	(0x00010000)
+#define NETARM_DMA_CTL_CH_3_4_DATA_8	(0x00020000)
+
+#define NETARM_DMA_CTL_STATE(X)	((X) & 0xFC00)
+#define NETARM_DMA_CTL_INDEX(X)	((X) & 0x03FF)
+
+/* DMA Status Register ( 0xFF90_0XX4 ) */
+
+#define NETARM_DMA_STAT_NC_INTPEN	(0x80000000)
+#define NETARM_DMA_STAT_EC_INTPEN	(0x40000000)
+#define NETARM_DMA_STAT_NR_INTPEN	(0x20000000)
+#define NETARM_DMA_STAT_CA_INTPEN	(0x10000000)
+#define NETARM_DMA_STAT_INTPEN_MASK	(0xF0000000)
+
+#define NETARM_DMA_STAT_NC_INT_EN	(0x00800000)
+#define NETARM_DMA_STAT_EC_INT_EN	(0x00400000)
+#define NETARM_DMA_STAT_NR_INT_EN	(0x00200000)
+#define NETARM_DMA_STAT_CA_INT_EN	(0x00100000)
+#define NETARM_DMA_STAT_INT_EN_MASK	(0x00F00000)
+
+#define NETARM_DMA_STAT_WRAP		(0x00080000)
+#define NETARM_DMA_STAT_IDONE		(0x00040000)
+#define NETARM_DMA_STAT_LAST		(0x00020000)
+#define NETARM_DMA_STAT_FULL		(0x00010000)
+
+#define	NETARM_DMA_STAT_BUFLEN(X)	((X) & 0x7FFF)
+
+/* DMA Buffer Descriptor Word 0 bitfields. */
+
+#define NETARM_DMA_BD0_WRAP		(0x80000000)
+#define NETARM_DMA_BD0_IDONE		(0x40000000)
+#define NETARM_DMA_BD0_LAST		(0x20000000)
+#define NETARM_DMA_BD0_BUFPTR_MASK	(0x1FFFFFFF)
+
+/* DMA Buffer Descriptor Word 1 bitfields. */
+
+#define NETARM_DMA_BD1_STATUS_MASK	(0xFFFF0000)
+#define NETARM_DMA_BD1_FULL		(0x00008000)
+#define NETARM_DMA_BD1_BUFLEN_MASK	(0x00007FFF)
+
+#ifndef	__ASSEMBLER__
+
+/*
+ * Old FlyBy DMA Buffer Description
+ */
+typedef	struct __NETARM_DMA_Buff_Desc_FlyBy
+{
+	unsigned int word0;
+	unsigned int word1;
+} NETARM_DMA_Buff_Desc_FlyBy, *pNETARM_DMA_Buff_Desc_FlyBy ;
+
+/*
+ * Old Memory to Memory DMA Buffer Description
+ */
+typedef	struct __NETARM_DMA_Buff_Desc_M_to_M
+{
+	unsigned int word0;
+	unsigned int word1;
+	unsigned int word2;
+	unsigned int word3;
+} NETARM_DMA_Buff_Desc_M_to_M, *pNETARM_DMA_Buff_Desc_M_to_M ;
+
+#endif /* !__ASSEMBLER__ */
+
+#else
+
+#define get_dma_reg_addr(c, reg) \
+	((volatile unsigned int *)(NETARM_DMA_MODULE_BASE + \
+		((unsigned int) (c)) + (reg)))
+
+#define NETARM_DMA_DESC			(0x00000000) // descriptor pointer
+#define NETARM_DMA_CONTROL		(0x00000010) // control register
+#define NETARM_DMA_STATUS		(0x00000014) // status register
+
+#define NETARM_DMA_CONTROL_CE		(0x80000000) // Channel enabled
+#define NETARM_DMA_CONTROL_CA		(0x40000000) // Channel abort
+#define NETARM_DMA_CONTROL_BB_MA	(0x30000000) // Bus bandwidth mask
+#define NETARM_DMA_CONTROL_BB_25	(0x30000000) // 25% bandwidth
+#define NETARM_DMA_CONTROL_BB_50	(0x20000000) // 50% bandwidth
+#define NETARM_DMA_CONTROL_BB_75	(0x10000000) // 75% bandwidth
+#define NETARM_DMA_CONTROL_BB_100	(0x00000000) // 100% bandwidth
+#define NETARM_DMA_CONTROL_MODE_MA	(0x0C000000) // DMA operation mode
+#define NETARM_DMA_CONTROL_MODE_RES	(0x0C000000) // Reserved
+#define NETARM_DMA_CONTROL_MODE_MEM2MEM	(0x08000000) // Mem-to-Mem
+#define NETARM_DMA_CONTROL_MODE_MEM2PER	(0x04000000) // Mem-to-Peripheral
+#define NETARM_DMA_CONTROL_MODE_PER2MEM	(0x00000000) // Peripheral-to-Mem
+#define NETARM_DMA_CONTROL_BTE_MA	(0x03000000) // Burst Transfer enable
+#define NETARM_DMA_CONTROL_BTE_RES	(0x03000000) // Reserved
+#define NETARM_DMA_CONTROL_BTE_4 	(0x02000000) // 4 operands
+#define NETARM_DMA_CONTROL_BTE_2 	(0x01000000) // 2 operands
+#define NETARM_DMA_CONTROL_BTE_1 	(0x00000000) // 1 operands
+#define NETARM_DMA_CONTROL_REQ		(0x00800000) // Channel Request Source
+#define NETARM_DMA_CONTROL_RES1		(0x00400000) // Reserved
+#define NETARM_DMA_CONTROL_SINC		(0x00200000) // Source address increment
+#define NETARM_DMA_CONTROL_DINC		(0x00100000) // Destination address incr
+#define NETARM_DMA_CONTROL_RES2		(0x000C0000) // Reserved
+#define NETARM_DMA_CONTROL_SIZE_MA	(0x00030000) // Data operand size
+#define NETARM_DMA_CONTROL_SIZE_RES	(0x00030000) // Reserved
+#define NETARM_DMA_CONTROL_SIZE_8   	(0x00020000) // 8 bit
+#define NETARM_DMA_CONTROL_SIZE_16	(0x00010000) // 16 bit
+#define NETARM_DMA_CONTROL_SIZE_32	(0x00000000) // 32 bit
+#define NETARM_DMA_CONTROL_STATE_MA	(0x0000FC00) // DMA channel state
+#define NETARM_DMA_CONTROL_STATE_UPDATE	(0x00008000) // Update
+#define NETARM_DMA_CONTROL_STATE_SECOP  (0x00004000) // Mem-mem second operand
+#define NETARM_DMA_CONTROL_STATE_FIROP	(0x00002000) // First operand
+#define NETARM_DMA_CONTROL_STATE_LOADDE	(0x00001000) // Load Destination address
+#define NETARM_DMA_CONTROL_STATE_LOADSO	(0x00000800) // Load Source address
+#define NETARM_DMA_CONTROL_STATE_IDLE	(0x00000400) // IDLE
+#define NETARM_DMA_CONTROL_INDEX	(0x000003FF) // buffer desciptor index
+
+#define NETARM_DMA_CONTROL_CE		(0x80000000) // Channel enabled
+
+// the status register bit fields
+
+#define NETARM_DMA_STATUS_IP_MA         (0xF8000000) // clear pending mask
+#define NETARM_DMA_STATUS_IP_NC  	(0x80000000) // normal int pending
+#define NETARM_DMA_STATUS_IP_EC  	(0x40000000) // error int pending
+#define NETARM_DMA_STATUS_IP_NR  	(0x20000000) // buffer not ready int pend
+#define NETARM_DMA_STATUS_IP_CA  	(0x10000000) // channel abort int pend
+#define NETARM_DMA_STATUS_IP_PC  	(0x08000000) // premature int pending
+#define NETARM_DMA_STATUS_RES1		(0x06000000) // Reserved
+#define NETARM_DMA_STATUS_IE_MA		(0x01F00000) // interrupt enable mask
+#define NETARM_DMA_STATUS_IE_PC  	(0x01000000) // premature int enable
+#define NETARM_DMA_STATUS_IE_NC   	(0x00800000) // normal int enable
+#define NETARM_DMA_STATUS_IE_EC  	(0x00400000) // error int enable
+#define NETARM_DMA_STATUS_IE_NR		(0x00200000) // buffer not ready int ena
+#define NETARM_DMA_STATUS_IE_CA		(0x00100000) // channel abort int enable
+#define NETARM_DMA_STATUS_WRAP		(0x00080000) // last descriptor
+#define NETARM_DMA_STATUS_IDONE		(0x00040000) // interrupt on done
+#define NETARM_DMA_STATUS_LAST		(0x00020000) // last buffer descriptor
+#define NETARM_DMA_STATUS_FULL		(0x00010000) // buffer full indicator
+#define NETARM_DMA_STATUS_RES2		(0x00008000) // Reserved
+#define NETARM_DMA_STATUS_BLEN		(0x00007FFF) // remaining buffer count
+
+#ifndef	__ASSEMBLER__
+
+// the supported DMA channels
+// they represent the offsets to the Buffer Descriptor Pointer on
+// the DMA base register
+typedef enum 
+{
+    NETARM_DMA_CHANNEL_1A = 0x0000,
+    NETARM_DMA_CHANNEL_1B = 0x0020,
+    NETARM_DMA_CHANNEL_1C = 0x0040,
+    NETARM_DMA_CHANNEL_1D = 0x0060,
+    NETARM_DMA_CHANNEL_2  = 0x0080,
+    NETARM_DMA_CHANNEL_3  = 0x00A0,
+    NETARM_DMA_CHANNEL_4  = 0x00C0,
+    NETARM_DMA_CHANNEL_5  = 0x00E0,
+    NETARM_DMA_CHANNEL_6  = 0x0100,
+    NETARM_DMA_CHANNEL_7  = 0x0120,
+    NETARM_DMA_CHANNEL_8  = 0x0140,
+    NETARM_DMA_CHANNEL_9  = 0x0160,
+    NETARM_DMA_CHANNEL_10 = 0x0180,
+    NETARM_DMA_CHANNEL_11 = 0x01A0,
+    NETARM_DMA_CHANNEL_12 = 0x01C0,
+    NETARM_DMA_CHANNEL_13 = 0x01E0
+} netarm_dmaChannel_t;
+
+
+/*
+ * New Forth-Systeme-designed DMA Flyby buffer descriptor
+ */
+typedef struct
+{  
+	union
+	{
+		unsigned int unReg;
+		struct {
+			unsigned srcPtr   : 29; /* d0-d28 actual buffer pointer */
+			unsigned last     : 1;  /* d29 1 if it is the last buffer */
+			unsigned intr     : 1;  /* d30 interrupt if buffer closed */
+			unsigned wrap     : 1;  /* d31 1 if next buffer is first */
+		} bits;
+	} l;
+	union 
+	{
+		unsigned int unReg;
+		struct 
+		{
+			unsigned bufLen : 15; /* d0-d14 size of buffer @ srcPtr */
+			unsigned full   : 1;  /* d15 1 if buffer full */
+			unsigned status : 16; /* d16-d31 depend on peripheral */
+		} bits;
+	} h;
+} netarm_dmaBufferDescFb_t;
+
+/*
+ * New Forth-Systeme-designed DMA Memory-to-memory buffer descriptor
+ */
+typedef struct
+{
+	netarm_dmaBufferDescFb_t common; /* common fields for fly-by and */
+					 /* mem-to-mem */
+	unsigned int unDestBPtr;  /* destination buffer pointer */
+	unsigned int unReserved;  /* reserved */
+} netarm_dmaBufferDescMem2Mem_t;
+
+/* all functions operate on netarm_dmaBufferFb_t if not overwise noted */
+#define DMA_CHANNEL_CONTROL	0x10 /* offset to control register */
+#define DMA_CHANNEL_STATUS	0x14 /* offset to status register */
+
+/***********************************************************************
+ * @Function: netarm_dmaChannelDisable
+ * @Return: nothing
+ * @Descr: disables DMA channel dmaChannel and disables interrupts.
+ *         Clears any pending interrupts
+ ***********************************************************************/
+
+static inline void netarm_dmaChannelDisable( netarm_dmaChannel_t dmaChannel )
+{
+	*get_dma_reg_addr( dmaChannel, NETARM_DMA_CONTROL ) &=
+	    ~(NETARM_DMA_CONTROL_CE);
+	/* acknowledge pending interrupts */
+	*get_dma_reg_addr( dmaChannel, NETARM_DMA_STATUS ) = 
+	    NETARM_DMA_STATUS_IP_MA;
+}
+
+
+/***********************************************************************
+ * @Function: netarm_dmaChannelEnable
+ * @Return: nothing
+ * @Descr: initializes the channel for the buffer descriptor and
+ *         enables interrupts and channels
+ ***********************************************************************/
+
+static inline void netarm_dmaChannelEnable( netarm_dmaChannel_t dmaChannel,
+			      netarm_dmaBufferDescFb_t* pFirstBufferDesc,
+			      unsigned int unControlOptions,
+			      unsigned int unInterruptsEnable )
+{
+	*get_dma_reg_addr( dmaChannel, NETARM_DMA_STATUS ) = 
+	    unInterruptsEnable;
+
+	*get_dma_reg_addr( dmaChannel, NETARM_DMA_DESC ) =
+	    (unsigned int) virt_to_bus( pFirstBufferDesc );
+
+	*get_dma_reg_addr( dmaChannel, NETARM_DMA_CONTROL ) =
+	    NETARM_DMA_CONTROL_CE | unControlOptions;
+	
+}
+
+
+/***********************************************************************
+ * @Function: netarm_dmaBufferDescInit
+ * @Return: nothing
+ * @Descr: sets up an array of descriptors sized nDescListSize starting from
+ *         pBufferDesc and may enable interrupt.
+ *         Currently only suitable for fly-by buffers
+ ***********************************************************************/
+
+static inline void netarm_dmaBufferDescInit( netarm_dmaBufferDescFb_t* pBufferDesc,
+			       unsigned int nDescListSize,
+			       unsigned char ucIntEnable )
+{
+	int nDescIndex;
+
+	for( nDescIndex = 1; nDescIndex <= nDescListSize; nDescIndex++ )
+	{
+	    pBufferDesc->l.bits.intr = ucIntEnable;
+	    pBufferDesc->l.bits.srcPtr = 0;
+	    pBufferDesc->h.bits.status = 0;
+ 	    pBufferDesc->h.bits.full = 0;
+	    pBufferDesc->h.bits.bufLen = 0;
+	    pBufferDesc->l.bits.last = 0;
+
+	    /* prepare the buffer descriptors so the controller knows whether to
+	     * stop or continue to next one
+       */
+	    if( nDescIndex != nDescListSize )
+	    {
+		pBufferDesc->l.bits.wrap = 0;
+	    } else {
+		pBufferDesc->l.bits.wrap = 1;
+	    }
+
+	    pBufferDesc++;
+	}
+}
+#endif /* !__ASSEMBLER__ */
+
+#endif /* OLD_STYLE_NETARM_DMA_CONFIGURATION */
+
+#endif
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_eni_module.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_eni_module.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_eni_module.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_eni_module.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,123 @@
+/*
+ * include/asm-armnommu/arch-netarm/netarm_eni_module.h
+ *
+ * Copyright (C) 2000 NETsilicon, Inc.
+ * Copyright (C) 2000 WireSpeed Communications Corporation
+ *
+ * This software is copyrighted by WireSpeed. LICENSEE agrees that
+ * it will not delete this copyright notice, trademarks or protective
+ * notices from any copy made by LICENSEE.
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall WireSpeed
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : David Smith
+ */
+
+#ifndef __NETARM_ENI_MODULE_REGISTERS_H
+#define __NETARM_ENI_MODULE_REGISTERS_H
+
+#include <linux/autoconf.h>
+
+/* ENI unit register offsets */
+
+#ifdef CONFIG_ARCH_NETARM
+#define	NETARM_ENI_MODULE_BASE		(0xFFA00000)
+#endif /* CONFIG_ARCH_NETARM */
+
+#define get_eni_reg_addr(c) ((volatile unsigned int *)(NETARM_ENI_MODULE_BASE + (c)))
+#define get_eni_ctl_reg_addr(minor) \
+	(get_eni_reg_addr(NETARM_ENI_1284_PORT1_CONTROL) + (minor))
+
+#define	NETARM_ENI_GENERAL_CONTROL	(0x00)
+#define	NETARM_ENI_STATUS_CONTROL	(0x04)
+#define	NETARM_ENI_FIFO_MODE_DATA	(0x08)
+
+#define	NETARM_ENI_1284_PORT1_CONTROL	(0x10)
+#define	NETARM_ENI_1284_PORT2_CONTROL	(0x14)
+#define	NETARM_ENI_1284_PORT3_CONTROL	(0x18)
+#define	NETARM_ENI_1284_PORT4_CONTROL	(0x1c)
+
+#define	NETARM_ENI_1284_CHANNEL1_DATA	(0x20)
+#define	NETARM_ENI_1284_CHANNEL2_DATA	(0x24)
+#define	NETARM_ENI_1284_CHANNEL3_DATA	(0x28)
+#define	NETARM_ENI_1284_CHANNEL4_DATA	(0x2c)
+
+#define	NETARM_ENI_ENI_CONTROL		(0x30)
+#define	NETARM_ENI_ENI_PULSED_INTR	(0x34)
+#define	NETARM_ENI_ENI_SHARED_RAM_ADDR	(0x38)
+#define	NETARM_ENI_ENI_SHARED		(0x3c)
+
+/* select bitfield defintions */
+
+/* General Control Register (0xFFA0_0000) */
+
+#define NETARM_ENI_GCR_ENIMODE_IEEE1284	(0x00000001)
+#define NETARM_ENI_GCR_ENIMODE_SHRAM16	(0x00000004)
+#define NETARM_ENI_GCR_ENIMODE_SHRAM8	(0x00000005)
+#define NETARM_ENI_GCR_ENIMODE_FIFO16	(0x00000006)
+#define NETARM_ENI_GCR_ENIMODE_FIFO8	(0x00000007)
+
+#define NETARM_ENI_GCR_ENIMODE_MASK	(0x00000007)
+
+/* IEEE 1284 Port Control Registers 1-4 (0xFFA0_0010, 0xFFA0_0014,
+   0xFFA0_0018, 0xFFA0_001c) */
+
+#define NETARM_ENI_1284PC_PORT_ENABLE	(0x80000000)
+#define NETARM_ENI_1284PC_DMA_ENABLE	(0x40000000)
+#define NETARM_ENI_1284PC_OBE_INT_EN	(0x20000000)
+#define NETARM_ENI_1284PC_ACK_INT_EN	(0x10000000)
+#define NETARM_ENI_1284PC_ECP_MODE	(0x08000000)
+#define NETARM_ENI_1284PC_LOOPBACK_MODE	(0x04000000)
+
+#define NETARM_ENI_1284PC_STROBE_TIME0	(0x00000000) /* 0.5 uS */
+#define NETARM_ENI_1284PC_STROBE_TIME1	(0x01000000) /* 1.0 uS */
+#define NETARM_ENI_1284PC_STROBE_TIME2	(0x02000000) /* 5.0 uS */
+#define NETARM_ENI_1284PC_STROBE_TIME3	(0x03000000) /* 10.0 uS */
+#define NETARM_ENI_1284PC_STROBE_MASK	(0x03000000)
+
+#define NETARM_ENI_1284PC_MAN_STROBE_EN	(0x00800000)
+#define NETARM_ENI_1284PC_FAST_MODE	(0x00400000)
+#define NETARM_ENI_1284PC_BIDIR_MODE	(0x00200000)
+
+#define NETARM_ENI_1284PC_MAN_STROBE	(0x00080000)
+#define NETARM_ENI_1284PC_AUTO_FEED	(0x00040000)
+#define NETARM_ENI_1284PC_INIT		(0x00020000)
+#define NETARM_ENI_1284PC_HSELECT	(0x00010000)
+#define NETARM_ENI_1284PC_FE_INT_EN	(0x00008000)
+#define NETARM_ENI_1284PC_EPP_MODE	(0x00004000)
+#define NETARM_ENI_1284PC_IBR_INT_EN	(0x00002000)
+#define NETARM_ENI_1284PC_IBR		(0x00001000)
+
+#define NETARM_ENI_1284PC_RXFDB_1BYTE	(0x00000400)
+#define NETARM_ENI_1284PC_RXFDB_2BYTE	(0x00000800)
+#define NETARM_ENI_1284PC_RXFDB_3BYTE	(0x00000c00)
+#define NETARM_ENI_1284PC_RXFDB_4BYTE	(0x00000000)
+
+#define NETARM_ENI_1284PC_RBCC		(0x00000200)
+#define NETARM_ENI_1284PC_RBCT		(0x00000100)
+#define NETARM_ENI_1284PC_ACK		(0x00000080)
+#define NETARM_ENI_1284PC_FIFO_E	(0x00000040)
+#define NETARM_ENI_1284PC_OBE		(0x00000020)
+#define NETARM_ENI_1284PC_ACK_INT	(0x00000010)
+#define NETARM_ENI_1284PC_BUSY		(0x00000008)
+#define NETARM_ENI_1284PC_PE		(0x00000004)
+#define NETARM_ENI_1284PC_PSELECT	(0x00000002)
+#define NETARM_ENI_1284PC_FAULT		(0x00000001)
+
+#endif /* __NETARM_ENI_MODULE_REGISTERS_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_eth_module.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_eth_module.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_eth_module.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_eth_module.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,141 @@
+/*
+ * include/asm-armnommu/arch-netarm/netarm_eth_module.h
+ *
+ * Copyright (C) 2000 NETsilicon, Inc.
+ * Copyright (C) 2000 WireSpeed Communications Corporation
+ *
+ * This software is copyrighted by WireSpeed. LICENSEE agrees that
+ * it will not delete this copyright notice, trademarks or protective
+ * notices from any copy made by LICENSEE.
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall WireSpeed
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : Jackie Smith Cashion
+ *             David Smith
+ */
+
+#ifndef __NETARM_ETH_MODULE_REGISTERS_H
+#define __NETARM_ETH_MODULE_REGISTERS_H
+
+/* ETH unit register offsets */
+
+#define	NETARM_ETH_MODULE_BASE		(0xFF800000)
+
+#define get_eth_reg_addr(c) ((volatile unsigned int *)(NETARM_ETH_MODULE_BASE + (c)))
+
+#define NETARM_ETH_GEN_CTRL		(0x000) /* Ethernet Gen Control Reg */
+#define NETARM_ETH_GEN_STAT		(0x004) /* Ethernet Gen Status Reg */
+
+#define NETARM_ETH_MAC_CFG		(0x400) /* MAC Configuration Reg */ 
+#define NETARM_ETH_PCS_CFG		(0x408) /* PCS Configuration Reg */
+#define NETARM_ETH_STL_CFG		(0x410) /* STL Configuration Reg */
+#define NETARM_ETH_B2B_IPG_GAP_TMR	(0x440) /* Back-to-back IPG
+						   Gap Timer Reg */
+#define NETARM_ETH_NB2B_IPG_GAP_TMR	(0x444) /* Non Back-to-back
+						   IPG Gap Timer Reg */
+#define NETARM_ETH_MII_CMD		(0x540) /* MII (PHY) Command Reg */
+#define NETARM_ETH_MII_ADDR		(0x544) /* MII Address Reg */
+#define NETARM_ETH_MII_WRITE		(0x548) /* MII Write Data Reg */
+#define NETARM_ETH_MII_READ		(0x54C) /* MII Read Data Reg */
+#define NETARM_ETH_MII_IND		(0x550) /* MII Indicators Reg */
+#define NETARM_ETH_MIB_CRCEC		(0x580) /* (MIB) CRC Error Counter */
+#define NETARM_ETH_MIB_AEC		(0x584) /* Alignment Error Counter */
+#define NETARM_ETH_MIB_CEC		(0x588) /* Code Error Counter */
+#define NETARM_ETH_MIB_LFC		(0x58C) /* Long Frame Counter */
+#define NETARM_ETH_MIB_SFC		(0x590) /* Short Frame Counter */
+#define NETARM_ETH_MIB_LCC		(0x594) /* Late Collision Counter */
+#define NETARM_ETH_MIB_EDC		(0x598) /* Excessive Deferral
+						   Counter */
+#define NETARM_ETH_MIB_MCC		(0x59C) /* Maximum Collision Counter */
+#define NETARM_ETH_SAL_FILTER		(0x5C0) /* SAL Station Address
+						   Filter Reg */
+#define NETARM_ETH_SAL_STATION_ADDR_1	(0x5C4) /* SAL Station Address
+						   Reg */
+#define NETARM_ETH_SAL_STATION_ADDR_2	(0x5C8)
+#define NETARM_ETH_SAL_STATION_ADDR_3	(0x5CC)
+#define NETARM_ETH_SAL_HASH_TBL_1	(0x5D0) /* SAL Multicast Hash Table*/
+#define NETARM_ETH_SAL_HASH_TBL_2	(0x5D4)
+#define NETARM_ETH_SAL_HASH_TBL_3	(0x5D8)
+#define NETARM_ETH_SAL_HASH_TBL_4	(0x5DC)
+
+/* select bitfield defintions */
+
+/* Ethernet General Control Register (0xFF80_0000) */
+
+#define NETARM_ETH_GCR_ERX		(0x80000000) /* Enable Receive FIFO */
+#define NETARM_ETH_GCR_ERXDMA		(0x40000000) /* Enable Receive DMA */
+#define NETARM_ETH_GCR_ETX		(0x00800000) /* Enable Transmit FIFO */
+#define NETARM_ETH_GCR_ETXDMA		(0x00400000) /* Enable Transmit DMA */
+#define NETARM_ETH_GCR_ETXWM_50		(0x00100000) /* Transmit FIFO Water
+							Mark.  Start transmit
+							when FIFO is 50%
+							full. */
+#define NETARM_ETH_GCR_PNA		(0x00000400) /* pSOS pNA Buffer
+							Descriptor Format */
+
+/* Ethernet General Status Register (0xFF80_0004) */
+
+#define NETARM_ETH_GST_RXREGR		(0x08000000) /* Receive Register
+							Ready */
+#define NETARM_ETH_GST_RXFIFOH		(0x04000000)
+#define NETARM_ETH_GST_RXBR		(0x02000000)
+#define NETARM_ETH_GST_RXSKIP		(0x01000000)
+
+/* PCS Configuration Register (0xFF80_0408) */
+
+#define NETARM_ETH_PCSC_NOCFR		(0x1) /* Disable Ciphering */
+#define NETARM_ETH_PCSC_ENJAB		(0x2) /* Enable Jabber Protection */
+#define NETARM_ETH_PCSC_CLKS_25M	(0x0) /* 25 MHz Clock Speed Select */ 
+#define NETARM_ETH_PCSC_CLKS_33M	(0x4) /* 33 MHz Clock Speed Select */ 
+
+/* STL Configuration Register (0xFF80_0410) */
+
+#define NETARM_ETH_STLC_RXEN		(0x2) /* Enable Packet Receiver */
+#define NETARM_ETH_STLC_AUTOZ		(0x4) /* Auto Zero Statistics */
+
+/* MAC Configuration Register (0xFF80_0400) */
+
+#define NETARM_ETH_MACC_HUGEN		(0x1) /* Enable Unlimited Transmit
+						 Frame Sizes */
+#define NETARM_ETH_MACC_PADEN		(0x4) /* Automatic Pad Fill Frames
+						 to 64 Bytes */
+#define NETARM_ETH_MACC_CRCEN		(0x8) /* Append CRC to Transmit
+						 Frames */
+
+/* MII (PHY) Command Register (0xFF80_0540) */
+
+#define NETARM_ETH_MIIC_RSTAT		(0x1) /* Single Scan for Read Data */
+
+/* MII Indicators Register (0xFF80_0550) */
+
+#define NETARM_ETH_MIII_BUSY		(0x1) /* MII I/F Busy with
+						 Read/Write */
+
+/* SAL Station Address Filter Register (0xFF80_05C0) */
+
+#define NETARM_ETH_SALF_PRO		(0x8) /* Enable Promiscuous Mode */
+#define NETARM_ETH_SALF_PRM		(0x4) /* Accept All Multicast
+						 Packets */
+#define NETARM_ETH_SALF_PRA		(0x2) /* Accept Mulitcast Packets
+						 using Hash Table */
+#define NETARM_ETH_SALF_BROAD		(0x1) /* Accept All Broadcast
+						 Packets */
+
+
+#endif /* __NETARM_GEN_MODULE_REGISTERS_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_gen_module.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_gen_module.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_gen_module.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_gen_module.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,175 @@
+/*
+ * include/asm-armnommu/arch-netarm/netarm_gen_module.h
+ *
+ * Copyright (C) 2003 Videon Central, Inc.
+ * Copyright (C) 2000, 2001 NETsilicon, Inc.
+ * Copyright (C) 2000, 2001 Red Hat, Inc.
+ *
+ * This software is copyrighted by Red Hat. LICENSEE agrees that
+ * it will not delete this copyright notice, trademarks or protective
+ * notices from any copy made by LICENSEE.
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall Red Hat
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : Joe deBlaquiere
+ *
+ * Modified to support NS7520 by Art Shipkowski <art@videon-central.com>
+ */
+
+#ifndef __NETARM_GEN_MODULE_REGISTERS_H
+#define __NETARM_GEN_MODULE_REGISTERS_H
+
+/* GEN unit register offsets */
+
+#define	NETARM_GEN_MODULE_BASE		(0xFFB00000)
+
+#define get_gen_reg_addr(c) ((volatile unsigned int *)(NETARM_GEN_MODULE_BASE + (c)))
+
+#define	NETARM_GEN_SYSTEM_CONTROL	(0x00)
+#define	NETARM_GEN_STATUS_CONTROL	(0x04)
+#define	NETARM_GEN_PLL_CONTROL		(0x08)
+#define	NETARM_GEN_SOFTWARE_SERVICE	(0x0c)
+
+#define	NETARM_GEN_TIMER1_CONTROL	(0x10)
+#define	NETARM_GEN_TIMER1_STATUS	(0x14)
+#define	NETARM_GEN_TIMER2_CONTROL	(0x18)
+#define	NETARM_GEN_TIMER2_STATUS	(0x1c)
+
+#define	NETARM_GEN_PORTA		(0x20)
+#ifndef CONFIG_NETARM_NS7520
+#define	NETARM_GEN_PORTB		(0x24)
+#endif
+#define	NETARM_GEN_PORTC		(0x28)
+
+#define	NETARM_GEN_INTR_ENABLE		(0x30)
+#define	NETARM_GEN_INTR_ENABLE_SET	(0x34)
+#define	NETARM_GEN_INTR_ENABLE_CLR	(0x38)
+#define	NETARM_GEN_INTR_STATUS_EN	(0x34)
+#define	NETARM_GEN_INTR_STATUS_RAW	(0x38)
+
+#define	NETARM_GEN_CACHE_CONTROL1	(0x40)
+#define	NETARM_GEN_CACHE_CONTROL2	(0x44)
+
+/* select bitfield definitions */
+
+/* System Control Register ( 0xFFB0_0000 ) */
+
+#define NETARM_GEN_SYS_CFG_LENDIAN	(0x80000000)
+#define NETARM_GEN_SYS_CFG_BENDIAN	(0x00000000)
+
+#define NETARM_GEN_SYS_CFG_BUSQRTR	(0x00000000)
+#define NETARM_GEN_SYS_CFG_BUSHALF	(0x20000000)
+#define NETARM_GEN_SYS_CFG_BUSFULL	(0x40000000)
+
+#define NETARM_GEN_SYS_CFG_BCLK_DISABLE	(0x10000000)
+
+#define NETARM_GEN_SYS_CFG_WDOG_EN	(0x01000000)
+#define NETARM_GEN_SYS_CFG_WDOG_IRQ	(0x00000000)
+#define NETARM_GEN_SYS_CFG_WDOG_FIQ	(0x00400000)
+#define NETARM_GEN_SYS_CFG_WDOG_RST	(0x00800000)
+#define NETARM_GEN_SYS_CFG_WDOG_24	(0x00000000)
+#define NETARM_GEN_SYS_CFG_WDOG_26	(0x00100000)
+#define NETARM_GEN_SYS_CFG_WDOG_28	(0x00200000)
+#define NETARM_GEN_SYS_CFG_WDOG_29	(0x00300000)
+
+#define NETARM_GEN_SYS_CFG_BUSMON_EN	(0x00040000)
+#define NETARM_GEN_SYS_CFG_BUSMON_128	(0x00000000)
+#define NETARM_GEN_SYS_CFG_BUSMON_64	(0x00010000)
+#define NETARM_GEN_SYS_CFG_BUSMON_32	(0x00020000)
+#define NETARM_GEN_SYS_CFG_BUSMON_16	(0x00030000)
+
+#define NETARM_GEN_SYS_CFG_USER_EN	(0x00008000)
+#define NETARM_GEN_SYS_CFG_BUSER_EN	(0x00004000)
+
+#define NETARM_GEN_SYS_CFG_BUSARB_INT	(0x00002000)
+#define NETARM_GEN_SYS_CFG_BUSARB_EXT	(0x00000000)
+
+#define NETARM_GEN_SYS_CFG_DMATST	(0x00001000)
+
+#define NETARM_GEN_SYS_CFG_TEALAST	(0x00000800)
+
+#define NETARM_GEN_SYS_CFG_ALIGN_ABORT	(0x00000400)
+
+#define NETARM_GEN_SYS_CFG_CACHE_EN	(0x00000200)
+
+#define NETARM_GEN_SYS_CFG_WRI_BUF_EN	(0x00000100)
+
+#define NETARM_GEN_SYS_CFG_CACHE_INIT	(0x00000080)
+
+/* PLL Control Register ( 0xFFB0_0008 ) */
+
+#define NETARM_GEN_PLL_CTL_PLLCNT_MASK	(0x0F000000)
+
+#define NETARM_GEN_PLL_CTL_PLLCNT(x)	(((x)<<24) & \
+                                         NETARM_GEN_PLL_CTL_PLLCNT_MASK)
+
+/* Software Service Register ( 0xFFB0_000C ) */
+
+#define	NETARM_GEN_SW_SVC_RESETA	(0x123)
+#define	NETARM_GEN_SW_SVC_RESETB	(0x321)
+
+/* PORT C Register ( 0xFFB0_0028 ) */
+
+#ifndef CONFIG_NETARM_NS7520
+#define	NETARM_GEN_PORT_MODE(x)		(((x)<<24) + (0xFF00))
+#define	NETARM_GEN_PORT_DIR(x)		(((x)<<16) + (0xFF00))
+#else
+#define	NETARM_GEN_PORT_MODE(x)		((x)<<24)
+#define	NETARM_GEN_PORT_DIR(x)		((x)<<16)
+#define NETARM_GEN_PORT_CSF(x)    ((x)<<8)
+#endif
+
+/* Timer Registers ( 0xFFB0_0010 0xFFB0_0018 ) */
+
+#define	NETARM_GEN_TCTL_ENABLE		(0x80000000)
+#define	NETARM_GEN_TCTL_INT_ENABLE	(0x40000000)
+
+#define	NETARM_GEN_TCTL_USE_IRQ		(0x00000000)
+#define	NETARM_GEN_TCTL_USE_FIQ		(0x20000000)
+
+#define	NETARM_GEN_TCTL_USE_PRESCALE	(0x10000000)
+#define	NETARM_GEN_TCTL_INIT_COUNT(x)	((x) & 0x1FF)
+
+#define	NETARM_GEN_TSTAT_INTPEN		(0x40000000)
+#define	NETARM_GEN_TSTAT_CTC_MASK	(0x000001FF)
+
+/* prescale to msecs conversion */
+
+#define	NETARM_GEN_TIMER_MSEC_P(x)	( ( ( 20480 ) * ( 0x1FF - ( (x) &	    \
+                                            NETARM_GEN_TSTAT_CTC_MASK ) +   \
+					    1 ) ) / (NETARM_XTAL_FREQ/1000) )
+
+#define	NETARM_GEN_TIMER_SET_HZ(x)	( ( ((NETARM_XTAL_FREQ/(20480*(x)))-1) & \
+					  NETARM_GEN_TSTAT_CTC_MASK ) | \
+					  NETARM_GEN_TCTL_USE_PRESCALE )
+
+#if 0
+/* ifdef CONFIG_NETARM_PLL_BYPASS else */
+#error test
+#define	NETARM_GEN_TIMER_MSEC_P(x)	( ( ( 4096 ) * ( 0x1FF - ( (x) &    \
+                                            NETARM_GEN_TSTAT_CTC_MASK ) +   \
+					    1 ) ) / (NETARM_XTAL_FREQ/1000) )
+
+#define	NETARM_GEN_TIMER_SET_HZ(x)	( ( ((NETARM_XTAL_FREQ/(4096*(x)))-1) & \
+					  NETARM_GEN_TSTAT_CTC_MASK ) | \
+					  NETARM_GEN_TCTL_USE_PRESCALE )
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_mem_module.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_mem_module.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_mem_module.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_mem_module.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,183 @@
+/*
+ * include/asm-armnommu/arch-netarm/netarm_mem_module.h
+ *
+ * Copyright (C) 2003 Videon Central, Inc.
+ * Copyright (C) 2000, 2001 NETsilicon, Inc.
+ * Copyright (C) 2000, 2001 Red Hat, Inc.
+ *
+ * This software is copyrighted by Red Hat. LICENSEE agrees that
+ * it will not delete this copyright notice, trademarks or protective
+ * notices from any copy made by LICENSEE.
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall Red Hat
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : Joe deBlaquiere
+ * 
+ * Modified to support NS7520 by Art Shipkowski <art@videon-central.com>
+ */
+
+#ifndef __NETARM_MEM_MODULE_REGISTERS_H
+#define __NETARM_MEM_MODULE_REGISTERS_H
+
+/* GEN unit register offsets */
+
+#define	NETARM_MEM_MODULE_BASE		(0xFFC00000)
+
+#define	NETARM_MEM_MODULE_CONFIG	(0x00)
+#define	NETARM_MEM_CS0_BASE_ADDR	(0x10)
+#define	NETARM_MEM_CS0_OPTIONS		(0x14)
+#define	NETARM_MEM_CS1_BASE_ADDR	(0x20)
+#define	NETARM_MEM_CS1_OPTIONS		(0x24)
+#define	NETARM_MEM_CS2_BASE_ADDR	(0x30)
+#define	NETARM_MEM_CS2_OPTIONS		(0x34)
+#define	NETARM_MEM_CS3_BASE_ADDR	(0x40)
+#define	NETARM_MEM_CS3_OPTIONS		(0x44)
+#define	NETARM_MEM_CS4_BASE_ADDR	(0x50)
+#define	NETARM_MEM_CS4_OPTIONS		(0x54)
+
+/* select bitfield defintions */
+
+/* Module Configuration Register ( 0xFFC0_0000 ) */
+
+#define NETARM_MEM_CFG_REFR_COUNT_MASK	(0xFF000000)
+#define NETARM_MEM_CFG_REFRESH_EN	(0x00800000)
+
+#define NETARM_MEM_CFG_REFR_CYCLE_8CLKS	(0x00000000)
+#define NETARM_MEM_CFG_REFR_CYCLE_6CLKS	(0x00200000)
+#define NETARM_MEM_CFG_REFR_CYCLE_5CLKS	(0x00400000)
+#define NETARM_MEM_CFG_REFR_CYCLE_4CLKS	(0x00600000)
+
+#define NETARM_MEM_CFG_PORTC_AMUX	(0x00100000)
+
+#define NETARM_MEM_CFG_A27_ADDR		(0x00080000)
+#define NETARM_MEM_CFG_A27_CS0OE	(0x00000000)
+
+#define NETARM_MEM_CFG_A26_ADDR		(0x00040000)
+#define NETARM_MEM_CFG_A26_CS0WE	(0x00000000)
+
+#define NETARM_MEM_CFG_A25_ADDR		(0x00020000)
+#define NETARM_MEM_CFG_A25_BLAST	(0x00000000)
+
+#define NETARM_MEM_CFG_PORTC_AMUX2	(0x00010000)
+
+
+/* range on this period is about 1 to 275 usec (with 18.432MHz clock)   */
+/* the expression will round down, so make sure to reverse it to verify */
+/* it is what you want. period = [( count + 1 ) * 20] / Fcrystal        */
+/* (note: Fxtal = Fcrystal/5, see HWRefGuide sections 8.2.5 and 11.3.2) */
+
+#define	NETARM_MEM_REFR_PERIOD_USEC(p)	(NETARM_MEM_CFG_REFR_COUNT_MASK & \
+					 (((((NETARM_XTAL_FREQ/(1000))*p)/(20000) \
+					    ) - (1) ) << (24)))
+
+#if 0
+/* range on this period is about 1 to 275 usec (with 18.432MHz clock) */
+/* the expression will round down, so make sure to reverse it toverify */
+/* it is what you want. period = [( count + 1 ) * 4] / Fxtal          */
+
+#define	NETARM_MEM_REFR_PERIOD_USEC(p)	(NETARM_MEM_CFG_REFR_COUNT_MASK & \
+					 (((((NETARM_XTAL_FREQ/(1000))*p)/(4000) \
+					    ) - (1) ) << (24)))
+#endif
+
+/* Base Address Registers (0xFFC0_00X0) */
+
+#define NETARM_MEM_BAR_BASE_MASK	(0xFFFFF000)
+
+/* macro to define base */
+
+#define NETARM_MEM_BAR_BASE(x)		((x) & NETARM_MEM_BAR_BASE_MASK)
+
+#define NETARM_MEM_BAR_DRAM_FP		(0x00000000)
+#define NETARM_MEM_BAR_DRAM_EDO		(0x00000100)
+#define NETARM_MEM_BAR_DRAM_SYNC	(0x00000200)
+
+#define NETARM_MEM_BAR_DRAM_MUX_INT	(0x00000000)
+#define NETARM_MEM_BAR_DRAM_MUX_EXT	(0x00000080)
+
+#define NETARM_MEM_BAR_DRAM_MUX_BAL	(0x00000000)
+#define NETARM_MEM_BAR_DRAM_MUX_UNBAL	(0x00000020)
+
+#define NETARM_MEM_BAR_1BCLK_IDLE	(0x00000010)
+
+#define NETARM_MEM_BAR_DRAM_SEL		(0x00000008)
+
+#define NETARM_MEM_BAR_BURST_EN		(0x00000004)
+
+#define NETARM_MEM_BAR_WRT_PROT		(0x00000002)
+
+#define NETARM_MEM_BAR_VALID		(0x00000001)
+
+/* Option Registers (0xFFC0_00X4) */
+
+/* macro to define which bits of the base are significant */
+
+#define NETARM_MEM_OPT_BASE_USE(x)	((x) & NETARM_MEM_BAR_BASE_MASK)
+
+#define NETARM_MEM_OPT_WAIT_MASK	(0x00000F00)
+
+#define	NETARM_MEM_OPT_WAIT_STATES(x)	(((x) << 8 ) & NETARM_MEM_OPT_WAIT_MASK )
+
+#define NETARM_MEM_OPT_BCYC_1		(0x00000000)
+#define NETARM_MEM_OPT_BCYC_2		(0x00000040)
+#define NETARM_MEM_OPT_BCYC_3		(0x00000080)
+#define NETARM_MEM_OPT_BCYC_4		(0x000000C0)
+
+#define NETARM_MEM_OPT_BSIZE_2		(0x00000000)
+#define NETARM_MEM_OPT_BSIZE_4		(0x00000010)
+#define NETARM_MEM_OPT_BSIZE_8		(0x00000020)
+#define NETARM_MEM_OPT_BSIZE_16		(0x00000030)
+
+#define NETARM_MEM_OPT_32BIT		(0x00000000)
+#define NETARM_MEM_OPT_16BIT		(0x00000004)
+#define NETARM_MEM_OPT_8BIT		(0x00000008)
+#define NETARM_MEM_OPT_32BIT_EXT_ACK	(0x0000000C)
+
+#define NETARM_MEM_OPT_BUS_SIZE_MASK	(0x0000000C)
+
+#define NETARM_MEM_OPT_READ_ASYNC	(0x00000000)
+#define NETARM_MEM_OPT_READ_SYNC	(0x00000002)
+
+#define NETARM_MEM_OPT_WRITE_ASYNC	(0x00000000)
+#define NETARM_MEM_OPT_WRITE_SYNC	(0x00000001)
+
+#ifdef CONFIG_NETARM_NS7520  
+/* The NS7520 has a second options register for each chip select */
+#define	NETARM_MEM_CS0_OPTIONS_B  (0x18)
+#define	NETARM_MEM_CS1_OPTIONS_B  (0x28)
+#define	NETARM_MEM_CS2_OPTIONS_B  (0x38)
+#define	NETARM_MEM_CS3_OPTIONS_B  (0x48)
+#define	NETARM_MEM_CS4_OPTIONS_B  (0x58)
+
+/* Option B Registers (0xFFC0_00x8) */
+#define NETARM_MEM_OPTB_SYNC_1_STAGE	(0x00000001)
+#define NETARM_MEM_OPTB_SYNC_2_STAGE	(0x00000002)
+#define NETARM_MEM_OPTB_BCYC_PLUS0   	(0x00000000)
+#define NETARM_MEM_OPTB_BCYC_PLUS4   	(0x00000004)
+#define NETARM_MEM_OPTB_BCYC_PLUS8   	(0x00000008)
+#define NETARM_MEM_OPTB_BCYC_PLUS12  	(0x0000000C)
+
+#define NETARM_MEM_OPTB_WAIT_PLUS0   	(0x00000000)
+#define NETARM_MEM_OPTB_WAIT_PLUS16   	(0x00000010)
+#define NETARM_MEM_OPTB_WAIT_PLUS32   	(0x00000020)
+#define NETARM_MEM_OPTB_WAIT_PLUS48   	(0x00000030)
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_mmap.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_mmap.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_mmap.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_mmap.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,104 @@
+/*
+ * include/asm-armnommu/arch-netarm/netarm_mmap.h
+ *
+ * Copyright (C) 2003 Videon Central, Inc.
+ * Copyright (C) 2000, 2001 NETsilicon, Inc.
+ * Copyright (C) 2000, 2001 Red Hat, Inc.
+ *
+ * This software is copyrighted by Red Hat. LICENSEE agrees that
+ * it will not delete this copyright notice, trademarks or protective
+ * notices from any copy made by LICENSEE.
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall Red Hat
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : Joe deBlaquiere
+ *
+ * Modified to support NS7520 by Art Shipkowski <art@videon-central.com>
+ */
+
+#ifndef __NETARM_MEMORY_MAP_H
+#define __NETARM_MEMORY_MAP_H
+
+#include <linux/autoconf.h>
+
+#ifndef (CONFIG_NETARM_NS7520)
+/* structure definitions for per-unit configuration data */
+#define	NETARM_MMAP_CS0_BASE	(0x10000000)	/* Flash AM29DL323DB */
+#define	NETARM_MMAP_CS0_MASK	(0xFF800000)	/* 8M bytes */
+
+#define	NETARM_MMAP_CS1_BASE	(0x00000000)	/* EDO DRAM MT4LC4M16R6 */
+#define	NETARM_MMAP_CS1_MASK	(0xFF000000)	/* 16M bytes */
+
+#define	NETARM_MMAP_CS2_BASE	(0x01000000)	/* EDO DRAM MT4LC4M16R6 */
+#define	NETARM_MMAP_CS2_MASK	(0xFF000000)	/* 16M bytes */
+
+#define	NETARM_MMAP_CS3_BASE	(0x20000000)	/* EEPROM - AT28LV64B */
+#define	NETARM_MMAP_CS3_MASK	(0xFFFFE000)	/* 8K bytes */
+
+#define	NETARM_MMAP_CS4_BASE	(0x30000000)	/* EPSON SED1355 */
+#define	NETARM_MMAP_CS4_MASK	(0xFF000000)	/* Memory Mapped I/O */
+#else
+/*
+ * The NS7520 has a nasty bug relating to SDRAM refresh if you place any
+ * chip selects above the first 256MB of addressable space.
+ *
+ * There is also a limit on memory-to-memory DMA that requires the source
+ * address be in the first 512MB addressable.
+ *
+ * These defaults are a little silly IMHO, anyhow. Perhaps they should be
+ * set up in the kernel configuration for those not using a bootloader?
+ */
+#define	NETARM_MMAP_CS0_BASE	(FLASH_BASE) 	/* Flash AM29DL323DB */
+#define	NETARM_MMAP_CS0_MASK	(0xFF800000)	/* 8M bytes */
+
+#define	NETARM_MMAP_CS1_BASE	(DRAM_BASE) 	/* EDO DRAM MT4LC4M16R6 */
+#define	NETARM_MMAP_CS1_MASK	(0xFF000000)	/* 16M bytes */
+
+#define	NETARM_MMAP_CS2_BASE	(0x01000000)	/* EDO DRAM MT4LC4M16R6 */
+#define	NETARM_MMAP_CS2_MASK	(0xFF000000)	/* 16M bytes */
+
+#define	NETARM_MMAP_CS3_BASE	(0x02000000)	/* EEPROM - AT28LV64B */
+#define	NETARM_MMAP_CS3_MASK	(0xFFFFE000)	/* 8K bytes */
+
+#define	NETARM_MMAP_CS4_BASE	(0x03000000)	/* EPSON SED1355 */
+#define	NETARM_MMAP_CS4_MASK	(0xFF000000)	/* Memory Mapped I/O */
+#endif
+
+#define NETARM_MMAP_RAM_BASE	(NETARM_MMAP_CS1_BASE)
+#define NETARM_MMAP_FLASH_BASE	(NETARM_MMAP_CS0_BASE)
+#define NETARM_MMAP_EEPROM_BASE	(NETARM_MMAP_CS3_BASE)
+#define NETARM_MMAP_FBDEV_BASE	(NETARM_MMAP_CS4_BASE)
+
+#ifdef	CONFIG_NETARM_NET40_REV2
+#define NETARM_MMAP_FLASH_COPY_SIZE	(0x00100000)	/* 1MB copy */
+#else
+#define NETARM_MMAP_FLASH_COPY_SIZE	(0x00400000)	/* 4MB copy */
+#endif
+
+#ifdef	CONFIG_ETHER_NETARM
+/* the OUI is defined via make xconfig (arch/armnommu/drivers/net/Config.in) */
+/* #define	NETARM_OUI		(0x0040AF) */
+
+#define	NETARM_OUI_BYTE1	((NETARM_OUI >> 16) & 0xFF)
+#define NETARM_OUI_BYTE2	((NETARM_OUI >> 8) & 0xFF)
+#define NETARM_OUI_BYTE3	(NETARM_OUI & 0xFF)
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_nvram.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_nvram.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_nvram.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_nvram.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,80 @@
+/*
+ * include/asm-armnommu/arch-netarm/netarm_nvram.h
+ *
+ * Copyright (C) 2000 NETsilicon, Inc.
+ * Copyright (C) 2000 WireSpeed Communications Corporation
+ *
+ * This software is copyrighted by WireSpeed. LICENSEE agrees that
+ * it will not delete this copyright notice, trademarks or protective
+ * notices from any copy made by LICENSEE.
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall WireSpeed
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : Joe deBlaquiere
+ */
+
+#ifndef __NETARM_NON_VOLATILE_MEMORY_H
+#define __NETARM_NON_VOLATILE_MEMORY_H
+
+/* structure definitions for per-unit configuration data */
+
+/* count determines how many dwords are used to calculate checksum */
+#define	NETARM_NVRAM_DWORD_COUNT	(11)
+
+typedef struct
+{
+  unsigned char serialNumber[8];
+  unsigned long ipAddress;
+  unsigned long subnetMask;
+  unsigned long gateway;
+  long		useDhcp;
+  unsigned long waitTime;
+  unsigned long baudrate;
+  unsigned long telnetMagic;
+  unsigned long reserved[1];
+  unsigned long checksum;
+} NA_dev_board_params_t;
+
+
+/* auxiliary functions, moved here from setup.c */
+static inline int
+parse_decimal(char ch)
+{
+	if ('0' >  ch) return -1;
+	if ('9' >= ch) return ch - '0' ;
+	return -1;
+}
+
+static inline unsigned int
+compute_checksum(NA_dev_board_params_t *pParams)
+{
+	int i;
+	unsigned int *pInt = (unsigned int *)pParams ;
+	unsigned int sum = 0;
+	for ( i = 0 ; i < NETARM_NVRAM_DWORD_COUNT ; i++ )
+	{
+		sum += pInt[i];
+	}
+	
+	if ( sum != 0 ) return -1 ;
+	return 0 ;
+}
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_registers.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_registers.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_registers.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_registers.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,94 @@
+/*
+ * linux/include/asm-arm/arch-netarm/netarm_registers.h
+ *
+ * Copyright (C) 2003 Videon Central, Inc.
+ * Copyright (C) 2000, 2001 NETsilicon, Inc.
+ * Copyright (C) 2000, 2001 WireSpeed Communications Corporation
+ *
+ * This software is copyrighted by WireSpeed. LICENSEE agrees that
+ * it will not delete this copyright notice, trademarks or protective
+ * notices from any copy made by LICENSEE.
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall WireSpeed
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : Joe deBlaquiere
+ *
+ * Modified to support NS7520 by Art Shipkowski <art@videon-central.com>
+ */
+
+#ifndef __NET_ARM_REGISTERS_H
+#define __NET_ARM_REGISTERS_H
+
+/* fundamental constants : */
+/* the input crystal/clock frequency ( in Hz ) */ 
+#define	NETARM_XTAL_FREQ_25MHz		(18432000)
+#define	NETARM_XTAL_FREQ_33MHz		(23698000)
+#define NETARM_XTAL_FREQ_48MHz 		(48000000)
+#define NETARM_XTAL_FREQ_55MHz 		(55000000)
+#define NETARM_XTAL_FREQ_EMLIN1		(20000000)
+
+/* the frequency of SYS_CLK */
+#if defined(CONFIG_NETARM_EMLIN)
+
+/* EMLIN board:  33 MHz (exp.) */
+#define	NETARM_PLL_COUNT_VAL		6
+#define NETARM_XTAL_FREQ		NETARM_XTAL_FREQ_25MHz
+
+#elif defined(CONFIG_NETARM_NET40_REV2)
+
+/* NET+40 Rev2 boards:  33 MHz (with NETARM_XTAL_FREQ_25MHz) */
+#define	NETARM_PLL_COUNT_VAL		6
+#define	NETARM_XTAL_FREQ		NETARM_XTAL_FREQ_25MHz
+
+#elif defined(CONFIG_NETARM_NET40_REV4)
+
+/* NET+40 Rev4 boards with EDO must clock slower: 25 MHz (with
+   NETARM_XTAL_FREQ_25MHz) 4 */
+#define	NETARM_PLL_COUNT_VAL		4
+#define	NETARM_XTAL_FREQ		NETARM_XTAL_FREQ_25MHz
+
+#elif defined(CONFIG_NETARM_NET50)
+
+/* NET+50 boards:  40 MHz (with NETARM_XTAL_FREQ_25MHz) */
+#define NETARM_PLL_COUNT_VAL		8
+#define	NETARM_XTAL_FREQ		NETARM_XTAL_FREQ_25MHz
+
+#else /* CONFIG_NETARM_NS7520 */
+
+#define	NETARM_PLL_COUNT_VAL		0
+
+#if defined(CONFIG_BOARD_UNC20)
+#define	NETARM_XTAL_FREQ		NETARM_XTAL_FREQ_48MHz
+#else
+/* Not a good assumption */
+#define	NETARM_XTAL_FREQ		NETARM_XTAL_FREQ_55MHz 
+#endif
+
+#endif
+
+#include "arm_registers.h"
+#include "netarm_gen_module.h"
+#include "netarm_mem_module.h"
+#include "netarm_ser_module.h"
+#include "netarm_eni_module.h"
+#include "netarm_dma_module.h"
+#include "netarm_eth_module.h"
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_ser_module.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_ser_module.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/netarm_ser_module.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/netarm_ser_module.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,351 @@
+/*
+ * linux/include/asm-arm/arch-netarm/netarm_ser_module.h
+ *
+ * Copyright (C) 2000 NETsilicon, Inc.
+ * Copyright (C) 2000 Red Hat, Inc.
+ *
+ * This software is copyrighted by Red Hat. LICENSEE agrees that
+ * it will not delete this copyright notice, trademarks or protective
+ * notices from any copy made by LICENSEE.
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall Red Hat
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : Joe deBlaquiere
+ *             Clark Williams
+ */
+
+#ifndef __NETARM_SER_MODULE_REGISTERS_H
+#define __NETARM_SER_MODULE_REGISTERS_H
+
+#include <linux/autoconf.h>
+
+#ifndef	__ASSEMBLER__
+
+#include <asm/types.h>
+
+// serial channel control structure
+typedef struct {
+  u32	ctrl_a;
+  u32	ctrl_b;
+  u32	status_a;
+  u32	bitrate;
+  u32	fifo;
+  u32	rx_buf_timer;
+  u32	rx_char_timer;
+  u32	rx_match;
+  u32	rx_match_mask;
+  u32	ctrl_c;
+  u32	status_b;
+  u32	status_c;
+  u32	fifo_last;
+  u32	unused[3];
+} netarm_serial_channel_t;
+
+#endif
+
+/* SER unit register offsets */
+
+#ifdef CONFIG_ARCH_NETARM
+#define	NETARM_SER_MODULE_BASE		(0xFFD00000)
+#else
+extern serial_channel_t netarm_dummy_registers[];
+#define NETARM_SER_MODULE_BASE		(netarm_dummy_registers)
+#ifndef NETARM_XTAL_FREQ
+#define NETARM_XTAL_FREQ                18432000
+#endif
+#endif
+
+/* calculate the sysclk value from the pll setting */
+#define	NETARM_PLLED_SYSCLK_FREQ	(( NETARM_XTAL_FREQ / 5 ) * \
+					 ( NETARM_PLL_COUNT_VAL + 3 ))
+
+#define get_serial_channel(c) (&(((netarm_serial_channel_t *)NETARM_SER_MODULE_BASE)[c]))
+
+#define	NETARM_SER_CH1_CTRL_A		(0x00)
+#define	NETARM_SER_CH1_CTRL_B		(0x04)
+#define	NETARM_SER_CH1_STATUS_A		(0x08)
+#define	NETARM_SER_CH1_BITRATE		(0x0C)
+#define	NETARM_SER_CH1_FIFO		(0x10)
+#define	NETARM_SER_CH1_RX_BUF_TMR	(0x14)
+#define	NETARM_SER_CH1_RX_CHAR_TMR	(0x18)
+#define	NETARM_SER_CH1_RX_MATCH		(0x1c)
+#define	NETARM_SER_CH1_RX_MATCH_MASK	(0x20)
+#define	NETARM_SER_CH1_CTRL_C		(0x24)
+#define	NETARM_SER_CH1_STATUS_B		(0x28)
+#define	NETARM_SER_CH1_STATUS_C		(0x2c)
+#define	NETARM_SER_CH1_FIFO_LAST	(0x30)
+
+#define	NETARM_SER_CH2_CTRL_A		(0x40)
+#define	NETARM_SER_CH2_CTRL_B		(0x44)
+#define	NETARM_SER_CH2_STATUS_A		(0x48)
+#define	NETARM_SER_CH2_BITRATE		(0x4C)
+#define	NETARM_SER_CH2_FIFO		(0x50)
+#define	NETARM_SER_CH2_RX_BUF_TMR	(0x54)
+#define	NETARM_SER_CH2_RX_CHAR_TMR	(0x58)
+#define	NETARM_SER_CH2_RX_MATCH		(0x5c)
+#define	NETARM_SER_CH2_RX_MATCH_MASK	(0x60)
+#define	NETARM_SER_CH2_CTRL_C		(0x64)
+#define	NETARM_SER_CH2_STATUS_B		(0x68)
+#define	NETARM_SER_CH2_STATUS_C		(0x6c)
+#define	NETARM_SER_CH2_FIFO_LAST	(0x70)
+
+/* select bitfield defintions */
+
+/* Control Register A */
+
+#define	NETARM_SER_CTLA_ENABLE		(0x80000000)
+#define	NETARM_SER_CTLA_BRK		(0x40000000)
+
+#define	NETARM_SER_CTLA_STICKP		(0x20000000)
+
+#define	NETARM_SER_CTLA_P_EVEN		(0x18000000)
+#define	NETARM_SER_CTLA_P_ODD		(0x08000000)
+#define	NETARM_SER_CTLA_P_NONE		(0x00000000)
+
+/* if you read the errata, you will find that the STOP bits don't work right */
+#define	NETARM_SER_CTLA_2STOP		(0x00000000)
+#define	NETARM_SER_CTLA_3STOP		(0x04000000)
+
+#define	NETARM_SER_CTLA_5BITS		(0x00000000)
+#define	NETARM_SER_CTLA_6BITS		(0x01000000)
+#define	NETARM_SER_CTLA_7BITS		(0x02000000)
+#define	NETARM_SER_CTLA_8BITS		(0x03000000)
+
+#define	NETARM_SER_CTLA_CTSTX		(0x00800000)
+#define	NETARM_SER_CTLA_RTSRX		(0x00400000)
+
+#define	NETARM_SER_CTLA_LOOP_REM	(0x00200000)
+#define	NETARM_SER_CTLA_LOOP_LOC	(0x00100000)
+
+#define	NETARM_SER_CTLA_GPIO2		(0x00080000)
+#define	NETARM_SER_CTLA_GPIO1		(0x00040000)
+
+#define	NETARM_SER_CTLA_DTR_EN		(0x00020000)
+#define	NETARM_SER_CTLA_RTS_EN		(0x00010000)
+
+#define	NETARM_SER_CTLA_IE_RX_BRK	(0x00008000)
+#define	NETARM_SER_CTLA_IE_RX_FRMERR	(0x00004000)
+#define	NETARM_SER_CTLA_IE_RX_PARERR	(0x00002000)
+#define	NETARM_SER_CTLA_IE_RX_OVERRUN	(0x00001000)
+#define	NETARM_SER_CTLA_IE_RX_RDY	(0x00000800)
+#define	NETARM_SER_CTLA_IE_RX_HALF	(0x00000400)
+#define	NETARM_SER_CTLA_IE_RX_FULL	(0x00000200)
+#define	NETARM_SER_CTLA_IE_RX_DMAEN	(0x00000100)
+#define	NETARM_SER_CTLA_IE_RX_DCD	(0x00000080)
+#define	NETARM_SER_CTLA_IE_RX_RI	(0x00000040)
+#define	NETARM_SER_CTLA_IE_RX_DSR	(0x00000020)
+
+#define NETARM_SER_CTLA_IE_RX_ALL	(NETARM_SER_CTLA_IE_RX_BRK \
+					|NETARM_SER_CTLA_IE_RX_FRMERR \
+					|NETARM_SER_CTLA_IE_RX_PARERR \
+					|NETARM_SER_CTLA_IE_RX_OVERRUN \
+					|NETARM_SER_CTLA_IE_RX_RDY \
+					|NETARM_SER_CTLA_IE_RX_HALF \
+					|NETARM_SER_CTLA_IE_RX_FULL \
+					|NETARM_SER_CTLA_IE_RX_DMAEN \
+					|NETARM_SER_CTLA_IE_RX_DCD \
+					|NETARM_SER_CTLA_IE_RX_RI \
+					|NETARM_SER_CTLA_IE_RX_DSR)
+
+#define	NETARM_SER_CTLA_IE_TX_CTS	(0x00000010)
+#define	NETARM_SER_CTLA_IE_TX_EMPTY	(0x00000008)
+#define	NETARM_SER_CTLA_IE_TX_HALF	(0x00000004)
+#define	NETARM_SER_CTLA_IE_TX_FULL	(0x00000002)
+#define	NETARM_SER_CTLA_IE_TX_DMAEN	(0x00000001)
+
+#define NETARM_SER_CTLA_IE_TX_ALL	(NETARM_SER_CTLA_IE_TX_CTS \
+					|NETARM_SER_CTLA_IE_TX_EMPTY \
+					|NETARM_SER_CTLA_IE_TX_HALF \
+					|NETARM_SER_CTLA_IE_TX_FULL \
+					|NETARM_SER_CTLA_IE_TX_DMAEN)
+
+/* Control Register B */
+
+#define	NETARM_SER_CTLB_MATCH1_EN	(0x80000000)
+#define	NETARM_SER_CTLB_MATCH2_EN	(0x40000000)
+#define	NETARM_SER_CTLB_MATCH3_EN	(0x20000000)
+#define	NETARM_SER_CTLB_MATCH4_EN	(0x10000000)
+
+#define	NETARM_SER_CTLB_RBGT_EN		(0x08000000)
+#define	NETARM_SER_CTLB_RCGT_EN		(0x04000000)
+
+#define	NETARM_SER_CTLB_UART_MODE	(0x00000000)
+#define	NETARM_SER_CTLB_HDLC_MODE	(0x00100000)
+#define	NETARM_SER_CTLB_SPI_MAS_MODE	(0x00200000)
+#define	NETARM_SER_CTLB_SPI_SLV_MODE	(0x00300000)
+
+#define	NETARM_SER_CTLB_REV_BIT_ORDER	(0x00080000)
+
+#define	NETARM_SER_CTLB_MAM1		(0x00040000)
+#define	NETARM_SER_CTLB_MAM2		(0x00020000)
+
+/* Status Register A */
+
+#define	NETARM_SER_STATA_MATCH1		(0x80000000)
+#define	NETARM_SER_STATA_MATCH2		(0x40000000)
+#define	NETARM_SER_STATA_MATCH3		(0x20000000)
+#define	NETARM_SER_STATA_MATCH4		(0x10000000)
+
+#define	NETARM_SER_STATA_BGAP		(0x80000000)
+#define	NETARM_SER_STATA_CGAP		(0x40000000)
+
+#define	NETARM_SER_STATA_RX_1B		(0x00100000)
+#define	NETARM_SER_STATA_RX_2B		(0x00200000)
+#define	NETARM_SER_STATA_RX_3B		(0x00300000)
+#define	NETARM_SER_STATA_RX_4B		(0x00000000)
+
+/* downshifted values */
+
+#define	NETARM_SER_STATA_RXFDB_1BYTES	(0x001)
+#define	NETARM_SER_STATA_RXFDB_2BYTES	(0x002)
+#define	NETARM_SER_STATA_RXFDB_3BYTES	(0x003)
+#define	NETARM_SER_STATA_RXFDB_4BYTES	(0x000)
+
+#define	NETARM_SER_STATA_RXFDB_MASK	(0x00300000)
+#define	NETARM_SER_STATA_RXFDB(x)	(((x) & NETARM_SER_STATA_RXFDB_MASK) \
+					 >> 20)
+
+#define	NETARM_SER_STATA_DCD		(0x00080000)
+#define	NETARM_SER_STATA_RI		(0x00040000)
+#define	NETARM_SER_STATA_DSR		(0x00020000)
+#define	NETARM_SER_STATA_CTS		(0x00010000)
+
+#define	NETARM_SER_STATA_RX_BRK		(0x00008000)
+#define	NETARM_SER_STATA_RX_FRMERR	(0x00004000)
+#define	NETARM_SER_STATA_RX_PARERR	(0x00002000)
+#define	NETARM_SER_STATA_RX_OVERRUN	(0x00001000)
+#define	NETARM_SER_STATA_RX_RDY		(0x00000800)
+#define	NETARM_SER_STATA_RX_HALF	(0x00000400)
+#define	NETARM_SER_STATA_RX_CLOSED	(0x00000200)
+#define	NETARM_SER_STATA_RX_FULL	(0x00000100)
+#define	NETARM_SER_STATA_RX_DCD		(0x00000080)
+#define	NETARM_SER_STATA_RX_RI		(0x00000040)
+#define	NETARM_SER_STATA_RX_DSR		(0x00000020)
+
+#define	NETARM_SER_STATA_TX_CTS		(0x00000010)
+#define	NETARM_SER_STATA_TX_RDY		(0x00000008)
+#define	NETARM_SER_STATA_TX_HALF	(0x00000004)
+#define	NETARM_SER_STATA_TX_FULL	(0x00000002)
+#define	NETARM_SER_STATA_TX_DMAEN	(0x00000001)
+
+/* you have to clear all receive signals to get the fifo to move forward */
+#define NETARM_SER_STATA_CLR_ALL	(NETARM_SER_STATA_RX_BRK | \
+					 NETARM_SER_STATA_RX_FRMERR | \
+					 NETARM_SER_STATA_RX_PARERR | \
+					 NETARM_SER_STATA_RX_OVERRUN | \
+					 NETARM_SER_STATA_RX_HALF | \
+					 NETARM_SER_STATA_RX_CLOSED | \
+					 NETARM_SER_STATA_RX_FULL | \
+					 NETARM_SER_STATA_RX_DCD | \
+					 NETARM_SER_STATA_RX_RI | \
+					 NETARM_SER_STATA_RX_DSR | \
+					 NETARM_SER_STATA_TX_CTS )
+
+/* Bit Rate Registers */
+
+#define	NETARM_SER_BR_EN		(0x80000000)
+#define	NETARM_SER_BR_TMODE		(0x40000000)
+
+#define	NETARM_SER_BR_RX_CLK_INT	(0x00000000)
+#define	NETARM_SER_BR_RX_CLK_EXT	(0x20000000)
+#define	NETARM_SER_BR_TX_CLK_INT	(0x00000000)
+#define	NETARM_SER_BR_TX_CLK_EXT	(0x10000000)
+
+#define	NETARM_SER_BR_RX_CLK_DRV	(0x08000000)
+#define	NETARM_SER_BR_TX_CLK_DRV	(0x04000000)
+
+#define	NETARM_SER_BR_CLK_EXT_5		(0x00000000)
+#define	NETARM_SER_BR_CLK_SYSTEM	(0x01000000)
+#define	NETARM_SER_BR_CLK_OUT1A		(0x02000000)
+#define	NETARM_SER_BR_CLK_OUT2A		(0x03000000)
+
+#define	NETARM_SER_BR_TX_CLK_INV	(0x00800000)
+#define	NETARM_SER_BR_RX_CLK_INV	(0x00400000)
+
+/* complete settings assuming system clock input is 18MHz */
+
+#define	NETARM_SER_BR_MASK		(0x000007FF)
+
+/* bit rate determined from equation Fbr = Fxtal / [ 10 * ( N + 1 ) ] */
+/* from section 7.5.4 of HW Ref Guide */
+
+#ifdef CONFIG_NETARM_PLL_BYPASS
+#define	NETARM_SER_BR_X16(x)	( NETARM_SER_BR_EN | 			\
+				  NETARM_SER_BR_RX_CLK_INT | 		\
+				  NETARM_SER_BR_TX_CLK_INT | 		\
+				  NETARM_SER_BR_CLK_EXT_5 | 		\
+				  ( ( ( ( NETARM_XTAL_FREQ / 		\
+				          ( x * 10 ) ) - 1 ) /	16 ) & 	\
+				    NETARM_SER_BR_MASK ) )
+#else
+#define	NETARM_SER_BR_X16(x)	( NETARM_SER_BR_EN | 			\
+				  NETARM_SER_BR_RX_CLK_INT | 		\
+				  NETARM_SER_BR_TX_CLK_INT | 		\
+				  NETARM_SER_BR_CLK_SYSTEM | 		\
+				  ( ( ( ( NETARM_PLLED_SYSCLK_FREQ / 		\
+				          ( x * 2 ) ) - 1 ) /	16 ) & 	\
+				    NETARM_SER_BR_MASK ) )
+#endif
+
+/* Receive Buffer Gap Timer */
+
+#define	NETARM_SER_RX_GAP_TIMER_EN	(0x80000000)
+#define	NETARM_SER_RX_GAP_MASK		(0x00003FFF)
+
+/* rx gap is a function of bit rate x */
+
+#ifdef CONFIG_NETARM_PLL_BYPASS
+#define	NETARM_SER_RXGAP(x)	( NETARM_SER_RX_GAP_TIMER_EN |		\
+				  ( ( ( ( 10 * NETARM_XTAL_FREQ ) /	\
+				        ( x * 5 * 512 ) ) - 1 ) & 	\
+			              NETARM_SER_RX_GAP_MASK ) )
+#else
+#define	NETARM_SER_RXGAP(x)	( NETARM_SER_RX_GAP_TIMER_EN |			\
+				  ( ( ( ( 2 * NETARM_PLLED_SYSCLK_FREQ ) /	\
+				        ( x * 512 ) ) - 1 ) & 			\
+			              NETARM_SER_RX_GAP_MASK ) )
+#endif
+
+#if 0
+#define	NETARM_SER_RXGAP(x)	( NETARM_SER_RX_GAP_TIMER_EN |		\
+				  ( ( ( ( 2 * NETARM_PLLED_SYSCLK_FREQ ) /	\
+				        ( x * 5 * 512 ) ) - 1 ) & 	\
+			              NETARM_SER_RX_GAP_MASK ) )
+#define	NETARM_SER_RXGAP(x)	( NETARM_SER_RX_GAP_TIMER_EN |		\
+				  ( ( ( ( 10 * NETARM_XTAL_FREQ ) /	\
+				        ( x * 512 ) ) - 1 ) & 	\
+			              NETARM_SER_RX_GAP_MASK ) )
+#endif
+
+#define MIN_BAUD_RATE        600
+#define MAX_BAUD_RATE     115200
+
+/* the default BAUD rate for the BOOTLOADER, there is a separate */
+/* setting in the serial driver <arch/armnommu/drivers/char/serial-netarm.h> */
+#define DEFAULT_BAUD_RATE 9600
+#ifndef CONFIG_NETARM_SERIAL_CONSOLE_CH2
+#define NETARM_SER_CONSOLE_OFFSET 0x00
+#else
+#define NETARM_SER_CONSOLE_OFFSET 0x40
+#endif
+
+#define NETARM_SER_FIFO_SIZE 32
+#define MIN_GAP 0
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/param.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/processor.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/processor.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/processor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,29 @@
+/*
+ * linux/include/asm-arm/arch-netarm/processor.h
+ *
+ * Copyright (c) 1996 Russell King.
+ *
+ * Changelog:
+ *  10-09-1996	RMK	Created
+ *  29-06-2001  RWP	larger user space for NetARM board
+ */
+
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+#define MCA_bus 0
+#define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+/*
+ * User space: 32 MB
+ */
+#define TASK_SIZE	(0x02000000UL)
+
+#define INIT_MMAP	{ &init_mm, 0, 0x02000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC }
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/serial.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/serial.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/serial.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,118 @@
+/*
+ *  linux/include/asm-armnommu/arch-netarm/serial.h
+ *
+ *  Copyright (C) 1996 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Changelog:
+ *   15-10-1996	RMK	Created
+ *   04-04-1998	PJB	Merged `arc' and `a5k' architectures
+ *   02-28-2001 GJM     Modified for dsc21
+ *   05-31-2001 RWP     Modified for Net+ARM
+ *   06-14-2003 AES     Altered so it didn't use a definition that conflicts
+ *                      with the 16550-oriented serial.c driver.
+ */
+
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/netarm_ser_module.h>
+#include <linux/termios.h>
+
+#undef SERIAL_DEBUG_OPEN	/* info on open/close */
+#undef NAS_DEBUG_VERBOSE	/* even more debug info */
+#define SERIAL_NETARM_INLINE 1
+
+/* setup */
+#define STD_COM_FLAGS  (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+#define NR_NAS_PORTS  2				/* NetARM's got 2 serial ports */
+#define SERIAL_DEV_OFFSET  0
+#define NAS_MAGIC  0x58414c4e			/* NALX (NetArm LinuX) */
+#define BASE_BAUD  (NETARM_XTAL_FREQ / 16)	/* actually not needed, just in case... */
+
+/* we might need a port type (for the serial_state struct),
+   but make sure it's out of reach of the standard serial driver  */
+#define PORT_NETARM	(PORT_MAX + 7)
+
+/* keep in mind that this is the serial driver default setting */
+/* there is also a default baud in <asm/arch/netarm_ser_module.h> */
+/* which is used by the bootloader */
+#define DEFAULT_CFLAGS (B9600 | CS8 | CREAD | HUPCL | CLOCAL)
+#define NETARM_SERIAL_PORT_DFNS \
+	{  \
+	magic: 0, \
+        baud_base: BASE_BAUD, \
+	port: 1, \
+	irq: IRQ_SER1_RX, \
+	flags: STD_COM_FLAGS, \
+	type: PORT_UNKNOWN, \
+	iomem_base: (u8*)NETARM_SER_MODULE_BASE, \
+	iomem_reg_shift: 0, \
+	io_type: SERIAL_IO_MEM \
+	},	/* ttyS0 */ \
+	{  \
+	magic: 0, \
+        baud_base: BASE_BAUD, \
+	port: 2, \
+	irq: IRQ_SER2_RX, \
+	flags: STD_COM_FLAGS, \
+	type: PORT_UNKNOWN, \
+	iomem_base: (u8*)(NETARM_SER_MODULE_BASE+NETARM_SER_CH2_CTRL_A), \
+	iomem_reg_shift: 0, \
+	io_type: SERIAL_IO_MEM \
+	}	/* ttyS1 */ 
+#define EXTRA_SERIAL_PORT_DEFNS
+
+typedef enum { NoMode, TtyMode, CuaMode, SpiMode, HdlcMode } port_mode_t;
+
+struct netarm_async_struct {
+	int			magic;
+	unsigned long		port;
+	port_mode_t		mode;
+	int			flags;
+	int			xmit_fifo_size;
+	struct serial_state	*state;
+	struct tty_struct 	*tty;
+	int			timeout;
+	int			quot;
+	int			x_char;	/* xon/xoff character */
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	unsigned long		SCSRA; 	/* Status Register A (at time of last interrupt) */
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+ 	struct circ_buf		xmit;
+ 	spinlock_t		xmit_lock;
+	netarm_serial_channel_t	*registers; /* address of control registers */
+	int			io_type;
+	int			baud;	/* bitrate */
+	struct tq_struct	tqueue;
+#ifdef DECLARE_WAITQUEUE
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+	wait_queue_head_t	delta_msr_wait;
+#else	
+	struct wait_queue	*open_wait;
+	struct wait_queue	*close_wait;
+	struct wait_queue	*delta_msr_wait;
+#endif	
+};
+
+#define CONFIGURED_NAS_PORT(info) ((info)->port || ((info)->registers))
+
+/* Function prototypes: */
+static void nas_rx_interrupt_1(int irq, void *dev_id, struct pt_regs *regs);
+static void nas_rx_interrupt_2(int irq, void *dev_id, struct pt_regs *regs);
+static void nas_rx_interrupt(struct netarm_async_struct *info, struct pt_regs *regs);
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/system.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,18 @@
+/*
+ * linux/include/asm-armnommu/arch-dsc21/system.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * Copyright (c) 2001 RidgeRun, Inc (http://www.ridgerun.org)
+ *
+ */
+
+static inline void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter);
+}
+
+extern inline void arch_reset(char mode)
+{
+  HARD_RESET_NOW();
+}
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/time.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/time.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,94 @@
+/*
+ * include/asm-armnommu/arch-netarm/time.h
+ *
+ * Copyright (C) 2000 NETsilicon, Inc.
+ * Copyright (C) 2000 WireSpeed Communications Corporation
+ *
+ * This software is copyrighted by WireSpeed. LICENSEE agrees that
+ * it will not delete this copyright notice, trademarks or protective
+ * notices from any copy made by LICENSEE.
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall WireSpeed
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : Joe deBlaquiere
+ * 
+ */
+
+#include	<asm/arch/netarm_registers.h>
+
+/* patched into do_gettimeoffset() - which uses microseconds */
+/* defined in arch/armnommu/mach-netarm/time.c          --rp */
+
+extern unsigned long netarm_gettimeoffset (void);
+extern void netarm_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+extern int setup_arm_irq(int, struct irqaction *);
+
+
+/*
+ * No need to reset the timer at every irq - timer rolls itself
+ */
+extern __inline__ int reset_timer(void)
+{
+#if 0
+	setup_timer();
+#endif	
+	return (1);
+}
+
+/*
+ * Updating of the RTC.  There is none, so do nothing :o)
+ */
+#define update_rtc()
+
+/*
+ * Set up timer interrupt, and the current time in seconds.
+ */
+
+extern void netarm_dump_int_stats(void);
+
+extern __inline__ void setup_timer(void)
+{
+	volatile unsigned int *timer_control = 
+		(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + 
+		NETARM_GEN_TIMER2_CONTROL) ;
+
+#if 1
+	*timer_control = NETARM_GEN_TIMER_SET_HZ( HZ ) | 
+		NETARM_GEN_TCTL_ENABLE | NETARM_GEN_TCTL_INT_ENABLE |
+		NETARM_GEN_TCTL_USE_IRQ | NETARM_GEN_TCTL_INIT_COUNT(0) ;
+#else
+	*timer_control = NETARM_GEN_TIMER_SET_HZ( 4 ) | 
+		NETARM_GEN_TCTL_ENABLE | NETARM_GEN_TCTL_INT_ENABLE |
+		NETARM_GEN_TCTL_USE_IRQ | NETARM_GEN_TCTL_INIT_COUNT(0) ;
+#endif
+
+	printk("setup_timer : T2 CTL = %08lX\n", ((unsigned long)*timer_control));
+
+	/* store in kernel's function pointer --rp */
+	gettimeoffset = netarm_gettimeoffset;	
+	/* set up the timer interrupt */
+	timer_irq.handler = netarm_timer_interrupt;
+
+/*	netarm_dump_int_stats();*/
+	printk("setting up timer IRQ\n");
+	setup_arm_irq(IRQ_TIMER2, &timer_irq);
+/*	netarm_dump_int_stats();*/
+}
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,48 @@
+/*
+ * timex.h:
+ *         System clock frequency.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+/*
+ * CLOCK_TICK_RATE -- frequency fed to the timer. Used to
+ * compute LATCH. LATCH is the number of clock ticks per timer interrupt.
+ * (See linux/timex.h, armnommu/mach-dsc21/time.c).
+ * defines taken from the 2.0.38 port, include/linux/timex.h --rp
+ */
+
+#ifndef __arm__
+#define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
+#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
+#else
+#define CLOCK_TICK_RATE		2000000
+#define CLOCK_TICK_FACTOR	1000000
+#endif
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-netarm/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-netarm/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-netarm/vmalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ *  linux/include/asm-arm/arch-dsc21/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Actually this file shouldn't be included at all
+ * but I need a dummy until the Makefiles are fixed (rp)
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ *
+ define VMALLOC_OFFSET	  (8*1024*1024)
+ define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+ define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+ */
+ 
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/a.out.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/a.out.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/a.out.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * uclinux/include/asm-armnommu/arch-atmel/a.out.h
+ *
+ */
+#ifndef __ASM_ARCH_A_OUT_H
+#define __ASM_ARCH_A_OUT_H
+
+#ifdef __KERNEL__
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,14 @@
+/*
+ * asm/arch-armnommu/arch-p52/dma.h:
+ * Mindspeed 2001
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+
+#define MAX_DMA_ADDRESS		0x01000000
+#define MAX_DMA_CHANNELS        13
+#define arch_dma_init(dma_chan)
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,84 @@
+/*
+ * linux/include/asm-arm/arch-p52/hardware.h
+ * to complete.... 
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+
+#define HARD_RESET_NOW()
+
+/*
+ * GPIO
+ */
+
+#define P52GPIO_ISM1  0x3500a0
+#define P52GPIO_ISM2  0x3500a4
+#define P52GPIO_ISM3  0x3500a8
+
+#define P52GPIO_OE1   0x3500b4
+#define P52GPIO_OE2   0x3500b8
+#define P52GPIO_OE3   0x3500bc
+
+#define P52GPIO_DIN1  0x3500c0
+#define P52GPIO_DIN2  0x3500c4
+#define P52GPIO_DIN3  0x3500c8
+
+#define P52GPIO_DOUT1 0x3500cc
+#define P52GPIO_DOUT2 0x3500d0
+#define P52GPIO_DOUT3 0x3500d4
+
+#define P52GPIO_ISR1  0x3500d8
+#define P52GPIO_ISR2  0x3500dc
+#define P52GPIO_ISR3  0x3500e0
+
+#define P52GPIO_IER1  0x3500e4
+#define P52GPIO_IER2  0x3500e8
+#define P52GPIO_IER3  0x3500ec
+
+#define P52GPIO_IPC1  0x3500f0
+#define P52GPIO_IPC2  0x3500f4
+#define P52GPIO_IPC3  0x3500f8
+
+/* 
+ * interrupts 
+ */
+
+#define INTBase_Addr  0x350040
+
+#define LA            0x00
+#define Stat          0x04
+#define SetStat       0x08
+#define Msk           0x0c
+#define MStat         0x50
+
+#define	P52INT_MASK     (INTBase_Addr+Msk) 
+#define	P52INT_STATUS   (INTBase_Addr+Stat)
+#define P52INT_STATUS_M (INTBase_Addr+MStat)
+
+/*
+ * timers
+ */
+
+#define P52TIMBase_Addr     0x350020
+
+#define TM_Cnt1          0x00
+#define TM_Cnt2          0x04
+#define TM_Cnt3          0x08
+#define TM_Cnt4          0x0C
+
+#define TM_Lmt1          0x10
+#define TM_Lmt2          0x14
+#define TM_Lmt3          0x18
+#define TM_Lmt4          0x1C
+
+#define TIM_SET_RATE(tmr, value) *((volatile unsigned long *)(P52TIMBase_Addr+tmr)) = value
+
+
+#define ASB_RAM_ADRS      0x00180000
+#define P52_CLK_SPEED     1000000         /* Timer speed is 1 microsecond*/
+
+#endif  /* _ASM_ARCH_HARDWARE_H */
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/ide.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/ide.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/ide.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,45 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/ide.h
+ *
+ * Copyright (c) 1998 Hugo Fiennes & Nicolas Pitre
+ *
+ * 18-aug-2000: Cleanup by Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
+ *              Get rid of the special ide_init_hwif_ports() functions
+ *              and make a generalised function that can be used by all
+ *              architectures.
+ */
+
+#include <linux/config.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+
+/*
+ * Set up a hw structure for a specified data port, control port and IRQ.
+ * This should follow whatever the default interface uses.
+ */
+static __inline__ void
+ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int *irq)
+{
+#ifdef CONFIG_REVISIT
+#error Not sure what to do for ide_init_hwif_ports
+#endif
+}
+
+
+
+
+/*
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ */
+static __inline__ void
+ide_init_default_hwifs(void)
+{
+#ifdef CONFIG_REVISIT
+#error Not sure what to do for ide_init_default_hwifs
+#endif
+}
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/io.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ * linux/include/asm-armnommu/arch-dsc21/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ *  02-19-2001  gjm     Leveraged for armnommu/dsc21
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ * --gmcnutt
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * If we define __io then asm/io.h will take care of most of the inb & friends
+ * macros. It still leaves us some 16bit macros to deal with ourselves, though.
+ * We don't have PCI or ISA on the dsc21 so I dropped __mem_pci & __mem_isa.
+ * --gmcnutt
+ */
+#define PCIO_BASE 0
+#define __io(a) (PCIO_BASE + (a))
+#define __arch_getw(a) (*(volatile unsigned short *)(a))
+#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
+
+/*
+ * Defining these two gives us ioremap for free. See asm/io.h.
+ * --gmcnutt
+ */
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,40 @@
+/*
+ * asm/arch-p52/irq.h:
+ * 2001 Mindspeed
+ */
+
+#ifndef __ASM_ARCH_IRQ_H__
+#define __ASM_ARCH_IRQ_H__
+
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irqs.h>
+
+
+#define fixup_irq(x) (x)
+
+extern void p52_mask_irq(unsigned int irq);
+extern void p52_unmask_irq(unsigned int irq);
+extern void p52_mask_ack_irq(unsigned int irq);
+
+extern struct irqdesc irq_desc[];
+
+static __inline__ void irq_init_irq(void)
+{
+	int irq;
+
+	/* disable all int sources */
+	(*(unsigned long*)P52INT_MASK)=0x00000000;
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= p52_mask_ack_irq;
+		irq_desc[irq].mask	= p52_mask_irq;
+		irq_desc[irq].unmask	= p52_unmask_irq;
+	}
+}
+
+#endif /* __ASM_ARCH_IRQ_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/irqs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ * asm/arch-p52/irqs.h:
+ * 2001 Mindspeed
+ */
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+
+#define P52INT_LVL_TIMER_1            0       /* Timer 0 interrupt */
+#define P52INT_LVL_TIMER_2            1       /* Timer 1 interrupt */
+#define P52INT_LVL_TIMER_3            2       /* Timer 2 interrupt */
+#define P52INT_LVL_TIMER_4            3       /* Timer 3 interrupt */
+#define P52INT_LVL_USB                4       /* USB interrupt */
+#define P52INT_LVL_RSVD1              5       /* Reserved */
+#define P52INT_LVL_HOST               6       /* External Host interrupt */
+#define P52INT_LVL_HOST_ERR           7       /* Host Bus error detect */
+#define P52INT_LVL_DMA8               8       /* M2M */
+#define P52INT_LVL_RSVD2              9       /* Reserved */
+#define P52INT_LVL_DMA6              10       /* DSL Rx */
+#define P52INT_LVL_DMA5              11       /* DSL Tx */
+#define P52INT_LVL_DMA4              12       /* Ethernet 2 Receive */
+#define P52INT_LVL_DMA3              13       /* Ethernet 2 Transmit */
+#define P52INT_LVL_DMA2              14       /* Ethernet 1 Receive */
+#define P52INT_LVL_DMA1              15       /* Ethernet 1 Transmit */
+#define P52INT_LVL_RSVD3             16       /* Reserved */
+#define P52INT_LVL_RSVD4             17       /* Reserved */
+#define P52INT_LVL_DMA_ERR           18       /* DMA Errort */
+#define P52INT_LVL_E2_ERR            19       /* EMAC 2 error */
+#define P52INT_LVL_E1_ERR            20       /* EMAC 1 error */
+#define P52INT_LVL_DSL               21       /* DSL intr*/
+#define P52INT_LVL_RSVD5             22       /* Reserved */
+#define P52INT_LVL_RSVD6             23       /* Reserved */
+#define P52INT_LVL_GPIO              24       /* GPIO interrupts */
+#define P52INT_LVL_RSVD7             25       /* Reserved */
+#define P52INT_LVL_COMMTX            26       /* ARM9 Comms Xmit */
+#define P52INT_LVL_COMMRX            27       /* ARM9 Comms Rcv */
+#define P52INT_LVL_SW1               28       /* Software interrupt 1 */
+#define P52INT_LVL_SW2               29       /* Software interrupt 2 */
+#define P52INT_LVL_SW3               30       /* Software interrupt 3 */
+#define P52INT_LVL_SW4               31       /* Software interrupt 4 */
+
+#define P52INT_MASK_TIMER_1        1
+#define P52INT_MASK_TIMER_2        (1 << 1)
+#define P52INT_MASK_TIMER_3        (1 << 2)
+#define P52INT_MASK_TIMER_4        (1 << 3)
+#define P52INT_MASK_USB            (1 << 4)
+#define P52INT_MASK_RSVD1          (1 << 5)
+#define P52INT_MASK_HOST           (1 << 6)
+#define P52INT_MASK_HOST_ERR       (1 << 7)
+#define P52INT_MASK_DMA8           (1 << 8)
+#define P52INT_MASK_RSVD2          (1 << 9)
+#define P52INT_MASK_DMA6           (1 << 10)
+#define P52INT_MASK_DMA5           (1 << 11)
+#define P52INT_MASK_DMA4           (1 << 12)
+#define P52INT_MASK_DMA3           (1 << 13)
+#define P52INT_MASK_DMA2           (1 << 14)
+#define P52INT_MASK_DMA1           (1 << 15)
+#define P52INT_MASK_RSVD3          (1 << 16)
+#define P52INT_MASK_RSVD4          (1 << 17)
+#define P52INT_MASK_DMA_ERR        (1 << 18)
+#define P52INT_MASK_E2_ERR         (1 << 19)
+#define P52INT_MASK_E1_ERR         (1 << 20)
+#define P52INT_MASK_DSL            (1 << 21)
+#define P52INT_MASK_RSVD5          (1 << 22)
+#define P52INT_MASK_RSVD6          (1 << 23)
+#define P52INT_MASK_GPIO           (1 << 24)
+#define P52INT_MASK_RSVD7          (1 << 25)
+#define P52INT_MASK_COMMTX         (1 << 26)
+#define P52INT_MASK_COMMRX         (1 << 27)
+#define P52INT_MASK_SW1            (1 << 28)
+#define P52INT_MASK_SW2            (1 << 29)
+#define P52INT_MASK_SW3            (1 << 30)
+#define P52INT_MASK_SW4            (1 << 31)
+
+#define NR_IRQS           32
+
+/* alias */
+#define IRQ_TIMER         P52INT_LVL_TIMER_1
+
+/* flags for request_irq() */
+#define IRQ_FLG_LOCK      (0x0001)  /* handler is not replaceable   */
+#define IRQ_FLG_REPLACE   (0x0002)  /* replace existing handler     */
+#define IRQ_FLG_FAST      (0x0004)
+#define IRQ_FLG_SLOW      (0x0008)
+#define IRQ_FLG_STD       (0x8000)  /* internally used              */
+
+#endif /* __ASM_ARCH_IRQS_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/keyboard.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/keyboard.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/keyboard.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ *  linux/include/asm-arm/arch-ti926/keyboard.h
+ *
+ *  Copyright (C) 2000 RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Keyboard driver definitions for ARM
+ */
+#ifndef __ASM_ARM_ARCH_TI925_KEYBOARD_H
+#define __ASM_ARM_ARCH_TI925_KEYBOARD_H
+
+#if 0
+#define kbd_request_region
+#define kbd_write_command
+#define kbd_write_output
+#define kbd_read_status
+#define kbd_read_input
+#define aux_request_irq
+#define aux_free_irq
+#endif
+
+/*
+ * Required by drivers/char/keyboard.c. I took these from arch-arc.
+ * --gmcnutt
+ */
+#define kbd_setkeycode(sc,kc) (-EINVAL)
+#define kbd_getkeycode(sc) (-EINVAL)
+#define kbd_translate(sc,kcp,rm) ({ *(kcp) = (sc); 1; })
+#define kbd_unexpected_up(kc) (0200)
+#define kbd_leds(leds)
+#define kbd_init_hw()
+#define kbd_enable_irq() /* what irq? ;) --gmcnutt */
+#define kbd_disable_irq()
+
+
+#endif /* __ASM_ARM_ARCH_TI925_KEYBOARD_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,29 @@
+/*
+ * linux/include/asm-armnommu/arch-p52/memory.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * 2001 Mindspeed
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <asm/page.h>
+
+#define TASK_SIZE	(0x01a00000UL)
+#define TASK_SIZE_26	TASK_SIZE
+
+
+extern unsigned long _end_kernel;
+#define PHYS_OFFSET	((unsigned long) &_end_kernel)
+
+#define PAGE_OFFSET DRAM_BASE
+#define END_MEM     DRAM_BASE + DRAM_SIZE
+
+
+#define __virt_to_phys(vpage) ((unsigned long) (vpage))
+#define __phys_to_virt(ppage) ((void *) (ppage))
+#define __virt_to_bus(vpage) ((unsigned long) (vpage))
+#define __bus_to_virt(ppage) ((void *) (ppage))
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/param.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/pcmcia.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/pcmcia.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/pcmcia.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/pcmcia.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,3 @@
+#ifdef CONFIG_REVISIT
+#error Do we need PCMCIA support?
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/processor.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/processor.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/processor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,15 @@
+/*
+ * uclinux/include/asm-armnommu/arch-atmel/mmu.h
+ *
+ */
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+#define EISA_bus 0
+#define EISA_bus__is_a_macro
+#define MCA_bus 0
+#define MCA_bus__is_a_macro
+
+#define TASK_SIZE (0x01a00000UL)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/serial.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/serial.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/serial.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,9 @@
+/*
+ *  linux/include/asm-arm/arch-p52/serial.h
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+/* need to move p52serial.h here */
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/shmparam.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/shmparam.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/shmparam.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-a5k/shmparam.h
+ *
+ * Copyright (c) 1996 Russell King.
+ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/system.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-armnommu/arch-p52/system.h
+ * 2001 Mindspeed
+ */
+
+static inline void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter)
+	  cpu_do_idle(IDLE_WAIT_SLOW);
+}
+
+extern inline void arch_reset(char mode)
+{
+  /* tbd */
+}
+
+ 
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/time.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/time.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ * linux/include/asm-arm/arch-p52/time.h
+ * 2001 Mindspeed
+ */
+
+#ifndef __ASM_ARCH_TIME_H__
+#define __ASM_ARCH_TIME_H__
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/timex.h>
+
+extern struct irqaction timer_irq;
+
+extern unsigned long p52_gettimeoffset(void);
+extern void p52_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+
+void __inline__ setup_timer (void)
+{
+
+	/* disable timer interrupt (should already been disabled) */
+	(*(volatile unsigned long*)P52INT_MASK) &=~(1 << P52INT_LVL_TIMER_1);
+
+	/* Timeout 10ms */
+	TIM_SET_RATE(TM_Lmt1,CLOCK_TICK_RATE);	
+
+	//gettimeoffset = p52_gettimeoffset;	
+	timer_irq.handler = p52_timer_interrupt;
+	setup_arm_irq(IRQ_TIMER, &timer_irq);
+
+}
+
+#endif /* __ASM_ARCH_TIME_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+ * timex.h:
+ * 2001 Mindspeed
+ */
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+#define CLOCK_TICK_RATE	   0x270f
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/uncompress.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/uncompress.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/uncompress.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ * asm/arch/uncompress.c:
+ *         Optional routines to aid in debugging the decompression phase
+ *         of kernel boot.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * This is used by arch/armnommu/boot/compressed/misc.c to write progress info
+ * out the serial port so that the user can see debug messages up to the point
+ * where the kernel is decompressed. The STANDALONE_DEBUG macro chooses between
+ * this and the standard printf. Punt.
+ * --gmcnutt
+ */
+#define puts(s)
+
+/*
+ * Not sure what this is for. Probably an optional watchdog to check if the
+ * decompress got hung so we can warn the user. Punt.
+ */
+#define arch_decomp_wdog()
+
+/*
+ * If we need to do some setup prior to decompression (like initializing the
+ * UART if we want to use puts() above) then we define it here. Punt.
+ */
+#define arch_decomp_setup()
diff -urN linux-2.4.29/include/asm-armnommu/arch-p52/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-p52/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-p52/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-p52/vmalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ *  linux/include/asm-arm/arch-dsc21/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/des.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/des.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/des.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/des.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,60 @@
+/*
+ * des.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc. 
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file includes the DES/3DES engine definitions 
+ * of the S3C2500 RISC microcontroller
+ * based on the Samsung's "S3C2500 32-bit RISC
+ * microcontroller pre. User's Manual"
+ */
+
+#ifndef __ASM_ARCH_DES_H
+#define __ASM_ARCH_DES_H
+
+#define DES_BASE	0xf0090000
+
+#define DESCON		0xf0090000	/* DES/3DES control (R/W)	      */
+#define DESSTA		0xf0090004	/* DES/3DES status (R)		      */
+#define DESINT		0xf0090008	/* DES/3DES interrupt enable (R/W)    */
+#define DESRUN		0xf009000c	/* DES/3DES run enable (W)	      */
+#define DESKEY1L	0xf0090010	/* DES/3DES Key 1 left half (R/W)     */
+#define DESKEY1R	0xf0090014	/* DES/3DES Key 1 right half (R/W)    */
+#define DESKEY2L	0xf0090018	/* DES/3DES Key 2 left half (R/W)     */
+#define DESKEY2R	0xf009001c	/* DES/3DES Key 2 right half (R/W)    */
+#define DESKEY3L	0xf0090020	/* DES/3DES Key 3 left half (R/W)     */
+#define DESKEY3R	0xf0090024	/* DES/3DES Key 3 right half (R/W)    */
+#define DESIVL		0xf0090028	/* DES/3DES IV left half (R/W)	      */
+#define DESIVR		0xf009002c	/* DES/3DES IV right half (R/W)	      */
+#define DESINFIFO	0xf0090030	/* DES/3DES input FIFO (W)	      */
+#define DESOUTFIFO	0xf0090034	/* DES/3DES output FIFO (R)	      */
+
+/*---------------------------------------< DES/3DES control (R/W) >-----------*/
+#define	DES_RUN		0x00000001
+#define	DES_INDMA	0x00000002
+#define	DES_OUTDMA	0x00000004
+#define	DES_R2LDATA	0x00000008
+#define	DES_DECRYPT	0x00000010
+#define	DES_3DES	0x00000020
+#define	DES_CBC		0x00000040
+#define	DES_2W		0x00000080
+#define	DES_TEST	0x00000100
+#define	DES_RESET	0x00000200
+
+/*---------------------------------------< DES/3DES status (R) >--------------*/
+#define	DES_IDLE	0x00000001
+#define	DES_INAVAILABLE	0x00000010
+#define	DES_INEMPTY	0x00000020
+#define	DES_INFULL	0x00000040
+#define	DES_OUTVALID	0x00000100
+#define	DES_OUTEMPTY	0x00000200
+#define	DES_OUTFULL	0x00000400
+
+/*---------------------------------------< DES/3DES interrupt enable (R/W) >--*/
+#define	DES_IDLE_IE		0x00000001
+#define	DES_INAVAILABLE_IE	0x00000010
+#define	DES_OUTVALID_IE		0x00000100
+
+
+#endif /* _ASM_ARCH_DES_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,85 @@
+/*
+ * dma.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file includes the DMA controller definitions 
+ * of the S3C2500X RISC microcontroller
+ * based on the Samsung's "S3C2500X 32-bit RISC
+ * microcontroller pre. User's Manual"
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_ADDRESS		0x01000000 /* End of the SDRAM */
+#define MAX_DMA_CHANNELS        6
+
+#define GDMA_BASE	0xf0050000
+
+#define DPRIC		0xf0051000	/* GDMA priority configuration R */
+#define DPRIF		0xf0052000	/* GDMA programmable priority R for fixed */
+#define DPRIR		0xf0053000	/* GDMA programmable priority R for round-robin */
+
+#define DCON0		0xf0050000	/* GDMA channel 0 control R		*/
+#define DSAR0		0xf0050004	/* GDMA channel 0 source address R	*/
+#define DDAR0		0xf0050008	/* GDMA channel 0 destination address R */
+#define DTCR0		0xf005000c	/* GDMA channel 0 transfer count R	*/
+#define DRER0		0xf0050010	/* GDMA channel 0 run enable R		*/
+#define DIPR0		0xf0050014	/* GDMA channel 0 interrupt pending R	*/
+
+#define DCON1		0xf0050020	/* GDMA channel 1 control R		*/
+#define DSAR1		0xf0050024	/* GDMA channel 1 source address R	*/
+#define DDAR1		0xf0050028	/* GDMA channel 1 destination address R */
+#define DTCR1		0xf005002c	/* GDMA channel 1 transfer count R	*/
+#define DRER1		0xf0050030	/* GDMA channel 1 run enable R		*/
+#define DIPR1		0xf0050034	/* GDMA channel 1 interrupt pending R	*/
+
+#define DCON2		0xf0050040	/* GDMA channel 2 control R		*/
+#define DSAR2		0xf0050044	/* GDMA channel 2 source address R	*/
+#define DDAR2		0xf0050048	/* GDMA channel 2 destination address R */
+#define DTCR2		0xf005004c	/* GDMA channel 2 transfer count R	*/
+#define DRER2		0xf0050050	/* GDMA channel 2 run enable R		*/
+#define DIPR2		0xf0050054	/* GDMA channel 2 interrupt pending R	*/
+
+#define DCON3		0xf0050060	/* GDMA channel 3 control R		*/
+#define DSAR3		0xf0050064	/* GDMA channel 3 source address R	*/
+#define DDAR3		0xf0050068	/* GDMA channel 3 destination address R */
+#define DTCR3		0xf005006c	/* GDMA channel 3 transfer count R	*/
+#define DRER3		0xf0050070	/* GDMA channel 3 run enable R		*/
+#define DIPR3		0xf0050074	/* GDMA channel 3 interrupt pending R	*/
+
+#define DCON4		0xf0050080	/* GDMA channel 4 control R		*/
+#define DSAR4		0xf0050084	/* GDMA channel 4 source address R	*/
+#define DDAR4		0xf0050088	/* GDMA channel 4 destination address R */
+#define DTCR4		0xf005008c	/* GDMA channel 4 transfer count R	*/
+#define DRER4		0xf0050090	/* GDMA channel 4 run enable R		*/
+#define DIPR4		0xf0050094	/* GDMA channel 4 interrupt pending R	*/
+
+#define DCON5		0xf00500a0	/* GDMA channel 5 control R		*/
+#define DSAR5		0xf00500a4	/* GDMA channel 5 source address R	*/
+#define DDAR5		0xf00500a8	/* GDMA channel 5 destination address R */
+#define DTCR5		0xf00500ac	/* GDMA channel 5 transfer count R	*/
+#define DRER5		0xf00500b0	/* GDMA channel 5 run enable R		*/
+#define DIPR5		0xf00500b4	/* GDMA channel 5 interrupt pending R	*/
+
+#define	DMA_RE		0x00000001
+#define	DMA_EXTDREQ	0x00000002
+#define	DMA_HUARTTX	0x00000004
+#define	DMA_HUARTRX	0x00000006
+#define	DMA_DESIN	0x00000008
+#define	DMA_DESOUT	0x0000000a
+#define	DMA_SB		0x00000010
+#define	DMA_FB		0x00000020
+#define	DMA_TS4		0x00000080
+#define	DMA_TS2		0x00000040
+#define	DMA_SD		0x00000100
+#define	DMA_SF		0x00000200
+#define	DMA_DD		0x00000400
+#define	DMA_DF		0x00000800
+#define	DMA_IE		0x00001000
+#define	DMA_XCNT(x)	((x-1)<<13)
+#define	DMA_BS		0x80000000
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,139 @@
+/*
+ * hardware.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file includes the hardware definitions 
+ * of the S3C2500X RISC microcontroller
+ * based on the Samsung's "S3C2500X 32-bit RISC
+ * microcontroller pre. User's Manual"
+ */
+ 
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <linux/config.h>
+
+#ifndef __ASSEMBLER__
+extern	unsigned int CONFIG_ARM_CLK;
+#endif
+
+#define PCLK		CONFIG_ARM_CLK
+
+#define MCLK2		(PCLK >> 1)
+
+#define Vol32	*(volatile unsigned int *)
+#define Vol16	*(volatile unsigned short *)
+#define Vol08	*(volatile unsigned char *)
+
+#define REG_WRITE(addr,data)	(Vol32(addr)=(data))
+#define REG_READ(addr)		(Vol32(addr))
+
+#define HARD_RESET_NOW()
+
+/*
+---	Memory map
+*/
+#define BASE_MEM_BANK0	0x00000000	/* EXT I/O Bank 0 base address */
+#define BASE_MEM_BANK1	0x01000000	/* EXT I/O Bank 1 base address */
+#define BASE_MEM_BANK2	0x02000000	/* EXT I/O Bank 2 base address */
+#define BASE_MEM_BANK3	0x03000000	/* EXT I/O Bank 3 base address */
+#define BASE_MEM_BANK4	0x04000000	/* EXT I/O Bank 4 base address */
+#define BASE_MEM_BANK5	0x05000000	/* EXT I/O Bank 5 base address */
+#define BASE_MEM_BANK6	0x06000000	/* EXT I/O Bank 6 base address */
+#define BASE_MEM_BANK7	0x07000000	/* EXT I/O Bank 7 base address */
+#define BASE_SDRAM_BANK0 0x40000000	/* SDRAM   Bank 0 base address */
+#define BASE_SDRAM_BANK1 0x80000000	/* SDRAM   Bank 1 base address */
+
+#define MAP_MEM_BANK0	0x80000000	/* EXT I/O Bank 0 remaped address */
+#define MAP_MEM_BANK1	0x81000000	/* EXT I/O Bank 1 remaped address */
+#define MAP_MEM_BANK2	0x82000000	/* EXT I/O Bank 2 remaped address */
+#define MAP_MEM_BANK3	0x83000000	/* EXT I/O Bank 3 remaped address */
+#define MAP_MEM_BANK4	0x84000000	/* EXT I/O Bank 4 remaped address */
+#define MAP_MEM_BANK5	0x85000000	/* EXT I/O Bank 5 remaped address */
+#define MAP_MEM_BANK6	0x86000000	/* EXT I/O Bank 6 remaped address */
+#define MAP_MEM_BANK7	0x87000000	/* EXT I/O Bank 7 remaped address */
+#define MAP_SDRAM_BANK0	0x00000000	/* SDRAM   Bank 0 remaped address */
+#define MAP_SDRAM_BANK1	0x04000000	/* SDRAM   Bank 1 remaped address */
+
+#define	BASE_REG	0xF0000000	/* Internal register base address */
+
+
+/*	
+---	System configuration special registers
+*/
+#define	SYSCFG		0xF0000000	/* System configuration R */
+#define	PDCODE		0xF0000004	/* Product code and revision number R */
+#define CLKCON		0xF0000008	/* System clock control R */
+#define PCLKDIS		0xF000000C	/* Pirepheral clock disable R */
+#define CLKST		0xF0000010	/* Clock status R */
+#define HPRIF		0xF0000014	/* AHB bus master fixed priority R */
+#define HPRIR		0xF0000018	/* AHB bus master round-robin priority R */
+#define CPLL		0xF000001C	/* Core PLL configuration R */
+#define SPLL		0xF0000020	/* System PLL configuration R */
+#define UPLL		0xF0000024	/* USB PLL configuration R */
+#define PPLL		0xF0000028	/* PHY PLL configuration R */
+
+/*
+---	External I/O bank controller
+*/
+#define	B0CON		0xF0010000	/* Bank 0 control R */
+#define	B1CON		0xF0010004	/* Bank 1 control R */
+#define	B2CON		0xF0010008	/* Bank 2 control R */
+#define	B3CON		0xF001000C	/* Bank 3 control R */
+#define	B4CON		0xF0010010	/* Bank 4 control R */
+#define	B5CON		0xF0010014	/* Bank 5 control R */
+#define	B6CON		0xF0010018	/* Bank 6 control R */
+#define	B7CON		0xF001001C	/* Bank 7 control R */
+#define	MUXBCON		0xF0010020	/* Muxed bus control R */
+#define	WAITCON		0xF0010024	/* Wait control R */
+
+/*
+---	SDRAM controller
+*/
+#define	RegO		0xF0020000	/* Configuration R 0 */
+#define	Reg1		0xF0020004	/* Configuration R 1 */
+#define	Reg3		0xF0020008	/* Refresh timer R */
+#define	Reg4		0xF002000C	/* Write buffer time-out R*/
+
+/*
+---	HDLC controller
+*/
+#define HMODE_A		0xF0100000	/* HDLC Channel A mode */
+#define HMODE_B		0xF0110000	/* HDLC Channel B mode */
+#define HMODE_C		0xF0120000	/* HDLC Channel C mode */
+
+/*
+---	Interrupt controller
+*/
+#include <asm/arch/irqs.h>
+
+/*
+---	Timers
+*/
+#define	ARM_CLK	CONFIG_ARM_CLK
+#include <asm/arch/timers.h>
+
+/*
+---	I/O ports
+*/
+#include <asm/arch/ios.h>
+
+/*
+---	UART controller
+*/
+#include <asm/arch/uart.h>
+
+/*
+---	DMA controller
+*/
+#include <asm/arch/dma.h>
+
+/*
+---	I2C BUS controller
+*/
+#include <asm/arch/i2c.h>
+
+	
+#endif	/* __ASM_ARCH_HARDWARE_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/i2c.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/i2c.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/i2c.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/i2c.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ * iic.h
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file includes the I2C bus controller definitions
+ * of the S3C2500X RISC microcontroller
+ * based on the Samsung's "S3C2500X 32-bit RISC
+ * microcontroller pre. User's Manual"
+ */
+ 
+#ifndef __ASM_ARCH_IIC_H
+#define __ASM_ARCH_IIC_H
+
+#define IICCON		0xF00F0000	/* Control status R	*/
+#define IICCON_BF	0x01		/* Buffer flag		*/
+#define IICCON_IEN	0x02		/* Interrupt enable	*/
+#define IICCON_LRB	0x04		/* Last received bit 	*/
+#define IICCON_ACK	0x08		/* Acknowlege enable	*/
+#define IICCON_START	0x10		/* Start condition	*/
+#define IICCON_STOP	0x20		/* Stop condition	*/
+#define IICCON_RESTART	0x30		/* Repeat Start(Restart)*/
+#define IICCON_BUSY	0x40		/* Bus busy		*/
+#define IICCON_RESET	0x80		/* Reset		*/
+
+#define IICBUF		0xF00F0004	/* Shift buffer R	*/
+#define IICBUF_WRITE	0x00		/* Slave Addr Write bit	*/
+#define IICBUF_READ	0x01		/* Slave Addr Read bit	*/
+
+#define IICPS		0xF00F0008	/* Prescaler R		*/
+#define IICCNT		0xF00F000C	/* Prescaler counter R
	*/
+#define IICPND		0xF00F0010	/* Interrupt pending R
	*/
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/io.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ * linux/include/asm-armnommu/arch-dsc21/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ *  02-19-2001  gjm     Leveraged for armnommu/dsc21
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ * --gmcnutt
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * If we define __io then asm/io.h will take care of most of the inb & friends
+ * macros. It still leaves us some 16bit macros to deal with ourselves, though.
+ * We don't have PCI or ISA on the dsc21 so I dropped __mem_pci & __mem_isa.
+ * --gmcnutt
+ */
+#define PCIO_BASE 0
+#define __io(a) (PCIO_BASE + (a))
+#define __arch_getw(a) (*(volatile unsigned short *)(a))
+#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
+
+/*
+ * Defining these two gives us ioremap for free. See asm/io.h.
+ * --gmcnutt
+ */
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/ios.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/ios.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/ios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/ios.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ * ios.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file includes the I/O ports definitions 
+ * of the S3C2500X RISC microcontroller
+ * based on the Samsung's "S3C2500X 32-bit RISC
+ * microcontroller pre. User's Manual"
+ */
+
+#ifndef __ASM_ARCH_IOS_H
+#define __ASM_ARCH_IOS_H
+
+#define MAX_IOS_PORTS	64
+
+#define IO_BASE		0xf0030000
+
+#define	IOPMOD1		0xF0030000	/* I/O port mode select lower R		*/
+#define	IOPMOD2		0xF0030004	/* I/O port mode select upper R		*/
+#define	IO_Ftn_cont1	0xF0030008	/* I/O port select lower R		*/
+#define	IO_Ftn_cont2	0xF003000C	/* I/O port select upper R		*/
+#define	IOP4DMA		0xF0030010	/* I/O port special function R for DMA	*/
+#define	IOP4xINT	0xF0030014	/* I/O port spec. function R for Ext.IRQ*/
+#define	IOP4xINT_PEND	0xF0030018	/* External IRQ clear R			*/
+#define	IOPDATA1	0xF003001c	/* I/O port data R			*/
+#define	IOPDATA2	0xF0030020	/* I/O port data R			*/
+#define	IOPDRV1		0xF0030024	/* I/O port drive control R		*/
+#define	IOPDRV2		0xF0030028	/* I/O port drive control R		*/
+
+#endif /* _ASM_ARCH_IOS_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,93 @@
+/*
+ * irq.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ */
+#ifndef __ASM_ARCH_IRQ_H
+#define __ASM_ARCH_IRQ_H
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irqs.h>
+
+#define fixup_irq(x) (x)
+
+extern void s3c2500_mask_irq(unsigned int irq);
+extern void s3c2500_unmask_irq(unsigned int irq);
+extern void s3c2500_mask_ack_irq(unsigned int irq);
+extern void s3c2500_mask_global(void);
+extern void s3c2500_unmask_global(void);
+
+static __inline__ void irq_init_irq(void)
+{
+/******************************************
+ * Interrupt priority table
+ ******************************************/
+static unsigned char s3c2500_irq_prtable[NR_IRQS] =
+	{
+	SRC_IRQ_0,
+	SRC_IRQ_1,
+	SRC_IRQ_2,
+ 	SRC_IRQ_3,
+ 	SRC_IRQ_4,
+ 	SRC_IRQ_5,
+ 	SRC_IRQ_IOM2,
+ 	SRC_IRQ_IICC,
+ 	SRC_IRQ_HUART0_TX,
+ 	SRC_IRQ_HUART0_RX,
+ 	SRC_IRQ_HUART1_TX,
+ 	SRC_IRQ_HUART1_RX,
+ 	SRC_IRQ_CUART_TX,
+ 	SRC_IRQ_CUART_RX,
+ 	SRC_IRQ_USB,
+ 	SRC_IRQ_HDLC_TX0,
+ 	SRC_IRQ_HDLC_RX0,
+ 	SRC_IRQ_HDLC_TX1,
+ 	SRC_IRQ_HDLC_RX1,
+ 	SRC_IRQ_HDLC_TX2,
+ 	SRC_IRQ_HDLC_RX2,
+ 	SRC_IRQ_ETH_TX0,
+ 	SRC_IRQ_ETH_RX0,
+ 	SRC_IRQ_ETH_TX1,
+ 	SRC_IRQ_ETH_RX1,
+ 	SRC_IRQ_DES,
+ 	SRC_IRQ_GDMA0,
+ 	SRC_IRQ_GDMA1,
+ 	SRC_IRQ_GDMA2,
+ 	SRC_IRQ_GDMA3,
+ 	SRC_IRQ_GDMA4,
+ 	SRC_IRQ_GDMA5,
+ 	SRC_IRQ_TIMER0,
+ 	SRC_IRQ_TIMER1,
+ 	SRC_IRQ_TIMER2,
+ 	SRC_IRQ_TIMER3,
+ 	SRC_IRQ_TIMER4,
+ 	SRC_IRQ_TIMER5,
+ 	SRC_IRQ_TIMER_WD
+	};
+    volatile unsigned int *PtIntPr = (volatile unsigned int *)INTPRIOR0;
+    unsigned int irq;
+    unsigned int *tmp = (unsigned int *)s3c2500_irq_prtable;
+    
+    for (irq = 0; irq < NR_IRQS; irq++) {
+	irq_desc[irq].valid	= 1;
+	irq_desc[irq].probe_ok	= 1;
+	irq_desc[irq].mask_ack	= s3c2500_mask_ack_irq;
+	irq_desc[irq].mask	= s3c2500_mask_irq;
+	irq_desc[irq].unmask	= s3c2500_unmask_irq;
+	}
+    for (irq = 0; irq < NR_IRQS; irq+=4) {
+	*PtIntPr++ = *tmp++;
+	}
+    
+    outl ( 0,          INTMOD );	/* Set internal interrupts
 in IRQ mode	*/
+    outl ( 0,          EXTMOD );	/* Set external interrupts
 in IRQ mode	*/
+    s3c2500_mask_global();		/* Disable all interrupt requests	*/
+    outl ( 0xFFFFFFFF, INTMASK );
	/* Mask all internal Intrerrupts	*/
+    outl ( 0x0000007F, EXTMASK );
	/* Mask all external Intrerrupts 	*/
+}
+
+#endif /* __ASM_ARCH_IRQ_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/irqs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,170 @@
+/*
+ * irqs.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file includes the interupt controller definitions 
+ * of the S3C2500X RISC microcontroller
+ * based on the Samsung's "S3C2500X 32-bit RISC
+ * microcontroller pre. User's Manual"
+ */
+ 
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define	INTMOD		0xF0140000	/* Internal interrupt mode R */
+#define	EXTMOD		0xF0140004	/* External interrupt mode R */
+#define	INTMASK		0xF0140008	/* Internal interrupt mask R */
+#define	EXTMASK		0xF014000C	/* External interrupt mask R */
+#define IPRIORHI	0xF0140010	/* HIgh bits, 5-0 bit, Interrupt by priority R */
+#define IPRIORLO	0xF0140014	/* LOw bits, 31-0 bit, Interrupt by priority R */
+#define INTOFFSET_FIQ	0xF0140018	/* FIQ interrupt offset R */
+#define INTOFFSET_IRQ	0xF014001C	/* IRQ interrupt offset R */
+#define INTPRIOR0	0xF0140020	/* Interrupt priority R 0 */
+#define INTPRIOR1	0xF0140024	/* Interrupt priority R 1 */
+#define INTPRIOR2	0xF0140028	/* Interrupt priority R 2 */
+#define INTPRIOR3	0xF014002C	/* Interrupt priority R 3 */
+#define INTPRIOR4	0xF0140030	/* Interrupt priority R 4 */
+#define INTPRIOR5	0xF0140034	/* Interrupt priority R 5 */
+#define INTPRIOR6	0xF0140038	/* Interrupt priority R 6 */
+#define INTPRIOR7	0xF014003C	/* Interrupt priority R 7 */
+#define INTPRIOR8	0xF0140040	/* Interrupt priority R 8 */
+#define INTPRIOR9	0xF0140044	/* Interrupt priority R 9 */
+#define INTTSTHI	0xF0140048	/* HIgh bits, 5-0 bit, Interrupt test R */
+#define INTTSTLO	0xF014004C	/* LOw bits, 31-0 bit, Interrupt test R */
+
+
+#define	NR_IRQS		39		/* There are 39 sources of the interrupts */
+
+#define	SRC_IRQ_0		0
+#define	SRC_IRQ_1		1
+#define	SRC_IRQ_2		2
+#define	SRC_IRQ_3		3
+#define	SRC_IRQ_4		4
+#define	SRC_IRQ_5		5
+#define	SRC_IRQ_IOM2		6
+#define	SRC_IRQ_IICC		7
+#define	SRC_IRQ_HUART0_TX	8
+#define	SRC_IRQ_HUART0_RX	9
+#define	SRC_IRQ_HUART1_TX	10
+#define	SRC_IRQ_HUART1_RX	11
+#define	SRC_IRQ_CUART_TX	12
+#define	SRC_IRQ_CUART_RX	13
+#define	SRC_IRQ_USB		14
+#define	SRC_IRQ_HDLC_TX0	15
+#define	SRC_IRQ_HDLC_RX0	16
+#define	SRC_IRQ_HDLC_TX1	17
+#define	SRC_IRQ_HDLC_RX1	18
+#define	SRC_IRQ_HDLC_TX2	19
+#define	SRC_IRQ_HDLC_RX2	20
+#define	SRC_IRQ_ETH_TX0		21
+#define	SRC_IRQ_ETH_RX0		22
+#define	SRC_IRQ_ETH_TX1		23
+#define	SRC_IRQ_ETH_RX1		24
+#define	SRC_IRQ_DES		25
+#define	SRC_IRQ_GDMA0		26
+#define	SRC_IRQ_GDMA1		27
+#define	SRC_IRQ_GDMA2		28
+#define	SRC_IRQ_GDMA3		29
+#define	SRC_IRQ_GDMA4		30
+#define	SRC_IRQ_GDMA5		31
+#define	SRC_IRQ_TIMER0		32
+#define	SRC_IRQ_TIMER1		33
+#define	SRC_IRQ_TIMER2		34
+#define	SRC_IRQ_TIMER3		35
+#define	SRC_IRQ_TIMER4		36
+#define	SRC_IRQ_TIMER5		37
+#define	SRC_IRQ_TIMER_WD	38
+
+
+#define NR_INT_IRQS	32		/* Internal interrupt sources number */
+
+#define	INT_IRQ_IICC		0
+#define	INT_IRQ_HUART0_TX	1
+#define	INT_IRQ_HUART0_RX	2
+#define	INT_IRQ_HUART1_TX	3
+#define	INT_IRQ_HUART1_RX	4
+#define	INT_IRQ_CUART_TX	5
+#define	INT_IRQ_CUART_RX	6
+#define	INT_IRQ_USB		7
+#define	INT_IRQ_HDLC_TX0	8
+#define	INT_IRQ_HDLC_RX0	9
+#define	INT_IRQ_HDLC_TX1	10
+#define	INT_IRQ_HDLC_RX1	11
+#define	INT_IRQ_HDLC_TX2	12
+#define	INT_IRQ_HDLC_RX2	13
+#define	INT_IRQ_ETH_TX0		14
+#define	INT_IRQ_ETH_RX0		15
+#define	INT_IRQ_ETH_TX1		16
+#define	INT_IRQ_ETH_RX1		17
+#define	INT_IRQ_DES		18
+#define	INT_IRQ_GDMA0		19
+#define	INT_IRQ_GDMA1		20
+#define	INT_IRQ_GDMA2		21
+#define	INT_IRQ_GDMA3		22
+#define	INT_IRQ_GDMA4		23
+#define	INT_IRQ_GDMA5		24
+#define	INT_IRQ_TIMER0		25
+#define	INT_IRQ_TIMER1		26
+#define	INT_IRQ_TIMER2		27
+#define	INT_IRQ_TIMER3		28
+#define	INT_IRQ_TIMER4		29
+#define	INT_IRQ_TIMER5		30
+#define	INT_IRQ_TIMER_WD	31
+
+#define	MASK_IRQ_IICC		0x00000001
+#define	MASK_IRQ_HUART0_TX	0x00000002
+#define	MASK_IRQ_HUART0_RX	0x00000004
+#define	MASK_IRQ_HUART1_TX	0x00000008
+#define	MASK_IRQ_HUART1_RX	0x00000010
+#define	MASK_IRQ_CUART_TX	0x00000020
+#define	MASK_IRQ_CUART_RX	0x00000040
+#define	MASK_IRQ_USB		0x00000080
+#define	MASK_IRQ_HDLC_TX0	0x00000100
+#define	MASK_IRQ_HDLC_RX0	0x00000200
+#define	MASK_IRQ_HDLC_TX1	0x00000400
+#define	MASK_IRQ_HDLC_RX1	0x00000800
+#define	MASK_IRQ_HDLC_TX2	0x00001000
+#define	MASK_IRQ_HDLC_RX2	0x00002000
+#define	MASK_IRQ_ETH_TX0	0x00004000
+#define	MASK_IRQ_ETH_RX0	0x00008000
+#define	MASK_IRQ_ETH_TX1	0x00010000
+#define	MASK_IRQ_ETH_RX1	0x00020000
+#define	MASK_IRQ_DES		0x00040000
+#define	MASK_IRQ_GDMA0		0x00080000
+#define	MASK_IRQ_GDMA1		0x00100000
+#define	MASK_IRQ_GDMA2		0x00200000
+#define	MASK_IRQ_GDMA3		0x00400000
+#define	MASK_IRQ_GDMA4		0x00800000
+#define	MASK_IRQ_GDMA5		0x01000000
+#define	MASK_IRQ_TIMER0		0x02000000
+#define	MASK_IRQ_TIMER1		0x04000000
+#define	MASK_IRQ_TIMER2		0x08000000
+#define	MASK_IRQ_TIMER3		0x10000000
+#define	MASK_IRQ_TIMER4		0x20000000
+#define	MASK_IRQ_TIMER5		0x40000000
+#define	MASK_IRQ_TIMER_WD	0x80000000
+
+
+#define	NR_EXT_IRQS	7		/* External interrupt sources number */
+
+#define	EXT_IRQ_0		0
+#define	EXT_IRQ_1		1
+#define	EXT_IRQ_2		2
+#define	EXT_IRQ_3		3
+#define	EXT_IRQ_4		4
+#define	EXT_IRQ_5		5
+#define	EXT_IRQ_IOM2		6
+
+#define	MASK_IRQ_0		0x00000001
+#define	MASK_IRQ_1		0x00000002
+#define	MASK_IRQ_2		0x00000004
+#define	MASK_IRQ_3		0x00000008
+#define	MASK_IRQ_4		0x00000010
+#define	MASK_IRQ_5		0x00000020
+#define	MASK_IRQ_IOM2		0x00000040
+#define	MASK_IRQ_GLOBAL		0x80000000
+
+	
+#endif	/* __ASM_ARCH_IRQS_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,29 @@
+/*
+ * linux/include/asm-armnommu/arch-p52/memory.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * 2001 Mindspeed
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define TASK_SIZE	(0x01a00000UL)
+#define TASK_SIZE_26	TASK_SIZE
+
+#define PHYS_OFFSET	(DRAM_BASE)
+#define PAGE_OFFSET 	(PHYS_OFFSET)
+#define END_MEM     	(DRAM_BASE + DRAM_SIZE)
+
+#define __virt_to_phys(vpage) ((unsigned long) (vpage))
+#define __phys_to_virt(ppage) ((void *) (ppage))
+#define __virt_to_bus(vpage) ((unsigned long) (vpage))
+#define __bus_to_virt(ppage) ((void *) (ppage))
+
+
+#endif
+
+
+
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/param.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/system.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-armnommu/arch-p52/system.h
+ * 2001 Mindspeed
+ */
+
+static inline void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter)
+	  cpu_do_idle(IDLE_WAIT_SLOW);
+}
+
+extern inline void arch_reset(char mode)
+{
+  /* tbd */
+}
+
+ 
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/time.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/time.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,41 @@
+/*
+ * time.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ */
+
+#ifndef __ASM_ARCH_TIME_H
+#define __ASM_ARCH_TIME_H
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/timex.h>
+
+extern struct irqaction timer_irq;
+
+extern unsigned long s3c2500_gettimeoffset(void);
+extern void s3c2500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+extern __inline__ void setup_timer (void)
+{
+    volatile struct s3c2500_timer* tt = (struct s3c2500_timer*) (TIMER_BASE);
+    unsigned long v, tmp;
+
+    gettimeoffset     = s3c2500_gettimeoffset;
+    timer_irq.handler = s3c2500_timer_interrupt;
+    
+    /* I/O port is used for timer */
+    tmp = *(unsigned int *)IO_Ftn_cont1 | ((0x1 << KERNEL_TIMER) << 22);
+    *(unsigned int *)IO_Ftn_cont1 = tmp;
+
+    tt->td[2*KERNEL_TIMER] = (unsigned long)(ARM_CLK/HZ);
+    tmp = tt->tmr & ~(0x7 << (3*KERNEL_TIMER));
+    tt->tmr = tmp | (0x1 << (3*KERNEL_TIMER));
+    setup_arm_irq((KERNEL_TIMER+32), &timer_irq);
+    enable_irq ( (KERNEL_TIMER+32) );
+}
+
+#endif /* __ASM_ARCH_TIME_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/timers.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/timers.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/timers.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/timers.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+ * timers.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file includes the 32-bit timers definitions 
+ * of the S3C2500X RISC microcontroller
+ * based on the Samsung's "S3C2500X 32-bit RISC
+ * microcontroller pre. User's Manual"
+ */
+ 
+#ifndef __ASM_ARCH_TIMERS_H
+#define __ASM_ARCH_TIMERS_H
+
+#define	KERNEL_TIMER	0
+
+#define	TMOD		0xF0040000	/* Timer mode R		*/
+#define	IC		0xF0040004	/* Interrupt clear R 	*/
+#define	WDT		0xF0040008	/* Wathdog timer R 	*/
+#define TDATA0		0xF0040010	/* Timer 0 data R 	*/
+#define TCNT0		0xF0040014	/* Timer 0 counter R 	*/
+#define TDATA1		0xF0040018	/* Timer 1 data R 	*/
+#define TCNT1		0xF004001C	/* Timer 1 counter R 	*/
+#define TDATA2		0xF0040020	/* Timer 2 data R 	*/
+#define TCNT2		0xF0040024	/* Timer 2 counter R 	*/
+#define TDATA3		0xF0040028	/* Timer 3 data R 	*/
+#define TCNT3		0xF004002C	/* Timer 3 counter R 	*/
+#define TDATA4		0xF0040030	/* Timer 4 data R 	*/
+#define TCNT4		0xF0040034	/* Timer 4 counter R 	*/
+#define TDATA5		0xF0040038	/* Timer 5 data R 	*/
+#define TCNT5		0xF004003C	/* Timer 5 counter R 	*/
+
+#define TIMER_BASE 	TMOD
+
+#ifndef __ASSEMBLER__
+struct s3c2500_timer
+{
+  unsigned int tmr;
+  unsigned int ic;
+  unsigned int wdt;
+  unsigned int reserved;
+  unsigned int td[12];
+};
+#endif
+	
+#endif	/* __ASM_ARCH_TIMERS_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+ * timex.h:
+ * 2001 Mindspeed
+ */
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+#define CLOCK_TICK_RATE	   0x270f
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/uart.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/uart.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/uart.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/uart.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,165 @@
+/*
+ * uart.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file includes the Serial I/O definitions 
+ * of the S3C2500X RISC microcontroller
+ * based on the Samsung's "S3C2500X 32-bit RISC
+ * microcontroller pre. User's Manual"
+ */
+ 
+#ifndef __ASM_ARCH_UART_H
+#define __ASM_ARCH_UART_H
+
+ /*
+ *	Console UART special registers
+*/
+#define CUCON		0xF0060000
+#define CUSTAT		0xF0060004
+#define CUINT		0xF0060008
+#define CUTXBUF		0xF006000C
+#define CURXBUF		0xF0060010
+#define CUBRD		0xF0060014
+#define CUCHAR1		0xF0060018
+#define CUCHAR2		0xF006001C
+
+ /*
+ *	High-speed UART special registers
+*/
+#define HUCON0		0xF0070000
+#define HUSTAT0		0xF0070004
+#define HUINT0		0xF0070008
+#define HUTXBUF0	0xF007000C
+#define HURXBUF0	0xF0070010
+#define HUBRD0		0xF0070014
+#define HUCHAR10	0xF0070018
+#define UUCHAR20	0xF007001C
+#define HUABB0		0xF0070100
+#define HUABT0		0xF0070104
+
+#define HUCON1		0xF0080000
+#define HUSTAT1		0xF0080004
+#define HUINT1		0xF0080008
+#define HUTXBUF1	0xF008000C
+#define HURXBUF1	0xF0080010
+#define HUBRD1		0xF0080014
+#define HUCHAR11	0xF0080018
+#define UUCHAR21	0xF008001C
+#define HUABB1		0xF0080100
+#define HUABT1		0xF0080104
+
+#define CUART_BASE 	CUCON
+#define HUART0_BASE 	HUCON0
+#define HUART1_BASE 	HUCON1
+
+
+#ifndef __ASSEMBLER__
+/****************************************  S3C2500 Samsung  UART registers */
+struct s3c2500_usart_regs{
+	unsigned int cr;		/* control		*/
+	unsigned int csr;		/* channel status	*/
+	unsigned int ier;		/* interrupt enable	*/
+	unsigned int thr;		/* tramsmit holding	*/
+	unsigned int rhr;		/* receive holding	*/
+	unsigned int brgr;		/* baud rate generator	*/
+	unsigned int ucc1;		/* contorl character 1	*/
+	unsigned int ucc2;		/* contorl character 2	*/
+};
+#endif
+
+/****************************************  UART control register */
+#define	U_DISABLE_TMODE	0xFFFFFFFC
+#define	U_IRQ_TMODE	0x00000001
+#define	U_GDMA_TMODE	0x00000002
+#define	U_TMODE		0x00000003
+
+#define	U_DISABLE_RMODE	0xFFFFFFF3
+#define	U_IRQ_RMODE	0x00000004
+#define	U_GDMA_RMODE	0x00000008
+#define	U_RMODE		0x0000000C
+
+#define	U_SBR		0x00000010
+#define	U_UCLK		0x00000020
+#define	U_AUBD		0x00000040
+#define	U_LOOPB		0x00000080
+
+#define	U_NO_PMD	0xFFFFF8FF
+#define	U_ODD_PMD	0x00000400
+#define	U_EVEN_PMD	0x00000500
+#define	U_FC1_PMD	0x00000600
+#define	U_FC0_PMD	0x00000700
+#define	U_PMD		0x00000700
+
+#define	U_STB		0x00000800
+
+#define	U_WL5		0xFFFFCFFF
+#define	U_WL6		0x00001000
+#define	U_WL7		0x00002000
+#define	U_WL8		0x00003000
+#define	U_WL		0x00003000
+
+#define	U_IR		0x00004000
+#define	U_TFEN		0x00010000
+#define	U_RFEN		0x00020000
+#define	U_TFRST		0x00040000
+#define	U_RFRST		0x00080000
+
+#define	U_TFTL30	0xFFCFFFFF
+#define	U_TFTL24	0x00100000
+#define	U_TFTL16	0x00200000
+#define	U_TFTL8		0x00300000
+#define	U_TFTL		0x00300000
+
+#define	U_RFTL1		0xFF3FFFFF
+#define	U_RFTL8		0x00400000
+#define	U_RFTL18	0x00800000
+#define	U_RFTL28	0x00C00000
+#define	U_RFTL		0x00C00000
+
+#define	U_DTR		0x01000000
+#define	U_RTS		0x02000000
+#define	U_HFEN		0x10000000
+#define	U_SFEN		0x20000000
+#define	U_ECHO		0x40000000
+#define	U_RTSRTR	0x80000000
+
+/****************************************  UART status register */
+#define	U_TFFUL		(1<<20)
+#define	U_TFEMT		(1<<19)
+#define	U_THE		(1<<18)
+#define	U_TI		(1<<17)
+#define	U_E_CTS		(1<<16)
+#define	U_CTS		(1<<15)
+#define	U_DSR		(1<<14)
+#define	U_E_RxTO	(1<<12)
+#define	U_RIDLE		(1<<11
+#define	U_RFOV		(1<<10)
+#define	U_RFFUL		(1<<9)
+#define	U_RFEMT		(1<<8)
+#define	U_RFREA		(1<<7)
+#define	U_DCD		(1<<6)
+#define	U_CCD		(1<<5)
+#define	U_OER		(1<<4)
+#define	U_PER		(1<<3)
+#define	U_FER		(1<<2)
+#define	U_BSD		(1<<1)
+#define	U_RDV		(1)
+
+/****************************************  UART Interrupt Enable register */
+#define	U_THEIE		(1<<18)
+#define	U_TIIE		(1<<17)
+#define	U_E_CTSIE	(1<<16)
+#define	U_E_RxTOIE	(1<<12)
+#define	U_OVFFIE	(1<<10)
+#define	U_RFREAIE	(1<<7)
+#define	U_DCDLIE	(1<<6)
+#define	U_CCDIE		(1<<5)
+#define	U_OERIE		(1<<4)
+#define	U_PERIE		(1<<3)
+#define	U_FERIE		(1<<2)
+#define	U_BSDIE		(1<<1)
+#define	U_RDVIE		(1)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C2500REFRGP/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C2500REFRGP/vmalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ *  linux/include/asm-arm/arch-dsc21/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/a.out.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/a.out.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/a.out.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,16 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C3410/a.out.h
+ *
+ * (just a placeholder, not needed in our machine)
+ *
+ * 2003 Thomas Eschenbacher <thomas.eschenbacher@gmx.de>
+ *
+ */
+#ifndef __ASM_ARCH_A_OUT_H
+#define __ASM_ARCH_A_OUT_H
+
+#ifdef __KERNEL__
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,14 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C3410/dma.h:
+ *
+ * 2003 Thomas Eschenbacher <thomas.eschenbacher@gmx.de>
+ *
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_ADDRESS   0x03000000
+#define MAX_DMA_CHANNELS  2
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C3410/hardware.h
+ *
+ * 2003 Thomas Eschenbacher <thomas.eschenbacher@gmx.de>
+ *
+ * Hardware definitions of SMDK40100 board, currently only
+ * the CPUs registers and definitions are included from
+ * s3c3410.h.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <linux/config.h>
+#include <asm/arch/s3c3410.h>
+
+#ifndef __ASSEMBLER__
+
+/**************************************** RAM definitions */
+// #define MAPTOPHYS(a)      ((unsigned long)a)
+// #define KERNTOPHYS(a)     ((unsigned long)(&a))
+// #define GET_MEMORY_END(p) ((p->u1.s.page_size) * (p->u1.s.nr_pages))
+// #define PARAMS_BASE       0x7000
+#define HARD_RESET_NOW()  { arch_hard_reset(); }
+
+#endif /* ! __ASSEMBLER__ */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/io.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,101 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C3410/io.h
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ *  02-19-2001  gjm     Leveraged for armnommu/dsc21
+ *  05-04-2003  the     copied to S3C3410 arch
+ *
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ * --gmcnutt
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * These functions are needed for mtd/maps/physmap.c
+ * (copied from include/asm/arch-atmel/io.h)
+ * --the
+ */
+#ifndef memset_io
+#define memset_io(a,b,c)                _memset_io((a),(b),(c))
+#endif
+#ifndef memcpy_fromio
+#define memcpy_fromio(a,b,c)            _memcpy_fromio((a),(b),(c))
+#endif
+#ifndef memcpy_toio
+#define memcpy_toio(a,b,c)              _memcpy_toio((a),(b),(c))
+#endif
+
+/* maybe someone needs this in far future... */
+#define PCIO_BASE 0
+
+/*
+ * These macros were copied from arch/armnommu/io.h and are used instead
+ * of the definitions found there, because we want to do 16/32 bit i/o
+ * without byte swapping.
+ * --the
+ */
+#define __arch_getw(a)    (*(volatile unsigned short *)(a))
+#define __arch_putw(v,a)  (*(volatile unsigned short *)(a) = (v))
+
+#ifndef __iob
+  #define __iob(a) __io(a)
+#endif
+
+#define outb(v,p)	__raw_writeb(v, p)
+#define outw(v,p)	__raw_writew(v, p)
+#define outl(v,p)	__raw_writel(v, p)
+
+#define inb(p)		({ unsigned int __v = __raw_readb(p); __v; })
+#define inw(p)		({ unsigned int __v = __raw_readw(p); __v; })
+#define inl(p)		({ unsigned int __v = __raw_readl(p); __v; })
+
+#define outsb(p,d,l)	__raw_writesb(p, d, l)
+#define outsw(p,d,l)	__raw_writesw(p, d, l)
+#define outsl(p,d,l)	__raw_writesl(p, d, l)
+
+#define insb(p,d,l)	__raw_readsb(p, d, l)
+#define insw(p,d,l)	__raw_readsw(p, d, l)
+#define insl(p,d,l)	__raw_readsl(p, d, l)
+
+#if 1
+/*
+ * Defining these two gives us ioremap for free. See asm/io.h.
+ * --gmcnutt
+ */
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+#else
+/*
+ * Cacheable/non-cacheable access of the S3C3410 is simply done via usage 
+ * of address line A27, so remapping with/without cache is quite easy.
+ *
+ * BUG: for some dubious reason this does not work yet, the kernel
+ *      boots fine, but the shell doesn't come up!?
+ *      Thus I had to disable this code for now... :-(
+ *
+ * --the 2003-05-04
+ */
+#define __arch_ioremap(off,sz,nocache) \
+	((void*)( (nocache) ? \
+	((off) |  S3C3410X_UNCACHED) : \
+	((off) & ~S3C3410X_UNCACHED) \
+	))
+
+#define __arch_iounmap __iounmap
+
+#endif
+
+#endif /* __ASM_ARM_ARCH_IO_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,59 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C3410/irq.h
+ *
+ * 2003 Thomas Eschenbacher <thomas.eschenbacher@gmx.de>
+ *
+ */
+
+#ifndef __ASM_ARCH_IRQ_H__
+#define __ASM_ARCH_IRQ_H__
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irqs.h>
+
+extern void s3c3410_mask_irq(unsigned int irq);
+extern void s3c3410_unmask_irq(unsigned int irq);
+extern void s3c3410_mask_ack_irq(unsigned int irq);
+extern void s3c3410_clear_pb(unsigned int irq);
+
+static __inline__ unsigned int fixup_irq (unsigned int irq)
+{
+	s3c3410_clear_pb(irq);
+	return (irq);
+}
+
+static __inline__ void irq_init_irq(void)
+{
+	int irq;
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= s3c3410_mask_ack_irq;
+		irq_desc[irq].mask	= s3c3410_mask_irq;
+		irq_desc[irq].unmask	= s3c3410_unmask_irq;
+
+		/* @TODO initialize interrupt priorities */
+	}
+
+
+	/* mask and disable all further interrupts */
+	outl(0x00000000, S3C3410X_INTMSK);
+
+	/* set all to IRQ mode, not FIQ */
+	outl(0x00000000, S3C3410X_INTMOD);
+
+	/* Clear Intrerrupt pending register	*/
+	outl(0x00000000, S3C3410X_INTPND);
+
+	/*
+	 * enable the gloabal interrupt flag, this should be
+	 * safe now, all sources are masked out and acknowledged
+	 */
+	outb(inb(S3C3410X_SYSCON) | S3C3410X_SYSCON_GIE, S3C3410X_SYSCON);
+	
+}
+
+
+#endif /* __ASM_ARCH_IRQ_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/irqs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,48 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C3410/irqs.h
+ *
+ * 2003 Thomas Eschenbacher <thomas.eschenbacher@gmx.de>
+ *
+ * All IRQ numbers of the S3C3410X CPUs.
+ *
+ */
+
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+
+#define NR_IRQS		32
+
+#define S3C3410X_INTERRUPT_EINT0	 0	/* External int. 0 */
+#define S3C3410X_INTERRUPT_EINT1	 1	/* External int. 1 */
+#define S3C3410X_INTERRUPT_URX  	 2	/* UART receive */
+#define S3C3410X_INTERRUPT_UTX  	 3	/* UART transmit */
+#define S3C3410X_INTERRUPT_UERR 	 4	/* UART error */
+#define S3C3410X_INTERRUPT_DMA0 	 5	/* DMA 0 */
+#define S3C3410X_INTERRUPT_DMA1 	 6	/* DMA 1 */
+#define S3C3410X_INTERRUPT_TOF0 	 7	/* Timer 0 overflow */
+#define S3C3410X_INTERRUPT_TMC0 	 8	/* Timer 0 match/capture */
+#define S3C3410X_INTERRUPT_TOF1 	 9	/* Timer 1 overflow */
+#define S3C3410X_INTERRUPT_TMC1 	10	/* Timer 1 match/capture */
+#define S3C3410X_INTERRUPT_TOF2 	11	/* Timer 2 overflow */
+#define S3C3410X_INTERRUPT_TMC2 	12	/* Timer 2 match/capture */
+#define S3C3410X_INTERRUPT_TOF3 	13	/* Timer 3 overflow */
+#define S3C3410X_INTERRUPT_TMC3 	14	/* Timer 3 match/capture */
+#define S3C3410X_INTERRUPT_TOF4 	15	/* Timer 4 overflow */
+#define S3C3410X_INTERRUPT_TMC4 	16	/* Timer 4 match/capture */
+#define S3C3410X_INTERRUPT_BT   	17	/* Basic Timer */
+#define S3C3410X_INTERRUPT_SIO0 	18	/* SIO 0 */
+#define S3C3410X_INTERRUPT_SIO1 	19	/* SIO 1 */
+#define S3C3410X_INTERRUPT_IIC  	20	/* IIC */
+#define S3C3410X_INTERRUPT_RTCA 	21	/* RTC alarm */
+#define S3C3410X_INTERRUPT_RTCT 	22	/* RTC time (SEC/MIN/HOUR) */
+#define S3C3410X_INTERRUPT_TF   	23	/* Timer4 FIFO interrupt */
+#define S3C3410X_INTERRUPT_EINT2	24	/* External int. 2 */
+#define S3C3410X_INTERRUPT_EINT3	25	/* External int. 3 */
+#define S3C3410X_INTERRUPT_EINT4567	26	/* External int. 4/5/6/7 */
+#define S3C3410X_INTERRUPT_ADC   	27	/* ADC interrupt */
+#define S3C3410X_INTERRUPT_EINT8	28	/* External int. 8 */
+#define S3C3410X_INTERRUPT_EINT9	29	/* External int. 9 */
+#define S3C3410X_INTERRUPT_EINT10	30	/* External int. 10 */
+#define S3C3410X_INTERRUPT_EINT11	31	/* External int. 11 */
+
+#endif /* __ASM_ARCH_IRQS_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/keyboard.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/keyboard.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/keyboard.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C3410/keyboard.h
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  (Dummy) Keyboard driver definitions for ARM
+ */
+#ifndef __ASM_ARM_ARCH_S3C3410_KEYBOARD_H
+#define __ASM_ARM_ARCH_S3C3410_KEYBOARD_H
+
+/*
+ * Required by drivers/char/keyboard.c. I took these from arch-arc.
+ * --gmcnutt
+ */
+#define kbd_setkeycode(sc,kc) (-EINVAL)
+#define kbd_getkeycode(sc) (-EINVAL)
+#define kbd_translate(sc,kcp,rm) ({ *(kcp) = (sc); 1; })
+#define kbd_unexpected_up(kc) (0200)
+#define kbd_leds(leds)
+#define kbd_init_hw()
+#define kbd_enable_irq() /* what irq? ;) --gmcnutt */
+#define kbd_disable_irq()
+
+#endif /* __ASM_ARM_ARCH_S3C3410_KEYBOARD_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,34 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C3410/memory.h
+ *
+ * Copyright (c) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ * 
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define TASK_SIZE	(0x01a00000UL)
+#define TASK_SIZE_26	TASK_SIZE
+
+#if 0
+#define PHYS_OFFSET     (DRAM_BASE + 14*8192)
+#define PAGE_OFFSET 	(PHYS_OFFSET)
+#define END_MEM		(DRAM_SIZE)
+#else
+#define PHYS_OFFSET     (DRAM_BASE + 128*1024)
+#define PAGE_OFFSET 	(PHYS_OFFSET)
+#define END_MEM		(DRAM_BASE + DRAM_SIZE - 128*1024)
+#endif
+
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((unsigned long) (vpage))
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((void *) (ppage))
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(vpage) ((unsigned long) (vpage))
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(ppage) ((void *) (ppage))
+
+#endif /* __ASM_ARCH_MEMORY_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/param.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,14 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C3410/a.out.h
+ *
+ * (just a placeholder, not needed in our machine)
+ *
+ * 2003 Thomas Eschenbacher <thomas.eschenbacher@gmx.de>
+ *
+ */
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/pcmcia.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/pcmcia.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/pcmcia.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/pcmcia.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,11 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C3410/pcmcia.h
+ *
+ * (just a placeholder, not needed in our machine)
+ *
+ * 2003 Thomas Eschenbacher <thomas.eschenbacher@gmx.de>
+ *
+ */
+#ifdef CONFIG_REVISIT
+#error Do we need PCMCIA support?
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/processor.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/processor.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/processor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,19 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C3410/processor.h
+ *
+ */
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+#define EISA_bus 0
+#define EISA_bus__is_a_macro
+#define MCA_bus 0
+#define MCA_bus__is_a_macro
+
+#define TASK_SIZE (0x01a00000UL)
+
+#define INIT_MMAP { \
+  &init_mm, 0, 0x02000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC \
+}
+
+#endif /* __ASM_ARCH_PROCESSOR_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/s3c3410.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/s3c3410.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/s3c3410.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/s3c3410.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,381 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C3410/s3c3410.h
+ *
+ * Special function registers of the Samsung S3C3410X
+ *
+ * (C) 2003 sympat GmbH
+ * by Thomas Eschenbacher <thomas.eschenbacher@sympat.de>
+ *
+ */
+
+#ifndef __ASM_ARCH_S3C3410_H
+#define __ASM_ARCH_S3C3410_H
+
+/* Address offset for accessing external memory uncached (A27=1) */
+#define S3C3410X_UNCACHED        0x08000000             /* (1 << 27) */
+
+/*
+ * SFR Base Address
+ */
+#define S3C3410X_BASE            0x07FF0000
+
+/* ************************ */
+/* System Manager Registers */
+/* ************************ */
+#define S3C3410X_SYSCFG          (S3C3410X_BASE+0x1000) /* System Configuration */
+
+#define S3C3410X_SYSCFG_ST       0x00000001		/* Stall enable */
+#define S3C3410X_SYSCFG_CE       0x00000002		/* Cache enable*/
+#define S3C3410X_SYSCFG_WE       0x00000004		/* Write Buffer enable */
+#define S3C3410X_SYSCFG_SFRSA    0x00007FF0		/* SYSCFG Address (SFR Start Address) */
+
+#define S3C3410X_SYSCFG_CM_MASK  0x00018000		/* Cache Mode (MASK) */
+#define S3C3410X_SYSCFG_CM_22    0x00000000		/* (Cache Mode) 2k Cache / 2k SRAM */
+#define S3C3410X_SYSCFG_CM_CACHE 0x00008000		/* (Cache Mode) 4k Cache */
+#define S3C3410X_SYSCFG_CM_SRAM  0x00010000		/* (Cache Mode) 4k SRAM */
+
+#define S3C3410X_SYSCFG_AME      0x00020000		/* Address Mux Enable */
+#define S3C3410X_SYSCFG_MT0_RFS  0x00000000		/* Memory Type 0 ROM/Flash/SRAM */
+#define S3C3410X_SYSCFG_MT0_FP   0x00040000		/* Memory Type 0 FP DRAM */
+#define S3C3410X_SYSCFG_MT0_EDO  0x00080000		/* Memory Type 0 EDO DRAM */
+#define S3C3410X_SYSCFG_MT0_SD   0x000C0000		/* Memory Type 0 Sync. DRAM */
+#define S3C3410X_SYSCFG_MT1_RFS  0x00000000		/* Memory Type 1 ROM/Flash/SRAM */
+#define S3C3410X_SYSCFG_MT1_FP   0x00100000		/* Memory Type 1 FP DRAM */
+#define S3C3410X_SYSCFG_MT1_EDO  0x00200000		/* Memory Type 1 EDO DRAM */
+#define S3C3410X_SYSCFG_MT1_SD   0x00300000		/* Memory Type 1 Sync. DRAM */
+
+#define S3C3410X_BANKCON0	(S3C3410X_BASE+0x2000) /* Memory Bank 0 Control */
+#define S3C3410X_BANKCON1	(S3C3410X_BASE+0x2004) /* Memory Bank 1 Control */
+#define S3C3410X_BANKCON2	(S3C3410X_BASE+0x2008) /* Memory Bank 2 Control */
+#define S3C3410X_BANKCON3	(S3C3410X_BASE+0x200C) /* Memory Bank 3 Control */
+#define S3C3410X_BANKCON4	(S3C3410X_BASE+0x2010) /* Memory Bank 4 Control */
+#define S3C3410X_BANKCON5	(S3C3410X_BASE+0x2014) /* Memory Bank 5 Control */
+#define S3C3410X_BANKCON6	(S3C3410X_BASE+0x2018) /* Memory Bank 6 Control */
+#define S3C3410X_BANKCON7	(S3C3410X_BASE+0x201C) /* Memory Bank 7 Controlr */
+
+#define S3C3410X_BANKCON_DBW	    0x00000001 	    	/* Data Bus Width (16Bit enable) else 8Bit */
+#define S3C3410X_BANKCON_PMC_1D	    0x00000000 	    	/* Page Mode 1Data */
+#define S3C3410X_BANKCON_PMC_4D	    0x00000002 	    	/* Page Mode 4Data */
+#define S3C3410X_BANKCON_PMC_8D	    0x00000004 	    	/* Page Mode 8Data */
+#define S3C3410X_BANKCON_PMC_16D    0x00000006 	    	/* Page Mode 16Data */
+#define S3C3410X_BANKCON_SM	    0x00000008 	    	/* UB/LB Byte selection enable (see nWE,WE in Chipdesign) */
+#define S3C3410X_BANKCON_TACC_DIS   0x00000000 	    	/* Access Cycle Timing Disabled */
+#define S3C3410X_BANKCON_TACC_2C    0x00000010 	    	/* Access Cycle Timing 2Clocks */
+#define S3C3410X_BANKCON_TACC_3C    0x00000020 	    	/* Access Cycle Timing 3Clocks */
+#define S3C3410X_BANKCON_TACC_4C    0x00000030 	    	/* Access Cycle Timing 4Clocks */
+#define S3C3410X_BANKCON_TACC_5C    0x00000040 	    	/* Access Cycle Timing 5Clocks */
+#define S3C3410X_BANKCON_TACC_6C    0x00000050 	    	/* Access Cycle Timing 6Clocks */
+#define S3C3410X_BANKCON_TACC_7C    0x00000060 	    	/* Access Cycle Timing 7Clocks */
+#define S3C3410X_BANKCON_TACC_10C   0x00000070 	    	/* Access Cycle Timing 10Clocks */
+#define S3C3410X_BANKCON_TACP_2C    0x00000080 	    	/* Page Mode Access Cycle Timing 2Clocks */
+#define S3C3410X_BANKCON_TACP_3C    0x00000100 	    	/* Page Mode Access Cycle Timing 3Clocks */
+#define S3C3410X_BANKCON_TACP_4C    0x00000180 	    	/* Page Mode Access Cycle Timing 4Clocks */
+#define S3C3410X_BANKCON_TACP_5C    0x00000000 	    	/* Page Mode Access Cycle Timing 5Clocks */
+
+#define S3C3410X_REFCON  	(S3C3410X_BASE+0x2020) /* DRAM Refresh Control */
+
+#define S3C3410X_EXTCON0 	(S3C3410X_BASE+0x2030) /* Extra device control 0 */
+#define S3C3410X_EXTCON1 	(S3C3410X_BASE+0x2034) /* Extra device control 1 */
+#define S3C3410X_EXTPORT 	(S3C3410X_BASE+0x203E) /* External port data */
+
+#define S3C3410X_EXTDAT0 	(S3C3410X_BASE+0x202C) /* Extra chip selection data 0 */
+#define S3C3410X_EXTDAT1 	(S3C3410X_BASE+0x202E) /* Extra chip selection data 1 */
+
+/* ************* */
+/* DMA Registers */
+/* ************* */
+#define S3C3410X_DMACON0 	(S3C3410X_BASE+0x300C) /* DMA 0 control */
+#define S3C3410X_DMASRC0 	(S3C3410X_BASE+0x3000) /* DMA 0 source address */
+#define S3C3410X_DMADST0 	(S3C3410X_BASE+0x3004) /* DMA 0 destination address */
+#define S3C3410X_DMACNT0 	(S3C3410X_BASE+0x3008) /* DMA 0 transfer count */
+
+#define S3C3410X_DMACON1 	(S3C3410X_BASE+0x400C) /* DMA 1 control */
+#define S3C3410X_DMASRC1 	(S3C3410X_BASE+0x4000) /* DMA 1 source address */
+#define S3C3410X_DMADST1 	(S3C3410X_BASE+0x4004) /* DMA 1 destination address */
+#define S3C3410X_DMACNT1 	(S3C3410X_BASE+0x4008) /* DMA 1 transfer count */
+
+/* ******************* */
+/* I/O Ports Registers */
+/* ******************* */
+#define S3C3410X_PDAT0   	(S3C3410X_BASE+0xB000) /* Port 0 data */
+#define S3C3410X_PDAT1   	(S3C3410X_BASE+0xB001) /* Port 1 data */
+#define S3C3410X_PDAT2   	(S3C3410X_BASE+0xB002) /* Port 2 data */
+#define S3C3410X_PDAT3   	(S3C3410X_BASE+0xB003) /* Port 3 data */
+#define S3C3410X_PDAT4   	(S3C3410X_BASE+0xB004) /* Port 4 data */
+#define S3C3410X_PDAT5   	(S3C3410X_BASE+0xB005) /* Port 5 data */
+#define S3C3410X_PDAT6   	(S3C3410X_BASE+0xB006) /* Port 6 data */
+#define S3C3410X_PDAT7   	(S3C3410X_BASE+0xB007) /* Port 7 data */
+#define S3C3410X_PDAT8   	(S3C3410X_BASE+0xB008) /* Port 8 data */
+#define S3C3410X_PDAT9   	(S3C3410X_BASE+0xB009) /* Port 9 data */
+
+#define S3C3410X_P7BR    	(S3C3410X_BASE+0xB00B) /* Port 7 buffer */
+
+#define S3C3410X_PCON0   	(S3C3410X_BASE+0xB010) /* Port 0 control */
+#define S3C3410X_PCON1   	(S3C3410X_BASE+0xB012) /* Port 1 control */
+#define S3C3410X_PCON2   	(S3C3410X_BASE+0xB014) /* Port 2 control */
+#define S3C3410X_PCON3   	(S3C3410X_BASE+0xB016) /* Port 3 control */
+#define S3C3410X_PCON4   	(S3C3410X_BASE+0xB018) /* Port 4 control */
+#define S3C3410X_PCON5   	(S3C3410X_BASE+0xB01C) /* Port 5 control */
+#define S3C3410X_PCON6   	(S3C3410X_BASE+0xB020) /* Port 6 control */
+#define S3C3410X_PCON7   	(S3C3410X_BASE+0xB024) /* Port 7 control */
+#define S3C3410X_PCON8   	(S3C3410X_BASE+0xB026) /* Port 8 control */
+#define S3C3410X_PCON9   	(S3C3410X_BASE+0xB027) /* Port 9 control */
+
+#define S3C3410X_PUR0    	(S3C3410X_BASE+0xB028) /* Port 0 pull-up control */
+#define S3C3410X_PDR1    	(S3C3410X_BASE+0xB029) /* Port 1 pull-down control */
+#define S3C3410X_PUR2    	(S3C3410X_BASE+0xB02A) /* Port 2 pull-up control */
+#define S3C3410X_PUR3    	(S3C3410X_BASE+0xB02B) /* Port 3 pull-up control */
+#define S3C3410X_PDR4    	(S3C3410X_BASE+0xB02C) /* Port 4 pull-down control */
+#define S3C3410X_PUR5    	(S3C3410X_BASE+0xB02D) /* Port 5 pull-up control */
+#define S3C3410X_PUR6    	(S3C3410X_BASE+0xB02E) /* Port 6 pull-up control */
+#define S3C3410X_PUR7    	(S3C3410X_BASE+0xB02F) /* Port 7 pull-up control */
+#define S3C3410X_PUR8    	(S3C3410X_BASE+0xB03C) /* Port 8 pull-up control */
+
+#define S3C3410X_EINTPND  	(S3C3410X_BASE+0xB031) /* External interrupt pending */
+#define S3C3410X_EINTCON  	(S3C3410X_BASE+0xB032) /* External interrupt control */
+#define S3C3410X_EINTMOD  	(S3C3410X_BASE+0xB034) /* External interrupt mode */
+
+/* *************** */
+/* Timer Registers */
+/* *************** */
+
+#define S3C3410X_TDAT0   	(S3C3410X_BASE+0x9000) /* Timer 0 data */
+#define S3C3410X_TPRE0   	(S3C3410X_BASE+0x9002) /* Timer 0 prescaler */
+#define S3C3410X_TCON0   	(S3C3410X_BASE+0x9003) /* Timer 0 control */
+#define S3C3410X_TCNT0   	(S3C3410X_BASE+0x9006) /* Timer 0 counter */
+
+#define S3C3410X_T16_ICS	0x00000004	/* 16Bit-Timer Input Select */
+#define S3C3410X_T16_OMS_MODE	0x00000038	/* 16Bit-Timer Mode bits */
+#define S3C3410X_T16_OMS_INTRV	0x00000000	/* 16Bit-Timer Mode (interval mode) */
+#define S3C3410X_T16_OMS_MAOF	0x00000008	/* 16Bit-Timer Mode (match & overflow mode) */
+#define S3C3410X_T16_OMS_MAD	0x00000010	/* 16Bit-Timer Mode (match & DMA mode) */
+#define S3C3410X_T16_OMS_CAPF	0x00000020	/* 16Bit-Timer Mode (capture on falling edge of TCAP 0,1,2) */
+#define S3C3410X_T16_OMS_CAPR	0x00000028	/* 16Bit-Timer Mode (capture on rising edge of TCAP 0,1,2) */
+#define S3C3410X_T16_OMS_CAPRF	0x00000030	/* 16Bit-Timer Mode (capture on rising/falling edge of TCAP 0,1,2) */
+#define S3C3410X_T16_CL		0x00000040	/* 16Bit-Timer Clear */
+#define S3C3410X_T16_TEN	0x00000080	/* 16Bit-Timer Enable */
+
+#define S3C3410X_TDAT1   	(S3C3410X_BASE+0x9010) /* Timer 1 data */
+#define S3C3410X_TPRE1   	(S3C3410X_BASE+0x9012) /* Timer 1 prescaler */
+#define S3C3410X_TCON1   	(S3C3410X_BASE+0x9013) /* Timer 1 control */
+#define S3C3410X_TCNT1   	(S3C3410X_BASE+0x9016) /* Timer 1 counter */
+
+#define S3C3410X_TDAT2   	(S3C3410X_BASE+0x9020) /* Timer 2 data */
+#define S3C3410X_TPRE2   	(S3C3410X_BASE+0x9022) /* Timer 2 prescaler */
+#define S3C3410X_TCON2   	(S3C3410X_BASE+0x9023) /* Timer 2 control */
+#define S3C3410X_TCNT2   	(S3C3410X_BASE+0x9026) /* Timer 2 counter */
+
+#define S3C3410X_TDAT3   	(S3C3410X_BASE+0x9030) /* Timer 3 data */
+#define S3C3410X_TPRE3   	(S3C3410X_BASE+0x9032) /* Timer 3 prescaler */
+#define S3C3410X_TCON3   	(S3C3410X_BASE+0x9033) /* Timer 3 control */
+#define S3C3410X_TCNT3   	(S3C3410X_BASE+0x9037) /* Timer 3 counter */
+
+#define S3C3410X_TDAT4   	(S3C3410X_BASE+0x9041) /* Timer 4 data */
+#define S3C3410X_TPRE4   	(S3C3410X_BASE+0x9042) /* Timer 4 prescaler */
+#define S3C3410X_TCON4   	(S3C3410X_BASE+0x9043) /* Timer 4 control */
+#define S3C3410X_TCNT4   	(S3C3410X_BASE+0x9047) /* Timer 4 counter */
+#define S3C3410X_TFCON   	(S3C3410X_BASE+0x904F) /* Timer 4 FIFO control */
+#define S3C3410X_TFSTAT  	(S3C3410X_BASE+0x904E) /* Timer 4 FIFO status */
+#define S3C3410X_TFB4    	(S3C3410X_BASE+0x904B) /* Timer 4 FIFO @ byte */
+#define S3C3410X_TFHW4   	(S3C3410X_BASE+0x904A) /* Timer 4 FIFO @ half-word */
+#define S3C3410X_TFW4    	(S3C3410X_BASE+0x9048) /* Timer 4 FIFO @ word */
+
+/* #define TDATA0	TDAT0
+   #define TMOD 	TCON0 */
+
+/* ************** */
+/* UART Registers */
+/* ************** */
+
+#define S3C3410X_UART_BASE	(S3C3410X_BASE) /* "virtual" start of UART registers */
+
+#define S3C3410X_ULCON   	(0x5003) /* UART line control */
+#define S3C3410X_UCON    	(0x5007) /* UART control */
+#define S3C3410X_USTAT   	(0x500B) /* UART status */
+#define S3C3410X_UFCON   	(0x500F) /* UART FIFO control */
+#define S3C3410X_UFSTAT  	(0x5012) /* UART FIFO status */
+#define S3C3410X_UTXH    	(0x5017) /* UART transmit holding */
+#define S3C3410X_UTXH_B  	(0x5017) /* UART transmit FIFO @ byte */
+#define S3C3410X_UTXH_HW 	(0x5016) /* UART transmit FIFO @ half-word */
+#define S3C3410X_UTXH_W  	(0x5014) /* UART transmit FIFO @ word */
+#define S3C3410X_URXH    	(0x501B) /* UART receive holding */
+#define S3C3410X_URXH_B  	(0x501B) /* UART receive FIFO @ byte */
+#define S3C3410X_URXH_HW 	(0x501A) /* UART receive FIFO @ half-word */
+#define S3C3410X_URXH_W  	(0x5018) /* UART receive FIFO @ word */
+#define S3C3410X_UBRDIV  	(0x501E) /* baud rate divisor */
+
+/* UART Line Control Register Bits */
+#define ULCON_WL_MASK		0x03	/* UART Word Length Mask */
+#define ULCON_WL_5		0x00	/* UART Word Length: 5 bits */
+#define ULCON_WL_6		0x01	/* UART Word Length: 6 bits */
+#define ULCON_WL_7		0x02	/* UART Word Length: 7 bits */
+#define ULCON_WL_8		0x03	/* UART Word Length: 8 bits */
+#define ULCON_SB		0x04	/* UART Stop Bits */
+#define ULCON_PMD_MASK		0x38	/* UART Parity Mode Mask */
+#define ULCON_PMD_NONE		0x00	/* UART Parity Mode: None */
+#define ULCON_PMD_ODD		0x20	/* UART Parity Mode: Odd */
+#define ULCON_PMD_EVEN		0x28	/* UART Parity Mode: Even */
+#define ULCON_IRM		0x40	/* UART Infrared Mode */
+/* 				0x80	   unused */
+
+
+/* UART Control Register Bits */
+#define UCON_RM_MASK		0x03	/* UART Mask for Receive Mode */
+#define UCON_RM_DISABLED	0x00	/* UART Receive Mode 0 : Disabled */
+#define UCON_RM_IRQ_POLL	0x01	/* UART Receive Mode 1 : Interrupt or Polling Mode */
+#define UCON_RM_DMA0		0x02	/* UART Receive Mode 2 : DMA0 request */
+#define UCON_RM_DMA1		0x03	/* UART Receive Mode 3 : DMA1 request */
+
+#define UCON_TM_MASK		0x0C	/* UART Mask for Transmit Mode */
+#define UCON_TM_DISABLED	0x00	/* UART Transmit Mode 0 : Disabled */
+#define UCON_TM_IRQ_POLL	0x04	/* UART Transmit Mode 1 : Interrupt or Polling Mode */
+#define UCON_TM_DMA0		0x08	/* UART Transmit Mode 2 : DMA0 request */
+#define UCON_TM_DMA1		0x0C	/* UART Transmit Mode 3 : DMA1 request */
+
+#define UCON_SBS		0x10	/* UART Send Break Signal */
+#define UCON_LBM		0x20	/* UART Loopback Mode */
+#define UCON_RSIE		0x40	/* UART Rx Status Interrupt Enable */
+#define UCON_RXTOEL		0x80	/* UART Rx Timeout Enable */
+
+/* UART Status Register Bits */
+#define USTAT_OE 		0x01	/* UART Overrun Error */
+#define USTAT_PE 		0x02	/* UART Parity Error */
+#define USTAT_FE 		0x04	/* UART Framing Error */
+#define USTAT_BD 		0x08	/* UART Break Detect */
+#define USTAT_RTO 		0x10	/* UART Receiver Time Out */
+#define USTAT_RFDR 		0x20	/* UART Receive FIFO Data Ready / Rx Buffer Data Ready */
+#define USTAT_TFE 		0x40	/* UART Transmit FIFO Empty / Tx Holding Register Empty */
+#define USTAT_TSE 		0x80	/* UART Transmit Shift Register Empty */
+
+/* UART FIFO Control Register Bits */
+#define UFCON_FE		0x01	/* UART FIFO Enable */
+#define UFCON_RFR		0x02	/* UART Rx FIFO Reset */
+#define UFCON_TFR		0x04	/* UART Tx FIFO Reset */
+/*				0x08	   reserved */
+#define UFCON_RFTL_MASK		0x30	/* UART Receive FIFO Trigger Level Mask */
+#define UFCON_RFTL_2		0x00	/* UART Receive FIFO Trigger Level: 2 byte */
+#define UFCON_RFTL_4		0x10	/* UART Receive FIFO Trigger Level: 4 byte */
+#define UFCON_RFTL_6		0x20	/* UART Receive FIFO Trigger Level: 6 byte */
+#define UFCON_RFTL_8		0x30	/* UART Receive FIFO Trigger Level: 8 byte */
+
+#define UFCON_TFTL_MASK		0x30	/* UART Transmit FIFO Trigger Level Mask */
+#define UFCON_TFTL_0		0x00	/* UART Transmit FIFO Trigger Level: 0 byte */
+#define UFCON_TFTL_2		0x10	/* UART Transmit FIFO Trigger Level: 2 byte */
+#define UFCON_TFTL_4		0x20	/* UART Transmit FIFO Trigger Level: 4 byte */
+#define UFCON_TFTL_6		0x30	/* UART Transmit FIFO Trigger Level: 6 byte */
+
+#define UFSTAT_RFC_MASK		0x07    /* UART FIFO STATUS Rx FIFO count */
+#define UFSTAT_TFC_MASK		0x38    /* UART FIFO STATUS Rx FIFO count */
+#define UFSTAT_RFF		0x20	/* UART FIFO STATUS Receive FIFO FULL */
+#define UFSTAT_TFF		0x40	/* UART FIFO STATUS Transmit FIFO FULL */
+#define UFSTAT_EIF		0x80	/* UART FIFO STATUS Error in FIFO */
+
+
+/* *********** */
+/* SIO 0 and 1 */
+/* *********** */
+
+#define S3C3410X_ITVCNT0  	(S3C3410X_BASE+0x6000) /* SIO 0 interval counter */
+#define S3C3410X_SBRDR0   	(S3C3410X_BASE+0x6001) /* SIO 0 baud rate prescaler */
+#define S3C3410X_SIODAT0  	(S3C3410X_BASE+0x6002) /* SIO 0 data */
+#define S3C3410X_SIOCON0  	(S3C3410X_BASE+0x6003) /* SIO 0 control */
+
+#define S3C3410X_ITVCNT1  	(S3C3410X_BASE+0x7000) /* SIO 1 interval counter */
+#define S3C3410X_SBRDR1   	(S3C3410X_BASE+0x7001) /* SIO 1 baud rate prescaler */
+#define S3C3410X_SIODAT1  	(S3C3410X_BASE+0x7002) /* SIO 1 data */
+#define S3C3410X_SIOCON1  	(S3C3410X_BASE+0x7003) /* SIO 1 control */
+
+/* ****************************** */
+/* Interrupt Controller Registers */
+/* ****************************** */
+
+#define S3C3410X_INTMOD		(S3C3410X_BASE+0xC000) /* Interrupt mode */
+#define S3C3410X_INTPND		(S3C3410X_BASE+0xC004) /* Interrupt pending */
+#define S3C3410X_INTMSK		(S3C3410X_BASE+0xC008) /* Interrupt mask */
+
+#define S3C3410X_INTPRI0	(S3C3410X_BASE+0xC00C) /* Interrupt priority 0 */
+#define S3C3410X_INTPRI1	(S3C3410X_BASE+0xC010) /* Interrupt priority 1 */
+#define S3C3410X_INTPRI2	(S3C3410X_BASE+0xC014) /* Interrupt priority 2 */
+#define S3C3410X_INTPRI3	(S3C3410X_BASE+0xC018) /* Interrupt priority 3 */
+#define S3C3410X_INTPRI4	(S3C3410X_BASE+0xC01C) /* Interrupt priority 4 */
+#define S3C3410X_INTPRI5	(S3C3410X_BASE+0xC020) /* Interrupt priority 5 */
+#define S3C3410X_INTPRI6	(S3C3410X_BASE+0xC024) /* Interrupt priority 6 */
+#define S3C3410X_INTPRI7	(S3C3410X_BASE+0xC028) /* Interrupt priority 7 */
+
+/* *** */
+/* ADC */
+/* *** */
+
+#define S3C3410X_ADCCON   	(S3C3410X_BASE+0x8002) /* A/D Converter control */
+#define S3C3410X_ADCDAT   	(S3C3410X_BASE+0x8006) /* A/D Converter data */
+
+/* *********** */
+/* Basic Timer */
+/* *********** */
+
+#define S3C3410X_BTCON    	(S3C3410X_BASE+0xA002)	/* Basic Timer control */
+#define S3C3410X_BTCON_WDTC     0x00000001		/* Watchdog Timer Clear */
+#define S3C3410X_BTCON_BTC      0x00000002		/* Basic Timer Clear */
+#define S3C3410X_BTCON_CS_13	0x00000000		/* Watchdog Clock source Fin / 2^13 */
+#define S3C3410X_BTCON_CS_12	0x00000040		/* Watchdog Clock source Fin / 2^12 */
+#define S3C3410X_BTCON_CS_11	0x00000080		/* Watchdog Clock source Fin / 2^11 */
+#define S3C3410X_BTCON_CS_9	0x000000C0		/* Watchdog Clock source Fin / 2^9 */
+
+/* When this value is written into BTCON it will disable the Timer. Any other value will enable it. */
+#define S3C3410X_BTCON_WDTD     0x0000A500		/* Watchdog Timer Disable */
+#define S3C3410X_BTCON_WDTE     0x0000FF00		/* Watchdog Timer Enable */
+
+#define S3C3410X_BTCNT   	(S3C3410X_BASE+0xA007)	/* Basic Timer count */
+
+/* ***************** */
+/* I2C Bus Registers */
+/* ***************** */
+
+#define S3C3410X_IICCON   	(S3C3410X_BASE+0xE000) /* IIC-bus control */
+#define S3C3410X_IICSTAT   	(S3C3410X_BASE+0xE001) /* IIC-bus status */
+#define S3C3410X_IICDS    	(S3C3410X_BASE+0xE002) /* IIC-bus tx/rx data shift reg. */
+#define S3C3410X_IICADD   	(S3C3410X_BASE+0xE003) /* IIC-bus tx/rx address */
+#define S3C3410X_IICPC    	(S3C3410X_BASE+0xE004) /* IIC-bus Prescaler */
+#define S3C3410X_IICPCNT  	(S3C3410X_BASE+0xE005) /* IIC-bus Prescaler counter */
+
+/* *********************** */
+/* System control register */
+/* *********************** */
+
+#define S3C3410X_SYSCON   	(S3C3410X_BASE+0xD003) /* System control */
+
+#define S3C3410X_SYSCON_STOP      0x00000001 /* STOP-Mode */
+#define S3C3410X_SYSCON_IDLE      0x00000002 /* IDLE-Mode */
+#define S3C3410X_SYSCON_DMAIDLE   0x00000004 /* DMA-IDLE-Mode */
+#define S3C3410X_SYSCON_MCLK16    0x00000000 /* system clock = MCLOCK / 16 */
+#define S3C3410X_SYSCON_MCLK2     0x00000010 /* system clock = MCLOCK / 2 */
+#define S3C3410X_SYSCON_MCLK1024  0x00000020 /* system clock = MCLOCK / 1024 */
+#define S3C3410X_SYSCON_MCLK8     0x00000008 /* system clock = MCLOCK / 8 */
+#define S3C3410X_SYSCON_MCLK      0x00000018 /* system clock = MCLOCK */
+#define S3C3410X_SYSCON_GIE       0x00000040 /* Global Interrupt Enable (set when enabled !!) */
+
+/* ************** */
+/* Realtime Clock */
+/* ************** */
+
+#define S3C3410X_RTCCON   	(S3C3410X_BASE+0xA013) /* RTC control */
+#define S3C3410X_RTCALM   	(S3C3410X_BASE+0xA012) /* RTC alarm control */
+#define S3C3410X_ALMSEC   	(S3C3410X_BASE+0xA033) /* Alarm second */
+#define S3C3410X_ALMMIN    	(S3C3410X_BASE+0xA032) /* Alarm minute */
+#define S3C3410X_ALMHOUR    	(S3C3410X_BASE+0xA031) /* Alarm hour */
+#define S3C3410X_ALMDAY   	(S3C3410X_BASE+0xA037) /* Alarm day */
+#define S3C3410X_ALMMON   	(S3C3410X_BASE+0xA036) /* Alarm month */
+#define S3C3410X_ALMYEAR   	(S3C3410X_BASE+0xA035) /* Alarm year */
+#define S3C3410X_BCDSEC   	(S3C3410X_BASE+0xA023) /* BCD second */
+#define S3C3410X_BCDMIN   	(S3C3410X_BASE+0xA022) /* BCD minute */
+#define S3C3410X_BCDHOUR   	(S3C3410X_BASE+0xA021) /* BCD hour */
+#define S3C3410X_BCDDAY   	(S3C3410X_BASE+0xA027) /* BCD day */
+#define S3C3410X_BCDDATE   	(S3C3410X_BASE+0xA020) /* BCD date */
+#define S3C3410X_BCDMON   	(S3C3410X_BASE+0xA026) /* BCD month */
+#define S3C3410X_BCDYEAR   	(S3C3410X_BASE+0xA025) /* BCD year */
+
+#define S3C3410X_RINTPND   	(S3C3410X_BASE+0xA010) /* RTC time interrupt pending */
+#define S3C3410X_RINTCON   	(S3C3410X_BASE+0xA011) /* RTC time interrupt control */
+
+
+#endif /* __ASM_ARCH_S3C3410_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/serial.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/serial.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/serial.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,16 @@
+/*
+ * linux/include/asm/arch-S3C3410/serial.h
+ *
+ * (C) 2003 sympat GmbH
+ * by Thomas Eschenbacher <thomas.eschenbacher@sympat.de>
+ *
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+/* 
+ * nothing needed here, all definitions are in 
+ * drivers/char/serial_s3c3410.h
+ */
+
+#endif /* __ASM_ARCH_SERIAL_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/shmparam.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/shmparam.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/shmparam.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,8 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C3410/shmparam.h
+ *
+ * (just a placeholder, not needed in our machine)
+ *
+ * 2003 Thomas Eschenbacher <thomas.eschenbacher@gmx.de>
+ *
+ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/system.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C3410/system.h
+ *
+ * (just a placeholder, not needed in our machine)
+ *
+ * 2003 Thomas Eschenbacher <thomas.eschenbacher@gmx.de>
+ *
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H_
+#define __ASM_ARCH_SYSTEM_H_
+
+static inline void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter)
+		cpu_do_idle(IDLE_WAIT_SLOW);
+}
+
+extern inline void arch_reset(char mode)
+{
+	/* @todo: reset the hardware in some way */
+}
+
+#endif /* __ASM_ARCH_SYSTEM_H_ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/time.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/time.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,60 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C3410/time.h
+ *
+ * 2003 Thomas Eschenbacher <thomas.eschenbacher@gmx.de>
+ *
+ * Setup for 16 bit timer 0, used as system timer.
+ *
+ */
+
+#ifndef __ASM_ARCH_TIME_H__
+#define __ASM_ARCH_TIME_H__
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/timex.h>
+
+extern struct irqaction timer_irq;
+
+extern unsigned long s3c3410_gettimeoffset(void);
+extern void s3c3410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+#define S3C3410X_TIMER0_PRESCALER 100
+
+extern __inline__ void setup_timer (void)
+{
+	u_int8_t tmod;
+	u_int16_t period;
+	
+	/*
+	 * disable and clear timer 0, set to
+	 * internal clock and interval mode
+	 */
+	tmod = S3C3410X_T16_OMS_INTRV | S3C3410X_T16_CL;
+	outb(tmod, S3C3410X_TCON0);
+
+	/* initialize the timer period and prescaler */
+	period = (CONFIG_ARM_CLK/S3C3410X_TIMER0_PRESCALER)/HZ;
+	outw(period, S3C3410X_TDAT0);
+	outb(S3C3410X_TIMER0_PRESCALER-1, S3C3410X_TPRE0);
+
+	/*
+	 * @todo do those really need to be function pointers ?
+	 */
+	gettimeoffset     = s3c3410_gettimeoffset;
+	timer_irq.handler = s3c3410_timer_interrupt;
+
+	/* set up the interrupt vevtor for timer 0 match */
+	setup_arm_irq(S3C3410X_INTERRUPT_TMC0, &timer_irq);
+	
+	/* enable the timer IRQ */
+	s3c3410_unmask_irq(S3C3410X_INTERRUPT_TMC0);
+
+	/* let timer 0 run... */
+	tmod |= S3C3410X_T16_TEN;
+	tmod &= ~S3C3410X_T16_CL;
+	outb(tmod, S3C3410X_TCON0);
+}
+
+#endif /* __ASM_ARCH_TIME_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C3410/timex.h
+ *
+ * (just a placeholder, not needed in our machine)
+ *
+ * 2003 Thomas Eschenbacher <thomas.eschenbacher@gmx.de>
+ *
+ */
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C3410/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C3410/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C3410/vmalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ *  uclinux/include/asm-armnommu/arch-S3C3410/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/a.out.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/a.out.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/a.out.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,16 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C44B0X/a.out.h
+ *
+ * (just a placeholder, not needed in our machine)
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ */
+#ifndef __ASM_ARCH_A_OUT_H
+#define __ASM_ARCH_A_OUT_H
+
+#ifdef __KERNEL__
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,14 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C44B0X/dma.h:
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_ADDRESS   0x03000000
+#define MAX_DMA_CHANNELS  2
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,23 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C44B0X/hardware.h
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ * Hardware definitions of MBA44 board, currently only
+ * the CPUs registers and definitions are included from
+ * s3c44b0x.h.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <linux/config.h>
+#include <asm/arch/s3c44b0x.h>
+
+#ifndef __ASSEMBLER__
+
+#define HARD_RESET_NOW()  { arch_hard_reset(); }
+
+#endif /* ! __ASSEMBLER__ */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/io.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,79 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C44B0X/io.h
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ *  02-19-2001  gjm     Leveraged for armnommu/dsc21
+ *  08-13-2003  the     copied to S3C44B0X arch
+ *
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ * --gmcnutt
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * These functions are needed for mtd/maps/physmap.c
+ * (copied from include/asm/arch-atmel/io.h)
+ * --the
+ */
+#ifndef memset_io
+#define memset_io(a,b,c)                _memset_io((a),(b),(c))
+#endif
+#ifndef memcpy_fromio
+#define memcpy_fromio(a,b,c)            _memcpy_fromio((a),(b),(c))
+#endif
+#ifndef memcpy_toio
+#define memcpy_toio(a,b,c)              _memcpy_toio((a),(b),(c))
+#endif
+
+/* maybe someone needs this in far future... */
+#define PCIO_BASE 0
+
+/*
+ * These macros were copied from arch/armnommu/io.h and are used instead
+ * of the definitions found there, because we want to do 16/32 bit i/o
+ * without byte swapping.
+ * --the
+ */
+#define __arch_getw(a)    (*(volatile unsigned short *)(a))
+#define __arch_putw(v,a)  (*(volatile unsigned short *)(a) = (v))
+
+#ifndef __iob
+  #define __iob(a) __io(a)
+#endif
+
+#define outb(v,p)	__raw_writeb(v, p)
+#define outw(v,p)	__raw_writew(v, p)
+#define outl(v,p)	__raw_writel(v, p)
+
+#define inb(p)		({ unsigned int __v = __raw_readb(p); __v; })
+#define inw(p)		({ unsigned int __v = __raw_readw(p); __v; })
+#define inl(p)		({ unsigned int __v = __raw_readl(p); __v; })
+
+#define outsb(p,d,l)	__raw_writesb(p, d, l)
+#define outsw(p,d,l)	__raw_writesw(p, d, l)
+#define outsl(p,d,l)	__raw_writesl(p, d, l)
+
+#define insb(p,d,l)	__raw_readsb(p, d, l)
+#define insw(p,d,l)	__raw_readsw(p, d, l)
+#define insl(p,d,l)	__raw_readsl(p, d, l)
+
+/*
+ * Defining these two gives us ioremap for free. See asm/io.h.
+ * --gmcnutt
+ */
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+#endif /* __ASM_ARM_ARCH_IO_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,53 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C44B0X/irq.h
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ */
+
+#ifndef __ASM_ARCH_IRQ_H__
+#define __ASM_ARCH_IRQ_H__
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irqs.h>
+
+extern void s3c44b0x_mask_irq(unsigned int irq);
+extern void s3c44b0x_unmask_irq(unsigned int irq);
+extern void s3c44b0x_mask_ack_irq(unsigned int irq);
+extern void s3c44b0x_clear_pb(unsigned int irq);
+
+static __inline__ unsigned int fixup_irq (unsigned int irq)
+{
+	s3c44b0x_clear_pb(irq);
+	return (irq);
+}
+
+static __inline__ void irq_init_irq(void)
+{
+	int irq;
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= s3c44b0x_mask_ack_irq;
+		irq_desc[irq].mask	= s3c44b0x_mask_irq;
+		irq_desc[irq].unmask	= s3c44b0x_unmask_irq;
+
+		/* @TODO initialize interrupt priorities */
+	}
+
+
+	/* mask and disable all further interrupts */
+	/* but globaly enable the INT-controller */
+	outl(0x03FFFFFF, S3C44B0X_INTMSK);
+
+	/* set all to IRQ mode, not FIQ */
+	outl(0x00000000, S3C44B0X_INTMOD);
+
+	/* clear all pending bits */
+	outl(0x07FFFFFF, S3C44B0X_I_ISPC);
+}
+
+
+#endif /* __ASM_ARCH_IRQ_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/irqs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,44 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C44B0X/irqs.h
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ * All IRQ numbers of the S3C44B0X CPU.
+ *
+ */
+
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+
+#define NR_IRQS		26
+
+#define S3C44B0X_INTERRUPT_EINT0      25      /* External int. 0 */
+#define S3C44B0X_INTERRUPT_EINT1      24      /* External int. 1 */
+#define S3C44B0X_INTERRUPT_EINT2      23      /* External int. 2 */
+#define S3C44B0X_INTERRUPT_EINT3      22      /* External int. 3 */
+#define S3C44B0X_INTERRUPT_EINT4567   21      /* External int. 4,5,6 and 7 */
+#define S3C44B0X_INTERRUPT_TICK       20      /* Clock Tick int. */
+#define S3C44B0X_INTERRUPT_ZDMA0      19      /* ZDMA 0 */
+#define S3C44B0X_INTERRUPT_ZDMA1      18      /* ZDMA 1 */
+#define S3C44B0X_INTERRUPT_BDMA0      17      /* BDMA 0 */
+#define S3C44B0X_INTERRUPT_BDMA1      16      /* BDMA 1 */
+#define S3C44B0X_INTERRUPT_WDT        15      /* Watchdog timer */
+#define S3C44B0X_INTERRUPT_UERR       14      /* UART error */
+#define S3C44B0X_INTERRUPT_TIMER0     13      /* Timer 0 zero-crossing */
+#define S3C44B0X_INTERRUPT_TIMER1     12      /* Timer 1 zero-crossing */
+#define S3C44B0X_INTERRUPT_TIMER2     11      /* Timer 2 zero-crossing */
+#define S3C44B0X_INTERRUPT_TIMER3     10      /* Timer 3 zero-crossing */
+#define S3C44B0X_INTERRUPT_TIMER4      9      /* Timer 4 zero-crossing */
+#define S3C44B0X_INTERRUPT_TIMER5      8      /* Timer 5 zero-crossing */
+#define S3C44B0X_INTERRUPT_URX0        7      /* UART0 receive */
+#define S3C44B0X_INTERRUPT_URX1        6      /* UART1 receive */
+#define S3C44B0X_INTERRUPT_IIC         5      /* IIC */
+#define S3C44B0X_INTERRUPT_SIO         4      /* SIO */
+#define S3C44B0X_INTERRUPT_UTX0        3      /* UART0 transmit */
+#define S3C44B0X_INTERRUPT_UTX1        2      /* UART1 transmit */
+#define S3C44B0X_INTERRUPT_RTCT        1      /* RTC time */
+#define S3C44B0X_INTERRUPT_ADC         0      /* ADC interrupt */
+
+#define S3C44B0X_INTERRUPT_RTC       S3C44B0X_INTERRUPT_TIMER5      /* system timer(5) */
+
+#endif /* __ASM_ARCH_IRQS_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/keyboard.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/keyboard.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/keyboard.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C44B0X/keyboard.h
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  (Dummy) Keyboard driver definitions for ARM
+ */
+#ifndef __ASM_ARM_ARCH_S3C44B0X_KEYBOARD_H
+#define __ASM_ARM_ARCH_S3C44B0X_KEYBOARD_H
+
+/*
+ * Required by drivers/char/keyboard.c. I took these from arch-arc.
+ * --gmcnutt
+ */
+#define kbd_setkeycode(sc,kc) (-EINVAL)
+#define kbd_getkeycode(sc) (-EINVAL)
+#define kbd_translate(sc,kcp,rm) ({ *(kcp) = (sc); 1; })
+#define kbd_unexpected_up(kc) (0200)
+#define kbd_leds(leds)
+#define kbd_init_hw()
+#define kbd_enable_irq() /* what irq? ;) --gmcnutt */
+#define kbd_disable_irq()
+
+#endif /* __ASM_ARM_ARCH_S3C44B0X_KEYBOARD_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C44B0X/memory.h
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define TASK_SIZE	(0x01a00000UL)
+#define TASK_SIZE_26	TASK_SIZE
+
+#define PHYS_OFFSET     (DRAM_BASE + 2*1024*1024)
+#define PAGE_OFFSET 	(PHYS_OFFSET)
+#define END_MEM		(DRAM_BASE + DRAM_SIZE - 2*1024*1024)
+
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((unsigned long) (vpage))
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((void *) (ppage))
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(vpage) ((unsigned long) (vpage))
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(ppage) ((void *) (ppage))
+
+#endif /* __ASM_ARCH_MEMORY_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/mmu.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/mmu.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/mmu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/mmu.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,22 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C44B0X/mmu.h
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) vpage
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ppage
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(vpage) vpage
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(ppage) ppage
+
+#define __flush_entry_to_
+
+#endif /* __ASM_ARCH_MMU_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/param.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,14 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C44B0X/a.out.h
+ *
+ * (just a placeholder, not needed in our machine)
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ */
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/pcmcia.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/pcmcia.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/pcmcia.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/pcmcia.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,11 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C44B0X/pcmcia.h
+ *
+ * (just a placeholder, not needed in our machine)
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ */
+#ifdef CONFIG_REVISIT
+#error Do we need PCMCIA support?
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/processor.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/processor.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/processor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,19 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C44B0X/processor.h
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ */
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+#define EISA_bus 0
+#define EISA_bus__is_a_macro
+#define MCA_bus 0
+#define MCA_bus__is_a_macro
+
+#define TASK_SIZE (0x01a00000UL)
+
+#define INIT_MMAP { \
+  &init_mm, 0, 0x02000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC \
+}
+
+#endif /* __ASM_ARCH_PROCESSOR_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/s3c44b0x.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/s3c44b0x.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/s3c44b0x.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/s3c44b0x.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,681 @@
+#ifndef _S3C44B0X_H_
+#define _S3C44B0X_H_
+
+/**
+ * register definitions for SAMSUNG S3C44B0X
+ *
+ * Copyright (C) 2003 Christian Schulte <schulte@sympat.de>
+ *
+ */
+ 
+/*******************/
+/*** CPU WRAPPER ***/
+/*******************/
+
+#define S3C44B0X_SYSCFG			0x01c00000
+#define S3C44B0X_NCACHBE0		0x01c00004 /* configuration of non-cachable areas */
+#define S3C44B0X_NCACHBE1		0x01c00008 /* configuration of non-cachable areas */
+#define S3C44B0X_SBUSCON		0x01c40000 /* bus configuration */
+
+/* SYSCFG */
+#define S3C44B0X_SYSCFG_DA		0x00000020 /* Data Abort disable */
+#define S3C44B0X_SYSCFG_RSE		0x00000010 /* Read Stall Option enable */
+#define S3C44B0X_SYSCFG_WE		0x00000008 /* Write Buffer enable */
+
+#define S3C44B0X_SYSCFG_CM_NONE		0x00000000 /* Cache Mode */
+#define S3C44B0X_SYSCFG_CM_4K		0x00000002
+#define S3C44B0X_SYSCFG_CM_8K		0x00000006
+
+#define S3C44B0X_SYSCFG_SE		0x00000001 /* Stall Option enable */
+
+/* SBUSCON */
+#define S3C44B0X_SBUSCON_FIX		0x80000000 /* use the fixed configuration that follows (instead of round-robin) */
+#define S3C44B0X_SBUSCON_S_LCD_DMA_1	0x00000000 /* read the bus priority of LCD-DMA */
+#define S3C44B0X_SBUSCON_S_LCD_DMA_2	0x00004000
+#define S3C44B0X_SBUSCON_S_LCD_DMA_3	0x00008000
+#define S3C44B0X_SBUSCON_S_LCD_DMA_4	0x0000c000
+#define S3C44B0X_SBUSCON_S_ZDMA_1	0x00000000 /* read the bus priority of Z DMA */
+#define S3C44B0X_SBUSCON_S_ZDMA_2	0x00001000
+#define S3C44B0X_SBUSCON_S_ZDMA_3	0x00002000
+#define S3C44B0X_SBUSCON_S_ZDMA_4	0x00003000
+#define S3C44B0X_SBUSCON_S_BDMA_1	0x00000000 /* read the bus priority of B DMA */
+#define S3C44B0X_SBUSCON_S_BDMA_2	0x00000400
+#define S3C44B0X_SBUSCON_S_BDMA_3	0x00000800
+#define S3C44B0X_SBUSCON_S_BDMA_4	0x00000c00
+#define S3C44B0X_SBUSCON_S_BREQ_1	0x00000000 /* read the bus priority of external BREAK REQUEST */
+#define S3C44B0X_SBUSCON_S_BREQ_2	0x00000100
+#define S3C44B0X_SBUSCON_S_BREQ_3	0x00000200
+#define S3C44B0X_SBUSCON_S_BREQ_4	0x00000300
+
+#define S3C44B0X_SBUSCON_LCD_DMA_1	0x00000000 /* set the bus priority of LCD-DMA */
+#define S3C44B0X_SBUSCON_LCD_DMA_2	0x00000040
+#define S3C44B0X_SBUSCON_LCD_DMA_3	0x00000080
+#define S3C44B0X_SBUSCON_LCD_DMA_4	0x000000c0
+#define S3C44B0X_SBUSCON_ZDMA_1		0x00000000 /* set the bus priority of Z DMA */
+#define S3C44B0X_SBUSCON_ZDMA_2		0x00000010
+#define S3C44B0X_SBUSCON_ZDMA_3		0x00000020
+#define S3C44B0X_SBUSCON_ZDMA_4		0x00000030
+#define S3C44B0X_SBUSCON_BDMA_1		0x00000000 /* set the bus priority of B DMA */
+#define S3C44B0X_SBUSCON_BDMA_2		0x00000004
+#define S3C44B0X_SBUSCON_BDMA_3		0x00000008
+#define S3C44B0X_SBUSCON_BDMA_4		0x0000000c
+#define S3C44B0X_SBUSCON_BREQ_1		0x00000000 /* set the bus priority of external BREAK REQUEST */
+#define S3C44B0X_SBUSCON_BREQ_2		0x00000001
+#define S3C44B0X_SBUSCON_BREQ_3		0x00000002
+#define S3C44B0X_SBUSCON_BREQ_4		0x00000003
+
+  /*************************/
+  /*** MEMORY CONTROLLER ***/
+  /*************************/
+
+#define S3C44B0X_BWSCON			0x01c80000 /* Bank size, width and type of memory */
+#define S3C44B0X_BANKCON0		0x01c80004 /* timing and page modes */
+#define S3C44B0X_BANKCON1		0x01c80008
+#define S3C44B0X_BANKCON2		0x01c8000c
+#define S3C44B0X_BANKCON3		0x01c80010
+#define S3C44B0X_BANKCON4		0x01c80014
+#define S3C44B0X_BANKCON5		0x01c80018
+#define S3C44B0X_BANKCON6		0x01c8001c
+#define S3C44B0X_BANKCON7		0x01c80020
+#define S3C44B0X_REFRESH		0x01c80024 /* refresh timing */
+#define S3C44B0X_BANKSIZE		0x01c80028 /* bank sizes 2,4,8,16,32 MB */
+#define S3C44B0X_MRSRB6			0x01c8002c /* burst settings, CAS latency */
+#define S3C44B0X_MRSRB7			0x01c80030
+
+/* BWSCON */
+#define S3C44B0X_BWSCON_ST7		0x80000000 /* use UB/LB addressing */
+#define S3C44B0X_BWSCON_WS7		0x40000000 /* waitstate enable */
+#define S3C44B0X_BWSCON_DW7_8		0x00000000 /* data bus width 8bit */
+#define S3C44B0X_BWSCON_DW7_16		0x10000000 /* data bus width 16bit */
+#define S3C44B0X_BWSCON_DW7_32		0x20000000 /* data bus width 32bit */
+
+#define S3C44B0X_BWSCON_ST6		0x08000000 /* use UB/LB addressing */
+#define S3C44B0X_BWSCON_WS6		0x04000000 /* waitstate enable */
+#define S3C44B0X_BWSCON_DW6_8		0x00000000 /* data bus width 8bit */
+#define S3C44B0X_BWSCON_DW6_16		0x01000000 /* data bus width 16bit */
+#define S3C44B0X_BWSCON_DW6_32		0x02000000 /* data bus width 32bit */
+
+#define S3C44B0X_BWSCON_ST5		0x00800000 /* use UB/LB addressing */
+#define S3C44B0X_BWSCON_WS5		0x00400000 /* waitstate enable */
+#define S3C44B0X_BWSCON_DW5_8		0x00000000 /* data bus width 8bit */
+#define S3C44B0X_BWSCON_DW5_16		0x00100000 /* data bus width 16bit */
+#define S3C44B0X_BWSCON_DW5_32		0x00200000 /* data bus width 32bit */
+
+#define S3C44B0X_BWSCON_ST4		0x00080000 /* use UB/LB addressing */
+#define S3C44B0X_BWSCON_WS4		0x00040000 /* waitstate enable */
+#define S3C44B0X_BWSCON_DW4_8		0x00000000 /* data bus width 8bit */
+#define S3C44B0X_BWSCON_DW4_16		0x00010000 /* data bus width 16bit */
+#define S3C44B0X_BWSCON_DW4_32		0x00020000 /* data bus width 32bit */
+
+#define S3C44B0X_BWSCON_ST3		0x00008000 /* use UB/LB addressing */
+#define S3C44B0X_BWSCON_WS3		0x00004000 /* waitstate enable */
+#define S3C44B0X_BWSCON_DW3_8		0x00000000 /* data bus width 8bit */
+#define S3C44B0X_BWSCON_DW3_16		0x00001000 /* data bus width 16bit */
+#define S3C44B0X_BWSCON_DW3_32		0x00002000 /* data bus width 32bit */
+
+#define S3C44B0X_BWSCON_ST2		0x00000800 /* use UB/LB addressing */
+#define S3C44B0X_BWSCON_WS2		0x00000400 /* waitstate enable */
+#define S3C44B0X_BWSCON_DW2_8		0x00000000 /* data bus width 8bit */
+#define S3C44B0X_BWSCON_DW2_16		0x00000100 /* data bus width 16bit */
+#define S3C44B0X_BWSCON_DW2_32		0x00000200 /* data bus width 32bit */
+
+#define S3C44B0X_BWSCON_ST1		0x00000080 /* use UB/LB addressing */
+#define S3C44B0X_BWSCON_WS1		0x00000040 /* waitstate enable */
+#define S3C44B0X_BWSCON_DW1_8		0x00000000 /* data bus width 8bit */
+#define S3C44B0X_BWSCON_DW1_16		0x00000010 /* data bus width 16bit */
+#define S3C44B0X_BWSCON_DW1_32		0x00000020 /* data bus width 32bit */
+
+#define S3C44B0X_BWSCON_DW0_8		0x00000000 /* data bus width 8bit */
+#define S3C44B0X_BWSCON_DW0_16		0x00000002 /* data bus width 16bit */
+#define S3C44B0X_BWSCON_DW0_32		0x00000004 /* data bus width 32bit */
+
+#define S3C44B0X_BWSCON_ENDIAN_BIG	0x00000001 /* read-only, samples the endianess input pin */
+
+/* BANKCON */
+#define S3C44B0X_BANKCON_TACS_0		0x00000000 /* time, adress setup to CS (in clocks) */
+#define S3C44B0X_BANKCON_TACS_1		0x00002000
+#define S3C44B0X_BANKCON_TACS_2		0x00004000
+#define S3C44B0X_BANKCON_TACS_4		0x00006000
+
+#define S3C44B0X_BANKCON_TCOS_0		0x00000000 /* time, CS to nOE (in clocks) */
+#define S3C44B0X_BANKCON_TCOS_1		0x00000800
+#define S3C44B0X_BANKCON_TCOS_2		0x00001000
+#define S3C44B0X_BANKCON_TCOS_4		0x00001800
+
+#define S3C44B0X_BANKCON_TACC_1		0x00000000 /* access cycle in clocks (in clocks) */
+#define S3C44B0X_BANKCON_TACC_2		0x00000100
+#define S3C44B0X_BANKCON_TACC_3		0x00000200
+#define S3C44B0X_BANKCON_TACC_4		0x00000300
+#define S3C44B0X_BANKCON_TACC_6		0x00000400
+#define S3C44B0X_BANKCON_TACC_8		0x00000500
+#define S3C44B0X_BANKCON_TACC_10	0x00000600
+#define S3C44B0X_BANKCON_TACC_14	0x00000700
+
+#define S3C44B0X_BANKCON_TOCH_0		0x00000000 /* time, CS hold on nOE (in clocks) */
+#define S3C44B0X_BANKCON_TOCH_1		0x00000040
+#define S3C44B0X_BANKCON_TOCH_2		0x00000080
+#define S3C44B0X_BANKCON_TOCH_4		0x000000c0
+
+#define S3C44B0X_BANKCON_TCAH_0		0x00000000 /* address hold on after CS (in clocks) */
+#define S3C44B0X_BANKCON_TCAH_1		0x00000010
+#define S3C44B0X_BANKCON_TCAH_2		0x00000020
+#define S3C44B0X_BANKCON_TCAH_4		0x00000030
+
+#define S3C44B0X_BANKCON_TPAC_2		0x00000000 /* page mode access cycle (in clocks) */
+#define S3C44B0X_BANKCON_TPAC_3		0x00000004
+#define S3C44B0X_BANKCON_TPAC_4		0x00000008
+#define S3C44B0X_BANKCON_TPAC_6		0x0000000c
+
+#define S3C44B0X_BANKCON_PMC_1		0x00000000 /* page mode config (in datawords) */
+#define S3C44B0X_BANKCON_PMC_4		0x00000001
+#define S3C44B0X_BANKCON_PMC_8		0x00000002
+#define S3C44B0X_BANKCON_PMC_16		0x00000003
+
+#define S3C44B0X_BANKCON_MT_SRAM	0x00000000 /* memory type selection */
+#define S3C44B0X_BANKCON_MT_DRAM	0x00004000
+#define S3C44B0X_BANKCON_MT_EDO		0x00008000
+#define S3C44B0X_BANKCON_MT_SDRAM	0x00018000
+
+/* only for FP-DRAM or EDO-DRAM */
+#define S3C44B0X_BANKCON_TRCD_1		0x00000000 /* RAS to CAS delay */
+#define S3C44B0X_BANKCON_TRCD_2		0x00000010
+#define S3C44B0X_BANKCON_TRCD_3		0x00000020
+#define S3C44B0X_BANKCON_TRCD_4		0x00000030
+
+#define S3C44B0X_BANKCON_TCAS_1		0x00000000 /* CAS pulse width (in clocks) */
+#define S3C44B0X_BANKCON_TCAS_2		0x00000008
+
+#define S3C44B0X_BANKCON_TCP_1		0x00000000 /* CAS precharge (in clocks) */
+#define S3C44B0X_BANKCON_TCP_2		0x00000004
+
+#define S3C44B0X_BANKCON_CAN_8		0x00000000 /* column address number (in bits) */
+#define S3C44B0X_BANKCON_CAN_9		0x00000001
+#define S3C44B0X_BANKCON_CAN_10		0x00000002
+#define S3C44B0X_BANKCON_CAN_11		0x00000003
+
+/* only for SDRAM */
+#define S3C44B0X_BANKCON_SDRAM_TRCD_2	0x00000000 /* RAS to CAS delay */
+#define S3C44B0X_BANKCON_SDRAM_TRCD_3	0x00000004
+#define S3C44B0X_BANKCON_SDRAM_TRCD_4	0x00000008
+
+#define S3C44B0X_BANKCON_SCAN_8		0x00000000 /* column address number (in bits) */
+#define S3C44B0X_BANKCON_SCAN_9		0x00000001
+#define S3C44B0X_BANKCON_SCAN_10	0x00000002
+
+
+/* REFRESH */
+#define S3C44B0X_REFRESH_REFEN		0x00800000
+#define S3C44B0X_REFRESH_TREFMD		0x00400000
+
+
+#define S3C44B0X_REFRESH_TRP_1_5	0x00000000 /* for DRAM */
+#define S3C44B0X_REFRESH_TRP_2_5	0x00000000
+#define S3C44B0X_REFRESH_TRP_3_5	0x00000000
+#define S3C44B0X_REFRESH_TRP_4_5	0x00000000
+#define S3C44B0X_REFRESH_TRP_2		0x00000000 /* for SDRAM */
+#define S3C44B0X_REFRESH_TRP_3		0x00000000
+#define S3C44B0X_REFRESH_TRP_4		0x00000000
+#define S3C44B0X_REFRESH_TRP_NONE	0x00000000
+
+#define S3C44B0X_REFRESH_TRC_4		0x00000000 /* SDRAM RC minimum time */
+#define S3C44B0X_REFRESH_TRC_5		0x00040000
+#define S3C44B0X_REFRESH_TRC_6		0x00080000
+#define S3C44B0X_REFRESH_TRC_7		0x000c0000
+
+#define S3C44B0X_REFRESH_TCHR_1		0x00000000 /* CAS Hold Time (DRAM) */
+#define S3C44B0X_REFRESH_TCHR_2		0x00010000
+#define S3C44B0X_REFRESH_TCHR_3		0x00020000
+#define S3C44B0X_REFRESH_TCHR_4		0x00030000
+
+#define S3C44B0X_REFRESH_COUNTER	0x000003FF /* mask for the refresh counter (bit 0-10) */
+
+/* BANKSIZE */
+#define S3C44B0X_BANKSIZE_SCLKEN	0x00000010
+#define S3C44B0X_BANKSIZE_BK76MAP_2	0x00000004
+#define S3C44B0X_BANKSIZE_BK76MAP_4	0x00000005
+#define S3C44B0X_BANKSIZE_BK76MAP_8	0x00000006
+#define S3C44B0X_BANKSIZE_BK76MAP_16	0x00000007
+#define S3C44B0X_BANKSIZE_BK76MAP_32	0x00000000
+
+/* MRSRB */
+#define S3C44B0X_MRSRB_WBL		0x00000200
+#define S3C44B0X_MRSRB_CL_1		0x00000000
+#define S3C44B0X_MRSRB_CL_2		0x00000020
+#define S3C44B0X_MRSRB_CL_3		0x00000030
+#define S3C44B0X_MRSRB_BT_SEQ		0x00000000
+#define S3C44B0X_MRSRB_BT_NONSEQ	0x00000008
+#define S3C44B0X_MRSRB_BL_1		0x00000000
+
+  /************/
+  /*** UART ***/
+  /************/
+  
+#define S3C44B0X_ULCON0			0x01d00000
+#define S3C44B0X_UCON0			0x01d00004
+#define S3C44B0X_UFCON0			0x01d00008
+#define S3C44B0X_UMCON0			0x01d0000c
+#define S3C44B0X_UTRSTAT0		0x01d00010
+#define S3C44B0X_UERSTAT0		0x01d00014
+#define S3C44B0X_UFSTAT0		0x01d00018
+#define S3C44B0X_UMSTAT0		0x01d0001c
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define S3C44B0X_UTXH0			0x01d00023
+#define S3C44B0X_URXH0			0x01d00027
+#else
+#define S3C44B0X_UTXH0			0x01d00020
+#define S3C44B0X_URXH0			0x01d00024
+#endif
+
+#define S3C44B0X_UBRDIV0		0x01d00028
+
+#define S3C44B0X_ULCON1			0x01d04000
+#define S3C44B0X_UCON1			0x01d04004
+#define S3C44B0X_UFCON1			0x01d04008
+#define S3C44B0X_UMCON1			0x01d0400c
+#define S3C44B0X_UTRSTAT1		0x01d04010
+#define S3C44B0X_UERSTAT1		0x01d04014
+#define S3C44B0X_UFSTAT1		0x01d04018
+#define S3C44B0X_UMSTAT1		0x01d0401c
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define S3C44B0X_UTXH1			0x01d04023
+#define S3C44B0X_URXH1			0x01d04027
+#else
+#define S3C44B0X_UTXH1			0x01d04020
+#define S3C44B0X_URXH1			0x01d04024
+#endif
+
+#define S3C44B0X_UBRDIV1		0x01d04028
+
+/* ULCON */
+#define S3C44B0X_ULCON_IR		0x00000040
+
+#define S3C44B0X_ULCON_PAR_NO		0x00000000
+#define S3C44B0X_ULCON_PAR_ODD		0x00000020
+#define S3C44B0X_ULCON_PAR_EVEN		0x00000028
+#define S3C44B0X_ULCON_PAR_1		0x00000030
+#define S3C44B0X_ULCON_PAR_0		0x00000038
+
+#define S3C44B0X_ULCON_STOPB_1		0x00000000
+#define S3C44B0X_ULCON_STOPB_2		0x00000004
+
+#define S3C44B0X_ULCON_WORDLN_5		0x00000000
+#define S3C44B0X_ULCON_WORDLN_6		0x00000001
+#define S3C44B0X_ULCON_WORDLN_7		0x00000002
+#define S3C44B0X_ULCON_WORDLN_8		0x00000003
+
+/* UCON */
+#define S3C44B0X_UCON_TXINT_LEVEL	0x00000200
+#define S3C44B0X_UCON_RXINT_LEVEL	0x00000100
+#define S3C44B0X_UCON_TXINT_PULSE	0x00000000
+#define S3C44B0X_UCON_RXINT_PULSE	0x00000000
+#define S3C44B0X_UCON_RX_TIMEOUT_EN	0x00000080
+#define S3C44B0X_UCON_RX_ERR_INT_EN	0x00000040
+#define S3C44B0X_UCON_LOOP		0x00000020
+#define S3C44B0X_UCON_SEND_BREAK	0x00000010
+
+#define S3C44B0X_UCON_TX_DIS		0x00000000
+#define S3C44B0X_UCON_TX_MODE_INT_POLL	0x00000004
+#define S3C44B0X_UCON_TX_MODE_BDMA0	0x00000008
+#define S3C44B0X_UCON_TX_MODE_BDMA1	0x0000000c
+
+#define S3C44B0X_UCON_RX_DIS		0x00000000
+#define S3C44B0X_UCON_RX_MODE_INT_POLL	0x00000001
+#define S3C44B0X_UCON_RX_MODE_BDMA0	0x00000002
+#define S3C44B0X_UCON_RX_MODE_BDMA1	0x00000003
+
+/* UFCON */
+#define S3C44B0X_UFCON_TX_FIFO_0	0x00000000 /* TX FIFO byte size */
+#define S3C44B0X_UFCON_TX_FIFO_4	0x00000040
+#define S3C44B0X_UFCON_TX_FIFO_8	0x00000080
+#define S3C44B0X_UFCON_TX_FIFO_12	0x000000c0
+
+#define S3C44B0X_UFCON_RX_FIFO_4	0x00000000 /* RX FIFO byte size */
+#define S3C44B0X_UFCON_RX_FIFO_8	0x00000010
+#define S3C44B0X_UFCON_RX_FIFO_12	0x00000020
+#define S3C44B0X_UFCON_RX_FIFO_16	0x00000030
+
+#define S3C44B0X_UFCON_TX_FIFO_RST	0x00000004
+#define S3C44B0X_UFCON_RX_FIFO_RST	0x00000002
+#define S3C44B0X_UFCON_FIFO_EN		0x00000001 /* global FIFO enable */
+
+/* UMCON */
+#define S3C44B0X_UMCON_AFC		0x00000010  /* auto flow control */
+#define S3C44B0X_UMCON_RQST_SEND	0x00000001  /* request to send 1=L(active RTS) 0=H(inactive RTS) */
+
+/* UTRSTAT */
+#define S3C44B0X_UTRSTAT_TSE		0x00000004  /* transmitter shifter empty */
+#define S3C44B0X_UTRSTAT_TBE		0x00000002  /* transmitt buffer empty */
+#define S3C44B0X_UTRSTAT_RBDR		0x00000001  /* receive buffer data ready */
+
+/* UERSTAT */
+#define S3C44B0X_UERSTAT_BREAK_DETECT	0x00000008
+#define S3C44B0X_UERSTAT_FRAME_ERROR	0x00000004
+#define S3C44B0X_UERSTAT_PARITY_ERROR	0x00000002
+#define S3C44B0X_UERSTAT_OVERRUN_ERROR	0x00000001
+
+/* UFSTAT */
+#define S3C44B0X_UFSTAT_TX_FIFO_FULL	0x00000200
+#define S3C44B0X_UFSTAT_RX_FIFO_FULL	0x00000100
+#define S3C44B0X_UFSTAT_TX_FIFO_COUNT	0x000000F0
+#define S3C44B0X_UFSTAT_RX_FIFO_COUNT	0x0000000F
+
+  /***********/
+  /*** SIO ***/
+  /***********/
+
+#define S3C44B0X_SIOCON			0x01d14000
+#define S3C44B0X_SIODAT			0x01d14004
+#define S3C44B0X_SBRDR			0x01d14008
+#define S3C44B0X_ITVCNT			0x01d1400c
+#define S3C44B0X_DNCTZ			0x01d14010
+
+  /****************************/
+  /*** IIS (Inter IC Sound) ***/
+  /****************************/
+
+#define S3C44B0X_IISCON			0x01d18000
+#define S3C44B0X_IISMOD			0x01d18004
+#define S3C44B0X_IISPSR			0x01d18008
+#define S3C44B0X_IISFIFCON		0x01d1800c
+#define S3C44B0X_IISFIF			0x01d18010
+
+  /*****************/
+  /*** I/O ports ***/
+  /*****************/
+
+#define S3C44B0X_PCONA			0x01d20000
+#define S3C44B0X_PDATA			0x01d20004
+#define S3C44B0X_PCONB			0x01d20008
+#define S3C44B0X_PDATB			0x01d2000c
+
+#define S3C44B0X_PCONC			0x01d20010
+#define S3C44B0X_PDATC			0x01d20014
+#define S3C44B0X_PUPC			0x01d20018
+#define S3C44B0X_PCOND			0x01d2001c
+#define S3C44B0X_PDATD			0x01d20020
+#define S3C44B0X_PUPD			0x01d20024
+#define S3C44B0X_PCONE			0x01d20028
+#define S3C44B0X_PDATE			0x01d2002c
+#define S3C44B0X_PUPE			0x01d20030
+#define S3C44B0X_PCONF			0x01d20034
+#define S3C44B0X_PDATF			0x01d20038
+#define S3C44B0X_PUPF			0x01d2003c
+#define S3C44B0X_PCONG			0x01d20040
+#define S3C44B0X_PDATG			0x01d20044
+#define S3C44B0X_PUPG			0x01d20048
+#define S3C44B0X_SPUCR			0x01d2004c
+
+  /***************************/
+  /*** external interrupts ***/
+  /***************************/
+
+#define S3C44B0X_EXTINT			0x01d20050
+#define S3C44B0X_EXTINPND		0x01d20054
+
+  /**********************/
+  /*** WATCHDOG TIMER ***/
+  /**********************/
+
+#define S3C44B0X_WTCON			0x01d30000
+#define S3C44B0X_WTDAT			0x01d30004
+#define S3C44B0X_WTCNT			0x01d30008
+
+  /*********************/
+  /*** A/D CONVERTER ***/
+  /*********************/
+
+#define S3C44B0X_ADCCON			0x01d40000
+#define S3C44B0X_ADCPSR			0x01d40004
+#define S3C44B0X_ADCDAT			0x01d40008
+
+  /*****************/
+  /*** PWM TIMER ***/
+  /*****************/
+
+#define S3C44B0X_TCFG0			0x01d50000 /* prescaler configuration */
+#define S3C44B0X_TCFG1			0x01d50004 /* MUX-input for PWM and DMA */
+#define S3C44B0X_TCON			0x01d50008 /* timer control register (start/stop, PWM-out, auto-reload, dead-zone) */
+#define S3C44B0X_TCNTB0 		0x01d5000c /* timer counter "buffer" register (read-write) to update the timer counter */
+#define S3C44B0X_TCMPB0			0x01d50010 /* timer compare register */
+#define S3C44B0X_TCNTO0			0x01d50014 /* timer counter "observation" register (real counter value, read-only) */
+#define S3C44B0X_TCNTB1			0x01d50018
+#define S3C44B0X_TCMPB1			0x01d5001c
+#define S3C44B0X_TCNTO1			0x01d50020
+#define S3C44B0X_TCNTB2			0x01d50024
+#define S3C44B0X_TCMPB2			0x01d50028
+#define S3C44B0X_TCNTO2			0x01d5002c
+#define S3C44B0X_TCNTB3			0x01d50030
+#define S3C44B0X_TCMPB3			0x01d50034
+#define S3C44B0X_TCNTO3			0x01d50038
+#define S3C44B0X_TCNTB4			0x01d5003c
+#define S3C44B0X_TCMPB4			0x01d50040
+#define S3C44B0X_TCNTO4			0x01d50044
+#define S3C44B0X_TCNTB5			0x01d50048
+#define S3C44B0X_TCNTO5			0x01d5004c
+
+/* TCON */
+#define S3C44B0X_TCON_T5_AUTO		0x04000000 /* automatically reload the timer register (cycle) */
+#define S3C44B0X_TCON_T5_MAN_UPDATE	0x02000000 /* manualy update the counter (read from TCNTBn) */
+#define S3C44B0X_TCON_T5_START		0x01000000 /* start the timer (normal modus) if bit not set -> no decrement of counter */
+
+#define S3C44B0X_TCON_T4_AUTO		0x00800000
+#define S3C44B0X_TCON_T4_OUTPUT		0x00400000 /* enable output to the PWM-pin (controlled by TCMPBn and TCNTBn) */
+#define S3C44B0X_TCON_T4_MAN_UPDATE	0x00200000
+#define S3C44B0X_TCON_T4_START		0x00100000
+
+#define S3C44B0X_TCON_T3_AUTO		0x00080000
+#define S3C44B0X_TCON_T3_OUTPUT		0x00040000
+#define S3C44B0X_TCON_T3_MAN_UPDATE	0x00020000
+#define S3C44B0X_TCON_T3_START		0x00010000
+
+#define S3C44B0X_TCON_T2_AUTO		0x00008000
+#define S3C44B0X_TCON_T2_OUTPUT		0x00004000
+#define S3C44B0X_TCON_T2_MAN_UPDATE	0x00002000
+#define S3C44B0X_TCON_T2_START		0x00001000
+
+#define S3C44B0X_TCON_T1_AUTO		0x00000800
+#define S3C44B0X_TCON_T1_OUTPUT		0x00000400
+#define S3C44B0X_TCON_T1_MAN_UPDATE	0x00000200
+#define S3C44B0X_TCON_T1_START		0x00000100
+
+#define S3C44B0X_TCON_DEAD_ZONE_EN	0x00000010 /* enable the dead zone for PWM-mode */
+
+#define S3C44B0X_TCON_T0_AUTO		0x00000008
+#define S3C44B0X_TCON_T0_OUTPUT		0x00000004
+#define S3C44B0X_TCON_T0_MAN_UPDATE	0x00000002
+#define S3C44B0X_TCON_T0_START		0x00000001
+
+  /***********/
+  /*** IIC ***/
+  /***********/
+
+#define S3C44B0X_IICCON			0x01d60000
+#define S3C44B0X_IICSTAT		0x01d60004
+#define S3C44B0X_IICADD			0x01d60008
+#define S3C44B0X_IICDS			0x01d6000c
+
+  /***********/
+  /*** RTC ***/
+  /***********/
+
+#define S3C44B0X_RTCCON			0x01d70040
+#define S3C44B0X_RTCALM			0x01d70050
+#define S3C44B0X_ALMSEC			0x01d70054
+#define S3C44B0X_ALMMIN			0x01d70058
+#define S3C44B0X_ALMHOUR		0x01d7005c
+#define S3C44B0X_ALMDAY			0x01d70060
+#define S3C44B0X_ALMMON			0x01d70064
+#define S3C44B0X_ALMYEAR		0x01d70068
+#define S3C44B0X_RTCRST			0x01d7006c
+#define S3C44B0X_BCDSEC			0x01d70070
+#define S3C44B0X_BCDMIN			0x01d70074
+#define S3C44B0X_BCDHOUR		0x01d70078
+#define S3C44B0X_BCDDAY			0x01d7007c
+#define S3C44B0X_BCDDATE		0x01d70080
+#define S3C44B0X_BCDMON			0x01d70084
+#define S3C44B0X_BCDYEAR		0x01d70088
+#define S3C44B0X_TICINT			0x01d7008c
+
+  /********************************/
+  /*** CLOCK & POWER MANAGEMENT ***/
+  /********************************/
+
+#define S3C44B0X_PLLCON			0x01d80000
+#define S3C44B0X_CLKCON			0x01d80004
+#define S3C44B0X_CLKSLOW		0x01d80008
+#define S3C44B0X_LOCKTIME		0x01d8000c
+
+#define S3C44B0X_CLKCON_IIS		0x4000
+#define S3C44B0X_CLKCON_IIC		0x2000
+#define S3C44B0X_CLKCON_ADC		0x1000
+#define S3C44B0X_CLKCON_RTC		0x0800
+#define S3C44B0X_CLKCON_GPIO		0x0400
+#define S3C44B0X_CLKCON_UART1		0x0200
+#define S3C44B0X_CLKCON_UART0		0x0100
+#define S3C44B0X_CLKCON_BDMA		0x0080
+#define S3C44B0X_CLKCON_LCDC		0x0040
+#define S3C44B0X_CLKCON_SIO		0x0020
+#define S3C44B0X_CLKCON_ZDMA		0x0010
+#define S3C44B0X_CLKCON_PWMTIMER	0x0008
+#define S3C44B0X_CLKCON_IDLE_BIT	0x0004
+#define S3C44B0X_CLKCON_SL_IDLE		0x0002
+#define S3C44B0X_CLKCON_STOP_BIT	0x0001
+
+#define S3C44B0X_CLKSLOW_PLL_OFF	0x00000010
+#define S3C44B0X_CLKSLOW_SLOW_BIT	0x00000008
+#define S3C44B0X_CLKSLOW_VAL_0		0x00000000
+#define S3C44B0X_CLKSLOW_VAL_1		0x00000001
+#define S3C44B0X_CLKSLOW_VAL_2		0x00000002
+#define S3C44B0X_CLKSLOW_VAL_3		0x00000003
+
+  /****************************/
+  /*** INTERRUPT CONTROLLER ***/
+  /****************************/
+
+#define S3C44B0X_INTCON			0x01e00000
+#define S3C44B0X_INTPND			0x01e00004
+#define S3C44B0X_INTMOD			0x01e00008
+#define S3C44B0X_INTMSK			0x01e0000c
+#define S3C44B0X_I_PSLV			0x01e00010
+#define S3C44B0X_I_PMST			0x01e00014
+#define S3C44B0X_I_CSLV			0x01e00018
+#define S3C44B0X_I_CMST			0x01e0001c
+#define S3C44B0X_I_ISPR			0x01e00020
+#define S3C44B0X_I_ISPC			0x01e00024
+#define S3C44B0X_F_ISPR			0x01e00038
+#define S3C44B0X_F_ISPC			0x01e0003c
+
+  /***********/
+  /*** DMA ***/
+  /***********/
+
+#define S3C44B0X_ZDCON0			0x01e80000
+#define S3C44B0X_ZDISRC0		0x01e80004
+#define S3C44B0X_ZDIDES0		0x01e80008
+#define S3C44B0X_ZDICNT0		0x01e8000c
+#define S3C44B0X_ZDCSRC0		0x01e80010
+#define S3C44B0X_ZDCDES0		0x01e80014
+#define S3C44B0X_ZDCCNT0		0x01e80018
+#define S3C44B0X_ZDCON1			0x01e80020
+#define S3C44B0X_ZDISRC1		0x01e80024
+#define S3C44B0X_ZDIDES1		0x01e80028
+#define S3C44B0X_ZDICNT1		0x01e8002c
+#define S3C44B0X_ZDCSRC1		0x01e80030
+#define S3C44B0X_ZDCDES1		0x01e80034
+#define S3C44B0X_ZDCCNT1		0x01e80038
+
+#define S3C44B0X_BDCON0			0x01f80000
+#define S3C44B0X_BDISRC0		0x01f80004
+#define S3C44B0X_BDIDES0		0x01f80008
+#define S3C44B0X_BDICNT0		0x01f8000c
+#define S3C44B0X_BDCSRC0		0x01f80010
+#define S3C44B0X_BDCDES0		0x01f80014
+#define S3C44B0X_BDCCNT0		0x01f80018
+#define S3C44B0X_BDCON1			0x01f80020
+#define S3C44B0X_BDISRC1		0x01f80024
+#define S3C44B0X_BDIDES1		0x01f80028
+#define S3C44B0X_BDICNT1		0x01f8002c
+#define S3C44B0X_BDCSRC1		0x01f80030
+#define S3C44B0X_BDCDES1		0x01f80034
+#define S3C44B0X_BDCCNT1		0x01f80038
+
+#define S3C44B0X_ZDCON_STE_RDY		0x00000000
+#define S3C44B0X_ZDCON_STE_NTC		0x00000040
+#define S3C44B0X_ZDCON_STE_TC		0x00000080
+
+#define S3C44B0X_ZDCON_QDS_EN		0x00000000
+#define S3C44B0X_ZDCON_QDS_DIS		0x0000000c
+
+#define S3C44B0X_ZDCON_CMD_NONE		0x00000000
+#define S3C44B0X_ZDCON_CMD_START	0x00000001
+#define S3C44B0X_ZDCON_CMD_PAUSE	0x00000002
+#define S3C44B0X_ZDCON_CMD_CANCEL	0x00000003
+
+
+/*********************
+ *   LCD controller  *
+ *********************/
+#define S3C44B0X_LCD_MEM		0x0c060000
+
+#define S3C44B0X_LCDCON1                0x01f00000
+#define S3C44B0X_LCDCON2                0x01f00004
+#define S3C44B0X_LCDCON3                0x01f00040
+#define S3C44B0X_LCDSADDR1              0x01f00008
+#define S3C44B0X_LCDSADDR2              0x01f0000c
+#define S3C44B0X_LCDSADDR3              0x01f00010
+
+#define S3C44B0X_REDLUT                 0x01f00014
+#define S3C44B0X_GREENLUT               0x01f00018
+#define S3C44B0X_BLUELUT                0x01f0001c
+#define S3C44B0X_DP1_2                  0x01f00020
+#define S3C44B0X_DP4_7                  0x01f00024
+#define S3C44B0X_DP3_5                  0x01f00028
+#define S3C44B0X_DP2_3                  0x01f0002c
+#define S3C44B0X_DP5_7                  0x01f00030
+#define S3C44B0X_DP3_4                  0x01f00034
+#define S3C44B0X_DP4_5                  0x01f00038
+#define S3C44B0X_DP6_7                  0x01f0003c
+
+#define S3C44B0X_DITHMODE               0x01f00044
+
+/* LCDCON1 */
+#define S3C44B0X_LCDCON1_WLH_4          0x00000000
+#define S3C44B0X_LCDCON1_WLH_8          0x00000400
+#define S3C44B0X_LCDCON1_WLH_12         0x00000800
+#define S3C44B0X_LCDCON1_WLH_16         0x00000c00
+
+#define S3C44B0X_LCDCON1_WDLY_4         0x00000000
+#define S3C44B0X_LCDCON1_WDLY_8         0x00000100
+#define S3C44B0X_LCDCON1_WDLY_12        0x00000200
+#define S3C44B0X_LCDCON1_WDLY_16        0x00000300
+
+#define S3C44B0X_LCDCON1_MMODE          0x00000080
+
+#define S3C44B0X_LCDCON1_DISMODE_4D     0x00000000
+#define S3C44B0X_LCDCON1_DISMODE_4S     0x00000020
+#define S3C44B0X_LCDCON1_DISMODE_8S     0x00000040
+
+#define S3C44B0X_LCDCON1_INVCLK         0x00000010
+#define S3C44B0X_LCDCON1_INVLINE        0x00000008
+#define S3C44B0X_LCDCON1_INVFRAME       0x00000004
+#define S3C44B0X_LCDCON1_INVVD          0x00000002
+#define S3C44B0X_LCDCON1_ENVID          0x00000001
+
+
+/* LCDCON3 */
+#define S3C44B0X_LCDCON3_SELFREFRESH	0x00000001
+
+
+/* LCDSADDR1 */
+#define S3C44B0X_LCDSADDR1_MONO		0x00000000
+#define S3C44B0X_LCDSADDR1_GRAY_4	0x08000000
+#define S3C44B0X_LCDSADDR1_GRAY_16	0x10000000
+#define S3C44B0X_LCDSADDR1_COLOR	0x18000000
+
+/* LCDSADDR2 */
+#define S3C44B0X_LCDSADDR2_BSWP     	0x20000000
+
+
+#endif /* _S3C44B0X_H_ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/serial.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/serial.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/serial.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,15 @@
+/*
+ * linux/include/asm/arch-S3C44B0X/serial.h
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+/* 
+ * nothing needed here, all definitions are in 
+ * drivers/char/serial_s3c44b0x.h
+ */
+
+#endif /* __ASM_ARCH_SERIAL_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/shmparam.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/shmparam.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/shmparam.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,8 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C44B0X/shmparam.h
+ *
+ * (just a placeholder, not needed in our machine)
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/system.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C44B0X/system.h
+ *
+ * (just a placeholder, not needed in our machine)
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H_
+#define __ASM_ARCH_SYSTEM_H_
+
+static inline void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter)
+		cpu_do_idle(IDLE_WAIT_SLOW);
+}
+
+extern inline void arch_reset(char mode)
+{
+	/* @todo: reset the hardware in some way */
+}
+
+#endif /* __ASM_ARCH_SYSTEM_H_ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/time.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/time.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,61 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C44B0X/time.h
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ * Setup for 16 bit timer 5, used as system timer.
+ *
+ */
+
+#ifndef __ASM_ARCH_TIME_H__
+#define __ASM_ARCH_TIME_H__
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/timex.h>
+
+extern struct irqaction timer_irq;
+
+extern unsigned long s3c44b0x_gettimeoffset(void);
+extern void s3c44b0x_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+/* TODO: THE, 2003-08-13, do timer setup like in eCos */
+#define S3C44B0X_TIMER5_PRESCALER 16
+
+extern __inline__ void setup_timer (void)
+{
+	u_int32_t tmod;
+	u_int32_t period;
+
+	period = (CONFIG_ARM_CLK/S3C44B0X_TIMER5_PRESCALER)/HZ;
+	outl(period, S3C44B0X_TCNTB5);
+
+	tmod=0;
+	tmod |= S3C44B0X_TCON_T5_MAN_UPDATE;
+	outl(tmod, S3C44B0X_TCON);
+
+	/* initialize the timer period and prescaler */
+	outl((5-1) << 16, S3C44B0X_TCFG0);
+	outl( (0x3 <<20), S3C44B0X_TCFG1); /* prescaler */
+
+	/*
+	 * @todo do those really need to be function pointers ?
+	 */
+	gettimeoffset     = s3c44b0x_gettimeoffset;
+	timer_irq.handler = s3c44b0x_timer_interrupt;
+
+	/* set up the interrupt vevtor for timer 5 match */
+	setup_arm_irq(S3C44B0X_INTERRUPT_TIMER5, &timer_irq);
+
+	/* enable the timer IRQ */
+	s3c44b0x_unmask_irq(S3C44B0X_INTERRUPT_TIMER5);
+
+	/* let timer 5 run... */
+	tmod=0;
+	tmod |= S3C44B0X_TCON_T5_AUTO;
+	tmod |= S3C44B0X_TCON_T5_START;
+	outl(tmod, S3C44B0X_TCON);
+}
+
+#endif /* __ASM_ARCH_TIME_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * uclinux/include/asm-armnommu/arch-S3C44B0X/timex.h
+ *
+ * (just a placeholder, not needed in our machine)
+ *
+ * Copyright (C) 2003 Thomas Eschenbacher <eschenbacher@sympat.de>
+ *
+ */
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-S3C44B0X/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-S3C44B0X/vmalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ *  uclinux/include/asm-armnommu/arch-S3C44B0X/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff -urN linux-2.4.29/include/asm-armnommu/arch-SMDK2500/des.h linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/des.h
--- linux-2.4.29/include/asm-armnommu/arch-SMDK2500/des.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/des.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,60 @@
+/*
+ * des.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file includes the DES/3DES engine definitions 
+ * of the S3C2500 RISC microcontroller
+ * based on the Samsung's "S3C2500 32-bit RISC
+ * microcontroller pre. User's Manual"
+ */
+
+#ifndef __ASM_ARCH_DES_H
+#define __ASM_ARCH_DES_H
+
+#define DES_BASE	0xf0090000
+
+#define DESCON		0xf0090000	/* DES/3DES control (R/W)	      */
+#define DESSTA		0xf0090004	/* DES/3DES status (R)		      */
+#define DESINT		0xf0090008	/* DES/3DES interrupt enable (R/W)    */
+#define DESRUN		0xf009000c	/* DES/3DES run enable (W)	      */
+#define DESKEY1L	0xf0090010	/* DES/3DES Key 1 left half (R/W)     */
+#define DESKEY1R	0xf0090014	/* DES/3DES Key 1 right half (R/W)    */
+#define DESKEY2L	0xf0090018	/* DES/3DES Key 2 left half (R/W)     */
+#define DESKEY2R	0xf009001c	/* DES/3DES Key 2 right half (R/W)    */
+#define DESKEY3L	0xf0090020	/* DES/3DES Key 3 left half (R/W)     */
+#define DESKEY3R	0xf0090024	/* DES/3DES Key 3 right half (R/W)    */
+#define DESIVL		0xf0090028	/* DES/3DES IV left half (R/W)	      */
+#define DESIVR		0xf009002c	/* DES/3DES IV right half (R/W)	      */
+#define DESINFIFO	0xf0090030	/* DES/3DES input FIFO (W)	      */
+#define DESOUTFIFO	0xf0090034	/* DES/3DES output FIFO (R)	      */
+
+/*---------------------------------------< DES/3DES control (R/W) >-----------*/
+#define	DES_RUN		0x00000001
+#define	DES_INDMA	0x00000002
+#define	DES_OUTDMA	0x00000004
+#define	DES_R2LDATA	0x00000008
+#define	DES_DECRYPT	0x00000010
+#define	DES_3DES	0x00000020
+#define	DES_CBC		0x00000040
+#define	DES_2W		0x00000080
+#define	DES_TEST	0x00000100
+#define	DES_RESET	0x00000200
+
+/*---------------------------------------< DES/3DES status (R) >--------------*/
+#define	DES_IDLE	0x00000001
+#define	DES_INAVAILABLE	0x00000010
+#define	DES_INEMPTY	0x00000020
+#define	DES_INFULL	0x00000040
+#define	DES_OUTVALID	0x00000100
+#define	DES_OUTEMPTY	0x00000200
+#define	DES_OUTFULL	0x00000400
+
+/*---------------------------------------< DES/3DES interrupt enable (R/W) >--*/
+#define	DES_IDLE_IE		0x00000001
+#define	DES_INAVAILABLE_IE	0x00000010
+#define	DES_OUTVALID_IE		0x00000100
+
+
+#endif /* _ASM_ARCH_DES_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-SMDK2500/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-SMDK2500/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,85 @@
+/*
+ * dma.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file includes the DMA controller definitions 
+ * of the S3C2500X RISC microcontroller
+ * based on the Samsung's "S3C2500X 32-bit RISC
+ * microcontroller pre. User's Manual"
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_ADDRESS		0x01000000 /* End of the SDRAM */
+#define MAX_DMA_CHANNELS        6
+
+#define GDMA_BASE	0xf0050000
+
+#define DPRIC		0xf0051000	/* GDMA priority configuration R */
+#define DPRIF		0xf0052000	/* GDMA programmable priority R for fixed */
+#define DPRIR		0xf0053000	/* GDMA programmable priority R for round-robin */
+
+#define DCON0		0xf0050000	/* GDMA channel 0 control R		*/
+#define DSAR0		0xf0050004	/* GDMA channel 0 source address R	*/
+#define DDAR0		0xf0050008	/* GDMA channel 0 destination address R */
+#define DTCR0		0xf005000c	/* GDMA channel 0 transfer count R	*/
+#define DRER0		0xf0050010	/* GDMA channel 0 run enable R		*/
+#define DIPR0		0xf0050014	/* GDMA channel 0 interrupt pending R	*/
+
+#define DCON1		0xf0050020	/* GDMA channel 1 control R		*/
+#define DSAR1		0xf0050024	/* GDMA channel 1 source address R	*/
+#define DDAR1		0xf0050028	/* GDMA channel 1 destination address R */
+#define DTCR1		0xf005002c	/* GDMA channel 1 transfer count R	*/
+#define DRER1		0xf0050030	/* GDMA channel 1 run enable R		*/
+#define DIPR1		0xf0050034	/* GDMA channel 1 interrupt pending R	*/
+
+#define DCON2		0xf0050040	/* GDMA channel 2 control R		*/
+#define DSAR2		0xf0050044	/* GDMA channel 2 source address R	*/
+#define DDAR2		0xf0050048	/* GDMA channel 2 destination address R */
+#define DTCR2		0xf005004c	/* GDMA channel 2 transfer count R	*/
+#define DRER2		0xf0050050	/* GDMA channel 2 run enable R		*/
+#define DIPR2		0xf0050054	/* GDMA channel 2 interrupt pending R	*/
+
+#define DCON3		0xf0050060	/* GDMA channel 3 control R		*/
+#define DSAR3		0xf0050064	/* GDMA channel 3 source address R	*/
+#define DDAR3		0xf0050068	/* GDMA channel 3 destination address R */
+#define DTCR3		0xf005006c	/* GDMA channel 3 transfer count R	*/
+#define DRER3		0xf0050070	/* GDMA channel 3 run enable R		*/
+#define DIPR3		0xf0050074	/* GDMA channel 3 interrupt pending R	*/
+
+#define DCON4		0xf0050080	/* GDMA channel 4 control R		*/
+#define DSAR4		0xf0050084	/* GDMA channel 4 source address R	*/
+#define DDAR4		0xf0050088	/* GDMA channel 4 destination address R */
+#define DTCR4		0xf005008c	/* GDMA channel 4 transfer count R	*/
+#define DRER4		0xf0050090	/* GDMA channel 4 run enable R		*/
+#define DIPR4		0xf0050094	/* GDMA channel 4 interrupt pending R	*/
+
+#define DCON5		0xf00500a0	/* GDMA channel 5 control R		*/
+#define DSAR5		0xf00500a4	/* GDMA channel 5 source address R	*/
+#define DDAR5		0xf00500a8	/* GDMA channel 5 destination address R */
+#define DTCR5		0xf00500ac	/* GDMA channel 5 transfer count R	*/
+#define DRER5		0xf00500b0	/* GDMA channel 5 run enable R		*/
+#define DIPR5		0xf00500b4	/* GDMA channel 5 interrupt pending R	*/
+
+#define	DMA_RE		0x00000001
+#define	DMA_EXTDREQ	0x00000002
+#define	DMA_HUARTTX	0x00000004
+#define	DMA_HUARTRX	0x00000006
+#define	DMA_DESIN	0x00000008
+#define	DMA_DESOUT	0x0000000a
+#define	DMA_SB		0x00000010
+#define	DMA_FB		0x00000020
+#define	DMA_TS4		0x00000080
+#define	DMA_TS2		0x00000040
+#define	DMA_SD		0x00000100
+#define	DMA_SF		0x00000200
+#define	DMA_DD		0x00000400
+#define	DMA_DF		0x00000800
+#define	DMA_IE		0x00001000
+#define	DMA_XCNT(x)	((x-1)<<13)
+#define	DMA_BS		0x80000000
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-SMDK2500/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-SMDK2500/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,139 @@
+/*
+ * hardware.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file includes the hardware definitions 
+ * of the S3C2500X RISC microcontroller
+ * based on the Samsung's "S3C2500X 32-bit RISC
+ * microcontroller pre. User's Manual"
+ */
+ 
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <linux/config.h>
+
+#ifndef __ASSEMBLER__
+extern	unsigned int CONFIG_ARM_CLK;
+#endif
+
+#define PCLK		CONFIG_ARM_CLK
+
+#define MCLK2		(PCLK >> 1)
+
+#define Vol32	*(volatile unsigned int *)
+#define Vol16	*(volatile unsigned short *)
+#define Vol08	*(volatile unsigned char *)
+
+#define REG_WRITE(addr,data)	(Vol32(addr)=(data))
+#define REG_READ(addr)		(Vol32(addr))
+
+#define HARD_RESET_NOW()
+
+/*
+---	Memory map
+*/
+#define BASE_MEM_BANK0	0x00000000	/* EXT I/O Bank 0 base address */
+#define BASE_MEM_BANK1	0x01000000	/* EXT I/O Bank 1 base address */
+#define BASE_MEM_BANK2	0x02000000	/* EXT I/O Bank 2 base address */
+#define BASE_MEM_BANK3	0x03000000	/* EXT I/O Bank 3 base address */
+#define BASE_MEM_BANK4	0x04000000	/* EXT I/O Bank 4 base address */
+#define BASE_MEM_BANK5	0x05000000	/* EXT I/O Bank 5 base address */
+#define BASE_MEM_BANK6	0x06000000	/* EXT I/O Bank 6 base address */
+#define BASE_MEM_BANK7	0x07000000	/* EXT I/O Bank 7 base address */
+#define BASE_SDRAM_BANK0 0x40000000	/* SDRAM   Bank 0 base address */
+#define BASE_SDRAM_BANK1 0x80000000	/* SDRAM   Bank 1 base address */
+
+#define MAP_MEM_BANK0	0x80000000	/* EXT I/O Bank 0 remaped address */
+#define MAP_MEM_BANK1	0x81000000	/* EXT I/O Bank 1 remaped address */
+#define MAP_MEM_BANK2	0x82000000	/* EXT I/O Bank 2 remaped address */
+#define MAP_MEM_BANK3	0x83000000	/* EXT I/O Bank 3 remaped address */
+#define MAP_MEM_BANK4	0x84000000	/* EXT I/O Bank 4 remaped address */
+#define MAP_MEM_BANK5	0x85000000	/* EXT I/O Bank 5 remaped address */
+#define MAP_MEM_BANK6	0x86000000	/* EXT I/O Bank 6 remaped address */
+#define MAP_MEM_BANK7	0x87000000	/* EXT I/O Bank 7 remaped address */
+#define MAP_SDRAM_BANK0	0x00000000	/* SDRAM   Bank 0 remaped address */
+#define MAP_SDRAM_BANK1	0x04000000	/* SDRAM   Bank 1 remaped address */
+
+#define	BASE_REG	0xF0000000	/* Internal register base address */
+
+
+/*	
+---	System configuration special registers
+*/
+#define	SYSCFG		0xF0000000	/* System configuration R */
+#define	PDCODE		0xF0000004	/* Product code and revision number R */
+#define CLKCON		0xF0000008	/* System clock control R */
+#define PCLKDIS		0xF000000C	/* Pirepheral clock disable R */
+#define CLKST		0xF0000010	/* Clock status R */
+#define HPRIF		0xF0000014	/* AHB bus master fixed priority R */
+#define HPRIR		0xF0000018	/* AHB bus master round-robin priority R */
+#define CPLL		0xF000001C	/* Core PLL configuration R */
+#define SPLL		0xF0000020	/* System PLL configuration R */
+#define UPLL		0xF0000024	/* USB PLL configuration R */
+#define PPLL		0xF0000028	/* PHY PLL configuration R */
+
+/*
+---	External I/O bank controller
+*/
+#define	B0CON		0xF0010000	/* Bank 0 control R */
+#define	B1CON		0xF0010004	/* Bank 1 control R */
+#define	B2CON		0xF0010008	/* Bank 2 control R */
+#define	B3CON		0xF001000C	/* Bank 3 control R */
+#define	B4CON		0xF0010010	/* Bank 4 control R */
+#define	B5CON		0xF0010014	/* Bank 5 control R */
+#define	B6CON		0xF0010018	/* Bank 6 control R */
+#define	B7CON		0xF001001C	/* Bank 7 control R */
+#define	MUXBCON		0xF0010020	/* Muxed bus control R */
+#define	WAITCON		0xF0010024	/* Wait control R */
+
+/*
+---	SDRAM controller
+*/
+#define	RegO		0xF0020000	/* Configuration R 0 */
+#define	Reg1		0xF0020004	/* Configuration R 1 */
+#define	Reg3		0xF0020008	/* Refresh timer R */
+#define	Reg4		0xF002000C	/* Write buffer time-out R*/
+
+/*
+---	HDLC controller
+*/
+#define HMODE_A		0xF0100000	/* HDLC Channel A mode */
+#define HMODE_B		0xF0110000	/* HDLC Channel B mode */
+#define HMODE_C		0xF0120000	/* HDLC Channel C mode */
+
+/*
+---	Interrupt controller
+*/
+#include <asm/arch/irqs.h>
+
+/*
+---	Timers
+*/
+#define	ARM_CLK	CONFIG_ARM_CLK
+#include <asm/arch/timers.h>
+
+/*
+---	I/O ports
+*/
+#include <asm/arch/ios.h>
+
+/*
+---	UART controller
+*/
+#include <asm/arch/uart.h>
+
+/*
+---	DMA controller
+*/
+#include <asm/arch/dma.h>
+
+/*
+---	I2C BUS controller
+*/
+#include <asm/arch/i2c.h>
+
+	
+#endif	/* __ASM_ARCH_HARDWARE_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-SMDK2500/i2c.h linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/i2c.h
--- linux-2.4.29/include/asm-armnommu/arch-SMDK2500/i2c.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/i2c.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ * iic.h
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file includes the I2C bus controller definitions
+ * of the S3C2500X RISC microcontroller
+ * based on the Samsung's "S3C2500X 32-bit RISC
+ * microcontroller pre. User's Manual"
+ */
+ 
+#ifndef __ASM_ARCH_IIC_H
+#define __ASM_ARCH_IIC_H
+
+#define IICCON		0xF00F0000	/* Control status R	*/
+#define IICCON_BF	0x01		/* Buffer flag		*/
+#define IICCON_IEN	0x02		/* Interrupt enable	*/
+#define IICCON_LRB	0x04		/* Last received bit 	*/
+#define IICCON_ACK	0x08		/* Acknowlege enable	*/
+#define IICCON_START	0x10		/* Start condition	*/
+#define IICCON_STOP	0x20		/* Stop condition	*/
+#define IICCON_RESTART	0x30		/* Repeat Start(Restart)*/
+#define IICCON_BUSY	0x40		/* Bus busy		*/
+#define IICCON_RESET	0x80		/* Reset		*/
+
+#define IICBUF		0xF00F0004	/* Shift buffer R	*/
+#define IICBUF_WRITE	0x00		/* Slave Addr Write bit	*/
+#define IICBUF_READ	0x01		/* Slave Addr Read bit	*/
+
+#define IICPS		0xF00F0008	/* Prescaler R		*/
+#define IICCNT		0xF00F000C	/* Prescaler counter R
	*/
+#define IICPND		0xF00F0010	/* Interrupt pending R
	*/
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-SMDK2500/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/io.h
--- linux-2.4.29/include/asm-armnommu/arch-SMDK2500/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ * linux/include/asm-armnommu/arch-dsc21/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ *  02-19-2001  gjm     Leveraged for armnommu/dsc21
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ * --gmcnutt
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * If we define __io then asm/io.h will take care of most of the inb & friends
+ * macros. It still leaves us some 16bit macros to deal with ourselves, though.
+ * We don't have PCI or ISA on the dsc21 so I dropped __mem_pci & __mem_isa.
+ * --gmcnutt
+ */
+#define PCIO_BASE 0
+#define __io(a) (PCIO_BASE + (a))
+#define __arch_getw(a) (*(volatile unsigned short *)(a))
+#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
+
+/*
+ * Defining these two gives us ioremap for free. See asm/io.h.
+ * --gmcnutt
+ */
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-SMDK2500/ios.h linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/ios.h
--- linux-2.4.29/include/asm-armnommu/arch-SMDK2500/ios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/ios.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ * ios.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file includes the I/O ports definitions 
+ * of the S3C2500X RISC microcontroller
+ * based on the Samsung's "S3C2500X 32-bit RISC
+ * microcontroller pre. User's Manual"
+ */
+
+#ifndef __ASM_ARCH_IOS_H
+#define __ASM_ARCH_IOS_H
+
+#define MAX_IOS_PORTS	64
+
+#define IO_BASE		0xf0030000
+
+#define	IOPMOD1		0xF0030000	/* I/O port mode select lower R		*/
+#define	IOPMOD2		0xF0030004	/* I/O port mode select upper R		*/
+#define	IO_Ftn_cont1	0xF0030008	/* I/O port select lower R		*/
+#define	IO_Ftn_cont2	0xF003000C	/* I/O port select upper R		*/
+#define	IOP4DMA		0xF0030010	/* I/O port special function R for DMA	*/
+#define	IOP4xINT	0xF0030014	/* I/O port spec. function R for Ext.IRQ*/
+#define	IOP4xINT_PEND	0xF0030018	/* External IRQ clear R			*/
+#define	IOPDATA1	0xF003001c	/* I/O port data R			*/
+#define	IOPDATA2	0xF0030020	/* I/O port data R			*/
+#define	IOPDRV1		0xF0030024	/* I/O port drive control R		*/
+#define	IOPDRV2		0xF0030028	/* I/O port drive control R		*/
+
+#endif /* _ASM_ARCH_IOS_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-SMDK2500/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-SMDK2500/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,93 @@
+/*
+ * irq.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ */
+#ifndef __ASM_ARCH_IRQ_H
+#define __ASM_ARCH_IRQ_H
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irqs.h>
+
+#define fixup_irq(x) (x)
+
+extern void s3c2500_mask_irq(unsigned int irq);
+extern void s3c2500_unmask_irq(unsigned int irq);
+extern void s3c2500_mask_ack_irq(unsigned int irq);
+extern void s3c2500_mask_global(void);
+extern void s3c2500_unmask_global(void);
+
+static __inline__ void irq_init_irq(void)
+{
+/******************************************
+ * Interrupt priority table
+ ******************************************/
+static unsigned char s3c2500_irq_prtable[NR_IRQS] =
+	{
+	SRC_IRQ_0,
+	SRC_IRQ_1,
+	SRC_IRQ_2,
+ 	SRC_IRQ_3,
+ 	SRC_IRQ_4,
+ 	SRC_IRQ_5,
+ 	SRC_IRQ_IOM2,
+ 	SRC_IRQ_IICC,
+ 	SRC_IRQ_HUART0_TX,
+ 	SRC_IRQ_HUART0_RX,
+ 	SRC_IRQ_HUART1_TX,
+ 	SRC_IRQ_HUART1_RX,
+ 	SRC_IRQ_CUART_TX,
+ 	SRC_IRQ_CUART_RX,
+ 	SRC_IRQ_USB,
+ 	SRC_IRQ_HDLC_TX0,
+ 	SRC_IRQ_HDLC_RX0,
+ 	SRC_IRQ_HDLC_TX1,
+ 	SRC_IRQ_HDLC_RX1,
+ 	SRC_IRQ_HDLC_TX2,
+ 	SRC_IRQ_HDLC_RX2,
+ 	SRC_IRQ_ETH_TX0,
+ 	SRC_IRQ_ETH_RX0,
+ 	SRC_IRQ_ETH_TX1,
+ 	SRC_IRQ_ETH_RX1,
+ 	SRC_IRQ_DES,
+ 	SRC_IRQ_GDMA0,
+ 	SRC_IRQ_GDMA1,
+ 	SRC_IRQ_GDMA2,
+ 	SRC_IRQ_GDMA3,
+ 	SRC_IRQ_GDMA4,
+ 	SRC_IRQ_GDMA5,
+ 	SRC_IRQ_TIMER0,
+ 	SRC_IRQ_TIMER1,
+ 	SRC_IRQ_TIMER2,
+ 	SRC_IRQ_TIMER3,
+ 	SRC_IRQ_TIMER4,
+ 	SRC_IRQ_TIMER5,
+ 	SRC_IRQ_TIMER_WD
+	};
+    volatile unsigned int *PtIntPr = (volatile unsigned int *)INTPRIOR0;
+    unsigned int irq;
+    unsigned int *tmp = (unsigned int *)s3c2500_irq_prtable;
+    
+    for (irq = 0; irq < NR_IRQS; irq++) {
+	irq_desc[irq].valid	= 1;
+	irq_desc[irq].probe_ok	= 1;
+	irq_desc[irq].mask_ack	= s3c2500_mask_ack_irq;
+	irq_desc[irq].mask	= s3c2500_mask_irq;
+	irq_desc[irq].unmask	= s3c2500_unmask_irq;
+	}
+    for (irq = 0; irq < NR_IRQS; irq+=4) {
+	*PtIntPr++ = *tmp++;
+	}
+    
+    outl ( 0,          INTMOD );	/* Set internal interrupts
 in IRQ mode	*/
+    outl ( 0,          EXTMOD );	/* Set external interrupts
 in IRQ mode	*/
+    s3c2500_mask_global();		/* Disable all interrupt requests	*/
+    outl ( 0xFFFFFFFF, INTMASK );
	/* Mask all internal Intrerrupts	*/
+    outl ( 0x0000007F, EXTMASK );
	/* Mask all external Intrerrupts 	*/
+}
+
+#endif /* __ASM_ARCH_IRQ_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-SMDK2500/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-SMDK2500/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/irqs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,170 @@
+/*
+ * irqs.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file includes the interupt controller definitions 
+ * of the S3C2500X RISC microcontroller
+ * based on the Samsung's "S3C2500X 32-bit RISC
+ * microcontroller pre. User's Manual"
+ */
+ 
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define	INTMOD		0xF0140000	/* Internal interrupt mode R */
+#define	EXTMOD		0xF0140004	/* External interrupt mode R */
+#define	INTMASK		0xF0140008	/* Internal interrupt mask R */
+#define	EXTMASK		0xF014000C	/* External interrupt mask R */
+#define IPRIORHI	0xF0140010	/* HIgh bits, 5-0 bit, Interrupt by priority R */
+#define IPRIORLO	0xF0140014	/* LOw bits, 31-0 bit, Interrupt by priority R */
+#define INTOFFSET_FIQ	0xF0140018	/* FIQ interrupt offset R */
+#define INTOFFSET_IRQ	0xF014001C	/* IRQ interrupt offset R */
+#define INTPRIOR0	0xF0140020	/* Interrupt priority R 0 */
+#define INTPRIOR1	0xF0140024	/* Interrupt priority R 1 */
+#define INTPRIOR2	0xF0140028	/* Interrupt priority R 2 */
+#define INTPRIOR3	0xF014002C	/* Interrupt priority R 3 */
+#define INTPRIOR4	0xF0140030	/* Interrupt priority R 4 */
+#define INTPRIOR5	0xF0140034	/* Interrupt priority R 5 */
+#define INTPRIOR6	0xF0140038	/* Interrupt priority R 6 */
+#define INTPRIOR7	0xF014003C	/* Interrupt priority R 7 */
+#define INTPRIOR8	0xF0140040	/* Interrupt priority R 8 */
+#define INTPRIOR9	0xF0140044	/* Interrupt priority R 9 */
+#define INTTSTHI	0xF0140048	/* HIgh bits, 5-0 bit, Interrupt test R */
+#define INTTSTLO	0xF014004C	/* LOw bits, 31-0 bit, Interrupt test R */
+
+
+#define	NR_IRQS		39		/* There are 39 sources of the interrupts */
+
+#define	SRC_IRQ_0		0
+#define	SRC_IRQ_1		1
+#define	SRC_IRQ_2		2
+#define	SRC_IRQ_3		3
+#define	SRC_IRQ_4		4
+#define	SRC_IRQ_5		5
+#define	SRC_IRQ_IOM2		6
+#define	SRC_IRQ_IICC		7
+#define	SRC_IRQ_HUART0_TX	8
+#define	SRC_IRQ_HUART0_RX	9
+#define	SRC_IRQ_HUART1_TX	10
+#define	SRC_IRQ_HUART1_RX	11
+#define	SRC_IRQ_CUART_TX	12
+#define	SRC_IRQ_CUART_RX	13
+#define	SRC_IRQ_USB		14
+#define	SRC_IRQ_HDLC_TX0	15
+#define	SRC_IRQ_HDLC_RX0	16
+#define	SRC_IRQ_HDLC_TX1	17
+#define	SRC_IRQ_HDLC_RX1	18
+#define	SRC_IRQ_HDLC_TX2	19
+#define	SRC_IRQ_HDLC_RX2	20
+#define	SRC_IRQ_ETH_TX0		21
+#define	SRC_IRQ_ETH_RX0		22
+#define	SRC_IRQ_ETH_TX1		23
+#define	SRC_IRQ_ETH_RX1		24
+#define	SRC_IRQ_DES		25
+#define	SRC_IRQ_GDMA0		26
+#define	SRC_IRQ_GDMA1		27
+#define	SRC_IRQ_GDMA2		28
+#define	SRC_IRQ_GDMA3		29
+#define	SRC_IRQ_GDMA4		30
+#define	SRC_IRQ_GDMA5		31
+#define	SRC_IRQ_TIMER0		32
+#define	SRC_IRQ_TIMER1		33
+#define	SRC_IRQ_TIMER2		34
+#define	SRC_IRQ_TIMER3		35
+#define	SRC_IRQ_TIMER4		36
+#define	SRC_IRQ_TIMER5		37
+#define	SRC_IRQ_TIMER_WD	38
+
+
+#define NR_INT_IRQS	32		/* Internal interrupt sources number */
+
+#define	INT_IRQ_IICC		0
+#define	INT_IRQ_HUART0_TX	1
+#define	INT_IRQ_HUART0_RX	2
+#define	INT_IRQ_HUART1_TX	3
+#define	INT_IRQ_HUART1_RX	4
+#define	INT_IRQ_CUART_TX	5
+#define	INT_IRQ_CUART_RX	6
+#define	INT_IRQ_USB		7
+#define	INT_IRQ_HDLC_TX0	8
+#define	INT_IRQ_HDLC_RX0	9
+#define	INT_IRQ_HDLC_TX1	10
+#define	INT_IRQ_HDLC_RX1	11
+#define	INT_IRQ_HDLC_TX2	12
+#define	INT_IRQ_HDLC_RX2	13
+#define	INT_IRQ_ETH_TX0		14
+#define	INT_IRQ_ETH_RX0		15
+#define	INT_IRQ_ETH_TX1		16
+#define	INT_IRQ_ETH_RX1		17
+#define	INT_IRQ_DES		18
+#define	INT_IRQ_GDMA0		19
+#define	INT_IRQ_GDMA1		20
+#define	INT_IRQ_GDMA2		21
+#define	INT_IRQ_GDMA3		22
+#define	INT_IRQ_GDMA4		23
+#define	INT_IRQ_GDMA5		24
+#define	INT_IRQ_TIMER0		25
+#define	INT_IRQ_TIMER1		26
+#define	INT_IRQ_TIMER2		27
+#define	INT_IRQ_TIMER3		28
+#define	INT_IRQ_TIMER4		29
+#define	INT_IRQ_TIMER5		30
+#define	INT_IRQ_TIMER_WD	31
+
+#define	MASK_IRQ_IICC		0x00000001
+#define	MASK_IRQ_HUART0_TX	0x00000002
+#define	MASK_IRQ_HUART0_RX	0x00000004
+#define	MASK_IRQ_HUART1_TX	0x00000008
+#define	MASK_IRQ_HUART1_RX	0x00000010
+#define	MASK_IRQ_CUART_TX	0x00000020
+#define	MASK_IRQ_CUART_RX	0x00000040
+#define	MASK_IRQ_USB		0x00000080
+#define	MASK_IRQ_HDLC_TX0	0x00000100
+#define	MASK_IRQ_HDLC_RX0	0x00000200
+#define	MASK_IRQ_HDLC_TX1	0x00000400
+#define	MASK_IRQ_HDLC_RX1	0x00000800
+#define	MASK_IRQ_HDLC_TX2	0x00001000
+#define	MASK_IRQ_HDLC_RX2	0x00002000
+#define	MASK_IRQ_ETH_TX0	0x00004000
+#define	MASK_IRQ_ETH_RX0	0x00008000
+#define	MASK_IRQ_ETH_TX1	0x00010000
+#define	MASK_IRQ_ETH_RX1	0x00020000
+#define	MASK_IRQ_DES		0x00040000
+#define	MASK_IRQ_GDMA0		0x00080000
+#define	MASK_IRQ_GDMA1		0x00100000
+#define	MASK_IRQ_GDMA2		0x00200000
+#define	MASK_IRQ_GDMA3		0x00400000
+#define	MASK_IRQ_GDMA4		0x00800000
+#define	MASK_IRQ_GDMA5		0x01000000
+#define	MASK_IRQ_TIMER0		0x02000000
+#define	MASK_IRQ_TIMER1		0x04000000
+#define	MASK_IRQ_TIMER2		0x08000000
+#define	MASK_IRQ_TIMER3		0x10000000
+#define	MASK_IRQ_TIMER4		0x20000000
+#define	MASK_IRQ_TIMER5		0x40000000
+#define	MASK_IRQ_TIMER_WD	0x80000000
+
+
+#define	NR_EXT_IRQS	7		/* External interrupt sources number */
+
+#define	EXT_IRQ_0		0
+#define	EXT_IRQ_1		1
+#define	EXT_IRQ_2		2
+#define	EXT_IRQ_3		3
+#define	EXT_IRQ_4		4
+#define	EXT_IRQ_5		5
+#define	EXT_IRQ_IOM2		6
+
+#define	MASK_IRQ_0		0x00000001
+#define	MASK_IRQ_1		0x00000002
+#define	MASK_IRQ_2		0x00000004
+#define	MASK_IRQ_3		0x00000008
+#define	MASK_IRQ_4		0x00000010
+#define	MASK_IRQ_5		0x00000020
+#define	MASK_IRQ_IOM2		0x00000040
+#define	MASK_IRQ_GLOBAL		0x80000000
+
+	
+#endif	/* __ASM_ARCH_IRQS_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-SMDK2500/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-SMDK2500/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,29 @@
+/*
+ * linux/include/asm-armnommu/arch-p52/memory.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * 2001 Mindspeed
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define TASK_SIZE	(0x01a00000UL)
+#define TASK_SIZE_26	TASK_SIZE
+
+#define PHYS_OFFSET	(DRAM_BASE)
+#define PAGE_OFFSET 	(PHYS_OFFSET)
+#define END_MEM     	(DRAM_BASE + DRAM_SIZE)
+
+#define __virt_to_phys(vpage) ((unsigned long) (vpage))
+#define __phys_to_virt(ppage) ((void *) (ppage))
+#define __virt_to_bus(vpage) ((unsigned long) (vpage))
+#define __bus_to_virt(ppage) ((void *) (ppage))
+
+
+#endif
+
+
+
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-SMDK2500/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/param.h
--- linux-2.4.29/include/asm-armnommu/arch-SMDK2500/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-SMDK2500/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/system.h
--- linux-2.4.29/include/asm-armnommu/arch-SMDK2500/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,21 @@
+/*
+ * linux/include/asm-armnommu/arch-p52/system.h
+ * 2001 Mindspeed
+ */
+
+static inline void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter)
+	  cpu_do_idle(IDLE_WAIT_SLOW);
+}
+
+extern inline void arch_reset(char mode)
+{
+	if (mode == 's') {
+		/* Jump into ROM at address 0 */
+		cpu_reset(0x80000000);
+	} /* tbd */
+	printk(KERN_ERR "Reboot mode '%c' not implemented\n", mode);
+}
+
+ 
diff -urN linux-2.4.29/include/asm-armnommu/arch-SMDK2500/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/time.h
--- linux-2.4.29/include/asm-armnommu/arch-SMDK2500/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/time.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,41 @@
+/*
+ * time.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ */
+
+#ifndef __ASM_ARCH_TIME_H
+#define __ASM_ARCH_TIME_H
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/timex.h>
+
+extern struct irqaction timer_irq;
+
+extern unsigned long s3c2500_gettimeoffset(void);
+extern void s3c2500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+extern __inline__ void setup_timer (void)
+{
+    volatile struct s3c2500_timer* tt = (struct s3c2500_timer*) (TIMER_BASE);
+    unsigned long v, tmp;
+
+    gettimeoffset     = s3c2500_gettimeoffset;
+    timer_irq.handler = s3c2500_timer_interrupt;
+    
+    /* I/O port is used for timer */
+    tmp = *(unsigned int *)IO_Ftn_cont1 | ((0x1 << KERNEL_TIMER) << 22);
+    *(unsigned int *)IO_Ftn_cont1 = tmp;
+
+    tt->td[2*KERNEL_TIMER] = (unsigned long)(ARM_CLK/HZ);
+    tmp = tt->tmr & ~(0x7 << (3*KERNEL_TIMER));
+    tt->tmr = tmp | (0x1 << (3*KERNEL_TIMER));
+    setup_arm_irq((KERNEL_TIMER+32), &timer_irq);
+    enable_irq ( (KERNEL_TIMER+32) );
+}
+
+#endif /* __ASM_ARCH_TIME_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-SMDK2500/timers.h linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/timers.h
--- linux-2.4.29/include/asm-armnommu/arch-SMDK2500/timers.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/timers.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+ * timers.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file includes the 32-bit timers definitions 
+ * of the S3C2500X RISC microcontroller
+ * based on the Samsung's "S3C2500X 32-bit RISC
+ * microcontroller pre. User's Manual"
+ */
+ 
+#ifndef __ASM_ARCH_TIMERS_H
+#define __ASM_ARCH_TIMERS_H
+
+#define	KERNEL_TIMER	0
+
+#define	TMOD		0xF0040000	/* Timer mode R		*/
+#define	IC		0xF0040004	/* Interrupt clear R 	*/
+#define	WDT		0xF0040008	/* Wathdog timer R 	*/
+#define TDATA0		0xF0040010	/* Timer 0 data R 	*/
+#define TCNT0		0xF0040014	/* Timer 0 counter R 	*/
+#define TDATA1		0xF0040018	/* Timer 1 data R 	*/
+#define TCNT1		0xF004001C	/* Timer 1 counter R 	*/
+#define TDATA2		0xF0040020	/* Timer 2 data R 	*/
+#define TCNT2		0xF0040024	/* Timer 2 counter R 	*/
+#define TDATA3		0xF0040028	/* Timer 3 data R 	*/
+#define TCNT3		0xF004002C	/* Timer 3 counter R 	*/
+#define TDATA4		0xF0040030	/* Timer 4 data R 	*/
+#define TCNT4		0xF0040034	/* Timer 4 counter R 	*/
+#define TDATA5		0xF0040038	/* Timer 5 data R 	*/
+#define TCNT5		0xF004003C	/* Timer 5 counter R 	*/
+
+#define TIMER_BASE 	TMOD
+
+#ifndef __ASSEMBLER__
+struct s3c2500_timer
+{
+  unsigned int tmr;
+  unsigned int ic;
+  unsigned int wdt;
+  unsigned int reserved;
+  unsigned int td[12];
+};
+#endif
+	
+#endif	/* __ASM_ARCH_TIMERS_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-SMDK2500/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-SMDK2500/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+ * timex.h:
+ * 2001 Mindspeed
+ */
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+#define CLOCK_TICK_RATE	   0x270f
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-SMDK2500/uart.h linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/uart.h
--- linux-2.4.29/include/asm-armnommu/arch-SMDK2500/uart.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/uart.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,165 @@
+/*
+ * uart.h 
+ *
+ * Copyright (C) 2002-2003 Arcturus Networks Inc.
+ *                         by Oleksandr Zhadan <www.ArcturusNetworks.com>
+ *
+ * This file includes the Serial I/O definitions 
+ * of the S3C2500X RISC microcontroller
+ * based on the Samsung's "S3C2500X 32-bit RISC
+ * microcontroller pre. User's Manual"
+ */
+ 
+#ifndef __ASM_ARCH_UART_H
+#define __ASM_ARCH_UART_H
+
+ /*
+ *	Console UART special registers
+*/
+#define CUCON		0xF0060000
+#define CUSTAT		0xF0060004
+#define CUINT		0xF0060008
+#define CUTXBUF		0xF006000C
+#define CURXBUF		0xF0060010
+#define CUBRD		0xF0060014
+#define CUCHAR1		0xF0060018
+#define CUCHAR2		0xF006001C
+
+ /*
+ *	High-speed UART special registers
+*/
+#define HUCON0		0xF0070000
+#define HUSTAT0		0xF0070004
+#define HUINT0		0xF0070008
+#define HUTXBUF0	0xF007000C
+#define HURXBUF0	0xF0070010
+#define HUBRD0		0xF0070014
+#define HUCHAR10	0xF0070018
+#define UUCHAR20	0xF007001C
+#define HUABB0		0xF0070100
+#define HUABT0		0xF0070104
+
+#define HUCON1		0xF0080000
+#define HUSTAT1		0xF0080004
+#define HUINT1		0xF0080008
+#define HUTXBUF1	0xF008000C
+#define HURXBUF1	0xF0080010
+#define HUBRD1		0xF0080014
+#define HUCHAR11	0xF0080018
+#define UUCHAR21	0xF008001C
+#define HUABB1		0xF0080100
+#define HUABT1		0xF0080104
+
+#define CUART_BASE 	CUCON
+#define HUART0_BASE 	HUCON0
+#define HUART1_BASE 	HUCON1
+
+
+#ifndef __ASSEMBLER__
+/****************************************  S3C2500 Samsung  UART registers */
+struct s3c2500_usart_regs{
+	unsigned int cr;		/* control		*/
+	unsigned int csr;		/* channel status	*/
+	unsigned int ier;		/* interrupt enable	*/
+	unsigned int thr;		/* tramsmit holding	*/
+	unsigned int rhr;		/* receive holding	*/
+	unsigned int brgr;		/* baud rate generator	*/
+	unsigned int ucc1;		/* contorl character 1	*/
+	unsigned int ucc2;		/* contorl character 2	*/
+};
+#endif
+
+/****************************************  UART control register */
+#define	U_DISABLE_TMODE	0xFFFFFFFC
+#define	U_IRQ_TMODE	0x00000001
+#define	U_GDMA_TMODE	0x00000002
+#define	U_TMODE		0x00000003
+
+#define	U_DISABLE_RMODE	0xFFFFFFF3
+#define	U_IRQ_RMODE	0x00000004
+#define	U_GDMA_RMODE	0x00000008
+#define	U_RMODE		0x0000000C
+
+#define	U_SBR		0x00000010
+#define	U_UCLK		0x00000020
+#define	U_AUBD		0x00000040
+#define	U_LOOPB		0x00000080
+
+#define	U_NO_PMD	0xFFFFF8FF
+#define	U_ODD_PMD	0x00000400
+#define	U_EVEN_PMD	0x00000500
+#define	U_FC1_PMD	0x00000600
+#define	U_FC0_PMD	0x00000700
+#define	U_PMD		0x00000700
+
+#define	U_STB		0x00000800
+
+#define	U_WL5		0xFFFFCFFF
+#define	U_WL6		0x00001000
+#define	U_WL7		0x00002000
+#define	U_WL8		0x00003000
+#define	U_WL		0x00003000
+
+#define	U_IR		0x00004000
+#define	U_TFEN		0x00010000
+#define	U_RFEN		0x00020000
+#define	U_TFRST		0x00040000
+#define	U_RFRST		0x00080000
+
+#define	U_TFTL30	0xFFCFFFFF
+#define	U_TFTL24	0x00100000
+#define	U_TFTL16	0x00200000
+#define	U_TFTL8		0x00300000
+#define	U_TFTL		0x00300000
+
+#define	U_RFTL1		0xFF3FFFFF
+#define	U_RFTL8		0x00400000
+#define	U_RFTL18	0x00800000
+#define	U_RFTL28	0x00C00000
+#define	U_RFTL		0x00C00000
+
+#define	U_DTR		0x01000000
+#define	U_RTS		0x02000000
+#define	U_HFEN		0x10000000
+#define	U_SFEN		0x20000000
+#define	U_ECHO		0x40000000
+#define	U_RTSRTR	0x80000000
+
+/****************************************  UART status register */
+#define	U_TFFUL		(1<<20)
+#define	U_TFEMT		(1<<19)
+#define	U_THE		(1<<18)
+#define	U_TI		(1<<17)
+#define	U_E_CTS		(1<<16)
+#define	U_CTS		(1<<15)
+#define	U_DSR		(1<<14)
+#define	U_E_RxTO	(1<<12)
+#define	U_RIDLE		(1<<11
+#define	U_RFOV		(1<<10)
+#define	U_RFFUL		(1<<9)
+#define	U_RFEMT		(1<<8)
+#define	U_RFREA		(1<<7)
+#define	U_DCD		(1<<6)
+#define	U_CCD		(1<<5)
+#define	U_OER		(1<<4)
+#define	U_PER		(1<<3)
+#define	U_FER		(1<<2)
+#define	U_BSD		(1<<1)
+#define	U_RDV		(1)
+
+/****************************************  UART Interrupt Enable register */
+#define	U_THEIE		(1<<18)
+#define	U_TIIE		(1<<17)
+#define	U_E_CTSIE	(1<<16)
+#define	U_E_RxTOIE	(1<<12)
+#define	U_OVFFIE	(1<<10)
+#define	U_RFREAIE	(1<<7)
+#define	U_DCDLIE	(1<<6)
+#define	U_CCDIE		(1<<5)
+#define	U_OERIE		(1<<4)
+#define	U_PERIE		(1<<3)
+#define	U_FERIE		(1<<2)
+#define	U_BSDIE		(1<<1)
+#define	U_RDVIE		(1)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-SMDK2500/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-SMDK2500/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-SMDK2500/vmalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ *  linux/include/asm-arm/arch-dsc21/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff -urN linux-2.4.29/include/asm-armnommu/arch-snds100/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-snds100/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,14 @@
+/*
+ * asm/arch-armnommu/arch-p52/dma.h:
+ * Mindspeed 2001
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+
+#define MAX_DMA_ADDRESS		0x01000000
+#define MAX_DMA_CHANNELS        13
+#define arch_dma_init(dma_chan)
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-snds100/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-snds100/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,292 @@
+/********************************************************/
+/*							*/
+/* Samsung KS32C4510b					*/
+/* Mac Wang <mac@os.nctu.edu.tw>			*/
+/*							*/
+/********************************************************/
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/*
+ * define S3C4510b CPU master clock
+ */
+#define MHz		1000000
+#define fMCLK_MHz	(50 * MHz)
+#define fMCLK		(fMCLK_MHz / MHz)
+#define MCLK2		(fMCLK_MHz / 2)
+
+/*
+ * ASIC Address Definition
+ */
+
+#define Base_Addr	0x3FF0000
+
+#define VPint	*(volatile unsigned int *)
+#define VPshort	*(volatile unsigned short *)
+#define VPchar	*(volatile unsigned char *)
+
+#ifndef CSR_WRITE
+#   define CSR_WRITE(addr,data)	(VPint(addr) = (data))
+#endif
+
+#ifndef CSR_READ
+#   define CSR_READ(addr)	(VPint(addr))
+#endif
+
+#ifndef CAM_Reg
+#   define CAM_Reg(x)		(VPint(CAMBASE+(x*0x4)))
+#endif
+
+/* ************************ */
+/* System Manager Registers */
+/* ************************ */
+#define SYSCFG		(Base_Addr+0x0000)
+#define CLKCON		(Base_Addr+0x3000)
+#define EXTACON0	(Base_Addr+0x3008)
+#define EXTACON1	(Base_Addr+0x300C)
+#define EXTDBWTH	(Base_Addr+0x3010)
+#define ROMCON0		(Base_Addr+0x3014)
+#define ROMCON1		(Base_Addr+0x3018)
+#define ROMCON2		(Base_Addr+0x301C)
+#define ROMCON3		(Base_Addr+0x3020)
+#define ROMCON4		(Base_Addr+0x3024)
+#define ROMCON5		(Base_Addr+0x3028)
+#define DRAMCON0	(Base_Addr+0x302C)
+#define DRAMCON1	(Base_Addr+0x3030)
+#define DRAMCON2	(Base_Addr+0x3034)
+#define DRAMCON3	(Base_Addr+0x3038)
+#define REFEXTCON	(Base_Addr+0x303C)
+
+/* *********************** */
+/* Ethernet BDMA Registers */
+/* *********************** */
+#define BDMATXCON	(Base_Addr+0x9000)
+#define BDMARXCON	(Base_Addr+0x9004)
+#define BDMATXPTR	(Base_Addr+0x9008)
+#define BDMARXPTR	(Base_Addr+0x900C)
+#define BDMARXLSZ	(Base_Addr+0x9010)
+#define BDMASTAT	(Base_Addr+0x9014)
+#define CAMBASE		(Base_Addr+0x9100)
+/*
+ * CAM		0x9100 ~ 0x917C
+ * BDMATXBUF	0x9200 ~ 0x92FC
+ * BDMARXBUF	0x9800 ~ 0x99FC
+ */
+
+/* ********************** */
+/* Ethernet MAC Registers */
+/* ********************** */
+#define MACON		(Base_Addr+0xA000)
+#define CAMCON		(Base_Addr+0xA004)
+#define MACTXCON	(Base_Addr+0xA008)
+#define MACTXSTAT	(Base_Addr+0xA00C)
+#define MACRXCON	(Base_Addr+0xA010)
+#define MACRXSTAT	(Base_Addr+0xA014)
+#define STADATA		(Base_Addr+0xA018)
+#define STACON		(Base_Addr+0xA01C)
+#define CAMEN		(Base_Addr+0xA028)
+#define EMISSCNT	(Base_Addr+0xA03C)
+#define EPZCNT		(Base_Addr+0xA040)
+#define ERMPZCNT	(Base_Addr+0xA044)
+#define EXTSTAT		(Base_Addr+0x9040)
+
+/* ************************ */
+/* HDLC Channel A Registers */
+/* ************************ */
+
+/* ************************ */
+/* HDLC Channel B Registers */
+/* ************************ */
+
+/* ******************* */
+/* I/O Ports Registers */
+/* ******************* */
+#define IOPMOD		(Base_Addr+0x5000)
+#define IOPCON		(Base_Addr+0x5004)
+#define IOPDATA		(Base_Addr+0x5008)
+
+/* ****************************** */
+/* Interrupt Controller Registers */
+/* ****************************** */
+#define INTMOD		(Base_Addr+0x4000)
+#define INTPND		(Base_Addr+0x4004)
+#define INTMSK		(Base_Addr+0x4008)
+#define INTPRI0		(Base_Addr+0x400C)
+#define INTPRI1		(Base_Addr+0x4010)
+#define INTPRI2		(Base_Addr+0x4014)
+#define INTPRI3		(Base_Addr+0x4018)
+#define INTPRI4		(Base_Addr+0x401C)
+#define INTPRI5		(Base_Addr+0x4020)
+#define INTOFFSET	(Base_Addr+0x4024)
+#define INTPNDTST	(Base_Addr+0x402C)
+#define INTOSET_FIQ	(Base_Addr+0x4030)
+#define INTOSET_IRQ	(Base_Addr+0x4034)
+
+#define IntMode		(VPint(INTMOD))
+#define IntPend		(VPint(INTPND))
+#define IntMask		(VPint(INTMSK))
+#define IntOffset	(VPint(INTOFFSET))
+#define IntPndTst	(VPint(INTPNDTST))
+#define IntOffset_FIQ	(VPint(INTOSET_FIQ))
+#define IntOffset_IRQ	(VPint(INTOSET_IRQ))
+
+#define INT_MODE_IRQ	0x000000
+#define INT_MODE_FIQ	0x1FFFFF
+#define INT_MASK_DIS	0x1FFFFF
+#define INT_MASK_ENA	0x000000
+
+#define INT_ENABLE(n)		IntMask &= ~(1<<(n))
+#define INT_DISABLE(n)		IntMask |= (1<<(n))
+#define CLEAR_PEND_INT(n)	IntPend = (1<<(n))
+#define SET_PEND_INT(n)		IntPndTst |= (1<<(n))
+
+/* ***************** */
+/* I2C Bus Registers */
+/* ***************** */
+
+/* ************** */
+/* GDMA Registers */
+/* ************** */
+
+/* ************** */
+/* UART Registers */
+/* ************** */
+
+#define DEBUG_CONSOLE	(0)
+
+#define ULCON0		(Base_Addr+0xD000)
+#define ULCON1		(Base_Addr+0xE000)
+#define UCON0		(Base_Addr+0xD004)
+#define UCON1		(Base_Addr+0xE004)
+#define USTAT0		(Base_Addr+0xD008)
+#define USTAT1		(Base_Addr+0xE008)
+#define UTXBUF0		(Base_Addr+0xD00C)
+#define UTXBUF1		(Base_Addr+0xE00C)
+#define URXBUF0		(Base_Addr+0xD010)
+#define URXBUF1		(Base_Addr+0xE010)
+#define UBRDIV0		(Base_Addr+0xD014)
+#define UBRDIV1		(Base_Addr+0xE014)
+
+#define UART_BASE0	ULCON0
+#define UART_BASE1	ULCON1
+
+#if DEBUG_CONSOLE == 0
+	#define DEBUG_TX_BUFF_BASE	UTXBUF0	
+	#define DEBUG_RX_BUFF_BASE	URXBUF0
+	#define DEBUG_UARTLCON_BASE	ULCON0
+	#define DEBUG_UARTCONT_BASE	UCON0
+	#define DEBUG_UARTBRD_BASE	UBRDIV0
+	#define DEBUG_CHK_STAT_BASE	USTAT0
+#elif DEBUG_CONSOLE == 1
+	#define DEBUG_TX_BUFF_BASE	UTXBUF1	
+	#define DEBUG_RX_BUFF_BASE	URXBUF1
+	#define DEBUG_UARTLCON_BASE	ULCON1
+	#define DEBUG_UARTCONT_BASE	UCON1
+	#define DEBUG_UARTBRD_BASE	UBRDIV1
+	#define DEBUG_CHK_STAT_BASE	USTAT1
+#endif
+
+#define DEBUG_ULCON_REG_VAL	(0x3)
+#define DEBUG_UCON_REG_VAL	(0x9)
+#define DEBUG_UBRDIV_REG_VAL	(0x500)
+#define DEBUG_RX_CHECK_BIT	(0X20)
+#define DEBUG_TX_CAN_CHECK_BIT	(0X40)
+#define DEBUG_TX_DONE_CHECK_BIT	(0X80)
+
+
+/* **************** */
+/* Timers Registers */
+/* **************** */
+#define TMOD		(Base_Addr+0x6000)
+#define TDATA0		(Base_Addr+0x6004)
+#define TDATA1		(Base_Addr+0x6008)
+#define TCNT0		(Base_Addr+0x600C)
+#define TCNT1		(Base_Addr+0x6010)
+
+/*******************/
+/* SYSCFG Register */
+/*******************/
+#define SYS_INIT_BASE	EXTDBWTH
+#define rSYSCFG		(0x87FFFF90)	/* disable Cache/Write buffer */
+
+/**********************************/
+/* System Memory Control Register */
+/**********************************/
+#define DSR0		(2<<0)	/* ROM Bank0 */
+#define DSR1		(0<<2)	/* 0: Disable, 1: Byte, 2: Half-Word, 3: Word */
+#define DSR2		(0<<4)
+#define DSR3		(0<<6)
+#define DSR4		(0<<8)
+#define DSR5		(0<<10)
+#define DSD0		(2<<12) /* RAM Bank0 */
+#define DSD1		(0<<14)
+#define DSD2		(0<<16)
+#define DSD3		(0<<18)
+#define DSX0		(0<<20)	/* EXTIO0 */
+#define DSX1		(0<<22)
+#define DSX2		(0<<24)
+#define DSX3		(0<<26)
+
+#define rEXTDBWTH	(DSR0|DSR1|DSR2|DSR3|DSR4|DSR5 | DSD0|DSD1|DSD2|DSD3 | DSX0|DSX1|DSX2|DSX3)
+
+/****************************************/
+/* ROMCON0: ROM Bank 0 Control Register */
+/****************************************/
+#define PMC0		(0x0<<0)	/*00: Normal ROM   01: 4 word page*/
+					/*10: 8 word page  11:16 word page*/
+#define tPA0		(0x0<<2)	/*00: 5 cycles     01: 2 cycles*/
+					/*10: 3 cycles     11: 4 cycles*/
+#define tACC0		(0x6<<4)	/*000: Disable bank 001: 2 cycles*/
+					/*010: 3 cycles     011: 4 cycles*/
+					/*110: 7 cycles     111: Reserved*/
+#define ROM_BASE0_R	((0x00000000>>16)<<10)
+#define ROM_NEXT0_R	((0x00200000>>16)<<20)
+#define ROM_BASE0_B	((0x01000000>>16)<<10)
+#define ROM_NEXT0_B	((0x01200000>>16)<<20)
+#define rROMCON0_R	(ROM_NEXT0_R|ROM_BASE0_R|tACC0|tPA0|PMC0)
+#define rROMCON0_B	(ROM_NEXT0_B|ROM_BASE0_B|tACC0|tPA0|PMC0)
+
+#define rROMCON1	0x0
+#define rROMCON2	0x0
+#define rROMCON3	0x0
+#define rROMCON4	0x0
+#define rROMCON5	0x0
+
+
+/********************************************/
+/* SDRAMCON0: SDRAM Bank 0 Control Register */
+/********************************************/
+#define StRC0		(0x1<<7)
+#define StRP0		(0x3<<8)
+#define SDRAM_BASE0_R	((0x01000000>>16)<<10)
+#define SDRAM_NEXT0_R	((0x01800000>>16)<<20)
+#define SDRAM_BASE0_B	((0x00000000>>16)<<10)
+#define SDRAM_NEXT0_B	((0x00800000>>16)<<20)
+#define SCAN0		(0x0<<30)
+#define rSDRAMCON0_R	(SCAN0|SDRAM_NEXT0_R|SDRAM_BASE0_R|StRP0|StRC0)
+#define rSDRAMCON0_B	(SCAN0|SDRAM_NEXT0_B|SDRAM_BASE0_B|StRP0|StRC0)
+
+#define rSDRAMCON1	0x0
+#define rSDRAMCON2	0x0
+#define rSDRAMCON3	0x0
+
+/************************************************/
+/* DRAM Refresh & External I/O Control Register */
+/************************************************/
+#define ExtIOBase	(0x360<<0)
+#define VSF		(0x1<<15)
+#define REN		(0x1<<16)
+#define tCHR		(0x0<<17)
+#define tCSR		(0x0<<20)
+#define RefCountValue	((2048+1-(16*fMCLK))<<21)
+#define rREFEXTCON	(RefCountValue|tCSR|tCHR|REN|VSF|ExtIOBase)
+
+/********/
+/* Misc */
+/********/
+
+#define HARD_RESET_NOW()
+#define TMOD_TIMER0_VAL	0x3	/* Timer0  TOGGLE, and Run */
+#define TAG_BASE	0x11000000
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-snds100/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/io.h
--- linux-2.4.29/include/asm-armnommu/arch-snds100/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ * linux/include/asm-armnommu/arch-dsc21/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ *  02-19-2001  gjm     Leveraged for armnommu/dsc21
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ * --gmcnutt
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * If we define __io then asm/io.h will take care of most of the inb & friends
+ * macros. It still leaves us some 16bit macros to deal with ourselves, though.
+ * We don't have PCI or ISA on the dsc21 so I dropped __mem_pci & __mem_isa.
+ * --gmcnutt
+ */
+#define PCIO_BASE 0
+#define __io(a) (PCIO_BASE + (a))
+#define __arch_getw(a) (*(volatile unsigned short *)(a))
+#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
+
+/*
+ * Defining these two gives us ioremap for free. See asm/io.h.
+ * --gmcnutt
+ */
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-snds100/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-snds100/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,38 @@
+/*
+ * asm/arch-samsung/irq.h:
+ * 2001 Mac Wang <mac@os.nctu.edu.tw>
+ */
+
+#ifndef __ASM_ARCH_IRQ_H__
+#define __ASM_ARCH_IRQ_H__
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irqs.h>
+
+#define fixup_irq(x) (x)
+
+extern void s3c4510b_mask_irq(unsigned int irq);
+extern void s3c4510b_unmask_irq(unsigned int irq);
+extern void s3c4510b_mask_ack_irq(unsigned int irq);
+extern void s3c4510b_int_init(void);
+
+static __inline__ void irq_init_irq(void)
+{
+	unsigned long flags;
+	int irq;
+
+	save_flags_cli(flags);
+	s3c4510b_int_init();
+	restore_flags(flags);
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= s3c4510b_mask_ack_irq;
+		irq_desc[irq].mask	= s3c4510b_mask_irq;
+		irq_desc[irq].unmask	= s3c4510b_unmask_irq;
+	}
+}
+#endif /* __ASM_ARCH_IRQ_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-snds100/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-snds100/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/irqs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ * asm/arch-samsung/irqs.h:
+ * Mac Wang <mac@os.nctu.edu.tw>
+ */
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+#define NR_IRQS		21
+#define VALID_IRQ(i)	(i<=8 ||(i>=16 && i<NR_IRQS))
+
+#define INT_EXTINT0	0
+#define INT_EXTINT1	1
+#define INT_EXTINT2	2
+#define INT_EXTINT3	3
+#define INT_UARTTX0	4
+#define INT_UARTRX0	5
+#define INT_UARTTX1	6
+#define INT_UARTRX1	7
+#define INT_GDMA0	8
+#define INT_GDMA1	9
+#define INT_TIMER0	10
+#define INT_TIMER1	11
+#define INT_HDLCTXA	12
+#define INT_HDLCRXA	13
+#define INT_HDLCTXB	14
+#define INT_HDLCRXB	15
+#define INT_BDMATX	16
+#define INT_BDMARX	17
+#define INT_MACTX	18
+#define INT_MACRX	19
+#define INT_IIC		20
+#define INT_GLOBAL	21
+
+#define IRQ_TIMER	INT_TIMER0
+
+#endif /* __ASM_ARCH_IRQS_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-snds100/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-snds100/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ * linux/include/asm-armnommu/arch-snds100/memory.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * 2001 Mindspeed
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <asm/page.h>
+
+#define TASK_SIZE	(0x01a00000UL)
+#define TASK_SIZE_26	TASK_SIZE
+
+#define PHYS_OFFSET	(DRAM_BASE)
+#define PAGE_OFFSET PHYS_OFFSET
+#define END_MEM     (DRAM_BASE + DRAM_SIZE)
+
+#define __virt_to_phys(vpage) ((unsigned long) (vpage))
+#define __phys_to_virt(ppage) ((void *) (ppage))
+#define __virt_to_bus(vpage) ((unsigned long) (vpage))
+#define __bus_to_virt(ppage) ((void *) (ppage))
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-snds100/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/param.h
--- linux-2.4.29/include/asm-armnommu/arch-snds100/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-snds100/processor.h linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/processor.h
--- linux-2.4.29/include/asm-armnommu/arch-snds100/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/processor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,15 @@
+/*
+ * uclinux/include/asm-armnommu/arch-atmel/mmu.h
+ *
+ */
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+#define EISA_bus 0
+#define EISA_bus__is_a_macro
+#define MCA_bus 0
+#define MCA_bus__is_a_macro
+
+#define TASK_SIZE (0x01a00000UL)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-snds100/serial.h linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/serial.h
--- linux-2.4.29/include/asm-armnommu/arch-snds100/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/serial.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,146 @@
+/*
+ * linux/include/asm/arch-samsung/serial.h
+ * 2001 Mac Wang <mac@os.nctu.edu.tw>
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <asm/arch/hardware.h>
+#include <asm/irq.h>
+
+#define RS_TABLE_SIZE	2
+#define BASE_BAUD	9600
+#define STD_COM_FLAGS	(ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+#define STD_SERIAL_PORT_DEFNS		\
+	/* UART CLK PORT IRQ FLAGS */	\
+	{ 0, BASE_BAUD, UART_BASE0, INT_UARTRX0, STD_COM_FLAGS },	/* ttyS0 */	\
+	{ 0, BASE_BAUD, UART_BASE1, INT_UARTRX1, STD_COM_FLAGS },	/* ttyS1 */
+#define EXTRA_SERIAL_PORT_DEFNS
+
+#define UART_LCR	0x00		/* Line Control Register	*/
+#define UART_IER	0x04		/* Global Control Register	*/
+#define UART_GCR	0x04		/* Global Control Register	*/
+#define UART_LSR	0x08		/* Line Status Reigster		*/
+#define UART_TX		0x0C		/* TX buffer Register		*/
+#define UART_RX		0x10		/* RX buffer Register		*/
+#define UART_BDR	0x14		/* Baudrate Divisor Reigster	*/
+
+#define UART_LSR_OE	0x01		// Overrun error
+#define UART_LSR_PE	0x02		// Parity error
+#define UART_LSR_FE	0x04		// Frame error
+#define UART_LSR_BI	0x08		// Break detect
+#define UART_LSR_DTR	0x10		// Data terminal ready
+#define UART_LSR_DR	0x20		// Receive data ready
+#define UART_LSR_THRE	0x40		// Transmit buffer register empty
+#define UART_LSR_TEMT	0x80		// Transmit complete
+
+#define UART_LCR_WLEN5	0x00
+#define UART_LCR_WLEN6	0x01
+#define UART_LCR_WLEN7	0x02
+#define UART_LCR_WLEN8	0x03
+#define UART_LCR_PARITY	0x20
+#define UART_LCR_NPAR	0x00
+#define UART_LCR_OPAR	0x20
+#define UART_LCR_EPAR	0x28
+#define UART_LCR_SPAR	0x10
+#define UART_LCR_SBC	0x40
+
+#define UART_GCR_RX_INT	0x01
+#define UART_GCR_TX_INT	0x08
+#define UART_GCR_RX_STAT_INT	0x04
+
+#define UART_IER_MSI
+#define UART_IER_RLSI	0x04
+#define UART_IER_THRI	0x08
+#define UART_IER_RDI	0x01
+	
+#define UART_MSR		0
+#define UART_MSR_DCD		0
+#define UART_MSR_RI		0
+#define UART_MSR_DSR		0
+#define UART_MSR_CTS		0
+#define UART_MSR_DDCD		0
+#define UART_MSR_TERI		0
+#define UART_MSR_DDSR		0
+#define UART_MSR_DCTS		0
+#define UART_MSR_ANY_DELTA	0
+
+#define PORT_S3C4510B	14
+
+struct serial_baudtable
+{
+	unsigned int baudrate;
+	unsigned int div;
+};
+
+struct serial_baudtable uart_baudrate[] =
+{
+	{  1200, 0x5150},
+	{  2400, 0x28A0},
+	{  4800, 0x1440},
+	{  9600, 0x0A20},
+	{ 19200, 0x0500},
+	{ 38400, 0x0280},
+	{ 57600, 0x01A0},
+	{115200, 0x00D0},
+	{230400, 0x0060},
+	{460860, 0x0020}
+};
+
+unsigned int baudrate_div(unsigned int baudrate)
+{
+	int i;
+	int len = sizeof(uart_baudrate)/sizeof(struct serial_baudtable);
+	for(i = 0; i < len; i++)
+		if(uart_baudrate[i].baudrate == baudrate)
+			return uart_baudrate[i].div;
+	return 0;
+}
+
+#define disable_uart_tx_interrupt(line)		\
+{						\
+	if(line) {				\
+		INT_DISABLE(INT_UARTTX1);	\
+		CLEAR_PEND_INT(INT_UARTTX1);	\
+	}					\
+	else {					\
+		INT_DISABLE(INT_UARTTX0);	\
+		CLEAR_PEND_INT(INT_UARTTX0);	\
+	}					\
+}
+
+#define disable_uart_rx_interrupt(line)		\
+{						\
+	if(line) {				\
+		INT_DISABLE(INT_UARTRX1);	\
+		CLEAR_PEND_INT(INT_UARTRX1);	\
+	}					\
+	else {					\
+		INT_DISABLE(INT_UARTRX0);	\
+		CLEAR_PEND_INT(INT_UARTRX0);	\
+	}					\
+}
+
+#define enable_uart_tx_interrupt(line)		\
+{						\
+	if(line) {				\
+		INT_ENABLE(INT_UARTTX1);	\
+		SET_PEND_INT(INT_UARTTX1);	\
+	}					\
+	else {					\
+		INT_ENABLE(INT_UARTTX0);	\
+		SET_PEND_INT(INT_UARTTX0);	\
+	}					\
+}
+
+#define enable_uart_rx_interrupt(line)		\
+{						\
+	if(line) {				\
+		INT_ENABLE(INT_UARTRX1);	\
+	}					\
+	else {					\
+		INT_ENABLE(INT_UARTRX0);	\
+	}					\
+}
+
+#endif /* __ASM_ARCH_SERIAL_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-snds100/shmparam.h linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/shmparam.h
--- linux-2.4.29/include/asm-armnommu/arch-snds100/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/shmparam.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-a5k/shmparam.h
+ *
+ * Copyright (c) 1996 Russell King.
+ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-snds100/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/system.h
--- linux-2.4.29/include/asm-armnommu/arch-snds100/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,18 @@
+/*
+ * linux/include/asm-armnommu/arch-dsc21/system.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * Copyright (c) 2001 RidgeRun, Inc (http://www.ridgerun.org)
+ *
+ */
+
+static inline void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter);
+}
+
+extern inline void arch_reset(char mode)
+{
+	/* REVISIT --gmcnutt */
+}
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-snds100/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/time.h
--- linux-2.4.29/include/asm-armnommu/arch-snds100/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/time.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ * linux/include/asm/arch-samsung/time.h
+ * 2001 Mac Wang <mac@os.nctu.edu.tw> 
+ */
+
+#ifndef __ASM_ARCH_TIME_H__
+#define __ASM_ARCH_TIME_H__
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/timex.h>
+
+extern struct irqaction timer_irq;
+
+extern unsigned long samsung_gettimeoffset(void);
+extern void samsung_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+
+void __inline__ setup_timer (void)
+{
+	CSR_WRITE(TCNT0, 0);
+	CSR_WRITE(TDATA0, CLOCK_TICK_RATE);
+	CSR_WRITE(TMOD, TMOD_TIMER0_VAL);
+
+	CLEAR_PEND_INT(IRQ_TIMER);
+	INT_ENABLE(IRQ_TIMER);
+	
+	timer_irq.handler = samsung_timer_interrupt;
+	setup_arm_irq(IRQ_TIMER, &timer_irq);
+}
+
+#endif /* __ASM_ARCH_TIME_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-snds100/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-snds100/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * timex.h:
+ * 2001 Mac Wang <mac@os.nctu.edu.tw> 
+ */
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+#include <asm/hardware.h>
+
+#define CLOCK_TICK_RATE	   (((fMCLK_MHz/100))*2)
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-snds100/uncompress.c linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/uncompress.c
--- linux-2.4.29/include/asm-armnommu/arch-snds100/uncompress.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/uncompress.c	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ * linux/include/asm/arch-samsung/uncompress.c
+ * 2001 Mac Wang <mac@os.nctu.edu.tw> 
+ */
+
+#include <asm/hardware.h>
+
+static int s3c4510b_decomp_setup()
+{
+	CSR_WRITE(DEBUG_UARTLCON_BASE, DEBUG_ULCON_REG_VAL);
+	CSR_WRITE(DEBUG_UARTCONT_BASE, DEBUG_UCON_REG_VAL);
+	CSR_WRITE(DEBUG_UARTBRD_BASE,  DEBUG_UBRDIV_REG_VAL);
+}
+
+static int s3c4510b_putc(char c)
+{
+	CSR_WRITE(DEBUG_TX_BUFF_BASE, c);
+	while(!(CSR_READ(DEBUG_CHK_STAT_BASE) & DEBUG_TX_DONE_CHECK_BIT));
+
+	if(c == '\n')
+		s3c4510b_putc('\r');
+}
+
+static void s3c4510b_puts(const char *s)
+{
+	while(*s != '\0')
+		s3c4510b_putc(*s++);
+}
diff -urN linux-2.4.29/include/asm-armnommu/arch-snds100/uncompress.h linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/uncompress.h
--- linux-2.4.29/include/asm-armnommu/arch-snds100/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/uncompress.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ * asm/arch/uncompress.c:
+ *         Optional routines to aid in debugging the decompression phase
+ *         of kernel boot.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <asm/arch/uncompress.c>
+/*
+ * This is used by arch/armnommu/boot/compressed/misc.c to write progress info
+ * out the serial port so that the user can see debug messages up to the point
+ * where the kernel is decompressed. The STANDALONE_DEBUG macro chooses between
+ * this and the standard printf. Punt.
+ * --gmcnutt
+ */
+#define puts(s)			s3c4510b_puts(s)
+
+/*
+ * Not sure what this is for. Probably an optional watchdog to check if the
+ * decompress got hung so we can warn the user. Punt.
+ */
+#define arch_decomp_wdog()
+
+/*
+ * If we need to do some setup prior to decompression (like initializing the
+ * UART if we want to use puts() above) then we define it here. Punt.
+ */
+#define arch_decomp_setup()	s3c4510b_decomp_setup()
diff -urN linux-2.4.29/include/asm-armnommu/arch-snds100/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-snds100/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-snds100/vmalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ *  linux/include/asm-arm/arch-dsc21/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/a.out.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/a.out.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/a.out.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * uclinux/include/asm-armnommu/arch-atmel/a.out.h
+ *
+ */
+#ifndef __ASM_ARCH_A_OUT_H
+#define __ASM_ARCH_A_OUT_H
+
+#ifdef __KERNEL__
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,63 @@
+/*
+ * asm/arch-armnommu/arch-dsc21/dma.h:
+ *         dsc21-specific macros for DMA support.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+/*
+ * MAX_DMA_ADDRESS -- max address we can program into the DMA address registers?
+ * Not sure. Various drivers use this value as a test before setting up a DMA.
+ * Also, the macros in linux/bootmem.h use this value as a goal for many of the
+ * bootmem allocations.
+ * Open questions:
+ * a) the DMA address register is only 26 bits -- does this limit us to this
+ *    section of memory, or can we only DMA in certain size chunks?
+ * b) can the ARM processor even directly program the DMA?
+ * I'm going to go out on a limb and assume that the DMA range is the first
+ * addresseable 26 bits.
+ * --gmcnutt
+ */
+#define MAX_DMA_ADDRESS		0x02000000
+
+/*
+ * MAX_DMA_CHANNELS -- # of DMA control register sets we possess. For the dsc21
+ * we have one that can run in either direction and between two different
+ * destinations.
+ * --gmcnutt
+ */
+#define MAX_DMA_CHANNELS        1
+
+/*
+ * arch_dma_init -- called by arch/armnommu/kernel/dma.c init_dma.
+ * Don't know what's needed here (if anything).
+ * --gmcnutt
+ */
+#define arch_dma_init(dma_chan)
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,149 @@
+/*
+ * linux/include/asm-arm/arch-trio/hardware.h
+ *
+ * Copyright (C) 1996 Russell King.
+ *
+ * This file contains the hardware definitions of the TI DSC21 series machines
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/* ARM clock rate (MHz) */
+#define DSC21_CLOCK_RATE     37125000
+
+/* external bus */
+#define DSC21_EXTBUS_RESET    0x00030a00
+#define DSC21_EXTBUS_MODE     0x00030a04
+#define DSC21_EXTBUS_INTEN    0x00030a08
+
+/* uarts (note that the register fields aren't needed by the standard linux
+   serial driver -- we only use them for our initial debugging console) */
+#define DSC21_UART0       0x00030380
+#define DSC21_UART0_DTRR  0x00030380
+#define DSC21_UART0_BRSR  0x00030382
+#define DSC21_UART0_MSR   0x00030384
+#define DSC21_UART0_RFCR  0x00030386
+#define DSC21_UART0_TFCR  0x00030388
+#define DSC21_UART0_LCR	  0x0003038a
+#define DSC21_UART0_SR 	  0x0003038c
+
+#define DSC21_UART1       0x00030400
+#define DSC21_UART1_DTRR  0x00030400
+#define DSC21_UART1_BRSR  0x00030402
+#define DSC21_UART1_MSR   0x00030404
+#define DSC21_UART1_RFCR  0x00030406
+#define DSC21_UART1_TFCR  0x00030408
+#define DSC21_UART1_LCR	  0x0003040a
+#define DSC21_UART1_SR 	  0x0003040c
+
+/* timers */
+#define DSC21_TIMER0_MODE    0x00030000
+#define DSC21_TIMER0_SEL     0x00030002
+#define DSC21_TIMER0_SCAL    0x00030004
+#define DSC21_TIMER0_DIV     0x00030006
+#define DSC21_TIMER0_TRG     0x00030008
+#define DSC21_TIMER0_CNT     0x0003000a
+
+#define DSC21_TIMER1_MODE    0x00030080
+#define DSC21_TIMER1_SEL     0x00030082
+#define DSC21_TIMER1_SCAL    0x00030084
+#define DSC21_TIMER1_DIV     0x00030086
+#define DSC21_TIMER1_TRG     0x00030088
+#define DSC21_TIMER1_CNT     0x0003008a
+
+#define DSC21_TIMER2_MODE    0x00030100
+#define DSC21_TIMER2_SEL     0x00030102
+#define DSC21_TIMER2_SCAL    0x00030104
+#define DSC21_TIMER2_DIV     0x00030106
+#define DSC21_TIMER2_TRG     0x00030108
+#define DSC21_TIMER2_CNT     0x0003010a
+
+#define DSC21_TIMER3_MODE    0x00030180
+#define DSC21_TIMER3_SEL     0x00030182
+#define DSC21_TIMER3_SCAL    0x00030184
+#define DSC21_TIMER3_DIV     0x00030186
+#define DSC21_TIMER3_TRG     0x00030188
+#define DSC21_TIMER3_CNT     0x0003018a
+
+/* interrupt */
+#define DSC21_FIQ_STATUS     0x00030580
+#define DSC21_IRQ0_STATUS    0x00030582
+#define DSC21_IRQ1_STATUS    0x00030584
+#define DSC21_FIQ_ENABLE     0x000305a0
+#define DSC21_IRQ0_ENABLE    0x000305a2
+#define DSC21_IRQ1_ENABLE    0x000305a4
+
+
+/*
+ * HARD_RESET_NOW -- used in blkmem.c. Should call arch_hard_reset(), but I 
+ * don't appear to have one ;).
+ * --gmcnutt
+ */
+#define HARD_RESET_NOW()
+
+
+/* reference */
+/////////////////////////////////////////////////
+//
+//	register and SDRAM map
+//
+//  (c) VSA/TITRDC   06/1999
+//
+/////////////////////////////////////////////////
+
+// memory mapped registers
+#define TIMER0_REGISTER_BASE    0x00030000		// timer0
+#define TIMER1_REGISTER_BASE	0x00030080		// timer1
+#define TIMER2_REGISTER_BASE	0x00030100		// timer2
+#define TIMER3_REGISTER_BASE	0x00030180		// timer3
+#define SERIAL0_REGISTER_BASE	0x00030200		// serial0
+#define SERIAL1_REGISTER_BASE	0x00030280		// serial1
+#define WDT_REGISTER_BASE	0x00030300		// watch dog timer
+#define UART0_REGISTER_BASE	0x00030380		// UART0
+#define UART1_REGISTER_BASE	0x00030400		// UART0
+#define USB_REGISTER_BASE	0x00030480		// USB
+#define IRDA_REGISTER_BASE	0x00030500		// IrDA
+#define INTCTRL_REGISTER_BASE	0x00030580		// INTC
+#define GIO_REGISTER_BASE	0x00030600		// GIO
+#define OSD_REGISTER_BASE	0x00030680		// OSD
+#define DSPC_REGISTER_BASE	0x00030700		// DSP controller
+#define CCDC_REGISTER_BASE	0x00030780		// CCD controller
+#define PREVIEW_REGISTER_BASE	0x00030800		// preview engine
+#define BURSTC_REGISTER_BASE	0x00030880		// burst mode compression
+#define VIDEOENC_REGISTER_BASE	0x00030900		// NTSC/PAL encoder
+#define SDRAMC_REGISTER_BASE	0x00030980		// SDRAM controller
+#define EXBC_REGISTER_BASE	0x00030A00		// external bus controller
+#define CLOCKC_REGISTER_BASE	0x00030A80		// clock controller
+#define BUSC_REGISTER_BASE	0x00030B00		// bus controller
+#define DMAIF_REGISTER_BASE	0x00030B80		// external bus DMA I/F
+
+// DSPRAM
+#define DSPRAM_BASE         0x00100000  // DSPRAM base address
+
+
+// SDRAM address (real byte address)
+#define SDRAM_BASE          0x08000000  // sdram base address
+#define SDRAM_SIZE          0x01000000  // hard-code 16MB for now
+#define SDRAM_PREVIEW       0x00000000  // output from preview engine
+#define SDRAM_RAWDATA       0x00100000  // output from CCDC
+#define SDRAM_WORK1         0x00100000  // WORK area #1 for burst-capture & decoded data
+#define SDRAM_WORK2         0x00500000  // WORK area #2 for burst-capture & decoded data
+#define SDRAM_ENCODED1      0x00900000  // work area #1 for encoded data
+#define SDRAM_ENCODED2      0x00B00000  // work area #2 for encoded data
+#define SDRAM_BURSTDATA     0x00B00000  // BURST-compressed data start address
+#define SDRAM_BURSTDATA_END 0x00EFFFFF  // BURST-compressed data end address
+#define SDRAM_OSD           0x00F00000  // OSD bitmap start address
+
+// CARD map (tentative)
+#define CARD_BASE           0x04000000		// CFC card base address
+#define CARD_ENCODED_START	0x00000800		// encoded image start address
+#define CARD_ENCODED_SLOT_SIZE	0x00044000		// encoded image slot size
+
+// IRQ defines  (Offset listed in register document is in words, so double offset)
+#define IRQ0_STATUS (INTCTRL_REGISTER_BASE + 0x02)
+#define IRQ1_STATUS (INTCTRL_REGISTER_BASE + 0x04)
+#define IRQ0_ENABLE (INTCTRL_REGISTER_BASE + 0x22)
+#define IRQ1_ENABLE (INTCTRL_REGISTER_BASE + 0x24)
+
+#endif  /* _ASM_ARCH_HARDWARE_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/ide.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/ide.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/ide.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,45 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/ide.h
+ *
+ * Copyright (c) 1998 Hugo Fiennes & Nicolas Pitre
+ *
+ * 18-aug-2000: Cleanup by Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
+ *              Get rid of the special ide_init_hwif_ports() functions
+ *              and make a generalised function that can be used by all
+ *              architectures.
+ */
+
+#include <linux/config.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+
+/*
+ * Set up a hw structure for a specified data port, control port and IRQ.
+ * This should follow whatever the default interface uses.
+ */
+static __inline__ void
+ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int *irq)
+{
+#ifdef CONFIG_REVISIT
+#error Not sure what to do for ide_init_hwif_ports
+#endif
+}
+
+
+
+
+/*
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ */
+static __inline__ void
+ide_init_default_hwifs(void)
+{
+#ifdef CONFIG_REVISIT
+#error Not sure what to do for ide_init_default_hwifs
+#endif
+}
+
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/io.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ * linux/include/asm-armnommu/arch-dsc21/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ *  02-19-2001  gjm     Leveraged for armnommu/dsc21
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ * --gmcnutt
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * If we define __io then asm/io.h will take care of most of the inb & friends
+ * macros. It still leaves us some 16bit macros to deal with ourselves, though.
+ * We don't have PCI or ISA on the dsc21 so I dropped __mem_pci & __mem_isa.
+ * --gmcnutt
+ */
+#define PCIO_BASE 0
+#define __io(a) (PCIO_BASE + (a))
+#define __arch_getw(a) (*(volatile unsigned short *)(a))
+#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
+
+/*
+ * Defining these two gives us ioremap for free. See asm/io.h.
+ * --gmcnutt
+ */
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,66 @@
+/*
+ * irq.h:
+ *         dsc21-specific IRQ setup.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_ARCH_IRQ_H__
+#define __ASM_ARCH_IRQ_H__
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/irqs.h>
+
+#define fixup_irq(x) (x)
+
+extern void dsc21_mask_irq(unsigned int irq);
+extern void dsc21_unmask_irq(unsigned int irq);
+extern void dsc21_mask_ack_irq(unsigned int irq);
+
+static __inline__ void irq_init_irq(void)
+{
+	int irq;
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= dsc21_mask_ack_irq;
+		irq_desc[irq].mask	= dsc21_mask_irq;
+		irq_desc[irq].unmask	= dsc21_unmask_irq;
+	}
+
+	/* clear all status */
+	outw(0xffff, DSC21_IRQ0_STATUS);
+	outw(0xffff, DSC21_IRQ1_STATUS);
+    
+	/* disable all */
+	outw(0, DSC21_FIQ_ENABLE);
+	outw(0, DSC21_IRQ0_ENABLE);
+	outw(0, DSC21_IRQ1_ENABLE);
+}
+
+#endif /* __ASM_ARCH_IRQ_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/irqs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,75 @@
+/*
+ * irqs.h:
+ *         IRQ numbers for the dsc21.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+
+/* irq #s */
+#define DSC21_IRQ_EXT0    0x00
+#define DSC21_IRQ_EXT1    0x01
+#define DSC21_IRQ_EXT2    0x02
+#define DSC21_IRQ_EXT3    0x03
+#define DSC21_IRQ_EXT4    0x04
+#define DSC21_IRQ_EXT5    0x05
+#define DSC21_IRQ_EXT6    0x06
+#define DSC21_IRQ_EXT7    0x07
+#define DSC21_IRQ_DMA     0x08
+#define DSC21_IRQ_FLASH   0x09
+#define DSC21_IRQ_IRDA_RX 0x0a
+#define DSC21_IRQ_IRDA_TX 0x0b
+#define DSC21_IRQ_TIMER0  0x10
+#define DSC21_IRQ_TIMER1  0x11
+#define DSC21_IRQ_TIMER2  0x12
+#define DSC21_IRQ_TIMER3  0x13
+#define DSC21_IRQ_CCDVD0  0x14
+#define DSC21_IRQ_CCDVD1  0x15
+#define DSC21_IRQ_CCDVD2  0x16
+#define DSC21_IRQ_ENCVD   0x17
+#define DSC21_IRQ_SERIAL0 0x18
+#define DSC21_IRQ_SERIAL1 0x19
+#define DSC21_IRQ_DSP     0x1a
+#define DSC21_IRQ_UART0   0x1b
+#define DSC21_IRQ_UART1   0x1c
+#define DSC21_IRQ_USB     0x1d
+#define DSC21_IRQ_BURST   0x1e
+#define DSC21_IRQ_CARD    0x1f
+#define DSC21_IRQ_EXB     0x1f /* conflict? */
+
+#define NR_IRQS           (DSC21_IRQ_EXB + 1)
+
+/* alias */
+#define IRQ_TIMER         DSC21_IRQ_TIMER0
+
+/* flags for request_irq() */
+#define IRQ_FLG_LOCK      (0x0001)  /* handler is not replaceable   */
+#define IRQ_FLG_REPLACE   (0x0002)  /* replace existing handler     */
+#define IRQ_FLG_FAST      (0x0004)
+#define IRQ_FLG_SLOW      (0x0008)
+#define IRQ_FLG_STD       (0x8000)  /* internally used              */
+
+#endif /* __ASM_ARCH_IRQS_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/keyboard.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/keyboard.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/keyboard.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ *  linux/include/asm-arm/arch-ti926/keyboard.h
+ *
+ *  Copyright (C) 2000 RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Keyboard driver definitions for ARM
+ */
+#ifndef __ASM_ARM_ARCH_TI925_KEYBOARD_H
+#define __ASM_ARM_ARCH_TI925_KEYBOARD_H
+
+#if 0
+#define kbd_request_region
+#define kbd_write_command
+#define kbd_write_output
+#define kbd_read_status
+#define kbd_read_input
+#define aux_request_irq
+#define aux_free_irq
+#endif
+
+/*
+ * Required by drivers/char/keyboard.c. I took these from arch-arc.
+ * --gmcnutt
+ */
+#define kbd_setkeycode(sc,kc) (-EINVAL)
+#define kbd_getkeycode(sc) (-EINVAL)
+#define kbd_translate(sc,kcp,rm) ({ *(kcp) = (sc); 1; })
+#define kbd_unexpected_up(kc) (0200)
+#define kbd_leds(leds)
+#define kbd_init_hw()
+#define kbd_enable_irq() /* what irq? ;) --gmcnutt */
+#define kbd_disable_irq()
+
+
+#endif /* __ASM_ARM_ARCH_TI925_KEYBOARD_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,57 @@
+/*
+ * linux/include/asm-armnommu/arch-spipe/memory.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * Copyright (c) 2001 RidgeRun <www.ridgerun.com>
+ *
+ * 02/19/2001  Gordon McNutt  Leveraged for the dsc21.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+
+/*
+ * These are used in the fault handling code (even for nommu) and various other
+ * macros. The current value comes from Steve Johnson's 2.0.38 uClinux port for
+ * the dsc21.
+ * --gmcnutt
+ */
+#define TASK_SIZE	(0x01a00000UL)
+#define TASK_SIZE_26	TASK_SIZE
+
+
+/*
+ * The start of physical memory. For the dsc21 this is the first SDRAM address.
+ * This value is used in the arch-specific bootup code like setup_arch &
+ * bootmem_init. By default we assume that we have one block of contiguous
+ * memory (a node) that starts here and runs MEM_SIZE long (see below). By 
+ * default the ARM bootup code sets MEM_SIZE to be 16MB  which is just right for
+ * us (see arch/armnommu/kernel/setup.c).
+ *
+ * NOTE:   I don't really use the start of SDRAM. Instead I reserve some pages
+ *         of SDRAM for some of the kernel sections (like .data & .bss). The
+ *         linker script has been modified to mark the first unreservered page
+ *         as _end_kernel (see arch/armnommu/vmlinux-armv.lds.in).
+ *         
+ * --gmcnutt
+ */
+extern int _end_kernel;
+#define PHYS_OFFSET	((unsigned long) &_end_kernel)
+//0x08000000
+
+/*
+ * PAGE_OFFSET -- the first address of the first page of memory. For archs with
+ * no MMU this corresponds to the first free page in physical memory (aligned
+ * on a page boundary).
+ * --gmcnutt
+ */
+#define PAGE_OFFSET  PHYS_OFFSET
+
+
+#define __virt_to_phys(vpage) ((unsigned long) (vpage))
+#define __phys_to_virt(ppage) ((void *) (ppage))
+#define __virt_to_bus(vpage) ((unsigned long) (vpage))
+#define __bus_to_virt(ppage) ((void *) (ppage))
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/param.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/pcmcia.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/pcmcia.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/pcmcia.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/pcmcia.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,3 @@
+#ifdef CONFIG_REVISIT
+#error Do we need PCMCIA support?
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/processor.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/processor.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/processor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,15 @@
+/*
+ * uclinux/include/asm-armnommu/arch-atmel/mmu.h
+ *
+ */
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+#define EISA_bus 0
+#define EISA_bus__is_a_macro
+#define MCA_bus 0
+#define MCA_bus__is_a_macro
+
+#define TASK_SIZE (0x01a00000UL)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/serial.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/serial.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/serial.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,135 @@
+/*
+ *  linux/include/asm-arm/arch-arc/serial.h
+ *
+ *  Copyright (C) 1996 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Changelog:
+ *   15-10-1996	RMK	Created
+ *   04-04-1998	PJB	Merged `arc' and `a5k' architectures
+ *   02-28-2001 GJM     Modified for dsc21
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/irqs.h>
+
+/* setup */
+#define BASE_BAUD      (DSC21_CLOCK_RATE / 16)
+#define STD_COM_FLAGS  (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+#define RS_TABLE_SIZE  2
+#define STD_SERIAL_PORT_DEFNS \
+	{  \
+	magic: 0, \
+        baud_base: BASE_BAUD, \
+	port: 0, \
+	irq: DSC21_IRQ_UART0, \
+	flags: STD_COM_FLAGS, \
+	type: PORT_UNKNOWN, \
+	iomem_base: (u8*)DSC21_UART0, \
+	iomem_reg_shift: 1, \
+	io_type: SERIAL_IO_MEM \
+	},	/* ttyS0 */ \
+	{  \
+	magic: 0, \
+        baud_base: BASE_BAUD, \
+	port: 0, \
+	irq: DSC21_IRQ_UART1, \
+	flags: STD_COM_FLAGS, \
+	type: PORT_UNKNOWN, \
+	iomem_base: (u8*)DSC21_UART1, \
+	iomem_reg_shift: 1, \
+	io_type: SERIAL_IO_MEM \
+	}	/* ttyS1 */ 
+#define EXTRA_SERIAL_PORT_DEFNS
+
+
+/* registers */
+#define UART_DTRR  0  /* Data Transmission/Reception Register */
+#define UART_BRSR  1  /* Bit Rate Set Register */
+#define UART_MSR   2  /* Mode Set Register */
+#define UART_RFCR  3  /* Reception FIFO Control Register */
+#define UART_TFCR  4  /* Transmission FIFO Control Register */
+#define UART_LCR   5  /* Line Control Register */
+#define UART_SR    6  /* Status Register */
+
+/* bitmasks */
+#define UART_MSR_CLS    0x0001    // Character length select (1=7bit, 0=8bit)
+#define UART_MSR_RSVD0  0x0002    // Reserved
+#define UART_MSR_SBLD   0x0004    // Stop bit length select (1=2bits, 0=1bit)
+#define UART_MSR_PSB 	0x0008	  // Parity select bit (1=odd, 0=even)
+#define UART_MSR_PEB    0x0010	  // Parity enable bit (1=enable, 0=disable)
+#define UART_MSR_TFTIE  0x4000    // Transmission FIFO trigger interrupt enable
+#define UART_MSR_RFTIE  0x8000    // Reception FIFO trigger interrupt enable
+#define UART_MSR_INTS   0xfc00    // All interrupt bits
+#define UART_MSR_MODE_BITS 0x001f // data length, stop & parity
+
+#define UART_SR_TREF    0x0001    // Transmission register empty flag
+#define UART_SR_TFEF    0x0002    // Transmission FIFO empty flag
+#define UART_SR_RFNEF   0x0004    // Reception FIFO not empty flag
+#define UART_SR_RSVD0   0x00f8    // Reserved
+#define UART_SR_TOIF    0x0100    // Time out interrupt flag
+#define UART_SR_RFER    0x0200    // Reception FIFO error flag
+#define UART_SR_TFTI    0x0400    // Transmission FIFO trigger indicator
+#define UART_SR_RFTI    0x0800    // Reception FIFO trigger indicator
+#define UART_SR_RSVD1   0xf000    // Reserved
+
+#define UART_LCR_BOC    0x0100    // Break output control (1=send break)
+
+#define UART_FCR_FTL1   0x0000    /* FIFO trigger level 1 byte */
+#define UART_FCR_FTL4   0x0100    /* FIFO trigger level 4 bytes */
+#define UART_FCR_FTL8   0x0200    /* FIFO trigger level 8 bytes */
+#define UART_FCR_FTL16  0x0300    /* FIFO trigger level 16 bytes */
+#define UART_FCR_FTL24  0x0400    /* FIFO trigger level 24 bytes */
+#define UART_FCR_FTL32  0x0500    /* FIFO trigger level 32 bytes */
+
+struct dsc21_async_struct {
+	int			magic;
+	unsigned long		port;
+	int			flags;
+	int			xmit_fifo_size;
+	struct serial_state	*state;
+	struct tty_struct 	*tty;
+	int			timeout;
+	int			quot;
+	int			x_char;	/* xon/xoff character */
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	u16			MSR; 	/* Interrupt Enable Register */
+	u16			LCR; 	/* Line control register */
+	u16                     RFCR;
+	u16                     TFCR;
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+ 	struct circ_buf		xmit;
+ 	spinlock_t		xmit_lock;
+	u8			*iomem_base;
+	u16			iomem_reg_shift;
+	int			io_type;
+	struct tq_struct	tqueue;
+#ifdef DECLARE_WAITQUEUE
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+	wait_queue_head_t	delta_msr_wait;
+#else	
+	struct wait_queue	*open_wait;
+	struct wait_queue	*close_wait;
+	struct wait_queue	*delta_msr_wait;
+#endif	
+	struct dsc21_async_struct *next_port;
+	struct dsc21_async_struct *prev_port;
+	
+};
+
+
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/shmparam.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/shmparam.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/shmparam.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-a5k/shmparam.h
+ *
+ * Copyright (c) 1996 Russell King.
+ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/system.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,18 @@
+/*
+ * linux/include/asm-armnommu/arch-dsc21/system.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * Copyright (c) 2001 RidgeRun, Inc (http://www.ridgerun.org)
+ *
+ */
+
+static inline void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter);
+}
+
+extern inline void arch_reset(char mode)
+{
+	/* REVISIT --gmcnutt */
+}
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/time.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/time.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,64 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/time.h
+ *
+ * Copyright (C) 1998 Deborah Wallach.
+ * Twiddles  (C) 1999 	Hugo Fiennes <hugo@empeg.com>
+ * 
+ * 2000/03/29 (C) Nicolas Pitre <nico@cam.org>
+ *	Rewritten: big cleanup, much simpler, better HZ acuracy.
+ *
+ * 2001/02/20 (C) RidgeRun, Inc (http://www.ridgerun.com)
+ *      Leveraged for the dsc21
+ */
+#ifndef __ASM_ARCH_TIME_H__
+#define __ASM_ARCH_TIME_H__
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+extern struct irqaction timer_irq;
+
+extern unsigned long dsc21_gettimeoffset(void);
+extern void dsc21_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+void __inline__ setup_timer (void)
+{
+	/* disable */
+	outw(0, DSC21_TIMER0_MODE);
+	outw(0, DSC21_TIMER1_MODE);
+	outw(0, DSC21_TIMER2_MODE);
+	outw(0, DSC21_TIMER3_MODE);
+
+	/*
+	 * System clock formula:
+	 *         freq = clock / (div * scale)
+	 * Where:
+	 *         clock = 27MHz
+	 *         div   = 27,000
+	 *         scale = 10
+	 *
+	 * Which gives us 100Hz, as desired.
+	 */
+
+	/* 27MHz clock (not ARM clock) */
+	outw(1, DSC21_TIMER0_SEL);
+	
+	/* prescale 10 */
+	outw(9, DSC21_TIMER0_SCAL);
+	
+	/* div 27000 */
+	outw(26999, DSC21_TIMER0_DIV);
+	
+	/* periodic */
+	outw(2, DSC21_TIMER0_MODE);
+
+
+	gettimeoffset = dsc21_gettimeoffset;	
+	timer_irq.handler = dsc21_timer_interrupt;
+	setup_arm_irq(IRQ_TIMER, &timer_irq);
+    
+}
+
+
+#endif /* __ASM_ARCH_TIME_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ * timex.h:
+ *         System clock frequency.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+/*
+ * CLOCK_TICK_RATE -- frequency fed to the timer. In our case, 27MHz. Used to
+ * compute LATCH. LATCH is the number of clock ticks per timer interrupt.
+ * (See linux/timex.h, armnommu/mach-dsc21/time.c).
+ */
+#define CLOCK_TICK_RATE	   27000000
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/uncompress.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/uncompress.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/uncompress.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ * asm/arch/uncompress.c:
+ *         Optional routines to aid in debugging the decompression phase
+ *         of kernel boot.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * This is used by arch/armnommu/boot/compressed/misc.c to write progress info
+ * out the serial port so that the user can see debug messages up to the point
+ * where the kernel is decompressed. The STANDALONE_DEBUG macro chooses between
+ * this and the standard printf. Punt.
+ * --gmcnutt
+ */
+#define puts(s)
+
+/*
+ * Not sure what this is for. Probably an optional watchdog to check if the
+ * decompress got hung so we can warn the user. Punt.
+ */
+#define arch_decomp_wdog()
+
+/*
+ * If we need to do some setup prior to decompression (like initializing the
+ * UART if we want to use puts() above) then we define it here. Punt.
+ */
+#define arch_decomp_setup()
diff -urN linux-2.4.29/include/asm-armnommu/arch-spipe/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-spipe/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-spipe/vmalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ *  linux/include/asm-arm/arch-dsc21/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-swarm/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-swarm/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,63 @@
+/*
+ * asm/arch-armnommu/arch-swarm/dma.h:
+ *   swarm-specific macros for DMA support.
+ * 09 Sep 2001 - C Hanish Menon [www.hanishkvc.com]
+ *   - Copied the file from dsc21 to swarm
+ *   - Have to verify and update has required later
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+/*
+ * MAX_DMA_ADDRESS -- max address we can program into the DMA address registers?
+ * Not sure. Various drivers use this value as a test before setting up a DMA.
+ * Also, the macros in linux/bootmem.h use this value as a goal for many of the
+ * bootmem allocations.
+ * Open questions:
+ * a) the DMA address register is only 26 bits -- does this limit us to this
+ *    section of memory, or can we only DMA in certain size chunks?
+ * b) can the ARM processor even directly program the DMA?
+ * I'm going to go out on a limb and assume that the DMA range is the first
+ * addresseable 26 bits.
+ * --gmcnutt
+ */
+#define MAX_DMA_ADDRESS		0x02000000
+
+/*
+ * MAX_DMA_CHANNELS -- # of DMA control register sets we possess. For the dsc21
+ * we have one that can run in either direction and between two different
+ * destinations.
+ * --gmcnutt
+ */
+#define MAX_DMA_CHANNELS        1
+
+/*
+ * arch_dma_init -- called by arch/armnommu/kernel/dma.c init_dma.
+ * Don't know what's needed here (if anything).
+ * --gmcnutt
+ */
+#define arch_dma_init(dma_chan)
+
+#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-swarm/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-swarm/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,54 @@
+/*
+ * linux/include/asm-armnommu/arch-swarm/hardware.h
+ *
+ * Copyright (C) 1996 Russell King.
+ * 09 Sep 2001 - C Hanish Menon [www.hanishkvc.com]
+ *   - Copied for armnommu/swarm and updated has required
+ *   
+ * This file contains the hardware definitions of the SWARM Emulator
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/* ARM clock rate (MHz) */
+#define SWARM_CLOCK_RATE     00010000
+
+/* uarts (note that the register fields aren't needed by the standard linux
+   serial driver -- we only use them for our initial debugging console) */
+#define SWARM_UART0_BASE     0x90081000
+#define SWARM_UART0_TXBASE   0x90081000
+#define SWARM_UART0_RXBASE   0x90081004
+#define SWARM_UART0_CR       0x90081008
+#define SWARM_UART0_SR       0x9008100c
+
+/* timers */
+#define SWARM_TIMER_BASE     0x90000000
+#define SWARM_TIMER_MATCH0   0x90000000
+#define SWARM_TIMER_MATCH1   0x90000004
+#define SWARM_TIMER_MATCH2   0x90000008
+#define SWARM_TIMER_MATCH3   0x9000000c
+#define SWARM_TIMER_CNT      0x90000010
+#define SWARM_TIMER_STATUS   0x90000014
+#define SWARM_TIMER_WDOG     0x90000018
+#define SWARM_TIMER_INTEN    0x9000001C
+
+#define SWARM_TIMER_SYS_COUNT 400000
+
+/* interrupt */
+#define SWARM_INT_BASE       0x90050000
+#define SWARM_INT_IRQ_STATUS 0x90050000
+#define SWARM_INT_MASK       0x90050004
+#define SWARM_INT_LEVEL      0x90050008
+#define SWARM_INT_FIQ_STATUS 0x9005000c
+
+/*
+ * HARD_RESET_NOW -- used in blkmem.c. Should call arch_hard_reset(), but I 
+ * don't appear to have one ;).
+ * --gmcnutt
+ */
+#define HARD_RESET_NOW()
+
+
+#endif  /* _ASM_ARCH_HARDWARE_H */
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-swarm/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/io.h
--- linux-2.4.29/include/asm-armnommu/arch-swarm/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,41 @@
+/*
+ * linux/include/asm-armnommu/arch-swarm/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ *  02-19-2001  gjm     Leveraged for armnommu/dsc21
+ *  09 Sep 2001 - C Hanish Menon [www.hanishkvc.com] 
+ *    - Leveraged for armnommu/swarm
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ * --gmcnutt
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * If we define __io then asm/io.h will take care of most of the inb & friends
+ * macros. It still leaves us some 16bit macros to deal with ourselves, though.
+ * We don't have PCI or ISA on the dsc21 so I dropped __mem_pci & __mem_isa.
+ * --gmcnutt
+ */
+#define PCIO_BASE 0
+#define __io(a) (PCIO_BASE + (a))
+#define __arch_getw(a) (*(volatile unsigned short *)(a))
+#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
+
+/*
+ * Defining these two gives us ioremap for free. See asm/io.h.
+ * --gmcnutt
+ */
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-swarm/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-swarm/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ * linux/include/asm-armnommu/arch-swarm/irq.h
+ *
+ * 18 Sep 2001 - C Hanish Menon [www.hanishkvc.com]
+ *
+ */
+
+#ifndef __ASM_ARCH_IRQ_H__
+#define __ASM_ARCH_IRQ_H__
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#define fixup_irq(x) (x)
+
+static __inline__ void irq_init_irq(void) 
+{
+	outl(0x0, SWARM_INT_MASK); /* Disable all interrupts */
+	outl(0x0, SWARM_INT_LEVEL); /* no FIQs only IRQs */
+	//printk("DebugKVC: In irq_init_irq \n");
+	return;
+}
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-swarm/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-swarm/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/irqs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,56 @@
+/*
+ * irqs.h:
+ *         IRQ numbers for the dsc21.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ *	   Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * 09 Sep 2001 - C Hanish Menon [www.hanishkvc.com]
+ *   - Copied and updated to suite armnommu/swarm
+ * 
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+
+/* irq #s */
+#define SWARM_IRQ_TIMER0  26
+#define SWARM_IRQ_TIMER1  27
+#define SWARM_IRQ_TIMER2  28
+#define SWARM_IRQ_TIMER3  29
+#define SWARM_IRQ_UART0   24
+#define SWARM_IRQ_MAX     29
+
+#define NR_IRQS           (SWARM_IRQ_MAX + 1)
+
+/* alias */
+#define IRQ_TIMER         SWARM_IRQ_TIMER0
+
+/* flags for request_irq() */
+#define IRQ_FLG_LOCK      (0x0001)  /* handler is not replaceable   */
+#define IRQ_FLG_REPLACE   (0x0002)  /* replace existing handler     */
+#define IRQ_FLG_FAST      (0x0004)
+#define IRQ_FLG_SLOW      (0x0008)
+#define IRQ_FLG_STD       (0x8000)  /* internally used              */
+
+#endif /* __ASM_ARCH_IRQS_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-swarm/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-swarm/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,60 @@
+/*
+ * linux/include/asm-armnommu/arch-swarm/memory.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * Copyright (c) 2001 RidgeRun <www.ridgerun.com>
+ *
+ * 02/19/2001  Gordon McNutt  Leveraged for the dsc21.
+ * 09 Sep 2001 C Hanish Menon [www.hanishkvc.com] 
+ *   - Added for SWARM
+ *   - Also put back the macros which McNutt had moved to asm/memory.h
+ * 
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+
+/*
+ * These are used in the fault handling code (even for nommu) and various other
+ * macros. The current value comes from Steve Johnson's 2.0.38 uClinux port for
+ * the dsc21.
+ * --gmcnutt
+ */
+#define TASK_SIZE	(0x01a00000UL)
+#define TASK_SIZE_26	TASK_SIZE
+
+
+/*
+ * The start of physical memory. For the dsc21 this is the first SDRAM address.
+ * This value is used in the arch-specific bootup code like setup_arch &
+ * bootmem_init. By default we assume that we have one block of contiguous
+ * memory (a node) that starts here and runs MEM_SIZE long (see below). By 
+ * default the ARM bootup code sets MEM_SIZE to be 16MB  which is just right for
+ * us (see arch/armnommu/kernel/setup.c).
+ *
+ * NOTE:   I don't really use the start of SDRAM. Instead I reserve some pages
+ *         of SDRAM for some of the kernel sections (like .data & .bss). The
+ *         linker script has been modified to mark the first unreservered page
+ *         as _end_kernel (see arch/armnommu/vmlinux-armv.lds.in).
+ *         
+ * --gmcnutt
+ */
+extern unsigned long _end_kernel;
+#define PHYS_OFFSET	((unsigned long) &_end_kernel)
+
+/*
+ * PAGE_OFFSET -- the first address of the first page of memory. For archs with
+ * no MMU this corresponds to the first free page in physical memory (aligned
+ * on a page boundary).
+ * --gmcnutt
+ */
+#define PAGE_OFFSET	PHYS_OFFSET
+#define END_MEM		(PHYS_OFFSET + (10*1024*1024))
+
+#define __virt_to_phys(vpage) ((unsigned long) (vpage))
+#define __phys_to_virt(ppage) ((void *) (ppage))
+#define __virt_to_bus(vpage) ((unsigned long) (vpage))
+#define __bus_to_virt(ppage) ((void *) (ppage))
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-swarm/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/param.h
--- linux-2.4.29/include/asm-armnommu/arch-swarm/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-swarm/serial.h linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/serial.h
--- linux-2.4.29/include/asm-armnommu/arch-swarm/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/serial.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,126 @@
+/*
+ *  linux/include/asm-arm/arch-arc/serial.h
+ *
+ *  Copyright (C) 1996 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Changelog:
+ *   15-10-1996	RMK	Created
+ *   04-04-1998	PJB	Merged `arc' and `a5k' architectures
+ *   02-28-2001 GJM     Modified for dsc21
+ *   09 Sep 2001 C Hanish Menon [www.hanishkvc.com]
+ *     - Updated for armnommu/swarm
+ *
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/irqs.h>
+
+/* setup */
+#define BASE_BAUD      (SWARM_CLOCK_RATE / 16)
+#define STD_COM_FLAGS  (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+#define RS_TABLE_SIZE  1
+#define STD_SERIAL_PORT_DEFNS \
+	{  \
+	magic: 0, \
+        baud_base: BASE_BAUD, \
+	port: 0, \
+	irq: SWARM_IRQ_UART0, \
+	flags: STD_COM_FLAGS, \
+	type: PORT_UNKNOWN, \
+	iomem_base: (u8*)SWARM_UART0_BASE, \
+	iomem_reg_shift: 1, \
+	io_type: SERIAL_IO_MEM \
+	}	/* ttyS0 */ 
+#define EXTRA_SERIAL_PORT_DEFNS
+
+
+/* registers */
+#define UART_DTRR  0  /* Data Transmission/Reception Register */
+#define UART_BRSR  1  /* Bit Rate Set Register */
+#define UART_MSR   2  /* Mode Set Register */
+#define UART_RFCR  3  /* Reception FIFO Control Register */
+#define UART_TFCR  4  /* Transmission FIFO Control Register */
+#define UART_LCR   5  /* Line Control Register */
+#define UART_SR    6  /* Status Register */
+
+/* bitmasks */
+#define UART_MSR_CLS    0x0001    // Character length select (1=7bit, 0=8bit)
+#define UART_MSR_RSVD0  0x0002    // Reserved
+#define UART_MSR_SBLD   0x0004    // Stop bit length select (1=2bits, 0=1bit)
+#define UART_MSR_PSB 	0x0008	  // Parity select bit (1=odd, 0=even)
+#define UART_MSR_PEB    0x0010	  // Parity enable bit (1=enable, 0=disable)
+#define UART_MSR_TFTIE  0x4000    // Transmission FIFO trigger interrupt enable
+#define UART_MSR_RFTIE  0x8000    // Reception FIFO trigger interrupt enable
+#define UART_MSR_INTS   0xfc00    // All interrupt bits
+#define UART_MSR_MODE_BITS 0x001f // data length, stop & parity
+
+#define UART_SR_TREF    0x0001    // Transmission register empty flag
+#define UART_SR_TFEF    0x0002    // Transmission FIFO empty flag
+#define UART_SR_RFNEF   0x0004    // Reception FIFO not empty flag
+#define UART_SR_RSVD0   0x00f8    // Reserved
+#define UART_SR_TOIF    0x0100    // Time out interrupt flag
+#define UART_SR_RFER    0x0200    // Reception FIFO error flag
+#define UART_SR_TFTI    0x0400    // Transmission FIFO trigger indicator
+#define UART_SR_RFTI    0x0800    // Reception FIFO trigger indicator
+#define UART_SR_RSVD1   0xf000    // Reserved
+
+#define UART_LCR_BOC    0x0100    // Break output control (1=send break)
+
+#define UART_FCR_FTL1   0x0000    /* FIFO trigger level 1 byte */
+#define UART_FCR_FTL4   0x0100    /* FIFO trigger level 4 bytes */
+#define UART_FCR_FTL8   0x0200    /* FIFO trigger level 8 bytes */
+#define UART_FCR_FTL16  0x0300    /* FIFO trigger level 16 bytes */
+#define UART_FCR_FTL24  0x0400    /* FIFO trigger level 24 bytes */
+#define UART_FCR_FTL32  0x0500    /* FIFO trigger level 32 bytes */
+
+struct swarm_async_struct {
+	int			magic;
+	unsigned long		port;
+	int			flags;
+	int			xmit_fifo_size;
+	struct serial_state	*state;
+	struct tty_struct 	*tty;
+	int			timeout;
+	int			quot;
+	int			x_char;	/* xon/xoff character */
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	u16			MSR; 	/* Interrupt Enable Register */
+	u16			LCR; 	/* Line control register */
+	u16                     RFCR;
+	u16                     TFCR;
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int			blocked_open; /* # of blocked opens */
+	long			session; /* Session of opening process */
+	long			pgrp; /* pgrp of opening process */
+ 	struct circ_buf		xmit;
+ 	spinlock_t		xmit_lock;
+	u8			*iomem_base;
+	u16			iomem_reg_shift;
+	int			io_type;
+	struct tq_struct	tqueue;
+#ifdef DECLARE_WAITQUEUE
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+	wait_queue_head_t	delta_msr_wait;
+#else	
+	struct wait_queue	*open_wait;
+	struct wait_queue	*close_wait;
+	struct wait_queue	*delta_msr_wait;
+#endif	
+	struct dsc21_async_struct *next_port;
+	struct dsc21_async_struct *prev_port;
+	
+};
+
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-swarm/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/system.h
--- linux-2.4.29/include/asm-armnommu/arch-swarm/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,16 @@
+/*
+ * system.h 
+ * 
+ * 9 Sep 2001 - C Hanish Menon [www.hanishkvc.com]
+ *
+ */ 
+
+static inline void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter);
+}
+
+extern __inline__ void arch_reset(char mode)
+{
+	return;
+}
diff -urN linux-2.4.29/include/asm-armnommu/arch-swarm/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/time.h
--- linux-2.4.29/include/asm-armnommu/arch-swarm/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/time.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,62 @@
+/*
+ * linux/include/asm-arm/arch-swarm/time.h
+ *
+ * Copyright (C) 1998 Deborah Wallach.
+ * Twiddles  (C) 1999 	Hugo Fiennes <hugo@empeg.com>
+ * 
+ * 2000/03/29 (C) Nicolas Pitre <nico@cam.org>
+ *	Rewritten: big cleanup, much simpler, better HZ acuracy.
+ *
+ * 2001/02/20 (C) RidgeRun, Inc (http://www.ridgerun.com)
+ *      Leveraged for the dsc21
+ * 09 Sep 2001 - C Hanish Menon [www.hanishkvc.com]
+ *   - Leveraged for SWARM
+ *
+ */
+#ifndef __ASM_ARCH_TIME_H__
+#define __ASM_ARCH_TIME_H__
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+  int  TimerCnt, IntPending;
+	
+	printk("DebugKVC: In timer_interrupt \n");
+	do_timer(regs);
+	do_set_rtc();
+	do_profile(regs);
+
+	TimerCnt = inl(SWARM_TIMER_CNT);
+	TimerCnt += SWARM_TIMER_SYS_COUNT;
+printk("%s(%d): outl(%x,%x)\n", "time.h", __LINE__, TimerCnt, SWARM_TIMER_MATCH0);
+	outl(TimerCnt, SWARM_TIMER_MATCH0);
+printk("%s(%d): inl(%x)=%x\n", "time.h", __LINE__, SWARM_INT_IRQ_STATUS, inl(SWARM_INT_IRQ_STATUS));
+	IntPending = inl(SWARM_INT_IRQ_STATUS);
+printk("%s(%d): outl(%x,%x)\n", "time.h", __LINE__, IntPending & ~(0x1 << SWARM_IRQ_TIMER0), SWARM_INT_IRQ_STATUS);
+	outl(IntPending & ~(0x1 << SWARM_IRQ_TIMER0), SWARM_INT_IRQ_STATUS); /* clear System timer interrupt */
+	printk("DebugKVC: Leaving timer_interrupt \n");
+}
+
+/*
+ * Set up timer interrupt.
+ */
+extern __inline__ void setup_timer(void)
+{
+  int  TimerCnt, IntMask;
+
+	//printk("DebugKVC: In setup_timer \n");
+	timer_irq.handler = timer_interrupt;
+	setup_arm_irq(IRQ_TIMER, &timer_irq);
+	TimerCnt = inl(SWARM_TIMER_CNT);
+	TimerCnt += SWARM_TIMER_SYS_COUNT;
+	outl(TimerCnt, SWARM_TIMER_MATCH0);
+	outl(0x1, SWARM_TIMER_INTEN); /* enable interrupt mode */
+	IntMask = inl(SWARM_INT_MASK);
+	outl(IntMask | (0x1 << SWARM_IRQ_TIMER0), SWARM_INT_MASK); /* enable System timer interrupt */
+}
+
+
+#endif /* __ASM_ARCH_TIME_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-swarm/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-swarm/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ * timex.h:
+ *         System clock frequency.
+ * 09 Sep 2001 - C Hanish Menon [www.hanishkvc.com]
+ *   - Copied and Updated to support armnommu/swarm
+ *         
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+/*
+ * CLOCK_TICK_RATE -- frequency fed to the timer. In our case, 27MHz. Used to
+ * compute LATCH. LATCH is the number of clock ticks per timer interrupt.
+ * (See linux/timex.h, armnommu/mach-dsc21/time.c).
+ */
+#define CLOCK_TICK_RATE	   20
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-swarm/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-swarm/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-swarm/vmalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ *  linux/include/asm-arm/arch-swarm/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *  09 Sep 2001 - C Hanish Menon [www.hanishkvc.com]
+ *    - Just copied in for armnommu/swarm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	  (10*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/arch.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/arch.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/arch.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/arch.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,42 @@
+/*
+ * include/asm-armnommu/arch-ta7s/arch.h
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall WireSpeed
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : Craig Hackney
+ * 
+ */
+
+#ifndef _ARCH_INIT_H
+#include <linux/autoconf.h>
+#include <asm/arch/triscend_a7.h>
+
+#ifndef __ASSEMBLER__
+
+extern void ta7_arch_init( void );
+
+#ifdef CONFIG_USE_A7HAL
+#include <asm/arch/a7hal/soft/lancs.h>
+#else
+extern void a7hal_lancs8900_reset( int interface );
+#endif
+
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/blkmem.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/blkmem.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/blkmem.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/blkmem.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,22 @@
+/*
+ * linux/include/asm-armnommu/arch-ta7s/blkmem.h
+ *
+ * Copyright (c) 2003 Triscend Corp. <www.triscend.com>
+ *
+ * 04/09/2003  Craig Hackney	Initial.
+ *
+ * Contains configuration settings for the blkmem driver.
+ */
+#ifndef __ASM_ARCH_BLKMEM_H
+#define __ASM_ARCH_BLKMEM_H
+
+#include <asm/arch/triscend_a7.h>
+
+#define CAT_ROMARRAY
+
+extern char __bss_start[];
+
+#define FIXUP_ARENAS \
+	arena[0].address = ((unsigned long)__bss_start)+EXTERNAL_FLASH_BASE;
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,45 @@
+/*
+ * asm/arch-armnommu/arch-ta7s/dma.h:
+ *   Triscend-A7S specific macros for DMA support.
+ * 09 Apr 2001 - Craig Hackney (craig@triscend.com)
+ *   - Copied the file from swarm to ta7s
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+/*
+ * This is the maximum DMA address that can be DMAd
+ */
+#define MAX_DMA_ADDRESS		0xffffffff
+
+/*
+ * Number of DMA channels
+ */
+#if defined(A7VL) || defined(A7VE) || defined(A7VC) || defined(A7VT)
+#define MAX_DMA_CHANNELS	8
+#else
+#define MAX_DMA_CHANNELS	4
+#endif
+#endif /* _ASM_ARCH_DMA_H */
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ * include/asm-armnommu/arch-ta7s/hardware.h
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall WireSpeed
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) : Craig Hackney
+ * 
+ */
+#ifndef __ASM_ARCH_TA7S_HARDWARE_H
+#define __ASM_ARCH_TA7S_HARDWARE_H
+
+#include <asm/arch/triscend_a7.h>
+
+#define HARD_RESET_NOW() A7_REG(SYS_RESET_CONTROL_REG)=(1L << SYS_RESET_BIT)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/io.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,70 @@
+/*
+ * linux/include/asm-armnommu/arch-ta7s/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ *  02-19-2001  gjm     Leveraged for armnommu/dsc21
+ *  05-30-2002  csh     Modified for armnommu/arch-ta7s
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ * --gmcnutt
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * If we define __io then asm/io.h will take care of most of the inb & friends
+ * macros. It still leaves us some 16bit macros to deal with ourselves, though.
+ * We don't have PCI or ISA on the dsc21 so I dropped __mem_pci & __mem_isa.
+ * --gmcnutt
+ */
+#define PCIO_BASE 0
+#define __io(a) (PCIO_BASE + (a))
+#define __arch_getw(a) (*(volatile unsigned short *)(a))
+#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
+
+/*
+ * Defining these two gives us ioremap for free. See asm/io.h.
+ * --gmcnutt
+ */
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+/*
+ * These functions are needed for mtd/maps/physmap.c
+ * --rp
+ */ 
+#ifndef memset_io
+#define memset_io(a,b,c)		_memset_io((a),(b),(c))
+#endif
+#ifndef memcpy_fromio
+#define memcpy_fromio(a,b,c)		_memcpy_fromio((a),(b),(c))
+#endif
+#ifndef memcpy_toio
+#define memcpy_toio(a,b,c)		_memcpy_toio((a),(b),(c))
+#endif
+
+#ifndef __mem_pci
+/* Implement memory read/write functions (needed for mtd) */
+#define readb(addr)			__arch_getb(addr)
+#define readw(addr)			__arch_getw(addr)
+#define readl(addr)			__arch_getl(addr)
+#define writeb(v,addr)			__arch_putb(v,addr)
+#define writew(v,addr)			__arch_putw(v,addr)
+#define writel(v,addr)			__arch_putl(v,addr)
+
+#define eth_io_copy_and_sum(a,b,c,d)	__readwrite_bug("eth_io_copy_and_sum")
+
+#define check_signature(io,sig,len)	(0)
+
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,93 @@
+/*
+ * linux/include/asm-armnommu/arch-ta7s/irq.h
+ *
+ * Copyright (C) 2000 Triscend Corporation
+ *
+ * Modifications:
+ *  05-Nov-200	GS	Created.
+ */
+
+#include	<asm/arch/hardware.h>
+#include	<asm/arch/irqs.h>
+
+#define fixup_irq(x) (x)
+
+#define BUILD_IRQ(s,n,m)
+
+extern void IRQ_interrupt(void);
+extern void timer_IRQ_interrupt(void);
+extern void fast_IRQ_interrupt(void);
+extern void bad_IRQ_interrupt(void);
+extern void probe_IRQ_interrupt(void);
+
+#define IRQ_interrupt0 IRQ_interrupt
+#define IRQ_interrupt1 IRQ_interrupt
+#define IRQ_interrupt2 IRQ_interrupt
+#define IRQ_interrupt3 timer_IRQ_interrupt
+#define IRQ_interrupt4 IRQ_interrupt
+#define IRQ_interrupt5 IRQ_interrupt
+#define IRQ_interrupt6 IRQ_interrupt
+#define IRQ_interrupt7 IRQ_interrupt
+#define IRQ_interrupt8 IRQ_interrupt
+#define IRQ_interrupt9 IRQ_interrupt
+#define IRQ_interrupt10 IRQ_interrupt
+#define IRQ_interrupt11 IRQ_interrupt
+#define IRQ_interrupt12 IRQ_interrupt
+#define IRQ_interrupt13 IRQ_interrupt
+#define IRQ_interrupt14 IRQ_interrupt
+#define IRQ_interrupt15 IRQ_interrupt
+
+#define IRQ_INTERRUPT(n)	IRQ_interrupt##n
+#define FAST_INTERRUPT(n)	fast_IRQ_interrupt
+#define BAD_INTERRUPT(n)	bad_IRQ_interrupt
+#define PROBE_INTERRUPT(n)	probe_IRQ_interrupt
+
+static __inline__ void mask_irq(unsigned int irq)
+{
+	volatile unsigned long int *mask = 
+		(volatile unsigned long *)(INT_IRQ_ENABLE_CLEAR_REG);
+	
+	if (irq < NR_IRQS) *mask = ( 1 << irq );
+}
+
+static __inline__ void unmask_irq(unsigned int irq)
+{
+	volatile unsigned long int *set = 
+		(volatile unsigned long *)(INT_IRQ_ENABLE_REG);
+	
+	if (irq < NR_IRQS) *set = ( 1 << irq );
+}
+ 
+static __inline__ unsigned long get_enabled_irqs(void)
+{
+	volatile unsigned long int *ie = 
+		(volatile unsigned long *)(INT_IRQ_ENABLE_REG);
+	
+	return *ie ;
+}
+
+static __inline__ void mask_ack_irq(unsigned int irq)
+{
+	mask_irq(irq);
+}
+
+static __inline__ void irq_init_irq(void)
+{
+	unsigned long flags;
+	int irq;
+	volatile unsigned long int *mask = 
+		(volatile unsigned long *)(INT_IRQ_ENABLE_CLEAR_REG);
+
+	save_flags_cli (flags);	/* clear all interrupt enables */
+	*mask = 0x0ffffffe;
+
+    	for (irq = 0; irq < NR_IRQS; irq++) {
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= mask_ack_irq;
+		irq_desc[irq].mask	= mask_irq;
+		irq_desc[irq].unmask	= unmask_irq;
+	}
+    
+	restore_flags (flags);
+}
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/irqs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,71 @@
+/*
+ * include/asm-armnommu/arch-ta7s/irqs.h
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall WireSpeed
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) :
+ * 
+ */
+#ifndef	_ASM_ARCH_IRQS_H
+#define	_ASM_ARCH_IRQS_H
+
+#if defined(A7VL) || defined(A7VE) || defined(A7VC) || defined(A7VT)
+#define	NR_IRQS	31
+#else
+#define	NR_IRQS	16
+#endif
+
+#define IRQ_FIQ          0
+#define IRQ_SOFTWARE     1
+#define IRQ_SERIAL_0     2
+#define IRQ_TIMER_0      3
+#define IRQ_TIMER_1      4
+#define IRQ_SERIAL_1     5
+#define IRQ_WATCHDOG     6
+#define IRQ_DMA_0        7
+#define IRQ_DMA_1        8
+#define IRQ_DMA_2        9
+#define IRQ_DMA_3       10
+#define IRQ_CSL_USER_0  11
+#define IRQ_CSL_USER_1  12
+#define IRQ_CSL_USER_2  13
+#define IRQ_JTAG        14
+#define IRQ_BREAKPOINT  15
+
+#if defined(A7VL) || defined(A7VE) || defined(A7VC) || defined(A7VT)
+#define IRQ_MFTA	16
+#define IRQ_TWSI0	17
+#define IRQ_TWSI1	18
+#define IRQ_DMA_4	19
+#define IRQ_DMA_5	20
+#define IRQ_USB		21
+#define IRQ_MAC0_TX	22
+#define IRQ_MAC0_RX	23
+#define IRQ_DMA_6	24
+#define IRQ_DMA_7	25
+#define IRQ_PLL		26
+#define IRQ_MAC1_TX	27
+#define IRQ_MAC1_RX	28
+#define IRQ_CAN		29
+#define	IRQ_ADC		30
+#endif
+
+#define IRQ_TC0	IRQ_TIMER_0
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,31 @@
+/*
+ * linux/include/asm-armnommu/arch-ta7s/memory.h
+ *
+ * Copyright (c) 2003 Triscend Corp. <www.triscend.com>
+ *
+ * 04/09/2003  Craig Hackney	Initial.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * These should be the same as the definitions in asm/memory.h
+ * without the '__' at the beginning.
+ */
+#define __virt_to_bus(x) ((unsigned long) (x))
+#define __bus_to_virt(x) ((void *) (x))
+#define __virt_to_phys(x) ((unsigned long) (x))
+#define __phys_to_virt(x) ((void *) (x))
+
+#define TASK_SIZE	(0x02000000UL)
+#define TASK_SIZE_26	(0x01a00000UL)
+
+
+#define PHYS_OFFSET	DRAM_BASE
+#define PAGE_OFFSET	PHYS_OFFSET
+
+#define MEM_SIZE	(DRAM_SIZE - PHYS_OFFSET)
+#define END_MEM		(DRAM_BASE + DRAM_SIZE)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/param.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/processor.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/processor.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/processor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,26 @@
+/*
+ * linux/include/asm-armnommu/arch-ta7s/processor.h
+ *
+ * Copyright (c) 1996 Russell King.
+ *
+ * Changelog:
+ *  10-09-1996	RMK	Created
+ */
+
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+#define MCA_bus 0
+#define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+/*
+ * User space: 26MB
+ */
+#define TASK_SIZE	(0x01a00000UL)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/serial.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/serial.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/serial.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ * linux/include/asm-armnommu/arch-ta7s/serial.h
+ * 2003	CSH	Created
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <asm/arch/hardware.h>
+#include <asm/irq.h>
+
+#define RS_TABLE_SIZE	2
+#define BASE_BAUD	115200
+#define STD_COM_FLAGS	(ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+#define STD_SERIAL_PORT_DEFNS		\
+	/* UART CLK PORT IRQ FLAGS */	\
+	{ 0, BASE_BAUD, UART0_RX_TX_REG, IRQ_SERIAL_0, STD_COM_FLAGS },	/* ttyS0 */	\
+	{ 0, BASE_BAUD, UART1_RX_TX_REG, IRQ_SERIAL_1, STD_COM_FLAGS },	/* ttyS1 */
+#define EXTRA_SERIAL_PORT_DEFNS
+
+extern unsigned long a7hal_clock_getFreq( int );
+
+unsigned int baudrate_div(unsigned int baudrate)
+{
+	return(((a7hal_clock_getFreq(0)/16)/baudrate)-1);
+}
+
+#endif /* __ASM_ARCH_SERIAL_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/system.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,19 @@
+/*
+ * linux/include/asm-armnommu/arch-ta7s/system.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * Copyright (c) 2001 RidgeRun, Inc (http://www.ridgerun.org)
+ *
+ */
+#include <asm/arch/arch.h>
+
+static inline void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter);
+}
+
+extern inline void arch_reset(char mode)
+{
+	A7_REG( SYS_RESET_CONTROL_REG ) = (1L<<SYS_RESET_BIT);
+}
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/time.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/time.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,78 @@
+/*
+ * include/asm-armnommu/arch-ta7s/time.h
+ *
+ * This software is provided "AS-IS" and any express or implied 
+ * warranties or conditions, including but not limited to any
+ * implied warranties of merchantability and fitness for a particular
+ * purpose regarding this software. In no event shall WireSpeed
+ * be liable for any indirect, consequential, or incidental damages,
+ * loss of profits or revenue, loss of use or data, or interruption
+ * of business, whether the alleged damages are labeled in contract,
+ * tort, or indemnity.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * author(s) :
+ * 
+ */
+#ifndef _ASM_ARCH_TIME_H
+#include <linux/autoconf.h>
+#include <asm/arch/arch.h>
+#include <linux/interrupt.h>
+
+#ifdef CONFIG_USE_A7HAL
+
+#include <asm/arch/a7hal/clock.h>
+#include <asm/arch/a7hal/timer.h>
+
+#else
+
+extern unsigned long a7hal_clock_getFreq( int noRAM );
+extern void a7hal_timer_start( unsigned short count, int whichTimer, unsigned long control );
+void a7hal_timer_clearInt( int whichTimer );
+unsigned short a7hal_timer_read( int whichTimer );
+
+#define A7HAL_DIV_16            0x04
+#define A7HAL_DIV_256           0x08
+#define A7HAL_PERIODIC          0x40
+
+#endif
+
+extern unsigned long ta7_gettimeoffset (void);
+extern void ta7_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+extern int setup_arm_irq(int, struct irqaction *);
+
+/*
+ * Set up timer interrupt, and the current time in seconds.
+ */
+extern __inline__ void setup_timer(void)
+{
+	if( a7hal_clock_getFreq(0) < 0x100000 )
+	{
+		a7hal_timer_start( ((a7hal_clock_getFreq(0)/16)/HZ) - 1,
+                                   0,
+                                   A7HAL_DIV_256 | A7HAL_PERIODIC ) ;
+	}
+	else
+	{
+		a7hal_timer_start( ((a7hal_clock_getFreq(0)/16)/HZ) - 1,
+                                   0,
+                                   A7HAL_DIV_16 | A7HAL_PERIODIC ) ;
+	} 
+
+	gettimeoffset = ta7_gettimeoffset;	
+
+	timer_irq.handler = ta7_timer_interrupt;
+
+	setup_arm_irq(IRQ_TIMER_0, &timer_irq);
+}
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,38 @@
+/*
+ * timex.h:
+ *         System clock frequency.
+ * 09 Apr 2003 - Craig Hackney
+ *   - Copied and Updated to support Triscend-A7S
+ *         
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+/*
+ * CLOCK_TICK_RATE -- frequency fed to the timer.
+ * (See linux/timex.h).
+ */
+#define CLOCK_TICK_RATE	   20
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/triscend_a7.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/triscend_a7.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/triscend_a7.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/triscend_a7.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ ***************************************************************************
+ *  triscend_a7.h
+ *
+ *  Copyright (c) 2000-2003 Triscend Corporation. All rights reserved.
+ *
+ ***************************************************************************
+ */
+
+#if defined(A7VL) || defined(A7VE) || defined(A7VC) || defined(A7VT)
+#ifdef CONFIG_USE_A7HAL
+#include <asm/arch/a7hal/triscend_a7v.h>
+#else
+#include <asm/arch/triscend_a7v.h>
+#endif
+#else
+#ifdef CONFIG_USE_A7HAL
+#include <asm/arch/a7hal/triscend_a7s.h>
+#else
+#include <asm/arch/triscend_a7s.h>
+#endif
+#endif
+
+#ifndef INLINE
+#ifdef _DIAB
+#define INLINE
+#elif defined( __ARM__ )
+#define INLINE	__inline
+#else
+#define INLINE	__inline__
+#endif
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/triscend_a7s.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/triscend_a7s.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/triscend_a7s.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/triscend_a7s.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,1299 @@
+/*
+ ***************************************************************************
+ *  triscend_a7.h
+ *
+ *  Copyright (c) 2000, 2001 Triscend Corporation. All rights reserved.
+ *
+ ***************************************************************************
+ */
+
+#ifndef _TRISCEND_A7_H
+#define _TRISCEND_A7_H
+
+/*
+ **********************************************************
+ *  Memory Map
+ **********************************************************
+ */
+#define EXTERNAL_SDRAM_BASE  0xc0000000
+#define EXTERNAL_SDRAM_SIZE  0x10000000
+#define EXTERNAL_FLASH_BASE  0xd0000000
+#define EXTERNAL_FLASH_SIZE  0x01000000
+#define CONTROL_REG_BASE     0xd1010000
+#define CONTROL_REG_SIZE     0x00010000
+#define TEST_AREA_BASE       0xd1020000
+#define TEST_AREA_SIZE       0x00010000
+#define INTERNAL_RAM_BASE    0xd1030000
+#define INTERNAL_RAM_SIZE    0x00004000
+#define CONFIG_MEM_BASE      0xd1040000
+#define CONFIG_MEM_SIZE      0x00040000
+
+
+/*
+ **********************************************************
+ *  Field and Bit Manipulation Defines and Macros
+ **********************************************************
+ */
+#define A7_REG(reg) (*(volatile unsigned int*)(reg))
+
+#define BIT_MASK(bitIdx) (1 << (bitIdx))
+
+#define FIELD_MASK(fieldIdx,nBits) (((1 << (nBits)) - 1) << (fieldIdx))
+
+#define GET_BIT(addr32,bitIdx) (*(volatile unsigned int*)(addr32) & (1 << (bitIdx)) ? 1 : 0)
+
+#define PUT_BIT(addr32,bitIdx,bitVal) (*(volatile unsigned int*)(addr32) = (0 == (bitVal)) ? *(volatile unsigned int*)(addr32) & ~(1 << (bitIdx)) : *(volatile unsigned int*)(addr32) | (1 << (bitIdx)))
+#define SET_BIT(addr32,bitIdx) (*(volatile unsigned int*)(addr32) |= (1 << (bitIdx)))
+
+#define CLR_BIT(addr32,bitIdx) (*(volatile unsigned int*)(addr32) &= ~(1 << (bitIdx)))
+
+#define GET_FIELD(addr32,fieldIdx,nBits) ((*(volatile unsigned int*)(addr32) >> (fieldIdx)) & ((1 << (nBits)) - 1))
+
+#define PUT_FIELD(addr32,fieldIdx,nBits,fieldValue) (*(volatile unsigned int*)(addr32) = (*(volatile unsigned int*)(addr32) & ~FIELD_MASK(fieldIdx,nBits)) | (((fieldValue) << (fieldIdx)) & FIELD_MASK(fieldIdx,nBits)))
+#define SET_FIELD(addr32,fieldIdx,nBits) (*(volatile unsigned int*)(addr32) |= FIELD_MASK(fieldIdx,nBits))
+
+#define CLR_FIELD(addr32,fieldIdx,nBits) (*(volatile unsigned int*)(addr32) &= ~FIELD_MASK(fieldIdx,nBits))
+
+
+/*
+ **********************************************************
+ *  Control Register Base Address Definitions
+ **********************************************************
+ */
+#define MSS_BASE    0xd1010000
+#define SYS_BASE    0xd1010100
+#define INT_BASE    0xd1010200
+#define REMAP_BASE  0xd1010400
+#define TIMER_BASE  0xd1010500
+#define WD_BASE     0xd1010600
+#define CFG_BASE    0xd1010700
+#define DMA_BASE    0xd1010800
+#define UART_BASE   0xd1010900
+#define BPU_BASE    0xd1010a00
+#define PU_BASE     0xd1011100
+
+
+/*
+ **********************************************************
+ * Memory Subsystem Unit Definition
+ **********************************************************
+ */
+
+/*
+ *  Memory Subsystem Configuration Register (read/write)
+ */
+#define MSS_CONFIG_REG          (MSS_BASE + 0x00)
+#define MSS_CONFIG_RESET_VALUE  0x00004002
+#define BUS_MODE_FIELD             0
+#define   NBITS_BUS_MODE             4
+#define MIU_DEV_WIDTH_FIELD        4
+#define   NBITS_MIU_DEV_WIDTH        2
+#define SDIU_DEV_WIDTH_FIELD       6
+#define   NBITS_SDIU_DEV_WIDTH       2
+#define R_MAP_FIELD                8
+#define   NBITS_R_MAP                2
+#define B_MAP_FIELD               10
+#define   NBITS_B_MAP                3
+#define N_BANK_BIT                13
+#define NE_BANK_BIT               14
+#define PIPE_BIT                  15
+#define SDRAM_DMA_BUF_EN_FIELD    16
+#define   NBITS_SDRAM_DMA_BUF_EN     4
+#define FLASH_DMA_BUF_EN_FIELD    20
+#define   NBITS_FLASH_DMA_BUF_EN     4
+#define MSS_FLASH_X16             24
+/* The following fields are now deleted
+#define MSS_ARB_FIELD             24
+#define   NBITS_MSS_ARB              2
+*/
+
+
+/*
+ *  Static Memory Interface Timing Control Register (read/write)
+ */
+#define MSS_TIM_CTRL_REG          (MSS_BASE + 0x04)
+#define MSS_TIM_CTRL_RESET_VALUE  0x00077777
+#define WC_SETUP_FIELD      0
+#define   NBITS_WC_SETUP      4
+#define WC_WIDTH_FIELD      4
+#define   NBITS_WC_WIDTH      4
+#define WC_HOLD_FIELD       8
+#define   NBITS_WC_HOLD       4
+#define RC_SETUP_FIELD     12
+#define   NBITS_RC_SETUP      4
+#define RC_WIDTH_FIELD     16
+#define   NBITS_RC_WIDTH      4
+
+
+/*
+ *  SDRAM Mode Register (read/write)
+ */
+#define MSS_SDR_MODE_REG          (MSS_BASE + 0x08)
+#define MSS_SDR_MODE_RESET_VALUE  0x02223222
+#define TRP_FIELD          0
+#define   NBITS_TRP          3
+#define TRCD_FIELD         4
+#define   NBITS_TRCD         3
+#define TWR_FIELD          8
+#define   NBITS_TWR          3
+#define TRC_FIELD         12
+#define   NBITS_TRC          3
+#define MODE_REG_FIELD    16
+#define   NBITS_MODE_REG    14
+
+
+/*
+ *  SDRAM Control Register (read/write)
+ */
+#define MSS_SDR_CTRL_REG          (MSS_BASE + 0x0c)
+#define MSS_SDR_CTRL_RESET_VALUE  0x00000000
+#define PWR_MAN_FIELD         0
+#define   NBITS_PWR_MAN         3
+#define RFSH_RATE_FIELD      16
+#define   NBITS_RFSH_RATE      12
+#define RFSH_BURST_FIELD     28
+#define   NBITS_RFSH_BURST      4
+
+
+/*
+ *  SDRAM Status Register (read only)
+ */
+#define MSS_STATUS_REG          (MSS_BASE + 0x10)
+#define MSS_STATUS_RESET_VALUE  0x00000001
+#define SD_STATUS_FIELD    0
+#define   NBITS_SD_STATUS    3
+#define RFSH_OVF_BIT       3
+
+
+/*
+ *  SDRAM Status Clear Register (write only)
+ *      write 1 to clear the corresponding status reg bit
+ */
+#define MSS_STATUS_CLEAR_REG  (MSS_BASE + 0x14)
+#define RFSH_OVF_CLR_BIT   3
+
+
+/*
+ **********************************************************
+ *  System Control Registers
+ **********************************************************
+ */
+
+/*
+ *  Clock Control Register (read/write)
+ *      Use this register to select which portion of the
+ *      device is turned off or kept on in power down mode.
+ *      For any of the bits set, the corresponding circuit
+ *      is be turned off in power down.
+ *      A "0" will keep the circuit running at all times.
+ *      The PLL output frequency = PLL_DIV x 32KHz
+ *      PLL_SCALE:   PLL Pre-scale Value:
+ *       0             1
+ *       1             2
+ *       2             4
+ *       4             8
+ *       8            16
+ *      16            32
+ */
+#define SYS_CLOCK_CONTROL_REG      (SYS_BASE + 0x00)
+#define CLOCK_CONTROL_RESET_VALUE  0x00040000
+#define CLK_SEL_BIT        0
+#define PLL_SEL_BIT        1
+#define CSL_SEL_BIT        2
+#define CK_EN_BIT          3
+#define XTAL_EN_BIT        4
+#define PLL_EN_BIT         5
+#define PLL_TEST_BIT       6
+#define REF_SEL_BIT        7
+#define PLL_DIV_FIELD      8
+#define   NBITS_PLL_DIV    12
+#define PLL_SCALE_FIELD    24
+#define   NBITS_PLL_SCALE     5
+
+
+/*
+ *  PLL Status Register (read only)
+ */
+#define SYS_PLL_STATUS_REG      (SYS_BASE + 0x04)
+#define PLL_STATUS_RESET_VALUE  0x00000001
+#define PLL_NOT_LOCK_BIT   0
+#define PLL_LOCK_BIT       1
+
+
+/*
+ *  PLL Status Clear Register (write only)
+ */
+#define SYS_PLL_STATUS_CLEAR_REG  (SYS_BASE + 0x08)
+#define PLL_NOT_LOCK_CLEAR_BIT   0
+#define PLL_LOCK_CLEAR_BIT       1
+
+
+/*
+ *  Reset Control Register (read/write)
+ *      The SYS_RESET bit is used by software to reset the
+ *      system as seen by the user. It resets the CPU, the
+ *      bus and all the peripherals without affecting the
+ *      configuration of the device.
+ *      The bit is self-clearing.
+ */
+#define SYS_RESET_CONTROL_REG      (SYS_BASE + 0x0c)
+#define RESET_CONTROL_RESET_VALUE  0x00000000
+#define SLAVE_DIS_BIT    1
+#define SYS_RESET_BIT    2
+
+
+/*
+ *  Power Down Control Register (read/write)
+ *      User can select which portion of the device is
+ *      turned off or kept on during power down mode.
+ *      Setting a bit turns off the circuit in power down.
+ *      A zero keeps the circuit running at all times.
+ */
+#define SYS_POWER_CONTROL_REG      (SYS_BASE + 0x10)
+#define POWER_CONTROL_RESET_VALUE  0x00000000
+#define PD_BCK_EN_BIT      0
+#define PD_CSL_BCK_EN_BIT  1
+#define PD_OSC_EN_BIT      2
+#define PD_IO_EN_BIT       3
+#define PD_BIT             4
+#define POR_DIS_BIT        5
+
+
+/*
+ *  Pause Register (write only)
+ *      Writing to this register puts the ARM core (only) in
+ *      a low power state until receiving an interrupt.
+ */
+#define REMAP_PAUSE_REG  (REMAP_BASE + 0x00)
+
+
+/*
+ *  Identification Register (read only)
+ */
+#define REMAP_IDENTIFICATION_REG  (REMAP_BASE + 0x10)
+#define TRISCEND_TA7S20  0x1803d2ff
+
+
+/*
+ *  Revision Register (read only)
+ *      Revision = 0 for first device
+ */
+#define REMAP_REVISION_REG  (REMAP_BASE + 0x14)
+#define TRISCEND_TA7S20_REV113  0x00000113
+
+
+/*
+ *  Clear Reset Map Register (write only)
+ *      Writing to this address causes a system memory map switch from the
+ *      user initial memory map to the one used during normal operation.
+ *      It effectively clears the Flash alias bit in the Alias Enable Register.
+ */
+#define REMAP_CLEAR_RESET_MAP_REG  (REMAP_BASE + 0x20)
+
+
+/*
+ *  Reset Status Register (read only)
+ *      Indicates the cause of the latest reset.
+ *      Default reset value depends on reset cause.
+ */
+#define REMAP_RESET_STATUS_REG  (REMAP_BASE + 0x30)
+#define POR_BIT         0
+#define CFG_RST_BIT     1
+#define RST_PIN_BIT     2
+#define J_CFG_RST_BIT   3
+#define CPU_RST_BIT     4
+#define J_CPU_RST_BIT   5
+#define WD_RST_BIT      6
+#define APP_RST_BIT     7
+#define SYS_RST_BIT     8
+#define J_SYS_RST_BIT   9
+#define SOFT_RST_BIT   10
+
+
+/*
+ *  Reset Status Clear Register (write only)
+ *      Writing a "1" clears the corresponding bit in Reset Status Register.
+ *      Writing a "0" has no effect.
+ */
+#define REMAP_RESET_STATUS_CLEAR_REG  (REMAP_BASE + 0x34)
+#define POR_CLR_BIT         0
+#define CFG_RST_CLR_BIT     1
+#define RST_PIN_CLR_BIT     2
+#define J_CFG_RST_CLR_BIT   3
+#define CPU_RST_CLR_BIT     4
+#define J_CPU_RST_CLR_BIT   5
+#define WD_RST_CLR_BIT      6
+#define APP_RST_CLR_BIT     7
+#define SYS_RST_CLR_BIT     8
+#define J_SYS_RST_CLR_BIT   9
+#define SOFT_RST_CLR_BIT   10
+
+
+/*
+ *  Pin Status Register (read only)
+ *      This register enables software to get the status of
+ *      some static pins of the device.
+ */
+#define REMAP_PIN_STATUS_REG  (REMAP_BASE + 0x38)
+#define VSYS_BIT       0
+#define RSTN_BIT       1
+#define SLAVEN_BIT     2
+#define VSYS_GOOD_BIT  3
+#define VSYS_BAD_BIT   4
+
+
+/*
+ *  Pin Status Clear Register (write only)
+ *      Writing a "1" clears the corresponding bit in the Pin Status Register.
+ *      Writing a "0" has no effect.
+ */
+#define REMAP_PIN_STATUS_CLEAR_REG  (REMAP_BASE + 0x3c)
+#define VSYS_GOOD_CLR_BIT  3
+#define VSYS_BAD_CLR_BIT   4
+
+
+/*
+ *  Alias Enable Register (read/write)
+ *      This register defines which alias is enabled at the bottom of the
+ *      memory starting at address 0. If more than one alias is enabled,
+ *      they are overlaid over each other with the following priority
+ *      (from highest to lowest priority): ROM, FLASH, SRAM, SDRAM.
+ */
+#define REMAP_ALIAS_ENABLE_REG    (REMAP_BASE + 0x40)
+#define ALIAS_ENABLE_RESET_VALUE  0x0000000f
+#define ROM_AEN_BIT     0
+#define FLASH_AEN_BIT   1
+#define SRAM_AEN_BIT    2
+#define SDRAM_AEN_BIT   3
+
+
+/*
+ *  SRAM Config Register (read/write)
+ */
+#define REMAP_SRAM_CONFIG_REG    (REMAP_BASE + 0x44)
+#define SRAM_CONFIG_RESET_VALUE  0x00000000
+#define SRAM_PRIO_BIT             0
+#define SRAM_SIZE_BIT             1
+#define SRAM_PROTECT_FIELD        2
+#define   NBITS_SRAM_PROTECT        4
+
+
+/*
+ *  SRAM Base Address Register (read/write)
+ *      The internal SRAM can be relocated using this register
+ */
+#define REMAP_SRAM_BASE_ADR_REG    (REMAP_BASE + 0x48)
+#define SRAM_BASE_ADR_RESET_VALUE  0x0d1030000
+#define SRAM_BASE_ADR_FIELD   14
+#define   NBITS_SRAM_BASE_ADR    18
+
+
+/*
+ *  Access Protect Register (read/write)
+ *      When the dmaDis bit is set, DMA writes are not
+ *      allowed into the control register area.
+ */
+#define REMAP_ACC_PROTECT_REG    (REMAP_BASE + 0x4c)
+#define ACC_PROTECT_RESET_VALUE  0x00000001
+#define DMA_DIS_BIT  0
+#define TEST_EN_BIT  1
+
+
+/*
+ **********************************************************
+ *  Configuration Unit Definition
+ **********************************************************
+ */
+
+/*
+ *  Configuration Control Register (read/write)
+ */
+#define CFG_CONFIG_CONTROL_REG      (CFG_BASE + 0x00)
+#define CONFIG_CONTROL_RESET_VALUE  0x00000000
+#define EN_ZIP_BIT       0
+#define EN_REG_BIT       1
+#define EN_IO_BIT        2
+#define CONFIG_DONE_BIT  4
+#define DEC_EN_BIT       5
+#define CFGENS_EN_BIT    6
+#define CFG_STOP_BIT     7
+
+
+/*
+ *  Configuration Timing Register (read/write)
+ *      CSL Configuration Access Wait States:
+ *          generated by config unit in response to CSL reads.
+ *          number of wait states = cslWait
+ *      PIO Phase Delay:
+ *          length in clock cycles of PIO config read & write phases.
+ *          length in clock cycles = (pioPhase - 1)
+ */
+#define CFG_CONFIG_TIMING_REG      (CFG_BASE + 0x04)
+#define CONFIG_TIMING_RESET_VALUE  0x00000024
+#define CSL_WAIT_FIELD       0
+#define   NBITS_CSL_WAIT       3
+#define PIO_PHASE_FIELD      3
+#define   NBITS_PIO_PHASE      3
+
+
+/*
+ *  IO Recover Register (read/write)
+ */
+#define CFG_IO_RECOVER_REG      (CFG_BASE + 0x08)
+#define IO_RECOVER_RESET_VALUE  0x00008061
+#define SD_SEL_BIT           0
+#define CEN1_SEL_BIT         1
+#define CEN2_SEL_BIT         2
+#define CEN3_SEL_BIT         3
+#define XDONE_SEL_BIT        4
+#define A18_SEL_BIT          5
+#define A19_SEL_BIT          6
+#define A20_SEL_BIT          7
+#define A21_SEL_BIT          8
+#define A22_SEL_BIT          9
+#define A23_SEL_BIT         10
+#define A24_TO_A31_SEL_BIT  11
+#define D8_TO_D15_SEL_BIT   12
+#define D16_TO_D31_SEL_BIT  13
+#define ECLK_SEL_BIT        14
+#define SDCEN1_SEL_BIT      15
+
+
+/*
+ *  Configuration Protection Register (read/write)
+ *      When a protection bit is set, the configuration plane
+ *      is protected from read or write accesses. (Read data = 0).
+ *      Once this bit is set, it can only be cleared through a power cycle.
+ */
+#define CFG_CONFIG_PROTECT_REG      (CFG_BASE + 0x0c)
+#define CONFIG_PROTECT_RESET_VALUE  0x00000000
+#define RD_SECURE_BIT   0
+#define WR_SECURE_BIT   1
+
+
+/*
+ **********************************************************
+ * Interrupt Unit Definition
+ **********************************************************
+ */
+
+/*
+ *  Interrupt Registers Definition
+ */
+#define INT_IRQ_STATUS_REG          (INT_BASE + 0x00)	// read only
+#define INT_IRQ_RAW_STATUS_REG      (INT_BASE + 0x04)	// read only
+#define INT_IRQ_ENABLE_REG          (INT_BASE + 0x08)	// read/write
+#define INT_IRQ_ENABLE_CLEAR_REG    (INT_BASE + 0x0c)	// write only
+#define INT_IRQ_SOFT_REG            (INT_BASE + 0x10)	// write only
+#define INT_FIQ_STATUS_REG          (INT_BASE + 0x100)	// read only
+#define INT_FIQ_RAW_STATUS_REG      (INT_BASE + 0x104)	// read only
+#define INT_FIQ_ENABLE_REG          (INT_BASE + 0x108)	// read/write
+#define INT_FIQ_ENABLE_CLEAR_REG    (INT_BASE + 0x10c)	// write only
+#define INT_IRQ_STEER_REG           (INT_BASE + 0x110)	// write only
+#define IRQ_STATUS_RESET_VALUE      0x00000000
+#define IRQ_RAW_STATUS_RESET_VALUE  0x00000000
+#define IRQ_ENABLE_RESET_VALUE      0x00000000
+#define FIQ_STATUS_RESET_VALUE      0x00000000
+#define FIQ_RAW_STATUS_RESET_VALUE  0x00000000
+#define FIQ_ENABLE_RESET_VALUE      0x00000000
+#define FIQ_BIT              0
+#define IRQ_SOFTWARE_BIT     1
+#define IRQ_SERIAL_0_BIT     2
+#define IRQ_TIMER_0_BIT      3
+#define IRQ_TIMER_1_BIT      4
+#define IRQ_SERIAL_1_BIT     5
+#define IRQ_WATCHDOG_BIT     6
+#define IRQ_DMA_0_BIT        7
+#define IRQ_DMA_1_BIT        8
+#define IRQ_DMA_2_BIT        9
+#define IRQ_DMA_3_BIT       10
+#define IRQ_CSL_USER_0_BIT  11
+#define IRQ_CSL_USER_1_BIT  12
+#define IRQ_CSL_USER_2_BIT  13
+#define IRQ_JTAG_BIT        14
+#define IRQ_BREAKPOINT_BIT  15
+
+
+/*
+ ***********************************************************
+ * DMA Unit Definition
+ ***********************************************************
+ */
+
+/*
+ *  DMA Control Registers Definition (read/write)
+ */
+#define DMA0_CONTROL_REG         (DMA_BASE + 0x00)
+#define DMA1_CONTROL_REG         (DMA_BASE + 0x40)
+#define DMA2_CONTROL_REG         (DMA_BASE + 0x80)
+#define DMA3_CONTROL_REG         (DMA_BASE + 0xc0)
+#define DMA_CONTROL_RESET_VALUE  0x00000000
+#define CLEAR_BIT                      0
+#define DMA_ENABLE_BIT                 1
+#define DMA_INIT_BIT                   2
+#define CONT_BIT                       3
+#define SFT_REQ_BIT                    4
+#define BLOCK_EN_BIT                   5
+#define TRANS_DIR_FIELD                6
+#define   NBITS_TRANS_DIR                2
+#define SRC_ADDR_MODE_FIELD            8
+#define   NBITS_SRC_ADDR_MODE            2
+#define DEST_ADDR_MODE_FIELD          10
+#define   NBITS_DEST_ADDR_MODE           2
+#define TRANS_SIZE_FIELD              12
+#define   NBITS_TRANS_SIZE               2
+#define METHOD_BIT                    14
+#define AUX_DIS_BIT                   15
+#define CRC_EN_BIT                    16
+#define BROADCAST_BIT                 17
+
+
+/*
+ *  DMA Interrupt Registers Definitions
+ */
+#define DMA0_INT_ENABLE_REG         (DMA_BASE + 0x04)	// read/write
+#define DMA1_INT_ENABLE_REG         (DMA_BASE + 0x44)	// read/write
+#define DMA2_INT_ENABLE_REG         (DMA_BASE + 0x84)	// read/write
+#define DMA3_INT_ENABLE_REG         (DMA_BASE + 0xc4)	// read/write
+#define DMA0_INT_REG                (DMA_BASE + 0x08)	// read only
+#define DMA1_INT_REG                (DMA_BASE + 0x48)	// read only
+#define DMA2_INT_REG                (DMA_BASE + 0x88)	// read only
+#define DMA3_INT_REG                (DMA_BASE + 0xc8)	// read only
+#define DMA0_INT_CLEAR_REG          (DMA_BASE + 0x0c)	// write only
+#define DMA1_INT_CLEAR_REG          (DMA_BASE + 0x4c)	// write only
+#define DMA2_INT_CLEAR_REG          (DMA_BASE + 0x8c)	// write only
+#define DMA3_INT_CLEAR_REG          (DMA_BASE + 0xcc)	// write only
+#define DMA_INT_ENABLE_RESET_VALUE  0x00000000
+#define DMA_INT_RESET_VALUE         0x00000000
+#define TC_BIT        0
+#define INIT_BIT      1
+#define OVF_BIT       2
+#define FULL_BIT      3
+#define EMPTY_BIT     4
+#define LAST_BIT      5
+#define RETRANS_BIT   6
+#define DESC_BIT      7
+#define BAD_RETR_BIT  8
+
+
+/*
+ *  DMA Transfer Count Registers Definition
+ */
+#define DMA0_TRANS_CNT_REG  (DMA_BASE + 0x1c)	// read/write
+#define DMA1_TRANS_CNT_REG  (DMA_BASE + 0x5c)	// read/write
+#define DMA2_TRANS_CNT_REG  (DMA_BASE + 0x9c)	// read/write
+#define DMA3_TRANS_CNT_REG  (DMA_BASE + 0xdc)	// read/write
+#define TRANS_CNT_FIELD    0
+#define   NBITS_TRANS_CNT    16
+
+#define DMA0_CUR_TRANS_CNT_REG  (DMA_BASE + 0x2c)	// read only
+#define DMA1_CUR_TRANS_CNT_REG  (DMA_BASE + 0x6c)	// read only
+#define DMA2_CUR_TRANS_CNT_REG  (DMA_BASE + 0xac)	// read only
+#define DMA3_CUR_TRANS_CNT_REG  (DMA_BASE + 0xec)	// read only
+#define CUR_TRANS_CNT_FIELD   TRANS_CNT_FIELD
+#define   NBITS_CUR_TRANS_CNT   NBITS_TRANS_CNT
+
+
+/*
+ *  DMA Pending Request Counter Register Definition (read only)
+ */
+#define DMA0_PEND_REQ_REG  (DMA_BASE + 0x30)
+#define DMA1_PEND_REQ_REG  (DMA_BASE + 0x70)
+#define DMA2_PEND_REQ_REG  (DMA_BASE + 0xb0)
+#define DMA3_PEND_REQ_REG  (DMA_BASE + 0xf0)
+#define PEND_REQ_CTRL_FIELD      0
+#define   NBITS_PEND_REQ_CTRL     10
+#define LAST_POST_FIELD         16
+#define   NBITS_LAST_POST         10
+
+
+/*
+ *  DMA Descriptor Table
+ */
+#define DMA0_DES_TABLE_ADDR_REG  (DMA_BASE + 0x10)	// read/write
+#define DMA1_DES_TABLE_ADDR_REG  (DMA_BASE + 0x50)	// read/write
+#define DMA2_DES_TABLE_ADDR_REG  (DMA_BASE + 0x90)	// read/write
+#define DMA3_DES_TABLE_ADDR_REG  (DMA_BASE + 0xd0)	// read/write
+#define DMA0_CUR_DESC_ADDR_REG   (DMA_BASE + 0x20)	// read only
+#define DMA1_CUR_DESC_ADDR_REG   (DMA_BASE + 0x60)	// read only
+#define DMA2_CUR_DESC_ADDR_REG   (DMA_BASE + 0xa0)	// read only
+#define DMA3_CUR_DESC_ADDR_REG   (DMA_BASE + 0xe0)	// read only
+
+#if !defined( _ASMLANGUAGE ) && !defined( __ASSEMBLER__ )
+typedef struct
+{
+    unsigned int sourceAddress;
+    unsigned int reserved;
+    unsigned int destinationAddress;
+    unsigned int controlStatus;
+}
+DMA_DESCRIPTOR;
+#endif
+
+/*
+ * DMA_DESCRIPTOR controlStatus Definition
+ */
+#define ACT_WHEN_COMPL_FIELD          0
+#define   NBITS_ACT_WHEN_COMPL          2
+#define DESC_INT_BIT                  2
+#define CRC_CLR_DIS_BIT               3
+#define CONT_DESC_BIT                 4
+#define BUFF_STAT_BIT                 5
+#define TRANS_LENGTH_FIELD           16
+#define   NBITS_TRANS_LENGTH           16
+
+
+/*
+ *  Other DMA Registers Definition - 32-bit registers
+ */
+#define DMA0_SRC_ADDR_REG       (DMA_BASE + 0x14)	// read/write
+#define DMA1_SRC_ADDR_REG       (DMA_BASE + 0x54)	// read/write
+#define DMA2_SRC_ADDR_REG       (DMA_BASE + 0x94)	// read/write
+#define DMA3_SRC_ADDR_REG       (DMA_BASE + 0xd4)	// read/write
+#define DMA0_CUR_SRC_ADDR_REG   (DMA_BASE + 0x24)	// read only
+#define DMA1_CUR_SRC_ADDR_REG   (DMA_BASE + 0x64)	// read only
+#define DMA2_CUR_SRC_ADDR_REG   (DMA_BASE + 0xa4)	// read only
+#define DMA3_CUR_SRC_ADDR_REG   (DMA_BASE + 0xe4)	// read only
+
+
+#define DMA0_DST_ADDR_REG       (DMA_BASE + 0x18)	// read/write
+#define DMA1_DST_ADDR_REG       (DMA_BASE + 0x58)	// read/write
+#define DMA2_DST_ADDR_REG       (DMA_BASE + 0x98)	// read/write
+#define DMA3_DST_ADDR_REG       (DMA_BASE + 0xd8)	// read/write
+#define DMA0_CUR_DEST_ADDR_REG  (DMA_BASE + 0x28)	// read only
+#define DMA1_CUR_DEST_ADDR_REG  (DMA_BASE + 0x68)	// read only
+#define DMA2_CUR_DEST_ADDR_REG  (DMA_BASE + 0xa8)	// read only
+#define DMA3_CUR_DEST_ADDR_REG  (DMA_BASE + 0xe8)	// read only
+
+
+#define DMA_CRC_REG  (DMA_BASE + 0xfc)	// read only
+
+
+/*
+ **********************************************************
+ * UART Definition
+ **********************************************************
+ */
+
+/*
+ *  Uart Control Register Structure (read/write)
+ */
+#define UART0_CONTROL_REG         (UART_BASE + 0x00)
+#define UART1_CONTROL_REG         (UART_BASE + 0x40)
+#define UART_CONTROL_RESET_VALUE  0x00000000
+#define UART_PRESCALE_FIELD     0
+#define   NBITS_UART_PRESCALE     8
+#define PRESCALE_EN_BIT         8
+#define MODEM_EN_BIT            9
+#define TX_DMA_EN_BIT          16
+#define TX_DMA_SEL_FIELD       17
+#define   NBITS_TX_DMA_SEL        2
+/*
+ * reserved bit 19
+ */
+#define RX_DMA_EN_BIT          20
+#define RX_DMA_SEL_FIELD       21
+#define   NBITS_RX_DMA_SEL        2
+
+
+/*
+ *  DLAB=0: Uart Rx Tx Register Structure       (read/write)
+ *  DLAB=1: Uart Divisor LSB Register Structure (read/write)
+ */
+#define UART0_RX_TX_REG  (UART_BASE + 0x20)
+#define UART1_RX_TX_REG  (UART_BASE + 0x60)
+#define DATA_FIELD    0
+#define   NBITS_DATA    8
+
+#define UART0_DIVISOR_LSB_REG  (UART_BASE + 0x20)
+#define UART1_DIVISOR_LSB_REG  (UART_BASE + 0x60)
+#define DIVISOR_LSB_FIELD    0
+#define   NBITS_DIVISOR_LSB    8
+
+
+/*
+ *  DLAB=0: Uart Interrupt Enable Register Structure (read/write)
+ *  DLAB=1: Uart Divisor MSB Register Structure      (read/write)
+ */
+#define UART0_INT_ENABLE_REG         (UART_BASE + 0x24)
+#define UART1_INT_ENABLE_REG         (UART_BASE + 0x64)
+#define UART_INT_ENABLE_RESET_VALUE  0x00000000
+#define RDRE_BIT   0
+#define THREE_BIT  1
+#define RLSE_BIT   2
+#define MSE_BIT    3
+
+#define UART0_DIVISOR_MSB_REG  (UART_BASE + 0x24)
+#define UART1_DIVISOR_MSB_REG  (UART_BASE + 0x64)
+#define DIVISOR_MSB_FIELD     0
+#define   NBITS_DIVISOR_MSB     8
+
+
+/*
+ *  Uart Interrupt ID Register Structure (read only)
+ *  Uart Fifo Control Register Structure (write only)
+ */
+#define UART0_INT_ID_REG         (UART_BASE + 0x28)
+#define UART1_INT_ID_REG         (UART_BASE + 0x68)
+#define UART_INT_ID_RESET_VALUE  0x00000001
+#define INT_ID_FIELD            0
+#define   NBITS_INT_ID            4
+#define FIFO_MODE_FIELD         6
+#define   NBITS_FIFO_MODE         2
+
+#define UART0_FIFO_CTRL_REG         (UART_BASE + 0x28)
+#define UART1_FIFO_CTRL_REG         (UART_BASE + 0x68)
+#define UART_FIFO_CTRL_RESET_VALUE  0x00000000
+#define FIFO_MODE_ENABLE_BIT      0
+#define RX_FIFO_CLR_BIT           1
+#define TX_FIFO_CLR_BIT           2
+#define FIFO_TRIG_LEVEL_FIELD     6
+#define   NBITS_FIFO_TRIG_LEVEL     2
+
+
+/*
+ *  Uart Line Control Register Structure (read/write)
+ */
+#define UART0_LINE_CONTROL_REG         (UART_BASE + 0x2c)
+#define UART1_LINE_CONTROL_REG         (UART_BASE + 0x6c)
+#define UART_LINE_CONTROL_RESET_VALUE  0x00000000
+#define STB_WLS_FIELD     0
+#define   NBITS_STB_WLS     3
+#define PEN_BIT           3
+#define EPS_BIT           4
+#define STICK_PARITY_BIT  5
+#define BREAK_BIT         6
+#define DLAB_BIT          7
+
+
+/*
+ *  Uart Modem Control Register Structure (read/write)
+ */
+#define UART0_MODEM_CONTROL_REG         (UART_BASE + 0x30)
+#define UART1_MODEM_CONTROL_REG         (UART_BASE + 0x70)
+#define UART_MODEM_CONTROL_RESET_VALUE  0x00000000
+#define DTR_BIT   0
+#define RTS_BIT   1
+#define LOOP_BIT  3
+
+
+/*
+ *  Uart Line Status Register Structure (read only)
+ */
+#define UART0_LINE_STATUS_REG         (UART_BASE + 0x34)
+#define UART1_LINE_STATUS_REG         (UART_BASE + 0x74)
+#define UART_LINE_STATUS_RESET_VALUE  0x00000060
+#define DR_BIT     0
+#define OE_BIT     1
+#define PE_BIT     2
+#define FE_BIT     3
+#define BI_BIT     4
+#define THRE_BIT   5
+#define TEMT_BIT   6
+#define ERROR_BIT  7
+
+
+/*
+ *  Uart Modem Status Register Structure (read only)
+ */
+#define UART0_MODEM_STATUS_REG         (UART_BASE + 0x38)
+#define UART1_MODEM_STATUS_REG         (UART_BASE + 0x78)
+#define UART_MODEM_STATUS_RESET_VALUE  0x00000000
+#define DELTA_CTS_BIT   0
+#define DELTA_DSR_BIT   1
+#define TERI_BIT        2
+#define DELTA_DCD_BIT   3
+#define CTS_BIT         4
+#define DSR_BIT         5
+#define RI_BIT          6
+#define DCD_BIT         7
+
+
+/*
+ *  Uart Scratchpad Register Structure (read/write)
+ */
+#define UART0_SCRATCHPAD_REG  (UART_BASE + 0x3c)
+#define UART1_SCRATCHPAD_REG  (UART_BASE + 0x7c)
+
+
+/*
+ **********************************************************
+ * Timer Unit Definition
+ **********************************************************
+ */
+/*
+ *  Timer Load Register Structure (read/write)
+ */
+#define TIMER0_LOAD_REG  (TIMER_BASE + 0x00)
+#define TIMER1_LOAD_REG  (TIMER_BASE + 0x20)
+#define LOAD_FIELD       0
+#define   NBITS_LOAD      16
+
+
+/*
+ *  Timer Value Register Structure (read only)
+ */
+#define TIMER0_VALUE_REG  (TIMER_BASE + 0x04)
+#define TIMER1_VALUE_REG  (TIMER_BASE + 0x24)
+#define VALUE_FIELD      0
+#define   NBITS_VALUE     16
+
+
+/*
+ *  Timer Control Register Structure (read/write)
+ */
+#define TIMER0_CONTROL_REG         (TIMER_BASE + 0x08)
+#define TIMER1_CONTROL_REG         (TIMER_BASE + 0x28)
+#define TIMER_CONTROL_RESET_VALUE  0x00000000
+#define PRESCALE_FIELD       2
+#define   NBITS_PRESCALE       2
+#define TIM_MODE_BIT         6
+#define TIM_ENABLE_BIT       7
+
+
+/*
+ *  Timer Clear Register Structure (write only)
+ *      Write a "1" to clear the timer interrupt.
+ *      Writing a "0" has no effect.
+ */
+#define TIMER0_CLEAR_REG  (TIMER_BASE + 0x0c)
+#define TIMER1_CLEAR_REG  (TIMER_BASE + 0x2c)
+#define TIM_INT_CLEAR_BIT   0
+
+
+/*
+ **********************************************************
+ * Watchdog Unit Definition
+ **********************************************************
+ */
+
+/*
+ *  Watchdog Control Register Structure (read/write)
+ *      Writing a '1' to the WD_RESET bit will reset the watchdog timer,
+ *      including its interrupt and reset logic. This bit is self-clearing.
+ */
+#define WATCHDOG_CONTROL_REG          (WD_BASE + 0x00)
+#define WATCHDOG_CONTROL_RESET_VALUE  0x00000000
+#define WD_ENABLE_BIT    0
+#define WD_RESET_BIT     1
+#define EN_WD_RST_BIT    2
+
+
+/*
+ *  Watchdog Timeout Value Register Structure (read/write)
+ */
+#define WATCHDOG_TIMEOUT_VAL_REG  (WD_BASE + 0x04)
+
+
+/*
+ *  Watchdog Current Value Register Structure (read only)
+ */
+#define WATCHDOG_CURRENT_VAL_REG  (WD_BASE + 0x08)
+
+
+/*
+ *  Watchdog Clear Register Structure (write only)
+ *      Writing a '1' to the WD_INT_CLR bit will clear the watchdog interrupt.
+ *      Writing a "0" has no effect.
+ */
+#define WATCHDOG_CLEAR_REG  (WD_BASE + 0x0c)
+#define WD_INT_CLR_BIT   0
+
+
+/*
+ ******************************************************************************
+ * Breakpoint Unit Definition
+ ******************************************************************************
+ */
+
+/*
+ * Breakpoint Control Register definition (read/write)
+ */
+#define BPU_BRK_CONTROL_REG      (BPU_BASE + 0x00)
+#define BRK_CONTROL_RESET_VALUE  0x00000000
+#define CPU_STIM_FIELD                 0
+#define   NBITS_CPU_STIM                 3
+#define CSL_FREEZE_BIT                 3
+#define CSL_MATCH_BIT                  4
+#define BP_TYPE_FIELD                  5
+#define   NBITS_BP_TYPE                  3
+#define RESTART_BIT                    8
+#define BP_ENABLE_FIELD                9
+#define   NBITS_BP_ENABLE                2
+#define BP0_NOT_MATCH_BIT             13
+#define BP1_NOT_MATCH_BIT             14
+#define ARB_FREEZE_BIT                15
+#define BUS_SEL_BIT                   16
+#define BP0_DATA_SEL_BIT              17
+#define BP1_DATA_SEL_BIT              18
+#define TRACE_EN_BIT                  20
+#define TRACE_FORMAT_FIELD            21
+#define   NBITS_TRACE_FORMAT             3
+#define CSL_CAPT_EN_BIT               24
+#define BCLK_FREEZE_BIT               25
+#define CPU_DBG_EN_BIT                26
+
+
+/*
+ * Breakpoint Bus Mask0/Compare0 Registers Definition (read/write)
+ */
+#define BPU_BRK0_BUS_MASK0_REG  (BPU_BASE + 0x04)
+#define BPU_BRK0_BUS_COMP0_REG  (BPU_BASE + 0x24)
+#define BPU_BRK1_BUS_MASK0_REG  (BPU_BASE + 0x14)
+#define BPU_BRK1_BUS_COMP0_REG  (BPU_BASE + 0x34)
+
+/*
+ * Breakpoint Bus Mask1/Compare1 Registers Definition (read/write)
+ */
+#define BPU_BRK0_BUS_MASK1_REG  (BPU_BASE + 0x08)
+#define BPU_BRK0_BUS_COMP1_REG  (BPU_BASE + 0x28)
+#define BPU_BRK1_BUS_MASK1_REG  (BPU_BASE + 0x18)
+#define BPU_BRK1_BUS_COMP1_REG  (BPU_BASE + 0x38)
+
+
+/*
+ * Breakpoint Bus Mask2/Compare2 Registers Definition (read/write)
+ */
+#define BPU_BRK0_BUS_MASK2_REG  (BPU_BASE + 0x0c)
+#define BPU_BRK0_BUS_COMP2_REG  (BPU_BASE + 0x2c)
+#define BPU_BRK1_BUS_MASK2_REG  (BPU_BASE + 0x1c)
+#define BPU_BRK1_BUS_COMP2_REG  (BPU_BASE + 0x3c)
+/*
+ * BUS MASK 2 for CPU BUS
+ */
+#define NRW_BIT               0
+#define MAS_FIELD             1
+#define   NBITS_MAS             2
+#define LOCK_BIT              3
+#define SEQ_BIT               4
+#define ABORT_BIT             5
+#define NTRANS_BIT            6
+#define NMREQ_BIT             7
+#define OPC_BIT               8
+#define DBGACK_BIT           17
+/*
+ * BUS MASK2 for CSI BUS
+ */
+#define SW_DMA_ACK_FIELD      0
+#define   NBITS_SW_DMA_ACK      4
+#define SW_MODE_FIELD         4
+#define   NBITS_SW_MODE         4
+#define SW_DMA_CTRL_FIELD     8
+#define   NBITS_SW_DMA_CTRL     4
+#define SW_SIZE_FIELD        12
+#define   NBITS_SW_SIZE         2
+#define SW_RD_EN_BIT         14
+#define SW_WR_EN_BIT         15
+#define SW_BP_CTRL_BIT       16
+#define RD_OR_WR_BIT         18
+#define OR_DMA_ACK_BIT       19
+#define RD_WR_ACK_BIT        20
+
+
+/*
+ * Breakpoint Bus Mask3 Registers Definition (read/write)
+ */
+#define BPU_BRK0_BUS_MASK3_REG  (BPU_BASE + 0x10)
+#define BPU_BRK1_BUS_MASK3_REG  (BPU_BASE + 0x20)
+#define FR_FIELD    0
+#define   NBITS_FR   11
+
+
+/*
+ * Breakpoint Counter Compare/Out Registers Definition
+ */
+#define BPU_BRK_CNT_COMP_REG  (BPU_BASE + 0x44)	// read/write
+#define BPU_BRK_CNT_OUT_REG   (BPU_BASE + 0x48)	// read only
+#define BRK_CNT0_FIELD     0
+#define   NBITS_BRK_CNT0    16
+#define BRK_CNT1_FIELD    16
+#define   NBITS_BRK_CNT1    16
+
+
+/*
+ * Trace Buffer Address Pointer Register Definition (read only)
+ * Trace Counter Register Definition (read/write)
+ */
+#define BPU_BRK_TR_ADDR_REG  (BPU_BASE + 0x4c)
+#define TRACE_ADDR_FIELD      0	// read only
+#define   NBITS_TRACE_ADDR      9	// read only
+#define TR_ADDR_FLIP_BIT      9	// read only
+#define TRACE_CNT_FIELD      16	// read/write
+#define   NBITS_TRACE_CNT       9	// read/write
+
+
+/*
+ * Breakpoint Interrupt Clear Register Definition (write only)
+ */
+#define BPU_BRK_INT_CLEAR_REG  (BPU_BASE + 0x50)
+#define BRK_INT_CLEAR_BIT   0
+
+
+/*
+ * Breakpoint Status Register Definition (read only)
+ */
+#define BPU_BRK_STATUS_REG  (BPU_BASE + 0x54)
+#define STAT_CPU_FREEZE_BIT   0
+#define STAT_CPU_IRQ_BIT      1
+#define STAT_ARB_FREEZE_BIT   6
+#define STAT_CSL_MATCH_BIT    7
+#define STAT_CSL_FREEZE_BIT   8
+#define STAT_CSL_STEP_BIT     9
+#define STAT_TRACE_FIN_BIT   10
+#define STAT_TRACE_EN_BIT    11
+#define STAT_BP0_CNT_TC_BIT  12
+#define STAT_BP1_CNT_TC_BIT  13
+#define STAT_BP_EVENT_BIT    14
+
+
+/*
+ * Trace Buffer Definition
+ *     The Trace Buffer is implemented in the Scratchpad RAM.
+ *     The buffer is a data array of 128-bit wide and 512 deep.
+ *     The trace can be moved relative to a programmed breakpoint event.
+ */
+/*
+ * CSI Trace Capture Description
+ */
+#if !defined( _ASMLANGUAGE ) && !defined( __ASSEMBLER__ )
+typedef struct
+{
+    unsigned int CsiSlaveWriteBusAddr;
+    unsigned int CsiSlaveWriteBusData;
+    unsigned int CsiControl;
+    unsigned int CsiMasterReadData;
+}
+CSI_TRACE;
+#endif
+
+/*
+ * CsiControl trace definition
+ */
+#define CSI_SW_DMAACK_FIELD      0
+#define   NBITS_CSI_SW_DMAACK      4
+#define CSI_SW_MODE_FIELD        4
+#define   NBITS_CSI_SW_MODE        4
+#define CSI_SW_DMA_CTRL_FIELD    8
+#define   NBITS_CSI_SW_DMA_CTRL    4
+#define CSI_SW_SIZE_FIELD       12
+#define   NBITS_CSI_SW_SIZE        2
+#define CSI_SW_RD_EN_BIT        14
+#define CSI_SW_WR_EN_BIT        15
+#define CSI_SR_BP_CTRL_BIT      16
+#define CSI_RD_OR_WR_BIT        18
+#define CSI_OR_DMA_ACK_BIT      19
+#define CSI_FR_FIELD            20
+#define   NBITS_CSI_FR            11
+#define CSI_SW_WAIT_NOW_BIT     31
+
+/*
+ * CPU Trace Capture Description
+ */
+#if !defined( _ASMLANGUAGE ) && !defined( __ASSEMBLER__ )
+
+typedef struct
+{
+    unsigned int CpuAddress;
+    unsigned int CpuData;
+    unsigned int CpuControl;
+    unsigned int Reserved;
+}
+CPU_TRACE;
+#endif
+
+/*
+ * CpuControl trace definition
+ */
+#define ARM_NRW_BIT         0
+#define ARM_MAS_FIELD       1
+#define   NBITS_ARM_MAS       2
+#define ARM_LOCK_BIT        3
+#define ARM_SEQ_BIT         4
+#define ARM_ABORT_BIT       5
+#define ARM_NTRANS_BIT      6
+#define ARM_NMREQ_BIT       7
+#define ARM_NOPC_BIT        8
+#define ARM_DBGACK_BIT     17
+#define ARM_CACHELINE_BIT  18
+#define ARM_TBIT       19
+#define ARM_NEXEC_BIT      20
+#define ARM_NM_FIELD       22
+#define   NBITS_ARM_NM        5
+#define ARM_NWAIT_BIT      27
+
+
+/*
+ ******************************************************************************
+ * Protection Unit Registers (PU_BASE)
+ ******************************************************************************
+ */
+
+/*
+ * Protection Unit Control Register definition (read/write)
+ */
+#define PU_CONTROL_REG         (PU_BASE + 0x04)
+#define PU_CONTROL_RESET_VALUE 0x00000000
+#define PROT_EN_BIT    0
+#define CACHE_EN_BIT   2
+
+
+/*
+ * Cacheable Area Register definition (read/write)
+ */
+#define PU_CACHEABLE_AREA_REG  (PU_BASE + 0x08)
+#define C_0_BIT  0
+#define C_1_BIT  1
+#define C_2_BIT  2
+#define C_3_BIT  3
+#define C_4_BIT  4
+#define C_5_BIT  5
+#define C_6_BIT  6
+#define C_7_BIT  7
+
+
+/*
+ * Protection Area Register definition (read/write)
+ */
+#define PU_PROTECTION_AREA_REG  (PU_BASE + 0x14)
+#define AP_0_FIELD      0
+#define   NBITS_AP_0      2
+#define AP_1_FIELD      2
+#define   NBITS_AP_1      2
+#define AP_2_FIELD      4
+#define   NBITS_AP_2      2
+#define AP_3_FIELD      6
+#define   NBITS_AP_3      2
+#define AP_4_FIELD      8
+#define   NBITS_AP_4      2
+#define AP_5_FIELD     10
+#define   NBITS_AP_5      2
+#define AP_6_FIELD     12
+#define   NBITS_AP_6      2
+#define AP_7_FIELD     14
+#define   NBITS_AP_7      2
+
+/*
+ * Memory Area Definition Registers definition (read/write)
+ *     These regsiters define 8 programmable regions in memory.
+ */
+#define PU_AREA_DEF0_REG  (PU_BASE + 0x20)
+#define PU_AREA_DEF1_REG  (PU_BASE + 0x24)
+#define PU_AREA_DEF2_REG  (PU_BASE + 0x28)
+#define PU_AREA_DEF3_REG  (PU_BASE + 0x2c)
+#define PU_AREA_DEF4_REG  (PU_BASE + 0x30)
+#define PU_AREA_DEF5_REG  (PU_BASE + 0x34)
+#define PU_AREA_DEF6_REG  (PU_BASE + 0x38)
+#define PU_AREA_DEF7_REG  (PU_BASE + 0x3c)
+#define AREA_EN_BIT           0
+#define AREA_SIZE_FIELD       1
+#define   NBITS_AREA_SIZE       5
+#define AREA_BASE_ADR_FIELD  12
+#define   NBITS_AREA_BASE      20
+
+
+/*
+ * Cache Invalidate Register definition (write only)
+ *     Reserved.
+ */
+#define PU_CACHE_INVALIDATE_REG  (PU_BASE + 0x1c)
+
+
+
+/*
+ **********************************************************
+ * Debug Unit Definition
+ **********************************************************
+ */
+
+/*
+ * Triscend A7 JTAG Instructions
+ */
+#define JTAG_EXTEST          0x00
+#define JTAG_SCAN_N          0x02
+#define JTAG_INTEST          0x0c
+#define JTAG_IDCODE          0x0e
+#define JTAG_BYPASS          0x0f
+#define JTAG_CLAMP           0x05
+#define JTAG_HIGHZ           0x07
+#define JTAG_CLAMPZ          0x09
+#define JTAG_SAMPLE_PRELOAD  0x03
+#define JTAG_RESTART         0x04
+#define JTAG_NONE            0xff
+
+/*
+ * Triscend A7 JTAG IDs
+ */
+#define JTAG_TA7S20     0x1843d2ff
+#define JTAG_TA7S20_AB  0x1f0f0f0f
+
+
+ /*
+    * Triscend A7 JTAG Scan Chains
+    *     The DEBUG chain is scanned with the msb first.
+    *     All other chains are scanned with the lsb first.
+  */
+#define SCAN_TEST_CHAIN        0
+#define DEBUG_CHAIN            1
+#define ICEBREAKER_CHAIN       2
+#define BOUNDARY_SCAN_CHAIN    3	// for Triscend internal use only
+#define INTERNAL_SCAN_CHAIN    5	// for Triscend internal use only
+#define BUSTAT_CHAIN           6
+#define BUSCON_CHAIN           7
+#define MEMORY_RW_CHAIN        9
+#define MEMORY_RW_INCR_CHAIN  10
+#define MEMORY_FILL_CHAIN     11
+#define CRC_CHANNEL_CHAIN     12
+
+/*
+ * Bitlengths of Triscend A7 JTAG registers/chains
+ */
+#define BITLEN_SCAN_N_REG             4
+#define BITLEN_IDENTIFICATION_REG    32
+#define BITLEN_BYPASS_REG             1
+#define BITLEN_INSTRUCTION_REG        4
+#define BITLEN_DEBUG_CHAIN           33
+#define BITLEN_ICEBREAKER_CHAIN      38
+#define BITLEN_BUSTAT_CHAIN          20
+#define BITLEN_BUSCON_CHAIN          12
+#define BITLEN_MEMORY_RW_CHAIN       68
+#define BITLEN_MEMORY_RW_INCR_CHAIN  34
+#define BITLEN_MEMORY_FILL_CHAIN     97
+#define BITLEN_CRC_CHANNEL_CHAIN     32
+
+
+/*
+ * Buscon chain bit defintion
+ */
+#define BUSCON_CPU_RESET_BIT        0
+#define BUSCON_CPU_FREEZE_BIT       1
+#define BUSCON_CPU_INT_BIT          2
+#define BUSCON_FORCE_CFGRST_BIT     3
+#define BUSCON_FORCE_NOCFGRST_BIT   4
+#define BUSCON_OSC_BREAK_BIT        5
+#define BUSCON_FORCE_BRST_BIT       6
+#define BUSCON_FORCE_NOBRST_BIT     7
+#define BUSCON_JTAG_BP_EVT_BIT      8
+
+/*
+ * BUSTAT chain bit definition
+ */
+#define BUSTAT_CPU_EXECUTING_BIT    0
+#define BUSTAT_DBG_ACK_BIT          1
+#define BUSTAT_BP_EVT_BIT           2
+#define BUSTAT_CPU_IN_RESET_BIT     3
+#define BUSTAT_BRST_STATUS_BIT      4
+#define BUSTAT_BCLK_STATUS_BIT      5
+#define BUSTAT_CFGRST_STATUS_BIT    6
+#define BUSTAT_END_OF_TRACE_BIT     7
+#define BUSTAT_CPU_RESET_BIT        8
+#define BUSTAT_CPU_FREEZE_BIT       9
+#define BUSTAT_CPU_INT_BIT         10
+#define BUSTAT_FORCE_CFGRST_BIT    11
+#define BUSTAT_FORCE_NOCFGRST_BIT  12
+#define BUSTAT_OSC_BREAK_BIT       13
+#define BUSTAT_FORCE_BRST_BIT      14
+#define BUSTAT_FORCE_NOBRST_BIT    15
+#define BUSTAT_JTAG_BP_EVT_BIT     16
+
+
+#endif /* _TRISCEND_A7_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/triscend_a7v.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/triscend_a7v.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/triscend_a7v.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/triscend_a7v.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,4436 @@
+/* $Id: //depot/software/SDK/Triscend/a7hal/include/triscend_a7v.h#31 $ */
+/*
+ ***************************************************************************
+ *  triscend_a7v.h
+ *
+ *  Copyright (c) 2002-2004 Triscend Corporation. All rights reserved.
+ *
+ ***************************************************************************
+ */
+#ifndef _TRISCEND_A7V_H
+#define _TRISCEND_A7V_H
+
+
+/*
+ **********************************************************
+ *  Field and Bit Manipulation Defines and Macros
+ **********************************************************
+ */
+#define A7_REG(reg) \
+    (*(volatile unsigned int*)(reg))
+
+#define BIT_MASK(bitIdx) \
+    (1 << (bitIdx))
+
+#define FIELD_MASK(fieldIdx,nBits) \
+    (((1 << (nBits)) - 1) << (fieldIdx))
+
+#define GET_BIT(addr32,bitIdx) \
+    (*(volatile unsigned int*)(addr32) & (1 << (bitIdx)) ? 1 : 0)
+
+#define PUT_BIT(addr32,bitIdx,bitVal) \
+    (*(volatile unsigned int*)(addr32) = (0 == (bitVal)) ? \
+     *(volatile unsigned int*)(addr32) & ~(1 << (bitIdx)) : \
+     *(volatile unsigned int*)(addr32) | (1 << (bitIdx)))
+
+#define SET_BIT(addr32,bitIdx) \
+    (*(volatile unsigned int*)(addr32) |= (1 << (bitIdx)))
+
+#define CLR_BIT(addr32,bitIdx) \
+    (*(volatile unsigned int*)(addr32) &= ~(1 << (bitIdx)))
+
+#define GET_FIELD(addr32,fieldIdx,nBits) \
+    ((*(volatile unsigned int*)(addr32) >> (fieldIdx)) & ((1 << (nBits)) - 1))
+
+#define PUT_FIELD(addr32,fieldIdx,nBits,fieldValue) \
+    (*(volatile unsigned int*)(addr32) = \
+    (*(volatile unsigned int*)(addr32) & ~FIELD_MASK(fieldIdx,nBits)) | \
+    (((fieldValue) << (fieldIdx)) & FIELD_MASK(fieldIdx,nBits)))
+
+#define SET_FIELD(addr32,fieldIdx,nBits) \
+    (*(volatile unsigned int*)(addr32) |= FIELD_MASK(fieldIdx,nBits))
+
+#define CLR_FIELD(addr32,fieldIdx,nBits) \
+    (*(volatile unsigned int*)(addr32) &= ~FIELD_MASK(fieldIdx,nBits))
+
+/*
+ **********************************************************
+ *  Memory Map
+ **********************************************************
+ */
+#define INTERNAL_ROM_BASE           0xd1000000UL
+#define INTERNAL_ROM_SIZE           0x00010000UL
+#define INTERNAL_RAM_BASE           0xd1030000UL
+#define INTERNAL_RAM_SIZE           0x00008000UL
+#define CONTROL_REG_BASE            0xd1010000UL
+#define CONTROL_REG_SIZE            0x00010000UL
+#define TEST_AREA_BASE              0xd1020000UL
+#define TEST_AREA_SIZE              0x00010000UL
+#define CONFIG_MEM_BASE             0xd1040000UL
+#define CONFIG_MEM_SIZE             0x00040000UL
+#define CSLDMA_BASE                 0xb0000000UL
+
+#define EXTERNAL_SDRAM_BASE         0xc0000000UL
+#define EXTERNAL_SDRAM_SIZE         0x10000000UL
+#define EXTERNAL_FLASH_RAM_0_BASE   0xd0000000UL
+#define EXTERNAL_FLASH_RAM_A_BASE   0xd2000000UL        // aliased FLASH_RAM_0
+#define EXTERNAL_FLASH_RAM_1_BASE   0xd3000000UL
+#define EXTERNAL_FLASH_RAM_SIZE     0x01000000UL
+
+/*
+ **********************************************************
+ * For backward compatibility with A7S
+ **********************************************************
+ */
+#define EXTERNAL_FLASH_BASE         EXTERNAL_FLASH_RAM_0_BASE
+#define EXTERNAL_FLASH_SIZE         EXTERNAL_FLASH_RAM_SIZE
+
+/*
+ **********************************************************
+ *  Control Register Base Address Definitions
+ **********************************************************
+ */
+#define MSS_BASE                    0xd1010000UL
+#define SYS_BASE                    0xd1010100UL
+#define INT_BASE                    0xd1010200UL
+#define REMAP_BASE                  0xd1010400UL
+#define TIMER_BASE                  0xd1010500UL
+#define WD_BASE                     0xd1010600UL
+#define CFG_BASE                    0xd1010700UL
+#define DMA_BASE                    0xd1010800UL
+#define UART_BASE                   0xd1010900UL
+#define BPU_BASE                    0xd1010a00UL
+#define PU_BASE                     0xd1011100UL
+
+#define DMAX_BASE                   0xd1010c00UL
+#define TWSI0_BASE                  0xd1010d00UL
+#define TWSI1_BASE                  0xd1010e00UL
+#define ENET0_BASE                  0xd1011200UL
+#define SSI_BASE                    0xd1011300UL
+#define MFTA_BASE                   0xd1011400UL
+#define ADC_BASE                    0xd1011500UL
+#define CAN_BASE                    0xd1011800UL
+#define ENET1_BASE                  0xd1011C00UL
+#define USB_BASE                    0xd1012000UL
+
+
+/*
+ **********************************************************
+ *  Register Access Attributes
+ **********************************************************
+ */
+#define READ_ACCESS                 1
+#define WRITE_ACCESS                2
+
+/*
+ **********************************************************
+ * Memory Subsystem Unit Definition
+ **********************************************************
+ */
+
+/*
+ *  Memory Subsystem Configuration Register (read/write)
+ *      Device Width encoding:
+ *          00: Byte     ( 8bit)
+ *          01: Halfword (16bit)
+ *          10: Word     (32bit)
+ *          11: Reserved
+ */
+#define MSS_CONFIG_REG              (MSS_BASE + 0x00)
+#define MSS_CONFIG_REG_ACCESS       (READ_ACCESS | WRITE_ACCESS)
+#define MSS_CONFIG_RESET_VALUE      0x00000002UL
+#define BUS_MODE_FIELD              0
+#define   NBITS_BUS_MODE              4
+#define MIU_DEV_WIDTH_FIELD         4
+#define   NBITS_MIU_DEV_WIDTH         2
+#define SDIU_DEV_WIDTH_FIELD        6
+#define   NBITS_SDIU_DEV_WIDTH        2
+#define R_MAP_FIELD                 8
+#define   NBITS_R_MAP                 2
+#define B_MAP_FIELD                 10
+#define   NBITS_B_MAP                 3
+#define N_BANK_BIT                  13
+#define NE_BANK_BIT                 14
+#define PIPE_BIT                    15
+#define DMA_0_BUF_EN_BIT            16
+#define DMA_1_BUF_EN_BIT            17
+#define DMA_2_BUF_EN_BIT            18
+#define DMA_3_BUF_EN_BIT            19
+#define DMA_4_BUF_EN_BIT            20
+#define DMA_5_BUF_EN_BIT            21
+#define DMA_6_BUF_EN_BIT            22
+#define DMA_BUF_EN_RESERVED_BIT     23
+#define MSS_CONFIG_RESERVED_24      24
+#define R_MAP_BIT_2                 26
+
+
+/*
+ *  CS1 Memory Subsystem Configuration Register (read/write)
+ *      Device Width encoding:
+ *          00: Byte     ( 8bit)
+ *          01: Halfword (16bit)
+ *          10: Word     (32bit)
+ *          11: Reserved
+ *      CS1 Size Field encoding:
+ *          0xff:  64K
+ *          0xfe: 128K
+ *          0xfc: 256K
+ *          0xf8: 512K
+ *          0xf0:   1M
+ *          0xe0:   2M
+ *          0xc0:   4M
+ *          0x80:   8M
+ *          0x00:  16M
+ */
+#define MSS_CS1_CONFIG_REG          (MSS_BASE + 0x18)
+#define MSS_CS1_CONFIG_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define MSS_CS1_CONFIG_RESET_VALUE  0x00000002UL
+#define CS1_DEV_WIDTH_FIELD         0
+#define   NBITS_CS1_DEV_WIDTH         2
+#define CS1_SIZE_FIELD              8
+#define   NBITS_CS1_SIZE              8
+
+
+/*
+ *  Static Memory Interface Timing Control Registers (read/write)
+ */
+#define MSS_CS0_TIM_CTRL_REG        (MSS_BASE + 0x04)
+#define MSS_CS1_TIM_CTRL_REG        (MSS_BASE + 0x1c)
+#define MSS_TIM_CTRL_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define MSS_TIM_CTRL_RESET_VALUE    0x00077777UL
+#define WC_SETUP_FIELD              0
+#define   NBITS_WC_SETUP              4
+#define WC_WIDTH_FIELD              4
+#define   NBITS_WC_WIDTH              4
+#define WC_HOLD_FIELD               8
+#define   NBITS_WC_HOLD               4
+#define RC_SETUP_FIELD              12
+#define   NBITS_RC_SETUP              4
+#define RC_WIDTH_FIELD              16
+#define   NBITS_RC_WIDTH              4
+
+
+/*
+ *  SDRAM Mode Register (read/write)
+ */
+#define MSS_SDR_MODE_REG            (MSS_BASE + 0x08)
+#define MSS_SDR_MODE_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define MSS_SDR_MODE_RESET_VALUE    0x02223222UL
+#define TRP_FIELD                   0
+#define   NBITS_TRP                   3
+#define TRCD_FIELD                  4
+#define   NBITS_TRCD                  3
+#define TWR_FIELD                   8
+#define   NBITS_TWR                   3
+#define TRC_FIELD                   12
+#define   NBITS_TRC                   3
+#define MODE_REG_FIELD              16
+#define   NBITS_MODE_REG              14
+
+
+/*
+ *  SDRAM Control Register (read/write)
+ */
+#define MSS_SDR_CTRL_REG            (MSS_BASE + 0x0c)
+#define MSS_SDR_CTRL_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define MSS_SDR_CTRL_RESET_VALUE    0x00000000UL
+#define PWR_MAN_FIELD               0
+#define   NBITS_PWR_MAN               3
+#define REF_EN_BIT                  3
+#define RFSH_RATE_FIELD             16
+#define   NBITS_RFSH_RATE             12
+#define RFSH_BURST_FIELD            28
+#define   NBITS_RFSH_BURST            4
+
+
+/*
+ *  SDRAM Status Register (read only)
+ *      SDRAM Status Field interpretation:
+ *          000: SDRAM controller is in normal operation
+ *          001: SDRAM controller is disabled
+ *          010: SDRAM controller is in self-refresh mode
+ *          100: SDRAM controller is in stand-by mode
+ */
+#define MSS_STATUS_REG              (MSS_BASE + 0x10)
+#define MSS_STATUS_REG_ACCESS       (READ_ACCESS)
+#define MSS_STATUS_RESET_VALUE      0x00000300UL
+#define SD_STATUS_FIELD             0
+#define   NBITS_SD_STATUS             3
+#define RFSH_OVF_BIT                3
+
+
+/*
+ *  SDRAM Status Clear Register (write only)
+ *      write 1 to clear the corresponding status reg bit
+ */
+#define MSS_STATUS_CLEAR_REG        (MSS_BASE + 0x14)
+#define MSS_STATUS_CLEAR_REG_ACCESS (WRITE_ACCESS)
+#define RFSH_OVF_CLR_BIT            3
+
+/*
+ **********************************************************
+ *  System Control Registers
+ **********************************************************
+ */
+
+/*
+ *  Clock Control Register (read/write)
+ */
+#define SYS_CLOCK_CONTROL_REG       (SYS_BASE + 0x00)
+#define SYS_CLOCK_CONTROL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CLOCK_CONTROL_RESET_VALUE   0x00000200UL
+#define CLK_SEL_BIT                 0
+#define PLL_SEL_BIT                 1
+#define CSL_SEL_BIT                 2
+#define CK_EN_BIT                   3
+#define XTAL_EN_BIT                 4
+#define OSC_SMT_BIT                 8
+#define OSC_FEB_BIT                 9
+#define OSC_EB_BIT                  10
+#define OSC_S_BIT                   11
+
+
+/*
+ *  PLL Control Register (read/write)
+ *      PLL lock: wait 500 reference cycles after de-asserting PLL reset
+ *      CLK_freq_out = CLK_reference * (CLKF+1) / ( (CLKR+1) * (CLKOD+1) )
+ */
+#define SYS_PLL_CONTROL_REG         (SYS_BASE + 0x14)
+#define SYS_PLL_CONTROL_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define PLL_CONTROL_RESET_VALUE     0x00000003UL
+#define PLL_RESET_BIT               0
+#define PLL_POWERDOWN_BIT           1
+#define PLL_BYPASS_BIT              2
+#define PLL_TEST_BIT                3
+#define PLL_REFSEL_BIT              4
+#define PLL_CLKF_FIELD              8   // PLL Feedback Divider
+#define   NBITS_PLL_CLKF              12
+#define PLL_CLKOD_FIELD             20  // PLL Output Divider
+#define   NBITS_PLL_CLKOD             3
+#define PLL_CLKR_FIELD              24
+#define   NBITS_PLL_CLKR              6 // PLL Reference divider
+
+
+/*
+ *  PLL Status Register (read only)
+ */
+#define SYS_PLL_STATUS_REG          (SYS_BASE + 0x04)
+#define SYS_PLL_STATUS_REG_ACCESS   (READ_ACCESS)
+#define PLL_STATUS_RESET_VALUE      0x00000001UL
+#define PLL_NOT_LOCK_BIT            0
+
+
+/*
+ *  PLL Status Clear Register (write only)
+ *      Write a '1' to clear the NotLock bit in the PLL status register
+ */
+#define SYS_PLL_STATUS_CLEAR_REG    (SYS_BASE + 0x08)
+#define SYS_PLL_STATUS_CLEAR_REG_ACCESS (WRITE_ACCESS)
+#define PLL_NOT_LOCK_CLEAR_BIT      0
+
+
+/*
+ *  Reset Control Register (read/write)
+ *      Write a '1' to assert the System Reset.
+ *      The System Reset bit is self-clearing.
+ */
+#define SYS_RESET_CONTROL_REG       (SYS_BASE + 0x0c)
+#define SYS_RESET_CONTROL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define RESET_CONTROL_RESET_VALUE   0x00000000UL
+#define SLAVE_DIS_BIT               1
+#define SYS_RESET_BIT               2
+
+
+/*
+ *  Power Down Control Register (read/write)
+ *      User can select which portion of the device is
+ *      turned off or kept on during power down mode.
+ *      Setting a bit turns off the circuit in power down.
+ *      A zero keeps the circuit running at all times.
+ */
+#define SYS_POWER_CONTROL_REG       (SYS_BASE + 0x10)
+#define SYS_POWER_CONTROL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define POWER_CONTROL_RESET_VALUE   0x00000000UL
+#define PD_BCK_EN_BIT               0
+#define PD_CSL_BCK_EN_BIT           1
+#define PD_OSC_EN_BIT               2
+#define PD_IO_EN_BIT                3
+#define PD_BIT                      4
+#define POR_DIS_BIT                 5
+
+
+/*
+ **********************************************************
+ *  Remap Control Registers
+ **********************************************************
+ */
+
+/*
+ *  Pause Register (write only)
+ *      Writing to this register puts the ARM core (only) in
+ *      a low power state until receiving an interrupt.
+ */
+#define REMAP_PAUSE_REG             (REMAP_BASE + 0x00)
+#define REMAP_PAUSE_ACCESS          (WRITE_ACCESS)
+
+
+/*
+ *  Identification Register (read only)
+ */
+#define REMAP_IDENTIFICATION_REG    (REMAP_BASE + 0x10)
+#define REMAP_IDENTIFICATION_REG_ACCESS (READ_ACCESS)
+#define TRISCEND_A7Vx05             0x08c9d2ffUL
+
+
+/*
+ *  Revision Register (read only)
+ */
+#define REMAP_REVISION_REG          (REMAP_BASE + 0x14)
+#define REMAP_REVISION_REG_ACCESS   (READ_ACCESS)
+#define SEMI_CUSTOM_REV_FIELD       0
+#define   NBITS_SEMI_CUSTOM_REV       4
+#define ROM_REV_FIELD               4
+#define   NBITS_ROM_REV               4
+#define CSL_REV_FIELD               8
+#define   NBITS_CSL_REV               4
+#define IO_REV_FIELD                12
+#define   NBITS_IO_REV                4
+#define MISC_REV_FIELD              16
+#define   NBITS_MISC_REV              4
+
+
+/*
+ *  Clear Reset Map Register (write only)
+ *      Writing to this address causes a system memory map switch from the
+ *      user initial memory map to the one used during normal operation.
+ *      It effectively clears the Flash alias bit in the Alias Enable Register.
+ */
+#define REMAP_CLEAR_RESET_MAP_REG   (REMAP_BASE + 0x20)
+#define REMAP_CLEAR_RESET_MAP_REG_ACCESS (WRITE_ACCESS)
+
+
+/*
+ *  Reset Status Register (read only)
+ *      Indicates the cause of the latest reset.
+ *      Default reset value depends on reset cause.
+ */
+#define REMAP_RESET_STATUS_REG      (REMAP_BASE + 0x30)
+#define REMAP_RESET_STATUS_REG_ACCESS (READ_ACCESS)
+#define POR_BIT                     0
+#define CFG_RST_BIT                 1
+#define RST_PIN_BIT                 2
+#define J_CFG_RST_BIT               3
+#define CPU_RST_BIT                 4
+#define J_CPU_RST_BIT               5
+#define WD_RST_BIT                  6
+#define APP_RST_BIT                 7
+#define SYS_RST_BIT                 8
+#define J_SYS_RST_BIT               9
+#define SOFT_RST_BIT                10
+
+
+/*
+ *  Reset Status Clear Register (write only)
+ *      Writing a "1" clears the corresponding bit in Reset Status Register.
+ *      Writing a "0" has no effect.
+ */
+#define REMAP_RESET_STATUS_CLEAR_REG (REMAP_BASE + 0x34)
+#define REMAP_RESET_STATUS_CLEAR_REG_ACCESS (WRITE_ACCESS)
+#define POR_CLR_BIT                 0
+#define CFG_RST_CLR_BIT             1
+#define RST_PIN_CLR_BIT             2
+#define J_CFG_RST_CLR_BIT           3
+#define CPU_RST_CLR_BIT             4
+#define J_CPU_RST_CLR_BIT           5
+#define WD_RST_CLR_BIT              6
+#define APP_RST_CLR_BIT             7
+#define SYS_RST_CLR_BIT             8
+#define J_SYS_RST_CLR_BIT           9
+#define SOFT_RST_CLR_BIT            10
+
+
+/*
+ *  Pin Status Register (read only)
+ *      This register enables software to get the status of
+ *      some static pins of the device.
+ */
+#define REMAP_PIN_STATUS_REG        (REMAP_BASE + 0x38)
+#define REMAP_PIN_STATUS_REG_ACCESS (READ_ACCESS)
+#define VSYS_BIT                    0
+#define RSTN_BIT                    1
+#define SLAVEN_BIT                  2
+#define VSYS_GOOD_BIT               3
+#define VSYS_BAD_BIT                4
+
+
+/*
+ *  Pin Status Clear Register (write only)
+ *      Writing a "1" clears the corresponding bit in the Pin Status Register.
+ *      Writing a "0" has no effect.
+ */
+#define REMAP_PIN_STATUS_CLEAR_REG  (REMAP_BASE + 0x3c)
+#define REMAP_PIN_STATUS_CLEAR_REG_ACCESS (WRITE_ACCESS)
+#define VSYS_GOOD_CLR_BIT           3
+#define VSYS_BAD_CLR_BIT            4
+
+
+/*
+ *  Alias Enable Register (read/write)
+ *      This register defines which alias is enabled at the bottom of the
+ *      memory starting at address 0. If more than one alias is enabled,
+ *      they are overlaid over each other with the following priority
+ *      (from highest to lowest priority):
+ *      1. Internal ROM
+ *      2. FLASH (CS0)
+ *      3. SRAM
+ *      4. FLASH (CS1)
+ *      5. SDRAM
+ */
+#define REMAP_ALIAS_ENABLE_REG      (REMAP_BASE + 0x40)
+#define REMAP_ALIAS_ENABLE_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define ALIAS_ENABLE_RESET_VALUE    0x0000001fUL
+#define ROM_AEN_BIT                 0
+#define FLASH_AEN_BIT               1
+#define SRAM_AEN_BIT                2
+#define SDRAM_AEN_BIT               3
+#define CS1_AEN_BIT                 4
+
+
+/*
+ *  Scratchpad SRAM Config Register (read/write)
+ *	    The SRAM size bit is set to 1 when tracing, thus blocking
+ *      CPU & CSI access to upper 8K SRAM (for use as trace buffer).
+ *          bit = 0 : SRAM size = 16K
+ *		    bit = 1 : SRAM size =  8K (lower)
+ *      Each SRAM protection bit protects a 4KB block from CSI accesses.
+ */
+#define REMAP_SRAM_CONFIG_REG       (REMAP_BASE + 0x44)
+#define REMAP_SRAM_CONFIG_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define SRAM_CONFIG_RESET_VALUE     0x00000000UL
+#define SRAM_PRIO_BIT               0
+#define SRAM_TRACE_EN_BIT           1
+#define SRAM_PROTECT_FIELD          2
+#define   NBITS_SRAM_PROTECT          8
+#define SRAM_ORG_BIT               11
+
+/*
+ *  Scratchpad SRAM Base Address Register (read/write)
+ *      Used to relocate the internal SRAM (scratchpad).
+ */
+#define REMAP_SRAM_BASE_ADR_REG     (REMAP_BASE + 0x48)
+#define REMAP_SRAM_BASE_ADR_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define SRAM_BASE_ADR_RESET_VALUE   0xd1030000UL
+#define SRAM_BASE_ADR_FIELD         14
+#define   NBITS_SRAM_BASE_ADR         18
+
+
+/*
+ *  Access Protect Register (read/write)
+ *      Setting dmaDis bit disallows DMA writes into Control Register area.
+ *      Setting testEn bit allows access to co-processor registers and Cache.
+ */
+#define REMAP_ACC_PROTECT_REG       (REMAP_BASE + 0x4c)
+#define REMAP_ACC_PROTECT_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define ACC_PROTECT_RESET_VALUE     0x00000001UL
+#define DMA_DIS_BIT                 0
+#define TEST_EN_BIT                 1
+
+/*
+ * USB Configuration Register.
+ */
+#define USB_CONFIG_REG              (REMAP_BASE + 0x50)
+#define USB_CONFIG_ACCESS           (READ_ACCESS | WRITE_ACCESS)
+#define USB_CONFIG_RESET_VALUE      0x00000000UL
+#define USB_RESET_BIT               0
+#define USB_ENABLE_BIT              1
+#define USB_INTERNAL_PHY_ENABLE_BIT 2
+#define USB_BUS_CLOCK_SELECT_BIT    3
+
+/*
+ * USB PHY Test Register.
+ */
+#define USB_PHY_TEST_REG            (REMAP_BASE + 0x54)
+#define USB_PHY_TEST_ACCESS         (READ_ACCESS | WRITE_ACCESS)
+#define USB_PHY_TEST_RESET_VALUE    0x00000000UL
+#define USB_RAM_TEST_ENABLE_BIT     0
+#define USB_PHY_TEST_ENABLE_BIT     1
+#define USB_PHY_VPO_BIT             2
+#define USB_PHY_VMO_BIT             3
+#define USB_PHY_OEB_BIT             4
+#define USB_PHY_EB_BIT              5
+#define USB_PHY_SP_BIT              6
+#define USB_PHY_VP_BIT              8
+#define USB_PHY_VM_BIT              9
+#define USB_PHY_RCV_BIT             10
+
+/*
+ **********************************************************
+ *  Configuration Unit Definition
+ **********************************************************
+ */
+
+/*
+ *  Configuration Control Register (read/write)
+ *      I/O Enable    : used to disable PIO during configuration.
+ *      Config Done   : used to blank signals coming from CSL during config.
+ *      Decode Enable : used to force '0' on CSL row and column addresses.
+ *      Config Stop   : used to gate off clocks used for config (saves power).
+ */
+#define CFG_CONFIG_CONTROL_REG      (CFG_BASE + 0x00)
+#define CFG_CONFIG_CONTROL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CONFIG_CONTROL_RESET_VALUE  0x00000000UL
+#define EN_ZIP_BIT                  0
+#define EN_REG_BIT                  1
+#define EN_IO_BIT                   2
+#define CONFIG_DONE_BIT             4
+#define DEC_EN_BIT                  5
+#define CFGENS_EN_BIT               6
+#define CFG_STOP_BIT                7
+#define CFG_CRC_EN_BIT              8
+#define CFG_CRC_RSTN_BIT            9
+#define ADEC_TST_BIT                10
+
+
+/*
+ *  Configuration Timing Register (read/write)
+ *      CSL Configuration Access Wait States:
+ *          generated by config unit in response to CSL reads.
+ *          number of wait states = cslWait
+ *      PIO Phase Delay:
+ *          length in clock cycles of PIO config read & write phases.
+ *          length in clock cycles = (pioPhase - 1)
+ */
+#define CFG_CONFIG_TIMING_REG       (CFG_BASE + 0x04)
+#define CFG_CONFIG_TIMING_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CONFIG_TIMING_RESET_VALUE   0x00000024UL
+#define CSL_WAIT_FIELD              0
+#define   NBITS_CSL_WAIT              3
+#define PIO_PHASE_FIELD             3
+#define   NBITS_PIO_PHASE             3
+
+
+/*
+ *  IO Recover Register (read/write)
+ *      bit = 0 : I/O pin is reclaimed by User
+ *      bit = 1 : I/O pin is reserved by System
+ */
+#define CFG_IO_RECOVER_REG          (CFG_BASE + 0x08)
+#define CFG_IO_RECOVER_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define IO_RECOVER_RESET_VALUE      0x00008061UL
+#define SD_SEL_BIT                  0
+#define WEN1_SEL_BIT                1
+#define WEN2_SEL_BIT                2
+#define WEN3_SEL_BIT                3
+#define XDONE_SEL_BIT               4
+#define A18_SEL_BIT                 5
+#define A19_SEL_BIT                 6
+#define A20_SEL_BIT                 7
+#define A21_SEL_BIT                 8
+#define A22_SEL_BIT                 9
+#define A23_SEL_BIT                 10
+#define A24_TO_A31_SEL_BIT          11
+#define D8_TO_D15_SEL_BIT           12
+#define D16_TO_D31_SEL_BIT          13
+#define ECLK_SEL_BIT                14
+#define SDCEN1_SEL_BIT              15
+#define ENET0_MII_SEL_BIT           18
+#define ENET0_MD_SEL_BIT            19
+#define ENET0_X_SEL_BIT             20
+#define CEN1_SEL_BIT                21
+#define CAN_SEL_BIT                 22
+#define SSI_SEL_BIT                 23
+#define ENET1_MII_SEL_BIT           24
+#define ENET1_MD_SEL_BIT            25
+#define ENET1_X_SEL_BIT             26
+#define USB_EXT_SEL_BIT             27
+#define USB_PDN_SEL_BIT             28
+#define USB_CLK_SEL_BIT             29
+#define TWSI0_SEL_BIT               30
+#define TWSI1_SEL_BIT               31
+
+/*
+ *  Configuration Protection Register (read/write)
+ *      When a protection bit is set, the configuration plane
+ *      is protected from read or write accesses. (Read data = 0).
+ *      Once this bit is set, it can only be cleared through a power cycle.
+ */
+#define CFG_CONFIG_PROTECT_REG      (CFG_BASE + 0x0c)
+#define CFG_CONFIG_PROTECT_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CONFIG_PROTECT_RESET_VALUE  0x00000000UL
+#define RD_SECURE_BIT               0
+#define WR_SECURE_BIT               1
+
+
+/*
+ **********************************************************
+ * Interrupt Unit Definition
+ **********************************************************
+ */
+
+/*
+ *  Interrupt Registers Definition
+ */
+#define INT_IRQ_STATUS_REG          (INT_BASE + 0x00)
+#define INT_IRQ_STATUS_REG_ACCESS   (READ_ACCESS)
+#define IRQ_STATUS_RESET_VALUE      0x00000000UL
+
+#define INT_IRQ_RAW_STATUS_REG      (INT_BASE + 0x04)
+#define INT_IRQ_RAW_STATUS_REG_ACCESS (READ_ACCESS)
+#define IRQ_RAW_STATUS_RESET_VALUE  0x00000000UL
+
+#define INT_IRQ_ENABLE_REG          (INT_BASE + 0x08)
+#define INT_IRQ_ENABLE_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define IRQ_ENABLE_RESET_VALUE      0x00000000UL
+
+#define INT_IRQ_ENABLE_CLEAR_REG    (INT_BASE + 0x0c)
+#define INT_IRQ_ENABLE_CLEAR_REG_ACCESS (WRITE_ACCESS)
+
+/* 
+ *  IRQ Software Reg provides a software mechanism to generate interrupts.
+ */
+#define INT_IRQ_SOFT_REG            (INT_BASE + 0x10)
+#define INT_IRQ_SOFT_REG_ACCESS     (WRITE_ACCESS)
+#define SOFT_IRQ_BIT                1
+
+/* 
+ *  IRQ Vector Enable Reg is used to enable individual hardware vectors.
+ */
+#define INT_IRQ_VECTOR_EN_REG       (INT_BASE + 0x20)
+#define INT_IRQ_VECTOR_EN_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define IRQ_VECTOR_EN_RESET_VALUE   0x00000000UL
+#define IRQ_VEC0_EN_BIT             0
+#define IRQ_VEC1_EN_BIT             1
+#define IRQ_VEC2_EN_BIT             2
+#define IRQ_VEC3_EN_BIT             3
+#define IRQ_VEC4_EN_BIT             4
+#define IRQ_VEC5_EN_BIT             5
+#define IRQ_VEC6_EN_BIT             6
+#define IRQ_VEC7_EN_BIT             7
+
+/* 
+ *  The 5-bit value in the IRQ Vector Source Reg is used to
+ *      assign an interrupt source to an interrupt vector.
+ */
+#define INT_IRQ_VECTOR0_SRC_REG     (INT_BASE + 0x24)
+#define INT_IRQ_VECTOR0_SRC__REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define IRQ_VECTOR0_SRC_RESET_VALUE 0x00000000UL
+
+#define INT_IRQ_VECTOR1_SRC_REG     (INT_BASE + 0x28)
+#define INT_IRQ_VECTOR1_SRC_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define IRQ_VECTOR1_SRC_RESET_VALUE 0x00000000UL
+
+#define INT_IRQ_VECTOR2_SRC_REG     (INT_BASE + 0x2c)
+#define INT_IRQ_VECTOR2_SRC_REG_CCESS (READ_ACCESS | WRITE_ACCESS)
+#define IRQ_VECTOR2_SRC_RESET_VALUE 0x00000000UL
+
+#define INT_IRQ_VECTOR3_SRC_REG     (INT_BASE + 0x30)
+#define INT_IRQ_VECTOR3_SRC__REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define IRQ_VECTOR3_SRC_RESET_VALUE 0x00000000UL
+
+#define INT_IRQ_VECTOR4_SRC_REG     (INT_BASE + 0x34)
+#define INT_IRQ_VECTOR4_SRC_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define IRQ_VECTOR4_SRC_RESET_VALUE 0x00000000UL
+
+#define INT_IRQ_VECTOR5_SRC_REG     (INT_BASE + 0x38)
+#define INT_IRQ_VECTOR5_SRC_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define IRQ_VECTOR5_SRC_RESET_VALUE 0x00000000UL
+
+#define INT_IRQ_VECTOR6_SRC_REG     (INT_BASE + 0x3c)
+#define INT_IRQ_VECTOR6_SRC_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define IRQ_VECTOR6_SRC_RESET_VALUE 0x00000000UL
+
+#define INT_IRQ_VECTOR7_SRC_REG     (INT_BASE + 0x40)
+#define INT_IRQ_VECTOR7_SRC_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define IRQ_VECTOR7_SRC_RESET_VALUE 0x00000000UL
+
+#define IRQ_VEC_SRC_FIELD           0
+#define   NBITS_IRQ_VEC_SRC           5
+
+
+/* 
+ *  The 32-bit value in the IRQ Vector Reg substitutes the instruction
+ *      that is fetched for the corresponding IRQ vector.
+ */
+#define INT_IRQ_VECTOR_DEF_REG      (INT_BASE + 0x60)
+#define INT_IRQ_VECTOR_DEF_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+
+#define INT_IRQ_VECTOR0_REG         (INT_BASE + 0x64)
+#define INT_IRQ_VECTOR0_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+
+#define INT_IRQ_VECTOR1_REG         (INT_BASE + 0x68)
+#define INT_IRQ_VECTOR1_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+
+#define INT_IRQ_VECTOR2_REG         (INT_BASE + 0x6c)
+#define INT_IRQ_VECTOR2_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+
+#define INT_IRQ_VECTOR3_REG         (INT_BASE + 0x70)
+#define INT_IRQ_VECTOR3_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+
+#define INT_IRQ_VECTOR4_REG         (INT_BASE + 0x74)
+#define INT_IRQ_VECTOR4_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+
+#define INT_IRQ_VECTOR5_REG         (INT_BASE + 0x78)
+#define INT_IRQ_VECTOR5_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+
+#define INT_IRQ_VECTOR6_REG         (INT_BASE + 0x7c)
+#define INT_IRQ_VECTOR6_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+
+#define INT_IRQ_VECTOR7_REG         (INT_BASE + 0x80)
+#define INT_IRQ_VECTOR7_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+
+#define INT_FIQ_STATUS_REG          (INT_BASE + 0x100)
+#define INT_FIQ_STATUS_REG_ACCESS   (READ_ACCESS)
+#define FIQ_STATUS_RESET_VALUE      0x00000000UL
+
+#define INT_FIQ_RAW_STATUS_REG      (INT_BASE + 0x104)
+#define INT_FIQ_RAW_STATUS_REG_ACCESS (READ_ACCESS)
+#define FIQ_RAW_STATUS_RESET_VALUE  0x00000000UL
+
+#define INT_FIQ_ENABLE_REG          (INT_BASE + 0x108)
+#define INT_FIQ_ENABLE_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define FIQ_ENABLE_RESET_VALUE      0x00000000UL
+#define FIQ_EN_BIT                  0
+
+#define INT_FIQ_ENABLE_CLEAR_REG    (INT_BASE + 0x10c)
+#define INT_FIQ_ENABLE_CLEAR_REG_ACCESS (WRITE_ACCESS)
+#define FIQ_EN_CLR_BIT              0
+
+#define INT_IRQ_STEER_REG           (INT_BASE + 0x110)
+#define INT_IRQ_STEER_REG_ACCESS    (WRITE_ACCESS)
+#define IRQ_STEER_RESET_VALUE       0x00000000UL
+
+
+/*
+ *  Interrupt Bits Definition
+ */
+#define FIQ_BIT                     0
+#define IRQ_SOFTWARE_BIT            1
+#define IRQ_SERIAL_0_BIT            2
+#define IRQ_TIMER_0_BIT             3
+#define IRQ_TIMER_1_BIT             4
+#define IRQ_SERIAL_1_BIT            5
+#define IRQ_WATCHDOG_BIT            6
+#define IRQ_DMA_0_BIT               7
+#define IRQ_DMA_1_BIT               8
+#define IRQ_DMA_2_BIT               9
+#define IRQ_DMA_3_BIT               10
+#define IRQ_CSL_USER_0_BIT          11
+#define IRQ_CSL_USER_1_BIT          12
+#define IRQ_CSL_USER_2_BIT          13
+#define IRQ_JTAG_BIT                14
+#define IRQ_BREAKPOINT_BIT          15
+#define IRQ_MFTA_BIT                16
+#define IRQ_TWSI0_BIT               17
+#define IRQ_TWSI1_BIT               18
+#define IRQ_DMA_4_BIT               19
+#define IRQ_DMA_5_BIT               20
+#define IRQ_USB_BIT                 21
+#define IRQ_MAC0_TX_BIT             22
+#define IRQ_MAC0_RX_BIT             23
+#define IRQ_DMA_6_BIT               24
+#define IRQ_DMA_7_BIT               25
+#define IRQ_PLL_BIT                 26
+#define IRQ_MAC1_TX_BIT             27
+#define IRQ_MAC1_RX_BIT             28
+#define IRQ_CAN_BIT                 29
+#define IRQ_ADC_BIT                 30
+
+
+/*
+ ***********************************************************
+ * DMA Unit Definition
+ ***********************************************************
+ */
+
+/*
+ *  DMA Control Registers Definition (read/write)
+ */
+#define DMA0_CONTROL_REG            (DMA_BASE + 0x00)
+#define DMA1_CONTROL_REG            (DMA_BASE + 0x40)
+#define DMA2_CONTROL_REG            (DMA_BASE + 0x80)
+#define DMA3_CONTROL_REG            (DMA_BASE + 0xc0)
+#define DMA_CONTROL_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define DMA_CONTROL_RESET_VALUE     0x00000000UL
+#define CLEAR_BIT                   0
+#define DMA_ENABLE_BIT              1
+#define DMA_INIT_BIT                2
+#define CONT_BIT                    3
+#define SFT_REQ_BIT                 4
+#define BLOCK_EN_BIT                5
+#define TRANS_DIR_FIELD             6
+#define   NBITS_TRANS_DIR             2
+#define SRC_ADDR_MODE_FIELD         8
+#define   NBITS_SRC_ADDR_MODE         2
+#define DEST_ADDR_MODE_FIELD        10
+#define   NBITS_DEST_ADDR_MODE        2
+#define TRANS_SIZE_FIELD            12
+#define   NBITS_TRANS_SIZE            2
+#define METHOD_BIT                  14
+#define AUX_DIS_BIT                 15
+#define CRC_EN_BIT                  16
+#define BROADCAST_BIT               17
+#define BUFFER_FULL_FREEZE_BIT      19
+
+
+/*
+ *  DMA Interrupt Registers Definitions
+ */
+#define DMA0_INT_ENABLE_REG         (DMA_BASE + 0x04)
+#define DMA1_INT_ENABLE_REG         (DMA_BASE + 0x44)
+#define DMA2_INT_ENABLE_REG         (DMA_BASE + 0x84)
+#define DMA3_INT_ENABLE_REG         (DMA_BASE + 0xc4)
+#define DMA_INT_ENABLE_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define DMA_INT_ENABLE_RESET_VALUE  0x00000000UL
+
+#define DMA0_INT_REG                (DMA_BASE + 0x08)
+#define DMA1_INT_REG                (DMA_BASE + 0x48)
+#define DMA2_INT_REG                (DMA_BASE + 0x88)
+#define DMA3_INT_REG                (DMA_BASE + 0xc8)
+#define DMA_INT_REG_ACCESS          (READ_ACCESS)
+#define DMA_INT_RESET_VALUE         0x00000000UL
+
+#define DMA0_INT_CLEAR_REG          (DMA_BASE + 0x0c)
+#define DMA1_INT_CLEAR_REG          (DMA_BASE + 0x4c)
+#define DMA2_INT_CLEAR_REG          (DMA_BASE + 0x8c)
+#define DMA3_INT_CLEAR_REG          (DMA_BASE + 0xcc)
+#define DMA_INT_CLEAR_REG_ACCESS    (WRITE_ACCESS)
+
+#define TC_BIT                      0
+#define INIT_BIT                    1
+#define OVF_BIT                     2
+#define FULL_BIT                    3
+#define EMPTY_BIT                   4
+#define LAST_BIT                    5
+#define RETRANS_BIT                 6
+#define DESC_BIT                    7
+#define BAD_RETR_BIT                8
+
+
+/*
+ *  DMA Transfer Count Registers Definition
+ */
+#define DMA0_TRANS_CNT_REG          (DMA_BASE + 0x1c)
+#define DMA1_TRANS_CNT_REG          (DMA_BASE + 0x5c)
+#define DMA2_TRANS_CNT_REG          (DMA_BASE + 0x9c)
+#define DMA3_TRANS_CNT_REG          (DMA_BASE + 0xdc)
+#define DMA_TRANS_CNT_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define TRANS_CNT_FIELD             0
+#define   NBITS_TRANS_CNT             16
+
+#define DMA0_CUR_TRANS_CNT_REG      (DMA_BASE + 0x2c)
+#define DMA1_CUR_TRANS_CNT_REG      (DMA_BASE + 0x6c)
+#define DMA2_CUR_TRANS_CNT_REG      (DMA_BASE + 0xac)
+#define DMA3_CUR_TRANS_CNT_REG      (DMA_BASE + 0xec)
+#define DMA_CUR_TRANS_CNT_REG_ACCESS (READ_ACCESS)
+#define CUR_TRANS_CNT_FIELD         TRANS_CNT_FIELD
+#define   NBITS_CUR_TRANS_CNT         NBITS_TRANS_CNT
+
+
+/*
+ *  DMA Pending Request Counter Register Definition (read only)
+ */
+#define DMA0_PEND_REQ_REG           (DMA_BASE + 0x30)
+#define DMA1_PEND_REQ_REG           (DMA_BASE + 0x70)
+#define DMA2_PEND_REQ_REG           (DMA_BASE + 0xb0)
+#define DMA3_PEND_REQ_REG           (DMA_BASE + 0xf0)
+#define DMA_PEND_REQ_REG_ACCESS     (READ_ACCESS)
+#define PEND_REQ_CTRL_FIELD         0
+#define   NBITS_PEND_REQ_CTRL         10
+#define LAST_POST_FIELD             16
+#define   NBITS_LAST_POST             10
+
+
+/*
+ *  DMA Descriptor Table
+ */
+#define DMA0_DES_TABLE_ADDR_REG     (DMA_BASE + 0x10)
+#define DMA1_DES_TABLE_ADDR_REG     (DMA_BASE + 0x50)
+#define DMA2_DES_TABLE_ADDR_REG     (DMA_BASE + 0x90)
+#define DMA3_DES_TABLE_ADDR_REG     (DMA_BASE + 0xd0)
+#define DMA_DES_TABLE_ADDR_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+
+#define DMA0_CUR_DESC_ADDR_REG      (DMA_BASE + 0x20)
+#define DMA1_CUR_DESC_ADDR_REG      (DMA_BASE + 0x60)
+#define DMA2_CUR_DESC_ADDR_REG      (DMA_BASE + 0xa0)
+#define DMA3_CUR_DESC_ADDR_REG      (DMA_BASE + 0xe0)
+#define DMA_CUR_DESC_ADDR_REG_ACCESS (READ_ACCESS)
+
+#if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
+typedef struct
+{
+    unsigned int sourceAddress;
+    unsigned int reserved;
+    unsigned int destinationAddress;
+    unsigned int controlStatus;
+}
+DMA_DESCRIPTOR;
+#endif
+
+// DMA_DESCRIPTOR -> controlStatus Definition
+#define ACT_WHEN_COMPL_FIELD        0
+#define   NBITS_ACT_WHEN_COMPL        2
+#define DESC_INT_BIT                2
+#define CRC_CLR_DIS_BIT             3
+#define CONT_DESC_BIT               4
+#define BUFF_STAT_BIT               5
+#define DIS_BRCST_BIT               6
+#define TRANS_LENGTH_FIELD          16
+#define   NBITS_TRANS_LENGTH          16
+
+
+/*
+ *  Other DMA Registers Definition - 32-bit
+ */
+#define DMA0_SRC_ADDR_REG           (DMA_BASE + 0x14)
+#define DMA1_SRC_ADDR_REG           (DMA_BASE + 0x54)
+#define DMA2_SRC_ADDR_REG           (DMA_BASE + 0x94)
+#define DMA3_SRC_ADDR_REG           (DMA_BASE + 0xd4)
+#define DMA_SRC_ADDR_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+
+#define DMA0_DST_ADDR_REG           (DMA_BASE + 0x18)
+#define DMA1_DST_ADDR_REG           (DMA_BASE + 0x58)
+#define DMA2_DST_ADDR_REG           (DMA_BASE + 0x98)
+#define DMA3_DST_ADDR_REG           (DMA_BASE + 0xd8)
+#define DMA_DST_ADDR_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+
+#define DMA0_CUR_SRC_ADDR_REG       (DMA_BASE + 0x24)
+#define DMA1_CUR_SRC_ADDR_REG       (DMA_BASE + 0x64)
+#define DMA2_CUR_SRC_ADDR_REG       (DMA_BASE + 0xa4)
+#define DMA3_CUR_SRC_ADDR_REG       (DMA_BASE + 0xe4)
+#define DMA_CUR_SRC_ADDR_REG_ACCESS (READ_ACCESS)
+
+#define DMA0_CUR_DEST_ADDR_REG      (DMA_BASE + 0x28)
+#define DMA1_CUR_DEST_ADDR_REG      (DMA_BASE + 0x68)
+#define DMA2_CUR_DEST_ADDR_REG      (DMA_BASE + 0xa8)
+#define DMA3_CUR_DEST_ADDR_REG      (DMA_BASE + 0xe8)
+#define DMA_CUR_DEST_ADDR_REG_ACCESS (READ_ACCESS)
+
+#define DMA_CRC_REG                 (DMA_BASE + 0xfc)
+#define DMA_CRC_REG_ACCESS          (READ_ACCESS)
+
+
+/*
+ ***********************************************************
+ * DMAX Unit Definition
+ ***********************************************************
+ */
+
+/*
+ *  DMAX Control Registers Definition (read/write)
+ */
+#define DMAX0_CONTROL_REG           (DMAX_BASE + 0x00)
+#define DMAX1_CONTROL_REG           (DMAX_BASE + 0x40)
+#define DMAX2_CONTROL_REG           (DMAX_BASE + 0x80)
+#define DMAX3_CONTROL_REG           (DMAX_BASE + 0xc0)
+#define DMAX_CONTROL_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define DMAX_CONTROL_RESET_VALUE    0x00000000UL
+// for more bit definitions see: DMA Unit -> DMA Control Registers Definition
+#define DMAX_PACKET_EN_BIT          18
+#define BUFFER_FULL_FREEZE_BIT      19
+
+
+/*
+ *  DMAX Interrupt Registers Definitions
+ *      The bitfields for these regs are defined in the DMA Unit.
+ */
+#define DMAX0_INT_ENABLE_REG        (DMAX_BASE + 0x04)
+#define DMAX1_INT_ENABLE_REG        (DMAX_BASE + 0x44)
+#define DMAX2_INT_ENABLE_REG        (DMAX_BASE + 0x84)
+#define DMAX3_INT_ENABLE_REG        (DMAX_BASE + 0xc4)
+#define DMAX_INT_ENABLE_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define DMAX_INT_ENABLE_RESET_VALUE 0x00000000UL
+
+#define DMAX0_INT_STATUS_REG        (DMAX_BASE + 0x08)
+#define DMAX1_INT_STATUS_REG        (DMAX_BASE + 0x48)
+#define DMAX2_INT_STATUS_REG        (DMAX_BASE + 0x88)
+#define DMAX3_INT_STATUS_REG        (DMAX_BASE + 0xc8)
+#define DMAX_INT_STATUS_REG_ACCESS  (READ_ACCESS)
+#define DMAX_INT_STATUS_RESET_VALUE 0x00000000UL
+
+#define DMAX0_INT_CLEAR_REG         (DMAX_BASE + 0x0c)
+#define DMAX1_INT_CLEAR_REG         (DMAX_BASE + 0x4c)
+#define DMAX2_INT_CLEAR_REG         (DMAX_BASE + 0x8c)
+#define DMAX3_INT_CLEAR_REG         (DMAX_BASE + 0xcc)
+#define DMAX_INT_CLEAR_REG_ACCESS   (WRITE_ACCESS)
+
+
+/*
+ *  DMAX Descriptor Table Address Registers Definition
+ */
+#define DMAX0_DES_TABLE_ADDR_REG    (DMAX_BASE + 0x10)
+#define DMAX1_DES_TABLE_ADDR_REG    (DMAX_BASE + 0x50)
+#define DMAX2_DES_TABLE_ADDR_REG    (DMAX_BASE + 0x90)
+#define DMAX3_DES_TABLE_ADDR_REG    (DMAX_BASE + 0xd0)
+#define DMAX_DES_TABLE_ADDR_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+
+#define DMAX0_CUR_DESC_ADDR_REG     (DMAX_BASE + 0x20)
+#define DMAX1_CUR_DESC_ADDR_REG     (DMAX_BASE + 0x60)
+#define DMAX2_CUR_DESC_ADDR_REG     (DMAX_BASE + 0xa0)
+#define DMAX3_CUR_DESC_ADDR_REG     (DMAX_BASE + 0xe0)
+#define DMAX_CUR_DESC_ADDR_REG_ACCESS (READ_ACCESS)
+
+/*
+ *  Descriptor typedefs
+ *      For A7-Mode, see typedef for DMA_DESCRIPTOR in the DMA Unit.
+ *      The controlStatus bitfields are also defined in the DMA Unit.
+ */
+#if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
+typedef struct
+{
+    unsigned int packetControlStatus;
+    unsigned int reserved;
+    unsigned int startAddress;
+    unsigned int controlStatus;
+}
+DMAX_PACKET_DESCRIPTOR;
+#endif
+
+/*
+ *  DMAX Source/Destination/Count Registers Definition - 32-bit
+ */
+#define DMAX0_TRANS_SRC_ADDR_REG    (DMAX_BASE + 0x14)
+#define DMAX1_TRANS_SRC_ADDR_REG    (DMAX_BASE + 0x54)
+#define DMAX2_TRANS_SRC_ADDR_REG    (DMAX_BASE + 0x94)
+#define DMAX3_TRANS_SRC_ADDR_REG    (DMAX_BASE + 0xd4)
+#define DMAX_TRANS_SRC_ADDR_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+
+#define DMAX0_TRANS_DEST_ADDR_REG   (DMAX_BASE + 0x18)
+#define DMAX1_TRANS_DEST_ADDR_REG   (DMAX_BASE + 0x58)
+#define DMAX2_TRANS_DEST_ADDR_REG   (DMAX_BASE + 0x98)
+#define DMAX3_TRANS_DEST_ADDR_REG   (DMAX_BASE + 0xd8)
+#define DMAX_TRANS_DEST_ADDR_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+
+#define DMAX0_TRANS_COUNT_REG       (DMAX_BASE + 0x1c)
+#define DMAX1_TRANS_COUNT_REG       (DMAX_BASE + 0x5c)
+#define DMAX2_TRANS_COUNT_REG       (DMAX_BASE + 0x9c)
+#define DMAX3_TRANS_COUNT_REG       (DMAX_BASE + 0xdc)
+#define DMAX_TRANS_COUNT_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+
+#define DMAX0_CUR_SRC_ADDR_REG      (DMAX_BASE + 0x24)
+#define DMAX1_CUR_SRC_ADDR_REG      (DMAX_BASE + 0x64)
+#define DMAX2_CUR_SRC_ADDR_REG      (DMAX_BASE + 0xa4)
+#define DMAX3_CUR_SRC_ADDR_REG      (DMAX_BASE + 0xe4)
+#define DMAX_CUR_SRC_ADDR_REG_ACCESS (READ_ACCESS)
+
+#define DMAX0_CUR_DEST_ADDR_REG     (DMAX_BASE + 0x28)
+#define DMAX1_CUR_DEST_ADDR_REG     (DMAX_BASE + 0x68)
+#define DMAX2_CUR_DEST_ADDR_REG     (DMAX_BASE + 0xa8)
+#define DMAX3_CUR_DEST_ADDR_REG     (DMAX_BASE + 0xe8)
+#define DMAX_CUR_DEST_ADDR_REG_ACCESS (READ_ACCESS)
+
+#define DMAX0_CUR_TRANS_COUNT_REG   (DMAX_BASE + 0x2c)
+#define DMAX1_CUR_TRANS_COUNT_REG   (DMAX_BASE + 0x6c)
+#define DMAX2_CUR_TRANS_COUNT_REG   (DMAX_BASE + 0xac)
+#define DMAX3_CUR_TRANS_COUNT_REG   (DMAX_BASE + 0xec)
+#define DMAX_CUR_TRANS_COUNT_REG_ACCESS (READ_ACCESS)
+
+/*
+ *  DMAX Pending Request Counter Register Definition (read only)
+ *      The bitfields for these regs are defined in the DMA Unit.
+ */
+#define DMAX0_PENDING_REQ_REG       (DMAX_BASE + 0x30)
+#define DMAX1_PENDING_REQ_REG       (DMAX_BASE + 0x70)
+#define DMAX2_PENDING_REQ_REG       (DMAX_BASE + 0xb0)
+#define DMAX3_PENDING_REQ_REG       (DMAX_BASE + 0xf0)
+#define DMAX_PENDING_REQ_REG_ACCESS (READ_ACCESS)
+
+
+/*
+ *  DMAX Packet Mode Control Status Register Definition - 32-bit (read only)
+ *      If DMA is configured for D2M (Ethernet Rx), this field is the
+ *          "Receive_Descriptor_Status", and is written from the Ethernet
+ *          device to the DMA after the last piece of data is transferred
+ *          for that particular Descriptor entry.
+ *      If the DMA is configured for M2D (Ethernet Tx), this field is the
+ *          "Transmit_Descriptor_Control", and is written from the DMA to
+ *          the Ethernet device before the first piece of data is transferred
+ *          for that particular Descriptor entry.
+ */
+#define DMAX0_PACK_CONT_STAT_REG    (DMAX_BASE + 0x34)
+#define DMAX1_PACK_CONT_STAT_REG    (DMAX_BASE + 0x74)
+#define DMAX2_PACK_CONT_STAT_REG    (DMAX_BASE + 0xb4)
+#define DMAX3_PACK_CONT_STAT_REG    (DMAX_BASE + 0xf4)
+#define DMAX_PACK_CONT_STAT_REG_ACCESS (READ_ACCESS)
+
+#define DMAX_PACK_TX_LAST_DESC      0
+#define DMAX_PACK_TX_OPTIONS_FIELD  4
+#define   NBITS_DMAX_PACK_TX_OPTIONS  3
+#define DMAX_PACK_TX_BVALID_FIELD   30
+#define   NBITS_DMAX_PACK_TX_BVALID   2
+
+#define DMAX_PACK_RX_LAST_DESC_BIT  0
+#define DMAX_PACK_RX_LEN_ERR_BIT    4
+#define DMAX_PACK_RX_CTL_RECD_BIT   5
+#define DMAX_PACK_RX_INT_RX_BIT     6
+#define DMAX_PACK_RX_ALIGN_ERR_BIT  8
+#define DMAX_PACK_RX_CRC_ERR_BIT    9
+#define DMAX_PACK_RX_OVERFLOW_BIT   10
+#define DMAX_PACK_RX_LONG_ERR_BIT   11
+#define DMAX_PACK_RX_PAR_BIT        13
+#define DMAX_PACK_RX_GOOD_BIT       14
+#define DMAX_PACK_RX_HALTED_BIT     15
+#define DMAX_PACK_RX_MCAST_BIT      17
+#define DMAX_PACK_RX_BCAST_BIT      18
+#define DMAX_PACK_RX_VLAN_BIT       19
+#define DMAX_PACK_RX_PAUSE_BIT      20
+#define DMAX_PACK_RX_ARC_STATUS_FIELD 21
+#define   NBITS_DMAX_PACK_RX_ARC_STATUS 4
+#define DMAX_PACK_RX_ARC_ENT_FIELD  25
+#define   NBITS_DMAX_PACK_RX_ARC_ENT  2
+#define DMAX_PACK_RX_LAST_BVALID_FIELD 30
+#define   NBITS_DMAX_PACK_RX_LAST_BVALID 2
+
+/*
+ * DMAX Descriptor IRQ Count Register Definition
+ */
+#define DMAX0_IRQ_COUNT_REG         (DMAX_BASE + 0x38)
+#define DMAX1_IRQ_COUNT_REG         (DMAX_BASE + 0x78)
+#define DMAX2_IRQ_COUNT_REG         (DMAX_BASE + 0xb8)
+#define DMAX3_IRQ_COUNT_REG         (DMAX_BASE + 0xf8)
+#define DMAX_PACK_CONT_STAT_REG_ACCESS (READ_ACCESS)
+
+/*
+ *  DMAX CRC Register Definition - 32-bit (read only)
+ */
+#define DMAX_CRC_REG                (DMAX_BASE + 0xfc)
+#define DMAX_CRC_REG_ACCESS         (READ_ACCESS)
+
+
+/*
+ **********************************************************
+ * UART Definition
+ **********************************************************
+ */
+
+/*
+ *  Uart Control Register Structure (read/write)
+ */
+#define UART0_CONTROL_REG           (UART_BASE + 0x00)
+#define UART1_CONTROL_REG           (UART_BASE + 0x40)
+#define UART_CONTROL_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define UART_CONTROL_RESET_VALUE    0x00000000UL
+#define UART_PRESCALE_FIELD         0
+#define   NBITS_UART_PRESCALE         8
+#define PRESCALE_EN_BIT             8
+#define MODEM_EN_BIT                9
+#define TX_DMA_EN_BIT               16
+#define TX_DMA_SEL_FIELD            17
+#define   NBITS_TX_DMA_SEL            2
+//reserved bit 19
+#define RX_DMA_EN_BIT               20
+#define RX_DMA_SEL_FIELD            21
+#define   NBITS_RX_DMA_SEL            2
+
+
+/*
+ *  DLAB=0: Uart Rx Tx Register Structure       (read/write)
+ *  DLAB=1: Uart Divisor LSB Register Structure (read/write)
+ */
+#define UART0_RX_TX_REG             (UART_BASE + 0x20)
+#define UART1_RX_TX_REG             (UART_BASE + 0x60)
+#define UART_RX_REG_ACCESS          (READ_ACCESS)
+#define UART_TX_REG_ACCESS          (WRITE_ACCESS)
+#define DATA_FIELD                  0
+#define   NBITS_DATA                  8
+
+#define UART0_DIVISOR_LSB_REG       (UART_BASE + 0x20)
+#define UART1_DIVISOR_LSB_REG       (UART_BASE + 0x60)
+#define UART_DIVISOR_LSB_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define DIVISOR_LSB_FIELD           0
+#define   NBITS_DIVISOR_LSB           8
+
+
+/*
+ *  DLAB=0: Uart Interrupt Enable Register Structure (read/write)
+ *  DLAB=1: Uart Divisor MSB Register Structure      (read/write)
+ */
+#define UART0_INT_ENABLE_REG        (UART_BASE + 0x24)
+#define UART1_INT_ENABLE_REG        (UART_BASE + 0x64)
+#define UART_INT_ENABLE_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define UART_INT_ENABLE_RESET_VALUE 0x00000000UL
+#define RDRE_BIT                    0
+#define THREE_BIT                   1
+#define RLSE_BIT                    2
+#define MSE_BIT                     3
+
+#define UART0_DIVISOR_MSB_REG       (UART_BASE + 0x24)
+#define UART1_DIVISOR_MSB_REG       (UART_BASE + 0x64)
+#define UART_DIVISOR_MSB_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define DIVISOR_MSB_FIELD           0
+#define   NBITS_DIVISOR_MSB           8
+
+
+/*
+ *  Uart Interrupt ID Register Structure (read only)
+ *  Uart Fifo Control Register Structure (write only)
+ */
+#define UART0_INT_ID_REG            (UART_BASE + 0x28)
+#define UART1_INT_ID_REG            (UART_BASE + 0x68)
+#define UART_INT_ID_REG_ACCESS      (READ_ACCESS)
+#define UART_INT_ID_RESET_VALUE     0x00000001UL
+#define INT_ID_FIELD                0
+#define   NBITS_INT_ID                4
+#define FIFO_MODE_FIELD             6
+#define   NBITS_FIFO_MODE             2
+
+#define UART0_FIFO_CTRL_REG         (UART_BASE + 0x28)
+#define UART1_FIFO_CTRL_REG         (UART_BASE + 0x68)
+#define UART_FIFO_CTRL_REG_ACCESS   (WRITE_READ_ACCESS)
+#define UART_FIFO_CTRL_RESET_VALUE  0x00000000UL
+#define FIFO_MODE_ENABLE_BIT        0
+#define RX_FIFO_CLR_BIT             1
+#define TX_FIFO_CLR_BIT             2
+#define FIFO_TRIG_LEVEL_FIELD       6
+#define   NBITS_FIFO_TRIG_LEVEL       2
+
+
+/*
+ *  Uart Line Control Register Structure (read/write)
+ */
+#define UART0_LINE_CONTROL_REG      (UART_BASE + 0x2c)
+#define UART1_LINE_CONTROL_REG      (UART_BASE + 0x6c)
+#define UART_LINE_CONTROL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define UART_LINE_CONTROL_RESET_VALUE 0x00000000UL
+#define STB_WLS_FIELD               0
+#define   NBITS_STB_WLS               3
+#define PEN_BIT                     3
+#define EPS_BIT                     4
+#define STICK_PARITY_BIT            5
+#define BREAK_BIT                   6
+#define DLAB_BIT                    7
+
+
+/*
+ *  Uart Modem Control Register Structure (read/write)
+ */
+#define UART0_MODEM_CONTROL_REG     (UART_BASE + 0x30)
+#define UART1_MODEM_CONTROL_REG     (UART_BASE + 0x70)
+#define UART_MODEM_CONTROL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define UART_MODEM_CONTROL_RESET_VALUE 0x00000000UL
+#define DTR_BIT                     0
+#define RTS_BIT                     1
+#define LOOP_BIT                    3
+
+
+/*
+ *  Uart Line Status Register Structure (read only)
+ */
+#define UART0_LINE_STATUS_REG       (UART_BASE + 0x34)
+#define UART1_LINE_STATUS_REG       (UART_BASE + 0x74)
+#define UART_LINE_STATUS_REG_ACCESS (READ_ACCESS)
+#define UART_LINE_STATUS_RESET_VALUE 0x00000060UL
+#define DR_BIT                      0
+#define OE_BIT                      1
+#define PE_BIT                      2
+#define FE_BIT                      3
+#define BI_BIT                      4
+#define THRE_BIT                    5
+#define TEMT_BIT                    6
+#define ERROR_BIT                   7
+
+
+/*
+ *  Uart Modem Status Register Structure (read only)
+ */
+#define UART0_MODEM_STATUS_REG      (UART_BASE + 0x38)
+#define UART1_MODEM_STATUS_REG      (UART_BASE + 0x78)
+#define UART_MODEM_STATUS_REG_ACCESS (READ_ACCESS)
+#define UART_MODEM_STATUS_RESET_VALUE 0x00000000UL
+#define DELTA_CTS_BIT               0
+#define DELTA_DSR_BIT               1
+#define TERI_BIT                    2
+#define DELTA_DCD_BIT               3
+#define CTS_BIT                     4
+#define DSR_BIT                     5
+#define RI_BIT                      6
+#define DCD_BIT                     7
+
+
+/*
+ *  Uart Scratchpad Register Structure (read/write)
+ */
+#define UART0_SCRATCHPAD_REG        (UART_BASE + 0x3c)
+#define UART1_SCRATCHPAD_REG        (UART_BASE + 0x7c)
+#define UART_SCRATCHPAD_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+
+
+
+/*
+ **********************************************************
+ * Timer Unit Definition
+ **********************************************************
+ */
+/*
+ *  Timer Load Register Structure (read/write)
+ */
+#define TIMER0_LOAD_REG             (TIMER_BASE + 0x00)
+#define TIMER1_LOAD_REG             (TIMER_BASE + 0x20)
+#define TIMER_LOAD_REG_ACCESS       (READ_ACCESS | WRITE_ACCESS)
+#define LOAD_FIELD                  0
+#define   NBITS_LOAD                  16
+
+
+/*
+ *  Timer Value Register Structure (read only)
+ */
+#define TIMER0_VALUE_REG            (TIMER_BASE + 0x04)
+#define TIMER1_VALUE_REG            (TIMER_BASE + 0x24)
+#define TIMER_VALUE_REG_ACCESS      (READ_ACCESS)
+#define VALUE_FIELD                 0
+#define   NBITS_VALUE                 16
+
+
+/*
+ *  Timer Control Register Structure (read/write)
+ */
+#define TIMER0_CONTROL_REG          (TIMER_BASE + 0x08)
+#define TIMER1_CONTROL_REG          (TIMER_BASE + 0x28)
+#define TIMER_CONTROL_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define TIMER_CONTROL_RESET_VALUE   0x00000000UL
+#define PRESCALE_FIELD              2
+#define   NBITS_PRESCALE              2
+#define TIM_MODE_BIT                6
+#define TIM_ENABLE_BIT              7
+
+
+/*
+ *  Timer Clear Register Structure (write only)
+ *      Write a "1" to clear the timer interrupt.
+ *      Writing a "0" has no effect.
+ */
+#define TIMER0_CLEAR_REG            (TIMER_BASE + 0x0c)
+#define TIMER1_CLEAR_REG            (TIMER_BASE + 0x2c)
+#define TIMER_CLEAR_REG_ACCESS      (WRITE_ACCESS)
+#define TIM_INT_CLEAR_BIT           0
+
+
+
+/*
+ **********************************************************
+ * Watchdog Unit Definition
+ **********************************************************
+ */
+
+/*
+ *  Watchdog Control Register Structure (read/write)
+ *      Writing a '1' to the WD_RESET bit will reset the watchdog timer,
+ *      including its interrupt and reset logic. This bit is self-clearing.
+ */
+#define WATCHDOG_CONTROL_REG        (WD_BASE + 0x00)
+#define WATCHDOG_CONTROL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define WATCHDOG_CONTROL_RESET_VALUE 0x00000000UL
+#define WD_ENABLE_BIT               0
+#define WD_RESET_BIT                1
+#define EN_WD_RST_BIT               2
+
+
+/*
+ *  Watchdog Timeout Value Register Structure (read/write)
+ */
+#define WATCHDOG_TIMEOUT_VAL_REG    (WD_BASE + 0x04)
+#define WATCHDOG_TIMEOUT_VAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+
+
+/*
+ *  Watchdog Current Value Register Structure (read only)
+ */
+#define WATCHDOG_CURRENT_VAL_REG    (WD_BASE + 0x08)
+#define WATCHDOG_CURRENT_VAL_REG_ACCESS (READ_ACCESS)
+
+
+/*
+ *  Watchdog Clear Register Structure (write only)
+ *      Writing a '1' to the WD_INT_CLR bit will clear the watchdog interrupt.
+ *      Writing a "0" has no effect.
+ */
+#define WATCHDOG_CLEAR_REG          (WD_BASE + 0x0c)
+#define WATCHDOG_CLEAR_REG_ACCESS   (WRITE_ACCESS)
+#define WD_INT_CLR_BIT              0
+
+
+
+/*
+ ******************************************************************************
+ * Breakpoint Unit Definition
+ ******************************************************************************
+ */
+
+/*
+ * Breakpoint Control Register definition (read/write)
+ */
+#define BPU_BRK_CONTROL_REG         (BPU_BASE + 0x00)
+#define BPU_BRK_CONTROL_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define BRK_CONTROL_RESET_VALUE     0x00000000UL
+#define CPU_STIM_FIELD          0
+#define   NBITS_CPU_STIM          2
+//#define CLR_DBG_REQ_BIT         2  // hardware not tested
+#define CSL_FREEZE_BIT          3
+#define CSL_MATCH_BIT           4
+#define BP_TYPE_FIELD           5
+#define   NBITS_BP_TYPE           3
+#define RESTART_BIT             8
+#define BP_ENABLE_FIELD         9
+#define   NBITS_BP_ENABLE         2
+//#define DBG_BRK_EN_BIT         11  // hardware not tested
+//#define DBG_REQ_EN_BIT         12  // hardware not tested
+#define BP0_NOT_MATCH_BIT      13
+#define BP1_NOT_MATCH_BIT      14
+#define ARB_FREEZE_BIT         15
+#define BUS_SEL_BIT            16
+#define BP0_DATA_SEL_BIT       17
+#define BP1_DATA_SEL_BIT       18
+#define TRACE_EN_BIT           19
+#define TRACE_FORMAT_FIELD     20
+#define   NBITS_TRACE_FORMAT      4
+#define CSL_CAPT_EN_BIT        24
+#define BCLK_FREEZE_BIT        25
+#define CPU_DBG_EN_BIT         26
+#define CAPT_PULSE_BIT         27
+//#define DBG_EXT0_EN_BIT        29  // hardware not tested
+//#define DBG_EXT1_EN_BIT        30  // hardware not tested
+
+// CSI bus Trace Format enumeration
+#define CSI_TRACE_ALL        0x0
+#define CSI_TRACE_VALID      0x1
+#define CSI_TRACE_DMA0       0x2
+#define CSI_TRACE_DMA1       0x3
+#define CSI_TRACE_DMA2       0x4
+#define CSI_TRACE_DMA3       0x5
+#define CSI_TRACE_ARM        0x6
+#define CSI_TRACE_DMAX0      0x7
+#define CSI_TRACE_DMAX1      0x8
+#define CSI_TRACE_DMAX2      0x9
+#define CSI_TRACE_ENET_TXRX  0xa
+
+// CPU bus Trace Format enumeration
+#define CPU_TRACE_ALL          0x0
+#define CPU_TRACE_VALID        0x1
+#define CPU_TRACE_INSTRUCTION  0x2
+#define CPU_TRACE_DATA_ACCESS  0x3
+
+
+/*
+ * Breakpoint Bus Mask/Compare Registers Definition (read/write)
+ */
+#define BPU_BRK_MASK_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define BPU_BRK_COMP_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+
+/*
+ * Breakpoint Bus Mask0/Compare0 Registers Definition (read/write)
+ */
+#define BPU_BRK0_BUS_MASK0_REG  (BPU_BASE + 0x04)
+#define BPU_BRK0_BUS_COMP0_REG  (BPU_BASE + 0x24)
+#define BPU_BRK1_BUS_MASK0_REG  (BPU_BASE + 0x14)
+#define BPU_BRK1_BUS_COMP0_REG  (BPU_BASE + 0x34)
+
+/*
+ * Breakpoint Bus Mask1/Compare1 Registers Definition (read/write)
+ */
+#define BPU_BRK0_BUS_MASK1_REG  (BPU_BASE + 0x08)
+#define BPU_BRK0_BUS_COMP1_REG  (BPU_BASE + 0x28)
+#define BPU_BRK1_BUS_MASK1_REG  (BPU_BASE + 0x18)
+#define BPU_BRK1_BUS_COMP1_REG  (BPU_BASE + 0x38)
+
+/*
+ * Breakpoint Bus Mask2/Compare2 Registers Definition (read/write)
+ */
+#define BPU_BRK0_BUS_MASK2_REG  (BPU_BASE + 0x0c)
+#define BPU_BRK0_BUS_COMP2_REG  (BPU_BASE + 0x2c)
+#define BPU_BRK1_BUS_MASK2_REG  (BPU_BASE + 0x1c)
+#define BPU_BRK1_BUS_COMP2_REG  (BPU_BASE + 0x3c)
+
+// BUS MASK2 for CSI BUS
+#define SW_DMA_ACK_FIELD       0
+#define   NBITS_SW_DMA_ACK       4
+#define SW_MODE_FIELD          4
+#define   NBITS_SW_MODE          6
+#define SW_DMA_CTRL_FIELD     10
+#define   NBITS_SW_DMA_CTRL      4
+#define SW_SIZE_FIELD         14
+#define   NBITS_SW_SIZE          2
+#define SW_RD_EN_BIT          16
+#define SW_WR_EN_BIT          17
+#define SW_BP_CTRL_BIT        18
+#define RD_OR_WR_BIT          19
+#define SW_DMAX_ACK_FIELD     20
+#define   NBITS_SW_DMAX_ACK      3
+#define SW_DMAX_CTRL_FIELD    23
+#define   NBITS_SW_DMAX_CTRL     3
+#define OR_DMA_ACK_BIT        26
+#define RD_WR_ACK_BIT         27
+
+// BUS MASK 2 for CPU BUS
+#define WRITE_BIT              0
+#define SIZE_FIELD             1
+#define   NBITS_SIZE             2
+#define LOCK_BIT               3
+#define TRANS_FIELD            4
+#define   NBITS_TRANS            2
+#define ABORT_BIT              6
+#define PROT_FIELD             7
+#define   NBITS_PROT             2
+#define DBGACK_BIT            17
+
+/*
+ * Breakpoint Bus Mask3 Registers Definition (read/write)
+ */
+#define BPU_BRK0_BUS_MASK3_REG  (BPU_BASE + 0x10)
+#define BPU_BRK1_BUS_MASK3_REG  (BPU_BASE + 0x20)
+#define FR_FIELD    0
+#define   NBITS_FR   18
+
+
+/*
+ * Breakpoint Counter Compare/Out Registers Definition
+ */
+#define BPU_BRK_CNT_COMP_REG         (BPU_BASE + 0x44)
+#define BPU_BRK_CNT_COMP_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+
+#define BPU_BRK_CNT_OUT_REG          (BPU_BASE + 0x48)
+#define BPU_BRK_CNT_OUT_REG_ACCESS   (READ_ACCESS)
+
+#define BRK_CNT0_FIELD     0
+#define   NBITS_BRK_CNT0    16
+#define BRK_CNT1_FIELD    16
+#define   NBITS_BRK_CNT1    16
+
+
+/*
+ * Trace Buffer Address Pointer Definition
+ * Trace Counter Definition
+ */
+#define BPU_BRK_TR_ADDR_REG              (BPU_BASE + 0x4c)
+#define BPU_BRK_TRACE_ADDR_FIELD_ACCESS  (READ_ACCESS)
+#define BPU_BRK_TR_ADDR_FLIP_BIT_ACCESS  (READ_ACCESS)
+#define BPU_BRK_TRACE_CNT_FIELD_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define TRACE_ADDR_FIELD      0 // read only
+#define   NBITS_TRACE_ADDR      9
+#define TR_ADDR_FLIP_BIT      9 // read only
+#define TRACE_CNT_FIELD      16 // read/write
+#define   NBITS_TRACE_CNT       9
+
+
+/*
+ * Breakpoint Interrupt Clear Register Definition (write only)
+ */
+#define BPU_BRK_INT_CLEAR_REG         (BPU_BASE + 0x50)
+#define BPU_BRK_INT_CLEAR_REG_ACCESS  (WRITE_ACCESS)
+#define BRK_INT_CLEAR_BIT   0
+
+
+/*
+ * Breakpoint Status Register Definition (read only)
+ */
+#define BPU_BRK_STATUS_REG         (BPU_BASE + 0x54)
+#define BPU_BRK_STATUS_REG_ACCESS  (READ_ACCESS)
+#define STAT_CPU_FREEZE_BIT   0
+#define STAT_CPU_IRQ_BIT      1
+//#define STAT_DBG_REQ_BIT      2  // hardware not tested
+//#define STAT_DBG_BREAK_BIT    3  // hardware not tested
+//#define STAT_DBG_EXT0_BIT     4  // hardware not tested
+//#define STAT_DBG_EXT1_BIT     5  // hardware not tested
+#define STAT_ARB_FREEZE_BIT   6
+#define STAT_CSL_MATCH_BIT    7
+#define STAT_CSL_FREEZE_BIT   8
+#define STAT_CSL_STEP_BIT     9
+#define STAT_TRACE_FIN_BIT   10
+#define STAT_TRACE_EN_BIT    11
+#define STAT_BP0_CNT_TC_BIT  12
+#define STAT_BP1_CNT_TC_BIT  13
+#define STAT_BP_EVENT_BIT    14
+#define STAT_DBG_ACK_BIT     15
+
+
+/*
+ * Breakpoint Start Count Register Definition (read only)
+ *     Retains initial value written to Trace Counter before Trace was enabled
+ */
+#define BPU_BRK_START_CNT_REG         (BPU_BASE + 0x58)
+#define BPU_BRK_START_CNT_REG_ACCESS  (READ_ACCESS)
+#define TRACE_START_CNT_FIELD    0
+#define   NBITS_TRACE_START_CNT    9
+
+
+/*
+ * Trace Buffer Definition
+ *     The Trace Buffer is implemented in the Scratchpad RAM.
+ *     The buffer is a data array of 128-bit wide and 512 deep.
+ *     The trace can be moved relative to a programmed breakpoint event.
+ */
+/*
+ * CSI Trace Capture Description
+ */
+#if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
+typedef struct
+{
+    unsigned int CsiSlaveWriteBusAddr;
+    unsigned int CsiSlaveWriteBusData;
+    unsigned int CsiControl;    // see definition below
+    unsigned int CsiMasterReadData;
+}
+CSI_TRACE;
+#endif
+
+// CsiControl trace definition
+#define CSI_SW_DMAACK_FIELD        0
+#define   NBITS_CSI_SW_DMAACK        4
+#define CSI_SW_MODE_FIELD          4
+#define   NBITS_CSI_SW_MODE          6
+#define CSI_SW_DMA_CTRL_FIELD     10
+#define   NBITS_CSI_SW_DMA_CTRL      4
+#define CSI_SW_SIZE_FIELD         14
+#define   NBITS_CSI_SW_SIZE          2
+#define CSI_SW_RD_EN_BIT          16
+#define CSI_SW_WR_EN_BIT          17
+#define CSI_SR_BP_CTRL_BIT        18
+#define CSI_RD_OR_WR_BIT          19
+#define CSI_SW_DMAX_ACK_FIELD     20
+#define   NBITS_CSI_SW_DMAX_ACK      3
+#define CSI_SW_DMAX_CTRL_FIELD    23
+#define   NBITS_CSI_SW_DMAX_CTRL     3
+#define CSI_FR_FIELD              26    // see enumeration below
+#define   NBITS_CSI_FR               5
+#define CSI_SW_WAIT_NOW_BIT       31
+
+// CSI_FR_FIELD enumeration
+#define FR_DMA0_IO      1
+#define FR_DMA0_MEM     2
+#define FR_DMA1_IO      3
+#define FR_DMA1_MEM     4
+#define FR_DMA2_IO      5
+#define FR_DMA2_MEM     6
+#define FR_DMA3_IO      7
+#define FR_DMA3_MEM     8
+#define FR_JTAG         9
+#define FR_MIU         10
+#define FR_CPU         11
+#define FR_DMAX4_IO    13
+#define FR_DMAX4_MEM   14
+#define FR_DMAX5_IO    15
+#define FR_DMAX5_MEM   16
+#define FR_DMAX6_IO    17
+#define FR_DMAX6_MEM   18
+
+
+/*
+ * CPU Trace Capture Description
+ */
+#if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
+typedef struct
+{
+    unsigned int CpuAddress;
+    unsigned int CpuData;
+    unsigned int CpuControl;    // see definition below
+    unsigned int Reserved;
+}
+CPU_TRACE;
+#endif
+
+// CpuControl trace definition
+#define ARM_WRITE_BIT         0
+#define ARM_SIZE_FIELD        1
+#define   NBITS_ARM_SIZE        2
+#define ARM_LOCK_BIT          3
+#define ARM_LOCK_FIELD        4
+#define   NBITS_LOCK            2
+#define ARM_ABORT_BIT         6
+#define ARM_PROT_FIELD        7
+#define   NBITS_ARM_PROT        2
+#define ARM_DBG_ACK_BIT      17
+#define ARM_DBG_BREAK_BIT    19
+#define ARM_DBG_EXT0_BIT     20
+#define ARM_DBG_EXT1_BIT     21
+#define ARM_DBG_REQ_BIT      22
+#define ARM_DBG_COMM_RX_BIT  23
+#define ARM_DBG_COMM_TX_BIT  24
+#define ARM_CACHELINE_BIT    25
+#define ARM_THUMB_BIT        26
+#define ARM_DBG_NEXEC_BIT    27
+#define ARM_DBG_EN_BIT       28
+#define ARM_DBG_RNG0_BIT     29
+#define ARM_DBG_RNG1_BIT     30
+#define ARM_CLK_EN_BIT       31
+
+
+
+/*
+ ******************************************************************************
+ * Protection Unit Registers (PU_BASE)
+ ******************************************************************************
+ */
+
+/*
+ * Protection Unit Control Register definition (read/write)
+ */
+#define PU_CONTROL_REG          (PU_BASE + 0x04)
+#define PU_CONTROL_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define PU_CONTROL_RESET_VALUE  0x00000000UL
+#define PROT_EN_BIT    0
+#define CACHE_EN_BIT   2
+
+
+/*
+ * Cacheable Area Register definition (read/write)
+ */
+#define PU_CACHEABLE_AREA_REG         (PU_BASE + 0x08)
+#define PU_CACHEABLE_AREA_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define C_0_BIT  0
+#define C_1_BIT  1
+#define C_2_BIT  2
+#define C_3_BIT  3
+#define C_4_BIT  4
+#define C_5_BIT  5
+#define C_6_BIT  6
+#define C_7_BIT  7
+
+
+/*
+ * Protection Area Register definition (read/write)
+ */
+#define PU_PROTECTION_AREA_REG         (PU_BASE + 0x14)
+#define PU_PROTECTION_AREA_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define AP_0_FIELD      0
+#define AP_1_FIELD      2
+#define AP_2_FIELD      4
+#define AP_3_FIELD      6
+#define AP_4_FIELD      8
+#define AP_5_FIELD     10
+#define AP_6_FIELD     12
+#define AP_7_FIELD     14
+#define   NBITS_AP        2
+
+// Access definitions
+#define SUPER_NONE_USER_NONE   0
+#define SUPER_FULL_USER_NONE   1
+#define SUPER_FULL_USER_READ   2
+#define SUPER_FULL_USER_FULL   3
+
+
+/*
+ * Memory Area Definition Registers definition (read/write)
+ *     These regsiters define 8 programmable regions in memory.
+ *     AREA_SIZE :  0 to 10 : reserved
+ *     AREA_SIZE : 11 to 31 : size = 2 power (AREA_SIZE + 1)
+ */
+#define PU_AREA_DEF0_REG         (PU_BASE + 0x20)
+#define PU_AREA_DEF1_REG         (PU_BASE + 0x24)
+#define PU_AREA_DEF2_REG         (PU_BASE + 0x28)
+#define PU_AREA_DEF3_REG         (PU_BASE + 0x2c)
+#define PU_AREA_DEF4_REG         (PU_BASE + 0x30)
+#define PU_AREA_DEF5_REG         (PU_BASE + 0x34)
+#define PU_AREA_DEF6_REG         (PU_BASE + 0x38)
+#define PU_AREA_DEF7_REG         (PU_BASE + 0x3c)
+#define PU_AREA_DEF0_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define AREA_EN_BIT           0
+#define AREA_SIZE_FIELD       1
+#define   NBITS_AREA_SIZE       5
+#define AREA_BASE_ADR_FIELD  12
+#define   NBITS_AREA_BASE      20
+
+
+/*
+ * Cache Invalidate Register definition (write only)
+ *     Writing to this register marks all lines of the cache as invalid.
+ */
+#define PU_CACHE_INVALIDATE_REG         (PU_BASE + 0x1c)
+#define PU_CACHE_INVALIDATE_REG_ACCESS  (WRITE_ACCESS)
+
+
+/*
+ **********************************************************
+ *  TWSI (Two-Wire Serial Interface) Register Definitions
+ **********************************************************
+ */
+
+/*
+ * TWSI Control Register definition (read/write)
+ */
+#define TWSI0_CONTROL_REG         (TWSI0_BASE + 0x00)
+#define TWSI1_CONTROL_REG         (TWSI1_BASE + 0x00)
+#define TWSI_CONTROL_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define TWSI_CONTROL_RESET_VALUE  0x00000000UL
+#define TWSI_SLV_EN_BIT        0
+#define TWSI_MSTR_EN_BIT       1
+#define TWSI_SCALE_FIELD       3
+#define   NBITS_TWSI_SCALE       2
+#define TWSI_GC_EN_BIT         5
+
+
+/*
+ * TWSI Master Command Register definition (read/write)
+ */
+#define TWSI0_MASTER_CMD_REG         (TWSI0_BASE + 0x04)
+#define TWSI1_MASTER_CMD_REG         (TWSI1_BASE + 0x04)
+#define TWSI_MASTER_CMD_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define TWSI_MASTER_CMD_RESET_VALUE  0x00000000UL
+#define TWSI_WR_REQ_BIT      0
+#define TWSI_RD_REQ_BIT      1
+#define TWSI_STOP_REQ_BIT    2
+#define TWSI_START_REQ_BIT   3
+#define TWSI_ABORT_CMD_BIT   6
+
+
+/*
+ * TWSI Timing Register definition (read/write)
+ *     Clock Low  Period = (TLOW +1)*(System clock period)*(prescale factor)
+ *     Clock High Period = (THIGH+1)*(System clock period)*(prescale factor)
+ *     Bus Free Time     = (TBUF +1)*(System clock period)*(prescale factor)
+ *     Data Hold Time    = (THOLD+1)*(System clock period)*(prescale factor)
+ */
+#define TWSI0_TIMING_REG         (TWSI0_BASE + 0x08)
+#define TWSI1_TIMING_REG         (TWSI1_BASE + 0x08)
+#define TWSI_TIMING_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define TWSI_TLOW_FIELD      0
+#define   NBITS_TWSI_TLOW      8
+#define TWSI_THIGH_FIELD     8
+#define   NBITS_TWSI_THIGH     8
+#define TWSI_TBUF_FIELD     16
+#define   NBITS_TWSI_TBUF      8
+#define TWSI_THOLD_FIELD    24
+#define   NBITS_TWSI_THOLD     1
+
+
+/*
+ * TWSI Timeout Register definition (read/write)
+ *     Clock Low Timeout Period =
+ *         (Timeout+1)*(System clock period)*(prescale factor)
+ */
+#define TWSI0_TIMEOUT_REG        (TWSI0_BASE + 0x0c)
+#define TWSI1_TIMEOUT_REG        (TWSI1_BASE + 0x0c)
+#define TWSI_TIMEOUT_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define TWSI_TIMEOUT_FIELD     0
+#define   NBITS_TWSI_TIMEOUT    16
+#define TWSI_TOUT_EN_BIT      16
+
+
+/*
+ * TWSI Slave Address Register definition (read/write)
+ */
+#define TWSI0_SLAVE_ADDRESS_REG        (TWSI0_BASE + 0x14)
+#define TWSI1_SLAVE_ADDRESS_REG        (TWSI1_BASE + 0x14)
+#define TWSI_SLAVE_ADDRESS_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define TWSI_SLV_ADDR_FIELD     0
+#define   NBITS_TWSI_SLV_ADDR     10
+#define TWSI_TEN_ADDR_EN_BIT    10
+
+
+/*
+ * TWSI Slave Data Register definition (read/write)
+ */
+#define TWSI0_SLAVE_DATA_REG        (TWSI0_BASE + 0x18)
+#define TWSI1_SLAVE_DATA_REG        (TWSI1_BASE + 0x18)
+#define TWSI_SLAVE_DATA_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define TWSI_SLV_DATA_FIELD     0
+#define   NBITS_TWSI_SLV_DATA     8
+
+
+/*
+ * TWSI Address Capture Register definition (read only)
+ */
+#define TWSI0_ADDRESS_CAPTURE_REG        (TWSI0_BASE + 0x1c)
+#define TWSI1_ADDRESS_CAPTURE_REG        (TWSI1_BASE + 0x1c)
+#define TWSI_ADDRESS_CAPTURE_REG_ACCESS  (READ_ACCESS)
+#define TWSI_TRANS_ADDR_FIELD   0
+#define   NBITS_TWSI_TRANS_ADDR   14
+
+
+/*
+ * TWSI Master Target Address Register definition (read/write)
+ */
+#define TWSI0_MSTR_TARGET_ADDRESS_REG       (TWSI0_BASE + 0x20)
+#define TWSI1_MSTR_TARGET_ADDRESS_REG       (TWSI1_BASE + 0x20)
+#define TWSI_MSTR_TARGET_ADDRESS_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define TWSI_MSTR_ADDR_FIELD     0
+#define   NBITS_TWSI_MSTR_ADDR     7
+
+
+/*
+ * TWSI Master Data Register definition (read/write)
+ */
+#define TWSI0_MSTR_DATA_REG       (TWSI0_BASE + 0x24)
+#define TWSI1_MSTR_DATA_REG       (TWSI1_BASE + 0x24)
+#define TWSI_MSTR_DATA_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define TWSI_MSTR_DATA_FIELD    0
+#define   NBITS_TWSI_MSTR_DATA    8
+
+
+/*
+ * TWSI Status Register definition (read only)
+ */
+#define TWSI0_STATUS_REG        (TWSI0_BASE + 0x28)
+#define TWSI1_STATUS_REG        (TWSI1_BASE + 0x28)
+#define TWSI_STATUS_REG_ACCESS  (READ_ACCESS)
+#define TWSI_STATUS_RESET_VALUE  0x00400000UL
+#define TWSI_SLV_RD_BIT        0
+#define TWSI_SLV_WR_BIT        1
+#define TWSI_GEN_CALL_BIT      2
+#define TWSI_MSTR_WR_BIT       3
+#define TWSI_MSTR_RD_BIT       4
+#define TWSI_ANACK_BIT         6
+#define TWSI_DNACK_BIT         7
+#define TWSI_SLV_TIMEOUT_BIT   8
+#define TWSI_MSTR_TIMEOUT_BIT  9
+#define TWSI_SLV_WBEND_BIT     10
+#define TWSI_SLV_RBEND_BIT     11
+#define TWSI_ARB_LOSS_BIT      12
+#define TWSI_EXT_CTIMEOUT_BIT  13
+
+
+/*
+ * TWSI Status Enable Register definition (read/write)
+ *     Write a '1' to enable the corresponding status bit.
+ */
+#define TWSI0_STATUS_EN_REG         (TWSI0_BASE + 0x2c)
+#define TWSI1_STATUS_EN_REG         (TWSI1_BASE + 0x2c)
+#define TWSI_STATUS_EN_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define TWSI_STATUS_EN_RESET_VALUE  0x00000000UL
+#define TWSI_SLV_RD_EN_BIT          0
+#define TWSI_SLV_WR_EN_BIT          1
+#define TWSI_GEN_CALL_EN_BIT        2
+#define TWSI_MSTR_WR_EN_BIT         3
+#define TWSI_MSTR_RD_EN_BIT         4
+#define TWSI_ANACK_EN_BIT           6
+#define TWSI_DNACK_EN_BIT           7
+#define TWSI_SLV_TIMEOUT_EN_BIT     8
+#define TWSI_MSTR_TIMEOUT_EN_BIT    9
+#define TWSI_SLV_WBEND_EN_BIT       10
+#define TWSI_SLV_RBEND_EN_BIT       11
+#define TWSI_ARB_LOSS_EN_BIT        12
+#define TWSI_EXT_CTIMEOUT_EN_BIT    13
+
+/*
+ * TWSI Status Clear Register definition (write only)
+ *     Write a '1' to clear the corresponding status bit.
+ */
+#define TWSI0_STATUS_CLEAR_REG        (TWSI0_BASE + 0x30)
+#define TWSI1_STATUS_CLEAR_REG        (TWSI1_BASE + 0x30)
+#define TWSI_STATUS_CLEAR_REG_ACCESS  (WRITE_ACCESS)
+#define TWSI_SLV_RD_CLR_BIT         0
+#define TWSI_SLV_WR_CLR_BIT         1
+#define TWSI_GEN_CALL_CLR_BIT       2
+#define TWSI_MSTR_WR_CLR_BIT        3
+#define TWSI_MSTR_RD_CLR_BIT        4
+#define TWSI_ANACK_CLR_BIT          6
+#define TWSI_DNACK_CLR_BIT          7
+#define TWSI_SLV_TIMEOUT_CLR_BIT    8
+#define TWSI_MSTR_TIMEOUT_CLR_BIT   9
+#define TWSI_SLV_WBEND_CLR_BIT      10
+#define TWSI_SLV_RBEND_CLR_BIT      11
+#define TWSI_ARB_LOSS_CLR_BIT       12
+#define TWSI_EXT_CTIMEOUT_CLR_BIT   13
+
+
+
+/*
+ **********************************************************
+ *  Ethernet Registers Definitions
+ **********************************************************
+ */
+
+/*
+ * Ethernet Module Control Register definition
+ *     Byte Order: 0 = LSB first
+ *                 1 = MSB first
+ *     Clock Divisor: 00 = Sysclock/14
+ *                    01 = Sysclock/28
+ *                    10 = Sysclock/34
+ *                    11 = Sysclock/40
+ */
+#define ENET0_CONTROL_REG             (ENET0_BASE + 0x00)
+#define ENET1_CONTROL_REG             (ENET1_BASE + 0x00)
+#define ENET_CONTROL_REG_ACCESS       (READ_ACCESS | WRITE_ACCESS)
+#define ENET_CONTROL_RESET_VALUE      0x00000000
+#define ENET_RESET_BIT                0
+#define ENET_TX_DMA_BIT               1
+#define ENET_RX_DMA_BIT               2
+#define ENET_BYTE_ORDER_BIT           3
+#define ENET_MDC_CLK_DIV_FIELD        4
+#define   NBITS_ENET_MDC_CLK_DIV        5
+#define ENET_CAMHIT_EN_BIT            11
+
+
+/*
+ * Ethernet Tx Write Data Port Register definition
+ *     Provides transmit packet data in non-DMA mode.
+ *     Don't use when Tx DMA mode is enabled.
+ */
+#define ENET0_TX_WRITE_DATA_REG        (ENET0_BASE + 0x04)
+#define ENET1_TX_WRITE_DATA_REG        (ENET1_BASE + 0x04)
+#define ENET_TX_WRITE_DATA_REG_ACCESS  (WRITE_ACCESS)
+
+
+/*
+ * Ethernet Tx Packet Boundary/Options Control Register definition
+ *     Provides control/status info for transmit packets in non-DMA mode.
+ *     Sets per-packet transmit options for transmit packets in non-DMA mode.
+ *     Don't use when Tx DMA mode is enabled.
+ *     Writing '1' to TxLastWord bit indicates that next word written to the
+ *         Tx Packet Write Data Port will contain the last byte of the packet.
+ *     LastByteValid  ByteOrder=0 ByteOrder=1
+ *             Field  Valid Bits  Valid Bits
+ *                00        0-31        0-31
+ *                01        0--7       24-31
+ *                10        0-15       16-31
+ *                11        0-23        8-31
+ *     The Tx Options bits[18:16] set the options for the next packet,
+ *         and should be written after TxLastWord is written
+ *         and before the first word of the next packet is written.
+ */
+#define ENET0_TX_PACKET_CTL_REG             (ENET0_BASE + 0x08)
+#define ENET1_TX_PACKET_CTL_REG             (ENET1_BASE + 0x08)
+#define ENET_TX_PACKET_CTL_REG_ACCESS       (READ_ACCESS | WRITE_ACCESS)
+#define ENET_TX_PACKET_CTL_RESET_VALUE      0x00000000
+#define ENET_TX_LAST_WORD_BIT               0
+#define ENET_TX_LAST_BVALID_FIELD           1
+#define   NBITS_ENET_TX_LAST_BVALID           2
+#define ENET_TX_OPTIONS_FIELD               16
+#define   NBITS_ENET_TX_OPTIONS               3
+// Tx Options Bits
+#define   ENET_TX_DONT_PAD_SPKTS_BIT        16
+#define   ENET_TX_NO_CRC_APPEND_BIT         17
+#define   ENET_TX_INT_AFTER_TX_BIT          18
+
+
+/*
+ * Ethernet Tx FIFO Status Register definition
+ *     Provides transmit write buffer and FIFO status.
+ * Ethernet Tx Interrupt Enable Register definition
+ *     Setting a bit position to '1' will enable the corresponding interrupt.
+ * Ethernet Tx Interrupt Status Register definition
+ *     Shows a '1' in each bit position where an interrupt has occurred.
+ * Ethernet Tx Interrupt Clear Register definition
+ *     Writing a '1' to a bit position will clear the corresponding interrupt.
+ */
+#define ENET0_TX_FIFO_STATUS_REG            (ENET0_BASE + 0x0c)
+#define ENET1_TX_FIFO_STATUS_REG            (ENET1_BASE + 0x0c)
+#define ENET_TX_FIFO_STATUS_REG_ACCESS      (READ_ACCESS)
+#define ENET_TX_FIFO_STATUS_RESET_VALUE     0x00000014
+#define ENET_WB_EMPTY_BIT                   2
+#define ENET_WB_FULL_BIT                    3
+#define ENET_WB_OVERFLOW_BIT                4
+#define ENET_TX_FIFO_EMPTY_BIT              5
+#define ENET_TX_FIFO_FULL_BIT               6
+
+/*
+ * Ethernet Tx Transmit Status Register definition
+ *     Contains the Transmit Status from the MAC of last transmitted packet.
+ *     Updated when packet is transmitted, not when its delivered into FIFO.
+ */
+#define ENET0_TX_TRANSMIT_STATUS_REG        (ENET0_BASE + 0x10)
+#define ENET1_TX_TRANSMIT_STATUS_REG        (ENET1_BASE + 0x10)
+#define ENET_TX_TRANSMIT_STATUS_REG_ACCESS      (READ_ACCESS)
+#define ENET_TX_TRANSMIT_STATUS_RESET_VALUE 0x00000000
+#define ENET_TX_COL_FIELD                   0
+#define   NBITS_ENET_TX_COL                   4
+#define ENET_EX_COL_BIT                     4
+#define ENET_TX_DEFER_BIT                   5
+#define ENET_PAUSED_BIT                     6
+#define ENET_INT_TX_BIT                     7
+#define ENET_UNDER_BIT                      8
+#define ENET_EX_DEFER_BIT                   9
+#define ENET_LCARR_BIT                      10
+#define ENET_LATE_COL_BIT                   12
+#define ENET_TX_PAR_BIT                     13
+#define ENET_TX_COMP_BIT                    14
+#define ENET_TX_HALTED_BIT                  15
+#define ENET_SQ_ERR_BIT                     16
+#define ENET_TX_MCAST_BIT                   17
+#define ENET_TX_BCAST_BIT                   18
+#define ENET_TX_VLAN_BIT                    19
+#define ENET_TX_MACC_BIT                    20
+#define ENET_TX_PAUSE_BIT                   21
+#define ENET_TX_HNR_BIT                     22
+#define ENET_TX_COUNT_LSB_FIELD             24
+#define   NBITS_ENET_TX_COUNT_LSB             8
+
+
+/*
+ * Ethernet Tx Interrupt Enable Register definition
+ *     Setting a bit position to '1' will enable the corresponding interrupt.
+ * Ethernet Tx Interrupt Status Register definition
+ *     Shows a '1' in each bit position where an interrupt has occurred.
+ * Ethernet Tx Interrupt Clear Register definition
+ *     Writing a '1' to a bit position will clear the corresponding interrupt.
+ */
+#define ENET0_TX_INT_ENABLE_REG             (ENET0_BASE + 0x14)
+#define ENET1_TX_INT_ENABLE_REG             (ENET1_BASE + 0x14)
+#define ENET_TX_INT_ENABLE_REG_ACCESS       (READ_ACCESS | WRITE_ACCESS)
+#define ENET_TX_INT_ENABLE_RESET_VALUE      0x00000000
+
+#define ENET0_TX_INT_STATUS_REG             (ENET0_BASE + 0x18)
+#define ENET1_TX_INT_STATUS_REG             (ENET1_BASE + 0x18)
+#define ENET_TX_INT_STATUS_REG_ACCESS       (READ_ACCESS)
+#define ENET_TX_INT_STATUS_RESET_VALUE      0x00000000
+
+#define ENET0_TX_INT_CLEAR_REG              (ENET0_BASE + 0x1c)
+#define ENET1_TX_INT_CLEAR_REG              (ENET1_BASE + 0x1c)
+#define ENET_TX_INT_CLEAR_REG_ACCESS        (WRITE_ACCESS)
+
+#define ENET_INT_WB_EMPTY_BIT               2
+#define ENET_INT_WB_FULL_BIT                3
+#define ENET_INT_WB_OVERFLOW_BIT            4
+#define ENET_INT_TX_FIFO_EMPTY_BIT          5
+#define ENET_INT_TX_FIFO_FULL_BIT           6
+#define ENET_INT_MAC_TX_BIT                 7
+#define ENET_INT_MAC_TX_LINK_BIT            16
+
+
+/*
+ * Ethernet Tx Packet Counter Register definition
+ *     If any byte is written to, all other bytes are cleared to '0'.
+ *    Count = number of packets transmitted by MAC since last counter reset.
+ */
+#define ENET0_TX_PACKET_COUNTER_REG             (ENET0_BASE + 0x20)
+#define ENET1_TX_PACKET_COUNTER_REG             (ENET1_BASE + 0x20)
+#define ENET_TX_PACKET_COUNTER_REG_ACCESS       (READ_ACCESS | WRITE_ACCESS)
+#define ENET_TX_PACKET_COUNTER_RESET_VALUE      0x00000000
+#define ENET_TX_COUNT_FIELD                     0
+#define   NBITS_ENET_TX_COUNT                     16
+
+
+/*
+ * Ethernet Rx Read Data Port Register definition
+ *     Used to read received packet data in non-DMA mode.
+ *     Reads from this register return garbage while Rx DMA mode is enabled.
+ *     Reads from this register empties the Rx FIFO.
+ *     Packet boundaries can be determined using the Rx Read Control register.
+ *     Reads from this register when there's no data in Rx FIFO, return garbage
+ *         and set the Rb_underflow bit in the Rx Read Status register, and
+ *         may generate Interrupt depending on value of corresponding bit in
+ *         the Interrupt mask register.
+ */
+#define ENET0_RX_READ_DATA_REG              (ENET0_BASE + 0x24)
+#define ENET1_RX_READ_DATA_REG              (ENET1_BASE + 0x24)
+#define ENET_RX_READ_DATA_REG_ACCESS        (READ_ACCESS)
+
+
+/*
+ * Ethernet Rx FIFO Status Register definition
+ *     Provides control and status info for receive packets in non-DMA mode.
+ *     This register should not be used when Rx DMA mode is enabled.
+ *     LastByteValid  ByteOrder=0 ByteOrder=1
+ *             Field  Valid Bits  Valid Bits
+ *                00        0-31        0-31
+ *                01        0--7       24-31
+ *                10        0-15       16-31
+ *                11        0-23        8-31
+ */
+#define ENET0_RX_FIFO_STATUS_REG            (ENET0_BASE + 0x28)
+#define ENET1_RX_FIFO_STATUS_REG            (ENET1_BASE + 0x28)
+#define ENET_RX_FIFO_STATUS_REG_ACCESS      (READ_ACCESS)
+#define ENET_RX_FIFO_STATUS_RESET_VALUE     0x00000000
+#define ENET_RX_LAST_WORD_BIT               0
+#define ENET_RB_LAST_PRESENT_BIT            1
+#define ENET_RB_EMPTY_BIT                   2
+#define ENET_RB_FULL_BIT                    3
+#define ENET_RB_UNDERFLOW_BIT               4
+#define ENET_RD_FIFO_EMPTY_BIT              5
+#define ENET_RD_FIFO_FULL_BIT               6
+#define ENET_RX_LAST_BVALID_FIELD           8
+#define   NBITS_ENET_RX_LAST_BVALID           2
+
+
+/*
+ * Ethernet Rx Receive Status Register definition
+ *     Provides control and status info for receive packets in non-DMA mode.
+ *     This register should not be used when Rx DMA mode is enabled.
+ *     ArcStatus  Action    Reason
+ *          0000  Toss      MAC control received and PassCtl==0
+ *          0001  Toss      6 <= length < minLen, and was keep otherwise
+ *          0010  Toss      ARC match, negative filtering
+ *          0011  Reserved
+ *          0100  Reserved
+ *          0101  Reserved
+ *          0110  Toss      no match, no enable, positive filtering
+ *          0111  Toss      length < 6 and shortEn not set
+ *          1000  Keep      broadcast, multicast, unicast enabled and matched
+ *          1001  Reserved
+ *          1010  Keep      ARC match positive filtering
+ *          1011  Reserved
+ *          1100  Reserved
+ *          1101  Reserved
+ *          1110  Keep      no match, negative filtering
+ *          1111  Reserved
+ */
+#define ENET0_RX_RECEIVE_STATUS_REG             (ENET0_BASE + 0x2c)
+#define ENET1_RX_RECEIVE_STATUS_REG             (ENET1_BASE + 0x2c)
+#define ENET_RX_RECEIVE_STATUS_REG_ACCESS       (READ_ACCESS)
+#define ENET_RX_RECEIVE_STATUS_RESET_VALUE      0x00000000
+#define ENET_LEN_ERR_BIT                        4
+#define ENET_CTL_RECD_BIT                       5
+#define ENET_INT_RX_BIT                         6
+#define ENET_ALIGN_ERR_BIT                      8
+#define ENET_CRC_ERR_BIT                        9
+#define ENET_OVERFLOW_BIT                       10
+#define ENET_LONG_ERR_BIT                       11
+#define ENET_RX_PARR_BIT                        13
+#define ENET_GOOD_BIT                           14
+#define ENET_RX_HALTED_BIT                      15
+#define ENET_RX_MCAST_BIT                       17
+#define ENET_RX_BCAST_BIT                       18
+#define ENET_RX_VLAN_BIT                        19
+#define ENET_RX_PAUSE_BIT                       20
+#define ENET_ARC_STATUS_FIELD                   21
+#define   NBITS_ENET_ARC_STATUS                   4
+#define ENET_ARC_ENTRY_FIELD                    25
+#define   NBITS_ENET_ARC_ENTRY                    2
+
+
+/*
+ * Ethernet Rx Interrupt Enable Register definition
+ *     Setting a bit position to '1' will enable the corresponding interrupt.
+ * Ethernet Rx Interrupt Status Register definition
+ *     Shows a '1' in each bit position where an interrupt has occurred.
+ * Ethernet Rx Interrupt Clear Register definition
+ *     Writing a '1' to a bit position will clear the corresponding interrupt.
+ */
+#define ENET0_RX_INT_ENABLE_REG             (ENET0_BASE + 0x30)
+#define ENET1_RX_INT_ENABLE_REG             (ENET1_BASE + 0x30)
+#define ENET_RX_INT_ENABLE_REG_ACCESS       (READ_ACCESS | WRITE_ACCESS)
+#define ENET_RX_INT_ENABLE_RESET_VALUE      0x00000000
+
+#define ENET0_RX_INT_STATUS_REG             (ENET0_BASE + 0x34)
+#define ENET1_RX_INT_STATUS_REG             (ENET1_BASE + 0x34)
+#define ENET_RX_INT_STATUS_REG_ACCESS       (READ_ACCESS)
+#define ENET_RX_INT_STATUS_RESET_VALUE      0x00000000
+
+#define ENET0_RX_INT_CLEAR_REG              (ENET0_BASE + 0x38)
+#define ENET1_RX_INT_CLEAR_REG              (ENET1_BASE + 0x38)
+#define ENET_RX_INT_CLEAR_REG_ACCESS        (WRITE_ACCESS)
+
+#define ENET_INT_RX_LAST_WORD_BIT           0
+#define ENET_INT_RB_LAST_PRESENT_BIT        1
+#define ENET_INT_RB_EMPTY_BIT               2
+#define ENET_INT_RB_FULL_BIT                3
+#define ENET_INT_RB_UNDERFLOW_BIT           4
+#define ENET_INT_RX_FIFO_EMPTY_BIT          5
+#define ENET_INT_RX_FIFO_FULL_BIT           6
+#define ENET_INT_MAC_RX_BIT                 7
+#define ENET_INT_MAC_RX_LINK_BIT            16
+
+
+/*
+ * Ethernet Rx Packet Keep/Toss Counters Register definition
+ *     If any byte is written to, all other bytes are cleared to '0'.
+ */
+#define ENET0_RX_PACKET_COUNTER_REG         (ENET0_BASE + 0x3c)
+#define ENET1_RX_PACKET_COUNTER_REG         (ENET1_BASE + 0x3c)
+#define ENET_RX_PACKET_COUNTER_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define ENET_RX_PACKET_COUNTER_RESET_VALUE  0x00000000
+#define ENET_RX_KEEP_COUNT_FIELD            0
+#define   NBITS_ENET_RX_KEEP_COUNT            16
+#define ENET_RX_TOSS_COUNT_FIELD            16
+#define   NBITS_ENET_RX_TOSS_COUNT            16
+
+
+/*
+ * Ethernet ARC Registers definition
+ *     These should not be written to while MAC is enabled to receive packets.
+ */
+#define ENET0_ARC_40_REG    (ENET0_BASE + 0x40)
+#define ENET1_ARC_40_REG    (ENET1_BASE + 0x40)
+#define ENET0_ARC_44_REG    (ENET0_BASE + 0x44)
+#define ENET1_ARC_44_REG    (ENET1_BASE + 0x44)
+#define ENET0_ARC_48_REG    (ENET0_BASE + 0x48)
+#define ENET1_ARC_48_REG    (ENET1_BASE + 0x48)
+#define ENET0_ARC_4C_REG    (ENET0_BASE + 0x4c)
+#define ENET1_ARC_4C_REG    (ENET1_BASE + 0x4c)
+#define ENET0_ARC_50_REG    (ENET0_BASE + 0x50)
+#define ENET1_ARC_50_REG    (ENET1_BASE + 0x50)
+#define ENET_ARC_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+
+
+/*
+ * Ethernet MAC Pause Count Register definition
+ * Ethernet MAC Remote Pause Count Register definition
+ */
+#define ENET0_MAC_PAUSE_COUNT_REG           (ENET0_BASE + 0xb0)
+#define ENET1_MAC_PAUSE_COUNT_REG           (ENET1_BASE + 0xb0)
+#define ENET0_MAC_REMOTE_PAUSE_COUNT_REG    (ENET0_BASE + 0xb4)
+#define ENET1_MAC_REMOTE_PAUSE_COUNT_REG    (ENET1_BASE + 0xb4)
+#define ENET_MAC_PAUSE_COUNT_REG_ACCESS     (READ_ACCESS)
+#define ENET_MAC_PAUSE_COUNT_RESET_VALUE    0x00000000
+#define MAC_PAUSE_COUNT_FIELD               0
+#define   NBITS_MAC_PAUSE_COUNT               16
+
+
+/*
+ * Ethernet MAC Control Register definition
+ */
+#define ENET0_MAC_CONTROL_REG           (ENET0_BASE + 0xc0)
+#define ENET1_MAC_CONTROL_REG           (ENET1_BASE + 0xc0)
+#define ENET_MAC_CONTROL_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define ENET_MAC_CONTROL_RESET_VALUE    0x0000
+#define MAC_HALT_REQ_BIT                0
+#define MAC_HALT_IMM_BIT                1
+#define MAC_FULL_DUP_BIT                3
+#define MAC_LOOP_BIT                    4
+#define MAC_CONN_FIELD                  5
+#define   NBITS_MAC_CONN                  2
+#define MAC_LOOP10_BIT                  7
+#define MAC_LNK_CHG_BIT                 8
+#define MAC_MISS_ROLL_BIT               10      // read-only
+#define MAC_EN_MISS_ROLL_BIT            13
+#define MAC_LINK10_BIT                  15      // read-only
+
+// MAC_CONN_FIELD definitions
+#define MAC_CONN_AUTO_BIT               0
+#define MAC_CONN_FORCE_10_BIT           1
+#define MAC_CONN_FORCE_MII_BIT          2
+
+
+/*
+ * Ethernet MAC ARC Control Register definition
+ */
+#define ENET0_MAC_ARC_CONTROL_REG           (ENET0_BASE + 0xc4)
+#define ENET1_MAC_ARC_CONTROL_REG           (ENET1_BASE + 0xc4)
+#define ENET_MAC_ARC_CONTROL_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define ENET_MAC_ARC_CONTROL_RESET_VALUE    0x0000
+#define MAC_STATION_ACC_BIT                 0
+#define MAC_GROUP_ACC_BIT                   1
+#define MAC_BROAD_ACC_BIT                   2
+#define MAC_NEG_ARC_BIT                     3
+#define MAC_COMP_EN_BIT                     4
+
+
+/*
+ * Ethernet MAC Transmit Control Register definition
+ */
+#define ENET0_MAC_TX_CONTROL_REG            (ENET0_BASE + 0xc8)
+#define ENET1_MAC_TX_CONTROL_REG            (ENET1_BASE + 0xc8)
+#define ENET_MAC_TX_CONTROL_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define ENET_MAC_TX_CONTROL_RESET_VALUE     0x0000
+#define MAC_TX_EN_BIT                       0
+#define MAC_TX_HALT_BIT                     1
+#define MAC_NO_PAD_BIT                      2
+#define MAC_NO_CRC_BIT                      3
+#define MAC_NO_EX_DEF_BIT                   5
+#define MAC_SD_PAUSE_BIT                    6
+#define MAC_EN_UNDER_BIT                    8
+#define MAC_EN_EX_DEFER_BIT                 9
+#define MAC_EN_LCARR_BIT                    10
+#define MAC_EN_EX_COLL_BIT                  11
+#define MAC_EN_LATE_COLL_BIT                12
+#define MAC_EN_TX_PAR_BIT                   13
+#define MAC_EN_COMPL_BIT                    14
+
+
+/*
+ * Ethernet MAC Transmit Status Register definition
+ */
+#define ENET0_MAC_TX_STATUS_REG             (ENET0_BASE + 0xcc)
+#define ENET1_MAC_TX_STATUS_REG             (ENET1_BASE + 0xcc)
+#define ENET_MAC_TX_STATUS_REG_ACCESS       (READ_ACCESS)
+#define ENET_MAC_TX_STATUS_RESET_VALUE      0x000000
+#define MAC_TX_COLL_FIELD                   0
+#define   NBITS_MAC_TX_COLL                   4
+#define MAC_EX_COLL_BIT                     4
+#define MAC_TX_DEFER_BIT                    5
+#define MAC_PAUSED_BIT                      6
+#define MAC_INT_TX_BIT                      7
+#define MAC_UNDER_BIT                       8
+#define MAC_EX_DEFER_BIT                    9
+#define MAC_LCARR_BIT                       10
+#define MAC_LATE_COLL_BIT                   12
+#define MAC_TX_PARR_BIT                     13
+#define MAC_COMP_BIT                        14
+#define MAC_TX_HALTED_BIT                   15
+#define MAC_SQ_ERR_BIT                      16
+#define MAC_TX_MCAST_BIT                    17
+#define MAC_TX_BCAST_BIT                    18
+#define MAC_TX_VLAN_BIT                     19
+#define MAC_TX_MACC_BIT                     20
+#define MAC_TX_PAUSE_BIT                    21
+
+/*
+ * Ethernet MAC Receive Control Register definition
+ */
+#define ENET0_MAC_RX_CONTROL_REG            (ENET0_BASE + 0xd0)
+#define ENET1_MAC_RX_CONTROL_REG            (ENET1_BASE + 0xd0)
+#define ENET_MAC_RX_CONTROL_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define ENET_MAC_RX_CONTROL_RESET_VALUE     0x0000
+#define MAC_RX_EN_BIT                       0
+#define MAC_RX_HALT_BIT                     1
+#define MAC_LONG_EN_BIT                     2
+#define MAC_SHORT_EN_BIT                    3
+#define MAC_STRIP_CRC_BIT                   4
+#define MAC_PASS_CTL_BIT                    5
+#define MAC_IGNORE_CRC_BIT                  6
+#define MAC_EN_ALIGN_BIT                    8
+#define MAC_EN_CRC_ERR_BIT                  9
+#define MAC_EN_OVER_BIT                     10
+#define MAC_EN_LONG_ERR_BIT                 11
+#define MAC_EN_RX_PARR_BIT                  13
+#define MAC_EN_GOOD_BIT                     14
+
+
+/*
+ * Ethernet MAC Receive Status Register definition
+ */
+#define ENET0_MAC_RX_STATUS_REG             (ENET0_BASE + 0xd4)
+#define ENET1_MAC_RX_STATUS_REG             (ENET1_BASE + 0xd4)
+#define ENET_MAC_RX_STATUS_REG_ACCESS       (READ_ACCESS)
+#define ENET_MAC_RX_STATUS_RESET_VALUE      0x00000000
+#define MAC_LEN_ERR_BIT                     4
+#define MAC_CTL_RECD_BIT                    5
+#define MAC_INT_RX_BIT                      6
+#define MAC_ALIGN_ERR_BIT                   8
+#define MAC_CRC_ERR_BIT                     9
+#define MAC_OVERFLOW_BIT                    10
+#define MAC_LONG_ERR_BIT                    11
+#define MAC_RX_PARR_BIT                     13
+#define MAC_GOOD_BIT                        14
+#define MAC_RX_HALTED_BIT                   15
+#define MAC_RX_MCAST_BIT                    17
+#define MAC_RX_BCAST_BIT                    18
+#define MAC_RX_VLAN_BIT                     19
+#define MAC_RX_PAUSE_BIT                    20
+#define MAC_ARC_STATUS_FIELD                21
+#define   NBITS_MAC_ARC_STATUS                4
+#define MAC_ARC_ENT_FIELD                   25
+#define   NBITS_MAC_ARC_ENT                   5
+
+
+/*
+ * Ethernet MAC SM Data Register definition
+ */
+#define ENET0_MAC_SM_DATA_REG               (ENET0_BASE + 0xd8)
+#define ENET1_MAC_SM_DATA_REG               (ENET1_BASE + 0xd8)
+#define ENET_MAC_SM_DATA_REG_ACCESS         (READ_ACCESS | WRITE_ACCESS)
+#define ENET_MAC_SM_DATA_RESET_VALUE        0x0000
+#define MAC_MD_DATA_FIELD    0
+#define   NBITS_MAC_MD_DATA   16
+
+
+/*
+ * Ethernet MAC SM Control/Address Register definition
+ *     Before accessing PHY regs, software must ensure BUSY bit is not set.
+ */
+#define ENET0_MAC_SM_CTRL_ADDR_REG         (ENET0_BASE + 0xdc)
+#define ENET1_MAC_SM_CTRL_ADDR_REG         (ENET1_BASE + 0xdc)
+#define ENET_MAC_SM_CTRL_ADDR_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define ENET_MAC_SM_CTRL_ADDR_RESET_VALUE   0x0000
+#define MAC_ADDR_FIELD                      0
+#define   NBITS_MAC_ADDR                      5
+#define MAC_PHY_FIELD                       5
+#define   NBITS_MAC_PHY                       5
+#define MAC_WRITE_BIT                       10
+#define MAC_BUSY_BIT                        11
+#define MAC_PRE_SUP_BIT                     12
+
+
+/*
+ * Ethernet MAC ARC Enable Register definition
+ */
+#define ENET0_MAC_ARC_ENABLE_REG            (ENET0_BASE + 0xe8)
+#define ENET1_MAC_ARC_ENABLE_REG            (ENET1_BASE + 0xe8)
+#define ENET_MAC_ARC_ENABLE_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define ENET_MAC_ARC_ENABLE_RESET_VALUE     0x000000
+#define MAC_ARC_ENABLE_FIELD                0
+#define   NBITS_MAC_ARC_ENABLE                3
+
+
+/*
+ * Ethernet MAC Missed Error Count Register definition
+ */
+#define ENET0_MAC_MISSED_ERR_CNT_REG        (ENET0_BASE + 0xec)
+#define ENET1_MAC_MISSED_ERR_CNT_REG        (ENET1_BASE + 0xec)
+#define ENET_MAC_MISSED_ERR_CNT_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define ENET_MAC_MISSED_ERR_CNT_RESET_VALUE 0x00000000
+#define MAC_MISS_CNT_FIELD                  0
+#define   NBITS_MAC_MISS_CNT                  16
+
+
+
+/*
+ **********************************************************
+ *  SSI/SPI PROM Registers Definitions
+ **********************************************************
+ */
+
+/*
+ * SSI/SPI Control Register definition
+ *     Shift applied = 1 << (shift value + 1)
+ */
+#define SSI_CONTROL_REG                 (SSI_BASE + 0x00)
+#define SSI_CONTROL_REG_ACCESS          (READ_ACCESS | WRITE_ACCESS)
+#define SSI_CONTROL_RESET_VALUE         0x00000000
+#define SSI_EN_BIT                      0
+#define SSI_RAW_MODE_EN_BIT             1
+#define SSI_XFER_MODE_BIT               2
+#define SSI_PRESCALER_FIELD             4
+#define   NBITS_SSI_PRESCALER             2
+#define SSI_FORCE_CS_BIT                6
+#define SSI_CS_CTRL_BIT                 7
+#define SSI_TX_SIZE_FIELD               12
+#define   NBITS_TX_SIZE                   5
+#define SSI_RX_SIZE_FIELD               20
+#define   NBITS_SSI_RX_SIZE               5
+
+
+/*
+ * SSI/SPI Master Execute Register definition
+ *     Setting the bit initiates a Master read or write transaction.
+ *     Hardware clears bit when transaction is processed by master logic.
+ *     Bit can be polled instead of the Ready/Busy status bit.
+ */
+#define SSI_XFER_INIT_REG               (SSI_BASE + 0x04)
+#define SSI_XFER_INIT_REG_ACCESS        (READ_ACCESS | WRITE_ACCESS)
+#define SSI_XFER_INIT_RESET_VALUE       0x00000000
+#define SSI_XFER_REQ_BIT                0
+
+
+/*
+ * SSI/SPI Timing Register definition
+ *    Serial eeprom clock frequency range is from 0 to about 250 kHz.
+ *    (Tsck+1) * 2 * (System clock period) * (prescale factor)
+ */
+#define SSI_TIMING_CTRL_REG             (SSI_BASE + 0x08)
+#define SSI_TIMING_CTRL_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define SSI_TIMING_CTRL_RESET_VALUE     0x00000000
+#define SSI_TSCK_FIELD                  0
+#define   NBITS_SSI_TSCK                  8
+
+
+/*
+ * SSI/SPI Data Input Register definition
+ */
+#define SSI_RX_DATA_REG                 (SSI_BASE + 0x0c)
+#define SSI_RX_DATA_REG_ACCESS          (READ_ACCESS | WRITE_ACCESS)
+#define SSI_RX_DATA_RESET_VALUE         0x00000000
+#define SSI_RX_DATA_FIELD               0
+#define   NBITS_SSI_RX_DATA               16
+
+
+/*
+ * SSI/SPI Command/Address I/O Register definition
+ */
+#define SSI_TX_DATA_REG                 (SSI_BASE + 0x10)
+#define SSI_TX_DATA_REG_ACCESS          (READ_ACCESS | WRITE_ACCESS)
+#define SSI_TX_DATA_RESET_VALUE         0x00000000
+#define SSI_TX_DATA_FIELD               0
+#define   NBITS_SSI_TX_DATA               32
+
+
+/*
+ * SSI/SPI Raw Mode Register definition
+ */
+#define SSI_RAW_MODE_REG                (SSI_BASE + 0x14)
+#define SSI_RAW_MODE_REG_ACCESS         (READ_ACCESS | WRITE_ACCESS)
+#define SSI_RAW_MODE_RESET_VALUE        0x00000000
+#define SSI_DO_OUT_BIT                  0
+#define SSI_DI_OUT_BIT                  1
+#define SSI_CLK_OUT_BIT                 2
+#define SSI_CS_OUT_BIT                  3
+#define SSI_DO_IN_BIT                   4
+#define SSI_DI_IN_BIT                   5
+#define SSI_CLK_IN_BIT                  6
+#define SSI_CS_IN_BIT                   7
+#define SSI_DO_DIR_BIT                  8
+#define SSI_DI_DIR_BIT                  9
+#define SSI_CLK_DIR_BIT                 10
+#define SSI_CS_DIR_BIT                  11
+
+
+/*
+ * SSI/SPI Status Register definition
+ */
+#define SSI_STATUS_REG                  (SSI_BASE + 0x1c)
+#define SSI_STATUS_REG_ACCESS           (READ_ACCESS | WRITE_ACCESS)
+#define SSI_STATUS_RESET_VALUE          0x00000000
+#define SSI_STAT_READY_BUSY_BIT         0
+
+
+/*
+ **********************************************************
+ *  MFTA Registers Definitions
+ **********************************************************
+ */
+/*
+ * MFTA Control Register definition
+ */
+#define MFTA_TIMER_CTRL_REG             (MFTA_BASE + 0x00)
+#define MFTA_TIMER_CTRL_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define MFTA_TIMER_CTRL_RESET_VALUE     0x03030303
+
+#define MFTA_TW0_FIELD                  0
+#define   NBITS_MFTA_TW0                  2
+#define MFTA_TEN0_BIT                   2
+#define MFTA_CLKSEL0_BIT                3
+#define MFTA_UDCTRL0_BIT                4
+#define MFTA_SBDCEN0_BIT                5
+#define MFTA_TCCMA0_BIT                 6
+
+#define MFTA_TW1_FIELD                  8
+#define   NBITS_MFTA_TW1                  2
+#define MFTA_TEN1_BIT                   10
+#define MFTA_CLKSEL1_BIT                11
+#define MFTA_UDCTRL1_BIT                12
+#define MFTA_SBDCEN1_BIT                13
+#define MFTA_TCCMA1_BIT                 14
+
+#define MFTA_TW2_FIELD                  16
+#define   NBITS_MFTA_TW2                  2
+#define MFTA_TEN2_BIT                   18
+#define MFTA_CLKSEL2_BIT                19
+#define MFTA_UDCTRL2_BIT                20
+#define MFTA_SBDCEN2_BIT                21
+#define MFTA_TCCMA2_BIT                 22
+
+#define MFTA_TW3_FIELD                  24
+#define   NBITS_MFTA_TW3                  2
+#define MFTA_TEN3_BIT                   26
+#define MFTA_CLKSEL3_BIT                27
+#define MFTA_UDCTRL3_BIT                28
+#define MFTA_SBDCEN3_BIT                29
+#define MFTA_TCCMA3_BIT                 30
+
+/*
+ * MFTA Interrupt Enable Register definition
+ */
+#define MFTA_INT_ENABLE_REG             (MFTA_BASE + 0x04)
+#define MFTA_INT_ENABLE_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define MFTA_INT_ENABLE_RESET_VALUE     0x00000000
+
+#define MFTA_TIMER0COMPA_IEN_BIT        0
+#define MFTA_TIMER0COMPB_IEN_BIT        1
+#define MFTA_TIMER0UDF_IEN_BIT          2
+#define MFTA_TIMER0OVF_IEN_BIT          3
+#define MFTA_TIMER0CAPTA_IEN_BIT        4
+#define MFTA_TIMER0CAPTB_IEN_BIT        5
+
+#define MFTA_TIMER1COMPA_IEN_BIT        8
+#define MFTA_TIMER1COMPB_IEN_BIT        9
+#define MFTA_TIMER1UDF_IEN_BIT          10
+#define MFTA_TIMER1OVF_IEN_BIT          11
+#define MFTA_TIMER1CAPTA_IEN_BIT        12
+#define MFTA_TIMER1CAPTB_IEN_BIT        13
+
+#define MFTA_TIMER2COMPA_IEN_BIT        16
+#define MFTA_TIMER2COMPB_IEN_BIT        17
+#define MFTA_TIMER2UDF_IEN_BIT          18
+#define MFTA_TIMER2OVF_IEN_BIT          19
+#define MFTA_TIMER2CAPTA_IEN_BIT        20
+#define MFTA_TIMER2CAPTB_IEN_BIT        21
+
+#define MFTA_TIMER3COMPA_IEN_BIT        24
+#define MFTA_TIMER3COMPB_IEN_BIT        25
+#define MFTA_TIMER3UDF_IEN_BIT          26
+#define MFTA_TIMER3OVF_IEN_BIT          27
+#define MFTA_TIMER3CAPTA_IEN_BIT        28
+#define MFTA_TIMER3CAPTB_IEN_BIT        29
+
+/*
+ * MFTA Interrupt Status Register definition
+ */
+#define MFTA_INT_STATUS_REG             (MFTA_BASE + 0x08)
+#define MFTA_INT_STATUS_REG_ACCESS      (READ_ACCESS)
+#define MFTA_INT_STATUS_RESET_VALUE     0x00000000
+
+#define MFTA_TIMER0COMPA_ISF_BIT        0
+#define MFTA_TIMER0COMPB_ISF_BIT        1
+#define MFTA_TIMER0UDF_ISF_BIT          2
+#define MFTA_TIMER0OVF_ISF_BIT          3
+#define MFTA_TIMER0CAPTA_ISF_BIT        4
+#define MFTA_TIMER0CAPTB_ISF_BIT        5
+
+#define MFTA_TIMER1COMPA_ISF_BIT        8
+#define MFTA_TIMER1COMPB_ISF_BIT        9
+#define MFTA_TIMER1UDF_ISF_BIT          10
+#define MFTA_TIMER1OVF_ISF_BIT          11
+#define MFTA_TIMER1CAPTA_ISF_BIT        12
+#define MFTA_TIMER1CAPTB_ISF_BIT        13
+
+#define MFTA_TIMER2COMPA_ISF_BIT        16
+#define MFTA_TIMER2COMPB_ISF_BIT        17
+#define MFTA_TIMER2UDF_ISF_BIT          18
+#define MFTA_TIMER2OVF_ISF_BIT          19
+#define MFTA_TIMER2CAPTA_ISF_BIT        20
+#define MFTA_TIMER2CAPTB_ISF_BIT        21
+
+#define MFTA_TIMER3COMPA_ISF_BIT        24
+#define MFTA_TIMER3COMPB_ISF_BIT        25
+#define MFTA_TIMER3UDF_ISF_BIT          26
+#define MFTA_TIMER3OVF_ISF_BIT          27
+#define MFTA_TIMER3CAPTA_ISF_BIT        28
+#define MFTA_TIMER3CAPTB_ISF_BIT        29
+
+/*
+ * MFTA Interrupt Clear Register definition
+ */
+#define MFTA_INT_CLEAR_REG              (MFTA_BASE + 0x0c)
+#define MFTA_INT_CLEAR_REG_ACCESS       (WRITE_ACCESS)
+
+#define MFTA_TIMER0COMPA_CLR_BIT        0
+#define MFTA_TIMER0COMPB_CLR_BIT        1
+#define MFTA_TIMER0UDF_CLR_BIT          2
+#define MFTA_TIMER0OVF_CLR_BIT          3
+#define MFTA_TIMER0CAPTA_CLR_BIT        4
+#define MFTA_TIMER0CAPTB_CLR_BIT        5
+
+#define MFTA_TIMER1COMPA_CLR_BIT        8
+#define MFTA_TIMER1COMPB_CLR_BIT        9
+#define MFTA_TIMER1UDF_CLR_BIT          10
+#define MFTA_TIMER1OVF_CLR_BIT          11
+#define MFTA_TIMER1CAPTA_CLR_BIT        12
+#define MFTA_TIMER1CAPTB_CLR_BIT        13
+
+#define MFTA_TIMER2COMPA_CLR_BIT        16
+#define MFTA_TIMER2COMPB_CLR_BIT        17
+#define MFTA_TIMER2UDF_CLR_BIT          18
+#define MFTA_TIMER2OVF_CLR_BIT          19
+#define MFTA_TIMER2CAPTA_CLR_BIT        20
+#define MFTA_TIMER2CAPTB_CLR_BIT        21
+
+#define MFTA_TIMER3COMPA_CLR_BIT        24
+#define MFTA_TIMER3COMPB_CLR_BIT        25
+#define MFTA_TIMER3UDF_CLR_BIT          26
+#define MFTA_TIMER3OVF_CLR_BIT          27
+#define MFTA_TIMER3CAPTA_CLR_BIT        28
+#define MFTA_TIMER3CAPTB_CLR_BIT        29
+
+/*
+ * MFTA Timer0 Value Register definition
+ */
+#define MFTA_TIMER0_VALUE_REG           (MFTA_BASE + 0x20)
+#define MFTA_TIMER0_VALUE_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define MFTA_TIMER0_VALUE_RESET_VALUE   0x00000000
+
+/*
+ * MFTA Timer0 CaptureA Register definition
+ */
+#define MFTA_TIMER0_CAPTUREA_REG        (MFTA_BASE + 0x24)
+#define MFTA_TIMER0_CAPTUREA_REG_ACCESS (READ_ACCESS)
+#define MFTA_TIMER0_CAPTUREA_RESET_VALUE 0x00000000
+
+/*
+ * MFTA Timer0 CaptureB Register definition
+ */
+#define MFTA_TIMER0_CAPTUREB_REG        (MFTA_BASE + 0x28)
+#define MFTA_TIMER0_CAPTUREB_REG_ACCESS (READ_ACCESS)
+#define MFTA_TIMER0_CAPTUREB_RESET_VALUE 0x00000000
+
+/*
+ * MFTA Timer0 CompareA Register definition
+ */
+#define MFTA_TIMER0_COMPAREA_REG        (MFTA_BASE + 0x2c)
+#define MFTA_TIMER0_COMPAREA_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define MFTA_TIMER0_COMPAREA_RESET_VALUE 0x00000000
+
+/*
+ * MFTA Timer0 CompareB Register definition
+ */
+#define MFTA_TIMER0_COMPAREB_REG        (MFTA_BASE + 0x30)
+#define MFTA_TIMER0_COMPAREB_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define MFTA_TIMER0_COMPAREB_RESET_VALUE 0x00000000
+
+/*
+ * MFTA Timer1 Value Register definition
+ */
+#define MFTA_TIMER1_VALUE_REG           (MFTA_BASE + 0x40)
+#define MFTA_TIMER1_VALUE_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define MFTA_TIMER1_VALUE_RESET_VALUE   0x00000000
+
+/*
+ * MFTA Timer1 CaptureA Register definition
+ */
+#define MFTA_TIMER1_CAPTUREA_REG        (MFTA_BASE + 0x44)
+#define MFTA_TIMER1_CAPTUREA_REG_ACCESS (READ_ACCESS)
+#define MFTA_TIMER1_CAPTUREA_RESET_VALUE 0x00000000
+
+/*
+ * MFTA Timer1 CaptureB Register definition
+ */
+#define MFTA_TIMER1_CAPTUREB_REG        (MFTA_BASE + 0x48)
+#define MFTA_TIMER1_CAPTUREB_REG_ACCESS (READ_ACCESS)
+#define MFTA_TIMER1_CAPTUREB_RESET_VALUE 0x00000000
+
+/*
+ * MFTA Timer1 CompareA Register definition
+ */
+#define MFTA_TIMER1_COMPAREA_REG        (MFTA_BASE + 0x4c)
+#define MFTA_TIMER1_COMPAREA_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define MFTA_TIMER1_COMPAREA_RESET_VALUE 0x00000000
+
+/*
+ * MFTA Timer1 CompareB Register definition
+ */
+#define MFTA_TIMER1_COMPAREB_REG        (MFTA_BASE + 0x50)
+#define MFTA_TIMER1_COMPAREB_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define MFTA_TIMER1_COMPAREB_RESET_VALUE 0x00000000
+
+/*
+ * MFTA Timer2 Value Register definition
+ */
+#define MFTA_TIMER2_VALUE_REG           (MFTA_BASE + 0x60)
+#define MFTA_TIMER2_VALUE_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define MFTA_TIMER2_VALUE_RESET_VALUE   0x00000000
+
+/*
+ * MFTA Timer2 CaptureA Register definition
+ */
+#define MFTA_TIMER2_CAPTUREA_REG        (MFTA_BASE + 0x64)
+#define MFTA_TIMER2_CAPTUREA_REG_ACCESS (READ_ACCESS)
+#define MFTA_TIMER2_CAPTUREA_RESET_VALUE 0x00000000
+
+/*
+ * MFTA Timer2 CaptureB Register definition
+ */
+#define MFTA_TIMER2_CAPTUREB_REG        (MFTA_BASE + 0x68)
+#define MFTA_TIMER2_CAPTUREB_REG_ACCESS (READ_ACCESS)
+#define MFTA_TIMER2_CAPTUREB_RESET_VALUE 0x00000000
+
+/*
+ * MFTA Timer2 CompareA Register definition
+ */
+#define MFTA_TIMER2_COMPAREA_REG        (MFTA_BASE + 0x6c)
+#define MFTA_TIMER2_COMPAREA_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define MFTA_TIMER2_COMPAREA_RESET_VALUE 0x00000000
+
+/*
+ * MFTA Timer2 CompareB Register definition
+ */
+#define MFTA_TIMER2_COMPAREB_REG        (MFTA_BASE + 0x70)
+#define MFTA_TIMER2_COMPAREB_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define MFTA_TIMER2_COMPAREB_RESET_VALUE 0x00000000
+
+/*
+ * MFTA Timer3 Value Register definition
+ */
+#define MFTA_TIMER3_VALUE_REG           (MFTA_BASE + 0x80)
+#define MFTA_TIMER3_VALUE_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define MFTA_TIMER3_VALUE_RESET_VALUE   0x00000000
+
+/*
+ * MFTA Timer3 CaptureA Register definition
+ */
+#define MFTA_TIMER3_CAPTUREA_REG        (MFTA_BASE + 0x84)
+#define MFTA_TIMER3_CAPTUREA_REG_ACCESS (READ_ACCESS)
+#define MFTA_TIMER3_CAPTUREA_RESET_VALUE 0x00000000
+
+/*
+ * MFTA Timer3 CaptureB Register definition
+ */
+#define MFTA_TIMER3_CAPTUREB_REG        (MFTA_BASE + 0x88)
+#define MFTA_TIMER3_CAPTUREB_REG_ACCESS (READ_ACCESS)
+#define MFTA_TIMER3_CAPTUREB_RESET_VALUE 0x00000000
+
+/*
+ * MFTA Timer3 CompareA Register definition
+ */
+#define MFTA_TIMER3_COMPAREA_REG        (MFTA_BASE + 0x8c)
+#define MFTA_TIMER3_COMPAREA_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define MFTA_TIMER3_COMPAREA_RESET_VALUE 0x00000000
+
+/*
+ * MFTA Timer3 CompareB Register definition
+ */
+#define MFTA_TIMER3_COMPAREB_REG        (MFTA_BASE + 0x90)
+#define MFTA_TIMER3_COMPAREB_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define MFTA_TIMER3_COMPAREB_RESET_VALUE 0x00000000
+
+/*
+ **********************************************************
+ *  CAN Registers Definitions
+ **********************************************************
+ */
+
+/*
+ * CAN Interrupt Status Register Definitions.
+ */
+#define CAN_INTERRUPT_STATUS_REG        (CAN_BASE + 0x00)
+#define CAN_INTERRUPT_STATUS_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_INTERRUPT_STATUS_RESET_VALUE 0x00000000
+
+#define CAN_ARB_LOSS_ISF_BIT            2
+#define CAN_OVR_LOAD_ISF_BIT            3
+#define CAN_BIT_ERR_ISF_BIT             4
+#define CAN_STUFF_ERR_ISF_BIT           5
+#define CAN_ACK_ERR_ISF_BIT             6
+#define CAN_FORM_ERR_ISF_BIT            7
+#define CAN_CRC_ERR_ISF_BIT             8
+#define CAN_BUS_OFF_ISF_BIT             9
+#define CAN_RX_MSG_LOSS_ISF_BIT         10
+#define CAN_TX_MSG_ISF_BIT              11
+#define CAN_RX_MSG_ISF_BIT              12
+
+/*
+ * CAN Interrupt Enable Register Definitions.
+ */
+#define CAN_INTERRUPT_ENABLE_REG        (CAN_BASE + 0x04)
+#define CAN_INTERRUPT_ENABLE_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_INTERRUPT_ENABLE_RESET_VALUE 0x00000000
+
+#define CAN_ARB_LOSS_IEN_BIT            2
+#define CAN_OVR_LOAD_IEN_BIT            3
+#define CAN_BIT_ERR_IEN_BIT             4
+#define CAN_STUFF_ERR_IEN_BIT           5
+#define CAN_ACK_ERR_IEN_BIT             6
+#define CAN_FORM_ERR_IEN_BIT            7
+#define CAN_CRC_ERR_IEN_BIT             8
+#define CAN_BUS_OFF_IEN_BIT             9
+#define CAN_RX_MSG_LOSS_IEN_BIT         10
+#define CAN_TX_MSG_IEN_BIT              11
+#define CAN_RX_MSG_IEN_BIT              12
+
+/*
+ * CAN Buffer Status Register Definitions.
+ */
+#define CAN_BUFFER_STATUS_REG           (CAN_BASE + 0x08)
+#define CAN_BUFFER_STATUS_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define CAN_BUFFER_STATUS_RESET_VALUE   0x00000000
+
+#define CAN_TX_PEND7_MTR_FIELD          16
+#define   NBITS_CAN_TX_PEND7_MTR          8
+
+#define CAN_RX_AV7_MTR_FIELD            0
+#define   NBITS_CAN_RX_AV7_MTR            16
+
+/*
+ * CAN Error Status Register Definitions.
+ */
+#define CAN_ERROR_STATUS_REG            (CAN_BASE + 0x0c)
+#define CAN_ERROR_STATUS_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_ERROR_STATUS_RESET_VALUE    0x00000000
+
+#define CAN_RXGTE96_BIT                 19
+#define CAN_TXGTE96_BIT                 18
+
+#define CAN_ERROR_STAT_FIELD            16
+#define   NBITS_CAN_ERROR_STAT            2
+
+#define CAN_RX_ERR_CNT_FIELD            8
+#define   NBITS_CAN_RX_ERR_CNT            8
+
+#define CAN_TX_ERR_CNT_FIELD            0
+#define   NBITS_CAN_TX_ERR_CNT            8
+
+#define CAN_OPERATING_MODE_REG          (CAN_BASE + 0x10)
+#define CAN_OPERATING_MODE_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_OPERATING_MODE_RESET_VALUE  0x00000000
+
+#define CAN_LO_MODE_SEL_BIT             1
+#define CAN_RUN_STOP_SEL_BIT            0
+
+/*
+ * CAN Configuration Register Definitions.
+ */
+#define CAN_CONFIG_REG                  (CAN_BASE + 0x14)
+#define CAN_CONFIG_REG_ACCESS           (READ_ACCESS | WRITE_ACCESS)
+#define CAN_CONFIG_RESET_VALUE          0x00000000
+
+#define CAN_BITRATE_CFG_FIELD           16
+#define   NBITS_CAN_BITRATE_CFG           15
+
+#define CAN_ARB_CTRL_BIT                12
+
+#define CAN_TSEG1_CTRL_FIELD            8
+#define   NBITS_CAN_TSEG1_CTRL            4
+
+#define CAN_TSEG2_CTRL_FIELD            5
+#define   NBITS_CAN_TSEG2_CTRL            3
+
+#define CAN_ARESTART_BIT                4
+
+#define CAN_SYNC_JMP_WIDTH_FIELD        2
+#define   NBITS_CAN_SYNC_JMP_WIDTH        2
+
+#define CAN_SMODE_SEL_BIT               1
+#define CAN_EMODE_SEL_BIT               0
+
+/*
+ * CAN TX Message Control Register Bit Definitions.
+ * (CAN_TX_MESSAGEx_CTRL)
+ */
+#define CAN_TX_RID_WPN_BIT              23
+#define CAN_TX_RTR_BIT                  21
+#define CAN_TX_IDE_BIT                  20
+
+#define CAN_TX_DLC_FIELD                16
+#define   NBITS_CAN_TX_DLC                4
+
+#define CAN_TX_IEN_WPN_BIT              3
+#define CAN_TX_IE_BIT                   2
+#define CAN_TX_TAR_BIT                  1
+#define CAN_TX_REQ_BIT                  0
+
+/*
+ * CAN TX Message ID Register Bit Definitions.
+ * (CAN_TX_MESSAGEx_ID)
+ */
+#define CAN_TX_MESSAGE_ID_FIELD         3
+#define   NBITS_CAN_TX_MESSAGE_ID         29
+
+/*
+ * CAN RX Message Control Register Bit Definitions.
+ * (CAN_RX_MESSAGEx_CTRL)
+ */
+#define CAN_RX_RID_WPN_BIT              23
+#define CAN_RX_RTR_BIT                  21
+#define CAN_RX_IDE_BIT                  20
+
+#define CAN_RX_DLC_FIELD                16
+#define   NBITS_CAN_RX_DLC                4
+
+#define CAN_RX_LIRB_WPN_BIT             7
+#define CAN_RX_LINKFLAG_BIT             6
+#define CAN_RX_IE_BIT                   5
+#define CAN_RX_RTR_AUTO_BIT             4
+#define CAN_RX_ENABLE_BIT               3
+#define CAN_RX_RAR_BIT                  2
+#define CAN_RX_RTR_PEND_BIT             1
+#define CAN_RX_MSGAV_BIT                0
+
+/*
+ * CAN RX Message ID Register Bit Definitions.
+ * (CAN_RX_MESSAGEx_ID)
+ */
+#define CAN_RX_MESSAGE_ID_FIELD         3
+#define   NBITS_CAN_RX_MESSAGE_ID         29
+
+/*
+ * CAN RX Message Arbitration Acceptance Mask Register Bit Definitions.
+ * (CAN_RX_ARB_AMRx)
+ * and
+ * CAN RX Message Arbitration Acceptance Code Register Bit Definitions.
+ * (CAN_RX_ARB_ACRx)
+ */
+#define CAN_RX_ID_MASK_FIELD            3
+#define   NBITS_CAN_RX_ID_MASK            29
+
+#define CAN_RX_IDE_MASK_BIT             2
+#define CAN_RX_RTR_MASK_BIT             1
+
+/*
+ * CAN RX Message Data Accpetance Mask Register Bit Definitions.
+ * (CAN_RX_DATA_ARMx)
+ * and
+ * CAN RX Message Data Accpetance Code Register Bit Definitions.
+ * (CAN_RX_DATA_ACRx)
+ */
+#define CAN_RX_DATA_MASK_FIELD          0
+#define   NBITS_CAN_RX_DATA_MASK          16
+
+
+/*
+ * CAN TX Message 0
+ */
+#define CAN_TX_MESSAGE0_CTRL_REG        (CAN_BASE + 0x20)
+#define CAN_TX_MESSAGE0_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE0_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_TX_MESSAGE0_ID_REG          (CAN_BASE + 0x24)
+#define CAN_TX_MESSAGE0_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE0_ID_RESET_VALUE  0x00000000
+
+#define CAN_TX_MESSAGE0_DATAH_REG       (CAN_BASE + 0x28)
+#define CAN_TX_MESSAGE0_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE0_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_TX_MESSAGE0_DATAL_REG       (CAN_BASE + 0x2c)
+#define CAN_TX_MESSAGE0_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE0_DATAL_RESET_VALUE 0x00000000
+
+/*
+ * CAN TX Message 1
+ */
+#define CAN_TX_MESSAGE1_CTRL_REG        (CAN_BASE + 0x30)
+#define CAN_TX_MESSAGE1_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE1_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_TX_MESSAGE1_ID_REG          (CAN_BASE + 0x34)
+#define CAN_TX_MESSAGE1_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE1_ID_RESET_VALUE  0x00000000
+
+#define CAN_TX_MESSAGE1_DATAH_REG       (CAN_BASE + 0x38)
+#define CAN_TX_MESSAGE1_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE1_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_TX_MESSAGE1_DATAL_REG       (CAN_BASE + 0x3c)
+#define CAN_TX_MESSAGE1_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE1_DATAL_RESET_VALUE 0x00000000
+
+/*
+ * CAN TX Message 2
+ */
+#define CAN_TX_MESSAGE2_CTRL_REG        (CAN_BASE + 0x40)
+#define CAN_TX_MESSAGE2_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE2_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_TX_MESSAGE2_ID_REG          (CAN_BASE + 0x44)
+#define CAN_TX_MESSAGE2_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE2_ID_RESET_VALUE  0x00000000
+
+#define CAN_TX_MESSAGE2_DATAH_REG       (CAN_BASE + 0x48)
+#define CAN_TX_MESSAGE2_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE2_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_TX_MESSAGE2_DATAL_REG       (CAN_BASE + 0x4c)
+#define CAN_TX_MESSAGE2_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE2_DATAL_RESET_VALUE 0x00000000
+
+/*
+ * CAN TX Message 3
+ */
+#define CAN_TX_MESSAGE3_CTRL_REG        (CAN_BASE + 0x50)
+#define CAN_TX_MESSAGE3_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE3_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_TX_MESSAGE3_ID_REG          (CAN_BASE + 0x54)
+#define CAN_TX_MESSAGE3_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE3_ID_RESET_VALUE  0x00000000
+
+#define CAN_TX_MESSAGE3_DATAH_REG       (CAN_BASE + 0x58)
+#define CAN_TX_MESSAGE3_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE3_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_TX_MESSAGE3_DATAL_REG       (CAN_BASE + 0x5c)
+#define CAN_TX_MESSAGE3_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE3_DATAL_RESET_VALUE 0x00000000
+
+/*
+ * CAN TX Message 4
+ */
+#define CAN_TX_MESSAGE4_CTRL_REG        (CAN_BASE + 0x60)
+#define CAN_TX_MESSAGE4_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE4_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_TX_MESSAGE4_ID_REG          (CAN_BASE + 0x64)
+#define CAN_TX_MESSAGE4_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE4_ID_RESET_VALUE  0x00000000
+
+#define CAN_TX_MESSAGE4_DATAH_REG       (CAN_BASE + 0x68)
+#define CAN_TX_MESSAGE4_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE4_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_TX_MESSAGE4_DATAL_REG       (CAN_BASE + 0x6c)
+#define CAN_TX_MESSAGE4_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE4_DATAL_RESET_VALUE 0x00000000
+
+/*
+ * CAN TX Message 5
+ */
+#define CAN_TX_MESSAGE5_CTRL_REG        (CAN_BASE + 0x70)
+#define CAN_TX_MESSAGE5_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE5_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_TX_MESSAGE5_ID_REG          (CAN_BASE + 0x74)
+#define CAN_TX_MESSAGE5_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE5_ID_RESET_VALUE  0x00000000
+
+#define CAN_TX_MESSAGE5_DATAH_REG       (CAN_BASE + 0x78)
+#define CAN_TX_MESSAGE5_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE5_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_TX_MESSAGE5_DATAL_REG       (CAN_BASE + 0x7c)
+#define CAN_TX_MESSAGE5_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE5_DATAL_RESET_VALUE 0x00000000
+
+/*
+ * CAN TX Message 6
+ */
+#define CAN_TX_MESSAGE6_CTRL_REG        (CAN_BASE + 0x80)
+#define CAN_TX_MESSAGE6_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE6_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_TX_MESSAGE6_ID_REG          (CAN_BASE + 0x84)
+#define CAN_TX_MESSAGE6_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE6_ID_RESET_VALUE  0x00000000
+
+#define CAN_TX_MESSAGE6_DATAH_REG       (CAN_BASE + 0x88)
+#define CAN_TX_MESSAGE6_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE6_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_TX_MESSAGE6_DATAL_REG       (CAN_BASE + 0x8c)
+#define CAN_TX_MESSAGE6_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE6_DATAL_RESET_VALUE 0x00000000
+
+/*
+ * CAN TX Message 7
+ */
+#define CAN_TX_MESSAGE7_CTRL_REG        (CAN_BASE + 0x90)
+#define CAN_TX_MESSAGE7_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE7_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_TX_MESSAGE7_ID_REG          (CAN_BASE + 0x94)
+#define CAN_TX_MESSAGE7_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE7_ID_RESET_VALUE  0x00000000
+
+#define CAN_TX_MESSAGE7_DATAH_REG       (CAN_BASE + 0x98)
+#define CAN_TX_MESSAGE7_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE7_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_TX_MESSAGE7_DATAL_REG       (CAN_BASE + 0x9c)
+#define CAN_TX_MESSAGE7_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_TX_MESSAGE7_DATAL_RESET_VALUE 0x00000000
+
+/*
+ * CAN RX Message 0
+ */
+#define CAN_RX_MESSAGE0_CTRL_REG        (CAN_BASE + 0xa0)
+#define CAN_RX_MESSAGE0_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE0_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE0_ID_REG          (CAN_BASE + 0xa4)
+#define CAN_RX_MESSAGE0_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE0_ID_RESET_VALUE  0x00000000
+
+#define CAN_RX_MESSAGE0_DATAH_REG       (CAN_BASE + 0xa8)
+#define CAN_RX_MESSAGE0_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE0_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE0_DATAL_REG       (CAN_BASE + 0xac)
+#define CAN_RX_MESSAGE0_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE0_DATAL_RESET_VALUE 0x00000000
+
+#define CAN_RX_ARB_AMR0_REG             (CAN_BASE + 0xb0)
+#define CAN_RX_ARB_AMR0_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_AMR0_RESET_VALUE     0x00000000
+
+#define CAN_RX_ARB_ACR0_REG             (CAN_BASE + 0xb4)
+#define CAN_RX_ARB_ACR0_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_ACR0_RESET_VALUE     0x00000000
+
+#define CAN_RX_DATA_AMR0_REG            (CAN_BASE + 0xb8)
+#define CAN_RX_DATA_AMR0_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_AMR0_RESET_VALUE    0x00000000
+
+#define CAN_RX_DATA_ACR0_REG            (CAN_BASE + 0xbc)
+#define CAN_RX_DATA_ACR0_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_ACR0_RESET_VALUE    0x00000000
+
+/*
+ * CAN RX Message 1
+ */
+#define CAN_RX_MESSAGE1_CTRL_REG        (CAN_BASE + 0xc0)
+#define CAN_RX_MESSAGE1_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE1_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE1_ID_REG          (CAN_BASE + 0xc4)
+#define CAN_RX_MESSAGE1_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE1_ID_RESET_VALUE  0x00000000
+
+#define CAN_RX_MESSAGE1_DATAH_REG       (CAN_BASE + 0xc8)
+#define CAN_RX_MESSAGE1_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE1_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE1_DATAL_REG       (CAN_BASE + 0xcc)
+#define CAN_RX_MESSAGE1_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE1_DATAL_RESET_VALUE 0x00000000
+
+#define CAN_RX_ARB_AMR1_REG             (CAN_BASE + 0xd0)
+#define CAN_RX_ARB_AMR1_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_AMR1_RESET_VALUE     0x00000000
+
+#define CAN_RX_ARB_ACR1_REG             (CAN_BASE + 0xd4)
+#define CAN_RX_ARB_ACR1_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_ACR1_RESET_VALUE     0x00000000
+
+#define CAN_RX_DATA_AMR1_REG            (CAN_BASE + 0xd8)
+#define CAN_RX_DATA_AMR1_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_AMR1_RESET_VALUE    0x00000000
+
+#define CAN_RX_DATA_ACR1_REG            (CAN_BASE + 0xdc)
+#define CAN_RX_DATA_ACR1_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_ACR1_RESET_VALUE    0x00000000
+
+/*
+ * CAN RX Message 2
+ */
+#define CAN_RX_MESSAGE2_CTRL_REG        (CAN_BASE + 0xe0)
+#define CAN_RX_MESSAGE2_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE2_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE2_ID_REG          (CAN_BASE + 0xe4)
+#define CAN_RX_MESSAGE2_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE2_ID_RESET_VALUE  0x00000000
+
+#define CAN_RX_MESSAGE2_DATAH_REG       (CAN_BASE + 0xe8)
+#define CAN_RX_MESSAGE2_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE2_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE2_DATAL_REG       (CAN_BASE + 0xec)
+#define CAN_RX_MESSAGE2_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE2_DATAL_RESET_VALUE 0x00000000
+
+#define CAN_RX_ARB_AMR2_REG             (CAN_BASE + 0xf0)
+#define CAN_RX_ARB_AMR2_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_AMR2_RESET_VALUE     0x00000000
+
+#define CAN_RX_ARB_ACR2_REG             (CAN_BASE + 0xf4)
+#define CAN_RX_ARB_ACR2_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_ACR2_RESET_VALUE     0x00000000
+
+#define CAN_RX_DATA_AMR2_REG            (CAN_BASE + 0xf8)
+#define CAN_RX_DATA_AMR2_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_AMR2_RESET_VALUE    0x00000000
+
+#define CAN_RX_DATA_ACR2_REG            (CAN_BASE + 0xfc)
+#define CAN_RX_DATA_ACR2_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_ACR2_RESET_VALUE    0x00000000
+
+/*
+ * CAN RX Message 3
+ */
+#define CAN_RX_MESSAGE3_CTRL_REG        (CAN_BASE + 0x100)
+#define CAN_RX_MESSAGE3_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE3_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE3_ID_REG          (CAN_BASE + 0x104)
+#define CAN_RX_MESSAGE3_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE3_ID_RESET_VALUE  0x00000000
+
+#define CAN_RX_MESSAGE3_DATAH_REG       (CAN_BASE + 0x108)
+#define CAN_RX_MESSAGE3_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE3_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE3_DATAL_REG       (CAN_BASE + 0x10c)
+#define CAN_RX_MESSAGE3_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE3_DATAL_RESET_VALUE 0x00000000
+
+#define CAN_RX_ARB_AMR3_REG             (CAN_BASE + 0x110)
+#define CAN_RX_ARB_AMR3_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_AMR3_RESET_VALUE     0x00000000
+
+#define CAN_RX_ARB_ACR3_REG             (CAN_BASE + 0x114)
+#define CAN_RX_ARB_ACR3_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_ACR3_RESET_VALUE     0x00000000
+
+#define CAN_RX_DATA_AMR3_REG            (CAN_BASE + 0x118)
+#define CAN_RX_DATA_AMR3_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_AMR3_RESET_VALUE    0x00000000
+
+#define CAN_RX_DATA_ACR3_REG            (CAN_BASE + 0x11c)
+#define CAN_RX_DATA_ACR3_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_ACR3_RESET_VALUE    0x00000000
+
+/*
+ * CAN RX Message 4
+ */
+#define CAN_RX_MESSAGE4_CTRL_REG        (CAN_BASE + 0x120)
+#define CAN_RX_MESSAGE4_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE4_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE4_ID_REG          (CAN_BASE + 0x124)
+#define CAN_RX_MESSAGE4_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE4_ID_RESET_VALUE  0x00000000
+
+#define CAN_RX_MESSAGE4_DATAH_REG       (CAN_BASE + 0x128)
+#define CAN_RX_MESSAGE4_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE4_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE4_DATAL_REG       (CAN_BASE + 0x12c)
+#define CAN_RX_MESSAGE4_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE4_DATAL_RESET_VALUE 0x00000000
+
+#define CAN_RX_ARB_AMR4_REG             (CAN_BASE + 0x130)
+#define CAN_RX_ARB_AMR4_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_AMR4_RESET_VALUE     0x00000000
+
+#define CAN_RX_ARB_ACR4_REG             (CAN_BASE + 0x134)
+#define CAN_RX_ARB_ACR4_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_ACR4_RESET_VALUE     0x00000000
+
+#define CAN_RX_DATA_AMR4_REG            (CAN_BASE + 0x138)
+#define CAN_RX_DATA_AMR4_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_AMR4_RESET_VALUE    0x00000000
+
+#define CAN_RX_DATA_ACR4_REG            (CAN_BASE + 0x13c)
+#define CAN_RX_DATA_ACR4_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_ACR4_RESET_VALUE    0x00000000
+
+/*
+ * CAN RX Message 5
+ */
+#define CAN_RX_MESSAGE5_CTRL_REG        (CAN_BASE + 0x140)
+#define CAN_RX_MESSAGE5_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE5_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE5_ID_REG          (CAN_BASE + 0x144)
+#define CAN_RX_MESSAGE5_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE5_ID_RESET_VALUE  0x00000000
+
+#define CAN_RX_MESSAGE5_DATAH_REG       (CAN_BASE + 0x148)
+#define CAN_RX_MESSAGE5_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE5_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE5_DATAL_REG       (CAN_BASE + 0x14c)
+#define CAN_RX_MESSAGE5_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE5_DATAL_RESET_VALUE 0x00000000
+
+#define CAN_RX_ARB_AMR5_REG             (CAN_BASE + 0x150)
+#define CAN_RX_ARB_AMR5_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_AMR5_RESET_VALUE     0x00000000
+
+#define CAN_RX_ARB_ACR5_REG             (CAN_BASE + 0x154)
+#define CAN_RX_ARB_ACR5_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_ACR5_RESET_VALUE     0x00000000
+
+#define CAN_RX_DATA_AMR5_REG            (CAN_BASE + 0x158)
+#define CAN_RX_DATA_AMR5_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_AMR5_RESET_VALUE    0x00000000
+
+#define CAN_RX_DATA_ACR5_REG            (CAN_BASE + 0x15c)
+#define CAN_RX_DATA_ACR5_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_ACR5_RESET_VALUE    0x00000000
+
+/*
+ * CAN RX Message 6
+ */
+#define CAN_RX_MESSAGE6_CTRL_REG        (CAN_BASE + 0x160)
+#define CAN_RX_MESSAGE6_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE6_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE6_ID_REG          (CAN_BASE + 0x164)
+#define CAN_RX_MESSAGE6_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE6_ID_RESET_VALUE  0x00000000
+
+#define CAN_RX_MESSAGE6_DATAH_REG       (CAN_BASE + 0x168)
+#define CAN_RX_MESSAGE6_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE6_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE6_DATAL_REG       (CAN_BASE + 0x16c)
+#define CAN_RX_MESSAGE6_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE6_DATAL_RESET_VALUE 0x00000000
+
+#define CAN_RX_ARB_AMR6_REG             (CAN_BASE + 0x170)
+#define CAN_RX_ARB_AMR6_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_AMR6_RESET_VALUE     0x00000000
+
+#define CAN_RX_ARB_ACR6_REG             (CAN_BASE + 0x174)
+#define CAN_RX_ARB_ACR6_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_ACR6_RESET_VALUE     0x00000000
+
+#define CAN_RX_DATA_AMR6_REG            (CAN_BASE + 0x178)
+#define CAN_RX_DATA_AMR6_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_AMR6_RESET_VALUE    0x00000000
+
+#define CAN_RX_DATA_ACR6_REG            (CAN_BASE + 0x17c)
+#define CAN_RX_DATA_ACR6_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_ACR6_RESET_VALUE    0x00000000
+
+/*
+ * CAN RX Message 7
+ */
+#define CAN_RX_MESSAGE7_CTRL_REG        (CAN_BASE + 0x180)
+#define CAN_RX_MESSAGE7_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE7_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE7_ID_REG          (CAN_BASE + 0x184)
+#define CAN_RX_MESSAGE7_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE7_ID_RESET_VALUE  0x00000000
+
+#define CAN_RX_MESSAGE7_DATAH_REG       (CAN_BASE + 0x188)
+#define CAN_RX_MESSAGE7_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE7_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE7_DATAL_REG       (CAN_BASE + 0x18c)
+#define CAN_RX_MESSAGE7_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE7_DATAL_RESET_VALUE 0x00000000
+
+#define CAN_RX_ARB_AMR7_REG             (CAN_BASE + 0x190)
+#define CAN_RX_ARB_AMR7_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_AMR7_RESET_VALUE     0x00000000
+
+#define CAN_RX_ARB_ACR7_REG             (CAN_BASE + 0x194)
+#define CAN_RX_ARB_ACR7_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_ACR7_RESET_VALUE     0x00000000
+
+#define CAN_RX_DATA_AMR7_REG            (CAN_BASE + 0x198)
+#define CAN_RX_DATA_AMR7_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_AMR7_RESET_VALUE    0x00000000
+
+#define CAN_RX_DATA_ACR7_REG            (CAN_BASE + 0x19c)
+#define CAN_RX_DATA_ACR7_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_ACR7_RESET_VALUE    0x00000000
+
+/*
+ * CAN RX Message 8
+ */
+#define CAN_RX_MESSAGE8_CTRL_REG        (CAN_BASE + 0x1a0)
+#define CAN_RX_MESSAGE8_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE8_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE8_ID_REG          (CAN_BASE + 0x1a4)
+#define CAN_RX_MESSAGE8_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE8_ID_RESET_VALUE  0x00000000
+
+#define CAN_RX_MESSAGE8_DATAH_REG       (CAN_BASE + 0x1a8)
+#define CAN_RX_MESSAGE8_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE8_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE8_DATAL_REG       (CAN_BASE + 0x1ac)
+#define CAN_RX_MESSAGE8_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE8_DATAL_RESET_VALUE 0x00000000
+
+#define CAN_RX_ARB_AMR8_REG             (CAN_BASE + 0x1b0)
+#define CAN_RX_ARB_AMR8_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_AMR8_RESET_VALUE     0x00000000
+
+#define CAN_RX_ARB_ACR8_REG             (CAN_BASE + 0x1b4)
+#define CAN_RX_ARB_ACR8_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_ACR8_RESET_VALUE     0x00000000
+
+#define CAN_RX_DATA_AMR8_REG            (CAN_BASE + 0x1b8)
+#define CAN_RX_DATA_AMR8_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_AMR8_RESET_VALUE    0x00000000
+
+#define CAN_RX_DATA_ACR8_REG            (CAN_BASE + 0x1bc)
+#define CAN_RX_DATA_ACR8_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_ACR8_RESET_VALUE    0x00000000
+
+/*
+ * CAN RX Message 9
+ */
+#define CAN_RX_MESSAGE9_CTRL_REG        (CAN_BASE + 0x1c0)
+#define CAN_RX_MESSAGE9_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE9_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE9_ID_REG          (CAN_BASE + 0x1c4)
+#define CAN_RX_MESSAGE9_ID_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE9_ID_RESET_VALUE  0x00000000
+
+#define CAN_RX_MESSAGE9_DATAH_REG       (CAN_BASE + 0x1c8)
+#define CAN_RX_MESSAGE9_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE9_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE9_DATAL_REG       (CAN_BASE + 0x1cc)
+#define CAN_RX_MESSAGE9_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE9_DATAL_RESET_VALUE 0x00000000
+
+#define CAN_RX_ARB_AMR9_REG             (CAN_BASE + 0x1d0)
+#define CAN_RX_ARB_AMR9_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_AMR9_RESET_VALUE     0x00000000
+
+#define CAN_RX_ARB_ACR9_REG             (CAN_BASE + 0x1d4)
+#define CAN_RX_ARB_ACR9_REG_ACCESS      (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_ACR9_RESET_VALUE     0x00000000
+
+#define CAN_RX_DATA_AMR9_REG            (CAN_BASE + 0x1d8)
+#define CAN_RX_DATA_AMR9_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_AMR9_RESET_VALUE    0x00000000
+
+#define CAN_RX_DATA_ACR9_REG            (CAN_BASE + 0x1dc)
+#define CAN_RX_DATA_ACR9_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_ACR9_RESET_VALUE    0x00000000
+
+/*
+ * CAN RX Message 10
+ */
+#define CAN_RX_MESSAGE10_CTRL_REG       (CAN_BASE + 0x1e0)
+#define CAN_RX_MESSAGE10_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE10_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE10_ID_REG         (CAN_BASE + 0x1e4)
+#define CAN_RX_MESSAGE10_ID_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE10_ID_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE10_DATAH_REG      (CAN_BASE + 0x1e8)
+#define CAN_RX_MESSAGE10_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE10_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE10_DATAL_REG      (CAN_BASE + 0x1ec)
+#define CAN_RX_MESSAGE10_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE10_DATAL_RESET_VALUE 0x00000000
+
+#define CAN_RX_ARB_AMR10_REG            (CAN_BASE + 0x1f0)
+#define CAN_RX_ARB_AMR10_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_AMR10_RESET_VALUE    0x00000000
+
+#define CAN_RX_ARB_ACR10_REG            (CAN_BASE + 0x1f4)
+#define CAN_RX_ARB_ACR10_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_ACR10_RESET_VALUE    0x00000000
+
+#define CAN_RX_DATA_AMR10_REG           (CAN_BASE + 0x1f8)
+#define CAN_RX_DATA_AMR10_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_AMR10_RESET_VALUE   0x00000000
+
+#define CAN_RX_DATA_ACR10_REG           (CAN_BASE + 0x1fc)
+#define CAN_RX_DATA_ACR10_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_ACR10_RESET_VALUE   0x00000000
+
+/*
+ * CAN RX Message 11
+ */
+#define CAN_RX_MESSAGE11_CTRL_REG       (CAN_BASE + 0x200)
+#define CAN_RX_MESSAGE11_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE11_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE11_ID_REG         (CAN_BASE + 0x204)
+#define CAN_RX_MESSAGE11_ID_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE11_ID_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE11_DATAH_REG      (CAN_BASE + 0x208)
+#define CAN_RX_MESSAGE11_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE11_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE11_DATAL_REG      (CAN_BASE + 0x20c)
+#define CAN_RX_MESSAGE11_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE11_DATAL_RESET_VALUE 0x00000000
+
+#define CAN_RX_ARB_AMR11_REG            (CAN_BASE + 0x210)
+#define CAN_RX_ARB_AMR11_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_AMR11_RESET_VALUE    0x00000000
+
+#define CAN_RX_ARB_ACR11_REG            (CAN_BASE + 0x214)
+#define CAN_RX_ARB_ACR11_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_ACR11_RESET_VALUE    0x00000000
+
+#define CAN_RX_DATA_AMR11_REG           (CAN_BASE + 0x218)
+#define CAN_RX_DATA_AMR11_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_AMR11_RESET_VALUE   0x00000000
+
+#define CAN_RX_DATA_ACR11_REG           (CAN_BASE + 0x21c)
+#define CAN_RX_DATA_ACR11_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_ACR11_RESET_VALUE   0x00000000
+
+/*
+ * CAN RX Message 12
+ */
+#define CAN_RX_MESSAGE12_CTRL_REG       (CAN_BASE + 0x220)
+#define CAN_RX_MESSAGE12_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE12_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE12_ID_REG         (CAN_BASE + 0x224)
+#define CAN_RX_MESSAGE12_ID_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE12_ID_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE12_DATAH_REG      (CAN_BASE + 0x228)
+#define CAN_RX_MESSAGE12_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE12_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE12_DATAL_REG      (CAN_BASE + 0x23c)
+#define CAN_RX_MESSAGE12_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE12_DATAL_RESET_VALUE 0x00000000
+
+#define CAN_RX_ARB_AMR12_REG            (CAN_BASE + 0x230)
+#define CAN_RX_ARB_AMR12_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_AMR12_RESET_VALUE    0x00000000
+
+#define CAN_RX_ARB_ACR12_REG            (CAN_BASE + 0x234)
+#define CAN_RX_ARB_ACR12_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_ACR12_RESET_VALUE    0x00000000
+
+#define CAN_RX_DATA_AMR12_REG           (CAN_BASE + 0x238)
+#define CAN_RX_DATA_AMR12_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_AMR12_RESET_VALUE   0x00000000
+
+#define CAN_RX_DATA_ACR12_REG           (CAN_BASE + 0x23c)
+#define CAN_RX_DATA_ACR12_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_ACR12_RESET_VALUE   0x00000000
+
+/*
+ * CAN RX Message 13
+ */
+#define CAN_RX_MESSAGE13_CTRL_REG       (CAN_BASE + 0x240)
+#define CAN_RX_MESSAGE13_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE13_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE13_ID_REG         (CAN_BASE + 0x244)
+#define CAN_RX_MESSAGE13_ID_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE13_ID_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE13_DATAH_REG      (CAN_BASE + 0x248)
+#define CAN_RX_MESSAGE13_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE13_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE13_DATAL_REG      (CAN_BASE + 0x24c)
+#define CAN_RX_MESSAGE13_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE13_DATAL_RESET_VALUE 0x00000000
+
+#define CAN_RX_ARB_AMR13_REG            (CAN_BASE + 0x250)
+#define CAN_RX_ARB_AMR13_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_AMR13_RESET_VALUE    0x00000000
+
+#define CAN_RX_ARB_ACR13_REG            (CAN_BASE + 0x254)
+#define CAN_RX_ARB_ACR13_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_ACR13_RESET_VALUE    0x00000000
+
+#define CAN_RX_DATA_AMR13_REG           (CAN_BASE + 0x258)
+#define CAN_RX_DATA_AMR13_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_AMR13_RESET_VALUE   0x00000000
+
+#define CAN_RX_DATA_ACR13_REG           (CAN_BASE + 0x25c)
+#define CAN_RX_DATA_ACR13_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_ACR13_RESET_VALUE   0x00000000
+
+/*
+ * CAN RX Message 14
+ */
+#define CAN_RX_MESSAGE14_CTRL_REG       (CAN_BASE + 0x260)
+#define CAN_RX_MESSAGE14_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE14_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE14_ID_REG         (CAN_BASE + 0x264)
+#define CAN_RX_MESSAGE14_ID_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE14_ID_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE14_DATAH_REG       (CAN_BASE + 0x268)
+#define CAN_RX_MESSAGE14_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE14_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE14_DATAL_REG      (CAN_BASE + 0x26c)
+#define CAN_RX_MESSAGE14_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE14_DATAL_RESET_VALUE 0x00000000
+
+#define CAN_RX_ARB_AMR14_REG            (CAN_BASE + 0x270)
+#define CAN_RX_ARB_AMR14_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_AMR14_RESET_VALUE    0x00000000
+
+#define CAN_RX_ARB_ACR14_REG            (CAN_BASE + 0x274)
+#define CAN_RX_ARB_ACR14_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_ACR14_RESET_VALUE    0x00000000
+
+#define CAN_RX_DATA_AMR14_REG           (CAN_BASE + 0x278)
+#define CAN_RX_DATA_AMR14_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_AMR14_RESET_VALUE   0x00000000
+
+#define CAN_RX_DATA_ACR14_REG           (CAN_BASE + 0x27c)
+#define CAN_RX_DATA_ACR14_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_ACR14_RESET_VALUE   0x00000000
+
+/*
+ * CAN RX Message 15
+ */
+#define CAN_RX_MESSAGE15_CTRL_REG       (CAN_BASE + 0x280)
+#define CAN_RX_MESSAGE15_CTRL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE15_CTRL_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE15_ID_REG         (CAN_BASE + 0x284)
+#define CAN_RX_MESSAGE15_ID_REG_ACCESS  (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE15_ID_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE15_DATAH_REG      (CAN_BASE + 0x288)
+#define CAN_RX_MESSAGE15_DATAH_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE15_DATAH_RESET_VALUE 0x00000000
+
+#define CAN_RX_MESSAGE15_DATAL_REG      (CAN_BASE + 0x28c)
+#define CAN_RX_MESSAGE15_DATAL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_MESSAGE15_DATAL_RESET_VALUE 0x00000000
+
+#define CAN_RX_ARB_AMR15_REG            (CAN_BASE + 0x290)
+#define CAN_RX_ARB_AMR15_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_AMR15_RESET_VALUE    0x00000000
+
+#define CAN_RX_ARB_ACR15_REG            (CAN_BASE + 0x294)
+#define CAN_RX_ARB_ACR15_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_ARB_ACR15_RESET_VALUE    0x00000000
+
+#define CAN_RX_DATA_AMR15_REG           (CAN_BASE + 0x298)
+#define CAN_RX_DATA_AMR15_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_AMR15_RESET_VALUE   0x00000000
+
+#define CAN_RX_DATA_ACR15_REG           (CAN_BASE + 0x29c)
+#define CAN_RX_DATA_ACR15_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define CAN_RX_DATA_ACR15_RESET_VALUE   0x00000000
+
+/*
+ **********************************************************
+ * ADC Interface Definition
+ **********************************************************
+ */
+/*
+ * ADC Control Register Definitions.
+ */
+#define ADC_CONTROL_REG                 (ADC_BASE + 0x00)
+#define ADC_CONTROL_REG_ACCESS          (READ_ACCESS | WRITE_ACCESS)
+#define ADC_CONTROL_RESET_VALUE         0x00000000
+
+/*
+ * ADC Control Register Bit Definitions.
+ */
+#define ADC_WAIT_FIELD                  24
+#define   NBITS_ADC_WAIT_FIELD            8
+
+#define ADC_WATER_MARK_FIELD            16
+#define   NBITS_ADC_WATER_MARK            5
+
+#define ADC_PRESCALER_FIELD             8
+#define   NBITS_ADC_PRESCALER             5
+
+#define ADC_INT_REF_BIT                 3
+#define ADC_POWER_DOWN_BIT              2
+#define ADC_RESET_BIT                   0
+
+/*
+ * ADC Scan Sequencer Control Register Definitions.
+ */
+#define ADC_SCAN_SEQ_CONTROL_REG        (ADC_BASE + 0x04)
+#define ADC_SCAN_SEQ_CONTROL_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define ADC_SCAN_SEQ_CONTROL_RESET_VALUE 0x00000000
+
+/*
+ * ADC Scan Sequencer Control Register Bit Definitions.
+ */
+#define ADC_SCAN_SEQ_ADDR_PTR_FIELD     8
+#define   NBITS_ADC_SCAN_SEQ_ADDR_PTR     5
+
+#define ADC_SCAN_SEQ_RUN_BIT            1
+#define ADC_SCAN_SEQ_RST_BIT            0
+
+/*
+ * ADC Interrupt Enable Register Definitions.
+ */
+#define ADC_INTERRUPT_ENABLE_REG        (ADC_BASE + 0x10)
+#define ADC_INTERRUPT_ENABLE_REG_ACCESS (READ_ACCESS | WRITE_ACCESS)
+#define ADC_INTERRUPT_ENABLE_RESET_VALUE 0x00000000
+
+/*
+ * ADC Interrupt Enable Register Bit Definitions.
+ */
+#define ADC_SAMPLE_IRQ_IE_BIT           7
+#define ADC_OVERWATER_IE_BIT            6
+#define ADC_OVF_IE_BIT                  5
+#define ADC_UDF_IE_BIT                  4
+#define ADC_FULL_IE_BIT                 3
+#define ADC_NOT_EMPTY_IE_BIT            2
+#define ADC_STOPPED_IE_BIT              1
+#define ADC_CONV_COMP_IE_BIT            0
+
+/*
+ * ADC Interrupt Status Register Definitions.
+ */
+#define ADC_INTERRUPT_STATUS_REG        (ADC_BASE + 0x14)
+#define ADC_INTERRUPT_STATUS_REG_ACCESS (READ_ACCESS)
+#define ADC_INTERRUPT_STATUS_RESET_VALUE 0x00000000
+
+/*
+ * ADC Interrupt Status Register Bit Definitions.
+ */
+#define ADC_SAMPLE_IRQ_ISF_BIT          7
+#define ADC_OVERWATER_ISF_BIT           6
+#define ADC_OVF_ISF_BIT                 5
+#define ADC_UDF_ISF_BIT                 4
+#define ADC_FULL_ISF_BIT                3
+#define ADC_NOT_EMPTY_ISF_BIT           2
+#define ADC_STOPPED_ISF_BIT             1
+#define ADC_CONV_COMP_ISF_BIT           0
+
+/*
+ * ADC Interrupt Clear Register Definitions.
+ */
+#define ADC_INTERRUPT_CLEAR_REG         (ADC_BASE + 0x18)
+#define ADC_INTERRUPT_CLEAR_REG_ACCESS  (WRITE_ACCESS)
+#define ADC_INTERRUPT_CLEAR_RESET_VALUE 0x00000000
+
+#define ADC_SAMPLE_IRQ_CLR_REG          7
+#define ADC_OVERWATER_CRL_REG           6
+#define ADC_OVF_CLR_REG                 5
+#define ADC_UDF_CLR_REG                 4
+#define ADC_FULL_CLR_REG                3
+#define ADC_NOT_EMPTY_CLR_REG           2
+#define ADC_STOPPED_CLR_REG             1
+#define ADC_CONV_COMP_CLR_REG           0
+
+/*
+ * ADC Result FIFO Read Register Definitions.
+ */
+#define ADC_FIFO_READ_REG               (ADC_BASE + 0x20)
+#define ADC_FIFO_READ_REG_ACCESS        (READ_ACCESS)
+#define ADC_FIFO_READ_RESET_VALUE       0x00000000
+
+/*
+ * ADC Result FIFO Read Register Bit Definitions.
+ */
+#define ADC_RESULT_INVALID_BIT          25
+#define ADC_RESULT_SAMPLE_IRQ_BIT       24
+
+#define ADC_RESULT_CH_FIELD             16
+#define   NBITS_ADC_RESULT_CH             4
+
+#define ADC_RESULT_FIELD                0
+#define  NBITS_ADC_RESULT                 10
+
+/*
+ * ADC Result FIFO Status Register Definitions.
+ */
+#define ADC_FIFO_STATUS_REG             (ADC_BASE + 0x24)
+#define ADC_FIFO_STATUS_REG_ACCESS      (READ_ACCESS)
+#define ADC_FIFO_STATUS_RESET_VALUE     0x00000000
+
+/*
+ * ADC Result FIFO Status Register Bit Definitions.
+ */
+#define ADC_RESULT_USED_FIELD           8
+#define   NBITS_ADC_RESULT_USED           7
+
+#define ADC_RESULT_OVERWATER_BIT        6
+#define ADC_RESULT_FULL_BIT             3
+#define ADC_RESULT_EMPTY_BIT            2
+
+/*
+ * ADC Scan Command Register Definitions.
+ */
+#define ADC_CMNDx_RESET_VALUE           0x00000000
+#define ADC_CMNDx_REG_ACCESS            (READ_ACCESS | WRITE_ACCESS)
+
+#define ADC_CMND0_REG                   (ADC_BASE + 0x80)
+#define ADC_CMND1_REG                   (ADC_BASE + 0x84)
+#define ADC_CMND2_REG                   (ADC_BASE + 0x88)
+#define ADC_CMND3_REG                   (ADC_BASE + 0x8c)
+#define ADC_CMND4_REG                   (ADC_BASE + 0x90)
+#define ADC_CMND5_REG                   (ADC_BASE + 0x94)
+#define ADC_CMND6_REG                   (ADC_BASE + 0x98)
+#define ADC_CMND7_REG                   (ADC_BASE + 0x9c)
+#define ADC_CMND8_REG                   (ADC_BASE + 0xa0)
+#define ADC_CMND9_REG                   (ADC_BASE + 0xa4)
+#define ADC_CMND10_REG                  (ADC_BASE + 0xa8)
+#define ADC_CMND11_REG                  (ADC_BASE + 0xac)
+#define ADC_CMND12_REG                  (ADC_BASE + 0xb0)
+#define ADC_CMND13_REG                  (ADC_BASE + 0xb4)
+#define ADC_CMND14_REG                  (ADC_BASE + 0xb8)
+#define ADC_CMND15_REG                  (ADC_BASE + 0xbc)
+#define ADC_CMND16_REG                  (ADC_BASE + 0xc0)
+#define ADC_CMND17_REG                  (ADC_BASE + 0xc4)
+#define ADC_CMND18_REG                  (ADC_BASE + 0xc8)
+#define ADC_CMND19_REG                  (ADC_BASE + 0xcc)
+#define ADC_CMND20_REG                  (ADC_BASE + 0xd0)
+#define ADC_CMND21_REG                  (ADC_BASE + 0xd4)
+#define ADC_CMND22_REG                  (ADC_BASE + 0xd8)
+#define ADC_CMND23_REG                  (ADC_BASE + 0xdc)
+#define ADC_CMND24_REG                  (ADC_BASE + 0xe0)
+#define ADC_CMND25_REG                  (ADC_BASE + 0xe4)
+#define ADC_CMND26_REG                  (ADC_BASE + 0xe8)
+#define ADC_CMND27_REG                  (ADC_BASE + 0xec)
+#define ADC_CMND28_REG                  (ADC_BASE + 0xf0)
+#define ADC_CMND29_REG                  (ADC_BASE + 0xf4)
+#define ADC_CMND30_REG                  (ADC_BASE + 0xf8)
+#define ADC_CMND31_REG                  (ADC_BASE + 0xfc)
+
+/*
+ * ADC Scan Command Register Bit Definitions.
+ */
+#define ADC_SCANSEQ_CMND_FIELD          4
+#define   NBITS_ADC_SCANSEQ_CMND          3
+#define ADC_SCANSEQ_PARAM_FIELD         0
+#define   NBITS_ADC_SCANSEQ_PARAM         4
+
+/*
+ **********************************************************
+ * USB Interface Definition
+ **********************************************************
+ */
+
+/*
+ * USB Function Address Register Definitions.
+ */
+#define USB_FUNCTION_ADDR_REG           (USB_BASE + 0x00)
+#define USB_FUNCTION_ADDR_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define USB_FUNCTION_ADDR_RESET_VALUE   0x00000000
+
+/*
+ * USB Function Address Register Bit Definitions.
+ */
+#define USB_FUNCTION_ADDR_FIELD         0
+#define   NBITS_USB_FUNCTION_ADDR         6
+
+#define USB_FUNCTION_ADDR_UPDATED_BIT   7
+
+/*
+ * USB Power Control Register Definitions.
+ */
+#define USB_POWER_CTRL_REG              (USB_BASE + 0x01)
+#define USB_POWER_CTRL_REG_ACCESS       (READ_ACCESS | WRITE_ACCESS)
+#define USB_POWER_CTRL_RESET_VALUE      0x00000000
+
+/*
+ * USB Power Control Register Bit Definitions.
+ */
+#define USB_SUSPEND_ENA_BIT             0
+#define USB_SUSPEND_MODE_BIT            1
+#define USB_RESUME_BIT                  2
+#define USB_RESET_ACTIVE_BIT            3
+#define USB_ISO_UPDATE_BIT              7
+
+/*
+ * USB Interrupt IN1 Status Register Definitions.
+ */
+#define USB_INT_IN_STATUS_REG           (USB_BASE + 0x02)
+#define USB_INT_IN_STATUS_REG_ACCESS    (READ_ACCESS)
+#define USB_INT_IN_STATUS_RESET_VALUE   0x00000000
+
+/*
+ * USB Interrupt IN1 Status Register Bit Definitions.
+ */
+#define USB_ENDPOINT0_IN_ISF_BIT        0
+#define USB_ENDPOINT1_IN_ISF_BIT        1
+#define USB_ENDPOINT2_IN_ISF_BIT        2
+#define USB_ENDPOINT3_IN_ISF_BIT        3
+#define USB_ENDPOINT4_IN_ISF_BIT        4
+
+/*
+ * USB Interrupt OUT1 Status Register Definitions.
+ */
+#define USB_INT_OUT_STATUS_REG          (USB_BASE + 0x04)
+#define USB_INT_OUT_STATUS_REG_ACCESS   (READ_ACCESS)
+#define USB_INT_OUT_STATUS_RESET_VALUE  0x00000000
+
+/*
+ * USB Interrupt OUT1 Status Register Bit Definitions.
+ */
+#define USB_ENDPOINT1_OUT_ISF_BIT       1
+#define USB_ENDPOINT2_OUT_ISF_BIT       2
+#define USB_ENDPOINT3_OUT_ISF_BIT       3
+#define USB_ENDPOINT4_OUT_ISF_BIT       4
+
+/*
+ * USB Interrupt Status Register Definitions.
+ */
+#define USB_INT_STATUS_REG              (USB_BASE + 0x06)
+#define USB_INT_STATUS_REG_ACCESS       (READ_ACCESS)
+#define USB_INT_STATUS_RESET_VALUE      0x00000000
+
+/*
+ * USB Interrupt Status Register Bit Definitions.
+ */
+#define USB_SUSPEND_ISF_BIT             0
+#define USB_RESUME_ISF_BIT              1
+#define USB_RESET_ISF_BIT               2
+#define USB_SOF_ISF_BIT                 3
+
+/*
+ * USB Interrupt IN1 Enable Register Definitions.
+ */
+#define USB_INT_IN_ENABLE_REG           (USB_BASE + 0x07)
+#define USB_INT_IN_ENABLE_REG_ACCESS    (READ_ACCESS | WRITE_ACCESS)
+#define USB_INT_IN_ENABLE_RESET_VALUE   0x00000000
+
+/*
+ * USB Interrupt IN1 Enable Register Bit Definitions.
+ */
+#define USB_ENDPOINT0_IN_IEN_BIT        0
+#define USB_ENDPOINT1_IN_IEN_BIT        1
+#define USB_ENDPOINT2_IN_IEN_BIT        2
+#define USB_ENDPOINT3_IN_IEN_BIT        3
+#define USB_ENDPOINT4_IN_IEN_BIT        4
+
+/*
+ * USB Interrupt OUT1 Enable Register Definitions.
+ */
+#define USB_INT_OUT_ENABLE_REG          (USB_BASE + 0x09)
+#define USB_INT_OUT_ENABLE_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define USB_INT_OUT_ENABLE_RESET_VALUE  0x00000000
+
+/*
+ * USB Interrupt OUT1 Enable Register Bit Definitions.
+ */
+#define USB_ENDPOINT1_OUT_IEN_BIT       1
+#define USB_ENDPOINT2_OUT_IEN_BIT       2
+#define USB_ENDPOINT3_OUT_IEN_BIT       3
+#define USB_ENDPOINT4_OUT_IEN_BIT       4
+
+/*
+ * USB Interrupt Enable Register Definitions.
+ */
+#define USB_INT_ENABLE_REG              (USB_BASE + 0x0b)
+#define USB_INT_ENABLE_REG_ACCESS       (READ_ACCESS | WRITE_ACCESS)
+#define USB_INT_ENABLE_RESET_VALUE      0x00000000
+
+/*
+ * USB Interrupt Enable Register Bit Definitions.
+ */
+#define USB_SUSPEND_IEN_BIT             0
+#define USB_RESUME_IEN_BIT              1
+#define USB_RESET_IEN_BIT               2
+#define USB_SOF_IEN_BIT                 3
+
+/*
+ * USB Frame Number Register Definitions.
+ */
+#define USB_FRAME_NUM_REG               (USB_BASE + 0x0c)
+#define USB_FRAME_NUM_REG_ACCESS        (READ_ACCESS)
+#define USB_FRAME_NUM_RESET_VALUE       0x00000000
+
+/*
+ * USB Frame Number Register Bit Definitions.
+ */
+#define USB_FRAME_NUM_FIELD             0
+#define   NBITS_USB_FRAME_NUM             11
+
+/*
+ * USB Endpoint Index Register Definitions.
+ */
+#define USB_ENDPOINT_INDEX_REG          (USB_BASE + 0x0e)
+#define USB_ENDPOINT_INDEX_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define USB_ENDPOINT_INDEX_RESET_VALUE  0x00000000
+
+/*
+ * USB Endpoint Index Register Bit Definitions.
+ */
+#define USB_ENDPOINT_INDEX_FIELD        0
+#define   NBITS_USB_ENDPOINT_INDEX        4
+
+/*
+ * USB Max IN Packet Register Definitions.
+ */
+#define USB_IN_MAX_PACKET_REG            (USB_BASE + 0x10)
+#define USB_IN_MAX_PACKET_REG_ACCESS     (READ_ACCESS | WRITE_ACCESS)
+#define USB_IN_MAX_PACKET_RESET_VALUE   0x00000000
+
+/*
+ * USB Max IN Packet Register Bit Definitions.
+ */
+#define USB_IN_MAX_PACKET_FIELD         0
+#define   NBITS_USB_IN_MAX_PACKET         8
+
+/*
+ * USB CSR0 Register Definitions.
+ */
+#define USB_CSR0_REG                    (USB_BASE + 0x11)
+#define USB_CSR0_REG_ACCESS             (READ_ACCESS | WRITE_ACCESS)
+#define USB_CSR0_RESET_VALUE            0x00000000
+
+/*
+ * USB CSR0 Register Bit Definitions.
+ */
+#define USB_CSR0_OUT_PKT_RDY_BIT        0
+#define USB_CSR0_IN_PKT_RDY_BIT         1
+#define USB_CSR0_STALL_SENT_BIT         2
+#define USB_CSR0_LAST_PKT_BIT           3
+#define USB_CSR0_SETUP_END_BIT          4
+#define USB_CSR0_STALL_BIT              5
+#define USB_CSR0_OUT_PKT_RDY_CLR_BIT    6
+#define USB_CSR0_SETUP_END_CLR_BIT      7
+
+/*
+ * USB IN CSR1 Register Definitions.
+ */
+#define USB_INCSR1_REG                  (USB_BASE + 0x11)
+#define USB_INCSR1_REG_ACCESS           (READ_ACCESS | WRITE_ACCESS)
+#define USB_INCSR1_RESET_VALUE          0x00000000
+
+/*
+ * USB IN CSR1 Register Bit Definitions.
+ */
+#define USB_INCSR1_IN_PKT_RDY_BIT       0
+#define USB_INCSR1_FIFO_NOT_EMPTY_BIT   1
+#define USB_INCSR1_UNDERRUN_BIT         2
+#define USB_INCSR1_FIFO_FLUSH_BIT       3
+#define USB_INCSR1_STALL_BIT            4
+#define USB_INCSR1_STALL_SENT_BIT       5
+#define USB_INCSR1_CLR_DATA_TOG_BIT     6
+
+/*
+ * USB IN CSR2 Register Definitions.
+ */
+#define USB_INCSR2_REG                  (USB_BASE + 0x12)
+#define USB_INCSR2_REG_ACCESS           (READ_ACCESS | WRITE_ACCESS)
+#define USB_INCSR2_RESET_VALUE          0x00000000
+
+/*
+ * USB IN CSR2 Register Bit Definitions.
+ */
+#define USB_INCSR2_DATA_TOG_FORCE_BIT   3
+#define USB_INCSR2_DMA_ENA_BIT          4
+#define USB_INCSR2_MODE_BIT             5
+#define USB_INCSR2_ISO_BIT              6
+#define USB_INCSR2_AUTO_SET_BIT         7
+
+/*
+ * USB Max OUT Packet Register Definitions.
+ */
+#define USB_OUT_MAX_PACKET_REG          (USB_BASE + 0x13)
+#define USB_OUT_MAX_PACKET_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define USB_OUT_MAX_PACKET_RESET_VALUE  0x00000000
+
+/*
+ * USB Max OUT Packet Register Bit Definitions.
+ */
+#define USB_OUT_MAX_PACKET_FIELD        0
+#define   NBITS_USB_OUT_MAX_PACKET        8
+
+/*
+ * USB OUT CSR1 Register Definitions.
+ */
+#define USB_OUTCSR1_REG                 (USB_BASE + 0x14)
+#define USB_OUTCSR1_REG_ACCESS          (READ_ACCESS | WRITE_ACCESS)
+#define USB_OUTCSR1_REG_RESET_VALUE     0x00000000
+
+/*
+ * USB OUT CSR1 Register Bit Definitions.
+ */
+#define USB_OUTCSR1_OUT_PKT_RDY_BIT     0
+#define USB_OUTCSR1_FIFO_FULL_BIT       1
+#define USB_OUTCSR1_OVERRUN_BIT         2
+#define USB_OUTCSR1_DATA_ERR_BIT        3
+#define USB_OUTCSR1_FIFO_FLUSH_BIT      4
+#define USB_OUTCSR1_STALL_BIT           5
+#define USB_OUTCSR1_STALL_SENT_BIT      6
+#define USB_OUTCSR1_CLR_DATA_TOG_BIT    7
+
+/*
+ * USB OUT CSR2 Register Definitions.
+ */
+#define USB_OUTCSR2_REG                 (USB_BASE + 0x15)
+#define USB_OUTCSR2_REG_ACCESS          (READ_ACCESS | WRITE_ACCESS)
+#define USB_OUTCSR2_REG_RESET_VALUE     0x00000000
+
+/*
+ * USB OUT CSR2 Register Bit Definitions.
+ */
+#define USB_OUTCSR2_DMA_MODE_BIT        4
+#define USB_OUTCSR2_DMA_ENABLE_BIT      5
+#define USB_OUTCSR2_ISO_BIT             6
+#define USB_OUTCSR2_AUTO_CLEAR_BIT      7
+
+/*
+ * USB Endpoint 0 Count Register Definitions.
+ */
+#define USB_ENDPOINT0_COUNT_REG         (USB_BASE + 0x16)
+#define USB_ENDPOINT0_COUNT_REG_ACCESS  (READ_ACCESS)
+#define USB_ENDPOINT0_COUNT_RESET_VALUE 0x00000000
+
+/*
+ * USB Endpoint 0 Count Register Bit Definitions.
+ */
+#define USB_ENDPOINT0_COUNT_FIELD       0
+#define   NBITS_USB_ENDPOINT0_COUNT       7
+
+/*
+ * USB OUT Count Register Definitions.
+ */
+#define USB_OUT_COUNT_REG               (USB_BASE + 0x16)
+#define USB_OUT_COUNT_REG_ACCESS        (READ_ACCESS)
+#define USB_OUT_COUNT_RESET_VALUE       0x00000000
+
+/*
+ * USB OUT Count Register Bit Definitions.
+ */
+#define USB_OUT_COUNT_FIELD             0
+#define   NBITS_USB_OUT_COUNT             11
+
+/*
+ * USB Endpoint 0 FIFO Register Definitions.
+ */
+#define USB_ENDPOINT0_FIFO_REG          (USB_BASE + 0x20)
+#define USB_ENDPOINT0_FIFO_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define USB_ENDPOINT0_FIFO_RESET_VALUE  0x00000000
+
+/*
+ * USB Endpoint 1 FIFO Register Definitions.
+ */
+#define USB_ENDPOINT1_FIFO_REG          (USB_BASE + 0x21)
+#define USB_ENDPOINT1_FIFO_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define USB_ENDPOINT1_FIFO_RESET_VALUE  0x00000000
+
+/*
+ * USB Endpoint 2 FIFO Register Definitions.
+ */
+#define USB_ENDPOINT2_FIFO_REG          (USB_BASE + 0x22)
+#define USB_ENDPOINT2_FIFO_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define USB_ENDPOINT2_FIFO_RESET_VALUE  0x00000000
+
+/*
+ * USB Endpoint 3 FIFO Register Definitions.
+ */
+#define USB_ENDPOINT3_FIFO_REG          (USB_BASE + 0x23)
+#define USB_ENDPOINT3_FIFO_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define USB_ENDPOINT3_FIFO_RESET_VALUE  0x00000000
+
+/*
+ * USB Endpoint 4 FIFO Register Definitions.
+ */
+#define USB_ENDPOINT4_FIFO_REG          (USB_BASE + 0x24)
+#define USB_ENDPOINT4_FIFO_REG_ACCESS   (READ_ACCESS | WRITE_ACCESS)
+#define USB_ENDPOINT4_FIFO_RESET_VALUE  0x00000000
+
+/*
+ **********************************************************
+ * JTAG Interface Definition
+ **********************************************************
+ */
+#define JTAG_A7Vx05  0x08c9d2ffUL
+
+
+/*
+ * Triscend A7V JTAG Instructions
+ */
+#define JTAG_EXTEST          0x00
+#define JTAG_SCAN_N          0x02
+#define JTAG_INTEST          0x0c
+#define JTAG_IDCODE          0x0e
+#define JTAG_BYPASS          0x0f
+#define JTAG_CLAMP           0x05
+#define JTAG_HIGHZ           0x07
+#define JTAG_CLAMPZ          0x09
+#define JTAG_SAMPLE_PRELOAD  0x03
+#define JTAG_RESTART         0x04
+#define JTAG_NONE            0xff
+
+
+/*
+ * Triscend A7V JTAG Scan Chains
+ *     The DEBUG chain is scanned with the msb first.
+ *     All other chains are scanned with the lsb first.
+ */
+#define SCAN_TEST_CHAIN        0
+#define DEBUG_CHAIN            1
+#define ICEBREAKER_CHAIN       2
+#define BOUNDARY_SCAN_CHAIN    3        // for Triscend internal use only
+#define INTERNAL_SCAN_CHAIN    5        // for Triscend internal use only
+#define BUSTAT_CHAIN           6
+#define BUSCON_CHAIN           7
+#define MEMORY_RW_CHAIN        9
+#define MEMORY_RW_INCR_CHAIN  10
+#define MEMORY_FILL_CHAIN     11
+#define CRC_CHANNEL_CHAIN     12
+
+/*
+ * Bitlengths of Triscend A7V JTAG registers/chains
+ */
+#define BITLEN_SCAN_N_REG             4
+#define BITLEN_IDENTIFICATION_REG    32
+#define BITLEN_BYPASS_REG             1
+#define BITLEN_INSTRUCTION_REG        4
+#define BITLEN_DEBUG_CHAIN           33
+#define BITLEN_ICEBREAKER_CHAIN      38
+#define BITLEN_BUSTAT_CHAIN          20
+#define BITLEN_BUSCON_CHAIN          12
+#define BITLEN_MEMORY_RW_CHAIN       68
+#define BITLEN_MEMORY_RW_INCR_CHAIN  34
+#define BITLEN_MEMORY_FILL_CHAIN     97
+#define BITLEN_CRC_CHANNEL_CHAIN     32
+
+
+/*
+ * Buscon chain bit defintion
+ */
+#define BUSCON_CPU_RESET_BIT         0
+#define BUSCON_CPU_FREEZE_BIT        1
+#define BUSCON_CPU_INT_BIT           2
+#define BUSCON_FORCE_CFGRST_BIT      3
+#define BUSCON_FORCE_NOCFGRST_BIT    4
+#define BUSCON_OSC_BREAK_BIT         5
+#define BUSCON_FORCE_BRST_BIT        6
+#define BUSCON_FORCE_NOBRST_BIT      7
+#define BUSCON_JTAG_BP_EVT_BIT       8
+#define BUSCON_A7S_TAP_RESET_BIT     9
+#define BUSCON_A7S_TAP_DISABLE_BIT  10
+
+/*
+ * BUSTAT chain bit definition
+ */
+#define BUSTAT_CPU_EXECUTING_BIT     0
+#define BUSTAT_DBG_ACK_BIT           1
+#define BUSTAT_BP_EVT_BIT            2
+#define BUSTAT_CPU_IN_RESET_BIT      3
+#define BUSTAT_BRST_STATUS_BIT       4
+#define BUSTAT_BCLK_STATUS_BIT       5
+#define BUSTAT_CFGRST_STATUS_BIT     6
+#define BUSTAT_END_OF_TRACE_BIT      7
+#define BUSTAT_CPU_RESET_BIT         8
+#define BUSTAT_CPU_FREEZE_BIT        9
+#define BUSTAT_CPU_INT_BIT          10
+#define BUSTAT_FORCE_CFGRST_BIT     11
+#define BUSTAT_FORCE_NOCFGRST_BIT   12
+#define BUSTAT_OSC_BREAK_BIT        13
+#define BUSTAT_FORCE_BRST_BIT       14
+#define BUSTAT_FORCE_NOBRST_BIT     15
+#define BUSTAT_JTAG_BP_EVT_BIT      16
+#define BUSTAT_A7S_TAP_RESET_BIT    17
+#define BUSTAT_A7S_TAP_DISABLE_BIT  18
+
+
+#endif /* _TRISCEND_A7V_H */
+
+/* end triscend_a7v.h */
diff -urN linux-2.4.29/include/asm-armnommu/arch-ta7s/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-ta7s/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-ta7s/vmalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ *  linux/include/asm-armnommu/arch-ta7s/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *  09 Apr 2003 - Craig Hackney
+ *    - Just copied in for Triscend-A7S
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifdef _ASM_ARCH_VMALLOC_H
+#define _ASM_ARCH_VMALLOC_H
+
+
+
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/a.out.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/a.out.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/a.out.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * uclinux/include/asm-armnommu/arch-c5471/a.out.h
+ *
+ */
+#ifndef __ASM_ARCH_A_OUT_H
+#define __ASM_ARCH_A_OUT_H
+
+#ifdef __KERNEL__
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/dma.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/dma.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,62 @@
+/***********************************************************************
+ * asm/arch-armnommu/arch-c5471/dma.h:
+ *
+ *   Copyright (C) 2003 Cadenux, LLC. All rights reserved.
+ *   todd.fischer@cadenux.com  <www.cadenux.com>
+ *
+ *   Copyright (C) 2001 RidgeRun, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#include "linux/autoconf.h"
+
+/* type dmamode_t is declared in include/asm-armnommu along with values.
+ * Some additional DMA mode values are declared here.
+ */
+
+#define DMA_MODE_CARD_TO_SDRAM  0x08
+#define DMA_MODE_SDRAM_TO_CARD  0x0c
+#define DMA_MODE_FLASH_TO_SDRAM 0x10
+#define DMA_MODE_SDRAM_TO_FLASH 0x14
+
+/* MAX_DMA_ADDRESS -- max address we can program into the DMA address
+ * registers? Not sure. Various drivers use this value as a test before
+ * setting up a DMA. Also, the macros in linux/bootmem.h use this value
+ * as a goal for many of the bootmem allocations.
+ */
+
+/* Configured memory is specified during configuration. */
+
+#define MAX_DMA_ADDRESS (DRAM_BASE + DRAM_SIZE - 1)
+
+/* MAX_DMA_CHANNELS -- # of DMA control register sets we possess.
+ * We have one that can run in either direction and between two different
+ * destinations.
+ */
+
+#define MAX_DMA_CHANNELS 1
+
+#endif /* __ASM_ARCH_DMA_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/gio_ioctl.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/gio_ioctl.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/gio_ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/gio_ioctl.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,90 @@
+/************************************************************************
+ * include/asm-armnommu/arch-c5471/gio_ioctl.h
+ *
+ * Definitions of the General Purpose I/O (GIO) for the C5471.
+ *
+ *   Copyright (C) 2003 Cadenux, LLC. All rights reserved.
+ *   todd.fischer@cadenux.com  <www.cadenux.com>
+ *
+ *   Copyright (C) 2001 RidgeRun, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ************************************************************************/
+
+#ifndef __ASM_ARCH_GIO_IOCTL_H
+#define __ASM_ARCH_GIO_IOCTL_H
+ 
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <asm/ioctl.h>
+ 
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+#define GIO_MAGIC_NUMBER 'g'
+
+/* Major numbers, (from Documentation/devices.txt local/experimental list)  */
+ 
+#define GIO_MAJOR     125
+ 
+/************************************************************************
+ * GIO_DIRECTION: The GIO_DIRECTION can be either input (GIO_INPUT) or
+ * output (GIO_OUTPUT).  If unspecified, the GIO will default to input.
+ */
+
+#define GIO_OUTPUT 0
+#define GIO_INPUT 1
+
+#define GIO_DIRECTION _IO(GIO_MAGIC_NUMBER, 0)
+ 
+/************************************************************************
+ * GIO_BITSET: If the direction is set to output, this ioctl will set the
+ * output.  If the direction is input, this ioctl will return the value
+ * of the GIO pin (0, 1, or -1 on error).
+ */
+
+#define GIO_BITSET _IO(GIO_MAGIC_NUMBER, 1)
+
+/************************************************************************
+ * GIO_BITCLR: If the direction is set to output, this ioctl will clear the
+ * output.  If the direction is input, this ioctl will return the value
+ * of the GIO pin (0, 1, or -1 on error).
+ */
+
+#define GIO_BITCLR _IO(GIO_MAGIC_NUMBER, 2)
+
+/************************************************************************
+ * GIO_IRQPORT: Configure a GIO as an interrupt.  Only GIO0-GIO3 can
+ * be configured as an interrupting source.
+ */
+
+#define GIO_NOINTERRUPT 0
+#define GIO_INTERRUPT 1
+
+#define GIO_IRQPORT _IO(GIO_MAGIC_NUMBER, 3)
+
+#define GIO_IOC_MAXNR 3
+ 
+#endif /* __ASM_ARCH_GIO_IOCTL_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/hardware.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/hardware.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,288 @@
+/***********************************************************************
+ * linux/include/asm-armnommu/arch-c5471/hardware.h
+ *
+ *   Copyright (C) 2003 Cadenux, LLC. All rights reserved.
+ *   todd.fischer@cadenux.com  <www.cadenux.com>
+ *
+ *   Copyright (C) 2001 RidgeRun, Inc. All rights reserved.
+ *         
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <linux/autoconf.h>
+
+
+/* Memory Map *************************************************************/
+
+/* SDRAM start/size and FLASH start/size are defined using the kernel
+   configuration tool
+*/
+
+#define C5471_IRAM_START 0xffc00000
+#define C5471_IRAM_SIZE  0x00004000
+
+/* UARTs ******************************************************************/
+
+/* HARD_RESET_N0W: This is used in drivers/block/block.c.
+ */
+
+#define HARD_RESET_NOW()
+
+/* UARTs ******************************************************************/
+
+#define UART_IRDA_BASE         0xffff0800
+#define UART_MODEM_BASE        0xffff1000
+#define UARTn_IO_RANGE         0x00000800
+
+/* Common UART Registers.  Expressed as offsets from the BASE address */
+
+#define UART_RHR_OFFS          0x00000000 /* Rcv Holding Register */
+#define UART_THR_OFFS          0x00000004 /* Xmit Holding Register */
+#define UART_FCR_OFFS          0x00000008 /* FIFO Control Register */
+#define UART_RFCR_OFFS         0x00000008 /* Rcv FIFO Control Register */
+#define UART_TFCR_OFFS         0x00000008 /* Xmit FIFO Control Register */
+#define UART_SCR_OFFS          0x0000000c /* Status Control Register */
+#define UART_LCR_OFFS          0x00000010 /* Line Control Register */
+#define UART_LSR_OFFS          0x00000014 /* Line Status Register */
+#define UART_SSR_OFFS          0x00000018 /* Supplementary Status Register */
+#define UART_MCR_OFFS          0x0000001c /* Modem Control Register */
+#define UART_MSR_OFFS          0x00000020 /* Modem Status Register */
+#define UART_IER_OFFS          0x00000024 /* Interrupt Enable Register */
+#define UART_ISR_OFFS          0x00000028 /* Interrupt Status Register */
+#define UART_EFR_OFFS          0x0000002c /* Enhanced Feature Register */
+#define UART_XON1_OFFS         0x00000030 /* XON1 Character Register */
+#define UART_XON2_OFFS         0x00000034 /* XON2 Character Register */
+#define UART_XOFF1_OFFS        0x00000038 /* XOFF1 Character Register */
+#define UART_XOFF2_OFFS        0x0000003c /* XOFF2 Character Register */
+#define UART_SPR_OFFS          0x00000040 /* Scratch-pad Register */
+#define UART_DIV_115K_OFFS     0x00000044 /* Divisor for baud generation */
+#define UART_DIV_BIT_RATE_OFFS 0x00000048 /* For baud rate generation */
+#define UART_TCR_OFFS          0x0000004c /* Transmission Control Register */
+#define UART_TLR_OFFS          0x00000050 /* Trigger Level Register */
+#define UART_MDR_OFFS          0x00000054 /* Mode Definition Register */
+
+/* Registers available only for the IrDA UART (absolute address). */
+
+#define UART_IRDA_MDR1         0xffff0854 /* Mode Definition Register 1 */
+#define UART_IRDA_MDR2         0xffff0858 /* Mode Definition Register 2 */
+#define UART_IRDA_TXFLL        0xffff085c /* LS Xmit Frame Length Register */
+#define UART_IRDA_TXFLH        0xffff0860 /* MS Xmit Frame Length Register */
+#define UART_IRDA_RXFLL        0xffff0864 /* LS Rcvd Frame Length Register */
+#define UART_IRDA_RXFLH        0xffff0868 /* MS Rcvd Frame Length Register */
+#define UART_IRDA_SFLSR        0xffff086c /* Status FIFO Line Status Reg */
+#define UART_IRDA_SFREGL       0xffff0870 /* LS Status FIFO Register */
+#define UART_IRDA_SFREGH       0xffff0874 /* MS Status FIFO Register */
+#define UART_IRDA_BLR          0xffff0878 /* Begin of File Length Register */
+#define UART_IRDA_PULSE_WIDTH  0xffff087c /* Pulse Width Register */
+#define UART_IRDA_ACREG        0xffff0880 /* Auxiliary Control Register */
+#define UART_IRDA_PULSE_START  0xffff0884 /* Start time of pulse */
+#define UART_IRDA_RX_W_PTR     0xffff0888 /* RX FIFO write pointer */
+#define UART_IRDA_RX_R_PTR     0xffff088c /* RX FIFO read pointer */
+#define UART_IRDA_TX_W_PTR     0xffff0890 /* TX FIFO write pointer */
+#define UART_IRDA_TX_R_PTR     0xffff0894 /* TX FIFO read pointer */
+#define UART_IRDA_STATUS_W_PTR 0xffff0898 /* Write pointer of status FIFO */
+#define UART_IRDA_STATUS_R_PTR 0xffff089c /* Read pointer of status FIFO */
+#define UART_IRDA_RESUME       0xffff08a0 /* Resume register */
+#define UART_IRDA_MUX          0xffff08a4 /* Selects UART_IRDA output mux */
+
+/* Registers available for the Modem UART (absolute addresses) */
+
+#define UART_MODEM_SER_RHR     0xffff1000 /* RX Hold Register */
+#define UART_MODEM_SER_THR     0xffff1004 /* TX Hold Register */
+#define UART_MODEM_FCR         0xffff1008 /* FIFO Control Register */
+#define UART_MODEM_SER_LCR     0xffff1010 /* Line Control Register */
+#define UART_MODEM_SER_SR      0xffff1014 /* Line Status Register */
+#define UART_MODEM_115K_DIV    0xffff1044 /* ARM clock to 115K divisor Reg */
+#define UART_MODEM_DIV         0xffff1048 /* Baud Rate Divisor Register */
+#define UART_MODEM_MDR         0xffff1054 /* Mode Definition Register */
+#define UART_MODEM_UASR        0xffff1058 /* UART Auto-baud Status Register */
+#define UART_MODEM_RDPTR_URX   0xffff105c /* RX FIFO Read Pointer Register */
+#define UART_MODEM_WRPTR_URX   0xffff1060 /* RX FIFO Write Pointer Register */
+#define UART_MODEM_RDPTR_UTX   0xffff1064 /* TX FIFO Read Pointer Register */
+#define UART_MODEM_WRPTR_UTX   0xffff1068 /* TX FIFO Write Pointer Register */
+
+/* UART Settings **********************************************************/
+
+/* Miscellaneous UART settings. */
+
+#define UART_RX_FIFO_NOEMPTY 0x00000001
+#define UART_SSR_TXFULL      0x00000001
+#define UART_LSR_TREF        0x00000020
+
+#define UART_XMIT_FIFO_SIZE      64
+#define UART_IRDA_XMIT_FIFO_SIZE 64
+
+/* UART_LCR Register */
+                                        /* Bits 31-7: Reserved */
+#define UART_LCR_BOC         0x00000040 /* Bit 6: Break Control */
+                                        /* Bit 5: Parity Type 2 */
+#define UART_LCR_ParEven     0x00000010 /* Bit 4: Parity Type 1 */
+#define UART_LCR_ParOdd      0x00000000
+#define UART_LCR_ParEn       0x00000008 /* Bit 3: Paity Enable */
+#define UART_LCR_ParDis      0x00000000
+#define UART_LCR_2stop       0x00000004 /* Bit 2: Number of stop bits */
+#define UART_LCR_1stop       0x00000000
+#define UART_LCR_5bits       0x00000000 /* Bits 0-1: Word-length */
+#define UART_LCR_6bits       0x00000001
+#define UART_LCR_7bits       0x00000002
+#define UART_LCR_8bits       0x00000003
+
+#define UART_FCR_FTL         0x00000000
+#define UART_FCR_FIFO_EN     0x00000001
+#define UART_FCR_TX_CLR      0x00000002
+#define UART_FCR_RX_CLR      0x00000004
+
+#define UART_IER_RecvInt     0x00000001
+#define UART_IER_XmitInt     0x00000002
+#define UART_IER_LineStsInt  0x00000004
+#define UART_IER_ModemStsInt 0x00000008 /* IrDA UART only */
+#define UART_IER_XoffInt     0x00000020
+#define UART_IER_RtsInt      0x00000040 /* IrDA UART only */
+#define UART_IER_CtsInt      0x00000080 /* IrDA UART only */
+#define UART_IER_AllInts     0x000000ff
+
+#define BAUD_115200_47_5MHZ  0x0000019C
+#define BAUD_115200_50MHZ  	 0x000001B2
+
+#define BAUD_115200          0x00000001
+#define BAUD_57600           0x00000002
+#define BAUD_38400           0x00000003
+#define BAUD_19200           0x00000006
+#define BAUD_9600            0x0000000C
+#define BAUD_4800            0x00000018
+#define BAUD_2400            0x00000030
+#define BAUD_1200            0x00000060
+
+#define MDR_UART_MODE        0x00000000  /* Both IrDA and Modem UARTs */
+#define MDR_SIR_MODE         0x00000001  /* IrDA UART only */
+#define MDR_AUTOBAUDING_MODE 0x00000002  /* Modem UART only */
+#define MDR_RESET_MODE       0x00000007  /* Both IrDA and Modem UARTs */
+
+/* SPI ********************************************************************/
+
+#define MAX_SPI 3
+
+#define SPI_REGISTER_BASE    0xffff2000
+
+/* GIO ********************************************************************/
+
+#define MAX_GIO (35)
+
+#define GIO_REGISTER_BASE    0xffff2800
+
+#define GPIO_IO              0xffff2800 /* Writeable when I/O is configured
+					 * as an output; reads value on I/O
+					 * pin when I/O is configured as an
+					 * input */
+#define GPIO_CIO             0xffff2804 /* GPIO configuration register */
+#define GPIO_IRQA            0xffff2808 /* In conjunction with GPIO_IRQB
+					 * determines the behavior when GPIO
+					 * pins configured as input IRQ */
+#define GPIO_IRQB            0xffff280c /* Determines the behavior when GPIO
+					 * pins configured as input IRQ */
+#define GPIO_DDIO            0xffff2810 /* Delta Detect Register
+					 * (detects changes in the I/O pins) */
+#define GPIO_EN              0xffff2814 /* Selects register for muxed GPIOs */
+
+#define KGIO_REGISTER_BASE   0xffff2900
+
+#define KBGPIO_IO            0xffff2900 /* Keyboard I/O bits: Writeable
+					 * when KBGPIO is configured as an
+					 * output; reads value on I/O pin
+					 * when KBGPIO is configured as an
+					 * input */
+#define KBGPIO_CIO           0xffff2904 /* KBGPIO configuration register */
+#define KBGPIO_IRQA          0xffff2908 /* In conjunction with KBGPIO_IRQB
+					 * determines the behavior when
+					 * KBGPIO pins configured as input
+					 * IRQ */
+#define KBGPIO_IRQB          0xffff290c /* In conjunction with KBGPIO_IRQA
+					 * determines the behavior when
+					 * KBGPIO pins configured as input
+					 * IRQ */
+#define KBGPIO_DDIO          0xffff2910 /* Delta Detect Register (detects
+					 * changes in the KBGPIO pins) */
+#define KBGPIO_EN            0xffff2914 /* Selects register for muxed
+					 * KBGPIOs */
+
+/* Timers *****************************************************************/
+
+#define C5471_TIMER0_CTRL    0xffff2a00
+#define C5471_TIMER0_CNT     0xffff2a04
+#define C5471_TIMER1_CTRL    0xffff2b00
+#define C5471_TIMER1_CNT     0xffff2b04
+#define C5471_TIMER2_CTRL    0xffff2c00
+
+#define C5471_TIMER2_CNT     0xffff2c04
+
+/* Interrupts
+ *
+ * NOTE:  The 2.0.x implementation uses SRC_IRQ_BIN_REG to decode
+ * interrupts (see entry-armv.S).  However, this register is
+ * not documented int the TMS320VC5472 User Guide???
+ * The switch, HAVE_SRC_IRQ_BIN_REG will enable use of this
+ * register.
+ */
+
+#define HAVE_SRC_IRQ_BIN_REG 0
+
+#define INT_FIRST_IO         0xffff2d00
+#define INT_IO_RANGE         0x5C
+
+#define IT_REG               0xffff2d00
+#define MASK_IT_REG          0xffff2d04
+#define SRC_IRQ_REG          0xffff2d08
+#define SRC_FIQ_REG          0xffff2d0c
+#define SRC_IRQ_BIN_REG      0xffff2d10
+#define INT_CTRL_REG         0xffff2d18
+
+#define ILR_IRQ0_REG         0xffff2d1C /*  0-Timer 0       */
+#define ILR_IRQ1_REG         0xffff2d20 /*  1-Timer 1       */
+#define ILR_IRQ2_REG         0xffff2d24 /*  2-Timer 2       */
+#define ILR_IRQ3_REG         0xffff2d28 /*  3-GPIO0         */
+#define ILR_IRQ4_REG         0xffff2d2c /*  4-Ethernet      */
+#define ILR_IRQ5_REG         0xffff2d30 /*  5-KBGPIO[7:0]   */
+#define ILR_IRQ6_REG         0xffff2d34 /*  6-Uart   serial */
+#define ILR_IRQ7_REG         0xffff2d38 /*  7-Uart   IRDA   */
+#define ILR_IRQ8_REG         0xffff2d3c /*  8-KBGPIO[15:8]  */
+#define ILR_IRQ9_REG         0xffff2d40 /*  9-GPIO3         */
+#define ILR_IRQ10_REG        0xffff2d44 /* 10-GPIO2         */
+#define ILR_IRQ11_REG        0xffff2d48 /* 11-I2C           */
+#define ILR_IRQ12_REG        0xffff2d4c /* 12-GPIO1         */
+#define ILR_IRQ13_REG        0xffff2d50 /* 13-SPI           */
+#define ILR_IRQ14_REG        0xffff2d54 /* 14-GPIO[19:4]    */
+#define ILR_IRQ15_REG        0xffff2d58 /* 15-API           */
+
+/* I2C ********************************************************************/
+
+#define MAX_I2C 1
+
+/* API ********************************************************************/
+
+
+#define DSPRAM_BASE          0xffe00000  /* DSPRAM base address */
+#define DSPRAM_END           0xffe03fff
+
+#endif  /* __ASM_ARCH_HARDWARE_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/io.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/io.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,42 @@
+/*
+ * linux/include/asm-armnommu/arch-c5471/io.h
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* kernel/resource.c uses this to initialize the global ioport_resource struct
+ * which is used in all calls to request_resource(), allocate_resource(), etc.
+ */
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* If we define __io then asm/io.h will take care of most of the inb & friends
+ * macros. It still leaves us some 16bit macros to deal with ourselves, though.
+ * We don't have PCI or ISA, no  __mem_pci & __mem_isa.
+ */
+
+#define PCIO_BASE 0
+#define __io(a) (PCIO_BASE + (a))
+
+/* Some compiler options will convert short loads and stores into byte loads
+ * and stores.  We don't want this to happen for IO reads and writes!
+ */
+
+static inline unsigned short __arch_getw(unsigned int addr)
+{
+  unsigned short retval;
+ __asm__ __volatile__("\tldrh %0, [%1]\n\t" : "=r"(retval) : "r"(addr));
+  return retval;
+}
+static inline void __arch_putw(unsigned short val, unsigned int addr)
+{
+ __asm__ __volatile__("\tstrh %0, [%1]\n\t": : "r"(val), "r"(addr));
+}
+
+/* Defining these two gives us ioremap for free. See asm/io.h. */
+
+#define iomem_valid_addr(iomem,sz) (1)
+#define iomem_to_phys(iomem) (iomem)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/irq.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/irq.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,104 @@
+/*
+ * linux/include/asm-armnommu/arch-c5471/irq.h
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _ASM_ARCH_IRQ_H_
+#define _ASM_ARCH_IRQ_H_
+
+#include <asm/arch/hardware.h>
+#include <asm/mach/irq.h>
+
+#define BUILD_IRQ(s,n,m)
+
+struct pt_regs;
+
+extern int IRQ_interrupt(int irq, struct pt_regs *regs);
+extern int timer_IRQ_interrupt(int irq, struct pt_regs *regs);
+extern int fast_IRQ_interrupt(int irq, struct pt_regs *regs);
+extern int bad_IRQ_interrupt(int irq, struct pt_regs *regs);
+extern int probe_IRQ_interrupt(int irq, struct pt_regs *regs);
+
+extern void c5471_init_irq(void);
+extern void c5471_mask_irq(unsigned int irq);
+extern void c5471_unmask_irq(unsigned int irq);
+extern void c5471_mask_ack_irq(unsigned int irq);
+
+#define IRQ_interrupt0  timer_IRQ_interrupt
+#define IRQ_interrupt1  IRQ_interrupt
+#define IRQ_interrupt2  IRQ_interrupt
+#define IRQ_interrupt3  IRQ_interrupt
+#define IRQ_interrupt4  IRQ_interrupt
+#define IRQ_interrupt5  IRQ_interrupt
+#define IRQ_interrupt4  IRQ_interrupt
+#define IRQ_interrupt6  IRQ_interrupt
+#define IRQ_interrupt7  IRQ_interrupt
+#define IRQ_interrupt8  IRQ_interrupt
+#define IRQ_interrupt9  IRQ_interrupt
+#define IRQ_interrupt10 IRQ_interrupt
+#define IRQ_interrupt11 IRQ_interrupt
+#define IRQ_interrupt12 IRQ_interrupt
+#define IRQ_interrupt13 IRQ_interrupt
+#define IRQ_interrupt14 IRQ_interrupt
+#define IRQ_interrupt15 IRQ_interrupt
+#define IRQ_interrupt16 IRQ_interrupt
+#define IRQ_interrupt17 IRQ_interrupt
+#define IRQ_interrupt18 IRQ_interrupt
+#define IRQ_interrupt19 IRQ_interrupt
+#define IRQ_interrupt20 IRQ_interrupt
+#define IRQ_interrupt21 IRQ_interrupt
+#define IRQ_interrupt22 IRQ_interrupt
+#define IRQ_interrupt23 IRQ_interrupt
+#define IRQ_interrupt24 IRQ_interrupt
+#define IRQ_interrupt25 IRQ_interrupt
+#define IRQ_interrupt26 IRQ_interrupt
+#define IRQ_interrupt27 IRQ_interrupt
+#define IRQ_interrupt28 IRQ_interrupt
+#define IRQ_interrupt29 IRQ_interrupt
+#define IRQ_interrupt30 IRQ_interrupt
+#define IRQ_interrupt31 IRQ_interrupt
+
+#define IRQ_INTERRUPT(n)   (void (*)(void))IRQ_interrupt##n
+#define FAST_INTERRUPT(n)  (void (*)(void))fast_IRQ_interrupt
+#define BAD_INTERRUPT(n)   (void (*)(void))bad_IRQ_interrupt
+#define PROBE_INTERRUPT(n) (void (*)(void))probe_IRQ_interrupt
+
+#define fixup_irq(x) (x)
+
+static __inline__ void irq_init_irq(void)
+{
+  int irq;
+
+  for (irq = 0; irq < NR_IRQS; irq++)
+    {
+      irq_desc[irq].valid	= 1;
+      irq_desc[irq].probe_ok	= 1;
+      irq_desc[irq].mask_ack	= c5471_mask_ack_irq;
+      irq_desc[irq].mask	= c5471_mask_irq;
+      irq_desc[irq].unmask	= c5471_unmask_irq;
+    }
+
+  c5471_init_irq();
+}
+
+#endif /* _ASM_ARCH_IRQ_H_ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/irqs.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/irqs.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/irqs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,90 @@
+/***********************************************************************
+ * include/asm-armnommu/arch-c5471/irqs.h
+ *
+ *   Copyright (C) 2003 Cadenux, LLC. All rights reserved.
+ *   todd.fischer@cadenux.com  <www.cadenux.com>
+ *
+ *   Copyright (C) 2001 RidgeRun, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+
+#include <linux/autoconf.h>
+
+#define UCLINUX_IRQ_TIMER  C5471_IRQ_TIMER2 /* interrupt number */
+
+#define C5471_IRQ_TIMER0         0
+#define C5471_IRQ_WATCHDOG       0
+#define C5471_IRQ_TIMER1         1
+#define C5471_IRQ_TIMER2         2
+#define C5471_IRQ_ETHER          3
+#define C5471_IRQ_GPIO0          4
+#define C5471_IRQ_KBGPIO_0_7     5
+#define C5471_IRQ_UART           6
+#define C5471_IRQ_UART_IRDA      7
+#define C5471_IRQ_KBGPIO_8_15    8
+#define C5471_IRQ_GPIO3          9
+#define C5471_IRQ_GPIO2         10
+#define C5471_IRQ_I2C           11
+#define C5471_IRQ_GPIO1         12
+#define C5471_IRQ_SPI           13
+#define C5471_IRQ_GPIO_4_19     14
+#define C5471_IRQ_API           15
+
+#define IRQ_TIMER UCLINUX_IRQ_TIMER
+
+/* flags for request_irq().  IRQ_FLG_STD is apparently a uClinux-ism,
+ * so I'll keep it around even though it is just a mapping for the
+ * real SA_INTERRUPT. -- skj 
+ */
+
+#define IRQ_FLG_STD SA_INTERRUPT
+
+/*  If you want to use the watchdog timer, send in this
+ *  as its interrupt flag
+ */
+
+#define FIQ_FORCE 0x2
+
+#define INT_WD_TIMER		 0
+#define INT_TIMER1		 1
+#define INT_TIMER2		 2
+#define INT_GPIO0		 3
+#define INT_ETH			 4
+#define INT_KBGPIO_0_7		 5
+#define INT_UART		 6
+#define INT_UART_IRDA		 7
+#define INT_KGPIO_8_15		 8
+#define INT_GPIO3		 9
+#define INT_GPIO2		10
+#define INT_I2C			11
+#define INT_GPIO1		12
+#define INT_SPI			13
+#define INT_GPIO_4_19		14
+#define INT_API			15
+#define NR_IRQS			INT_API+1
+
+#endif /* __ASM_ARCH_IRQS_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/keyboard.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/keyboard.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/keyboard.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ *  linux/include/asm-armnommu/arch-c5471/keyboard.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef __ASM_ARM_ARCH_C5471_KEYBOARD_H
+#define __ASM_ARM_ARCH_C5471_KEYBOARD_H
+
+/*
+ * Required by drivers/char/keyboard.c.
+ */
+
+#define kbd_setkeycode(sc,kc) (-EINVAL)
+#define kbd_getkeycode(sc) (-EINVAL)
+#define kbd_translate(sc,kcp,rm) ({ *(kcp) = (sc); 1; })
+#define kbd_unexpected_up(kc) (0200)
+#define kbd_leds(leds)
+#define kbd_init_hw()
+#define kbd_enable_irq() 
+#define kbd_disable_irq()
+
+#endif /* __ASM_ARM_ARCH_C5471_KEYBOARD_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/memory.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/memory.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,67 @@
+/*
+ * linux/include/asm-armnommu/arch-c5471/memory.h
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <linux/autoconf.h>
+
+#define __virt_to_bus(x) ((unsigned long) (x))
+#define __bus_to_virt(x) ((void *) (x))
+#define __virt_to_phys(x) ((unsigned long) (x))
+#define __phys_to_virt(x) ((void *) (x))
+
+#define END_MEM		(DRAM_BASE + DRAM_SIZE)
+
+/* These are used in the fault handling code (even for nommu) and various other
+ * macros.
+ */
+
+#define TASK_SIZE	(0x01a00000UL)
+#define TASK_SIZE_26	TASK_SIZE
+
+/* The alignment requirement of the memory management system
+ * this is ~(1 << (PAGE_OFFSET+(MAX_ORDER-1)))-1.
+ */
+
+#define PHYS_OFFSET_MASK 0x001fffff
+
+/* The start of physical memory.  This is the first SDRAM address.
+ * This value is used in the arch-specific bootup code like setup_arch &
+ * bootmem_init.
+ *
+ * NOTE the alignment requirement of the memory management system
+ * this is given by PHYS_OFFSET_MASK.
+ *
+ * Boot from flash -  kernel .text and .rodata are in rom/flash and only
+ * .data lies in SDRAM.  So the mem_map tables can begin near the
+ * beginning of physical SDRAM.  The value _end_kernel provides
+ * SDRAM address after the memory used by the kernel .data section.
+ * There can still be a significant loss of memory due to the alignment
+ * requirement.
+ */
+
+/*
+  extern unsigned long _end_kernel;
+#define PHYS_OFFSET \
+  ((((unsigned long)&_end_kernel) + PHYS_OFFSET_MASK) & ~PHYS_OFFSET_MASK)
+*/
+
+
+#define PHYS_OFFSET \
+  ((((unsigned long)DRAM_BASE) + PHYS_OFFSET_MASK) & ~PHYS_OFFSET_MASK)
+
+
+#define UNALIGNED_PHYS_OFFSET ((unsigned long)&_end_kernel)
+
+#define LOST_MEMORY_SIZE (PHYS_OFFSET - UNALIGNED_PHYS_OFFSET)
+
+/* PAGE_OFFSET -- the first address of the first page of memory. For archs with
+ * no MMU this corresponds to the first free page in physical memory (aligned
+ * on a page boundary).
+ */
+
+#define PAGE_OFFSET PHYS_OFFSET
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/mmu.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/mmu.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/mmu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/mmu.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,23 @@
+/*
+ * linux/include/asm-arm/arch-c5471/mmu.h
+ *
+ * Copyright (c) 1996 Russell King.
+ *
+ * Changelog:
+ *  22-11-1996	RMK	Created
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((unsigned long) (vpage))
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((void *) (ppage))
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(vpage) ((unsigned long) (vpage))
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(ppage) ((void *) (ppage))
+
+#define __flush_entry_to_
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/param.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/param.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,8 @@
+/* include/asm-armnommu/arch-c5471/param.h */
+
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/processor.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/processor.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/processor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,21 @@
+/*
+ * linux/include/asm-armnommu/arch-c5471/processor.h
+ * Derived from linux/include/asm-armnommu/arch-atmel/mmu.h
+ *
+ */
+
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+#define EISA_bus 0
+#define EISA_bus__is_a_macro
+#define MCA_bus 0
+#define MCA_bus__is_a_macro
+
+#define TASK_SIZE (0x01a00000UL)
+
+#define INIT_MMAP { \
+  &init_mm, 0, 0x02000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC \
+}
+
+#endif /* __ASM_ARCH_PROCESSOR_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/serial.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/serial.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/serial.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,182 @@
+/***********************************************************************
+ * linux/include/asm-arm/arch-c5471/serial.h
+ *
+ *   Copyright (C) 2003 Cadenux, LLC. All rights reserved.
+ *   todd.fischer@cadenux.com  <www.cadenux.com>
+ *
+ *   Copyright (C) 2001 RidgeRun, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <linux/config.h>
+#include <linux/termios.h>
+#include <linux/tqueue.h>
+#include <linux/circ_buf.h>
+#include <linux/wait.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/irqs.h>
+
+#define BASE_BAUD     115200
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+/* This defines the initializer for a struct serial_state describing the
+ * C5471 serial IRDA port.
+ */
+
+#define C5471_IRDA_SERIAL_PORT_DEFN \
+  {  \
+    magic:          0, \
+    port:           0, \
+    flags:          STD_COM_FLAGS, \
+    xmit_fifo_size: UART_IRDA_XMIT_FIFO_SIZE, \
+    baud_base:      BASE_BAUD, \
+    irq:            C5471_IRQ_UART_IRDA, \
+    type:           PORT_UNKNOWN, \
+    iomem_base:     UART_IRDA_BASE, \
+    io_type:        SERIAL_IO_MEM \
+  }
+
+/* This defines the initializer for a struct serial_state describing the
+ * C5471 serial MODEM port.
+ */
+
+#define C5471_MODEM_SERIAL_PORT_DEFN \
+  {  \
+    magic:          0, \
+    port:           1, \
+    flags:          STD_COM_FLAGS, \
+    xmit_fifo_size: UART_XMIT_FIFO_SIZE, \
+    baud_base:      BASE_BAUD, \
+    irq:            C5471_IRQ_UART, \
+    type:           PORT_UNKNOWN, \
+    iomem_base:     UART_MODEM_BASE, \
+    io_type:        SERIAL_IO_MEM \
+  }
+
+/* There will always be two serial ports:  The C5471 Modem UART and
+ * the C5471 IrDA UART.
+ */
+
+//#define RS_TABLE_SIZE 2
+#define RS_TABLE_SIZE 1
+
+/* STD_SERIAL_PORT_DEFNS (plus EXTRA_SERIAL_PORT_DEFNS, see
+ * include/asm/serial.h) define an array of struct serial_state
+ * instance initializers.  These array initilizers are used
+ * in drivers/char/serial_c5471.c to described the serial
+ * ports that will be support.
+ */
+
+# define STD_SERIAL_PORT_DEFNS \
+  C5471_MODEM_SERIAL_PORT_DEFN, /* ttyS0 */ \
+
+/*  C5471_IRDA_SERIAL_PORT_DEFN */  /* ttyS1 */ \
+
+#define EXTRA_SERIAL_PORT_DEFNS
+
+/* Events are used to schedule things to happen at timer-interrupt
+ * time, instead of at rs interrupt time.
+ */
+
+#define RS_EVENT_WRITE_WAKEUP	0
+
+#define CONFIGURED_SERIAL_PORT(info) ((info)->state)
+
+#define SERIAL_MAGIC 0x5301
+#define SSTATE_MAGIC 0x5302
+
+/* This is the internal structure for each serial port's state.
+ *
+ * For definitions of the flags field, see tty.h
+ */
+
+struct c5471_serial_state_s
+{
+  int			magic;
+  int                   port;
+  int			baud_base;
+  int			irq;
+  int			flags;
+  int			type;
+  int			line;
+  int			xmit_fifo_size;
+  int			custom_divisor;
+  int			count;
+  int			io_type;
+  unsigned long		iomem_base;
+  unsigned short	close_delay;
+  unsigned short	closing_wait; /* time to wait before closing */
+  struct async_icount	icount;	
+  struct termios	normal_termios;
+  struct termios	callout_termios;
+  struct c5471_async_s	*info;
+};
+typedef struct c5471_serial_state_s c5471_serial_state_t;
+
+struct c5471_async_s
+{
+  int			magic;
+  int                   port;
+  int			flags;
+  c5471_serial_state_t	*state;
+  struct tty_struct 	*tty;
+  unsigned short	closing_wait;
+  int			line;
+  int			timeout;
+  int			quot;
+  int			x_char;		/* xon/xoff character */
+  int			close_delay;
+  int			blocked_open;	/* # of blocked opens */
+  unsigned long		event;
+  unsigned long		last_active;
+  long			session;	/* Session of opening process */
+  long			pgrp;		/* pgrp of opening process */
+  struct circ_buf	xmit;
+  struct tq_struct	tqueue;
+#ifdef DECLARE_WAITQUEUE
+  wait_queue_head_t	open_wait;
+  wait_queue_head_t	close_wait;
+  wait_queue_head_t	delta_msr_wait;
+#else	
+  struct wait_queue	*open_wait;
+  struct wait_queue	*close_wait;
+  struct wait_queue	*delta_msr_wait;
+#endif	
+  struct c5471_async_s	*next_port; /* For the linked list */
+  struct c5471_async_s	*prev_port;
+};
+typedef struct c5471_async_s c5471_async_t;
+
+struct hw_reg_shadow {
+  unsigned long		IER_cached;	/* Cached UART interrupt enable reg */
+  unsigned long		LCR_cached;	/* Cached UART line control reg */
+  unsigned long		FCR_cached;	/* Cached UART fifo control reg */
+  unsigned long		EFR_cached;	/* Cached UART enhanced feature reg */
+  unsigned long		TCR_cached;	/* Cached UART TX control reg */
+};
+
+#endif /* __ASM_ARCH_SERIAL_H */
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/shmparam.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/shmparam.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/shmparam.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-c5471/shmparam.h
+ *
+ * Copyright (c) 1996 Russell King.
+ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/sysdep.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/sysdep.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/sysdep.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/sysdep.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,819 @@
+/* linux/include/asm-armnommu/arch-c5471/sysdep.h
+ *   Centralized compatibility issues between 2.0, 2.2, 2.4
+ *
+ * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
+ * Copyright (C) 2001 O'Reilly & Associates
+ *
+ * The source code in this file can be freely used, adapted,
+ * and redistributed in source or binary form, so long as an
+ * acknowledgment appears in derived source files.  The citation
+ * should list that the code comes from the book "Linux Device
+ * Drivers" by Alessandro Rubini and Jonathan Corbet, published
+ * by O'Reilly & Associates.   No warranty is attached;
+ * we cannot take responsibility for errors or fitness for use.
+ *
+ * $Id: sysdep.h,v 1.1 2005/03/02 05:30:26 gerg Exp $
+ */
+
+#ifndef _ASM_ARCH_SYSDEP_H_
+#define _ASM_ARCH_SYSDEP_H_
+
+#ifndef LINUX_VERSION_CODE
+#  include <linux/version.h>
+#endif
+
+#ifndef KERNEL_VERSION /* pre-2.1.90 didn't have it */
+#  define KERNEL_VERSION(vers,rel,seq) ( ((vers)<<16) | ((rel)<<8) | (seq) )
+#endif
+
+/* only allow 2.0.x  2.2.y and 2.4.z */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,0,0) /* not < 2.0 */
+#  error "This kernel is too old: not supported by this file"
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* not > 2.4, by now */
+#  error "This kernel is too recent: not supported by this file"
+#endif
+#if (LINUX_VERSION_CODE & 0xff00) == 1 /* not 2.1 */
+#  error "Please don't use linux-2.1, use 2.2 or 2.4 instead"
+#endif
+#if (LINUX_VERSION_CODE & 0xff00) == 3 /* not 2.3 */
+#  error "Please don't use linux-2.3, use 2.4 instead"
+#endif
+
+/* remember about the current version */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
+#  define LINUX_20
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
+#  define LINUX_22
+#else
+#  define LINUX_24
+#endif
+
+/* we can't support versioning in pre-2.4 because we #define some functions */
+#if !defined(LINUX_24) && defined(CONFIG_MODVERSIONS)
+#  error "This sysdep.h can't support CONFIG_MODVERSIONS"
+#  error "and old kernels at the same time."
+#  error "Either use 2.4 or avoid using versioning"
+#endif
+
+#ifndef LINUX_20 /* include vmalloc.h if this is 2.2/2.4 */
+#  ifdef VM_READ /* a typical flag defined by mm.h */
+#    include <linux/vmalloc.h>
+#  endif
+#endif
+
+#include <linux/sched.h>
+
+/* Modularization issues */
+#ifdef LINUX_20
+#  define __USE_OLD_SYMTAB__
+#  define EXPORT_NO_SYMBOLS register_symtab(NULL);
+#  define REGISTER_SYMTAB(tab) register_symtab(tab)
+#else
+#  define REGISTER_SYMTAB(tab) /* nothing */
+#endif
+
+#ifdef __USE_OLD_SYMTAB__
+#  define __MODULE_STRING(s)         /* nothing */
+#  define MODULE_PARM(v,t)           /* nothing */
+#  define MODULE_PARM_DESC(v,t)      /* nothing */
+#  define MODULE_AUTHOR(n)           /* nothing */
+#  define MODULE_DESCRIPTION(d)      /* nothing */
+#  define MODULE_SUPPORTED_DEVICE(n) /* nothing */
+#endif
+
+/*
+ * In version 2.2 (up to 2.2.19, at least), the macro for request_module()
+ * when no kmod is there is wrong. It's a "do {} while 0" but it shouldbe int
+ */
+#ifdef LINUX_22
+#  ifndef CONFIG_KMOD
+#    undef request_module
+#    define request_module(name) -ENOSYS
+#  endif
+#endif
+
+
+#ifndef LINUX_20
+#  include <linux/init.h>     /* module_init/module_exit */
+#endif
+
+#ifndef module_init
+#  define module_init(x)        int init_module(void) { return x(); }
+#  define module_exit(x)        void cleanup_module(void) { x(); }
+#endif
+
+#ifndef SET_MODULE_OWNER
+#  define SET_MODULE_OWNER(structure) /* nothing */
+#endif
+
+/*
+ * "select" changed in 2.1.23. The implementation is twin, but this
+ * header is new
+ *
+ */
+#ifdef LINUX_20
+#  define __USE_OLD_SELECT__
+#else
+#  include <linux/poll.h>
+#endif
+
+#ifdef LINUX_20
+#  define INODE_FROM_F(filp) ((filp)->f_inode)
+#else
+#  define INODE_FROM_F(filp) ((filp)->f_dentry->d_inode)
+#endif
+
+/* Other changes in the fops are solved using wrappers */
+
+/*
+ * Wait queues changed with 2.3
+ */
+#ifndef DECLARE_WAIT_QUEUE_HEAD
+#  define DECLARE_WAIT_QUEUE_HEAD(head) struct wait_queue *head = NULL
+   typedef  struct wait_queue *wait_queue_head_t;
+#  define init_waitqueue_head(head) (*(head)) = NULL
+
+/* offer wake_up_sync as an alias for wake_up */
+#  define wake_up_sync(head) wake_up(head)
+#  define wake_up_interruptible_sync(head) wake_up_interruptible(head)
+
+/* Pretend we have add_wait_queue_exclusive */
+#  define add_wait_queue_exclusive(q,entry) add_wait_queue ((q), (entry))
+
+#endif /* no DECLARE_WAIT_QUEUE_HEAD */
+
+/*
+ * Define wait_event for 2.0 kernels.  (This ripped off directly from
+ * the 2.2.18 sched.h)
+ */
+#ifdef LINUX_20
+
+#define __wait_event(wq, condition) 					\
+do {									\
+	struct wait_queue __wait;					\
+									\
+	__wait.task = current;						\
+	add_wait_queue(&wq, &__wait);					\
+	for (;;) {							\
+		current->state = TASK_UNINTERRUPTIBLE;			\
+		mb();							\
+		if (condition)						\
+			break;						\
+		schedule();						\
+	}								\
+	current->state = TASK_RUNNING;					\
+	remove_wait_queue(&wq, &__wait);				\
+} while (0)
+
+#define wait_event(wq, condition) 					\
+do {									\
+	if (condition)	 						\
+		break;							\
+	__wait_event(wq, condition);					\
+} while (0)
+
+#define __wait_event_interruptible(wq, condition, ret)			\
+do {									\
+	struct wait_queue __wait;					\
+									\
+	__wait.task = current;						\
+	add_wait_queue(&wq, &__wait);					\
+	for (;;) {							\
+		current->state = TASK_INTERRUPTIBLE;			\
+		mb();							\
+		if (condition)						\
+			break;						\
+		if (!signal_pending(current)) {				\
+			schedule();					\
+			continue;					\
+		}							\
+		ret = -ERESTARTSYS;					\
+		break;							\
+	}								\
+	current->state = TASK_RUNNING;					\
+	remove_wait_queue(&wq, &__wait);				\
+} while (0)
+	
+#define wait_event_interruptible(wq, condition)				\
+({									\
+	int __ret = 0;							\
+	if (!(condition))						\
+		__wait_event_interruptible(wq, condition, __ret);	\
+	__ret;								\
+})
+#endif
+
+
+/*
+ * 2.3 added tasklets
+ */
+#ifdef LINUX_24
+#  define HAVE_TASKLETS
+#endif
+
+
+
+
+/* FIXME: implement the other versions of wake_up etc */
+
+
+/*
+ * access to user space: use the 2.2 functions,
+ * and implement them as macros for 2.0
+ */
+
+#ifdef LINUX_20
+#  include <asm/segment.h>
+#  define access_ok(t,a,sz)           (verify_area((t),(void *) (a),(sz)) ? 0 : 1)
+#  define verify_area_20              verify_area
+#  define   copy_to_user(t,f,n)         (memcpy_tofs((t), (f), (n)), 0)
+#  define copy_from_user(t,f,n)       (memcpy_fromfs((t), (f), (n)), 0)
+#  define   __copy_to_user(t,f,n)       copy_to_user((t), (f), (n))
+#  define __copy_from_user(t,f,n)     copy_from_user((t), (f), (n))
+
+#  define PUT_USER(val,add)           (put_user((val),(add)), 0)
+#  define __PUT_USER(val,add)         PUT_USER((val),(add))
+
+#  define GET_USER(dest,add)          ((dest)=get_user((add)), 0)
+#  define __GET_USER(dest,add)        GET_USER((dest),(add))
+#else
+#  include <asm/uaccess.h>
+#  include <asm/io.h>
+#  define verify_area_20(t,a,sz) (0) /* == success */
+#  define   PUT_USER   put_user
+#  define __PUT_USER __put_user
+#  define   GET_USER   get_user
+#  define __GET_USER __get_user
+#endif
+
+/*
+ * Allocation issues
+ */
+#ifdef GFP_USER /* only if mm.h has been included */
+#  ifdef LINUX_20
+#    define __GFP_DMA GFP_DMA /* 2.0 didn't have the leading __ */
+#  endif
+#  ifndef LINUX_24
+#    define __GFP_HIGHMEM  0  /* was not there */
+#    define GFP_HIGHUSER   0   /* idem */
+#  endif
+
+#  ifdef LINUX_20
+#    define __get_free_pages(a,b) __get_free_pages((a),(b),0)
+#  endif
+#  ifndef LINUX_24
+#    define get_zeroed_page get_free_page
+#  endif
+#endif
+
+/* ioremap */
+#if defined(LINUX_20) && defined(_LINUX_MM_H)
+#  define ioremap_nocache ioremap
+#  ifndef __i386__
+   /* This simple approach works for non-PC platforms. */
+#    define ioremap vremap
+#    define iounmap vfree
+#  else /* the PC has <expletive> ISA; 2.2 and 2.4 remap it, 2.0 needs not */
+extern inline void *ioremap(unsigned long phys_addr, unsigned long size)
+{
+    if (phys_addr >= 0xA0000 && phys_addr + size <= 0x100000)
+        return (void *)phys_addr;
+    return vremap(phys_addr, size);
+}
+
+extern inline void iounmap(void *addr)
+{
+    if ((unsigned long)addr >= 0xA0000
+            && (unsigned long)addr < 0x100000)
+        return;
+    vfree(addr);
+}
+#  endif
+#endif
+
+/* Also, define check_mem_region etc */
+#ifndef LINUX_24
+#  define check_mem_region(a,b)     0 /* success */
+#  define request_mem_region(a,b,c) /* nothing */
+#  define release_mem_region(a,b)   /* nothing */
+#endif
+
+/* implement capable() for 2.0 */
+#ifdef LINUX_20
+#  define capable(anything)  suser()
+#endif
+
+/* The use_count of exec_domain and binfmt changed in 2.1.23 */
+
+#ifdef LINUX_20
+#  define INCRCOUNT(p)  ((p)->module ? __MOD_INC_USE_COUNT((p)->module) : 0)
+#  define DECRCOUNT(p)  ((p)->module ? __MOD_DEC_USE_COUNT((p)->module) : 0)
+#  define CURRCOUNT(p)  ((p)->module && (p)->module->usecount)
+#else
+#  define INCRCOUNT(p)  ((p)->use_count++)
+#  define DECRCOUNT(p)  ((p)->use_count--)
+#  define CURRCOUNT(p)  ((p)->use_count)
+#endif
+
+/*
+ * /proc has changed a lot across the versions...
+ */
+#ifdef LINUX_20
+#  define USE_PROC_REGISTER
+#endif
+
+
+/*
+ * 2.2 didn't have create_proc_{read|info}_entry yet.
+ * And it looks like there are no other "interesting" entry point, as
+ * the rest is somehow esotique (mknod, symlink, ...)
+ */
+#ifdef LINUX_22
+#  ifdef PROC_SUPER_MAGIC  /* Only if procfs is being used */
+extern inline struct proc_dir_entry *create_proc_read_entry(const char *name,
+                          mode_t mode, struct proc_dir_entry *base, 
+                          read_proc_t *read_proc, void * data)
+{
+    struct proc_dir_entry *res=create_proc_entry(name,mode,base);
+    if (res) {
+        res->read_proc=read_proc;
+        res->data=data;
+    }
+    return res;
+}
+
+#    ifndef create_proc_info_entry /* added in 2.2.18 */
+typedef int (get_info_t)(char *, char **, off_t, int, int);
+extern inline struct proc_dir_entry *create_proc_info_entry(const char *name,
+        mode_t mode, struct proc_dir_entry *base, get_info_t *get_info)
+{
+        struct proc_dir_entry *res=create_proc_entry(name,mode,base);
+        if (res) res->get_info=get_info;
+        return res;
+}
+#    endif  /* no create_proc_info_entry */
+#  endif
+#endif
+
+#ifdef LINUX_20
+#  define test_and_set_bit(nr,addr)  test_bit((nr),(addr))
+#  define test_and_clear_bit(nr,addr) clear_bit((nr),(addr))
+#  define test_and_change_bit(nr,addr) change_bit((nr),(addr))
+#endif
+
+
+/* 2.0 had no read and write memory barriers, and 2.2 lacks the
+   set_ functions */
+#ifndef LINUX_24
+#  ifdef LINUX_20
+#    define wmb() mb() /* this is a big penalty on non-reordering platfs */
+#    define rmb() mb() /* this is a big penalty on non-reordering platfs */
+#  endif /* LINUX_20 */
+
+#define set_mb() do { var = value; mb(); } while (0)
+#define set_wmb() do { var = value; wmb(); } while (0)
+#endif /* ! LINUX_24 */
+
+
+
+/* 2.1.30 removed these functions. Let's define them, just in case */
+#ifndef LINUX_20
+#  define queue_task_irq      queue_task
+#  define queue_task_irq_off  queue_task
+#endif
+
+/* 2.1.10 and 2.1.43 introduced new functions. They are worth using */
+
+#ifdef LINUX_20
+
+#  include <asm/byteorder.h>
+#  ifdef __LITTLE_ENDIAN
+#    define cpu_to_le16(x) (x)
+#    define cpu_to_le32(x) (x)
+#    define cpu_to_be16(x) htons((x))
+#    define cpu_to_be32(x) htonl((x))
+#  else
+#    define cpu_to_be16(x) (x)
+#    define cpu_to_be32(x) (x)
+     extern inline __u16 cpu_to_le16(__u16 x) { return (x<<8) | (x>>8);}
+     extern inline __u32 cpu_to_le32(__u32 x) { return (x>>24) |
+             ((x>>8)&0xff00) | ((x<<8)&0xff0000) | (x<<24);}
+#  endif
+
+#  define le16_to_cpu(x)  cpu_to_le16(x)
+#  define le32_to_cpu(x)  cpu_to_le32(x)
+#  define be16_to_cpu(x)  cpu_to_be16(x)
+#  define be32_to_cpu(x)  cpu_to_be32(x)
+
+#  define cpu_to_le16p(addr) (cpu_to_le16(*(addr)))
+#  define cpu_to_le32p(addr) (cpu_to_le32(*(addr)))
+#  define cpu_to_be16p(addr) (cpu_to_be16(*(addr)))
+#  define cpu_to_be32p(addr) (cpu_to_be32(*(addr)))
+
+   extern inline void cpu_to_le16s(__u16 *a) {*a = cpu_to_le16(*a);}
+   extern inline void cpu_to_le32s(__u16 *a) {*a = cpu_to_le32(*a);}
+   extern inline void cpu_to_be16s(__u16 *a) {*a = cpu_to_be16(*a);}
+   extern inline void cpu_to_be32s(__u16 *a) {*a = cpu_to_be32(*a);}
+
+#  define le16_to_cpup(x) cpu_to_le16p(x)
+#  define le32_to_cpup(x) cpu_to_le32p(x)
+#  define be16_to_cpup(x) cpu_to_be16p(x)
+#  define be32_to_cpup(x) cpu_to_be32p(x)
+
+#  define le16_to_cpus(x) cpu_to_le16s(x)
+#  define le32_to_cpus(x) cpu_to_le32s(x)
+#  define be16_to_cpus(x) cpu_to_be16s(x)
+#  define be32_to_cpus(x) cpu_to_be32s(x)
+
+#endif
+
+#ifdef LINUX_20
+#  define __USE_OLD_REBUILD_HEADER__
+#endif
+
+/*
+ * 2.0 didn't include sema_init, so we make our own - but only if it
+ * looks like semaphore.h got included.
+ */
+#ifdef LINUX_20
+#  ifdef MUTEX_LOCKED   /* Only if semaphore.h included */
+     extern inline void sema_init (struct semaphore *sem, int val)
+     {
+         sem->count = val;
+         sem->waking = sem->lock = 0;
+         sem->wait = NULL;
+     }
+#  endif
+#endif /* LINUX_20 */
+
+/*
+ * In 2.0, there is no real need for spinlocks, and they weren't really
+ * implemented anyway.
+ *
+ * XXX the _irqsave variant should be defined eventually to do the
+ * right thing.
+ */
+#ifdef LINUX_20
+typedef int spinlock_t;
+#  define spin_lock(lock)
+#  define spin_unlock(lock)
+#  define spin_lock_init(lock)
+
+#  define spin_lock_irqsave(lock,flags) do { \
+        save_flags(flags); cli(); } while (0);
+#  define spin_unlock_irqrestore(lock,flags) restore_flags(flags);
+#endif
+
+/*
+ * 2.1 stuffed the "flush" method into the middle of the file_operations
+ * structure.  The FOP_NO_FLUSH symbol is for drivers that do not implement
+ * flush (most of them), it can be inserted in initializers for all 2.x
+ * kernel versions.
+ */
+#ifdef LINUX_20
+#  define FOP_NO_FLUSH   /* nothing */
+#  define TAG_LLSEEK    lseek
+#  define TAG_POLL      select
+#else
+#  define FOP_NO_FLUSH  NULL,
+#  define TAG_LLSEEK    llseek
+#  define TAG_POLL      poll
+#endif
+
+
+
+/*
+ * fasync changed in 2.2.
+ */
+#ifdef LINUX_20
+/*  typedef struct inode *fasync_file; */
+#  define fasync_file struct inode *
+#else
+  typedef int fasync_file;
+#endif
+
+/* kill_fasync had less arguments, and a different indirection in the first */
+#ifndef LINUX_24
+#  define kill_fasync(ptrptr,sig,band)  kill_fasync(*(ptrptr),(sig))
+#endif
+
+/* other things that are virtualized: define the new functions for the old k */
+#ifdef LINUX_20
+#  define in_interrupt() (intr_count!=0)
+#  define mdelay(x) udelay((x)*1000)
+#  define signal_pending(current)  ((current)->signal & ~(current)->blocked)
+#endif
+
+#ifdef LINUX_PCI_H /* only if PCI stuff is being used */
+#  ifdef LINUX_20
+#    include "pci-compat.h" /* a whole set of replacement functions */
+#  else
+#    define  pci_release_device(d) /* placeholder, used in 2.0 to free stuff */
+#  endif
+#endif
+
+
+
+/*
+ * Some task state stuff
+ */
+
+#ifndef set_current_state
+#  define set_current_state(s) current->state = (s);
+#endif
+
+#ifdef LINUX_20
+extern inline void schedule_timeout(int timeout)
+{
+    current->timeout = jiffies + timeout;
+    current->state = TASK_INTERRUPTIBLE;
+    schedule();
+    current->timeout = 0;
+}
+
+extern inline long sleep_on_timeout(wait_queue_head_t *q, signed long timeout)
+{
+    signed long early = 0;
+        
+    current->timeout = jiffies + timeout;
+    sleep_on (q);
+    if (current->timeout > 0) {
+        early = current->timeout - jiffies;
+        current->timeout = 0;
+    }
+    return early;
+}
+
+
+extern inline long interruptible_sleep_on_timeout(wait_queue_head_t *q,
+                signed long timeout)
+{
+    signed long early = 0;
+        
+    current->timeout = jiffies + timeout;
+    interruptible_sleep_on (q);
+    if (current->timeout > 0) {
+        early = current->timeout - jiffies;
+        current->timeout = 0;
+    }
+    return early;
+}
+
+#endif /* LINUX_20 */
+
+/*
+ * Schedule_task was a late 2.4 addition.
+ */
+#ifndef LINUX_24
+extern inline int schedule_task(struct tq_struct *task)
+{
+        queue_task(task, &tq_scheduler);
+        return 1;
+}
+#endif
+
+
+/*
+ * Timing issues
+ */
+#ifdef LINUX_20
+#  define get_fast_time do_gettimeofday
+#endif
+
+#ifdef _LINUX_DELAY_H /* only if linux/delay.h is included */
+#  ifndef mdelay /* linux-2.0 */
+#    ifndef MAX_UDELAY_MS
+#      define MAX_UDELAY_MS   5
+#    endif
+#    define mdelay(n) (\
+        (__builtin_constant_p(n) && (n)<=MAX_UDELAY_MS) ? udelay((n)*1000) : \
+        ({unsigned long msec=(n); while (msec--) udelay(1000);}))
+#  endif /* mdelay */
+#endif /* _LINUX_DELAY_H */
+
+
+/*
+ * No del_timer_sync before 2.4
+ */
+#ifndef LINUX_24
+#  define del_timer_sync(timer) del_timer(timer)  /* and hope */
+#endif
+
+/*
+ * mod_timer wasn't present in 2.0
+ */
+#ifdef LINUX_20
+static inline int mod_timer(struct timer_list *timer, unsigned long expires)
+{
+    int pending = del_timer(timer);
+    if (pending) {
+        timer->expires = expires;
+        add_timer(timer);
+    }
+    return pending;
+}
+#endif
+/*
+ * Various changes in mmap and friends.
+ */
+
+#ifndef NOPAGE_SIGBUS
+#  define NOPAGE_SIGBUS  NULL  /* return value of the nopage memory method */
+#  define NOPAGE_OOM     NULL  /* No real equivalent in older kernels */
+#endif
+
+#ifndef VM_RESERVED            /* Added 2.4.0-test10 */
+#  define VM_RESERVED 0
+#endif
+
+#ifdef LINUX_24 /* use "vm_pgoff" to get an offset */
+#define VMA_OFFSET(vma)  ((vma)->vm_pgoff << PAGE_SHIFT)
+#else /* use "vm_offset" */
+#define VMA_OFFSET(vma)  ((vma)->vm_offset)
+#endif
+
+#ifdef MAP_NR
+#define virt_to_page(page) (mem_map + MAP_NR(page))
+#endif
+
+#ifndef get_page
+#  define get_page(p) atomic_inc(&(p)->count)
+#endif
+
+/*
+ * No DMA lock in 2.0.
+ */
+#ifdef LINUX_20
+static inline unsigned long claim_dma_lock(void)
+{
+    unsigned long flags;
+    save_flags(flags);
+    cli();
+    return flags;
+}
+
+static inline void release_dma_lock(unsigned long flags)
+{
+    restore_flags(flags);
+}
+#endif
+
+
+/*
+ * I/O memory was not managed by ealier kernels, define them as success
+ */
+
+#if 0 /* FIXME: what is the right way to do request_mem_region? */
+#ifndef LINUX_24
+#  define check_mem_region(start, len)          0
+#  define request_mem_region(start, len, name)  0
+#  define release_mem_region(start, len)        0
+
+   /*
+    * Also, request_ and release_ region used to return void. Return 0 instead
+    */
+#  define request_region(s, l, n)  ({request_region((s),(l),(n));0;})
+#  define release_region(s, l)     ({release_region((s),(l));0;})
+
+#endif /* not LINUX_24 */
+#endif
+
+/*
+ * Block layer stuff.
+ */
+#ifndef LINUX_24
+
+/* BLK_DEFAULT_QUEUE for use with these macros only!!!! */
+#define BLK_DEFAULT_QUEUE(major) blk_dev[(major)].request_fn
+#define blk_init_queue(where,request_fn) where = request_fn;
+#define blk_cleanup_queue(where) where = NULL;
+
+/* No QUEUE_EMPTY in older kernels */
+#ifndef QUEUE_EMPTY  /* Driver can redefine it too */
+#  define QUEUE_EMPTY (CURRENT != NULL)
+#endif
+
+#ifdef RO_IOCTLS
+static inline int blk_ioctl(kdev_t dev, unsigned int cmd, unsigned long arg)
+{
+    int err;
+
+    switch (cmd) {
+      case BLKRAGET: /* return the readahead value */
+        if (!arg)  return -EINVAL;
+        err = ! access_ok(VERIFY_WRITE, arg, sizeof(long));
+        if (err) return -EFAULT;
+        PUT_USER(read_ahead[MAJOR(dev)],(long *) arg);
+        return 0;
+
+      case BLKRASET: /* set the readahead value */
+        if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+        if (arg > 0xff) return -EINVAL; /* limit it */
+        read_ahead[MAJOR(dev)] = arg;
+        return 0;
+
+      case BLKFLSBUF: /* flush */
+        if (! capable(CAP_SYS_ADMIN)) return -EACCES; /* only root */
+        fsync_dev(dev);
+        invalidate_buffers(dev);
+        return 0;
+
+        RO_IOCTLS(dev, arg);
+    }
+    return -ENOTTY;
+}
+#endif  /* RO_IOCTLS */
+
+#ifdef LINUX_EXTENDED_PARTITION /* defined in genhd.h */
+static inline void register_disk(struct gendisk *gdev, kdev_t dev,
+                unsigned minors, struct file_operations *ops, long size)
+{
+    if (! gdev)
+        return;
+    resetup_one_dev(gdev, MINOR(dev) >> gdev->minor_shift);
+}
+#endif /* LINUX_EXTENDED_PARTITION */
+
+
+#else  /* it is Linux 2.4 */
+#define HAVE_BLKPG_H
+#endif /* LINUX_24 */
+
+
+
+#ifdef LINUX_20 /* physical and virtual addresses had the same value */
+#  define __pa(a) (a)
+#  define __va(a) (a)
+#endif
+
+/*
+ * Network driver compatibility
+ */
+
+/*
+ * 2.0 dev_kfree_skb had an extra arg.  The following is a little dangerous
+ * in that it assumes that FREE_WRITE is always wanted.  Very few 2.0 drivers
+ * use FREE_READ, but the number is *not* zero...
+ *
+ * Also: implement the non-checking versions of a couple skb functions -
+ * but they still check in 2.0.
+ */
+#ifdef LINUX_20
+#  define dev_kfree_skb(skb) dev_kfree_skb((skb), FREE_WRITE);
+
+#  define __skb_push(skb, len) skb_push((skb), (len))
+#  define __skb_put(skb, len)  skb_put((skb), (len))
+#endif
+
+/*
+ * Softnet changes in 2.4
+ */
+#ifndef LINUX_24
+#  ifdef _LINUX_NETDEVICE_H /* only if netdevice.h was included */
+#  define netif_start_queue(dev) clear_bit(0, (void *) &(dev)->tbusy);
+#  define netif_stop_queue(dev)  set_bit(0, (void *) &(dev)->tbusy);
+
+static inline void netif_wake_queue(struct device *dev)
+{
+    clear_bit(0, (void *) &(dev)->tbusy);
+    mark_bh(NET_BH);
+}
+
+/* struct device became struct net_device */
+#  define net_device device
+#  endif /* netdevice.h */
+#endif /* ! LINUX_24 */
+
+/*
+ * Memory barrier stuff, define what's missing from older kernel versions
+ */
+#ifdef switch_to /* this is always a macro, defined in <asm/sysstem.h> */
+
+#  ifndef set_mb
+#    define set_mb(var, value) do {(var) = (value); mb();}  while 0
+#  endif
+#  ifndef set_rmb
+#    define set_rmb(var, value) do {(var) = (value); rmb();}  while 0
+#  endif
+#  ifndef set_wmb
+#    define set_wmb(var, value) do {(var) = (value); wmb();}  while 0
+#  endif
+
+/* The hw barriers are defined as sw barriers. A correct thing if this
+   specific kernel/platform is supported but has no specific instruction */
+#  ifndef mb
+#    define mb barrier
+#  endif
+#  ifndef rmb
+#    define rmb barrier
+#  endif
+#  ifndef wmb
+#    define wmb barrier
+#  endif
+
+#endif /* switch to (i.e. <asm/system.h>) */
+
+
+#endif /* _ASM_ARCH_SYSDEP_H_ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/system.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/system.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,13 @@
+/*
+ * linux/include/asm-armnommu/arch-c5471/system.h
+ */
+
+static inline void arch_idle(void)
+{
+  while (!current->need_resched && !hlt_counter);
+}
+
+extern inline void arch_reset(char mode)
+{
+}
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/time.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/time.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/time.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,53 @@
+/***********************************************************************
+ * linux/include/asm-arm/arch-c5471/time.h
+ *
+ *   Copyright (C) 2003 Cadenux, LLC. All rights reserved.
+ *   todd.fischer@cadenux.com  <www.cadenux.com>
+ *
+ *   Copyright (C) 2001 RidgeRun, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************/
+
+#ifndef __ASM_ARCH_TIME_H__
+#define __ASM_ARCH_TIME_H__
+
+/* The actually timer initialization is performed in the file
+ * arch/armnommu/mach-c5471/time.c.  This inline function is
+ * just a thin candy coating to get to that function.
+ */
+
+extern void c5471_setup_timer(struct irqaction *timer_irq);
+
+/* setup_timer() is "called" from arch/armnommu/kernel/time.c
+ * In the context where setup_timer runs (in this context, timer_irq
+ * is declared as a static intialized variable.  Provided that
+ * the asm/arch/time.h is included AFTER this declaration, the
+ * following should be quite happy:
+ */
+
+void __inline__ setup_timer(void)
+{
+  c5471_setup_timer(&timer_irq);
+}
+
+#endif /* __ASM_ARCH_TIME_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/timex.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/timex.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,37 @@
+/* include/asm-armnommu/arch-c5471/time.h:
+ *
+ *         System clock frequency.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+/* CLOCK_TICK_RATE -- frequency fed to the timer. In our case, 27MHz. Used to
+ * compute LATCH. LATCH is the number of clock ticks per timer interrupt.
+ * (See linux/timex.h, armnommu/mach-c5471/time.c).
+ */
+
+#define CLOCK_TICK_RATE	   27000000
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/uncompress.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/uncompress.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/uncompress.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ * asm/arch/uncompress.c:
+ *         Optional routines to aid in debugging the decompression phase
+ *         of kernel boot.
+ * copyright:
+ *         (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
+ * author: Gordon McNutt <gmcnutt@ridgerun.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * This is used by arch/armnommu/boot/compressed/misc.c to write progress info
+ * out the serial port so that the user can see debug messages up to the point
+ * where the kernel is decompressed. The STANDALONE_DEBUG macro chooses between
+ * this and the standard printf. Punt.
+ * --gmcnutt
+ */
+#define puts(s)
+
+/*
+ * Not sure what this is for. Probably an optional watchdog to check if the
+ * decompress got hung so we can warn the user. Punt.
+ */
+#define arch_decomp_wdog()
+
+/*
+ * If we need to do some setup prior to decompression (like initializing the
+ * UART if we want to use puts() above) then we define it here. Punt.
+ */
+#define arch_decomp_setup()
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/vmalloc.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/vmalloc.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/vmalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,31 @@
+/*
+ *  linux/include/asm-arm/arch-c5471/vmalloc.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/* Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+
+#define VMALLOC_OFFSET	  (8*1024*1024)
+#define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+
diff -urN linux-2.4.29/include/asm-armnommu/arch-vc547x/wdt_ioctl.h linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/wdt_ioctl.h
--- linux-2.4.29/include/asm-armnommu/arch-vc547x/wdt_ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/arch-vc547x/wdt_ioctl.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,48 @@
+/*
+ *	Generic watchdog defines. Derived from..
+ *
+ * Berkshire PC Watchdog Defines
+ * by Ken Hollis <khollis@bitgate.com>
+ *
+ */
+
+#ifndef _LINUX_WATCHDOG_H
+#define _LINUX_WATCHDOG_H
+
+#include <linux/ioctl.h>
+
+#define	WATCHDOG_IOCTL_BASE	'W'
+
+struct watchdog_info {
+	__u32 options;		/* Options the card/driver supports */
+	__u32 firmware_version;	/* Firmware version of the card */
+	__u8  identity[32];	/* Identity of the board */
+};
+
+#define	WDIOC_GETSUPPORT	_IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info)
+#define	WDIOC_GETSTATUS		_IOR(WATCHDOG_IOCTL_BASE, 1, int)
+#define	WDIOC_GETBOOTSTATUS	_IOR(WATCHDOG_IOCTL_BASE, 2, int)
+#define	WDIOC_GETTEMP		_IOR(WATCHDOG_IOCTL_BASE, 3, int)
+#define	WDIOC_SETOPTIONS	_IOR(WATCHDOG_IOCTL_BASE, 4, int)
+#define	WDIOC_KEEPALIVE		_IOR(WATCHDOG_IOCTL_BASE, 5, int)
+#define	WDIOC_SETTIMEOUT        _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
+#define	WDIOC_GETTIMEOUT        _IOR(WATCHDOG_IOCTL_BASE, 7, int)
+
+#define	WDIOF_UNKNOWN		-1	/* Unknown flag error */
+#define	WDIOS_UNKNOWN		-1	/* Unknown status error */
+
+#define	WDIOF_OVERHEAT		0x0001	/* Reset due to CPU overheat */
+#define	WDIOF_FANFAULT		0x0002	/* Fan failed */
+#define	WDIOF_EXTERN1		0x0004	/* External relay 1 */
+#define	WDIOF_EXTERN2		0x0008	/* External relay 2 */
+#define	WDIOF_POWERUNDER	0x0010	/* Power bad/power fault */
+#define	WDIOF_CARDRESET		0x0020	/* Card previously reset the CPU */
+#define WDIOF_POWEROVER		0x0040	/* Power over voltage */
+#define WDIOF_SETTIMEOUT	0x0080  /* Set timeout (in seconds) */
+#define	WDIOF_KEEPALIVEPING	0x8000	/* Keep alive ping reply */
+
+#define	WDIOS_DISABLECARD	0x0001	/* Turn off the watchdog timer */
+#define	WDIOS_ENABLECARD	0x0002	/* Turn on the watchdog timer */
+#define	WDIOS_TEMPPANIC		0x0004	/* Kernel panic on temperature trip */
+
+#endif  /* ifndef _LINUX_WATCHDOG_H */
diff -urN linux-2.4.29/include/asm-armnommu/assembler.h linux-2.4.29-uc1/include/asm-armnommu/assembler.h
--- linux-2.4.29/include/asm-armnommu/assembler.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/assembler.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,29 @@
+/*
+ * linux/asm/assembler.h
+ *
+ * This file contains arm architecture specific defines
+ * for the different processors.
+ *
+ * Do not include any C declarations in this file - it is included by
+ * assembler source.
+ */
+#ifndef __ASSEMBLY__
+#error "Only include this from assembly code"
+#endif
+
+#include <asm/proc/ptrace.h>
+#include <asm/proc/assembler.h>
+
+/*
+ * Endian independent macros for shifting bytes within registers.
+ */
+#ifndef __ARMEB__
+#define pull            lsr
+#define push            lsl
+#define byte(x)         (x*8)
+#else
+#define pull            lsl
+#define push            lsr
+#define byte(x)         ((3-x)*8)
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/atomic.h linux-2.4.29-uc1/include/asm-armnommu/atomic.h
--- linux-2.4.29/include/asm-armnommu/atomic.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/atomic.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,117 @@
+/*
+ *  linux/include/asm-arm/atomic.h
+ *
+ *  Copyright (c) 1996 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Changelog:
+ *   27-06-1996	RMK	Created
+ *   13-04-1997	RMK	Made functions atomic!
+ *   07-12-1997	RMK	Upgraded for v2.1.
+ *   26-08-1998	PJB	Added #ifdef __KERNEL__
+ */
+#ifndef __ASM_ARM_ATOMIC_H
+#define __ASM_ARM_ATOMIC_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_SMP
+#error SMP not supported
+#endif
+
+#ifdef CONFIG_ARCH_CO285
+typedef struct { volatile int counter; } atomic_t;
+#else
+typedef struct { int counter; } atomic_t;
+#endif
+
+#define ATOMIC_INIT(i)	{ (i) }
+
+#ifdef __KERNEL__
+#include <asm/proc/system.h>
+
+#define atomic_read(v)	((v)->counter)
+#define atomic_set(v,i)	(((v)->counter) = (i))
+
+static __inline__ void atomic_add(int i, volatile atomic_t *v)
+{
+	unsigned long flags;
+
+	__save_flags_cli(flags);
+	v->counter += i;
+	__restore_flags(flags);
+}
+
+static __inline__ void atomic_sub(int i, volatile atomic_t *v)
+{
+	unsigned long flags;
+
+	__save_flags_cli(flags);
+	v->counter -= i;
+	__restore_flags(flags);
+}
+
+static __inline__ void atomic_inc(volatile atomic_t *v)
+{
+	unsigned long flags;
+
+	__save_flags_cli(flags);
+	v->counter += 1;
+	__restore_flags(flags);
+}
+
+static __inline__ void atomic_dec(volatile atomic_t *v)
+{
+	unsigned long flags;
+
+	__save_flags_cli(flags);
+	v->counter -= 1;
+	__restore_flags(flags);
+}
+
+static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
+{
+	unsigned long flags;
+	int result;
+
+	__save_flags_cli(flags);
+	v->counter -= 1;
+	result = (v->counter == 0);
+	__restore_flags(flags);
+
+	return result;
+}
+
+extern __inline__ int atomic_add_negative(int i, volatile atomic_t *v)
+{
+	unsigned long flags;
+	int result;
+
+	__save_flags_cli(flags);
+	v->counter += i;
+	result = (v->counter < 0);
+	__restore_flags(flags);
+
+	return result;
+}
+
+static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+{
+	unsigned long flags;
+
+	__save_flags_cli(flags);
+	*addr &= ~mask;
+	__restore_flags(flags);
+}
+
+/* Atomic operations are already serializing on ARM */
+#define smp_mb__before_atomic_dec()	barrier()
+#define smp_mb__after_atomic_dec()	barrier()
+#define smp_mb__before_atomic_inc()	barrier()
+#define smp_mb__after_atomic_inc()	barrier()
+
+#endif
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/bitops.h linux-2.4.29-uc1/include/asm-armnommu/bitops.h
--- linux-2.4.29/include/asm-armnommu/bitops.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/bitops.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,519 @@
+/*
+ * Copyright 1995, Russell King.
+ * Various bits and pieces copyrights include:
+ *  Linus Torvalds (test_bit).
+ *
+ * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
+ *
+ * Please note that the code in this file should never be included
+ * from user space.  Many of these are not implemented in assembler
+ * since they would be too costly.  Also, they require priviledged
+ * instructions (which are not available from user mode) to ensure
+ * that they are atomic.
+ */
+
+#ifndef __ASM_ARM_BITOPS_H
+#define __ASM_ARM_BITOPS_H
+
+#ifdef __KERNEL__
+
+#ifndef __ARMEB__
+
+#define smp_mb__before_clear_bit()	do { } while (0)
+#define smp_mb__after_clear_bit()	do { } while (0)
+
+/*
+ * Function prototypes to keep gcc -Wall happy.
+ */
+extern void set_bit(int nr, volatile void * addr);
+
+static inline void __set_bit(int nr, volatile void *addr)
+{
+	((unsigned char *) addr)[nr >> 3] |= (1U << (nr & 7));
+}
+
+extern void clear_bit(int nr, volatile void * addr);
+
+static inline void __clear_bit(int nr, volatile void *addr)
+{
+	((unsigned char *) addr)[nr >> 3] &= ~(1U << (nr & 7));
+}
+
+extern void change_bit(int nr, volatile void * addr);
+
+static inline void __change_bit(int nr, volatile void *addr)
+{
+	((unsigned char *) addr)[nr >> 3] ^= (1U << (nr & 7));
+}
+
+extern int test_and_set_bit(int nr, volatile void * addr);
+
+static inline int __test_and_set_bit(int nr, volatile void *addr)
+{
+	unsigned int mask = 1 << (nr & 7);
+	unsigned int oldval;
+
+	oldval = ((unsigned char *) addr)[nr >> 3];
+	((unsigned char *) addr)[nr >> 3] = oldval | mask;
+	return oldval & mask;
+}
+
+extern int test_and_clear_bit(int nr, volatile void * addr);
+
+static inline int __test_and_clear_bit(int nr, volatile void *addr)
+{
+	unsigned int mask = 1 << (nr & 7);
+	unsigned int oldval;
+
+	oldval = ((unsigned char *) addr)[nr >> 3];
+	((unsigned char *) addr)[nr >> 3] = oldval & ~mask;
+	return oldval & mask;
+}
+
+extern int test_and_change_bit(int nr, volatile void * addr);
+
+static inline int __test_and_change_bit(int nr, volatile void *addr)
+{
+	unsigned int mask = 1 << (nr & 7);
+	unsigned int oldval;
+
+	oldval = ((unsigned char *) addr)[nr >> 3];
+	((unsigned char *) addr)[nr >> 3] = oldval ^ mask;
+	return oldval & mask;
+}
+
+extern int find_first_zero_bit(void * addr, unsigned size);
+extern int find_next_zero_bit(void * addr, int size, int offset);
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+extern __inline__ int test_bit(int nr, const void * addr)
+{
+    return ((unsigned char *) addr)[nr >> 3] & (1U << (nr & 7));
+}	
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+extern __inline__ unsigned long ffz(unsigned long word)
+{
+	int k;
+
+	word = ~word;
+	k = 31;
+	if (word & 0x0000ffff) { k -= 16; word <<= 16; }
+	if (word & 0x00ff0000) { k -= 8;  word <<= 8;  }
+	if (word & 0x0f000000) { k -= 4;  word <<= 4;  }
+	if (word & 0x30000000) { k -= 2;  word <<= 2;  }
+	if (word & 0x40000000) { k -= 1; }
+        return k;
+}
+
+/*
+ * ffs: find first bit set. This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+
+#define ffs(x) generic_ffs(x)
+
+#define ext2_set_bit			test_and_set_bit
+#define ext2_clear_bit			test_and_clear_bit
+#define ext2_test_bit			test_bit
+#define ext2_find_first_zero_bit	find_first_zero_bit
+#define ext2_find_next_zero_bit		find_next_zero_bit
+
+/* Bitmap functions for the minix filesystem. */
+#define minix_test_and_set_bit(nr,addr)	test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr)		set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr)	test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr)		test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size)	find_first_zero_bit(addr,size)
+
+
+
+#else /******* __ARMEB__ *******/
+
+
+
+/*
+ * All these stolen from the m68knommu header,  why ? because
+ * they implement everything and it saves having to fix the
+ * assembler routines in arch/armnommu/lib ;-)
+ */
+
+#include <linux/config.h>
+#include <asm/byteorder.h>	/* swab32 */
+#include <asm/system.h>		/* save_flags */
+
+#ifndef save_and_cli
+#define save_and_cli(x) do { save_flags(flags); cli(); } while(0)
+#endif
+
+#ifndef save_and_set
+#define save_and_set(x) do { save_flags(flags); set(); } while(0)
+#endif
+
+
+extern void set_bit(int nr, volatile void * addr);
+extern void __set_bit(int nr, volatile void * addr);
+extern void clear_bit(int nr, volatile void * addr);
+extern void change_bit(int nr, volatile void * addr);
+extern void __change_bit(int nr, volatile void * addr);
+extern int test_and_set_bit(int nr, volatile void * addr);
+extern int __test_and_set_bit(int nr, volatile void * addr);
+extern int test_and_clear_bit(int nr, volatile void * addr);
+extern int __test_and_clear_bit(int nr, volatile void * addr);
+extern int test_and_change_bit(int nr, volatile void * addr);
+extern int __test_and_change_bit(int nr, volatile void * addr);
+extern int __constant_test_bit(int nr, const volatile void * addr);
+extern int __test_bit(int nr, volatile void * addr);
+extern int find_first_zero_bit(void * addr, unsigned size);
+extern int find_next_zero_bit (void * addr, int size, int offset);
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+extern __inline__ unsigned long ffz(unsigned long word)
+{
+	unsigned long result = 0;
+
+	while(word & 1) {
+		result++;
+		word >>= 1;
+	}
+	return result;
+}
+
+
+extern __inline__ void set_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_flags(flags); cli();
+	*a |= mask;
+	restore_flags(flags);
+}
+
+extern __inline__ void __set_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	*a |= mask;
+}
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+
+extern __inline__ void clear_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_flags(flags); cli();
+	*a &= ~mask;
+	restore_flags(flags);
+}
+
+extern __inline__ void change_bit(int nr, volatile void * addr)
+{
+	int mask, flags;
+	unsigned long *ADDR = (unsigned long *) addr;
+
+	ADDR += nr >> 5;
+	mask = 1 << (nr & 31);
+	save_flags(flags); cli();
+	*ADDR ^= mask;
+	restore_flags(flags);
+}
+
+extern __inline__ void __change_bit(int nr, volatile void * addr)
+{
+	int mask;
+	unsigned long *ADDR = (unsigned long *) addr;
+
+	ADDR += nr >> 5;
+	mask = 1 << (nr & 31);
+	*ADDR ^= mask;
+}
+
+extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+extern __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+	return retval;
+}
+
+extern __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+	return retval;
+}
+
+extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+extern __inline__ int __test_and_change_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	return retval;
+}
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+extern __inline__ int __constant_test_bit(int nr, const volatile void * addr)
+{
+	return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
+}
+
+extern __inline__ int __test_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	return ((mask & *a) != 0);
+}
+
+#define test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ __constant_test_bit((nr),(addr)) : \
+ __test_bit((nr),(addr)))
+
+#define find_first_zero_bit(addr, size) \
+        find_next_zero_bit((addr), (size), 0)
+
+extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if (offset) {
+		tmp = *(p++);
+		tmp |= ~0UL >> (32-offset);
+		if (size < 32)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while (size & ~31UL) {
+		if (~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp |= ~0UL >> size;
+found_middle:
+	return result + ffz(tmp);
+}
+
+#define ffs(x) generic_ffs(x)
+
+extern __inline__ int ext2_set_bit(int nr, volatile void * addr)
+{
+	int		mask, retval;
+	unsigned long	flags;
+	volatile unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	save_and_cli(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR |= mask;
+	restore_flags(flags);
+	return retval;
+}
+
+extern __inline__ int ext2_clear_bit(int nr, volatile void * addr)
+{
+	int		mask, retval;
+	unsigned long	flags;
+	volatile unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	save_and_cli(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR &= ~mask;
+	restore_flags(flags);
+	return retval;
+}
+
+extern __inline__ int ext2_test_bit(int nr, const volatile void * addr)
+{
+	int			mask;
+	const volatile unsigned char	*ADDR = (const unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	return ((mask & *ADDR) != 0);
+}
+
+#define ext2_find_first_zero_bit(addr, size) \
+        ext2_find_next_zero_bit((addr), (size), 0)
+
+extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if(offset) {
+		/* We hold the little endian value in tmp, but then the
+		 * shift is illegal. So we could keep a big endian value
+		 * in tmp, like this:
+		 *
+		 * tmp = __swab32(*(p++));
+		 * tmp |= ~0UL >> (32-offset);
+		 *
+		 * but this would decrease preformance, so we change the
+		 * shift:
+		 */
+		tmp = *(p++);
+		tmp |= __swab32(~0UL >> (32-offset));
+		if(size < 32)
+			goto found_first;
+		if(~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while(size & ~31UL) {
+		if(~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if(!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	/* tmp is little endian, so we would have to swab the shift,
+	 * see above. But then we have to swab tmp below for ffz, so
+	 * we might as well do this here.
+	 */
+	return result + ffz(__swab32(tmp) | (~0UL << size));
+found_middle:
+	return result + ffz(__swab32(tmp));
+}
+
+/* Bitmap functions for the minix filesystem.  */
+#define minix_test_and_set_bit(nr,addr) ext2_test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr) ext2_set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr) ext2_test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) ext2_test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) ext2_find_first_zero_bit(addr,size)
+
+
+#endif /* __ARMEB__ */
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+
+#endif /* __KERNEL__ */
+
+#endif /* _ARM_BITOPS_H */
diff -urN linux-2.4.29/include/asm-armnommu/bugs.h linux-2.4.29-uc1/include/asm-armnommu/bugs.h
--- linux-2.4.29/include/asm-armnommu/bugs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/bugs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ *  linux/include/asm-arm/bugs.h
+ *
+ *  Copyright (C) 1995  Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_BUGS_H
+#define __ASM_BUGS_H
+
+#include <asm/proc-fns.h>
+
+#define check_bugs() cpu_check_bugs()
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/byteorder.h linux-2.4.29-uc1/include/asm-armnommu/byteorder.h
--- linux-2.4.29/include/asm-armnommu/byteorder.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/byteorder.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ *  linux/include/asm-arm/byteorder.h
+ *
+ * ARM Endian-ness.  In little endian mode, the data bus is connected such
+ * that byte accesses appear as:
+ *  0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31
+ * and word accesses (data or instruction) appear as:
+ *  d0...d31
+ *
+ * When in big endian mode, byte accesses appear as:
+ *  0 = d24...d31, 1 = d16...d23, 2 = d8...d15, 3 = d0...d7
+ * and word accesses (data or instruction) appear as:
+ *  d0...d31
+ */
+#ifndef __ASM_ARM_BYTEORDER_H
+#define __ASM_ARM_BYTEORDER_H
+
+
+#include <asm/types.h>
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#ifdef __ARMEB__
+#include <linux/byteorder/big_endian.h>
+#else
+#include <linux/byteorder/little_endian.h>
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/cache.h linux-2.4.29-uc1/include/asm-armnommu/cache.h
--- linux-2.4.29/include/asm-armnommu/cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/cache.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,19 @@
+/*
+ *  linux/include/asm-arm/cache.h
+ */
+#ifndef __ASMARM_CACHE_H
+#define __ASMARM_CACHE_H
+
+#define        L1_CACHE_BYTES  32
+#define        L1_CACHE_ALIGN(x)       (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
+#define        SMP_CACHE_BYTES L1_CACHE_BYTES
+
+#ifdef MODULE
+#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES)))
+#else
+#define __cacheline_aligned					\
+  __attribute__((__aligned__(L1_CACHE_BYTES),			\
+		 __section__(".data.cacheline_aligned")))
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/checksum.h linux-2.4.29-uc1/include/asm-armnommu/checksum.h
--- linux-2.4.29/include/asm-armnommu/checksum.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/checksum.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,166 @@
+/*
+ *  linux/include/asm-arm/checksum.h
+ *
+ * IP checksum routines
+ *
+ * Copyright (C) Original authors of ../asm-i386/checksum.h
+ * Copyright (C) 1996-1999 Russell King
+ */
+#ifndef __ASM_ARM_CHECKSUM_H
+#define __ASM_ARM_CHECKSUM_H
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums, and handles user-space pointer exceptions correctly, when needed.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+unsigned int
+csum_partial_copy_nocheck(const char *src, char *dst, int len, int sum);
+
+unsigned int
+csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *err_ptr);
+
+/*
+ * These are the old (and unsafe) way of doing checksums, a warning message will be
+ * printed if they are used and an exception occurs.
+ *
+ * these functions should go away after some time.
+ */
+#define csum_partial_copy(src,dst,len,sum)	csum_partial_copy_nocheck(src,dst,len,sum)
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ */
+static inline unsigned short
+ip_fast_csum(unsigned char * iph, unsigned int ihl)
+{
+	unsigned int sum, tmp1;
+
+	__asm__ __volatile__(
+	"ldr	%0, [%1], #4		@ ip_fast_csum 		\n"
+	"ldr	%3, [%1], #4					\n"
+	"sub	%2, %2, #5					\n"
+	"adds	%0, %0, %3					\n"
+	"ldr	%3, [%1], #4					\n"
+	"adcs	%0, %0, %3					\n"
+	"ldr	%3, [%1], #4					\n"
+	"adcs	%0, %0, %3					\n"
+"1:	ldr	%3, [%1], #4					\n"
+	"adcs	%0, %0, %3					\n"
+	"tst	%2, #15						\n"
+	"subne	%2, %2, #1					\n"
+	"bne	1b						\n"
+	"adc	%0, %0, #0					\n"
+	"adds	%0, %0, %0, lsl #16				\n"
+	"addcs	%0, %0, #0x10000				\n"
+	"mvn	%0, %0						\n"
+	"mov	%0, %0, lsr #16"
+	: "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1)
+	: "1" (iph), "2" (ihl)
+	: "cc");
+	return sum;
+}
+
+/*
+ * 	Fold a partial checksum without adding pseudo headers
+ */
+static inline unsigned int
+csum_fold(unsigned int sum)
+{
+	__asm__(
+	"adds	%0, %1, %1, lsl #16	@ csum_fold	\n"
+	"addcs	%0, %0, #0x10000"
+	: "=r" (sum)
+	: "r" (sum)
+	: "cc");
+	return (~sum) >> 16;
+}
+
+static inline unsigned int
+csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
+		   unsigned int proto, unsigned int sum)
+{
+	__asm__(
+	"adds	%0, %1, %2		@ csum_tcpudp_nofold	\n"
+	"adcs	%0, %0, %3					\n"
+	"adcs	%0, %0, %4					\n"
+	"adcs	%0, %0, %5					\n"
+	"adc	%0, %0, #0"
+	: "=&r"(sum)
+#ifndef __ARMEB__
+	: "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len) << 16), "Ir" (proto << 8)
+#else
+	: "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (proto)
+#endif
+	: "cc");
+	return sum;
+}	
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline unsigned short int
+csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
+		  unsigned int proto, unsigned int sum)
+{
+	__asm__(
+	"adds	%0, %1, %2		@ csum_tcpudp_magic	\n"
+	"adcs	%0, %0, %3					\n"
+	"adcs	%0, %0, %4					\n"
+	"adcs	%0, %0, %5					\n"
+	"adc	%0, %0, #0					\n"
+	"adds	%0, %0, %0, lsl #16				\n"
+	"addcs	%0, %0, #0x10000				\n"
+	"mvn	%0, %0"
+	: "=&r"(sum)
+#ifndef __ARMEB__
+	: "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len)), "Ir" (proto << 8)
+#else
+	: "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (proto)
+#endif
+	: "cc");
+	return sum >> 16;
+}
+
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+static inline unsigned short
+ip_compute_csum(unsigned char * buff, int len)
+{
+	return csum_fold(csum_partial(buff, len, 0));
+}
+
+#define _HAVE_ARCH_IPV6_CSUM
+extern unsigned long
+__csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, __u32 len,
+		__u32 proto, unsigned int sum);
+
+extern __inline__ unsigned short int
+csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, __u32 len,
+		unsigned short proto, unsigned int sum)
+{
+	return csum_fold(__csum_ipv6_magic(saddr, daddr, htonl(len),
+					   htonl(proto), sum));
+}
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/cpu-multi26.h linux-2.4.29-uc1/include/asm-armnommu/cpu-multi26.h
--- linux-2.4.29/include/asm-armnommu/cpu-multi26.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/cpu-multi26.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ *  linux/include/asm-arm/cpu-multi26.h
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASSEMBLY__
+
+#include <asm/page.h>
+
+/* forward-declare task_struct */
+struct task_struct;
+
+/*
+ * Don't change this structure - ASM code
+ * relies on it.
+ */
+extern struct processor {
+	/* check for any bugs */
+	void (*_check_bugs)(void);
+	/* Set up any processor specifics */
+	void (*_proc_init)(void);
+	/* Disable any processor specifics */
+	void (*_proc_fin)(void);
+	/* set the MEMC hardware mappings */
+	void (*_set_pgd)(pgd_t *pgd);
+	/* XCHG */
+	unsigned long (*_xchg_1)(unsigned long x, volatile void *ptr);
+	unsigned long (*_xchg_4)(unsigned long x, volatile void *ptr);
+} processor;
+
+extern const struct processor arm2_processor_functions;
+extern const struct processor arm250_processor_functions;
+extern const struct processor arm3_processor_functions;
+
+#define cpu_check_bugs()			processor._check_bugs()
+#define cpu_proc_init()				processor._proc_init()
+#define cpu_proc_fin()				processor._proc_fin()
+#define cpu_do_idle()				do { } while (0)
+#define cpu_switch_mm(pgd,tsk)			processor._set_pgd(pgd)
+#define cpu_xchg_1(x,ptr)			processor._xchg_1(x,ptr)
+#define cpu_xchg_4(x,ptr)			processor._xchg_4(x,ptr)
+
+extern void cpu_memc_update_all(pgd_t *pgd);
+extern void cpu_memc_update_entry(pgd_t *pgd, unsigned long phys_pte, unsigned long log_addr);
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/cpu-multi32.h linux-2.4.29-uc1/include/asm-armnommu/cpu-multi32.h
--- linux-2.4.29/include/asm-armnommu/cpu-multi32.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/cpu-multi32.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,159 @@
+/*
+ *  linux/include/asm-arm/cpu-multi32.h
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASSEMBLY__
+
+#include <asm/page.h>
+
+/* forward-declare task_struct */
+struct task_struct;
+
+/*
+ * Don't change this structure - ASM code
+ * relies on it.
+ */
+extern struct processor {
+	/* MISC
+	 * get data abort address/flags
+	 */
+	void (*_data_abort)(unsigned long pc);
+	/*
+	 * check for any bugs
+	 */
+	void (*_check_bugs)(void);
+	/*
+	 * Set up any processor specifics
+	 */
+	void (*_proc_init)(void);
+	/*
+	 * Disable any processor specifics
+	 */
+	void (*_proc_fin)(void);
+	/*
+	 * Special stuff for a reset
+	 */
+	volatile void (*reset)(unsigned long addr);
+	/*
+	 * Idle the processor
+	 */
+	int (*_do_idle)(int mode);
+	/*
+	 * Processor architecture specific
+	 */
+	struct {	/* CACHE */
+		/*
+		 * flush all caches
+		 */
+		void (*clean_invalidate_all)(void);
+		/*
+		 * flush a specific page or pages
+		 */
+		void (*clean_invalidate_range)(unsigned long address, unsigned long end, int flags);
+		/*
+		 * flush a page to RAM
+		 */
+		void (*_flush_ram_page)(void *virt_page);
+	} cache;
+
+	struct {	/* D-cache */
+		/*
+		 * invalidate the specified data range
+		 */
+		void (*invalidate_range)(unsigned long start, unsigned long end);
+		/*
+		 * clean specified data range
+		 */
+		void (*clean_range)(unsigned long start, unsigned long end);
+		/*
+		 * obsolete flush cache entry
+		 */
+		void (*clean_page)(void *virt_page);
+		/*
+		 * clean a virtual address range from the
+		 * D-cache without flushing the cache.
+		 */
+		void (*clean_entry)(unsigned long start);
+	} dcache;
+
+	struct {	/* I-cache */
+		/*
+		 * invalidate the I-cache for the specified range
+		 */
+		void (*invalidate_range)(unsigned long start, unsigned long end);
+		/*
+		 * invalidate the I-cache for the specified virtual page
+		 */
+		void (*invalidate_page)(void *virt_page);
+	} icache;
+
+	struct {	/* TLB */
+		/*
+		 * flush all TLBs
+		 */
+		void (*invalidate_all)(void);
+		/*
+		 * flush a specific TLB
+		 */
+		void (*invalidate_range)(unsigned long address, unsigned long end);
+		/*
+		 * flush a specific TLB
+		 */
+		void (*invalidate_page)(unsigned long address, int flags);
+	} tlb;
+
+	struct {	/* PageTable */
+		/*
+		 * Set the page table
+		 */
+		void (*set_pgd)(unsigned long pgd_phys);
+		/*
+		 * Set a PMD (handling IMP bit 4)
+		 */
+		void (*set_pmd)(pmd_t *pmdp, pmd_t pmd);
+		/*
+		 * Set a PTE
+		 */
+		void (*set_pte)(pte_t *ptep, pte_t pte);
+	} pgtable;
+} processor;
+
+extern const struct processor arm6_processor_functions;
+extern const struct processor arm7_processor_functions;
+extern const struct processor sa110_processor_functions;
+
+#define cpu_data_abort(pc)			processor._data_abort(pc)
+#define cpu_check_bugs()			processor._check_bugs()
+#define cpu_proc_init()				processor._proc_init()
+#define cpu_proc_fin()				processor._proc_fin()
+#define cpu_reset(addr)				processor.reset(addr)
+#define cpu_do_idle(mode)			processor._do_idle(mode)
+
+#define cpu_cache_clean_invalidate_all()	processor.cache.clean_invalidate_all()
+#define cpu_cache_clean_invalidate_range(s,e,f)	processor.cache.clean_invalidate_range(s,e,f)
+#define cpu_flush_ram_page(vp)			processor.cache._flush_ram_page(vp)
+
+#define cpu_dcache_clean_page(vp)		processor.dcache.clean_page(vp)
+#define cpu_dcache_clean_entry(addr)		processor.dcache.clean_entry(addr)
+#define cpu_dcache_clean_range(s,e)		processor.dcache.clean_range(s,e)
+#define cpu_dcache_invalidate_range(s,e)	processor.dcache.invalidate_range(s,e)
+
+#define cpu_icache_invalidate_range(s,e)	processor.icache.invalidate_range(s,e)
+#define cpu_icache_invalidate_page(vp)		processor.icache.invalidate_page(vp)
+
+#define cpu_tlb_invalidate_all()		processor.tlb.invalidate_all()
+#define cpu_tlb_invalidate_range(s,e)		processor.tlb.invalidate_range(s,e)
+#define cpu_tlb_invalidate_page(vp,f)		processor.tlb.invalidate_page(vp,f)
+
+#define cpu_set_pgd(pgd)			processor.pgtable.set_pgd(pgd)
+#define cpu_set_pmd(pmdp, pmd)			processor.pgtable.set_pmd(pmdp, pmd)
+#define cpu_set_pte(ptep, pte)			processor.pgtable.set_pte(ptep, pte)
+
+#define cpu_switch_mm(pgd,tsk)			cpu_set_pgd(__virt_to_phys(pgd))
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/cpu-single.h linux-2.4.29-uc1/include/asm-armnommu/cpu-single.h
--- linux-2.4.29/include/asm-armnommu/cpu-single.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/cpu-single.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,89 @@
+/*
+ *  linux/include/asm-arm/cpu-single.h
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/*
+ * Single CPU
+ */
+#ifdef __STDC__
+#define __cpu_fn(name,x)	cpu_##name##x
+#else
+#define __cpu_fn(name,x)	cpu_/**/name/**/x
+#endif
+#define cpu_fn(name,x)		__cpu_fn(name,x)
+
+/*
+ * If we are supporting multiple CPUs, then we must use a table of
+ * function pointers for this lot.  Otherwise, we can optimise the
+ * table away.
+ */
+#define cpu_data_abort			cpu_fn(CPU_NAME,_data_abort)
+#define cpu_check_bugs			cpu_fn(CPU_NAME,_check_bugs)
+#define cpu_proc_init			cpu_fn(CPU_NAME,_proc_init)
+#define cpu_proc_fin			cpu_fn(CPU_NAME,_proc_fin)
+#define cpu_reset			cpu_fn(CPU_NAME,_reset)
+#define cpu_do_idle			cpu_fn(CPU_NAME,_do_idle)
+
+#define cpu_cache_clean_invalidate_all	cpu_fn(CPU_NAME,_cache_clean_invalidate_all)
+#define cpu_cache_clean_invalidate_range cpu_fn(CPU_NAME,_cache_clean_invalidate_range)
+#define cpu_flush_ram_page		cpu_fn(CPU_NAME,_flush_ram_page)
+
+#define cpu_dcache_invalidate_range	cpu_fn(CPU_NAME,_dcache_invalidate_range)
+#define cpu_dcache_clean_range		cpu_fn(CPU_NAME,_dcache_clean_range)
+#define cpu_dcache_clean_page		cpu_fn(CPU_NAME,_dcache_clean_page)
+#define cpu_dcache_clean_entry		cpu_fn(CPU_NAME,_dcache_clean_entry)
+
+#define cpu_icache_invalidate_range	cpu_fn(CPU_NAME,_icache_invalidate_range)
+#define cpu_icache_invalidate_page	cpu_fn(CPU_NAME,_icache_invalidate_page)
+
+#define cpu_tlb_invalidate_all		cpu_fn(CPU_NAME,_tlb_invalidate_all)
+#define cpu_tlb_invalidate_range	cpu_fn(CPU_NAME,_tlb_invalidate_range)
+#define cpu_tlb_invalidate_page		cpu_fn(CPU_NAME,_tlb_invalidate_page)
+
+#define cpu_set_pgd			cpu_fn(CPU_NAME,_set_pgd)
+#define cpu_set_pmd			cpu_fn(CPU_NAME,_set_pmd)
+#define cpu_set_pte			cpu_fn(CPU_NAME,_set_pte)
+
+#ifndef __ASSEMBLY__
+
+#include <asm/page.h>
+
+/* forward declare task_struct */
+struct task_struct;
+
+/* declare all the functions as extern */
+extern void cpu_data_abort(unsigned long pc);
+extern void cpu_check_bugs(void);
+extern void cpu_proc_init(void);
+extern void cpu_proc_fin(void);
+extern int cpu_do_idle(int mode);
+
+extern void cpu_cache_clean_invalidate_all(void);
+extern void cpu_cache_clean_invalidate_range(unsigned long address, unsigned long end, int flags);
+extern void cpu_flush_ram_page(void *virt_page);
+
+extern void cpu_dcache_invalidate_range(unsigned long start, unsigned long end);
+extern void cpu_dcache_clean_range(unsigned long start, unsigned long end);
+extern void cpu_dcache_clean_page(void *virt_page);
+extern void cpu_dcache_clean_entry(unsigned long address);
+
+extern void cpu_icache_invalidate_range(unsigned long start, unsigned long end);
+extern void cpu_icache_invalidate_page(void *virt_page);
+
+extern void cpu_tlb_invalidate_all(void);
+extern void cpu_tlb_invalidate_range(unsigned long address, unsigned long end);
+extern void cpu_tlb_invalidate_page(unsigned long address, int flags);
+
+extern void cpu_set_pgd(unsigned long pgd_phys);
+extern void cpu_set_pmd(pmd_t *pmdp, pmd_t pmd);
+extern void cpu_set_pte(pte_t *ptep, pte_t pte);
+extern volatile void cpu_reset(unsigned long addr);
+
+#define cpu_switch_mm(pgd,tsk) cpu_set_pgd(__virt_to_phys(pgd))
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/current.h linux-2.4.29-uc1/include/asm-armnommu/current.h
--- linux-2.4.29/include/asm-armnommu/current.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/current.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,14 @@
+#ifndef _ASMARM_CURRENT_H
+#define _ASMARM_CURRENT_H
+
+static inline struct task_struct *get_current(void) __attribute__ (( __const__ ));
+
+static inline struct task_struct *get_current(void)
+{
+	register unsigned long sp asm ("sp");
+	return (struct task_struct *)(sp & ~0x1fff);
+}
+
+#define current (get_current())
+
+#endif /* _ASMARM_CURRENT_H */
diff -urN linux-2.4.29/include/asm-armnommu/dec21285.h linux-2.4.29-uc1/include/asm-armnommu/dec21285.h
--- linux-2.4.29/include/asm-armnommu/dec21285.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/dec21285.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,144 @@
+/*
+ * include/asm-arm/dec21285.h
+ *
+ * Copyright (C) 1998 Russell King
+ *
+ * DC21285 registers
+ */
+#define DC21285_PCI_IACK		0x79000000
+#define DC21285_ARMCSR_BASE		0x42000000
+#define DC21285_PCI_TYPE_0_CONFIG	0x7b000000
+#define DC21285_PCI_TYPE_1_CONFIG	0x7a000000
+#define DC21285_OUTBOUND_WRITE_FLUSH	0x78000000
+#define DC21285_FLASH			0x41000000
+#define DC21285_PCI_IO			0x7c000000
+#define DC21285_PCI_MEM			0x80000000
+
+#include <linux/config.h>
+#ifndef __ASSEMBLY__
+#include <asm/arch/hardware.h>
+#define DC21285_IO(x)		((volatile unsigned long *)(ARMCSR_BASE+(x)))
+#else
+#define DC21285_IO(x)		(x)
+#endif
+
+#define CSR_PCICMD		DC21285_IO(0x0004)
+#define CSR_CLASSREV		DC21285_IO(0x0008)
+#define CSR_PCICACHELINESIZE	DC21285_IO(0x000c)
+#define CSR_PCICSRBASE		DC21285_IO(0x0010)
+#define CSR_PCICSRIOBASE	DC21285_IO(0x0014)
+#define CSR_PCISDRAMBASE	DC21285_IO(0x0018)
+#define CSR_PCIROMBASE		DC21285_IO(0x0030)
+#define CSR_MBOX0		DC21285_IO(0x0050)
+#define CSR_MBOX1		DC21285_IO(0x0054)
+#define CSR_MBOX2		DC21285_IO(0x0058)
+#define CSR_MBOX3		DC21285_IO(0x005c)
+#define CSR_DOORBELL		DC21285_IO(0x0060)
+#define CSR_DOORBELL_SETUP	DC21285_IO(0x0064)
+#define CSR_ROMWRITEREG		DC21285_IO(0x0068)
+#define CSR_CSRBASEMASK		DC21285_IO(0x00f8)
+#define CSR_CSRBASEOFFSET	DC21285_IO(0x00fc)
+#define CSR_SDRAMBASEMASK	DC21285_IO(0x0100)
+#define CSR_SDRAMBASEOFFSET	DC21285_IO(0x0104)
+#define CSR_ROMBASEMASK		DC21285_IO(0x0108)
+#define CSR_SDRAMTIMING		DC21285_IO(0x010c)
+#define CSR_SDRAMADDRSIZE0	DC21285_IO(0x0110)
+#define CSR_SDRAMADDRSIZE1	DC21285_IO(0x0114)
+#define CSR_SDRAMADDRSIZE2	DC21285_IO(0x0118)
+#define CSR_SDRAMADDRSIZE3	DC21285_IO(0x011c)
+#define CSR_I2O_INFREEHEAD	DC21285_IO(0x0120)
+#define CSR_I2O_INPOSTTAIL	DC21285_IO(0x0124)
+#define CSR_I2O_OUTPOSTHEAD	DC21285_IO(0x0128)
+#define CSR_I2O_OUTFREETAIL	DC21285_IO(0x012c)
+#define CSR_I2O_INFREECOUNT	DC21285_IO(0x0130)
+#define CSR_I2O_OUTPOSTCOUNT	DC21285_IO(0x0134)
+#define CSR_I2O_INPOSTCOUNT	DC21285_IO(0x0138)
+#define CSR_SA110_CNTL		DC21285_IO(0x013c)
+#define SA110_CNTL_INITCMPLETE		(1 << 0)
+#define SA110_CNTL_ASSERTSERR		(1 << 1)
+#define SA110_CNTL_RXSERR		(1 << 3)
+#define SA110_CNTL_SA110DRAMPARITY	(1 << 4)
+#define SA110_CNTL_PCISDRAMPARITY	(1 << 5)
+#define SA110_CNTL_DMASDRAMPARITY	(1 << 6)
+#define SA110_CNTL_DISCARDTIMER		(1 << 8)
+#define SA110_CNTL_PCINRESET		(1 << 9)
+#define SA110_CNTL_I2O_256		(0 << 10)
+#define SA110_CNTL_I20_512		(1 << 10)
+#define SA110_CNTL_I2O_1024		(2 << 10)
+#define SA110_CNTL_I2O_2048		(3 << 10)
+#define SA110_CNTL_I2O_4096		(4 << 10)
+#define SA110_CNTL_I2O_8192		(5 << 10)
+#define SA110_CNTL_I2O_16384		(6 << 10)
+#define SA110_CNTL_I2O_32768		(7 << 10)
+#define SA110_CNTL_WATCHDOG		(1 << 13)
+#define SA110_CNTL_ROMWIDTH_UNDEF	(0 << 14)
+#define SA110_CNTL_ROMWIDTH_16		(1 << 14)
+#define SA110_CNTL_ROMWIDTH_32		(2 << 14)
+#define SA110_CNTL_ROMWIDTH_8		(3 << 14)
+#define SA110_CNTL_ROMACCESSTIME(x)	((x)<<16)
+#define SA110_CNTL_ROMBURSTTIME(x)	((x)<<20)
+#define SA110_CNTL_ROMTRISTATETIME(x)	((x)<<24)
+#define SA110_CNTL_XCSDIR(x)		((x)<<28)
+#define SA110_CNTL_PCICFN		(1 << 31)
+
+/*
+ * footbridge_cfn_mode() is used when we want
+ * to check whether we are the central function
+ */
+#define __footbridge_cfn_mode() (*CSR_SA110_CNTL & SA110_CNTL_PCICFN)
+#if defined(CONFIG_FOOTBRIDGE_HOST) && defined(CONFIG_FOOTBRIDGE_ADDIN)
+#define footbridge_cfn_mode() __footbridge_cfn_mode()
+#elif defined(CONFIG_FOOTBRIDGE_HOST)
+#define footbridge_cfn_mode() (1)
+#else
+#define footbridge_cfn_mode() (0)
+#endif
+
+#define CSR_PCIADDR_EXTN	DC21285_IO(0x0140)
+#define CSR_PREFETCHMEMRANGE	DC21285_IO(0x0144)
+#define CSR_XBUS_CYCLE		DC21285_IO(0x0148)
+#define CSR_XBUS_IOSTROBE	DC21285_IO(0x014c)
+#define CSR_DOORBELL_PCI	DC21285_IO(0x0150)
+#define CSR_DOORBELL_SA110	DC21285_IO(0x0154)
+#define CSR_UARTDR		DC21285_IO(0x0160)
+#define CSR_RXSTAT		DC21285_IO(0x0164)
+#define CSR_H_UBRLCR		DC21285_IO(0x0168)
+#define CSR_M_UBRLCR		DC21285_IO(0x016c)
+#define CSR_L_UBRLCR		DC21285_IO(0x0170)
+#define CSR_UARTCON		DC21285_IO(0x0174)
+#define CSR_UARTFLG		DC21285_IO(0x0178)
+#define CSR_IRQ_STATUS		DC21285_IO(0x0180)
+#define CSR_IRQ_RAWSTATUS	DC21285_IO(0x0184)
+#define CSR_IRQ_ENABLE		DC21285_IO(0x0188)
+#define CSR_IRQ_DISABLE		DC21285_IO(0x018c)
+#define CSR_IRQ_SOFT		DC21285_IO(0x0190)
+#define CSR_FIQ_STATUS		DC21285_IO(0x0280)
+#define CSR_FIQ_RAWSTATUS	DC21285_IO(0x0284)
+#define CSR_FIQ_ENABLE		DC21285_IO(0x0288)
+#define CSR_FIQ_DISABLE		DC21285_IO(0x028c)
+#define CSR_FIQ_SOFT		DC21285_IO(0x0290)
+#define CSR_TIMER1_LOAD		DC21285_IO(0x0300)
+#define CSR_TIMER1_VALUE	DC21285_IO(0x0304)
+#define CSR_TIMER1_CNTL		DC21285_IO(0x0308)
+#define CSR_TIMER1_CLR		DC21285_IO(0x030c)
+#define CSR_TIMER2_LOAD		DC21285_IO(0x0320)
+#define CSR_TIMER2_VALUE	DC21285_IO(0x0324)
+#define CSR_TIMER2_CNTL		DC21285_IO(0x0328)
+#define CSR_TIMER2_CLR		DC21285_IO(0x032c)
+#define CSR_TIMER3_LOAD		DC21285_IO(0x0340)
+#define CSR_TIMER3_VALUE	DC21285_IO(0x0344)
+#define CSR_TIMER3_CNTL		DC21285_IO(0x0348)
+#define CSR_TIMER3_CLR		DC21285_IO(0x034c)
+#define CSR_TIMER4_LOAD		DC21285_IO(0x0360)
+#define CSR_TIMER4_VALUE	DC21285_IO(0x0364)
+#define CSR_TIMER4_CNTL		DC21285_IO(0x0368)
+#define CSR_TIMER4_CLR		DC21285_IO(0x036c)
+
+#define TIMER_CNTL_ENABLE	(1 << 7)
+#define TIMER_CNTL_AUTORELOAD	(1 << 6)
+#define TIMER_CNTL_DIV1		(0)
+#define TIMER_CNTL_DIV16	(1 << 2)
+#define TIMER_CNTL_DIV256	(2 << 2)
+#define TIMER_CNTL_CNTEXT	(3 << 2)
+
+
diff -urN linux-2.4.29/include/asm-armnommu/delay.h linux-2.4.29-uc1/include/asm-armnommu/delay.h
--- linux-2.4.29/include/asm-armnommu/delay.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/delay.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,33 @@
+#ifndef __ASM_ARM_DELAY_H
+#define __ASM_ARM_DELAY_H
+
+/*
+ * Copyright (C) 1995 Russell King
+ *
+ * Delay routines, using a pre-computed "loops_per_second" value.
+ */
+
+extern void __delay(int loops);
+
+/*
+ * division by multiplication: you don't have to worry about
+ * loss of precision.
+ *
+ * Use only for very small delays ( < 1 msec).  Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays.  This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)
+ */
+extern void udelay(unsigned long usecs);
+
+extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c)
+{
+	return a * b / c;
+}
+
+#define ndelay(nsecs) udelay((nsecs) * 5)
+	
+
+#endif /* defined(_ARM_DELAY_H) */
+
diff -urN linux-2.4.29/include/asm-armnommu/div64.h linux-2.4.29-uc1/include/asm-armnommu/div64.h
--- linux-2.4.29/include/asm-armnommu/div64.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/div64.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-generic/div64.h>
diff -urN linux-2.4.29/include/asm-armnommu/dma.h linux-2.4.29-uc1/include/asm-armnommu/dma.h
--- linux-2.4.29/include/asm-armnommu/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,132 @@
+#ifndef __ASM_ARM_DMA_H
+#define __ASM_ARM_DMA_H
+
+typedef unsigned int dmach_t;
+
+#include <linux/config.h>
+#include <linux/spinlock.h>
+#include <asm/system.h>
+#include <asm/memory.h>
+#include <asm/scatterlist.h>
+#include <asm/arch/dma.h>
+
+/*
+ * DMA modes
+ */
+typedef unsigned int dmamode_t;
+
+#define DMA_MODE_MASK	3
+
+#define DMA_MODE_READ	 0
+#define DMA_MODE_WRITE	 1
+#define DMA_MODE_CASCADE 2
+#define DMA_AUTOINIT	 4
+
+extern spinlock_t  dma_spin_lock;
+
+extern __inline__ unsigned long claim_dma_lock(void)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&dma_spin_lock, flags);
+	return flags;
+}
+
+extern __inline__ void release_dma_lock(unsigned long flags)
+{
+	spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+/* Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ */
+#define clear_dma_ff(channel)
+
+/* Set only the page register bits of the transfer address.
+ *
+ * NOTE: This is an architecture specific function, and should
+ *       be hidden from the drivers
+ */
+extern void set_dma_page(dmach_t channel, char pagenr);
+
+/* Request a DMA channel
+ *
+ * Some architectures may need to do allocate an interrupt
+ */
+extern int  request_dma(dmach_t channel, const char * device_id);
+
+/* Free a DMA channel
+ *
+ * Some architectures may need to do free an interrupt
+ */
+extern void free_dma(dmach_t channel);
+
+/* Enable DMA for this channel
+ *
+ * On some architectures, this may have other side effects like
+ * enabling an interrupt and setting the DMA registers.
+ */
+extern void enable_dma(dmach_t channel);
+
+/* Disable DMA for this channel
+ *
+ * On some architectures, this may have other side effects like
+ * disabling an interrupt or whatever.
+ */
+extern void disable_dma(dmach_t channel);
+
+/* Set the DMA scatter gather list for this channel
+ *
+ * This should not be called if a DMA channel is enabled,
+ * especially since some DMA architectures don't update the
+ * DMA address immediately, but defer it to the enable_dma().
+ */
+extern void set_dma_sg(dmach_t channel, struct scatterlist *sg, int nr_sg);
+
+/* Set the DMA address for this channel
+ *
+ * This should not be called if a DMA channel is enabled,
+ * especially since some DMA architectures don't update the
+ * DMA address immediately, but defer it to the enable_dma().
+ */
+extern void set_dma_addr(dmach_t channel, unsigned long physaddr);
+
+/* Set the DMA byte count for this channel
+ *
+ * This should not be called if a DMA channel is enabled,
+ * especially since some DMA architectures don't update the
+ * DMA count immediately, but defer it to the enable_dma().
+ */
+extern void set_dma_count(dmach_t channel, unsigned long count);
+
+/* Set the transfer direction for this channel
+ *
+ * This should not be called if a DMA channel is enabled,
+ * especially since some DMA architectures don't update the
+ * DMA transfer direction immediately, but defer it to the
+ * enable_dma().
+ */
+extern void set_dma_mode(dmach_t channel, dmamode_t mode);
+
+/* Set the transfer speed for this channel
+ */
+extern void set_dma_speed(dmach_t channel, int cycle_ns);
+
+/* Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * If called before the channel has been used, it may return 1.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ */
+extern int  get_dma_residue(dmach_t channel);
+
+#ifndef NO_DMA
+#define NO_DMA	255
+#endif
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy    (0)
+#endif
+
+#endif /* _ARM_DMA_H */
diff -urN linux-2.4.29/include/asm-armnommu/ecard.h linux-2.4.29-uc1/include/asm-armnommu/ecard.h
--- linux-2.4.29/include/asm-armnommu/ecard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/ecard.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,251 @@
+/*
+ * linux/include/asm-arm/ecard.h
+ *
+ * definitions for expansion cards
+ *
+ * This is a new system as from Linux 1.2.3
+ *
+ * Changelog:
+ *  11-12-1996	RMK	Further minor improvements
+ *  12-09-1997	RMK	Added interrupt enable/disable for card level
+ *
+ * Reference: Acorns Risc OS 3 Programmers Reference Manuals.
+ */
+
+#ifndef __ASM_ECARD_H
+#define __ASM_ECARD_H
+
+/*
+ * Currently understood cards (but not necessarily
+ * supported):
+ *                        Manufacturer  Product ID
+ */
+#define MANU_ACORN		0x0000
+#define PROD_ACORN_SCSI			0x0002
+#define PROD_ACORN_ETHER1		0x0003
+#define PROD_ACORN_MFM			0x000b
+
+#define MANU_ANT2		0x0011
+#define PROD_ANT_ETHER3			0x00a4
+
+#define MANU_ATOMWIDE		0x0017
+#define PROD_ATOMWIDE_3PSERIAL		0x0090
+
+#define MANU_IRLAM_INSTRUMENTS	0x001f
+#define MANU_IRLAM_INSTRUMENTS_ETHERN	0x5678
+
+#define MANU_OAK		0x0021
+#define PROD_OAK_SCSI			0x0058
+
+#define MANU_MORLEY		0x002b
+#define PROD_MORLEY_SCSI_UNCACHED	0x0067
+
+#define MANU_CUMANA		0x003a
+#define PROD_CUMANA_SCSI_2		0x003a
+#define PROD_CUMANA_SCSI_1		0x00a0
+
+#define MANU_ICS		0x003c
+#define PROD_ICS_IDE			0x00ae
+
+#define MANU_ICS2		0x003d
+#define PROD_ICS2_IDE			0x00ae
+
+#define MANU_SERPORT		0x003f
+#define PROD_SERPORT_DSPORT		0x00b9
+
+#define MANU_I3			0x0046
+#define PROD_I3_ETHERLAN500		0x00d4
+#define PROD_I3_ETHERLAN600		0x00ec
+#define PROD_I3_ETHERLAN600A		0x011e
+
+#define MANU_ANT		0x0053
+#define PROD_ANT_ETHERM			0x00d8
+#define PROD_ANT_ETHERB			0x00e4
+
+#define MANU_ALSYSTEMS		0x005b
+#define PROD_ALSYS_SCSIATAPI		0x0107
+
+#define MANU_MCS		0x0063
+#define PROD_MCS_CONNECT32		0x0125
+
+#define MANU_EESOX		0x0064
+#define PROD_EESOX_SCSI2		0x008c
+
+#define MANU_YELLOWSTONE	0x0096
+#define PROD_YELLOWSTONE_RAPIDE32	0x0120
+
+#ifdef ECARD_C
+#define CONST
+#else
+#define CONST const
+#endif
+
+#define MAX_ECARDS	9
+
+typedef enum {				/* Cards address space		*/
+	ECARD_IOC,
+	ECARD_MEMC,
+	ECARD_EASI
+} card_type_t;
+
+typedef enum {				/* Speed for ECARD_IOC space	*/
+	ECARD_SLOW	 = 0,
+	ECARD_MEDIUM	 = 1,
+	ECARD_FAST	 = 2,
+	ECARD_SYNC	 = 3
+} card_speed_t;
+
+typedef struct  {			/* Card ID structure		*/
+	unsigned short manufacturer;
+	unsigned short product;
+} card_ids;
+
+struct in_ecid {			/* Packed card ID information	*/
+	unsigned short	product;	/* Product code			*/
+	unsigned short	manufacturer;	/* Manufacturer code		*/
+	unsigned char	id:4;		/* Simple ID			*/
+	unsigned char	cd:1;		/* Chunk dir present		*/
+	unsigned char	is:1;		/* Interrupt status pointers	*/
+	unsigned char	w:2;		/* Width			*/
+	unsigned char	country;	/* Country			*/
+	unsigned char	irqmask;	/* IRQ mask			*/
+	unsigned char	fiqmask;	/* FIQ mask			*/
+	unsigned long	irqoff;		/* IRQ offset			*/
+	unsigned long	fiqoff;		/* FIQ offset			*/
+};
+
+typedef struct expansion_card ecard_t;
+typedef unsigned long *loader_t;
+
+typedef struct {			/* Card handler routines	*/
+	void (*irqenable)(ecard_t *ec, int irqnr);
+	void (*irqdisable)(ecard_t *ec, int irqnr);
+	int  (*irqpending)(ecard_t *ec);
+	void (*fiqenable)(ecard_t *ec, int fiqnr);
+	void (*fiqdisable)(ecard_t *ec, int fiqnr);
+	int  (*fiqpending)(ecard_t *ec);
+} expansioncard_ops_t;
+
+/*
+ * This contains all the info needed on an expansion card
+ */
+struct expansion_card {
+	struct expansion_card  *next;
+
+	/* Public data */
+	volatile unsigned char *irqaddr;	/* address of IRQ register	*/
+	volatile unsigned char *fiqaddr;	/* address of FIQ register	*/
+	unsigned char		irqmask;	/* IRQ mask			*/
+	unsigned char		fiqmask;	/* FIQ mask			*/
+	unsigned char  		claimed;	/* Card claimed?		*/
+
+	void			*irq_data;	/* Data for use for IRQ by card	*/
+	void			*fiq_data;	/* Data for use for FIQ by card	*/
+	expansioncard_ops_t	*ops;		/* Enable/Disable Ops for card	*/
+
+	CONST unsigned int	slot_no;	/* Slot number			*/
+	CONST unsigned int	dma;		/* DMA number (for request_dma)	*/
+	CONST unsigned int	irq;		/* IRQ number (for request_irq)	*/
+	CONST unsigned int	fiq;		/* FIQ number (for request_irq)	*/
+	CONST card_type_t	type;		/* Type of card			*/
+	CONST struct in_ecid	cid;		/* Card Identification		*/
+
+	/* Private internal data */
+	const char		*card_desc;	/* Card description		*/
+	CONST unsigned int	podaddr;	/* Base Linux address for card	*/
+	CONST loader_t		loader;		/* loader program */
+};
+
+struct in_chunk_dir {
+	unsigned int start_offset;
+	union {
+		unsigned char string[256];
+		unsigned char data[1];
+	} d;
+};
+
+/*
+ * ecard_claim: claim an expansion card entry
+ */
+#define ecard_claim(ec) ((ec)->claimed = 1)
+
+/*
+ * ecard_release: release an expansion card entry
+ */
+#define ecard_release(ec) ((ec)->claimed = 0)
+
+/*
+ * Start finding cards from the top of the list
+ */
+extern void ecard_startfind (void);
+
+/*
+ * Find an expansion card with the correct cid, product and manufacturer code
+ */
+extern struct expansion_card *ecard_find (int cid, const card_ids *ids);
+ 
+/*
+ * Read a chunk from an expansion card
+ * cd : where to put read data
+ * ec : expansion card info struct
+ * id : id number to find
+ * num: (n+1)'th id to find.
+ */
+extern int ecard_readchunk (struct in_chunk_dir *cd, struct expansion_card *ec, int id, int num);
+
+/*
+ * Obtain the address of a card
+ */
+extern unsigned int ecard_address (struct expansion_card *ec, card_type_t card_type, card_speed_t speed);
+
+#ifdef ECARD_C
+/* Definitions internal to ecard.c - for it's use only!!
+ *
+ * External expansion card header as read from the card
+ */
+struct ex_ecid {
+	unsigned char	r_irq:1;
+	unsigned char	r_zero:1;
+	unsigned char	r_fiq:1;
+	unsigned char	r_id:4;
+	unsigned char	r_a:1;
+
+	unsigned char	r_cd:1;
+	unsigned char	r_is:1;
+	unsigned char	r_w:2;
+	unsigned char	r_r1:4;
+
+	unsigned char	r_r2:8;
+
+	unsigned char	r_prod[2];
+
+	unsigned char	r_manu[2];
+
+	unsigned char	r_country;
+
+	unsigned char	r_irqmask;
+	unsigned char	r_irqoff[3];
+
+	unsigned char	r_fiqmask;
+	unsigned char	r_fiqoff[3];
+};
+
+/*
+ * Chunk directory entry as read from the card
+ */
+struct ex_chunk_dir {
+	unsigned char r_id;
+	unsigned char r_len[3];
+	unsigned long r_start;
+	union {
+		char string[256];
+		char data[1];
+	} d;
+#define c_id(x)		((x)->r_id)
+#define c_len(x)	((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16))
+#define c_start(x)	((x)->r_start)
+};
+
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/elf.h linux-2.4.29-uc1/include/asm-armnommu/elf.h
--- linux-2.4.29/include/asm-armnommu/elf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/elf.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,75 @@
+#ifndef __ASMARM_ELF_H
+#define __ASMARM_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+#include <asm/proc/elf.h>
+#include <asm/procinfo.h>
+
+typedef unsigned long elf_greg_t;
+typedef unsigned long elf_freg_t[3];
+
+#define EM_ARM	40
+#define EF_ARM_APCS26 0x08
+
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct { void *null; } elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ( ((x)->e_machine == EM_ARM) && (ELF_PROC_OK((x))) )
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#ifdef __ARMEB__
+#define ELF_DATA	ELFDATA2MSB;
+#else
+#define ELF_DATA	ELFDATA2LSB;
+#endif
+#define ELF_ARCH	EM_ARM
+
+#define USE_ELF_CORE_DUMP
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#define ELF_ET_DYN_BASE	(2 * TASK_SIZE / 3)
+
+/* When the program starts, a1 contains a pointer to a function to be 
+   registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
+   have no such handler.  */
+#define ELF_PLAT_INIT(_r)	(_r)->ARM_r0 = 0
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports. */
+
+extern unsigned int elf_hwcap;
+#define ELF_HWCAP	(elf_hwcap)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo. */
+
+/* For now we just provide a fairly general string that describes the
+   processor family.  This could be made more specific later if someone
+   implemented optimisations that require it.  26-bit CPUs give you
+   "v1l" for ARM2 (no SWP) and "v2l" for anything else (ARM1 isn't
+   supported).  32-bit CPUs give you "v3[lb]" for anything based on an
+   ARM6 or ARM7 core and "armv4[lb]" for anything based on a StrongARM-1
+   core.  */
+
+#define ELF_PLATFORM_SIZE 8
+extern char elf_platform[];
+#define ELF_PLATFORM	(elf_platform)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/errno.h linux-2.4.29-uc1/include/asm-armnommu/errno.h
--- linux-2.4.29/include/asm-armnommu/errno.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/errno.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,132 @@
+#ifndef _ARM_ERRNO_H
+#define _ARM_ERRNO_H
+
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Arg list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	EDEADLK		35	/* Resource deadlock would occur */
+#define	ENAMETOOLONG	36	/* File name too long */
+#define	ENOLCK		37	/* No record locks available */
+#define	ENOSYS		38	/* Function not implemented */
+#define	ENOTEMPTY	39	/* Directory not empty */
+#define	ELOOP		40	/* Too many symbolic links encountered */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	ENOMSG		42	/* No message of desired type */
+#define	EIDRM		43	/* Identifier removed */
+#define	ECHRNG		44	/* Channel number out of range */
+#define	EL2NSYNC	45	/* Level 2 not synchronized */
+#define	EL3HLT		46	/* Level 3 halted */
+#define	EL3RST		47	/* Level 3 reset */
+#define	ELNRNG		48	/* Link number out of range */
+#define	EUNATCH		49	/* Protocol driver not attached */
+#define	ENOCSI		50	/* No CSI structure available */
+#define	EL2HLT		51	/* Level 2 halted */
+#define	EBADE		52	/* Invalid exchange */
+#define	EBADR		53	/* Invalid request descriptor */
+#define	EXFULL		54	/* Exchange full */
+#define	ENOANO		55	/* No anode */
+#define	EBADRQC		56	/* Invalid request code */
+#define	EBADSLT		57	/* Invalid slot */
+
+#define	EDEADLOCK	EDEADLK
+
+#define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
+#define	EMULTIHOP	72	/* Multihop attempted */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EBADMSG		74	/* Not a data message */
+#define	EOVERFLOW	75	/* Value too large for defined data type */
+#define	ENOTUNIQ	76	/* Name not unique on network */
+#define	EBADFD		77	/* File descriptor in bad state */
+#define	EREMCHG		78	/* Remote address changed */
+#define	ELIBACC		79	/* Can not access a needed shared library */
+#define	ELIBBAD		80	/* Accessing a corrupted shared library */
+#define	ELIBSCN		81	/* .lib section in a.out corrupted */
+#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	EILSEQ		84	/* Illegal byte sequence */
+#define	ERESTART	85	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUSERS		87	/* Too many users */
+#define	ENOTSOCK	88	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	89	/* Destination address required */
+#define	EMSGSIZE	90	/* Message too long */
+#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	92	/* Protocol not available */
+#define	EPROTONOSUPPORT	93	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
+#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	96	/* Protocol family not supported */
+#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
+#define	EADDRINUSE	98	/* Address already in use */
+#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
+#define	ENETDOWN	100	/* Network is down */
+#define	ENETUNREACH	101	/* Network is unreachable */
+#define	ENETRESET	102	/* Network dropped connection because of reset */
+#define	ECONNABORTED	103	/* Software caused connection abort */
+#define	ECONNRESET	104	/* Connection reset by peer */
+#define	ENOBUFS		105	/* No buffer space available */
+#define	EISCONN		106	/* Transport endpoint is already connected */
+#define	ENOTCONN	107	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
+#define	ETIMEDOUT	110	/* Connection timed out */
+#define	ECONNREFUSED	111	/* Connection refused */
+#define	EHOSTDOWN	112	/* Host is down */
+#define	EHOSTUNREACH	113	/* No route to host */
+#define	EALREADY	114	/* Operation already in progress */
+#define	EINPROGRESS	115	/* Operation now in progress */
+#define	ESTALE		116	/* Stale NFS file handle */
+#define	EUCLEAN		117	/* Structure needs cleaning */
+#define	ENOTNAM		118	/* Not a XENIX named type file */
+#define	ENAVAIL		119	/* No XENIX semaphores available */
+#define	EISNAM		120	/* Is a named type file */
+#define	EREMOTEIO	121	/* Remote I/O error */
+#define	EDQUOT		122	/* Quota exceeded */
+
+#define	ENOMEDIUM	123	/* No medium found */
+#define	EMEDIUMTYPE	124	/* Wrong medium type */
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/fcntl.h linux-2.4.29-uc1/include/asm-armnommu/fcntl.h
--- linux-2.4.29/include/asm-armnommu/fcntl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/fcntl.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,86 @@
+#ifndef _ARM_FCNTL_H
+#define _ARM_FCNTL_H
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	   0003
+#define O_RDONLY	     00
+#define O_WRONLY	     01
+#define O_RDWR		     02
+#define O_CREAT		   0100	/* not fcntl */
+#define O_EXCL		   0200	/* not fcntl */
+#define O_NOCTTY	   0400	/* not fcntl */
+#define O_TRUNC		  01000	/* not fcntl */
+#define O_APPEND	  02000
+#define O_NONBLOCK	  04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC		 010000
+#define FASYNC		 020000	/* fcntl, for BSD compatibility */
+#define O_DIRECTORY	 040000	/* must be a directory */
+#define O_NOFOLLOW	0100000	/* don't follow links */
+#define O_DIRECT	0200000	/* direct disk access hint - currently ignored */
+#define O_LARGEFILE	0400000
+
+#define F_DUPFD		0	/* dup */
+#define F_GETFD		1	/* get close_on_exec */
+#define F_SETFD		2	/* set/clear close_on_exec */
+#define F_GETFL		3	/* get file->f_flags */
+#define F_SETFL		4	/* set file->f_flags */
+#define F_GETLK		5
+#define F_SETLK		6
+#define F_SETLKW	7
+
+#define F_SETOWN	8	/*  for sockets. */
+#define F_GETOWN	9	/*  for sockets. */
+#define F_SETSIG	10	/*  for sockets. */
+#define F_GETSIG	11	/*  for sockets. */
+
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK		0
+#define F_WRLCK		1
+#define F_UNLCK		2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+/* for leases */
+#define F_INPROGRESS	16
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* or'd with one of the above to prevent
+				   blocking */
+#define LOCK_UN		8	/* remove lock */
+
+#define LOCK_MAND	32	/* This is a mandatory flock */
+#define LOCK_READ	64	/* ... Which allows concurrent read operations */
+#define LOCK_WRITE	128	/* ... Which allows concurrent write operations */
+#define LOCK_RW		192	/* ... Which allows concurrent read & write ops */
+
+struct flock {
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE	1024
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/fiq.h linux-2.4.29-uc1/include/asm-armnommu/fiq.h
--- linux-2.4.29/include/asm-armnommu/fiq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/fiq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,37 @@
+/*
+ *  linux/include/asm-arm/fiq.h
+ *
+ * Support for FIQ on ARM architectures.
+ * Written by Philip Blundell <philb@gnu.org>, 1998
+ * Re-written by Russell King
+ */
+
+#ifndef __ASM_FIQ_H
+#define __ASM_FIQ_H
+
+#include <asm/ptrace.h>
+
+struct fiq_handler {
+	struct fiq_handler *next;
+	/* Name
+	 */
+	const char *name;
+	/* Called to ask driver to relinquish/
+	 * reacquire FIQ
+	 * return zero to accept, or -<errno>
+	 */
+	int (*fiq_op)(void *, int relinquish);
+	/* data for the relinquish/reacquire functions
+	 */
+	void *dev_id;
+};
+
+extern int claim_fiq(struct fiq_handler *f);
+extern void release_fiq(struct fiq_handler *f);
+extern void set_fiq_handler(void *start, unsigned int length);
+extern void set_fiq_regs(struct pt_regs *regs);
+extern void get_fiq_regs(struct pt_regs *regs);
+extern void enable_fiq(int fiq);
+extern void disable_fiq(int fiq);
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/flat.h linux-2.4.29-uc1/include/asm-armnommu/flat.h
--- linux-2.4.29/include/asm-armnommu/flat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/flat.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,16 @@
+/*
+ * include/asm-armnommu/flat.h -- uClinux flat-format executables
+ */
+
+#ifndef __ARMNOMMU_FLAT_H__
+#define __ARMNOMMU_FLAT_H__
+
+#define	flat_stack_align(sp)			/* nothing needed */
+#define	flat_argvp_envp_on_stack()		1
+#define	flat_old_ram_flag(flags)		(flags)
+#define	flat_reloc_valid(reloc, size)		((reloc) <= (size))
+#define	flat_get_addr_from_rp(rp, relval, flags)	get_unaligned(rp)
+#define	flat_put_addr_at_rp(rp, val, relval)	put_unaligned(val,rp)
+#define	flat_get_relocate_addr(rel)		(rel)
+
+#endif /* __ARMNOMMU_FLAT_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/floppy.h linux-2.4.29-uc1/include/asm-armnommu/floppy.h
--- linux-2.4.29/include/asm-armnommu/floppy.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/floppy.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,144 @@
+/*
+ *  linux/include/asm-arm/floppy.h
+ *
+ *  Copyright (C) 1996-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Note that we don't touch FLOPPY_DMA nor FLOPPY_IRQ here
+ */
+#ifndef __ASM_ARM_FLOPPY_H
+#define __ASM_ARM_FLOPPY_H
+#if 0
+#include <asm/arch/floppy.h>
+#endif
+
+#define fd_outb(val,port)			\
+	do {					\
+		if ((port) == FD_DOR)		\
+			fd_setdor((val));	\
+		else				\
+			outb((val),(port));	\
+	} while(0)
+
+#define fd_inb(port)		inb((port))
+#define fd_request_irq()	request_irq(IRQ_FLOPPYDISK,floppy_interrupt,\
+					SA_INTERRUPT|SA_SAMPLE_RANDOM,"floppy",NULL)
+#define fd_free_irq()		free_irq(IRQ_FLOPPYDISK,NULL)
+#define fd_disable_irq()	disable_irq(IRQ_FLOPPYDISK)
+#define fd_enable_irq()		enable_irq(IRQ_FLOPPYDISK)
+
+#define fd_request_dma()	request_dma(DMA_FLOPPY,"floppy")
+#define fd_free_dma()		free_dma(DMA_FLOPPY)
+#define fd_disable_dma()	disable_dma(DMA_FLOPPY)
+#define fd_enable_dma()		enable_dma(DMA_FLOPPY)
+#define fd_clear_dma_ff()	clear_dma_ff(DMA_FLOPPY)
+#define fd_set_dma_mode(mode)	set_dma_mode(DMA_FLOPPY, (mode))
+#define fd_set_dma_addr(addr)	set_dma_addr(DMA_FLOPPY, virt_to_bus((addr)))
+#define fd_set_dma_count(len)	set_dma_count(DMA_FLOPPY, (len))
+#define fd_cacheflush(addr,sz)
+
+/* need to clean up dma.h */
+#define DMA_FLOPPYDISK		DMA_FLOPPY
+
+/* Floppy_selects is the list of DOR's to select drive fd
+ *
+ * On initialisation, the floppy list is scanned, and the drives allocated
+ * in the order that they are found.  This is done by seeking the drive
+ * to a non-zero track, and then restoring it to track 0.  If an error occurs,
+ * then there is no floppy drive present.       [to be put back in again]
+ */
+static unsigned char floppy_selects[2][4] =
+{
+	{ 0x10, 0x21, 0x23, 0x33 },
+	{ 0x10, 0x21, 0x23, 0x33 }
+};
+
+#define fd_setdor(dor)								\
+do {										\
+	int new_dor = (dor);							\
+	if (new_dor & 0xf0)							\
+		new_dor = (new_dor & 0x0c) | floppy_selects[fdc][new_dor & 3];	\
+	else									\
+		new_dor &= 0x0c;						\
+	outb(new_dor, FD_DOR);							\
+} while (0)
+
+/*
+ * Someday, we'll automatically detect which drives are present...
+ */
+extern __inline__ void fd_scandrives (void)
+{
+#if 0
+	int floppy, drive_count;
+
+	fd_disable_irq();
+	raw_cmd = &default_raw_cmd;
+	raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_SEEK;
+	raw_cmd->track = 0;
+	raw_cmd->rate = ?;
+	drive_count = 0;
+	for (floppy = 0; floppy < 4; floppy ++) {
+		current_drive = drive_count;
+		/*
+		 * Turn on floppy motor
+		 */
+		if (start_motor(redo_fd_request))
+			continue;
+		/*
+		 * Set up FDC
+		 */
+		fdc_specify();
+		/*
+		 * Tell FDC to recalibrate
+		 */
+		output_byte(FD_RECALIBRATE);
+		LAST_OUT(UNIT(floppy));
+		/* wait for command to complete */
+		if (!successful) {
+			int i;
+			for (i = drive_count; i < 3; i--)
+				floppy_selects[fdc][i] = floppy_selects[fdc][i + 1];
+			floppy_selects[fdc][3] = 0;
+			floppy -= 1;
+		} else
+			drive_count++;
+	}
+#else
+	floppy_selects[0][0] = 0x10;
+	floppy_selects[0][1] = 0x21;
+	floppy_selects[0][2] = 0x23;
+	floppy_selects[0][3] = 0x33;
+#endif
+}
+
+#define FDC1 (0x3f0)
+
+#define FLOPPY0_TYPE 4
+#define FLOPPY1_TYPE 4
+
+#define N_FDC 1
+#define N_DRIVE 4
+
+#define FLOPPY_MOTOR_MASK 0xf0
+
+#define CROSS_64KB(a,s) (0)
+
+/*
+ * This allows people to reverse the order of
+ * fd0 and fd1, in case their hardware is
+ * strangely connected (as some RiscPCs
+ * and A5000s seem to be).
+ */
+static void driveswap(int *ints, int dummy, int dummy2)
+{
+	floppy_selects[0][0] ^= floppy_selects[0][1];
+	floppy_selects[0][1] ^= floppy_selects[0][0];
+	floppy_selects[0][0] ^= floppy_selects[0][1];
+}
+
+#define EXTRA_FLOPPY_PARAMS ,{ "driveswap", &driveswap, NULL, 0, 0 }
+	
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/hardirq.h linux-2.4.29-uc1/include/asm-armnommu/hardirq.h
--- linux-2.4.29/include/asm-armnommu/hardirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/hardirq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,41 @@
+#ifndef __ASM_HARDIRQ_H
+#define __ASM_HARDIRQ_H
+
+#include <linux/config.h>
+#include <linux/threads.h>
+
+/* softirq.h is sensitive to the offsets of these fields */
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned int __local_irq_count;
+	unsigned int __local_bh_count;
+	unsigned int __syscall_count;
+	struct task_struct * __ksoftirqd_task;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt() ({ const int __cpu = smp_processor_id(); \
+	(local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
+
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
+
+#ifndef CONFIG_SMP
+
+#define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
+#define hardirq_endlock(cpu)	do { } while (0)
+
+#define irq_enter(cpu,irq)	(local_irq_count(cpu)++)
+#define irq_exit(cpu,irq)	(local_irq_count(cpu)--)
+
+#define synchronize_irq()	do { } while (0)
+
+#else
+#error SMP not supported
+#endif /* CONFIG_SMP */
+
+#endif /* __ASM_HARDIRQ_H */
diff -urN linux-2.4.29/include/asm-armnommu/hardware/amba_kmi.h linux-2.4.29-uc1/include/asm-armnommu/hardware/amba_kmi.h
--- linux-2.4.29/include/asm-armnommu/hardware/amba_kmi.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/hardware/amba_kmi.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,92 @@
+/*
+ *  linux/include/asm-arm/hardware/amba_kmi.h
+ *
+ *  Internal header file for AMBA KMI ports
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *
+ * ---------------------------------------------------------------------------
+ *  From ARM PrimeCell(tm) PS2 Keyboard/Mouse Interface (PL050) Technical
+ *  Reference Manual - ARM DDI 0143B - see http://www.arm.com/
+ * ---------------------------------------------------------------------------
+ */
+#ifndef ASM_ARM_HARDWARE_AMBA_KMI_H
+#define ASM_ARM_HARDWARE_AMBA_KMI_H
+
+/*
+ * KMI control register:
+ *  KMICR_TYPE       0 = PS2/AT mode, 1 = No line control bit mode
+ *  KMICR_RXINTREN   1 = enable RX interrupts
+ *  KMICR_TXINTREN   1 = enable TX interrupts
+ *  KMICR_EN         1 = enable KMI
+ *  KMICR_FD         1 = force KMI data low
+ *  KMICR_FC         1 = force KMI clock low
+ */
+#define KMICR		(KMI_BASE + 0x00)
+#define KMICR_TYPE		(1 << 5)
+#define KMICR_RXINTREN		(1 << 4)
+#define KMICR_TXINTREN		(1 << 3)
+#define KMICR_EN		(1 << 2)
+#define KMICR_FD		(1 << 1)
+#define KMICR_FC		(1 << 0)
+
+/*
+ * KMI status register:
+ *  KMISTAT_TXEMPTY  1 = transmitter register empty
+ *  KMISTAT_TXBUSY   1 = currently sending data
+ *  KMISTAT_RXFULL   1 = receiver register ready to be read
+ *  KMISTAT_RXBUSY   1 = currently receiving data
+ *  KMISTAT_RXPARITY parity of last databyte received
+ *  KMISTAT_IC       current level of KMI clock input
+ *  KMISTAT_ID       current level of KMI data input
+ */
+#define KMISTAT		(KMI_BASE + 0x04)
+#define KMISTAT_TXEMPTY		(1 << 6)
+#define KMISTAT_TXBUSY		(1 << 5)
+#define KMISTAT_RXFULL		(1 << 4)
+#define KMISTAT_RXBUSY		(1 << 3)
+#define KMISTAT_RXPARITY	(1 << 2)
+#define KMISTAT_IC		(1 << 1)
+#define KMISTAT_ID		(1 << 0)
+
+/*
+ * KMI data register
+ */
+#define KMIDATA		(KMI_BASE + 0x08)
+
+/*
+ * KMI clock divisor: to generate 8MHz internal clock
+ *  div = (ref / 8MHz) - 1; 0 <= div <= 15
+ */
+#define KMICLKDIV	(KMI_BASE + 0x0c)
+
+/*
+ * KMI interrupt register:
+ *  KMIIR_TXINTR     1 = transmit interrupt asserted
+ *  KMIIR_RXINTR     1 = receive interrupt asserted
+ */
+#define KMIIR		(KMI_BASE + 0x10)
+#define KMIIR_TXINTR		(1 << 1)
+#define KMIIR_RXINTR		(1 << 0)
+
+/*
+ * The size of the KMI primecell
+ */
+#define KMI_SIZE	(0x100)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/hardware/clps7111.h linux-2.4.29-uc1/include/asm-armnommu/hardware/clps7111.h
--- linux-2.4.29/include/asm-armnommu/hardware/clps7111.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/hardware/clps7111.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,181 @@
+/*
+ *  linux/include/asm-arm/hardware/clps7111.h
+ *
+ *  This file contains the hardware definitions of the CLPS7111 internal
+ *  registers.
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef __ASM_HARDWARE_CLPS7111_H
+#define __ASM_HARDWARE_CLPS7111_H
+
+#define CLPS7111_PHYS_BASE	(0x80000000)
+
+#ifndef __ASSEMBLY__
+#define clps_readb(off)		__raw_readb(CLPS7111_BASE + (off))
+#define clps_readl(off)		__raw_readl(CLPS7111_BASE + (off))
+#define clps_writeb(val,off)	__raw_writeb(val, CLPS7111_BASE + (off))
+#define clps_writel(val,off)	__raw_writel(val, CLPS7111_BASE + (off))
+#endif
+
+#define PADR		(0x0000)
+#define PBDR		(0x0001)
+#define PDDR		(0x0003)
+#define PADDR		(0x0040)
+#define PBDDR		(0x0041)
+#define PDDDR		(0x0043)
+#define PEDR		(0x0080)
+#define PEDDR		(0x00c0)
+#define SYSCON1		(0x0100)
+#define SYSFLG1		(0x0140)
+#define MEMCFG1		(0x0180)
+#define MEMCFG2		(0x01c0)
+#define DRFPR		(0x0200)
+#define INTSR1		(0x0240)
+#define INTMR1		(0x0280)
+#define LCDCON		(0x02c0)
+#define TC2D		(0x0340)
+#define RTCDR		(0x0380)
+#define RTCMR		(0x03c0)
+#define PMPCON		(0x0400)
+#define CODR		(0x0440)
+#define UARTDR1		(0x0480)
+#define UBRLCR1		(0x04c0)
+#define SYNCIO		(0x0500)
+#define PALLSW		(0x0540)
+#define PALMSW		(0x0580)
+#define STFCLR		(0x05c0)
+#define BLEOI		(0x0600)
+#define MCEOI		(0x0640)
+#define TEOI		(0x0680)
+#define TC1EOI		(0x06c0)
+#define TC2EOI		(0x0700)
+#define RTCEOI		(0x0740)
+#define UMSEOI		(0x0780)
+#define COEOI		(0x07c0)
+#define HALT		(0x0800)
+#define STDBY		(0x0840)
+
+#define FBADDR		(0x1000)
+#define SYSCON2		(0x1100)
+#define SYSFLG2		(0x1140)
+#define INTSR2		(0x1240)
+#define INTMR2		(0x1280)
+#define UARTDR2		(0x1480)
+#define UBRLCR2		(0x14c0)
+#define SS2DR		(0x1500)
+#define SRXEOF		(0x1600)
+#define SS2POP		(0x16c0)
+#define KBDEOI		(0x1700)
+
+/* common bits: SYSCON1 / SYSCON2 */
+#define SYSCON_UARTEN		(1 << 8)
+
+#define SYSCON1_KBDSCAN(x)	((x) & 15)
+#define SYSCON1_KBDSCANMASK	(15)
+#define SYSCON1_TC1M		(1 << 4)
+#define SYSCON1_TC1S		(1 << 5)
+#define SYSCON1_TC2M		(1 << 6)
+#define SYSCON1_TC2S		(1 << 7)
+#define SYSCON1_UART1EN		SYSCON_UARTEN
+#define SYSCON1_BZTOG		(1 << 9)
+#define SYSCON1_BZMOD		(1 << 10)
+#define SYSCON1_DBGEN		(1 << 11)
+#define SYSCON1_LCDEN		(1 << 12)
+#define SYSCON1_CDENTX		(1 << 13)
+#define SYSCON1_CDENRX		(1 << 14)
+#define SYSCON1_SIREN		(1 << 15)
+#define SYSCON1_ADCKSEL(x)	(((x) & 3) << 16)
+#define SYSCON1_ADCKSEL_MASK	(3 << 16)
+#define SYSCON1_EXCKEN		(1 << 18)
+#define SYSCON1_WAKEDIS		(1 << 19)
+#define SYSCON1_IRTXM		(1 << 20)
+
+/* common bits: SYSFLG1 / SYSFLG2 */
+#define SYSFLG_UBUSY		(1 << 11)
+#define SYSFLG_URXFE		(1 << 22)
+#define SYSFLG_UTXFF		(1 << 23)
+
+#define SYSFLG1_MCDR		(1 << 0)
+#define SYSFLG1_DCDET		(1 << 1)
+#define SYSFLG1_WUDR		(1 << 2)
+#define SYSFLG1_WUON		(1 << 3)
+#define SYSFLG1_CTS		(1 << 8)
+#define SYSFLG1_DSR		(1 << 9)
+#define SYSFLG1_DCD		(1 << 10)
+#define SYSFLG1_UBUSY		SYSFLG_UBUSY
+#define SYSFLG1_NBFLG		(1 << 12)
+#define SYSFLG1_RSTFLG		(1 << 13)
+#define SYSFLG1_PFFLG		(1 << 14)
+#define SYSFLG1_CLDFLG		(1 << 15)
+#define SYSFLG1_URXFE		SYSFLG_URXFE
+#define SYSFLG1_UTXFF		SYSFLG_UTXFF
+#define SYSFLG1_CRXFE		(1 << 24)
+#define SYSFLG1_CTXFF		(1 << 25)
+#define SYSFLG1_SSIBUSY		(1 << 26)
+#define SYSFLG1_ID		(1 << 29)
+
+#define SYSFLG2_SSRXOF		(1 << 0)
+#define SYSFLG2_RESVAL		(1 << 1)
+#define SYSFLG2_RESFRM		(1 << 2)
+#define SYSFLG2_SS2RXFE		(1 << 3)
+#define SYSFLG2_SS2TXFF		(1 << 4)
+#define SYSFLG2_SS2TXUF		(1 << 5)
+#define SYSFLG2_CKMODE		(1 << 6)
+#define SYSFLG2_UBUSY		SYSFLG_UBUSY
+#define SYSFLG2_URXFE		SYSFLG_URXFE
+#define SYSFLG2_UTXFF		SYSFLG_UTXFF
+
+#define LCDCON_GSEN		(1 << 30)
+#define LCDCON_GSMD		(1 << 31)
+
+#define SYSCON2_SERSEL		(1 << 0)
+#define SYSCON2_KBD6		(1 << 1)
+#define SYSCON2_DRAMZ		(1 << 2)
+#define SYSCON2_KBWEN		(1 << 3)
+#define SYSCON2_SS2TXEN		(1 << 4)
+#define SYSCON2_PCCARD1		(1 << 5)
+#define SYSCON2_PCCARD2		(1 << 6)
+#define SYSCON2_SS2RXEN		(1 << 7)
+#define SYSCON2_UART2EN		SYSCON_UARTEN
+#define SYSCON2_SS2MAEN		(1 << 9)
+#define SYSCON2_OSTB		(1 << 12)
+#define SYSCON2_CLKENSL		(1 << 13)
+#define SYSCON2_BUZFREQ		(1 << 14)
+
+/* common bits: UARTDR1 / UARTDR2 */
+#define UARTDR_FRMERR		(1 << 8)
+#define UARTDR_PARERR		(1 << 9)
+#define UARTDR_OVERR		(1 << 10)
+
+/* common bits: UBRLCR1 / UBRLCR2 */
+#define UBRLCR_BAUD_MASK	((1 << 12) - 1)
+#define UBRLCR_BREAK		(1 << 12)
+#define UBRLCR_PRTEN		(1 << 13)
+#define UBRLCR_EVENPRT		(1 << 14)
+#define UBRLCR_XSTOP		(1 << 15)
+#define UBRLCR_FIFOEN		(1 << 16)
+#define UBRLCR_WRDLEN5		(0 << 17)
+#define UBRLCR_WRDLEN6		(1 << 17)
+#define UBRLCR_WRDLEN7		(2 << 17)
+#define UBRLCR_WRDLEN8		(3 << 17)
+#define UBRLCR_WRDLEN_MASK	(3 << 17)
+
+#define SYNCIO_SMCKEN		(1 << 13)
+#define SYNCIO_TXFRMEN		(1 << 14)
+
+#endif /* __ASM_HARDWARE_CLPS7111_H */
diff -urN linux-2.4.29/include/asm-armnommu/hardware/dec21285.h linux-2.4.29-uc1/include/asm-armnommu/hardware/dec21285.h
--- linux-2.4.29/include/asm-armnommu/hardware/dec21285.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/hardware/dec21285.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,148 @@
+/*
+ *  linux/include/asm-arm/hardware/dec21285.h
+ *
+ *  Copyright (C) 1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  DC21285 registers
+ */
+#define DC21285_PCI_IACK		0x79000000
+#define DC21285_ARMCSR_BASE		0x42000000
+#define DC21285_PCI_TYPE_0_CONFIG	0x7b000000
+#define DC21285_PCI_TYPE_1_CONFIG	0x7a000000
+#define DC21285_OUTBOUND_WRITE_FLUSH	0x78000000
+#define DC21285_FLASH			0x41000000
+#define DC21285_PCI_IO			0x7c000000
+#define DC21285_PCI_MEM			0x80000000
+
+#include <linux/config.h>
+#ifndef __ASSEMBLY__
+#include <asm/arch/hardware.h>
+#define DC21285_IO(x)		((volatile unsigned long *)(ARMCSR_BASE+(x)))
+#else
+#define DC21285_IO(x)		(x)
+#endif
+
+#define CSR_PCICMD		DC21285_IO(0x0004)
+#define CSR_CLASSREV		DC21285_IO(0x0008)
+#define CSR_PCICACHELINESIZE	DC21285_IO(0x000c)
+#define CSR_PCICSRBASE		DC21285_IO(0x0010)
+#define CSR_PCICSRIOBASE	DC21285_IO(0x0014)
+#define CSR_PCISDRAMBASE	DC21285_IO(0x0018)
+#define CSR_PCIROMBASE		DC21285_IO(0x0030)
+#define CSR_MBOX0		DC21285_IO(0x0050)
+#define CSR_MBOX1		DC21285_IO(0x0054)
+#define CSR_MBOX2		DC21285_IO(0x0058)
+#define CSR_MBOX3		DC21285_IO(0x005c)
+#define CSR_DOORBELL		DC21285_IO(0x0060)
+#define CSR_DOORBELL_SETUP	DC21285_IO(0x0064)
+#define CSR_ROMWRITEREG		DC21285_IO(0x0068)
+#define CSR_CSRBASEMASK		DC21285_IO(0x00f8)
+#define CSR_CSRBASEOFFSET	DC21285_IO(0x00fc)
+#define CSR_SDRAMBASEMASK	DC21285_IO(0x0100)
+#define CSR_SDRAMBASEOFFSET	DC21285_IO(0x0104)
+#define CSR_ROMBASEMASK		DC21285_IO(0x0108)
+#define CSR_SDRAMTIMING		DC21285_IO(0x010c)
+#define CSR_SDRAMADDRSIZE0	DC21285_IO(0x0110)
+#define CSR_SDRAMADDRSIZE1	DC21285_IO(0x0114)
+#define CSR_SDRAMADDRSIZE2	DC21285_IO(0x0118)
+#define CSR_SDRAMADDRSIZE3	DC21285_IO(0x011c)
+#define CSR_I2O_INFREEHEAD	DC21285_IO(0x0120)
+#define CSR_I2O_INPOSTTAIL	DC21285_IO(0x0124)
+#define CSR_I2O_OUTPOSTHEAD	DC21285_IO(0x0128)
+#define CSR_I2O_OUTFREETAIL	DC21285_IO(0x012c)
+#define CSR_I2O_INFREECOUNT	DC21285_IO(0x0130)
+#define CSR_I2O_OUTPOSTCOUNT	DC21285_IO(0x0134)
+#define CSR_I2O_INPOSTCOUNT	DC21285_IO(0x0138)
+#define CSR_SA110_CNTL		DC21285_IO(0x013c)
+#define SA110_CNTL_INITCMPLETE		(1 << 0)
+#define SA110_CNTL_ASSERTSERR		(1 << 1)
+#define SA110_CNTL_RXSERR		(1 << 3)
+#define SA110_CNTL_SA110DRAMPARITY	(1 << 4)
+#define SA110_CNTL_PCISDRAMPARITY	(1 << 5)
+#define SA110_CNTL_DMASDRAMPARITY	(1 << 6)
+#define SA110_CNTL_DISCARDTIMER		(1 << 8)
+#define SA110_CNTL_PCINRESET		(1 << 9)
+#define SA110_CNTL_I2O_256		(0 << 10)
+#define SA110_CNTL_I20_512		(1 << 10)
+#define SA110_CNTL_I2O_1024		(2 << 10)
+#define SA110_CNTL_I2O_2048		(3 << 10)
+#define SA110_CNTL_I2O_4096		(4 << 10)
+#define SA110_CNTL_I2O_8192		(5 << 10)
+#define SA110_CNTL_I2O_16384		(6 << 10)
+#define SA110_CNTL_I2O_32768		(7 << 10)
+#define SA110_CNTL_WATCHDOG		(1 << 13)
+#define SA110_CNTL_ROMWIDTH_UNDEF	(0 << 14)
+#define SA110_CNTL_ROMWIDTH_16		(1 << 14)
+#define SA110_CNTL_ROMWIDTH_32		(2 << 14)
+#define SA110_CNTL_ROMWIDTH_8		(3 << 14)
+#define SA110_CNTL_ROMACCESSTIME(x)	((x)<<16)
+#define SA110_CNTL_ROMBURSTTIME(x)	((x)<<20)
+#define SA110_CNTL_ROMTRISTATETIME(x)	((x)<<24)
+#define SA110_CNTL_XCSDIR(x)		((x)<<28)
+#define SA110_CNTL_PCICFN		(1 << 31)
+
+/*
+ * footbridge_cfn_mode() is used when we want
+ * to check whether we are the central function
+ */
+#define __footbridge_cfn_mode() (*CSR_SA110_CNTL & SA110_CNTL_PCICFN)
+#if defined(CONFIG_FOOTBRIDGE_HOST) && defined(CONFIG_FOOTBRIDGE_ADDIN)
+#define footbridge_cfn_mode() __footbridge_cfn_mode()
+#elif defined(CONFIG_FOOTBRIDGE_HOST)
+#define footbridge_cfn_mode() (1)
+#else
+#define footbridge_cfn_mode() (0)
+#endif
+
+#define CSR_PCIADDR_EXTN	DC21285_IO(0x0140)
+#define CSR_PREFETCHMEMRANGE	DC21285_IO(0x0144)
+#define CSR_XBUS_CYCLE		DC21285_IO(0x0148)
+#define CSR_XBUS_IOSTROBE	DC21285_IO(0x014c)
+#define CSR_DOORBELL_PCI	DC21285_IO(0x0150)
+#define CSR_DOORBELL_SA110	DC21285_IO(0x0154)
+#define CSR_UARTDR		DC21285_IO(0x0160)
+#define CSR_RXSTAT		DC21285_IO(0x0164)
+#define CSR_H_UBRLCR		DC21285_IO(0x0168)
+#define CSR_M_UBRLCR		DC21285_IO(0x016c)
+#define CSR_L_UBRLCR		DC21285_IO(0x0170)
+#define CSR_UARTCON		DC21285_IO(0x0174)
+#define CSR_UARTFLG		DC21285_IO(0x0178)
+#define CSR_IRQ_STATUS		DC21285_IO(0x0180)
+#define CSR_IRQ_RAWSTATUS	DC21285_IO(0x0184)
+#define CSR_IRQ_ENABLE		DC21285_IO(0x0188)
+#define CSR_IRQ_DISABLE		DC21285_IO(0x018c)
+#define CSR_IRQ_SOFT		DC21285_IO(0x0190)
+#define CSR_FIQ_STATUS		DC21285_IO(0x0280)
+#define CSR_FIQ_RAWSTATUS	DC21285_IO(0x0284)
+#define CSR_FIQ_ENABLE		DC21285_IO(0x0288)
+#define CSR_FIQ_DISABLE		DC21285_IO(0x028c)
+#define CSR_FIQ_SOFT		DC21285_IO(0x0290)
+#define CSR_TIMER1_LOAD		DC21285_IO(0x0300)
+#define CSR_TIMER1_VALUE	DC21285_IO(0x0304)
+#define CSR_TIMER1_CNTL		DC21285_IO(0x0308)
+#define CSR_TIMER1_CLR		DC21285_IO(0x030c)
+#define CSR_TIMER2_LOAD		DC21285_IO(0x0320)
+#define CSR_TIMER2_VALUE	DC21285_IO(0x0324)
+#define CSR_TIMER2_CNTL		DC21285_IO(0x0328)
+#define CSR_TIMER2_CLR		DC21285_IO(0x032c)
+#define CSR_TIMER3_LOAD		DC21285_IO(0x0340)
+#define CSR_TIMER3_VALUE	DC21285_IO(0x0344)
+#define CSR_TIMER3_CNTL		DC21285_IO(0x0348)
+#define CSR_TIMER3_CLR		DC21285_IO(0x034c)
+#define CSR_TIMER4_LOAD		DC21285_IO(0x0360)
+#define CSR_TIMER4_VALUE	DC21285_IO(0x0364)
+#define CSR_TIMER4_CNTL		DC21285_IO(0x0368)
+#define CSR_TIMER4_CLR		DC21285_IO(0x036c)
+
+#define TIMER_CNTL_ENABLE	(1 << 7)
+#define TIMER_CNTL_AUTORELOAD	(1 << 6)
+#define TIMER_CNTL_DIV1		(0)
+#define TIMER_CNTL_DIV16	(1 << 2)
+#define TIMER_CNTL_DIV256	(2 << 2)
+#define TIMER_CNTL_CNTEXT	(3 << 2)
+
+
diff -urN linux-2.4.29/include/asm-armnommu/hardware/ep7212.h linux-2.4.29-uc1/include/asm-armnommu/hardware/ep7212.h
--- linux-2.4.29/include/asm-armnommu/hardware/ep7212.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/hardware/ep7212.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,91 @@
+/*
+ *  linux/include/asm-arm/hardware/ep7212.h
+ *
+ *  This file contains the hardware definitions of the EP7212 internal
+ *  registers.
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef __ASM_HARDWARE_EP7212_H
+#define __ASM_HARDWARE_EP7212_H
+
+/*
+ * define EP7212_BASE to be the base address of the region
+ * you want to access.
+ */
+
+#define EP7212_PHYS_BASE	(0x80000000)
+
+/*
+ * The first group of registers (0x0000 through 0x1fff)
+ * are CL-PS7111 compatible
+ */
+#define CLPS7111_BASE		EP7212_BASE
+#include <asm/hardware/clps7111.h>
+
+#ifndef __ASSEMBLY__
+#define ep_readl(off)		__raw_readl(EP7212_BASE + (off))
+#define ep_writel(val,off)	__raw_writel(val, EP7212_BASE + (off))
+#endif
+
+/*
+ * These registers are specific to the EP7212 only
+ */
+#define DAIR			0x2000
+#define DAIR0			0x2040
+#define DAIDR1			0x2080
+#define DAIDR2			0x20c0
+#define DAISR			0x2100
+#define SYSCON3			0x2200
+#define INTSR3			0x2240
+#define INTMR3			0x2280
+#define LEDFLSH			0x22c0
+
+#define DAIR_DAIEN		(1 << 16)
+#define DAIR_ECS		(1 << 17)
+#define DAIR_LCTM		(1 << 19)
+#define DAIR_LCRM		(1 << 20)
+#define DAIR_RCTM		(1 << 21)
+#define DAIR_RCRM		(1 << 22)
+#define DAIR_LBM		(1 << 23)
+
+#define DAIDR2_FIFOEN		(1 << 15)
+#define DAIDR2_FIFOLEFT		(0x0d << 16)
+#define DAIDR2_FIFORIGHT	(0x11 << 16)
+
+#define DAISR_RCTS		(1 << 0)
+#define DAISR_RCRS		(1 << 1)
+#define DAISR_LCTS		(1 << 2)
+#define DAISR_LCRS		(1 << 3)
+#define DAISR_RCTU		(1 << 4)
+#define DAISR_RCRO		(1 << 5)
+#define DAISR_LCTU		(1 << 6)
+#define DAISR_LCRO		(1 << 7)
+#define DAISR_RCNF		(1 << 8)
+#define DAISR_RCNE		(1 << 9)
+#define DAISR_LCNF		(1 << 10)
+#define DAISR_LCNE		(1 << 11)
+#define DAISR_FIFO		(1 << 12)
+
+#define SYSCON3_ADCCON		(1 << 0)
+#define SYSCON3_DAISEL		(1 << 3)
+#define SYSCON3_ADCCKNSEN	(1 << 4)
+#define SYSCON3_FASTWAKE	(1 << 8)
+#define SYSCON3_DAIEN		(1 << 9)
+
+
+#endif /* __ASM_HARDWARE_EP7212_H */
diff -urN linux-2.4.29/include/asm-armnommu/hardware/ioc.h linux-2.4.29-uc1/include/asm-armnommu/hardware/ioc.h
--- linux-2.4.29/include/asm-armnommu/hardware/ioc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/hardware/ioc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,72 @@
+/*
+ *  linux/include/asm-arm/hardware/ioc.h
+ *
+ *  Copyright (C) Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Use these macros to read/write the IOC.  All it does is perform the actual
+ *  read/write.
+ */
+
+#ifndef IOC_CONTROL
+
+#ifndef __ASSEMBLY__
+
+/*
+ * We use __raw_base variants here so that we give the compiler the
+ * chance to keep IOC_BASE in a register.
+ */
+#define ioc_readb(off)		__raw_base_readb(IOC_BASE, (off))
+#define ioc_writeb(val,off)	__raw_base_writeb(val, IOC_BASE, (off))
+
+#endif
+
+#define IOC_CONTROL	(0x00)
+#define IOC_KARTTX	(0x04)
+#define IOC_KARTRX	(0x04)
+
+#define IOC_IRQSTATA	(0x10)
+#define IOC_IRQREQA	(0x14)
+#define IOC_IRQCLRA	(0x14)
+#define IOC_IRQMASKA	(0x18)
+
+#define IOC_IRQSTATB	(0x20)
+#define IOC_IRQREQB	(0x24)
+#define IOC_IRQMASKB	(0x28)
+
+#define IOC_FIQSTAT	(0x30)
+#define IOC_FIQREQ	(0x34)
+#define IOC_FIQMASK	(0x38)
+
+#define IOC_T0CNTL	(0x40)
+#define IOC_T0LTCHL	(0x40)
+#define IOC_T0CNTH	(0x44)
+#define IOC_T0LTCHH	(0x44)
+#define IOC_T0GO	(0x48)
+#define IOC_T0LATCH	(0x4c)
+
+#define IOC_T1CNTL	(0x50)
+#define IOC_T1LTCHL	(0x50)
+#define IOC_T1CNTH	(0x54)
+#define IOC_T1LTCHH	(0x54)
+#define IOC_T1GO	(0x58)
+#define IOC_T1LATCH	(0x5c)
+
+#define IOC_T2CNTL	(0x60)
+#define IOC_T2LTCHL	(0x60)
+#define IOC_T2CNTH	(0x64)
+#define IOC_T2LTCHH	(0x64)
+#define IOC_T2GO	(0x68)
+#define IOC_T2LATCH	(0x6c)
+
+#define IOC_T3CNTL	(0x70)
+#define IOC_T3LTCHL	(0x70)
+#define IOC_T3CNTH	(0x74)
+#define IOC_T3LTCHH	(0x74)
+#define IOC_T3GO	(0x78)
+#define IOC_T3LATCH	(0x7c)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/hardware/iomd.h linux-2.4.29-uc1/include/asm-armnommu/hardware/iomd.h
--- linux-2.4.29/include/asm-armnommu/hardware/iomd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/hardware/iomd.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,256 @@
+/*
+ *  linux/include/asm-arm/iomd.h
+ *
+ *  Copyright (C) 1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  This file contains information out the IOMD ASIC used in the
+ *  Acorn RiscPC and subsequently integrated into the CLPS7500 chips.
+ */
+#include <linux/config.h>
+
+#ifndef __ASSEMBLY__
+
+/*
+ * We use __raw_base variants here so that we give the compiler the
+ * chance to keep IOC_BASE in a register.
+ */
+#define iomd_readb(off)		__raw_base_readb(IOMD_BASE, (off))
+#define iomd_readl(off)		__raw_base_readl(IOMD_BASE, (off))
+#define iomd_writeb(val,off)	__raw_base_writeb(val, IOMD_BASE, (off))
+#define iomd_writel(val,off)	__raw_base_writel(val, IOMD_BASE, (off))
+
+#endif
+
+#define IOMD_CONTROL	(0x000)
+#define IOMD_KARTTX	(0x004)
+#define IOMD_KARTRX	(0x004)
+#define IOMD_KCTRL	(0x008)
+
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_IOLINES	(0x00C)
+#endif
+
+#define IOMD_IRQSTATA	(0x010)
+#define IOMD_IRQREQA	(0x014)
+#define IOMD_IRQCLRA	(0x014)
+#define IOMD_IRQMASKA	(0x018)
+
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_SUSMODE	(0x01C)
+#endif
+
+#define IOMD_IRQSTATB	(0x020)
+#define IOMD_IRQREQB	(0x024)
+#define IOMD_IRQMASKB	(0x028)
+
+#define IOMD_FIQSTAT	(0x030)
+#define IOMD_FIQREQ	(0x034)
+#define IOMD_FIQMASK	(0x038)
+
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_CLKCTL	(0x03C)
+#endif
+
+#define IOMD_T0CNTL	(0x040)
+#define IOMD_T0LTCHL	(0x040)
+#define IOMD_T0CNTH	(0x044)
+#define IOMD_T0LTCHH	(0x044)
+#define IOMD_T0GO	(0x048)
+#define IOMD_T0LATCH	(0x04c)
+
+#define IOMD_T1CNTL	(0x050)
+#define IOMD_T1LTCHL	(0x050)
+#define IOMD_T1CNTH	(0x054)
+#define IOMD_T1LTCHH	(0x054)
+#define IOMD_T1GO	(0x058)
+#define IOMD_T1LATCH	(0x05c)
+
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_IRQSTATC	(0x060)
+#define IOMD_IRQREQC	(0x064)
+#define IOMD_IRQMASKC	(0x068)
+
+#define IOMD_VIDMUX	(0x06c)
+
+#define IOMD_IRQSTATD	(0x070)
+#define IOMD_IRQREQD	(0x074)
+#define IOMD_IRQMASKD	(0x078)
+#endif
+
+#define IOMD_ROMCR0	(0x080)
+#define IOMD_ROMCR1	(0x084)
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_DRAMCR	(0x088)
+#endif
+#define IOMD_REFCR	(0x08C)
+
+#define IOMD_FSIZE	(0x090)
+#define IOMD_ID0	(0x094)
+#define IOMD_ID1	(0x098)
+#define IOMD_VERSION	(0x09C)
+
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_MOUSEX	(0x0A0)
+#define IOMD_MOUSEY	(0x0A4)
+#endif
+
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_MSEDAT	(0x0A8)
+#define IOMD_MSECTL	(0x0Ac)
+#endif
+
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_DMATCR	(0x0C0)
+#endif
+#define IOMD_IOTCR	(0x0C4)
+#define IOMD_ECTCR	(0x0C8)
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_DMAEXT	(0x0CC)
+#endif
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_ASTCR	(0x0CC)
+#define IOMD_DRAMCR	(0x0D0)
+#define IOMD_SELFREF	(0x0D4)
+#define IOMD_ATODICR	(0x0E0)
+#define IOMD_ATODSR	(0x0E4)
+#define IOMD_ATODCC	(0x0E8)
+#define IOMD_ATODCNT1	(0x0EC)
+#define IOMD_ATODCNT2	(0x0F0)
+#define IOMD_ATODCNT3	(0x0F4)
+#define IOMD_ATODCNT4	(0x0F8)
+#endif
+
+#ifdef CONFIG_ARCH_RPC
+#define DMA_EXT_IO0	1
+#define DMA_EXT_IO1	2
+#define DMA_EXT_IO2	4
+#define DMA_EXT_IO3	8
+
+#define IOMD_IO0CURA	(0x100)
+#define IOMD_IO0ENDA	(0x104)
+#define IOMD_IO0CURB	(0x108)
+#define IOMD_IO0ENDB	(0x10C)
+#define IOMD_IO0CR	(0x110)
+#define IOMD_IO0ST	(0x114)
+
+#define IOMD_IO1CURA	(0x120)
+#define IOMD_IO1ENDA	(0x124)
+#define IOMD_IO1CURB	(0x128)
+#define IOMD_IO1ENDB	(0x12C)
+#define IOMD_IO1CR	(0x130)
+#define IOMD_IO1ST	(0x134)
+
+#define IOMD_IO2CURA	(0x140)
+#define IOMD_IO2ENDA	(0x144)
+#define IOMD_IO2CURB	(0x148)
+#define IOMD_IO2ENDB	(0x14C)
+#define IOMD_IO2CR	(0x150)
+#define IOMD_IO2ST	(0x154)
+
+#define IOMD_IO3CURA	(0x160)
+#define IOMD_IO3ENDA	(0x164)
+#define IOMD_IO3CURB	(0x168)
+#define IOMD_IO3ENDB	(0x16C)
+#define IOMD_IO3CR	(0x170)
+#define IOMD_IO3ST	(0x174)
+#endif
+
+#define IOMD_SD0CURA	(0x180)
+#define IOMD_SD0ENDA	(0x184)
+#define IOMD_SD0CURB	(0x188)
+#define IOMD_SD0ENDB	(0x18C)
+#define IOMD_SD0CR	(0x190)
+#define IOMD_SD0ST	(0x194)
+
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_SD1CURA	(0x1A0)
+#define IOMD_SD1ENDA	(0x1A4)
+#define IOMD_SD1CURB	(0x1A8)
+#define IOMD_SD1ENDB	(0x1AC)
+#define IOMD_SD1CR	(0x1B0)
+#define IOMD_SD1ST	(0x1B4)
+#endif
+
+#define IOMD_CURSCUR	(0x1C0)
+#define IOMD_CURSINIT	(0x1C4)
+
+#define IOMD_VIDCUR	(0x1D0)
+#define IOMD_VIDEND	(0x1D4)
+#define IOMD_VIDSTART	(0x1D8)
+#define IOMD_VIDINIT	(0x1DC)
+#define IOMD_VIDCR	(0x1E0)
+
+#define IOMD_DMASTAT	(0x1F0)
+#define IOMD_DMAREQ	(0x1F4)
+#define IOMD_DMAMASK	(0x1F8)
+
+#define DMA_END_S	(1 << 31)
+#define DMA_END_L	(1 << 30)
+
+#define DMA_CR_C	0x80
+#define DMA_CR_D	0x40
+#define DMA_CR_E	0x20
+
+#define DMA_ST_OFL	4
+#define DMA_ST_INT	2
+#define DMA_ST_AB	1
+
+#ifndef IOC_CONTROL
+/*
+ * IOC compatability
+ */
+#define IOC_CONTROL	IOMD_CONTROL
+#define IOC_IRQSTATA	IOMD_IRQSTATA
+#define IOC_IRQREQA	IOMD_IRQREQA
+#define IOC_IRQCLRA	IOMD_IRQCLRA
+#define IOC_IRQMASKA	IOMD_IRQMASKA
+
+#define IOC_IRQSTATB	IOMD_IRQSTATB
+#define IOC_IRQREQB	IOMD_IRQREQB
+#define IOC_IRQMASKB	IOMD_IRQMASKB
+
+#define IOC_FIQSTAT	IOMD_FIQSTAT
+#define IOC_FIQREQ	IOMD_FIQREQ
+#define IOC_FIQMASK	IOMD_FIQMASK
+
+#define IOC_T0CNTL	IOMD_T0CNTL
+#define IOC_T0LTCHL	IOMD_T0LTCHL
+#define IOC_T0CNTH	IOMD_T0CNTH
+#define IOC_T0LTCHH	IOMD_T0LTCHH
+#define IOC_T0GO	IOMD_T0GO
+#define IOC_T0LATCH	IOMD_T0LATCH
+
+#define IOC_T1CNTL	IOMD_T1CNTL
+#define IOC_T1LTCHL	IOMD_T1LTCHL
+#define IOC_T1CNTH	IOMD_T1CNTH
+#define IOC_T1LTCHH	IOMD_T1LTCHH
+#define IOC_T1GO	IOMD_T1GO
+#define IOC_T1LATCH	IOMD_T1LATCH
+#endif
+
+/*
+ * DMA (MEMC) compatability
+ */
+#define HALF_SAM	vram_half_sam
+#define VDMA_ALIGNMENT	(HALF_SAM * 2)
+#define VDMA_XFERSIZE	(HALF_SAM)
+#define VDMA_INIT	IOMD_VIDINIT
+#define VDMA_START	IOMD_VIDSTART
+#define VDMA_END	IOMD_VIDEND
+
+#ifndef __ASSEMBLY__
+extern unsigned int vram_half_sam;
+#define video_set_dma(start,end,offset)				\
+do {								\
+	outl (SCREEN_START + start, VDMA_START);		\
+	outl (SCREEN_START + end - VDMA_XFERSIZE, VDMA_END);	\
+	if (offset >= end - VDMA_XFERSIZE)			\
+		offset |= 0x40000000;				\
+	outl (SCREEN_START + offset, VDMA_INIT);		\
+} while (0)
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/hardware/memc.h linux-2.4.29-uc1/include/asm-armnommu/hardware/memc.h
--- linux-2.4.29/include/asm-armnommu/hardware/memc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/hardware/memc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,26 @@
+/*
+ *  linux/include/asm-arm/hardware/memc.h
+ *
+ *  Copyright (C) Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define VDMA_ALIGNMENT	PAGE_SIZE
+#define VDMA_XFERSIZE	16
+#define VDMA_INIT	0
+#define VDMA_START	1
+#define VDMA_END	2
+
+#ifndef __ASSEMBLY__
+extern void memc_write(unsigned int reg, unsigned long val);
+
+#define video_set_dma(start,end,offset)				\
+do {								\
+	memc_write (VDMA_START, (start >> 2));			\
+	memc_write (VDMA_END, (end - VDMA_XFERSIZE) >> 2);	\
+	memc_write (VDMA_INIT, (offset >> 2));			\
+} while (0)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/hardware/pci_v3.h linux-2.4.29-uc1/include/asm-armnommu/hardware/pci_v3.h
--- linux-2.4.29/include/asm-armnommu/hardware/pci_v3.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/hardware/pci_v3.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,148 @@
+/*
+ *  linux/include/asm-arm/hardware/pci_v3.h
+ *
+ *  Internal header file PCI V3 chip
+ *
+ *  Copyright (C) ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef ASM_ARM_HARDWARE_PCI_V3_H
+#define ASM_ARM_HARDWARE_PCI_V3_H
+
+/* -------------------------------------------------------------------------------
+ *  V3 Local Bus to PCI Bridge definitions
+ * -------------------------------------------------------------------------------
+ *  Registers (these are taken from page 129 of the EPC User's Manual Rev 1.04
+ *  All V3 register names are prefaced by V3_ to avoid clashing with any other
+ *  PCI definitions.  Their names match the user's manual.
+ * 
+ *  I'm assuming that I20 is disabled.
+ * 
+ */
+#define V3_PCI_VENDOR                   0x00000000
+#define V3_PCI_DEVICE                   0x00000002
+#define V3_PCI_CMD                      0x00000004
+#define V3_PCI_STAT                     0x00000006
+#define V3_PCI_CC_REV                   0x00000008
+#define V3_PCI_HDR_CFG                  0x0000000C
+#define V3_PCI_IO_BASE                  0x00000010
+#define V3_PCI_BASE0                    0x00000014
+#define V3_PCI_BASE1                    0x00000018
+#define V3_PCI_SUB_VENDOR               0x0000002C
+#define V3_PCI_SUB_ID                   0x0000002E
+#define V3_PCI_ROM                      0x00000030
+#define V3_PCI_BPARAM                   0x0000003C
+#define V3_PCI_MAP0                     0x00000040
+#define V3_PCI_MAP1                     0x00000044
+#define V3_PCI_INT_STAT                 0x00000048
+#define V3_PCI_INT_CFG                  0x0000004C 
+#define V3_LB_BASE0                     0x00000054
+#define V3_LB_BASE1                     0x00000058
+#define V3_LB_MAP0                      0x0000005E
+#define V3_LB_MAP1                      0x00000062
+#define V3_LB_BASE2                     0x00000064
+#define V3_LB_MAP2                      0x00000066
+#define V3_LB_SIZE                      0x00000068
+#define V3_LB_IO_BASE                   0x0000006E
+#define V3_FIFO_CFG                     0x00000070
+#define V3_FIFO_PRIORITY                0x00000072
+#define V3_FIFO_STAT                    0x00000074
+#define V3_LB_ISTAT                     0x00000076
+#define V3_LB_IMASK                     0x00000077
+#define V3_SYSTEM                       0x00000078
+#define V3_LB_CFG                       0x0000007A
+#define V3_PCI_CFG                      0x0000007C
+#define V3_DMA_PCI_ADR0                 0x00000080
+#define V3_DMA_PCI_ADR1                 0x00000090
+#define V3_DMA_LOCAL_ADR0               0x00000084
+#define V3_DMA_LOCAL_ADR1               0x00000094
+#define V3_DMA_LENGTH0                  0x00000088
+#define V3_DMA_LENGTH1                  0x00000098
+#define V3_DMA_CSR0                     0x0000008B
+#define V3_DMA_CSR1                     0x0000009B
+#define V3_DMA_CTLB_ADR0                0x0000008C
+#define V3_DMA_CTLB_ADR1                0x0000009C
+#define V3_DMA_DELAY                    0x000000E0
+#define V3_MAIL_DATA                    0x000000C0
+#define V3_PCI_MAIL_IEWR                0x000000D0
+#define V3_PCI_MAIL_IERD                0x000000D2
+#define V3_LB_MAIL_IEWR                 0x000000D4
+#define V3_LB_MAIL_IERD                 0x000000D6
+#define V3_MAIL_WR_STAT                 0x000000D8
+#define V3_MAIL_RD_STAT                 0x000000DA
+#define V3_QBA_MAP                      0x000000DC
+
+/*  PCI COMMAND REGISTER bits
+ */
+#define V3_COMMAND_M_FBB_EN             (1 << 9)
+#define V3_COMMAND_M_SERR_EN            (1 << 8)
+#define V3_COMMAND_M_PAR_EN             (1 << 6)
+#define V3_COMMAND_M_MASTER_EN          (1 << 2)
+#define V3_COMMAND_M_MEM_EN             (1 << 1)
+#define V3_COMMAND_M_IO_EN              (1 << 0)
+
+/*  SYSTEM REGISTER bits
+ */
+#define V3_SYSTEM_M_RST_OUT             (1 << 15)
+#define V3_SYSTEM_M_LOCK                (1 << 14)
+
+/*  PCI_CFG bits
+ */
+#define V3_PCI_CFG_M_RETRY_EN           (1 << 10)
+#define V3_PCI_CFG_M_AD_LOW1            (1 << 9)
+#define V3_PCI_CFG_M_AD_LOW0            (1 << 8)
+
+/*  PCI_BASE register bits (PCI -> Local Bus)
+ */
+#define V3_PCI_BASE_M_ADR_BASE          0xFFF00000
+#define V3_PCI_BASE_M_ADR_BASEL         0x000FFF00
+#define V3_PCI_BASE_M_PREFETCH          (1 << 3)
+#define V3_PCI_BASE_M_TYPE              (3 << 1)
+#define V3_PCI_BASE_M_IO                (1 << 0)
+
+/*  PCI MAP register bits (PCI -> Local bus)
+ */
+#define V3_PCI_MAP_M_MAP_ADR            0xFFF00000
+#define V3_PCI_MAP_M_RD_POST_INH        (1 << 15)
+#define V3_PCI_MAP_M_ROM_SIZE           (3 << 10)
+#define V3_PCI_MAP_M_SWAP               (3 << 8)
+#define V3_PCI_MAP_M_ADR_SIZE           0x000000F0
+#define V3_PCI_MAP_M_REG_EN             (1 << 1)
+#define V3_PCI_MAP_M_ENABLE             (1 << 0)
+
+/*  9 => 512M window size
+ */
+#define V3_PCI_MAP_M_ADR_SIZE_512M      0x00000090
+/*  A => 1024M window size
+ */
+#define V3_PCI_MAP_M_ADR_SIZE_1024M     0x000000A0      
+
+/*  LB_BASE register bits (Local bus -> PCI)
+ */
+#define V3_LB_BASE_M_MAP_ADR            0xFFF00000
+#define V3_LB_BASE_M_SWAP               (3 << 8)
+#define V3_LB_BASE_M_ADR_SIZE           0x000000F0
+#define V3_LB_BASE_M_PREFETCH           (1 << 3)
+#define V3_LB_BASE_M_ENABLE             (1 << 0)
+
+/*  LB_MAP register bits (Local bus -> PCI)
+ */
+#define V3_LB_MAP_M_MAP_ADR             0xFFF0
+#define V3_LB_MAP_M_TYPE                0x000E
+#define V3_LB_MAP_M_AD_LOW_EN           (1 << 0)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/hardware/serial_amba.h linux-2.4.29-uc1/include/asm-armnommu/hardware/serial_amba.h
--- linux-2.4.29/include/asm-armnommu/hardware/serial_amba.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/hardware/serial_amba.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,94 @@
+/*
+ *  linux/include/asm-arm/hardware/serial_amba.h
+ *
+ *  Internal header file for AMBA serial ports
+ *
+ *  Copyright (C) ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef ASM_ARM_HARDWARE_SERIAL_AMBA_H
+#define ASM_ARM_HARDWARE_SERIAL_AMBA_H
+
+/* -------------------------------------------------------------------------------
+ *  From AMBA UART (PL010) Block Specification (ARM-0001-CUST-DSPC-A03)
+ * -------------------------------------------------------------------------------
+ *  UART Register Offsets.
+ */
+#define AMBA_UARTDR                     0x00	 /*  Data read or written from the interface. */
+#define AMBA_UARTRSR                    0x04	 /*  Receive status register (Read). */
+#define AMBA_UARTECR                    0x04	 /*  Error clear register (Write). */
+#define AMBA_UARTLCR_H                  0x08	 /*  Line control register, high byte. */
+#define AMBA_UARTLCR_M                  0x0C	 /*  Line control register, middle byte. */
+#define AMBA_UARTLCR_L                  0x10	 /*  Line control register, low byte. */
+#define AMBA_UARTCR                     0x14	 /*  Control register. */
+#define AMBA_UARTFR                     0x18	 /*  Flag register (Read only). */
+#define AMBA_UARTIIR                    0x1C	 /*  Interrupt indentification register (Read). */
+#define AMBA_UARTICR                    0x1C	 /*  Interrupt clear register (Write). */
+#define AMBA_UARTILPR                   0x20	 /*  IrDA low power counter register. */
+
+#define AMBA_UARTRSR_OE                 0x08
+#define AMBA_UARTRSR_BE                 0x04
+#define AMBA_UARTRSR_PE                 0x02
+#define AMBA_UARTRSR_FE                 0x01
+
+#define AMBA_UARTFR_TXFF                0x20
+#define AMBA_UARTFR_RXFE                0x10
+#define AMBA_UARTFR_BUSY                0x08
+#define AMBA_UARTFR_DCD			0x04
+#define AMBA_UARTFR_DSR			0x02
+#define AMBA_UARTFR_CTS			0x01
+#define AMBA_UARTFR_TMSK                (AMBA_UARTFR_TXFF + AMBA_UARTFR_BUSY)
+ 
+#define AMBA_UARTCR_RTIE                0x40
+#define AMBA_UARTCR_TIE                 0x20
+#define AMBA_UARTCR_RIE                 0x10
+#define AMBA_UARTCR_MSIE                0x08
+#define AMBA_UARTCR_IIRLP               0x04
+#define AMBA_UARTCR_SIREN               0x02
+#define AMBA_UARTCR_UARTEN              0x01
+ 
+#define AMBA_UARTLCR_H_WLEN_8           0x60
+#define AMBA_UARTLCR_H_WLEN_7           0x40
+#define AMBA_UARTLCR_H_WLEN_6           0x20
+#define AMBA_UARTLCR_H_WLEN_5           0x00
+#define AMBA_UARTLCR_H_FEN              0x10
+#define AMBA_UARTLCR_H_STP2             0x08
+#define AMBA_UARTLCR_H_EPS              0x04
+#define AMBA_UARTLCR_H_PEN              0x02
+#define AMBA_UARTLCR_H_BRK              0x01
+
+#define AMBA_UARTIIR_RTIS               0x08
+#define AMBA_UARTIIR_TIS                0x04
+#define AMBA_UARTIIR_RIS                0x02
+#define AMBA_UARTIIR_MIS                0x01
+
+#define ARM_BAUD_460800                 1
+#define ARM_BAUD_230400                 3
+#define ARM_BAUD_115200                 7
+#define ARM_BAUD_57600                  15
+#define ARM_BAUD_38400                  23
+#define ARM_BAUD_19200                  47
+#define ARM_BAUD_14400                  63
+#define ARM_BAUD_9600                   95
+#define ARM_BAUD_4800                   191
+#define ARM_BAUD_2400                   383
+#define ARM_BAUD_1200                   767
+
+#define AMBA_UARTRSR_ANY	(AMBA_UARTRSR_OE|AMBA_UARTRSR_BE|AMBA_UARTRSR_PE|AMBA_UARTRSR_FE)
+#define AMBA_UARTFR_MODEM_ANY	(AMBA_UARTFR_DCD|AMBA_UARTFR_DSR|AMBA_UARTFR_CTS)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/hardware.h linux-2.4.29-uc1/include/asm-armnommu/hardware.h
--- linux-2.4.29/include/asm-armnommu/hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/hardware.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,18 @@
+/*
+ *  linux/include/asm-arm/hardware.h
+ *
+ *  Copyright (C) 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Common hardware definitions
+ */
+
+#ifndef __ASM_HARDWARE_H
+#define __ASM_HARDWARE_H
+
+#include <asm/arch/hardware.h>
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/hdreg.h linux-2.4.29-uc1/include/asm-armnommu/hdreg.h
--- linux-2.4.29/include/asm-armnommu/hdreg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/hdreg.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,13 @@
+/*
+ *  linux/include/asm-arm/hdreg.h
+ *
+ *  Copyright (C) 1994-1996  Linus Torvalds & authors
+ */
+
+#ifndef __ASMARM_HDREG_H
+#define __ASMARM_HDREG_H
+
+typedef unsigned long ide_ioreg_t;
+
+#endif /* __ASMARM_HDREG_H */
+
diff -urN linux-2.4.29/include/asm-armnommu/hw_irq.h linux-2.4.29-uc1/include/asm-armnommu/hw_irq.h
--- linux-2.4.29/include/asm-armnommu/hw_irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/hw_irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1 @@
+/* place holder for now */
diff -urN linux-2.4.29/include/asm-armnommu/ide.h linux-2.4.29-uc1/include/asm-armnommu/ide.h
--- linux-2.4.29/include/asm-armnommu/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/ide.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ *  linux/include/asm-armnommu/ide.h
+ *
+ *  Copyright (C) 1994-1996  Linus Torvalds & authors
+ */
+
+/*
+ *  This file contains the i386 architecture specific IDE code.
+ */
+
+#ifndef __ASMARMNOMMU_IDE_H
+#define __ASMARMNOMMU_IDE_H
+
+#ifdef __KERNEL__
+
+#ifndef MAX_HWIFS
+#define MAX_HWIFS	4
+#endif
+
+#include <asm/arch/ide.h>
+
+/*
+ * We always use the new IDE port registering,
+ * so these are fixed here.
+ */
+#define ide_default_io_base(i)		((ide_ioreg_t)0)
+#define ide_default_irq(b)		(0)
+
+#include <asm-generic/ide_iops.h>
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASMARMNOMMU_IDE_H */
diff -urN linux-2.4.29/include/asm-armnommu/ioc.h linux-2.4.29-uc1/include/asm-armnommu/ioc.h
--- linux-2.4.29/include/asm-armnommu/ioc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/ioc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,59 @@
+/*
+ * Use these macros to read/write the IOC.  All it does is perform the actual
+ * read/write.
+ */
+
+#ifndef IOC_CONTROL
+
+#ifndef __ASSEMBLY__
+#define __IOC(offset)	(IOC_BASE + (offset >> 2))
+#else
+#define __IOC(offset)	offset
+#endif
+
+#define IOC_CONTROL	__IOC(0x00)
+#define IOC_KARTTX	__IOC(0x04)
+#define IOC_KARTRX	__IOC(0x04)
+
+#define IOC_IRQSTATA	__IOC(0x10)
+#define IOC_IRQREQA	__IOC(0x14)
+#define IOC_IRQCLRA	__IOC(0x14)
+#define IOC_IRQMASKA	__IOC(0x18)
+
+#define IOC_IRQSTATB	__IOC(0x20)
+#define IOC_IRQREQB	__IOC(0x24)
+#define IOC_IRQMASKB	__IOC(0x28)
+
+#define IOC_FIQSTAT	__IOC(0x30)
+#define IOC_FIQREQ	__IOC(0x34)
+#define IOC_FIQMASK	__IOC(0x38)
+
+#define IOC_T0CNTL	__IOC(0x40)
+#define IOC_T0LTCHL	__IOC(0x40)
+#define IOC_T0CNTH	__IOC(0x44)
+#define IOC_T0LTCHH	__IOC(0x44)
+#define IOC_T0GO	__IOC(0x48)
+#define IOC_T0LATCH	__IOC(0x4c)
+
+#define IOC_T1CNTL	__IOC(0x50)
+#define IOC_T1LTCHL	__IOC(0x50)
+#define IOC_T1CNTH	__IOC(0x54)
+#define IOC_T1LTCHH	__IOC(0x54)
+#define IOC_T1GO	__IOC(0x58)
+#define IOC_T1LATCH	__IOC(0x5c)
+
+#define IOC_T2CNTL	__IOC(0x60)
+#define IOC_T2LTCHL	__IOC(0x60)
+#define IOC_T2CNTH	__IOC(0x64)
+#define IOC_T2LTCHH	__IOC(0x64)
+#define IOC_T2GO	__IOC(0x68)
+#define IOC_T2LATCH	__IOC(0x6c)
+
+#define IOC_T3CNTL	__IOC(0x70)
+#define IOC_T3LTCHL	__IOC(0x70)
+#define IOC_T3CNTH	__IOC(0x74)
+#define IOC_T3LTCHH	__IOC(0x74)
+#define IOC_T3GO	__IOC(0x78)
+#define IOC_T3LATCH	__IOC(0x7c)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/ioctl.h linux-2.4.29-uc1/include/asm-armnommu/ioctl.h
--- linux-2.4.29/include/asm-armnommu/ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/ioctl.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,74 @@
+/*
+ * linux/ioctl.h for Linux by H.H. Bergman.
+ */
+
+#ifndef _ASMARM_IOCTL_H
+#define _ASMARM_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	14
+#define _IOC_DIRBITS	2
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE	0U
+#define _IOC_WRITE	1U
+#define _IOC_READ	2U
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* _ASMARM_IOCTL_H */
diff -urN linux-2.4.29/include/asm-armnommu/ioctls.h linux-2.4.29-uc1/include/asm-armnommu/ioctls.h
--- linux-2.4.29/include/asm-armnommu/ioctls.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/ioctls.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,81 @@
+#ifndef __ASM_ARM_IOCTLS_H
+#define __ASM_ARM_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+#define TIOCSBRK	0x5427  /* BSD compatibility */
+#define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define FIONCLEX	0x5450  /* these numbers need to be adjusted. */
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+#define FIOQSIZE	0x545E
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+#define TIOCSER_TEMT	0x01	/* Transmitter physically empty */
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/io.h linux-2.4.29-uc1/include/asm-armnommu/io.h
--- linux-2.4.29/include/asm-armnommu/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,320 @@
+/*
+ *  linux/include/asm-arm/io.h
+ *
+ *  Copyright (C) 1996-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Modifications:
+ *  16-Sep-1996	RMK	Inlined the inx/outx functions & optimised for both
+ *			constant addresses and variable addresses.
+ *  04-Dec-1997	RMK	Moved a lot of this stuff to the new architecture
+ *			specific IO header files.
+ *  27-Mar-1999	PJB	Second parameter of memcpy_toio is const..
+ *  04-Apr-1999	PJB	Added check_signature.
+ *  12-Dec-1999	RMK	More cleanups
+ *  18-Jun-2000 RMK	Removed virt_to_* and friends definitions
+ */
+#ifndef __ASM_ARM_IO_H
+#define __ASM_ARM_IO_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <asm/memory.h>
+#include <asm/byteorder.h>
+#include <asm/arch/hardware.h>
+
+/*
+ * Generic virtual read/write.  Note that we don't support half-word
+ * read/writes.  We define __arch_*[bl] here, and leave __arch_*w
+ * to the architecture specific code.
+ */
+#define __arch_getb(a)			(*(volatile unsigned char *)(a))
+#define __arch_getl(a)			(*(volatile unsigned int  *)(a))
+
+#define __arch_putb(v,a)		(*(volatile unsigned char *)(a) = (v))
+#define __arch_putl(v,a)		(*(volatile unsigned int  *)(a) = (v))
+
+extern void __raw_writesb(unsigned int addr, const void *data, int bytelen);
+extern void __raw_writesw(unsigned int addr, const void *data, int wordlen);
+extern void __raw_writesl(unsigned int addr, const void *data, int longlen);
+
+extern void __raw_readsb(unsigned int addr, void *data, int bytelen);
+extern void __raw_readsw(unsigned int addr, void *data, int wordlen);
+extern void __raw_readsl(unsigned int addr, void *data, int longlen);
+
+#define __raw_writeb(v,a)		__arch_putb(v,a)
+#define __raw_writew(v,a)		__arch_putw(v,a)
+#define __raw_writel(v,a)		__arch_putl(v,a)
+
+#define __raw_readb(a)			__arch_getb(a)
+#define __raw_readw(a)			__arch_getw(a)
+#define __raw_readl(a)			__arch_getl(a)
+
+/*
+ * The compiler seems to be incapable of optimising constants
+ * properly.  Spell it out to the compiler in some cases.
+ * These are only valid for small values of "off" (< 1<<12)
+ */
+#define __raw_base_writeb(val,base,off)	__arch_base_putb(val,base,off)
+#define __raw_base_writew(val,base,off)	__arch_base_putw(val,base,off)
+#define __raw_base_writel(val,base,off)	__arch_base_putl(val,base,off)
+
+#define __raw_base_readb(base,off)	__arch_base_getb(base,off)
+#define __raw_base_readw(base,off)	__arch_base_getw(base,off)
+#define __raw_base_readl(base,off)	__arch_base_getl(base,off)
+
+/*
+ * Now, pick up the machine-defined IO definitions
+ */
+#include <asm/arch/io.h>
+
+/*
+ *  IO port access primitives
+ *  -------------------------
+ *
+ * The ARM doesn't have special IO access instructions; all IO is memory
+ * mapped.  Note that these are defined to perform little endian accesses
+ * only.  Their primary purpose is to access PCI and ISA peripherals.
+ *
+ * Note that for a big endian machine, this implies that the following
+ * big endian mode connectivity is in place, as described by numerious
+ * ARM documents:
+ *
+ *    PCI:  D0-D7   D8-D15 D16-D23 D24-D31
+ *    ARM: D24-D31 D16-D23  D8-D15  D0-D7
+ *
+ * The machine specific io.h include defines __io to translate an "IO"
+ * address to a memory address.
+ *
+ * Note that we prevent GCC re-ordering or caching values in expressions
+ * by introducing sequence points into the in*() definitions.  Note that
+ * __raw_* do not guarantee this behaviour.
+ *
+ * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.
+ */
+#ifdef __io
+
+#ifndef __iob
+  #define __iob(a) __io(a)
+#endif
+
+#ifdef __io_noswap
+#define outb(v,p)			__raw_writeb(v,__iob(p))
+#define outw(v,p)			__raw_writew(v,__io(p))
+#define outl(v,p)			__raw_writel(v,__io(p))
+
+#define inb(p)	({ unsigned int __v = __raw_readb(__iob(p)); __v; })
+#define inw(p)	({ unsigned int __v = __raw_readw(__io(p)); __v; })
+#define inl(p)	({ unsigned int __v = __raw_readl(__io(p)); __v; })
+#else
+#define outb(v,p)			__raw_writeb(v,__iob(p))
+#define outw(v,p)			__raw_writew(cpu_to_le16(v),__io(p))
+#define outl(v,p)			__raw_writel(cpu_to_le32(v),__io(p))
+
+#define inb(p)	({ unsigned int __v = __raw_readb(__iob(p)); __v; })
+#define inw(p)	({ unsigned int __v = le16_to_cpu(__raw_readw(__io(p))); __v; })
+#define inl(p)	({ unsigned int __v = le32_to_cpu(__raw_readl(__io(p))); __v; })
+#endif
+
+#define outsb(p,d,l)			__raw_writesb(__iob(p),d,l)
+#define outsw(p,d,l)			__raw_writesw(__io(p),d,l)
+#define outsl(p,d,l)			__raw_writesl(__io(p),d,l)
+
+#define insb(p,d,l)			__raw_readsb(__iob(p),d,l)
+#define insw(p,d,l)			__raw_readsw(__io(p),d,l)
+#define insl(p,d,l)			__raw_readsl(__io(p),d,l)
+#endif
+
+#define outb_p(val,port)		outb((val),(port))
+#define outw_p(val,port)		outw((val),(port))
+#define outl_p(val,port)		outl((val),(port))
+#define inb_p(port)			inb((port))
+#define inw_p(port)			inw((port))
+#define inl_p(port)			inl((port))
+
+#define outsb_p(port,from,len)		outsb(port,from,len)
+#define outsw_p(port,from,len)		outsw(port,from,len)
+#define outsl_p(port,from,len)		outsl(port,from,len)
+#define insb_p(port,to,len)		insb(port,to,len)
+#define insw_p(port,to,len)		insw(port,to,len)
+#define insl_p(port,to,len)		insl(port,to,len)
+
+/*
+ * ioremap and friends.
+ *
+ * ioremap takes a PCI memory address, as specified in
+ * linux/Documentation/IO-mapping.txt.  If you want a
+ * physical address, use __ioremap instead.
+ */
+extern void * __ioremap(unsigned long offset, size_t size, unsigned long flags);
+extern void __iounmap(void *addr);
+
+/*
+ * Generic ioremap support.
+ *
+ * Define:
+ *  iomem_valid_addr(off,size)
+ *  iomem_to_phys(off)
+ */
+#ifdef iomem_valid_addr
+#define __arch_ioremap(off,sz,nocache)				\
+ ({								\
+	unsigned long _off = (off), _size = (sz);		\
+	void *_ret = (void *)0;					\
+	if (iomem_valid_addr(_off, _size))			\
+		_ret = __ioremap(iomem_to_phys(_off),_size,0);	\
+	_ret;							\
+ })
+
+#define __arch_iounmap __iounmap
+#endif
+
+#define ioremap(off,sz)			__arch_ioremap((off),(sz),0)
+#define ioremap_nocache(off,sz)		__arch_ioremap((off),(sz),1)
+#define iounmap(_addr)			__arch_iounmap(_addr)
+
+/*
+ * DMA-consistent mapping functions.  These allocate/free a region of
+ * uncached, unwrite-buffered mapped memory space for use with DMA
+ * devices.  This is the "generic" version.  The PCI specific version
+ * is in pci.h
+ */
+extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle);
+extern void consistent_free(void *vaddr, size_t size, dma_addr_t handle);
+extern void consistent_sync(void *vaddr, size_t size, int rw);
+
+/*
+ * String version of IO memory access ops:
+ */
+extern void _memcpy_fromio(void *, unsigned long, size_t);
+extern void _memcpy_toio(unsigned long, const void *, size_t);
+extern void _memset_io(unsigned long, int, size_t);
+
+extern void __readwrite_bug(const char *fn);
+
+/*
+ * If this architecture has PCI memory IO, then define the read/write
+ * macros.  These should only be used with the cookie passed from
+ * ioremap.
+ */
+#ifdef __mem_pci
+
+#ifdef __io_noswap
+#define readb(c) ({ unsigned int __v = __raw_readb(__mem_pci(c)); __v; })
+#define readw(c) ({ unsigned int __v = __raw_readw(__mem_pci(c)); __v; })
+#define readl(c) ({ unsigned int __v = __raw_readl(__mem_pci(c)); __v; })
+
+#define writeb(v,c)		__raw_writeb(v,__mem_pci(c))
+#define writew(v,c)		__raw_writew(v,__mem_pci(c))
+#define writel(v,c)		__raw_writel(v,__mem_pci(c))
+#else
+#define readb(c) ({ unsigned int __v = __raw_readb(__mem_pci(c)); __v; })
+#define readw(c) ({ unsigned int __v = le16_to_cpu(__raw_readw(__mem_pci(c))); __v; })
+#define readl(c) ({ unsigned int __v = le32_to_cpu(__raw_readl(__mem_pci(c))); __v; })
+
+#define writeb(v,c)		__raw_writeb(v,__mem_pci(c))
+#define writew(v,c)		__raw_writew(cpu_to_le16(v),__mem_pci(c))
+#define writel(v,c)		__raw_writel(cpu_to_le32(v),__mem_pci(c))
+#endif
+
+#define memset_io(c,v,l)		_memset_io(__mem_pci(c),(v),(l))
+#define memcpy_fromio(a,c,l)		_memcpy_fromio((a),__mem_pci(c),(l))
+#define memcpy_toio(c,a,l)		_memcpy_toio(__mem_pci(c),(a),(l))
+
+#define eth_io_copy_and_sum(s,c,l,b) \
+				eth_copy_and_sum((s),__mem_pci(c),(l),(b))
+
+static inline int
+check_signature(unsigned long io_addr, const unsigned char *signature,
+		int length)
+{
+	int retval = 0;
+	do {
+		if (readb(io_addr) != *signature)
+			goto out;
+		io_addr++;
+		signature++;
+		length--;
+	} while (length);
+	retval = 1;
+out:
+	return retval;
+}
+
+#elif !defined(readb)
+
+#define readb(addr)			(__readwrite_bug("readb"),0)
+#define readw(addr)			(__readwrite_bug("readw"),0)
+#define readl(addr)			(__readwrite_bug("readl"),0)
+#define writeb(v,addr)			__readwrite_bug("writeb")
+#define writew(v,addr)			__readwrite_bug("writew")
+#define writel(v,addr)			__readwrite_bug("writel")
+
+#define eth_io_copy_and_sum(a,b,c,d)	__readwrite_bug("eth_io_copy_and_sum")
+
+#define check_signature(io,sig,len)	(0)
+
+#endif	/* __mem_pci */
+
+/*
+ * If this architecture has ISA IO, then define the isa_read/isa_write
+ * macros.
+ */
+#ifdef __mem_isa
+
+#define isa_readb(addr)			__raw_readb(__mem_isa(addr))
+#define isa_readw(addr)			__raw_readw(__mem_isa(addr))
+#define isa_readl(addr)			__raw_readl(__mem_isa(addr))
+#define isa_writeb(val,addr)		__raw_writeb(val,__mem_isa(addr))
+#define isa_writew(val,addr)		__raw_writew(val,__mem_isa(addr))
+#define isa_writel(val,addr)		__raw_writel(val,__mem_isa(addr))
+#define isa_memset_io(a,b,c)		_memset_io(__mem_isa(a),(b),(c))
+#define isa_memcpy_fromio(a,b,c)	_memcpy_fromio((a),__mem_isa(b),(c))
+#define isa_memcpy_toio(a,b,c)		_memcpy_toio(__mem_isa((a)),(b),(c))
+
+#define isa_eth_io_copy_and_sum(a,b,c,d) \
+				eth_copy_and_sum((a),__mem_isa(b),(c),(d))
+
+static inline int
+isa_check_signature(unsigned long io_addr, const unsigned char *signature,
+		    int length)
+{
+	int retval = 0;
+	do {
+		if (isa_readb(io_addr) != *signature)
+			goto out;
+		io_addr++;
+		signature++;
+		length--;
+	} while (length);
+	retval = 1;
+out:
+	return retval;
+}
+
+#else	/* __mem_isa */
+
+#define isa_readb(addr)			(__readwrite_bug("isa_readb"),0)
+#define isa_readw(addr)			(__readwrite_bug("isa_readw"),0)
+#define isa_readl(addr)			(__readwrite_bug("isa_readl"),0)
+#define isa_writeb(val,addr)		__readwrite_bug("isa_writeb")
+#define isa_writew(val,addr)		__readwrite_bug("isa_writew")
+#define isa_writel(val,addr)		__readwrite_bug("isa_writel")
+#define isa_memset_io(a,b,c)		__readwrite_bug("isa_memset_io")
+#define isa_memcpy_fromio(a,b,c)	__readwrite_bug("isa_memcpy_fromio")
+#define isa_memcpy_toio(a,b,c)		__readwrite_bug("isa_memcpy_toio")
+
+#define isa_eth_io_copy_and_sum(a,b,c,d) \
+				__readwrite_bug("isa_eth_io_copy_and_sum")
+
+#define isa_check_signature(io,sig,len)	(0)
+
+#endif	/* __mem_isa */
+
+#endif	/* __KERNEL__ */
+#endif	/* __ASM_ARM_IO_H */
diff -urN linux-2.4.29/include/asm-armnommu/iomd.h linux-2.4.29-uc1/include/asm-armnommu/iomd.h
--- linux-2.4.29/include/asm-armnommu/iomd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/iomd.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,245 @@
+/*
+ * linux/include/asm-arm/iomd.h
+ *
+ * Copyright (C) 1999 Russell King
+ *
+ * This file contains information out the IOMD ASIC used in the
+ * Acorn RiscPC and subsequently integrated into the CLPS7500 chips.
+ */
+#include <linux/config.h>
+
+#ifndef __ASSEMBLY__
+#define __IOMD(offset)	(IO_IOMD_BASE + (offset >> 2))
+#else
+#define __IOMD(offset)	offset
+#endif
+
+#define IOMD_CONTROL	__IOMD(0x000)
+#define IOMD_KARTTX	__IOMD(0x004)
+#define IOMD_KARTRX	__IOMD(0x004)
+#define IOMD_KCTRL	__IOMD(0x008)
+
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_IOLINES	__IOMD(0x00C)
+#endif
+
+#define IOMD_IRQSTATA	__IOMD(0x010)
+#define IOMD_IRQREQA	__IOMD(0x014)
+#define IOMD_IRQCLRA	__IOMD(0x014)
+#define IOMD_IRQMASKA	__IOMD(0x018)
+
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_SUSMODE	__IOMD(0x01C)
+#endif
+
+#define IOMD_IRQSTATB	__IOMD(0x020)
+#define IOMD_IRQREQB	__IOMD(0x024)
+#define IOMD_IRQMASKB	__IOMD(0x028)
+
+#define IOMD_FIQSTAT	__IOMD(0x030)
+#define IOMD_FIQREQ	__IOMD(0x034)
+#define IOMD_FIQMASK	__IOMD(0x038)
+
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_CLKCTL	__IOMD(0x03C)
+#endif
+
+#define IOMD_T0CNTL	__IOMD(0x040)
+#define IOMD_T0LTCHL	__IOMD(0x040)
+#define IOMD_T0CNTH	__IOMD(0x044)
+#define IOMD_T0LTCHH	__IOMD(0x044)
+#define IOMD_T0GO	__IOMD(0x048)
+#define IOMD_T0LATCH	__IOMD(0x04c)
+
+#define IOMD_T1CNTL	__IOMD(0x050)
+#define IOMD_T1LTCHL	__IOMD(0x050)
+#define IOMD_T1CNTH	__IOMD(0x054)
+#define IOMD_T1LTCHH	__IOMD(0x054)
+#define IOMD_T1GO	__IOMD(0x058)
+#define IOMD_T1LATCH	__IOMD(0x05c)
+
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_IRQSTATC	__IOMD(0x060)
+#define IOMD_IRQREQC	__IOMD(0x064)
+#define IOMD_IRQMASKC	__IOMD(0x068)
+
+#define IOMD_VIDMUX	__IOMD(0x06c)
+
+#define IOMD_IRQSTATD	__IOMD(0x070)
+#define IOMD_IRQREQD	__IOMD(0x074)
+#define IOMD_IRQMASKD	__IOMD(0x078)
+#endif
+
+#define IOMD_ROMCR0	__IOMD(0x080)
+#define IOMD_ROMCR1	__IOMD(0x084)
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_DRAMCR	__IOMD(0x088)
+#endif
+#define IOMD_REFCR	__IOMD(0x08C)
+
+#define IOMD_FSIZE	__IOMD(0x090)
+#define IOMD_ID0	__IOMD(0x094)
+#define IOMD_ID1	__IOMD(0x098)
+#define IOMD_VERSION	__IOMD(0x09C)
+
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_MOUSEX	__IOMD(0x0A0)
+#define IOMD_MOUSEY	__IOMD(0x0A4)
+#endif
+
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_MSEDAT	__IOMD(0x0A8)
+#define IOMD_MSECTL	__IOMD(0x0Ac)
+#endif
+
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_DMATCR	__IOMD(0x0C0)
+#endif
+#define IOMD_IOTCR	__IOMD(0x0C4)
+#define IOMD_ECTCR	__IOMD(0x0C8)
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_DMAEXT	__IOMD(0x0CC)
+#endif
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_ASTCR	__IOMD(0x0CC)
+#define IOMD_DRAMCR	__IOMD(0x0D0)
+#define IOMD_SELFREF	__IOMD(0x0D4)
+#define IOMD_ATODICR	__IOMD(0x0E0)
+#define IOMD_ATODSR	__IOMD(0x0E4)
+#define IOMD_ATODCC	__IOMD(0x0E8)
+#define IOMD_ATODCNT1	__IOMD(0x0EC)
+#define IOMD_ATODCNT2	__IOMD(0x0F0)
+#define IOMD_ATODCNT3	__IOMD(0x0F4)
+#define IOMD_ATODCNT4	__IOMD(0x0F8)
+#endif
+
+#ifdef CONFIG_ARCH_RPC
+#define DMA_EXT_IO0	1
+#define DMA_EXT_IO1	2
+#define DMA_EXT_IO2	4
+#define DMA_EXT_IO3	8
+
+#define IOMD_IO0CURA	__IOMD(0x100)
+#define IOMD_IO0ENDA	__IOMD(0x104)
+#define IOMD_IO0CURB	__IOMD(0x108)
+#define IOMD_IO0ENDB	__IOMD(0x10C)
+#define IOMD_IO0CR	__IOMD(0x110)
+#define IOMD_IO0ST	__IOMD(0x114)
+
+#define IOMD_IO1CURA	__IOMD(0x120)
+#define IOMD_IO1ENDA	__IOMD(0x124)
+#define IOMD_IO1CURB	__IOMD(0x128)
+#define IOMD_IO1ENDB	__IOMD(0x12C)
+#define IOMD_IO1CR	__IOMD(0x130)
+#define IOMD_IO1ST	__IOMD(0x134)
+
+#define IOMD_IO2CURA	__IOMD(0x140)
+#define IOMD_IO2ENDA	__IOMD(0x144)
+#define IOMD_IO2CURB	__IOMD(0x148)
+#define IOMD_IO2ENDB	__IOMD(0x14C)
+#define IOMD_IO2CR	__IOMD(0x150)
+#define IOMD_IO2ST	__IOMD(0x154)
+
+#define IOMD_IO3CURA	__IOMD(0x160)
+#define IOMD_IO3ENDA	__IOMD(0x164)
+#define IOMD_IO3CURB	__IOMD(0x168)
+#define IOMD_IO3ENDB	__IOMD(0x16C)
+#define IOMD_IO3CR	__IOMD(0x170)
+#define IOMD_IO3ST	__IOMD(0x174)
+#endif
+
+#define IOMD_SD0CURA	__IOMD(0x180)
+#define IOMD_SD0ENDA	__IOMD(0x184)
+#define IOMD_SD0CURB	__IOMD(0x188)
+#define IOMD_SD0ENDB	__IOMD(0x18C)
+#define IOMD_SD0CR	__IOMD(0x190)
+#define IOMD_SD0ST	__IOMD(0x194)
+
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_SD1CURA	__IOMD(0x1A0)
+#define IOMD_SD1ENDA	__IOMD(0x1A4)
+#define IOMD_SD1CURB	__IOMD(0x1A8)
+#define IOMD_SD1ENDB	__IOMD(0x1AC)
+#define IOMD_SD1CR	__IOMD(0x1B0)
+#define IOMD_SD1ST	__IOMD(0x1B4)
+#endif
+
+#define IOMD_CURSCUR	__IOMD(0x1C0)
+#define IOMD_CURSINIT	__IOMD(0x1C4)
+
+#define IOMD_VIDCUR	__IOMD(0x1D0)
+#define IOMD_VIDEND	__IOMD(0x1D4)
+#define IOMD_VIDSTART	__IOMD(0x1D8)
+#define IOMD_VIDINIT	__IOMD(0x1DC)
+#define IOMD_VIDCR	__IOMD(0x1E0)
+
+#define IOMD_DMASTAT	__IOMD(0x1F0)
+#define IOMD_DMAREQ	__IOMD(0x1F4)
+#define IOMD_DMAMASK	__IOMD(0x1F8)
+
+#define DMA_END_S	(1 << 31)
+#define DMA_END_L	(1 << 30)
+
+#define DMA_CR_C	0x80
+#define DMA_CR_D	0x40
+#define DMA_CR_E	0x20
+
+#define DMA_ST_OFL	4
+#define DMA_ST_INT	2
+#define DMA_ST_AB	1
+
+#ifndef IOC_CONTROL
+/*
+ * IOC compatability
+ */
+#define IOC_CONTROL	IOMD_CONTROL
+#define IOC_IRQSTATA	IOMD_IRQSTATA
+#define IOC_IRQREQA	IOMD_IRQREQA
+#define IOC_IRQCLRA	IOMD_IRQCLRA
+#define IOC_IRQMASKA	IOMD_IRQMASKA
+
+#define IOC_IRQSTATB	IOMD_IRQSTATB
+#define IOC_IRQREQB	IOMD_IRQREQB
+#define IOC_IRQMASKB	IOMD_IRQMASKB
+
+#define IOC_FIQSTAT	IOMD_FIQSTAT
+#define IOC_FIQREQ	IOMD_FIQREQ
+#define IOC_FIQMASK	IOMD_FIQMASK
+
+#define IOC_T0CNTL	IOMD_T0CNTL
+#define IOC_T0LTCHL	IOMD_T0LTCHL
+#define IOC_T0CNTH	IOMD_T0CNTH
+#define IOC_T0LTCHH	IOMD_T0LTCHH
+#define IOC_T0GO	IOMD_T0GO
+#define IOC_T0LATCH	IOMD_T0LATCH
+
+#define IOC_T1CNTL	IOMD_T1CNTL
+#define IOC_T1LTCHL	IOMD_T1LTCHL
+#define IOC_T1CNTH	IOMD_T1CNTH
+#define IOC_T1LTCHH	IOMD_T1LTCHH
+#define IOC_T1GO	IOMD_T1GO
+#define IOC_T1LATCH	IOMD_T1LATCH
+#endif
+
+/*
+ * DMA (MEMC) compatability
+ */
+#define HALF_SAM	vram_half_sam
+#define VDMA_ALIGNMENT	(HALF_SAM * 2)
+#define VDMA_XFERSIZE	(HALF_SAM)
+#define VDMA_INIT	IOMD_VIDINIT
+#define VDMA_START	IOMD_VIDSTART
+#define VDMA_END	IOMD_VIDEND
+
+#ifndef __ASSEMBLY__
+extern unsigned int vram_half_sam;
+#define video_set_dma(start,end,offset)				\
+do {								\
+	outl (SCREEN_START + start, VDMA_START);		\
+	outl (SCREEN_START + end - VDMA_XFERSIZE, VDMA_END);	\
+	if (offset >= end - VDMA_XFERSIZE)			\
+		offset |= 0x40000000;				\
+	outl (SCREEN_START + offset, VDMA_INIT);		\
+} while (0)
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/ipcbuf.h linux-2.4.29-uc1/include/asm-armnommu/ipcbuf.h
--- linux-2.4.29/include/asm-armnommu/ipcbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/ipcbuf.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,29 @@
+#ifndef __ASMARM_IPCBUF_H
+#define __ASMARM_IPCBUF_H
+
+/*
+ * The ipc64_perm structure for arm architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
+	__kernel_mode_t		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* __ASMARM_IPCBUF_H */
diff -urN linux-2.4.29/include/asm-armnommu/ipc.h linux-2.4.29-uc1/include/asm-armnommu/ipc.h
--- linux-2.4.29/include/asm-armnommu/ipc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/ipc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,28 @@
+#ifndef __ASMARM_IPC_H
+#define __ASMARM_IPC_H
+
+/* 
+ * These are used to wrap system calls on ARM.
+ *
+ * See arch/arm/kernel/sys-arm.c for ugly details..
+ */
+struct ipc_kludge {
+	struct msgbuf *msgp;
+	long msgtyp;
+};
+
+#define SEMOP		 1
+#define SEMGET		 2
+#define SEMCTL		 3
+#define MSGSND		11
+#define MSGRCV		12
+#define MSGGET		13
+#define MSGCTL		14
+#define SHMAT		21
+#define SHMDT		22
+#define SHMGET		23
+#define SHMCTL		24
+
+#define IPCCALL(version,op)	((version)<<16 | (op))
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/irq.h linux-2.4.29-uc1/include/asm-armnommu/irq.h
--- linux-2.4.29/include/asm-armnommu/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,28 @@
+#ifndef __ASM_ARM_IRQ_H
+#define __ASM_ARM_IRQ_H
+
+#include <asm/arch/irqs.h>
+
+#ifndef irq_cannonicalize
+#define irq_cannonicalize(i)	(i)
+#endif
+
+#ifndef NR_IRQS
+#define NR_IRQS	128
+#endif
+
+/*
+ * Use this value to indicate lack of interrupt
+ * capability
+ */
+#ifndef NO_IRQ
+#define NO_IRQ	((unsigned int)(-1))
+#endif
+
+#define disable_irq_nosync(i) disable_irq(i)
+
+extern void disable_irq(unsigned int);
+extern void enable_irq(unsigned int);
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/keyboard.h linux-2.4.29-uc1/include/asm-armnommu/keyboard.h
--- linux-2.4.29/include/asm-armnommu/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/keyboard.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ *  linux/include/asm-arm/keyboard.h
+ *
+ *  Copyright (C) 1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Keyboard driver definitions for ARM
+ */
+#ifndef __ASM_ARM_KEYBOARD_H
+#define __ASM_ARM_KEYBOARD_H
+
+/*
+ * We provide a unified keyboard interface when in VC_MEDIUMRAW
+ * mode.  This means that all keycodes must be common between
+ * all supported keyboards.  This unfortunately puts us at odds
+ * with the PC keyboard interface chip... but we can't do anything
+ * about that now.
+ */
+#ifdef __KERNEL__
+
+#include <asm/arch/keyboard.h>
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_ARM_KEYBOARD_H */
diff -urN linux-2.4.29/include/asm-armnommu/kmap_types.h linux-2.4.29-uc1/include/asm-armnommu/kmap_types.h
--- linux-2.4.29/include/asm-armnommu/kmap_types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/kmap_types.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,16 @@
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+enum km_type {
+	KM_BOUNCE_READ,
+	KM_SKB_SUNRPC_DATA,
+	KM_SKB_DATA_SOFTIRQ,
+	KM_USER0,
+	KM_USER1,
+	KM_BH_IRQ,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
+	KM_TYPE_NR
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/leds.h linux-2.4.29-uc1/include/asm-armnommu/leds.h
--- linux-2.4.29/include/asm-armnommu/leds.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/leds.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+ *  linux/include/asm-arm/leds.h
+ *
+ *  Copyright (C) 1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Event-driven interface for LEDs on machines
+ *  Added led_start and led_stop- Alex Holden, 28th Dec 1998.
+ */
+#ifndef ASM_ARM_LEDS_H
+#define ASM_ARM_LEDS_H
+
+#include <linux/config.h>
+
+typedef enum {
+	led_idle_start,
+	led_idle_end,
+	led_timer,
+	led_start,
+	led_stop,
+	led_claim,		/* override idle & timer leds */
+	led_release,		/* restore idle & timer leds */
+	led_green_on,
+	led_green_off,
+	led_amber_on,
+	led_amber_off,
+	led_red_on,
+	led_red_off,
+	/*
+	 * I want this between led_timer and led_start, but
+	 * someone has decided to export this to user space
+	 */
+	led_halted
+} led_event_t;
+
+/* Use this routine to handle LEDs */
+
+#ifdef CONFIG_LEDS
+extern void (*leds_event)(led_event_t);
+#else
+#define leds_event(e)
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/limits.h linux-2.4.29-uc1/include/asm-armnommu/limits.h
--- linux-2.4.29/include/asm-armnommu/limits.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/limits.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,11 @@
+#ifndef __ASM_PIPE_H
+#define __ASM_PIPE_H
+
+#ifndef PAGE_SIZE
+#include <asm/page.h>
+#endif
+
+#define PIPE_BUF	PAGE_SIZE
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/linux_logo.h linux-2.4.29-uc1/include/asm-armnommu/linux_logo.h
--- linux-2.4.29/include/asm-armnommu/linux_logo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/linux_logo.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,19 @@
+/*
+ *  linux/include/asm-arm/linux_logo.h
+ *
+ *  Copyright (C) 1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Linux console driver logo definitions for ARM
+ */
+
+#include <linux/init.h>
+#include <linux/version.h>
+
+#define linux_logo_banner "ARM Linux version " UTS_RELEASE
+
+#include <linux/linux_logo.h>
+
diff -urN linux-2.4.29/include/asm-armnommu/mach/amba_kmi.h linux-2.4.29-uc1/include/asm-armnommu/mach/amba_kmi.h
--- linux-2.4.29/include/asm-armnommu/mach/amba_kmi.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/mach/amba_kmi.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ *  linux/include/asm-arm/mach/amba_kmi.h
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+struct kmi_info {
+	u_int			base;
+	u_int			irq;
+	u_char			divisor;
+	u_char			type;
+	u_char			state;
+	u_char			prev_rx;
+	u_char			last_tx;
+	u_char			resend_count;
+	u_short			res;
+	wait_queue_head_t	wait_q;
+	void			(*rx)(struct kmi_info *, u_int val,
+				      struct pt_regs *regs);
+	char			name[8];
+};
+
+#define KMI_KEYBOARD		0
+#define KMI_MOUSE		1
+
+int register_kmi(struct kmi_info *kmi);
diff -urN linux-2.4.29/include/asm-armnommu/mach/arch.h linux-2.4.29-uc1/include/asm-armnommu/mach/arch.h
--- linux-2.4.29/include/asm-armnommu/mach/arch.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/mach/arch.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,97 @@
+/*
+ *  linux/include/asm-arm/mach/arch.h
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * The size of struct machine_desc
+ *   (for assembler code)
+ */
+#define SIZEOF_MACHINE_DESC	56
+
+#ifndef __ASSEMBLY__
+
+extern void setup_initrd(unsigned int start, unsigned int size);
+extern void setup_ramdisk(int doload, int prompt, int start, unsigned int rd_sz);
+
+struct tagtable;
+
+struct machine_desc {
+	/*
+	 * Note! The first four elements are used
+	 * by assembler code in head-armv.S
+	 */
+	unsigned int		nr;		/* architecture number	*/
+	unsigned int		phys_ram;	/* start of physical ram */
+	unsigned int		phys_io;	/* start of physical io	*/
+	unsigned int		virt_io;	/* start of virtual io	*/
+
+	const char		*name;		/* architecture name	*/
+	unsigned int		param_offset;	/* parameter page	*/
+
+	unsigned int		video_start;	/* start of video RAM	*/
+	unsigned int		video_end;	/* end of video RAM	*/
+
+	unsigned int		reserve_lp0 :1;	/* never has lp0	*/
+	unsigned int		reserve_lp1 :1;	/* never has lp1	*/
+	unsigned int		reserve_lp2 :1;	/* never has lp2	*/
+	unsigned int		soft_reboot :1;	/* soft reboot		*/
+	const struct tagtable *	tagtable;	/* tag table		*/
+	int			tagsize;	/* tag table size	*/
+	void			(*fixup)(struct machine_desc *,
+					 struct param_struct *, char **,
+					 struct meminfo *);
+	void			(*map_io)(void);/* IO mapping function	*/
+	void			(*init_irq)(void);
+};
+
+/*
+ * Set of macros to define architecture features.  This is built into
+ * a table by the linker.
+ */
+#define MACHINE_START(_type,_name)		\
+const struct machine_desc __mach_desc_##_type	\
+ __attribute__((__section__(".arch.info"))) = {	\
+	nr:		MACH_TYPE_##_type,	\
+	name:		_name,
+
+#define MAINTAINER(n)
+
+#define BOOT_MEM(_pram,_pio,_vio)		\
+	phys_ram:	_pram,			\
+	phys_io:	_pio,			\
+	virt_io:	_vio,
+
+#define BOOT_PARAMS(_params)			\
+	param_offset:	_params,
+
+#define VIDEO(_start,_end)			\
+	video_start:	_start,			\
+	video_end:	_end,
+
+#define DISABLE_PARPORT(_n)			\
+	reserve_lp##_n:	1,
+
+#define BROKEN_HLT /* unused */
+
+#define SOFT_REBOOT				\
+	soft_reboot:	1,
+
+#define FIXUP(_func)				\
+	fixup:		_func,
+
+#define MAPIO(_func)				\
+	map_io:		_func,
+
+#define INITIRQ(_func)				\
+	init_irq:	_func,
+
+#define MACHINE_END				\
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/mach/dma.h linux-2.4.29-uc1/include/asm-armnommu/mach/dma.h
--- linux-2.4.29/include/asm-armnommu/mach/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/mach/dma.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,55 @@
+/*
+ *  linux/include/asm-armnommu/mach/dma.h
+ *
+ *  Copyright (C) 1998-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  This header file describes the interface between the generic DMA handler
+ *  (dma.c) and the architecture-specific DMA backends (dma-*.c)
+ */
+
+struct dma_struct;
+typedef struct dma_struct dma_t;
+
+struct dma_ops {
+	int	(*request)(dmach_t, dma_t *);		/* optional */
+	void	(*free)(dmach_t, dma_t *);		/* optional */
+	void	(*enable)(dmach_t, dma_t *);		/* mandatory */
+	void 	(*disable)(dmach_t, dma_t *);		/* mandatory */
+	int	(*residue)(dmach_t, dma_t *);		/* optional */
+	int	(*setspeed)(dmach_t, dma_t *, int);	/* optional */
+	char	*type;
+};
+
+struct dma_struct {
+	struct scatterlist buf;		/* single DMA			*/
+	int		sgcount;	/* number of DMA SG		*/
+	struct scatterlist *sg;		/* DMA Scatter-Gather List	*/
+
+	unsigned int	active:1;	/* Transfer active		*/
+	unsigned int	invalid:1;	/* Address/Count changed	*/
+	unsigned int	using_sg:1;	/* using scatter list?		*/
+	dmamode_t	dma_mode;	/* DMA mode			*/
+	int		speed;		/* DMA speed			*/
+
+	unsigned int	lock;		/* Device is allocated		*/
+	const char	*device_id;	/* Device name			*/
+
+	unsigned int	dma_base;	/* Controller base address	*/
+	int		dma_irq;	/* Controller IRQ		*/
+	int		state;		/* Controller state		*/
+	struct scatterlist cur_sg;	/* Current controller buffer	*/
+
+	struct dma_ops	*d_ops;
+};
+
+/* Prototype: void arch_dma_init(dma)
+ * Purpose  : Initialise architecture specific DMA
+ * Params   : dma - pointer to array of DMA structures
+ */
+extern void arch_dma_init(dma_t *dma);
+
+extern void isa_init_dma(dma_t *dma);
diff -urN linux-2.4.29/include/asm-armnommu/mach/irq.h linux-2.4.29-uc1/include/asm-armnommu/mach/irq.h
--- linux-2.4.29/include/asm-armnommu/mach/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/mach/irq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,41 @@
+/*
+ *  linux/include/asm-arm/mach/irq.h
+ *
+ *  Copyright (C) 1995-2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_ARM_MACH_IRQ_H
+#define __ASM_ARM_MACH_IRQ_H
+
+struct irqdesc {
+	unsigned int	 nomask   : 1;		/* IRQ does not mask in IRQ   */
+	unsigned int	 enabled  : 1;		/* IRQ is currently enabled   */
+	unsigned int	 triggered: 1;		/* IRQ has occurred	      */
+	unsigned int	 probing  : 1;		/* IRQ in use for a probe     */
+	unsigned int	 probe_ok : 1;		/* IRQ can be used for probe  */
+	unsigned int	 valid    : 1;		/* IRQ claimable	      */
+	unsigned int	 noautoenable : 1;	/* don't automatically enable IRQ */
+	unsigned int	 unused   :25;
+	void (*mask_ack)(unsigned int irq);	/* Mask and acknowledge IRQ   */
+	void (*mask)(unsigned int irq);		/* Mask IRQ		      */
+	void (*unmask)(unsigned int irq);	/* Unmask IRQ		      */
+	struct irqaction *action;
+	/*
+	 * IRQ lock detection
+	 */
+	unsigned int	 lck_cnt;
+	unsigned int	 lck_pc;
+	unsigned int	 lck_jif;
+};
+
+extern struct irqdesc irq_desc[];
+
+extern void (*init_arch_irq)(void);
+extern int setup_arm_irq(int, struct irqaction *);
+extern int get_fiq_list(char *);
+extern void init_FIQ(void);
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/mach/map.h linux-2.4.29-uc1/include/asm-armnommu/mach/map.h
--- linux-2.4.29/include/asm-armnommu/mach/map.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/mach/map.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ *  linux/include/asm-arm/map.h
+ *
+ *  Copyright (C) 1999-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Page table mapping constructs and function prototypes
+ */
+struct map_desc {
+	unsigned long virtual;
+	unsigned long physical;
+	unsigned long length;
+	int domain:4,
+	    prot_read:1,
+	    prot_write:1,
+	    cacheable:1,
+	    bufferable:1,
+	    last:1;
+};
+
+#define LAST_DESC \
+  { last: 1 }
+
+struct meminfo;
+
+extern void create_memmap_holes(struct meminfo *);
+extern void memtable_init(struct meminfo *);
+extern void iotable_init(struct map_desc *);
+extern void setup_io_desc(void);
diff -urN linux-2.4.29/include/asm-armnommu/mach/pci.h linux-2.4.29-uc1/include/asm-armnommu/mach/pci.h
--- linux-2.4.29/include/asm-armnommu/mach/pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/mach/pci.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,42 @@
+/*
+ *  linux/include/asm-arm/mach/pci.h
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define MAX_NR_BUS	2
+
+struct arm_bus_sysdata {
+	/*
+	 * bitmask of features we can turn.
+	 * See PCI command register for more info.
+	 */
+	u16		features;
+	/*
+	 * Maximum devsel for this bus.
+	 */
+	u16		maxdevsel;
+	/*
+	 * The maximum latency that devices on this
+	 * bus can withstand.
+	 */
+	u8		max_lat;
+};
+
+struct arm_pci_sysdata {
+	struct arm_bus_sysdata bus[MAX_NR_BUS];
+};
+
+struct hw_pci {
+	void		(*init)(struct arm_pci_sysdata *);
+	u8		(*swizzle)(struct pci_dev *dev, u8 *pin);
+	int		(*map_irq)(struct pci_dev *dev, u8 slot, u8 pin);
+};
+
+extern u8 no_swizzle(struct pci_dev *dev, u8 *pin);
+
+void __init dc21285_init(struct arm_pci_sysdata *);
+void __init plx90x0_init(struct arm_pci_sysdata *);
diff -urN linux-2.4.29/include/asm-armnommu/mc146818rtc.h linux-2.4.29-uc1/include/asm-armnommu/mc146818rtc.h
--- linux-2.4.29/include/asm-armnommu/mc146818rtc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/mc146818rtc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+#include <asm/arch/irqs.h>
+#include <asm/io.h>
+
+#ifndef RTC_PORT
+#define RTC_PORT(x)	(0x70 + (x))
+#define RTC_ALWAYS_BCD	1	/* RTC operates in binary mode */
+#endif
+
+/*
+ * The yet supported machines all access the RTC index register via
+ * an ISA port access but the way to access the date register differs ...
+ */
+#define CMOS_READ(addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+outb_p((val),RTC_PORT(1)); \
+})
+
+#endif /* _ASM_MC146818RTC_H */
diff -urN linux-2.4.29/include/asm-armnommu/memc.h linux-2.4.29-uc1/include/asm-armnommu/memc.h
--- linux-2.4.29/include/asm-armnommu/memc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/memc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,17 @@
+#define VDMA_ALIGNMENT	PAGE_SIZE
+#define VDMA_XFERSIZE	16
+#define VDMA_INIT	0
+#define VDMA_START	1
+#define VDMA_END	2
+
+#ifndef __ASSEMBLY__
+extern void memc_write(unsigned int reg, unsigned long val);
+
+#define video_set_dma(start,end,offset)				\
+do {								\
+	memc_write (VDMA_START, (start >> 2));			\
+	memc_write (VDMA_END, (end - VDMA_XFERSIZE) >> 2);	\
+	memc_write (VDMA_INIT, (offset >> 2));			\
+} while (0)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/memory.h linux-2.4.29-uc1/include/asm-armnommu/memory.h
--- linux-2.4.29/include/asm-armnommu/memory.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/memory.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,54 @@
+/*
+ *  linux/include/asm-armnommu/memory.h
+ *
+ *  Copyright (C) 2000 Russell King
+ *  Copyright (C) 2001 RidgeRun, Inc (http://www.ridgerun.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Note: this file should not be included by non-asm/.h files
+ *
+ *  Modifications:
+ *  02/20/01  Gordon McNutt  Leveraged for uClinux-2.4.x
+ */
+#ifndef __ASM_ARM_MEMORY_H
+#define __ASM_ARM_MEMORY_H
+
+#include <asm/arch/memory.h>
+
+/*
+ * Virtual, bus and physical addresses are all the same when there's no MMU.
+ * --gmcnutt
+ */
+#define virt_to_bus(x) ((unsigned long) (x))
+#define bus_to_virt(x) ((void *) (x))
+#define virt_to_phys(x) ((unsigned long) (x))
+#define phys_to_virt(x) ((void *) (x))
+
+#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define page_to_phys(page)	virt_to_phys((void *)__page_address(page))
+
+#if 0
+/*
+ * For some reason other asm/.h files refer to these instead of the more 
+ * public macros above.
+ * --gmcnutt
+ */
+#define __virt_to_bus(x) ((unsigned long) (x))
+#define __bus_to_virt(x) ((void *) (x))
+#define __virt_to_phys(x) ((unsigned long) (x))
+#define __phys_to_virt(x) ((void *) (x))
+#endif
+
+/*
+ * arch/armnommu/kernel/armksyms.c needs these.
+ * --gmcnutt
+ */
+#define __virt_to_phys__is_a_macro
+#define __phys_to_virt__is_a_macro
+#define __virt_to_bus__is_a_macro
+#define __bus_to_virt__is_a_macro
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/mman.h linux-2.4.29-uc1/include/asm-armnommu/mman.h
--- linux-2.4.29/include/asm-armnommu/mman.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/mman.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,38 @@
+#ifndef __ARM_MMAN_H__
+#define __ARM_MMAN_H__
+
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_NONE	0x0		/* page can not be accessed */
+
+#define MAP_SHARED	0x01		/* Share changes */
+#define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_TYPE	0x0f		/* Mask for type of mapping */
+#define MAP_FIXED	0x10		/* Interpret addr exactly */
+#define MAP_ANONYMOUS	0x20		/* don't use a file */
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
+#define MAP_LOCKED	0x2000		/* pages are locked */
+#define MAP_NORESERVE	0x4000		/* don't check for reservations */
+
+#define MS_ASYNC	1		/* sync memory asynchronously */
+#define MS_INVALIDATE	2		/* invalidate the caches */
+#define MS_SYNC		4		/* synchronous memory sync */
+
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
+
+#define MADV_NORMAL	0x0		/* default page-in behavior */
+#define MADV_RANDOM	0x1		/* page-in minimum required */
+#define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
+#define MADV_WILLNEED	0x3		/* pre-fault pages */
+#define MADV_DONTNEED	0x4		/* discard these pages */
+
+/* compatibility flags */
+#define MAP_ANON	MAP_ANONYMOUS
+#define MAP_FILE	0
+
+#endif /* __ARM_MMAN_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/mmu_context.h linux-2.4.29-uc1/include/asm-armnommu/mmu_context.h
--- linux-2.4.29/include/asm-armnommu/mmu_context.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/mmu_context.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+ *  linux/include/asm-arm/mmu_context.h
+ *
+ *  Copyright (C) 1996 Russell King.
+ *  Copyright (C) 2001 RidgRun Inc (www.ridgerun.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Changelog:
+ *   27-06-1996	RMK	Created
+ *   20-02-2001 GJM     Gutted for uClinux
+ */
+#ifndef __ASM_ARM_MMU_CONTEXT_H
+#define __ASM_ARM_MMU_CONTEXT_H
+
+#define destroy_context(mm)		do { } while(0)
+#define init_new_context(tsk,mm)	0
+#define switch_mm(prev,next,tsk,cpu)
+#define activate_mm(prev,next)
+#define enter_lazy_tlb(mm,tsk,cpu)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/mmu.h linux-2.4.29-uc1/include/asm-armnommu/mmu.h
--- linux-2.4.29/include/asm-armnommu/mmu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/mmu.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,7 @@
+#ifndef __ARM_MMU_H
+#define __ARM_MMU_H
+
+/* The ARM doesn't have a mmu context */
+typedef struct { } mm_context_t;
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/mmzone.h linux-2.4.29-uc1/include/asm-armnommu/mmzone.h
--- linux-2.4.29/include/asm-armnommu/mmzone.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/mmzone.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ *  linux/include/asm-arm/mmzone.h
+ *
+ *  1999-12-29	Nicolas Pitre		Created
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_MMZONE_H
+#define __ASM_MMZONE_H
+
+/*
+ * Currently defined in arch/arm/mm/discontig.c
+ */
+extern pg_data_t discontig_node_data[];
+
+/*
+ * Return a pointer to the node data for node n.
+ */
+#define NODE_DATA(nid)		(&discontig_node_data[nid])
+
+/*
+ * NODE_MEM_MAP gives the kaddr for the mem_map of the node.
+ */
+#define NODE_MEM_MAP(nid)	(NODE_DATA(nid)->node_mem_map)
+
+#include <asm/arch/mmzone.h>
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/module.h linux-2.4.29-uc1/include/asm-armnommu/module.h
--- linux-2.4.29/include/asm-armnommu/module.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/module.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef _ASM_ARM_MODULE_H
+#define _ASM_ARM_MODULE_H
+/*
+ * This file contains the arm architecture specific module code.
+ */
+
+#define module_map(x)		vmalloc(x)
+#define module_unmap(x)		vfree(x)
+#define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
+
+#endif /* _ASM_ARM_MODULE_H */
diff -urN linux-2.4.29/include/asm-armnommu/msgbuf.h linux-2.4.29-uc1/include/asm-armnommu/msgbuf.h
--- linux-2.4.29/include/asm-armnommu/msgbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/msgbuf.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef _ASMARM_MSGBUF_H
+#define _ASMARM_MSGBUF_H
+
+/* 
+ * The msqid64_ds structure for arm architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm msg_perm;
+	__kernel_time_t msg_stime;	/* last msgsnd time */
+	unsigned long	__unused1;
+	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	unsigned long	__unused2;
+	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned long	__unused3;
+	unsigned long  msg_cbytes;	/* current number of bytes on queue */
+	unsigned long  msg_qnum;	/* number of messages in queue */
+	unsigned long  msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t msg_lrpid;	/* last receive pid */
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+#endif /* _ASMARM_MSGBUF_H */
diff -urN linux-2.4.29/include/asm-armnommu/namei.h linux-2.4.29-uc1/include/asm-armnommu/namei.h
--- linux-2.4.29/include/asm-armnommu/namei.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/namei.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,25 @@
+/* 
+ * linux/include/asm-arm/namei.h
+ *
+ * Routines to handle famous /usr/gnemul
+ * Derived from the Sparc version of this file
+ *
+ * Included from linux/fs/namei.c
+ */
+
+#ifndef __ASMARM_NAMEI_H
+#define __ASMARM_NAMEI_H
+
+#define ARM_BSD_EMUL "usr/gnemul/bsd/"
+
+static inline char *__emul_prefix(void)
+{
+	switch (current->personality) {
+	case PER_BSD:
+		return ARM_BSD_EMUL;
+	default:
+		return NULL;
+	}
+}
+
+#endif /* __ASMARM_NAMEI_H */
diff -urN linux-2.4.29/include/asm-armnommu/nwflash.h linux-2.4.29-uc1/include/asm-armnommu/nwflash.h
--- linux-2.4.29/include/asm-armnommu/nwflash.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/nwflash.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,9 @@
+#ifndef _FLASH_H
+#define _FLASH_H
+
+#define FLASH_MINOR		 160	/* MAJOR is 10 - miscdevice */
+#define CMD_WRITE_DISABLE	 0
+#define CMD_WRITE_ENABLE	 0x28
+#define CMD_WRITE_BASE64K_ENABLE 0x47
+
+#endif /* _FLASH_H */
diff -urN linux-2.4.29/include/asm-armnommu/page.h linux-2.4.29-uc1/include/asm-armnommu/page.h
--- linux-2.4.29/include/asm-armnommu/page.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/page.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,115 @@
+#ifndef _ASMARM_PAGE_H
+#define _ASMARM_PAGE_H
+
+#include <asm/proc/page.h>
+
+#define PAGE_SIZE       (1UL << PAGE_SHIFT)
+#define PAGE_MASK       (~(PAGE_SIZE-1))
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#define STRICT_MM_TYPECHECKS
+
+#define clear_page(page)	memzero((void *)(page), PAGE_SIZE)
+extern void copy_page(void *to, void *from);
+
+#define clear_user_page(page, vaddr)	clear_page(page)
+#define copy_user_page(to, from, vaddr)	copy_page(to, from)
+
+#ifdef STRICT_MM_TYPECHECKS
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pmd; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)      ((x).pte)
+#define pmd_val(x)      ((x).pmd)
+#define pgd_val(x)      ((x).pgd)
+#define pgprot_val(x)   ((x).pgprot)
+
+#define __pte(x)        ((pte_t) { (x) } )
+#define __pmd(x)        ((pmd_t) { (x) } )
+#define __pgd(x)        ((pgd_t) { (x) } )
+#define __pgprot(x)     ((pgprot_t) { (x) } )
+
+#else
+/*
+ * .. while these make it easier on the compiler
+ */
+typedef unsigned long pte_t;
+typedef unsigned long pmd_t;
+typedef unsigned long pgd_t;
+typedef unsigned long pgprot_t;
+
+#define pte_val(x)      (x)
+#define pmd_val(x)      (x)
+#define pgd_val(x)      (x)
+#define pgprot_val(x)   (x)
+
+#define __pte(x)        (x)
+#define __pmd(x)        (x)
+#define __pgd(x)        (x)
+#define __pgprot(x)     (x)
+
+#endif
+#endif /* !__ASSEMBLY__ */
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+#ifndef __ASSEMBLY__
+
+#if defined(CONFIG_DEBUG_BUGVERBOSE) || defined(CONFIG_UCLINUX)
+extern void __bug(const char *file, int line, void *data);
+
+/* give file/line information */
+#define BUG()		__bug(__FILE__, __LINE__, NULL)
+#define PAGE_BUG(page)	__bug(__FILE__, __LINE__, page)
+
+#else
+
+/* these just cause an oops */
+#define BUG()		(*(int *)0 = 0)
+#define PAGE_BUG(page)	(*(int *)0 = 0)
+
+#endif
+
+/* Pure 2^n version of get_order */
+static inline int get_order(unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#include <linux/config.h>
+#include <asm/arch/memory.h>
+
+#define __pa(x)			__virt_to_phys((unsigned long)(x))
+#define __va(x)			((void *)__phys_to_virt((unsigned long)(x)))
+
+#ifndef CONFIG_DISCONTIGMEM
+#define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT) - \
+				 (PHYS_OFFSET >> PAGE_SHIFT))
+#define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
+
+/* MAP_NR should not be used in 2.4 */
+#define MAP_NR(addr)      (((unsigned long) (addr) - PAGE_OFFSET) >> PAGE_SHIFT)
+
+#endif
+
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/param.h linux-2.4.29-uc1/include/asm-armnommu/param.h
--- linux-2.4.29/include/asm-armnommu/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/param.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ *  linux/include/asm-arm/param.h
+ *
+ *  Copyright (C) 1995-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_PARAM_H
+#define __ASM_PARAM_H
+
+#include <asm/arch/param.h>	/* for HZ */
+#include <asm/proc/page.h>	/* for EXEC_PAGE_SIZE */
+
+#ifndef HZ
+#define HZ 100
+#endif
+#if defined(__KERNEL__) && (HZ == 100)
+#define hz_to_std(a) (a)
+#endif
+
+#ifndef NGROUPS
+#define NGROUPS         32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP         (-1)
+#endif
+
+/* max length of hostname */
+#define MAXHOSTNAMELEN  64
+
+#ifdef __KERNEL__
+# define CLOCKS_PER_SEC	HZ
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/parport.h linux-2.4.29-uc1/include/asm-armnommu/parport.h
--- linux-2.4.29/include/asm-armnommu/parport.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/parport.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,18 @@
+/*
+ *  linux/include/asm-arm/parport.h: ARM-specific parport initialisation
+ *
+ *  Copyright (C) 1999, 2000  Tim Waugh <tim@cyberelk.demon.co.uk>
+ *
+ * This file should only be included by drivers/parport/parport_pc.c.
+ */
+
+#ifndef __ASMARM_PARPORT_H
+#define __ASMARM_PARPORT_H
+
+static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
+static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
+{
+	return parport_pc_find_isa_ports (autoirq, autodma);
+}
+
+#endif /* !(_ASMARM_PARPORT_H) */
diff -urN linux-2.4.29/include/asm-armnommu/pci.h linux-2.4.29-uc1/include/asm-armnommu/pci.h
--- linux-2.4.29/include/asm-armnommu/pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/pci.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,188 @@
+#ifndef ASMARM_PCI_H
+#define ASMARM_PCI_H
+
+#ifdef __KERNEL__
+
+#include <asm/arch/hardware.h>
+
+extern inline void pcibios_set_master(struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling */
+}
+
+extern inline void pcibios_penalize_isa_irq(int irq)
+{
+	/* We don't do dynamic PCI IRQ allocation */
+}
+
+#include <asm/scatterlist.h>
+#include <asm/io.h>
+
+
+struct pci_dev;
+
+/*
+ * The PCI address space does equal the physical memory address space.
+ * The networking and block device layers use this boolean for bounce
+ * buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS     (0)
+
+/* Allocate and map kernel buffer using consistent mode DMA for a device.
+ * hwdev should be valid struct pci_dev pointer for PCI devices,
+ * NULL for PCI-like buses (ISA, EISA).
+ * Returns non-NULL cpu-view pointer to the buffer if successful and
+ * sets *dma_addrp to the pci side dma address as well, else *dma_addrp
+ * is undefined.
+ */
+extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *handle);
+
+/* Free and unmap a consistent DMA buffer.
+ * cpu_addr is what was returned from pci_alloc_consistent,
+ * size must be the same as what as passed into pci_alloc_consistent,
+ * and likewise dma_addr must be the same as what *dma_addrp was set to.
+ *
+ * References to the memory and mappings associated with cpu_addr/dma_addr
+ * past this call are illegal.
+ */
+extern inline void
+pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr,
+		    dma_addr_t dma_handle)
+{
+	consistent_free(vaddr, size, dma_handle);
+}
+
+/* Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Once the device is given the dma address, the device owns this memory
+ * until either pci_unmap_single or pci_dma_sync_single is performed.
+ */
+extern inline dma_addr_t
+pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
+{
+	consistent_sync(ptr, size, direction);
+	return virt_to_bus(ptr);
+}
+
+/* Unmap a single streaming mode DMA translation.  The dma_addr and size
+ * must match what was provided for in a previous pci_map_single call.  All
+ * other usages are undefined.
+ *
+ * After this call, reads by the cpu to the buffer are guarenteed to see
+ * whatever the device wrote there.
+ */
+extern inline void
+pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
+{
+	/* nothing to do */
+}
+
+static inline dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
+                                      unsigned long offset, size_t size, int direction)
+{
+	return pci_map_single(hwdev, page_address(page) + offset, size, direction);
+}
+
+static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,                                  size_t size, int direction)
+{
+	/* Nothing to do */
+}
+
+/* Map a set of buffers described by scatterlist in streaming
+ * mode for DMA.  This is the scather-gather version of the
+ * above pci_map_single interface.  Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length.  They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ *       DMA address/length pairs than there are SG table elements.
+ *       (for example via virtual mapping capabilities)
+ *       The routine returns the number of addr/length pairs actually
+ *       used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+extern inline int
+pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
+{
+	int i;
+
+	for (i = 0; i < nents; i++, sg++) {
+ 		if (sg->address) {
+			consistent_sync(sg->address, sg->length, direction);
+			sg->dma_address = virt_to_bus(sg->address);
+		}
+		else {
+/* bus & phys are the same */
+#define page_to_bus page_to_phys
+
+			consistent_sync(page_address(sg->page) + sg->offset, sg->length, direction);
+			sg->dma_address = page_to_bus(sg->page) + sg->offset;
+		}
+	}
+
+	return nents;
+} 
+/* Unmap a set of streaming mode DMA translations.
+ * Again, cpu read rules concerning calls here are the same as for
+ * pci_unmap_single() above.
+ */
+extern inline void
+pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
+{
+	/* nothing to do */
+}
+
+/* Make physical memory consistent for a single
+ * streaming mode DMA translation after a transfer.
+ *
+ * If you perform a pci_map_single() but wish to interrogate the
+ * buffer using the cpu, yet do not wish to teardown the PCI dma
+ * mapping, you must call this function before doing so.  At the
+ * next point you give the PCI dma address back to the card, the
+ * device again owns the buffer.
+ */
+extern inline void
+pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction)
+{
+	consistent_sync(bus_to_virt(dma_handle), size, direction);
+}
+
+/* Make physical memory consistent for a set of streaming
+ * mode DMA translations after a transfer.
+ *
+ * The same as pci_dma_sync_single but for a scatter-gather list,
+ * same rules and usage.
+ */
+extern inline void
+pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction)
+{
+	int i;
+
+	for (i = 0; i < nelems; i++, sg++)
+		if (sg->address) {
+			consistent_sync(sg->address, sg->length, direction);
+		}
+		else {
+			consistent_sync(page_address(sg->page) + sg->offset, sg->length, direction);
+		}
+}
+
+/* Return whether the given PCI device DMA address mask can
+ * be supported properly.  For example, if your device can
+ * only drive the low 24-bits during PCI bus mastering, then
+ * you would pass 0x00ffffff as the mask to this function.
+ */
+extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
+{
+	return 1;
+}
+
+/* Return the index of the PCI controller for device PDEV. */
+#define pci_controller_num(PDEV)	(0)
+
+#endif /* __KERNEL__ */
+ 
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/pgalloc.h linux-2.4.29-uc1/include/asm-armnommu/pgalloc.h
--- linux-2.4.29/include/asm-armnommu/pgalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/pgalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,143 @@
+/*
+ *  linux/include/asm-arm/pgalloc.h
+ *
+ *  Copyright (C) 2000-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _ASMARM_PGALLOC_H
+#define _ASMARM_PGALLOC_H
+
+#include <linux/config.h>
+
+#include <asm/processor.h>
+
+/*
+ * Get the cache handling stuff now.
+ */
+#include <asm/proc/cache.h>
+
+/*
+ * ARM processors do not cache TLB tables in RAM.
+ */
+#define flush_tlb_pgtables(mm,start,end)	do { } while (0)
+
+#ifndef CONFIG_UCLINUX /* kf */ 
+/*
+ * Processor specific parts...
+ */
+#include <asm/proc/pgalloc.h>
+
+#endif
+/*
+ * Page table cache stuff
+ */
+#ifndef CONFIG_NO_PGT_CACHE
+
+#ifdef CONFIG_SMP
+#error Pgtable caches have to be per-CPU, so that no locking is needed.
+#endif	/* CONFIG_SMP */
+
+extern struct pgtable_cache_struct {
+	unsigned long *pgd_cache;
+	unsigned long *pte_cache;
+	unsigned long pgtable_cache_sz;
+} quicklists;
+
+#define pgd_quicklist		(quicklists.pgd_cache)
+#define pmd_quicklist		((unsigned long *)0)
+#define pte_quicklist		(quicklists.pte_cache)
+#define pgtable_cache_size	(quicklists.pgtable_cache_sz)
+
+/* used for quicklists */
+#define __pgd_next(pgd) (((unsigned long *)pgd)[1])
+#define __pte_next(pte)	(((unsigned long *)pte)[0])
+
+extern __inline__ pgd_t *get_pgd_fast(void)
+{
+	unsigned long *ret;
+
+	if ((ret = pgd_quicklist) != NULL) {
+		pgd_quicklist = (unsigned long *)__pgd_next(ret);
+		ret[1] = ret[2];
+		clean_dcache_entry(ret + 1);
+		pgtable_cache_size--;
+	}
+	return (pgd_t *)ret;
+}
+
+extern __inline__ void free_pgd_fast(pgd_t *pgd)
+{
+	__pgd_next(pgd) = (unsigned long) pgd_quicklist;
+	pgd_quicklist = (unsigned long *) pgd;
+	pgtable_cache_size++;
+}
+
+static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
+{
+	unsigned long *ret;
+
+	if((ret = pte_quicklist) != NULL) {
+		pte_quicklist = (unsigned long *)__pte_next(ret);
+		ret[0] = 0;
+		clean_dcache_entry(ret);
+		pgtable_cache_size--;
+	}
+	return (pte_t *)ret;
+}
+
+extern __inline__ void free_pte_fast(pte_t *pte)
+{
+	__pte_next(pte) = (unsigned long) pte_quicklist;
+	pte_quicklist = (unsigned long *) pte;
+	pgtable_cache_size++;
+}
+
+#else	/* CONFIG_NO_PGT_CACHE */
+
+#define pgd_quicklist			((unsigned long *)0)
+#define pmd_quicklist			((unsigned long *)0)
+#define pte_quicklist			((unsigned long *)0)
+
+#define get_pgd_fast()			((pgd_t *)0)
+#define pte_alloc_one_fast(mm,addr)	((pte_t *)0)
+
+#define free_pgd_fast(pgd)		free_pgd_slow(pgd)
+#define free_pte_fast(pte)		pte_free_slow(pte)
+
+#endif	/* CONFIG_NO_PGT_CACHE */
+
+#define pte_free(pte)			free_pte_fast(pte)
+
+
+/*
+ * Since we have only two-level page tables, these are trivial
+ */
+#define pmd_alloc_one_fast(mm,addr)	({ BUG(); ((pmd_t *)1); })
+#define pmd_alloc_one(mm,addr)		({ BUG(); ((pmd_t *)2); })
+#define pmd_free_slow(pmd)		do { } while (0)
+#define pmd_free_fast(pmd)		do { } while (0)
+#define pmd_free(pmd)			do { } while (0)
+#define pgd_populate(mm,pmd,pte)	BUG()
+
+extern pgd_t *get_pgd_slow(struct mm_struct *mm);
+extern void free_pgd_slow(pgd_t *pgd);
+
+extern __inline__ pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+	pgd_t *pgd;
+
+	pgd = get_pgd_fast();
+	if (!pgd)
+		pgd = get_pgd_slow(mm);
+
+	return pgd;
+}
+
+#define pgd_free(pgd)			free_pgd_fast(pgd)
+
+extern int do_check_pgt_cache(int, int);
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/pgtable.h linux-2.4.29-uc1/include/asm-armnommu/pgtable.h
--- linux-2.4.29/include/asm-armnommu/pgtable.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/pgtable.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,184 @@
+/*
+ *  linux/include/asm-arm/pgtable.h
+ *
+ *  Copyright (C) 2000-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _ASMARM_PGTABLE_H
+#define _ASMARM_PGTABLE_H
+
+#include <linux/config.h>
+#include <asm/arch/memory.h>
+#include <asm/proc-fns.h>
+
+/*
+ * PMD_SHIFT determines the size of the area a second-level page table can map
+ * PGDIR_SHIFT determines what a third-level page table entry can map
+ */
+#define PMD_SHIFT		20
+#define PGDIR_SHIFT		20
+
+#define LIBRARY_TEXT_START	0x0c000000
+
+#ifndef __ASSEMBLY__
+extern void __pte_error(const char *file, int line, unsigned long val);
+extern void __pmd_error(const char *file, int line, unsigned long val);
+extern void __pgd_error(const char *file, int line, unsigned long val);
+
+#define pte_ERROR(pte)		__pte_error(__FILE__, __LINE__, pte_val(pte))
+#define pmd_ERROR(pmd)		__pmd_error(__FILE__, __LINE__, pmd_val(pmd))
+#define pgd_ERROR(pgd)		__pgd_error(__FILE__, __LINE__, pgd_val(pgd))
+#endif /* !__ASSEMBLY__ */
+
+#define PMD_SIZE		(1UL << PMD_SHIFT)
+#define PMD_MASK		(~(PMD_SIZE-1))
+#define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK		(~(PGDIR_SIZE-1))
+
+#define FIRST_USER_PGD_NR	1
+#define USER_PTRS_PER_PGD	((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR)
+
+/*
+ * The table below defines the page protection levels that we insert into our
+ * Linux page table version.  These get translated into the best that the
+ * architecture can perform.  Note that on most ARM hardware:
+ *  1) We cannot do execute protection
+ *  2) If we could do execute protection, then read is implied
+ *  3) write implies read permissions
+ */
+#define __P000  PAGE_NONE
+#define __P001  PAGE_READONLY
+#define __P010  PAGE_COPY
+#define __P011  PAGE_COPY
+#define __P100  PAGE_READONLY
+#define __P101  PAGE_READONLY
+#define __P110  PAGE_COPY
+#define __P111  PAGE_COPY
+
+#define __S000  PAGE_NONE
+#define __S001  PAGE_READONLY
+#define __S010  PAGE_SHARED
+#define __S011  PAGE_SHARED
+#define __S100  PAGE_READONLY
+#define __S101  PAGE_READONLY
+#define __S110  PAGE_SHARED
+#define __S111  PAGE_SHARED
+
+#ifndef __ASSEMBLY__
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern struct page *empty_zero_page;
+#define ZERO_PAGE(vaddr)	(empty_zero_page)
+
+#define pte_none(pte)		(!pte_val(pte))
+#define pte_clear(ptep)		set_pte((ptep), __pte(0))
+
+#ifndef CONFIG_DISCONTIGMEM
+#define pte_page(x)		(mem_map + (pte_val((x)) >> PAGE_SHIFT) - \
+				 (PHYS_OFFSET >> PAGE_SHIFT))
+#else
+/*
+ * I'm not happy with this - we needlessly convert a physical address
+ * to a virtual one, and then immediately back to a physical address,
+ * which, if __va and __pa are expensive causes twice the expense for
+ * zero gain. --rmk
+ */
+#define pte_page(x)		(virt_to_page(__va(pte_val((x)))))
+#endif
+
+#define pmd_none(pmd)		(!pmd_val(pmd))
+#define pmd_present(pmd)	(pmd_val(pmd))
+#define pmd_clear(pmdp)		set_pmd(pmdp, __pmd(0))
+
+/*
+ * Permanent address of a page. We never have highmem, so this is trivial.
+ */
+#define pages_to_mb(x)		((x) >> (20 - PAGE_SHIFT))
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+extern __inline__ pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
+{
+	pte_t pte;
+	pte_val(pte) = physpage | pgprot_val(pgprot);
+	return pte;
+}
+
+#define mk_pte(page,pgprot)				\
+({							\
+	pte_t __pte;					\
+	pte_val(__pte) = __pa(page_address(page)) +	\
+			   pgprot_val(pgprot);		\
+	__pte;						\
+})
+
+/*
+ * The "pgd_xxx()" functions here are trivial for a folded two-level
+ * setup: the pgd is never bad, and a pmd always exists (as it's folded
+ * into the pgd entry)
+ */
+#define pgd_none(pgd)		(0)
+#define pgd_bad(pgd)		(0)
+#define pgd_present(pgd)	(1)
+#define pgd_clear(pgdp)
+
+#define page_pte_prot(page,prot)	mk_pte(page, prot)
+#define page_pte(page)		mk_pte(page, __pgprot(0))
+
+/* to find an entry in a page-table-directory */
+#define pgd_index(addr)		((addr) >> PGDIR_SHIFT)
+#define __pgd_offset(addr)	pgd_index(addr)
+
+#define pgd_offset(mm, addr)	((mm)->pgd+pgd_index(addr))
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(addr)	pgd_offset(&init_mm, addr)
+
+/* Find an entry in the second-level page table.. */
+#define pmd_offset(dir, addr)	((pmd_t *)(dir))
+
+/* Find an entry in the third-level page table.. */
+#define __pte_offset(addr)	(((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset(dir, addr)	((pte_t *)pmd_page(*(dir)) + __pte_offset(addr))
+
+#include <asm/proc/pgtable.h>
+
+extern __inline__ pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+	pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
+	return pte;
+}
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+/* Encode and decode a swap entry.
+ *
+ * We support up to 32GB of swap on 4k machines
+ */
+#define SWP_TYPE(x)		(((x).val >> 2) & 0x7f)
+#define SWP_OFFSET(x)		((x).val >> 9)
+#define SWP_ENTRY(type,offset)	((swp_entry_t) { ((type) << 2) | ((offset) << 9) })
+#define pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
+#define swp_entry_to_pte(swp)	((pte_t) { (swp).val })
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+/* FIXME: this is not correct */
+#define kern_addr_valid(addr)	(1)
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()   do { } while (0)
+
+#include <asm-generic/pgtable.h>
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASMARM_PGTABLE_H */
diff -urN linux-2.4.29/include/asm-armnommu/poll.h linux-2.4.29-uc1/include/asm-armnommu/poll.h
--- linux-2.4.29/include/asm-armnommu/poll.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/poll.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef __ASMARM_POLL_H
+#define __ASMARM_POLL_H
+
+/* These are specified by iBCS2 */
+#define POLLIN		0x0001
+#define POLLPRI		0x0002
+#define POLLOUT		0x0004
+#define POLLERR		0x0008
+#define POLLHUP		0x0010
+#define POLLNVAL	0x0020
+
+/* The rest seem to be more-or-less nonstandard. Check them! */
+#define POLLRDNORM	0x0040
+#define POLLRDBAND	0x0080
+#define POLLWRNORM	0x0100
+#define POLLWRBAND	0x0200
+#define POLLMSG		0x0400
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/posix_types.h linux-2.4.29-uc1/include/asm-armnommu/posix_types.h
--- linux-2.4.29/include/asm-armnommu/posix_types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/posix_types.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,79 @@
+/*
+ *  linux/include/asm-arm/posix_types.h
+ *
+ *  Copyright (C) 1996-1998 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Changelog:
+ *   27-06-1996	RMK	Created
+ */
+#ifndef __ARCH_ARM_POSIX_TYPES_H
+#define __ARCH_ARM_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned short		__kernel_dev_t;
+typedef unsigned long		__kernel_ino_t;
+typedef unsigned short		__kernel_mode_t;
+typedef unsigned short		__kernel_nlink_t;
+typedef long			__kernel_off_t;
+typedef int			__kernel_pid_t;
+typedef unsigned short		__kernel_ipc_pid_t;
+typedef unsigned short		__kernel_uid_t;
+typedef unsigned short		__kernel_gid_t;
+typedef unsigned int		__kernel_size_t;
+typedef int			__kernel_ssize_t;
+typedef int			__kernel_ptrdiff_t;
+typedef long			__kernel_time_t;
+typedef long			__kernel_suseconds_t;
+typedef long			__kernel_clock_t;
+typedef int			__kernel_daddr_t;
+typedef char *			__kernel_caddr_t;
+typedef unsigned short		__kernel_uid16_t;
+typedef unsigned short		__kernel_gid16_t;
+typedef unsigned int		__kernel_uid32_t;
+typedef unsigned int		__kernel_gid32_t;
+
+typedef unsigned short		__kernel_old_uid_t;
+typedef unsigned short		__kernel_old_gid_t;
+
+#ifdef __GNUC__
+typedef long long		__kernel_loff_t;
+#endif
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+	int	val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+	int	__val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#undef	__FD_SET
+#define __FD_SET(fd, fdsetp) \
+		(((fd_set *)fdsetp)->fds_bits[fd >> 5] |= (1<<(fd & 31)))
+
+#undef	__FD_CLR
+#define __FD_CLR(fd, fdsetp) \
+		(((fd_set *)fdsetp)->fds_bits[fd >> 5] &= ~(1<<(fd & 31)))
+
+#undef	__FD_ISSET
+#define __FD_ISSET(fd, fdsetp) \
+		((((fd_set *)fdsetp)->fds_bits[fd >> 5] & (1<<(fd & 31))) != 0)
+
+#undef	__FD_ZERO
+#define __FD_ZERO(fdsetp) \
+		(memset (fdsetp, 0, sizeof (*(fd_set *)fdsetp)))
+
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/proc-armo/assembler.h linux-2.4.29-uc1/include/asm-armnommu/proc-armo/assembler.h
--- linux-2.4.29/include/asm-armnommu/proc-armo/assembler.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armo/assembler.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,106 @@
+/*
+ *  linux/asm-arm/proc-armo/assembler.h
+ *
+ *  Copyright (C) 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  This file contains arm architecture specific defines
+ *  for the different processors
+ */
+#define MODE_USR	USR26_MODE
+#define MODE_FIQ	FIQ26_MODE
+#define MODE_IRQ	IRQ26_MODE
+#define MODE_SVC	SVC26_MODE
+
+#define DEFAULT_FIQ	MODE_FIQ
+
+#ifdef __STDC__
+#define LOADREGS(cond, base, reglist...)\
+	ldm##cond	base,reglist^
+
+#define RETINSTR(instr, regs...)\
+	instr##s	regs
+#else
+#define LOADREGS(cond, base, reglist...)\
+	ldm/**/cond	base,reglist^
+
+#define RETINSTR(instr, regs...)\
+	instr/**/s	regs
+#endif
+
+#define MODENOP\
+	mov	r0, r0
+
+#define MODE(savereg,tmpreg,mode) \
+	mov	savereg, pc; \
+	bic	tmpreg, savereg, $0x0c000003; \
+	orr	tmpreg, tmpreg, $mode; \
+	teqp	tmpreg, $0
+
+#define RESTOREMODE(savereg) \
+	teqp	savereg, $0
+
+#define SAVEIRQS(tmpreg)
+
+#define RESTOREIRQS(tmpreg)
+
+#define DISABLEIRQS(tmpreg)\
+	teqp	pc, $0x08000003
+
+#define ENABLEIRQS(tmpreg)\
+	teqp	pc, $0x00000003
+
+#define USERMODE(tmpreg)\
+	teqp	pc, $0x00000000;\
+	mov	r0, r0
+
+#define SVCMODE(tmpreg)\
+	teqp	pc, $0x00000003;\
+	mov	r0, r0
+
+
+/*
+ * Save the current IRQ state and disable IRQs
+ * Note that this macro assumes FIQs are enabled, and
+ * that the processor is in SVC mode.
+ */
+	.macro	save_and_disable_irqs, oldcpsr, temp
+  mov \oldcpsr, pc
+  orr \temp, \oldcpsr, #0x08000000
+  teqp \temp, #0
+  .endm
+
+/*
+ * Restore interrupt state previously stored in
+ * a register
+ * ** Actually do nothing on Arc - hope that the caller uses a MOVS PC soon
+ * after!
+ */
+	.macro	restore_irqs, oldcpsr
+  @ This be restore_irqs
+  .endm
+
+/*
+ * These two are used to save LR/restore PC over a user-based access.
+ * The old 26-bit architecture requires that we do.  On 32-bit
+ * architecture, we can safely ignore this requirement.
+ */
+	.macro	save_lr
+	str	lr, [sp, #-4]!
+	.endm
+
+	.macro	restore_pc
+	ldmfd	sp!, {pc}^
+	.endm
+
+#define USER(x...)				\
+9999:	x;					\
+	.section __ex_table,"a";		\
+	.align	3;				\
+	.long	9999b,9001f;			\
+	.previous
+
+
diff -urN linux-2.4.29/include/asm-armnommu/proc-armo/cache.h linux-2.4.29-uc1/include/asm-armnommu/proc-armo/cache.h
--- linux-2.4.29/include/asm-armnommu/proc-armo/cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armo/cache.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ *  linux/include/asm-arm/proc-armo/cache.h
+ *
+ *  Copyright (C) 1999-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Cache handling for 26-bit ARM processors.
+ */
+#define flush_cache_all()			do { } while (0)
+#define flush_cache_mm(mm)			do { } while (0)
+#define flush_cache_range(mm,start,end)		do { } while (0)
+#define flush_cache_page(vma,vmaddr)		do { } while (0)
+#define flush_page_to_ram(page)			do { } while (0)
+
+#define invalidate_dcache_range(start,end)	do { } while (0)
+#define clean_dcache_range(start,end)		do { } while (0)
+#define flush_dcache_range(start,end)		do { } while (0)
+#define flush_dcache_page(page)			do { } while (0)
+#define clean_dcache_entry(_s)      do { } while (0)
+#define clean_cache_entry(_start)		do { } while (0)
+
+#define flush_icache_range(start,end)		do { } while (0)
+#define flush_icache_page(vma,page)		do { } while (0)
+#define flush_icache_user_range(vma,pg,adr,len)		do { } while (0)
+
+
+/* DAG: ARM3 will flush cache on MEMC updates anyway? so don't bother */
+#define clean_cache_area(_start,_size) do { } while (0)
+
+/*
+ * TLB flushing:
+ *
+ *  - flush_tlb_all() flushes all processes TLBs
+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
+ *  - flush_tlb_page(vma, vmaddr) flushes one page
+ *  - flush_tlb_range(mm, start, end) flushes a range of pages
+ */
+#define flush_tlb_all()				memc_update_all()
+#define flush_tlb_mm(mm)			do { } while (0)
+#define flush_tlb_range(mm, start, end)		do { (void)(start); (void)(end); } while (0)
+#define flush_tlb_page(vma, vmaddr)		do { } while (0)
+
+/*
+ * The following handle the weird MEMC chip
+ */
+extern __inline__ void memc_update_all(void)
+{
+	struct task_struct *p;
+
+	cpu_memc_update_all(init_mm.pgd);
+	for_each_task(p) {
+		if (!p->mm)
+			continue;
+		cpu_memc_update_all(p->mm->pgd);
+	}
+	processor._set_pgd(current->active_mm->pgd);
+}
+
+extern __inline__ void memc_update_mm(struct mm_struct *mm)
+{
+	cpu_memc_update_all(mm->pgd);
+
+	if (mm == current->active_mm)
+		processor._set_pgd(mm->pgd);
+}
+
+extern __inline__ void
+memc_update_addr(struct mm_struct *mm, pte_t pte, unsigned long vaddr)
+{
+	cpu_memc_update_entry(mm->pgd, pte_val(pte), vaddr);
+
+	if (mm == current->active_mm)
+		processor._set_pgd(mm->pgd);
+}
+
+extern __inline__ void
+memc_clear(struct mm_struct *mm, struct page *page)
+{
+	cpu_memc_update_entry(mm->pgd, (unsigned long) page_address(page), 0);
+
+	if (mm == current->active_mm)
+		processor._set_pgd(mm->pgd);
+}
diff -urN linux-2.4.29/include/asm-armnommu/proc-armo/elf.h linux-2.4.29-uc1/include/asm-armnommu/proc-armo/elf.h
--- linux-2.4.29/include/asm-armnommu/proc-armo/elf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armo/elf.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,15 @@
+/*
+ * ELF definitions for 26-bit CPUs
+ */
+
+#define ELF_EXEC_PAGESIZE	32768
+
+#ifdef __KERNEL__
+
+/* We can only execute 26-bit code. */
+#define ELF_PROC_OK(x)		\
+	((x)->e_flags & EF_ARM_APCS26)
+
+#define SET_PERSONALITY(ex,ibcs2) set_personality(PER_LINUX)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/proc-armo/io.h linux-2.4.29-uc1/include/asm-armnommu/proc-armo/io.h
--- linux-2.4.29/include/asm-armnommu/proc-armo/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armo/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,8 @@
+/*
+ * linux/include/asm-arm/proc-armo/io.h
+ */
+
+/* Nothing to do */
+#define dma_cache_inv(_start,_size)		do { } while (0)
+#define dma_cache_wback(_start,_size)		do { } while (0)
+#define dma_cache_wback_inv(_start,_size)	do { } while (0)
diff -urN linux-2.4.29/include/asm-armnommu/proc-armo/locks.h linux-2.4.29-uc1/include/asm-armnommu/proc-armo/locks.h
--- linux-2.4.29/include/asm-armnommu/proc-armo/locks.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armo/locks.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,161 @@
+/*
+ *  linux/include/asm-arm/proc-armo/locks.h
+ *
+ *  Copyright (C) 2000 Russell King
+ *  Fixes for 26 bit machines, (C) 2000 Dave Gilbert
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Interrupt safe locking assembler. 
+ */
+#ifndef __ASM_PROC_LOCKS_H
+#define __ASM_PROC_LOCKS_H
+
+/* Decrements by 1, fails if value < 0 */
+#define __down_op(ptr,fail)			\
+	({					\
+	__asm__ __volatile__ (			\
+	"@ atomic down operation\n"		\
+"	mov	ip, pc\n"			\
+"	orr	lr, ip, #0x08000000\n"		\
+"	teqp	lr, #0\n"			\
+"	ldr	lr, [%0]\n"			\
+"	and	ip, ip, #0x0c000003\n"		\
+"	subs	lr, lr, #1\n"			\
+"	str	lr, [%0]\n"			\
+"	orrmi	ip, ip, #0x80000000	@ set N\n" \
+"	teqp	ip, #0\n"			\
+"	movmi	ip, %0\n"			\
+"	blmi	" SYMBOL_NAME_STR(fail)		\
+	:					\
+	: "r" (ptr)				\
+	: "ip", "lr", "cc");			\
+	})
+
+#define __down_op_ret(ptr,fail)			\
+	({					\
+		unsigned int result;		\
+	__asm__ __volatile__ (			\
+"	@ down_op_ret\n"			\
+"	mov	ip, pc\n"			\
+"	orr	lr, ip, #0x08000000\n"		\
+"	teqp	lr, #0\n"			\
+"	ldr	lr, [%1]\n"			\
+"	and	ip, ip, #0x0c000003\n"		\
+"	subs	lr, lr, #1\n"			\
+"	str	lr, [%1]\n"			\
+"	orrmi	ip, ip, #0x80000000	@ set N\n" \
+"	teqp	ip, #0\n"			\
+"	movmi	ip, %1\n"			\
+"	movpl	ip, #0\n"			\
+"	blmi	" SYMBOL_NAME_STR(fail) "\n"	\
+"	mov	%0, ip"				\
+	: "=&r" (result)			\
+	: "r" (ptr)				\
+	: "ip", "lr", "cc");			\
+	result;					\
+	})
+
+#define __up_op(ptr,wake)			\
+	({					\
+	__asm__ __volatile__ (			\
+	"@ up_op\n"				\
+"	mov	ip, pc\n"			\
+"	orr	lr, ip, #0x08000000\n"		\
+"	teqp	lr, #0\n"			\
+"	ldr	lr, [%0]\n"			\
+"	and	ip, ip, #0x0c000003\n"		\
+"	adds	lr, lr, #1\n"			\
+"	str	lr, [%0]\n"			\
+"	orrle	ip, ip, #0x80000000	@ set N - should this be mi ??? DAG ! \n" \
+"	teqp	ip, #0\n"			\
+"	movmi	ip, %0\n"			\
+"	blmi	" SYMBOL_NAME_STR(wake)		\
+	:					\
+	: "r" (ptr)				\
+	: "ip", "lr", "cc");			\
+	})
+
+/*
+ * The value 0x01000000 supports up to 128 processors and
+ * lots of processes.  BIAS must be chosen such that sub'ing
+ * BIAS once per CPU will result in the long remaining
+ * negative.
+ */
+#define RW_LOCK_BIAS      0x01000000
+#define RW_LOCK_BIAS_STR "0x01000000"
+
+/* Decrements by RW_LOCK_BIAS rather than 1, fails if value != 0 */
+#define __down_op_write(ptr,fail)		\
+	({					\
+	__asm__ __volatile__(			\
+	"@ down_op_write\n"			\
+"	mov	ip, pc\n"			\
+"	orr	lr, ip, #0x08000000\n"		\
+"	teqp	lr, #0\n"			\
+"	and	ip, ip, #0x0c000003\n"		\
+\
+"	ldr	lr, [%0]\n"			\
+"	subs	lr, lr, %1\n"			\
+"	str	lr, [%0]\n"			\
+\
+" orreq ip, ip, #0x40000000 @ set Z \n"\
+"	teqp	ip, #0\n"			\
+"	movne	ip, %0\n"			\
+"	blne	" SYMBOL_NAME_STR(fail)		\
+	:					\
+	: "r" (ptr), "I" (RW_LOCK_BIAS)		\
+	: "ip", "lr", "cc");			\
+	})
+
+/* Increments by RW_LOCK_BIAS, wakes if value >= 0 */
+#define __up_op_write(ptr,wake)			\
+	({					\
+	__asm__ __volatile__(			\
+	"@ up_op_read\n"			\
+"	mov	ip, pc\n"			\
+"	orr	lr, ip, #0x08000000\n"		\
+"	teqp	lr, #0\n"			\
+\
+"	ldr	lr, [%0]\n"			\
+"	and	ip, ip, #0x0c000003\n"		\
+"	adds	lr, lr, %1\n"			\
+"	str	lr, [%0]\n"			\
+\
+" orrcs ip, ip, #0x20000000 @ set C\n" \
+"	teqp	ip, #0\n"			\
+"	movcs	ip, %0\n"			\
+"	blcs	" SYMBOL_NAME_STR(wake)		\
+	:					\
+	: "r" (ptr), "I" (RW_LOCK_BIAS)		\
+	: "ip", "lr", "cc");			\
+	})
+
+#define __down_op_read(ptr,fail)		\
+	__down_op(ptr, fail)
+
+#define __up_op_read(ptr,wake)			\
+	({					\
+	__asm__ __volatile__(			\
+	"@ up_op_read\n"			\
+"	mov	ip, pc\n"			\
+"	orr	lr, ip, #0x08000000\n"		\
+"	teqp	lr, #0\n"			\
+\
+"	ldr	lr, [%0]\n"			\
+"	and	ip, ip, #0x0c000003\n"		\
+"	adds	lr, lr, %1\n"			\
+"	str	lr, [%0]\n"			\
+\
+" orreq ip, ip, #0x40000000 @ Set Z \n" \
+"	teqp	ip, #0\n"			\
+"	moveq	ip, %0\n"			\
+"	bleq	" SYMBOL_NAME_STR(wake)		\
+	:					\
+	: "r" (ptr), "I" (1)			\
+	: "ip", "lr", "cc");			\
+	})
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/proc-armo/page.h linux-2.4.29-uc1/include/asm-armnommu/proc-armo/page.h
--- linux-2.4.29/include/asm-armnommu/proc-armo/page.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armo/page.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+ *  linux/include/asm-arm/proc-armo/page.h
+ *
+ *  Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_PROC_PAGE_H
+#define __ASM_PROC_PAGE_H
+
+#include <linux/config.h>
+
+/* PAGE_SHIFT determines the page size.  This is configurable. */
+#if defined(CONFIG_PAGESIZE_16)
+#define PAGE_SHIFT	14		/* 16K */
+#else		/* default */
+#define PAGE_SHIFT	15		/* 32K */
+#endif
+
+#define EXEC_PAGESIZE   32768
+
+#endif /* __ASM_PROC_PAGE_H */
diff -urN linux-2.4.29/include/asm-armnommu/proc-armo/pgtable.h linux-2.4.29-uc1/include/asm-armnommu/proc-armo/pgtable.h
--- linux-2.4.29/include/asm-armnommu/proc-armo/pgtable.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armo/pgtable.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,104 @@
+/*
+ *  linux/include/asm-arm/proc-armo/pgtable.h
+ *
+ *  Copyright (C) 1995-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  18-Oct-1997	RMK	Now two-level (32x32)
+ */
+#ifndef __ASM_PROC_PGTABLE_H
+#define __ASM_PROC_PGTABLE_H
+
+/*
+ * entries per page directory level: they are two-level, so
+ * we don't really have any PMD directory.
+ */
+#define PTRS_PER_PTE		32
+#define PTRS_PER_PMD		1
+#define PTRS_PER_PGD		32
+
+/*
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_START	  0x01a00000
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END	  0x01c00000
+
+#define _PAGE_TABLE     (0x01)
+
+#define pmd_bad(pmd)		((pmd_val(pmd) & 0xfc000002))
+#define set_pmd(pmdp,pmd)	((*(pmdp)) = (pmd))
+
+extern __inline__ pmd_t __mk_pmd(pte_t *ptep, unsigned long prot)
+{
+	unsigned long pte_ptr = (unsigned long)ptep;
+	pmd_t pmd;
+
+	pmd_val(pmd) = __virt_to_phys(pte_ptr) | prot;
+
+	return pmd;
+}
+
+/* these are aliases for the above function */
+#define mk_user_pmd(ptep)	__mk_pmd(ptep, _PAGE_TABLE)
+#define mk_kernel_pmd(ptep)	__mk_pmd(ptep, _PAGE_TABLE)
+
+extern __inline__ unsigned long pmd_page(pmd_t pmd)
+{
+	return __phys_to_virt(pmd_val(pmd) & ~_PAGE_TABLE);
+}
+
+#define set_pte(pteptr, pteval)	((*(pteptr)) = (pteval))
+
+#define _PAGE_PRESENT	0x01
+#define _PAGE_READONLY	0x02
+#define _PAGE_NOT_USER	0x04
+#define _PAGE_OLD	0x08
+#define _PAGE_CLEAN	0x10
+
+/*                               -- present --   -- !dirty --  --- !write ---   ---- !user --- */
+#define PAGE_NONE       __pgprot(_PAGE_PRESENT | _PAGE_CLEAN | _PAGE_READONLY | _PAGE_NOT_USER)
+#define PAGE_SHARED     __pgprot(_PAGE_PRESENT | _PAGE_CLEAN                                  )
+#define PAGE_COPY       __pgprot(_PAGE_PRESENT | _PAGE_CLEAN | _PAGE_READONLY                 )
+#define PAGE_READONLY   __pgprot(_PAGE_PRESENT | _PAGE_CLEAN | _PAGE_READONLY                 )
+#define PAGE_KERNEL     __pgprot(_PAGE_PRESENT                                | _PAGE_NOT_USER)
+
+#define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_OLD | _PAGE_CLEAN)
+
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+#define pte_present(pte)		(pte_val(pte) & _PAGE_PRESENT)
+#define pte_read(pte)			(!(pte_val(pte) & _PAGE_NOT_USER))
+#define pte_write(pte)			(!(pte_val(pte) & _PAGE_READONLY))
+#define pte_exec(pte)			(!(pte_val(pte) & _PAGE_NOT_USER))
+#define pte_dirty(pte)			(!(pte_val(pte) & _PAGE_CLEAN))
+#define pte_young(pte)			(!(pte_val(pte) & _PAGE_OLD))
+
+extern inline pte_t pte_nocache(pte_t pte)	{ return pte; }
+extern inline pte_t pte_wrprotect(pte_t pte)    { pte_val(pte) |= _PAGE_READONLY;  return pte; }
+extern inline pte_t pte_rdprotect(pte_t pte)    { pte_val(pte) |= _PAGE_NOT_USER;  return pte; }
+extern inline pte_t pte_exprotect(pte_t pte)    { pte_val(pte) |= _PAGE_NOT_USER;  return pte; }
+extern inline pte_t pte_mkclean(pte_t pte)      { pte_val(pte) |= _PAGE_CLEAN;     return pte; }
+extern inline pte_t pte_mkold(pte_t pte)        { pte_val(pte) |= _PAGE_OLD;       return pte; }
+
+extern inline pte_t pte_mkwrite(pte_t pte)      { pte_val(pte) &= ~_PAGE_READONLY; return pte; }
+extern inline pte_t pte_mkread(pte_t pte)       { pte_val(pte) &= ~_PAGE_NOT_USER; return pte; }
+extern inline pte_t pte_mkexec(pte_t pte)       { pte_val(pte) &= ~_PAGE_NOT_USER; return pte; }
+extern inline pte_t pte_mkdirty(pte_t pte)      { pte_val(pte) &= ~_PAGE_CLEAN;    return pte; }
+extern inline pte_t pte_mkyoung(pte_t pte)      { pte_val(pte) &= ~_PAGE_OLD;      return pte; }
+
+#define pte_alloc_kernel        pte_alloc
+
+/*
+ * We don't store cache state bits in the page table here.
+ */
+#define pgprot_noncached(prot)	(prot)
+
+#endif /* __ASM_PROC_PGTABLE_H */
diff -urN linux-2.4.29/include/asm-armnommu/proc-armo/processor.h linux-2.4.29-uc1/include/asm-armnommu/proc-armo/processor.h
--- linux-2.4.29/include/asm-armnommu/proc-armo/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armo/processor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,87 @@
+/*
+ *  linux/include/asm-arm/proc-armo/processor.h
+ *
+ *  Copyright (C) 1996 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Changelog:
+ *   27-06-1996	RMK	Created
+ *   10-10-1996	RMK	Brought up to date with SA110
+ *   26-09-1996	RMK	Added 'EXTRA_THREAD_STRUCT*'
+ *   28-09-1996	RMK	Moved start_thread into the processor dependencies
+ *   11-01-1998	RMK	Added new uaccess_t
+ *   09-09-1998	PJB	Delete redundant `wp_works_ok'
+ *   30-05-1999	PJB	Save sl across context switches
+ */
+#ifndef __ASM_PROC_PROCESSOR_H
+#define __ASM_PROC_PROCESSOR_H
+
+#include <linux/string.h>
+
+#define KERNEL_STACK_SIZE 4096
+
+struct context_save_struct {
+	unsigned long r4;
+	unsigned long r5;
+	unsigned long r6;
+	unsigned long r7;
+	unsigned long r8;
+	unsigned long r9;
+	unsigned long sl;
+	unsigned long fp;
+	unsigned long pc;
+};
+
+#define INIT_CSS (struct context_save_struct){ 0, 0, 0, 0, 0, 0, 0, 0, SVC26_MODE }
+
+typedef struct {
+	void (*put_byte)(void);			/* Special calling convention */
+	void (*get_byte)(void);			/* Special calling convention */
+	void (*put_half)(void);			/* Special calling convention */
+	void (*get_half)(void);			/* Special calling convention */
+	void (*put_word)(void);			/* Special calling convention */
+	void (*get_word)(void);			/* Special calling convention */
+	unsigned long (*copy_from_user)(void *to, const void *from, unsigned long sz);
+	unsigned long (*copy_to_user)(void *to, const void *from, unsigned long sz);
+	unsigned long (*clear_user)(void *addr, unsigned long sz);
+	unsigned long (*strncpy_from_user)(char *to, const char *from, unsigned long sz);
+	unsigned long (*strnlen_user)(const char *s, long n);
+} uaccess_t;
+
+extern uaccess_t uaccess_user, uaccess_kernel;
+
+#define EXTRA_THREAD_STRUCT							\
+	uaccess_t	*uaccess;		/* User access functions*/
+
+#define EXTRA_THREAD_STRUCT_INIT		\
+	uaccess:	&uaccess_kernel,
+
+#define start_thread(regs,pc,sp)					\
+({									\
+	unsigned long *stack = (unsigned long *)sp;			\
+	set_fs(USER_DS);						\
+	memzero(regs->uregs, sizeof (regs->uregs));			\
+	regs->ARM_pc = pc;		/* pc */			\
+	regs->ARM_sp = sp;		/* sp */			\
+	regs->ARM_r2 = stack[2];	/* r2 (envp) */			\
+	regs->ARM_r1 = stack[1];	/* r1 (argv) */			\
+	regs->ARM_r0 = stack[0];	/* r0 (argc) */			\
+})
+
+#define KSTK_EIP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)))[1022])
+#define KSTK_ESP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)))[1020])
+
+/* Allocation and freeing of basic task resources. */
+/*
+ * NOTE! The task struct and the stack go together
+ */
+extern unsigned long get_page_8k(int priority);
+extern void free_page_8k(unsigned long page);
+
+#define ll_alloc_task_struct()	((struct task_struct *)get_page_8k(GFP_KERNEL))
+#define ll_free_task_struct(p)  free_page_8k((unsigned long)(p))
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/proc-armo/ptrace.h linux-2.4.29-uc1/include/asm-armnommu/proc-armo/ptrace.h
--- linux-2.4.29/include/asm-armnommu/proc-armo/ptrace.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armo/ptrace.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,94 @@
+/*
+ *  linux/include/asm-arm/proc-armo/ptrace.h
+ *
+ *  Copyright (C) 1996-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_PROC_PTRACE_H
+#define __ASM_PROC_PTRACE_H
+
+#define USR26_MODE	0x00
+#define FIQ26_MODE	0x01
+#define IRQ26_MODE	0x02
+#define SVC26_MODE	0x03
+#define MODE_MASK	0x03
+#define F_BIT		(1 << 26)
+#define I_BIT		(1 << 27)
+#define CC_V_BIT	(1 << 28)
+#define CC_C_BIT	(1 << 29)
+#define CC_Z_BIT	(1 << 30)
+#define CC_N_BIT	(1 << 31)
+#define PCMASK		0xfc000003
+
+#ifndef __ASSEMBLY__
+
+/* this struct defines the way the registers are stored on the
+   stack during a system call. */
+
+struct pt_regs {
+	long uregs[17];
+};
+
+#define ARM_pc		uregs[15]
+#define ARM_lr		uregs[14]
+#define ARM_sp		uregs[13]
+#define ARM_ip		uregs[12]
+#define ARM_fp		uregs[11]
+#define ARM_r10		uregs[10]
+#define ARM_r9		uregs[9]
+#define ARM_r8		uregs[8]
+#define ARM_r7		uregs[7]
+#define ARM_r6		uregs[6]
+#define ARM_r5		uregs[5]
+#define ARM_r4		uregs[4]
+#define ARM_r3		uregs[3]
+#define ARM_r2		uregs[2]
+#define ARM_r1		uregs[1]
+#define ARM_r0		uregs[0]
+#define ARM_ORIG_r0	uregs[16]
+
+#ifdef __KERNEL__
+
+#define processor_mode(regs) \
+	((regs)->ARM_pc & MODE_MASK)
+
+#define user_mode(regs) \
+	(processor_mode(regs) == USR26_MODE)
+
+#define thumb_mode(regs) (0)
+
+#define interrupts_enabled(regs) \
+	(!((regs)->ARM_pc & I_BIT))
+
+#define fast_interrupts_enabled(regs) \
+	(!((regs)->ARM_pc & F_BIT))
+
+#define condition_codes(regs) \
+	((regs)->ARM_pc & (CC_V_BIT|CC_C_BIT|CC_Z_BIT|CC_N_BIT))
+
+/* Are the current registers suitable for user mode?
+ * (used to maintain security in signal handlers)
+ */
+static inline int valid_user_regs(struct pt_regs *regs)
+{
+	if (user_mode(regs) &&
+	    (regs->ARM_pc & (F_BIT | I_BIT)) == 0)
+		return 1;
+
+	/*
+	 * force it to be something sensible
+	 */
+	regs->ARM_pc &= ~(MODE_MASK | F_BIT | I_BIT);
+
+	return 0;
+}
+
+#endif	/* __KERNEL__ */
+
+#endif	/* __ASSEMBLY__ */
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/proc-armo/shmparam.h linux-2.4.29-uc1/include/asm-armnommu/proc-armo/shmparam.h
--- linux-2.4.29/include/asm-armnommu/proc-armo/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armo/shmparam.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,19 @@
+/*
+ *  linux/include/asm-arm/proc-armo/shmparam.h
+ *
+ *  Copyright (C) 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  definitions for the shared process memory on the ARM3
+ */
+#ifndef __ASM_PROC_SHMPARAM_H
+#define __ASM_PROC_SHMPARAM_H
+
+#ifndef SHMMAX
+#define SHMMAX		0x003fa000
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/proc-armo/system.h linux-2.4.29-uc1/include/asm-armnommu/proc-armo/system.h
--- linux-2.4.29/include/asm-armnommu/proc-armo/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armo/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,128 @@
+/*
+ *  linux/include/asm-arm/proc-armo/system.h
+ *
+ *  Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_PROC_SYSTEM_H
+#define __ASM_PROC_SYSTEM_H
+
+#include <asm/proc-fns.h>
+
+extern __inline__ unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
+{
+	extern void __bad_xchg(volatile void *, int);
+
+	switch (size) {
+		case 1:	return cpu_xchg_1(x, ptr);
+		case 4:	return cpu_xchg_4(x, ptr);
+		default: __bad_xchg(ptr, size);
+	}
+	return 0;
+}
+
+/*
+ * We need to turn the caches off before calling the reset vector - RiscOS
+ * messes up if we don't
+ */
+#define proc_hard_reset()	cpu_proc_fin()
+
+/*
+ * A couple of speedups for the ARM
+ */
+
+/*
+ * Save the current interrupt enable state & disable IRQs
+ */
+#define __save_flags_cli(x)				\
+	do {						\
+	  unsigned long temp;				\
+	  __asm__ __volatile__(				\
+"	mov	%0, pc		@ save_flags_cli\n"	\
+"	orr	%1, %0, #0x08000000\n"			\
+"	and	%0, %0, #0x0c000000\n"			\
+"	teqp	%1, #0\n"				\
+	  : "=r" (x), "=r" (temp)			\
+	  :						\
+	  : "memory");					\
+	} while (0)
+	
+/*
+ * Enable IRQs
+ */
+#define __sti()					\
+	do {					\
+	  unsigned long temp;			\
+	  __asm__ __volatile__(			\
+"	mov	%0, pc		@ sti\n"	\
+"	bic	%0, %0, #0x08000000\n"		\
+"	teqp	%0, #0\n"			\
+	  : "=r" (temp)				\
+	  :					\
+	  : "memory");				\
+	} while(0)
+
+/*
+ * Disable IRQs
+ */
+#define __cli()					\
+	do {					\
+	  unsigned long temp;			\
+	  __asm__ __volatile__(			\
+"	mov	%0, pc		@ cli\n"	\
+"	orr	%0, %0, #0x08000000\n"		\
+"	teqp	%0, #0\n"			\
+	  : "=r" (temp)				\
+	  :					\
+	  : "memory");				\
+	} while(0)
+
+#define __clf()	do {				\
+	unsigned long temp;			\
+	__asm__ __volatile__(			\
+"	mov	%0, pc		@ clf\n"	\
+"	orr	%0, %0, #0x04000000\n"		\
+"	teqp	%0, #0\n"			\
+	: "=r" (temp));				\
+    } while(0)
+
+#define __stf()	do {				\
+	unsigned long temp;			\
+	__asm__ __volatile__(			\
+"	mov	%0, pc		@ stf\n"	\
+"	bic	%0, %0, #0x04000000\n"		\
+"	teqp	%0, #0\n"			\
+	: "=r" (temp));				\
+    } while(0)
+
+/*
+ * save current IRQ & FIQ state
+ */
+#define __save_flags(x)				\
+	do {					\
+	  __asm__ __volatile__(			\
+"	mov	%0, pc		@ save_flags\n"	\
+"	and	%0, %0, #0x0c000000\n"		\
+	  : "=r" (x));				\
+	} while (0)
+
+/*
+ * restore saved IRQ & FIQ state
+ */
+#define __restore_flags(x)				\
+	do {						\
+	  unsigned long temp;				\
+	  __asm__ __volatile__(				\
+"	mov	%0, pc		@ restore_flags\n"	\
+"	bic	%0, %0, #0x0c000000\n"			\
+"	orr	%0, %0, %1\n"				\
+"	teqp	%0, #0\n"				\
+	  : "=&r" (temp)				\
+	  : "r" (x)					\
+	  : "memory");					\
+	} while (0)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/proc-armo/uaccess.h linux-2.4.29-uc1/include/asm-armnommu/proc-armo/uaccess.h
--- linux-2.4.29/include/asm-armnommu/proc-armo/uaccess.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armo/uaccess.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,138 @@
+/*
+ *  linux/include/asm-arm/proc-armo/segment.h
+ *
+ *  Copyright (C) 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * The fs functions are implemented on the ARM2 and ARM3 architectures
+ * manually.
+ * Use *_user functions to access user memory with faulting behaving
+ *   as though the user is accessing the memory.
+ * Use set_fs(get_ds()) and then the *_user functions to allow them to
+ *   access kernel memory.
+ */
+
+/*
+ * These are the values used to represent the user `fs' and the kernel `ds'
+ */
+#define KERNEL_DS	0x03000000
+#define USER_DS   	0x02000000
+
+extern uaccess_t uaccess_user, uaccess_kernel;
+
+extern __inline__ void set_fs (mm_segment_t fs)
+{
+	current->addr_limit = fs;
+	current->thread.uaccess = fs == USER_DS ? &uaccess_user : &uaccess_kernel;
+}
+
+#define __range_ok(addr,size) ({					\
+	unsigned long flag, sum;					\
+	__asm__ __volatile__("subs %1, %0, %3; cmpcs %1, %2; movcs %0, #0" \
+		: "=&r" (flag), "=&r" (sum)				\
+		: "r" (addr), "Ir" (size), "0" (current->addr_limit)	\
+		: "cc");						\
+	flag; })
+
+#define __addr_ok(addr) ({						\
+	unsigned long flag;						\
+	__asm__ __volatile__("cmp %2, %0; movlo %0, #0"			\
+		: "=&r" (flag)						\
+		: "0" (current->addr_limit), "r" (addr)			\
+		: "cc");						\
+	(flag == 0); })
+
+#define __put_user_asm_byte(x,addr,err)					\
+	__asm__ __volatile__(						\
+	"	mov	r0, %1\n"					\
+	"	mov	r1, %2\n"					\
+	"	mov	r2, %0\n"					\
+	"	mov	lr, pc\n"					\
+	"	mov	pc, %3\n"					\
+	"	mov	%0, r2\n"					\
+	: "=r" (err)							\
+	: "r" (x), "r" (addr), "r" (current->thread.uaccess->put_byte),	\
+	  "0" (err)							\
+	: "r0", "r1", "r2", "lr")
+
+#define __put_user_asm_half(x,addr,err)					\
+	__asm__ __volatile__(						\
+	"	mov	r0, %1\n"					\
+	"	mov	r1, %2\n"					\
+	"	mov	r2, %0\n"					\
+	"	mov	lr, pc\n"					\
+	"	mov	pc, %3\n"					\
+	"	mov	%0, r2\n"					\
+	: "=r" (err)							\
+	: "r" (x), "r" (addr), "r" (current->thread.uaccess->put_half),	\
+	  "0" (err)							\
+	: "r0", "r1", "r2", "lr")
+
+#define __put_user_asm_word(x,addr,err)					\
+	__asm__ __volatile__(						\
+	"	mov	r0, %1\n"					\
+	"	mov	r1, %2\n"					\
+	"	mov	r2, %0\n"					\
+	"	mov	lr, pc\n"					\
+	"	mov	pc, %3\n"					\
+	"	mov	%0, r2\n"					\
+	: "=r" (err)							\
+	: "r" (x), "r" (addr), "r" (current->thread.uaccess->put_word),	\
+	  "0" (err)							\
+	: "r0", "r1", "r2", "lr")
+
+#define __get_user_asm_byte(x,addr,err)					\
+	__asm__ __volatile__(						\
+	"	mov	r0, %2\n"					\
+	"	mov	r1, %0\n"					\
+	"	mov	lr, pc\n"					\
+	"	mov	pc, %3\n"					\
+	"	mov	%0, r1\n"					\
+	"	mov	%1, r0\n"					\
+	: "=r" (err), "=r" (x)						\
+	: "r" (addr), "r" (current->thread.uaccess->get_byte), "0" (err)	\
+	: "r0", "r1", "r2", "lr")
+
+#define __get_user_asm_half(x,addr,err)					\
+	__asm__ __volatile__(						\
+	"	mov	r0, %2\n"					\
+	"	mov	r1, %0\n"					\
+	"	mov	lr, pc\n"					\
+	"	mov	pc, %3\n"					\
+	"	mov	%0, r1\n"					\
+	"	mov	%1, r0\n"					\
+	: "=r" (err), "=r" (x)						\
+	: "r" (addr), "r" (current->thread.uaccess->get_half), "0" (err)	\
+	: "r0", "r1", "r2", "lr")
+
+#define __get_user_asm_word(x,addr,err)					\
+	__asm__ __volatile__(						\
+	"	mov	r0, %2\n"					\
+	"	mov	r1, %0\n"					\
+	"	mov	lr, pc\n"					\
+	"	mov	pc, %3\n"					\
+	"	mov	%0, r1\n"					\
+	"	mov	%1, r0\n"					\
+	: "=r" (err), "=r" (x)						\
+	: "r" (addr), "r" (current->thread.uaccess->get_word), "0" (err)	\
+	: "r0", "r1", "r2", "lr")
+
+#define __do_copy_from_user(to,from,n)					\
+	(n) = current->thread.uaccess->copy_from_user((to),(from),(n))
+
+#define __do_copy_to_user(to,from,n)					\
+	(n) = current->thread.uaccess->copy_to_user((to),(from),(n))
+
+#define __do_clear_user(addr,sz)					\
+	(sz) = current->thread.uaccess->clear_user((addr),(sz))
+
+#define __do_strncpy_from_user(dst,src,count,res)			\
+	(res) = current->thread.uaccess->strncpy_from_user(dst,src,count)
+
+#define __do_strnlen_user(s,n,res)					\
+	(res) = current->thread.uaccess->strnlen_user(s,n)
diff -urN linux-2.4.29/include/asm-armnommu/proc-armo/uncompress.h linux-2.4.29-uc1/include/asm-armnommu/proc-armo/uncompress.h
--- linux-2.4.29/include/asm-armnommu/proc-armo/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armo/uncompress.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,11 @@
+/*
+ *  linux/include/asm-arm/proc-armo/uncompress.h
+ *
+ *  Copyright (C) 1997 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define proc_decomp_setup()
diff -urN linux-2.4.29/include/asm-armnommu/proc-armv/assembler.h linux-2.4.29-uc1/include/asm-armnommu/proc-armv/assembler.h
--- linux-2.4.29/include/asm-armnommu/proc-armv/assembler.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armv/assembler.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,74 @@
+/*
+ *  linux/asm-arm/proc-armv/assembler.h
+ *
+ *  Copyright (C) 1996-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  This file contains ARM processor specifics for
+ *  the ARM6 and better processors.
+ */
+#define MODE_USR	USR_MODE
+#define MODE_FIQ	FIQ_MODE
+#define MODE_IRQ	IRQ_MODE
+#define MODE_SVC	SVC_MODE
+
+#define DEFAULT_FIQ	MODE_FIQ
+
+/*
+ * LOADREGS - ldm with PC in register list (eg, ldmfd sp!, {pc})
+ */
+#ifdef __STDC__
+#define LOADREGS(cond, base, reglist...)\
+	ldm##cond	base,reglist
+#else
+#define LOADREGS(cond, base, reglist...)\
+	ldm/**/cond	base,reglist
+#endif
+
+/*
+ * Build a return instruction for this processor type.
+ */
+#define RETINSTR(instr, regs...)\
+	instr	regs
+
+/*
+ * Save the current IRQ state and disable IRQs.  Note that this macro
+ * assumes FIQs are enabled, and that the processor is in SVC mode.
+ */
+	.macro	save_and_disable_irqs, oldcpsr, temp
+	mrs	\oldcpsr, cpsr
+	mov	\temp, #I_BIT | MODE_SVC
+	msr	cpsr_c, \temp
+	.endm
+
+/*
+ * Restore interrupt state previously stored in a register.  We don't
+ * guarantee that this will preserve the flags.
+ */
+	.macro	restore_irqs, oldcpsr
+	msr	cpsr_c, \oldcpsr
+	.endm
+
+/*
+ * These two are used to save LR/restore PC over a user-based access.
+ * The old 26-bit architecture requires that we do.  On 32-bit
+ * architecture, we can safely ignore this requirement.
+ */
+	.macro	save_lr
+	.endm
+
+	.macro	restore_pc
+	mov	pc, lr
+	.endm
+
+#define USER(x...)				\
+9999:	x;					\
+	.section __ex_table,"a";		\
+	.align	3;				\
+	.long	9999b,9001f;			\
+	.previous
+
+
diff -urN linux-2.4.29/include/asm-armnommu/proc-armv/cache.h linux-2.4.29-uc1/include/asm-armnommu/proc-armv/cache.h
--- linux-2.4.29/include/asm-armnommu/proc-armv/cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armv/cache.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,165 @@
+/*
+ *  linux/include/asm-arm/proc-armv/cache.h
+ *
+ *  Copyright (C) 1999-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <asm/mman.h>
+
+/*
+ * Cache handling for 32-bit ARM processors.
+ *
+ * Note that on ARM, we have a more accurate specification than that
+ * Linux's "flush".  We therefore do not use "flush" here, but instead
+ * use:
+ *
+ * clean:      the act of pushing dirty cache entries out to memory.
+ * invalidate: the act of discarding data held within the cache,
+ *             whether it is dirty or not.
+ */
+
+/*
+ * Generic I + D cache
+ */
+#define flush_cache_all()						\
+	do {								\
+		cpu_cache_clean_invalidate_all();			\
+	} while (0)
+
+/* This is always called for current->mm */
+#define flush_cache_mm(_mm)						\
+	do {								\
+		if ((_mm) == current->active_mm)			\
+			cpu_cache_clean_invalidate_all();		\
+	} while (0)
+
+#define flush_cache_range(_mm,_start,_end)				\
+	do {								\
+		if ((_mm) == current->mm)				\
+			cpu_cache_clean_invalidate_range((_start), (_end), 1); \
+	} while (0)
+
+#define flush_cache_page(_vma,_vmaddr)					\
+	do {								\
+		if (1 /* DAVIDM (_vma)->vm_mm == current->mm */) {			\
+			cpu_cache_clean_invalidate_range((_vmaddr),	\
+				(_vmaddr) + PAGE_SIZE,			\
+				((_vma)->vm_flags & VM_EXEC));		\
+		} \
+	} while (0)
+
+/*
+ * This flushes back any buffered write data.  We have to clean the entries
+ * in the cache for this page.  This does not invalidate either I or D caches.
+ */
+static __inline__ void flush_page_to_ram(struct page *page)
+{
+	cpu_flush_ram_page(page_address(page));
+}
+
+/*
+ * D cache only
+ */
+
+#define invalidate_dcache_range(_s,_e)	cpu_dcache_invalidate_range((_s),(_e))
+#define clean_dcache_range(_s,_e)	cpu_dcache_clean_range((_s),(_e))
+#define flush_dcache_range(_s,_e)	cpu_cache_clean_invalidate_range((_s),(_e),0)
+
+/*
+ * FIXME: We currently clean the dcache for this page.  Should we
+ * also invalidate the Dcache?  And what about the Icache? -- rmk
+ */
+#define flush_dcache_page(page)		cpu_dcache_clean_page(page_address(page))
+
+#define clean_dcache_entry(_s)		cpu_dcache_clean_entry((unsigned long)(_s))
+
+/*
+ * I cache only
+ */
+#define flush_icache_range(_s,_e)					\
+	do {								\
+		cpu_icache_invalidate_range((_s), (_e));		\
+	} while (0)
+
+/* DAVIDM - this could be better */
+#define flush_icache_user_range(vma,pg,adr,len) flush_cache_all()
+
+#define flush_icache_page(vma,pg)					\
+	do {								\
+		if ((vma)->vm_flags & PROT_EXEC)			\
+			cpu_icache_invalidate_page(page_address(pg));	\
+	} while (0)
+
+/*
+ * Old ARM MEMC stuff.  This supports the reversed mapping handling that
+ * we have on the older 26-bit machines.  We don't have a MEMC chip, so...
+ */
+#define memc_update_all()		do { } while (0)
+#define memc_update_mm(mm)		do { } while (0)
+#define memc_update_addr(mm,pte,log)	do { } while (0)
+#define memc_clear(mm,physaddr)		do { } while (0)
+
+/*
+ * TLB flushing.
+ *
+ *  - flush_tlb_all()			flushes all processes TLBs
+ *  - flush_tlb_mm(mm)			flushes the specified mm context TLB's
+ *  - flush_tlb_page(vma, vmaddr)	flushes TLB for specified page
+ *  - flush_tlb_range(mm, start, end)	flushes TLB for specified range of pages
+ *
+ * We drain the write buffer in here to ensure that the page tables in ram
+ * are really up to date.  It is more efficient to do this here...
+ */
+
+/*
+ * Notes:
+ *  current->active_mm is the currently active memory description.
+ *  current->mm == NULL iff we are lazy.
+ */
+#define flush_tlb_all()							\
+	do {								\
+		cpu_tlb_invalidate_all();				\
+	} while (0)
+
+/*
+ * Flush all user virtual address space translations described by `_mm'.
+ *
+ * Currently, this is always called for current->mm, which should be
+ * the same as current->active_mm.  This is currently not be called for
+ * the lazy TLB case.
+ */
+#define flush_tlb_mm(_mm)						\
+	do {								\
+		if ((_mm) == current->active_mm)			\
+			cpu_tlb_invalidate_all();			\
+	} while (0)
+
+/*
+ * Flush the specified range of user virtual address space translations.
+ *
+ * _mm may not be current->active_mm, but may not be NULL.
+ */
+#define flush_tlb_range(_mm,_start,_end)				\
+	do {								\
+		if ((_mm) == current->active_mm)			\
+			cpu_tlb_invalidate_range((_start), (_end));	\
+	} while (0)
+
+/*
+ * Flush the specified user virtual address space translation.
+ */
+#define flush_tlb_page(_vma,_page)					\
+	do {								\
+		if (1 /* DAVIDM (_vma)->vm_mm == current->active_mm */)		\
+			cpu_tlb_invalidate_page((_page),		\
+				 ((_vma)->vm_flags & VM_EXEC));		\
+	} while (0)
+
+/*
+ * 32-bit ARM Processors don't have any MMU cache
+ */
+#define update_mmu_cache(vma,address,pte) do { } while (0)
+
diff -urN linux-2.4.29/include/asm-armnommu/proc-armv/domain.h linux-2.4.29-uc1/include/asm-armnommu/proc-armv/domain.h
--- linux-2.4.29/include/asm-armnommu/proc-armv/domain.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armv/domain.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,45 @@
+/*
+ *  linux/include/asm-arm/proc-armv/domain.h
+ *
+ *  Copyright (C) 1999 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Note:   REVISIT: look into weeding all this stuff out for armnommu.
+ *         --gmcnutt
+ */
+#ifndef __ASM_PROC_DOMAIN_H
+#define __ASM_PROC_DOMAIN_H
+
+/*
+ * Domain numbers
+ *
+ *  DOMAIN_IO     - domain 2 includes all IO only
+ *  DOMAIN_KERNEL - domain 1 includes all kernel memory only
+ *  DOMAIN_USER   - domain 0 includes all user memory only
+ */
+#define DOMAIN_USER	0
+#define DOMAIN_KERNEL	1
+#define DOMAIN_TABLE	1
+#define DOMAIN_IO	2
+
+/*
+ * Domain types
+ */
+#define DOMAIN_NOACCESS	0
+#define DOMAIN_CLIENT	1
+#define DOMAIN_MANAGER	3
+
+#define domain_val(dom,type)	((type) << 2*(dom))
+
+#define modify_domain(dom,type)				\
+	do {						\
+	unsigned int domain = current->thread.domain;	\
+	domain &= ~domain_val(dom, DOMAIN_MANAGER);	\
+	domain |= domain_val(dom, type);		\
+	current->thread.domain = domain;		\
+	} while (0)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/proc-armv/elf.h linux-2.4.29-uc1/include/asm-armnommu/proc-armv/elf.h
--- linux-2.4.29/include/asm-armnommu/proc-armv/elf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armv/elf.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,22 @@
+/*
+ * ELF definitions for 32-bit CPUs
+ */
+
+#define ELF_EXEC_PAGESIZE	4096
+
+#ifdef __KERNEL__
+
+/* 32-bit code is always OK.  Some cpus can do 26-bit, some can't.  */
+#define ELF_PROC_OK(x)				\
+	((! ((x)->e_flags & EF_ARM_APCS26))	\
+	|| (elf_hwcap & HWCAP_26BIT))
+
+/* Old NetWinder binaries were compiled in such a way that the iBCS
+   heuristic always trips on them.  Until these binaries become uncommon
+   enough not to care, don't trust the `ibcs' flag here.  In any case
+   there is no other ELF system currently supported by iBCS.
+   @@ Could print a warning message to encourage users to upgrade.  */
+#define SET_PERSONALITY(ex,ibcs2) \
+	set_personality(((ex).e_flags&EF_ARM_APCS26 ?PER_LINUX :PER_LINUX_32BIT))
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/proc-armv/io.h linux-2.4.29-uc1/include/asm-armnommu/proc-armv/io.h
--- linux-2.4.29/include/asm-armnommu/proc-armv/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armv/io.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ * linux/include/asm-arm/proc-armv/io.h
+ */
+
+/*
+ * The caches on some architectures aren't dma-coherent and have need to
+ * handle this in software.  There are two types of operations that
+ * can be applied to dma buffers.
+ *
+ *  - dma_cache_wback_inv(start, size) makes caches and RAM coherent by
+ *    writing the content of the caches back to memory, if necessary.
+ *    The function also invalidates the affected part of the caches as
+ *    necessary before DMA transfers from outside to memory.
+ *  - dma_cache_inv(start, size) invalidates the affected parts of the
+ *    caches.  Dirty lines of the caches may be written back or simply
+ *    be discarded.  This operation is necessary before dma operations
+ *    to the memory.
+ *  - dma_cache_wback(start, size) writes back any dirty lines but does
+ *    not invalidate the cache.  This can be used before DMA reads from
+ *    memory,
+ */
+
+#include <asm/proc-fns.h>
+
+#define dma_cache_inv(start, size)				\
+	do { cpu_cache_purge_area((unsigned long)(start),	\
+		((unsigned long)(start)+(size))); } while (0)
+
+#define dma_cache_wback(start, size)				\
+	do { cpu_cache_wback_area((unsigned long)(start),	\
+		((unsigned long)(start)+(size))); } while (0)
+
+#define dma_cache_wback_inv(start, size)			\
+	do { cpu_flush_cache_area((unsigned long)(start),	\
+		((unsigned long)(start)+(size)), 0); } while (0)
diff -urN linux-2.4.29/include/asm-armnommu/proc-armv/locks.h linux-2.4.29-uc1/include/asm-armnommu/proc-armv/locks.h
--- linux-2.4.29/include/asm-armnommu/proc-armv/locks.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armv/locks.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,139 @@
+/*
+ *  linux/include/asm-arm/proc-armv/locks.h
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Interrupt safe locking assembler. 
+ */
+#ifndef __ASM_PROC_LOCKS_H
+#define __ASM_PROC_LOCKS_H
+
+#define __down_op(ptr,fail)			\
+	({					\
+	__asm__ __volatile__(			\
+	"@ down_op\n"				\
+"	mrs	ip, cpsr\n"			\
+"	orr	lr, ip, #128\n"			\
+"	msr	cpsr_c, lr\n"			\
+"	ldr	lr, [%0]\n"			\
+"	subs	lr, lr, %1\n"			\
+"	str	lr, [%0]\n"			\
+"	msr	cpsr_c, ip\n"			\
+"	movmi	ip, %0\n"			\
+"	blmi	" SYMBOL_NAME_STR(fail)		\
+	:					\
+	: "r" (ptr), "I" (1)			\
+	: "ip", "lr", "cc");			\
+	})
+
+#define __down_op_ret(ptr,fail)			\
+	({					\
+		unsigned int ret;		\
+	__asm__ __volatile__(			\
+	"@ down_op_ret\n"			\
+"	mrs	ip, cpsr\n"			\
+"	orr	lr, ip, #128\n"			\
+"	msr	cpsr_c, lr\n"			\
+"	ldr	lr, [%1]\n"			\
+"	subs	lr, lr, %2\n"			\
+"	str	lr, [%1]\n"			\
+"	msr	cpsr_c, ip\n"			\
+"	movmi	ip, %1\n"			\
+"	movpl	ip, #0\n"			\
+"	blmi	" SYMBOL_NAME_STR(fail) "\n"	\
+"	mov	%0, ip"				\
+	: "=&r" (ret)				\
+	: "r" (ptr), "I" (1)			\
+	: "ip", "lr", "cc");			\
+	ret;					\
+	})
+
+#define __up_op(ptr,wake)			\
+	({					\
+	__asm__ __volatile__(			\
+	"@ up_op\n"				\
+"	mrs	ip, cpsr\n"			\
+"	orr	lr, ip, #128\n"			\
+"	msr	cpsr_c, lr\n"			\
+"	ldr	lr, [%0]\n"			\
+"	adds	lr, lr, %1\n"			\
+"	str	lr, [%0]\n"			\
+"	msr	cpsr_c, ip\n"			\
+"	movle	ip, %0\n"			\
+"	blle	" SYMBOL_NAME_STR(wake)		\
+	:					\
+	: "r" (ptr), "I" (1)			\
+	: "ip", "lr", "cc");			\
+	})
+
+/*
+ * The value 0x01000000 supports up to 128 processors and
+ * lots of processes.  BIAS must be chosen such that sub'ing
+ * BIAS once per CPU will result in the long remaining
+ * negative.
+ */
+#define RW_LOCK_BIAS      0x01000000
+#define RW_LOCK_BIAS_STR "0x01000000"
+
+#define __down_op_write(ptr,fail)		\
+	({					\
+	__asm__ __volatile__(			\
+	"@ down_op_write\n"			\
+"	mrs	ip, cpsr\n"			\
+"	orr	lr, ip, #128\n"			\
+"	msr	cpsr_c, lr\n"			\
+"	ldr	lr, [%0]\n"			\
+"	subs	lr, lr, %1\n"			\
+"	str	lr, [%0]\n"			\
+"	msr	cpsr_c, ip\n"			\
+"	movne	ip, %0\n"			\
+"	blne	" SYMBOL_NAME_STR(fail)		\
+	:					\
+	: "r" (ptr), "I" (RW_LOCK_BIAS)		\
+	: "ip", "lr", "cc");			\
+	})
+
+#define __up_op_write(ptr,wake)			\
+	({					\
+	__asm__ __volatile__(			\
+	"@ up_op_read\n"			\
+"	mrs	ip, cpsr\n"			\
+"	orr	lr, ip, #128\n"			\
+"	msr	cpsr_c, lr\n"			\
+"	ldr	lr, [%0]\n"			\
+"	adds	lr, lr, %1\n"			\
+"	str	lr, [%0]\n"			\
+"	msr	cpsr_c, ip\n"			\
+"	movcs	ip, %0\n"			\
+"	blcs	" SYMBOL_NAME_STR(wake)		\
+	:					\
+	: "r" (ptr), "I" (RW_LOCK_BIAS)		\
+	: "ip", "lr", "cc");			\
+	})
+
+#define __down_op_read(ptr,fail)		\
+	__down_op(ptr, fail)
+
+#define __up_op_read(ptr,wake)			\
+	({					\
+	__asm__ __volatile__(			\
+	"@ up_op_read\n"			\
+"	mrs	ip, cpsr\n"			\
+"	orr	lr, ip, #128\n"			\
+"	msr	cpsr_c, lr\n"			\
+"	ldr	lr, [%0]\n"			\
+"	adds	lr, lr, %1\n"			\
+"	str	lr, [%0]\n"			\
+"	msr	cpsr_c, ip\n"			\
+"	moveq	ip, %0\n"			\
+"	bleq	" SYMBOL_NAME_STR(wake)		\
+	:					\
+	: "r" (ptr), "I" (1)			\
+	: "ip", "lr", "cc");			\
+	})
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/proc-armv/page.h linux-2.4.29-uc1/include/asm-armnommu/proc-armv/page.h
--- linux-2.4.29/include/asm-armnommu/proc-armv/page.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armv/page.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,18 @@
+/*
+ *  linux/include/asm-arm/proc-armv/page.h
+ *
+ *  Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_PROC_PAGE_H
+#define __ASM_PROC_PAGE_H
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT	12
+
+#define EXEC_PAGESIZE   4096
+
+#endif /* __ASM_PROC_PAGE_H */
diff -urN linux-2.4.29/include/asm-armnommu/proc-armv/pgalloc.h linux-2.4.29-uc1/include/asm-armnommu/proc-armv/pgalloc.h
--- linux-2.4.29/include/asm-armnommu/proc-armv/pgalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armv/pgalloc.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,58 @@
+/*
+ *  linux/include/asm-arm/proc-armv/pgalloc.h
+ *
+ *  Copyright (C) 2001 Russell King
+ *
+ * Page table allocation/freeing primitives for 32-bit ARM processors.
+ */
+
+/* unfortunately, this includes linux/mm.h and the rest of the universe. */
+#include <linux/slab.h>
+
+extern kmem_cache_t *pte_cache;
+
+/*
+ * Allocate one PTE table.
+ *
+ * Note that we keep the processor copy of the PTE entries separate
+ * from the Linux copy.  The processor copies are offset by -PTRS_PER_PTE
+ * words from the Linux copy.
+ */
+static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+	pte_t *pte;
+
+	pte = kmem_cache_alloc(pte_cache, GFP_KERNEL);
+	if (pte)
+		pte += PTRS_PER_PTE;
+	return pte;
+}
+
+/*
+ * Free one PTE table.
+ */
+static inline void pte_free_slow(pte_t *pte)
+{
+	if (pte) {
+		pte -= PTRS_PER_PTE;
+		kmem_cache_free(pte_cache, pte);
+	}
+}
+
+/*
+ * Populate the pmdp entry with a pointer to the pte.  This pmd is part
+ * of the mm address space.
+ *
+ * If 'mm' is the init tasks mm, then we are doing a vmalloc, and we
+ * need to set stuff up correctly for it.
+ */
+#define pmd_populate(mm,pmdp,pte)			\
+	do {						\
+		unsigned long __prot;			\
+		if (mm == &init_mm)			\
+			__prot = _PAGE_KERNEL_TABLE;	\
+		else					\
+			__prot = _PAGE_USER_TABLE;	\
+		set_pmd(pmdp, __mk_pmd(pte, __prot));	\
+	} while (0)
+
diff -urN linux-2.4.29/include/asm-armnommu/proc-armv/pgtable.h linux-2.4.29-uc1/include/asm-armnommu/proc-armv/pgtable.h
--- linux-2.4.29/include/asm-armnommu/proc-armv/pgtable.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armv/pgtable.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,175 @@
+/*
+ *  linux/include/asm-arm/proc-armv/pgtable.h
+ *
+ *  Copyright (C) 1995-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  12-Jan-1997	RMK	Altered flushing routines to use function pointers
+ *			now possible to combine ARM6, ARM7 and StrongARM versions.
+ *  17-Apr-1999	RMK	Now pass an area size to clean_cache_area and
+ *			flush_icache_area.
+ */
+#ifndef __ASM_PROC_PGTABLE_H
+#define __ASM_PROC_PGTABLE_H
+
+#include <asm/proc/domain.h>
+#include <asm/arch/vmalloc.h>
+
+/*
+ * entries per page directory level: they are two-level, so
+ * we don't really have any PMD directory.
+ */
+#define PTRS_PER_PTE		256
+#define PTRS_PER_PMD		1
+#define PTRS_PER_PGD		4096
+
+/****************
+* PMD functions *
+****************/
+
+/* PMD types (actually level 1 descriptor) */
+#define PMD_TYPE_MASK		0x0003
+#define PMD_TYPE_FAULT		0x0000
+#define PMD_TYPE_TABLE		0x0001
+#define PMD_TYPE_SECT		0x0002
+#define PMD_UPDATABLE		0x0010
+#define PMD_SECT_CACHEABLE	0x0008
+#define PMD_SECT_BUFFERABLE	0x0004
+#define PMD_SECT_AP_WRITE	0x0400
+#define PMD_SECT_AP_READ	0x0800
+#define PMD_DOMAIN(x)		((x) << 5)
+
+#define _PAGE_USER_TABLE	(PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_USER))
+#define _PAGE_KERNEL_TABLE	(PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_KERNEL))
+
+#define pmd_bad(pmd)		(pmd_val(pmd) & 2)
+#define set_pmd(pmdp,pmd)	cpu_set_pmd(pmdp,pmd)
+
+static inline pmd_t __mk_pmd(pte_t *ptep, unsigned long prot)
+{
+#ifndef CONFIG_UCLINUX
+	unsigned long pte_ptr = (unsigned long)ptep;
+	pmd_t pmd;
+
+	pte_ptr -= PTRS_PER_PTE * sizeof(void *);
+
+	/*
+	 * The pmd must be loaded with the physical
+	 * address of the PTE table
+	 */
+	pmd_val(pmd) = __virt_to_phys(pte_ptr) | prot;
+
+	return pmd;
+#else
+	pmd_t pmd;
+	return pmd;
+#endif
+}
+
+static inline unsigned long pmd_page(pmd_t pmd)
+{
+#ifndef CONFIG_UCLINUX
+	unsigned long ptr;
+
+	ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1);
+
+	ptr += PTRS_PER_PTE * sizeof(void *);
+
+	return __phys_to_virt(ptr);
+#else
+	return 0;
+#endif
+}
+
+/****************
+* PTE functions *
+****************/
+
+/* PTE types (actually level 2 descriptor) */
+#define PTE_TYPE_MASK		0x0003
+#define PTE_TYPE_FAULT		0x0000
+#define PTE_TYPE_LARGE		0x0001
+#define PTE_TYPE_SMALL		0x0002
+#define PTE_AP_READ		0x0aa0
+#define PTE_AP_WRITE		0x0550
+#define PTE_CACHEABLE		0x0008
+#define PTE_BUFFERABLE		0x0004
+
+#define set_pte(ptep, pte)	cpu_set_pte(ptep,pte)
+
+/* We now keep two sets of ptes - the physical and the linux version.
+ * This gives us many advantages, and allows us greater flexibility.
+ *
+ * The Linux pte's contain:
+ *  bit   meaning
+ *   0    page present
+ *   1    young
+ *   2    bufferable	- matches physical pte
+ *   3    cacheable	- matches physical pte
+ *   4    user
+ *   5    write
+ *   6    execute
+ *   7    dirty
+ *  8-11  unused
+ *  12-31 virtual page address
+ *
+ * These are stored at the pte pointer; the physical PTE is at -1024bytes
+ */
+#define L_PTE_PRESENT		(1 << 0)
+#define L_PTE_YOUNG		(1 << 1)
+#define L_PTE_BUFFERABLE	(1 << 2)
+#define L_PTE_CACHEABLE		(1 << 3)
+#define L_PTE_USER		(1 << 4)
+#define L_PTE_WRITE		(1 << 5)
+#define L_PTE_EXEC		(1 << 6)
+#define L_PTE_DIRTY		(1 << 7)
+
+/*
+ * The following macros handle the cache and bufferable bits...
+ */
+#define _L_PTE_DEFAULT	L_PTE_PRESENT | L_PTE_YOUNG
+#define _L_PTE_READ	L_PTE_USER | L_PTE_CACHEABLE | L_PTE_BUFFERABLE
+
+#define PAGE_NONE       __pgprot(_L_PTE_DEFAULT)
+#define PAGE_COPY       __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
+#define PAGE_SHARED     __pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_WRITE)
+#define PAGE_READONLY   __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
+#define PAGE_KERNEL     __pgprot(_L_PTE_DEFAULT | L_PTE_CACHEABLE | L_PTE_BUFFERABLE | L_PTE_DIRTY | L_PTE_WRITE)
+
+#define _PAGE_CHG_MASK	(PAGE_MASK | L_PTE_DIRTY | L_PTE_YOUNG)
+
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+#define pte_present(pte)		(pte_val(pte) & L_PTE_PRESENT)
+#define pte_read(pte)			(pte_val(pte) & L_PTE_USER)
+#define pte_write(pte)			(pte_val(pte) & L_PTE_WRITE)
+#define pte_exec(pte)			(pte_val(pte) & L_PTE_EXEC)
+#define pte_dirty(pte)			(pte_val(pte) & L_PTE_DIRTY)
+#define pte_young(pte)			(pte_val(pte) & L_PTE_YOUNG)
+
+#define PTE_BIT_FUNC(fn,op)			\
+extern inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
+
+/*PTE_BIT_FUNC(rdprotect, &= ~L_PTE_USER);*/
+/*PTE_BIT_FUNC(mkread,    |= L_PTE_USER);*/
+PTE_BIT_FUNC(wrprotect, &= ~L_PTE_WRITE);
+PTE_BIT_FUNC(mkwrite,   |= L_PTE_WRITE);
+PTE_BIT_FUNC(exprotect, &= ~L_PTE_EXEC);
+PTE_BIT_FUNC(mkexec,    |= L_PTE_EXEC);
+PTE_BIT_FUNC(mkclean,   &= ~L_PTE_DIRTY);
+PTE_BIT_FUNC(mkdirty,   |= L_PTE_DIRTY);
+PTE_BIT_FUNC(mkold,     &= ~L_PTE_YOUNG);
+PTE_BIT_FUNC(mkyoung,   |= L_PTE_YOUNG);
+
+/*
+ * Mark the prot value as uncacheable and unbufferable.
+ */
+#define pgprot_noncached(prot)	__pgprot(pgprot_val(prot) & ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE))
+
+#endif /* __ASM_PROC_PGTABLE_H */
diff -urN linux-2.4.29/include/asm-armnommu/proc-armv/processor.h linux-2.4.29-uc1/include/asm-armnommu/proc-armv/processor.h
--- linux-2.4.29/include/asm-armnommu/proc-armv/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armv/processor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,75 @@
+/*
+ *  linux/include/asm-arm/proc-armv/processor.h
+ *
+ *  Copyright (C) 1996-1999 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Changelog:
+ *   20-09-1996	RMK	Created
+ *   26-09-1996	RMK	Added 'EXTRA_THREAD_STRUCT*'
+ *   28-09-1996	RMK	Moved start_thread into the processor dependencies
+ *   09-09-1998	PJB	Delete redundant `wp_works_ok'
+ *   30-05-1999	PJB	Save sl across context switches
+ *   31-07-1999	RMK	Added 'domain' stuff
+ */
+#ifndef __ASM_PROC_PROCESSOR_H
+#define __ASM_PROC_PROCESSOR_H
+
+#include <asm/proc/domain.h>
+
+#define KERNEL_STACK_SIZE	PAGE_SIZE
+
+struct context_save_struct {
+	unsigned long cpsr;
+	unsigned long r4;
+	unsigned long r5;
+	unsigned long r6;
+	unsigned long r7;
+	unsigned long r8;
+	unsigned long r9;
+	unsigned long sl;
+	unsigned long fp;
+	unsigned long pc;
+};
+
+#define INIT_CSS (struct context_save_struct){ SVC_MODE, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+
+#define EXTRA_THREAD_STRUCT						\
+	unsigned int	domain;
+
+#define EXTRA_THREAD_STRUCT_INIT					\
+	domain:	  domain_val(DOMAIN_USER, DOMAIN_CLIENT) |		\
+		  domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) |		\
+		  domain_val(DOMAIN_IO, DOMAIN_CLIENT)
+
+#define start_thread(regs,pc,sp)					 \
+({									 \
+	unsigned long *stack = (unsigned long *)sp;			 \
+	set_fs(USER_DS);						 \
+	memzero(regs->uregs, sizeof(regs->uregs));			 \
+	if (current->personality & ADDR_LIMIT_32BIT)			 \
+		regs->ARM_cpsr = USR_MODE;				 \
+	else								 \
+		regs->ARM_cpsr = USR26_MODE;				 \
+	regs->ARM_pc = pc;		/* pc */			 \
+	regs->ARM_sp = sp;		/* sp */			 \
+	regs->ARM_r2 = stack[2];	/* r2 (envp) */			 \
+	regs->ARM_r1 = stack[1];	/* r1 (argv) */			 \
+	regs->ARM_r0 = stack[0];	/* r0 (argc) */			 \
+	regs->ARM_r10 = current->mm->start_data; /* data segment base */ \
+})
+
+#define KSTK_EIP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)))[1021])
+#define KSTK_ESP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)))[1019])
+
+/* Allocation and freeing of basic task resources. */
+/*
+ * NOTE! The task struct and the stack go together
+ */
+#define ll_alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
+#define ll_free_task_struct(p) free_pages((unsigned long)(p),1)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/proc-armv/ptrace.h linux-2.4.29-uc1/include/asm-armnommu/proc-armv/ptrace.h
--- linux-2.4.29/include/asm-armnommu/proc-armv/ptrace.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armv/ptrace.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,110 @@
+/*
+ *  linux/include/asm-arm/proc-armv/ptrace.h
+ *
+ *  Copyright (C) 1996-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_PROC_PTRACE_H
+#define __ASM_PROC_PTRACE_H
+
+#include <linux/config.h>
+
+#define USR26_MODE	0x00
+#define FIQ26_MODE	0x01
+#define IRQ26_MODE	0x02
+#define SVC26_MODE	0x03
+#define USR_MODE	0x10
+#define FIQ_MODE	0x11
+#define IRQ_MODE	0x12
+#define SVC_MODE	0x13
+#define ABT_MODE	0x17
+#define UND_MODE	0x1b
+#define SYSTEM_MODE	0x1f
+#define MODE_MASK	0x1f
+#define T_BIT		0x20
+#define F_BIT		0x40
+#define I_BIT		0x80
+#define CC_V_BIT	(1 << 28)
+#define CC_C_BIT	(1 << 29)
+#define CC_Z_BIT	(1 << 30)
+#define CC_N_BIT	(1 << 31)
+#define PCMASK		0
+
+#ifndef __ASSEMBLY__
+
+/* this struct defines the way the registers are stored on the
+   stack during a system call. */
+
+struct pt_regs {
+	long uregs[18];
+};
+
+#define ARM_cpsr	uregs[16]
+#define ARM_pc		uregs[15]
+#define ARM_lr		uregs[14]
+#define ARM_sp		uregs[13]
+#define ARM_ip		uregs[12]
+#define ARM_fp		uregs[11]
+#define ARM_r10		uregs[10]
+#define ARM_r9		uregs[9]
+#define ARM_r8		uregs[8]
+#define ARM_r7		uregs[7]
+#define ARM_r6		uregs[6]
+#define ARM_r5		uregs[5]
+#define ARM_r4		uregs[4]
+#define ARM_r3		uregs[3]
+#define ARM_r2		uregs[2]
+#define ARM_r1		uregs[1]
+#define ARM_r0		uregs[0]
+#define ARM_ORIG_r0	uregs[17]
+
+#ifdef __KERNEL__
+
+#define user_mode(regs)	\
+	(((regs)->ARM_cpsr & 0xf) == 0)
+
+#ifdef CONFIG_ARM_THUMB
+#define thumb_mode(regs) \
+	(((regs)->ARM_cpsr & T_BIT))
+#else
+#define thumb_mode(regs) (0)
+#endif
+
+#define processor_mode(regs) \
+	((regs)->ARM_cpsr & MODE_MASK)
+
+#define interrupts_enabled(regs) \
+	(!((regs)->ARM_cpsr & I_BIT))
+
+#define fast_interrupts_enabled(regs) \
+	(!((regs)->ARM_cpsr & F_BIT))
+
+#define condition_codes(regs) \
+	((regs)->ARM_cpsr & (CC_V_BIT|CC_C_BIT|CC_Z_BIT|CC_N_BIT))
+	
+/* Are the current registers suitable for user mode?
+ * (used to maintain security in signal handlers)
+ */
+static inline int valid_user_regs(struct pt_regs *regs)
+{
+	if ((regs->ARM_cpsr & 0xf) == 0 &&
+	    (regs->ARM_cpsr & (F_BIT|I_BIT)) == 0)
+		return 1;
+
+	/*
+	 * Force CPSR to something logical...
+	 */
+	regs->ARM_cpsr &= (CC_V_BIT|CC_C_BIT|CC_Z_BIT|CC_N_BIT|0x10);
+
+	return 0;
+}
+
+#endif	/* __KERNEL__ */
+
+#endif	/* __ASSEMBLY__ */
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/proc-armv/shmparam.h linux-2.4.29-uc1/include/asm-armnommu/proc-armv/shmparam.h
--- linux-2.4.29/include/asm-armnommu/proc-armv/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armv/shmparam.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,20 @@
+/*
+ *  linux/include/asm-arm/proc-armv/shmparam.h
+ *
+ *  Copyright (C) 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  definitions for the shared process memory on ARM v3 or v4
+ *  processors
+ */
+#ifndef __ASM_PROC_SHMPARAM_H
+#define __ASM_PROC_SHMPARAM_H
+
+#ifndef SHMMAX
+#define SHMMAX		0x01000000
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/proc-armv/system.h linux-2.4.29-uc1/include/asm-armnommu/proc-armv/system.h
--- linux-2.4.29/include/asm-armnommu/proc-armv/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armv/system.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,216 @@
+/*
+ *  linux/include/asm-arm/proc-armv/system.h
+ *
+ *  Copyright (C) 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_PROC_SYSTEM_H
+#define __ASM_PROC_SYSTEM_H
+
+#include <linux/config.h>
+
+#define set_cr(x)					\
+	__asm__ __volatile__(				\
+	"mcr	p15, 0, %0, c1, c0	@ set CR"	\
+	: : "r" (x))
+
+#define CR_M	(1 << 0)	/* MMU enable				*/
+#define CR_A	(1 << 1)	/* Alignment abort enable		*/
+#define CR_C	(1 << 2)	/* Dcache enable			*/
+#define CR_W	(1 << 3)	/* Write buffer enable			*/
+#define CR_P	(1 << 4)	/* 32-bit exception handler		*/
+#define CR_D	(1 << 5)	/* 32-bit data address range		*/
+#define CR_L	(1 << 6)	/* Implementation defined		*/
+#define CD_B	(1 << 7)	/* Big endian				*/
+#define CR_S	(1 << 8)	/* System MMU protection		*/
+#define CD_R	(1 << 9)	/* ROM MMU protection			*/
+#define CR_F	(1 << 10)	/* Implementation defined		*/
+#define CR_Z	(1 << 11)	/* Implementation defined		*/
+#define CR_I	(1 << 12)	/* Icache enable			*/
+#define CR_V	(1 << 13)	/* Vectors relocated to 0xffff0000	*/
+#define CR_RR	(1 << 14)	/* Round Robin cache replacement	*/
+
+extern unsigned long cr_no_alignment;	/* defined in entry-armv.S */
+extern unsigned long cr_alignment;	/* defined in entry-armv.S */
+
+#ifdef __ARM_ARCH_4__
+#define vectors_base()	((cr_alignment & CR_V) ? 0xffff0000 : 0)
+#else
+#define vectors_base()	(0)
+#endif
+
+/*
+ * A couple of speedups for the ARM
+ */
+
+/*
+ * Save the current interrupt enable state & disable IRQs
+ */
+#define __save_flags_cli(x)					\
+	({							\
+		unsigned long temp;				\
+	__asm__ __volatile__(					\
+	"mrs	%0, cpsr		@ save_flags_cli\n"	\
+"	orr	%1, %0, #128\n"					\
+"	msr	cpsr_c, %1"					\
+	: "=r" (x), "=r" (temp)					\
+	:							\
+	: "memory");						\
+	})
+
+/*
+ * Save the current interrupt enable state & enable IRQs
+ */
+#define __save_flags_sti(x)					\
+	({							\
+		unsigned long temp;				\
+	__asm__ __volatile__(					\
+	"mrs	%0, cpsr		@ save_flags_sti\n"	\
+"	bic	%1, %0, #128\n"					\
+"	msr	cpsr_c, %1"					\
+	: "=r" (x), "=r" (temp)					\
+	:							\
+	: "memory");						\
+	})
+	
+/*
+ * Enable IRQs
+ */
+#define __sti()							\
+	({							\
+		unsigned long temp;				\
+	__asm__ __volatile__(					\
+	"mrs	%0, cpsr		@ sti\n"		\
+"	bic	%0, %0, #128\n"					\
+"	msr	cpsr_c, %0"					\
+	: "=r" (temp)						\
+	:							\
+	: "memory");						\
+	})
+
+/*
+ * Disable IRQs
+ */
+#define __cli()							\
+	({							\
+		unsigned long temp;				\
+	__asm__ __volatile__(					\
+	"mrs	%0, cpsr		@ cli\n"		\
+"	orr	%0, %0, #128\n"					\
+"	msr	cpsr_c, %0"					\
+	: "=r" (temp)						\
+	:							\
+	: "memory");						\
+	})
+
+/*
+ * Enable FIQs
+ */
+#define __stf()							\
+	({							\
+		unsigned long temp;				\
+	__asm__ __volatile__(					\
+	"mrs	%0, cpsr		@ stf\n"		\
+"	bic	%0, %0, #64\n"					\
+"	msr	cpsr_c, %0"					\
+	: "=r" (temp)						\
+	:							\
+	: "memory");						\
+	})
+
+/*
+ * Disable FIQs
+ */
+#define __clf()							\
+	({							\
+		unsigned long temp;				\
+	__asm__ __volatile__(					\
+	"mrs	%0, cpsr		@ clf\n"		\
+"	orr	%0, %0, #64\n"					\
+"	msr	cpsr_c, %0"					\
+	: "=r" (temp)						\
+	:							\
+	: "memory");						\
+	})
+
+/*
+ * save current IRQ & FIQ state
+ */
+#define __save_flags(x)						\
+	__asm__ __volatile__(					\
+	"mrs	%0, cpsr		@ save_flags\n"		\
+	  : "=r" (x)						\
+	  :							\
+	  : "memory")
+
+/*
+ * restore saved IRQ & FIQ state
+ */
+#define __restore_flags(x)					\
+	__asm__ __volatile__(					\
+	"msr	cpsr_c, %0		@ restore_flags\n"	\
+	:							\
+	: "r" (x)						\
+	: "memory")
+
+#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
+/*
+ * On the StrongARM, "swp" is terminally broken since it bypasses the
+ * cache totally.  This means that the cache becomes inconsistent, and,
+ * since we use normal loads/stores as well, this is really bad.
+ * Typically, this causes oopsen in filp_close, but could have other,
+ * more disasterous effects.  There are two work-arounds:
+ *  1. Disable interrupts and emulate the atomic swap
+ *  2. Clean the cache, perform atomic swap, flush the cache
+ *
+ * We choose (1) since its the "easiest" to achieve here and is not
+ * dependent on the processor type.
+ */
+#define swp_is_buggy
+#endif
+
+extern __inline__ unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
+{
+	extern void __bad_xchg(volatile void *, int);
+	unsigned long ret;
+#ifdef swp_is_buggy
+	unsigned long flags;
+#endif
+
+	switch (size) {
+#ifdef swp_is_buggy
+		case 1:
+			__save_flags_cli(flags);
+			ret = *(volatile unsigned char *)ptr;
+			*(volatile unsigned char *)ptr = x;
+			__restore_flags(flags);
+			break;
+
+		case 4:
+			__save_flags_cli(flags);
+			ret = *(volatile unsigned long *)ptr;
+			*(volatile unsigned long *)ptr = x;
+			__restore_flags(flags);
+			break;
+#else
+		case 1:	__asm__ __volatile__ ("swpb %0, %1, [%2]"
+					: "=r" (ret)
+					: "r" (x), "r" (ptr)
+					: "memory");
+			break;
+		case 4:	__asm__ __volatile__ ("swp %0, %1, [%2]"
+					: "=r" (ret)
+					: "r" (x), "r" (ptr)
+					: "memory");
+			break;
+#endif
+		default: __bad_xchg(ptr, size);
+	}
+
+	return ret;
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/proc-armv/uaccess.h linux-2.4.29-uc1/include/asm-armnommu/proc-armv/uaccess.h
--- linux-2.4.29/include/asm-armnommu/proc-armv/uaccess.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armv/uaccess.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,182 @@
+/*
+ *  linux/include/asm-arm/proc-armv/uaccess.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_PROC_UACCESS_H__
+#define __ASM_PROC_UACCESS_H__
+
+#include <asm/arch/memory.h>
+#include <asm/proc/domain.h>
+
+/*
+ * Note that this is actually 0x1,0000,0000
+ */
+#define KERNEL_DS	0x00000000
+/*
+ * REVISIT_gjm
+ * Be careful here for the DSC21.
+ */
+#define USER_DS		PAGE_OFFSET
+
+/*
+ * m68knommu defines this to be empty.
+ * --gmcnutt
+ */
+extern __inline__ void set_fs (mm_segment_t fs)
+{
+}
+
+/*
+ * REVISIT_gjm -- __rnage_ok & __addr_ok
+ *         Not sure if we might really want to do these checks in
+ *         uClinux. For now I'm assuming they'll always succeed.
+ */
+#include <linux/config.h>
+#ifdef CONFIG_UCLINUX
+#define __range_ok(addr,size) 0
+#define __addr_ok(addr) 1
+
+#else
+/* We use 33-bit arithmetic here... */
+#define __range_ok(addr,size) ({ \
+	unsigned long flag, sum; \
+	__asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \
+		: "=&r" (flag), "=&r" (sum) \
+		: "r" (addr), "Ir" (size), "0" (current->addr_limit) \
+		: "cc"); \
+	flag; })
+
+#define __addr_ok(addr) ({ \
+	unsigned long flag; \
+	__asm__("cmp %2, %0; movlo %0, #0" \
+		: "=&r" (flag) \
+		: "0" (current->addr_limit), "r" (addr) \
+		: "cc"); \
+	(flag == 0); })
+#endif /* CONFIG_UCLINUX */
+
+#define __put_user_asm_byte(x,addr,err)				\
+	__asm__ __volatile__(					\
+	"1:	strbt	%1,[%2],#0\n"				\
+	"2:\n"							\
+	"	.section .fixup,\"ax\"\n"			\
+	"	.align	2\n"					\
+	"3:	mov	%0, %3\n"				\
+	"	b	2b\n"					\
+	"	.previous\n"					\
+	"	.section __ex_table,\"a\"\n"			\
+	"	.align	3\n"					\
+	"	.long	1b, 3b\n"				\
+	"	.previous"					\
+	: "=r" (err)						\
+	: "r" (x), "r" (addr), "i" (-EFAULT), "0" (err))
+
+#ifdef __ARMEB__
+#define __put_user_asm_half(x,addr,err)				\
+({								\
+	unsigned long __temp = (unsigned long)(x);		\
+	__put_user_asm_byte(__temp, (int)(addr) + 1, err);	\
+	__put_user_asm_byte(__temp >> 8, addr, err);		\
+})
+#else
+#define __put_user_asm_half(x,addr,err)				\
+({								\
+	unsigned long __temp = (unsigned long)(x);		\
+	__put_user_asm_byte(__temp, addr, err);			\
+	__put_user_asm_byte(__temp >> 8, (int)(addr) + 1, err);	\
+})
+#endif
+
+#define __put_user_asm_word(x,addr,err)				\
+	__asm__ __volatile__(					\
+	"1:	strt	%1,[%2],#0\n"				\
+	"2:\n"							\
+	"	.section .fixup,\"ax\"\n"			\
+	"	.align	2\n"					\
+	"3:	mov	%0, %3\n"				\
+	"	b	2b\n"					\
+	"	.previous\n"					\
+	"	.section __ex_table,\"a\"\n"			\
+	"	.align	3\n"					\
+	"	.long	1b, 3b\n"				\
+	"	.previous"					\
+	: "=r" (err)						\
+	: "r" (x), "r" (addr), "i" (-EFAULT), "0" (err))
+
+#define __get_user_asm_byte(x,addr,err)				\
+	__asm__ __volatile__(					\
+	"1:	ldrbt	%1,[%2],#0\n"				\
+	"2:\n"							\
+	"	.section .fixup,\"ax\"\n"			\
+	"	.align	2\n"					\
+	"3:	mov	%0, %3\n"				\
+	"	mov	%1, #0\n"				\
+	"	b	2b\n"					\
+	"	.previous\n"					\
+	"	.section __ex_table,\"a\"\n"			\
+	"	.align	3\n"					\
+	"	.long	1b, 3b\n"				\
+	"	.previous"					\
+	: "=r" (err), "=&r" (x)					\
+	: "r" (addr), "i" (-EFAULT), "0" (err))
+	
+#ifdef __ARMEB__
+#define __get_user_asm_half(x,addr,err)				\
+({								\
+	unsigned long __b1, __b2;				\
+	__get_user_asm_byte(__b1, addr, err);			\
+	__get_user_asm_byte(__b2, (int)(addr) + 1, err);	\
+	(x) = (__b1 << 8) | __b2;				\
+})
+#else
+#define __get_user_asm_half(x,addr,err)				\
+({								\
+	unsigned long __b1, __b2;				\
+	__get_user_asm_byte(__b1, addr, err);			\
+	__get_user_asm_byte(__b2, (int)(addr) + 1, err);	\
+	(x) = __b1 | (__b2 << 8);				\
+})
+#endif
+
+
+#define __get_user_asm_word(x,addr,err)				\
+	__asm__ __volatile__(					\
+	"1:	ldrt	%1,[%2],#0\n"				\
+	"2:\n"							\
+	"	.section .fixup,\"ax\"\n"			\
+	"	.align	2\n"					\
+	"3:	mov	%0, %3\n"				\
+	"	mov	%1, #0\n"				\
+	"	b	2b\n"					\
+	"	.previous\n"					\
+	"	.section __ex_table,\"a\"\n"			\
+	"	.align	3\n"					\
+	"	.long	1b, 3b\n"				\
+	"	.previous"					\
+	: "=r" (err), "=&r" (x)					\
+	: "r" (addr), "i" (-EFAULT), "0" (err))
+
+extern unsigned long __arch_copy_from_user(void *to, const void *from, unsigned long n);
+#define __do_copy_from_user(to,from,n)				\
+	(n) = __arch_copy_from_user(to,from,n)
+
+extern unsigned long __arch_copy_to_user(void *to, const void *from, unsigned long n);
+#define __do_copy_to_user(to,from,n)				\
+	(n) = __arch_copy_to_user(to,from,n)
+
+extern unsigned long __arch_clear_user(void *addr, unsigned long n);
+#define __do_clear_user(addr,sz)				\
+	(sz) = __arch_clear_user(addr,sz)
+
+extern unsigned long __arch_strncpy_from_user(char *to, const char *from, unsigned long count);
+#define __do_strncpy_from_user(dst,src,count,res)		\
+	(res) = __arch_strncpy_from_user(dst,src,count)
+
+extern unsigned long __arch_strnlen_user(const char *s, long n);
+#define __do_strnlen_user(s,n,res)					\
+	(res) = __arch_strnlen_user(s,n)
+
+#endif /*  __ASM_PROC_UACCESS_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/proc-armv/uncompress.h linux-2.4.29-uc1/include/asm-armnommu/proc-armv/uncompress.h
--- linux-2.4.29/include/asm-armnommu/proc-armv/uncompress.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-armv/uncompress.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ *  linux/include/asm-arm/proc-armv/uncompress.h
+ *
+ *  Copyright (C) 1997 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+static inline void proc_decomp_setup (void)
+{
+#if defined(CONFIG_CPU_WITH_CACHE) && defined(CONFIG_CPU_WITH_MCR_INSTRUCTION)
+	__asm__ __volatile__("
+	mrc	p15, 0, r0, c0, c0
+	eor	r0, r0, #0x44 << 24
+	eor	r0, r0, #0x01 << 16
+	eor	r0, r0, #0xA1 << 8
+	movs	r0, r0, lsr #5
+	mcreq	p15, 0, r0, c7, c5, 0		@ flush I cache
+	mrceq	p15, 0, r0, c1, c0
+	orreq	r0, r0, #1 << 12
+	mcreq	p15, 0, r0, c1, c0		@ enable I cache
+	mov	r0, #0
+	mcreq	p15, 0, r0, c15, c1, 2		@ enable clock switching
+	" : : : "r0", "cc", "memory");
+#endif
+}
diff -urN linux-2.4.29/include/asm-armnommu/processor.h linux-2.4.29-uc1/include/asm-armnommu/processor.h
--- linux-2.4.29/include/asm-armnommu/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/processor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,133 @@
+/*
+ *  linux/include/asm-arm/processor.h
+ *
+ *  Copyright (C) 1995 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_PROCESSOR_H
+#define __ASM_ARM_PROCESSOR_H
+
+#include <linux/linkage.h>
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#define FP_SIZE 35
+
+struct fp_hard_struct {
+	unsigned int save[FP_SIZE];		/* as yet undefined */
+};
+
+struct fp_soft_struct {
+	unsigned int save[FP_SIZE];		/* undefined information */
+};
+
+union fp_state {
+	struct fp_hard_struct	hard;
+	struct fp_soft_struct	soft;
+};
+
+typedef unsigned long mm_segment_t;		/* domain register	*/
+
+#ifdef __KERNEL__
+
+#define EISA_bus 0
+#define MCA_bus 0
+
+#include <asm/atomic.h>
+#include <asm/ptrace.h>
+#include <asm/arch/memory.h>
+#include <asm/proc/processor.h>
+
+struct debug_info {
+	int				nsaved;
+	struct {
+		unsigned long		address;
+		unsigned long		insn;
+	} bp[2];
+};
+
+struct thread_struct {
+	atomic_t			refcount;
+							/* fault info	  */
+	unsigned long			address;
+	unsigned long			trap_no;
+	unsigned long			error_code;
+							/* floating point */
+	union fp_state			fpstate;
+							/* debugging	  */
+	struct debug_info		debug;
+							/* context info	  */
+	struct context_save_struct	*save;
+	EXTRA_THREAD_STRUCT
+};
+
+#define INIT_THREAD  {					\
+	refcount:	ATOMIC_INIT(1),			\
+	EXTRA_THREAD_STRUCT_INIT			\
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+extern __inline__ unsigned long thread_saved_pc(struct thread_struct *t)
+{
+	return t->save ? pc_pointer(t->save->pc) : 0;
+}
+
+extern __inline__ unsigned long get_css_fp(struct thread_struct *t)
+{
+	return t->save ? t->save->fp : 0;
+}
+
+asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
+
+extern __inline__ void init_thread_css(struct context_save_struct *save)
+{
+	*save = INIT_CSS;
+	save->pc |= (unsigned long)ret_from_sys_call;
+}
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/* Free all resources held by a thread. */
+extern void release_thread(struct task_struct *);
+
+/* Copy and release all segment info associated with a VM */
+#define copy_segments(tsk, mm)		do { } while (0)
+#define release_segments(mm)		do { } while (0)
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define THREAD_SIZE	(8192)
+
+extern struct task_struct *alloc_task_struct(void);
+extern void __free_task_struct(struct task_struct *);
+#define get_task_struct(p)	atomic_inc(&(p)->thread.refcount)
+#define free_task_struct(p)					\
+ do {								\
+	if (atomic_dec_and_test(&(p)->thread.refcount))		\
+		__free_task_struct((p));			\
+ } while (0)
+
+#define init_task	(init_task_union.task)
+#define init_stack	(init_task_union.stack)
+
+#define cpu_relax()    barrier()
+
+/*
+ * Create a new kernel thread
+ */
+extern int arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+
+#endif
+
+#endif /* __ASM_ARM_PROCESSOR_H */
diff -urN linux-2.4.29/include/asm-armnommu/proc-fns.h linux-2.4.29-uc1/include/asm-armnommu/proc-fns.h
--- linux-2.4.29/include/asm-armnommu/proc-fns.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/proc-fns.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,116 @@
+/*
+ *  linux/include/asm-arm/proc-fns.h
+ *
+ *  Copyright (C) 1997-1999 Russell King
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_PROCFNS_H
+#define __ASM_PROCFNS_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+
+/*
+ * Work out if we need multiple CPU support
+ */
+#undef MULTI_CPU
+#undef CPU_NAME
+
+#ifdef CONFIG_CPU_26
+# define CPU_INCLUDE_NAME "asm/cpu-multi26.h"
+# define MULTI_CPU
+#endif
+
+#ifdef CONFIG_CPU_32
+# define CPU_INCLUDE_NAME "asm/cpu-multi32.h"
+# ifdef CONFIG_CPU_ARM610
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME arm6
+#  endif
+# endif
+# ifdef CONFIG_CPU_ARM7V3
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME arm7
+#  endif
+# endif
+# ifdef CONFIG_CPU_ARM710
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME arm7
+#  endif
+# endif
+# ifdef CONFIG_CPU_ARM720T
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME arm720
+#  endif
+# endif
+# ifdef CONFIG_CPU_ARM920T
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME arm920
+#  endif
+# endif
+# ifdef CONFIG_CPU_ARM940T
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME arm940
+#  endif
+# endif
+# ifdef CONFIG_CPU_SA110
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME sa110
+#  endif
+# endif
+# ifdef CONFIG_CPU_SA1100
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME sa1100
+#  endif
+# endif
+#endif
+
+#ifndef MULTI_CPU
+#undef CPU_INCLUDE_NAME
+#define CPU_INCLUDE_NAME "asm/cpu-single.h"
+#endif
+
+#include CPU_INCLUDE_NAME
+
+#endif /* __KERNEL__ */
+
+#if 0
+ * The following is to fool mkdep into generating the correct
+ * dependencies.  Without this, it cant figure out that this
+ * file does indeed depend on the cpu-*.h files.
+#include <asm/cpu-single.h>
+#include <asm/cpu-multi26.h>
+#include <asm/cpu-multi32.h>
+ *
+#endif
+
+#endif /* __ASM_PROCFNS_H */
diff -urN linux-2.4.29/include/asm-armnommu/procinfo.h linux-2.4.29-uc1/include/asm-armnommu/procinfo.h
--- linux-2.4.29/include/asm-armnommu/procinfo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/procinfo.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,58 @@
+/*
+ *  linux/include/asm-arm/procinfo.h
+ *
+ *  Copyright (C) 1996-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_PROCINFO_H
+#define __ASM_PROCINFO_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/proc-fns.h>
+
+struct proc_info_item {
+	const char	 *manufacturer;
+	const char	 *cpu_name;
+};
+
+/*
+ * Note!  struct processor is always defined if we're
+ * using MULTI_CPU, otherwise this entry is unused,
+ * but still exists.
+ *
+ * NOTE! The following structure is defined by assembly
+ * language, NOT C code.  For more information, check:
+ *  arch/arm/mm/proc-*.S and arch/arm/kernel/head-armv.S
+ */
+struct proc_info_list {
+	unsigned int	 cpu_val;
+	unsigned int	 cpu_mask;
+	unsigned long	 __cpu_mmu_flags;	/* used by head-armv.S */
+	unsigned long	 __cpu_flush;		/* used by head-armv.S */
+	const char	 *arch_name;
+	const char	 *elf_name;
+	unsigned int	 elf_hwcap;
+	struct proc_info_item *info;
+#ifdef MULTI_CPU
+	struct processor *proc;
+#else
+	void		 *unused;
+#endif
+};
+
+#endif	/* __ASSEMBLY__ */
+
+#define HWCAP_SWP	 1
+#define HWCAP_HALF	 2
+#define HWCAP_THUMB	 4
+#define HWCAP_26BIT	 8	/* Play it safe */
+#define HWCAP_FAST_MULT	 16
+#define HWCAP_FPA        32
+#define HWCAP_VFP        64
+#define HWCAP_EDSP	 128
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/ptrace.h linux-2.4.29-uc1/include/asm-armnommu/ptrace.h
--- linux-2.4.29/include/asm-armnommu/ptrace.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/ptrace.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef __ASM_ARM_PTRACE_H
+#define __ASM_ARM_PTRACE_H
+
+#include <asm/proc/ptrace.h>
+
+#ifndef __ASSEMBLY__
+#define pc_pointer(v) \
+	((v) & ~PCMASK)
+
+#define instruction_pointer(regs) \
+	(pc_pointer((regs)->ARM_pc))
+
+#define user_stack(regs) ((regs)->ARM_sp)
+
+#ifdef __KERNEL__
+#define PTRACE_GETREGS		12
+#define PTRACE_SETREGS		13
+#define PTRACE_GETFPREGS	14
+#define PTRACE_SETFPREGS	15
+
+extern void show_regs(struct pt_regs *);
+
+#define predicate(x)	(x & 0xf0000000)
+#define PREDICATE_ALWAYS	0xe0000000
+
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/resource.h linux-2.4.29-uc1/include/asm-armnommu/resource.h
--- linux-2.4.29/include/asm-armnommu/resource.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/resource.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,47 @@
+#ifndef _ARM_RESOURCE_H
+#define _ARM_RESOURCE_H
+
+/*
+ * Resource limits
+ */
+
+#define RLIMIT_CPU	0		/* CPU time in ms */
+#define RLIMIT_FSIZE	1		/* Maximum filesize */
+#define RLIMIT_DATA	2		/* max data size */
+#define RLIMIT_STACK	3		/* max stack size */
+#define RLIMIT_CORE	4		/* max core file size */
+#define RLIMIT_RSS	5		/* max resident set size */
+#define RLIMIT_NPROC	6		/* max number of processes */
+#define RLIMIT_NOFILE	7		/* max number of open files */
+#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
+#define RLIMIT_AS	9		/* address space limit */
+#define RLIMIT_LOCKS	10		/* maximum file locks held */
+
+#define RLIM_NLIMITS	11
+
+#ifdef __KERNEL__
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway.
+ */
+#define RLIM_INFINITY	(~0UL)
+
+#define INIT_RLIMITS				\
+{						\
+	{ RLIM_INFINITY, RLIM_INFINITY },	\
+	{ RLIM_INFINITY, RLIM_INFINITY },	\
+	{ RLIM_INFINITY, RLIM_INFINITY },	\
+	{ _STK_LIM,      RLIM_INFINITY },	\
+	{ 0,             RLIM_INFINITY },	\
+	{ RLIM_INFINITY, RLIM_INFINITY },	\
+	{ 0,             0             },	\
+	{ INR_OPEN,      INR_OPEN      },	\
+	{ RLIM_INFINITY, RLIM_INFINITY },	\
+	{ RLIM_INFINITY, RLIM_INFINITY },	\
+	{ RLIM_INFINITY, RLIM_INFINITY },	\
+}
+
+#endif /* __KERNEL__ */
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/s3cmprofile.h linux-2.4.29-uc1/include/asm-armnommu/s3cmprofile.h
--- linux-2.4.29/include/asm-armnommu/s3cmprofile.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/s3cmprofile.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,69 @@
+/***********************************************************************
+ * 
+ * Profiling Header
+ * Copyright (c) 2002 Arcturus Networks Inc.
+ *                    by MaTed <www.ArcturusNetworks.com>
+ *
+ ***********************************************************************/
+/* s3cprofile.h */
+/*
+ * modification history
+ * --------------------
+ *
+ * 	08/02/02 MaTed <www.ArcturusNetworks.com>
+ *			- Initial version for uClinux - Samsung
+ *			- please set TABS == 4
+ *
+ */
+
+
+//#ifdef MPROFILE		// enable miniprofile
+#undef MPROFILE
+#if 0
+#define ProfileArraySize 2048
+typedef struct
+{
+  unsigned short	code;
+  void *			addr;
+  unsigned long		jiffie;
+  unsigned long		counter;
+} PROFILE_ARRAY;
+
+#ifdef S3C2500_ETHERNET
+PROFILE_ARRAY profileArray[ ProfileArraySize ];
+UINT32	profileAddrIndex = 0;
+#else
+extern PROFILE_ARRAY profileArray[ ProfileArraySize ];
+extern unsigned long	profileAddrIndex;
+#endif
+
+extern unsigned long volatile jiffies; 
+
+#define COUNTER_REG		0xf0040014		// Counter register - runs at bus speed
+#define enterCnt( profileCode )				\
+({										\
+   __label__ entryAddr;					\
+entryAddr:								\
+	profileArray[ profileAddrIndex ].code = profileCode;	\
+	profileArray[ profileAddrIndex ].addr = && entryAddr;	\
+	profileArray[ profileAddrIndex ].counter				\
+	  = (*((unsigned long *) 0xf0040010) -*((unsigned long *) 0xf0040014));	\
+	profileArray[ profileAddrIndex ].jiffie = jiffies;		\
+	if (++profileAddrIndex >= ProfileArraySize)				\
+	  profileAddrIndex = 0;									\
+})
+
+#define enterCntVal( profileCode, value )				\
+({										\
+	profileArray[ profileAddrIndex ].code = profileCode;	\
+	profileArray[ profileAddrIndex ].addr = (void*) value;	\
+	profileArray[ profileAddrIndex ].counter				\
+	  = (*((unsigned long *) 0xf0040010) -*((unsigned long *) 0xf0040014));	\
+	profileArray[ profileAddrIndex ].jiffie = jiffies;		\
+	if (++profileAddrIndex >= ProfileArraySize)				\
+	  profileAddrIndex = 0;									\
+})
+#else // MPROFILE
+#define enterCnt( profileCode)
+#define enterCntVal( profileCode, value)
+#endif // MPROFILE
diff -urN linux-2.4.29/include/asm-armnommu/scatterlist.h linux-2.4.29-uc1/include/asm-armnommu/scatterlist.h
--- linux-2.4.29/include/asm-armnommu/scatterlist.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/scatterlist.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,28 @@
+#ifndef _ASMARM_SCATTERLIST_H
+#define _ASMARM_SCATTERLIST_H
+
+#include <asm/types.h>
+
+struct scatterlist {
+	char		*address;	/* virtual address		 */
+	struct page	*page;		/* Location for highmem page, if any */
+	unsigned int	offset;
+
+	char		*alt_address;	/* indirect dma address, or NULL */
+	dma_addr_t	dma_address;	/* dma address			 */
+	unsigned int	length;		/* length			 */
+};
+
+/*
+ * These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
+#define sg_dma_address(sg)      ((sg)->dma_address)
+#define sg_dma_len(sg)          ((sg)->length)
+
+#define ISA_DMA_THRESHOLD (0xffffffff)
+
+#endif /* _ASMARM_SCATTERLIST_H */
diff -urN linux-2.4.29/include/asm-armnommu/segment.h linux-2.4.29-uc1/include/asm-armnommu/segment.h
--- linux-2.4.29/include/asm-armnommu/segment.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/segment.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,11 @@
+#ifndef __ASM_ARM_SEGMENT_H
+#define __ASM_ARM_SEGMENT_H
+
+#define __KERNEL_CS   0x0
+#define __KERNEL_DS   0x0
+
+#define __USER_CS     0x1
+#define __USER_DS     0x1
+
+#endif /* __ASM_ARM_SEGMENT_H */
+
diff -urN linux-2.4.29/include/asm-armnommu/semaphore.h linux-2.4.29-uc1/include/asm-armnommu/semaphore.h
--- linux-2.4.29/include/asm-armnommu/semaphore.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/semaphore.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,133 @@
+/*
+ * linux/include/asm-arm/semaphore.h
+ */
+#ifndef __ASM_ARM_SEMAPHORE_H
+#define __ASM_ARM_SEMAPHORE_H
+
+#include <linux/linkage.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/rwsem.h>
+
+#include <asm/atomic.h>
+#include <asm/proc/locks.h>
+
+struct semaphore {
+	atomic_t count;
+	int sleepers;
+	wait_queue_head_t wait;
+#if WAITQUEUE_DEBUG
+	long __magic;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+# define __SEM_DEBUG_INIT(name) \
+		, (long)&(name).__magic
+#else
+# define __SEM_DEBUG_INIT(name)
+#endif
+
+#define __SEMAPHORE_INIT(name,count)			\
+	{ ATOMIC_INIT(count), 0,			\
+	  __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
+	  __SEM_DEBUG_INIT(name) }
+
+#define __MUTEX_INITIALIZER(name) \
+	__SEMAPHORE_INIT(name,1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count)	\
+	struct semaphore name = __SEMAPHORE_INIT(name,count)
+
+#define DECLARE_MUTEX(name)		__DECLARE_SEMAPHORE_GENERIC(name,1)
+#define DECLARE_MUTEX_LOCKED(name)	__DECLARE_SEMAPHORE_GENERIC(name,0)
+
+extern inline void sema_init(struct semaphore *sem, int val)
+{
+	atomic_set(&sem->count, val);
+	sem->sleepers = 0;
+	init_waitqueue_head(&sem->wait);
+#if WAITQUEUE_DEBUG
+	sem->__magic = (long)&sem->__magic;
+#endif
+}
+
+static inline void init_MUTEX(struct semaphore *sem)
+{
+	sema_init(sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED(struct semaphore *sem)
+{
+	sema_init(sem, 0);
+}
+
+/*
+ * special register calling convention
+ */
+asmlinkage void __down_failed(void);
+asmlinkage int  __down_interruptible_failed(void);
+asmlinkage int  __down_trylock_failed(void);
+asmlinkage void __up_wakeup(void);
+
+extern void __down(struct semaphore * sem);
+extern int  __down_interruptible(struct semaphore * sem);
+extern int  __down_trylock(struct semaphore * sem);
+extern void __up(struct semaphore * sem);
+
+/*
+ * This is ugly, but we want the default case to fall through.
+ * "__down" is the actual routine that waits...
+ */
+extern inline void down(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	__down_op(sem, __down_failed);
+}
+
+/*
+ * This is ugly, but we want the default case to fall through.
+ * "__down_interruptible" is the actual routine that waits...
+ */
+extern inline int down_interruptible (struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	return __down_op_ret(sem, __down_interruptible_failed);
+}
+
+extern inline int down_trylock(struct semaphore *sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	return __down_op_ret(sem, __down_trylock_failed);
+}
+
+/*
+ * Note! This is subtle. We jump to wake people up only if
+ * the semaphore was negative (== somebody was waiting on it).
+ * The default case (no contention) will result in NO
+ * jumps for both down() and up().
+ */
+extern inline void up(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	__up_op(sem, __up_wakeup);
+}
+
+static inline int sem_getcount(struct semaphore *sem)
+{
+	return atomic_read(&sem->count);
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/semaphore-helper.h linux-2.4.29-uc1/include/asm-armnommu/semaphore-helper.h
--- linux-2.4.29/include/asm-armnommu/semaphore-helper.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/semaphore-helper.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,84 @@
+#ifndef ASMARM_SEMAPHORE_HELPER_H
+#define ASMARM_SEMAPHORE_HELPER_H
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ */
+static inline void wake_one_more(struct semaphore * sem)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (atomic_read(&sem->count) <= 0)
+		sem->waking++;
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+}
+
+static inline int waking_non_zero(struct semaphore *sem)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (sem->waking > 0) {
+		sem->waking--;
+		ret = 1;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+/*
+ * waking non zero interruptible
+ *	1	got the lock
+ *	0	go to sleep
+ *	-EINTR	interrupted
+ *
+ * We must undo the sem->count down_interruptible() increment while we are
+ * protected by the spinlock in order to make this atomic_inc() with the
+ * atomic_read() in wake_one_more(), otherwise we can race. -arca
+ */
+static inline int waking_non_zero_interruptible(struct semaphore *sem,
+						struct task_struct *tsk)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (sem->waking > 0) {
+		sem->waking--;
+		ret = 1;
+	} else if (signal_pending(tsk)) {
+		atomic_inc(&sem->count);
+		ret = -EINTR;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;	
+}
+
+/*
+ * waking_non_zero_try_lock:
+ *	1	failed to lock
+ *	0	got the lock
+ *
+ * We must undo the sem->count down_interruptible() increment while we are
+ * protected by the spinlock in order to make this atomic_inc() with the
+ * atomic_read() in wake_one_more(), otherwise we can race. -arca
+ */
+static inline int waking_non_zero_trylock(struct semaphore *sem)
+{
+	unsigned long flags;
+	int ret = 1;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (sem->waking <= 0)
+		atomic_inc(&sem->count);
+	else {
+		sem->waking--;
+		ret = 0;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/sembuf.h linux-2.4.29-uc1/include/asm-armnommu/sembuf.h
--- linux-2.4.29/include/asm-armnommu/sembuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/sembuf.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef _ASMARM_SEMBUF_H
+#define _ASMARM_SEMBUF_H
+
+/* 
+ * The semid64_ds structure for arm architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
+	__kernel_time_t	sem_otime;		/* last semop time */
+	unsigned long	__unused1;
+	__kernel_time_t	sem_ctime;		/* last change time */
+	unsigned long	__unused2;
+	unsigned long	sem_nsems;		/* no. of semaphores in array */
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _ASMARM_SEMBUF_H */
diff -urN linux-2.4.29/include/asm-armnommu/serial.h linux-2.4.29-uc1/include/asm-armnommu/serial.h
--- linux-2.4.29/include/asm-armnommu/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/serial.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,23 @@
+/*
+ *  linux/include/asm-arm/serial.h
+ *
+ *  Copyright (C) 1996 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Changelog:
+ *   15-10-1996	RMK	Created
+ */
+
+#ifndef __ASM_SERIAL_H
+#define __ASM_SERIAL_H
+
+#include <asm/arch/serial.h>
+
+#define SERIAL_PORT_DFNS		\
+	STD_SERIAL_PORT_DEFNS		\
+	EXTRA_SERIAL_PORT_DEFNS
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/setup.h linux-2.4.29-uc1/include/asm-armnommu/setup.h
--- linux-2.4.29/include/asm-armnommu/setup.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/setup.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,270 @@
+/*
+ *  linux/include/asm/setup.h
+ *
+ *  Copyright (C) 1997-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Structure passed to kernel to tell it about the
+ *  hardware it's running on.  See linux/Documentation/arm/Setup
+ *  for more info.
+ *
+ * NOTE:
+ *  This file contains two ways to pass information from the boot
+ *  loader to the kernel. The old struct param_struct is deprecated,
+ *  but it will be kept in the kernel for 5 years from now
+ *  (2001). This will allow boot loaders to convert to the new struct
+ *  tag way.
+ */
+#ifndef __ASMARM_SETUP_H
+#define __ASMARM_SETUP_H
+
+/*
+ * Usage:
+ *  - do not go blindly adding fields, add them at the end
+ *  - when adding fields, don't rely on the address until
+ *    a patch from me has been released
+ *  - unused fields should be zero (for future expansion)
+ *  - this structure is relatively short-lived - only
+ *    guaranteed to contain useful data in setup_arch()
+ */
+#define COMMAND_LINE_SIZE 1024
+
+/* This is the old deprecated way to pass parameters to the kernel */
+struct param_struct {
+    union {
+	struct {
+	    unsigned long page_size;		/*  0 */
+	    unsigned long nr_pages;		/*  4 */
+	    unsigned long ramdisk_size;		/*  8 */
+	    unsigned long flags;		/* 12 */
+#define FLAG_READONLY	1
+#define FLAG_RDLOAD	4
+#define FLAG_RDPROMPT	8
+	    unsigned long rootdev;		/* 16 */
+	    unsigned long video_num_cols;	/* 20 */
+	    unsigned long video_num_rows;	/* 24 */
+	    unsigned long video_x;		/* 28 */
+	    unsigned long video_y;		/* 32 */
+	    unsigned long memc_control_reg;	/* 36 */
+	    unsigned char sounddefault;		/* 40 */
+	    unsigned char adfsdrives;		/* 41 */
+	    unsigned char bytes_per_char_h;	/* 42 */
+	    unsigned char bytes_per_char_v;	/* 43 */
+	    unsigned long pages_in_bank[4];	/* 44 */
+	    unsigned long pages_in_vram;	/* 60 */
+	    unsigned long initrd_start;		/* 64 */
+	    unsigned long initrd_size;		/* 68 */
+	    unsigned long rd_start;		/* 72 */
+	    unsigned long system_rev;		/* 76 */
+	    unsigned long system_serial_low;	/* 80 */
+	    unsigned long system_serial_high;	/* 84 */
+	    unsigned long mem_fclk_21285;       /* 88 */
+	} s;
+	char unused[256];
+    } u1;
+    union {
+	char paths[8][128];
+	struct {
+	    unsigned long magic;
+	    char n[1024 - sizeof(unsigned long)];
+	} s;
+    } u2;
+    char commandline[COMMAND_LINE_SIZE];
+};
+
+
+
+/*
+ * The new way of passing information: a list of tagged entries
+ */
+
+/* The list ends with an ATAG_NONE node. */
+#define ATAG_NONE	0x00000000
+
+struct tag_header {
+	u32 size;
+	u32 tag;
+};
+
+/* The list must start with an ATAG_CORE node */
+#define ATAG_CORE	0x54410001
+
+struct tag_core {
+	u32 flags;		/* bit 0 = read-only */
+	u32 pagesize;
+	u32 rootdev;
+};
+
+/* it is allowed to have multiple ATAG_MEM nodes */
+#define ATAG_MEM	0x54410002
+
+struct tag_mem32 {
+	u32	size;
+	u32	start;	/* physical start address */
+};
+
+/* VGA text type displays */
+#define ATAG_VIDEOTEXT	0x54410003
+
+struct tag_videotext {
+	u8		x;
+	u8		y;
+	u16		video_page;
+	u8		video_mode;
+	u8		video_cols;
+	u16		video_ega_bx;
+	u8		video_lines;
+	u8		video_isvga;
+	u16		video_points;
+};
+
+/* describes how the ramdisk will be used in kernel */
+#define ATAG_RAMDISK	0x54410004
+
+struct tag_ramdisk {
+	u32 flags;	/* bit 0 = load, bit 1 = prompt */
+	u32 size;	/* decompressed ramdisk size in _kilo_ bytes */
+	u32 start;	/* starting block of floppy-based RAM disk image */
+};
+
+/* describes where the compressed ramdisk image lives (virtual address) */
+/*
+ * this one accidentally used virtual addresses - as such,
+ * its depreciated.
+ */
+#define ATAG_INITRD	0x54410005
+
+/* describes where the compressed ramdisk image lives (physical address) */
+#define ATAG_INITRD2	0x54420005
+
+struct tag_initrd {
+	u32 start;	/* physical start address */
+	u32 size;	/* size of compressed ramdisk image in bytes */
+};
+
+/* board serial number. "64 bits should be enough for everybody" */
+#define ATAG_SERIAL	0x54410006
+
+struct tag_serialnr {
+	u32 low;
+	u32 high;
+};
+
+/* board revision */
+#define ATAG_REVISION	0x54410007
+
+struct tag_revision {
+	u32 rev;
+};
+
+/* initial values for vesafb-type framebuffers. see struct screen_info
+ * in include/linux/tty.h
+ */
+#define ATAG_VIDEOLFB	0x54410008
+
+struct tag_videolfb {
+	u16		lfb_width;
+	u16		lfb_height;
+	u16		lfb_depth;
+	u16		lfb_linelength;
+	u32		lfb_base;
+	u32		lfb_size;
+	u8		red_size;
+	u8		red_pos;
+	u8		green_size;
+	u8		green_pos;
+	u8		blue_size;
+	u8		blue_pos;
+	u8		rsvd_size;
+	u8		rsvd_pos;
+};
+
+/* command line: \0 terminated string */
+#define ATAG_CMDLINE	0x54410009
+
+struct tag_cmdline {
+	char	cmdline[1];	/* this is the minimum size */
+};
+
+/* acorn RiscPC specific information */
+#define ATAG_ACORN	0x41000101
+
+struct tag_acorn {
+	u32 memc_control_reg;
+	u32 vram_pages;
+	u8 sounddefault;
+	u8 adfsdrives;
+};
+
+/* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */
+#define ATAG_MEMCLK	0x41000402
+
+struct tag_memclk {
+	u32 fmemclk;
+};
+
+struct tag {
+	struct tag_header hdr;
+	union {
+		struct tag_core		core;
+		struct tag_mem32	mem;
+		struct tag_videotext	videotext;
+		struct tag_ramdisk	ramdisk;
+		struct tag_initrd	initrd;
+		struct tag_serialnr	serialnr;
+		struct tag_revision	revision;
+		struct tag_videolfb	videolfb;
+		struct tag_cmdline	cmdline;
+
+		/*
+		 * Acorn specific
+		 */
+		struct tag_acorn	acorn;
+
+		/*
+		 * DC21285 specific
+		 */
+		struct tag_memclk	memclk;
+	} u;
+};
+
+struct tagtable {
+	u32 tag;
+	int (*parse)(const struct tag *);
+};
+
+#define __tag __attribute__((unused, __section__(".taglist")))
+#define __tagtable(tag, fn) \
+static struct tagtable __tagtable_##fn __tag = { tag, fn }
+
+#define tag_member_present(tag,member)				\
+	((unsigned long)(&((struct tag *)0L)->member + 1)	\
+		<= (tag)->hdr.size * 4)
+
+#define tag_next(t)	((struct tag *)((u32 *)(t) + (t)->hdr.size))
+#define tag_size(type)	((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
+
+#define for_each_tag(t,base)		\
+	for (t = base; t->hdr.size; t = tag_next(t))
+
+/*
+ * Memory map description
+ */
+#define NR_BANKS 8
+
+struct meminfo {
+	int nr_banks;
+	unsigned long end;
+	struct {
+		unsigned long start;
+		unsigned long size;
+		int           node;
+	} bank[NR_BANKS];
+};
+
+extern struct meminfo meminfo;
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/shmbuf.h linux-2.4.29-uc1/include/asm-armnommu/shmbuf.h
--- linux-2.4.29/include/asm-armnommu/shmbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/shmbuf.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,42 @@
+#ifndef _ASMARM_SHMBUF_H
+#define _ASMARM_SHMBUF_H
+
+/* 
+ * The shmid64_ds structure for arm architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	unsigned long		__unused1;
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	unsigned long		__unused2;
+	__kernel_time_t		shm_ctime;	/* last change time */
+	unsigned long		__unused3;
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _ASMARM_SHMBUF_H */
diff -urN linux-2.4.29/include/asm-armnommu/shmparam.h linux-2.4.29-uc1/include/asm-armnommu/shmparam.h
--- linux-2.4.29/include/asm-armnommu/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/shmparam.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef _ASMARM_SHMPARAM_H
+#define _ASMARM_SHMPARAM_H
+
+#include <asm/proc/shmparam.h>
+
+/*
+ * This should be the size of the virtually indexed cache/ways,
+ * or page size, whichever is greater since the cache aliases
+ * every size/ways bytes.
+ */
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
+
+#endif /* _ASMARM_SHMPARAM_H */
diff -urN linux-2.4.29/include/asm-armnommu/sigcontext.h linux-2.4.29-uc1/include/asm-armnommu/sigcontext.h
--- linux-2.4.29/include/asm-armnommu/sigcontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/sigcontext.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,34 @@
+#ifndef _ASMARM_SIGCONTEXT_H
+#define _ASMARM_SIGCONTEXT_H
+
+/*
+ * Signal context structure - contains all info to do with the state
+ * before the signal handler was invoked.  Note: only add new entries
+ * to the end of the structure.
+ */
+struct sigcontext {
+	unsigned long trap_no;
+	unsigned long error_code;
+	unsigned long oldmask;
+	unsigned long arm_r0;
+	unsigned long arm_r1;
+	unsigned long arm_r2;
+	unsigned long arm_r3;
+	unsigned long arm_r4;
+	unsigned long arm_r5;
+	unsigned long arm_r6;
+	unsigned long arm_r7;
+	unsigned long arm_r8;
+	unsigned long arm_r9;
+	unsigned long arm_r10;
+	unsigned long arm_fp;
+	unsigned long arm_ip;
+	unsigned long arm_sp;
+	unsigned long arm_lr;
+	unsigned long arm_pc;
+	unsigned long arm_cpsr;
+	unsigned long fault_address;
+};
+
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/siginfo.h linux-2.4.29-uc1/include/asm-armnommu/siginfo.h
--- linux-2.4.29/include/asm-armnommu/siginfo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/siginfo.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,233 @@
+#ifndef _ASMARM_SIGINFO_H
+#define _ASMARM_SIGINFO_H
+
+#include <linux/types.h>
+
+/* XXX: This structure was copied from the Alpha; is there an iBCS version?  */
+
+typedef union sigval {
+	int sival_int;
+	void *sival_ptr;
+} sigval_t;
+
+#define SI_MAX_SIZE	128
+#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct siginfo {
+	int si_signo;
+	int si_errno;
+	int si_code;
+
+	union {
+		int _pad[SI_PAD_SIZE];
+
+		/* kill() */
+		struct {
+			pid_t _pid;		/* sender's pid */
+			uid_t _uid;		/* sender's uid */
+		} _kill;
+
+		/* POSIX.1b timers */
+		struct {
+			unsigned int _timer1;
+			unsigned int _timer2;
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			pid_t _pid;		/* sender's pid */
+			uid_t _uid;		/* sender's uid */
+			sigval_t _sigval;
+		} _rt;
+
+		/* SIGCHLD */
+		struct {
+			pid_t _pid;		/* which child */
+			uid_t _uid;		/* sender's uid */
+			int _status;		/* exit code */
+			clock_t _utime;
+			clock_t _stime;
+		} _sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			void *_addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+	} _sifields;
+} siginfo_t;
+
+/*
+ * How these fields are to be accessed.
+ */
+#define si_pid		_sifields._kill._pid
+#define si_uid		_sifields._kill._uid
+#define si_status	_sifields._sigchld._status
+#define si_utime	_sifields._sigchld._utime
+#define si_stime	_sifields._sigchld._stime
+#define si_value	_sifields._rt._sigval
+#define si_int		_sifields._rt._sigval.sival_int
+#define si_ptr		_sifields._rt._sigval.sival_ptr
+#define si_addr		_sifields._sigfault._addr
+#define si_band		_sifields._sigpoll._band
+#define si_fd		_sifields._sigpoll._fd
+
+#ifdef __KERNEL__
+#define __SI_MASK	0xffff0000
+#define __SI_KILL	(0 << 16)
+#define __SI_TIMER	(1 << 16)
+#define __SI_POLL	(2 << 16)
+#define __SI_FAULT	(3 << 16)
+#define __SI_CHLD	(4 << 16)
+#define __SI_RT		(5 << 16)
+#define __SI_CODE(T,N)	((T) << 16 | ((N) & 0xffff))
+#else
+#define __SI_KILL	0
+#define __SI_TIMER	0
+#define __SI_POLL	0
+#define __SI_FAULT	0
+#define __SI_CHLD	0
+#define __SI_RT		0
+#define __SI_CODE(T,N)	(N)
+#endif
+
+/*
+ * si_code values
+ * Digital reserves positive values for kernel-generated signals.
+ */
+#define SI_USER		0		/* sent by kill, sigsend, raise */
+#define SI_KERNEL	0x80		/* sent by the kernel from somewhere */
+#define SI_QUEUE	-1		/* sent by sigqueue */
+#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
+#define SI_MESGQ	-3		/* sent by real time mesq state change */
+#define SI_ASYNCIO	-4		/* sent by AIO completion */
+#define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
+
+#define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
+#define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
+
+/*
+ * SIGILL si_codes
+ */
+#define ILL_ILLOPC	(__SI_FAULT|1)	/* illegal opcode */
+#define ILL_ILLOPN	(__SI_FAULT|2)	/* illegal operand */
+#define ILL_ILLADR	(__SI_FAULT|3)	/* illegal addressing mode */
+#define ILL_ILLTRP	(__SI_FAULT|4)	/* illegal trap */
+#define ILL_PRVOPC	(__SI_FAULT|5)	/* privileged opcode */
+#define ILL_PRVREG	(__SI_FAULT|6)	/* privileged register */
+#define ILL_COPROC	(__SI_FAULT|7)	/* coprocessor error */
+#define ILL_BADSTK	(__SI_FAULT|8)	/* internal stack error */
+#define NSIGILL		8
+
+/*
+ * SIGFPE si_codes
+ */
+#define FPE_INTDIV	(__SI_FAULT|1)	/* integer divide by zero */
+#define FPE_INTOVF	(__SI_FAULT|2)	/* integer overflow */
+#define FPE_FLTDIV	(__SI_FAULT|3)	/* floating point divide by zero */
+#define FPE_FLTOVF	(__SI_FAULT|4)	/* floating point overflow */
+#define FPE_FLTUND	(__SI_FAULT|5)	/* floating point underflow */
+#define FPE_FLTRES	(__SI_FAULT|6)	/* floating point inexact result */
+#define FPE_FLTINV	(__SI_FAULT|7)	/* floating point invalid operation */
+#define FPE_FLTSUB	(__SI_FAULT|8)	/* subscript out of range */
+#define NSIGFPE		8
+
+/*
+ * SIGSEGV si_codes
+ */
+#define SEGV_MAPERR	(__SI_FAULT|1)	/* address not mapped to object */
+#define SEGV_ACCERR	(__SI_FAULT|2)	/* invalid permissions for mapped object */
+#define NSIGSEGV	2
+
+/*
+ * SIGBUS si_codes
+ */
+#define BUS_ADRALN	(__SI_FAULT|1)	/* invalid address alignment */
+#define BUS_ADRERR	(__SI_FAULT|2)	/* non-existant physical address */
+#define BUS_OBJERR	(__SI_FAULT|3)	/* object specific hardware error */
+#define NSIGBUS		3
+
+/*
+ * SIGTRAP si_codes
+ */
+#define TRAP_BRKPT	(__SI_FAULT|1)	/* process breakpoint */
+#define TRAP_TRACE	(__SI_FAULT|2)	/* process trace trap */
+#define NSIGTRAP	2
+
+/*
+ * SIGCHLD si_codes
+ */
+#define CLD_EXITED	(__SI_CHLD|1)	/* child has exited */
+#define CLD_KILLED	(__SI_CHLD|2)	/* child was killed */
+#define CLD_DUMPED	(__SI_CHLD|3)	/* child terminated abnormally */
+#define CLD_TRAPPED	(__SI_CHLD|4)	/* traced child has trapped */
+#define CLD_STOPPED	(__SI_CHLD|5)	/* child has stopped */
+#define CLD_CONTINUED	(__SI_CHLD|6)	/* stopped child has continued */
+#define NSIGCHLD	6
+
+/*
+ * SIGPOLL si_codes
+ */
+#define POLL_IN		(__SI_POLL|1)	/* data input available */
+#define POLL_OUT	(__SI_POLL|2)	/* output buffers available */
+#define POLL_MSG	(__SI_POLL|3)	/* input message available */
+#define POLL_ERR	(__SI_POLL|4)	/* i/o error */
+#define POLL_PRI	(__SI_POLL|5)	/* high priority input available */
+#define POLL_HUP	(__SI_POLL|6)	/* device disconnected */
+#define NSIGPOLL	6
+
+/*
+ * sigevent definitions
+ * 
+ * It seems likely that SIGEV_THREAD will have to be handled from 
+ * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
+ * thread manager then catches and does the appropriate nonsense.
+ * However, everything is written out here so as to not get lost.
+ */
+#define SIGEV_SIGNAL	0	/* notify via signal */
+#define SIGEV_NONE	1	/* other notification: meaningless */
+#define SIGEV_THREAD	2	/* deliver via thread creation */
+
+#define SIGEV_MAX_SIZE	64
+#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct sigevent {
+	sigval_t sigev_value;
+	int sigev_signo;
+	int sigev_notify;
+	union {
+		int _pad[SIGEV_PAD_SIZE];
+
+		struct {
+			void (*_function)(sigval_t);
+			void *_attribute;	/* really pthread_attr_t */
+		} _sigev_thread;
+	} _sigev_un;
+} sigevent_t;
+
+#define sigev_notify_function	_sigev_un._sigev_thread._function
+#define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
+
+#ifdef __KERNEL__
+#include <linux/string.h>
+
+extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
+{
+	if (from->si_code < 0)
+		memcpy(to, from, sizeof(siginfo_t));
+	else
+		/* _sigchld is currently the largest know union member */
+		memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
+}
+
+extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
+
+#endif /* __KERNEL__ */
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/signal.h linux-2.4.29-uc1/include/asm-armnommu/signal.h
--- linux-2.4.29/include/asm-armnommu/signal.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/signal.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,191 @@
+#ifndef _ASMARM_SIGNAL_H
+#define _ASMARM_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+#define SIGSWI		32
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_NOCLDSTOP		flag to turn off SIGCHLD when children stop.
+ * SA_NOCLDWAIT		flag on SIGCHLD to inhibit zombies.
+ * SA_SIGINFO		deliver the signal with SIGINFO structs
+ * SA_THIRTYTWO		delivers the signal in 32-bit mode, even if the task 
+ *			is running in 26-bit.
+ * SA_ONSTACK		allows alternate signal stacks (see sigaltstack(2)).
+ * SA_RESTART		flag to get restarting signals (which were the default long ago)
+ * SA_INTERRUPT		is a no-op, but left due to historical reasons. Use the
+ * SA_NODEFER		prevents the current signal from being masked in the handler.
+ * SA_RESETHAND		clears the handler when the signal is delivered.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_THIRTYTWO	0x02000000
+#define SA_RESTORER	0x04000000
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#ifdef __KERNEL__
+
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE		0x80000000
+#define SA_SAMPLE_RANDOM	0x10000000
+#define SA_IRQNOMASK		0x08000000
+#define SA_SHIRQ		0x04000000
+#endif
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+#ifdef __KERNEL__
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+#include <asm/sigcontext.h>
+
+#define sigmask(sig)	(1UL << ((sig) - 1))
+
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/smp.h linux-2.4.29-uc1/include/asm-armnommu/smp.h
--- linux-2.4.29/include/asm-armnommu/smp.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/smp.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,10 @@
+#ifndef __ASM_SMP_H
+#define __ASM_SMP_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_SMP
+#error SMP not supported
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/smplock.h linux-2.4.29-uc1/include/asm-armnommu/smplock.h
--- linux-2.4.29/include/asm-armnommu/smplock.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/smplock.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,51 @@
+/*
+ * <asm/smplock.h>
+ *
+ * Default SMP lock implementation
+ */
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+extern spinlock_t kernel_flag;
+
+#define kernel_locked()		spin_is_locked(&kernel_flag)
+
+/*
+ * Release global kernel lock and global interrupt lock
+ */
+#define release_kernel_lock(task, cpu) \
+do { \
+	if (task->lock_depth >= 0) \
+		spin_unlock(&kernel_flag); \
+	release_irqlock(cpu); \
+	__sti(); \
+} while (0)
+
+/*
+ * Re-acquire the kernel lock
+ */
+#define reacquire_kernel_lock(task) \
+do { \
+	if (task->lock_depth >= 0) \
+		spin_lock(&kernel_flag); \
+} while (0)
+
+
+/*
+ * Getting the big kernel lock.
+ *
+ * This cannot happen asynchronously,
+ * so we only need to worry about other
+ * CPU's.
+ */
+extern __inline__ void lock_kernel(void)
+{
+	if (!++current->lock_depth)
+		spin_lock(&kernel_flag);
+}
+
+extern __inline__ void unlock_kernel(void)
+{
+	if (--current->lock_depth < 0)
+		spin_unlock(&kernel_flag);
+}
diff -urN linux-2.4.29/include/asm-armnommu/socket.h linux-2.4.29-uc1/include/asm-armnommu/socket.h
--- linux-2.4.29/include/asm-armnommu/socket.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/socket.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,64 @@
+#ifndef _ASMARM_SOCKET_H
+#define _ASMARM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED	16
+#define SO_PEERCRED	17
+#define SO_RCVLOWAT	18
+#define SO_SNDLOWAT	19
+#define SO_RCVTIMEO	20
+#define SO_SNDTIMEO	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE 25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME             28
+#define SO_TIMESTAMP		29
+#define SCM_TIMESTAMP		SO_TIMESTAMP
+
+#define SO_ACCEPTCONN		30
+
+/* Nast libc5 fixup - bletch */
+#if defined(__KERNEL__)
+/* Socket types. */
+#define SOCK_STREAM	1		/* stream (connection) socket	*/
+#define SOCK_DGRAM	2		/* datagram (conn.less) socket	*/
+#define SOCK_RAW	3		/* raw socket			*/
+#define SOCK_RDM	4		/* reliably-delivered message	*/
+#define SOCK_SEQPACKET	5		/* sequential packet socket	*/
+#define SOCK_PACKET	10		/* linux specific way of	*/
+					/* getting packets at the dev	*/
+					/* level.  For writing rarp and	*/
+					/* other similar things on the	*/
+					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
+#endif
+
+#endif /* _ASM_SOCKET_H */
diff -urN linux-2.4.29/include/asm-armnommu/sockios.h linux-2.4.29-uc1/include/asm-armnommu/sockios.h
--- linux-2.4.29/include/asm-armnommu/sockios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/sockios.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef __ARCH_ARM_SOCKIOS_H
+#define __ARCH_ARM_SOCKIOS_H
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 	0x8901
+#define SIOCSPGRP	0x8902
+#define FIOGETOWN	0x8903
+#define SIOCGPGRP	0x8904
+#define SIOCATMARK	0x8905
+#define SIOCGSTAMP	0x8906		/* Get stamp */
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/softirq.h linux-2.4.29-uc1/include/asm-armnommu/softirq.h
--- linux-2.4.29/include/asm-armnommu/softirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/softirq.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,24 @@
+#ifndef __ASM_SOFTIRQ_H
+#define __ASM_SOFTIRQ_H
+
+#include <asm/atomic.h>
+#include <asm/hardirq.h>
+
+#define __cpu_bh_enable(cpu) \
+		do { barrier(); local_bh_count(cpu)--; } while (0)
+#define cpu_bh_disable(cpu) \
+		do { local_bh_count(cpu)++; barrier(); } while (0)
+
+#define local_bh_disable()	cpu_bh_disable(smp_processor_id())
+#define __local_bh_enable()	__cpu_bh_enable(smp_processor_id())
+
+#define in_softirq()		(local_bh_count(smp_processor_id()) != 0)
+
+#define local_bh_enable()						\
+do {									\
+	unsigned int *ptr = &local_bh_count(smp_processor_id());	\
+	if (!--*ptr && ptr[-2])						\
+		__asm__("bl%? __do_softirq": : : "lr");/* out of line */\
+} while (0)
+
+#endif	/* __ASM_SOFTIRQ_H */
diff -urN linux-2.4.29/include/asm-armnommu/spinlock.h linux-2.4.29-uc1/include/asm-armnommu/spinlock.h
--- linux-2.4.29/include/asm-armnommu/spinlock.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/spinlock.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __ASM_SPINLOCK_H
+#define __ASM_SPINLOCK_H
+
+#error ARM architecture does not support SMP spin locks
+
+#endif /* __ASM_SPINLOCK_H */
diff -urN linux-2.4.29/include/asm-armnommu/statfs.h linux-2.4.29-uc1/include/asm-armnommu/statfs.h
--- linux-2.4.29/include/asm-armnommu/statfs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/statfs.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef _ASMARM_STATFS_H
+#define _ASMARM_STATFS_H
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t	fsid_t;
+
+#endif
+
+struct statfs {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_spare[6];
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/stat.h linux-2.4.29-uc1/include/asm-armnommu/stat.h
--- linux-2.4.29/include/asm-armnommu/stat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/stat.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,77 @@
+#ifndef _ASMARM_STAT_H
+#define _ASMARM_STAT_H
+
+struct __old_kernel_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+struct stat {
+	unsigned short st_dev;
+	unsigned short __pad1;
+	unsigned long st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned short __pad2;
+	unsigned long  st_size;
+	unsigned long  st_blksize;
+	unsigned long  st_blocks;
+	unsigned long  st_atime;
+	unsigned long  __unused1;
+	unsigned long  st_mtime;
+	unsigned long  __unused2;
+	unsigned long  st_ctime;
+	unsigned long  __unused3;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat64 {
+	unsigned short	st_dev;
+	unsigned char	__pad0[10];
+
+#define STAT64_HAS_BROKEN_ST_INO	1
+	unsigned long	__st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned short	st_rdev;
+	unsigned char	__pad3[10];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+
+	unsigned long	st_atime;
+	unsigned long	__pad5;
+
+	unsigned long	st_mtime;
+	unsigned long	__pad6;
+
+	unsigned long	st_ctime;
+	unsigned long	__pad7;		/* will be high 32 bits of ctime someday */
+
+	unsigned long long	st_ino;
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/string.h linux-2.4.29-uc1/include/asm-armnommu/string.h
--- linux-2.4.29/include/asm-armnommu/string.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/string.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,43 @@
+#ifndef __ASM_ARM_STRING_H
+#define __ASM_ARM_STRING_H
+
+/*
+ * We don't do inline string functions, since the
+ * optimised inline asm versions are not small.
+ */
+
+#define __HAVE_ARCH_STRRCHR
+extern char * strrchr(const char * s, int c);
+
+#define __HAVE_ARCH_STRCHR
+extern char * strchr(const char * s, int c);
+
+#define __HAVE_ARCH_MEMCPY
+extern void * memcpy(void *, const void *, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMMOVE
+extern void * memmove(void *, const void *, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMCHR
+extern void * memchr(const void *, int, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMZERO
+#define __HAVE_ARCH_MEMSET
+extern void * memset(void *, int, __kernel_size_t);
+
+extern void __memzero(void *ptr, __kernel_size_t n);
+
+#define memset(p,v,n)							\
+	({								\
+		if ((n) != 0) {						\
+			if (__builtin_constant_p((v)) && (v) == 0)	\
+				__memzero((p),(n));			\
+			else						\
+				memset((p),(v),(n));			\
+		}							\
+		(p);							\
+	})
+
+#define memzero(p,n) ({ if ((n) != 0) __memzero((p),(n)); (p); })
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/system.h linux-2.4.29-uc1/include/asm-armnommu/system.h
--- linux-2.4.29/include/asm-armnommu/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/system.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,95 @@
+#ifndef __ASM_ARM_SYSTEM_H
+#define __ASM_ARM_SYSTEM_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+
+/* information about the system we're running on */
+extern unsigned int system_rev;
+extern unsigned int system_serial_low;
+extern unsigned int system_serial_high;
+extern unsigned int mem_fclk_21285;
+
+/*
+ * This tells us if we have an ISA bridge
+ * present in a PCI system.
+ */
+#ifdef CONFIG_PCI
+extern int have_isa_bridge;
+#else
+#define have_isa_bridge		(0)
+#endif
+
+#include <asm/proc-fns.h>
+
+#define xchg(ptr,x) \
+	((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+
+#define tas(ptr) (xchg((ptr),1))
+
+extern asmlinkage void __backtrace(void);
+
+/*
+ * Include processor dependent parts
+ */
+#include <asm/proc/system.h>
+
+#define mb() __asm__ __volatile__ ("" : : : "memory")
+#define rmb() mb()
+#define wmb() mb()
+#define set_mb(var, value)  do { var = value; mb(); } while (0)
+#define set_wmb(var, value) do { var = value; wmb(); } while (0)
+#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
+
+#define prepare_to_switch()    do { } while(0)
+
+/*
+ * switch_to(prev, next) should switch from task `prev' to `next'
+ * `prev' will never be the same as `next'.
+ * The `mb' is to tell GCC not to cache `current' across this call.
+ */
+extern struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *next);
+
+#define switch_to(prev,next,last)		\
+	do {			 		\
+		last = __switch_to(prev,next);	\
+		mb();				\
+	} while (0)
+
+/* For spinlocks etc */
+#define local_irq_save(x)	__save_flags_cli(x)
+#define local_irq_set(x)	__save_flags_sti(x)
+#define local_irq_restore(x)	__restore_flags(x)
+#define local_irq_disable()	__cli()
+#define local_irq_enable()	__sti()
+
+#ifdef CONFIG_SMP
+#error SMP not supported
+
+#define smp_mb()		mb()
+#define smp_rmb()		rmb()
+#define smp_wmb()		wmb()
+
+#else
+
+#define smp_mb()		barrier()
+#define smp_rmb()		barrier()
+#define smp_wmb()		barrier()
+
+#define cli()			__cli()
+#define sti()			__sti()
+#define clf()			__clf()
+#define stf()			__stf()
+#define save_flags(x)		__save_flags(x)
+#define restore_flags(x)	__restore_flags(x)
+#define save_flags_cli(x)	__save_flags_cli(x)
+#define save_and_cli(x)		__save_flags_cli(x)
+#define save_and_set(x)		__save_flags_sti(x)
+
+#endif /* CONFIG_SMP */
+
+#endif /* __KERNEL__ */
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/termbits.h linux-2.4.29-uc1/include/asm-armnommu/termbits.h
--- linux-2.4.29/include/asm-armnommu/termbits.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/termbits.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,170 @@
+#ifndef __ASM_ARM_TERMBITS_H
+#define __ASM_ARM_TERMBITS_H
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#define NCCS 19
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IUCLC	0001000
+#define IXON	0002000
+#define IXANY	0004000
+#define IXOFF	0010000
+#define IMAXBEL	0020000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define OLCUC	0000002
+#define ONLCR	0000004
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#define NLDLY	0000400
+#define   NL0	0000000
+#define   NL1	0000400
+#define CRDLY	0003000
+#define   CR0	0000000
+#define   CR1	0001000
+#define   CR2	0002000
+#define   CR3	0003000
+#define TABDLY	0014000
+#define   TAB0	0000000
+#define   TAB1	0004000
+#define   TAB2	0010000
+#define   TAB3	0014000
+#define   XTABS	0014000
+#define BSDLY	0020000
+#define   BS0	0000000
+#define   BS1	0020000
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+#define FFDLY	0100000
+#define   FF0	0000000
+#define   FF1	0100000
+
+/* c_cflag bit meaning */
+#define CBAUD	0010017
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE	0000060
+#define   CS5	0000000
+#define   CS6	0000020
+#define   CS7	0000040
+#define   CS8	0000060
+#define CSTOPB	0000100
+#define CREAD	0000200
+#define PARENB	0000400
+#define PARODD	0001000
+#define HUPCL	0002000
+#define CLOCAL	0004000
+#define CBAUDEX 0010000
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+#define CIBAUD	  002003600000	/* input baud rate (not used) */
+#define CMSPAR    010000000000		/* mark or space (stick) parity */
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+#define ISIG	0000001
+#define ICANON	0000002
+#define XCASE	0000004
+#define ECHO	0000010
+#define ECHOE	0000020
+#define ECHOK	0000040
+#define ECHONL	0000100
+#define NOFLSH	0000200
+#define TOSTOP	0000400
+#define ECHOCTL	0001000
+#define ECHOPRT	0002000
+#define ECHOKE	0004000
+#define FLUSHO	0010000
+#define PENDIN	0040000
+#define IEXTEN	0100000
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif	/* __ASM_ARM_TERMBITS_H */
diff -urN linux-2.4.29/include/asm-armnommu/termios.h linux-2.4.29-uc1/include/asm-armnommu/termios.h
--- linux-2.4.29/include/asm-armnommu/termios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/termios.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,108 @@
+#ifndef __ASM_ARM_TERMIOS_H
+#define __ASM_ARM_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+#ifdef __KERNEL__
+/*	intr=^C		quit=^|		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+#endif
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6	/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14
+#define N_HCI		15  /* Bluetooth HCI UART */
+
+#ifdef __KERNEL__
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) {		\
+	unsigned short __tmp;					\
+	get_user(__tmp,&(termio)->x);				\
+	*(unsigned short *) &(termios)->x = __tmp;		\
+}
+
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif	/* __KERNEL__ */
+
+#endif	/* __ASM_ARM_TERMIOS_H */
diff -urN linux-2.4.29/include/asm-armnommu/therm.h linux-2.4.29-uc1/include/asm-armnommu/therm.h
--- linux-2.4.29/include/asm-armnommu/therm.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/therm.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ * linux/include/asm-arm/therm.h: Definitions for Dallas Semiconductor
+ *  DS1620 thermometer driver (as used in the Rebel.com NetWinder)
+ */
+#ifndef __ASM_THERM_H
+#define __ASM_THERM_H
+
+/* ioctl numbers for /dev/therm */
+#define CMD_SET_THERMOSTATE	0x53
+#define CMD_GET_THERMOSTATE	0x54
+#define CMD_GET_STATUS		0x56
+#define CMD_GET_TEMPERATURE	0x57
+#define CMD_SET_THERMOSTATE2	0x58
+#define CMD_GET_THERMOSTATE2	0x59
+#define CMD_GET_TEMPERATURE2	0x5a
+#define CMD_GET_FAN		0x5b
+#define CMD_SET_FAN		0x5c
+
+#define FAN_OFF			0
+#define FAN_ON			1
+#define FAN_ALWAYS_ON		2
+
+struct therm {
+	int hi;
+	int lo;
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/timex.h linux-2.4.29-uc1/include/asm-armnommu/timex.h
--- linux-2.4.29/include/asm-armnommu/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/timex.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,29 @@
+/*
+ *  linux/include/asm-arm/timex.h
+ *
+ *  Copyright (C) 1997,1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Architecture Specific TIME specifications
+ */
+#ifndef _ASMARM_TIMEX_H
+#define _ASMARM_TIMEX_H
+
+#include <asm/arch/timex.h>
+
+typedef unsigned long cycles_t;
+
+extern cycles_t cacheflush_time;
+
+static inline cycles_t get_cycles (void)
+{
+	return 0;
+}
+
+#define vxtime_lock()		do {} while (0)
+#define vxtime_unlock()		do {} while (0)
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/tlb.h linux-2.4.29-uc1/include/asm-armnommu/tlb.h
--- linux-2.4.29/include/asm-armnommu/tlb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/tlb.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-arm/tlb.h>
diff -urN linux-2.4.29/include/asm-armnommu/types.h linux-2.4.29-uc1/include/asm-armnommu/types.h
--- linux-2.4.29/include/asm-armnommu/types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/types.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,52 @@
+#ifndef __ASM_ARM_TYPES_H
+#define __ASM_ARM_TYPES_H
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide.  */
+
+typedef u32 dma_addr_t;
+typedef u32 dma64_addr_t;
+
+#endif /* __KERNEL__ */
+
+#endif
+
diff -urN linux-2.4.29/include/asm-armnommu/uaccess.h linux-2.4.29-uc1/include/asm-armnommu/uaccess.h
--- linux-2.4.29/include/asm-armnommu/uaccess.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/uaccess.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,238 @@
+#ifndef _ASMARM_UACCESS_H
+#define _ASMARM_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <asm/errno.h>
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+#define get_ds()	(KERNEL_DS)
+#define get_fs()	(USER_DS) /* copied m68knommu --gmcnutt */
+#define segment_eq(a,b)	((a) == (b))
+
+#include <asm/proc/uaccess.h>
+
+/*
+ * REVISIT_gjm -- access_ok
+ *         Lots of drivers use this. __range_ok is going to try and used the
+ *         current->addr_limit setting as a check. I don't know that we ever
+ *         set that up the way it expects it.
+ */
+#define access_ok(type,addr,size)	(__range_ok(addr,size) == 0)
+
+extern __inline__ int verify_area(int type, const void * addr, unsigned long size)
+{
+	return access_ok(type, addr, size) ? 0 : -EFAULT;
+}
+
+/*
+ * Single-value transfer routines.  They automatically use the right
+ * size if we just have the right pointer type.  Note that the functions
+ * which read from user space (*get_*) need to take care not to leak
+ * kernel data even if the calling code is buggy and fails to check
+ * the return value.  This means zeroing out the destination variable
+ * or buffer on error.  Normally this is done out of line by the
+ * fixup code, but there are a few places where it intrudes on the
+ * main code path.  When we only write to user space, there is no
+ * problem.
+ *
+ * The "__xxx" versions of the user access functions do not verify the
+ * address space - it must have been done previously with a separate
+ * "access_ok()" call.
+ *
+ * The "xxx_error" versions set the third argument to EFAULT if an
+ * error occurs, and leave it unchanged on success.  Note that these
+ * versions are void (ie, don't return a value as such).
+ */
+#define get_user(x,p)		__get_user_check((x),(p),sizeof(*(p)))
+#define __get_user(x,p)		__get_user_nocheck((x),(p),sizeof(*(p)))
+#define __get_user_error(x,p,e)	__get_user_nocheck_error((x),(p),sizeof(*(p)),(e))
+
+#define put_user(x,p)		__put_user_check((__typeof(*(p)))(x),(p),sizeof(*(p)))
+#define __put_user(x,p)		__put_user_nocheck((__typeof(*(p)))(x),(p),sizeof(*(p)))
+#define __put_user_error(x,p,e)	__put_user_nocheck_error((x),(p),sizeof(*(p)),(e))
+
+static __inline__ unsigned long copy_from_user(void *to, const void *from, unsigned long n)
+{
+	if (access_ok(VERIFY_READ, from, n))
+		__do_copy_from_user(to, from, n);
+	else /* security hole */
+	  memzero(to, n);
+	return n;
+}
+
+static __inline__ unsigned long __copy_from_user(void *to, const void *from, unsigned long n)
+{
+	__do_copy_from_user(to, from, n);
+	return n;
+}
+
+static __inline__ unsigned long copy_to_user(void *to, const void *from, unsigned long n)
+{
+	if (access_ok(VERIFY_WRITE, to, n))
+		__do_copy_to_user(to, from, n);
+	return n;
+}
+
+static __inline__ unsigned long __copy_to_user(void *to, const void *from, unsigned long n)
+{
+	__do_copy_to_user(to, from, n);
+	return n;
+}
+
+static __inline__ unsigned long clear_user (void *to, unsigned long n)
+{
+	if (access_ok(VERIFY_WRITE, to, n))
+		__do_clear_user(to, n);
+	return n;
+}
+
+static __inline__ unsigned long __clear_user (void *to, unsigned long n)
+{
+	__do_clear_user(to, n);
+	return n;
+}
+
+static __inline__ long strncpy_from_user (char *dst, const char *src, long count)
+{
+	long res = -EFAULT;
+	if (access_ok(VERIFY_READ, src, 1))
+		__do_strncpy_from_user(dst, src, count, res);
+	return res;
+}
+
+static __inline__ long __strncpy_from_user (char *dst, const char *src, long count)
+{
+	long res;
+	__do_strncpy_from_user(dst, src, count, res);
+	return res;
+}
+
+#define strlen_user(s)	strnlen_user(s, ~0UL >> 1)
+
+/* FIXME: was defined as "extern", and used __addr_ok (??) -rp */
+static __inline__ long strnlen_user(const char *s, long n)
+{
+	unsigned long res = 0;
+
+	if (access_ok(VERIFY_READ, s, 1))
+		__do_strnlen_user(s, n, res);
+
+	return res;
+}
+
+/*
+ * These are the work horses of the get/put_user functions
+ */
+#define __get_user_check(x,ptr,size)					\
+({									\
+	long __gu_err = -EFAULT, __gu_val = 0;				\
+	const __typeof__(*(ptr)) *__gu_addr = (ptr);			\
+	if (access_ok(VERIFY_READ,__gu_addr,size)) {			\
+		__gu_err = 0;						\
+		__get_user_size(__gu_val,__gu_addr,(size),__gu_err);	\
+	}								\
+	(x) = (__typeof__(*(ptr)))__gu_val;				\
+	__gu_err;							\
+})
+
+#define __get_user_nocheck(x,ptr,size)					\
+({									\
+	long __gu_err = 0, __gu_val;					\
+	__get_user_size(__gu_val,(ptr),(size),__gu_err);		\
+	(x) = (__typeof__(*(ptr)))__gu_val;				\
+	__gu_err;							\
+})
+
+#define __get_user_nocheck_error(x,ptr,size,err)			\
+({									\
+	long __gu_val;							\
+	__get_user_size(__gu_val,(ptr),(size),(err));			\
+	(x) = (__typeof__(*(ptr)))__gu_val;				\
+	(void) 0;							\
+})
+
+#define __put_user_check(x,ptr,size)					\
+({									\
+	long __pu_err = -EFAULT;					\
+	__typeof__(*(ptr)) *__pu_addr = (ptr);				\
+	if (access_ok(VERIFY_WRITE,__pu_addr,size)) {			\
+		__pu_err = 0;						\
+		__put_user_size((x),__pu_addr,(size),__pu_err);		\
+	}								\
+	__pu_err;							\
+})
+
+#define __put_user_nocheck(x,ptr,size)					\
+({									\
+	long __pu_err = 0;						\
+	__typeof__(*(ptr)) *__pu_addr = (ptr);				\
+	__put_user_size((x),__pu_addr,(size),__pu_err);			\
+	__pu_err;							\
+})
+
+#define __put_user_nocheck_error(x,ptr,size,err)			\
+({									\
+	__put_user_size((x),(ptr),(size),err);				\
+	(void) 0;							\
+})
+
+extern long __get_user_bad(void);
+
+#define __get_user_size(x,ptr,size,retval)				\
+do {									\
+	switch (size) {							\
+	case 1:	__get_user_asm_byte(x,ptr,retval);	break;		\
+	case 2:	__get_user_asm_half(x,ptr,retval);	break;		\
+	case 4:	__get_user_asm_word(x,ptr,retval);	break;		\
+	case 8: {							\
+		typeof(*(ptr)) __gu_val;				\
+		memcpy(&__gu_val, ptr, sizeof(__gu_val));		\
+		(x) = __gu_val;						\
+		} break;						\
+	default: (x) = __get_user_bad();				\
+	}								\
+} while (0)
+
+extern long __put_user_bad(void);
+
+#define __put_user_size(x,ptr,size,retval)				\
+do {									\
+	switch (size) {							\
+	case 1: __put_user_asm_byte(x,ptr,retval);	break;		\
+	case 2: __put_user_asm_half(x,ptr,retval);	break;		\
+	case 4: __put_user_asm_word(x,ptr,retval);	break;		\
+	case 8: {							\
+		typeof(*(ptr)) __gu_val = (x);				\
+		memcpy(ptr, &__gu_val, sizeof(__gu_val));		\
+		} break;						\
+	default: __put_user_bad();					\
+	}								\
+} while (0)
+
+#endif /* _ASMARM_UACCESS_H */
diff -urN linux-2.4.29/include/asm-armnommu/uCbootstrap.h linux-2.4.29-uc1/include/asm-armnommu/uCbootstrap.h
--- linux-2.4.29/include/asm-armnommu/uCbootstrap.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/uCbootstrap.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,180 @@
+/* uCbootstrap.h:  Bootloader system call interface
+ *
+ * (c) 2002 Arcturus networks, Inc.
+ *
+ *  ARM7TDMI support by O.Zhadan,  2001
+ *  ( used undefined instruction trap )
+ */
+
+#ifndef __UCBOOTSTRAP_H__
+#define __UCBOOTSTRAP_H__
+
+#define NR_BSC 23            /* last used bootloader system call */
+
+#define __BN_reset        	0  /* reset and start the bootloader */
+#define __BN_test         	1  /* tests the system call interface */
+#define __BN_exec         	2  /* executes a bootloader image */
+#define __BN_exit         	3  /* terminates a bootloader image */
+#define __BN_program      	4  /* program FLASH from a chain */
+#define __BN_erase        	5  /* erase sector(s) of FLASH */
+#define __BN_open         	6
+#define __BN_write        	7
+#define __BN_read         	8
+#define __BN_close        	9
+#define __BN_mmap         	10 /* map a file descriptor into memory */
+#define __BN_munmap       	11 /* remove a file to memory mapping */
+#define __BN_gethwaddr    	12 /* get the hardware address of my interfaces */
+#define __BN_getserialnum 	13 /* get the serial number of this board */
+#define __BN_getbenv      	14 /* get a bootloader envvar */
+#define __BN_setbenv      	15 /* get a bootloader envvar */
+#define __BN_setpmask     	16 /* set the protection mask */
+#define __BN_readbenv      	17 /* read environment variables */
+#define __BN_flash_chattr_range	18
+#define __BN_flash_erase_range	19
+#define __BN_flash_write_range	20
+#define __BN_ramload            21 /* load kernel into RAM and exec */
+#define __BN_program2      	22  /* program second FLASH from a chain */
+
+/* Calling conventions for (uC)linux
+ */
+
+#define __bsc_return(type, res) \
+do { \
+   if ((unsigned int)(res) >= (unsigned int)(-64)) { \
+      /* let errno be a function, preserve res in %r0 */ \
+      int __err = -(res); \
+      errno = __err; \
+      res = -1; \
+   } \
+   return (type)(res); \
+} while (0)
+
+#define _bsc0(type,name) \
+type name(void) \
+{ \
+   register unsigned int __res __asm__ ("%sl") = __BN_##name; \
+   __asm__ __volatile__ (".word 0xe65a4f10; mov sl, r0" \
+                         : "=g" (__res) \
+                         : "0"  (__res) \
+                         : "%r0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc1(type,name,atype,a) \
+type name(atype a) \
+{ \
+   register unsigned int __res __asm__ ("%sl") = __BN_##name; \
+   __asm__ __volatile__ (".word 0xe65a4f10; mov sl, r0" \
+                         : "=g" (__res) \
+                         : "0"  (__res) \
+                         : "%r0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc2(type,name,atype,a,btype,b) \
+type name(atype a, btype b) \
+{ \
+   register unsigned int __res __asm__ ("%sl") = __BN_##name; \
+   __asm__ __volatile__ (".word 0xe65a4f10; mov sl, r0" \
+                         : "=g" (__res) \
+                         : "0"  (__res) \
+                         : "%r0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc3(type,name,atype,a,btype,b,ctype,c) \
+type name(atype a, btype b, ctype c) \
+{ \
+   register unsigned int __res __asm__ ("%sl") = __BN_##name; \
+   __asm__ __volatile__ (".word 0xe65a4f10; mov sl, r0" \
+                         : "=g" (__res) \
+                         : "0"  (__res) \
+                         : "%r0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
+type name(atype a, btype b, ctype c, dtype d) \
+{ \
+   register unsigned int __res __asm__ ("%sl") = __BN_##name; \
+   __asm__ __volatile__ (".word 0xe65a4f10; mov sl, r0" \
+                         : "=g" (__res) \
+                         : "0"  (__res) \
+                         : "%r0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
+type name(atype a, btype b, ctype c, dtype d, etype e) \
+{ \
+   register unsigned int __e   __asm__ ("%r4") = e; \
+   register unsigned int __res __asm__ ("%sl") = __BN_##name; \
+   __asm__ __volatile__ (".word 0xe65A4F10; mov sl, r0" \
+                         : "=g" (__res) \
+                         : "0"  (__res) \
+                         : "%r0"); \
+   __bsc_return(type,__res); \
+}
+
+/* Command codes for the flash_command routine */
+#define FLASH_SELECT    0       /* no command; just perform the mapping */
+#define FLASH_RESET     1       /* reset to read mode */
+#define FLASH_READ      1       /* reset to read mode, by any other name */
+#define FLASH_AUTOSEL   2       /* autoselect (fake Vid on pin 9) */
+#define FLASH_PROG      3       /* program a word */
+#define FLASH_CERASE    4       /* chip erase */
+#define FLASH_SERASE    5       /* sector erase */
+#define FLASH_ESUSPEND  6       /* suspend sector erase */
+#define FLASH_ERESUME   7       /* resume sector erase */
+#define FLASH_UB        8       /* go into unlock bypass mode */
+#define FLASH_UBPROG    9       /* program a word using unlock bypass */
+#define FLASH_UBRESET   10      /* reset to read mode from unlock bypass mode */
+#define FLASH_LASTCMD   10      /* used for parameter checking */
+
+/* Return codes from flash_status */
+#define STATUS_READY    0       /* ready for action */
+#define STATUS_BUSY     1       /* operation in progress */
+#define STATUS_ERSUSP   2       /* erase suspended */
+#define STATUS_TIMEOUT  3       /* operation timed out */
+#define STATUS_ERROR    4       /* unclassified but unhappy status */
+
+/* manufacturer ID */
+#define AMDPART   	0x01
+#define TOSPART		0x98
+#define SSTPART		0xbf
+#define ATPART		0x1f
+
+/* A list of 4 AMD device ID's - add others as needed */
+#define ID_AM29DL800T   0x224A
+#define ID_AM29DL800B   0x22CB
+#define ID_AM29LV800T   0x22DA
+#define ID_AM29LV800B   0x225B
+#define ID_AM29LV160B   0x2249
+#define ID_AM29LV160T   0x22C4
+#define ID_TC58FVT160	0x00C2
+#define ID_TC58FVB160	0x0043
+#define ID_TC58FVB160X2	0x00430043
+#define ID_AM29LV400B   0x22BA
+#define ID_AT49BV1614   0x00C0
+#define ID_SST39VF160   0x2782
+/* definition for arm7tdni */
+#define ID_AT27LV1024	0x0000
+#define ID_AT29LV1024	0x0001
+
+#define SECTOR_DIRTY   0x01
+#define SECTOR_ERASED  0x02
+#define SECTOR_PROTECT 0x04
+
+#define PGM_ERASE_FIRST 0x0001
+#define PGM_RESET_AFTER 0x0002
+#define PGM_EXEC_AFTER  0x0004
+#define PGM_HALT_AFTER  0x0008
+#define PGM_DEBUG       0x0010
+
+/* an mnode points at 4k pages of data through an offset table. */
+typedef struct _memnode {
+  int len;
+  int *offset;
+} mnode_t;
+
+#endif /* __UCBOOTSTRAP_H__ */
diff -urN linux-2.4.29/include/asm-armnommu/ucontext.h linux-2.4.29-uc1/include/asm-armnommu/ucontext.h
--- linux-2.4.29/include/asm-armnommu/ucontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/ucontext.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef _ASMARM_UCONTEXT_H
+#define _ASMARM_UCONTEXT_H
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct sigcontext uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif /* !_ASMARM_UCONTEXT_H */
diff -urN linux-2.4.29/include/asm-armnommu/unaligned.h linux-2.4.29-uc1/include/asm-armnommu/unaligned.h
--- linux-2.4.29/include/asm-armnommu/unaligned.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/unaligned.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,140 @@
+#ifndef __ASM_ARM_UNALIGNED_H
+#define __ASM_ARM_UNALIGNED_H
+
+#include <asm/types.h>
+
+extern int __bug_unaligned_x(void *ptr);
+
+/*
+ * What is the most efficient way of loading/storing an unaligned value?
+ *
+ * That is the subject of this file.  Efficiency here is defined as
+ * minimum code size with minimum register usage for the common cases.
+ * It is currently not believed that long longs are common, so we
+ * trade efficiency for the chars, shorts and longs against the long
+ * longs.
+ *
+ * Current stats with gcc 2.7.2.2 for these functions:
+ *
+ *	ptrsize	get:	code	regs	put:	code	regs
+ *	1		1	1		1	2
+ *	2		3	2		3	2
+ *	4		7	3		7	3
+ *	8		20	6		16	6
+ *
+ * gcc 2.95.1 seems to code differently:
+ *
+ *	ptrsize	get:	code	regs	put:	code	regs
+ *	1		1	1		1	2
+ *	2		3	2		3	2
+ *	4		7	4		7	4
+ *	8		19	8		15	6
+ *
+ * which may or may not be more efficient (depending upon whether
+ * you can afford the extra registers).  Hopefully the gcc 2.95
+ * is inteligent enough to decide if it is better to use the
+ * extra register, but evidence so far seems to suggest otherwise.
+ *
+ * Unfortunately, gcc is not able to optimise the high word
+ * out of long long >> 32, or the low word from long long << 32
+ */
+
+#ifdef __ARMEB__
+#define S_BYTE_0 1
+#define S_BYTE_1 0
+#define L_BYTE_0 3
+#define L_BYTE_1 2
+#define L_BYTE_2 1
+#define L_BYTE_3 0
+#else
+#define S_BYTE_0 0
+#define S_BYTE_1 1
+#define L_BYTE_0 0
+#define L_BYTE_1 1
+#define L_BYTE_2 2
+#define L_BYTE_3 3
+#endif
+
+#define __get_unaligned_2(__p)					\
+	(__p[S_BYTE_0] | __p[S_BYTE_1] << 8)
+
+#define __get_unaligned_4(__p)					\
+	(__p[L_BYTE_0] | __p[L_BYTE_1] << 8 | __p[L_BYTE_2] << 16 | __p[L_BYTE_3] << 24)
+
+#define get_unaligned(ptr)					\
+	({							\
+		__typeof__(*(ptr)) __v;				\
+		__u8 *__p = (__u8 *)(ptr);			\
+		switch (sizeof(*(ptr))) {			\
+		case 1:	__v = *(ptr);			break;	\
+		case 2: __v = __get_unaligned_2(__p);	break;	\
+		case 4: __v = __get_unaligned_4(__p);	break;	\
+		case 8: {					\
+				unsigned int __v1, __v2;	\
+				__v2 = __get_unaligned_4((__p+4)); \
+				__v1 = __get_unaligned_4(__p);	\
+				__v = ((unsigned long long)__v2 << 32 | __v1);	\
+			}					\
+			break;					\
+		default: __v = __bug_unaligned_x(__p);	break;	\
+		}						\
+		__v;						\
+	})
+
+
+static inline void __put_unaligned_2(__u32 __v, register __u8 *__p)
+{
+#ifdef __ARMEB__
+	*__p++ = __v >> 8;
+	*__p++ = __v;
+#else
+	*__p++ = __v;
+	*__p++ = __v >> 8;
+#endif
+}
+
+static inline void __put_unaligned_4(__u32 __v, register __u8 *__p)
+{
+#ifdef __ARMEB__
+	__put_unaligned_2(__v >> 16, __p);
+	__put_unaligned_2(__v, __p + 2);
+#else
+	__put_unaligned_2(__v >> 16, __p + 2);
+	__put_unaligned_2(__v, __p);
+#endif
+}
+
+static inline void __put_unaligned_8(const unsigned long long __v, register __u8 *__p)
+{
+	/*
+	 * tradeoff: 8 bytes of stack for all unaligned puts (2
+	 * instructions), or an extra register in the long long
+	 * case - go for the extra register.
+	 */
+	__put_unaligned_4(__v >> 32, __p+4);
+	__put_unaligned_4(__v, __p);
+}
+
+/*
+ * Try to store an unaligned value as efficiently as possible.
+ */
+#define put_unaligned(val,ptr)					\
+	({							\
+		switch (sizeof(*(ptr))) {			\
+		case 1:						\
+			*(ptr) = (val);				\
+			break;					\
+		case 2: __put_unaligned_2((val),(__u8 *)(ptr));	\
+			break;					\
+		case 4:	__put_unaligned_4((val),(__u8 *)(ptr));	\
+			break;					\
+		case 8:	__put_unaligned_8((val),(__u8 *)(ptr)); \
+			break;					\
+		default: __bug_unaligned_x(ptr);		\
+			break;					\
+		}						\
+		(void) 0;					\
+	})
+
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/unistd.h linux-2.4.29-uc1/include/asm-armnommu/unistd.h
--- linux-2.4.29/include/asm-armnommu/unistd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/unistd.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,452 @@
+/*
+ *  linux/include/asm-arm/unistd.h
+ *
+ *  Copyright (C) 2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ***  N O T E  ***
+ *
+ * Please do not fsck with this file.  Instead, if you want to make changes
+ * send them by email to rmk@arm.linux.org.uk.  I do not want to fix this
+ * file in the middle of a stable kernel series.
+ */
+#ifndef __ASM_ARM_UNISTD_H
+#define __ASM_ARM_UNISTD_H
+
+#define __NR_SYSCALL_BASE	0x900000
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_exit			(__NR_SYSCALL_BASE+  1)
+#define __NR_fork			(__NR_SYSCALL_BASE+  2)
+#define __NR_read			(__NR_SYSCALL_BASE+  3)
+#define __NR_write			(__NR_SYSCALL_BASE+  4)
+#define __NR_open			(__NR_SYSCALL_BASE+  5)
+#define __NR_close			(__NR_SYSCALL_BASE+  6)
+#define __NR_waitpid			(__NR_SYSCALL_BASE+  7)
+#define __NR_creat			(__NR_SYSCALL_BASE+  8)
+#define __NR_link			(__NR_SYSCALL_BASE+  9)
+#define __NR_unlink			(__NR_SYSCALL_BASE+ 10)
+#define __NR_execve			(__NR_SYSCALL_BASE+ 11)
+#define __NR_chdir			(__NR_SYSCALL_BASE+ 12)
+#define __NR_time			(__NR_SYSCALL_BASE+ 13)
+#define __NR_mknod			(__NR_SYSCALL_BASE+ 14)
+#define __NR_chmod			(__NR_SYSCALL_BASE+ 15)
+#define __NR_lchown			(__NR_SYSCALL_BASE+ 16)
+#define __NR_break			(__NR_SYSCALL_BASE+ 17)
+
+#define __NR_lseek			(__NR_SYSCALL_BASE+ 19)
+#define __NR_getpid			(__NR_SYSCALL_BASE+ 20)
+#define __NR_mount			(__NR_SYSCALL_BASE+ 21)
+#define __NR_umount			(__NR_SYSCALL_BASE+ 22)
+#define __NR_setuid			(__NR_SYSCALL_BASE+ 23)
+#define __NR_getuid			(__NR_SYSCALL_BASE+ 24)
+#define __NR_stime			(__NR_SYSCALL_BASE+ 25)
+#define __NR_ptrace			(__NR_SYSCALL_BASE+ 26)
+#define __NR_alarm			(__NR_SYSCALL_BASE+ 27)
+
+#define __NR_pause			(__NR_SYSCALL_BASE+ 29)
+#define __NR_utime			(__NR_SYSCALL_BASE+ 30)
+#define __NR_stty			(__NR_SYSCALL_BASE+ 31)
+#define __NR_gtty			(__NR_SYSCALL_BASE+ 32)
+#define __NR_access			(__NR_SYSCALL_BASE+ 33)
+#define __NR_nice			(__NR_SYSCALL_BASE+ 34)
+#define __NR_ftime			(__NR_SYSCALL_BASE+ 35)
+#define __NR_sync			(__NR_SYSCALL_BASE+ 36)
+#define __NR_kill			(__NR_SYSCALL_BASE+ 37)
+#define __NR_rename			(__NR_SYSCALL_BASE+ 38)
+#define __NR_mkdir			(__NR_SYSCALL_BASE+ 39)
+#define __NR_rmdir			(__NR_SYSCALL_BASE+ 40)
+#define __NR_dup			(__NR_SYSCALL_BASE+ 41)
+#define __NR_pipe			(__NR_SYSCALL_BASE+ 42)
+#define __NR_times			(__NR_SYSCALL_BASE+ 43)
+#define __NR_prof			(__NR_SYSCALL_BASE+ 44)
+#define __NR_brk			(__NR_SYSCALL_BASE+ 45)
+#define __NR_setgid			(__NR_SYSCALL_BASE+ 46)
+#define __NR_getgid			(__NR_SYSCALL_BASE+ 47)
+#define __NR_signal			(__NR_SYSCALL_BASE+ 48)
+#define __NR_geteuid			(__NR_SYSCALL_BASE+ 49)
+#define __NR_getegid			(__NR_SYSCALL_BASE+ 50)
+#define __NR_acct			(__NR_SYSCALL_BASE+ 51)
+#define __NR_umount2			(__NR_SYSCALL_BASE+ 52)
+#define __NR_lock			(__NR_SYSCALL_BASE+ 53)
+#define __NR_ioctl			(__NR_SYSCALL_BASE+ 54)
+#define __NR_fcntl			(__NR_SYSCALL_BASE+ 55)
+#define __NR_mpx			(__NR_SYSCALL_BASE+ 56)
+#define __NR_setpgid			(__NR_SYSCALL_BASE+ 57)
+#define __NR_ulimit			(__NR_SYSCALL_BASE+ 58)
+
+#define __NR_umask			(__NR_SYSCALL_BASE+ 60)
+#define __NR_chroot			(__NR_SYSCALL_BASE+ 61)
+#define __NR_ustat			(__NR_SYSCALL_BASE+ 62)
+#define __NR_dup2			(__NR_SYSCALL_BASE+ 63)
+#define __NR_getppid			(__NR_SYSCALL_BASE+ 64)
+#define __NR_getpgrp			(__NR_SYSCALL_BASE+ 65)
+#define __NR_setsid			(__NR_SYSCALL_BASE+ 66)
+#define __NR_sigaction			(__NR_SYSCALL_BASE+ 67)
+#define __NR_sgetmask			(__NR_SYSCALL_BASE+ 68)
+#define __NR_ssetmask			(__NR_SYSCALL_BASE+ 69)
+#define __NR_setreuid			(__NR_SYSCALL_BASE+ 70)
+#define __NR_setregid			(__NR_SYSCALL_BASE+ 71)
+#define __NR_sigsuspend			(__NR_SYSCALL_BASE+ 72)
+#define __NR_sigpending			(__NR_SYSCALL_BASE+ 73)
+#define __NR_sethostname		(__NR_SYSCALL_BASE+ 74)
+#define __NR_setrlimit			(__NR_SYSCALL_BASE+ 75)
+#define __NR_getrlimit			(__NR_SYSCALL_BASE+ 76)	/* Back compat 2GB limited rlimit */
+#define __NR_getrusage			(__NR_SYSCALL_BASE+ 77)
+#define __NR_gettimeofday		(__NR_SYSCALL_BASE+ 78)
+#define __NR_settimeofday		(__NR_SYSCALL_BASE+ 79)
+#define __NR_getgroups			(__NR_SYSCALL_BASE+ 80)
+#define __NR_setgroups			(__NR_SYSCALL_BASE+ 81)
+#define __NR_select			(__NR_SYSCALL_BASE+ 82)
+#define __NR_symlink			(__NR_SYSCALL_BASE+ 83)
+
+#define __NR_readlink			(__NR_SYSCALL_BASE+ 85)
+#define __NR_uselib			(__NR_SYSCALL_BASE+ 86)
+#define __NR_swapon			(__NR_SYSCALL_BASE+ 87)
+#define __NR_reboot			(__NR_SYSCALL_BASE+ 88)
+#define __NR_readdir			(__NR_SYSCALL_BASE+ 89)
+#define __NR_mmap			(__NR_SYSCALL_BASE+ 90)
+#define __NR_munmap			(__NR_SYSCALL_BASE+ 91)
+#define __NR_truncate			(__NR_SYSCALL_BASE+ 92)
+#define __NR_ftruncate			(__NR_SYSCALL_BASE+ 93)
+#define __NR_fchmod			(__NR_SYSCALL_BASE+ 94)
+#define __NR_fchown			(__NR_SYSCALL_BASE+ 95)
+#define __NR_getpriority		(__NR_SYSCALL_BASE+ 96)
+#define __NR_setpriority		(__NR_SYSCALL_BASE+ 97)
+#define __NR_profil			(__NR_SYSCALL_BASE+ 98)
+#define __NR_statfs			(__NR_SYSCALL_BASE+ 99)
+#define __NR_fstatfs			(__NR_SYSCALL_BASE+100)
+#define __NR_ioperm			(__NR_SYSCALL_BASE+101)
+#define __NR_socketcall			(__NR_SYSCALL_BASE+102)
+#define __NR_syslog			(__NR_SYSCALL_BASE+103)
+#define __NR_setitimer			(__NR_SYSCALL_BASE+104)
+#define __NR_getitimer			(__NR_SYSCALL_BASE+105)
+#define __NR_stat			(__NR_SYSCALL_BASE+106)
+#define __NR_lstat			(__NR_SYSCALL_BASE+107)
+#define __NR_fstat			(__NR_SYSCALL_BASE+108)
+
+
+#define __NR_vhangup			(__NR_SYSCALL_BASE+111)
+#define __NR_idle			(__NR_SYSCALL_BASE+112)
+#define __NR_syscall			(__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */
+#define __NR_wait4			(__NR_SYSCALL_BASE+114)
+#define __NR_swapoff			(__NR_SYSCALL_BASE+115)
+#define __NR_sysinfo			(__NR_SYSCALL_BASE+116)
+#define __NR_ipc			(__NR_SYSCALL_BASE+117)
+#define __NR_fsync			(__NR_SYSCALL_BASE+118)
+#define __NR_sigreturn			(__NR_SYSCALL_BASE+119)
+#define __NR_clone			(__NR_SYSCALL_BASE+120)
+#define __NR_setdomainname		(__NR_SYSCALL_BASE+121)
+#define __NR_uname			(__NR_SYSCALL_BASE+122)
+#define __NR_modify_ldt			(__NR_SYSCALL_BASE+123)
+#define __NR_adjtimex			(__NR_SYSCALL_BASE+124)
+#define __NR_mprotect			(__NR_SYSCALL_BASE+125)
+#define __NR_sigprocmask		(__NR_SYSCALL_BASE+126)
+#define __NR_create_module		(__NR_SYSCALL_BASE+127)
+#define __NR_init_module		(__NR_SYSCALL_BASE+128)
+#define __NR_delete_module		(__NR_SYSCALL_BASE+129)
+#define __NR_get_kernel_syms		(__NR_SYSCALL_BASE+130)
+#define __NR_quotactl			(__NR_SYSCALL_BASE+131)
+#define __NR_getpgid			(__NR_SYSCALL_BASE+132)
+#define __NR_fchdir			(__NR_SYSCALL_BASE+133)
+#define __NR_bdflush			(__NR_SYSCALL_BASE+134)
+#define __NR_sysfs			(__NR_SYSCALL_BASE+135)
+#define __NR_personality		(__NR_SYSCALL_BASE+136)
+#define __NR_afs_syscall		(__NR_SYSCALL_BASE+137) /* Syscall for Andrew File System */
+#define __NR_setfsuid			(__NR_SYSCALL_BASE+138)
+#define __NR_setfsgid			(__NR_SYSCALL_BASE+139)
+#define __NR__llseek			(__NR_SYSCALL_BASE+140)
+#define __NR_getdents			(__NR_SYSCALL_BASE+141)
+#define __NR__newselect			(__NR_SYSCALL_BASE+142)
+#define __NR_flock			(__NR_SYSCALL_BASE+143)
+#define __NR_msync			(__NR_SYSCALL_BASE+144)
+#define __NR_readv			(__NR_SYSCALL_BASE+145)
+#define __NR_writev			(__NR_SYSCALL_BASE+146)
+#define __NR_getsid			(__NR_SYSCALL_BASE+147)
+#define __NR_fdatasync			(__NR_SYSCALL_BASE+148)
+#define __NR__sysctl			(__NR_SYSCALL_BASE+149)
+#define __NR_mlock			(__NR_SYSCALL_BASE+150)
+#define __NR_munlock			(__NR_SYSCALL_BASE+151)
+#define __NR_mlockall			(__NR_SYSCALL_BASE+152)
+#define __NR_munlockall			(__NR_SYSCALL_BASE+153)
+#define __NR_sched_setparam		(__NR_SYSCALL_BASE+154)
+#define __NR_sched_getparam		(__NR_SYSCALL_BASE+155)
+#define __NR_sched_setscheduler		(__NR_SYSCALL_BASE+156)
+#define __NR_sched_getscheduler		(__NR_SYSCALL_BASE+157)
+#define __NR_sched_yield		(__NR_SYSCALL_BASE+158)
+#define __NR_sched_get_priority_max	(__NR_SYSCALL_BASE+159)
+#define __NR_sched_get_priority_min	(__NR_SYSCALL_BASE+160)
+#define __NR_sched_rr_get_interval	(__NR_SYSCALL_BASE+161)
+#define __NR_nanosleep			(__NR_SYSCALL_BASE+162)
+#define __NR_mremap			(__NR_SYSCALL_BASE+163)
+#define __NR_setresuid			(__NR_SYSCALL_BASE+164)
+#define __NR_getresuid			(__NR_SYSCALL_BASE+165)
+#define __NR_vm86			(__NR_SYSCALL_BASE+166)
+#define __NR_query_module		(__NR_SYSCALL_BASE+167)
+#define __NR_poll			(__NR_SYSCALL_BASE+168)
+#define __NR_nfsservctl			(__NR_SYSCALL_BASE+169)
+#define __NR_setresgid			(__NR_SYSCALL_BASE+170)
+#define __NR_getresgid			(__NR_SYSCALL_BASE+171)
+#define __NR_prctl			(__NR_SYSCALL_BASE+172)
+#define __NR_rt_sigreturn		(__NR_SYSCALL_BASE+173)
+#define __NR_rt_sigaction		(__NR_SYSCALL_BASE+174)
+#define __NR_rt_sigprocmask		(__NR_SYSCALL_BASE+175)
+#define __NR_rt_sigpending		(__NR_SYSCALL_BASE+176)
+#define __NR_rt_sigtimedwait		(__NR_SYSCALL_BASE+177)
+#define __NR_rt_sigqueueinfo		(__NR_SYSCALL_BASE+178)
+#define __NR_rt_sigsuspend		(__NR_SYSCALL_BASE+179)
+#define __NR_pread			(__NR_SYSCALL_BASE+180)
+#define __NR_pwrite			(__NR_SYSCALL_BASE+181)
+#define __NR_chown			(__NR_SYSCALL_BASE+182)
+#define __NR_getcwd			(__NR_SYSCALL_BASE+183)
+#define __NR_capget			(__NR_SYSCALL_BASE+184)
+#define __NR_capset			(__NR_SYSCALL_BASE+185)
+#define __NR_sigaltstack		(__NR_SYSCALL_BASE+186)
+#define __NR_sendfile			(__NR_SYSCALL_BASE+187)
+					/* 188 reserved */
+					/* 189 reserved */
+#define __NR_vfork			(__NR_SYSCALL_BASE+190)
+#define __NR_ugetrlimit			(__NR_SYSCALL_BASE+191)	/* SuS compliant getrlimit */
+#define __NR_mmap2			(__NR_SYSCALL_BASE+192)
+#define __NR_truncate64			(__NR_SYSCALL_BASE+193)
+#define __NR_ftruncate64		(__NR_SYSCALL_BASE+194)
+#define __NR_stat64			(__NR_SYSCALL_BASE+195)
+#define __NR_lstat64			(__NR_SYSCALL_BASE+196)
+#define __NR_fstat64			(__NR_SYSCALL_BASE+197)
+#define __NR_lchown32			(__NR_SYSCALL_BASE+198)
+#define __NR_getuid32			(__NR_SYSCALL_BASE+199)
+#define __NR_getgid32			(__NR_SYSCALL_BASE+200)
+#define __NR_geteuid32			(__NR_SYSCALL_BASE+201)
+#define __NR_getegid32			(__NR_SYSCALL_BASE+202)
+#define __NR_setreuid32			(__NR_SYSCALL_BASE+203)
+#define __NR_setregid32			(__NR_SYSCALL_BASE+204)
+#define __NR_getgroups32		(__NR_SYSCALL_BASE+205)
+#define __NR_setgroups32		(__NR_SYSCALL_BASE+206)
+#define __NR_fchown32			(__NR_SYSCALL_BASE+207)
+#define __NR_setresuid32		(__NR_SYSCALL_BASE+208)
+#define __NR_getresuid32		(__NR_SYSCALL_BASE+209)
+#define __NR_setresgid32		(__NR_SYSCALL_BASE+210)
+#define __NR_getresgid32		(__NR_SYSCALL_BASE+211)
+#define __NR_chown32			(__NR_SYSCALL_BASE+212)
+#define __NR_setuid32			(__NR_SYSCALL_BASE+213)
+#define __NR_setgid32			(__NR_SYSCALL_BASE+214)
+#define __NR_setfsuid32			(__NR_SYSCALL_BASE+215)
+#define __NR_setfsgid32			(__NR_SYSCALL_BASE+216)
+#define __NR_getdents64			(__NR_SYSCALL_BASE+217)
+#define __NR_pivot_root			(__NR_SYSCALL_BASE+218)
+#define __NR_mincore			(__NR_SYSCALL_BASE+219)
+#define __NR_madvise			(__NR_SYSCALL_BASE+220)
+#define __NR_fcntl64			(__NR_SYSCALL_BASE+221)
+
+/*
+ * The following SWIs are ARM private.
+ */
+#define __ARM_NR_BASE			(__NR_SYSCALL_BASE+0x0f0000)
+#define __ARM_NR_breakpoint		(__ARM_NR_BASE+1)
+#define __ARM_NR_cacheflush		(__ARM_NR_BASE+2)
+#define __ARM_NR_usr26			(__ARM_NR_BASE+3)
+#define __ARM_NR_usr32			(__ARM_NR_BASE+4)
+
+#define __sys2(x) #x
+#define __sys1(x) __sys2(x)
+
+#ifndef __syscall
+#define __syscall(name) "swi\t" __sys1(__NR_##name) "\n\t"
+#endif
+
+#define __syscall_return(type, res)					\
+do {									\
+	if ((unsigned long)(res) >= (unsigned long)(-125)) {		\
+		errno = -(res);						\
+		res = -1;						\
+	}								\
+	return (type) (res);						\
+} while (0)
+
+#define _syscall0(type,name)						\
+type name(void) {							\
+  long __res;								\
+  __asm__ __volatile__ (						\
+  __syscall(name)							\
+  "mov %0,r0"								\
+  :"=r" (__res) : : "r0","lr");						\
+  __syscall_return(type,__res);						\
+}
+
+#define _syscall1(type,name,type1,arg1)					\
+type name(type1 arg1) {							\
+  long __res;								\
+  __asm__ __volatile__ (						\
+  "mov\tr0,%1\n\t"							\
+  __syscall(name)							\
+  "mov %0,r0"								\
+        : "=r" (__res)							\
+        : "r" ((long)(arg1))						\
+	: "r0","lr");							\
+  __syscall_return(type,__res);						\
+}
+
+#define _syscall2(type,name,type1,arg1,type2,arg2)			\
+type name(type1 arg1,type2 arg2) {					\
+  long __res;								\
+  __asm__ __volatile__ (						\
+  "mov\tr0,%1\n\t"							\
+  "mov\tr1,%2\n\t"							\
+  __syscall(name)							\
+  "mov\t%0,r0"								\
+        : "=r" (__res)							\
+        : "r" ((long)(arg1)),"r" ((long)(arg2))				\
+	: "r0","r1","lr");						\
+  __syscall_return(type,__res);						\
+}
+
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)		\
+type name(type1 arg1,type2 arg2,type3 arg3) {				\
+  long __res;								\
+  __asm__ __volatile__ (						\
+  "mov\tr0,%1\n\t"							\
+  "mov\tr1,%2\n\t"							\
+  "mov\tr2,%3\n\t"							\
+  __syscall(name)							\
+  "mov\t%0,r0"								\
+        : "=r" (__res)							\
+        : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3))	\
+        : "r0","r1","r2","lr");						\
+  __syscall_return(type,__res);						\
+}
+
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)		\
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {				\
+  long __res;										\
+  __asm__ __volatile__ (								\
+  "mov\tr0,%1\n\t"									\
+  "mov\tr1,%2\n\t"									\
+  "mov\tr2,%3\n\t"									\
+  "mov\tr3,%4\n\t"									\
+  __syscall(name)									\
+  "mov\t%0,r0"										\
+  	: "=r" (__res)									\
+  	: "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)),"r" ((long)(arg4))	\
+  	: "r0","r1","r2","r3","lr");							\
+  __syscall_return(type,__res);								\
+}
+  
+
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5)	\
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) {			\
+  long __res;										\
+  __asm__ __volatile__ (								\
+  "mov\tr0,%1\n\t"									\
+  "mov\tr1,%2\n\t"									\
+  "mov\tr2,%3\n\t"									\
+  "mov\tr3,%4\n\t"									\
+  "mov\tr4,%5\n\t"									\
+  __syscall(name)									\
+  "mov\t%0,r0"										\
+  	: "=r" (__res)									\
+  	: "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)),"r" ((long)(arg4)),	\
+	  "r" ((long)(arg5))								\
+	: "r0","r1","r2","r3","r4","lr");						\
+  __syscall_return(type,__res);								\
+}
+
+#ifdef __KERNEL_SYSCALLS__
+
+static inline long idle(void)
+{
+	extern long sys_idle(void);
+	return sys_idle();
+}
+
+static inline long pause(void)
+{
+	extern long sys_pause(void);
+	return sys_pause();
+}
+
+static inline long sync(void)
+{
+	extern long sys_sync(void);
+	return sys_sync();
+}
+
+static inline pid_t setsid(void)
+{
+	extern long sys_setsid(void);
+	return sys_setsid();
+}
+
+static inline long write(int fd, const char *buf, off_t count)
+{
+	extern long sys_write(int, const char *, int);
+	return sys_write(fd, buf, count);
+}
+
+static inline long read(int fd, char *buf, off_t count)
+{
+	extern long sys_read(int, char *, int);
+	return sys_read(fd, buf, count);
+}
+
+static inline off_t lseek(int fd, off_t offset, int count)
+{
+	extern off_t sys_lseek(int, off_t, int);
+	return sys_lseek(fd, offset, count);
+}
+
+static inline long dup(int fd)
+{
+	extern long sys_dup(int);
+	return sys_dup(fd);
+}
+
+static inline long open(const char *file, int flag, int mode)
+{
+	extern long sys_open(const char *, int, int);
+	return sys_open(file, flag, mode);
+}
+
+static inline long close(int fd)
+{
+	extern long sys_close(unsigned int);
+	return sys_close(fd);
+}
+
+static inline long _exit(int exitcode)
+{
+	extern long sys_exit(int) __attribute__((noreturn));
+	return sys_exit(exitcode);
+}
+
+static inline pid_t waitpid(pid_t pid, int *wait_stat, int options)
+{
+	return sys_wait4((int)pid, wait_stat, options, NULL);
+}
+
+static inline long delete_module(const char *name)
+{
+	extern long sys_delete_module(const char *name);
+	return sys_delete_module(name);
+}
+
+static inline pid_t wait(int * wait_stat)
+{
+	return sys_wait4(-1, wait_stat, 0, NULL);
+}
+
+/*
+ * The following two can't be eliminated yet - they rely on
+ * specific conditions.
+ */
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp);
+
+#endif
+#endif /* __ASM_ARM_UNISTD_H */
diff -urN linux-2.4.29/include/asm-armnommu/user.h linux-2.4.29-uc1/include/asm-armnommu/user.h
--- linux-2.4.29/include/asm-armnommu/user.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/user.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,84 @@
+#ifndef _ARM_USER_H
+#define _ARM_USER_H
+
+#include <asm/page.h>
+#include <asm/ptrace.h>
+/* Core file format: The core file is written in such a way that gdb
+   can understand it and provide useful information to the user (under
+   linux we use the 'trad-core' bfd).  There are quite a number of
+   obstacles to being able to view the contents of the floating point
+   registers, and until these are solved you will not be able to view the
+   contents of them.  Actually, you can read in the core file and look at
+   the contents of the user struct to find out what the floating point
+   registers contain.
+   The actual file contents are as follows:
+   UPAGE: 1 page consisting of a user struct that tells gdb what is present
+   in the file.  Directly after this is a copy of the task_struct, which
+   is currently not used by gdb, but it may come in useful at some point.
+   All of the registers are stored as part of the upage.  The upage should
+   always be only one page.
+   DATA: The data area is stored.  We use current->end_text to
+   current->brk to pick up all of the user variables, plus any memory
+   that may have been malloced.  No attempt is made to determine if a page
+   is demand-zero or if a page is totally unused, we just cover the entire
+   range.  All of the addresses are rounded in such a way that an integral
+   number of pages is written.
+   STACK: We need the stack information in order to get a meaningful
+   backtrace.  We need to write the data from (esp) to
+   current->start_stack, so we round each of these off in order to be able
+   to write an integer number of pages.
+   The minimum core file size is 3 pages, or 12288 bytes.
+*/
+
+struct user_fp {
+	struct fp_reg {
+		unsigned int sign1:1;
+		unsigned int unused:15;
+		unsigned int sign2:1;
+		unsigned int exponent:14;
+		unsigned int j:1;
+		unsigned int mantissa1:31;
+		unsigned int mantissa0:32;
+	} fpregs[8];
+	unsigned int fpsr:32;
+	unsigned int fpcr:32;
+	unsigned char ftype[8];
+	unsigned int init_flag;
+};
+
+/* When the kernel dumps core, it starts by dumping the user struct -
+   this will be used by gdb to figure out where the data and stack segments
+   are within the file, and what virtual addresses to use. */
+struct user{
+/* We start with the registers, to mimic the way that "memory" is returned
+   from the ptrace(3,...) function.  */
+  struct pt_regs regs;		/* Where the registers are actually stored */
+/* ptrace does not yet supply these.  Someday.... */
+  int u_fpvalid;		/* True if math co-processor being used. */
+                                /* for this mess. Not yet used. */
+/* The rest of this junk is to help gdb figure out what goes where */
+  unsigned long int u_tsize;	/* Text segment size (pages). */
+  unsigned long int u_dsize;	/* Data segment size (pages). */
+  unsigned long int u_ssize;	/* Stack segment size (pages). */
+  unsigned long start_code;     /* Starting virtual address of text. */
+  unsigned long start_stack;	/* Starting virtual address of stack area.
+				   This is actually the bottom of the stack,
+				   the top of the stack is always found in the
+				   esp register.  */
+  long int signal;     		/* Signal that caused the core dump. */
+  int reserved;			/* No longer used */
+  struct pt_regs * u_ar0;	/* Used by gdb to help find the values for */
+				/* the registers. */
+  unsigned long magic;		/* To uniquely identify a core file */
+  char u_comm[32];		/* User command that was responsible */
+  int u_debugreg[8];
+  struct user_fp u_fp;		/* FP state */
+  struct user_fp_struct * u_fp0;/* Used by gdb to help find the values for */
+  				/* the FP registers. */
+};
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+#endif /* _ARM_USER_H */
diff -urN linux-2.4.29/include/asm-armnommu/vga.h linux-2.4.29-uc1/include/asm-armnommu/vga.h
--- linux-2.4.29/include/asm-armnommu/vga.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/vga.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef ASMARM_VGA_H
+#define ASMARM_VGA_H
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#define VGA_MAP_MEM(x)	(PCIMEM_BASE + (x))
+
+#define vga_readb(x)	(*((volatile unsigned char *)x))
+#define vga_writeb(x,y)	(*((volatile unsigned char *)y) = (x))
+
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/virtconvert.h linux-2.4.29-uc1/include/asm-armnommu/virtconvert.h
--- linux-2.4.29/include/asm-armnommu/virtconvert.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/virtconvert.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef __M68KNOMMU_VIRT_CONVERT__
+#define __M68KNOMMU_VIRT_CONVERT__
+
+/*
+ * Macros used for converting between virtual and physical mappings.
+ */
+
+#ifdef __KERNEL__
+
+#define mm_vtop(vaddr)		((unsigned long) vaddr)
+
+#endif
+#endif
diff -urN linux-2.4.29/include/asm-armnommu/vt.h linux-2.4.29-uc1/include/asm-armnommu/vt.h
--- linux-2.4.29/include/asm-armnommu/vt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/vt.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,8 @@
+#ifndef _ASMARM_VT_H
+#define _ASMARM_VT_H
+
+#define VT_GETSCRINFO	0x56FD	/* get screen info */
+#define VT_GETPALETTE	0x56FE  /* get palette */
+#define VT_SETPALETTE	0x56FF  /* set palette */
+
+#endif /* _ASMARM_VT_H */
diff -urN linux-2.4.29/include/asm-armnommu/xor.h linux-2.4.29-uc1/include/asm-armnommu/xor.h
--- linux-2.4.29/include/asm-armnommu/xor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-armnommu/xor.h	2005-06-14 02:11:31.000000000 +0100
@@ -0,0 +1,141 @@
+/*
+ *  linux/include/asm-arm/xor.h
+ *
+ *  Copyright (C) 2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <asm-generic/xor.h>
+
+#define __XOR(a1, a2) a1 ^= a2
+
+#define GET_BLOCK_2(dst) \
+	__asm__("ldmia	%0, {%1, %2}" \
+		: "=r" (dst), "=r" (a1), "=r" (a2) \
+		: "0" (dst))
+
+#define GET_BLOCK_4(dst) \
+	__asm__("ldmia	%0, {%1, %2, %3, %4}" \
+		: "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \
+		: "0" (dst))
+
+#define XOR_BLOCK_2(src) \
+	__asm__("ldmia	%0!, {%1, %2}" \
+		: "=r" (src), "=r" (b1), "=r" (b2) \
+		: "0" (src)); \
+	__XOR(a1, b1); __XOR(a2, b2);
+
+#define XOR_BLOCK_4(src) \
+	__asm__("ldmia	%0!, {%1, %2, %3, %4}" \
+		: "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \
+		: "0" (src)); \
+	__XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4)
+
+#define PUT_BLOCK_2(dst) \
+	__asm__ __volatile__("stmia	%0!, {%2, %3}" \
+		: "=r" (dst) \
+		: "0" (dst), "r" (a1), "r" (a2))
+
+#define PUT_BLOCK_4(dst) \
+	__asm__ __volatile__("stmia	%0!, {%2, %3, %4, %5}" \
+		: "=r" (dst) \
+		: "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4))
+
+static void
+xor_arm4regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+{
+	unsigned int lines = bytes / sizeof(unsigned long) / 4;
+	register unsigned int a1 __asm__("r4");
+	register unsigned int a2 __asm__("r5");
+	register unsigned int a3 __asm__("r6");
+	register unsigned int a4 __asm__("r7");
+	register unsigned int b1 __asm__("r8");
+	register unsigned int b2 __asm__("r9");
+	register unsigned int b3 __asm__("ip");
+	register unsigned int b4 __asm__("lr");
+
+	do {
+		GET_BLOCK_4(p1);
+		XOR_BLOCK_4(p2);
+		PUT_BLOCK_4(p1);
+	} while (--lines);
+}
+
+static void
+xor_arm4regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+		unsigned long *p3)
+{
+	unsigned int lines = bytes / sizeof(unsigned long) / 4;
+	register unsigned int a1 __asm__("r4");
+	register unsigned int a2 __asm__("r5");
+	register unsigned int a3 __asm__("r6");
+	register unsigned int a4 __asm__("r7");
+	register unsigned int b1 __asm__("r8");
+	register unsigned int b2 __asm__("r9");
+	register unsigned int b3 __asm__("ip");
+	register unsigned int b4 __asm__("lr");
+
+	do {
+		GET_BLOCK_4(p1);
+		XOR_BLOCK_4(p2);
+		XOR_BLOCK_4(p3);
+		PUT_BLOCK_4(p1);
+	} while (--lines);
+}
+
+static void
+xor_arm4regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+		unsigned long *p3, unsigned long *p4)
+{
+	unsigned int lines = bytes / sizeof(unsigned long) / 2;
+	register unsigned int a1 __asm__("r8");
+	register unsigned int a2 __asm__("r9");
+	register unsigned int b1 __asm__("ip");
+	register unsigned int b2 __asm__("lr");
+
+	do {
+		GET_BLOCK_2(p1);
+		XOR_BLOCK_2(p2);
+		XOR_BLOCK_2(p3);
+		XOR_BLOCK_2(p4);
+		PUT_BLOCK_2(p1);
+	} while (--lines);
+}
+
+static void
+xor_arm4regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+		unsigned long *p3, unsigned long *p4, unsigned long *p5)
+{
+	unsigned int lines = bytes / sizeof(unsigned long) / 2;
+	register unsigned int a1 __asm__("r8");
+	register unsigned int a2 __asm__("r9");
+	register unsigned int b1 __asm__("ip");
+	register unsigned int b2 __asm__("lr");
+
+	do {
+		GET_BLOCK_2(p1);
+		XOR_BLOCK_2(p2);
+		XOR_BLOCK_2(p3);
+		XOR_BLOCK_2(p4);
+		XOR_BLOCK_2(p5);
+		PUT_BLOCK_2(p1);
+	} while (--lines);
+}
+
+static struct xor_block_template xor_block_arm4regs = {
+	name:	"arm4regs",
+	do_2:	xor_arm4regs_2,
+	do_3:	xor_arm4regs_3,
+	do_4:	xor_arm4regs_4,
+	do_5:	xor_arm4regs_5,
+};
+
+#undef XOR_TRY_TEMPLATES
+#define XOR_TRY_TEMPLATES			\
+	do {					\
+		xor_speed(&xor_block_arm4regs);	\
+		xor_speed(&xor_block_8regs);	\
+		xor_speed(&xor_block_32regs);	\
+	} while (0)
diff -urN linux-2.4.29/include/asm-blackfin/adsp_rtc.h linux-2.4.29-uc1/include/asm-blackfin/adsp_rtc.h
--- linux-2.4.29/include/asm-blackfin/adsp_rtc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/adsp_rtc.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,60 @@
+/*
+ * include/asm-frionommu/memdma.h - Function declaration for memory to 
+ * memory dma for Blackfin ADSP-21535
+ *  derived from:
+ *  include/asm-i386/dma.h
+ *  Written by Hennus Bergman, 1992.
+ *  Hannu Savolainen  and John Boyd, Nov. 1992.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * or (at your option) any later version as  published by the Free 
+ * Software Foundation.
+ *
+ */
+#ifndef _ADSP_RTC_H
+#define ADSP_RTC_H 1
+
+#define BYTE_REF(addr)		 (*((volatile unsigned char*)addr))
+#define HALFWORD_REF(addr) 	 (*((volatile unsigned short*)addr))
+#define WORD_REF(addr)		 (*((volatile unsigned long*)addr))
+#define RTC_STAT_ADDR	0xffc01400 /*RTC Status register 17-8 */
+#define RTC_STAT	WORD_REF(RTC_STAT_ADDR) /*RTC Status register 17-8 */
+#define RTC_ICTL_ADDR	0xffc01404 /*RTC Interrupt Control register 17-9 */
+#define RTC_ICTL	HALFWORD_REF(RTC_ICTL_ADDR) /*RTC Interrupt Control register 17-9 */
+#define RTC_ISTAT_ADDR	0xffc01408 /*RTC Interrupt Status register 17-10 */
+#define RTC_ISTAT	HALFWORD_REF(RTC_ISTAT_ADDR) /*RTC Interrupt Status register 17-10 */
+#define RTC_SWCNT_ADDR	0xffc0140c /*RTC Stopwatch Count register 17-11 */
+#define RTC_SWCNT	HALFWORD_REF(RTC_SWCNT_ADDR) /*RTC Stopwatch Count register 17-11 */
+#define RTC_ALARM_ADDR	0xffc01410 /*RTC Alarm register 17-12 */
+#define RTC_ALARM	WORD_REF(RTC_ALARM_ADDR) /*RTC Alarm register 17-12 */
+#define RTC_FAST_ADDR	0xffc01414 /*RTC Enable register 17-13 */
+#define RTC_FAST	HALFWORD_REF(RTC_FAST_ADDR) /*RTC Enable register 17-13 */
+
+
+#define ENABLE_PRESCALER				0x0001
+#define RESET						0x0000
+#define RTC_SECONDS					0x0000003f
+#define RTC_MINUTES					0x00003f00
+#define RTC_HOURS					0x001f0000
+#define	RTC_DAYS					0xff000000
+#define WRITE_COMPLETE_ENABLE				0x8000
+#define WRITE_COMPLETE				 WRITE_COMPLETE_ENABLE
+#define WRITE_PENDING				0X4000
+
+/* ioctls */
+#define RTC_GET_TIME			1
+#define RTC_SET_TIME			2
+
+struct rtc_time {
+	int tm_sec;
+	int tm_min;
+	int tm_hour;
+	int tm_mday;
+	int tm_mon;
+	int tm_year;
+	int tm_wday;
+	int tm_yday;
+	int tm_isdst;
+};
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/a.out.h linux-2.4.29-uc1/include/asm-blackfin/a.out.h
--- linux-2.4.29/include/asm-blackfin/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/a.out.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,26 @@
+#ifndef __FRIO_A_OUT_H__
+#define __FRIO_A_OUT_H__
+
+struct exec
+{
+  unsigned long a_info;		/* Use macros N_MAGIC, etc for access */
+  unsigned a_text;		/* length of text, in bytes */
+  unsigned a_data;		/* length of data, in bytes */
+  unsigned a_bss;		/* length of uninitialized data area for file, in bytes */
+  unsigned a_syms;		/* length of symbol table data in file, in bytes */
+  unsigned a_entry;		/* start address */
+  unsigned a_trsize;		/* length of relocation info for text, in bytes */
+  unsigned a_drsize;		/* length of relocation info for data, in bytes */
+};
+
+#define N_TRSIZE(a)	((a).a_trsize)
+#define N_DRSIZE(a)	((a).a_drsize)
+#define N_SYMSIZE(a)	((a).a_syms)
+
+#ifdef __KERNEL__
+
+#define STACK_TOP	TASK_SIZE
+
+#endif
+
+#endif /* __FRIO_A_OUT_H__ */
diff -urN linux-2.4.29/include/asm-blackfin/atomic.h linux-2.4.29-uc1/include/asm-blackfin/atomic.h
--- linux-2.4.29/include/asm-blackfin/atomic.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/atomic.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,153 @@
+#ifndef __ARCH_FRIONOMMU_ATOMIC__
+#define __ARCH_FRIONOMMU_ATOMIC__
+
+/*
+ * Atomic operations that C can't guarantee us.  Useful for
+ * resource counting etc..
+ *
+ * Generally we do not concern about SMP FRIO systems, so we don't have
+ * to deal with that.
+ *
+ * Tony Kou (tonyko@lineo.ca)   Lineo Inc.   2001
+ */
+
+typedef struct { int counter; } atomic_t;
+#define ATOMIC_INIT(i)	{ (i) }
+
+#define atomic_read(v)		((v)->counter)
+#define atomic_set(v, i)	(((v)->counter) = i)
+
+
+static __inline__ void atomic_add(int i, atomic_t *v)
+{	
+	int __temp = 0;
+	__asm__ __volatile__(
+		"cli R3;\n\t"
+		"%0 = %1;\n\t"
+		"%0 = %0 + %2;\n\t"
+		"%1 = %0;\n\t"
+		"sti R3;\n\t"
+		: "=d" (__temp), "=m" (v->counter)
+		: "d" (i), "m" (v->counter), "0" (__temp)
+		: "R3");
+}
+
+static __inline__ void atomic_sub(int i, atomic_t *v)
+{
+	int __temp = 0;
+	__asm__ __volatile__(
+		"cli R3;\n\t"
+		"%0 = %1;\n\t"
+		"%0 = %0 - %2;\n\t"
+		"%1 = %0;\n\t"
+		"sti R3;\n\t"
+		: "=d" (__temp), "=m" (v->counter)
+		: "d" (i), "m" (v->counter), "0" (__temp)
+		: "R3");
+}
+
+static __inline__ int atomic_add_return(int i, atomic_t * v)
+{
+	int __temp = 0;
+	__asm__ __volatile__(
+		"cli R3;\n\t"
+		"%0 = %1;\n\t"
+		"%0 = %0 + %2;\n\t"
+		"%1 = %0;\n\t"
+		"sti R3;\n\t"
+		: "=d" (__temp), "=m" (v->counter)
+		: "d" (i), "m" (v->counter), "0" (__temp)
+		: "R3");
+
+	return __temp;
+}
+
+static __inline__ int atomic_sub_return(int i, atomic_t * v)
+{
+	int __temp = 0;
+	__asm__ __volatile__(
+		"cli R3;\n\t"
+		"%0 = %1;\n\t"
+		"%0 = %0 - %2;\n\t"
+		"%1 = %0;\n\t"
+		"sti R3;\n\t"
+		: "=d" (__temp), "=m" (v->counter)
+		: "d" (i), "m" (v->counter), "0" (__temp)
+		: "R3");
+
+	return __temp;
+}
+
+
+static __inline__ void atomic_inc(volatile atomic_t *v)
+{
+	int __temp = 0;
+	__asm__ __volatile__(
+		"cli R3;\n\t"
+		"%0 = %1;\n\t"
+		"%0 += 1;\n\t"
+		"%1 = %0;\n\t"
+		"sti R3;\n\t"
+		: "=d" (__temp), "=m" (v->counter)
+		: "m" (v->counter), "0" (__temp)
+		: "R3");
+}
+
+static __inline__ void atomic_dec(volatile atomic_t *v)
+{ 
+	int __temp = 0;
+	__asm__ __volatile__(
+		"cli R3;\n\t"
+		"%0 = %1;\n\t"
+		"%0 += -1;\n\t"
+		"%1 = %0;\n\t"
+		"sti R3;\n\t"
+		: "=d" (__temp), "=m" (v->counter)
+		: "m" (v->counter), "0" (__temp)
+		: "R3");
+}
+
+static __inline__ void atomic_clear_mask(unsigned int mask, atomic_t *v)
+{
+	int __temp = 0;
+        __asm__ __volatile__(
+		"cli R3;\n\t"
+		"%0 = %1;\n\t"
+		"%0 = %0 & %2;\n\t"
+		"%1 = %0;\n\t"
+		"sti R3;\n\t"
+		: "=d" (__temp), "=m" (v->counter)
+		: "d" (~(mask)), "m" (v->counter), "0" (__temp)
+		: "R3");
+}
+
+static __inline__ void atomic_set_mask(unsigned int mask, atomic_t *v)
+{
+	int __temp = 0;
+        __asm__ __volatile__(
+		"cli R3;\n\t"
+		"%0 = %1;\n\t"
+		"%0 = %0 | %2;\n\t"
+		"%1 = %0;\n\t"
+		"sti R3;\n\t"
+		: "=d" (__temp), "=m" (v->counter)
+		: "d" (mask), "m" (v->counter), "0" (__temp)
+		: "R3");
+}
+
+#define atomic_dec_return(v) atomic_sub_return(1,(v))
+#define atomic_inc_return(v) atomic_add_return(1,(v))
+
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+
+/*
+ * XXX: Defined here because needed in put_bh()
+ */
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec()    barrier()
+#define smp_mb__after_atomic_dec() barrier()
+#define smp_mb__before_atomic_inc()    barrier()
+#define smp_mb__after_atomic_inc() barrier()
+
+#endif /* __ARCH_FRIONOMMU_ATOMIC __ */
diff -urN linux-2.4.29/include/asm-blackfin/bitops.h linux-2.4.29-uc1/include/asm-blackfin/bitops.h
--- linux-2.4.29/include/asm-blackfin/bitops.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/bitops.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,353 @@
+#ifndef _FRIONOMMU_BITOPS_H
+#define _FRIONOMMU_BITOPS_H
+
+/*
+ * Copyright 1992, Linus Torvalds.
+ */
+
+#include <linux/config.h>
+#include <asm/byteorder.h>	/* swab32     */
+#include <asm/system.h>		/* save_flags */
+
+#ifdef __KERNEL__
+/*
+ * Function prototypes to keep gcc -Wall happy
+ */
+
+/*
+ * The __ functions are not atomic
+ */  
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+static __inline__ unsigned long ffz(unsigned long word)
+{
+	unsigned long result = 0;
+
+	while(word & 1) {
+		result++;
+		word >>= 1;
+	}
+	return result;
+}
+
+
+static __inline__ void set_bit(int nr, volatile void * addr)
+{
+    int 	* a = (int *) addr;
+    int		mask;
+    unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	*a |= mask;
+	restore_flags(flags);
+}
+
+static __inline__ void __set_bit(int nr, volatile void * addr)
+{
+        int     * a = (int *) addr;
+        int     mask;
+ 
+        a += nr >> 5;
+        mask = 1 << (nr & 0x1f);
+        *a |= mask;
+}
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+
+static __inline__ void clear_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	*a &= ~mask;
+	restore_flags(flags);
+}
+
+static __inline__ void change_bit(int nr, volatile void * addr)
+{
+	int mask, flags;
+	unsigned long *ADDR = (unsigned long *) addr;
+
+	ADDR += nr >> 5;
+	mask = 1 << (nr & 31);
+	save_and_cli(flags);
+	//save_flags(flags); cli();
+	*ADDR ^= mask;
+	restore_flags(flags);
+}
+
+static __inline__ void __change_bit(int nr, volatile void * addr)
+{
+        int mask;
+        unsigned long *ADDR = (unsigned long *) addr;
+ 
+        ADDR += nr >> 5;
+        mask = 1 << (nr & 31);
+        *ADDR ^= mask;
+}
+
+static __inline__ int test_and_set_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+{
+        int     mask, retval;
+        volatile unsigned int *a = (volatile unsigned int *) addr;
+ 
+        a += nr >> 5;
+        mask = 1 << (nr & 0x1f);
+        retval = (mask & *a) != 0;
+        *a |= mask;
+        return retval;
+}
+
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+{
+        int     mask, retval;
+        volatile unsigned int *a = (volatile unsigned int *) addr;
+ 
+        a += nr >> 5;
+        mask = 1 << (nr & 0x1f);
+        retval = (mask & *a) != 0;
+        *a &= ~mask;
+        return retval;
+}
+
+static __inline__ int test_and_change_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
+{
+        int     mask, retval;
+        volatile unsigned int *a = (volatile unsigned int *) addr;
+ 
+        a += nr >> 5;
+        mask = 1 << (nr & 0x1f);
+        retval = (mask & *a) != 0;
+        *a ^= mask;
+        return retval;
+}
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+static __inline__ int __constant_test_bit(int nr, const volatile void * addr)
+{
+	return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
+}
+
+static __inline__ int __test_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	return ((mask & *a) != 0);
+}
+
+#define test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ __constant_test_bit((nr),(addr)) : \
+ __test_bit((nr),(addr)))
+
+#define find_first_zero_bit(addr, size) \
+        find_next_zero_bit((addr), (size), 0)
+
+static __inline__ int find_next_zero_bit (void * addr, int size, int offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if (offset) {
+		tmp = *(p++);
+		tmp |= ~0UL >> (32-offset);
+		if (size < 32)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while (size & ~31UL) {
+		if (~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp |= ~0UL >> size;
+found_middle:
+	return result + ffz(tmp);
+}
+
+/*
+ * ffs: find first bit set. This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+
+#define ffs(x) generic_ffs(x)
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+static __inline__ int ext2_set_bit(int nr, volatile void * addr)
+{
+	int		mask, retval;
+	unsigned long	flags;
+	volatile unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	save_and_cli(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR |= mask;
+	restore_flags(flags);
+	return retval;
+}
+
+static __inline__ int ext2_clear_bit(int nr, volatile void * addr)
+{
+	int		mask, retval;
+	unsigned long	flags;
+	volatile unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	save_and_cli(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR &= ~mask;
+	restore_flags(flags);
+	return retval;
+}
+
+static __inline__ int ext2_test_bit(int nr, const volatile void * addr)
+{
+	int   mask;
+	const volatile unsigned char	*ADDR = (const unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	return ((mask & *ADDR) != 0);
+}
+
+#define ext2_find_first_zero_bit(addr, size) \
+        ext2_find_next_zero_bit((addr), (size), 0)
+
+static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if(offset) {
+		tmp = *(p++);
+		tmp |= ~0UL >> (32-offset);
+		if(size < 32)
+			goto found_first;
+		if(~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while(size & ~31UL) {
+		if(~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if(!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp |= ~0UL >> size;
+found_middle:
+	return result + ffz(tmp);
+}
+
+/* Bitmap functions for the minix filesystem.  */
+#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr) set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+
+#endif /* __KERNEL__ */
+
+#endif /* _FRIONOMMU_BITOPS_H */
diff -urN linux-2.4.29/include/asm-blackfin/blackfin.h linux-2.4.29-uc1/include/asm-blackfin/blackfin.h
--- linux-2.4.29/include/asm-blackfin/blackfin.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/blackfin.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,38 @@
+/*
+ * Rev:$Id: blackfin.h,v 1.1 2003/11/04 14:47:41 bas Exp $
+ *
+ * Copyright (C) 2003 Bas Vermeulen/Buyways B.V. <bf533@buyways.nl>
+ *
+ * Created by Buyways B.V. for Astent <info@astent.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+#ifndef _BLACKFIN_H_
+#define _BLACKFIN_H_
+#ifdef CONFIG_PUB
+#include <asm/board/pub.h>
+#endif
+#ifdef CONFIG_HAWK
+#include <asm/board/hawk.h>
+#endif
+#ifdef CONFIG_EAGLE
+#include <asm/board/eagle.h>
+#endif
+#ifdef CONFIG_BLACKFIN_EZKIT
+#include <asm/board/ezkit.h>
+#endif
+#endif /* _BLACKFIN_H_ */
diff -urN linux-2.4.29/include/asm-blackfin/board/bf533.h linux-2.4.29-uc1/include/asm-blackfin/board/bf533.h
--- linux-2.4.29/include/asm-blackfin/board/bf533.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/board/bf533.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,1269 @@
+/*
+ * Copyright (c) 2003 by BuyWays B.V. (www.buyways.nl)
+ * Copyright (c) 2000, 2001 by Lineo, Inc./Lineo Canada Corp. (www.lineo.com),
+ * Copyright (c) 2001,2002 by Arcturus Networks Inc. (www.arcturusnetworks.com),
+ * Ported for Blackfin/Frio Architecture by 
+ *					Akbar Hussain  <akbar.hussain@arcturusnetworks.com>,
+ *             Tony Kou <tony.ko@arcturusnetworks.com>
+ *					MaTed <mated@sympatico.ca> <mated@arcturusnetworks.com>
+ * Ported to the BlackFin BF533 by Bas Vermeulen <bas@buyways.nl>
+ * Tab Size == 4 ....MaTed
+ */
+
+
+/* FOR BlackFin DSP:     BYTE = 08 bits,  HALFWORD = 16 bit & WORD = 32 bits    */
+
+
+#ifndef _BLKFin_H_
+#define _BLKFin_H_
+
+#define BYTE_REF(addr)		 (*((volatile unsigned char*)addr))
+#define HALFWORD_REF(addr) 	 (*((volatile unsigned short*)addr))
+#define WORD_REF(addr)		 (*((volatile unsigned long*)addr))
+
+/*
+ * Typedefs
+ */
+typedef unsigned long	UINT32;
+typedef unsigned short 	UINT16;
+typedef	unsigned char	UCHAR;
+
+#define PUT_FIELD(field, val) (((val) << field##_SHIFT) & field##_MASK) /* ?  */
+#define GET_FIELD(reg, field) (((reg) & field##_MASK) >> field##_SHIFT) /*  ?   */
+
+/*      FOLLOWING ARE THE BlackFin SYSTEM MMR REGISTERS (LOWER 2 MB)     */
+
+/**************************
+ *
+ * L2 MULTIPLE INPUT SIGNATURE REGISTERS (MISR) (0XFFC0000 - 0XFFC003FF)
+ *
+ **************************/
+ 
+#define MISR_CTL_ADDR		0xffc00000  /* Control register 32 bit*/
+#define MISR_CTL			WORD_REF(MISR_CTL_ADDR)
+#define MISR_RMISR0_ADDR	0xffc00004  /* CoreL2[31:0] read bus register 32 bit*/
+#define MISR_RMISR0			WORD_REF(MISR_RMISR0_ADDR)
+#define MISR_RMISR1_ADDR	0xffc00008  /* CoreL2[63:32] read bus register 32 bit*/
+#define MISR_RMISR1			WORD_REF(MISR_RMISR1_ADDR)
+#define MISR_RMISR2_ADDR	0xffc0000C  /* SysL2[31:0] read bus register 32 bit*/
+#define MISR_RMISR2			WORD_REF(MISR_RMISR2_ADDR)
+#define MISR_WMISR0_ADDR	0xffc00010  /* CoreL2[31:0] write bus register 32 bit*/
+#define MISR_WMISR0			WORD_REF(MISR_WMISR0_ADDR)
+#define MISR_WMISR1_ADDR	0xffc00014  /* CoreL2[63:32] write bus register 32 bit*/
+#define MISR_WMISR1			WORD_REF(MISR_WMISR1_ADDR)
+#define MISR_WMISR2_ADDR	0xffc00018  /* SysL2[31:0] write bus register 32 bit*/
+#define MISR_WMISR2			WORD_REF(MISR_WMISR2_ADDR)
+
+/**************************
+ *
+ * CLOCK & SYSTEM CONTROL (0XFFC0400 - 0XFFC007FF)
+ *
+ **************************/
+ 
+#define PLLCTL_ADDR			0xffc00400  /* PLL control register 32 bit*/
+#define PLLCTL				WORD_REF(PLLCTL_ADDR)
+#define PLLSTAT_ADDR		0xffc00404  /* PLL status register 16 bit */
+#define PLLSTAT				HALFWORD_REF(PLLSTAT_ADDR)
+#define LOCKCNT_ADDR		0xffc00406  /* PLL lock counter register 16 bit */
+#define LOCKCNT				HALFWORD_REF(LOCKCNT_ADDR)
+#define IOCKR_ADDR			0xffc00408  /* Peripheral clock enable register 16 bit */
+#define IOCKR				HALFWORD_REF(IOCKR_ADDR)
+#define SWRST_ADDR			0xffc00410  /* Software reset register 16 bit */
+#define SWRST				HALFWORD_REF(SWRST_ADDR)
+#define NXTSCR_ADDR			0xffc00412  /* Next system configuration register 16 bit */
+#define NXTSCR				HALFWORD_REF(NXTSCR_ADDR)
+#define SYSCR_ADDR			0xffc00414  /* Sytem Configuration register */
+#define SYSCR 				HALFWORD_REF(SYSCR_ADDR)
+
+/**************************
+ *
+ * JTAG/DEBUG COMMUNICATION CHANNEL (0XFFC00800 - 0XFFC00BFF)
+ *
+ **************************/
+ 
+#define INDATA_ADDR			0xffc00800   /* Indata register 16 bit */
+#define INDATA				HALFWORD_REF(INDATA_ADDR)
+#define OUTDATA_ADDR		0xffc00802   /*  Outdata register  16 bit */
+#define OUTDATA				HALFWORD_REF(OUTDATA_ADDR)
+#define JDCSR_ADDR			0xffc00804   /*  JDCC Control/Status register 32 bit */
+#define JDCSR				WORD_REF(JDCSR_ADDR)
+#define IDDEV_ADDR			0xffc00808   /*  Device ID register  32 bit */
+#define IDDEV				WORD_REF(IDDEV_ADDR)
+#define IDCORE_ADDR			0xffc0080c   /*  Core ID register 32 bit */
+#define IDCORE				WORD_REF(IDCORE_ADDR)
+
+/****************************
+ *
+ *  EXTENDED CORE INTERRUPT CONTROLLER (ECIC) 0XFFC00C00 - 0XFFC0OFFF
+ *
+ ****************************/
+ 
+#define RVECT_ADDR			0xffc00c00   /* Reset vector register 32 bit */
+#define RVECT				WORD_REF(RVECT_ADDR)
+#define IAR0_ADDR			0xffc00c04   /* Interrupt assignment register 0 32 bit*/
+#define IAR0				WORD_REF(IAR0_ADDR)
+#define IAR1_ADDR			0xffc00c08   /* Interrupt assignment register 1 32 bit*/
+#define IAR1				WORD_REF(IAR1_ADDR)
+#define IAR2_ADDR			0xffc00c0c   /* Interrupt assignment register 2 32 bit*/
+#define IAR2				WORD_REF(IAR2_ADDR)
+#define IMR_ADDR			0xffc00c10   /* Interrupt mask register  32 bit*/
+#define IMR				WORD_REF(IMR_ADDR)
+#define ISR_ADDR			0xffc00c14   /* Interrupt status register  32 bit*/
+#define ISR				WORD_REF(ISR_ADDR)
+#define IWR_ADDR			0xffc00c18   /* Interrupt wakeup register  32 bit*/
+#define IWR				WORD_REF(IWR_ADDR)
+
+/****************************
+ *
+ *  WATCHDOG TIMER  (0XFFC01000 - 0XFFC013F)
+ *
+ ****************************/
+ 
+#define WDOGCTL_ADDR		0xffc01000  /* Watchdog control register  32 bit */
+#define WDOGCTL				WORD_REF(WDOGCTL_ADDR)
+#define WDOGCNT_ADDR		0xffc01004  /* Watchdog count register 32 bit */
+#define WDOGCNT				WORD_REF(WDOGCNT_ADDR)
+#define WDOGSTAT_ADDR		0xffc01008  /* Watchdog status register 32 bit */
+#define WDOGSTAT			WORD_REF(WDOGSTAT_ADDR)
+
+/****************************
+ *
+ *  REAL TIME CLOCK (RTC) REGISTERS  (0XFFC01400 - 0XFFC017FF)
+ *
+ ****************************/
+ 
+#define RTCSTAT_ADDR		0xffc01400  /* RTC status register  32 bit */
+#define RTCSTAT				WORD_REF(RTCSTAT_ADDR)
+#define RTCICTL_ADDR		0xffc01404  /* RTC Interrupt control register  32 bit */
+#define RTCICTL				WORD_REF(RTCICTL_ADDR)
+#define RTCISTAT_ADDR		0xffc01408  /* RTC Interrupt status register  32 bit */
+#define RTCISTAT			WORD_REF(RTCISTAT_ADDR)
+#define RTCSWCNT_ADDR		0xffc0140c  /* RTC Stop watch count register  32 bit */
+#define RTCSWCNT			WORD_REF(RTCSWCNT_ADDR)
+#define RTCALARM_ADDR		0xffc01410  /* RTC Alarm time register  32 bit */
+#define RTCALARM			WORD_REF(RTCALARM_ADDR)
+#define RTCFAST_ADDR		0xffc01414  /* RTC Prescalar control register  32 bit */
+#define RTCFAST				WORD_REF(RTCFAST_ADDR)
+
+/****************************
+ *
+ *  UART 0 CONTROLLER REGISTERS  (0XFFC01800 - 0XFFC01BFF)
+ *
+ ****************************/
+
+#define UART0_THR_ADDR		0xffc01800  /* UART 0 Transmit holding register  16 bit */
+#define UART0_THR			HALFWORD_REF(UART0_THR_ADDR)
+#define UART0_THR_MASK		0x00ff /* Data to be transmitted */ 
+
+
+#define UART0_RBR_ADDR		0xffc01800  /* UART 0 Receive buffer register  16 bit */
+#define UART0_RBR			HALFWORD_REF(UART0_RBR_ADDR)
+#define UART0_RBR_MASK		0x00ff /* Data to be received */ 
+
+#define UART0_DLL_ADDR		0xffc01800  /* UART 0 Divisor latch (low byte) register  16 bit */
+#define UART0_DLL			HALFWORD_REF(UART0_DLL_ADDR)
+
+#define UART0_IER_ADDR		0xffc01802  /* UART 0 Interrupt enable register  16 bit */
+#define UART0_IER			HALFWORD_REF(UART0_IER_ADDR)
+#define UART0_IER_ERBFI			0x01	/* Enable Receive Buffer Full Interrupt(DR bit) */
+#define UART0_IER_ETBEI			0x02	/* Enable Transmit Buffer Empty Interrupt(THRE bit) */
+#define UART0_IER_ELSI			0x04	/* Enable RX Status Interrupt(gen if any of LSR[4:1] set) */
+#define UART0_IER_EDDSI			0x08	/* Enable Modem Status Interrupt(gen if any UARTx_MSR[3:0] set) */
+
+
+#define UART0_DLH_ADDR		0xffc01802  /* UART 0 Divisor latch (high byte) register  16 bit */
+#define UART0_DLH			HALFWORD_REF(UART0_DLH_ADDR)
+#define UART0_IIR_ADDR		0xffc01804  /* UART 0 Interrupt identification register  16 bit */
+#define UART0_IIR			HALFWORD_REF(UART0_IIR_ADDR)
+#define UART0_IIR_NOINT			0x01	/* Bit0: cleared when no interrupt */
+#define UART0_IIR_STATUS		0x06	/* mask bit for the status: bit2-1 */
+#define UART0_IIR_LSR			0x06	/* Receive line status */
+#define UART0_IIR_RBR			0x04	/* Receive data ready */
+#define UART0_IIR_THR			0x02	/* Ready to transmit  */
+#define UART0_IIR_MSR			0x00	/* Modem status       */
+
+#define UART0_LCR_ADDR		0xffc01806  /* UART 0 Line control register  16 bit */
+#define UART0_LCR			HALFWORD_REF(UART0_LCR_ADDR)
+#define UART0_LCR_WLS5			0	/* word length 5 bits */
+#define UART0_LCR_WLS6			0x01	/* word length 6 bits */
+#define UART0_LCR_WLS7			0x02	/* word length 7 bits */
+#define UART0_LCR_WLS8			0x03	/* word length 8 bits */
+#define UART0_LCR_STB			0x04	/* StopBit: 1: 2 stop bits for non-5-bit word length
+                                                       1/2 stop bits for 5-bit word length
+                                                    0: 1 stop bit */
+#define UART0_LCR_PEN			0x08	/* Parity Enable 1: for enable */
+#define UART0_LCR_EPS			0x10	/* Parity Selection: 1: for even pariety
+                                                             0: odd parity when PEN =1 & SP =0 */
+#define UART0_LCR_SP			0x20	/* Sticky Parity: */
+#define UART0_LCR_SB			0x40	/* Set Break: force TX pin to 0 */
+#define UART0_LCR_DLAB			0x80	/* Divisor Latch Access */
+
+
+#define UART0_MCR_ADDR		0xffc01808  /* UART 0 Module Control register  16 bit */
+#define UART0_MCR			HALFWORD_REF(UART0_MCR_ADDR)
+
+#define UART0_LSR_ADDR		0xffc0180a  /* UART 0 Line status register  16 bit */
+#define UART0_LSR			HALFWORD_REF(UART0_LSR_ADDR)
+#define UART0_LSR_DR			0x01	/* Data Ready */
+#define UART0_LSR_OE			0x02	/* Overrun Error */
+#define UART0_LSR_PE			0x04	/* Parity Error  */
+#define UART0_LSR_FE			0x08	/* Frame Error   */
+#define UART0_LSR_BI			0x10	/* Break Interrupt */
+#define UART0_LSR_THRE			0x20	/* THR empty, REady to accept */
+#define UART0_LSR_TEMT			0x40	/* TSR and UARTx_thr both empty */
+
+#define UART0_MSR_ADDR		0xffc0180c  /* UART 0 Modem status register  16 bit */
+#define UART0_MSR			HALFWORD_REF(UART0_MSR_ADDR
+#define UART0_SCR_ADDR		0xffc0180e  /* UART 0 Scratch register  16 bit */
+#define UART0_SCR			HALFWORD_REF(UART0_SCR_ADDR)
+#define UART0_IRCR_ADDR		0xffc01810  /* UART 0 IrDA Control register  16 bit */
+#define UART0_IRCR			HALFWORD_REF(UART0_IRCR_ADDR)
+
+#define UART0_CURR_PTR_RX_ADDR		0xffc01a00 /* UART 0 RCV DMA Current pointer register 16 bit*/
+#define UART0_CURR_PTR_RX			HALFWORD_REF(UART0_CURR_PTR_RX_ADDR)
+#define UART0_CONFIG_RX_ADDR		0xffc01a02 /* UART 0 RCV DMA Configuration register 16 bit */
+#define UART0_CONFIG_RX				HALFWORD_REF(UART0_CONFIG_RX_ADDR)
+#define UART0_START_ADDR_HI_RX_ADDR	0xffc01a04 /* UART 0 RCV DMA start add. hi reg 16 bit */
+#define UART0_START_ADDR_HI_RX		HALFWORD_REF(UART0_START_ADDR_HI_RX_ADDR)
+#define UART0_START_ADDR_LO_RX_ADDR	0xffc01a06 /* UART 0 RCV DMA start add. lo reg 16 bit */
+#define UART0_START_ADDR_LO_RX		HALFWORD_REF(UART0_START_ADDR_LO_RX_ADDR)
+#define UART0_COUNT_RX_ADDR			0xffc01a08 /* UART 0 RCV DMA count register  16 bit */
+#define UART0_COUNT_RX				HALFWORD_REF(UART0_COUNT_RX_ADDR)
+#define UART0_NEXT_DESCR_RX_ADDR    0xffc01a0a /*UART 0 RCV DMA next descripter poin reg 16 bit */
+#define UART0_NEXT_DESCR_RX			HALFWORD_REF(UART0_NEXT_DESCR_RX_ADDR)
+#define UART0_DESCR_RDY_RX_ADDR		0xffc01a0c /* UART 0 RCV DMA descripter ready reg 16 bit */
+#define UART0_DESCR_RDY_RX			HALFWORD_REF(UART0_DESCR_RDY_RX_ADDR)
+#define UART0_IRQSTAT_RX_ADDR		0xffc01a0e /* UART 0 RCV DMA Interrupt register  16 bit */
+#define UART0_IRQSTAT_RX			HALFWORD_REF(UART0_IRQSTAT_RX_ADDR)
+
+#define UART0_CURR_PTR_TX_ADDR		0xffc01b00 /* UART 0 XMT DMA Current pointer register 16 bit*/
+#define UART0_CURR_PTR_TX			HALFWORD_REF(UART0_CURR_PTR_TX_ADDR)
+#define UART0_CONFIG_TX_ADDR		0xffc01b02 /* UART 0 XMT DMA Configuration register 16 bit */
+#define UART0_CONFIG_TX				HALFWORD_REF(UART0_CONFIG_TX_ADDR)
+#define UART0_START_ADDR_HI_TX_ADDR	0xffc01b04 /* UART 0 XMT DMA start add. hi reg 16 bit */
+#define UART0_START_ADDR_HI_TX		HALFWORD_REF(UART0_START_ADDR_HI_TX_ADDR)
+#define UART0_START_ADDR_LO_TX_ADDR	0xffc01b06 /* UART 0 XMT DMA start add. lo reg 16 bit */
+#define UART0_START_ADDR_LO_TX		HALFWORD_REF(UART0_START_ADDR_LO_TX_ADDR)
+#define UART0_COUNT_TX_ADDR			0xffc01b08 /* UART 0 XMT DMA count register  16 bit */
+#define UART0_COUNT_TX				HALFWORD_REF(UART0_COUNT_TX_ADDR)
+#define UART0_NEXT_DESCR_TX_ADDR	0xffc01b0a /*UART 0 XMT DMA next descripter poin reg 16 bit */
+#define UART0_NEXT_DESCR_TX			HALFWORD_REF(UART0_NEXT_DESCR_TX_ADDR)
+#define UART0_DESCR_RDY_TX_ADDR		0xffc01b0c /* UART 0 XMT DMA descripter ready reg 16 bit */
+#define UART0_DESCR_RDY_TX			HALFWORD_REF(UART0_DESCR_RDY_TX_ADDR)
+#define UART0_IRQSTAT_TX_ADDR		0xffc01b0e /* UART 0 XMT DMA Interrupt register  16 bit */
+#define UART0_IRQSTAT_TX			HALFWORD_REF(UART0_IRQSTAT_TX_ADDR)
+
+/****************************
+ *
+ *  UART 1 CONTROLLER REGISTERS  (0XFFC01C00 - 0XFFC01FFF)
+ *
+ ****************************/
+
+#define UART1_THR_ADDR		0xffc01c00  /* UART 1 Transmit holding register  16 bit */
+#define UART1_THR			HALFWORD_REF(UART1_THR_ADDR)
+#define UART1_THR_MASK		0x00ff /* Data to be transmitted */
+
+#define UART1_RBR_ADDR		0xffc01c00  /* UART 1 Receive buffer register  16 bit */
+#define UART1_RBR			HALFWORD_REF(UART1_RBR_ADDR)
+#define UART1_RBR_MASK		0x00ff /* Data to be transmitted */
+
+#define UART1_DLL_ADDR		0xffc01c00  /* UART 1 Divisor latch (low byte) register  16 bit */
+#define UART1_DLL			HALFWORD_REF(UART1_DLL_ADDR)
+
+#define UART1_IER_ADDR		0xffc01c02  /* UART 1 Interrupt enable register  16 bit */
+#define UART1_IER			HALFWORD_REF(UART1_IER_ADDR)
+#define UART1_IER_ERBFI			0x01    /* Enable Receive Buffer Full Interrupt(DR bit) */
+#define UART1_IER_ETBEI			0x02    /* Enable Transmit Buffer Empty Interrupt(THRE bit) */
+#define UART1_IER_ELSI			0x04    /* Enable RX Status Interrupt(gen if any of LSR[4:1] set) */
+#define UART1_IER_EDDSI			0x08    /* Enable Modem Status Interrupt(gen if any UARTx_MSR[3:0] set) */
+
+#define UART1_DLH_ADDR		0xffc01c02  /* UART 1 Divisor latch (high byte) register  16 bit */
+#define UART1_DLH			HALFWORD_REF(UART1_DLH_ADDR)
+
+#define UART1_IIR_ADDR		0xffc01c04  /* UART 1 Interrupt identification register  16 bit */
+#define UART1_IIR			HALFWORD_REF(UART1_IIR_ADDR)
+#define UART1_IIR_NOINT     	0x01    /* Bit0: cleared when no interrupt */
+#define UART1_IIR_STATUS        0x06    /* mask bit for the status: bit2-1 */
+#define UART1_IIR_LSR           0x06    /* Receive line status */
+#define UART1_IIR_RBR           0x04    /* Receive data ready */
+#define UART1_IIR_THR           0x02    /* Ready to transmit  */
+#define UART1_IIR_MSR           0x00    /* Modem status       */
+
+#define UART1_LCR_ADDR		0xffc01c06  /* UART 1 Line control register  16 bit */
+#define UART1_LCR			HALFWORD_REF(UART1_LCR_ADDR)
+#define UART1_LCR_WLS5      	0       /* word length 5 bits */
+#define UART1_LCR_WLS6      	0x01    /* word length 6 bits */
+#define UART1_LCR_WLS7          0x02    /* word length 7 bits */
+#define UART1_LCR_WLS8          0x03    /* word length 8 bits */
+#define UART1_LCR_STB           0x04    /* StopBit: 1: 2 stop bits for non-5-bit word length
+                                                       1/2 stop bits for 5-bit word length
+                                                    0: 1 stop bit */
+#define UART1_LCR_PEN           0x08    /* Parity Enable 1: for enable */
+#define UART1_LCR_EPS           0x10    /* Parity Selection: 1: for even pariety
+                                                             0: odd parity when PEN =1 &
+															 SP =0 */
+#define UART1_LCR_SP            0x20    /* Sticky Parity: */
+#define UART1_LCR_SB            0x40    /* Set Break: force TX pin to 0 */
+#define UART1_LCR_DLAB          0x80    /* Divisor Latch Access */
+
+#define UART1_MCR_ADDR		0xffc01c08  /* UART 1 Module Control register  16 bit */
+#define UART1_MCR			HALFWORD_REF(UART1_MCR_ADDR)
+
+#define UART1_LSR_ADDR		0xffc01c0a  /* UART 1 Line status register  16 bit */
+#define UART1_LSR			HALFWORD_REF(UART1_LSR_ADDR)
+#define UART1_LSR_DR        	0x01    /* Data Ready */
+#define UART1_LSR_OE            0x02    /* Overrun Error */
+#define UART1_LSR_PE            0x04    /* Parity Error  */
+#define UART1_LSR_FE            0x08    /* Frame Error   */
+#define UART1_LSR_BI            0x10    /* Break Interrupt */
+#define UART1_LSR_THRE          0x20    /* THR empty, REady to accept */
+#define UART1_LSR_TEMT          0x40    /* TSR and UARTx_thr both empty */
+
+#define UART1_MSR_ADDR		0xffc01c0c  /* UART 1 Modem status register  16 bit */
+#define UART1_MSR			HALFWORD_REF(UART1_MSR_ADDR
+#define UART1_SCR_ADDR		0xffc01c0e  /* UART 1 Scratch register  16 bit */
+#define UART1_SCR			HALFWORD_REF(UART1_SCR_ADDR)
+
+#define UART1_CURR_PTR_RX_ADDR		0xffc01e00 /* UART 1 RCV DMA Current pointer register 16 bit*/
+#define UART1_CURR_PTR_RX			HALFWORD_REF(UART1_CURR_PTR_RX_ADDR)
+#define UART1_CONFIG_RX_ADDR		0xffc01e02 /* UART 1 RCV DMA Configuration register 16 bit */
+#define UART1_CONFIG_RX				HALFWORD_REF(UART1_CONFIG_RX_ADDR)
+#define UART1_START_ADDR_HI_RX_ADDR	0xffc01e04 /* UART 1 RCV DMA start add. hi reg 16 bit */
+#define UART1_START_ADDR_HI_RX		HALFWORD_REF(UART1_START_ADDR_HI_RX_ADDR)
+#define UART1_START_ADDR_LO_RX_ADDR	0xffc01e06 /* UART 1 RCV DMA start add. lo reg 16 bit */
+#define UART1_START_ADDR_LO_RX		HALFWORD_REF(UART1_START_ADDR_LO_RX_ADDR)
+#define UART1_COUNT_RX_ADDR			0xffc01e08 /* UART 1 RCV DMA count register  16 bit */
+#define UART1_COUNT_RX				HALFWORD_REF(UART1_COUNT_RX_ADDR)
+#define UART1_NEXT_DESCR_RX_ADDR   	0xffc01e0a /*UART 1 RCV DMA next descripter poin reg 16 bit */
+#define UART1_NEXT_DESCR_RX			HALFWORD_REF(UART1_NEXT_DESCR_RX_ADDR)
+#define UART1_DESCR_RDY_RX_ADDR		0xffc01e0c /* UART 1 RCV DMA descripter ready reg 16 bit */
+#define UART1_DESCR_RDY_RX			HALFWORD_REF(UART1_DESCR_RDY_RX_ADDR)
+#define UART1_IRQSTAT_RX_ADDR		0xffc01e0e /* UART 1 RCV DMA Interrupt register  16 bit */
+#define UART1_IRQSTAT_RX			HALFWORD_REF(UART1_IRQSTAT_RX_ADDR)
+
+#define UART1_CURR_PTR_TX_ADDR		0xffc01f00 /* UART 1 XMT DMA Current pointer register 16 bit*/
+#define UART1_CURR_PTR_TX			HALFWORD_REF(UART1_CURR_PTR_TX_ADDR)
+#define UART1_CONFIG_TX_ADDR		0xffc01f02 /* UART 1 XMT DMA Configuration register 16 bit */
+#define UART1_CONFIG_TX				HALFWORD_REF(UART1_CONFIG_TX_ADDR)
+#define UART1_START_ADDR_HI_TX_ADDR	0xffc01f04 /* UART 1 XMT DMA start add. hi reg 16 bit */
+#define UART1_START_ADDR_HI_TX		HALFWORD_REF(UART1_START_ADDR_HI_TX_ADDR)
+#define UART1_START_ADDR_LO_TX_ADDR	0xffc01f06 /* UART 1 XMT DMA start add. lo reg 16 bit */
+#define UART1_START_ADDR_LO_TX		HALFWORD_REF(UART1_START_ADDR_LO_TX_ADDR)
+#define UART1_COUNT_TX_ADDR			0xffc01f08 /* UART 1 XMT DMA count register  16 bit */
+#define UART1_COUNT_TX				HALFWORD_REF(UART1_COUNT_TX_ADDR)
+#define UART1_NEXT_DESCR_TX_ADDR	0xffc01f0a /*UART 1 XMT DMA next descripter poin reg 16 bit */
+#define UART1_NEXT_DESCR_TX			HALFWORD_REF(UART1_NEXT_DESCR_TX_ADDR)
+#define UART1_DESCR_RDY_TX_ADDR		0xffc01f0c /* UART 1 XMT DMA descripter ready reg 16 bit */
+#define UART1_DESCR_RDY_TX			HALFWORD_REF(UART1_DESCR_RDY_TX_ADDR)
+#define UART1_IRQSTAT_TX_ADDR		0xffc01f0e /* UART 1 XMT DMA Interrupt register  16 bit */
+#define UART1_IRQSTAT_TX			HALFWORD_REF(UART1_IRQSTAT_TX_ADDR)
+
+/****************************
+ *
+ *  TIMER REGISTERS  (0XFFC02000 - 0XFFC023FF)
+ *       THERE ARE 3 TIMERS
+ ****************************/
+ 
+		/*             TIMER 0              */
+		
+#define TIMER0_STATUS_ADDR		0xffc02000 /* TIMER 0 Global status & sticky register  16 bit */
+#define TIMER0_STATUS			HALFWORD_REF(TIMER0_STATUS_ADDR)
+#define TIMER0_CONFIG_ADDR		0xffc02002 /* TIMER 0 configuration register  16 bit */
+#define TIMER0_CONFIG			HALFWORD_REF(TIMER0_CONFIG_ADDR)
+#define TIMER0_COUNTER_LO_ADDR	0xffc02004 /* TIMER 0 counter (low word) register   16 bit */
+#define TIMER0_COUNTER_LO		HALFWORD_REF(TIMER0_COUNTER_LO_ADDR)
+#define TIMER0_COUNTER_HI_ADDR	0xffc02006 /* TIMER 0 counter (high word) register  16 bit */
+#define TIMER0_COUNTER_HI		HALFWORD_REF(TIMER0_COUNTER_HI_ADDR)
+#define TIMER0_PERIOD_LO_ADDR	0xffc02008 /* TIMER 0 period (low word) register  16 bit */
+#define TIMER0_PERIOD_LO		HALFWORD_REF(TIMER0_PERIOD_LO_ADDR)
+#define TIMER0_PERIOD_HI_ADDR	0xffc0200a /* TIMER 0 period (high word) register  16 bit */
+#define TIMER0_PERIOD_HI		HALFWORD_REF(TIMER0_PERIOD_HI_ADDR)
+#define TIMER0_WIDTH_LO_ADDR	0xffc0200c /* TIMER 0 width (low word) register  16 bit */
+#define TIMER0_WIDTH_LO			HALFWORD_REF(TIMER0_WIDTH_LO_ADDR)
+#define TIMER0_WIDTH_HI_ADDR	0xffc0200e /* TIMER 0 width (high word) register  16 bit */
+#define TIMER0_WIDTH_HI			HALFWORD_REF(TIMER0_WIDTH_HI_ADDR)
+
+		/*             TIMER 1              */
+
+#define TIMER1_STATUS_ADDR		0xffc02010 /* TIMER 1 Global status & sticky register  16 bit */
+#define TIMER1_STATUS			HALFWORD_REF(TIMER1_STATUS_ADDR)
+#define TIMER1_CONFIG_ADDR		0xffc02012 /* TIMER 1 configuration register  16 bit */
+#define TIMER1_CONFIG			HALFWORD_REF(TIMER1_CONFIG_ADDR)
+#define TIMER1_COUNTER_LO_ADDR	0xffc02014 /* TIMER 1 counter (low word) register   16 bit */
+#define TIMER1_COUNTER_LO		HALFWORD_REF(TIMER1_COUNTER_LO_ADDR)
+#define TIMER1_COUNTER_HI_ADDR	0xffc02016 /* TIMER 1 counter (high word) register  16 bit */
+#define TIMER1_COUNTER_HI		HALFWORD_REF(TIMER1_COUNTER_HI_ADDR)
+#define TIMER1_PERIOD_LO_ADDR	0xffc02018 /* TIMER 1 period (low word) register  16 bit */
+#define TIMER1_PERIOD_LO		HALFWORD_REF(TIMER1_PERIOD_LO_ADDR)
+#define TIMER1_PERIOD_HI_ADDR	0xffc0201a /* TIMER 1 period (high word) register  16 bit */
+#define TIMER1_PERIOD_HI		HALFWORD_REF(TIMER1_PERIOD_HI_ADDR)
+#define TIMER1_WIDTH_LO_ADDR	0xffc0201c /* TIMER 1 width (low word) register  16 bit */
+#define TIMER1_WIDTH_LO			HALFWORD_REF(TIMER1_WIDTH_LO_ADDR)
+#define TIMER1_WIDTH_HI_ADDR	0xffc0201e /* TIMER 1 width (high word) register  16 bit */
+#define TIMER1_WIDTH_HI			HALFWORD_REF(TIMER1_WIDTH_HI_ADDR)
+
+		/*             TIMER 2              */
+
+#define TIMER2_STATUS_ADDR		0xffc02020 /* TIMER 2 Global status & sticky register  16 bit */
+#define TIMER2_STATUS			HALFWORD_REF(TIMER2_STATUS_ADDR)
+#define TIMER2_CONFIG_ADDR		0xffc02022 /* TIMER 2 configuration register  16 bit */
+#define TIMER2_CONFIG			HALFWORD_REF(TIMER2_CONFIG_ADDR)
+#define TIMER2_COUNTER_LO_ADDR	0xffc02024 /* TIMER 2 counter (low word) register   16 bit */
+#define TIMER2_COUNTER_LO		HALFWORD_REF(TIMER2_COUNTER_LO_ADDR)
+#define TIMER2_COUNTER_HI_ADDR	0xffc02026 /* TIMER 2 counter (high word) register  16 bit */
+#define TIMER2_COUNTER_HI		HALFWORD_REF(TIMER2_COUNTER_HI_ADDR)
+#define TIMER2_PERIOD_LO_ADDR	0xffc02028 /* TIMER 2 period (low word) register  16 bit */
+#define TIMER2_PERIOD_LO		HALFWORD_REF(TIMER2_PERIOD_LO_ADDR)
+#define TIMER2_PERIOD_HI_ADDR	0xffc0202a /* TIMER 2 period (high word) register  16 bit */
+#define TIMER2_PERIOD_HI		HALFWORD_REF(TIMER2_PERIOD_HI_ADDR)
+#define TIMER2_WIDTH_LO_ADDR	0xffc0202c /* TIMER 2 width (low word) register  16 bit */
+#define TIMER2_WIDTH_LO			HALFWORD_REF(TIMER2_WIDTH_LO_ADDR)
+#define TIMER2_WIDTH_HI_ADDR	0xffc0202e /* TIMER 2 width (high word) register  16 bit */
+#define TIMER2_WIDTH_HI			HALFWORD_REF(TIMER2_WIDTH_HI_ADDR)
+
+/****************************
+ *
+ *  GENERAL PURPOSE IO REGISTERS  (0XFFC02400 - 0XFFC027FF)
+ *       
+ ****************************/
+
+#define FIO_DIR_C_ADDR		0xffc02400 /* Peripheral flag direction (clear) register 16 bit */
+#define FIO_DIR_C			HALFWORD_REF(FIO_DIR_C_ADDR)
+#define FIO_DIR_S_ADDR		0xffc02402 /* Peripheral flag direction (set) register 16 bit */
+#define FIO_DIR_S			HALFWORD_REF(FIO_DIR_S_ADDR)
+#define FIO_FLAG_C_ADDR		0xffc02404 /* Peripheral Interrupt flag (clear) register 16 bit */
+#define FIO_FLAG_C			HALFWORD_REF(FIO_FLAG_C_ADDR)
+#define FIO_FLAG_S_ADDR		0xffc02406 /* Peripheral Interrupt flag (set) register 16 bit */
+#define FIO_FLAG_S			HALFWORD_REF(FIO_FLAG_S_ADDR)
+#define FIO_MASKA_C_ADDR	0xffc02408 /* Flag Mask Interrupt A (clear) register 16 bit */
+#define FIO_MASKA_C			HALFWORD_REF(FIO_MASKA_C_ADDR)
+#define FIO_MASKA_S_ADDR	0xffc0240a /* Flag Mask Interrupt A (set) register 16 bit */
+#define FIO_MASKA_S			HALFWORD_REF(FIO_MASKA_S_ADDR)
+#define FIO_MASKB_C_ADDR	0xffc0240c /* Flag Mask Interrupt B (clear) register 16 bit */
+#define FIO_MASKB_C			HALFWORD_REF(FIO_MASKB_C_ADDR)
+#define FIO_MASKB_S_ADDR	0xffc0240e /* Flag Mask Interrupt B (set) register 16 bit */
+#define FIO_MASKB_S			HALFWORD_REF(FIO_MASKB_S_ADDR)
+#define FIO_POLAR_C_ADDR	0xffc02410 /* Flag source polarity (clear) register 16 bit */
+#define FIO_POLAR_C			HALFWORD_REF(FIO_POLAR_C_ADDR)
+#define FIO_POLAR_S_ADDR	0xffc02412 /* Flag source polarity (set) register 16 bit */
+#define FIO_POLAR_S			HALFWORD_REF(FIO_POLAR_S_ADDR)
+#define FIO_EDGE_C_ADDR		0xffc02414 /* Flag source sensitivity (clear) register 16 bit */
+#define FIO_EDGE_C			HALFWORD_REF(FIO_EDGE_C_ADDR)
+#define FIO_EDGE_S_ADDR		0xffc02416 /* Flag source sensitivity (set) register 16 bit */
+#define FIO_EDGE_S			HALFWORD_REF(FIO_EDGE_S_ADDR)
+#define FIO_BOTH_C_ADDR		0xffc02418 /* Flag set on both edges (clear) register 16 bit */
+#define FIO_BOTH_C			HALFWORD_REF(FIO_BOTH_C_ADDR)
+#define FIO_BOTH_S_ADDR		0xffc0241a /* Flag set on both edges (set) register 16 bit */
+#define FIO_BOTH_S			HALFWORD_REF(FIO_BOTH_S_ADDR)
+
+/****************************
+ *
+ *  SPORT 0 CONTROLLER REGISTERS  (0XFFC02800 - 0XFFC02BFF)
+ *       
+ ****************************/
+ 
+#define SPORT0_TX_CONFIG_ADDR	0xffc02800 /* SPORT 0 Transmit configuration register 16 bit */
+#define SPORT0_TX_CONFIG		HALFWORD_REF(SPORT0_TX_CONFIG_ADDR)
+#define SPORT0_RX_CONFIG_ADDR	0xffc02802 /* SPORT 0 Receive configuration register 16 bit */
+#define SPORT0_RX_CONFIG		HALFWORD_REF(SPORT0_RX_CONFIG_ADDR)
+#define SPORT0_TX_ADDR			0xffc02804 /* SPORT 0 Transmit register 16 bit */
+#define SPORT0_TX				HALFWORD_REF(SPORT0_TX_ADDR)
+#define SPORT0_RX_ADDR			0xffc02806 /* SPORT 0 Receive register 16 bit */
+#define SPORT0_RX				HALFWORD_REF(SPORT0_RX_ADDR)
+#define SPORT0_TSCLKDIV_ADDR	0xffc02808 /* SPORT 0 Transmit serial clock divider 16 bit */
+#define SPORT0_TSCLKDIV			HALFWORD_REF(SPORT0_TSCLKDIV_ADDR)
+#define SPORT0_RSCLKDIV_ADDR	0xffc0280a /* SPORT 0 Receive serial clock divider 16 bit */
+#define SPORT0_RSCLKDIV			HALFWORD_REF(SPORT0_RSCLKDIV_ADDR)
+#define SPORT0_TFSDIV_ADDR		0xffc0280c /* SPORT 0 Transmit frame sync divider 16 bit */
+#define SPORT0_TFSDIV			HALFWORD_REF(SPORT0_TFSDIV_ADDR)
+#define SPORT0_RFSDIV_ADDR		0xffc0280e /* SPORT 0 Receive frame sync divider 16 bit */
+#define SPORT0_RFSDIV			HALFWORD_REF(SPORT0_RFSDIV_ADDR)
+#define SPORT0_STAT_ADDR		0xffc02810 /* SPORT 0 status register 16 bit */
+#define SPORT0_STAT				HALFWORD_REF(SPORT0_STAT_ADDR)
+#define SPORT0_MTCS0_ADDR		0xffc02812 /* SPORT 0 Multi-channel Transmit select reg 16 bit */
+#define SPORT0_MTCS0			HALFWORD_REF(SPORT0_MTCS0_ADDR)
+#define SPORT0_MTCS1_ADDR		0xffc02814 /* SPORT 0 Multi-channel Transmit select reg 16 bit */
+#define SPORT0_MTCS1			HALFWORD_REF(SPORT0_MTCS1_ADDR)
+#define SPORT0_MTCS2_ADDR		0xffc02816 /* SPORT 0 Multi-channel Transmit select reg 16 bit */
+#define SPORT0_MTCS2			HALFWORD_REF(SPORT0_MTCS2_ADDR)
+#define SPORT0_MTCS3_ADDR		0xffc02818 /* SPORT 0 Multi-channel Transmit select reg 16 bit */
+#define SPORT0_MTCS3			HALFWORD_REF(SPORT0_MTCS3_ADDR)
+#define SPORT0_MTCS4_ADDR		0xffc0281a /* SPORT 0 Multi-channel Transmit select reg 16 bit */
+#define SPORT0_MTCS4			HALFWORD_REF(SPORT0_MTCS4_ADDR)
+#define SPORT0_MTCS5_ADDR		0xffc0281c /* SPORT 0 Multi-channel Transmit select reg 16 bit */
+#define SPORT0_MTCS5			HALFWORD_REF(SPORT0_MTCS5_ADDR)
+#define SPORT0_MTCS6_ADDR		0xffc0281e /* SPORT 0 Multi-channel Transmit select reg 16 bit */
+#define SPORT0_MTCS6			HALFWORD_REF(SPORT0_MTCS6_ADDR)
+#define SPORT0_MTCS7_ADDR		0xffc02820 /* SPORT 0 Multi-channel Transmit select reg 16 bit */
+#define SPORT0_MTCS7			HALFWORD_REF(SPORT0_MTCS7_ADDR)
+#define SPORT0_MRCS0_ADDR		0xffc02822 /* SPORT 0 Multi-channel Receive select reg 16 bit */
+#define SPORT0_MRCS0			HALFWORD_REF(SPORT0_MRCS0_ADDR)
+#define SPORT0_MRCS1_ADDR		0xffc02824 /* SPORT 0 Multi-channel Receive select reg 16 bit */
+#define SPORT0_MRCS1			HALFWORD_REF(SPORT0_MRCS1_ADDR)
+#define SPORT0_MRCS2_ADDR		0xffc02826 /* SPORT 0 Multi-channel Receive select reg 16 bit */
+#define SPORT0_MRCS2			HALFWORD_REF(SPORT0_MRCS2_ADDR)
+#define SPORT0_MRCS3_ADDR		0xffc02828 /* SPORT 0 Multi-channel Receive select reg 16 bit */
+#define SPORT0_MRCS3			HALFWORD_REF(SPORT0_MRCS3_ADDR)
+#define SPORT0_MRCS4_ADDR		0xffc0282a /* SPORT 0 Multi-channel Receive select reg 16 bit */
+#define SPORT0_MRCS4			HALFWORD_REF(SPORT0_MRCS4_ADDR)
+#define SPORT0_MRCS5_ADDR		0xffc0282c /* SPORT 0 Multi-channel Receive select reg 16 bit */
+#define SPORT0_MRCS5			HALFWORD_REF(SPORT0_MRCS5_ADDR)
+#define SPORT0_MRCS6_ADDR		0xffc0282e /* SPORT 0 Multi-channel Receive select reg 16 bit */
+#define SPORT0_MRCS6			HALFWORD_REF(SPORT0_MRCS6_ADDR)
+#define SPORT0_MRCS7_ADDR		0xffc02830 /* SPORT 0 Multi-channel Receive select reg 16 bit */
+#define SPORT0_MRCS7			HALFWORD_REF(SPORT0_MRCS7_ADDR)
+#define SPORT0_MCMC1_ADDR		0xffc02832 /* SPORT 0 Multi-channel configuration reg 1 16 bit */
+#define SPORT0_MCMC1			HALFWORD_REF(SPORT0_MCMC1_ADDR)
+#define SPORT0_MCMC2_ADDR		0xffc02834 /* SPORT 0 Multi-channel configuration reg 2 16 bit */
+#define SPORT0_MCMC2			HALFWORD_REF(SPORT0_MCMC2_ADDR)
+
+#define SPORT0_CURR_PTR_RX_ADDR		0xffc02a00 /* SPORT 0 RCV DMA Current pointer reg 16 bit*/
+#define SPORT0_CURR_PTR_RX			HALFWORD_REF(SPORT0_CURR_PTR_RX_ADDR)
+#define SPORT0_CONFIG_DMA_RX_ADDR	0xffc02a02 /* SPORT 0 RCV DMA Configuration reg 16 bit */
+
+#if 0
+#define SPORT0_CONFIG_DMA_RX		HALFWORD_REF(SPORT0_CONFIG_RX_ADDR)
+#else
+#define SPORT0_CONFIG_DMA_RX		HALFWORD_REF(SPORT0_CONFIG_DMA_RX_ADDR)
+#endif
+
+#define SPORT0_START_ADDR_HI_RX_ADDR  	0xffc02a04 /* SPORT 0 RCV DMA start add. hi reg 16 bit */
+#define SPORT0_START_ADDR_HI_RX		HALFWORD_REF(SPORT0_START_ADDR_HI_RX_ADDR)
+#define SPORT0_START_ADDR_LO_RX_ADDR  	0xffc02a06 /* SPORT 0 RCV DMA start add. lo reg 16 bit */
+#define SPORT0_START_ADDR_LO_RX		HALFWORD_REF(SPORT0_START_ADDR_LO_RX_ADDR)
+#define SPORT0_COUNT_RX_ADDR  		0xffc02a08 /* SPORT 0 RCV DMA count reg 16 bit */
+#define SPORT0_COUNT_RX				HALFWORD_REF(SPORT0_COUNT_RX_ADDR)
+#define SPORT0_NEXT_DESCR_RX_ADDR  	0xffc02a0a /* SPORT 0 RCV DMA next descriptor poin reg 16 bit */
+#define SPORT0_NEXT_DESCR_RX		HALFWORD_REF(SPORT0_NEXT_DESCR_RX_ADDR)
+#define SPORT0_DESCR_RDY_RX_ADDR  	0xffc02a0c /* SPORT 0 RCV DMA descriptor ready reg 16 bit */
+#define SPORT0_DESCR_RDY_RX			HALFWORD_REF(SPORT0_DESCR_RDY_RX_ADDR)
+#define SPORT0_IRQSTAT_RX_ADDR  	0xffc02a0e /* SPORT 0 RCV DMA interrupt reg 16 bit */
+#define SPORT0_IRQSTAT_RX			HALFWORD_REF(SPORT0_IRQSTAT_RX_ADDR)
+
+#define SPORT0_CURR_PTR_TX_ADDR		0xffc02b00 /* SPORT 0 XMT DMA Current pointer reg 16 bit*/
+#define SPORT0_CURR_PTR_TX			HALFWORD_REF(SPORT0_CURR_PTR_TX_ADDR)
+#define SPORT0_CONFIG_DMA_TX_ADDR	0xffc02b02 /* SPORT 0 XMT DMA Configuration reg 16 bit */
+
+/* Fixed in Jul 2 2003 for SPORT driver*/
+#if 0
+#define SPORT0_CONFIG_DMA_TX		HALFWORD_REF(SPORT0_CONFIG_TX_ADDR)
+#else
+#define SPORT0_CONFIG_DMA_TX		HALFWORD_REF(SPORT0_CONFIG_DMA_TX_ADDR)
+#endif
+
+#define SPORT0_START_ADDR_HI_TX_ADDR  	0xffc02b04 /* SPORT 0 XMT DMA start add. hi reg 16 bit */
+#define SPORT0_START_ADDR_HI_TX		HALFWORD_REF(SPORT0_START_ADDR_HI_TX_ADDR)
+#define SPORT0_START_ADDR_LO_TX_ADDR  	0xffc02b06 /* SPORT 0 XMT DMA start add. lo reg 16 bit */
+#define SPORT0_START_ADDR_LO_TX		HALFWORD_REF(SPORT0_START_ADDR_LO_TX_ADDR)
+#define SPORT0_COUNT_TX_ADDR  		0xffc02b08 /* SPORT 0 XMT DMA count reg 16 bit */
+#define SPORT0_COUNT_TX				HALFWORD_REF(SPORT0_COUNT_TX_ADDR)
+#define SPORT0_NEXT_DESCR_TX_ADDR  	0xffc02b0a /* SPORT 0 XMT DMA next descriptor poin reg 16 bit */
+#define SPORT0_NEXT_DESCR_TX		HALFWORD_REF(SPORT0_NEXT_DESCR_TX_ADDR)
+#define SPORT0_DESCR_RDY_TX_ADDR  	0xffc02b0c /* SPORT 0 XMT DMA descriptor ready reg 16 bit */
+#define SPORT0_DESCR_RDY_TX			HALFWORD_REF(SPORT0_DESCR_RDY_TX_ADDR)
+#define SPORT0_IRQSTAT_TX_ADDR  	0xffc02b0e /* SPORT 0 XMT DMA interrupt reg 16 bit */
+#define SPORT0_IRQSTAT_TX			HALFWORD_REF(SPORT0_IRQSTAT_TX_ADDR)
+
+/****************************
+ *
+ *  SPORT 1 CONTROLLER REGISTERS  (0XFFC02C00 - 0XFFC02FFF)
+ *
+ ****************************/
+
+#define SPORT1_TX_CONFIG_ADDR	0xffc02c00 /* SPORT 1 Transmit configuration register 16 bit */
+#define SPORT1_TX_CONFIG		HALFWORD_REF(SPORT1_TX_CONFIG_ADDR)
+#define SPORT1_RX_CONFIG_ADDR	0xffc02c02 /* SPORT 1 Receive configuration register 16 bit */
+#define SPORT1_RX_CONFIG		HALFWORD_REF(SPORT1_RX_CONFIG_ADDR)
+#define SPORT1_TX_ADDR			0xffc02c04 /* SPORT 1 Transmit register 16 bit */
+#define SPORT1_TX				HALFWORD_REF(SPORT1_TX_ADDR)
+#define SPORT1_RX_ADDR			0xffc02c06 /* SPORT 1 Receive register 16 bit */
+#define SPORT1_RX				HALFWORD_REF(SPORT1_RX_ADDR)
+#define SPORT1_TSCLKDIV_ADDR	0xffc02c08 /* SPORT 1 Transmit serial clock divider 16 bit */
+#define SPORT1_TSCLKDIV			HALFWORD_REF(SPORT1_TSCLKDIV_ADDR)
+#define SPORT1_RSCLKDIV_ADDR	0xffc02c0a /* SPORT 1 Receive serial clock divider 16 bit */
+#define SPORT1_RSCLKDIV			HALFWORD_REF(SPORT1_RSCLKDIV_ADDR)
+#define SPORT1_TFSDIV_ADDR		0xffc02c0c /* SPORT 1 Transmit frame sync divider 16 bit */
+#define SPORT1_TFSDIV			HALFWORD_REF(SPORT1_TFSDIV_ADDR)
+#define SPORT1_RFSDIV_ADDR		0xffc02c0e /* SPORT 1 Receive frame sync divider 16 bit */
+#define SPORT1_RFSDIV			HALFWORD_REF(SPORT1_RFSDIV_ADDR)
+#define SPORT1_STAT_ADDR		0xffc02c10 /* SPORT 1 status register 16 bit */
+#define SPORT1_STAT				HALFWORD_REF(SPORT1_STAT_ADDR)
+#define SPORT1_MTCS0_ADDR		0xffc02c12 /* SPORT 1 Multi-channel Transmit select reg 16 bit */
+#define SPORT1_MTCS0			HALFWORD_REF(SPORT1_MTCS0_ADDR)
+#define SPORT1_MTCS1_ADDR		0xffc02c14 /* SPORT 1 Multi-channel Transmit select reg 16 bit */
+#define SPORT1_MTCS1			HALFWORD_REF(SPORT1_MTCS1_ADDR)
+#define SPORT1_MTCS2_ADDR		0xffc02c16 /* SPORT 1 Multi-channel Transmit select reg 16 bit */
+#define SPORT1_MTCS2			HALFWORD_REF(SPORT1_MTCS2_ADDR)
+#define SPORT1_MTCS3_ADDR		0xffc02c18 /* SPORT 1 Multi-channel Transmit select reg 16 bit */
+#define SPORT1_MTCS3			HALFWORD_REF(SPORT1_MTCS3_ADDR)
+#define SPORT1_MTCS4_ADDR		0xffc02c1a /* SPORT 1 Multi-channel Transmit select reg 16 bit */
+#define SPORT1_MTCS4			HALFWORD_REF(SPORT1_MTCS4_ADDR)
+#define SPORT1_MTCS5_ADDR		0xffc02c1c /* SPORT 1 Multi-channel Transmit select reg 16 bit */
+#define SPORT1_MTCS5			HALFWORD_REF(SPORT1_MTCS5_ADDR)
+#define SPORT1_MTCS6_ADDR		0xffc02c1e /* SPORT 1 Multi-channel Transmit select reg 16 bit */
+#define SPORT1_MTCS6			HALFWORD_REF(SPORT1_MTCS6_ADDR)
+#define SPORT1_MTCS7_ADDR		0xffc02c20 /* SPORT 1 Multi-channel Transmit select reg 16 bit */
+#define SPORT1_MTCS7			HALFWORD_REF(SPORT1_MTCS7_ADDR)
+#define SPORT1_MRCS0_ADDR		0xffc02c22 /* SPORT 1 Multi-channel Receive select reg 16 bit */
+#define SPORT1_MRCS0			HALFWORD_REF(SPORT1_MRCS0_ADDR)
+#define SPORT1_MRCS1_ADDR		0xffc02c24 /* SPORT 1 Multi-channel Receive select reg 16 bit */
+#define SPORT1_MRCS1			HALFWORD_REF(SPORT1_MRCS1_ADDR)
+#define SPORT1_MRCS2_ADDR		0xffc02c26 /* SPORT 1 Multi-channel Receive select reg 16 bit */
+#define SPORT1_MRCS2			HALFWORD_REF(SPORT1_MRCS2_ADDR)
+#define SPORT1_MRCS3_ADDR		0xffc02c28 /* SPORT 1 Multi-channel Receive select reg 16 bit */
+#define SPORT1_MRCS3			HALFWORD_REF(SPORT1_MRCS3_ADDR)
+#define SPORT1_MRCS4_ADDR		0xffc02c2a /* SPORT 1 Multi-channel Receive select reg 16 bit */
+#define SPORT1_MRCS4			HALFWORD_REF(SPORT1_MRCS4_ADDR)
+#define SPORT1_MRCS5_ADDR		0xffc02c2c /* SPORT 1 Multi-channel Receive select reg 16 bit */
+#define SPORT1_MRCS5			HALFWORD_REF(SPORT1_MRCS5_ADDR)
+#define SPORT1_MRCS6_ADDR		0xffc02c2e /* SPORT 1 Multi-channel Receive select reg 16 bit */
+#define SPORT1_MRCS6			HALFWORD_REF(SPORT1_MRCS6_ADDR)
+#define SPORT1_MRCS7_ADDR		0xffc02c30 /* SPORT 1 Multi-channel Receive select reg 16 bit */
+#define SPORT1_MRCS7			HALFWORD_REF(SPORT1_MRCS7_ADDR)
+#define SPORT1_MCMC1_ADDR		0xffc02c32 /* SPORT 1 Multi-channel configuration reg 1 16 bit */
+#define SPORT1_MCMC1			HALFWORD_REF(SPORT1_MCMC1_ADDR)
+#define SPORT1_MCMC2_ADDR		0xffc02c34 /* SPORT 1 Multi-channel configuration reg 2 16 bit */
+#define SPORT1_MCMC2			HALFWORD_REF(SPORT1_MCMC2_ADDR)
+
+#define SPORT1_CURR_PTR_RX_ADDR		0xffc02e00 /* SPORT 1 RCV DMA Current pointer reg 16 bit*/
+#define SPORT1_CURR_PTR_RX			HALFWORD_REF(SPORT1_CURR_PTR_RX_ADDR)
+#define SPORT1_CONFIG_DMA_RX_ADDR	0xffc02e02 /* SPORT 1 RCV DMA Configuration reg 16 bit */
+
+/* Fixed for SPORT driver, Jul 2 2003 */
+#if 0
+#define SPORT1_CONFIG_DMA_RX		HALFWORD_REF(SPORT1_CONFIG_RX_ADDR)
+#else
+#define SPORT1_CONFIG_DMA_RX		HALFWORD_REF(SPORT1_CONFIG_DMA_RX_ADDR)
+#endif
+
+#define SPORT1_START_ADDR_HI_RX_ADDR  	0xffc02e04 /* SPORT 1 RCV DMA start add. hi reg 16 bit */
+#define SPORT1_START_ADDR_HI_RX		HALFWORD_REF(SPORT1_START_ADDR_HI_RX_ADDR)
+#define SPORT1_START_ADDR_LO_RX_ADDR  	0xffc02e06 /* SPORT 1 RCV DMA start add. lo reg 16 bit */
+#define SPORT1_START_ADDR_LO_RX		HALFWORD_REF(SPORT1_START_ADDR_LO_RX_ADDR)
+#define SPORT1_COUNT_RX_ADDR  		0xffc02e08 /* SPORT 1 RCV DMA count reg 16 bit */
+#define SPORT1_COUNT_RX				HALFWORD_REF(SPORT1_COUNT_RX_ADDR)
+#define SPORT1_NEXT_DESCR_RX_ADDR  	0xffc02e0a /* SPORT 1 RCV DMA next descriptor poin reg 16 bit */
+#define SPORT1_NEXT_DESCR_RX		HALFWORD_REF(SPORT1_NEXT_DESCR_RX_ADDR)
+#define SPORT1_DESCR_RDY_RX_ADDR  	0xffc02e0c /* SPORT 1 RCV DMA descriptor ready reg 16 bit */
+#define SPORT1_DESCR_RDY_RX			HALFWORD_REF(SPORT1_DESCR_RDY_RX_ADDR)
+#define SPORT1_IRQSTAT_RX_ADDR  	0xffc02e0e /* SPORT 1 RCV DMA interrupt reg 16 bit */
+#define SPORT1_IRQSTAT_RX			HALFWORD_REF(SPORT1_IRQSTAT_RX_ADDR)
+
+#define SPORT1_CURR_PTR_TX_ADDR		0xffc02f00 /* SPORT 1 XMT DMA Current pointer reg 16 bit*/
+#define SPORT1_CURR_PTR_TX			HALFWORD_REF(SPORT1_CURR_PTR_TX_ADDR)
+#define SPORT1_CONFIG_DMA_TX_ADDR	0xffc02f02 /* SPORT 1 XMT DMA Configuration reg 16 bit */
+
+#if 0
+#define SPORT1_CONFIG_DMA_TX		HALFWORD_REF(SPORT1_CONFIG_TX_ADDR)
+#else
+#define SPORT1_CONFIG_DMA_TX		HALFWORD_REF(SPORT1_CONFIG_DMA_TX_ADDR)
+#endif
+
+#define SPORT1_START_ADDR_HI_TX_ADDR  	0xffc02f04 /* SPORT 1 XMT DMA start add. hi reg 16 bit */
+#define SPORT1_START_ADDR_HI_TX		HALFWORD_REF(SPORT1_START_ADDR_HI_TX_ADDR)
+#define SPORT1_START_ADDR_LO_TX_ADDR  	0xffc02f06 /* SPORT 1 XMT DMA start add. lo reg 16 bit */
+#define SPORT1_START_ADDR_LO_TX		HALFWORD_REF(SPORT1_START_ADDR_LO_TX_ADDR)
+#define SPORT1_COUNT_TX_ADDR  		0xffc02f08 /* SPORT 1 XMT DMA count reg 16 bit */
+#define SPORT1_COUNT_TX				HALFWORD_REF(SPORT1_COUNT_TX_ADDR)
+#define SPORT1_NEXT_DESCR_TX_ADDR  	0xffc02f0a /* SPORT 1 XMT DMA next descriptor poin reg 16 bit */
+#define SPORT1_NEXT_DESCR_TX		HALFWORD_REF(SPORT1_NEXT_DESCR_TX_ADDR)
+#define SPORT1_DESCR_RDY_TX_ADDR  	0xffc02f0c /* SPORT 1 XMT DMA descriptor ready reg 16 bit */
+#define SPORT1_DESCR_RDY_TX			HALFWORD_REF(SPORT1_DESCR_RDY_TX_ADDR)
+#define SPORT1_IRQSTAT_TX_ADDR  	0xffc02f0e /* SPORT 1 XMT DMA interrupt reg 16 bit */
+#define SPORT1_IRQSTAT_TX			HALFWORD_REF(SPORT1_IRQSTAT_TX_ADDR)
+
+/****************************
+ *
+ *  SPI 0 CONTROLLER REGISTERS  (0XFFC03000 - 0XFFC033FF)
+ *
+ ****************************/
+
+#define SPI0_CTL_ADDR		0xffc03000 /* SPI 0 control register 16 bit */
+#define SPI0_CTL			HALFWORD_REF(SPI0_CTL_ADDR)
+#define SPI0_FLG_ADDR		0xffc03002 /* SPI 0 flag register 16 bit */
+#define SPI0_FLG			HALFWORD_REF(SPI0_FLG_ADDR)
+#define SPI0_ST_ADDR		0xffc03004 /* SPI 0 status register 16 bit */
+#define SPI0_ST				HALFWORD_REF(SPI0_ST_ADDR)
+#define SPI0_TDBR_ADDR		0xffc03006 /* SPI 0 transmit data buffer register 16 bit */
+#define SPI0_TDBR			HALFWORD_REF(SPI0_TDBR_ADDR)
+#define SPI0_RDBR_ADDR		0xffc03008 /* SPI 0 receive data buffer register 16 bit */
+#define SPI0_RDBR			HALFWORD_REF(SPI0_RDBR_ADDR)
+#define SPI0_BAUD_ADDR		0xffc0300a /* SPI 0 baud rate register 16 bit */
+#define SPI0_BAUD			HALFWORD_REF(SPI0_BAUD_ADDR)
+#define SPI0_SHADOW_ADDR	0xffc0300c /* SPI 0 RDBR register 16 bit */
+#define SPI0_SHADOW			HALFWORD_REF(SPI0_SHADOW_ADDR)
+
+#define SPI0_CURR_PTR_ADDR		0xffc03200 /* SPI 0 DMA current pointer register 16 bit */
+#define SPI0_CURR_PTR			HALFWORD_REF(SPI0_CURR_PTR_ADDR)
+#define SPI0_CONFIG_ADDR		0xffc03202 /* SPI 0 DMA configuration register 16 bit */
+#define SPI0_CONFIG				HALFWORD_REF(SPI0_CONFIG_ADDR)
+#define SPI0_START_ADDR_HI_ADDR	0xffc03204 /* SPI 0 DMA start address hi register 16 bit */
+#define SPI0_START_ADDR_HI		HALFWORD_REF(SPI0_START_ADDR_HI_ADDR)
+#define SPI0_START_ADDR_LO_ADDR	0xffc03206 /* SPI 0 DMA start address lo register 16 bit */
+#define SPI0_START_ADDR_LO		HALFWORD_REF(SPI0_START_ADDR_LO_ADDR)
+#define SPI0_COUNT_ADDR			0xffc03208 /* SPI 0 DMA count register 16 bit */
+#define SPI0_COUNT				HALFWORD_REF(SPI0_COUNT_ADDR)
+#define SPI0_NEXT_DESCR_ADDR	0xffc0320a /* SPI 0 DMA Next descriptor pointer register 16 bit */
+#define SPI0_NEXT_DESCR			HALFWORD_REF(SPI0_NEXT_DESCR_ADDR)
+#define SPI0_DESCR_RDY_ADDR		0xffc0320c /* SPI 0 DMA descriptor ready register 16 bit */
+#define SPI0_DESCR_RDY			HALFWORD_REF(SPI0_DESCR_RDY_ADDR)
+#define SPI0_DMA_INT_ADDR		0xffc0320e /* SPI 0 DMA interrupt register 16 bit */
+#define SPI0_DMA_INT			HALFWORD_REF(SPI0_DMA_INT_ADDR)
+
+/****************************
+ *
+ *  SPI 1 CONTROLLER REGISTERS  (0XFFC03400 - 0XFFC037FF)
+ *
+ ****************************/
+
+#define SPI1_CTL_ADDR		0xffc03400 /* SPI 1 control register 16 bit */
+#define SPI1_CTL			HALFWORD_REF(SPI1_CTL_ADDR)
+#define SPI1_FLG_ADDR		0xffc03402 /* SPI 1 flag register 16 bit */
+#define SPI1_FLG			HALFWORD_REF(SPI1_FLG_ADDR)
+#define SPI1_ST_ADDR		0xffc03404 /* SPI 1 status register 16 bit */
+#define SPI1_ST				HALFWORD_REF(SPI1_ST_ADDR)
+#define SPI1_TDBR_ADDR		0xffc03406 /* SPI 1 transmit data buffer register 16 bit */
+#define SPI1_TDBR			HALFWORD_REF(SPI1_TDBR_ADDR)
+#define SPI1_RDBR_ADDR		0xffc03408 /* SPI 1 receive data buffer register 16 bit */
+#define SPI1_RDBR			HALFWORD_REF(SPI1_RDBR_ADDR)
+#define SPI1_BAUD_ADDR		0xffc0340a /* SPI 1 baud rate register 16 bit */
+#define SPI1_BAUD			HALFWORD_REF(SPI1_BAUD_ADDR)
+#define SPI1_SHADOW_ADDR	0xffc0340c /* SPI 1 RDBR register 16 bit */
+#define SPI1_SHADOW			HALFWORD_REF(SPI1_SHADOW_ADDR)
+
+#define SPI1_CURR_PTR_ADDR		0xffc03600 /* SPI 1 DMA current pointer register 16 bit */
+#define SPI1_CURR_PTR			HALFWORD_REF(SPI1_CURR_PTR_ADDR)
+#define SPI1_CONFIG_ADDR		0xffc03602 /* SPI 1 DMA configuration register 16 bit */
+#define SPI1_CONFIG				HALFWORD_REF(SPI1_CONFIG_ADDR)
+#define SPI1_START_ADDR_HI_ADDR	0xffc03604 /* SPI 1 DMA start address hi register 16 bit */
+#define SPI1_START_ADDR_HI		HALFWORD_REF(SPI1_START_ADDR_HI_ADDR)
+#define SPI1_START_ADDR_LO_ADDR	0xffc03606 /* SPI 1 DMA start address lo register 16 bit */
+#define SPI1_START_ADDR_LO		HALFWORD_REF(SPI1_START_ADDR_LO_ADDR)
+#define SPI1_COUNT_ADDR			0xffc03608 /* SPI 1 DMA count register 16 bit */
+#define SPI1_COUNT				HALFWORD_REF(SPI1_COUNT_ADDR)
+#define SPI1_NEXT_DESCR_ADDR	0xffc0360a /* SPI 1 DMA Next descriptor pointer register 16 bit */
+#define SPI1_NEXT_DESCR			HALFWORD_REF(SPI1_NEXT_DESCR_ADDR)
+#define SPI1_DESCR_RDY_ADDR		0xffc0360c /* SPI 1 DMA descriptor ready register 16 bit */
+#define SPI1_DESCR_RDY			HALFWORD_REF(SPI1_DESCR_RDY_ADDR)
+#define SPI1_DMA_INT_ADDR		0xffc0360e /* SPI 1 DMA interrupt register 16 bit */
+#define SPI1_DMA_INT			HALFWORD_REF(SPI1_DMA_INT_ADDR)
+
+/****************************
+ *
+ *  MEMORY DMA CONTROLLER REGISTERS  (0XFFC03800 - 0XFFC03BFF)
+ *
+ ****************************/
+
+#define MDW_DCP_ADDR		0xffc03800 /* Current pointer write channel register 16 bit */
+#define MDW_DCP				HALFWORD_REF(MDW_DCP_ADDR)
+#define MDW_DCFG_ADDR		0xffc03802 /* DMA configuration write channel register 16 bit */
+#define MDW_DCFG			HALFWORD_REF(MDW_DCFG_ADDR)
+#define MDW_DSAH_ADDR		0xffc03804 /* Start address hi write channel register 16 bit */
+#define MDW_DSAH			HALFWORD_REF(MDW_DSAH_ADDR)
+#define MDW_DSAL_ADDR		0xffc03806 /* Start address lo write channel register 16 bit */
+#define MDW_DSAL			HALFWORD_REF(MDW_DSAL_ADDR)
+#define MDW_DCT_ADDR		0xffc03808 /* DMA count write channel register 16 bit */
+#define MDW_DCT				HALFWORD_REF(MDW_DCT_ADDR)
+#define MDW_DND_ADDR		0xffc0380a /* Next descriptor pointer write channel register 16 bit */
+#define MDW_DND				HALFWORD_REF(MDW_DND_ADDR)
+#define MDW_DDR_ADDR		0xffc0380c /* Descriptor ready write channel register 16 bit */
+#define MDW_DDR				HALFWORD_REF(MDW_DDR_ADDR)
+#define MDW_DI_ADDR			0xffc0380e /* DMA interrupt write channel register 16 bit */
+#define MDW_DI				HALFWORD_REF(MDW_DI_ADDR)
+
+#define MDR_DCP_ADDR		0xffc03900 /* Current pointer read channel register 16 bit */
+#define MDR_DCP				HALFWORD_REF(MDR_DCP_ADDR)
+#define MDR_DCFG_ADDR		0xffc03902 /* DMA configuration read channel register 16 bit */
+#define MDR_DCFG			HALFWORD_REF(MDR_DCFG_ADDR)
+#define MDR_DSAH_ADDR		0xffc03904 /* Start address hi read channel register 16 bit */
+#define MDR_DSAH			HALFWORD_REF(MDR_DSAH_ADDR)
+#define MDR_DSAL_ADDR		0xffc03906 /* Start address lo read channel register 16 bit */
+#define MDR_DSAL			HALFWORD_REF(MDR_DSAL_ADDR)
+#define MDR_DCT_ADDR		0xffc03908 /* DMA count read channel register 16 bit */
+#define MDR_DCT				HALFWORD_REF(MDR_DCT_ADDR)
+#define MDR_DND_ADDR		0xffc0390a /* Next descriptor pointer read channel register 16 bit */
+#define MDR_DND				HALFWORD_REF(MDR_DND_ADDR)
+#define MDR_DDR_ADDR		0xffc0390c /* Descriptor ready read channel register 16 bit */
+#define MDR_DDR				HALFWORD_REF(MDR_DDR_ADDR)
+#define MDR_DI_ADDR			0xffc0390e /* DMA interrupt read channel register 16 bit */
+#define MDR_DI				HALFWORD_REF(MDR_DI_ADDR)
+
+/****************************
+ *
+ *  ASYNCHRONOUS MEMORY CONTROLLER REGISTERS EDIU (0XFFC03C00 - 0XFFC03FFF)
+ *
+ ****************************/
+
+#define EBIU_AMGCTL_ADDR	0xffc03c00 /* Asynchronous memory global control register ? bit */
+#define EBIU_AMGCTL			WORD_REF(MDW_AMGCTL_ADDR)
+#define EBIU_AMBCTL0_ADDR	0xffc03c04 /* Asynchronous memory bank control register 0 32 bit */
+#define EBIU_AMBCTL0		WORD_REF(MDW_AMBCTL0_ADDR)
+#define EBIU_AMBCTL1_ADDR	0xffc03c08 /* Asynchronous memory bank control register 1 32 bit */
+#define EBIU_AMBCTL1		WORD_REF(MDW_AMBCTL1_ADDR)
+
+/****************************
+ *
+ *  PCI BRIDGE PAB REGISTERS  (0XFFC04000 - 0XFFC043FF)
+ *
+ ****************************/
+
+#define PCI_CTL_ADDR		0xffc04000 /* PCI bridge control register 32 bit */
+#define PCI_CTL				WORD_REF(PCI_CTL_ADDR)
+#define PCI_STAT_ADDR		0xffc04004 /* PCI bridge status register 32 bit */
+#define PCI_STAT			WORD_REF(PCI_STAT_ADDR)
+#define PCI_ICTL_ADDR		0xffc04008 /* PCI bridge interrupt control register 32 bit */
+#define PCI_ICTL			WORD_REF(PCI_ICTL_ADDR)
+#define PCI_MBAP_ADDR		0xffc0400c /* PCI memory space base address pointer[31:27] register 32 bit */
+#define PCI_MBAP			WORD_REF(PCI_MBAP_ADDR)
+#define PCI_IBAP_ADDR		0xffc04010 /* PCI IO space base address pointer register 32 bit */
+#define PCI_IBAP			WORD_REF(PCI_IBAP_ADDR)
+#define PCI_CPAB_ADDR		0xffc04014 /* PCI config space base address port register 32 bit */
+#define PCI_CPAB			WORD_REF(PCI_CPAB_ADDR)
+#define PCI_TMBAP_ADDR		0xffc04018 /* PCI to Tahoe memory base address pointer register 32 bit */
+#define PCI_TMBAP			WORD_REF(PCI_TMBAP_ADDR)
+#define PCI_TIBAP_ADDR		0xffc0401c /* PCI to Tahoe IO base address pointer register 32 bit */
+#define PCI_TIBAP			WORD_REF(PCI_TIBAP_ADDR)
+
+/****************************
+ *
+ *  PCI BRIDGE EXTERNAL ACCESS BUS REGISTERS  (0XEEFFFF00 - 0XEEFFFFFF)
+ *
+ ****************************/
+
+#define PCI_DMBARM_ADDR		0xeeffff00 /* PCI Device memory bar mask register 32 bit */
+#define PCI_DMBARM			WORD_REF(PCI_DMBARM_ADDR)
+#define PCI_DIBARM_ADDR		0xeeffff04 /* PCI Device IO bar mask register 32 bit */
+#define PCI_DIBARM			WORD_REF(PCI_DIBARM_ADDR)
+#define PCI_CFG_DIC_ADDR	0xeeffff08 /* PCI config Device ID register 32 bit */
+#define PCI_CFG_DIC			WORD_REF(PCI_CFG_DIC_ADDR)
+#define PCI_CFG_VIC_ADDR	0xeeffff0c /* PCI config vendor ID register 32 bit */
+#define PCI_CFG_VIC			WORD_REF(PCI_CFG_VIC_ADDR)
+#define PCI_CFG_STAT_ADDR	0xeeffff10 /* PCI config status (read only) register 32 bit */
+#define PCI_CFG_STAT		WORD_REF(PCI_CFG_STAT_ADDR)
+#define PCI_CFG_CMD_ADDR	0xeeffff14 /* PCI config command register 32 bit */
+#define PCI_CFG_CMD			WORD_REF(PCI_CFG_CMD_ADDR)
+#define PCI_CFG_CC_ADDR		0xeeffff18 /* PCI config class code register 32 bit */
+#define PCI_CFG_CC			WORD_REF(PCI_CFG_CC_ADDR)
+#define PCI_CFG_RID_ADDR	0xeeffff1C /* PCI config revision ID register 32 bit */
+#define PCI_CFG_RID			WORD_REF(PCI_CFG_RID_ADDR)
+#define PCI_CFG_BIST_ADDR	0xeeffff20 /* PCI config BIST register 32 bit */
+#define PCI_CFG_BIST		WORD_REF(PCI_CFG_BIST_ADDR)
+#define PCI_CFG_HT_ADDR		0xeeffff24 /* PCI config header type register 32 bit */
+#define PCI_CFG_HT			WORD_REF(PCI_CFG_HT_ADDR)
+#define PCI_CFG_MLT_ADDR	0xeeffff28 /* PCI config memory latency timer register 32 bit */
+#define PCI_CFG_MLT			WORD_REF(PCI_CFG_MLT_ADDR)
+#define PCI_CFG_CLS_ADDR	0xeeffff2C /* PCI config cache line (block) size register 32 bit */
+#define PCI_CFG_CLS			WORD_REF(PCI_CFG_CLS_ADDR)
+#define PCI_CFG_MBAR_ADDR	0xeeffff30 /* PCI config memory base address register 32 bit */
+#define PCI_CFG_MBAR		WORD_REF(PCI_CFG_MBAR_ADDR)
+#define PCI_CFG_IBAR_ADDR	0xeeffff34 /* PCI config IO base address register 32 bit */
+#define PCI_CFG_IBAR		WORD_REF(PCI_CFG_IBAR_ADDR)
+#define PCI_CFG_SID_ADDR	0xeeffff38 /* PCI config subsystem ID register 32 bit */
+#define PCI_CFG_SID			WORD_REF(PCI_CFG_SID_ADDR)
+#define PCI_CFG_SVID_ADDR	0xeeffff3C /* PCI config subsystem vendor ID register 32 bit */
+#define PCI_CFG_SVID		WORD_REF(PCI_CFG_SVID_ADDR)
+#define PCI_CFG_MAXL_ADDR	0xeeffff40 /* PCI config maximum latency cycles register 32 bit */
+#define PCI_CFG_MAXL		WORD_REF(PCI_CFG_MAXL_ADDR)
+#define PCI_CFG_MING_ADDR	0xeeffff44 /* PCI config minimum grant cycles register 32 bit */
+#define PCI_CFG_MING		WORD_REF(PCI_CFG_MING_ADDR)
+#define PCI_CFG_IP_ADDR		0xeeffff48 /* PCI config interrupt pin register 32 bit */
+#define PCI_CFG_IP			WORD_REF(PCI_CFG_IP_ADDR)
+#define PCI_CFG_IL_ADDR		0xeeffff4C /* PCI config interrupt line register 32 bit */
+#define PCI_CFG_IL			WORD_REF(PCI_CFG_IL_ADDR)
+#define PCI_HMCTL_ADDR		0xeeffff50 /* PCI config blocking BAR mask 1 (host only) register 32 bit */
+#define PCI_HMCTL			WORD_REF(PCI_HMCTL_ADDR)
+
+/****************************
+ *
+ *  UNIVERSAL SERIAL BUS INTERFACE (USB) REGISTERS  (0XFFC04400 - 0XFFC047FF)
+ *
+ ****************************/
+
+#define USBD_ID_ADDR		0xffc04400 /* USB Device ID register 16 bit */
+#define USBD_ID				HALFWORD_REF(USBD_ID_ADDR)
+#define USBD_FRM_ADDR		0xffc04402 /* Current USB frame number register 16 bit */
+#define USBD_FRM			HALFWORD_REF(USBD_FRM_ADDR)
+#define USBD_FRMAT_ADDR		0xffc04404 /* Match value for USB frame number register 16 bit */
+#define USBD_FRMAT			HALFWORD_REF(USBD_FRMAT_ADDR)
+#define USBD_EPBUF_ADDR		0xffc04406 /* Enables download of configuration into UDC core register 16 bit */
+#define USBD_EPBUF			HALFWORD_REF(USBD_EPBUF_ADDR)
+#define USBD_STAT_ADDR		0xffc04408 /* Return USBD Module status register 16 bit */
+#define USBD_STAT			HALFWORD_REF(USBD_STAT_ADDR)
+#define USBD_CTRL_ADDR		0xffc0440a /* Allows configuration & control of USBD module register 16 bit */
+#define USBD_CTRL			HALFWORD_REF(USBD_CTRL_ADDR)
+#define USBD_GINTR_ADDR		0xffc0440c /* Global interrupt register 16 bit */
+#define USBD_GINTR			HALFWORD_REF(USBD_GINTR_ADDR)
+#define USBD_GMASK_ADDR		0xffc0440e /* Global interrupt register mask register 16 bit */
+#define USBD_GMASK			HALFWORD_REF(USBD_GMASK_ADDR)
+
+#define USBD_DMACFG_ADDR	0xffc04440 /* DMA Master channel configuration register 16 bit */
+#define USBD_DMACFG			HALFWORD_REF(USBD_DMACFG_ADDR)
+#define USBD_DMABL_ADDR		0xffc04442 /* DMA Master channel base address low register 16 bit */
+#define USBD_DMABL			HALFWORD_REF(USBD_DMABL_ADDR)
+#define USBD_DMABH_ADDR		0xffc04444 /* DMA Master channel base address high register 16 bit */
+#define USBD_DMABH			HALFWORD_REF(USBD_DMABH_ADDR)
+#define USBD_DMACT_ADDR		0xffc04446 /* DMA Master channel count register 16 bit */
+#define USBD_DMACT			HALFWORD_REF(USBD_DMACT_ADDR)
+#define USBD_DMAIRQ_ADDR	0xffc04448 /* DMA Master channel IRQ register 16 bit */
+#define USBD_DMAIRQ			HALFWORD_REF(USBD_DMAIRQ_ADDR)
+
+#define USBD_INTR0_ADDR		0xffc04480 /* USB Endpoint 0 interrupt register 16 bit */
+#define USBD_INTR0			HALFWORD_REF(USBD_INTR0_ADDR)
+#define USBD_MASK0_ADDR		0xffc04482 /* USB Endpoint 0 mask register 16 bit */
+#define USBD_MASK0			HALFWORD_REF(USBD_MASK0_ADDR)
+#define USBD_EPCFG0_ADDR	0xffc04484 /* USB Endpoint 0 control register 16 bit */
+#define USBD_EPCFG0			HALFWORD_REF(USBD_EPCFG0_ADDR)
+#define USBD_EPADR0_ADDR	0xffc04486 /* USB Endpoint 0 address offset register 16 bit */
+#define USBD_EPADR0			HALFWORD_REF(USBD_EPADR0_ADDR)
+#define USBD_EPLEN0_ADDR	0xffc04488 /* USB Endpoint 0 buffer length register 16 bit */
+#define USBD_EPLEN0			HALFWORD_REF(USBD_EPLEN0_ADDR)
+
+#define USBD_INTR1_ADDR		0xffc0448a /* USB Endpoint 1 interrupt register 16 bit */
+#define USBD_INTR1			HALFWORD_REF(USBD_INTR1_ADDR)
+#define USBD_MASK1_ADDR		0xffc0448c /* USB Endpoint 1 mask register 16 bit */
+#define USBD_MASK1			HALFWORD_REF(USBD_MASK1_ADDR)
+#define USBD_EPCFG1_ADDR	0xffc0448e /* USB Endpoint 1 control register 16 bit */
+#define USBD_EPCFG1			HALFWORD_REF(USBD_EPCFG1_ADDR)
+#define USBD_EPADR1_ADDR	0xffc04490 /* USB Endpoint 1 address offset register 16 bit */
+#define USBD_EPADR1			HALFWORD_REF(USBD_EPADR1_ADDR)
+#define USBD_EPLEN1_ADDR	0xffc04492 /* USB Endpoint 1 buffer length register 16 bit */
+#define USBD_EPLEN1			HALFWORD_REF(USBD_EPLEN1_ADDR)
+
+#define USBD_INTR2_ADDR		0xffc04494 /* USB Endpoint 2 interrupt register 16 bit */
+#define USBD_INTR2			HALFWORD_REF(USBD_INTR2_ADDR)
+#define USBD_MASK2_ADDR		0xffc04496 /* USB Endpoint 2 mask register 16 bit */
+#define USBD_MASK2			HALFWORD_REF(USBD_MASK2_ADDR)
+#define USBD_EPCFG2_ADDR	0xffc04498 /* USB Endpoint 2 control register 16 bit */
+#define USBD_EPCFG2			HALFWORD_REF(USBD_EPCFG2_ADDR)
+#define USBD_EPADR2_ADDR	0xffc0449a /* USB Endpoint 2 address offset register 16 bit */
+#define USBD_EPADR2			HALFWORD_REF(USBD_EPADR2_ADDR)
+#define USBD_EPLEN2_ADDR	0xffc0449c /* USB Endpoint 2 buffer length register 16 bit */
+#define USBD_EPLEN2			HALFWORD_REF(USBD_EPLEN2_ADDR)
+
+/* Fixed by HuTao, Jun18 2003 4:35PM */
+#if 0
+#define USBD_INTR3_ADDR		0xffc0448e /* USB Endpoint 3 interrupt register 16 bit */
+#else
+#define USBD_INTR3_ADDR		0xffc0449e /* USB Endpoint 3 interrupt register 16 bit */
+#endif
+
+#define USBD_INTR3			HALFWORD_REF(USBD_INTR3_ADDR)
+#define USBD_MASK3_ADDR		0xffc044a0 /* USB Endpoint 3 mask register 16 bit */
+#define USBD_MASK3			HALFWORD_REF(USBD_MASK3_ADDR)
+#define USBD_EPCFG3_ADDR	0xffc044a2 /* USB Endpoint 3 control register 16 bit */
+#define USBD_EPCFG3			HALFWORD_REF(USBD_EPCFG3_ADDR)
+#define USBD_EPADR3_ADDR	0xffc044a4 /* USB Endpoint 3 address offset register 16 bit */
+#define USBD_EPADR3			HALFWORD_REF(USBD_EPADR3_ADDR)
+#define USBD_EPLEN3_ADDR	0xffc044a6 /* USB Endpoint 3 buffer length register 16 bit */
+#define USBD_EPLEN3			HALFWORD_REF(USBD_EPLEN3_ADDR)
+
+#define USBD_INTR4_ADDR		0xffc044a8 /* USB Endpoint 4 interrupt register 16 bit */
+#define USBD_INTR4			HALFWORD_REF(USBD_INTR4_ADDR)
+#define USBD_MASK4_ADDR		0xffc044aa /* USB Endpoint 4 mask register 16 bit */
+#define USBD_MASK4			HALFWORD_REF(USBD_MASK4_ADDR)
+#define USBD_EPCFG4_ADDR	0xffc044ac /* USB Endpoint 4 control register 16 bit */
+#define USBD_EPCFG4			HALFWORD_REF(USBD_EPCFG4_ADDR)
+#define USBD_EPADR4_ADDR	0xffc044ae /* USB Endpoint 4 address offset register 16 bit */
+#define USBD_EPADR4			HALFWORD_REF(USBD_EPADR4_ADDR)
+#define USBD_EPLEN4_ADDR	0xffc044b0 /* USB Endpoint 4 buffer length register 16 bit */
+#define USBD_EPLEN4			HALFWORD_REF(USBD_EPLEN4_ADDR)
+
+#define USBD_INTR5_ADDR		0xffc044b2 /* USB Endpoint 5 interrupt register 16 bit */
+#define USBD_INTR5			HALFWORD_REF(USBD_INTR5_ADDR)
+#define USBD_MASK5_ADDR		0xffc044b4 /* USB Endpoint 5 mask register 16 bit */
+#define USBD_MASK5			HALFWORD_REF(USBD_MASK5_ADDR)
+#define USBD_EPCFG5_ADDR	0xffc044b6 /* USB Endpoint 5 control register 16 bit */
+#define USBD_EPCFG5			HALFWORD_REF(USBD_EPCFG5_ADDR)
+#define USBD_EPADR5_ADDR	0xffc044b8 /* USB Endpoint 5 address offset register 16 bit */
+#define USBD_EPADR5			HALFWORD_REF(USBD_EPADR5_ADDR)
+#define USBD_EPLEN5_ADDR	0xffc044ba /* USB Endpoint 5 buffer length register 16 bit */
+#define USBD_EPLEN5			HALFWORD_REF(USBD_EPLEN5_ADDR)
+
+#define USBD_INTR6_ADDR		0xffc044bc /* USB Endpoint 6 interrupt register 16 bit */
+#define USBD_INTR6			HALFWORD_REF(USBD_INTR6_ADDR)
+#define USBD_MASK6_ADDR		0xffc044be /* USB Endpoint 6 mask register 16 bit */
+#define USBD_MASK6			HALFWORD_REF(USBD_MASK6_ADDR)
+#define USBD_EPCFG6_ADDR	0xffc044c0 /* USB Endpoint 6 control register 16 bit */
+#define USBD_EPCFG6			HALFWORD_REF(USBD_EPCFG6_ADDR)
+#define USBD_EPADR6_ADDR	0xffc044c2 /* USB Endpoint 6 address offset register 16 bit */
+#define USBD_EPADR6			HALFWORD_REF(USBD_EPADR6_ADDR)
+#define USBD_EPLEN6_ADDR	0xffc044c4 /* USB Endpoint 6 buffer length register 16 bit */
+#define USBD_EPLEN6			HALFWORD_REF(USBD_EPLEN6_ADDR)
+
+#define USBD_INTR7_ADDR		0xffc044c6 /* USB Endpoint 7 interrupt register 16 bit */
+#define USBD_INTR7			HALFWORD_REF(USBD_INTR7_ADDR)
+#define USBD_MASK7_ADDR		0xffc044c8 /* USB Endpoint 7 mask register 16 bit */
+#define USBD_MASK7			HALFWORD_REF(USBD_MASK7_ADDR)
+#define USBD_EPCFG7_ADDR	0xffc044ca /* USB Endpoint 7 control register 16 bit */
+#define USBD_EPCFG7			HALFWORD_REF(USBD_EPCFG7_ADDR)
+#define USBD_EPADR7_ADDR	0xffc044cc /* USB Endpoint 7 address offset register 16 bit */
+#define USBD_EPADR7			HALFWORD_REF(USBD_EPADR7_ADDR)
+#define USBD_EPLEN7_ADDR	0xffc044ce /* USB Endpoint 7 buffer length register 16 bit */
+#define USBD_EPLEN7			HALFWORD_REF(USBD_EPLEN7_ADDR)
+
+/****************************
+ *
+ * SYSTEM BUS INTERFACE UNIT REGISTERS  (0XFFC04800 - 0XFFC04FFF)
+ *
+ ****************************/
+
+#define L1SBAR_ADDR		0xffc04840 /* L1 SRAM base address register 16 bit */
+#define L1SBAR			HALFWORD_REF(L1SBAR_ADDR)
+#define L1CSR_ADDR		0xffc04844 /* L1 SRAM control initialization register 32 bit */
+#define L1CSR			WORD_REF(L1CSR_ADDR)
+#define DB_NDBP_ADDR		0xffc04880 /* Next descriptor base pointer register 32 bit */
+#define DB_NDBP			WORD_REF(DB_NDBP_ADDR)
+#define DB_ACOMP_ADDR		0xffc04884 /* DMA bus address comparator register 32 bit */
+#define DB_ACOMP		WORD_REF(DB_ACOMP_ADDR)
+#define DB_CCOMP_ADDR		0xffc04888 /* DMA bus control comparator register 32 bit */
+#define DB_CCOMP		WORD_REF(DB_CCOMP_ADDR)
+
+/****************************
+ *
+ * SDRAM CONTROLLER EXTERNAL BUS INTERFACE REGISTERS  (0XFFC04C00 - 0XFFC04FFF)
+ *
+ ****************************/
+
+#define EBIU_SDGCTL_ADDR	0xffc04c00 /* SDRAM Memory global control register 32 bit */
+#define EBIU_SDGCTL		WORD_REF(EBIU_SDGCTL_ADDR)
+#define EBIU_SDBCTL_ADDR	0xffc04c00 /* SDRAM Memory bank control register 32 bit */
+#define EBIU_SDBCTL		WORD_REF(EBIU_SDBCTL_ADDR)
+#define EBIU_SDRRC_ADDR		0xffc04c00 /* SDRAM Memory refresh rate count register 16 bit */
+#define EBIU_SDRRC		HALFWORD_REF(EBIU_SDRRC_ADDR)
+#define EBIU_SDSTAT_ADDR	0xffc04c00 /* SDRAM control status register 16 bit */
+#define EBIU_SDSTAT		HALFWORD_REF(EBIU_SDSTAT_ADDR)
+
+
+ /*      FOLLOWING ARE THE FRIO CORE MMR REGISTERS (TOP 2 MB)     */
+
+/****************************
+ *
+ *  L1 DATA MEMORY CONTROLLER REGISTERS  (0XFFE00000 - 0XFFE00404)
+ *
+ ****************************/
+
+#define SRAM_BASE_ADDR_ADDR	0xffe00000 /* read only register 32 bit */
+#define SRAM_BASE_ADDR		WORD_REF(SRAM_BASE_ADDR_ADDR)
+#define DATA_FAULT_STATUS_ADDR	0xffe00008 /* read only register 32 bit */
+#define DATA_FAULT_STATUS	WORD_REF(DATA_FAULT_STATUS_ADDR)
+#define DATA_FAULT_ADDR_ADDR	0xffe0000c /* read only register 32 bit */
+#define DATA_FAULT_ADDR		WORD_REF(DATA_FAULT_ADDR_ADDR)
+
+		/* These are total sixtenn */
+		
+#define DCPLB_ADDR_ADDR		0xffe00100 /* read/write register 32 bit */
+#define DCPLB_ADDR		WORD_REF(DCPLB_ADDR_ADDR)
+
+		/* These are total sixtenn */
+		
+#define DCPLB_DATA_ADDR		0xffe00200 /* read/write register 32 bit */
+#define DCPLB_DATA		WORD_REF(DCPLB_DATA_ADDR)
+
+
+		/* These are total 4 */
+
+#define DTEST_DATA_ADDR		0xffe00400 /* read/write register 32 bit */
+#define DTEST_DATA		WORD_REF(DTEST_DATA_ADDR)
+
+/****************************
+ *
+ *  L1 CODE MEMORY CONTROLLER REGISTERS  (0XFFE01004 - 0XFFE1404)
+ *
+ ****************************/
+
+#define CODE_FAULT_STATUS_ADDR	0xffe01008 /* read only register 32 bit */
+#define CODE_FAULT_STATUS	WORD_REF(CODE_FAULT_STATUS_ADDR)
+#define CODE_FAULT_ADDR_ADDR	0xffe0100c /* read only register 32 bit */
+#define CODE_FAULT_ADDR		WORD_REF(CODE_FAULT_ADDR_ADDR)
+
+		/* These are total sixtenn */
+		
+#define ICPLB_ADDR_ADDR		0xffe01100 /* read/write register 32 bit */
+#define ICPLB_ADDR		WORD_REF(ICPLB_ADDR_ADDR)
+
+		/* These are total sixtenn */
+		
+#define ICPLB_DATA_ADDR		0xffe01200 /* read/write register 32 bit */
+#define ICPLB_DATA		WORD_REF(ICPLB_DATA_ADDR)
+
+
+		/* These are total 4 */
+
+#define ITEST_DATA_ADDR		0xffe01400 /* read/write register 32 bit */
+#define ITEST_DATA		WORD_REF(ITEST_DATA_ADDR)
+
+/****************************
+ *
+ *  INTERRUPT CONTROLLER REGISTERS  (0XFFE02000 - 0XFFE0210C)
+ *
+ ****************************/
+
+ /*   EVENT VECTOR TABLE IS USED FOR 16 INTERRUPTS AS SHOWN BELOW
+      ALSO THEIR PRIORITY SEQUENCE IS ALSO GIVEN HERE
+      1		EMULATION		HIGHEST
+      2		RESET
+      3		NMI
+      4		EXCEPTION
+      5		INTERRUPTS		LOWEST */
+
+/*  Used with JTAG register 32 bit */
+#define EVT_EMULATION_ADDR	0xffe02000 
+#define EVT_EMULATION		WORD_REF(EVT_EMULATION_ADDR)
+/*  register 32 bit */
+#define EVT_RESET_ADDR		0xffe02004 
+#define EVT_RESET		WORD_REF(EVT_RESET_ADDR)
+/*  NMI register 32 bit */
+#define EVT_NMI_ADDR		0xffe02008 
+#define EVT_NMI			WORD_REF(EVT_NMI_ADDR)
+/*  Identification with code in EXCAUSE register 32 bit */
+#define EVT_EXCEPTION_ADDR	0xffe0200c 
+#define EVT_EXCEPTION		WORD_REF(EVT_EXCEPTION_ADDR)
+/*  Global interrupt enable register 32 bit */
+#define EVT_GLOBAL_INT_ENB_ADDR	0xffe02010 
+#define EVT_GLOBAL_INT_ENB	WORD_REF(EVT_GLOBAL_INT_ENB_ADDR)
+/*  Active while error condition exsists register 32 bit */
+#define EVT_HARDWARE_ERROR_ADDR	0xffe02014 
+#define EVT_HARDWARE_ERROR	WORD_REF(EVT_HARDWARE_ERROR_ADDR)
+/*  High priority timer register 32 bit */
+#define EVT_TIMER_ADDR		0xffe02018 
+#define EVT_TIMER		WORD_REF(EVT_TIMER_ADDR)
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG7_ADDR		0xffe0201c 
+#define EVT_IVG7		WORD_REF(EVT_IVG7_ADDR)
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG8_ADDR		0xffe02020 
+#define EVT_IVG8		WORD_REF(EVT_IVG8_ADDR)
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG9_ADDR		0xffe02024 
+#define EVT_IVG9		WORD_REF(EVT_IVG9_ADDR)
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG10_ADDR		0xffe02028 
+#define EVT_IVG10		WORD_REF(EVT_IVG10_ADDR)
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG11_ADDR		0xffe0202c 
+#define EVT_IVG11		WORD_REF(EVT_IVG11_ADDR)
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG12_ADDR		0xffe02030 
+#define EVT_IVG12		WORD_REF(EVT_IVG12_ADDR)
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG13_ADDR		0xffe02034 
+#define EVT_IVG13		WORD_REF(EVT_IVG13_ADDR)
+
+/* IVG14 & IVG15 should be used as software interrupts  */
+
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG14_ADDR		0xffe02038 
+#define EVT_IVG14		WORD_REF(EVT_IVG14_ADDR)
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG15_ADDR		0xffe0203c 
+#define EVT_IVG15		WORD_REF(EVT_IVG15_ADDR)
+
+#define EVT_OVERRIDE_ADDR	0xffe02100 /*  register 32 bit */
+#define EVT_OVERRIDE		WORD_REF(EVT_OVERRIDE_ADDR)
+#define IMASK_ADDR		0xffe02104 /*  register 32 bit */
+#define IMASK			WORD_REF(IMASK_ADDR)
+#define IPEND_ADDR		0xffe02108 /*  register 32 bit */
+#define IPEND			WORD_REF(IPEND_ADDR)
+#define ILAT_ADDR		0xffe0210c /*  register 32 bit */
+#define ILAT			WORD_REF(ILAT_ADDR)
+
+/****************************
+ *
+ *  TIMER REGISTERS  (0XFFC03000 - 0XFFC0300C)
+ *
+ ****************************/
+
+#define TCNTL_ADDR		0xffe03000 /*  register 32 bit */
+#define TCNTL			WORD_REF(TCNTL_ADDR)
+#define TPERIOD_ADDR		0xffe03004 /*  register 32 bit */
+#define TPERIOD			WORD_REF(TPERIOD_ADDR)
+#define TSCALE_ADDR		0xffe03008 /*  register 32 bit */
+#define TSCALE			WORD_REF(TSCALE_ADDR)
+#define TCOUNT_ADDR		0xffe0300c /*  register 32 bit */
+#define TCOUNT			WORD_REF(TCOUNT_ADDR)
+
+/****************************
+ *
+ *  DEBUG & EMULATION UNIT REGISTERS  (0XFFC05000 - 0XFFC0500C)
+ *
+ ****************************/
+
+#define DSPID_ADDR		0xffe05000 /*  register 32 bit */
+#define DSPID			WORD_REF(DSPID_ADDR)
+#define DBGSTAT_ADDR		0xffe05008 /*  register 32 bit */
+#define DBGSTAT			WORD_REF(DBGSTAT_ADDR)
+#define EMUDAT_ADDR		0xffe0500c /*  register 32 bit */
+#define EMUDAT			WORD_REF(EMUDAT_ADDR)
+
+/****************************
+ *
+ *  TRACE UNIT REGISTERS  (0XFFC06000 - 0XFFC06100)
+ *
+ ****************************/
+
+#define TBUFCTL_ADDR		0xffe06000 /*  register 32 bit */
+#define TBUFCTL			WORD_REF(TBUFCTL_ADDR)
+#define TBUFSTAT_ADDR		0xffe06004 /*  register 32 bit */
+#define TBUFSTAT		WORD_REF(TBUFSTAT_ADDR)
+#define TBUF_ADDR		0xffe06100 /*  register 32 bit */
+#define TBUF			WORD_REF(TBUF_ADDR)
+
+/****************************
+ *
+ *  WATCHPOINT & PATCH UNIT REGISTERS  (0XFFC07000 - 0XFFC07200)
+ *
+ ****************************/
+
+#define WPIACTL_ADDR		0xffe07000 /*  register 32 bit */
+#define WPIACTL			WORD_REF(WPIACTL_ADDR)
+		/* TOTAL OF 6  */
+#define WPIA_ADDR		0xffe07040 /*  register 32 bit */
+#define WPIA			WORD_REF(WPIA_ADDR)
+		/* TOTAL OF 6  */
+#define WPIACNT_ADDR		0xffe07080 /*  register 32 bit */
+#define WPIACNT			WORD_REF(WPIACNT_ADDR)
+
+#define WPDACTL_ADDR		0xffe07100 /*  register 32 bit */
+#define WPDACTL			WORD_REF(WPDACTL_ADDR)
+		/* TOTAL OF 2 */
+#define WPDA_ADDR		0xffe07140 /*  register 32 bit */
+#define WPDA			WORD_REF(WPDA_ADDR)
+		/* TOTAL OF 2 */
+#define WPDACNT_ADDR		0xffe07180 /*  register 32 bit */
+#define WPDACNT			WORD_REF(WPDACNT_ADDR)
+
+#define WPSTAT_ADDR		0xffe07200 /*  register 32 bit */
+#define WPSTAT			WORD_REF(WPSTAT_ADDR)
+
+/****************************
+ *
+ *  PERFORMANCE MONITOR REGISTERS  (0XFFC08000 - 0XFFC08104)
+ *
+ ****************************/
+
+#define PFCTL_ADDR		0xffe08000 /*  register 32 bit */
+#define PFCTL			WORD_REF(PFCTL_ADDR)
+		/* TOTAL OF 2 */
+#define PFCNTR_ADDR		0xffe08100 /*  register 32 bit */
+#define PFCNTR			WORD_REF(PFCNTR_ADDR)
+
+/***************************
+ *
+ * SYSTEM INTERRUPT CONTROLLER REGISTERS
+ *
+ ***************************/
+#define SIC_ISR_ADDR		0xffc00120 /*  register 32 bit */
+#define SIC_ISR			WORD_REF(SIC_ISR_ADDR)
+
+#define SIC_IWR_ADDR		0xffc00124 /*  register 32 bit */
+#define SIC_IWR			WORD_REF(SIC_IWR_ADDR)
+
+#define SIC_MASK_ADDR		0xffc0010c /*  register 32 bit */
+#define SIC_MASK		WORD_REF(SIC_MASK_ADDR)
+
+#define SIC_RVECT_ADDR		0xffc00108 /*  register 16 bit */
+#define SIC_RVECT		HALFWORD_REF(SIC_RVECT_ADDR)
+
+#define SIC_MASK_ALL		0x00000000
+
+#endif  /* _BLKFin_H_  */
diff -urN linux-2.4.29/include/asm-blackfin/board/bf533_irq.h linux-2.4.29-uc1/include/asm-blackfin/board/bf533_irq.h
--- linux-2.4.29/include/asm-blackfin/board/bf533_irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/board/bf533_irq.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,112 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/irq.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Changed by HuTao Apr18, 2003
+ *
+ * Copyright was missing when I got the code so took from MIPS arch ...MaTed---
+ * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle
+ * Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001 by Ralf Baechle
+ *
+ * Adapted for BlackFin (ADI) by Ted Ma <mated@sympatico.ca>
+ * Copyright (c) 2002 Arcturus Networks Inc. (www.arcturusnetworks.com)
+ * Copyright (c) 2002 Lineo, Inc. <mattw@lineo.com>
+ *
+ * Adapted for BlackFin BF533 by Bas Vermeulen <bas@buyways.nl>
+ * Copyright (c) 2003 BuyWays B.V. (www.buyways.nl)
+ */
+
+#ifndef _BF533_IRQ_H_
+#define _BF533_IRQ_H_
+
+/*
+ * Interrupt source definitions
+             Event Source    Core Event Name
+Core        Emulation               **
+ Events         (highest priority)  EMU         0
+            Reset                   RST         1
+            NMI                     NMI         2
+            Exception               EVX         3
+            Reserved                --          4
+            Hardware Error          IVHW        5
+            Core Timer              IVTMR       6 *
+	    PLL Wakeup Interrupt    IVG7	7
+	    DMA Error (generic)	    IVG7	8
+	    PPI Error Interrupt     IVG7	9
+	    SPORT0 Error Interrupt  IVG7	10
+	    SPORT1 Error Interrupt  IVG7	11
+	    SPI Error Interrupt	    IVG7	12
+	    UART Error Interrupt    IVG7	13
+	    RTC Interrupt	    IVG8        14
+	    DMA0 Interrupt (PPI)    IVG8	15
+	    DMA1 (SPORT0 RX)	    IVG9	16
+	    DMA2 (SPORT0 TX)	    IVG9        17
+	    DMA3 (SPORT1 RX)        IVG9	18
+	    DMA4 (SPORT1 TX)	    IVG9	19
+	    DMA5 (PPI)		    IVG10	20
+	    DMA6 (UART RX)	    IVG10	21
+	    DMA7 (UART TX)	    IVG10	22
+	    Timer0		    IVG11	23
+	    Timer1		    IVG11	24
+	    Timer2		    IVG11	25
+	    PF Interrupt A	    IVG12	26
+	    PF Interrupt B	    IVG12	27
+	    DMA8/9 Interrupt	    IVG13	28
+	    DMA10/11 Interrupt	    IVG13	29
+	    Watchdog Timer	    IVG13	30
+            Software Interrupt 1    IVG14       31
+            Software Interrupt 2    --
+                 (lowest priority)  IVG15       32 *
+ */
+/* The ABSTRACT IRQ definitions */
+/** the first seven of the following are fixed, the rest you change if you need to **/
+#define	IRQ_EMU			0	// Emulation
+#define	IRQ_RST			1	// reset
+#define	IRQ_NMI			2	// Non Maskable
+#define	IRQ_EVX			3	// Exception
+#define	IRQ_UNUSED		4	//  - unused interrupt
+#define	IRQ_HWERR		5	// Hardware Error
+#define	IRQ_CORETMR		6	// Core timer
+#define	IRQ_PLL_WAKEUP		7	// PLL Wakeup Interrupt
+#define	IRQ_DMA_ERROR		8	// DMA Error (general)
+#define	IRQ_PPI_ERROR		9	// PPI Error Interrupt
+#define	IRQ_SPORT0_ERROR	10 	// SPORT0 Error Interrupt
+#define	IRQ_SPORT1_ERROR	11	// SPORT1 Error Interrupt
+#define	IRQ_SPI_ERROR		12	// SPI Error Interrupt
+#define	IRQ_UART_ERROR		13	// UART Error Interrupt
+#define	IRQ_RTC			14	// RTC Interrupt
+#define	IRQ_PPI			15	// DMA0 Interrupt (PPI)
+#define	IRQ_SPORT0		16	// DMA1 Interrupt (SPORT0 RX)
+#define	IRQ_SPARE1		17	// DMA2 Interrupt (SPORT0 TX)
+#define	IRQ_SPORT1		18	// DMA3 Interrupt (SPORT1 RX)
+#define	IRQ_SPARE2		19	// DMA4 Interrupt (SPORT1 TX)
+#define IRQ_SPI			20	// DMA5 Interrupt (SPI)
+#define	IRQ_UART		21	// DMA6 Interrupt (UART RX)
+#define	IRQ_SPARE3		22	// DMA7 Interrupt (UART TX)
+#define	IRQ_TMR0		23	// Timer 0
+#define	IRQ_TMR1		24	// Timer 1
+#define	IRQ_TMR2		25	// Timer 2
+#define	IRQ_PROG_INTA		26	// Programmable Flags A (8)
+#define	IRQ_PROG_INTB		27	// Programmable Flags B (8)
+#define	IRQ_MEM_DMA0		28	// DMA8/9 Interrupt (Memory DMA Stream 0)
+#define	IRQ_MEM_DMA1		29	// DMA10/11 Interrupt (Memory DMA Stream 1)
+#define	IRQ_WATCH	   	30	// Watch Dog Timer
+#define	IRQ_SW_INT1		31	// Software Int 1
+#define	IRQ_SW_INT2		32	// Software Int 2 (reserved for SYSCALL)
+
+#define IVG7			7
+#define IVG8			8
+#define IVG9			9
+#define IVG10			10
+#define IVG11			11
+#define IVG12			12
+#define IVG13			13
+#define IVG14			14
+#define IVG15			15
+
+#define SYS_IRQS		33	// Number of interrupt levels that the kernel sees.
+
+#endif /* _BF535_IRQ_H_ */
diff -urN linux-2.4.29/include/asm-blackfin/board/bf533_serial.h linux-2.4.29-uc1/include/asm-blackfin/board/bf533_serial.h
--- linux-2.4.29/include/asm-blackfin/board/bf533_serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/board/bf533_serial.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,106 @@
+/*
+ * Rev:$Id: bf533_serial.h,v 1.1 2003/11/04 14:47:42 bas Exp $
+ *
+ * Copyright (C) 2003 Bas Vermeulen/Buyways B.V. <bf533@buyways.nl>
+ *
+ * Created by Buyways B.V. for Astent <info@astent.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef _BF533_SERIAL_H_
+#define _BF533_SERIAL_H_
+/* 
+ *  ADI uart macro definition :
+ *     UART 0 CONTROLLER REGISTERS  (0XFFC01800 - 0XFFC01BFF)
+ *     UART 1 CONTROLLER REGISTERS  (0XFFC01C00 - 0XFFC01FFF)
+ */
+#define UART_THR_ADDR		0xffc00400  /* UART 0 Transmit holding register
+					       16 bit */
+#define UART_THR(idx)		HALFWORD_REF(UART_THR_ADDR)
+
+
+#define UART_RBR_ADDR		0xffc00400  /* UART 0 Receive buffer register  
+					     16 bit */
+#define UART_RBR(idx)		HALFWORD_REF(UART_RBR_ADDR)
+
+#define UART_DLL_ADDR		0xffc00400  /* UART 0 Divisor latch (low byte) 
+					       register  16 bit */
+#define UART_DLL(idx)		HALFWORD_REF(UART_DLL_ADDR)
+
+#define UART_IER_ADDR		0xffc00404  /* UART 0 Interrupt enable register  16 bit */
+#define UART_IER(idx)		HALFWORD_REF(UART_IER_ADDR)
+#define UART_IER_ERBFI		0x01    /* Enable Receive Buffer Full Interrupt
+					   (DR bit) */
+#define UART_IER_ETBEI		0x02    /* Enable Transmit Buffer Empty 
+					   Interrupt(THRE bit) */
+#define UART_IER_ELSI		0x04    /* Enable RX Status Interrupt
+					   (gen if any of LSR[4:1] set) */
+#define UART_IER_EDDSI		0x08    /* Enable Modem Status Interrupt(gen if any UARTx_MSR[3:0] set) */
+
+#define UART_DLH_ADDR		0xffc00404  /* UART 0 Divisor latch (high byte) register  16 bit */
+#define UART_DLH(idx)		HALFWORD_REF(UART_DLH_ADDR)
+#define UART_IIR_ADDR		0xffc00408  /* UART 0 Interrupt identification register  16 bit */
+#define UART_IIR(idx)		HALFWORD_REF(UART_IIR_ADDR)
+#define UART_IIR_NOINT		0x01    /* Bit0: cleared when no interrupt */
+#define UART_IIR_STATUS		0x06    /* mask bit for the status: bit2-1 */
+#define UART_IIR_LSR		0x06    /* Receive line status */
+#define UART_IIR_RBR		0x04    /* Receive data ready */
+#define UART_IIR_THR		0x02    /* Ready to transmit  */
+#define UART_IIR_MSR		0x00    /* Modem status       */
+
+#define UART_LCR_ADDR          	0xffc0040C  /* UART 0 Line control register  16 bit */
+#define UART_LCR(idx)           	HALFWORD_REF(UART_LCR_ADDR)
+#define UART_LCR_WLS5           0       /* word length 5 bits */
+#define UART_LCR_WLS6           0x01    /* word length 6 bits */
+#define UART_LCR_WLS7           0x02    /* word length 7 bits */
+#define UART_LCR_WLS8           0x03    /* word length 8 bits */
+#define UART_LCR_STB            0x04    /* StopBit: 1: 2 stop bits for 
+					   non-5-bit word length 1/2 stop bits 
+					   for 5-bit word length 0: 
+					   1 stop bit */
+#define UART_LCR_PEN            0x08    /* Parity Enable 1: for enable */
+#define UART_LCR_EPS            0x10    /* Parity Selection: 
+					   1: for even pariety
+                                           0: odd parity when PEN =1 & SP =0 */
+#define UART_LCR_SP             0x20    /* Sticky Parity: */
+#define UART_LCR_SB             0x40    /* Set Break: force TX pin to 0 */
+#define UART_LCR_DLAB           0x80    /* Divisor Latch Access */
+
+
+#define UART_MCR_ADDR          	0xffc00410  /* UART 0 Module Control register  
+					       16 bit */
+#define UART_MCR(idx)           	HALFWORD_REF(UART_MCR_ADDR)
+
+#define UART_LSR_ADDR          	0xffc00414  /* UART 0 Line status register  
+					       16 bit */
+#define UART_LSR(idx)           	HALFWORD_REF(UART_LSR_ADDR)
+#define UART_LSR_DR             0x01    /* Data Ready */
+#define UART_LSR_OE             0x02    /* Overrun Error */
+#define UART_LSR_PE             0x04    /* Parity Error  */
+#define UART_LSR_FE             0x08    /* Frame Error   */
+#define UART_LSR_BI             0x10    /* Break Interrupt */
+#define UART_LSR_THRE           0x20    /* THR empty, REady to accept */
+#define UART_LSR_TEMT           0x40    /* TSR and UARTx_thr both empty */
+
+#define UART_MSR_ADDR          	0xffc00418  /* UART 0 Modem status register  16 bit */
+#define UART_MSR(idx)           	HALFWORD_REF(UART_MSR_ADDR)
+#define UART_SCR_ADDR          	0xffc00418  /* UART 0 Scratch register  16 bit */
+#define UART_SCR(idx)           	HALFWORD_REF(UART_SCR_ADDR)
+#define UART_GCTL_ADDR		0xffc00424
+#define UART_GCTL(idx)		HALFWORD_REF(UART_GCTL_ADDR)
+#define UART_GCTL_UCEN		0x01
+#endif /* _BF533_SERIAL_H_ */
+
diff -urN linux-2.4.29/include/asm-blackfin/board/bf535.h linux-2.4.29-uc1/include/asm-blackfin/board/bf535.h
--- linux-2.4.29/include/asm-blackfin/board/bf535.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/board/bf535.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,1267 @@
+/*
+ * Copyright (c) 2000, 2001 by Lineo, Inc./Lineo Canada Corp. (www.lineo.com),
+ * Copyright (c) 2001,2002 by Arcturus Networks Inc. (www.arcturusnetworks.com),
+ * Ported for Blackfin/Frio Architecture by 
+ *					Akbar Hussain  <akbar.hussain@arcturusnetworks.com>,
+ *             Tony Kou <tony.ko@arcturusnetworks.com>
+ *					MaTed <mated@sympatico.ca> <mated@arcturusnetworks.com>
+ * Tab Size == 4 ....MaTed
+ */
+
+
+/* FOR BlackFin DSP:     BYTE = 08 bits,  HALFWORD = 16 bit & WORD = 32 bits    */
+
+
+#ifndef _BLKFin_H_
+#define _BLKFin_H_
+
+#define BYTE_REF(addr)		 (*((volatile unsigned char*)addr))
+#define HALFWORD_REF(addr) 	 (*((volatile unsigned short*)addr))
+#define WORD_REF(addr)		 (*((volatile unsigned long*)addr))
+
+/*
+ * Typedefs
+ */
+typedef unsigned long	UINT32;
+typedef unsigned short 	UINT16;
+typedef	unsigned char	UCHAR;
+
+#define PUT_FIELD(field, val) (((val) << field##_SHIFT) & field##_MASK) /* ?  */
+#define GET_FIELD(reg, field) (((reg) & field##_MASK) >> field##_SHIFT) /*  ?   */
+
+/*      FOLLOWING ARE THE BlackFin SYSTEM MMR REGISTERS (LOWER 2 MB)     */
+
+/**************************
+ *
+ * L2 MULTIPLE INPUT SIGNATURE REGISTERS (MISR) (0XFFC0000 - 0XFFC003FF)
+ *
+ **************************/
+ 
+#define MISR_CTL_ADDR		0xffc00000  /* Control register 32 bit*/
+#define MISR_CTL			WORD_REF(MISR_CTL_ADDR)
+#define MISR_RMISR0_ADDR	0xffc00004  /* CoreL2[31:0] read bus register 32 bit*/
+#define MISR_RMISR0			WORD_REF(MISR_RMISR0_ADDR)
+#define MISR_RMISR1_ADDR	0xffc00008  /* CoreL2[63:32] read bus register 32 bit*/
+#define MISR_RMISR1			WORD_REF(MISR_RMISR1_ADDR)
+#define MISR_RMISR2_ADDR	0xffc0000C  /* SysL2[31:0] read bus register 32 bit*/
+#define MISR_RMISR2			WORD_REF(MISR_RMISR2_ADDR)
+#define MISR_WMISR0_ADDR	0xffc00010  /* CoreL2[31:0] write bus register 32 bit*/
+#define MISR_WMISR0			WORD_REF(MISR_WMISR0_ADDR)
+#define MISR_WMISR1_ADDR	0xffc00014  /* CoreL2[63:32] write bus register 32 bit*/
+#define MISR_WMISR1			WORD_REF(MISR_WMISR1_ADDR)
+#define MISR_WMISR2_ADDR	0xffc00018  /* SysL2[31:0] write bus register 32 bit*/
+#define MISR_WMISR2			WORD_REF(MISR_WMISR2_ADDR)
+
+/**************************
+ *
+ * CLOCK & SYSTEM CONTROL (0XFFC0400 - 0XFFC007FF)
+ *
+ **************************/
+ 
+#define PLLCTL_ADDR			0xffc00400  /* PLL control register 32 bit*/
+#define PLLCTL				WORD_REF(PLLCTL_ADDR)
+#define PLLSTAT_ADDR		0xffc00404  /* PLL status register 16 bit */
+#define PLLSTAT				HALFWORD_REF(PLLSTAT_ADDR)
+#define LOCKCNT_ADDR		0xffc00406  /* PLL lock counter register 16 bit */
+#define LOCKCNT				HALFWORD_REF(LOCKCNT_ADDR)
+#define IOCKR_ADDR			0xffc00408  /* Peripheral clock enable register 16 bit */
+#define IOCKR				HALFWORD_REF(IOCKR_ADDR)
+#define SWRST_ADDR			0xffc00410  /* Software reset register 16 bit */
+#define SWRST				HALFWORD_REF(SWRST_ADDR)
+#define NXTSCR_ADDR			0xffc00412  /* Next system configuration register 16 bit */
+#define NXTSCR				HALFWORD_REF(NXTSCR_ADDR)
+#define SYSCR_ADDR			0xffc00414  /* Sytem Configuration register */
+#define SYSCR 				HALFWORD_REF(SYSCR_ADDR)
+
+/**************************
+ *
+ * JTAG/DEBUG COMMUNICATION CHANNEL (0XFFC00800 - 0XFFC00BFF)
+ *
+ **************************/
+ 
+#define INDATA_ADDR			0xffc00800   /* Indata register 16 bit */
+#define INDATA				HALFWORD_REF(INDATA_ADDR)
+#define OUTDATA_ADDR		0xffc00802   /*  Outdata register  16 bit */
+#define OUTDATA				HALFWORD_REF(OUTDATA_ADDR)
+#define JDCSR_ADDR			0xffc00804   /*  JDCC Control/Status register 32 bit */
+#define JDCSR				WORD_REF(JDCSR_ADDR)
+#define IDDEV_ADDR			0xffc00808   /*  Device ID register  32 bit */
+#define IDDEV				WORD_REF(IDDEV_ADDR)
+#define IDCORE_ADDR			0xffc0080c   /*  Core ID register 32 bit */
+#define IDCORE				WORD_REF(IDCORE_ADDR)
+
+/****************************
+ *
+ *  EXTENDED CORE INTERRUPT CONTROLLER (ECIC) 0XFFC00C00 - 0XFFC0OFFF
+ *
+ ****************************/
+ 
+#define RVECT_ADDR			0xffc00c00   /* Reset vector register 32 bit */
+#define RVECT				WORD_REF(RVECT_ADDR)
+#define IAR0_ADDR			0xffc00c04   /* Interrupt assignment register 0 32 bit*/
+#define IAR0				WORD_REF(IAR0_ADDR)
+#define IAR1_ADDR			0xffc00c08   /* Interrupt assignment register 1 32 bit*/
+#define IAR1				WORD_REF(IAR1_ADDR)
+#define IAR2_ADDR			0xffc00c0c   /* Interrupt assignment register 2 32 bit*/
+#define IAR2				WORD_REF(IAR2_ADDR)
+#define IMR_ADDR			0xffc00c10   /* Interrupt mask register  32 bit*/
+#define IMR				WORD_REF(IMR_ADDR)
+#define ISR_ADDR			0xffc00c14   /* Interrupt status register  32 bit*/
+#define ISR				WORD_REF(ISR_ADDR)
+#define IWR_ADDR			0xffc00c18   /* Interrupt wakeup register  32 bit*/
+#define IWR				WORD_REF(IWR_ADDR)
+
+/****************************
+ *
+ *  WATCHDOG TIMER  (0XFFC01000 - 0XFFC013F)
+ *
+ ****************************/
+ 
+#define WDOGCTL_ADDR		0xffc01000  /* Watchdog control register  32 bit */
+#define WDOGCTL				WORD_REF(WDOGCTL_ADDR)
+#define WDOGCNT_ADDR		0xffc01004  /* Watchdog count register 32 bit */
+#define WDOGCNT				WORD_REF(WDOGCNT_ADDR)
+#define WDOGSTAT_ADDR		0xffc01008  /* Watchdog status register 32 bit */
+#define WDOGSTAT			WORD_REF(WDOGSTAT_ADDR)
+
+/****************************
+ *
+ *  REAL TIME CLOCK (RTC) REGISTERS  (0XFFC01400 - 0XFFC017FF)
+ *
+ ****************************/
+ 
+#define RTCSTAT_ADDR		0xffc01400  /* RTC status register  32 bit */
+#define RTCSTAT				WORD_REF(RTCSTAT_ADDR)
+#define RTCICTL_ADDR		0xffc01404  /* RTC Interrupt control register  32 bit */
+#define RTCICTL				WORD_REF(RTCICTL_ADDR)
+#define RTCISTAT_ADDR		0xffc01408  /* RTC Interrupt status register  32 bit */
+#define RTCISTAT			WORD_REF(RTCISTAT_ADDR)
+#define RTCSWCNT_ADDR		0xffc0140c  /* RTC Stop watch count register  32 bit */
+#define RTCSWCNT			WORD_REF(RTCSWCNT_ADDR)
+#define RTCALARM_ADDR		0xffc01410  /* RTC Alarm time register  32 bit */
+#define RTCALARM			WORD_REF(RTCALARM_ADDR)
+#define RTCFAST_ADDR		0xffc01414  /* RTC Prescalar control register  32 bit */
+#define RTCFAST				WORD_REF(RTCFAST_ADDR)
+
+/****************************
+ *
+ *  UART 0 CONTROLLER REGISTERS  (0XFFC01800 - 0XFFC01BFF)
+ *
+ ****************************/
+
+#define UART0_THR_ADDR		0xffc01800  /* UART 0 Transmit holding register  16 bit */
+#define UART0_THR			HALFWORD_REF(UART0_THR_ADDR)
+#define UART0_THR_MASK		0x00ff /* Data to be transmitted */ 
+
+
+#define UART0_RBR_ADDR		0xffc01800  /* UART 0 Receive buffer register  16 bit */
+#define UART0_RBR			HALFWORD_REF(UART0_RBR_ADDR)
+#define UART0_RBR_MASK		0x00ff /* Data to be received */ 
+
+#define UART0_DLL_ADDR		0xffc01800  /* UART 0 Divisor latch (low byte) register  16 bit */
+#define UART0_DLL			HALFWORD_REF(UART0_DLL_ADDR)
+
+#define UART0_IER_ADDR		0xffc01802  /* UART 0 Interrupt enable register  16 bit */
+#define UART0_IER			HALFWORD_REF(UART0_IER_ADDR)
+#define UART0_IER_ERBFI			0x01	/* Enable Receive Buffer Full Interrupt(DR bit) */
+#define UART0_IER_ETBEI			0x02	/* Enable Transmit Buffer Empty Interrupt(THRE bit) */
+#define UART0_IER_ELSI			0x04	/* Enable RX Status Interrupt(gen if any of LSR[4:1] set) */
+#define UART0_IER_EDDSI			0x08	/* Enable Modem Status Interrupt(gen if any UARTx_MSR[3:0] set) */
+
+
+#define UART0_DLH_ADDR		0xffc01802  /* UART 0 Divisor latch (high byte) register  16 bit */
+#define UART0_DLH			HALFWORD_REF(UART0_DLH_ADDR)
+#define UART0_IIR_ADDR		0xffc01804  /* UART 0 Interrupt identification register  16 bit */
+#define UART0_IIR			HALFWORD_REF(UART0_IIR_ADDR)
+#define UART0_IIR_NOINT			0x01	/* Bit0: cleared when no interrupt */
+#define UART0_IIR_STATUS		0x06	/* mask bit for the status: bit2-1 */
+#define UART0_IIR_LSR			0x06	/* Receive line status */
+#define UART0_IIR_RBR			0x04	/* Receive data ready */
+#define UART0_IIR_THR			0x02	/* Ready to transmit  */
+#define UART0_IIR_MSR			0x00	/* Modem status       */
+
+#define UART0_LCR_ADDR		0xffc01806  /* UART 0 Line control register  16 bit */
+#define UART0_LCR			HALFWORD_REF(UART0_LCR_ADDR)
+#define UART0_LCR_WLS5			0	/* word length 5 bits */
+#define UART0_LCR_WLS6			0x01	/* word length 6 bits */
+#define UART0_LCR_WLS7			0x02	/* word length 7 bits */
+#define UART0_LCR_WLS8			0x03	/* word length 8 bits */
+#define UART0_LCR_STB			0x04	/* StopBit: 1: 2 stop bits for non-5-bit word length
+                                                       1/2 stop bits for 5-bit word length
+                                                    0: 1 stop bit */
+#define UART0_LCR_PEN			0x08	/* Parity Enable 1: for enable */
+#define UART0_LCR_EPS			0x10	/* Parity Selection: 1: for even pariety
+                                                             0: odd parity when PEN =1 & SP =0 */
+#define UART0_LCR_SP			0x20	/* Sticky Parity: */
+#define UART0_LCR_SB			0x40	/* Set Break: force TX pin to 0 */
+#define UART0_LCR_DLAB			0x80	/* Divisor Latch Access */
+
+
+#define UART0_MCR_ADDR		0xffc01808  /* UART 0 Module Control register  16 bit */
+#define UART0_MCR			HALFWORD_REF(UART0_MCR_ADDR)
+
+#define UART0_LSR_ADDR		0xffc0180a  /* UART 0 Line status register  16 bit */
+#define UART0_LSR			HALFWORD_REF(UART0_LSR_ADDR)
+#define UART0_LSR_DR			0x01	/* Data Ready */
+#define UART0_LSR_OE			0x02	/* Overrun Error */
+#define UART0_LSR_PE			0x04	/* Parity Error  */
+#define UART0_LSR_FE			0x08	/* Frame Error   */
+#define UART0_LSR_BI			0x10	/* Break Interrupt */
+#define UART0_LSR_THRE			0x20	/* THR empty, REady to accept */
+#define UART0_LSR_TEMT			0x40	/* TSR and UARTx_thr both empty */
+
+#define UART0_MSR_ADDR		0xffc0180c  /* UART 0 Modem status register  16 bit */
+#define UART0_MSR			HALFWORD_REF(UART0_MSR_ADDR
+#define UART0_SCR_ADDR		0xffc0180e  /* UART 0 Scratch register  16 bit */
+#define UART0_SCR			HALFWORD_REF(UART0_SCR_ADDR)
+#define UART0_IRCR_ADDR		0xffc01810  /* UART 0 IrDA Control register  16 bit */
+#define UART0_IRCR			HALFWORD_REF(UART0_IRCR_ADDR)
+
+#define UART0_CURR_PTR_RX_ADDR		0xffc01a00 /* UART 0 RCV DMA Current pointer register 16 bit*/
+#define UART0_CURR_PTR_RX			HALFWORD_REF(UART0_CURR_PTR_RX_ADDR)
+#define UART0_CONFIG_RX_ADDR		0xffc01a02 /* UART 0 RCV DMA Configuration register 16 bit */
+#define UART0_CONFIG_RX				HALFWORD_REF(UART0_CONFIG_RX_ADDR)
+#define UART0_START_ADDR_HI_RX_ADDR	0xffc01a04 /* UART 0 RCV DMA start add. hi reg 16 bit */
+#define UART0_START_ADDR_HI_RX		HALFWORD_REF(UART0_START_ADDR_HI_RX_ADDR)
+#define UART0_START_ADDR_LO_RX_ADDR	0xffc01a06 /* UART 0 RCV DMA start add. lo reg 16 bit */
+#define UART0_START_ADDR_LO_RX		HALFWORD_REF(UART0_START_ADDR_LO_RX_ADDR)
+#define UART0_COUNT_RX_ADDR			0xffc01a08 /* UART 0 RCV DMA count register  16 bit */
+#define UART0_COUNT_RX				HALFWORD_REF(UART0_COUNT_RX_ADDR)
+#define UART0_NEXT_DESCR_RX_ADDR    0xffc01a0a /*UART 0 RCV DMA next descripter poin reg 16 bit */
+#define UART0_NEXT_DESCR_RX			HALFWORD_REF(UART0_NEXT_DESCR_RX_ADDR)
+#define UART0_DESCR_RDY_RX_ADDR		0xffc01a0c /* UART 0 RCV DMA descripter ready reg 16 bit */
+#define UART0_DESCR_RDY_RX			HALFWORD_REF(UART0_DESCR_RDY_RX_ADDR)
+#define UART0_IRQSTAT_RX_ADDR		0xffc01a0e /* UART 0 RCV DMA Interrupt register  16 bit */
+#define UART0_IRQSTAT_RX			HALFWORD_REF(UART0_IRQSTAT_RX_ADDR)
+
+#define UART0_CURR_PTR_TX_ADDR		0xffc01b00 /* UART 0 XMT DMA Current pointer register 16 bit*/
+#define UART0_CURR_PTR_TX			HALFWORD_REF(UART0_CURR_PTR_TX_ADDR)
+#define UART0_CONFIG_TX_ADDR		0xffc01b02 /* UART 0 XMT DMA Configuration register 16 bit */
+#define UART0_CONFIG_TX				HALFWORD_REF(UART0_CONFIG_TX_ADDR)
+#define UART0_START_ADDR_HI_TX_ADDR	0xffc01b04 /* UART 0 XMT DMA start add. hi reg 16 bit */
+#define UART0_START_ADDR_HI_TX		HALFWORD_REF(UART0_START_ADDR_HI_TX_ADDR)
+#define UART0_START_ADDR_LO_TX_ADDR	0xffc01b06 /* UART 0 XMT DMA start add. lo reg 16 bit */
+#define UART0_START_ADDR_LO_TX		HALFWORD_REF(UART0_START_ADDR_LO_TX_ADDR)
+#define UART0_COUNT_TX_ADDR			0xffc01b08 /* UART 0 XMT DMA count register  16 bit */
+#define UART0_COUNT_TX				HALFWORD_REF(UART0_COUNT_TX_ADDR)
+#define UART0_NEXT_DESCR_TX_ADDR	0xffc01b0a /*UART 0 XMT DMA next descripter poin reg 16 bit */
+#define UART0_NEXT_DESCR_TX			HALFWORD_REF(UART0_NEXT_DESCR_TX_ADDR)
+#define UART0_DESCR_RDY_TX_ADDR		0xffc01b0c /* UART 0 XMT DMA descripter ready reg 16 bit */
+#define UART0_DESCR_RDY_TX			HALFWORD_REF(UART0_DESCR_RDY_TX_ADDR)
+#define UART0_IRQSTAT_TX_ADDR		0xffc01b0e /* UART 0 XMT DMA Interrupt register  16 bit */
+#define UART0_IRQSTAT_TX			HALFWORD_REF(UART0_IRQSTAT_TX_ADDR)
+
+/****************************
+ *
+ *  UART 1 CONTROLLER REGISTERS  (0XFFC01C00 - 0XFFC01FFF)
+ *
+ ****************************/
+
+#define UART1_THR_ADDR		0xffc01c00  /* UART 1 Transmit holding register  16 bit */
+#define UART1_THR			HALFWORD_REF(UART1_THR_ADDR)
+#define UART1_THR_MASK		0x00ff /* Data to be transmitted */
+
+#define UART1_RBR_ADDR		0xffc01c00  /* UART 1 Receive buffer register  16 bit */
+#define UART1_RBR			HALFWORD_REF(UART1_RBR_ADDR)
+#define UART1_RBR_MASK		0x00ff /* Data to be transmitted */
+
+#define UART1_DLL_ADDR		0xffc01c00  /* UART 1 Divisor latch (low byte) register  16 bit */
+#define UART1_DLL			HALFWORD_REF(UART1_DLL_ADDR)
+
+#define UART1_IER_ADDR		0xffc01c02  /* UART 1 Interrupt enable register  16 bit */
+#define UART1_IER			HALFWORD_REF(UART1_IER_ADDR)
+#define UART1_IER_ERBFI			0x01    /* Enable Receive Buffer Full Interrupt(DR bit) */
+#define UART1_IER_ETBEI			0x02    /* Enable Transmit Buffer Empty Interrupt(THRE bit) */
+#define UART1_IER_ELSI			0x04    /* Enable RX Status Interrupt(gen if any of LSR[4:1] set) */
+#define UART1_IER_EDDSI			0x08    /* Enable Modem Status Interrupt(gen if any UARTx_MSR[3:0] set) */
+
+#define UART1_DLH_ADDR		0xffc01c02  /* UART 1 Divisor latch (high byte) register  16 bit */
+#define UART1_DLH			HALFWORD_REF(UART1_DLH_ADDR)
+
+#define UART1_IIR_ADDR		0xffc01c04  /* UART 1 Interrupt identification register  16 bit */
+#define UART1_IIR			HALFWORD_REF(UART1_IIR_ADDR)
+#define UART1_IIR_NOINT     	0x01    /* Bit0: cleared when no interrupt */
+#define UART1_IIR_STATUS        0x06    /* mask bit for the status: bit2-1 */
+#define UART1_IIR_LSR           0x06    /* Receive line status */
+#define UART1_IIR_RBR           0x04    /* Receive data ready */
+#define UART1_IIR_THR           0x02    /* Ready to transmit  */
+#define UART1_IIR_MSR           0x00    /* Modem status       */
+
+#define UART1_LCR_ADDR		0xffc01c06  /* UART 1 Line control register  16 bit */
+#define UART1_LCR			HALFWORD_REF(UART1_LCR_ADDR)
+#define UART1_LCR_WLS5      	0       /* word length 5 bits */
+#define UART1_LCR_WLS6      	0x01    /* word length 6 bits */
+#define UART1_LCR_WLS7          0x02    /* word length 7 bits */
+#define UART1_LCR_WLS8          0x03    /* word length 8 bits */
+#define UART1_LCR_STB           0x04    /* StopBit: 1: 2 stop bits for non-5-bit word length
+                                                       1/2 stop bits for 5-bit word length
+                                                    0: 1 stop bit */
+#define UART1_LCR_PEN           0x08    /* Parity Enable 1: for enable */
+#define UART1_LCR_EPS           0x10    /* Parity Selection: 1: for even pariety
+                                                             0: odd parity when PEN =1 &
+															 SP =0 */
+#define UART1_LCR_SP            0x20    /* Sticky Parity: */
+#define UART1_LCR_SB            0x40    /* Set Break: force TX pin to 0 */
+#define UART1_LCR_DLAB          0x80    /* Divisor Latch Access */
+
+#define UART1_MCR_ADDR		0xffc01c08  /* UART 1 Module Control register  16 bit */
+#define UART1_MCR			HALFWORD_REF(UART1_MCR_ADDR)
+
+#define UART1_LSR_ADDR		0xffc01c0a  /* UART 1 Line status register  16 bit */
+#define UART1_LSR			HALFWORD_REF(UART1_LSR_ADDR)
+#define UART1_LSR_DR        	0x01    /* Data Ready */
+#define UART1_LSR_OE            0x02    /* Overrun Error */
+#define UART1_LSR_PE            0x04    /* Parity Error  */
+#define UART1_LSR_FE            0x08    /* Frame Error   */
+#define UART1_LSR_BI            0x10    /* Break Interrupt */
+#define UART1_LSR_THRE          0x20    /* THR empty, REady to accept */
+#define UART1_LSR_TEMT          0x40    /* TSR and UARTx_thr both empty */
+
+#define UART1_MSR_ADDR		0xffc01c0c  /* UART 1 Modem status register  16 bit */
+#define UART1_MSR			HALFWORD_REF(UART1_MSR_ADDR
+#define UART1_SCR_ADDR		0xffc01c0e  /* UART 1 Scratch register  16 bit */
+#define UART1_SCR			HALFWORD_REF(UART1_SCR_ADDR)
+
+#define UART1_CURR_PTR_RX_ADDR		0xffc01e00 /* UART 1 RCV DMA Current pointer register 16 bit*/
+#define UART1_CURR_PTR_RX			HALFWORD_REF(UART1_CURR_PTR_RX_ADDR)
+#define UART1_CONFIG_RX_ADDR		0xffc01e02 /* UART 1 RCV DMA Configuration register 16 bit */
+#define UART1_CONFIG_RX				HALFWORD_REF(UART1_CONFIG_RX_ADDR)
+#define UART1_START_ADDR_HI_RX_ADDR	0xffc01e04 /* UART 1 RCV DMA start add. hi reg 16 bit */
+#define UART1_START_ADDR_HI_RX		HALFWORD_REF(UART1_START_ADDR_HI_RX_ADDR)
+#define UART1_START_ADDR_LO_RX_ADDR	0xffc01e06 /* UART 1 RCV DMA start add. lo reg 16 bit */
+#define UART1_START_ADDR_LO_RX		HALFWORD_REF(UART1_START_ADDR_LO_RX_ADDR)
+#define UART1_COUNT_RX_ADDR			0xffc01e08 /* UART 1 RCV DMA count register  16 bit */
+#define UART1_COUNT_RX				HALFWORD_REF(UART1_COUNT_RX_ADDR)
+#define UART1_NEXT_DESCR_RX_ADDR   	0xffc01e0a /*UART 1 RCV DMA next descripter poin reg 16 bit */
+#define UART1_NEXT_DESCR_RX			HALFWORD_REF(UART1_NEXT_DESCR_RX_ADDR)
+#define UART1_DESCR_RDY_RX_ADDR		0xffc01e0c /* UART 1 RCV DMA descripter ready reg 16 bit */
+#define UART1_DESCR_RDY_RX			HALFWORD_REF(UART1_DESCR_RDY_RX_ADDR)
+#define UART1_IRQSTAT_RX_ADDR		0xffc01e0e /* UART 1 RCV DMA Interrupt register  16 bit */
+#define UART1_IRQSTAT_RX			HALFWORD_REF(UART1_IRQSTAT_RX_ADDR)
+
+#define UART1_CURR_PTR_TX_ADDR		0xffc01f00 /* UART 1 XMT DMA Current pointer register 16 bit*/
+#define UART1_CURR_PTR_TX			HALFWORD_REF(UART1_CURR_PTR_TX_ADDR)
+#define UART1_CONFIG_TX_ADDR		0xffc01f02 /* UART 1 XMT DMA Configuration register 16 bit */
+#define UART1_CONFIG_TX				HALFWORD_REF(UART1_CONFIG_TX_ADDR)
+#define UART1_START_ADDR_HI_TX_ADDR	0xffc01f04 /* UART 1 XMT DMA start add. hi reg 16 bit */
+#define UART1_START_ADDR_HI_TX		HALFWORD_REF(UART1_START_ADDR_HI_TX_ADDR)
+#define UART1_START_ADDR_LO_TX_ADDR	0xffc01f06 /* UART 1 XMT DMA start add. lo reg 16 bit */
+#define UART1_START_ADDR_LO_TX		HALFWORD_REF(UART1_START_ADDR_LO_TX_ADDR)
+#define UART1_COUNT_TX_ADDR			0xffc01f08 /* UART 1 XMT DMA count register  16 bit */
+#define UART1_COUNT_TX				HALFWORD_REF(UART1_COUNT_TX_ADDR)
+#define UART1_NEXT_DESCR_TX_ADDR	0xffc01f0a /*UART 1 XMT DMA next descripter poin reg 16 bit */
+#define UART1_NEXT_DESCR_TX			HALFWORD_REF(UART1_NEXT_DESCR_TX_ADDR)
+#define UART1_DESCR_RDY_TX_ADDR		0xffc01f0c /* UART 1 XMT DMA descripter ready reg 16 bit */
+#define UART1_DESCR_RDY_TX			HALFWORD_REF(UART1_DESCR_RDY_TX_ADDR)
+#define UART1_IRQSTAT_TX_ADDR		0xffc01f0e /* UART 1 XMT DMA Interrupt register  16 bit */
+#define UART1_IRQSTAT_TX			HALFWORD_REF(UART1_IRQSTAT_TX_ADDR)
+
+/****************************
+ *
+ *  TIMER REGISTERS  (0XFFC02000 - 0XFFC023FF)
+ *       THERE ARE 3 TIMERS
+ ****************************/
+ 
+		/*             TIMER 0              */
+		
+#define TIMER0_STATUS_ADDR		0xffc02000 /* TIMER 0 Global status & sticky register  16 bit */
+#define TIMER0_STATUS			HALFWORD_REF(TIMER0_STATUS_ADDR)
+#define TIMER0_CONFIG_ADDR		0xffc02002 /* TIMER 0 configuration register  16 bit */
+#define TIMER0_CONFIG			HALFWORD_REF(TIMER0_CONFIG_ADDR)
+#define TIMER0_COUNTER_LO_ADDR	0xffc02004 /* TIMER 0 counter (low word) register   16 bit */
+#define TIMER0_COUNTER_LO		HALFWORD_REF(TIMER0_COUNTER_LO_ADDR)
+#define TIMER0_COUNTER_HI_ADDR	0xffc02006 /* TIMER 0 counter (high word) register  16 bit */
+#define TIMER0_COUNTER_HI		HALFWORD_REF(TIMER0_COUNTER_HI_ADDR)
+#define TIMER0_PERIOD_LO_ADDR	0xffc02008 /* TIMER 0 period (low word) register  16 bit */
+#define TIMER0_PERIOD_LO		HALFWORD_REF(TIMER0_PERIOD_LO_ADDR)
+#define TIMER0_PERIOD_HI_ADDR	0xffc0200a /* TIMER 0 period (high word) register  16 bit */
+#define TIMER0_PERIOD_HI		HALFWORD_REF(TIMER0_PERIOD_HI_ADDR)
+#define TIMER0_WIDTH_LO_ADDR	0xffc0200c /* TIMER 0 width (low word) register  16 bit */
+#define TIMER0_WIDTH_LO			HALFWORD_REF(TIMER0_WIDTH_LO_ADDR)
+#define TIMER0_WIDTH_HI_ADDR	0xffc0200e /* TIMER 0 width (high word) register  16 bit */
+#define TIMER0_WIDTH_HI			HALFWORD_REF(TIMER0_WIDTH_HI_ADDR)
+
+		/*             TIMER 1              */
+
+#define TIMER1_STATUS_ADDR		0xffc02010 /* TIMER 1 Global status & sticky register  16 bit */
+#define TIMER1_STATUS			HALFWORD_REF(TIMER1_STATUS_ADDR)
+#define TIMER1_CONFIG_ADDR		0xffc02012 /* TIMER 1 configuration register  16 bit */
+#define TIMER1_CONFIG			HALFWORD_REF(TIMER1_CONFIG_ADDR)
+#define TIMER1_COUNTER_LO_ADDR	0xffc02014 /* TIMER 1 counter (low word) register   16 bit */
+#define TIMER1_COUNTER_LO		HALFWORD_REF(TIMER1_COUNTER_LO_ADDR)
+#define TIMER1_COUNTER_HI_ADDR	0xffc02016 /* TIMER 1 counter (high word) register  16 bit */
+#define TIMER1_COUNTER_HI		HALFWORD_REF(TIMER1_COUNTER_HI_ADDR)
+#define TIMER1_PERIOD_LO_ADDR	0xffc02018 /* TIMER 1 period (low word) register  16 bit */
+#define TIMER1_PERIOD_LO		HALFWORD_REF(TIMER1_PERIOD_LO_ADDR)
+#define TIMER1_PERIOD_HI_ADDR	0xffc0201a /* TIMER 1 period (high word) register  16 bit */
+#define TIMER1_PERIOD_HI		HALFWORD_REF(TIMER1_PERIOD_HI_ADDR)
+#define TIMER1_WIDTH_LO_ADDR	0xffc0201c /* TIMER 1 width (low word) register  16 bit */
+#define TIMER1_WIDTH_LO			HALFWORD_REF(TIMER1_WIDTH_LO_ADDR)
+#define TIMER1_WIDTH_HI_ADDR	0xffc0201e /* TIMER 1 width (high word) register  16 bit */
+#define TIMER1_WIDTH_HI			HALFWORD_REF(TIMER1_WIDTH_HI_ADDR)
+
+		/*             TIMER 2              */
+
+#define TIMER2_STATUS_ADDR		0xffc02020 /* TIMER 2 Global status & sticky register  16 bit */
+#define TIMER2_STATUS			HALFWORD_REF(TIMER2_STATUS_ADDR)
+#define TIMER2_CONFIG_ADDR		0xffc02022 /* TIMER 2 configuration register  16 bit */
+#define TIMER2_CONFIG			HALFWORD_REF(TIMER2_CONFIG_ADDR)
+#define TIMER2_COUNTER_LO_ADDR	0xffc02024 /* TIMER 2 counter (low word) register   16 bit */
+#define TIMER2_COUNTER_LO		HALFWORD_REF(TIMER2_COUNTER_LO_ADDR)
+#define TIMER2_COUNTER_HI_ADDR	0xffc02026 /* TIMER 2 counter (high word) register  16 bit */
+#define TIMER2_COUNTER_HI		HALFWORD_REF(TIMER2_COUNTER_HI_ADDR)
+#define TIMER2_PERIOD_LO_ADDR	0xffc02028 /* TIMER 2 period (low word) register  16 bit */
+#define TIMER2_PERIOD_LO		HALFWORD_REF(TIMER2_PERIOD_LO_ADDR)
+#define TIMER2_PERIOD_HI_ADDR	0xffc0202a /* TIMER 2 period (high word) register  16 bit */
+#define TIMER2_PERIOD_HI		HALFWORD_REF(TIMER2_PERIOD_HI_ADDR)
+#define TIMER2_WIDTH_LO_ADDR	0xffc0202c /* TIMER 2 width (low word) register  16 bit */
+#define TIMER2_WIDTH_LO			HALFWORD_REF(TIMER2_WIDTH_LO_ADDR)
+#define TIMER2_WIDTH_HI_ADDR	0xffc0202e /* TIMER 2 width (high word) register  16 bit */
+#define TIMER2_WIDTH_HI			HALFWORD_REF(TIMER2_WIDTH_HI_ADDR)
+
+/****************************
+ *
+ *  GENERAL PURPOSE IO REGISTERS  (0XFFC02400 - 0XFFC027FF)
+ *       
+ ****************************/
+
+#define FIO_DIR_C_ADDR		0xffc02400 /* Peripheral flag direction (clear) register 16 bit */
+#define FIO_DIR_C			HALFWORD_REF(FIO_DIR_C_ADDR)
+#define FIO_DIR_S_ADDR		0xffc02402 /* Peripheral flag direction (set) register 16 bit */
+#define FIO_DIR_S			HALFWORD_REF(FIO_DIR_S_ADDR)
+#define FIO_FLAG_C_ADDR		0xffc02404 /* Peripheral Interrupt flag (clear) register 16 bit */
+#define FIO_FLAG_C			HALFWORD_REF(FIO_FLAG_C_ADDR)
+#define FIO_FLAG_S_ADDR		0xffc02406 /* Peripheral Interrupt flag (set) register 16 bit */
+#define FIO_FLAG_S			HALFWORD_REF(FIO_FLAG_S_ADDR)
+#define FIO_MASKA_C_ADDR	0xffc02408 /* Flag Mask Interrupt A (clear) register 16 bit */
+#define FIO_MASKA_C			HALFWORD_REF(FIO_MASKA_C_ADDR)
+#define FIO_MASKA_S_ADDR	0xffc0240a /* Flag Mask Interrupt A (set) register 16 bit */
+#define FIO_MASKA_S			HALFWORD_REF(FIO_MASKA_S_ADDR)
+#define FIO_MASKB_C_ADDR	0xffc0240c /* Flag Mask Interrupt B (clear) register 16 bit */
+#define FIO_MASKB_C			HALFWORD_REF(FIO_MASKB_C_ADDR)
+#define FIO_MASKB_S_ADDR	0xffc0240e /* Flag Mask Interrupt B (set) register 16 bit */
+#define FIO_MASKB_S			HALFWORD_REF(FIO_MASKB_S_ADDR)
+#define FIO_POLAR_C_ADDR	0xffc02410 /* Flag source polarity (clear) register 16 bit */
+#define FIO_POLAR_C			HALFWORD_REF(FIO_POLAR_C_ADDR)
+#define FIO_POLAR_S_ADDR	0xffc02412 /* Flag source polarity (set) register 16 bit */
+#define FIO_POLAR_S			HALFWORD_REF(FIO_POLAR_S_ADDR)
+#define FIO_EDGE_C_ADDR		0xffc02414 /* Flag source sensitivity (clear) register 16 bit */
+#define FIO_EDGE_C			HALFWORD_REF(FIO_EDGE_C_ADDR)
+#define FIO_EDGE_S_ADDR		0xffc02416 /* Flag source sensitivity (set) register 16 bit */
+#define FIO_EDGE_S			HALFWORD_REF(FIO_EDGE_S_ADDR)
+#define FIO_BOTH_C_ADDR		0xffc02418 /* Flag set on both edges (clear) register 16 bit */
+#define FIO_BOTH_C			HALFWORD_REF(FIO_BOTH_C_ADDR)
+#define FIO_BOTH_S_ADDR		0xffc0241a /* Flag set on both edges (set) register 16 bit */
+#define FIO_BOTH_S			HALFWORD_REF(FIO_BOTH_S_ADDR)
+
+/****************************
+ *
+ *  SPORT 0 CONTROLLER REGISTERS  (0XFFC02800 - 0XFFC02BFF)
+ *       
+ ****************************/
+ 
+#define SPORT0_TX_CONFIG_ADDR	0xffc02800 /* SPORT 0 Transmit configuration register 16 bit */
+#define SPORT0_TX_CONFIG		HALFWORD_REF(SPORT0_TX_CONFIG_ADDR)
+#define SPORT0_RX_CONFIG_ADDR	0xffc02802 /* SPORT 0 Receive configuration register 16 bit */
+#define SPORT0_RX_CONFIG		HALFWORD_REF(SPORT0_RX_CONFIG_ADDR)
+#define SPORT0_TX_ADDR			0xffc02804 /* SPORT 0 Transmit register 16 bit */
+#define SPORT0_TX				HALFWORD_REF(SPORT0_TX_ADDR)
+#define SPORT0_RX_ADDR			0xffc02806 /* SPORT 0 Receive register 16 bit */
+#define SPORT0_RX				HALFWORD_REF(SPORT0_RX_ADDR)
+#define SPORT0_TSCLKDIV_ADDR	0xffc02808 /* SPORT 0 Transmit serial clock divider 16 bit */
+#define SPORT0_TSCLKDIV			HALFWORD_REF(SPORT0_TSCLKDIV_ADDR)
+#define SPORT0_RSCLKDIV_ADDR	0xffc0280a /* SPORT 0 Receive serial clock divider 16 bit */
+#define SPORT0_RSCLKDIV			HALFWORD_REF(SPORT0_RSCLKDIV_ADDR)
+#define SPORT0_TFSDIV_ADDR		0xffc0280c /* SPORT 0 Transmit frame sync divider 16 bit */
+#define SPORT0_TFSDIV			HALFWORD_REF(SPORT0_TFSDIV_ADDR)
+#define SPORT0_RFSDIV_ADDR		0xffc0280e /* SPORT 0 Receive frame sync divider 16 bit */
+#define SPORT0_RFSDIV			HALFWORD_REF(SPORT0_RFSDIV_ADDR)
+#define SPORT0_STAT_ADDR		0xffc02810 /* SPORT 0 status register 16 bit */
+#define SPORT0_STAT				HALFWORD_REF(SPORT0_STAT_ADDR)
+#define SPORT0_MTCS0_ADDR		0xffc02812 /* SPORT 0 Multi-channel Transmit select reg 16 bit */
+#define SPORT0_MTCS0			HALFWORD_REF(SPORT0_MTCS0_ADDR)
+#define SPORT0_MTCS1_ADDR		0xffc02814 /* SPORT 0 Multi-channel Transmit select reg 16 bit */
+#define SPORT0_MTCS1			HALFWORD_REF(SPORT0_MTCS1_ADDR)
+#define SPORT0_MTCS2_ADDR		0xffc02816 /* SPORT 0 Multi-channel Transmit select reg 16 bit */
+#define SPORT0_MTCS2			HALFWORD_REF(SPORT0_MTCS2_ADDR)
+#define SPORT0_MTCS3_ADDR		0xffc02818 /* SPORT 0 Multi-channel Transmit select reg 16 bit */
+#define SPORT0_MTCS3			HALFWORD_REF(SPORT0_MTCS3_ADDR)
+#define SPORT0_MTCS4_ADDR		0xffc0281a /* SPORT 0 Multi-channel Transmit select reg 16 bit */
+#define SPORT0_MTCS4			HALFWORD_REF(SPORT0_MTCS4_ADDR)
+#define SPORT0_MTCS5_ADDR		0xffc0281c /* SPORT 0 Multi-channel Transmit select reg 16 bit */
+#define SPORT0_MTCS5			HALFWORD_REF(SPORT0_MTCS5_ADDR)
+#define SPORT0_MTCS6_ADDR		0xffc0281e /* SPORT 0 Multi-channel Transmit select reg 16 bit */
+#define SPORT0_MTCS6			HALFWORD_REF(SPORT0_MTCS6_ADDR)
+#define SPORT0_MTCS7_ADDR		0xffc02820 /* SPORT 0 Multi-channel Transmit select reg 16 bit */
+#define SPORT0_MTCS7			HALFWORD_REF(SPORT0_MTCS7_ADDR)
+#define SPORT0_MRCS0_ADDR		0xffc02822 /* SPORT 0 Multi-channel Receive select reg 16 bit */
+#define SPORT0_MRCS0			HALFWORD_REF(SPORT0_MRCS0_ADDR)
+#define SPORT0_MRCS1_ADDR		0xffc02824 /* SPORT 0 Multi-channel Receive select reg 16 bit */
+#define SPORT0_MRCS1			HALFWORD_REF(SPORT0_MRCS1_ADDR)
+#define SPORT0_MRCS2_ADDR		0xffc02826 /* SPORT 0 Multi-channel Receive select reg 16 bit */
+#define SPORT0_MRCS2			HALFWORD_REF(SPORT0_MRCS2_ADDR)
+#define SPORT0_MRCS3_ADDR		0xffc02828 /* SPORT 0 Multi-channel Receive select reg 16 bit */
+#define SPORT0_MRCS3			HALFWORD_REF(SPORT0_MRCS3_ADDR)
+#define SPORT0_MRCS4_ADDR		0xffc0282a /* SPORT 0 Multi-channel Receive select reg 16 bit */
+#define SPORT0_MRCS4			HALFWORD_REF(SPORT0_MRCS4_ADDR)
+#define SPORT0_MRCS5_ADDR		0xffc0282c /* SPORT 0 Multi-channel Receive select reg 16 bit */
+#define SPORT0_MRCS5			HALFWORD_REF(SPORT0_MRCS5_ADDR)
+#define SPORT0_MRCS6_ADDR		0xffc0282e /* SPORT 0 Multi-channel Receive select reg 16 bit */
+#define SPORT0_MRCS6			HALFWORD_REF(SPORT0_MRCS6_ADDR)
+#define SPORT0_MRCS7_ADDR		0xffc02830 /* SPORT 0 Multi-channel Receive select reg 16 bit */
+#define SPORT0_MRCS7			HALFWORD_REF(SPORT0_MRCS7_ADDR)
+#define SPORT0_MCMC1_ADDR		0xffc02832 /* SPORT 0 Multi-channel configuration reg 1 16 bit */
+#define SPORT0_MCMC1			HALFWORD_REF(SPORT0_MCMC1_ADDR)
+#define SPORT0_MCMC2_ADDR		0xffc02834 /* SPORT 0 Multi-channel configuration reg 2 16 bit */
+#define SPORT0_MCMC2			HALFWORD_REF(SPORT0_MCMC2_ADDR)
+
+#define SPORT0_CURR_PTR_RX_ADDR		0xffc02a00 /* SPORT 0 RCV DMA Current pointer reg 16 bit*/
+#define SPORT0_CURR_PTR_RX			HALFWORD_REF(SPORT0_CURR_PTR_RX_ADDR)
+#define SPORT0_CONFIG_DMA_RX_ADDR	0xffc02a02 /* SPORT 0 RCV DMA Configuration reg 16 bit */
+
+#if 0
+#define SPORT0_CONFIG_DMA_RX		HALFWORD_REF(SPORT0_CONFIG_RX_ADDR)
+#else
+#define SPORT0_CONFIG_DMA_RX		HALFWORD_REF(SPORT0_CONFIG_DMA_RX_ADDR)
+#endif
+
+#define SPORT0_START_ADDR_HI_RX_ADDR  	0xffc02a04 /* SPORT 0 RCV DMA start add. hi reg 16 bit */
+#define SPORT0_START_ADDR_HI_RX		HALFWORD_REF(SPORT0_START_ADDR_HI_RX_ADDR)
+#define SPORT0_START_ADDR_LO_RX_ADDR  	0xffc02a06 /* SPORT 0 RCV DMA start add. lo reg 16 bit */
+#define SPORT0_START_ADDR_LO_RX		HALFWORD_REF(SPORT0_START_ADDR_LO_RX_ADDR)
+#define SPORT0_COUNT_RX_ADDR  		0xffc02a08 /* SPORT 0 RCV DMA count reg 16 bit */
+#define SPORT0_COUNT_RX				HALFWORD_REF(SPORT0_COUNT_RX_ADDR)
+#define SPORT0_NEXT_DESCR_RX_ADDR  	0xffc02a0a /* SPORT 0 RCV DMA next descriptor poin reg 16 bit */
+#define SPORT0_NEXT_DESCR_RX		HALFWORD_REF(SPORT0_NEXT_DESCR_RX_ADDR)
+#define SPORT0_DESCR_RDY_RX_ADDR  	0xffc02a0c /* SPORT 0 RCV DMA descriptor ready reg 16 bit */
+#define SPORT0_DESCR_RDY_RX			HALFWORD_REF(SPORT0_DESCR_RDY_RX_ADDR)
+#define SPORT0_IRQSTAT_RX_ADDR  	0xffc02a0e /* SPORT 0 RCV DMA interrupt reg 16 bit */
+#define SPORT0_IRQSTAT_RX			HALFWORD_REF(SPORT0_IRQSTAT_RX_ADDR)
+
+#define SPORT0_CURR_PTR_TX_ADDR		0xffc02b00 /* SPORT 0 XMT DMA Current pointer reg 16 bit*/
+#define SPORT0_CURR_PTR_TX			HALFWORD_REF(SPORT0_CURR_PTR_TX_ADDR)
+#define SPORT0_CONFIG_DMA_TX_ADDR	0xffc02b02 /* SPORT 0 XMT DMA Configuration reg 16 bit */
+
+/* Fixed in Jul 2 2003 for SPORT driver*/
+#if 0
+#define SPORT0_CONFIG_DMA_TX		HALFWORD_REF(SPORT0_CONFIG_TX_ADDR)
+#else
+#define SPORT0_CONFIG_DMA_TX		HALFWORD_REF(SPORT0_CONFIG_DMA_TX_ADDR)
+#endif
+
+#define SPORT0_START_ADDR_HI_TX_ADDR  	0xffc02b04 /* SPORT 0 XMT DMA start add. hi reg 16 bit */
+#define SPORT0_START_ADDR_HI_TX		HALFWORD_REF(SPORT0_START_ADDR_HI_TX_ADDR)
+#define SPORT0_START_ADDR_LO_TX_ADDR  	0xffc02b06 /* SPORT 0 XMT DMA start add. lo reg 16 bit */
+#define SPORT0_START_ADDR_LO_TX		HALFWORD_REF(SPORT0_START_ADDR_LO_TX_ADDR)
+#define SPORT0_COUNT_TX_ADDR  		0xffc02b08 /* SPORT 0 XMT DMA count reg 16 bit */
+#define SPORT0_COUNT_TX				HALFWORD_REF(SPORT0_COUNT_TX_ADDR)
+#define SPORT0_NEXT_DESCR_TX_ADDR  	0xffc02b0a /* SPORT 0 XMT DMA next descriptor poin reg 16 bit */
+#define SPORT0_NEXT_DESCR_TX		HALFWORD_REF(SPORT0_NEXT_DESCR_TX_ADDR)
+#define SPORT0_DESCR_RDY_TX_ADDR  	0xffc02b0c /* SPORT 0 XMT DMA descriptor ready reg 16 bit */
+#define SPORT0_DESCR_RDY_TX			HALFWORD_REF(SPORT0_DESCR_RDY_TX_ADDR)
+#define SPORT0_IRQSTAT_TX_ADDR  	0xffc02b0e /* SPORT 0 XMT DMA interrupt reg 16 bit */
+#define SPORT0_IRQSTAT_TX			HALFWORD_REF(SPORT0_IRQSTAT_TX_ADDR)
+
+/****************************
+ *
+ *  SPORT 1 CONTROLLER REGISTERS  (0XFFC02C00 - 0XFFC02FFF)
+ *
+ ****************************/
+
+#define SPORT1_TX_CONFIG_ADDR	0xffc02c00 /* SPORT 1 Transmit configuration register 16 bit */
+#define SPORT1_TX_CONFIG		HALFWORD_REF(SPORT1_TX_CONFIG_ADDR)
+#define SPORT1_RX_CONFIG_ADDR	0xffc02c02 /* SPORT 1 Receive configuration register 16 bit */
+#define SPORT1_RX_CONFIG		HALFWORD_REF(SPORT1_RX_CONFIG_ADDR)
+#define SPORT1_TX_ADDR			0xffc02c04 /* SPORT 1 Transmit register 16 bit */
+#define SPORT1_TX				HALFWORD_REF(SPORT1_TX_ADDR)
+#define SPORT1_RX_ADDR			0xffc02c06 /* SPORT 1 Receive register 16 bit */
+#define SPORT1_RX				HALFWORD_REF(SPORT1_RX_ADDR)
+#define SPORT1_TSCLKDIV_ADDR	0xffc02c08 /* SPORT 1 Transmit serial clock divider 16 bit */
+#define SPORT1_TSCLKDIV			HALFWORD_REF(SPORT1_TSCLKDIV_ADDR)
+#define SPORT1_RSCLKDIV_ADDR	0xffc02c0a /* SPORT 1 Receive serial clock divider 16 bit */
+#define SPORT1_RSCLKDIV			HALFWORD_REF(SPORT1_RSCLKDIV_ADDR)
+#define SPORT1_TFSDIV_ADDR		0xffc02c0c /* SPORT 1 Transmit frame sync divider 16 bit */
+#define SPORT1_TFSDIV			HALFWORD_REF(SPORT1_TFSDIV_ADDR)
+#define SPORT1_RFSDIV_ADDR		0xffc02c0e /* SPORT 1 Receive frame sync divider 16 bit */
+#define SPORT1_RFSDIV			HALFWORD_REF(SPORT1_RFSDIV_ADDR)
+#define SPORT1_STAT_ADDR		0xffc02c10 /* SPORT 1 status register 16 bit */
+#define SPORT1_STAT				HALFWORD_REF(SPORT1_STAT_ADDR)
+#define SPORT1_MTCS0_ADDR		0xffc02c12 /* SPORT 1 Multi-channel Transmit select reg 16 bit */
+#define SPORT1_MTCS0			HALFWORD_REF(SPORT1_MTCS0_ADDR)
+#define SPORT1_MTCS1_ADDR		0xffc02c14 /* SPORT 1 Multi-channel Transmit select reg 16 bit */
+#define SPORT1_MTCS1			HALFWORD_REF(SPORT1_MTCS1_ADDR)
+#define SPORT1_MTCS2_ADDR		0xffc02c16 /* SPORT 1 Multi-channel Transmit select reg 16 bit */
+#define SPORT1_MTCS2			HALFWORD_REF(SPORT1_MTCS2_ADDR)
+#define SPORT1_MTCS3_ADDR		0xffc02c18 /* SPORT 1 Multi-channel Transmit select reg 16 bit */
+#define SPORT1_MTCS3			HALFWORD_REF(SPORT1_MTCS3_ADDR)
+#define SPORT1_MTCS4_ADDR		0xffc02c1a /* SPORT 1 Multi-channel Transmit select reg 16 bit */
+#define SPORT1_MTCS4			HALFWORD_REF(SPORT1_MTCS4_ADDR)
+#define SPORT1_MTCS5_ADDR		0xffc02c1c /* SPORT 1 Multi-channel Transmit select reg 16 bit */
+#define SPORT1_MTCS5			HALFWORD_REF(SPORT1_MTCS5_ADDR)
+#define SPORT1_MTCS6_ADDR		0xffc02c1e /* SPORT 1 Multi-channel Transmit select reg 16 bit */
+#define SPORT1_MTCS6			HALFWORD_REF(SPORT1_MTCS6_ADDR)
+#define SPORT1_MTCS7_ADDR		0xffc02c20 /* SPORT 1 Multi-channel Transmit select reg 16 bit */
+#define SPORT1_MTCS7			HALFWORD_REF(SPORT1_MTCS7_ADDR)
+#define SPORT1_MRCS0_ADDR		0xffc02c22 /* SPORT 1 Multi-channel Receive select reg 16 bit */
+#define SPORT1_MRCS0			HALFWORD_REF(SPORT1_MRCS0_ADDR)
+#define SPORT1_MRCS1_ADDR		0xffc02c24 /* SPORT 1 Multi-channel Receive select reg 16 bit */
+#define SPORT1_MRCS1			HALFWORD_REF(SPORT1_MRCS1_ADDR)
+#define SPORT1_MRCS2_ADDR		0xffc02c26 /* SPORT 1 Multi-channel Receive select reg 16 bit */
+#define SPORT1_MRCS2			HALFWORD_REF(SPORT1_MRCS2_ADDR)
+#define SPORT1_MRCS3_ADDR		0xffc02c28 /* SPORT 1 Multi-channel Receive select reg 16 bit */
+#define SPORT1_MRCS3			HALFWORD_REF(SPORT1_MRCS3_ADDR)
+#define SPORT1_MRCS4_ADDR		0xffc02c2a /* SPORT 1 Multi-channel Receive select reg 16 bit */
+#define SPORT1_MRCS4			HALFWORD_REF(SPORT1_MRCS4_ADDR)
+#define SPORT1_MRCS5_ADDR		0xffc02c2c /* SPORT 1 Multi-channel Receive select reg 16 bit */
+#define SPORT1_MRCS5			HALFWORD_REF(SPORT1_MRCS5_ADDR)
+#define SPORT1_MRCS6_ADDR		0xffc02c2e /* SPORT 1 Multi-channel Receive select reg 16 bit */
+#define SPORT1_MRCS6			HALFWORD_REF(SPORT1_MRCS6_ADDR)
+#define SPORT1_MRCS7_ADDR		0xffc02c30 /* SPORT 1 Multi-channel Receive select reg 16 bit */
+#define SPORT1_MRCS7			HALFWORD_REF(SPORT1_MRCS7_ADDR)
+#define SPORT1_MCMC1_ADDR		0xffc02c32 /* SPORT 1 Multi-channel configuration reg 1 16 bit */
+#define SPORT1_MCMC1			HALFWORD_REF(SPORT1_MCMC1_ADDR)
+#define SPORT1_MCMC2_ADDR		0xffc02c34 /* SPORT 1 Multi-channel configuration reg 2 16 bit */
+#define SPORT1_MCMC2			HALFWORD_REF(SPORT1_MCMC2_ADDR)
+
+#define SPORT1_CURR_PTR_RX_ADDR		0xffc02e00 /* SPORT 1 RCV DMA Current pointer reg 16 bit*/
+#define SPORT1_CURR_PTR_RX			HALFWORD_REF(SPORT1_CURR_PTR_RX_ADDR)
+#define SPORT1_CONFIG_DMA_RX_ADDR	0xffc02e02 /* SPORT 1 RCV DMA Configuration reg 16 bit */
+
+/* Fixed for SPORT driver, Jul 2 2003 */
+#if 0
+#define SPORT1_CONFIG_DMA_RX		HALFWORD_REF(SPORT1_CONFIG_RX_ADDR)
+#else
+#define SPORT1_CONFIG_DMA_RX		HALFWORD_REF(SPORT1_CONFIG_DMA_RX_ADDR)
+#endif
+
+#define SPORT1_START_ADDR_HI_RX_ADDR  	0xffc02e04 /* SPORT 1 RCV DMA start add. hi reg 16 bit */
+#define SPORT1_START_ADDR_HI_RX		HALFWORD_REF(SPORT1_START_ADDR_HI_RX_ADDR)
+#define SPORT1_START_ADDR_LO_RX_ADDR  	0xffc02e06 /* SPORT 1 RCV DMA start add. lo reg 16 bit */
+#define SPORT1_START_ADDR_LO_RX		HALFWORD_REF(SPORT1_START_ADDR_LO_RX_ADDR)
+#define SPORT1_COUNT_RX_ADDR  		0xffc02e08 /* SPORT 1 RCV DMA count reg 16 bit */
+#define SPORT1_COUNT_RX				HALFWORD_REF(SPORT1_COUNT_RX_ADDR)
+#define SPORT1_NEXT_DESCR_RX_ADDR  	0xffc02e0a /* SPORT 1 RCV DMA next descriptor poin reg 16 bit */
+#define SPORT1_NEXT_DESCR_RX		HALFWORD_REF(SPORT1_NEXT_DESCR_RX_ADDR)
+#define SPORT1_DESCR_RDY_RX_ADDR  	0xffc02e0c /* SPORT 1 RCV DMA descriptor ready reg 16 bit */
+#define SPORT1_DESCR_RDY_RX			HALFWORD_REF(SPORT1_DESCR_RDY_RX_ADDR)
+#define SPORT1_IRQSTAT_RX_ADDR  	0xffc02e0e /* SPORT 1 RCV DMA interrupt reg 16 bit */
+#define SPORT1_IRQSTAT_RX			HALFWORD_REF(SPORT1_IRQSTAT_RX_ADDR)
+
+#define SPORT1_CURR_PTR_TX_ADDR		0xffc02f00 /* SPORT 1 XMT DMA Current pointer reg 16 bit*/
+#define SPORT1_CURR_PTR_TX			HALFWORD_REF(SPORT1_CURR_PTR_TX_ADDR)
+#define SPORT1_CONFIG_DMA_TX_ADDR	0xffc02f02 /* SPORT 1 XMT DMA Configuration reg 16 bit */
+
+#if 0
+#define SPORT1_CONFIG_DMA_TX		HALFWORD_REF(SPORT1_CONFIG_TX_ADDR)
+#else
+#define SPORT1_CONFIG_DMA_TX		HALFWORD_REF(SPORT1_CONFIG_DMA_TX_ADDR)
+#endif
+
+#define SPORT1_START_ADDR_HI_TX_ADDR  	0xffc02f04 /* SPORT 1 XMT DMA start add. hi reg 16 bit */
+#define SPORT1_START_ADDR_HI_TX		HALFWORD_REF(SPORT1_START_ADDR_HI_TX_ADDR)
+#define SPORT1_START_ADDR_LO_TX_ADDR  	0xffc02f06 /* SPORT 1 XMT DMA start add. lo reg 16 bit */
+#define SPORT1_START_ADDR_LO_TX		HALFWORD_REF(SPORT1_START_ADDR_LO_TX_ADDR)
+#define SPORT1_COUNT_TX_ADDR  		0xffc02f08 /* SPORT 1 XMT DMA count reg 16 bit */
+#define SPORT1_COUNT_TX				HALFWORD_REF(SPORT1_COUNT_TX_ADDR)
+#define SPORT1_NEXT_DESCR_TX_ADDR  	0xffc02f0a /* SPORT 1 XMT DMA next descriptor poin reg 16 bit */
+#define SPORT1_NEXT_DESCR_TX		HALFWORD_REF(SPORT1_NEXT_DESCR_TX_ADDR)
+#define SPORT1_DESCR_RDY_TX_ADDR  	0xffc02f0c /* SPORT 1 XMT DMA descriptor ready reg 16 bit */
+#define SPORT1_DESCR_RDY_TX			HALFWORD_REF(SPORT1_DESCR_RDY_TX_ADDR)
+#define SPORT1_IRQSTAT_TX_ADDR  	0xffc02f0e /* SPORT 1 XMT DMA interrupt reg 16 bit */
+#define SPORT1_IRQSTAT_TX			HALFWORD_REF(SPORT1_IRQSTAT_TX_ADDR)
+
+/****************************
+ *
+ *  SPI 0 CONTROLLER REGISTERS  (0XFFC03000 - 0XFFC033FF)
+ *
+ ****************************/
+
+#define SPI0_CTL_ADDR		0xffc03000 /* SPI 0 control register 16 bit */
+#define SPI0_CTL			HALFWORD_REF(SPI0_CTL_ADDR)
+#define SPI0_FLG_ADDR		0xffc03002 /* SPI 0 flag register 16 bit */
+#define SPI0_FLG			HALFWORD_REF(SPI0_FLG_ADDR)
+#define SPI0_ST_ADDR		0xffc03004 /* SPI 0 status register 16 bit */
+#define SPI0_ST				HALFWORD_REF(SPI0_ST_ADDR)
+#define SPI0_TDBR_ADDR		0xffc03006 /* SPI 0 transmit data buffer register 16 bit */
+#define SPI0_TDBR			HALFWORD_REF(SPI0_TDBR_ADDR)
+#define SPI0_RDBR_ADDR		0xffc03008 /* SPI 0 receive data buffer register 16 bit */
+#define SPI0_RDBR			HALFWORD_REF(SPI0_RDBR_ADDR)
+#define SPI0_BAUD_ADDR		0xffc0300a /* SPI 0 baud rate register 16 bit */
+#define SPI0_BAUD			HALFWORD_REF(SPI0_BAUD_ADDR)
+#define SPI0_SHADOW_ADDR	0xffc0300c /* SPI 0 RDBR register 16 bit */
+#define SPI0_SHADOW			HALFWORD_REF(SPI0_SHADOW_ADDR)
+
+#define SPI0_CURR_PTR_ADDR		0xffc03200 /* SPI 0 DMA current pointer register 16 bit */
+#define SPI0_CURR_PTR			HALFWORD_REF(SPI0_CURR_PTR_ADDR)
+#define SPI0_CONFIG_ADDR		0xffc03202 /* SPI 0 DMA configuration register 16 bit */
+#define SPI0_CONFIG				HALFWORD_REF(SPI0_CONFIG_ADDR)
+#define SPI0_START_ADDR_HI_ADDR	0xffc03204 /* SPI 0 DMA start address hi register 16 bit */
+#define SPI0_START_ADDR_HI		HALFWORD_REF(SPI0_START_ADDR_HI_ADDR)
+#define SPI0_START_ADDR_LO_ADDR	0xffc03206 /* SPI 0 DMA start address lo register 16 bit */
+#define SPI0_START_ADDR_LO		HALFWORD_REF(SPI0_START_ADDR_LO_ADDR)
+#define SPI0_COUNT_ADDR			0xffc03208 /* SPI 0 DMA count register 16 bit */
+#define SPI0_COUNT				HALFWORD_REF(SPI0_COUNT_ADDR)
+#define SPI0_NEXT_DESCR_ADDR	0xffc0320a /* SPI 0 DMA Next descriptor pointer register 16 bit */
+#define SPI0_NEXT_DESCR			HALFWORD_REF(SPI0_NEXT_DESCR_ADDR)
+#define SPI0_DESCR_RDY_ADDR		0xffc0320c /* SPI 0 DMA descriptor ready register 16 bit */
+#define SPI0_DESCR_RDY			HALFWORD_REF(SPI0_DESCR_RDY_ADDR)
+#define SPI0_DMA_INT_ADDR		0xffc0320e /* SPI 0 DMA interrupt register 16 bit */
+#define SPI0_DMA_INT			HALFWORD_REF(SPI0_DMA_INT_ADDR)
+
+/****************************
+ *
+ *  SPI 1 CONTROLLER REGISTERS  (0XFFC03400 - 0XFFC037FF)
+ *
+ ****************************/
+
+#define SPI1_CTL_ADDR		0xffc03400 /* SPI 1 control register 16 bit */
+#define SPI1_CTL			HALFWORD_REF(SPI1_CTL_ADDR)
+#define SPI1_FLG_ADDR		0xffc03402 /* SPI 1 flag register 16 bit */
+#define SPI1_FLG			HALFWORD_REF(SPI1_FLG_ADDR)
+#define SPI1_ST_ADDR		0xffc03404 /* SPI 1 status register 16 bit */
+#define SPI1_ST				HALFWORD_REF(SPI1_ST_ADDR)
+#define SPI1_TDBR_ADDR		0xffc03406 /* SPI 1 transmit data buffer register 16 bit */
+#define SPI1_TDBR			HALFWORD_REF(SPI1_TDBR_ADDR)
+#define SPI1_RDBR_ADDR		0xffc03408 /* SPI 1 receive data buffer register 16 bit */
+#define SPI1_RDBR			HALFWORD_REF(SPI1_RDBR_ADDR)
+#define SPI1_BAUD_ADDR		0xffc0340a /* SPI 1 baud rate register 16 bit */
+#define SPI1_BAUD			HALFWORD_REF(SPI1_BAUD_ADDR)
+#define SPI1_SHADOW_ADDR	0xffc0340c /* SPI 1 RDBR register 16 bit */
+#define SPI1_SHADOW			HALFWORD_REF(SPI1_SHADOW_ADDR)
+
+#define SPI1_CURR_PTR_ADDR		0xffc03600 /* SPI 1 DMA current pointer register 16 bit */
+#define SPI1_CURR_PTR			HALFWORD_REF(SPI1_CURR_PTR_ADDR)
+#define SPI1_CONFIG_ADDR		0xffc03602 /* SPI 1 DMA configuration register 16 bit */
+#define SPI1_CONFIG				HALFWORD_REF(SPI1_CONFIG_ADDR)
+#define SPI1_START_ADDR_HI_ADDR	0xffc03604 /* SPI 1 DMA start address hi register 16 bit */
+#define SPI1_START_ADDR_HI		HALFWORD_REF(SPI1_START_ADDR_HI_ADDR)
+#define SPI1_START_ADDR_LO_ADDR	0xffc03606 /* SPI 1 DMA start address lo register 16 bit */
+#define SPI1_START_ADDR_LO		HALFWORD_REF(SPI1_START_ADDR_LO_ADDR)
+#define SPI1_COUNT_ADDR			0xffc03608 /* SPI 1 DMA count register 16 bit */
+#define SPI1_COUNT				HALFWORD_REF(SPI1_COUNT_ADDR)
+#define SPI1_NEXT_DESCR_ADDR	0xffc0360a /* SPI 1 DMA Next descriptor pointer register 16 bit */
+#define SPI1_NEXT_DESCR			HALFWORD_REF(SPI1_NEXT_DESCR_ADDR)
+#define SPI1_DESCR_RDY_ADDR		0xffc0360c /* SPI 1 DMA descriptor ready register 16 bit */
+#define SPI1_DESCR_RDY			HALFWORD_REF(SPI1_DESCR_RDY_ADDR)
+#define SPI1_DMA_INT_ADDR		0xffc0360e /* SPI 1 DMA interrupt register 16 bit */
+#define SPI1_DMA_INT			HALFWORD_REF(SPI1_DMA_INT_ADDR)
+
+/****************************
+ *
+ *  MEMORY DMA CONTROLLER REGISTERS  (0XFFC03800 - 0XFFC03BFF)
+ *
+ ****************************/
+
+#define MDW_DCP_ADDR		0xffc03800 /* Current pointer write channel register 16 bit */
+#define MDW_DCP				HALFWORD_REF(MDW_DCP_ADDR)
+#define MDW_DCFG_ADDR		0xffc03802 /* DMA configuration write channel register 16 bit */
+#define MDW_DCFG			HALFWORD_REF(MDW_DCFG_ADDR)
+#define MDW_DSAH_ADDR		0xffc03804 /* Start address hi write channel register 16 bit */
+#define MDW_DSAH			HALFWORD_REF(MDW_DSAH_ADDR)
+#define MDW_DSAL_ADDR		0xffc03806 /* Start address lo write channel register 16 bit */
+#define MDW_DSAL			HALFWORD_REF(MDW_DSAL_ADDR)
+#define MDW_DCT_ADDR		0xffc03808 /* DMA count write channel register 16 bit */
+#define MDW_DCT				HALFWORD_REF(MDW_DCT_ADDR)
+#define MDW_DND_ADDR		0xffc0380a /* Next descriptor pointer write channel register 16 bit */
+#define MDW_DND				HALFWORD_REF(MDW_DND_ADDR)
+#define MDW_DDR_ADDR		0xffc0380c /* Descriptor ready write channel register 16 bit */
+#define MDW_DDR				HALFWORD_REF(MDW_DDR_ADDR)
+#define MDW_DI_ADDR			0xffc0380e /* DMA interrupt write channel register 16 bit */
+#define MDW_DI				HALFWORD_REF(MDW_DI_ADDR)
+
+#define MDR_DCP_ADDR		0xffc03900 /* Current pointer read channel register 16 bit */
+#define MDR_DCP				HALFWORD_REF(MDR_DCP_ADDR)
+#define MDR_DCFG_ADDR		0xffc03902 /* DMA configuration read channel register 16 bit */
+#define MDR_DCFG			HALFWORD_REF(MDR_DCFG_ADDR)
+#define MDR_DSAH_ADDR		0xffc03904 /* Start address hi read channel register 16 bit */
+#define MDR_DSAH			HALFWORD_REF(MDR_DSAH_ADDR)
+#define MDR_DSAL_ADDR		0xffc03906 /* Start address lo read channel register 16 bit */
+#define MDR_DSAL			HALFWORD_REF(MDR_DSAL_ADDR)
+#define MDR_DCT_ADDR		0xffc03908 /* DMA count read channel register 16 bit */
+#define MDR_DCT				HALFWORD_REF(MDR_DCT_ADDR)
+#define MDR_DND_ADDR		0xffc0390a /* Next descriptor pointer read channel register 16 bit */
+#define MDR_DND				HALFWORD_REF(MDR_DND_ADDR)
+#define MDR_DDR_ADDR		0xffc0390c /* Descriptor ready read channel register 16 bit */
+#define MDR_DDR				HALFWORD_REF(MDR_DDR_ADDR)
+#define MDR_DI_ADDR			0xffc0390e /* DMA interrupt read channel register 16 bit */
+#define MDR_DI				HALFWORD_REF(MDR_DI_ADDR)
+
+/****************************
+ *
+ *  ASYNCHRONOUS MEMORY CONTROLLER REGISTERS EDIU (0XFFC03C00 - 0XFFC03FFF)
+ *
+ ****************************/
+
+#define EBIU_AMGCTL_ADDR	0xffc03c00 /* Asynchronous memory global control register ? bit */
+#define EBIU_AMGCTL			WORD_REF(MDW_AMGCTL_ADDR)
+#define EBIU_AMBCTL0_ADDR	0xffc03c04 /* Asynchronous memory bank control register 0 32 bit */
+#define EBIU_AMBCTL0		WORD_REF(MDW_AMBCTL0_ADDR)
+#define EBIU_AMBCTL1_ADDR	0xffc03c08 /* Asynchronous memory bank control register 1 32 bit */
+#define EBIU_AMBCTL1		WORD_REF(MDW_AMBCTL1_ADDR)
+
+/****************************
+ *
+ *  PCI BRIDGE PAB REGISTERS  (0XFFC04000 - 0XFFC043FF)
+ *
+ ****************************/
+
+#define PCI_CTL_ADDR		0xffc04000 /* PCI bridge control register 32 bit */
+#define PCI_CTL				WORD_REF(PCI_CTL_ADDR)
+#define PCI_STAT_ADDR		0xffc04004 /* PCI bridge status register 32 bit */
+#define PCI_STAT			WORD_REF(PCI_STAT_ADDR)
+#define PCI_ICTL_ADDR		0xffc04008 /* PCI bridge interrupt control register 32 bit */
+#define PCI_ICTL			WORD_REF(PCI_ICTL_ADDR)
+#define PCI_MBAP_ADDR		0xffc0400c /* PCI memory space base address pointer[31:27] register 32 bit */
+#define PCI_MBAP			WORD_REF(PCI_MBAP_ADDR)
+#define PCI_IBAP_ADDR		0xffc04010 /* PCI IO space base address pointer register 32 bit */
+#define PCI_IBAP			WORD_REF(PCI_IBAP_ADDR)
+#define PCI_CPAB_ADDR		0xffc04014 /* PCI config space base address port register 32 bit */
+#define PCI_CPAB			WORD_REF(PCI_CPAB_ADDR)
+#define PCI_TMBAP_ADDR		0xffc04018 /* PCI to Tahoe memory base address pointer register 32 bit */
+#define PCI_TMBAP			WORD_REF(PCI_TMBAP_ADDR)
+#define PCI_TIBAP_ADDR		0xffc0401c /* PCI to Tahoe IO base address pointer register 32 bit */
+#define PCI_TIBAP			WORD_REF(PCI_TIBAP_ADDR)
+
+/****************************
+ *
+ *  PCI BRIDGE EXTERNAL ACCESS BUS REGISTERS  (0XEEFFFF00 - 0XEEFFFFFF)
+ *
+ ****************************/
+
+#define PCI_DMBARM_ADDR		0xeeffff00 /* PCI Device memory bar mask register 32 bit */
+#define PCI_DMBARM			WORD_REF(PCI_DMBARM_ADDR)
+#define PCI_DIBARM_ADDR		0xeeffff04 /* PCI Device IO bar mask register 32 bit */
+#define PCI_DIBARM			WORD_REF(PCI_DIBARM_ADDR)
+#define PCI_CFG_DIC_ADDR	0xeeffff08 /* PCI config Device ID register 32 bit */
+#define PCI_CFG_DIC			WORD_REF(PCI_CFG_DIC_ADDR)
+#define PCI_CFG_VIC_ADDR	0xeeffff0c /* PCI config vendor ID register 32 bit */
+#define PCI_CFG_VIC			WORD_REF(PCI_CFG_VIC_ADDR)
+#define PCI_CFG_STAT_ADDR	0xeeffff10 /* PCI config status (read only) register 32 bit */
+#define PCI_CFG_STAT		WORD_REF(PCI_CFG_STAT_ADDR)
+#define PCI_CFG_CMD_ADDR	0xeeffff14 /* PCI config command register 32 bit */
+#define PCI_CFG_CMD			WORD_REF(PCI_CFG_CMD_ADDR)
+#define PCI_CFG_CC_ADDR		0xeeffff18 /* PCI config class code register 32 bit */
+#define PCI_CFG_CC			WORD_REF(PCI_CFG_CC_ADDR)
+#define PCI_CFG_RID_ADDR	0xeeffff1C /* PCI config revision ID register 32 bit */
+#define PCI_CFG_RID			WORD_REF(PCI_CFG_RID_ADDR)
+#define PCI_CFG_BIST_ADDR	0xeeffff20 /* PCI config BIST register 32 bit */
+#define PCI_CFG_BIST		WORD_REF(PCI_CFG_BIST_ADDR)
+#define PCI_CFG_HT_ADDR		0xeeffff24 /* PCI config header type register 32 bit */
+#define PCI_CFG_HT			WORD_REF(PCI_CFG_HT_ADDR)
+#define PCI_CFG_MLT_ADDR	0xeeffff28 /* PCI config memory latency timer register 32 bit */
+#define PCI_CFG_MLT			WORD_REF(PCI_CFG_MLT_ADDR)
+#define PCI_CFG_CLS_ADDR	0xeeffff2C /* PCI config cache line (block) size register 32 bit */
+#define PCI_CFG_CLS			WORD_REF(PCI_CFG_CLS_ADDR)
+#define PCI_CFG_MBAR_ADDR	0xeeffff30 /* PCI config memory base address register 32 bit */
+#define PCI_CFG_MBAR		WORD_REF(PCI_CFG_MBAR_ADDR)
+#define PCI_CFG_IBAR_ADDR	0xeeffff34 /* PCI config IO base address register 32 bit */
+#define PCI_CFG_IBAR		WORD_REF(PCI_CFG_IBAR_ADDR)
+#define PCI_CFG_SID_ADDR	0xeeffff38 /* PCI config subsystem ID register 32 bit */
+#define PCI_CFG_SID			WORD_REF(PCI_CFG_SID_ADDR)
+#define PCI_CFG_SVID_ADDR	0xeeffff3C /* PCI config subsystem vendor ID register 32 bit */
+#define PCI_CFG_SVID		WORD_REF(PCI_CFG_SVID_ADDR)
+#define PCI_CFG_MAXL_ADDR	0xeeffff40 /* PCI config maximum latency cycles register 32 bit */
+#define PCI_CFG_MAXL		WORD_REF(PCI_CFG_MAXL_ADDR)
+#define PCI_CFG_MING_ADDR	0xeeffff44 /* PCI config minimum grant cycles register 32 bit */
+#define PCI_CFG_MING		WORD_REF(PCI_CFG_MING_ADDR)
+#define PCI_CFG_IP_ADDR		0xeeffff48 /* PCI config interrupt pin register 32 bit */
+#define PCI_CFG_IP			WORD_REF(PCI_CFG_IP_ADDR)
+#define PCI_CFG_IL_ADDR		0xeeffff4C /* PCI config interrupt line register 32 bit */
+#define PCI_CFG_IL			WORD_REF(PCI_CFG_IL_ADDR)
+#define PCI_HMCTL_ADDR		0xeeffff50 /* PCI config blocking BAR mask 1 (host only) register 32 bit */
+#define PCI_HMCTL			WORD_REF(PCI_HMCTL_ADDR)
+
+/****************************
+ *
+ *  UNIVERSAL SERIAL BUS INTERFACE (USB) REGISTERS  (0XFFC04400 - 0XFFC047FF)
+ *
+ ****************************/
+
+#define USBD_ID_ADDR		0xffc04400 /* USB Device ID register 16 bit */
+#define USBD_ID				HALFWORD_REF(USBD_ID_ADDR)
+#define USBD_FRM_ADDR		0xffc04402 /* Current USB frame number register 16 bit */
+#define USBD_FRM			HALFWORD_REF(USBD_FRM_ADDR)
+#define USBD_FRMAT_ADDR		0xffc04404 /* Match value for USB frame number register 16 bit */
+#define USBD_FRMAT			HALFWORD_REF(USBD_FRMAT_ADDR)
+#define USBD_EPBUF_ADDR		0xffc04406 /* Enables download of configuration into UDC core register 16 bit */
+#define USBD_EPBUF			HALFWORD_REF(USBD_EPBUF_ADDR)
+#define USBD_STAT_ADDR		0xffc04408 /* Return USBD Module status register 16 bit */
+#define USBD_STAT			HALFWORD_REF(USBD_STAT_ADDR)
+#define USBD_CTRL_ADDR		0xffc0440a /* Allows configuration & control of USBD module register 16 bit */
+#define USBD_CTRL			HALFWORD_REF(USBD_CTRL_ADDR)
+#define USBD_GINTR_ADDR		0xffc0440c /* Global interrupt register 16 bit */
+#define USBD_GINTR			HALFWORD_REF(USBD_GINTR_ADDR)
+#define USBD_GMASK_ADDR		0xffc0440e /* Global interrupt register mask register 16 bit */
+#define USBD_GMASK			HALFWORD_REF(USBD_GMASK_ADDR)
+
+#define USBD_DMACFG_ADDR	0xffc04440 /* DMA Master channel configuration register 16 bit */
+#define USBD_DMACFG			HALFWORD_REF(USBD_DMACFG_ADDR)
+#define USBD_DMABL_ADDR		0xffc04442 /* DMA Master channel base address low register 16 bit */
+#define USBD_DMABL			HALFWORD_REF(USBD_DMABL_ADDR)
+#define USBD_DMABH_ADDR		0xffc04444 /* DMA Master channel base address high register 16 bit */
+#define USBD_DMABH			HALFWORD_REF(USBD_DMABH_ADDR)
+#define USBD_DMACT_ADDR		0xffc04446 /* DMA Master channel count register 16 bit */
+#define USBD_DMACT			HALFWORD_REF(USBD_DMACT_ADDR)
+#define USBD_DMAIRQ_ADDR	0xffc04448 /* DMA Master channel IRQ register 16 bit */
+#define USBD_DMAIRQ			HALFWORD_REF(USBD_DMAIRQ_ADDR)
+
+#define USBD_INTR0_ADDR		0xffc04480 /* USB Endpoint 0 interrupt register 16 bit */
+#define USBD_INTR0			HALFWORD_REF(USBD_INTR0_ADDR)
+#define USBD_MASK0_ADDR		0xffc04482 /* USB Endpoint 0 mask register 16 bit */
+#define USBD_MASK0			HALFWORD_REF(USBD_MASK0_ADDR)
+#define USBD_EPCFG0_ADDR	0xffc04484 /* USB Endpoint 0 control register 16 bit */
+#define USBD_EPCFG0			HALFWORD_REF(USBD_EPCFG0_ADDR)
+#define USBD_EPADR0_ADDR	0xffc04486 /* USB Endpoint 0 address offset register 16 bit */
+#define USBD_EPADR0			HALFWORD_REF(USBD_EPADR0_ADDR)
+#define USBD_EPLEN0_ADDR	0xffc04488 /* USB Endpoint 0 buffer length register 16 bit */
+#define USBD_EPLEN0			HALFWORD_REF(USBD_EPLEN0_ADDR)
+
+#define USBD_INTR1_ADDR		0xffc0448a /* USB Endpoint 1 interrupt register 16 bit */
+#define USBD_INTR1			HALFWORD_REF(USBD_INTR1_ADDR)
+#define USBD_MASK1_ADDR		0xffc0448c /* USB Endpoint 1 mask register 16 bit */
+#define USBD_MASK1			HALFWORD_REF(USBD_MASK1_ADDR)
+#define USBD_EPCFG1_ADDR	0xffc0448e /* USB Endpoint 1 control register 16 bit */
+#define USBD_EPCFG1			HALFWORD_REF(USBD_EPCFG1_ADDR)
+#define USBD_EPADR1_ADDR	0xffc04490 /* USB Endpoint 1 address offset register 16 bit */
+#define USBD_EPADR1			HALFWORD_REF(USBD_EPADR1_ADDR)
+#define USBD_EPLEN1_ADDR	0xffc04492 /* USB Endpoint 1 buffer length register 16 bit */
+#define USBD_EPLEN1			HALFWORD_REF(USBD_EPLEN1_ADDR)
+
+#define USBD_INTR2_ADDR		0xffc04494 /* USB Endpoint 2 interrupt register 16 bit */
+#define USBD_INTR2			HALFWORD_REF(USBD_INTR2_ADDR)
+#define USBD_MASK2_ADDR		0xffc04496 /* USB Endpoint 2 mask register 16 bit */
+#define USBD_MASK2			HALFWORD_REF(USBD_MASK2_ADDR)
+#define USBD_EPCFG2_ADDR	0xffc04498 /* USB Endpoint 2 control register 16 bit */
+#define USBD_EPCFG2			HALFWORD_REF(USBD_EPCFG2_ADDR)
+#define USBD_EPADR2_ADDR	0xffc0449a /* USB Endpoint 2 address offset register 16 bit */
+#define USBD_EPADR2			HALFWORD_REF(USBD_EPADR2_ADDR)
+#define USBD_EPLEN2_ADDR	0xffc0449c /* USB Endpoint 2 buffer length register 16 bit */
+#define USBD_EPLEN2			HALFWORD_REF(USBD_EPLEN2_ADDR)
+
+/* Fixed by HuTao, Jun18 2003 4:35PM */
+#if 0
+#define USBD_INTR3_ADDR		0xffc0448e /* USB Endpoint 3 interrupt register 16 bit */
+#else
+#define USBD_INTR3_ADDR		0xffc0449e /* USB Endpoint 3 interrupt register 16 bit */
+#endif
+
+#define USBD_INTR3			HALFWORD_REF(USBD_INTR3_ADDR)
+#define USBD_MASK3_ADDR		0xffc044a0 /* USB Endpoint 3 mask register 16 bit */
+#define USBD_MASK3			HALFWORD_REF(USBD_MASK3_ADDR)
+#define USBD_EPCFG3_ADDR	0xffc044a2 /* USB Endpoint 3 control register 16 bit */
+#define USBD_EPCFG3			HALFWORD_REF(USBD_EPCFG3_ADDR)
+#define USBD_EPADR3_ADDR	0xffc044a4 /* USB Endpoint 3 address offset register 16 bit */
+#define USBD_EPADR3			HALFWORD_REF(USBD_EPADR3_ADDR)
+#define USBD_EPLEN3_ADDR	0xffc044a6 /* USB Endpoint 3 buffer length register 16 bit */
+#define USBD_EPLEN3			HALFWORD_REF(USBD_EPLEN3_ADDR)
+
+#define USBD_INTR4_ADDR		0xffc044a8 /* USB Endpoint 4 interrupt register 16 bit */
+#define USBD_INTR4			HALFWORD_REF(USBD_INTR4_ADDR)
+#define USBD_MASK4_ADDR		0xffc044aa /* USB Endpoint 4 mask register 16 bit */
+#define USBD_MASK4			HALFWORD_REF(USBD_MASK4_ADDR)
+#define USBD_EPCFG4_ADDR	0xffc044ac /* USB Endpoint 4 control register 16 bit */
+#define USBD_EPCFG4			HALFWORD_REF(USBD_EPCFG4_ADDR)
+#define USBD_EPADR4_ADDR	0xffc044ae /* USB Endpoint 4 address offset register 16 bit */
+#define USBD_EPADR4			HALFWORD_REF(USBD_EPADR4_ADDR)
+#define USBD_EPLEN4_ADDR	0xffc044b0 /* USB Endpoint 4 buffer length register 16 bit */
+#define USBD_EPLEN4			HALFWORD_REF(USBD_EPLEN4_ADDR)
+
+#define USBD_INTR5_ADDR		0xffc044b2 /* USB Endpoint 5 interrupt register 16 bit */
+#define USBD_INTR5			HALFWORD_REF(USBD_INTR5_ADDR)
+#define USBD_MASK5_ADDR		0xffc044b4 /* USB Endpoint 5 mask register 16 bit */
+#define USBD_MASK5			HALFWORD_REF(USBD_MASK5_ADDR)
+#define USBD_EPCFG5_ADDR	0xffc044b6 /* USB Endpoint 5 control register 16 bit */
+#define USBD_EPCFG5			HALFWORD_REF(USBD_EPCFG5_ADDR)
+#define USBD_EPADR5_ADDR	0xffc044b8 /* USB Endpoint 5 address offset register 16 bit */
+#define USBD_EPADR5			HALFWORD_REF(USBD_EPADR5_ADDR)
+#define USBD_EPLEN5_ADDR	0xffc044ba /* USB Endpoint 5 buffer length register 16 bit */
+#define USBD_EPLEN5			HALFWORD_REF(USBD_EPLEN5_ADDR)
+
+#define USBD_INTR6_ADDR		0xffc044bc /* USB Endpoint 6 interrupt register 16 bit */
+#define USBD_INTR6			HALFWORD_REF(USBD_INTR6_ADDR)
+#define USBD_MASK6_ADDR		0xffc044be /* USB Endpoint 6 mask register 16 bit */
+#define USBD_MASK6			HALFWORD_REF(USBD_MASK6_ADDR)
+#define USBD_EPCFG6_ADDR	0xffc044c0 /* USB Endpoint 6 control register 16 bit */
+#define USBD_EPCFG6			HALFWORD_REF(USBD_EPCFG6_ADDR)
+#define USBD_EPADR6_ADDR	0xffc044c2 /* USB Endpoint 6 address offset register 16 bit */
+#define USBD_EPADR6			HALFWORD_REF(USBD_EPADR6_ADDR)
+#define USBD_EPLEN6_ADDR	0xffc044c4 /* USB Endpoint 6 buffer length register 16 bit */
+#define USBD_EPLEN6			HALFWORD_REF(USBD_EPLEN6_ADDR)
+
+#define USBD_INTR7_ADDR		0xffc044c6 /* USB Endpoint 7 interrupt register 16 bit */
+#define USBD_INTR7			HALFWORD_REF(USBD_INTR7_ADDR)
+#define USBD_MASK7_ADDR		0xffc044c8 /* USB Endpoint 7 mask register 16 bit */
+#define USBD_MASK7			HALFWORD_REF(USBD_MASK7_ADDR)
+#define USBD_EPCFG7_ADDR	0xffc044ca /* USB Endpoint 7 control register 16 bit */
+#define USBD_EPCFG7			HALFWORD_REF(USBD_EPCFG7_ADDR)
+#define USBD_EPADR7_ADDR	0xffc044cc /* USB Endpoint 7 address offset register 16 bit */
+#define USBD_EPADR7			HALFWORD_REF(USBD_EPADR7_ADDR)
+#define USBD_EPLEN7_ADDR	0xffc044ce /* USB Endpoint 7 buffer length register 16 bit */
+#define USBD_EPLEN7			HALFWORD_REF(USBD_EPLEN7_ADDR)
+
+/****************************
+ *
+ * SYSTEM BUS INTERFACE UNIT REGISTERS  (0XFFC04800 - 0XFFC04FFF)
+ *
+ ****************************/
+
+#define L1SBAR_ADDR		0xffc04840 /* L1 SRAM base address register 16 bit */
+#define L1SBAR			HALFWORD_REF(L1SBAR_ADDR)
+#define L1CSR_ADDR		0xffc04844 /* L1 SRAM control initialization register 32 bit */
+#define L1CSR			WORD_REF(L1CSR_ADDR)
+#define DB_NDBP_ADDR		0xffc04880 /* Next descriptor base pointer register 32 bit */
+#define DB_NDBP			WORD_REF(DB_NDBP_ADDR)
+#define DB_ACOMP_ADDR		0xffc04884 /* DMA bus address comparator register 32 bit */
+#define DB_ACOMP		WORD_REF(DB_ACOMP_ADDR)
+#define DB_CCOMP_ADDR		0xffc04888 /* DMA bus control comparator register 32 bit */
+#define DB_CCOMP		WORD_REF(DB_CCOMP_ADDR)
+
+/****************************
+ *
+ * SDRAM CONTROLLER EXTERNAL BUS INTERFACE REGISTERS  (0XFFC04C00 - 0XFFC04FFF)
+ *
+ ****************************/
+
+#define EBIU_SDGCTL_ADDR	0xffc04c00 /* SDRAM Memory global control register 32 bit */
+#define EBIU_SDGCTL		WORD_REF(EBIU_SDGCTL_ADDR)
+#define EBIU_SDBCTL_ADDR	0xffc04c00 /* SDRAM Memory bank control register 32 bit */
+#define EBIU_SDBCTL		WORD_REF(EBIU_SDBCTL_ADDR)
+#define EBIU_SDRRC_ADDR		0xffc04c00 /* SDRAM Memory refresh rate count register 16 bit */
+#define EBIU_SDRRC		HALFWORD_REF(EBIU_SDRRC_ADDR)
+#define EBIU_SDSTAT_ADDR	0xffc04c00 /* SDRAM control status register 16 bit */
+#define EBIU_SDSTAT		HALFWORD_REF(EBIU_SDSTAT_ADDR)
+
+
+ /*      FOLLOWING ARE THE FRIO CORE MMR REGISTERS (TOP 2 MB)     */
+
+/****************************
+ *
+ *  L1 DATA MEMORY CONTROLLER REGISTERS  (0XFFE00000 - 0XFFE00404)
+ *
+ ****************************/
+
+#define SRAM_BASE_ADDR_ADDR	0xffe00000 /* read only register 32 bit */
+#define SRAM_BASE_ADDR		WORD_REF(SRAM_BASE_ADDR_ADDR)
+#define DATA_FAULT_STATUS_ADDR	0xffe00008 /* read only register 32 bit */
+#define DATA_FAULT_STATUS	WORD_REF(DATA_FAULT_STATUS_ADDR)
+#define DATA_FAULT_ADDR_ADDR	0xffe0000c /* read only register 32 bit */
+#define DATA_FAULT_ADDR		WORD_REF(DATA_FAULT_ADDR_ADDR)
+
+		/* These are total sixtenn */
+		
+#define DCPLB_ADDR_ADDR		0xffe00100 /* read/write register 32 bit */
+#define DCPLB_ADDR		WORD_REF(DCPLB_ADDR_ADDR)
+
+		/* These are total sixtenn */
+		
+#define DCPLB_DATA_ADDR		0xffe00200 /* read/write register 32 bit */
+#define DCPLB_DATA		WORD_REF(DCPLB_DATA_ADDR)
+
+
+		/* These are total 4 */
+
+#define DTEST_DATA_ADDR		0xffe00400 /* read/write register 32 bit */
+#define DTEST_DATA		WORD_REF(DTEST_DATA_ADDR)
+
+/****************************
+ *
+ *  L1 CODE MEMORY CONTROLLER REGISTERS  (0XFFE01004 - 0XFFE1404)
+ *
+ ****************************/
+
+#define CODE_FAULT_STATUS_ADDR	0xffe01008 /* read only register 32 bit */
+#define CODE_FAULT_STATUS	WORD_REF(CODE_FAULT_STATUS_ADDR)
+#define CODE_FAULT_ADDR_ADDR	0xffe0100c /* read only register 32 bit */
+#define CODE_FAULT_ADDR		WORD_REF(CODE_FAULT_ADDR_ADDR)
+
+		/* These are total sixtenn */
+		
+#define ICPLB_ADDR_ADDR		0xffe01100 /* read/write register 32 bit */
+#define ICPLB_ADDR		WORD_REF(ICPLB_ADDR_ADDR)
+
+		/* These are total sixtenn */
+		
+#define ICPLB_DATA_ADDR		0xffe01200 /* read/write register 32 bit */
+#define ICPLB_DATA		WORD_REF(ICPLB_DATA_ADDR)
+
+
+		/* These are total 4 */
+
+#define ITEST_DATA_ADDR		0xffe01400 /* read/write register 32 bit */
+#define ITEST_DATA		WORD_REF(ITEST_DATA_ADDR)
+
+/****************************
+ *
+ *  INTERRUPT CONTROLLER REGISTERS  (0XFFE02000 - 0XFFE0210C)
+ *
+ ****************************/
+
+ /*   EVENT VECTOR TABLE IS USED FOR 16 INTERRUPTS AS SHOWN BELOW
+      ALSO THEIR PRIORITY SEQUENCE IS ALSO GIVEN HERE
+      1		EMULATION		HIGHEST
+      2		RESET
+      3		NMI
+      4		EXCEPTION
+      5		INTERRUPTS		LOWEST */
+
+/*  Used with JTAG register 32 bit */
+#define EVT_EMULATION_ADDR	0xffe02000 
+#define EVT_EMULATION		WORD_REF(EVT_EMULATION_ADDR)
+/*  register 32 bit */
+#define EVT_RESET_ADDR		0xffe02004 
+#define EVT_RESET		WORD_REF(EVT_RESET_ADDR)
+/*  NMI register 32 bit */
+#define EVT_NMI_ADDR		0xffe02008 
+#define EVT_NMI			WORD_REF(EVT_NMI_ADDR)
+/*  Identification with code in EXCAUSE register 32 bit */
+#define EVT_EXCEPTION_ADDR	0xffe0200c 
+#define EVT_EXCEPTION		WORD_REF(EVT_EXCEPTION_ADDR)
+/*  Global interrupt enable register 32 bit */
+#define EVT_GLOBAL_INT_ENB_ADDR	0xffe02010 
+#define EVT_GLOBAL_INT_ENB	WORD_REF(EVT_GLOBAL_INT_ENB_ADDR)
+/*  Active while error condition exsists register 32 bit */
+#define EVT_HARDWARE_ERROR_ADDR	0xffe02014 
+#define EVT_HARDWARE_ERROR	WORD_REF(EVT_HARDWARE_ERROR_ADDR)
+/*  High priority timer register 32 bit */
+#define EVT_TIMER_ADDR		0xffe02018 
+#define EVT_TIMER		WORD_REF(EVT_TIMER_ADDR)
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG7_ADDR		0xffe0201c 
+#define EVT_IVG7		WORD_REF(EVT_IVG7_ADDR)
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG8_ADDR		0xffe02020 
+#define EVT_IVG8		WORD_REF(EVT_IVG8_ADDR)
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG9_ADDR		0xffe02024 
+#define EVT_IVG9		WORD_REF(EVT_IVG9_ADDR)
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG10_ADDR		0xffe02028 
+#define EVT_IVG10		WORD_REF(EVT_IVG10_ADDR)
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG11_ADDR		0xffe0202c 
+#define EVT_IVG11		WORD_REF(EVT_IVG11_ADDR)
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG12_ADDR		0xffe02030 
+#define EVT_IVG12		WORD_REF(EVT_IVG12_ADDR)
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG13_ADDR		0xffe02034 
+#define EVT_IVG13		WORD_REF(EVT_IVG13_ADDR)
+
+/* IVG14 & IVG15 should be used as software interrupts  */
+
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG14_ADDR		0xffe02038 
+#define EVT_IVG14		WORD_REF(EVT_IVG14_ADDR)
+/*  General purpose interrupt register 32 bit */
+#define EVT_IVG15_ADDR		0xffe0203c 
+#define EVT_IVG15		WORD_REF(EVT_IVG15_ADDR)
+
+#define EVT_OVERRIDE_ADDR	0xffe02100 /*  register 32 bit */
+#define EVT_OVERRIDE		WORD_REF(EVT_OVERRIDE_ADDR)
+#define IMASK_ADDR		0xffe02104 /*  register 32 bit */
+#define IMASK			WORD_REF(IMASK_ADDR)
+#define IPEND_ADDR		0xffe02108 /*  register 32 bit */
+#define IPEND			WORD_REF(IPEND_ADDR)
+#define ILAT_ADDR		0xffe0210c /*  register 32 bit */
+#define ILAT			WORD_REF(ILAT_ADDR)
+
+/****************************
+ *
+ *  TIMER REGISTERS  (0XFFC03000 - 0XFFC0300C)
+ *
+ ****************************/
+
+#define TCNTL_ADDR		0xffe03000 /*  register 32 bit */
+#define TCNTL			WORD_REF(TCNTL_ADDR)
+#define TPERIOD_ADDR		0xffe03004 /*  register 32 bit */
+#define TPERIOD			WORD_REF(TPERIOD_ADDR)
+#define TSCALE_ADDR		0xffe03008 /*  register 32 bit */
+#define TSCALE			WORD_REF(TSCALE_ADDR)
+#define TCOUNT_ADDR		0xffe0300c /*  register 32 bit */
+#define TCOUNT			WORD_REF(TCOUNT_ADDR)
+
+/****************************
+ *
+ *  DEBUG & EMULATION UNIT REGISTERS  (0XFFC05000 - 0XFFC0500C)
+ *
+ ****************************/
+
+#define DSPID_ADDR		0xffe05000 /*  register 32 bit */
+#define DSPID			WORD_REF(DSPID_ADDR)
+#define DBGSTAT_ADDR		0xffe05008 /*  register 32 bit */
+#define DBGSTAT			WORD_REF(DBGSTAT_ADDR)
+#define EMUDAT_ADDR		0xffe0500c /*  register 32 bit */
+#define EMUDAT			WORD_REF(EMUDAT_ADDR)
+
+/****************************
+ *
+ *  TRACE UNIT REGISTERS  (0XFFC06000 - 0XFFC06100)
+ *
+ ****************************/
+
+#define TBUFCTL_ADDR		0xffe06000 /*  register 32 bit */
+#define TBUFCTL			WORD_REF(TBUFCTL_ADDR)
+#define TBUFSTAT_ADDR		0xffe06004 /*  register 32 bit */
+#define TBUFSTAT		WORD_REF(TBUFSTAT_ADDR)
+#define TBUF_ADDR		0xffe06100 /*  register 32 bit */
+#define TBUF			WORD_REF(TBUF_ADDR)
+
+/****************************
+ *
+ *  WATCHPOINT & PATCH UNIT REGISTERS  (0XFFC07000 - 0XFFC07200)
+ *
+ ****************************/
+
+#define WPIACTL_ADDR		0xffe07000 /*  register 32 bit */
+#define WPIACTL			WORD_REF(WPIACTL_ADDR)
+		/* TOTAL OF 6  */
+#define WPIA_ADDR		0xffe07040 /*  register 32 bit */
+#define WPIA			WORD_REF(WPIA_ADDR)
+		/* TOTAL OF 6  */
+#define WPIACNT_ADDR		0xffe07080 /*  register 32 bit */
+#define WPIACNT			WORD_REF(WPIACNT_ADDR)
+
+#define WPDACTL_ADDR		0xffe07100 /*  register 32 bit */
+#define WPDACTL			WORD_REF(WPDACTL_ADDR)
+		/* TOTAL OF 2 */
+#define WPDA_ADDR		0xffe07140 /*  register 32 bit */
+#define WPDA			WORD_REF(WPDA_ADDR)
+		/* TOTAL OF 2 */
+#define WPDACNT_ADDR		0xffe07180 /*  register 32 bit */
+#define WPDACNT			WORD_REF(WPDACNT_ADDR)
+
+#define WPSTAT_ADDR		0xffe07200 /*  register 32 bit */
+#define WPSTAT			WORD_REF(WPSTAT_ADDR)
+
+/****************************
+ *
+ *  PERFORMANCE MONITOR REGISTERS  (0XFFC08000 - 0XFFC08104)
+ *
+ ****************************/
+
+#define PFCTL_ADDR		0xffe08000 /*  register 32 bit */
+#define PFCTL			WORD_REF(PFCTL_ADDR)
+		/* TOTAL OF 2 */
+#define PFCNTR_ADDR		0xffe08100 /*  register 32 bit */
+#define PFCNTR			WORD_REF(PFCNTR_ADDR)
+
+/***************************
+ *
+ * SYSTEM INTERRUPT CONTROLLER REGISTERS
+ *
+ ***************************/
+#define SIC_ISR_ADDR		0xffc00c14 /*  register 32 bit */
+#define SIC_ISR			WORD_REF(SIC_ISR_ADDR)
+
+#define SIC_IWR_ADDR		0xffc00c18 /*  register 32 bit */
+#define SIC_IWR			WORD_REF(SIC_IWR_ADDR)
+
+#define SIC_MASK_ADDR		0xffc00c10 /*  register 32 bit */
+#define SIC_MASK		WORD_REF(SIC_MASK_ADDR)
+
+#define SIC_RVECT_ADDR		0xffc00c00 /*  register 16 bit */
+#define SIC_RVECT		HALFWORD_REF(SIC_RVECT_ADDR)
+
+#define SIC_MASK_ALL		0x80000000
+
+#endif  /* _BLKFin_H_  */
diff -urN linux-2.4.29/include/asm-blackfin/board/bf535_irq.h linux-2.4.29-uc1/include/asm-blackfin/board/bf535_irq.h
--- linux-2.4.29/include/asm-blackfin/board/bf535_irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/board/bf535_irq.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,112 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/irq.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Changed by HuTao Apr18, 2003
+ *
+ * Copyright was missing when I got the code so took from MIPS arch ...MaTed---
+ * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle
+ * Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001 by Ralf Baechle
+ *
+ * Adapted for BlackFin (ADI) by Ted Ma <mated@sympatico.ca>
+ * Copyright (c) 2002 Arcturus Networks Inc. (www.arcturusnetworks.com)
+ * Copyright (c) 2002 Lineo, Inc. <mattw@lineo.com>
+ */
+
+#ifndef _BF535_IRQ_H_
+#define _BF535_IRQ_H_
+
+/*
+ * Interrupt source definitions
+             Event Source    Core Event Name
+Core        Emulation               **
+ Events         (highest priority)  EMU         0
+            Reset                   RST         1
+            NMI                     NMI         2
+            Exception               EVX         3
+            Reserved                --          4
+            Hardware Error          IVHW        5
+            Core Timer              IVTMR       6 *
+            System RTC              IVG7        7
+            Interrupts USB Rx/Tx    IVG7        8
+            ** SPARE **             --          9
+            PCI                     IVG7        10
+            SPORT0 RX/TX            IVG8        11
+            ** SPARE **             --          12
+            SPORT1 RX/TX            IVG8        13
+            ** SPARE **             --          14
+            SPI0 RX/TX              IVG9        15
+            ** SPARE **             --          16
+            SPI1 RX/TX              IVG9        17
+            ** SPARE **             --          18
+            UART0 RX/TX             IVG10       19
+            **SPARE **              --          20
+            UART1 RX/TX             IVG10       21
+            ** SPARE **             --          22
+            Timer0                  IVG11       23
+            Timer1                  IVG11       24
+            Timer2                  IVG11       25
+            ** SPARE **                         26
+            Programmable Flags      **
+                    Interrupt A     IVG12       27 (all 8)
+                    Interrupt B     IVG12       28 (all 8)
+            Memory DMA              --          29
+            Watchdog Timer          IVG13       30
+            Software Interrupt 1    IVG14       31
+            Software Interrupt 2    --
+                 (lowest priority)  IVG15       32 *
+ */
+/* The ABSTRACT IRQ definitions */
+/** the first seven of the following are fixed, the rest you change if you need to **/
+#define	IRQ_EMU			0	// Emulation
+#define	IRQ_RST			1	// reset
+#define	IRQ_NMI			2	// Non Maskable
+#define	IRQ_EVX			3	// Exception
+#define	IRQ_UNUSED		4	//  - unused interrupt
+#define	IRQ_HWERR		5	// Hardware Error
+#define	IRQ_CORETMR		6	// Core timer
+#define	IRQ_RTC			7	// Real Time Clock		
+#define	IRQ_USB			8	// Universal Serial Bus
+#define	IRQ_SPARE1		9	//  Spare ?? USB
+#define IRQ_PCI_INTA		9	// PCI INTA
+
+// Exchanged with IRQ_UART1. HuTao Apr18 2003
+#define	IRQ_PCI			10 	// Personal Computer Interface ??
+#define	IRQ_SPORT0		11	// Synchronous Serial Port 0
+#define	IRQ_SPARE2		12	//  Spare ?? split SPORT0
+#define IRQ_PCI_INTB		12	// PCI INTB
+
+#define	IRQ_SPORT1		13	// Synchronous Serial Port 1
+#define	IRQ_SPARE3		14	//  Spare ?? split SPORT1
+#define IRQ_PCI_INTC		14
+
+#define	IRQ_SPI0		15	// Serial Peripheral Interface 0
+#define	IRQ_SPARE4		16	//  Spare 
+#define IRQ_PCI_INTD		16
+
+#define	IRQ_SPI1		17	// Serial Peripheral Interface 1
+#define	IRQ_SPARE5		18	//  Spare
+#define	IRQ_UART0		19	// UART 0
+#define	IRQ_SPARE6		20	//  Spare
+
+// Changed to make UART driver work. HuTao Apr18 2003
+#define	IRQ_UART1		21 	// UART 1
+
+#define	IRQ_SPARE7		22	//  Spare
+#define	IRQ_TMR0		23	// Timer 0
+#define	IRQ_TMR1		24	// Timer 1
+#define	IRQ_TMR2		25	// Timer 2
+#define	IRQ_SPARE8		26	//  Spare
+#define	IRQ_PROG_INTA		27	// Programmable Flags A (8)
+#define	IRQ_PROG_INTB		28	// Programmable Flags B (8)
+#define	IRQ_MEM_DMA		29	// Memory DMA Xfer Comp
+#define	IRQ_WATCH	   	30	// Watch Dog Timer
+#define	IRQ_SW_INT1		31	// Software Int 1
+#define	IRQ_SW_INT2		32	// Software Int 2 (reserved for SYSCALL)
+
+#define SYS_IRQS		33	// Number of interrupt levels the kernel sees.
+
+#endif /* _BF535_IRQ_H_ */
diff -urN linux-2.4.29/include/asm-blackfin/board/bf535_serial.h linux-2.4.29-uc1/include/asm-blackfin/board/bf535_serial.h
--- linux-2.4.29/include/asm-blackfin/board/bf535_serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/board/bf535_serial.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,84 @@
+/* 
+ *  ADI uart macro definition :
+ *     UART 0 CONTROLLER REGISTERS  (0XFFC01800 - 0XFFC01BFF)
+ *     UART 1 CONTROLLER REGISTERS  (0XFFC01C00 - 0XFFC01FFF)
+ */
+#ifndef _BF535_SERIAL_H_
+#define _BF535_SERIAL_H_
+
+#define UART0_THR_ADDR		0xffc01800  /* UART 0 Transmit holding register
+					       16 bit */
+#define UART_THR(idx)		HALFWORD_REF((UART0_THR_ADDR | (idx << 10)))
+
+
+#define UART0_RBR_ADDR		0xffc01800  /* UART 0 Receive buffer register  
+					     16 bit */
+#define UART_RBR(idx)		HALFWORD_REF((UART0_RBR_ADDR | (idx << 10)))
+
+#define UART0_DLL_ADDR		0xffc01800  /* UART 0 Divisor latch (low byte) 
+					       register  16 bit */
+#define UART_DLL(idx)		HALFWORD_REF((UART0_DLL_ADDR | (idx << 10)))
+
+#define UART0_IER_ADDR		0xffc01802  /* UART 0 Interrupt enable register  16 bit */
+#define UART_IER(idx)		HALFWORD_REF((UART0_IER_ADDR | (idx << 10)))
+#define UART_IER_ERBFI		0x01    /* Enable Receive Buffer Full Interrupt
+					   (DR bit) */
+#define UART_IER_ETBEI		0x02    /* Enable Transmit Buffer Empty 
+					   Interrupt(THRE bit) */
+#define UART_IER_ELSI		0x04    /* Enable RX Status Interrupt
+					   (gen if any of LSR[4:1] set) */
+#define UART_IER_EDDSI		0x08    /* Enable Modem Status Interrupt(gen if any UARTx_MSR[3:0] set) */
+
+#define UART0_DLH_ADDR		0xffc01802  /* UART 0 Divisor latch (high byte) register  16 bit */
+#define UART_DLH(idx)		HALFWORD_REF((UART0_DLH_ADDR | (idx << 10)))
+#define UART0_IIR_ADDR		0xffc01804  /* UART 0 Interrupt identification register  16 bit */
+#define UART_IIR(idx)		HALFWORD_REF((UART0_IIR_ADDR | (idx << 10)))
+#define UART_IIR_NOINT		0x01    /* Bit0: cleared when no interrupt */
+#define UART_IIR_STATUS		0x06    /* mask bit for the status: bit2-1 */
+#define UART_IIR_LSR		0x06    /* Receive line status */
+#define UART_IIR_RBR		0x04    /* Receive data ready */
+#define UART_IIR_THR		0x02    /* Ready to transmit  */
+#define UART_IIR_MSR		0x00    /* Modem status       */
+
+#define UART0_LCR_ADDR          0xffc01806  /* UART 0 Line control register  16 bit */
+#define UART_LCR(idx)           HALFWORD_REF((UART0_LCR_ADDR | (idx << 10)))
+#define UART_LCR_WLS5           0       /* word length 5 bits */
+#define UART_LCR_WLS6           0x01    /* word length 6 bits */
+#define UART_LCR_WLS7           0x02    /* word length 7 bits */
+#define UART_LCR_WLS8           0x03    /* word length 8 bits */
+#define UART_LCR_STB            0x04    /* StopBit: 1: 2 stop bits for 
+					   non-5-bit word length 1/2 stop bits 
+					   for 5-bit word length 0: 
+					   1 stop bit */
+#define UART_LCR_PEN            0x08    /* Parity Enable 1: for enable */
+#define UART_LCR_EPS            0x10    /* Parity Selection: 
+					   1: for even pariety
+                                           0: odd parity when PEN =1 & SP =0 */
+#define UART_LCR_SP             0x20    /* Sticky Parity: */
+#define UART_LCR_SB             0x40    /* Set Break: force TX pin to 0 */
+#define UART_LCR_DLAB           0x80    /* Divisor Latch Access */
+
+
+#define UART0_MCR_ADDR          0xffc01808  /* UART 0 Module Control register  
+					       16 bit */
+#define UART_MCR(idx)           HALFWORD_REF((UART0_MCR_ADDR | (idx << 10)))
+
+#define UART0_LSR_ADDR          0xffc0180a  /* UART 0 Line status register  
+					       16 bit */
+#define UART_LSR(idx)           HALFWORD_REF((UART0_LSR_ADDR | (idx << 10)))
+#define UART_LSR_DR             0x01    /* Data Ready */
+#define UART_LSR_OE             0x02    /* Overrun Error */
+#define UART_LSR_PE             0x04    /* Parity Error  */
+#define UART_LSR_FE             0x08    /* Frame Error   */
+#define UART_LSR_BI             0x10    /* Break Interrupt */
+#define UART_LSR_THRE           0x20    /* THR empty, REady to accept */
+#define UART_LSR_TEMT           0x40    /* TSR and UARTx_thr both empty */
+
+#define UART0_MSR_ADDR          0xffc0180c  /* UART 0 Modem status register  16 bit */
+#define UART_MSR(idx)           HALFWORD_REF((UART0_MSR_ADDR | (idx << 10)))
+#define UART0_SCR_ADDR          0xffc0180e  /* UART 0 Scratch register  16 bit */
+#define UART_SCR(idx)           HALFWORD_REF((UART0_SCR_ADDR | (idx << 10)))
+#define UART0_IRCR_ADDR         0xffc01810  /* UART 0 IrDA Control register  16 bit */
+#define UART_IRCR(idx)          HALFWORD_REF((UART0_IRCR_ADDR | (idx << 10)))
+
+#endif /* _BF535_SERIAL_H_ */
diff -urN linux-2.4.29/include/asm-blackfin/board/eagle.h linux-2.4.29-uc1/include/asm-blackfin/board/eagle.h
--- linux-2.4.29/include/asm-blackfin/board/eagle.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/board/eagle.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,4 @@
+#ifndef _EAGLE_H_
+#define _EAGLE_H_
+#include <asm/board/bf535.h>
+#endif /* _EAGLE_H_ */
diff -urN linux-2.4.29/include/asm-blackfin/board/ezkit.h linux-2.4.29-uc1/include/asm-blackfin/board/ezkit.h
--- linux-2.4.29/include/asm-blackfin/board/ezkit.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/board/ezkit.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,5 @@
+#ifndef _EZKIT_H_
+#define _EZKIT_H_
+#include <asm/board/bf533.h>
+#include <asm/board/bf533_serial.h>
+#endif /* _EZKIT_H_ */
diff -urN linux-2.4.29/include/asm-blackfin/board/hawk.h linux-2.4.29-uc1/include/asm-blackfin/board/hawk.h
--- linux-2.4.29/include/asm-blackfin/board/hawk.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/board/hawk.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,4 @@
+#ifndef _HAWK_H_
+#define _HAWK_H_
+#include <asm/board/bf535.h>
+#endif /* _HAWK_H_ */
diff -urN linux-2.4.29/include/asm-blackfin/board/pub.h linux-2.4.29-uc1/include/asm-blackfin/board/pub.h
--- linux-2.4.29/include/asm-blackfin/board/pub.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/board/pub.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,19 @@
+#ifndef _PUB_H_
+#define _PUB_H_
+#include <asm/board/bf535.h>
+
+/*
+ * The PUB board uses the ADI21535 Rev0.2 silicon.
+ *
+ * According to ADI21535 Anomaly List (Dec3, 2002),
+ * the polarity of SIC_MASK reg in Rev0.2 silicon
+ * is inverted. Value '1' will disable interrupt
+ * while '0' will enable interrupt.
+ *
+ * HuTao, Jun 20 2003, 5:50PM
+ */
+#undef SIC_MASK_ALL
+#define SIC_MASK_ALL	(~0x80000000)
+
+#endif
+
diff -urN linux-2.4.29/include/asm-blackfin/bootinfo.h linux-2.4.29-uc1/include/asm-blackfin/bootinfo.h
--- linux-2.4.29/include/asm-blackfin/bootinfo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/bootinfo.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1 @@
+/* Nothing for frionommu */
diff -urN linux-2.4.29/include/asm-blackfin/bugs.h linux-2.4.29-uc1/include/asm-blackfin/bugs.h
--- linux-2.4.29/include/asm-blackfin/bugs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/bugs.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,15 @@
+/*
+ *  include/asm-frionommu/bugs.h
+ *
+ *  Copyright (C) 1994  Linus Torvalds
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *	void check_bugs(void);
+ */
+
+static void check_bugs(void)
+{}
diff -urN linux-2.4.29/include/asm-blackfin/byteorder.h linux-2.4.29-uc1/include/asm-blackfin/byteorder.h
--- linux-2.4.29/include/asm-blackfin/byteorder.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/byteorder.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,14 @@
+#ifndef _FRIONOMMU_BYTEORDER_H
+#define _FRIONOMMU_BYTEORDER_H
+
+#include <asm/types.h>
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#include <linux/byteorder/little_endian.h>
+
+#endif /* _FRIONOMMU_BYTEORDER_H */
+
diff -urN linux-2.4.29/include/asm-blackfin/cachectl.h linux-2.4.29-uc1/include/asm-blackfin/cachectl.h
--- linux-2.4.29/include/asm-blackfin/cachectl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/cachectl.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,14 @@
+#ifndef _FRIO_CACHECTL_H
+#define _FRIO_CACHECTL_H
+
+/* Definitions for the cacheflush system call.  */
+
+#define FLUSH_SCOPE_LINE    1	/* Flush a cache line */
+#define FLUSH_SCOPE_PAGE    2	/* Flush a page */
+#define FLUSH_SCOPE_ALL     3	/* Flush the whole cache -- superuser only */
+
+#define FLUSH_CACHE_DATA    1	/* Writeback and flush data cache */
+#define FLUSH_CACHE_INSN    2	/* Flush instruction cache */
+#define FLUSH_CACHE_BOTH    3	/* Flush both caches */
+
+#endif /* _FRIO_CACHECTL_H */
diff -urN linux-2.4.29/include/asm-blackfin/cache.h linux-2.4.29-uc1/include/asm-blackfin/cache.h
--- linux-2.4.29/include/asm-blackfin/cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/cache.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef __ARCH_FRIONOMMU_CACHE_H
+#define __ARCH_FRIONOMMU_CACHE_H
+
+/* bytes per L1 cache line */
+#define        L1_CACHE_BYTES  32	/* BlackFin loads 32 bytes for cache */
+
+// For speed we do need to align these ...MaTed---
+//  But include/linux/cache.h does this for us if we DO not define ...MaTed---
+#define __cacheline_aligned	/***** maybe no need this   Tony *****/
+// We don't set  
+#define ____cacheline_aligned
+
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/checksum.h linux-2.4.29-uc1/include/asm-blackfin/checksum.h
--- linux-2.4.29/include/asm-blackfin/checksum.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/checksum.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,122 @@
+#ifndef _FRIO_CHECKSUM_H
+#define _FRIO_CHECKSUM_H
+
+/*
+ * MODIFIED FOR FRIO April 30, 2001 akbar.hussain@lineo.com
+ *
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
+
+
+/*
+ * the same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
+						int len, int sum, int *csum_err);
+
+#define csum_partial_copy_nocheck(src, dst, len, sum)	\
+	csum_partial_copy((src), (dst), (len), (sum))
+
+unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl);
+
+
+/*
+ *	Fold a partial checksum
+ */
+
+static inline unsigned int csum_fold(unsigned int sum)
+{
+	sum = (sum & 0xffff) + (sum >> 16);
+	sum = (sum & 0xffff) + (sum >> 16);
+	return ~sum;
+}
+
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+
+static inline unsigned int
+csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
+		  unsigned short proto, unsigned int sum)
+{
+	__asm__ ("%0 = %0 + %1;\n\t"
+		 "%0 = %0 + %2;\n\t"
+		 "%0 = %0 + %3;\n\t"
+		 : "=d" (sum)
+		 : "d" (daddr), "d" (saddr), "d" ((ntohs(len)<<16)+proto*256), "0"(sum));
+	return sum;
+}
+
+static inline unsigned short int
+csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
+		  unsigned short proto, unsigned int sum)
+{
+	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+extern unsigned short ip_compute_csum(const unsigned char * buff, int len);
+
+#define _HAVE_ARCH_IPV6_CSUM
+static __inline__ unsigned short int
+csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr,
+		__u32 len, unsigned short proto, unsigned int sum) 
+{
+	register unsigned long tmp;
+	__asm__("R3 = [%2]; %0 = %0 + R3;\n\t"	/*"addl %2@,%0\n\t"*/
+		"%1 = [%2+4];\n\t"		/* "movel %2@(4),%1\n\t"*/
+		"%0 = %0 + %1; R3 = CC; %0 = %0 + R3;\n\t"	/*"addxl %1,%0\n\t"*/
+		"%1 = [%2+8];\n\t"		/* "movel %2@(8),%1\n\t" */
+		"%0 = %0 + %1; R3 = CC; %0 = %0 + R3;\n\t"	/*"addxl %1,%0\n\t"*/
+		"%1 = [%2+12];\n\t"		/* "movel %2@(12),%1\n\t" */
+		"%0 = %0 + %1; R3 = CC; %0 = %0 + R3;\n\t"	/*"addxl %1,%0\n\t" */
+		"%1 = [%3];\n\t"		/* "movel %3@,%1\n\t" */
+		"%0 = %0 + %1; R3 = CC; %0 = %0 + R3;\n\t"	/*"addxl %1,%0\n\t" */
+		"%1 = [%3+4];\n\t"		/* movel %3@(4),%1\n\t"*/
+		"%0 = %0 + %1; R3 = CC; %0 = %0 + R3;\n\t"	/*"addxl %1,%0\n\t" */
+		"%1 = [%3+8];\n\t"		/* "movel %3@(8),%1\n\t"*/
+		"%0 = %0 + %1; R3 = CC; %0 = %0 + R3;\n\t"	/*"addxl %1,%0\n\t" */
+		"%1 = [%3+12];\n\t"		/* "movel %3@(12),%1\n\t" */
+		"%0 = %0 + %1; R3 = CC; %0 = %0 + R3;\n\t"	/*"addxl %1,%0\n\t" */
+		"%0 = %0 + %4; R3 = CC; %0 = %0 + R3;\n\t"	/*"addxl %4,%0\n\t" */
+		"%1 = 0;\n\t"			/* "clrl %1\n\t" */
+		"%0 = %0 + %1; R3 = CC; %0 = %0 + R3;\n\t"	/*"addxl %1,%0"  */
+		: "=&d" (sum), "=&d" (tmp)
+		: "a" (saddr), "a" (daddr), "d" (len + proto),
+		  "0" (sum)
+		: "R3");
+
+	return csum_fold(sum);
+}
+
+#endif /* _FRIO_CHECKSUM_H */
diff -urN linux-2.4.29/include/asm-blackfin/current.h linux-2.4.29-uc1/include/asm-blackfin/current.h
--- linux-2.4.29/include/asm-blackfin/current.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/current.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,16 @@
+#ifndef _FRIONOMMU_CURRENT_H
+#define _FRIONOMMU_CURRENT_H
+/*
+ *	current.h
+ *	(C) Copyright 2000, Lineo, David McCullough <davidm@lineo.com>
+ *
+ *	rather than dedicate a register (as the m68k source does), we
+ *	just keep a global,  we should probably just change it all to be
+ *	current and lose _current_task.
+ */
+
+extern struct task_struct *_current_task;
+#define get_current()	_current_task
+#define current _current_task
+
+#endif /* _FRIONOMMU_CURRENT_H */
diff -urN linux-2.4.29/include/asm-blackfin/delay.h linux-2.4.29-uc1/include/asm-blackfin/delay.h
--- linux-2.4.29/include/asm-blackfin/delay.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/delay.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,34 @@
+#ifndef _FRIONOMMU_DELAY_H
+#define _FRIONOMMU_DELAY_H
+
+/*
+ * Changes made by akbar.hussain@Lineo.com, for FRIO
+ * Copyright (C) 1994 Hamish Macdonald
+ *
+ * Delay routines, using a pre-computed "loops_per_second" value.
+ */
+
+extern __inline__ void __delay(unsigned long loops)
+{
+	__asm__ __volatile__ (	"1:\t%0 += -1;\n\t"
+				"cc = %0 == 0;\n\t"
+				"if ! cc jump 1b;\n"
+				: "=d" (loops) 
+				: "0" (loops));
+}
+
+/*
+ * Use only for very small delays ( < 1 msec).  Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays.  This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)  
+ */
+extern __inline__ void udelay(unsigned long usecs)
+{
+
+	__delay(usecs);
+}
+
+
+#endif /* defined(_FRIONOMMU_DELAY_H) */
diff -urN linux-2.4.29/include/asm-blackfin/div64.h linux-2.4.29-uc1/include/asm-blackfin/div64.h
--- linux-2.4.29/include/asm-blackfin/div64.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/div64.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef _FRIONOMMU_DIV64_H
+#define _FRIONOMMU_DIV64_H
+
+/* n = n / base; return rem; */
+
+#define do_div(n,base) ({					\
+	int __res;						\
+	__res = ((unsigned long) n) % (unsigned) base;		\
+	n = ((unsigned long) n) / (unsigned) base;		\
+	__res;							\
+})
+
+#endif /* _FRIO_DIV64_H */
diff -urN linux-2.4.29/include/asm-blackfin/dma.h linux-2.4.29-uc1/include/asm-blackfin/dma.h
--- linux-2.4.29/include/asm-blackfin/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/dma.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,92 @@
+/*
+ * include/asm-frionommu/dma.h
+ * Data structures and register support for DMA on Blackfin ADSP-21535.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * or (at your option) any later version as  published by the Free Software 
+ * Foundation.
+ *
+ */
+
+#ifndef _FRIONOMMU_DMA_H
+#define _FRIONOMMU_DMA_H 1
+
+#include <linux/config.h>
+#include <linux/mm.h>  // Included for memory management
+#include <asm/blackfin.h>
+#include <asm/memdma.h>
+/* it's useless on the m68k, but unfortunately needed by the new
+   bootmem allocator (but this should do it for this) */
+#define MAX_DMA_ADDRESS PAGE_OFFSET
+
+/*#define MAX_DMA_CHANNELS 8 */
+/* Code may need to identify peripheral caller*/
+#define BYTE_REF(addr)		 (*((volatile unsigned char*)addr))
+#define HALFWORD_REF(addr) 	 (*((volatile unsigned short*)addr))
+#define WORD_REF(addr)		 (*((volatile unsigned long*)addr))
+#define MAX_DMA_CHANNELS        13
+/* The configuration word below will enable any DMA channel but will not be ready yet to transfer any data  DMA_CONFIGURATION_WORD 0x8005                           */
+/* System I/O mapping values */
+
+#define DMA_DBP_ADDR            0xffc04880 /* DMA Descriptor Base pointer register */
+#define DMA_DBP			HALFWORD_REF(DMA_DBP_ADDR)
+
+#define DMA_CONFIGURATION_WORD_ENABLE  0x0005  /*  Ownership still with processor Default granularity 8-bit check for options*/
+#define DMA_CONFIGURATION_WORD_DISABLE  0x0004  /* Ownership still with processor Must check for other options*/
+#define DMA_END_SEQUENCE	0x0000 /* The 15th bit must be 0*/
+#define DMA_START_SEQUENCE	0x8005 /* 15th bit 1 and def gran = 8 bit with channel enabled */
+#define DMA2_MASK_REG
+#define DESCRIPTOR_BLOCK_BASE_ADDRESS
+/* DMA Channel mappings */
+#define SPORT0_DMA_RCV		0
+#define SPORT1_DMA_RCV		1
+#define SPORT0_DMA_XMT		2
+#define SPORT1_DMA_XMT		3
+#define USB_DMA_CONTROL		4
+#define SPI0_DMA_CONTROL	5
+#define SPI1_DMA_CONTROL	6
+#define UART0_DMA_RCV		7
+#define UART1_DMA_RCV		8
+#define UART0_DMA_XMT		9
+#define UART1_DMA_XMT		10
+#define MEM_DMA_XMT		11
+#define MEM_DMA_RCV		12
+
+/* Descriptor LInked list structure
+*/
+typedef struct _dma_descriptor_block
+{
+ unsigned short configuration_word; /* BASE + 0 */
+ unsigned short transfer_count;     /* BASE + 2 */
+ unsigned short start_addr_lsb;     /* BASE + 4 */
+ unsigned short start_addr_msb;     /* BASE + 6 */
+ unsigned short next_descriptor;     /* BASE + 8 */
+}dma_descriptor_block;
+
+typedef struct _dma_channel_struct
+{
+ const char* device_id;
+ unsigned int dma_intr;
+ unsigned int lock;
+ dma_descriptor_block descriptor;    //Defined for standalone sequence only   
+}dma_channel;
+
+
+/* Bits in the configuration word */
+#define DMA_ENABLE	0x0001
+#define DMA_DIRECTION	
+#define DMA_INTR_COMPLETE	0x0004
+#define DMA_BUFFER_CLEAR	(0x0080 ^ 0x0080) /* must be zero in configuration word */
+#define DMA_CONPLETION_ERROR	0x4000
+#define DMA_DESCRIPTOR_OWNER	0x8000
+#define DMA_MODE_WRITE		0x0002
+#define DMA_MODE_READ		0x0000
+#define DATA_SIZE_8_BIT		0x1008
+#define DATA_SIZE_16_BIT	
+#define DATA_SIZE_32_BIT	
+extern spinlock_t  dma_spin_lock;
+
+
+#endif /* _FRIONOMMU_DMA_H */
+
diff -urN linux-2.4.29/include/asm-blackfin/elf.h linux-2.4.29-uc1/include/asm-blackfin/elf.h
--- linux-2.4.29/include/asm-blackfin/elf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/elf.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,68 @@
+/* Changes made by Tony Kou    Lineo  Inc.  May 2001	*/
+
+#ifndef __ASMFRIO_ELF_H
+#define __ASMFRIO_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <linux/config.h>
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == EM_FRIO)
+
+/* EM_FRIO defined in linux/elf.h	*/
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2LSB
+#define ELF_ARCH	EM_FRIO
+
+/* For SVR4/m68k the function pointer to be registered with `atexit' is
+   passed in %a1.  Although my copy of the ABI has no such statement, it
+   is actually used on ASV.  */
+#define ELF_PLAT_INIT(_r)	_r->p1 = 0	/*   ???    tonyko */
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	4096
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#define ELF_ET_DYN_BASE         0xD0000000UL
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs)	\
+        memcpy((char *) &pr_reg, (char *)regs,  \
+               sizeof(struct pt_regs));
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.  */
+
+#define ELF_PLATFORM  (NULL)
+
+#ifdef __KERNEL__
+#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/entry.h linux-2.4.29-uc1/include/asm-blackfin/entry.h
--- linux-2.4.29/include/asm-blackfin/entry.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/entry.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,393 @@
+#ifndef __FRIO_ENTRY_H
+#define __FRIO_ENTRY_H
+
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+
+/*
+ * Stack layout in 'ret_from_exception':
+ *
+ */
+
+/*
+ * Register %p2 is now set to the current task throughout
+ * the whole kernel.
+ */
+
+#ifdef __ASSEMBLY__
+
+#define	LFLUSH_I_AND_D	0x00000808
+#define	LSIGTRAP	5
+
+/* process bits for task_struct.flags */
+#define	PF_TRACESYS_OFF	3
+#define	PF_TRACESYS_BIT	5
+#define	PF_PTRACED_OFF	3
+#define	PF_PTRACED_BIT	4
+#define	PF_DTRACE_OFF	1
+#define	PF_DTRACE_BIT	5
+
+#define NEW_PT_REGS
+
+#if defined(NEW_PT_REGS)
+
+# define SAVE_ALL_INT		save_context_no_interrupts
+# define SAVE_ALL_SYS		save_context_no_interrupts
+# define SAVE_CONTEXT		save_context_with_interrupts
+
+# define RESTORE_ALL		restore_context_no_interrupts
+# define RESTORE_ALL_SYS	restore_context_no_interrupts
+# define RESTORE_CONTEXT	restore_context_with_interrupts
+
+#else
+
+# define SAVE_ALL_INT		save_all_int
+# define SAVE_ALL_SYS		save_all_sys
+# define SAVE_CONTEXT		save_context
+
+# define RESTORE_ALL		restore_context
+# define RESTORE_CONTEXT	restore_context
+
+#endif
+
+/*
+ * Code to save processor context.
+ *  We even save the register which are preserved by a function call
+ *	 - r4, r5, r6, r7, p3, p4, p5
+ */
+.macro save_context_with_interrupts
+	[--sp] = R0;	// orig_r0
+	[--sp] = ( R7:0, P5:0 );
+	[--sp] = fp;
+	[--sp] = usp;
+
+	[--sp] = i0;
+	[--sp] = i1;
+	[--sp] = i2;
+	[--sp] = i3;
+
+	[--sp] = m0;
+	[--sp] = m1;
+	[--sp] = m2;
+	[--sp] = m3;
+
+	[--sp] = l0;
+	[--sp] = l1;
+	[--sp] = l2;
+	[--sp] = l3;
+
+	[--sp] = b0;
+	[--sp] = b1;
+	[--sp] = b2;
+	[--sp] = b3;
+	[--sp] = a0.x;
+	[--sp] = a0.w;
+	[--sp] = a1.x;
+	[--sp] = a1.w;
+
+	[--sp] = LC0;
+	[--sp] = LC1;
+	[--sp] = LT0;
+	[--sp] = LT1;
+	[--sp] = LB0;
+	[--sp] = LB1;
+
+	[--sp] = ASTAT;
+
+	[--sp] = r0;	/* Skip reserved */
+	[--sp] = RETS;
+	[--sp] = RETI;
+	[--sp] = RETX;
+	[--sp] = RETN;
+	[--sp] = RETE;
+	[--sp] = SEQSTAT;
+	[--sp] = SYSCFG;
+	[--sp] = r0;	/* Skip IPEND as well. */
+.endm
+
+.macro save_context_no_interrupts
+	[--sp] = R0;	// orig_r0
+	[--sp] = ( R7:0, P5:0 );
+	[--sp] = fp;
+	[--sp] = usp;
+
+	[--sp] = i0;
+	[--sp] = i1;
+	[--sp] = i2;
+	[--sp] = i3;
+
+	[--sp] = m0;
+	[--sp] = m1;
+	[--sp] = m2;
+	[--sp] = m3;
+
+	[--sp] = l0;
+	[--sp] = l1;
+	[--sp] = l2;
+	[--sp] = l3;
+
+	[--sp] = b0;
+	[--sp] = b1;
+	[--sp] = b2;
+	[--sp] = b3;
+	[--sp] = a0.x;
+	[--sp] = a0.w;
+	[--sp] = a1.x;
+	[--sp] = a1.w;
+
+	[--sp] = LC0;
+	[--sp] = LC1;
+	[--sp] = LT0;
+	[--sp] = LT1;
+	[--sp] = LB0;
+	[--sp] = LB1;
+
+	[--sp] = ASTAT;
+
+	[--sp] = r0;	/* Skip reserved */
+	[--sp] = RETS;
+	r0 = RETI;
+	[--sp] = r0;
+	[--sp] = RETX;
+	[--sp] = RETN;
+	[--sp] = RETE;
+	[--sp] = SEQSTAT;
+	[--sp] = SYSCFG;
+	[--sp] = r0;	/* Skip IPEND as well. */
+.endm
+	 
+.macro restore_context_no_interrupts
+	sp += 4;	// Skip IPEND
+	SYSCFG = [sp++];
+	SEQSTAT = [sp++];
+	RETE = [sp++];
+	RETN = [sp++];
+	RETX = [sp++];
+	r0 = [sp++];
+	RETI = r0;	// Restore RETI indirectly when in exception
+	RETS = [sp++];
+
+	sp += 4;	// Skip Reserved
+
+	ASTAT = [sp++];
+
+	LB1 = [sp++];
+	LB0 = [sp++];
+	LT1 = [sp++];
+	LT0 = [sp++];
+	LC1 = [sp++];
+	LC0 = [sp++];
+
+	a1.w = [sp++];
+	a1.x = [sp++];
+	a0.w = [sp++];
+	a0.x = [sp++];
+	b3 = [sp++];
+	b2 = [sp++];
+	b1 = [sp++];
+	b0 = [sp++];
+
+	l3 = [sp++];
+	l2 = [sp++];
+	l1 = [sp++];
+	l0 = [sp++];
+
+	m3 = [sp++];
+	m2 = [sp++];
+	m1 = [sp++];
+	m0 = [sp++];
+
+	i3 = [sp++];
+	i2 = [sp++];
+	i1 = [sp++];
+	i0 = [sp++];
+
+	/* Don't mess with USP unless we have to. Things break if we do. */
+	/* usp = [sp++]; */
+	sp += 4;
+	fp = [sp++];
+
+	( R7 : 0, P5 : 0) = [ SP ++ ];
+	sp += 4;	// Skip orig_r0
+.endm
+
+.macro restore_context_with_interrupts
+	sp += 4;	// Skip IPEND
+	SYSCFG = [sp++];
+	SEQSTAT = [sp++];
+	RETE = [sp++];
+	RETN = [sp++];
+	RETX = [sp++];
+	RETI = [sp++];
+	RETS = [sp++];
+
+	sp += 4;	// Skip Reserved
+
+	ASTAT = [sp++];
+
+	LB1 = [sp++];
+	LB0 = [sp++];
+	LT1 = [sp++];
+	LT0 = [sp++];
+	LC1 = [sp++];
+	LC0 = [sp++];
+
+	a1.w = [sp++];
+	a1.x = [sp++];
+	a0.w = [sp++];
+	a0.x = [sp++];
+	b3 = [sp++];
+	b2 = [sp++];
+	b1 = [sp++];
+	b0 = [sp++];
+
+	l3 = [sp++];
+	l2 = [sp++];
+	l1 = [sp++];
+	l0 = [sp++];
+
+	m3 = [sp++];
+	m2 = [sp++];
+	m1 = [sp++];
+	m0 = [sp++];
+
+	i3 = [sp++];
+	i2 = [sp++];
+	i1 = [sp++];
+	i0 = [sp++];
+
+	/* Don't mess with USP unless we have to. Things break if we do. */
+	/* usp = [sp++]; */
+	sp += 4;
+	fp = [sp++];
+
+	( R7 : 0, P5 : 0) = [ SP ++ ];
+	sp += 4;	// Skip orig_r0
+.endm
+/*
+ * regs a3-a6 and d6-d7 are preserved by C code
+ * the kernel doesn't mess with usp unless it needs to
+ */
+
+#if !defined(NEW_PT_REGS)
+/*
+ * a -1 in the orig_r0 field signifies
+ * that the stack frame is NOT for syscall
+ */
+.macro	save_all_int
+/* reserved and disable the single step of SYSCFG, by Steven Chen 03/07/10 */
+	[--sp] = r0;
+	r0.l = 0x30;	/* Errata for BF533 */
+	r0.h = 0x0;
+	syscfg = r0;	 /* disable single step flag in SYSCFG */
+	r0 = [sp++];
+	[--sp] = syscfg;	/* store SYSCFG */
+
+/********************************/
+/* Added by HuTao, May 26 2003 3:31PM */
+	[--sp] = r0;		/* Reserved for IPEND */	
+	[--sp] = fp;
+	[--sp] = usp;
+/*******************************/
+	[--sp] = r0;
+
+#if 0 /* HuTao, May 21, 2003 4:48 */
+	r0 = -1;
+#endif 
+	[--sp] = r0;
+	r0 = [sp + 8];
+	[--sp] = a0.x;
+	[--sp] = a1.x;
+	[--sp] = a0.w;
+	[--sp] = a1.w;
+	[--sp] = rets;
+	[--sp] = astat;
+	[--sp] = seqstat;
+	[--sp] = retx;	/* current pc when exception happens */
+	[--sp] = ( r7:5, p5:0 );
+	[--sp] = r1;
+	[--sp] = r2;
+	[--sp] = r4;
+	[--sp] = r3;
+
+
+/******************************
+	clrl	%sp@-		 stk_adj 
+	pea	-1:w		 orig d0 
+	movel	%d0,%sp@-	 d0 
+	moveml	%d1-%d5/%a0-%a1/%curptr,%sp@-
+******************************/
+.endm
+
+.macro	save_all_sys
+	[--sp] = r0;
+	[--sp] = r0;
+	[--sp] = a0.x;
+	[--sp] = a1.x;
+	[--sp] = a0.w;
+	[--sp] = a1.w;
+	[--sp] = rets;
+	[--sp] = astat;
+	[--sp] = seqstat;
+	[--sp] = retx;	/* current pc when exception happens */
+	[--sp] = ( r7:5, p5:0 );
+	[--sp] = r1;
+	[--sp] = r2;
+	[--sp] = r4;
+	[--sp] = r3;
+.endm
+
+.macro	restore_all
+	r3 = [sp++];
+	r4 = [sp++];
+	r2 = [sp++];
+	r1 = [sp++];
+	( r7:5, p5:0 ) = [sp++];
+	retx = [sp++];
+	seqstat = [sp++];
+	astat = [sp++];
+	rets = [sp++];
+	a1.w = [sp++];
+	a0.w = [sp++];
+	a1.x = [sp++];
+	a0.x = [sp++];
+	sp += 4;	/* orig r0 */
+	r0 = [sp++];
+	
+	/* usp = [sp++]; */
+	sp += 4;
+	fp = [sp++];
+	sp +=4;		/* Skip the IPEND */
+
+	syscfg = [sp++];
+
+/*******************************************************/
+
+.endm
+
+#endif
+
+#define STR(X) STR1(X)
+#define STR1(X) #X
+
+#if defined(NEW_PT_REGS)
+
+# define PT_OFF_ORIG_R0		208
+# define PT_OFF_SR		8
+
+#else
+
+# define PT_OFF_ORIG_R0	 0x54
+# define PT_OFF_SR	 0x38	/* seqstat in pt_regs	*/
+
+#endif
+#endif	/* __ASSEMBLY__	*/
+
+#endif	/* __FRIO_ENTRY_H */
+
+
+/**************************** garbage *************************
+
+#define GET_CURRENT(tmp)
+**************************************************************/
diff -urN linux-2.4.29/include/asm-blackfin/errno.h linux-2.4.29-uc1/include/asm-blackfin/errno.h
--- linux-2.4.29/include/asm-blackfin/errno.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/errno.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,132 @@
+#ifndef _FRIO_ERRNO_H
+#define _FRIO_ERRNO_H
+
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Arg list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	EDEADLK		35	/* Resource deadlock would occur */
+#define	ENAMETOOLONG	36	/* File name too long */
+#define	ENOLCK		37	/* No record locks available */
+#define	ENOSYS		38	/* Function not implemented */
+#define	ENOTEMPTY	39	/* Directory not empty */
+#define	ELOOP		40	/* Too many symbolic links encountered */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	ENOMSG		42	/* No message of desired type */
+#define	EIDRM		43	/* Identifier removed */
+#define	ECHRNG		44	/* Channel number out of range */
+#define	EL2NSYNC	45	/* Level 2 not synchronized */
+#define	EL3HLT		46	/* Level 3 halted */
+#define	EL3RST		47	/* Level 3 reset */
+#define	ELNRNG		48	/* Link number out of range */
+#define	EUNATCH		49	/* Protocol driver not attached */
+#define	ENOCSI		50	/* No CSI structure available */
+#define	EL2HLT		51	/* Level 2 halted */
+#define	EBADE		52	/* Invalid exchange */
+#define	EBADR		53	/* Invalid request descriptor */
+#define	EXFULL		54	/* Exchange full */
+#define	ENOANO		55	/* No anode */
+#define	EBADRQC		56	/* Invalid request code */
+#define	EBADSLT		57	/* Invalid slot */
+
+#define	EDEADLOCK	EDEADLK
+
+#define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
+#define	EMULTIHOP	72	/* Multihop attempted */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EBADMSG		74	/* Not a data message */
+#define	EOVERFLOW	75	/* Value too large for defined data type */
+#define	ENOTUNIQ	76	/* Name not unique on network */
+#define	EBADFD		77	/* File descriptor in bad state */
+#define	EREMCHG		78	/* Remote address changed */
+#define	ELIBACC		79	/* Can not access a needed shared library */
+#define	ELIBBAD		80	/* Accessing a corrupted shared library */
+#define	ELIBSCN		81	/* .lib section in a.out corrupted */
+#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	EILSEQ		84	/* Illegal byte sequence */
+#define	ERESTART	85	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUSERS		87	/* Too many users */
+#define	ENOTSOCK	88	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	89	/* Destination address required */
+#define	EMSGSIZE	90	/* Message too long */
+#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	92	/* Protocol not available */
+#define	EPROTONOSUPPORT	93	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
+#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	96	/* Protocol family not supported */
+#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
+#define	EADDRINUSE	98	/* Address already in use */
+#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
+#define	ENETDOWN	100	/* Network is down */
+#define	ENETUNREACH	101	/* Network is unreachable */
+#define	ENETRESET	102	/* Network dropped connection because of reset */
+#define	ECONNABORTED	103	/* Software caused connection abort */
+#define	ECONNRESET	104	/* Connection reset by peer */
+#define	ENOBUFS		105	/* No buffer space available */
+#define	EISCONN		106	/* Transport endpoint is already connected */
+#define	ENOTCONN	107	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
+#define	ETIMEDOUT	110	/* Connection timed out */
+#define	ECONNREFUSED	111	/* Connection refused */
+#define	EHOSTDOWN	112	/* Host is down */
+#define	EHOSTUNREACH	113	/* No route to host */
+#define	EALREADY	114	/* Operation already in progress */
+#define	EINPROGRESS	115	/* Operation now in progress */
+#define	ESTALE		116	/* Stale NFS file handle */
+#define	EUCLEAN		117	/* Structure needs cleaning */
+#define	ENOTNAM		118	/* Not a XENIX named type file */
+#define	ENAVAIL		119	/* No XENIX semaphores available */
+#define	EISNAM		120	/* Is a named type file */
+#define	EREMOTEIO	121	/* Remote I/O error */
+#define	EDQUOT		122	/* Quota exceeded */
+
+#define	ENOMEDIUM	123	/* No medium found */
+#define	EMEDIUMTYPE	124	/* Wrong medium type */
+
+#endif /* _FRIO_ERRNO_H */
diff -urN linux-2.4.29/include/asm-blackfin/fcntl.h linux-2.4.29-uc1/include/asm-blackfin/fcntl.h
--- linux-2.4.29/include/asm-blackfin/fcntl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/fcntl.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,86 @@
+#ifndef _FRIO_FCNTL_H
+#define _FRIO_FCNTL_H
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	  0003
+#define O_RDONLY	    00
+#define O_WRONLY	    01
+#define O_RDWR		    02
+#define O_CREAT		  0100	/* not fcntl */
+#define O_EXCL		  0200	/* not fcntl */
+#define O_NOCTTY	  0400	/* not fcntl */
+#define O_TRUNC		 01000	/* not fcntl */
+#define O_APPEND	 02000
+#define O_NONBLOCK	 04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC		010000
+#define FASYNC		020000	/* fcntl, for BSD compatibility */
+#define O_DIRECTORY	040000	/* must be a directory */
+#define O_NOFOLLOW	0100000	/* don't follow links */
+#define O_DIRECT	0200000	/* direct disk access hint - currently ignored */
+#define O_LARGEFILE	0400000
+
+#define F_DUPFD		0	/* dup */
+#define F_GETFD		1	/* get close_on_exec */
+#define F_SETFD		2	/* set/clear close_on_exec */
+#define F_GETFL		3	/* get file->f_flags */
+#define F_SETFL		4	/* set file->f_flags */
+#define F_GETLK		5
+#define F_SETLK		6
+#define F_SETLKW	7
+
+#define F_SETOWN	8	/*  for sockets. */
+#define F_GETOWN	9	/*  for sockets. */
+#define F_SETSIG	10	/*  for sockets. */
+#define F_GETSIG	11	/*  for sockets. */
+
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK		0
+#define F_WRLCK		1
+#define F_UNLCK		2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+/* for leases */
+#define F_INPROGRESS	16
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* or'd with one of the above to prevent
+				   blocking */
+#define LOCK_UN		8	/* remove lock */
+
+#define LOCK_MAND	32	/* This is a mandatory flock */
+#define LOCK_READ	64	/* ... Which allows concurrent read operations */
+#define LOCK_WRITE	128	/* ... Which allows concurrent write operations */
+#define LOCK_RW		192	/* ... Which allows concurrent read & write ops */
+
+struct flock {
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE	1024
+#endif /* _FRIO_FCNTL_H */
diff -urN linux-2.4.29/include/asm-blackfin/flat.h linux-2.4.29-uc1/include/asm-blackfin/flat.h
--- linux-2.4.29/include/asm-blackfin/flat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/flat.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef __BLACKFIN_FLAT_H__
+#define __BLACKFIN_FLAT_H__
+
+#define flat_stack_align(sp)                    /* nothing needed */
+#define flat_argvp_envp_on_stack()              1
+#define flat_old_ram_flag(flags)                (flags)
+#define flat_reloc_valid(reloc, size)           ((reloc) <= (size))
+#define flat_get_addr_from_rp(rp, relval, flags)       get_unaligned(rp)
+#define flat_put_addr_at_rp(rp, val, relval)    put_unaligned(val,rp)
+#define flat_get_relocate_addr(rel)             (rel)
+
+#endif /* __BLACKFIN_FLAT_H__ */
diff -urN linux-2.4.29/include/asm-blackfin/hardirq.h linux-2.4.29-uc1/include/asm-blackfin/hardirq.h
--- linux-2.4.29/include/asm-blackfin/hardirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/hardirq.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,41 @@
+#ifndef __FRIO_HARDIRQ_H
+#define __FRIO_HARDIRQ_H
+
+#include <linux/config.h>
+#include <linux/threads.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned int __local_irq_count;
+	unsigned int __local_bh_count;
+	unsigned int __syscall_count;
+	struct task_struct * __ksoftirqd_task;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt() (local_irq_count(smp_processor_id()) + local_bh_count(smp_processor_id()) != 0)
+
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
+
+#ifndef CONFIG_SMP
+
+#define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
+#define hardirq_endlock(cpu)	do { } while (0)
+
+#define irq_enter(cpu, irq)	(local_irq_count(cpu)++)
+#define irq_exit(cpu, irq)	(local_irq_count(cpu)--)
+
+#define synchronize_irq()	barrier()
+
+#else
+
+#error frionommu SMP is not available
+
+#endif /* CONFIG_SMP */
+
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/hdreg.h linux-2.4.29-uc1/include/asm-blackfin/hdreg.h
--- linux-2.4.29/include/asm-blackfin/hdreg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/hdreg.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,14 @@
+/*
+ *  linux/include/asm-frionommu/hdreg.h
+ *
+ *  Copyright (C) 1994-1996  Linus Torvalds & authors
+ *
+ *  Chabges made by Lineo Inc	May 2001
+ */
+
+#ifndef _FRIO_HDREG_H
+#define _FRIO_HDREG_H
+
+typedef unsigned char * ide_ioreg_t;
+
+#endif /* _FRIO_HDREG_H */
diff -urN linux-2.4.29/include/asm-blackfin/hw_irq.h linux-2.4.29-uc1/include/asm-blackfin/hw_irq.h
--- linux-2.4.29/include/asm-blackfin/hw_irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/hw_irq.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,29 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/hw_irq.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * BlackFin (ADI) assembler restricted values by Ted Ma <mated@sympatico.ca>
+ * Copyright (c) 2002 Arcturus Networks Inc. (www.arcturusnetworks.com)
+ * Copyright (c) 2002 Lineo, Inc <mattw@lineo.com>
+ */
+/*
+ This is included from <linux/irq.h>.
+	Include by assembler files which don't need the 'C' stuff
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_BLACKFIN_EZKIT
+  #include <asm/board/bf533_irq.h>
+#endif
+#ifdef CONFIG_PUB
+  #include <asm/board/bf535_irq.h>
+#endif
+#ifdef CONFIG_HAWK
+  #include <asm/board/bf535_irq.h>
+#endif
+#ifdef CONFIG_EAGLE
+  #include <asm/board/bf535_irq.h>
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/ide.h linux-2.4.29-uc1/include/asm-blackfin/ide.h
--- linux-2.4.29/include/asm-blackfin/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/ide.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,488 @@
+/* Changes made by Tony Kou     Lineo, Inc     May 2001	*/
+
+
+/*
+ *  linux/include/asm-m68k/ide.h
+ *
+ *  Copyright (C) 1994-1996  Linus Torvalds & authors
+ */
+ 
+/* Copyright(c) 1996 Kars de Jong */
+/* Based on the ide driver from 1.2.13pl8 */
+
+/*
+ * Credits (alphabetical):
+ *
+ *  - Bjoern Brauel
+ *  - Kars de Jong
+ *  - Torsten Ebeling
+ *  - Dwight Engen
+ *  - Thorsten Floeck
+ *  - Roman Hodek
+ *  - Guenther Kelleter
+ *  - Chris Lawrence
+ *  - Michael Rausch
+ *  - Christian Sauer
+ *  - Michael Schmitz
+ *  - Jes Soerensen
+ *  - Michael Thurm
+ *  - Geert Uytterhoeven
+ */
+
+#ifndef _FRIO_IDE_H
+#define _FRIO_IDE_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+
+#include <asm/setup.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#ifdef CONFIG_ATARI
+#include <linux/interrupt.h>
+#include <asm/atari_stdma.h>
+#endif
+
+#ifdef CONFIG_MAC
+#include <asm/macints.h>
+#endif
+
+#ifndef MAX_HWIFS
+#define MAX_HWIFS	4	/* same as the other archs */
+#endif
+
+
+static __inline__ int ide_default_irq(ide_ioreg_t base)
+{
+	  return 0;
+}
+
+static __inline__ ide_ioreg_t ide_default_io_base(int index)
+{
+          return 0;
+}
+
+/*
+ *  Can we do this in a generic manner??
+ */
+
+
+/*
+ * Set up a hw structure for a specified data port, control port and IRQ.
+ * This should follow whatever the default interface uses.
+ */
+static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
+{
+	if (data_port || ctrl_port)
+		printk("ide_init_hwif_ports: must not be called\n");
+}
+
+/*
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ */
+static __inline__ void ide_init_default_hwifs(void)
+{
+}
+
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+		unsigned bit7		: 1;	/* always 1 */
+		unsigned lba		: 1;	/* using LBA instead of CHS */
+		unsigned bit5		: 1;	/* always 1 */
+		unsigned unit		: 1;	/* drive select number, 0 or 1 */
+		unsigned head		: 4;	/* always zeros here */
+	} b;
+	} select_t;
+
+static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+			unsigned long flags, const char *device, void *dev_id)
+{
+#ifdef CONFIG_AMIGA
+	if (MACH_IS_AMIGA)
+		return request_irq(irq, handler, 0, device, dev_id);
+#endif /* CONFIG_AMIGA */
+#ifdef CONFIG_Q40
+	if (MACH_IS_Q40)
+	  	return request_irq(irq, handler, 0, device, dev_id);
+#endif /* CONFIG_Q40*/
+#ifdef CONFIG_MAC
+	if (MACH_IS_MAC)
+		return request_irq(irq, handler, 0, device, dev_id);
+#endif /* CONFIG_MAC */
+	return 0;
+}
+
+static __inline__ void ide_free_irq(unsigned int irq, void *dev_id)
+{
+#ifdef CONFIG_AMIGA
+	if (MACH_IS_AMIGA)
+		free_irq(irq, dev_id);
+#endif /* CONFIG_AMIGA */
+#ifdef CONFIG_Q40
+	if (MACH_IS_Q40)
+	  	free_irq(irq, dev_id);
+#endif /* CONFIG_Q40*/
+#ifdef CONFIG_MAC
+	if (MACH_IS_MAC)
+		free_irq(irq, dev_id);
+#endif /* CONFIG_MAC */
+}
+
+/*
+ * We should really implement those some day.
+ */
+static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent)
+{
+	return 0;
+}
+
+static __inline__ void ide_request_region (ide_ioreg_t from, unsigned int extent, const char *name)
+{
+#ifdef CONFIG_Q40
+        if (MACH_IS_Q40)
+            request_region((q40ide_ioreg_t)from,extent,name);
+#endif
+}
+
+static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent)
+{
+#ifdef CONFIG_Q40
+        if (MACH_IS_Q40)
+            release_region((q40ide_ioreg_t)from,extent);
+#endif
+}
+
+#undef SUPPORT_SLOW_DATA_PORTS
+#define SUPPORT_SLOW_DATA_PORTS 0
+
+#undef SUPPORT_VLB_SYNC
+#define SUPPORT_VLB_SYNC 0
+
+/* this definition is used only on startup .. */
+#ifndef CONFIG_Q40
+#undef HD_DATA
+#define HD_DATA NULL
+#else
+#ifdef MACH_Q40_ONLY
+#undef HD_DATA
+#define HD_DATA ((ide_ioreg_t)0x1f0)
+#else
+#undef HD_DATA
+#define HD_DATA   (MACH_IS_Q40 ? (ide_ioreg_t)0x1f0 : 0)
+#endif
+#endif
+
+
+#define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1)
+#define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1)
+
+#ifdef CONFIG_Q40
+#ifdef MACH_Q40_ONLY
+#define ADDR_TRANS(_addr_) (Q40_ISA_IO_W(_addr_))
+#else
+#define ADDR_TRANS(_addr_) (MACH_IS_Q40 ? ((unsigned char *)Q40_ISA_IO_W(_addr_)) : (_addr_))
+#endif
+#else
+#define ADDR_TRANS(_addr_) (_addr_)
+#endif
+
+#define insw(port, buf, nr) ({				\
+	unsigned char *_port = (unsigned char *) ADDR_TRANS(port);	\
+	unsigned char *_buf = (buf);			\
+	int _nr = (nr);					\
+	unsigned short _tmp;				\
+							\
+	asm volatile (					\
+		"L$0:\n\t"				\
+		"cc = %1<=0;(iu)\n\t"			\
+		"if cc jump L$1;\n\t"				\
+		"%2 = w[%3](z);\n\t"			\
+		"w[%0++] = %2;\n\t"			\
+		"%1 += -1;\n\t"				\
+		"jump.s L$0;\n"				\
+		"L$1:\n\t"				\
+		: "=a" (_buf),  "=d" (_nr), "=d" (_tmp)	\
+		: "a"  (_port), "0" (_buf),		\
+		  "2" (_tmp)				\
+		: "CC");				\
+})
+
+#define outsw(port, buf, nr) ({				\
+	unsigned char *_port = (unsigned char *) ADDR_TRANS(port);	\
+	unsigned char *_buf = (buf);			\
+	int _nr = (nr);					\
+	unsigned long _tmp;				\
+							\
+	asm volatile (					\
+		"1:\n\t"				\
+		"cc = %1<=0(iu);\n\t"			\
+		"if cc jump 2f;\n\t"				\
+		"%2 = w[%0++](z);\n\t"			\
+		"w[%3] = %2;\n\t"			\
+		"%1 += -1;\n\t"				\
+		"jump.s 1b;\n"				\
+		"2:\n"				\
+		: "=a" (_buf),  "=d" (_nr), "=d" (_tmp)	\
+		: "a"  (_port), "0" (_buf),		\
+		  "2" (_tmp)				\
+		: "CC");				\
+})
+
+
+
+#if 0
+#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
+#define insl_swapw(data_reg, buffer, wcount) \
+    insw_swapw(data_reg, buffer, (wcount)<<1)
+#define outsl_swapw(data_reg, buffer, wcount) \
+    outsw_swapw(data_reg, buffer, (wcount)<<1)
+
+#define insw_swapw(port, buf, nr) \
+    if ((nr) % 8) \
+	__asm__ __volatile__ \
+	       ("movel %0,%/a0; \
+		 movel %1,%/a1; \
+		 movel %2,%/d6; \
+		 subql #1,%/d6; \
+	       1:movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 dbra %/d6,1b" : \
+		: "g" (ADDR_TRANS(port)), "g" (buf), "g" (nr) \
+		: "d0", "a0", "a1", "d6"); \
+    else \
+	__asm__ __volatile__ \
+	       ("movel %0,%/a0; \
+		 movel %1,%/a1; \
+		 movel %2,%/d6; \
+		 lsrl  #3,%/d6; \
+		 subql #1,%/d6; \
+	       1:movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 dbra %/d6,1b" : \
+		: "g" (ADDR_TRANS(port)), "g" (buf), "g" (nr) \
+		: "d0", "a0", "a1", "d6") 
+
+
+#define outsw_swapw(port, buf, nr) \
+    if ((nr) % 8) \
+	__asm__ __volatile__ \
+	       ("movel %0,%/a0; \
+		 movel %1,%/a1; \
+		 movel %2,%/d6; \
+		 subql #1,%/d6; \
+	       1:movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 dbra %/d6,1b" : \
+		: "g" (ADDR_TRANS(port)), "g" (buf), "g" (nr) \
+		: "d0", "a0", "a1", "d6"); \
+    else \
+	__asm__ __volatile__ \
+	       ("movel %0,%/a0; \
+		 movel %1,%/a1; \
+		 movel %2,%/d6; \
+		 lsrl  #3,%/d6; \
+		 subql #1,%/d6; \
+	       1:movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 dbra %/d6,1b" : \
+		: "g" (ADDR_TRANS(port)), "g" (buf), "g" (nr) \
+		: "d0", "a0", "a1", "d6")
+
+#endif /* CONFIG_ATARI */
+#endif
+
+
+
+#define T_CHAR          (0x0000)        /* char:  don't touch  */
+#define T_SHORT         (0x4000)        /* short: 12 -> 21     */
+#define T_INT           (0x8000)        /* int:   1234 -> 4321 */
+#define T_TEXT          (0xc000)        /* text:  12 -> 21     */
+
+#define T_MASK_TYPE     (0xc000)
+#define T_MASK_COUNT    (0x3fff)
+
+#define D_CHAR(cnt)     (T_CHAR  | (cnt))
+#define D_SHORT(cnt)    (T_SHORT | (cnt))
+#define D_INT(cnt)      (T_INT   | (cnt))
+#define D_TEXT(cnt)     (T_TEXT  | (cnt))
+
+#if defined(CONFIG_AMIGA) || defined (CONFIG_MAC)
+static u_short driveid_types[] = {
+	D_SHORT(10),	/* config - vendor2 */
+	D_TEXT(20),	/* serial_no */
+	D_SHORT(3),	/* buf_type, buf_size - ecc_bytes */
+	D_TEXT(48),	/* fw_rev - model */
+	D_CHAR(2),	/* max_multsect - vendor3 */
+	D_SHORT(1),	/* dword_io */
+	D_CHAR(2),	/* vendor4 - capability */
+	D_SHORT(1),	/* reserved50 */
+	D_CHAR(4),	/* vendor5 - tDMA */
+	D_SHORT(4),	/* field_valid - cur_sectors */
+	D_INT(1),	/* cur_capacity */
+	D_CHAR(2),	/* multsect - multsect_valid */
+	D_INT(1),	/* lba_capacity */
+	D_SHORT(194)	/* dma_1word - reservedyy */
+};
+
+#define num_driveid_types       (sizeof(driveid_types)/sizeof(*driveid_types))
+#endif /* CONFIG_AMIGA */
+
+static __inline__ void ide_fix_driveid(struct hd_driveid *id)
+{
+#if defined(CONFIG_AMIGA) || defined (CONFIG_MAC)
+   u_char *p = (u_char *)id;
+   int i, j, cnt;
+   u_char t;
+
+   if (!MACH_IS_AMIGA && !MACH_IS_MAC)
+   	return;
+   for (i = 0; i < num_driveid_types; i++) {
+      cnt = driveid_types[i] & T_MASK_COUNT;
+      switch (driveid_types[i] & T_MASK_TYPE) {
+         case T_CHAR:
+            p += cnt;
+            break;
+         case T_SHORT:
+            for (j = 0; j < cnt; j++) {
+               t = p[0];
+               p[0] = p[1];
+               p[1] = t;
+               p += 2;
+            }
+            break;
+         case T_INT:
+            for (j = 0; j < cnt; j++) {
+               t = p[0];
+               p[0] = p[3];
+               p[3] = t;
+               t = p[1];
+               p[1] = p[2];
+               p[2] = t;
+               p += 4;
+            }
+            break;
+         case T_TEXT:
+            for (j = 0; j < cnt; j += 2) {
+               t = p[0];
+               p[0] = p[1];
+               p[1] = t;
+               p += 2;
+            }
+            break;
+      }
+   }
+#endif /* CONFIG_AMIGA */
+}
+
+static __inline__ void ide_release_lock (int *ide_lock)
+{
+#ifdef CONFIG_ATARI
+	if (MACH_IS_ATARI) {
+		if (*ide_lock == 0) {
+			printk("ide_release_lock: bug\n");
+			return;
+		}
+		*ide_lock = 0;
+		stdma_release();
+	}
+#endif /* CONFIG_ATARI */
+}
+
+static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data)
+{
+#ifdef CONFIG_ATARI
+	if (MACH_IS_ATARI) {
+		if (*ide_lock == 0) {
+			if (in_interrupt() > 0)
+				panic( "Falcon IDE hasn't ST-DMA lock in interrupt" );
+			stdma_lock(handler, data);
+			*ide_lock = 1;
+		}
+	}
+#endif /* CONFIG_ATARI */
+}
+
+#define ide_ack_intr(hwif)	((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1)
+
+/*
+ * On the Atari, we sometimes can't enable interrupts:
+ */
+
+/* MSch: changed sti() to STI() wherever possible in ide.c; moved STI() def. 
+ * to asm/ide.h 
+ */
+/* The Atari interrupt structure strictly requires that the IPL isn't lowered
+ * uncontrolled in an interrupt handler. In the concrete case, the IDE
+ * interrupt is already a slow int, so the irq is already disabled at the time
+ * the handler is called, and the IPL has been lowered to the minimum value
+ * possible. To avoid going below that, STI() checks for being called inside
+ * an interrupt, and in that case it does nothing. Hope that is reasonable and
+ * works. (Roman)
+ */
+#ifdef MACH_ATARI_ONLY
+#define	ide__sti()					\
+    do {						\
+	if (!in_interrupt()) __sti();			\
+    } while(0)
+#elif defined(CONFIG_ATARI)
+#define	ide__sti()						\
+    do {							\
+	if (!MACH_IS_ATARI || !in_interrupt()) sti();		\
+    } while(0)
+#else /* !defined(CONFIG_ATARI) */
+#define	ide__sti()	__sti()
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* _FRIO_IDE_H */
diff -urN linux-2.4.29/include/asm-blackfin/init.h linux-2.4.29-uc1/include/asm-blackfin/init.h
--- linux-2.4.29/include/asm-blackfin/init.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/init.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,11 @@
+#ifndef _FRIO_INIT_H
+#define _FRIO_INIT_H
+
+#define __init __attribute__ ((__section__ (".text.init")))
+#define __initdata __attribute__ ((__section__ (".data.init")))
+/* For assembly routines */
+#define __INIT		.section	".text.init",#alloc,#execinstr
+#define __FINIT		.previous
+#define __INITDATA	.section	".data.init",#alloc,#write
+
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/ioctl.h linux-2.4.29-uc1/include/asm-blackfin/ioctl.h
--- linux-2.4.29/include/asm-blackfin/ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/ioctl.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,80 @@
+/* $Id: ioctl.h,v 1.1 2003/11/04 14:47:41 bas Exp $
+ *
+ * linux/ioctl.h for Linux by H.H. Bergman.
+ */
+
+#ifndef _FRIO_IOCTL_H
+#define _FRIO_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * I don't really have any idea about what this should look like, so
+ * for the time being, this is heavily based on the PC definitions.
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	14
+#define _IOC_DIRBITS	2
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE	0U
+#define _IOC_WRITE	1U
+#define _IOC_READ	2U
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* _FRIO_IOCTL_H */
diff -urN linux-2.4.29/include/asm-blackfin/ioctls.h linux-2.4.29-uc1/include/asm-blackfin/ioctls.h
--- linux-2.4.29/include/asm-blackfin/ioctls.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/ioctls.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,81 @@
+#ifndef __ARCH_FRIO_IOCTLS_H__
+#define __ARCH_FRIO_IOCTLS_H__
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+#define TIOCSBRK	0x5427  /* BSD compatibility */
+#define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define FIONCLEX	0x5450  /* these numbers need to be adjusted. */
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+#define FIOQSIZE	0x545E
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+#endif /* __ARCH_FRIO_IOCTLS_H__ */
diff -urN linux-2.4.29/include/asm-blackfin/io.h linux-2.4.29-uc1/include/asm-blackfin/io.h
--- linux-2.4.29/include/asm-blackfin/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/io.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,99 @@
+#ifndef _FRIO_IO_H
+#define _FRIO_IO_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <asm/virtconvert.h>
+
+/* Chang Junxiao, June 25, 2003.
+ * This macro is base of PCI IO address window of AD21535 */
+#define AD21535_PCIIO_BASE 0xeefe0000
+
+/*
+ * These are for ISA/PCI shared memory _only_ and should never be used
+ * on any other type of memory, including Zorro memory. They are meant to
+ * access the bus in the bus byte order which is little-endian!.
+ *
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the m68k architecture, we just read/write the
+ * memory location directly.
+ */
+/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
+ * two accesses to memory, which may be undesireable for some devices.
+ */
+#define readb(addr) ({ unsigned char __v = (*(volatile unsigned char *) (addr));asm("ssync;"); __v; })
+#define readw(addr) ({ unsigned short __v = (*(volatile unsigned short *) (addr)); asm("ssync;");__v; })
+#define readl(addr) ({ unsigned int __v = (*(volatile unsigned int *) (addr));asm("ssync;"); __v; })
+
+#define writeb(b,addr) {((*(volatile unsigned char *) (addr)) = (b)); asm("ssync;");}
+#define writew(b,addr) {((*(volatile unsigned short *) (addr)) = (b)); asm("ssync;");}
+#define writel(b,addr) {((*(volatile unsigned int *) (addr)) = (b)); asm("ssync;");}
+
+#define memset_io(a,b,c)	memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
+
+#define inb_p(addr) readb((addr) + AD21535_PCIIO_BASE)
+#define inb(addr) readb((addr) + AD21535_PCIIO_BASE)
+
+#define outb(x,addr) writeb(x, (addr) + AD21535_PCIIO_BASE)
+#define outb_p(x,addr) outb(x, (addr) + AD21535_PCIIO_BASE)
+
+#define inw(addr) readw((addr) + AD21535_PCIIO_BASE)
+#define inl(addr) readl((addr) + AD21535_PCIIO_BASE)
+
+#define outw(x,addr) writew(x, (addr) + AD21535_PCIIO_BASE)
+#define outl(x,addr) writel(x, (addr) + AD21535_PCIIO_BASE)
+
+#define insb(port, addr, count) memcpy((void*)addr, (void*)(AD21535_PCIIO_BASE + port), count)
+#define insw(port, addr, count) memcpy((void*)addr, (void*)(AD21535_PCIIO_BASE + port), (2*count))
+#define insl(port, addr, count) memcpy((void*)addr, (void*)(AD21535_PCIIO_BASE + port), (4*count))
+
+#define outsb(port, addr, count) memcpy((void*)(AD21535_PCIIO_BASE + port), (void*)addr, count)
+#define outsw(port, addr, count) memcpy((void*)(AD21535_PCIIO_BASE + port), (void*)addr, (2*count))
+#define outsl(port, addr, count) memcpy((void*)(AD21535_PCIIO_BASE + port), (void*)addr, (4*count))
+
+#define IO_SPACE_LIMIT 0xffff
+
+
+/* Values for nocacheflag and cmode */
+#define IOMAP_FULL_CACHING		0
+#define IOMAP_NOCACHE_SER		1
+#define IOMAP_NOCACHE_NONSER		2
+#define IOMAP_WRITETHROUGH		3
+
+extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
+extern void __iounmap(void *addr, unsigned long size);
+
+extern inline void *ioremap(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+extern inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+extern inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
+}
+extern inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
+}
+
+extern void iounmap(void *addr);
+
+/* Nothing to do */
+
+
+extern void blkfin_inv_cache_all(void);
+#define dma_cache_inv(_start,_size) do { blkfin_inv_cache_all();} while (0)
+#define dma_cache_wback(_start,_size) do { } while (0)
+#define dma_cache_wback_inv(_start,_size) do { blkfin_inv_cache_all();} while (0)
+
+#endif /* __KERNEL__ */
+
+#endif /* _FRIO_IO_H */
diff -urN linux-2.4.29/include/asm-blackfin/ipcbuf.h linux-2.4.29-uc1/include/asm-blackfin/ipcbuf.h
--- linux-2.4.29/include/asm-blackfin/ipcbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/ipcbuf.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,31 @@
+/* Changes origined from m68k version.    Lineo Inc.  May 2001   */
+
+#ifndef __FRIO_IPCBUF_H__
+#define __FRIO_IPCBUF_H__
+
+/*
+ * The user_ipc_perm structure for m68k architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
+	__kernel_mode_t		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* __FRIO_IPCBUF_H__ */
diff -urN linux-2.4.29/include/asm-blackfin/ipc.h linux-2.4.29-uc1/include/asm-blackfin/ipc.h
--- linux-2.4.29/include/asm-blackfin/ipc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/ipc.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,33 @@
+/* Changes origined from m68k version.     Lineo  Inc.   May 2001  */
+
+#ifndef __FRIO_IPC_H__
+#define __FRIO_IPC_H__
+
+/* 
+ * These are used to wrap system calls on m68k.
+ *
+ * See arch/m68k/kernel/sys_m68k.c for ugly details..
+ */
+struct ipc_kludge {
+	struct msgbuf *msgp;
+	long msgtyp;
+};
+
+#define SEMOP		 1
+#define SEMGET		 2
+#define SEMCTL		 3
+#define MSGSND		11
+#define MSGRCV		12
+#define MSGGET		13
+#define MSGCTL		14
+#define SHMAT		21
+#define SHMDT		22
+#define SHMGET		23
+#define SHMCTL		24
+
+/* Used by the DIPC package, try and avoid reusing it */
+#define DIPC		25
+
+#define IPCCALL(version,op)	((version)<<16 | (op))
+
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/irq.h linux-2.4.29-uc1/include/asm-blackfin/irq.h
--- linux-2.4.29/include/asm-blackfin/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/irq.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,140 @@
+/*
+ * linux/arch/$(ARCH)/platform/$(PLATFORM)/irq.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Changed by HuTao Apr18, 2003
+ *
+ * Copyright was missing when I got the code so took from MIPS arch ...MaTed---
+ * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle
+ * Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001 by Ralf Baechle
+ *
+ * Adapted for BlackFin (ADI) by Ted Ma <mated@sympatico.ca>
+ * Copyright (c) 2002 Arcturus Networks Inc. (www.arcturusnetworks.com)
+ * Copyright (c) 2002 Lineo, Inc. <mattw@lineo.com>
+ */
+
+#ifndef _FRIO_IRQ_H_
+#define _FRIO_IRQ_H_
+
+#include <linux/config.h>
+#ifdef CONFIG_PUB
+  #include <asm/board/bf535_irq.h>
+#endif
+#ifdef CONFIG_EAGLE
+  #include <asm/board/bf535_irq.h>
+#endif
+#ifdef CONFIG_HAWK
+  #include <asm/board/bf535_irq.h>
+#endif
+#ifdef CONFIG_BLACKFIN_EZKIT
+  #include <asm/board/bf533_irq.h>
+#endif
+
+/*******************************************************************************
+ *****   INTRODUCTION ***********
+ *   On the Blackfin, the interrupt structure allows remmapping of the hardware
+ *   levels.
+ * - I'm going to assume that the H/W level is going to stay at the default
+ *   settings. If someone wants to go through and abstart this out, feel free
+ *   to mod the interrupt numbering scheme. 
+ * - I'm abstracting the interrupts so that uClinux does not know anything
+ *   about the H/W levels. If you want to change the H/W AND keep the abstracted
+ *   levels that uClinux sees, you should be able to do most of it here.
+ * - I've left the "abstract" numbering sparce in case someone wants to pull the
+ *   interrupts apart (just the TX/RX for the various devices)
+ *******************************************************************************/
+
+// SYS_IRQS defined in <asm/board/bf53[35]_irq.h>
+
+#define	NR_IRQS		SYS_IRQS
+
+/*
+ * "Generic" interrupt sources
+ */
+#define IRQ_SCHED_TIMER	(8)    /* interrupt source for scheduling timer */
+
+static __inline__ int irq_cannonicalize(int irq)
+{
+	return irq;
+}
+
+/*
+ * Machine specific interrupt sources.
+ *
+ * Adding an interrupt service routine for a source with this bit
+ * set indicates a special machine specific interrupt source.
+ * The machine specific files define these sources.
+ *
+ * The IRQ_MACHSPEC bit is now gone - the only thing it did was to
+ * introduce unnecessary overhead.
+ *
+ * All interrupt handling is actually machine specific so it is better
+ * to use function pointers, as used by the Sparc port, and select the
+ * interrupt handling functions when initializing the kernel. This way
+ * we save some unnecessary overhead at run-time. 
+ *                                                      01/11/97 - Jes
+ */
+
+extern void (*mach_enable_irq)(unsigned int);
+extern void (*mach_disable_irq)(unsigned int);
+
+extern int sys_request_irq(unsigned int, 
+	void (*)(int, void *, struct pt_regs *), 
+	unsigned long, const char *, void *);
+extern void sys_free_irq(unsigned int, void *);
+
+/*
+ * various flags for request_irq() - the Amiga now uses the standard
+ * mechanism like all other architectures - SA_INTERRUPT and SA_SHIRQ
+ * are your friends.
+ */
+#define IRQ_FLG_LOCK    (0x0001)        /* handler is not replaceable   */
+#define IRQ_FLG_REPLACE (0x0002)        /* replace existing handler     */
+#define IRQ_FLG_FAST    (0x0004)
+#define IRQ_FLG_SLOW    (0x0008)
+#define IRQ_FLG_STD     (0x8000)        /* internally used              */
+
+/*
+ * This structure is used to chain together the ISRs for a particular
+ * interrupt source (if it supports chaining).
+ */
+typedef struct irq_node {
+	void		(*handler)(int, void *, struct pt_regs *);
+	unsigned long	flags;
+	void		*dev_id;
+	const char	*devname;
+	struct irq_node *next;
+} irq_node_t;
+
+
+/*
+ * This structure has only 4 elements for speed reasons
+ */
+typedef struct irq_handler {
+	void		(*handler)(int, void *, struct pt_regs *);
+	unsigned long	flags;
+	void		*dev_id;
+	const char	*devname;
+} irq_handler_t;
+
+/* count of spurious interrupts */
+extern volatile unsigned int num_spurious;
+
+/*
+ * This function returns a new irq_node_t
+ */
+extern irq_node_t *new_irq_node(void);
+
+/*
+ * Some drivers want these entry points
+ */
+#define enable_irq(x)	(mach_enable_irq  ? (*mach_enable_irq)(x)  : 0)
+#define disable_irq(x)	(mach_disable_irq ? (*mach_disable_irq)(x) : 0)
+
+#define enable_irq_nosync(x)	enable_irq(x)
+#define disable_irq_nosync(x)	disable_irq(x)
+
+#endif /* _FRIO_IRQ_H_ */
diff -urN linux-2.4.29/include/asm-blackfin/linux_logo.h linux-2.4.29-uc1/include/asm-blackfin/linux_logo.h
--- linux-2.4.29/include/asm-blackfin/linux_logo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/linux_logo.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,11 @@
+/*
+ * include/asm-frionommu/linux_logo.h: This is a linux logo
+ *                                 to be displayed on boot.
+ */
+ 
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/version.h>
+
+#define linux_logo_banner "Linux/frionommu version " UTS_RELEASE
+
diff -urN linux-2.4.29/include/asm-blackfin/machdep.h linux-2.4.29-uc1/include/asm-blackfin/machdep.h
--- linux-2.4.29/include/asm-blackfin/machdep.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/machdep.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,59 @@
+#ifndef _FRIONOMMU_MACHDEP_H
+#define _FRIONOMMU_MACHDEP_H
+
+/** Machine dependent initial routines:
+ *
+ *  Based on include/asm-m68knommu/machdep.h
+ *  For frio, just now we only have nisa, so they'd point to the default nisa
+ *
+ */
+ 
+struct pt_regs;
+struct kbd_repeat;
+struct mktime;
+struct hwclk_time;
+struct gendisk;
+struct buffer_head;
+
+extern void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *));
+/* machine dependent keyboard functions */
+extern int (*mach_keyb_init) (void);
+extern int (*mach_kbdrate) (struct kbd_repeat *);
+extern void (*mach_kbd_leds) (unsigned int);
+/* machine dependent irq functions */
+extern void (*mach_init_IRQ) (void);
+extern void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *);
+extern int (*mach_request_irq) (unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                                unsigned long flags, const char *devname, void *dev_id);
+extern void (*mach_free_irq) (unsigned int irq, void *dev_id);
+extern void (*mach_get_model) (char *model);
+extern int (*mach_get_hardware_list) (char *buffer);
+extern int (*mach_get_irq_list) (char *buf);
+extern void (*mach_process_int) (int irq, struct pt_regs *fp);
+/* machine dependent timer functions */
+extern unsigned long (*mach_gettimeoffset)(void);
+extern void (*mach_gettod)(int *year, int *mon, int *day, int *hour,
+			   int *min, int *sec);
+extern int (*mach_hwclk)(int, struct hwclk_time*);
+extern int (*mach_set_clock_mmss)(unsigned long);
+extern void (*mach_reset)( void );
+extern void (*mach_halt)( void );
+extern void (*mach_power_off)( void );
+extern unsigned long (*mach_hd_init) (unsigned long, unsigned long);
+extern void (*mach_hd_setup)(char *, int *);
+extern long mach_max_dma_address;
+extern void (*mach_floppy_setup)(char *, int *);
+extern void (*mach_floppy_eject)(void);
+extern void (*mach_heartbeat) (int);
+extern void (*mach_l2_flush) (int);
+extern int mach_sysrq_key;
+extern int mach_sysrq_shift_state;
+extern int mach_sysrq_shift_mask;
+extern char *mach_sysrq_xlate;
+
+#ifdef CONFIG_UCLINUX
+extern void config_BSP(char *command, int len);
+extern void (*mach_tick)(void);
+#endif
+
+#endif /* _FRIONOMMU_MACHDEP_H */
diff -urN linux-2.4.29/include/asm-blackfin/md.h linux-2.4.29-uc1/include/asm-blackfin/md.h
--- linux-2.4.29/include/asm-blackfin/md.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/md.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,13 @@
+/* $Id: md.h,v 1.1 2003/11/04 14:47:41 bas Exp $
+ * md.h: High speed xor_block operation for RAID4/5 
+ *
+ */
+ 
+#ifndef __ASM_MD_H
+#define __ASM_MD_H
+
+/* #define HAVE_ARCH_XORBLOCK */
+
+#define MD_XORBLOCK_ALIGNMENT	sizeof(long)
+
+#endif /* __ASM_MD_H */
diff -urN linux-2.4.29/include/asm-blackfin/memdma.h linux-2.4.29-uc1/include/asm-blackfin/memdma.h
--- linux-2.4.29/include/asm-blackfin/memdma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/memdma.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ * include/asm-frionommu/memdma.h - Function declaration for memory to memory 
+ * dma for Blackfin ADSP-21535
+ *  derived from:
+ *  include/asm-i386/dma.h
+ *  Written by Hennus Bergman, 1992.
+ *  Hannu Savolainen  and John Boyd, Nov. 1992.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * or (at your option) any later version as  published by the Free Software 
+ * Foundation.
+ *
+ */
+#ifndef _FRIONOMMU_MEMDMA_H
+#define _FRIONOMMU_MEMDMA_H 1
+
+void mem_dma_xmt_enable(void);
+void mem_dma_xmt_disable(void);
+void mem_dma_set_dma_mode(unsigned int channel);
+int mem_dma_xmt_get_dma_residue(void);
+void mem_dma_xmt_clear_dma_ff(void);
+void mem_dma_rcv_clear_dma_ff(void);
+int mem_dma_rcv_get_dma_residue(void);
+void mem_dma_rcv_disable(void);
+void mem_dma_rcv_enable(void);
+void mem_dma_xmt_set_dma_addr(unsigned int addr);
+void mem_dma_rcv_set_dma_addr(unsigned int addr);
+void mem_dma_xmt_set_dma_count(unsigned int count);
+void mem_dma_rcv_set_dma_count(unsigned int count);
+
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/mman.h linux-2.4.29-uc1/include/asm-blackfin/mman.h
--- linux-2.4.29/include/asm-blackfin/mman.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/mman.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,38 @@
+#ifndef __FRIO_MMAN_H__
+#define __FRIO_MMAN_H__
+
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_NONE	0x0		/* page can not be accessed */
+
+#define MAP_SHARED	0x01		/* Share changes */
+#define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_TYPE	0x0f		/* Mask for type of mapping */
+#define MAP_FIXED	0x10		/* Interpret addr exactly */
+#define MAP_ANONYMOUS	0x20		/* don't use a file */
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
+#define MAP_LOCKED	0x2000		/* pages are locked */
+#define MAP_NORESERVE	0x4000		/* don't check for reservations */
+
+#define MS_ASYNC	1		/* sync memory asynchronously */
+#define MS_INVALIDATE	2		/* invalidate the caches */
+#define MS_SYNC		4		/* synchronous memory sync */
+
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
+
+#define MADV_NORMAL	0x0		/* default page-in behavior */
+#define MADV_RANDOM	0x1		/* page-in minimum required */
+#define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
+#define MADV_WILLNEED	0x3		/* pre-fault pages */
+#define MADV_DONTNEED	0x4		/* discard these pages */
+
+/* compatibility flags */
+#define MAP_ANON	MAP_ANONYMOUS
+#define MAP_FILE	0
+
+#endif /* __FRIO_MMAN_H__ */
diff -urN linux-2.4.29/include/asm-blackfin/mmu_context.h linux-2.4.29-uc1/include/asm-blackfin/mmu_context.h
--- linux-2.4.29/include/asm-blackfin/mmu_context.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/mmu_context.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef __FRIONOMMU_MMU_CONTEXT_H
+#define __FRIONOMMU_MMU_CONTEXT_H
+
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
+{
+}
+
+extern inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	// mm->context = virt_to_phys(mm->pgd);
+	return(0);
+}
+
+#define destroy_context(mm)		do { } while(0)
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu)
+{
+}
+
+extern inline void activate_mm(struct mm_struct *prev_mm,
+			       struct mm_struct *next_mm)
+{
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/mmu.h linux-2.4.29-uc1/include/asm-blackfin/mmu.h
--- linux-2.4.29/include/asm-blackfin/mmu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/mmu.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,7 @@
+#ifndef __MMU_H
+#define __MMU_H
+
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_t;
+
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/module.h linux-2.4.29-uc1/include/asm-blackfin/module.h
--- linux-2.4.29/include/asm-blackfin/module.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/module.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,13 @@
+/* changes origined from m68k.....   Lineo, Inc		May 2001  */
+
+#ifndef _ASM_FRIO_MODULE_H
+#define _ASM_FRIO_MODULE_H
+/*
+ * This file contains the frio architecture specific module code.
+ */
+
+#define module_map(x)		vmalloc(x)
+#define module_unmap(x)		vfree(x)
+#define module_arch_init(x)	(0)
+
+#endif /* _ASM_FRIO_MODULE_H */
diff -urN linux-2.4.29/include/asm-blackfin/msgbuf.h linux-2.4.29-uc1/include/asm-blackfin/msgbuf.h
--- linux-2.4.29/include/asm-blackfin/msgbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/msgbuf.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef _FRIO_MSGBUF_H
+#define _FRIO_MSGBUF_H
+
+/* 
+ * The msqid64_ds structure for m68k architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm msg_perm;
+	__kernel_time_t msg_stime;	/* last msgsnd time */
+	unsigned long	__unused1;
+	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	unsigned long	__unused2;
+	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned long	__unused3;
+	unsigned long  msg_cbytes;	/* current number of bytes on queue */
+	unsigned long  msg_qnum;	/* number of messages in queue */
+	unsigned long  msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t msg_lrpid;	/* last receive pid */
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+#endif /* _FRIO_MSGBUF_H */
diff -urN linux-2.4.29/include/asm-blackfin/namei.h linux-2.4.29-uc1/include/asm-blackfin/namei.h
--- linux-2.4.29/include/asm-blackfin/namei.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/namei.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,19 @@
+/*
+ * linux/include/asm-m68k/namei.h
+ *
+ * Included from linux/fs/namei.c
+ *
+ * Changes made by Lineo Inc.    May 2001
+ */
+
+#ifndef __FRIO_NAMEI_H
+#define __FRIO_NAMEI_H
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+
+#define __emul_prefix() NULL
+
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/openprom.h linux-2.4.29-uc1/include/asm-blackfin/openprom.h
--- linux-2.4.29/include/asm-blackfin/openprom.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/openprom.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,311 @@
+/* openprom.h,v 1.19 1996/09/25 03:51:08 davem Exp  */
+#ifndef __SPARC_OPENPROM_H
+#define __SPARC_OPENPROM_H
+
+/* openprom.h:  Prom structures and defines for access to the OPENBOOT
+ *              prom routines and data areas.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <linux/config.h>
+
+/* Empirical constants... */
+#ifdef CONFIG_SUN3
+#define KADB_DEBUGGER_BEGVM     0x0fee0000    /* There is no kadb yet but...*/
+#define LINUX_OPPROM_BEGVM      0x0fef0000
+#define LINUX_OPPROM_ENDVM      0x0ff10000    /* I think this is right - tm */
+#else
+#define KADB_DEBUGGER_BEGVM     0xffc00000    /* Where kern debugger is in virt-mem */
+#define	LINUX_OPPROM_BEGVM	0xffd00000
+#define	LINUX_OPPROM_ENDVM	0xfff00000
+#define	LINUX_OPPROM_MAGIC      0x10010407
+#endif
+
+#ifndef __ASSEMBLY__
+/* V0 prom device operations. */
+struct linux_dev_v0_funcs {
+	int (*v0_devopen)(char *device_str);
+	int (*v0_devclose)(int dev_desc);
+	int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
+	int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
+	int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf);
+	int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf);
+	int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
+	int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
+	int (*v0_seekdev)(int dev_desc, long logical_offst, int from);
+};
+
+/* V2 and later prom device operations. */
+struct linux_dev_v2_funcs {
+	int (*v2_inst2pkg)(int d);	/* Convert ihandle to phandle */
+	char * (*v2_dumb_mem_alloc)(char *va, unsigned sz);
+	void (*v2_dumb_mem_free)(char *va, unsigned sz);
+
+	/* To map devices into virtual I/O space. */
+	char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz);
+	void (*v2_dumb_munmap)(char *virta, unsigned size);
+
+	int (*v2_dev_open)(char *devpath);
+	void (*v2_dev_close)(int d);
+	int (*v2_dev_read)(int d, char *buf, int nbytes);
+	int (*v2_dev_write)(int d, char *buf, int nbytes);
+	int (*v2_dev_seek)(int d, int hi, int lo);
+
+	/* Never issued (multistage load support) */
+	void (*v2_wheee2)(void);
+	void (*v2_wheee3)(void);
+};
+
+struct linux_mlist_v0 {
+	struct linux_mlist_v0 *theres_more;
+	char *start_adr;
+	unsigned num_bytes;
+};
+
+struct linux_mem_v0 {
+	struct linux_mlist_v0 **v0_totphys;
+	struct linux_mlist_v0 **v0_prommap;
+	struct linux_mlist_v0 **v0_available; /* What we can use */
+};
+
+/* Arguments sent to the kernel from the boot prompt. */
+struct linux_arguments_v0 {
+	char *argv[8];
+	char args[100];
+	char boot_dev[2];
+	int boot_dev_ctrl;
+	int boot_dev_unit;
+	int dev_partition;
+	char *kernel_file_name;
+	void *aieee1;           /* XXX */
+};
+
+/* V2 and up boot things. */
+struct linux_bootargs_v2 {
+	char **bootpath;
+	char **bootargs;
+	int *fd_stdin;
+	int *fd_stdout;
+};
+
+#ifdef CONFIG_SUN3
+struct linux_romvec {
+	char		*pv_initsp;		
+	int		(*pv_startmon)(void);
+
+	int		*diagberr;		
+
+	struct linux_arguments_v0 **pv_v0bootargs;
+ 	unsigned	*pv_sun3mem;		
+
+	unsigned char	(*pv_getchar)(void);
+	int		(*pv_putchar)(int ch);
+	int		(*pv_nbgetchar)(void);	
+	int		(*pv_nbputchar)(int ch);
+	unsigned char	*pv_echo;	
+	unsigned char	*pv_insource;
+	unsigned char	*pv_outsink;
+
+	int		(*pv_getkey)(void);		
+	int		(*pv_initgetkey)(void);
+	unsigned int	*pv_translation;
+	unsigned char	*pv_keybid;		
+	int		*pv_screen_x;		
+	int		*pv_screen_y;		
+	struct keybuf	*pv_keybuf;		
+
+	char		*pv_monid;
+
+	/* 
+	 * Frame buffer output and terminal emulation 
+	 */
+
+	int		(*pv_fbwritechar)(char);	
+	int		*pv_fbaddr;		
+	char		**pv_font;		
+	int		(*pv_fbwritestr)(char);	
+
+	void		(*pv_reboot)(char *bootstr);
+
+	/* 
+	 * Line input and parsing 
+	 */
+
+	unsigned char	*pv_linebuf;		
+	unsigned char	**pv_lineptr;		
+	int		*pv_linesize;		
+	int		(*pv_getline)(void);	
+	unsigned char	(*pv_getnextchar)(void);	
+	unsigned char	(*pv_peeknextchar)(void);	
+	int		*pv_fbthere;		
+	int		(*pv_getnum)(void);		
+
+	void		(*pv_printf)(const char *fmt, ...);
+	int		(*pv_printhex)(void);
+
+	unsigned char	*pv_leds;		
+	int		(*pv_setleds)(void);	
+
+	/* 
+	 * Non-maskable interrupt  (nmi) information
+	 */ 
+
+	int		(*pv_nmiaddr)(void);
+	int		(*pv_abortentry)(void);
+	int		*pv_nmiclock;		
+
+	int		*pv_fbtype;
+
+	/* 
+	 * Assorted other things 
+	 */
+
+	unsigned	pv_romvers;
+	struct globram  *pv_globram;		
+	char		*pv_kbdzscc;		
+
+	int		*pv_keyrinit;		
+	unsigned char	*pv_keyrtick; 		
+	unsigned	*pv_memoryavail;	
+	long		*pv_resetaddr;		
+	long		*pv_resetmap;		
+						
+	void		(*pv_halt)(void);	
+	unsigned char	*pv_memorybitmap;	
+	void		(*pv_setctxt)(int ctxt, char *va, int pmeg);
+	void		(*pv_vector_cmd)(void);	
+	int		dummy1z;
+	int		dummy2z;
+	int		dummy3z;
+	int		dummy4z;
+};
+#else
+/* The top level PROM vector. */
+struct linux_romvec {
+	/* Version numbers. */
+	unsigned int pv_magic_cookie;
+	unsigned int pv_romvers;
+	unsigned int pv_plugin_revision;
+	unsigned int pv_printrev;
+
+	/* Version 0 memory descriptors. */
+	struct linux_mem_v0 pv_v0mem;
+
+	/* Node operations. */
+	struct linux_nodeops *pv_nodeops;
+
+	char **pv_bootstr;
+	struct linux_dev_v0_funcs pv_v0devops;
+
+	char *pv_stdin;
+	char *pv_stdout;
+#define	PROMDEV_KBD	0		/* input from keyboard */
+#define	PROMDEV_SCREEN	0		/* output to screen */
+#define	PROMDEV_TTYA	1		/* in/out to ttya */
+#define	PROMDEV_TTYB	2		/* in/out to ttyb */
+
+	/* Blocking getchar/putchar.  NOT REENTRANT! (grr) */
+	int (*pv_getchar)(void);
+	void (*pv_putchar)(int ch);
+
+	/* Non-blocking variants. */
+	int (*pv_nbgetchar)(void);
+	int (*pv_nbputchar)(int ch);
+
+	void (*pv_putstr)(char *str, int len);
+
+	/* Miscellany. */
+	void (*pv_reboot)(char *bootstr);
+	void (*pv_printf)(__const__ char *fmt, ...);
+	void (*pv_abort)(void);
+	__volatile__ int *pv_ticks;
+	void (*pv_halt)(void);
+	void (**pv_synchook)(void);
+
+	/* Evaluate a forth string, not different proto for V0 and V2->up. */
+	union {
+		void (*v0_eval)(int len, char *str);
+		void (*v2_eval)(char *str);
+	} pv_fortheval;
+
+	struct linux_arguments_v0 **pv_v0bootargs;
+
+	/* Get ether address. */
+	unsigned int (*pv_enaddr)(int d, char *enaddr);
+
+	struct linux_bootargs_v2 pv_v2bootargs;
+	struct linux_dev_v2_funcs pv_v2devops;
+
+	int filler[15];
+
+	/* This one is sun4c/sun4 only. */
+	void (*pv_setctxt)(int ctxt, char *va, int pmeg);
+
+	/* Prom version 3 Multiprocessor routines. This stuff is crazy.
+	 * No joke. Calling these when there is only one cpu probably
+	 * crashes the machine, have to test this. :-)
+	 */
+
+	/* v3_cpustart() will start the cpu 'whichcpu' in mmu-context
+	 * 'thiscontext' executing at address 'prog_counter'
+	 */
+	int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr,
+			   int thiscontext, char *prog_counter);
+
+	/* v3_cpustop() will cause cpu 'whichcpu' to stop executing
+	 * until a resume cpu call is made.
+	 */
+	int (*v3_cpustop)(unsigned int whichcpu);
+
+	/* v3_cpuidle() will idle cpu 'whichcpu' until a stop or
+	 * resume cpu call is made.
+	 */
+	int (*v3_cpuidle)(unsigned int whichcpu);
+
+	/* v3_cpuresume() will resume processor 'whichcpu' executing
+	 * starting with whatever 'pc' and 'npc' were left at the
+	 * last 'idle' or 'stop' call.
+	 */
+	int (*v3_cpuresume)(unsigned int whichcpu);
+};
+#endif
+
+/* Routines for traversing the prom device tree. */
+struct linux_nodeops {
+	int (*no_nextnode)(int node);
+	int (*no_child)(int node);
+	int (*no_proplen)(int node, char *name);
+	int (*no_getprop)(int node, char *name, char *val);
+	int (*no_setprop)(int node, char *name, char *val, int len);
+	char * (*no_nextprop)(int node, char *name);
+};
+
+/* More fun PROM structures for device probing. */
+#define PROMREG_MAX     16
+#define PROMVADDR_MAX   16
+#define PROMINTR_MAX    15
+
+struct linux_prom_registers {
+	int which_io;         /* is this in OBIO space? */
+	char *phys_addr;      /* The physical address of this register */
+	int reg_size;         /* How many bytes does this register take up? */
+};
+
+struct linux_prom_irqs {
+	int pri;    /* IRQ priority */
+	int vector; /* This is foobar, what does it do? */
+};
+
+/* Element of the "ranges" vector */
+struct linux_prom_ranges {
+	unsigned int ot_child_space;
+	unsigned int ot_child_base;		/* Bus feels this */
+	unsigned int ot_parent_space;
+	unsigned int ot_parent_base;		/* CPU looks from here */
+	unsigned int or_size;
+};
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__SPARC_OPENPROM_H) */
diff -urN linux-2.4.29/include/asm-blackfin/oplib.h linux-2.4.29-uc1/include/asm-blackfin/oplib.h
--- linux-2.4.29/include/asm-blackfin/oplib.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/oplib.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,294 @@
+/* oplib.h  1996/10/31 06:29:13 davem Exp 
+ * oplib.h:  Describes the interface and available routines in the
+ *           Linux Prom library.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __SPARC_OPLIB_H
+#define __SPARC_OPLIB_H
+
+#include <asm/openprom.h>
+
+/* The master romvec pointer... */
+extern struct linux_romvec *romvec;
+
+/* Enumeration to describe the prom major version we have detected. */
+enum prom_major_version {
+	PROM_V0,      /* Original sun4c V0 prom */
+	PROM_V2,      /* sun4c and early sun4m V2 prom */
+	PROM_V3,      /* sun4m and later, up to sun4d/sun4e machines V3 */
+	PROM_P1275,   /* IEEE compliant ISA based Sun PROM, only sun4u */
+        PROM_AP1000,  /* actually no prom at all */
+};
+
+extern enum prom_major_version prom_vers;
+/* Revision, and firmware revision. */
+extern unsigned int prom_rev, prom_prev;
+
+/* Root node of the prom device tree, this stays constant after
+ * initialization is complete.
+ */
+extern int prom_root_node;
+
+/* Pointer to prom structure containing the device tree traversal
+ * and usage utility functions.  Only prom-lib should use these,
+ * users use the interface defined by the library only!
+ */
+extern struct linux_nodeops *prom_nodeops;
+
+/* The functions... */
+
+/* You must call prom_init() before using any of the library services,
+ * preferably as early as possible.  Pass it the romvec pointer.
+ */
+extern void prom_init(struct linux_romvec *rom_ptr);
+
+/* Boot argument acquisition, returns the boot command line string. */
+extern char *prom_getbootargs(void);
+
+/* Device utilities. */
+
+/* Map and unmap devices in IO space at virtual addresses. Note that the
+ * virtual address you pass is a request and the prom may put your mappings
+ * somewhere else, so check your return value as that is where your new
+ * mappings really are!
+ *
+ * Another note, these are only available on V2 or higher proms!
+ */
+extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes);
+extern void prom_unmapio(char *virt_addr, unsigned int num_bytes);
+
+/* Device operations. */
+
+/* Open the device described by the passed string.  Note, that the format
+ * of the string is different on V0 vs. V2->higher proms.  The caller must
+ * know what he/she is doing!  Returns the device descriptor, an int.
+ */
+extern int prom_devopen(char *device_string);
+
+/* Close a previously opened device described by the passed integer
+ * descriptor.
+ */
+extern int prom_devclose(int device_handle);
+
+/* Do a seek operation on the device described by the passed integer
+ * descriptor.
+ */
+extern void prom_seek(int device_handle, unsigned int seek_hival,
+		      unsigned int seek_lowval);
+
+/* Machine memory configuration routine. */
+
+/* This function returns a V0 format memory descriptor table, it has three
+ * entries.  One for the total amount of physical ram on the machine, one
+ * for the amount of physical ram available, and one describing the virtual
+ * areas which are allocated by the prom.  So, in a sense the physical
+ * available is a calculation of the total physical minus the physical mapped
+ * by the prom with virtual mappings.
+ *
+ * These lists are returned pre-sorted, this should make your life easier
+ * since the prom itself is way too lazy to do such nice things.
+ */
+extern struct linux_mem_v0 *prom_meminfo(void);
+
+/* Miscellaneous routines, don't really fit in any category per se. */
+
+/* Reboot the machine with the command line passed. */
+extern void prom_reboot(char *boot_command);
+
+/* Evaluate the forth string passed. */
+extern void prom_feval(char *forth_string);
+
+/* Enter the prom, with possibility of continuation with the 'go'
+ * command in newer proms.
+ */
+extern void prom_cmdline(void);
+
+/* Enter the prom, with no chance of continuation for the stand-alone
+ * which calls this.
+ */
+extern void prom_halt(void);
+
+/* Set the PROM 'sync' callback function to the passed function pointer.
+ * When the user gives the 'sync' command at the prom prompt while the
+ * kernel is still active, the prom will call this routine.
+ *
+ * XXX The arguments are different on V0 vs. V2->higher proms, grrr! XXX
+ */
+typedef void (*sync_func_t)(void);
+extern void prom_setsync(sync_func_t func_ptr);
+
+/* Acquire the IDPROM of the root node in the prom device tree.  This
+ * gets passed a buffer where you would like it stuffed.  The return value
+ * is the format type of this idprom or 0xff on error.
+ */
+extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
+
+/* Get the prom major version. */
+extern int prom_version(void);
+
+/* Get the prom plugin revision. */
+extern int prom_getrev(void);
+
+/* Get the prom firmware revision. */
+extern int prom_getprev(void);
+
+/* Character operations to/from the console.... */
+
+/* Non-blocking get character from console. */
+extern int prom_nbgetchar(void);
+
+/* Non-blocking put character to console. */
+extern int prom_nbputchar(char character);
+
+/* Blocking get character from console. */
+extern char prom_getchar(void);
+
+/* Blocking put character to console. */
+extern void prom_putchar(char character);
+
+/* Query for input device type */
+
+enum prom_input_device {
+	PROMDEV_IKBD,			/* input from keyboard */
+	PROMDEV_ITTYA,			/* input from ttya */
+	PROMDEV_ITTYB,			/* input from ttyb */
+	PROMDEV_I_UNK,
+};
+
+extern enum prom_input_device prom_query_input_device(void);
+
+/* Query for output device type */
+
+enum prom_output_device {
+	PROMDEV_OSCREEN,		/* to screen */
+	PROMDEV_OTTYA,			/* to ttya */
+	PROMDEV_OTTYB,			/* to ttyb */
+	PROMDEV_O_UNK,
+};
+
+extern enum prom_output_device prom_query_output_device(void);
+
+/* Multiprocessor operations... */
+
+/* Start the CPU with the given device tree node, context table, and context
+ * at the passed program counter.
+ */
+extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table,
+			 int context, char *program_counter);
+
+/* Stop the CPU with the passed device tree node. */
+extern int prom_stopcpu(int cpunode);
+
+/* Idle the CPU with the passed device tree node. */
+extern int prom_idlecpu(int cpunode);
+
+/* Re-Start the CPU with the passed device tree node. */
+extern int prom_restartcpu(int cpunode);
+
+/* PROM memory allocation facilities... */
+
+/* Allocated at possibly the given virtual address a chunk of the
+ * indicated size.
+ */
+extern char *prom_alloc(char *virt_hint, unsigned int size);
+
+/* Free a previously allocated chunk. */
+extern void prom_free(char *virt_addr, unsigned int size);
+
+/* Sun4/sun4c specific memory-management startup hook. */
+
+/* Map the passed segment in the given context at the passed
+ * virtual address.
+ */
+extern void prom_putsegment(int context, unsigned long virt_addr,
+			    int physical_segment);
+
+/* PROM device tree traversal functions... */
+
+/* Get the child node of the given node, or zero if no child exists. */
+extern int prom_getchild(int parent_node);
+
+/* Get the next sibling node of the given node, or zero if no further
+ * siblings exist.
+ */
+extern int prom_getsibling(int node);
+
+/* Get the length, at the passed node, of the given property type.
+ * Returns -1 on error (ie. no such property at this node).
+ */
+extern int prom_getproplen(int thisnode, char *property);
+
+/* Fetch the requested property using the given buffer.  Returns
+ * the number of bytes the prom put into your buffer or -1 on error.
+ */
+extern int prom_getproperty(int thisnode, char *property,
+			    char *prop_buffer, int propbuf_size);
+
+/* Acquire an integer property. */
+extern int prom_getint(int node, char *property);
+
+/* Acquire an integer property, with a default value. */
+extern int prom_getintdefault(int node, char *property, int defval);
+
+/* Acquire a boolean property, 0=FALSE 1=TRUE. */
+extern int prom_getbool(int node, char *prop);
+
+/* Acquire a string property, null string on error. */
+extern void prom_getstring(int node, char *prop, char *buf, int bufsize);
+
+/* Does the passed node have the given "name"? YES=1 NO=0 */
+extern int prom_nodematch(int thisnode, char *name);
+
+/* Puts in buffer a prom name in the form name@x,y or name (x for which_io 
+ * and y for first regs phys address
+ */
+extern int prom_getname(int node, char *buf, int buflen);
+
+/* Search all siblings starting at the passed node for "name" matching
+ * the given string.  Returns the node on success, zero on failure.
+ */
+extern int prom_searchsiblings(int node_start, char *name);
+
+/* Return the first property type, as a string, for the given node.
+ * Returns a null string on error.
+ */
+extern char *prom_firstprop(int node);
+
+/* Returns the next property after the passed property for the given
+ * node.  Returns null string on failure.
+ */
+extern char *prom_nextprop(int node, char *prev_property);
+
+/* Returns 1 if the specified node has given property. */
+extern int prom_node_has_property(int node, char *property);
+
+/* Set the indicated property at the given node with the passed value.
+ * Returns the number of bytes of your value that the prom took.
+ */
+extern int prom_setprop(int node, char *prop_name, char *prop_value,
+			int value_size);
+			
+extern int prom_pathtoinode(char *path);
+extern int prom_inst2pkg(int);
+
+/* Dorking with Bus ranges... */
+
+/* Adjust reg values with the passed ranges. */
+extern void prom_adjust_regs(struct linux_prom_registers *regp, int nregs,
+			     struct linux_prom_ranges *rangep, int nranges);
+
+/* Adjust child ranges with the passed parent ranges. */
+extern void prom_adjust_ranges(struct linux_prom_ranges *cranges, int ncranges,
+			       struct linux_prom_ranges *pranges, int npranges);
+
+/* Apply promlib probed OBIO ranges to registers. */
+extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs);
+
+/* Apply ranges of any prom node (and optionally parent node as well) to registers. */
+extern void prom_apply_generic_ranges(int node, int parent, 
+				      struct linux_prom_registers *sbusregs, int nregs);
+				   
+
+#endif /* !(__SPARC_OPLIB_H) */
diff -urN linux-2.4.29/include/asm-blackfin/page.h linux-2.4.29-uc1/include/asm-blackfin/page.h
--- linux-2.4.29/include/asm-blackfin/page.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/page.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,102 @@
+#ifndef _FRIONOMMU_PAGE_H
+#define _FRIONOMMU_PAGE_H
+
+#include <linux/config.h>
+
+/* PAGE_SHIFT determines the page size */
+
+#define PAGE_SHIFT	(12)
+#define PAGE_SIZE	(4096)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+
+#ifdef __KERNEL__
+
+#include <asm/setup.h>
+
+#if PAGE_SHIFT < 13
+#define KTHREAD_SIZE (8192)
+#else
+#define KTHREAD_SIZE PAGE_SIZE
+#endif
+ 
+#ifndef __ASSEMBLY__
+ 
+#define get_user_page(vaddr)		__get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr)	free_page(addr)
+
+#define clear_page(page)	memset((page), 0, PAGE_SIZE)
+#define copy_page(to,from)	memcpy((to), (from), PAGE_SIZE)
+
+#define clear_user_page(page, vaddr)	clear_page(page)
+#define copy_user_page(to, from, vaddr)	copy_page(to, from)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pmd[16]; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)	((x).pte)
+#define pmd_val(x)	((&x)->pmd[0])
+#define pgd_val(x)	((x).pgd)
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x)	((pte_t) { (x) } )
+#define __pmd(x)	((pmd_t) { (x) } )
+#define __pgd(x)	((pgd_t) { (x) } )
+#define __pgprot(x)	((pgprot_t) { (x) } )
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+/* Pure 2^n version of get_order */
+extern __inline__ int get_order(unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#include <asm/page_offset.h>
+
+#define PAGE_OFFSET		(PAGE_OFFSET_RAW)
+
+#ifndef __ASSEMBLY__
+
+#define __pa(vaddr)		virt_to_phys((void *)vaddr)
+#define __va(paddr)		phys_to_virt((unsigned long)paddr)
+
+#define MAP_NR(addr)		(((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
+#define virt_to_page(addr)	(mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
+#define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
+
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	/* asm volatile ("halt"); */ /* FIXME */ /* panic("BUG!"); */ \
+        while (1);	/* dead-loop */ \
+} while (0)
+
+#define PAGE_BUG(page) do { \
+	BUG(); \
+} while (0)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+/*
+ * To get page_address to do the right thing, define WANT_PAGE_VIRTUAL
+ */
+#define WANT_PAGE_VIRTUAL 1
+
+#endif /* _FRIONOMMU_PAGE_H */
diff -urN linux-2.4.29/include/asm-blackfin/page_offset.h linux-2.4.29-uc1/include/asm-blackfin/page_offset.h
--- linux-2.4.29/include/asm-blackfin/page_offset.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/page_offset.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,10 @@
+/* Changes made by Akbar Hussain April 10, 2001 */
+
+#include <linux/config.h>
+
+/* This handles the memory map.. */
+
+#ifdef CONFIG_BLACKFIN
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+
diff -urN linux-2.4.29/include/asm-blackfin/param.h linux-2.4.29-uc1/include/asm-blackfin/param.h
--- linux-2.4.29/include/asm-blackfin/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/param.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,24 @@
+#ifndef _FRIONOMMU_PARAM_H
+#define _FRIONOMMU_PARAM_H
+
+#include <linux/config.h>
+
+#ifndef HZ
+#ifdef CONFIG_BLACKFIN
+#define HZ 100		/* need changes accordingly	*/
+#endif
+#endif
+
+#define EXEC_PAGESIZE	4096
+
+#ifndef NGROUPS
+#define NGROUPS		32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#endif /* _FRIONOMMU_PARAM_H */
diff -urN linux-2.4.29/include/asm-blackfin/pci.h linux-2.4.29-uc1/include/asm-blackfin/pci.h
--- linux-2.4.29/include/asm-blackfin/pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/pci.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,148 @@
+/* Changed from asm-m68k version, Lineo Inc. 	May 2001	*/
+
+#ifndef _ASM_FRIO_PCI_H
+#define _ASM_FRIO_PCI_H
+
+/*
+ * asm-m68k/pci_m68k.h - m68k specific PCI declarations.
+ *
+ * Written by Wout Klaren.
+ */
+
+/* Added by Chang Junxiao */
+#define PCIBIOS_MIN_IO 0x00001000
+#define PCIBIOS_MIN_MEM 0x10000000
+
+struct pci_ops;
+
+/*
+ * Structure with hardware dependent information and functions of the
+ * PCI bus.
+ */
+
+struct pci_bus_info
+{
+	/*
+	 * Resources of the PCI bus.
+	 */
+
+	struct resource mem_space;
+	struct resource io_space;
+
+	/*
+	 * System dependent functions.
+	 */
+
+	struct pci_ops *frio_pci_ops;
+
+	void (*fixup)(int pci_modify);
+	void (*conf_device)(unsigned char bus, unsigned char device_fn);
+};
+
+#define pcibios_assign_all_busses()	0
+
+extern inline void pcibios_set_master(struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling */
+}
+
+extern inline void pcibios_penalize_isa_irq(int irq)
+{
+	/* We don't do dynamic PCI IRQ allocation */
+}
+
+
+extern inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+					size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+	// return virt_to_bus(ptr);
+	return (dma_addr_t) ptr;
+}
+
+/* Unmap a single streaming mode DMA translation.  The dma_addr and size
+ * must match what was provided for in a previous pci_map_single call.  All
+ * other usages are undefined.
+ *
+ * After this call, reads by the cpu to the buffer are guarenteed to see
+ * whatever the device wrote there.
+ */
+extern inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+				    size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+	/* Nothing to do */
+}
+
+/* Map a set of buffers described by scatterlist in streaming
+ * mode for DMA.  This is the scather-gather version of the
+ * above pci_map_single interface.  Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length.  They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ *       DMA address/length pairs than there are SG table elements.
+ *       (for example via virtual mapping capabilities)
+ *       The routine returns the number of addr/length pairs actually
+ *       used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+extern inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+			     int nents, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+	return nents;
+}
+
+/* Unmap a set of streaming mode DMA translations.
+ * Again, cpu read rules concerning calls here are the same as for
+ * pci_unmap_single() above.
+ */
+extern inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+				int nents, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+	/* Nothing to do */
+}
+
+/* Make physical memory consistent for a single
+ * streaming mode DMA translation after a transfer.
+ *
+ * If you perform a pci_map_single() but wish to interrogate the
+ * buffer using the cpu, yet do not wish to teardown the PCI dma
+ * mapping, you must call this function before doing so.  At the
+ * next point you give the PCI dma address back to the card, the
+ * device again owns the buffer.
+ */
+extern inline void pci_dma_sync_single(struct pci_dev *hwdev,
+				       dma_addr_t dma_handle,
+				       size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+	/* Nothing to do */
+}
+
+/* Make physical memory consistent for a set of streaming
+ * mode DMA translations after a transfer.
+ *
+ * The same as pci_dma_sync_single but for a scatter-gather list,
+ * same rules and usage.
+ */
+extern inline void pci_dma_sync_sg(struct pci_dev *hwdev,
+				   struct scatterlist *sg,
+				   int nelems, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+	/* Nothing to do */
+}
+
+
+#endif /* _ASM_FRIO_PCI_H */
diff -urN linux-2.4.29/include/asm-blackfin/pgalloc.h linux-2.4.29-uc1/include/asm-blackfin/pgalloc.h
--- linux-2.4.29/include/asm-blackfin/pgalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/pgalloc.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,112 @@
+#ifndef _FRIONOMMU_PGALLOC_H
+#define _FRIONOMMU_PGALLOC_H
+
+/*
+ * Copyright (C) 2000 Lineo, David McCullough <davidm@lineo.com>
+ */
+
+#include <asm/setup.h>
+#include <asm/virtconvert.h>
+
+/*
+ * Cache handling functions
+ */
+
+#if DAVIDM
+/*
+ * invalidate the cache for the specified memory range.
+ * It starts at the physical address specified for
+ * the given number of bytes.
+ */
+extern void cache_clear(unsigned long paddr, int len);
+
+/*
+ * push any dirty cache in the specified memory range.
+ * It starts at the physical address specified for
+ * the given number of bytes.
+ */
+extern void cache_push(unsigned long paddr, int len);
+
+/*
+ * push and invalidate pages in the specified user virtual
+ * memory range.
+ */
+extern void cache_push_v(unsigned long vaddr, int len);
+
+/* cache code */
+#define FLUSH_I_AND_D	(0x00000808)
+#define FLUSH_I 	(0x00000008)
+
+/* This is needed whenever the virtual mapping of the current
+   process changes.  */
+#endif
+
+static inline void __flush_cache_all(void)
+{
+}
+
+#define flush_cache_all()				__flush_cache_all()
+#define flush_cache_mm(mm)				__flush_cache_all()
+#define flush_cache_range(mm, start, end)		__flush_cache_all()
+#define flush_cache_page(vma, vmaddr)			__flush_cache_all()
+#define flush_page_to_ram(page)				__flush_cache_all()
+#define flush_dcache_page(page)				__flush_cache_all()
+#define flush_icache_range(start, end)			__flush_cache_all()
+#define flush_icache_user_range(vma,pg,addr,len)	__flush_cache_all()
+#define flush_icache_page(vma,pg)			__flush_cache_all()
+#define flush_icache()					__flush_cache_all()
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+	printk("%s,%d: called %s!\n", __FILE__,  __LINE__, __FUNCTION__);
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+	printk("%s,%d: called %s!\n", __FILE__,  __LINE__, __FUNCTION__);
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * DAVIDM - the rest of these are just so I can check where they happen
+ */
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+	printk("%s,%d: DAVIDM called %s!\n", __FILE__,  __LINE__, __FUNCTION__);
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+	printk("%s,%d: DAVIDM called %s!\n", __FILE__,  __LINE__, __FUNCTION__);
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+	printk("%s,%d: DAVIDM called %s!\n", __FILE__,  __LINE__, __FUNCTION__);
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+				   unsigned long start, unsigned long end)
+{
+	printk("%s,%d: DAVIDM called %s!\n", __FILE__,  __LINE__, __FUNCTION__);
+}
+
+static inline void flush_tlb_kernel_page(unsigned long addr)
+{
+	printk("%s,%d: DAVIDM called %s!\n", __FILE__,  __LINE__, __FUNCTION__);
+}
+
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
+				      unsigned long start, unsigned long end)
+{
+	printk("%s,%d: DAVIDM called %s!\n", __FILE__,  __LINE__, __FUNCTION__);
+}
+
+#endif /* _FRIONOMMU_PGALLOC_H */
diff -urN linux-2.4.29/include/asm-blackfin/pgtable.h linux-2.4.29-uc1/include/asm-blackfin/pgtable.h
--- linux-2.4.29/include/asm-blackfin/pgtable.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/pgtable.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,28 @@
+#ifndef _FRIONOMMU_PGTABLE_H
+#define _FRIONOMMU_PGTABLE_H
+
+#include <linux/config.h>
+#include <asm/setup.h>
+
+/* XXX: defined in <linux/mm.h>
+#define page_address(page)   ({ if (!(page)->virtual) BUG(); (page)->virtual;})
+*/
+/* XXX: defined in <asm/virtconvert.h>
+#define __page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+*/
+#define kern_addr_valid(addr) (1)
+
+#define PAGE_NONE		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_SHARED		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_COPY		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_READONLY		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_KERNEL		__pgprot(0)    /* these mean nothing to NO_MM */
+
+extern void paging_init(void);
+
+/*
+ * No page table caches to initialise.
+ */
+#define pgtable_cache_init()	do {} while (0)
+
+#endif /* _FRIONOMMU_PGTABLE_H */
diff -urN linux-2.4.29/include/asm-blackfin/poll.h linux-2.4.29-uc1/include/asm-blackfin/poll.h
--- linux-2.4.29/include/asm-blackfin/poll.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/poll.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,22 @@
+#ifndef __FRIO_POLL_H
+#define __FRIO_POLL_H
+
+#define POLLIN		  1
+#define POLLPRI		  2
+#define POLLOUT		  4
+#define POLLERR		  8
+#define POLLHUP		 16
+#define POLLNVAL	 32
+#define POLLRDNORM	 64
+#define POLLWRNORM	POLLOUT
+#define POLLRDBAND	128
+#define POLLWRBAND	256
+#define POLLMSG		0x0400
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+#endif	/* __FRIO_POLL_H */
diff -urN linux-2.4.29/include/asm-blackfin/posix_types.h linux-2.4.29-uc1/include/asm-blackfin/posix_types.h
--- linux-2.4.29/include/asm-blackfin/posix_types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/posix_types.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,63 @@
+#ifndef __ARCH_FRIO_POSIX_TYPES_H
+#define __ARCH_FRIO_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned short	__kernel_dev_t;
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned short	__kernel_mode_t;
+typedef unsigned short	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
+typedef unsigned short	__kernel_uid_t;
+typedef unsigned short	__kernel_gid_t;
+typedef unsigned int	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+typedef unsigned short	__kernel_old_uid_t;
+typedef unsigned short	__kernel_old_gid_t;
+
+#ifdef __GNUC__
+typedef long long	__kernel_loff_t;
+#endif
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+	int	val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+	int	__val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#undef	__FD_SET
+#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+
+#undef	__FD_CLR
+#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+
+#undef	__FD_ISSET
+#define	__FD_ISSET(d, set)	((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
+
+#undef	__FD_ZERO
+#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/processor.h linux-2.4.29-uc1/include/asm-blackfin/processor.h
--- linux-2.4.29/include/asm-blackfin/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/processor.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,152 @@
+/* Changes made by Akbar Hussain Lineo, Inc, May 2001 for FRIO */
+
+
+/*
+ * include/asm-m68k/processor.h
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+ */
+
+#ifndef __ASM_FRIO_PROCESSOR_H
+#define __ASM_FRIO_PROCESSOR_H
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#include <linux/config.h>
+#include <asm/segment.h>
+/*   #include <asm/fpu.h>	*/
+#include <asm/ptrace.h>
+#include <asm/current.h>
+
+extern inline unsigned long rdusp(void) {
+  	unsigned long usp;
+
+	__asm__ __volatile__("%0 = usp;\n\t" : "=da" (usp));
+	return usp;
+}
+
+extern inline void wrusp(unsigned long usp) {
+	__asm__ __volatile__("usp = %0;\n\t" : : "da" (usp));
+}
+
+/*
+ * User space process size: 3.75GB. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.
+ */
+#define TASK_SIZE	(0xF0000000UL)
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define MCA_bus 0
+
+/*  There is no pc register avaliable for FRIO, so we are going to get
+    it indirectly   */
+
+#if 0
+inline unsigned long obtain_pc_indirectly (void)
+{
+	unsigned long pc;
+	__asm__ __volatile__ ("%0 = rets;\n" : "=d" (pc));
+	return (pc - 4);	/* call pcrel24 is 4 bytes long  */
+}
+#endif
+
+/* 
+ * if you change this structure, you must change the code and offsets
+ * in m68k/machasm.S
+ */
+   
+struct thread_struct {
+	unsigned long  ksp;		/* kernel stack pointer */
+	unsigned long  usp;		/* user stack pointer */
+	unsigned short seqstat;		/* saved status register */
+	unsigned long  esp0;		/* points to SR of stack frame pt_regs*/
+	unsigned long  pc;		/* instruction pointer */
+};
+
+#define INIT_MMAP { &init_mm, 0, 0x40000000, NULL, __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED), VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
+
+#define INIT_THREAD  { \
+	sizeof(init_stack) + (unsigned long) init_stack, 0, \
+	PS_S, 0\
+}
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ *
+ * pass the data segment into user programs if it exists,
+ * it can't hurt anything as far as I can tell
+ */
+#define start_thread(_regs, _pc, _usp)           \
+do {                                             \
+	set_fs(USER_DS); /* reads from user space */ \
+	(_regs)->pc = (_pc);                         \
+	if (current->mm)                             \
+		(_regs)->r5 = current->mm->start_data;   \
+	(_regs)->seqstat &= ~0x0c00;                      \
+	wrusp(_usp);                                 \
+	/* Adde by HuTao, May 26, 2003 3:39PM */\
+	if ((_regs)->ipend & 0x8000) /* check whether system in supper mode - StChen */\
+		(_regs)->ipend = 0x0;\
+} while(0)
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+#define copy_segments(tsk, mm)		do { } while (0)
+#define release_segments(mm)		do { } while (0)
+#define forget_segments()		do { } while (0)
+
+/*
+ * Free current thread data structures etc..
+ */
+static inline void exit_thread(void)
+{
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+extern inline unsigned long thread_saved_pc(struct thread_struct *t)
+{
+	extern void scheduling_functions_start_here(void);
+	extern void scheduling_functions_end_here(void);
+	return 0;
+}
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define	KSTK_EIP(tsk)	\
+    ({			\
+	unsigned long eip = 0;	 \
+	if ((tsk)->thread.esp0 > PAGE_SIZE && \
+	    MAP_NR((tsk)->thread.esp0) < max_mapnr) \
+	      eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
+	eip; })
+#define	KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->thread.usp)
+
+#define THREAD_SIZE (2*PAGE_SIZE)
+
+/* Allocation and freeing of basic task resources. */
+#define alloc_task_struct() \
+	((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
+#define free_task_struct(p)	free_pages((unsigned long)(p),1)
+#define get_task_struct(tsk)      atomic_inc(&mem_map[MAP_NR(tsk)].count)
+
+#define init_task	(init_task_union.task)
+#define init_stack	(init_task_union.stack)
+
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/ptrace.h linux-2.4.29-uc1/include/asm-blackfin/ptrace.h
--- linux-2.4.29/include/asm-blackfin/ptrace.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/ptrace.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,248 @@
+#ifndef _FRIO_PTRACE_H
+#define _FRIO_PTRACE_H
+
+#define NEW_PT_REGS
+
+/*
+ * GCC defines register number like this:
+ * -----------------------------
+ *       0 - 7 are data registers R0-R7
+ *       8 - 15 are address registers P0-P7
+ *      16 - 31 dsp registers I/B/L0 -- I/B/L3 & M0--M3
+ *      32 - 33 A registers A0 & A1
+ *      34 -    status register
+ * -----------------------------
+ *
+ * We follows above, except:
+ *      32-33 --- Low 32-bit of A0&1
+ *      34-35 --- High 8-bit of A0&1
+ */
+
+#if defined(NEW_PT_REGS)
+
+#define PT_IPEND	0
+#define PT_SYSCFG	(PT_IPEND+4)
+#define PT_SEQSTAT	(PT_SYSCFG+4)
+#define PT_RETE		(PT_SEQSTAT+4)
+#define PT_RETN		(PT_RETE+4)
+#define PT_RETX		(PT_RETN+4)
+#define PT_RETI		(PT_RETX+4)
+#define PT_PC		PT_RETI
+#define PT_RETS		(PT_RETI+4)
+#define PT_RESERVED	(PT_RETS+4)
+#define PT_ASTAT	(PT_RESERVED+4)
+#define PT_LB1		(PT_ASTAT+4)
+#define PT_LB0		(PT_LB1+4)
+#define PT_LT1		(PT_LB0+4)
+#define PT_LT0		(PT_LT1+4)
+#define PT_LC1		(PT_LT0+4)
+#define PT_LC0		(PT_LC1+4)
+#define PT_A1W		(PT_LC0+4)
+#define PT_A1X		(PT_A1W+4)
+#define PT_A0W		(PT_A1X+4)
+#define PT_A0X		(PT_A0W+4)
+#define PT_B3		(PT_A0X+4)
+#define PT_B2		(PT_B3+4)
+#define PT_B1		(PT_B2+4)
+#define PT_B0		(PT_B1+4)
+#define PT_L3		(PT_B0+4)
+#define PT_L2		(PT_L3+4)
+#define PT_L1		(PT_L2+4)
+#define PT_L0		(PT_L1+4)
+#define PT_M3		(PT_L0+4)
+#define PT_M2		(PT_M3+4)
+#define PT_M1		(PT_M2+4)
+#define PT_M0		(PT_M1+4)
+#define PT_I3		(PT_M0+4)
+#define PT_I2		(PT_I3+4)
+#define PT_I1		(PT_I2+4)
+#define PT_I0		(PT_I1+4)
+#define PT_USP		(PT_I0+4)
+#define PT_FP		(PT_USP+4)
+#define PT_P5		(PT_FP+4)
+#define PT_P4		(PT_P5+4)
+#define PT_P3		(PT_P4+4)
+#define PT_P2		(PT_P3+4)
+#define PT_P1		(PT_P2+4)
+#define PT_P0		(PT_P1+4)
+#define PT_R7		(PT_P0+4)
+#define PT_R6		(PT_R7+4)
+#define PT_R5		(PT_R6+4)
+#define PT_R4		(PT_R5+4)
+#define PT_R3		(PT_R4+4)
+#define PT_R2		(PT_R3+4)
+#define PT_R1		(PT_R2+4)
+#define PT_R0		(PT_R1+4)
+#define PT_ORIG_R0	(PT_R0+4)
+#define PT_SR		PT_SEQSTAT
+
+#else
+/*
+ * Here utilize frio : dpregs = [pregs + imm16s4]
+ *                     [pregs + imm16s4] = dpregs
+ * to access defferent saved reg in stack
+ */
+#define PT_R3	  	 0
+#define PT_R4	  	 4
+#define PT_R2	  	 8
+#define PT_R1	  	 12
+#define PT_P5	  	 16
+#define PT_P4	  	 20
+#define PT_P3	  	 24
+#define PT_P2	  	 28
+#define PT_P1	  	 32
+#define PT_P0	  	 36
+#define PT_R7	  	 40
+#define PT_R6	  	 44
+#define PT_R5	  	 48
+#define PT_PC		 52
+#define PT_SEQSTAT	 56	/* so-called SR reg */
+#define PT_SR		 PT_SEQSTAT
+#define PT_ASTAT	 60
+#define PT_RETS		 64
+#define PT_A1w		 68
+#define PT_A0w		 72
+#define PT_A1x		 76
+#define PT_A0x		 80
+#define PT_ORIG_R0	 84
+#define PT_R0	  	 88
+#define PT_USP	  	 92
+#define PT_FP	  	 96
+#define PT_SP		 100
+
+/* Added by HuTao, May26 2003 3:18PM */ 
+#define PT_IPEND	 100
+
+/* Add SYSCFG register for single stepping support */
+#define PT_SYSCFG	 104
+
+#endif
+
+#ifndef __ASSEMBLY__
+
+
+#if defined(NEW_PT_REGS)
+/* this struct defines the way the registers are stored on the
+   stack during a system call. */
+
+struct pt_regs {
+	long ipend;
+	long syscfg;
+	long seqstat;
+	long rete;
+	long retn;
+	long retx;
+	long pc;	// PC == RETI
+	long rets;
+	long reserved; // Used as scratch during system calls
+	long astat;
+	long lb1;
+	long lb0;
+	long lt1;
+	long lt0;
+	long lc1;
+	long lc0;
+	long a1w;
+	long a1x;
+	long a0w;
+	long a0x;
+	long b3;
+	long b2;
+	long b1;
+	long b0;
+	long l3;
+	long l2;
+	long l1;
+	long l0;
+	long m3;
+	long m2;
+	long m1;
+	long m0;
+	long i3;
+	long i2;
+	long i1;
+	long i0;
+	long usp;
+	long fp;
+	long p5;
+	long p4;
+	long p3;
+	long p2;
+	long p1;
+	long p0;
+	long r7;
+	long r6;
+	long r5;
+	long r4;
+	long r3;
+	long r2;
+	long r1;
+	long r0;
+	long orig_r0;
+};
+
+#else
+/* now we don't know what regs the system call will use	*/
+struct pt_regs {
+  long     r3;
+  long     r4;
+  long     r2;
+  long     r1;
+  long     p5;
+  long     p4;
+  long     p3;
+  long     p2;
+  long     p1;
+  long     p0;
+  long     r7;
+  long     r6;
+  long     r5;
+  unsigned long pc;
+  unsigned long seqstat;
+  unsigned long astat;
+  unsigned long rets;
+  long     a1w;
+  long     a0w;
+  long     a1x;
+  long     a0x;
+  long     orig_r0;
+  long	   r0;
+  long	   usp;
+  long     fp;
+
+/*
+ * Added for supervisor/user mode switch.
+ *
+ * HuTao May26 03 3:23PM
+ */
+ long ipend;
+
+ long	syscfg;
+};
+
+#endif
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS            12
+#define PTRACE_SETREGS            13	/* ptrace signal  */
+
+#ifdef __KERNEL__
+
+#ifndef PS_S
+#define PS_S  (0x0c00)  
+/* Bit 11:10 of SEQSTAT defines user/supervisor/debug mode
+ *        00: user 
+ *        01: supervisor
+ *        1x: debug
+ */
+
+#define PS_M  (0x1000)  /*  I am not sure why this is required here Akbar  */
+#endif
+
+#define user_mode(regs) (!((regs)->seqstat & PS_S))
+#define instruction_pointer(regs) ((regs)->pc)
+extern void show_regs(struct pt_regs *);
+
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+#endif /* _FRIO_PTRACE_H */
diff -urN linux-2.4.29/include/asm-blackfin/regs.h linux-2.4.29-uc1/include/asm-blackfin/regs.h
--- linux-2.4.29/include/asm-blackfin/regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/regs.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,48 @@
+/*
+  This is an include file that must be syncronized with the compiler event model
+  it basically provides the context of a full save i.e. __attribute__((saveall)).
+*/
+#ifndef REG
+#define REG(a,b)
+#endif
+
+REG(A1x,0)
+REG(A1w,1)
+REG(A0x,2)
+REG(A0w,3)
+REG(M3,4)
+REG(M2,5)
+REG(M1,6)
+REG(M0,7)
+REG(L3,8)
+REG(B3,9)
+REG(I3,10)
+REG(L2,11)
+REG(B2,12)
+REG(I2,13)
+REG(L1,14)
+REG(B1,15)
+REG(I1,16)
+REG(L0,17)
+REG(B0,18)
+REG(I0,19)
+REG(FP,20)
+REG(P5,21)
+REG(P4,22)
+REG(P3,23)
+REG(P2,24)
+REG(P1,25)
+REG(P0,26)
+REG(R7,27)
+REG(R6,28)
+REG(R5,29)
+REG(R4,30)
+REG(R3,31)
+REG(R2,32)
+REG(R1,33)
+REG(R0,34)
+REG(ASTAT,35)
+
+#ifndef NSAVED_REGS
+#define NSAVED_REGS 36
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/resource.h linux-2.4.29-uc1/include/asm-blackfin/resource.h
--- linux-2.4.29/include/asm-blackfin/resource.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/resource.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,47 @@
+#ifndef _FRIO_RESOURCE_H
+#define _FRIO_RESOURCE_H
+
+/*
+ * Resource limits
+ */
+
+#define RLIMIT_CPU	0		/* CPU time in ms */
+#define RLIMIT_FSIZE	1		/* Maximum filesize */
+#define RLIMIT_DATA	2		/* max data size */
+#define RLIMIT_STACK	3		/* max stack size */
+#define RLIMIT_CORE	4		/* max core file size */
+#define RLIMIT_RSS	5		/* max resident set size */
+#define RLIMIT_NPROC	6		/* max number of processes */
+#define RLIMIT_NOFILE	7		/* max number of open files */
+#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space*/
+#define RLIMIT_AS	9		/* address space limit */
+#define RLIMIT_LOCKS	10		/* maximum file locks held */
+
+#define RLIM_NLIMITS	11		/* number of limited items -tony*/
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway.
+ */
+#define RLIM_INFINITY	(~0UL)
+
+#ifdef __KERNEL__
+
+#define INIT_RLIMITS	\
+{                       \
+  {LONG_MAX, LONG_MAX}, \
+  {LONG_MAX, LONG_MAX}, \
+  {LONG_MAX, LONG_MAX}, \
+  {_STK_LIM, LONG_MAX}, \
+  {       0, LONG_MAX}, \
+  {LONG_MAX, LONG_MAX}, \
+  {0, 0},		\
+  {INR_OPEN, INR_OPEN}, \
+  {LONG_MAX, LONG_MAX}, \
+  {LONG_MAX, LONG_MAX}, \
+  {LONG_MAX, LONG_MAX}  \
+}				/* add up to 11 limited items */
+
+#endif /* __KERNEL__ */
+
+#endif /* _FRIO_RESOURCE_H */
diff -urN linux-2.4.29/include/asm-blackfin/scatterlist.h linux-2.4.29-uc1/include/asm-blackfin/scatterlist.h
--- linux-2.4.29/include/asm-blackfin/scatterlist.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/scatterlist.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,4 @@
+#ifndef _FRIONOMMU_SCATTERLIST_H
+#define _FRIONOMMU_SCATTERLIST_H
+
+#endif /* !(_FRIONOMMU_SCATTERLIST_H) */
diff -urN linux-2.4.29/include/asm-blackfin/segment.h linux-2.4.29-uc1/include/asm-blackfin/segment.h
--- linux-2.4.29/include/asm-blackfin/segment.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/segment.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,22 @@
+#ifndef _FRIO_SEGMENT_H
+#define _FRIO_SEGMENT_H
+
+/* define constants */
+typedef unsigned long mm_segment_t;         /* domain register      */
+ 
+#define KERNEL_CS   0x0
+#define KERNEL_DS   0x0
+#define __KERNEL_CS   0x0
+#define __KERNEL_DS   0x0
+ 
+#define USER_CS     0x1
+#define USER_DS     0x1 
+#define __USER_CS     0x1
+#define __USER_DS     0x1 
+
+#define get_ds()        (KERNEL_DS)
+#define get_fs()        (__USER_DS)
+#define segment_eq(a,b) ((a) == (b))
+#define set_fs(val)
+
+#endif /* _FRIO_SEGMENT_H */
diff -urN linux-2.4.29/include/asm-blackfin/semaphore.h linux-2.4.29-uc1/include/asm-blackfin/semaphore.h
--- linux-2.4.29/include/asm-blackfin/semaphore.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/semaphore.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,141 @@
+#ifndef _FRIO_SEMAPHORE_H
+#define _FRIO_SEMAPHORE_H
+
+#define RW_LOCK_BIAS		 0x01000000
+
+#ifndef __ASSEMBLY__
+
+#include <linux/linkage.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/rwsem.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+
+/*
+ * Interrupt-safe semaphores..
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ *
+ * FRIO version by akbar hussain Lineo Inc  April 2001
+ *
+ */
+
+struct semaphore {
+	atomic_t count;
+	atomic_t waking;
+	wait_queue_head_t wait;
+#if WAITQUEUE_DEBUG
+	long __magic;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+#define __SEM_DEBUG_INIT(name) \
+		, (long)&(name).__magic
+#else
+#define __SEM_DEBUG_INIT(name)
+#endif
+
+#define __SEMAPHORE_INITIALIZER(name,count) \
+{ ATOMIC_INIT(count), ATOMIC_INIT(0), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+	__SEM_DEBUG_INIT(name) }
+
+#define __MUTEX_INITIALIZER(name) \
+	__SEMAPHORE_INITIALIZER(name,1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+
+#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
+#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
+
+static inline void sema_init (struct semaphore *sem, int val)
+{
+	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
+}
+
+static inline void init_MUTEX (struct semaphore *sem)
+{
+	sema_init(sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+{
+	sema_init(sem, 0);
+}
+
+#if 0
+asmlinkage void __down_failed(void /* special register calling convention */);
+asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
+asmlinkage int  __down_failed_trylock(void  /* params in registers */);
+asmlinkage void __up_wakeup(void /* special register calling convention */);
+#endif
+
+asmlinkage void __down(struct semaphore * sem);
+asmlinkage int  __down_interruptible(struct semaphore * sem);
+asmlinkage int  __down_trylock(struct semaphore * sem);
+asmlinkage void __up(struct semaphore * sem);
+
+extern spinlock_t semaphore_wake_lock;
+
+/*
+ * This is ugly, but we want the default case to fall through.
+ * "down_failed" is a special asm handler that calls the C
+ * routine that actually waits. See arch/m68k/lib/semaphore.S
+ */
+static inline void down(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+ 
+        if (atomic_dec_return(&sem->count) < 0)
+                __down(sem);  
+}
+
+static inline int down_interruptible(struct semaphore * sem)
+{
+	int ret = 0;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+ 
+        if (atomic_dec_return(&sem->count) < 0)
+                ret = __down_interruptible(sem); 
+	return(ret);
+}
+
+static inline int down_trylock(struct semaphore * sem)
+{
+	int ret = 0;
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+ 
+        if (atomic_dec_return(&sem->count) < 0)
+                ret = __down_trylock(sem);  
+	return ret;
+}
+
+/*
+ * Note! This is subtle. We jump to wake people up only if
+ * the semaphore was negative (== somebody was waiting on it).
+ * The default case (no contention) will result in NO
+ * jumps for both down() and up().
+ */
+static inline void up(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+        if (atomic_inc_return(&sem->count) <= 0)
+                __up(sem);  
+}
+
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _FRIO_SEMAPHORE_H */
diff -urN linux-2.4.29/include/asm-blackfin/semaphore-helper.h linux-2.4.29-uc1/include/asm-blackfin/semaphore-helper.h
--- linux-2.4.29/include/asm-blackfin/semaphore-helper.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/semaphore-helper.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,82 @@
+/* Based on M68K version,	Lineo Inc.	May 2001 */
+
+#ifndef _FRIO_SEMAPHORE_HELPER_H
+#define _FRIO_SEMAPHORE_HELPER_H
+
+/*
+ * SMP- and interrupt-safe semaphores helper functions.
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ *
+ */
+
+#include <linux/config.h>
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ */
+static inline void wake_one_more(struct semaphore * sem)
+{
+	atomic_inc(&sem->waking);
+}
+
+static inline int waking_non_zero(struct semaphore *sem)
+{
+	int ret;
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	ret = 0;
+	if (atomic_read(&sem->waking) > 0) {
+		atomic_dec(&sem->waking);
+		ret = 1;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+/*
+ * waking_non_zero_interruptible:
+ *	1	got the lock
+ *	0	go to sleep
+ *	-EINTR	interrupted
+ */
+static inline int waking_non_zero_interruptible(struct semaphore *sem,
+						struct task_struct *tsk)
+{
+	int ret = 0;
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (atomic_read(&sem->waking) > 0) {
+		atomic_dec(&sem->waking);
+		ret = 1;
+	} else if (signal_pending(tsk)) {
+		atomic_inc(&sem->count);
+		ret = -EINTR;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+/*
+ * waking_non_zero_trylock:
+ *	1	failed to lock
+ *	0	got the lock
+ */
+static inline int waking_non_zero_trylock(struct semaphore *sem)
+{
+	int ret = 1;
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (atomic_read(&sem->waking) > 0) {
+		atomic_dec(&sem->waking);
+		ret = 0;
+	} else
+		atomic_inc(&sem->count);
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+#endif /* _FRIO_SEMAPHORE_HELPER_H */
diff -urN linux-2.4.29/include/asm-blackfin/sembuf.h linux-2.4.29-uc1/include/asm-blackfin/sembuf.h
--- linux-2.4.29/include/asm-blackfin/sembuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/sembuf.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef _FRIO_SEMBUF_H
+#define _FRIO_SEMBUF_H
+
+/* 
+ * The semid64_ds structure for frio architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm;	/* permissions .. see ipc.h */
+	__kernel_time_t	sem_otime;	/* last semop time */
+	unsigned long	__unused1;
+	__kernel_time_t	sem_ctime;	/* last change time */
+	unsigned long	__unused2;
+	unsigned long	sem_nsems;	/* no. of semaphores in array */
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _FRIO_SEMBUF_H */
diff -urN linux-2.4.29/include/asm-blackfin/serial.h linux-2.4.29-uc1/include/asm-blackfin/serial.h
--- linux-2.4.29/include/asm-blackfin/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/serial.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,100 @@
+/*
+ * include/asm-frionommu/serial.h
+ *
+ * its an almost exact copy of ../asm-68knommu/serial.h 
+ *
+ * Adapted for BlackFin (ADI) by Ted Ma <mated@sympatico.ca>
+ * Copyright (c) 2002 Arcturus Networks Inc. (www.arcturusnetworks.com)
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  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 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 <linux/config.h>
+/*
+ * This assumes you have a 1.8432 MHz clock for your UART. Updated for
+ * Blackfin which uses FSCLK for the clock. Currently set at 100 MHz
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ */
+#define BASE_BAUD ( 100000000 / 16 )
+#define DEFAULT_BAUD	115200		// FIXME - pick this up some else ...MaTed---
+
+
+/* Standard COM flags (except for COM4, because of the 8514 problem) */
+#ifdef CONFIG_SERIAL_DETECT_IRQ
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
+#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
+#else
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
+#endif
+
+#ifdef CONFIG_SERIAL_MANY_PORTS
+#define FOURPORT_FLAGS ASYNC_FOURPORT
+#define ACCENT_FLAGS 0
+#define BOCA_FLAGS 0
+#define RS_TABLE_SIZE  64
+#else
+#define RS_TABLE_SIZE  2		// only two for frio
+#endif
+	
+#define STD_SERIAL_PORT_DEFNS			\
+	/* UART CLK   PORT IRQ     FLAGS        */			\
+	{ 0, BASE_BAUD, 0xffc01800, 19, STD_COM_FLAGS },	/* ttyS0 */	\
+	{ 0, BASE_BAUD, 0xffc01c00, 21, STD_COM_FLAGS },	/* ttyS1 */	\
+
+#ifdef CONFIG_SERIAL_MANY_PORTS
+#define EXTRA_SERIAL_PORT_DEFNS			\
+	{ 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, 	/* ttyS4 */	\
+	{ 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS },	/* ttyS5 */	\
+	{ 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS },	/* ttyS6 */	\
+	{ 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS },	/* ttyS7 */	\
+	{ 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS },	/* ttyS8 */	\
+	{ 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS },	/* ttyS9 */	\
+	{ 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS },	/* ttyS10 */	\
+	{ 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS },	/* ttyS11 */	\
+	{ 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS },	/* ttyS12 */	\
+	{ 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS },	/* ttyS13 */	\
+	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS14 (spare) */		\
+	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS15 (spare) */		\
+	{ 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS },	/* ttyS16 */	\
+	{ 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS },	/* ttyS17 */	\
+	{ 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS },	/* ttyS18 */	\
+	{ 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS },	/* ttyS19 */	\
+	{ 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS },	/* ttyS20 */	\
+	{ 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS },	/* ttyS21 */	\
+	{ 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS },	/* ttyS22 */	\
+	{ 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS },	/* ttyS23 */	\
+	{ 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS },	/* ttyS24 */	\
+	{ 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS },	/* ttyS25 */	\
+	{ 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS },	/* ttyS26 */	\
+	{ 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS },	/* ttyS27 */	\
+	{ 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS },	/* ttyS28 */	\
+	{ 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS },	/* ttyS29 */	\
+	{ 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS },	/* ttyS30 */	\
+	{ 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS },	/* ttyS31 */
+#else
+#define EXTRA_SERIAL_PORT_DEFNS
+#endif
+
+#define SERIAL_PORT_DFNS		\
+	STD_SERIAL_PORT_DEFNS		\
+	EXTRA_SERIAL_PORT_DEFNS
diff -urN linux-2.4.29/include/asm-blackfin/setup.h linux-2.4.29-uc1/include/asm-blackfin/setup.h
--- linux-2.4.29/include/asm-blackfin/setup.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/setup.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,71 @@
+/*
+** asm/setup.h -- Definition of the Linux/Frio setup information
+**
+** This file is subject to the terms and conditions of the GNU General Public
+** License.  See the file COPYING in the main directory of this archive
+** for more details.
+**
+** Copyright Lineo, Inc 2001          Tony Kou
+**
+*/
+
+#ifndef _FRIO_SETUP_H
+#define _FRIO_SETUP_H
+
+#include <linux/config.h>
+
+
+/*
+ *  Linux/BlackFin Architectures
+ */
+
+#define MACH_BLACKFIN    1
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+extern unsigned long blackfin_machtype;
+#endif /* !__ASSEMBLY__ */
+
+#if defined(CONFIG_BLACKFIN)
+#define MACH_IS_BLACKFIN (blackfin_machtype == MACH_BLACKFIN)
+#endif
+
+#ifndef MACH_TYPE
+#define MACH_TYPE (blackfin_machtype)
+#endif
+
+#endif /* __KERNEL__ */
+
+
+    /*
+     *  CPU, FPU and MMU types
+     *
+     *  Note: we don't need now:
+     *
+     */
+
+#ifndef __ASSEMBLY__
+extern unsigned long frio_cputype;
+#ifdef CONFIG_VME
+extern unsigned long vme_brdtype;
+#endif 
+
+    /*
+     *  Miscellaneous
+     */
+
+#define NUM_MEMINFO	4
+#define CL_SIZE		256
+
+extern int frio_num_memory;		/* # of memory blocks found (and used) */
+extern int frio_realnum_memory;		/* real # of memory blocks found */
+extern struct mem_info frio_memory[NUM_MEMINFO];/* memory description */
+
+struct mem_info {
+	unsigned long addr;		/* physical address of memory chunk */
+	unsigned long size;		/* length of memory chunk (in bytes) */
+};
+#endif /* __ASSEMBLY__ */
+
+#endif /* _FRIO_SETUP_H */
diff -urN linux-2.4.29/include/asm-blackfin/shmbuf.h linux-2.4.29-uc1/include/asm-blackfin/shmbuf.h
--- linux-2.4.29/include/asm-blackfin/shmbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/shmbuf.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,42 @@
+#ifndef _FRIO_SHMBUF_H
+#define _FRIO_SHMBUF_H
+
+/* 
+ * The shmid64_ds structure for Frio architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	unsigned long		__unused1;
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	unsigned long		__unused2;
+	__kernel_time_t		shm_ctime;	/* last change time */
+	unsigned long		__unused3;
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _FRIO_SHMBUF_H */
diff -urN linux-2.4.29/include/asm-blackfin/shm.h linux-2.4.29-uc1/include/asm-blackfin/shm.h
--- linux-2.4.29/include/asm-blackfin/shm.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/shm.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,27 @@
+#ifndef _FRIO_SHM_H
+#define _FRIO_SHM_H
+
+#include <linux/config.h>
+
+/* format of page table entries that correspond to shared memory pages
+   currently out in swap space (see also mm/swap.c):
+   bits 0-1 (PAGE_PRESENT) is  = 0
+   bits 8..2 (SWP_TYPE) are = SHM_SWP_TYPE
+   bits 31..9 are used like this:
+   bits 15..9 (SHM_ID) the id of the shared memory segment
+   bits 30..16 (SHM_IDX) the index of the page within the shared memory segment
+            (actually only bits 25..16 get used since SHMMAX is so low)
+   bit 31 (SHM_READ_ONLY) flag whether the page belongs to a read-only attach
+*/
+/* on the m68k both bits 0 and 1 must be zero */	/* ???  */
+
+#define SHM_ID_SHIFT	9
+
+#define _SHM_ID_BITS	7
+#define SHM_ID_MASK	((1<<_SHM_ID_BITS)-1)
+
+#define SHM_IDX_SHIFT	(SHM_ID_SHIFT+_SHM_ID_BITS)
+#define _SHM_IDX_BITS	15
+#define SHM_IDX_MASK	((1<<_SHM_IDX_BITS)-1)
+
+#endif /* _FRIO_SHM_H */
diff -urN linux-2.4.29/include/asm-blackfin/shmparam.h linux-2.4.29-uc1/include/asm-blackfin/shmparam.h
--- linux-2.4.29/include/asm-blackfin/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/shmparam.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef _FRIO_SHMPARAM_H
+#define _FRIO_SHMPARAM_H
+
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
+
+#endif /* _FRIO_SHMPARAM_H */
diff -urN linux-2.4.29/include/asm-blackfin/sigcontext.h linux-2.4.29-uc1/include/asm-blackfin/sigcontext.h
--- linux-2.4.29/include/asm-blackfin/sigcontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/sigcontext.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,15 @@
+#ifndef _ASM_FRIONOMMU_SIGCONTEXT_H
+#define _ASM_FRIONOMMU_SIGCONTEXT_H
+
+struct sigcontext {
+	unsigned long  sc_mask; 	/* old sigmask */
+	unsigned long  sc_usp;		/* old user stack pointer */
+	unsigned long  sc_r0;
+	unsigned long  sc_r1;
+	unsigned long  sc_p0;
+	unsigned long  sc_p1;
+	unsigned short sc_seqstat;
+	unsigned long  sc_pc;
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/siginfo.h linux-2.4.29-uc1/include/asm-blackfin/siginfo.h
--- linux-2.4.29/include/asm-blackfin/siginfo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/siginfo.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,251 @@
+#ifndef _FRIO_SIGINFO_H
+#define _FRIO_SIGINFO_H
+
+#include <linux/types.h>
+
+/* This is copied from asm-m68k/siginfo.h.  */
+
+typedef union sigval {
+	int sival_int;
+	void *sival_ptr;
+} sigval_t;
+
+#define SI_MAX_SIZE	128
+#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct siginfo {
+	int si_signo;
+	int si_errno;
+	int si_code;
+
+	union {
+		int _pad[SI_PAD_SIZE];
+
+		/* kill() */
+		struct {
+			__kernel_pid_t _pid;	/* sender's pid */
+			__kernel_uid_t _uid;	/* backwards compatibility */
+			__kernel_uid32_t _uid32; /* sender's uid */
+		} _kill;
+
+		/* POSIX.1b timers */
+		struct {
+			unsigned int _timer1;
+			unsigned int _timer2;
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			__kernel_pid_t _pid;	/* sender's pid */
+			__kernel_uid_t _uid;	/* backwards compatibility */
+			sigval_t _sigval;
+			__kernel_uid32_t _uid32; /* sender's uid */
+		} _rt;
+
+		/* SIGCHLD */
+		struct {
+			__kernel_pid_t _pid;	/* which child */
+			__kernel_uid_t _uid;	/* backwards compatibility */
+			int _status;		/* exit code */
+			clock_t _utime;
+			clock_t _stime;
+			__kernel_uid32_t _uid32; /* sender's uid */
+		} _sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			void *_addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+	} _sifields;
+} siginfo_t;
+
+#define UID16_SIGINFO_COMPAT_NEEDED
+
+/*
+ * How these fields are to be accessed.
+ */
+#define si_pid		_sifields._kill._pid
+#ifdef __KERNEL__
+#define si_uid		_sifields._kill._uid32
+#define si_uid16	_sifields._kill._uid
+#else
+#define si_uid		_sifields._kill._uid
+#endif /* __KERNEL__ */
+#define si_status	_sifields._sigchld._status
+#define si_utime	_sifields._sigchld._utime
+#define si_stime	_sifields._sigchld._stime
+#define si_value	_sifields._rt._sigval
+#define si_int		_sifields._rt._sigval.sival_int
+#define si_ptr		_sifields._rt._sigval.sival_ptr
+#define si_addr		_sifields._sigfault._addr
+#define si_band		_sifields._sigpoll._band
+#define si_fd		_sifields._sigpoll._fd
+
+#ifdef __KERNEL__
+#define __SI_MASK	0xffff0000
+#define __SI_KILL	(0 << 16)
+#define __SI_TIMER	(1 << 16)
+#define __SI_POLL	(2 << 16)
+#define __SI_FAULT	(3 << 16)
+#define __SI_CHLD	(4 << 16)
+#define __SI_RT		(5 << 16)
+#define __SI_CODE(T,N)	((T) << 16 | ((N) & 0xffff))
+#else
+#define __SI_KILL	0
+#define __SI_TIMER	0
+#define __SI_POLL	0
+#define __SI_FAULT	0
+#define __SI_CHLD	0
+#define __SI_RT		0
+#define __SI_CODE(T,N)	(N)
+#endif
+
+/*
+ * si_code values
+ * Digital reserves positive values for kernel-generated signals.
+ */
+#define SI_USER		0		/* sent by kill, sigsend, raise */
+#define SI_KERNEL	0x80		/* sent by the kernel from somewhere */
+#define SI_QUEUE	-1		/* sent by sigqueue */
+#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
+#define SI_MESGQ	-3		/* sent by real time mesq state change */
+#define SI_ASYNCIO	-4		/* sent by AIO completion */
+#define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
+
+#define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
+#define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
+
+/*
+ * SIGILL si_codes
+ */
+#define ILL_ILLOPC	(__SI_FAULT|1)	/* illegal opcode ***********/
+#define ILL_ILLPARAOP	(__SI_FAULT|2)	/* illegal opcode combine ***********/
+#define ILL_ILLOPD	(__SI_FAULT|3)  /* illegal data access **********/
+#define ILL_ILLADR	(__SI_FAULT|3)	/* illegal addressing mode */
+#define ILL_ILLTRP	(__SI_FAULT|4)	/* illegal trap */
+#define ILL_ILLEXCPT	(__SI_FAULT|4)	/* unrecoverable exception ***********/
+#define ILL_PRVOPC	(__SI_FAULT|5)	/* privileged opcode */
+#define ILL_PRVREG	(__SI_FAULT|6)	/* privileged register */
+#define ILL_COPROC	(__SI_FAULT|7)	/* coprocessor error */
+#define ILL_BADSTK	(__SI_FAULT|8)	/* internal stack error */
+#define ILL_CPLB_VI	(__SI_FAULT|9)	/* D/I CPLB protect violation *********/
+#define IlL_CPLB_MISS	(__SI_FAULT|10)	/* D/I CPLB miss *********/
+#define ILL_CPLB_MULHIT	(__SI_FAULT|11)	/* D/I CPLB multiple hit *********/
+#define NSIGILL	11	
+
+/*
+ * SIGFPE si_codes
+ */
+#define FPE_INTDIV	(__SI_FAULT|1)	/* integer divide by zero */
+#define FPE_INTOVF	(__SI_FAULT|2)	/* integer overflow */
+#define FPE_FLTDIV	(__SI_FAULT|3)	/* floating point divide by zero */
+#define FPE_FLTOVF	(__SI_FAULT|4)	/* floating point overflow */
+#define FPE_FLTUND	(__SI_FAULT|5)	/* floating point underflow */
+#define FPE_FLTRES	(__SI_FAULT|6)	/* floating point inexact result */
+#define FPE_FLTINV	(__SI_FAULT|7)	/* floating point invalid operation */
+#define FPE_FLTSUB	(__SI_FAULT|8)	/* subscript out of range */
+#define NSIGFPE		8
+
+/*
+ * SIGSEGV si_codes
+ */
+#define SEGV_MAPERR	(__SI_FAULT|1)	/* address not mapped to object */
+#define SEGV_ACCERR	(__SI_FAULT|2)	/* invalid permissions for mapped object */
+#define NSIGSEGV	2
+
+/*
+ * SIGBUS si_codes
+ */
+#define BUS_ADRALN	(__SI_FAULT|1)	/* invalid address alignment **********/
+#define BUS_ADRERR	(__SI_FAULT|2)	/* non-existant physical address */
+#define BUS_OBJERR	(__SI_FAULT|3)	/* object specific hardware error */
+#define BUS_OPFETCH	(__SI_FAULT|4)  /* error from instruction fetch *********/
+#define NSIGBUS		4
+
+/*
+ * SIGTRAP si_codes
+ */
+#define TRAP_STEP	(__SI_FAULT|1)	/* single-step breakpoint**************/
+#define TRAP_TRACEFLOW	(__SI_FAULT|2)	/* trace buffer overflow **************/
+#define TRAP_WATCHPT	(__SI_FAULT|3)  /* watchpoint match      **************/
+#define TRAP_ILLTRAP	(__SI_FAULT|4)	/* illegal trap          **************/
+#define NSIGTRAP	4
+
+/*
+ * SIGCHLD si_codes
+ */
+#define CLD_EXITED	(__SI_CHLD|1)	/* child has exited */
+#define CLD_KILLED	(__SI_CHLD|2)	/* child was killed */
+#define CLD_DUMPED	(__SI_CHLD|3)	/* child terminated abnormally */
+#define CLD_TRAPPED	(__SI_CHLD|4)	/* traced child has trapped */
+#define CLD_STOPPED	(__SI_CHLD|5)	/* child has stopped */
+#define CLD_CONTINUED	(__SI_CHLD|6)	/* stopped child has continued */
+#define NSIGCHLD	6
+
+/*
+ * SIGPOLL si_codes
+ */
+#define POLL_IN		(__SI_POLL|1)	/* data input available */
+#define POLL_OUT	(__SI_POLL|2)	/* output buffers available */
+#define POLL_MSG	(__SI_POLL|3)	/* input message available */
+#define POLL_ERR	(__SI_POLL|4)	/* i/o error */
+#define POLL_PRI	(__SI_POLL|5)	/* high priority input available */
+#define POLL_HUP	(__SI_POLL|6)	/* device disconnected */
+#define NSIGPOLL	6
+
+/*
+ * sigevent definitions
+ * 
+ * It seems likely that SIGEV_THREAD will have to be handled from 
+ * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
+ * thread manager then catches and does the appropriate nonsense.
+ * However, everything is written out here so as to not get lost.
+ */
+#define SIGEV_SIGNAL	0	/* notify via signal */
+#define SIGEV_NONE	1	/* other notification: meaningless */
+#define SIGEV_THREAD	2	/* deliver via thread creation */
+
+#define SIGEV_MAX_SIZE	64
+#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct sigevent {
+	sigval_t sigev_value;
+	int sigev_signo;
+	int sigev_notify;
+	union {
+		int _pad[SIGEV_PAD_SIZE];
+
+		struct {
+			void (*_function)(sigval_t);
+			void *_attribute;	/* really pthread_attr_t */
+		} _sigev_thread;
+	} _sigev_un;
+} sigevent_t;
+
+#define sigev_notify_function	_sigev_un._sigev_thread._function
+#define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
+
+#ifdef __KERNEL__
+#include <linux/string.h>
+
+extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
+{
+	if (from->si_code < 0)
+		memcpy(to, from, sizeof(siginfo_t));
+	else
+		/* _sigchld is currently the largest know union member */
+		memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
+}
+
+extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
+
+#endif /* __KERNEL__ */
+
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/signal.h linux-2.4.29-uc1/include/asm-blackfin/signal.h
--- linux-2.4.29/include/asm-blackfin/signal.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/signal.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,181 @@
+#ifndef _FRIONOMMU_SIGNAL_H
+#define _FRIONOMMU_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#ifdef __KERNEL__
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE		SA_ONESHOT
+#define SA_SAMPLE_RANDOM	SA_RESTART
+#define SA_SHIRQ		0x04000000
+#endif
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+#ifdef __KERNEL__
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+
+#include <asm/sigcontext.h>
+#undef __HAVE_ARCH_SIG_BITOPS
+
+#endif /* __KERNEL__ */
+
+#endif /* _FRIONOMMU_SIGNAL_H */
diff -urN linux-2.4.29/include/asm-blackfin/smplock.h linux-2.4.29-uc1/include/asm-blackfin/smplock.h
--- linux-2.4.29/include/asm-blackfin/smplock.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/smplock.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,52 @@
+/********************************
+ * <asm/smplock.h>
+ *
+ * Default SMP lock implementation, 
+ * generally we don't need them
+******************************* */
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+extern spinlock_t kernel_flag;
+
+#define kernel_locked()		spin_is_locked(&kernel_flag)
+
+/*
+ * Release global kernel lock and global interrupt lock
+ */
+#define release_kernel_lock(task, cpu) \
+do { \
+	if (task->lock_depth >= 0) \
+		spin_unlock(&kernel_flag); \
+	release_irqlock(cpu); \
+	__sti(); \
+} while (0)
+
+/*
+ * Re-acquire the kernel lock
+ */
+#define reacquire_kernel_lock(task) \
+do { \
+	if (task->lock_depth >= 0) \
+		spin_lock(&kernel_flag); \
+} while (0)
+
+
+/*
+ * Getting the big kernel lock.
+ *
+ * This cannot happen asynchronously,
+ * so we only need to worry about other
+ * CPU's.
+ */
+extern __inline__ void lock_kernel(void)
+{
+	if (!++current->lock_depth)
+		spin_lock(&kernel_flag);
+}
+
+extern __inline__ void unlock_kernel(void)
+{
+	if (--current->lock_depth < 0)
+		spin_unlock(&kernel_flag);
+}
diff -urN linux-2.4.29/include/asm-blackfin/socket.h linux-2.4.29-uc1/include/asm-blackfin/socket.h
--- linux-2.4.29/include/asm-blackfin/socket.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/socket.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,64 @@
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED	16
+#define SO_PEERCRED	17
+#define SO_RCVLOWAT	18
+#define SO_SNDLOWAT	19
+#define SO_RCVTIMEO	20
+#define SO_SNDTIMEO	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE	25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME             28
+#define SO_TIMESTAMP		29
+#define SCM_TIMESTAMP		SO_TIMESTAMP
+
+#define SO_ACCEPTCONN		30
+
+/* Nast libc5 fixup - bletch */
+#if defined(__KERNEL__)
+/* Socket types. */
+#define SOCK_STREAM	1		/* stream (connection) socket	*/
+#define SOCK_DGRAM	2		/* datagram (conn.less) socket	*/
+#define SOCK_RAW	3		/* raw socket			*/
+#define SOCK_RDM	4		/* reliably-delivered message	*/
+#define SOCK_SEQPACKET	5		/* sequential packet socket	*/
+#define SOCK_PACKET	10		/* linux specific way of	*/
+					/* getting packets at the dev	*/
+					/* level.  For writing rarp and	*/
+					/* other similar things on the	*/
+					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
+#endif
+
+#endif /* _ASM_SOCKET_H */
diff -urN linux-2.4.29/include/asm-blackfin/sockios.h linux-2.4.29-uc1/include/asm-blackfin/sockios.h
--- linux-2.4.29/include/asm-blackfin/sockios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/sockios.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef __ARCH_FRIO_SOCKIOS__
+#define __ARCH_FRIO_SOCKIOS__
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 	0x8901
+#define SIOCSPGRP	0x8902
+#define FIOGETOWN	0x8903
+#define SIOCGPGRP	0x8904
+#define SIOCATMARK	0x8905
+#define SIOCGSTAMP	0x8906		/* Get stamp */
+
+#endif /* __ARCH_FRIO_SOCKIOS__ */
diff -urN linux-2.4.29/include/asm-blackfin/softirq.h linux-2.4.29-uc1/include/asm-blackfin/softirq.h
--- linux-2.4.29/include/asm-blackfin/softirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/softirq.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,26 @@
+#ifndef __FRIO_SOFTIRQ_H
+#define __FRIO_SOFTIRQ_H
+
+#include <asm/atomic.h>
+#include <asm/hardirq.h>
+
+#define __cpu_bh_enable(cpu)	\
+	do { barrier(); local_bh_count(cpu)--; } while (0)
+#define cpu_bh_disable(cpu)	\
+	do { local_bh_count(cpu)++; barrier(); } while (0)
+
+#define local_bh_disable()	cpu_bh_disable(smp_processor_id())
+#define __local_bh_enable()	__cpu_bh_enable(smp_processor_id())
+
+/* XXX: defined in <linux/interrupt.h>
+#define __cpu_raise_softirq(cpu,nr) set_bit((nr), &softirq_pending(cpu));
+#define raise_softirq(nr) __cpu_raise_softirq(smp_processor_id(), (nr))
+*/
+/*
+#define __cpu_raise_softirq(cpu,nr)
+#define raise_softirq(nr)*/
+
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
+#define local_bh_enable() __local_bh_enable()
+
+#endif /* __FRIO_SOFTIRQ_H */
diff -urN linux-2.4.29/include/asm-blackfin/spinlock.h linux-2.4.29-uc1/include/asm-blackfin/spinlock.h
--- linux-2.4.29/include/asm-blackfin/spinlock.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/spinlock.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __FRIO_SPINLOCK_H
+#define __FRIO_SPINLOCK_H
+
+#error Frio architecture does not support SMP spin lock yet
+
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/statfs.h linux-2.4.29-uc1/include/asm-blackfin/statfs.h
--- linux-2.4.29/include/asm-blackfin/statfs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/statfs.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef _FRIO_STATFS_H
+#define _FRIO_STATFS_H
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t	fsid_t;
+
+#endif
+
+struct statfs {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_spare[6];
+};
+
+#endif /* _FRIO_STATFS_H */
diff -urN linux-2.4.29/include/asm-blackfin/stat.h linux-2.4.29-uc1/include/asm-blackfin/stat.h
--- linux-2.4.29/include/asm-blackfin/stat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/stat.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,80 @@
+#ifndef _FRIO_STAT_H
+#define _FRIO_STAT_H
+
+struct __old_kernel_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+struct stat {
+	unsigned short st_dev;
+	unsigned short __pad1;
+	unsigned long st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned short __pad2;
+	unsigned long  st_size;
+	unsigned long  st_blksize;
+	unsigned long  st_blocks;
+	unsigned long  st_atime;
+	unsigned long  __unused1;
+	unsigned long  st_mtime;
+	unsigned long  __unused2;
+	unsigned long  st_ctime;
+	unsigned long  __unused3;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat64 {
+	unsigned char	__pad0[6];
+	unsigned short	st_dev;
+	unsigned char	__pad1[4];
+
+#define STAT64_HAS_BROKEN_ST_INO	1
+	unsigned long	__st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned char	__pad2[6];
+	unsigned short	st_rdev;
+	unsigned char	__pad3[4];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+
+	unsigned long	st_atime;
+	unsigned long	__pad5;
+
+	unsigned long	st_mtime;
+	unsigned long	__pad6;
+
+	unsigned long	st_ctime;
+	unsigned long	__pad7;		/* will be high 32 bits of ctime someday */
+
+	unsigned long long	st_ino;
+};
+
+#endif /* _FRIO_STAT_H */
diff -urN linux-2.4.29/include/asm-blackfin/string.h linux-2.4.29-uc1/include/asm-blackfin/string.h
--- linux-2.4.29/include/asm-blackfin/string.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/string.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,143 @@
+/*  Changed by Lineo Inc. May 2001		*/
+
+#ifndef _FRIONOMMU_STRING_H_
+#define _FRIONOMMU_STRING_H_
+
+#ifdef __KERNEL__ /* only set these up for kernel code */
+
+/*************
+ * Still not sure whether the optimised inline asm 
+ * are small.
+**************/
+
+#include <asm/setup.h>
+#include <asm/page.h>
+
+#define __HAVE_ARCH_STRCPY
+static inline char * strcpy(char * dest,const char *src)
+{
+  char *xdest = dest;
+  char  temp = 0;
+
+  __asm__ __volatile__
+       ("1:\t%2 = B [%1++] (Z);\n\t"
+	"B [%0++] = %2;\n\t"
+	"CC = %2;\n\t"
+        "if cc jump 1b (bp);\n"
+	: "=a" (dest), "=a" (src), "=d" (temp)
+        : "0" (dest), "1" (src), "2" (temp) : "memory");
+  return xdest;
+}
+
+#define __HAVE_ARCH_STRNCPY
+static inline char * strncpy(char *dest, const char *src, size_t n)
+{
+  char *xdest = dest;
+  char  temp = 0;
+
+  if (n == 0)
+    return xdest;
+
+  __asm__ __volatile__
+       ("1:\t%3 = B [%1++] (Z);\n\t"
+	"B [%0++] = %3;\n\t"
+	"CC = %3;\n\t"
+	"if ! cc jump 2f;\n\t"
+        "%2 += -1;\n\t"
+	"CC = %2 == 0;\n\t"
+        "if ! cc jump 1b (bp);\n"
+        "2:\n"
+        : "=a" (dest), "=a" (src), "=da" (n), "=d" (temp)
+        : "0" (dest), "1" (src), "2" (n), "3" (temp)
+        : "memory");
+
+  return xdest;
+}
+
+#define __HAVE_ARCH_STRCMP
+static inline int strcmp(const char * cs,const char * ct)
+{
+  char __res1, __res2;
+
+  __asm__
+       ("1:\t%2 = B[%0++] (Z);\n\t" /* get *cs */
+	"%3 = B[%1++] (Z);\n\t"	/* get *ct */
+        "CC = %2 == %3;\n\t"       /* compare a byte */
+        "if ! cc jump 2f;\n\t"         /* not equal, break out */
+        "CC = %2;\n\t"           /* at end of cs? */
+        "if cc jump 1b (bp);\n\t"           /* no, keep going */
+        "jump.s 3f;\n"		/* strings are equal */
+        "2:\t%2 = %2 - %3;\n"  /* *cs - *ct */
+        "3:\n"
+        : "=a" (cs), "=a" (ct), "=d" (__res1), "=d" (__res2)
+        : "0" (cs), "1" (ct));
+
+  return __res1;
+}
+
+#define __HAVE_ARCH_STRNCMP
+static inline int strncmp(const char * cs,const char * ct,size_t count)
+{
+  char __res1, __res2;
+
+  if (!count)
+    return 0;
+  __asm__
+       ("1:\t%3 = B[%0++] (Z);\n\t"        /* get *cs */
+	"%4 = B[%1++] (Z);\n\t"		/* get *ct */
+        "CC = %3 == %4;\n\t"            /* compare a byte */
+        "if ! cc jump 3f;\n\t"                  /* not equal, break out */
+        "CC = %3;\n\t"                  /* at end of cs? */
+        "if ! cc jump 4f;\n\t"                 /* yes, all done */
+        "%2 += -1;\n\t"              /* no, adjust count */
+	"CC = %2 == 0;\n\t"
+        "if ! cc jump 1b;\n"                 /* more to do, keep going */
+        "2:\t%3 = 0;\n\t"           /* strings are equal */
+        "jump.s    4f;\n"
+        "3:\t%3 = %3 - %4;\n"          /* *cs - *ct */
+        "4:"
+        : "=a" (cs), "=a" (ct), "=da" (count), "=d" (__res1), "=d" (__res2)
+        : "0" (cs), "1" (ct), "2" (count));
+
+  return __res1;
+}
+
+#define __HAVE_ARCH_MEMSET
+extern void * memset(void * s, int c, size_t count);
+
+#define __HAVE_ARCH_MEMCPY
+extern void * memcpy(void *d, const void *s, size_t count);
+
+#define __HAVE_ARCH_MEMCMP
+extern int memcmp(const void *,const void *,__kernel_size_t);
+
+#else /* KERNEL */
+
+/*
+ *	let user libraries deal with these,
+ *	IMHO the kernel has no place defining these functions for user apps
+ */
+
+#define __HAVE_ARCH_STRCPY 1
+#define __HAVE_ARCH_STRNCPY 1
+#define __HAVE_ARCH_STRCAT 1
+#define __HAVE_ARCH_STRNCAT 1
+#define __HAVE_ARCH_STRCMP 1
+#define __HAVE_ARCH_STRNCMP 1
+#define __HAVE_ARCH_STRNICMP 1
+#define __HAVE_ARCH_STRCHR 1
+#define __HAVE_ARCH_STRRCHR 1
+#define __HAVE_ARCH_STRSTR 1
+#define __HAVE_ARCH_STRLEN 1
+#define __HAVE_ARCH_STRNLEN 1
+#define __HAVE_ARCH_MEMSET 1
+#define __HAVE_ARCH_MEMCPY 1
+#define __HAVE_ARCH_MEMMOVE 1
+#define __HAVE_ARCH_MEMSCAN 1
+#define __HAVE_ARCH_MEMCMP 1
+#define __HAVE_ARCH_MEMCHR 1
+#define __HAVE_ARCH_STRTOK 1
+
+#endif /* KERNEL */
+
+#endif /* _FRIO_STRING_H_ */
diff -urN linux-2.4.29/include/asm-blackfin/system.h linux-2.4.29-uc1/include/asm-blackfin/system.h
--- linux-2.4.29/include/asm-blackfin/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/system.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,168 @@
+#ifndef _FRIONOMMU_SYSTEM_H
+#define _FRIONOMMU_SYSTEM_H
+
+#include <linux/config.h> /* get configuration macros */
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+#include <asm/segment.h>
+#include <asm/entry.h>
+
+#define prepare_to_switch()	do { } while(0)
+
+/*
+ * switch_to(n) should switch tasks to task ptr, first checking that
+ * ptr isn't the current task, in which case it does nothing.  This
+ * also clears the TS-flag if the task we switched to has used the
+ * math co-processor latest.
+ *
+ * 05/25/01 - Tony Kou (tonyko@lineo.ca)
+ *
+ * Adapted for BlackFin (ADI) by Ted Ma, Metrowerks, and Motorola GSG
+ * Copyright (c) 2002 Arcturus Networks Inc. (www.arcturusnetworks.com)
+ * Copyright (c) 2003 Metrowerks (www.metrowerks.com)
+ */
+
+/**************
+MACRO definitions
+***************/
+
+asmlinkage void resume(void);
+#define switch_to(prev,next,last) { \
+  void *_last;								\
+  __asm__ __volatile__(							\
+  			"r0 = %1;\n\t"					\
+			"r1 = %2;\n\t"					\
+			"call resume;\n\t" 				\
+			"%0 = r0;\n\t"					\
+		       : "=d" (_last)					\
+		       : "d" (prev),					\
+			 "d" (next)					\
+		       : "CC", "R0", "R1", "R2", "R3", "R4", "R5", "P0", "P1");	\
+  (last) = _last; 								\
+}
+
+/* Force kerenl switch to user mode -- Steven Chen */
+#define switch_to_user_mode() { \
+	__asm__ __volatile__(	\
+			"call kernel_to_user_mode;\n\t"	\
+			::	\
+		       : "CC", "R0", "R1", "R2", "R3", "R4", "R5", "P0", "P1");	\
+}
+
+/*
+ * Interrupt configuring macros.
+ */
+
+extern int irq_flags;
+
+#define __sti() {			\
+	__asm__ __volatile__ (		\
+		"r3 = %0;"		\
+		"sti r3;"		\
+		::"m"(irq_flags):"R3");	\
+if (irq_flags == 0) printk("Whoops\n");	\
+}
+
+#define __cli() {			\
+	__asm__ __volatile__ (		\
+		"cli r3;"		\
+		:::"R3");		\
+}
+
+#define __save_flags(x) {		\
+	__asm__ __volatile__ (		\
+		"cli r3;"		\
+		"%0 = r3;"		\
+		"sti r3;"		\
+		::"m"(x):"R3");		\
+}
+
+#define __save_and_cli(x) {		\
+	__asm__ __volatile__ (          \
+		"cli r3;"		\
+		"%0 = r3;"		\
+		::"m"(x):"R3");         \
+}
+
+#define __restore_flags(x) {		\
+	__asm__ __volatile__ (		\
+		"r3 = %0;"		\
+		"sti r3;"		\
+		::"m"(x):"R3");		\
+}
+
+/* For spinlocks etc */
+#define local_irq_save(x)	__save_and_cli(x)
+#define local_irq_restore(x)	__restore_flags(x)
+#define local_irq_disable()	__cli()
+#define local_irq_enable()	__sti()
+
+#define cli()			__cli()
+#define sti()			__sti()
+#define save_flags(x)		__save_flags(x)
+#define restore_flags(x)	__restore_flags(x)
+#define save_and_cli(x)		__save_and_cli(x)
+
+/*
+ * Force strict CPU ordering.
+ */
+#define nop()  asm volatile ("nop;\n\t"::)
+#define mb()   asm volatile (""   : : :"memory")
+#define rmb()  asm volatile (""   : : :"memory")
+#define wmb()  asm volatile (""   : : :"memory")
+#define set_rmb(var, value)    do { xchg(&var, value); } while (0)
+#define set_mb(var, value)     set_rmb(var, value)
+#define set_wmb(var, value)    do { var = value; wmb(); } while (0)
+
+#ifdef CONFIG_SMP
+#define smp_mb()	mb()
+#define smp_rmb()	rmb()
+#define smp_wmb()	wmb()
+#else
+#define smp_mb()	barrier()
+#define smp_rmb()	barrier()
+#define smp_wmb()	barrier()
+#endif
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+#define tas(ptr) (xchg((ptr),1))
+
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((volatile struct __xchg_dummy *)(x))
+
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+  unsigned long tmp;
+  unsigned long flags = 0;
+
+  save_and_cli( flags);
+
+  switch (size) {
+  case 1:
+    __asm__ __volatile__
+    ("%0 = %2;\n\t"
+     "%2 = %1;\n\t"
+    : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
+    break;
+  case 2:
+    __asm__ __volatile__
+    ("%0 = %2;\n\t"
+     "%2 = %1;\n\t"
+    : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
+    break;
+  case 4:
+    __asm__ __volatile__
+    ("%0 = %2;\n\t"
+     "%2 = %1;\n\t"
+    : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
+    break;
+  }
+  restore_flags( flags);
+  return tmp;
+}
+
+/* Depend on whether Blackfin has hard reset function */
+/* YES it does, but it is tricky to implement - FIXME later ...MaTed--- */
+#define HARD_RESET_NOW() ({})
+
+#endif /* _FRIONOMMU_SYSTEM_H */
diff -urN linux-2.4.29/include/asm-blackfin/termbits.h linux-2.4.29-uc1/include/asm-blackfin/termbits.h
--- linux-2.4.29/include/asm-blackfin/termbits.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/termbits.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,174 @@
+#ifndef __ARCH_FRIO_TERMBITS_H__
+#define __ARCH_FRIO_TERMBITS_H__
+
+#include <linux/posix_types.h>
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#define NCCS 19
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IUCLC	0001000
+#define IXON	0002000
+#define IXANY	0004000
+#define IXOFF	0010000
+#define IMAXBEL	0020000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define OLCUC	0000002
+#define ONLCR	0000004
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#define NLDLY	0000400
+#define   NL0	0000000
+#define   NL1	0000400
+#define CRDLY	0003000
+#define   CR0	0000000
+#define   CR1	0001000
+#define   CR2	0002000
+#define   CR3	0003000
+#define TABDLY	0014000
+#define   TAB0	0000000
+#define   TAB1	0004000
+#define   TAB2	0010000
+#define   TAB3	0014000
+#define   XTABS	0014000
+#define BSDLY	0020000
+#define   BS0	0000000
+#define   BS1	0020000
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+#define FFDLY	0100000
+#define   FF0	0000000
+#define   FF1	0100000
+
+/* c_cflag bit meaning */
+#define CBAUD	0010017
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE	0000060
+#define   CS5	0000000
+#define   CS6	0000020
+#define   CS7	0000040
+#define   CS8	0000060
+#define CSTOPB	0000100
+#define CREAD	0000200
+#define PARENB	0000400
+#define PARODD	0001000
+#define HUPCL	0002000
+#define CLOCAL	0004000
+#define CBAUDEX 0010000
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+#define CIBAUD	  002003600000	/* input baud rate (not used) */
+#define CMSPAR	  010000000000		/* mark or space (stick) parity */
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+#define ISIG	0000001
+#define ICANON	0000002
+#define XCASE	0000004
+#define ECHO	0000010
+#define ECHOE	0000020
+#define ECHOK	0000040
+#define ECHONL	0000100
+#define NOFLSH	0000200
+#define TOSTOP	0000400
+#define ECHOCTL	0001000
+#define ECHOPRT	0002000
+#define ECHOKE	0004000
+#define FLUSHO	0010000
+#define PENDIN	0040000
+#define IEXTEN	0100000
+
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* __ARCH_FRIO_TERMBITS_H__ */
diff -urN linux-2.4.29/include/asm-blackfin/termios.h linux-2.4.29-uc1/include/asm-blackfin/termios.h
--- linux-2.4.29/include/asm-blackfin/termios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/termios.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,107 @@
+#ifndef _FRIO_TERMIOS_H
+#define _FRIO_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+ 
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+#ifdef __KERNEL__
+/*	intr=^C		quit=^|		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+#endif
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6	/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11	/* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14
+
+#ifdef __KERNEL__
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+	unsigned short tmp; \
+	get_user(tmp, &(termio)->c_iflag); \
+	(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
+	get_user(tmp, &(termio)->c_oflag); \
+	(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
+	get_user(tmp, &(termio)->c_cflag); \
+	(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
+	get_user(tmp, &(termio)->c_lflag); \
+	(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
+	get_user((termios)->c_line, &(termio)->c_line); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif	/* __KERNEL__ */
+
+#endif /* _FRIO_TERMIOS_H */
diff -urN linux-2.4.29/include/asm-blackfin/timex.h linux-2.4.29-uc1/include/asm-blackfin/timex.h
--- linux-2.4.29/include/asm-blackfin/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/timex.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,25 @@
+/* Frio architecture timex specifications: Lineo Inc. 2001
+ *
+ * Based on: include/asm-m68knommu/timex.h
+ */
+
+#ifndef _ASMFRIONOMMU_TIMEX_H
+#define _ASMFRIONOMMU_TIMEX_H
+
+#define CLOCK_TICK_RATE	1193180 	/* Underlying HZ */
+#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
+#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
+	(1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
+		<< (SHIFT_SCALE-SHIFT_HZ)) / HZ)
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+	return 0;
+}
+
+#define vxtime_lock()		do {} while (0)
+#define vxtime_unlock()		do {} while (0)
+
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/tlb.h linux-2.4.29-uc1/include/asm-blackfin/tlb.h
--- linux-2.4.29/include/asm-blackfin/tlb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/tlb.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-generic/tlb.h>
diff -urN linux-2.4.29/include/asm-blackfin/traps.h linux-2.4.29-uc1/include/asm-blackfin/traps.h
--- linux-2.4.29/include/asm-blackfin/traps.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/traps.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,67 @@
+/*
+ *  linux/include/asm/traps.h
+ *
+ *  Copyright (C) 1993        Hamish Macdonald
+ *
+ *  Lineo, Inc    Jul 2001    Tony Kou
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _FRIO_TRAPS_H
+#define _FRIO_TRAPS_H
+
+#ifndef __ASSEMBLY__
+typedef void (*e_vector)(void);
+extern e_vector vectors[];
+#endif
+
+#define VEC_SYS		(0)
+#define VEC_EXCPT01	(1)
+#define VEC_EXCPT02	(2)
+#define VEC_EXCPT03	(3)
+#define VEC_EXCPT04	(4)
+#define VEC_EXCPT05	(5)
+#define VEC_EXCPT06	(6)
+#define VEC_EXCPT07	(7)
+#define VEC_EXCPT08	(8)
+#define VEC_EXCPT09	(9)
+#define VEC_EXCPT10	(10)
+#define VEC_EXCPT11	(11)
+#define VEC_EXCPT12	(12)
+#define VEC_EXCPT13	(13)
+#define VEC_EXCPT14	(14)
+#define VEC_EXCPT15	(15)
+#define VEC_STEP	(16)
+#define VEC_OVFLOW	(17)
+#define VEC_UNDEF_I	(33)
+#define VEC_ILGAL_I	(34)
+#define VEC_CPLB_VL	(35)
+#define VEC_MISALI_D	(36)
+#define VEC_UNCOV	(37)
+#define VEC_CPLB_M	(38)
+#define VEC_CPLB_MHIT	(39)
+#define VEC_WATCH	(40)
+#define VEC_ISTRU_VL	(41)
+#define VEC_MISALI_I	(42)
+#define VEC_CPLB_I_VL	(43)
+#define VEC_CPLB_I_M	(44)
+#define VEC_CPLB_I_MHIT	(45)
+#define VEC_ILL_RES	(46)	/* including unvalid supervisor mode insn */
+
+#define VECOFF(vec) ((vec)<<2)
+
+#ifndef __ASSEMBLY__
+
+/* Status register bits */
+#define PS_T  (0x8000)
+#define PS_S  (0x0c00)	/*  Supervisor mode = 0b01 	*/
+#define PS_D  (0x0c00)	/*  Debug mode = 0b1x		*/
+#define PS_M  (0x1000)
+#define PS_C  (0x0001)
+
+#endif /* __ASSEMBLY__ */
+#endif /* _FRIO_TRAPS_H */
+
diff -urN linux-2.4.29/include/asm-blackfin/types.h linux-2.4.29-uc1/include/asm-blackfin/types.h
--- linux-2.4.29/include/asm-blackfin/types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/types.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,59 @@
+#ifndef _FRIO_TYPES_H
+#define _FRIO_TYPES_H
+
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue.  However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ */
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+/* HK0617   -- Changes to unsigned long temporarily */
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide.  */
+
+typedef u32 dma_addr_t;
+
+#endif /* __KERNEL__ */
+
+#endif /* _FRIO_TYPES_H */
diff -urN linux-2.4.29/include/asm-blackfin/uaccess.h linux-2.4.29-uc1/include/asm-blackfin/uaccess.h
--- linux-2.4.29/include/asm-blackfin/uaccess.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/uaccess.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,187 @@
+/* Changes made by Lineo Inc.    May 2001
+ *
+ * Based on: include/asm-m68knommu/uaccess.h
+ */
+
+#ifndef __FRIONOMMU_UACCESS_H
+#define __FRIONOMMU_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <asm/segment.h>
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+/* We let the MMU do all checking */
+static inline int access_ok(int type, const void * addr, unsigned long size)
+{
+	return((unsigned long)addr < 0x10f00000);  /* need final decision - Tony */
+}
+
+static inline int verify_area(int type, const void * addr, unsigned long size)
+{
+	return access_ok(type,addr,size)?0:-EFAULT;
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ */
+
+#define put_user(x, ptr)				\
+({							\
+    int __pu_err = 0;					\
+    typeof(*(ptr)) __pu_val = (x);			\
+    switch (sizeof (*(ptr))) {				\
+    case 1:						\
+	__put_user_asm(__pu_err, __pu_val, ptr, B);	\
+	break;						\
+    case 2:						\
+	__put_user_asm(__pu_err, __pu_val, ptr, W);	\
+	break;						\
+    case 4:						\
+	__put_user_asm(__pu_err, __pu_val, ptr,  );	\
+	break;						\
+    default:						\
+	__pu_err = __put_user_bad();			\
+	break;						\
+    }							\
+    __pu_err;						\
+})
+/*    [pregs] = dregs  ==> 32bits
+     H[pregs] = dregs  ==> 16bits
+     B[pregs] = dregs  ==> 8 bits
+*/
+
+#define __put_user(x, ptr) put_user(x, ptr)
+
+static inline int bad_user_access_length(void)
+{
+                panic("bad_user_access_length");
+                return -1;
+}
+
+#define __put_user_bad() (bad_user_access_length(), (-EFAULT))
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+
+#define __ptr(x) ((unsigned long *)(x))
+
+#define __put_user_asm(err,x,ptr,bhw)			\
+	__asm__ (#bhw"[%1] = %0;\n\t"			\
+		: /* no outputs */			\
+		:"d" (x),"a" (__ptr(ptr)) : "memory")
+
+#define get_user(x, ptr)					\
+({								\
+    int __gu_err = 0;						\
+    typeof(*(ptr)) __gu_val = 0;				\
+    switch (sizeof(*(ptr))) {					\
+    case 1:							\
+	__get_user_asm(__gu_err, __gu_val, ptr, B, "=d",(Z));	\
+	break;							\
+    case 2:							\
+	__get_user_asm(__gu_err, __gu_val, ptr, W, "=r",(Z));	\
+	break;							\
+    case 4:							\
+	__get_user_asm(__gu_err, __gu_val, ptr,  , "=r",);	\
+	break;							\
+    default:							\
+	__gu_val = 0;						\
+	__gu_err = __get_user_bad();				\
+	break;							\
+    }								\
+    (x) = __gu_val;						\
+    __gu_err;							\
+})
+/*   dregs =  [pregs]   ==> 32bits
+             H[pregs]   ==> 16bits
+             B[pregs]   ==> 8 bits
+*/
+
+#define __get_user(x, ptr) get_user(x, ptr)
+
+#define __get_user_bad() (bad_user_access_length(), (-EFAULT))
+
+#define __get_user_asm(err,x,ptr,bhw,reg,option)		\
+	__asm__ ("%0 =" #bhw "[%1]"#option";\n\t"			\
+		 : "=d" (x)							\
+		 : "a" (__ptr(ptr)))
+
+#define copy_from_user(to, from, n)		(memcpy(to, from, n), 0)
+#define copy_to_user(to, from, n)		(memcpy(to, from, n), 0)
+
+#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
+#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
+
+#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; })
+
+#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; })
+
+/*
+ * Copy a null terminated string from userspace.
+ */
+
+static inline long
+strncpy_from_user(char *dst, const char *src, long count)
+{
+	char *tmp;
+	strncpy(dst, src, count);
+	for (tmp = dst; *tmp && count > 0; tmp++, count--)
+		;
+	return(tmp - dst); /* DAVIDM should we count a NUL ?  check getname */
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 on exception, a value greater than N if too long
+ */
+static inline long strnlen_user(const char *src, long n)
+{
+	return(strlen(src) + 1); /* DAVIDM make safer */
+}
+
+#define strlen_user(str) strnlen_user(str, 32767)
+
+/*
+ * Zero Userspace
+ */
+
+static inline unsigned long
+clear_user(void *to, unsigned long n)
+{
+	memset(to, 0, n);
+    return(0);
+}
+
+#endif /* _FRIONOMMU_UACCESS_H */
diff -urN linux-2.4.29/include/asm-blackfin/ucontext.h linux-2.4.29-uc1/include/asm-blackfin/ucontext.h
--- linux-2.4.29/include/asm-blackfin/ucontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/ucontext.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,30 @@
+/** Changes made by Tony Kou   Lineo Inc.    May 2001
+ *
+ *  Based on: include/m68knommu/ucontext.h  
+ */
+
+#ifndef _FRIONOMMU_UCONTEXT_H
+#define _FRIONOMMU_UCONTEXT_H
+
+typedef int greg_t;
+#define NGREG 20
+/* including: r0-7, p0-5, a0/1w, a0/1x, astat, rets */
+
+typedef greg_t gregset_t[NGREG];
+
+struct mcontext {
+	int version;
+	gregset_t gregs;
+};
+
+#define MCONTEXT_VERSION 2
+
+struct ucontext {
+	unsigned long	  uc_flags; /* the others are necessary */
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct mcontext	  uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif /* _FRIONOMMU_UCONTEXT_H */
diff -urN linux-2.4.29/include/asm-blackfin/unaligned.h linux-2.4.29-uc1/include/asm-blackfin/unaligned.h
--- linux-2.4.29/include/asm-blackfin/unaligned.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/unaligned.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,21 @@
+/* Changed by Lineo, Inc, May 2001 for FRIO */ 
+
+#ifndef __FRIO_UNALIGNED_H
+#define __FRIO_UNALIGNED_H
+
+#include <linux/config.h>
+
+/* The FRIO architecture follows Strict Data Alighment rules for accessing data,
+   and an unaligned data access causes a software exception.  */
+
+/* Use memmove here, so gcc does not insert a __builtin_memcpy. */
+
+#define get_unaligned(ptr) \
+  ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
+
+#define put_unaligned(val, ptr)				\
+  ({ __typeof__(*(ptr)) __tmp = (val);			\
+     memmove((ptr), &__tmp, sizeof(*(ptr)));		\
+     (void)0; })
+
+#endif /* __FRIO_UNALIGNED_H */
diff -urN linux-2.4.29/include/asm-blackfin/unistd.h linux-2.4.29-uc1/include/asm-blackfin/unistd.h
--- linux-2.4.29/include/asm-blackfin/unistd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/unistd.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,455 @@
+#ifndef __ASM_FRIO_UNISTD_H
+#define __ASM_FRIO_UNISTD_H
+
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_setup			0	/* used only by init, to get system going */
+#define __NR_exit			1
+#define __NR_fork			2
+#define __NR_read			3
+#define __NR_write			4
+#define __NR_open			5
+#define __NR_close			6
+#define __NR_waitpid			7
+#define __NR_creat			8
+#define __NR_link			9
+#define __NR_unlink			10
+#define __NR_execve			11
+#define __NR_chdir			12
+#define __NR_time			13
+#define __NR_mknod			14
+#define __NR_chmod			15
+#define __NR_lchown			16
+#define __NR_break			17
+#define __NR_oldstat			18
+#define __NR_lseek			19
+#define __NR_getpid			20
+#define __NR_mount			21
+#define __NR_umount			22
+#define __NR_setuid			23
+#define __NR_getuid			24
+#define __NR_stime			25
+#define __NR_ptrace			26
+#define __NR_alarm			27
+#define __NR_oldfstat			28
+#define __NR_pause			29
+#define __NR_utime			30
+#define __NR_stty			31
+#define __NR_gtty			32
+#define __NR_access			33
+#define __NR_nice			34
+#define __NR_ftime			35
+#define __NR_sync			36
+#define __NR_kill			37
+#define __NR_rename			38
+#define __NR_mkdir			39
+#define __NR_rmdir			40
+#define __NR_dup			41
+#define __NR_pipe			42
+#define __NR_times			43
+#define __NR_prof			44
+#define __NR_brk			45
+#define __NR_setgid			46
+#define __NR_getgid			47
+#define __NR_signal			48
+#define __NR_geteuid			49
+#define __NR_getegid			50
+#define __NR_acct			51
+#define __NR_phys			52
+#define __NR_lock			53
+#define __NR_ioctl			54
+#define __NR_fcntl			55
+#define __NR_mpx			56
+#define __NR_setpgid			57
+#define __NR_ulimit			58
+#define __NR_oldolduname		59
+#define __NR_umask			60
+#define __NR_chroot			61
+#define __NR_ustat			62
+#define __NR_dup2			63
+#define __NR_getppid			64
+#define __NR_getpgrp			65
+#define __NR_setsid			66
+#define __NR_sigaction			67
+#define __NR_sgetmask			68
+#define __NR_ssetmask			69
+#define __NR_setreuid			70
+#define __NR_setregid			71
+#define __NR_sigsuspend			72
+#define __NR_sigpending			73
+#define __NR_sethostname		74
+#define __NR_setrlimit			75
+#define __NR_getrlimit			76
+#define __NR_getrusage			77
+#define __NR_gettimeofday		78
+#define __NR_settimeofday		79
+#define __NR_getgroups			80
+#define __NR_setgroups			81
+#define __NR_select			82
+#define __NR_symlink			83
+#define __NR_oldlstat			84
+#define __NR_readlink			85
+#define __NR_uselib			86
+#define __NR_swapon			87
+#define __NR_reboot			88
+#define __NR_readdir			89
+#define __NR_mmap			90
+#define __NR_munmap			91
+#define __NR_truncate			92
+#define __NR_ftruncate			93
+#define __NR_fchmod			94
+#define __NR_fchown			95
+#define __NR_getpriority		96
+#define __NR_setpriority		97
+#define __NR_profil			98
+#define __NR_statfs			99
+#define __NR_fstatfs			100
+#define __NR_ioperm			101
+#define __NR_socketcall			102
+#define __NR_syslog			103
+#define __NR_setitimer			104
+#define __NR_getitimer			105
+#define __NR_stat			106
+#define __NR_lstat			107
+#define __NR_fstat			108
+#define __NR_olduname			109
+#define __NR_iopl			110
+#define __NR_vhangup			111
+#define __NR_idle			112
+#define __NR_syscall			113 /* syscall to call a syscall! */
+#define __NR_wait4			114
+#define __NR_swapoff			115
+#define __NR_sysinfo			116
+#define __NR_ipc			117
+#define __NR_fsync			118
+#define __NR_sigreturn			119
+#define __NR_clone			120
+#define __NR_setdomainname		121
+#define __NR_uname			122
+#define __NR_modify_ldt			123
+#define __NR_adjtimex			124
+#define __NR_mprotect			125
+#define __NR_sigprocmask		126
+#define __NR_create_module		127
+#define __NR_init_module		128
+#define __NR_delete_module		129
+#define __NR_get_kernel_syms		130
+#define __NR_quotactl			131
+#define __NR_getpgid			132
+#define __NR_fchdir			133
+#define __NR_bdflush			134
+#define __NR_sysfs			135
+#define __NR_personality		136
+#define __NR_afs_syscall		137 /* Syscall for Andrew File System */
+#define __NR_setfsuid			138
+#define __NR_setfsgid			139
+#define __NR__llseek			140
+#define __NR_getdents			141
+#define __NR__newselect			142
+#define __NR_flock			143
+#define __NR_msync			144
+#define __NR_readv			145
+#define __NR_writev			146
+#define __NR_getsid			147
+#define __NR_fdatasync			148
+#define __NR__sysctl			149
+#define __NR_mlock			150
+#define __NR_munlock			151
+#define __NR_mlockall			152
+#define __NR_munlockall			153
+#define __NR_sched_setparam			154
+#define __NR_sched_getparam			155
+#define __NR_sched_setscheduler			156
+#define __NR_sched_getscheduler			157
+#define __NR_sched_yield			158
+#define __NR_sched_get_priority_max		159
+#define __NR_sched_get_priority_min		160
+#define __NR_sched_rr_get_interval		161
+#define __NR_nanosleep			162
+#define __NR_mremap			163
+#define __NR_setresuid			164
+#define __NR_getresuid			165
+#define __NR_vm86			166
+#define __NR_query_module		167
+#define __NR_poll			168
+#define __NR_nfsservctl			169
+#define __NR_setresgid			170
+#define __NR_getresgid			171
+#define __NR_prctl			172
+#define __NR_rt_sigreturn		173
+#define __NR_rt_sigaction		174
+#define __NR_rt_sigprocmask		175
+#define __NR_rt_sigpending		176
+#define __NR_rt_sigtimedwait		177
+#define __NR_rt_sigqueueinfo		178
+#define __NR_rt_sigsuspend		179
+#define __NR_pread			180
+#define __NR_pwrite			181
+#define __NR_chown			182
+#define __NR_getcwd			183
+#define __NR_capget			184
+#define __NR_capset			185
+#define __NR_sigaltstack		186
+#define __NR_sendfile			187
+#define __NR_getpmsg			188	/* some people actually want streams */
+#define __NR_putpmsg			189	/* some people actually want streams */
+#define __NR_vfork			190
+#define __NR_ugetrlimit			191
+#define __NR_mmap2			192
+#define __NR_truncate64			193
+#define __NR_ftruncate64		194
+#define __NR_stat64			195
+#define __NR_lstat64			196
+#define __NR_fstat64			197
+
+
+#define __NR_chown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_lchown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+
+#define __syscall_return(type, res)					\
+do {									\
+	if ((unsigned long)(res) >= (unsigned long)(-125)) 		\
+	{	errno = -(res);						\
+		res = -1;						\
+	}								\
+	return (type) (res);						\
+} while (0)
+
+#define _syscall0(type,name)						\
+type name(void) {							\
+  long __res;								\
+  __asm__ __volatile__ (						\
+  "[--sp] = r5;\n\t"							\
+  "r5 = %1;\n\t"							\
+  "excpt 0;\n\t" 							\
+  "%0=r0;\n\t"								\
+  "r5 = [sp++];\n\t"							\
+  : "=da" (__res) 							\
+  : "i" (__NR_##name)							\
+  : "CC", "R5");							\
+  __syscall_return(type,__res);						\
+}
+
+#define _syscall1(type,name,type1,arg1)					\
+type name(type1 arg1) {							\
+  long __res;								\
+  __asm__ __volatile__ (						\
+  "[--sp] = r5;\n\t"							\
+  "r0=%2;\n\t"								\
+  "r5=%1;\n\t"								\
+  "excpt 0;\n\t" 							\
+  "%0=r0;\n\t"								\
+  "r5 = [sp++];\n\t"							\
+        : "=da" (__res)							\
+        : "i" (__NR_##name),						\
+	  "a" ((long)(arg1))						\
+	: "CC", "R0", "R5");						\
+  __syscall_return(type,__res);						\
+}
+
+#define _syscall2(type,name,type1,arg1,type2,arg2)			\
+type name(type1 arg1,type2 arg2) {					\
+  long __res;								\
+  __asm__ __volatile__ (						\
+  "[--sp] = r5;\n\t"							\
+  "r1=%3;\n\t"								\
+  "r0=%2;\n\t"								\
+  "r5=%1;\n\t"								\
+  "excpt 0;\n\t" 							\
+  "%0=r0;\n\t"								\
+  "r5 = [sp++];\n\t"							\
+        : "=da" (__res)							\
+        : "i" (__NR_##name),						\
+	  "a" ((long)(arg1)),						\
+	  "a" ((long)(arg2))						\
+	: "CC", "R0","R1", "R5");					\
+  __syscall_return(type,__res);						\
+}
+
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)		\
+type name(type1 arg1,type2 arg2,type3 arg3) {				\
+  long __res;								\
+  __asm__ __volatile__ (						\
+  "[--sp] = r5;\n\t"							\
+  "r2=%4;\n\t"								\
+  "r1=%3;\n\t"								\
+  "r0=%2;\n\t"								\
+  "r5=%1;\n\t"								\
+  "excpt 0;\n\t" 							\
+  "%0=r0;\n\t"								\
+  "r5 = [sp++];\n\t"							\
+        : "=da" (__res)							\
+        : "i"   (__NR_##name),						\
+	  "a"   ((long)(arg1)),						\
+	  "a"   ((long)(arg2)),						\
+	  "a"   ((long)(arg3))						\
+        : "CC", "R0","R1","R2", "R5");					\
+  __syscall_return(type,__res);						\
+}
+
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)\
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {		\
+  long __res;								\
+  __asm__ __volatile__ (						\
+  "[--sp] = r5;\n\t"							\
+  "[--sp] = r3;\n\t"							\
+  "r3=%5;\n\t"								\
+  "r2=%4;\n\t"								\
+  "r1=%3;\n\t"								\
+  "r0=%2;\n\t"								\
+  "r5=%1;\n\t"								\
+  "excpt 0;\n\t" 							\
+  "%0=r0;\n\t"								\
+  "r3 = [sp++];\n\t"							\
+  "r5 = [sp++];\n\t"							\
+  	: "=da" (__res)							\
+  	: "i"  (__NR_##name),						\
+	  "a"  ((long)(arg1)),						\
+	  "a"  ((long)(arg2)),						\
+	  "a"  ((long)(arg3)),						\
+	  "a"  ((long)(arg4))						\
+  	: "CC", "R0","R1","R2","R3", "R5");				\
+  __syscall_return(type,__res);						\
+}
+  
+
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5)	\
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) {	\
+  long __res;								\
+  __asm__ __volatile__ (						\
+  "[--sp] = ( r7:3 );\n\t"						\
+  "r4=%6;\n\t"								\
+  "r3=%5;\n\t"								\
+  "r2=%4;\n\t"								\
+  "r1=%3;\n\t"								\
+  "r0=%2;\n\t"								\
+  "r5=%1;\n\t"								\
+  "excpt 0;\n\t" 							\
+  "%0=r0;\n\t"								\
+  "( r7:3 ) = [sp++];\n\t"						\
+  	: "=da" (__res)							\
+  	: "i"  (__NR_##name),						\
+	  "a"  ((long)(arg1)),						\
+	  "a"  ((long)(arg2)),						\
+	  "a"  ((long)(arg3)),						\
+	  "a"  ((long)(arg4)),						\
+	  "a"  ((long)(arg5))						\
+	: "CC","R0","R1","R2","R3","R4","R5");				\
+  __syscall_return(type,__res);						\
+}
+
+#ifdef __KERNEL_SYSCALLS__
+
+static inline int idle(void)
+{
+	extern int sys_idle(void);
+	return sys_idle();
+}
+
+static inline int pause(void)
+{
+	extern int sys_pause(void);
+	return sys_pause();
+}
+
+static inline int sync(void)
+{
+	extern int sys_sync(void);
+	return sys_sync();
+}
+
+static inline pid_t setsid(void)
+{
+	extern int sys_setsid(void);
+	return sys_setsid();
+}
+
+static inline int write(int fd, const char *buf, off_t count)
+{
+	extern int sys_write(int, const char *, int);
+	return sys_write(fd, buf, count);
+}
+
+static inline int read(int fd, char *buf, off_t count)
+{
+	extern int sys_read(int, char *, int);
+	return sys_read(fd, buf, count);
+}
+
+static inline off_t lseek(int fd, off_t offset, int count)
+{
+	extern off_t sys_lseek(int, off_t, int);
+	return sys_lseek(fd, offset, count);
+}
+
+static inline int dup(int fd)
+{
+	extern int sys_dup(int);
+	return sys_dup(fd);
+}
+
+static inline int open(const char *file, int flag, int mode)
+{
+	extern long sys_open(const char *, int, int);
+	return sys_open(file, flag, mode);
+}
+
+static inline int close(int fd)
+{
+	return sys_close(fd);
+}
+
+static inline int _exit(int exitcode)
+{
+	extern int sys_exit(int) __attribute__((noreturn));
+	return sys_exit(exitcode);
+}
+
+static inline pid_t waitpid(pid_t pid, int *wait_stat, int options)
+{
+	extern long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru);
+	return sys_wait4(pid, wait_stat, options, NULL);
+}
+
+static inline int delete_module(const char *name)
+{
+	extern int sys_delete_module(const char *name);
+	return sys_delete_module(name);
+}
+
+static inline pid_t wait(int * wait_stat)
+{
+	extern long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru);
+	return sys_wait4(-1, wait_stat, 0, NULL);
+}
+
+/*
+ * The following two can't be eliminated yet - they rely on
+ * specific conditions.
+ */
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp);
+
+#endif	/* __KERNEL_SYSCALLS__ */
+#endif  /* __ASM_FRIO_UNISTD_H */
diff -urN linux-2.4.29/include/asm-blackfin/user.h linux-2.4.29-uc1/include/asm-blackfin/user.h
--- linux-2.4.29/include/asm-blackfin/user.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/user.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,91 @@
+#ifndef _FRIO_USER_H
+#define _FRIO_USER_H
+
+/* Changes by Tony Kou   Lineo, Inc.  July, 2001
+ *
+ * Based include/asm-m68knommu/user.h
+ *
+ */
+
+#include <asm/page.h>
+
+/* Core file format: The core file is written in such a way that gdb
+   can understand it and provide useful information to the user (under
+   linux we use the 'trad-core' bfd).  There are quite a number of
+   obstacles to being able to view the contents of the floating point
+   registers, and until these are solved you will not be able to view the
+   contents of them.  Actually, you can read in the core file and look at
+   the contents of the user struct to find out what the floating point
+   registers contain.
+   The actual file contents are as follows:
+   UPAGE: 1 page consisting of a user struct that tells gdb what is present
+   in the file.  Directly after this is a copy of the task_struct, which
+   is currently not used by gdb, but it may come in useful at some point.
+   All of the registers are stored as part of the upage.  The upage should
+   always be only one page.
+   DATA: The data area is stored.  We use current->end_text to
+   current->brk to pick up all of the user variables, plus any memory
+   that may have been malloced.  No attempt is made to determine if a page
+   is demand-zero or if a page is totally unused, we just cover the entire
+   range.  All of the addresses are rounded in such a way that an integral
+   number of pages is written.
+   STACK: We need the stack information in order to get a meaningful
+   backtrace.  We need to write the data from (esp) to
+   current->start_stack, so we round each of these off in order to be able
+   to write an integer number of pages.
+   The minimum core file size is 3 pages, or 12288 bytes.
+*/
+
+
+/* This is the old layout of "struct pt_regs" as of Linux 1.x, and
+   is still the layout used by user (the new pt_regs doesn't have
+   all registers). */
+struct user_regs_struct {
+	long r0,r1,r2,r3,r4,r5,r6,r7;
+	long p0,p1,p2,p3,p4,p5,usp,fp;
+	long i0,i1,i2,i3;
+	long l0,l1,l2,l3;
+	long b0,b1,b2,b3;
+	long m0,m1,m2,m3;
+	long a0w,a1w;
+	long a0x,a1x;
+	unsigned long rets;
+	unsigned long astat;
+	unsigned long pc;
+        unsigned long orig_r0;
+};
+
+	
+/* When the kernel dumps core, it starts by dumping the user struct -
+   this will be used by gdb to figure out where the data and stack segments
+   are within the file, and what virtual addresses to use. */
+
+struct user{
+/* We start with the registers, to mimic the way that "memory" is returned
+   from the ptrace(3,...) function.  */
+
+  struct user_regs_struct regs;	/* Where the registers are actually stored */
+
+/* The rest of this junk is to help gdb figure out what goes where */
+  unsigned long int u_tsize;	/* Text segment size (pages). */
+  unsigned long int u_dsize;	/* Data segment size (pages). */
+  unsigned long int u_ssize;	/* Stack segment size (pages). */
+  unsigned long start_code;     /* Starting virtual address of text. */
+  unsigned long start_stack;	/* Starting virtual address of stack area.
+				   This is actually the bottom of the stack,
+				   the top of the stack is always found in the
+				   esp register.  */
+  long int signal;     		/* Signal that caused the core dump. */
+  int reserved;			/* No longer used */
+  struct user_regs_struct *u_ar0;
+				/* Used by gdb to help find the values for */
+				/* the registers. */
+  unsigned long magic;		/* To uniquely identify a core file */
+  char u_comm[32];		/* User command that was responsible */
+};
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+#endif
diff -urN linux-2.4.29/include/asm-blackfin/virtconvert.h linux-2.4.29-uc1/include/asm-blackfin/virtconvert.h
--- linux-2.4.29/include/asm-blackfin/virtconvert.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-blackfin/virtconvert.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,26 @@
+#ifndef __FRIONOMMU_VIRT_CONVERT__
+#define __FRIONOMMU_VIRT_CONVERT__
+
+/*
+ * Macros used for converting between virtual and physical mappings.
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+
+#define mm_vtop(vaddr)		((unsigned long) vaddr)
+#define mm_ptov(vaddr)		((unsigned long) vaddr)
+#define phys_to_virt(vaddr)	((unsigned long) vaddr)
+#define virt_to_phys(vaddr)	((unsigned long) vaddr)
+
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+#define __page_address(page) 	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define page_to_phys(page)	virt_to_phys((void *)__page_address(page))
+
+#endif /* __KERNEL__ */
+#endif /* __FRIONOMMU_VIRT_CONVERT__ */
diff -urN linux-2.4.29/include/asm-cris/div64.h linux-2.4.29-uc1/include/asm-cris/div64.h
--- linux-2.4.29/include/asm-cris/div64.h	2001-02-09 00:32:44.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-cris/div64.h	2005-06-14 02:11:27.000000000 +0100
@@ -1,16 +1 @@
-#ifndef __ASM_CRIS_DIV64
-#define __ASM_CRIS_DIV64
-
-/* copy from asm-arm */
-
-/* We're not 64-bit, but... */
-#define do_div(n,base)						\
-({								\
-	int __res;						\
-	__res = ((unsigned long)n) % (unsigned int)base;	\
-	n = ((unsigned long)n) / (unsigned int)base;		\
-	__res;							\
-})
-
-#endif
-
+#include <asm-generic/div64.h>
diff -urN linux-2.4.29/include/asm-e1nommu/a.out.h linux-2.4.29-uc1/include/asm-e1nommu/a.out.h
--- linux-2.4.29/include/asm-e1nommu/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/a.out.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,4 @@
+#ifndef _HYPERSTONE_A_OUT_H_
+#define _HYPERSTONE_A_OUT_H_
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/atomic.h linux-2.4.29-uc1/include/asm-e1nommu/atomic.h
--- linux-2.4.29/include/asm-e1nommu/atomic.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/atomic.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,119 @@
+#ifndef _HYPERSTONE_NOMMU_ATOMIC_H
+#define _HYPERSTONE_NOMMU_ATOMIC_H
+
+#include <asm/system.h>
+/*
+ * We do not have SMP Hyperstone systems, so we don't have to deal with that.
+ */
+
+typedef struct { int counter; } atomic_t;
+#define ATOMIC_INIT(i)	{ (i) }
+
+#define atomic_read(v)		((v)->counter)
+#define atomic_set(v, i)	(((v)->counter) = i)
+
+static __inline__ int atomic_add(int i, atomic_t *v)
+{
+	int newval;
+	cli();
+	newval = v->counter += i;
+	sti();
+	return newval;
+}
+
+static __inline__ int atomic_add_negative(int i, atomic_t *v)
+{
+	int newval;
+	cli();
+	newval = v->counter += i;
+	sti();
+	return newval < 0;
+}
+
+static __inline__ void atomic_sub(int i, atomic_t *v)
+{
+	cli();
+	v->counter -= i;
+	sti();
+}
+
+static __inline__ void atomic_inc(volatile atomic_t *v)
+{
+	cli();
+	v->counter += 1;
+	sti();
+}
+
+static __inline__ void atomic_dec(volatile atomic_t *v)
+{
+	cli();
+	v->counter -= 1;
+	sti();
+}
+
+static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
+{
+	int result;
+
+	cli();
+	v->counter -= 1;
+	result = (v->counter == 0);
+	sti();
+	
+	return result;
+}
+
+static __inline__ void atomic_clear_mask(unsigned long mask, volatile atomic_t *v)
+{
+	cli();
+	v->counter &= mask;
+	sti();
+}
+
+static __inline__ void atomic_set_mask(unsigned long mask, volatile atomic_t *v)
+{
+	cli();
+	v->counter |= mask;
+	sti();
+}
+
+extern __inline__ int atomic_add_return(int i, atomic_t * v)
+{
+	unsigned long temp;
+
+	cli();
+	temp = v->counter;
+	temp += i;
+	v->counter = temp;
+	sti();
+
+	return temp;
+}
+
+extern __inline__ int atomic_sub_return(int i, atomic_t * v)
+{
+	unsigned long temp;
+
+	cli();
+	temp = v->counter;
+	temp -= i;
+	v->counter = temp;
+	sti();
+
+	return temp;
+}
+
+#define atomic_dec_return(v) atomic_sub_return(1,(v))
+#define atomic_inc_return(v) atomic_add_return(1,(v))
+
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec()    barrier()
+#define smp_mb__after_atomic_dec() barrier()
+#define smp_mb__before_atomic_inc()    barrier()
+#define smp_mb__after_atomic_inc() barrier()
+
+
+#endif /* _HYPERSTONE_NOMMU_ATOMIC_H */
diff -urN linux-2.4.29/include/asm-e1nommu/bitops.h linux-2.4.29-uc1/include/asm-e1nommu/bitops.h
--- linux-2.4.29/include/asm-e1nommu/bitops.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/bitops.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,365 @@
+#ifndef _HYPERSTONE_NOMMU_BITOPS_H
+#define _HYPERSTONE_NOMMU_BITOPS_H
+
+#include <linux/config.h>
+#include <asm/byteorder.h>	/* swab32 */
+#include <asm/system.h>		/* save_flags */
+
+#ifdef __KERNEL__
+
+/*
+ * The __ functions are not atomic
+ */
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+static __inline__ unsigned long ffz(unsigned long word)
+{
+	unsigned long result = 0;
+
+	while(word & 1) {
+		result++;
+		word >>= 1;
+	}
+	return result;
+}
+
+
+static __inline__ void set_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_flags(flags); cli();
+	*a |= mask;
+	restore_flags(flags);
+}
+
+static __inline__ void __set_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	*a |= mask;
+}
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+
+static __inline__ void clear_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_flags(flags); cli();
+	*a &= ~mask;
+	restore_flags(flags);
+}
+
+static __inline__ void change_bit(int nr, volatile void * addr)
+{
+	int mask, flags;
+	unsigned long *ADDR = (unsigned long *) addr;
+
+	ADDR += nr >> 5;
+	mask = 1 << (nr & 31);
+	save_flags(flags); cli();
+	*ADDR ^= mask;
+	restore_flags(flags);
+}
+
+static __inline__ void __change_bit(int nr, volatile void * addr)
+{
+	int mask;
+	unsigned long *ADDR = (unsigned long *) addr;
+
+	ADDR += nr >> 5;
+	mask = 1 << (nr & 31);
+	*ADDR ^= mask;
+}
+
+static __inline__ int test_and_set_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+	return retval;
+}
+
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+	return retval;
+}
+
+static __inline__ int test_and_change_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	return retval;
+}
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+static __inline__ int __constant_test_bit(int nr, const volatile void * addr)
+{
+	return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
+}
+
+static __inline__ int __test_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	return ((mask & *a) != 0);
+}
+
+#define test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ __constant_test_bit((nr),(addr)) : \
+ __test_bit((nr),(addr)))
+
+#define find_first_zero_bit(addr, size) \
+        find_next_zero_bit((addr), (size), 0)
+
+static __inline__ int find_next_zero_bit (void * addr, int size, int offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if (offset) {
+		tmp = *(p++);
+		tmp |= ~0UL >> (32-offset);
+		if (size < 32)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while (size & ~31UL) {
+		if (~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp |= ~0UL >> size;
+found_middle:
+	return result + ffz(tmp);
+}
+
+#define ffs(x) generic_ffs(x)
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+
+static __inline__ int ext2_set_bit(int nr, volatile void * addr)
+{
+	int		mask, retval;
+	unsigned long	flags;
+	volatile unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	save_and_cli(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR |= mask;
+	restore_flags(flags);
+	return retval;
+}
+
+static __inline__ int ext2_clear_bit(int nr, volatile void * addr)
+{
+	int		mask, retval;
+	unsigned long	flags;
+	volatile unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	save_and_cli(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR &= ~mask;
+	restore_flags(flags);
+	return retval;
+}
+
+static __inline__ int ext2_test_bit(int nr, const volatile void * addr)
+{
+	int			mask;
+	const volatile unsigned char	*ADDR = (const unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	return ((mask & *ADDR) != 0);
+}
+
+#define ext2_find_first_zero_bit(addr, size) \
+        ext2_find_next_zero_bit((addr), (size), 0)
+
+static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if(offset) {
+		/* We hold the little endian value in tmp, but then the
+		 * shift is illegal. So we could keep a big endian value
+		 * in tmp, like this:
+		 *
+		 * tmp = __swab32(*(p++));
+		 * tmp |= ~0UL >> (32-offset);
+		 *
+		 * but this would decrease preformance, so we change the
+		 * shift:
+		 */
+		tmp = *(p++);
+		tmp |= __swab32(~0UL >> (32-offset));
+		if(size < 32)
+			goto found_first;
+		if(~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while(size & ~31UL) {
+		if(~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if(!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	/* tmp is little endian, so we would have to swab the shift,
+	 * see above. But then we have to swab tmp below for ffz, so
+	 * we might as well do this here.
+	 */
+	return result + ffz(__swab32(tmp) | (~0UL << size));
+found_middle:
+	return result + ffz(__swab32(tmp));
+}
+
+/* Bitmap functions for the minix filesystem.  */
+#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr) set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+
+/**
+ * hweightN - returns the hamming weight of a N-bit word
+ * @x: the word to weigh
+ *
+ * The Hamming Weight of a number is the total number of bits set in it.
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+#endif /* __KERNEL__ */
+
+#endif /* _HYPERSTONE_NOMMU_BITOPS_H */
diff -urN linux-2.4.29/include/asm-e1nommu/blkmem.h linux-2.4.29-uc1/include/asm-e1nommu/blkmem.h
--- linux-2.4.29/include/asm-e1nommu/blkmem.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/blkmem.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,36 @@
+/*
+ * include/asm-hyperstone-nommu/blkmem.h -- `blkmem' device configuration
+ *
+ *  Copyright (c) 2003, Yannis Mitsos, George Thanos 
+ *  					yannis.mitsos@gdt.gr george.thanos@gdt.gr	
+ *  Original copyright  belongs to (C) 2001,2002  NEC Corporation and
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#ifndef __ASM_HYPERSTONE_NOMMU_BLKMEM_H__
+#define __ASM_HYPERSTONE_NOMMU_BLKMEM_H__
+
+#ifndef FIXUP_ARENAS  /* provide a default */
+
+#ifndef ROOT_FS_IMAGE_RW
+#define ROOT_FS_IMAGE_RW	0 /* assume read-only */
+#endif
+
+#define CAT_ROMARRAY
+/* These should be defined by the linker map.  */
+extern unsigned long _ebss;
+extern unsigned long _romfs_size;
+
+/* Make the single arena point use them.  */
+#define FIXUP_ARENAS							      \
+        arena[0].rw = ROOT_FS_IMAGE_RW;					      \
+	arena[0].address = (unsigned long)&_ebss;	      \
+	arena[0].length = _romfs_size ; /* Let the others find the length */
+#endif /* FIXUP_ARENAS */
+
+#endif /* __ASM_HYPERSTONE_NOMMU_BLKMEM_H__ */
diff -urN linux-2.4.29/include/asm-e1nommu/bugs.h linux-2.4.29-uc1/include/asm-e1nommu/bugs.h
--- linux-2.4.29/include/asm-e1nommu/bugs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/bugs.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef __HYPERSTONE_BUGS_H
+#define __HYPERSTONE_BUGS_H
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *	void check_bugs(void);
+ */
+
+static void check_bugs(void)
+{
+}
+#endif 
diff -urN linux-2.4.29/include/asm-e1nommu/byteorder.h linux-2.4.29-uc1/include/asm-e1nommu/byteorder.h
--- linux-2.4.29/include/asm-e1nommu/byteorder.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/byteorder.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef _HYPERSTONE_BYTEORDER_H_
+#define _HYPERSTONE_BYTEORDER_H_
+
+#include <asm/types.h>
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#include <linux/byteorder/big_endian.h>
+
+#endif /* _HYPERSTONE_BYTEORDER_H_ */
diff -urN linux-2.4.29/include/asm-e1nommu/cache.h linux-2.4.29-uc1/include/asm-e1nommu/cache.h
--- linux-2.4.29/include/asm-e1nommu/cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/cache.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,9 @@
+#ifndef _HYPERSTONE_CACHE_H
+#define _HYPERSTONE_CACHE_H
+
+/* bytes per L1 cache line */
+#define        L1_CACHE_BYTES			16 
+#define        L1_CACHE_ALIGN(x)       (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
+#define        SMP_CACHE_BYTES          L1_CACHE_BYTES
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/checksum.h linux-2.4.29-uc1/include/asm-e1nommu/checksum.h
--- linux-2.4.29/include/asm-e1nommu/checksum.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/checksum.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,118 @@
+#ifndef _HYPERSTONE_NOMMU_CHECKSUM_H
+#define _HYPERSTONE_NOMMU_CHECKSUM_H
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ *
+ */
+extern unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl);
+
+/*
+ *	Fold a partial checksum
+ */
+static inline unsigned int csum_fold(unsigned int sum)
+{
+	sum = (sum & 0xffff) + (sum >> 16);
+	sum = (sum & 0xffff) + (sum >> 16);
+	return ~sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline unsigned int
+csum_tcpudp_nofold( unsigned long saddr, unsigned long daddr,  
+			   	    unsigned short len,  unsigned short proto,  
+					unsigned int sum)
+{
+#ifdef FULL_DEBUG
+	__u64 result;
+	result = (saddr + daddr + sum +
+		  ((__u64) len ) +
+		  ((__u64) proto << 16));
+	/* fold down to 32 bits */
+	/* 64 to 33 */
+	result = (result & 0xffffffff) + (result >> 32);
+	/* 33 to 32 */
+	result = (result & 0xffffffff) + (result >> 32);
+	
+	return result;
+#else
+    __asm__("
+	add  %0,%1
+	addc %0,%2
+	addc %0,%3
+	addc %0,C
+	"
+	: "=l" (sum)
+	: "l" (daddr), "l"(saddr), "l"((proto<<16)+len), "0"(sum));
+	return sum;
+#endif
+}
+
+static inline unsigned short int
+csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
+		  unsigned short proto, unsigned int sum)
+{
+	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+extern unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+extern unsigned int csum_partial_copy(const char *src, char *dst, int len, unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from user space 
+ * this is obsolete and will go away.
+ */
+#define csum_partial_copy_fromuser csum_partial_copy
+
+/*
+ * this is a new version of the above that records errors it finds in *errp,
+ * but continues and zeros the rest of the buffer.
+ */
+extern unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len, unsigned int sum, int *errp);
+
+#define csum_partial_copy_nocheck(src, dst, len, sum)	\
+	csum_partial_copy((src), (dst), (len), (sum))
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+extern unsigned short ip_compute_csum(const unsigned char * buff, int len);
+
+#define _HAVE_ARCH_IPV6_CSUM
+static inline unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
+						     struct in6_addr *daddr,
+						     __u16 len,
+						     unsigned short proto,
+						     unsigned int sum) 
+{
+	BUG();
+	return csum_fold(sum);
+}
+
+#endif /* _HYPERSTONE_NOMMU_CHECKSUM_H */
diff -urN linux-2.4.29/include/asm-e1nommu/current.h linux-2.4.29-uc1/include/asm-e1nommu/current.h
--- linux-2.4.29/include/asm-e1nommu/current.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/current.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,9 @@
+#ifndef _HYPERSTONE_CURRENT_H
+#define _HYPERSTONE_CURRENT_H
+
+extern struct task_struct *_current_task;
+#define get_current()   _current_task
+#define current 	_current_task
+
+
+#endif /* !(_HYPERSTONE_CURRENT_H) */
diff -urN linux-2.4.29/include/asm-e1nommu/delay.h linux-2.4.29-uc1/include/asm-e1nommu/delay.h
--- linux-2.4.29/include/asm-e1nommu/delay.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/delay.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,9 @@
+#ifndef _HYPERSTONE_NOMMU_DELAY_H
+#define _HYPERSTONE_NOMMU__DELAY_H
+
+extern void __udelay(unsigned long usecs);
+extern void __delay(unsigned long loops);
+
+#define udelay(n) __udelay(n)
+
+#endif  /*  _HYPERSTONE_NOMMU_DELAY_H */
diff -urN linux-2.4.29/include/asm-e1nommu/div64.h linux-2.4.29-uc1/include/asm-e1nommu/div64.h
--- linux-2.4.29/include/asm-e1nommu/div64.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/div64.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,17 @@
+#ifndef __HYPERSTONE_NOMMU_DIV64
+#define __HYPERSTONE_NOMMU_DIV64
+/* 
+ * Taken from ARM nommu 
+ */
+
+/* We're not 64-bit, but... */
+#define do_div(n,base)						\
+({								\
+	int __res;						\
+	__res = ((unsigned long)n) % (unsigned int)base;	\
+	n = ((unsigned long)n) / (unsigned int)base;		\
+	__res;							\
+})
+
+#endif
+
diff -urN linux-2.4.29/include/asm-e1nommu/dma.h linux-2.4.29-uc1/include/asm-e1nommu/dma.h
--- linux-2.4.29/include/asm-e1nommu/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/dma.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,10 @@
+#ifndef _HYPERSTONE_DMA_H
+#define _HYPERSTONE_DMA_H
+
+#define MAX_DMA_ADDRESS  	PAGE_OFFSET
+#define MAX_DMA_CHANNELS 	0
+
+extern int request_dma(unsigned int dmanr, const char * device_id);	/* reserve a DMA channel */
+extern void free_dma(unsigned int dmanr);	/* release it again */
+
+#endif /* _M68K_DMA_H */
diff -urN linux-2.4.29/include/asm-e1nommu/elf.h linux-2.4.29-uc1/include/asm-e1nommu/elf.h
--- linux-2.4.29/include/asm-e1nommu/elf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/elf.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,77 @@
+#ifndef __V850_ELF_H__
+#define __V850_ELF_H__
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+#include <asm/byteorder.h>
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_fpu_struct elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ( (x)->e_machine == EM_E1 )
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#ifdef __LITTLE_ENDIAN__
+#define ELF_DATA	ELFDATA2LSB
+#else
+#define ELF_DATA	ELFDATA2MSB
+#endif
+#define ELF_ARCH	EM_V850
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	4096
+
+
+#define ELF_CORE_COPY_REGS(_dest,_regs)				\
+	memcpy((char *) &_dest, (char *) _regs,			\
+	       sizeof(struct pt_regs));
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this CPU supports.  This could be done in user space,
+   but it's not easy, and we've already done it here.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.
+
+   For the moment, we have only optimizations for the Intel generations,
+   but that could change... */
+
+#define ELF_PLATFORM  (NULL)
+
+#if 0
+#define ELF_PLAT_INIT(_r)						      \
+  do {									      \
+	 _r->gpr[0] =  _r->gpr[1] =  _r->gpr[2] =  _r->gpr[3] =		      \
+	 _r->gpr[4] =  _r->gpr[5] =  _r->gpr[6] =  _r->gpr[7] =		      \
+	 _r->gpr[8] =  _r->gpr[9] = _r->gpr[10] = _r->gpr[11] =		      \
+	_r->gpr[12] = _r->gpr[13] = _r->gpr[14] = _r->gpr[15] =		      \
+	_r->gpr[16] = _r->gpr[17] = _r->gpr[18] = _r->gpr[19] =		      \
+	_r->gpr[20] = _r->gpr[21] = _r->gpr[22] = _r->gpr[23] =		      \
+	_r->gpr[24] = _r->gpr[25] = _r->gpr[26] = _r->gpr[27] =		      \
+	_r->gpr[28] = _r->gpr[29] = _r->gpr[30] = _r->gpr[31] =		      \
+	0;								      \
+  } while (0)
+#endif
+
+#ifdef __KERNEL__
+#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+#endif
+
+#endif /* __V850_ELF_H__ */
diff -urN linux-2.4.29/include/asm-e1nommu/errno.h linux-2.4.29-uc1/include/asm-e1nommu/errno.h
--- linux-2.4.29/include/asm-e1nommu/errno.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/errno.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,132 @@
+#ifndef _HYPERSTONE_ERRNO_H_
+#define _HYPERSTONE_ERRNO_H_
+
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Arg list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	EDEADLK		35	/* Resource deadlock would occur */
+#define	ENAMETOOLONG	36	/* File name too long */
+#define	ENOLCK		37	/* No record locks available */
+#define	ENOSYS		38	/* Function not implemented */
+#define	ENOTEMPTY	39	/* Directory not empty */
+#define	ELOOP		40	/* Too many symbolic links encountered */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	ENOMSG		42	/* No message of desired type */
+#define	EIDRM		43	/* Identifier removed */
+#define	ECHRNG		44	/* Channel number out of range */
+#define	EL2NSYNC	45	/* Level 2 not synchronized */
+#define	EL3HLT		46	/* Level 3 halted */
+#define	EL3RST		47	/* Level 3 reset */
+#define	ELNRNG		48	/* Link number out of range */
+#define	EUNATCH		49	/* Protocol driver not attached */
+#define	ENOCSI		50	/* No CSI structure available */
+#define	EL2HLT		51	/* Level 2 halted */
+#define	EBADE		52	/* Invalid exchange */
+#define	EBADR		53	/* Invalid request descriptor */
+#define	EXFULL		54	/* Exchange full */
+#define	ENOANO		55	/* No anode */
+#define	EBADRQC		56	/* Invalid request code */
+#define	EBADSLT		57	/* Invalid slot */
+
+#define	EDEADLOCK	EDEADLK
+
+#define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
+#define	EMULTIHOP	72	/* Multihop attempted */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EBADMSG		74	/* Not a data message */
+#define	EOVERFLOW	75	/* Value too large for defined data type */
+#define	ENOTUNIQ	76	/* Name not unique on network */
+#define	EBADFD		77	/* File descriptor in bad state */
+#define	EREMCHG		78	/* Remote address changed */
+#define	ELIBACC		79	/* Can not access a needed shared library */
+#define	ELIBBAD		80	/* Accessing a corrupted shared library */
+#define	ELIBSCN		81	/* .lib section in a.out corrupted */
+#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	EILSEQ		84	/* Illegal byte sequence */
+#define	ERESTART	85	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUSERS		87	/* Too many users */
+#define	ENOTSOCK	88	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	89	/* Destination address required */
+#define	EMSGSIZE	90	/* Message too long */
+#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	92	/* Protocol not available */
+#define	EPROTONOSUPPORT	93	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
+#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	96	/* Protocol family not supported */
+#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
+#define	EADDRINUSE	98	/* Address already in use */
+#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
+#define	ENETDOWN	100	/* Network is down */
+#define	ENETUNREACH	101	/* Network is unreachable */
+#define	ENETRESET	102	/* Network dropped connection because of reset */
+#define	ECONNABORTED	103	/* Software caused connection abort */
+#define	ECONNRESET	104	/* Connection reset by peer */
+#define	ENOBUFS		105	/* No buffer space available */
+#define	EISCONN		106	/* Transport endpoint is already connected */
+#define	ENOTCONN	107	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
+#define	ETIMEDOUT	110	/* Connection timed out */
+#define	ECONNREFUSED	111	/* Connection refused */
+#define	EHOSTDOWN	112	/* Host is down */
+#define	EHOSTUNREACH	113	/* No route to host */
+#define	EALREADY	114	/* Operation already in progress */
+#define	EINPROGRESS	115	/* Operation now in progress */
+#define	ESTALE		116	/* Stale NFS file handle */
+#define	EUCLEAN		117	/* Structure needs cleaning */
+#define	ENOTNAM		118	/* Not a XENIX named type file */
+#define	ENAVAIL		119	/* No XENIX semaphores available */
+#define	EISNAM		120	/* Is a named type file */
+#define	EREMOTEIO	121	/* Remote I/O error */
+#define	EDQUOT		122	/* Quota exceeded */
+
+#define	ENOMEDIUM	123	/* No medium found */
+#define	EMEDIUMTYPE	124	/* Wrong medium type */
+
+#endif /* _HYPERSTONE_ERRNO_H_ */
diff -urN linux-2.4.29/include/asm-e1nommu/ext2_bitops.h linux-2.4.29-uc1/include/asm-e1nommu/ext2_bitops.h
--- linux-2.4.29/include/asm-e1nommu/ext2_bitops.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/ext2_bitops.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,93 @@
+#ifndef _HYPERSTONE_EXT2_BITOPS_H_
+#define _HYPERSTONE_EXT2_BITOPS_H_
+
+/* ext2 bitops - Taken from MIPS and PPC implementations of bitops.h */
+
+static __inline__ int ext2_set_bit(int nr, volatile void * addr)
+{
+        int mask, retval;
+        volatile unsigned char *ADDR = (unsigned char *) addr;
+
+        ADDR += nr >> 3;
+        mask = 1 << (nr & 7);
+        cli();
+        retval = (mask & *ADDR) != 0;
+        *ADDR |= mask;
+        sti();
+        return retval;
+}
+
+static __inline__ int ext2_clear_bit(int nr, volatile void * addr)
+{
+        int mask, retval;
+        volatile unsigned char *ADDR = (unsigned char *) addr;
+
+        ADDR += nr >> 3;
+        mask = 1 << (nr & 7);
+        cli();
+        retval = (mask & *ADDR) != 0;
+        *ADDR &= ~mask;
+        sti();
+        return retval;
+}
+
+static __inline__ int ext2_test_bit(int nr, const volatile void * addr)
+{
+        int mask;
+        const volatile unsigned char *ADDR = (const unsigned char *) addr;
+
+        ADDR += nr >> 3;
+        mask = 1 << (nr & 7);
+        return ((mask & *ADDR) != 0);
+}
+
+/* This implementation is originally taken from PPC
+ */
+#define ext2_find_first_zero_bit(addr, size) \
+        ext2_find_next_zero_bit((addr), (size), 0)
+
+extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+        unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+        unsigned long result = offset & ~31UL;
+        unsigned long tmp;
+
+        if (offset >= size)
+                return size;
+        size -= result;
+        offset &= 31UL;
+        if(offset) {
+                tmp = *(p++);
+                tmp |= (~0UL >> (32-offset));
+                if(size < 32)
+                        goto found_first;
+                if(~tmp)
+                        goto found_middle;
+                size -= 32;
+                result += 32;
+        }
+        while(size & ~31UL) {
+                if(~(tmp = *(p++)))
+                        goto found_middle;
+                result += 32;
+                size -= 32;
+        }
+        if(!size)
+                return result;
+        tmp = *p;
+
+found_first:
+        return result + ffz((tmp) | (~0UL << size));
+found_middle:
+        return result + ffz((tmp));
+}
+
+/* Bitmap functions for the minix filesystem.  */
+#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr) set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+
+#endif
+
diff -urN linux-2.4.29/include/asm-e1nommu/fcntl.h linux-2.4.29-uc1/include/asm-e1nommu/fcntl.h
--- linux-2.4.29/include/asm-e1nommu/fcntl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/fcntl.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,86 @@
+#ifndef _HYPERSTONE_FCNTL_H
+#define _HYPERSTONE_FCNTL_H
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	  0003
+#define O_RDONLY	    00
+#define O_WRONLY	    01
+#define O_RDWR		    02
+#define O_CREAT		  0100	/* not fcntl */
+#define O_EXCL		  0200	/* not fcntl */
+#define O_NOCTTY	  0400	/* not fcntl */
+#define O_TRUNC		 01000	/* not fcntl */
+#define O_APPEND	 02000
+#define O_NONBLOCK	 04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC		010000
+#define FASYNC		020000	/* fcntl, for BSD compatibility */
+#define O_DIRECTORY	040000	/* must be a directory */
+#define O_NOFOLLOW	0100000	/* don't follow links */
+#define O_DIRECT	0200000	/* direct disk access hint - currently ignored */
+#define O_LARGEFILE	0400000
+
+#define F_DUPFD		0	/* dup */
+#define F_GETFD		1	/* get close_on_exec */
+#define F_SETFD		2	/* set/clear close_on_exec */
+#define F_GETFL		3	/* get file->f_flags */
+#define F_SETFL		4	/* set file->f_flags */
+#define F_GETLK		5
+#define F_SETLK		6
+#define F_SETLKW	7
+
+#define F_SETOWN	8	/*  for sockets. */
+#define F_GETOWN	9	/*  for sockets. */
+#define F_SETSIG	10	/*  for sockets. */
+#define F_GETSIG	11	/*  for sockets. */
+
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK		0
+#define F_WRLCK		1
+#define F_UNLCK		2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+/* for leases */
+#define F_INPROGRESS	16
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* or'd with one of the above to prevent
+				   blocking */
+#define LOCK_UN		8	/* remove lock */
+
+#define LOCK_MAND	32	/* This is a mandatory flock */
+#define LOCK_READ	64	/* ... Which allows concurrent read operations */
+#define LOCK_WRITE	128	/* ... Which allows concurrent write operations */
+#define LOCK_RW		192	/* ... Which allows concurrent read & write ops */
+
+struct flock {
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE	1024
+#endif /* _HYPERSTONE_FCNTL_H */
diff -urN linux-2.4.29/include/asm-e1nommu/flat.h linux-2.4.29-uc1/include/asm-e1nommu/flat.h
--- linux-2.4.29/include/asm-e1nommu/flat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/flat.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+ * include/asm-e1nommu/flat.h -- uClinux flat-format executables
+ */
+
+#ifndef __E1NOMMU_FLAT_H__
+#define __E1NOMMU_FLAT_H__
+
+#include <asm/unaligned.h>
+
+#define	flat_stack_align(sp)			/* nothing needed */
+#define	flat_argvp_envp_on_stack()		0 
+#define	flat_old_ram_flag(flags)		(flags)
+#define	flat_reloc_valid(reloc, size)		((reloc) <= (size))
+
+static inline unsigned long	
+flat_get_addr_from_rp(unsigned long *rp, unsigned long relval, unsigned long flags)
+{	
+	unsigned long offset = get_unaligned (rp);
+	(void)flags;
+	if (relval & 0x80000000)
+		offset &= 0x3fFFffFF; // 30 bits
+	else if (relval & 0x40000000)
+		offset &= 0x0fFFffFF; // 28 bits
+
+	return(offset);
+}
+
+static inline void
+flat_put_addr_at_rp(unsigned long *rp, unsigned long addr, unsigned long relval)
+{
+	unsigned long val = get_unaligned (rp);
+	if (relval & 0x80000000)
+		val = (val & 0xc0000000) | addr ;
+	else if (relval & 0x40000000)
+		val = (val & 0xf0000000) | addr ;
+	else
+		val = addr;
+	
+		put_unaligned (val, rp);
+	
+}
+
+static inline unsigned long flat_get_relocate_addr(unsigned long relval)
+{ 
+	return ( relval & 0x3fFFffFF );
+}
+#endif 
diff -urN linux-2.4.29/include/asm-e1nommu/hardirq.h linux-2.4.29-uc1/include/asm-e1nommu/hardirq.h
--- linux-2.4.29/include/asm-e1nommu/hardirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/hardirq.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef _HYPERSTONE_NOMMU_HARDIRQ_H_
+#define _HYPERSTONE_NOMMU_HARDIRQ_H_
+
+#include <linux/threads.h>
+
+typedef struct {
+        unsigned int __softirq_pending;
+        unsigned int __local_irq_count;
+        unsigned int __local_bh_count;
+        unsigned int __syscall_count;
+        struct task_struct * __ksoftirqd_task;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>  /* Standard mappings for irq_cpustat_t above */
+
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt() (local_irq_count(smp_processor_id()) + local_bh_count(smp_processor_id()) != 0)
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
+
+#define irq_enter(cpu, irq)	(local_irq_count(cpu)++)
+#define irq_exit(cpu, irq)	(local_irq_count(cpu)--)
+
+#define hardirq_trylock(cpu)    (local_irq_count(cpu) == 0)
+#define hardirq_endlock(cpu)    do { } while (0)
+
+#define synchronize_irq()	barrier()
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/hw_irq.h linux-2.4.29-uc1/include/asm-e1nommu/hw_irq.h
--- linux-2.4.29/include/asm-e1nommu/hw_irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/hw_irq.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,8 @@
+#ifndef _HYPERSTONE_HW_IRQ_H__
+#define _HYPERSTONE_HW_IRQ_H__
+
+extern inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int i)
+{
+}
+
+#endif /* _HYPERSTONE_HW_IRQ_H__ */
diff -urN linux-2.4.29/include/asm-e1nommu/ioctl.h linux-2.4.29-uc1/include/asm-e1nommu/ioctl.h
--- linux-2.4.29/include/asm-e1nommu/ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/ioctl.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,70 @@
+#ifndef _HYPERSTONE_NOMMU_IOCTL_H
+#define _HYPERSTONE_NOMMU_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	14
+#define _IOC_DIRBITS	2
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE	0U
+#define _IOC_WRITE	1U
+#define _IOC_READ	2U
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* _HYPERSTONE_NOMMU_IOCTL_H */
diff -urN linux-2.4.29/include/asm-e1nommu/ioctls.h linux-2.4.29-uc1/include/asm-e1nommu/ioctls.h
--- linux-2.4.29/include/asm-e1nommu/ioctls.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/ioctls.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,81 @@
+#ifndef __HYPERSTONE_NOMMU_IOCTLS_H
+#define __HYPERSTONE_NOMMU_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+#define TIOCSBRK	0x5427  /* BSD compatibility */
+#define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define FIONCLEX	0x5450  /* these numbers need to be adjusted. */
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+#define FIOQSIZE	0x545E
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+#define TIOCSER_TEMT	0x01	/* Transmitter physically empty */
+
+#endif /* __HYPERSTONE_NOMMU_IOCTLS_H */
diff -urN linux-2.4.29/include/asm-e1nommu/io.h linux-2.4.29-uc1/include/asm-e1nommu/io.h
--- linux-2.4.29/include/asm-e1nommu/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/io.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,242 @@
+#ifndef _HYPERSTONE_NOMMU_IO_H
+#define _HYPERSTONE_NOMMU_IO_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <asm/virtconvert.h>
+
+#define IORegAddress	13
+#define IOWait			11
+#define IOSetupTime		8
+#define IOAccessTime	5
+#define IOHoldTime		3
+
+#ifdef CONFIG_E132XS_BOARD
+#define NR_CS	15
+#define SLOW_IO_ACCESS ( 0x3 << IOSetupTime | 0x0 << IOWait | 7 << IOAccessTime | 3 << IOHoldTime )
+#else
+/* Yannis Fixme !! */
+#define NR_CS	4
+#endif
+
+extern unsigned int io_periph[NR_CS];
+
+/*
+ * swap functions are sometimes needed to interface little-endian hardware
+ */
+static inline unsigned short _swapw(volatile unsigned short v)
+{
+    return ((v << 8) | (v >> 8));
+}
+
+static inline unsigned int _swapl(volatile unsigned long v)
+{
+    return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
+}
+
+#define  hy_inpw(addr)  						\
+	({   register unsigned long dummy, dummy1; 			\
+		 dummy  = addr; 						\
+		 asm volatile  ("LDW.IOD   %1, %0, 0" 	\
+				 		: "=l" (dummy1) 		\
+					   	: "l" (dummy)); dummy1; })
+
+
+#define  hy_outpw(x, addr)						  \
+	({   register unsigned long dummy0,dummy1; \
+	 	 dummy0 = addr; 					  \
+		 dummy1 = x;						  \
+		 asm volatile  ("STW.IOD   %1, %0, 0" \
+						 : "=l" (dummy1) 	  \
+						 : "l"(dummy0), "l" (dummy1)); dummy1; })
+
+#ifndef CONFIG_IO_ACCESS 
+#define readb(addr)	(hy_inpw(addr))
+#define readw(addr)	(hy_inpw(addr))
+#define readl(addr)	(hy_inpw(addr))
+
+#define writeb(b,addr) (void)(hy_outpw(b,addr))
+#define writew(b,addr) (void)(hy_outpw(b,addr))
+#define writel(b,addr) (void)(hy_outpw(b,addr))
+
+#else
+
+#define readb(addr)	({ unsigned char  __v = inregb(addr); __v; })
+#define readw(addr)	({ unsigned short __v = inregw(addr); __v; })
+#define readl(addr)	({ unsigned long  __v = inregl(addr); __v; })
+
+#define writeb(b,addr) (void)(outreg(b, addr))
+#define writew(b,addr) (void)(outreg(b, addr))
+#define writel(b,addr) (void)(outreg(b, addr))
+
+#endif
+
+static inline unsigned long common_io_access(unsigned long addr)
+{
+#ifdef CONFIG_IO_ACCESS
+	return io_periph[(addr & 0x03C00000) >> 22];
+#else 
+	return 	addr;
+#endif
+}
+
+static inline volatile unsigned char inregb(volatile unsigned long reg)
+{
+	unsigned char val;
+
+/* FIXME: ask Christoph for the masking of the "reg" value. In the manual
+ * it appears to be 3 bit, but in the schematic they use 4 bits. So we mask
+ * 4 bits
+ */
+	
+	val = hy_inpw(common_io_access(reg) | ((0xf & reg) << IORegAddress)); 
+	return val;
+}
+
+static inline volatile unsigned short inregw(volatile unsigned long reg)
+{
+	unsigned short val;
+
+	val = hy_inpw(common_io_access(reg) | ((0xf & reg) << IORegAddress)); 
+	return val;
+}
+
+static inline volatile unsigned long inregl(volatile unsigned long reg)
+{
+	unsigned long val;
+
+	val = hy_inpw(common_io_access(reg) | ((0xf & reg) << IORegAddress)); 
+	return val;
+}
+
+
+static inline void outreg(volatile unsigned long val, volatile unsigned long reg)
+{
+		
+	hy_outpw(val, (common_io_access(reg) | ((0xf & reg) << IORegAddress)));
+}
+
+static inline void io_outsb(unsigned int addr, void *buf, int len)
+{
+	unsigned long tmp;
+	unsigned char *bp = (unsigned char *) buf;
+
+	tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
+
+	while (len--){
+		hy_outpw(_swapw(*bp++), tmp);
+	}
+}
+
+static inline void io_outsw(volatile unsigned int addr, void *buf, int len)
+{
+	unsigned long tmp;
+	unsigned short *bp = (unsigned short *) buf;
+	
+	tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
+
+	while (len--){
+		hy_outpw(_swapw(*bp++), tmp);
+	}
+}
+
+static inline void io_outsl(volatile unsigned int addr, void *buf, int len)
+{
+	unsigned long tmp;
+	unsigned int *bp = (unsigned int *) buf;
+		
+	tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
+
+	while (len--){
+		hy_outpw(_swapl(*bp++), tmp);
+	}
+}
+
+static inline void io_insb(volatile unsigned int addr, void *buf, int len)
+{
+	unsigned long tmp;
+	unsigned char *bp = (unsigned char *) buf;
+
+	tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
+
+	while (len--)
+		*bp++ = hy_inpw((unsigned char) tmp);
+	
+}
+
+static inline void io_insw(unsigned int addr, void *buf, int len)
+{
+	unsigned long tmp;
+	unsigned short *bp = (unsigned short *) buf;
+
+	tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
+
+	while (len--)
+		*bp++ = _swapw((unsigned short)hy_inpw(tmp));
+
+}
+
+static inline void io_insl(unsigned int addr, void *buf, int len)
+{
+	unsigned long tmp;
+	unsigned int *bp = (unsigned int *) buf;
+
+	tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
+
+	while (len--)
+		*bp++ = _swapl((unsigned int)hy_inpw(tmp));
+}
+
+/*
+ *	make the short names macros so specific devices
+ *	can override them as required
+ */
+
+#define memset_io(a,b,c)	memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
+
+#define inb(addr)    readb(addr)
+#define inw(addr)    readw(addr)
+#define inl(addr)    readl(addr)
+#define outb(x,addr) ((void) writeb(x,addr))
+#define outw(x,addr) ((void) writew(x,addr))
+#define outl(x,addr) ((void) writel(x,addr))
+
+#define inb_p(addr)    inb(addr)
+#define inw_p(addr)    inw(addr)
+#define inl_p(addr)    inl(addr)
+#define outb_p(x,addr) outb(x,addr)
+#define outw_p(x,addr) outw(x,addr)
+#define outl_p(x,addr) outl(x,addr)
+
+#define outsb(a,b,l) io_outsb(a,b,l)
+#define outsw(a,b,l) io_outsw(a,b,l)
+#define outsl(a,b,l) io_outsl(a,b,l)
+
+#define insb(a,b,l) io_insb(a,b,l)
+#define insw(a,b,l) io_insw(a,b,l)
+#define insl(a,b,l) io_insl(a,b,l)
+
+
+#define __io_virt(x)            ((unsigned long)x)
+#define __io_phys(x)            ((unsigned long)x)
+
+/* FIXME */
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define MAX_NR_EXTERNAL_DEVICES		8
+
+//#define iounmap(addr)				((void)0)
+#define ioremap(physaddr, size)			(physaddr)
+#define ioremap_nocache(physaddr, size)		(physaddr)
+#define ioremap_writethrough(physaddr, size)	(physaddr)
+#define ioremap_fullcache(physaddr, size)	(physaddr)
+
+
+#define page_to_phys(page)    ((page - mem_map) << PAGE_SHIFT)
+
+#endif /* __KERNEL__ */
+
+#endif /* _HYPERSTONE_NOMMU_IO_H */
diff -urN linux-2.4.29/include/asm-e1nommu/ipcbuf.h linux-2.4.29-uc1/include/asm-e1nommu/ipcbuf.h
--- linux-2.4.29/include/asm-e1nommu/ipcbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/ipcbuf.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,29 @@
+#ifndef _HYPERSTONE_IPCBUF_H__
+#define _HYPERSTONE_IPCBUF_H__
+
+/*
+ * The user_ipc_perm structure.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
+	__kernel_mode_t		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* !_HYPERSTONE_IPCBUF_H__ */
diff -urN linux-2.4.29/include/asm-e1nommu/ipc.h linux-2.4.29-uc1/include/asm-e1nommu/ipc.h
--- linux-2.4.29/include/asm-e1nommu/ipc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/ipc.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,26 @@
+#ifndef __HYPERSTONE_IPC_H__
+#define __HYPERSTONE_IPC_H__
+
+struct ipc_kludge {
+	struct msgbuf *msgp;
+	long msgtyp;
+};
+
+#define SEMOP		 1
+#define SEMGET		 2
+#define SEMCTL		 3
+#define MSGSND		11
+#define MSGRCV		12
+#define MSGGET		13
+#define MSGCTL		14
+#define SHMAT		21
+#define SHMDT		22
+#define SHMGET		23
+#define SHMCTL		24
+
+/* Used by the DIPC package, try and avoid reusing it */
+#define DIPC		25
+
+#define IPCCALL(version,op)	((version)<<16 | (op))
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/irq.h linux-2.4.29-uc1/include/asm-e1nommu/irq.h
--- linux-2.4.29/include/asm-e1nommu/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/irq.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,24 @@
+#ifndef _HYPERSTONE_IRQ_H_
+#define _HYPERSTONE_IRQ_H_
+
+#include <asm/ptrace.h>
+
+#define NR_IRQS  8
+
+#define IRQ_EXT1	0
+#define IRQ_EXT2	1	
+#define IRQ_EXT3	2		
+#define IRQ_EXT		3
+#define IRQ_TIMER	7	
+
+#ifndef __ASSEMBLY__
+
+extern void disable_irq(unsigned int);
+extern void disable_irq_nosync(unsigned int);
+extern void enable_irq(unsigned int);
+
+extern void do_IRQ(struct pt_regs regs, unsigned int irq);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _HYPERSTONE_IRQ_H_ */
diff -urN linux-2.4.29/include/asm-e1nommu/machdep.h linux-2.4.29-uc1/include/asm-e1nommu/machdep.h
--- linux-2.4.29/include/asm-e1nommu/machdep.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/machdep.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,61 @@
+#ifndef _HYPERSTONE_NOMMU_MACHDEP_H
+#define _HYPERSTONE_NOMMU_MACHDEP_H
+
+
+struct pt_regs;
+struct kbd_repeat;
+struct mktime;
+struct hwclk_time;
+struct gendisk;
+struct buffer_head;
+
+
+extern void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *));
+/* machine dependent keyboard functions 
+ * Not needed for us: Yannis
+ */
+/*
+extern int (*mach_keyb_init) (void);
+extern int (*mach_kbdrate) (struct kbd_repeat *);
+extern void (*mach_kbd_leds) (unsigned int);
+*/
+
+/* machine dependent irq functions */
+extern void (*mach_init_IRQ) (void);
+extern void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *);
+extern int (*mach_request_irq) (unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                                unsigned long flags, const char *devname, void *dev_id);
+extern void (*mach_free_irq) (unsigned int irq, void *dev_id);
+extern void (*mach_get_model) (char *model);
+extern int (*mach_get_hardware_list) (char *buffer);
+extern int (*mach_get_irq_list) (char *buf);
+extern void (*mach_process_int) (int irq, struct pt_regs *fp);
+/* machine dependent timer functions */
+extern unsigned long (*mach_gettimeoffset)(void);
+extern void (*mach_gettod)(int *year, int *mon, int *day, int *hour,
+			   int *min, int *sec);
+extern int (*mach_hwclk)(int, struct hwclk_time*);
+extern int (*mach_set_clock_mmss)(unsigned long);
+extern void (*mach_reset)( void );
+extern void (*mach_halt)( void );
+extern void (*mach_power_off)( void );
+extern unsigned long (*mach_hd_init) (unsigned long, unsigned long);
+extern void (*mach_hd_setup)(char *, int *);
+extern long mach_max_dma_address;
+extern void (*mach_floppy_setup)(char *, int *);
+extern void (*mach_floppy_eject)(void);
+extern void (*mach_heartbeat) (int);
+extern void (*mach_l2_flush) (int);
+extern int mach_sysrq_key;
+extern int mach_sysrq_shift_state;
+extern int mach_sysrq_shift_mask;
+extern char *mach_sysrq_xlate;
+
+#ifdef CONFIG_UCLINUX
+extern void config_BSP(char *command, int len);
+extern void BSP_init_periphs(void);
+extern void (*mach_tick)(void);
+extern void (*mach_trap_init)(void);
+#endif
+
+#endif /* _HYPERSTONE_NOMMU_MACHDEP_H */
diff -urN linux-2.4.29/include/asm-e1nommu/mman.h linux-2.4.29-uc1/include/asm-e1nommu/mman.h
--- linux-2.4.29/include/asm-e1nommu/mman.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/mman.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,38 @@
+#ifndef _HYPERSTONE_MMAN_H_
+#define _HYPERSTONE_MMAN_H_
+
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_NONE	0x0		/* page can not be accessed */
+
+#define MAP_SHARED	0x01		/* Share changes */
+#define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_TYPE	0x0f		/* Mask for type of mapping */
+#define MAP_FIXED	0x10		/* Interpret addr exactly */
+#define MAP_ANONYMOUS	0x20		/* don't use a file */
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
+#define MAP_LOCKED	0x2000		/* pages are locked */
+#define MAP_NORESERVE	0x4000		/* don't check for reservations */
+
+#define MS_ASYNC	1		/* sync memory asynchronously */
+#define MS_INVALIDATE	2		/* invalidate the caches */
+#define MS_SYNC		4		/* synchronous memory sync */
+
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
+
+#define MADV_NORMAL	0x0		/* default page-in behavior */
+#define MADV_RANDOM	0x1		/* page-in minimum required */
+#define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
+#define MADV_WILLNEED	0x3		/* pre-fault pages */
+#define MADV_DONTNEED	0x4		/* discard these pages */
+
+/* compatibility flags */
+#define MAP_ANON	MAP_ANONYMOUS
+#define MAP_FILE	0
+
+#endif /* _HYPERSTONE_MMAN_H_ */
diff -urN linux-2.4.29/include/asm-e1nommu/mmu_context.h linux-2.4.29-uc1/include/asm-e1nommu/mmu_context.h
--- linux-2.4.29/include/asm-e1nommu/mmu_context.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/mmu_context.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,10 @@
+#ifndef _HYPERSTONE_MMU_CONTEXT_H_
+#define _HYPERSTONE_MMU_CONTEXT_H_
+
+#define destroy_context(mm)             do { } while(0)
+#define init_new_context(tsk,mm)        0
+#define switch_mm(prev,next,tsk,cpu)    do { } while(0)
+#define activate_mm(prev,next)		do { } while(0)
+#define enter_lazy_tlb(mm,tsk,cpu)	do { } while(0)
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/mmu.h linux-2.4.29-uc1/include/asm-e1nommu/mmu.h
--- linux-2.4.29/include/asm-e1nommu/mmu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/mmu.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,4 @@
+#ifndef _HYPERSTONE_MMU_H__
+#define _HYPERSTONE_MMU_H__
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/module.h linux-2.4.29-uc1/include/asm-e1nommu/module.h
--- linux-2.4.29/include/asm-e1nommu/module.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/module.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,4 @@
+#ifndef _HYPERSTONE_MODULE_H_
+#define _HYPERSTONE_MODULE_H_
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/msgbuf.h linux-2.4.29-uc1/include/asm-e1nommu/msgbuf.h
--- linux-2.4.29/include/asm-e1nommu/msgbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/msgbuf.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef _HYPERSTONE_MSGBUF_H
+#define _HYPERSTONE_MSGBUF_H
+
+/* 
+ * The msqid64_ds structure.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm msg_perm;
+	__kernel_time_t msg_stime;	/* last msgsnd time */
+	unsigned long	__unused1;
+	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	unsigned long	__unused2;
+	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned long	__unused3;
+	unsigned long  msg_cbytes;	/* current number of bytes on queue */
+	unsigned long  msg_qnum;	/* number of messages in queue */
+	unsigned long  msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t msg_lrpid;	/* last receive pid */
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+#endif /* _HYPERSTONE_MSGBUF_H */
diff -urN linux-2.4.29/include/asm-e1nommu/namei.h linux-2.4.29-uc1/include/asm-e1nommu/namei.h
--- linux-2.4.29/include/asm-e1nommu/namei.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/namei.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,11 @@
+#ifndef _HYPERSTONE_NAMEI_H
+#define _HYPERSTONE_NAMEI_H
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+
+#define __emul_prefix() NULL
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/page.h linux-2.4.29-uc1/include/asm-e1nommu/page.h
--- linux-2.4.29/include/asm-e1nommu/page.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/page.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,102 @@
+#ifndef _HYPERSTONE_PAGE_H_
+#define _HYPERSTONE_PAGE_H_
+
+#include <linux/config.h>
+
+/* PAGE_SHIFT determines the page size */
+
+#define PAGE_SHIFT      (12)
+#define PAGE_SIZE       (4096)
+#define PAGE_MASK       (~(PAGE_SIZE-1))
+
+#ifdef __KERNEL__
+
+#include <asm/setup.h>
+
+#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1) & PAGE_MASK)
+
+#define PAGE_OFFSET     0x00000000
+
+#define get_user_page(vaddr)            __get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr)      free_page(addr)
+
+#define clear_page(page)        memset((page), 0, PAGE_SIZE)
+#define copy_page(to,from)      memcpy((to), (from), PAGE_SIZE)
+
+#define clear_user_page(page, vaddr)    clear_page(page)
+#define copy_user_page(to, from, vaddr) copy_page(to, from)
+
+#ifdef STRICT_MM_TYPECHECKS
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pmd[16]; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)      ((x).pte)
+#define pmd_val(x)      ((&x)->pmd[0])
+#define pgd_val(x)      ((x).pgd)
+#define pgprot_val(x)   ((x).pgprot)
+
+#define __pte(x)        ((pte_t) { (x) } )
+#define __pmd(x)        ((pmd_t) { (x) } )
+#define __pgd(x)        ((pgd_t) { (x) } )
+#define __pgprot(x)     ((pgprot_t) { (x) } )
+
+#else
+/*
+ * .. while these make it easier on the compiler
+ */
+typedef unsigned long pte_t;
+typedef struct { unsigned long pmd[16]; } pmd_t;
+typedef unsigned long pgd_t;
+typedef unsigned long pgprot_t;
+
+#define pte_val(x)      (x)
+#define pmd_val(x)      ((&x)->pmd[0])
+#define pgd_val(x)      (x)
+#define pgprot_val(x)   (x)
+
+#define __pte(x)        (x)
+#define __pmd(x)        ((pmd_t) { (x) } )
+#define __pgd(x)        (x)
+#define __pgprot(x)     (x)
+
+#endif
+
+#define __pa(vaddr)             virt_to_phys((void *)vaddr)
+#define __va(paddr)             phys_to_virt((unsigned long)paddr)
+#define MAP_NR(addr)            (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
+#define virt_to_page(addr)      (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
+#define VALID_PAGE(page)        ((page - mem_map) < max_mapnr)
+
+#define BUG() do { \
+        printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+		while(1); \
+        __asm__ __volatile__(".word 0x0000"); \
+} while (0)                                       
+
+#define PAGE_BUG(page) do { \
+        BUG(); \
+} while (0)
+
+#endif /* __KERNEL__ */
+
+/* Pure 2^n version of get_order */
+extern __inline__ int get_order(unsigned long size)
+{
+    int order;
+
+    size = (size-1) >> (PAGE_SHIFT-1);
+    order = -1;
+    do {
+        size >>= 1;
+        order++;
+    } while (size);
+    return order;
+}
+
+
+#endif /* !_HYPERSTONE_PAGE_H_ */
diff -urN linux-2.4.29/include/asm-e1nommu/param.h linux-2.4.29-uc1/include/asm-e1nommu/param.h
--- linux-2.4.29/include/asm-e1nommu/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/param.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,24 @@
+#ifndef _HYPERSTONE_PARAM_H
+#define _HYPERSTONE_PARAM_H
+
+#include <asm/user.h>
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#if defined(__KERNEL__) && (HZ == 100)
+#define hz_to_std(a) (a)
+#endif
+
+#ifndef NGROUPS
+#define NGROUPS		32 
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/pgalloc.h linux-2.4.29-uc1/include/asm-e1nommu/pgalloc.h
--- linux-2.4.29/include/asm-e1nommu/pgalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/pgalloc.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,107 @@
+#ifndef _HYPERSTONE_PGALLOC_H
+#define _HYPERSTONE_PGALLOC_H
+
+#include <asm/setup.h>
+#include <asm/virtconvert.h>
+
+/*
+ * Cache handling functions
+ */
+
+#if DAVIDM
+/*
+ * invalidate the cache for the specified memory range.
+ * It starts at the physical address specified for
+ * the given number of bytes.
+ */
+extern void cache_clear(unsigned long paddr, int len);
+
+/*
+ * push any dirty cache in the specified memory range.
+ * It starts at the physical address specified for
+ * the given number of bytes.
+ */
+extern void cache_push(unsigned long paddr, int len);
+
+/*
+ * push and invalidate pages in the specified user virtual
+ * memory range.
+ */
+extern void cache_push_v(unsigned long vaddr, int len);
+
+/* cache code */
+#define FLUSH_I_AND_D	(0x00000808)
+#define FLUSH_I 	(0x00000008)
+
+/* This is needed whenever the virtual mapping of the current
+   process changes.  */
+#endif  /* !DAVIDM */
+
+#define __flush_cache_all()  do{ } while(0)/* FIXME Invalidate Caches!  */	
+
+#define flush_cache_all()			__flush_cache_all()
+#define flush_cache_mm(mm)			__flush_cache_all()
+#define flush_cache_range(mm, start, end)	__flush_cache_all()
+#define flush_cache_page(vma, vmaddr)		__flush_cache_all()
+#define flush_page_to_ram(page)			__flush_cache_all()
+#define flush_dcache_page(page)			__flush_cache_all()
+#define flush_icache_range(start, end)		__flush_cache_all()
+#define flush_icache_page(vma,pg)		__flush_cache_all()
+#define flush_icache()				__flush_cache_all()
+#define flush_icache_user_range(vma,pg,adr,len) __flush_cache_all()
+
+/*
+ * DAVIDM - the rest of these are just so I can check where they happen
+ */
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+	BUG();
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+	BUG();
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+	BUG();
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+	BUG();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+	BUG();
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+				   unsigned long start, unsigned long end)
+{
+	BUG();
+}
+
+extern inline void flush_tlb_kernel_page(unsigned long addr)
+{
+	BUG();
+}
+
+extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+				      unsigned long start, unsigned long end)
+{
+	BUG();
+}
+
+#endif /* _HYPERSTONE_PGALLOC_H */
diff -urN linux-2.4.29/include/asm-e1nommu/pgtable.h linux-2.4.29-uc1/include/asm-e1nommu/pgtable.h
--- linux-2.4.29/include/asm-e1nommu/pgtable.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/pgtable.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,23 @@
+#ifndef _HYPERSTONE_PGTABLE_H
+#define _HYPERSTONE_PGTABLE_H
+
+#include <linux/config.h>
+#include <asm/setup.h>
+
+#define pgd_present(pgd)     (1)       /* pages are always present on NO_MM */
+#define kern_addr_valid(addr) (1)
+
+#define PAGE_NONE		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_SHARED		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_COPY		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_READONLY		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_KERNEL		__pgprot(0)    /* these mean nothing to NO_MM */
+
+extern void paging_init(void);
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()   do { } while (0)
+
+#endif /* _HYPERSTONE_PGTABLE_H */
diff -urN linux-2.4.29/include/asm-e1nommu/poll.h linux-2.4.29-uc1/include/asm-e1nommu/poll.h
--- linux-2.4.29/include/asm-e1nommu/poll.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/poll.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef _HYPERSTONE_POLL_H
+#define _HYPERSTONE_POLL_H
+
+/* These are specified by iBCS2 */
+#define POLLIN		0x0001
+#define POLLPRI		0x0002
+#define POLLOUT		0x0004
+#define POLLERR		0x0008
+#define POLLHUP		0x0010
+#define POLLNVAL	0x0020
+
+/* The rest seem to be more-or-less nonstandard. Check them! */
+#define POLLRDNORM	0x0040
+#define POLLRDBAND	0x0080
+#define POLLWRNORM	0x0100
+#define POLLWRBAND	0x0200
+#define POLLMSG		0x0400
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+#endif /* ! _HYPERSTONE_POLL_H_ */
diff -urN linux-2.4.29/include/asm-e1nommu/posix_types.h linux-2.4.29-uc1/include/asm-e1nommu/posix_types.h
--- linux-2.4.29/include/asm-e1nommu/posix_types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/posix_types.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,64 @@
+#ifndef _HYPERSTONE_POSIX_TYPES_H
+#define _HYPERSTONE_POSIX_TYPES_H
+
+/* Originally derived from include/asm-m68k/posix_types.h
+ * 
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+#if defined(__KERNEL__) && !defined(_LIBC)
+
+typedef unsigned short	__kernel_dev_t;
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned short	__kernel_mode_t;
+typedef unsigned short	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
+typedef unsigned short	__kernel_uid_t;
+typedef unsigned short	__kernel_gid_t;
+typedef unsigned int	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+typedef unsigned short	__kernel_old_uid_t;
+typedef unsigned short	__kernel_old_gid_t;
+
+#ifdef __GNUC__
+typedef long long __kernel_loff_t;
+#endif
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+	int	val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+	int	__val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+
+#undef	__FD_SET
+#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+
+#undef	__FD_CLR
+#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+
+#undef	__FD_ISSET
+#define	__FD_ISSET(d, set)	((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
+
+#undef	__FD_ZERO
+#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/processor.h linux-2.4.29-uc1/include/asm-e1nommu/processor.h
--- linux-2.4.29/include/asm-e1nommu/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/processor.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,350 @@
+#ifndef _HYPERSTONE_PROCESSOR_H_
+#define _HYPERSTONE_PROCESSOR_H_
+
+#include <linux/types.h>
+#include <asm/ptrace.h>
+#include <asm/bitops.h>
+
+typedef struct
+{
+    unsigned char DownLoadMode;         // offset 0
+    unsigned char BoardType;            //        1
+    unsigned char BoardRevisionNumber;  //        2
+    unsigned char SysDriverPriority;    //        3
+    unsigned int  TPRValue;				//        4
+    unsigned int  BCRValue;             //        8
+    unsigned int  MCRValue;             //       12
+    unsigned int  FCRValue;             //       16
+    unsigned int  SDCRValue;            //       20
+    unsigned int  SDMRValue;            //       24
+    unsigned char CPUType;              //       28
+/*    unsigned char MEMAllocation;        //       29 */
+} shadow_regs_t;
+
+#define TPR_reg		1
+#define BCR_reg		2
+#define MCR_reg		3
+#define FCR_reg		4
+#define SDCR_reg	5
+#define SDMR_reg	6
+
+/*
+ * Default implementation that returns current
+ * value of program counter
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#define EXPAND_STACK 		1
+#define DONT_EXPAND_STACK 	0
+
+/* struct indicates if an exception happened
+ * in kernel mode, but we were using either the
+ * user register stack or the kernel register stack.
+ * In that case we have to switch stack before calling
+ * the appropriate exception handler.
+ *
+ * We should maintain this information in order to
+ * gracefully return from exception to the exact point
+ * the exception happened in kernel mode.
+ */
+struct stack_use {
+	unsigned long excp_in_km_while_using_user_reg_stack;
+	unsigned long excp_in_km_while_using_user_aggr_stack;
+};
+
+struct return_from_vfork {
+	unsigned long ret_from_vfork;
+	unsigned long ReturnPC;
+	unsigned long ReturnSR;
+};
+
+struct thread_struct {
+	unsigned long SR;
+	unsigned long G2;
+	unsigned long G3;
+	unsigned long G4;
+	unsigned long G5;
+	unsigned long G6;
+	unsigned long G7;
+	unsigned long G8;
+	unsigned long G9;
+	//unsigned long G10; G10 is used by GDB
+	unsigned long G11;
+	unsigned long G12;
+	unsigned long G13;
+	unsigned long G14;
+	unsigned long G15;
+	unsigned long SP;
+	unsigned long UB;
+	struct stack_use stack_use;
+	struct return_from_vfork vfork_ret_info;
+ };
+
+#define INIT_THREAD { \
+0,0,0,0, \
+0,0,0,0, \
+0,0,0,0, \
+0,0,0,0, \
+0,\
+/*stack_use*/0,0,\
+/*vfork_ret_info*/0,0,0\
+}
+
+/* Allocation and freeing of basic task resources. */
+#define alloc_task_struct() \
+        ((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
+#define free_task_struct(p)     free_pages((unsigned long)(p),1)
+#define get_task_struct(tsk)    atomic_inc(&mem_map[MAP_NR(tsk)].count)
+
+#define init_task       (init_task_union.task)
+#define init_stack      (init_task_union.stack)
+
+#define THREAD_SIZE (2*PAGE_SIZE)
+
+/*
+ * User space process size: 3.75GB. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.
+ */
+/* FIXME */
+#define TASK_SIZE       (0xFFFFFFFFUL)
+
+extern long arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+#define copy_segments(tsk, mm)          do { } while (0)
+#define release_segments(mm)            do { } while (0)
+#define forget_segments()               do { } while (0)
+
+/* Forward declaration, a strange C thing - Don't remove it!*/
+struct task_struct;
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task) { }
+
+extern shadow_regs_t *system_sh_regs; 
+
+#ifdef CONFIG_RAMKERNEL 
+static inline void update_sh_reg_bit(unsigned char reg, unsigned short position, unsigned char value)
+{
+volatile long *base_addr;
+
+	asm volatile("mov %0, G10"
+				:"=l" (base_addr)
+				:);
+
+		switch (reg){
+				case FCR_reg:
+					if(value) set_bit(position, &(system_sh_regs->FCRValue)); 
+					else clear_bit (position, &(system_sh_regs->FCRValue));
+					*(base_addr+FCR_reg) = system_sh_regs->FCRValue;
+					asm volatile ("
+									fetch 2
+									ori SR, 0x20
+									mov FCR, %0"
+									:
+									:"l" (system_sh_regs->FCRValue));
+					break;
+				case TPR_reg:
+					if(value) set_bit(position, &(system_sh_regs->TPRValue)); 
+					else clear_bit (position, &(system_sh_regs->TPRValue));
+					*(base_addr+TPR_reg) = system_sh_regs->TPRValue;
+					asm volatile ("
+									fetch 2
+									ori SR, 0x20
+									mov TPR, %0"
+									:
+									:"l" (system_sh_regs->TPRValue));
+					break;
+				case BCR_reg:
+					if(value) set_bit(position, &(system_sh_regs->BCRValue)); 
+					else clear_bit (position, &(system_sh_regs->BCRValue));
+					*(base_addr+BCR_reg) = system_sh_regs->BCRValue;
+					asm volatile ("
+									fetch 2
+									ori SR, 0x20
+									mov BCR, %0"
+									:
+									:"l" (system_sh_regs->BCRValue));
+					break;
+				case MCR_reg:
+					if(value) set_bit(position, &(system_sh_regs->MCRValue)); 
+					else clear_bit (position, &(system_sh_regs->MCRValue));
+					*(base_addr+MCR_reg) = system_sh_regs->MCRValue;
+					asm volatile ("
+									fetch 2
+									ori SR, 0x20
+									mov MCR, %0"
+									:
+									:"l" (system_sh_regs->MCRValue));
+					break;
+				default:
+					asm volatile ("trap 16"::); /* FIXME */
+				}
+}
+
+static inline void update_sh_reg(unsigned char reg, unsigned long value)
+{
+volatile long *base_addr;
+
+	asm volatile("mov %0, G10"
+				:"=l" (base_addr)
+				:);
+
+		switch (reg){
+				case FCR_reg:
+					system_sh_regs->FCRValue = value; 
+					*(base_addr+FCR_reg) = system_sh_regs->FCRValue;
+					asm volatile ("
+									fetch 2
+									ori SR, 0x20
+									mov FCR, %0"
+									:
+									:"l" (system_sh_regs->FCRValue));
+					break;
+				case TPR_reg:
+					system_sh_regs->TPRValue = value; 
+					*(base_addr+TPR_reg) = system_sh_regs->TPRValue;
+					asm volatile ("
+									fetch 2
+									ori SR, 0x20
+									mov TPR, %0"
+									:
+									:"l" (system_sh_regs->TPRValue));
+					break;
+				case BCR_reg:
+					system_sh_regs->BCRValue = value; 
+					*(base_addr+BCR_reg) = system_sh_regs->BCRValue;
+					asm volatile ("
+									fetch 2
+									ori SR, 0x20
+									mov BCR, %0"
+									:
+									:"l" (system_sh_regs->BCRValue));
+					break;
+				case MCR_reg:
+					system_sh_regs->MCRValue = value; 
+					*(base_addr+MCR_reg) = system_sh_regs->MCRValue;
+					asm volatile ("
+									fetch 2
+									ori SR, 0x20
+									mov MCR, %0"
+									:
+									:"l" (system_sh_regs->MCRValue));
+					break;
+				default:
+					asm volatile ("trap 16"::); /* FIXME */	
+
+		}
+}
+
+#ifdef __KERNEL__
+extern void __udelay(unsigned long usecs);
+static inline void toggle_red_led(unsigned int usec)
+{
+		unsigned long tmp; 
+
+		if (test_bit(2, &(system_sh_regs->FCRValue))){ 
+				update_sh_reg_bit(FCR_reg, 2, 0); 
+		}
+				tmp=system_sh_regs->FCRValue;
+		if(!usec){
+				test_and_change_bit(1, &tmp);
+				update_sh_reg(FCR_reg, tmp); 
+		}
+		else{
+			while(1){
+				__udelay(usec);
+				test_and_change_bit(1, &tmp);
+				asm volatile ("
+								fetch 2
+								ori SR, 0x20
+								mov FCR, %0"
+								:
+								:"l" (tmp));
+			};
+		}
+
+}
+
+static inline void toggle_green_led(unsigned int usec)
+{
+		unsigned long tmp;;
+
+		if (test_bit(6, &(system_sh_regs->FCRValue))){ 
+				update_sh_reg_bit(FCR_reg, 6, 0); 
+		}
+				tmp=system_sh_regs->FCRValue;
+		if(!usec){
+				test_and_change_bit(5, &tmp);
+				update_sh_reg(FCR_reg, tmp); 
+		}
+		else{
+			while(1){
+				__udelay(usec);
+				test_and_change_bit(5, &tmp);
+				asm volatile ("
+								fetch 2
+								ori SR, 0x20
+								mov FCR, %0"
+								:
+								:"l" (tmp));
+			};
+		}
+
+}
+
+static inline void toggle_red_and_green_led(unsigned int usec)
+{
+		unsigned long tmp;;
+
+		if (test_bit(2, &(system_sh_regs->FCRValue))){ 
+				update_sh_reg_bit(FCR_reg, 2, 0); 
+		}
+		if (test_bit(6, &(system_sh_regs->FCRValue))){ 
+				update_sh_reg_bit(FCR_reg, 6, 0); 
+		}
+
+		tmp=system_sh_regs->FCRValue;
+		if(!usec){
+				test_and_change_bit(1, &tmp);
+				test_and_change_bit(5, &tmp);
+				update_sh_reg(FCR_reg, tmp); 
+		}
+		else{
+			while(1){
+				__udelay(usec);
+				test_and_change_bit(1, &tmp);
+				test_and_change_bit(5, &tmp);
+				asm volatile ("
+								fetch 2
+								ori SR, 0x20
+								mov FCR, %0"
+								:
+								:"l" (tmp));
+			};
+		}
+
+}
+#endif /* __KERNEL__ */
+#else
+#error "The write-only registers are not initialized"
+
+
+#endif /* RAMKERNEL */
+
+extern unsigned long get_wchan(struct task_struct *p);
+
+#define KSTK_EIP(tsk)  (1)
+#define KSTK_ESP(tsk)  (1)
+
+
+#define init_task       (init_task_union.task)
+#define init_stack      (init_task_union.stack)
+ 
+#define cpu_relax()     do { } while (0)
+
+unsigned long get_wchan(struct task_struct *p);
+#define KSTK_EIP(tsk) (1)
+#define KSTK_ESP(tsk) (1)
+
+
+#endif /* _HYPERSTONE_PROCESSOR_H_ */
diff -urN linux-2.4.29/include/asm-e1nommu/ptrace.h linux-2.4.29-uc1/include/asm-e1nommu/ptrace.h
--- linux-2.4.29/include/asm-e1nommu/ptrace.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/ptrace.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,18 @@
+#ifndef _HYPERSTONE_PTRACE_H_
+#define _HYPERSTONE_PTRACE_H_
+
+struct pt_regs{
+	unsigned long *L;
+	unsigned long  FL;
+};
+
+/* If interrupted task was in User Mode return 1,
+ * else if it was in System Mode return 0 */
+/*#define user_mode(regs)		(( (regs)->L [(regs)->FL] & 0x1) == 0)*/
+
+static inline int user_mode(struct pt_regs *regs )
+{
+		return(( (regs)->L [(regs)->FL] & 0x1) == 0);
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/resource.h linux-2.4.29-uc1/include/asm-e1nommu/resource.h
--- linux-2.4.29/include/asm-e1nommu/resource.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/resource.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,46 @@
+#ifndef _HYPERSTONE_NOMMU_RESOURCE_H
+#define _HYPERSTONE_NOMMU_RESOURCE_H
+
+ /* Resource limits
+ */
+
+#define RLIMIT_CPU	0		/* CPU time in ms */
+#define RLIMIT_FSIZE	1		/* Maximum filesize */
+#define RLIMIT_DATA	2		/* max data size */
+#define RLIMIT_STACK	3		/* max stack size */
+#define RLIMIT_CORE	4		/* max core file size */
+#define RLIMIT_RSS	5		/* max resident set size */
+#define RLIMIT_NPROC	6		/* max number of processes */
+#define RLIMIT_NOFILE	7		/* max number of open files */
+#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
+#define RLIMIT_AS	9		/* address space limit */
+#define RLIMIT_LOCKS	10		/* maximum file locks held */
+
+#define RLIM_NLIMITS	11
+
+#ifdef __KERNEL__
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway.
+ */
+#define RLIM_INFINITY	(~0UL)
+
+#define INIT_RLIMITS				\
+{						\
+	{ RLIM_INFINITY, RLIM_INFINITY },	\
+	{ RLIM_INFINITY, RLIM_INFINITY },	\
+	{ RLIM_INFINITY, RLIM_INFINITY },	\
+	{ _STK_LIM,      RLIM_INFINITY },	\
+	{ 0,             RLIM_INFINITY },	\
+	{ RLIM_INFINITY, RLIM_INFINITY },	\
+	{ 0,             0             },	\
+	{ INR_OPEN,      INR_OPEN      },	\
+	{ RLIM_INFINITY, RLIM_INFINITY },	\
+	{ RLIM_INFINITY, RLIM_INFINITY },	\
+	{ RLIM_INFINITY, RLIM_INFINITY },	\
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _HYPERSTONE_NOMMU_RESOURCE_H */
diff -urN linux-2.4.29/include/asm-e1nommu/segment.h linux-2.4.29-uc1/include/asm-e1nommu/segment.h
--- linux-2.4.29/include/asm-e1nommu/segment.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/segment.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,52 @@
+#ifndef _HYPERSTONE_SEGMENT_H
+#define _HYPERSTONE_SEGMENT_H
+
+
+/* define constants */
+/* Address spaces (FC0-FC2) */
+#define USER_DATA     (1)
+#ifndef __USER_DS
+#define __USER_DS     (USER_DATA)
+#endif
+#define USER_PROGRAM  (2)
+#define SUPER_DATA    (5)
+#ifndef __KERNEL_DS
+#define __KERNEL_DS   (SUPER_DATA)
+#endif
+#define SUPER_PROGRAM (6)
+#define CPU_SPACE     (7)
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
+#define USER_DS		MAKE_MM_SEG(__USER_DS)
+#define KERNEL_DS	MAKE_MM_SEG(__KERNEL_DS)
+
+/*
+ * Get/set the SFC/DFC registers for MOVES instructions
+ */
+
+static inline mm_segment_t get_fs(void)
+{
+    return USER_DS;
+}
+
+static inline mm_segment_t get_ds(void)
+{
+    /* return the supervisor data space code */
+    return KERNEL_DS;
+}
+
+static inline void set_fs(mm_segment_t val)
+{
+}
+
+#define segment_eq(a,b)	((a).seg == (b).seg)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _HYPERSTONE_SEGMENT_H */
diff -urN linux-2.4.29/include/asm-e1nommu/semaphore.h linux-2.4.29-uc1/include/asm-e1nommu/semaphore.h
--- linux-2.4.29/include/asm-e1nommu/semaphore.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/semaphore.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,85 @@
+#ifndef _HYPERSTONE_SEMAPHORE_H
+#define _HYPERSTONE_SEMAPHORE_H
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <linux/wait.h>
+#include <linux/rwsem.h>
+
+struct semaphore {
+	atomic_t count;
+	int sleepers;
+	wait_queue_head_t wait;
+};
+
+#define __SEM_DEBUG_INIT(name)
+
+#define __SEMAPHORE_INITIALIZER(name,count) \
+{ ATOMIC_INIT(count), 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+	__SEM_DEBUG_INIT(name) }
+
+#define __MUTEX_INITIALIZER(name) \
+	__SEMAPHORE_INITIALIZER(name,1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+
+#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
+#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
+
+static inline void sema_init (struct semaphore *sem, int val)
+{
+	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
+}
+
+static inline void init_MUTEX (struct semaphore *sem)
+{
+	sema_init(sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+{
+	sema_init(sem, 0);
+}
+
+asmlinkage void __down_failed(void /* special register calling convention */);
+asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
+asmlinkage int  __down_failed_trylock(void  /* params in registers */);
+asmlinkage void __up_wakeup(void /* special register calling convention */);
+
+asmlinkage void __down(struct semaphore * sem);
+asmlinkage int  __down_interruptible(struct semaphore * sem);
+asmlinkage int  __down_trylock(struct semaphore * sem);
+asmlinkage void __up(struct semaphore * sem);
+
+static inline void down(struct semaphore * sem)
+{
+	if (atomic_dec_return(&sem->count) < 0)
+		__down(sem);
+}
+
+static inline int down_interruptible(struct semaphore * sem)
+{
+	int ret = 0;
+
+	if (atomic_dec_return(&sem->count) < 0)
+		ret = __down_interruptible(sem);
+	return ret;
+}
+
+static inline int down_trylock(struct semaphore * sem)
+{
+	int ret = 0;
+
+	if (atomic_dec_return(&sem->count) < 0)
+		ret = __down_trylock(sem);
+	return ret;
+}
+
+static inline void up(struct semaphore * sem)
+{
+	if (atomic_inc_return(&sem->count) <= 0)
+		__up(sem);
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/sembuf.h linux-2.4.29-uc1/include/asm-e1nommu/sembuf.h
--- linux-2.4.29/include/asm-e1nommu/sembuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/sembuf.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef _HYPERSTONE_NOMMU_SEMBUF_H
+#define _HYPERSTONE_NOMMU_SEMBUF_H
+
+/* 
+ * The semid64_ds structure for hyperstone architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
+	__kernel_time_t	sem_otime;		/* last semop time */
+	unsigned long	__unused1;
+	__kernel_time_t	sem_ctime;		/* last change time */
+	unsigned long	__unused2;
+	unsigned long	sem_nsems;		/* no. of semaphores in array */
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _HYPERSTONE_NOMMU_SEMBUF_H */
diff -urN linux-2.4.29/include/asm-e1nommu/serial.h linux-2.4.29-uc1/include/asm-e1nommu/serial.h
--- linux-2.4.29/include/asm-e1nommu/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/serial.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,28 @@
+#ifndef _ASM_SERIAL_H
+#define _ASM_SERIAL_H
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+
+/*
+ * This assumes you have a 7.3728 MHz clock for your UART.
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ */
+#define BASE_BAUD ( 7372800 / 16 )
+
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+#define RS_TABLE_SIZE  1
+
+#define STD_SERIAL_PORT_DEFNS                   \
+        /* UART CLK   PORT IRQ     FLAGS        */                      \
+        { 0, BASE_BAUD, 0x01C00000, 2-1, STD_COM_FLAGS }  /* ttyS0 */
+
+#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS
+
+#define irq_cannonicalize(x) (x)
+
+#endif /* _ASM_SERIAL_H */
diff -urN linux-2.4.29/include/asm-e1nommu/setup.h linux-2.4.29-uc1/include/asm-e1nommu/setup.h
--- linux-2.4.29/include/asm-e1nommu/setup.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/setup.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef _HYPERSTONE_SETUP_H_
+#define _HYPERSTONE_SETUP_H_
+
+/*  #include <asm/io.h> */
+
+#endif /* !_HYPERSTONE_SETUP_H_ */
diff -urN linux-2.4.29/include/asm-e1nommu/shmbuf.h linux-2.4.29-uc1/include/asm-e1nommu/shmbuf.h
--- linux-2.4.29/include/asm-e1nommu/shmbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/shmbuf.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,45 @@
+#ifndef _HYPERSTONE_NOMMU_SHMBUF_H
+#define _HYPERSTONE_NOMMU_SHMBUF_H
+
+#if 0 /* Out for the time being by G.Thanos*/
+/* 
+ * The shmid64_ds structure for m68k architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	unsigned long		__unused1;
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	unsigned long		__unused2;
+	__kernel_time_t		shm_ctime;	/* last change time */
+	unsigned long		__unused3;
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif
+
+#endif /* _HYPERSTONE_NOMMU_SHMBUF_H */
diff -urN linux-2.4.29/include/asm-e1nommu/shmparam.h linux-2.4.29-uc1/include/asm-e1nommu/shmparam.h
--- linux-2.4.29/include/asm-e1nommu/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/shmparam.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,8 @@
+#ifndef _HYPERSTONE_NOMMU_SHMPARAM_H
+#define _HYPERSTONE_NOMMU_SHMPARAM_H
+
+#if 0 /* Out for the time being */
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
+#endif
+
+#endif /* _HYPERSTONE_NOMMU_SHMPARAM_H */
diff -urN linux-2.4.29/include/asm-e1nommu/sigcontext.h linux-2.4.29-uc1/include/asm-e1nommu/sigcontext.h
--- linux-2.4.29/include/asm-e1nommu/sigcontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/sigcontext.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef _HYPERSTONE_NOMMU_SIGCONTEXT_H
+#define _HYPERSTONE_NOMMU_SIGCONTEXT_H
+
+/*
+ * Signal context structure - contains all info to do with the state
+ * before the signal handler was invoked.  Note: only add new entries
+ * to the end of the structure.
+ */
+struct sigcontext {
+};
+
+
+#endif /* _HYPERSTONE_NOMMU_SIGCONTEXT_H */
diff -urN linux-2.4.29/include/asm-e1nommu/siginfo.h linux-2.4.29-uc1/include/asm-e1nommu/siginfo.h
--- linux-2.4.29/include/asm-e1nommu/siginfo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/siginfo.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,231 @@
+#ifndef _HYPERSTONE_NOMMU_SIGINFO_H
+#define _HYPERSTONE_NOMMU_SIGINFO_H
+
+#include <linux/types.h>
+
+typedef union sigval {
+	int sival_int;
+	void *sival_ptr;
+} sigval_t;
+
+#define SI_MAX_SIZE	128
+#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct siginfo {
+	int si_signo;
+	int si_errno;
+	int si_code;
+
+	union {
+		int _pad[SI_PAD_SIZE];
+
+		/* kill() */
+		struct {
+			pid_t _pid;		/* sender's pid */
+			uid_t _uid;		/* sender's uid */
+		} _kill;
+
+		/* POSIX.1b timers */
+		struct {
+			unsigned int _timer1;
+			unsigned int _timer2;
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			pid_t _pid;		/* sender's pid */
+			uid_t _uid;		/* sender's uid */
+			sigval_t _sigval;
+		} _rt;
+
+		/* SIGCHLD */
+		struct {
+			pid_t _pid;		/* which child */
+			uid_t _uid;		/* sender's uid */
+			int _status;		/* exit code */
+			clock_t _utime;
+			clock_t _stime;
+		} _sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			void *_addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+	} _sifields;
+} siginfo_t;
+
+/*
+ * How these fields are to be accessed.
+ */
+#define si_pid		_sifields._kill._pid
+#define si_uid		_sifields._kill._uid
+#define si_status	_sifields._sigchld._status
+#define si_utime	_sifields._sigchld._utime
+#define si_stime	_sifields._sigchld._stime
+#define si_value	_sifields._rt._sigval
+#define si_int		_sifields._rt._sigval.sival_int
+#define si_ptr		_sifields._rt._sigval.sival_ptr
+#define si_addr		_sifields._sigfault._addr
+#define si_band		_sifields._sigpoll._band
+#define si_fd		_sifields._sigpoll._fd
+
+#ifdef __KERNEL__
+#define __SI_MASK	0xffff0000
+#define __SI_KILL	(0 << 16)
+#define __SI_TIMER	(1 << 16)
+#define __SI_POLL	(2 << 16)
+#define __SI_FAULT	(3 << 16)
+#define __SI_CHLD	(4 << 16)
+#define __SI_RT		(5 << 16)
+#define __SI_CODE(T,N)	((T) << 16 | ((N) & 0xffff))
+#else
+#define __SI_KILL	0
+#define __SI_TIMER	0
+#define __SI_POLL	0
+#define __SI_FAULT	0
+#define __SI_CHLD	0
+#define __SI_RT		0
+#define __SI_CODE(T,N)	(N)
+#endif
+
+/*
+ * si_code values
+ * Digital reserves positive values for kernel-generated signals.
+ */
+#define SI_USER		0		/* sent by kill, sigsend, raise */
+#define SI_KERNEL	0x80		/* sent by the kernel from somewhere */
+#define SI_QUEUE	-1		/* sent by sigqueue */
+#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
+#define SI_MESGQ	-3		/* sent by real time mesq state change */
+#define SI_ASYNCIO	-4		/* sent by AIO completion */
+#define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
+
+#define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
+#define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
+
+/*
+ * SIGILL si_codes
+ */
+#define ILL_ILLOPC	(__SI_FAULT|1)	/* illegal opcode */
+#define ILL_ILLOPN	(__SI_FAULT|2)	/* illegal operand */
+#define ILL_ILLADR	(__SI_FAULT|3)	/* illegal addressing mode */
+#define ILL_ILLTRP	(__SI_FAULT|4)	/* illegal trap */
+#define ILL_PRVOPC	(__SI_FAULT|5)	/* privileged opcode */
+#define ILL_PRVREG	(__SI_FAULT|6)	/* privileged register */
+#define ILL_COPROC	(__SI_FAULT|7)	/* coprocessor error */
+#define ILL_BADSTK	(__SI_FAULT|8)	/* internal stack error */
+#define NSIGILL		8
+
+/*
+ * SIGFPE si_codes
+ */
+#define FPE_INTDIV	(__SI_FAULT|1)	/* integer divide by zero */
+#define FPE_INTOVF	(__SI_FAULT|2)	/* integer overflow */
+#define FPE_FLTDIV	(__SI_FAULT|3)	/* floating point divide by zero */
+#define FPE_FLTOVF	(__SI_FAULT|4)	/* floating point overflow */
+#define FPE_FLTUND	(__SI_FAULT|5)	/* floating point underflow */
+#define FPE_FLTRES	(__SI_FAULT|6)	/* floating point inexact result */
+#define FPE_FLTINV	(__SI_FAULT|7)	/* floating point invalid operation */
+#define FPE_FLTSUB	(__SI_FAULT|8)	/* subscript out of range */
+#define NSIGFPE		8
+
+/*
+ * SIGSEGV si_codes
+ */
+#define SEGV_MAPERR	(__SI_FAULT|1)	/* address not mapped to object */
+#define SEGV_ACCERR	(__SI_FAULT|2)	/* invalid permissions for mapped object */
+#define NSIGSEGV	2
+
+/*
+ * SIGBUS si_codes
+ */
+#define BUS_ADRALN	(__SI_FAULT|1)	/* invalid address alignment */
+#define BUS_ADRERR	(__SI_FAULT|2)	/* non-existant physical address */
+#define BUS_OBJERR	(__SI_FAULT|3)	/* object specific hardware error */
+#define NSIGBUS		3
+
+/*
+ * SIGTRAP si_codes
+ */
+#define TRAP_BRKPT	(__SI_FAULT|1)	/* process breakpoint */
+#define TRAP_TRACE	(__SI_FAULT|2)	/* process trace trap */
+#define NSIGTRAP	2
+
+/*
+ * SIGCHLD si_codes
+ */
+#define CLD_EXITED	(__SI_CHLD|1)	/* child has exited */
+#define CLD_KILLED	(__SI_CHLD|2)	/* child was killed */
+#define CLD_DUMPED	(__SI_CHLD|3)	/* child terminated abnormally */
+#define CLD_TRAPPED	(__SI_CHLD|4)	/* traced child has trapped */
+#define CLD_STOPPED	(__SI_CHLD|5)	/* child has stopped */
+#define CLD_CONTINUED	(__SI_CHLD|6)	/* stopped child has continued */
+#define NSIGCHLD	6
+
+/*
+ * SIGPOLL si_codes
+ */
+#define POLL_IN		(__SI_POLL|1)	/* data input available */
+#define POLL_OUT	(__SI_POLL|2)	/* output buffers available */
+#define POLL_MSG	(__SI_POLL|3)	/* input message available */
+#define POLL_ERR	(__SI_POLL|4)	/* i/o error */
+#define POLL_PRI	(__SI_POLL|5)	/* high priority input available */
+#define POLL_HUP	(__SI_POLL|6)	/* device disconnected */
+#define NSIGPOLL	6
+
+/*
+ * sigevent definitions
+ * 
+ * It seems likely that SIGEV_THREAD will have to be handled from 
+ * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
+ * thread manager then catches and does the appropriate nonsense.
+ * However, everything is written out here so as to not get lost.
+ */
+#define SIGEV_SIGNAL	0	/* notify via signal */
+#define SIGEV_NONE	1	/* other notification: meaningless */
+#define SIGEV_THREAD	2	/* deliver via thread creation */
+
+#define SIGEV_MAX_SIZE	64
+#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct sigevent {
+	sigval_t sigev_value;
+	int sigev_signo;
+	int sigev_notify;
+	union {
+		int _pad[SIGEV_PAD_SIZE];
+
+		struct {
+			void (*_function)(sigval_t);
+			void *_attribute;	/* really pthread_attr_t */
+		} _sigev_thread;
+	} _sigev_un;
+} sigevent_t;
+
+#define sigev_notify_function	_sigev_un._sigev_thread._function
+#define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
+
+#ifdef __KERNEL__
+#include <linux/string.h>
+
+extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
+{
+	if (from->si_code < 0)
+		memcpy(to, from, sizeof(siginfo_t));
+	else
+		/* _sigchld is currently the largest know union member */
+		memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
+}
+
+extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
+
+#endif /* __KERNEL__ */
+
+#endif /* _HYPERSTONE_NOMMU_SIGINFO_H */
diff -urN linux-2.4.29/include/asm-e1nommu/signal.h linux-2.4.29-uc1/include/asm-e1nommu/signal.h
--- linux-2.4.29/include/asm-e1nommu/signal.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/signal.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,185 @@
+#ifndef _HYPERSTONE_NOMMU_SIGNAL_H
+#define _HYPERSTONE_NOMMU_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+#define SIGSWI		32
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_NOCLDSTOP		flag to turn off SIGCHLD when children stop.
+ * SA_NOCLDWAIT		flag on SIGCHLD to inhibit zombies.
+ * SA_SIGINFO		deliver the signal with SIGINFO structs
+ * SA_THIRTYTWO		delivers the signal in 32-bit mode, even if the task 
+ *			is running in 26-bit.
+ * SA_ONSTACK		allows alternate signal stacks (see sigaltstack(2)).
+ * SA_RESTART		flag to get restarting signals (which were the default long ago)
+ * SA_INTERRUPT		is a no-op, but left due to historical reasons. Use the
+ * SA_NODEFER		prevents the current signal from being masked in the handler.
+ * SA_RESETHAND		clears the handler when the signal is delivered.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_THIRTYTWO	0x02000000
+#define SA_RESTORER	0x04000000
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#ifdef __KERNEL__
+
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE		0x80000000
+#define SA_SAMPLE_RANDOM	0x10000000
+#define SA_IRQNOMASK		0x08000000
+#define SA_SHIRQ		0x04000000
+#endif
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+#ifdef __KERNEL__
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+#include <asm/sigcontext.h>
+
+#define sigmask(sig)	(1UL << ((sig) - 1))
+
+#endif
+
+#endif /* _HYPERSTONE_NOMMU_SIGNAL_H */
diff -urN linux-2.4.29/include/asm-e1nommu/socket.h linux-2.4.29-uc1/include/asm-e1nommu/socket.h
--- linux-2.4.29/include/asm-e1nommu/socket.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/socket.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,64 @@
+#ifndef _HYPERSTONE_SOCKET_H
+#define _HYPERSTONE_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED	16
+#define SO_PEERCRED	17
+#define SO_RCVLOWAT	18
+#define SO_SNDLOWAT	19
+#define SO_RCVTIMEO	20
+#define SO_SNDTIMEO	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE	25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME		28
+#define SO_TIMESTAMP		29
+#define SCM_TIMESTAMP		SO_TIMESTAMP
+
+#define SO_ACCEPTCONN		30
+
+/* Nasty libc5 fixup - bletch */
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+/* Socket types. */
+#define SOCK_STREAM	1		/* stream (connection) socket	*/
+#define SOCK_DGRAM	2		/* datagram (conn.less) socket	*/
+#define SOCK_RAW	3		/* raw socket			*/
+#define SOCK_RDM	4		/* reliably-delivered message	*/
+#define SOCK_SEQPACKET	5		/* sequential packet socket	*/
+#define SOCK_PACKET	10		/* linux specific way of	*/
+					/* getting packets at the dev	*/
+					/* level.  For writing rarp and	*/
+					/* other similar things on the	*/
+					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
+#endif
+
+#endif /* _HYPERSTONE_SOCKET_H */
diff -urN linux-2.4.29/include/asm-e1nommu/sockios.h linux-2.4.29-uc1/include/asm-e1nommu/sockios.h
--- linux-2.4.29/include/asm-e1nommu/sockios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/sockios.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef __ARCH_HYPERSTONE_SOCKIOS__
+#define __ARCH_HYPERSTONE_SOCKIOS__
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 	0x8901
+#define SIOCSPGRP	0x8902
+#define FIOGETOWN	0x8903
+#define SIOCGPGRP	0x8904
+#define SIOCATMARK	0x8905
+#define SIOCGSTAMP	0x8906		/* Get stamp */
+
+#endif /* __ARCH_HYPERSTONE_SOCKIOS__ */
diff -urN linux-2.4.29/include/asm-e1nommu/softirq.h linux-2.4.29-uc1/include/asm-e1nommu/softirq.h
--- linux-2.4.29/include/asm-e1nommu/softirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/softirq.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,19 @@
+#ifndef _HYPERSTONE_SOFTIRQ_H_
+#define _HYPERSTONE_SOFTIRQ_H_
+
+#include <asm/atomic.h>
+#include <asm/hardirq.h>
+
+#define __cpu_bh_enable(cpu) \
+                do { barrier(); local_bh_count(cpu)--; } while (0)
+#define cpu_bh_disable(cpu) \
+                do { local_bh_count(cpu)++; barrier(); } while (0)
+
+#define local_bh_disable()      cpu_bh_disable(smp_processor_id())
+#define __local_bh_enable()     __cpu_bh_enable(smp_processor_id())
+
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
+
+#define local_bh_enable() __local_bh_enable()
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/st16550_serial.h linux-2.4.29-uc1/include/asm-e1nommu/st16550_serial.h
--- linux-2.4.29/include/asm-e1nommu/st16550_serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/st16550_serial.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,28 @@
+#ifndef __HYPERSTONE_NOMMU_SERIAL_H
+#define __HYPERSTONE_NOMMU_SERIAL_H
+
+#include <linux/config.h> 
+#include <asm/io.h> 
+
+#ifdef CONFIG_EMBEDDED_SERIAL_CONSOLE
+static unsigned long Debug_UART = (((CONFIG_EMBEDDED_SERIAL_CONSOLE_CS + 4) << 22) | ( 0x3 << IOSetupTime ) | (0x7 << IOAccessTime) | (0x3 << IOHoldTime)) ;
+#endif
+
+#define XTAL 7372800 /* The oscilator's frequency */
+
+#define FIFO_ENABLE 0x07
+#define INT_ENABLE  0x04	/* default interrupt mask */
+
+
+struct low_level_serial {
+	int port;
+	unsigned long base_addr;
+	unsigned long chipselect;
+	unsigned long addr_offset;
+	int SetupTime;
+	int AccessTime;
+	int HoldTime;
+};
+
+
+#endif /* __HYPERSTONE_NOMMU_SERIAL_H */
diff -urN linux-2.4.29/include/asm-e1nommu/stack.h linux-2.4.29-uc1/include/asm-e1nommu/stack.h
--- linux-2.4.29/include/asm-e1nommu/stack.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/stack.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,14 @@
+#ifndef __ASM_E1_STACK_H__
+#define __ASM_E1_STACK_H__
+
+/* We assign a stack offset of 512 bytes
+ * We need at least <register_size>*64 = 256 bytes
+ */
+#define STACK_OFFSET  0x200
+
+/* A register stack size of 4K is considered enough for most applications
+ * If not increase from here...
+ */
+#define USER_REGISTER_STACK_SIZE 0x1000
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/statfs.h linux-2.4.29-uc1/include/asm-e1nommu/statfs.h
--- linux-2.4.29/include/asm-e1nommu/statfs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/statfs.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef _HYPERSTONE_STATFS_H
+#define _HYPERSTONE_STATFS_H
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t	fsid_t;
+
+#endif
+
+struct statfs {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_spare[6];
+};
+
+#endif /* _HYPERSTONE_STATFS_H */
diff -urN linux-2.4.29/include/asm-e1nommu/stat.h linux-2.4.29-uc1/include/asm-e1nommu/stat.h
--- linux-2.4.29/include/asm-e1nommu/stat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/stat.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,78 @@
+#ifndef _HYPERSTONE_STAT_H_
+#define _HYPERSTONE_STAT_H_
+
+struct __old_kernel_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+struct stat {
+	unsigned short st_dev;
+	unsigned short __pad1;
+	unsigned long st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned short __pad2;
+	unsigned long  st_size;
+	unsigned long  st_blksize;
+	unsigned long  st_blocks;
+	unsigned long  st_atime;
+	unsigned long  __unused1;
+	unsigned long  st_mtime;
+	unsigned long  __unused2;
+	unsigned long  st_ctime;
+	unsigned long  __unused3;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat64 {
+	unsigned short	st_dev;
+	unsigned char	__pad0[10];
+
+#define STAT64_HAS_BROKEN_ST_INO	1
+	unsigned long	__st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned short	st_rdev;
+	unsigned char	__pad3[10];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+
+	unsigned long	st_atime;
+	unsigned long	__pad5;
+
+	unsigned long	st_mtime;
+	unsigned long	__pad6;
+
+	unsigned long	st_ctime;
+	unsigned long	__pad7;		/* will be high 32 bits of ctime someday */
+
+	unsigned long long	st_ino;
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/string.h linux-2.4.29-uc1/include/asm-e1nommu/string.h
--- linux-2.4.29/include/asm-e1nommu/string.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/string.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,22 @@
+#ifndef _HYPERSTONE_NOMMU_STRING_H
+#define _HYPERSTONE_NOMMU_STRING_H
+
+#define __HAVE_ARCH_MEMCHR
+extern void * memchr(const void * s, int c, size_t count);
+
+#define __HAVE_ARCH_MEMCMP
+extern int memcmp(const void * s ,const void * d ,size_t );
+
+#define __HAVE_ARCH_MEMCPY
+extern void * memcpy(const void *d, const void *s, size_t count);
+
+#define __HAVE_ARCH_MEMSET
+extern void * memset(const void * s, int c, size_t count);
+
+#define __HAVE_ARCH_STRCPY
+extern char * strcpy(char * dest,const char *src);
+
+#define __HAVE_ARCH_STRCMP
+extern int strcmp(const char * cs,const char * ct);
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/syscalls.h linux-2.4.29-uc1/include/asm-e1nommu/syscalls.h
--- linux-2.4.29/include/asm-e1nommu/syscalls.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/syscalls.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,264 @@
+#ifndef _HYPERSTONE_NOMMU_SYSCALLS_H_
+#define _HYPERSTONE_NOMMU_SYSCALLS_H_
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+#include <linux/utime.h>
+#include <linux/module.h>
+#include <linux/sysctl.h>
+#include <asm/poll.h>
+
+struct mmap_arg_struct {
+	unsigned long addr;
+	unsigned long len;
+	unsigned long prot;
+	unsigned long flags;
+	unsigned long fd;
+	unsigned long offset;
+};
+
+struct sel_arg_struct {
+	unsigned long n;
+	fd_set *inp, *outp, *exp;
+	struct timeval *tvp;
+};
+
+extern asmlinkage long sys_ni_syscall(void);
+extern asmlinkage long sys_exit(int);
+extern asmlinkage int sys_fork(struct pt_regs regs);
+extern asmlinkage ssize_t sys_read(unsigned int, char *, size_t);
+extern asmlinkage ssize_t sys_write(unsigned int, const char *, size_t);
+extern asmlinkage long sys_open(const char *, int, int);
+extern asmlinkage long sys_close(unsigned int);
+extern asmlinkage long sys_waitpid(pid_t, unsigned int *, int);
+extern asmlinkage long sys_creat(const char *, int);
+extern asmlinkage long sys_link(const char *, const char *);
+extern asmlinkage long sys_unlink(const char *);
+extern asmlinkage int sys_execve(struct pt_regs regs);
+extern asmlinkage long sys_chdir(const char *);
+extern asmlinkage long sys_time(int *);
+extern asmlinkage long sys_mknod(const char *, int, dev_t);
+extern asmlinkage long sys_chmod(const char *, mode_t);
+extern asmlinkage long sys_chown(const char *, uid_t,gid_t);
+/* sys_break is not used */
+/* sys_oldstat is not used */
+extern asmlinkage off_t sys_lseek(unsigned int, off_t, unsigned int);
+extern asmlinkage long sys_getpid(void);
+extern asmlinkage long sys_mount(char *, char *, char *, unsigned long, void *);
+extern asmlinkage long sys_umount(char *, int);
+extern asmlinkage long sys_setuid(uid_t);
+extern asmlinkage long sys_getuid(void);
+extern asmlinkage long sys_stime(int *);
+extern asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
+extern asmlinkage long sys_alarm(unsigned int);
+/* sys_oldfstat is not used */
+extern asmlinkage int sys_pause(void);
+extern asmlinkage long sys_utime(char *, struct utimbuf *);
+/* sys_stty is not used */
+/* sys_gtty is not used */
+extern asmlinkage long sys_access(const char *, int);
+extern asmlinkage long sys_nice(int);
+/* sys_ftime is not used */
+extern asmlinkage long sys_sync(void);
+extern asmlinkage long sys_kill(int, int);
+extern asmlinkage long sys_rename(const char *, const char *);
+extern asmlinkage long sys_mkdir(const char *, int);
+extern asmlinkage long sys_rmdir(const char *);
+extern asmlinkage long sys_dup(int);
+extern asmlinkage int sys_pipe(unsigned long *);
+extern asmlinkage long sys_times(struct tms *);
+/* sys_prof is not used */
+extern asmlinkage long sys_brk(long);
+extern asmlinkage long sys_setgid(gid_t);
+extern asmlinkage long sys_getgid(void);
+extern asmlinkage long sys_signal(int, __sighandler_t);
+extern asmlinkage long sys_geteuid(void);
+extern asmlinkage long sys_getegid(void);
+extern asmlinkage long sys_acct(const char *);
+/* sys_umount2 is not used */
+/* sys_lock is not used */
+extern asmlinkage long sys_ioctl(unsigned int, unsigned int, unsigned long);
+extern asmlinkage long sys_fcntl(unsigned int, unsigned int, unsigned long);
+/* sys_mpx is not used */
+extern asmlinkage long sys_setpgid(pid_t, pid_t);
+/* sys_ulimit is not used */
+/* sys_oldolduname is not used */
+extern asmlinkage long sys_umask(int);
+extern asmlinkage long sys_chroot(const char *);
+extern asmlinkage long sys_ustat(dev_t, struct ustat *);
+extern asmlinkage long sys_dup2(int, int);
+extern asmlinkage long sys_getppid(void);
+extern asmlinkage long sys_getpgrp(void);
+extern asmlinkage long sys_setsid(void);
+extern asmlinkage long sys_sigaction(int, const struct sigaction *, struct sigaction *);
+extern asmlinkage long sys_sgetmask(void);
+extern asmlinkage long sys_ssetmask(int);
+extern asmlinkage long sys_setreuid(uid_t, uid_t);
+extern asmlinkage long sys_setregid(uid_t, uid_t);
+extern asmlinkage long sys_sigsuspend(struct pt_regs);
+extern asmlinkage long sys_sigpending(old_sigset_t *);
+extern asmlinkage long sys_sethostname(char *, int);
+extern asmlinkage long sys_setrlimit(unsigned int, struct rlimit *);
+extern asmlinkage long sys_old_getrlimit(unsigned int, struct rlimit *);
+extern asmlinkage long sys_getrusage(int, struct rusage *);
+extern asmlinkage long sys_gettimeofday(struct timeval *, struct timezone *);
+extern asmlinkage long sys_settimeofday(struct timeval *, struct timezone *);
+extern asmlinkage long sys_getgroups(int, gid_t *);
+extern asmlinkage long sys_setgroups(int, gid_t *);
+extern asmlinkage long sys_old_select(struct sel_arg_struct *);
+extern asmlinkage long sys_symlink(const char *, const char *);
+/* sys_oldlstat is not used */
+extern asmlinkage long sys_readlink(const char *, char *, int);
+extern asmlinkage long sys_uselib(const char *);
+extern asmlinkage long sys_swapon(const char *, int);
+extern asmlinkage long sys_reboot(int, int, unsigned int, void *);
+/* sys_readdir is not used */
+extern asmlinkage int sys_old_mmap(struct mmap_arg_struct *arg);
+extern asmlinkage long sys_munmap(unsigned long, size_t);
+extern asmlinkage long sys_truncate(const char *, unsigned long);
+extern asmlinkage long sys_ftruncate(unsigned int, unsigned long);
+extern asmlinkage long sys_fchmod(unsigned int, mode_t);
+extern asmlinkage long sys_fchown(unsigned int, uid_t,gid_t);
+extern asmlinkage long sys_getpriority(int, int);
+extern asmlinkage long sys_setpriority(int, int,int);
+/* sys_profil is not used */
+extern asmlinkage long sys_statfs(char *, struct statfs *);
+extern asmlinkage long sys_fstatfs(unsigned int, struct statfs *);
+extern asmlinkage int sys_ioperm(unsigned long, unsigned long, int);
+extern asmlinkage long sys_socketcall(int, unsigned long *);
+extern asmlinkage long sys_syslog(int, char *, int);
+extern asmlinkage long sys_setitimer(int, struct itimerval *, struct itimerval *);
+extern asmlinkage long sys_getitimer(int, struct itimerval *);
+//extern asmlinkage long sys_stat(char *, struct __old_kernel_stat *);
+extern asmlinkage long sys_newstat(char *, struct __old_kernel_stat *);
+//extern asmlinkage long sys_lstat(char *, struct __old_kernel_stat *);
+extern asmlinkage long sys_newlstat(char *, struct __old_kernel_stat *);
+//extern asmlinkage long sys_fstat(unsigned int, struct __old_kernel_stat *);
+extern asmlinkage long sys_newfstat(unsigned int, struct __old_kernel_stat *);
+extern asmlinkage long sys_olduname(struct old_utsname *);
+/* sys_iopl is not available */
+extern asmlinkage long sys_vhangup(void);
+/* sys_idle is not used */
+/* sys_vm86 is not used */
+extern asmlinkage long sys_wait4(pid_t, unsigned int *, int, struct rusage *);
+extern asmlinkage long sys_swapoff(const char *);
+extern asmlinkage long sys_sysinfo(struct sysinfo *);
+extern asmlinkage long sys_ipc (uint, int, int, int, void *, long);
+extern asmlinkage long sys_fsync(unsigned int);
+extern asmlinkage long sys_sigreturn(void);
+extern asmlinkage long sys_clone(struct pt_regs);
+extern asmlinkage long sys_setdomainname(char *, int);
+extern asmlinkage long sys_newuname(struct new_utsname * name);
+//extern asmlinkage long sys_uname(struct old_utsname *);
+extern asmlinkage long sys_cacheflush (unsigned long, int, int, unsigned long);
+extern asmlinkage long sys_adjtimex(struct timex *);
+extern asmlinkage long sys_mprotect(unsigned long, size_t, unsigned long);
+extern asmlinkage long sys_sigprocmask(int, old_sigset_t *, old_sigset_t *);
+extern asmlinkage long sys_create_module(const char *, size_t);
+extern asmlinkage long sys_init_module(const char *, struct module *);
+extern asmlinkage long sys_delete_module(const char *);
+extern asmlinkage long sys_get_kernel_syms(struct kernel_sym *);
+extern asmlinkage long sys_quotactl(int, const char *, int, caddr_t);
+extern asmlinkage long sys_getpgid(pid_t);
+extern asmlinkage long sys_fchdir(unsigned int);
+extern asmlinkage long sys_bdflush(int, long);
+extern asmlinkage long sys_sysfs(int, unsigned long, unsigned long);
+extern asmlinkage long sys_personality(unsigned long);
+/* Andrew Filesystem */
+extern asmlinkage long sys_setfsuid(uid_t);
+extern asmlinkage long sys_setfsgid(gid_t);
+extern asmlinkage long sys_llseek(unsigned int, unsigned long, unsigned long, loff_t *, unsigned int);
+extern asmlinkage long sys_getdents(unsigned int, void *, unsigned int);
+extern asmlinkage long sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+extern asmlinkage long sys_flock(unsigned int, unsigned int);
+extern asmlinkage long sys_msync(unsigned long, size_t, int);
+extern asmlinkage long sys_readv(unsigned long, const struct iovec *, unsigned long);
+extern asmlinkage long sys_writev(unsigned long, const struct iovec *, unsigned long);
+extern asmlinkage long sys_getsid(pid_t);
+extern asmlinkage long sys_fdatasync(unsigned int);
+extern asmlinkage long sys_sysctl(struct __sysctl_args *);
+extern asmlinkage long sys_mlock(unsigned long, size_t);
+extern asmlinkage long sys_munlock(unsigned long, size_t);
+extern asmlinkage long sys_mlockall(int);
+extern asmlinkage long sys_munlockall(void);
+extern asmlinkage long sys_sched_setparam(pid_t, struct sched_param *);
+extern asmlinkage long sys_sched_getparam(pid_t, struct sched_param *);
+extern asmlinkage long sys_sched_setscheduler(pid_t, int, struct sched_param *);
+extern asmlinkage long sys_sched_getscheduler(pid_t);
+extern asmlinkage long sys_sched_yield(void);
+extern asmlinkage long sys_sched_get_priority_max(int);
+extern asmlinkage long sys_sched_get_priority_min(int);
+extern asmlinkage long sys_sched_rr_get_interval(pid_t, struct timespec *);
+extern asmlinkage long sys_nanosleep(struct timespec *, struct timespec *);
+extern asmlinkage long sys_mremap(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
+extern asmlinkage long sys_setresuid(uid_t, uid_t, uid_t);
+extern asmlinkage long sys_getresuid(uid_t *, uid_t *, uid_t *);
+extern asmlinkage long sys_query_module(const char *, int, char *, size_t, size_t *);
+extern asmlinkage long sys_poll(struct pollfd *, unsigned int, long);
+extern asmlinkage long sys_nfsservctl(int, void *, void *);
+extern asmlinkage long sys_setresgid(gid_t, gid_t, gid_t);
+extern asmlinkage long sys_getresgid(gid_t *, gid_t *, gid_t *);
+extern asmlinkage long sys_prctl(int, unsigned long, unsigned long, unsigned long, unsigned long);
+/* sys_rt_sigreturn is not available */
+extern asmlinkage long sys_rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t);
+extern asmlinkage long sys_rt_sigprocmask(int, sigset_t *, sigset_t *, size_t);
+extern asmlinkage long sys_rt_sigpending(sigset_t *, size_t);
+extern asmlinkage long sys_rt_sigtimedwait(const sigset_t *, siginfo_t *, const struct timespec *, size_t);
+extern asmlinkage long sys_rt_sigqueueinfo(int, int, siginfo_t *);
+extern asmlinkage long sys_rt_sigsuspend(struct pt_regs);
+extern asmlinkage long sys_pread(unsigned int, char *, size_t, loff_t);
+extern asmlinkage long sys_pwrite(unsigned int, const char *, size_t, loff_t);
+extern asmlinkage long sys_lchown(const char *, uid_t,gid_t);
+extern asmlinkage long sys_getcwd(char *, unsigned long);
+extern asmlinkage long sys_capget(cap_user_header_t, cap_user_data_t);
+extern asmlinkage long sys_capset(cap_user_header_t, const cap_user_data_t);
+/* sys_sigaltstack is not available */
+extern asmlinkage ssize_t sys_sendfile(int, int, off_t *, size_t);
+/* sys_getpmsg is not used */
+/* sys_putpmsg is not used */
+extern asmlinkage int sys_vfork(struct pt_regs regs);
+extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim);
+extern asmlinkage long sys_mmap2(	unsigned long, unsigned long,
+				    				unsigned long, unsigned long,
+					    			unsigned long, unsigned long );
+extern asmlinkage long sys_truncate64(const char *, loff_t);
+extern asmlinkage long sys_ftruncate64(unsigned int, loff_t);
+extern asmlinkage long sys_stat64(char *, struct stat64 *, long);
+extern asmlinkage long sys_lstat64(char *, struct stat64 *, long);
+extern asmlinkage long sys_fstat64(unsigned long, struct stat64 *, long);
+/* sys_chown32 is not used */
+/* sys_getuid32 is not used */
+/* sys_getgid32 is not used */
+/* sys_geteuid32 is not used */
+/* sys_getegid32 is not used */
+/* sys_setreuid32 is not used */
+/* sys_setregid32 is not used */
+/* sys_getgroups32 is not used  */
+/* sys_setgroups32 is not used  */
+/* sys_fchown32 is not used  */
+/* sys_setresuid32 is not used  */
+/* sys_getresuid32 is not used  */
+/* sys_setresgid32 is not used  */ /*210*/
+/* sys_getresgid32 is not used  */
+/* sys_lchown32 is not used  */
+/* sys_setuid32 is not used  */
+/* sys_setgid32 is not used  */
+/* sys_setfsuid32 is not used  */
+/* sys_setfsgid32 is not used  */
+extern asmlinkage long sys_pivot_root(const char *new_root, const char *put_old);
+extern asmlinkage long sys_getdents64(unsigned int fd, void * dirent, unsigned int count);
+extern asmlinkage long sys_gettid(void);
+extern asmlinkage long sys_tkill(int pid, int sig);
+extern asmlinkage long sys_kprintf(const char *msg, int len);
+extern asmlinkage long sys_e1newSP(unsigned long);
+
+#endif /* _HYPERSTONE_NOMMU_SYSCALLS_H_ */
diff -urN linux-2.4.29/include/asm-e1nommu/system.h linux-2.4.29-uc1/include/asm-e1nommu/system.h
--- linux-2.4.29/include/asm-e1nommu/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/system.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,109 @@
+#ifndef _HYPERSTONE_NOMMU_SYSTEM_H
+#define _HYPERSTONE_NOMMU_SYSTEM_H
+
+#include <linux/config.h> /* get configuration macros */
+#include <asm/segment.h>
+
+#define prepare_to_switch()          do { } while(0)
+struct task_struct;
+extern void __switch_to(struct task_struct * prev, struct task_struct * next);
+#define switch_to(prev,next,last)    __switch_to( prev, next )
+
+/* interrupt control */
+#define __cli()			asm volatile ("ori   SR, 0x00008000 \n":::"cc"); 
+#define __sti()			asm volatile ("andni SR, 0x00008000 \n":::"cc");
+
+#define __save_flags(x)		\
+	  asm volatile ("mask %0, SR, 0x0000800F\n\t" \
+				    :"=l"(x) \
+		  :/* no input*/ \
+		  :"memory"); 
+							
+#define __restore_flags(x)						\
+{ static unsigned long temp; 					\
+		asm volatile (							\
+			"movi %0, 0x0\n\t"					\
+			"mask %0, SR, 0xffff7FF0\n\t" 		\
+			"or   %0, %1\n\t" 					\
+			"mov  SR, %0\n\t" 					\
+		  :/* no output*/  \
+		  :"l" (temp), "l"(x) \
+		  :"memory"); }
+
+#define	__save_and_cli(flags) \
+		  do { save_flags(flags); cli(); }\
+		  while(0) 
+
+#define cli()   		__cli()
+#define sti()   		__sti()
+#define save_flags(flags)       __save_flags(flags)
+#define restore_flags(flags)    __restore_flags(flags)
+#define save_and_cli(flags)     __save_and_cli(flags)
+
+/* For spinlocks etc */
+#define local_irq_save(x)       ({ __save_flags(x); __cli(); })
+#define local_irq_restore(x)    ({__restore_flags(x); }) 
+#define local_irq_disable()     __cli()
+#define local_irq_enable()      __sti()
+
+#define nop()          	__asm__ __volatile__ ("nop"::)
+#define mb()			__asm__ __volatile__ ("" ::: "memory")
+#define rmb()			mb ()
+#define wmb()			mb ()
+#define read_barrier_depends()	((void)0)
+#define set_mb(var, value)	do { var = value; mb (); } while (0)
+#define set_wmb(var, value)	do { var = value; wmb (); } while (0)
+
+#define smp_mb()	mb ()
+#define smp_rmb()	rmb ()
+#define smp_wmb()	wmb ()
+#define smp_read_barrier_depends()	read_barrier_depends()
+	
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+#define tas(ptr) (xchg((ptr),1))
+
+/* This function doesn't exist, so you'll get a linker error
+   if something tries to do an invalid xchg().  */
+
+extern unsigned long __xchg_called_with_bad_pointer(void);
+
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+
+  unsigned long tmp; //, flags; /* FIXME ?? */
+//  save_flags(flags);
+//  cli();
+
+  switch (size) {
+  case 1:
+	__asm__ __volatile__
+    ("
+	  ldbu.d %2, %0, 0 
+	  stbu.d %2, %1, 0"
+    : "=l" (tmp) : "l" (x), "l" (ptr) : "memory");
+    break;
+  case 2:
+    __asm__ __volatile__
+    ("
+	  ldhu.d %2, %0, 0 
+	  sthu.d %2, %1, 0"
+    : "=l" (tmp) : "l" (x), "l" (ptr) : "memory");
+    break;
+  case 4:
+    __asm__ __volatile__
+    ("
+	  ldw.d %2, %0, 0 
+	  stw.d %2, %1, 0"
+    : "=l" (tmp) : "l" (x), "l" (ptr) : "memory");
+    break;
+	
+  default:
+	__xchg_called_with_bad_pointer();
+  }
+//  restore_flags(flags);
+	return tmp;
+}
+/* Yannis: FIXME */
+#define HARD_RESET_NOW()	do{}while(0)
+
+#endif 
diff -urN linux-2.4.29/include/asm-e1nommu/termbits.h linux-2.4.29-uc1/include/asm-e1nommu/termbits.h
--- linux-2.4.29/include/asm-e1nommu/termbits.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/termbits.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,170 @@
+#ifndef __HYPERSTONE_NOMMU_TERMBITS_H
+#define __HYPERSTONE_NOMMU_TERMBITS_H
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#define NCCS 19
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IUCLC	0001000
+#define IXON	0002000
+#define IXANY	0004000
+#define IXOFF	0010000
+#define IMAXBEL	0020000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define OLCUC	0000002
+#define ONLCR	0000004
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#define NLDLY	0000400
+#define   NL0	0000000
+#define   NL1	0000400
+#define CRDLY	0003000
+#define   CR0	0000000
+#define   CR1	0001000
+#define   CR2	0002000
+#define   CR3	0003000
+#define TABDLY	0014000
+#define   TAB0	0000000
+#define   TAB1	0004000
+#define   TAB2	0010000
+#define   TAB3	0014000
+#define   XTABS	0014000
+#define BSDLY	0020000
+#define   BS0	0000000
+#define   BS1	0020000
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+#define FFDLY	0100000
+#define   FF0	0000000
+#define   FF1	0100000
+
+/* c_cflag bit meaning */
+#define CBAUD	0010017
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE	0000060
+#define   CS5	0000000
+#define   CS6	0000020
+#define   CS7	0000040
+#define   CS8	0000060
+#define CSTOPB	0000100
+#define CREAD	0000200
+#define PARENB	0000400
+#define PARODD	0001000
+#define HUPCL	0002000
+#define CLOCAL	0004000
+#define CBAUDEX 0010000
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+#define CIBAUD	  002003600000	/* input baud rate (not used) */
+#define CMSPAR    010000000000		/* mark or space (stick) parity */
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+#define ISIG	0000001
+#define ICANON	0000002
+#define XCASE	0000004
+#define ECHO	0000010
+#define ECHOE	0000020
+#define ECHOK	0000040
+#define ECHONL	0000100
+#define NOFLSH	0000200
+#define TOSTOP	0000400
+#define ECHOCTL	0001000
+#define ECHOPRT	0002000
+#define ECHOKE	0004000
+#define FLUSHO	0010000
+#define PENDIN	0040000
+#define IEXTEN	0100000
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif	/* __HYPERSTONE_NOMMU_TERMBITS_H  */
diff -urN linux-2.4.29/include/asm-e1nommu/termios.h linux-2.4.29-uc1/include/asm-e1nommu/termios.h
--- linux-2.4.29/include/asm-e1nommu/termios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/termios.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,108 @@
+#ifndef __HYPERSTONE_NOMMU_TERMIOS_H
+#define __HYPERSTONE_NOMMU_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+#ifdef __KERNEL__
+/*	intr=^C		quit=^|		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+#endif
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6	/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14
+#define N_HCI		15  /* Bluetooth HCI UART */
+
+#ifdef __KERNEL__
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) {		\
+	unsigned short __tmp;					\
+	get_user(__tmp,&(termio)->x);				\
+	*(unsigned short *) &(termios)->x = __tmp;		\
+}
+
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif	/* __KERNEL__ */
+
+#endif	/* __HYPERSTONE_NOMMU_TERMIOS_H */
diff -urN linux-2.4.29/include/asm-e1nommu/timex.h linux-2.4.29-uc1/include/asm-e1nommu/timex.h
--- linux-2.4.29/include/asm-e1nommu/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/timex.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,23 @@
+#ifndef _HYPERSTONE_TIMEX_H
+#define _HYPERSTONE_TIMEX_H
+
+#if 0 // Out for the time being (G.Thanos)
+#define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
+#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
+
+#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
+	(1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
+		<< (SHIFT_SCALE-SHIFT_HZ)) / HZ)
+#endif // 0
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+	return 0;
+}
+
+#define vxtime_lock()		do {} while (0)
+#define vxtime_unlock()		do {} while (0)
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/tlb.h linux-2.4.29-uc1/include/asm-e1nommu/tlb.h
--- linux-2.4.29/include/asm-e1nommu/tlb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/tlb.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-generic/tlb.h>
diff -urN linux-2.4.29/include/asm-e1nommu/types.h linux-2.4.29-uc1/include/asm-e1nommu/types.h
--- linux-2.4.29/include/asm-e1nommu/types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/types.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,57 @@
+#ifndef _HYPERSTONE_TYPES_H
+#define _HYPERSTONE_TYPES_H
+
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue.  However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ */
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide.  */
+typedef u32 dma_addr_t;
+
+#endif /* __KERNEL__ */
+
+#endif /* _HYPERSTONE_TYPES_H */
diff -urN linux-2.4.29/include/asm-e1nommu/uaccess.h linux-2.4.29-uc1/include/asm-e1nommu/uaccess.h
--- linux-2.4.29/include/asm-e1nommu/uaccess.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/uaccess.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,153 @@
+#ifndef _HYPERSTONE_UACCESS_H_
+#define _HYPERSTONE_UACCESS_H_
+
+#include <linux/sched.h>
+#include <asm/segment.h>
+
+#define VERIFY_READ     0
+#define VERIFY_WRITE    1
+
+
+extern inline int access_ok(int type, const void * addr, unsigned long size)
+{
+extern unsigned long __ramend;
+extern unsigned long _ramstart;
+#define RANGE_CHECK_OK(addr, size, lower, upper) \
+        (((addr) >= (lower)) && (((addr) + (size)) < (upper)))
+
+/* Since we do not have an MMU we just check to 
+ * ensure that the address is inside the valid address space. 
+ * I suppose that we should also exclude the kernel space the data 
+ * and bss segment as well as the exception entry table. Since by default
+ * the exception table begins at 0xFC we do not make any other check.
+ * or in the entry table. 0x01000000 since we have 16MB ram.
+ */ 
+	return(RANGE_CHECK_OK((unsigned long)addr, size, (unsigned long)PAGE_ALIGN(_ramstart), (unsigned long)&__ramend));
+}
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+        return access_ok(type,addr,size)?0:-EFAULT;
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+#define __get_user(var, ptr)						      \
+  ({									      \
+	  int __gu_err = 0;						      \
+	  typeof(*(ptr)) __gu_val = 0;					      \
+	  switch (sizeof (*(ptr))) {					      \
+	  case 1:							      \
+	  case 2:							      \
+	  case 4:							      \
+		  __gu_val = *(ptr);					      \
+		  break;						      \
+	  case 8:							      \
+		  memcpy(&__gu_val, ptr, sizeof(__gu_val));		      \
+		  break;						      \
+	  default:							      \
+		  __gu_val = 0;						      \
+		  __gu_err = __get_user_bad ();				      \
+		  break;						      \
+	  }								      \
+	  (var) = __gu_val;						      \
+	  __gu_err;							      \
+  })
+#define __get_user_bad()	(bad_user_access_length (), (-EFAULT))
+
+#define __put_user(var, ptr)						      \
+  ({									      \
+	  int __pu_err = 0;						      \
+	  switch (sizeof (*(ptr))) {					      \
+	  case 1:							      \
+	  case 2:							      \
+	  case 4:							      \
+		  *(ptr) = (var);					      \
+		  break;						      \
+	  case 8: {							      \
+	  	  typeof(*(ptr)) __pu_val = 0;				      \
+		  __pu_val = var;						\
+		  memcpy(ptr, &__pu_val, sizeof(__pu_val));		      \
+		  }							      \
+		  break;						      \
+	  default:							      \
+		  __pu_err = __put_user_bad ();				      \
+		  break;						      \
+	  }								      \
+	  __pu_err;							      \
+  })
+
+extern int bad_user_access_length (void);
+
+#define __put_user_bad()	(bad_user_access_length (), (-EFAULT))
+
+#define put_user(x, ptr)	__put_user(x, ptr)
+#define get_user(x, ptr)	__get_user(x, ptr)
+
+#define __copy_from_user(to, from, n)	(memcpy (to, from, n), 0)
+#define __copy_to_user(to, from, n)	(memcpy(to, from, n), 0)
+
+#define copy_from_user(to, from, n)	__copy_from_user (to, from, n)
+#define copy_to_user(to, from, n) 	__copy_to_user(to, from, n)
+
+#define copy_to_user_ret(to,from,n,retval) \
+  ({ if (copy_to_user (to,from,n)) return retval; })
+
+#define copy_from_user_ret(to,from,n,retval) \
+  ({ if (copy_from_user (to,from,n)) return retval; })
+
+/*
+ * Copy a null terminated string from userspace.
+ */
+static inline long
+strncpy_from_user(char *dst, const char *src, long count)
+{
+        char *tmp;
+        strncpy(dst, src, count);
+        for (tmp = dst; *tmp && count > 0; tmp++, count--)
+                ;
+        return(tmp - dst);
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 for error
+ */
+static inline long strnlen_user(const char * src, long n)
+{
+  return(strlen(src) + 1);
+}
+#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
+
+
+/*
+ * Zero Userspace
+ */
+
+static inline unsigned long
+clear_user (void *to, unsigned long n)
+{
+	memset (to, 0, n);
+	return 0;
+}
+#endif /* !_HYPERSTONE_UACCESS_H_ */
diff -urN linux-2.4.29/include/asm-e1nommu/unaligned.h linux-2.4.29-uc1/include/asm-e1nommu/unaligned.h
--- linux-2.4.29/include/asm-e1nommu/unaligned.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/unaligned.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef _HYPERSTONE_UNALIGNED_H_
+#define _HYPERSTONE_UNALIGNED_H_
+
+#include <asm-generic/unaligned.h>
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/unistd.h linux-2.4.29-uc1/include/asm-e1nommu/unistd.h
--- linux-2.4.29/include/asm-e1nommu/unistd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/unistd.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,610 @@
+#ifndef _HYPERSTONE_NOMMU_UNISTD_H_
+#define _HYPERSTONE_NOMMU_UNISTD_H_
+
+#define __E1_COFF_GCC__
+
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid	  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_chown		 16
+#define __NR_break		 17
+#define __NR_oldstat		18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_umount2		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+#define __NR_oldolduname	 59
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_old_getrlimit	 76
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+#define __NR_ioperm		101
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_olduname		109
+#define __NR_iopl		/* 110 */ not supported
+#define __NR_vhangup		111
+#define __NR_idle		/* 112 */ Obsolete
+#define __NR_vm86		/* 113 */ not supported
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_cacheflush		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+/*166 is missing*/
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl		172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread		180
+#define __NR_pwrite		181
+#define __NR_lchown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_getpmsg		188	/* some people actually want streams */
+#define __NR_putpmsg		189	/* some people actually want streams */
+#define __NR_vfork		190
+#define __NR_getrlimit		191
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_chown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_lchown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+#define __NR_pivot_root         217
+#define __NR_getdents64         220
+#define __NR_gettid             221
+#define __NR_tkill              222
+#define __NR_kprintf            223
+
+/* user-visible error numbers are in the range -1 - -124: see <asm/errno.h> */
+
+#if 0
+#define _syscall0(type, name)           \
+type name(void)                         \
+{                                       \
+        register int res;               \
+        __asm__ __volatile__(           \
+            "movi  L4, -1\n\t"          \
+            "movi  L3, %0\n\t"          \
+        :/* no output */                \
+        :"i" (__NR_##name)              \
+        :"cc","memory","L4","L3" );     \
+        __asm__ __volatile__(           \
+            "trap    47\n\t"            \
+            "mov %0, L4\n\t"            \
+        :"=l"(res)                      \
+        :/* no input */                 \
+        :"memory","L4");                \
+        return (type)(res);             \
+}
+
+#define _syscall1(type, name,atype, a)  \
+type name(atype a)                      \
+{                                       \
+        register int res;               \
+        __asm__ __volatile__(           \
+            "movi   L5, -1\n\t"         \
+            "movi   L4, %0\n\t"         \
+            "mov    L3, %1\n\t"         \
+        :/* no output */                \
+        :"i"(__NR_##name),              \
+         "l"(a)                         \
+        :"cc","memory","L5","L4","L3");      \
+        __asm__ __volatile__(           \
+            "trap    47\n\t"            \
+            "mov %0, L5\n\t"            \
+        :"=l"(res)                      \
+        :/* no input */                 \
+        :"memory","L5");                \
+        return (type)(res);             \
+}
+
+#define _syscall2(type, name,atype, a,btype, b)  \
+type name(atype a, btype b)                      \
+{                                               \
+        register int res;                       \
+        __asm__ __volatile__(                   \
+            "movi  L7, -1\n\t"   				\
+            "movi  L6, %0\n\t"                  \
+            "mov   L5, %1\n\t"                  \
+            "mov   L4, %2\n\t"                  \
+        :/* no output*/                         \
+        :"i"(__NR_##name),                      \
+         "l"(a),                                \
+         "l"(b)                                 \
+        :"cc","memory","L7","L6","L5","L4");    \
+        __asm__ __volatile__(                   \
+            "trap    47\n\t"                    \
+            "mov %0, L7\n\t"                    \
+        :"=l"(res)                              \
+        :/* no input */                         \
+        :"memory","L7");                        \
+        return (type)(res);                     \
+}
+
+#define _syscall3(type, name,atype, a, btype, b, ctype, c)  \
+type name(atype a, btype b, ctype c)                      \
+{                                               \
+        register int res;                       \
+        __asm__ __volatile__(                   \
+            "movi  L9, -1\n\t"   				\
+            "movi  L8, %0\n\t"                  \
+            "mov   L7, %1\n\t"                  \
+            "mov   L6, %2\n\t"                  \
+            "mov   L5, %3\n\t"                  \
+        :/* no output*/                         \
+        :"i"(__NR_##name),                      \
+         "l"(a),                                \
+         "l"(b),                                \
+         "l"(c)                                 \
+        :"cc","memory","L5","L6","L7","L8","L9");    \
+        __asm__ __volatile__(                   \
+            "trap    47\n\t"                    \
+            "mov %0, L9\n\t"                    \
+        :"=l"(res)                              \
+        :/* no input */                         \
+        :"memory","L9");                        \
+        return (type)(res);                     \
+}
+
+#define _syscall4(type, name,atype, a, btype, b, ctype, c, dtype, d)  \
+type name(atype a, btype b, ctype c,dtype d)                      \
+{                                               \
+        register int res;                       \
+        __asm__ __volatile__(                   \
+            "movi  L11, -1\n\t"   				\
+            "movi  L10, %0\n\t"                 \
+            "mov   L9,  %1\n\t"                 \
+            "mov   L8,  %2\n\t"                 \
+            "mov   L7,  %3\n\t"                 \
+            "mov   L6,  %4\n\t"                 \
+        :/* no output*/                         \
+        :"i"(__NR_##name),                      \
+         "l"(a),                                \
+         "l"(b),                                \
+         "l"(c),                                \
+         "l"(d)                                 \
+        :"cc","memory","L6","L7","L8","L9","L10","L11");\
+        __asm__ __volatile__(                   \
+            "trap     47\n\t"                   \
+            "mov %0, L11\n\t"                   \
+        :"=l"(res)                              \
+        :/* no input */                         \
+        :"memory","L11");                       \
+        return (type)(res);                     \
+}
+
+#define _syscall5(type, name,atype, a, btype, b, ctype, c, dtype, d, etype, e)  \
+type name(atype a, btype b, ctype c,dtype d, etype e)                      \
+{                                                       \
+        register int res;                               \
+        __asm__ __volatile__(                           \
+            	"movi  L13, -1\n\t"   				\
+                "movi  L12, %0\n\t"                     \
+                "mov   L11, %1\n\t"                     \
+                "mov   L10, %2\n\t"                     \
+                "mov   L9,  %3\n\t"                     \
+                "mov   L8,  %4\n\t"                     \
+                "mov   L7,  %5\n\t"                     \
+        :/* no output*/                                 \
+        :"i"(__NR_##name),                              \
+         "l"(a),                                        \
+         "l"(b),                                        \
+         "l"(c),                                        \
+         "l"(d),                                        \
+         "l"(e)                                         \
+        :"cc","memory","L7","L8","L9","L10","L11","L12","L13");\
+        __asm__ __volatile__(                           \
+            "trap    47\n\t"                            \
+            "mov %0, L13\n\t"                           \
+        :"=l"(res)                                      \
+        :/* no input */                                 \
+        :"memory","L13");                               \
+        return (type)(res);                             \
+}
+
+#define _syscall6(type, name,atype, a, btype, b, ctype, c, dtype, d, etype, e, ftype, f)  \
+type name(atype a, btype b, ctype c,dtype d, etype e, ftype f)                      \
+{                                                               \
+        register int res;                                       \
+        __asm__ __volatile__(                                   \
+            	"movi  L15, -1\n\t"   				\
+                "movi  L14, %0\n\t"                             \
+                "mov   L13, %1\n\t"                             \
+                "mov   L12, %2\n\t"                             \
+                "mov   L11, %3\n\t"                             \
+                "mov   L10, %4\n\t"                             \
+                "mov   L9,  %5\n\t"                             \
+                "mov   L8,  %6\n\t"                             \
+        :/* no output*/                                         \
+        :"i"(__NR_##name),                                      \
+         "l"(a),                                                \
+         "l"(b),                                                \
+         "l"(c),                                                \
+         "l"(d),                                                \
+         "l"(e),                                                \
+         "l"(f)                                                 \
+        :"cc","memory","L8","L9","L10","L11","L12","L13","L14","L15");\
+        __asm__ __volatile__(                                   \
+            "trap    47\n\t"                                    \
+            "mov %0, L15\n\t"                                   \
+        :"=l"(res)                                              \
+        :/* no input */                                         \
+        :"memory","L15");                                       \
+        return (type)(res);                                     \
+}
+#endif
+
+/* The following macros have been provided by C.Baumhof
+ * They can be inlined in contrast to the previous ones*/
+#define _syscall0(type, name)  \
+type name(void)              \
+{                                               \
+	register int par1 __asm__("L15");   \
+	register int par2 __asm__("L14");   \
+    par1 = -1;              \
+	par2 = __NR_##name;         \
+	__asm__ __volatile__(                   \
+		"trap    47"                        \
+		:"=l"(par1)                             \
+		:"0"(par1), "l"(par2)  \
+		:"memory","L14","L15");   \
+	return (type)(par1);                    \
+}
+
+#define _syscall1(type, name,atype, a)  \
+type name(atype a)              \
+{                                               \
+	register int par1 __asm__("L15");   \
+	register int par2 __asm__("L14");   \
+	register int par3 __asm__("L13");   \
+    par1 = -1;              \
+	par2 = __NR_##name;         \
+	par3 = (int)a;              \
+	__asm__ __volatile__(                   \
+		"trap    47"                        \
+		:"=l"(par1)                             \
+		:"0"(par1), "l"(par2), "l"(par3)  \
+		:"memory","L13","L14","L15");   \
+	return (type)(par1);                    \
+}
+
+#define _syscall2(type, name,atype, a, btype, b)  \
+type name(atype a, btype b)              \
+{                                               \
+	register int par1 __asm__("L15");   \
+	register int par2 __asm__("L14");   \
+	register int par3 __asm__("L13");   \
+	register int par4 __asm__("L12");   \
+    par1 = -1;              \
+	par2 = __NR_##name;         \
+	par3 = (int)a;              \
+	par4 = (int)b;              \
+	__asm__ __volatile__(                   \
+		"trap    47"                        \
+		:"=l"(par1)                             \
+		:"0"(par1), "l"(par2), "l"(par3), "l"(par4) \
+		:"memory","L12","L13","L14","L15");   \
+	return (type)(par1);                    \
+}
+
+#define _syscall3(type, name,atype, a, btype, b, ctype, c)  \
+type name(atype a, btype b, ctype c)                      \
+{                                               \
+	register int par1 __asm__("L15");   \
+	register int par2 __asm__("L14");   \
+	register int par3 __asm__("L13");   \
+	register int par4 __asm__("L12");   \
+	register int par5 __asm__("L11");   \
+    par1 = -1;              \
+	par2 = __NR_##name;         \
+	par3 = (int)a;              \
+	par4 = (int)b;              \
+	par5 = (int)c;              \
+	__asm__ __volatile__(                   \
+		"trap    47"                        \
+		:"=l"(par1)                             \
+		:"0"(par1), "l"(par2), "l"(par3), "l"(par4), "l"(par5) \
+		:"memory","L11","L12","L13","L14","L15");    \
+	return (type)(par1);                    \
+}
+
+#define _syscall4(type, name,atype, a, btype, b, ctype, c, dtype, d)  \
+type name(atype a, btype b, ctype c,dtype d)                      \
+{                                               \
+	register int par1 __asm__("L15");   \
+	register int par2 __asm__("L14");   \
+	register int par3 __asm__("L13");   \
+	register int par4 __asm__("L12");   \
+	register int par5 __asm__("L11");   \
+	register int par6 __asm__("L10");   \
+    par1 = -1;              \
+	par2 = __NR_##name;         \
+	par3 = (int)a;              \
+	par4 = (int)b;              \
+	par5 = (int)c;              \
+	par6 = (int)d;              \
+	__asm__ __volatile__(                   \
+		"trap    47"                        \
+		:"=l"(par1)                             \
+		:"0"(par1),"l"(par2),"l"(par3),"l"(par4),"l"(par5),"l"(par6) \
+		:"memory","L10","L11","L12","L13","L14","L15");    \
+	return (type)(par1);                    \
+}
+
+#define _syscall5(type, name,atype, a, btype, b, ctype, c, dtype, d, etype, e)  \
+type name(atype a, btype b, ctype c,dtype d, etype e)                      \
+{                                                       \
+	register int par1 __asm__("L15");   \
+	register int par2 __asm__("L14");   \
+	register int par3 __asm__("L13");   \
+	register int par4 __asm__("L12");   \
+	register int par5 __asm__("L11");   \
+	register int par6 __asm__("L10");   \
+	register int par7 __asm__("L9");   \
+    par1 = -1;              	\
+	par2 = __NR_##name;         \
+	par3 = (int)a;              \
+	par4 = (int)b;              \
+	par5 = (int)c;              \
+	par6 = (int)d;              \
+	par7 = (int)e;              \
+	__asm__ __volatile__(                   \
+		"trap    47"                        \
+		:"=l"(par1)                             \
+		:"0"(par1),"l"(par2),"l"(par3),"l"(par4),"l"(par5),"l"(par6),"l"(par7) \
+		:"memory","L9","L10","L11","L12","L13","L14","L15");    \
+	return (type)(par1);                    \
+}
+
+#define _syscall6(type, name,atype, a, btype, b, ctype, c, dtype, d, etype, e, ftype, f)  \
+type name(atype a, btype b, ctype c,dtype d, etype e, ftype f)                      \
+{                                                               \
+	register int par1 __asm__("L15");   \
+	register int par2 __asm__("L14");   \
+	register int par3 __asm__("L13");   \
+	register int par4 __asm__("L12");   \
+	register int par5 __asm__("L11");   \
+	register int par6 __asm__("L10");   \
+	register int par7 __asm__("L9");   \
+	register int par8 __asm__("L8");   \
+    par1 = -1;              	\
+	par2 = __NR_##name;         \
+	par3 = (int)a;              \
+	par4 = (int)b;              \
+	par5 = (int)c;              \
+	par6 = (int)d;              \
+	par7 = (int)e;              \
+	par7 = (int)f;              \
+	__asm__ __volatile__(                   \
+		"trap    47"                        \
+		:"=l"(par1)                             \
+		:"0"(par1),"l"(par2),"l"(par3),"l"(par4),"l"(par5),"l"(par6),"l"(par7),"l"(par8) \
+		:"memory","L8","L9","L10","L11","L12","L13","L14","L15");    \
+	return (type)(par1);                    \
+}
+
+#ifdef __KERNEL__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+/* Yannis: FIXME We should make the followings inline !!! 
+ * When they are inline the compiler gets comfused and the frame 
+ * length is wrong. This is due to the fact that the function is 
+ * quite large ...!!!
+ */
+static inline _syscall0(int,pause)
+static inline _syscall0(int,sync)
+static inline _syscall0(pid_t,setsid)
+static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+static inline _syscall1(int,dup,int,fd)
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+static inline _syscall1(int,close,int,fd)
+static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,delete_module,const char *,name)
+static inline _syscall0(int, sigreturn )
+static inline _syscall2(int, kill, int, pid, int, sig)
+
+/* We estimate a FL of 6 in <copy_thread> for clone.
+ * Don't inline clone because its FL will take an arbitrary value */
+static /*inline*/ _syscall1(int,clone,unsigned long,clone_flags)
+
+/*
+static inline pid_t waitpid(int pid, int * wait_stat, int flags)
+{
+        return sys_wait4(pid, wait_stat, flags, NULL);
+}
+*/
+
+static inline pid_t wait(int * wait_stat)
+{
+        return waitpid(-1,wait_stat,0);
+}
+
+#endif
+
+#endif /* !_HYPERSTONE_NOMMU_UNISTD_H_ */
diff -urN linux-2.4.29/include/asm-e1nommu/user.h linux-2.4.29-uc1/include/asm-e1nommu/user.h
--- linux-2.4.29/include/asm-e1nommu/user.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/user.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef _HYPERSTONE_NOMMU_USER_H
+#define _HYPERSTONE_NOMMU_USER_H
+
+#include <asm/page.h>
+#include <asm/ptrace.h>
+
+struct user_regs_struct {
+};
+
+#define NBPG PAGE_SIZE
+
+#endif
diff -urN linux-2.4.29/include/asm-e1nommu/virtconvert.h linux-2.4.29-uc1/include/asm-e1nommu/virtconvert.h
--- linux-2.4.29/include/asm-e1nommu/virtconvert.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-e1nommu/virtconvert.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,24 @@
+#ifndef __HYPERSTONE_VIRT_CONVERT__
+#define __HYPERSTONE_VIRT_CONVERT__
+
+/*
+ * Macros used for converting between virtual and physical mappings.
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+
+#define mm_ptov(vaddr)		((void *) (vaddr))
+#define mm_vtop(vaddr)		((unsigned long) (vaddr))
+#define phys_to_virt(vaddr)	((void *) (vaddr))
+#define virt_to_phys(vaddr)	((unsigned long) (vaddr))
+
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+#endif /* !__KERNEL__ */
+
+#endif
diff -urN linux-2.4.29/include/asm-frv/a.out.h linux-2.4.29-uc1/include/asm-frv/a.out.h
--- linux-2.4.29/include/asm-frv/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/a.out.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,23 @@
+#ifndef __ASM_A_OUT_H__
+#define __ASM_A_OUT_H__
+
+#include <asm/mem-layout.h>
+
+struct exec
+{
+	unsigned long a_info;		/* Use macros N_MAGIC, etc for access */
+	unsigned a_text;		/* length of text, in bytes */
+	unsigned a_data;		/* length of data, in bytes */
+	unsigned a_bss;			/* length of uninitialized data area for file, in bytes */
+	unsigned a_syms;		/* length of symbol table data in file, in bytes */
+	unsigned a_entry;		/* start address */
+	unsigned a_trsize;		/* length of relocation info for text, in bytes */
+	unsigned a_drsize;		/* length of relocation info for data, in bytes */
+};
+
+#define N_TRSIZE(a)	((a).a_trsize)
+#define N_DRSIZE(a)	((a).a_drsize)
+#define N_SYMSIZE(a)	((a).a_syms)
+
+#endif /* __ASM_A_OUT_H__ */
+
diff -urN linux-2.4.29/include/asm-frv/atomic.h linux-2.4.29-uc1/include/asm-frv/atomic.h
--- linux-2.4.29/include/asm-frv/atomic.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/atomic.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,417 @@
+/* atomic.h: atomic operation emulation for FR-V
+ *
+ * For an explanation of how atomic ops work in this arch, see:
+ *   Documentation/fujitsu/frv/atomic-ops.txt
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_ATOMIC_H
+#define _ASM_ATOMIC_H
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/spr-regs.h>
+
+#ifdef CONFIG_SMP
+#error not SMP safe
+#endif
+
+/*
+ * Atomic operations that C can't guarantee us.  Useful for
+ * resource counting etc..
+ *
+ * We do not have SMP systems, so we don't have to deal with that.
+ */
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec()	barrier()
+#define smp_mb__after_atomic_dec()	barrier()
+#define smp_mb__before_atomic_inc()	barrier()
+#define smp_mb__after_atomic_inc()	barrier()
+
+typedef struct {
+	int counter;
+} atomic_t;
+
+#define ATOMIC_INIT(i)		{ (i) }
+#define atomic_read(v)		((v)->counter)
+#define atomic_set(v, i)	(((v)->counter) = (i))
+
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+	unsigned long val;
+
+	asm("0:						\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	ckeq		icc3,cc7		\n"
+	    "	ld.p		%M0,%1			\n"	/* LD.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "	add%I2		%1,%2,%1		\n"
+	    "	cst.p		%1,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    : "+U"(v->counter), "=&r"(val)
+	    : "NPr"(i)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	return val;
+}
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+	unsigned long val;
+
+	asm("0:						\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	ckeq		icc3,cc7		\n"
+	    "	ld.p		%M0,%1			\n"	/* LD.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "	sub%I2		%1,%2,%1		\n"
+	    "	cst.p		%1,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    : "+U"(v->counter), "=&r"(val)
+	    : "NPr"(i)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	return val;
+}
+
+#else
+
+extern int atomic_add_return(int i, atomic_t *v);
+extern int atomic_sub_return(int i, atomic_t *v);
+
+#endif
+
+static inline int atomic_add_negative(int i, atomic_t *v)
+{
+	return atomic_add_return(i, v) < 0;
+}
+
+static inline void atomic_add(int i, atomic_t *v)
+{
+	atomic_add_return(i, v);
+}
+
+static inline void atomic_sub(int i, atomic_t *v)
+{
+	atomic_sub_return(i, v);
+}
+
+static inline void atomic_inc(atomic_t *v)
+{
+	atomic_add_return(1, v);
+}
+
+static inline void atomic_dec(atomic_t *v)
+{
+	atomic_sub_return(1, v);
+}
+
+#define atomic_dec_return(v)		atomic_sub_return(1, (v))
+#define atomic_inc_return(v)		atomic_add_return(1, (v))
+
+#define atomic_sub_and_test(i,v)	(atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v)		(atomic_sub_return(1, (v)) == 0)
+#define atomic_inc_and_test(v)		(atomic_add_return(1, (v)) == 0)
+
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+static inline
+unsigned long atomic_test_and_ANDNOT_mask(unsigned long mask, volatile unsigned long *v)
+{
+	unsigned long old, tmp;
+
+	asm volatile(
+		"0:						\n"
+		"	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+		"	ckeq		icc3,cc7		\n"
+		"	ld.p		%M0,%1			\n"	/* LD.P/ORCR are atomic */
+		"	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+		"	and%I3		%1,%3,%2		\n"
+		"	cst.p		%2,%M0		,cc3,#1	\n"	/* if store happens... */
+		"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* ... clear ICC3.Z */
+		"	beq		icc3,#0,0b		\n"
+		: "+U"(*v), "=&r"(old), "=r"(tmp)
+		: "NPr"(~mask)
+		: "memory", "cc7", "cc3", "icc3"
+		);
+
+	return old;
+}
+
+static inline
+unsigned long atomic_test_and_OR_mask(unsigned long mask, volatile unsigned long *v)
+{
+	unsigned long old, tmp;
+
+	asm volatile(
+		"0:						\n"
+		"	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+		"	ckeq		icc3,cc7		\n"
+		"	ld.p		%M0,%1			\n"	/* LD.P/ORCR are atomic */
+		"	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+		"	or%I3		%1,%3,%2		\n"
+		"	cst.p		%2,%M0		,cc3,#1	\n"	/* if store happens... */
+		"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* ... clear ICC3.Z */
+		"	beq		icc3,#0,0b		\n"
+		: "+U"(*v), "=&r"(old), "=r"(tmp)
+		: "NPr"(mask)
+		: "memory", "cc7", "cc3", "icc3"
+		);
+
+	return old;
+}
+
+static inline
+unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsigned long *v)
+{
+	unsigned long old, tmp;
+
+	asm volatile(
+		"0:						\n"
+		"	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+		"	ckeq		icc3,cc7		\n"
+		"	ld.p		%M0,%1			\n"	/* LD.P/ORCR are atomic */
+		"	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+		"	xor%I3		%1,%3,%2		\n"
+		"	cst.p		%2,%M0		,cc3,#1	\n"	/* if store happens... */
+		"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* ... clear ICC3.Z */
+		"	beq		icc3,#0,0b		\n"
+		: "+U"(*v), "=&r"(old), "=r"(tmp)
+		: "NPr"(mask)
+		: "memory", "cc7", "cc3", "icc3"
+		);
+
+	return old;
+}
+
+#else
+
+extern unsigned long atomic_test_and_ANDNOT_mask(unsigned long mask, volatile unsigned long *v);
+extern unsigned long atomic_test_and_OR_mask(unsigned long mask, volatile unsigned long *v);
+extern unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsigned long *v);
+
+#endif
+
+#define atomic_clear_mask(mask, v)	atomic_test_and_ANDNOT_mask((mask), (v))
+#define atomic_set_mask(mask, v)	atomic_test_and_OR_mask((mask), (v))
+
+/*****************************************************************************/
+/*
+ * exchange value with memory
+ */
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+
+#define xchg(ptr, x)								\
+({										\
+	__typeof__(ptr) __xg_ptr = (ptr);					\
+	__typeof__(*(ptr)) __xg_orig;						\
+										\
+	switch (sizeof(__xg_orig)) {						\
+	case 1:									\
+		asm volatile(							\
+			"0:						\n"	\
+			"	orcc		gr0,gr0,gr0,icc3	\n"	\
+			"	ckeq		icc3,cc7		\n"	\
+			"	ldub.p		%M0,%1			\n"	\
+			"	orcr		cc7,cc7,cc3		\n"	\
+			"	cstb.p		%2,%M0		,cc3,#1	\n"	\
+			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
+			"	beq		icc3,#0,0b		\n"	\
+			: "+U"(*__xg_ptr), "=&r"(__xg_orig)			\
+			: "r"(x)						\
+			: "memory", "cc7", "cc3", "icc3"			\
+			);							\
+		break;								\
+										\
+	case 2:									\
+		asm volatile(							\
+			"0:						\n"	\
+			"	orcc		gr0,gr0,gr0,icc3	\n"	\
+			"	ckeq		icc3,cc7		\n"	\
+			"	lduh.p		%M0,%1			\n"	\
+			"	orcr		cc7,cc7,cc3		\n"	\
+			"	csth.p		%2,%M0		,cc3,#1	\n"	\
+			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
+			"	beq		icc3,#0,0b		\n"	\
+			: "+U"(*__xg_ptr), "=&r"(__xg_orig)			\
+			: "r"(x)						\
+			: "memory", "cc7", "cc3", "icc3"			\
+			);							\
+		break;								\
+										\
+	case 4:									\
+		asm volatile(							\
+			"0:						\n"	\
+			"	orcc		gr0,gr0,gr0,icc3	\n"	\
+			"	ckeq		icc3,cc7		\n"	\
+			"	ld.p		%M0,%1			\n"	\
+			"	orcr		cc7,cc7,cc3		\n"	\
+			"	cst.p		%2,%M0		,cc3,#1	\n"	\
+			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
+			"	beq		icc3,#0,0b		\n"	\
+			: "+U"(*__xg_ptr), "=&r"(__xg_orig)			\
+			: "r"(x)						\
+			: "memory", "cc7", "cc3", "icc3"			\
+			);							\
+		break;								\
+										\
+	default:								\
+		__xg_orig = 0;							\
+		asm volatile("break");						\
+		break;								\
+	}									\
+										\
+	__xg_orig;								\
+})
+
+#else
+
+extern uint8_t  __xchg_8 (uint8_t i,  volatile void *v);
+extern uint16_t __xchg_16(uint16_t i, volatile void *v);
+extern uint32_t __xchg_32(uint32_t i, volatile void *v);
+
+#define xchg(ptr, x)										\
+({												\
+	__typeof__(ptr) __xg_ptr = (ptr);							\
+	__typeof__(*(ptr)) __xg_orig;								\
+												\
+	switch (sizeof(__xg_orig)) {								\
+	case 1: __xg_orig = (__typeof__(*(ptr))) __xchg_8 ((uint8_t)  x, __xg_ptr);	break;	\
+	case 2: __xg_orig = (__typeof__(*(ptr))) __xchg_16((uint16_t) x, __xg_ptr);	break;	\
+	case 4: __xg_orig = (__typeof__(*(ptr))) __xchg_32((uint32_t) x, __xg_ptr);	break;	\
+	default:										\
+		__xg_orig = 0;									\
+		asm volatile("break");								\
+		break;										\
+	}											\
+	__xg_orig;										\
+})
+
+#endif
+
+#define tas(ptr) (xchg((ptr), 1))
+
+/*****************************************************************************/
+/*
+ * compare and conditionally exchange value with memory
+ * - if (*ptr == test) then orig = *ptr; *ptr = test;
+ * - if (*ptr != test) then orig = *ptr;
+ */
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+
+#define cmpxchg(ptr, test, new)							\
+({										\
+	__typeof__(ptr) __xg_ptr = (ptr);					\
+	__typeof__(*(ptr)) __xg_orig, __xg_tmp;					\
+	__typeof__(*(ptr)) __xg_test = (test);					\
+	__typeof__(*(ptr)) __xg_new = (new);					\
+										\
+	switch (sizeof(__xg_orig)) {						\
+	case 1:									\
+		asm volatile(							\
+			"0:						\n"	\
+			"	orcc		gr0,gr0,gr0,icc3	\n"	\
+			"	ckeq		icc3,cc7		\n"	\
+			"	ldub.p		%M0,%1			\n"	\
+			"	orcr		cc7,cc7,cc3		\n"	\
+			"	sub%I4		%1,%4,%2		\n"	\
+			"	sllcc		%2,#24,gr0,icc0		\n"	\
+			"	bne		icc0,#0,1f		\n"	\
+			"	cstb.p		%3,%M0		,cc3,#1	\n"	\
+			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
+			"	beq		icc3,#0,0b		\n"	\
+			"1:						\n"	\
+			: "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp)	\
+			: "r"(__xg_new), "NPr"(__xg_test)			\
+			: "memory", "cc7", "cc3", "icc3", "icc0"		\
+			);							\
+		break;								\
+										\
+	case 2:									\
+		asm volatile(							\
+			"0:						\n"	\
+			"	orcc		gr0,gr0,gr0,icc3	\n"	\
+			"	ckeq		icc3,cc7		\n"	\
+			"	lduh.p		%M0,%1			\n"	\
+			"	orcr		cc7,cc7,cc3		\n"	\
+			"	sub%I4		%1,%4,%2		\n"	\
+			"	sllcc		%2,#16,gr0,icc0		\n"	\
+			"	bne		icc0,#0,1f		\n"	\
+			"	csth.p		%3,%M0		,cc3,#1	\n"	\
+			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
+			"	beq		icc3,#0,0b		\n"	\
+			"1:						\n"	\
+			: "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp)	\
+			: "r"(__xg_new), "NPr"(__xg_test)			\
+			: "memory", "cc7", "cc3", "icc3", "icc0"		\
+			);							\
+		break;								\
+										\
+	case 4:									\
+		asm volatile(							\
+			"0:						\n"	\
+			"	orcc		gr0,gr0,gr0,icc3	\n"	\
+			"	ckeq		icc3,cc7		\n"	\
+			"	ld.p		%M0,%1			\n"	\
+			"	orcr		cc7,cc7,cc3		\n"	\
+			"	sub%I4cc	%1,%4,%2,icc0		\n"	\
+			"	bne		icc0,#0,1f		\n"	\
+			"	cst.p		%3,%M0		,cc3,#1	\n"	\
+			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
+			"	beq		icc3,#0,0b		\n"	\
+			"1:						\n"	\
+			: "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp)	\
+			: "r"(__xg_new), "NPr"(__xg_test)			\
+			: "memory", "cc7", "cc3", "icc3", "icc0"		\
+			);							\
+		break;								\
+										\
+	default:								\
+		__xg_orig = 0;							\
+		asm volatile("break");						\
+		break;								\
+	}									\
+										\
+	__xg_orig;								\
+})
+
+#else
+
+extern uint8_t  __cmpxchg_8 (uint8_t *v,  uint8_t test,  uint8_t new);
+extern uint16_t __cmpxchg_16(uint16_t *v, uint16_t test, uint16_t new);
+extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new);
+
+#define cmpxchg(ptr, test, new)							\
+({										\
+	__typeof__(ptr) __xg_ptr = (ptr);					\
+	__typeof__(*(ptr)) __xg_orig;						\
+	__typeof__(*(ptr)) __xg_test = (test);					\
+	__typeof__(*(ptr)) __xg_new = (new);					\
+										\
+	switch (sizeof(__xg_orig)) {						\
+	case 1: __xg_orig = __cmpxchg_8 (__xg_ptr, __xg_test, __xg_new); break;	\
+	case 2: __xg_orig = __cmpxchg_16(__xg_ptr, __xg_test, __xg_new); break;	\
+	case 4: __xg_orig = __cmpxchg_32(__xg_ptr, __xg_test, __xg_new); break;	\
+	default:								\
+		__xg_orig = 0;							\
+		asm volatile("break");						\
+		break;								\
+	}									\
+										\
+	__xg_orig;								\
+})
+
+#endif
+
+#endif /* _ASM_ATOMIC_H */
diff -urN linux-2.4.29/include/asm-frv/ax88796.h linux-2.4.29-uc1/include/asm-frv/ax88796.h
--- linux-2.4.29/include/asm-frv/ax88796.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/ax88796.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,22 @@
+/* ax88796.h: access points to the driver for the AX88796 NE2000 clone
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_AX88796_H
+#define _ASM_AX88796_H
+
+#include <asm/mb-regs.h>
+
+#define AX88796_IOADDR		(__region_CS1 + 0x200)
+#define AX88796_IRQ		IRQ_CPU_EXTERNAL7
+#define AX88796_FULL_DUPLEX	0			/* force full duplex */
+#define AX88796_BUS_INFO	"CS1#+0x200"		/* bus info for ethtool */
+
+#endif /* _ASM_AX88796_H */
diff -urN linux-2.4.29/include/asm-frv/bitops.h linux-2.4.29-uc1/include/asm-frv/bitops.h
--- linux-2.4.29/include/asm-frv/bitops.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/bitops.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,403 @@
+/* bitops.h: bit operations for the Fujitsu FR-V CPUs
+ *
+ * For an explanation of how atomic ops work in this arch, see:
+ *   Documentation/fujitsu/frv/atomic-ops.txt
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_BITOPS_H
+#define _ASM_BITOPS_H
+
+#include <linux/config.h>
+#include <linux/compiler.h>
+#include <asm/byteorder.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
+
+#ifdef __KERNEL__
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+static inline unsigned long ffz(unsigned long word)
+{
+	unsigned long result = 0;
+
+	while (word & 1) {
+		result++;
+		word >>= 1;
+	}
+	return result;
+}
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+
+static inline int test_and_clear_bit(int nr, volatile void *addr)
+{
+	volatile unsigned long *ptr = addr;
+	unsigned long mask = 1UL << (nr & 31);
+	ptr += nr >> 5;
+	return (atomic_test_and_ANDNOT_mask(mask, ptr) & mask) != 0;
+}
+
+static inline int test_and_set_bit(int nr, volatile void *addr)
+{
+	volatile unsigned long *ptr = addr;
+	unsigned long mask = 1UL << (nr & 31);
+	ptr += nr >> 5;
+	return (atomic_test_and_OR_mask(mask, ptr) & mask) != 0;
+}
+
+static inline int test_and_change_bit(int nr, volatile void *addr)
+{
+	volatile unsigned long *ptr = addr;
+	unsigned long mask = 1UL << (nr & 31);
+	ptr += nr >> 5;
+	return (atomic_test_and_XOR_mask(mask, ptr) & mask) != 0;
+}
+
+static inline void clear_bit(int nr, volatile void *addr)
+{
+	test_and_clear_bit(nr, addr);
+}
+
+static inline void set_bit(int nr, volatile void *addr)
+{
+	test_and_set_bit(nr, addr);
+}
+
+static inline void change_bit(int nr, volatile void * addr)
+{
+	test_and_change_bit(nr, addr);
+}
+
+static inline void __clear_bit(int nr, volatile void * addr)
+{
+	volatile unsigned long *a = addr;
+	int mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	*a &= ~mask;
+}
+
+static inline void __set_bit(int nr, volatile void * addr)
+{
+	volatile unsigned long *a = addr;
+	int mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	*a |= mask;
+}
+
+static inline void __change_bit(int nr, volatile void *addr)
+{
+	volatile unsigned long *a = addr;
+	int mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	*a ^= mask;
+}
+
+static inline int __test_and_clear_bit(int nr, volatile void * addr)
+{
+	volatile unsigned long *a = addr;
+	int mask, retval;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+	return retval;
+}
+
+static inline int __test_and_set_bit(int nr, volatile void * addr)
+{
+	volatile unsigned long *a = addr;
+	int mask, retval;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+	return retval;
+}
+
+static inline int __test_and_change_bit(int nr, volatile void * addr)
+{
+	volatile unsigned long *a = addr;
+	int mask, retval;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	return retval;
+}
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+static inline int __constant_test_bit(int nr, const volatile void * addr)
+{
+	return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
+}
+
+static inline int __test_bit(int nr, const volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	return ((mask & *a) != 0);
+}
+
+#define test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ __constant_test_bit((nr),(addr)) : \
+ __test_bit((nr),(addr)))
+
+extern int find_next_bit(const unsigned long *addr, int size, int offset);
+
+#define find_first_bit(addr, size) find_next_bit(addr, size, 0)
+
+#define find_first_zero_bit(addr, size) \
+        find_next_zero_bit((addr), (size), 0)
+
+static inline int find_next_zero_bit(const void *addr, int size, int offset)
+{
+	const unsigned long *p = ((const unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if (offset) {
+		tmp = *(p++);
+		tmp |= ~0UL >> (32-offset);
+		if (size < 32)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while (size & ~31UL) {
+		if (~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp |= ~0UL >> size;
+found_middle:
+	return result + ffz(tmp);
+}
+
+static inline int ffs(int x)
+{
+	int r = 1;
+
+	if (!x)
+		return 0;
+	if (!(x & 0xffff)) {
+		x >>= 16;
+		r += 16;
+	}
+	if (!(x & 0xff)) {
+		x >>= 8;
+		r += 8;
+	}
+	if (!(x & 0xf)) {
+		x >>= 4;
+		r += 4;
+	}
+	if (!(x & 3)) {
+		x >>= 2;
+		r += 2;
+	}
+	if (!(x & 1)) {
+		x >>= 1;
+		r += 1;
+	}
+	return r;
+}
+
+#define __ffs(x) (ffs(x)-1)
+
+/*
+ * Every architecture must define this function. It's the fastest
+ * way of searching a 140-bit bitmap where the first 100 bits are
+ * unlikely to be set. It's guaranteed that at least one of the 140
+ * bits is cleared.
+ */
+static inline int sched_find_first_bit(unsigned long *b)
+{
+	if (unlikely(b[0]))
+		return __ffs(b[0]);
+	if (unlikely(b[1]))
+		return __ffs(b[1]) + 32;
+	if (unlikely(b[2]))
+		return __ffs(b[2]) + 64;
+	if (b[3])
+		return __ffs(b[3]) + 96;
+	return __ffs(b[4]) + 128;
+}
+
+#define fls(x) generic_fls(x)
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+static inline int ext2_set_bit(int nr, volatile void * addr)
+{
+	unsigned long old, tmp, mask;
+	volatile unsigned char *ptr = addr;
+	ptr += nr >> 3;
+
+	asm("0:						\n"
+	    "	setlos.p	#1,%3			\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	sll%I4.p	%3,%4,%3		\n"
+	    "	ckeq		icc3,cc7		\n"
+	    "	ldub.p		%M0,%1			\n"	/* LDUB.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "	or		%1,%3,%2		\n"
+	    "	cstb.p		%2,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    : "+U"(*ptr), "=&r"(old), "=r"(tmp), "=&r"(mask)
+	    : "Ir"(nr & 7)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	return old & mask;
+}
+
+static inline int ext2_clear_bit(int nr, volatile void * addr)
+{
+	unsigned long old, tmp, mask;
+	volatile unsigned char *ptr = addr;
+	ptr += nr >> 3;
+
+	asm("0:						\n"
+	    "	setlos.p	#1,%3			\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	sll%I4.p	%3,%4,%3		\n"
+	    "	ckeq		icc3,cc7		\n"
+	    "	ldub.p		%M0,%1			\n"	/* LDUB.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "	not		%3,%2			\n"
+	    "	and		%1,%2,%2		\n"
+	    "	cstb.p		%2,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    : "+U"(*ptr), "=&r"(old), "=r"(tmp), "=&r"(mask)
+	    : "Ir"(nr & 7)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	return old & mask;
+}
+
+static inline int ext2_test_bit(int nr, const volatile void * addr)
+{
+	int			mask;
+	const volatile unsigned char	*ADDR = (const unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	return ((mask & *ADDR) != 0);
+}
+
+#define ext2_find_first_zero_bit(addr, size) \
+        ext2_find_next_zero_bit((addr), (size), 0)
+
+static inline unsigned long ext2_find_next_zero_bit(const void *addr,
+						    unsigned long size,
+						    unsigned long offset)
+{
+	const unsigned long *p = ((const unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if(offset) {
+		/* We hold the little endian value in tmp, but then the
+		 * shift is illegal. So we could keep a big endian value
+		 * in tmp, like this:
+		 *
+		 * tmp = __swab32(*(p++));
+		 * tmp |= ~0UL >> (32-offset);
+		 *
+		 * but this would decrease preformance, so we change the
+		 * shift:
+		 */
+		tmp = *(p++);
+		tmp |= __swab32(~0UL >> (32-offset));
+		if(size < 32)
+			goto found_first;
+		if(~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while(size & ~31UL) {
+		if(~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if(!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	/* tmp is little endian, so we would have to swab the shift,
+	 * see above. But then we have to swab tmp below for ffz, so
+	 * we might as well do this here.
+	 */
+	return result + ffz(__swab32(tmp) | (~0UL << size));
+found_middle:
+	return result + ffz(__swab32(tmp));
+}
+
+/* Bitmap functions for the minix filesystem.  */
+#define minix_test_and_set_bit(nr,addr) ext2_set_bit(nr,addr)
+#define minix_set_bit(nr,addr) ext2_set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr) ext2_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) ext2_test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) ext2_find_first_zero_bit(addr,size)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_BITOPS_H */
diff -urN linux-2.4.29/include/asm-frv/bootinfo.h linux-2.4.29-uc1/include/asm-frv/bootinfo.h
--- linux-2.4.29/include/asm-frv/bootinfo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/bootinfo.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,2 @@
+
+/* Nothing for m68knommu */
diff -urN linux-2.4.29/include/asm-frv/bugs.h linux-2.4.29-uc1/include/asm-frv/bugs.h
--- linux-2.4.29/include/asm-frv/bugs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/bugs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,14 @@
+/* bugs.h: arch bug checking entry
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+static inline void check_bugs(void)
+{
+}
diff -urN linux-2.4.29/include/asm-frv/busctl-regs.h linux-2.4.29-uc1/include/asm-frv/busctl-regs.h
--- linux-2.4.29/include/asm-frv/busctl-regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/busctl-regs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,41 @@
+/* busctl-regs.h: FR400-series CPU bus controller registers
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_BUSCTL_REGS_H
+#define _ASM_BUSCTL_REGS_H
+
+/* bus controller registers */
+#define __get_LGCR()	({ *(volatile unsigned long *)(0xfe000010); })
+#define __get_LMAICR()	({ *(volatile unsigned long *)(0xfe000030); })
+#define __get_LEMBR()	({ *(volatile unsigned long *)(0xfe000040); })
+#define __get_LEMAM()	({ *(volatile unsigned long *)(0xfe000048); })
+#define __get_LCR(R)	({ *(volatile unsigned long *)(0xfe000100 + 8*(R)); })
+#define __get_LSBR(R)	({ *(volatile unsigned long *)(0xfe000c00 + 8*(R)); })
+#define __get_LSAM(R)	({ *(volatile unsigned long *)(0xfe000d00 + 8*(R)); })
+
+#define __set_LGCR(V)	do { *(volatile unsigned long *)(0xfe000010) = (V); } while(0)
+#define __set_LMAICR(V)	do { *(volatile unsigned long *)(0xfe000030) = (V); } while(0)
+#define __set_LEMBR(V)	do { *(volatile unsigned long *)(0xfe000040) = (V); } while(0)
+#define __set_LEMAM(V)	do { *(volatile unsigned long *)(0xfe000048) = (V); } while(0)
+#define __set_LCR(R,V)	do { *(volatile unsigned long *)(0xfe000100 + 8*(R)) = (V); } while(0)
+#define __set_LSBR(R,V)	do { *(volatile unsigned long *)(0xfe000c00 + 8*(R)) = (V); } while(0)
+#define __set_LSAM(R,V)	do { *(volatile unsigned long *)(0xfe000d00 + 8*(R)) = (V); } while(0)
+
+/* FR401 SDRAM controller registers */
+#define __get_DBR(R)	({ *(volatile unsigned long *)(0xfe000e00 + 8*(R)); })
+#define __get_DAM(R)	({ *(volatile unsigned long *)(0xfe000f00 + 8*(R)); })
+
+/* FR551 SDRAM controller registers */
+#define __get_DARS(R)	({ *(volatile unsigned long *)(0xfeff0100 + 8*(R)); })
+#define __get_DAMK(R)	({ *(volatile unsigned long *)(0xfeff0110 + 8*(R)); })
+
+
+#endif /* _ASM_BUSCTL_REGS_H */
diff -urN linux-2.4.29/include/asm-frv/byteorder.h linux-2.4.29-uc1/include/asm-frv/byteorder.h
--- linux-2.4.29/include/asm-frv/byteorder.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/byteorder.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef _M68KNOMMU_BYTEORDER_H
+#define _M68KNOMMU_BYTEORDER_H
+
+#include <asm/types.h>
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#include <linux/byteorder/big_endian.h>
+
+#endif /* _M68KNOMMU_BYTEORDER_H */
diff -urN linux-2.4.29/include/asm-frv/cache.h linux-2.4.29-uc1/include/asm-frv/cache.h
--- linux-2.4.29/include/asm-frv/cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/cache.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,17 @@
+#ifndef __ASM_CACHE_H
+#define __ASM_CACHE_H
+
+#include <linux/config.h>
+
+/* bytes per L1 cache line */
+#ifdef CONFIG_FR55x
+#define L1_CACHE_SHIFT		6
+#else
+#define L1_CACHE_SHIFT		5
+#endif
+#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
+
+#define __cacheline_aligned	__attribute__((aligned(L1_CACHE_BYTES)))
+#define ____cacheline_aligned	__attribute__((aligned(L1_CACHE_BYTES)))
+
+#endif
diff -urN linux-2.4.29/include/asm-frv/checksum.h linux-2.4.29-uc1/include/asm-frv/checksum.h
--- linux-2.4.29/include/asm-frv/checksum.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/checksum.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,185 @@
+#ifndef _ASM_CHECKSUM_H
+#define _ASM_CHECKSUM_H
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
+
+
+/*
+ * the same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
+						int len, int sum, int *csum_err);
+
+#define csum_partial_copy_nocheck(src, dst, len, sum)	\
+	csum_partial_copy((src), (dst), (len), (sum))
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ *
+ */
+static inline unsigned short
+ip_fast_csum(unsigned char *iph, unsigned int ihl)
+{
+	unsigned int tmp, inc, sum = 0;
+
+	asm("	addcc		gr0,gr0,gr0,icc0\n" /* clear icc0.C */
+	    "	subi		%1,#4,%1	\n"
+	    "0:					\n"
+	    "	ldu.p		@(%1,%3),%4	\n"
+	    "	subicc		%2,#1,%2,icc1	\n"
+	    "	addxcc.p	%4,%0,%0,icc0	\n"
+	    "	bhi		icc1,#2,0b	\n"
+
+	    /* fold the 33-bit result into 16-bits */
+	    "	addxcc		gr0,%0,%0,icc0	\n"
+	    "	srli		%0,#16,%1	\n"
+	    "	sethi		#0,%0		\n"
+	    "	add		%1,%0,%0	\n"
+	    "	srli		%0,#16,%1	\n"
+	    "	add		%1,%0,%0	\n"
+
+	    : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (inc), "=&r"(tmp)
+	    : "0" (sum), "1" (iph), "2" (ihl), "3" (4),
+	    "m"(*(volatile struct { int _[100]; } *)iph)
+	    : "icc0", "icc1"
+	    );
+
+	return ~sum;
+}
+
+/*
+ *	Fold a partial checksum
+ */
+
+static inline unsigned int csum_fold(unsigned int sum)
+{
+	unsigned int tmp;
+
+	asm("	srli		%0,#16,%1	\n"
+	    "	sethi		#0,%0		\n"
+	    "	add		%1,%0,%0	\n"
+	    "	srli		%0,#16,%1	\n"
+	    "	add		%1,%0,%0	\n"
+	    : "=r"(sum), "=&r"(tmp)
+	    : "0"(sum)
+	    );
+
+	return ~sum;
+}
+
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+
+static inline unsigned int
+csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
+		  unsigned short proto, unsigned int sum)
+{
+	asm("	addcc		%1,%0,%0,icc0	\n"
+	    "	addxcc		%2,%0,%0,icc0	\n"
+	    "	addxcc		%3,%0,%0,icc0	\n"
+	    "	addxcc		gr0,%0,%0,icc0	\n"
+	    : "=r" (sum)
+	    : "r" (daddr), "r" (saddr), "r" (len + proto), "0"(sum)
+	    : "icc0"
+	    );
+	return sum;
+}
+
+static inline unsigned short int
+csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
+		  unsigned short proto, unsigned int sum)
+{
+	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+#if 0 /* DAVIDM - these are in arch/frvnommu/lib */
+static inline unsigned short
+ip_compute_csum(unsigned char * buff, int len)
+{
+	return csum_fold (csum_partial(buff, len, 0));
+}
+#else
+extern unsigned short ip_compute_csum(const unsigned char * buff, int len);
+#endif
+
+#define _HAVE_ARCH_IPV6_CSUM
+static inline unsigned short int
+csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr,
+		__u32 len, unsigned short proto, unsigned int sum) 
+{
+	unsigned long tmp, tmp2;
+
+	asm("	addcc		%2,%0,%0,icc0	\n"
+
+	    /* add up the source addr */
+	    "	ldi		@(%3,0),%1	\n"
+	    "	addxcc		%1,%0,%0,icc0	\n"
+	    "	ldi		@(%3,4),%2	\n"
+	    "	addxcc		%2,%0,%0,icc0	\n"
+	    "	ldi		@(%3,8),%1	\n"
+	    "	addxcc		%1,%0,%0,icc0	\n"
+	    "	ldi		@(%3,12),%2	\n"
+	    "	addxcc		%2,%0,%0,icc0	\n"
+
+	    /* add up the dest addr */
+	    "	ldi		@(%4,0),%1	\n"
+	    "	addxcc		%1,%0,%0,icc0	\n"
+	    "	ldi		@(%4,4),%2	\n"
+	    "	addxcc		%2,%0,%0,icc0	\n"
+	    "	ldi		@(%4,8),%1	\n"
+	    "	addxcc		%1,%0,%0,icc0	\n"
+	    "	ldi		@(%4,12),%2	\n"
+	    "	addxcc		%2,%0,%0,icc0	\n"
+
+	    /* fold the 33-bit result into 16-bits */
+	    "	addxcc		gr0,%0,%0,icc0	\n"
+	    "	srli		%0,#16,%1	\n"
+	    "	sethi		#0,%0		\n"
+	    "	add		%1,%0,%0	\n"
+	    "	srli		%0,#16,%1	\n"
+	    "	add		%1,%0,%0	\n"
+
+	    : "=r" (sum), "=&r" (tmp), "=r" (tmp2)
+	    : "r" (saddr), "r" (daddr), "0" (sum), "2" (len + proto)
+	    : "icc0"
+	    );
+
+	return ~sum;
+}
+
+#endif /* _ASM_CHECKSUM_H */
diff -urN linux-2.4.29/include/asm-frv/cpu-irqs.h linux-2.4.29-uc1/include/asm-frv/cpu-irqs.h
--- linux-2.4.29/include/asm-frv/cpu-irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/cpu-irqs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,87 @@
+/* cpu-irqs.h: CPU irqs
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_CPU_IRQS_H
+#define _ASM_CPU_IRQS_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/irq-routing.h>
+
+#define IRQ_BASE_CPU		(NR_IRQ_ACTIONS_PER_GROUP * 0)
+
+/* IRQ IDs presented to drivers */
+enum {
+	IRQ_CPU__UNUSED = IRQ_BASE_CPU,
+	IRQ_CPU_UART0,
+	IRQ_CPU_UART1,
+	IRQ_CPU_TIMER0,
+	IRQ_CPU_TIMER1,
+	IRQ_CPU_TIMER2,
+	IRQ_CPU_DMA0,
+	IRQ_CPU_DMA1,
+	IRQ_CPU_DMA2,
+	IRQ_CPU_DMA3,
+	IRQ_CPU_DMA4,
+	IRQ_CPU_DMA5,
+	IRQ_CPU_DMA6,
+	IRQ_CPU_DMA7,
+	IRQ_CPU_EXTERNAL0,
+	IRQ_CPU_EXTERNAL1,
+	IRQ_CPU_EXTERNAL2,
+	IRQ_CPU_EXTERNAL3,
+	IRQ_CPU_EXTERNAL4,
+	IRQ_CPU_EXTERNAL5,
+	IRQ_CPU_EXTERNAL6,
+	IRQ_CPU_EXTERNAL7,
+};
+
+/* IRQ to level mappings */
+#define IRQ_GDBSTUB_LEVEL	15
+#define IRQ_UART_LEVEL		13
+
+#ifdef CONFIG_GDBSTUB_UART0
+#define IRQ_UART0_LEVEL		IRQ_GDBSTUB_LEVEL
+#else
+#define IRQ_UART0_LEVEL		IRQ_UART_LEVEL
+#endif
+
+#ifdef CONFIG_GDBSTUB_UART1
+#define IRQ_UART1_LEVEL		IRQ_GDBSTUB_LEVEL
+#else
+#define IRQ_UART1_LEVEL		IRQ_UART_LEVEL
+#endif
+
+#define IRQ_DMA0_LEVEL		14
+#define IRQ_DMA1_LEVEL		14
+#define IRQ_DMA2_LEVEL		14
+#define IRQ_DMA3_LEVEL		14
+#define IRQ_DMA4_LEVEL		14
+#define IRQ_DMA5_LEVEL		14
+#define IRQ_DMA6_LEVEL		14
+#define IRQ_DMA7_LEVEL		14
+
+#define IRQ_TIMER0_LEVEL	12
+#define IRQ_TIMER1_LEVEL	11
+#define IRQ_TIMER2_LEVEL	10
+
+#define IRQ_XIRQ0_LEVEL		1
+#define IRQ_XIRQ1_LEVEL		2
+#define IRQ_XIRQ2_LEVEL		3
+#define IRQ_XIRQ3_LEVEL		4
+#define IRQ_XIRQ4_LEVEL		5
+#define IRQ_XIRQ5_LEVEL		6
+#define IRQ_XIRQ6_LEVEL		7
+#define IRQ_XIRQ7_LEVEL		8
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_CPU_IRQS_H */
diff -urN linux-2.4.29/include/asm-frv/current.h linux-2.4.29-uc1/include/asm-frv/current.h
--- linux-2.4.29/include/asm-frv/current.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/current.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,25 @@
+/* current.h: current task pointer
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells <dhowells@redhat.com>
+ */
+
+#ifndef _ASM_CURRENT_H
+#define _ASM_CURRENT_H
+
+#ifndef __ASSEMBLY__
+
+/*
+ * dedicate GR29 to keeping the current task pointer
+ */
+register struct task_struct *current asm("gr29");
+
+#define get_current() current
+
+#else
+
+#define CURRENT gr29
+
+#endif
+
+#endif /* _ASM_CURRENT_H */
diff -urN linux-2.4.29/include/asm-frv/dbg.h linux-2.4.29-uc1/include/asm-frv/dbg.h
--- linux-2.4.29/include/asm-frv/dbg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/dbg.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,2 @@
+#define DEBUG 1
+#define	BREAK asm volatile ("break")
diff -urN linux-2.4.29/include/asm-frv/delay.h linux-2.4.29-uc1/include/asm-frv/delay.h
--- linux-2.4.29/include/asm-frv/delay.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/delay.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,63 @@
+/* delay.h: description
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_DELAY_H
+#define _ASM_DELAY_H
+
+#include <asm/param.h>
+#include <asm/timer-regs.h>
+
+/*
+ * delay loop - runs at __core_clock_speed_HZ / 2 [there are 2 insns in the loop]
+ */
+extern unsigned long __delay_loops_MHz;
+extern void calibrate_delay(void);
+
+static inline void __delay(unsigned long loops)
+{
+	asm volatile("1:	subicc	%0,#1,%0,icc0	\n"
+		     "		bnc	icc0,#2,1b	\n"
+		     : "=r" (loops)
+		     : "0" (loops)
+		     : "icc0"
+		     );
+}
+
+/*
+ * Use only for very small delays ( < 1 msec).  Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays.  This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)
+ */
+
+extern unsigned long loops_per_jiffy;
+
+static inline void udelay(unsigned long usecs)
+{
+	__delay(usecs * __delay_loops_MHz);
+}
+
+#define ndelay(n)	udelay((n) * 5)
+
+#if 0 /* DAVIDM - elsewhere under m68knommu */
+static inline unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c)
+{
+	unsigned long tmp;
+
+	asm ("	mulul		%2,%0,%1	\n"
+	     "	divul		%3,%0,%1	\n"
+		: "=r" (tmp), "=r" (a)
+		: "r" (b), "r" (c), "1" (a));
+	return a;
+}
+#endif
+
+#endif /* _ASM_DELAY_H) */
diff -urN linux-2.4.29/include/asm-frv/div64.h linux-2.4.29-uc1/include/asm-frv/div64.h
--- linux-2.4.29/include/asm-frv/div64.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/div64.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-generic/div64.h>
diff -urN linux-2.4.29/include/asm-frv/dm9000.h linux-2.4.29-uc1/include/asm-frv/dm9000.h
--- linux-2.4.29/include/asm-frv/dm9000.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/dm9000.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,37 @@
+/* dm9000.h: Davicom DM9000 adapter configuration
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_DM9000_H
+#define _ASM_DM9000_H
+
+#include <asm/mb-regs.h>
+
+#define DM9000_ARCH_IOBASE	(__region_CS6 + 0x300)
+#define DM9000_ARCH_IRQ		IRQ_CPU_EXTERNAL3	/* XIRQ #3 (shared with FPGA) */
+#undef DM9000_ARCH_IRQ_ACTLOW				/* IRQ pin active high */
+#define DM9000_ARCH_BUS_INFO	"CS6#+0x300"		/* bus info for ethtool */
+
+#undef __is_PCI_IO
+#define __is_PCI_IO(addr)	0	/* not PCI */
+
+#undef inl
+#define inl(addr)										\
+({												\
+	unsigned long __ioaddr = (unsigned long) addr;						\
+	uint32_t x = readl(__ioaddr);								\
+	((x & 0xff) << 24) | ((x & 0xff00) << 8) | ((x >> 8) & 0xff00) | ((x >> 24) & 0xff);	\
+})
+
+#undef insl
+#define insl(a,b,l)	__insl(a,b,l,0) /* don't byte-swap */
+
+
+#endif /* _ASM_DM9000_H */
diff -urN linux-2.4.29/include/asm-frv/dma.h linux-2.4.29-uc1/include/asm-frv/dma.h
--- linux-2.4.29/include/asm-frv/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/dma.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,117 @@
+#ifndef _ASM_DMA_H
+#define _ASM_DMA_H 1
+
+//#define	DMA_DEBUG	1
+
+#include <linux/config.h>
+
+#undef MAX_DMA_CHANNELS		/* don't use kernel/dma.c */
+
+/* under 2.4 this is actually needed by the new bootmem allocator */
+#define MAX_DMA_ADDRESS		PAGE_OFFSET
+
+/*
+ * FRV DMA controller management
+ */
+struct pt_regs;
+
+typedef void (*dma_irq_handler_t)(int dmachan, unsigned long cstr, void *data,
+				  struct pt_regs *regs);
+
+extern void frv_dma_init(void);
+
+extern int frv_dma_open(const char *devname,
+			unsigned long dmamask,
+			int dmacap,
+			dma_irq_handler_t handler,
+			unsigned long irq_flags,
+			void *data);
+
+/* channels required */
+#define FRV_DMA_MASK_ANY	ULONG_MAX	/* any channel */
+
+/* capabilities required */
+#define FRV_DMA_CAP_DREQ	0x01		/* DMA request pin */
+#define FRV_DMA_CAP_DACK	0x02		/* DMA ACK pin */
+#define FRV_DMA_CAP_DONE	0x04		/* DMA done pin */
+
+extern void frv_dma_close(int dma);
+
+extern void frv_dma_config(int dma, unsigned long ccfr, unsigned long cctr, unsigned long apr);
+
+extern void frv_dma_start(int dma,
+			  unsigned long sba, unsigned long dba,
+			  unsigned long pix, unsigned long six, unsigned long bcl);
+
+extern void frv_dma_restart_circular(int dma, unsigned long six);
+
+extern void frv_dma_stop(int dma);
+
+extern int is_frv_dma_interrupting(int dma);
+
+extern void frv_dma_dump(int dma);
+
+extern void frv_dma_status_clear(int dma);
+
+#define FRV_DMA_NCHANS	8
+#define FRV_DMA_4CHANS	4
+#define FRV_DMA_8CHANS	8
+
+#define DMAC_CCFRx		0x00	/* channel configuration reg */
+#define DMAC_CCFRx_CM_SHIFT	16
+#define DMAC_CCFRx_CM_DA	0x00000000
+#define DMAC_CCFRx_CM_SCA	0x00010000
+#define DMAC_CCFRx_CM_DCA	0x00020000
+#define DMAC_CCFRx_CM_2D	0x00030000
+#define DMAC_CCFRx_ATS_SHIFT	8
+#define DMAC_CCFRx_RS_INTERN	0x00000000
+#define DMAC_CCFRx_RS_EXTERN	0x00000001
+#define DMAC_CCFRx_RS_SHIFT	0
+
+#define DMAC_CSTRx		0x08	/* channel status reg */
+#define DMAC_CSTRx_FS		0x0000003f
+#define DMAC_CSTRx_NE		0x00000100
+#define DMAC_CSTRx_FED		0x00000200
+#define DMAC_CSTRx_WER		0x00000800
+#define DMAC_CSTRx_RER		0x00001000
+#define DMAC_CSTRx_CE		0x00002000
+#define DMAC_CSTRx_INT		0x00800000
+#define DMAC_CSTRx_BUSY		0x80000000
+
+#define DMAC_CCTRx		0x10	/* channel control reg */
+#define DMAC_CCTRx_DSIZ_1	0x00000000
+#define DMAC_CCTRx_DSIZ_2	0x00000001
+#define DMAC_CCTRx_DSIZ_4	0x00000002
+#define DMAC_CCTRx_DSIZ_32	0x00000005
+#define DMAC_CCTRx_DAU_HOLD	0x00000000
+#define DMAC_CCTRx_DAU_INC	0x00000010
+#define DMAC_CCTRx_DAU_DEC	0x00000020
+#define DMAC_CCTRx_SSIZ_1	0x00000000
+#define DMAC_CCTRx_SSIZ_2	0x00000100
+#define DMAC_CCTRx_SSIZ_4	0x00000200
+#define DMAC_CCTRx_SSIZ_32	0x00000500
+#define DMAC_CCTRx_SAU_HOLD	0x00000000
+#define DMAC_CCTRx_SAU_INC	0x00001000
+#define DMAC_CCTRx_SAU_DEC	0x00002000
+#define DMAC_CCTRx_FC		0x08000000
+#define DMAC_CCTRx_ICE		0x10000000
+#define DMAC_CCTRx_IE		0x40000000
+#define DMAC_CCTRx_ACT		0x80000000
+
+#define DMAC_SBAx		0x18	/* source base address reg */
+#define DMAC_DBAx		0x20	/* data base address reg */
+#define DMAC_PIXx		0x28	/* primary index reg */
+#define DMAC_SIXx		0x30	/* secondary index reg */
+#define DMAC_BCLx		0x38	/* byte count limit reg */
+#define DMAC_APRx		0x40	/* alternate pointer reg */
+
+/*
+ * required for PCI + MODULES
+ */
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy 	(0)
+#endif
+
+#endif /* _ASM_DMA_H */
diff -urN linux-2.4.29/include/asm-frv/elf.h linux-2.4.29-uc1/include/asm-frv/elf.h
--- linux-2.4.29/include/asm-frv/elf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/elf.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,108 @@
+/* elf.h: FR-V ELF definitions
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from include/asm-m68knommu/elf.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_ELF_H
+#define __ASM_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <linux/config.h>
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct fpmedia_struct elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+
+struct elf32_hdr;
+extern int elf_check_arch(const struct elf32_hdr *hdr);
+#define elf_check_fdpic(x) ((x)->e_flags & EF_FRV_FDPIC && !((x)->e_flags & EF_FRV_NON_PIC_RELOCS))
+#define elf_check_const_displacement(x) ((x)->e_flags & EF_FRV_PIC)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2MSB
+#define ELF_ARCH	EM_FRV
+
+#define ELF_PLAT_INIT(_r)			\
+do {						\
+	__kernel_frame0_ptr->gr16	= 0;	\
+	__kernel_frame0_ptr->gr17	= 0;	\
+	__kernel_frame0_ptr->gr18	= 0;	\
+	__kernel_frame0_ptr->gr19	= 0;	\
+	__kernel_frame0_ptr->gr20	= 0;	\
+	__kernel_frame0_ptr->gr21	= 0;	\
+	__kernel_frame0_ptr->gr22	= 0;	\
+	__kernel_frame0_ptr->gr23	= 0;	\
+	__kernel_frame0_ptr->gr24	= 0;	\
+	__kernel_frame0_ptr->gr25	= 0;	\
+	__kernel_frame0_ptr->gr26	= 0;	\
+	__kernel_frame0_ptr->gr27	= 0;	\
+	__kernel_frame0_ptr->gr29	= 0;	\
+} while(0)
+
+#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map_addr, _interp_map_addr, _dynamic_addr)	\
+do {											\
+	__kernel_frame0_ptr->gr16	= _exec_map_addr;				\
+	__kernel_frame0_ptr->gr17	= _interp_map_addr;				\
+	__kernel_frame0_ptr->gr18	= _dynamic_addr;				\
+	__kernel_frame0_ptr->gr19	= 0;						\
+	__kernel_frame0_ptr->gr20	= 0;						\
+	__kernel_frame0_ptr->gr21	= 0;						\
+	__kernel_frame0_ptr->gr22	= 0;						\
+	__kernel_frame0_ptr->gr23	= 0;						\
+	__kernel_frame0_ptr->gr24	= 0;						\
+	__kernel_frame0_ptr->gr25	= 0;						\
+	__kernel_frame0_ptr->gr26	= 0;						\
+	__kernel_frame0_ptr->gr27	= 0;						\
+	__kernel_frame0_ptr->gr29	= 0;						\
+} while(0)
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	16384
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#define ELF_ET_DYN_BASE         0x08000000UL
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs)				\
+	memcpy(&pr_reg[0], &regs->sp, 31 * sizeof(uint32_t));
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.  */
+
+#define ELF_PLATFORM  (NULL)
+
+#ifdef __KERNEL__
+#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-frv/errno.h linux-2.4.29-uc1/include/asm-frv/errno.h
--- linux-2.4.29/include/asm-frv/errno.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/errno.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,133 @@
+#ifndef _ASM_ERRNO_H
+#define _ASM_ERRNO_H
+
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Arg list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	EDEADLK		35	/* Resource deadlock would occur */
+#define	ENAMETOOLONG	36	/* File name too long */
+#define	ENOLCK		37	/* No record locks available */
+#define	ENOSYS		38	/* Function not implemented */
+#define	ENOTEMPTY	39	/* Directory not empty */
+#define	ELOOP		40	/* Too many symbolic links encountered */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	ENOMSG		42	/* No message of desired type */
+#define	EIDRM		43	/* Identifier removed */
+#define	ECHRNG		44	/* Channel number out of range */
+#define	EL2NSYNC	45	/* Level 2 not synchronized */
+#define	EL3HLT		46	/* Level 3 halted */
+#define	EL3RST		47	/* Level 3 reset */
+#define	ELNRNG		48	/* Link number out of range */
+#define	EUNATCH		49	/* Protocol driver not attached */
+#define	ENOCSI		50	/* No CSI structure available */
+#define	EL2HLT		51	/* Level 2 halted */
+#define	EBADE		52	/* Invalid exchange */
+#define	EBADR		53	/* Invalid request descriptor */
+#define	EXFULL		54	/* Exchange full */
+#define	ENOANO		55	/* No anode */
+#define	EBADRQC		56	/* Invalid request code */
+#define	EBADSLT		57	/* Invalid slot */
+
+#define	EDEADLOCK	EDEADLK
+
+#define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
+#define	EMULTIHOP	72	/* Multihop attempted */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EBADMSG		74	/* Not a data message */
+#define	EOVERFLOW	75	/* Value too large for defined data type */
+#define	ENOTUNIQ	76	/* Name not unique on network */
+#define	EBADFD		77	/* File descriptor in bad state */
+#define	EREMCHG		78	/* Remote address changed */
+#define	ELIBACC		79	/* Can not access a needed shared library */
+#define	ELIBBAD		80	/* Accessing a corrupted shared library */
+#define	ELIBSCN		81	/* .lib section in a.out corrupted */
+#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	EILSEQ		84	/* Illegal byte sequence */
+#define	ERESTART	85	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUSERS		87	/* Too many users */
+#define	ENOTSOCK	88	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	89	/* Destination address required */
+#define	EMSGSIZE	90	/* Message too long */
+#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	92	/* Protocol not available */
+#define	EPROTONOSUPPORT	93	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
+#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	96	/* Protocol family not supported */
+#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
+#define	EADDRINUSE	98	/* Address already in use */
+#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
+#define	ENETDOWN	100	/* Network is down */
+#define	ENETUNREACH	101	/* Network is unreachable */
+#define	ENETRESET	102	/* Network dropped connection because of reset */
+#define	ECONNABORTED	103	/* Software caused connection abort */
+#define	ECONNRESET	104	/* Connection reset by peer */
+#define	ENOBUFS		105	/* No buffer space available */
+#define	EISCONN		106	/* Transport endpoint is already connected */
+#define	ENOTCONN	107	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
+#define	ETIMEDOUT	110	/* Connection timed out */
+#define	ECONNREFUSED	111	/* Connection refused */
+#define	EHOSTDOWN	112	/* Host is down */
+#define	EHOSTUNREACH	113	/* No route to host */
+#define	EALREADY	114	/* Operation already in progress */
+#define	EINPROGRESS	115	/* Operation now in progress */
+#define	ESTALE		116	/* Stale NFS file handle */
+#define	EUCLEAN		117	/* Structure needs cleaning */
+#define	ENOTNAM		118	/* Not a XENIX named type file */
+#define	ENAVAIL		119	/* No XENIX semaphores available */
+#define	EISNAM		120	/* Is a named type file */
+#define	EREMOTEIO	121	/* Remote I/O error */
+#define	EDQUOT		122	/* Quota exceeded */
+
+#define	ENOMEDIUM	123	/* No medium found */
+#define	EMEDIUMTYPE	124	/* Wrong medium type */
+
+#endif /* _ASM_ERRNO_H */
+
diff -urN linux-2.4.29/include/asm-frv/fcntl.h linux-2.4.29-uc1/include/asm-frv/fcntl.h
--- linux-2.4.29/include/asm-frv/fcntl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/fcntl.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,87 @@
+#ifndef _ASM_FCNTL_H
+#define _ASM_FCNTL_H
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	  0003
+#define O_RDONLY	    00
+#define O_WRONLY	    01
+#define O_RDWR		    02
+#define O_CREAT		  0100	/* not fcntl */
+#define O_EXCL		  0200	/* not fcntl */
+#define O_NOCTTY	  0400	/* not fcntl */
+#define O_TRUNC		 01000	/* not fcntl */
+#define O_APPEND	 02000
+#define O_NONBLOCK	 04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC		010000
+#define FASYNC		020000	/* fcntl, for BSD compatibility */
+#define O_DIRECT	040000	/* direct disk access hint - currently ignored */
+#define O_LARGEFILE	0100000
+#define O_DIRECTORY	0200000	/* must be a directory */
+#define O_NOFOLLOW	0400000	/* don't follow links */
+
+#define F_DUPFD		0	/* dup */
+#define F_GETFD		1	/* get close_on_exec */
+#define F_SETFD		2	/* set/clear close_on_exec */
+#define F_GETFL		3	/* get file->f_flags */
+#define F_SETFL		4	/* set file->f_flags */
+#define F_GETLK		5
+#define F_SETLK		6
+#define F_SETLKW	7
+
+#define F_SETOWN	8	/*  for sockets. */
+#define F_GETOWN	9	/*  for sockets. */
+#define F_SETSIG	10	/*  for sockets. */
+#define F_GETSIG	11	/*  for sockets. */
+
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK		0
+#define F_WRLCK		1
+#define F_UNLCK		2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+/* for leases */
+#define F_INPROGRESS	16
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* or'd with one of the above to prevent
+				   blocking */
+#define LOCK_UN		8	/* remove lock */
+
+#define LOCK_MAND	32	/* This is a mandatory flock */
+#define LOCK_READ	64	/* ... Which allows concurrent read operations */
+#define LOCK_WRITE	128	/* ... Which allows concurrent write operations */
+#define LOCK_RW		192	/* ... Which allows concurrent read & write ops */
+
+struct flock {
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE	1024
+#endif /* _ASM_FCNTL_H */
+
diff -urN linux-2.4.29/include/asm-frv/flat.h linux-2.4.29-uc1/include/asm-frv/flat.h
--- linux-2.4.29/include/asm-frv/flat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/flat.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,16 @@
+/*
+ * flat.h - uClinux flat-format executables
+ */
+
+#ifndef __ASM_FLAT_H__
+#define __ASM_FLAT_H__
+
+#define	flat_stack_align(sp)			/* nothing needed */
+#define	flat_argvp_envp_on_stack()		1
+#define	flat_old_ram_flag(flags)		(flags)
+#define	flat_reloc_valid(reloc, size)		((reloc) <= (size))
+#define	flat_get_addr_from_rp(rp, relval)	get_unaligned(rp)
+#define	flat_put_addr_at_rp(rp, val, relval)	put_unaligned(val,rp)
+#define	flat_get_relocate_addr(rel)		(rel)
+
+#endif /* __ASM_FLAT_H__ */
diff -urN linux-2.4.29/include/asm-frv/fpu.h linux-2.4.29-uc1/include/asm-frv/fpu.h
--- linux-2.4.29/include/asm-frv/fpu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/fpu.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef __M68KNOMMU_FPU_H
+#define __M68KNOMMU_FPU_H
+
+#include <linux/config.h>
+
+/*
+ * MAX floating point unit state size (FSAVE/FRESTORE)
+ */
+
+/* #if defined(CONFIG_COLDFIRE) */
+#if defined(CONFIG_UCLINUX) /* FIXME */
+#define FPSTATESIZE (2) /* dummy size */
+#elif defined(CONFIG_M68020) || defined(CONFIG_M68030)
+#define FPSTATESIZE (216/sizeof(unsigned char))
+#elif defined(CONFIG_M68040)
+#define FPSTATESIZE (96/sizeof(unsigned char))
+#elif defined(CONFIG_M68KFPU_EMU)
+#define FPSTATESIZE (28/sizeof(unsigned char))
+#elif defined(CONFIG_M68060)
+#define FPSTATESIZE (12/sizeof(unsigned char))
+#else
+#define FPSTATESIZE error no_cpu_type_configured
+#endif
+
+#endif /* __M68K_FPU_H */
diff -urN linux-2.4.29/include/asm-frv/gdb-stub.h linux-2.4.29-uc1/include/asm-frv/gdb-stub.h
--- linux-2.4.29/include/asm-frv/gdb-stub.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/gdb-stub.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,117 @@
+/* gdb-stub.h: FRV GDB stub
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from asm-mips/gdb-stub.h (c) 1995 Andreas Busse
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_GDB_STUB_H
+#define __ASM_GDB_STUB_H
+
+#undef GDBSTUB_DEBUG_PROTOCOL
+
+#include <asm/ptrace.h>
+
+/*
+ * important register numbers in GDB protocol
+ * - GR0,  GR1,  GR2,  GR3,  GR4,  GR5,  GR6,  GR7,
+ * - GR8,  GR9,  GR10, GR11, GR12, GR13, GR14, GR15,
+ * - GR16, GR17, GR18, GR19, GR20, GR21, GR22, GR23,
+ * - GR24, GR25, GR26, GR27, GR28, GR29, GR30, GR31,
+ * - GR32, GR33, GR34, GR35, GR36, GR37, GR38, GR39,
+ * - GR40, GR41, GR42, GR43, GR44, GR45, GR46, GR47,
+ * - GR48, GR49, GR50, GR51, GR52, GR53, GR54, GR55,
+ * - GR56, GR57, GR58, GR59, GR60, GR61, GR62, GR63,
+ * - FR0,  FR1,  FR2,  FR3,  FR4,  FR5,  FR6,  FR7,
+ * - FR8,  FR9,  FR10, FR11, FR12, FR13, FR14, FR15,
+ * - FR16, FR17, FR18, FR19, FR20, FR21, FR22, FR23,
+ * - FR24, FR25, FR26, FR27, FR28, FR29, FR30, FR31,
+ * - FR32, FR33, FR34, FR35, FR36, FR37, FR38, FR39,
+ * - FR40, FR41, FR42, FR43, FR44, FR45, FR46, FR47,
+ * - FR48, FR49, FR50, FR51, FR52, FR53, FR54, FR55,
+ * - FR56, FR57, FR58, FR59, FR60, FR61, FR62, FR63,
+ * - PC, PSR, CCR, CCCR,
+ * - _X132, _X133, _X134
+ * - TBR, BRR, DBAR0, DBAR1, DBAR2, DBAR3,
+ * - SCR0, SCR1, SCR2, SCR3,
+ * - LR, LCR,
+ * - IACC0H, IACC0L,
+ * - FSR0,
+ * - ACC0, ACC1, ACC2, ACC3, ACC4, ACC5, ACC6, ACC7,
+ * - ACCG0123, ACCG4567,
+ * - MSR0, MSR1,
+ * - GNER0, GNER1,
+ * - FNER0, FNER1,
+ */
+#define GDB_REG_GR(N)	(N)
+#define GDB_REG_FR(N)	(64+(N))
+#define GDB_REG_PC	128
+#define GDB_REG_PSR	129
+#define GDB_REG_CCR	130
+#define GDB_REG_CCCR	131
+#define GDB_REG_TBR	135
+#define GDB_REG_BRR	136
+#define GDB_REG_DBAR(N)	(137+(N))
+#define GDB_REG_SCR(N)	(141+(N))
+#define GDB_REG_LR	145
+#define GDB_REG_LCR	146
+#define GDB_REG_FSR0	149
+#define GDB_REG_ACC(N)	(150+(N))
+#define GDB_REG_ACCG(N)	(158+(N)/4)
+#define GDB_REG_MSR(N)	(160+(N))
+#define GDB_REG_GNER(N)	(162+(N))
+#define GDB_REG_FNER(N)	(164+(N))
+
+#define GDB_REG_SP	GDB_REG_GR(1)
+#define GDB_REG_FP	GDB_REG_GR(2)
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+/*
+ * Prototypes
+ */
+extern void show_registers_only(struct pt_regs *regs);
+
+extern void gdbstub_init(void);
+extern void gdbstub(int type);
+extern void gdbstub_exit(int status);
+
+extern void gdbstub_io_init(void);
+extern void gdbstub_set_baud(unsigned baud);
+extern int gdbstub_rx_char(unsigned char *_ch, int nonblock);
+extern void gdbstub_tx_char(unsigned char ch);
+extern void gdbstub_tx_flush(void);
+extern void gdbstub_do_rx(void);
+
+extern asmlinkage void __debug_stub_init_break(void);
+extern asmlinkage void start_kernel(void);
+
+extern asmlinkage void gdbstub_rx_handler(void);
+extern asmlinkage void gdbstub_rx_irq(void);
+extern asmlinkage void gdbstub_intercept(void);
+
+extern uint32_t __entry_usertrap_table[];
+extern uint32_t __entry_kerneltrap_table[];
+
+extern volatile u8	gdbstub_rx_buffer[PAGE_SIZE];
+extern volatile u32	gdbstub_rx_inp;
+extern volatile u32	gdbstub_rx_outp;
+extern volatile u8	gdbstub_rx_overflow;
+extern u8		gdbstub_rx_unget;
+
+extern void gdbstub_printk(const char *fmt, ...);
+extern void debug_to_serial(const char *p, int n);
+extern void console_set_baud(unsigned baud);
+
+#ifdef GDBSTUB_DEBUG_PROTOCOL
+#define gdbstub_proto(FMT,...) gdbstub_printk(FMT,##__VA_ARGS__)
+#else
+#define gdbstub_proto(FMT,...) ({ 0; })
+#endif
+
+#endif /* _LANGUAGE_ASSEMBLY */
+#endif /* __ASM_GDB_STUB_H */
diff -urN linux-2.4.29/include/asm-frv/gpio-regs.h linux-2.4.29-uc1/include/asm-frv/gpio-regs.h
--- linux-2.4.29/include/asm-frv/gpio-regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/gpio-regs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,116 @@
+/* gpio-regs.h: on-chip general purpose I/O registers
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_GPIO_REGS
+#define _ASM_GPIO_REGS
+
+#define __reg(ADDR) (*(volatile unsigned long *)(ADDR))
+
+#define __get_PDR()	({ __reg(0xfeff0400); })
+#define __set_PDR(V)	do { __reg(0xfeff0400) = (V); mb(); } while(0)
+
+#define __get_GPDR()	({ __reg(0xfeff0408); })
+#define __set_GPDR(V)	do { __reg(0xfeff0408) = (V); mb(); } while(0)
+
+#define __get_SIR()	({ __reg(0xfeff0410); })
+#define __set_SIR(V)	do { __reg(0xfeff0410) = (V); mb(); } while(0)
+
+#define __get_SOR()	({ __reg(0xfeff0418); })
+#define __set_SOR(V)	do { __reg(0xfeff0418) = (V); mb(); } while(0)
+
+#define __set_PDSR(V)	do { __reg(0xfeff0420) = (V); mb(); } while(0)
+
+#define __set_PDCR(V)	do { __reg(0xfeff0428) = (V); mb(); } while(0)
+
+#define __get_RSTR()	({ __reg(0xfeff0500); })
+#define __set_RSTR(V)	do { __reg(0xfeff0500) = (V); mb(); } while(0)
+
+
+
+/* PDR definitions */
+#define PDR_GPIO_DATA(X)	(1 << (X))
+
+/* GPDR definitions */
+#define GPDR_INPUT		0
+#define GPDR_OUTPUT		1
+#define GPDR_DREQ0_BIT		0x00001000
+#define GPDR_DREQ1_BIT		0x00008000
+#define GPDR_DREQ2_BIT		0x00040000
+#define GPDR_DREQ3_BIT		0x00080000
+#define GPDR_DREQ4_BIT		0x00004000
+#define GPDR_DREQ5_BIT		0x00020000
+#define GPDR_DREQ6_BIT		0x00100000
+#define GPDR_DREQ7_BIT		0x00200000
+#define GPDR_DACK0_BIT		0x00002000
+#define GPDR_DACK1_BIT		0x00010000
+#define GPDR_DACK2_BIT		0x00100000
+#define GPDR_DACK3_BIT		0x00200000
+#define GPDR_DONE0_BIT		0x00004000
+#define GPDR_DONE1_BIT		0x00020000
+#define GPDR_GPIO_DIR(X,D)	((D) << (X))
+
+/* SIR definitions */
+#define SIR_GPIO_INPUT		0
+#define SIR_DREQ7_INPUT		0x00200000
+#define SIR_DREQ6_INPUT		0x00100000
+#define SIR_DREQ3_INPUT		0x00080000
+#define SIR_DREQ2_INPUT		0x00040000
+#define SIR_DREQ5_INPUT		0x00020000
+#define SIR_DREQ1_INPUT		0x00008000
+#define SIR_DREQ4_INPUT		0x00004000
+#define SIR_DREQ0_INPUT		0x00001000
+#define SIR_RXD1_INPUT		0x00000400
+#define SIR_CTS0_INPUT		0x00000100
+#define SIR_RXD0_INPUT		0x00000040
+#define SIR_GATE1_INPUT		0x00000020
+#define SIR_GATE0_INPUT		0x00000010
+#define SIR_IRQ3_INPUT		0x00000008
+#define SIR_IRQ2_INPUT		0x00000004
+#define SIR_IRQ1_INPUT		0x00000002
+#define SIR_IRQ0_INPUT		0x00000001
+#define SIR_DREQ_BITS		(SIR_DREQ0_INPUT | SIR_DREQ1_INPUT | \
+				 SIR_DREQ2_INPUT | SIR_DREQ3_INPUT | \
+				 SIR_DREQ4_INPUT | SIR_DREQ5_INPUT | \
+				 SIR_DREQ6_INPUT | SIR_DREQ7_INPUT)
+
+/* SOR definitions */
+#define SOR_GPIO_OUTPUT		0
+#define SOR_DACK3_OUTPUT	0x00200000
+#define SOR_DACK2_OUTPUT	0x00100000
+#define SOR_DONE1_OUTPUT	0x00020000
+#define SOR_DACK1_OUTPUT	0x00010000
+#define SOR_DONE0_OUTPUT	0x00004000
+#define SOR_DACK0_OUTPUT	0x00002000
+#define SOR_TXD1_OUTPUT		0x00000800
+#define SOR_RTS0_OUTPUT		0x00000200
+#define SOR_TXD0_OUTPUT		0x00000080
+#define SOR_TOUT1_OUTPUT	0x00000020
+#define SOR_TOUT0_OUTPUT	0x00000010
+#define SOR_DONE_BITS		(SOR_DONE0_OUTPUT | SOR_DONE1_OUTPUT)
+#define SOR_DACK_BITS		(SOR_DACK0_OUTPUT | SOR_DACK1_OUTPUT | \
+				 SOR_DACK2_OUTPUT | SOR_DACK3_OUTPUT)
+
+/* PDSR definitions */
+#define PDSR_UNCHANGED		0
+#define PDSR_SET_BIT(X)		(1 << (X))
+
+/* PDCR definitions */
+#define PDCR_UNCHANGED		0
+#define PDCR_CLEAR_BIT(X)	(1 << (X))
+
+/* RSTR definitions */
+/* Read Only */
+#define RSTR_POWERON		0x00000400
+#define RSTR_SOFTRESET_STATUS	0x00000100
+/* Write Only */
+#define RSTR_SOFTRESET		0x00000001
+
+#endif /* _ASM_GPIO_REGS */
diff -urN linux-2.4.29/include/asm-frv/hardirq.h linux-2.4.29-uc1/include/asm-frv/hardirq.h
--- linux-2.4.29/include/asm-frv/hardirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/hardirq.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,45 @@
+#ifndef __ASM_HARDIRQ_H
+#define __ASM_HARDIRQ_H
+
+#include <linux/config.h>
+#include <linux/threads.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned int __local_irq_count;
+	unsigned int __local_bh_count;
+	unsigned int __syscall_count;
+	struct task_struct * __ksoftirqd_task;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt() (\
+	({unsigned long __cpu = smp_processor_id(); \
+	(local_irq_count(__cpu) + local_bh_count(__cpu) != 0); }))
+
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
+
+#ifndef CONFIG_SMP
+
+#define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
+#define hardirq_endlock(cpu)	do { } while (0)
+
+#define irq_enter(cpu, irq)	(local_irq_count(cpu)++)
+#define irq_exit(cpu, irq)	(local_irq_count(cpu)--)
+
+#define synchronize_irq()	barrier()
+
+#define release_irqlock(cpu)	do { } while (0)
+
+#else
+
+#error frv SMP is not available
+
+#endif /* CONFIG_SMP */
+
+#endif
diff -urN linux-2.4.29/include/asm-frv/hdreg.h linux-2.4.29-uc1/include/asm-frv/hdreg.h
--- linux-2.4.29/include/asm-frv/hdreg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/hdreg.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,13 @@
+/*
+ *  linux/include/asm-m68k/hdreg.h
+ *
+ *  Copyright (C) 1994-1996  Linus Torvalds & authors
+ */
+
+#ifndef _ASM_HDREG_H
+#define _ASM_HDREG_H
+
+typedef unsigned long ide_ioreg_t;
+
+#endif /* _ASM_HDREG_H */
+
diff -urN linux-2.4.29/include/asm-frv/highmem.h linux-2.4.29-uc1/include/asm-frv/highmem.h
--- linux-2.4.29/include/asm-frv/highmem.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/highmem.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,198 @@
+/*
+ * highmem.h: virtual kernel memory mappings for high memory
+ *
+ * Used in CONFIG_HIGHMEM systems for memory pages which
+ * are not addressable by direct kernel virtual addresses.
+ *
+ * Copyright (C) 1999 Gerhard Wichert, Siemens AG
+ *		      Gerhard.Wichert@pdb.siemens.de
+ *
+ *
+ * Redesigned the x86 32-bit VM architecture to deal with 
+ * up to 16 Terabyte physical memory. With current x86 CPUs
+ * we now support up to 64 Gigabytes physical RAM.
+ *
+ * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
+ */
+
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <asm/mem-layout.h>
+#include <asm/spr-regs.h>
+#include <asm/mb-regs.h>
+
+#define NR_TLB_LINES		64	/* number of lines in the TLB */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/interrupt.h>
+#include <asm/kmap_types.h>
+#include <asm/pgtable.h>
+
+#ifdef CONFIG_DEBUG_HIGHMEM
+#define HIGHMEM_DEBUG 1
+#else
+#define HIGHMEM_DEBUG 0
+#endif
+
+/* declarations for highmem.c */
+extern unsigned long highstart_pfn, highend_pfn;
+
+#define kmap_prot PAGE_KERNEL
+#define kmap_pte ______kmap_pte_in_TLB
+extern pte_t *pkmap_page_table;
+
+extern void kmap_init(void);
+
+/*
+ * Right now we initialize only a single pte table. It can be extended
+ * easily, subsequent pte tables have to be allocated in one physical
+ * chunk of RAM.
+ */
+#define LAST_PKMAP	PTRS_PER_PTE
+#define LAST_PKMAP_MASK	(LAST_PKMAP - 1)
+#define PKMAP_NR(virt)	((virt - PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr)	(PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+extern void *kmap_high(struct page *page, int nonblocking);
+extern void kunmap_high(struct page *page);
+
+static inline void *__kmap(struct page *page, int nonblocking)
+{
+	if (in_interrupt())
+		out_of_line_bug();
+	if (page < highmem_start_page)
+		return page_address(page);
+	return kmap_high(page, nonblocking);
+}
+
+static inline void kunmap(struct page *page)
+{
+	if (in_interrupt())
+		out_of_line_bug();
+	if (page < highmem_start_page)
+		return;
+	kunmap_high(page);
+}
+
+#define kmap(page) __kmap(page, 0)
+#define kmap_nonblock(page) __kmap(page, 1)
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
+ * gives a more generic (and caching) interface. But kmap_atomic can
+ * be used in IRQ contexts, so in some (very limited) cases we need
+ * it.
+ */
+#define KMAP_ATOMIC_CACHE_DAMR		8
+
+#ifndef __ASSEMBLY__
+
+#define __kmap_atomic_primary(type, paddr, ampr)						\
+({												\
+	unsigned long damlr, dampr;								\
+												\
+	dampr = paddr | xAMPRx_L | xAMPRx_M | xAMPRx_S | xAMPRx_SS_16Kb | xAMPRx_V;		\
+												\
+	if (type != __KM_CACHE)									\
+		asm volatile("movgs %0,dampr"#ampr :: "r"(dampr));				\
+	else											\
+		asm volatile("movgs %0,iampr"#ampr"\n"						\
+			     "movgs %0,dampr"#ampr"\n"						\
+			     :: "r"(dampr)							\
+			     );									\
+												\
+	asm("movsg damlr"#ampr",%0" : "=r"(damlr));						\
+												\
+	/*printk("DAMR"#ampr": PRIM sl=%d L=%08lx P=%08lx\n", type, damlr, dampr);*/		\
+												\
+	(void *) damlr;										\
+})
+
+#define __kmap_atomic_secondary(slot, paddr)							  \
+({												  \
+	unsigned long damlr = KMAP_ATOMIC_SECONDARY_FRAME + (slot) * PAGE_SIZE;			  \
+	unsigned long dampr = paddr | xAMPRx_L | xAMPRx_M | xAMPRx_S | xAMPRx_SS_16Kb | xAMPRx_V; \
+												  \
+	asm volatile("movgs %0,tplr \n"								  \
+		     "movgs %1,tppr \n"								  \
+		     "tlbpr %0,gr0,#2,#1"							  \
+		     : : "r"(damlr), "r"(dampr));						  \
+												  \
+	/*printk("TLB: SECN sl=%d L=%08lx P=%08lx\n", slot, damlr, dampr);*/			  \
+												  \
+	(void *) damlr;										  \
+})
+
+static inline void *kmap_atomic(struct page *page, enum km_type type)
+{
+	unsigned long paddr;
+
+	paddr = page_to_phys(page);
+
+	switch (type) {
+        case 0:		return __kmap_atomic_primary(0, paddr, 2);
+        case 1:		return __kmap_atomic_primary(1, paddr, 3);
+        case 2:		return __kmap_atomic_primary(2, paddr, 4);
+        case 3:		return __kmap_atomic_primary(3, paddr, 5);
+        case 4:		return __kmap_atomic_primary(4, paddr, 6);
+        case 5:		return __kmap_atomic_primary(5, paddr, 7);
+        case 6:		return __kmap_atomic_primary(6, paddr, 8);
+        case 7:		return __kmap_atomic_primary(7, paddr, 9);
+        case 8:		return __kmap_atomic_primary(8, paddr, 10);
+
+	case 9 ... 9 + NR_TLB_LINES - 1:
+		return __kmap_atomic_secondary(type - 9, paddr);
+
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+#define __kunmap_atomic_primary(type, ampr)			\
+do {								\
+	asm volatile("movgs gr0,dampr"#ampr"\n");		\
+	if (type == __KM_CACHE)					\
+		asm volatile("movgs gr0,iampr"#ampr"\n");	\
+} while(0)
+
+#define __kunmap_atomic_secondary(slot, vaddr)			\
+do {								\
+	asm volatile("tlbpr %0,gr0,#4,#1" : : "r"(vaddr));	\
+} while(0)
+
+static inline void kunmap_atomic(void *kvaddr, enum km_type type)
+{
+	switch (type) {
+        case 0:		__kunmap_atomic_primary(0, 2);	break;
+        case 1:		__kunmap_atomic_primary(1, 3);	break;
+        case 2:		__kunmap_atomic_primary(2, 4);	break;
+        case 3:		__kunmap_atomic_primary(3, 5);	break;
+        case 4:		__kunmap_atomic_primary(4, 6);	break;
+        case 5:		__kunmap_atomic_primary(5, 7);	break;
+        case 6:		__kunmap_atomic_primary(6, 8);	break;
+        case 7:		__kunmap_atomic_primary(7, 9);	break;
+        case 8:		__kunmap_atomic_primary(8, 10);	break;
+
+	case 9 ... 9 + NR_TLB_LINES - 1:
+		__kunmap_atomic_secondary(type - 9, kvaddr);
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_HIGHMEM_H */
diff -urN linux-2.4.29/include/asm-frv/hrtime.h linux-2.4.29-uc1/include/asm-frv/hrtime.h
--- linux-2.4.29/include/asm-frv/hrtime.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/hrtime.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,331 @@
+/*
+ * include/linux/asm-frv/hrtime.h
+ *
+ * Based on asm-i386/hrtime.h
+ *
+ *    2003-7-7  Posix Clocks & timers 
+ *                           by George Anzinger george@mvista.com
+ *
+ *			     Copyright (C) 2002 2003, 2004 by MontaVista Software.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * MontaVista Software | 1237 East Arques Avenue | Sunnyvale | CA 94085 | USA 
+ */
+#ifndef _FRV_HRTIME_H
+#define _FRV_HRTIME_H
+#ifdef __KERNEL__
+
+#include <linux/config.h>	/* for CONFIG_APM etc... */
+#include <asm/types.h>		/* for u16s */
+#include <linux/init.h>
+#include <asm/io.h>
+#include <linux/sc_math.h>	/* scaling math routines */
+#include <asm/delay.h>
+#include <asm/smp.h>
+#include <linux/timex.h>
+/*
+ * We always want the timer, if not touched otherwise, to give periodic
+ * 1/HZ interrupts.  This is done by programing the interrupt we want
+ * and, once it it loaded, (in the case of the PIT) dropping a 1/HZ
+ * program on top of it.  For other timers, other strategies are used,
+ * such as programming a 1/HZ interval on interrupt.  The The PIT will
+ * give us the desired interrupt and, at interrupt time, load the 1/HZ
+ * program.  So...
+
+ * If no sub 1/HZ ticks are needed AND we are aligned with the 1/HZ 
+ * boundry, we don't need to touch the PIT.  Otherwise we do the above.
+
+ * There are two reasons to keep this:
+ * 1. The NMI watchdog uses the timer interrupt to generate the NMI interrupts.
+ * 2. We don't have to touch the PIT unless we have a sub jiffie event in
+ *    the next 1/HZ interval (unless we drift away from the 1/HZ boundry).
+ */
+
+/*
+ * The high-res-timers option is set up to self configure with different 
+ * platforms.  It is up to the platform to provide certian macros which
+ * override the default macros defined in system without (or with disabled)
+ * high-res-timers.
+ *
+ * To do high-res-timers at some fundamental level the timer interrupt must
+ * be seperated from the time keeping tick.  A tick can still be generated
+ * by the timer interrupt, but it may be surrounded by non-tick interrupts.
+ * It is up to the platform to determine if a particular interrupt is a tick,
+ * and up to the timer code (in timer.c) to determine what time events have
+ * expired.
+ *
+ * Details on the functions and macros can be found in the file:
+ * include/hrtime.h
+ */
+struct timer_conversion_bits {
+	unsigned long _arch_to_usec;
+	unsigned long _arch_to_nsec;
+	unsigned long _usec_to_arch;
+	unsigned long _nsec_to_arch;
+	long _arch_cycles_per_jiffy;
+	unsigned long _arch_to_latch;
+	unsigned long volatile _last_update;
+};
+extern struct timer_conversion_bits timer_conversion_bits;
+/*
+ * The following four values are not used for machines 
+ * without a TSC.  For machines with a TSC they
+ * are caculated at boot time. They are used to 
+ * calculate "cycles" to jiffies or usec.  Don't get
+ * confused into thinking they are simple multiples or
+ * divisors, however.  
+ */
+#define arch_to_usec timer_conversion_bits._arch_to_usec
+#define arch_to_nsec timer_conversion_bits._arch_to_nsec
+#define usec_to_arch timer_conversion_bits._usec_to_arch
+#define nsec_to_arch timer_conversion_bits._nsec_to_arch
+
+#define arch_cycles_per_jiffy timer_conversion_bits._arch_cycles_per_jiffy
+/*#define arch_to_latch timer_conversion_bits._arch_to_latch*/
+#define last_update timer_conversion_bits._last_update
+
+/*
+ * no of usecs less than which events cannot be scheduled
+ */
+#define TIMER_DELTA  50
+#ifdef _INCLUDED_FROM_TIME_C
+// EXPORT_SYMBOL(timer_conversion_bits);
+#define EXTERN
+int timer_delta = TIMER_DELTA;
+int hr_time_resolution;
+#else
+#define EXTERN  extern
+extern int timer_delta;
+extern int hr_time_resolution;
+#endif
+
+/*
+ * Interrupt generators need to be disciplined to generate the interrupt
+ * on the 1/HZ boundry (assuming we don't need sub_jiffie interrupts) if
+ * the timer clock is other than the interrupt generator clock.  In the
+ * FR-V case we use the same clock source so no discipine is needed.
+ */
+#define IF_DISCIPLINE(x)
+
+EXTERN int _last_was_long;
+#define __last_was_long  _last_was_long
+
+#define USEC_PER_JIFFIES  (1000000/HZ)
+
+#define schedule_hr_timer_int(a,b)  _schedule_next_int(a,b)
+#define schedule_jiffies_int(a) _schedule_jiffies_int(a)
+
+extern spinlock_t tm0_lock;
+extern rwlock_t xtime_lock;
+extern volatile unsigned long __attribute__((section(".sdata"))) jiffies;
+extern u64 __attribute__((section(".sdata"))) jiffies_64;
+
+extern int _schedule_next_int(unsigned long jiffie_f, long sub_jiffie_in);
+extern int _schedule_jiffies_int(unsigned long jiffie_f);
+
+extern unsigned int   __arch_latch;
+extern unsigned long  __arch_timer_clock_hz;
+
+#define cpuctr_pre   5
+#define cpuctr_hz    (__arch_timer_clock_hz)
+#define cpuctr_shift (cpuctr_pre - 4)
+
+/*
+ * The spec says the counter can be either 32 or 24 bits wide.
+ */
+#define SIZE_MASK 0x1ffff
+
+extern inline unsigned long
+quick_get_cpuctr(void)
+{
+    	unsigned cur;
+
+	__set_TCTR(TCTR_SC_CTR1 | TCTR_RL_LATCH);
+	cur = __get_TCSR_DATA(1);
+	cur |= __get_TCSR_DATA(1) << 8;
+	cur = 0xffff - cur;
+
+	return ((cur << cpuctr_shift) - last_update) & SIZE_MASK;
+}
+
+/*
+ * This function moves the last_update value to the closest to the
+ * current 1/HZ boundry.  This MUST be called under the write xtime_lock.
+ */
+extern inline unsigned long
+stake_cpuctr(void)
+{
+
+	if ((unsigned)quick_get_cpuctr() > arch_cycles_per_jiffy) {
+		last_update = (last_update + arch_cycles_per_jiffy) & SIZE_MASK;
+	}
+}
+
+#define arch_hrtime_init(x) (x)
+
+/* 
+ * We use various scaling.  The sc32 scales by 2**32, sc_n by the first
+ * parm.  When working with constants, choose a scale such that
+ * x/n->(32-scale)< 1/2.  So for 1/3 <1/2 so scale of 32, where as 3/1
+ * must be shifted 3 times (3/8) to be less than 1/2 so scale should be
+ * 29
+ *
+ */
+#define HR_SCALE_ARCH_NSEC 22
+#define HR_SCALE_NSEC_ARCH 32
+#define HR_SCALE_USEC_ARCH 29
+
+extern inline int
+arch_cycle_to_usec(unsigned long update)
+{
+	return (mpy_sc32(update, arch_to_usec));
+}
+
+extern inline int
+arch_cycle_to_latch(unsigned long update)
+{
+	return update >> cpuctr_shift;
+}
+
+extern inline int
+arch_cycle_to_nsec(long update)
+{
+	return mpy_sc_n(HR_SCALE_ARCH_NSEC, update, arch_to_nsec);
+}
+/* 
+ * And the other way...
+ */
+extern inline int
+usec_to_arch_cycle(unsigned long usec)
+{
+	return mpy_sc_n(HR_SCALE_USEC_ARCH, usec, usec_to_arch);
+}
+extern inline int
+nsec_to_arch_cycle(unsigned long nsec)
+{
+	return mpy_sc32(nsec, nsec_to_arch);
+}
+
+#ifdef _INCLUDED_FROM_TIME_C
+struct timer_conversion_bits timer_conversion_bits;
+
+/*
+ * After we get the address, we set last_update to the current timer value
+ */
+static inline __init void  init_hrtimers(void)
+{
+	arch_cycles_per_jiffy = (cpuctr_hz + HZ / 2) / HZ;
+	hr_time_resolution = 10000;
+	arch_to_usec = SC_32(100000000)/(long long)(cpuctr_hz * 100);
+	arch_to_nsec = SC_n(HR_SCALE_ARCH_NSEC,100000000000LL)/ 
+	    		(long long)(cpuctr_hz * 100);
+	usec_to_arch = SC_n( HR_SCALE_USEC_ARCH,cpuctr_hz * 100)/
+			(long long)100000000;
+	nsec_to_arch = SC_n( HR_SCALE_NSEC_ARCH,cpuctr_hz)/ \
+			(long long)1000000000;
+	
+	__set_TxCKSL_DATA(1, cpuctr_pre);
+	__set_TCTR(TCTR_SC_CTR1 | TCTR_RL_RW_LH8 | TCTR_MODE_2);
+	__set_TCSR_DATA(1, 0);
+	__set_TCSR_DATA(1, 0);
+	last_update = 0;
+}
+
+#endif  /* _INCLUDED_FROM_TIME_C_ */
+
+
+	/*
+	 * We program the PIT to give periodic interrupts and, if no
+	 * sub_jiffie timers are due, leave it alone.  This means that
+	 * it can drift WRT the clock (TSC or pm timer).  What we are
+	 * trying to do is to program the next interrupt to occure on
+	 * exactly the requested time.  If we are not doing sub HZ
+	 * interrupts we expect to find a small excess of time beyond
+	 * the 1/HZ, i.e. _sub_jiffie will have some small value.  This
+	 * value will drift AND may jump upward from time to time.  The
+	 * drift is due to not having precise tracking between the two
+	 * timers (the PIT and either the TSC or the PM timer) and the
+	 * jump is caused by interrupt delays, cache misses etc.  We
+	 * need to correct for the drift.  To correct all we need to do
+	 * is to set "last_was_long" to zero and a new timer program
+	 * will be started to "do the right thing".
+
+	 * Detecting the need to do this correction is another issue.
+	 * Here is what we do:
+	 *
+	 * Each interrupt where last_was_long is !=0 (indicates the
+	 * interrupt should be on a 1/HZ boundry) we check the resulting
+	 * _sub_jiffie.  If it is smaller than some MIN value, we do the
+	 * correction.  (Note that drift that makes the value smaller is
+	 * the easy one.)  We also require that _sub_jiffie <= some max
+	 * at least once over a period of 1 second.  I.e.  with HZ =
+	 * 100, we will allow up to 99 "late" interrupts before we do a
+	 * correction.
+
+	 * The values we use for min_hz_sub_jiffie and max_hz_sub_jiffie
+	 * depend on the units and we will start by, during boot,
+	 * observing what MIN appears to be.  We will set
+	 * max_hz_sub_jiffie to be about 100 machine cycles more than
+	 * this.
+
+	 * Note that with min_hz_sub_jiffie and max_hz_sub_jiffie set to
+	 * 0, this code will reset the PIT every HZ.
+	 */
+#define discipline_timer(a)
+
+/*
+ * This routine is always called under the write_lockirq(xtime_lock)
+ * We provide something like a sequence lock for local use.  We need to
+ * keep cycles, sub_jiffie and jiffie aligned (be nice to get 
+ * wall_to_monotonic, but, sigh, another day).
+ */
+
+extern inline long
+get_arch_cycles(unsigned long ref) 
+{
+	return (long)(jiffies - ref) * arch_cycles_per_jiffy + quick_get_cpuctr();
+}
+
+extern inline void
+reload_timer_chip(int new_latch_value)
+{
+	unsigned char pit_status;
+
+	/*
+	 * The input value is in arch cycles
+	 * We must be called with irq disabled.
+	 */
+	new_latch_value = arch_cycle_to_latch(new_latch_value);
+	if (new_latch_value < TIMER_DELTA) {
+		new_latch_value = TIMER_DELTA;
+	}
+	spin_lock(&tm0_lock);
+	__set_TCTR(TCTR_SC_CTR0 | TCTR_RL_RW_LH8 | TCTR_MODE_2);
+	__set_TCSR_DATA(0, new_latch_value & 0xff);
+	__set_TCSR_DATA(0, new_latch_value >> 8);
+	do {
+		__set_TCTR(TCTR_SC_READBACK | TCTR_CNT0);
+		pit_status = __get_TCSR_DATA(0);
+	} while (pit_status & TCSRx_NULLCOUNT);
+	__set_TCSR_DATA(0, __arch_latch & 0xff);
+	__set_TCSR_DATA(0, __arch_latch >> 8);
+	spin_unlock(&tm0_lock);
+	return;
+}
+
+#define final_clock_init()
+#endif				/* __KERNEL__ */
+#endif				/* _I386_HRTIME_H */
diff -urN linux-2.4.29/include/asm-frv/hw_irq.h linux-2.4.29-uc1/include/asm-frv/hw_irq.h
--- linux-2.4.29/include/asm-frv/hw_irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/hw_irq.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,16 @@
+/* hw_irq.h: FR-V specific h/w IRQ stuff
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_HW_IRQ_H
+#define _ASM_HW_IRQ_H
+
+
+#endif /* _ASM_HW_IRQ_H */
diff -urN linux-2.4.29/include/asm-frv/hwtest.h linux-2.4.29-uc1/include/asm-frv/hwtest.h
--- linux-2.4.29/include/asm-frv/hwtest.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/hwtest.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,18 @@
+/* Routines to test for presence/absence of hardware registers:
+ * see arch/m68k/mm/hwtest.c.
+ *  -- PMM <pmaydell@chiark.greenend.org.uk> 05/1998
+ *
+ * Removed __init from decls.  We might want them in modules, and 
+ * the code is tiny anyway.  16/5/98 pb
+ */
+
+#ifndef __ASM_HWTEST_H
+#define __ASM_HWTEST_H 
+
+#error
+
+extern int hwreg_present(volatile void *regp);
+extern int hwreg_write(volatile void *regp, unsigned short val);
+
+#endif
+
diff -urN linux-2.4.29/include/asm-frv/ide.h linux-2.4.29-uc1/include/asm-frv/ide.h
--- linux-2.4.29/include/asm-frv/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/ide.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,97 @@
+/****************************************************************************/
+/*
+ *  linux/include/asm-m68knommu/ide.h
+ *
+ *  Copyright (C) 2001-2003  David McCullough <davidm@snapgear.com>
+ */
+
+#ifndef _ASM_IDE_H
+#define _ASM_IDE_H
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+
+#include <asm/setup.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+/****************************************************************************/
+
+#undef SUPPORT_SLOW_DATA_PORTS
+#define SUPPORT_SLOW_DATA_PORTS 0
+
+#undef SUPPORT_VLB_SYNC
+#define SUPPORT_VLB_SYNC 0
+
+#ifndef MAX_HWIFS
+#define MAX_HWIFS 8
+#endif
+
+#define IDE_ARCH_ACK_INTR 1
+#define ide_ack_intr(hwif) ((hwif)->hw.ack_intr?(hwif)->hw.ack_intr(hwif):1)
+
+/****************************************************************************/
+/*
+ * these guys are not used on uClinux,  the uclinux.c driver does it all for us
+ */
+static inline int ide_default_irq(ide_ioreg_t base)
+{
+	return 0;
+}
+
+static inline ide_ioreg_t ide_default_io_base(int index)
+{
+	/* we don't have an ISA bus */
+	return 0;
+}
+
+static inline void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
+				       ide_ioreg_t ctrl_port, int *irq)
+{
+#if 1 //ndef CONFIG_UCLINUX
+	ide_ioreg_t reg = data_port;
+	int i;
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = reg;
+		reg += 1;
+	}
+	if (ctrl_port) {
+		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+	} else {
+		hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
+	}
+	if (irq != NULL)
+		*irq = 0;
+	hw->io_ports[IDE_IRQ_OFFSET] = 0;
+#else
+	return 0;
+#endif
+}
+
+static inline void ide_init_default_hwifs(void)
+{
+#if 1 //ndef CONFIG_BLK_DEV_IDEPCI
+	hw_regs_t hw;
+	int index;
+
+	for (index = 0; index < MAX_HWIFS; index++) {
+		ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
+		hw.irq = ide_default_irq(ide_default_io_base(index));
+		ide_register_hw(&hw, NULL);
+	}
+#endif /* CONFIG_BLK_DEV_IDEPCI */
+}
+
+/****************************************************************************/
+/*
+ * some bits needed for parts of the IDE subsystem to compile
+ */
+#define __ide_mm_insw(port, addr, n)	insw((u16 *)port, addr, n)
+#define __ide_mm_insl(port, addr, n)	insl((u32 *)port, addr, n)
+#define __ide_mm_outsw(port, addr, n)	outsw((u16 *)port, addr, n)
+#define __ide_mm_outsl(port, addr, n)	outsl((u32 *)port, addr, n)
+
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_IDE_H */
diff -urN linux-2.4.29/include/asm-frv/init.h linux-2.4.29-uc1/include/asm-frv/init.h
--- linux-2.4.29/include/asm-frv/init.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/init.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef _ASM_INIT_H
+#define _ASM_INIT_H
+
+#define __init __attribute__ ((__section__ (".text.init")))
+#define __initdata __attribute__ ((__section__ (".data.init")))
+/* For assembly routines */
+#define __INIT		.section	".text.init",#alloc,#execinstr
+#define __FINIT		.previous
+#define __INITDATA	.section	".data.init",#alloc,#write
+
+#endif
+
diff -urN linux-2.4.29/include/asm-frv/ioctl.h linux-2.4.29-uc1/include/asm-frv/ioctl.h
--- linux-2.4.29/include/asm-frv/ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/ioctl.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,80 @@
+/*
+ * linux/ioctl.h for Linux by H.H. Bergman.
+ */
+
+#ifndef _ASM_IOCTL_H
+#define _ASM_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * I don't really have any idea about what this should look like, so
+ * for the time being, this is heavily based on the PC definitions.
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	14
+#define _IOC_DIRBITS	2
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE	0U
+#define _IOC_WRITE	1U
+#define _IOC_READ	2U
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* _ASM_IOCTL_H */
+
diff -urN linux-2.4.29/include/asm-frv/ioctls.h linux-2.4.29-uc1/include/asm-frv/ioctls.h
--- linux-2.4.29/include/asm-frv/ioctls.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/ioctls.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,82 @@
+#ifndef __ASM_IOCTLS_H__
+#define __ASM_IOCTLS_H__
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+#define TIOCSBRK	0x5427  /* BSD compatibility */
+#define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define FIONCLEX	0x5450  /* these numbers need to be adjusted. */
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+#define FIOQSIZE	0x545E
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+#endif /* __ASM_IOCTLS_H__ */
+
diff -urN linux-2.4.29/include/asm-frv/io.h linux-2.4.29-uc1/include/asm-frv/io.h
--- linux-2.4.29/include/asm-frv/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/io.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,268 @@
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <asm/virtconvert.h>
+#include <asm/mb-regs.h>
+#include <linux/delay.h>
+
+/*
+ * These are for ISA/PCI shared memory _only_ and should never be used
+ * on any other type of memory, including Zorro memory. They are meant to
+ * access the bus in the bus byte order which is little-endian!.
+ *
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the m68k architecture, we just read/write the
+ * memory location directly.
+ */
+/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
+ * two accesses to memory, which may be undesireable for some devices.
+ */
+
+/*
+ * swap functions are sometimes needed to interface little-endian hardware
+ */
+
+/*
+ * CHANGES
+ * 
+ * 020325   Added some #define's for the COBRA5272 board
+ *          (hede)
+ */
+static inline unsigned short _swapw(unsigned short v)
+{
+    return ((v << 8) | (v >> 8));
+}
+
+static inline unsigned long _swapl(unsigned long v)
+{
+    return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
+}
+
+//#define __iormb() asm volatile("membar")
+//#define __iowmb() asm volatile("membar")
+
+#define __raw_readb(addr) __builtin_read8((volatile void *) (addr))
+#define __raw_readw(addr) __builtin_read16((volatile void *) (addr))
+#define __raw_readl(addr) __builtin_read32((volatile void *) (addr))
+
+#define __raw_writeb(datum, addr) __builtin_write8((volatile void *) (addr), datum)
+#define __raw_writew(datum, addr) __builtin_write16((volatile void *) (addr), datum)
+#define __raw_writel(datum, addr) __builtin_write32((volatile void *) (addr), datum)
+
+static inline void io_outsb(unsigned int addr, const void *buf, int len)
+{
+	unsigned long __ioaddr = (unsigned long) addr;
+	const uint8_t *bp = buf;
+
+	while (len--)
+		__builtin_write8((volatile void *) __ioaddr, *bp++);
+}
+
+static inline void io_outsw(unsigned int addr, const void *buf, int len)
+{
+	unsigned long __ioaddr = (unsigned long) addr;
+	const uint16_t *bp = buf;
+
+	while (len--)
+		__builtin_write16((volatile void *) __ioaddr, (*bp++));
+}
+
+extern void __outsl_ns(unsigned int addr, const void *buf, int len);
+extern void __outsl_sw(unsigned int addr, const void *buf, int len);
+static inline void __outsl(unsigned int addr, const void *buf, int len, int swap)
+{
+	unsigned long __ioaddr = (unsigned long) addr;
+
+	if (!swap)
+		__outsl_ns(__ioaddr, buf, len);
+	else
+		__outsl_sw(__ioaddr, buf, len);
+}
+
+static inline void io_insb(unsigned int addr, void *buf, int len)
+{
+	unsigned long __ioaddr = (unsigned long) addr;
+	uint8_t *bp = buf;
+
+	while (len--)
+		*bp++ = __builtin_read8((volatile void *) __ioaddr);
+}
+
+static inline void io_insw(unsigned int addr, void *buf, int len)
+{
+	unsigned long __ioaddr = (unsigned long) addr;
+	uint16_t *bp = buf;
+
+	while (len--)
+		*bp++ = __builtin_read16((volatile void *) __ioaddr);
+}
+
+extern void __insl_ns(unsigned int addr, void *buf, int len);
+extern void __insl_sw(unsigned int addr, void *buf, int len);
+static inline void __insl(unsigned int addr, void *buf, int len, int swap)
+{
+	unsigned long __ioaddr = (unsigned long) addr;
+
+	if (!swap)
+		__insl_ns(__ioaddr, buf, len);
+	else
+		__insl_sw(__ioaddr, buf, len);
+}
+
+/*
+ *	make the short names macros so specific devices
+ *	can override them as required
+ */
+
+#define memset_io(a,b,c)	memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
+
+static inline uint8_t inb(unsigned long addr)
+{
+	return __builtin_read8((volatile void *)addr);
+}
+
+static inline uint16_t inw(unsigned long addr)
+{
+	uint16_t ret = __builtin_read16((volatile void *)addr);
+
+	if (__is_PCI_IO(addr))
+		ret = _swapw(ret);
+
+	return ret;
+}
+
+static inline uint32_t inl(unsigned long addr)
+{
+	uint32_t ret = __builtin_read32((volatile void *)addr);
+
+	if (__is_PCI_IO(addr))
+		ret = _swapl(ret);
+
+	return ret;
+}
+
+static inline void outb(uint8_t datum, unsigned long addr)
+{
+	__builtin_write8((volatile void *)addr, datum);
+}
+
+static inline void outw(uint16_t datum, unsigned long addr)
+{
+	if (__is_PCI_IO(addr))
+		datum = _swapw(datum);
+	__builtin_write16((volatile void *)addr, datum);
+}
+
+static inline void outl(uint32_t datum, unsigned long addr)
+{
+	if (__is_PCI_IO(addr))
+		datum = _swapl(datum);
+	__builtin_write32((volatile void *)addr, datum);
+}
+
+#define inb_p(addr)	inb(addr)
+#define inw_p(addr)	inw(addr)
+#define inl_p(addr)	inl(addr)
+#define outb_p(x,addr)	outb(x,addr)
+#define outw_p(x,addr)	outw(x,addr)
+#define outl_p(x,addr)	outl(x,addr)
+
+#define outsb(a,b,l)	io_outsb(a,b,l)
+#define outsw(a,b,l)	io_outsw(a,b,l)
+#define outsl(a,b,l)	__outsl(a,b,l,0)
+
+#define insb(a,b,l)	io_insb(a,b,l)
+#define insw(a,b,l)	io_insw(a,b,l)
+#define insl(a,b,l)	__insl(a,b,l,0)
+
+#define IO_SPACE_LIMIT	0xffffffff
+
+static inline uint8_t readb(volatile void *addr)
+{
+	return __builtin_read8(addr);
+}
+
+static inline uint16_t readw(volatile void *addr)
+{
+	uint16_t ret =	__builtin_read16(addr);
+
+	if (__is_PCI_MEM(addr))
+		ret = _swapw(ret);
+	return ret;
+}
+
+static inline uint32_t readl(volatile void *addr)
+{
+	uint32_t ret =	__builtin_read32(addr);
+
+	if (__is_PCI_MEM(addr))
+		ret = _swapl(ret);
+
+	return ret;
+}
+
+static inline void writeb(uint8_t datum, volatile void *addr)
+{
+	__builtin_write8(addr, datum);
+	if (__is_PCI_MEM(addr))
+		__flush_PCI_writes();
+}
+
+static inline void writew(uint16_t datum, volatile void *addr)
+{
+	if (__is_PCI_MEM(addr))
+		datum = _swapw(datum);
+
+	__builtin_write16(addr, datum);
+	if (__is_PCI_MEM(addr))
+		__flush_PCI_writes();
+}
+
+static inline void writel(uint32_t datum, volatile void *addr)
+{
+	if (__is_PCI_MEM(addr))
+		datum = _swapl(datum);
+
+	__builtin_write32(addr, datum);
+	if (__is_PCI_MEM(addr))
+		__flush_PCI_writes();
+}
+
+
+/* Values for nocacheflag and cmode */
+#define IOMAP_FULL_CACHING		0
+#define IOMAP_NOCACHE_SER		1
+#define IOMAP_NOCACHE_NONSER		2
+#define IOMAP_WRITETHROUGH		3
+
+extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
+extern void __iounmap(void *addr, unsigned long size);
+
+extern inline void *ioremap(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+extern inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+extern inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
+}
+extern inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
+}
+
+extern void iounmap(void *addr);
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_IO_H */
diff -urN linux-2.4.29/include/asm-frv/io_hw_swap.h linux-2.4.29-uc1/include/asm-frv/io_hw_swap.h
--- linux-2.4.29/include/asm-frv/io_hw_swap.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/io_hw_swap.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,94 @@
+#ifndef _M68K_IO_HW_SWAP_H
+#define _M68K_IO_HW_SWAP_H
+
+/*
+ * swap functions are sometimes needed to interface little-endian hardware
+ */
+static inline unsigned short _swapw(volatile unsigned short v)
+{
+    return ((v << 8) | (v >> 8));
+}
+
+static inline unsigned int _swapl(volatile unsigned long v)
+{
+    return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
+}
+
+/*
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the m68k architecture, we just read/write the
+ * memory location directly.
+ */
+/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
+ * two accesses to memory, which may be undesireable for some devices.
+ */
+#define readb(addr) \
+    ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
+#define readw(addr) \
+    ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
+#define readl(addr) \
+    ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
+
+#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+
+/* There is no difference between I/O and memory on 68k, these are the same */
+#define inb(addr) \
+    ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
+#define inw(addr) \
+    ({ unsigned short __v = (*(volatile unsigned short *) (addr)); \
+       _swapw(__v); })
+#define inl(addr) \
+    ({ unsigned int __v = (*(volatile unsigned int *) (addr)); _swapl(__v); })
+
+#define outb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
+#define outw(b,addr) ((*(volatile unsigned short *) (addr)) = (_swapw(b)))
+#define outl(b,addr) ((*(volatile unsigned int *) (addr)) = (_swapl(b)))
+
+/* FIXME: these need to be optimized.  Watch out for byte swapping, they
+ * are used mostly for Intel devices... */
+#define outsw(addr,buf,len) \
+    ({ unsigned short * __p = (unsigned short *)(buf); \
+       unsigned short * __e = (unsigned short *)(__p) + (len); \
+       while (__p < __e) { \
+	  *(volatile unsigned short *)(addr) = *__p++;\
+       } \
+     })
+
+#define insw(addr,buf,len) \
+    ({ unsigned short * __p = (unsigned short *)(buf); \
+       unsigned short * __e = (unsigned short *)(__p) + (len); \
+       while (__p < __e) { \
+          *(__p++) = *(volatile unsigned short *)(addr); \
+       } \
+     })
+
+
+static inline unsigned char get_user_byte_io(const char * addr)
+{
+	register unsigned char _v;
+
+	__asm__ __volatile__ ("moveb %1,%0":"=dm" (_v):"m" (*addr));
+	return _v;
+}
+#define inb_p(addr) get_user_byte_io((char *)(addr))
+
+static inline void put_user_byte_io(char val,char *addr)
+{
+	__asm__ __volatile__ ("moveb %0,%1"
+			      : /* no outputs */
+			      :"idm" (val),"m" (*addr)
+			      : "memory");
+}
+#define outb_p(x,addr) put_user_byte_io((x),(char *)(addr))
+
+/*
+ * IO bus memory addresses are also 1:1 with the physical address
+ */
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+
+#endif /* _M68K_IO_HW_SWAP_H */
diff -urN linux-2.4.29/include/asm-frv/ipcbuf.h linux-2.4.29-uc1/include/asm-frv/ipcbuf.h
--- linux-2.4.29/include/asm-frv/ipcbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/ipcbuf.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,30 @@
+#ifndef __ASM_IPCBUF_H__
+#define __ASM_IPCBUF_H__
+
+/*
+ * The user_ipc_perm structure for FR-V architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
+	__kernel_mode_t		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* __ASM_IPCBUF_H__ */
+
diff -urN linux-2.4.29/include/asm-frv/ipc.h linux-2.4.29-uc1/include/asm-frv/ipc.h
--- linux-2.4.29/include/asm-frv/ipc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/ipc.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,32 @@
+#ifndef __ASM_IPC_H__
+#define __ASM_IPC_H__
+
+/* 
+ * These are used to wrap system calls on FR-V
+ *
+ * See arch/frv/kernel/sys_frv.c for ugly details..
+ */
+struct ipc_kludge {
+	struct msgbuf *msgp;
+	long msgtyp;
+};
+
+#define SEMOP		 1
+#define SEMGET		 2
+#define SEMCTL		 3
+#define MSGSND		11
+#define MSGRCV		12
+#define MSGGET		13
+#define MSGCTL		14
+#define SHMAT		21
+#define SHMDT		22
+#define SHMGET		23
+#define SHMCTL		24
+
+/* Used by the DIPC package, try and avoid reusing it */
+#define DIPC		25
+
+#define IPCCALL(version,op)	((version)<<16 | (op))
+
+#endif
+
diff -urN linux-2.4.29/include/asm-frv/irc-regs.h linux-2.4.29-uc1/include/asm-frv/irc-regs.h
--- linux-2.4.29/include/asm-frv/irc-regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/irc-regs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,53 @@
+/* irc-regs.h: on-chip interrupt controller registers
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_IRC_REGS
+#define _ASM_IRC_REGS
+
+#define __reg(ADDR) (*(volatile unsigned long *)(ADDR))
+
+#define __get_TM0()	({ __reg(0xfeff9800); })
+#define __get_TM1()	({ __reg(0xfeff9808); })
+#define __set_TM1(V)	do { __reg(0xfeff9808) = (V); mb(); } while(0)
+
+#define __set_TM1x(XI,V)			\
+do {						\
+	int shift = (XI) * 2 + 16;		\
+	unsigned long tm1 = __reg(0xfeff9808);	\
+	tm1 &= ~(0x3 << shift);			\
+	tm1 |= (V) << shift;			\
+	__reg(0xfeff9808) = tm1;		\
+	mb();					\
+} while(0)
+
+#define __get_RS(C)	({ (__reg(0xfeff9810) >> ((C)+16)) & 1; })
+
+#define __clr_RC(C)	do { __reg(0xfeff9818) = 1 << ((C)+16); mb(); } while(0)
+
+#define __get_MASK(C)	({ (__reg(0xfeff9820) >> ((C)+16)) & 1; })
+#define __set_MASK(C)	do { __reg(0xfeff9820) |=  1 << ((C)+16); mb(); } while(0)
+#define __clr_MASK(C)	do { __reg(0xfeff9820) &=  ~(1 << ((C)+16)); mb(); } while(0)
+
+#define __get_MASK_all() __get_MASK(0)
+#define __set_MASK_all() __set_MASK(0)
+#define __clr_MASK_all() __clr_MASK(0)
+
+#define __get_IRL()	({ (__reg(0xfeff9828) >> 16) & 0xf; })
+#define __clr_IRL()	do { __reg(0xfeff9828) = 0x100000; mb(); } while(0)
+
+#define __get_IRR(N)	({ __reg(0xfeff9840 + (N) * 8); })
+#define __set_IRR(N,V)	do { __reg(0xfeff9840 + (N) * 8) = (V); } while(0)
+
+#define __get_IITMR(N)	({ __reg(0xfeff9880 + (N) * 8); })
+#define __set_IITMR(N,V) do { __reg(0xfeff9880 + (N) * 8) = (V); } while(0)
+
+
+#endif /* _ASM_IRC_REGS */
diff -urN linux-2.4.29/include/asm-frv/irq.h linux-2.4.29-uc1/include/asm-frv/irq.h
--- linux-2.4.29/include/asm-frv/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/irq.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,30 @@
+#ifndef _ASM_IRQ_H_
+#define _ASM_IRQ_H_
+
+#include <linux/config.h>
+
+/*
+ * the system has an on-CPU PIC and another PIC on the FPGA and other PICs on other peripherals,
+ * so we do some routing in irq-routing.[ch] to reduce the number of false-positives seen by
+ * drivers
+ */
+
+#define NR_IRQ_LOG2_ACTIONS_PER_GROUP	5
+#define NR_IRQ_ACTIONS_PER_GROUP	(1 << NR_IRQ_LOG2_ACTIONS_PER_GROUP)
+#define NR_IRQ_GROUPS			4
+#define NR_IRQS				(NR_IRQ_ACTIONS_PER_GROUP * NR_IRQ_GROUPS)
+
+/* probe returns a 32-bit IRQ mask:-/ */
+#define MIN_PROBE_IRQ	(NR_IRQS - 32)
+
+static inline int irq_cannonicalize(int irq)
+{
+	return irq;
+}
+
+extern void disable_irq_nosync(unsigned int irq);
+extern void disable_irq(unsigned int irq);
+extern void enable_irq(unsigned int irq);
+
+
+#endif /* _ASM_IRQ_H_ */
diff -urN linux-2.4.29/include/asm-frv/irq-routing.h linux-2.4.29-uc1/include/asm-frv/irq-routing.h
--- linux-2.4.29/include/asm-frv/irq-routing.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/irq-routing.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,71 @@
+/* irq-routing.h: multiplexed IRQ routing
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_IRQ_ROUTING_H
+#define _ASM_IRQ_ROUTING_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <asm/irq.h>
+
+struct irq_source;
+struct irq_level;
+
+/*
+ * IRQ action distribution sets
+ */
+struct irq_group {
+	int			first_irq;	/* first IRQ distributed here */
+	void (*control)(struct irq_group *group, int index, int on);
+
+	struct irqaction	*actions[NR_IRQ_ACTIONS_PER_GROUP];	/* IRQ action chains */
+	struct irq_source	*sources[NR_IRQ_ACTIONS_PER_GROUP];	/* IRQ sources */
+	int			disable_cnt[NR_IRQ_ACTIONS_PER_GROUP];	/* disable counts */
+};
+
+/*
+ * IRQ source manager
+ */
+struct irq_source {
+	struct irq_source	*next;
+	struct irq_level	*level;
+	const char		*muxname;
+	unsigned long		muxdata;
+	unsigned long		irqmask;
+
+	void (*doirq)(struct irq_source *source);
+};
+
+/*
+ * IRQ level management (per CPU IRQ priority / entry vector)
+ */
+struct irq_level {
+	int			usage;
+	int			disable_count;
+	unsigned long		flags;		/* current SA_INTERRUPT and SA_SHIRQ settings */
+	spinlock_t		lock;
+	struct irq_source	*sources;
+};
+
+extern struct irq_level frv_irq_levels[16];
+extern struct irq_group *irq_groups[NR_IRQ_GROUPS];
+
+extern void frv_irq_route(struct irq_source *source, int irqlevel);
+extern void frv_irq_route_external(struct irq_source *source, int irq);
+extern void frv_irq_set_group(struct irq_group *group);
+extern void distribute_irqs(struct irq_group *group, unsigned long irqmask);
+extern void route_cpu_irqs(void);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_IRQ_ROUTING_H */
diff -urN linux-2.4.29/include/asm-frv/keyboard.h linux-2.4.29-uc1/include/asm-frv/keyboard.h
--- linux-2.4.29/include/asm-frv/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/keyboard.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,31 @@
+/*
+ *  keyboard.h
+ *  Created 04 Dec 2001 by Khaled Hassounah <khassounah@mediumware.net>
+ *  This file contains the Dragonball architecture specific keyboard definitions
+ */
+
+#ifndef _ASM_KEYBOARD_H
+#define _ASM_KEYBOARD_H
+
+#include <linux/config.h>
+
+/* dummy i.e. no real keyboard */
+#define kbd_setkeycode(x...)	(-ENOSYS)
+#define kbd_getkeycode(x...)	(-ENOSYS)
+#define kbd_translate(x...)	(0)
+#define kbd_unexpected_up(x...)	(1)
+#define kbd_leds(x...)		do {;} while (0)
+#define kbd_init_hw(x...)	do {;} while (0)
+#define kbd_enable_irq(x...)	do {;} while (0)
+#define kbd_disable_irq(x...)	do {;} while (0)
+#define kbd_write_output(val)	do {;} while (0)
+
+
+/* needed if MAGIC_SYSRQ is enabled for serial console */
+#ifndef SYSRQ_KEY
+#define SYSRQ_KEY		((unsigned char)(-1))
+#define kbd_sysrq_xlate         ((unsigned char *)NULL)
+#endif
+
+
+#endif  /* _ASM_KEYBOARD_H */
diff -urN linux-2.4.29/include/asm-frv/kmap_types.h linux-2.4.29-uc1/include/asm-frv/kmap_types.h
--- linux-2.4.29/include/asm-frv/kmap_types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/kmap_types.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,24 @@
+                                                                                
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+ 
+enum km_type {
+	/* arch specific kmaps - change the numbers attached to these at your peril */
+	__KM_CACHE,		/* cache flush page attachment point */
+	__KM_PGD,		/* current page directory */
+	__KM_ITLB_PTD,		/* current instruction TLB miss page table lookup */
+	__KM_DTLB_PTD,		/* current data TLB miss page table lookup */
+
+	/* general kmaps */
+        KM_BOUNCE_READ,
+        KM_SKB_SUNRPC_DATA,
+        KM_SKB_DATA_SOFTIRQ,
+        KM_USER0,
+        KM_USER1,
+        KM_BH_IRQ,
+        KM_SOFTIRQ0,
+        KM_SOFTIRQ1,
+        KM_TYPE_NR
+};
+ 
+#endif
diff -urN linux-2.4.29/include/asm-frv/linux_logo.h linux-2.4.29-uc1/include/asm-frv/linux_logo.h
--- linux-2.4.29/include/asm-frv/linux_logo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/linux_logo.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,1430 @@
+/*
+ * include/linux/linux_logo.h: This is a linux logo
+ *                             to be displayed on boot.
+ *
+ *  This file has been generated. Do not edit.
+ */
+
+#ifndef __HAVE_ARCH_LINUX_LOGO
+#define LINUX_LOGO_COLORS       224
+#endif
+
+#ifdef INCLUDE_LINUX_LOGO_DATA
+
+#ifndef __HAVE_ARCH_LINUX_LOGO
+
+unsigned char linux_logo_red[] __initdata = {
+    0x02, 0xf2, 0xe2, 0xfe, 0xba, 0x8a, 0x62, 0xe6,
+    0x32, 0xde, 0xfe, 0x36, 0xfe, 0xf6, 0xbe, 0x1a,
+    0xf6, 0x9e, 0x9a, 0xde, 0xfe, 0x16, 0x8a, 0xba,
+    0xf6, 0xd6, 0xf6, 0xfe, 0x65, 0x7a, 0xea, 0xc6,
+    0x12, 0xfe, 0xca, 0xf6, 0x5a, 0x7a, 0x8e, 0x9e,
+    0xb0, 0xfe, 0xf2, 0xbe, 0xf6, 0x0a, 0x8a, 0x5e,
+    0x68, 0x52, 0xc6, 0xee, 0xad, 0xfe, 0x4a, 0xbe,
+    0xd2, 0x3a, 0xfe, 0xfe, 0xf6, 0xa2, 0xa6, 0xfe,
+    0xf2, 0x06, 0x3e, 0x4e, 0xf2, 0x7a, 0x82, 0xbe,
+    0xea, 0xe2, 0xfa, 0xfd, 0xfa, 0x7f, 0x9e, 0xba,
+    0xe2, 0x5e, 0xbe, 0x26, 0x02, 0xa2, 0xfe, 0x2e,
+    0xfe, 0xda, 0xfe, 0xee, 0xf2, 0x56, 0x9e, 0xd2,
+    0x3a, 0x42, 0x76, 0xfe, 0x8a, 0xfe, 0xfe, 0xaa,
+    0xee, 0xee, 0xfe, 0xb2, 0x8e, 0xd6, 0x30, 0x76,
+    0xc6, 0xb5, 0xae, 0x9c, 0xfe, 0xca, 0xfe, 0x16,
+    0xfa, 0x72, 0xc6, 0x5a, 0xe2, 0xfe, 0x4a, 0x2a,
+    0x22, 0xce, 0xe6, 0xd2, 0xe6, 0xfe, 0xce, 0xea,
+    0x66, 0x97, 0x9a, 0xda, 0x66, 0x54, 0x46, 0xfe,
+    0xd2, 0xd6, 0x7e, 0x76, 0xfe, 0xe2, 0xda, 0x36,
+    0x52, 0xf6, 0x3e, 0x5e, 0x26, 0xf6, 0x26, 0x5a,
+    0xb6, 0xbe, 0xa6, 0xb6, 0x9a, 0x6e, 0xd2, 0xfe,
+    0xfe, 0xae, 0x5a, 0xf6, 0x1a, 0xc2, 0xa6, 0xc2,
+    0x5e, 0x84, 0xfe, 0xd6, 0xca, 0xfe, 0xb6, 0xf6,
+    0x8e, 0xca, 0xda, 0xfc, 0xfe, 0x92, 0x56, 0xe2,
+    0xee, 0x87, 0xea, 0x12, 0xfe, 0xa2, 0xfe, 0xee,
+    0xca, 0x1e, 0xee, 0x6a, 0xe2, 0xfe, 0xfe, 0x0e,
+    0xd6, 0x6b, 0xfd, 0xfb, 0xfc, 0xd6, 0x46, 0xac,
+    0x7a, 0xce, 0xf2, 0x68, 0xfe, 0x5e, 0xee, 0xfe,
+    0x42, 0xff, 0xff, 0xff, 0x42, 0xff, 0xff, 0xff,
+    0x42, 0xff, 0xff, 0xff, 0x42, 0xff, 0xff, 0xff,
+    0x42, 0xff, 0xff, 0xff, 0x42, 0xff, 0xff, 0xff,
+    0x42, 0xff, 0xff, 0xff, 0x42, 0xff, 0xff, 0xff
+};
+
+unsigned char linux_logo_green[] __initdata = {
+    0x02, 0xd2, 0xba, 0x02, 0x92, 0x5e, 0x46, 0xae,
+    0x32, 0xbe, 0x1e, 0x26, 0x4d, 0xd6, 0xbe, 0x1a,
+    0xd9, 0x9e, 0x62, 0xde, 0x6e, 0x12, 0x8a, 0xba,
+    0xe6, 0x0a, 0xd6, 0x7e, 0x4e, 0x5e, 0xea, 0x1a,
+    0x0e, 0xba, 0xa6, 0xda, 0x5a, 0x56, 0x7a, 0x76,
+    0x9b, 0x90, 0xf2, 0x92, 0xda, 0x0a, 0x66, 0x46,
+    0x22, 0x36, 0x9a, 0xce, 0x77, 0x99, 0x4a, 0xa6,
+    0xd2, 0x3a, 0x18, 0x2a, 0xf6, 0x86, 0x4a, 0xd2,
+    0xc6, 0x06, 0x2a, 0x4e, 0x9e, 0x66, 0x62, 0xb2,
+    0xc1, 0x9e, 0xba, 0x12, 0xfa, 0x52, 0x90, 0x86,
+    0xb2, 0x56, 0x96, 0x1e, 0x02, 0xa2, 0xcb, 0x2e,
+    0x56, 0x9e, 0xdf, 0xba, 0xaa, 0x56, 0x6a, 0xa6,
+    0x12, 0x42, 0x76, 0xe6, 0x6e, 0xed, 0x40, 0x7e,
+    0xbe, 0xb6, 0x0e, 0xa6, 0x86, 0xa6, 0x22, 0x62,
+    0x8a, 0xb5, 0x92, 0x78, 0xfe, 0x92, 0xb2, 0x16,
+    0x69, 0x66, 0xc6, 0x52, 0xa6, 0xc6, 0x36, 0x2a,
+    0x22, 0xa2, 0xba, 0xce, 0xe6, 0x0a, 0xce, 0xae,
+    0x62, 0x97, 0x72, 0xda, 0x66, 0x40, 0x46, 0x31,
+    0x96, 0xaa, 0x72, 0x52, 0x72, 0xaa, 0xc2, 0x36,
+    0x52, 0xce, 0x3e, 0x56, 0x1a, 0xba, 0x26, 0x3e,
+    0x7a, 0x8e, 0xa6, 0x8e, 0x7a, 0x6a, 0xa2, 0xf2,
+    0xf6, 0x86, 0x4e, 0xe6, 0x0e, 0x86, 0x72, 0xc2,
+    0x5e, 0x84, 0x37, 0x9a, 0x96, 0x26, 0x86, 0xbe,
+    0x6e, 0xa2, 0xa2, 0xb6, 0xc2, 0x92, 0x42, 0xe2,
+    0xb2, 0x56, 0xca, 0x12, 0x06, 0x6e, 0x5c, 0xee,
+    0xca, 0x1e, 0xc6, 0x46, 0xae, 0xda, 0xaa, 0x0e,
+    0xd6, 0x6b, 0x79, 0xa5, 0x85, 0xae, 0x2e, 0xac,
+    0x7a, 0x92, 0xba, 0x54, 0xbe, 0x52, 0xca, 0x22,
+    0x7b, 0xff, 0xff, 0xff, 0x7c, 0xff, 0xff, 0xff,
+    0x7d, 0xff, 0xff, 0xff, 0x7e, 0xff, 0xff, 0xff,
+    0x7f, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff,
+    0x81, 0xff, 0xff, 0xff, 0x82, 0xff, 0xff, 0xff
+};
+
+unsigned char linux_logo_blue[] __initdata = {
+    0x02, 0x12, 0x0e, 0xfe, 0x0e, 0x06, 0x06, 0x0a,
+    0x32, 0xde, 0xfe, 0x06, 0xfe, 0x16, 0xbe, 0x1a,
+    0x27, 0x9e, 0x06, 0xde, 0xfe, 0x06, 0x8a, 0xba,
+    0xbe, 0xd6, 0x36, 0xfe, 0x0a, 0x0a, 0xea, 0xca,
+    0x06, 0xfe, 0x12, 0x3e, 0x5a, 0x1a, 0x4a, 0x0a,
+    0x70, 0xfe, 0xf2, 0x0e, 0x4a, 0x0a, 0x0e, 0x1e,
+    0x68, 0x06, 0x0a, 0x5a, 0x07, 0xfe, 0x4a, 0x72,
+    0xd2, 0x3a, 0xfe, 0xfe, 0xf6, 0x42, 0xa6, 0xfe,
+    0x0e, 0x06, 0x06, 0x4e, 0xf2, 0x46, 0x2e, 0x92,
+    0x11, 0xe2, 0xfa, 0xfd, 0xfa, 0x06, 0x5c, 0x0a,
+    0x3e, 0x42, 0x2e, 0x0a, 0x06, 0xa2, 0xfe, 0x2e,
+    0xfe, 0x0a, 0xfe, 0x0a, 0xf2, 0x56, 0x0a, 0x0a,
+    0x3e, 0x42, 0x76, 0xfe, 0x32, 0xfe, 0xfe, 0x2e,
+    0x0a, 0x0e, 0xfe, 0x92, 0x6a, 0x3a, 0x06, 0x2e,
+    0x0a, 0xb5, 0x3e, 0x2b, 0xfe, 0x0a, 0xfe, 0x16,
+    0xfa, 0x4e, 0xc6, 0x42, 0x0a, 0xfe, 0x0e, 0x2a,
+    0x22, 0x2a, 0x3e, 0xba, 0xe6, 0xfe, 0xce, 0x0e,
+    0x5a, 0x97, 0x0a, 0xda, 0x66, 0x22, 0x46, 0xfe,
+    0x0a, 0x36, 0x5a, 0x0a, 0xfe, 0x0a, 0x86, 0x36,
+    0x52, 0x2e, 0x3e, 0x4e, 0x0a, 0x0e, 0x26, 0x06,
+    0x06, 0x22, 0xa6, 0x2e, 0x3e, 0x5e, 0x0a, 0xfe,
+    0xfe, 0x32, 0x5e, 0xf6, 0x1a, 0x0a, 0x06, 0xc2,
+    0x5e, 0x84, 0xfe, 0x0a, 0x22, 0xfe, 0x26, 0x0e,
+    0x2e, 0x46, 0x0a, 0xfc, 0xfe, 0x92, 0x1e, 0xe2,
+    0x0e, 0x06, 0x1e, 0x12, 0xfe, 0x0a, 0xfe, 0xee,
+    0xca, 0x1e, 0xee, 0x06, 0x0e, 0xfe, 0xfe, 0x0e,
+    0xd6, 0x6b, 0xfd, 0xfb, 0xfc, 0x0e, 0x06, 0xac,
+    0x7a, 0x0a, 0x0e, 0x38, 0xfe, 0x5e, 0x0e, 0xfe,
+    0xbd, 0xff, 0xff, 0xff, 0xbe, 0xff, 0xff, 0xff,
+    0xbf, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xff,
+    0xc1, 0xff, 0xff, 0xff, 0xc2, 0xff, 0xff, 0xff,
+    0xc3, 0xff, 0xff, 0xff, 0xc4, 0xff, 0xff, 0xff
+};
+
+unsigned char linux_logo[] __initdata = {
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x61, 0x61, 0x4d, 0x4d,
+    0x4d, 0x61, 0x61, 0x61, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x61, 0x4d, 0xef, 0x97, 0x2f, 0xe9, 0xa0,
+    0xe9, 0xe9, 0x2f, 0xe3, 0xef, 0x4d, 0x61, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x61, 0xef, 0x2f, 0x9f, 0xb7, 0x81, 0x63, 0x63,
+    0x63, 0x56, 0x81, 0xb7, 0x9f, 0x2f, 0xe3, 0x4d,
+    0x61, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d,
+    0x97, 0x9f, 0x81, 0x7d, 0x81, 0xbe, 0xbe, 0x97,
+    0x2f, 0xa0, 0xb7, 0x81, 0x7d, 0xae, 0x77, 0x2f,
+    0xef, 0x61, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x2f,
+    0x28, 0xb8, 0x59, 0x61, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0x74, 0x61, 0xb7, 0x7d, 0x81,
+    0xbe, 0xe3, 0x61, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x97, 0x28,
+    0x63, 0xa0, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x61, 0xae,
+    0x63, 0x77, 0x97, 0x61, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x61, 0xe3, 0x9f, 0xb8,
+    0x2f, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0xef, 0x77, 0xa0, 0x61, 0x74,
+    0x9f, 0x63, 0x9f, 0xe3, 0x61, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x4d, 0xe9, 0x81, 0x59,
+    0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0x2f, 0x7d, 0xa8, 0x77, 0x4d,
+    0x74, 0x59, 0xae, 0xa0, 0x4d, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0xef, 0x9f, 0x7d, 0x4d,
+    0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0xe9, 0xd0, 0xd0, 0x59, 0x2f,
+    0x74, 0x61, 0x63, 0xb7, 0x97, 0x61, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x61, 0x97, 0xba, 0xba, 0x74,
+    0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0x2f, 0xb7, 0xbe, 0xe3, 0x4d,
+    0x74, 0x74, 0xa0, 0xb8, 0xbe, 0xef, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x61, 0xe9, 0x63, 0xe9, 0x74,
+    0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0x4d, 0x4d, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0x63, 0x28, 0xe3, 0x61, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x4d, 0xbe, 0x7d, 0xef, 0x74,
+    0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0xb7, 0x81, 0x2f, 0x61, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0xef, 0x9f, 0xb8, 0x74, 0x74,
+    0x74, 0x61, 0x4d, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0x61, 0xef, 0x4d, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0xe3, 0xb8, 0xa0, 0x4d, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0xef, 0x77, 0x7d, 0x74, 0x74,
+    0x61, 0x61, 0x97, 0xa0, 0x61, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0xe3, 0xa0, 0x4d, 0x28, 0x97, 0x74,
+    0x74, 0x74, 0x74, 0x4d, 0x7d, 0x9f, 0xef, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0xef, 0x77, 0x7d, 0x74, 0x74,
+    0xbe, 0x82, 0xd0, 0x97, 0x97, 0x74, 0x74, 0x74,
+    0xef, 0x7d, 0x36, 0x75, 0xa9, 0xbe, 0x2f, 0x61,
+    0x74, 0x74, 0x74, 0x74, 0x7d, 0x77, 0xef, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0xef, 0x77, 0x7d, 0x74, 0xef,
+    0xd1, 0x9a, 0xcf, 0x82, 0x4d, 0x74, 0x74, 0x61,
+    0xa8, 0x2e, 0x58, 0xab, 0xf0, 0xd1, 0xef, 0x61,
+    0x74, 0x74, 0x74, 0x74, 0x7d, 0x28, 0xe3, 0x61,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0xef, 0x77, 0x7d, 0x74, 0x59,
+    0xab, 0x9a, 0xdf, 0x5c, 0x59, 0x74, 0x74, 0xe9,
+    0x58, 0x6c, 0xf7, 0xf8, 0x33, 0x3e, 0x56, 0x74,
+    0x74, 0x74, 0x74, 0x74, 0xae, 0x59, 0x97, 0x61,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0xef, 0x77, 0xb8, 0x74, 0xac,
+    0xf7, 0x2f, 0x7d, 0xdf, 0xf8, 0x4d, 0xef, 0x77,
+    0xa4, 0x2e, 0x61, 0x56, 0x44, 0xe7, 0x31, 0x74,
+    0x74, 0x74, 0x74, 0x74, 0xae, 0x59, 0x97, 0x61,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0xef, 0x9f, 0x7d, 0x61, 0x82,
+    0xac, 0x61, 0xae, 0xa9, 0xf8, 0xe3, 0xbe, 0xb7,
+    0x33, 0xf1, 0x74, 0xef, 0x77, 0x2e, 0x9a, 0x74,
+    0x74, 0x74, 0x74, 0x74, 0x56, 0xba, 0x97, 0x61,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0xef, 0x9f, 0xd0, 0xef, 0xa8,
+    0xd1, 0x74, 0xe3, 0x82, 0x8f, 0x3d, 0x3d, 0x3c,
+    0x75, 0xf1, 0x74, 0x74, 0x74, 0xcf, 0xcf, 0x61,
+    0x74, 0x74, 0x74, 0x74, 0x56, 0xba, 0x97, 0x61,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x4d, 0xbe, 0x44, 0xef, 0x59,
+    0xa6, 0x2f, 0x2b, 0xaa, 0xb5, 0x89, 0xec, 0x24,
+    0xf5, 0x92, 0xbc, 0x20, 0xae, 0x5c, 0x36, 0x74,
+    0x74, 0x74, 0x74, 0x74, 0xae, 0x81, 0x2f, 0x61,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x4d, 0xbe, 0x7d, 0xef, 0x4d,
+    0xcf, 0x57, 0x6f, 0xec, 0x89, 0x22, 0x68, 0xe2,
+    0xb9, 0xfe, 0x68, 0x24, 0xb6, 0xa3, 0x9f, 0x74,
+    0x74, 0x74, 0x74, 0x74, 0x28, 0x56, 0xe9, 0x61,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x4d, 0xa0, 0x7d, 0xef, 0x74,
+    0x45, 0xcd, 0xda, 0x89, 0x88, 0xe2, 0xfe, 0x3a,
+    0x43, 0x30, 0x2d, 0xfe, 0x21, 0x22, 0x45, 0x20,
+    0x74, 0x74, 0x74, 0x74, 0x28, 0xb8, 0xa0, 0x4d,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x4d, 0xa0, 0xb8, 0xe9, 0x62,
+    0xc0, 0xf9, 0x27, 0x89, 0x22, 0xfe, 0x21, 0x4c,
+    0x30, 0x30, 0x2d, 0x2d, 0x22, 0xf5, 0x24, 0x61,
+    0x74, 0x74, 0x74, 0x74, 0x2f, 0xd0, 0x9f, 0xef,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x4d, 0xe9, 0x63, 0x28, 0x26,
+    0x6f, 0x79, 0xe0, 0x7b, 0x68, 0x21, 0x3a, 0x30,
+    0x2d, 0x2d, 0x21, 0x52, 0x90, 0x79, 0xaa, 0x74,
+    0x74, 0x74, 0x74, 0x74, 0x61, 0x44, 0xb7, 0xe3,
+    0x61, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x4d, 0xe9, 0x63, 0x77, 0x35,
+    0x25, 0xc6, 0x89, 0x88, 0xfe, 0xfe, 0x2d, 0x2d,
+    0x21, 0x42, 0x6f, 0xb0, 0xc6, 0xb0, 0x3c, 0x74,
+    0x61, 0xb7, 0xef, 0x74, 0x74, 0xba, 0x56, 0xe9,
+    0x4d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x4d, 0xa0, 0x63, 0x28, 0x61,
+    0x4f, 0x4e, 0x4b, 0x22, 0xe2, 0xe2, 0xf5, 0x24,
+    0x54, 0x6f, 0xb0, 0xd3, 0xd4, 0x48, 0xa8, 0x20,
+    0x74, 0x63, 0x82, 0xb7, 0x74, 0x97, 0x44, 0x77,
+    0xe3, 0x61, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x4d, 0xbe, 0x7d, 0x28, 0x61,
+    0xf8, 0x48, 0xaa, 0x47, 0x52, 0x24, 0x90, 0x95,
+    0xf9, 0xf9, 0x90, 0x57, 0xcf, 0xe8, 0xf7, 0xef,
+    0x74, 0xe3, 0x82, 0x82, 0x97, 0x74, 0x56, 0xae,
+    0xe9, 0x4d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x61, 0xe3, 0x28, 0xac, 0x2f, 0xef,
+    0x36, 0x37, 0x48, 0x7e, 0x90, 0x90, 0x90, 0x6f,
+    0xc0, 0xc1, 0x67, 0x37, 0xe8, 0x33, 0xf0, 0x81,
+    0x74, 0x74, 0x28, 0xba, 0x61, 0x74, 0x4d, 0x44,
+    0x28, 0xe3, 0x61, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x4d, 0xa0, 0x56, 0x56, 0x74, 0x20,
+    0xdd, 0x9a, 0x2e, 0x8b, 0x93, 0xaa, 0x7e, 0x87,
+    0x48, 0x37, 0x2e, 0x58, 0x5c, 0x94, 0x6c, 0x91,
+    0x61, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0xba,
+    0x56, 0xa0, 0xef, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x4d, 0x97, 0xb7, 0xd0, 0xe3, 0x74, 0x77,
+    0x3e, 0x33, 0x2e, 0x2e, 0x2e, 0x37, 0x37, 0x2e,
+    0x2e, 0xcf, 0xf0, 0x4a, 0x94, 0x94, 0x94, 0x94,
+    0xb8, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0xef,
+    0x7d, 0xb7, 0x97, 0x61, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x61, 0xe3, 0x77, 0x44, 0x77, 0xe3, 0x61, 0x91,
+    0x94, 0x5c, 0xa6, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+    0xa6, 0xa4, 0x6c, 0x6c, 0x6c, 0x94, 0x6c, 0x94,
+    0xe8, 0xef, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x9f, 0x7d, 0x9f, 0xe3, 0x61, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61,
+    0xef, 0xbe, 0x56, 0x81, 0x74, 0x61, 0x44, 0x6c,
+    0x94, 0x94, 0xe7, 0x9a, 0x2e, 0x2e, 0xcf, 0x33,
+    0x5c, 0x94, 0x94, 0x94, 0x94, 0x94, 0x6c, 0x6c,
+    0x6c, 0xb8, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x63, 0xae, 0xa0, 0xef, 0x61, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xef,
+    0xa0, 0x81, 0x63, 0x61, 0x74, 0xe3, 0xab, 0x94,
+    0x6c, 0x94, 0x6c, 0x5c, 0xdf, 0xa4, 0x5c, 0x6c,
+    0x94, 0x6c, 0x94, 0x94, 0x6c, 0x94, 0x94, 0x94,
+    0x94, 0x91, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0xe3, 0x44, 0xba, 0xe9, 0x4d, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x2f,
+    0x59, 0x44, 0xe3, 0x74, 0x74, 0xf1, 0x6c, 0x94,
+    0x6c, 0x94, 0x6c, 0x94, 0x6c, 0x94, 0x94, 0x94,
+    0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x6c,
+    0x6c, 0xa4, 0xe3, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0xe3, 0xd0, 0xb7, 0x2f, 0x4d, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x97, 0x28,
+    0x44, 0x2f, 0x74, 0x74, 0x40, 0x9a, 0x6c, 0x94,
+    0x94, 0x94, 0x94, 0x94, 0x94, 0x6c, 0x94, 0x6c,
+    0x94, 0x6c, 0x6c, 0x94, 0x6c, 0x94, 0x94, 0x94,
+    0x6c, 0x4a, 0xb7, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0xbe, 0x7d, 0x28, 0x97, 0x61,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x61, 0xef, 0xbe, 0xb8,
+    0xa0, 0x74, 0x74, 0x74, 0x9f, 0x9a, 0x5c, 0x94,
+    0x94, 0x94, 0x6c, 0x6c, 0x4a, 0x4a, 0x6c, 0x94,
+    0x94, 0x94, 0x94, 0x94, 0x6c, 0x6c, 0x5c, 0xe7,
+    0xdf, 0xa4, 0xa8, 0x61, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0x74, 0xbe, 0xb8, 0x9f, 0xef,
+    0x61, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x4d, 0x2f, 0xba, 0x81,
+    0x74, 0x74, 0x74, 0x61, 0xae, 0xf7, 0xa6, 0x3e,
+    0x5c, 0x6c, 0x6c, 0xe7, 0xdf, 0xa4, 0xe7, 0x6c,
+    0x6c, 0x6c, 0x5c, 0xa4, 0xf0, 0xa6, 0xe8, 0xe8,
+    0x9a, 0xe8, 0x91, 0xe3, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0x74, 0x74, 0xba, 0x81, 0xe9,
+    0x4d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0xef, 0x9f, 0xb8, 0xe3,
+    0x74, 0x74, 0x74, 0x4d, 0xd0, 0x91, 0xab, 0x4a,
+    0x6c, 0x94, 0x94, 0x6c, 0x3e, 0x94, 0x6c, 0x94,
+    0x94, 0x6c, 0x94, 0x5c, 0xe7, 0xdf, 0x58, 0xe8,
+    0xcf, 0x9a, 0x58, 0x31, 0x61, 0xef, 0x28, 0xef,
+    0x74, 0x74, 0x74, 0x74, 0x74, 0x61, 0x7d, 0x77,
+    0xe3, 0x61, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x61, 0x97, 0xb7, 0xae, 0x74,
+    0x74, 0x4d, 0x74, 0x97, 0xc2, 0xa4, 0x6c, 0x6c,
+    0x94, 0x94, 0x6c, 0x6c, 0x4a, 0x94, 0x94, 0x94,
+    0x94, 0x94, 0x94, 0x94, 0x6c, 0x94, 0x94, 0x5c,
+    0xa4, 0xa6, 0x9a, 0xdf, 0xd0, 0x74, 0x61, 0xbe,
+    0xe9, 0x74, 0x74, 0x74, 0x74, 0x74, 0xba, 0x81,
+    0x2f, 0x4d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x4d, 0xe9, 0x56, 0x28, 0x74,
+    0x2f, 0x2f, 0x74, 0xf1, 0xe7, 0x94, 0x94, 0x6c,
+    0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x6c, 0x6c,
+    0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x6c, 0x94,
+    0x94, 0x5c, 0xab, 0xe8, 0x58, 0xef, 0x74, 0x74,
+    0xe9, 0x97, 0x74, 0x74, 0x74, 0x74, 0xe3, 0x7d,
+    0x9f, 0xef, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0xef, 0x9f, 0x44, 0x97, 0x74,
+    0x9f, 0x74, 0xe3, 0xab, 0x94, 0x6c, 0x94, 0x94,
+    0x6c, 0x94, 0x94, 0x94, 0x6c, 0x94, 0x94, 0x94,
+    0x94, 0x6c, 0x94, 0x94, 0x6c, 0x94, 0x94, 0x94,
+    0x6c, 0x6c, 0x6c, 0xab, 0xab, 0xa8, 0x74, 0xef,
+    0xe3, 0xbe, 0x4d, 0x74, 0x74, 0x74, 0x74, 0x63,
+    0x59, 0x97, 0x61, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x61, 0xe3, 0xb7, 0xb8, 0x74, 0x2f,
+    0x97, 0x74, 0xf8, 0x6c, 0x94, 0x94, 0x94, 0x94,
+    0x94, 0x94, 0x6c, 0x94, 0x6c, 0x94, 0x94, 0x6c,
+    0x94, 0x6c, 0x94, 0x94, 0x6c, 0x94, 0x94, 0x94,
+    0x94, 0x6c, 0x94, 0x6c, 0xe7, 0x9a, 0x61, 0xbe,
+    0x59, 0x2f, 0xbe, 0x74, 0x74, 0x74, 0x74, 0x77,
+    0x63, 0xe9, 0x4d, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x4d, 0xe9, 0x56, 0x59, 0x74, 0x9f,
+    0x74, 0x97, 0xa4, 0x94, 0x94, 0x6c, 0x94, 0x94,
+    0x6c, 0x6c, 0x94, 0x6c, 0x94, 0x94, 0x94, 0x94,
+    0x94, 0x94, 0x6c, 0x7a, 0xdb, 0x96, 0x96, 0x76,
+    0x94, 0x94, 0x94, 0x6c, 0x94, 0x5c, 0x77, 0x50,
+    0x50, 0xef, 0xbe, 0xef, 0x74, 0x74, 0x74, 0x61,
+    0x7d, 0x77, 0xef, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x61, 0xef, 0x9f, 0x44, 0xe3, 0xe3, 0x2f,
+    0x74, 0x82, 0x94, 0x94, 0x94, 0x6c, 0x94, 0x94,
+    0x94, 0x94, 0x6c, 0xe7, 0x6c, 0x6c, 0x94, 0x94,
+    0x94, 0x94, 0x94, 0xf2, 0x23, 0x23, 0x23, 0x6b,
+    0x7a, 0x94, 0x94, 0x94, 0x6c, 0x6c, 0x5e, 0xe4,
+    0x3f, 0x74, 0x4d, 0xa0, 0x74, 0x74, 0x74, 0x74,
+    0x56, 0x59, 0x97, 0x61, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x4d, 0x2f, 0x81, 0xb8, 0x74, 0xbe, 0x61,
+    0x4d, 0x29, 0x41, 0x6a, 0x41, 0x41, 0x6a, 0x41,
+    0x41, 0xed, 0xdb, 0xdb, 0x41, 0x41, 0x5f, 0x5c,
+    0x94, 0x94, 0x6c, 0x55, 0x34, 0xe6, 0x23, 0x23,
+    0x76, 0x6c, 0x94, 0x94, 0x94, 0xdc, 0xe4, 0x39,
+    0xcc, 0x74, 0x74, 0x77, 0x74, 0x74, 0x74, 0x74,
+    0x9f, 0x56, 0xe9, 0x4d, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x61, 0xef, 0x9f, 0x44, 0x2f, 0x61, 0x9f, 0x74,
+    0x56, 0x2c, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
+    0x2a, 0x2c, 0x23, 0x23, 0x23, 0x23, 0xe4, 0x5b,
+    0x41, 0x94, 0x6c, 0x6c, 0x6c, 0x76, 0x23, 0x23,
+    0x7a, 0x94, 0x6c, 0x94, 0x83, 0xff, 0x8a, 0x80,
+    0x74, 0x74, 0x74, 0x77, 0x74, 0x74, 0x74, 0x74,
+    0x4d, 0x7d, 0xbe, 0x4d, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x4d, 0x2f, 0x81, 0xb8, 0x74, 0x97, 0xe3, 0x74,
+    0xdd, 0xee, 0xe4, 0x23, 0x34, 0xee, 0xee, 0xee,
+    0xdc, 0xdb, 0x64, 0xf3, 0xee, 0xf4, 0x23, 0x23,
+    0xd5, 0x94, 0x94, 0x94, 0x94, 0x96, 0x23, 0x23,
+    0x85, 0x6c, 0x94, 0xc7, 0xd2, 0xa5, 0x69, 0x74,
+    0x74, 0x74, 0x74, 0xbe, 0x74, 0x74, 0x74, 0x74,
+    0x61, 0x7d, 0x77, 0xef, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61,
+    0xe3, 0x77, 0x7d, 0xe3, 0x74, 0xa0, 0x4d, 0x61,
+    0x58, 0xfc, 0x23, 0xa5, 0x83, 0x94, 0x94, 0x94,
+    0xf3, 0xff, 0x86, 0x3e, 0x6c, 0x6c, 0x2a, 0x23,
+    0xd2, 0x94, 0x94, 0x6c, 0x6c, 0x55, 0x23, 0x23,
+    0x85, 0x94, 0x6c, 0x78, 0x23, 0x49, 0x33, 0x61,
+    0x74, 0x74, 0x61, 0xe9, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0xb8, 0xb7, 0xe3, 0x61, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d,
+    0x2f, 0x81, 0xba, 0x74, 0x74, 0xbe, 0x4d, 0x2f,
+    0xe7, 0x34, 0x23, 0xd2, 0x94, 0x6c, 0x94, 0x6c,
+    0x2c, 0x23, 0x98, 0xe7, 0xc8, 0x55, 0x23, 0xff,
+    0x9d, 0x94, 0x6c, 0x94, 0x94, 0xf4, 0x23, 0x5a,
+    0xc8, 0x94, 0x49, 0x23, 0xe6, 0x94, 0xa4, 0x61,
+    0x74, 0x74, 0x4d, 0xe9, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x81, 0x59, 0x97, 0x61, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d,
+    0xbe, 0x63, 0x61, 0x74, 0x74, 0x77, 0xef, 0x9f,
+    0x4a, 0x5a, 0x23, 0xe4, 0x6b, 0x8a, 0x2a, 0x5f,
+    0x6b, 0x23, 0xf4, 0x98, 0x2a, 0xd5, 0x49, 0x76,
+    0xaf, 0xaf, 0xaf, 0xaf, 0x76, 0x98, 0x23, 0x2a,
+    0xc8, 0xee, 0xe4, 0x86, 0xc7, 0x94, 0x3e, 0x4d,
+    0x74, 0x74, 0x97, 0xef, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x81, 0xba, 0x97, 0x61, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0xe3,
+    0x28, 0x56, 0x74, 0x74, 0xef, 0xae, 0xa0, 0xba,
+    0xdb, 0x23, 0xe4, 0x64, 0x96, 0x96, 0xdc, 0x96,
+    0x23, 0x8a, 0xea, 0x8a, 0x23, 0x34, 0x6c, 0x76,
+    0xf2, 0x3b, 0xf2, 0xf4, 0xc8, 0x78, 0x23, 0xd2,
+    0x76, 0x8a, 0x5a, 0x83, 0x94, 0x6c, 0x3e, 0xef,
+    0x74, 0x74, 0xe9, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x81, 0xba, 0x97, 0x61, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0xe3,
+    0xb7, 0xba, 0x74, 0x74, 0x74, 0xe9, 0x77, 0xae,
+    0xe6, 0x23, 0xd2, 0x6c, 0x94, 0x6c, 0x94, 0xe6,
+    0x23, 0x78, 0x3e, 0xf2, 0x23, 0xa5, 0x7a, 0x94,
+    0x6c, 0x94, 0x94, 0x6c, 0x6c, 0x86, 0x23, 0x86,
+    0x5b, 0x8a, 0x9d, 0x94, 0x94, 0x6c, 0xdf, 0x4d,
+    0x74, 0x61, 0xe9, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x81, 0x59, 0x97, 0x61, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x97,
+    0x59, 0xba, 0x74, 0x74, 0x74, 0x74, 0xe9, 0xfd,
+    0x6b, 0x23, 0x49, 0x94, 0x6c, 0x94, 0x85, 0x8a,
+    0x23, 0x96, 0xa4, 0xcb, 0x2a, 0x23, 0xf2, 0x94,
+    0x94, 0x94, 0x94, 0x94, 0x94, 0xd5, 0x23, 0x23,
+    0x5a, 0xdb, 0x94, 0x6c, 0x94, 0x94, 0xa6, 0x74,
+    0x97, 0xa0, 0x40, 0x97, 0x2f, 0xe3, 0x61, 0x74,
+    0x74, 0xb8, 0xb7, 0xe3, 0x61, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x2f,
+    0xba, 0xf1, 0x9e, 0x6f, 0xc6, 0x3d, 0x61, 0xca,
+    0xf3, 0xdb, 0x85, 0x94, 0x94, 0x6c, 0x85, 0x96,
+    0x96, 0xc7, 0xa4, 0x5c, 0x5f, 0x96, 0xfc, 0x94,
+    0x94, 0x94, 0x94, 0x94, 0x94, 0xfc, 0x96, 0xdb,
+    0x85, 0x6c, 0x94, 0x94, 0x94, 0x6c, 0x31, 0xe3,
+    0xef, 0x74, 0x74, 0x74, 0x61, 0xe3, 0x81, 0xbe,
+    0x61, 0xd0, 0x28, 0xe3, 0x61, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x61, 0x4d, 0x4d, 0xe3, 0xbe,
+    0x63, 0x8c, 0x79, 0xfa, 0xd7, 0xd7, 0x47, 0x4d,
+    0x44, 0xe7, 0x6c, 0x94, 0x94, 0x94, 0x94, 0x94,
+    0x94, 0x94, 0xa4, 0x6c, 0x6c, 0x94, 0x94, 0x6c,
+    0x94, 0x94, 0x94, 0x94, 0x6c, 0x6c, 0x94, 0x6c,
+    0x6c, 0x94, 0x94, 0x38, 0x53, 0x53, 0xc3, 0xbc,
+    0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0xbe, 0x77,
+    0x97, 0xf1, 0xb7, 0xe3, 0x61, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x61, 0xef, 0x97, 0xe9, 0xbe, 0x28, 0xae,
+    0xf1, 0xc1, 0xb5, 0xfa, 0xd7, 0xd7, 0xd7, 0xaa,
+    0x61, 0x56, 0xdf, 0x6c, 0x94, 0x94, 0x6c, 0x94,
+    0x94, 0x94, 0xa4, 0x6c, 0x94, 0x94, 0x94, 0x6c,
+    0x6c, 0x6c, 0x6c, 0x94, 0x94, 0x6c, 0x94, 0x94,
+    0x94, 0x6c, 0x6c, 0x70, 0x60, 0xfe, 0x68, 0x73,
+    0x20, 0x74, 0x74, 0x74, 0x74, 0x61, 0xe9, 0x2f,
+    0x42, 0x6e, 0xba, 0x2f, 0x61, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x61, 0xe3, 0xbe, 0x59, 0x63, 0x7d, 0xac, 0xf8,
+    0x92, 0xb0, 0xa7, 0xbd, 0xd7, 0xd7, 0xd7, 0x88,
+    0x3c, 0x74, 0x77, 0x9a, 0x94, 0x94, 0x94, 0x6c,
+    0x94, 0x94, 0x3e, 0x4a, 0x6c, 0x94, 0x94, 0x94,
+    0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+    0x6c, 0x94, 0x94, 0x70, 0xfa, 0x60, 0x7f, 0x35,
+    0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x61, 0x3d,
+    0x60, 0x68, 0xb8, 0xa0, 0x4d, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0xef, 0xbe, 0xae, 0x93, 0xc1, 0x95, 0x90, 0x90,
+    0xd3, 0xb5, 0xfa, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0xec, 0x8e, 0x74, 0x97, 0x31, 0x6c, 0x94, 0x6c,
+    0x94, 0x94, 0x94, 0x94, 0x6c, 0x94, 0x94, 0x94,
+    0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+    0x94, 0x6c, 0x5c, 0x70, 0x89, 0x7b, 0xd3, 0x73,
+    0x20, 0x74, 0x74, 0x74, 0x74, 0x74, 0x62, 0xec,
+    0x88, 0x7b, 0x99, 0xbe, 0xef, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61,
+    0x97, 0xb7, 0xc4, 0xd3, 0xb5, 0x27, 0xb5, 0xb5,
+    0xe0, 0xfa, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0x60, 0x24, 0x4d, 0x20, 0x61, 0x82, 0x4a, 0x94,
+    0x6c, 0x6c, 0x94, 0x94, 0x94, 0x6c, 0x94, 0x94,
+    0x94, 0x94, 0x6c, 0x6c, 0x94, 0x6c, 0x6c, 0x94,
+    0x94, 0x3e, 0x9a, 0xb1, 0xe0, 0xe0, 0xb0, 0x25,
+    0x40, 0x74, 0x74, 0x74, 0x61, 0xf6, 0x90, 0x89,
+    0x89, 0x89, 0xb2, 0x59, 0x97, 0x61, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d,
+    0xe9, 0xae, 0xd6, 0xb5, 0x89, 0xfa, 0xfa, 0xbd,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0xd7, 0x68, 0x26, 0x74, 0x20, 0x20, 0x81, 0x33,
+    0x94, 0x94, 0x94, 0x94, 0x94, 0x6c, 0x6c, 0x6c,
+    0x6c, 0x94, 0x94, 0x6c, 0x94, 0x94, 0x94, 0x6c,
+    0x6c, 0xa6, 0x9a, 0x8d, 0xec, 0xec, 0x79, 0x6f,
+    0x7e, 0xb3, 0x3c, 0xb3, 0xce, 0x90, 0xb5, 0x89,
+    0x7b, 0xfa, 0x6e, 0x63, 0xa0, 0xef, 0x61, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61,
+    0xe9, 0x63, 0xc1, 0xb5, 0x89, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0x88, 0x60, 0x42, 0x35, 0x74, 0x74, 0x74, 0xbe,
+    0xab, 0x6c, 0x6c, 0x94, 0x94, 0x94, 0x94, 0x94,
+    0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x6c, 0x94,
+    0x6c, 0xa6, 0x9a, 0xd9, 0xb5, 0xe0, 0x9c, 0xb0,
+    0x95, 0xcd, 0x6f, 0x90, 0xb0, 0xec, 0x7b, 0xd7,
+    0xd7, 0xbd, 0xec, 0xb2, 0xba, 0xe9, 0xef, 0x61,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d,
+    0xe9, 0x63, 0xc9, 0x9c, 0x89, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0x68, 0x4e, 0x74, 0x74, 0x74, 0x74,
+    0x63, 0x6c, 0x6c, 0x94, 0x94, 0x94, 0x94, 0x94,
+    0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+    0x6c, 0xf0, 0x9a, 0x72, 0xda, 0xe0, 0xa7, 0x9c,
+    0x79, 0xd3, 0xb0, 0x79, 0xb5, 0x89, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xfa, 0xa1, 0xa8, 0x59, 0xe9, 0xef,
+    0x61, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d,
+    0xe9, 0x56, 0xc9, 0x79, 0xe0, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0x60, 0x22, 0x62, 0x74, 0x74, 0x74,
+    0x97, 0xe7, 0x94, 0x6c, 0x94, 0x94, 0x94, 0x94,
+    0x6c, 0x6c, 0x94, 0x6c, 0x6c, 0x94, 0x94, 0x94,
+    0x6c, 0xdf, 0x37, 0xd6, 0x79, 0xe0, 0x89, 0xe0,
+    0x27, 0xb5, 0xb5, 0xec, 0xe0, 0xfa, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xbd, 0x89, 0xa1, 0xf1, 0x81, 0xa0,
+    0xef, 0x61, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61,
+    0x2f, 0xae, 0x5d, 0xd3, 0xe0, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0x68, 0x4b, 0x40, 0x74, 0x74,
+    0x77, 0x5c, 0x94, 0x6c, 0x6c, 0x6c, 0x6c, 0x94,
+    0x94, 0x6c, 0x94, 0x94, 0x94, 0x6c, 0x94, 0x94,
+    0x94, 0x33, 0x7d, 0x7e, 0x79, 0xe0, 0x7b, 0xbd,
+    0xfa, 0x89, 0x89, 0xfa, 0xfa, 0xbd, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xfa, 0xec, 0x46, 0x81,
+    0xe9, 0x4d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61,
+    0x2f, 0xae, 0x5d, 0xb0, 0xe0, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0x68, 0x3d, 0xa0, 0xf1,
+    0x33, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+    0x94, 0x94, 0x94, 0x94, 0x6c, 0x94, 0x6c, 0x94,
+    0x4a, 0xb8, 0x40, 0xe5, 0x79, 0xe0, 0xfa, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0x89, 0x5d,
+    0x77, 0xe3, 0x61, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d,
+    0xe9, 0x63, 0x5d, 0xb0, 0xe0, 0xfa, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0x68, 0xf5, 0x67, 0x94,
+    0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+    0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0xab,
+    0x59, 0x20, 0x35, 0xce, 0x79, 0xe0, 0xfa, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xbd, 0xfa, 0x72,
+    0xb7, 0x97, 0x61, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xef,
+    0xbe, 0xb8, 0xd6, 0xd3, 0xe0, 0xbd, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0x68, 0x4b, 0xf0,
+    0x6c, 0x6c, 0x94, 0x94, 0x94, 0x94, 0x6c, 0x6c,
+    0x94, 0x6c, 0x6c, 0x94, 0x94, 0x6c, 0xf7, 0x2f,
+    0x74, 0x20, 0xbc, 0xe5, 0xda, 0x89, 0xbd, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xbd, 0xe0, 0x9c, 0x46,
+    0x77, 0xe3, 0x61, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0xe3,
+    0x28, 0xc5, 0x6f, 0x9c, 0x7b, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0x88, 0x22, 0xc6, 0xd8,
+    0xdf, 0x6c, 0x6c, 0x6c, 0x6c, 0x94, 0x94, 0x6c,
+    0x94, 0x94, 0x94, 0x6c, 0x9a, 0x81, 0x20, 0x20,
+    0x74, 0x74, 0x8e, 0x7e, 0xda, 0x89, 0xbd, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xfa, 0xa7, 0xd3, 0x93, 0x81,
+    0xe9, 0x4d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x97,
+    0x59, 0xc4, 0xf9, 0xa7, 0xfa, 0xbd, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xbd, 0xe0, 0xc6, 0xe5,
+    0x62, 0x36, 0xab, 0x6c, 0x94, 0x94, 0x94, 0x6c,
+    0x4a, 0x58, 0x36, 0x81, 0x61, 0x74, 0x74, 0x74,
+    0x74, 0x20, 0x62, 0xe5, 0x79, 0xe0, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0xd7, 0x89, 0xec, 0x79, 0xc1, 0xb2, 0xae, 0xbe,
+    0xe3, 0x61, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x97,
+    0xba, 0x87, 0xf9, 0x9c, 0xe0, 0x89, 0xfa, 0xfa,
+    0xbd, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xe0, 0x79, 0x54,
+    0x51, 0x74, 0x61, 0xe9, 0xb7, 0xba, 0x28, 0xbe,
+    0xef, 0x61, 0x61, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x61, 0x51, 0xce, 0xd3, 0xe0, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0x89, 0x89,
+    0x27, 0xb0, 0xc9, 0xb2, 0xb8, 0xb7, 0xa0, 0xe3,
+    0x61, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0xe3,
+    0x77, 0xaa, 0x6f, 0x90, 0x79, 0xda, 0x9c, 0xb5,
+    0x27, 0xe0, 0x89, 0x89, 0xfa, 0xbd, 0xd7, 0xd7,
+    0xd7, 0xd7, 0xd7, 0xd7, 0xbd, 0x27, 0xb0, 0xe5,
+    0x26, 0x4d, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x20, 0xbf, 0xce, 0xf9, 0x27, 0xfa, 0xd7,
+    0xd7, 0xd7, 0xbd, 0xfa, 0x89, 0xec, 0x9c, 0xb0,
+    0xd6, 0xb2, 0x7d, 0x59, 0xbe, 0x97, 0x4d, 0x61,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xef,
+    0xa0, 0xae, 0xd8, 0x93, 0xce, 0xc0, 0x6f, 0x90,
+    0x90, 0xf9, 0xd3, 0xda, 0x9c, 0x27, 0x89, 0xd7,
+    0xd7, 0xbd, 0xbd, 0xbd, 0x89, 0x79, 0x6f, 0x32,
+    0xeb, 0x40, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
+    0x74, 0x61, 0x51, 0x32, 0x6f, 0xda, 0xe0, 0x89,
+    0xbd, 0xfa, 0x89, 0xe0, 0x9c, 0xf9, 0xcd, 0x93,
+    0xd0, 0xba, 0x9f, 0x97, 0xef, 0x61, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x61,
+    0xe3, 0xa0, 0xba, 0x63, 0xd0, 0xb2, 0xd8, 0xaa,
+    0xce, 0xce, 0x54, 0xc0, 0x6f, 0x90, 0xb0, 0xda,
+    0xb5, 0xe0, 0xe0, 0xa7, 0xda, 0x90, 0xe5, 0xe1,
+    0xbf, 0x4d, 0x74, 0x74, 0xe3, 0xbe, 0xbe, 0xbe,
+    0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x2f, 0x74,
+    0x74, 0x61, 0xf6, 0x25, 0x54, 0x95, 0xda, 0x27,
+    0xa7, 0x27, 0xda, 0xf9, 0x6f, 0x7e, 0xb2, 0xb8,
+    0x28, 0xe9, 0xef, 0x61, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74,
+    0x61, 0xef, 0x97, 0xa0, 0x9f, 0x59, 0xae, 0xb8,
+    0xa8, 0x65, 0x66, 0x45, 0xe1, 0x32, 0xe5, 0xc0,
+    0x6f, 0x90, 0xf9, 0x90, 0xc0, 0x7e, 0x6d, 0xeb,
+    0x8e, 0xb7, 0xf1, 0xa8, 0x7d, 0xb8, 0x63, 0x63,
+    0x63, 0x63, 0x63, 0x63, 0x63, 0xb8, 0x7d, 0xd0,
+    0xf1, 0xac, 0xde, 0x6d, 0x7e, 0xc0, 0x6f, 0x95,
+    0xf9, 0x95, 0xcd, 0x54, 0x4e, 0xc5, 0xae, 0x9f,
+    0x97, 0x4d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x61, 0x4d, 0xef, 0x97, 0xe9, 0xbe,
+    0x28, 0xba, 0x56, 0x44, 0xac, 0x99, 0x45, 0xb3,
+    0x25, 0x32, 0x32, 0x32, 0x25, 0xb3, 0x26, 0xde,
+    0xa8, 0xb8, 0xba, 0x77, 0xbe, 0xa0, 0xa0, 0xa0,
+    0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xbe, 0x9f,
+    0xb7, 0xb8, 0x9b, 0xbf, 0xe1, 0x7e, 0xce, 0xce,
+    0x54, 0xce, 0x32, 0x45, 0xa8, 0xba, 0xa0, 0xe3,
+    0x61, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x61, 0x4d,
+    0xe3, 0x97, 0xe9, 0x9f, 0x28, 0x81, 0x7d, 0xa8,
+    0xfb, 0x26, 0x26, 0x26, 0xeb, 0xbf, 0xad, 0x44,
+    0xba, 0xbe, 0x97, 0xef, 0x4d, 0x4d, 0x4d, 0x4d,
+    0x4d, 0x4d, 0x61, 0x4d, 0x4d, 0x4d, 0x4d, 0xef,
+    0x97, 0x9f, 0xae, 0x9b, 0x51, 0xeb, 0x6d, 0x25,
+    0x6d, 0xb3, 0xfb, 0x7d, 0x59, 0xe9, 0xef, 0x61,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x61, 0x4d, 0xef, 0xe3, 0x2f, 0xbe, 0xb7,
+    0xae, 0x7d, 0xbb, 0x9b, 0x9b, 0xfd, 0x56, 0x28,
+    0xe9, 0xef, 0x61, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x61, 0xe3, 0xe9, 0x59, 0xb8, 0x9b, 0x9b, 0x9b,
+    0x71, 0x71, 0x56, 0x28, 0x2f, 0xef, 0x61, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x61, 0x61, 0xef, 0xe3,
+    0xe9, 0xbe, 0x77, 0x28, 0x28, 0x9f, 0xe9, 0xe3,
+    0x4d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x61, 0xef, 0x2f, 0xbe, 0x77, 0xb7, 0x59,
+    0xb7, 0x9f, 0xe9, 0xe3, 0x4d, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61,
+    0x61, 0x4d, 0xef, 0x35, 0xe3, 0xef, 0x4d, 0x61,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x61, 0x40, 0xe3, 0x97, 0x97,
+    0xe3, 0xef, 0x4d, 0x61, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
+};
+
+#endif /* !__HAVE_ARCH_LINUX_LOGO */
+
+#ifndef __HAVE_ARCH_LINUX_LOGOBW
+
+unsigned char linux_logo_bw[] __initdata = {
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xcf, 0xf3, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xbf, 0xfc, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfd, 0xff, 0xf3, 0xdf, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfd, 0xff, 0xf7, 0xef, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x9f, 0x87, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x0f, 0x03, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x67, 0x33, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xe7, 0x79, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xf7, 0x79, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0xf9, 0xf7, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x60, 0x3b, 0xf7, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x89, 0x07, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x00, 0x03, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x00, 0x0d, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x80, 0x33, 0xfd, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xc0, 0xc3, 0xfd, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0x0d, 0xdd, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x40, 0x31, 0xee, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf7, 0x20, 0xc1, 0xee, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf7, 0x1f, 0x00, 0xff, 0x7f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x7f, 0xbf, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xee, 0x00, 0x00, 0x7f, 0xbf, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xde, 0x00, 0x00, 0x7f, 0xdf, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xbc, 0x00, 0x00, 0x3f, 0xef, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x3f, 0xf7, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x1f, 0xf7, 0xff, 0xff,
+    0xff, 0xff, 0xfe, 0xff, 0x1c, 0x07, 0xdf, 0xfb, 0xff, 0xff,
+    0xff, 0xff, 0xfd, 0xfc, 0x08, 0x0f, 0xef, 0xfd, 0xff, 0xff,
+    0xff, 0xff, 0xfd, 0xf8, 0x00, 0x01, 0xef, 0xfd, 0xff, 0xff,
+    0xff, 0xff, 0xfb, 0xf0, 0x00, 0x00, 0x7f, 0xfe, 0xff, 0xff,
+    0xff, 0xff, 0xfb, 0xe0, 0x00, 0x00, 0x1f, 0xfe, 0xff, 0xff,
+    0xff, 0xff, 0xf7, 0xe0, 0x00, 0x00, 0x07, 0xbf, 0x7f, 0xff,
+    0xff, 0xff, 0xf7, 0xc0, 0x00, 0x00, 0x03, 0xbf, 0x7f, 0xff,
+    0xff, 0xff, 0xef, 0xc0, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
+    0xff, 0xff, 0xef, 0x80, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
+    0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
+    0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x03, 0x03, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x02, 0xfd, 0xdf, 0xff,
+    0xff, 0xff, 0xa3, 0x80, 0x00, 0x00, 0x1f, 0xff, 0xdf, 0xff,
+    0xff, 0xff, 0xc1, 0xc0, 0x00, 0x00, 0x11, 0xff, 0x3f, 0xff,
+    0xff, 0xff, 0x80, 0xe0, 0x00, 0x00, 0x21, 0xfe, 0x3f, 0xff,
+    0xff, 0xff, 0x00, 0x70, 0x00, 0x00, 0x21, 0xfc, 0x3f, 0xff,
+    0xff, 0xfe, 0x00, 0x3c, 0x00, 0x00, 0x20, 0xf8, 0x3f, 0xff,
+    0xff, 0xf0, 0x00, 0x3e, 0x00, 0x00, 0x20, 0x00, 0x3f, 0xff,
+    0xff, 0xc0, 0x00, 0x1f, 0x00, 0x00, 0x20, 0x00, 0x3f, 0xff,
+    0xff, 0xc0, 0x00, 0x1f, 0x80, 0x00, 0x20, 0x00, 0x1f, 0xff,
+    0xff, 0xc0, 0x00, 0x0f, 0x80, 0x00, 0x20, 0x00, 0x07, 0xff,
+    0xff, 0xc0, 0x00, 0x07, 0x80, 0x00, 0x20, 0x00, 0x03, 0xff,
+    0xff, 0xc0, 0x00, 0x07, 0x80, 0x00, 0x60, 0x00, 0x01, 0xff,
+    0xff, 0xc0, 0x00, 0x02, 0x00, 0x00, 0xe0, 0x00, 0x01, 0xff,
+    0xff, 0xc0, 0x00, 0x01, 0x00, 0x01, 0xe0, 0x00, 0x01, 0xff,
+    0xff, 0xc0, 0x00, 0x00, 0x80, 0x07, 0xe0, 0x00, 0x03, 0xff,
+    0xff, 0xc0, 0x00, 0x00, 0x80, 0x3f, 0xe0, 0x00, 0x0f, 0xff,
+    0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x1f, 0xff,
+    0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x7f, 0xff,
+    0xff, 0xe0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0xff, 0xff,
+    0xff, 0xfc, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x03, 0xff, 0xff,
+    0xff, 0xff, 0xc0, 0x00, 0x70, 0x00, 0xc0, 0x07, 0xff, 0xff,
+    0xff, 0xff, 0xfc, 0x00, 0x8f, 0xff, 0x20, 0x0f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+
+#endif /* !__HAVE_ARCH_LINUX_LOGOBW */
+
+#ifndef __HAVE_ARCH_LINUX_LOGO16
+
+unsigned char linux_logo16[] __initdata = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x88, 0x88, 0x88, 0x80, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x88, 0x80, 0x00, 0x00, 0x08, 0x88, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80,
+    0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x08, 0x70, 0x00, 0x00, 0x00, 0x77, 0x70, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x87, 0x77, 0x00, 0x00, 0x07, 0xff, 0xf7, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+    0x77, 0xff, 0x00, 0x00, 0x7f, 0x77, 0xf7, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+    0x70, 0x0f, 0x80, 0x00, 0xf7, 0x08, 0x7f, 0x70,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+    0x80, 0x07, 0x80, 0x00, 0xf8, 0x00, 0x8f, 0x70,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+    0x70, 0x07, 0x88, 0x88, 0xf8, 0x00, 0x8f, 0x70,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0xf0, 0x06, 0xe6, 0xe6, 0xe6, 0x00, 0x8f, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x77, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x77, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x06, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60,
+    0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x60,
+    0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66, 0x66, 0x80,
+    0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
+    0x86, 0xe6, 0xe6, 0xe6, 0x66, 0x66, 0x66, 0x80,
+    0x08, 0x78, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
+    0x86, 0x66, 0x66, 0x66, 0x66, 0x66, 0x77, 0x70,
+    0x00, 0x77, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x87, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x78,
+    0x00, 0x88, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x87, 0x76, 0x66, 0x66, 0x77, 0x77, 0xff, 0xf7,
+    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08,
+    0xff, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff,
+    0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07,
+    0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff,
+    0x70, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x8f,
+    0xff, 0xf7, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff,
+    0xf0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x7f,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf8, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x87, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x77,
+    0xff, 0xf7, 0x77, 0xff, 0xff, 0xff, 0x77, 0x77,
+    0x77, 0x78, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x7f,
+    0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x77,
+    0x77, 0x78, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x7f, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x77, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x80, 0x80, 0x08, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x77, 0x80, 0x00, 0x08, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x08, 0x00, 0x80, 0x07, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0x78, 0x00, 0x08, 0x80, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x08, 0x08, 0x00, 0x8f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xf7, 0x08, 0x80, 0x80, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xf7, 0x08, 0x80, 0x80, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x08, 0x07, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x80, 0x00, 0x08, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x80, 0x0f, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x08, 0x00, 0x80, 0x8f, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x08, 0x08, 0x00, 0x7f, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x80, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x08, 0x08, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x08, 0x08, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x88, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x88, 0x88, 0x80, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x06, 0xe6, 0x00, 0x8f, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x08, 0x80,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x6e, 0x6e, 0x60, 0x08, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x88,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x06, 0xe6, 0xe6, 0xe6, 0x00, 0x8f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xfe, 0x6e, 0x60, 0x00, 0x00, 0x00, 0x00,
+    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x08, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xf6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x06,
+    0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x8f, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xfe, 0x6e, 0x60, 0x00, 0x00, 0x00, 0x0e,
+    0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x00, 0x08, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x76, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0xe6,
+    0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x8f,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x7e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x00, 0x08,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x76, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00,
+    0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x7e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x00,
+    0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x76, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00,
+    0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x8e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x88,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0x78, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xef,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7,
+    0x80, 0x06, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78,
+    0x00, 0x06, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x80,
+    0x00, 0x06, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x0e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
+    0x67, 0xff, 0xff, 0xff, 0xff, 0x78, 0x80, 0x00,
+    0x00, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x06, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x86, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x66, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x0e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
+    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x86, 0x6e, 0x6e, 0x6e, 0x6e, 0x66, 0x66,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66,
+    0x66, 0x66, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
+    0x60, 0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x80,
+    0x00, 0x06, 0x66, 0xe6, 0xe6, 0xe6, 0x66, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x66, 0x66, 0x66, 0x66, 0xe6, 0xe6, 0x66,
+    0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+    0x88, 0x86, 0x66, 0x6e, 0x6e, 0x66, 0x60, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x06, 0x66, 0x66, 0x66, 0x66,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x06, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x06, 0x66, 0x66, 0x60,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x66, 0x66, 0x66, 0x60, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+#endif /* !__HAVE_ARCH_LINUX_LOGO16 */
+
+#else /* !INCLUDE_LINUX_LOGO_DATA */
+
+/* prototypes only */
+extern unsigned char linux_logo_red[];
+extern unsigned char linux_logo_green[];
+extern unsigned char linux_logo_blue[];
+extern unsigned char linux_logo[];
+extern unsigned char linux_logo_bw[];
+extern unsigned char linux_logo16[];
+
+#endif /* !INCLUDE_LINUX_LOGO_DATA */
diff -urN linux-2.4.29/include/asm-frv/math-emu.h linux-2.4.29-uc1/include/asm-frv/math-emu.h
--- linux-2.4.29/include/asm-frv/math-emu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/math-emu.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,301 @@
+#ifndef _ASM_MATH_EMU_H
+#define _ASM_MATH_EMU_H
+
+#include <asm/setup.h>
+#include <linux/linkage.h>
+
+/* Status Register bits */
+
+/* accrued exception bits */
+#define FPSR_AEXC_INEX	3
+#define FPSR_AEXC_DZ	4
+#define FPSR_AEXC_UNFL	5
+#define FPSR_AEXC_OVFL	6
+#define FPSR_AEXC_IOP	7
+
+/* exception status bits */
+#define FPSR_EXC_INEX1	8
+#define FPSR_EXC_INEX2	9
+#define FPSR_EXC_DZ	10
+#define FPSR_EXC_UNFL	11
+#define FPSR_EXC_OVFL	12
+#define FPSR_EXC_OPERR	13
+#define FPSR_EXC_SNAN	14
+#define FPSR_EXC_BSUN	15
+
+/* quotient byte, assumes big-endian, of course */
+#define FPSR_QUOTIENT(fpsr) (*((signed char *) &(fpsr) + 1))
+
+/* condition code bits */
+#define FPSR_CC_NAN	24
+#define FPSR_CC_INF	25
+#define FPSR_CC_Z	26
+#define FPSR_CC_NEG	27
+
+
+/* Control register bits */
+
+/* rounding mode */
+#define	FPCR_ROUND_RN	0		/* round to nearest/even */
+#define FPCR_ROUND_RZ	1		/* round to zero */
+#define FPCR_ROUND_RM	2		/* minus infinity */
+#define FPCR_ROUND_RP	3		/* plus infinity */
+
+/* rounding precision */
+#define FPCR_PRECISION_X	0	/* long double */
+#define FPCR_PRECISION_S	1	/* double */
+#define FPCR_PRECISION_D	2	/* float */
+
+
+/* Flags to select the debugging output */
+#define PDECODE		0
+#define PEXECUTE	1
+#define PCONV		2
+#define PNORM		3
+#define PREGISTER	4
+#define PINSTR		5
+#define PUNIMPL		6
+#define PMOVEM		7
+
+#define PMDECODE	(1<<PDECODE)
+#define PMEXECUTE	(1<<PEXECUTE)
+#define PMCONV		(1<<PCONV)
+#define PMNORM		(1<<PNORM)
+#define PMREGISTER	(1<<PREGISTER)
+#define PMINSTR		(1<<PINSTR)
+#define PMUNIMPL	(1<<PUNIMPL)
+#define PMMOVEM		(1<<PMOVEM)
+
+#ifndef __ASSEMBLY__
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+union fp_mant64 {
+	unsigned long long m64;
+	unsigned long m32[2];
+};
+
+union fp_mant128 {
+	unsigned long long m64[2];
+	unsigned long m32[4];
+};
+
+/* internal representation of extended fp numbers */
+struct fp_ext {
+	unsigned char lowmant;
+	unsigned char sign;
+	unsigned short exp;
+	union fp_mant64 mant;
+};
+
+/* C representation of FPU registers */
+/* NOTE: if you change this, you have to change the assembler offsets
+   below and the size in <asm/fpu.h>, too */
+struct fp_data {
+	struct fp_ext fpreg[8];
+	unsigned int fpcr;
+	unsigned int fpsr;
+	unsigned int fpiar;
+	unsigned short prec;
+	unsigned short rnd;
+	struct fp_ext temp[2];
+};
+
+#if FPU_EMU_DEBUG
+extern unsigned int fp_debugprint;
+
+#define dprint(bit, fmt, args...) ({			\
+	if (fp_debugprint & (1 << (bit)))		\
+		printk(fmt, ## args);			\
+})
+#else
+#define dprint(bit, fmt, args...)
+#endif
+
+#define uprint(str) ({					\
+	static int __count = 3;				\
+							\
+	if (__count > 0) {				\
+		printk("You just hit an unimplemented "	\
+		       "fpu instruction (%s)\n", str);	\
+		printk("Please report this to ....\n");	\
+		__count--;				\
+	}						\
+})
+
+#define FPDATA		((struct fp_data *)current->thread.fp)
+
+#else	/* __ASSEMBLY__ */
+
+#define FPDATA		%a2
+
+/* offsets from the base register to the floating point data in the task struct */
+#define FPD_FPREG	(TASK_THREAD+THREAD_FPREG+0)
+#define FPD_FPCR	(TASK_THREAD+THREAD_FPREG+96)
+#define FPD_FPSR	(TASK_THREAD+THREAD_FPREG+100)
+#define FPD_FPIAR	(TASK_THREAD+THREAD_FPREG+104)
+#define FPD_PREC	(TASK_THREAD+THREAD_FPREG+108)
+#define FPD_RND		(TASK_THREAD+THREAD_FPREG+110)
+#define FPD_TEMPFP1	(TASK_THREAD+THREAD_FPREG+112)
+#define FPD_TEMPFP2	(TASK_THREAD+THREAD_FPREG+124)
+#define FPD_SIZEOF	(TASK_THREAD+THREAD_FPREG+136)
+
+/* offsets on the stack to access saved registers,
+ * these are only used during instruction decoding
+ * where we always know how deep we're on the stack.
+ */
+#define FPS_DO		(PT_D0)
+#define FPS_D1		(PT_D1)
+#define FPS_D2		(PT_D2)
+#define FPS_A0		(PT_A0)
+#define FPS_A1		(PT_A1)
+#define FPS_A2		(PT_A2)
+#define FPS_SR		(PT_SR)
+#define FPS_PC		(PT_PC)
+#define FPS_EA		(PT_PC+6)
+#define FPS_PC2		(PT_PC+10)
+
+.macro	fp_get_fp_reg
+	lea	(FPD_FPREG,FPDATA,%d0.w*4),%a0
+	lea	(%a0,%d0.w*8),%a0
+.endm
+
+/* Macros used to get/put the current program counter.
+ * 020/030 use a different stack frame then 040/060, for the
+ * 040/060 the return pc points already to the next location,
+ * so this only needs to be modified for jump instructions.
+ */
+.macro	fp_get_pc dest
+	move.l	(FPS_PC+4,%sp),\dest
+.endm
+
+.macro	fp_put_pc src,jump=0
+	move.l	\src,(FPS_PC+4,%sp)
+.endm
+
+.macro	fp_get_instr_data	f,s,dest,label
+	getuser	\f,%sp@(FPS_PC+4)@(0),\dest,\label,%sp@(FPS_PC+4)
+	addq.l	#\s,%sp@(FPS_PC+4)
+.endm
+
+.macro	fp_get_instr_word	dest,label,addr
+	fp_get_instr_data	w,2,\dest,\label,\addr
+.endm
+
+.macro	fp_get_instr_long	dest,label,addr
+	fp_get_instr_data	l,4,\dest,\label,\addr
+.endm
+
+/* These macros are used to read from/write to user space
+ * on error we jump to the fixup section, load the fault
+ * address into %a0 and jump to the exit.
+ * (derived from <asm/uaccess.h>)
+ */
+.macro	getuser	size,src,dest,label,addr
+|	printf	,"[\size<%08x]",1,\addr
+.Lu1\@:	moves\size	\src,\dest
+
+	.section .fixup,"ax"
+	.even
+.Lu2\@:	move.l	\addr,%a0
+	jra	\label
+	.previous
+
+	.section __ex_table,"a"
+	.align	4
+	.long	.Lu1\@,.Lu2\@
+	.previous
+.endm
+
+.macro	putuser	size,src,dest,label,addr
+|	printf	,"[\size>%08x]",1,\addr
+.Lu1\@:	moves\size	\src,\dest
+.Lu2\@:
+
+	.section .fixup,"ax"
+	.even
+.Lu3\@:	move.l	\addr,%a0
+	jra	\label
+	.previous
+
+	.section __ex_table,"a"
+	.align	4
+	.long	.Lu1\@,.Lu3\@
+	.long	.Lu2\@,.Lu3\@
+	.previous
+.endm
+
+
+.macro	movestack	nr,arg1,arg2,arg3,arg4,arg5
+	.if	\nr
+	movestack	(\nr-1),\arg2,\arg3,\arg4,\arg5
+	move.l	\arg1,-(%sp)
+	.endif
+.endm
+
+.macro	printf	bit=-1,string,nr=0,arg1,arg2,arg3,arg4,arg5
+#ifdef FPU_EMU_DEBUG
+	.data
+.Lpdata\@:
+	.string	"\string"
+	.previous
+
+	movem.l	%d0/%d1/%a0/%a1,-(%sp)
+	.if	\bit+1
+#if 0
+	moveq	#\bit,%d0
+	andw	#7,%d0
+	btst	%d0,fp_debugprint+((31-\bit)/8)
+#else
+	btst	#\bit,fp_debugprint+((31-\bit)/8)
+#endif
+	jeq	.Lpskip\@
+	.endif
+	movestack	\nr,\arg1,\arg2,\arg3,\arg4,\arg5
+	pea	.Lpdata\@
+	jsr	printk
+	lea	((\nr+1)*4,%sp),%sp
+.Lpskip\@:
+	movem.l	(%sp)+,%d0/%d1/%a0/%a1
+#endif
+.endm
+
+.macro	printx	bit,fp
+#ifdef FPU_EMU_DEBUG
+	movem.l	%d0/%a0,-(%sp)
+	lea	\fp,%a0
+#if 0
+	moveq	#'+',%d0
+	tst.w	(%a0)
+	jeq	.Lx1\@
+	moveq	#'-',%d0
+.Lx1\@:	printf	\bit," %c",1,%d0
+	move.l	(4,%a0),%d0
+	bclr	#31,%d0
+	jne	.Lx2\@
+	printf	\bit,"0."
+	jra	.Lx3\@
+.Lx2\@:	printf	\bit,"1."
+.Lx3\@:	printf	\bit,"%08x%08x",2,%d0,%a0@(8)
+	move.w	(2,%a0),%d0
+	ext.l	%d0
+	printf	\bit,"E%04x",1,%d0
+#else
+	printf	\bit," %08x%08x%08x",3,%a0@,%a0@(4),%a0@(8)
+#endif
+	movem.l	(%sp)+,%d0/%a0
+#endif
+.endm
+
+.macro	debug	instr,args
+#ifdef FPU_EMU_DEBUG
+	\instr	\args
+#endif
+.endm
+
+
+#endif	/* __ASSEMBLY__ */
+
+#endif	/* _ASM_FRV_MATH_EMU_H */
+
diff -urN linux-2.4.29/include/asm-frv/mb86943a.h linux-2.4.29-uc1/include/asm-frv/mb86943a.h
--- linux-2.4.29/include/asm-frv/mb86943a.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/mb86943a.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,39 @@
+/* mb86943a.h: MB86943 SPARClite <-> PCI bridge registers
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB86943A_H
+#define _ASM_MB86943A_H
+
+#include <asm/mb-regs.h>
+
+#define __reg_MB86943_sl_ctl		*(volatile uint32_t *) (__region_CS1 + 0x00)
+
+#define MB86943_SL_CTL_BUS_WIDTH_64	0x00000001
+#define MB86943_SL_CTL_AS_HOST		0x00000002
+#define MB86943_SL_CTL_DRCT_MASTER_SWAP	0x00000004
+#define MB86943_SL_CTL_DRCT_SLAVE_SWAP	0x00000008
+#define MB86943_SL_CTL_PCI_CONFIG_SWAP	0x00000010
+#define MB86943_SL_CTL_ECS0_ENABLE	0x00000020
+#define MB86943_SL_CTL_ECS1_ENABLE	0x00000040
+#define MB86943_SL_CTL_ECS2_ENABLE	0x00000080
+
+#define __reg_MB86943_ecs_ctl(N)	*(volatile uint32_t *) (__region_CS1 + 0x08 + (0x08*(N)))
+#define __reg_MB86943_ecs_range(N)	*(volatile uint32_t *) (__region_CS1 + 0x20 + (0x10*(N)))
+#define __reg_MB86943_ecs_base(N)	*(volatile uint32_t *) (__region_CS1 + 0x28 + (0x10*(N)))
+
+#define __reg_MB86943_sl_pci_io_range	*(volatile uint32_t *) (__region_CS1 + 0x50)
+#define __reg_MB86943_sl_pci_io_base	*(volatile uint32_t *) (__region_CS1 + 0x58)
+#define __reg_MB86943_sl_pci_mem_range	*(volatile uint32_t *) (__region_CS1 + 0x60)
+#define __reg_MB86943_sl_pci_mem_base	*(volatile uint32_t *) (__region_CS1 + 0x68)
+#define __reg_MB86943_pci_sl_io_base	*(volatile uint32_t *) (__region_CS1 + 0x70)
+#define __reg_MB86943_pci_sl_mem_base	*(volatile uint32_t *) (__region_CS1 + 0x78)
+
+#endif /* _ASM_MB86943A_H */
diff -urN linux-2.4.29/include/asm-frv/mb93091-fpga-irqs.h linux-2.4.29-uc1/include/asm-frv/mb93091-fpga-irqs.h
--- linux-2.4.29/include/asm-frv/mb93091-fpga-irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/mb93091-fpga-irqs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,44 @@
+/* mb93091-fpga-irqs.h: MB93091 CPU board FPGA IRQs
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB93091_FPGA_IRQS_H
+#define _ASM_MB93091_FPGA_IRQS_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/irq-routing.h>
+
+#define IRQ_BASE_FPGA		(NR_IRQ_ACTIONS_PER_GROUP * 1)
+
+/* IRQ IDs presented to drivers */
+enum {
+	IRQ_FPGA__UNUSED			= IRQ_BASE_FPGA,
+	IRQ_FPGA_SYSINT_BUS_EXPANSION_1,
+	IRQ_FPGA_SL_BUS_EXPANSION_2,
+	IRQ_FPGA_PCI_INTD,
+	IRQ_FPGA_PCI_INTC,
+	IRQ_FPGA_PCI_INTB,
+	IRQ_FPGA_PCI_INTA,
+	IRQ_FPGA_SL_BUS_EXPANSION_7,
+	IRQ_FPGA_SYSINT_BUS_EXPANSION_8,
+	IRQ_FPGA_SL_BUS_EXPANSION_9,
+	IRQ_FPGA_MB86943_PCI_INTA,
+	IRQ_FPGA_MB86943_SLBUS_SIDE,
+	IRQ_FPGA_RTL8029_INTA,
+	IRQ_FPGA_SYSINT_BUS_EXPANSION_13,
+	IRQ_FPGA_SL_BUS_EXPANSION_14,
+	IRQ_FPGA_NMI,
+};
+
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_MB93091_FPGA_IRQS_H */
diff -urN linux-2.4.29/include/asm-frv/mb93093-fpga-irqs.h linux-2.4.29-uc1/include/asm-frv/mb93093-fpga-irqs.h
--- linux-2.4.29/include/asm-frv/mb93093-fpga-irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/mb93093-fpga-irqs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,31 @@
+/* mb93093-fpga-irqs.h: MB93093 CPU board FPGA IRQs
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB93093_FPGA_IRQS_H
+#define _ASM_MB93093_FPGA_IRQS_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/irq-routing.h>
+
+#define IRQ_BASE_FPGA		(NR_IRQ_ACTIONS_PER_GROUP * 1)
+
+/* IRQ IDs presented to drivers */
+enum {
+	IRQ_FPGA_PUSH_BUTTON_SW1_5		= IRQ_BASE_FPGA + 8,
+	IRQ_FPGA_ROCKER_C_SW8			= IRQ_BASE_FPGA + 9,
+	IRQ_FPGA_ROCKER_C_SW9			= IRQ_BASE_FPGA + 10,
+};
+
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_MB93093_FPGA_IRQS_H */
diff -urN linux-2.4.29/include/asm-frv/mb93493-irqs.h linux-2.4.29-uc1/include/asm-frv/mb93493-irqs.h
--- linux-2.4.29/include/asm-frv/mb93493-irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/mb93493-irqs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,52 @@
+/* mb93493-irqs.h: MB93493 companion chip IRQs
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB93493_IRQS_H
+#define _ASM_MB93493_IRQS_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/irq-routing.h>
+
+#define IRQ_BASE_MB93493	(NR_IRQ_ACTIONS_PER_GROUP * 2)
+
+/* IRQ IDs presented to drivers */
+enum {
+	IRQ_MB93493_VDC			= IRQ_BASE_MB93493 + 0,
+	IRQ_MB93493_VCC			= IRQ_BASE_MB93493 + 1,
+	IRQ_MB93493_AUDIO_OUT		= IRQ_BASE_MB93493 + 2,
+	IRQ_MB93493_I2C_0		= IRQ_BASE_MB93493 + 3,
+	IRQ_MB93493_I2C_1		= IRQ_BASE_MB93493 + 4,
+	IRQ_MB93493_USB			= IRQ_BASE_MB93493 + 5,
+	IRQ_MB93493_LOCAL_BUS		= IRQ_BASE_MB93493 + 7,
+	IRQ_MB93493_PCMCIA		= IRQ_BASE_MB93493 + 8,
+	IRQ_MB93493_GPIO		= IRQ_BASE_MB93493 + 9,
+	IRQ_MB93493_AUDIO_IN		= IRQ_BASE_MB93493 + 10,
+};
+
+/* IRQ multiplexor mappings */
+#define ROUTE_VIA_IRQ0	0	/* route IRQ by way of CPU external IRQ 0 */
+#define ROUTE_VIA_IRQ1	1	/* route IRQ by way of CPU external IRQ 1 */
+
+#define IRQ_MB93493_VDC_ROUTE		ROUTE_VIA_IRQ0
+#define IRQ_MB93493_VCC_ROUTE		ROUTE_VIA_IRQ1
+#define IRQ_MB93493_AUDIO_OUT_ROUTE	ROUTE_VIA_IRQ1
+#define IRQ_MB93493_I2C_0_ROUTE		ROUTE_VIA_IRQ1
+#define IRQ_MB93493_I2C_1_ROUTE		ROUTE_VIA_IRQ1
+#define IRQ_MB93493_USB_ROUTE		ROUTE_VIA_IRQ1
+#define IRQ_MB93493_LOCAL_BUS_ROUTE	ROUTE_VIA_IRQ1
+#define IRQ_MB93493_PCMCIA_ROUTE	ROUTE_VIA_IRQ1
+#define IRQ_MB93493_GPIO_ROUTE		ROUTE_VIA_IRQ1
+#define IRQ_MB93493_AUDIO_IN_ROUTE	ROUTE_VIA_IRQ1
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_MB93493_IRQS_H */
diff -urN linux-2.4.29/include/asm-frv/mb93493-regs.h linux-2.4.29-uc1/include/asm-frv/mb93493-regs.h
--- linux-2.4.29/include/asm-frv/mb93493-regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/mb93493-regs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,279 @@
+/* mb93493-regs.h: MB93493 companion chip registers
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB93493_REGS_H
+#define _ASM_MB93493_REGS_H
+
+#include <asm/mb-regs.h>
+#include <asm/mb93493-irqs.h>
+
+#define __get_MB93493(X)	({ *(volatile unsigned long *)(__region_CS3 + (X)); })
+
+#define __set_MB93493(X,V)						\
+do {									\
+	*(volatile unsigned long *)(__region_CS3 + (X)) = (V); mb();	\
+} while(0)
+
+#define __get_MB93493_STSR(X)	__get_MB93493(0x3c0 + (X) * 4)
+#define __set_MB93493_STSR(X,V)	__set_MB93493(0x3c0 + (X) * 4, (V))
+#define MB93493_STSR_EN
+
+#define __get_MB93493_IQSR(X)	__get_MB93493(0x3d0 + (X) * 4)
+#define __set_MB93493_IQSR(X,V)	__set_MB93493(0x3d0 + (X) * 4, (V))
+
+#define __get_MB93493_DQSR(X)	__get_MB93493(0x3e0 + (X) * 4)
+#define __set_MB93493_DQSR(X,V)	__set_MB93493(0x3e0 + (X) * 4, (V))
+
+#define __get_MB93493_LBSER()	__get_MB93493(0x3f0)
+#define __set_MB93493_LBSER(V)	__set_MB93493(0x3f0, (V))
+
+#define MB93493_LBSER_VDC	0x00010000
+#define MB93493_LBSER_VCC	0x00020000
+#define MB93493_LBSER_AUDIO	0x00040000
+#define MB93493_LBSER_I2C_0	0x00080000
+#define MB93493_LBSER_I2C_1	0x00100000
+#define MB93493_LBSER_USB	0x00200000
+#define MB93493_LBSER_GPIO	0x00800000
+#define MB93493_LBSER_PCMCIA	0x01000000
+
+#define __get_MB93493_LBSR()	__get_MB93493(0x3fc)
+#define __set_MB93493_LBSR(V)	__set_MB93493(0x3fc, (V))
+
+/*
+ * video display controller
+ */
+#define __get_MB93493_VDC(X)	__get_MB93493(MB93493_VDC_##X)
+#define __set_MB93493_VDC(X,V)	__set_MB93493(MB93493_VDC_##X, (V))
+
+#define MB93493_VDC_RCURSOR	0x140	/* cursor position */
+#define MB93493_VDC_RCT1	0x144	/* cursor colour 1 */
+#define MB93493_VDC_RCT2	0x148	/* cursor colour 2 */
+#define MB93493_VDC_RHDC	0x150	/* horizontal display period */
+#define MB93493_VDC_RH_MARGINS	0x154	/* horizontal margin sizes */
+#define MB93493_VDC_RVDC	0x158	/* vertical display period */
+#define MB93493_VDC_RV_MARGINS	0x15c	/* vertical margin sizes */
+#define MB93493_VDC_RC		0x170	/* VDC control */
+#define MB93493_VDC_RCLOCK	0x174	/* clock divider, DMA req delay */
+#define MB93493_VDC_RBLACK	0x178	/* black insert sizes */
+#define MB93493_VDC_RS		0x17c	/* VDC status */
+
+#define __addr_MB93493_VDC_BCI(X)  ({ (volatile unsigned long *)(__region_CS3 + 0x000 + (X)); })
+#define __addr_MB93493_VDC_TPO(X)  (__region_CS3 + 0x1c0 + (X))
+
+#define VDC_TPO_WIDTH		32
+
+#define VDC_RC_DSR		0x00000080	/* VDC master reset */
+
+#define VDC_RS_IT		0x00060000	/* interrupt indicators */
+#define VDC_RS_IT_UNDERFLOW	0x00040000	/* - underflow event */
+#define VDC_RS_IT_VSYNC		0x00020000	/* - VSYNC event */
+#define VDC_RS_DFI		0x00010000	/* current interlace field number */
+#define VDC_RS_DFI_TOP		0x00000000	/* - top field */
+#define VDC_RS_DFI_BOTTOM	0x00010000	/* - bottom field */
+#define VDC_RS_DCSR		0x00000010	/* cursor state */
+#define VDC_RS_DCM		0x00000003	/* display mode */
+#define VDC_RS_DCM_DISABLED	0x00000000	/* - display disabled */
+#define VDC_RS_DCM_STOPPED	0x00000001	/* - VDC stopped */
+#define VDC_RS_DCM_FREERUNNING	0x00000002	/* - VDC free-running */
+#define VDC_RS_DCM_TRANSFERRING	0x00000003	/* - data being transferred to VDC */
+
+/*
+ * video capture controller
+ */
+#define __get_MB93493_VCC(X)	__get_MB93493(MB93493_VCC_##X)
+#define __set_MB93493_VCC(X,V)	__set_MB93493(MB93493_VCC_##X, (V))
+
+#define MB93493_VCC_RREDUCT	0x104	/* reduction rate */
+#define MB93493_VCC_RHY		0x108	/* horizontal brightness filter coefficients */
+#define MB93493_VCC_RHC		0x10c	/* horizontal colour-difference filter coefficients */
+#define MB93493_VCC_RHSIZE	0x110	/* horizontal cycle sizes */
+#define MB93493_VCC_RHBC	0x114	/* horizontal back porch size */
+#define MB93493_VCC_RVCC	0x118	/* vertical capture period */
+#define MB93493_VCC_RVBC	0x11c	/* vertical back porch period */
+#define MB93493_VCC_RV		0x120	/* vertical filter coefficients */
+#define MB93493_VCC_RDTS	0x128	/* DMA transfer size */
+#define MB93493_VCC_RDTS_4B	0x01000000	/* 4-byte transfer */
+#define MB93493_VCC_RDTS_32B	0x03000000	/* 32-byte transfer */
+#define MB93493_VCC_RDTS_SHIFT	24
+#define MB93493_VCC_RCC		0x130	/* VCC control */
+#define MB93493_VCC_RIS		0x134	/* VCC interrupt status */
+
+#define __addr_MB93493_VCC_TPI(X)  (__region_CS3 + 0x180 + (X))
+
+#define VCC_RHSIZE_RHCC		0x000007ff
+#define VCC_RHSIZE_RHCC_SHIFT	0
+#define VCC_RHSIZE_RHTCC	0x0fff0000
+#define VCC_RHSIZE_RHTCC_SHIFT	16
+
+#define VCC_RVBC_RVBC		0x00003f00
+#define VCC_RVBC_RVBC_SHIFT	8
+
+#define VCC_RREDUCT_RHR		0x07ff0000
+#define VCC_RREDUCT_RHR_SHIFT	16
+#define VCC_RREDUCT_RVR		0x000007ff
+#define VCC_RREDUCT_RVR_SHIFT	0
+
+#define VCC_RCC_CE		0x00000001	/* VCC enable */
+#define VCC_RCC_CS		0x00000002	/* request video capture start */
+#define VCC_RCC_CPF		0x0000000c	/* pixel format */
+#define VCC_RCC_CPF_YCBCR_16	0x00000000	/* - YCbCr 4:2:2 16-bit format */
+#define VCC_RCC_CPF_RGB		0x00000004	/* - RGB 4:4:4 format */
+#define VCC_RCC_CPF_YCBCR_24	0x00000008	/* - YCbCr 4:2:2 24-bit format */
+#define VCC_RCC_CPF_BT656	0x0000000c	/* - ITU R-BT.656 format */
+#define VCC_RCC_CPF_SHIFT	2
+#define VCC_RCC_CSR		0x00000080	/* request reset */
+#define VCC_RCC_HSIP		0x00000100	/* HSYNC polarity */
+#define VCC_RCC_HSIP_LOACT	0x00000000	/* - low active */
+#define VCC_RCC_HSIP_HIACT	0x00000100	/* - high active */
+#define VCC_RCC_VSIP		0x00000200	/* VSYNC polarity */
+#define VCC_RCC_VSIP_LOACT	0x00000000	/* - low active */
+#define VCC_RCC_VSIP_HIACT	0x00000200	/* - high active */
+#define VCC_RCC_CIE		0x00000800	/* interrupt enable */
+#define VCC_RCC_CFP		0x00001000	/* RGB pixel packing */
+#define VCC_RCC_CFP_4TO3	0x00000000	/* - pack 4 pixels into 3 words */
+#define VCC_RCC_CFP_1TO1	0x00001000	/* - pack 1 pixel into 1 words */
+#define VCC_RCC_CSM		0x00006000	/* interlace specification */
+#define VCC_RCC_CSM_ONEPASS	0x00002000	/* - non-interlaced */
+#define VCC_RCC_CSM_INTERLACE	0x00004000	/* - interlaced */
+#define VCC_RCC_CSM_SHIFT	13
+#define VCC_RCC_ES		0x00008000	/* capture start polarity */
+#define VCC_RCC_ES_NEG		0x00000000	/* - negative edge */
+#define VCC_RCC_ES_POS		0x00008000	/* - positive edge */
+#define VCC_RCC_IFI		0x00080000	/* inferlace field evaluation reverse */
+#define VCC_RCC_FDTS		0x00300000	/* interlace field start */
+#define VCC_RCC_FDTS_3_8	0x00000000	/* - 3/8 of horizontal entire cycle */
+#define VCC_RCC_FDTS_1_4	0x00100000	/* - 1/4 of horizontal entire cycle */
+#define VCC_RCC_FDTS_7_16	0x00200000	/* - 7/16 of horizontal entire cycle */
+#define VCC_RCC_FDTS_SHIFT	20
+#define VCC_RCC_MOV		0x00400000	/* test bit - always set to 1 */
+#define VCC_RCC_STP		0x00800000	/* request video capture stop */
+#define VCC_RCC_TO		0x01000000	/* input during top-field only */
+
+#define VCC_RIS_VSYNC		0x01000000	/* VSYNC interrupt */
+#define VCC_RIS_OV		0x02000000	/* overflow interrupt */
+#define VCC_RIS_BOTTOM		0x08000000	/* interlace bottom field */
+#define VCC_RIS_STARTED		0x10000000	/* capture started */
+
+/*
+ * I2C
+ */
+#define MB93493_I2C_BSR 	0x340		/* bus status */
+#define MB93493_I2C_BCR		0x344		/* bus control */
+#define MB93493_I2C_CCR		0x348		/* clock control */
+#define MB93493_I2C_ADR		0x34c		/* address */
+#define MB93493_I2C_DTR		0x350		/* data */
+#define MB93493_I2C_BC2R	0x35c		/* bus control 2 */
+
+#define __addr_MB93493_I2C(port,X)   (__region_CS3 + MB93493_I2C_##X + ((port)*0x20))
+#define __get_MB93493_I2C(port,X)    __get_MB93493(MB93493_I2C_##X + ((port)*0x20))
+#define __set_MB93493_I2C(port,X,V)  __set_MB93493(MB93493_I2C_##X + ((port)*0x20), (V))
+
+#define I2C_BSR_BB	(1 << 7)
+
+/*
+ * audio controller (I2S) registers
+ */
+#define __get_MB93493_I2S(X)	__get_MB93493(MB93493_I2S_##X)
+#define __set_MB93493_I2S(X,V)	__set_MB93493(MB93493_I2S_##X, (V))
+
+#define MB93493_I2S_ALDR	0x300		/* L-channel data */
+#define MB93493_I2S_ARDR	0x304		/* R-channel data */
+#define MB93493_I2S_APDR	0x308		/* 16-bit packed data */
+#define MB93493_I2S_AISTR	0x310		/* status */
+#define MB93493_I2S_AICR	0x314		/* control */
+
+#define __addr_MB93493_I2S_ALDR(X)	(__region_CS3 + MB93493_I2S_ALDR + (X))
+#define __addr_MB93493_I2S_ARDR(X)	(__region_CS3 + MB93493_I2S_ARDR + (X))
+#define __addr_MB93493_I2S_APDR(X)	(__region_CS3 + MB93493_I2S_APDR + (X))
+#define __addr_MB93493_I2S_ADR(X)	(__region_CS3 + 0x320 + (X))
+
+#define I2S_AISTR_OTST		0x00000003	/* status of output data transfer */
+#define I2S_AISTR_OTR		0x00000010	/* output transfer request pending */
+#define I2S_AISTR_OUR		0x00000020	/* output FIFO underrun detected */
+#define I2S_AISTR_OOR		0x00000040	/* output FIFO overrun detected */
+#define I2S_AISTR_ODS		0x00000100	/* output DMA transfer size */
+#define I2S_AISTR_ODE		0x00000400	/* output DMA transfer request enable */
+#define I2S_AISTR_OTRIE		0x00001000	/* output transfer request interrupt enable */
+#define I2S_AISTR_OURIE		0x00002000	/* output FIFO underrun interrupt enable */
+#define I2S_AISTR_OORIE		0x00004000	/* output FIFO overrun interrupt enable */
+#define I2S_AISTR__OUT_MASK	0x00007570
+#define I2S_AISTR_ITST		0x00030000	/* status of input data transfer */
+#define I2S_AISTR_ITST_SHIFT	16
+#define I2S_AISTR_ITR		0x00100000	/* input transfer request pending */
+#define I2S_AISTR_IUR		0x00200000	/* input FIFO underrun detected */
+#define I2S_AISTR_IOR		0x00400000	/* input FIFO overrun detected */
+#define I2S_AISTR_IDS		0x01000000	/* input DMA transfer size */
+#define I2S_AISTR_IDE		0x04000000	/* input DMA transfer request enable */
+#define I2S_AISTR_ITRIE		0x10000000	/* input transfer request interrupt enable */
+#define I2S_AISTR_IURIE		0x20000000	/* input FIFO underrun interrupt enable */
+#define I2S_AISTR_IORIE		0x40000000	/* input FIFO overrun interrupt enable */
+#define I2S_AISTR__IN_MASK	0x75700000
+
+#define I2S_AICR_MI		0x00000001	/* mono input requested */
+#define I2S_AICR_AMI		0x00000002	/* relation between LRCKI/FS1 and SDI */
+#define I2S_AICR_LRI		0x00000004	/* function of LRCKI pin */
+#define I2S_AICR_SDMI		0x00000070	/* format of input audio data */
+#define I2S_AICR_SDMI_SHIFT	4
+#define I2S_AICR_CLI		0x00000080	/* input FIFO clearing control */
+#define I2S_AICR_IM		0x00000300	/* input state control */
+#define I2S_AICR_IM_SHIFT	8
+#define I2S_AICR__IN_MASK	0x000003f7
+#define I2S_AICR_MO		0x00001000	/* mono output requested */
+#define I2S_AICR_AMO		0x00002000	/* relation between LRCKO/FS0 and SDO */
+#define I2S_AICR_AMO_SHIFT	13
+#define I2S_AICR_LRO		0x00004000	/* function of LRCKO pin */
+#define I2S_AICR_SDMO		0x00070000	/* format of output audio data */
+#define I2S_AICR_SDMO_SHIFT	16
+#define I2S_AICR_CLO		0x00080000	/* output FIFO clearing control */
+#define I2S_AICR_OM		0x00100000	/* output state control */
+#define I2S_AICR__OUT_MASK	0x001f7000
+#define I2S_AICR_DIV		0x03000000	/* frequency division rate */
+#define I2S_AICR_DIV_SHIFT	24
+#define I2S_AICR_FL		0x20000000	/* frame length */
+#define I2S_AICR_FS		0x40000000	/* frame sync method */
+#define I2S_AICR_ME		0x80000000	/* master enable */
+
+/*
+ * PCMCIA
+ */
+#define __addr_MB93493_PCMCIA(X)  ((volatile unsigned long *)(__region_CS5 + (X)))
+
+/*
+ * GPIO
+ */
+#define __get_MB93493_GPIO_PDR(X)	__get_MB93493(0x380 + (X) * 0xc0)
+#define __set_MB93493_GPIO_PDR(X,V)	__set_MB93493(0x380 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_GPDR(X)	__get_MB93493(0x384 + (X) * 0xc0)
+#define __set_MB93493_GPIO_GPDR(X,V)	__set_MB93493(0x384 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_SIR(X)	__get_MB93493(0x388 + (X) * 0xc0)
+#define __set_MB93493_GPIO_SIR(X,V)	__set_MB93493(0x388 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_SOR(X)	__get_MB93493(0x38c + (X) * 0xc0)
+#define __set_MB93493_GPIO_SOR(X,V)	__set_MB93493(0x38c + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_PDSR(X)	__get_MB93493(0x390 + (X) * 0xc0)
+#define __set_MB93493_GPIO_PDSR(X,V)	__set_MB93493(0x390 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_PDCR(X)	__get_MB93493(0x394 + (X) * 0xc0)
+#define __set_MB93493_GPIO_PDCR(X,V)	__set_MB93493(0x394 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_INTST(X)	__get_MB93493(0x398 + (X) * 0xc0)
+#define __set_MB93493_GPIO_INTST(X,V)	__set_MB93493(0x398 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_IEHL(X)	__get_MB93493(0x39c + (X) * 0xc0)
+#define __set_MB93493_GPIO_IEHL(X,V)	__set_MB93493(0x39c + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_IELH(X)	__get_MB93493(0x3a0 + (X) * 0xc0)
+#define __set_MB93493_GPIO_IELH(X,V)	__set_MB93493(0x3a0 + (X) * 0xc0, (V))
+
+#endif /* _ASM_MB93493_REGS_H */
diff -urN linux-2.4.29/include/asm-frv/mb-regs.h linux-2.4.29-uc1/include/asm-frv/mb-regs.h
--- linux-2.4.29/include/asm-frv/mb-regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/mb-regs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,188 @@
+/* mb-regs.h: motherboard registers
+ *
+ * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+
+#ifndef _ASM_MB_REGS_H
+#define _ASM_MB_REGS_H
+
+#include <asm/cpu-irqs.h>
+#include <asm/vmlinux.h>
+#include <asm/mem-layout.h>
+
+#define __region_IO	KERNEL_IO_START	/* the region from 0xe0000000 to 0xffffffff has suitable
+					 * protection laid over the top for use in memory-mapped
+					 * I/O
+					 */
+
+#define __region_CS0	0xff000000	/* Boot ROMs area */
+
+#ifdef CONFIG_MB93091_VDK
+/*
+ * VDK motherboard and CPU card specific stuff
+ */
+
+#include <asm/mb93091-fpga-irqs.h>
+
+#define IRQ_CPU_MB93493_0	IRQ_CPU_EXTERNAL0
+#define IRQ_CPU_MB93493_1	IRQ_CPU_EXTERNAL1
+
+#define __region_CS2	0xe0000000	/* SLBUS/PCI I/O space */
+#define __region_CS2_M		0x0fffffff /* mask */
+#define __region_CS2_C		0x00000000 /* control */
+#define __region_CS5	0xf0000000	/* MB93493 CSC area (DAV daughter board) */
+#define __region_CS5_M		0x00ffffff
+#define __region_CS5_C		0x00010000
+#define __region_CS7	0xf1000000	/* CB70 CPU-card PCMCIA port I/O space */
+#define __region_CS7_M		0x00ffffff
+#define __region_CS7_C		0x00410701
+#define __region_CS1	0xfc000000	/* SLBUS/PCI bridge control registers */
+#define __region_CS1_M		0x000fffff
+#define __region_CS1_C		0x00000000
+#define __region_CS6	0xfc100000	/* CB70 CPU-card DM9000 LAN I/O space */
+#define __region_CS6_M		0x000fffff
+#define __region_CS6_C		0x00400707
+#define __region_CS3	0xfc200000	/* MB93493 CSR area (DAV daughter board) */
+#define __region_CS3_M		0x000fffff
+#define __region_CS3_C		0xc8100000
+#define __region_CS4	0xfd000000	/* CB70 CPU-card extra flash space */
+#define __region_CS4_M		0x00ffffff
+#define __region_CS4_C		0x00000f07
+
+#define __region_PCI_IO		(__region_CS2 + 0x04000000UL)
+#define __region_PCI_MEM	(__region_CS2 + 0x08000000UL)
+#define __flush_PCI_writes()						\
+do {									\
+	__builtin_write8((volatile void *) __region_PCI_MEM, 0);	\
+} while(0)
+
+#define __is_PCI_IO(addr) \
+	(((unsigned long)(addr) >> 24) - (__region_PCI_IO >> 24)  < (0x04000000UL >> 24))
+
+#define __is_PCI_MEM(addr) \
+	((unsigned long)(addr) - __region_PCI_MEM < 0x08000000UL)
+
+#define __get_CLKSW()	({ *(volatile unsigned long *)(__region_CS2 + 0x0130000cUL) & 0xffUL; })
+#define __get_CLKIN()	(__get_CLKSW() * 125U * 100000U / 24U)
+
+#ifndef __ASSEMBLY__
+extern int __nongprelbss mb93090_mb00_detected;
+#endif
+
+#define __addr_LEDS()		(__region_CS2 + 0x01200004UL)
+#ifdef CONFIG_MB93090_MB00
+#define __set_LEDS(X)							\
+do {									\
+	if (mb93090_mb00_detected)					\
+		__builtin_write32((void *) __addr_LEDS(), ~(X));	\
+} while (0)
+#else
+#define __set_LEDS(X)
+#endif
+
+#define __addr_LCD()		(__region_CS2 + 0x01200008UL)
+#define __get_LCD(B)		__builtin_read32((volatile void *) (B))
+#define __set_LCD(B,X)		__builtin_write32((volatile void *) (B), (X))
+
+#define LCD_D			0x000000ff		/* LCD data bus */
+#define LCD_RW			0x00000100		/* LCD R/W signal */
+#define LCD_RS			0x00000200		/* LCD Register Select */
+#define LCD_E			0x00000400		/* LCD Start Enable Signal */
+
+#define LCD_CMD_CLEAR		(LCD_E|0x001)
+#define LCD_CMD_HOME		(LCD_E|0x002)
+#define LCD_CMD_CURSOR_INC	(LCD_E|0x004)
+#define LCD_CMD_SCROLL_INC	(LCD_E|0x005)
+#define LCD_CMD_CURSOR_DEC	(LCD_E|0x006)
+#define LCD_CMD_SCROLL_DEC	(LCD_E|0x007)
+#define LCD_CMD_OFF		(LCD_E|0x008)
+#define LCD_CMD_ON(CRSR,BLINK)	(LCD_E|0x00c|(CRSR<<1)|BLINK)
+#define LCD_CMD_CURSOR_MOVE_L	(LCD_E|0x010)
+#define LCD_CMD_CURSOR_MOVE_R	(LCD_E|0x014)
+#define LCD_CMD_DISPLAY_SHIFT_L	(LCD_E|0x018)
+#define LCD_CMD_DISPLAY_SHIFT_R	(LCD_E|0x01c)
+#define LCD_CMD_FUNCSET(DL,N,F)	(LCD_E|0x020|(DL<<4)|(N<<3)|(F<<2))
+#define LCD_CMD_SET_CG_ADDR(X)	(LCD_E|0x040|X)
+#define LCD_CMD_SET_DD_ADDR(X)	(LCD_E|0x080|X)
+#define LCD_CMD_READ_BUSY	(LCD_E|LCD_RW)
+#define LCD_DATA_WRITE(X)	(LCD_E|LCD_RS|(X))
+#define LCD_DATA_READ		(LCD_E|LCD_RS|LCD_RW)
+
+#else
+/*
+ * PDK unit specific stuff
+ */
+
+#include <asm/mb93093-fpga-irqs.h>
+
+#define IRQ_CPU_MB93493_0	IRQ_CPU_EXTERNAL0
+#define IRQ_CPU_MB93493_1	IRQ_CPU_EXTERNAL1
+
+#define __region_CS5	0xf0000000	/* MB93493 CSC area (DAV daughter board) */
+#define __region_CS5_M		0x00ffffff /* mask */
+#define __region_CS5_C		0x00010000 /* control */
+#define __region_CS2	0x20000000	/* FPGA registers */
+#define __region_CS2_M		0x000fffff
+#define __region_CS2_C		0x00000000
+#define __region_CS1	0xfc100000	/* LAN registers */
+#define __region_CS1_M		0x000fffff
+#define __region_CS1_C		0x00010404
+#define __region_CS3	0xfc200000	/* MB93493 CSR area (DAV daughter board) */
+#define __region_CS3_M		0x000fffff
+#define __region_CS3_C		0xc8000000
+#define __region_CS4	0xfd000000	/* extra ROMs area */
+#define __region_CS4_M		0x00ffffff
+#define __region_CS4_C		0x00000f07
+
+#define __region_CS6	0xfe000000	/* not used - hide behind CPU resource I/O regs */
+#define __region_CS6_M		0x000fffff
+#define __region_CS6_C		0x00000f07
+#define __region_CS7	0xfe000000	/* not used - hide behind CPU resource I/O regs */
+#define __region_CS7_M		0x000fffff
+#define __region_CS7_C		0x00000f07
+
+#define __is_PCI_IO(addr)	0	/* no PCI */
+#define __is_PCI_MEM(addr)	0
+#define __region_PCI_IO		0
+#define __region_PCI_MEM	0
+#define __flush_PCI_writes()	do { } while(0)
+
+#define __get_CLKSW()		0UL
+#define __get_CLKIN()		66000000UL
+
+#define __addr_LEDS()		(__region_CS2 + 0x00000023UL)
+#define __set_LEDS(X)		__builtin_write8((volatile void *) __addr_LEDS(), (X))
+
+#define __addr_FPGATR()		(__region_CS2 + 0x00000030UL)
+#define __set_FPGATR(X)		__builtin_write32((volatile void *) __addr_FPGATR(), (X))
+#define __get_FPGATR()		__builtin_read32((volatile void *) __addr_FPGATR())
+
+#define MB93093_FPGA_FPGATR_AUDIO_CLK	0x00000003
+
+#define __set_FPGATR_AUDIO_CLK(V) \
+	__set_FPGATR((__get_FPGATR() & ~MB93093_FPGA_FPGATR_AUDIO_CLK) | (V))
+
+#define MB93093_FPGA_FPGATR_AUDIO_CLK_OFF	0x0
+#define MB93093_FPGA_FPGATR_AUDIO_CLK_11MHz	0x1
+#define MB93093_FPGA_FPGATR_AUDIO_CLK_12MHz	0x2
+#define MB93093_FPGA_FPGATR_AUDIO_CLK_02MHz	0x3
+
+#define MB93093_FPGA_SWR_PUSHSWMASK	(0x1F<<26)
+#define MB93093_FPGA_SWR_PUSHSW4	(1<<29)
+
+#define __addr_FPGA_SWR		((volatile void *)(__region_CS2 + 0x28UL))
+#define __get_FPGA_PUSHSW1_5()	(__builtin_read32(__addr_FPGA_SWR) & MB93093_FPGA_SWR_PUSHSWMASK)
+
+
+#endif
+
+
+
+#endif /* _ASM_MB_REGS_H */
diff -urN linux-2.4.29/include/asm-frv/mc146818rtc.h linux-2.4.29-uc1/include/asm-frv/mc146818rtc.h
--- linux-2.4.29/include/asm-frv/mc146818rtc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/mc146818rtc.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,9 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _M68KNOMMU_MC146818RTC_H
+#define _M68KNOMMU_MC146818RTC_H
+
+/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */
+
+#endif /* _M68KNOMMU_MC146818RTC_H */
diff -urN linux-2.4.29/include/asm-frv/md.h linux-2.4.29-uc1/include/asm-frv/md.h
--- linux-2.4.29/include/asm-frv/md.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/md.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,13 @@
+/* md.h: High speed xor_block operation for RAID4/5 
+ *
+ */
+ 
+#ifndef __ASM_MD_H
+#define __ASM_MD_H
+
+/* #define HAVE_ARCH_XORBLOCK */
+
+#define MD_XORBLOCK_ALIGNMENT	sizeof(long)
+
+#endif /* __ASM_MD_H */
+
diff -urN linux-2.4.29/include/asm-frv/mem-layout.h linux-2.4.29-uc1/include/asm-frv/mem-layout.h
--- linux-2.4.29/include/asm-frv/mem-layout.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/mem-layout.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,78 @@
+/* mem-layout.h: memory layout
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MEM_LAYOUT_H
+#define _ASM_MEM_LAYOUT_H
+
+#ifndef __ASSEMBLY__
+#define __UL(X)	((unsigned long) (X))
+#else
+#define __UL(X)	(X)
+#endif
+
+/*
+ * PAGE_SHIFT determines the page size
+ */
+#define PAGE_SHIFT			14
+
+#ifndef __ASSEMBLY__
+#define PAGE_SIZE			(1UL << PAGE_SHIFT)
+#else
+#define PAGE_SIZE			(1 << PAGE_SHIFT)
+#endif
+
+#define PAGE_MASK			(~(PAGE_SIZE-1))
+
+/*****************************************************************************/
+/*
+ * virtual memory layout from kernel's point of view
+ */
+#define PAGE_OFFSET			((unsigned long) &__page_offset)
+
+#ifndef CONFIG_UCLINUX
+
+/* see Documentation/fujitsu/frv/mmu-layout.txt */
+#define KERNEL_LOWMEM_START		__UL(0xc0000000)
+#define KERNEL_LOWMEM_END		__UL(0xd0000000)
+#define VMALLOC_START			__UL(0xd0000000)
+#define VMALLOC_END			__UL(0xd8000000)
+#define PKMAP_BASE			__UL(0xd8000000)
+#define PKMAP_END			__UL(0xdc000000)
+#define KMAP_ATOMIC_SECONDARY_FRAME	__UL(0xdc000000)
+#define KMAP_ATOMIC_PRIMARY_FRAME	__UL(0xdd000000)
+
+#endif
+
+#define KERNEL_IO_START			__UL(0xe0000000)
+
+
+/*****************************************************************************/
+/*
+ * memory layout from userspace's point of view
+ */
+#define BRK_BASE			__UL(2 * 1024 * 1024 + PAGE_SIZE)
+#define STACK_TOP			__UL(2 * 1024 * 1024)
+
+/* userspace process size */
+#ifndef CONFIG_UCLINUX
+#define TASK_SIZE			(PAGE_OFFSET)
+#else
+#define TASK_SIZE			__UL(0xFFFFFFFFUL)
+#endif
+
+/* base of area at which unspecified mmaps will start */
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+#define TASK_UNMAPPED_BASE		__UL(16 * 1024 * 1024)
+#else
+#define TASK_UNMAPPED_BASE		__UL(TASK_SIZE / 3)
+#endif
+
+#endif /* _ASM_MEM_LAYOUT_H */
diff -urN linux-2.4.29/include/asm-frv/mman.h linux-2.4.29-uc1/include/asm-frv/mman.h
--- linux-2.4.29/include/asm-frv/mman.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/mman.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,39 @@
+#ifndef __ASM_MMAN_H__
+#define __ASM_MMAN_H__
+
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_NONE	0x0		/* page can not be accessed */
+
+#define MAP_SHARED	0x01		/* Share changes */
+#define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_TYPE	0x0f		/* Mask for type of mapping */
+#define MAP_FIXED	0x10		/* Interpret addr exactly */
+#define MAP_ANONYMOUS	0x20		/* don't use a file */
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
+#define MAP_LOCKED	0x2000		/* pages are locked */
+#define MAP_NORESERVE	0x4000		/* don't check for reservations */
+
+#define MS_ASYNC	1		/* sync memory asynchronously */
+#define MS_INVALIDATE	2		/* invalidate the caches */
+#define MS_SYNC		4		/* synchronous memory sync */
+
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
+
+#define MADV_NORMAL	0x0		/* default page-in behavior */
+#define MADV_RANDOM	0x1		/* page-in minimum required */
+#define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
+#define MADV_WILLNEED	0x3		/* pre-fault pages */
+#define MADV_DONTNEED	0x4		/* discard these pages */
+
+/* compatibility flags */
+#define MAP_ANON	MAP_ANONYMOUS
+#define MAP_FILE	0
+
+#endif /* __ASM_MMAN_H__ */
+
diff -urN linux-2.4.29/include/asm-frv/mmu_context.h linux-2.4.29-uc1/include/asm-frv/mmu_context.h
--- linux-2.4.29/include/asm-frv/mmu_context.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/mmu_context.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,35 @@
+#ifndef _ASM_MMU_CONTEXT_H
+#define _ASM_MMU_CONTEXT_H
+
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
+{
+}
+
+#ifndef CONFIG_UCLINUX
+extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
+extern void change_mm_context(mm_context_t *old, mm_context_t *ctx, pgd_t *_pgd);
+extern void destroy_context(struct mm_struct *mm);
+
+#else
+#define init_new_context(tsk,mm)	({ 0; })
+#define change_mm_context(old,ctx,_pgd)	do {} while(0)
+#define destroy_context(mm)		do {} while(0)
+#endif
+
+#define switch_mm(prev, next, tsk, cpu)						\
+do {										\
+	if (prev != next)							\
+		change_mm_context(&prev->context, &next->context, next->pgd);	\
+} while(0)
+
+#define activate_mm(prev, next)						\
+do {									\
+	change_mm_context(&prev->context, &next->context, next->pgd);	\
+} while(0)
+
+#endif
diff -urN linux-2.4.29/include/asm-frv/mmu.h linux-2.4.29-uc1/include/asm-frv/mmu.h
--- linux-2.4.29/include/asm-frv/mmu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/mmu.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,22 @@
+#ifndef __MMU_H
+#define __MMU_H
+
+typedef struct {
+#ifndef CONFIG_UCLINUX
+	struct list_head id_link;		/* link in list of context ID owners */
+	unsigned short	id;			/* MMU context ID */
+	unsigned short	id_busy;		/* true if ID is in CXNR */
+	unsigned long	itlb_cached_pge;	/* [SCR0] PGE cached for insn TLB handler */
+	unsigned long	itlb_ptd_mapping;	/* [DAMR4] PTD mapping for itlb cached PGE */
+	unsigned long	dtlb_cached_pge;	/* [SCR1] PGE cached for data TLB handler */
+	unsigned long	dtlb_ptd_mapping;	/* [DAMR5] PTD mapping for dtlb cached PGE */
+#endif
+} mm_context_t;
+
+#ifndef CONFIG_UCLINUX
+extern int __nongpreldata cxn_pinned;
+extern int cxn_pin_by_pid(pid_t pid);
+#endif
+
+#endif
+
diff -urN linux-2.4.29/include/asm-frv/module.h linux-2.4.29-uc1/include/asm-frv/module.h
--- linux-2.4.29/include/asm-frv/module.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/module.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef _ASM_MODULE_H
+#define _ASM_MODULE_H
+/*
+ * This file contains the FR-V architecture specific module code.
+ */
+
+#define module_map(x)		vmalloc(x)
+#define module_unmap(x)		vfree(x)
+#define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
+
+#endif /* _ASM_MODULE_H */
+
diff -urN linux-2.4.29/include/asm-frv/msgbuf.h linux-2.4.29-uc1/include/asm-frv/msgbuf.h
--- linux-2.4.29/include/asm-frv/msgbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/msgbuf.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,32 @@
+#ifndef _ASM_MSGBUF_H
+#define _ASM_MSGBUF_H
+
+/* 
+ * The msqid64_ds structure for FR-V architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm	msg_perm;
+	__kernel_time_t		msg_stime;	/* last msgsnd time */
+	unsigned long		__unused1;
+	__kernel_time_t		msg_rtime;	/* last msgrcv time */
+	unsigned long		__unused2;
+	__kernel_time_t		msg_ctime;	/* last change time */
+	unsigned long		__unused3;
+	unsigned long		msg_cbytes;	/* current number of bytes on queue */
+	unsigned long		msg_qnum;	/* number of messages in queue */
+	unsigned long		msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t		msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t		msg_lrpid;	/* last receive pid */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+#endif /* _ASM_MSGBUF_H */
+
diff -urN linux-2.4.29/include/asm-frv/namei.h linux-2.4.29-uc1/include/asm-frv/namei.h
--- linux-2.4.29/include/asm-frv/namei.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/namei.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,18 @@
+/*
+ * asm/namei.h
+ *
+ * Included from linux/fs/namei.c
+ */
+
+#ifndef __ASM_NAMEI_H
+#define __ASM_NAMEI_H
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+
+#define __emul_prefix() NULL
+
+#endif
+
diff -urN linux-2.4.29/include/asm-frv/page.h linux-2.4.29-uc1/include/asm-frv/page.h
--- linux-2.4.29/include/asm-frv/page.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/page.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,104 @@
+#ifndef _ASM_PAGE_H
+#define _ASM_PAGE_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <asm/virtconvert.h>
+#include <asm/mem-layout.h>
+#include <asm/vmlinux.h>
+#include <asm/setup.h>
+ 
+#ifndef __ASSEMBLY__
+ 
+#define get_user_page(vaddr)		__get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr)	free_page(addr)
+
+#define clear_page(page)		memset((page), 0, PAGE_SIZE)
+#define copy_page(to,from)		memcpy((to), (from), PAGE_SIZE)
+
+#define clear_user_page(page, vaddr)	clear_page(page)
+#define copy_user_page(to, from, vaddr)	copy_page(to, from)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte;	} pte_t;
+typedef struct { unsigned long ste[64];	} pmd_t;
+typedef struct { pmd_t         pge[1];	} pgd_t;
+typedef struct { unsigned long pgprot;	} pgprot_t;
+
+#define pte_val(x)	((x).pte)
+#define pmd_val(x)	((&x)->ste[0])
+#define pgd_val(x)	((x).pge[0])
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x)	((pte_t) { (x) } )
+#define __pmd(x)	((pmd_t) { (x) } )
+#define __pgd(x)	((pgd_t) { (x) } )
+#define __pgprot(x)	((pgprot_t) { (x) } )
+#define PTE_MASK	PAGE_MASK
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr) + PAGE_SIZE - 1) & PAGE_MASK)
+
+/* Pure 2^n version of get_order */
+extern __inline__ int get_order(unsigned long size)
+{
+	int order;
+
+	size = (size - 1) >> (PAGE_SHIFT - 1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+#define __pa(vaddr)		virt_to_phys((void *)vaddr)
+#define __va(paddr)		phys_to_virt((unsigned long)paddr)
+
+#define MAP_NR(addr)		(((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT)
+#define virt_to_page(addr)	(mem_map + (((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT))
+#define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
+
+
+#ifdef CONFIG_NO_KERNEL_MSG
+#define	BUG_PRINT()
+#else
+#define	BUG_PRINT() printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__)
+#endif
+
+extern asmlinkage void __debug_bug_trap(void);
+#define BUG_PANIC()				\
+do {						\
+	__debug_bug_trap();			\
+	asm volatile("nop");			\
+	/*panic("BUG!");*/			\
+} while(0)
+
+
+#define BUG() do {				\
+	BUG_PRINT();				\
+	BUG_PANIC();				\
+} while (0)
+
+#define PAGE_BUG(page) do {			\
+	BUG();					\
+} while (0)
+
+#ifndef CONFIG_UCLINUX
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
+#define WANT_PAGE_VIRTUAL	1
+#endif
+
+#endif /* _ASM_PAGE_H */
diff -urN linux-2.4.29/include/asm-frv/param.h linux-2.4.29-uc1/include/asm-frv/param.h
--- linux-2.4.29/include/asm-frv/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/param.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,27 @@
+#ifndef _ASM_PARAM_H
+#define _ASM_PARAM_H
+
+#include <linux/config.h>
+
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#define EXEC_PAGESIZE	16384
+
+#ifndef NGROUPS
+#define NGROUPS		32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#ifdef __KERNEL__
+#define CLOCKS_PER_SEC HZ
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_PARAM_H */
diff -urN linux-2.4.29/include/asm-frv/pci.h linux-2.4.29-uc1/include/asm-frv/pci.h
--- linux-2.4.29/include/asm-frv/pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/pci.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,174 @@
+/* pci.h: FR-V specific PCI declarations
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from include/asm-m68k/pci.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef ASM_PCI_H
+#define	ASM_PCI_H
+
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+#include <asm/pgalloc.h>
+
+extern unsigned long __nongprelbss dma_consistent_mem_start;
+extern unsigned long __nongprelbss dma_consistent_mem_end;
+
+#define pcibios_assign_all_busses()	0
+#define pcibios_scan_all_fns()          0
+
+extern void pcibios_set_master(struct pci_dev *dev);
+
+extern void pcibios_penalize_isa_irq(int irq);
+
+#ifndef CONFIG_UCLINUX
+extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle);
+extern void consistent_free(void *vaddr);
+extern void consistent_sync(void *vaddr, size_t size, int direction);
+extern void consistent_sync_page(struct page *page, unsigned long offset,
+				 size_t size, int direction);
+#endif
+
+extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+				  dma_addr_t *dma_handle);
+
+extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+				void *vaddr, dma_addr_t dma_handle);
+
+/* Return whether the given PCI device DMA address mask can
+ * be supported properly.  For example, if your device can
+ * only drive the low 24-bits during PCI bus mastering, then
+ * you would pass 0x00ffffff as the mask to this function.
+ */
+static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
+{
+        /*
+         * we fall back to GFP_DMA when the mask isn't all 1s,
+         * so we can't guarantee allocations that must be
+         * within a tighter range than GFP_DMA..
+         */
+        if(mask < 0x00ffffff)
+                return 0;
+
+	return 1;
+}
+
+/* This is always fine. */
+#define pci_dac_dma_supported(pci_dev, mask)	(1)
+
+/* Return the index of the PCI controller for device PDEV. */
+#define pci_controller_num(PDEV)	(0)
+
+/* The PCI address space does equal the physical memory
+ * address space.  The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS	(1)
+
+/*
+ *	These are pretty much arbitary with the CoMEM implementation.
+ *	We have the whole address space to ourselves.
+ */
+#define PCIBIOS_MIN_IO		0x100
+#define PCIBIOS_MIN_MEM		0x00010000
+
+/* These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
+#define sg_dma_address(sg)	((unsigned long)(page_to_phys((sg)->page)+(sg)->offset))
+#define sg_dma_len(sg)		((sg)->length)
+
+/* Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Once the device is given the dma address, the device owns this memory
+ * until either pci_unmap_single or pci_dma_sync_single is performed.
+ */
+extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+				 size_t size, int direction);
+
+
+/* Unmap a single streaming mode DMA translation.  The dma_addr and size
+ * must match what was provided for in a previous pci_map_single call.  All
+ * other usages are undefined.
+ *
+ * After this call, reads by the cpu to the buffer are guarenteed to see
+ * whatever the device wrote there.
+ */
+static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+				    size_t size,int direction)
+{
+	/* Nothing to do */
+}
+/* Map a set of buffers described by scatterlist in streaming
+ * mode for DMA.  This is the scather-gather version of the
+ * above pci_map_single interface.  Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length.  They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ *       DMA address/length pairs than there are SG table elements.
+ *       (for example via virtual mapping capabilities)
+ *       The routine returns the number of addr/length pairs actually
+ *       used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+		      int nents, int direction);
+
+/* Unmap a set of streaming mode DMA translations.
+ * Again, cpu read rules concerning calls here are the same as for
+ * pci_unmap_single() above.
+ */
+static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+				int nents, int direction)
+{
+	/* Nothing to do */
+}
+
+/* Make physical memory consistent for a single
+ * streaming mode DMA translation after a transfer.
+ *
+ * If you perform a pci_map_single() but wish to interrogate the
+ * buffer using the cpu, yet do not wish to teardown the PCI dma
+ * mapping, you must call this function before doing so.  At the
+ * next point you give the PCI dma address back to the card, the
+ * device again owns the buffer.
+ */
+static inline void pci_dma_sync_single(struct pci_dev *hwdev,
+				       dma_addr_t dma_handle,
+				       size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+                BUG();
+
+	frv_cache_wback_inv((unsigned long)bus_to_virt(dma_handle), 
+			    (unsigned long)bus_to_virt(dma_handle) + size);
+}
+
+/* Make physical memory consistent for a set of streaming
+ * mode DMA translations after a transfer.
+ *
+ * The same as pci_dma_sync_single but for a scatter-gather list,
+ * same rules and usage.
+ */
+static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
+				   struct scatterlist *sg,
+				   int nelems, int direction)
+{
+	pci_map_sg(hwdev, sg, nelems, direction);
+}
+
+
+#endif
diff -urN linux-2.4.29/include/asm-frv/pgalloc.h linux-2.4.29-uc1/include/asm-frv/pgalloc.h
--- linux-2.4.29/include/asm-frv/pgalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/pgalloc.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,211 @@
+/* pgalloc.h: Page allocation and TLB flushing routines for FR-V
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Derived from:
+ *	include/asm-m68knommu/pgalloc.h
+ *	include/asm-i386/pgalloc.h
+ */
+#ifndef _ASM_PGALLOC_H
+#define _ASM_PGALLOC_H
+
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/virtconvert.h>
+
+#ifndef CONFIG_UCLINUX
+
+#define pgd_quicklist		(current_cpu_data.pgd_quick)
+#define pmd_quicklist		NULL
+#define pte_quicklist		(current_cpu_data.pte_quick)
+#define pgtable_cache_size	(current_cpu_data.pgtable_cache_sz)
+
+#define pmd_populate(mm, pmd, pte)  __set_pmd(pmd, __pa(pte) | _PAGE_TABLE)
+
+/*
+ * Allocate and free page tables.
+ */
+extern pgd_t *get_pgd_slow(void);
+
+static inline pgd_t *get_pgd_fast(void)
+{
+	unsigned long *ret;
+
+	if ((ret = pgd_quicklist) != NULL) {
+		pgd_quicklist = (unsigned long *) *ret;
+		ret[0] = 0;
+		asm volatile ("dcf %M0" :: "m"(ret[0]));
+		pgtable_cache_size--;
+	}
+	else {
+		ret = (unsigned long *) get_pgd_slow();
+	}
+
+	return (pgd_t *) ret;
+}
+
+static inline void free_pgd_fast(pgd_t *pgd)
+{
+	*(unsigned long *) pgd = (unsigned long) pgd_quicklist;
+	pgd_quicklist = (unsigned long *) pgd;
+	pgtable_cache_size++;
+}
+
+#define free_pgd_slow(pgd) do { free_page((unsigned long) (pgd)); } while(0)
+
+extern pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address);
+
+static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
+{
+	unsigned long *ret;
+
+	if ((ret = (unsigned long *) pte_quicklist) != NULL) {
+		pte_quicklist = (unsigned long *) *ret;
+		ret[0] = ret[1];
+		asm volatile ("dcf %M0" :: "m"(ret[0]));
+		pgtable_cache_size--;
+	}
+	return (pte_t *) ret;
+}
+
+static inline void pte_free_fast(pte_t *pte)
+{
+	*(unsigned long *) pte = (unsigned long) pte_quicklist;
+	pte_quicklist = (unsigned long *) pte;
+	pgtable_cache_size++;
+}
+
+#define pte_free_slow(pte) do { free_page((unsigned long) (pte)); } while(0)
+
+#define pte_free(pte)	pte_free_fast(pte)
+#define pgd_free(pgd)	free_pgd_slow(pgd)
+#define pgd_alloc(mm)	get_pgd_fast()
+
+/*
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
+ * (In the PAE case we free the pmds as part of the pgd.)
+ */
+#define pmd_alloc_one_fast(mm, addr)	({ BUG(); ((pmd_t *) 1); })
+#define pmd_alloc_one(mm, addr)		({ BUG(); ((pmd_t *) 2); })
+#define pmd_free_slow(x)		do { } while (0)
+#define pmd_free_fast(x)		do { } while (0)
+#define pmd_free(x)			do { } while (0)
+#define pgd_populate(mm, pmd, pte)	BUG()
+
+extern int do_check_pgt_cache(int, int);
+
+#endif /* !CONFIG_UCLINUX */
+
+/*
+ * Cache handling functions
+ */
+/* Those implemented in arch/frvnommu/lib/cache.S: */
+extern void frv_dcache_writeback(unsigned long start, unsigned long size);
+extern void frv_cache_invalidate(unsigned long start, unsigned long size);
+extern void frv_icache_invalidate(unsigned long start, unsigned long size);
+extern void frv_cache_wback_inv(unsigned long start, unsigned long size);
+
+static inline void __flush_cache_all(void)
+{
+	asm volatile("	dcef	@(gr0,gr0),#1	\n"
+		     "	icei	@(gr0,gr0),#1	\n"
+		     "	membar			\n"
+		     : : : "memory"
+		     );
+}
+
+/* Needed only for virtually-indexed caches */
+#define flush_cache_all()			do {} while(0)
+#define flush_cache_mm(mm)			do {} while(0)
+#define flush_cache_range(mm, start, end)	do {} while(0)
+#define flush_cache_page(vma, vmaddr)		do {} while(0)
+
+/* dcache/icache coherency... */
+#ifndef CONFIG_UCLINUX
+extern void flush_dcache_page(struct page *page);
+#else
+static inline void flush_dcache_page(struct page *page)
+{
+	unsigned long addr = page_to_phys(page);
+	frv_dcache_writeback(addr, addr + PAGE_SIZE);
+}
+#endif
+
+static inline void flush_page_to_ram(struct page *page)
+{
+	flush_dcache_page(page);
+}
+
+static inline void flush_icache(void)
+{
+	__flush_cache_all();
+}
+
+static inline void flush_icache_range(unsigned long start, unsigned long end)
+{
+	frv_cache_wback_inv(start, end);
+}
+
+#ifndef CONFIG_UCLINUX
+extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+				    unsigned long start, unsigned long len);
+#else
+static inline void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+					   unsigned long start, unsigned long len)
+{
+	frv_cache_wback_inv(start, start + len);
+}
+#endif
+
+static inline void flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	flush_icache_user_range(vma, page, page_to_phys(page), PAGE_SIZE);
+}
+
+/*
+ * TLB flushing functions
+ */
+#ifndef CONFIG_UCLINUX
+#define flush_tlb()				flush_tlb_all()
+
+static inline void flush_tlb_all(void)
+{
+	__flush_tlb_all();
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+	__flush_tlb_mm(mm->context.id);
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+	unsigned long start, unsigned long end)
+{
+	__flush_tlb_range(mm->context.id, start, end);
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma,
+	unsigned long addr)
+{
+	__flush_tlb_page(vma->vm_mm->context.id, addr);
+}
+
+#define flush_tlb_pgtables(mm,start,end)	asm volatile("movgs gr0,scr0 ! movgs gr0,scr1");
+
+#else
+#define flush_tlb()				BUG();
+#define flush_tlb_all()				BUG();
+#define flush_tlb_page(vma,addr)		BUG();
+#define flush_tlb_range(mm,start,end)		BUG();
+#define flush_tlb_pgtables(mm,start,end)	BUG();
+
+#endif
+
+#endif /* _ASM_PGALLOC_H */
diff -urN linux-2.4.29/include/asm-frv/pgtable.h linux-2.4.29-uc1/include/asm-frv/pgtable.h
--- linux-2.4.29/include/asm-frv/pgtable.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/pgtable.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,397 @@
+/* pgtable.h: FR-V page table mangling
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Derived from:
+ *	include/asm-m68knommu/pgtable.h
+ *	include/asm-i386/pgtable.h
+ */
+
+#ifndef _ASM_PGTABLE_H
+#define _ASM_PGTABLE_H
+
+#include <linux/config.h>
+#include <asm/setup.h>
+
+
+#ifdef CONFIG_UCLINUX
+
+#define pgd_present(pgd)	(1)		/* pages are always present on NO_MM */
+#define kern_addr_valid(addr)	(1)
+
+#define PAGE_NONE		__pgprot(0)	/* these mean nothing to NO_MM */
+#define PAGE_SHARED		__pgprot(0)	/* these mean nothing to NO_MM */
+#define PAGE_COPY		__pgprot(0)	/* these mean nothing to NO_MM */
+#define PAGE_READONLY		__pgprot(0)	/* these mean nothing to NO_MM */
+#define PAGE_KERNEL		__pgprot(0)	/* these mean nothing to NO_MM */
+#else /* CONFIG_UCLINUX */
+
+#ifndef __ASSEMBLY__
+extern void asmlinkage __flush_tlb_all(void);
+extern void asmlinkage __flush_tlb_mm(unsigned long contextid);
+extern void asmlinkage __flush_tlb_page(unsigned long contextid, unsigned long start);
+extern void asmlinkage __flush_tlb_range(unsigned long contextid,
+					 unsigned long start, unsigned long end);
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+#ifndef __ASSEMBLY__
+extern unsigned long empty_zero_page;
+#define ZERO_PAGE(vaddr)	virt_to_page(empty_zero_page)
+#endif
+
+/*
+ * we use 2-level page tables, folding the PMD (mid-level table) into the PGE (top-level entry)
+ * [see Documentation/fujitsu/frv/mmu-layout.txt]
+ *
+ * Page Directory:
+ *  - Size: 16Kb
+ *  - 64 PGEs per PGD
+ *  - Each PGE holds 1 PMD and covers 64Mb
+ *
+ * Page Mid-Level Directory
+ *  - 1 PME per PMD
+ *  - Each PME holds 64 STEs, all of which point to separate chunks of the same Page Table
+ *  - All STEs are instantiated at the same time
+ *  - Size: 256b
+ *
+ * Page Table
+ *  - Size: 16Kb
+ *  - 4096 PTEs per PT
+ *  - Each Linux PT is subdivided into 64 FR451 PT's, each of which holds 64 entries
+ *
+ * total PTEs
+ *	= 64 PGEs * 1 PMEs * 4096 PTEs
+ *	= 64 PGEs * 64 STEs * 64 PTEs/FR451-PT
+ *	= 262144 (or 256 * 1024)
+ */
+#define PGDIR_SHIFT		26
+#define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK		(~(PGDIR_SIZE - 1))
+#define PTRS_PER_PGD		64
+
+#define PMD_SHIFT		26
+#define PMD_SIZE		(1UL << PMD_SHIFT)
+#define PMD_MASK		(~(PMD_SIZE - 1))
+#define PTRS_PER_PMD		1
+#define PME_SIZE		256
+
+#define __frv_PT_SIZE		256
+
+#define PTRS_PER_PTE		4096
+
+#define USER_PTRS_PER_PGD	(TASK_SIZE / PGDIR_SIZE)
+#define FIRST_USER_PGD_NR	0
+
+#define USER_PGD_PTRS		(PAGE_OFFSET >> PGDIR_SHIFT)
+#define KERNEL_PGD_PTRS		(PTRS_PER_PGD - USER_PGD_PTRS)
+
+#define TWOLEVEL_PGDIR_SHIFT	26
+#define BOOT_USER_PGD_PTRS	(__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
+#define BOOT_KERNEL_PGD_PTRS	(PTRS_PER_PGD - BOOT_USER_PGD_PTRS)
+
+#ifndef __ASSEMBLY__
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+#define pte_ERROR(e) \
+	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte)
+#define pmd_ERROR(e) \
+	printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+#define pgd_ERROR(e) \
+	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pmd_val(pgd_val(e)))
+
+/*
+ * The "pgd_xxx()" functions here are trivial for a folded two-level
+ * setup: the pgd is never bad, and a pmd always exists (as it's folded
+ * into the pgd entry)
+ */
+static inline int pgd_none(pgd_t pgd)		{ return 0; }
+static inline int pgd_bad(pgd_t pgd)		{ return 0; }
+static inline int pgd_present(pgd_t pgd)	{ return 1; }
+#define pgd_clear(xp)				do { } while (0)
+
+/*
+ * Certain architectures need to do special things when PTEs
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+#define set_pte(pteptr, pteval)				\
+do {							\
+	*(pteptr) = (pteval);				\
+	asm volatile("dcf %M0" :: "U"(*pteptr));	\
+} while(0)
+
+#define set_pte_atomic(pteptr, pteval)		set_pte((pteptr), (pteval))
+
+/*
+ * (pmds are folded into pgds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pgd(pgdptr, pgdval)			(*(pgdptr) = pgdval)
+
+extern void __set_pmd(pmd_t *pmdptr, unsigned long __pmd);
+
+#define set_pmd(pmdptr, pmdval)			\
+do {						\
+	__set_pmd((pmdptr), (pmdval).ste[0]);	\
+} while(0)
+
+#define pgd_page(pgd)				((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
+
+#define __pmd_index(address)			0
+
+static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
+{
+	return (pmd_t *) dir + __pmd_index(address);
+}
+
+#define pte_same(a, b)		((a).pte == (b).pte)
+#define pte_page(x)		(mem_map + ((unsigned long)(((x).pte >> PAGE_SHIFT))))
+#define pte_none(x)		(!(x).pte)
+#define __mk_pte(page_nr,pgprot) __pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot))
+
+#define VMALLOC_VMADDR(x)	((unsigned long) (x))
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * control flags in AMPR registers and TLB entries
+ */
+#define _PAGE_BIT_PRESENT	xAMPRx_V_BIT
+#define _PAGE_BIT_WP		DAMPRx_WP_BIT
+#define _PAGE_BIT_NOCACHE	xAMPRx_C_BIT
+#define _PAGE_BIT_SUPER		xAMPRx_S_BIT
+#define _PAGE_BIT_ACCESSED	xAMPRx_RESERVED8_BIT
+#define _PAGE_BIT_DIRTY		xAMPRx_M_BIT
+#define _PAGE_BIT_NOTGLOBAL	xAMPRx_NG_BIT
+
+#define _PAGE_PRESENT		xAMPRx_V
+#define _PAGE_WP		DAMPRx_WP
+#define _PAGE_NOCACHE		xAMPRx_C
+#define _PAGE_SUPER		xAMPRx_S
+#define _PAGE_ACCESSED		xAMPRx_RESERVED8	/* accessed if set */
+#define _PAGE_DIRTY		xAMPRx_M
+#define _PAGE_NOTGLOBAL		xAMPRx_NG
+
+#define _PAGE_RESERVED_MASK	(xAMPRx_RESERVED8 | xAMPRx_RESERVED13)
+
+#define _PAGE_PROTNONE		0x000	/* If not present */
+
+#define _PAGE_CHG_MASK		(PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+
+#define __PGPROT_BASE \
+	(_PAGE_PRESENT | xAMPRx_SS_16Kb | xAMPRx_D | _PAGE_NOTGLOBAL | _PAGE_ACCESSED)
+
+#define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
+#define PAGE_SHARED	__pgprot(__PGPROT_BASE)
+#define PAGE_COPY	__pgprot(__PGPROT_BASE | _PAGE_WP)
+#define PAGE_READONLY	__pgprot(__PGPROT_BASE | _PAGE_WP)
+
+#define __PAGE_KERNEL		(__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY)
+#define __PAGE_KERNEL_NOCACHE	(__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY | _PAGE_NOCACHE)
+#define __PAGE_KERNEL_RO	(__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY | _PAGE_WP)
+
+#define MAKE_GLOBAL(x) __pgprot((x) & ~_PAGE_NOTGLOBAL)
+
+#define PAGE_KERNEL		MAKE_GLOBAL(__PAGE_KERNEL)
+#define PAGE_KERNEL_RO		MAKE_GLOBAL(__PAGE_KERNEL_RO)
+#define PAGE_KERNEL_NOCACHE	MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
+
+#define _PAGE_TABLE		xAMPRx_V
+
+#ifndef __ASSEMBLY__
+
+/*
+ * The FR451 can do execute protection by virtue of having separate TLB miss handlers for
+ * instruction access and for data access. However, we don't have enough reserved bits to say
+ * "execute only", so we don't bother. If you can read it, you can execute it and vice versa.
+ */
+#define __P000	PAGE_NONE
+#define __P001	PAGE_READONLY
+#define __P010	PAGE_COPY
+#define __P011	PAGE_COPY
+#define __P100	PAGE_READONLY
+#define __P101	PAGE_READONLY
+#define __P110	PAGE_COPY
+#define __P111	PAGE_COPY
+
+#define __S000	PAGE_NONE
+#define __S001	PAGE_READONLY
+#define __S010	PAGE_SHARED
+#define __S011	PAGE_SHARED
+#define __S100	PAGE_READONLY
+#define __S101	PAGE_READONLY
+#define __S110	PAGE_SHARED
+#define __S111	PAGE_SHARED
+
+/*
+ * Define this to warn about kernel memory accesses that are
+ * done without a 'verify_area(VERIFY_WRITE,..)'
+ */
+#undef TEST_VERIFY_AREA
+
+#define pte_present(x)	(pte_val(x) & _PAGE_PRESENT)
+#define pte_clear(xp)	do { set_pte(xp, __pte(0)); } while (0)
+
+#define pmd_none(x)	(!pmd_val(x))
+#define pmd_present(x)	(pmd_val(x) & _PAGE_PRESENT)
+#define	pmd_bad(x)	(pmd_val(x) & 0xf0)
+#define pmd_clear(xp)	do { __set_pmd(xp, 0); } while(0)
+
+
+#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+static inline int pte_read(pte_t pte)		{ return !((pte).pte & _PAGE_SUPER); }
+static inline int pte_exec(pte_t pte)		{ return !((pte).pte & _PAGE_SUPER); }
+static inline int pte_dirty(pte_t pte)		{ return (pte).pte & _PAGE_DIRTY; }
+static inline int pte_young(pte_t pte)		{ return (pte).pte & _PAGE_ACCESSED; }
+static inline int pte_write(pte_t pte)		{ return !((pte).pte & _PAGE_WP); }
+
+static inline pte_t pte_rdprotect(pte_t pte)	{ (pte).pte |= _PAGE_SUPER; return pte; }
+static inline pte_t pte_exprotect(pte_t pte)	{ (pte).pte |= _PAGE_SUPER; return pte; }
+static inline pte_t pte_mkclean(pte_t pte)	{ (pte).pte &= ~_PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkold(pte_t pte)	{ (pte).pte &= ~_PAGE_ACCESSED; return pte; }
+static inline pte_t pte_wrprotect(pte_t pte)	{ (pte).pte |= _PAGE_WP; return pte; }
+static inline pte_t pte_mkread(pte_t pte)	{ (pte).pte &= ~_PAGE_SUPER; return pte; }
+static inline pte_t pte_mkexec(pte_t pte)	{ (pte).pte &= ~_PAGE_SUPER; return pte; }
+static inline pte_t pte_mkdirty(pte_t pte)	{ (pte).pte |= _PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkyoung(pte_t pte)	{ (pte).pte |= _PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkwrite(pte_t pte)	{ (pte).pte &= ~_PAGE_WP; return pte; }
+
+static inline int ptep_test_and_clear_dirty(pte_t *ptep)
+{
+	int i = test_and_clear_bit(_PAGE_BIT_DIRTY, ptep);
+	asm volatile("dcf %M0" :: "U"(*ptep));
+	return i;
+}
+
+static inline int ptep_test_and_clear_young(pte_t *ptep)
+{
+	int i = test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep);
+	asm volatile("dcf %M0" :: "U"(*ptep));
+	return i;
+}
+
+static inline pte_t ptep_get_and_clear(pte_t *ptep)
+{
+	unsigned long x = xchg(&ptep->pte, 0);
+	asm volatile("dcf %M0" :: "U"(*ptep));
+	return __pte(x);
+}
+
+static inline void ptep_set_wrprotect(pte_t *ptep)
+{
+	set_bit(_PAGE_BIT_WP, ptep);
+	asm volatile("dcf %M0" :: "U"(*ptep));
+}
+
+static inline void ptep_mkdirty(pte_t *ptep)
+{
+	set_bit(_PAGE_BIT_DIRTY, ptep);
+	asm volatile("dcf %M0" :: "U"(*ptep));
+}
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+
+#define mk_pte(page, pgprot)	__mk_pte((page) - mem_map, (pgprot))
+
+/* This takes a physical page address that is used by the remapping functions */
+#define mk_pte_phys(physpage, pgprot)	__mk_pte((physpage) >> PAGE_SHIFT, pgprot)
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+	pte.pte &= _PAGE_CHG_MASK;
+	pte.pte |= pgprot_val(newprot);
+	return pte;
+}
+
+#define page_pte(page)	page_pte_prot(page, __pgprot(0))
+
+#define pmd_page(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+
+/* to find an entry in a page-table-directory. */
+#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
+
+#define __pgd_offset(address) pgd_index(address)
+
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+/* Find an entry in the third-level page table.. */
+#define __pte_index(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset(dir, address) ((pte_t *) pmd_page(*(dir)) + __pte_index(address))
+
+/*
+ * preload information about a newly instantiated PTE into the SCR0/SCR1 PGE cache
+ */
+static inline void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+{
+	unsigned long ampr;
+	pmd_t *pme = pmd_offset(pgd_offset(current->mm, address), address);
+
+	ampr = pme->ste[0] & 0xffffff00;
+	ampr |= xAMPRx_L | xAMPRx_SS_16Kb | xAMPRx_S | xAMPRx_C | xAMPRx_V;
+
+	asm volatile("movgs %0,scr0\n"
+		     "movgs %0,scr1\n"
+		     "movgs %1,dampr4\n"
+		     "movgs %1,dampr5\n"
+		     :
+		     : "r"(address), "r"(ampr)
+		     );
+}
+
+#ifdef CONFIG_PROC_FS
+extern char *proc_pid_status_frv_cxnr(struct mm_struct *mm, char *buffer);
+#endif
+
+/*
+ * Encode and de-code a swap entry (swap entries have xAMPR.V bits clear)
+ */
+#define SWP_TYPE(x)			(((x).val >> 1) & 0x3f)
+#define SWP_OFFSET(x)			((x).val >> 8)
+#define SWP_ENTRY(type, offset)		((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
+#define pte_to_swp_entry(xpte)		((swp_entry_t) { (xpte).pte })
+#define swp_entry_to_pte(x)		((pte_t) { (x).val })
+
+struct page;
+int change_page_attr(struct page *, int, pgprot_t prot);
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+#define PageSkip(page)		(0)
+#define kern_addr_valid(addr)	(1)
+
+#define io_remap_page_range	remap_page_range
+
+#endif /* !__ASSEMBLY__ */
+#endif /* CONFIG_UCLINUX */
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()   do { } while (0)
+
+#ifndef __ASSEMBLY__
+extern void paging_init(void);
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_PGTABLE_H */
diff -urN linux-2.4.29/include/asm-frv/poll.h linux-2.4.29-uc1/include/asm-frv/poll.h
--- linux-2.4.29/include/asm-frv/poll.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/poll.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,23 @@
+#ifndef _ASM_POLL_H
+#define _ASM_POLL_H
+
+#define POLLIN		  1
+#define POLLPRI		  2
+#define POLLOUT		  4
+#define POLLERR		  8
+#define POLLHUP		 16
+#define POLLNVAL	 32
+#define POLLRDNORM	 64
+#define POLLWRNORM	POLLOUT
+#define POLLRDBAND	128
+#define POLLWRBAND	256
+#define POLLMSG		0x0400
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+#endif
+
diff -urN linux-2.4.29/include/asm-frv/posix_types.h linux-2.4.29-uc1/include/asm-frv/posix_types.h
--- linux-2.4.29/include/asm-frv/posix_types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/posix_types.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,66 @@
+#ifndef _ASM_POSIX_TYPES_H
+#define _ASM_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned short	__kernel_dev_t;
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned short	__kernel_mode_t;
+typedef unsigned short	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
+typedef unsigned short	__kernel_uid_t;
+typedef unsigned short	__kernel_gid_t;
+typedef unsigned int	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_timer_t;
+typedef int		__kernel_clockid_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+typedef unsigned short	__kernel_old_uid_t;
+typedef unsigned short	__kernel_old_gid_t;
+
+#ifdef __GNUC__
+typedef long long	__kernel_loff_t;
+#endif
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+	int	val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+	int	__val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#undef	__FD_SET
+#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+
+#undef	__FD_CLR
+#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+
+#undef	__FD_ISSET
+#define	__FD_ISSET(d, set)	(!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d)))
+
+#undef	__FD_ZERO
+#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif
+
diff -urN linux-2.4.29/include/asm-frv/processor.h linux-2.4.29-uc1/include/asm-frv/processor.h
--- linux-2.4.29/include/asm-frv/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/processor.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,177 @@
+/* processor.h: FRV processor definitions
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_PROCESSOR_H
+#define _ASM_PROCESSOR_H
+
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <asm/mem-layout.h>
+
+#ifdef CONFIG_SMALL_TASKS
+#define THREAD_SIZE	4096
+#else
+#define THREAD_SIZE	8192
+#endif
+
+#ifndef __ASSEMBLY__
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#include <linux/linkage.h>
+#include <asm/vmlinux.h>
+#include <asm/segment.h>
+#include <asm/fpu.h>
+#include <asm/registers.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+#include <asm/cache.h>
+#include <asm/a.out.h>
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/*
+ *  CPU type and hardware bug flags. Kept separately for each CPU.
+ */
+struct cpuinfo_frv {
+#ifndef CONFIG_UCLINUX
+	unsigned long	*pgd_quick;
+	unsigned long	*pte_quick;
+	unsigned long	pgtable_cache_sz;
+#endif
+} __cacheline_aligned;
+
+extern struct cpuinfo_frv __nongprelbss boot_cpu_data;
+
+#define cpu_data		(&boot_cpu_data)
+#define current_cpu_data	boot_cpu_data
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define MCA_bus 0
+
+struct thread_struct {
+	struct pt_regs		*frame;		/* [GR28] exception frame ptr for this thread */
+	struct task_struct	*curr;		/* [GR29] current pointer for this thread */
+	unsigned long		sp;		/* [GR1 ] kernel stack pointer */
+	unsigned long		fp;		/* [GR2 ] kernel frame pointer */
+	unsigned long		lr;		/* link register */
+	unsigned long		pc;		/* program counter */
+	unsigned long		gr[12];		/* [GR16-GR27] */
+	unsigned long		sched_lr;	/* LR from schedule() */
+
+	union {
+		struct pt_regs		*frame0;	/* top (user) stack frame */
+		struct user_context	*user;		/* userspace context */
+	};
+} __attribute__((aligned(8)));
+
+extern struct pt_regs *__kernel_frame0_ptr;
+extern struct task_struct *__kernel_current_task;
+
+#endif
+
+#ifndef __ASSEMBLY__
+#define INIT_THREAD_FRAME0 \
+	((struct pt_regs *) \
+	(sizeof(init_stack) + (unsigned long) init_stack - sizeof(struct user_context)))
+
+#define INIT_THREAD {				\
+	NULL,					\
+	(struct task_struct *) init_stack,	\
+	0, 0, 0, 0,				\
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },	\
+	0,					\
+	{ INIT_THREAD_FRAME0 },			\
+}
+
+/*
+ * do necessary setup to start up a newly executed thread.
+ * - need to discard the frame stacked by init() invoking the execve syscall
+ */
+#define start_thread(_regs, _pc, _usp)			\
+do {							\
+	set_fs(USER_DS); /* reads from user space */	\
+	__frame = __kernel_frame0_ptr;			\
+	__frame->pc	= (_pc);			\
+	__frame->psr	&= ~PSR_S;			\
+	__frame->sp	= (_usp);			\
+} while(0)
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+extern asmlinkage int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+extern asmlinkage void save_user_regs(struct user_context *target);
+extern asmlinkage void *restore_user_regs(const struct user_context *target, ...);
+
+#define copy_segments(tsk, mm)		do { } while (0)
+#define release_segments(mm)		do { } while (0)
+#define forget_segments()		do { } while (0)
+
+/*
+ * Free current thread data structures etc..
+ */
+static inline void exit_thread(void)
+{
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+static inline unsigned long thread_saved_pc(struct thread_struct *t)
+{
+	extern void scheduling_functions_start_here(void);
+	extern void scheduling_functions_end_here(void);
+
+	/* Check whether the thread is blocked in resume() */
+	if (t->pc > (unsigned long) scheduling_functions_start_here &&
+	    t->pc < (unsigned long) scheduling_functions_end_here)
+		return ((unsigned long *)t->fp)[2];
+	else
+		return t->pc;
+}
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define	KSTK_EIP(tsk)	((tsk)->thread.frame0->pc)
+#define	KSTK_ESP(tsk)	((tsk)->thread.frame0->sp)
+
+/* Allocation and freeing of basic task resources. */
+extern struct task_struct *alloc_task_struct(void);
+extern void free_task_struct(struct task_struct *p);
+extern void get_task_struct(struct task_struct *p);
+
+#define __alloc_task_struct alloc_task_struct
+#define __free_task_struct free_task_struct
+
+#define init_task		(init_task_union.task)
+#define init_stack		(init_task_union.stack)
+
+#define cpu_relax()    do { } while (0)
+
+/* data cache prefetch */
+#define ARCH_HAS_PREFETCH
+static inline void prefetch(const void *x)
+{
+	asm volatile("dcpl %0,gr0,#0" : : "r"(x));
+}
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_PROCESSOR_H */
diff -urN linux-2.4.29/include/asm-frv/ptrace.h linux-2.4.29-uc1/include/asm-frv/ptrace.h
--- linux-2.4.29/include/asm-frv/ptrace.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/ptrace.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,89 @@
+/* ptrace.h: ptrace() relevant definitions
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_PTRACE_H
+#define _ASM_PTRACE_H
+
+#include <asm/registers.h>
+
+#define in_syscall(regs) (((regs)->tbr & TBR_TT) == TBR_TT_TRAP0)
+
+
+#define PT_PSR		0
+#define	PT_ISR		1
+#define PT_CCR		2
+#define PT_CCCR		3
+#define PT_LR		4
+#define PT_LCR		5
+#define PT_PC		6
+
+#define PT__STATUS	7	/* exception status */
+#define PT_SYSCALLNO	8	/* syscall number or -1 */
+#define PT_ORIG_GR8	9	/* saved GR8 for signal handling */
+#define PT_GNER0	10
+#define PT_GNER1	11
+#define PT_IACC0H	12
+#define PT_IACC0L	13
+
+#define PT_GR(j)	( 14 + (j))	/* GRj for 0<=j<=63 */
+#define PT_FR(j)	( 78 + (j))	/* FRj for 0<=j<=63 */
+#define PT_FNER(j)	(142 + (j))	/* FNERj for 0<=j<=1 */
+#define PT_MSR(j)	(144 + (j))	/* MSRj for 0<=j<=2 */
+#define PT_ACC(j)	(146 + (j))	/* ACCj for 0<=j<=7 */
+#define PT_ACCG(jklm)	(154 + (jklm))	/* ACCGjklm for 0<=jklm<=1 (reads four regs per slot) */
+#define PT_FSR(j)	(156 + (j))	/* FSRj for 0<=j<=0 */
+#define PT__GPEND	78
+#define PT__END		157
+
+#define PT_TBR		PT_GR(0)
+#define PT_SP		PT_GR(1)
+#define PT_FP		PT_GR(2)
+#define PT_PREV_FRAME	PT_GR(28)	/* previous exception frame pointer (old gr28 value) */
+#define PT_CURR_TASK	PT_GR(29)	/* current task */
+
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS		12
+#define PTRACE_SETREGS		13
+#define PTRACE_GETFPREGS	14
+#define PTRACE_SETFPREGS	15
+#define PTRACE_GETFDPIC		31	/* get the ELF fdpic loadmap address */
+
+#define PTRACE_GETFDPIC_EXEC	0	/* [addr] request the executable loadmap */
+#define PTRACE_GETFDPIC_INTERP	1	/* [addr] request the interpreter loadmap */
+
+#ifndef __ASSEMBLY__
+
+/*
+ * dedicate GR28; to keeping the a pointer to the current exception frame
+ */
+register struct pt_regs *__frame asm("gr28");
+register struct pt_regs *__debug_frame asm("gr31");
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({			\
+        const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
+        (type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+#define __debug_regs container_of(__debug_frame, struct pt_debug_regs, normal_regs)
+
+#define user_mode(regs)			(!((regs)->psr & PSR_S))
+#define instruction_pointer(regs)	((regs)->pc)
+
+extern unsigned long user_stack(const struct pt_regs *);
+extern void show_regs(struct pt_regs *);
+extern void show_stack(struct pt_regs *);
+
+struct task_struct;
+extern void ptrace_disable(struct task_struct *child);
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASM_PTRACE_H */
diff -urN linux-2.4.29/include/asm-frv/registers.h linux-2.4.29-uc1/include/asm-frv/registers.h
--- linux-2.4.29/include/asm-frv/registers.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/registers.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,255 @@
+/* registers.h: register frame declarations
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
+ * notes:
+ *
+ * (1) that the members of all these structures are carefully aligned to permit
+ *     usage of STD/STDF instructions
+ *
+ * (2) if you change these structures, you must change the code in
+ *     arch/frvnommu/kernel/{break.S,entry.S,switch_to.S,gdb-stub.c}
+ *
+ *
+ * the kernel stack space block looks like this:
+ *
+ *	+0x2000	+----------------------
+ *		| union {
+ *		|	struct user_context
+ *		|	struct pt_regs [user exception]
+ *		| }
+ *		+---------------------- <-- __kernel_frame0_ptr (maybe GR28)
+ *		|
+ *		| kernel stack
+ *		|
+ *		|......................
+ *		| struct pt_regs [kernel exception]
+ *		|...................... <-- __kernel_frame0_ptr (maybe GR28)
+ *		|
+ *		| kernel stack
+ *		|
+ *		|...................... <-- stack pointer (GR1)
+ *		|
+ *		| unused stack space
+ *		|
+ *		+----------------------
+ *		| struct task_struct
+ *	+0x0000	+---------------------- <-- current (GR29);
+ *	
+ * note that GR28 points to the current exception frame
+ */
+
+#ifndef _ASM_REGISTERS_H
+#define _ASM_REGISTERS_H
+
+#ifndef __ASSEMBLY__
+#define __OFFSET(X)	(X)
+#define __OFFSETC(X,N)	xxxxxxxxxxxxxxxxxxxxxxxx
+#else
+#define __OFFSET(X)	((X)*4)
+#define __OFFSETC(X,N)	((X)*4+(N))
+#endif
+
+/*****************************************************************************/
+/*
+ * Exception/Interrupt frame
+ * - held on kernel stack
+ * - 8-byte aligned on stack (old SP is saved in frame)
+ * - GR0 is fixed 0, so we don't save it
+ */
+#ifndef __ASSEMBLY__
+
+struct pt_regs {
+	unsigned long		psr;		/* Processor Status Register */
+	unsigned long		isr;		/* Integer Status Register */
+	unsigned long		ccr;		/* Condition Code Register */
+	unsigned long		cccr;		/* Condition Code for Conditional Insns Register */
+	unsigned long		lr;		/* Link Register */
+	unsigned long		lcr;		/* Loop Count Register */
+	unsigned long		pc;		/* Program Counter Register */
+	unsigned long		__status;	/* exception status */
+	unsigned long		syscallno;	/* syscall number or -1 */
+	unsigned long		orig_gr8;	/* original syscall arg #1 */
+	unsigned long		gner0;
+	unsigned long		gner1;
+	unsigned long long	iacc0;
+	unsigned long		tbr;		/* GR0 is fixed zero, so we use this for TBR */
+	unsigned long		sp;		/* GR1: USP/KSP */
+	unsigned long		fp;		/* GR2: FP */
+	unsigned long		gr3;
+	unsigned long		gr4;
+	unsigned long		gr5;
+	unsigned long		gr6;
+	unsigned long		gr7;		/* syscall number */
+	unsigned long		gr8;		/* 1st syscall param; syscall return */
+	unsigned long		gr9;		/* 2nd syscall param */
+	unsigned long		gr10;		/* 3rd syscall param */
+	unsigned long		gr11;		/* 4th syscall param */
+	unsigned long		gr12;		/* 5th syscall param */
+	unsigned long		gr13;		/* 6th syscall param */
+	unsigned long		gr14;
+	unsigned long		gr15;
+	unsigned long		gr16;		/* GP pointer */
+	unsigned long		gr17;		/* small data */
+	unsigned long		gr18;		/* PIC/PID */
+	unsigned long		gr19;
+	unsigned long		gr20;
+	unsigned long		gr21;
+	unsigned long		gr22;
+	unsigned long		gr23;
+	unsigned long		gr24;
+	unsigned long		gr25;
+	unsigned long		gr26;
+	unsigned long		gr27;
+	struct pt_regs		*next_frame;	/* GR28 - next exception frame */
+	unsigned long		gr29;		/* GR29 - OS reserved */
+	unsigned long		gr30;		/* GR30 - OS reserved */
+	unsigned long		gr31;		/* GR31 - OS reserved */
+} __attribute__((aligned(8)));
+
+#endif
+
+#define REG_PSR		__OFFSET( 0)	/* Processor Status Register */
+#define REG_ISR		__OFFSET( 1)	/* Integer Status Register */
+#define REG_CCR		__OFFSET( 2)	/* Condition Code Register */
+#define REG_CCCR	__OFFSET( 3)	/* Condition Code for Conditional Insns Register */
+#define REG_LR		__OFFSET( 4)	/* Link Register */
+#define REG_LCR		__OFFSET( 5)	/* Loop Count Register */
+#define REG_PC		__OFFSET( 6)	/* Program Counter */
+
+#define REG__STATUS	__OFFSET( 7)	/* exception status */
+#define REG__STATUS_STEP	0x00000001	/* - reenable single stepping on return */
+#define REG__STATUS_STEPPED	0x00000002	/* - single step caused exception */
+#define REG__STATUS_BROKE	0x00000004	/* - BREAK insn caused exception */
+#define REG__STATUS_SYSC_ENTRY	0x40000000	/* - T on syscall entry (ptrace.c only) */
+#define REG__STATUS_SYSC_EXIT	0x80000000	/* - T on syscall exit (ptrace.c only) */
+
+#define REG_SYSCALLNO	__OFFSET( 8)	/* syscall number or -1 */
+#define REG_ORIG_GR8	__OFFSET( 9)	/* saved GR8 for signal handling */
+#define REG_GNER0	__OFFSET(10)
+#define REG_GNER1	__OFFSET(11)
+#define REG_IACC0	__OFFSET(12)
+
+#define REG_TBR		__OFFSET(14)	/* Trap Vector Register */
+#define REG_GR(R)	__OFFSET((14+(R)))
+#define REG__END	REG_GR(32)
+
+#define REG_SP		REG_GR(1)
+#define REG_FP		REG_GR(2)
+#define REG_PREV_FRAME	REG_GR(28)	/* previous exception frame pointer (old gr28 value) */
+#define REG_CURR_TASK	REG_GR(29)	/* current task */
+
+/*****************************************************************************/
+/*
+ * extension tacked in front of the exception frame in debug mode
+ */
+#ifndef __ASSEMBLY__
+
+struct pt_debug_regs
+{
+	unsigned long		bpsr;
+	unsigned long		dcr;
+	unsigned long		brr;
+	unsigned long		nmar;
+	struct pt_regs		normal_regs;
+} __attribute__((aligned(8)));
+
+#endif
+
+#define REG_NMAR		__OFFSET(-1)
+#define REG_BRR			__OFFSET(-2)
+#define REG_DCR			__OFFSET(-3)
+#define REG_BPSR		__OFFSET(-4)
+#define REG__DEBUG_XTRA		__OFFSET(4)
+
+/*****************************************************************************/
+/*
+ * userspace registers
+ */
+#ifndef __ASSEMBLY__
+
+struct user_int_regs
+{
+	/* integer registers
+	 * - up to gr[31] mirror pt_regs
+	 * - total size must be multiple of 8 bytes
+	 */
+	unsigned long		psr;		/* Processor Status Register */
+	unsigned long		isr;		/* Integer Status Register */
+	unsigned long		ccr;		/* Condition Code Register */
+	unsigned long		cccr;		/* Condition Code for Conditional Insns Register */
+	unsigned long		lr;		/* Link Register */
+	unsigned long		lcr;		/* Loop Count Register */
+	unsigned long		pc;		/* Program Counter Register */
+	unsigned long		__status;	/* exception status */
+	unsigned long		syscallno;	/* syscall number or -1 */
+	unsigned long		orig_gr8;	/* original syscall arg #1 */
+	unsigned long		gner[2];
+	unsigned long long	iacc[1];
+
+	union {
+		unsigned long	tbr;
+		unsigned long	gr[64];
+	};
+};
+
+struct user_fpmedia_regs
+{
+	/* FP/Media registers */
+	unsigned long	fr[64];
+	unsigned long	fner[2];
+	unsigned long	msr[2];
+	unsigned long	acc[8];
+	unsigned char	accg[8];
+	unsigned long	fsr[1];
+};
+
+struct user_context
+{
+	struct user_int_regs		i;
+	struct user_fpmedia_regs	f;
+
+	/* we provide a context extension so that we can save the regs for CPUs that
+	 * implement many more of Fujitsu's lavish register spec
+	 */
+	void *extension;
+} __attribute__((aligned(8)));
+
+#endif
+
+#define NR_USER_INT_REGS	(14 + 64)
+#define NR_USER_FPMEDIA_REGS	(64 + 2 + 2 + 8 + 8/4 + 1)
+#define NR_USER_CONTEXT		(NR_USER_INT_REGS + NR_USER_FPMEDIA_REGS + 1)
+
+#define USER_CONTEXT_SIZE	(((NR_USER_CONTEXT + 1) & ~1) * 4)
+
+#define __THREAD_FRAME		__OFFSET(0)
+#define __THREAD_CURR		__OFFSET(1)
+#define __THREAD_SP		__OFFSET(2)
+#define __THREAD_FP		__OFFSET(3)
+#define __THREAD_LR		__OFFSET(4)
+#define __THREAD_PC		__OFFSET(5)
+#define __THREAD_GR(R)		__OFFSET(6 + (R) - 16)
+#define __THREAD_FRAME0		__OFFSET(19)
+#define __THREAD_USER		__OFFSET(19)
+
+#define __USER_INT		__OFFSET(0)
+#define __INT_GR(R)		__OFFSET(14 + (R))
+
+#define __USER_FPMEDIA		__OFFSET(NR_USER_INT_REGS)
+#define __FPMEDIA_FR(R)		__OFFSET(NR_USER_INT_REGS + (R))
+#define __FPMEDIA_FNER(R)	__OFFSET(NR_USER_INT_REGS + 64 + (R))
+#define __FPMEDIA_MSR(R)	__OFFSET(NR_USER_INT_REGS + 66 + (R))
+#define __FPMEDIA_ACC(R)	__OFFSET(NR_USER_INT_REGS + 68 + (R))
+#define __FPMEDIA_ACCG(R)	__OFFSETC(NR_USER_INT_REGS + 76, (R))
+#define __FPMEDIA_FSR(R)	__OFFSET(NR_USER_INT_REGS + 78 + (R))
+
+#endif /* _ASM_REGISTERS_H */
diff -urN linux-2.4.29/include/asm-frv/resource.h linux-2.4.29-uc1/include/asm-frv/resource.h
--- linux-2.4.29/include/asm-frv/resource.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/resource.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,48 @@
+#ifndef _ASM_RESOURCE_H
+#define _ASM_RESOURCE_H
+
+/*
+ * Resource limits
+ */
+
+#define RLIMIT_CPU	0		/* CPU time in ms */
+#define RLIMIT_FSIZE	1		/* Maximum filesize */
+#define RLIMIT_DATA	2		/* max data size */
+#define RLIMIT_STACK	3		/* max stack size */
+#define RLIMIT_CORE	4		/* max core file size */
+#define RLIMIT_RSS	5		/* max resident set size */
+#define RLIMIT_NPROC	6		/* max number of processes */
+#define RLIMIT_NOFILE	7		/* max number of open files */
+#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
+#define RLIMIT_AS	9		/* address space limit */
+#define RLIMIT_LOCKS	10		/* maximum file locks held */
+
+#define RLIM_NLIMITS	11
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway.
+ */
+#define RLIM_INFINITY	(~0UL)
+
+#ifdef __KERNEL__
+
+#define INIT_RLIMITS					\
+{							\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{      _STK_LIM, RLIM_INFINITY },		\
+	{             0, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{             0,             0 },		\
+	{      INR_OPEN,     INR_OPEN  },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+        { RLIM_INFINITY, RLIM_INFINITY },		\
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_RESOURCE_H */
+
diff -urN linux-2.4.29/include/asm-frv/scatterlist.h linux-2.4.29-uc1/include/asm-frv/scatterlist.h
--- linux-2.4.29/include/asm-frv/scatterlist.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/scatterlist.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,32 @@
+#ifndef _ASM_SCATTERLIST_H
+#define _ASM_SCATTERLIST_H
+
+/*
+ * Drivers must set either ->address or (preferred) ->page and ->offset
+ * to indicate where data must be transferred to/from.
+ *
+ * Using ->page is recommended since it handles highmem data as well as
+ * low mem. ->address is restricted to data which has a virtual mapping, and
+ * it will go away in the future. Updating to ->page can be automated very
+ * easily -- something like
+ *
+ * sg->address = some_ptr;
+ *
+ * can be rewritten as
+ *
+ * sg->page = virt_to_page(some_ptr);
+ * sg->offset = (unsigned long) some_ptr & ~PAGE_MASK;
+ *
+ * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens
+ */
+struct scatterlist {
+	char		*address;	/* Location data is to be transferred to, NULL for
+					 * highmem page */
+	struct page	*page;		/* Location for highmem page, if any */
+	unsigned int	offset;		/* for highmem, page offset */
+
+	dma_addr_t	dma_address;
+	unsigned int	length;
+};
+
+#endif /* !_ASM_SCATTERLIST_H */
diff -urN linux-2.4.29/include/asm-frv/segment.h linux-2.4.29-uc1/include/asm-frv/segment.h
--- linux-2.4.29/include/asm-frv/segment.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/segment.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,46 @@
+/* segment.h: MMU segment settings
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SEGMENT_H
+#define _ASM_SEGMENT_H
+
+#include <linux/config.h>
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
+
+#define KERNEL_DS		MAKE_MM_SEG(0xdfffffffUL)
+
+#ifndef CONFIG_UCLINUX
+#define USER_DS			MAKE_MM_SEG(TASK_SIZE - 1)
+#else
+#define USER_DS			KERNEL_DS
+#endif
+
+#define get_ds()		(KERNEL_DS)
+#define get_fs()		(current->addr_limit)
+#define segment_eq(a,b)		((a).seg == (b).seg)
+#define __kernel_ds_p()		segment_eq(current->addr_limit, KERNEL_DS)
+#define get_addr_limit()	(current->addr_limit.seg)
+
+#define set_fs(_x)				\
+do {						\
+	current->addr_limit = (_x);		\
+} while(0)
+
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_SEGMENT_H */
diff -urN linux-2.4.29/include/asm-frv/semaphore.h linux-2.4.29-uc1/include/asm-frv/semaphore.h
--- linux-2.4.29/include/asm-frv/semaphore.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/semaphore.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,161 @@
+/* semaphore.h: semaphores for the FR-V
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_SEMAPHORE_H
+#define _ASM_SEMAPHORE_H
+
+#define RW_LOCK_BIAS		 0x01000000
+
+#ifndef __ASSEMBLY__
+
+#include <linux/linkage.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/rwsem.h>
+
+#define SEMAPHORE_DEBUG		WAITQUEUE_DEBUG
+
+/*
+ * the semaphore definition
+ * - if counter is >0 then there are tokens available on the semaphore for down to collect
+ * - if counter is <=0 then there are no spare tokens, and anyone that wants one must wait
+ * - if wait_list is not empty, then there are processes waiting for the semaphore
+ */
+struct semaphore {
+	unsigned		counter;
+	spinlock_t		wait_lock;
+	struct list_head	wait_list;
+#if SEMAPHORE_DEBUG
+	unsigned		__magic;
+#endif
+};
+
+#if SEMAPHORE_DEBUG
+# define __SEM_DEBUG_INIT(name) , (long)&(name).__magic
+#else
+# define __SEM_DEBUG_INIT(name)
+#endif
+
+
+#define __SEMAPHORE_INITIALIZER(name,count) \
+{ count, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) __SEM_DEBUG_INIT(name) }
+
+#define __MUTEX_INITIALIZER(name) \
+	__SEMAPHORE_INITIALIZER(name,1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+
+#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
+#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
+
+static inline void sema_init (struct semaphore *sem, int val)
+{
+	*sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val);
+}
+
+static inline void init_MUTEX (struct semaphore *sem)
+{
+	sema_init(sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+{
+	sema_init(sem, 0);
+}
+
+extern void __down(struct semaphore *sem, unsigned long flags);
+extern int  __down_interruptible(struct semaphore *sem, unsigned long flags);
+extern void __up(struct semaphore *sem);
+
+static inline void down(struct semaphore *sem)
+{
+	unsigned long flags;
+
+#if SEMAPHORE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	spin_lock_irqsave(&sem->wait_lock, flags);
+	if (likely(sem->counter > 0)) {
+		sem->counter--;
+		spin_unlock_irqrestore(&sem->wait_lock, flags);
+	}
+	else {
+		__down(sem, flags);
+	}
+}
+
+static inline int down_interruptible(struct semaphore *sem)
+{
+	unsigned long flags;
+	int ret = 0;
+
+#if SEMAPHORE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	spin_lock_irqsave(&sem->wait_lock, flags);
+	if (likely(sem->counter > 0)) {
+		sem->counter--;
+		spin_unlock_irqrestore(&sem->wait_lock, flags);
+	}
+	else {
+		ret = __down_interruptible(sem, flags);
+	}
+	return ret;
+}
+
+/*
+ * non-blockingly attempt to down() a semaphore.
+ * - returns zero if we acquired it
+ */
+static inline int down_trylock(struct semaphore *sem)
+{
+	unsigned long flags;
+	int success = 0;
+
+#if SEMAPHORE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	spin_lock_irqsave(&sem->wait_lock, flags);
+	if (sem->counter > 0) {
+		sem->counter--;
+		success = 1;
+	}
+	spin_unlock_irqrestore(&sem->wait_lock, flags);
+	return !success;
+}
+
+static inline void up(struct semaphore *sem)
+{
+	unsigned long flags;
+
+#if SEMAPHORE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	spin_lock_irqsave(&sem->wait_lock, flags);
+	if (!list_empty(&sem->wait_list))
+		__up(sem);
+	else
+		sem->counter++;
+	spin_unlock_irqrestore(&sem->wait_lock, flags);
+}
+
+static inline int sem_getcount(struct semaphore *sem)
+{
+	return sem->counter;
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff -urN linux-2.4.29/include/asm-frv/sembuf.h linux-2.4.29-uc1/include/asm-frv/sembuf.h
--- linux-2.4.29/include/asm-frv/sembuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/sembuf.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,26 @@
+#ifndef _ASM_SEMBUF_H
+#define _ASM_SEMBUF_H
+
+/* 
+ * The semid64_ds structure for FR-V architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm	sem_perm;	/* permissions .. see ipc.h */
+	__kernel_time_t		sem_otime;	/* last semop time */
+	unsigned long		__unused1;
+	__kernel_time_t		sem_ctime;	/* last change time */
+	unsigned long		__unused2;
+	unsigned long		sem_nsems;	/* no. of semaphores in array */
+	unsigned long		__unused3;
+	unsigned long		__unused4;
+};
+
+#endif /* _ASM_SEMBUF_H */
+
diff -urN linux-2.4.29/include/asm-frv/serial.h linux-2.4.29-uc1/include/asm-frv/serial.h
--- linux-2.4.29/include/asm-frv/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/serial.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+ * serial.h
+ *
+ * Copyright (C) 2003 Develer S.r.l. (http://www.develer.com/)
+ * Author: Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * Based on linux/include/asm-i386/serial.h
+ */
+#include <linux/config.h>
+#include <asm/serial-regs.h>
+
+/*
+ * This assumes you have a 1.8432 MHz clock for your UART.
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ */
+#define BASE_BAUD 0
+
+#define STD_COM_FLAGS		ASYNC_BOOT_AUTOCONF
+
+#define RS_TABLE_SIZE		2
+#define SERIAL_PORT_DFNS	{ line: 0 }, { line: 1 }
diff -urN linux-2.4.29/include/asm-frv/serial-regs.h linux-2.4.29-uc1/include/asm-frv/serial-regs.h
--- linux-2.4.29/include/asm-frv/serial-regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/serial-regs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,44 @@
+/* serial-regs.h: serial port registers
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SERIAL_REGS_H
+#define _ASM_SERIAL_REGS_H
+
+#include <linux/serial_reg.h>
+#include <asm/irc-regs.h>
+
+#define SERIAL_ICLK	33333333	/* the target serial input clock */
+#define UART0_BASE	0xfeff9c00
+#define UART1_BASE	0xfeff9c40
+
+#define __get_UART0(R) ({ __reg(UART0_BASE + (R) * 8) >> 24; })
+#define __get_UART1(R) ({ __reg(UART1_BASE + (R) * 8) >> 24; })
+#define __set_UART0(R,V) do { __reg(UART0_BASE + (R) * 8) = (V) << 24; } while(0)
+#define __set_UART1(R,V) do { __reg(UART1_BASE + (R) * 8) = (V) << 24; } while(0)
+
+#define __get_UART0_LSR() ({ __get_UART0(UART_LSR); })
+#define __get_UART1_LSR() ({ __get_UART1(UART_LSR); })
+
+#define __set_UART0_IER(V) __set_UART0(UART_IER,(V))
+#define __set_UART1_IER(V) __set_UART1(UART_IER,(V))
+
+/* serial prescaler select register */
+#define __get_UCPSR()	({ *(volatile unsigned long *)(0xfeff9c90); })
+#define __set_UCPSR(V)	do { *(volatile unsigned long *)(0xfeff9c90) = (V); } while(0)
+#define UCPSR_SELECT0	0x07000000
+#define UCPSR_SELECT1	0x38000000
+
+/* serial prescaler base value register */
+#define __get_UCPVR()	({ *(volatile unsigned long *)(0xfeff9c98); mb(); })
+#define __set_UCPVR(V)	do { *(volatile unsigned long *)(0xfeff9c98) = (V) << 24; mb(); } while(0)
+
+
+#endif /* _ASM_SERIAL_REGS_H */
diff -urN linux-2.4.29/include/asm-frv/setup.h linux-2.4.29-uc1/include/asm-frv/setup.h
--- linux-2.4.29/include/asm-frv/setup.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/setup.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1 @@
+/* not needed */
diff -urN linux-2.4.29/include/asm-frv/shmbuf.h linux-2.4.29-uc1/include/asm-frv/shmbuf.h
--- linux-2.4.29/include/asm-frv/shmbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/shmbuf.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,43 @@
+#ifndef _ASM_SHMBUF_H
+#define _ASM_SHMBUF_H
+
+/* 
+ * The shmid64_ds structure for FR-V architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	unsigned long		__unused1;
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	unsigned long		__unused2;
+	__kernel_time_t		shm_ctime;	/* last change time */
+	unsigned long		__unused3;
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _ASM_SHMBUF_H */
+
diff -urN linux-2.4.29/include/asm-frv/shm.h linux-2.4.29-uc1/include/asm-frv/shm.h
--- linux-2.4.29/include/asm-frv/shm.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/shm.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,33 @@
+#ifndef _ASM_SHM_H
+#define _ASM_SHM_H
+
+#include <linux/config.h>
+
+/* format of page table entries that correspond to shared memory pages
+   currently out in swap space (see also mm/swap.c):
+   bits 0-1 (PAGE_PRESENT) is  = 0
+   bits 8..2 (SWP_TYPE) are = SHM_SWP_TYPE
+   bits 31..9 are used like this:
+   bits 15..9 (SHM_ID) the id of the shared memory segment
+   bits 30..16 (SHM_IDX) the index of the page within the shared memory segment
+                    (actually only bits 25..16 get used since SHMMAX is so low)
+   bit 31 (SHM_READ_ONLY) flag whether the page belongs to a read-only attach
+*/
+/* on the m68k both bits 0 and 1 must be zero */
+/* format on the sun3 is similar, but bits 30, 31 are set to zero and all
+   others are reduced by 2. --m */
+
+#ifndef CONFIG_SUN3
+#define SHM_ID_SHIFT	9
+#else
+#define SHM_ID_SHIFT	7
+#endif
+#define _SHM_ID_BITS	7
+#define SHM_ID_MASK	((1<<_SHM_ID_BITS)-1)
+
+#define SHM_IDX_SHIFT	(SHM_ID_SHIFT+_SHM_ID_BITS)
+#define _SHM_IDX_BITS	15
+#define SHM_IDX_MASK	((1<<_SHM_IDX_BITS)-1)
+
+#endif /* _ASM_SHM_H */
+
diff -urN linux-2.4.29/include/asm-frv/shmparam.h linux-2.4.29-uc1/include/asm-frv/shmparam.h
--- linux-2.4.29/include/asm-frv/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/shmparam.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,7 @@
+#ifndef _ASM_SHMPARAM_H
+#define _ASM_SHMPARAM_H
+
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
+
+#endif /* _ASM_SHMPARAM_H */
+
diff -urN linux-2.4.29/include/asm-frv/sigcontext.h linux-2.4.29-uc1/include/asm-frv/sigcontext.h
--- linux-2.4.29/include/asm-frv/sigcontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/sigcontext.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,26 @@
+/* sigcontext.h: FRV signal context
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_SIGCONTEXT_H
+#define _ASM_SIGCONTEXT_H
+
+#include <asm/registers.h>
+
+/*
+ * Signal context structure - contains all info to do with the state
+ * before the signal handler was invoked.  Note: only add new entries
+ * to the end of the structure.
+ */
+struct sigcontext {
+	struct user_context	sc_context;
+	unsigned long		sc_oldmask; 	/* old sigmask */
+} __attribute__((aligned(8)));
+
+#endif
diff -urN linux-2.4.29/include/asm-frv/siginfo.h linux-2.4.29-uc1/include/asm-frv/siginfo.h
--- linux-2.4.29/include/asm-frv/siginfo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/siginfo.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,245 @@
+#ifndef _ASM_SIGINFO_H
+#define _ASM_SIGINFO_H
+
+#include <linux/types.h>
+
+/* This is copied from asm-alpha/siginfo.h.  */
+
+typedef union sigval {
+	int sival_int;
+	void *sival_ptr;
+} sigval_t;
+
+#define SI_MAX_SIZE	128
+#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct siginfo {
+	int si_signo;
+	int si_errno;
+	int si_code;
+
+	union {
+		int _pad[SI_PAD_SIZE];
+
+		/* kill() */
+		struct {
+			__kernel_pid_t _pid;	/* sender's pid */
+			__kernel_uid_t _uid;	/* backwards compatibility */
+			__kernel_uid32_t _uid32; /* sender's uid */
+		} _kill;
+
+		/* POSIX.1b signals */
+		struct {
+			__kernel_pid_t _pid;	/* sender's pid */
+			__kernel_uid_t _uid;	/* backwards compatibility */
+			sigval_t _sigval;
+			__kernel_uid32_t _uid32; /* sender's uid */
+		} _rt;
+
+		/* SIGCHLD */
+		struct {
+			__kernel_pid_t _pid;	/* which child */
+			__kernel_uid_t _uid;	/* backwards compatibility */
+			int _status;		/* exit code */
+			clock_t _utime;
+			clock_t _stime;
+			__kernel_uid32_t _uid32; /* sender's uid */
+		} _sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			void *_addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+	} _sifields;
+} siginfo_t;
+
+#define UID16_SIGINFO_COMPAT_NEEDED
+
+/*
+ * How these fields are to be accessed.
+ */
+#define si_pid		_sifields._kill._pid
+#ifdef __KERNEL__
+#define si_uid		_sifields._kill._uid32
+#define si_uid16	_sifields._kill._uid
+#else
+#define si_uid		_sifields._kill._uid
+#endif /* __KERNEL__ */
+#define si_tid		_sifields._timer._tid
+#define si_overrun	_sifields._timer._overrun
+#define si_sys_private  _sifields._timer._sys_private
+#define si_status	_sifields._sigchld._status
+#define si_utime	_sifields._sigchld._utime
+#define si_stime	_sifields._sigchld._stime
+#define si_value	_sifields._rt._sigval
+#define si_int		_sifields._rt._sigval.sival_int
+#define si_ptr		_sifields._rt._sigval.sival_ptr
+#define si_addr		_sifields._sigfault._addr
+#define si_band		_sifields._sigpoll._band
+#define si_fd		_sifields._sigpoll._fd
+
+#ifdef __KERNEL__
+#define __SI_MASK	0xffff0000
+#define __SI_KILL	(0 << 16)
+#define __SI_TIMER	(1 << 16)
+#define __SI_POLL	(2 << 16)
+#define __SI_FAULT	(3 << 16)
+#define __SI_CHLD	(4 << 16)
+#define __SI_RT		(5 << 16)
+#define __SI_CODE(T,N)	((T) | ((N) & 0xffff))
+#else
+#define __SI_KILL	0
+#define __SI_TIMER	0
+#define __SI_POLL	0
+#define __SI_FAULT	0
+#define __SI_CHLD	0
+#define __SI_RT		0
+#define __SI_CODE(T,N)	(N)
+#endif
+
+/*
+ * si_code values
+ * Digital reserves positive values for kernel-generated signals.
+ */
+#define SI_USER		0		/* sent by kill, sigsend, raise */
+#define SI_KERNEL	0x80		/* sent by the kernel from somewhere */
+#define SI_QUEUE	-1		/* sent by sigqueue */
+#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
+#define SI_MESGQ	-3		/* sent by real time mesq state change */
+#define SI_ASYNCIO	-4		/* sent by AIO completion */
+#define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
+
+#define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
+#define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
+
+/*
+ * SIGILL si_codes
+ */
+#define ILL_ILLOPC	(__SI_FAULT|1)	/* illegal opcode */
+#define ILL_ILLOPN	(__SI_FAULT|2)	/* illegal operand */
+#define ILL_ILLADR	(__SI_FAULT|3)	/* illegal addressing mode */
+#define ILL_ILLTRP	(__SI_FAULT|4)	/* illegal trap */
+#define ILL_PRVOPC	(__SI_FAULT|5)	/* privileged opcode */
+#define ILL_PRVREG	(__SI_FAULT|6)	/* privileged register */
+#define ILL_COPROC	(__SI_FAULT|7)	/* coprocessor error */
+#define ILL_BADSTK	(__SI_FAULT|8)	/* internal stack error */
+#define NSIGILL		8
+
+/*
+ * SIGFPE si_codes
+ */
+#define FPE_INTDIV	(__SI_FAULT|1)	/* integer divide by zero */
+#define FPE_INTOVF	(__SI_FAULT|2)	/* integer overflow */
+#define FPE_FLTDIV	(__SI_FAULT|3)	/* floating point divide by zero */
+#define FPE_FLTOVF	(__SI_FAULT|4)	/* floating point overflow */
+#define FPE_FLTUND	(__SI_FAULT|5)	/* floating point underflow */
+#define FPE_FLTRES	(__SI_FAULT|6)	/* floating point inexact result */
+#define FPE_FLTINV	(__SI_FAULT|7)	/* floating point invalid operation */
+#define FPE_FLTSUB	(__SI_FAULT|8)	/* subscript out of range */
+#define FPE_MDAOVF	(__SI_FAULT|9)	/* media overflow */
+#define NSIGFPE		9
+
+/*
+ * SIGSEGV si_codes
+ */
+#define SEGV_MAPERR	(__SI_FAULT|1)	/* address not mapped to object */
+#define SEGV_ACCERR	(__SI_FAULT|2)	/* invalid permissions for mapped object */
+#define NSIGSEGV	2
+
+/*
+ * SIGBUS si_codes
+ */
+#define BUS_ADRALN	(__SI_FAULT|1)	/* invalid address alignment */
+#define BUS_ADRERR	(__SI_FAULT|2)	/* non-existant physical address */
+#define BUS_OBJERR	(__SI_FAULT|3)	/* object specific hardware error */
+#define NSIGBUS		3
+
+/*
+ * SIGTRAP si_codes
+ */
+#define TRAP_BRKPT	(__SI_FAULT|1)	/* process breakpoint */
+#define TRAP_TRACE	(__SI_FAULT|2)	/* process trace trap */
+#define NSIGTRAP	2
+
+/*
+ * SIGCHLD si_codes
+ */
+#define CLD_EXITED	(__SI_CHLD|1)	/* child has exited */
+#define CLD_KILLED	(__SI_CHLD|2)	/* child was killed */
+#define CLD_DUMPED	(__SI_CHLD|3)	/* child terminated abnormally */
+#define CLD_TRAPPED	(__SI_CHLD|4)	/* traced child has trapped */
+#define CLD_STOPPED	(__SI_CHLD|5)	/* child has stopped */
+#define CLD_CONTINUED	(__SI_CHLD|6)	/* stopped child has continued */
+#define NSIGCHLD	6
+
+/*
+ * SIGPOLL si_codes
+ */
+#define POLL_IN		(__SI_POLL|1)	/* data input available */
+#define POLL_OUT	(__SI_POLL|2)	/* output buffers available */
+#define POLL_MSG	(__SI_POLL|3)	/* input message available */
+#define POLL_ERR	(__SI_POLL|4)	/* i/o error */
+#define POLL_PRI	(__SI_POLL|5)	/* high priority input available */
+#define POLL_HUP	(__SI_POLL|6)	/* device disconnected */
+#define NSIGPOLL	6
+
+/*
+ * sigevent definitions
+ * 
+ * It seems likely that SIGEV_THREAD will have to be handled from 
+ * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
+ * thread manager then catches and does the appropriate nonsense.
+ * However, everything is written out here so as to not get lost.
+ */
+#define SIGEV_SIGNAL	0	/* notify via signal */
+#define SIGEV_NONE	1	/* other notification: meaningless */
+#define SIGEV_THREAD	2	/* deliver via thread creation */
+#define SIGEV_THREAD_ID 4	/* deliver to thread */
+
+#define SIGEV_MAX_SIZE	64
+#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct sigevent {
+	sigval_t sigev_value;
+	int sigev_signo;
+	int sigev_notify;
+	union {
+		int _pad[SIGEV_PAD_SIZE];
+		int _tid;
+		struct {
+			void (*_function)(sigval_t);
+			void *_attribute;	/* really pthread_attr_t */
+		} _sigev_thread;
+	} _sigev_un;
+} sigevent_t;
+
+#define sigev_notify_function	_sigev_un._sigev_thread._function
+#define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
+#define sigev_notify_thread_id	_sigev_un._tid
+
+#ifdef __KERNEL__
+#include <linux/string.h>
+
+extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
+{
+	if (from->si_code < 0)
+		memcpy(to, from, sizeof(siginfo_t));
+	else
+		/* _sigchld is currently the largest know union member */
+		memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
+}
+
+extern void do_schedule_next_timer(struct siginfo *info);
+extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
+
+#endif /* __KERNEL__ */
+
+#endif
+
diff -urN linux-2.4.29/include/asm-frv/signal.h linux-2.4.29-uc1/include/asm-frv/signal.h
--- linux-2.4.29/include/asm-frv/signal.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/signal.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,184 @@
+#ifndef _ASM_SIGNAL_H
+#define _ASM_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
+
+#define SA_RESTORER	0x04000000
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#ifdef __KERNEL__
+
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE		SA_ONESHOT
+#define SA_SAMPLE_RANDOM	SA_RESTART
+#define SA_SHIRQ		0x04000000
+#endif
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+#ifdef __KERNEL__
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+
+#include <asm/sigcontext.h>
+#undef __HAVE_ARCH_SIG_BITOPS
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_SIGNAL_H */
diff -urN linux-2.4.29/include/asm-frv/smp.h linux-2.4.29-uc1/include/asm-frv/smp.h
--- linux-2.4.29/include/asm-frv/smp.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/smp.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,10 @@
+#ifndef __ASM_SMP_H
+#define __ASM_SMP_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_SMP
+#error SMP not supported
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-frv/smplock.h linux-2.4.29-uc1/include/asm-frv/smplock.h
--- linux-2.4.29/include/asm-frv/smplock.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/smplock.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,62 @@
+/*
+ * <asm/smplock.h>
+ *
+ * Default SMP lock implementation
+ */
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+extern spinlock_t kernel_flag;
+
+#ifdef CONFIG_SMP
+#define kernel_locked()		spin_is_locked(&kernel_flag)
+#else
+#define kernel_locked()		1
+#endif
+
+/*
+ * Release global kernel lock and global interrupt lock
+ */
+#define release_kernel_lock(task, cpu) \
+do { \
+	if (task->lock_depth >= 0) \
+		spin_unlock(&kernel_flag); \
+	release_irqlock(cpu); \
+	__sti(); \
+} while (0)
+
+/*
+ * Re-acquire the kernel lock
+ */
+#define reacquire_kernel_lock(task) \
+do { \
+	if (task->lock_depth >= 0) \
+		spin_lock(&kernel_flag); \
+} while (0)
+
+
+/*
+ * Getting the big kernel lock.
+ *
+ * This cannot happen asynchronously,
+ * so we only need to worry about other
+ * CPU's.
+ */
+extern __inline__ void lock_kernel(void)
+{
+#ifdef CONFIG_PREEMPT
+	if (current->lock_depth == -1)
+		spin_lock(&kernel_flag);
+	++current->lock_depth;
+#else
+	if (!++current->lock_depth)
+		spin_lock(&kernel_flag);
+#endif
+}
+
+extern __inline__ void unlock_kernel(void)
+{
+	if (--current->lock_depth < 0)
+		spin_unlock(&kernel_flag);
+}
+
diff -urN linux-2.4.29/include/asm-frv/socket.h linux-2.4.29-uc1/include/asm-frv/socket.h
--- linux-2.4.29/include/asm-frv/socket.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/socket.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,65 @@
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockopt(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED	16
+#define SO_PEERCRED	17
+#define SO_RCVLOWAT	18
+#define SO_SNDLOWAT	19
+#define SO_RCVTIMEO	20
+#define SO_SNDTIMEO	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE	25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME             28
+#define SO_TIMESTAMP		29
+#define SCM_TIMESTAMP		SO_TIMESTAMP
+
+#define SO_ACCEPTCONN		30
+
+/* Nast libc5 fixup - bletch */
+#if defined(__KERNEL__)
+/* Socket types. */
+#define SOCK_STREAM	1		/* stream (connection) socket	*/
+#define SOCK_DGRAM	2		/* datagram (conn.less) socket	*/
+#define SOCK_RAW	3		/* raw socket			*/
+#define SOCK_RDM	4		/* reliably-delivered message	*/
+#define SOCK_SEQPACKET	5		/* sequential packet socket	*/
+#define SOCK_PACKET	10		/* linux specific way of	*/
+					/* getting packets at the dev	*/
+					/* level.  For writing rarp and	*/
+					/* other similar things on the	*/
+					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
+#endif
+
+#endif /* _ASM_SOCKET_H */
+
diff -urN linux-2.4.29/include/asm-frv/sockios.h linux-2.4.29-uc1/include/asm-frv/sockios.h
--- linux-2.4.29/include/asm-frv/sockios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/sockios.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef _ASM_SOCKIOS__
+#define _ASM_SOCKIOS__
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 	0x8901
+#define SIOCSPGRP	0x8902
+#define FIOGETOWN	0x8903
+#define SIOCGPGRP	0x8904
+#define SIOCATMARK	0x8905
+#define SIOCGSTAMP	0x8906		/* Get stamp */
+
+#endif /* _ASM_SOCKIOS__ */
+
diff -urN linux-2.4.29/include/asm-frv/softirq.h linux-2.4.29-uc1/include/asm-frv/softirq.h
--- linux-2.4.29/include/asm-frv/softirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/softirq.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,27 @@
+#ifndef __ASM_SOFTIRQ_H
+#define __ASM_SOFTIRQ_H
+
+#include <asm/atomic.h>
+#include <asm/hardirq.h>
+
+#define __cpu_bh_enable(cpu) \
+		do { barrier(); local_bh_count(cpu)--; } while (0)
+#define cpu_bh_disable(cpu) \
+		do { local_bh_count(cpu)++; barrier(); } while (0)
+
+#define local_bh_disable()	cpu_bh_disable(smp_processor_id())
+#define __local_bh_enable()	__cpu_bh_enable(smp_processor_id())
+
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
+
+#define _local_bh_enable()				\
+do {							\
+	if (!--local_bh_count(smp_processor_id())	\
+	    && softirq_pending(smp_processor_id())) {	\
+		do_softirq();				\
+	}						\
+} while (0)
+
+#define local_bh_enable() do { _local_bh_enable(); } while (0)
+
+#endif
diff -urN linux-2.4.29/include/asm-frv/spinlock.h linux-2.4.29-uc1/include/asm-frv/spinlock.h
--- linux-2.4.29/include/asm-frv/spinlock.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/spinlock.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,17 @@
+/* spinlock.h: spinlocks for FR-V
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SPINLOCK_H
+#define _ASM_SPINLOCK_H
+
+#error no spinlocks for FR-V yet
+
+#endif /* _ASM_SPINLOCK_H */
diff -urN linux-2.4.29/include/asm-frv/spr-regs.h linux-2.4.29-uc1/include/asm-frv/spr-regs.h
--- linux-2.4.29/include/asm-frv/spr-regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/spr-regs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,401 @@
+/* spr-regs.h: special-purpose registers on the FRV
+ *
+ * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SPR_REGS_H
+#define _ASM_SPR_REGS_H
+
+/*
+ * PSR - Processor Status Register
+ */
+#define PSR_ET			0x00000001	/* enable interrupts/exceptions flag */
+#define PSR_PS			0x00000002	/* previous supervisor mode flag */
+#define PSR_S			0x00000004	/* supervisor mode flag */
+#define PSR_PIL			0x00000078	/* processor external interrupt level */
+#define PSR_PIL_0		0x00000000	/* - no interrupt in progress */
+#define PSR_PIL_13		0x00000068	/* - debugging only */
+#define PSR_PIL_14		0x00000070	/* - debugging in progress */
+#define PSR_PIL_15		0x00000078	/* - NMI in progress */
+#define PSR_EM			0x00000080	/* enable media operation */
+#define PSR_EF			0x00000100	/* enable FPU operation */
+#define PSR_BE			0x00001000	/* endianness mode */
+#define PSR_BE_LE		0x00000000	/* - little endian mode */
+#define PSR_BE_BE		0x00001000	/* - big endian mode */
+#define PSR_CM			0x00002000	/* conditional mode */
+#define PSR_NEM			0x00004000	/* non-excepting mode */
+#define PSR_ICE			0x00010000	/* in-circuit emulation mode */
+#define PSR_VERSION_SHIFT	24		/* CPU silicon ID */
+#define PSR_IMPLE_SHIFT		28		/* CPU core ID */
+
+#define PSR_VERSION(psr)	(((psr) >> PSR_VERSION_SHIFT) & 0xf)
+#define PSR_IMPLE(psr)		(((psr) >> PSR_IMPLE_SHIFT) & 0xf)
+
+#define PSR_IMPLE_FR401		0x2
+#define PSR_VERSION_FR401_MB93401	0x0
+#define PSR_VERSION_FR401_MB93401A	0x1
+#define PSR_VERSION_FR401_MB93403	0x2
+
+#define PSR_IMPLE_FR405		0x4
+#define PSR_VERSION_FR405_MB93405	0x0
+
+#define PSR_IMPLE_FR451		0x5
+#define PSR_VERSION_FR451_MB93451	0x0
+
+#define PSR_IMPLE_FR501		0x1
+#define PSR_VERSION_FR501_MB93501	0x1
+#define PSR_VERSION_FR501_MB93501A	0x2
+
+#define PSR_IMPLE_FR551		0x3
+#define PSR_VERSION_FR551_MB93555	0x1
+
+#define __get_PSR()	({ unsigned long x; asm volatile("movsg psr,%0" : "=r"(x)); x; })
+#define __set_PSR(V)	do { asm volatile("movgs %0,psr" : : "r"(V)); } while(0)
+
+/*
+ * TBR - Trap Base Register
+ */
+#define TBR_TT			0x00000ff0
+#define TBR_TT_INSTR_MMU_MISS	(0x01 << 4)
+#define TBR_TT_INSTR_ACC_ERROR	(0x02 << 4)
+#define TBR_TT_INSTR_ACC_EXCEP	(0x03 << 4)
+#define TBR_TT_PRIV_INSTR	(0x06 << 4)
+#define TBR_TT_ILLEGAL_INSTR	(0x07 << 4)
+#define TBR_TT_FP_EXCEPTION	(0x0d << 4)
+#define TBR_TT_MP_EXCEPTION	(0x0e << 4)
+#define TBR_TT_DATA_ACC_ERROR	(0x11 << 4)
+#define TBR_TT_DATA_MMU_MISS	(0x12 << 4)
+#define TBR_TT_DATA_ACC_EXCEP	(0x13 << 4)
+#define TBR_TT_DATA_STR_ERROR	(0x14 << 4)
+#define TBR_TT_DIVISION_EXCEP	(0x17 << 4)
+#define TBR_TT_COMMIT_EXCEP	(0x19 << 4)
+#define TBR_TT_INSTR_TLB_MISS	(0x1a << 4)
+#define TBR_TT_DATA_TLB_MISS	(0x1b << 4)
+#define TBR_TT_DATA_DAT_EXCEP	(0x1d << 4)
+#define TBR_TT_DECREMENT_TIMER	(0x1f << 4)
+#define TBR_TT_COMPOUND_EXCEP	(0x20 << 4)
+#define TBR_TT_INTERRUPT_1	(0x21 << 4)
+#define TBR_TT_INTERRUPT_2	(0x22 << 4)
+#define TBR_TT_INTERRUPT_3	(0x23 << 4)
+#define TBR_TT_INTERRUPT_4	(0x24 << 4)
+#define TBR_TT_INTERRUPT_5	(0x25 << 4)
+#define TBR_TT_INTERRUPT_6	(0x26 << 4)
+#define TBR_TT_INTERRUPT_7	(0x27 << 4)
+#define TBR_TT_INTERRUPT_8	(0x28 << 4)
+#define TBR_TT_INTERRUPT_9	(0x29 << 4)
+#define TBR_TT_INTERRUPT_10	(0x2a << 4)
+#define TBR_TT_INTERRUPT_11	(0x2b << 4)
+#define TBR_TT_INTERRUPT_12	(0x2c << 4)
+#define TBR_TT_INTERRUPT_13	(0x2d << 4)
+#define TBR_TT_INTERRUPT_14	(0x2e << 4)
+#define TBR_TT_INTERRUPT_15	(0x2f << 4)
+#define TBR_TT_TRAP0		(0x80 << 4)
+#define TBR_TT_TRAP1		(0x81 << 4)
+#define TBR_TT_TRAP2		(0x82 << 4)
+#define TBR_TT_TRAP126		(0xfe << 4)
+#define TBR_TT_BREAK		(0xff << 4)
+
+#define __get_TBR()	({ unsigned long x; asm volatile("movsg tbr,%0" : "=r"(x)); x; })
+
+/*
+ * HSR0 - Hardware Status Register 0
+ */
+#define HSR0_PDM		0x00000007	/* power down mode */
+#define HSR0_PDM_NORMAL		0x00000000	/* - normal mode */
+#define HSR0_PDM_CORE_SLEEP	0x00000001	/* - CPU core sleep mode */
+#define HSR0_PDM_BUS_SLEEP	0x00000003	/* - bus sleep mode */
+#define HSR0_PDM_PLL_RUN	0x00000005	/* - PLL run */
+#define HSR0_PDM_PLL_STOP	0x00000007	/* - PLL stop */
+#define HSR0_GRLE		0x00000040	/* GR lower register set enable */
+#define HSR0_GRHE		0x00000080	/* GR higher register set enable */
+#define HSR0_FRLE		0x00000100	/* FR lower register set enable */
+#define HSR0_FRHE		0x00000200	/* FR higher register set enable */
+#define HSR0_GRN		0x00000400	/* GR quantity */
+#define HSR0_GRN_64		0x00000000	/* - 64 GR registers */
+#define HSR0_GRN_32		0x00000400	/* - 32 GR registers */
+#define HSR0_FRN		0x00000800	/* FR quantity */
+#define HSR0_FRN_64		0x00000000	/* - 64 FR registers */
+#define HSR0_FRN_32		0x00000800	/* - 32 FR registers */
+#define HSR0_SA			0x00001000	/* start address (RAMBOOT#) */
+#define HSR0_ETMI		0x00008000	/* enable TIMERI (64-bit up timer) */
+#define HSR0_ETMD		0x00004000	/* enable TIMERD (32-bit down timer) */
+#define HSR0_PEDAT		0x00010000	/* previous DAT mode */
+#define HSR0_XEDAT		0x00020000	/* exception DAT mode */
+#define HSR0_EDAT		0x00080000	/* enable DAT mode */
+#define HSR0_RME		0x00400000	/* enable RAM mode */
+#define HSR0_EMEM		0x00800000	/* enable MMU_Miss mask */
+#define HSR0_EXMMU		0x01000000	/* enable extended MMU mode */
+#define HSR0_EDMMU		0x02000000	/* enable data MMU */
+#define HSR0_EIMMU		0x04000000	/* enable instruction MMU */
+#define HSR0_CBM		0x08000000	/* copy back mode */
+#define HSR0_CBM_WRITE_THRU	0x00000000	/* - write through */
+#define HSR0_CBM_COPY_BACK	0x08000000	/* - copy back */
+#define HSR0_NWA		0x10000000	/* no write allocate */
+#define HSR0_DCE		0x40000000	/* data cache enable */
+#define HSR0_ICE		0x80000000	/* instruction cache enable */
+
+#define __get_HSR(R)	({ unsigned long x; asm volatile("movsg hsr"#R",%0" : "=r"(x)); x; })
+#define __set_HSR(R,V)	do { asm volatile("movgs %0,hsr"#R : : "r"(V)); } while(0)
+
+/*
+ * CCR - Condition Codes Register
+ */
+#define CCR_FCC0		0x0000000f	/* FP/Media condition 0 (fcc0 reg) */
+#define CCR_FCC1		0x000000f0	/* FP/Media condition 1 (fcc1 reg) */
+#define CCR_FCC2		0x00000f00	/* FP/Media condition 2 (fcc2 reg) */
+#define CCR_FCC3		0x0000f000	/* FP/Media condition 3 (fcc3 reg) */
+#define CCR_ICC0		0x000f0000	/* Integer condition 0 (icc0 reg) */
+#define CCR_ICC0_C		0x00010000	/* - Carry flag */
+#define CCR_ICC0_V		0x00020000	/* - Overflow flag */
+#define CCR_ICC0_Z		0x00040000	/* - Zero flag */
+#define CCR_ICC0_N		0x00080000	/* - Negative flag */
+#define CCR_ICC1		0x00f00000	/* Integer condition 1 (icc1 reg) */
+#define CCR_ICC2		0x0f000000	/* Integer condition 2 (icc2 reg) */
+#define CCR_ICC3		0xf0000000	/* Integer condition 3 (icc3 reg) */
+
+/*
+ * CCCR - Condition Codes for Conditional Instructions Register
+ */
+#define CCCR_CC0		0x00000003	/* condition 0 (cc0 reg) */
+#define CCCR_CC0_FALSE		0x00000002	/* - condition is false */
+#define CCCR_CC0_TRUE		0x00000003	/* - condition is true */
+#define CCCR_CC1		0x0000000c	/* condition 1 (cc1 reg) */
+#define CCCR_CC2		0x00000030	/* condition 2 (cc2 reg) */
+#define CCCR_CC3		0x000000c0	/* condition 3 (cc3 reg) */
+#define CCCR_CC4		0x00000300	/* condition 4 (cc4 reg) */
+#define CCCR_CC5		0x00000c00	/* condition 5 (cc5 reg) */
+#define CCCR_CC6		0x00003000	/* condition 6 (cc6 reg) */
+#define CCCR_CC7		0x0000c000	/* condition 7 (cc7 reg) */
+
+/*
+ * ISR - Integer Status Register
+ */
+#define ISR_EMAM		0x00000001	/* memory misaligned access handling */
+#define ISR_EMAM_EXCEPTION	0x00000000	/* - generate exception */
+#define ISR_EMAM_FUDGE		0x00000001	/* - mask out invalid address bits */
+#define ISR_AEXC		0x00000004	/* accrued [overflow] exception */
+#define ISR_DTT			0x00000018	/* division type trap */
+#define ISR_DTT_IGNORE		0x00000000	/* - ignore division error */
+#define ISR_DTT_DIVBYZERO	0x00000008	/* - generate exception */
+#define ISR_DTT_OVERFLOW	0x00000010	/* - record overflow */
+#define ISR_EDE			0x00000020	/* enable division exception */
+#define ISR_PLI			0x20000000	/* pre-load instruction information */
+#define ISR_QI			0x80000000	/* quad data implementation information */
+
+/*
+ * EPCR0 - Exception PC Register
+ */
+#define EPCR0_V			0x00000001	/* register content validity indicator */
+#define EPCR0_PC		0xfffffffc	/* faulting instruction address */
+
+/*
+ * ESR0/14/15 - Exception Status Register
+ */
+#define ESRx_VALID		0x00000001	/* register content validity indicator */
+#define ESRx_EC			0x0000003e	/* exception type */
+#define ESRx_EC_DATA_STORE	0x00000000	/* - data_store_error */
+#define ESRx_EC_INSN_ACCESS	0x00000006	/* - instruction_access_error */
+#define ESRx_EC_PRIV_INSN	0x00000008	/* - privileged_instruction */
+#define ESRx_EC_ILL_INSN	0x0000000a	/* - illegal_instruction */
+#define ESRx_EC_MP_EXCEP	0x0000001c	/* - mp_exception */
+#define ESRx_EC_DATA_ACCESS	0x00000024	/* - data_access_error */
+#define ESRx_EC_DIVISION	0x00000026	/* - division_exception */
+#define ESRx_EC_ITLB_MISS	0x00000034	/* - instruction_access_TLB_miss */
+#define ESRx_EC_DTLB_MISS	0x00000036	/* - data_access_TLB_miss */
+#define ESRx_EC_DATA_ACCESS_DAT	0x0000003a	/* - data_access_DAT_exception */
+
+#define ESR0_IAEC		0x00000100	/* info for instruction-access-exception */
+#define ESR0_IAEC_RESV		0x00000000	/* - reserved */
+#define ESR0_IAEC_PROT_VIOL	0x00000100	/* - protection violation */
+
+#define ESR0_ATXC		0x00f00000	/* address translation exception code */
+#define ESR0_ATXC_MMU_MISS	0x00000000	/* - MMU miss exception and more (?) */
+#define ESR0_ATXC_MULTI_DAT	0x00800000	/* - multiple DAT entry hit */
+#define ESR0_ATXC_MULTI_SAT	0x00900000	/* - multiple SAT entry hit */
+#define ESR0_ATXC_AMRTLB_MISS	0x00a00000	/* - MMU/TLB miss exception */
+#define ESR0_ATXC_PRIV_EXCEP	0x00c00000	/* - privilege protection fault */
+#define ESR0_ATXC_WP_EXCEP	0x00d00000	/* - write protection fault */
+
+#define ESR0_EAV		0x00000800	/* true if EAR0 register valid */
+#define ESR15_EAV		0x00000800	/* true if EAR15 register valid */
+
+/*
+ * ESFR1 - Exception Status Valid Flag Register
+ */
+#define ESFR1_ESR0		0x00000001	/* true if ESR0 is valid */
+#define ESFR1_ESR14		0x00004000	/* true if ESR14 is valid */
+#define ESFR1_ESR15		0x00008000	/* true if ESR15 is valid */
+
+/*
+ * MSR - Media Status Register
+ */
+#define MSR0_AOVF		0x00000001	/* overflow exception accrued */
+#define MSRx_OVF		0x00000002	/* overflow exception detected */
+#define MSRx_SIE		0x0000003c	/* last SIMD instruction exception detected */
+#define MSRx_SIE_NONE		0x00000000	/* - none detected */
+#define MSRx_SIE_FRkHI_ACCk	0x00000020	/* - exception at FRkHI or ACCk */
+#define MSRx_SIE_FRkLO_ACCk1	0x00000010	/* - exception at FRkLO or ACCk+1 */
+#define MSRx_SIE_FRk1HI_ACCk2	0x00000008	/* - exception at FRk+1HI or ACCk+2 */
+#define MSRx_SIE_FRk1LO_ACCk3	0x00000004	/* - exception at FRk+1LO or ACCk+3 */
+#define MSR0_MTT		0x00007000	/* type of last media trap detected */
+#define MSR0_MTT_NONE		0x00000000	/* - none detected */
+#define MSR0_MTT_OVERFLOW	0x00001000	/* - overflow detected */
+#define MSR0_HI			0x00c00000	/* hardware implementation */
+#define MSR0_HI_ROUNDING	0x00000000	/* - rounding mode */
+#define MSR0_HI_NONROUNDING	0x00c00000	/* - non-rounding mode */
+#define MSR0_EMCI		0x01000000	/* enable media custom instructions */
+#define MSR0_SRDAV		0x10000000	/* select rounding mode of MAVEH */
+#define MSR0_SRDAV_RDAV		0x00000000	/* - controlled by MSR.RDAV */
+#define MSR0_SRDAV_RD		0x10000000	/* - controlled by MSR.RD */
+#define MSR0_RDAV		0x20000000	/* rounding mode of MAVEH */
+#define MSR0_RDAV_NEAREST_MI	0x00000000	/* - round to nearest minus */
+#define MSR0_RDAV_NEAREST_PL	0x20000000	/* - round to nearest plus */
+#define MSR0_RD			0xc0000000	/* rounding mode */
+#define MSR0_RD_NEAREST		0x00000000	/* - nearest */
+#define MSR0_RD_ZERO		0x40000000	/* - zero */
+#define MSR0_RD_POS_INF		0x80000000	/* - postive infinity */
+#define MSR0_RD_NEG_INF		0xc0000000	/* - negative infinity */
+
+/*
+ * IAMPR0-7 - Instruction Address Mapping Register
+ * DAMPR0-7 - Data Address Mapping Register
+ */
+#define xAMPRx_V		0x00000001	/* register content validity indicator */
+#define DAMPRx_WP		0x00000002	/* write protect */
+#define DAMPRx_WP_RW		0x00000000	/* - read/write */
+#define DAMPRx_WP_RO		0x00000002	/* - read-only */
+#define xAMPRx_C		0x00000004	/* cached/uncached */
+#define xAMPRx_C_CACHED		0x00000000	/* - cached */
+#define xAMPRx_C_UNCACHED	0x00000004	/* - uncached */
+#define xAMPRx_S		0x00000008	/* supervisor only */
+#define xAMPRx_S_USER		0x00000000	/* - userspace can access */
+#define xAMPRx_S_KERNEL		0x00000008	/* - kernel only */
+#define xAMPRx_SS		0x000000f0	/* segment size */
+#define xAMPRx_SS_16Kb		0x00000000	/* - 16 kilobytes */
+#define xAMPRx_SS_64Kb		0x00000010	/* - 64 kilobytes */
+#define xAMPRx_SS_256Kb		0x00000020	/* - 256 kilobytes */
+#define xAMPRx_SS_1Mb		0x00000030	/* - 1 megabyte */
+#define xAMPRx_SS_2Mb		0x00000040	/* - 2 megabytes */
+#define xAMPRx_SS_4Mb		0x00000050	/* - 4 megabytes */
+#define xAMPRx_SS_8Mb		0x00000060	/* - 8 megabytes */
+#define xAMPRx_SS_16Mb		0x00000070	/* - 16 megabytes */
+#define xAMPRx_SS_32Mb		0x00000080	/* - 32 megabytes */
+#define xAMPRx_SS_64Mb		0x00000090	/* - 64 megabytes */
+#define xAMPRx_SS_128Mb		0x000000a0	/* - 128 megabytes */
+#define xAMPRx_SS_256Mb		0x000000b0	/* - 256 megabytes */
+#define xAMPRx_SS_512Mb		0x000000c0	/* - 512 megabytes */
+#define xAMPRx_RESERVED8	0x00000100	/* reserved bit */
+#define xAMPRx_NG		0x00000200	/* non-global */
+#define xAMPRx_L		0x00000400	/* locked */
+#define xAMPRx_M		0x00000800	/* modified */
+#define xAMPRx_D		0x00001000	/* DAT entry */
+#define xAMPRx_RESERVED13	0x00002000	/* reserved bit */
+#define xAMPRx_PPFN		0xfff00000	/* physical page frame number */
+
+#define xAMPRx_V_BIT		0
+#define DAMPRx_WP_BIT		1
+#define xAMPRx_C_BIT		2
+#define xAMPRx_S_BIT		3
+#define xAMPRx_RESERVED8_BIT	8
+#define xAMPRx_NG_BIT		9
+#define xAMPRx_L_BIT		10
+#define xAMPRx_M_BIT		11
+#define xAMPRx_D_BIT		12
+#define xAMPRx_RESERVED13_BIT	13
+
+#define __get_IAMPR(R) ({ unsigned long x; asm volatile("movsg iampr"#R",%0" : "=r"(x)); x; })
+#define __get_DAMPR(R) ({ unsigned long x; asm volatile("movsg dampr"#R",%0" : "=r"(x)); x; })
+
+#define __get_IAMLR(R) ({ unsigned long x; asm volatile("movsg iamlr"#R",%0" : "=r"(x)); x; })
+#define __get_DAMLR(R) ({ unsigned long x; asm volatile("movsg damlr"#R",%0" : "=r"(x)); x; })
+
+#define __set_IAMPR(R,V) 	do { asm volatile("movgs %0,iampr"#R : : "r"(V)); } while(0)
+#define __set_DAMPR(R,V)  	do { asm volatile("movgs %0,dampr"#R : : "r"(V)); } while(0)
+
+#define __set_IAMLR(R,V) 	do { asm volatile("movgs %0,iamlr"#R : : "r"(V)); } while(0)
+#define __set_DAMLR(R,V)  	do { asm volatile("movgs %0,damlr"#R : : "r"(V)); } while(0)
+
+#define save_dampr(R, _dampr)					\
+do {								\
+	asm volatile("movsg dampr"R",%0" : "=r"(_dampr));	\
+} while(0)
+
+#define restore_dampr(R, _dampr)			\
+do {							\
+	asm volatile("movgs %0,dampr"R :: "r"(_dampr));	\
+} while(0)
+
+/*
+ * AMCR - Address Mapping Control Register
+ */
+#define AMCR_IAMRN		0x000000ff	/* quantity of IAMPR registers */
+#define AMCR_DAMRN		0x0000ff00	/* quantity of DAMPR registers */
+
+/*
+ * TTBR - Address Translation Table Base Register
+ */
+#define __get_TTBR()		({ unsigned long x; asm volatile("movsg ttbr,%0" : "=r"(x)); x; })
+
+/*
+ * TPXR - TLB Probe Extend Register
+ */
+#define TPXR_E			0x00000001
+#define TPXR_LMAX_SHIFT		20
+#define TPXR_LMAX_SMASK		0xf
+#define TPXR_WMAX_SHIFT		24
+#define TPXR_WMAX_SMASK		0xf
+#define TPXR_WAY_SHIFT		28
+#define TPXR_WAY_SMASK		0xf
+
+/*
+ * DCR - Debug Control Register
+ */
+#define DCR_IBCE3		0x00000001	/* break on conditional insn pointed to by IBAR3 */
+#define DCR_IBE3		0x00000002	/* break on insn pointed to by IBAR3 */
+#define DCR_IBCE1		0x00000004	/* break on conditional insn pointed to by IBAR2 */
+#define DCR_IBE1		0x00000008	/* break on insn pointed to by IBAR2 */
+#define DCR_IBCE2		0x00000010	/* break on conditional insn pointed to by IBAR1 */
+#define DCR_IBE2		0x00000020	/* break on insn pointed to by IBAR1 */
+#define DCR_IBCE0		0x00000040	/* break on conditional insn pointed to by IBAR0 */
+#define DCR_IBE0		0x00000080	/* break on insn pointed to by IBAR0 */
+
+#define DCR_DDBE1		0x00004000	/* use DBDR1x when checking DBAR1 */
+#define DCR_DWBE1		0x00008000	/* break on store to address in DBAR1/DBMR1x */
+#define DCR_DRBE1		0x00010000	/* break on load from address in DBAR1/DBMR1x */
+#define DCR_DDBE0		0x00020000	/* use DBDR0x when checking DBAR0 */
+#define DCR_DWBE0		0x00040000	/* break on store to address in DBAR0/DBMR0x */
+#define DCR_DRBE0		0x00080000	/* break on load from address in DBAR0/DBMR0x */
+
+#define DCR_EIM			0x0c000000	/* external interrupt disable */
+#define DCR_IBM			0x10000000	/* instruction break disable */
+#define DCR_SE			0x20000000	/* single step enable */
+#define DCR_EBE			0x40000000	/* exception break enable */
+
+/*
+ * BRR - Break Interrupt Request Register
+ */
+#define BRR_ST			0x00000001	/* single-step detected */
+#define BRR_SB			0x00000002	/* break instruction detected */
+#define BRR_BB			0x00000004	/* branch with hint detected */
+#define BRR_CBB			0x00000008	/* branch to LR detected */
+#define BRR_IBx			0x000000f0	/* hardware breakpoint detected */
+#define BRR_DBx			0x00000f00	/* hardware watchpoint detected */
+#define BRR_DBNEx		0x0000f000	/* ? */
+#define BRR_EBTT		0x00ff0000	/* trap type of exception break */
+#define BRR_TB			0x10000000	/* external break request detected */
+#define BRR_CB			0x20000000	/* ICE break command detected */
+#define BRR_EB			0x40000000	/* exception break detected */
+
+/*
+ * BPSR - Break PSR Save Register
+ */
+#define BPSR_BET		0x00000001	/* former PSR.ET */
+#define BPSR_BS			0x00001000	/* former PSR.S */
+
+#endif /* _ASM_SPR_REGS_H */
diff -urN linux-2.4.29/include/asm-frv/statfs.h linux-2.4.29-uc1/include/asm-frv/statfs.h
--- linux-2.4.29/include/asm-frv/statfs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/statfs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,26 @@
+#ifndef _ASM_STATFS_H
+#define _ASM_STATFS_H
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t	fsid_t;
+
+#endif
+
+struct statfs {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_spare[6];
+};
+
+#endif /* _ASM_STATFS_H */
+
diff -urN linux-2.4.29/include/asm-frv/stat.h linux-2.4.29-uc1/include/asm-frv/stat.h
--- linux-2.4.29/include/asm-frv/stat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/stat.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,100 @@
+#ifndef _ASM_STAT_H
+#define _ASM_STAT_H
+
+struct __old_kernel_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+/* This matches struct stat in uClibc/glibc.  */
+struct stat {
+	unsigned char __pad1[6];
+	unsigned short st_dev;
+
+	unsigned long __pad2;
+	unsigned long st_ino;
+
+	unsigned short __pad3;
+	unsigned short st_mode;
+	unsigned short __pad4;
+	unsigned short st_nlink;
+
+	unsigned short __pad5;
+	unsigned short st_uid;
+	unsigned short __pad6;
+	unsigned short st_gid;
+
+	unsigned char __pad7[6];
+	unsigned short st_rdev;
+
+	unsigned long __pad8;
+	unsigned long st_size;
+
+	unsigned long __pad9;		/* align 64-bit st_blocks to 2-word */
+	unsigned long st_blksize;
+
+	unsigned long __pad10;	/* future possible st_blocks high bits */
+	unsigned long st_blocks;	/* Number 512-byte blocks allocated. */
+
+	unsigned long __unused1;
+	unsigned long st_atime;
+
+	unsigned long __unused2;
+	unsigned long st_mtime;
+
+	unsigned long __unused3;
+	unsigned long st_ctime;
+
+	unsigned long long __unused4;
+};
+
+/* This matches struct stat64 in uClibc/glibc.  The layout is exactly
+   the same as that of struct stat above, with 64-bit types taking up
+   space that was formerly used by padding.  stat syscalls are still
+   different from stat64, though, in that the former tests for
+   overflow.  */
+struct stat64 {
+	unsigned char __pad1[6];
+	unsigned short st_dev;
+
+	unsigned long long st_ino;
+
+	unsigned int st_mode;
+	unsigned int st_nlink;
+
+	unsigned long st_uid;
+	unsigned long st_gid;
+
+	unsigned char __pad2[6];
+	unsigned short st_rdev;
+
+	long long st_size;
+
+	unsigned long __pad3;		/* align 64-bit st_blocks to 2-word */
+	unsigned long st_blksize;
+
+	unsigned long __pad4;		/* future possible st_blocks high bits */
+	unsigned long st_blocks;	/* Number 512-byte blocks allocated. */
+
+	unsigned long __unused1;
+	unsigned long st_atime;
+
+	unsigned long __unused2;
+	unsigned long st_mtime;
+
+	unsigned long __unused3;	/* will be high 32 bits of ctime someday */
+	unsigned long st_ctime;
+
+	unsigned long long __unused4;
+};
+
+#endif /* _ASM_STAT_H */
diff -urN linux-2.4.29/include/asm-frv/string.h linux-2.4.29-uc1/include/asm-frv/string.h
--- linux-2.4.29/include/asm-frv/string.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/string.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,40 @@
+#ifndef _ASM_STRING_H_
+#define _ASM_STRING_H_
+
+#ifdef __KERNEL__ /* only set these up for kernel code */
+
+#define __HAVE_ARCH_MEMSET 1
+#define __HAVE_ARCH_MEMCPY 1
+
+extern void *memset(void *, int, __kernel_size_t);
+extern void *memcpy(void *, const void *, __kernel_size_t);
+
+#else /* KERNEL */
+
+/*
+ *	let user libraries deal with these,
+ *	IMHO the kernel has no place defining these functions for user apps
+ */
+
+#define __HAVE_ARCH_STRCPY 1
+#define __HAVE_ARCH_STRNCPY 1
+#define __HAVE_ARCH_STRCAT 1
+#define __HAVE_ARCH_STRNCAT 1
+#define __HAVE_ARCH_STRCMP 1
+#define __HAVE_ARCH_STRNCMP 1
+#define __HAVE_ARCH_STRNICMP 1
+#define __HAVE_ARCH_STRCHR 1
+#define __HAVE_ARCH_STRRCHR 1
+#define __HAVE_ARCH_STRSTR 1
+#define __HAVE_ARCH_STRLEN 1
+#define __HAVE_ARCH_STRNLEN 1
+#define __HAVE_ARCH_MEMSET 1
+#define __HAVE_ARCH_MEMCPY 1
+#define __HAVE_ARCH_MEMMOVE 1
+#define __HAVE_ARCH_MEMSCAN 1
+#define __HAVE_ARCH_MEMCMP 1
+#define __HAVE_ARCH_MEMCHR 1
+#define __HAVE_ARCH_STRTOK 1
+
+#endif /* KERNEL */
+#endif /* _ASM_STRING_H_ */
diff -urN linux-2.4.29/include/asm-frv/system.h linux-2.4.29-uc1/include/asm-frv/system.h
--- linux-2.4.29/include/asm-frv/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/system.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,132 @@
+/* system.h: FR-V CPU control definitions
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_SYSTEM_H
+#define _ASM_SYSTEM_H
+
+#include <linux/config.h> /* get configuration macros */
+#include <linux/linkage.h>
+#include <asm/atomic.h>
+
+struct thread_struct;
+
+#define prepare_to_switch()    do { } while(0)
+
+/*
+ * switch_to(prev, next) should switch from task `prev' to `next'
+ * `prev' will never be the same as `next'.
+ * The `mb' is to tell GCC not to cache `current' across this call.
+ */
+extern asmlinkage
+struct task_struct *__switch_to(struct thread_struct *prev_thread,
+				struct thread_struct *next_thread,
+				struct task_struct *prev);
+
+#define switch_to(prev, next, last)					\
+do {									\
+	(prev)->thread.sched_lr =					\
+		(unsigned long) __builtin_return_address(0);		\
+	(last) = __switch_to(&(prev)->thread, &(next)->thread, (prev));	\
+	mb();								\
+} while(0)
+
+#define __cli()						\
+do {							\
+	unsigned long psr;				\
+	asm volatile("	movsg	psr,%0		\n"	\
+		     "	ori	%0,%1,%0	\n"	\
+		     "	movgs	%0,psr		\n"	\
+		     : "=r"(psr)			\
+		     : "i" (PSR_PIL)			\
+		     : "memory");			\
+} while(0)
+
+#define __sti()						\
+do {							\
+	unsigned long psr;				\
+	asm volatile("	movsg	psr,%0		\n"	\
+		     "	andi	%0,%1,%0	\n"	\
+		     "	movgs	%0,psr		\n"	\
+		     : "=r"(psr)			\
+		     : "i" (~PSR_PIL)			\
+		     : "memory");			\
+} while(0)
+
+#define __save_flags(x)		asm("movsg psr,%0" : "=r"(x) : : "memory")
+#define __restore_flags(x)	asm volatile("movgs %0,psr" : : "r"(x) : "memory")
+
+#define	__save_and_cli(flags)				\
+do {							\
+	unsigned long npsr;				\
+	asm volatile("	movsg	psr,%0		\n"	\
+		     "	ori	%0,%2,%1	\n"	\
+		     "	movgs	%1,psr		\n"	\
+		     : "=r"(flags), "=r"(npsr)		\
+		     : "i" (PSR_PIL)			\
+		     : "memory");			\
+} while(0)
+
+#define	__save_and_sti(flags)				\
+do {							\
+	unsigned long npsr;				\
+	asm volatile("	movsg	psr,%0		\n"	\
+		     "	andi	%0,%2,%1	\n"	\
+		     "	movgs	%1,psr		\n"	\
+		     : "=r"(flags), "=r"(npsr)		\
+		     : "i" (~PSR_PIL)			\
+		     : "memory");			\
+} while(0)
+
+#define irqs_disabled()					\
+({							\
+       unsigned long flags;				\
+       __save_flags(flags);				\
+       (flags & PSR_PIL);				\
+})
+
+
+/* For spinlocks etc */
+#define local_irq_save(x)	__save_and_cli(x)
+#define local_irq_set(x)	__save_and_sti(x)
+#define local_irq_restore(x)	__restore_flags(x)
+#define local_irq_disable()	__cli()
+#define local_irq_enable()	__sti()
+
+#define cli()			__cli()
+#define sti()			__sti()
+#define save_flags(x)		__save_flags(x)
+#define restore_flags(x)	__restore_flags(x)
+#define save_and_cli(x)		__save_and_cli(x)
+#define save_and_set(x)		__save_and_sti(x)
+
+/*
+ * Force strict CPU ordering.
+ * Not really required on m68k...
+ */
+#define nop()			asm volatile ("nop"::)
+#define mb()			asm volatile ("membar" : : :"memory")
+#define rmb()			asm volatile ("membar" : : :"memory")
+#define wmb()			asm volatile ("membar" : : :"memory")
+#define set_mb(var, value)	do { var = value; mb(); } while (0)
+#define set_wmb(var, value)	do { var = value; wmb(); } while (0)
+
+#define smp_mb()		barrier()
+#define smp_rmb()		barrier()
+#define smp_wmb()		barrier()
+
+#define HARD_RESET_NOW()			\
+do {						\
+	cli();					\
+} while(1)
+
+extern void die_if_kernel(const char *, ...) __attribute__((format(printf, 1, 2)));
+extern void free_initmem(void);
+
+#endif /* _ASM_SYSTEM_H */
diff -urN linux-2.4.29/include/asm-frv/termbits.h linux-2.4.29-uc1/include/asm-frv/termbits.h
--- linux-2.4.29/include/asm-frv/termbits.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/termbits.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,175 @@
+#ifndef _ASM_TERMBITS_H__
+#define _ASM_TERMBITS_H__
+
+#include <linux/posix_types.h>
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#define NCCS 19
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IUCLC	0001000
+#define IXON	0002000
+#define IXANY	0004000
+#define IXOFF	0010000
+#define IMAXBEL	0020000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define OLCUC	0000002
+#define ONLCR	0000004
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#define NLDLY	0000400
+#define   NL0	0000000
+#define   NL1	0000400
+#define CRDLY	0003000
+#define   CR0	0000000
+#define   CR1	0001000
+#define   CR2	0002000
+#define   CR3	0003000
+#define TABDLY	0014000
+#define   TAB0	0000000
+#define   TAB1	0004000
+#define   TAB2	0010000
+#define   TAB3	0014000
+#define   XTABS	0014000
+#define BSDLY	0020000
+#define   BS0	0000000
+#define   BS1	0020000
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+#define FFDLY	0100000
+#define   FF0	0000000
+#define   FF1	0100000
+
+/* c_cflag bit meaning */
+#define CBAUD	0010017
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE	0000060
+#define   CS5	0000000
+#define   CS6	0000020
+#define   CS7	0000040
+#define   CS8	0000060
+#define CSTOPB	0000100
+#define CREAD	0000200
+#define PARENB	0000400
+#define PARODD	0001000
+#define HUPCL	0002000
+#define CLOCAL	0004000
+#define CBAUDEX 0010000
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+#define CIBAUD	  002003600000	/* input baud rate (not used) */
+#define CMSPAR	  010000000000		/* mark or space (stick) parity */
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+#define ISIG	0000001
+#define ICANON	0000002
+#define XCASE	0000004
+#define ECHO	0000010
+#define ECHOE	0000020
+#define ECHOK	0000040
+#define ECHONL	0000100
+#define NOFLSH	0000200
+#define TOSTOP	0000400
+#define ECHOCTL	0001000
+#define ECHOPRT	0002000
+#define ECHOKE	0004000
+#define FLUSHO	0010000
+#define PENDIN	0040000
+#define IEXTEN	0100000
+
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* _ASM_TERMBITS_H__ */
+
diff -urN linux-2.4.29/include/asm-frv/termios.h linux-2.4.29-uc1/include/asm-frv/termios.h
--- linux-2.4.29/include/asm-frv/termios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/termios.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,111 @@
+#ifndef _ASM_TERMIOS_H
+#define _ASM_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+ 
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+#ifdef __KERNEL__
+/*	intr=^C		quit=^|		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+#endif
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+#define TIOCM_MODEM_BITS       TIOCM_OUT2      /* IRDA support */
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6	/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14
+#define N_HCI		15  /* Bluetooth HCI UART */
+
+#ifdef __KERNEL__
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+	unsigned short tmp; \
+	get_user(tmp, &(termio)->c_iflag); \
+	(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
+	get_user(tmp, &(termio)->c_oflag); \
+	(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
+	get_user(tmp, &(termio)->c_cflag); \
+	(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
+	get_user(tmp, &(termio)->c_lflag); \
+	(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
+	get_user((termios)->c_line, &(termio)->c_line); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif	/* __KERNEL__ */
+
+#endif /* _ASM_TERMIOS_H */
+
diff -urN linux-2.4.29/include/asm-frv/timer-regs.h linux-2.4.29-uc1/include/asm-frv/timer-regs.h
--- linux-2.4.29/include/asm-frv/timer-regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/timer-regs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,106 @@
+/* timer-regs.h: hardware timer register definitions
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_TIMER_REGS_H
+#define _ASM_TIMER_REGS_H
+
+#include <asm/vmlinux.h>
+
+extern unsigned long __nongprelbss __clkin_clock_speed_HZ;
+extern unsigned long __nongprelbss __ext_bus_clock_speed_HZ;
+extern unsigned long __nongprelbss __res_bus_clock_speed_HZ;
+extern unsigned long __nongprelbss __sdram_clock_speed_HZ;
+extern unsigned long __nongprelbss __core_bus_clock_speed_HZ;
+extern unsigned long __nongprelbss __core_clock_speed_HZ;
+extern unsigned long __nongprelbss __dsu_clock_speed_HZ;
+extern unsigned long __nongprelbss __serial_clock_speed_HZ;
+
+#define __get_CLKC()	({ *(volatile unsigned long *)(0xfeff9a00); })
+
+static inline void __set_CLKC(unsigned long v)
+{
+	int tmp;
+
+	asm volatile("	st%I0.p	%2,%M0		\n"
+		     "	setlos	%3,%1		\n"
+		     "	membar			\n"
+		     "0:			\n"
+		     "	subicc	%1,#1,%1,icc0	\n"
+		     "	bnc	icc0,#1,0b	\n"
+		     : "=m"(*(volatile unsigned long *) 0xfeff9a00), "=r"(tmp)
+		     : "r"(v), "i"(256)
+		     : "icc0");
+}
+
+#define __get_TCTR()	({ *(volatile unsigned long *)(0xfeff9418); })
+#define __get_TPRV()	({ *(volatile unsigned long *)(0xfeff9420); })
+#define __get_TPRCKSL()	({ *(volatile unsigned long *)(0xfeff9428); })
+#define __get_TCSR(T)	({ *(volatile unsigned long *)(0xfeff9400 + 8 * (T)); })
+#define __get_TxCKSL(T)	({ *(volatile unsigned long *)(0xfeff9430 + 8 * (T)); })
+
+#define __get_TCSR_DATA(T) ({ __get_TCSR(T) >> 24; })
+
+#define __set_TCTR(V)	do { *(volatile unsigned long *)(0xfeff9418) = (V); mb(); } while(0)
+#define __set_TPRV(V)	do { *(volatile unsigned long *)(0xfeff9420) = (V) << 24; mb(); } while(0)
+#define __set_TPRCKSL(V) do { *(volatile unsigned long *)(0xfeff9428) = (V); mb(); } while(0)
+#define __set_TCSR(T,V)	\
+do { *(volatile unsigned long *)(0xfeff9400 + 8 * (T)) = (V); mb(); } while(0)
+
+#define __set_TxCKSL(T,V) \
+do { *(volatile unsigned long *)(0xfeff9430 + 8 * (T)) = (V); mb(); } while(0)
+
+#define __set_TCSR_DATA(T,V) __set_TCSR(T, (V) << 24)
+#define __set_TxCKSL_DATA(T,V) __set_TxCKSL(T, TxCKSL_EIGHT | __TxCKSL_SELECT((V)))
+
+/* clock control register */
+#define CLKC_CMODE		0x0f000000
+#define CLKC_SLPL		0x000f0000
+#define CLKC_P0			0x00000100
+#define CLKC_CM			0x00000003
+
+#define CLKC_CMODE_s		24
+
+/* timer control register - non-readback mode */
+#define TCTR_MODE_0		0x00000000
+#define TCTR_MODE_2		0x04000000
+#define TCTR_MODE_4		0x08000000
+#define TCTR_MODE_5		0x0a000000
+#define TCTR_RL_LATCH		0x00000000
+#define TCTR_RL_RW_LOW8		0x10000000
+#define TCTR_RL_RW_HIGH8	0x20000000
+#define TCTR_RL_RW_LH8		0x30000000
+#define TCTR_SC_CTR0		0x00000000
+#define TCTR_SC_CTR1		0x40000000
+#define TCTR_SC_CTR2		0x80000000
+
+/* timer control register - readback mode */
+#define TCTR_CNT0		0x02000000
+#define TCTR_CNT1		0x04000000
+#define TCTR_CNT2		0x08000000
+#define TCTR_NSTATUS		0x10000000
+#define TCTR_NCOUNT		0x20000000
+#define TCTR_SC_READBACK	0xc0000000
+
+/* timer control status registers - non-readback mode */
+#define TCSRx_DATA		0xff000000
+
+/* timer control status registers - readback mode */
+#define TCSRx_OUTPUT		0x80000000
+#define TCSRx_NULLCOUNT		0x40000000
+#define TCSRx_RL		0x30000000
+#define TCSRx_MODE		0x07000000
+
+/* timer clock select registers */
+#define TxCKSL_SELECT		0x0f000000
+#define __TxCKSL_SELECT(X)	((X) << 24)
+#define TxCKSL_EIGHT		0xf0000000
+
+#endif /* _ASM_TIMER_REGS_H */
diff -urN linux-2.4.29/include/asm-frv/timex.h linux-2.4.29-uc1/include/asm-frv/timex.h
--- linux-2.4.29/include/asm-frv/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/timex.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,25 @@
+/* timex.h: FR-V architecture timex specifications
+ */
+#ifndef _ASM_TIMEX_H
+#define _ASM_TIMEX_H
+
+#define CLOCK_TICK_RATE		1193180 /* Underlying HZ */
+#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
+
+#define FINETUNE							\
+((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) *			\
+   (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR))	\
+  << (SHIFT_SCALE-SHIFT_HZ)) / HZ)
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+	return 0;
+}
+
+#define vxtime_lock()		do {} while (0)
+#define vxtime_unlock()		do {} while (0)
+
+#endif
+
diff -urN linux-2.4.29/include/asm-frv/tlb.h linux-2.4.29-uc1/include/asm-frv/tlb.h
--- linux-2.4.29/include/asm-frv/tlb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/tlb.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,2 @@
+#include <asm-generic/tlb.h>
+
diff -urN linux-2.4.29/include/asm-frv/types.h linux-2.4.29-uc1/include/asm-frv/types.h
--- linux-2.4.29/include/asm-frv/types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/types.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,59 @@
+#ifndef _M68K_TYPES_H
+#define _M68K_TYPES_H
+
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue.  However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ */
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+typedef u64 u_quad_t;
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide.  */
+
+typedef u32 dma_addr_t;
+
+#endif /* __KERNEL__ */
+
+#endif /* _M68K_TYPES_H */
diff -urN linux-2.4.29/include/asm-frv/uaccess.h linux-2.4.29-uc1/include/asm-frv/uaccess.h
--- linux-2.4.29/include/asm-frv/uaccess.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/uaccess.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,292 @@
+#ifndef __ASM_UACCESS_H
+#define __ASM_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/segment.h>
+#ifdef CONFIG_UCLINUX
+// For proper declarations of memory_start and memory_end
+#include <asm/vmlinux.h>
+#endif
+
+#define HAVE_ARCH_UNMAPPED_AREA	/* we decide where to put mmaps */
+
+#define __ptr(x) ((unsigned long *)(x))
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+#define __addr_ok(addr) ((unsigned long)(addr) < (current->addr_limit.seg))
+
+
+/*
+ * check that a range of addresses falls within the current address limit
+ */
+static inline int ___range_ok(unsigned long addr, unsigned long size)
+{
+#ifndef CONFIG_UCLINUX
+	int flag = -EFAULT, tmp;
+
+	asm volatile (
+		"	addcc	%3,%2,%1,icc0	\n"	/* set C-flag if addr+size>4GB */
+		"	subcc.p	%1,%4,gr0,icc1	\n"	/* jump if addr+size>limit */
+		"	bc	icc0,#0,0f	\n"
+		"	bhi	icc1,#0,0f	\n"
+		"	setlos	#0,%0		\n"	/* mark okay */
+		"0:				\n"
+		: "=r"(flag), "=&r"(tmp)
+		: "r"(addr), "r"(size), "r"(get_addr_limit()), "0"(flag)
+		);
+
+	return flag;
+
+#else
+	if (addr < memory_start ||
+	    addr > memory_end ||
+	    size > memory_end - memory_start ||
+	    addr + size > memory_end)
+		return -EFAULT;
+
+	return 0;
+#endif
+}
+
+#define __range_ok(addr,size) ___range_ok((unsigned long) (addr), (unsigned long) (size))
+
+#define access_ok(type,addr,size) (__range_ok((addr), (size)) == 0)
+#define __access_ok(addr,size) (__range_ok((addr), (size)) == 0)
+
+static inline int verify_area(int type, const void * addr, unsigned long size)
+{
+	return __range_ok(addr, size);
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ */
+#define __put_user(x, ptr)						\
+({									\
+	int __pu_err = 0;						\
+									\
+	typeof(*(ptr)) __pu_val = (x);					\
+									\
+	switch (sizeof (*(ptr))) {					\
+	case 1:								\
+		__put_user_asm(__pu_err, __pu_val, ptr, "b", "r");	\
+		break;							\
+	case 2:								\
+		__put_user_asm(__pu_err, __pu_val, ptr, "h", "r");	\
+		break;							\
+	case 4:								\
+		__put_user_asm(__pu_err, __pu_val, ptr, "",  "r");	\
+		break;							\
+	case 8:								\
+		__put_user_asm(__pu_err, __pu_val, ptr, "d", "e");	\
+		break;							\
+	default:							\
+		__pu_err = __put_user_bad();				\
+		break;							\
+	}								\
+	__pu_err;							\
+})
+
+#define put_user(x, ptr)			\
+({						\
+	typeof(&*ptr) _p = (ptr);		\
+	int _e;					\
+						\
+	_e = __range_ok(_p, sizeof(*_p));	\
+	if (_e == 0)				\
+		_e = __put_user((x), _p);	\
+	_e;					\
+})
+
+extern int __put_user_bad(void);
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+
+#ifndef CONFIG_UCLINUX
+
+#define __put_user_asm(err,x,ptr,dsize,constraint)					\
+do {											\
+	asm volatile("1:	st"dsize"%I1	%2,%M1	\n"				\
+		     "2:				\n"				\
+		     ".subsection 2			\n"				\
+		     "3:	setlos		%3,%0	\n"				\
+		     "		bra		2b	\n"				\
+		     ".previous				\n"				\
+		     ".section __ex_table,\"a\"		\n"				\
+		     "		.balign		8	\n"				\
+		     "		.long		1b,3b	\n"				\
+		     ".previous"							\
+		     : "=r" (err)							\
+		     : "m" (*__ptr(ptr)), constraint (x), "i"(-EFAULT), "0"(err)	\
+		     : "memory");							\
+} while (0)
+
+#else
+
+#define __put_user_asm(err,x,ptr,bwl,con)	\
+do {						\
+	asm("	st"bwl"%I0	%1,%M0	\n"	\
+	    "	membar			\n"	\
+	    :					\
+	    : "m" (*__ptr(ptr)), con (x)	\
+	    : "memory");			\
+} while (0)
+
+#endif
+
+/*****************************************************************************/
+/*
+ *
+ */
+#define __get_user(x, ptr)						\
+({									\
+	typeof(*(ptr)) __gu_val = 0;					\
+	int __gu_err = 0;						\
+									\
+	switch (sizeof(*(ptr))) {					\
+	case 1:								\
+		__get_user_asm(__gu_err, __gu_val, ptr, "ub", "=r");	\
+		break;							\
+	case 2:								\
+		__get_user_asm(__gu_err, __gu_val, ptr, "uh", "=r");	\
+		break;							\
+	case 4:								\
+		__get_user_asm(__gu_err, __gu_val, ptr, "", "=r");	\
+		break;							\
+	case 8:								\
+		__get_user_asm(__gu_err, __gu_val, ptr, "d", "=e");	\
+		break;							\
+	default:							\
+		__gu_err = __get_user_bad();				\
+		break;							\
+	}								\
+	(x) = __gu_val;							\
+	__gu_err;							\
+})
+
+#define get_user(x, ptr)			\
+({						\
+	typeof(&*ptr) _p = (ptr);		\
+	int _e;					\
+						\
+	_e = __range_ok(_p, sizeof(*_p));	\
+	if (likely(_e == 0))			\
+		_e = __get_user((x), _p);	\
+	else					\
+		(x) = (typeof(x)) 0;		\
+	_e;					\
+})
+
+extern int __get_user_bad(void);
+
+#ifndef CONFIG_UCLINUX
+
+#define __get_user_asm(err,x,ptr,dtype,constraint)	\
+do {							\
+	asm("1:		ld"dtype"%I2	%M2,%1	\n"	\
+	    "2:					\n"	\
+	    ".subsection 2			\n"	\
+	    "3:		setlos		%3,%0	\n"	\
+	    "		setlos		#0,%1	\n"	\
+	    "		bra		2b	\n"	\
+	    ".previous				\n"	\
+	    ".section __ex_table,\"a\"		\n"	\
+	    "		.balign		8	\n"	\
+	    "		.long		1b,3b	\n"	\
+	    ".previous"					\
+	    : "=r" (err), constraint (x)		\
+	    : "m" (*__ptr(ptr)), "i"(-EFAULT), "0"(err)	\
+	    );						\
+} while(0)
+
+#else
+
+#define __get_user_asm(err,x,ptr,bwl,con)	\
+	asm("	ld"bwl"%I1	%M1,%0	\n"	\
+	    "	membar			\n"	\
+	    : con(x)				\
+	    : "m" (*__ptr(ptr)))
+
+#endif
+
+/*****************************************************************************/
+/*
+ *
+ */
+#ifndef CONFIG_UCLINUX
+extern long __memset_user(void *dst, unsigned long count);
+extern long __memcpy_user(void *dst, const void *src, unsigned long count);
+
+#define clear_user(dst,count)			__memset_user((dst), (count))
+#define __copy_from_user(to, from, n)		__memcpy_user((to), (from), (n))
+#define __copy_to_user(to, from, n)		__memcpy_user((to), (from), (n))
+
+#else
+
+#define clear_user(dst,count)			(memset((dst), 0, (count)), 0)
+#define __copy_from_user(to, from, n)		(memcpy((to), (from), (n)), 0)
+#define __copy_to_user(to, from, n)		(memcpy((to), (from), (n)), 0)
+
+#endif
+
+static inline long copy_from_user(void *to, const void *from, unsigned long n)
+{
+	unsigned long ret = n;
+
+	if (likely(__access_ok(from, n)))
+		ret = __copy_from_user(to, from, n);
+
+	if (unlikely(ret != 0))
+		memset(to + (n - ret), 0, ret);
+
+	return ret;
+}
+
+static inline long copy_to_user(void *to, const void *from, unsigned long n)
+{
+	return likely(__access_ok(to, n)) ? __copy_to_user(to, from, n) : n;
+}
+
+#define copy_to_user_ret(to,from,n,retval)	({ if (copy_to_user(to,from,n)) return retval; })
+#define copy_from_user_ret(to,from,n,retval)	({ if (copy_from_user(to,from,n)) return retval; })
+
+extern long strncpy_from_user(char *dst, const char *src, long count);
+extern long strnlen_user(const char *src, long count);
+
+#define strlen_user(str) strnlen_user(str, 32767)
+
+extern unsigned long search_exception_table(unsigned long addr);
+
+#endif /* _ASM_UACCESS_H */
diff -urN linux-2.4.29/include/asm-frv/uCbootstrap.h linux-2.4.29-uc1/include/asm-frv/uCbootstrap.h
--- linux-2.4.29/include/asm-frv/uCbootstrap.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/uCbootstrap.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,313 @@
+/*
+ * uCbootstrap.h:  uCbootstrap and uCbootloader system call interface
+ *
+ * (c) Copyright 1999 Rt-Control Inc.
+ * (c) Copyright 2001 Arcturus Networks Inc.
+ * Maintained by Michael Durrant <mdurrant@arcturusnetworks.com>
+ *
+ * Release notes:
+ * 7 Nov 2001 by mdurrant@arcturusnetworks.com
+ *            - moved old uCbootloader.h file from the 
+ *              uCdimm platform directory into linux/asm-m68knommu/
+ *            - combined the bootstd.h and flash.h file from uCsimm
+ *              and uCdimm into a common uCbootloader.h file.
+ *
+ */
+
+#ifndef __UCBOOTSTRAP_H__
+#define __UCBOOTSTRAP_H__
+
+#define NR_BSC 23            /* last used bootloader system call */
+
+#define __BN_reset		0  /* reset and start the bootloader */
+#define __BN_test		1  /* tests the system call interface */
+#define __BN_exec		2  /* executes a bootloader image */
+#define __BN_exit		3  /* terminates a bootloader image */
+#define __BN_program		4  /* program FLASH from a chain */
+#define __BN_erase		5  /* erase sector(s) of FLASH */
+#define __BN_open		6
+#define __BN_write		7
+#define __BN_read		8
+#define __BN_close		9
+#define __BN_mmap		10 /* map a file descriptor into memory */
+#define __BN_munmap		11 /* remove a file to memory mapping */
+#define __BN_gethwaddr		12 /* get the hardware address of my interfaces */
+#define __BN_getserialnum	13 /* get the serial number of this board */
+#define __BN_getbenv		14 /* get a bootloader envvar */
+#define __BN_setbenv		15 /* get a bootloader envvar */
+#define __BN_setpmask		16 /* set the protection mask */
+#define __BN_readbenv		17 /* read environment variables */
+#define __BN_flash_chattr_range	18
+#define __BN_flash_erase_range	19
+#define __BN_flash_write_range	20
+#define __BN_ramload		21 /* load kernel into RAM and exec */
+#define __BN_program2		22 /* program second FLASH from a chain */
+
+
+/* Calling conventions compatible to (uC)linux/frv
+ * We use simmilar macros to call into the bootloader as for uClinux
+ */
+
+#define __bsc_return(type, res)						\
+do {									\
+	if ((unsigned long)(res) >= (unsigned long)(-64)) {		\
+		/* let errno be a function, preserve res in %d0 */	\
+		int __err = -(res);					\
+		errno = __err;						\
+		res = -1;						\
+	}								\
+	return (type)(res);						\
+} while (0)
+
+/*
+ * zero argument boot loader call stub
+ */
+#define _bsc0(type, name)				\
+type name(void)						\
+{							\
+	register long __err;				\
+	register type __res asm("gr7");			\
+							\
+	asm volatile("	tira	gr0,#126	\n"	\
+		     "	setlos	#4095,%1	\n"	\
+		     "	add	%0,%1,%1	\n"	\
+		     : "=r"(__res), "=r"(__err)		\
+		     : "0" (__NR_##name)		\
+		     );					\
+	if (unlikely((long) __err < 4095))		\
+		goto error_handler;			\
+							\
+	return __res;					\
+							\
+ error_handler:						\
+	errno = 4095 - __err;				\
+	return (type) 0xffffffffUL;			\
+}
+
+/*
+ * one argument boot loader call stub
+ */
+#define _bsc1(type, name, atype, _a)			\
+type name(atype _a)					\
+{							\
+	register long __err;				\
+	register type __res asm("gr7");			\
+	register atype a asm("gr8") = _a;		\
+							\
+	asm volatile("	tira	gr0,#126	\n"	\
+		     "	setlos	#4095,%1	\n"	\
+		     "	add	%0,%1,%1	\n"	\
+		     : "=r"(__res), "=r"(__err)		\
+		     : "0" (__NR_##name),		\
+		     "r" (a)				\
+		     );					\
+	if (unlikely((long) __err < 4095))		\
+		goto error_handler;			\
+							\
+	return __res;					\
+							\
+ error_handler:						\
+	errno = 4095 - __err;				\
+	return (type) 0xffffffffUL;			\
+}
+
+/*
+ * two argument boot loader call stub
+ */
+#define _bsc2(type, name, atype, _a, btype, _b)		\
+type name(atype _a,					\
+	  btype _b)					\
+{							\
+	register long __err;				\
+	register type __res asm("gr7");			\
+	register atype a asm("gr8") = _a;		\
+	register atype b asm("gr9") = _b;		\
+							\
+	asm volatile("	tira	gr0,#126	\n"	\
+		     "	setlos	#4095,%1	\n"	\
+		     "	add	%0,%1,%1	\n"	\
+		     : "=r"(__res), "=r"(__err)		\
+		     : "0" (__NR_##name),		\
+		     "r" (a),				\
+		     "r" (b)				\
+		     );					\
+	if (unlikely((long) __err < 4095))		\
+		goto error_handler;			\
+							\
+	return __res;					\
+							\
+ error_handler:						\
+	errno = 4095 - __err;				\
+	return (type) 0xffffffffUL;			\
+}
+
+/*
+ * three argument boot loader call stub
+ */
+#define _bsc3(type, name, atype, _a, btype, _b, ctype, _c)	\
+type name(atype _a,						\
+	  btype _b,						\
+	  ctype _c)						\
+{								\
+	register long __err;					\
+	register type __res asm("gr7");				\
+	register atype a asm("gr8") = _a;			\
+	register btype b asm("gr9") = _b;			\
+	register ctype c asm("gr10") = _c;			\
+								\
+	asm volatile("	tira	gr0,#126	\n"		\
+		     "	setlos	#4095,%1	\n"		\
+		     "	add	%0,%1,%1	\n"		\
+		     : "=r"(__res), "=r"(__err)			\
+		     : "0" (__NR_##name),			\
+		     "r" (a),					\
+		     "r" (b),					\
+		     "r" (c)					\
+		     );						\
+	if (unlikely((long) __err < 4095))			\
+		goto error_handler;				\
+								\
+	return __res;						\
+								\
+ error_handler:							\
+	errno = 4095 - __err;					\
+	return (type) 0xffffffffUL;				\
+}
+
+/*
+ * four argument boot loader call stub
+ */
+#define _bsc4(type, name, atype, _a, btype, _b, ctype, _c, dtype, _d)		\
+type name(atype _a,								\
+	  btype _b,								\
+	  ctype _c,								\
+	  dtype _d)								\
+{										\
+	register long __err;							\
+	register type __res asm("gr7");						\
+	register atype a asm("gr8") = _a;					\
+	register btype b asm("gr9") = _b;					\
+	register ctype c asm("gr10") = _c;					\
+	register dtype d asm("gr11") = _d;					\
+										\
+	asm volatile("	tira	gr0,#126	\n"				\
+		     "	setlos	#4095,%1	\n"				\
+		     "	add	%0,%1,%1	\n"				\
+		     : "=r"(__res), "=r"(__err)					\
+		     : "0" (__NR_##name),					\
+		     "r" (a),							\
+		     "r" (b),							\
+		     "r" (c),							\
+		     "r" (d)							\
+		     );								\
+	if (unlikely((long) __err < 4095))					\
+		goto error_handler;						\
+										\
+	return __res;								\
+										\
+ error_handler:									\
+	errno = 4095 - __err;							\
+	return (type) 0xffffffffUL;						\
+}
+
+/*
+ * five argument boot loader call stub
+ */
+#define _bsc5(type, name, atype, _a, btype, _b, ctype, _c, dtype, _d, etype, _e)	\
+type name(atype _a,									\
+	  btype _b,									\
+	  ctype _c,									\
+	  dtype _d,									\
+	  etype _e)									\
+{											\
+	register long __err;								\
+	register type __res asm("gr7");							\
+	register atype a asm("gr8") = _a;						\
+	register btype b asm("gr9") = _b;						\
+	register ctype c asm("gr10") = _c;						\
+	register dtype d asm("gr11") = _d;						\
+	register etype e asm("gr12") = _e;						\
+											\
+	asm volatile("	tira	gr0,#126	\n"					\
+		     "	setlos	#4095,%1	\n"					\
+		     "	add	%0,%1,%1	\n"					\
+		     : "=r"(__res), "=r"(__err)						\
+		     : "0" (__NR_##name),						\
+		     "r" (a),								\
+		     "r" (b),								\
+		     "r" (c),								\
+		     "r" (d),								\
+		     "r" (e)								\
+		     );									\
+	if (unlikely((long) __err < 4095))						\
+		goto error_handler;							\
+											\
+	return __res;									\
+											\
+ error_handler:										\
+	errno = 4095 - __err;								\
+	return (type) 0xffffffffUL;							\
+}
+
+/* Command codes for the flash_command routine */
+#define FLASH_SELECT    0       /* no command; just perform the mapping */
+#define FLASH_RESET     1       /* reset to read mode */
+#define FLASH_READ      1       /* reset to read mode, by any other name */
+#define FLASH_AUTOSEL   2       /* autoselect (fake Vid on pin 9) */
+#define FLASH_PROG      3       /* program a word */
+#define FLASH_CERASE    4       /* chip erase */
+#define FLASH_SERASE    5       /* sector erase */
+#define FLASH_ESUSPEND  6       /* suspend sector erase */
+#define FLASH_ERESUME   7       /* resume sector erase */
+#define FLASH_UB        8       /* go into unlock bypass mode */
+#define FLASH_UBPROG    9       /* program a word using unlock bypass */
+#define FLASH_UBRESET   10      /* reset to read mode from unlock bypass mode */
+#define FLASH_LASTCMD   10      /* used for parameter checking */
+
+/* Return codes from flash_status */
+#define STATUS_READY    0       /* ready for action */
+#define STATUS_BUSY     1       /* operation in progress */
+#define STATUS_ERSUSP   2       /* erase suspended */
+#define STATUS_TIMEOUT  3       /* operation timed out */
+#define STATUS_ERROR    4       /* unclassified but unhappy status */
+
+/* manufacturer ID */
+#define AMDPART   	0x01
+#define TOSPART		0x98
+#define SSTPART		0xbf
+#define ATPART		0x1f
+
+/* A list of 4 AMD device ID's - add others as needed */
+#define ID_AM29DL800T   0x224A
+#define ID_AM29DL800B   0x22CB
+#define ID_AM29LV800T   0x22DA
+#define ID_AM29LV800B   0x225B
+#define ID_AM29LV160B   0x2249
+#define ID_AM29LV160T   0x22C4
+#define ID_TC58FVT160	0x00C2
+#define ID_TC58FVB160	0x0043
+#define ID_TC58FVB160X2	0x00430043
+#define ID_AM29LV400B   0x22BA
+#define ID_AT49BV1614   0x00C0
+#define ID_SST39VF160   0x2782
+/* definition for arm7tdni */
+#define ID_AT27LV1024	0x0000
+#define ID_AT29LV1024	0x0001
+
+#define SECTOR_DIRTY   0x01
+#define SECTOR_ERASED  0x02
+#define SECTOR_PROTECT 0x04
+
+#define PGM_ERASE_FIRST 0x0001
+#define PGM_RESET_AFTER 0x0002
+#define PGM_EXEC_AFTER  0x0004
+#define PGM_HALT_AFTER  0x0008
+#define PGM_DEBUG       0x0010
+
+/* an mnode points at 4k pages of data through an offset table. */
+typedef struct _memnode {
+	int	len;
+	int	*offset;
+} mnode_t;
+
+#endif /* __UCBOOTSTRAP_H__ */
diff -urN linux-2.4.29/include/asm-frv/ucontext.h linux-2.4.29-uc1/include/asm-frv/ucontext.h
--- linux-2.4.29/include/asm-frv/ucontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/ucontext.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef _ASM_UCONTEXT_H
+#define _ASM_UCONTEXT_H
+
+struct ucontext {
+	unsigned long		uc_flags;
+	struct ucontext		*uc_link;
+	stack_t			uc_stack;
+	struct sigcontext	uc_mcontext;
+	sigset_t		uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-frv/unaligned.h linux-2.4.29-uc1/include/asm-frv/unaligned.h
--- linux-2.4.29/include/asm-frv/unaligned.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/unaligned.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,195 @@
+#ifndef _ASM_UNALIGNED_H
+#define _ASM_UNALIGNED_H
+
+#include <linux/config.h>
+
+/*
+ * Unaligned accesses on uClinux can't be performed in a fault handler
+ * - the CPU detects them as imprecise exceptions making this
+ * impossible.
+ *
+ * With the FR451, however, they are precise, and so we used to fix
+ * them up in the memory access fault handler.  However, instruction
+ * bundling make this impractical.  So, now we fall back to using
+ * memcpy.
+ */
+#ifndef CONFIG_UCLINUX
+
+/*
+ * The asm statement in the macros below is a way to get GCC to copy a
+ * value from one variable to another without having any clue it's
+ * actually doing so, so that it won't have any idea that the values
+ * in the two variables are related.
+ */
+
+#define get_unaligned(ptr) ({				\
+	typeof((*(ptr))) __x;				\
+	void *__ptrcopy;				\
+	asm("" : "=r" (__ptrcopy) : "0" (ptr));		\
+	memcpy(&__x, __ptrcopy, sizeof(*(ptr)));	\
+	__x;						\
+})
+
+#define put_unaligned(val, ptr) ({			\
+	typeof((*(ptr))) __x = (val);			\
+	void *__ptrcopy;				\
+	asm("" : "=r" (__ptrcopy) : "0" (ptr));		\
+	memcpy(__ptrcopy, &__x, sizeof(*(ptr)));	\
+})
+
+extern int handle_misalignment(unsigned long esr0, unsigned long ear0,
+			       unsigned long epcr0);
+
+#else
+
+#define get_unaligned(ptr)							\
+({										\
+	typeof(*(ptr)) x;							\
+	const char *__p = (const char *) (ptr);					\
+										\
+	switch (sizeof(x)) {							\
+	case 1:									\
+		x = *(ptr);							\
+		break;								\
+	case 2:									\
+	{									\
+		uint8_t a;							\
+		asm("	ldub%I2		%M2,%0		\n"			\
+		    "	ldub%I3.p	%M3,%1		\n"			\
+		    "	slli		%0,#8,%0	\n"			\
+		    "	or		%0,%1,%0	\n"			\
+		    : "=&r"(x), "=&r"(a)					\
+		    : "m"(__p[0]),  "m"(__p[1])					\
+		    );								\
+		break;								\
+	}									\
+										\
+	case 4:									\
+	{									\
+		uint8_t a;							\
+		asm("	ldub%I2		%M2,%0		\n"			\
+		    "	ldub%I3.p	%M3,%1		\n"			\
+		    "	slli		%0,#8,%0	\n"			\
+		    "	or		%0,%1,%0	\n"			\
+		    "	ldub%I4.p	%M4,%1		\n"			\
+		    "	slli		%0,#8,%0	\n"			\
+		    "	or		%0,%1,%0	\n"			\
+		    "	ldub%I5.p	%M5,%1		\n"			\
+		    "	slli		%0,#8,%0	\n"			\
+		    "	or		%0,%1,%0	\n"			\
+		    : "=&r"(x), "=&r"(a)					\
+		    : "m"(__p[0]),  "m"(__p[1]), "m"(__p[2]), "m"(__p[3])	\
+		    );								\
+		break;								\
+	}									\
+										\
+	case 8:									\
+	{									\
+		union { uint64_t x; u32 y[2]; } z;				\
+		uint8_t a;							\
+		asm("	ldub%I3		%M3,%0		\n"			\
+		    "	ldub%I4.p	%M4,%2		\n"			\
+		    "	slli		%0,#8,%0	\n"			\
+		    "	or		%0,%2,%0	\n"			\
+		    "	ldub%I5.p	%M5,%2		\n"			\
+		    "	slli		%0,#8,%0	\n"			\
+		    "	or		%0,%2,%0	\n"			\
+		    "	ldub%I6.p	%M6,%2		\n"			\
+		    "	slli		%0,#8,%0	\n"			\
+		    "	or		%0,%2,%0	\n"			\
+		    "	ldub%I7		%M7,%1		\n"			\
+		    "	ldub%I8.p	%M8,%2		\n"			\
+		    "	slli		%1,#8,%1	\n"			\
+		    "	or		%1,%2,%1	\n"			\
+		    "	ldub%I9.p	%M9,%2		\n"			\
+		    "	slli		%1,#8,%1	\n"			\
+		    "	or		%1,%2,%1	\n"			\
+		    "	ldub%I10.p	%M10,%2		\n"			\
+		    "	slli		%1,#8,%1	\n"			\
+		    "	or		%1,%2,%1	\n"			\
+		    : "=&r"(z.y[0]), "=&r"(z.y[1]), "=&r"(a)			\
+		    : "m"(__p[0]), "m"(__p[1]), "m"(__p[2]), "m"(__p[3]),	\
+		      "m"(__p[4]), "m"(__p[5]), "m"(__p[6]), "m"(__p[7])	\
+		    );								\
+		x = z.x;							\
+		break;								\
+	}									\
+										\
+	default:								\
+		x = 0;								\
+		BUG();								\
+		break;								\
+	}									\
+										\
+	x;									\
+})
+
+#define put_unaligned(val, ptr)								\
+do {											\
+	char *__p = (char *) (ptr);							\
+	int x;										\
+											\
+	switch (sizeof(*ptr)) {								\
+	case 2:										\
+	{										\
+		asm("	stb%I1.p	%0,%M1		\n"				\
+		    "	srli		%0,#8,%0	\n"				\
+		    "	stb%I2		%0,%M2		\n"				\
+		    : "=r"(x), "=m"(__p[1]),  "=m"(__p[0])				\
+		    : "0"(val)								\
+		    );									\
+		break;									\
+	}										\
+											\
+	case 4:										\
+	{										\
+		asm("	stb%I1.p	%0,%M1		\n"				\
+		    "	srli		%0,#8,%0	\n"				\
+		    "	stb%I2.p	%0,%M2		\n"				\
+		    "	srli		%0,#8,%0	\n"				\
+		    "	stb%I3.p	%0,%M3		\n"				\
+		    "	srli		%0,#8,%0	\n"				\
+		    "	stb%I4		%0,%M4		\n"				\
+		    : "=r"(x), "=m"(__p[3]),  "=m"(__p[2]), "=m"(__p[1]), "=m"(__p[0])	\
+		    : "0"(val)								\
+		    );									\
+		break;									\
+	}										\
+											\
+	case 8:										\
+	{										\
+		uint32_t __high, __low;							\
+		__high = (uint64_t)val >> 32;						\
+		__low = val & 0xffffffff;						\
+		asm("	stb%I2.p	%0,%M2		\n"				\
+		    "	srli		%0,#8,%0	\n"				\
+		    "	stb%I3.p	%0,%M3		\n"				\
+		    "	srli		%0,#8,%0	\n"				\
+		    "	stb%I4.p	%0,%M4		\n"				\
+		    "	srli		%0,#8,%0	\n"				\
+		    "	stb%I5.p	%0,%M5		\n"				\
+		    "	srli		%0,#8,%0	\n"				\
+		    "	stb%I6.p	%1,%M6		\n"				\
+		    "	srli		%1,#8,%1	\n"				\
+		    "	stb%I7.p	%1,%M7		\n"				\
+		    "	srli		%1,#8,%1	\n"				\
+		    "	stb%I8.p	%1,%M8		\n"				\
+		    "	srli		%1,#8,%1	\n"				\
+		    "	stb%I9		%1,%M9		\n"				\
+		    : "=&r"(__low), "=&r"(__high), "=m"(__p[7]), "=m"(__p[6]), 		\
+		      "=m"(__p[5]), "=m"(__p[4]), "=m"(__p[3]), "=m"(__p[2]), 		\
+		      "=m"(__p[1]), "=m"(__p[0])					\
+		    : "0"(__low), "1"(__high)						\
+		    );									\
+		break;									\
+	}										\
+											\
+        default:									\
+		*(ptr) = (val);								\
+		break;									\
+	}										\
+} while(0)
+
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-frv/unistd.h linux-2.4.29-uc1/include/asm-frv/unistd.h
--- linux-2.4.29/include/asm-frv/unistd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/unistd.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,448 @@
+#ifndef _ASM_UNISTD_H_
+#define _ASM_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_restart_syscall      0
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_lchown		 16
+#define __NR_break		 17
+#define __NR_oldstat		 18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_umount2		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+// #define __NR_oldolduname	 /* 59 */ obsolete
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_getrlimit		 76	/* Back compatible 2Gig limited rlimit */
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+// #define __NR_mmap		 90	/* obsolete - not implemented */
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+// #define __NR_profil		 /* 98 */ obsolete
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+// #define __NR_ioperm		/* 101 */ not supported
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+// #define __NR_olduname		/* 109 */ obsolete
+// #define __NR_iopl		/* 110 */ not supported
+#define __NR_vhangup		111
+// #define __NR_idle		/* 112 */ Obsolete
+// #define __NR_vm86old		/* 113 */ not supported
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+// #define __NR_modify_ldt	/* 123 */ not supported
+#define __NR_cacheflush		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+// #define __NR_vm86		/* 166 */ not supported
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl		172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread		180
+#define __NR_pwrite		181
+#define __NR_chown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_getpmsg		188	/* some people actually want streams */
+#define __NR_putpmsg		189	/* some people actually want streams */
+#define __NR_vfork		190
+#define __NR_ugetrlimit		191	/* SuS compliant getrlimit */
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_lchown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_chown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+#define __NR_pivot_root		217
+#define __NR_mincore		218
+#define __NR_madvise		219
+#define __NR_getdents64		220
+#define __NR_fcntl64		221
+#define __NR_security		223	/* syscall for security modules */
+#define __NR_gettid		224
+#define __NR_readahead		225
+#define __NR_setxattr		226
+#define __NR_lsetxattr		227
+#define __NR_fsetxattr		228
+#define __NR_getxattr		229
+#define __NR_lgetxattr		230
+#define __NR_fgetxattr		231
+#define __NR_listxattr		232
+#define __NR_llistxattr		233
+#define __NR_flistxattr		234
+#define __NR_removexattr	235
+#define __NR_lremovexattr	236
+#define __NR_fremovexattr	237
+#define __NR_tkill		238
+#define __NR_sendfile64		239
+#define __NR_futex		240
+#define __NR_sched_setaffinity	241
+#define __NR_sched_getaffinity	242
+#define __NR_set_thread_area	243
+#define __NR_get_thread_area	244
+#define __NR_io_setup		245
+#define __NR_io_destroy		246
+#define __NR_io_getevents	247
+#define __NR_io_submit		248
+#define __NR_io_cancel		249
+#define __NR_alloc_hugepages	250
+#define __NR_free_hugepages	251
+#define __NR_exit_group		252
+#define __NR_lookup_dcookie	253
+#define __NR_epoll_create	254
+#define __NR_epoll_ctl		255
+#define __NR_epoll_wait		256
+#define __NR_remap_file_pages	257
+#define __NR_set_tid_address	258
+#define __NR_timer_create	259
+#define __NR_timer_settime	(__NR_timer_create+1)
+#define __NR_timer_gettime	(__NR_timer_create+2)
+#define __NR_timer_getoverrun	(__NR_timer_create+3)
+#define __NR_timer_delete	(__NR_timer_create+4)
+#define __NR_clock_settime	(__NR_timer_create+5)
+#define __NR_clock_gettime	(__NR_timer_create+6)
+#define __NR_clock_getres	(__NR_timer_create+7)
+#define __NR_clock_nanosleep	(__NR_timer_create+8)
+#define __NR_statfs64		268
+#define __NR_fstatfs64		269
+#define __NR_tgkill		270
+#define __NR_utimes		271
+#define __NR_fadvise64_64	272
+#define __NR_vserver		273
+#define __NR_mbind		274
+#define __NR_get_mempolicy	275
+#define __NR_set_mempolicy	276
+#define __NR_mq_open 		277
+#define __NR_mq_unlink		(__NR_mq_open+1)
+#define __NR_mq_timedsend	(__NR_mq_open+2)
+#define __NR_mq_timedreceive	(__NR_mq_open+3)
+#define __NR_mq_notify		(__NR_mq_open+4)
+#define __NR_mq_getsetattr	(__NR_mq_open+5)
+#define __NR_sys_kexec_load	283
+
+/*
+ * process the return value of a syscall, consigning it to one of two possible fates
+ * - user-visible error numbers are in the range -1 - -4095: see <asm-frv/errno.h>
+ */
+#undef __syscall_return
+#define __syscall_return(type, res)					\
+do {									\
+        unsigned long __sr2 = (res);					\
+	if (__builtin_expect(__sr2 >= (unsigned long)(-4095), 0)) {	\
+		errno = (-__sr2);					\
+		__sr2 = ULONG_MAX;					\
+	}								\
+	return (type) __sr2;						\
+} while (0)
+
+/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
+
+#undef _syscall0
+#define _syscall0(type,name)						\
+type name(void)								\
+{									\
+	register unsigned long __scnum __asm__ ("gr7") = (__NR_##name);	\
+	register unsigned long __sc0 __asm__ ("gr8");			\
+	__asm__ __volatile__ ("tira gr0,#0"				\
+			      : "=r" (__sc0)				\
+			      : "r" (__scnum));				\
+	__syscall_return(type, __sc0);					\
+}
+
+#undef _syscall1
+#define _syscall1(type,name,type1,arg1)						\
+type name(type1 arg1)								\
+{										\
+	register unsigned long __scnum __asm__ ("gr7") = (__NR_##name);		\
+	register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1;	\
+	__asm__ __volatile__ ("tira gr0,#0"					\
+			      : "+r" (__sc0)					\
+			      : "r" (__scnum));					\
+	__syscall_return(type, __sc0);						\
+}
+
+#undef _syscall2
+#define _syscall2(type,name,type1,arg1,type2,arg2)				\
+type name(type1 arg1,type2 arg2)						\
+{										\
+	register unsigned long __scnum __asm__ ("gr7") = (__NR_##name);		\
+	register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1;	\
+	register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2;	\
+	__asm__ __volatile__ ("tira gr0,#0"					\
+			      : "+r" (__sc0)					\
+			      : "r" (__scnum), "r" (__sc1));			\
+	__syscall_return(type, __sc0);						\
+}
+
+#undef _syscall3
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)			\
+type name(type1 arg1,type2 arg2,type3 arg3)					\
+{										\
+	register unsigned long __scnum __asm__ ("gr7") = (__NR_##name);		\
+	register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1;	\
+	register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2;	\
+	register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3;	\
+	__asm__ __volatile__ ("tira gr0,#0"					\
+			      : "+r" (__sc0)					\
+			      : "r" (__scnum), "r" (__sc1), "r" (__sc2));	\
+	__syscall_return(type, __sc0);						\
+}
+
+#undef _syscall4
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)		\
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4)				\
+{											\
+	register unsigned long __scnum __asm__ ("gr7") = (__NR_##name);			\
+	register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1;		\
+	register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2;		\
+	register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3;		\
+	register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4;		\
+	__asm__ __volatile__ ("tira gr0,#0"						\
+			      : "+r" (__sc0)						\
+			      : "r" (__scnum), "r" (__sc1), "r" (__sc2), "r" (__sc3));	\
+	__syscall_return(type, __sc0);							\
+}
+
+#undef _syscall5
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5)	\
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)			\
+{											\
+	register unsigned long __scnum __asm__ ("gr7") = (__NR_##name);			\
+	register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1;		\
+	register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2;		\
+	register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3;		\
+	register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4;		\
+	register unsigned long __sc4 __asm__ ("gr12") = (unsigned long) arg5;		\
+	__asm__ __volatile__ ("tira gr0,#0"						\
+			      : "+r" (__sc0)						\
+			      : "r" (__scnum), "r" (__sc1), "r" (__sc2),		\
+			      "r" (__sc3), "r" (__sc4));				\
+	__syscall_return(type, __sc0);							\
+}
+
+#undef _syscall6
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5, type6, arg6) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6)		 \
+{												 \
+	register unsigned long __scnum __asm__ ("gr7") = (__NR_##name);				 \
+	register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1;			 \
+	register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2;			 \
+	register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3;			 \
+	register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4;			 \
+	register unsigned long __sc4 __asm__ ("gr12") = (unsigned long) arg5;			 \
+	register unsigned long __sc5 __asm__ ("gr13") = (unsigned long) arg6;			 \
+	__asm__ __volatile__ ("tira gr0,#0"							 \
+			      : "+r" (__sc0)							 \
+			      : "r" (__scnum), "r" (__sc1), "r" (__sc2),			 \
+			      "r" (__sc3), "r" (__sc4), "r" (__sc5));				 \
+	__syscall_return(type, __sc0);								 \
+}
+		
+
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+static inline _syscall0(int,pause)
+static inline _syscall0(int,sync)
+static inline _syscall0(pid_t,setsid)
+static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+static inline _syscall1(int,dup,int,fd)
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+static inline _syscall1(int,close,int,fd)
+static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,delete_module,const char *,name)
+
+static inline pid_t wait(int * wait_stat)
+{
+	return waitpid(-1,wait_stat,0);
+}
+
+#endif
+
+#endif /* _ASM_UNISTD_H_ */
diff -urN linux-2.4.29/include/asm-frv/user.h linux-2.4.29-uc1/include/asm-frv/user.h
--- linux-2.4.29/include/asm-frv/user.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/user.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,80 @@
+/* user.h: FR-V core file format stuff
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_USER_H
+#define _ASM_USER_H
+
+#include <asm/page.h>
+#include <asm/registers.h>
+
+/* Core file format: The core file is written in such a way that gdb
+ * can understand it and provide useful information to the user (under
+ * linux we use the 'trad-core' bfd).  There are quite a number of
+ * obstacles to being able to view the contents of the floating point
+ * registers, and until these are solved you will not be able to view
+ * the contents of them.  Actually, you can read in the core file and
+ * look at the contents of the user struct to find out what the
+ * floating point registers contain.
+ * 
+ * The actual file contents are as follows:
+ * UPAGE:
+ *   1 page consisting of a user struct that tells gdb what is present
+ *   in the file.  Directly after this is a copy of the task_struct,
+ *   which is currently not used by gdb, but it may come in useful at
+ *   some point.  All of the registers are stored as part of the
+ *   upage.  The upage should always be only one page.
+ *
+ * DATA:
+ *   The data area is stored.  We use current->end_text to
+ *   current->brk to pick up all of the user variables, plus any
+ *   memory that may have been malloced.  No attempt is made to
+ *   determine if a page is demand-zero or if a page is totally
+ *   unused, we just cover the entire range.  All of the addresses are
+ *   rounded in such a way that an integral number of pages is
+ *   written.
+ *
+ * STACK:
+ *   We need the stack information in order to get a meaningful
+ *   backtrace.  We need to write the data from (esp) to
+ *   current->start_stack, so we round each of these off in order to
+ *   be able to write an integer number of pages.  The minimum core
+ *   file size is 3 pages, or 12288 bytes.
+ */
+	
+/* When the kernel dumps core, it starts by dumping the user struct -
+ * this will be used by gdb to figure out where the data and stack segments
+ *  are within the file, and what virtual addresses to use.
+ */
+struct user {
+	/* We start with the registers, to mimic the way that "memory" is returned
+	 * from the ptrace(3,...) function.  */
+	struct user_context	regs;
+
+	/* The rest of this junk is to help gdb figure out what goes where */
+	unsigned long		u_tsize;	/* Text segment size (pages). */
+	unsigned long		u_dsize;	/* Data segment size (pages). */
+	unsigned long		u_ssize;	/* Stack segment size (pages). */
+	unsigned long		start_code;     /* Starting virtual address of text. */
+	unsigned long		start_stack;	/* Starting virtual address of stack area.
+						 * This is actually the bottom of the stack,
+						 * the top of the stack is always found in the
+						 * esp register.  */
+	long int		signal;		/* Signal that caused the core dump. */
+
+	unsigned long		magic;		/* To uniquely identify a core file */
+	char			u_comm[32];	/* User command that was responsible */
+};
+
+#define NBPG			PAGE_SIZE
+#define UPAGES			1
+#define HOST_TEXT_START_ADDR	(u.start_code)
+#define HOST_STACK_END_ADDR	(u.start_stack + u.u_ssize * NBPG)
+
+#endif
diff -urN linux-2.4.29/include/asm-frv/virtconvert.h linux-2.4.29-uc1/include/asm-frv/virtconvert.h
--- linux-2.4.29/include/asm-frv/virtconvert.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/virtconvert.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,32 @@
+#ifndef __ASM_VIRT_CONVERT__
+#define __ASM_VIRT_CONVERT__
+
+/*
+ * Macros used for converting between virtual and physical mappings.
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <asm/setup.h>
+
+#ifndef CONFIG_UCLINUX
+
+#define phys_to_virt(vaddr)	((void *) ((unsigned long)(vaddr) + PAGE_OFFSET))
+#define virt_to_phys(vaddr)	((unsigned long) (vaddr) - PAGE_OFFSET)
+
+#else
+
+#define phys_to_virt(vaddr)	((void *) (vaddr))
+#define virt_to_phys(vaddr)	((unsigned long) (vaddr))
+
+#endif
+
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define page_to_phys(page)	virt_to_phys((void *)__page_address(page))
+
+#endif
+#endif
diff -urN linux-2.4.29/include/asm-frv/vmlinux.h linux-2.4.29-uc1/include/asm-frv/vmlinux.h
--- linux-2.4.29/include/asm-frv/vmlinux.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-frv/vmlinux.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,47 @@
+/* vmlinux.h: linkage layout variables
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_VMLINUX_H
+#define _ASM_VMLINUX_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+#ifdef __KERNEL__
+
+/*
+ * we don't want to put variables in the GP-REL section if they're not used very much - that would
+ * be waste since GP-REL addressing is limited to GP16+/-2048
+ */
+#define __nongpreldata	__attribute__((section(".data")))
+#define __nongprelbss	__attribute__((section(".bss")))
+
+/*
+ * linker symbols
+ */
+extern const char _stext[], _etext[], _sdata[], _edata[], _sbss[], _ebss[], _end[];
+extern const char __init_begin[], __init_end[];
+extern const void __kernel_image_start, __kernel_image_end, __page_offset;
+
+extern unsigned long __nongprelbss memory_start;
+extern unsigned long __nongprelbss memory_end;
+extern unsigned long __nongprelbss rom_length;
+
+/* determine if we're running from ROM */
+static inline int is_in_rom(unsigned long addr)
+{
+	return 0; /* default case: not in ROM */
+}
+
+#endif
+#endif
+#endif /* _ASM_VMLINUX_H */
diff -urN linux-2.4.29/include/asm-generic/div64.h linux-2.4.29-uc1/include/asm-generic/div64.h
--- linux-2.4.29/include/asm-generic/div64.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-generic/div64.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,66 @@
+#ifndef _ASM_GENERIC_DIV64_H
+#define _ASM_GENERIC_DIV64_H
+
+#include <linux/types.h>
+
+/*
+ * do_div() performs a 64bit/32bit unsigned division and modulo.
+ * The 64bit result is stored back in the divisor, the 32bit
+ * remainder is returned.
+ *
+ * A semantically correct implementation would do this:
+ *
+ *	static inline uint32_t do_div(uint64_t &n, uint32_t base)
+ *	{
+ *		uint32_t rem;
+ *		rem = n % base;
+ *		n = n / base;
+ *		return rem;
+ *	}
+ *
+ * We can't rely on GCC's "long long" math since it would turn
+ * everything into a full 64bit division implemented through _udivdi3(),
+ * which is much slower.
+ */
+
+#if BITS_PER_LONG == 64
+
+# define do_div(n,base) ({					\
+	uint32_t __res;						\
+	__res = ((uint64_t)(n)) % (uint32_t)(base);		\
+	(n) = ((uint64_t)(n)) / (uint32_t)(base);		\
+	__res;							\
+ })
+
+#elif BITS_PER_LONG == 32
+
+# define do_div(n,base)	({					\
+								\
+	uint32_t __low, __low2, __high, __rem;			\
+	__low  = (n) & 0xffffffff;				\
+	__high = (n) >> 32;					\
+	if (__high) {						\
+		__rem   = __high % (uint32_t)(base);		\
+		__high  = __high / (uint32_t)(base);		\
+		__low2  = __low >> 16;				\
+		__low2 += __rem << 16;				\
+		__rem   = __low2 % (uint32_t)(base);		\
+		__low2  = __low2 / (uint32_t)(base);		\
+		__low   = __low & 0xffff;			\
+		__low  += __rem << 16;				\
+		__rem   = __low  % (uint32_t)(base);		\
+		__low   = __low  / (uint32_t)(base);		\
+		(n) = __low  + ((uint64_t)__low2 << 16) +	\
+			((uint64_t) __high << 32);		\
+	} else {						\
+		__rem = __low % (uint32_t)(base);		\
+		(n) = (__low / (uint32_t)(base));		\
+	}							\
+	__rem;							\
+ })
+
+#else /* BITS_PER_LONG == ?? */
+# error do_div() does not yet support the C64
+#endif /* BITS_PER_LONG */
+
+#endif /* _ASM_GENERIC_DIV64_H */
diff -urN linux-2.4.29/include/asm-h8300/aki3068net/ne.h linux-2.4.29-uc1/include/asm-h8300/aki3068net/ne.h
--- linux-2.4.29/include/asm-h8300/aki3068net/ne.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/aki3068net/ne.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,23 @@
+/* AE-3068 (aka. aki3068net) RTL8019AS Config */
+
+#define NE2000_ADDR		CONFIG_NE_BASE
+#define NE2000_IRQ              5
+#define NE2000_IRQ_VECTOR	(12 + NE2000_IRQ)
+#define	NE2000_BYTE		volatile unsigned short
+
+#define IER                     0xfee015
+#define ISR			0xfee016
+#define IRQ_MASK		(1 << NE2000_IRQ)
+
+#define WCRL                    0xfee023
+#define MAR0A                   0xffff20
+#define ETCR0A                  0xffff24
+#define DTCR0A                  0xffff27
+#define MAR0B                   0xffff28
+#define DTCR0B                  0xffff2f
+
+#define H8300_INIT_NE()                  \
+do {                                     \
+	wordlength = 1;                  \
+        outb_p(0x48, ioaddr + EN0_DCFG); \
+} while(0)
diff -urN linux-2.4.29/include/asm-h8300/a.out.h linux-2.4.29-uc1/include/asm-h8300/a.out.h
--- linux-2.4.29/include/asm-h8300/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/a.out.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,28 @@
+#ifndef __H8300_A_OUT_H__
+#define __H8300_A_OUT_H__
+
+/* do not use */
+
+struct exec
+{
+  unsigned long a_info;		/* Use macros N_MAGIC, etc for access */
+  unsigned a_text;		/* length of text, in bytes */
+  unsigned a_data;		/* length of data, in bytes */
+  unsigned a_bss;		/* length of uninitialized data area for file, in bytes */
+  unsigned a_syms;		/* length of symbol table data in file, in bytes */
+  unsigned a_entry;		/* start address */
+  unsigned a_trsize;		/* length of relocation info for text, in bytes */
+  unsigned a_drsize;		/* length of relocation info for data, in bytes */
+};
+
+#define N_TRSIZE(a)	((a).a_trsize)
+#define N_DRSIZE(a)	((a).a_drsize)
+#define N_SYMSIZE(a)	((a).a_syms)
+
+#ifdef __KERNEL__
+
+#define STACK_TOP	TASK_SIZE
+
+#endif
+
+#endif /* __H8300_A_OUT_H__ */
diff -urN linux-2.4.29/include/asm-h8300/atomic.h linux-2.4.29-uc1/include/asm-h8300/atomic.h
--- linux-2.4.29/include/asm-h8300/atomic.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/atomic.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,104 @@
+#ifndef __ARCH_H8300_ATOMIC__
+#define __ARCH_H8300_ATOMIC__
+
+/*
+ * Atomic operations that C can't guarantee us.  Useful for
+ * resource counting etc..
+ */
+
+typedef struct { int counter; } atomic_t;
+#define ATOMIC_INIT(i)	{ (i) }
+
+#define atomic_read(v)		((v)->counter)
+#define atomic_set(v, i)	(((v)->counter) = i)
+
+#include <asm/system.h>
+
+static __inline__ int atomic_add_return(int i, atomic_t *v)
+{
+	int ret,flags;
+	__save_and_cli(flags);
+	ret = v->counter += i;
+	restore_flags(flags);
+	return ret;
+}
+
+#define atomic_add(i, v) atomic_add_return(i, v)
+
+static __inline__ int atomic_sub_return(int i, atomic_t *v)
+{
+	int ret,flags;
+	__save_and_cli(flags);
+	ret = v->counter -= i;
+	restore_flags(flags);
+	return ret;
+}
+
+#define atomic_sub(i, v) atomic_sub_return(i, v)
+
+static __inline__ int atomic_inc_return(atomic_t *v)
+{
+	int ret,flags;
+	__save_and_cli(flags);
+	v->counter++;
+	ret = v->counter;
+	restore_flags(flags);
+	return ret;
+}
+
+#define atomic_inc(v) atomic_inc_return(v)
+
+static __inline__ int atomic_dec_return(atomic_t *v)
+{
+	int ret,flags;
+	__save_and_cli(flags);
+	--v->counter;
+	ret = v->counter;
+	restore_flags(flags);
+	return ret;
+}
+
+#define atomic_dec(v) atomic_dec_return(v)
+
+static __inline__ int atomic_dec_and_test(atomic_t *v)
+{
+	int ret,flags;
+	__save_and_cli(flags);
+	--v->counter;
+	ret = v->counter;
+	restore_flags(flags);
+	return ret == 0;
+}
+
+static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *v)
+{
+	__asm__ __volatile__("stc ccr,r1l\n\t"
+	                     "orc #0x80,ccr\n\t"
+	                     "mov.l %0,er0\n\t"
+	                     "and.l %1,er0\n\t"
+	                     "mov.l er0,%0\n\t"
+	                     "ldc r1l,ccr" 
+                             : "=m" (*v) : "g" (~(mask)) :"er0","er1");
+}
+
+static __inline__ void atomic_set_mask(unsigned long mask, unsigned long *v)
+{
+	__asm__ __volatile__("stc ccr,r1l\n\t"
+	                     "orc #0x80,ccr\n\t"
+	                     "mov.l %0,er0\n\t"
+	                     "or.l %1,er0\n\t"
+	                     "mov.l er0,%0\n\t"
+	                     "ldc r1l,ccr" 
+                             : "=m" (*v) : "g" (mask) :"er0","er1");
+}
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec()    barrier()
+#define smp_mb__after_atomic_dec() barrier()
+#define smp_mb__before_atomic_inc()    barrier()
+#define smp_mb__after_atomic_inc() barrier()
+
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+
+#endif /* __ARCH_H8300_ATOMIC __ */
diff -urN linux-2.4.29/include/asm-h8300/bitops.h linux-2.4.29-uc1/include/asm-h8300/bitops.h
--- linux-2.4.29/include/asm-h8300/bitops.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/bitops.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,393 @@
+#ifndef _H8300_BITOPS_H
+#define _H8300_BITOPS_H
+
+/*
+ * Copyright 1992, Linus Torvalds.
+ * Copyright 2002, Yoshinori Sato
+ */
+
+#include <linux/config.h>
+#include <asm/byteorder.h>	/* swab32 */
+#include <asm/system.h>
+
+#ifdef __KERNEL__
+/*
+ * Function prototypes to keep gcc -Wall happy
+ */
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+static __inline__ unsigned long ffz(unsigned long word)
+{
+        unsigned long result;
+
+	result = -1;
+	__asm__("1:\n\t"
+		"shlr.l %2\n\t"
+		"adds #1,%0\n\t"
+		"bcs 1b"
+		: "=r" (result)
+		: "0"  (result),"r" (word));
+	return result;
+}
+
+#define H8300_GEN_BITOP(FNNAME,OP)					   \
+static __inline__ void FNNAME(int nr, volatile void * addr)		   \
+{									   \
+	volatile unsigned char *b_addr;					   \
+	b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3);         \
+	if (__builtin_constant_p (nr & 7))				   \
+	{								   \
+		switch(nr & 7)						   \
+		{							   \
+		case 0:							   \
+			__asm__(OP " #0,@%0" : :"r"(b_addr) : "memory");   \
+			break;						   \
+		case 1:							   \
+			__asm__(OP " #1,@%0" : :"r"(b_addr) : "memory");   \
+			break;						   \
+		case 2:							   \
+			__asm__(OP " #2,@%0" : :"r"(b_addr) : "memory");   \
+			break;						   \
+		case 3:							   \
+			__asm__(OP " #3,@%0" : :"r"(b_addr) : "memory");   \
+			break;						   \
+		case 4:							   \
+			__asm__(OP " #4,@%0" : :"r"(b_addr) : "memory");   \
+			break;						   \
+		case 5:							   \
+			__asm__(OP " #5,@%0" : :"r"(b_addr) : "memory");   \
+			break;						   \
+		case 6:							   \
+			__asm__(OP " #6,@%0" : :"r"(b_addr) : "memory");   \
+			break;						   \
+		case 7:							   \
+			__asm__(OP " #7,@%0" : :"r"(b_addr) : "memory");   \
+			break;						   \
+		}							   \
+	}								   \
+	else								   \
+	{								   \
+		__asm__(OP " %w0,@%1" : :"r"(nr),"r"(b_addr) : "memory");  \
+	}								   \
+}
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+
+H8300_GEN_BITOP(set_bit, "bset");
+
+static __inline__ void _set_bit(int nr, const volatile void * addr)
+{
+	*(((volatile unsigned int *)addr)+(nr >> 5)) |=  (1 << (nr & 31));
+}
+
+H8300_GEN_BITOP(clear_bit, "bclr");
+  
+static __inline__ void _clear_bit(int nr, const volatile void * addr)
+{
+	*(((volatile unsigned int *)addr)+(nr >> 5)) &= ~(1 << (nr & 31));
+}
+
+H8300_GEN_BITOP(change_bit, "bnot");
+  
+static __inline__ void __change_bit(int nr, const volatile void * addr)
+{
+	*(((volatile unsigned int *)addr)+(nr >> 5)) ^=  (1 << (nr & 31));
+}
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+
+static __inline__ int test_bit(int nr, const volatile void * addr)
+{
+	return (*((volatile unsigned char *)addr + ((nr >> 3) ^ 3)) & (1UL << (nr & 7))) != 0;
+}
+
+#define __test_bit(nr, addr) test_bit((nr), (addr))
+
+#define H8300_GEN_TEST_BITOP_IMM_INT(OP,BIT)		 	           \
+	__asm__("stc ccr,%w1\n\t"                                           \
+		"orc #0x80,ccr\n\t"                                        \
+		"bld #" BIT ",@%3\n\t"                                     \
+		OP " #" BIT ",@%3\n\t"                                     \
+		"rotxl.l %0\n\t"                                           \
+		"ldc %w1,ccr"                                               \
+		: "=r"(retval),"=&r"(ccrsave)                              \
+		: "0" (retval),"r" (a)                                     \
+		: "memory");
+
+#define H8300_GEN_TEST_BITOP_IMM(OP,BIT)			           \
+	__asm__("bld #" BIT ",@%2\n\t"                                     \
+		OP " #" BIT ",@%2\n\t"                                     \
+		"rotxl.l %0\n\t"                                           \
+		: "=r"(retval)                                             \
+		: "0" (retval),"r" (a)                                     \
+		: "memory");
+
+#define H8300_GEN_TEST_BITOP_INT(FNNAME,OP)                                \
+static __inline__ int FNNAME(int nr, volatile void * addr)                 \
+{                                                                          \
+	int retval = 0;                                                    \
+        char ccrsave;                                                      \
+	volatile unsigned char *a;                                         \
+                                                                           \
+	a = (volatile unsigned char *)addr + ((nr >> 3) ^ 3);              \
+	if(__builtin_constant_p(nr) == 0) {                                \
+		__asm__("stc ccr,%w1\n\t"                                  \
+			"orc #0x80,ccr\n\t"                                \
+			"btst %w4,@%3\n\t"                                 \
+			OP " %w4,@%3\n\t"                                  \
+			"beq 1f\n\t"                                       \
+			"inc.l #1,%0\n"                                    \
+			"1:\n\t"                                           \
+			"ldc %w1,ccr"                                      \
+			: "=r"(retval),"=&r"(ccrsave)                      \
+			: "0" (retval),"r" (a),"r"(nr)                     \
+			: "memory");                                       \
+		return retval;                                             \
+	} else {                                                           \
+		switch(nr & 7) {                                           \
+		case 0:                                                    \
+			H8300_GEN_TEST_BITOP_IMM_INT(OP,"0");              \
+			break;                                             \
+		case 1:                                                    \
+			H8300_GEN_TEST_BITOP_IMM_INT(OP,"1");              \
+			break;                                             \
+		case 2:                                                    \
+			H8300_GEN_TEST_BITOP_IMM_INT(OP,"2");              \
+			break;                                             \
+		case 3:                                                    \
+			H8300_GEN_TEST_BITOP_IMM_INT(OP,"3");              \
+			break;                                             \
+		case 4:                                                    \
+			H8300_GEN_TEST_BITOP_IMM_INT(OP,"4");              \
+			break;                                             \
+		case 5:                                                    \
+			H8300_GEN_TEST_BITOP_IMM_INT(OP,"5");              \
+			break;                                             \
+		case 6:                                                    \
+			H8300_GEN_TEST_BITOP_IMM_INT(OP,"6");              \
+			break;                                             \
+		case 7:                                                    \
+			H8300_GEN_TEST_BITOP_IMM_INT(OP,"7");              \
+			break;                                             \
+		}                                                          \
+		return retval;                                             \
+	}                                                                  \
+}
+
+#define H8300_GEN_TEST_BITOP(FNNAME,OP)                                    \
+static __inline__  int FNNAME(int nr, volatile void * addr)                \
+{                                                                          \
+	int retval = 0;                                                    \
+	volatile unsigned char *a;                                         \
+                                                                           \
+	a = (volatile unsigned char *)addr + ((nr >> 3) ^ 3);              \
+	if(__builtin_constant_p(nr) == 0) {                                \
+		__asm__("btst %w3,@%2\n\t"                                 \
+			OP " %w3,@%2\n\t"                                  \
+			"beq 1f\n\t"                                       \
+			"inc.l #1,%0\n"                                    \
+			"1:\n\t"                                           \
+			: "=r"(retval)                                     \
+			: "0" (retval),"r" (a),"r"(nr)                     \
+			: "memory");                                       \
+		return retval;                                             \
+	} else {                                                           \
+		switch(nr & 7) {                                           \
+		case 0:                                                    \
+			H8300_GEN_TEST_BITOP_IMM(OP,"0");                  \
+			break;                                             \
+		case 1:                                                    \
+			H8300_GEN_TEST_BITOP_IMM(OP,"1");                  \
+			break;                                             \
+		case 2:                                                    \
+			H8300_GEN_TEST_BITOP_IMM(OP,"2");                  \
+			break;                                             \
+		case 3:                                                    \
+			H8300_GEN_TEST_BITOP_IMM(OP,"3");                  \
+			break;                                             \
+		case 4:                                                    \
+			H8300_GEN_TEST_BITOP_IMM(OP,"4");                  \
+			break;                                             \
+		case 5:                                                    \
+			H8300_GEN_TEST_BITOP_IMM(OP,"5");                  \
+			break;                                             \
+		case 6:                                                    \
+			H8300_GEN_TEST_BITOP_IMM(OP,"6");                  \
+			break;                                             \
+		case 7:                                                    \
+			H8300_GEN_TEST_BITOP_IMM(OP,"7");                  \
+			break;                                             \
+		}                                                          \
+		return retval;                                             \
+	}                                                                  \
+}
+
+H8300_GEN_TEST_BITOP_INT(test_and_set_bit,"bset")
+H8300_GEN_TEST_BITOP_INT(test_and_clear_bit,"bclr")
+H8300_GEN_TEST_BITOP_INT(test_and_change_bit,"bnot")
+H8300_GEN_TEST_BITOP    (__test_and_set_bit,"bset")
+H8300_GEN_TEST_BITOP    (__test_and_clear_bit,"bclr")
+H8300_GEN_TEST_BITOP    (__test_and_change_bit,"bnot")
+
+#define find_first_zero_bit(addr, size) \
+        find_next_zero_bit((addr), (size), 0)
+
+static __inline__ int find_next_zero_bit (void * addr, int size, int offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if (offset) {
+		tmp = *(p++);
+		tmp |= ~0UL >> (32-offset);
+		if (size < 32)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while (size & ~31UL) {
+		if (~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp |= ~0UL >> size;
+found_middle:
+	return result + ffz(tmp);
+}
+
+#define ffs(x) generic_ffs(x)
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+static __inline__ int ext2_set_bit(int nr, volatile void * addr)
+{
+	int		mask, retval;
+	unsigned long	flags;
+	volatile unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	save_and_cli(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR |= mask;
+	restore_flags(flags);
+	return retval;
+}
+
+static __inline__ int ext2_clear_bit(int nr, volatile void * addr)
+{
+	int		mask, retval;
+	unsigned long	flags;
+	volatile unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	save_and_cli(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR &= ~mask;
+	restore_flags(flags);
+	return retval;
+}
+
+static __inline__ int ext2_test_bit(int nr, const volatile void * addr)
+{
+	int			mask;
+	const volatile unsigned char	*ADDR = (const unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	return ((mask & *ADDR) != 0);
+}
+
+#define ext2_find_first_zero_bit(addr, size) \
+        ext2_find_next_zero_bit((addr), (size), 0)
+
+static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if(offset) {
+		/* We hold the little endian value in tmp, but then the
+		 * shift is illegal. So we could keep a big endian value
+		 * in tmp, like this:
+		 *
+		 * tmp = __swab32(*(p++));
+		 * tmp |= ~0UL >> (32-offset);
+		 *
+		 * but this would decrease preformance, so we change the
+		 * shift:
+		 */
+		tmp = *(p++);
+		tmp |= __swab32(~0UL >> (32-offset));
+		if(size < 32)
+			goto found_first;
+		if(~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while(size & ~31UL) {
+		if(~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if(!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	/* tmp is little endian, so we would have to swab the shift,
+	 * see above. But then we have to swab tmp below for ffz, so
+	 * we might as well do this here.
+	 */
+	return result + ffz(__swab32(tmp) | (~0UL << size));
+found_middle:
+	return result + ffz(__swab32(tmp));
+}
+
+/* Bitmap functions for the minix filesystem.  */
+#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr) set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+
+#endif /* __KERNEL__ */
+
+#endif /* _H8300_BITOPS_H */
diff -urN linux-2.4.29/include/asm-h8300/bootinfo.h linux-2.4.29-uc1/include/asm-h8300/bootinfo.h
--- linux-2.4.29/include/asm-h8300/bootinfo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/bootinfo.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,2 @@
+
+/* Nothing for h8300 */
diff -urN linux-2.4.29/include/asm-h8300/bugs.h linux-2.4.29-uc1/include/asm-h8300/bugs.h
--- linux-2.4.29/include/asm-h8300/bugs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/bugs.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,16 @@
+/*
+ *  include/asm-h8300/bugs.h
+ *
+ *  Copyright (C) 1994  Linus Torvalds
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *	void check_bugs(void);
+ */
+
+static void check_bugs(void)
+{
+}
diff -urN linux-2.4.29/include/asm-h8300/byteorder.h linux-2.4.29-uc1/include/asm-h8300/byteorder.h
--- linux-2.4.29/include/asm-h8300/byteorder.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/byteorder.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef _H8300_BYTEORDER_H
+#define _H8300_BYTEORDER_H
+
+#include <asm/types.h>
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#include <linux/byteorder/big_endian.h>
+
+#endif /* _H8300_BYTEORDER_H */
diff -urN linux-2.4.29/include/asm-h8300/cachectl.h linux-2.4.29-uc1/include/asm-h8300/cachectl.h
--- linux-2.4.29/include/asm-h8300/cachectl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/cachectl.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,14 @@
+#ifndef _H8300_CACHECTL_H
+#define _H8300_CACHECTL_H
+
+/* Definitions for the cacheflush system call.  */
+
+#define FLUSH_SCOPE_LINE    0	/* Flush a cache line */
+#define FLUSH_SCOPE_PAGE    0	/* Flush a page */
+#define FLUSH_SCOPE_ALL     0	/* Flush the whole cache -- superuser only */
+
+#define FLUSH_CACHE_DATA    0	/* Writeback and flush data cache */
+#define FLUSH_CACHE_INSN    0	/* Flush instruction cache */
+#define FLUSH_CACHE_BOTH    0	/* Flush both caches */
+
+#endif /* _H8300_CACHECTL_H */
diff -urN linux-2.4.29/include/asm-h8300/cache.h linux-2.4.29-uc1/include/asm-h8300/cache.h
--- linux-2.4.29/include/asm-h8300/cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/cache.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef __ARCH_H8300_CACHE_H
+#define __ARCH_H8300_CACHE_H
+
+/* bytes per L1 cache line */
+#define        L1_CACHE_BYTES  sizeof(long)
+
+/* m68k-elf-gcc  2.95.2 doesn't like these */
+
+#define __cacheline_aligned
+#define ____cacheline_aligned
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/checksum.h linux-2.4.29-uc1/include/asm-h8300/checksum.h
--- linux-2.4.29/include/asm-h8300/checksum.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/checksum.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,106 @@
+#ifndef _H8300_CHECKSUM_H
+#define _H8300_CHECKSUM_H
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
+
+
+/*
+ * the same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
+						int len, int sum, int *csum_err);
+
+#define csum_partial_copy_nocheck(src, dst, len, sum)	\
+	csum_partial_copy((src), (dst), (len), (sum))
+
+unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl);
+
+
+/*
+ *	Fold a partial checksum
+ *      Thanks Kazu Hirata
+ */
+
+static inline unsigned int csum_fold(unsigned int sum)
+{
+	__asm__("mov.l %0,er0\n\t"
+		"add.w e0,r0\n\t"
+		"xor.w e0,e0\n\t"
+		"rotxl.w e0\n\t"
+		"add.w e0,r0\n\t"
+		"sub.w e0,e0\n\t"
+		"mov.l er0,%0"
+		: "=r"(sum)
+		: "0"(sum)
+		: "er0");
+	return ~sum;
+}
+
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+
+static inline unsigned int
+csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
+		  unsigned short proto, unsigned int sum)
+{
+	__asm__ ("sub.l er0,er0\n\t"
+		 "add.l %2,%0\n\t"
+		 "addx	#0,r0l\n\t"
+		 "add.l	%3,%0\n\t"
+		 "addx	#0,r0l\n\t"
+		 "add.l %4,%0\n\t"
+		 "addx	#0,r0l\n\t"
+		 "add.l	er0,%0\n\t"
+		 "bcc	1f\n\t"
+		 "inc.l	#1,%0\n"
+		 "1:"
+		 : "=&r" (sum)
+		 : "0" (sum), "r" (daddr), "r" (saddr), "r" (len + proto)
+		 :"er0");
+	return sum;
+}
+
+static inline unsigned short int
+csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
+		  unsigned short proto, unsigned int sum)
+{
+	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+extern unsigned short ip_compute_csum(const unsigned char * buff, int len);
+
+#endif /* _H8300_CHECKSUM_H */
diff -urN linux-2.4.29/include/asm-h8300/current.h linux-2.4.29-uc1/include/asm-h8300/current.h
--- linux-2.4.29/include/asm-h8300/current.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/current.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,16 @@
+#ifndef _H8300_CURRENT_H
+#define _H8300_CURRENT_H
+/*
+ *	current.h
+ *	(C) Copyright 2000, Lineo, David McCullough <davidm@lineo.com>
+ *
+ *	rather than dedicate a register (as the m68k source does), we
+ *	just keep a global,  we should probably just change it all to be
+ *	current and lose _current_task.
+ */
+
+extern struct task_struct *_current_task;
+#define get_current()	_current_task
+#define current _current_task
+
+#endif /* _H8300_CURRENT_H */
diff -urN linux-2.4.29/include/asm-h8300/dbg.h linux-2.4.29-uc1/include/asm-h8300/dbg.h
--- linux-2.4.29/include/asm-h8300/dbg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/dbg.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,2 @@
+#define DEBUG 1
+#define	BREAK asm volatile ("trap #3")
diff -urN linux-2.4.29/include/asm-h8300/delay.h linux-2.4.29-uc1/include/asm-h8300/delay.h
--- linux-2.4.29/include/asm-h8300/delay.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/delay.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,40 @@
+#ifndef _H8300_DELAY_H
+#define _H8300_DELAY_H
+
+#include <asm/param.h>
+
+/*
+ * Copyright (C) 2002 Yoshinori Sato <ysato@sourceforge.jp>
+ *
+ * Delay routines, using a pre-computed "loops_per_second" value.
+ */
+
+extern __inline__ void __delay(unsigned long loops)
+{
+	__asm__ __volatile__ ("1:\n\t"
+			      "dec.l #1,%0\n\t"
+			      "bne 1b"
+			      :"=r"(loops):"0"(loops));
+}
+
+/*
+ * Use only for very small delays ( < 1 msec).  Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays.  This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)  
+ */
+
+extern unsigned long loops_per_jiffy;
+
+extern __inline__ void udelay(unsigned long usecs)
+{
+	usecs *= 4295;		/* 2**32 / 1000000 */
+	usecs /= (loops_per_jiffy*HZ);
+	if (usecs)
+		__delay(usecs);
+}
+
+#define ndelay(nsecs) udelay((nsecs) * 5)
+
+#endif /* _H8300_DELAY_H */
diff -urN linux-2.4.29/include/asm-h8300/div64.h linux-2.4.29-uc1/include/asm-h8300/div64.h
--- linux-2.4.29/include/asm-h8300/div64.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/div64.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-generic/div64.h>
diff -urN linux-2.4.29/include/asm-h8300/dma.h linux-2.4.29-uc1/include/asm-h8300/dma.h
--- linux-2.4.29/include/asm-h8300/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/dma.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,16 @@
+#ifndef _H8300_DMA_H
+#define _H8300_DMA_H 
+ 
+#include <linux/config.h>
+
+/*
+ * Set number of channels of DMA on ColdFire for different implementations.
+ */
+#define MAX_DMA_CHANNELS 0
+#define MAX_DMA_ADDRESS PAGE_OFFSET
+
+/* These are in kernel/dma.c: */
+extern int request_dma(unsigned int dmanr, const char *device_id);	/* reserve a DMA channel */
+extern void free_dma(unsigned int dmanr);	/* release it again */
+ 
+#endif /* _H8300_DMA_H */
diff -urN linux-2.4.29/include/asm-h8300/edosk2674/smsc.h linux-2.4.29-uc1/include/asm-h8300/edosk2674/smsc.h
--- linux-2.4.29/include/asm-h8300/edosk2674/smsc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/edosk2674/smsc.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,60 @@
+/* EDOSK-2674R SMSC Network Controler Target Depend impliments */
+
+#define SMSC_BASE 0xf80000
+#define SMSC_IRQ 16
+
+/* sorry quick hack */
+#if defined(outw)
+# undef outw
+#endif
+#define outw(d,a) edosk2674_smsc_outw(d,(volatile unsigned short *)(a))
+#if defined(inw)
+# undef inw
+#endif
+#define inw(a) edosk2674_smsc_inw((volatile unsigned short *)(a))
+#if defined(outsw)
+# undef outsw
+#endif
+#define outsw(a,p,l) edosk2674_smsc_outsw((volatile unsigned short *)(a),p,l)
+#if defined(insw)
+# undef insw
+#endif
+#define insw(a,p,l) edosk2674_smsc_insw((volatile unsigned short *)(a),p,l)
+
+static inline void edosk2674_smsc_outw(
+	unsigned short d,
+	volatile unsigned short *a
+	)
+{
+	*a = (d >> 8) | (d << 8);
+}
+
+static inline unsigned short edosk2674_smsc_inw(
+	volatile unsigned short *a
+	)
+{
+	unsigned short d;
+	d = *a;
+	return (d >> 8) | (d << 8);
+}
+
+static inline void edosk2674_smsc_outsw(
+	volatile unsigned short *a,
+	unsigned short *p,
+	unsigned long l
+	)
+{
+	for (; l != 0; --l, p++)
+		*a = *p;
+}
+
+static inline void edosk2674_smsc_insw(
+	volatile unsigned short *a,
+	unsigned short *p,
+	unsigned long l
+	)
+{
+	for (; l != 0; --l, p++)
+		*p = *a;
+}
+
diff -urN linux-2.4.29/include/asm-h8300/elf.h linux-2.4.29-uc1/include/asm-h8300/elf.h
--- linux-2.4.29/include/asm-h8300/elf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/elf.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,57 @@
+#ifndef __ASMH8300_ELF_H
+#define __ASMH8300_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <linux/config.h>
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_m68kfp_struct elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == EM_68K)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2MSB
+#define ELF_ARCH	EM_H8_300H
+
+#define ELF_PLAT_INIT(_r)	_r->er1 = 0
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	4096
+#endif
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#define ELF_ET_DYN_BASE         0xD0000000UL
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.  */
+
+#define ELF_PLATFORM  (NULL)
+
+#ifdef __KERNEL__
+#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX)
+#endif
diff -urN linux-2.4.29/include/asm-h8300/errno.h linux-2.4.29-uc1/include/asm-h8300/errno.h
--- linux-2.4.29/include/asm-h8300/errno.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/errno.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,132 @@
+#ifndef _H8300_ERRNO_H
+#define _H8300_ERRNO_H
+
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Arg list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	EDEADLK		35	/* Resource deadlock would occur */
+#define	ENAMETOOLONG	36	/* File name too long */
+#define	ENOLCK		37	/* No record locks available */
+#define	ENOSYS		38	/* Function not implemented */
+#define	ENOTEMPTY	39	/* Directory not empty */
+#define	ELOOP		40	/* Too many symbolic links encountered */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	ENOMSG		42	/* No message of desired type */
+#define	EIDRM		43	/* Identifier removed */
+#define	ECHRNG		44	/* Channel number out of range */
+#define	EL2NSYNC	45	/* Level 2 not synchronized */
+#define	EL3HLT		46	/* Level 3 halted */
+#define	EL3RST		47	/* Level 3 reset */
+#define	ELNRNG		48	/* Link number out of range */
+#define	EUNATCH		49	/* Protocol driver not attached */
+#define	ENOCSI		50	/* No CSI structure available */
+#define	EL2HLT		51	/* Level 2 halted */
+#define	EBADE		52	/* Invalid exchange */
+#define	EBADR		53	/* Invalid request descriptor */
+#define	EXFULL		54	/* Exchange full */
+#define	ENOANO		55	/* No anode */
+#define	EBADRQC		56	/* Invalid request code */
+#define	EBADSLT		57	/* Invalid slot */
+
+#define	EDEADLOCK	EDEADLK
+
+#define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
+#define	EMULTIHOP	72	/* Multihop attempted */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EBADMSG		74	/* Not a data message */
+#define	EOVERFLOW	75	/* Value too large for defined data type */
+#define	ENOTUNIQ	76	/* Name not unique on network */
+#define	EBADFD		77	/* File descriptor in bad state */
+#define	EREMCHG		78	/* Remote address changed */
+#define	ELIBACC		79	/* Can not access a needed shared library */
+#define	ELIBBAD		80	/* Accessing a corrupted shared library */
+#define	ELIBSCN		81	/* .lib section in a.out corrupted */
+#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	EILSEQ		84	/* Illegal byte sequence */
+#define	ERESTART	85	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUSERS		87	/* Too many users */
+#define	ENOTSOCK	88	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	89	/* Destination address required */
+#define	EMSGSIZE	90	/* Message too long */
+#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	92	/* Protocol not available */
+#define	EPROTONOSUPPORT	93	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
+#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	96	/* Protocol family not supported */
+#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
+#define	EADDRINUSE	98	/* Address already in use */
+#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
+#define	ENETDOWN	100	/* Network is down */
+#define	ENETUNREACH	101	/* Network is unreachable */
+#define	ENETRESET	102	/* Network dropped connection because of reset */
+#define	ECONNABORTED	103	/* Software caused connection abort */
+#define	ECONNRESET	104	/* Connection reset by peer */
+#define	ENOBUFS		105	/* No buffer space available */
+#define	EISCONN		106	/* Transport endpoint is already connected */
+#define	ENOTCONN	107	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
+#define	ETIMEDOUT	110	/* Connection timed out */
+#define	ECONNREFUSED	111	/* Connection refused */
+#define	EHOSTDOWN	112	/* Host is down */
+#define	EHOSTUNREACH	113	/* No route to host */
+#define	EALREADY	114	/* Operation already in progress */
+#define	EINPROGRESS	115	/* Operation now in progress */
+#define	ESTALE		116	/* Stale NFS file handle */
+#define	EUCLEAN		117	/* Structure needs cleaning */
+#define	ENOTNAM		118	/* Not a XENIX named type file */
+#define	ENAVAIL		119	/* No XENIX semaphores available */
+#define	EISNAM		120	/* Is a named type file */
+#define	EREMOTEIO	121	/* Remote I/O error */
+#define	EDQUOT		122	/* Quota exceeded */
+
+#define	ENOMEDIUM	123	/* No medium found */
+#define	EMEDIUMTYPE	124	/* Wrong medium type */
+
+#endif /* _H8300_ERRNO_H */
diff -urN linux-2.4.29/include/asm-h8300/fcntl.h linux-2.4.29-uc1/include/asm-h8300/fcntl.h
--- linux-2.4.29/include/asm-h8300/fcntl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/fcntl.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,86 @@
+#ifndef _H8300_FCNTL_H
+#define _H8300_FCNTL_H
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	  0003
+#define O_RDONLY	    00
+#define O_WRONLY	    01
+#define O_RDWR		    02
+#define O_CREAT		  0100	/* not fcntl */
+#define O_EXCL		  0200	/* not fcntl */
+#define O_NOCTTY	  0400	/* not fcntl */
+#define O_TRUNC		 01000	/* not fcntl */
+#define O_APPEND	 02000
+#define O_NONBLOCK	 04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC		010000
+#define FASYNC		020000	/* fcntl, for BSD compatibility */
+#define O_DIRECTORY	040000	/* must be a directory */
+#define O_NOFOLLOW	0100000	/* don't follow links */
+#define O_DIRECT	0200000	/* direct disk access hint - currently ignored */
+#define O_LARGEFILE	0400000
+
+#define F_DUPFD		0	/* dup */
+#define F_GETFD		1	/* get close_on_exec */
+#define F_SETFD		2	/* set/clear close_on_exec */
+#define F_GETFL		3	/* get file->f_flags */
+#define F_SETFL		4	/* set file->f_flags */
+#define F_GETLK		5
+#define F_SETLK		6
+#define F_SETLKW	7
+
+#define F_SETOWN	8	/*  for sockets. */
+#define F_GETOWN	9	/*  for sockets. */
+#define F_SETSIG	10	/*  for sockets. */
+#define F_GETSIG	11	/*  for sockets. */
+
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK		0
+#define F_WRLCK		1
+#define F_UNLCK		2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+/* for leases */
+#define F_INPROGRESS	16
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* or'd with one of the above to prevent
+				   blocking */
+#define LOCK_UN		8	/* remove lock */
+
+#define LOCK_MAND	32	/* This is a mandatory flock */
+#define LOCK_READ	64	/* ... Which allows concurrent read operations */
+#define LOCK_WRITE	128	/* ... Which allows concurrent write operations */
+#define LOCK_RW		192	/* ... Which allows concurrent read & write ops */
+
+struct flock {
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE	1024
+#endif /* _H8300_FCNTL_H */
diff -urN linux-2.4.29/include/asm-h8300/flat.h linux-2.4.29-uc1/include/asm-h8300/flat.h
--- linux-2.4.29/include/asm-h8300/flat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/flat.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,26 @@
+/*
+ * include/asm-h8300/flat.h -- uClinux flat-format executables
+ */
+
+#ifndef __H8300_FLAT_H__
+#define __H8300_FLAT_H__
+
+#define	flat_stack_align(sp)			/* nothing needed */
+#define	flat_argvp_envp_on_stack()		1
+#define	flat_old_ram_flag(flags)		1
+#define	flat_reloc_valid(reloc, size)		((reloc) <= (size))
+
+/*
+ * on the H8 a couple of the relocations have an instruction in the
+ * top byte.  As there can only be 24bits of address space,  we just
+ * always preserve that 8bits at the top,  when it isn't an instruction
+ * is is 0 (davidm@snapgear.com)
+ */
+
+#define	flat_get_relocate_addr(rel)		(rel)
+#define flat_get_addr_from_rp(rp, relval, flags) \
+      ((flags & FLAT_FLAG_GOTPIC) ? get_unaligned(rp) : get_unaligned(rp) & 0x00ffffff)
+#define flat_put_addr_at_rp(rp, addr, rel) \
+	put_unaligned (((*(char *)(rp)) << 24) | ((addr) & 0x00ffffff), rp)
+
+#endif /* __H8300_FLAT_H__ */
diff -urN linux-2.4.29/include/asm-h8300/fpu.h linux-2.4.29-uc1/include/asm-h8300/fpu.h
--- linux-2.4.29/include/asm-h8300/fpu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/fpu.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1 @@
+/* Nothing do */
diff -urN linux-2.4.29/include/asm-h8300/gpio.h linux-2.4.29-uc1/include/asm-h8300/gpio.h
--- linux-2.4.29/include/asm-h8300/gpio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/gpio.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,52 @@
+#ifndef _H8300_GPIO_H
+#define _H8300_GPIO_H
+
+#define H8300_GPIO_P1 0
+#define H8300_GPIO_P2 1
+#define H8300_GPIO_P3 2
+#define H8300_GPIO_P4 3
+#define H8300_GPIO_P5 4
+#define H8300_GPIO_P6 5
+#define H8300_GPIO_P7 6
+#define H8300_GPIO_P8 7
+#define H8300_GPIO_P9 8
+#define H8300_GPIO_PA 9
+#define H8300_GPIO_PB 10
+#define H8300_GPIO_PC 11
+#define H8300_GPIO_PD 12
+#define H8300_GPIO_PE 13
+#define H8300_GPIO_PF 14
+#define H8300_GPIO_PG 15
+#define H8300_GPIO_PH 16
+
+#define H8300_GPIO_B7 0x80
+#define H8300_GPIO_B6 0x40
+#define H8300_GPIO_B5 0x20
+#define H8300_GPIO_B4 0x10
+#define H8300_GPIO_B3 0x08
+#define H8300_GPIO_B2 0x04
+#define H8300_GPIO_B1 0x02
+#define H8300_GPIO_B0 0x01
+
+#define H8300_GPIO_INPUT 0
+#define H8300_GPIO_OUTPUT 1
+
+#define H8300_GPIO_RESERVE(port, bits) \
+        h8300_reserved_gpio(port, bits)
+
+#define H8300_GPIO_FREE(port, bits) \
+        h8300_free_gpio(port, bits)
+
+#define H8300_GPIO_DDR(port, bit, dir) \
+        h8300_set_gpio_dir(((port) << 8) | (bit), dir)
+
+#define H8300_GPIO_GETDIR(port, bit) \
+        h8300_get_gpio_dir(((port) << 8) | (bit))
+
+extern int h8300_reserved_gpio(int port, int bits);
+extern int h8300_free_gpio(int port, int bits);
+extern int h8300_set_gpio_dir(int port_bit, int dir);
+extern int h8300_get_gpio_dir(int port_bit);
+extern int h8300_init_gpio(void);
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/h8300_ne.h linux-2.4.29-uc1/include/asm-h8300/h8300_ne.h
--- linux-2.4.29/include/asm-h8300/h8300_ne.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/h8300_ne.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,19 @@
+/****************************************************************************/
+
+/*
+ *	h8300_ne.h -- NE2000 in H8/300H Evalution Board.
+ *      
+ *	(C) Copyright 2002, Yoshinori Sato <ysato@users.sourceforge.jp>
+ */
+
+/****************************************************************************/
+#ifndef	h8300ne_h
+#define	h8300ne_h
+/****************************************************************************/
+
+/* Such a description is OK ? */
+#define DEPEND_HEADER(target) <asm/target/ne.h> 
+#include DEPEND_HEADER(TARGET)
+
+/****************************************************************************/
+#endif	/* h8300ne_h */
diff -urN linux-2.4.29/include/asm-h8300/h8300_smsc.h linux-2.4.29-uc1/include/asm-h8300/h8300_smsc.h
--- linux-2.4.29/include/asm-h8300/h8300_smsc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/h8300_smsc.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,19 @@
+/****************************************************************************/
+
+/*
+ *	h8300_smsc.h -- SMSC in H8/300H and H8S Evalution Board.
+ *      
+ *	(C) Copyright 2003, Yoshinori Sato <ysato@users.sourceforge.jp>
+ */
+
+/****************************************************************************/
+#ifndef	h8300smsc_h
+#define	h8300smsc_h
+/****************************************************************************/
+
+/* Such a description is OK ? */
+#define DEPEND_HEADER(target) <asm/target/smsc.h> 
+#include DEPEND_HEADER(TARGET)
+
+/****************************************************************************/
+#endif	/* h8300smsc_h */
diff -urN linux-2.4.29/include/asm-h8300/h8max/ne.h linux-2.4.29-uc1/include/asm-h8300/h8max/ne.h
--- linux-2.4.29/include/asm-h8300/h8max/ne.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/h8max/ne.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,71 @@
+/* H8MAX RTL8019AS Config */
+
+#define NE2000_ADDR		0x800600
+#define NE2000_IRQ              4
+#define NE2000_IRQ_VECTOR	(12 + NE2000_IRQ)
+#define	NE2000_BYTE		volatile unsigned short
+
+#define IER                     0xfee015
+#define ISR			0xfee016
+#define IRQ_MASK		(1 << NE2000_IRQ)
+/* sorry quick hack */
+#if defined(outb)
+# undef outb
+#endif
+#define outb(d,a)               h8max_outb((d),(a) - NE2000_ADDR)
+#if defined(inb)
+# undef inb
+#endif
+#define inb(a)                  h8max_inb((a) - NE2000_ADDR)
+#if defined(outb_p)
+# undef outb_p
+#endif
+#define outb_p(d,a)             h8max_outb((d),(a) - NE2000_ADDR)
+#if defined(inb_p)
+# undef inb_p
+#endif
+#define inb_p(a)                h8max_inb((a) - NE2000_ADDR)
+#if defined(outsw)
+# undef outsw
+#endif
+#define outsw(a,p,l)            h8max_outsw((a) - NE2000_ADDR,(unsigned short *)p,l)
+#if defined(insw)
+# undef insw
+#endif
+#define insw(a,p,l)             h8max_insw((a) - NE2000_ADDR,(unsigned short *)p,l)
+
+#define H8300_INIT_NE()                  \
+do {                                     \
+	wordlength = 2;                  \
+	h8max_outb(0x49, ioaddr + EN0_DCFG); \
+	SA_prom[14] = SA_prom[15] = 0x57;\
+} while(0)
+
+static inline void h8max_outb(unsigned char d,unsigned char a)
+{
+	*(unsigned short *)(NE2000_ADDR + (a << 1)) = d;
+}
+
+static inline unsigned char h8max_inb(unsigned char a)
+{
+	return *(unsigned char *)(NE2000_ADDR + (a << 1) +1);
+}
+
+static inline void h8max_outsw(unsigned char a,unsigned short *p,unsigned long l)
+{
+	unsigned short d;
+	for (; l != 0; --l, p++) {
+		d = (((*p) >> 8) & 0xff) | ((*p) << 8);
+		*(unsigned short *)(NE2000_ADDR + (a << 1)) = d;
+	}
+}
+
+static inline void h8max_insw(unsigned char a,unsigned short *p,unsigned long l)
+{
+	unsigned short d;
+	for (; l != 0; --l, p++) {
+		d = *(unsigned short *)(NE2000_ADDR + (a << 1));
+		*p = (d << 8)|((d >> 8) & 0xff);
+	}
+}
+
diff -urN linux-2.4.29/include/asm-h8300/hardirq.h linux-2.4.29-uc1/include/asm-h8300/hardirq.h
--- linux-2.4.29/include/asm-h8300/hardirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/hardirq.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,41 @@
+#ifndef __H8300_HARDIRQ_H
+#define __H8300_HARDIRQ_H
+
+#include <linux/config.h>
+#include <linux/threads.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned int __local_irq_count;
+	unsigned int __local_bh_count;
+	unsigned int __syscall_count;
+	struct task_struct * __ksoftirqd_task;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt() (local_irq_count(smp_processor_id()) + local_bh_count(smp_processor_id()) != 0)
+
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
+
+#ifndef CONFIG_SMP
+
+#define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
+#define hardirq_endlock(cpu)	do { } while (0)
+
+#define irq_enter(cpu, irq)	(local_irq_count(cpu)++)
+#define irq_exit(cpu, irq)	(local_irq_count(cpu)--)
+
+#define synchronize_irq()	barrier()
+
+#else
+
+#error h8300 SMP is not available
+
+#endif /* CONFIG_SMP */
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/hdreg.h linux-2.4.29-uc1/include/asm-h8300/hdreg.h
--- linux-2.4.29/include/asm-h8300/hdreg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/hdreg.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ *  linux/include/asm-h8300/hdreg.h
+ *
+ *  Copyright (C) 1994-1996  Linus Torvalds & authors
+ */
+
+#ifndef _H8300_HDREG_H
+#define _H8300_HDREG_H
+
+typedef unsigned long ide_ioreg_t;
+
+#endif /* _H8300_HDREG_H */
diff -urN linux-2.4.29/include/asm-h8300/hw_irq.h linux-2.4.29-uc1/include/asm-h8300/hw_irq.h
--- linux-2.4.29/include/asm-h8300/hw_irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/hw_irq.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1 @@
+/* Do Nothing */
diff -urN linux-2.4.29/include/asm-h8300/ide.h linux-2.4.29-uc1/include/asm-h8300/ide.h
--- linux-2.4.29/include/asm-h8300/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/ide.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,43 @@
+/****************************************************************************/
+
+/*
+ *  linux/include/asm-h8300/ide.h
+ *
+ *  Copyright (C) 1994-1996  Linus Torvalds & authors
+ *  Copyright (C) 2001       Lineo Inc., davidm@snapgear.com
+ *  Copyright (C) 2002       Greg Ungerer (gerg@snapgear.com)
+ *  Copyright (C) 2002       Yoshinori Sato (ysato@users.sourceforge.jp)
+ */
+
+/****************************************************************************/
+#ifndef _H8300_IDE_H
+#define _H8300_IDE_H
+/****************************************************************************/
+#ifdef __KERNEL__
+/****************************************************************************/
+
+void ide_print_resource(char *name, hw_regs_t *hw);
+static inline int ide_default_irq(ide_ioreg_t base) { return 0; };
+static inline ide_ioreg_t ide_default_io_base(int index) { return 0; };
+
+static inline void ide_init_hwif_ports(hw_regs_t *hw,	ide_ioreg_t data_port,
+ 	                               ide_ioreg_t ctrl_port, int *irq)
+{
+}
+
+
+static inline void ide_init_default_hwifs(void)
+{
+}
+
+#define MAX_HWIFS	1
+
+#define __ide_mm_insw(port,addr,count)  do { } while(0)
+#define __ide_mm_insl(port,addr,count)  do { } while(0)
+#define __ide_mm_outsw(port,addr,count) do { } while(0)
+#define __ide_mm_outsl(port,addr,count) do { } while(0)
+
+/****************************************************************************/
+#endif /* __KERNEL__ */
+#endif /* _H8300_IDE_H */
+/****************************************************************************/
diff -urN linux-2.4.29/include/asm-h8300/init.h linux-2.4.29-uc1/include/asm-h8300/init.h
--- linux-2.4.29/include/asm-h8300/init.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/init.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,11 @@
+#ifndef _H8300_INIT_H
+#define _H8300_INIT_H
+
+#define __init __attribute__ ((__section__ (".text.init")))
+#define __initdata __attribute__ ((__section__ (".data.init")))
+/* For assembly routines */
+#define __INIT		.section	".text.init",#alloc,#execinstr
+#define __FINIT		.previous
+#define __INITDATA	.section	".data.init",#alloc,#write
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/ioctl.h linux-2.4.29-uc1/include/asm-h8300/ioctl.h
--- linux-2.4.29/include/asm-h8300/ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/ioctl.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,79 @@
+/*
+ * linux/ioctl.h for Linux by H.H. Bergman.
+ */
+
+#ifndef _H8300_IOCTL_H
+#define _H8300_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * I don't really have any idea about what this should look like, so
+ * for the time being, this is heavily based on the PC definitions.
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	14
+#define _IOC_DIRBITS	2
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE	0U
+#define _IOC_WRITE	1U
+#define _IOC_READ	2U
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* _H8300_IOCTL_H */
diff -urN linux-2.4.29/include/asm-h8300/ioctls.h linux-2.4.29-uc1/include/asm-h8300/ioctls.h
--- linux-2.4.29/include/asm-h8300/ioctls.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/ioctls.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,82 @@
+#ifndef __ARCH_H8300_IOCTLS_H__
+#define __ARCH_H8300_IOCTLS_H__
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+#define TIOCSBRK	0x5427  /* BSD compatibility */
+#define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define FIONCLEX	0x5450  /* these numbers need to be adjusted. */
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+
+#define	FIOQSIZE	0x545E
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+#endif /* __ARCH_H8300_IOCTLS_H__ */
diff -urN linux-2.4.29/include/asm-h8300/io.h linux-2.4.29-uc1/include/asm-h8300/io.h
--- linux-2.4.29/include/asm-h8300/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/io.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,220 @@
+#ifndef _H8300_IO_H
+#define _H8300_IO_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <asm/virtconvert.h>
+
+/*
+ * These are for ISA/PCI shared memory _only_ and should never be used
+ * on any other type of memory, including Zorro memory. They are meant to
+ * access the bus in the bus byte order which is little-endian!.
+ *
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the m68k architecture, we just read/write the
+ * memory location directly.
+ */
+/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
+ * two accesses to memory, which may be undesireable for some devices.
+ */
+
+/*
+ * swap functions are sometimes needed to interface little-endian hardware
+ */
+
+/*
+ * CHANGES
+ * 
+ * 020325   Added some #define's for the COBRA5272 board
+ *          (hede)
+ */
+static inline unsigned short _swapw(volatile unsigned short v)
+{
+	unsigned short r;
+	__asm__("mov.b %w1,r1h\n\t"
+		"mov.b %x1,r1l\n\t"
+		"mov.w r1,%0"
+		:"=r"(r)
+		:"r"(v)
+		:"er1");
+	return r;
+}
+
+static inline unsigned int _swapl(volatile unsigned long v)
+{
+	unsigned int r;
+	__asm__("mov.b %w1,r1h\n\t"
+		"mov.b %x1,r1l\n\t"
+		"mov.w r1,%e0\n\t"
+		"mov.w %e1,r1\n\t"
+		"mov.b r1l,%x0\n\t"
+		"mov.b r1h,%w0"
+		:"=r"(r)
+		:"r"(v)
+		:"er1");
+	return r;
+}
+
+#define readb(addr) \
+    ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
+#define readw(addr) \
+    ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
+#define readl(addr) \
+    ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
+
+#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
+
+static inline void io_outsb(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned char *ap = (volatile unsigned char *) addr;
+	unsigned char *bp = (unsigned char *) buf;
+	while (len--)
+		*ap = *bp++;
+}
+
+static inline void io_outsw(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned short *ap = (volatile unsigned short *) addr;
+	unsigned short *bp = (unsigned short *) buf;
+	while (len--)
+		*ap = _swapw(*bp++);
+}
+
+static inline void io_outsl(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned int *ap = (volatile unsigned int *) addr;
+	unsigned int *bp = (unsigned int *) buf;
+	while (len--)
+		*ap = _swapl(*bp++);
+}
+
+static inline void io_insb(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned char *ap = (volatile unsigned char *) addr;
+	unsigned char *bp = (unsigned char *) buf;
+	while (len--)
+		*bp++ = *ap;
+}
+
+static inline void io_insw(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned short *ap = (volatile unsigned short *) addr;
+	unsigned short *bp = (unsigned short *) buf;
+	while (len--)
+		*bp++ = _swapw(*ap);
+}
+
+static inline void io_insl(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned int *ap = (volatile unsigned int *) addr;
+	unsigned int *bp = (unsigned int *) buf;
+	while (len--)
+		*bp++ = _swapl(*ap);
+}
+
+/*
+ *	make the short names macros so specific devices
+ *	can override them as required
+ */
+
+#define memset_io(a,b,c)	memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
+
+#define inb(addr)      readb(addr)
+#define inw(addr)    readw(addr)
+#define inl(addr)    readl(addr)
+#define outb(x,addr) ((void) writeb(x,addr))
+#define outw(x,addr) ((void) writew(x,addr))
+#define outl(x,addr) ((void) writel(x,addr))
+
+#define inb_p(addr)    inb(addr)
+#define inw_p(addr)    inw(addr)
+#define inl_p(addr)    inl(addr)
+#define outb_p(x,addr) outb(x,addr)
+#define outw_p(x,addr) outw(x,addr)
+#define outl_p(x,addr) outl(x,addr)
+
+#define outsb(a,b,l) io_outsb(a,b,l)
+#define outsw(a,b,l) io_outsw(a,b,l)
+#define outsl(a,b,l) io_outsl(a,b,l)
+
+#define insb(a,b,l) io_insb(a,b,l)
+#define insw(a,b,l) io_insw(a,b,l)
+#define insl(a,b,l) io_insl(a,b,l)
+
+#define IO_SPACE_LIMIT 0xffffff
+
+
+/* Values for nocacheflag and cmode */
+#define IOMAP_FULL_CACHING		0
+#define IOMAP_NOCACHE_SER		1
+#define IOMAP_NOCACHE_NONSER		2
+#define IOMAP_WRITETHROUGH		3
+
+extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
+extern void __iounmap(void *addr, unsigned long size);
+
+extern inline void *ioremap(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+extern inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+extern inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
+}
+extern inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
+}
+
+extern void iounmap(void *addr);
+
+/* Nothing to do */
+
+#define dma_cache_inv(_start,_size)		do { } while (0)
+#define dma_cache_wback(_start,_size)		do { } while (0)
+#define dma_cache_wback_inv(_start,_size)	do { } while (0)
+
+/* H8/300 internal I/O functions */
+static __inline__ unsigned char ctrl_inb(unsigned long addr)
+{
+	return *(volatile unsigned char*)addr;
+}
+
+static __inline__ unsigned short ctrl_inw(unsigned long addr)
+{
+	return *(volatile unsigned short*)addr;
+}
+
+static __inline__ unsigned int ctrl_inl(unsigned long addr)
+{
+	return *(volatile unsigned long*)addr;
+}
+
+static __inline__ void ctrl_outb(unsigned char b, unsigned long addr)
+{
+	*(volatile unsigned char*)addr = b;
+}
+
+static __inline__ void ctrl_outw(unsigned short b, unsigned long addr)
+{
+	*(volatile unsigned short*)addr = b;
+}
+
+static __inline__ void ctrl_outl(unsigned int b, unsigned long addr)
+{
+        *(volatile unsigned long*)addr = b;
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _H8300_IO_H */
diff -urN linux-2.4.29/include/asm-h8300/ipcbuf.h linux-2.4.29-uc1/include/asm-h8300/ipcbuf.h
--- linux-2.4.29/include/asm-h8300/ipcbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/ipcbuf.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,29 @@
+#ifndef __H8300_IPCBUF_H__
+#define __H8300_IPCBUF_H__
+
+/*
+ * The user_ipc_perm structure for H8/300 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
+	__kernel_mode_t		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* __H8300_IPCBUF_H__ */
diff -urN linux-2.4.29/include/asm-h8300/ipc.h linux-2.4.29-uc1/include/asm-h8300/ipc.h
--- linux-2.4.29/include/asm-h8300/ipc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/ipc.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef __H8300_IPC_H__
+#define __H8300_IPC_H__
+
+/* 
+ * These are used to wrap system calls on H8/300.
+ *
+ * See arch/h8300/kernel/sys_h8300.c for ugly details..
+ */
+struct ipc_kludge {
+	struct msgbuf *msgp;
+	long msgtyp;
+};
+
+#define SEMOP		 1
+#define SEMGET		 2
+#define SEMCTL		 3
+#define MSGSND		11
+#define MSGRCV		12
+#define MSGGET		13
+#define MSGCTL		14
+#define SHMAT		21
+#define SHMDT		22
+#define SHMGET		23
+#define SHMCTL		24
+
+/* Used by the DIPC package, try and avoid reusing it */
+#define DIPC		25
+
+#define IPCCALL(version,op)	((version)<<16 | (op))
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/irq.h linux-2.4.29-uc1/include/asm-h8300/irq.h
--- linux-2.4.29/include/asm-h8300/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/irq.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,97 @@
+#ifndef _H8300_IRQ_H_
+#define _H8300_IRQ_H_
+
+#if defined(__H8300H__)
+#define NR_IRQS 64
+#define EXT_IRQ0 12
+#define EXT_IRQ1 13
+#define EXT_IRQ2 14
+#define EXT_IRQ3 15
+#define EXT_IRQ4 16
+#define EXT_IRQ5 17
+#define EXT_IRQ6 18
+#define EXT_IRQ7 19
+#define EXT_IRQS 5
+
+#include <asm/regs306x.h>
+#define h8300_clear_isr(irq)                                                \
+do {                                                                        \
+	if (irq >= EXT_IRQ0 && irq <= EXT_IRQ5)                             \
+		*(volatile unsigned char *)ISR &= ~(1 << (irq - EXT_IRQ0)); \
+} while(0)
+
+#define IER_REGS *(volatile unsigned char *)IER
+#endif
+#if defined(__H8300S__)
+#define NR_IRQS 128
+#define EXT_IRQ0 16
+#define EXT_IRQ1 17
+#define EXT_IRQ2 18
+#define EXT_IRQ3 19
+#define EXT_IRQ4 20
+#define EXT_IRQ5 21
+#define EXT_IRQ6 22
+#define EXT_IRQ7 23
+#define EXT_IRQ8 24
+#define EXT_IRQ9 25
+#define EXT_IRQ10 26
+#define EXT_IRQ11 27
+#define EXT_IRQ12 28
+#define EXT_IRQ13 29
+#define EXT_IRQ14 30
+#define EXT_IRQ15 31
+#define EXT_IRQS  15
+
+#include <asm/regs267x.h>
+#define h8300_clear_isr(irq)                                                 \
+do {                                                                         \
+	if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15)                             \
+		*(volatile unsigned short *)ISR &= ~(1 << (irq - EXT_IRQ0)); \
+} while(0)
+
+#define IER_REGS *(volatile unsigned short *)IER
+#endif
+
+/*
+ * "Generic" interrupt sources
+ */
+
+static __inline__ int irq_cannonicalize(int irq)
+{
+	return irq;
+}
+
+extern void enable_irq(unsigned int);
+extern void disable_irq(unsigned int);
+
+extern int sys_request_irq(unsigned int, 
+	void (*)(int, void *, struct pt_regs *), 
+	unsigned long, const char *, void *);
+extern void sys_free_irq(unsigned int, void *);
+
+typedef struct irq_node {
+	void		(*handler)(int, void *, struct pt_regs *);
+	unsigned long	flags;
+	void		*dev_id;
+	const char	*devname;
+	struct irq_node *next;
+} irq_node_t;
+
+/*
+ * This structure has only 4 elements for speed reasons
+ */
+typedef struct irq_handler {
+	void (*handler)(int, void *, struct pt_regs *);
+	int         flags;
+	int         count;
+	void	    *dev_id;
+	const char  *devname;
+} irq_handler_t;
+
+/*
+ * Some drivers want these entry points
+ */
+#define enable_irq_nosync(x)	enable_irq(x)
+#define disable_irq_nosync(x)	disable_irq(x)
+
+#endif /* _H8300_IRQ_H_ */
diff -urN linux-2.4.29/include/asm-h8300/keyboard.h linux-2.4.29-uc1/include/asm-h8300/keyboard.h
--- linux-2.4.29/include/asm-h8300/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/keyboard.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ *  linux/include/asm-h8300/keyboard.h
+ *  Created 04 Dec 2001 by Khaled Hassounah <khassounah@mediumware.net>
+ *  This file contains the Dragonball architecture specific keyboard definitions
+ */
+
+#ifndef _H8300_KEYBOARD_H
+#define _H8300_KEYBOARD_H
+
+#include <linux/config.h>
+
+/* dummy i.e. no real keyboard */
+#define kbd_setkeycode(x...)	(-ENOSYS)
+#define kbd_getkeycode(x...)	(-ENOSYS)
+#define kbd_translate(x...)	(0)
+#define kbd_unexpected_up(x...)	(1)
+#define kbd_leds(x...)		do {;} while (0)
+#define kbd_init_hw(x...)	do {;} while (0)
+#define kbd_enable_irq(x...)	do {;} while (0)
+#define kbd_disable_irq(x...)	do {;} while (0)
+
+
+/* needed if MAGIC_SYSRQ is enabled for serial console */
+#ifndef SYSRQ_KEY
+#define SYSRQ_KEY		((unsigned char)(-1))
+#define kbd_sysrq_xlate         ((unsigned char *)NULL)
+#endif
+
+
+#endif  /* _H8300_KEYBOARD_H */
+
+
+
diff -urN linux-2.4.29/include/asm-h8300/linkage.h linux-2.4.29-uc1/include/asm-h8300/linkage.h
--- linux-2.4.29/include/asm-h8300/linkage.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/linkage.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,9 @@
+#ifndef _H8300_LINKAGE_H
+#define _H8300_LINKAGE_H
+
+#undef SYMBOL_NAME_LABEL
+#undef SYMBOL_NAME
+#define SYMBOL_NAME_LABEL(_name_) _##_name_##:
+#define SYMBOL_NAME(_name_) _##_name_
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/linux_logo.h linux-2.4.29-uc1/include/asm-h8300/linux_logo.h
--- linux-2.4.29/include/asm-h8300/linux_logo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/linux_logo.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,11 @@
+/*
+ * include/asm-h8300/linux_logo.h: This is a linux logo
+ *                                 to be displayed on boot.
+ */
+ 
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/version.h>
+
+#define linux_logo_banner "Linux/m68knommu version " UTS_RELEASE
+
diff -urN linux-2.4.29/include/asm-h8300/mc146818rtc.h linux-2.4.29-uc1/include/asm-h8300/mc146818rtc.h
--- linux-2.4.29/include/asm-h8300/mc146818rtc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/mc146818rtc.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,9 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _H8300_MC146818RTC_H
+#define _H8300_MC146818RTC_H
+
+/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */
+
+#endif /* _H8300_MC146818RTC_H */
diff -urN linux-2.4.29/include/asm-h8300/md.h linux-2.4.29-uc1/include/asm-h8300/md.h
--- linux-2.4.29/include/asm-h8300/md.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/md.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * md.h: High speed xor_block operation for RAID4/5 
+ */
+ 
+#ifndef __ASM_MD_H
+#define __ASM_MD_H
+
+/* #define HAVE_ARCH_XORBLOCK */
+
+#define MD_XORBLOCK_ALIGNMENT	sizeof(long)
+
+#endif /* __ASM_MD_H */
diff -urN linux-2.4.29/include/asm-h8300/mman.h linux-2.4.29-uc1/include/asm-h8300/mman.h
--- linux-2.4.29/include/asm-h8300/mman.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/mman.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,38 @@
+#ifndef __H8300_MMAN_H__
+#define __H8300_MMAN_H__
+
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_NONE	0x0		/* page can not be accessed */
+
+#define MAP_SHARED	0x01		/* Share changes */
+#define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_TYPE	0x0f		/* Mask for type of mapping */
+#define MAP_FIXED	0x10		/* Interpret addr exactly */
+#define MAP_ANONYMOUS	0x20		/* don't use a file */
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
+#define MAP_LOCKED	0x2000		/* pages are locked */
+#define MAP_NORESERVE	0x4000		/* don't check for reservations */
+
+#define MS_ASYNC	1		/* sync memory asynchronously */
+#define MS_INVALIDATE	2		/* invalidate the caches */
+#define MS_SYNC		4		/* synchronous memory sync */
+
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
+
+#define MADV_NORMAL	0x0		/* default page-in behavior */
+#define MADV_RANDOM	0x1		/* page-in minimum required */
+#define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
+#define MADV_WILLNEED	0x3		/* pre-fault pages */
+#define MADV_DONTNEED	0x4		/* discard these pages */
+
+/* compatibility flags */
+#define MAP_ANON	MAP_ANONYMOUS
+#define MAP_FILE	0
+
+#endif /* __H8300_MMAN_H__ */
diff -urN linux-2.4.29/include/asm-h8300/mmu_context.h linux-2.4.29-uc1/include/asm-h8300/mmu_context.h
--- linux-2.4.29/include/asm-h8300/mmu_context.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/mmu_context.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef __H8300_MMU_CONTEXT_H
+#define __H8300_MMU_CONTEXT_H
+
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
+{
+}
+
+extern inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	// mm->context = virt_to_phys(mm->pgd);
+	return(0);
+}
+
+#define destroy_context(mm)		do { } while(0)
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu)
+{
+}
+
+extern inline void activate_mm(struct mm_struct *prev_mm,
+			       struct mm_struct *next_mm)
+{
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/mmu.h linux-2.4.29-uc1/include/asm-h8300/mmu.h
--- linux-2.4.29/include/asm-h8300/mmu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/mmu.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,7 @@
+#ifndef __MMU_H
+#define __MMU_H
+
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_t;
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/module.h linux-2.4.29-uc1/include/asm-h8300/module.h
--- linux-2.4.29/include/asm-h8300/module.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/module.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef _ASM_H8300_MODULE_H
+#define _ASM_H8300_MODULE_H
+/*
+ * This file contains the H8/300 architecture specific module code.
+ */
+
+#define module_map(x)		vmalloc(x)
+#define module_unmap(x)		vfree(x)
+#define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
+
+#endif /* _ASM_H8/300_MODULE_H */
diff -urN linux-2.4.29/include/asm-h8300/msgbuf.h linux-2.4.29-uc1/include/asm-h8300/msgbuf.h
--- linux-2.4.29/include/asm-h8300/msgbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/msgbuf.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef _H8300_MSGBUF_H
+#define _H8300_MSGBUF_H
+
+/* 
+ * The msqid64_ds structure for H8/300 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm msg_perm;
+	__kernel_time_t msg_stime;	/* last msgsnd time */
+	unsigned long	__unused1;
+	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	unsigned long	__unused2;
+	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned long	__unused3;
+	unsigned long  msg_cbytes;	/* current number of bytes on queue */
+	unsigned long  msg_qnum;	/* number of messages in queue */
+	unsigned long  msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t msg_lrpid;	/* last receive pid */
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+#endif /* _H8300_MSGBUF_H */
diff -urN linux-2.4.29/include/asm-h8300/namei.h linux-2.4.29-uc1/include/asm-h8300/namei.h
--- linux-2.4.29/include/asm-h8300/namei.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/namei.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-h8300/namei.h
+ *
+ * Included from linux/fs/namei.c
+ */
+
+#ifndef __H8300_NAMEI_H
+#define __H8300_NAMEI_H
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+
+#define __emul_prefix() NULL
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/page.h linux-2.4.29-uc1/include/asm-h8300/page.h
--- linux-2.4.29/include/asm-h8300/page.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/page.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,109 @@
+#ifndef _H8300NOMMU_PAGE_H
+#define _H8300NOMMU_PAGE_H
+
+#include <linux/config.h>
+
+/* PAGE_SHIFT determines the page size */
+
+#define PAGE_SHIFT	(12)
+#define PAGE_SIZE	(4096)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+
+#ifdef __KERNEL__
+
+#include <asm/setup.h>
+
+#if !defined(CONFIG_SMALL_TASKS) && PAGE_SHIFT < 13
+#define KTHREAD_SIZE (8192)
+#else
+#define KTHREAD_SIZE PAGE_SIZE
+#endif
+ 
+#ifndef __ASSEMBLY__
+ 
+#define get_user_page(vaddr)		__get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr)	free_page(addr)
+
+#define clear_page(page)	memset((page), 0, PAGE_SIZE)
+#define copy_page(to,from)	memcpy((to), (from), PAGE_SIZE)
+
+#define clear_user_page(page, vaddr)	clear_page(page)
+#define copy_user_page(to, from, vaddr)	copy_page(to, from)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pmd[16]; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)	((x).pte)
+#define pmd_val(x)	((&x)->pmd[0])
+#define pgd_val(x)	((x).pgd)
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x)	((pte_t) { (x) } )
+#define __pmd(x)	((pmd_t) { (x) } )
+#define __pgd(x)	((pgd_t) { (x) } )
+#define __pgprot(x)	((pgprot_t) { (x) } )
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+/* Pure 2^n version of get_order */
+extern __inline__ int get_order(unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#include <asm/page_offset.h>
+
+#define PAGE_OFFSET		(PAGE_OFFSET_RAW)
+
+#ifndef __ASSEMBLY__
+
+#define __pa(vaddr)		virt_to_phys((void *)vaddr)
+#define __va(paddr)		phys_to_virt((unsigned long)paddr)
+
+#define MAP_NR(addr)		(((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
+#define virt_to_page(addr)	(mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
+#define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
+
+
+#ifdef CONFIG_NO_KERNEL_MSG
+#define	BUG_PRINT()
+#else
+#define	BUG_PRINT() printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__)
+#endif
+
+
+// #define BUG_PANIC()	asm volatile ("halt") /* drop to debugger */
+// #define BUG_PANIC()	while(1)
+#define BUG_PANIC()	panic("BUG!")
+
+
+#define BUG() do { \
+	BUG_PRINT(); \
+	BUG_PANIC(); \
+} while (0)
+
+#define PAGE_BUG(page) do { \
+	BUG(); \
+} while (0)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _H8300NOMMU_PAGE_H */
diff -urN linux-2.4.29/include/asm-h8300/page_offset.h linux-2.4.29-uc1/include/asm-h8300/page_offset.h
--- linux-2.4.29/include/asm-h8300/page_offset.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/page_offset.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,4 @@
+
+#include <linux/config.h>
+#define PAGE_OFFSET_RAW		0x00000000
+
diff -urN linux-2.4.29/include/asm-h8300/param.h linux-2.4.29-uc1/include/asm-h8300/param.h
--- linux-2.4.29/include/asm-h8300/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/param.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,26 @@
+#ifndef _H8300_PARAM_H
+#define _H8300_PARAM_H
+
+#include <linux/config.h>
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#define EXEC_PAGESIZE	4096
+
+#ifndef NGROUPS
+#define NGROUPS		32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#ifdef __KERNEL__
+#define CLOCKS_PER_SEC HZ
+#endif
+
+#endif /* _H8300_PARAM_H */
diff -urN linux-2.4.29/include/asm-h8300/pci.h linux-2.4.29-uc1/include/asm-h8300/pci.h
--- linux-2.4.29/include/asm-h8300/pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/pci.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,27 @@
+#ifndef _ASM_H8300_PCI_H
+#define _ASM_H8300_PCI_H
+
+/*
+ * asm-h8300/pci.h - H8/300 specific PCI declarations.
+ *
+ * Yoshinori Sato <ysato@users.sourceforge.jp>
+ */
+
+#define pcibios_assign_all_busses()	0
+
+extern inline void pcibios_set_master(struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling */
+}
+
+extern inline void pcibios_penalize_isa_irq(int irq)
+{
+	/* We don't do dynamic PCI IRQ allocation */
+}
+
+/* Return the index of the PCI controller for device PDEV. */
+#define pci_controller_num(PDEV)	(0)
+
+#define PCI_DMA_BUS_IS_PHYS             (1)
+
+#endif /* _ASM_H8300_PCI_H */
diff -urN linux-2.4.29/include/asm-h8300/pgalloc.h linux-2.4.29-uc1/include/asm-h8300/pgalloc.h
--- linux-2.4.29/include/asm-h8300/pgalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/pgalloc.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,77 @@
+#ifndef _H8300_PGALLOC_H
+#define _H8300_PGALLOC_H
+
+/*
+ * Copyright (C) 2000 Lineo, David McCullough <davidm@lineo.com>
+ * Copyright (C) 2001 Lineo, Greg Ungerer <gerg@snapgear.com>
+ */
+
+#include <asm/setup.h>
+#include <asm/virtconvert.h>
+
+#define flush_cache_all()                       do { } while(0)
+#define flush_cache_mm(mm)                      do { } while(0)
+#define flush_cache_range(mm, start, end)       do { } while(0)
+#define flush_cache_page(vma, vmaddr)           do { } while(0)
+#define flush_page_to_ram(page)                 do { } while(0)
+#define flush_dcache_page(page)                 do { } while(0)
+#define flush_icache_range(start, end)          do { } while(0)
+#define flush_icache_user_range(vma,pg,adr,len) do { } while(0)
+#define flush_icache_page(vma,pg)               do { } while(0)
+#define flush_icache()                          do { } while(0)
+
+/*
+ * DAVIDM - the rest of these are just so I can check where they happen
+ */
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+	BUG();
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+	BUG();
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+	BUG();
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+	BUG();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+	BUG();
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+				   unsigned long start, unsigned long end)
+{
+	BUG();
+}
+
+extern inline void flush_tlb_kernel_page(unsigned long addr)
+{
+	BUG();
+}
+
+extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+				      unsigned long start, unsigned long end)
+{
+	BUG();
+}
+
+#endif /* _H8300_PGALLOC_H */
diff -urN linux-2.4.29/include/asm-h8300/pgtable.h linux-2.4.29-uc1/include/asm-h8300/pgtable.h
--- linux-2.4.29/include/asm-h8300/pgtable.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/pgtable.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,23 @@
+#ifndef _H8300_PGTABLE_H
+#define _H8300_PGTABLE_H
+
+#include <linux/config.h>
+#include <asm/setup.h>
+
+#define pgd_present(pgd)     (1)       /* pages are always present on NO_MM */
+#define kern_addr_valid(addr) (1)
+
+#define PAGE_NONE		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_SHARED		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_COPY		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_READONLY	__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_KERNEL		__pgprot(0)    /* these mean nothing to NO_MM */
+
+extern void paging_init(void);
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()   do { } while (0)
+
+#endif /* _H8300_PGTABLE_H */
diff -urN linux-2.4.29/include/asm-h8300/poll.h linux-2.4.29-uc1/include/asm-h8300/poll.h
--- linux-2.4.29/include/asm-h8300/poll.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/poll.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,22 @@
+#ifndef __H8300_POLL_H
+#define __H8300_POLL_H
+
+#define POLLIN		  1
+#define POLLPRI		  2
+#define POLLOUT		  4
+#define POLLERR		  8
+#define POLLHUP		 16
+#define POLLNVAL	 32
+#define POLLRDNORM	 64
+#define POLLWRNORM	POLLOUT
+#define POLLRDBAND	128
+#define POLLWRBAND	256
+#define POLLMSG		0x0400
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/posix_types.h linux-2.4.29-uc1/include/asm-h8300/posix_types.h
--- linux-2.4.29/include/asm-h8300/posix_types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/posix_types.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,63 @@
+#ifndef __ARCH_H8300_POSIX_TYPES_H
+#define __ARCH_H8300_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned short	__kernel_dev_t;
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned short	__kernel_mode_t;
+typedef unsigned short	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
+typedef unsigned short	__kernel_uid_t;
+typedef unsigned short	__kernel_gid_t;
+typedef unsigned int	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+typedef unsigned short	__kernel_old_uid_t;
+typedef unsigned short	__kernel_old_gid_t;
+
+#ifdef __GNUC__
+typedef long long	__kernel_loff_t;
+#endif
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+	int	val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+	int	__val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#undef	__FD_SET
+#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+
+#undef	__FD_CLR
+#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+
+#undef	__FD_ISSET
+#define	__FD_ISSET(d, set)	((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
+
+#undef	__FD_ZERO
+#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/processor.h linux-2.4.29-uc1/include/asm-h8300/processor.h
--- linux-2.4.29/include/asm-h8300/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/processor.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,163 @@
+/*
+ * include/asm-h8300/processor.h
+ *
+ * Copyright (C) 2002 Yoshinori Sato
+ *
+ * Based on: linux/asm-m68nommu/processor.h
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+ */
+
+#ifndef __ASM_H8300_PROCESSOR_H
+#define __ASM_H8300_PROCESSOR_H
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#include <linux/config.h>
+#include <asm/segment.h>
+#include <asm/fpu.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+
+extern inline unsigned long rdusp(void) {
+	extern unsigned int	sw_usp;
+	return(sw_usp);
+}
+
+extern inline void wrusp(unsigned long usp) {
+	extern unsigned int	sw_usp;
+	sw_usp = usp;
+}
+
+/*
+ * User space process size: 3.75GB. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.
+ */
+#define TASK_SIZE	(0xFFFFFFFFUL)
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define MCA_bus 0
+
+struct thread_struct {
+	unsigned long  ksp;		/* kernel stack pointer */
+	unsigned long  usp;		/* user stack pointer */
+	unsigned long  ccr;		/* saved status register */
+	unsigned long  esp0;            /* points to SR of stack frame */
+	struct {
+		unsigned short *addr;
+		unsigned short inst;
+	} breakinfo;
+};
+
+#define INIT_THREAD  { \
+	sizeof(init_stack) + (unsigned long) init_stack, 0, \
+	PS_S,  0, {-1, 0}, \
+}
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ *
+ * pass the data segment into user programs if it exists,
+ * it can't hurt anything as far as I can tell
+ */
+#if defined(__H8300H__)
+#define start_thread(_regs, _pc, _usp)			        \
+do {							        \
+	set_fs(USER_DS); /* reads from user space */            \
+	(_regs)->pc = (_pc);				        \
+	(_regs)->ccr = 0;				        \
+	(_regs)->er5 = current->mm->start_data;		        \
+	wrusp((unsigned long)(_usp) - sizeof(unsigned long)*3);	\
+} while(0)
+#endif
+#if defined(__H8300S__)
+#define start_thread(_regs, _pc, _usp)			  \
+do {                                              \
+	set_fs(USER_DS); /* reads from user space */  \
+	(_regs)->pc = (_pc);                          \
+	(_regs)->ccr = 0;                             \
+	(_regs)->exr = 0x00;                          \
+	(_regs)->er5 = current->mm->start_data;	      \
+	/* 14 = space for retaddr(4), vector(4), er0(4) and ext(2) on stack */ \
+	wrusp(((unsigned long)(_usp)) - 14);          \
+} while(0)
+#endif
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+#define copy_segments(tsk, mm)		do { } while (0)
+#define release_segments(mm)		do { } while (0)
+#define forget_segments()		do { } while (0)
+
+/*
+ * Free current thread data structures etc..
+ */
+static inline void exit_thread(void)
+{
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+extern inline unsigned long thread_saved_pc(struct thread_struct *t)
+{
+	extern void scheduling_functions_start_here(void);
+	extern void scheduling_functions_end_here(void);
+	struct switch_stack *sw = (struct switch_stack *)t->ksp;
+	/* Check whether the thread is blocked in resume() */
+	if (sw->retpc > (unsigned long)scheduling_functions_start_here &&
+	    sw->retpc < (unsigned long)scheduling_functions_end_here)
+		return ((unsigned long *)sw->er6)[1];
+	else
+		return sw->retpc;
+}
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define	KSTK_EIP(tsk)	\
+    ({			\
+	unsigned long eip = 0;	 \
+	if ((tsk)->thread.esp0 > PAGE_SIZE && \
+	    MAP_NR((tsk)->thread.esp0) < max_mapnr) \
+	      eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
+	eip; })
+#define	KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->thread.usp)
+
+#ifdef CONFIG_SMALL_TASKS
+#define THREAD_SIZE PAGE_SIZE
+
+/* Allocation and freeing of basic task resources. */
+#define alloc_task_struct() \
+	((struct task_struct *) __get_free_pages(GFP_KERNEL,0))
+#define free_task_struct(p)	free_pages((unsigned long)(p),0)
+#else
+#define THREAD_SIZE (2*PAGE_SIZE)
+
+/* Allocation and freeing of basic task resources. */
+#define alloc_task_struct() \
+	((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
+#define free_task_struct(p)	free_pages((unsigned long)(p),1)
+#endif
+#define get_task_struct(tsk)      atomic_inc(&mem_map[MAP_NR(tsk)].count)
+
+#define init_task	(init_task_union.task)
+#define init_stack	(init_task_union.stack)
+
+#define cpu_relax()    barrier()
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/ptrace.h linux-2.4.29-uc1/include/asm-h8300/ptrace.h
--- linux-2.4.29/include/asm-h8300/ptrace.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/ptrace.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,74 @@
+#ifndef _H8300_PTRACE_H
+#define _H8300_PTRACE_H
+
+#ifndef __ASSEMBLY__
+
+#define PT_ER1	   0
+#define PT_ER2	   1
+#define PT_ER3	   2
+#define PT_ER4	   3
+#define PT_ER5	   4
+#define PT_ER6	   5
+#define PT_ER0	   6
+#define PT_ORIG_ER0	   7
+#define PT_CCR	   8
+#define PT_PC	   9
+#define PT_USP	   10
+#define PT_EXR     11
+
+/* this struct defines the way the registers are stored on the
+   stack during a system call. */
+
+struct pt_regs {
+	long     er4;
+	long     er5;
+	long     er3;
+	long     er2;
+	long     er1;
+	long     orig_er0;
+	unsigned short ccr;
+	long     er0;
+	long     vector;
+#if defined(__H8300S__)
+	unsigned short exr;
+#endif
+	unsigned long  pc;
+} __attribute__((aligned(2),packed));
+
+/*
+ * This is the extended stack used by signal handlers and the context
+ * switcher: it's pushed after the normal "struct pt_regs".
+ */
+struct switch_stack {
+	unsigned long  er6;
+	unsigned long  retpc;
+};
+
+#define PTRACE_GETREGS            12
+#define PTRACE_SETREGS            13
+
+#ifdef __KERNEL__
+#ifndef PS_S
+#define PS_S  (0x10)
+#endif
+
+#if defined(__H8300H__)
+#define H8300_REGS_NO 11
+#endif
+#if defined(__H8300S__)
+#define H8300_REGS_NO 12
+#endif
+
+/* Find the stack offset for a register, relative to thread.esp0. */
+#define PT_REG(reg)	((long)&((struct pt_regs *)0)->reg)
+#define SW_REG(reg)	((long)&((struct switch_stack *)0)->reg \
+			 - sizeof(struct switch_stack))
+
+#define user_mode(regs) (!((regs)->ccr & PS_S))
+#define instruction_pointer(regs) ((regs)->pc)
+
+extern void show_regs(struct pt_regs *);
+
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+#endif /* _H8300_PTRACE_H */
diff -urN linux-2.4.29/include/asm-h8300/regs267x.h linux-2.4.29-uc1/include/asm-h8300/regs267x.h
--- linux-2.4.29/include/asm-h8300/regs267x.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/regs267x.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,336 @@
+/* internal Peripherals Register address define */
+/* CPU: H8/306x                                 */
+
+#if !defined(__REGS_H8S267x__)
+#define __REGS_H8S267x__ 
+
+#if defined(__KERNEL__)
+
+#define DASTCR 0xFEE01A
+#define DADR0  0xFFFFA4
+#define DADR1  0xFFFFA5
+#define DACR01 0xFFFFA6
+#define DADR2  0xFFFFA8
+#define DADR3  0xFFFFA9
+#define DACR23 0xFFFFAA
+
+#define ADDRA  0xFFFF90
+#define ADDRAH 0xFFFF90
+#define ADDRAL 0xFFFF91
+#define ADDRB  0xFFFF92
+#define ADDRBH 0xFFFF92
+#define ADDRBL 0xFFFF93
+#define ADDRC  0xFFFF94
+#define ADDRCH 0xFFFF94
+#define ADDRCL 0xFFFF95
+#define ADDRD  0xFFFF96
+#define ADDRDH 0xFFFF96
+#define ADDRDL 0xFFFF97
+#define ADDRE  0xFFFF98
+#define ADDREH 0xFFFF98
+#define ADDREL 0xFFFF99
+#define ADDRF  0xFFFF9A
+#define ADDRFH 0xFFFF9A
+#define ADDRFL 0xFFFF9B
+#define ADDRG  0xFFFF9C
+#define ADDRGH 0xFFFF9C
+#define ADDRGL 0xFFFF9D
+#define ADDRH  0xFFFF9E
+#define ADDRHH 0xFFFF9E
+#define ADDRHL 0xFFFF9F
+
+#define ADCSR  0xFFFFA0
+#define ADCR   0xFFFFA1
+
+#define ABWCR  0xFFFEC0
+#define ASTCR  0xFFFEC1
+#define WTCRAH 0xFFFEC2
+#define WTCRAL 0xFFFEC3
+#define WTCRBH 0xFFFEC4
+#define WTCRBL 0xFFFEC5
+#define RDNCR  0xFFFEC6
+#define CSACRH 0xFFFEC8
+#define CSACRL 0xFFFEC9
+#define BROMCRH 0xFFFECA
+#define BROMCRL 0xFFFECB
+#define BCR    0xFFFECC
+#define DRAMCR 0xFFFED0
+#define DRACCR 0xFFFED2
+#define REFCR  0xFFFED4
+#define RTCNT  0xFFFED6
+#define RTCOR  0xFFFED7
+
+#define MAR0AH  0xFFFEE0
+#define MAR0AL  0xFFFEE2
+#define IOAR0A  0xFFFEE4
+#define ETCR0A  0xFFFEE6
+#define MAR0BH  0xFFFEE8
+#define MAR0BL  0xFFFEEA
+#define IOAR0B  0xFFFEEC
+#define ETCR0B  0xFFFEEE
+#define MAR1AH  0xFFFEF0
+#define MAR1AL  0xFFFEF2
+#define IOAR1A  0xFFFEF4
+#define ETCR1A  0xFFFEF6
+#define MAR1BH  0xFFFEF8
+#define MAR1BL  0xFFFEFA
+#define IOAR1B  0xFFFEFC
+#define ETCR1B  0xFFFEFE
+#define DMAWER  0xFFFF20
+#define DMATCR  0xFFFF21
+#define DMACR0A 0xFFFF22
+#define DMACR0B 0xFFFF23
+#define DMACR1A 0xFFFF24
+#define DMACR1B 0xFFFF25
+#define DMABCRH 0xFFFF26
+#define DMABCRL 0xFFFF27
+
+#define EDSAR0  0xFFFDC0
+#define EDDAR0  0xFFFDC4
+#define EDTCR0  0xFFFDC8
+#define EDMDR0  0xFFFDCC
+#define EDMDR0H 0xFFFDCC
+#define EDMDR0L 0xFFFDCD
+#define EDACR0  0xFFFDCE
+#define EDSAR1  0xFFFDD0
+#define EDDAR1  0xFFFDD4
+#define EDTCR1  0xFFFDD8
+#define EDMDR1  0xFFFDDC
+#define EDMDR1H 0xFFFDDC
+#define EDMDR1L 0xFFFDDD
+#define EDACR1  0xFFFDDE
+#define EDSAR2  0xFFFDE0
+#define EDDAR2  0xFFFDE4
+#define EDTCR2  0xFFFDE8
+#define EDMDR2  0xFFFDEC
+#define EDMDR2H 0xFFFDEC
+#define EDMDR2L 0xFFFDED
+#define EDACR2  0xFFFDEE
+#define EDSAR3  0xFFFDF0
+#define EDDAR3  0xFFFDF4
+#define EDTCR3  0xFFFDF8
+#define EDMDR3  0xFFFDFC
+#define EDMDR3H 0xFFFDFC
+#define EDMDR3L 0xFFFDFD
+#define EDACR3  0xFFFDFE
+
+#define IPRA  0xFFFE00
+#define IPRB  0xFFFE02
+#define IPRC  0xFFFE04
+#define IPRD  0xFFFE06
+#define IPRE  0xFFFE08
+#define IPRF  0xFFFE0A
+#define IPRG  0xFFFE0C
+#define IPRH  0xFFFE0E
+#define IPRI  0xFFFE10
+#define IPRJ  0xFFFE12
+#define IPRK  0xFFFE14
+#define ITSR  0xFFFE16
+#define SSIER 0xFFFE18
+#define ISCRH 0xFFFE1A
+#define ISCRL 0xFFFE1C
+
+#define INTCR 0xFFFF31
+#define IER   0xFFFF32
+#define IERH  0xFFFF32
+#define IERL  0xFFFF33
+#define ISR   0xFFFF34
+#define ISRH  0xFFFF34
+#define ISRL  0xFFFF35
+
+#define P1DDR 0xFFFE20
+#define P2DDR 0xFFFE21
+#define P3DDR 0xFFFE22
+#define P4DDR 0xFFFE23
+#define P5DDR 0xFFFE24
+#define P6DDR 0xFFFE25
+#define P7DDR 0xFFFE26
+#define P8DDR 0xFFFE27
+#define P9DDR 0xFFFE28
+#define PADDR 0xFFFE29
+#define PBDDR 0xFFFE2A
+#define PCDDR 0xFFFE2B
+#define PDDDR 0xFFFE2C
+#define PEDDR 0xFFFE2D
+#define PFDDR 0xFFFE2E
+#define PGDDR 0xFFFE2F
+#define PHDDR 0xFFFF74
+
+#define PFCR0 0xFFFE32
+#define PFCR1 0xFFFE33
+#define PFCR2 0xFFFE34
+
+#define PAPCR 0xFFFE36
+#define PBPCR 0xFFFE37
+#define PCPCR 0xFFFE38
+#define PDPCR 0xFFFE39
+#define PEPCR 0xFFFE3A
+
+#define P3ODR 0xFFFE3C
+#define PAODR 0xFFFE3D
+
+#define P1DR  0xFFFF60
+#define P2DR  0xFFFF61
+#define P3DR  0xFFFF62
+#define P4DR  0xFFFF63
+#define P5DR  0xFFFF64
+#define P6DR  0xFFFF65
+#define P7DR  0xFFFF66
+#define P8DR  0xFFFF67
+#define P9DR  0xFFFF68
+#define PADR  0xFFFF69
+#define PBDR  0xFFFF6A
+#define PCDR  0xFFFF6B
+#define PDDR  0xFFFF6C
+#define PEDR  0xFFFF6D
+#define PFDR  0xFFFF6E
+#define PGDR  0xFFFF6F
+#define PHDR  0xFFFF72
+
+#define PORT1 0xFFFF50
+#define PORT2 0xFFFF51
+#define PORT3 0xFFFF52
+#define PORT4 0xFFFF53
+#define PORT5 0xFFFF54
+#define PORT6 0xFFFF55
+#define PORT7 0xFFFF56
+#define PORT8 0xFFFF57
+#define PORT9 0xFFFF58
+#define PORTA 0xFFFF59
+#define PORTB 0xFFFF5A
+#define PORTC 0xFFFF5B
+#define PORTD 0xFFFF5C
+#define PORTE 0xFFFF5D
+#define PORTF 0xFFFF5E
+#define PORTG 0xFFFF5F
+#define PORTH 0xFFFF70
+
+#define PCR   0xFFFF46
+#define PMR   0xFFFF47
+#define NDERH 0xFFFF48
+#define NDERL 0xFFFF49
+#define PODRH 0xFFFF4A
+#define PODRL 0xFFFF4B
+#define NDRH1 0xFFFF4C
+#define NDRL1 0xFFFF4D
+#define NDRH2 0xFFFF4E
+#define NDRL2 0xFFFF4F
+
+#define SMR0  0xFFFF78
+#define BRR0  0xFFFF79
+#define SCR0  0xFFFF7A
+#define TDR0  0xFFFF7B
+#define SSR0  0xFFFF7C
+#define RDR0  0xFFFF7D
+#define SCMR0 0xFFFF7E
+#define SMR1  0xFFFF80
+#define BRR1  0xFFFF81
+#define SCR1  0xFFFF82
+#define TDR1  0xFFFF83
+#define SSR1  0xFFFF84
+#define RDR1  0xFFFF85
+#define SCMR1 0xFFFF86
+#define SMR2  0xFFFF88
+#define BRR2  0xFFFF89
+#define SCR2  0xFFFF8A
+#define TDR2  0xFFFF8B
+#define SSR2  0xFFFF8C
+#define RDR2  0xFFFF8D
+#define SCMR2 0xFFFF8E
+
+#define IRCR0 0xFFFE1E
+#define SEMR  0xFFFDA8
+
+#define MDCR    0xFFFF3E
+#define SYSCR   0xFFFF3D
+#define MSTPCRH 0xFFFF40
+#define MSTPCRL 0xFFFF41
+#define FLMCR1  0xFFFFC8
+#define FLMCR2  0xFFFFC9
+#define EBR1    0xFFFFCA
+#define EBR2    0xFFFFCB
+#define CTGARC_RAMCR   0xFFFECE
+#define SBYCR   0xFFFF3A
+#define SCKCR   0xFFFF3B
+#define PLLCR   0xFFFF45
+
+#define TSTR   0xFFFFC0
+#define TSNC   0XFFFFC1
+
+#define TCR0   0xFFFFD0
+#define TMDR0  0xFFFFD1
+#define TIORH0 0xFFFFD2
+#define TIORL0 0xFFFFD3
+#define TIER0  0xFFFFD4
+#define TSR0   0xFFFFD5
+#define TCNT0  0xFFFFD6
+#define GRA0   0xFFFFD8
+#define GRB0   0xFFFFDA
+#define GRC0   0xFFFFDC
+#define GRD0   0xFFFFDE
+#define TCR1   0xFFFFE0
+#define TMDR1  0xFFFFE1
+#define TIORH1 0xFFFFE2
+#define TIORL1 0xFFFFE3
+#define TIER1  0xFFFFE4
+#define TSR1   0xFFFFE5
+#define TCNT1  0xFFFFE6
+#define GRA1   0xFFFFE8
+#define GRB1   0xFFFFEA
+#define TCR2   0xFFFFF0
+#define TMDR2  0xFFFFF1
+#define TIORH2 0xFFFFF2
+#define TIORL2 0xFFFFF3
+#define TIER2  0xFFFFF4
+#define TSR2   0xFFFFF5
+#define TCNT2  0xFFFFF6
+#define GRA2   0xFFFFF8
+#define GRB2   0xFFFFFA
+#define TCR3   0xFFFE80
+#define TMDR3  0xFFFE81
+#define TIORH3 0xFFFE82
+#define TIORL3 0xFFFE83
+#define TIER3  0xFFFE84
+#define TSR3   0xFFFE85
+#define TCNT3  0xFFFE86
+#define GRA3   0xFFFE88
+#define GRB3   0xFFFE8A
+#define GRC3   0xFFFE8C
+#define GRD3   0xFFFE8E
+#define TCR4   0xFFFE90
+#define TMDR4  0xFFFE91
+#define TIORH4 0xFFFE92
+#define TIORL4 0xFFFE93
+#define TIER4  0xFFFE94
+#define TSR4   0xFFFE95
+#define TCNT4  0xFFFE96
+#define GRA4   0xFFFE98
+#define GRB4   0xFFFE9A
+#define TCR5   0xFFFEA0
+#define TMDR5  0xFFFEA1
+#define TIORH5 0xFFFEA2
+#define TIORL5 0xFFFEA3
+#define TIER5  0xFFFEA4
+#define TSR5   0xFFFEA5
+#define TCNT5  0xFFFEA6
+#define GRA5   0xFFFEA8
+#define GRB5   0xFFFEAA
+
+#define _8TCR0   0xFFFFB0
+#define _8TCR1   0xFFFFB1
+#define _8TCSR0  0xFFFFB2
+#define _8TCSR1  0xFFFFB3
+#define _8TCORA0 0xFFFFB4
+#define _8TCORA1 0xFFFFB5
+#define _8TCORB0 0xFFFFB6
+#define _8TCORB1 0xFFFFB7
+#define _8TCNT0  0xFFFFB8
+#define _8TCNT1  0xFFFFB9
+
+#define TCSR    0xFFFFBC
+#define TCNT    0xFFFFBD
+#define RSTCSRW 0xFFFFBE
+#define RSTCSRR 0xFFFFBF
+
+#endif /* __KERNEL__ */
+#endif /* __REGS_H8S267x__ */
diff -urN linux-2.4.29/include/asm-h8300/regs306x.h linux-2.4.29-uc1/include/asm-h8300/regs306x.h
--- linux-2.4.29/include/asm-h8300/regs306x.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/regs306x.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,212 @@
+/* internal Peripherals Register address define */
+/* CPU: H8/306x                                 */
+
+#if !defined(__REGS_H8306x__)
+#define __REGS_H8306x__ 
+
+#if defined(__KERNEL__)
+
+#define DASTCR 0xFEE01A
+#define DADR0  0xFEE09C
+#define DADR1  0xFEE09D
+#define DACR   0xFEE09E
+
+#define ADDRAH 0xFFFFE0
+#define ADDRAL 0xFFFFE1
+#define ADDRBH 0xFFFFE2
+#define ADDRBL 0xFFFFE3
+#define ADDRCH 0xFFFFE4
+#define ADDRCL 0xFFFFE5
+#define ADDRDH 0xFFFFE6
+#define ADDRDL 0xFFFFE7
+#define ADCSR  0xFFFFE8
+#define ADCR   0xFFFFE9
+
+#define BRCR   0xFEE013
+#define ADRCR  0xFEE01E
+#define CSCR   0xFEE01F
+#define ABWCR  0xFEE020
+#define ASTCR  0xFEE021
+#define WCRH   0xFEE022
+#define WCRL   0xFEE023
+#define BCR    0xFEE024
+#define DRCRA  0xFEE026
+#define DRCRB  0xFEE027
+#define RTMCSR 0xFEE028
+#define RTCNT  0xFEE029
+#define RTCOR  0xFEE02A
+
+#define MAR0AR  0xFFFF20
+#define MAR0AE  0xFFFF21
+#define MAR0AH  0xFFFF22
+#define MAR0AL  0xFFFF23
+#define ETCR0AH 0xFFFF24
+#define ETCR0AL 0xFFFF25
+#define IOAR0A  0xFFFF26
+#define DTCR0A  0xFFFF27
+#define MAR0BR  0xFFFF28
+#define MAR0BE  0xFFFF29
+#define MAR0BH  0xFFFF2A
+#define MAR0BL  0xFFFF2B
+#define ETCR0BH 0xFFFF2C
+#define ETCR0BL 0xFFFF2D
+#define IOAR0B  0xFFFF2E
+#define DTCR0B  0xFFFF2F
+#define MAR1AR  0xFFFF30
+#define MAR1AE  0xFFFF31
+#define MAR1AH  0xFFFF32
+#define MAR1AL  0xFFFF33
+#define ETCR1AL 0xFFFF34
+#define ETCR1AH 0xFFFF35
+#define IOAR1A  0xFFFF36
+#define DTCR1A  0xFFFF37
+#define MAR1BR  0xFFFF38
+#define MAR1BE  0xFFFF39
+#define MAR1BH  0xFFFF3A
+#define MAR1BL  0xFFFF3B
+#define ETCR1BL 0xFFFF3C
+#define ETCR1BH 0xFFFF3D
+#define IOAR1B  0xFFFF3E
+#define DTCR1B  0xFFFF3F
+
+#define ISCR 0xFEE014
+#define IER  0xFEE015
+#define ISR  0xFEE016
+#define IPRA 0xFEE018
+#define IPRB 0xFEE019
+
+#define P1DDR 0xFEE000
+#define P2DDR 0xFEE001
+#define P3DDR 0xFEE002
+#define P4DDR 0xFEE003
+#define P5DDR 0xFEE004
+#define P6DDR 0xFEE005
+/*#define P7DDR 0xFEE006*/
+#define P8DDR 0xFEE007
+#define P9DDR 0xFEE008
+#define PADDR 0xFEE009
+#define PBDDR 0xFEE00A
+
+#define P1DR  0xFFFFD0
+#define P2DR  0xFFFFD1
+#define P3DR  0xFFFFD2
+#define P4DR  0xFFFFD3
+#define P5DR  0xFFFFD4
+#define P6DR  0xFFFFD5
+/*#define P7DR  0xFFFFD6*/
+#define P8DR  0xFFFFD7
+#define P9DR  0xFFFFD8
+#define PADR  0xFFFFD9
+#define PBDR  0xFFFFDA
+
+#define P2CR  0xFEE03C
+#define P4CR  0xFEE03E
+#define P5CR  0xFEE03F
+
+#define SMR0  0xFFFFB0
+#define BRR0  0xFFFFB1
+#define SCR0  0xFFFFB2
+#define TDR0  0xFFFFB3
+#define SSR0  0xFFFFB4
+#define RDR0  0xFFFFB5
+#define SCMR0 0xFFFFB6
+#define SMR1  0xFFFFB8
+#define BRR1  0xFFFFB9
+#define SCR1  0xFFFFBA
+#define TDR1  0xFFFFBB
+#define SSR1  0xFFFFBC
+#define RDR1  0xFFFFBD
+#define SCMR1 0xFFFFBE
+#define SMR2  0xFFFFC0
+#define BRR2  0xFFFFC1
+#define SCR2  0xFFFFC2
+#define TDR2  0xFFFFC3
+#define SSR2  0xFFFFC4
+#define RDR2  0xFFFFC5
+#define SCMR2 0xFFFFC6
+
+#define MDCR   0xFEE011
+#define SYSCR  0xFEE012
+#define DIVCR  0xFEE01B
+#define MSTCRH 0xFEE01C
+#define MSTCRL 0xFEE01D
+#define FLMCR1 0xFEE030
+#define FLMCR2 0xFEE031
+#define EBR1   0xFEE032
+#define EBR2   0xFEE033
+#define RAMCR  0xFEE077
+
+#define TSTR   0xFFFF60
+#define TSNC   0XFFFF61
+#define TMDR   0xFFFF62
+#define TOLR   0xFFFF63
+#define TISRA  0xFFFF64
+#define TISRB  0xFFFF65
+#define TISRC  0xFFFF66
+#define TCR0   0xFFFF68
+#define TIOR0  0xFFFF69
+#define TCNT0H 0xFFFF6A
+#define TCNT0L 0xFFFF6B
+#define GRA0H  0xFFFF6C
+#define GRA0L  0xFFFF6D
+#define GRB0H  0xFFFF6E
+#define GRB0L  0xFFFF6F
+#define TCR1   0xFFFF70
+#define TIOR1  0xFFFF71
+#define TCNT1H 0xFFFF72
+#define TCNT1L 0xFFFF73
+#define GRA1H  0xFFFF74
+#define GRA1L  0xFFFF75
+#define GRB1H  0xFFFF76
+#define GRB1L  0xFFFF77
+#define TCR3   0xFFFF78
+#define TIOR3  0xFFFF79
+#define TCNT3H 0xFFFF7A
+#define TCNT3L 0xFFFF7B
+#define GRA3H  0xFFFF7C
+#define GRA3L  0xFFFF7D
+#define GRB3H  0xFFFF7E
+#define GRB3L  0xFFFF7F
+
+#define _8TCR0  0xFFFF80
+#define _8TCR1  0xFFFF81
+#define _8TCSR0 0xFFFF82
+#define _8TCSR1 0xFFFF83
+#define TCORA0 0xFFFF84
+#define TCORA1 0xFFFF85
+#define TCORB0 0xFFFF86
+#define TCORB1 0xFFFF87
+#define _8TCNT0 0xFFFF88
+#define _8TCNT1 0xFFFF89
+
+#define _8TCR2  0xFFFF90
+#define _8TCR3  0xFFFF91
+#define _8TCSR2 0xFFFF92
+#define _8TCSR3 0xFFFF93
+#define TCORA2 0xFFFF94
+#define TCORA3 0xFFFF95
+#define TCORB2 0xFFFF96
+#define TCORB3 0xFFFF97
+#define _8TCNT2 0xFFFF98
+#define _8TCNT3 0xFFFF99
+
+#define TCSR   0xFFFF8C
+#define TCNT   0xFFFF8D
+#define RSTCSR 0xFFFF8F
+
+#define TPMR  0xFFFFA0
+#define TPCR  0xFFFFA1
+#define NDERB 0xFFFFA2
+#define NDERA 0xFFFFA3
+#define NDRB1 0xFFFFA4
+#define NDRA1 0xFFFFA5
+#define NDRB2 0xFFFFA6
+#define NDRA2 0xFFFFA7
+
+#define TCSR    0xFFFF8C
+#define TCNT    0xFFFF8D
+#define RSTCSRW 0xFFFF8E
+#define RSTCSRR 0xFFFF8F
+
+#endif /* __KERNEL__ */
+#endif /* __REGS_H8306x__ */
diff -urN linux-2.4.29/include/asm-h8300/resource.h linux-2.4.29-uc1/include/asm-h8300/resource.h
--- linux-2.4.29/include/asm-h8300/resource.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/resource.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,47 @@
+#ifndef _H8300_RESOURCE_H
+#define _H8300_RESOURCE_H
+
+/*
+ * Resource limits
+ */
+
+#define RLIMIT_CPU	0		/* CPU time in ms */
+#define RLIMIT_FSIZE	1		/* Maximum filesize */
+#define RLIMIT_DATA	2		/* max data size */
+#define RLIMIT_STACK	3		/* max stack size */
+#define RLIMIT_CORE	4		/* max core file size */
+#define RLIMIT_RSS	5		/* max resident set size */
+#define RLIMIT_NPROC	6		/* max number of processes */
+#define RLIMIT_NOFILE	7		/* max number of open files */
+#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
+#define RLIMIT_AS	9		/* address space limit */
+#define RLIMIT_LOCKS	10		/* maximum file locks held */
+
+#define RLIM_NLIMITS	11
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway.
+ */
+#define RLIM_INFINITY	(~0UL)
+
+#ifdef __KERNEL__
+
+#define INIT_RLIMITS					\
+{							\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{      _STK_LIM, RLIM_INFINITY },		\
+	{             0, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{             0,             0 },		\
+	{      INR_OPEN,     INR_OPEN  },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+        { RLIM_INFINITY, RLIM_INFINITY },		\
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _H8300_RESOURCE_H */
diff -urN linux-2.4.29/include/asm-h8300/scatterlist.h linux-2.4.29-uc1/include/asm-h8300/scatterlist.h
--- linux-2.4.29/include/asm-h8300/scatterlist.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/scatterlist.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,4 @@
+#ifndef _H8300_SCATTERLIST_H
+#define _H8300_SCATTERLIST_H
+
+#endif /* !(_H8300_SCATTERLIST_H) */
diff -urN linux-2.4.29/include/asm-h8300/segment.h linux-2.4.29-uc1/include/asm-h8300/segment.h
--- linux-2.4.29/include/asm-h8300/segment.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/segment.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,49 @@
+#ifndef _H8300_SEGMENT_H
+#define _H8300_SEGMENT_H
+
+/* define constants */
+#define USER_DATA     (1)
+#ifndef __USER_DS
+#define __USER_DS     (USER_DATA)
+#endif
+#define USER_PROGRAM  (2)
+#define SUPER_DATA    (3)
+#ifndef __KERNEL_DS
+#define __KERNEL_DS   (SUPER_DATA)
+#endif
+#define SUPER_PROGRAM (4)
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
+#define USER_DS		MAKE_MM_SEG(__USER_DS)
+#define KERNEL_DS	MAKE_MM_SEG(__KERNEL_DS)
+
+/*
+ * Get/set the SFC/DFC registers for MOVES instructions
+ */
+
+static inline mm_segment_t get_fs(void)
+{
+    return USER_DS;
+}
+
+static inline mm_segment_t get_ds(void)
+{
+    /* return the supervisor data space code */
+    return KERNEL_DS;
+}
+
+static inline void set_fs(mm_segment_t val)
+{
+}
+
+#define segment_eq(a,b)	((a).seg == (b).seg)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _H8300_SEGMENT_H */
diff -urN linux-2.4.29/include/asm-h8300/semaphore.h linux-2.4.29-uc1/include/asm-h8300/semaphore.h
--- linux-2.4.29/include/asm-h8300/semaphore.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/semaphore.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,219 @@
+#ifndef _H8300_SEMAPHORE_H
+#define _H8300_SEMAPHORE_H
+
+#define RW_LOCK_BIAS		 0x01000000
+
+#ifndef __ASSEMBLY__
+
+#include <linux/linkage.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/rwsem.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+
+/*
+ * Interrupt-safe semaphores..
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ *
+ * H8/300 version by Yoshinori Sato
+ */
+
+
+struct semaphore {
+	atomic_t count;
+	int sleepers;
+	wait_queue_head_t wait;
+#if WAITQUEUE_DEBUG
+	long __magic;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+# define __SEM_DEBUG_INIT(name) \
+		, (long)&(name).__magic
+#else
+# define __SEM_DEBUG_INIT(name)
+#endif
+
+#define __SEMAPHORE_INITIALIZER(name,count) \
+{ ATOMIC_INIT(count), 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+	__SEM_DEBUG_INIT(name) }
+
+#define __MUTEX_INITIALIZER(name) \
+	__SEMAPHORE_INITIALIZER(name,1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+
+#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
+#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
+
+extern inline void sema_init (struct semaphore *sem, int val)
+{
+	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
+}
+
+static inline void init_MUTEX (struct semaphore *sem)
+{
+	sema_init(sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+{
+	sema_init(sem, 0);
+}
+
+asmlinkage void __down_failed(void /* special register calling convention */);
+asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
+asmlinkage int  __down_failed_trylock(void  /* params in registers */);
+asmlinkage void __up_wakeup(void /* special register calling convention */);
+
+asmlinkage void __down(struct semaphore * sem);
+asmlinkage int  __down_interruptible(struct semaphore * sem);
+asmlinkage int  __down_trylock(struct semaphore * sem);
+asmlinkage void __up(struct semaphore * sem);
+
+extern spinlock_t semaphore_wake_lock;
+
+/*
+ * This is ugly, but we want the default case to fall through.
+ * "down_failed" is a special asm handler that calls the C
+ * routine that actually waits. See arch/m68k/lib/semaphore.S
+ */
+static inline void down(struct semaphore * sem)
+{
+	register atomic_t *count asm("er0");
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	count = &(sem->count);
+	__asm__ __volatile__(
+		"stc ccr,r3l\n\t"
+		"orc #0x80,ccr\n\t"
+		"mov.l %2, er1\n\t"
+		"dec.l #1,er1\n\t"
+		"mov.l er1,%0\n\t"
+		"bpl 1f\n\t"
+		"ldc r3l,ccr\n\t"
+		"mov.l %1,er0\n\t"
+		"jsr @_" SYMBOL_NAME_STR(__down) "\n\t"
+		"bra 2f\n"
+		"1:\n\t"
+		"ldc r3l,ccr\n"
+		"2:"
+		: "=m"(*count)
+		: "g"(sem),"m"(*count)
+		: "cc",  "er1", "er2", "er3");
+}
+
+static inline int down_interruptible(struct semaphore * sem)
+{
+	register atomic_t *count asm("er0");
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	count = &(sem->count);
+	__asm__ __volatile__(
+		"stc ccr,r1l\n\t"
+		"orc #0x80,ccr\n\t"
+		"mov.l %3, er2\n\t"
+		"dec.l #1,er2\n\t"
+		"mov.l er2,%1\n\t"
+		"bpl 1f\n\t"
+		"ldc r1l,ccr\n\t"
+		"mov.l %2,er0\n\t"
+		"jsr @_" SYMBOL_NAME_STR(__down_interruptible) "\n\t"
+		"bra 2f\n"
+		"1:\n\t"
+		"ldc r1l,ccr\n\t"
+		"sub.l %0,%0\n\t"
+		"2:\n\t"
+		: "=r" (count),"=m" (*count)
+		: "g" (sem),"m" (*count)
+		: "cc", "er1", "er2", "er3");
+	return (int)count;
+}
+
+static inline int down_trylock(struct semaphore * sem)
+{
+	register atomic_t *count asm("er0");
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	count = &(sem->count);
+	__asm__ __volatile__(
+		"stc ccr,r3l\n\t"
+		"orc #0x80,ccr\n\t"
+		"mov.l %3,er2\n\t"
+		"dec.l #1,er2\n\t"
+		"mov.l er2,%0\n\t"
+		"bpl 1f\n\t"
+		"ldc r3l,ccr\n\t"
+		"jmp @3f\n\t"
+		".section .text.lock,\"ax\"\n"
+		".align 2\n"
+		"3:\n\t"
+		"mov.l %2,er0\n\t"
+		"jsr @_" SYMBOL_NAME_STR(__down_trylock) "\n\t"
+		"jmp @2f\n\t"
+		".previous\n"
+		"1:\n\t"
+		"ldc r3l,ccr\n\t"
+		"sub.l %1,%1\n"
+		"2:"
+		: "=m" (*count),"=r"(count)
+		: "g" (sem),"m" (*count)
+		: "cc", "er1","er2", "er3");
+	return (int)count;
+}
+
+/*
+ * Note! This is subtle. We jump to wake people up only if
+ * the semaphore was negative (== somebody was waiting on it).
+ * The default case (no contention) will result in NO
+ * jumps for both down() and up().
+ */
+static inline void up(struct semaphore * sem)
+{
+	register atomic_t *count asm("er0");
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	count = &(sem->count);
+	__asm__ __volatile__(
+		"stc ccr,r3l\n\t"
+		"orc #0x80,ccr\n\t"
+		"mov.l %2,er1\n\t"
+		"inc.l #1,er1\n\t"
+		"mov.l er1,%0\n\t"
+		"ldc r3l,ccr\n\t"
+		"sub.l er2,er2\n\t"
+		"cmp.l er2,er1\n\t"
+		"bgt 1f\n\t"
+		"mov.l %1,er0\n\t"
+		"jsr @_" SYMBOL_NAME_STR(__up) "\n"
+		"1:"
+		: "=m"(*count)
+		: "g" (sem),"m" (*count)
+		: "cc", "er1", "er2", "er3");
+}
+
+static inline int sem_getcount(struct semaphore *sem)
+{
+	return atomic_read(&sem->count);
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/semaphore-helper.h linux-2.4.29-uc1/include/asm-h8300/semaphore-helper.h
--- linux-2.4.29/include/asm-h8300/semaphore-helper.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/semaphore-helper.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,85 @@
+#ifndef _H8300_SEMAPHORE_HELPER_H
+#define _H8300_SEMAPHORE_HELPER_H
+
+/*
+ * SMP- and interrupt-safe semaphores helper functions.
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ *
+ * based on
+ * m68k version by Andreas Schwab
+ */
+
+#include <linux/config.h>
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ */
+static inline void wake_one_more(struct semaphore * sem)
+{
+	atomic_inc((atomic_t *)&sem->sleepers);
+}
+
+static inline int waking_non_zero(struct semaphore *sem)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	ret = 0;
+	if (sem->sleepers > 0) {
+		sem->sleepers--;
+		ret = 1;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+/*
+ * waking_non_zero_interruptible:
+ *	1	got the lock
+ *	0	go to sleep
+ *	-EINTR	interrupted
+ */
+static inline int waking_non_zero_interruptible(struct semaphore *sem,
+						struct task_struct *tsk)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	ret = 0;
+	if (sem->sleepers > 0) {
+		sem->sleepers--;
+		ret = 1;
+	} else if (signal_pending(tsk)) {
+		atomic_inc(&sem->count);
+		ret = -EINTR;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+/*
+ * waking_non_zero_trylock:
+ *	1	failed to lock
+ *	0	got the lock
+ */
+static inline int waking_non_zero_trylock(struct semaphore *sem)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	ret = 1;
+	if (sem->sleepers <= 0)
+		atomic_inc(&sem->count);
+	else {
+		sem->sleepers--;
+		ret = 0;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/sembuf.h linux-2.4.29-uc1/include/asm-h8300/sembuf.h
--- linux-2.4.29/include/asm-h8300/sembuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/sembuf.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef _H8300_SEMBUF_H
+#define _H8300_SEMBUF_H
+
+/* 
+ * The semid64_ds structure for m68k architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
+	__kernel_time_t	sem_otime;		/* last semop time */
+	unsigned long	__unused1;
+	__kernel_time_t	sem_ctime;		/* last change time */
+	unsigned long	__unused2;
+	unsigned long	sem_nsems;		/* no. of semaphores in array */
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _H8300_SEMBUF_H */
diff -urN linux-2.4.29/include/asm-h8300/setup.h linux-2.4.29-uc1/include/asm-h8300/setup.h
--- linux-2.4.29/include/asm-h8300/setup.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/setup.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1 @@
+/* Nothing do */
diff -urN linux-2.4.29/include/asm-h8300/sh_bios.h linux-2.4.29-uc1/include/asm-h8300/sh_bios.h
--- linux-2.4.29/include/asm-h8300/sh_bios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/sh_bios.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,29 @@
+/* eCos HAL interface header */
+
+#ifndef SH_BIOS_H
+#define SH_BIOS_H
+
+#define HAL_IF_VECTOR_TABLE 0xfffe20
+#define CALL_IF_SET_CONSOLE_COMM  13
+#define QUERY_CURRENT -1
+#define MANGLER       -3
+
+/* Checking for GDB stub active */
+/* suggestion Jonathan Larmour */
+static int sh_bios_in_gdb_mode(void)
+{
+	static int gdb_active = -1;
+	if (gdb_active == -1) {
+		int (*set_console_comm)(int);
+		set_console_comm = ((void **)HAL_IF_VECTOR_TABLE)[CALL_IF_SET_CONSOLE_COMM];
+		gdb_active = (set_console_comm(QUERY_CURRENT) == MANGLER);
+	}
+	return gdb_active;
+}
+
+static void sh_bios_gdb_detach(void)
+{
+
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/shmbuf.h linux-2.4.29-uc1/include/asm-h8300/shmbuf.h
--- linux-2.4.29/include/asm-h8300/shmbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/shmbuf.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,42 @@
+#ifndef _H8300_SHMBUF_H
+#define _H8300_SHMBUF_H
+
+/* 
+ * The shmid64_ds structure for m68k architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	unsigned long		__unused1;
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	unsigned long		__unused2;
+	__kernel_time_t		shm_ctime;	/* last change time */
+	unsigned long		__unused3;
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _H8300_SHMBUF_H */
diff -urN linux-2.4.29/include/asm-h8300/shm.h linux-2.4.29-uc1/include/asm-h8300/shm.h
--- linux-2.4.29/include/asm-h8300/shm.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/shm.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,32 @@
+#ifndef _H8300_SHM_H
+#define _H8300_SHM_H
+
+#include <linux/config.h>
+
+/* format of page table entries that correspond to shared memory pages
+   currently out in swap space (see also mm/swap.c):
+   bits 0-1 (PAGE_PRESENT) is  = 0
+   bits 8..2 (SWP_TYPE) are = SHM_SWP_TYPE
+   bits 31..9 are used like this:
+   bits 15..9 (SHM_ID) the id of the shared memory segment
+   bits 30..16 (SHM_IDX) the index of the page within the shared memory segment
+                    (actually only bits 25..16 get used since SHMMAX is so low)
+   bit 31 (SHM_READ_ONLY) flag whether the page belongs to a read-only attach
+*/
+/* on the m68k both bits 0 and 1 must be zero */
+/* format on the sun3 is similar, but bits 30, 31 are set to zero and all
+   others are reduced by 2. --m */
+
+#ifndef CONFIG_SUN3
+#define SHM_ID_SHIFT	9
+#else
+#define SHM_ID_SHIFT	7
+#endif
+#define _SHM_ID_BITS	7
+#define SHM_ID_MASK	((1<<_SHM_ID_BITS)-1)
+
+#define SHM_IDX_SHIFT	(SHM_ID_SHIFT+_SHM_ID_BITS)
+#define _SHM_IDX_BITS	15
+#define SHM_IDX_MASK	((1<<_SHM_IDX_BITS)-1)
+
+#endif /* _H8300_SHM_H */
diff -urN linux-2.4.29/include/asm-h8300/shmparam.h linux-2.4.29-uc1/include/asm-h8300/shmparam.h
--- linux-2.4.29/include/asm-h8300/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/shmparam.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef _H8300_SHMPARAM_H
+#define _H8300_SHMPARAM_H
+
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
+
+#endif /* _H8300_SHMPARAM_H */
diff -urN linux-2.4.29/include/asm-h8300/sigcontext.h linux-2.4.29-uc1/include/asm-h8300/sigcontext.h
--- linux-2.4.29/include/asm-h8300/sigcontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/sigcontext.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,16 @@
+#ifndef _ASM_H8300_SIGCONTEXT_H
+#define _ASM_H8300_SIGCONTEXT_H
+
+struct sigcontext {
+	unsigned long  sc_mask; 	/* old sigmask */
+	unsigned long  sc_usp;		/* old user stack pointer */
+	unsigned long  sc_er0;
+	unsigned long  sc_er1;
+	unsigned long  sc_er2;
+	unsigned long  sc_er3;
+	unsigned long  sc_er5;
+	unsigned short sc_ccr;
+	unsigned long  sc_pc;
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/siginfo.h linux-2.4.29-uc1/include/asm-h8300/siginfo.h
--- linux-2.4.29/include/asm-h8300/siginfo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/siginfo.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,243 @@
+#ifndef _H8300_SIGINFO_H
+#define _H8300_SIGINFO_H
+
+#include <linux/types.h>
+
+/* This is copied from asm-alpha/siginfo.h.  */
+
+typedef union sigval {
+	int sival_int;
+	void *sival_ptr;
+} sigval_t;
+
+#define SI_MAX_SIZE	128
+#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct siginfo {
+	int si_signo;
+	int si_errno;
+	int si_code;
+
+	union {
+		int _pad[SI_PAD_SIZE];
+
+		/* kill() */
+		struct {
+			__kernel_pid_t _pid;	/* sender's pid */
+			__kernel_uid_t _uid;	/* backwards compatibility */
+			__kernel_uid32_t _uid32; /* sender's uid */
+		} _kill;
+
+		/* POSIX.1b timers */
+		struct {
+			unsigned int _timer1;
+			unsigned int _timer2;
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			__kernel_pid_t _pid;	/* sender's pid */
+			__kernel_uid_t _uid;	/* backwards compatibility */
+			sigval_t _sigval;
+			__kernel_uid32_t _uid32; /* sender's uid */
+		} _rt;
+
+		/* SIGCHLD */
+		struct {
+			__kernel_pid_t _pid;	/* which child */
+			__kernel_uid_t _uid;	/* backwards compatibility */
+			int _status;		/* exit code */
+			clock_t _utime;
+			clock_t _stime;
+			__kernel_uid32_t _uid32; /* sender's uid */
+		} _sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			void *_addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+	} _sifields;
+} siginfo_t;
+
+#define UID16_SIGINFO_COMPAT_NEEDED
+
+/*
+ * How these fields are to be accessed.
+ */
+#define si_pid		_sifields._kill._pid
+#ifdef __KERNEL__
+#define si_uid		_sifields._kill._uid32
+#define si_uid16	_sifields._kill._uid
+#else
+#define si_uid		_sifields._kill._uid
+#endif /* __KERNEL__ */
+#define si_status	_sifields._sigchld._status
+#define si_utime	_sifields._sigchld._utime
+#define si_stime	_sifields._sigchld._stime
+#define si_value	_sifields._rt._sigval
+#define si_int		_sifields._rt._sigval.sival_int
+#define si_ptr		_sifields._rt._sigval.sival_ptr
+#define si_addr		_sifields._sigfault._addr
+#define si_band		_sifields._sigpoll._band
+#define si_fd		_sifields._sigpoll._fd
+
+#ifdef __KERNEL__
+#define __SI_MASK	0xffff0000
+#define __SI_KILL	(0 << 16)
+#define __SI_TIMER	(1 << 16)
+#define __SI_POLL	(2 << 16)
+#define __SI_FAULT	(3 << 16)
+#define __SI_CHLD	(4 << 16)
+#define __SI_RT		(5 << 16)
+#define __SI_CODE(T,N)	((T) << 16 | ((N) & 0xffff))
+#else
+#define __SI_KILL	0
+#define __SI_TIMER	0
+#define __SI_POLL	0
+#define __SI_FAULT	0
+#define __SI_CHLD	0
+#define __SI_RT		0
+#define __SI_CODE(T,N)	(N)
+#endif
+
+/*
+ * si_code values
+ * Digital reserves positive values for kernel-generated signals.
+ */
+#define SI_USER		0		/* sent by kill, sigsend, raise */
+#define SI_KERNEL	0x80		/* sent by the kernel from somewhere */
+#define SI_QUEUE	-1		/* sent by sigqueue */
+#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
+#define SI_MESGQ	-3		/* sent by real time mesq state change */
+#define SI_ASYNCIO	-4		/* sent by AIO completion */
+#define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
+
+#define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
+#define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
+
+/*
+ * SIGILL si_codes
+ */
+#define ILL_ILLOPC	(__SI_FAULT|1)	/* illegal opcode */
+#define ILL_ILLOPN	(__SI_FAULT|2)	/* illegal operand */
+#define ILL_ILLADR	(__SI_FAULT|3)	/* illegal addressing mode */
+#define ILL_ILLTRP	(__SI_FAULT|4)	/* illegal trap */
+#define ILL_PRVOPC	(__SI_FAULT|5)	/* privileged opcode */
+#define ILL_PRVREG	(__SI_FAULT|6)	/* privileged register */
+#define ILL_COPROC	(__SI_FAULT|7)	/* coprocessor error */
+#define ILL_BADSTK	(__SI_FAULT|8)	/* internal stack error */
+#define NSIGILL		8
+
+/*
+ * SIGFPE si_codes
+ */
+#define FPE_INTDIV	(__SI_FAULT|1)	/* integer divide by zero */
+#define FPE_INTOVF	(__SI_FAULT|2)	/* integer overflow */
+#define FPE_FLTDIV	(__SI_FAULT|3)	/* floating point divide by zero */
+#define FPE_FLTOVF	(__SI_FAULT|4)	/* floating point overflow */
+#define FPE_FLTUND	(__SI_FAULT|5)	/* floating point underflow */
+#define FPE_FLTRES	(__SI_FAULT|6)	/* floating point inexact result */
+#define FPE_FLTINV	(__SI_FAULT|7)	/* floating point invalid operation */
+#define FPE_FLTSUB	(__SI_FAULT|8)	/* subscript out of range */
+#define NSIGFPE		8
+
+/*
+ * SIGSEGV si_codes
+ */
+#define SEGV_MAPERR	(__SI_FAULT|1)	/* address not mapped to object */
+#define SEGV_ACCERR	(__SI_FAULT|2)	/* invalid permissions for mapped object */
+#define NSIGSEGV	2
+
+/*
+ * SIGBUS si_codes
+ */
+#define BUS_ADRALN	(__SI_FAULT|1)	/* invalid address alignment */
+#define BUS_ADRERR	(__SI_FAULT|2)	/* non-existant physical address */
+#define BUS_OBJERR	(__SI_FAULT|3)	/* object specific hardware error */
+#define NSIGBUS		3
+
+/*
+ * SIGTRAP si_codes
+ */
+#define TRAP_BRKPT	(__SI_FAULT|1)	/* process breakpoint */
+#define TRAP_TRACE	(__SI_FAULT|2)	/* process trace trap */
+#define NSIGTRAP	2
+
+/*
+ * SIGCHLD si_codes
+ */
+#define CLD_EXITED	(__SI_CHLD|1)	/* child has exited */
+#define CLD_KILLED	(__SI_CHLD|2)	/* child was killed */
+#define CLD_DUMPED	(__SI_CHLD|3)	/* child terminated abnormally */
+#define CLD_TRAPPED	(__SI_CHLD|4)	/* traced child has trapped */
+#define CLD_STOPPED	(__SI_CHLD|5)	/* child has stopped */
+#define CLD_CONTINUED	(__SI_CHLD|6)	/* stopped child has continued */
+#define NSIGCHLD	6
+
+/*
+ * SIGPOLL si_codes
+ */
+#define POLL_IN		(__SI_POLL|1)	/* data input available */
+#define POLL_OUT	(__SI_POLL|2)	/* output buffers available */
+#define POLL_MSG	(__SI_POLL|3)	/* input message available */
+#define POLL_ERR	(__SI_POLL|4)	/* i/o error */
+#define POLL_PRI	(__SI_POLL|5)	/* high priority input available */
+#define POLL_HUP	(__SI_POLL|6)	/* device disconnected */
+#define NSIGPOLL	6
+
+/*
+ * sigevent definitions
+ * 
+ * It seems likely that SIGEV_THREAD will have to be handled from 
+ * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
+ * thread manager then catches and does the appropriate nonsense.
+ * However, everything is written out here so as to not get lost.
+ */
+#define SIGEV_SIGNAL	0	/* notify via signal */
+#define SIGEV_NONE	1	/* other notification: meaningless */
+#define SIGEV_THREAD	2	/* deliver via thread creation */
+
+#define SIGEV_MAX_SIZE	64
+#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct sigevent {
+	sigval_t sigev_value;
+	int sigev_signo;
+	int sigev_notify;
+	union {
+		int _pad[SIGEV_PAD_SIZE];
+
+		struct {
+			void (*_function)(sigval_t);
+			void *_attribute;	/* really pthread_attr_t */
+		} _sigev_thread;
+	} _sigev_un;
+} sigevent_t;
+
+#define sigev_notify_function	_sigev_un._sigev_thread._function
+#define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
+
+#ifdef __KERNEL__
+#include <linux/string.h>
+
+extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
+{
+	if (from->si_code < 0)
+		memcpy(to, from, sizeof(siginfo_t));
+	else
+		/* _sigchld is currently the largest know union member */
+		memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
+}
+
+extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
+
+#endif /* __KERNEL__ */
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/signal.h linux-2.4.29-uc1/include/asm-h8300/signal.h
--- linux-2.4.29/include/asm-h8300/signal.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/signal.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,181 @@
+#ifndef _H8300_SIGNAL_H
+#define _H8300_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#ifdef __KERNEL__
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE		SA_ONESHOT
+#define SA_SAMPLE_RANDOM	SA_RESTART
+#define SA_SHIRQ		0x04000000
+#endif
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+#ifdef __KERNEL__
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+
+#include <asm/sigcontext.h>
+#undef __HAVE_ARCH_SIG_BITOPS
+
+#endif /* __KERNEL__ */
+
+#endif /* _H8300_SIGNAL_H */
diff -urN linux-2.4.29/include/asm-h8300/smp.h linux-2.4.29-uc1/include/asm-h8300/smp.h
--- linux-2.4.29/include/asm-h8300/smp.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/smp.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1 @@
+/* nothing required here yet */
diff -urN linux-2.4.29/include/asm-h8300/smplock.h linux-2.4.29-uc1/include/asm-h8300/smplock.h
--- linux-2.4.29/include/asm-h8300/smplock.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/smplock.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,51 @@
+/*
+ * <asm/smplock.h>
+ *
+ * Default SMP lock implementation
+ */
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+extern spinlock_t kernel_flag;
+
+#define kernel_locked()		spin_is_locked(&kernel_flag)
+
+/*
+ * Release global kernel lock and global interrupt lock
+ */
+#define release_kernel_lock(task, cpu) \
+do { \
+	if (task->lock_depth >= 0) \
+		spin_unlock(&kernel_flag); \
+	release_irqlock(cpu); \
+	__sti(); \
+} while (0)
+
+/*
+ * Re-acquire the kernel lock
+ */
+#define reacquire_kernel_lock(task) \
+do { \
+	if (task->lock_depth >= 0) \
+		spin_lock(&kernel_flag); \
+} while (0)
+
+
+/*
+ * Getting the big kernel lock.
+ *
+ * This cannot happen asynchronously,
+ * so we only need to worry about other
+ * CPU's.
+ */
+extern __inline__ void lock_kernel(void)
+{
+	if (!++current->lock_depth)
+		spin_lock(&kernel_flag);
+}
+
+extern __inline__ void unlock_kernel(void)
+{
+	if (--current->lock_depth < 0)
+		spin_unlock(&kernel_flag);
+}
diff -urN linux-2.4.29/include/asm-h8300/socket.h linux-2.4.29-uc1/include/asm-h8300/socket.h
--- linux-2.4.29/include/asm-h8300/socket.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/socket.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,64 @@
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED	16
+#define SO_PEERCRED	17
+#define SO_RCVLOWAT	18
+#define SO_SNDLOWAT	19
+#define SO_RCVTIMEO	20
+#define SO_SNDTIMEO	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE	25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME             28
+#define SO_TIMESTAMP		29
+#define SCM_TIMESTAMP		SO_TIMESTAMP
+
+#define SO_ACCEPTCONN		30
+
+/* Nast libc5 fixup - bletch */
+#if defined(__KERNEL__)
+/* Socket types. */
+#define SOCK_STREAM	1		/* stream (connection) socket	*/
+#define SOCK_DGRAM	2		/* datagram (conn.less) socket	*/
+#define SOCK_RAW	3		/* raw socket			*/
+#define SOCK_RDM	4		/* reliably-delivered message	*/
+#define SOCK_SEQPACKET	5		/* sequential packet socket	*/
+#define SOCK_PACKET	10		/* linux specific way of	*/
+					/* getting packets at the dev	*/
+					/* level.  For writing rarp and	*/
+					/* other similar things on the	*/
+					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
+#endif
+
+#endif /* _ASM_SOCKET_H */
diff -urN linux-2.4.29/include/asm-h8300/sockios.h linux-2.4.29-uc1/include/asm-h8300/sockios.h
--- linux-2.4.29/include/asm-h8300/sockios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/sockios.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef __ARCH_H8300_SOCKIOS__
+#define __ARCH_H8300_SOCKIOS__
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 	0x8901
+#define SIOCSPGRP	0x8902
+#define FIOGETOWN	0x8903
+#define SIOCGPGRP	0x8904
+#define SIOCATMARK	0x8905
+#define SIOCGSTAMP	0x8906		/* Get stamp */
+
+#endif /* __ARCH_H8300_SOCKIOS__ */
diff -urN linux-2.4.29/include/asm-h8300/softirq.h linux-2.4.29-uc1/include/asm-h8300/softirq.h
--- linux-2.4.29/include/asm-h8300/softirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/softirq.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,19 @@
+#ifndef __H8300_SOFTIRQ_H
+#define __H8300_SOFTIRQ_H
+
+#include <asm/atomic.h>
+#include <asm/hardirq.h>
+
+#define __cpu_bh_enable(cpu) \
+		do { barrier(); local_bh_count(cpu)--; } while (0)
+#define cpu_bh_disable(cpu) \
+		do { local_bh_count(cpu)++; barrier(); } while (0)
+
+#define local_bh_disable()	cpu_bh_disable(smp_processor_id())
+#define __local_bh_enable()	__cpu_bh_enable(smp_processor_id())
+
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
+
+#define local_bh_enable() __local_bh_enable()
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/spinlock.h linux-2.4.29-uc1/include/asm-h8300/spinlock.h
--- linux-2.4.29/include/asm-h8300/spinlock.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/spinlock.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __H8300_SPINLOCK_H
+#define __H8300_SPINLOCK_H
+
+#error "H8/300 doesn't do SMP yet"
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/statfs.h linux-2.4.29-uc1/include/asm-h8300/statfs.h
--- linux-2.4.29/include/asm-h8300/statfs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/statfs.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef _H8300_STATFS_H
+#define _H8300_STATFS_H
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t	fsid_t;
+
+#endif
+
+struct statfs {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_spare[6];
+};
+
+#endif /* _H8300_STATFS_H */
diff -urN linux-2.4.29/include/asm-h8300/stat.h linux-2.4.29-uc1/include/asm-h8300/stat.h
--- linux-2.4.29/include/asm-h8300/stat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/stat.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,80 @@
+#ifndef _H8300_STAT_H
+#define _H8300_STAT_H
+
+struct __old_kernel_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+struct stat {
+	unsigned short st_dev;
+	unsigned short __pad1;
+	unsigned long st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned short __pad2;
+	unsigned long  st_size;
+	unsigned long  st_blksize;
+	unsigned long  st_blocks;
+	unsigned long  st_atime;
+	unsigned long  __unused1;
+	unsigned long  st_mtime;
+	unsigned long  __unused2;
+	unsigned long  st_ctime;
+	unsigned long  __unused3;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat64 {
+	unsigned char	__pad0[6];
+	unsigned short	st_dev;
+	unsigned char	__pad1[2];
+
+#define STAT64_HAS_BROKEN_ST_INO	1
+	unsigned long	__st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned char	__pad2[6];
+	unsigned short	st_rdev;
+	unsigned char	__pad3[2];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+
+	unsigned long	st_atime;
+	unsigned long	__pad5;
+
+	unsigned long	st_mtime;
+	unsigned long	__pad6;
+
+	unsigned long	st_ctime;
+	unsigned long	__pad7;		/* will be high 32 bits of ctime someday */
+
+	unsigned long long	st_ino;
+};
+
+#endif /* _H8300_STAT_H */
diff -urN linux-2.4.29/include/asm-h8300/string.h linux-2.4.29-uc1/include/asm-h8300/string.h
--- linux-2.4.29/include/asm-h8300/string.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/string.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,44 @@
+#ifndef _H8300_STRING_H_
+#define _H8300_STRING_H_
+
+#ifdef __KERNEL__ /* only set these up for kernel code */
+
+#include <asm/setup.h>
+#include <asm/page.h>
+
+#define __HAVE_ARCH_MEMSET
+extern void * memset(void * s, int c, size_t count);
+
+#define __HAVE_ARCH_MEMCPY
+extern void * memcpy(void *d, const void *s, size_t count);
+
+#else /* KERNEL */
+
+/*
+ *	let user libraries deal with these,
+ *	IMHO the kernel has no place defining these functions for user apps
+ */
+
+#define __HAVE_ARCH_STRCPY 1
+#define __HAVE_ARCH_STRNCPY 1
+#define __HAVE_ARCH_STRCAT 1
+#define __HAVE_ARCH_STRNCAT 1
+#define __HAVE_ARCH_STRCMP 1
+#define __HAVE_ARCH_STRNCMP 1
+#define __HAVE_ARCH_STRNICMP 1
+#define __HAVE_ARCH_STRCHR 1
+#define __HAVE_ARCH_STRRCHR 1
+#define __HAVE_ARCH_STRSTR 1
+#define __HAVE_ARCH_STRLEN 1
+#define __HAVE_ARCH_STRNLEN 1
+#define __HAVE_ARCH_MEMSET 1
+#define __HAVE_ARCH_MEMCPY 1
+#define __HAVE_ARCH_MEMMOVE 1
+#define __HAVE_ARCH_MEMSCAN 1
+#define __HAVE_ARCH_MEMCMP 1
+#define __HAVE_ARCH_MEMCHR 1
+#define __HAVE_ARCH_STRTOK 1
+
+#endif /* KERNEL */
+
+#endif /* _M68K_STRING_H_ */
diff -urN linux-2.4.29/include/asm-h8300/system.h linux-2.4.29-uc1/include/asm-h8300/system.h
--- linux-2.4.29/include/asm-h8300/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/system.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,145 @@
+#ifndef _H8300_SYSTEM_H
+#define _H8300_SYSTEM_H
+
+#include <linux/config.h> /* get configuration macros */
+#include <linux/linkage.h>
+
+#define prepare_to_switch()	do { } while(0)
+
+/*
+ * switch_to(n) should switch tasks to task ptr, first checking that
+ * ptr isn't the current task, in which case it does nothing.  This
+ * also clears the TS-flag if the task we switched to has used the
+ * math co-processor latest.
+ */
+/*
+ * switch_to() saves the extra registers, that are not saved
+ * automatically by SAVE_SWITCH_STACK in resume(), ie. d0-d5 and
+ * a0-a1. Some of these are used by schedule() and its predecessors
+ * and so we might get see unexpected behaviors when a task returns
+ * with unexpected register values.
+ *
+ * syscall stores these registers itself and none of them are used
+ * by syscall after the function in the syscall has been called.
+ *
+ * Beware that resume now expects *next to be in d1 and the offset of
+ * tss to be in a1. This saves a few instructions as we no longer have
+ * to push them onto the stack and read them back right after.
+ *
+ * 02/17/96 - Jes Sorensen (jds@kom.auc.dk)
+ *
+ * Changed 96/09/19 by Andreas Schwab
+ * pass prev in a0, next in a1, offset of tss in d1, and whether
+ * the mm structures are shared in d2 (to avoid atc flushing).
+ *
+ * H8/300 Porting 2002/09/04 Yoshinori Sato
+ */
+asmlinkage void resume(void);
+#define switch_to(prev,next,last) { \
+  void *_last;								        \
+  __asm__ __volatile__(								\
+  			"mov.l	%1, er0\n\t"					\
+			"mov.l	%2, er1\n\t"					\
+			"jsr @_" SYMBOL_NAME_STR(resume) "\n\t"                 \
+			"mov.l	er2, %0\n\t"					\
+		       : "=r" (_last)						\
+		       : "r" (prev),						\
+			 "r" (next)						\
+		       : "cc", "er0", "er1", "er2", "er3");	                \
+  (last) = _last; 								\
+}
+
+#define __sti() asm volatile ("andc #0x7f,ccr")
+#define __cli() asm volatile ("orc  #0x80,ccr")
+
+#define __save_flags(x) \
+       asm volatile ("stc ccr,%w0":"=r" (x))
+
+#define __restore_flags(x) \
+       asm volatile ("ldc %w0,ccr": :"r" (x))
+
+#define	__save_and_cli(flags) do { save_flags(flags); cli(); } while(0) 
+#define	__save_and_sti(flags) do { save_flags(flags); sti(); } while(0) 
+
+#define iret() __asm__ __volatile__ ("rte": : :"memory", "sp", "cc")
+
+/* For spinlocks etc */
+#define local_irq_save(x)	({ __save_flags(x); __cli(); })
+#define local_irq_set(x)	({ __save_flags(x); __sti(); })
+#define local_irq_restore(x)	__restore_flags(x)
+#define local_irq_disable()	__cli()
+#define local_irq_enable()	__sti()
+
+#define cli()			__cli()
+#define sti()			__sti()
+#define save_flags(x)		__save_flags(x)
+#define restore_flags(x)	__restore_flags(x)
+#define save_and_cli(x)	__save_and_cli(x)
+#define save_and_set(x)	__save_and_sti(x)
+
+/*
+ * Force strict CPU ordering.
+ * Not really required on h8...
+ */
+#define nop()  asm volatile ("nop"::)
+#define mb()   asm volatile (""   : : :"memory")
+#define rmb()  asm volatile (""   : : :"memory")
+#define wmb()  asm volatile (""   : : :"memory")
+#define set_mb(var, value)     do { var = value; mb(); } while (0)
+#define set_wmb(var, value)    do { var = value; wmb(); } while (0)
+
+#ifdef CONFIG_SMP
+#define smp_mb()	mb()
+#define smp_rmb()	rmb()
+#define smp_wmb()	wmb()
+#else
+#define smp_mb()	barrier()
+#define smp_rmb()	barrier()
+#define smp_wmb()	barrier()
+#endif
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+#define tas(ptr) (xchg((ptr),1))
+
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((volatile struct __xchg_dummy *)(x))
+
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+  unsigned long tmp, flags;
+
+  save_flags(flags);
+  cli();
+
+  switch (size) {
+  case 1:
+    __asm__ __volatile__
+    ("mov.b %2,%0\n\t"
+     "mov.b %1,%2"
+    : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "er0","memory");
+    break;
+  case 2:
+    __asm__ __volatile__
+    ("mov.w %2,%0\n\t"
+     "mov.w %1,%2"
+    : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "memory");
+    break;
+  case 4:
+    __asm__ __volatile__
+    ("mov.l %2,%0\n\t"
+     "mov.l %1,%2"
+    : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "memory");
+    break;
+  default:
+    tmp = 0;	  
+  }
+  restore_flags(flags);
+  return tmp;
+}
+
+#define HARD_RESET_NOW() ({		\
+        cli();				\
+        asm("jmp @@0");			\
+})
+
+#endif /* _H8300_SYSTEM_H */
diff -urN linux-2.4.29/include/asm-h8300/target_time.h linux-2.4.29-uc1/include/asm-h8300/target_time.h
--- linux-2.4.29/include/asm-h8300/target_time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/target_time.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,5 @@
+extern int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *));
+extern void platform_timer_eoi(void);
+extern void platform_gettod(unsigned int *year, unsigned int *mon, unsigned int *day, 
+                            unsigned int *hour, unsigned int *min, unsigned int *sec);
+extern unsigned long platform_get_usec(void);
diff -urN linux-2.4.29/include/asm-h8300/termbits.h linux-2.4.29-uc1/include/asm-h8300/termbits.h
--- linux-2.4.29/include/asm-h8300/termbits.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/termbits.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,174 @@
+#ifndef __ARCH_H8300_TERMBITS_H__
+#define __ARCH_H8300_TERMBITS_H__
+
+#include <linux/posix_types.h>
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#define NCCS 19
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IUCLC	0001000
+#define IXON	0002000
+#define IXANY	0004000
+#define IXOFF	0010000
+#define IMAXBEL	0020000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define OLCUC	0000002
+#define ONLCR	0000004
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#define NLDLY	0000400
+#define   NL0	0000000
+#define   NL1	0000400
+#define CRDLY	0003000
+#define   CR0	0000000
+#define   CR1	0001000
+#define   CR2	0002000
+#define   CR3	0003000
+#define TABDLY	0014000
+#define   TAB0	0000000
+#define   TAB1	0004000
+#define   TAB2	0010000
+#define   TAB3	0014000
+#define   XTABS	0014000
+#define BSDLY	0020000
+#define   BS0	0000000
+#define   BS1	0020000
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+#define FFDLY	0100000
+#define   FF0	0000000
+#define   FF1	0100000
+
+/* c_cflag bit meaning */
+#define CBAUD	0010017
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE	0000060
+#define   CS5	0000000
+#define   CS6	0000020
+#define   CS7	0000040
+#define   CS8	0000060
+#define CSTOPB	0000100
+#define CREAD	0000200
+#define PARENB	0000400
+#define PARODD	0001000
+#define HUPCL	0002000
+#define CLOCAL	0004000
+#define CBAUDEX 0010000
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+#define CIBAUD	  002003600000	/* input baud rate (not used) */
+#define CMSPAR	  010000000000		/* mark or space (stick) parity */
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+#define ISIG	0000001
+#define ICANON	0000002
+#define XCASE	0000004
+#define ECHO	0000010
+#define ECHOE	0000020
+#define ECHOK	0000040
+#define ECHONL	0000100
+#define NOFLSH	0000200
+#define TOSTOP	0000400
+#define ECHOCTL	0001000
+#define ECHOPRT	0002000
+#define ECHOKE	0004000
+#define FLUSHO	0010000
+#define PENDIN	0040000
+#define IEXTEN	0100000
+
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* __ARCH_H8300_TERMBITS_H__ */
diff -urN linux-2.4.29/include/asm-h8300/termios.h linux-2.4.29-uc1/include/asm-h8300/termios.h
--- linux-2.4.29/include/asm-h8300/termios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/termios.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,108 @@
+#ifndef _H8300_TERMIOS_H
+#define _H8300_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+ 
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+#ifdef __KERNEL__
+/*	intr=^C		quit=^|		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+#endif
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6	/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14
+#define N_HCI		15  /* Bluetooth HCI UART */
+
+#ifdef __KERNEL__
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+	unsigned short tmp; \
+	get_user(tmp, &(termio)->c_iflag); \
+	(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
+	get_user(tmp, &(termio)->c_oflag); \
+	(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
+	get_user(tmp, &(termio)->c_cflag); \
+	(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
+	get_user(tmp, &(termio)->c_lflag); \
+	(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
+	get_user((termios)->c_line, &(termio)->c_line); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif	/* __KERNEL__ */
+
+#endif /* _H8300_TERMIOS_H */
diff -urN linux-2.4.29/include/asm-h8300/timex.h linux-2.4.29-uc1/include/asm-h8300/timex.h
--- linux-2.4.29/include/asm-h8300/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/timex.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ * linux/include/asm-h8300/timex.h
+ *
+ * m68k architecture timex specifications
+ */
+#ifndef _ASM_H8300_TIMEX_H
+#define _ASM_H8300_TIMEX_H
+
+#define CLOCK_TICK_RATE TIMER_COUNT_CYCLE	
+#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
+#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
+	(1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
+		<< (SHIFT_SCALE-SHIFT_HZ)) / HZ)
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+	return 0;
+}
+
+#define vxtime_lock()		do {} while (0)
+#define vxtime_unlock()		do {} while (0)
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/tlb.h linux-2.4.29-uc1/include/asm-h8300/tlb.h
--- linux-2.4.29/include/asm-h8300/tlb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/tlb.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-generic/tlb.h>
diff -urN linux-2.4.29/include/asm-h8300/traps.h linux-2.4.29-uc1/include/asm-h8300/traps.h
--- linux-2.4.29/include/asm-h8300/traps.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/traps.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,37 @@
+/*
+ *  linux/include/asm-h8300/traps.h
+ *
+ *  Copyright (C) 2003 Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _H8300_TRAPS_H
+#define _H8300_TRAPS_H
+
+extern void system_call(void);
+extern void interrupt_entry(void);
+extern void trace_break(void);
+
+#define JMP_OP 0x5a000000
+#define JSR_OP 0x5e000000
+#define VECTOR(address) ((JMP_OP)|((unsigned long)address))
+#define REDIRECT(address) ((JSR_OP)|((unsigned long)address))
+
+#define TRACE_VEC 5
+
+#define TRAP0_VEC 8
+#define TRAP1_VEC 9
+#define TRAP2_VEC 10
+#define TRAP3_VEC 11
+
+#if defined(__H8300H__)
+#define NR_TRAPS 12
+#endif
+#if defined(__H8300S__)
+#define NR_TRAPS 16
+#endif
+
+#endif /* _H8300_TRAPS_H */
diff -urN linux-2.4.29/include/asm-h8300/types.h linux-2.4.29-uc1/include/asm-h8300/types.h
--- linux-2.4.29/include/asm-h8300/types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/types.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,58 @@
+#ifndef _H8300_TYPES_H
+#define _H8300_TYPES_H
+
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue.  However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ */
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide.  */
+
+typedef u32 dma_addr_t;
+
+#endif /* __KERNEL__ */
+
+#endif /* _H8300_TYPES_H */
diff -urN linux-2.4.29/include/asm-h8300/uaccess.h linux-2.4.29-uc1/include/asm-h8300/uaccess.h
--- linux-2.4.29/include/asm-h8300/uaccess.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/uaccess.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,159 @@
+#ifndef __H8300_UACCESS_H
+#define __H8300_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/segment.h>
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+/* We let the MMU do all checking */
+extern inline int access_ok(int type, const void * addr, unsigned long size)
+{
+#define	RANGE_CHECK_OK(addr, size, lower, upper) \
+	(((addr) >= (lower)) && (((addr) + (size)) < (upper)))
+
+	extern unsigned long _ramend;
+	return(RANGE_CHECK_OK((unsigned long) addr, size, 0L, (unsigned long)&_ramend));
+}
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+	return access_ok(type,addr,size)?0:-EFAULT;
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ */
+
+#define put_user(x, ptr)				\
+({							\
+    int __pu_err = 0;					\
+    typeof(*(ptr)) __pu_val = (x);			\
+    switch (sizeof (*(ptr))) {				\
+    case 1:						\
+    case 2:						\
+    case 4:						\
+        *(ptr) = __pu_val;                                \
+	break;						\
+    case 8:						\
+	memcpy(ptr, &__pu_val, sizeof (*(ptr)));        \
+	break;						\
+    default:						\
+	__pu_err = __put_user_bad();			\
+	break;						\
+    }							\
+    __pu_err;						\
+})
+#define __put_user(x, ptr) put_user(x, ptr)
+
+extern int __put_user_bad(void);
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+
+#define get_user(x, ptr)					\
+({								\
+    int __gu_err = 0;						\
+    typeof(*(ptr)) __gu_val = 0;				\
+    switch (sizeof(*(ptr))) {					\
+    case 1:							\
+    case 2:							\
+    case 4:							\
+	__gu_val = *(ptr);                                        \
+	break;							\
+    case 8:							\
+	memcpy(&__gu_val, ptr, sizeof (*(ptr)));                \
+	break;							\
+    default:							\
+	__gu_val = 0;						\
+	__gu_err = __get_user_bad();				\
+	break;							\
+    }								\
+    (x) = __gu_val;						\
+    __gu_err;							\
+})
+#define __get_user(x, ptr) get_user(x, ptr)
+
+extern int __get_user_bad(void);
+
+extern int __get_user_bad(void);
+
+#define copy_from_user(to, from, n)		(memcpy(to, from, n), 0)
+#define copy_to_user(to, from, n)		(memcpy(to, from, n), 0)
+
+#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
+#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
+
+#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; })
+
+#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; })
+
+/*
+ * Copy a null terminated string from userspace.
+ */
+
+static inline long
+strncpy_from_user(char *dst, const char *src, long count)
+{
+	char *tmp;
+	strncpy(dst, src, count);
+	for (tmp = dst; *tmp && count > 0; tmp++, count--)
+		;
+	return(tmp - dst); /* DAVIDM should we count a NUL ?  check getname */
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 on exception, a value greater than N if too long
+ */
+static inline long strnlen_user(const char *src, long n)
+{
+	return(strlen(src) + 1); /* DAVIDM make safer */
+}
+
+#define strlen_user(str) strnlen_user(str, 32767)
+
+/*
+ * Zero Userspace
+ */
+
+static inline unsigned long
+clear_user(void *to, unsigned long n)
+{
+	memset(to, 0, n);
+    return(0);
+}
+
+#endif /* _H8300_UACCESS_H */
diff -urN linux-2.4.29/include/asm-h8300/ucontext.h linux-2.4.29-uc1/include/asm-h8300/ucontext.h
--- linux-2.4.29/include/asm-h8300/ucontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/ucontext.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,23 @@
+#ifndef _H8300_UCONTEXT_H
+#define _H8300_UCONTEXT_H
+
+typedef int greg_t;
+#define NGREG 10
+typedef greg_t gregset_t[NGREG];
+
+struct mcontext {
+	int version;
+	gregset_t gregs;
+};
+
+#define MCONTEXT_VERSION 1
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct mcontext	  uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/unaligned.h linux-2.4.29-uc1/include/asm-h8300/unaligned.h
--- linux-2.4.29/include/asm-h8300/unaligned.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/unaligned.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,16 @@
+#ifndef __H8300_UNALIGNED_H
+#define __H8300_UNALIGNED_H
+
+#include <linux/config.h>
+
+/* Use memmove here, so gcc does not insert a __builtin_memcpy. */
+
+#define get_unaligned(ptr) \
+  ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
+
+#define put_unaligned(val, ptr)				\
+  ({ __typeof__(*(ptr)) __tmp = (val);			\
+     memmove((ptr), &__tmp, sizeof(*(ptr)));		\
+     (void)0; })
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/unistd.h linux-2.4.29-uc1/include/asm-h8300/unistd.h
--- linux-2.4.29/include/asm-h8300/unistd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/unistd.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,431 @@
+#ifndef _ASM_H8300_UNISTD_H_
+#define _ASM_H8300_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_chown		 16
+#define __NR_break		 17
+#define __NR_oldstat		 18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_umount2		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+#define __NR_oldolduname	 59
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_old_getrlimit	 76
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+#define __NR_ioperm		101
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_olduname		109
+#define __NR_iopl		/* 110 */ not supported
+#define __NR_vhangup		111
+#define __NR_idle		/* 112 */ Obsolete
+#define __NR_vm86		/* 113 */ not supported
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_cacheflush		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl		172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread		180
+#define __NR_pwrite		181
+#define __NR_lchown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_getpmsg		188	/* some people actually want streams */
+#define __NR_putpmsg		189	/* some people actually want streams */
+#define __NR_vfork		190
+#define __NR_getrlimit		191
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_chown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_lchown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+#define __NR_pivot_root		217
+#define __NR_mincore		218
+#define __NR_madvise		219
+#define __NR_madvise1		219	/* delete when C lib stub is removed */
+#define __NR_getdents64		220
+#define __NR_fcntl64		221
+#define __NR_security		223	/* syscall for security modules */
+#define __NR_gettid		224
+#define __NR_readahead		225
+#define __NR_setxattr		226
+#define __NR_lsetxattr		227
+#define __NR_fsetxattr		228
+#define __NR_getxattr		229
+#define __NR_lgetxattr		230
+#define __NR_fgetxattr		231
+#define __NR_listxattr		232
+#define __NR_llistxattr		233
+#define __NR_flistxattr		234
+#define __NR_removexattr	235
+#define __NR_lremovexattr	236
+#define __NR_fremovexattr	237
+#define __NR_tkill		238
+#define __NR_sendfile64		239
+#define __NR_futex		240
+#define __NR_sched_setaffinity	241
+#define __NR_sched_getaffinity	242
+#define __NR_set_thread_area	243
+#define __NR_get_thread_area	244
+#define __NR_io_setup		245
+#define __NR_io_destroy		246
+#define __NR_io_getevents	247
+#define __NR_io_submit		248
+#define __NR_io_cancel		249
+#define __NR_alloc_hugepages	250
+#define __NR_free_hugepages	251
+#define __NR_exit_group		252
+
+/* user-visible error numbers are in the range -1 - -122: see
+   <asm-m68k/errno.h> */
+
+#define __syscall_return(type, res) \
+do { \
+	if ((unsigned long)(res) >= (unsigned long)(-125)) { \
+	/* avoid using res which is declared to be in register d0; \
+	   errno might expand to a function call and clobber it.  */ \
+		int __err = -(res); \
+		errno = __err; \
+		res = -1; \
+	} \
+	return (type) (res); \
+} while (0)
+
+#define _syscall0(type, name)				\
+type name(void)						\
+{							\
+  register long __res __asm__("er0");			\
+  register long _callno __asm__("er0");			\
+  __asm__ __volatile__ ("mov.l %1,er0\n\t"		\
+                        "trapa	#0\n\t"			\
+			: "=r" (__res)			\
+			: "g" (__NR_##name)		\
+			: "cc", "memory");		\
+  __syscall_return(type, __res);			\
+}
+
+#define _syscall1(type, name, atype, a)			\
+type name(atype a)					\
+{							\
+  register long __res __asm__("er0");			\
+  register long _a __asm__("er1");			\
+  _a = a;						\
+  __asm__ __volatile__ ("mov.l %1,er0\n\t"		\
+                        "trapa	#0\n\t"			\
+			: "=r" (__res)			\
+			: "g" (__NR_##name),		\
+			  "g" (_a)			\
+			: "cc", "memory");	 	\
+  __syscall_return(type, __res);			\
+}
+
+#define _syscall2(type, name, atype, a, btype, b)	\
+type name(atype a, btype b)				\
+{							\
+  register long __res __asm__("er0");			\
+  register long _a __asm__("er1");			\
+  register long _b __asm__("er2");			\
+  _a = a;						\
+  _b = b;						\
+  __asm__ __volatile__ ("mov.l %1,er0\n\t"		\
+                        "trapa	#0\n\t"			\
+			: "=r" (__res)			\
+			: "g" (__NR_##name),		\
+			  "g" (_a),			\
+			  "g" (_b)			\
+			: "cc", "memory");	 	\
+  __syscall_return(type, __res);			\
+}
+
+#define _syscall3(type, name, atype, a, btype, b, ctype, c)	\
+type name(atype a, btype b, ctype c)			\
+{							\
+  register long __res __asm__("er0");			\
+  register long _a __asm__("er1");			\
+  register long _b __asm__("er2");			\
+  register long _c __asm__("er3");			\
+  _a = a;						\
+  _b = b;						\
+  _c = c;						\
+  __asm__ __volatile__ ("mov.l %1,er0\n\t"		\
+                        "trapa	#0\n\t"			\
+			: "=r" (__res)			\
+			: "g" (__NR_##name),		\
+			  "g" (_a),			\
+			  "g" (_b),			\
+			  "g" (_c)			\
+			: "cc", "memory");		\
+  __syscall_return(type, __res);			\
+}
+
+#define _syscall4(type, name, atype, a, btype, b,	\
+                  ctype, c, dtype, d)			\
+type name(atype a, btype b, ctype c, dtype d)		\
+{							\
+  register long __res __asm__("er0");			\
+  register long _a __asm__("er1");			\
+  register long _b __asm__("er2");			\
+  register long _c __asm__("er3");			\
+  register long _d __asm__("er4");			\
+  _a = a;						\
+  _b = b;						\
+  _c = c;						\
+  _d = d;						\
+  __asm__ __volatile__ ("mov.l	%1,er0\n\t"		\
+                        "trapa	#0\n\t"			\
+			: "=r" (__res)			\
+			: "g" (__NR_##name),		\
+			  "g" (_a),			\
+			  "g" (_b),			\
+			  "g" (_c),			\
+			  "g" (_d)			\
+			: "cc", "memory");		\
+  __syscall_return(type, __res);			\
+}
+
+#define _syscall5(type, name, atype, a, btype, b,	\
+                  ctype, c, dtype, d, etype, e)		\
+type name(atype a, btype b, ctype c, dtype d, etype e)	\
+{							\
+  register long __res __asm__("er0");			\
+  register long _a __asm__("er1");			\
+  register long _b __asm__("er2");			\
+  register long _c __asm__("er3");			\
+  register long _d __asm__("er4");			\
+  register long _e __asm__("er5");			\
+  _a = a;                                       	\
+  _b = b;                                       	\
+  _c = c;                                       	\
+  _d = d;                                       	\
+  _e = e;                                       	\
+  __asm__ __volatile__ ("mov.l	%1,er0\n\t"		\
+                        "trapa	#0\n\t"			\
+			: "=r" (__res)			\
+			: "g" (__NR_##name),		\
+			  "g" (_a),			\
+			  "g" (_b),			\
+			  "g" (_c),			\
+			  "g" (_d),			\
+			  "g" (_e)			\
+			: "cc", "memory");		\
+  __syscall_return(type, __res);			\
+}
+
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+static inline _syscall0(int,pause)
+static inline _syscall0(int,sync)
+static inline _syscall0(pid_t,setsid)
+static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+static inline _syscall1(int,dup,int,fd)
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+static inline _syscall1(int,close,int,fd)
+static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,delete_module,const char *,name)
+
+static inline pid_t wait(int * wait_stat)
+{
+	return waitpid(-1,wait_stat,0);
+}
+
+#endif
+
+#endif /* _ASM_H8300_UNISTD_H_ */
diff -urN linux-2.4.29/include/asm-h8300/user.h linux-2.4.29-uc1/include/asm-h8300/user.h
--- linux-2.4.29/include/asm-h8300/user.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/user.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,80 @@
+#ifndef _H8300_USER_H
+#define _H8300_USER_H
+
+#include <asm/page.h>
+
+/* Core file format: The core file is written in such a way that gdb
+   can understand it and provide useful information to the user (under
+   linux we use the 'trad-core' bfd).  There are quite a number of
+   obstacles to being able to view the contents of the floating point
+   registers, and until these are solved you will not be able to view the
+   contents of them.  Actually, you can read in the core file and look at
+   the contents of the user struct to find out what the floating point
+   registers contain.
+   The actual file contents are as follows:
+   UPAGE: 1 page consisting of a user struct that tells gdb what is present
+   in the file.  Directly after this is a copy of the task_struct, which
+   is currently not used by gdb, but it may come in useful at some point.
+   All of the registers are stored as part of the upage.  The upage should
+   always be only one page.
+   DATA: The data area is stored.  We use current->end_text to
+   current->brk to pick up all of the user variables, plus any memory
+   that may have been malloced.  No attempt is made to determine if a page
+   is demand-zero or if a page is totally unused, we just cover the entire
+   range.  All of the addresses are rounded in such a way that an integral
+   number of pages is written.
+   STACK: We need the stack information in order to get a meaningful
+   backtrace.  We need to write the data from (esp) to
+   current->start_stack, so we round each of these off in order to be able
+   to write an integer number of pages.
+   The minimum core file size is 3 pages, or 12288 bytes.
+*/
+
+/* This is the old layout of "struct pt_regs" as of Linux 1.x, and
+   is still the layout used by user (the new pt_regs doesn't have
+   all registers). */
+struct user_regs_struct {
+	long er1,er2,er3,er4,er5,er6;
+	long er0;
+	long usp;
+	long orig_er0;
+	long ccr;
+#if defined(__H8300S__)
+	long exr;
+#endif
+	long pc;
+	
+};
+
+	
+/* When the kernel dumps core, it starts by dumping the user struct -
+   this will be used by gdb to figure out where the data and stack segments
+   are within the file, and what virtual addresses to use. */
+struct user{
+/* We start with the registers, to mimic the way that "memory" is returned
+   from the ptrace(3,...) function.  */
+  struct user_regs_struct regs;	/* Where the registers are actually stored */
+/* ptrace does not yet supply these.  Someday.... */
+/* The rest of this junk is to help gdb figure out what goes where */
+  unsigned long int u_tsize;	/* Text segment size (pages). */
+  unsigned long int u_dsize;	/* Data segment size (pages). */
+  unsigned long int u_ssize;	/* Stack segment size (pages). */
+  unsigned long start_code;     /* Starting virtual address of text. */
+  unsigned long start_stack;	/* Starting virtual address of stack area.
+				   This is actually the bottom of the stack,
+				   the top of the stack is always found in the
+				   esp register.  */
+  long int signal;     		/* Signal that caused the core dump. */
+  int reserved;			/* No longer used */
+  struct user_regs_struct *u_ar0;
+				/* Used by gdb to help find the values for */
+				/* the registers. */
+  unsigned long magic;		/* To uniquely identify a core file */
+  char u_comm[32];		/* User command that was responsible */
+};
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+#endif
diff -urN linux-2.4.29/include/asm-h8300/virtconvert.h linux-2.4.29-uc1/include/asm-h8300/virtconvert.h
--- linux-2.4.29/include/asm-h8300/virtconvert.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-h8300/virtconvert.h	2005-06-14 02:11:26.000000000 +0100
@@ -0,0 +1,26 @@
+#ifndef __H8300_VIRT_CONVERT__
+#define __H8300_VIRT_CONVERT__
+
+/*
+ * Macros used for converting between virtual and physical mappings.
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+
+#define mm_ptov(vaddr)		((void *) (vaddr))
+#define mm_vtop(vaddr)		((unsigned long) (vaddr))
+#define phys_to_virt(vaddr)	((void *) (vaddr))
+#define virt_to_phys(vaddr)	((unsigned long) (vaddr))
+
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define page_to_phys(page)	virt_to_phys((void *)__page_address(page))
+
+#endif
+#endif
diff -urN linux-2.4.29/include/asm-i386/fast_timer.h linux-2.4.29-uc1/include/asm-i386/fast_timer.h
--- linux-2.4.29/include/asm-i386/fast_timer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-i386/fast_timer.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,150 @@
+#ifndef __ASM_I386_FAST_TIMER_H
+#define __ASM_I386_FAST_TIMER_H
+
+#include <linux/sched.h>
+#include <asm/io.h>
+
+#if defined(CONFIG_MTD_NETtel)
+
+#define	SC520_CLOCK		1188200
+#define SC520_TIMER_PAGE_ADDR	0xfffef000
+
+static void *fast_timer_mmcrp;
+
+static void fast_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	do_fast_timer();
+}
+
+static void fast_timer_set(void)
+{
+	unsigned long interval;
+
+	/* Setup PIT1 timer */
+	outb(0x74, 0x43);
+	interval = SC520_CLOCK / fast_timer_rate;
+	outb(interval & 0xff, 0x41);
+	outb((interval >> 8) & 0xff, 0x41);
+}
+
+static int __init fast_timer_setup(void)
+{
+	int pageaddr;
+	int offset;
+	volatile unsigned char *pit1map;
+
+	pageaddr = SC520_TIMER_PAGE_ADDR & PAGE_MASK;
+	offset = SC520_TIMER_PAGE_ADDR & ~PAGE_MASK;
+	set_fixmap_nocache(FIX_SC520_TIMER, pageaddr);
+	fast_timer_mmcrp = (void *) fix_to_virt(FIX_SC520_TIMER + offset);
+	if (fast_timer_mmcrp == NULL)
+		return -ENOMEM;
+
+	if (request_irq(15, fast_timer_interrupt, SA_INTERRUPT,
+				"fast timer", NULL))
+		return -EBUSY;
+
+	/* Set up interrupt routing for PIT1 timer to IRQ 15 */
+	pit1map = (volatile unsigned char *) (fast_timer_mmcrp + 0xd21);
+	*pit1map = 0x0a;
+
+	fast_timer_rate = 500;
+	fast_timer_set();
+
+	printk("fast timer: %d Hz, IRQ %d\n", fast_timer_rate, 15);
+	return 0;
+}
+
+static void __exit fast_timer_cleanup(void)
+{
+	volatile unsigned char *pit1map;
+
+	/* Disable interrupt routing for PIT1 timer */
+	pit1map = (volatile unsigned char *) (fast_timer_mmcrp + 0xd21);
+	*pit1map = 0x00;
+
+	free_irq(15, NULL);
+}
+
+#elif defined(CONFIG_MTD_SNAPGEODE)
+
+static void fast_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* Ack RTC periodic interrupt */
+	outb(0xc, 0x70);
+	inb(0x71);
+
+	do_fast_timer();
+}
+
+static void fast_timer_set(void)
+{
+	/* Fixed at 512Hz */
+}
+
+static int __init fast_timer_setup(void)
+{
+	/* We are using the RTC periodic interrupt */
+	if (request_irq(8, fast_timer_interrupt, SA_INTERRUPT,
+				"fast timer", NULL))
+		return -EBUSY;
+
+	/* Set clock to 1.953ms - 512Hz */
+	outb(0xa, 0x70);
+	outb(((inb(0x71) & 0x70) | 0x7), 0x71);
+
+	/* Enable RTC periodic interrupt */
+	outb(0xb, 0x70);
+	outb(((inb(0x71) & 0xf7) | 0x40), 0x71);
+
+	fast_timer_rate = 512;
+	printk("fast timer: %d Hz, IRQ %d\n", fast_timer_rate, 8);
+	return 0;
+}
+
+static void __exit fast_timer_cleanup(void)
+{
+	/* Disable RTC periodic interrupt */
+	outb(0xb, 0x70);
+	outb((inb(0x71) & 0xb7), 0x71);
+}
+
+#else
+
+static struct timer_list fast_timer_list;
+
+static void fast_timer_poll(unsigned long arg)
+{
+	unsigned long timer_status;
+
+	do_fast_timer();
+
+	fast_timer_list.expires = jiffies + 1;
+	add_timer(&fast_timer_list);
+}
+
+static void fast_timer_set(void)
+{
+	/* Fixed at 1 jiffy */
+}
+
+static int __init fast_timer_setup(void)
+{
+	init_timer(&fast_timer_list);
+	fast_timerlist.function = fast_timer_poll;
+	fast_timerlist.data = 0;
+	fast_timerlist.expires = jiffies + 1;
+	add_timer(&fast_timer_list);
+
+	printk("fast timer: %d Hz\n", HZ);
+	return 0;
+}
+
+static void __exit fast_timer_cleanup(void)
+{
+	del_timer(&fast_timer_list);
+}
+
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-i386/fixmap.h linux-2.4.29-uc1/include/asm-i386/fixmap.h
--- linux-2.4.29/include/asm-i386/fixmap.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-i386/fixmap.h	2005-06-14 02:11:27.000000000 +0100
@@ -72,6 +72,9 @@
 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
 	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
 #endif
+#if defined(CONFIG_MTD_NETtel)
+	FIX_SC520_TIMER,
+#endif
 #ifdef CONFIG_ACPI_BOOT
 	FIX_ACPI_BEGIN,
 	FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
diff -urN linux-2.4.29/include/asm-i386/intlat.h linux-2.4.29-uc1/include/asm-i386/intlat.h
--- linux-2.4.29/include/asm-i386/intlat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-i386/intlat.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,100 @@
+#ifndef _INTLAT_H_
+#define _INTLAT_H_
+
+#include <asm/timepeg_slot.h>
+
+#define __save_flags(x)		__asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */ :"memory")
+
+extern void intlat_restore_flags(struct timepeg_slot * _tps, unsigned long x);
+
+#define __restore_flags(x)						\
+	do {								\
+		static struct timepeg_slot _x_Timepeg =			\
+		{							\
+			name: __FILE__,					\
+			line: __LINE__,					\
+			lock: SPIN_LOCK_UNLOCKED,			\
+		};							\
+		intlat_restore_flags(&_x_Timepeg, x);			\
+	} while (0)
+
+extern void intlat_cli(struct timepeg_slot *_tps);
+#define __cli()								\
+	do {								\
+		static struct timepeg_slot _x_Timepeg =			\
+		{							\
+			name: __FILE__,					\
+			line: __LINE__,					\
+			lock: SPIN_LOCK_UNLOCKED,			\
+		};							\
+		intlat_cli(&_x_Timepeg);				\
+	} while (0)
+
+extern void intlat_sti(struct timepeg_slot *_tps);
+#define __sti()								\
+	do {								\
+		static struct timepeg_slot _x_Timepeg =			\
+		{							\
+			name: __FILE__,					\
+			line: __LINE__,					\
+			lock: SPIN_LOCK_UNLOCKED,			\
+		};							\
+		intlat_sti(&_x_Timepeg);				\
+	} while (0)
+
+/* used in the idle loop; sti takes one instruction cycle to complete */
+#define safe_halt()		__asm__ __volatile__("sti; hlt": : :"memory")
+
+extern unsigned long intlat_local_irq_save(struct timepeg_slot *_tps);
+#define local_irq_save(x)						\
+	do {								\
+		static struct timepeg_slot _x_Timepeg =			\
+		{							\
+			name: __FILE__,					\
+			line: __LINE__,					\
+			lock: SPIN_LOCK_UNLOCKED,			\
+		};							\
+		x = intlat_local_irq_save(&_x_Timepeg);			\
+	} while (0)
+
+extern void intlat_local_irq_restore(struct timepeg_slot *_tps, unsigned long _flags);
+#define local_irq_restore(x)						\
+	do {								\
+		static struct timepeg_slot _x_Timepeg =			\
+		{							\
+			name: __FILE__,					\
+			line: __LINE__,					\
+			lock: SPIN_LOCK_UNLOCKED,			\
+		};							\
+		intlat_local_irq_restore(&_x_Timepeg, x);		\
+	} while (0)
+
+extern void intlat_local_irq_disable(struct timepeg_slot *_tps);
+#define local_irq_disable()						\
+	do {								\
+		static struct timepeg_slot _x_Timepeg =			\
+		{							\
+			name: __FILE__,					\
+			line: __LINE__,					\
+			lock: SPIN_LOCK_UNLOCKED,			\
+		};							\
+		intlat_local_irq_disable(&_x_Timepeg);			\
+	} while (0)
+
+extern void intlat_local_irq_enable(struct timepeg_slot *_tps);
+#define local_irq_enable()						\
+	do {								\
+		static struct timepeg_slot _x_Timepeg =			\
+		{							\
+			name: __FILE__,					\
+			line: __LINE__,					\
+			lock: SPIN_LOCK_UNLOCKED,			\
+		};							\
+		intlat_local_irq_enable(&_x_Timepeg);			\
+	} while (0)
+
+extern void intlat_enter_isr(struct timepeg_slot *_tps);
+extern void intlat_exit_isr(struct timepeg_slot *_tps);
+
+#endif	/* _INTLAT_H_ */
+
diff -urN linux-2.4.29/include/asm-i386/ptrace.h linux-2.4.29-uc1/include/asm-i386/ptrace.h
--- linux-2.4.29/include/asm-i386/ptrace.h	2001-09-14 22:04:08.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-i386/ptrace.h	2005-06-14 02:11:27.000000000 +0100
@@ -57,6 +57,7 @@
 #ifdef __KERNEL__
 #define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs))
 #define instruction_pointer(regs) ((regs)->eip)
+#define user_stack(regs) ((regs)->esp)
 extern void show_regs(struct pt_regs *);
 #endif
 
diff -urN linux-2.4.29/include/asm-i386/system.h linux-2.4.29-uc1/include/asm-i386/system.h
--- linux-2.4.29/include/asm-i386/system.h	2004-04-14 14:05:40.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-i386/system.h	2005-06-14 02:11:27.000000000 +0100
@@ -312,6 +312,12 @@
 
 #define set_wmb(var, value) do { var = value; wmb(); } while (0)
 
+#ifdef CONFIG_INTLAT
+
+#include <asm/intlat.h>
+
+#else   /* CONFIG_INTLAT_ */
+
 /* interrupt control.. */
 #define __save_flags(x)		__asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
 #define __restore_flags(x) 	__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc")
@@ -336,6 +342,8 @@
 #define local_irq_disable()	__cli()
 #define local_irq_enable()	__sti()
 
+#endif		/* CONFIG_INTLAT */
+
 #ifdef CONFIG_SMP
 
 extern void __global_cli(void);
diff -urN linux-2.4.29/include/asm-i386/timepeg.h linux-2.4.29-uc1/include/asm-i386/timepeg.h
--- linux-2.4.29/include/asm-i386/timepeg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-i386/timepeg.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,205 @@
+/*
+ * Header for timepeg instrumentation.  See:
+ *
+ * Documentation/timepeg.txt
+ * http://www.uow.edu.au/~andrewm/linux/
+ *
+ * Andrew Morton <andrewm@uow.edu.au>
+ *
+ * Some code and ideas taken from the net profiling code
+ * which was contributed by <insert name here>
+ */
+
+#ifndef _TIMEPEG_H_
+#define _TIMEPEG_H_ 1
+
+#include <linux/config.h> 		/* for CONFIG_TIMEPEG */
+
+#ifdef CONFIG_TIMEPEG
+
+#include <linux/types.h>
+#include <linux/time.h>
+#include <linux/kernel.h>
+#include <asm/system.h>
+#include <linux/spinlock.h>
+#include <linux/threads.h>
+#include <linux/module.h>		/* for EXPORT_SYMBOL */
+#include <linux/cache.h>		/* for __cacheline_aligned */
+#include <asm/current.h>		/* smp_processor_id() needs this */
+#include <linux/sched.h>		/* for struct task_struct */
+#include <linux/smp.h>			/* for smp_proessor_id() */
+#include <asm/atomic.h>
+#ifdef CONFIG_X86_TSC
+#include <asm/msr.h>			/* for rdtsc() */
+#endif
+
+#include <asm/timepeg_slot.h>
+
+#ifdef CONFIG_X86_TSC
+
+extern __inline__ void
+timepeg_stamp(timepeg_t *pstamp)
+{
+	rdtscll(*pstamp);
+}
+
+#else
+
+/* This one is a bit ugly to include inline */
+extern void timepeg_stamp(timepeg_t *pstamp);
+
+/*
+ * The profile stuff uses gettimeofday() here.
+ * Skip it for now.
+ */
+
+//#error Timepegs not supported on this architecture.  Did you configure for a Pentium?
+
+#endif	/* architecture */
+
+#endif	/* CONFIG_TIMEPEG */
+
+
+#ifdef CONFIG_TIMEPEG
+
+/*
+ * This does the real work for timepeg_hit.  It returns a pointer to
+ * the most-recently-departed timepeg_slot_percpu's departure_tp
+ * so that we can update it within the inline code, thus providing
+ * minimal drift.
+ *
+ * Performs once-off on-demand initialisation of the timepeg.
+ */
+
+extern timepeg_t *
+timepeg_do_hit(	struct timepeg_slot * const _ntps,
+		timepeg_t * const _now_tp,
+		const int _mode);
+/*
+ * The main worker function:  execution enters a new timepeg.
+ *
+ * 'mode' is a combination of:
+ *
+ * TPH_MODE_START: this is a 'start' timepeg - mark it in g_prev_slots
+ * TPH_MODE_STOP:  this is a 'stop' timepeh - accumulate predecessor arc.
+ */
+
+#define TPH_MODE_START	1
+#define TPH_MODE_STOP	2
+#define TPH_MODE_BOTH	(TPH_MODE_START | TPH_MODE_STOP)
+
+extern int timepeg_no_recur[NR_CPUS];
+extern int timepegs_are_running;
+extern timepeg_t entered_tp[NR_CPUS];
+
+extern __inline__ void
+timepeg_hit(struct timepeg_slot * const _ntps, const int _mode)
+{
+	if (timepegs_are_running) {
+		const int cpu = smp_processor_id();
+
+		if (timepeg_no_recur[cpu] == 0)
+		{
+			unsigned long flags;
+			timepeg_t *prev_tp;
+
+			timepeg_no_recur[cpu] = 1;
+
+			local_irq_save(flags);
+
+			timepeg_stamp(&entered_tp[cpu]);
+
+			{
+				/*
+				 * Within this block timepeg accounting is 'suspended'.  We
+				 * can spend as long as we like in here and it doesn't
+				 * affect the instrumentation
+				 */
+				prev_tp = timepeg_do_hit(_ntps, &entered_tp[cpu], _mode);
+			}
+
+			if (prev_tp)
+				timepeg_stamp(prev_tp);
+
+			local_irq_restore(flags);
+			timepeg_no_recur[cpu] = 0;
+		}
+	}
+}
+
+/*
+ * timepeg interface macros.  NB: None of macros have
+ * semicolons.
+ */
+#define TIMEPEG_DEFINE(_id_, _M_name)				\
+		static struct timepeg_slot _id_ =		\
+		{						\
+			name: _M_name,				\
+			lock: SPIN_LOCK_UNLOCKED,		\
+		}
+
+/*
+ * Define and hit a timepeg
+ */
+#define TIMEPEG_MODE(_M_name, _M_mode)				\
+	do {							\
+		static struct timepeg_slot _x_Timepeg =		\
+		{						\
+			name: _M_name,				\
+			lock: SPIN_LOCK_UNLOCKED,		\
+		};						\
+		(void)timepeg_hit(&_x_Timepeg, _M_mode);	\
+	} while (0)
+
+/*
+ * With file-and-line
+ */
+
+#define TIMEPEG_MODE_FL(_M_mode)				\
+	do {							\
+		static struct timepeg_slot _x_Timepeg =		\
+		{						\
+			name: __FILE__,				\
+			line: __LINE__,				\
+			lock: SPIN_LOCK_UNLOCKED,		\
+		};						\
+		(void)timepeg_hit(&_x_Timepeg, _M_mode);	\
+	} while (0)
+
+#define TIMEPEG(_M_name)					\
+	TIMEPEG_MODE(_M_name, TPH_MODE_BOTH)
+
+#define TIMEPEG_FL() TIMEPEG_MODE_FL(TPH_MODE_BOTH)
+
+/*
+ * Define and hit a directed timepeg
+ */
+#define DTIMEPEG(_M_name, _M_directed_pred)			\
+	do {							\
+		static struct timepeg_slot _x_Timepeg =		\
+		{						\
+			name: _M_name,				\
+			lock: SPIN_LOCK_UNLOCKED,		\
+			directee_name: _M_directed_pred,	\
+		};						\
+		(void)timepeg_hit(&_x_Timepeg, TPH_MODE_BOTH);	\
+	} while (0)
+
+#else	/* CONFIG_TIMEPEG */
+
+#define TIMEPEG_DEFINE(_id_, _M_name)
+
+#define TIMEPEG_MODE(_M_name, _M_mode)				\
+	do {							\
+	} while (0)
+
+#define TIMEPEG(_M_name)					\
+	do { } while (0)
+
+#define DTIMEPEG(_M_name, _M_directed_pred)			\
+	do { } while (0)
+
+#endif	/* CONFIG_TIMEPEG */
+
+#endif	/* _TIMEPEG_H_ */
+
diff -urN linux-2.4.29/include/asm-i386/timepeg_slot.h linux-2.4.29-uc1/include/asm-i386/timepeg_slot.h
--- linux-2.4.29/include/asm-i386/timepeg_slot.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-i386/timepeg_slot.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,69 @@
+#ifndef _TIMEPEG_SLOT_H_
+#define _TIMEPEG_SLOT_H_
+
+#include <linux/spinlock.h>	/* For spinlock_t */
+#include <linux/threads.h>	/* For NR_CPUS */
+
+/*
+ * A 64 bit counter
+ */
+
+typedef unsigned long long timepeg_t;
+
+/*
+ * The system-wide list of timepeg slots constitutes a directed graph.
+ * This is because a particular slot may have any number of predecessors.
+ * We don't attempt to record all possible predecessors.  We record a finite number.
+ * If a timepeg slot has more than TIMEPEG_SLOT_PREDS predecessors then
+ * XXXX drops some info on the floor
+ */
+
+#define TIMEPEG_NR_PREDS	16
+
+/* Mode bits */
+#define TIMEPEG_MODE_INITIALISED	1	/* It has been constructed */
+#define TIMEPEG_MODE_FULL		2	/* All timepeg arcs in preds[] are used */
+#define TIMEPEG_MODE_DEAD		4	/* Flag: something wrong - ignore this timepeg
+						 * from now on.
+						 */
+
+struct timepeg_slot
+{
+	struct timepeg_slot *next;		/* Singly linked */
+	const char *name;			/* Human readable identifier */
+	short line;				/* File line number */
+	short mode_bits;			/* See above */
+	spinlock_t lock;
+
+	struct timepeg_slot *directed_pred;	/* If it's a directed timepeg, this is the predecessor */
+	const char *directee_name;		/* Name of the timepeg we're directed at */
+
+	/* We logically separate each CPU */
+	struct timepeg_slot_percpu
+	{
+		timepeg_t departure_tp;		/* Most recent time when we hit this timepeg */
+
+		/*
+		 * A simple array of arcs to predecessors
+		 * Each entry represents a predecessor.  That is, a most-recently-called
+		 * TIMEPEG().
+		 */
+		struct timepeg_arc
+		{
+			/* This points at the most-recently-called timepeg */
+			struct timepeg_slot *timepeg;
+
+			/* Accumulated time on this arc */
+			timepeg_t acc_tp;
+
+			/* Best and worst transit times */
+			timepeg_t min_tp, max_tp;
+
+			/* The number of times this arc was used */
+			unsigned long nr_times;
+		} preds[TIMEPEG_NR_PREDS];
+	} percpu[NR_CPUS];
+};
+
+#endif	/* _TIMEPEG_SLOT_H_ */
+
diff -urN linux-2.4.29/include/asm-i386/timex.h linux-2.4.29-uc1/include/asm-i386/timex.h
--- linux-2.4.29/include/asm-i386/timex.h	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-i386/timex.h	2005-06-14 02:11:27.000000000 +0100
@@ -9,11 +9,15 @@
 #include <linux/config.h>
 #include <asm/msr.h>
 
+#ifdef CONFIG_MTD_NETtel
+#define CLOCK_TICK_RATE	1188200 /* Underlying HZ for AMD-SC520 */
+#else
 #ifdef CONFIG_MELAN
 #  define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */
 #else
 #  define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
 #endif
+#endif
 
 #define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
 #define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
diff -urN linux-2.4.29/include/asm-i386/wordops.h linux-2.4.29-uc1/include/asm-i386/wordops.h
--- linux-2.4.29/include/asm-i386/wordops.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-i386/wordops.h	2005-06-14 02:11:27.000000000 +0100
@@ -0,0 +1,20 @@
+#ifndef _I386_WORDOPS_H
+#define _I386_WORDOPS_H
+
+extern __inline__ int rotr32(__u32 x, int n)
+{
+	if (n == 32 || n == 0 || n == -32)
+		return x;
+	__asm__("rorl %1,%0" : "=r"(x) : "ir"(n));
+	return x;
+}
+
+extern __inline__ int rotl32(__u32 x, int n)
+{
+	if (n == 32 || n == 0 || n == -32)
+		return x;
+	__asm__("roll %1,%0" : "=r"(x) : "ir"(n));
+	return x;
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-ia64/div64.h linux-2.4.29-uc1/include/asm-ia64/div64.h
--- linux-2.4.29/include/asm-ia64/div64.h	2000-02-07 02:42:40.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-ia64/div64.h	2005-06-14 02:11:40.000000000 +0100
@@ -1,20 +1 @@
-#ifndef _ASM_IA64_DIV64_H
-#define _ASM_IA64_DIV64_H
-
-/*
- * Copyright (C) 1999 Hewlett-Packard Co
- * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * vsprintf uses this to divide a 64-bit integer N by a small integer BASE.
- * This is incredibly hard on IA-64...
- */
-
-#define do_div(n,base)						\
-({								\
-	int _res;						\
-	_res = ((unsigned long) (n)) % (unsigned) (base);	\
-	(n) = ((unsigned long) (n)) / (unsigned) (base);	\
-	_res;							\
-})
-
-#endif /* _ASM_IA64_DIV64_H */
+#include <asm-generic/div64.h>
diff -urN linux-2.4.29/include/asm-m68k/div64.h linux-2.4.29-uc1/include/asm-m68k/div64.h
--- linux-2.4.29/include/asm-m68k/div64.h	2000-01-26 20:44:21.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-m68k/div64.h	2005-06-14 02:11:33.000000000 +0100
@@ -3,7 +3,6 @@
 
 /* n = n / base; return rem; */
 
-#if 1
 #define do_div(n, base) ({					\
 	union {							\
 		unsigned long n32[2];				\
@@ -23,13 +22,5 @@
 	(n) = __n.n64;						\
 	__rem;							\
 })
-#else
-#define do_div(n,base) ({					\
-	int __res;						\
-	__res = ((unsigned long) n) % (unsigned) base;		\
-	n = ((unsigned long) n) / (unsigned) base;		\
-	__res;							\
-})
-#endif
 
 #endif /* _M68K_DIV64_H */
diff -urN linux-2.4.29/include/asm-m68k/param.h linux-2.4.29-uc1/include/asm-m68k/param.h
--- linux-2.4.29/include/asm-m68k/param.h	2001-01-04 21:00:55.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-m68k/param.h	2005-06-14 02:11:33.000000000 +0100
@@ -2,6 +2,9 @@
 #define _M68K_PARAM_H
 
 #ifndef HZ
+#if defined(CONFIG_HW_FEITH)
+#define HZ 1000
+#else
 #define HZ 100
 #endif
 
diff -urN linux-2.4.29/include/asm-m68k/pci.h linux-2.4.29-uc1/include/asm-m68k/pci.h
--- linux-2.4.29/include/asm-m68k/pci.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-m68k/pci.h	2005-06-14 02:11:33.000000000 +0100
@@ -55,4 +55,31 @@
  */
 #define PCI_DMA_BUS_IS_PHYS	(1)
 
+
+/* Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Once the device is given the dma address, the device owns this memory
+ * until either pci_unmap_single or pci_dma_sync_single is performed.
+ */
+extern inline dma_addr_t
+pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
+{
+	return ptr;
+}
+
+/* Unmap a single streaming mode DMA translation.  The dma_addr and size
+ * must match what was provided for in a previous pci_map_single call.  All
+ * other usages are undefined.
+ *
+ * After this call, reads by the cpu to the buffer are guarenteed to see
+ * whatever the device wrote there.
+ */
+extern inline void
+pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
+{
+	/* nothing to do */
+}
+
+
 #endif /* _ASM_M68K_PCI_H */
diff -urN linux-2.4.29/include/asm-m68knommu/anchor.h linux-2.4.29-uc1/include/asm-m68knommu/anchor.h
--- linux-2.4.29/include/asm-m68knommu/anchor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/anchor.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,112 @@
+/****************************************************************************/
+
+/*
+ *	anchor.h -- Anchor CO-MEM Lite PCI host bridge part.
+ *
+ *	(C) Copyright 2000, Moreton Bay (www.moreton.com.au)
+ */
+
+/****************************************************************************/
+#ifndef	anchor_h
+#define	anchor_h
+/****************************************************************************/
+
+/*
+ *	Define basic addressing info.
+ */
+#if defined(CONFIG_MOTOROLA) && defined(CONFIG_M5407)
+#define	COMEM_BASE	0xFFFF0000	/* Base of CO-MEM address space */
+#define	COMEM_IRQ	25		/* IRQ of anchor part */
+#else
+#define	COMEM_BASE	0x80000000	/* Base of CO-MEM address space */
+#define	COMEM_IRQ	25		/* IRQ of anchor part */
+#endif
+
+/****************************************************************************/
+
+/*
+ *	4-byte registers of CO-MEM, so adjust register addresses for
+ *	easy access. Handy macro for word access too.
+ */
+#define	LREG(a)		((a) >> 2)
+#define	WREG(a)		((a) >> 1)
+
+
+/*
+ *	Define base addresses within CO-MEM Lite register address space.
+ */
+#define	COMEM_I2O	0x0000		/* I2O registers */
+#define	COMEM_OPREGS	0x0400		/* Operation registers */
+#define	COMEM_PCIBUS	0x2000		/* Direct access to PCI bus */
+#define	COMEM_SHMEM	0x4000		/* Shared memory region */
+
+#define	COMEM_SHMEMSIZE	0x4000		/* Size of shared memory */
+
+
+/*
+ *	Define CO-MEM Registers.
+ */
+#define	COMEM_I2OHISR	0x0030		/* I2O host interrupt status */
+#define	COMEM_I2OHIMR	0x0034		/* I2O host interrupt mask */
+#define	COMEM_I2OLISR	0x0038		/* I2O local interrupt status */
+#define	COMEM_I2OLIMR	0x003c		/* I2O local interrupt mask */
+#define	COMEM_IBFPFIFO	0x0040		/* I2O inbound free/post FIFO */
+#define	COMEM_OBPFFIFO	0x0044		/* I2O outbound post/free FIFO */
+#define	COMEM_IBPFFIFO	0x0048		/* I2O inbound post/free FIFO */
+#define	COMEM_OBFPFIFO	0x004c		/* I2O outbound free/post FIFO */
+
+#define	COMEM_DAHBASE	0x0460		/* Direct access base address */
+
+#define	COMEM_NVCMD	0x04a0		/* I2C serial command */
+#define	COMEM_NVREAD	0x04a4		/* I2C serial read */
+#define	COMEM_NVSTAT	0x04a8		/* I2C status */
+
+#define	COMEM_DMALBASE	0x04b0		/* DMA local base address */
+#define	COMEM_DMAHBASE	0x04b4		/* DMA host base address */
+#define	COMEM_DMASIZE	0x04b8		/* DMA size */
+#define	COMEM_DMACTL	0x04bc		/* DMA control */
+
+#define	COMEM_HCTL	0x04e0		/* Host control */
+#define	COMEM_HINT	0x04e4		/* Host interrupt control/status */
+#define	COMEM_HLDATA	0x04e8		/* Host to local data mailbox */
+#define	COMEM_LINT	0x04f4		/* Local interrupt contole status */
+#define	COMEM_LHDATA	0x04f8		/* Local to host data mailbox */
+
+#define	COMEM_LBUSCFG	0x04fc		/* Local bus configuration */
+
+
+/*
+ *	Commands and flags for use with Direct Access Register.
+ */
+#define	COMEM_DA_IACK	0x00000000	/* Interrupt acknowledge (read) */
+#define	COMEM_DA_SPCL	0x00000010	/* Special cycle (write) */
+#define	COMEM_DA_MEMRD	0x00000004	/* Memory read cycle */
+#define	COMEM_DA_MEMWR	0x00000004	/* Memory write cycle */
+#define	COMEM_DA_IORD	0x00000002	/* I/O read cycle */
+#define	COMEM_DA_IOWR	0x00000002	/* I/O write cycle */
+#define	COMEM_DA_CFGRD	0x00000006	/* Configuration read cycle */
+#define	COMEM_DA_CFGWR	0x00000006	/* Configuration write cycle */
+
+#define	COMEM_DA_ADDR(a)	((a) & 0xffffe000)
+
+#define	COMEM_DA_OFFSET(a)	((a) & 0x00001fff)
+
+
+/*
+ *	The PCI bus will be limited in what slots will actually be used.
+ *	Define valid device numbers for different boards.
+ */
+#if defined(CONFIG_MOTOROLA) && defined(CONFIG_M5407)
+#define	COMEM_MINDEV	14		/* Minimum valid DEVICE */
+#define	COMEM_MAXDEV	14		/* Maximum valid DEVICE */
+#define	COMEM_BRIDGEDEV	15		/* Slot bridge is in */
+#else
+#define	COMEM_MINDEV	0		/* Minimum valid DEVICE */
+#define	COMEM_MAXDEV	3		/* Maximum valid DEVICE */
+#endif
+
+#define	COMEM_MAXPCI	(COMEM_MAXDEV+1)	/* Maximum PCI devices */
+
+
+/****************************************************************************/
+#endif	/* anchor_h */
diff -urN linux-2.4.29/include/asm-m68knommu/a.out.h linux-2.4.29-uc1/include/asm-m68knommu/a.out.h
--- linux-2.4.29/include/asm-m68knommu/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/a.out.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/a.out.h>
diff -urN linux-2.4.29/include/asm-m68knommu/atomic.h linux-2.4.29-uc1/include/asm-m68knommu/atomic.h
--- linux-2.4.29/include/asm-m68knommu/atomic.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/atomic.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,117 @@
+#ifndef __ARCH_M68KNOMMU_ATOMIC__
+#define __ARCH_M68KNOMMU_ATOMIC__
+
+#include <asm/system.h>	/* save_and_cli() */
+
+/*
+ * Atomic operations that C can't guarantee us.  Useful for
+ * resource counting etc..
+ */
+
+/*
+ * We do not have SMP m68k systems, so we don't have to deal with that.
+ */
+
+typedef struct { int counter; } atomic_t;
+#define ATOMIC_INIT(i)	{ (i) }
+
+#define atomic_read(v)		((v)->counter)
+#define atomic_set(v, i)	(((v)->counter) = i)
+
+#ifdef CONFIG_COLDFIRE
+
+static __inline__ void atomic_add(int i, atomic_t *v)
+{
+	__asm__ __volatile__(
+		"movel %1,%%d0\t\n"
+		"addl %%d0,%0"
+		:
+		: "m" (*v), "id" (i)
+		: "d0");
+}
+
+static __inline__ void atomic_sub(int i, atomic_t *v)
+{
+	__asm__ __volatile__(
+		"movel %1,%%d0\t\n"
+		"subl %%d0,%0"
+		:
+		: "m" (*v), "id" (i)
+		: "d0");
+}
+
+#else
+
+static __inline__ void atomic_add(int i, atomic_t *v)
+{
+	__asm__ __volatile__("addl %1,%0" : "=m" (*v) : "d" (i), "0" (*v));
+}
+
+static __inline__ void atomic_sub(int i, atomic_t *v)
+{
+	__asm__ __volatile__("subl %1,%0" : "=m" (*v) : "d" (i), "0" (*v));
+}
+
+#endif /* COLDFIRE */
+
+static __inline__ void atomic_inc(volatile atomic_t *v)
+{
+	__asm__ __volatile__("addql #1,%0" : "=m" (*v): "0" (*v));
+}
+
+static __inline__ void atomic_dec(volatile atomic_t *v)
+{
+	__asm__ __volatile__("subql #1,%0" : "=m" (*v): "0" (*v));
+}
+
+static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
+{
+	char c;
+	__asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c), "=m" (*v): "1" (*v));
+	return c != 0;
+}
+
+#define atomic_clear_mask(mask, v) \
+	__asm__ __volatile__("andl %1,%0" : "=m" (*v) : "id" (~(mask)),"0"(*v))
+
+#define atomic_set_mask(mask, v) \
+	__asm__ __volatile__("orl %1,%0" : "=m" (*v) : "id" (mask),"0"(*v))
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec()    barrier()
+#define smp_mb__after_atomic_dec() barrier()
+#define smp_mb__before_atomic_inc()    barrier()
+#define smp_mb__after_atomic_inc() barrier()
+
+extern __inline__ int atomic_add_return(int i, atomic_t * v)
+{
+	unsigned long temp, flags;
+
+	save_and_cli(flags);
+	temp = *(long *)v;
+	temp += i;
+	*(long *)v = temp;
+	restore_flags(flags);
+
+	return temp;
+}
+
+extern __inline__ int atomic_sub_return(int i, atomic_t * v)
+{
+	unsigned long temp, flags;
+
+	save_and_cli(flags);
+	temp = *(long *)v;
+	temp -= i;
+	*(long *)v = temp;
+	restore_flags(flags);
+
+	return temp;
+}
+
+#define atomic_dec_return(v) atomic_sub_return(1,(v))
+#define atomic_inc_return(v) atomic_add_return(1,(v))
+
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+
+#endif /* __ARCH_M68KNOMMU_ATOMIC __ */
diff -urN linux-2.4.29/include/asm-m68knommu/bitops.h linux-2.4.29-uc1/include/asm-m68knommu/bitops.h
--- linux-2.4.29/include/asm-m68knommu/bitops.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/bitops.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,388 @@
+#ifndef _M68KNOMMU_BITOPS_H
+#define _M68KNOMMU_BITOPS_H
+
+/*
+ * Copyright 1992, Linus Torvalds.
+ */
+
+#include <linux/config.h>
+#include <asm/byteorder.h>	/* swab32 */
+#include <asm/system.h>		/* save_flags */
+
+#ifdef __KERNEL__
+/*
+ * Function prototypes to keep gcc -Wall happy
+ */
+
+/*
+ * The __ functions are not atomic
+ */
+
+extern void set_bit(int nr, volatile void * addr);
+extern void __set_bit(int nr, volatile void * addr);
+extern void clear_bit(int nr, volatile void * addr);
+extern void change_bit(int nr, volatile void * addr);
+extern void __change_bit(int nr, volatile void * addr);
+extern int test_and_set_bit(int nr, volatile void * addr);
+extern int __test_and_set_bit(int nr, volatile void * addr);
+extern int test_and_clear_bit(int nr, volatile void * addr);
+extern int __test_and_clear_bit(int nr, volatile void * addr);
+extern int test_and_change_bit(int nr, volatile void * addr);
+extern int __test_and_change_bit(int nr, volatile void * addr);
+extern int __constant_test_bit(int nr, const volatile void * addr);
+extern int __test_bit(int nr, volatile void * addr);
+extern int find_first_zero_bit(void * addr, unsigned size);
+extern int find_next_zero_bit (void * addr, int size, int offset);
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+extern __inline__ unsigned long ffz(unsigned long word)
+{
+	unsigned long result = 0;
+
+	while(word & 1) {
+		result++;
+		word >>= 1;
+	}
+	return result;
+}
+
+
+extern __inline__ void set_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_flags(flags); cli();
+	*a |= mask;
+	restore_flags(flags);
+}
+
+extern __inline__ void __set_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	*a |= mask;
+}
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+
+extern __inline__ void clear_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_flags(flags); cli();
+	*a &= ~mask;
+	restore_flags(flags);
+}
+
+extern __inline__ void change_bit(int nr, volatile void * addr)
+{
+	int mask, flags;
+	unsigned long *ADDR = (unsigned long *) addr;
+
+	ADDR += nr >> 5;
+	mask = 1 << (nr & 31);
+	save_flags(flags); cli();
+	*ADDR ^= mask;
+	restore_flags(flags);
+}
+
+extern __inline__ void __change_bit(int nr, volatile void * addr)
+{
+	int mask;
+	unsigned long *ADDR = (unsigned long *) addr;
+
+	ADDR += nr >> 5;
+	mask = 1 << (nr & 31);
+	*ADDR ^= mask;
+}
+
+extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+extern __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+	return retval;
+}
+
+extern __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+	return retval;
+}
+
+extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_and_cli(flags);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+extern __inline__ int __test_and_change_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	return retval;
+}
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+extern __inline__ int __constant_test_bit(int nr, const volatile void * addr)
+{
+	return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
+}
+
+extern __inline__ int __test_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	return ((mask & *a) != 0);
+}
+
+#define test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ __constant_test_bit((nr),(addr)) : \
+ __test_bit((nr),(addr)))
+
+#define find_first_zero_bit(addr, size) \
+        find_next_zero_bit((addr), (size), 0)
+
+extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if (offset) {
+		tmp = *(p++);
+		tmp |= ~0UL >> (32-offset);
+		if (size < 32)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while (size & ~31UL) {
+		if (~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp |= ~0UL >> size;
+found_middle:
+	return result + ffz(tmp);
+}
+
+#define ffs(x) generic_ffs(x)
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+
+extern __inline__ int ext2_set_bit(int nr, volatile void * addr)
+{
+	int		mask, retval;
+	unsigned long	flags;
+	volatile unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	save_and_cli(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR |= mask;
+	restore_flags(flags);
+	return retval;
+}
+
+extern __inline__ int ext2_clear_bit(int nr, volatile void * addr)
+{
+	int		mask, retval;
+	unsigned long	flags;
+	volatile unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	save_and_cli(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR &= ~mask;
+	restore_flags(flags);
+	return retval;
+}
+
+extern __inline__ int ext2_test_bit(int nr, const volatile void * addr)
+{
+	int			mask;
+	const volatile unsigned char	*ADDR = (const unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	return ((mask & *ADDR) != 0);
+}
+
+#define ext2_find_first_zero_bit(addr, size) \
+        ext2_find_next_zero_bit((addr), (size), 0)
+
+extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if(offset) {
+		/* We hold the little endian value in tmp, but then the
+		 * shift is illegal. So we could keep a big endian value
+		 * in tmp, like this:
+		 *
+		 * tmp = __swab32(*(p++));
+		 * tmp |= ~0UL >> (32-offset);
+		 *
+		 * but this would decrease preformance, so we change the
+		 * shift:
+		 */
+		tmp = *(p++);
+		tmp |= __swab32(~0UL >> (32-offset));
+		if(size < 32)
+			goto found_first;
+		if(~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while(size & ~31UL) {
+		if(~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if(!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	/* tmp is little endian, so we would have to swab the shift,
+	 * see above. But then we have to swab tmp below for ffz, so
+	 * we might as well do this here.
+	 */
+	return result + ffz(__swab32(tmp) | (~0UL << size));
+found_middle:
+	return result + ffz(__swab32(tmp));
+}
+
+/* Bitmap functions for the minix filesystem.  */
+#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr) set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+
+/**
+ * hweightN - returns the hamming weight of a N-bit word
+ * @x: the word to weigh
+ *
+ * The Hamming Weight of a number is the total number of bits set in it.
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+#endif /* __KERNEL__ */
+
+#endif /* _M68KNOMMU_BITOPS_H */
diff -urN linux-2.4.29/include/asm-m68knommu/bootinfo.h linux-2.4.29-uc1/include/asm-m68knommu/bootinfo.h
--- linux-2.4.29/include/asm-m68knommu/bootinfo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/bootinfo.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,2 @@
+
+/* Nothing for m68knommu */
diff -urN linux-2.4.29/include/asm-m68knommu/bugs.h linux-2.4.29-uc1/include/asm-m68knommu/bugs.h
--- linux-2.4.29/include/asm-m68knommu/bugs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/bugs.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,16 @@
+/*
+ *  include/asm-m68k/bugs.h
+ *
+ *  Copyright (C) 1994  Linus Torvalds
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *	void check_bugs(void);
+ */
+
+static void check_bugs(void)
+{
+}
diff -urN linux-2.4.29/include/asm-m68knommu/byteorder.h linux-2.4.29-uc1/include/asm-m68knommu/byteorder.h
--- linux-2.4.29/include/asm-m68knommu/byteorder.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/byteorder.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef _M68KNOMMU_BYTEORDER_H
+#define _M68KNOMMU_BYTEORDER_H
+
+#include <asm/types.h>
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#include <linux/byteorder/big_endian.h>
+
+#endif /* _M68KNOMMU_BYTEORDER_H */
diff -urN linux-2.4.29/include/asm-m68knommu/cachectl.h linux-2.4.29-uc1/include/asm-m68knommu/cachectl.h
--- linux-2.4.29/include/asm-m68knommu/cachectl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/cachectl.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/cachectl.h>
diff -urN linux-2.4.29/include/asm-m68knommu/cache.h linux-2.4.29-uc1/include/asm-m68knommu/cache.h
--- linux-2.4.29/include/asm-m68knommu/cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/cache.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef __ARCH_M68KNOMMU_CACHE_H
+#define __ARCH_M68KNOMMU_CACHE_H
+
+/* bytes per L1 cache line */
+#define        L1_CACHE_BYTES  16	/* this need to be at least 1 */
+
+/* m68k-elf-gcc  2.95.2 doesn't like these */
+
+#define __cacheline_aligned
+#define ____cacheline_aligned
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/checksum.h linux-2.4.29-uc1/include/asm-m68knommu/checksum.h
--- linux-2.4.29/include/asm-m68knommu/checksum.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/checksum.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,183 @@
+#ifndef _M68K_CHECKSUM_H
+#define _M68K_CHECKSUM_H
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
+
+
+/*
+ * the same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
+						int len, int sum, int *csum_err);
+
+#define csum_partial_copy_nocheck(src, dst, len, sum)	\
+	csum_partial_copy((src), (dst), (len), (sum))
+
+unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl);
+
+#if 0 /* DAVIDM - these are in arch/m68knommu/lib */
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ *
+ */
+static inline unsigned short
+ip_fast_csum(unsigned char *iph, unsigned int ihl)
+{
+	unsigned int sum = 0;
+#ifndef CONFIG_COLDFIRE
+	__asm__ ("subqw #1,%2\n"
+		 "1:\t"
+		 "movel %1@+,%/d0\n\t"
+		 "addxl %/d0,%0\n\t"
+		 "dbra  %2,1b\n\t"
+		 "movel %0,%/d0\n\t"
+		 "swap  %/d0\n\t"
+		 "addxw %/d0,%0\n\t"
+		 "clrw  %/d0\n\t"
+		 "addxw %/d0,%0\n\t"
+		 : "=d" (sum), "=a" (iph), "=d" (ihl)
+		 : "0" (sum), "1" (iph), "2" (ihl)
+		 : "d0");
+#else
+	__asm__ ("subql #1,%2\n"
+		 "1:\t"
+		 "movel %1@+,%/d0\n\t"
+		 "addxl %/d0,%0\n\t"
+		 "subql #1,%2\n\t"
+		 "bra 1b\n\t"
+		 "movel %0,%/d0\n\t"
+		 "swap  %/d0\n\t"
+		 "addxl %/d0,%0\n\t"
+		 "clrw  %/d0\n\t"
+		 "addxl %/d0,%0\n\t"
+		 : "=d" (sum), "=a" (iph), "=d" (ihl)
+		 : "0" (sum), "1" (iph), "2" (ihl)
+		 : "d0");
+#endif
+	return ~sum;
+}
+#endif
+
+/*
+ *	Fold a partial checksum
+ */
+
+static inline unsigned int csum_fold(unsigned int sum)
+{
+#ifdef CONFIG_COLDFIRE
+	sum = (sum & 0xffff) + (sum >> 16);
+	sum = (sum & 0xffff) + (sum >> 16);
+#else
+	unsigned int tmp = sum;
+	__asm__("swap %1\n\t"
+		"addw %1, %0\n\t"
+		"clrw %1\n\t"
+		"addxw %1, %0"
+		: "=&d" (sum), "=&d" (tmp)
+		: "0" (sum), "1" (sum));
+#endif
+	return ~sum;
+}
+
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+
+static inline unsigned int
+csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
+		  unsigned short proto, unsigned int sum)
+{
+	__asm__ ("addl  %1,%0\n\t"
+		 "addxl %4,%0\n\t"
+		 "addxl %5,%0\n\t"
+		 "clrl %1\n\t"
+		 "addxl %1,%0"
+		 : "=&d" (sum), "=&d" (saddr)
+		 : "0" (daddr), "1" (saddr), "d" (len + proto),
+		   "d"(sum));
+	return sum;
+}
+
+static inline unsigned short int
+csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
+		  unsigned short proto, unsigned int sum)
+{
+	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+#if 0 /* DAVIDM - these are in arch/m68knommu/lib */
+static inline unsigned short
+ip_compute_csum(unsigned char * buff, int len)
+{
+	return csum_fold (csum_partial(buff, len, 0));
+}
+#else
+extern unsigned short ip_compute_csum(const unsigned char * buff, int len);
+#endif
+
+#define _HAVE_ARCH_IPV6_CSUM
+static __inline__ unsigned short int
+csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr,
+		__u32 len, unsigned short proto, unsigned int sum) 
+{
+	register unsigned long tmp;
+	__asm__("addl %2@,%0\n\t"
+		"movel %2@(4),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %2@(8),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %2@(12),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %3@,%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %3@(4),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %3@(8),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %3@(12),%1\n\t"
+		"addxl %1,%0\n\t"
+		"addxl %4,%0\n\t"
+		"clrl %1\n\t"
+		"addxl %1,%0"
+		: "=&d" (sum), "=&d" (tmp)
+		: "a" (saddr), "a" (daddr), "d" (len + proto),
+		  "0" (sum));
+
+	return csum_fold(sum);
+}
+
+#endif /* _M68K_CHECKSUM_H */
diff -urN linux-2.4.29/include/asm-m68knommu/coldfire.h linux-2.4.29-uc1/include/asm-m68knommu/coldfire.h
--- linux-2.4.29/include/asm-m68knommu/coldfire.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/coldfire.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,91 @@
+/****************************************************************************/
+
+/*
+ *	coldfire.h -- Motorola ColdFire CPU sepecific defines
+ *
+ *	(C) Copyright 1999-2004, Greg Ungerer (gerg@snapgear.com)
+ *	(C) Copyright 2000, Lineo (www.lineo.com)
+ */
+
+/****************************************************************************/
+#ifndef	coldfire_h
+#define	coldfire_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Define the processor support peripherals base address.
+ *	This is generally setup by the boards start up code.
+ */
+#define	MCF_MBAR	0x10000000
+#define	MCF_MBAR2	0x80000000
+#define	MCF_IPSBAR	0x40000000
+
+#if defined(CONFIG_M5235) || defined(CONFIG_M527x) || \
+    defined(CONFIG_M5282) || defined(CONFIG_M5280)
+#undef MCF_MBAR
+#define	MCF_MBAR	MCF_IPSBAR
+#endif
+
+/*
+ *	Define master clock frequency.
+ */
+#if defined(CONFIG_CLOCK_11MHz)
+#define	MCF_CLK		11289600
+#elif defined(CONFIG_CLOCK_16MHz)
+#define	MCF_CLK		16000000
+#elif defined(CONFIG_CLOCK_20MHz)
+#define	MCF_CLK		20000000
+#elif defined(CONFIG_CLOCK_24MHz)
+#define	MCF_CLK		24000000
+#elif defined(CONFIG_CLOCK_25MHz)
+#define	MCF_CLK		25000000
+#elif defined(CONFIG_CLOCK_29_5MHz)
+#define	MCF_CLK		29500000
+#elif defined(CONFIG_CLOCK_33MHz)
+#define	MCF_CLK		33000000
+#elif defined(CONFIG_CLOCK_40MHz)
+#define	MCF_CLK		40000000
+#elif defined(CONFIG_CLOCK_45MHz)
+#define	MCF_CLK		45000000
+#elif defined(CONFIG_CLOCK_48MHz)
+#define	MCF_CLK		48000000
+#elif defined(CONFIG_CLOCK_50MHz)
+#define	MCF_CLK		50000000
+#elif defined(CONFIG_CLOCK_54MHz)
+#define	MCF_CLK		54000000
+#elif defined(CONFIG_CLOCK_60MHz)
+#define	MCF_CLK		60000000
+#elif defined(CONFIG_CLOCK_64MHz)
+#define	MCF_CLK		64000000
+#elif defined(CONFIG_CLOCK_66MHz)
+#define	MCF_CLK		66000000
+#elif defined(CONFIG_CLOCK_70MHz)
+#define	MCF_CLK		70000000
+#elif defined(CONFIG_CLOCK_100MHz)
+#define	MCF_CLK		100000000
+#elif defined(CONFIG_CLOCK_140MHz)
+#define	MCF_CLK		140000000
+#elif defined(CONFIG_CLOCK_150MHz)
+#define	MCF_CLK		150000000
+#elif defined(CONFIG_CLOCK_166MHz)
+#define	MCF_CLK		166000000
+#else
+#error "Don't know what your ColdFire CPU clock frequency is??"
+#endif
+
+/*
+ *	On some ColdFire family members the bus clock (used by internal
+ *	peripherals) is not the same as the CPU clock.
+ */
+#if defined(CONFIG_M547x)
+#define	MCF_BUSCLK	(MCF_CLK * 2)
+#elif defined(CONFIG_M5235) || defined(CONFIG_M5249) || defined(CONFIG_M527x)
+#define	MCF_BUSCLK	(MCF_CLK / 2)
+#else
+#define	MCF_BUSCLK	MCF_CLK
+#endif
+
+/****************************************************************************/
+#endif	/* coldfire_h */
diff -urN linux-2.4.29/include/asm-m68knommu/current.h linux-2.4.29-uc1/include/asm-m68knommu/current.h
--- linux-2.4.29/include/asm-m68knommu/current.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/current.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,16 @@
+#ifndef _M68KNOMMU_CURRENT_H
+#define _M68KNOMMU_CURRENT_H
+/*
+ *	current.h
+ *	(C) Copyright 2000, Lineo, David McCullough <davidm@lineo.com>
+ *
+ *	rather than dedicate a register (as the m68k source does), we
+ *	just keep a global,  we should probably just change it all to be
+ *	current and lose _current_task.
+ */
+
+extern struct task_struct *_current_task;
+#define get_current()	_current_task
+#define current _current_task
+
+#endif /* _M68KNOMMU_CURRENT_H */
diff -urN linux-2.4.29/include/asm-m68knommu/dbg.h linux-2.4.29-uc1/include/asm-m68knommu/dbg.h
--- linux-2.4.29/include/asm-m68knommu/dbg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/dbg.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,6 @@
+#define DEBUG 1
+#ifdef CONFIG_COLDFIRE
+#define	BREAK asm volatile ("halt")
+#else
+#define BREAK *(volatile unsigned char *)0xdeadbee0 = 0
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/delay.h linux-2.4.29-uc1/include/asm-m68knommu/delay.h
--- linux-2.4.29/include/asm-m68knommu/delay.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/delay.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,77 @@
+#ifndef _M68KNOMMU_DELAY_H
+#define _M68KNOMMU_DELAY_H
+
+/*
+ * Copyright (C) 1994 Hamish Macdonald
+ */
+#include <asm/param.h>
+
+
+extern __inline__ void __delay(unsigned long loops)
+{
+#if defined(CONFIG_COLDFIRE)
+	/* The coldfire runs this loop at significantly different speeds
+	 * depending upon long word alignment or not.  We'll pad it to
+	 * long word alignment which is the faster version.
+	 * The 0x4a8e is of course a 'tstl %fp' instruction.  This is better
+	 * than using a NOP (0x4e71) instruction because it executes in one
+	 * cycle not three and doesn't allow for an arbitary delay waiting
+	 * for bus cycles to finish.  Also fp/a6 isn't likely to cause a
+	 * stall waiting for the register to become valid if such is added
+	 * to the coldfire at some stage.
+	 */
+	__asm__ __volatile__ (	".balignw 4, 0x4a8e\n\t"
+				"1: subql #1, %0\n\t"
+				"jcc 1b"
+		: "=d" (loops) : "0" (loops));
+#else
+	__asm__ __volatile__ (	"1: subql #1, %0\n\t"
+				"jcc 1b"
+		: "=d" (loops) : "0" (loops));
+#endif
+}
+
+/*
+ *	Ideally we use a 32*32->64 multiply to calculate the number of
+ *	loop iterations, but the older standard 68k and ColdFire do not
+ *	have this instruction. So for them we have a clsoe approximation
+ *	loop using 32*32->32 multiplies only. This calculation based on
+ *	the ARM version of delay.
+ *
+ *	We want to implement:
+ *
+ *	loops = (usecs * 0x10c6 * HZ * loops_per_jiffy) / 2^32
+ */
+
+#define	HZSCALE		(268435456 / (1000000/HZ))
+
+extern unsigned long loops_per_jiffy;
+
+extern __inline__ void _udelay(unsigned long usecs)
+{
+#if defined(CONFIG_M68328) || defined(CONFIG_M68EZ328) || \
+    defined(CONFIG_M68VZ328) || defined(CONFIG_M68360) || \
+    defined(CONFIG_COLDFIRE)
+	__delay((((usecs * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6);
+#else
+	unsigned long tmp;
+
+	usecs *= 4295;		/* 2**32 / 1000000 */
+	__asm__ ("mulul %2,%0:%1"
+		: "=d" (usecs), "=d" (tmp)
+		: "d" (usecs), "1" (loops_per_jiffy*HZ));
+	__delay(usecs);
+#endif
+}
+
+/*
+ *	Moved the udelay() function into library code, no longer inlined.
+ *	I had to change the algorithm because we are overflowing now on
+ *	the faster ColdFire parts. The code is a little biger, so it makes
+ *	sense to library it.
+ */
+extern void udelay(unsigned long usecs);
+
+#define ndelay(n)	udelay((n) * 5)
+
+#endif /* defined(_M68KNOMMU_DELAY_H) */
diff -urN linux-2.4.29/include/asm-m68knommu/div64.h linux-2.4.29-uc1/include/asm-m68knommu/div64.h
--- linux-2.4.29/include/asm-m68knommu/div64.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/div64.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-generic/div64.h>
diff -urN linux-2.4.29/include/asm-m68knommu/dma.h linux-2.4.29-uc1/include/asm-m68knommu/dma.h
--- linux-2.4.29/include/asm-m68knommu/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/dma.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,495 @@
+#ifndef _M68K_DMA_H
+#define _M68K_DMA_H 1
+ 
+//#define	DMA_DEBUG	1
+
+#include <linux/config.h>
+
+#ifdef CONFIG_COLDFIRE
+/*
+ * ColdFire DMA Model:
+ *   ColdFire DMA supports two forms of DMA: Single and Dual address. Single
+ * address mode emits a source address, and expects that the device will either
+ * pick up the data (DMA READ) or source data (DMA WRITE). This implies that
+ * the device will place data on the correct byte(s) of the data bus, as the
+ * memory transactions are always 32 bits. This implies that only 32 bit
+ * devices will find single mode transfers useful. Dual address DMA mode
+ * performs two cycles: source read and destination write. ColdFire will
+ * align the data so that the device will always get the correct bytes, thus
+ * is useful for 8 and 16 bit devices. This is the mode that is supported
+ * below.
+ *
+ * AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000 
+ *               Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
+ *
+ * AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000
+ *               Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
+ *
+ * APR/18/2002 : added proper support for MCF5272 DMA controller.
+ *               Arthur Shipkowski (art@videon-central.com)
+ */
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+
+/*
+ * Set number of channels of DMA on ColdFire for different implementations.
+ */
+#if defined(CONFIG_M5307) || defined(CONFIG_M5407)
+#define MAX_DMA_CHANNELS 4
+#elif defined(CONFIG_M5272)
+#define MAX_DMA_CHANNELS 1
+#else
+#define MAX_DMA_CHANNELS 2
+#endif
+
+extern unsigned int dma_base_addr[MAX_DMA_CHANNELS];
+extern unsigned int dma_device_address[MAX_DMA_CHANNELS];
+
+#if !defined(CONFIG_M5272)
+#define DMA_MODE_WRITE_BIT  0x01  /* Memory/IO to IO/Memory select */
+#define DMA_MODE_WORD_BIT   0x02  /* 8 or 16 bit transfers */
+#define DMA_MODE_LONG_BIT   0x04  /* or 32 bit transfers */
+#define DMA_MODE_SINGLE_BIT 0x08  /* single-address-mode */
+
+/* I/O to memory, 8 bits, mode */
+#define DMA_MODE_READ	            0
+/* memory to I/O, 8 bits, mode */
+#define DMA_MODE_WRITE	            1
+/* I/O to memory, 16 bits, mode */
+#define DMA_MODE_READ_WORD          2
+/* memory to I/O, 16 bits, mode */
+#define DMA_MODE_WRITE_WORD         3
+/* I/O to memory, 32 bits, mode */
+#define DMA_MODE_READ_LONG          4
+/* memory to I/O, 32 bits, mode */
+#define DMA_MODE_WRITE_LONG         5
+/* I/O to memory, 8 bits, single-address-mode */     
+#define DMA_MODE_READ_SINGLE        8
+/* memory to I/O, 8 bits, single-address-mode */
+#define DMA_MODE_WRITE_SINGLE       9
+/* I/O to memory, 16 bits, single-address-mode */
+#define DMA_MODE_READ_WORD_SINGLE  10
+/* memory to I/O, 16 bits, single-address-mode */
+#define DMA_MODE_WRITE_WORD_SINGLE 11
+/* I/O to memory, 32 bits, single-address-mode */
+#define DMA_MODE_READ_LONG_SINGLE  12
+/* memory to I/O, 32 bits, single-address-mode */
+#define DMA_MODE_WRITE_LONG_SINGLE 13
+
+#else /* CONFIG_M5272 is defined */
+
+/* Source static-address mode */
+#define DMA_MODE_SRC_SA_BIT 0x01  
+/* Two bits to select between all four modes */
+#define DMA_MODE_SSIZE_MASK 0x06 
+/* Offset to shift bits in */
+#define DMA_MODE_SSIZE_OFF  0x01  
+/* Destination static-address mode */
+#define DMA_MODE_DES_SA_BIT 0x10  
+/* Two bits to select between all four modes */
+#define DMA_MODE_DSIZE_MASK 0x60  
+/* Offset to shift bits in */
+#define DMA_MODE_DSIZE_OFF  0x05
+/* Size modifiers */
+#define DMA_MODE_SIZE_LONG  0x00
+#define DMA_MODE_SIZE_BYTE  0x01
+#define DMA_MODE_SIZE_WORD  0x02
+#define DMA_MODE_SIZE_LINE  0x03
+
+/* 
+ * Aliases to help speed quick ports; these may be suboptimal, however. They
+ * do not include the SINGLE mode modifiers since the MCF5272 does not have a
+ * mode where the device is in control of its addressing.
+ */
+
+/* I/O to memory, 8 bits, mode */
+#define DMA_MODE_READ	              ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_MODE_SRC_SA_BIT)
+/* memory to I/O, 8 bits, mode */
+#define DMA_MODE_WRITE	            ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_MODE_DES_SA_BIT)
+/* I/O to memory, 16 bits, mode */
+#define DMA_MODE_READ_WORD	        ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_MODE_SRC_SA_BIT)
+/* memory to I/O, 16 bits, mode */
+#define DMA_MODE_WRITE_WORD         ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_MODE_DES_SA_BIT)
+/* I/O to memory, 32 bits, mode */
+#define DMA_MODE_READ_LONG	        ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_MODE_SRC_SA_BIT)
+/* memory to I/O, 32 bits, mode */
+#define DMA_MODE_WRITE_LONG         ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_MODE_DES_SA_BIT)
+
+#endif /* !defined(CONFIG_M5272) */
+
+#if !defined(CONFIG_M5272)
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+  volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+  printk("enable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT;
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+  volatile unsigned short *dmawp;
+  volatile unsigned char  *dmapb;
+
+#ifdef DMA_DEBUG
+  printk("disable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  dmapb = (unsigned char *) dma_base_addr[dmanr];
+
+  /* Turn off external requests, and stop any DMA in progress */
+  dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT;
+  dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE;
+}
+
+/*
+ * Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while interrupts are disabled! ---
+ *
+ * This is a NOP for ColdFire. Provide a stub for compatibility.
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+
+  volatile unsigned char  *dmabp;
+  volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
+#endif
+
+  dmabp = (unsigned char *) dma_base_addr[dmanr];
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+
+  // Clear config errors
+  dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE; 
+
+  // Set command register
+  dmawp[MCFDMA_DCR] =
+    MCFDMA_DCR_INT |         // Enable completion irq
+    MCFDMA_DCR_CS |          // Force one xfer per request
+    MCFDMA_DCR_AA |          // Enable auto alignment
+    // single-address-mode
+    ((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) |
+    // sets s_rw (-> r/w) high if Memory to I/0
+    ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) |
+    // Memory to I/O or I/O to Memory
+    ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) |
+    // 32 bit, 16 bit or 8 bit transfers
+    ((mode & DMA_MODE_WORD_BIT)  ? MCFDMA_DCR_SSIZE_WORD : 
+     ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG :
+                                   MCFDMA_DCR_SSIZE_BYTE)) |
+    ((mode & DMA_MODE_WORD_BIT)  ? MCFDMA_DCR_DSIZE_WORD :
+     ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_DSIZE_LONG :
+                                   MCFDMA_DCR_DSIZE_BYTE));
+
+#ifdef DEBUG_DMA
+  printk("%s(%d): dmanr=%d DSR[%x]=%x DCR[%x]=%x\n", __FILE__, __LINE__,
+         dmanr, (int) &dmabp[MCFDMA_DSR], dmabp[MCFDMA_DSR],
+	 (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR]);
+#endif
+}
+
+/* Set transfer address for specific DMA channel */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+  volatile unsigned short *dmawp;
+  volatile unsigned int   *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+
+  // Determine which address registers are used for memory/device accesses
+  if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) {
+    // Source incrementing, must be memory
+    dmalp[MCFDMA_SAR] = a;
+    // Set dest address, must be device
+    dmalp[MCFDMA_DAR] = dma_device_address[dmanr];
+  } else {
+    // Destination incrementing, must be memory
+    dmalp[MCFDMA_DAR] = a;
+    // Set source address, must be device
+    dmalp[MCFDMA_SAR] = dma_device_address[dmanr];
+  }
+
+#ifdef DEBUG_DMA
+  printk("%s(%d): dmanr=%d DCR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
+	__FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR],
+	(int) &dmalp[MCFDMA_SAR], dmalp[MCFDMA_SAR],
+	(int) &dmalp[MCFDMA_DAR], dmalp[MCFDMA_DAR]);
+#endif
+}
+
+/*
+ * Specific for Coldfire - sets device address.
+ * Should be called after the mode set call, and before set DMA address.
+ */
+static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
+{
+#ifdef DMA_DEBUG
+  printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+  dma_device_address[dmanr] = a;
+}
+
+/*
+ * NOTE 2: "count" represents _bytes_.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+  volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  dmawp[MCFDMA_BCR] = (unsigned short)count;
+}
+
+/*
+ * Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+  volatile unsigned short *dmawp;
+  unsigned short count;
+
+#ifdef DMA_DEBUG
+  printk("get_dma_residue(dmanr=%d)\n", dmanr);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  count = dmawp[MCFDMA_BCR];
+  return((int) count);
+}
+#else /* CONFIG_M5272 is defined */
+
+/*
+ * The MCF5272 DMA controller is very different than the controller defined above
+ * in terms of register mapping.  For instance, with the exception of the 16-bit 
+ * interrupt register (IRQ#85, for reference), all of the registers are 32-bit.
+ *
+ * The big difference, however, is the lack of device-requested DMA.  All modes
+ * are dual address transfer, and there is no 'device' setup or direction bit.
+ * You can DMA between a device and memory, between memory and memory, or even between
+ * two devices directly, with any combination of incrementing and non-incrementing
+ * addresses you choose.  This puts a crimp in distinguishing between the 'device 
+ * address' set up by set_dma_device_addr.
+ *
+ * Therefore, there are two options.  One is to use set_dma_addr and set_dma_device_addr,
+ * which will act exactly as above in -- it will look to see if the source is set to
+ * autoincrement, and if so it will make the source use the set_dma_addr value and the
+ * destination the set_dma_device_addr value.  Otherwise the source will be set to the
+ * set_dma_device_addr value and the destination will get the set_dma_addr value.
+ *
+ * The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions
+ * and make it explicit.  Depending on what you're doing, one of these two should work
+ * for you, but don't mix them in the same transfer setup.
+ */
+
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+  volatile unsigned int  *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("enable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN;
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+  volatile unsigned int   *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("disable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+
+  /* Turn off external requests, and stop any DMA in progress */
+  dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN;
+  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
+}
+
+/*
+ * Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while interrupts are disabled! ---
+ *
+ * This is a NOP for ColdFire. Provide a stub for compatibility.
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+
+  volatile unsigned int   *dmalp;
+  volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
+#endif
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+
+  // Clear config errors
+  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; 
+
+  // Set command register
+  dmalp[MCFDMA_DMR] =
+    MCFDMA_DMR_RQM_DUAL |         // Mandatory Request Mode setting
+    MCFDMA_DMR_DSTT_SD  |         // Set up addressing types; set to supervisor-data.
+    MCFDMA_DMR_SRCT_SD  |         // Set up addressing types; set to supervisor-data. 
+    // source static-address-mode
+    ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) |
+    // dest static-address-mode
+    ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) |
+    // burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272
+    (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) |
+    (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF);
+    
+  dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN;   /* Enable completion interrupts */
+  
+#ifdef DEBUG_DMA
+  printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__,
+         dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR],
+	 (int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]);
+#endif
+}
+
+/* Set transfer address for specific DMA channel */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+  volatile unsigned int   *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+
+  // Determine which address registers are used for memory/device accesses
+  if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) {
+    // Source incrementing, must be memory
+    dmalp[MCFDMA_DSAR] = a;
+    // Set dest address, must be device
+    dmalp[MCFDMA_DDAR] = dma_device_address[dmanr];
+  } else {
+    // Destination incrementing, must be memory
+    dmalp[MCFDMA_DDAR] = a;
+    // Set source address, must be device
+    dmalp[MCFDMA_DSAR] = dma_device_address[dmanr];
+  }
+
+#ifdef DEBUG_DMA
+  printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
+	__FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR],
+	(int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR],
+	(int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]);
+#endif
+}
+
+/*
+ * Specific for Coldfire - sets device address.
+ * Should be called after the mode set call, and before set DMA address.
+ */
+static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
+{
+#ifdef DMA_DEBUG
+  printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+  dma_device_address[dmanr] = a;
+}
+
+/*
+ * NOTE 2: "count" represents _bytes_.
+ *
+ * NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+  volatile unsigned int *dmalp;
+  
+#ifdef DMA_DEBUG
+  printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+  dmalp[MCFDMA_DBCR] = count;
+}
+
+/*
+ * Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+  volatile unsigned int *dmalp;
+  unsigned int count;
+
+#ifdef DMA_DEBUG
+  printk("get_dma_residue(dmanr=%d)\n", dmanr);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+  count = dmalp[MCFDMA_DBCR];
+  return(count);
+}
+
+#endif /* !defined(CONFIG_M5272) */
+
+#else
+ 
+#define MAX_DMA_CHANNELS 8
+ 
+#endif /* CONFIG_COLDFIRE */
+
+/* Don't define MAX_DMA_ADDRESS; it's useless on the m68k/coldfire and any
+   occurrence should be flagged as an error.  */
+/* under 2.4 it is actually needed by the new bootmem allocator */
+#define MAX_DMA_ADDRESS PAGE_OFFSET
+
+/* These are in kernel/dma.c: */
+extern int request_dma(unsigned int dmanr, const char *device_id);	/* reserve a DMA channel */
+extern void free_dma(unsigned int dmanr);	/* release it again */
+ 
+#endif /* _M68K_DMA_H */
diff -urN linux-2.4.29/include/asm-m68knommu/dsp56k.h linux-2.4.29-uc1/include/asm-m68knommu/dsp56k.h
--- linux-2.4.29/include/asm-m68knommu/dsp56k.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/dsp56k.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,36 @@
+/* DAVIDM is this needed */
+/*
+ * linux/include/asm-m68k/dsp56k.h - defines and declarations for
+ *                                   DSP56k device driver
+ *
+ * Copyright (C) 1996,1997 Fredrik Noring, lars brinkhoff & Tomas Berndtsson
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+
+/* Used for uploading DSP binary code */
+struct dsp56k_upload {
+	int len;
+	char *bin;
+};
+
+/* For the DSP host flags */
+struct dsp56k_host_flags {
+	int dir;     /* Bit field. 1 = write output bit, 0 = do nothing.
+		      * 0x0000 means reading only, 0x0011 means
+		      * writing the bits stored in `out' on HF0 and HF1.
+		      * Note that HF2 and HF3 can only be read.
+		      */
+	int out;     /* Bit field like above. */
+	int status;  /* Host register's current state is returned */
+};
+
+/* ioctl command codes */
+#define DSP56K_UPLOAD	        1    /* Upload DSP binary program       */
+#define DSP56K_SET_TX_WSIZE	2    /* Host transmit word size (1-4)   */
+#define DSP56K_SET_RX_WSIZE	3    /* Host receive word size (1-4)    */
+#define DSP56K_HOST_FLAGS	4    /* Host flag registers             */
+#define DSP56K_HOST_CMD         5    /* Trig Host Command (0-31)        */
diff -urN linux-2.4.29/include/asm-m68knommu/elf.h linux-2.4.29-uc1/include/asm-m68knommu/elf.h
--- linux-2.4.29/include/asm-m68knommu/elf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/elf.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,95 @@
+#ifndef __ASMm68k_ELF_H
+#define __ASMm68k_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <linux/config.h>
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_m68kfp_struct elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == EM_68K)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2MSB
+#define ELF_ARCH	EM_68K
+
+/* For SVR4/m68k the function pointer to be registered with `atexit' is
+   passed in %a1.  Although my copy of the ABI has no such statement, it
+   is actually used on ASV.  */
+#define ELF_PLAT_INIT(_r)	_r->a1 = 0
+
+#define USE_ELF_CORE_DUMP
+#ifndef CONFIG_SUN3
+#define ELF_EXEC_PAGESIZE	4096
+#else
+#define ELF_EXEC_PAGESIZE	8192
+#endif
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#ifndef CONFIG_SUN3
+#define ELF_ET_DYN_BASE         0xD0000000UL
+#else
+#define ELF_ET_DYN_BASE         0x0D800000UL
+#endif
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs)				\
+	/* Bleech. */							\
+	pr_reg[0] = regs->d1;						\
+	pr_reg[1] = regs->d2;						\
+	pr_reg[2] = regs->d3;						\
+	pr_reg[3] = regs->d4;						\
+	pr_reg[4] = regs->d5;						\
+	pr_reg[7] = regs->a0;						\
+	pr_reg[8] = regs->a1;						\
+	pr_reg[14] = regs->d0;						\
+	pr_reg[15] = rdusp();						\
+	pr_reg[16] = 0 /* regs->orig_d0; */			\
+	pr_reg[17] = regs->sr;						\
+	pr_reg[18] = regs->pc;						\
+	/* pr_reg[19] = (regs->format << 12) | regs->vector; */		\
+	{								\
+	  struct switch_stack *sw = ((struct switch_stack *)regs) - 1;	\
+	  pr_reg[5] = sw->d6;						\
+	  pr_reg[6] = sw->d7;						\
+	  pr_reg[9] = sw->a2;						\
+	  pr_reg[10] = sw->a3;						\
+	  pr_reg[11] = sw->a4;						\
+	  pr_reg[12] = sw->a5;						\
+	  pr_reg[13] = sw->a6;						\
+	}
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.  */
+
+#define ELF_PLATFORM  (NULL)
+
+#ifdef __KERNEL__
+#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/elia.h linux-2.4.29-uc1/include/asm-m68knommu/elia.h
--- linux-2.4.29/include/asm-m68knommu/elia.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/elia.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,88 @@
+/****************************************************************************/
+
+/*
+ *	elia.h -- Lineo (formerly Moreton Bay) eLIA platform support.
+ *
+ *	(C) Copyright 1999-2000, Moreton Bay (www.moreton.com.au)
+ *	(C) Copyright 1999-2000, Lineo (www.lineo.com)
+ */
+
+/****************************************************************************/
+#ifndef	elia_h
+#define	elia_h
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <asm/coldfire.h>
+
+#ifdef CONFIG_eLIA
+
+/*
+ *	The serial port DTR and DCD lines are also on the Parallel I/O
+ *	as well, so define those too.
+ */
+#define	MCF_HAVEDCD0
+#define	MCF_HAVEDCD1
+#define	MCF_HAVEDTR0
+#define	MCF_HAVEDTR1
+
+#define	eLIA_PCIRESET		0x0020
+
+/*
+ *	Kernel functions to set and unset DTR/DCD and the LEDs.
+ */
+#ifndef __ASSEMBLY__
+
+#define	MCFPP_DCD1	0x0001
+#define	MCFPP_DCD0	0x0002
+#define	MCFPP_DTR1	0x0004
+#define	MCFPP_DTR0	0x0008
+
+extern volatile unsigned short ppdata;
+
+static __inline__ unsigned int mcf_getppdcd(unsigned int portnr)
+{
+	volatile unsigned short *pp;
+	if (portnr < 2) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+		return((*pp & (portnr ? 0x0001 : 0x0002)) ? 0 : 1);
+	}
+	return(0);
+}
+
+static __inline__ unsigned int mcf_getppdtr(unsigned int portnr)
+{
+	volatile unsigned short *pp;
+	if (portnr < 2) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+		return((*pp & (portnr ? 0x0004 : 0x0008)) ? 0 : 1);
+	}
+	return(0);
+}
+
+static __inline__ void mcf_setppdtr(unsigned int portnr, unsigned int dtr)
+{
+	volatile unsigned short *pp;
+	unsigned short bit;
+	if (portnr < 2) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+		bit = (portnr ? 0x0004 : 0x0008);
+		*pp = (*pp & ~bit) | (dtr ? 0 : bit);
+	}
+}
+
+/*
+ *	The power and heartbeat LED's are connected to PIO bits of
+ *	the 5307 based boards.
+ */
+static __inline__ void mcf_setppleds(unsigned int mask, unsigned int bits)
+{
+	volatile unsigned short *pp;
+	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+	*pp = (*pp & ~mask) | bits;
+}
+#endif /* __ASSEMBLY__ */
+#endif	/* CONFIG_eLIA */
+
+/****************************************************************************/
+#endif	/* elia_h */
diff -urN linux-2.4.29/include/asm-m68knommu/entry.h linux-2.4.29-uc1/include/asm-m68knommu/entry.h
--- linux-2.4.29/include/asm-m68knommu/entry.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/entry.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,166 @@
+#ifndef __M68K_ENTRY_H
+#define __M68K_ENTRY_H
+
+#include <linux/config.h>
+#ifndef CONFIG_COLDFIRE
+#include <asm/setup.h>
+#include <asm/page.h>
+
+/*
+ * Stack layout in 'ret_from_exception':
+ *
+ *	This allows access to the syscall arguments in registers d1-d5
+ *
+ *	 0(sp) - d1
+ *	 4(sp) - d2
+ *	 8(sp) - d3
+ *	 C(sp) - d4
+ *	10(sp) - d5
+ *	14(sp) - a0
+ *	18(sp) - a1
+ *	1C(sp) - a2
+ *	20(sp) - d0
+ *	24(sp) - orig_d0
+ *	28(sp) - stack adjustment
+ *	2C(sp) - sr
+ *	2E(sp) - pc
+ *	32(sp) - format & vector
+ */
+
+/*
+ * 97/05/14 Andreas: Register %a2 is now set to the current task throughout
+ *		     the whole kernel.
+ */
+
+/* the following macro is used when enabling interrupts */
+#if defined(MACH_ATARI_ONLY) && !defined(CONFIG_HADES)
+	/* block out HSYNC on the atari */
+#define ALLOWINT 0xfbff
+#define	MAX_NOINT_IPL	3
+#else
+	/* portable version */
+#define ALLOWINT 0xf8ff
+#define	MAX_NOINT_IPL	0
+#endif /* machine compilation types */ 
+
+#ifdef __ASSEMBLY__
+
+#define curptr a2
+
+LFLUSH_I_AND_D = 0x00000808
+LSIGTRAP = 5
+
+/* process bits for task_struct.flags */
+PF_TRACESYS_OFF = 3
+PF_TRACESYS_BIT = 5
+PF_PTRACED_OFF = 3
+PF_PTRACED_BIT = 4
+PF_DTRACE_OFF = 1
+PF_DTRACE_BIT = 5
+
+#define SAVE_ALL_INT save_all_int
+#define SAVE_ALL_SYS save_all_sys
+#define RESTORE_ALL restore_all
+/*
+ * This defines the normal kernel pt-regs layout.
+ *
+ * regs a3-a6 and d6-d7 are preserved by C code
+ * the kernel doesn't mess with usp unless it needs to
+ */
+
+/*
+ * a -1 in the orig_d0 field signifies
+ * that the stack frame is NOT for syscall
+ */
+.macro	save_all_int VEC=0
+#if defined(CONFIG_PSEUDO_EXCEPTION_VECTOR)
+        movew   %sp@(0),%sp@-   /* add the pseudo vector on the stack */
+        movew   %sp@(4),%sp@(2)
+        movew   %sp@(6),%sp@(4)
+        movew   #\VEC,%sp@(6)   /* pseudo-vector number */
+#endif
+	oriw	#0x0700,%sr	/* disable interrupts */
+	clrl	%sp@-		/* stk_adj */
+	pea	-1:w		/* orig d0 */
+	movel	%d0,%sp@-	/* d0 */
+	moveml	%d1-%d5/%a0-%a1/%curptr,%sp@-
+.endm
+
+.macro	save_all_sys VEC=0
+#if defined(CONFIG_PSEUDO_EXCEPTION_VECTOR)
+        movew   %sp@(0),%sp@-   /* add the pseudo vector on the stack */
+        movew   %sp@(4),%sp@(2)
+        movew   %sp@(6),%sp@(4)
+        movew   #\VEC,%sp@(6)   /* pseudo-vector number */
+#endif
+	clrl	%sp@-		/* stk_adj */
+	movel	%d0,%sp@-	/* orig d0 */
+	movel	%d0,%sp@-	/* d0 */
+	moveml	%d1-%d5/%a0-%a1/%curptr,%sp@-
+.endm
+
+.macro	restore_all
+	moveml	%sp@+,%a0-%a1/%curptr/%d1-%d5
+	movel	%sp@+,%d0
+	addql	#4,%sp		/* orig d0 */
+	addl	%sp@+,%sp	/* stk adj */
+#if defined(CONFIG_PSEUDO_EXCEPTION_VECTOR)
+        movew   %sp@(4),%sp@(6) /* adjust stack to remove pseudo vector */
+        movew   %sp@(2),%sp@(4)
+        movew   %sp@(0),%sp@(2)
+        addql   #2,%sp
+#endif
+	rte
+.endm
+
+#define SWITCH_STACK_SIZE (6*4+4)	/* includes return address */
+
+#define SAVE_SWITCH_STACK save_switch_stack
+#define RESTORE_SWITCH_STACK restore_switch_stack
+#if 0 // DAVIDM
+#define GET_CURRENT(tmp) get_current tmp
+#else
+#define GET_CURRENT(tmp)
+#endif
+
+.macro	save_switch_stack
+	moveml	%a3-%a6/%d6-%d7,%sp@-
+.endm
+
+.macro	restore_switch_stack
+	moveml	%sp@+,%a3-%a6/%d6-%d7
+.endm
+
+#if 0 // DAVIDM
+.macro	get_current reg=%d0
+	movel	%sp,\reg
+	andw	#-KTHREAD_SIZE,\reg
+	movel	\reg,%curptr
+.endm
+#endif
+
+#else /* C source */
+
+#define STR(X) STR1(X)
+#define STR1(X) #X
+
+#define PT_OFF_ORIG_D0	 0x24
+#define PT_OFF_FORMATVEC 0x32
+#define PT_OFF_SR	 0x2C
+#if 0 // DAVIDM
+#define SAVE_ALL_INT				\
+	"clrl	%%sp@-;"    /* stk_adj */	\
+	"pea	-1:w;"	    /* orig d0 = -1 */	\
+	"movel	%%d0,%%sp@-;" /* d0 */		\
+	"moveml	%%d1-%%d5/%%a0-%%a2,%%sp@-"
+
+#define GET_CURRENT(tmp) \
+	"movel	%%sp,"#tmp"\n\t" \
+	"andw	#-"STR(KTHREAD_SIZE)","#tmp"\n\t" \
+	"movel	"#tmp",%%a2"
+#endif
+
+#endif
+
+#endif /* CONFIG_COLDFIRE */
+#endif /* __M68K_ENTRY_H */
diff -urN linux-2.4.29/include/asm-m68knommu/errno.h linux-2.4.29-uc1/include/asm-m68knommu/errno.h
--- linux-2.4.29/include/asm-m68knommu/errno.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/errno.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/errno.h>
diff -urN linux-2.4.29/include/asm-m68knommu/fcntl.h linux-2.4.29-uc1/include/asm-m68knommu/fcntl.h
--- linux-2.4.29/include/asm-m68knommu/fcntl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/fcntl.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/fcntl.h>
diff -urN linux-2.4.29/include/asm-m68knommu/flat.h linux-2.4.29-uc1/include/asm-m68knommu/flat.h
--- linux-2.4.29/include/asm-m68knommu/flat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/flat.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,16 @@
+/*
+ * include/asm-m68knommu/flat.h -- uClinux flat-format executables
+ */
+
+#ifndef __M68KNOMMU_FLAT_H__
+#define __M68KNOMMU_FLAT_H__
+
+#define	flat_stack_align(sp)			/* nothing needed */
+#define	flat_argvp_envp_on_stack()		1
+#define	flat_old_ram_flag(flags)		(flags)
+#define	flat_reloc_valid(reloc, size)		((reloc) <= (size))
+#define	flat_get_addr_from_rp(rp, relval, flags)	get_unaligned(rp)
+#define	flat_put_addr_at_rp(rp, val, relval)	put_unaligned(val,rp)
+#define	flat_get_relocate_addr(rel)		(rel)
+
+#endif /* __M68KNOMMU_FLAT_H__ */
diff -urN linux-2.4.29/include/asm-m68knommu/fpu.h linux-2.4.29-uc1/include/asm-m68knommu/fpu.h
--- linux-2.4.29/include/asm-m68knommu/fpu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/fpu.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef __M68KNOMMU_FPU_H
+#define __M68KNOMMU_FPU_H
+
+#include <linux/config.h>
+
+/*
+ * MAX floating point unit state size (FSAVE/FRESTORE)
+ */
+
+/* #if defined(CONFIG_COLDFIRE) */
+#if defined(CONFIG_UCLINUX) /* FIXME */
+#define FPSTATESIZE (2) /* dummy size */
+#elif defined(CONFIG_M68020) || defined(CONFIG_M68030)
+#define FPSTATESIZE (216/sizeof(unsigned char))
+#elif defined(CONFIG_M68040)
+#define FPSTATESIZE (96/sizeof(unsigned char))
+#elif defined(CONFIG_M68KFPU_EMU)
+#define FPSTATESIZE (28/sizeof(unsigned char))
+#elif defined(CONFIG_M68060)
+#define FPSTATESIZE (12/sizeof(unsigned char))
+#else
+#define FPSTATESIZE error no_cpu_type_configured
+#endif
+
+#endif /* __M68K_FPU_H */
diff -urN linux-2.4.29/include/asm-m68knommu/hardirq.h linux-2.4.29-uc1/include/asm-m68knommu/hardirq.h
--- linux-2.4.29/include/asm-m68knommu/hardirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/hardirq.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,41 @@
+#ifndef __M68K_HARDIRQ_H
+#define __M68K_HARDIRQ_H
+
+#include <linux/config.h>
+#include <linux/threads.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned int __local_irq_count;
+	unsigned int __local_bh_count;
+	unsigned int __syscall_count;
+	struct task_struct * __ksoftirqd_task;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt() (local_irq_count(smp_processor_id()) + local_bh_count(smp_processor_id()) != 0)
+
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
+
+#ifndef CONFIG_SMP
+
+#define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
+#define hardirq_endlock(cpu)	do { } while (0)
+
+#define irq_enter(cpu, irq)	(local_irq_count(cpu)++)
+#define irq_exit(cpu, irq)	(local_irq_count(cpu)--)
+
+#define synchronize_irq()	barrier()
+
+#else
+
+#error m68knommu SMP is not available
+
+#endif /* CONFIG_SMP */
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/hc_sl811-hw.h linux-2.4.29-uc1/include/asm-m68knommu/hc_sl811-hw.h
--- linux-2.4.29/include/asm-m68knommu/hc_sl811-hw.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/hc_sl811-hw.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,131 @@
+/*
+File: include/asm-arm/hc_sl811-hw.h
+*/
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+
+/* The base_addr, data_reg_addr, and irq number are board specific.
+ * NOTE: values need to modify for different development boards
+ */
+
+#if defined(CONFIG_SIGNAL_MCP751)
+#define SIZEOF_IO_REGION	256	/* Size for request/release region */
+static int base_addr	 = 0x46000000;
+static int data_reg_addr = 0x46000001;
+static int irq		 = 90;
+#define MAX_CONTROLERS  1
+
+MODULE_PARM (base_addr, "i");
+MODULE_PARM_DESC (base_addr, "sl811 base address 0x46000000");
+MODULE_PARM (data_reg_addr, "i");
+MODULE_PARM_DESC (data_reg_addr, "sl811 data register address 0x46000001");
+MODULE_PARM (irq, "i");
+MODULE_PARM_DESC (irq, "IRQ 90 (default)");
+#endif
+
+/*
+ * Low level: Read from Data port [arm]
+ */
+static __u8 inline sl811_read_data (hcipriv_t *hp)
+{
+	__u8 data;
+	data = readb (hp->hcport2);
+	rmb ();
+	return (data);
+}
+
+/*
+ * Low level: Write to index register [arm]
+ */
+static void inline sl811_write_index (hcipriv_t *hp, __u8 index)
+{
+	writeb (index, hp->hcport);
+	wmb ();
+}
+
+/*
+ * Low level: Write to Data port [arm]
+ */
+static void inline sl811_write_data (hcipriv_t *hp, __u8 data)
+{
+	writeb (data, hp->hcport2);
+}
+
+/*
+ * Low level: Write to index register and data port [arm]
+ */
+static void inline sl811_write_index_data (hcipriv_t *hp, __u8 index, __u8 data)
+{
+	writeb (index, hp->hcport);
+	writeb (data, hp->hcport2);
+	wmb ();
+}
+
+/*****************************************************************
+ *
+ * Function Name: init_irq [arm]
+ *
+ * This function is board specific.  It sets up the interrupt to
+ * be an edge trigger and trigger on the rising edge
+ *
+ * Input: none
+ *
+ * Return value  : none
+ *
+ *****************************************************************/
+static void inline init_irq (void)
+{
+#if defined(CONFIG_SIGNAL_MCP751)
+	// ICR4 enable INT5
+	{
+	volatile unsigned long *icrp;
+
+	// PORTD configure pin K3 for INT5
+	*((volatile unsigned long  *) (MCF_MBAR+MCFSIM_PDCNT)) |= 0x000000C0;
+
+	// transition low to high
+	*((volatile unsigned long  *) (MCF_MBAR+MCFSIM_PITR)) |= 0x00000040;
+
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR4);
+	*icrp = (*icrp & 0x70777777) | 0x0d000000; // INT5
+	}
+#endif
+}
+
+/*****************************************************************
+ *
+ * Function Name: release_regions [arm]
+ *
+ * This function is board specific.  It frees all io address.
+ *
+ * Input: hcipriv_t *
+ *
+ * Return value  : none
+ *
+ *****************************************************************/
+static void inline sl811_release_regions (hcipriv_t *hp)
+{
+}
+
+/*****************************************************************
+ *
+ * Function Name: request_regions [arm]
+ *
+ * This function is board specific. It request all io address and
+ * maps into memory (if can).
+ *
+ * Input: hcipriv_t *
+ *
+ * Return value  : 0 = OK
+ *
+ *****************************************************************/
+static int inline sl811_request_regions (hcipriv_t *hp, int addr1, int addr2)
+{
+	hp->hcport = addr1;
+	hp->hcport2 = addr2;
+
+	return 0;
+}
+
diff -urN linux-2.4.29/include/asm-m68knommu/hdreg.h linux-2.4.29-uc1/include/asm-m68knommu/hdreg.h
--- linux-2.4.29/include/asm-m68knommu/hdreg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/hdreg.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/hdreg.h>
diff -urN linux-2.4.29/include/asm-m68knommu/hw_irq.h linux-2.4.29-uc1/include/asm-m68knommu/hw_irq.h
--- linux-2.4.29/include/asm-m68knommu/hw_irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/hw_irq.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+/* place holder for now */
diff -urN linux-2.4.29/include/asm-m68knommu/hwtest.h linux-2.4.29-uc1/include/asm-m68knommu/hwtest.h
--- linux-2.4.29/include/asm-m68knommu/hwtest.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/hwtest.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/hwtest.h>
diff -urN linux-2.4.29/include/asm-m68knommu/ide.h linux-2.4.29-uc1/include/asm-m68knommu/ide.h
--- linux-2.4.29/include/asm-m68knommu/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/ide.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,56 @@
+#ifndef _M68KNOMMU_IDE_H
+#define _M68KNOMMU_IDE_H
+#ifdef __KERNEL__
+/****************************************************************************/
+/*
+ *  linux/include/asm-m68knommu/ide.h
+ *
+ *  Copyright (C) 2001-2003  David McCullough <davidm@snapgear.com>
+ */
+/****************************************************************************/
+
+#include <linux/config.h>
+
+#include <asm/setup.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+/****************************************************************************/
+
+#undef SUPPORT_SLOW_DATA_PORTS
+#define SUPPORT_SLOW_DATA_PORTS 0
+
+#undef SUPPORT_VLB_SYNC
+#define SUPPORT_VLB_SYNC 0
+
+#ifndef MAX_HWIFS
+#define MAX_HWIFS 4
+#endif
+
+#define IDE_ARCH_ACK_INTR 1
+#define ide_ack_intr(hwif) ((hwif)->hw.ack_intr?(hwif)->hw.ack_intr(hwif):1)
+
+/****************************************************************************/
+/* these guys are not used,  the uclinux.c driver does it all for us        */
+
+static __inline__ int ide_default_irq(ide_ioreg_t base) { return 0; }
+static __inline__ ide_ioreg_t ide_default_io_base(int index) { return 0; }
+static __inline__ void ide_init_default_hwifs(void) { }
+
+static __inline__ void ide_init_hwif_ports(hw_regs_t *hw,
+		                       ide_ioreg_t data_port, ide_ioreg_t ctrl_port,
+							   int *irq)
+{
+}
+
+/****************************************************************************/
+/* some bits needed for parts of the IDE subsystem to compile               */
+
+#define __ide_mm_insw(port, addr, n)	insw((u16 *)port, addr, n)
+#define __ide_mm_insl(port, addr, n)	insl((u32 *)port, addr, n)
+#define __ide_mm_outsw(port, addr, n)	outsw((u16 *)port, addr, n)
+#define __ide_mm_outsl(port, addr, n)	outsl((u32 *)port, addr, n)
+
+/****************************************************************************/
+#endif /* __KERNEL__ */
+#endif /* _M68KNOMMU_IDE_H */
diff -urN linux-2.4.29/include/asm-m68knommu/init.h linux-2.4.29-uc1/include/asm-m68knommu/init.h
--- linux-2.4.29/include/asm-m68knommu/init.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/init.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/init.h>
diff -urN linux-2.4.29/include/asm-m68knommu/ioctl.h linux-2.4.29-uc1/include/asm-m68knommu/ioctl.h
--- linux-2.4.29/include/asm-m68knommu/ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/ioctl.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/ioctl.h>
diff -urN linux-2.4.29/include/asm-m68knommu/ioctls.h linux-2.4.29-uc1/include/asm-m68knommu/ioctls.h
--- linux-2.4.29/include/asm-m68knommu/ioctls.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/ioctls.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/ioctls.h>
diff -urN linux-2.4.29/include/asm-m68knommu/io.h linux-2.4.29-uc1/include/asm-m68knommu/io.h
--- linux-2.4.29/include/asm-m68knommu/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/io.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,190 @@
+#ifndef _M68KNOMMU_IO_H
+#define _M68KNOMMU_IO_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <asm/virtconvert.h>
+
+/*
+ * These are for ISA/PCI shared memory _only_ and should never be used
+ * on any other type of memory, including Zorro memory. They are meant to
+ * access the bus in the bus byte order which is little-endian!.
+ *
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the m68k architecture, we just read/write the
+ * memory location directly.
+ */
+/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
+ * two accesses to memory, which may be undesireable for some devices.
+ */
+
+/*
+ * swap functions are sometimes needed to interface little-endian hardware
+ */
+
+/*
+ * CHANGES
+ * 
+ * 020325   Added some #define's for the COBRA5272 board
+ *          (hede)
+ */
+static inline unsigned short _swapw(volatile unsigned short v)
+{
+    return ((v << 8) | (v >> 8));
+}
+
+static inline unsigned int _swapl(volatile unsigned long v)
+{
+    return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
+}
+
+#define readb(addr) \
+    ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
+#define readw(addr) \
+    ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
+#define readl(addr) \
+    ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
+
+#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
+
+/*
+ * The following are some defines we need for MTD with our
+ * COBRA5272 board.
+ * Because I don't know if they break something I have
+ * #ifdef'd them.
+ * (020325 - hede)
+ * As far as I can see they are safe, lets try
+ * them always included - DAVIDM
+ */
+#if 1 /* def CONFIG_COBRA5272 */
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
+#endif /* CONFIG_COBRA5272 */
+
+static inline void io_outsb(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned char *ap = (volatile unsigned char *) addr;
+	unsigned char *bp = (unsigned char *) buf;
+	while (len--)
+		*ap = *bp++;
+}
+
+static inline void io_outsw(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned short *ap = (volatile unsigned short *) addr;
+	unsigned short *bp = (unsigned short *) buf;
+	while (len--)
+		*ap = _swapw(*bp++);
+}
+
+static inline void io_outsl(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned int *ap = (volatile unsigned int *) addr;
+	unsigned int *bp = (unsigned int *) buf;
+	while (len--)
+		*ap = _swapl(*bp++);
+}
+
+static inline void io_insb(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned char *ap = (volatile unsigned char *) addr;
+	unsigned char *bp = (unsigned char *) buf;
+	while (len--)
+		*bp++ = *ap;
+}
+
+static inline void io_insw(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned short *ap = (volatile unsigned short *) addr;
+	unsigned short *bp = (unsigned short *) buf;
+	while (len--)
+		*bp++ = _swapw(*ap);
+}
+
+static inline void io_insl(unsigned int addr, void *buf, int len)
+{
+	volatile unsigned int *ap = (volatile unsigned int *) addr;
+	unsigned int *bp = (unsigned int *) buf;
+	while (len--)
+		*bp++ = _swapl(*ap);
+}
+
+/*
+ *	make the short names macros so specific devices
+ *	can override them as required
+ */
+
+#define memset_io(a,b,c)	memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
+
+#define inb(addr)      readb(addr)
+#define inw(addr)    readw(addr)
+#define inl(addr)    readl(addr)
+#define outb(x,addr) ((void) writeb(x,addr))
+#define outw(x,addr) ((void) writew(x,addr))
+#define outl(x,addr) ((void) writel(x,addr))
+
+#define inb_p(addr)    inb(addr)
+#define inw_p(addr)    inw(addr)
+#define inl_p(addr)    inl(addr)
+#define outb_p(x,addr) outb(x,addr)
+#define outw_p(x,addr) outw(x,addr)
+#define outl_p(x,addr) outl(x,addr)
+
+#define outsb(a,b,l) io_outsb(a,b,l)
+#define outsw(a,b,l) io_outsw(a,b,l)
+#define outsl(a,b,l) io_outsl(a,b,l)
+
+#define insb(a,b,l) io_insb(a,b,l)
+#define insw(a,b,l) io_insw(a,b,l)
+#define insl(a,b,l) io_insl(a,b,l)
+
+#define IO_SPACE_LIMIT 0xffff
+
+
+/* Values for nocacheflag and cmode */
+#define IOMAP_FULL_CACHING		0
+#define IOMAP_NOCACHE_SER		1
+#define IOMAP_NOCACHE_NONSER		2
+#define IOMAP_WRITETHROUGH		3
+
+extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
+extern void __iounmap(void *addr, unsigned long size);
+
+extern inline void *ioremap(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+extern inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+extern inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
+}
+extern inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
+}
+
+extern void iounmap(void *addr);
+
+/* Nothing to do */
+
+#define dma_cache_inv(_start,_size)		do { } while (0)
+#define dma_cache_wback(_start,_size)		do { } while (0)
+#define dma_cache_wback_inv(_start,_size)	do { } while (0)
+
+#endif /* __KERNEL__ */
+
+#endif /* _M68KNOMMU_IO_H */
diff -urN linux-2.4.29/include/asm-m68knommu/io_hw_swap.h linux-2.4.29-uc1/include/asm-m68knommu/io_hw_swap.h
--- linux-2.4.29/include/asm-m68knommu/io_hw_swap.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/io_hw_swap.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,94 @@
+#ifndef _M68K_IO_HW_SWAP_H
+#define _M68K_IO_HW_SWAP_H
+
+/*
+ * swap functions are sometimes needed to interface little-endian hardware
+ */
+static inline unsigned short _swapw(volatile unsigned short v)
+{
+    return ((v << 8) | (v >> 8));
+}
+
+static inline unsigned int _swapl(volatile unsigned long v)
+{
+    return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
+}
+
+/*
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the m68k architecture, we just read/write the
+ * memory location directly.
+ */
+/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
+ * two accesses to memory, which may be undesireable for some devices.
+ */
+#define readb(addr) \
+    ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
+#define readw(addr) \
+    ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
+#define readl(addr) \
+    ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
+
+#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+
+/* There is no difference between I/O and memory on 68k, these are the same */
+#define inb(addr) \
+    ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
+#define inw(addr) \
+    ({ unsigned short __v = (*(volatile unsigned short *) (addr)); \
+       _swapw(__v); })
+#define inl(addr) \
+    ({ unsigned int __v = (*(volatile unsigned int *) (addr)); _swapl(__v); })
+
+#define outb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
+#define outw(b,addr) ((*(volatile unsigned short *) (addr)) = (_swapw(b)))
+#define outl(b,addr) ((*(volatile unsigned int *) (addr)) = (_swapl(b)))
+
+/* FIXME: these need to be optimized.  Watch out for byte swapping, they
+ * are used mostly for Intel devices... */
+#define outsw(addr,buf,len) \
+    ({ unsigned short * __p = (unsigned short *)(buf); \
+       unsigned short * __e = (unsigned short *)(__p) + (len); \
+       while (__p < __e) { \
+	  *(volatile unsigned short *)(addr) = *__p++;\
+       } \
+     })
+
+#define insw(addr,buf,len) \
+    ({ unsigned short * __p = (unsigned short *)(buf); \
+       unsigned short * __e = (unsigned short *)(__p) + (len); \
+       while (__p < __e) { \
+          *(__p++) = *(volatile unsigned short *)(addr); \
+       } \
+     })
+
+
+static inline unsigned char get_user_byte_io(const char * addr)
+{
+	register unsigned char _v;
+
+	__asm__ __volatile__ ("moveb %1,%0":"=dm" (_v):"m" (*addr));
+	return _v;
+}
+#define inb_p(addr) get_user_byte_io((char *)(addr))
+
+static inline void put_user_byte_io(char val,char *addr)
+{
+	__asm__ __volatile__ ("moveb %0,%1"
+			      : /* no outputs */
+			      :"idm" (val),"m" (*addr)
+			      : "memory");
+}
+#define outb_p(x,addr) put_user_byte_io((x),(char *)(addr))
+
+/*
+ * IO bus memory addresses are also 1:1 with the physical address
+ */
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+
+#endif /* _M68K_IO_HW_SWAP_H */
diff -urN linux-2.4.29/include/asm-m68knommu/ipcbuf.h linux-2.4.29-uc1/include/asm-m68knommu/ipcbuf.h
--- linux-2.4.29/include/asm-m68knommu/ipcbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/ipcbuf.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/ipcbuf.h>
diff -urN linux-2.4.29/include/asm-m68knommu/ipc.h linux-2.4.29-uc1/include/asm-m68knommu/ipc.h
--- linux-2.4.29/include/asm-m68knommu/ipc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/ipc.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/ipc.h>
diff -urN linux-2.4.29/include/asm-m68knommu/irq.h linux-2.4.29-uc1/include/asm-m68knommu/irq.h
--- linux-2.4.29/include/asm-m68knommu/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/irq.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,153 @@
+#ifndef _M68K_IRQ_H_
+#define _M68K_IRQ_H_
+
+#include <linux/config.h>
+
+#ifdef CONFIG_COLDFIRE
+/*
+ *	On the ColdFire we keep track of all vectors. That way drivers
+ *	can register whatever vector number they wish, and we can deal
+ *	with it.
+ */
+#define	SYS_IRQS	256
+#define	NR_IRQS		SYS_IRQS
+
+#else
+
+/*
+ * # of m68k interrupts
+ */
+
+#define SYS_IRQS 8
+
+/*
+ * This should be the same as the max(NUM_X_SOURCES) for all the
+ * different m68k hosts compiled into the kernel.
+ * Currently the Atari has 72 and the Amiga 24, but if both are
+ * supported in the kernel it is better to make room for 72.
+ */
+#if defined(CONFIG_ATARI) || defined(CONFIG_MAC)
+#define NR_IRQS (72+SYS_IRQS)
+#else
+#define NR_IRQS (24+SYS_IRQS)
+#endif
+#endif /* CONFIG_COLDFIRE */
+
+/*
+ * Interrupt source definitions
+ * General interrupt sources are the level 1-7.
+ * Adding an interrupt service routine for one of these sources
+ * results in the addition of that routine to a chain of routines.
+ * Each one is called in succession.  Each individual interrupt
+ * service routine should determine if the device associated with
+ * that routine requires service.
+ */
+
+#define IRQ1		(1)	/* level 1 interrupt */
+#define IRQ2		(2)	/* level 2 interrupt */
+#define IRQ3		(3)	/* level 3 interrupt */
+#define IRQ4		(4)	/* level 4 interrupt */
+#define IRQ5		(5)	/* level 5 interrupt */
+#define IRQ6		(6)	/* level 6 interrupt */
+#define IRQ7		(7)	/* level 7 interrupt (non-maskable) */
+
+/*
+ * "Generic" interrupt sources
+ */
+
+#define IRQ_SCHED_TIMER	(8)    /* interrupt source for scheduling timer */
+
+static __inline__ int irq_cannonicalize(int irq)
+{
+	return irq;
+}
+
+/*
+ * Machine specific interrupt sources.
+ *
+ * Adding an interrupt service routine for a source with this bit
+ * set indicates a special machine specific interrupt source.
+ * The machine specific files define these sources.
+ *
+ * The IRQ_MACHSPEC bit is now gone - the only thing it did was to
+ * introduce unnecessary overhead.
+ *
+ * All interrupt handling is actually machine specific so it is better
+ * to use function pointers, as used by the Sparc port, and select the
+ * interrupt handling functions when initializing the kernel. This way
+ * we save some unnecessary overhead at run-time. 
+ *                                                      01/11/97 - Jes
+ */
+
+extern void (*mach_enable_irq)(unsigned int);
+extern void (*mach_disable_irq)(unsigned int);
+
+extern int sys_request_irq(unsigned int, 
+	void (*)(int, void *, struct pt_regs *), 
+	unsigned long, const char *, void *);
+extern void sys_free_irq(unsigned int, void *);
+
+/*
+ * various flags for request_irq() - the Amiga now uses the standard
+ * mechanism like all other architectures - SA_INTERRUPT and SA_SHIRQ
+ * are your friends.
+ */
+#ifndef CONFIG_AMIGA
+#define IRQ_FLG_LOCK	(0x0001)	/* handler is not replaceable	*/
+#define IRQ_FLG_REPLACE	(0x0002)	/* replace existing handler	*/
+#define IRQ_FLG_FAST	(0x0004)
+#define IRQ_FLG_SLOW	(0x0008)
+#define IRQ_FLG_STD	(0x8000)	/* internally used		*/
+#endif
+
+#ifdef CONFIG_M68360
+
+#define CPM_INTERRUPT    IRQ4
+
+/* see MC68360 User's Manual, p. 7-377  */
+#define CPM_VECTOR_BASE  0x04           /* 3 MSbits of CPM vector */
+
+#endif /* CONFIG_M68360 */
+
+/*
+ * This structure is used to chain together the ISRs for a particular
+ * interrupt source (if it supports chaining).
+ */
+typedef struct irq_node {
+	void		(*handler)(int, void *, struct pt_regs *);
+	unsigned long	flags;
+	void		*dev_id;
+	const char	*devname;
+	struct irq_node *next;
+} irq_node_t;
+
+/*
+ * This structure has only 4 elements for speed reasons
+ */
+typedef struct irq_handler {
+	void		(*handler)(int, void *, struct pt_regs *);
+	unsigned long	flags;
+	void		*dev_id;
+	const char	*devname;
+} irq_handler_t;
+
+/* count of spurious interrupts */
+extern volatile unsigned int num_spurious;
+
+#ifndef CONFIG_COLDFIRE
+/*
+ * This function returns a new irq_node_t
+ */
+extern irq_node_t *new_irq_node(void);
+#endif /* CONFIG_COLDFIRE */
+
+/*
+ * Some drivers want these entry points
+ */
+#define enable_irq(x)	(mach_enable_irq  ? (*mach_enable_irq)(x)  : 0)
+#define disable_irq(x)	(mach_disable_irq ? (*mach_disable_irq)(x) : 0)
+
+#define enable_irq_nosync(x)	enable_irq(x)
+#define disable_irq_nosync(x)	disable_irq(x)
+
+#endif /* _M68K_IRQ_H_ */
diff -urN linux-2.4.29/include/asm-m68knommu/keyboard.h linux-2.4.29-uc1/include/asm-m68knommu/keyboard.h
--- linux-2.4.29/include/asm-m68knommu/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/keyboard.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+ *  linux/include/asm-m68knommu/keyboard.h
+ *  Created 04 Dec 2001 by Khaled Hassounah <khassounah@mediumware.net>
+ *  This file contains the Dragonball architecture specific keyboard definitions
+ */
+
+#ifndef _M68KNOMMU_KEYBOARD_H
+#define _M68KNOMMU_KEYBOARD_H
+
+#include <linux/config.h>
+
+#if 0
+#define kbd_setkeycode(x...)    (-ENOSYS)
+#define kbd_getkeycode(x...)    (-ENOSYS)
+#define kbd_translate(sc_,kc_,rm_)	((*(kc_)=(sc_)),1)
+#define kbd_unexpected_up(x...) (1)
+#define kbd_leds(x...)		do { } while (0)
+#define kbd_init_hw(x...)	do { } while (0)
+#define kbd_enable_irq(x...)	do { } while (0)
+#define kbd_disable_irq(x...)	do { } while (0)
+
+#else
+
+/* dummy i.e. no real keyboard */
+#define kbd_setkeycode(x...)	(-ENOSYS)
+#define kbd_getkeycode(x...)	(-ENOSYS)
+#define kbd_translate(x...)	(0)
+#define kbd_unexpected_up(x...)	(1)
+#define kbd_leds(x...)		do {;} while (0)
+#define kbd_init_hw(x...)	do {;} while (0)
+#define kbd_enable_irq(x...)	do {;} while (0)
+#define kbd_disable_irq(x...)	do {;} while (0)
+
+#endif
+
+
+/* needed if MAGIC_SYSRQ is enabled for serial console */
+#ifndef SYSRQ_KEY
+#define SYSRQ_KEY		((unsigned char)(-1))
+#define kbd_sysrq_xlate         ((unsigned char *)NULL)
+#endif
+
+
+#endif  /* _M68KNOMMU_KEYBOARD_H */
+
+
+
diff -urN linux-2.4.29/include/asm-m68knommu/kmap_types.h linux-2.4.29-uc1/include/asm-m68knommu/kmap_types.h
--- linux-2.4.29/include/asm-m68knommu/kmap_types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/kmap_types.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/kmap_types.h>
diff -urN linux-2.4.29/include/asm-m68knommu/linux_logo.h linux-2.4.29-uc1/include/asm-m68knommu/linux_logo.h
--- linux-2.4.29/include/asm-m68knommu/linux_logo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/linux_logo.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,12 @@
+/*
+ * include/asm-m68knommu/linux_logo.h: This is a linux logo
+ *                                 to be displayed on boot.
+ */
+ 
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/version.h>
+
+#define linux_logo_banner "Linux/m68knommu version " UTS_RELEASE
+
+#include <linux/linux_logo.h>
diff -urN linux-2.4.29/include/asm-m68knommu/m5206sim.h linux-2.4.29-uc1/include/asm-m68knommu/m5206sim.h
--- linux-2.4.29/include/asm-m68knommu/m5206sim.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/m5206sim.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,132 @@
+/****************************************************************************/
+
+/*
+ *	m5206sim.h -- ColdFire 5206 System Integration Module support.
+ *
+ *	(C) Copyright 1999, Greg Ungerer (gerg@snapgear.com)
+ * 	(C) Copyright 2000, Lineo Inc. (www.lineo.com) 
+ */
+
+/****************************************************************************/
+#ifndef	m5206sim_h
+#define	m5206sim_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Define the 5206 SIM register set addresses.
+ */
+#define	MCFSIM_SIMR		0x03		/* SIM Config reg (r/w) */
+#define	MCFSIM_ICR1		0x14		/* Intr Ctrl reg 1 (r/w) */
+#define	MCFSIM_ICR2		0x15		/* Intr Ctrl reg 2 (r/w) */
+#define	MCFSIM_ICR3		0x16		/* Intr Ctrl reg 3 (r/w) */
+#define	MCFSIM_ICR4		0x17		/* Intr Ctrl reg 4 (r/w) */
+#define	MCFSIM_ICR5		0x18		/* Intr Ctrl reg 5 (r/w) */
+#define	MCFSIM_ICR6		0x19		/* Intr Ctrl reg 6 (r/w) */
+#define	MCFSIM_ICR7		0x1a		/* Intr Ctrl reg 7 (r/w) */
+#define	MCFSIM_ICR8		0x1b		/* Intr Ctrl reg 8 (r/w) */
+#define	MCFSIM_ICR9		0x1c		/* Intr Ctrl reg 9 (r/w) */
+#define	MCFSIM_ICR10		0x1d		/* Intr Ctrl reg 10 (r/w) */
+#define	MCFSIM_ICR11		0x1e		/* Intr Ctrl reg 11 (r/w) */
+#define	MCFSIM_ICR12		0x1f		/* Intr Ctrl reg 12 (r/w) */
+#define	MCFSIM_ICR13		0x20		/* Intr Ctrl reg 13 (r/w) */
+#ifdef CONFIG_M5206e
+#define	MCFSIM_ICR14		0x21		/* Intr Ctrl reg 14 (r/w) */
+#define	MCFSIM_ICR15		0x22		/* Intr Ctrl reg 15 (r/w) */
+#endif
+
+#define MCFSIM_IMR		0x36		/* Interrupt Mask reg (r/w) */
+#define MCFSIM_IPR		0x3a		/* Interrupt Pend reg (r/w) */
+
+#define	MCFSIM_RSR		0x40		/* Reset Status reg (r/w) */
+#define	MCFSIM_SYPCR		0x41		/* System Protection reg (r/w)*/
+
+#define	MCFSIM_SWIVR		0x42		/* SW Watchdog intr reg (r/w) */
+#define	MCFSIM_SWSR		0x43		/* SW Watchdog service (r/w) */
+
+#define	MCFSIM_DCRR		0x46		/* DRAM Refresh reg (r/w) */
+#define	MCFSIM_DCTR		0x4a		/* DRAM Timing reg (r/w) */
+#define	MCFSIM_DCAR0		0x4c		/* DRAM 0 Address reg(r/w) */
+#define	MCFSIM_DCMR0		0x50		/* DRAM 0 Mask reg (r/w) */
+#define	MCFSIM_DCCR0		0x57		/* DRAM 0 Control reg (r/w) */
+#define	MCFSIM_DCAR1		0x58		/* DRAM 1 Address reg (r/w) */
+#define	MCFSIM_DCMR1		0x5c		/* DRAM 1 Mask reg (r/w) */
+#define	MCFSIM_DCCR1		0x63		/* DRAM 1 Control reg (r/w) */
+
+#define	MCFSIM_CSAR0		0x64		/* CS 0 Address 0 reg (r/w) */
+#define	MCFSIM_CSMR0		0x68		/* CS 0 Mask 0 reg (r/w) */
+#define	MCFSIM_CSCR0		0x6e		/* CS 0 Control reg (r/w) */
+#define	MCFSIM_CSAR1		0x70		/* CS 1 Address reg (r/w) */
+#define	MCFSIM_CSMR1		0x74		/* CS 1 Mask reg (r/w) */
+#define	MCFSIM_CSCR1		0x7a		/* CS 1 Control reg (r/w) */
+#define	MCFSIM_CSAR2		0x7c		/* CS 2 Address reg (r/w) */
+#define	MCFSIM_CSMR2		0x80		/* CS 2 Mask reg (r/w) */
+#define	MCFSIM_CSCR2		0x86		/* CS 2 Control reg (r/w) */
+#define	MCFSIM_CSAR3		0x88		/* CS 3 Address reg (r/w) */
+#define	MCFSIM_CSMR3		0x8c		/* CS 3 Mask reg (r/w) */
+#define	MCFSIM_CSCR3		0x92		/* CS 3 Control reg (r/w) */
+#define	MCFSIM_CSAR4		0x94		/* CS 4 Address reg (r/w) */
+#define	MCFSIM_CSMR4		0x98		/* CS 4 Mask reg (r/w) */
+#define	MCFSIM_CSCR4		0x9e		/* CS 4 Control reg (r/w) */
+#define	MCFSIM_CSAR5		0xa0		/* CS 5 Address reg (r/w) */
+#define	MCFSIM_CSMR5		0xa4		/* CS 5 Mask reg (r/w) */
+#define	MCFSIM_CSCR5		0xaa		/* CS 5 Control reg (r/w) */
+#define	MCFSIM_CSAR6		0xac		/* CS 6 Address reg (r/w) */
+#define	MCFSIM_CSMR6		0xb0		/* CS 6 Mask reg (r/w) */
+#define	MCFSIM_CSCR6		0xb6		/* CS 6 Control reg (r/w) */
+#define	MCFSIM_CSAR7		0xb8		/* CS 7 Address reg (r/w) */
+#define	MCFSIM_CSMR7		0xbc		/* CS 7 Mask reg (r/w) */
+#define	MCFSIM_CSCR7		0xc2		/* CS 7 Control reg (r/w) */
+#define	MCFSIM_DMCR		0xc6		/* Default control */
+
+#ifdef CONFIG_M5206e
+#define	MCFSIM_PAR		0xca		/* Pin Assignment reg (r/w) */
+#else
+#define	MCFSIM_PAR		0xcb		/* Pin Assignment reg (r/w) */
+#endif
+
+#define	MCFSIM_PADDR		0x1c5		/* Parallel Direction (r/w) */
+#define	MCFSIM_PADAT		0x1c9		/* Parallel Port Value (r/w) */
+
+/*
+ *	Some symbol defines for the Parallel Port Pin Assignment Register
+ */
+#ifdef CONFIG_M5206e
+#define MCFSIM_PAR_DREQ0        0x100           /* Set to select DREQ0 input */
+                                                /* Clear to select T0 input */
+#define MCFSIM_PAR_DREQ1        0x200           /* Select DREQ1 input */
+                                                /* Clear to select T0 output */
+#endif
+
+/*
+ *	Some symbol defines for the Interrupt Control Register
+ */
+#define	MCFSIM_SWDICR		MCFSIM_ICR8	/* Watchdog timer ICR */
+#define	MCFSIM_TIMER1ICR	MCFSIM_ICR9	/* Timer 1 ICR */
+#define	MCFSIM_TIMER2ICR	MCFSIM_ICR10	/* Timer 2 ICR */
+#define	MCFSIM_UART1ICR		MCFSIM_ICR12	/* UART 1 ICR */
+#define	MCFSIM_UART2ICR		MCFSIM_ICR13	/* UART 2 ICR */
+#ifdef CONFIG_M5206e
+#define	MCFSIM_DMA1ICR		MCFSIM_ICR14	/* DMA 1 ICR */
+#define	MCFSIM_DMA2ICR		MCFSIM_ICR15	/* DMA 2 ICR */
+#endif
+
+#if defined(CONFIG_M5206e)
+#define	MCFSIM_IMR_MASKALL	0xfffe		/* All SIM intr sources */
+#endif
+
+/*
+ *	Macro to get and set IMR register. It is 16 bits on the 5206.
+ */
+#define	mcf_getimr()		\
+	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR))
+
+#define	mcf_setimr(imr)		\
+	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR)) = (imr)
+
+#define	mcf_getipr()		\
+	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_IPR))
+
+/****************************************************************************/
+#endif	/* m5206sim_h */
diff -urN linux-2.4.29/include/asm-m68knommu/m5235sim.h linux-2.4.29-uc1/include/asm-m68knommu/m5235sim.h
--- linux-2.4.29/include/asm-m68knommu/m5235sim.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/m5235sim.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,43 @@
+/****************************************************************************/
+
+/*
+ *	m5235sim.h -- ColdFire 5235 System Integration Module support.
+ *
+ *	(C) Copyright 2003, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/****************************************************************************/
+#ifndef	m5235sim_h
+#define	m5235sim_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Define the 5235 SIM register set addresses.
+ */
+#define	MCFICM_INTC0		0x0c00		/* Base for Interrupt Ctrl 0 */
+#define	MCFICM_INTC1		0x0d00		/* Base for Interrupt Ctrl 0 */
+#define	MCFINTC_IPRH		0x00		/* Interrupt pending 32-63 */
+#define	MCFINTC_IPRL		0x04		/* Interrupt pending 1-31 */
+#define	MCFINTC_IMRH		0x08		/* Interrupt mask 32-63 */
+#define	MCFINTC_IMRL		0x0c		/* Interrupt mask 1-31 */
+#define	MCFINTC_INTFRCH		0x10		/* Interrupt force 32-63 */
+#define	MCFINTC_INTFRCL		0x14		/* Interrupt force 1-31 */
+#define	MCFINTC_IRLR		0x18		/* */
+#define	MCFINTC_IACKL		0x19		/* */
+#define	MCFINTC_ICR0		0x40		/* Base ICR register */
+
+#define	MCFINT_UART0		13		/* Interrupt number for UART0 */
+#define	MCFINT_QSPI		18		/* Interrupt number for QSPI */
+#define	MCFINT_PIT1		36		/* Interrupt number for PIT1 */
+
+#define MCFINT_CAN_BUF00	43		/* Interrupt for CAN Buffer*/
+#define MCFINT_CAN_BUF01	44		/* Interrupt for CAN Buffer*/
+#define MCFINT_CAN_WARN		59		/* Interrupt for CAN Error int*/
+#define MCFINT_CAN_BUSOFF	60		/* Interrupt for CAN On/Off */
+
+#define MCF5235_GPIO_PFECI2CPAR 0x100047        /* */
+
+/****************************************************************************/
+#endif	/* m5235sim_h */
diff -urN linux-2.4.29/include/asm-m68knommu/m5249audio.h linux-2.4.29-uc1/include/asm-m68knommu/m5249audio.h
--- linux-2.4.29/include/asm-m68knommu/m5249audio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/m5249audio.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,163 @@
+/****************************************************************************/
+
+/*
+ *	m5249audio.h -- ColdFire internal audio support defines.
+ *
+ *	(C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/****************************************************************************/
+#ifndef	m5249audio_h
+#define	m5249audio_h
+/****************************************************************************/
+
+/*
+ *	Define the ColdFire audio register set addresses.
+ */
+#define	MCFA_IISCONFIG		0x10		/* IIS config regs (r/w) */
+#define	MCFA_IIS1CONFIG		0x10		/* IIS1 config reg (r/w) */
+#define	MCFA_IIS2CONFIG		0x14		/* IIS2 config reg (r/w) */
+#define	MCFA_IIS3CONFIG		0x18		/* IIS3 config reg (r/w) */
+#define	MCFA_IIS4CONFIG		0x1c		/* IIS4 config reg (r/w) */
+
+#define	MCFA_DATAINCTRL		0x30		/* Data in Control reg (r/w) */
+
+#define	MCFA_PDIR1L		0x34		/* Data in left #1 (r) */
+#define	MCFA_PDIR3L		0x44		/* Data in left #3 (r) */
+#define	MCFA_PDIR1R		0x54		/* Data in right #1 (r) */
+#define	MCFA_PDIR3R		0x64		/* Data in right #3 (r) */
+#define	MCFA_PDOR1L		0x34		/* Data out left #1 (w) */
+#define	MCFA_PDOR1R		0x44		/* Data out right #1 (w) */
+#define	MCFA_PDOR2L		0x54		/* Data out left #2 (w) */
+#define	MCFA_PDOR2R		0x64		/* Data out right #2 (w) */
+#define	MCFA_PDOR3		0x74		/* Data out l+r #3 (w) */
+#define	MCFA_PDIR2		0x74		/* Data in l+r #2 (w) */
+
+#define	MCFA_INTENABLE		0x94		/* Interrupt enable (r/w) */
+#define	MCFA_INTCLEAR		0x98		/* Interrupt clear (w) */
+#define	MCFA_INTSTAT		0x98		/* Interupt status (r) */
+
+#define	MCFA_DMACONF		0x9f		/* Audio DMA config (r/w) */
+
+#define	MCFA_AUDIOGLOB		0xcc		/* Audio glob register (r/w) */
+
+
+/*
+ *	Flag defines for the IIS configuration registers.
+ */
+#define	MCFA_IIS_EFCFLG		0x00040000	/* EF/CFLG insert */
+#define	MCFA_IIS_CFLGPOS	0x00020000	/* CFLG sample position */
+#define	MCFA_IIS_CLKINPUT	0x00000000	/* CLK is SCLK/LRCLK input */
+#define	MCFA_IIS_CLK24		0x00001000	/* CLK is AudioClk/24 */
+#define	MCFA_IIS_CLK16		0x00002000	/* CLK is AudioClk/16 */
+#define	MCFA_IIS_CLK12		0x00003000	/* CLK is AudioClk/12 */
+#define	MCFA_IIS_CLK8		0x00004000	/* CLK is AudioClk/8 */
+#define	MCFA_IIS_CLK6		0x00005000	/* CLK is AudioClk/6 */
+#define	MCFA_IIS_CLK4		0x00006000	/* CLK is AudioClk/4 */
+#define	MCFA_IIS_CLK3		0x00007000	/* CLK is AudioClk/3 */
+#define	MCFA_IIS_CLK2		0x0000c000	/* CLK is AudioClk/2 */
+#define	MCFA_IIS_CLKIIS1	0x00008000	/* CLK is IIS1 clock */
+#define	MCFA_IIS_CLKIIS2	0x00009000	/* CLK is IIS2 clock */
+#define	MCFA_IIS_CLKIIS3	0x0000a000	/* CLK is IIS3 clock */
+#define	MCFA_IIS_CLKIIS4	0x0000b000	/* CLK is IIS4 clock */
+#define	MCFA_IIS_FIFO		0x00000000	/* Normal FIFO operation */
+#define	MCFA_IIS_FIFO1		0x00000800	/* 1 sample FIFO mode */
+#define	MCFA_IIS_TXSRC_0	0x00000000	/* TX source is digital 0 */
+#define	MCFA_IIS_TXSRC_PDOR1	0x00000100	/* TX source is PDOR1 */
+#define	MCFA_IIS_TXSRC_PDOR2	0x00000200	/* TX source is PDOR2 */
+#define	MCFA_IIS_TXSRC_PDOR3	0x00000300	/* TX source is PDOR3 */
+#define	MCFA_IIS_TXSRC_IIS1	0x00000400	/* TX source is IIS1 in data */
+#define	MCFA_IIS_TXSRC_IIS3	0x00000500	/* TX source is IIS3 in data */
+#define	MCFA_IIS_TXSRC_IIS4	0x00000600	/* TX source is IIS4 in data */
+#define	MCFA_IIS_TXSRC_EBU	0x00000700	/* TX source is EBU in data */
+#define	MCFA_IIS_TXSRC_EBU2	0x00010000	/* TX source is EBU2 in data */
+#define	MCFA_IIS_16BIT		0x00000000	/* 16 bit samples */
+#define	MCFA_IIS_18BIT		0x00000040	/* 18 bit samples */
+#define	MCFA_IIS_20BIT		0x00000080	/* 20 bit samples */
+#define	MCFA_IIS_0BIT		0x000000c0	/* 0 sample */
+#define	MCFA_IIS_MODE_IIS	0x00000000	/* Philips IIS mode */
+#define	MCFA_IIS_MODE_EIAJ	0x00000000	/* Sony EIAJ mode */
+#define	MCFA_IIS_LRCK64BIT	0x00000010	/* LRCK frequency 64 bit clk */
+#define	MCFA_IIS_LRCK48BIT	0x00000008	/* LRCK frequency 48 bit clk */
+#define	MCFA_IIS_LRCK32BIT	0x00000000	/* LRCK frequency 32 bit clk */
+#define	MCFA_IIS_LRCKINV	0x00000002	/* Invert LRCK */
+#define	MCFA_IIS_SCLKINV	0x00000001	/* Invert SCLK */
+
+/*
+ *	Data in Control register flags.
+ */
+#define	MCFA_DIC_PDIR3_0	0x00800000	/* PDIR3 zero control */
+#define	MCFA_DIC_PDIR3_RESET	0x00400000	/* PDIR3 reset */
+#define	MCFA_DIC_PDIR3_1SAMP	0x00000000	/* PDIR3 full on 1 sample */
+#define	MCFA_DIC_PDIR3_2SAMP	0x00100000	/* PDIR3 full on 2 sample */
+#define	MCFA_DIC_PDIR3_3SAMP	0x00200000	/* PDIR3 full on 3 sample */
+#define	MCFA_DIC_PDIR3_6SAMP	0x00300000	/* PDIR3 full on 6 sample */
+#define	MCFA_DIC_PDIR3_OFF	0x00000000	/* PDIR3 Disabled */
+#define	MCFA_DIC_PDIR3_PDOR1	0x00010000	/* PDIR3 PDOR1 data */
+#define	MCFA_DIC_PDIR3_PDOR2	0x00020000	/* PDIR3 PDOR2 data */
+#define	MCFA_DIC_PDIR3_IIS1	0x00040000	/* PDIR3 IIS1 receiver data */
+#define	MCFA_DIC_PDIR3_IIS3	0x00050000	/* PDIR3 IIS3 receiver data */
+#define	MCFA_DIC_PDIR3_IIS4	0x00060000	/* PDIR3 IIS4 receiver data */
+#define	MCFA_DIC_PDIR3_EBU1	0x00070000	/* PDIR3 EBU1 receiver data */
+#define	MCFA_DIC_PDIR3_EBU2	0x00080000	/* PDIR3 EBU2 receiver data */
+#define	MCFA_DIC_PDIR2_1SAMP	0x00000000	/* PDIR2 full on 1 sample */
+#define	MCFA_DIC_PDIR2_2SAMP	0x00004000	/* PDIR2 full on 2 sample */
+#define	MCFA_DIC_PDIR2_3SAMP	0x00008000	/* PDIR2 full on 3 sample */
+#define	MCFA_DIC_PDIR2_6SAMP	0x0000c000	/* PDIR2 full on 6 sample */
+#define	MCFA_DIC_PDIR2_0	0x00000800	/* PDIR2 zero control */
+#define	MCFA_DIC_PDIR1_0	0x00000400	/* PDIR1 zero control */
+#define	MCFA_DIC_PDIR2_RESET	0x00000200	/* PDIR2 reset */
+#define	MCFA_DIC_PDIR1_RESET	0x00000100	/* PDIR1 reset */
+#define	MCFA_DIC_PDIR1_1SAMP	0x00000000	/* PDIR1 full on 1 sample */
+#define	MCFA_DIC_PDIR1_2SAMP	0x00000040	/* PDIR1 full on 2 sample */
+#define	MCFA_DIC_PDIR1_3SAMP	0x00000080	/* PDIR1 full on 3 sample */
+#define	MCFA_DIC_PDIR1_6SAMP	0x000000c0	/* PDIR1 full on 6 sample */
+#define	MCFA_DIC_PDIR2_OFF	0x00000000	/* PDIR2 disable */
+#define	MCFA_DIC_PDIR2_PDOR1	0x00000008	/* PDIR2 PDOR1 data */
+#define	MCFA_DIC_PDIR2_PDOR2	0x00000010	/* PDIR2 PDOR2 data */
+#define	MCFA_DIC_PDIR2_IIS1	0x00000020	/* PDIR2 IIS1 data */
+#define	MCFA_DIC_PDIR2_IIS3	0x00000028	/* PDIR2 IIS3 data */
+#define	MCFA_DIC_PDIR2_IIS4	0x00000030	/* PDIR2 IIS4 data */
+#define	MCFA_DIC_PDIR2_EBU1	0x00000038	/* PDIR2 EBU1 data */
+#define	MCFA_DIC_PDIR2_EBU2	0x00002000	/* PDIR2 EBU1 data */
+#define	MCFA_DIC_PDIR1_OFF	0x00000000	/* PDIR1 disable */
+#define	MCFA_DIC_PDIR1_PDOR1	0x00000001	/* PDIR1 PDOR1 data */
+#define	MCFA_DIC_PDIR1_PDOR2	0x00000002	/* PDIR1 PDOR2 data */
+#define	MCFA_DIC_PDIR1_IIS1	0x00000004	/* PDIR1 IIS1 data */
+#define	MCFA_DIC_PDIR1_IIS3	0x00000005	/* PDIR1 IIS3 data */
+#define	MCFA_DIC_PDIR1_IIS4	0x00000006	/* PDIR1 IIS4 data */
+#define	MCFA_DIC_PDIR1_EBU1	0x00000007	/* PDIR1 EBU1 data */
+#define	MCFA_DIC_PDIR1_EBU2	0x00001000	/* PDIR1 EBU2 data */
+
+/*
+ *	Audio glob register bit flags.
+ */
+#define	MCFA_GB_PDIR3_AUTOSYNC	0x00001000	/* PDIR3 auto sync mode */
+#define	MCFA_GB_EBU1_AUTOSYNC	0x00000400	/* EBU1 TX auto sync mode */
+#define	MCFA_GB_IIS2_AUTOSYNC	0x00000200	/* IIS2 auto sync mode */
+#define	MCFA_GB_IIS1_AUTOSYNC	0x00000100	/* IIS1 auto sync mode */
+#define	MCFA_GB_PDIR2_AUTOSYNC	0x00000080	/* PDIR2 auto sync mode */
+#define	MCFA_GB_PDIR1_AUTOSYNC	0x00000040	/* PDIR1 auto sync mode */
+#define	MCFA_GB_1TICK		0x00000000	/* Interrupt on 1 tick */
+#define	MCFA_GB_2TICK		0x00000008	/* Interrupt on 2 ticks */
+#define	MCFA_GB_3TICK		0x00000010	/* Interrupt on 3 ticks */
+#define	MCFA_GB_4TICK		0x00000018	/* Interrupt on 4 ticks */
+#define	MCFA_GB_5TICK		0x00000020	/* Interrupt on 5 ticks */
+#define	MCFA_GB_TICK_OFF	0x00000000	/* Tick disable */
+#define	MCFA_GB_TICK_IIS1TX	0x00000001	/* Tick on IIS1 TX */
+#define	MCFA_GB_TICK_IIS2TX	0x00000002	/* Tick on IIS2 TX */
+#define	MCFA_GB_TICK_EBUTX	0x00000003	/* Tick on EBU TX */
+#define	MCFA_GB_TICK_IIS1RX	0x00000004	/* Tick on IIS1 RX */
+#define	MCFA_GB_TICK_IIS3RX	0x00000005	/* Tick on IIS3 RX */
+#define	MCFA_GB_TICK_IIS4RX	0x00000006	/* Tick on IIS4 RX */
+#define	MCFA_GB_TICK_EBU1RX	0x00000007	/* Tick on EBU1 RX */
+#define	MCFA_GB_TICK_EBU2RX	0x00001000	/* Tick on EBU2 RX */
+
+/*
+ *	Flags for the DMA configuration register.
+ */
+#define	MCFA_DMA_0REQ		0x01		/* PDOR3 DMA on chan 0 */
+#define	MCFA_DMA_1REQ		0x02		/* PDOR3 DMA on chan 1 */
+
+/****************************************************************************/
+#endif	/* m5249audio_h */
diff -urN linux-2.4.29/include/asm-m68knommu/m5249sim.h linux-2.4.29-uc1/include/asm-m68knommu/m5249sim.h
--- linux-2.4.29/include/asm-m68knommu/m5249sim.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/m5249sim.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,119 @@
+/****************************************************************************/
+
+/*
+ *	m5249sim.h -- ColdFire 5249 System Integration Module support.
+ *
+ *	(C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/****************************************************************************/
+#ifndef	m5249sim_h
+#define	m5249sim_h
+/****************************************************************************/
+
+/*
+ *	Define the 5249 SIM register set addresses.
+ */
+#define	MCFSIM_RSR		0x00		/* Reset Status reg (r/w) */
+#define	MCFSIM_SYPCR		0x01		/* System Protection reg (r/w)*/
+#define	MCFSIM_SWIVR		0x02		/* SW Watchdog intr reg (r/w) */
+#define	MCFSIM_SWSR		0x03		/* SW Watchdog service (r/w) */
+#define	MCFSIM_PAR		0x04		/* Pin Assignment reg (r/w) */
+#define	MCFSIM_IRQPAR		0x06		/* Interrupt Assignment reg (r/w) */
+#define	MCFSIM_MPARK		0x0C		/* BUS Master Control Reg*/
+#define	MCFSIM_IPR		0x40		/* Interrupt Pend reg (r/w) */
+#define	MCFSIM_IMR		0x44		/* Interrupt Mask reg (r/w) */
+#define	MCFSIM_AVR		0x4b		/* Autovector Ctrl reg (r/w) */
+#define	MCFSIM_ICR0		0x4c		/* Intr Ctrl reg 0 (r/w) */
+#define	MCFSIM_ICR1		0x4d		/* Intr Ctrl reg 1 (r/w) */
+#define	MCFSIM_ICR2		0x4e		/* Intr Ctrl reg 2 (r/w) */
+#define	MCFSIM_ICR3		0x4f		/* Intr Ctrl reg 3 (r/w) */
+#define	MCFSIM_ICR4		0x50		/* Intr Ctrl reg 4 (r/w) */
+#define	MCFSIM_ICR5		0x51		/* Intr Ctrl reg 5 (r/w) */
+#define	MCFSIM_ICR6		0x52		/* Intr Ctrl reg 6 (r/w) */
+#define	MCFSIM_ICR7		0x53		/* Intr Ctrl reg 7 (r/w) */
+#define	MCFSIM_ICR8		0x54		/* Intr Ctrl reg 8 (r/w) */
+#define	MCFSIM_ICR9		0x55		/* Intr Ctrl reg 9 (r/w) */
+#define	MCFSIM_ICR10		0x56		/* Intr Ctrl reg 10 (r/w) */
+#define	MCFSIM_ICR11		0x57		/* Intr Ctrl reg 11 (r/w) */
+
+#define MCFSIM_CSAR0		0x80		/* CS 0 Address 0 reg (r/w) */
+#define MCFSIM_CSMR0		0x84		/* CS 0 Mask 0 reg (r/w) */
+#define MCFSIM_CSCR0		0x8a		/* CS 0 Control reg (r/w) */
+#define MCFSIM_CSAR1		0x8c		/* CS 1 Address reg (r/w) */
+#define MCFSIM_CSMR1		0x90		/* CS 1 Mask reg (r/w) */
+#define MCFSIM_CSCR1		0x96		/* CS 1 Control reg (r/w) */
+#define MCFSIM_CSAR2		0x98		/* CS 2 Adress reg (r/w) */
+#define MCFSIM_CSMR2		0x9c		/* CS 2 Mask reg (r/w) */
+#define MCFSIM_CSCR2		0xa2		/* CS 2 Control reg (r/w) */
+#define MCFSIM_CSAR3		0xa4		/* CS 3 Adress reg (r/w) */
+#define MCFSIM_CSMR3		0xa8		/* CS 3 Mask reg (r/w) */
+#define MCFSIM_CSCR3		0xae		/* CS 3 Control reg (r/w) */
+
+#define MCFSIM_DCR		0x100		/* DRAM Control reg (r/w) */
+#define MCFSIM_DACR0		0x108		/* DRAM 0 Addr and Ctrl (r/w) */
+#define MCFSIM_DMR0		0x10c		/* DRAM 0 Mask reg (r/w) */
+#define MCFSIM_DACR1		0x110		/* DRAM 1 Addr and Ctrl (r/w) */
+#define MCFSIM_DMR1		0x114		/* DRAM 1 Mask reg (r/w) */
+
+
+/*
+ *	Some symbol defines for the above...
+ */
+#define	MCFSIM_SWDICR		MCFSIM_ICR0	/* Watchdog timer ICR */
+#define	MCFSIM_TIMER1ICR	MCFSIM_ICR1	/* Timer 1 ICR */
+#define	MCFSIM_TIMER2ICR	MCFSIM_ICR2	/* Timer 2 ICR */
+#define	MCFSIM_UART1ICR		MCFSIM_ICR4	/* UART 1 ICR */
+#define	MCFSIM_UART2ICR		MCFSIM_ICR5	/* UART 2 ICR */
+#define	MCFSIM_DMA0ICR		MCFSIM_ICR6	/* DMA 0 ICR */
+#define	MCFSIM_DMA1ICR		MCFSIM_ICR7	/* DMA 1 ICR */
+#define	MCFSIM_DMA2ICR		MCFSIM_ICR8	/* DMA 2 ICR */
+#define	MCFSIM_DMA3ICR		MCFSIM_ICR9	/* DMA 3 ICR */
+
+/*
+ *	General purpose IO registers (in MBAR2).
+ */
+#define	MCFSIM2_GPIOREAD	0x0		/* GPIO read values */
+#define	MCFSIM2_GPIOWRITE	0x4		/* GPIO write values */
+#define	MCFSIM2_GPIOENABLE	0x8		/* GPIO enabled */
+#define	MCFSIM2_GPIOFUNC	0xc		/* GPIO function */
+#define	MCFSIM2_GPIO1READ	0xb0		/* GPIO1 read values */
+#define	MCFSIM2_GPIO1WRITE	0xb4		/* GPIO1 write values */
+#define	MCFSIM2_GPIO1ENABLE	0xb8		/* GPIO1 enabled */
+#define	MCFSIM2_GPIO1FUNC	0xbc		/* GPIO1 function */
+
+#define	MCFSIM2_GPIOINTSTAT	0xc0		/* GPIO interrupt status */
+#define	MCFSIM2_GPIOINTCLEAR	0xc0		/* GPIO interrupt clear */
+#define	MCFSIM2_GPIOINTENABLE	0xc4		/* GPIO interrupt enable */
+
+#define	MCFSIM2_INTLEVEL1	0x140		/* Interrupt level reg 1 */
+#define	MCFSIM2_INTLEVEL2	0x144		/* Interrupt level reg 2 */
+#define	MCFSIM2_INTLEVEL3	0x148		/* Interrupt level reg 3 */
+#define	MCFSIM2_INTLEVEL4	0x14c		/* Interrupt level reg 4 */
+#define	MCFSIM2_INTLEVEL5	0x150		/* Interrupt level reg 5 */
+#define	MCFSIM2_INTLEVEL6	0x154		/* Interrupt level reg 6 */
+#define	MCFSIM2_INTLEVEL7	0x158		/* Interrupt level reg 7 */
+#define	MCFSIM2_INTLEVEL8	0x15c		/* Interrupt level reg 8 */
+
+#define	MCFSIM2_DMAROUTE	0x188		/* DMA routing */
+
+#define	MCFSIM2_IDECONFIG1	0x18c		/* IDEconfig1 */
+#define	MCFSIM2_IDECONFIG2	0x190		/* IDEconfig2 */
+
+
+/*
+ *	Macro to set IMR register. It is 32 bits on the 5249.
+ */
+#define	MCFSIM_IMR_MASKALL	0x7fffe		/* All SIM intr sources */
+
+#define	mcf_getimr()		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
+
+#define	mcf_setimr(imr)		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
+
+#define	mcf_getipr()		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
+
+/****************************************************************************/
+#endif	/* m5249sim_h */
diff -urN linux-2.4.29/include/asm-m68knommu/m5272sim.h linux-2.4.29-uc1/include/asm-m68knommu/m5272sim.h
--- linux-2.4.29/include/asm-m68knommu/m5272sim.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/m5272sim.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,142 @@
+/****************************************************************************/
+
+/*
+ *	m5272sim.h -- ColdFire 5272 System Integration Module support.
+ *
+ *	(C) Copyright 1999, Greg Ungerer (gerg@snapgear.com)
+ * 	(C) Copyright 2000, Lineo Inc. (www.lineo.com) 
+ *      (c) copyright 2003, Arcturus Networks Inc.
+ *                          by Michael Leslie <mleslie@ArcturusNetworks.com>
+ */
+
+/****************************************************************************/
+#ifndef	m5272sim_h
+#define	m5272sim_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Define the 5272 SIM register set addresses.
+ */
+#define	MCFSIM_SCR		0x04		/* SIM Config reg (r/w) */
+#define	MCFSIM_SPR		0x06		/* System Protection reg (r/w)*/
+#define	MCFSIM_PMR		0x08		/* Power Management reg (r/w) */
+#define	MCFSIM_APMR		0x0e		/* Active Low Power reg (r/w) */
+#define	MCFSIM_DIR		0x10		/* Device Identity reg (r/w) */
+
+#define	MCFSIM_ICR1		0x20		/* Intr Ctrl reg 1 (r/w) */
+#define	MCFSIM_ICR2		0x24		/* Intr Ctrl reg 2 (r/w) */
+#define	MCFSIM_ICR3		0x28		/* Intr Ctrl reg 3 (r/w) */
+#define	MCFSIM_ICR4		0x2c		/* Intr Ctrl reg 4 (r/w) */
+
+#define MCFSIM_ISR		0x30		/* Interrupt Source reg (r/w) */
+#define MCFSIM_PITR		0x34		/* Interrupt Transition (r/w) */
+#define	MCFSIM_PIWR		0x38		/* Interrupt Wakeup reg (r/w) */
+#define	MCFSIM_PIVR		0x3f		/* Interrupt Vector reg (r/w( */
+
+#define	MCFSIM_WRRR		0x280		/* Watchdog reference (r/w) */
+#define	MCFSIM_WIRR		0x284		/* Watchdog interrupt (r/w) */
+#define	MCFSIM_WCR		0x288		/* Watchdog counter (r/w) */
+#define	MCFSIM_WER		0x28c		/* Watchdog event (r/w) */
+
+#define	MCFSIM_CSBR0		0x40		/* CS0 Base Address (r/w) */
+#define	MCFSIM_CSOR0		0x44		/* CS0 Option (r/w) */
+#define	MCFSIM_CSBR1		0x48		/* CS1 Base Address (r/w) */
+#define	MCFSIM_CSOR1		0x4c		/* CS1 Option (r/w) */
+#define	MCFSIM_CSBR2		0x50		/* CS2 Base Address (r/w) */
+#define	MCFSIM_CSOR2		0x54		/* CS2 Option (r/w) */
+#define	MCFSIM_CSBR3		0x58		/* CS3 Base Address (r/w) */
+#define	MCFSIM_CSOR3		0x5c		/* CS3 Option (r/w) */
+#define	MCFSIM_CSBR4		0x60		/* CS4 Base Address (r/w) */
+#define	MCFSIM_CSOR4		0x64		/* CS4 Option (r/w) */
+#define	MCFSIM_CSBR5		0x68		/* CS5 Base Address (r/w) */
+#define	MCFSIM_CSOR5		0x6c		/* CS5 Option (r/w) */
+#define	MCFSIM_CSBR6		0x70		/* CS6 Base Address (r/w) */
+#define	MCFSIM_CSOR6		0x74		/* CS6 Option (r/w) */
+#define	MCFSIM_CSBR7		0x78		/* CS7 Base Address (r/w) */
+#define	MCFSIM_CSOR7		0x7c		/* CS7 Option (r/w) */
+
+#define	MCFSIM_SDCR		0x180		/* SDRAM Configuration (r/w) */
+#define	MCFSIM_SDTR		0x184		/* SDRAM Timing (r/w) */
+#define	MCFSIM_DCAR0		0x4c		/* DRAM 0 Address reg(r/w) */
+#define	MCFSIM_DCMR0		0x50		/* DRAM 0 Mask reg (r/w) */
+#define	MCFSIM_DCCR0		0x57		/* DRAM 0 Control reg (r/w) */
+#define	MCFSIM_DCAR1		0x58		/* DRAM 1 Address reg (r/w) */
+#define	MCFSIM_DCMR1		0x5c		/* DRAM 1 Mask reg (r/w) */
+#define	MCFSIM_DCCR1		0x63		/* DRAM 1 Control reg (r/w) */
+
+#define	MCFSIM_PACNT		0x80		/* Port A Control (r/w) */
+#define	MCFSIM_PADDR		0x84		/* Port A Direction (r/w) */
+#define	MCFSIM_PADAT		0x86		/* Port A Data (r/w) */
+#define	MCFSIM_PBCNT		0x88		/* Port B Control (r/w) */
+#define	MCFSIM_PBDDR		0x8c		/* Port B Direction (r/w) */
+#define	MCFSIM_PBDAT		0x8e		/* Port B Data (r/w) */
+#define	MCFSIM_PCDDR		0x94		/* Port C Direction (r/w) */
+#define	MCFSIM_PCDAT		0x96		/* Port C Data (r/w) */
+#define	MCFSIM_PDCNT		0x98		/* Port D Control (r/w) */
+
+
+/*
+ *	Bit definitions for 5272 ICRs
+ */
+
+/* Hereunder, PI = interrupt enable, IPL = int priority level */
+/* IPL may only be written at the same time as PI is enabled */
+#define MCFSIM_INT1PI           0x80000000
+#define MCFSIM_INT1IPL(x)       ((x & 0x7) << 28)
+#define MCFSIM_INT2PI           0x08000000
+#define MCFSIM_INT2IPL(x)       ((x & 0x7) << 24)
+#define MCFSIM_INT3PI           0x00800000
+#define MCFSIM_INT3IPL(x)       ((x & 0x7) << 20)
+#define MCFSIM_INT4PI           0x00080000
+#define MCFSIM_INT4IPL(x)       ((x & 0x7) << 16)
+
+#define MCFSIM_TMR0PI           0x00008000
+#define MCFSIM_TMR0IPL(x)       ((x & 0x7) << 12)
+#define MCFSIM_TMR1PI           0x00000800
+#define MCFSIM_TMR1IPL(x)       ((x & 0x7) << 8)
+#define MCFSIM_TMR2PI           0x00000080
+#define MCFSIM_TMR2IPL(x)       ((x & 0x7) << 4)
+#define MCFSIM_TMR3PI           0x00000008
+#define MCFSIM_TMR3IPL(x)       ((x & 0x7) << 0)
+
+
+/* Interrupt vectors for 5272: */
+
+#define MCF_INT_SUPRIOUS 64 /* User Spurious Interrupt */
+#define MCF_INT_INT1     65 /* External Interrupt Input 1 */
+#define MCF_INT_INT2     66 /* External Interrupt Input 2 */
+#define MCF_INT_INT3     67 /* External Interrupt Input 3 */
+#define MCF_INT_INT4     68 /* External Interrupt Input 4 */
+#define MCF_INT_TMR0     69 /* Timer 0 */
+#define MCF_INT_TMR1     70 /* Timer 1 */
+#define MCF_INT_TMR2     71 /* Timer 2 */
+#define MCF_INT_TMR3     72 /* Timer 3 */
+#define MCF_INT_UART1    73 /* UART 1 */
+#define MCF_INT_UART2    74 /* UART 2 */
+#define MCF_INT_PLIP     75 /* PLIC 2KHz Periodic */
+#define MCF_INT_PLIA     76 /* PLIC Asynchronous */
+#define MCF_INT_USB0     77 /* USB Endpoint 0 */
+#define MCF_INT_USB1     78 /* USB Endpoint 1 */
+#define MCF_INT_USB2     79 /* USB Endpoint 2 */
+#define MCF_INT_USB3     80 /* USB Endpoint 3 */
+#define MCF_INT_USB4     81 /* USB Endpoint 4 */
+#define MCF_INT_USB5     82 /* USB Endpoint 5 */
+#define MCF_INT_USB6     83 /* USB Endpoint 6 */
+#define MCF_INT_USB7     84 /* USB Endpoint 7 */
+#define MCF_INT_DMA      85 /* DMA Controller */
+#define MCF_INT_ERx      86 /* Ethernet Receiver */
+#define MCF_INT_ETx      87 /* Ethernet Transmitter */
+#define MCF_INT_ENTC     88 /* Ethernet Module Non-time-critical */
+#define MCF_INT_QSPI     89 /* Queued Serial Peripheral Interface */
+#define MCF_INT_INT5     90 /* External Interrupt Input 5 */
+#define MCF_INT_INT6     91 /* External Interrupt Input 6 */
+#define MCF_INT_SWTO     92 /* Software Watchdog Timer Timeout */
+#define MCF_INT_93       93 /* Reserved */
+#define MCF_INT_94       94 /* Reserved */
+#define MCF_INT_95       95 /* Reserved */
+
+
+/****************************************************************************/
+#endif	/* m5272sim_h */
diff -urN linux-2.4.29/include/asm-m68knommu/m527xsim.h linux-2.4.29-uc1/include/asm-m68knommu/m527xsim.h
--- linux-2.4.29/include/asm-m68knommu/m527xsim.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/m527xsim.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,52 @@
+/****************************************************************************/
+
+/*
+ *	m527xsim.h -- ColdFire 527x System Integration Module support.
+ *
+ *	(C) Copyright 2003-2004, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/****************************************************************************/
+#ifndef	m527xsim_h
+#define	m527xsim_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Define the 527x SIM register set addresses. These are similar,
+ *	but not quite identical to the 5282 registers and offsets.
+ */
+#define	MCFICM_INTC0		0x0c00		/* Base for Interrupt Ctrl 0 */
+#define	MCFICM_INTC1		0x0d00		/* Base for Interrupt Ctrl 1 */
+#define	MCFINTC_IPRH		0x00		/* Interrupt pending 32-63 */
+#define	MCFINTC_IPRL		0x04		/* Interrupt pending 1-31 */
+#define	MCFINTC_IMRH		0x08		/* Interrupt mask 32-63 */
+#define	MCFINTC_IMRL		0x0c		/* Interrupt mask 1-31 */
+#define	MCFINTC_INTFRCH		0x10		/* Interrupt force 32-63 */
+#define	MCFINTC_INTFRCL		0x14		/* Interrupt force 1-31 */
+#define	MCFINTC_IRLR		0x18		/* */
+#define	MCFINTC_IACKL		0x19		/* */
+#define	MCFINTC_ICR0		0x40		/* Base ICR register */
+
+#define	MCFINT_UART0		13		/* Interrupt number for UART0 */
+#define	MCFINT_UART1		14		/* Interrupt number for UART1 */
+#define	MCFINT_UART2		15		/* Interrupt number for UART2 */
+#define	MCFINT_QSPI		18		/* Interrupt number for QSPI */
+#define	MCFINT_PIT1		36		/* Interrupt number for PIT1 */
+
+#if defined(CONFIG_M5271)
+#define MCF_GPIO_PAR_UART	0x100048	/* Enable/Disable Uart on External Pin */
+#define UART0_ENABLE_MASK	0x000f
+#define UART1_ENABLE_MASK	0x0ff0
+#define UART2_ENABLE_MASK	0x3000
+#endif
+#if defined(CONFIG_M5275)
+#define MCF_GPIO_PAR_UART	0x10007c	/* Enable/Disable Uart on External Pin */
+#define UART0_ENABLE_MASK	0x000f
+#define UART1_ENABLE_MASK	0x00f0
+#define UART2_ENABLE_MASK	0x3f00 
+#endif
+
+/****************************************************************************/
+#endif	/* m527xsim_h */
diff -urN linux-2.4.29/include/asm-m68knommu/m5282sim.h linux-2.4.29-uc1/include/asm-m68knommu/m5282sim.h
--- linux-2.4.29/include/asm-m68knommu/m5282sim.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/m5282sim.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,290 @@
+/****************************************************************************/
+
+/*
+ *	m5282sim.h -- ColdFire 5282 System Integration Module support.
+ *
+ *	(C) Copyright 2003, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/****************************************************************************/
+#ifndef	m5282sim_h
+#define	m5282sim_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Define the 5282 SIM register set addresses.
+ */
+#define	MCFICM_INTC0		0x0c00		/* Base for Interrupt Ctrl 0 */
+#define	MCFICM_INTC1		0x0d00		/* Base for Interrupt Ctrl 1 */
+#define	MCFINTC_IPRH		0x00		/* Interrupt pending 32-63 */
+#define	MCFINTC_IPRL		0x04		/* Interrupt pending 1-31 */
+#define	MCFINTC_IMRH		0x08		/* Interrupt mask 32-63 */
+#define	MCFINTC_IMRL		0x0c		/* Interrupt mask 1-31 */
+#define	MCFINTC_INTFRCH		0x10		/* Interrupt force 32-63 */
+#define	MCFINTC_INTFRCL		0x14		/* Interrupt force 1-31 */
+#define	MCFINTC_IRLR		0x18		/* */
+#define	MCFINTC_IACKL		0x19		/* */
+#define	MCFINTC_ICR0		0x40		/* Base ICR register */
+
+#define	MCFINT_UART0		13		/* Interrupt number for UART0 */
+#define	MCFINT_UART1		14		/* Interrupt number for UART1 */
+#define	MCFINT_UART2		15		/* Interrupt number for UART2 */
+#define	MCFINT_QSPI		18		/* Interrupt number for QSPI */
+#define	MCFINT_PIT1		55		/* Interrupt number for PIT1 */
+
+#define MCFINT_CAN_BUF00	8		/* Interrupt for CAN Buffer*/
+#define MCFINT_CAN_BUF01	9		/* Interrupt for CAN Buffer*/
+#define	MCFINT_CAN_BUF02	10		/* CAN BUF 2  register  10 */
+#define	MCFINT_CAN_BUF03	11		/* CAN BUF 3  register  11 */
+#define	MCFINT_CAN_BUF04	12		/* CAN BUF 4  register  12 */
+#define	MCFINT_CAN_BUF05	13		/* CAN BUF 5  register  13 */
+#define	MCFINT_CAN_BUF06	14		/* CAN BUF 6  register  14 */
+#define	MCFINT_CAN_BUF07	15		/* CAN BUF 7  register  15 */
+#define	MCFINT_CAN_BUF08	16		/* CAN BUF 8  register  16 */
+#define	MCFINT_CAN_BUF09	17		/* CAN BUF 9  register  17 */
+#define	MCFINT_CAN_BUF10	18		/* CAN BUF 10 register  18 */
+#define	MCFINT_CAN_BUF11	19		/* CAN BUF 11 register  19 */
+#define	MCFINT_CAN_BUF12	20		/* CAN BUF 12 register  20 */
+#define	MCFINT_CAN_BUF13	21		/* CAN BUF 13 register  21 */
+#define	MCFINT_CAN_BUF14	22		/* CAN BUF 14 register  22 */
+#define	MCFINT_CAN_BUF15	23		/* CAN BUF 15 register  23 */
+#define	MCFINT_CAN_WARN	        24		/* CAN warn register    24 */
+#define	MCFINT_CAN_BUSOFF	25		/* CAN bus off register 25 */
+#define	MCFINT_CAN_WUP	        26		/* CAN wake up register 26 */
+
+/* QSPI Register */
+#define MCF5282_QSPI_QMR	0x340		/* QSPI Mode Register (16 Bit) */
+#define MCF5282_QSPI_QDLYR	0x344		/* QSPI Delay Register (16 Bit) */
+#define MCF5282_QSPI_QWR	0x348		/* QSPI Wrap Register (16 Bit) */
+#define MCF5282_QSPI_QIR	0x34C		/* QSPI Interrupt Register (16 Bit) */
+#define MCF5282_QSPI_QAR	0x350		/* QSPI Address Register (16 Bit) */
+#define MCF5282_QSPI_QDR	0x354		/* QSPI Data Register (16 Bit) */
+
+/* DMA Timer 0 Register */
+#define MCF5282_DTM_DTMR0	0x400		/* DMA Timer Mode Register 0 (16 Bit) */
+#define MCF5282_DTM_DTXMR0	0x402		/* DMA Timer Extended Mode Register 0 (8 Bit) */
+#define MCF5282_DTM_DTER0	0x403		/* DMA Timer Event Register 0 (8 Bit) */
+#define MCF5282_DTM_DTRR0	0x404		/* DMA Timer Reference Register 0 (32 Bit) */
+#define MCF5282_DTM_DTCR0	0x408		/* DMA Timer Capture Register 0 (32 Bit) */
+#define MCF5282_DTM_DTCN0	0x40C		/* DMA Timer Counter Register 0 (32 Bit) */
+/* DMA Timer 1 Register */
+#define MCF5282_DTM_DTMR1	0x440		/* DMA Timer Mode Register 1 (16 Bit) */
+#define MCF5282_DTM_DTXMR1	0x442		/* DMA Timer Extended Mode Register 1 (8 Bit) */
+#define MCF5282_DTM_DTER1	0x443		/* DMA Timer Event Register 1 (8 Bit) */
+#define MCF5282_DTM_DTRR1	0x444		/* DMA Timer Reference Register 1 (32 Bit) */
+#define MCF5282_DTM_DTCR1	0x448		/* DMA Timer Capture Register 1 (32 Bit) */
+#define MCF5282_DTM_DTCN1	0x44C		/* DMA Timer Counter Register 1 (32 Bit) */
+/* DMA Timer 2 Register */
+#define MCF5282_DTM_DTMR2	0x480		/* DMA Timer Mode Register 2 (16 Bit) */
+#define MCF5282_DTM_DTXMR2	0x482		/* DMA Timer Extended Mode Register 2 (8 Bit) */
+#define MCF5282_DTM_DTER2	0x483		/* DMA Timer Event Register 2 (8 Bit) */
+#define MCF5282_DTM_DTRR2	0x484		/* DMA Timer Reference Register 2 (32 Bit) */
+#define MCF5282_DTM_DTCR2	0x488		/* DMA Timer Capture Register 2 (32 Bit) */
+#define MCF5282_DTM_DTCN2	0x48C		/* DMA Timer Counter Register 2 (32 Bit) */
+/* DMA Timer 3 Register */
+#define MCF5282_DTM_DTMR3	0x4C0		/* DMA Timer Mode Register 3 (16 Bit) */
+#define MCF5282_DTM_DTXMR3	0x4C2		/* DMA Timer Extended Mode Register 3 (8 Bit) */
+#define MCF5282_DTM_DTER3	0x4C3		/* DMA Timer Event Register 3 (8 Bit) */
+#define MCF5282_DTM_DTRR3	0x4C4		/* DMA Timer Reference Register 3 (32 Bit) */
+#define MCF5282_DTM_DTCR3	0x4C8		/* DMA Timer Capture Register 3 (32 Bit) */
+#define MCF5282_DTM_DTCN3	0x4CC		/* DMA Timer Counter Register 3 (32 Bit) */
+
+/* GPIO Register */
+#define	MCF5282_GPIO_PORTA	0x100000	/* Port A Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTB	0x100001	/* Port B Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTC	0x100002	/* Port C Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTD	0x100003	/* Port D Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTE	0x100004	/* Port E Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTF	0x100005	/* Port F Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTG	0x100006	/* Port G Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTH	0x100007	/* Port H Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTJ	0x100008	/* Port J Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTDD	0x100009	/* Port DD Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTEH	0x10000A	/* Port EH Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTEL	0x10000B	/* Port EL Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTAS	0x10000C	/* Port AS Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTQS	0x10000D	/* Port QS Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTSD	0x10000E	/* Port SD Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTTC	0x10000F	/* Port TC Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTTD	0x100010	/* Port TD Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_PORTUA	0x100011	/* Port UA Output Data Register (8 Bit) */
+
+#define	MCF5282_GPIO_DDRA	0x100014	/* Port A Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDRB	0x100015	/* Port B Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDRC	0x100016	/* Port C Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDRD	0x100017	/* Port D Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDRE	0x100018	/* Port E Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDRF	0x100019	/* Port F Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDRG	0x10001A	/* Port G Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDRH	0x10001B	/* Port H Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDRJ	0x10001C	/* Port J Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDRDD	0x10001D	/* Port DD Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDREH	0x10001E	/* Port EH Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDREL	0x10001F	/* Port EL Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDRAS	0x100020	/* Port AS Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDRQS	0x100021	/* Port QS Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDRSD	0x100022	/* Port SD Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDRTC	0x100023	/* Port TC Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDRTD	0x100024	/* Port TD Data Direction Register (8 Bit) */
+#define	MCF5282_GPIO_DDRUA	0x100025	/* Port UA Data Direction Register (8 Bit) */
+
+#define	MCF5282_GPIO_SETA	0x100028	/* Port A Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETB	0x100029	/* Port B Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETC	0x10002A	/* Port C Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETD	0x10002B	/* Port D Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETE	0x10002C	/* Port E Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETF	0x10002D	/* Port F Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETG	0x10002E	/* Port G Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETH	0x10002F	/* Port H Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETJ	0x100030	/* Port J Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETDD	0x100031	/* Port DD Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETEH	0x100032	/* Port EH Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETEL	0x100033	/* Port EL Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETAS	0x100034	/* Port AS Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETQS	0x100035	/* Port QS Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETSD	0x100036	/* Port SD Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETTC	0x100037	/* Port TC Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETTD	0x100038	/* Port TD Pin Data/Set Data Register (8 Bit) */
+#define	MCF5282_GPIO_SETUA	0x100039	/* Port UA Pin Data/Set Data Register (8 Bit) */
+
+#define	MCF5282_GPIO_CLRA	0x10003C	/* Port A Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLRB	0x10003D	/* Port B Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLRC	0x10003E	/* Port C Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLRD	0x10003F	/* Port D Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLRE	0x100040	/* Port E Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLRF	0x100041	/* Port F Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLRG	0x100042	/* Port G Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLRH	0x100043	/* Port H Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLRJ	0x100044	/* Port J Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLRDD	0x100045	/* Port DD Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLREH	0x100046	/* Port EH Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLREL	0x100047	/* Port EL Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLRAS	0x100048	/* Port AS Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLRQS	0x100049	/* Port QS Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLRSD	0x10004A	/* Port SD Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLRTC	0x10004B	/* Port TC Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLRTD	0x10004C	/* Port TD Clear Output Data Register (8 Bit) */
+#define	MCF5282_GPIO_CLRUA	0x10004D	/* Port UA Clear Output Data Register (8 Bit) */
+
+#define	MCF5282_GPIO_PBCDPAR	0x100050	/* Port B, C, and D Pin Assignment Register (8 Bit) */
+#define	MCF5282_GPIO_PFPAR	0x100051	/* Port F Pin Assignment Register (8 Bit) */
+#define	MCF5282_GPIO_PEPAR	0x100052	/* Port E Pin Assignment Register (16 Bit) */
+#define	MCF5282_GPIO_PJPAR	0x100054	/* Port J Pin Assignment Register (8 Bit) */
+#define	MCF5282_GPIO_PSDPAR	0x100055	/* Port SD Pin Assignment Register (8 Bit) */
+#define	MCF5282_GPIO_PASPAR	0x100056	/* Port AS Pin Assignment Register (16 Bit) */
+#define	MCF5282_GPIO_PEHLPAR	0x100058	/* Port EH and EL Pin Assignment Register (8 Bit) */
+#define	MCF5282_GPIO_PQSPAR	0x100059	/* Port QS Pin Assignment Register (8 Bit) */
+#define	MCF5282_GPIO_PTCPAR	0x10005A	/* Port TC Pin Assignment Register (8 Bit) */
+#define	MCF5282_GPIO_PTDPAR	0x10005B	/* Port TD Pin Assignment Register (8 Bit) */
+#define	MCF5282_GPIO_PUAPAR	0x10005C	/* Port UA Pin Assignment Register (8 Bit) */
+
+/* EPORT Register */
+#define MCF5282_EPORT_EPPAR	0x130000	/* EPORT Pin Assignment Register (16 Bit) */
+#define MCF5282_EPORT_EPDDR	0x130002	/* EPORT Data Direction Register (8 Bit) */
+#define MCF5282_EPORT_EPIER	0x130003	/* EPORT Interrupt Enable Register (8 Bit) */
+#define MCF5282_EPORT_EPDR	0x130004	/* EPORT Data Register (8 Bit) */
+#define MCF5282_EPORT_EPPDR	0x130005	/* EPORT Pin Data Direction Register (8 Bit) */
+#define MCF5282_EPORT_EPFR	0x130006	/* EPORT Flag Register (8 Bit) */
+
+/* Watchdog Timer Module */
+#define MCFSIM_WCR		0x140000
+#define MCFSIM_WMR		0x140002
+#define MCFSIM_WCNTR		0x140004
+#define MCFSIM_WSR		0x140006
+
+/* Programmable Interrupt Timer (PIT) Module 0 */
+#define MCF5282_PIT_PCSR0	0x150000	/* PIT Control and Status Register 0 (16 Bit) */
+#define MCF5282_PIT_PMR0	0x150002	/* PIT Modulus Register 0 (16 Bit) */
+#define MCF5282_PIT_PCNTR0	0x150004	/* PIT Count Register 0 (16 Bit) */
+/* Programmable Interrupt Timer (PIT) Module 1 */
+#define MCF5282_PIT_PCSR1	0x160000	/* PIT Control and Status Register 1 (16 Bit) */
+#define MCF5282_PIT_PMR1	0x160002	/* PIT Modulus Register 1 (16 Bit) */
+#define MCF5282_PIT_PCNTR1	0x160004	/* PIT Count Register 1 (16 Bit) */
+/* Programmable Interrupt Timer (PIT) Module 2 */
+#define MCF5282_PIT_PCSR2	0x170000	/* PIT Control and Status Register 2 (16 Bit) */
+#define MCF5282_PIT_PMR2	0x170002	/* PIT Modulus Register 2 (16 Bit) */
+#define MCF5282_PIT_PCNTR2	0x170004	/* PIT Count Register 2 (16 Bit) */
+/* Programmable Interrupt Timer (PIT) Module 3 */
+#define MCF5282_PIT_PCSR3	0x180000	/* PIT Control and Status Register 3 (16 Bit) */
+#define MCF5282_PIT_PMR3	0x180002	/* PIT Modulus Register 3 (16 Bit) */
+#define MCF5282_PIT_PCNTR3	0x180004	/* PIT Count Register 3 (16 Bit) */
+
+/* QADC Register */
+#define MCF5282_QADC_QADCMCR	0x190000	/* QADC Module Configuartion Register (16 Bit) */
+#define MCF5282_QADC_PORTQA	0x190006	/* Port QA Data Register (8 Bit) */
+#define MCF5282_QADC_PORTQB	0x190007	/* Port QB Data Register (8 Bit) */
+#define MCF5282_QADC_DDRQA	0x190008	/* Port QA Data Direction Register (8 Bit) */
+#define MCF5282_QADC_DDRQB	0x190009	/* Port QB Data Direction Register (8 Bit) */
+#define MCF5282_QADC_QACR0	0x19000A	/* QADC Control Register 0 (16 Bit) */
+#define MCF5282_QADC_QACR1	0x19000C	/* QADC Control Register 1 (16 Bit) */
+#define MCF5282_QADC_QACR2	0x19000E	/* QADC Control Register 2 (16 Bit) */
+#define MCF5282_QADC_QASR0	0x190010	/* QADC Status Register 0 (16 Bit) */
+#define MCF5282_QADC_QASR1	0x190012	/* QADC Status Register 1 (16 Bit) */
+#define MCF5282_QADC_CCW	0x190200	/* Conversion Command Word Table (64x16 Bit) */
+#define MCF5282_QADC_RJURR	0x190280	/* Right Justified, Unsigned Result Register (64x16 Bit) */
+#define MCF5282_QADC_LJSRR	0x190300	/* Left Justified, Signed Result Register (64x16 Bit) */
+#define MCF5282_QADC_LJURR	0x190380	/* Left Justified, Unsigned Result Register (64x16 Bit) */
+
+/* DMA Register */
+#define MCF5282_DMA_DMAREQC	0x014		/* DMA Request Control Register (32 Bit) */
+
+#define MCF5282_DMA_SAR0	0x100		/* DMA Source Address Register 0 (32 Bit) */
+#define MCF5282_DMA_DAR0	0x104		/* DMA Destination Address Register 0 (32 Bit) */
+#define MCF5282_DMA_DCR0	0x108		/* DMA Control Register 0 (32 Bit) */
+#define MCF5282_DMA_BCR0	0x10C		/* DMA Byte Count Register 0 (32 Bit) */
+#define MCF5282_DMA_DSR0	0x110		/* DMA Status Register 0 (8 Bit) */
+#define MCF5282_DMA_SAR1	0x140		/* DMA Source Address Register 1 (32 Bit) */
+#define MCF5282_DMA_DAR1	0x144		/* DMA Destination Address Register 1 (32 Bit) */
+#define MCF5282_DMA_DCR1	0x148		/* DMA Control Register 1 (32 Bit) */
+#define MCF5282_DMA_BCR1	0x14C		/* DMA Byte Count Register 1 (32 Bit) */
+#define MCF5282_DMA_DSR1	0x150		/* DMA Status Register 1 (8 Bit) */
+#define MCF5282_DMA_SAR2	0x180		/* DMA Source Address Register 2 (32 Bit) */
+#define MCF5282_DMA_DAR2	0x184		/* DMA Destination Address Register 2 (32 Bit) */
+#define MCF5282_DMA_DCR2	0x188		/* DMA Control Register 2 (32 Bit) */
+#define MCF5282_DMA_BCR2	0x18C		/* DMA Byte Count Register 2 (32 Bit) */
+#define MCF5282_DMA_DSR2	0x190		/* DMA Status Register 2 (8 Bit) */
+#define MCF5282_DMA_SAR3	0x1C0		/* DMA Source Address Register 3 (32 Bit) */
+#define MCF5282_DMA_DAR3	0x1C4		/* DMA Destination Address Register 3 (32 Bit) */
+#define MCF5282_DMA_DCR3	0x1C8		/* DMA Control Register 3 (32 Bit) */
+#define MCF5282_DMA_BCR3	0x1CC		/* DMA Byte Count Register 3 (32 Bit) */
+#define MCF5282_DMA_DSR3	0x1D0		/* DMA Status Register 3 (8 Bit) */
+
+/* CFI Register */
+#define MCF5282_CFM_MCR		0x1D0000		/* CFM Configuration Register (16 Bit) */
+#define MCF5282_CFM_CLKD	0x1D0002		/* CFM Clock Divider Register (8 Bit) */
+#define MCF5282_CFM_SEC		0x1D0008		/* CFM Security Register (32 Bit) */
+#define MCF5282_CFM_PROT	0x1D0010		/* CFM Protection Register (32 Bit) */
+#define MCF5282_CFM_SACC	0x1D0014		/* CFM Supervisor Access Register (32 Bit) */
+#define MCF5282_CFM_DACC	0x1D0018		/* CFM Data Access Register (32 Bit) */
+#define MCF5282_CFM_USTAT	0x1D0020		/* CFM User Status Register (8 Bit) */
+#define MCF5282_CFM_CMD		0x1D0024		/* CFM Command Register (8 Bit) */
+
+/* Interrupt vectors INTC0 */
+#define MCF5282_INT_EPORT1	(64+1)
+#define MCF5282_INT_EPORT2	(64+2)
+#define MCF5282_INT_EPORT3	(64+3)
+#define MCF5282_INT_EPORT4	(64+4)
+#define MCF5282_INT_EPORT5	(64+5)
+#define MCF5282_INT_EPORT6	(64+6)
+#define MCF5282_INT_EPORT7	(64+7)
+#define MCF5282_INT_SWT1	(64+8)
+#define MCF5282_INT_DMA0	(64+9)
+#define MCF5282_INT_DMA1	(64+10)
+#define MCF5282_INT_DMA2	(64+11)
+#define MCF5282_INT_DMA3	(64+12)
+
+#define MCF5282_INT_QSPI	(64+18)
+#define MCF5282_INT_DTIM0	(64+19)
+#define MCF5282_INT_DTIM1	(64+20)
+#define MCF5282_INT_DTIM2	(64+21)
+#define MCF5282_INT_DTIM3	(64+22)
+
+#define MCF5282_INT_PIT0	(64+55)
+#define MCF5282_INT_PIT1	(64+56)
+#define MCF5282_INT_PIT2	(64+57)
+#define MCF5282_INT_PIT3	(64+58)
+
+/****************************************************************************/
+#endif	/* m5282sim_h */
diff -urN linux-2.4.29/include/asm-m68knommu/m5307dma.h linux-2.4.29-uc1/include/asm-m68knommu/m5307dma.h
--- linux-2.4.29/include/asm-m68knommu/m5307dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/m5307dma.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,152 @@
+#ifndef _M5307_DMA_H
+#define _M5307_DMA_H 1
+
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/irq.h>
+
+
+#define MAX_DMA_CHANNELS 4
+
+/* 
+*DMA Address Definitions
+*/
+
+
+#define MCF5307_DMA_SAR 	(MCF_MBAR+0x300)  /*Source Address Register Channel */
+#define MCF5307_DMA_DAR 	(MCF_MBAR+0x304)  /*Destination Address Register Channel*/
+#define MCF5307_DMA_DCR 	(MCF_MBAR+0x308)  /*DMA Controll Register Channel*/
+#define MCF5307_DMA_BCR 	(MCF_MBAR+0x30C)  /*Byte Count Register Channel*/
+#define MCF5307_DMA_SR 		(MCF_MBAR+0x310)  /*Status Register Channel*/
+#define MCF5307_DMA_IVR 	(MCF_MBAR+0x314)  /*InterruptVectorRegister Channel*/
+
+/*
+*DMA Controll Register Definition
+*/
+
+
+#define MCF5307_DMA_DCR_INT             (0x8000) /* Interrupt on Completion     */
+#define MCF5307_DMA_DCR_EEXT            (0x4000) /* Enable External Request     */
+#define MCF5307_DMA_DCR_CS              (0x2000) /* Cycle Steal                 */
+#define MCF5307_DMA_DCR_AA              (0x1000) /* Auto Align                  */
+#define MCF5307_DMA_DCR_BWC_DMA         (0x0000) /* Bandwidth: DMA Priority     */
+#define MCF5307_DMA_DCR_BWC_512         (0x0200) /* Bandwidth:   512 Bytes      */
+#define MCF5307_DMA_DCR_BWC_1024        (0x0400) /* Bandwidth:  1024 Bytes      */
+#define MCF5307_DMA_DCR_BWC_2048        (0x0600) /* Bandwidth:  2048 Bytes      */
+#define MCF5307_DMA_DCR_BWC_4096        (0x0800) /* Bandwidth:  4096 Bytes      */
+#define MCF5307_DMA_DCR_BWC_8192        (0x0a00) /* Bandwidth:  8192 Bytes      */
+#define MCF5307_DMA_DCR_BWC_16384       (0x0c00) /* Bandwidth: 16384 Bytes      */
+#define MCF5307_DMA_DCR_BWC_32768       (0x0e00) /* Bandwidth: 32768 Bytes      */
+#define MCF5307_DMA_DCR_SAA             (0x0100) /* Single Address Access       */
+#define MCF5307_DMA_DCR_SRW             (0x0080) /* Forces MRW Signal High      */
+#define MCF5307_DMA_DCR_SINC            (0x0040) /* Source Increment            */
+#define MCF5307_DMA_DCR_SSIZE_LONG      (0x0000) /* Source Size:  Longword      */
+#define MCF5307_DMA_DCR_SSIZE_BYTE      (0x0010) /* Source Size:  Byte          */
+#define MCF5307_DMA_DCR_SSIZE_WORD      (0x0020) /* Source Size:  Word          */
+#define MCF5307_DMA_DCR_SSIZE_LINE      (0x0030) /* Source Size:  Line          */
+#define MCF5307_DMA_DCR_DINC            (0x0008) /* Destination Increment       */
+#define MCF5307_DMA_DCR_DSIZE_LONG      (0x0000) /* Destination Size:  Longword */
+#define MCF5307_DMA_DCR_DSIZE_BYTE      (0x0002) /* Destination Size:  Byte     */
+#define MCF5307_DMA_DCR_DSIZE_WORD      (0x0004) /* Destination Size:  Word     */
+#define MCF5307_DMA_DCR_DSIZE_LINE      (0x0006) /* Destination Size:  Line          */
+#define MCF5307_DMA_DCR_START           (0x0001) /* Start Transfer                      */
+
+/*
+*DMA Status Register Definitions
+*/
+
+
+#define MCF5307_DMA_DSR_CE              (0x40)  /* Configuration Error          */
+#define MCF5307_DMA_DSR_BES             (0x20)  /* Bus Error on Source          */
+#define MCF5307_DMA_DSR_BED             (0x10)  /* Bus Error on Destination     */
+#define MCF5307_DMA_DSR_REQ             (0x04)  /* Request                                      */
+#define MCF5307_DMA_DSR_BSY             (0x02)  /* Busy                                         */
+#define MCF5307_DMA_DSR_DONE            (0x01)  /* Transaction Done                     */          
+
+
+#define DMA_STATE_BUSY			1
+#define DMA_STATE_IDLE			0
+#define DMA_STATE_CONFIGURATION_ERROR	-1
+#define DMA_STATE_SOURCE_ERROR		-2
+#define DMA_STATE_DESTINATION_ERROR	-3
+
+struct dma_mcf
+{
+	const char *devname;
+	unsigned char* source;
+	unsigned char* dest;
+	unsigned short count;
+	unsigned short creg;  /*16 bit controllregister use the defines above*/
+	void (*handler) (int, void *, struct pt_regs *);
+	unsigned int irq_vector;
+	unsigned int irq_level;
+	unsigned long irq_flags;
+};
+
+static __inline__ int dma_init(int channel)
+{
+	int err;
+	if ((err = request_dma(channel, 0)) != 0) return err;
+	
+	*(unsigned char*) (MCF_MBAR + MCFSIM_MPARK) |= 0x80; /* DMA BUS
+	MASTER with highest priority*/
+	return err;
+}
+
+
+
+static __inline__ void dma_set(int channel, struct dma_mcf dma)
+{
+		
+	
+	*(unsigned int*) (MCF5307_DMA_SAR + (0x40 * channel)) = dma.source;
+        *(unsigned int*) (MCF5307_DMA_DAR + (0x40 * channel)) = dma.dest;
+	*(unsigned short*) (MCF5307_DMA_BCR + (0x40 * channel)) = dma.count;
+	if ((dma.creg & MCF5307_DMA_DCR_INT) !=0)		/* DMA generates a Interrupt on complrtion*/
+		{					/* Now configure the Interrupt handler*/
+		*(unsigned short*) (MCF5307_DMA_IVR + (0x40 * channel)) = dma.irq_vector;
+		if (request_irq(dma.irq_vector,dma.handler,dma.irq_flags,
+		dma.devname, 0) !=0)
+				printk("request irq fail\n");
+		
+		*(volatile unsigned char*)(MCF_MBAR + 0x52 + channel) = dma.irq_level | MCFSIM_ICR_AUTOVEC;    /* set MBUS IRQ-Level and autovector */
+	        mcf_setimr(mcf_getimr() & ~(0x4000 << channel));
+		printk("maskreg%X\n",mcf_getimr());
+		}
+	*(unsigned short*) (MCF5307_DMA_DCR + (0x40 * channel)) = dma.creg;
+}
+
+
+static __inline__ unsigned char dma_busy(unsigned char channel)
+{
+	if ((*(unsigned char*) (MCF5307_DMA_SR + (0x40 * channel)) & MCF5307_DMA_DSR_BSY)!=0) return(0x1);
+	
+	return 0;
+}
+
+static __inline__ void dma_done(unsigned char channel)
+{
+
+
+	*(unsigned char*) (MCF5307_DMA_SR + (0x40 * channel)) = MCF5307_DMA_DSR_DONE;
+}
+
+
+static __inline__ void dma_clear(unsigned char channel)
+{				
+	*(unsigned short*) (MCF5307_DMA_DCR + (0x40 * channel)) = 0x0000;
+}
+
+
+static __inline__ unsigned char dma_get_status(unsigned char dsr)
+{
+	if ((dsr & MCF5307_DMA_DSR_CE) != 0) return(DMA_STATE_CONFIGURATION_ERROR);
+	if ((dsr & MCF5307_DMA_DSR_BES) !=0) return(DMA_STATE_SOURCE_ERROR);
+	if ((dsr & MCF5307_DMA_DSR_BED) !=0) return(DMA_STATE_DESTINATION_ERROR);
+	return 0;
+}
+
+extern int request_dma(unsigned int dmanr, const char * device_id);	/* reserve a DMA channel */
+extern void free_dma(unsigned int dmanr);	/* release it again */
+#endif /* _M5307_DMA_H */
diff -urN linux-2.4.29/include/asm-m68knommu/m5307sim.h linux-2.4.29-uc1/include/asm-m68knommu/m5307sim.h
--- linux-2.4.29/include/asm-m68knommu/m5307sim.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/m5307sim.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,183 @@
+/****************************************************************************/
+
+/*
+ *	m5307sim.h -- ColdFire 5307 System Integration Module support.
+ *
+ *	(C) Copyright 1999,  Moreton Bay Ventures Pty Ltd.
+ *	(C) Copyright 1999,  Lineo (www.lineo.com)
+ *
+ *      Modified by David W. Miller for the MCF5307 Eval Board.
+ */
+
+/****************************************************************************/
+#ifndef	m5307sim_h
+#define	m5307sim_h
+/****************************************************************************/
+
+/*
+ *	Define the 5307 SIM register set addresses.
+ */
+#define	MCFSIM_RSR		0x00		/* Reset Status reg (r/w) */
+#define MCFSIM_RSR_HRST		0x80		/* Reset was due to hard reset */
+#define MCFSIM_RSR_SWTR		0x20		/* Reset was due to software reset */
+#define	MCFSIM_SYPCR		0x01		/* System Protection reg (r/w)*/
+#define	MCFSIM_SWIVR		0x02		/* SW Watchdog intr reg (r/w) */
+#define	MCFSIM_SWSR		0x03		/* SW Watchdog service (r/w) */
+#define	MCFSIM_PAR		0x04		/* Pin Assignment reg (r/w) */
+#define	MCFSIM_IRQPAR		0x06		/* Interrupt Assignment reg (r/w) */
+#define	MCFSIM_PLLCR		0x08		/* PLL Controll Reg*/
+#define	MCFSIM_MPARK		0x0C		/* BUS Master Control Reg*/
+#define	MCFSIM_IPR		0x40		/* Interrupt Pend reg (r/w) */
+#define	MCFSIM_IMR		0x44		/* Interrupt Mask reg (r/w) */
+#define	MCFSIM_AVR		0x4b		/* Autovector Ctrl reg (r/w) */
+#define	MCFSIM_ICR0		0x4c		/* Intr Ctrl reg 0 (r/w) */
+#define	MCFSIM_ICR1		0x4d		/* Intr Ctrl reg 1 (r/w) */
+#define	MCFSIM_ICR2		0x4e		/* Intr Ctrl reg 2 (r/w) */
+#define	MCFSIM_ICR3		0x4f		/* Intr Ctrl reg 3 (r/w) */
+#define	MCFSIM_ICR4		0x50		/* Intr Ctrl reg 4 (r/w) */
+#define	MCFSIM_ICR5		0x51		/* Intr Ctrl reg 5 (r/w) */
+#define	MCFSIM_ICR6		0x52		/* Intr Ctrl reg 6 (r/w) */
+#define	MCFSIM_ICR7		0x53		/* Intr Ctrl reg 7 (r/w) */
+#define	MCFSIM_ICR8		0x54		/* Intr Ctrl reg 8 (r/w) */
+#define	MCFSIM_ICR9		0x55		/* Intr Ctrl reg 9 (r/w) */
+#define	MCFSIM_ICR10		0x56		/* Intr Ctrl reg 10 (r/w) */
+#define	MCFSIM_ICR11		0x57		/* Intr Ctrl reg 11 (r/w) */
+
+#define MCFSIM_CSAR0		0x80		/* CS 0 Address 0 reg (r/w) */
+#define MCFSIM_CSMR0		0x84		/* CS 0 Mask 0 reg (r/w) */
+#define MCFSIM_CSCR0		0x8a		/* CS 0 Control reg (r/w) */
+#define MCFSIM_CSAR1		0x8c		/* CS 1 Address reg (r/w) */
+#define MCFSIM_CSMR1		0x90		/* CS 1 Mask reg (r/w) */
+#define MCFSIM_CSCR1		0x96		/* CS 1 Control reg (r/w) */
+
+#ifdef CONFIG_OLDMASK
+#define MCFSIM_CSBAR		0x98		/* CS Base Address reg (r/w) */
+#define MCFSIM_CSBAMR		0x9c		/* CS Base Mask reg (r/w) */
+#define MCFSIM_CSMR2		0x9e		/* CS 2 Mask reg (r/w) */
+#define MCFSIM_CSCR2		0xa2		/* CS 2 Control reg (r/w) */
+#define MCFSIM_CSMR3		0xaa		/* CS 3 Mask reg (r/w) */
+#define MCFSIM_CSCR3		0xae		/* CS 3 Control reg (r/w) */
+#define MCFSIM_CSMR4		0xb6		/* CS 4 Mask reg (r/w) */
+#define MCFSIM_CSCR4		0xba		/* CS 4 Control reg (r/w) */
+#define MCFSIM_CSMR5		0xc2		/* CS 5 Mask reg (r/w) */
+#define MCFSIM_CSCR5		0xc6		/* CS 5 Control reg (r/w) */
+#define MCFSIM_CSMR6		0xce		/* CS 6 Mask reg (r/w) */
+#define MCFSIM_CSCR6		0xd2		/* CS 6 Control reg (r/w) */
+#define MCFSIM_CSMR7		0xda		/* CS 7 Mask reg (r/w) */
+#define MCFSIM_CSCR7		0xde		/* CS 7 Control reg (r/w) */
+#else
+#define MCFSIM_CSAR2		0x98		/* CS 2 Adress reg (r/w) */
+#define MCFSIM_CSMR2		0x9c		/* CS 2 Mask reg (r/w) */
+#define MCFSIM_CSCR2		0xa2		/* CS 2 Control reg (r/w) */
+#define MCFSIM_CSAR3		0xa4		/* CS 3 Adress reg (r/w) */
+#define MCFSIM_CSMR3		0xa8		/* CS 3 Mask reg (r/w) */
+#define MCFSIM_CSCR3		0xae		/* CS 3 Control reg (r/w) */
+#define MCFSIM_CSAR4		0xb0		/* CS 4 Adress reg (r/w) */
+#define MCFSIM_CSMR4		0xb4		/* CS 4 Mask reg (r/w) */
+#define MCFSIM_CSCR4		0xba		/* CS 4 Control reg (r/w) */
+#define MCFSIM_CSAR5		0xbc		/* CS 5 Adress reg (r/w) */
+#define MCFSIM_CSMR5		0xc0		/* CS 5 Mask reg (r/w) */
+#define MCFSIM_CSCR5		0xc6		/* CS 5 Control reg (r/w) */
+#define MCFSIM_CSAR6		0xc8		/* CS 6 Adress reg (r/w) */
+#define MCFSIM_CSMR6		0xcc		/* CS 6 Mask reg (r/w) */
+#define MCFSIM_CSCR6		0xd2		/* CS 6 Control reg (r/w) */
+#define MCFSIM_CSAR7		0xd4		/* CS 7 Adress reg (r/w) */
+#define MCFSIM_CSMR7		0xd8		/* CS 7 Mask reg (r/w) */
+#define MCFSIM_CSCR7		0xde		/* CS 7 Control reg (r/w) */
+#endif /* CONFIG_OLDMASK */
+
+#define MCFSIM_DCR		0x100		/* DRAM Control reg (r/w) */
+#define MCFSIM_DACR0		0x108		/* DRAM 0 Addr and Ctrl (r/w) */
+#define MCFSIM_DMR0		0x10c		/* DRAM 0 Mask reg (r/w) */
+#define MCFSIM_DACR1		0x110		/* DRAM 1 Addr and Ctrl (r/w) */
+#define MCFSIM_DMR1		0x114		/* DRAM 1 Mask reg (r/w) */
+
+#define	MCFSIM_PADDR		0x244		/* Parallel Direction (r/w) */
+#define	MCFSIM_PADAT		0x248		/* Parallel Data (r/w) */
+
+
+/* Definition offset address for CS2-7  -- old mask 5307 */
+
+#define	MCF5307_CS2		(0x400000)
+#define	MCF5307_CS3		(0x600000)
+#define	MCF5307_CS4		(0x800000)
+#define	MCF5307_CS5		(0xA00000)
+#define	MCF5307_CS6		(0xC00000)
+#define	MCF5307_CS7		(0xE00000)
+
+
+/*
+ *	Some symbol defines for the above...
+ */
+#define	MCFSIM_SWDICR		MCFSIM_ICR0	/* Watchdog timer ICR */
+#define	MCFSIM_TIMER1ICR	MCFSIM_ICR1	/* Timer 1 ICR */
+#define	MCFSIM_TIMER2ICR	MCFSIM_ICR2	/* Timer 2 ICR */
+#define	MCFSIM_UART1ICR		MCFSIM_ICR4	/* UART 1 ICR */
+#define	MCFSIM_UART2ICR		MCFSIM_ICR5	/* UART 2 ICR */
+#define	MCFSIM_DMA0ICR		MCFSIM_ICR6	/* DMA 0 ICR */
+#define	MCFSIM_DMA1ICR		MCFSIM_ICR7	/* DMA 1 ICR */
+#define	MCFSIM_DMA2ICR		MCFSIM_ICR8	/* DMA 2 ICR */
+#define	MCFSIM_DMA3ICR		MCFSIM_ICR9	/* DMA 3 ICR */
+
+#if defined(CONFIG_M5307)
+#define	MCFSIM_IMR_MASKALL	0x3fffe		/* All SIM intr sources */
+#endif
+
+/*
+ *	Macro to set IMR register. It is 32 bits on the 5307.
+ */
+#define	mcf_getimr()		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
+
+#define	mcf_setimr(imr)		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
+
+#define	mcf_getipr()		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
+
+
+/*
+ *	Some symbol defines for the Parallel Port Pin Assignment Register
+ */
+#define MCFSIM_PAR_DREQ0        0x40            /* Set to select DREQ0 input */
+                                                /* Clear to select par I/O */
+#define MCFSIM_PAR_DREQ1        0x20            /* Select DREQ1 input */
+                                                /* Clear to select par I/O */
+
+/*
+ *       Defines for the IRQPAR Register
+ */
+#define IRQ5_LEVEL4	0x80
+#define IRQ3_LEVEL6	0x40
+#define IRQ1_LEVEL2	0x20
+
+
+/*
+ *	Define the Cache register flags.
+ */
+#define	CACR_EC			(1<<31)
+#define	CACR_ESB		(1<<29)
+#define	CACR_DPI		(1<<28)
+#define	CACR_HLCK		(1<<27)
+#define	CACR_CINVA		(1<<24)
+#define	CACR_DNFB		(1<<10)
+#define	CACR_DCM_WTHRU		(0<<8)
+#define	CACR_DCM_WBACK		(1<<8)
+#define	CACR_DCM_OFF_PRE	(2<<8)
+#define	CACR_DCM_OFF_IMP	(3<<8)
+#define	CACR_DW			(1<<5)
+
+#define	ACR_BASE_POS		24
+#define	ACR_MASK_POS		16
+#define	ACR_ENABLE		(1<<15)
+#define	ACR_USER		(0<<13)
+#define	ACR_SUPER		(1<<13)
+#define	ACR_ANY			(2<<13)
+#define	ACR_CM_WTHRU		(0<<5)
+#define	ACR_CM_WBACK		(1<<5)
+#define	ACR_CM_OFF_PRE		(2<<5)
+#define	ACR_CM_OFF_IMP		(3<<5)
+#define	ACR_WPROTECT		(1<<2)
+
+/****************************************************************************/
+#endif	/* m5307sim_h */
diff -urN linux-2.4.29/include/asm-m68knommu/m5407sim.h linux-2.4.29-uc1/include/asm-m68knommu/m5407sim.h
--- linux-2.4.29/include/asm-m68knommu/m5407sim.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/m5407sim.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,159 @@
+/****************************************************************************/
+
+/*
+ *	m5407sim.h -- ColdFire 5407 System Integration Module support.
+ *
+ *	(C) Copyright 2000,  Lineo (www.lineo.com)
+ *	(C) Copyright 1999,  Moreton Bay Ventures Pty Ltd.
+ *
+ *      Modified by David W. Miller for the MCF5307 Eval Board.
+ */
+
+/****************************************************************************/
+#ifndef	m5407sim_h
+#define	m5407sim_h
+/****************************************************************************/
+
+/*
+ *	Define the 5407 SIM register set addresses.
+ */
+#define	MCFSIM_RSR		0x00		/* Reset Status reg (r/w) */
+#define MCFSIM_RSR_HRST     0x80    /* Reset was due to hard reset */
+#define MCFSIM_RSR_SWTR     0x20    /* Reset was due to software reset */
+#define	MCFSIM_SYPCR		0x01		/* System Protection reg (r/w)*/
+#define	MCFSIM_SWIVR		0x02		/* SW Watchdog intr reg (r/w) */
+#define	MCFSIM_SWSR		0x03		/* SW Watchdog service (r/w) */
+#define	MCFSIM_PAR		0x04		/* Pin Assignment reg (r/w) */
+#define	MCFSIM_IRQPAR		0x06		/* Interrupt Assignment reg (r/w) */
+#define	MCFSIM_PLLCR		0x08		/* PLL Controll Reg*/
+#define	MCFSIM_MPARK		0x0C		/* BUS Master Control Reg*/
+#define	MCFSIM_IPR		0x40		/* Interrupt Pend reg (r/w) */
+#define	MCFSIM_IMR		0x44		/* Interrupt Mask reg (r/w) */
+#define	MCFSIM_AVR		0x4b		/* Autovector Ctrl reg (r/w) */
+#define	MCFSIM_ICR0		0x4c		/* Intr Ctrl reg 0 (r/w) */
+#define	MCFSIM_ICR1		0x4d		/* Intr Ctrl reg 1 (r/w) */
+#define	MCFSIM_ICR2		0x4e		/* Intr Ctrl reg 2 (r/w) */
+#define	MCFSIM_ICR3		0x4f		/* Intr Ctrl reg 3 (r/w) */
+#define	MCFSIM_ICR4		0x50		/* Intr Ctrl reg 4 (r/w) */
+#define	MCFSIM_ICR5		0x51		/* Intr Ctrl reg 5 (r/w) */
+#define	MCFSIM_ICR6		0x52		/* Intr Ctrl reg 6 (r/w) */
+#define	MCFSIM_ICR7		0x53		/* Intr Ctrl reg 7 (r/w) */
+#define	MCFSIM_ICR8		0x54		/* Intr Ctrl reg 8 (r/w) */
+#define	MCFSIM_ICR9		0x55		/* Intr Ctrl reg 9 (r/w) */
+#define	MCFSIM_ICR10		0x56		/* Intr Ctrl reg 10 (r/w) */
+#define	MCFSIM_ICR11		0x57		/* Intr Ctrl reg 11 (r/w) */
+
+#define MCFSIM_CSAR0		0x80		/* CS 0 Address 0 reg (r/w) */
+#define MCFSIM_CSMR0		0x84		/* CS 0 Mask 0 reg (r/w) */
+#define MCFSIM_CSCR0		0x8a		/* CS 0 Control reg (r/w) */
+#define MCFSIM_CSAR1		0x8c		/* CS 1 Address reg (r/w) */
+#define MCFSIM_CSMR1		0x90		/* CS 1 Mask reg (r/w) */
+#define MCFSIM_CSCR1		0x96		/* CS 1 Control reg (r/w) */
+
+#define MCFSIM_CSAR2		0x98		/* CS 2 Adress reg (r/w) */
+#define MCFSIM_CSMR2		0x9c		/* CS 2 Mask reg (r/w) */
+#define MCFSIM_CSCR2		0xa2		/* CS 2 Control reg (r/w) */
+#define MCFSIM_CSAR3		0xa4		/* CS 3 Adress reg (r/w) */
+#define MCFSIM_CSMR3		0xa8		/* CS 3 Mask reg (r/w) */
+#define MCFSIM_CSCR3		0xae		/* CS 3 Control reg (r/w) */
+#define MCFSIM_CSAR4		0xb0		/* CS 4 Adress reg (r/w) */
+#define MCFSIM_CSMR4		0xb4		/* CS 4 Mask reg (r/w) */
+#define MCFSIM_CSCR4		0xba		/* CS 4 Control reg (r/w) */
+#define MCFSIM_CSAR5		0xbc		/* CS 5 Adress reg (r/w) */
+#define MCFSIM_CSMR5		0xc0		/* CS 5 Mask reg (r/w) */
+#define MCFSIM_CSCR5		0xc6		/* CS 5 Control reg (r/w) */
+#define MCFSIM_CSAR6		0xc8		/* CS 6 Adress reg (r/w) */
+#define MCFSIM_CSMR6		0xcc		/* CS 6 Mask reg (r/w) */
+#define MCFSIM_CSCR6		0xd2		/* CS 6 Control reg (r/w) */
+#define MCFSIM_CSAR7		0xd4		/* CS 7 Adress reg (r/w) */
+#define MCFSIM_CSMR7		0xd8		/* CS 7 Mask reg (r/w) */
+#define MCFSIM_CSCR7		0xde		/* CS 7 Control reg (r/w) */
+
+#define MCFSIM_DCR		0x100		/* DRAM Control reg (r/w) */
+#define MCFSIM_DACR0		0x108		/* DRAM 0 Addr and Ctrl (r/w) */
+#define MCFSIM_DMR0		0x10c		/* DRAM 0 Mask reg (r/w) */
+#define MCFSIM_DACR1		0x110		/* DRAM 1 Addr and Ctrl (r/w) */
+#define MCFSIM_DMR1		0x114		/* DRAM 1 Mask reg (r/w) */
+
+#define	MCFSIM_PADDR		0x244		/* Parallel Direction (r/w) */
+#define	MCFSIM_PADAT		0x248		/* Parallel Data (r/w) */
+
+
+/*
+ *	Some symbol defines for the above...
+ */
+#define	MCFSIM_SWDICR		MCFSIM_ICR0	/* Watchdog timer ICR */
+#define	MCFSIM_TIMER1ICR	MCFSIM_ICR1	/* Timer 1 ICR */
+#define	MCFSIM_TIMER2ICR	MCFSIM_ICR2	/* Timer 2 ICR */
+#define	MCFSIM_UART1ICR		MCFSIM_ICR4	/* UART 1 ICR */
+#define	MCFSIM_UART2ICR		MCFSIM_ICR5	/* UART 2 ICR */
+#define	MCFSIM_DMA0ICR		MCFSIM_ICR6	/* DMA 0 ICR */
+#define	MCFSIM_DMA1ICR		MCFSIM_ICR7	/* DMA 1 ICR */
+#define	MCFSIM_DMA2ICR		MCFSIM_ICR8	/* DMA 2 ICR */
+#define	MCFSIM_DMA3ICR		MCFSIM_ICR9	/* DMA 3 ICR */
+
+/*
+ *	Macro to set IMR register. It is 32 bits on the 5407.
+ */
+#define	mcf_getimr()		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
+
+#define	mcf_setimr(imr)		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
+
+#define	mcf_getipr()		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
+
+
+/*
+ *	Some symbol defines for the Parallel Port Pin Assignment Register
+ */
+#define MCFSIM_PAR_DREQ0        0x40            /* Set to select DREQ0 input */
+                                                /* Clear to select par I/O */
+#define MCFSIM_PAR_DREQ1        0x20            /* Select DREQ1 input */
+                                                /* Clear to select par I/O */
+
+/*
+ *       Defines for the IRQPAR Register
+ */
+#define IRQ5_LEVEL4	0x80
+#define IRQ3_LEVEL6	0x40
+#define IRQ1_LEVEL2	0x20
+
+
+/*
+ *	Define the Cache register flags.
+ */
+#define	CACR_DEC		0x80000000	/* Enable data cache */
+#define	CACR_DWP		0x40000000	/* Data write protection */
+#define	CACR_DESB		0x20000000	/* Enable data store buffer */
+#define	CACR_DDPI		0x10000000	/* Disable CPUSHL */
+#define	CACR_DHCLK		0x08000000	/* Half data cache lock mode */
+#define	CACR_DDCM_WT		0x00000000	/* Write through cache*/
+#define	CACR_DDCM_CP		0x02000000	/* Copyback cache */
+#define	CACR_DDCM_P		0x04000000	/* No cache, precise */
+#define	CACR_DDCM_IMP		0x06000000	/* No cache, imprecise */
+#define	CACR_DCINVA		0x01000000	/* Invalidate data cache */
+#define	CACR_BEC		0x00080000	/* Enable branch cache */
+#define	CACR_BCINVA		0x00040000	/* Invalidate branch cache */
+#define	CACR_IEC		0x00008000	/* Enable instruction cache */
+#define	CACR_DNFB		0x00002000	/* Inhibited fill buffer */
+#define	CACR_IDPI		0x00001000	/* Disable CPUSHL */
+#define	CACR_IHLCK		0x00000800	/* Intruction cache half lock */
+#define	CACR_IDCM		0x00000400	/* Intruction cache inhibit */
+#define	CACR_ICINVA		0x00000100	/* Invalidate instr cache */
+
+#define	ACR_BASE_POS		24		/* Address Base */
+#define	ACR_MASK_POS		16		/* Address Mask */
+#define	ACR_ENABLE		0x00008000	/* Enable address */
+#define	ACR_USER		0x00000000	/* User mode access only */
+#define	ACR_SUPER		0x00002000	/* Supervisor mode only */
+#define	ACR_ANY			0x00004000	/* Match any access mode */
+#define	ACR_CM_WT		0x00000000	/* Write through mode */
+#define	ACR_CM_CP		0x00000020	/* Copyback mode */
+#define	ACR_CM_OFF_PRE		0x00000040	/* No cache, precise */
+#define	ACR_CM_OFF_IMP		0x00000060	/* No cache, imprecise */
+#define	ACR_WPROTECT		0x00000004	/* Write protect */
+
+/****************************************************************************/
+#endif	/* m5407sim_h */
diff -urN linux-2.4.29/include/asm-m68knommu/m547xsim.h linux-2.4.29-uc1/include/asm-m68knommu/m547xsim.h
--- linux-2.4.29/include/asm-m68knommu/m547xsim.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/m547xsim.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,29 @@
+/****************************************************************************/
+
+/*
+ *	m547xsim.h -- ColdFire 547x System Integration Module support.
+ *
+ *	(C) Copyright 2004, Greg Ungerer <gerg@snapgear.com>
+ */
+
+/****************************************************************************/
+#ifndef	m547xsim_h
+#define	m547xsim_h
+/****************************************************************************/
+
+/*
+ *	Define the 547x SIM register set addresses.
+ */
+#define	MCFSIM_IPRH		0x700		/* Interrupt pending 32-63 */
+#define	MCFSIM_IPRL		0x704		/* Interrupt pending 1-31 */
+#define	MCFSIM_IMRH		0x708		/* Interrupt mask 32-63 */
+#define	MCFSIM_IMRL		0x70c		/* Interrupt mask 1-31 */
+#define	MCFSIM_INTFRCH		0x710		/* Interrupt force 32-63 */
+#define	MCFSIM_INTFRCL		0x714		/* Interrupt force 1-31 */
+#define	MCFSIM_IRLR		0x718		/* */
+#define	MCFSIM_IACKL		0x719		/* */
+
+#define	MCFSIM_ICR0		0x740		/* Base ICR register */
+
+/****************************************************************************/
+#endif	/* m547xsim_h */
diff -urN linux-2.4.29/include/asm-m68knommu/m68360_enet.h linux-2.4.29-uc1/include/asm-m68knommu/m68360_enet.h
--- linux-2.4.29/include/asm-m68knommu/m68360_enet.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/m68360_enet.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,177 @@
+/***********************************
+ * $Id: m68360_enet.h,v 1.1.1.1 2001/05/18 17:10:11 hamilton Exp $
+ ***********************************
+ *
+ ***************************************
+ * Definitions for the ETHERNET controllers
+ ***************************************
+ */
+
+#ifndef __ETHER_H
+#define __ETHER_H
+
+#include "quicc_simple.h"
+
+/*
+ * transmit BD's
+ */
+#define T_R     0x8000          /* ready bit */
+#define E_T_PAD 0x4000          /* short frame padding */
+#define T_W     0x2000          /* wrap bit */
+#define T_I     0x1000          /* interrupt on completion */
+#define T_L     0x0800          /* last in frame */
+#define T_TC    0x0400          /* transmit CRC (when last) */
+
+#define T_DEF   0x0200          /* defer indication */
+#define T_HB    0x0100          /* heartbeat */
+#define T_LC    0x0080          /* error: late collision */
+#define T_RL    0x0040          /* error: retransmission limit */
+#define T_RC    0x003c          /* retry count */
+#define T_UN    0x0002          /* error: underrun */
+#define T_CSL   0x0001          /* carier sense lost */
+#define T_ERROR (T_HB | T_LC | T_RL | T_UN | T_CSL)
+
+/*
+ * receive BD's
+ */
+#define R_E     0x8000          /* buffer empty */
+#define R_W     0x2000          /* wrap bit */
+#define R_I     0x1000          /* interrupt on reception */
+#define R_L     0x0800          /* last BD in frame */
+#define R_F     0x0400          /* first BD in frame */
+#define R_M     0x0100          /* received because of promisc. mode */
+
+#define R_LG    0x0020          /* frame too long */
+#define R_NO    0x0010          /* non-octet aligned */
+#define R_SH    0x0008          /* short frame */
+#define R_CR    0x0004          /* receive CRC error */
+#define R_OV    0x0002          /* receive overrun */
+#define R_CL    0x0001          /* collision */
+#define ETHER_R_ERROR (R_LG | R_NO | R_SH | R_CR | R_OV | R_CL)
+
+
+/*
+ * ethernet interrupts
+ */
+#define ETHERNET_GRA    0x0080  /* graceful stop complete */
+#define ETHERNET_TXE    0x0010  /* transmit error         */
+#define ETHERNET_RXF    0x0008  /* receive frame          */
+#define ETHERNET_BSY    0x0004  /* busy condition         */
+#define ETHERNET_TXB    0x0002  /* transmit buffer        */
+#define ETHERNET_RXB    0x0001  /* receive buffer         */
+
+/*
+ * ethernet protocol specific mode register (PSMR)
+ */
+#define ETHER_HBC       0x8000    /* heartbeat checking      */
+#define ETHER_FC        0x4000    /* force collision         */
+#define ETHER_RSH       0x2000    /* receive short frames    */
+#define ETHER_IAM       0x1000    /* individual address mode */
+#define ETHER_CRC_32    (0x2<<10) /* Enable CRC              */
+#define ETHER_PRO       0x0200    /* promiscuous             */
+#define ETHER_BRO       0x0100    /* broadcast address       */
+#define ETHER_SBT       0x0080    /* stop backoff timer      */
+#define ETHER_LPB       0x0040    /* Loop Back Mode          */
+#define ETHER_SIP       0x0020    /* sample input pins       */
+#define ETHER_LCW       0x0010    /* late collision window   */
+#define ETHER_NIB_13    (0x0<<1)  /* # of ignored bits 13    */
+#define ETHER_NIB_14    (0x1<<1)  /* # of ignored bits 14    */
+#define ETHER_NIB_15    (0x2<<1)  /* # of ignored bits 15    */
+#define ETHER_NIB_16    (0x3<<1)  /* # of ignored bits 16    */
+#define ETHER_NIB_21    (0x4<<1)  /* # of ignored bits 21    */
+#define ETHER_NIB_22    (0x5<<1)  /* # of ignored bits 22    */
+#define ETHER_NIB_23    (0x6<<1)  /* # of ignored bits 23    */
+#define ETHER_NIB_24    (0x7<<1)  /* # of ignored bits 24    */
+
+/*
+ * ethernet specific parameters
+ */
+#define CRC_WORD 4          /* Length in bytes of CRC */               
+#define C_PRES   0xffffffff /* preform 32 bit CRC */
+#define C_MASK   0xdebb20e3 /* comply with 32 bit CRC */       
+#define CRCEC    0x00000000
+#define ALEC     0x00000000
+#define DISFC    0x00000000
+#define PADS     0x00000000
+#define RET_LIM  0x000f     /* retry 15 times to send a frame before interupt */
+#define ETH_MFLR 0x05ee     /* 1518 max frame size */
+#define MINFLR   0x0040     /* Minimum frame size 64 */
+#define MAXD1    0x05ee     /* Max dma count 1518 */
+#define MAXD2    0x05ee
+#define GADDR1   0x00000000 /* Clear group address */  
+#define GADDR2   0x00000000
+#define GADDR3   0x00000000    
+#define GADDR4   0x00000000    
+#define P_PER    0x00000000 /*not used */              
+#define IADDR1   0x00000000 /* Individual hash table not used */       
+#define IADDR2   0x00000000
+#define IADDR3   0x00000000    
+#define IADDR4   0x00000000            
+#define TADDR_H  0x00000000 /* clear this regs */              
+#define TADDR_M  0x00000000            
+#define TADDR_L  0x00000000            
+
+/*       SCC Parameter Ram */
+#define RFCR    0x18 /* normal operation */
+#define TFCR    0x18 /* normal operation */
+#define E_MRBLR 1518 /* Max ethernet frame length */
+
+/*
+ * ethernet specific structure
+ */
+typedef union {
+        unsigned char b[6];
+        struct {
+            unsigned short high;
+            unsigned short middl;
+            unsigned short low;
+        } w;
+} ETHER_ADDR;
+
+typedef struct {
+    int        max_frame_length;
+    int        promisc_mode;
+    int        reject_broadcast;
+    ETHER_ADDR phys_adr;
+} ETHER_SPECIFIC;
+
+typedef struct {
+    ETHER_ADDR     dst_addr;
+    ETHER_ADDR     src_addr;
+    unsigned short type_or_len;
+    unsigned char  data[1];
+} ETHER_FRAME;
+
+#define MAX_DATALEN 1500
+typedef struct {
+    ETHER_ADDR     dst_addr;
+    ETHER_ADDR     src_addr;
+    unsigned short type_or_len;
+    unsigned char  data[MAX_DATALEN];
+    unsigned char  fcs[CRC_WORD];
+} ETHER_MAX_FRAME;
+
+
+/*
+ * Internal ethernet function prototypes
+ */
+void        ether_interrupt(int scc_num);
+/* mleslie: debug */
+/* static void ethernet_rx_internal(int scc_num); */
+/* static void ethernet_tx_internal(int scc_num); */
+
+/*
+ * User callable routines prototypes (ethernet specific)
+ */
+void ethernet_init(int                       scc_number,
+                   alloc_routine             *alloc_buffer,
+                   free_routine              *free_buffer,
+                   store_rx_buffer_routine   *store_rx_buffer,
+                   handle_tx_error_routine   *handle_tx_error,
+                   handle_rx_error_routine   *handle_rx_error,
+                   handle_lost_error_routine *handle_lost_error,
+                   ETHER_SPECIFIC            *ether_spec);
+int  ethernet_tx(int scc_number, void *buf, int length);
+
+#endif
+
diff -urN linux-2.4.29/include/asm-m68knommu/m68360.h linux-2.4.29-uc1/include/asm-m68knommu/m68360.h
--- linux-2.4.29/include/asm-m68knommu/m68360.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/m68360.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,5 @@
+#include "m68360_regs.h"
+#include "m68360_pram.h"
+#include "m68360_quicc.h"
+#include "m68360_enet.h"
+
diff -urN linux-2.4.29/include/asm-m68knommu/m68360_pram.h linux-2.4.29-uc1/include/asm-m68knommu/m68360_pram.h
--- linux-2.4.29/include/asm-m68knommu/m68360_pram.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/m68360_pram.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,431 @@
+/***********************************
+ * $Id: m68360_pram.h,v 1.1.1.1 2001/05/18 17:10:11 hamilton Exp $
+ ***********************************
+ *
+ ***************************************
+ * Definitions of the parameter area RAM.
+ * Note that different structures are overlaid
+ * at the same offsets for the different modes
+ * of operation.
+ ***************************************
+ */
+
+#ifndef __PRAM_H
+#define __PRAM_H
+
+/* Time slot assignment table */
+#define VALID_SLOT	0x8000
+#define WRAP_SLOT	0x4000
+
+/*****************************************************************
+        Global Multichannel parameter RAM
+*****************************************************************/
+struct global_multi_pram {
+    /*
+     * Global Multichannel parameter RAM
+     */
+    unsigned long   mcbase;		/* Multichannel Base pointer */
+    unsigned short  qmcstate;		/* Multichannel Controller state */
+    unsigned short  mrblr;		/* Maximum Receive Buffer Length */
+    unsigned short  tx_s_ptr;		/* TSTATx Pointer */
+    unsigned short  rxptr;		/* Current Time slot entry in TSATRx */
+    unsigned short  grfthr;		/* Global Receive frame threshold */
+    unsigned short  grfcnt;		/* Global Receive Frame Count */
+    unsigned long   intbase;		/* Multichannel Base address */
+    unsigned long   iintptr;		/* Pointer to interrupt queue */
+    unsigned short  rx_s_ptr;		/* TSTARx Pointer */
+
+    unsigned short  txptr;		/* Current Time slot entry in TSATTx */
+    unsigned long   c_mask32;		/* CRC Constant (debb20e3) */
+    unsigned short  tsatrx[32];		/* Time Slot Assignment Table Rx */
+    unsigned short  tsattx[32];		/* Time Slot Assignment Table Tx */
+    unsigned short  c_mask16;		/* CRC Constant (f0b8) */
+};
+
+/*****************************************************************
+        Quicc32 HDLC parameter RAM
+*****************************************************************/
+struct quicc32_pram {
+
+    unsigned short  tbase;		/* Tx Buffer Descriptors Base Address */
+    unsigned short  chamr;		/* Channel Mode Register */
+    unsigned long   tstate;		/* Tx Internal State */
+    unsigned long   txintr;		/* Tx Internal Data Pointer */
+    unsigned short  tbptr;		/* Tx Buffer Descriptor Pointer */
+    unsigned short  txcntr;		/* Tx Internal Byte Count */
+    unsigned long   tupack;		/* (Tx Temp) */
+    unsigned long   zistate;		/* Zero Insertion machine state */
+    unsigned long   tcrc;		/* Temp Transmit CRC */
+    unsigned short  intmask;		/* Channel's interrupt mask flags */
+    unsigned short  bdflags;		
+    unsigned short  rbase;		/* Rx Buffer Descriptors Base Address */
+    unsigned short  mflr;		/* Max Frame Length Register */
+    unsigned long   rstate;		/* Rx Internal State */
+    unsigned long   rxintr;		/* Rx Internal Data Pointer */
+    unsigned short  rbptr;		/* Rx Buffer Descriptor Pointer */
+    unsigned short  rxbyc;		/* Rx Internal Byte Count */
+    unsigned long   rpack;		/* (Rx Temp) */
+    unsigned long   zdstate;		/* Zero Deletion machine state */
+    unsigned long   rcrc;		/* Temp Transmit CRC */
+    unsigned short  maxc;		/* Max_length counter */
+    unsigned short  tmp_mb;		/* Temp */
+};
+
+
+/*****************************************************************
+        HDLC parameter RAM
+*****************************************************************/
+
+struct hdlc_pram {
+    /*
+     * SCC parameter RAM
+     */
+    unsigned short  rbase;          /* RX BD base address */
+    unsigned short  tbase;          /* TX BD base address */
+    unsigned char   rfcr;           /* Rx function code */
+    unsigned char   tfcr;           /* Tx function code */
+    unsigned short  mrblr;          /* Rx buffer length */
+    unsigned long   rstate;         /* Rx internal state */
+    unsigned long   rptr;           /* Rx internal data pointer */
+    unsigned short  rbptr;          /* rb BD Pointer */
+    unsigned short  rcount;         /* Rx internal byte count */
+    unsigned long   rtemp;          /* Rx temp */
+    unsigned long   tstate;         /* Tx internal state */
+    unsigned long   tptr;           /* Tx internal data pointer */
+    unsigned short  tbptr;          /* Tx BD pointer */
+    unsigned short  tcount;         /* Tx byte count */
+    unsigned long   ttemp;          /* Tx temp */
+    unsigned long   rcrc;           /* temp receive CRC */
+    unsigned long   tcrc;           /* temp transmit CRC */
+   
+    /*
+     * HDLC specific parameter RAM
+     */
+    unsigned char   RESERVED1[4];   /* Reserved area */
+    unsigned long   c_mask;         /* CRC constant */
+    unsigned long   c_pres;         /* CRC preset */
+    unsigned short  disfc;          /* discarded frame counter */
+    unsigned short  crcec;          /* CRC error counter */
+    unsigned short  abtsc;          /* abort sequence counter */
+    unsigned short  nmarc;          /* nonmatching address rx cnt */
+    unsigned short  retrc;          /* frame retransmission cnt */
+    unsigned short  mflr;           /* maximum frame length reg */
+    unsigned short  max_cnt;        /* maximum length counter */
+    unsigned short  rfthr;          /* received frames threshold */
+    unsigned short  rfcnt;          /* received frames count */
+    unsigned short  hmask;          /* user defined frm addr mask */
+    unsigned short  haddr1;         /* user defined frm address 1 */
+    unsigned short  haddr2;         /* user defined frm address 2 */
+    unsigned short  haddr3;         /* user defined frm address 3 */
+    unsigned short  haddr4;         /* user defined frm address 4 */
+    unsigned short  tmp;            /* temp */
+    unsigned short  tmp_mb;         /* temp */
+};
+
+
+
+/*****************************************************************
+        UART parameter RAM
+*****************************************************************/
+
+/*
+ * bits in uart control characters table
+ */
+#define CC_INVALID  0x8000          /* control character is valid */
+#define CC_REJ      0x4000          /* don't store char in buffer */
+#define CC_CHAR     0x00ff          /* control character */
+
+/* UART */
+struct uart_pram {
+    /*
+     * SCC parameter RAM
+     */
+    unsigned short  rbase;          /* RX BD base address */
+    unsigned short  tbase;          /* TX BD base address */
+    unsigned char   rfcr;           /* Rx function code */
+    unsigned char   tfcr;           /* Tx function code */
+    unsigned short  mrblr;          /* Rx buffer length */
+    unsigned long   rstate;         /* Rx internal state */
+    unsigned long   rptr;           /* Rx internal data pointer */
+    unsigned short  rbptr;          /* rb BD Pointer */
+    unsigned short  rcount;         /* Rx internal byte count */
+    unsigned long   rx_temp;        /* Rx temp */
+    unsigned long   tstate;         /* Tx internal state */
+    unsigned long   tptr;           /* Tx internal data pointer */
+    unsigned short  tbptr;          /* Tx BD pointer */
+    unsigned short  tcount;         /* Tx byte count */
+    unsigned long   ttemp;          /* Tx temp */
+    unsigned long   rcrc;           /* temp receive CRC */
+    unsigned long   tcrc;           /* temp transmit CRC */
+   
+    /*
+     * UART specific parameter RAM
+     */
+    unsigned char   RESERVED1[8];   /* Reserved area */
+    unsigned short  max_idl;        /* maximum idle characters */
+    unsigned short  idlc;           /* rx idle counter (internal) */
+    unsigned short  brkcr;          /* break count register */
+                   
+    unsigned short  parec;          /* Rx parity error counter */
+    unsigned short  frmer;          /* Rx framing error counter */
+    unsigned short  nosec;          /* Rx noise counter */
+    unsigned short  brkec;          /* Rx break character counter */
+    unsigned short  brkln;          /* Reaceive break length */
+                   
+    unsigned short  uaddr1;         /* address character 1 */
+    unsigned short  uaddr2;         /* address character 2 */
+    unsigned short  rtemp;          /* temp storage */
+    unsigned short  toseq;          /* Tx out of sequence char */
+    unsigned short  cc[8];          /* Rx control characters */
+    unsigned short  rccm;           /* Rx control char mask */
+    unsigned short  rccr;           /* Rx control char register */
+    unsigned short  rlbc;           /* Receive last break char */
+};
+
+
+
+/*****************************************************************
+        BISYNC parameter RAM
+*****************************************************************/
+
+struct bisync_pram {
+    /*
+     * SCC parameter RAM
+     */
+    unsigned short  rbase;          /* RX BD base address */
+    unsigned short  tbase;          /* TX BD base address */
+    unsigned char   rfcr;           /* Rx function code */
+    unsigned char   tfcr;           /* Tx function code */
+    unsigned short  mrblr;          /* Rx buffer length */
+    unsigned long   rstate;         /* Rx internal state */
+    unsigned long   rptr;           /* Rx internal data pointer */
+    unsigned short  rbptr;          /* rb BD Pointer */
+    unsigned short  rcount;         /* Rx internal byte count */
+    unsigned long   rtemp;          /* Rx temp */
+    unsigned long   tstate;         /* Tx internal state */
+    unsigned long   tptr;           /* Tx internal data pointer */
+    unsigned short  tbptr;          /* Tx BD pointer */
+    unsigned short  tcount;         /* Tx byte count */
+    unsigned long   ttemp;          /* Tx temp */
+    unsigned long   rcrc;           /* temp receive CRC */
+    unsigned long   tcrc;           /* temp transmit CRC */
+   
+    /*
+     * BISYNC specific parameter RAM
+     */
+    unsigned char   RESERVED1[4];   /* Reserved area */
+    unsigned long   crcc;           /* CRC Constant Temp Value */
+    unsigned short  prcrc;          /* Preset Receiver CRC-16/LRC */
+    unsigned short  ptcrc;          /* Preset Transmitter CRC-16/LRC */
+    unsigned short  parec;          /* Receive Parity Error Counter */
+    unsigned short  bsync;          /* BISYNC SYNC Character */
+    unsigned short  bdle;           /* BISYNC DLE Character */
+    unsigned short  cc[8];          /* Rx control characters */
+    unsigned short  rccm;           /* Receive Control Character Mask */
+};
+
+/*****************************************************************
+        IOM2 parameter RAM
+        (overlaid on tx bd[5] of SCC channel[2])
+*****************************************************************/
+struct iom2_pram {
+    unsigned short  ci_data;        /* ci data */
+    unsigned short  monitor_data;   /* monitor data */
+    unsigned short  tstate;         /* transmitter state */
+    unsigned short  rstate;         /* receiver state */
+};
+
+/*****************************************************************
+        SPI/SMC parameter RAM
+        (overlaid on tx bd[6,7] of SCC channel[2])
+*****************************************************************/
+
+#define SPI_R       0x8000          /* Ready bit in BD */
+
+struct spi_pram {
+    unsigned short  rbase;          /* Rx BD Base Address */
+    unsigned short  tbase;          /* Tx BD Base Address */
+    unsigned char   rfcr;           /* Rx function code */
+    unsigned char   tfcr;           /* Tx function code */
+    unsigned short  mrblr;          /* Rx buffer length */
+    unsigned long   rstate;         /* Rx internal state */
+    unsigned long   rptr;           /* Rx internal data pointer */
+    unsigned short  rbptr;          /* rb BD Pointer */
+    unsigned short  rcount;         /* Rx internal byte count */
+    unsigned long   rtemp;          /* Rx temp */
+    unsigned long   tstate;         /* Tx internal state */
+    unsigned long   tptr;           /* Tx internal data pointer */
+    unsigned short  tbptr;          /* Tx BD pointer */
+    unsigned short  tcount;         /* Tx byte count */
+    unsigned long   ttemp;          /* Tx temp */
+};
+
+struct smc_uart_pram {
+    unsigned short  rbase;          /* Rx BD Base Address */
+    unsigned short  tbase;          /* Tx BD Base Address */
+    unsigned char   rfcr;           /* Rx function code */
+    unsigned char   tfcr;           /* Tx function code */
+    unsigned short  mrblr;          /* Rx buffer length */
+    unsigned long   rstate;         /* Rx internal state */
+    unsigned long   rptr;           /* Rx internal data pointer */
+    unsigned short  rbptr;          /* rb BD Pointer */
+    unsigned short  rcount;         /* Rx internal byte count */
+    unsigned long   rtemp;          /* Rx temp */
+    unsigned long   tstate;         /* Tx internal state */
+    unsigned long   tptr;           /* Tx internal data pointer */
+    unsigned short  tbptr;          /* Tx BD pointer */
+    unsigned short  tcount;         /* Tx byte count */
+    unsigned long   ttemp;          /* Tx temp */
+    unsigned short  max_idl;        /* Maximum IDLE Characters */
+    unsigned short  idlc;           /* Temporary IDLE Counter */
+    unsigned short  brkln;          /* Last Rx Break Length */
+    unsigned short  brkec;          /* Rx Break Condition Counter */
+    unsigned short  brkcr;          /* Break Count Register (Tx) */
+    unsigned short  r_mask;         /* Temporary bit mask */
+};
+
+struct smc_trnsp_pram {
+    unsigned short  rbase;          /* rx BD Base Address */
+    unsigned short  tbase;          /* Tx BD Base Address */
+    unsigned char   rfcr;           /* Rx function code */
+    unsigned char   tfcr;           /* Tx function code */
+    unsigned short  mrblr;          /* Rx buffer length */
+    unsigned long   rstate;         /* Rx internal state */
+    unsigned long   rptr;           /* Rx internal data pointer */
+    unsigned short  rbptr;          /* rb BD Pointer */
+    unsigned short  rcount;         /* Rx internal byte count */
+    unsigned long   rtemp;          /* Rx temp */
+    unsigned long   tstate;         /* Tx internal state */
+    unsigned long   tptr;           /* Tx internal data pointer */
+    unsigned short  tbptr;          /* Tx BD pointer */
+    unsigned short  tcount;         /* Tx byte count */
+    unsigned long   ttemp;          /* Tx temp */
+    unsigned short  reserved[5];    /* Reserved */
+};
+
+struct idma_pram {
+    unsigned short  ibase;          /* IDMA BD Base Address */
+    unsigned short  ibptr;          /* IDMA buffer descriptor pointer */
+    unsigned long   istate;         /* IDMA internal state */
+    unsigned long   itemp;          /* IDMA temp */
+};
+
+struct ethernet_pram {
+    /*
+     * SCC parameter RAM
+     */
+    unsigned short  rbase;          /* RX BD base address */
+    unsigned short  tbase;          /* TX BD base address */
+    unsigned char   rfcr;           /* Rx function code */
+    unsigned char   tfcr;           /* Tx function code */
+    unsigned short  mrblr;          /* Rx buffer length */
+    unsigned long   rstate;         /* Rx internal state */
+    unsigned long   rptr;           /* Rx internal data pointer */
+    unsigned short  rbptr;          /* rb BD Pointer */
+    unsigned short  rcount;         /* Rx internal byte count */
+    unsigned long   rtemp;          /* Rx temp */
+    unsigned long   tstate;         /* Tx internal state */
+    unsigned long   tptr;           /* Tx internal data pointer */
+    unsigned short  tbptr;          /* Tx BD pointer */
+    unsigned short  tcount;         /* Tx byte count */
+    unsigned long   ttemp;          /* Tx temp */
+    unsigned long   rcrc;           /* temp receive CRC */
+    unsigned long   tcrc;           /* temp transmit CRC */
+   
+    /*
+     * ETHERNET specific parameter RAM
+     */
+    unsigned long   c_pres;         /* preset CRC */
+    unsigned long   c_mask;         /* constant mask for CRC */
+    unsigned long   crcec;          /* CRC error counter */
+    unsigned long   alec;           /* alighnment error counter */
+    unsigned long   disfc;          /* discard frame counter */
+    unsigned short  pads;           /* short frame PAD characters */
+    unsigned short  ret_lim;        /* retry limit threshold */
+    unsigned short  ret_cnt;        /* retry limit counter */
+    unsigned short  mflr;           /* maximum frame length reg */
+    unsigned short  minflr;         /* minimum frame length reg */
+    unsigned short  maxd1;          /* maximum DMA1 length reg */
+    unsigned short  maxd2;          /* maximum DMA2 length reg */
+    unsigned short  maxd;           /* rx max DMA */
+    unsigned short  dma_cnt;        /* rx dma counter */
+    unsigned short  max_b;          /* max bd byte count */
+    unsigned short  gaddr1;         /* group address filter 1 */
+    unsigned short  gaddr2;         /* group address filter 2 */
+    unsigned short  gaddr3;         /* group address filter 3 */
+    unsigned short  gaddr4;         /* group address filter 4 */
+    unsigned long   tbuf0_data0;    /* save area 0 - current frm */
+    unsigned long   tbuf0_data1;    /* save area 1 - current frm */
+    unsigned long   tbuf0_rba0;
+    unsigned long   tbuf0_crc;
+    unsigned short  tbuf0_bcnt;
+    union {
+        unsigned char b[6];
+        struct {
+            unsigned short high;
+            unsigned short middl;
+            unsigned short low;
+        } w;
+    } paddr;
+    unsigned short  p_per;          /* persistence */
+    unsigned short  rfbd_ptr;       /* rx first bd pointer */
+    unsigned short  tfbd_ptr;       /* tx first bd pointer */
+    unsigned short  tlbd_ptr;       /* tx last bd pointer */
+    unsigned long   tbuf1_data0;    /* save area 0 - next frame */
+    unsigned long   tbuf1_data1;    /* save area 1 - next frame */
+    unsigned long   tbuf1_rba0;
+    unsigned long   tbuf1_crc;
+    unsigned short  tbuf1_bcnt;
+    unsigned short  tx_len;         /* tx frame length counter */
+    unsigned short  iaddr1;         /* individual address filter 1*/
+    unsigned short  iaddr2;         /* individual address filter 2*/
+    unsigned short  iaddr3;         /* individual address filter 3*/
+    unsigned short  iaddr4;         /* individual address filter 4*/
+    unsigned short  boff_cnt;       /* back-off counter */
+    unsigned short  taddr_h;        /* temp address (MSB) */
+    unsigned short  taddr_m;        /* temp address */
+    unsigned short  taddr_l;        /* temp address (LSB) */
+};
+
+struct transparent_pram {
+    /*
+     * SCC parameter RAM
+     */
+    unsigned short  rbase;          /* RX BD base address */
+    unsigned short  tbase;          /* TX BD base address */
+    unsigned char   rfcr;           /* Rx function code */
+    unsigned char   tfcr;           /* Tx function code */
+    unsigned short  mrblr;          /* Rx buffer length */
+    unsigned long   rstate;         /* Rx internal state */
+    unsigned long   rptr;           /* Rx internal data pointer */
+    unsigned short  rbptr;          /* rb BD Pointer */
+    unsigned short  rcount;         /* Rx internal byte count */
+    unsigned long   rtemp;          /* Rx temp */
+    unsigned long   tstate;         /* Tx internal state */
+    unsigned long   tptr;           /* Tx internal data pointer */
+    unsigned short  tbptr;          /* Tx BD pointer */
+    unsigned short  tcount;         /* Tx byte count */
+    unsigned long   ttemp;          /* Tx temp */
+    unsigned long   rcrc;           /* temp receive CRC */
+    unsigned long   tcrc;           /* temp transmit CRC */
+   
+    /*
+     * TRANSPARENT specific parameter RAM
+     */
+    unsigned long   crc_p;          /* CRC Preset */
+    unsigned long   crc_c;          /* CRC constant */
+};
+
+struct timer_pram {
+    /*
+     * RISC timers parameter RAM
+     */
+    unsigned short  tm_base;        /* RISC timer table base adr */
+    unsigned short  tm_ptr;         /* RISC timer table pointer */
+    unsigned short  r_tmr;          /* RISC timer mode register */
+    unsigned short  r_tmv;          /* RISC timer valid register */
+    unsigned long   tm_cmd;         /* RISC timer cmd register */
+    unsigned long   tm_cnt;         /* RISC timer internal cnt */
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/m68360_quicc.h linux-2.4.29-uc1/include/asm-m68knommu/m68360_quicc.h
--- linux-2.4.29/include/asm-m68knommu/m68360_quicc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/m68360_quicc.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,362 @@
+/***********************************
+ * $Id: m68360_quicc.h,v 1.1.1.1 2001/05/18 17:10:11 hamilton Exp $
+ ***********************************
+ *
+ ***************************************
+ * Definitions of QUICC memory structures
+ ***************************************
+ */
+
+#ifndef __M68360_QUICC_H
+#define __M68360_QUICC_H
+
+/*
+ * include registers and
+ * parameter ram definitions files
+ */
+#include <asm/m68360_regs.h>
+#include <asm/m68360_pram.h>
+
+
+
+/* Buffer Descriptors */
+typedef struct quicc_bd {
+    volatile unsigned short     status;
+    volatile unsigned short     length;
+    volatile unsigned char      *buf;     /* WARNING: This is only true if *char is 32 bits */
+} QUICC_BD;
+
+
+#ifdef MOTOROLA_ORIGINAL
+struct user_data {
+    /* BASE + 0x000: user data memory */
+    volatile unsigned char      udata_bd_ucode[0x400]; /*user data bd's Ucode*/
+    volatile unsigned char      udata_bd[0x200];       /*user data Ucode     */
+    volatile unsigned char      ucode_ext[0x100];      /*Ucode Extention ram */
+    volatile unsigned char      RESERVED1[0x500];      /* Reserved area      */
+};
+#else
+struct user_data {
+    /* BASE + 0x000: user data memory */
+    volatile unsigned char      udata_bd_ucode[0x400]; /* user data, bds, Ucode*/
+    volatile unsigned char      udata_bd1[0x200];       /* user, bds */
+    volatile unsigned char      ucode_bd_scratch[0x100]; /* user, bds, ucode scratch */
+    volatile unsigned char      udata_bd2[0x100];       /* user, bds */
+    volatile unsigned char      RESERVED1[0x400];      /* Reserved area      */
+};
+#endif
+
+
+/*
+ * internal ram
+ */
+typedef struct quicc {
+	union {
+		struct quicc32_pram ch_pram_tbl[32];	/* 32*64(bytes) per channel */	
+		struct user_data		u;
+	}ch_or_u;	/* multipul or user space */
+
+    /* BASE + 0xc00: PARAMETER RAM */
+	union {
+		struct scc_pram {
+			union {
+				struct hdlc_pram        h;
+				struct uart_pram        u;
+				struct bisync_pram      b;
+				struct transparent_pram t;
+				unsigned char   RESERVED66[0x70];
+			} pscc;               /* scc parameter area (protocol dependent) */
+			union {
+				struct {
+					unsigned char       RESERVED70[0x10];
+					struct spi_pram     spi;
+					unsigned char       RESERVED72[0x8];
+					struct timer_pram   timer;
+				} timer_spi;
+				struct {
+					struct idma_pram idma;
+					unsigned char       RESERVED67[0x4];
+					union {
+						struct smc_uart_pram u;
+						struct smc_trnsp_pram t;
+					} psmc;
+				} idma_smc;
+			} pothers;
+		} scc;
+		struct ethernet_pram    enet_scc;
+		struct global_multi_pram        m;
+		unsigned char   pr[0x100];
+	} pram[4];
+
+    /* reserved */
+
+    /* BASE + 0x1000: INTERNAL REGISTERS */
+    /* SIM */
+    volatile unsigned long      sim_mcr;        /* module configuration reg */
+    volatile unsigned short     sim_simtr;      /* module test register     */
+    volatile unsigned char      RESERVED2[0x2]; /* Reserved area            */
+    volatile unsigned char      sim_avr;        /* auto vector reg          */
+    volatile unsigned char      sim_rsr;        /* reset status reg         */
+    volatile unsigned char      RESERVED3[0x2]; /* Reserved area            */
+    volatile unsigned char      sim_clkocr;     /* CLCO control register    */
+    volatile unsigned char      RESERVED62[0x3];        /* Reserved area    */
+    volatile unsigned short     sim_pllcr;      /* PLL control register     */
+    volatile unsigned char      RESERVED63[0x2];        /* Reserved area    */
+    volatile unsigned short     sim_cdvcr;      /* Clock devider control register */
+    volatile unsigned short     sim_pepar;      /* Port E pin assignment register */
+    volatile unsigned char      RESERVED64[0xa];        /* Reserved area    */
+    volatile unsigned char      sim_sypcr;      /* system protection control*/
+    volatile unsigned char      sim_swiv;       /* software interrupt vector*/
+    volatile unsigned char      RESERVED6[0x2]; /* Reserved area            */
+    volatile unsigned short     sim_picr;       /* periodic interrupt control reg */
+    volatile unsigned char      RESERVED7[0x2]; /* Reserved area            */
+    volatile unsigned short     sim_pitr;       /* periodic interrupt timing reg */
+    volatile unsigned char      RESERVED8[0x3]; /* Reserved area            */
+    volatile unsigned char      sim_swsr;       /* software service         */
+    volatile unsigned long      sim_bkar;       /* breakpoint address register*/
+    volatile unsigned long      sim_bkcr;       /* breakpoint control register*/
+    volatile unsigned char      RESERVED10[0x8];        /* Reserved area    */
+    /* MEMC */
+    volatile unsigned long      memc_gmr;       /* Global memory register   */
+    volatile unsigned short     memc_mstat;     /* MEMC status register     */
+    volatile unsigned char      RESERVED11[0xa];        /* Reserved area    */
+    volatile unsigned long      memc_br0;       /* base register 0          */
+    volatile unsigned long      memc_or0;       /* option register 0        */
+    volatile unsigned char      RESERVED12[0x8];        /* Reserved area    */
+    volatile unsigned long      memc_br1;       /* base register 1          */
+    volatile unsigned long      memc_or1;       /* option register 1        */
+    volatile unsigned char      RESERVED13[0x8];        /* Reserved area    */
+    volatile unsigned long      memc_br2;       /* base register 2          */
+    volatile unsigned long      memc_or2;       /* option register 2        */
+    volatile unsigned char      RESERVED14[0x8];        /* Reserved area    */
+    volatile unsigned long      memc_br3;       /* base register 3          */
+    volatile unsigned long      memc_or3;       /* option register 3        */
+    volatile unsigned char      RESERVED15[0x8];        /* Reserved area    */
+    volatile unsigned long      memc_br4;       /* base register 3          */
+    volatile unsigned long      memc_or4;       /* option register 3        */
+    volatile unsigned char      RESERVED16[0x8];        /* Reserved area    */
+    volatile unsigned long      memc_br5;       /* base register 3          */
+    volatile unsigned long      memc_or5;       /* option register 3        */
+    volatile unsigned char      RESERVED17[0x8];        /* Reserved area    */
+    volatile unsigned long      memc_br6;       /* base register 3          */
+    volatile unsigned long      memc_or6;       /* option register 3        */
+    volatile unsigned char      RESERVED18[0x8];        /* Reserved area    */
+    volatile unsigned long      memc_br7;       /* base register 3          */
+    volatile unsigned long      memc_or7;       /* option register 3        */
+    volatile unsigned char      RESERVED9[0x28];        /* Reserved area    */
+    /* TEST */
+    volatile unsigned short     test_tstmra;    /* master shift a           */
+    volatile unsigned short     test_tstmrb;    /* master shift b           */
+    volatile unsigned short     test_tstsc;     /* shift count              */
+    volatile unsigned short     test_tstrc;     /* repetition counter       */
+    volatile unsigned short     test_creg;      /* control                  */
+    volatile unsigned short     test_dreg;      /* destributed register     */
+    volatile unsigned char      RESERVED58[0x404];      /* Reserved area    */
+    /* IDMA1 */
+    volatile unsigned short     idma_iccr;      /* channel configuration reg*/
+    volatile unsigned char      RESERVED19[0x2];        /* Reserved area    */
+    volatile unsigned short     idma1_cmr;      /* dma mode reg             */
+    volatile unsigned char      RESERVED68[0x2];        /* Reserved area    */
+    volatile unsigned long      idma1_sapr;     /* dma source addr ptr      */
+    volatile unsigned long      idma1_dapr;     /* dma destination addr ptr */
+    volatile unsigned long      idma1_bcr;      /* dma byte count reg       */
+    volatile unsigned char      idma1_fcr;      /* function code reg        */
+    volatile unsigned char      RESERVED20;     /* Reserved area            */
+    volatile unsigned char      idma1_cmar;     /* channel mask reg         */
+    volatile unsigned char      RESERVED21;     /* Reserved area            */
+    volatile unsigned char      idma1_csr;      /* channel status reg       */
+    volatile unsigned char      RESERVED22[0x3];        /* Reserved area    */
+    /* SDMA */
+    volatile unsigned char      sdma_sdsr;      /* status reg               */
+    volatile unsigned char      RESERVED23;     /* Reserved area            */
+    volatile unsigned short     sdma_sdcr;      /* configuration reg        */
+    volatile unsigned long      sdma_sdar;      /* address reg              */
+    /* IDMA2 */
+    volatile unsigned char      RESERVED69[0x2];        /* Reserved area    */
+    volatile unsigned short     idma2_cmr;      /* dma mode reg             */
+    volatile unsigned long      idma2_sapr;     /* dma source addr ptr      */
+    volatile unsigned long      idma2_dapr;     /* dma destination addr ptr */
+    volatile unsigned long      idma2_bcr;      /* dma byte count reg       */
+    volatile unsigned char      idma2_fcr;      /* function code reg        */
+    volatile unsigned char      RESERVED24;     /* Reserved area            */
+    volatile unsigned char      idma2_cmar;     /* channel mask reg         */
+    volatile unsigned char      RESERVED25;     /* Reserved area            */
+    volatile unsigned char      idma2_csr;      /* channel status reg       */
+    volatile unsigned char      RESERVED26[0x7];        /* Reserved area    */
+    /* Interrupt Controller */
+    volatile unsigned long      intr_cicr;      /* CP interrupt configuration reg*/
+    volatile unsigned long      intr_cipr;      /* CP interrupt pending reg */
+    volatile unsigned long      intr_cimr;      /* CP interrupt mask reg    */
+    volatile unsigned long      intr_cisr;      /* CP interrupt in service reg*/
+    /* Parallel I/O */
+    volatile unsigned short     pio_padir;      /* port A data direction reg */
+    volatile unsigned short     pio_papar;      /* port A pin assignment reg */
+    volatile unsigned short     pio_paodr;      /* port A open drain reg    */
+    volatile unsigned short     pio_padat;      /* port A data register     */
+    volatile unsigned char      RESERVED28[0x8];        /* Reserved area    */
+    volatile unsigned short     pio_pcdir;      /* port C data direction reg*/
+    volatile unsigned short     pio_pcpar;      /* port C pin assignment reg*/
+    volatile unsigned short     pio_pcso;       /* port C special options   */
+    volatile unsigned short     pio_pcdat;      /* port C data register     */
+    volatile unsigned short     pio_pcint;      /* port C interrupt cntrl reg */
+    volatile unsigned char      RESERVED29[0x16];       /* Reserved area    */
+    /* Timer */
+    volatile unsigned short     timer_tgcr;     /* timer global configuration reg */
+    volatile unsigned char      RESERVED30[0xe];        /* Reserved area    */
+    volatile unsigned short     timer_tmr1;     /* timer 1 mode reg         */
+    volatile unsigned short     timer_tmr2;     /* timer 2 mode reg         */
+    volatile unsigned short     timer_trr1;     /* timer 1 referance reg    */
+    volatile unsigned short     timer_trr2;     /* timer 2 referance reg    */
+    volatile unsigned short     timer_tcr1;     /* timer 1 capture reg      */
+    volatile unsigned short     timer_tcr2;     /* timer 2 capture reg      */
+    volatile unsigned short     timer_tcn1;     /* timer 1 counter reg      */
+    volatile unsigned short     timer_tcn2;     /* timer 2 counter reg      */
+    volatile unsigned short     timer_tmr3;     /* timer 3 mode reg         */
+    volatile unsigned short     timer_tmr4;     /* timer 4 mode reg         */
+    volatile unsigned short     timer_trr3;     /* timer 3 referance reg    */
+    volatile unsigned short     timer_trr4;     /* timer 4 referance reg    */
+    volatile unsigned short     timer_tcr3;     /* timer 3 capture reg      */
+    volatile unsigned short     timer_tcr4;     /* timer 4 capture reg      */
+    volatile unsigned short     timer_tcn3;     /* timer 3 counter reg      */
+    volatile unsigned short     timer_tcn4;     /* timer 4 counter reg      */
+    volatile unsigned short     timer_ter1;     /* timer 1 event reg        */
+    volatile unsigned short     timer_ter2;     /* timer 2 event reg        */
+    volatile unsigned short     timer_ter3;     /* timer 3 event reg        */
+    volatile unsigned short     timer_ter4;     /* timer 4 event reg        */
+    volatile unsigned char      RESERVED34[0x8];        /* Reserved area    */
+    /* CP */
+    volatile unsigned short     cp_cr;          /* command register         */
+    volatile unsigned char      RESERVED35[0x2];        /* Reserved area    */
+    volatile unsigned short     cp_rccr;        /* main configuration reg   */
+    volatile unsigned char      RESERVED37;     /* Reserved area            */
+    volatile unsigned char      cp_rmds;        /* development support status reg */
+    volatile unsigned long      cp_rmdr;        /* development support control reg */
+    volatile unsigned short     cp_rctr1;       /* ram break register 1     */
+    volatile unsigned short     cp_rctr2;       /* ram break register 2     */
+    volatile unsigned short     cp_rctr3;       /* ram break register 3     */
+    volatile unsigned short     cp_rctr4;       /* ram break register 4     */
+    volatile unsigned char      RESERVED59[0x2];        /* Reserved area    */
+    volatile unsigned short     cp_rter;        /* RISC timers event reg    */
+    volatile unsigned char      RESERVED38[0x2];        /* Reserved area    */
+    volatile unsigned short     cp_rtmr;        /* RISC timers mask reg     */
+    volatile unsigned char      RESERVED39[0x14];       /* Reserved area    */
+    /* BRG */
+    union {
+        volatile unsigned long l;
+        struct {
+            volatile unsigned short BRGC_RESERV:14;
+            volatile unsigned short rst:1;
+            volatile unsigned short en:1;
+            volatile unsigned short extc:2;
+            volatile unsigned short atb:1;
+            volatile unsigned short cd:12;
+            volatile unsigned short div16:1;
+        } b;
+    } brgc[4];                                  /* BRG1-BRG4 configuration regs*/
+    /* SCC registers */
+    struct scc_regs {
+        union {
+            struct {
+                /* Low word. */
+                volatile unsigned short GSMR_RESERV2:1;
+                volatile unsigned short edge:2;
+                volatile unsigned short tci:1;
+                volatile unsigned short tsnc:2;
+                volatile unsigned short rinv:1;
+                volatile unsigned short tinv:1;
+                volatile unsigned short tpl:3;
+                volatile unsigned short tpp:2;
+                volatile unsigned short tend:1;
+                volatile unsigned short tdcr:2;
+                volatile unsigned short rdcr:2;
+                volatile unsigned short renc:3;
+                volatile unsigned short tenc:3;
+                volatile unsigned short diag:2;
+                volatile unsigned short enr:1;
+                volatile unsigned short ent:1;
+                volatile unsigned short mode:4;
+                /* High word. */
+                volatile unsigned short GSMR_RESERV1:14;
+                volatile unsigned short pri:1;
+                volatile unsigned short gde:1;
+                volatile unsigned short tcrc:2;
+                volatile unsigned short revd:1;
+                volatile unsigned short trx:1;
+                volatile unsigned short ttx:1;
+                volatile unsigned short cdp:1;
+                volatile unsigned short ctsp:1;
+                volatile unsigned short cds:1;
+                volatile unsigned short ctss:1;
+                volatile unsigned short tfl:1;
+                volatile unsigned short rfw:1;
+                volatile unsigned short txsy:1;
+                volatile unsigned short synl:2;
+                volatile unsigned short rtsm:1;
+                volatile unsigned short rsyn:1;
+            } b;
+            struct {
+                volatile unsigned long low;
+                volatile unsigned long high;
+            } w;
+        } scc_gsmr;                         /* SCC general mode reg         */
+        volatile unsigned short scc_psmr;   /* protocol specific mode reg   */
+        volatile unsigned char  RESERVED42[0x2]; /* Reserved area           */
+        volatile unsigned short scc_todr; /* SCC transmit on demand         */
+        volatile unsigned short scc_dsr;        /* SCC data sync reg        */
+        volatile unsigned short scc_scce;       /* SCC event reg            */
+        volatile unsigned char  RESERVED43[0x2];/* Reserved area            */
+        volatile unsigned short scc_sccm;       /* SCC mask reg             */
+        volatile unsigned char  RESERVED44[0x1];/* Reserved area            */
+        volatile unsigned char  scc_sccs;       /* SCC status reg           */
+        volatile unsigned char  RESERVED45[0x8]; /* Reserved area           */
+    } scc_regs[4];
+    /* SMC */
+    struct smc_regs {
+        volatile unsigned char  RESERVED46[0x2]; /* Reserved area           */
+        volatile unsigned short smc_smcmr;       /* SMC mode reg            */
+        volatile unsigned char  RESERVED60[0x2]; /* Reserved area           */
+        volatile unsigned char  smc_smce;        /* SMC event reg           */
+        volatile unsigned char  RESERVED47[0x3]; /* Reserved area           */
+        volatile unsigned char  smc_smcm;        /* SMC mask reg            */
+        volatile unsigned char  RESERVED48[0x5]; /* Reserved area           */
+    } smc_regs[2];
+    /* SPI */
+    volatile unsigned short     spi_spmode;     /* SPI mode reg             */
+    volatile unsigned char      RESERVED51[0x4];        /* Reserved area    */
+    volatile unsigned char      spi_spie;       /* SPI event reg            */
+    volatile unsigned char      RESERVED52[0x3];        /* Reserved area    */
+    volatile unsigned char      spi_spim;       /* SPI mask reg             */
+    volatile unsigned char      RESERVED53[0x2];        /* Reserved area    */
+    volatile unsigned char      spi_spcom;      /* SPI command reg          */
+    volatile unsigned char      RESERVED54[0x4];        /* Reserved area    */
+    /* PIP */
+    volatile unsigned short     pip_pipc;       /* pip configuration reg    */
+    volatile unsigned char      RESERVED65[0x2];        /* Reserved area    */
+    volatile unsigned short     pip_ptpr;       /* pip timing parameters reg */
+    volatile unsigned long      pip_pbdir;      /* port b data direction reg */
+    volatile unsigned long      pip_pbpar;      /* port b pin assignment reg */
+    volatile unsigned long      pip_pbodr;      /* port b open drain reg    */
+    volatile unsigned long      pip_pbdat;      /* port b data reg          */
+    volatile unsigned char      RESERVED71[0x18];       /* Reserved area    */
+    /* Serial Interface */
+    volatile unsigned long      si_simode;      /* SI mode register         */
+    volatile unsigned char      si_sigmr;       /* SI global mode register  */
+    volatile unsigned char      RESERVED55;     /* Reserved area            */
+    volatile unsigned char      si_sistr;       /* SI status register       */
+    volatile unsigned char      si_sicmr;       /* SI command register      */
+    volatile unsigned char      RESERVED56[0x4]; /* Reserved area           */
+    volatile unsigned long      si_sicr;        /* SI clock routing         */
+    volatile unsigned long      si_sirp;        /* SI ram pointers          */
+    volatile unsigned char      RESERVED57[0xc]; /* Reserved area           */
+    volatile unsigned short     si_siram[0x80]; /* SI routing ram          */
+} QUICC;
+
+#endif
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff -urN linux-2.4.29/include/asm-m68knommu/m68360_regs.h linux-2.4.29-uc1/include/asm-m68knommu/m68360_regs.h
--- linux-2.4.29/include/asm-m68knommu/m68360_regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/m68360_regs.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,408 @@
+/***********************************
+ * $Id: m68360_regs.h,v 1.1.1.1 2001/05/18 17:10:11 hamilton Exp $
+ ***********************************
+ *
+ ***************************************
+ * Definitions of the QUICC registers
+ ***************************************
+ */
+
+#ifndef __REGISTERS_H
+#define __REGISTERS_H
+
+#define CLEAR_BIT(x, bit)  x =bit 
+
+/*****************************************************************
+        Command Register
+*****************************************************************/
+
+/* bit fields within command register */
+#define SOFTWARE_RESET  0x8000
+#define CMD_OPCODE      0x0f00
+#define CMD_CHANNEL     0x00f0
+#define CMD_FLAG        0x0001
+
+/* general command opcodes */
+#define INIT_RXTX_PARAMS        0x0000
+#define INIT_RX_PARAMS          0x0100
+#define INIT_TX_PARAMS          0x0200
+#define ENTER_HUNT_MODE         0x0300
+#define STOP_TX                 0x0400
+#define GR_STOP_TX              0x0500
+#define RESTART_TX              0x0600
+#define CLOSE_RX_BD             0x0700
+#define SET_ENET_GROUP          0x0800
+#define RESET_ENET_GROUP        0x0900
+
+/* quicc32 CP commands */
+#define STOP_TX_32		0x0e00	/*add chan# bits 2-6 */
+#define ENTER_HUNT_MODE_32	0x1e00
+
+/* quicc32 mask/event SCC register */
+#define GOV	0x01
+#define GUN	0x02
+#define GINT	0x04
+#define IQOV	0x08
+
+
+/* Timer commands */
+#define SET_TIMER               0x0800
+
+/* Multi channel Interrupt structure */
+#define INTR_VALID	0x8000	/* Valid interrupt entry */
+#define INTR_WRAP	0x4000	/* Wrap bit in the interrupt entry table */
+#define INTR_CH_NU	0x07c0	/* Channel Num in interrupt table */
+#define INTR_MASK_BITS	0x383f
+
+/*
+ * General SCC mode register (GSMR)
+ */
+
+#define MODE_HDLC               0x0
+#define MODE_APPLE_TALK         0x2
+#define MODE_SS7                0x3
+#define MODE_UART               0x4
+#define MODE_PROFIBUS           0x5
+#define MODE_ASYNC_HDLC         0x6
+#define MODE_V14                0x7
+#define MODE_BISYNC             0x8
+#define MODE_DDCMP              0x9
+#define MODE_MULTI_CHANNEL      0xa
+#define MODE_ETHERNET           0xc
+
+#define DIAG_NORMAL             0x0
+#define DIAG_LOCAL_LPB          0x1
+#define DIAG_AUTO_ECHO          0x2
+#define DIAG_LBP_ECHO           0x3
+
+/* For RENC and TENC fields in GSMR */
+#define ENC_NRZ                 0x0
+#define ENC_NRZI                0x1
+#define ENC_FM0                 0x2
+#define ENC_MANCH               0x4
+#define ENC_DIFF_MANC           0x6
+
+/* For TDCR and RDCR fields in GSMR */
+#define CLOCK_RATE_1            0x0
+#define CLOCK_RATE_8            0x1
+#define CLOCK_RATE_16           0x2
+#define CLOCK_RATE_32           0x3
+
+#define TPP_00                  0x0
+#define TPP_10                  0x1
+#define TPP_01                  0x2
+#define TPP_11                  0x3
+
+#define TPL_NO                  0x0
+#define TPL_8                   0x1
+#define TPL_16                  0x2
+#define TPL_32                  0x3
+#define TPL_48                  0x4
+#define TPL_64                  0x5
+#define TPL_128                 0x6
+
+#define TSNC_INFINITE           0x0
+#define TSNC_14_65              0x1
+#define TSNC_4_15               0x2
+#define TSNC_3_1                0x3
+
+#define EDGE_BOTH               0x0
+#define EDGE_POS                0x1
+#define EDGE_NEG                0x2
+#define EDGE_NO                 0x3
+
+#define SYNL_NO                 0x0
+#define SYNL_4                  0x1
+#define SYNL_8                  0x2
+#define SYNL_16                 0x3
+
+#define TCRC_CCITT16            0x0
+#define TCRC_CRC16              0x1
+#define TCRC_CCITT32            0x2
+
+
+/*****************************************************************
+        TODR (Transmit on demand) Register
+*****************************************************************/
+#define TODR_TOD        0x8000  /* Transmit on demand */
+
+
+/*****************************************************************
+        CICR register settings
+*****************************************************************/
+
+/* note that relative irq priorities of the SCCs can be reordered
+ * if desired - see p. 7-377 of the MC68360UM */
+#define CICR_SCA_SCC1           ((uint)0x00000000)      /* SCC1 @ SCCa */
+#define CICR_SCB_SCC2           ((uint)0x00040000)      /* SCC2 @ SCCb */
+#define CICR_SCC_SCC3           ((uint)0x00200000)      /* SCC3 @ SCCc */
+#define CICR_SCD_SCC4           ((uint)0x00c00000)      /* SCC4 @ SCCd */
+
+#define CICR_IRL_MASK           ((uint)0x0000e000)      /* Core interrrupt */
+#define CICR_HP_MASK            ((uint)0x00001f00)      /* Hi-pri int. */
+#define CICR_VBA_MASK           ((uint)0x000000e0)      /* Vector Base Address */
+#define CICR_SPS                ((uint)0x00000001)      /* SCC Spread */
+
+
+/*****************************************************************
+       Interrupt bits for CIPR and CIMR (MC68360UM p. 7-379)
+*****************************************************************/
+
+#define INTR_PIO_PC0    0x80000000      /* parallel I/O C bit 0 */
+#define INTR_SCC1       0x40000000      /* SCC port 1 */
+#define INTR_SCC2       0x20000000      /* SCC port 2 */
+#define INTR_SCC3       0x10000000      /* SCC port 3 */
+#define INTR_SCC4       0x08000000      /* SCC port 4 */
+#define INTR_PIO_PC1    0x04000000      /* parallel i/o C bit 1 */
+#define INTR_TIMER1     0x02000000      /* timer 1 */
+#define INTR_PIO_PC2    0x01000000      /* parallel i/o C bit 2 */
+#define INTR_PIO_PC3    0x00800000      /* parallel i/o C bit 3 */
+#define INTR_SDMA_BERR  0x00400000      /* SDMA channel bus error */
+#define INTR_DMA1       0x00200000      /* idma 1 */
+#define INTR_DMA2       0x00100000      /* idma 2 */
+#define INTR_TIMER2     0x00040000      /* timer 2 */
+#define INTR_CP_TIMER   0x00020000      /* CP timer */
+#define INTR_PIP_STATUS 0x00010000      /* PIP status */
+#define INTR_PIO_PC4    0x00008000      /* parallel i/o C bit 4 */
+#define INTR_PIO_PC5    0x00004000      /* parallel i/o C bit 5 */
+#define INTR_TIMER3     0x00001000      /* timer 3 */
+#define INTR_PIO_PC6    0x00000800      /* parallel i/o C bit 6 */
+#define INTR_PIO_PC7    0x00000400      /* parallel i/o C bit 7 */
+#define INTR_PIO_PC8    0x00000200      /* parallel i/o C bit 8 */
+#define INTR_TIMER4     0x00000080      /* timer 4 */
+#define INTR_PIO_PC9    0x00000040      /* parallel i/o C bit 9 */
+#define INTR_SCP        0x00000020      /* SCP */
+#define INTR_SMC1       0x00000010      /* SMC 1 */
+#define INTR_SMC2       0x00000008      /* SMC 2 */
+#define INTR_PIO_PC10   0x00000004      /* parallel i/o C bit 10 */
+#define INTR_PIO_PC11   0x00000002      /* parallel i/o C bit 11 */
+#define INTR_ERR        0x00000001      /* error */
+
+
+/*****************************************************************
+        CPM Interrupt vector encodings (MC68360UM p. 7-376)
+*****************************************************************/
+
+#define CPMVEC_NR		32
+#define CPMVEC_PIO_PC0		0x1f
+#define CPMVEC_SCC1		0x1e
+#define CPMVEC_SCC2		0x1d
+#define CPMVEC_SCC3		0x1c
+#define CPMVEC_SCC4		0x1b
+#define CPMVEC_PIO_PC1		0x1a
+#define CPMVEC_TIMER1		0x19
+#define CPMVEC_PIO_PC2		0x18
+#define CPMVEC_PIO_PC3		0x17
+#define CPMVEC_SDMA_CB_ERR	0x16
+#define CPMVEC_IDMA1		0x15
+#define CPMVEC_IDMA2		0x14
+#define CPMVEC_RESERVED3	0x13
+#define CPMVEC_TIMER2		0x12
+#define CPMVEC_RISCTIMER	0x11
+#define CPMVEC_RESERVED2	0x10
+#define CPMVEC_PIO_PC4		0x0f
+#define CPMVEC_PIO_PC5		0x0e
+#define CPMVEC_TIMER3		0x0c
+#define CPMVEC_PIO_PC6		0x0b
+#define CPMVEC_PIO_PC7		0x0a
+#define CPMVEC_PIO_PC8		0x09
+#define CPMVEC_RESERVED1	0x08
+#define CPMVEC_TIMER4		0x07
+#define CPMVEC_PIO_PC9		0x06
+#define CPMVEC_SPI		0x05
+#define CPMVEC_SMC1		0x04
+#define CPMVEC_SMC2		0x03
+#define CPMVEC_PIO_PC10		0x02
+#define CPMVEC_PIO_PC11		0x01
+#define CPMVEC_ERROR		0x00
+
+/* #define CPMVEC_PIO_PC0		((ushort)0x1f) */
+/* #define CPMVEC_SCC1		((ushort)0x1e) */
+/* #define CPMVEC_SCC2		((ushort)0x1d) */
+/* #define CPMVEC_SCC3		((ushort)0x1c) */
+/* #define CPMVEC_SCC4		((ushort)0x1b) */
+/* #define CPMVEC_PIO_PC1		((ushort)0x1a) */
+/* #define CPMVEC_TIMER1		((ushort)0x19) */
+/* #define CPMVEC_PIO_PC2		((ushort)0x18) */
+/* #define CPMVEC_PIO_PC3		((ushort)0x17) */
+/* #define CPMVEC_SDMA_CB_ERR	((ushort)0x16) */
+/* #define CPMVEC_IDMA1		((ushort)0x15) */
+/* #define CPMVEC_IDMA2		((ushort)0x14) */
+/* #define CPMVEC_RESERVED3	((ushort)0x13) */
+/* #define CPMVEC_TIMER2		((ushort)0x12) */
+/* #define CPMVEC_RISCTIMER	((ushort)0x11) */
+/* #define CPMVEC_RESERVED2	((ushort)0x10) */
+/* #define CPMVEC_PIO_PC4		((ushort)0x0f) */
+/* #define CPMVEC_PIO_PC5		((ushort)0x0e) */
+/* #define CPMVEC_TIMER3		((ushort)0x0c) */
+/* #define CPMVEC_PIO_PC6		((ushort)0x0b) */
+/* #define CPMVEC_PIO_PC7		((ushort)0x0a) */
+/* #define CPMVEC_PIO_PC8		((ushort)0x09) */
+/* #define CPMVEC_RESERVED1	((ushort)0x08) */
+/* #define CPMVEC_TIMER4		((ushort)0x07) */
+/* #define CPMVEC_PIO_PC9		((ushort)0x06) */
+/* #define CPMVEC_SPI		((ushort)0x05) */
+/* #define CPMVEC_SMC1		((ushort)0x04) */
+/* #define CPMVEC_SMC2		((ushort)0x03) */
+/* #define CPMVEC_PIO_PC10		((ushort)0x02) */
+/* #define CPMVEC_PIO_PC11		((ushort)0x01) */
+/* #define CPMVEC_ERROR		((ushort)0x00) */
+
+
+/*****************************************************************
+ *        PIO control registers
+ *****************************************************************/
+
+/* Port A - See 360UM p. 7-358
+ * 
+ *  Note that most of these pins have alternate functions
+ */
+
+
+/* The macros are nice, but there are all sorts of references to 1-indexed
+ * facilities on the 68360... */
+/* #define PA_RXD(n)	((ushort)(0x01<<(2*n))) */
+/* #define PA_TXD(n)	((ushort)(0x02<<(2*n))) */
+
+#define PA_RXD1		((ushort)0x0001)
+#define PA_TXD1		((ushort)0x0002)
+#define PA_RXD2		((ushort)0x0004)
+#define PA_TXD2		((ushort)0x0008)
+#define PA_RXD3		((ushort)0x0010)
+#define PA_TXD3		((ushort)0x0020)
+#define PA_RXD4		((ushort)0x0040)
+#define PA_TXD4		((ushort)0x0080)
+
+#define PA_CLK1		((ushort)0x0100)
+#define PA_CLK2		((ushort)0x0200)
+#define PA_CLK3		((ushort)0x0400)
+#define PA_CLK4		((ushort)0x0800)
+#define PA_CLK5		((ushort)0x1000)
+#define PA_CLK6		((ushort)0x2000)
+#define PA_CLK7		((ushort)0x4000)
+#define PA_CLK8		((ushort)0x8000)
+
+
+/* Port B - See 360UM p. 7-362
+ */
+
+
+/* Port C - See 360UM p. 7-365
+ */
+
+#define PC_RTS1		((ushort)0x0001)
+#define PC_RTS2		((ushort)0x0002)
+#define PC__RTS3	((ushort)0x0004) /* !RTS3 */
+#define PC__RTS4	((ushort)0x0008) /* !RTS4 */
+
+#define PC_CTS1		((ushort)0x0010)
+#define PC_CD1		((ushort)0x0020)
+#define PC_CTS2		((ushort)0x0040)
+#define PC_CD2		((ushort)0x0080)
+#define PC_CTS3		((ushort)0x0100)
+#define PC_CD3		((ushort)0x0200)
+#define PC_CTS4		((ushort)0x0400)
+#define PC_CD4		((ushort)0x0800)
+
+
+
+/*****************************************************************
+        chip select option register
+*****************************************************************/
+#define DTACK           0xe000
+#define ADR_MASK        0x1ffc
+#define RW_MASK         0x0002
+#define FC_MASK         0x0001
+
+/*****************************************************************
+        tbase and rbase registers
+*****************************************************************/
+#define TBD_ADDR(quicc,pram) ((struct quicc_bd *) \
+    (quicc->ch_or_u.u.udata_bd_ucode + pram->tbase))
+#define RBD_ADDR(quicc,pram) ((struct quicc_bd *) \
+    (quicc->ch_or_u.u.udata_bd_ucode + pram->rbase))
+#define TBD_CUR_ADDR(quicc,pram) ((struct quicc_bd *) \
+    (quicc->ch_or_u.u.udata_bd_ucode + pram->tbptr))
+#define RBD_CUR_ADDR(quicc,pram) ((struct quicc_bd *) \
+    (quicc->ch_or_u.u.udata_bd_ucode + pram->rbptr))
+#define TBD_SET_CUR_ADDR(bd,quicc,pram) pram->tbptr = \
+    ((unsigned short)((char *)(bd) - (char *)(quicc->ch_or_u.u.udata_bd_ucode)))
+#define RBD_SET_CUR_ADDR(bd,quicc,pram) pram->rbptr = \
+    ((unsigned short)((char *)(bd) - (char *)(quicc->ch_or_u.u.udata_bd_ucode)))
+#define INCREASE_TBD(bd,quicc,pram) {  \
+    if((bd)->status & T_W)             \
+        (bd) = TBD_ADDR(quicc,pram);   \
+    else                               \
+        (bd)++;                        \
+}
+#define DECREASE_TBD(bd,quicc,pram) {  \
+    if ((bd) == TBD_ADDR(quicc, pram)) \
+        while (!((bd)->status & T_W))  \
+            (bd)++;                    \
+    else                               \
+        (bd)--;                        \
+}
+#define INCREASE_RBD(bd,quicc,pram) {  \
+    if((bd)->status & R_W)             \
+        (bd) = RBD_ADDR(quicc,pram);   \
+    else                               \
+        (bd)++;                        \
+}
+#define DECREASE_RBD(bd,quicc,pram) {  \
+    if ((bd) == RBD_ADDR(quicc, pram)) \
+        while (!((bd)->status & T_W))  \
+            (bd)++;                    \
+    else                               \
+        (bd)--;                        \
+}
+
+/*****************************************************************
+        Macros for Multi channel
+*****************************************************************/
+#define QMC_BASE(quicc,page) (struct global_multi_pram *)(&quicc->pram[page])
+#define MCBASE(quicc,page) (unsigned long)(quicc->pram[page].m.mcbase)
+#define CHANNEL_PRAM_BASE(quicc,channel) ((struct quicc32_pram *) \
+		(&(quicc->ch_or_u.ch_pram_tbl[channel])))
+#define TBD_32_ADDR(quicc,page,channel) ((struct quicc_bd *) \
+    (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->tbase)))
+#define RBD_32_ADDR(quicc,page,channel) ((struct quicc_bd *) \
+    (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->rbase)))
+#define TBD_32_CUR_ADDR(quicc,page,channel) ((struct quicc_bd *) \
+    (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->tbptr)))
+#define RBD_32_CUR_ADDR(quicc,page,channel) ((struct quicc_bd *) \
+    (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->rbptr)))
+#define TBD_32_SET_CUR_ADDR(bd,quicc,page,channel) \
+     CHANNEL_PRAM_BASE(quicc,channel)->tbptr = \
+    ((unsigned short)((char *)(bd) - (char *)(MCBASE(quicc,page))))
+#define RBD_32_SET_CUR_ADDR(bd,quicc,page,channel) \
+     CHANNEL_PRAM_BASE(quicc,channel)->rbptr = \
+    ((unsigned short)((char *)(bd) - (char *)(MCBASE(quicc,page))))
+
+#define INCREASE_TBD_32(bd,quicc,page,channel) {  \
+    if((bd)->status & T_W)                        \
+        (bd) = TBD_32_ADDR(quicc,page,channel);   \
+    else                                          \
+        (bd)++;                                   \
+}
+#define DECREASE_TBD_32(bd,quicc,page,channel) {  \
+    if ((bd) == TBD_32_ADDR(quicc, page,channel)) \
+        while (!((bd)->status & T_W))             \
+            (bd)++;                               \
+    else                                          \
+        (bd)--;                                   \
+}
+#define INCREASE_RBD_32(bd,quicc,page,channel) {  \
+    if((bd)->status & R_W)                        \
+        (bd) = RBD_32_ADDR(quicc,page,channel);   \
+    else                                          \
+        (bd)++;                                   \
+}
+#define DECREASE_RBD_32(bd,quicc,page,channel) {  \
+    if ((bd) == RBD_32_ADDR(quicc, page,channel)) \
+        while (!((bd)->status & T_W))             \
+            (bd)++;                               \
+    else                                          \
+        (bd)--;                                   \
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/machdep.h linux-2.4.29-uc1/include/asm-m68knommu/machdep.h
--- linux-2.4.29/include/asm-m68knommu/machdep.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/machdep.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,53 @@
+#ifndef _M68KNOMMU_MACHDEP_H
+#define _M68KNOMMU_MACHDEP_H
+
+struct pt_regs;
+struct kbd_repeat;
+struct mktime;
+struct hwclk_time;
+struct gendisk;
+struct buffer_head;
+
+extern void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *));
+/* machine dependent keyboard functions */
+extern int (*mach_keyb_init) (void);
+extern int (*mach_kbdrate) (struct kbd_repeat *);
+extern void (*mach_kbd_leds) (unsigned int);
+/* machine dependent irq functions */
+extern void (*mach_init_IRQ) (void);
+extern void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *);
+extern int (*mach_request_irq) (unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                                unsigned long flags, const char *devname, void *dev_id);
+extern void (*mach_free_irq) (unsigned int irq, void *dev_id);
+extern void (*mach_get_model) (char *model);
+extern int (*mach_get_hardware_list) (char *buffer);
+extern int (*mach_get_irq_list) (char *buf);
+extern void (*mach_process_int) (int irq, struct pt_regs *fp);
+/* machine dependent timer functions */
+extern unsigned long (*mach_gettimeoffset)(void);
+extern void (*mach_gettod)(int *year, int *mon, int *day, int *hour,
+			   int *min, int *sec);
+extern int (*mach_hwclk)(int, struct hwclk_time*);
+extern int (*mach_set_clock_mmss)(unsigned long);
+extern void (*mach_reset)( void );
+extern void (*mach_halt)( void );
+extern void (*mach_power_off)( void );
+extern unsigned long (*mach_hd_init) (unsigned long, unsigned long);
+extern void (*mach_hd_setup)(char *, int *);
+extern long mach_max_dma_address;
+extern void (*mach_floppy_setup)(char *, int *);
+extern void (*mach_floppy_eject)(void);
+extern void (*mach_heartbeat) (int);
+extern void (*mach_l2_flush) (int);
+extern int mach_sysrq_key;
+extern int mach_sysrq_shift_state;
+extern int mach_sysrq_shift_mask;
+extern char *mach_sysrq_xlate;
+
+#ifdef CONFIG_UCLINUX
+extern void config_BSP(char *command, int len);
+extern void (*mach_tick)(void);
+extern void (*mach_trap_init)(void);
+#endif
+
+#endif /* _M68KNOMMU_MACHDEP_H */
diff -urN linux-2.4.29/include/asm-m68knommu/math-emu.h linux-2.4.29-uc1/include/asm-m68knommu/math-emu.h
--- linux-2.4.29/include/asm-m68knommu/math-emu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/math-emu.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/math-emu.h>
diff -urN linux-2.4.29/include/asm-m68knommu/mc146818rtc.h linux-2.4.29-uc1/include/asm-m68knommu/mc146818rtc.h
--- linux-2.4.29/include/asm-m68knommu/mc146818rtc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mc146818rtc.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,9 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _M68KNOMMU_MC146818RTC_H
+#define _M68KNOMMU_MC146818RTC_H
+
+/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */
+
+#endif /* _M68KNOMMU_MC146818RTC_H */
diff -urN linux-2.4.29/include/asm-m68knommu/MC68328.h linux-2.4.29-uc1/include/asm-m68knommu/MC68328.h
--- linux-2.4.29/include/asm-m68knommu/MC68328.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/MC68328.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,1266 @@
+
+/* include/asm-m68knommu/MC68328.h: '328 control registers
+ *
+ * Copyright (C) 1999  Vladimir Gurevich <vgurevic@cisco.com>
+ *                     Bear & Hare Software, Inc.
+ *
+ * Based on include/asm-m68knommu/MC68332.h
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *
+ */
+
+#ifndef _MC68328_H_
+#define _MC68328_H_
+
+#define BYTE_REF(addr) (*((volatile unsigned char*)addr))
+#define WORD_REF(addr) (*((volatile unsigned short*)addr))
+#define LONG_REF(addr) (*((volatile unsigned long*)addr))
+
+#define PUT_FIELD(field, val) (((val) << field##_SHIFT) & field##_MASK)
+#define GET_FIELD(reg, field) (((reg) & field##_MASK) >> field##_SHIFT)
+
+/********** 
+ *
+ * 0xFFFFF0xx -- System Control
+ *
+ **********/
+ 
+/*
+ * System Control Register (SCR)
+ */
+#define SCR_ADDR	0xfffff000
+#define SCR		BYTE_REF(SCR_ADDR)
+
+#define SCR_WDTH8	0x01	/* 8-Bit Width Select */
+#define SCR_DMAP	0x04	/* Double Map */
+#define SCR_SO		0x08	/* Supervisor Only */
+#define SCR_BETEN	0x10	/* Bus-Error Time-Out Enable */
+#define SCR_PRV		0x20	/* Privilege Violation */
+#define SCR_WPV		0x40	/* Write Protect Violation */
+#define SCR_BETO	0x80	/* Bus-Error TimeOut */
+
+/*
+ * Mask Revision Register
+ */
+#define MRR_ADDR 0xfffff004
+#define MRR      LONG_REF(MRR_ADDR)
+ 
+/********** 
+ *
+ * 0xFFFFF1xx -- Chip-Select logic
+ *
+ **********/
+
+/********** 
+ *
+ * 0xFFFFF2xx -- Phase Locked Loop (PLL) & Power Control
+ *
+ **********/
+
+/*
+ * Group Base Address Registers
+ */
+#define GRPBASEA_ADDR	0xfffff100
+#define GRPBASEB_ADDR	0xfffff102
+#define GRPBASEC_ADDR	0xfffff104
+#define GRPBASED_ADDR	0xfffff106
+
+#define GRPBASEA	WORD_REF(GRPBASEA_ADDR)
+#define GRPBASEB	WORD_REF(GRPBASEB_ADDR)
+#define GRPBASEC	WORD_REF(GRPBASEC_ADDR)
+#define GRPBASED	WORD_REF(GRPBASED_ADDR)
+
+#define GRPBASE_V	  0x0001	/* Valid */
+#define GRPBASE_GBA_MASK  0xfff0	/* Group Base Address (bits 31-20) */
+
+/*
+ * Group Base Address Mask Registers 
+ */
+#define GRPMASKA_ADDR	0xfffff108
+#define GRPMASKB_ADDR	0xfffff10a
+#define GRPMASKC_ADDR	0xfffff10c
+#define GRPMASKD_ADDR	0xfffff10e
+
+#define GRPMASKA	WORD_REF(GRPMASKA_ADDR)
+#define GRPMASKB	WORD_REF(GRPMASKB_ADDR)
+#define GRPMASKC	WORD_REF(GRPMASKC_ADDR)
+#define GRPMASKD	WORD_REF(GRPMASKD_ADDR)
+
+#define GRMMASK_GMA_MASK 0xfffff0	/* Group Base Mask (bits 31-20) */
+
+/*
+ * Chip-Select Option Registers (group A)
+ */
+#define CSA0_ADDR	0xfffff110
+#define CSA1_ADDR	0xfffff114
+#define CSA2_ADDR	0xfffff118
+#define CSA3_ADDR	0xfffff11c
+
+#define CSA0		LONG_REF(CSA0_ADDR)
+#define CSA1		LONG_REF(CSA1_ADDR)
+#define CSA2		LONG_REF(CSA2_ADDR)
+#define CSA3		LONG_REF(CSA3_ADDR)
+
+#define CSA_WAIT_MASK	0x00000007	/* Wait State Selection */
+#define CSA_WAIT_SHIFT	0
+#define CSA_RO		0x00000008	/* Read-Only */
+#define CSA_AM_MASK	0x0000ff00	/* Address Mask (bits 23-16) */
+#define CSA_AM_SHIFT	8
+#define CSA_BUSW	0x00010000	/* Bus Width Select */
+#define CSA_AC_MASK	0xff000000	/* Address Compare (bits 23-16) */
+#define CSA_AC_SHIFT	24
+
+/*
+ * Chip-Select Option Registers (group B)
+ */
+#define CSB0_ADDR	0xfffff120
+#define CSB1_ADDR	0xfffff124
+#define CSB2_ADDR	0xfffff128
+#define CSB3_ADDR	0xfffff12c
+
+#define CSB0		LONG_REF(CSB0_ADDR)
+#define CSB1		LONG_REF(CSB1_ADDR)
+#define CSB2		LONG_REF(CSB2_ADDR)
+#define CSB3		LONG_REF(CSB3_ADDR)
+
+#define CSB_WAIT_MASK	0x00000007	/* Wait State Selection */
+#define CSB_WAIT_SHIFT	0
+#define CSB_RO		0x00000008	/* Read-Only */
+#define CSB_AM_MASK	0x0000ff00	/* Address Mask (bits 23-16) */
+#define CSB_AM_SHIFT	8
+#define CSB_BUSW	0x00010000	/* Bus Width Select */
+#define CSB_AC_MASK	0xff000000	/* Address Compare (bits 23-16) */
+#define CSB_AC_SHIFT	24
+
+/*
+ * Chip-Select Option Registers (group C)
+ */
+#define CSC0_ADDR	0xfffff130
+#define CSC1_ADDR	0xfffff134
+#define CSC2_ADDR	0xfffff138
+#define CSC3_ADDR	0xfffff13c
+
+#define CSC0		LONG_REF(CSC0_ADDR)
+#define CSC1		LONG_REF(CSC1_ADDR)
+#define CSC2		LONG_REF(CSC2_ADDR)
+#define CSC3		LONG_REF(CSC3_ADDR)
+
+#define CSC_WAIT_MASK	0x00000007	/* Wait State Selection */
+#define CSC_WAIT_SHIFT	0
+#define CSC_RO		0x00000008	/* Read-Only */
+#define CSC_AM_MASK	0x0000fff0	/* Address Mask (bits 23-12) */
+#define CSC_AM_SHIFT	4
+#define CSC_BUSW	0x00010000	/* Bus Width Select */
+#define CSC_AC_MASK	0xfff00000	/* Address Compare (bits 23-12) */
+#define CSC_AC_SHIFT	20
+
+/*
+ * Chip-Select Option Registers (group D)
+ */
+#define CSD0_ADDR	0xfffff140
+#define CSD1_ADDR	0xfffff144
+#define CSD2_ADDR	0xfffff148
+#define CSD3_ADDR	0xfffff14c
+
+#define CSD0		LONG_REF(CSD0_ADDR)
+#define CSD1		LONG_REF(CSD1_ADDR)
+#define CSD2		LONG_REF(CSD2_ADDR)
+#define CSD3		LONG_REF(CSD3_ADDR)
+
+#define CSD_WAIT_MASK	0x00000007	/* Wait State Selection */
+#define CSD_WAIT_SHIFT	0
+#define CSD_RO		0x00000008	/* Read-Only */
+#define CSD_AM_MASK	0x0000fff0	/* Address Mask (bits 23-12) */
+#define CSD_AM_SHIFT	4
+#define CSD_BUSW	0x00010000	/* Bus Width Select */
+#define CSD_AC_MASK	0xfff00000	/* Address Compare (bits 23-12) */
+#define CSD_AC_SHIFT	20
+
+/**********
+ *
+ * 0xFFFFF2xx -- Phase Locked Loop (PLL) & Power Control
+ *
+ **********/
+ 
+/*
+ * PLL Control Register 
+ */
+#define PLLCR_ADDR	0xfffff200
+#define PLLCR		WORD_REF(PLLCR_ADDR)
+
+#define PLLCR_DISPLL	       0x0008	/* Disable PLL */
+#define PLLCR_CLKEN	       0x0010	/* Clock (CLKO pin) enable */
+#define PLLCR_SYSCLK_SEL_MASK  0x0700	/* System Clock Selection */
+#define PLLCR_SYSCLK_SEL_SHIFT 8
+#define PLLCR_PIXCLK_SEL_MASK  0x3800	/* LCD Clock Selection */
+#define PLLCR_PIXCLK_SEL_SHIFT 11
+
+/* 'EZ328-compatible definitions */
+#define PLLCR_LCDCLK_SEL_MASK	PLLCR_PIXCLK_SEL_MASK
+#define PLLCR_LCDCLK_SEL_SHIFT	PLLCR_PIXCLK_SEL_SHIFT
+
+/*
+ * PLL Frequency Select Register
+ */
+#define PLLFSR_ADDR	0xfffff202
+#define PLLFSR		WORD_REF(PLLFSR_ADDR)
+
+#define PLLFSR_PC_MASK	0x00ff		/* P Count */
+#define PLLFSR_PC_SHIFT 0
+#define PLLFSR_QC_MASK	0x0f00		/* Q Count */
+#define PLLFSR_QC_SHIFT 8
+#define PLLFSR_PROT	0x4000		/* Protect P & Q */
+#define PLLFSR_CLK32	0x8000		/* Clock 32 (kHz) */
+
+/*
+ * Power Control Register
+ */
+#define PCTRL_ADDR	0xfffff207
+#define PCTRL		BYTE_REF(PCTRL_ADDR)
+
+#define PCTRL_WIDTH_MASK	0x1f	/* CPU Clock bursts width */
+#define PCTRL_WIDTH_SHIFT	0
+#define PCTRL_STOP		0x40	/* Enter power-save mode immediately */ 
+#define PCTRL_PCEN		0x80	/* Power Control Enable */
+
+/**********
+ *
+ * 0xFFFFF3xx -- Interrupt Controller
+ *
+ **********/
+
+/* 
+ * Interrupt Vector Register
+ */
+#define IVR_ADDR	0xfffff300
+#define IVR		BYTE_REF(IVR_ADDR)
+
+#define IVR_VECTOR_MASK 0xF8
+
+/*
+ * Interrupt control Register
+ */
+#define ICR_ADRR	0xfffff302
+#define ICR		WORD_REF(ICR_ADDR)
+
+#define ICR_ET6		0x0100	/* Edge Trigger Select for IRQ6 */
+#define ICR_ET3		0x0200	/* Edge Trigger Select for IRQ3 */
+#define ICR_ET2		0x0400	/* Edge Trigger Select for IRQ2 */
+#define ICR_ET1		0x0800	/* Edge Trigger Select for IRQ1 */
+#define ICR_POL6	0x1000	/* Polarity Control for IRQ6 */
+#define ICR_POL3	0x2000	/* Polarity Control for IRQ3 */
+#define ICR_POL2	0x4000	/* Polarity Control for IRQ2 */
+#define ICR_POL1	0x8000	/* Polarity Control for IRQ1 */
+
+/*
+ * Interrupt Mask Register
+ */
+#define IMR_ADDR	0xfffff304
+#define IMR		LONG_REF(IMR_ADDR)
+ 
+/*
+ * Define the names for bit positions first. This is useful for
+ * request_irq
+ */
+#define SPIM_IRQ_NUM	0	/* SPI Master interrupt */
+#define	TMR2_IRQ_NUM	1	/* Timer 2 interrupt */
+#define UART_IRQ_NUM	2	/* UART interrupt */	
+#define	WDT_IRQ_NUM	3	/* Watchdog Timer interrupt */
+#define RTC_IRQ_NUM	4	/* RTC interrupt */
+#define	KB_IRQ_NUM	6	/* Keyboard Interrupt */
+#define PWM_IRQ_NUM	7	/* Pulse-Width Modulator int. */
+#define	INT0_IRQ_NUM	8	/* External INT0 */
+#define	INT1_IRQ_NUM	9	/* External INT1 */
+#define	INT2_IRQ_NUM	10	/* External INT2 */
+#define	INT3_IRQ_NUM	11	/* External INT3 */
+#define	INT4_IRQ_NUM	12	/* External INT4 */
+#define	INT5_IRQ_NUM	13	/* External INT5 */
+#define	INT6_IRQ_NUM	14	/* External INT6 */
+#define	INT7_IRQ_NUM	15	/* External INT7 */
+#define IRQ1_IRQ_NUM	16	/* IRQ1 */
+#define IRQ2_IRQ_NUM	17	/* IRQ2 */
+#define IRQ3_IRQ_NUM	18	/* IRQ3 */
+#define IRQ6_IRQ_NUM	19	/* IRQ6 */
+#define PEN_IRQ_NUM	20	/* Pen Interrupt */
+#define SPIS_IRQ_NUM	21	/* SPI Slave Interrupt */
+#define TMR1_IRQ_NUM	22	/* Timer 1 interrupt */
+#define IRQ7_IRQ_NUM	23	/* IRQ7 */
+
+/* '328-compatible definitions */
+#define SPI_IRQ_NUM	SPIM_IRQ_NUM
+#define TMR_IRQ_NUM	TMR1_IRQ_NUM
+ 
+/*
+ * Here go the bitmasks themselves
+ */
+#define IMR_MSPIM 	(1 << SPIM _IRQ_NUM)	/* Mask SPI Master interrupt */
+#define	IMR_MTMR2	(1 << TMR2_IRQ_NUM)	/* Mask Timer 2 interrupt */
+#define IMR_MUART	(1 << UART_IRQ_NUM)	/* Mask UART interrupt */	
+#define	IMR_MWDT	(1 << WDT_IRQ_NUM)	/* Mask Watchdog Timer interrupt */
+#define IMR_MRTC	(1 << RTC_IRQ_NUM)	/* Mask RTC interrupt */
+#define	IMR_MKB		(1 << KB_IRQ_NUM)	/* Mask Keyboard Interrupt */
+#define IMR_MPWM	(1 << PWM_IRQ_NUM)	/* Mask Pulse-Width Modulator int. */
+#define	IMR_MINT0	(1 << INT0_IRQ_NUM)	/* Mask External INT0 */
+#define	IMR_MINT1	(1 << INT1_IRQ_NUM)	/* Mask External INT1 */
+#define	IMR_MINT2	(1 << INT2_IRQ_NUM)	/* Mask External INT2 */
+#define	IMR_MINT3	(1 << INT3_IRQ_NUM)	/* Mask External INT3 */
+#define	IMR_MINT4	(1 << INT4_IRQ_NUM)	/* Mask External INT4 */
+#define	IMR_MINT5	(1 << INT5_IRQ_NUM)	/* Mask External INT5 */
+#define	IMR_MINT6	(1 << INT6_IRQ_NUM)	/* Mask External INT6 */
+#define	IMR_MINT7	(1 << INT7_IRQ_NUM)	/* Mask External INT7 */
+#define IMR_MIRQ1	(1 << IRQ1_IRQ_NUM)	/* Mask IRQ1 */
+#define IMR_MIRQ2	(1 << IRQ2_IRQ_NUM)	/* Mask IRQ2 */
+#define IMR_MIRQ3	(1 << IRQ3_IRQ_NUM)	/* Mask IRQ3 */
+#define IMR_MIRQ6	(1 << IRQ6_IRQ_NUM)	/* Mask IRQ6 */
+#define IMR_MPEN	(1 << PEN_IRQ_NUM)	/* Mask Pen Interrupt */
+#define IMR_MSPIS	(1 << SPIS_IRQ_NUM)	/* Mask SPI Slave Interrupt */
+#define IMR_MTMR1	(1 << TMR1_IRQ_NUM)	/* Mask Timer 1 interrupt */
+#define IMR_MIRQ7	(1 << IRQ7_IRQ_NUM)	/* Mask IRQ7 */
+
+/* 'EZ328-compatible definitions */
+#define IMR_MSPI	IMR_MSPIM
+#define IMR_MTMR	IMR_MTMR1
+
+/* 
+ * Interrupt Wake-Up Enable Register
+ */
+#define IWR_ADDR	0xfffff308
+#define IWR		LONG_REF(IWR_ADDR)
+
+#define IWR_SPIM 	(1 << SPIM _IRQ_NUM)	/* SPI Master interrupt */
+#define	IWR_TMR2	(1 << TMR2_IRQ_NUM)	/* Timer 2 interrupt */
+#define IWR_UART	(1 << UART_IRQ_NUM)	/* UART interrupt */	
+#define	IWR_WDT		(1 << WDT_IRQ_NUM)	/* Watchdog Timer interrupt */
+#define IWR_RTC		(1 << RTC_IRQ_NUM)	/* RTC interrupt */
+#define	IWR_KB		(1 << KB_IRQ_NUM)	/* Keyboard Interrupt */
+#define IWR_PWM		(1 << PWM_IRQ_NUM)	/* Pulse-Width Modulator int. */
+#define	IWR_INT0	(1 << INT0_IRQ_NUM)	/* External INT0 */
+#define	IWR_INT1	(1 << INT1_IRQ_NUM)	/* External INT1 */
+#define	IWR_INT2	(1 << INT2_IRQ_NUM)	/* External INT2 */
+#define	IWR_INT3	(1 << INT3_IRQ_NUM)	/* External INT3 */
+#define	IWR_INT4	(1 << INT4_IRQ_NUM)	/* External INT4 */
+#define	IWR_INT5	(1 << INT5_IRQ_NUM)	/* External INT5 */
+#define	IWR_INT6	(1 << INT6_IRQ_NUM)	/* External INT6 */
+#define	IWR_INT7	(1 << INT7_IRQ_NUM)	/* External INT7 */
+#define IWR_IRQ1	(1 << IRQ1_IRQ_NUM)	/* IRQ1 */
+#define IWR_IRQ2	(1 << IRQ2_IRQ_NUM)	/* IRQ2 */
+#define IWR_IRQ3	(1 << IRQ3_IRQ_NUM)	/* IRQ3 */
+#define IWR_IRQ6	(1 << IRQ6_IRQ_NUM)	/* IRQ6 */
+#define IWR_PEN		(1 << PEN_IRQ_NUM)	/* Pen Interrupt */
+#define IWR_SPIS	(1 << SPIS_IRQ_NUM)	/* SPI Slave Interrupt */
+#define IWR_TMR1	(1 << TMR1_IRQ_NUM)	/* Timer 1 interrupt */
+#define IWR_IRQ7	(1 << IRQ7_IRQ_NUM)	/* IRQ7 */
+
+/* 
+ * Interrupt Status Register 
+ */
+#define ISR_ADDR	0xfffff30c
+#define ISR		LONG_REF(ISR_ADDR)
+
+#define ISR_SPIM 	(1 << SPIM _IRQ_NUM)	/* SPI Master interrupt */
+#define	ISR_TMR2	(1 << TMR2_IRQ_NUM)	/* Timer 2 interrupt */
+#define ISR_UART	(1 << UART_IRQ_NUM)	/* UART interrupt */	
+#define	ISR_WDT		(1 << WDT_IRQ_NUM)	/* Watchdog Timer interrupt */
+#define ISR_RTC		(1 << RTC_IRQ_NUM)	/* RTC interrupt */
+#define	ISR_KB		(1 << KB_IRQ_NUM)	/* Keyboard Interrupt */
+#define ISR_PWM		(1 << PWM_IRQ_NUM)	/* Pulse-Width Modulator int. */
+#define	ISR_INT0	(1 << INT0_IRQ_NUM)	/* External INT0 */
+#define	ISR_INT1	(1 << INT1_IRQ_NUM)	/* External INT1 */
+#define	ISR_INT2	(1 << INT2_IRQ_NUM)	/* External INT2 */
+#define	ISR_INT3	(1 << INT3_IRQ_NUM)	/* External INT3 */
+#define	ISR_INT4	(1 << INT4_IRQ_NUM)	/* External INT4 */
+#define	ISR_INT5	(1 << INT5_IRQ_NUM)	/* External INT5 */
+#define	ISR_INT6	(1 << INT6_IRQ_NUM)	/* External INT6 */
+#define	ISR_INT7	(1 << INT7_IRQ_NUM)	/* External INT7 */
+#define ISR_IRQ1	(1 << IRQ1_IRQ_NUM)	/* IRQ1 */
+#define ISR_IRQ2	(1 << IRQ2_IRQ_NUM)	/* IRQ2 */
+#define ISR_IRQ3	(1 << IRQ3_IRQ_NUM)	/* IRQ3 */
+#define ISR_IRQ6	(1 << IRQ6_IRQ_NUM)	/* IRQ6 */
+#define ISR_PEN		(1 << PEN_IRQ_NUM)	/* Pen Interrupt */
+#define ISR_SPIS	(1 << SPIS_IRQ_NUM)	/* SPI Slave Interrupt */
+#define ISR_TMR1	(1 << TMR1_IRQ_NUM)	/* Timer 1 interrupt */
+#define ISR_IRQ7	(1 << IRQ7_IRQ_NUM)	/* IRQ7 */
+
+/* 'EZ328-compatible definitions */
+#define ISR_SPI	ISR_SPIM
+#define ISR_TMR	ISR_TMR1
+
+/* 
+ * Interrupt Pending Register 
+ */
+#define IPR_ADDR	0xfffff310
+#define IPR		LONG_REF(IPR_ADDR)
+
+#define IPR_SPIM 	(1 << SPIM _IRQ_NUM)	/* SPI Master interrupt */
+#define	IPR_TMR2	(1 << TMR2_IRQ_NUM)	/* Timer 2 interrupt */
+#define IPR_UART	(1 << UART_IRQ_NUM)	/* UART interrupt */	
+#define	IPR_WDT		(1 << WDT_IRQ_NUM)	/* Watchdog Timer interrupt */
+#define IPR_RTC		(1 << RTC_IRQ_NUM)	/* RTC interrupt */
+#define	IPR_KB		(1 << KB_IRQ_NUM)	/* Keyboard Interrupt */
+#define IPR_PWM		(1 << PWM_IRQ_NUM)	/* Pulse-Width Modulator int. */
+#define	IPR_INT0	(1 << INT0_IRQ_NUM)	/* External INT0 */
+#define	IPR_INT1	(1 << INT1_IRQ_NUM)	/* External INT1 */
+#define	IPR_INT2	(1 << INT2_IRQ_NUM)	/* External INT2 */
+#define	IPR_INT3	(1 << INT3_IRQ_NUM)	/* External INT3 */
+#define	IPR_INT4	(1 << INT4_IRQ_NUM)	/* External INT4 */
+#define	IPR_INT5	(1 << INT5_IRQ_NUM)	/* External INT5 */
+#define	IPR_INT6	(1 << INT6_IRQ_NUM)	/* External INT6 */
+#define	IPR_INT7	(1 << INT7_IRQ_NUM)	/* External INT7 */
+#define IPR_IRQ1	(1 << IRQ1_IRQ_NUM)	/* IRQ1 */
+#define IPR_IRQ2	(1 << IRQ2_IRQ_NUM)	/* IRQ2 */
+#define IPR_IRQ3	(1 << IRQ3_IRQ_NUM)	/* IRQ3 */
+#define IPR_IRQ6	(1 << IRQ6_IRQ_NUM)	/* IRQ6 */
+#define IPR_PEN		(1 << PEN_IRQ_NUM)	/* Pen Interrupt */
+#define IPR_SPIS	(1 << SPIS_IRQ_NUM)	/* SPI Slave Interrupt */
+#define IPR_TMR1	(1 << TMR1_IRQ_NUM)	/* Timer 1 interrupt */
+#define IPR_IRQ7	(1 << IRQ7_IRQ_NUM)	/* IRQ7 */
+
+/* 'EZ328-compatible definitions */
+#define IPR_SPI	IPR_SPIM
+#define IPR_TMR	IPR_TMR1
+
+/**********
+ *
+ * 0xFFFFF4xx -- Parallel Ports
+ *
+ **********/
+
+/*
+ * Port A
+ */
+#define PADIR_ADDR	0xfffff400		/* Port A direction reg */
+#define PADATA_ADDR	0xfffff401		/* Port A data register */
+#define PASEL_ADDR	0xfffff403		/* Port A Select register */
+
+#define PADIR		BYTE_REF(PADIR_ADDR)
+#define PADATA		BYTE_REF(PADATA_ADDR)
+#define PASEL		BYTE_REF(PASEL_ADDR)
+
+#define PA(x)           (1 << (x))
+#define PA_A(x)		PA((x) - 16)	/* This is specific to PA only! */
+
+#define PA_A16		PA(0)		/* Use A16 as PA(0) */
+#define PA_A17		PA(1)		/* Use A17 as PA(1) */
+#define PA_A18		PA(2)		/* Use A18 as PA(2) */
+#define PA_A19		PA(3)		/* Use A19 as PA(3) */
+#define PA_A20		PA(4)		/* Use A20 as PA(4) */
+#define PA_A21		PA(5)		/* Use A21 as PA(5) */
+#define PA_A22		PA(6)		/* Use A22 as PA(6) */
+#define PA_A23		PA(7)		/* Use A23 as PA(7) */
+
+/* 
+ * Port B
+ */
+#define PBDIR_ADDR	0xfffff408		/* Port B direction reg */
+#define PBDATA_ADDR	0xfffff409		/* Port B data register */
+#define PBSEL_ADDR	0xfffff40b		/* Port B Select Register */
+
+#define PBDIR		BYTE_REF(PBDIR_ADDR)
+#define PBDATA		BYTE_REF(PBDATA_ADDR)
+#define PBSEL		BYTE_REF(PBSEL_ADDR)
+
+#define PB(x)           (1 << (x))
+#define PB_D(x)		PB(x)		/* This is specific to port B only */
+
+#define PB_D0		PB(0)		/* Use D0 as PB(0) */
+#define PB_D1		PB(1)		/* Use D1 as PB(1) */
+#define PB_D2		PB(2)		/* Use D2 as PB(2) */
+#define PB_D3		PB(3)		/* Use D3 as PB(3) */
+#define PB_D4		PB(4)		/* Use D4 as PB(4) */
+#define PB_D5		PB(5)		/* Use D5 as PB(5) */
+#define PB_D6		PB(6)		/* Use D6 as PB(6) */
+#define PB_D7		PB(7)		/* Use D7 as PB(7) */
+
+/* 
+ * Port C
+ */
+#define PCDIR_ADDR	0xfffff410		/* Port C direction reg */
+#define PCDATA_ADDR	0xfffff411		/* Port C data register */
+#define PCSEL_ADDR	0xfffff413		/* Port C Select Register */
+
+#define PCDIR		BYTE_REF(PCDIR_ADDR)
+#define PCDATA		BYTE_REF(PCDATA_ADDR)
+#define PCSEL		BYTE_REF(PCSEL_ADDR)
+
+#define PC(x)           (1 << (x))
+
+#define PC_WE		PC(6)		/* Use WE    as PC(6) */
+#define PC_DTACK	PC(5)		/* Use DTACK as PC(5) */
+#define PC_IRQ7		PC(4)		/* Use IRQ7  as PC(4) */
+#define PC_LDS		PC(2)		/* Use LDS   as PC(2) */
+#define PC_UDS		PC(1)		/* Use UDS   as PC(1) */
+#define PC_MOCLK	PC(0)		/* Use MOCLK as PC(0) */
+
+/* 
+ * Port D
+ */
+#define PDDIR_ADDR	0xfffff418		/* Port D direction reg */
+#define PDDATA_ADDR	0xfffff419		/* Port D data register */
+#define PDPUEN_ADDR	0xfffff41a		/* Port D Pull-Up enable reg */
+#define PDPOL_ADDR	0xfffff41c		/* Port D Polarity Register */
+#define PDIRQEN_ADDR	0xfffff41d		/* Port D IRQ enable register */
+#define	PDIQEG_ADDR	0xfffff41f		/* Port D IRQ Edge Register */
+
+#define PDDIR		BYTE_REF(PDDIR_ADDR)
+#define PDDATA		BYTE_REF(PDDATA_ADDR)
+#define PDPUEN		BYTE_REF(PDPUEN_ADDR)
+#define	PDPOL		BYTE_REF(PDPOL_ADDR)
+#define PDIRQEN		BYTE_REF(PDIRQEN_ADDR)
+#define PDIQEG		BYTE_REF(PDIQEG_ADDR)
+
+#define PD(x)           (1 << (x))
+#define PD_KB(x)	PD(x)		/* This is specific for Port D only */
+
+#define PD_KB0		PD(0)	/* Use KB0 as PD(0) */
+#define PD_KB1		PD(1)	/* Use KB1 as PD(1) */
+#define PD_KB2		PD(2)	/* Use KB2 as PD(2) */
+#define PD_KB3		PD(3)	/* Use KB3 as PD(3) */
+#define PD_KB4		PD(4)	/* Use KB4 as PD(4) */
+#define PD_KB5		PD(5)	/* Use KB5 as PD(5) */
+#define PD_KB6		PD(6)	/* Use KB6 as PD(6) */
+#define PD_KB7		PD(7)	/* Use KB7 as PD(7) */
+
+/* 
+ * Port E
+ */
+#define PEDIR_ADDR	0xfffff420		/* Port E direction reg */
+#define PEDATA_ADDR	0xfffff421		/* Port E data register */
+#define PEPUEN_ADDR	0xfffff422		/* Port E Pull-Up enable reg */
+#define PESEL_ADDR	0xfffff423		/* Port E Select Register */
+
+#define PEDIR		BYTE_REF(PEDIR_ADDR)
+#define PEDATA		BYTE_REF(PEDATA_ADDR)
+#define PEPUEN		BYTE_REF(PEPUEN_ADDR)
+#define PESEL		BYTE_REF(PESEL_ADDR)
+
+#define PE(x)           (1 << (x))
+
+#define PE_CSA1		PE(1)	/* Use CSA1 as PE(1) */
+#define PE_CSA2		PE(2)	/* Use CSA2 as PE(2) */
+#define PE_CSA3		PE(3)	/* Use CSA3 as PE(3) */
+#define PE_CSB0		PE(4)	/* Use CSB0 as PE(4) */
+#define PE_CSB1		PE(5)	/* Use CSB1 as PE(5) */
+#define PE_CSB2		PE(6)	/* Use CSB2 as PE(6) */
+#define PE_CSB3		PE(7)	/* Use CSB3 as PE(7) */
+
+/* 
+ * Port F
+ */
+#define PFDIR_ADDR	0xfffff428		/* Port F direction reg */
+#define PFDATA_ADDR	0xfffff429		/* Port F data register */
+#define PFPUEN_ADDR	0xfffff42a		/* Port F Pull-Up enable reg */
+#define PFSEL_ADDR	0xfffff42b		/* Port F Select Register */
+
+#define PFDIR		BYTE_REF(PFDIR_ADDR)
+#define PFDATA		BYTE_REF(PFDATA_ADDR)
+#define PFPUEN		BYTE_REF(PFPUEN_ADDR)
+#define PFSEL		BYTE_REF(PFSEL_ADDR)
+
+#define PF(x)           (1 << (x))
+#define PF_A(x)		PF((x) - 24)	/* This is Port F specific only */
+
+#define PF_A24		PF(0)	/* Use A24 as PF(0) */
+#define PF_A25		PF(1)	/* Use A25 as PF(1) */
+#define PF_A26		PF(2)	/* Use A26 as PF(2) */
+#define PF_A27		PF(3)	/* Use A27 as PF(3) */
+#define PF_A28		PF(4)	/* Use A28 as PF(4) */
+#define PF_A29		PF(5)	/* Use A29 as PF(5) */
+#define PF_A30		PF(6)	/* Use A30 as PF(6) */
+#define PF_A31		PF(7)	/* Use A31 as PF(7) */
+
+/* 
+ * Port G
+ */
+#define PGDIR_ADDR	0xfffff430		/* Port G direction reg */
+#define PGDATA_ADDR	0xfffff431		/* Port G data register */
+#define PGPUEN_ADDR	0xfffff432		/* Port G Pull-Up enable reg */
+#define PGSEL_ADDR	0xfffff433		/* Port G Select Register */
+
+#define PGDIR		BYTE_REF(PGDIR_ADDR)
+#define PGDATA		BYTE_REF(PGDATA_ADDR)
+#define PGPUEN		BYTE_REF(PGPUEN_ADDR)
+#define PGSEL		BYTE_REF(PGSEL_ADDR)
+
+#define PG(x)           (1 << (x))
+
+#define PG_UART_TXD	PG(0)	/* Use UART_TXD as PG(0) */
+#define PG_UART_RXD	PG(1)	/* Use UART_RXD as PG(1) */
+#define PG_PWMOUT	PG(2)	/* Use PWMOUT   as PG(2) */
+#define PG_TOUT2	PG(3)   /* Use TOUT2    as PG(3) */
+#define PG_TIN2		PG(4)	/* Use TIN2     as PG(4) */
+#define PG_TOUT1	PG(5)   /* Use TOUT1    as PG(5) */
+#define PG_TIN1		PG(6)	/* Use TIN1     as PG(6) */
+#define PG_RTCOUT	PG(7)	/* Use RTCOUT   as PG(7) */
+
+/* 
+ * Port J
+ */
+#define PJDIR_ADDR	0xfffff438		/* Port J direction reg */
+#define PJDATA_ADDR	0xfffff439		/* Port J data register */
+#define PJSEL_ADDR	0xfffff43b		/* Port J Select Register */
+
+#define PJDIR		BYTE_REF(PJDIR_ADDR)
+#define PJDATA		BYTE_REF(PJDATA_ADDR)
+#define PJSEL		BYTE_REF(PJSEL_ADDR)
+
+#define PJ(x)           (1 << (x)) 
+
+#define PJ_CSD3		PJ(7)	/* Use CSD3 as PJ(7) */
+
+/* 
+ * Port K
+ */
+#define PKDIR_ADDR	0xfffff440		/* Port K direction reg */
+#define PKDATA_ADDR	0xfffff441		/* Port K data register */
+#define PKPUEN_ADDR	0xfffff442		/* Port K Pull-Up enable reg */
+#define PKSEL_ADDR	0xfffff443		/* Port K Select Register */
+
+#define PKDIR		BYTE_REF(PKDIR_ADDR)
+#define PKDATA		BYTE_REF(PKDATA_ADDR)
+#define PKPUEN		BYTE_REF(PKPUEN_ADDR)
+#define PKSEL		BYTE_REF(PKSEL_ADDR)
+
+#define PK(x)           (1 << (x))
+
+/* 
+ * Port M
+ */
+#define PMDIR_ADDR	0xfffff438		/* Port M direction reg */
+#define PMDATA_ADDR	0xfffff439		/* Port M data register */
+#define PMPUEN_ADDR	0xfffff43a		/* Port M Pull-Up enable reg */
+#define PMSEL_ADDR	0xfffff43b		/* Port M Select Register */
+
+#define PMDIR		BYTE_REF(PMDIR_ADDR)
+#define PMDATA		BYTE_REF(PMDATA_ADDR)
+#define PMPUEN		BYTE_REF(PMPUEN_ADDR)
+#define PMSEL		BYTE_REF(PMSEL_ADDR)
+
+#define PM(x)           (1 << (x))
+
+/**********
+ *
+ * 0xFFFFF5xx -- Pulse-Width Modulator (PWM)
+ *
+ **********/
+
+/*
+ * PWM Control Register 
+ */
+#define PWMC_ADDR	0xfffff500
+#define PWMC		WORD_REF(PWMC_ADDR)
+
+#define PWMC_CLKSEL_MASK	0x0007	/* Clock Selection */
+#define PWMC_CLKSEL_SHIFT	0
+#define PWMC_PWMEN		0x0010	/* Enable PWM */
+#define PMNC_POL		0x0020	/* PWM Output Bit Polarity */
+#define PWMC_PIN		0x0080	/* Current PWM output pin status */
+#define PWMC_LOAD		0x0100	/* Force a new period */
+#define PWMC_IRQEN		0x4000	/* Interrupt Request Enable */
+#define PWMC_CLKSRC		0x8000	/* Clock Source Select */
+
+/* 'EZ328-compatible definitions */
+#define PWMC_EN	PWMC_PWMEN
+
+/*
+ * PWM Period Register
+ */
+#define PWMP_ADDR	0xfffff502
+#define PWMP		WORD_REF(PWMP_ADDR)
+
+/* 
+ * PWM Width Register 
+ */
+#define PWMW_ADDR	0xfffff504
+#define PWMW		WORD_REF(PWMW_ADDR)
+
+/*
+ * PWM Counter Register
+ */
+#define PWMCNT_ADDR	0xfffff506
+#define PWMCNT		WORD_REF(PWMCNT_ADDR)
+
+/**********
+ *
+ * 0xFFFFF6xx -- General-Purpose Timers
+ *
+ **********/
+
+/* 
+ * Timer Unit 1 and 2 Control Registers
+ */
+#define TCTL1_ADDR	0xfffff600
+#define TCTL1		WORD_REF(TCTL1_ADDR)
+#define TCTL2_ADDR	0xfffff60c
+#define TCTL2		WORD_REF(TCTL2_ADDR)
+
+#define	TCTL_TEN		0x0001	/* Timer Enable  */
+#define TCTL_CLKSOURCE_MASK 	0x000e	/* Clock Source: */
+#define   TCTL_CLKSOURCE_STOP	   0x0000	/* Stop count (disabled)    */
+#define   TCTL_CLKSOURCE_SYSCLK	   0x0002	/* SYSCLK to prescaler      */
+#define   TCTL_CLKSOURCE_SYSCLK_16 0x0004	/* SYSCLK/16 to prescaler   */
+#define   TCTL_CLKSOURCE_TIN	   0x0006	/* TIN to prescaler         */
+#define   TCTL_CLKSOURCE_32KHZ	   0x0008	/* 32kHz clock to prescaler */
+#define TCTL_IRQEN		0x0010	/* IRQ Enable    */
+#define TCTL_OM			0x0020	/* Output Mode   */
+#define TCTL_CAP_MASK		0x00c0	/* Capture Edge: */
+#define	  TCTL_CAP_RE		0x0040		/* Capture on rizing edge   */
+#define   TCTL_CAP_FE		0x0080		/* Capture on falling edge  */
+#define TCTL_FRR		0x0010	/* Free-Run Mode */
+
+/* 'EZ328-compatible definitions */
+#define TCTL_ADDR	TCTL1_ADDR
+#define TCTL		TCTL1
+
+/*
+ * Timer Unit 1 and 2 Prescaler Registers
+ */
+#define TPRER1_ADDR	0xfffff602
+#define TPRER1		WORD_REF(TPRER1_ADDR)
+#define TPRER2_ADDR	0xfffff60e
+#define TPRER2		WORD_REF(TPRER2_ADDR)
+
+/* 'EZ328-compatible definitions */
+#define TPRER_ADDR	TPRER1_ADDR
+#define TPRER		TPRER1
+
+/*
+ * Timer Unit 1 and 2 Compare Registers
+ */
+#define TCMP1_ADDR	0xfffff604
+#define TCMP1		WORD_REF(TCMP1_ADDR)
+#define TCMP2_ADDR	0xfffff610
+#define TCMP2		WORD_REF(TCMP2_ADDR)
+
+/* 'EZ328-compatible definitions */
+#define TCMP_ADDR	TCMP1_ADDR
+#define TCMP		TCMP1
+
+/*
+ * Timer Unit 1 and 2 Capture Registers
+ */
+#define TCR1_ADDR	0xfffff606
+#define TCR1		WORD_REF(TCR1_ADDR)
+#define TCR2_ADDR	0xfffff612
+#define TCR2		WORD_REF(TCR2_ADDR)
+
+/* 'EZ328-compatible definitions */
+#define TCR_ADDR	TCR1_ADDR
+#define TCR		TCR1
+
+/*
+ * Timer Unit 1 and 2 Counter Registers
+ */
+#define TCN1_ADDR	0xfffff608
+#define TCN1		WORD_REF(TCN1_ADDR)
+#define TCN2_ADDR	0xfffff614
+#define TCN2		WORD_REF(TCN2_ADDR)
+
+/* 'EZ328-compatible definitions */
+#define TCN_ADDR	TCN1_ADDR
+#define TCN		TCN
+
+/*
+ * Timer Unit 1 and 2 Status Registers
+ */
+#define TSTAT1_ADDR	0xfffff60a
+#define TSTAT1		WORD_REF(TSTAT1_ADDR)
+#define TSTAT2_ADDR	0xfffff616
+#define TSTAT2		WORD_REF(TSTAT2_ADDR)
+
+#define TSTAT_COMP	0x0001		/* Compare Event occurred */
+#define TSTAT_CAPT	0x0001		/* Capture Event occurred */
+
+/* 'EZ328-compatible definitions */
+#define TSTAT_ADDR	TSTAT1_ADDR
+#define TSTAT		TSTAT1
+
+/*
+ * Watchdog Compare Register 
+ */
+#define WRR_ADDR	0xfffff61a
+#define WRR		WORD_REF(WRR_ADDR)
+
+/*
+ * Watchdog Counter Register 
+ */
+#define WCN_ADDR	0xfffff61c
+#define WCN		WORD_REF(WCN_ADDR)
+
+/*
+ * Watchdog Control and Status Register
+ */
+#define WCSR_ADDR	0xfffff618
+#define WCSR		WORD_REF(WCSR_ADDR)
+
+#define WCSR_WDEN	0x0001	/* Watchdog Enable */
+#define WCSR_FI		0x0002	/* Forced Interrupt (instead of SW reset)*/
+#define WCSR_WRST	0x0004	/* Watchdog Reset */
+
+/**********
+ *
+ * 0xFFFFF7xx -- Serial Periferial Interface Slave (SPIS)
+ *
+ **********/
+
+/*
+ * SPI Slave Register
+ */
+#define SPISR_ADDR	0xfffff700
+#define SPISR		WORD_REF(SPISR_ADDR)
+
+#define SPISR_DATA_ADDR	0xfffff701
+#define SPISR_DATA	BYTE_REF(SPISR_DATA_ADDR)
+
+#define SPISR_DATA_MASK	 0x00ff	/* Shifted data from the external device */
+#define SPISR_DATA_SHIFT 0
+#define SPISR_SPISEN	 0x0100	/* SPIS module enable */
+#define SPISR_POL	 0x0200	/* SPSCLK polarity control */
+#define SPISR_PHA	 0x0400	/* Phase relationship between SPSCLK & SPSRxD */
+#define SPISR_OVWR	 0x0800	/* Data buffer has been overwritten */
+#define SPISR_DATARDY	 0x1000	/* Data ready */
+#define SPISR_ENPOL	 0x2000	/* Enable Polarity */
+#define SPISR_IRQEN	 0x4000	/* SPIS IRQ Enable */
+#define SPISR_SPISIRQ	 0x8000	/* SPIS IRQ posted */
+
+/**********
+ *
+ * 0xFFFFF8xx -- Serial Periferial Interface Master (SPIM)
+ *
+ **********/
+
+/*
+ * SPIM Data Register
+ */
+#define SPIMDATA_ADDR	0xfffff800
+#define SPIMDATA	WORD_REF(SPIMDATA_ADDR)
+
+/*
+ * SPIM Control/Status Register
+ */
+#define SPIMCONT_ADDR	0xfffff802
+#define SPIMCONT	WORD_REF(SPIMCONT_ADDR)
+
+#define SPIMCONT_BIT_COUNT_MASK	 0x000f	/* Transfer Length in Bytes */
+#define SPIMCONT_BIT_COUNT_SHIFT 0
+#define SPIMCONT_POL		 0x0010	/* SPMCLK Signel Polarity */
+#define	SPIMCONT_PHA		 0x0020	/* Clock/Data phase relationship */
+#define SPIMCONT_IRQEN		 0x0040 /* IRQ Enable */
+#define SPIMCONT_SPIMIRQ	 0x0080	/* Interrupt Request */
+#define SPIMCONT_XCH		 0x0100	/* Exchange */
+#define SPIMCONT_RSPIMEN	 0x0200	/* Enable SPIM */
+#define SPIMCONT_DATA_RATE_MASK	 0xe000	/* SPIM Data Rate */
+#define SPIMCONT_DATA_RATE_SHIFT 13
+
+/* 'EZ328-compatible definitions */
+#define SPIMCONT_IRQ	SPIMCONT_SPIMIRQ
+#define SPIMCONT_ENABLE	SPIMCONT_SPIMEN
+/**********
+ *
+ * 0xFFFFF9xx -- UART
+ *
+ **********/
+
+/*
+ * UART Status/Control Register
+ */
+#define USTCNT_ADDR	0xfffff900
+#define USTCNT		WORD_REF(USTCNT_ADDR)
+
+#define USTCNT_TXAVAILEN	0x0001	/* Transmitter Available Int Enable */
+#define USTCNT_TXHALFEN		0x0002	/* Transmitter Half Empty Int Enable */
+#define USTCNT_TXEMPTYEN	0x0004	/* Transmitter Empty Int Enable */
+#define USTCNT_RXREADYEN	0x0008	/* Receiver Ready Interrupt Enable */
+#define USTCNT_RXHALFEN		0x0010	/* Receiver Half-Full Int Enable */
+#define USTCNT_RXFULLEN		0x0020	/* Receiver Full Interrupt Enable */
+#define USTCNT_CTSDELTAEN	0x0040	/* CTS Delta Interrupt Enable */
+#define USTCNT_GPIODELTAEN	0x0080	/* Old Data Interrupt Enable */
+#define USTCNT_8_7		0x0100	/* Eight or seven-bit transmission */
+#define USTCNT_STOP		0x0200	/* Stop bit transmission */
+#define USTCNT_ODD_EVEN		0x0400	/* Odd Parity */
+#define	USTCNT_PARITYEN		0x0800	/* Parity Enable */
+#define USTCNT_CLKMODE		0x1000	/* Clock Mode Select */
+#define	USTCNT_TXEN		0x2000	/* Transmitter Enable */
+#define USTCNT_RXEN		0x4000	/* Receiver Enable */
+#define USTCNT_UARTEN		0x8000	/* UART Enable */
+
+/* 'EZ328-compatible definitions */
+#define USTCNT_TXAE	USTCNT_TXAVAILEN 
+#define USTCNT_TXHE	USTCNT_TXHALFEN
+#define USTCNT_TXEE	USTCNT_TXEMPTYEN
+#define USTCNT_RXRE	USTCNT_RXREADYEN
+#define USTCNT_RXHE	USTCNT_RXHALFEN
+#define USTCNT_RXFE	USTCNT_RXFULLEN
+#define USTCNT_CTSD	USTCNT_CTSDELTAEN
+#define USTCNT_ODD	USTCNT_ODD_EVEN
+#define USTCNT_PEN	USTCNT_PARITYEN
+#define USTCNT_CLKM	USTCNT_CLKMODE
+#define USTCNT_UEN	USTCNT_UARTEN
+
+/*
+ * UART Baud Control Register
+ */
+#define UBAUD_ADDR	0xfffff902
+#define UBAUD		WORD_REF(UBAUD_ADDR)
+
+#define UBAUD_PRESCALER_MASK	0x003f	/* Actual divisor is 65 - PRESCALER */
+#define UBAUD_PRESCALER_SHIFT	0
+#define UBAUD_DIVIDE_MASK	0x0700	/* Baud Rate freq. divizor */
+#define UBAUD_DIVIDE_SHIFT	8
+#define UBAUD_BAUD_SRC		0x0800	/* Baud Rate Source */
+#define UBAUD_GPIOSRC		0x1000	/* GPIO source */
+#define UBAUD_GPIODIR		0x2000	/* GPIO Direction */
+#define UBAUD_GPIO		0x4000	/* Current GPIO pin status */
+#define UBAUD_GPIODELTA		0x8000	/* GPIO pin value changed */
+
+/*
+ * UART Receiver Register 
+ */
+#define URX_ADDR	0xfffff904
+#define URX		WORD_REF(URX_ADDR)
+
+#define URX_RXDATA_ADDR	0xfffff905
+#define URX_RXDATA	BYTE_REF(URX_RXDATA_ADDR)
+
+#define URX_RXDATA_MASK	 0x00ff	/* Received data */
+#define URX_RXDATA_SHIFT 0
+#define URX_PARITY_ERROR 0x0100	/* Parity Error */
+#define URX_BREAK	 0x0200	/* Break Detected */
+#define URX_FRAME_ERROR	 0x0400	/* Framing Error */
+#define URX_OVRUN	 0x0800	/* Serial Overrun */
+#define URX_DATA_READY	 0x2000	/* Data Ready (FIFO not empty) */
+#define URX_FIFO_HALF	 0x4000 /* FIFO is Half-Full */
+#define URX_FIFO_FULL	 0x8000	/* FIFO is Full */
+
+/*
+ * UART Transmitter Register 
+ */
+#define UTX_ADDR	0xfffff906
+#define UTX		WORD_REF(UTX_ADDR)
+
+#define UTX_TXDATA_ADDR	0xfffff907
+#define UTX_TXDATA	BYTE_REF(UTX_TXDATA_ADDR)
+
+#define UTX_TXDATA_MASK	 0x00ff	/* Data to be transmitted */
+#define UTX_TXDATA_SHIFT 0
+#define UTX_CTS_DELTA	 0x0100	/* CTS changed */
+#define UTX_CTS_STATUS	 0x0200	/* CTS State */
+#define	UTX_IGNORE_CTS	 0x0800	/* Ignore CTS */
+#define UTX_SEND_BREAK	 0x1000	/* Send a BREAK */
+#define UTX_TX_AVAIL	 0x2000	/* Transmit FIFO has a slot available */
+#define UTX_FIFO_HALF	 0x4000	/* Transmit FIFO is half empty */
+#define UTX_FIFO_EMPTY	 0x8000	/* Transmit FIFO is empty */
+
+/* 'EZ328-compatible definitions */
+#define UTX_CTS_STAT	UTX_CTS_STATUS
+#define UTX_NOCTS	UTX_IGNORE_CTS
+
+/*
+ * UART Miscellaneous Register 
+ */
+#define UMISC_ADDR	0xfffff908
+#define UMISC		WORD_REF(UMISC_ADDR)
+
+#define UMISC_TX_POL	 0x0004	/* Transmit Polarity */
+#define UMISC_RX_POL	 0x0008	/* Receive Polarity */
+#define UMISC_IRDA_LOOP	 0x0010	/* IrDA Loopback Enable */
+#define UMISC_IRDA_EN	 0x0020	/* Infra-Red Enable */
+#define UMISC_RTS	 0x0040	/* Set RTS status */
+#define UMISC_RTSCONT	 0x0080	/* Choose RTS control */
+#define UMISC_LOOP	 0x1000	/* Serial Loopback Enable */
+#define UMISC_FORCE_PERR 0x2000	/* Force Parity Error */
+#define UMISC_CLKSRC	 0x4000	/* Clock Source */
+
+
+/* generalization of uart control registers to support multiple ports: */
+typedef volatile struct {
+  volatile unsigned short int ustcnt;
+  volatile unsigned short int ubaud;
+  union {
+    volatile unsigned short int w;
+    struct {
+      volatile unsigned char status;
+      volatile unsigned char rxdata;
+    } b;
+  } urx;
+  union {
+    volatile unsigned short int w;
+    struct {
+      volatile unsigned char status;
+      volatile unsigned char txdata;
+    } b;
+  } utx;
+  volatile unsigned short int umisc;
+  volatile unsigned short int pad1;
+  volatile unsigned short int pad2;
+  volatile unsigned short int pad3;
+} m68328_uart __attribute__((packed));
+
+
+/**********
+ *
+ * 0xFFFFFAxx -- LCD Controller
+ *
+ **********/
+
+/*
+ * LCD Screen Starting Address Register 
+ */
+#define LSSA_ADDR	0xfffffa00
+#define LSSA		LONG_REF(LSSA_ADDR)
+
+#define LSSA_SSA_MASK	0xfffffffe	/* Bit 0 is reserved */
+
+/*
+ * LCD Virtual Page Width Register 
+ */
+#define LVPW_ADDR	0xfffffa05
+#define LVPW		BYTE_REF(LVPW_ADDR)
+
+/*
+ * LCD Screen Width Register (not compatible with 'EZ328 !!!)
+ */
+#define LXMAX_ADDR	0xfffffa08
+#define LXMAX		WORD_REF(LXMAX_ADDR)
+
+#define LXMAX_XM_MASK	0x02ff		/* Bits 0-3 are reserved */
+
+/*
+ * LCD Screen Height Register
+ */
+#define LYMAX_ADDR	0xfffffa0a
+#define LYMAX		WORD_REF(LYMAX_ADDR)
+
+#define LYMAX_YM_MASK	0x02ff		/* Bits 10-15 are reserved */
+
+/*
+ * LCD Cursor X Position Register
+ */
+#define LCXP_ADDR	0xfffffa18
+#define LCXP		WORD_REF(LCXP_ADDR)
+
+#define LCXP_CC_MASK	0xc000		/* Cursor Control */
+#define   LCXP_CC_TRAMSPARENT	0x0000
+#define   LCXP_CC_BLACK		0x4000
+#define   LCXP_CC_REVERSED	0x8000
+#define   LCXP_CC_WHITE		0xc000
+#define LCXP_CXP_MASK	0x02ff		/* Cursor X position */
+
+/*
+ * LCD Cursor Y Position Register
+ */
+#define LCYP_ADDR	0xfffffa1a
+#define LCYP		WORD_REF(LCYP_ADDR)
+
+#define LCYP_CYP_MASK	0x01ff		/* Cursor Y Position */
+
+/*
+ * LCD Cursor Width and Heigth Register
+ */
+#define LCWCH_ADDR	0xfffffa1c
+#define LCWCH		WORD_REF(LCWCH_ADDR)
+
+#define LCWCH_CH_MASK	0x001f		/* Cursor Height */
+#define LCWCH_CH_SHIFT	0
+#define LCWCH_CW_MASK	0x1f00		/* Cursor Width */
+#define LCWCH_CW_SHIFT	8
+
+/*
+ * LCD Blink Control Register
+ */
+#define LBLKC_ADDR	0xfffffa1f
+#define LBLKC		BYTE_REF(LBLKC_ADDR)
+
+#define LBLKC_BD_MASK	0x7f	/* Blink Divisor */
+#define LBLKC_BD_SHIFT	0
+#define LBLKC_BKEN	0x80	/* Blink Enabled */
+
+/*
+ * LCD Panel Interface Configuration Register 
+ */
+#define LPICF_ADDR	0xfffffa20
+#define LPICF		BYTE_REF(LPICF_ADDR)
+
+#define LPICF_GS_MASK	 0x01	 /* Gray-Scale Mode */
+#define	  LPICF_GS_BW	   0x00
+#define   LPICF_GS_GRAY_4  0x01
+#define LPICF_PBSIZ_MASK 0x06	/* Panel Bus Width */
+#define   LPICF_PBSIZ_1	   0x00
+#define   LPICF_PBSIZ_2    0x02
+#define   LPICF_PBSIZ_4    0x04
+
+/*
+ * LCD Polarity Configuration Register 
+ */
+#define LPOLCF_ADDR	0xfffffa21
+#define LPOLCF		BYTE_REF(LPOLCF_ADDR)
+
+#define LPOLCF_PIXPOL	0x01	/* Pixel Polarity */
+#define LPOLCF_LPPOL	0x02	/* Line Pulse Polarity */
+#define LPOLCF_FLMPOL	0x04	/* Frame Marker Polarity */
+#define LPOLCF_LCKPOL	0x08	/* LCD Shift Lock Polarity */
+
+/*
+ * LACD (LCD Alternate Crystal Direction) Rate Control Register
+ */
+#define LACDRC_ADDR	0xfffffa23
+#define LACDRC		BYTE_REF(LACDRC_ADDR)
+
+#define LACDRC_ACD_MASK	 0x0f	/* Alternate Crystal Direction Control */
+#define LACDRC_ACD_SHIFT 0
+
+/*
+ * LCD Pixel Clock Divider Register
+ */
+#define LPXCD_ADDR	0xfffffa25
+#define LPXCD		BYTE_REF(LPXCD_ADDR)
+
+#define	LPXCD_PCD_MASK	0x3f 	/* Pixel Clock Divider */
+#define LPXCD_PCD_SHIFT	0
+
+/*
+ * LCD Clocking Control Register
+ */
+#define LCKCON_ADDR	0xfffffa27
+#define LCKCON		BYTE_REF(LCKCON_ADDR)
+
+#define LCKCON_PCDS	 0x01	/* Pixel Clock Divider Source Select */
+#define LCKCON_DWIDTH	 0x02	/* Display Memory Width  */
+#define LCKCON_DWS_MASK	 0x3c	/* Display Wait-State */
+#define LCKCON_DWS_SHIFT 2
+#define LCKCON_DMA16	 0x40	/* DMA burst length */
+#define LCKCON_LCDON	 0x80	/* Enable LCD Controller */
+
+/* 'EZ328-compatible definitions */
+#define LCKCON_DW_MASK	LCKCON_DWS_MASK
+#define LCKCON_DW_SHIFT	LCKCON_DWS_SHIFT
+
+/*
+ * LCD Last Buffer Address Register
+ */
+#define LLBAR_ADDR	0xfffffa29
+#define LLBAR		BYTE_REF(LLBAR_ADDR)
+
+#define LLBAR_LBAR_MASK	 0x7f	/* Number of memory words to fill 1 line */
+#define LLBAR_LBAR_SHIFT 0
+
+/*
+ * LCD Octet Terminal Count Register 
+ */
+#define LOTCR_ADDR	0xfffffa2b
+#define LOTCR		BYTE_REF(LOTCR_ADDR)
+
+/*
+ * LCD Panning Offset Register
+ */
+#define LPOSR_ADDR	0xfffffa2d
+#define LPOSR		BYTE_REF(LPOSR_ADDR)
+
+#define LPOSR_BOS	0x08	/* Byte offset (for B/W mode only */
+#define LPOSR_POS_MASK	0x07	/* Pixel Offset Code */
+#define LPOSR_POS_SHIFT	0
+
+/*
+ * LCD Frame Rate Control Modulation Register
+ */
+#define LFRCM_ADDR	0xfffffa31
+#define LFRCM		BYTE_REF(LFRCM_ADDR)
+
+#define LFRCM_YMOD_MASK	 0x0f	/* Vertical Modulation */
+#define LFRCM_YMOD_SHIFT 0
+#define LFRCM_XMOD_MASK	 0xf0	/* Horizontal Modulation */
+#define LFRCM_XMOD_SHIFT 4
+
+/*
+ * LCD Gray Palette Mapping Register
+ */
+#define LGPMR_ADDR	0xfffffa32
+#define LGPMR		WORD_REF(LGPMR_ADDR)
+
+#define LGPMR_GLEVEL3_MASK	0x000f
+#define LGPMR_GLEVEL3_SHIFT	0 
+#define LGPMR_GLEVEL2_MASK	0x00f0
+#define LGPMR_GLEVEL2_SHIFT	4 
+#define LGPMR_GLEVEL0_MASK	0x0f00
+#define LGPMR_GLEVEL0_SHIFT	8 
+#define LGPMR_GLEVEL1_MASK	0xf000
+#define LGPMR_GLEVEL1_SHIFT	12
+
+/**********
+ *
+ * 0xFFFFFBxx -- Real-Time Clock (RTC)
+ *
+ **********/
+
+/*
+ * RTC Hours Minutes and Seconds Register
+ */
+#define RTCTIME_ADDR	0xfffffb00
+#define RTCTIME		LONG_REF(RTCTIME_ADDR)
+
+#define RTCTIME_SECONDS_MASK	0x0000003f	/* Seconds */
+#define RTCTIME_SECONDS_SHIFT	0
+#define RTCTIME_MINUTES_MASK	0x003f0000	/* Minutes */
+#define RTCTIME_MINUTES_SHIFT	16
+#define RTCTIME_HOURS_MASK	0x1f000000	/* Hours */
+#define RTCTIME_HOURS_SHIFT	24
+
+/*
+ *  RTC Alarm Register 
+ */
+#define RTCALRM_ADDR    0xfffffb04
+#define RTCALRM         LONG_REF(RTCALRM_ADDR)
+
+#define RTCALRM_SECONDS_MASK    0x0000003f      /* Seconds */
+#define RTCALRM_SECONDS_SHIFT   0
+#define RTCALRM_MINUTES_MASK    0x003f0000      /* Minutes */
+#define RTCALRM_MINUTES_SHIFT   16
+#define RTCALRM_HOURS_MASK      0x1f000000      /* Hours */
+#define RTCALRM_HOURS_SHIFT     24
+
+/*
+ * RTC Control Register
+ */
+#define RTCCTL_ADDR	0xfffffb0c
+#define RTCCTL		WORD_REF(RTCCTL_ADDR)
+
+#define RTCCTL_384	0x0020	/* Crystal Selection */
+#define RTCCTL_ENABLE	0x0080	/* RTC Enable */
+
+/* 'EZ328-compatible definitions */
+#define RTCCTL_XTL	RTCCTL_384
+#define RTCCTL_EN	RTCCTL_ENABLE
+
+/*
+ * RTC Interrupt Status Register 
+ */
+#define RTCISR_ADDR	0xfffffb0e
+#define RTCISR		WORD_REF(RTCISR_ADDR)
+
+#define RTCISR_SW	0x0001	/* Stopwatch timed out */
+#define RTCISR_MIN	0x0002	/* 1-minute interrupt has occured */
+#define RTCISR_ALM	0x0004	/* Alarm interrupt has occured */
+#define RTCISR_DAY	0x0008	/* 24-hour rollover interrupt has occured */
+#define RTCISR_1HZ	0x0010	/* 1Hz interrupt has occured */
+
+/*
+ * RTC Interrupt Enable Register
+ */
+#define RTCIENR_ADDR	0xfffffb10
+#define RTCIENR		WORD_REF(RTCIENR_ADDR)
+
+#define RTCIENR_SW	0x0001	/* Stopwatch interrupt enable */
+#define RTCIENR_MIN	0x0002	/* 1-minute interrupt enable */
+#define RTCIENR_ALM	0x0004	/* Alarm interrupt enable */
+#define RTCIENR_DAY	0x0008	/* 24-hour rollover interrupt enable */
+#define RTCIENR_1HZ	0x0010	/* 1Hz interrupt enable */
+
+/* 
+ * Stopwatch Minutes Register
+ */
+#define STPWCH_ADDR	0xfffffb12
+#define STPWCH		WORD_REF(STPWCH)
+
+#define STPWCH_CNT_MASK	 0x00ff	/* Stopwatch countdown value */
+#define SPTWCH_CNT_SHIFT 0
+
+#endif /* _MC68328_H_ */
diff -urN linux-2.4.29/include/asm-m68knommu/MC68332.h linux-2.4.29-uc1/include/asm-m68knommu/MC68332.h
--- linux-2.4.29/include/asm-m68knommu/MC68332.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/MC68332.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,152 @@
+
+/* include/asm-m68knommu/MC68332.h: '332 control registers
+ *
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *
+ */
+
+#ifndef _MC68332_H_
+#define _MC68332_H_
+
+#define BYTE_REF(addr) (*((volatile unsigned char*)addr))
+#define WORD_REF(addr) (*((volatile unsigned short*)addr))
+
+#define PORTE_ADDR	0xfffa11
+#define PORTE	BYTE_REF(PORTE_ADDR)
+#define DDRE_ADDR	0xfffa15
+#define DDRE	BYTE_REF(DDRE_ADDR)
+#define PEPAR_ADDR	0xfffa17
+#define PEPAR	BYTE_REF(PEPAR_ADDR)
+
+#define PORTF_ADDR	0xfffa19
+#define PORTF	BYTE_REF(PORTF_ADDR)
+#define DDRF_ADDR	0xfffa1d
+#define DDRF	BYTE_REF(DDRF_ADDR)
+#define PFPAR_ADDR	0xfffa1f
+#define PFPAR	BYTE_REF(PFPAR_ADDR)
+
+#define PORTQS_ADDR	0xfffc15
+#define PORTQS	BYTE_REF(PORTQS_ADDR)
+#define DDRQS_ADDR	0xfffc17
+#define DDRQS	BYTE_REF(DDRQS_ADDR)
+#define PQSPAR_ADDR	0xfffc16
+#define PQSPAR	BYTE_REF(PQSPAR_ADDR)
+
+#define CSPAR0_ADDR 0xFFFA44
+#define CSPAR0 WORD_REF(CSPAR0_ADDR)
+#define CSPAR1_ADDR 0xFFFA46
+#define CSPAR1 WORD_REF(CSPAR1_ADDR)
+#define CSARBT_ADDR 0xFFFA48
+#define CSARBT WORD_REF(CSARBT_ADDR)
+#define CSOPBT_ADDR 0xFFFA4A
+#define CSOPBT WORD_REF(CSOPBT_ADDR)
+#define CSBAR0_ADDR 0xFFFA4C
+#define CSBAR0 WORD_REF(CSBAR0_ADDR)
+#define CSOR0_ADDR 0xFFFA4E
+#define CSOR0 WORD_REF(CSOR0_ADDR)
+#define CSBAR1_ADDR 0xFFFA50
+#define CSBAR1 WORD_REF(CSBAR1_ADDR)
+#define CSOR1_ADDR 0xFFFA52
+#define CSOR1 WORD_REF(CSOR1_ADDR)
+#define CSBAR2_ADDR 0xFFFA54
+#define CSBAR2 WORD_REF(CSBAR2_ADDR)
+#define CSOR2_ADDR 0xFFFA56
+#define CSOR2 WORD_REF(CSOR2_ADDR)
+#define CSBAR3_ADDR 0xFFFA58
+#define CSBAR3 WORD_REF(CSBAR3_ADDR)
+#define CSOR3_ADDR 0xFFFA5A
+#define CSOR3 WORD_REF(CSOR3_ADDR)
+#define CSBAR4_ADDR 0xFFFA5C
+#define CSBAR4 WORD_REF(CSBAR4_ADDR)
+#define CSOR4_ADDR 0xFFFA5E
+#define CSOR4 WORD_REF(CSOR4_ADDR)
+#define CSBAR5_ADDR 0xFFFA60
+#define CSBAR5 WORD_REF(CSBAR5_ADDR)
+#define CSOR5_ADDR 0xFFFA62
+#define CSOR5 WORD_REF(CSOR5_ADDR)
+#define CSBAR6_ADDR 0xFFFA64
+#define CSBAR6 WORD_REF(CSBAR6_ADDR)
+#define CSOR6_ADDR 0xFFFA66
+#define CSOR6 WORD_REF(CSOR6_ADDR)
+#define CSBAR7_ADDR 0xFFFA68
+#define CSBAR7 WORD_REF(CSBAR7_ADDR)
+#define CSOR7_ADDR 0xFFFA6A
+#define CSOR7 WORD_REF(CSOR7_ADDR)
+#define CSBAR8_ADDR 0xFFFA6C
+#define CSBAR8 WORD_REF(CSBAR8_ADDR)
+#define CSOR8_ADDR 0xFFFA6E
+#define CSOR8 WORD_REF(CSOR8_ADDR)
+#define CSBAR9_ADDR 0xFFFA70
+#define CSBAR9 WORD_REF(CSBAR9_ADDR)
+#define CSOR9_ADDR 0xFFFA72
+#define CSOR9 WORD_REF(CSOR9_ADDR)
+#define CSBAR10_ADDR 0xFFFA74
+#define CSBAR10 WORD_REF(CSBAR10_ADDR)
+#define CSOR10_ADDR 0xFFFA76
+#define CSOR10 WORD_REF(CSOR10_ADDR)
+
+#define CSOR_MODE_ASYNC	0x0000
+#define CSOR_MODE_SYNC	0x8000
+#define CSOR_MODE_MASK	0x8000
+#define CSOR_BYTE_DISABLE	0x0000
+#define CSOR_BYTE_UPPER		0x4000
+#define CSOR_BYTE_LOWER		0x2000
+#define CSOR_BYTE_BOTH		0x6000
+#define CSOR_BYTE_MASK		0x6000
+#define CSOR_RW_RSVD		0x0000
+#define CSOR_RW_READ		0x0800
+#define CSOR_RW_WRITE		0x1000
+#define CSOR_RW_BOTH		0x1800
+#define CSOR_RW_MASK		0x1800
+#define CSOR_STROBE_DS		0x0400
+#define CSOR_STROBE_AS		0x0000
+#define CSOR_STROBE_MASK	0x0400
+#define CSOR_DSACK_WAIT(x)	(wait << 6)
+#define CSOR_DSACK_FTERM	(14 << 6)
+#define CSOR_DSACK_EXTERNAL	(15 << 6)
+#define CSOR_DSACK_MASK		0x03c0
+#define CSOR_SPACE_CPU		0x0000
+#define CSOR_SPACE_USER		0x0010
+#define CSOR_SPACE_SU		0x0020
+#define CSOR_SPACE_BOTH		0x0030
+#define CSOR_SPACE_MASK		0x0030
+#define CSOR_IPL_ALL		0x0000
+#define CSOR_IPL_PRIORITY(x)	(x << 1)
+#define CSOR_IPL_MASK		0x000e
+#define CSOR_AVEC_ON		0x0001
+#define CSOR_AVEC_OFF		0x0000
+#define CSOR_AVEC_MASK		0x0001
+
+#define CSBAR_ADDR(x)		((addr >> 11) << 3) 
+#define CSBAR_ADDR_MASK		0xfff8
+#define CSBAR_BLKSIZE_2K	0x0000
+#define CSBAR_BLKSIZE_8K	0x0001
+#define CSBAR_BLKSIZE_16K	0x0002
+#define CSBAR_BLKSIZE_64K	0x0003
+#define CSBAR_BLKSIZE_128K	0x0004
+#define CSBAR_BLKSIZE_256K	0x0005
+#define CSBAR_BLKSIZE_512K	0x0006
+#define CSBAR_BLKSIZE_1M	0x0007
+#define CSBAR_BLKSIZE_MASK	0x0007
+
+#define CSPAR_DISC	0
+#define CSPAR_ALT	1
+#define CSPAR_CS8	2
+#define CSPAR_CS16	3
+#define CSPAR_MASK	3
+
+#define CSPAR0_CSBOOT(x) (x << 0)
+#define CSPAR0_CS0(x)	(x << 2)
+#define CSPAR0_CS1(x)	(x << 4)
+#define CSPAR0_CS2(x)	(x << 6)
+#define CSPAR0_CS3(x)	(x << 8)
+#define CSPAR0_CS4(x)	(x << 10)
+#define CSPAR0_CS5(x)	(x << 12)
+
+#define CSPAR1_CS6(x)	(x << 0)
+#define CSPAR1_CS7(x)	(x << 2)
+#define CSPAR1_CS8(x)	(x << 4)
+#define CSPAR1_CS9(x)	(x << 6)
+#define CSPAR1_CS10(x)	(x << 8)
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/MC68EZ328.h linux-2.4.29-uc1/include/asm-m68knommu/MC68EZ328.h
--- linux-2.4.29/include/asm-m68knommu/MC68EZ328.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/MC68EZ328.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,1253 @@
+
+/* include/asm-m68knommu/MC68EZ328.h: 'EZ328 control registers
+ *
+ * Copyright (C) 1999  Vladimir Gurevich <vgurevic@cisco.com>
+ *                     Bear & Hare Software, Inc.
+ *
+ * Based on include/asm-m68knommu/MC68332.h
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ */
+
+#ifndef _MC68EZ328_H_
+#define _MC68EZ328_H_
+
+#define BYTE_REF(addr) (*((volatile unsigned char*)addr))
+#define WORD_REF(addr) (*((volatile unsigned short*)addr))
+#define LONG_REF(addr) (*((volatile unsigned long*)addr))
+
+#define PUT_FIELD(field, val) (((val) << field##_SHIFT) & field##_MASK)
+#define GET_FIELD(reg, field) (((reg) & field##_MASK) >> field##_SHIFT)
+
+/********** 
+ *
+ * 0xFFFFF0xx -- System Control
+ *
+ **********/
+ 
+/*
+ * System Control Register (SCR)
+ */
+#define SCR_ADDR	0xfffff000
+#define SCR		BYTE_REF(SCR_ADDR)
+
+#define SCR_WDTH8	0x01	/* 8-Bit Width Select */
+#define SCR_DMAP	0x04	/* Double Map */
+#define SCR_SO		0x08	/* Supervisor Only */
+#define SCR_BETEN	0x10	/* Bus-Error Time-Out Enable */
+#define SCR_PRV		0x20	/* Privilege Violation */
+#define SCR_WPV		0x40	/* Write Protect Violation */
+#define SCR_BETO	0x80	/* Bus-Error TimeOut */
+
+/*
+ * Silicon ID Register (Mask Revision Register (MRR) for '328 Compatibility)
+ */
+#define MRR_ADDR 0xfffff004
+#define MRR	 LONG_REF(MRR_ADDR)
+
+/********** 
+ *
+ * 0xFFFFF1xx -- Chip-Select logic
+ *
+ **********/
+ 
+/*
+ * Chip Select Group Base Registers 
+ */
+#define CSGBA_ADDR	0xfffff100
+#define CSGBB_ADDR	0xfffff102
+
+#define CSGBC_ADDR	0xfffff104
+#define CSGBD_ADDR	0xfffff106
+
+#define CSGBA		WORD_REF(CSGBA_ADDR)
+#define CSGBB		WORD_REF(CSGBB_ADDR)
+#define CSGBC		WORD_REF(CSGBC_ADDR)
+#define CSGBD		WORD_REF(CSGBD_ADDR)
+
+/*
+ * Chip Select Registers 
+ */
+#define CSA_ADDR	0xfffff110
+#define CSB_ADDR	0xfffff112
+#define CSC_ADDR	0xfffff114
+#define CSD_ADDR	0xfffff116
+
+#define CSA		WORD_REF(CSA_ADDR)
+#define CSB		WORD_REF(CSB_ADDR)
+#define CSC		WORD_REF(CSC_ADDR)
+#define CSD		WORD_REF(CSD_ADDR)
+
+#define CSA_EN		0x0001		/* Chip-Select Enable */
+#define CSA_SIZ_MASK	0x000e		/* Chip-Select Size */
+#define CSA_SIZ_SHIFT   1
+#define CSA_WS_MASK	0x0070		/* Wait State */
+#define CSA_WS_SHIFT    4
+#define CSA_BSW		0x0080		/* Data Bus Width */
+#define CSA_FLASH	0x0100		/* FLASH Memory Support */
+#define CSA_RO		0x8000		/* Read-Only */
+
+#define CSB_EN		0x0001		/* Chip-Select Enable */
+#define CSB_SIZ_MASK	0x000e		/* Chip-Select Size */
+#define CSB_SIZ_SHIFT   1
+#define CSB_WS_MASK	0x0070		/* Wait State */
+#define CSB_WS_SHIFT    4
+#define CSB_BSW		0x0080		/* Data Bus Width */
+#define CSB_FLASH	0x0100		/* FLASH Memory Support */
+#define CSB_UPSIZ_MASK	0x1800		/* Unprotected memory block size */
+#define CSB_UPSIZ_SHIFT 11
+#define CSB_ROP		0x2000		/* Readonly if protected */
+#define CSB_SOP		0x4000		/* Supervisor only if protected */
+#define CSB_RO		0x8000		/* Read-Only */
+
+#define CSC_EN		0x0001		/* Chip-Select Enable */
+#define CSC_SIZ_MASK	0x000e		/* Chip-Select Size */
+#define CSC_SIZ_SHIFT   1
+#define CSC_WS_MASK	0x0070		/* Wait State */
+#define CSC_WS_SHIFT    4
+#define CSC_BSW		0x0080		/* Data Bus Width */
+#define CSC_FLASH	0x0100		/* FLASH Memory Support */
+#define CSC_UPSIZ_MASK	0x1800		/* Unprotected memory block size */
+#define CSC_UPSIZ_SHIFT 11
+#define CSC_ROP		0x2000		/* Readonly if protected */
+#define CSC_SOP		0x4000		/* Supervisor only if protected */
+#define CSC_RO		0x8000		/* Read-Only */
+
+#define CSD_EN		0x0001		/* Chip-Select Enable */
+#define CSD_SIZ_MASK	0x000e		/* Chip-Select Size */
+#define CSD_SIZ_SHIFT   1
+#define CSD_WS_MASK	0x0070		/* Wait State */
+#define CSD_WS_SHIFT    4
+#define CSD_BSW		0x0080		/* Data Bus Width */
+#define CSD_FLASH	0x0100		/* FLASH Memory Support */
+#define CSD_DRAM	0x0200		/* Dram Selection */
+#define	CSD_COMB	0x0400		/* Combining */
+#define CSD_UPSIZ_MASK	0x1800		/* Unprotected memory block size */
+#define CSD_UPSIZ_SHIFT 11
+#define CSD_ROP		0x2000		/* Readonly if protected */
+#define CSD_SOP		0x4000		/* Supervisor only if protected */
+#define CSD_RO		0x8000		/* Read-Only */
+
+/*
+ * Emulation Chip-Select Register 
+ */
+#define EMUCS_ADDR	0xfffff118
+#define EMUCS		WORD_REF(EMUCS_ADDR)
+
+#define EMUCS_WS_MASK	0x0070
+#define EMUCS_WS_SHIFT	4
+
+/********** 
+ *
+ * 0xFFFFF2xx -- Phase Locked Loop (PLL) & Power Control
+ *
+ **********/
+
+/*
+ * PLL Control Register 
+ */
+#define PLLCR_ADDR	0xfffff200
+#define PLLCR		WORD_REF(PLLCR_ADDR)
+
+#define PLLCR_DISPLL	       0x0008	/* Disable PLL */
+#define PLLCR_CLKEN	       0x0010	/* Clock (CLKO pin) enable */
+#define PLLCR_PRESC	       0x0020	/* VCO prescaler */
+#define PLLCR_SYSCLK_SEL_MASK  0x0700	/* System Clock Selection */
+#define PLLCR_SYSCLK_SEL_SHIFT 8
+#define PLLCR_LCDCLK_SEL_MASK  0x3800	/* LCD Clock Selection */
+#define PLLCR_LCDCLK_SEL_SHIFT 11
+
+/* '328-compatible definitions */
+#define PLLCR_PIXCLK_SEL_MASK	PLLCR_LCDCLK_SEL_MASK
+#define PLLCR_PIXCLK_SEL_SHIFT	PLLCR_LCDCLK_SEL_SHIFT
+
+/*
+ * PLL Frequency Select Register
+ */
+#define PLLFSR_ADDR	0xfffff202
+#define PLLFSR		WORD_REF(PLLFSR_ADDR)
+
+#define PLLFSR_PC_MASK	0x00ff		/* P Count */
+#define PLLFSR_PC_SHIFT 0
+#define PLLFSR_QC_MASK	0x0f00		/* Q Count */
+#define PLLFSR_QC_SHIFT 8
+#define PLLFSR_PROT	0x4000		/* Protect P & Q */
+#define PLLFSR_CLK32	0x8000		/* Clock 32 (kHz) */
+
+/*
+ * Power Control Register
+ */
+#define PCTRL_ADDR	0xfffff207
+#define PCTRL		BYTE_REF(PCTRL_ADDR)
+
+#define PCTRL_WIDTH_MASK	0x1f	/* CPU Clock bursts width */
+#define PCTRL_WIDTH_SHIFT	0
+#define PCTRL_PCEN		0x80	/* Power Control Enable */
+
+/**********
+ *
+ * 0xFFFFF3xx -- Interrupt Controller
+ *
+ **********/
+
+/* 
+ * Interrupt Vector Register
+ */
+#define IVR_ADDR	0xfffff300
+#define IVR		BYTE_REF(IVR_ADDR)
+
+#define IVR_VECTOR_MASK 0xF8
+
+/*
+ * Interrupt control Register
+ */
+#define ICR_ADDR	0xfffff302
+#define ICR		WORD_REF(ICR_ADDR)
+
+#define ICR_POL5	0x0080	/* Polarity Control for IRQ5 */
+#define ICR_ET6		0x0100	/* Edge Trigger Select for IRQ6 */
+#define ICR_ET3		0x0200	/* Edge Trigger Select for IRQ3 */
+#define ICR_ET2		0x0400	/* Edge Trigger Select for IRQ2 */
+#define ICR_ET1		0x0800	/* Edge Trigger Select for IRQ1 */
+#define ICR_POL6	0x1000	/* Polarity Control for IRQ6 */
+#define ICR_POL3	0x2000	/* Polarity Control for IRQ3 */
+#define ICR_POL2	0x4000	/* Polarity Control for IRQ2 */
+#define ICR_POL1	0x8000	/* Polarity Control for IRQ1 */
+
+/*
+ * Interrupt Mask Register
+ */
+#define IMR_ADDR	0xfffff304
+#define IMR		LONG_REF(IMR_ADDR)
+
+/*
+ * Define the names for bit positions first. This is useful for 
+ * request_irq
+ */
+#define SPI_IRQ_NUM	0	/* SPI interrupt */
+#define TMR_IRQ_NUM	1	/* Timer interrupt */
+#define UART_IRQ_NUM	2	/* UART interrupt */	
+#define	WDT_IRQ_NUM	3	/* Watchdog Timer interrupt */
+#define RTC_IRQ_NUM	4	/* RTC interrupt */
+#define	KB_IRQ_NUM	6	/* Keyboard Interrupt */
+#define PWM_IRQ_NUM	7	/* Pulse-Width Modulator int. */
+#define	INT0_IRQ_NUM	8	/* External INT0 */
+#define	INT1_IRQ_NUM	9	/* External INT1 */
+#define	INT2_IRQ_NUM	10	/* External INT2 */
+#define	INT3_IRQ_NUM	11	/* External INT3 */
+#define IRQ1_IRQ_NUM	16	/* IRQ1 */
+#define IRQ2_IRQ_NUM	17	/* IRQ2 */
+#define IRQ3_IRQ_NUM	18	/* IRQ3 */
+#define IRQ6_IRQ_NUM	19	/* IRQ6 */
+#define IRQ5_IRQ_NUM	20	/* IRQ5 */
+#define SAM_IRQ_NUM	22	/* Sampling Timer for RTC */
+#define EMIQ_IRQ_NUM	23	/* Emulator Interrupt */
+
+/* '328-compatible definitions */
+#define SPIM_IRQ_NUM	SPI_IRQ_NUM
+#define TMR1_IRQ_NUM	TMR_IRQ_NUM
+
+/* 
+ * Here go the bitmasks themselves
+ */
+#define IMR_MSPI 	(1 << SPI_IRQ_NUM)	/* Mask SPI interrupt */
+#define	IMR_MTMR	(1 << TMR_IRQ_NUM)	/* Mask Timer interrupt */
+#define IMR_MUART	(1 << UART_IRQ_NUM)	/* Mask UART interrupt */	
+#define	IMR_MWDT	(1 << WDT_IRQ_NUM)	/* Mask Watchdog Timer interrupt */
+#define IMR_MRTC	(1 << RTC_IRQ_NUM)	/* Mask RTC interrupt */
+#define	IMR_MKB		(1 << KB_IRQ_NUM)	/* Mask Keyboard Interrupt */
+#define IMR_MPWM	(1 << PWM_IRQ_NUM)	/* Mask Pulse-Width Modulator int. */
+#define	IMR_MINT0	(1 << INT0_IRQ_NUM)	/* Mask External INT0 */
+#define	IMR_MINT1	(1 << INT1_IRQ_NUM)	/* Mask External INT1 */
+#define	IMR_MINT2	(1 << INT2_IRQ_NUM)	/* Mask External INT2 */
+#define	IMR_MINT3	(1 << INT3_IRQ_NUM)	/* Mask External INT3 */
+#define IMR_MIRQ1	(1 << IRQ1_IRQ_NUM)	/* Mask IRQ1 */
+#define IMR_MIRQ2	(1 << IRQ2_IRQ_NUM)	/* Mask IRQ2 */
+#define IMR_MIRQ3	(1 << IRQ3_IRQ_NUM)	/* Mask IRQ3 */
+#define IMR_MIRQ6	(1 << IRQ6_IRQ_NUM)	/* Mask IRQ6 */
+#define IMR_MIRQ5	(1 << IRQ5_IRQ_NUM)	/* Mask IRQ5 */
+#define IMR_MSAM	(1 << SAM_IRQ_NUM)	/* Mask Sampling Timer for RTC */
+#define IMR_MEMIQ	(1 << EMIQ_IRQ_NUM)	/* Mask Emulator Interrupt */
+
+/* '328-compatible definitions */
+#define IMR_MSPIM	IMR_MSPI
+#define IMR_MTMR1	IMR_MTMR
+
+/* 
+ * Interrupt Status Register 
+ */
+#define ISR_ADDR	0xfffff30c
+#define ISR		LONG_REF(ISR_ADDR)
+
+#define ISR_SPI 	(1 << SPI_IRQ_NUM)	/* SPI interrupt */
+#define	ISR_TMR		(1 << TMR_IRQ_NUM)	/* Timer interrupt */
+#define ISR_UART	(1 << UART_IRQ_NUM)	/* UART interrupt */	
+#define	ISR_WDT		(1 << WDT_IRQ_NUM)	/* Watchdog Timer interrupt */
+#define ISR_RTC		(1 << RTC_IRQ_NUM)	/* RTC interrupt */
+#define	ISR_KB		(1 << KB_IRQ_NUM)	/* Keyboard Interrupt */
+#define ISR_PWM		(1 << PWM_IRQ_NUM)	/* Pulse-Width Modulator interrupt */
+#define	ISR_INT0	(1 << INT0_IRQ_NUM)	/* External INT0 */
+#define	ISR_INT1	(1 << INT1_IRQ_NUM)	/* External INT1 */
+#define	ISR_INT2	(1 << INT2_IRQ_NUM)	/* External INT2 */
+#define	ISR_INT3	(1 << INT3_IRQ_NUM)	/* External INT3 */
+#define ISR_IRQ1	(1 << IRQ1_IRQ_NUM)	/* IRQ1 */
+#define ISR_IRQ2	(1 << IRQ2_IRQ_NUM)	/* IRQ2 */
+#define ISR_IRQ3	(1 << IRQ3_IRQ_NUM)	/* IRQ3 */
+#define ISR_IRQ6	(1 << IRQ6_IRQ_NUM)	/* IRQ6 */
+#define ISR_IRQ5	(1 << IRQ5_IRQ_NUM)	/* IRQ5 */
+#define ISR_SAM		(1 << SAM_IRQ_NUM)	/* Sampling Timer for RTC */
+#define ISR_EMIQ	(1 << EMIQ_IRQ_NUM)	/* Emulator Interrupt */
+
+/* '328-compatible definitions */
+#define ISR_SPIM	ISR_SPI
+#define ISR_TMR1	ISR_TMR
+
+/* 
+ * Interrupt Pending Register 
+ */
+#define IPR_ADDR	0xfffff30c
+#define IPR		LONG_REF(IPR_ADDR)
+
+#define IPR_SPI 	(1 << SPI_IRQ_NUM)	/* SPI interrupt */
+#define	IPR_TMR		(1 << TMR_IRQ_NUM)	/* Timer interrupt */
+#define IPR_UART	(1 << UART_IRQ_NUM)	/* UART interrupt */	
+#define	IPR_WDT		(1 << WDT_IRQ_NUM)	/* Watchdog Timer interrupt */
+#define IPR_RTC		(1 << RTC_IRQ_NUM)	/* RTC interrupt */
+#define	IPR_KB		(1 << KB_IRQ_NUM)	/* Keyboard Interrupt */
+#define IPR_PWM		(1 << PWM_IRQ_NUM)	/* Pulse-Width Modulator interrupt */
+#define	IPR_INT0	(1 << INT0_IRQ_NUM)	/* External INT0 */
+#define	IPR_INT1	(1 << INT1_IRQ_NUM)	/* External INT1 */
+#define	IPR_INT2	(1 << INT2_IRQ_NUM)	/* External INT2 */
+#define	IPR_INT3	(1 << INT3_IRQ_NUM)	/* External INT3 */
+#define IPR_IRQ1	(1 << IRQ1_IRQ_NUM)	/* IRQ1 */
+#define IPR_IRQ2	(1 << IRQ2_IRQ_NUM)	/* IRQ2 */
+#define IPR_IRQ3	(1 << IRQ3_IRQ_NUM)	/* IRQ3 */
+#define IPR_IRQ6	(1 << IRQ6_IRQ_NUM)	/* IRQ6 */
+#define IPR_IRQ5	(1 << IRQ5_IRQ_NUM)	/* IRQ5 */
+#define IPR_SAM		(1 << SAM_IRQ_NUM)	/* Sampling Timer for RTC */
+#define IPR_EMIQ	(1 << EMIQ_IRQ_NUM)	/* Emulator Interrupt */
+
+/* '328-compatible definitions */
+#define IPR_SPIM	IPR_SPI
+#define IPR_TMR1	IPR_TMR
+
+/**********
+ *
+ * 0xFFFFF4xx -- Parallel Ports
+ *
+ **********/
+
+/*
+ * Port A
+ */
+#define PADIR_ADDR	0xfffff400		/* Port A direction reg */
+#define PADATA_ADDR	0xfffff401		/* Port A data register */
+#define PAPUEN_ADDR	0xfffff402		/* Port A Pull-Up enable reg */
+
+#define PADIR		BYTE_REF(PADIR_ADDR)
+#define PADATA		BYTE_REF(PADATA_ADDR)
+#define PAPUEN		BYTE_REF(PAPUEN_ADDR)
+
+#define PA(x)		(1 << (x))
+
+/* 
+ * Port B
+ */
+#define PBDIR_ADDR	0xfffff408		/* Port B direction reg */
+#define PBDATA_ADDR	0xfffff409		/* Port B data register */
+#define PBPUEN_ADDR	0xfffff40a		/* Port B Pull-Up enable reg */
+#define PBSEL_ADDR	0xfffff40b		/* Port B Select Register */
+
+#define PBDIR		BYTE_REF(PBDIR_ADDR)
+#define PBDATA		BYTE_REF(PBDATA_ADDR)
+#define PBPUEN		BYTE_REF(PBPUEN_ADDR)
+#define PBSEL		BYTE_REF(PBSEL_ADDR)
+
+#define PB(x)		(1 << (x))
+
+#define PB_CSB0		0x01	/* Use CSB0      as PB[0] */
+#define PB_CSB1		0x02	/* Use CSB1      as PB[1] */
+#define PB_CSC0_RAS0	0x04    /* Use CSC0/RAS0 as PB[2] */	
+#define PB_CSC1_RAS1	0x08    /* Use CSC1/RAS1 as PB[3] */	
+#define PB_CSD0_CAS0	0x10    /* Use CSD0/CAS0 as PB[4] */	
+#define PB_CSD1_CAS1	0x20    /* Use CSD1/CAS1 as PB[5] */
+#define PB_TIN_TOUT	0x40	/* Use TIN/TOUT  as PB[6] */
+#define PB_PWMO		0x80	/* Use PWMO      as PB[7] */
+
+/* 
+ * Port C
+ */
+#define PCDIR_ADDR	0xfffff410		/* Port C direction reg */
+#define PCDATA_ADDR	0xfffff411		/* Port C data register */
+#define PCPDEN_ADDR	0xfffff412		/* Port C Pull-Down enb. reg */
+#define PCSEL_ADDR	0xfffff413		/* Port C Select Register */
+
+#define PCDIR		BYTE_REF(PCDIR_ADDR)
+#define PCDATA		BYTE_REF(PCDATA_ADDR)
+#define PCPDEN		BYTE_REF(PCPDEN_ADDR)
+#define PCSEL		BYTE_REF(PCSEL_ADDR)
+
+#define PC(x)		(1 << (x))
+
+#define PC_LD0		0x01	/* Use LD0  as PC[0] */
+#define PC_LD1		0x02	/* Use LD1  as PC[1] */
+#define PC_LD2		0x04	/* Use LD2  as PC[2] */
+#define PC_LD3		0x08	/* Use LD3  as PC[3] */
+#define PC_LFLM		0x10	/* Use LFLM as PC[4] */
+#define PC_LLP 		0x20	/* Use LLP  as PC[5] */
+#define PC_LCLK		0x40	/* Use LCLK as PC[6] */
+#define PC_LACD		0x80	/* Use LACD as PC[7] */
+
+/* 
+ * Port D
+ */
+#define PDDIR_ADDR	0xfffff418		/* Port D direction reg */
+#define PDDATA_ADDR	0xfffff419		/* Port D data register */
+#define PDPUEN_ADDR	0xfffff41a		/* Port D Pull-Up enable reg */
+#define PDSEL_ADDR	0xfffff41b		/* Port D Select Register */
+#define PDPOL_ADDR	0xfffff41c		/* Port D Polarity Register */
+#define PDIRQEN_ADDR	0xfffff41d		/* Port D IRQ enable register */
+#define PDKBEN_ADDR	0xfffff41e		/* Port D Keyboard Enable reg */
+#define	PDIQEG_ADDR	0xfffff41f		/* Port D IRQ Edge Register */
+
+#define PDDIR		BYTE_REF(PDDIR_ADDR)
+#define PDDATA		BYTE_REF(PDDATA_ADDR)
+#define PDPUEN		BYTE_REF(PDPUEN_ADDR)
+#define PDSEL		BYTE_REF(PDSEL_ADDR)
+#define	PDPOL		BYTE_REF(PDPOL_ADDR)
+#define PDIRQEN		BYTE_REF(PDIRQEN_ADDR)
+#define PDKBEN		BYTE_REF(PDKBEN_ADDR)
+#define PDIQEG		BYTE_REF(PDIQEG_ADDR)
+
+#define PD(x)		(1 << (x))
+
+#define PD_INT0		0x01	/* Use INT0 as PD[0] */
+#define PD_INT1		0x02	/* Use INT1 as PD[1] */
+#define PD_INT2		0x04	/* Use INT2 as PD[2] */
+#define PD_INT3		0x08	/* Use INT3 as PD[3] */
+#define PD_IRQ1		0x10	/* Use IRQ1 as PD[4] */
+#define PD_IRQ2		0x20	/* Use IRQ2 as PD[5] */
+#define PD_IRQ3		0x40	/* Use IRQ3 as PD[6] */
+#define PD_IRQ6		0x80	/* Use IRQ6 as PD[7] */
+
+/* 
+ * Port E
+ */
+#define PEDIR_ADDR	0xfffff420		/* Port E direction reg */
+#define PEDATA_ADDR	0xfffff421		/* Port E data register */
+#define PEPUEN_ADDR	0xfffff422		/* Port E Pull-Up enable reg */
+#define PESEL_ADDR	0xfffff423		/* Port E Select Register */
+
+#define PEDIR		BYTE_REF(PEDIR_ADDR)
+#define PEDATA		BYTE_REF(PEDATA_ADDR)
+#define PEPUEN		BYTE_REF(PEPUEN_ADDR)
+#define PESEL		BYTE_REF(PESEL_ADDR)
+
+#define PE(x)		(1 << (x))
+
+#define PE_SPMTXD	0x01	/* Use SPMTXD as PE[0] */
+#define PE_SPMRXD	0x02	/* Use SPMRXD as PE[1] */
+#define PE_SPMCLK	0x04	/* Use SPMCLK as PE[2] */
+#define PE_DWE		0x08	/* Use DWE    as PE[3] */
+#define PE_RXD		0x10	/* Use RXD    as PE[4] */
+#define PE_TXD		0x20	/* Use TXD    as PE[5] */
+#define PE_RTS		0x40	/* Use RTS    as PE[6] */
+#define PE_CTS		0x80	/* Use CTS    as PE[7] */
+
+/* 
+ * Port F
+ */
+#define PFDIR_ADDR	0xfffff428		/* Port F direction reg */
+#define PFDATA_ADDR	0xfffff429		/* Port F data register */
+#define PFPUEN_ADDR	0xfffff42a		/* Port F Pull-Up enable reg */
+#define PFSEL_ADDR	0xfffff42b		/* Port F Select Register */
+
+#define PFDIR		BYTE_REF(PFDIR_ADDR)
+#define PFDATA		BYTE_REF(PFDATA_ADDR)
+#define PFPUEN		BYTE_REF(PFPUEN_ADDR)
+#define PFSEL		BYTE_REF(PFSEL_ADDR)
+
+#define PF(x)		(1 << (x))
+
+#define PF_LCONTRAST	0x01	/* Use LCONTRAST as PF[0] */
+#define PF_IRQ5         0x02    /* Use IRQ5      as PF[1] */
+#define PF_CLKO         0x04    /* Use CLKO      as PF[2] */
+#define PF_A20          0x08    /* Use A20       as PF[3] */
+#define PF_A21          0x10    /* Use A21       as PF[4] */
+#define PF_A22          0x20    /* Use A22       as PF[5] */
+#define PF_A23          0x40    /* Use A23       as PF[6] */
+#define PF_CSA1		0x80    /* Use CSA1      as PF[7] */
+
+/* 
+ * Port G
+ */
+#define PGDIR_ADDR	0xfffff430		/* Port G direction reg */
+#define PGDATA_ADDR	0xfffff431		/* Port G data register */
+#define PGPUEN_ADDR	0xfffff432		/* Port G Pull-Up enable reg */
+#define PGSEL_ADDR	0xfffff433		/* Port G Select Register */
+
+#define PGDIR		BYTE_REF(PGDIR_ADDR)
+#define PGDATA		BYTE_REF(PGDATA_ADDR)
+#define PGPUEN		BYTE_REF(PGPUEN_ADDR)
+#define PGSEL		BYTE_REF(PGSEL_ADDR)
+
+#define PG(x)		(1 << (x))
+
+#define PG_BUSW_DTACK	0x01	/* Use BUSW/DTACK as PG[0] */
+#define PG_A0		0x02	/* Use A0         as PG[1] */
+#define PG_EMUIRQ	0x04	/* Use EMUIRQ     as PG[2] */
+#define PG_HIZ_P_D	0x08	/* Use HIZ/P/D    as PG[3] */
+#define PG_EMUCS        0x10	/* Use EMUCS      as PG[4] */
+#define PG_EMUBRK	0x20	/* Use EMUBRK     as PG[5] */
+
+/**********
+ *
+ * 0xFFFFF5xx -- Pulse-Width Modulator (PWM)
+ *
+ **********/
+
+/*
+ * PWM Control Register 
+ */
+#define PWMC_ADDR	0xfffff500
+#define PWMC		WORD_REF(PWMC_ADDR)
+
+#define PWMC_CLKSEL_MASK	0x0003	/* Clock Selection */
+#define PWMC_CLKSEL_SHIFT	0
+#define PWMC_REPEAT_MASK	0x000c	/* Sample Repeats */
+#define PWMC_REPEAT_SHIFT	2
+#define PWMC_EN			0x0010	/* Enable PWM */
+#define PMNC_FIFOAV		0x0020	/* FIFO Available */
+#define PWMC_IRQEN		0x0040	/* Interrupt Request Enable */
+#define PWMC_IRQ		0x0080	/* Interrupt Request (FIFO empty) */
+#define PWMC_PRESCALER_MASK	0x7f00	/* Incoming Clock prescaler */
+#define PWMC_PRESCALER_SHIFT	8
+#define PWMC_CLKSRC		0x8000	/* Clock Source Select */
+
+/* '328-compatible definitions */
+#define PWMC_PWMEN	PWMC_EN
+
+/*
+ * PWM Sample Register 
+ */
+#define PWMS_ADDR	0xfffff502
+#define PWMS		WORD_REF(PWMS_ADDR)
+
+/*
+ * PWM Period Register
+ */
+#define PWMP_ADDR	0xfffff504
+#define PWMP		BYTE_REF(PWMP_ADDR)
+
+/*
+ * PWM Counter Register
+ */
+#define PWMCNT_ADDR	0xfffff505
+#define PWMCNT		BYTE_REF(PWMCNT_ADDR)
+
+/**********
+ *
+ * 0xFFFFF6xx -- General-Purpose Timer
+ *
+ **********/
+
+/* 
+ * Timer Control register
+ */
+#define TCTL_ADDR	0xfffff600
+#define TCTL		WORD_REF(TCTL_ADDR)
+
+#define	TCTL_TEN		0x0001	/* Timer Enable  */
+#define TCTL_CLKSOURCE_MASK 	0x000e	/* Clock Source: */
+#define   TCTL_CLKSOURCE_STOP	   0x0000	/* Stop count (disabled)    */
+#define   TCTL_CLKSOURCE_SYSCLK	   0x0002	/* SYSCLK to prescaler      */
+#define   TCTL_CLKSOURCE_SYSCLK_16 0x0004	/* SYSCLK/16 to prescaler   */
+#define   TCTL_CLKSOURCE_TIN	   0x0006	/* TIN to prescaler         */
+#define   TCTL_CLKSOURCE_32KHZ	   0x0008	/* 32kHz clock to prescaler */
+#define TCTL_IRQEN		0x0010	/* IRQ Enable    */
+#define TCTL_OM			0x0020	/* Output Mode   */
+#define TCTL_CAP_MASK		0x00c0	/* Capture Edge: */
+#define	  TCTL_CAP_RE		0x0040		/* Capture on rizing edge   */
+#define   TCTL_CAP_FE		0x0080		/* Capture on falling edge  */
+#define TCTL_FRR		0x0010	/* Free-Run Mode */
+
+/* '328-compatible definitions */
+#define TCTL1_ADDR	TCTL_ADDR
+#define TCTL1		TCTL
+
+/*
+ * Timer Prescaler Register
+ */
+#define TPRER_ADDR	0xfffff602
+#define TPRER		WORD_REF(TPRER_ADDR)
+
+/* '328-compatible definitions */
+#define TPRER1_ADDR	TPRER_ADDR
+#define TPRER1		TPRER
+
+/*
+ * Timer Compare Register
+ */
+#define TCMP_ADDR	0xfffff604
+#define TCMP		WORD_REF(TCMP_ADDR)
+
+/* '328-compatible definitions */
+#define TCMP1_ADDR	TCMP_ADDR
+#define TCMP1		TCMP
+
+/*
+ * Timer Capture register
+ */
+#define TCR_ADDR	0xfffff606
+#define TCR		WORD_REF(TCR_ADDR)
+
+/* '328-compatible definitions */
+#define TCR1_ADDR	TCR_ADDR
+#define TCR1		TCR
+
+/*
+ * Timer Counter Register
+ */
+#define TCN_ADDR	0xfffff608
+#define TCN		WORD_REF(TCN_ADDR)
+
+/* '328-compatible definitions */
+#define TCN1_ADDR	TCN_ADDR
+#define TCN1		TCN
+
+/*
+ * Timer Status Register
+ */
+#define TSTAT_ADDR	0xfffff60a
+#define TSTAT		WORD_REF(TSTAT_ADDR)
+
+#define TSTAT_COMP	0x0001		/* Compare Event occurred */
+#define TSTAT_CAPT	0x0001		/* Capture Event occurred */
+
+/* '328-compatible definitions */
+#define TSTAT1_ADDR	TSTAT_ADDR
+#define TSTAT1		TSTAT
+
+/**********
+ *
+ * 0xFFFFF8xx -- Serial Periferial Interface Master (SPIM)
+ *
+ **********/
+
+/*
+ * SPIM Data Register
+ */
+#define SPIMDATA_ADDR	0xfffff800
+#define SPIMDATA	WORD_REF(SPIMDATA_ADDR)
+
+/*
+ * SPIM Control/Status Register
+ */
+#define SPIMCONT_ADDR	0xfffff802
+#define SPIMCONT	WORD_REF(SPIMCONT_ADDR)
+
+#define SPIMCONT_BIT_COUNT_MASK	 0x000f	/* Transfer Length in Bytes */
+#define SPIMCONT_BIT_COUNT_SHIFT 0
+#define SPIMCONT_POL		 0x0010	/* SPMCLK Signel Polarity */
+#define	SPIMCONT_PHA		 0x0020	/* Clock/Data phase relationship */
+#define SPIMCONT_IRQEN		 0x0040 /* IRQ Enable */
+#define SPIMCONT_IRQ		 0x0080	/* Interrupt Request */
+#define SPIMCONT_XCH		 0x0100	/* Exchange */
+#define SPIMCONT_ENABLE		 0x0200	/* Enable SPIM */
+#define SPIMCONT_DATA_RATE_MASK	 0xe000	/* SPIM Data Rate */
+#define SPIMCONT_DATA_RATE_SHIFT 13
+
+/* '328-compatible definitions */
+#define SPIMCONT_SPIMIRQ	SPIMCONT_IRQ
+#define SPIMCONT_SPIMEN		SPIMCONT_ENABLE
+
+/**********
+ *
+ * 0xFFFFF9xx -- UART
+ *
+ **********/
+
+/*
+ * UART Status/Control Register
+ */
+#define USTCNT_ADDR	0xfffff900
+#define USTCNT		WORD_REF(USTCNT_ADDR)
+
+#define USTCNT_TXAE	0x0001	/* Transmitter Available Interrupt Enable */
+#define USTCNT_TXHE	0x0002	/* Transmitter Half Empty Enable */
+#define USTCNT_TXEE	0x0004	/* Transmitter Empty Interrupt Enable */
+#define USTCNT_RXRE	0x0008	/* Receiver Ready Interrupt Enable */
+#define USTCNT_RXHE	0x0010	/* Receiver Half-Full Interrupt Enable */
+#define USTCNT_RXFE	0x0020	/* Receiver Full Interrupt Enable */
+#define USTCNT_CTSD	0x0040	/* CTS Delta Interrupt Enable */
+#define USTCNT_ODEN	0x0080	/* Old Data Interrupt Enable */
+#define USTCNT_8_7	0x0100	/* Eight or seven-bit transmission */
+#define USTCNT_STOP	0x0200	/* Stop bit transmission */
+#define USTCNT_ODD	0x0400	/* Odd Parity */
+#define	USTCNT_PEN	0x0800	/* Parity Enable */
+#define USTCNT_CLKM	0x1000	/* Clock Mode Select */
+#define	USTCNT_TXEN	0x2000	/* Transmitter Enable */
+#define USTCNT_RXEN	0x4000	/* Receiver Enable */
+#define USTCNT_UEN	0x8000	/* UART Enable */
+
+/* '328-compatible definitions */
+#define USTCNT_TXAVAILEN	USTCNT_TXAE
+#define USTCNT_TXHALFEN		USTCNT_TXHE
+#define USTCNT_TXEMPTYEN	USTCNT_TXEE
+#define USTCNT_RXREADYEN	USTCNT_RXRE
+#define USTCNT_RXHALFEN		USTCNT_RXHE
+#define USTCNT_RXFULLEN		USTCNT_RXFE
+#define USTCNT_CTSDELTAEN	USTCNT_CTSD
+#define USTCNT_ODD_EVEN		USTCNT_ODD
+#define USTCNT_PARITYEN		USTCNT_PEN
+#define USTCNT_CLKMODE		USTCNT_CLKM
+#define USTCNT_UARTEN		USTCNT_UEN
+
+/*
+ * UART Baud Control Register
+ */
+#define UBAUD_ADDR	0xfffff902
+#define UBAUD		WORD_REF(UBAUD_ADDR)
+
+#define UBAUD_PRESCALER_MASK	0x003f	/* Actual divisor is 65 - PRESCALER */
+#define UBAUD_PRESCALER_SHIFT	0
+#define UBAUD_DIVIDE_MASK	0x0700	/* Baud Rate freq. divizor */
+#define UBAUD_DIVIDE_SHIFT	8
+#define UBAUD_BAUD_SRC		0x0800	/* Baud Rate Source */
+#define UBAUD_UCLKDIR		0x2000	/* UCLK Direction */
+
+/*
+ * UART Receiver Register 
+ */
+#define URX_ADDR	0xfffff904
+#define URX		WORD_REF(URX_ADDR)
+
+#define URX_RXDATA_ADDR	0xfffff905
+#define URX_RXDATA	BYTE_REF(URX_RXDATA_ADDR)
+
+#define URX_RXDATA_MASK	 0x00ff	/* Received data */
+#define URX_RXDATA_SHIFT 0
+#define URX_PARITY_ERROR 0x0100	/* Parity Error */
+#define URX_BREAK	 0x0200	/* Break Detected */
+#define URX_FRAME_ERROR	 0x0400	/* Framing Error */
+#define URX_OVRUN	 0x0800	/* Serial Overrun */
+#define URX_OLD_DATA	 0x1000	/* Old data in FIFO */
+#define URX_DATA_READY	 0x2000	/* Data Ready (FIFO not empty) */
+#define URX_FIFO_HALF	 0x4000 /* FIFO is Half-Full */
+#define URX_FIFO_FULL	 0x8000	/* FIFO is Full */
+
+/*
+ * UART Transmitter Register 
+ */
+#define UTX_ADDR	0xfffff906
+#define UTX		WORD_REF(UTX_ADDR)
+
+#define UTX_TXDATA_ADDR	0xfffff907
+#define UTX_TXDATA	BYTE_REF(UTX_TXDATA_ADDR)
+
+#define UTX_TXDATA_MASK	 0x00ff	/* Data to be transmitted */
+#define UTX_TXDATA_SHIFT 0
+#define UTX_CTS_DELTA	 0x0100	/* CTS changed */
+#define UTX_CTS_STAT	 0x0200	/* CTS State */
+#define	UTX_BUSY	 0x0400	/* FIFO is busy, sending a character */
+#define	UTX_NOCTS	 0x0800	/* Ignore CTS */
+#define UTX_SEND_BREAK	 0x1000	/* Send a BREAK */
+#define UTX_TX_AVAIL	 0x2000	/* Transmit FIFO has a slot available */
+#define UTX_FIFO_HALF	 0x4000	/* Transmit FIFO is half empty */
+#define UTX_FIFO_EMPTY	 0x8000	/* Transmit FIFO is empty */
+
+/* '328-compatible definitions */
+#define UTX_CTS_STATUS	UTX_CTS_STAT
+#define UTX_IGNORE_CTS	UTX_NOCTS
+
+/*
+ * UART Miscellaneous Register 
+ */
+#define UMISC_ADDR	0xfffff908
+#define UMISC		WORD_REF(UMISC_ADDR)
+
+#define UMISC_TX_POL	 0x0004	/* Transmit Polarity */
+#define UMISC_RX_POL	 0x0008	/* Receive Polarity */
+#define UMISC_IRDA_LOOP	 0x0010	/* IrDA Loopback Enable */
+#define UMISC_IRDA_EN	 0x0020	/* Infra-Red Enable */
+#define UMISC_RTS	 0x0040	/* Set RTS status */
+#define UMISC_RTSCONT	 0x0080	/* Choose RTS control */
+#define UMISC_IR_TEST	 0x0400	/* IRDA Test Enable */
+#define UMISC_BAUD_RESET 0x0800	/* Reset Baud Rate Generation Counters */
+#define UMISC_LOOP	 0x1000	/* Serial Loopback Enable */
+#define UMISC_FORCE_PERR 0x2000	/* Force Parity Error */
+#define UMISC_CLKSRC	 0x4000	/* Clock Source */
+#define UMISC_BAUD_TEST	 0x8000	/* Enable Baud Test Mode */
+
+/* 
+ * UART Non-integer Prescaler Register
+ */
+#define NIPR_ADDR	0xfffff90a
+#define NIPR		WORD_REF(NIPR_ADDR)
+
+#define NIPR_STEP_VALUE_MASK	0x00ff	/* NI prescaler step value */
+#define NIPR_STEP_VALUE_SHIFT	0
+#define NIPR_SELECT_MASK	0x0700	/* Tap Selection */
+#define NIPR_SELECT_SHIFT	8
+#define NIPR_PRE_SEL		0x8000	/* Non-integer prescaler select */
+
+
+/* generalization of uart control registers to support multiple ports: */
+typedef volatile struct {
+  volatile unsigned short int ustcnt;
+  volatile unsigned short int ubaud;
+  union {
+    volatile unsigned short int w;
+    struct {
+      volatile unsigned char status;
+      volatile unsigned char rxdata;
+    } b;
+  } urx;
+  union {
+    volatile unsigned short int w;
+    struct {
+      volatile unsigned char status;
+      volatile unsigned char txdata;
+    } b;
+  } utx;
+  volatile unsigned short int umisc;
+  volatile unsigned short int nipr;
+  volatile unsigned short int pad1;
+  volatile unsigned short int pad2;
+} m68328_uart __attribute__((packed));
+
+
+/**********
+ *
+ * 0xFFFFFAxx -- LCD Controller
+ *
+ **********/
+
+/*
+ * LCD Screen Starting Address Register 
+ */
+#define LSSA_ADDR	0xfffffa00
+#define LSSA		LONG_REF(LSSA_ADDR)
+
+#define LSSA_SSA_MASK	0x1ffffffe	/* Bits 0 and 29-31 are reserved */
+
+/*
+ * LCD Virtual Page Width Register 
+ */
+#define LVPW_ADDR	0xfffffa05
+#define LVPW		BYTE_REF(LVPW_ADDR)
+
+/*
+ * LCD Screen Width Register (not compatible with '328 !!!) 
+ */
+#define LXMAX_ADDR	0xfffffa08
+#define LXMAX		WORD_REF(LXMAX_ADDR)
+
+#define LXMAX_XM_MASK	0x02f0		/* Bits 0-3 and 10-15 are reserved */
+
+/*
+ * LCD Screen Height Register
+ */
+#define LYMAX_ADDR	0xfffffa0a
+#define LYMAX		WORD_REF(LYMAX_ADDR)
+
+#define LYMAX_YM_MASK	0x01ff		/* Bits 9-15 are reserved */
+
+/*
+ * LCD Cursor X Position Register
+ */
+#define LCXP_ADDR	0xfffffa18
+#define LCXP		WORD_REF(LCXP_ADDR)
+
+#define LCXP_CC_MASK	0xc000		/* Cursor Control */
+#define   LCXP_CC_TRAMSPARENT	0x0000
+#define   LCXP_CC_BLACK		0x4000
+#define   LCXP_CC_REVERSED	0x8000
+#define   LCXP_CC_WHITE		0xc000
+#define LCXP_CXP_MASK	0x02ff		/* Cursor X position */
+
+/*
+ * LCD Cursor Y Position Register
+ */
+#define LCYP_ADDR	0xfffffa1a
+#define LCYP		WORD_REF(LCYP_ADDR)
+
+#define LCYP_CYP_MASK	0x01ff		/* Cursor Y Position */
+
+/*
+ * LCD Cursor Width and Heigth Register
+ */
+#define LCWCH_ADDR	0xfffffa1c
+#define LCWCH		WORD_REF(LCWCH_ADDR)
+
+#define LCWCH_CH_MASK	0x001f		/* Cursor Height */
+#define LCWCH_CH_SHIFT	0
+#define LCWCH_CW_MASK	0x1f00		/* Cursor Width */
+#define LCWCH_CW_SHIFT	8
+
+/*
+ * LCD Blink Control Register
+ */
+#define LBLKC_ADDR	0xfffffa1f
+#define LBLKC		BYTE_REF(LBLKC_ADDR)
+
+#define LBLKC_BD_MASK	0x7f	/* Blink Divisor */
+#define LBLKC_BD_SHIFT	0
+#define LBLKC_BKEN	0x80	/* Blink Enabled */
+
+/*
+ * LCD Panel Interface Configuration Register 
+ */
+#define LPICF_ADDR	0xfffffa20
+#define LPICF		BYTE_REF(LPICF_ADDR)
+
+#define LPICF_GS_MASK	 0x03	 /* Gray-Scale Mode */
+#define	  LPICF_GS_BW	   0x00
+#define   LPICF_GS_GRAY_4  0x01
+#define   LPICF_GS_GRAY_16 0x02
+#define LPICF_PBSIZ_MASK 0x0c	/* Panel Bus Width */
+#define   LPICF_PBSIZ_1	   0x00
+#define   LPICF_PBSIZ_2    0x04
+#define   LPICF_PBSIZ_4    0x08
+
+/*
+ * LCD Polarity Configuration Register 
+ */
+#define LPOLCF_ADDR	0xfffffa21
+#define LPOLCF		BYTE_REF(LPOLCF_ADDR)
+
+#define LPOLCF_PIXPOL	0x01	/* Pixel Polarity */
+#define LPOLCF_LPPOL	0x02	/* Line Pulse Polarity */
+#define LPOLCF_FLMPOL	0x04	/* Frame Marker Polarity */
+#define LPOLCF_LCKPOL	0x08	/* LCD Shift Lock Polarity */
+
+/*
+ * LACD (LCD Alternate Crystal Direction) Rate Control Register
+ */
+#define LACDRC_ADDR	0xfffffa23
+#define LACDRC		BYTE_REF(LACDRC_ADDR)
+
+#define LACDRC_ACDSLT	 0x80	/* Signal Source Select */
+#define LACDRC_ACD_MASK	 0x0f	/* Alternate Crystal Direction Control */
+#define LACDRC_ACD_SHIFT 0
+
+/*
+ * LCD Pixel Clock Divider Register
+ */
+#define LPXCD_ADDR	0xfffffa25
+#define LPXCD		BYTE_REF(LPXCD_ADDR)
+
+#define	LPXCD_PCD_MASK	0x3f 	/* Pixel Clock Divider */
+#define LPXCD_PCD_SHIFT	0
+
+/*
+ * LCD Clocking Control Register
+ */
+#define LCKCON_ADDR	0xfffffa27
+#define LCKCON		BYTE_REF(LCKCON_ADDR)
+
+#define LCKCON_DWS_MASK	 0x0f	/* Display Wait-State */
+#define LCKCON_DWS_SHIFT 0
+#define LCKCON_DWIDTH	 0x40	/* Display Memory Width  */
+#define LCKCON_LCDON	 0x80	/* Enable LCD Controller */
+
+/* '328-compatible definitions */
+#define LCKCON_DW_MASK  LCKCON_DWS_MASK
+#define LCKCON_DW_SHIFT LCKCON_DWS_SHIFT
+ 
+/*
+ * LCD Refresh Rate Adjustment Register 
+ */
+#define LRRA_ADDR	0xfffffa29
+#define LRRA		BYTE_REF(LRRA_ADDR)
+
+/*
+ * LCD Panning Offset Register
+ */
+#define LPOSR_ADDR	0xfffffa2d
+#define LPOSR		BYTE_REF(LPOSR_ADDR)
+
+#define LPOSR_POS_MASK	0x0f	/* Pixel Offset Code */
+#define LPOSR_POS_SHIFT	0
+
+/*
+ * LCD Frame Rate Control Modulation Register
+ */
+#define LFRCM_ADDR	0xfffffa31
+#define LFRCM		BYTE_REF(LFRCM_ADDR)
+
+#define LFRCM_YMOD_MASK	 0x0f	/* Vertical Modulation */
+#define LFRCM_YMOD_SHIFT 0
+#define LFRCM_XMOD_MASK	 0xf0	/* Horizontal Modulation */
+#define LFRCM_XMOD_SHIFT 4
+
+/*
+ * LCD Gray Palette Mapping Register
+ */
+#define LGPMR_ADDR	0xfffffa33
+#define LGPMR		BYTE_REF(LGPMR_ADDR)
+
+#define LGPMR_G1_MASK	0x0f
+#define LGPMR_G1_SHIFT	0
+#define LGPMR_G2_MASK	0xf0
+#define LGPMR_G2_SHIFT	4
+
+/* 
+ * PWM Contrast Control Register
+ */
+#define PWMR_ADDR	0xfffffa36
+#define PWMR		WORD_REF(PWMR_ADDR)
+
+#define PWMR_PW_MASK	0x00ff	/* Pulse Width */
+#define PWMR_PW_SHIFT	0
+#define PWMR_CCPEN	0x0100	/* Contrast Control Enable */
+#define PWMR_SRC_MASK	0x0600	/* Input Clock Source */
+#define   PWMR_SRC_LINE	  0x0000	/* Line Pulse  */
+#define   PWMR_SRC_PIXEL  0x0200	/* Pixel Clock */
+#define   PWMR_SRC_LCD    0x4000	/* LCD clock   */
+
+/**********
+ *
+ * 0xFFFFFBxx -- Real-Time Clock (RTC)
+ *
+ **********/
+
+/*
+ * RTC Hours Minutes and Seconds Register
+ */
+#define RTCTIME_ADDR	0xfffffb00
+#define RTCTIME		LONG_REF(RTCTIME_ADDR)
+
+#define RTCTIME_SECONDS_MASK	0x0000003f	/* Seconds */
+#define RTCTIME_SECONDS_SHIFT	0
+#define RTCTIME_MINUTES_MASK	0x003f0000	/* Minutes */
+#define RTCTIME_MINUTES_SHIFT	16
+#define RTCTIME_HOURS_MASK	0x1f000000	/* Hours */
+#define RTCTIME_HOURS_SHIFT	24
+
+/*
+ *  RTC Alarm Register 
+ */
+#define RTCALRM_ADDR    0xfffffb04
+#define RTCALRM         LONG_REF(RTCALRM_ADDR)
+
+#define RTCALRM_SECONDS_MASK    0x0000003f      /* Seconds */
+#define RTCALRM_SECONDS_SHIFT   0
+#define RTCALRM_MINUTES_MASK    0x003f0000      /* Minutes */
+#define RTCALRM_MINUTES_SHIFT   16
+#define RTCALRM_HOURS_MASK      0x1f000000      /* Hours */
+#define RTCALRM_HOURS_SHIFT     24
+
+/*
+ * Watchdog Timer Register 
+ */
+#define WATCHDOG_ADDR	0xfffffb0a
+#define WATCHDOG	WORD_REF(WATCHDOG_ADDR)
+
+#define WATCHDOG_EN	0x0001	/* Watchdog Enabled */
+#define WATCHDOG_ISEL	0x0002	/* Select the watchdog interrupt */
+#define WATCHDOG_INTF	0x0080	/* Watchdog interrupt occcured */
+#define WATCHDOG_CNT_MASK  0x0300	/* Watchdog Counter */
+#define WATCHDOG_CNT_SHIFT 8
+
+/*
+ * RTC Control Register
+ */
+#define RTCCTL_ADDR	0xfffffb0c
+#define RTCCTL		WORD_REF(RTCCTL_ADDR)
+
+#define RTCCTL_XTL	0x0020	/* Crystal Selection */
+#define RTCCTL_EN	0x0080	/* RTC Enable */
+
+/* '328-compatible definitions */
+#define RTCCTL_384	RTCCTL_XTL
+#define RTCCTL_ENABLE	RTCCTL_EN
+
+/*
+ * RTC Interrupt Status Register 
+ */
+#define RTCISR_ADDR	0xfffffb0e
+#define RTCISR		WORD_REF(RTCISR_ADDR)
+
+#define RTCISR_SW	0x0001	/* Stopwatch timed out */
+#define RTCISR_MIN	0x0002	/* 1-minute interrupt has occured */
+#define RTCISR_ALM	0x0004	/* Alarm interrupt has occured */
+#define RTCISR_DAY	0x0008	/* 24-hour rollover interrupt has occured */
+#define RTCISR_1HZ	0x0010	/* 1Hz interrupt has occured */
+#define RTCISR_HR	0x0020	/* 1-hour interrupt has occured */
+#define RTCISR_SAM0	0x0100	/*   4Hz /   4.6875Hz interrupt has occured */ 
+#define RTCISR_SAM1	0x0200	/*   8Hz /   9.3750Hz interrupt has occured */ 
+#define RTCISR_SAM2	0x0400	/*  16Hz /  18.7500Hz interrupt has occured */ 
+#define RTCISR_SAM3	0x0800	/*  32Hz /  37.5000Hz interrupt has occured */ 
+#define RTCISR_SAM4	0x1000	/*  64Hz /  75.0000Hz interrupt has occured */ 
+#define RTCISR_SAM5	0x2000	/* 128Hz / 150.0000Hz interrupt has occured */ 
+#define RTCISR_SAM6	0x4000	/* 256Hz / 300.0000Hz interrupt has occured */ 
+#define RTCISR_SAM7	0x8000	/* 512Hz / 600.0000Hz interrupt has occured */ 
+
+/*
+ * RTC Interrupt Enable Register
+ */
+#define RTCIENR_ADDR	0xfffffb10
+#define RTCIENR		WORD_REF(RTCIENR_ADDR)
+
+#define RTCIENR_SW	0x0001	/* Stopwatch interrupt enable */
+#define RTCIENR_MIN	0x0002	/* 1-minute interrupt enable */
+#define RTCIENR_ALM	0x0004	/* Alarm interrupt enable */
+#define RTCIENR_DAY	0x0008	/* 24-hour rollover interrupt enable */
+#define RTCIENR_1HZ	0x0010	/* 1Hz interrupt enable */
+#define RTCIENR_HR	0x0020	/* 1-hour interrupt enable */
+#define RTCIENR_SAM0	0x0100	/*   4Hz /   4.6875Hz interrupt enable */ 
+#define RTCIENR_SAM1	0x0200	/*   8Hz /   9.3750Hz interrupt enable */ 
+#define RTCIENR_SAM2	0x0400	/*  16Hz /  18.7500Hz interrupt enable */ 
+#define RTCIENR_SAM3	0x0800	/*  32Hz /  37.5000Hz interrupt enable */ 
+#define RTCIENR_SAM4	0x1000	/*  64Hz /  75.0000Hz interrupt enable */ 
+#define RTCIENR_SAM5	0x2000	/* 128Hz / 150.0000Hz interrupt enable */ 
+#define RTCIENR_SAM6	0x4000	/* 256Hz / 300.0000Hz interrupt enable */ 
+#define RTCIENR_SAM7	0x8000	/* 512Hz / 600.0000Hz interrupt enable */ 
+
+/* 
+ * Stopwatch Minutes Register
+ */
+#define STPWCH_ADDR	0xfffffb12
+#define STPWCH		WORD_REF(STPWCH)
+
+#define STPWCH_CNT_MASK	 0x003f	/* Stopwatch countdown value */
+#define SPTWCH_CNT_SHIFT 0
+
+/*
+ * RTC Day Count Register 
+ */
+#define DAYR_ADDR	0xfffffb1a
+#define DAYR		WORD_REF(DAYR_ADDR)
+
+#define DAYR_DAYS_MASK	0x1ff	/* Day Setting */
+#define DAYR_DAYS_SHIFT 0
+
+/*
+ * RTC Day Alarm Register 
+ */
+#define DAYALARM_ADDR	0xfffffb1c
+#define DAYALARM	WORD_REF(DAYALARM_ADDR)
+
+#define DAYALARM_DAYSAL_MASK	0x01ff	/* Day Setting of the Alarm */
+#define DAYALARM_DAYSAL_SHIFT 	0
+
+/**********
+ *
+ * 0xFFFFFCxx -- DRAM Controller
+ *
+ **********/
+
+/*
+ * DRAM Memory Configuration Register 
+ */
+#define DRAMMC_ADDR	0xfffffc00
+#define DRAMMC		WORD_REF(DRAMMC_ADDR)
+
+#define DRAMMC_ROW12_MASK	0xc000	/* Row address bit for MD12 */
+#define   DRAMMC_ROW12_PA10	0x0000
+#define   DRAMMC_ROW12_PA21	0x4000	
+#define   DRAMMC_ROW12_PA23	0x8000
+#define	DRAMMC_ROW0_MASK	0x3000	/* Row address bit for MD0 */
+#define	  DRAMMC_ROW0_PA11	0x0000
+#define   DRAMMC_ROW0_PA22	0x1000
+#define   DRAMMC_ROW0_PA23	0x2000
+#define DRAMMC_ROW11		0x0800	/* Row address bit for MD11 PA20/PA22 */
+#define DRAMMC_ROW10		0x0400	/* Row address bit for MD10 PA19/PA21 */
+#define	DRAMMC_ROW9		0x0200	/* Row address bit for MD9  PA9/PA19  */
+#define DRAMMC_ROW8		0x0100	/* Row address bit for MD8  PA10/PA20 */
+#define DRAMMC_COL10		0x0080	/* Col address bit for MD10 PA11/PA0  */
+#define DRAMMC_COL9		0x0040	/* Col address bit for MD9  PA10/PA0  */
+#define DRAMMC_COL8		0x0020	/* Col address bit for MD8  PA9/PA0   */
+#define DRAMMC_REF_MASK		0x001f	/* Reresh Cycle */
+#define DRAMMC_REF_SHIFT	0
+
+/*
+ * DRAM Control Register
+ */
+#define DRAMC_ADDR	0xfffffc02
+#define DRAMC		WORD_REF(DRAMC_ADDR)
+
+#define DRAMC_DWE	   0x0001	/* DRAM Write Enable */
+#define DRAMC_RST	   0x0002	/* Reset Burst Refresh Enable */
+#define DRAMC_LPR	   0x0004	/* Low-Power Refresh Enable */
+#define DRAMC_SLW	   0x0008	/* Slow RAM */
+#define DRAMC_LSP	   0x0010	/* Light Sleep */
+#define DRAMC_MSW	   0x0020	/* Slow Multiplexing */
+#define DRAMC_WS_MASK	   0x00c0	/* Wait-states */
+#define DRAMC_WS_SHIFT	   6
+#define DRAMC_PGSZ_MASK    0x0300	/* Page Size for fast page mode */
+#define DRAMC_PGSZ_SHIFT   8
+#define   DRAMC_PGSZ_256K  0x0000	
+#define   DRAMC_PGSZ_512K  0x0100
+#define   DRAMC_PGSZ_1024K 0x0200
+#define	  DRAMC_PGSZ_2048K 0x0300
+#define DRAMC_EDO	   0x0400	/* EDO DRAM */
+#define DRAMC_CLK	   0x0800	/* Refresh Timer Clock source select */
+#define DRAMC_BC_MASK	   0x3000	/* Page Access Clock Cycle (FP mode) */
+#define DRAMC_BC_SHIFT	   12
+#define DRAMC_RM	   0x4000	/* Refresh Mode */
+#define DRAMC_EN	   0x8000	/* DRAM Controller enable */
+
+
+/**********
+ *
+ * 0xFFFFFDxx -- In-Circuit Emulation (ICE)
+ *
+ **********/
+
+/*
+ * ICE Module Address Compare Register
+ */
+#define ICEMACR_ADDR	0xfffffd00
+#define ICEMACR		LONG_REF(ICEMACR_ADDR)
+
+/*
+ * ICE Module Address Mask Register
+ */
+#define ICEMAMR_ADDR	0xfffffd04
+#define ICEMAMR		LONG_REF(ICEMAMR_ADDR)
+
+/*
+ * ICE Module Control Compare Register
+ */
+#define ICEMCCR_ADDR	0xfffffd08
+#define ICEMCCR		WORD_REF(ICEMCCR_ADDR)
+
+#define ICEMCCR_PD	0x0001	/* Program/Data Cycle Selection */
+#define ICEMCCR_RW	0x0002	/* Read/Write Cycle Selection */
+
+/*
+ * ICE Module Control Mask Register
+ */
+#define ICEMCMR_ADDR	0xfffffd0a
+#define ICEMCMR		WORD_REF(ICEMCMR_ADDR)
+
+#define ICEMCMR_PDM	0x0001	/* Program/Data Cycle Mask */
+#define ICEMCMR_RWM	0x0002	/* Read/Write Cycle Mask */
+
+/*
+ * ICE Module Control Register 
+ */
+#define ICEMCR_ADDR	0xfffffd0c
+#define ICEMCR		WORD_REF(ICEMCR_ADDR)
+
+#define ICEMCR_CEN	0x0001	/* Compare Enable */
+#define ICEMCR_PBEN	0x0002	/* Program Break Enable */
+#define ICEMCR_SB	0x0004	/* Single Breakpoint */
+#define ICEMCR_HMDIS	0x0008	/* HardMap disable */
+#define ICEMCR_BBIEN	0x0010	/* Bus Break Interrupt Enable */
+
+/*
+ * ICE Module Status Register 
+ */
+#define ICEMSR_ADDR	0xfffffd0e
+#define ICEMSR		WORD_REF(ICEMSR_ADDR)
+
+#define ICEMSR_EMUEN	0x0001	/* Emulation Enable */
+#define ICEMSR_BRKIRQ	0x0002	/* A-Line Vector Fetch Detected */
+#define ICEMSR_BBIRQ	0x0004	/* Bus Break Interrupt Detected */
+#define ICEMSR_EMIRQ	0x0008	/* EMUIRQ Falling Edge Detected */
+
+#endif /* _MC68EZ328_H_ */
diff -urN linux-2.4.29/include/asm-m68knommu/MC68VZ328.h linux-2.4.29-uc1/include/asm-m68knommu/MC68VZ328.h
--- linux-2.4.29/include/asm-m68knommu/MC68VZ328.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/MC68VZ328.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,1350 @@
+
+/* include/asm-m68knommu/MC68VZ328.h: 'VZ328 control registers
+ *
+ * Copyright (c) 2000-2001	Lineo Inc. <www.lineo.com>
+ * Copyright (c) 2000-2001	Lineo Canada Corp. <www.lineo.ca>
+ * Copyright (C) 1999		Vladimir Gurevich <vgurevic@cisco.com>
+ * 				Bare & Hare Software, Inc.
+ * Based on include/asm-m68knommu/MC68332.h
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *                     The Silver Hammer Group, Ltd.
+ *
+ * M68VZ328 fixes by Evan Stawnyczy <evan@lineo.com>
+ * vz multiport fixes by Michael Leslie <mleslie@ArcturusNetworks.com>
+ */
+
+#ifndef _MC68VZ328_H_
+#define _MC68VZ328_H_
+
+#define BYTE_REF(addr) (*((volatile unsigned char*)addr))
+#define WORD_REF(addr) (*((volatile unsigned short*)addr))
+#define LONG_REF(addr) (*((volatile unsigned long*)addr))
+
+#define PUT_FIELD(field, val) (((val) << field##_SHIFT) & field##_MASK)
+#define GET_FIELD(reg, field) (((reg) & field##_MASK) >> field##_SHIFT)
+
+/********** 
+ *
+ * 0xFFFFF0xx -- System Control
+ *
+ **********/
+ 
+/*
+ * System Control Register (SCR)
+ */
+#define SCR_ADDR	0xfffff000
+#define SCR		BYTE_REF(SCR_ADDR)
+
+#define SCR_WDTH8	0x01	/* 8-Bit Width Select */
+#define SCR_DMAP	0x04	/* Double Map */
+#define SCR_SO		0x08	/* Supervisor Only */
+#define SCR_BETEN	0x10	/* Bus-Error Time-Out Enable */
+#define SCR_PRV		0x20	/* Privilege Violation */
+#define SCR_WPV		0x40	/* Write Protect Violation */
+#define SCR_BETO	0x80	/* Bus-Error TimeOut */
+
+/*
+ * Silicon ID Register (Mask Revision Register (MRR) for '328 Compatibility)
+ */
+#define MRR_ADDR 0xfffff004
+#define MRR	 LONG_REF(MRR_ADDR)
+
+/********** 
+ *
+ * 0xFFFFF1xx -- Chip-Select logic
+ *
+ **********/
+ 
+/*
+ * Chip Select Group Base Registers 
+ */
+#define CSGBA_ADDR	0xfffff100
+#define CSGBB_ADDR	0xfffff102
+
+#define CSGBC_ADDR	0xfffff104
+#define CSGBD_ADDR	0xfffff106
+
+#define CSGBA		WORD_REF(CSGBA_ADDR)
+#define CSGBB		WORD_REF(CSGBB_ADDR)
+#define CSGBC		WORD_REF(CSGBC_ADDR)
+#define CSGBD		WORD_REF(CSGBD_ADDR)
+
+/*
+ * Chip Select Registers 
+ */
+#define CSA_ADDR	0xfffff110
+#define CSB_ADDR	0xfffff112
+#define CSC_ADDR	0xfffff114
+#define CSD_ADDR	0xfffff116
+
+#define CSA		WORD_REF(CSA_ADDR)
+#define CSB		WORD_REF(CSB_ADDR)
+#define CSC		WORD_REF(CSC_ADDR)
+#define CSD		WORD_REF(CSD_ADDR)
+
+#define CSA_EN		0x0001		/* Chip-Select Enable */
+#define CSA_SIZ_MASK	0x000e		/* Chip-Select Size */
+#define CSA_SIZ_SHIFT   1
+#define CSA_WS_MASK	0x0070		/* Wait State */
+#define CSA_WS_SHIFT    4
+#define CSA_BSW		0x0080		/* Data Bus Width */
+#define CSA_FLASH	0x0100		/* FLASH Memory Support */
+#define CSA_RO		0x8000		/* Read-Only */
+
+#define CSB_EN		0x0001		/* Chip-Select Enable */
+#define CSB_SIZ_MASK	0x000e		/* Chip-Select Size */
+#define CSB_SIZ_SHIFT   1
+#define CSB_WS_MASK	0x0070		/* Wait State */
+#define CSB_WS_SHIFT    4
+#define CSB_BSW		0x0080		/* Data Bus Width */
+#define CSB_FLASH	0x0100		/* FLASH Memory Support */
+#define CSB_UPSIZ_MASK	0x1800		/* Unprotected memory block size */
+#define CSB_UPSIZ_SHIFT 11
+#define CSB_ROP		0x2000		/* Readonly if protected */
+#define CSB_SOP		0x4000		/* Supervisor only if protected */
+#define CSB_RO		0x8000		/* Read-Only */
+
+#define CSC_EN		0x0001		/* Chip-Select Enable */
+#define CSC_SIZ_MASK	0x000e		/* Chip-Select Size */
+#define CSC_SIZ_SHIFT   1
+#define CSC_WS_MASK	0x0070		/* Wait State */
+#define CSC_WS_SHIFT    4
+#define CSC_BSW		0x0080		/* Data Bus Width */
+#define CSC_FLASH	0x0100		/* FLASH Memory Support */
+#define CSC_UPSIZ_MASK	0x1800		/* Unprotected memory block size */
+#define CSC_UPSIZ_SHIFT 11
+#define CSC_ROP		0x2000		/* Readonly if protected */
+#define CSC_SOP		0x4000		/* Supervisor only if protected */
+#define CSC_RO		0x8000		/* Read-Only */
+
+#define CSD_EN		0x0001		/* Chip-Select Enable */
+#define CSD_SIZ_MASK	0x000e		/* Chip-Select Size */
+#define CSD_SIZ_SHIFT   1
+#define CSD_WS_MASK	0x0070		/* Wait State */
+#define CSD_WS_SHIFT    4
+#define CSD_BSW		0x0080		/* Data Bus Width */
+#define CSD_FLASH	0x0100		/* FLASH Memory Support */
+#define CSD_DRAM	0x0200		/* Dram Selection */
+#define	CSD_COMB	0x0400		/* Combining */
+#define CSD_UPSIZ_MASK	0x1800		/* Unprotected memory block size */
+#define CSD_UPSIZ_SHIFT 11
+#define CSD_ROP		0x2000		/* Readonly if protected */
+#define CSD_SOP		0x4000		/* Supervisor only if protected */
+#define CSD_RO		0x8000		/* Read-Only */
+
+/*
+ * Emulation Chip-Select Register 
+ */
+#define EMUCS_ADDR	0xfffff118
+#define EMUCS		WORD_REF(EMUCS_ADDR)
+
+#define EMUCS_WS_MASK	0x0070
+#define EMUCS_WS_SHIFT	4
+
+/********** 
+ *
+ * 0xFFFFF2xx -- Phase Locked Loop (PLL) & Power Control
+ *
+ **********/
+
+/*
+ * PLL Control Register 
+ */
+#define PLLCR_ADDR	0xfffff200
+#define PLLCR		WORD_REF(PLLCR_ADDR)
+
+#define PLLCR_DISPLL	       0x0008	/* Disable PLL */
+#define PLLCR_CLKEN	       0x0010	/* Clock (CLKO pin) enable */
+#define PLLCR_PRESC1	       0x0080	/* prescaler 1 */
+#define PLLCR_PRESC2	       0x0020	/* VCO prescaler */
+#define PLLCR_SYSCLK_SEL_MASK  0x0700	/* System Clock Selection */
+#define PLLCR_SYSCLK_SEL_SHIFT 8
+#define PLLCR_LCDCLK_SEL_MASK  0x3800	/* LCD Clock Selection */
+#define PLLCR_LCDCLK_SEL_SHIFT 11
+
+/* '328-compatible definitions */
+#define PLLCR_PIXCLK_SEL_MASK	PLLCR_LCDCLK_SEL_MASK
+#define PLLCR_PIXCLK_SEL_SHIFT	PLLCR_LCDCLK_SEL_SHIFT
+
+/*
+ * PLL Frequency Select Register
+ */
+#define PLLFSR_ADDR	0xfffff202
+#define PLLFSR		WORD_REF(PLLFSR_ADDR)
+
+#define PLLFSR_PC_MASK	0x00ff		/* P Count */
+#define PLLFSR_PC_SHIFT 0
+#define PLLFSR_QC_MASK	0x0f00		/* Q Count */
+#define PLLFSR_QC_SHIFT 8
+#define PLLFSR_PROT	0x4000		/* Protect P & Q */
+#define PLLFSR_CLK32	0x8000		/* Clock 32 (kHz) */
+
+/*
+ * Power Control Register
+ */
+#define PCTRL_ADDR	0xfffff207
+#define PCTRL		BYTE_REF(PCTRL_ADDR)
+
+#define PCTRL_WIDTH_MASK	0x1f	/* CPU Clock bursts width */
+#define PCTRL_WIDTH_SHIFT	0
+#define PCTRL_PCEN		0x80	/* Power Control Enable */
+
+/**********
+ *
+ * 0xFFFFF3xx -- Interrupt Controller
+ *
+ **********/
+
+/* 
+ * Interrupt Vector Register
+ */
+#define IVR_ADDR	0xfffff300
+#define IVR		BYTE_REF(IVR_ADDR)
+
+#define IVR_VECTOR_MASK 0xF8
+
+/*
+ * Interrupt control Register
+ */
+#define ICR_ADDR	0xfffff302
+#define ICR		WORD_REF(ICR_ADDR)
+
+#define ICR_POL5	0x0080	/* Polarity Control for IRQ5 */
+#define ICR_ET6		0x0100	/* Edge Trigger Select for IRQ6 */
+#define ICR_ET3		0x0200	/* Edge Trigger Select for IRQ3 */
+#define ICR_ET2		0x0400	/* Edge Trigger Select for IRQ2 */
+#define ICR_ET1		0x0800	/* Edge Trigger Select for IRQ1 */
+#define ICR_POL6	0x1000	/* Polarity Control for IRQ6 */
+#define ICR_POL3	0x2000	/* Polarity Control for IRQ3 */
+#define ICR_POL2	0x4000	/* Polarity Control for IRQ2 */
+#define ICR_POL1	0x8000	/* Polarity Control for IRQ1 */
+
+/*
+ * Interrupt Mask Register
+ */
+#define IMR_ADDR	0xfffff304
+#define IMR		LONG_REF(IMR_ADDR)
+
+/*
+ * Define the names for bit positions first. This is useful for 
+ * request_irq
+ */
+#define SPI2_IRQ_NUM	0	/* SPI 2 interrupt */
+#define TMR_IRQ_NUM	1	/* Timer 1 interrupt */
+#define UART1_IRQ_NUM	2	/* UART 1 interrupt */	
+#define	WDT_IRQ_NUM	3	/* Watchdog Timer interrupt */
+#define RTC_IRQ_NUM	4	/* RTC interrupt */
+#define TMR2_IRQ_NUM	5	/* Timer 2 interrupt */
+#define	KB_IRQ_NUM	6	/* Keyboard Interrupt */
+#define PWM1_IRQ_NUM	7	/* Pulse-Width Modulator 1 int. */
+#define	INT0_IRQ_NUM	8	/* External INT0 */
+#define	INT1_IRQ_NUM	9	/* External INT1 */
+#define	INT2_IRQ_NUM	10	/* External INT2 */
+#define	INT3_IRQ_NUM	11	/* External INT3 */
+#define UART2_IRQ_NUM	12	/* UART 2 interrupt */	
+#define PWM2_IRQ_NUM	13	/* Pulse-Width Modulator 1 int. */
+#define IRQ1_IRQ_NUM	16	/* IRQ1 */
+#define IRQ2_IRQ_NUM	17	/* IRQ2 */
+#define IRQ3_IRQ_NUM	18	/* IRQ3 */
+#define IRQ6_IRQ_NUM	19	/* IRQ6 */
+#define IRQ5_IRQ_NUM	20	/* IRQ5 */
+#define SPI1_IRQ_NUM	21	/* SPI 1 interrupt */
+#define SAM_IRQ_NUM	22	/* Sampling Timer for RTC */
+#define EMIQ_IRQ_NUM	23	/* Emulator Interrupt */
+
+#define SPI_IRQ_NUM	SPI2_IRQ_NUM
+
+/* '328-compatible definitions */
+#define SPIM_IRQ_NUM	SPI_IRQ_NUM
+#define TMR1_IRQ_NUM	TMR_IRQ_NUM
+#define UART_IRQ_NUM	UART1_IRQ_NUM
+
+/* 
+ * Here go the bitmasks themselves
+ */
+#define IMR_MSPI 	(1 << SPI_IRQ_NUM)	/* Mask SPI interrupt */
+#define	IMR_MTMR	(1 << TMR_IRQ_NUM)	/* Mask Timer interrupt */
+#define IMR_MUART	(1 << UART_IRQ_NUM)	/* Mask UART interrupt */	
+#define	IMR_MWDT	(1 << WDT_IRQ_NUM)	/* Mask Watchdog Timer interrupt */
+#define IMR_MRTC	(1 << RTC_IRQ_NUM)	/* Mask RTC interrupt */
+#define	IMR_MKB		(1 << KB_IRQ_NUM)	/* Mask Keyboard Interrupt */
+#define IMR_MPWM	(1 << PWM_IRQ_NUM)	/* Mask Pulse-Width Modulator int. */
+#define	IMR_MINT0	(1 << INT0_IRQ_NUM)	/* Mask External INT0 */
+#define	IMR_MINT1	(1 << INT1_IRQ_NUM)	/* Mask External INT1 */
+#define	IMR_MINT2	(1 << INT2_IRQ_NUM)	/* Mask External INT2 */
+#define	IMR_MINT3	(1 << INT3_IRQ_NUM)	/* Mask External INT3 */
+#define IMR_MIRQ1	(1 << IRQ1_IRQ_NUM)	/* Mask IRQ1 */
+#define IMR_MIRQ2	(1 << IRQ2_IRQ_NUM)	/* Mask IRQ2 */
+#define IMR_MIRQ3	(1 << IRQ3_IRQ_NUM)	/* Mask IRQ3 */
+#define IMR_MIRQ6	(1 << IRQ6_IRQ_NUM)	/* Mask IRQ6 */
+#define IMR_MIRQ5	(1 << IRQ5_IRQ_NUM)	/* Mask IRQ5 */
+#define IMR_MSAM	(1 << SAM_IRQ_NUM)	/* Mask Sampling Timer for RTC */
+#define IMR_MEMIQ	(1 << EMIQ_IRQ_NUM)	/* Mask Emulator Interrupt */
+
+/* '328-compatible definitions */
+#define IMR_MSPIM	IMR_MSPI
+#define IMR_MTMR1	IMR_MTMR
+
+/* 
+ * Interrupt Status Register 
+ */
+#define ISR_ADDR	0xfffff30c
+#define ISR		LONG_REF(ISR_ADDR)
+
+#define ISR_SPI 	(1 << SPI_IRQ_NUM)	/* SPI interrupt */
+#define	ISR_TMR		(1 << TMR_IRQ_NUM)	/* Timer interrupt */
+#define ISR_UART	(1 << UART_IRQ_NUM)	/* UART interrupt */	
+#define	ISR_WDT		(1 << WDT_IRQ_NUM)	/* Watchdog Timer interrupt */
+#define ISR_RTC		(1 << RTC_IRQ_NUM)	/* RTC interrupt */
+#define	ISR_KB		(1 << KB_IRQ_NUM)	/* Keyboard Interrupt */
+#define ISR_PWM		(1 << PWM_IRQ_NUM)	/* Pulse-Width Modulator interrupt */
+#define	ISR_INT0	(1 << INT0_IRQ_NUM)	/* External INT0 */
+#define	ISR_INT1	(1 << INT1_IRQ_NUM)	/* External INT1 */
+#define	ISR_INT2	(1 << INT2_IRQ_NUM)	/* External INT2 */
+#define	ISR_INT3	(1 << INT3_IRQ_NUM)	/* External INT3 */
+#define ISR_IRQ1	(1 << IRQ1_IRQ_NUM)	/* IRQ1 */
+#define ISR_IRQ2	(1 << IRQ2_IRQ_NUM)	/* IRQ2 */
+#define ISR_IRQ3	(1 << IRQ3_IRQ_NUM)	/* IRQ3 */
+#define ISR_IRQ6	(1 << IRQ6_IRQ_NUM)	/* IRQ6 */
+#define ISR_IRQ5	(1 << IRQ5_IRQ_NUM)	/* IRQ5 */
+#define ISR_SAM		(1 << SAM_IRQ_NUM)	/* Sampling Timer for RTC */
+#define ISR_EMIQ	(1 << EMIQ_IRQ_NUM)	/* Emulator Interrupt */
+
+/* '328-compatible definitions */
+#define ISR_SPIM	ISR_SPI
+#define ISR_TMR1	ISR_TMR
+
+/* 
+ * Interrupt Pending Register 
+ */
+#define IPR_ADDR	0xfffff30c
+#define IPR		LONG_REF(IPR_ADDR)
+
+#define IPR_SPI 	(1 << SPI_IRQ_NUM)	/* SPI interrupt */
+#define	IPR_TMR		(1 << TMR_IRQ_NUM)	/* Timer interrupt */
+#define IPR_UART	(1 << UART_IRQ_NUM)	/* UART interrupt */	
+#define	IPR_WDT		(1 << WDT_IRQ_NUM)	/* Watchdog Timer interrupt */
+#define IPR_RTC		(1 << RTC_IRQ_NUM)	/* RTC interrupt */
+#define	IPR_KB		(1 << KB_IRQ_NUM)	/* Keyboard Interrupt */
+#define IPR_PWM		(1 << PWM_IRQ_NUM)	/* Pulse-Width Modulator interrupt */
+#define	IPR_INT0	(1 << INT0_IRQ_NUM)	/* External INT0 */
+#define	IPR_INT1	(1 << INT1_IRQ_NUM)	/* External INT1 */
+#define	IPR_INT2	(1 << INT2_IRQ_NUM)	/* External INT2 */
+#define	IPR_INT3	(1 << INT3_IRQ_NUM)	/* External INT3 */
+#define IPR_IRQ1	(1 << IRQ1_IRQ_NUM)	/* IRQ1 */
+#define IPR_IRQ2	(1 << IRQ2_IRQ_NUM)	/* IRQ2 */
+#define IPR_IRQ3	(1 << IRQ3_IRQ_NUM)	/* IRQ3 */
+#define IPR_IRQ6	(1 << IRQ6_IRQ_NUM)	/* IRQ6 */
+#define IPR_IRQ5	(1 << IRQ5_IRQ_NUM)	/* IRQ5 */
+#define IPR_SAM		(1 << SAM_IRQ_NUM)	/* Sampling Timer for RTC */
+#define IPR_EMIQ	(1 << EMIQ_IRQ_NUM)	/* Emulator Interrupt */
+
+/* '328-compatible definitions */
+#define IPR_SPIM	IPR_SPI
+#define IPR_TMR1	IPR_TMR
+
+/**********
+ *
+ * 0xFFFFF4xx -- Parallel Ports
+ *
+ **********/
+
+/*
+ * Port A
+ */
+#define PADIR_ADDR	0xfffff400		/* Port A direction reg */
+#define PADATA_ADDR	0xfffff401		/* Port A data register */
+#define PAPUEN_ADDR	0xfffff402		/* Port A Pull-Up enable reg */
+
+#define PADIR		BYTE_REF(PADIR_ADDR)
+#define PADATA		BYTE_REF(PADATA_ADDR)
+#define PAPUEN		BYTE_REF(PAPUEN_ADDR)
+
+#define PA(x)		(1 << (x))
+
+/* 
+ * Port B
+ */
+#define PBDIR_ADDR	0xfffff408		/* Port B direction reg */
+#define PBDATA_ADDR	0xfffff409		/* Port B data register */
+#define PBPUEN_ADDR	0xfffff40a		/* Port B Pull-Up enable reg */
+#define PBSEL_ADDR	0xfffff40b		/* Port B Select Register */
+
+#define PBDIR		BYTE_REF(PBDIR_ADDR)
+#define PBDATA		BYTE_REF(PBDATA_ADDR)
+#define PBPUEN		BYTE_REF(PBPUEN_ADDR)
+#define PBSEL		BYTE_REF(PBSEL_ADDR)
+
+#define PB(x)		(1 << (x))
+
+#define PB_CSB0		0x01	/* Use CSB0      as PB[0] */
+#define PB_CSB1		0x02	/* Use CSB1      as PB[1] */
+#define PB_CSC0_RAS0	0x04    /* Use CSC0/RAS0 as PB[2] */	
+#define PB_CSC1_RAS1	0x08    /* Use CSC1/RAS1 as PB[3] */	
+#define PB_CSD0_CAS0	0x10    /* Use CSD0/CAS0 as PB[4] */	
+#define PB_CSD1_CAS1	0x20    /* Use CSD1/CAS1 as PB[5] */
+#define PB_TIN_TOUT	0x40	/* Use TIN/TOUT  as PB[6] */
+#define PB_PWMO		0x80	/* Use PWMO      as PB[7] */
+
+/* 
+ * Port C
+ */
+#define PCDIR_ADDR	0xfffff410		/* Port C direction reg */
+#define PCDATA_ADDR	0xfffff411		/* Port C data register */
+#define PCPDEN_ADDR	0xfffff412		/* Port C Pull-Down enb. reg */
+#define PCSEL_ADDR	0xfffff413		/* Port C Select Register */
+
+#define PCDIR		BYTE_REF(PCDIR_ADDR)
+#define PCDATA		BYTE_REF(PCDATA_ADDR)
+#define PCPDEN		BYTE_REF(PCPDEN_ADDR)
+#define PCSEL		BYTE_REF(PCSEL_ADDR)
+
+#define PC(x)		(1 << (x))
+
+#define PC_LD0		0x01	/* Use LD0  as PC[0] */
+#define PC_LD1		0x02	/* Use LD1  as PC[1] */
+#define PC_LD2		0x04	/* Use LD2  as PC[2] */
+#define PC_LD3		0x08	/* Use LD3  as PC[3] */
+#define PC_LFLM		0x10	/* Use LFLM as PC[4] */
+#define PC_LLP 		0x20	/* Use LLP  as PC[5] */
+#define PC_LCLK		0x40	/* Use LCLK as PC[6] */
+#define PC_LACD		0x80	/* Use LACD as PC[7] */
+
+/* 
+ * Port D
+ */
+#define PDDIR_ADDR	0xfffff418		/* Port D direction reg */
+#define PDDATA_ADDR	0xfffff419		/* Port D data register */
+#define PDPUEN_ADDR	0xfffff41a		/* Port D Pull-Up enable reg */
+#define PDSEL_ADDR	0xfffff41b		/* Port D Select Register */
+#define PDPOL_ADDR	0xfffff41c		/* Port D Polarity Register */
+#define PDIRQEN_ADDR	0xfffff41d		/* Port D IRQ enable register */
+#define PDKBEN_ADDR	0xfffff41e		/* Port D Keyboard Enable reg */
+#define	PDIQEG_ADDR	0xfffff41f		/* Port D IRQ Edge Register */
+
+#define PDDIR		BYTE_REF(PDDIR_ADDR)
+#define PDDATA		BYTE_REF(PDDATA_ADDR)
+#define PDPUEN		BYTE_REF(PDPUEN_ADDR)
+#define PDSEL		BYTE_REF(PDSEL_ADDR)
+#define	PDPOL		BYTE_REF(PDPOL_ADDR)
+#define PDIRQEN		BYTE_REF(PDIRQEN_ADDR)
+#define PDKBEN		BYTE_REF(PDKBEN_ADDR)
+#define PDIQEG		BYTE_REF(PDIQEG_ADDR)
+
+#define PD(x)		(1 << (x))
+
+#define PD_INT0		0x01	/* Use INT0 as PD[0] */
+#define PD_INT1		0x02	/* Use INT1 as PD[1] */
+#define PD_INT2		0x04	/* Use INT2 as PD[2] */
+#define PD_INT3		0x08	/* Use INT3 as PD[3] */
+#define PD_IRQ1		0x10	/* Use IRQ1 as PD[4] */
+#define PD_IRQ2		0x20	/* Use IRQ2 as PD[5] */
+#define PD_IRQ3		0x40	/* Use IRQ3 as PD[6] */
+#define PD_IRQ6		0x80	/* Use IRQ6 as PD[7] */
+
+/* 
+ * Port E
+ */
+#define PEDIR_ADDR	0xfffff420		/* Port E direction reg */
+#define PEDATA_ADDR	0xfffff421		/* Port E data register */
+#define PEPUEN_ADDR	0xfffff422		/* Port E Pull-Up enable reg */
+#define PESEL_ADDR	0xfffff423		/* Port E Select Register */
+
+#define PEDIR		BYTE_REF(PEDIR_ADDR)
+#define PEDATA		BYTE_REF(PEDATA_ADDR)
+#define PEPUEN		BYTE_REF(PEPUEN_ADDR)
+#define PESEL		BYTE_REF(PESEL_ADDR)
+
+#define PE(x)		(1 << (x))
+
+#define PE_SPMTXD	0x01	/* Use SPMTXD as PE[0] */
+#define PE_SPMRXD	0x02	/* Use SPMRXD as PE[1] */
+#define PE_SPMCLK	0x04	/* Use SPMCLK as PE[2] */
+#define PE_DWE		0x08	/* Use DWE    as PE[3] */
+#define PE_RXD		0x10	/* Use RXD    as PE[4] */
+#define PE_TXD		0x20	/* Use TXD    as PE[5] */
+#define PE_RTS		0x40	/* Use RTS    as PE[6] */
+#define PE_CTS		0x80	/* Use CTS    as PE[7] */
+
+/* 
+ * Port F
+ */
+#define PFDIR_ADDR	0xfffff428		/* Port F direction reg */
+#define PFDATA_ADDR	0xfffff429		/* Port F data register */
+#define PFPUEN_ADDR	0xfffff42a		/* Port F Pull-Up enable reg */
+#define PFSEL_ADDR	0xfffff42b		/* Port F Select Register */
+
+#define PFDIR		BYTE_REF(PFDIR_ADDR)
+#define PFDATA		BYTE_REF(PFDATA_ADDR)
+#define PFPUEN		BYTE_REF(PFPUEN_ADDR)
+#define PFSEL		BYTE_REF(PFSEL_ADDR)
+
+#define PF(x)		(1 << (x))
+
+#define PF_LCONTRAST	0x01	/* Use LCONTRAST as PF[0] */
+#define PF_IRQ5         0x02    /* Use IRQ5      as PF[1] */
+#define PF_CLKO         0x04    /* Use CLKO      as PF[2] */
+#define PF_A20          0x08    /* Use A20       as PF[3] */
+#define PF_A21          0x10    /* Use A21       as PF[4] */
+#define PF_A22          0x20    /* Use A22       as PF[5] */
+#define PF_A23          0x40    /* Use A23       as PF[6] */
+#define PF_CSA1		0x80    /* Use CSA1      as PF[7] */
+
+/* 
+ * Port G
+ */
+#define PGDIR_ADDR	0xfffff430		/* Port G direction reg */
+#define PGDATA_ADDR	0xfffff431		/* Port G data register */
+#define PGPUEN_ADDR	0xfffff432		/* Port G Pull-Up enable reg */
+#define PGSEL_ADDR	0xfffff433		/* Port G Select Register */
+
+#define PGDIR		BYTE_REF(PGDIR_ADDR)
+#define PGDATA		BYTE_REF(PGDATA_ADDR)
+#define PGPUEN		BYTE_REF(PGPUEN_ADDR)
+#define PGSEL		BYTE_REF(PGSEL_ADDR)
+
+#define PG(x)		(1 << (x))
+
+#define PG_BUSW_DTACK	0x01	/* Use BUSW/DTACK as PG[0] */
+#define PG_A0		0x02	/* Use A0         as PG[1] */
+#define PG_EMUIRQ	0x04	/* Use EMUIRQ     as PG[2] */
+#define PG_HIZ_P_D	0x08	/* Use HIZ/P/D    as PG[3] */
+#define PG_EMUCS        0x10	/* Use EMUCS      as PG[4] */
+#define PG_EMUBRK	0x20	/* Use EMUBRK     as PG[5] */
+
+/* 
+ * Port J
+ */
+#define PJDIR_ADDR	0xfffff438		/* Port J direction reg */
+#define PJDATA_ADDR	0xfffff439		/* Port J data register */
+#define PJPUEN_ADDR	0xfffff43A		/* Port J Pull-Up enb. reg */
+#define PJSEL_ADDR	0xfffff43B		/* Port J Select Register */
+
+#define PJDIR		BYTE_REF(PJDIR_ADDR)
+#define PJDATA		BYTE_REF(PJDATA_ADDR)
+#define PJPUEN		BYTE_REF(PJPUEN_ADDR)
+#define PJSEL		BYTE_REF(PJSEL_ADDR)
+
+#define PJ(x)		(1 << (x))
+
+/*
+ * Port K
+ */
+#define PKDIR_ADDR	0xfffff440		/* Port K direction reg */
+#define PKDATA_ADDR	0xfffff441		/* Port K data register */
+#define PKPUEN_ADDR	0xfffff442		/* Port K Pull-Up enb. reg */
+#define PKSEL_ADDR	0xfffff443		/* Port K Select Register */
+
+#define PKDIR		BYTE_REF(PKDIR_ADDR)
+#define PKDATA		BYTE_REF(PKDATA_ADDR)
+#define PKPUEN		BYTE_REF(PKPUEN_ADDR)
+#define PKSEL		BYTE_REF(PKSEL_ADDR)
+
+#define PK(x)		(1 << (x))
+
+#define PK_DATAREADY		0x01	/* Use ~DATA_READY  as PK[0] */
+#define PK_PWM2		0x01	/* Use PWM2  as PK[0] */
+#define PK_R_W		0x02	/* Use R/W  as PK[1] */
+#define PK_LDS		0x04	/* Use /LDS  as PK[2] */
+#define PK_UDS		0x08	/* Use /UDS  as PK[3] */
+#define PK_LD4		0x10	/* Use LD4 as PK[4] */
+#define PK_LD5 		0x20	/* Use LD5  as PK[5] */
+#define PK_LD6		0x40	/* Use LD6 as PK[6] */
+#define PK_LD7		0x80	/* Use LD7 as PK[7] */
+
+#define PJDIR_ADDR	0xfffff438		/* Port J direction reg */
+#define PJDATA_ADDR	0xfffff439		/* Port J data register */
+#define PJPUEN_ADDR	0xfffff43A		/* Port J Pull-Up enable reg */
+#define PJSEL_ADDR	0xfffff43B		/* Port J Select Register */
+
+#define PJDIR		BYTE_REF(PJDIR_ADDR)
+#define PJDATA		BYTE_REF(PJDATA_ADDR)
+#define PJPUEN		BYTE_REF(PJPUEN_ADDR)
+#define PJSEL		BYTE_REF(PJSEL_ADDR)
+
+#define PJ(x)		(1 << (x))
+
+#define PJ_MOSI 	0x01	/* Use MOSI       as PJ[0] */
+#define PJ_MISO		0x02	/* Use MISO       as PJ[1] */
+#define PJ_SPICLK1  	0x04	/* Use SPICLK1    as PJ[2] */
+#define PJ_SS   	0x08	/* Use SS         as PJ[3] */
+#define PJ_RXD2         0x10	/* Use RXD2       as PJ[4] */
+#define PJ_TXD2  	0x20	/* Use TXD2       as PJ[5] */
+#define PJ_RTS2  	0x40	/* Use RTS2       as PJ[5] */
+#define PJ_CTS2  	0x80	/* Use CTS2       as PJ[5] */
+
+/*
+ * Port M
+ */
+#define PMDIR_ADDR	0xfffff448		/* Port M direction reg */
+#define PMDATA_ADDR	0xfffff449		/* Port M data register */
+#define PMPUEN_ADDR	0xfffff44a		/* Port M Pull-Up enable reg */
+#define PMSEL_ADDR	0xfffff44b		/* Port M Select Register */
+
+#define PMDIR		BYTE_REF(PMDIR_ADDR)
+#define PMDATA		BYTE_REF(PMDATA_ADDR)
+#define PMPUEN		BYTE_REF(PMPUEN_ADDR)
+#define PMSEL		BYTE_REF(PMSEL_ADDR)
+
+#define PM(x)		(1 << (x))
+
+#define PM_SDCLK	0x01	/* Use SDCLK      as PM[0] */
+#define PM_SDCE		0x02	/* Use SDCE       as PM[1] */
+#define PM_DQMH 	0x04	/* Use DQMH       as PM[2] */
+#define PM_DQML 	0x08	/* Use DQML       as PM[3] */
+#define PM_SDA10        0x10	/* Use SDA10      as PM[4] */
+#define PM_DMOE 	0x20	/* Use DMOE       as PM[5] */
+
+/**********
+ *
+ * 0xFFFFF5xx -- Pulse-Width Modulator (PWM)
+ *
+ **********/
+
+/*
+ * PWM Control Register
+ */
+#define PWMC_ADDR	0xfffff500
+#define PWMC		WORD_REF(PWMC_ADDR)
+
+#define PWMC_CLKSEL_MASK	0x0003	/* Clock Selection */
+#define PWMC_CLKSEL_SHIFT	0
+#define PWMC_REPEAT_MASK	0x000c	/* Sample Repeats */
+#define PWMC_REPEAT_SHIFT	2
+#define PWMC_EN			0x0010	/* Enable PWM */
+#define PMNC_FIFOAV		0x0020	/* FIFO Available */
+#define PWMC_IRQEN		0x0040	/* Interrupt Request Enable */
+#define PWMC_IRQ		0x0080	/* Interrupt Request (FIFO empty) */
+#define PWMC_PRESCALER_MASK	0x7f00	/* Incoming Clock prescaler */
+#define PWMC_PRESCALER_SHIFT	8
+#define PWMC_CLKSRC		0x8000	/* Clock Source Select */
+
+/* '328-compatible definitions */
+#define PWMC_PWMEN	PWMC_EN
+
+/*
+ * PWM Sample Register 
+ */
+#define PWMS_ADDR	0xfffff502
+#define PWMS		WORD_REF(PWMS_ADDR)
+
+/*
+ * PWM Period Register
+ */
+#define PWMP_ADDR	0xfffff504
+#define PWMP		BYTE_REF(PWMP_ADDR)
+
+/*
+ * PWM Counter Register
+ */
+#define PWMCNT_ADDR	0xfffff505
+#define PWMCNT		BYTE_REF(PWMCNT_ADDR)
+
+/**********
+ *
+ * 0xFFFFF6xx -- General-Purpose Timer
+ *
+ **********/
+
+/* 
+ * Timer Control register
+ */
+#define TCTL_ADDR	0xfffff600
+#define TCTL		WORD_REF(TCTL_ADDR)
+
+#define	TCTL_TEN		0x0001	/* Timer Enable  */
+#define TCTL_CLKSOURCE_MASK 	0x000e	/* Clock Source: */
+#define   TCTL_CLKSOURCE_STOP	   0x0000	/* Stop count (disabled)    */
+#define   TCTL_CLKSOURCE_SYSCLK	   0x0002	/* SYSCLK to prescaler      */
+#define   TCTL_CLKSOURCE_SYSCLK_16 0x0004	/* SYSCLK/16 to prescaler   */
+#define   TCTL_CLKSOURCE_TIN	   0x0006	/* TIN to prescaler         */
+#define   TCTL_CLKSOURCE_32KHZ	   0x0008	/* 32kHz clock to prescaler */
+#define TCTL_IRQEN		0x0010	/* IRQ Enable    */
+#define TCTL_OM			0x0020	/* Output Mode   */
+#define TCTL_CAP_MASK		0x00c0	/* Capture Edge: */
+#define	  TCTL_CAP_RE		0x0040		/* Capture on rizing edge   */
+#define   TCTL_CAP_FE		0x0080		/* Capture on falling edge  */
+#define TCTL_FRR		0x0010	/* Free-Run Mode */
+
+/* '328-compatible definitions */
+#define TCTL1_ADDR	TCTL_ADDR
+#define TCTL1		TCTL
+
+/*
+ * Timer Prescaler Register
+ */
+#define TPRER_ADDR	0xfffff602
+#define TPRER		WORD_REF(TPRER_ADDR)
+
+/* '328-compatible definitions */
+#define TPRER1_ADDR	TPRER_ADDR
+#define TPRER1		TPRER
+
+/*
+ * Timer Compare Register
+ */
+#define TCMP_ADDR	0xfffff604
+#define TCMP		WORD_REF(TCMP_ADDR)
+
+/* '328-compatible definitions */
+#define TCMP1_ADDR	TCMP_ADDR
+#define TCMP1		TCMP
+
+/*
+ * Timer Capture register
+ */
+#define TCR_ADDR	0xfffff606
+#define TCR		WORD_REF(TCR_ADDR)
+
+/* '328-compatible definitions */
+#define TCR1_ADDR	TCR_ADDR
+#define TCR1		TCR
+
+/*
+ * Timer Counter Register
+ */
+#define TCN_ADDR	0xfffff608
+#define TCN		WORD_REF(TCN_ADDR)
+
+/* '328-compatible definitions */
+#define TCN1_ADDR	TCN_ADDR
+#define TCN1		TCN
+
+/*
+ * Timer Status Register
+ */
+#define TSTAT_ADDR	0xfffff60a
+#define TSTAT		WORD_REF(TSTAT_ADDR)
+
+#define TSTAT_COMP	0x0001		/* Compare Event occurred */
+#define TSTAT_CAPT	0x0001		/* Capture Event occurred */
+
+/* '328-compatible definitions */
+#define TSTAT1_ADDR	TSTAT_ADDR
+#define TSTAT1		TSTAT
+
+/**********
+ *
+ * 0xFFFFF8xx -- Serial Periferial Interface Master (SPIM)
+ *
+ **********/
+
+/*
+ * SPIM Data Register
+ */
+#define SPIMDATA_ADDR	0xfffff800
+#define SPIMDATA	WORD_REF(SPIMDATA_ADDR)
+
+/*
+ * SPIM Control/Status Register
+ */
+#define SPIMCONT_ADDR	0xfffff802
+#define SPIMCONT	WORD_REF(SPIMCONT_ADDR)
+
+#define SPIMCONT_BIT_COUNT_MASK	 0x000f	/* Transfer Length in Bytes */
+#define SPIMCONT_BIT_COUNT_SHIFT 0
+#define SPIMCONT_POL		 0x0010	/* SPMCLK Signel Polarity */
+#define	SPIMCONT_PHA		 0x0020	/* Clock/Data phase relationship */
+#define SPIMCONT_IRQEN		 0x0040 /* IRQ Enable */
+#define SPIMCONT_IRQ		 0x0080	/* Interrupt Request */
+#define SPIMCONT_XCH		 0x0100	/* Exchange */
+#define SPIMCONT_ENABLE		 0x0200	/* Enable SPIM */
+#define SPIMCONT_DATA_RATE_MASK	 0xe000	/* SPIM Data Rate */
+#define SPIMCONT_DATA_RATE_SHIFT 13
+
+/* '328-compatible definitions */
+#define SPIMCONT_SPIMIRQ	SPIMCONT_IRQ
+#define SPIMCONT_SPIMEN		SPIMCONT_ENABLE
+
+/**********
+ *
+ * 0xFFFFF9xx -- UART
+ *
+ **********/
+
+/*
+ * UART Status/Control Register
+ */
+
+#define USTCNT_ADDR	0xfffff900
+#define USTCNT		WORD_REF(USTCNT_ADDR)
+
+#define USTCNT_TXAE	0x0001	/* Transmitter Available Interrupt Enable */
+#define USTCNT_TXHE	0x0002	/* Transmitter Half Empty Enable */
+#define USTCNT_TXEE	0x0004	/* Transmitter Empty Interrupt Enable */
+#define USTCNT_RXRE	0x0008	/* Receiver Ready Interrupt Enable */
+#define USTCNT_RXHE	0x0010	/* Receiver Half-Full Interrupt Enable */
+#define USTCNT_RXFE	0x0020	/* Receiver Full Interrupt Enable */
+#define USTCNT_CTSD	0x0040	/* CTS Delta Interrupt Enable */
+#define USTCNT_ODEN	0x0080	/* Old Data Interrupt Enable */
+#define USTCNT_8_7	0x0100	/* Eight or seven-bit transmission */
+#define USTCNT_STOP	0x0200	/* Stop bit transmission */
+#define USTCNT_ODD	0x0400	/* Odd Parity */
+#define	USTCNT_PEN	0x0800	/* Parity Enable */
+#define USTCNT_CLKM	0x1000	/* Clock Mode Select */
+#define	USTCNT_TXEN	0x2000	/* Transmitter Enable */
+#define USTCNT_RXEN	0x4000	/* Receiver Enable */
+#define USTCNT_UEN	0x8000	/* UART Enable */
+
+/* '328-compatible definitions */
+#define USTCNT_TXAVAILEN	USTCNT_TXAE
+#define USTCNT_TXHALFEN		USTCNT_TXHE
+#define USTCNT_TXEMPTYEN	USTCNT_TXEE
+#define USTCNT_RXREADYEN	USTCNT_RXRE
+#define USTCNT_RXHALFEN		USTCNT_RXHE
+#define USTCNT_RXFULLEN		USTCNT_RXFE
+#define USTCNT_CTSDELTAEN	USTCNT_CTSD
+#define USTCNT_ODD_EVEN		USTCNT_ODD
+#define USTCNT_PARITYEN		USTCNT_PEN
+#define USTCNT_CLKMODE		USTCNT_CLKM
+#define USTCNT_UARTEN		USTCNT_UEN
+
+/*
+ * UART Baud Control Register
+ */
+#define UBAUD_ADDR	0xfffff902
+#define UBAUD		WORD_REF(UBAUD_ADDR)
+
+#define UBAUD_PRESCALER_MASK	0x003f	/* Actual divisor is 65 - PRESCALER */
+#define UBAUD_PRESCALER_SHIFT	0
+#define UBAUD_DIVIDE_MASK	0x0700	/* Baud Rate freq. divizor */
+#define UBAUD_DIVIDE_SHIFT	8
+#define UBAUD_BAUD_SRC		0x0800	/* Baud Rate Source */
+#define UBAUD_UCLKDIR		0x2000	/* UCLK Direction */
+
+/*
+ * UART Receiver Register 
+ */
+#define URX_ADDR	0xfffff904
+#define URX		WORD_REF(URX_ADDR)
+
+#define URX_RXDATA_ADDR	0xfffff905
+#define URX_RXDATA	BYTE_REF(URX_RXDATA_ADDR)
+
+#define URX_RXDATA_MASK	 0x00ff	/* Received data */
+#define URX_RXDATA_SHIFT 0
+#define URX_PARITY_ERROR 0x0100	/* Parity Error */
+#define URX_BREAK	 0x0200	/* Break Detected */
+#define URX_FRAME_ERROR	 0x0400	/* Framing Error */
+#define URX_OVRUN	 0x0800	/* Serial Overrun */
+#define URX_OLD_DATA	 0x1000	/* Old data in FIFO */
+#define URX_DATA_READY	 0x2000	/* Data Ready (FIFO not empty) */
+#define URX_FIFO_HALF	 0x4000 /* FIFO is Half-Full */
+#define URX_FIFO_FULL	 0x8000	/* FIFO is Full */
+
+/*
+ * UART Transmitter Register 
+ */
+#define UTX_ADDR	0xfffff906
+#define UTX		WORD_REF(UTX_ADDR)
+
+#define UTX_TXDATA_ADDR	0xfffff907
+#define UTX_TXDATA	BYTE_REF(UTX_TXDATA_ADDR)
+
+#define UTX_TXDATA_MASK	 0x00ff	/* Data to be transmitted */
+#define UTX_TXDATA_SHIFT 0
+#define UTX_CTS_DELTA	 0x0100	/* CTS changed */
+#define UTX_CTS_STAT	 0x0200	/* CTS State */
+#define	UTX_BUSY	 0x0400	/* FIFO is busy, sending a character */
+#define	UTX_NOCTS	 0x0800	/* Ignore CTS */
+#define UTX_SEND_BREAK	 0x1000	/* Send a BREAK */
+#define UTX_TX_AVAIL	 0x2000	/* Transmit FIFO has a slot available */
+#define UTX_FIFO_HALF	 0x4000	/* Transmit FIFO is half empty */
+#define UTX_FIFO_EMPTY	 0x8000	/* Transmit FIFO is empty */
+
+/* '328-compatible definitions */
+#define UTX_CTS_STATUS	UTX_CTS_STAT
+#define UTX_IGNORE_CTS	UTX_NOCTS
+
+/*
+ * UART Miscellaneous Register 
+ */
+#define UMISC_ADDR	0xfffff908
+#define UMISC		WORD_REF(UMISC_ADDR)
+
+#define UMISC_TX_POL	 0x0004	/* Transmit Polarity */
+#define UMISC_RX_POL	 0x0008	/* Receive Polarity */
+#define UMISC_IRDA_LOOP	 0x0010	/* IrDA Loopback Enable */
+#define UMISC_IRDA_EN	 0x0020	/* Infra-Red Enable */
+#define UMISC_RTS	 0x0040	/* Set RTS status */
+#define UMISC_RTSCONT	 0x0080	/* Choose RTS control */
+#define UMISC_IR_TEST	 0x0400	/* IRDA Test Enable */
+#define UMISC_BAUD_RESET 0x0800	/* Reset Baud Rate Generation Counters */
+#define UMISC_LOOP	 0x1000	/* Serial Loopback Enable */
+#define UMISC_FORCE_PERR 0x2000	/* Force Parity Error */
+#define UMISC_CLKSRC	 0x4000	/* Clock Source */
+#define UMISC_BAUD_TEST	 0x8000	/* Enable Baud Test Mode */
+
+/* 
+ * UART Non-integer Prescaler Register
+ */
+#define NIPR_ADDR	0xfffff90a
+#define NIPR		WORD_REF(NIPR_ADDR)
+
+#define NIPR_STEP_VALUE_MASK	0x00ff	/* NI prescaler step value */
+#define NIPR_STEP_VALUE_SHIFT	0
+#define NIPR_SELECT_MASK	0x0700	/* Tap Selection */
+#define NIPR_SELECT_SHIFT	8
+#define NIPR_PRE_SEL		0x8000	/* Non-integer prescaler select */
+
+
+/* generalization of uart control registers to support multiple ports: */
+typedef struct {
+  volatile unsigned short int ustcnt;
+  volatile unsigned short int ubaud;
+  union {
+    volatile unsigned short int w;
+    struct {
+      volatile unsigned char status;
+      volatile unsigned char rxdata;
+    } b;
+  } urx;
+  union {
+    volatile unsigned short int w;
+    struct {
+      volatile unsigned char status;
+      volatile unsigned char txdata;
+    } b;
+  } utx;
+  volatile unsigned short int umisc;
+  volatile unsigned short int nipr;
+  volatile unsigned short int hmark;
+  volatile unsigned short int unused;
+} m68328_uart __attribute__((packed));
+
+
+
+
+/**********
+ *
+ * 0xFFFFFAxx -- LCD Controller
+ *
+ **********/
+
+/*
+ * LCD Screen Starting Address Register 
+ */
+#define LSSA_ADDR	0xfffffa00
+#define LSSA		LONG_REF(LSSA_ADDR)
+
+#define LSSA_SSA_MASK	0x1ffffffe	/* Bits 0 and 29-31 are reserved */
+
+/*
+ * LCD Virtual Page Width Register 
+ */
+#define LVPW_ADDR	0xfffffa05
+#define LVPW		BYTE_REF(LVPW_ADDR)
+
+/*
+ * LCD Screen Width Register (not compatible with '328 !!!) 
+ */
+#define LXMAX_ADDR	0xfffffa08
+#define LXMAX		WORD_REF(LXMAX_ADDR)
+
+#define LXMAX_XM_MASK	0x02f0		/* Bits 0-3 and 10-15 are reserved */
+
+/*
+ * LCD Screen Height Register
+ */
+#define LYMAX_ADDR	0xfffffa0a
+#define LYMAX		WORD_REF(LYMAX_ADDR)
+
+#define LYMAX_YM_MASK	0x01ff		/* Bits 9-15 are reserved */
+
+/*
+ * LCD Cursor X Position Register
+ */
+#define LCXP_ADDR	0xfffffa18
+#define LCXP		WORD_REF(LCXP_ADDR)
+
+#define LCXP_CC_MASK	0xc000		/* Cursor Control */
+#define   LCXP_CC_TRAMSPARENT	0x0000
+#define   LCXP_CC_BLACK		0x4000
+#define   LCXP_CC_REVERSED	0x8000
+#define   LCXP_CC_WHITE		0xc000
+#define LCXP_CXP_MASK	0x02ff		/* Cursor X position */
+
+/*
+ * LCD Cursor Y Position Register
+ */
+#define LCYP_ADDR	0xfffffa1a
+#define LCYP		WORD_REF(LCYP_ADDR)
+
+#define LCYP_CYP_MASK	0x01ff		/* Cursor Y Position */
+
+/*
+ * LCD Cursor Width and Heigth Register
+ */
+#define LCWCH_ADDR	0xfffffa1c
+#define LCWCH		WORD_REF(LCWCH_ADDR)
+
+#define LCWCH_CH_MASK	0x001f		/* Cursor Height */
+#define LCWCH_CH_SHIFT	0
+#define LCWCH_CW_MASK	0x1f00		/* Cursor Width */
+#define LCWCH_CW_SHIFT	8
+
+/*
+ * LCD Blink Control Register
+ */
+#define LBLKC_ADDR	0xfffffa1f
+#define LBLKC		BYTE_REF(LBLKC_ADDR)
+
+#define LBLKC_BD_MASK	0x7f	/* Blink Divisor */
+#define LBLKC_BD_SHIFT	0
+#define LBLKC_BKEN	0x80	/* Blink Enabled */
+
+/*
+ * LCD Panel Interface Configuration Register 
+ */
+#define LPICF_ADDR	0xfffffa20
+#define LPICF		BYTE_REF(LPICF_ADDR)
+
+#define LPICF_GS_MASK	 0x03	 /* Gray-Scale Mode */
+#define	  LPICF_GS_BW	   0x00
+#define   LPICF_GS_GRAY_4  0x01
+#define   LPICF_GS_GRAY_16 0x02
+#define LPICF_PBSIZ_MASK 0x0c	/* Panel Bus Width */
+#define   LPICF_PBSIZ_1	   0x00
+#define   LPICF_PBSIZ_2    0x04
+#define   LPICF_PBSIZ_4    0x08
+
+/*
+ * LCD Polarity Configuration Register 
+ */
+#define LPOLCF_ADDR	0xfffffa21
+#define LPOLCF		BYTE_REF(LPOLCF_ADDR)
+
+#define LPOLCF_PIXPOL	0x01	/* Pixel Polarity */
+#define LPOLCF_LPPOL	0x02	/* Line Pulse Polarity */
+#define LPOLCF_FLMPOL	0x04	/* Frame Marker Polarity */
+#define LPOLCF_LCKPOL	0x08	/* LCD Shift Lock Polarity */
+
+/*
+ * LACD (LCD Alternate Crystal Direction) Rate Control Register
+ */
+#define LACDRC_ADDR	0xfffffa23
+#define LACDRC		BYTE_REF(LACDRC_ADDR)
+
+#define LACDRC_ACDSLT	 0x80	/* Signal Source Select */
+#define LACDRC_ACD_MASK	 0x0f	/* Alternate Crystal Direction Control */
+#define LACDRC_ACD_SHIFT 0
+
+/*
+ * LCD Pixel Clock Divider Register
+ */
+#define LPXCD_ADDR	0xfffffa25
+#define LPXCD		BYTE_REF(LPXCD_ADDR)
+
+#define	LPXCD_PCD_MASK	0x3f 	/* Pixel Clock Divider */
+#define LPXCD_PCD_SHIFT	0
+
+/*
+ * LCD Clocking Control Register
+ */
+#define LCKCON_ADDR	0xfffffa27
+#define LCKCON		BYTE_REF(LCKCON_ADDR)
+
+#define LCKCON_DWS_MASK	 0x0f	/* Display Wait-State */
+#define LCKCON_DWS_SHIFT 0
+#define LCKCON_DWIDTH	 0x40	/* Display Memory Width  */
+#define LCKCON_LCDON	 0x80	/* Enable LCD Controller */
+
+/* '328-compatible definitions */
+#define LCKCON_DW_MASK  LCKCON_DWS_MASK
+#define LCKCON_DW_SHIFT LCKCON_DWS_SHIFT
+ 
+/*
+ * LCD Refresh Rate Adjustment Register 
+ */
+#define LRRA_ADDR	0xfffffa29
+#define LRRA		BYTE_REF(LRRA_ADDR)
+
+/*
+ * LCD Panning Offset Register
+ */
+#define LPOSR_ADDR	0xfffffa2d
+#define LPOSR		BYTE_REF(LPOSR_ADDR)
+
+#define LPOSR_POS_MASK	0x0f	/* Pixel Offset Code */
+#define LPOSR_POS_SHIFT	0
+
+/*
+ * LCD Frame Rate Control Modulation Register
+ */
+#define LFRCM_ADDR	0xfffffa31
+#define LFRCM		BYTE_REF(LFRCM_ADDR)
+
+#define LFRCM_YMOD_MASK	 0x0f	/* Vertical Modulation */
+#define LFRCM_YMOD_SHIFT 0
+#define LFRCM_XMOD_MASK	 0xf0	/* Horizontal Modulation */
+#define LFRCM_XMOD_SHIFT 4
+
+/*
+ * LCD Gray Palette Mapping Register
+ */
+#define LGPMR_ADDR	0xfffffa33
+#define LGPMR		BYTE_REF(LGPMR_ADDR)
+
+#define LGPMR_G1_MASK	0x0f
+#define LGPMR_G1_SHIFT	0
+#define LGPMR_G2_MASK	0xf0
+#define LGPMR_G2_SHIFT	4
+
+/* 
+ * PWM Contrast Control Register
+ */
+#define PWMR_ADDR	0xfffffa36
+#define PWMR		WORD_REF(PWMR_ADDR)
+
+#define PWMR_PW_MASK	0x00ff	/* Pulse Width */
+#define PWMR_PW_SHIFT	0
+#define PWMR_CCPEN	0x0100	/* Contrast Control Enable */
+#define PWMR_SRC_MASK	0x0600	/* Input Clock Source */
+#define   PWMR_SRC_LINE	  0x0000	/* Line Pulse  */
+#define   PWMR_SRC_PIXEL  0x0200	/* Pixel Clock */
+#define   PWMR_SRC_LCD    0x4000	/* LCD clock   */
+
+/**********
+ *
+ * 0xFFFFFBxx -- Real-Time Clock (RTC)
+ *
+ **********/
+
+/*
+ * RTC Hours Minutes and Seconds Register
+ */
+#define RTCTIME_ADDR	0xfffffb00
+#define RTCTIME		LONG_REF(RTCTIME_ADDR)
+
+#define RTCTIME_SECONDS_MASK	0x0000003f	/* Seconds */
+#define RTCTIME_SECONDS_SHIFT	0
+#define RTCTIME_MINUTES_MASK	0x003f0000	/* Minutes */
+#define RTCTIME_MINUTES_SHIFT	16
+#define RTCTIME_HOURS_MASK	0x1f000000	/* Hours */
+#define RTCTIME_HOURS_SHIFT	24
+
+/*
+ *  RTC Alarm Register 
+ */
+#define RTCALRM_ADDR    0xfffffb04
+#define RTCALRM         LONG_REF(RTCALRM_ADDR)
+
+#define RTCALRM_SECONDS_MASK    0x0000003f      /* Seconds */
+#define RTCALRM_SECONDS_SHIFT   0
+#define RTCALRM_MINUTES_MASK    0x003f0000      /* Minutes */
+#define RTCALRM_MINUTES_SHIFT   16
+#define RTCALRM_HOURS_MASK      0x1f000000      /* Hours */
+#define RTCALRM_HOURS_SHIFT     24
+
+/*
+ * Watchdog Timer Register 
+ */
+#define WATCHDOG_ADDR	0xfffffb0a
+#define WATCHDOG	WORD_REF(WATCHDOG_ADDR)
+
+#define WATCHDOG_EN	0x0001	/* Watchdog Enabled */
+#define WATCHDOG_ISEL	0x0002	/* Select the watchdog interrupt */
+#define WATCHDOG_INTF	0x0080	/* Watchdog interrupt occcured */
+#define WATCHDOG_CNT_MASK  0x0300	/* Watchdog Counter */
+#define WATCHDOG_CNT_SHIFT 8
+
+/*
+ * RTC Control Register
+ */
+#define RTCCTL_ADDR	0xfffffb0c
+#define RTCCTL		WORD_REF(RTCCTL_ADDR)
+
+#define RTCCTL_XTL	0x0020	/* Crystal Selection */
+#define RTCCTL_EN	0x0080	/* RTC Enable */
+
+/* '328-compatible definitions */
+#define RTCCTL_384	RTCCTL_XTL
+#define RTCCTL_ENABLE	RTCCTL_EN
+
+/*
+ * RTC Interrupt Status Register 
+ */
+#define RTCISR_ADDR	0xfffffb0e
+#define RTCISR		WORD_REF(RTCISR_ADDR)
+
+#define RTCISR_SW	0x0001	/* Stopwatch timed out */
+#define RTCISR_MIN	0x0002	/* 1-minute interrupt has occured */
+#define RTCISR_ALM	0x0004	/* Alarm interrupt has occured */
+#define RTCISR_DAY	0x0008	/* 24-hour rollover interrupt has occured */
+#define RTCISR_1HZ	0x0010	/* 1Hz interrupt has occured */
+#define RTCISR_HR	0x0020	/* 1-hour interrupt has occured */
+#define RTCISR_SAM0	0x0100	/*   4Hz /   4.6875Hz interrupt has occured */ 
+#define RTCISR_SAM1	0x0200	/*   8Hz /   9.3750Hz interrupt has occured */ 
+#define RTCISR_SAM2	0x0400	/*  16Hz /  18.7500Hz interrupt has occured */ 
+#define RTCISR_SAM3	0x0800	/*  32Hz /  37.5000Hz interrupt has occured */ 
+#define RTCISR_SAM4	0x1000	/*  64Hz /  75.0000Hz interrupt has occured */ 
+#define RTCISR_SAM5	0x2000	/* 128Hz / 150.0000Hz interrupt has occured */ 
+#define RTCISR_SAM6	0x4000	/* 256Hz / 300.0000Hz interrupt has occured */ 
+#define RTCISR_SAM7	0x8000	/* 512Hz / 600.0000Hz interrupt has occured */ 
+
+/*
+ * RTC Interrupt Enable Register
+ */
+#define RTCIENR_ADDR	0xfffffb10
+#define RTCIENR		WORD_REF(RTCIENR_ADDR)
+
+#define RTCIENR_SW	0x0001	/* Stopwatch interrupt enable */
+#define RTCIENR_MIN	0x0002	/* 1-minute interrupt enable */
+#define RTCIENR_ALM	0x0004	/* Alarm interrupt enable */
+#define RTCIENR_DAY	0x0008	/* 24-hour rollover interrupt enable */
+#define RTCIENR_1HZ	0x0010	/* 1Hz interrupt enable */
+#define RTCIENR_HR	0x0020	/* 1-hour interrupt enable */
+#define RTCIENR_SAM0	0x0100	/*   4Hz /   4.6875Hz interrupt enable */ 
+#define RTCIENR_SAM1	0x0200	/*   8Hz /   9.3750Hz interrupt enable */ 
+#define RTCIENR_SAM2	0x0400	/*  16Hz /  18.7500Hz interrupt enable */ 
+#define RTCIENR_SAM3	0x0800	/*  32Hz /  37.5000Hz interrupt enable */ 
+#define RTCIENR_SAM4	0x1000	/*  64Hz /  75.0000Hz interrupt enable */ 
+#define RTCIENR_SAM5	0x2000	/* 128Hz / 150.0000Hz interrupt enable */ 
+#define RTCIENR_SAM6	0x4000	/* 256Hz / 300.0000Hz interrupt enable */ 
+#define RTCIENR_SAM7	0x8000	/* 512Hz / 600.0000Hz interrupt enable */ 
+
+/* 
+ * Stopwatch Minutes Register
+ */
+#define STPWCH_ADDR	0xfffffb12
+#define STPWCH		WORD_REF(STPWCH_ADDR)
+
+#define STPWCH_CNT_MASK	 0x003f	/* Stopwatch countdown value */
+#define SPTWCH_CNT_SHIFT 0
+
+/*
+ * RTC Day Count Register 
+ */
+#define DAYR_ADDR	0xfffffb1a
+#define DAYR		WORD_REF(DAYR_ADDR)
+
+#define DAYR_DAYS_MASK	0x1ff	/* Day Setting */
+#define DAYR_DAYS_SHIFT 0
+
+/*
+ * RTC Day Alarm Register 
+ */
+#define DAYALARM_ADDR	0xfffffb1c
+#define DAYALARM	WORD_REF(DAYALARM_ADDR)
+
+#define DAYALARM_DAYSAL_MASK	0x01ff	/* Day Setting of the Alarm */
+#define DAYALARM_DAYSAL_SHIFT 	0
+
+/**********
+ *
+ * 0xFFFFFCxx -- DRAM Controller
+ *
+ **********/
+
+/*
+ * DRAM Memory Configuration Register 
+ */
+#define DRAMMC_ADDR	0xfffffc00
+#define DRAMMC		WORD_REF(DRAMMC_ADDR)
+
+#define DRAMMC_ROW12_MASK	0xc000	/* Row address bit for MD12 */
+#define   DRAMMC_ROW12_PA10	0x0000
+#define   DRAMMC_ROW12_PA21	0x4000	
+#define   DRAMMC_ROW12_PA23	0x8000
+#define	DRAMMC_ROW0_MASK	0x3000	/* Row address bit for MD0 */
+#define	  DRAMMC_ROW0_PA11	0x0000
+#define   DRAMMC_ROW0_PA22	0x1000
+#define   DRAMMC_ROW0_PA23	0x2000
+#define DRAMMC_ROW11		0x0800	/* Row address bit for MD11 PA20/PA22 */
+#define DRAMMC_ROW10		0x0400	/* Row address bit for MD10 PA19/PA21 */
+#define	DRAMMC_ROW9		0x0200	/* Row address bit for MD9  PA9/PA19  */
+#define DRAMMC_ROW8		0x0100	/* Row address bit for MD8  PA10/PA20 */
+#define DRAMMC_COL10		0x0080	/* Col address bit for MD10 PA11/PA0  */
+#define DRAMMC_COL9		0x0040	/* Col address bit for MD9  PA10/PA0  */
+#define DRAMMC_COL8		0x0020	/* Col address bit for MD8  PA9/PA0   */
+#define DRAMMC_REF_MASK		0x001f	/* Reresh Cycle */
+#define DRAMMC_REF_SHIFT	0
+
+/*
+ * DRAM Control Register
+ */
+#define DRAMC_ADDR	0xfffffc02
+#define DRAMC		WORD_REF(DRAMC_ADDR)
+
+#define DRAMC_DWE	   0x0001	/* DRAM Write Enable */
+#define DRAMC_RST	   0x0002	/* Reset Burst Refresh Enable */
+#define DRAMC_LPR	   0x0004	/* Low-Power Refresh Enable */
+#define DRAMC_SLW	   0x0008	/* Slow RAM */
+#define DRAMC_LSP	   0x0010	/* Light Sleep */
+#define DRAMC_MSW	   0x0020	/* Slow Multiplexing */
+#define DRAMC_WS_MASK	   0x00c0	/* Wait-states */
+#define DRAMC_WS_SHIFT	   6
+#define DRAMC_PGSZ_MASK    0x0300	/* Page Size for fast page mode */
+#define DRAMC_PGSZ_SHIFT   8
+#define   DRAMC_PGSZ_256K  0x0000	
+#define   DRAMC_PGSZ_512K  0x0100
+#define   DRAMC_PGSZ_1024K 0x0200
+#define	  DRAMC_PGSZ_2048K 0x0300
+#define DRAMC_EDO	   0x0400	/* EDO DRAM */
+#define DRAMC_CLK	   0x0800	/* Refresh Timer Clock source select */
+#define DRAMC_BC_MASK	   0x3000	/* Page Access Clock Cycle (FP mode) */
+#define DRAMC_BC_SHIFT	   12
+#define DRAMC_RM	   0x4000	/* Refresh Mode */
+#define DRAMC_EN	   0x8000	/* DRAM Controller enable */
+
+
+/**********
+ *
+ * 0xFFFFFDxx -- In-Circuit Emulation (ICE)
+ *
+ **********/
+
+/*
+ * ICE Module Address Compare Register
+ */
+#define ICEMACR_ADDR	0xfffffd00
+#define ICEMACR		LONG_REF(ICEMACR_ADDR)
+
+/*
+ * ICE Module Address Mask Register
+ */
+#define ICEMAMR_ADDR	0xfffffd04
+#define ICEMAMR		LONG_REF(ICEMAMR_ADDR)
+
+/*
+ * ICE Module Control Compare Register
+ */
+#define ICEMCCR_ADDR	0xfffffd08
+#define ICEMCCR		WORD_REF(ICEMCCR_ADDR)
+
+#define ICEMCCR_PD	0x0001	/* Program/Data Cycle Selection */
+#define ICEMCCR_RW	0x0002	/* Read/Write Cycle Selection */
+
+/*
+ * ICE Module Control Mask Register
+ */
+#define ICEMCMR_ADDR	0xfffffd0a
+#define ICEMCMR		WORD_REF(ICEMCMR_ADDR)
+
+#define ICEMCMR_PDM	0x0001	/* Program/Data Cycle Mask */
+#define ICEMCMR_RWM	0x0002	/* Read/Write Cycle Mask */
+
+/*
+ * ICE Module Control Register 
+ */
+#define ICEMCR_ADDR	0xfffffd0c
+#define ICEMCR		WORD_REF(ICEMCR_ADDR)
+
+#define ICEMCR_CEN	0x0001	/* Compare Enable */
+#define ICEMCR_PBEN	0x0002	/* Program Break Enable */
+#define ICEMCR_SB	0x0004	/* Single Breakpoint */
+#define ICEMCR_HMDIS	0x0008	/* HardMap disable */
+#define ICEMCR_BBIEN	0x0010	/* Bus Break Interrupt Enable */
+
+/*
+ * ICE Module Status Register 
+ */
+#define ICEMSR_ADDR	0xfffffd0e
+#define ICEMSR		WORD_REF(ICEMSR_ADDR)
+
+#define ICEMSR_EMUEN	0x0001	/* Emulation Enable */
+#define ICEMSR_BRKIRQ	0x0002	/* A-Line Vector Fetch Detected */
+#define ICEMSR_BBIRQ	0x0004	/* Bus Break Interrupt Detected */
+#define ICEMSR_EMIRQ	0x0008	/* EMUIRQ Falling Edge Detected */
+
+#endif /* _MC68VZ328_H_ */
diff -urN linux-2.4.29/include/asm-m68knommu/mcfdma.h linux-2.4.29-uc1/include/asm-m68knommu/mcfdma.h
--- linux-2.4.29/include/asm-m68knommu/mcfdma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mcfdma.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,146 @@
+/****************************************************************************/
+
+/*
+ *	mcfdma.h -- Coldfire internal DMA support defines.
+ *
+ *	(C) Copyright 1999, Rob Scott (rscott@mtrob.ml.org)
+ */
+
+/****************************************************************************/
+#ifndef	mcfdma_h
+#define	mcfdma_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Get address specific defines for this Coldfire member.
+ */
+#if defined(CONFIG_M5206) || defined(CONFIG_M5206e)
+#define	MCFDMA_BASE0		0x200		/* Base address of DMA 0 */
+#define	MCFDMA_BASE1		0x240		/* Base address of DMA 1 */
+#elif defined(CONFIG_M5272)
+#define	MCFDMA_BASE0		0x0e0		/* Base address of DMA 0 */
+#elif defined(CONFIG_M5235) || defined(CONFIG_M527x) || \
+      defined(CONFIG_M5282) || defined(CONFIG_M5280)
+/* These are relative to the IPSBAR, not MBAR */
+#define	MCFDMA_BASE0		0x100		/* Base address of DMA 0 */
+#define	MCFDMA_BASE1		0x140		/* Base address of DMA 1 */
+#define	MCFDMA_BASE2		0x180		/* Base address of DMA 2 */
+#define	MCFDMA_BASE3		0x1C0		/* Base address of DMA 3 */
+#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407)
+#define	MCFDMA_BASE0		0x300		/* Base address of DMA 0 */
+#define	MCFDMA_BASE1		0x340		/* Base address of DMA 1 */
+#define	MCFDMA_BASE2		0x380		/* Base address of DMA 2 */
+#define	MCFDMA_BASE3		0x3C0		/* Base address of DMA 3 */
+#endif
+
+
+#if !defined(CONFIG_M5272)
+
+/*
+ *	Define the DMA register set addresses.
+ *      Note: these are longword registers, use unsigned long as data type
+ */
+#define	MCFDMA_SAR		0x00		/* DMA source address (r/w) */
+#define	MCFDMA_DAR		0x01		/* DMA destination adr (r/w) */
+/* these are word registers, use unsigned short data type */
+#define	MCFDMA_DCR		0x04		/* DMA control reg (r/w) */
+#define	MCFDMA_BCR		0x06		/* DMA byte count reg (r/w) */
+/* these are byte registers, use unsiged char data type */
+#define	MCFDMA_DSR		0x10		/* DMA status reg (r/w) */
+#define	MCFDMA_DIVR		0x14		/* DMA interrupt vec (r/w) */
+
+/*
+ *	Bit definitions for the DMA Control Register (DCR).
+ */
+#define	MCFDMA_DCR_INT	        0x8000		/* Enable completion irq */
+#define	MCFDMA_DCR_EEXT	        0x4000		/* Enable external DMA req */
+#define	MCFDMA_DCR_CS 	        0x2000		/* Enable cycle steal */
+#define	MCFDMA_DCR_AA   	0x1000		/* Enable auto alignment */
+#define	MCFDMA_DCR_BWC_MASK  	0x0E00		/* Bandwidth ctl mask */
+#define MCFDMA_DCR_BWC_512      0x0200          /* Bandwidth:   512 Bytes */
+#define MCFDMA_DCR_BWC_1024     0x0400          /* Bandwidth:  1024 Bytes */
+#define MCFDMA_DCR_BWC_2048     0x0600          /* Bandwidth:  2048 Bytes */
+#define MCFDMA_DCR_BWC_4096     0x0800          /* Bandwidth:  4096 Bytes */
+#define MCFDMA_DCR_BWC_8192     0x0a00          /* Bandwidth:  8192 Bytes */
+#define MCFDMA_DCR_BWC_16384    0x0c00          /* Bandwidth: 16384 Bytes */
+#define MCFDMA_DCR_BWC_32768    0x0e00          /* Bandwidth: 32768 Bytes */
+#define	MCFDMA_DCR_SAA         	0x0100		/* Single Address Access */
+#define	MCFDMA_DCR_S_RW        	0x0080		/* SAA read/write value */
+#define	MCFDMA_DCR_SINC        	0x0040		/* Source addr inc enable */
+#define	MCFDMA_DCR_SSIZE_MASK  	0x0030		/* Src xfer size */
+#define	MCFDMA_DCR_SSIZE_LONG  	0x0000		/* Src xfer size, 00 = longw */
+#define	MCFDMA_DCR_SSIZE_BYTE  	0x0010		/* Src xfer size, 01 = byte */
+#define	MCFDMA_DCR_SSIZE_WORD  	0x0020		/* Src xfer size, 10 = word */
+#define	MCFDMA_DCR_SSIZE_LINE  	0x0030		/* Src xfer size, 11 = line */
+#define	MCFDMA_DCR_DINC        	0x0008		/* Dest addr inc enable */
+#define	MCFDMA_DCR_DSIZE_MASK  	0x0006		/* Dest xfer size */
+#define	MCFDMA_DCR_DSIZE_LONG  	0x0000		/* Dest xfer size, 00 = long */
+#define	MCFDMA_DCR_DSIZE_BYTE  	0x0002		/* Dest xfer size, 01 = byte */
+#define	MCFDMA_DCR_DSIZE_WORD  	0x0004		/* Dest xfer size, 10 = word */
+#define	MCFDMA_DCR_DSIZE_LINE  	0x0006		/* Dest xfer size, 11 = line */
+#define	MCFDMA_DCR_START       	0x0001		/* Start transfer */
+
+/*
+ *	Bit definitions for the DMA Status Register (DSR).
+ */
+#define	MCFDMA_DSR_CE	        0x40		/* Config error */
+#define	MCFDMA_DSR_BES	        0x20		/* Bus Error on source */
+#define	MCFDMA_DSR_BED 	        0x10		/* Bus Error on dest */
+#define	MCFDMA_DSR_REQ   	0x04		/* Requests remaining */
+#define	MCFDMA_DSR_BSY  	0x02		/* Busy */
+#define	MCFDMA_DSR_DONE        	0x01		/* DMA transfer complete */
+
+#else /* This is an MCF5272 */
+
+#define MCFDMA_DMR        0x00    /* Mode Register (r/w) */
+#define MCFDMA_DIR        0x03    /* Interrupt trigger register (r/w) */
+#define MCFDMA_DSAR       0x03    /* Source Address register (r/w) */
+#define MCFDMA_DDAR       0x04    /* Destination Address register (r/w) */
+#define MCFDMA_DBCR       0x02    /* Byte Count Register (r/w) */
+
+/* Bit definitions for the DMA Mode Register (DMR) */
+#define MCFDMA_DMR_RESET     0x80000000L /* Reset bit */
+#define MCFDMA_DMR_EN        0x40000000L /* DMA enable */
+#define MCFDMA_DMR_RQM       0x000C0000L /* Request Mode Mask */
+#define MCFDMA_DMR_RQM_DUAL  0x000C0000L /* Dual address mode, the only valid mode */
+#define MCFDMA_DMR_DSTM      0x00002000L /* Destination addressing mask */
+#define MCFDMA_DMR_DSTM_SA   0x00000000L /* Destination uses static addressing */
+#define MCFDMA_DMR_DSTM_IA   0x00002000L /* Destination uses incremental addressing */
+#define MCFDMA_DMR_DSTT_UD   0x00000400L /* Destination is user data */
+#define MCFDMA_DMR_DSTT_UC   0x00000800L /* Destination is user code */
+#define MCFDMA_DMR_DSTT_SD   0x00001400L /* Destination is supervisor data */
+#define MCFDMA_DMR_DSTT_SC   0x00001800L /* Destination is supervisor code */
+#define MCFDMA_DMR_DSTS_OFF  0x8         /* offset to the destination size bits */
+#define MCFDMA_DMR_DSTS_LONG 0x00000000L /* Long destination size */
+#define MCFDMA_DMR_DSTS_BYTE 0x00000100L /* Byte destination size */
+#define MCFDMA_DMR_DSTS_WORD 0x00000200L /* Word destination size */
+#define MCFDMA_DMR_DSTS_LINE 0x00000300L /* Line destination size */
+#define MCFDMA_DMR_SRCM      0x00000020L /* Source addressing mask */
+#define MCFDMA_DMR_SRCM_SA   0x00000000L /* Source uses static addressing */
+#define MCFDMA_DMR_SRCM_IA   0x00000020L /* Source uses incremental addressing */
+#define MCFDMA_DMR_SRCT_UD   0x00000004L /* Source is user data */
+#define MCFDMA_DMR_SRCT_UC   0x00000008L /* Source is user code */
+#define MCFDMA_DMR_SRCT_SD   0x00000014L /* Source is supervisor data */
+#define MCFDMA_DMR_SRCT_SC   0x00000018L /* Source is supervisor code */
+#define MCFDMA_DMR_SRCS_OFF  0x0         /* Offset to the source size bits */
+#define MCFDMA_DMR_SRCS_LONG 0x00000000L /* Long source size */
+#define MCFDMA_DMR_SRCS_BYTE 0x00000001L /* Byte source size */
+#define MCFDMA_DMR_SRCS_WORD 0x00000002L /* Word source size */
+#define MCFDMA_DMR_SRCS_LINE 0x00000003L /* Line source size */
+
+/* Bit definitions for the DMA interrupt register (DIR) */
+#define MCFDMA_DIR_INVEN     0x1000 /* Invalid Combination interrupt enable */
+#define MCFDMA_DIR_ASCEN     0x0800 /* Address Sequence Complete (Completion) interrupt enable */
+#define MCFDMA_DIR_TEEN      0x0200 /* Transfer Error interrupt enable */
+#define MCFDMA_DIR_TCEN      0x0100 /* Transfer Complete (a bus transfer, that is) interrupt enable */
+#define MCFDMA_DIR_INV       0x1000 /* Invalid Combination */
+#define MCFDMA_DIR_ASC       0x0008 /* Address Sequence Complete (DMA Completion) */
+#define MCFDMA_DIR_TE        0x0002 /* Transfer Error */
+#define MCFDMA_DIR_TC        0x0001 /* Transfer Complete */
+
+#endif /* !defined(CONFIG_M5272) */ 
+
+/****************************************************************************/
+#endif	/* mcfdma_h */
diff -urN linux-2.4.29/include/asm-m68knommu/mcfgpt.h linux-2.4.29-uc1/include/asm-m68knommu/mcfgpt.h
--- linux-2.4.29/include/asm-m68knommu/mcfgpt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mcfgpt.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,53 @@
+/****************************************************************************/
+
+/*
+ *	mcfgpt.h -- ColdFire internal GPT timer support defines.
+ *
+ *	(C) Copyright 2004, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/****************************************************************************/
+#ifndef	mcfgpt_h
+#define	mcfgpt_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Get address specific defines for the 547x.
+ */
+#define	MCFPIT_BASE0		0x800	/* Base address of TIMER0 */
+#define	MCFPIT_BASE1		0x810	/* Base address of TIMER1 */
+#define	MCFPIT_BASE2		0x820	/* Base address of TIMER2 */
+#define	MCFPIT_BASE3		0x830	/* Base address of TIMER3 */
+
+
+/*
+ *	Define the GPT timer register set addresses.
+ */
+struct mcfgpt {
+	unsigned int	gms;			/* Enable and mode select */
+	unsigned int	gcir;			/* Counter input */
+	unsigned int	gpwm;			/* PWM configuration */
+	unsigned int	gsr;			/* Status */
+};
+
+/*
+ *	Bit definitions for the GMS Enable and mode select register.
+ */
+#define	MCFGPT_GMS_ICTANY	0x0000000	/* Input any transition */
+#define	MCFGPT_GMS_ICTUP	0x0000400	/* Input rising edge */
+#define	MCFGPT_GMS_ICTDOWN	0x0000800	/* Input falling edge */
+#define	MCFGPT_GMS_ICTPULSE	0x0000c00	/* Input on pulse */
+#define	MCFGPT_GMS_WDT		0x0001000	/* Watchdog enable */
+#define	MCFGPT_GMS_CE		0x0008000	/* Counter enable */
+#define	MCFGPT_GMS_SC		0x0020000	/* Stop/Continuous mode */
+#define	MCFGPT_GMS_IEN		0x0080000	/* Interrupt enable */
+#define	MCFGPT_GMS_MODE_OFF	0x0000000	/* Disable timer */
+#define	MCFGPT_GMS_MODE_INPUT	0x2000000	/* Input capture mode */
+#define	MCFGPT_GMS_MODE_OUTPUT	0x4000000	/* Output capture mode */
+#define	MCFGPT_GMS_MODE_PWM	0x6000000	/* PWM mode */
+#define	MCFGPT_GMS_MODE_GPIO	0x8000000	/* GPIO mode */
+
+/****************************************************************************/
+#endif	/* mcfgpt_h */
diff -urN linux-2.4.29/include/asm-m68knommu/mcfmbus.h linux-2.4.29-uc1/include/asm-m68knommu/mcfmbus.h
--- linux-2.4.29/include/asm-m68knommu/mcfmbus.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mcfmbus.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,78 @@
+/****************************************************************************/
+
+/*
+ *      mcfmbus.h -- Coldfire MBUS support defines.
+ *
+ *      (C) Copyright 1999, Martin Floeer (mfloeer@axcent.de) 
+ */
+
+/****************************************************************************/
+
+
+#ifndef mcfmbus_h
+#define mcfmbus_h
+#include <linux/config.h>
+
+
+#define MCFMBUS_BASE		0x280
+#define MCFMBUS_IRQ_VECTOR	0x19
+#define MCFMBUS_IRQ		0x1
+#define MCFMBUS_CLK		0x3f
+#define MCFMBUS_IRQ_LEVEL	0x07	/*IRQ Level 1*/
+#define MCFMBUS_ADDRESS		0x01
+
+
+/*
+*	Define the 5307 MBUS register set adresses
+*/
+
+#define MCFMBUS_MADR	0x00
+#define MCFMBUS_MFDR	0x04
+#define MCFMBUS_MBCR	0x08
+#define MCFMBUS_MBSR	0x0C
+#define MCFMBUS_MBDR	0x10
+
+
+#define MCFMBUS_MADR_ADDR(a)	(((a)&0x7F)<<0x01) /*Slave Address*/
+
+#define MCFMBUS_MFDR_MBC(a)	((a)&0x3F)	   /*M-Bus Clock*/
+
+/*
+*	Define bit flags in Controll Register
+*/
+
+#define MCFMBUS_MBCR_MEN           (0x80)  /* M-Bus Enable                 */
+#define MCFMBUS_MBCR_MIEN          (0x40)  /* M-Bus Interrupt Enable       */
+#define MCFMBUS_MBCR_MSTA          (0x20)  /* Master/Slave Mode Select Bit */
+#define MCFMBUS_MBCR_MTX           (0x10)  /* Transmit/Rcv Mode Select Bit */
+#define MCFMBUS_MBCR_TXAK          (0x08)  /* Transmit Acknowledge Enable  */
+#define MCFMBUS_MBCR_RSTA          (0x04)  /* Repeat Start                 */
+
+/*
+*	Define bit flags in Status Register
+*/
+
+#define MCFMBUS_MBSR_MCF           (0x80)  /* Data Transfer Complete       */
+#define MCFMBUS_MBSR_MAAS          (0x40)  /* Addressed as a Slave         */
+#define MCFMBUS_MBSR_MBB           (0x20)  /* Bus Busy                     */
+#define MCFMBUS_MBSR_MAL           (0x10)  /* Arbitration Lost             */
+#define MCFMBUS_MBSR_SRW           (0x04)  /* Slave Transmit               */
+#define MCFMBUS_MBSR_MIF           (0x02)  /* M-Bus Interrupt              */
+#define MCFMBUS_MBSR_RXAK          (0x01)  /* No Acknowledge Received      */
+
+/*
+*	Define bit flags in DATA I/O Register
+*/
+
+#define MCFMBUS_MBDR_READ          (0x01)  /* 1=read 0=write MBUS */
+
+#define MBUSIOCSCLOCK		1
+#define MBUSIOCGCLOCK		2
+#define MBUSIOCSADDR			3
+#define MBUSIOCGADDR			4
+#define MBUSIOCSSLADDR			5
+#define MBUSIOCGSLADDR			6
+#define MBUSIOCSSUBADDR			7
+#define MBUSIOCGSUBADDR			8
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/mcfne.h linux-2.4.29-uc1/include/asm-m68knommu/mcfne.h
--- linux-2.4.29/include/asm-m68knommu/mcfne.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mcfne.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,353 @@
+/****************************************************************************/
+
+/*
+ *	mcfne.h -- NE2000 in ColdFire eval boards.
+ *
+ *	(C) Copyright 1999-2000, Greg Ungerer (gerg@snapgear.com)
+ *	(C) Copyright 2000,      Lineo (www.lineo.com)
+ *	(C) Copyright 2001,      SnapGear (www.snapgear.com)
+ *
+ *      19990409 David W. Miller  Converted from m5206ne.h for 5307 eval board
+ *
+ *      Hacked support for m5206e Cadre III evaluation board
+ *      Fred Stevens (fred.stevens@pemstar.com) 13 April 1999
+ */
+
+/****************************************************************************/
+#ifndef	mcfne_h
+#define	mcfne_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Support for NE2000 clones devices in ColdFire based boards.
+ *	Not all boards address these parts the same way, some use a
+ *	direct addressing method, others use a side-band address space
+ *	to access odd address registers, some require byte swapping
+ *	others do not.
+ */
+#define	BSWAP(w)	(((w) << 8) | ((w) >> 8))
+#define	RSWAP(w)	(w)
+
+
+/*
+ *	Define the basic hardware resources of NE2000 boards.
+ */
+
+#if defined(CONFIG_M5206) && defined(CONFIG_ARNEWSH)
+#define NE2000_ADDR		0x40000300
+#define NE2000_ODDOFFSET	0x00010000
+#define	NE2000_IRQ_VECTOR	0xf0
+#define	NE2000_IRQ_PRIORITY	2
+#define	NE2000_IRQ_LEVEL	4
+#define	NE2000_BYTE		volatile unsigned short
+#endif
+
+#if defined(CONFIG_M5206e) && defined(CONFIG_MOTOROLA)
+#define	NE2000_ADDR		0x40000300
+#define	NE2000_ODDOFFSET	0x00010000
+#define	NE2000_IRQ_VECTOR	0x1c
+#define	NE2000_IRQ_PRIORITY	2
+#define	NE2000_IRQ_LEVEL	4
+#define	NE2000_BYTE		volatile unsigned short
+#endif
+
+#if defined(CONFIG_M5206e) && defined(CONFIG_NETtel)
+#define NE2000_ADDR		0x30000300
+#define NE2000_IRQ_VECTOR	25
+#define NE2000_IRQ_PRIORITY	1
+#define NE2000_IRQ_LEVEL	3
+#define	NE2000_BYTE		volatile unsigned char
+#endif
+
+#if defined(CONFIG_M5206e) && defined(CONFIG_CFV240)
+#define NE2000_ADDR             0x40010000
+#define NE2000_ADDR1            0x40010001
+#define NE2000_ODDOFFSET        0x00000000
+#define NE2000_IRQ              1
+#define NE2000_IRQ_VECTOR       0x19
+#define NE2000_IRQ_PRIORITY     2
+#define NE2000_IRQ_LEVEL        1
+#define	NE2000_BYTE		volatile unsigned char
+#endif
+
+#if defined(CONFIG_M5307) && defined(CONFIG_MOTOROLA)
+#define NE2000_ADDR		0x40000300
+#define NE2000_ODDOFFSET	0x00010000
+#define NE2000_IRQ_VECTOR	0x1b
+#define	NE2000_BYTE		volatile unsigned short
+#endif
+
+#if defined(CONFIG_M5272) && defined(CONFIG_NETtel)
+#define NE2000_ADDR		0x30600300
+#define NE2000_ODDOFFSET	0x00008000
+#define NE2000_IRQ_VECTOR	67
+#undef	BSWAP
+#define	BSWAP(w)		(w)
+#define	NE2000_BYTE		volatile unsigned short
+#undef	RSWAP
+#define	RSWAP(w)		(((w) << 8) | ((w) >> 8))
+#endif
+
+#if defined(CONFIG_M5307) && defined(CONFIG_NETtel)
+#define NE2000_ADDR0		0x30600300
+#define NE2000_ADDR1		0x30800300
+#define NE2000_ODDOFFSET	0x00008000
+#define NE2000_IRQ_VECTOR0	27
+#define NE2000_IRQ_VECTOR1	29
+#undef	BSWAP
+#define	BSWAP(w)		(w)
+#define	NE2000_BYTE		volatile unsigned short
+#undef	RSWAP
+#define	RSWAP(w)		(((w) << 8) | ((w) >> 8))
+#endif
+
+#if defined(CONFIG_M5307) && defined(CONFIG_SECUREEDGEMP3)
+#define NE2000_ADDR		0x30600300
+#define NE2000_ODDOFFSET	0x00008000
+#define NE2000_IRQ_VECTOR	27
+#undef	BSWAP
+#define	BSWAP(w)		(w)
+#define	NE2000_BYTE		volatile unsigned short
+#undef	RSWAP
+#define	RSWAP(w)		(((w) << 8) | ((w) >> 8))
+#endif
+
+#if defined(CONFIG_M5307) && defined(CONFIG_ARNEWSH)
+#define NE2000_ADDR		0xfe600300
+#define NE2000_ODDOFFSET	0x00010000
+#define NE2000_IRQ_VECTOR	0x1b
+#define NE2000_IRQ_PRIORITY	2
+#define NE2000_IRQ_LEVEL	3
+#define	NE2000_BYTE		volatile unsigned short
+#endif
+
+#if defined(CONFIG_M5407)
+#define NE2000_ADDR		0x40000300
+#define NE2000_ODDOFFSET	0x00010000
+#define NE2000_IRQ_VECTOR	0x1b
+#define	NE2000_BYTE		volatile unsigned short
+#endif
+
+/****************************************************************************/
+
+/*
+ *	Side-band address space for odd address requires re-mapping
+ *	many of the standard ISA access functions.
+ */
+#ifdef NE2000_ODDOFFSET
+
+#undef outb
+#undef outb_p
+#undef inb
+#undef inb_p
+#undef outsb
+#undef outsw
+#undef insb
+#undef insw
+
+#define	outb	ne2000_outb
+#define	inb	ne2000_inb
+#define	outb_p	ne2000_outb
+#define	inb_p	ne2000_inb
+#define	outsb	ne2000_outsb
+#define	outsw	ne2000_outsw
+#define	insb	ne2000_insb
+#define	insw	ne2000_insw
+
+
+#ifndef COLDFIRE_NE2000_FUNCS
+
+void ne2000_outb(unsigned int val, unsigned int addr);
+int  ne2000_inb(unsigned int addr);
+void ne2000_insb(unsigned int addr, void *vbuf, int unsigned long len);
+void ne2000_insw(unsigned int addr, void *vbuf, unsigned long len);
+void ne2000_outsb(unsigned int addr, void *vbuf, unsigned long len);
+void ne2000_outsw(unsigned int addr, void *vbuf, unsigned long len);
+
+#else
+
+/*
+ *	This macro converts a conventional register address into the
+ *	real memory pointer of the mapped NE2000 device.
+ *	On most NE2000 implementations on ColdFire boards the chip is
+ *	mapped in kinda funny, due to its ISA heritage.
+ */
+#ifdef CONFIG_CFV240
+#define NE2000_PTR(addr)	(NE2000_ADDR + ((addr & 0x3f) << 1) + 1)
+#define NE2000_DATA_PTR(addr)	(NE2000_ADDR + ((addr & 0x3f) << 1))
+#else
+#define	NE2000_PTR(addr)	((addr&0x1)?(NE2000_ODDOFFSET+addr-1):(addr))
+#define	NE2000_DATA_PTR(addr)	(addr)
+#endif
+
+
+void ne2000_outb(unsigned int val, unsigned int addr)
+{
+	NE2000_BYTE	*rp;
+
+	rp = (NE2000_BYTE *) NE2000_PTR(addr);
+	*rp = RSWAP(val);
+}
+
+int ne2000_inb(unsigned int addr)
+{
+	NE2000_BYTE	*rp, val;
+
+	rp = (NE2000_BYTE *) NE2000_PTR(addr);
+	val = *rp;
+	return((int) ((NE2000_BYTE) RSWAP(val)));
+}
+
+void ne2000_insb(unsigned int addr, void *vbuf, int unsigned long len)
+{
+	NE2000_BYTE	*rp, val;
+	unsigned char	*buf;
+
+	buf = (unsigned char *) vbuf;
+	rp = (NE2000_BYTE *) NE2000_DATA_PTR(addr);
+	for (; (len > 0); len--) {
+		val = *rp;
+		*buf++ = RSWAP(val);
+	}
+}
+
+void ne2000_insw(unsigned int addr, void *vbuf, unsigned long len)
+{
+	volatile unsigned short	*rp;
+	unsigned short		w, *buf;
+
+	buf = (unsigned short *) vbuf;
+	rp = (volatile unsigned short *) NE2000_DATA_PTR(addr);
+	for (; (len > 0); len--) {
+		w = *rp;
+		*buf++ = BSWAP(w);
+	}
+}
+
+void ne2000_outsb(unsigned int addr, const void *vbuf, unsigned long len)
+{
+	NE2000_BYTE	*rp, val;
+	unsigned char	*buf;
+
+	buf = (unsigned char *) vbuf;
+	rp = (NE2000_BYTE *) NE2000_DATA_PTR(addr);
+	for (; (len > 0); len--) {
+		val = *buf++;
+		*rp = RSWAP(val);
+	}
+}
+
+void ne2000_outsw(unsigned int addr, const void *vbuf, unsigned long len)
+{
+	volatile unsigned short	*rp;
+	unsigned short		w, *buf;
+
+	buf = (unsigned short *) vbuf;
+	rp = (volatile unsigned short *) NE2000_DATA_PTR(addr);
+	for (; (len > 0); len--) {
+		w = *buf++;
+		*rp = BSWAP(w);
+	}
+}
+
+#endif /* COLDFIRE_NE2000_FUNCS */
+#endif /* NE2000_OFFOFFSET */
+
+/****************************************************************************/
+
+#ifdef COLDFIRE_NE2000_FUNCS
+
+/*
+ *	Lastly the interrupt set up code...
+ *	Minor diferences between the different board types.
+ */
+
+#if defined(CONFIG_M5206) && defined(CONFIG_ARNEWSH)
+void ne2000_irqsetup(int irq)
+{
+	volatile unsigned char  *icrp;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4);
+	*icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2;
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4);
+}
+#endif
+
+#if defined(CONFIG_M5206e) && defined(CONFIG_MOTOROLA)
+void ne2000_irqsetup(int irq)
+{
+	volatile unsigned char  *icrp;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4);
+	*icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2 | MCFSIM_ICR_AUTOVEC;
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4);
+}
+#endif
+
+#if defined(CONFIG_M5206e) && defined(CONFIG_CFV240)
+void ne2000_irqsetup(int irq)
+{
+	volatile unsigned char  *icrp;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = MCFSIM_ICR_LEVEL1 | MCFSIM_ICR_PRI2 | MCFSIM_ICR_AUTOVEC;
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT1);
+}
+#endif
+
+#if defined(CONFIG_M5206e) && defined(CONFIG_NETtel)
+void ne2000_irqsetup(int irq)
+{
+	mcf_autovector(irq);
+}
+#endif
+
+#if defined(CONFIG_M5272) && defined(CONFIG_NETtel)
+void ne2000_irqsetup(int irq)
+{
+	volatile unsigned long	*icrp;
+	volatile unsigned long	*pitr;
+
+	/* The NE2000 device uses external IRQ3 */
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x77077777) | 0x00d00000;
+
+	pitr = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PITR);
+	*pitr = *pitr | 0x20000000;
+}
+
+void ne2000_irqack(int irq)
+{
+	volatile unsigned long	*icrp;
+
+	/* The NE2000 device uses external IRQ3 */
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
+	*icrp = (*icrp & 0x77777777) | 0x00800000;
+}
+#endif
+
+#if defined(CONFIG_M5307) || defined(CONFIG_M5407)
+#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3)
+
+void ne2000_irqsetup(int irq)
+{
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3);
+	mcf_autovector(irq);
+}
+
+#else
+
+void ne2000_irqsetup(int irq)
+{
+	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3);
+}
+
+#endif /* ! CONFIG_NETtel || CONFIG_SECUREEDGEMP3 */
+#endif /* CONFIG_M5307 || CONFIG_M5407 */
+
+#endif /* COLDFIRE_NE2000_FUNCS */
+
+/****************************************************************************/
+#endif	/* mcfne_h */
diff -urN linux-2.4.29/include/asm-m68knommu/mcfpci.h linux-2.4.29-uc1/include/asm-m68knommu/mcfpci.h
--- linux-2.4.29/include/asm-m68knommu/mcfpci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mcfpci.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,120 @@
+/****************************************************************************/
+
+/*
+ *	mcfpci.h -- PCI bridge on ColdFire eval boards.
+ *
+ *	(C) Copyright 2000, Greg Ungerer (gerg@snapgear.com)
+ *	(C) Copyright 2000, Lineo Inc. (www.lineo.com)
+ */
+
+/****************************************************************************/
+#ifndef	mcfpci_h
+#define	mcfpci_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+#ifdef CONFIG_PCI
+
+/*
+ *	Address regions in the PCI addres space are not mapped into the
+ *	normal memory space of the ColdFire. They must be accessed via
+ *	handler routines. This is easy for I/O space (inb/outb/etc) but
+ *	needs some code changes to support ordinary memory. Interrupts
+ *	also need to be vectored through the PCI handler first, then it
+ *	will call the actual driver sub-handlers.
+ */
+
+/*
+ *	Un-define all the standard I/O access routines.
+ */
+#undef	inb
+#undef	inw
+#undef	inl
+#undef	inb_p
+#undef	inw_p
+#undef	insb
+#undef	insw
+#undef	insl
+#undef	outb
+#undef	outw
+#undef	outl
+#undef	outb_p
+#undef	outw_p
+#undef	outsb
+#undef	outsw
+#undef	outsl
+
+#undef	request_irq
+#undef	free_irq
+
+#undef	bus_to_virt
+#undef	virt_to_bus
+
+
+/*
+ *	Re-direct all I/O memory accesses functions to PCI specific ones.
+ */
+#define	inb	pci_inb
+#define	inw	pci_inw
+#define	inl	pci_inl
+#define	inb_p	pci_inb
+#define	inw_p	pci_inw
+#define	insb	pci_insb
+#define	insw	pci_insw
+#define	insl	pci_insl
+
+#define	outb	pci_outb
+#define	outw	pci_outw
+#define	outl	pci_outl
+#define	outb_p	pci_outb
+#define	outw_p	pci_outw
+#define	outsb	pci_outsb
+#define	outsw	pci_outsw
+#define	outsl	pci_outsl
+
+#define	request_irq	pci_request_irq
+#define	free_irq	pci_free_irq
+
+#define	virt_to_bus	pci_virt_to_bus
+#define	bus_to_virt	pci_bus_to_virt
+
+#define	CONFIG_COMEMPCI	1
+
+
+/*
+ *	Prototypes of the real PCI functions (defined in bios32.c).
+ */
+unsigned char	pci_inb(unsigned int addr);
+unsigned short	pci_inw(unsigned int addr);
+unsigned int	pci_inl(unsigned int addr);
+void		pci_insb(void *addr, void *buf, int len);
+void		pci_insw(void *addr, void *buf, int len);
+void		pci_insl(void *addr, void *buf, int len);
+
+void		pci_outb(unsigned char val, unsigned int addr);
+void		pci_outw(unsigned short val, unsigned int addr);
+void		pci_outl(unsigned int val, unsigned int addr);
+void		pci_outsb(void *addr, void *buf, int len);
+void		pci_outsw(void *addr, void *buf, int len);
+void		pci_outsl(void *addr, void *buf, int len);
+
+int		pci_request_irq(unsigned int irq,
+			void (*handler)(int, void *, struct pt_regs *),
+			unsigned long flags,
+			const char *device,
+			void *dev_id);
+void		pci_free_irq(unsigned int irq, void *dev_id);
+
+void		*pci_bmalloc(int size);
+void		pci_bmfree(void *bmp, int len);
+void		pci_copytoshmem(unsigned long bmp, void *src, int size);
+void		pci_copyfromshmem(void *dst, unsigned long bmp, int size);
+unsigned long	pci_virt_to_bus(volatile void *address);
+void		*pci_bus_to_virt(unsigned long address);
+void		pci_bmcpyto(void *dst, void *src, int len);
+void		pci_bmcpyfrom(void *dst, void *src, int len);
+
+#endif /* CONFIG_PCI */
+/****************************************************************************/
+#endif	/* mcfpci_h */
diff -urN linux-2.4.29/include/asm-m68knommu/mcfpit.h linux-2.4.29-uc1/include/asm-m68knommu/mcfpit.h
--- linux-2.4.29/include/asm-m68knommu/mcfpit.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mcfpit.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,63 @@
+/****************************************************************************/
+
+/*
+ *	mcfpit.h -- ColdFire internal PIT timer support defines.
+ *
+ *	(C) Copyright 2003, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/****************************************************************************/
+#ifndef	mcfpit_h
+#define	mcfpit_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Get address specific defines for the 5282 and 527x.
+ */
+#define	MCFPIT_BASE1		0x00150000	/* Base address of TIMER1 */
+#define	MCFPIT_BASE2		0x00160000	/* Base address of TIMER2 */
+#define	MCFPIT_BASE3		0x00170000	/* Base address of TIMER3 */
+#define	MCFPIT_BASE4		0x00180000	/* Base address of TIMER4 */
+
+
+/*
+ *	Define the PIT timer register set addresses.
+ */
+struct mcfpit {
+	unsigned short	pcsr;			/* PIT control and status */
+	unsigned short	pmr;			/* PIT modulus register */
+	unsigned short	pcntr;			/* PIT count register */
+};
+
+/*
+ *	Bit definitions for the PIT Control and Status register.
+ */
+#define	MCFPIT_PCSR_CLK1	0x0000		/* System clock divisor */
+#define	MCFPIT_PCSR_CLK2	0x0100		/* System clock divisor */
+#define	MCFPIT_PCSR_CLK4	0x0200		/* System clock divisor */
+#define	MCFPIT_PCSR_CLK8	0x0300		/* System clock divisor */
+#define	MCFPIT_PCSR_CLK16	0x0400		/* System clock divisor */
+#define	MCFPIT_PCSR_CLK32	0x0500		/* System clock divisor */
+#define	MCFPIT_PCSR_CLK64	0x0600		/* System clock divisor */
+#define	MCFPIT_PCSR_CLK128	0x0700		/* System clock divisor */
+#define	MCFPIT_PCSR_CLK256	0x0800		/* System clock divisor */
+#define	MCFPIT_PCSR_CLK512	0x0900		/* System clock divisor */
+#define	MCFPIT_PCSR_CLK1024	0x0a00		/* System clock divisor */
+#define	MCFPIT_PCSR_CLK2048	0x0b00		/* System clock divisor */
+#define	MCFPIT_PCSR_CLK4096	0x0c00		/* System clock divisor */
+#define	MCFPIT_PCSR_CLK8192	0x0d00		/* System clock divisor */
+#define	MCFPIT_PCSR_CLK16384	0x0e00		/* System clock divisor */
+#define	MCFPIT_PCSR_CLK32768	0x0f00		/* System clock divisor */
+#define	MCFPIT_PCSR_DOZE	0x0040		/* Clock run in doze mode */
+#define	MCFPIT_PCSR_HALTED	0x0020		/* Clock run in halt mode */
+#define	MCFPIT_PCSR_OVW		0x0010		/* Overwrite PIT counter now */
+#define	MCFPIT_PCSR_PIE		0x0008		/* Enable PIT interrupt */
+#define	MCFPIT_PCSR_PIF		0x0004		/* PIT interrupt flag */
+#define	MCFPIT_PCSR_RLD		0x0002		/* Reload counter */
+#define	MCFPIT_PCSR_EN		0x0001		/* Enable PIT */
+#define	MCFPIT_PCSR_DISABLE	0x0000		/* Disable PIT */
+
+/****************************************************************************/
+#endif	/* mcfpit_h */
diff -urN linux-2.4.29/include/asm-m68knommu/mcfqspi.h linux-2.4.29-uc1/include/asm-m68knommu/mcfqspi.h
--- linux-2.4.29/include/asm-m68knommu/mcfqspi.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mcfqspi.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,32 @@
+#if !defined(MCFQSPI_H)
+#define MCFQSPI_H
+
+#include <linux/config.h>
+#include <linux/types.h>
+
+
+#define QSPIIOCS_DOUT_HIZ       1       /* QMR[DOHIE] set hi-z dout between transfers */
+#define QSPIIOCS_BITS           2       /* QMR[BITS] set transfer size */
+#define QSPIIOCG_BITS           3       /* QMR[BITS] get transfer size */
+#define QSPIIOCS_CPOL           4       /* QMR[CPOL] set SCK inactive state */
+#define QSPIIOCS_CPHA           5       /* QMR[CPHA] set SCK phase, 1=rising edge */
+#define QSPIIOCS_BAUD           6       /* QMR[BAUD] set SCK baud rate divider */
+#define QSPIIOCS_QCD            7       /* QDLYR[QCD] set start delay */
+#define QSPIIOCS_DTL            8       /* QDLYR[DTL] set after delay */
+#define QSPIIOCS_CONT           9       /* continuous CS asserted during transfer */
+#define QSPIIOCS_READDATA       10      /* set data send during read */
+#define QSPIIOCS_ODD_MOD        11      /* if length of buffer is a odd number, 16-bit transfers */
+                                        /* are finalized with a 8-bit transfer */
+#define QSPIIOCS_DSP_MOD        12      /* transfers are bounded to 15/30 bytes (a multiple of 3 bytes = 1 DSP word) */
+#define QSPIIOCS_POLL_MOD       13      /* driver uses polling instead of interrupts */
+
+
+typedef struct qspi_read_data {
+        __u32 length;
+        __u8 buf[32];                   /* data to send during read */
+        unsigned int loop : 1;
+} qspi_read_data;
+
+
+#endif  /* MCFQSPI_H */
+
diff -urN linux-2.4.29/include/asm-m68knommu/mcfsim.h linux-2.4.29-uc1/include/asm-m68knommu/mcfsim.h
--- linux-2.4.29/include/asm-m68knommu/mcfsim.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mcfsim.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,112 @@
+/****************************************************************************/
+
+/*
+ *	mcfsim.h -- ColdFire System Integration Module support.
+ *
+ *	(C) Copyright 1999-2004, Greg Ungerer (gerg@snapgear.com)
+ * 	(C) Copyright 2000, Lineo Inc. (www.lineo.com) 
+ */
+
+/****************************************************************************/
+#ifndef	mcfsim_h
+#define	mcfsim_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Include ColdFire CPU specific addresses.
+ */
+#if defined(CONFIG_M5204)
+#include <asm/m5204sim.h>
+#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e)
+#include <asm/m5206sim.h>
+#elif defined(CONFIG_M5249)
+#include <asm/m5249sim.h>
+#elif defined(CONFIG_M5272)
+#include <asm/m5272sim.h>
+#elif defined(CONFIG_M527x)
+#include <asm/m527xsim.h>
+#elif defined(CONFIG_M5282) || defined(CONFIG_M5280)
+#include <asm/m5282sim.h>
+#elif defined(CONFIG_M5235)
+#include <asm/m5235sim.h>
+#elif defined(CONFIG_M5307)
+#include <asm/m5307sim.h>
+#elif defined(CONFIG_M5407)
+#include <asm/m5407sim.h>
+#elif defined(CONFIG_M547x)
+#include <asm/m547xsim.h>
+#endif
+
+
+/*
+ *	Define the base address of the SIM within the MBAR address space.
+ */
+#define	MCFSIM_BASE		0x0		/* Base address of SIM */
+
+
+/*
+ *	Bit definitions for the ICR family of registers.
+ */
+#define	MCFSIM_ICR_AUTOVEC	0x80		/* Auto-vectored intr */
+#define	MCFSIM_ICR_LEVEL0	0x00		/* Level 0 intr */
+#define	MCFSIM_ICR_LEVEL1	0x04		/* Level 1 intr */
+#define	MCFSIM_ICR_LEVEL2	0x08		/* Level 2 intr */
+#define	MCFSIM_ICR_LEVEL3	0x0c		/* Level 3 intr */
+#define	MCFSIM_ICR_LEVEL4	0x10		/* Level 4 intr */
+#define	MCFSIM_ICR_LEVEL5	0x14		/* Level 5 intr */
+#define	MCFSIM_ICR_LEVEL6	0x18		/* Level 6 intr */
+#define	MCFSIM_ICR_LEVEL7	0x1c		/* Level 7 intr */
+
+#define	MCFSIM_ICR_PRI0		0x00		/* Priority 0 intr */
+#define	MCFSIM_ICR_PRI1		0x01		/* Priority 1 intr */
+#define	MCFSIM_ICR_PRI2		0x02		/* Priority 2 intr */
+#define	MCFSIM_ICR_PRI3		0x03		/* Priority 3 intr */
+
+/*
+ *	Bit definitions for the Interrupt Mask register (IMR).
+ */
+#define	MCFSIM_IMR_EINT1	0x0002		/* External intr # 1 */
+#define	MCFSIM_IMR_EINT2	0x0004		/* External intr # 2 */
+#define	MCFSIM_IMR_EINT3	0x0008		/* External intr # 3 */
+#define	MCFSIM_IMR_EINT4	0x0010		/* External intr # 4 */
+#define	MCFSIM_IMR_EINT5	0x0020		/* External intr # 5 */
+#define	MCFSIM_IMR_EINT6	0x0040		/* External intr # 6 */
+#define	MCFSIM_IMR_EINT7	0x0080		/* External intr # 7 */
+
+#define	MCFSIM_IMR_SWD		0x0100		/* Software Watchdog intr */
+#define	MCFSIM_IMR_TIMER1	0x0200		/* TIMER 1 intr */
+#define	MCFSIM_IMR_TIMER2	0x0400		/* TIMER 2 intr */
+#define MCFSIM_IMR_MBUS		0x0800		/* MBUS intr	*/
+#define	MCFSIM_IMR_UART1	0x1000		/* UART 1 intr */
+#define	MCFSIM_IMR_UART2	0x2000		/* UART 2 intr */
+
+#if defined(CONFIG_M5206e)
+#define	MCFSIM_IMR_DMA1		0x4000		/* DMA 1 intr */
+#define	MCFSIM_IMR_DMA2		0x8000		/* DMA 2 intr */
+#elif defined(CONFIG_M5249) || defined(CONFIG_M5307)
+#define	MCFSIM_IMR_DMA0		0x4000		/* DMA 0 intr */
+#define	MCFSIM_IMR_DMA1		0x8000		/* DMA 1 intr */
+#define	MCFSIM_IMR_DMA2		0x10000		/* DMA 2 intr */
+#define	MCFSIM_IMR_DMA3		0x20000		/* DMA 3 intr */
+#endif
+
+/*
+ *	Mask for all of the SIM devices. Some parts have more or less
+ *	SIM devices. This is a catchall for the sandard set.
+ */
+#ifndef MCFSIM_IMR_MASKALL
+#define	MCFSIM_IMR_MASKALL	0x3ffe		/* All intr sources */
+#endif
+
+
+#ifndef __ASSEMBLY__
+/*
+ *	Definition for the interrupt auto-vectoring support.
+ */
+extern void	mcf_autovector(unsigned int vec);
+#endif /* __ASSEMBLY__ */
+
+/****************************************************************************/
+#endif	/* mcfsim_h */
diff -urN linux-2.4.29/include/asm-m68knommu/mcfslt.h linux-2.4.29-uc1/include/asm-m68knommu/mcfslt.h
--- linux-2.4.29/include/asm-m68knommu/mcfslt.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mcfslt.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,45 @@
+/****************************************************************************/
+
+/*
+ *	mcfslt.h -- ColdFire internal Slice (SLT) timer support defines.
+ *
+ *	(C) Copyright 2004, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/****************************************************************************/
+#ifndef	mcfslt_h
+#define	mcfslt_h
+/****************************************************************************/
+
+/*
+ *	Get address specific defines for the 547x.
+ */
+#define	MCFSLT_TIMER0		0x900	/* Base address of TIMER0 */
+#define	MCFSLT_TIMER1		0x910	/* Base address of TIMER1 */
+
+
+/*
+ *	Define the SLT timer register set addresses.
+ */
+struct mcfslt {
+	unsigned int	stcnt;			/* Terminal count */
+	unsigned int	scr;			/* Control */
+	unsigned int	scnt;			/* Current count */
+	unsigned int	ssr;			/* Status */
+};
+
+/*
+ *	Bit definitions for the SCR control register.
+ */
+#define	MCFSLT_SCR_RUN		0x04000000	/* Run mode (continuous) */
+#define	MCFSLT_SCR_IEN		0x02000000	/* Interrupt enable */
+#define	MCFSLT_SCR_TEN		0x01000000	/* Timer enable */
+
+/*
+ *	Bit definitions for the SSR status register.
+ */
+#define	MCFSLT_SSR_BE		0x02000000	/* Bus error condition */
+#define	MCFSLT_SSR_TE		0x01000000	/* Timeout condition */
+
+/****************************************************************************/
+#endif	/* mcfslt_h */
diff -urN linux-2.4.29/include/asm-m68knommu/mcfsmc.h linux-2.4.29-uc1/include/asm-m68knommu/mcfsmc.h
--- linux-2.4.29/include/asm-m68knommu/mcfsmc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mcfsmc.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,184 @@
+/****************************************************************************/
+
+/*
+ *	mcfsmc.h -- SMC ethernet support for ColdFire environments.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *	(C) Copyright 2000, Lineo Inc. (www.lineo.com) 
+ */
+
+/****************************************************************************/
+#ifndef	mcfsmc_h
+#define	mcfsmc_h
+/****************************************************************************/
+
+/*
+ *	None of the current ColdFire targets that use the SMC91x111
+ *	allow 8 bit accesses. So this code is 16bit access only.
+ */
+
+#include <linux/config.h>
+
+#undef	outb
+#undef	inb
+
+/*
+ *	Re-defines for ColdFire environment... The SMC part is
+ *	mapped into memory space, so remap the PC-style in/out
+ *	routines to handle that.
+ */
+#define	outb	smc_outb
+#define	inb	smc_inb
+#define	outw	smc_outw
+#define	outwd	smc_outwd
+#define	inw	smc_inw
+#define	outl	smc_outl
+#define	inl	smc_inl
+
+#define	outsb	smc_outsb
+#define	outsw	smc_outsw
+#define	outsl	smc_outsl
+#define	insb	smc_insb
+#define	insw	smc_insw
+#define	insl	smc_insl
+
+
+static inline int smc_inb(unsigned int addr)
+{
+	register unsigned short	w;
+	w = *((volatile unsigned short *) (addr & ~0x1));
+	return(((addr & 0x1) ? w : (w >> 8)) & 0xff);
+}
+
+static inline void smc_outw(unsigned int val, unsigned int addr)
+{
+	*((volatile unsigned short *) addr) = (val << 8) | (val >> 8);
+}
+
+static inline int smc_inw(unsigned int addr)
+{
+	register unsigned short	w;
+	w = *((volatile unsigned short *) addr);
+	return(((w << 8) | (w >> 8)) & 0xffff);
+}
+
+static inline int smc_inl(unsigned int addr)
+{
+	register unsigned long	v;
+	v = *((volatile unsigned long *) addr);
+	return((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) |
+			(v >> 24));
+}
+
+static inline void smc_outl(unsigned long val, unsigned int addr)
+{
+	*((volatile unsigned long *) addr) = 
+		((val << 8) & 0xff000000) | ((val >> 8) & 0x00ff0000) |
+		((val << 8) & 0x0000ff00) | ((val >> 8) & 0x000000ff);
+}
+
+static inline void smc_outwd(unsigned int val, unsigned int addr)
+{
+	*((volatile unsigned short *) addr) = val;
+}
+
+
+/*
+ *	The rep* functions are used to feed the data port with
+ *	raw data. So we do not byte swap them when copying.
+ */
+
+static inline void smc_insb(unsigned int addr, void *vbuf, int unsigned long len)
+{
+	volatile unsigned short	*rp;
+	unsigned short		*buf, *ebuf;
+
+	buf = (unsigned short *) vbuf;
+	rp = (volatile unsigned short *) addr;
+
+	/* Copy as words for as long as possible */
+	for (ebuf = buf + (len >> 1); (buf < ebuf); )
+		*buf++ = *rp;
+
+	/* Lastly, handle left over byte */
+	if (len & 0x1)
+		*((unsigned char *) buf) = (*rp >> 8) & 0xff;
+}
+
+static inline void smc_insw(unsigned int addr, void *vbuf, unsigned long len)
+{
+	volatile unsigned short	*rp;
+	unsigned short		*buf, *ebuf;
+
+	buf = (unsigned short *) vbuf;
+	rp = (volatile unsigned short *) addr;
+	for (ebuf = buf + len; (buf < ebuf); )
+		*buf++ = *rp;
+}
+
+static inline void smc_insl(unsigned int addr, void *vbuf, unsigned long len)
+{
+	volatile unsigned long	*rp;
+	unsigned long		*buf, *ebuf;
+
+	buf = (unsigned long *) vbuf;
+	rp = (volatile unsigned long *) addr;
+	for (ebuf = buf + len; (buf < ebuf); )
+		*buf++ = *rp;
+}
+
+static inline void smc_outsw(unsigned int addr, const void *vbuf, unsigned long len)
+{
+	volatile unsigned short	*rp;
+	unsigned short		*buf, *ebuf;
+
+	buf = (unsigned short *) vbuf;
+	rp = (volatile unsigned short *) addr;
+	for (ebuf = buf + len; (buf < ebuf); )
+		*rp = *buf++;
+}
+
+static inline void smc_outsl(unsigned int addr, void *vbuf, unsigned long len)
+{
+	volatile unsigned long	*rp;
+	unsigned long		*buf, *ebuf;
+
+	buf = (unsigned long *) vbuf;
+	rp = (volatile unsigned long *) addr;
+	for (ebuf = buf + len; (buf < ebuf); )
+		*rp = *buf++;
+}
+
+
+#ifdef CONFIG_NETtel
+/*
+ *	Re-map the address space of at least one of the SMC ethernet
+ *	parts. Both parts power up decoding the same address, so we
+ *	need to move one of them first, before doing enything else.
+ *
+ *	We also increase the number of wait states for this part by one.
+ */
+
+void smc_remap(unsigned int ioaddr)
+{
+	static int		once = 0;
+	extern unsigned short	ppdata;
+	if (once++ == 0) {
+		*((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADDR)) = 0x00ec;
+		ppdata |= 0x0080;
+		*((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata;
+		outw(0x0001, ioaddr + BANK_SELECT);
+		outw(0x0001, ioaddr + BANK_SELECT);
+		outw(0x0067, ioaddr + BASE);
+
+		ppdata &= ~0x0080;
+		*((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata;
+	}
+	
+	*((volatile unsigned short *)(MCF_MBAR+MCFSIM_CSCR3)) = 0x1180;
+}
+
+#endif
+
+/****************************************************************************/
+#endif	/* mcfsmc_h */
diff -urN linux-2.4.29/include/asm-m68knommu/mcftimer.h linux-2.4.29-uc1/include/asm-m68knommu/mcftimer.h
--- linux-2.4.29/include/asm-m68knommu/mcftimer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mcftimer.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,73 @@
+/****************************************************************************/
+
+/*
+ *	mcftimer.h -- ColdFire internal TIMER support defines.
+ *
+ *	(C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com)
+ * 	(C) Copyright 2000, Lineo Inc. (www.lineo.com) 
+ */
+
+/****************************************************************************/
+#ifndef	mcftimer_h
+#define	mcftimer_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Get address specific defines for this ColdFire member.
+ */
+#if defined(CONFIG_M5204) || defined(CONFIG_M5206) || defined(CONFIG_M5206e)
+#define	MCFTIMER_BASE1		0x100		/* Base address of TIMER1 */
+#define	MCFTIMER_BASE2		0x120		/* Base address of TIMER2 */
+#elif defined(CONFIG_M5272)
+#define MCFTIMER_BASE1		0x200           /* Base address of TIMER1 */
+#define MCFTIMER_BASE2		0x220           /* Base address of TIMER2 */
+#define MCFTIMER_BASE3		0x240           /* Base address of TIMER4 */
+#define MCFTIMER_BASE4		0x260           /* Base address of TIMER3 */
+#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407)
+#define MCFTIMER_BASE1		0x140           /* Base address of TIMER1 */
+#define MCFTIMER_BASE2		0x180           /* Base address of TIMER2 */
+#endif
+
+
+/*
+ *	Define the TIMER register set addresses.
+ */
+#define	MCFTIMER_TMR		0x00		/* Timer Mode reg (r/w) */
+#define	MCFTIMER_TRR		0x02		/* Timer Reference (r/w) */
+#define	MCFTIMER_TCR		0x04		/* Timer Capture reg (r/w) */
+#define	MCFTIMER_TCN		0x06		/* Timer Counter reg (r/w) */
+#define	MCFTIMER_TER		0x11		/* Timer Event reg (r/w) */
+
+
+/*
+ *	Bit definitions for the Timer Mode Register (TMR).
+ *	Register bit flags are common accross ColdFires.
+ */
+#define	MCFTIMER_TMR_PREMASK	0xff00		/* Prescalar mask */
+#define	MCFTIMER_TMR_DISCE	0x0000		/* Disable capture */
+#define	MCFTIMER_TMR_ANYCE	0x00c0		/* Capture any edge */
+#define	MCFTIMER_TMR_FALLCE	0x0080		/* Capture fallingedge */
+#define	MCFTIMER_TMR_RISECE	0x0040		/* Capture rising edge */
+#define	MCFTIMER_TMR_ENOM	0x0020		/* Enable output toggle */
+#define	MCFTIMER_TMR_DISOM	0x0000		/* Do single output pulse  */
+#define	MCFTIMER_TMR_ENORI	0x0010		/* Enable ref interrupt */
+#define	MCFTIMER_TMR_DISORI	0x0000		/* Disable ref interrupt */
+#define	MCFTIMER_TMR_RESTART	0x0008		/* Restart counter */
+#define	MCFTIMER_TMR_FREERUN	0x0000		/* Free running counter */
+#define	MCFTIMER_TMR_CLKTIN	0x0006		/* Input clock is TIN */
+#define	MCFTIMER_TMR_CLK16	0x0004		/* Input clock is /16 */
+#define	MCFTIMER_TMR_CLK1	0x0002		/* Input clock is /1 */
+#define	MCFTIMER_TMR_CLKSTOP	0x0000		/* Stop counter */
+#define	MCFTIMER_TMR_ENABLE	0x0001		/* Enable timer */
+#define	MCFTIMER_TMR_DISABLE	0x0000		/* Disable timer */
+
+/*
+ *	Bit definitions for the Timer Event Registers (TER).
+ */
+#define	MCFTIMER_TER_CAP	0x01		/* Capture event */
+#define	MCFTIMER_TER_REF	0x02		/* Refernece event */
+
+/****************************************************************************/
+#endif	/* mcftimer_h */
diff -urN linux-2.4.29/include/asm-m68knommu/mcfuart.h linux-2.4.29-uc1/include/asm-m68knommu/mcfuart.h
--- linux-2.4.29/include/asm-m68knommu/mcfuart.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mcfuart.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,206 @@
+/****************************************************************************/
+
+/*
+ *	mcfuart.h -- ColdFire internal UART support defines.
+ *
+ *	(C) Copyright 1999-2004, Greg Ungerer (gerg@snapgear.com)
+ * 	(C) Copyright 2000, Lineo Inc. (www.lineo.com) 
+ */
+
+/****************************************************************************/
+#ifndef	mcfuart_h
+#define	mcfuart_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	Define the base address of the UARTS within the MBAR address
+ *	space.
+ */
+#if defined(CONFIG_M5272)
+#define	MCFUART_BASE1		0x100		/* Base address of UART1 */
+#define	MCFUART_BASE2		0x140		/* Base address of UART2 */
+#elif defined(CONFIG_M5204) || defined(CONFIG_M5206) || defined(CONFIG_M5206e)
+#if defined(CONFIG_NETtel)
+#define	MCFUART_BASE1		0x180		/* Base address of UART1 */
+#define	MCFUART_BASE2		0x140		/* Base address of UART2 */
+#else
+#define	MCFUART_BASE1		0x140		/* Base address of UART1 */
+#define	MCFUART_BASE2		0x180		/* Base address of UART2 */
+#endif
+#elif defined(CONFIG_M5235) || defined(CONFIG_M527x) || \
+      defined(CONFIG_M5282) || defined(CONFIG_M5280)
+#define MCFUART_BASE1		0x200           /* Base address of UART1 */
+#define MCFUART_BASE2		0x240           /* Base address of UART2 */
+#define MCFUART_BASE3		0x280           /* Base address of UART3 */
+#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407)
+#if defined(CONFIG_NETtel) || defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3)
+#define MCFUART_BASE1		0x200           /* Base address of UART1 */
+#define MCFUART_BASE2		0x1c0           /* Base address of UART2 */
+#else
+#define MCFUART_BASE1		0x1c0           /* Base address of UART1 */
+#define MCFUART_BASE2		0x200           /* Base address of UART2 */
+#endif
+#elif defined(CONFIG_M547x)
+#define MCFUART_BASE1		0x8600           /* Base address of UART1 */
+#define MCFUART_BASE2		0x8700           /* Base address of UART2 */
+#define MCFUART_BASE3		0x8800           /* Base address of UART3 */
+#define MCFUART_BASE4		0x8900           /* Base address of UART4 */
+#endif
+
+
+/*
+ *	Define the ColdFire UART register set addresses.
+ */
+#define	MCFUART_UMR		0x00		/* Mode register (r/w) */
+#define	MCFUART_USR		0x04		/* Status register (r) */
+#define	MCFUART_UCSR		0x04		/* Clock Select (w) */
+#define	MCFUART_UCR		0x08		/* Command register (w) */
+#define	MCFUART_URB		0x0c		/* Receiver Buffer (r) */
+#define	MCFUART_UTB		0x0c		/* Transmit Buffer (w) */
+#define	MCFUART_UIPCR		0x10		/* Input Port Change (r) */
+#define	MCFUART_UACR		0x10		/* Auxiliary Control (w) */
+#define	MCFUART_UISR		0x14		/* Interrup Status (r) */
+#define	MCFUART_UIMR		0x14		/* Interrupt Mask (w) */
+#define	MCFUART_UBG1		0x18		/* Baud Rate MSB (r/w) */
+#define	MCFUART_UBG2		0x1c		/* Baud Rate LSB (r/w) */
+#ifdef	CONFIG_M5272
+#define	MCFUART_UTF		0x28		/* Transmitter FIFO (r/w) */
+#define	MCFUART_URF		0x2c		/* Receiver FIFO (r/w) */
+#define	MCFUART_UFPD		0x30		/* Frac Prec. Divider (r/w) */
+#else
+#define	MCFUART_UIVR		0x30		/* Interrupt Vector (r/w) */
+#endif
+#define	MCFUART_UIPR		0x34		/* Input Port (r) */
+#define	MCFUART_UOP1		0x38		/* Output Port Bit Set (w) */
+#define	MCFUART_UOP0		0x3c		/* Output Port Bit Reset (w) */
+
+
+/*
+ *	Define bit flags in Mode Register 1 (MR1).
+ */
+#define	MCFUART_MR1_RXRTS	0x80		/* Auto RTS flow control */
+#define	MCFUART_MR1_RXIRQFULL	0x40		/* RX IRQ type FULL */
+#define	MCFUART_MR1_RXIRQRDY	0x00		/* RX IRQ type RDY */
+#define	MCFUART_MR1_RXERRBLOCK	0x20		/* RX block error mode */
+#define	MCFUART_MR1_RXERRCHAR	0x00		/* RX char error mode */
+
+#define	MCFUART_MR1_PARITYNONE	0x10		/* No parity */
+#define	MCFUART_MR1_PARITYEVEN	0x00		/* Even parity */
+#define	MCFUART_MR1_PARITYODD	0x04		/* Odd parity */
+#define	MCFUART_MR1_PARITYSPACE	0x08		/* Space parity */
+#define	MCFUART_MR1_PARITYMARK	0x0c		/* Mark parity */
+
+#define	MCFUART_MR1_CS5		0x00		/* 5 bits per char */
+#define	MCFUART_MR1_CS6		0x01		/* 6 bits per char */
+#define	MCFUART_MR1_CS7		0x02		/* 7 bits per char */
+#define	MCFUART_MR1_CS8		0x03		/* 8 bits per char */
+
+/*
+ *	Define bit flags in Mode Register 2 (MR2).
+ */
+#define	MCFUART_MR2_LOOPBACK	0x80		/* Loopback mode */
+#define	MCFUART_MR2_REMOTELOOP	0xc0		/* Remote loopback mode */
+#define	MCFUART_MR2_AUTOECHO	0x40		/* Automatic echo */
+#define	MCFUART_MR2_TXRTS	0x20		/* Assert RTS on TX */
+#define	MCFUART_MR2_TXCTS	0x10		/* Auto CTS flow control */
+
+#define	MCFUART_MR2_STOP1	0x07		/* 1 stop bit */
+#define	MCFUART_MR2_STOP15	0x08		/* 1.5 stop bits */
+#define	MCFUART_MR2_STOP2	0x0f		/* 2 stop bits */
+
+/*
+ *	Define bit flags in Status Register (USR).
+ */
+#define	MCFUART_USR_RXBREAK	0x80		/* Received BREAK */
+#define	MCFUART_USR_RXFRAMING	0x40		/* Received framing error */
+#define	MCFUART_USR_RXPARITY	0x20		/* Received parity error */
+#define	MCFUART_USR_RXOVERRUN	0x10		/* Received overrun error */
+#define	MCFUART_USR_TXEMPTY	0x08		/* Transmitter empty */
+#define	MCFUART_USR_TXREADY	0x04		/* Transmitter ready */
+#define	MCFUART_USR_RXFULL	0x02		/* Receiver full */
+#define	MCFUART_USR_RXREADY	0x01		/* Receiver ready */
+
+#define	MCFUART_USR_RXERR	(MCFUART_USR_RXBREAK | MCFUART_USR_RXFRAMING | \
+				MCFUART_USR_RXPARITY | MCFUART_USR_RXOVERRUN)
+
+/*
+ *	Define bit flags in Clock Select Register (UCSR).
+ */
+#define	MCFUART_UCSR_RXCLKTIMER	0xd0		/* RX clock is timer */
+#define	MCFUART_UCSR_RXCLKEXT16	0xe0		/* RX clock is external x16 */
+#define	MCFUART_UCSR_RXCLKEXT1	0xf0		/* RX clock is external x1 */
+
+#define	MCFUART_UCSR_TXCLKTIMER	0x0d		/* TX clock is timer */
+#define	MCFUART_UCSR_TXCLKEXT16	0x0e		/* TX clock is external x16 */
+#define	MCFUART_UCSR_TXCLKEXT1	0x0f		/* TX clock is external x1 */
+
+/*
+ *	Define bit flags in Command Register (UCR).
+ */
+#define	MCFUART_UCR_CMDNULL		0x00	/* No command */
+#define	MCFUART_UCR_CMDRESETMRPTR	0x10	/* Reset MR pointer */
+#define	MCFUART_UCR_CMDRESETRX		0x20	/* Reset receiver */
+#define	MCFUART_UCR_CMDRESETTX		0x30	/* Reset transmitter */
+#define	MCFUART_UCR_CMDRESETERR		0x40	/* Reset error status */
+#define	MCFUART_UCR_CMDRESETBREAK	0x50	/* Reset BREAK change */
+#define	MCFUART_UCR_CMDBREAKSTART	0x60	/* Start BREAK */
+#define	MCFUART_UCR_CMDBREAKSTOP	0x70	/* Stop BREAK */
+
+#define	MCFUART_UCR_TXNULL	0x00		/* No TX command */
+#define	MCFUART_UCR_TXENABLE	0x04		/* Enable TX */
+#define	MCFUART_UCR_TXDISABLE	0x08		/* Disable TX */
+#define	MCFUART_UCR_RXNULL	0x00		/* No RX command */
+#define	MCFUART_UCR_RXENABLE	0x01		/* Enable RX */
+#define	MCFUART_UCR_RXDISABLE	0x02		/* Disable RX */
+
+/*
+ *	Define bit flags in Input Port Change Register (UIPCR).
+ */
+#define	MCFUART_UIPCR_CTSCOS	0x10		/* CTS change of state */
+#define	MCFUART_UIPCR_CTS	0x01		/* CTS value */
+
+/*
+ *	Define bit flags in Input Port Register (UIP).
+ */
+#define	MCFUART_UIPR_CTS	0x01		/* CTS value */
+
+/*
+ *	Define bit flags in Output Port Registers (UOP).
+ *	Clear bit by writing to UOP0, set by writing to UOP1.
+ */
+#define	MCFUART_UOP_RTS		0x01		/* RTS set or clear */
+
+/*
+ *	Define bit flags in the Auxiliary Control Register (UACR).
+ */
+#define	MCFUART_UACR_IEC	0x01		/* Input enable control */
+
+/*
+ *	Define bit flags in Interrupt Status Register (UISR).
+ *	These same bits are used for the Interrupt Mask Register (UIMR).
+ */
+#define	MCFUART_UIR_COS		0x80		/* Change of state (CTS) */
+#define	MCFUART_UIR_DELTABREAK	0x04		/* Break start or stop */
+#define	MCFUART_UIR_RXREADY	0x02		/* Receiver ready */
+#define	MCFUART_UIR_TXREADY	0x01		/* Transmitter ready */
+
+#ifdef	CONFIG_M5272
+/*
+ *	Define bit flags in the Transmitter FIFO Register (UTF).
+ */
+#define	MCFUART_UTF_TXB		0x1f		/* transmitter data level */
+#define	MCFUART_UTF_FULL	0x20		/* transmitter fifo full */
+#define	MCFUART_UTF_TXS		0xc0		/* transmitter status */
+
+/*
+ *	Define bit flags in the Receiver FIFO Register (URF).
+ */
+#define	MCFUART_URF_RXB		0x1f		/* receiver data level */
+#define	MCFUART_URF_FULL	0x20		/* receiver fifo full */
+#define	MCFUART_URF_RXS		0xc0		/* receiver status */
+#endif
+
+/****************************************************************************/
+#endif	/* mcfuart_h */
diff -urN linux-2.4.29/include/asm-m68knommu/mcfwdebug.h linux-2.4.29-uc1/include/asm-m68knommu/mcfwdebug.h
--- linux-2.4.29/include/asm-m68knommu/mcfwdebug.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mcfwdebug.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,119 @@
+/****************************************************************************/
+
+/*
+ *	mcfdebug.h -- ColdFire Debug Module support.
+ *
+ * 	(C) Copyright 2001, Lineo Inc. (www.lineo.com) 
+ */
+
+/****************************************************************************/
+#ifndef mcfdebug_h
+#define mcfdebug_h
+/****************************************************************************/
+#include <linux/config.h>
+
+/* Define the debug module registers */
+#define MCFDEBUG_CSR	0x0			/* Configuration status		*/
+#define MCFDEBUG_BAAR	0x5			/* BDM address attribute	*/
+#define MCFDEBUG_AATR	0x6			/* Address attribute trigger	*/
+#define MCFDEBUG_TDR	0x7			/* Trigger definition		*/
+#define MCFDEBUG_PBR	0x8			/* PC breakpoint		*/
+#define MCFDEBUG_PBMR	0x9			/* PC breakpoint mask		*/
+#define MCFDEBUG_ABHR	0xc			/* High address breakpoint	*/
+#define MCFDEBUG_ABLR	0xd			/* Low address breakpoint	*/
+#define MCFDEBUG_DBR	0xe			/* Data breakpoint		*/
+#define MCFDEBUG_DBMR	0xf			/* Data breakpoint mask		*/
+
+/* Define some handy constants for the trigger definition register */
+#define MCFDEBUG_TDR_TRC_DISP	0x00000000	/* display on DDATA only	*/
+#define MCFDEBUG_TDR_TRC_HALT	0x40000000	/* Processor halt on BP		*/
+#define MCFDEBUG_TDR_TRC_INTR	0x80000000	/* Debug intr on BP		*/
+#define MCFDEBUG_TDR_LXT1	0x00004000	/* TDR level 1			*/
+#define MCFDEBUG_TDR_LXT2	0x00008000	/* TDR level 2			*/
+#define MCFDEBUG_TDR_EBL1	0x00002000	/* Enable breakpoint level 1	*/
+#define MCFDEBUG_TDR_EBL2	0x20000000	/* Enable breakpoint level 2	*/
+#define MCFDEBUG_TDR_EDLW1	0x00001000	/* Enable data BP longword	*/
+#define MCFDEBUG_TDR_EDLW2	0x10000000
+#define MCFDEBUG_TDR_EDWL1	0x00000800	/* Enable data BP lower word	*/
+#define MCFDEBUG_TDR_EDWL2	0x08000000
+#define MCFDEBUG_TDR_EDWU1	0x00000400	/* Enable data BP upper word	*/
+#define MCFDEBUG_TDR_EDWU2	0x04000000
+#define MCFDEBUG_TDR_EDLL1	0x00000200	/* Enable data BP low low byte	*/
+#define MCFDEBUG_TDR_EDLL2	0x02000000
+#define MCFDEBUG_TDR_EDLM1	0x00000100	/* Enable data BP low mid byte	*/
+#define MCFDEBUG_TDR_EDLM2	0x01000000
+#define MCFDEBUG_TDR_EDUM1	0x00000080	/* Enable data BP up mid byte	*/
+#define MCFDEBUG_TDR_EDUM2	0x00800000
+#define MCFDEBUG_TDR_EDUU1	0x00000040	/* Enable data BP up up byte	*/
+#define MCFDEBUG_TDR_EDUU2	0x00400000
+#define MCFDEBUG_TDR_DI1	0x00000020	/* Data BP invert		*/
+#define MCFDEBUG_TDR_DI2	0x00200000
+#define MCFDEBUG_TDR_EAI1	0x00000010	/* Enable address BP inverted	*/
+#define MCFDEBUG_TDR_EAI2	0x00100000
+#define MCFDEBUG_TDR_EAR1	0x00000008	/* Enable address BP range	*/
+#define MCFDEBUG_TDR_EAR2	0x00080000
+#define MCFDEBUG_TDR_EAL1	0x00000004	/* Enable address BP low	*/
+#define MCFDEBUG_TDR_EAL2	0x00040000
+#define MCFDEBUG_TDR_EPC1	0x00000002	/* Enable PC BP			*/
+#define MCFDEBUG_TDR_EPC2	0x00020000
+#define MCFDEBUG_TDR_PCI1	0x00000001	/* PC BP invert			*/
+#define MCFDEBUG_TDR_PCI2	0x00010000
+
+/* Constants for the address attribute trigger register */
+#define MCFDEBUG_AAR_RESET	0x00000005
+/* Fields not yet implemented */
+
+/* And some definitions for the writable sections of the CSR */
+#define MCFDEBUG_CSR_RESET	0x00100000
+#define MCFDEBUG_CSR_PSTCLK	0x00020000	/* PSTCLK disable		*/
+#define MCFDEBUG_CSR_IPW	0x00010000	/* Inhibit processor writes	*/
+#define MCFDEBUG_CSR_MAP	0x00008000	/* Processor refs in emul mode	*/
+#define MCFDEBUG_CSR_TRC	0x00004000	/* Emul mode on trace exception	*/
+#define MCFDEBUG_CSR_EMU	0x00002000	/* Force emulation mode		*/
+#define MCFDEBUG_CSR_DDC_READ	0x00000800	/* Debug data control		*/
+#define MCFDEBUG_CSR_DDC_WRITE	0x00001000
+#define MCFDEBUG_CSR_UHE	0x00000400	/* User mode halt enable	*/
+#define MCFDEBUG_CSR_BTB0	0x00000000	/* Branch target 0 bytes	*/
+#define MCFDEBUG_CSR_BTB2	0x00000100	/* Branch target 2 bytes	*/
+#define MCFDEBUG_CSR_BTB3	0x00000200	/* Branch target 3 bytes	*/
+#define MCFDEBUG_CSR_BTB4	0x00000300	/* Branch target 4 bytes	*/
+#define MCFDEBUG_CSR_NPL	0x00000040	/* Non-pipelined mode		*/
+#define MCFDEBUG_CSR_SSM	0x00000010	/* Single step mode		*/
+
+/* Constants for the BDM address attribute register */
+#define MCFDEBUG_BAAR_RESET	0x00000005
+/* Fields not yet implemented */
+
+
+/* This routine wrappers up the wdebug asm instruction so that the register
+ * and value can be relatively easily specified.  The biggest hassle here is
+ * that the debug module instructions (2 longs) must be long word aligned and
+ * some pointer fiddling is performed to ensure this.
+ */
+extern inline void wdebug(int reg, unsigned long data) {
+	unsigned short dbg_spc[6];
+	unsigned short *dbg;
+
+	// Force alignment to long word boundary
+	dbg = (unsigned short *)((((unsigned long)dbg_spc) + 3) & 0xfffffffc);
+
+	// Build up the debug instruction
+	dbg[0] = 0x2c80 | (reg & 0xf);
+	dbg[1] = (data >> 16) & 0xffff;
+	dbg[2] = data & 0xffff;
+	dbg[3] = 0;
+
+	// Perform the wdebug instruction
+#if 0
+	// This strain is for gas which doesn't have the wdebug instructions defined
+	asm(	"move.l	%0, %%a0\n\t"
+		".word	0xfbd0\n\t"
+		".word	0x0003\n\t"
+	    :: "g" (dbg) : "a0");
+#else
+	// And this is for when it does
+	asm(	"wdebug	(%0)" :: "a" (dbg));
+#endif
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/md.h linux-2.4.29-uc1/include/asm-m68knommu/md.h
--- linux-2.4.29/include/asm-m68knommu/md.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/md.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/md.h>
diff -urN linux-2.4.29/include/asm-m68knommu/mman.h linux-2.4.29-uc1/include/asm-m68knommu/mman.h
--- linux-2.4.29/include/asm-m68knommu/mman.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mman.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/mman.h>
diff -urN linux-2.4.29/include/asm-m68knommu/mmc-COBRA5272.h linux-2.4.29-uc1/include/asm-m68knommu/mmc-COBRA5272.h
--- linux-2.4.29/include/asm-m68knommu/mmc-COBRA5272.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mmc-COBRA5272.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,52 @@
+/*
+ * linux-2.4.x/include/linux/mmc-COBRA5272.h 
+ *
+ * MMC/SD-Card driver
+ *
+ * based on mmc.h
+ * Copyright (C) 2003 Thomas Fehrenbacher <thomas@blumba.de>
+ *
+ * Changed to COBRA5272:  Wolfgang Elsner (wolfgang.elsner@sentec-elektronik.de)
+ */
+
+/* QSPI registers */
+#define	MCFSIM_QMR		0xa0	/* mode */
+#define	MCFSIM_QDLYR	0xa4	/* delay */
+#define	MCFSIM_QWR		0xa8	/* wrap */
+#define	MCFSIM_QIR		0xac	/* interrupt */
+#define	MCFSIM_QAR		0xb0	/* address */
+#define	MCFSIM_QDR		0xb4	/* address */
+
+#define TX_RAM_START		   0x00
+#define RX_RAM_START		   0x10
+#define COMMAND_RAM_START	0x20
+
+#define QMR		*(volatile unsigned short *)(MCF_MBAR + MCFSIM_QMR)
+#define QAR		*(volatile unsigned short *)(MCF_MBAR + MCFSIM_QAR)
+#define QDR		*(volatile unsigned short *)(MCF_MBAR + MCFSIM_QDR)
+#define QWR		*(volatile unsigned short *)(MCF_MBAR + MCFSIM_QWR)
+#define QDLYR	*(volatile unsigned short *)(MCF_MBAR + MCFSIM_QDLYR)
+#define QIR		*(volatile unsigned short *)(MCF_MBAR + MCFSIM_QIR)
+
+/* QSPI register bits */
+#define QMR_MSTR	0x8000	/* master mode enable: must always be set */
+#define QMR_DOHIE	0x4000	/* shut off (hi-z) Dout between transfers */
+#define QMR_BITS	0x3c00	/* bits per transfer (size) */
+#define QMR_CPOL	0x0200	/* clock state when inactive */
+#define QMR_CPHA	0x0100	/* clock phase: 1 = data taken at rising edge */
+#define QMR_BAUD	0x00ff	/* clock rate divider */
+
+#define QIR_WCEF	0x0008	/* write collison */
+#define QIR_ABRT	0x0004	/* abort */
+#define QIR_SPIF	0x0001	/* finished */
+#define QIR_SETUP	0x0001  /* setup QIR for polling mode */
+
+#define QWR_CSIV	0x1000	/* 1 = active low chip selects */
+
+#define QDLYR_SPE	0x8000	/* initiates transfer when set */
+#define QDLYR_QCD	0x7f00	/* start delay between CS and first clock */
+#define QDLYR_DTL	0x00ff	/* delay after CS release */
+
+#define QCR_SETUP	0x7000
+#define QCR_CONT	0x8000	/* 1=continuous CS after transfer */
+#define QCR_CS    0x0500   /* QSPI_CS 5 */
diff -urN linux-2.4.29/include/asm-m68knommu/mmc-COBRA5282.h linux-2.4.29-uc1/include/asm-m68knommu/mmc-COBRA5282.h
--- linux-2.4.29/include/asm-m68knommu/mmc-COBRA5282.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mmc-COBRA5282.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,56 @@
+/*
+ * linux-2.4.x/include/linux/mmc-COBRA5282.h 
+ *
+ * MMC/SD-Card driver
+ *
+ * based on mmc.h
+ * Copyright (C) 2003 Thomas Fehrenbacher <thomas@blumba.de>
+ *
+ * Changed to COBRA5282:  Wolfgang Elsner wolfgang.elsner@sentec-elektronik.de
+ */
+
+/* QSPI registers */
+#define	MCFSIM_QMR		0x340	/* mode */
+#define	MCFSIM_QDLYR	0x344	/* delay */
+#define	MCFSIM_QWR		0x348	/* wrap */
+#define	MCFSIM_QIR		0x34c /* interrupt */
+#define	MCFSIM_QAR		0x350	/* address */
+#define	MCFSIM_QDR		0x354	/* address */
+
+#define TX_RAM_START		   0x00
+#define RX_RAM_START		   0x10
+#define COMMAND_RAM_START	0x20
+
+#define QMR		*(volatile unsigned short *)(MCF_IPSBAR + MCFSIM_QMR)
+#define QAR		*(volatile unsigned short *)(MCF_IPSBAR + MCFSIM_QAR)
+#define QDR		*(volatile unsigned short *)(MCF_IPSBAR + MCFSIM_QDR)
+#define QWR		*(volatile unsigned short *)(MCF_IPSBAR + MCFSIM_QWR)
+#define QDLYR	*(volatile unsigned short *)(MCF_IPSBAR + MCFSIM_QDLYR)
+#define QIR		*(volatile unsigned short *)(MCF_IPSBAR + MCFSIM_QIR)
+
+/* QSPI register bits */
+#define QMR_MSTR	0x8000	/* master mode enable: must always be set */
+#define QMR_DOHIE	0x4000	/* shut off (hi-z) Dout between transfers */
+#define QMR_BITS	0x3c00	/* bits per transfer (size) */
+#define QMR_CPOL	0x0200	/* clock state when inactive */
+#define QMR_CPHA	0x0100	/* clock phase: 1 = data taken at rising edge */
+#define QMR_BAUD	0x00ff	/* clock rate divider */
+
+#define QIR_WCEF	0x0008	/* write collison */
+#define QIR_ABRT	0x0004	/* abort */
+#define QIR_SPIF	0x0001	/* finished */
+#define QIR_SETUP	0x0001   /* setup QIR for polling mode */
+
+#define QWR_CSIV	0x1000	/* 1 = active low chip selects */
+
+#define QDLYR_SPE	0x8000	/* initiates transfer when set */
+#define QDLYR_QCD	0x7f00	/* start delay between CS and first clock */
+#define QDLYR_DTL	0x00ff	/* delay after CS release */
+
+#define QCR_SETUP	0x7000
+#define QCR_CONT	0x8000	/* 1=continuous CS after transfer */
+#define QCR_CS		0x0e00	/* QSPI_CS 0 */
+
+#define MCF5282_GPTSCR1    0x1b0006
+#define MCF5282_GPTDDR     0x1b001e
+#define MCF5282_GPTPORT    0x1b001d
diff -urN linux-2.4.29/include/asm-m68knommu/mmu_context.h linux-2.4.29-uc1/include/asm-m68knommu/mmu_context.h
--- linux-2.4.29/include/asm-m68knommu/mmu_context.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mmu_context.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef __M68KNOMMU_MMU_CONTEXT_H
+#define __M68KNOMMU_MMU_CONTEXT_H
+
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
+{
+}
+
+extern inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	// mm->context = virt_to_phys(mm->pgd);
+	return(0);
+}
+
+#define destroy_context(mm)		do { } while(0)
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu)
+{
+}
+
+extern inline void activate_mm(struct mm_struct *prev_mm,
+			       struct mm_struct *next_mm)
+{
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/mmu.h linux-2.4.29-uc1/include/asm-m68knommu/mmu.h
--- linux-2.4.29/include/asm-m68knommu/mmu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/mmu.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/mmu.h>
diff -urN linux-2.4.29/include/asm-m68knommu/module.h linux-2.4.29-uc1/include/asm-m68knommu/module.h
--- linux-2.4.29/include/asm-m68knommu/module.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/module.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/module.h>
diff -urN linux-2.4.29/include/asm-m68knommu/movs.h linux-2.4.29-uc1/include/asm-m68knommu/movs.h
--- linux-2.4.29/include/asm-m68knommu/movs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/movs.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/movs.h>
diff -urN linux-2.4.29/include/asm-m68knommu/msgbuf.h linux-2.4.29-uc1/include/asm-m68knommu/msgbuf.h
--- linux-2.4.29/include/asm-m68knommu/msgbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/msgbuf.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/msgbuf.h>
diff -urN linux-2.4.29/include/asm-m68knommu/namei.h linux-2.4.29-uc1/include/asm-m68knommu/namei.h
--- linux-2.4.29/include/asm-m68knommu/namei.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/namei.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/namei.h>
diff -urN linux-2.4.29/include/asm-m68knommu/nap.h linux-2.4.29-uc1/include/asm-m68knommu/nap.h
--- linux-2.4.29/include/asm-m68knommu/nap.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/nap.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,123 @@
+/****************************************************************************/
+
+/*
+ *	nap.h -- Gilbarco/NAP support.
+ *
+ * 	(C) Copyright 2001-2003, SnapGear (www.snapgear.com) 
+ */
+
+/****************************************************************************/
+#ifndef	nap_h
+#define	nap_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/****************************************************************************/
+#ifdef CONFIG_GILBARCONAP
+/****************************************************************************/
+
+#ifdef CONFIG_COLDFIRE
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#endif
+
+/*
+ *	Command to support selecting RS232 or RS422 mode on the
+ *	second COM port.
+ */
+#define	TIOCSET422	0x4d01		/* Set port mode 232 or 422 */
+#define	TIOCGET422	0x4d02		/* Get current port mode */
+
+/*
+ *	Low level control of the RS232/422 enable.
+ */
+#define	MCFPP_PA11	0x0800
+
+#ifndef __ASSEMBLY__
+/*
+ *	RS232/422 control is via the single PA11 line. Low is the RS422
+ *	enable, high is RS232 mode.
+ */
+static __inline__ unsigned int mcf_getpa(void)
+{
+	volatile unsigned short *pp;
+	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+	return((unsigned int) *pp);
+}
+
+static __inline__ void mcf_setpa(unsigned int mask, unsigned int bits)
+{
+	volatile unsigned short *pp;
+	unsigned long		flags;
+
+	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+	save_flags(flags); cli();
+	*pp = (*pp & ~mask) | bits;
+	restore_flags(flags);
+}
+#endif /* __ASSEMBLY__ */
+
+/****************************************************************************/
+
+#if defined(CONFIG_M5272)
+/*
+ *	Gilbarco/NAP based hardware. DTR/DCD lines are wired to GPB lines.
+ */
+#define	MCF_HAVEDCD0
+#define	MCF_HAVEDCD1
+#define	MCF_HAVEDTR0
+#define	MCF_HAVEDTR1
+
+#ifndef __ASSEMBLY__
+/*
+ *	Functions to abstract access to the DCD/DTR lines. There is no
+ *	standard way to implement these on ColdFire, mostly spare PPIO
+ *	bits are used.
+ */
+static __inline__ unsigned int mcf_getppdcd(unsigned int portnr)
+{
+	volatile unsigned short *pp;
+#ifdef CONFIG_SMC91111
+	if (portnr == 0) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
+		return((*pp & 0x0080) ? 0 : 1);
+	} else if (portnr == 1) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+		return((*pp & 0x0004) ? 0 : 1);
+	}
+#else
+	if (portnr < 2) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
+		return((*pp & (portnr ? 0x0020 : 0x0080)) ? 0 : 1);
+	}
+#endif
+	return(0);
+}
+static __inline__ unsigned int mcf_getppdtr(unsigned int portnr)
+{
+	volatile unsigned short *pp;
+	if (portnr < 2) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
+		return((*pp & (portnr ? 0x0010 : 0x0040)) ? 0 : 1);
+	}
+	return(0);
+}
+
+static __inline__ void mcf_setppdtr(unsigned int portnr, unsigned int dtr)
+{
+	volatile unsigned short *pp;
+	unsigned short bit;
+	if (portnr < 2) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
+		bit = (portnr ? 0x0010 : 0x0040);
+		*pp = (*pp & ~bit) | (dtr ? 0 : bit);
+	}
+}
+#endif /* __ASSEMBLY__ */
+#endif /* CONFIG_M5272 */
+
+/****************************************************************************/
+#endif /* CONFIG_GILBARCONAP */
+/****************************************************************************/
+#endif	/* nap_h */
diff -urN linux-2.4.29/include/asm-m68knommu/nettel.h linux-2.4.29-uc1/include/asm-m68knommu/nettel.h
--- linux-2.4.29/include/asm-m68knommu/nettel.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/nettel.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,139 @@
+/****************************************************************************/
+
+/*
+ *	nettel.h -- SnapGear (formerly Moreton Bay) NETtel support.
+ *
+ *	(C) Copyright 1999-2000, Moreton Bay (www.moretonbay.com)
+ * 	(C) Copyright 2000-2001, Lineo Inc. (www.lineo.com) 
+ * 	(C) Copyright 2001-2003, SnapGear Inc., (www.snapgear.com) 
+ */
+
+/****************************************************************************/
+#ifndef	nettel_h
+#define	nettel_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/****************************************************************************/
+#ifdef CONFIG_NETtel
+/****************************************************************************/
+
+#ifdef CONFIG_COLDFIRE
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#endif
+
+/*---------------------------------------------------------------------------*/
+#if defined(CONFIG_M5307)
+/*
+ *	NETtel/5307 based hardware first. DTR/DCD lines are wired to
+ *	GPIO lines. Most of the LED's are driven through a latch
+ *	connected to CS2.
+ */
+#define	MCF_HAVEDCD0
+#define	MCF_HAVEDCD1
+#define	MCF_HAVEDTR0
+#define	MCF_HAVEDTR1
+
+#define	NETtel_LEDADDR	0x30400000
+
+#ifndef __ASSEMBLY__
+static __inline__ unsigned int mcf_getppdcd(unsigned int portnr)
+{
+	volatile unsigned short *pp;
+	if (portnr < 2) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+		return((*pp & (portnr ? 0x0001 : 0x0002)) ? 0 : 1);
+	}
+	return(0);
+}
+
+static __inline__ unsigned int mcf_getppdtr(unsigned int portnr)
+{
+	volatile unsigned short *pp;
+	if (portnr < 2) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+		return((*pp & (portnr ? 0x0004 : 0x0008)) ? 0 : 1);
+	}
+	return(0);
+}
+
+static __inline__ void mcf_setppdtr(unsigned int portnr, unsigned int dtr)
+{
+	volatile unsigned short *pp;
+	unsigned short bit;
+	if (portnr < 2) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+		bit = (portnr ? 0x0004 : 0x0008);
+		*pp = (*pp & ~bit) | (dtr ? 0 : bit);
+	}
+}
+
+/*
+ *	The power and heartbeat LED's are connected to PIO bits of
+ *	the 5307 based boards.
+ */
+static __inline__ void mcf_setppleds(unsigned int mask, unsigned int bits)
+{
+	volatile unsigned short *pp;
+	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+	*pp = (*pp & ~mask) | bits;
+}
+#endif /* __ASSEMBLY__ */
+
+/*---------------------------------------------------------------------------*/
+#elif defined(CONFIG_M5206e)
+/*
+ *	NETtel/5206e based hardware has leds on latch on CS3.
+ *	No support modem for lines??
+ */
+#define	NETtel_LEDADDR	0x50000000
+
+/*---------------------------------------------------------------------------*/
+#elif defined(CONFIG_M5272)
+/*
+ *	NETtel/5272 based hardware. DTR/DCD lines are wired to GPB lines.
+ *	No DCD/DTR on port 1, only on port 0.
+ */
+#define	MCF_HAVEDCD0
+#define	MCF_HAVEDTR0
+
+#ifndef __ASSEMBLY__
+static __inline__ unsigned int mcf_getppdcd(unsigned int portnr)
+{
+	volatile unsigned short *pp;
+	if (portnr == 0) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
+		return((*pp & 0x0080) ? 0 : 1);
+	}
+	return(0);
+}
+
+static __inline__ unsigned int mcf_getppdtr(unsigned int portnr)
+{
+	volatile unsigned short *pp;
+	if (portnr == 0) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
+		return((*pp & 0x0040) ? 0 : 1);
+	}
+	return(0);
+}
+
+static __inline__ void mcf_setppdtr(unsigned int portnr, unsigned int dtr)
+{
+	volatile unsigned short *pp;
+	if (portnr == 0) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
+		*pp = (*pp & ~0x0040) | (dtr ? 0 : 0x0040);
+	}
+}
+#endif /* __ASSEMBLY */
+
+#endif
+/*---------------------------------------------------------------------------*/
+
+/****************************************************************************/
+#endif /* CONFIG_NETtel */
+/****************************************************************************/
+#endif	/* nettel_h */
diff -urN linux-2.4.29/include/asm-m68knommu/openprom.h linux-2.4.29-uc1/include/asm-m68knommu/openprom.h
--- linux-2.4.29/include/asm-m68knommu/openprom.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/openprom.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/openprom.h>
diff -urN linux-2.4.29/include/asm-m68knommu/oplib.h linux-2.4.29-uc1/include/asm-m68knommu/oplib.h
--- linux-2.4.29/include/asm-m68knommu/oplib.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/oplib.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/oplib.h>
diff -urN linux-2.4.29/include/asm-m68knommu/page.h linux-2.4.29-uc1/include/asm-m68knommu/page.h
--- linux-2.4.29/include/asm-m68knommu/page.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/page.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,114 @@
+#ifndef _M68KNOMMU_PAGE_H
+#define _M68KNOMMU_PAGE_H
+
+#include <linux/config.h>
+#include <asm/virtconvert.h>
+
+/* PAGE_SHIFT determines the page size */
+
+#define PAGE_SHIFT	(12)
+#define PAGE_SIZE	(4096)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+
+#ifdef __KERNEL__
+
+#include <asm/setup.h>
+
+#if !defined(CONFIG_SMALL_TASKS) && PAGE_SHIFT < 13
+#define KTHREAD_SIZE (8192)
+#else
+#define KTHREAD_SIZE PAGE_SIZE
+#endif
+ 
+#ifndef __ASSEMBLY__
+ 
+#define get_user_page(vaddr)		__get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr)	free_page(addr)
+
+#define clear_page(page)	memset((page), 0, PAGE_SIZE)
+#define copy_page(to,from)	memcpy((to), (from), PAGE_SIZE)
+
+#define clear_user_page(page, vaddr)	clear_page(page)
+#define copy_user_page(to, from, vaddr)	copy_page(to, from)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pmd[16]; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)	((x).pte)
+#define pmd_val(x)	((&x)->pmd[0])
+#define pgd_val(x)	((x).pgd)
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x)	((pte_t) { (x) } )
+#define __pmd(x)	((pmd_t) { (x) } )
+#define __pgd(x)	((pgd_t) { (x) } )
+#define __pgprot(x)	((pgprot_t) { (x) } )
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+/* Pure 2^n version of get_order */
+extern __inline__ int get_order(unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#include <asm/page_offset.h>
+
+#define PAGE_OFFSET		(PAGE_OFFSET_RAW)
+
+#ifndef __ASSEMBLY__
+
+#define __pa(vaddr)		virt_to_phys((void *)vaddr)
+#define __va(paddr)		phys_to_virt((unsigned long)paddr)
+
+#define MAP_NR(addr)		(((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
+#define virt_to_page(addr)	(mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
+#define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
+
+
+#ifdef CONFIG_NO_KERNEL_MSG
+#define	BUG_PRINT()
+#else
+#define	BUG_PRINT() printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__)
+#endif
+
+
+// #define BUG_PANIC()	asm volatile ("halt") /* drop to debugger */
+// #define BUG_PANIC()	while(1)
+#define BUG_PANIC()	panic("BUG!")
+
+
+#define BUG() do { \
+	BUG_PRINT(); \
+	BUG_PANIC(); \
+} while (0)
+
+#define PAGE_BUG(page) do { \
+	BUG(); \
+} while (0)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
+#define WANT_PAGE_VIRTUAL 1
+#endif
+
+#endif /* _M68KNOMMU_PAGE_H */
diff -urN linux-2.4.29/include/asm-m68knommu/page_offset.h linux-2.4.29-uc1/include/asm-m68knommu/page_offset.h
--- linux-2.4.29/include/asm-m68knommu/page_offset.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/page_offset.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,64 @@
+
+#include <linux/config.h>
+#include <asm/shglcore.h>
+
+/* This handles the memory map.. */
+
+#ifdef CONFIG_COLDFIRE
+#if defined(CONFIG_SMALL)
+#define PAGE_OFFSET_RAW		0x30020000
+#elif defined(CONFIG_CFV240)
+#define PAGE_OFFSET_RAW		0x02000000
+#else
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+#endif
+
+#ifdef CONFIG_M68360
+#define PAGE_OFFSET_RAW     0x00000000
+#endif
+
+#ifdef CONFIG_PILOT
+#ifdef CONFIG_M68328
+#define PAGE_OFFSET_RAW		0x10000000
+#endif
+#ifdef CONFIG_M68EZ328
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+#endif
+#ifdef CONFIG_UCSIMM
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+#ifdef CONFIG_CWEZ328
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+#ifdef CONFIG_CWVZ328
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+#ifdef CONFIG_CLIE
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+
+#if defined(CONFIG_UCDIMM) || defined(CONFIG_DRAGEN2)
+#ifdef CONFIG_M68VZ328 
+#define PAGE_OFFSET_RAW		0x00000000
+#endif /* CONFIG_M68VZ328 */
+#endif /* CONFIG_UCDIMM */
+
+#ifdef CONFIG_DRAGONIXVZ
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+
+#ifdef CONFIG_M68EZ328ADS
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+#ifdef CONFIG_ALMA_ANS
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+#ifdef CONFIG_M68EN302
+#define PAGE_OFFSET_RAW		0x00000000
+#endif
+#ifdef CONFIG_SHGLCORE
+#define PAGE_OFFSET_RAW		SHGLCORE_RAM_BANK_0_ADDR 
+#endif
+
diff -urN linux-2.4.29/include/asm-m68knommu/param.h linux-2.4.29-uc1/include/asm-m68knommu/param.h
--- linux-2.4.29/include/asm-m68knommu/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/param.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,62 @@
+#ifndef _M68KNOMMU_PARAM_H
+#define _M68KNOMMU_PARAM_H
+
+#include <linux/config.h>
+
+
+#ifndef HZ
+#ifdef CONFIG_COLDFIRE
+#if defined(CONFIG_HW_FEITH)
+#define HZ 1000
+#else
+#define HZ 100
+#endif
+#endif
+#ifdef CONFIG_M68EN302
+#define HZ 100
+#endif
+#ifdef CONFIG_M68328
+#define HZ 100
+#endif
+#ifdef CONFIG_M68EZ328
+#ifdef CONFIG_M68EZ328_USE_RTC
+#define HZ 128
+#else
+#define HZ 100
+#endif
+#endif
+
+#ifdef CONFIG_M68VZ328
+#ifdef CONFIG_DRAGONBALL_USE_RTC
+#define HZ 128
+#else
+#define HZ 100
+#endif
+#endif
+
+#ifdef CONFIG_SHGLCORE
+#define HZ 50
+#endif
+#ifdef CONFIG_M68360
+#define HZ 100
+#endif
+
+#endif
+
+#define EXEC_PAGESIZE	4096
+
+#ifndef NGROUPS
+#define NGROUPS		32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#ifdef __KERNEL__
+#define CLOCKS_PER_SEC HZ
+#endif /* __KERNEL__ */
+
+#endif /* _M68KNOMMU_PARAM_H */
diff -urN linux-2.4.29/include/asm-m68knommu/pci.h linux-2.4.29-uc1/include/asm-m68knommu/pci.h
--- linux-2.4.29/include/asm-m68knommu/pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/pci.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef M68KNOMMU_PCI_H
+#define	M68KNOMMU_PCI_H
+
+#include <asm-m68k/pci.h>
+
+/*
+ *	These are pretty much arbitary with the CoMEM implementation.
+ *	We have the whole address space to ourselves.
+ */
+#define PCIBIOS_MIN_IO		0x100
+#define PCIBIOS_MIN_MEM		0x00010000
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/pgalloc.h linux-2.4.29-uc1/include/asm-m68knommu/pgalloc.h
--- linux-2.4.29/include/asm-m68knommu/pgalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/pgalloc.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,111 @@
+#ifndef _M68KNOMMU_PGALLOC_H
+#define _M68KNOMMU_PGALLOC_H
+
+/*
+ * Copyright (C) 2000 Lineo, David McCullough <davidm@lineo.com>
+ * Copyright (C) 2001 Lineo, Greg Ungerer <gerg@snapgear.com>
+ */
+
+#include <asm/setup.h>
+#include <asm/virtconvert.h>
+
+/*
+ * Cache handling functions
+ */
+
+extern inline void __flush_cache_all(void)
+{
+#if defined(CONFIG_M5407) || defined(CONFIG_M547x)
+	/*
+	 *	Use cpushl to push and invalidate all cache lines.
+	 *	Gas doesn't seem to know how to generate the ColdFire
+	 *	cpushl instruction... Oh well, bit stuff it for now.
+	 */
+	__asm__ __volatile__ (
+		"nop\n\t"
+		"clrl	%%d0\n\t"
+		"1:\n\t"
+		"movel	%%d0,%%a0\n\t"
+		"2:\n\t"
+		".word	0xf468\n\t"
+		"addl	#0x10,%%a0\n\t"
+		"cmpl	#0x00000800,%%a0\n\t"
+		"blt	2b\n\t"
+		"addql	#1,%%d0\n\t"
+		"cmpil	#4,%%d0\n\t"
+		"bne	1b\n\t"
+		"movel	#0xb6088500,%%d0\n\t"
+		"movec	%%d0,%%CACR\n\t"
+		: : : "d0", "a0" );
+#endif /* CONFIG_M5407 */
+#if defined(CONFIG_M527x) || defined(CONFIG_M528x)
+	__asm__ __volatile__ (
+        	"movel	#0x81400100, %%d0\n\t"
+        	"movec	%%d0, %%CACR\n\t"
+		"nop\n\t"
+		: : : "d0" );
+#endif /* CONFIG_M527x || CONFIG_M528x */
+}
+
+#define flush_cache_all()			__flush_cache_all()
+#define flush_cache_mm(mm)			__flush_cache_all()
+#define flush_cache_range(mm, start, end)	__flush_cache_all()
+#define flush_cache_page(vma, vmaddr)		__flush_cache_all()
+#define flush_page_to_ram(page)			__flush_cache_all()
+#define flush_dcache_page(page)			__flush_cache_all()
+#define flush_icache_range(start, end)		__flush_cache_all()
+#define flush_icache_user_range(vma,pg,adr,len) __flush_cache_all()
+#define flush_icache_page(vma,pg)		__flush_cache_all()
+#define flush_icache()				__flush_cache_all()
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+	BUG();
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+	BUG();
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+	BUG();
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+	BUG();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+	BUG();
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+				   unsigned long start, unsigned long end)
+{
+	BUG();
+}
+
+extern inline void flush_tlb_kernel_page(unsigned long addr)
+{
+	BUG();
+}
+
+extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+				      unsigned long start, unsigned long end)
+{
+	BUG();
+}
+
+#endif /* _M68KNOMMU_PGALLOC_H */
diff -urN linux-2.4.29/include/asm-m68knommu/pgtable.h linux-2.4.29-uc1/include/asm-m68knommu/pgtable.h
--- linux-2.4.29/include/asm-m68knommu/pgtable.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/pgtable.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,23 @@
+#ifndef _M68KNOMMU_PGTABLE_H
+#define _M68KNOMMU_PGTABLE_H
+
+#include <linux/config.h>
+#include <asm/setup.h>
+
+#define pgd_present(pgd)     (1)       /* pages are always present on NO_MM */
+#define kern_addr_valid(addr) (1)
+
+#define PAGE_NONE		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_SHARED		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_COPY		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_READONLY	__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_KERNEL		__pgprot(0)    /* these mean nothing to NO_MM */
+
+extern void paging_init(void);
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()   do { } while (0)
+
+#endif /* _M68KNOMMU_PGTABLE_H */
diff -urN linux-2.4.29/include/asm-m68knommu/poll.h linux-2.4.29-uc1/include/asm-m68knommu/poll.h
--- linux-2.4.29/include/asm-m68knommu/poll.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/poll.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/poll.h>
diff -urN linux-2.4.29/include/asm-m68knommu/posix_types.h linux-2.4.29-uc1/include/asm-m68knommu/posix_types.h
--- linux-2.4.29/include/asm-m68knommu/posix_types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/posix_types.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/posix_types.h>
diff -urN linux-2.4.29/include/asm-m68knommu/processor.h linux-2.4.29-uc1/include/asm-m68knommu/processor.h
--- linux-2.4.29/include/asm-m68knommu/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/processor.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,175 @@
+/*
+ * include/asm-m68k/processor.h
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+ */
+
+#ifndef __ASM_M68K_PROCESSOR_H
+#define __ASM_M68K_PROCESSOR_H
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#include <linux/config.h>
+#include <asm/segment.h>
+#include <asm/fpu.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+
+extern inline unsigned long rdusp(void) {
+#ifdef CONFIG_COLDFIRE
+	extern unsigned int	sw_usp;
+	return(sw_usp);
+#else
+  	unsigned long usp;
+
+	__asm__ __volatile__("move %/usp,%0" : "=a" (usp));
+	return usp;
+#endif
+}
+
+extern inline void wrusp(unsigned long usp) {
+#ifdef CONFIG_COLDFIRE
+	extern unsigned int	sw_usp;
+	sw_usp = usp;
+#else
+	__asm__ __volatile__("move %0,%/usp" : : "a" (usp));
+#endif
+}
+
+/*
+ * User space process size: 3.75GB. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.
+ */
+#define TASK_SIZE	(0xFFFFFFFFUL)
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define MCA_bus 0
+
+/* 
+ * if you change this structure, you must change the code and offsets
+ * in m68k/machasm.S
+ */
+   
+struct thread_struct {
+	unsigned long  ksp;		/* kernel stack pointer */
+	unsigned long  usp;		/* user stack pointer */
+	unsigned short sr;		/* saved status register */
+	unsigned short fs;		/* saved fs (sfc, dfc) */
+	unsigned long  crp[2];		/* cpu root pointer */
+	unsigned long  esp0;		/* points to SR of stack frame */
+	unsigned long  fp[8*3];
+	unsigned long  fpcntl[3];	/* fp control regs */
+	unsigned char  fpstate[FPSTATESIZE];  /* floating point state */
+};
+
+#define INIT_THREAD  { \
+	sizeof(init_stack) + (unsigned long) init_stack, 0, \
+	PS_S, __KERNEL_DS, \
+	{0, 0}, 0, {0,}, {0, 0, 0}, {0,}, \
+}
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ *
+ * pass the data segment into user programs if it exists,
+ * it can't hurt anything as far as I can tell
+ */
+#ifdef CONFIG_COLDFIRE
+#define start_thread(_regs, _pc, _usp)			\
+do {							\
+	set_fs(USER_DS); /* reads from user space */	\
+	(_regs)->pc = (_pc);				\
+	(_regs)->sr &= ~0x2000;				\
+	(_regs)->d5 = current->mm->start_data;		\
+	(_regs)->format = 0x4;		\
+	wrusp(_usp);					\
+} while(0)
+#else
+#define start_thread(_regs, _pc, _usp)			\
+do {							\
+	set_fs(USER_DS); /* reads from user space */	\
+	(_regs)->pc = (_pc);				\
+	(_regs)->sr &= ~0x2000;				\
+	(_regs)->d5 = current->mm->start_data;		\
+	wrusp(_usp);					\
+} while(0)
+#endif
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+#define copy_segments(tsk, mm)		do { } while (0)
+#define release_segments(mm)		do { } while (0)
+#define forget_segments()		do { } while (0)
+
+/*
+ * Free current thread data structures etc..
+ */
+static inline void exit_thread(void)
+{
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+extern inline unsigned long thread_saved_pc(struct thread_struct *t)
+{
+	extern void scheduling_functions_start_here(void);
+	extern void scheduling_functions_end_here(void);
+	struct switch_stack *sw = (struct switch_stack *)t->ksp;
+	/* Check whether the thread is blocked in resume() */
+	if (sw->retpc > (unsigned long)scheduling_functions_start_here &&
+	    sw->retpc < (unsigned long)scheduling_functions_end_here)
+		return ((unsigned long *)sw->a6)[1];
+	else
+		return sw->retpc;
+}
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define	KSTK_EIP(tsk)	\
+    ({			\
+	unsigned long eip = 0;	 \
+	if ((tsk)->thread.esp0 > PAGE_SIZE && \
+	    MAP_NR((tsk)->thread.esp0) < max_mapnr) \
+	      eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
+	eip; })
+#define	KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->thread.usp)
+
+#ifdef CONFIG_SMALL_TASKS
+#define THREAD_SIZE PAGE_SIZE
+
+/* Allocation and freeing of basic task resources. */
+#define alloc_task_struct() \
+	((struct task_struct *) __get_free_pages(GFP_KERNEL,0))
+#define free_task_struct(p)	free_pages((unsigned long)(p),0)
+#else
+#define THREAD_SIZE (2*PAGE_SIZE)
+
+/* Allocation and freeing of basic task resources. */
+#define alloc_task_struct() \
+	((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
+#define free_task_struct(p)	free_pages((unsigned long)(p),1)
+#endif
+#define get_task_struct(tsk)      atomic_inc(&mem_map[MAP_NR(tsk)].count)
+
+#define init_task	(init_task_union.task)
+#define init_stack	(init_task_union.stack)
+
+#define cpu_relax()    barrier()
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/ptrace.h linux-2.4.29-uc1/include/asm-m68knommu/ptrace.h
--- linux-2.4.29/include/asm-m68knommu/ptrace.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/ptrace.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,92 @@
+#ifndef _M68K_PTRACE_H
+#define _M68K_PTRACE_H
+
+#define PT_D1	   0
+#define PT_D2	   1
+#define PT_D3	   2
+#define PT_D4	   3
+#define PT_D5	   4
+#define PT_D6	   5
+#define PT_D7	   6
+#define PT_A0	   7
+#define PT_A1	   8
+#define PT_A2	   9
+#define PT_A3	   10
+#define PT_A4	   11
+#define PT_A5	   12
+#define PT_A6	   13
+#define PT_D0	   14
+#define PT_USP	   15
+#define PT_ORIG_D0 16
+#define PT_SR	   17
+#define PT_PC	   18
+
+#ifndef __ASSEMBLY__
+
+/* this struct defines the way the registers are stored on the
+   stack during a system call. */
+
+struct pt_regs {
+  long     d1;
+  long     d2;
+  long     d3;
+  long     d4;
+  long     d5;
+  long     a0;
+  long     a1;
+  long     a2;
+  long     d0;
+  long     orig_d0;
+  long     stkadj;
+#ifdef CONFIG_COLDFIRE
+  unsigned format :  4; /* frame format specifier */
+  unsigned vector : 12; /* vector offset */
+  unsigned short sr;
+  unsigned long  pc;
+#else
+  unsigned short sr;
+  unsigned long  pc;
+#ifndef NO_FORMAT_VEC
+  unsigned format :  4; /* frame format specifier */
+  unsigned vector : 12; /* vector offset */
+#endif
+#endif
+};
+
+/*
+ * This is the extended stack used by signal handlers and the context
+ * switcher: it's pushed after the normal "struct pt_regs".
+ */
+struct switch_stack {
+	unsigned long  d6;
+	unsigned long  d7;
+	unsigned long  a3;
+	unsigned long  a4;
+	unsigned long  a5;
+	unsigned long  a6;
+	unsigned long  retpc;
+};
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS            12
+#define PTRACE_SETREGS            13
+#ifndef NO_FPU
+#define PTRACE_GETFPREGS          14
+#define PTRACE_SETFPREGS          15
+#endif
+
+#ifdef __KERNEL__
+
+#ifndef PS_S
+#define PS_S  (0x2000)
+#define PS_M  (0x1000)
+#endif
+
+#define user_mode(regs) (!((regs)->sr & PS_S))
+#define instruction_pointer(regs) ((regs)->pc)
+extern unsigned int sw_usp;
+#define user_stack(regs) (sw_usp)
+extern void show_regs(struct pt_regs *);
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+#endif /* _M68K_PTRACE_H */
diff -urN linux-2.4.29/include/asm-m68knommu/quicc_simple.h linux-2.4.29-uc1/include/asm-m68knommu/quicc_simple.h
--- linux-2.4.29/include/asm-m68knommu/quicc_simple.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/quicc_simple.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,52 @@
+/***********************************
+ * $Id: quicc_simple.h,v 1.1.1.1 2001/05/18 17:10:11 hamilton Exp $
+ ***********************************
+ *
+ ***************************************
+ * Simple drivers common header
+ ***************************************
+ */
+
+#ifndef __SIMPLE_H
+#define __SIMPLE_H
+
+/* #include "quicc.h" */
+
+#define GLB_SCC_0   0
+#define GLB_SCC_1   1
+#define GLB_SCC_2   2
+#define GLB_SCC_3   3
+
+typedef void (int_routine)(unsigned short interrupt_event);
+typedef int_routine *int_routine_ptr; 
+typedef void *(alloc_routine)(int length);
+typedef void (free_routine)(int scc_num, int channel_num, void *buf);
+typedef void (store_rx_buffer_routine)(int scc_num, int channel_num, void *buff, int length);
+typedef int  (handle_tx_error_routine)(int scc_num, int channel_num, QUICC_BD *tbd);
+typedef void (handle_rx_error_routine)(int scc_num, int channel_num, QUICC_BD *rbd);
+typedef void (handle_lost_error_routine)(int scc_num, int channel_num);
+
+/* user defined functions for global errors */
+typedef void (handle_glob_overrun_routine)(int scc_number);
+typedef void (handle_glob_underrun_routine)(int scc_number);
+typedef void (glob_intr_q_overflow_routine)(int scc_number);
+
+/*
+ * General initialization and command routines
+ */
+void quicc_issue_cmd (unsigned short cmd, int scc_num);
+void quicc_init(void);
+void quicc_scc_init(int scc_number, int number_of_rx_buf, int number_of_tx_buf);
+void quicc_smc_init(int smc_number, int number_of_rx_buf, int number_of_tx_buf);
+void quicc_scc_start(int scc_num);
+void quicc_scc_loopback(int scc_num);
+
+/* Interrupt enable/disable routines for critical pieces of code*/
+unsigned short  IntrDis(void);
+void            IntrEna(unsigned short old_sr);
+
+/* For debugging */
+void print_rbd(int scc_num);
+void print_tbd(int scc_num);
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/resource.h linux-2.4.29-uc1/include/asm-m68knommu/resource.h
--- linux-2.4.29/include/asm-m68knommu/resource.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/resource.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/resource.h>
diff -urN linux-2.4.29/include/asm-m68knommu/scatterlist.h linux-2.4.29-uc1/include/asm-m68knommu/scatterlist.h
--- linux-2.4.29/include/asm-m68knommu/scatterlist.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/scatterlist.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,4 @@
+#ifndef _M68KNOMMU_SCATTERLIST_H
+#define _M68KNOMMU_SCATTERLIST_H
+
+#endif /* !(_M68KNOMMU_SCATTERLIST_H) */
diff -urN linux-2.4.29/include/asm-m68knommu/se1100.h linux-2.4.29-uc1/include/asm-m68knommu/se1100.h
--- linux-2.4.29/include/asm-m68knommu/se1100.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/se1100.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,112 @@
+/****************************************************************************/
+
+/*
+ *	se1100.h -- SecureEdge SE1100 support.
+ *
+ * 	(C) Copyright 2002-2003, SnapGear (www.snapgear.com) 
+ */
+
+/****************************************************************************/
+#ifndef	se1100_h
+#define	se1100_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/****************************************************************************/
+#ifdef CONFIG_SE1100
+/****************************************************************************/
+
+#ifdef CONFIG_COLDFIRE
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#endif
+
+/*
+ *	Command to support selecting RS232 or RS422 mode on the
+ *	second COM port.
+ */
+#define	TIOCSET422	0x4d01		/* Set port mode 232 or 422 */
+#define	TIOCGET422	0x4d02		/* Get current port mode */
+
+/*
+ *	Low level control of the RS232/422 enable.
+ */
+#define	MCFPP_PA11	0x0800
+
+#ifndef __ASSEMBLY__
+/*
+ *	RS232/422 control is via the single PA11 line. Low is the RS422
+ *	enable, high is RS232 mode.
+ */
+static __inline__ unsigned int mcf_getpa(void)
+{
+	volatile unsigned short *pp;
+	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+	return((unsigned int) *pp);
+}
+
+static __inline__ void mcf_setpa(unsigned int mask, unsigned int bits)
+{
+	volatile unsigned short *pp;
+	unsigned long		flags;
+
+	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+	save_flags(flags); cli();
+	*pp = (*pp & ~mask) | bits;
+	restore_flags(flags);
+}
+#endif /* __ASSEMBLY__ */
+
+/****************************************************************************/
+
+#if defined(CONFIG_M5272)
+/*
+ *	SecureEdge SE1100 based hardware. DTR/DCD lines are wired to GPB lines.
+ *	We've only got DCD and DTR on serial line 0.  We hijack DTR on line 1
+ *	for the purpose of RS485 line driving.  The mcfserial driver conditions
+ *	mostly on DCD (everywhere except setsignals) so this should hang
+ *	together okay.
+ */
+#define	MCF_HAVEDCD0
+#define	MCF_HAVEDTR0
+#define	MCF_HAVEDTR1
+
+#ifndef __ASSEMBLY__
+static __inline__ unsigned int mcf_getppdcd(unsigned int portnr)
+{
+	volatile unsigned short *pp;
+	if (portnr == 0) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
+		return((*pp & 0x0080) ? 0 : 1);
+	}
+	return(0);
+}
+
+static __inline__ unsigned int mcf_getppdtr(unsigned int portnr)
+{
+	volatile unsigned short *pp;
+	if (portnr < 2) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
+		return((*pp & (portnr ? 0x0020 : 0x0040)) ? 0 : 1);
+	}
+	return(0);
+}
+
+static __inline__ void mcf_setppdtr(unsigned int portnr, unsigned int dtr)
+{
+	volatile unsigned short *pp;
+	unsigned short bit;
+	if (portnr < 2) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
+		bit = (portnr ? 0x0020 : 0x0040);
+		*pp = (*pp & ~bit) | (dtr ? 0 : bit);
+	}
+}
+#endif /* __ASSEMBLY__ */
+#endif /* CONFIG_M5272 */
+
+/****************************************************************************/
+#endif /* CONFIG_SE1100 */
+/****************************************************************************/
+#endif	/* se1100_h */
diff -urN linux-2.4.29/include/asm-m68knommu/segment.h linux-2.4.29-uc1/include/asm-m68knommu/segment.h
--- linux-2.4.29/include/asm-m68knommu/segment.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/segment.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,51 @@
+#ifndef _M68K_SEGMENT_H
+#define _M68K_SEGMENT_H
+
+/* define constants */
+/* Address spaces (FC0-FC2) */
+#define USER_DATA     (1)
+#ifndef __USER_DS
+#define __USER_DS     (USER_DATA)
+#endif
+#define USER_PROGRAM  (2)
+#define SUPER_DATA    (5)
+#ifndef __KERNEL_DS
+#define __KERNEL_DS   (SUPER_DATA)
+#endif
+#define SUPER_PROGRAM (6)
+#define CPU_SPACE     (7)
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
+#define USER_DS		MAKE_MM_SEG(__USER_DS)
+#define KERNEL_DS	MAKE_MM_SEG(__KERNEL_DS)
+
+/*
+ * Get/set the SFC/DFC registers for MOVES instructions
+ */
+
+static inline mm_segment_t get_fs(void)
+{
+    return USER_DS;
+}
+
+static inline mm_segment_t get_ds(void)
+{
+    /* return the supervisor data space code */
+    return KERNEL_DS;
+}
+
+static inline void set_fs(mm_segment_t val)
+{
+}
+
+#define segment_eq(a,b)	((a).seg == (b).seg)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _M68K_SEGMENT_H */
diff -urN linux-2.4.29/include/asm-m68knommu/semaphore.h linux-2.4.29-uc1/include/asm-m68knommu/semaphore.h
--- linux-2.4.29/include/asm-m68knommu/semaphore.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/semaphore.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,184 @@
+#ifndef _M68K_SEMAPHORE_H
+#define _M68K_SEMAPHORE_H
+
+#define RW_LOCK_BIAS		 0x01000000
+
+#ifndef __ASSEMBLY__
+
+#include <linux/linkage.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/rwsem.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+
+/*
+ * Interrupt-safe semaphores..
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ *
+ * m68k version by Andreas Schwab
+ */
+
+
+struct semaphore {
+	atomic_t count;
+	atomic_t waking;
+	wait_queue_head_t wait;
+#if WAITQUEUE_DEBUG
+	long __magic;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+# define __SEM_DEBUG_INIT(name) \
+		, (long)&(name).__magic
+#else
+# define __SEM_DEBUG_INIT(name)
+#endif
+
+#define __SEMAPHORE_INITIALIZER(name,count) \
+{ ATOMIC_INIT(count), ATOMIC_INIT(0), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+	__SEM_DEBUG_INIT(name) }
+
+#define __MUTEX_INITIALIZER(name) \
+	__SEMAPHORE_INITIALIZER(name,1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+
+#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
+#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
+
+extern inline void sema_init (struct semaphore *sem, int val)
+{
+	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
+}
+
+static inline void init_MUTEX (struct semaphore *sem)
+{
+	sema_init(sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+{
+	sema_init(sem, 0);
+}
+
+asmlinkage void __down_failed(void /* special register calling convention */);
+asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
+asmlinkage int  __down_failed_trylock(void  /* params in registers */);
+asmlinkage void __up_wakeup(void /* special register calling convention */);
+
+asmlinkage void __down(struct semaphore * sem);
+asmlinkage int  __down_interruptible(struct semaphore * sem);
+asmlinkage int  __down_trylock(struct semaphore * sem);
+asmlinkage void __up(struct semaphore * sem);
+
+extern spinlock_t semaphore_wake_lock;
+
+/*
+ * This is ugly, but we want the default case to fall through.
+ * "down_failed" is a special asm handler that calls the C
+ * routine that actually waits. See arch/m68k/lib/semaphore.S
+ */
+extern inline void down(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	__asm__ __volatile__(
+		"| atomic down operation\n\t"
+		"movel	%0, %%a1\n\t"
+		"lea	%%pc@(1f), %%a0\n\t"
+		"subql	#1, %%a1@\n\t"
+		"jmi " SYMBOL_NAME_STR(__down_failed) "\n"
+		"1:"
+		: /* no outputs */
+		: "g" (sem)
+		: "cc", "%a0", "%a1", "memory");
+}
+
+extern inline int down_interruptible(struct semaphore * sem)
+{
+	int ret;
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	__asm__ __volatile__(
+		"| atomic down operation\n\t"
+		"movel	%1, %%a1\n\t"
+		"lea	%%pc@(1f), %%a0\n\t"
+		"subql	#1, %%a1@\n\t"
+		"jmi " SYMBOL_NAME_STR(__down_failed_interruptible) "\n\t"
+		"clrl	%%d0\n"
+		"1: movel	%%d0, %0\n"
+		: "=d" (ret)
+		: "g" (sem)
+		: "cc", "%d0", "%a0", "%a1", "memory");
+	return(ret);
+}
+
+/* DAVIDM - unsafe asm for use with gcc-2.95.2 */
+extern inline int down_trylock(struct semaphore * sem)
+{
+	register struct semaphore *sem1 __asm__ ("%a1") = sem;
+	register int result __asm__ ("%d0");
+
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	__asm__ __volatile__(
+		"| atomic down trylock operation\n\t"
+		"subql #1,%1@\n\t"
+		"jmi 2f\n\t"
+		"clrl %0\n"
+		"1:\n"
+		".section .text.lock,\"ax\"\n"
+		".even\n"
+		"2:\tpea 1b\n\t"
+		"jbra __down_failed_trylock\n"
+		".previous"
+		: "=d" (result)
+		: "a" (sem1)
+		: "memory");
+	return result;
+}
+
+/*
+ * Note! This is subtle. We jump to wake people up only if
+ * the semaphore was negative (== somebody was waiting on it).
+ * The default case (no contention) will result in NO
+ * jumps for both down() and up().
+ */
+extern inline void up(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	__asm__ __volatile__(
+		"| atomic up operation\n\t"
+		"movel	%0, %%a1\n\t"
+		"lea	%%pc@(1f), %%a0\n\t"
+		"addql	#1, %%a1@\n\t"
+		"jle " SYMBOL_NAME_STR(__up_wakeup) "\n"
+		"1:"
+		: /* no outputs */
+		: "g" (sem)
+		: "cc", "%a0", "%a1", "memory");
+}
+
+static inline int sem_getcount(struct semaphore *sem)
+{
+	return atomic_read(&sem->count);
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/semaphore-helper.h linux-2.4.29-uc1/include/asm-m68knommu/semaphore-helper.h
--- linux-2.4.29/include/asm-m68knommu/semaphore-helper.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/semaphore-helper.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,83 @@
+#ifndef _M68K_SEMAPHORE_HELPER_H
+#define _M68K_SEMAPHORE_HELPER_H
+
+/*
+ * SMP- and interrupt-safe semaphores helper functions.
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ *
+ * m68k version by Andreas Schwab
+ */
+
+#include <linux/config.h>
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ */
+static inline void wake_one_more(struct semaphore * sem)
+{
+	atomic_inc(&sem->waking);
+}
+
+static inline int waking_non_zero(struct semaphore *sem)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	ret = 0;
+	if (atomic_read(&sem->waking) > 0) {
+		atomic_dec(&sem->waking);
+		ret = 1;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+/*
+ * waking_non_zero_interruptible:
+ *	1	got the lock
+ *	0	go to sleep
+ *	-EINTR	interrupted
+ */
+static inline int waking_non_zero_interruptible(struct semaphore *sem,
+						struct task_struct *tsk)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	ret = 0;
+	if (atomic_read(&sem->waking) > 0) {
+		atomic_dec(&sem->waking);
+		ret = 1;
+	} else if (signal_pending(tsk)) {
+		atomic_inc(&sem->count);
+		ret = -EINTR;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+/*
+ * waking_non_zero_trylock:
+ *	1	failed to lock
+ *	0	got the lock
+ */
+static inline int waking_non_zero_trylock(struct semaphore *sem)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	ret = 1;
+	if (atomic_read(&sem->waking) > 0) {
+		atomic_dec(&sem->waking);
+		ret = 0;
+	} else
+		atomic_inc(&sem->count);
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/sembuf.h linux-2.4.29-uc1/include/asm-m68knommu/sembuf.h
--- linux-2.4.29/include/asm-m68knommu/sembuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/sembuf.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/sembuf.h>
diff -urN linux-2.4.29/include/asm-m68knommu/semp3.h linux-2.4.29-uc1/include/asm-m68knommu/semp3.h
--- linux-2.4.29/include/asm-m68knommu/semp3.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/semp3.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,64 @@
+/****************************************************************************/
+
+/*
+ *	semp.h -- SecureEdge MP3 hardware platform support.
+ *
+ *	(C) Copyright 2001-2003, Greg Ungerer (gerg@snapgear.com).
+ */
+
+/****************************************************************************/
+#ifndef	semp3_h
+#define	semp3_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/****************************************************************************/
+#ifdef CONFIG_SECUREEDGEMP3
+/****************************************************************************/
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+/*
+ *	The ColdFire UARTs do not have any support for DTR/DCD lines.
+ *	We have wired them onto some of the parallel IO lines.
+ */
+#define	MCF_HAVEDCD1
+#define	MCF_HAVEDTR1
+
+#ifndef __ASSEMBLY__
+static __inline__ unsigned int mcf_getppdcd(unsigned int portnr)
+{
+	volatile unsigned short *pp;
+	if (portnr == 1) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+		return((*pp & 0x0004) ? 0 : 1);
+	}
+	return(0);
+}
+
+static __inline__ unsigned int mcf_getppdtr(unsigned int portnr)
+{
+	volatile unsigned short *pp;
+	if (portnr == 1) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+		return((*pp & 0x0080) ? 0 : 1);
+	}
+	return(0);
+}
+
+static __inline__ void mcf_setppdtr(unsigned int portnr, unsigned int dtr)
+{
+	volatile unsigned short *pp;
+	if (portnr == 1) {
+		pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+		*pp = (*pp & ~0x0080) | (dtr ? 0 : 0x0080);
+	}
+}
+#endif /* __ASSEMBLY__ */
+
+/****************************************************************************/
+#endif /* CONFIG_SECUREEDGEMP3 */
+/****************************************************************************/
+#endif	/* semp3_h */
diff -urN linux-2.4.29/include/asm-m68knommu/serial.h linux-2.4.29-uc1/include/asm-m68knommu/serial.h
--- linux-2.4.29/include/asm-m68knommu/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/serial.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,84 @@
+/*
+ * linux/include/asm-m68knommu/serial.h
+ *
+ * Copyright (C) 2003 Develer S.r.l. (http://www.develer.com/)
+ * Author: Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * Based on linux/include/asm-i386/serial.h
+ */
+#include <linux/config.h>
+
+
+#if defined(CONFIG_SERIAL_CDB4)
+/*
+ * This assumes you have a 1.8432 MHz clock for your UART.
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ */
+#define BASE_BAUD ( 1843200 / 16 )
+#define CONFIG_SERIAL_SHARE_IRQ
+#define CDB4_COM_BASE		((u8 *)0x40000000)
+#define CDB4_COM_IRQ		67	/* external IRQ3 */
+#define CDB4_COM_IRQPRI		5	/* interrupt priority */
+#define CDB4_COM_RESET_BIT	13	/* PA13 hooked to 16C554 RESET line, active high */
+#define STD_COM_FLAGS		ASYNC_BOOT_AUTOCONF
+
+#define SERIAL_PORT_DFNS				\
+	{						\
+		.baud_base	= BASE_BAUD,		\
+		.iomem_base	= CDB4_COM_BASE + 0x10,	\
+		.io_type	= SERIAL_IO_MEM,	\
+		.irq		= CDB4_COM_IRQ,		\
+		.flags		= STD_COM_FLAGS		\
+	},						\
+	{						\
+		.baud_base	= BASE_BAUD,		\
+		.iomem_base	= CDB4_COM_BASE + 0x18,	\
+		.io_type	= SERIAL_IO_MEM,	\
+		.irq		= CDB4_COM_IRQ,		\
+		.flags		= STD_COM_FLAGS		\
+	},						\
+	{						\
+		.baud_base	= BASE_BAUD,		\
+		.iomem_base	= CDB4_COM_BASE + 0x20,	\
+		.io_type	= SERIAL_IO_MEM,	\
+		.irq		= CDB4_COM_IRQ,		\
+		.flags		= STD_COM_FLAGS		\
+	},						\
+	{						\
+		.baud_base	= BASE_BAUD,		\
+		.iomem_base	= CDB4_COM_BASE + 0x28,	\
+		.io_type	= SERIAL_IO_MEM,	\
+		.irq		= CDB4_COM_IRQ,		\
+		.flags		= STD_COM_FLAGS		\
+	}
+
+#define RS_TABLE_SIZE  4
+
+#elif defined(CONFIG_SED_SIOSIII)
+#define BASE_BAUD (12500000 / 16)
+#define STD_COM_FLAGS		ASYNC_BOOT_AUTOCONF
+#define SERIAL_PORT_DFNS \
+	{\
+		.baud_base	= BASE_BAUD,		 \
+		.iomem_base	= ((void *)0x80020000),	\
+		.io_type	= SERIAL_IO_MEM,	\
+		.irq		= 25,			\
+		.flags		= STD_COM_FLAGS | SA_SHIRQ		\
+	},\
+	{\
+		.baud_base      = BASE_BAUD,             \
+		.iomem_base     = ((void *)0x80020008), \
+		.io_type        = SERIAL_IO_MEM,        \
+		.irq            = 25,                   \
+		.flags          = STD_COM_FLAGS | SA_SHIRQ \
+	}
+#define RS_TABLE_SIZE	2
+#undef CONFIG_SERIAL_MULTIPORT
+
+#else /* !CONFIG_SERIAL_CDB4 */
+#error serial port not supported on this board
+#endif /* !CONFIG_SERIAL_CDB4 */
+
diff -urN linux-2.4.29/include/asm-m68knommu/setup.h linux-2.4.29-uc1/include/asm-m68knommu/setup.h
--- linux-2.4.29/include/asm-m68knommu/setup.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/setup.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+/* not needed */
diff -urN linux-2.4.29/include/asm-m68knommu/shglcore.h linux-2.4.29-uc1/include/asm-m68knommu/shglcore.h
--- linux-2.4.29/include/asm-m68knommu/shglcore.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/shglcore.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,65 @@
+
+/* Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ */
+
+#ifndef _M68K_SHGLCORE_H
+#define _M68K_SHGLCORE_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_SHGLCORE
+
+#include <asm/MC68332.h>
+
+#ifdef CONFIG_SHGLCORE_2MEG
+
+#define SHGLCORE_ROM_BANK_0_ADDR	0x000000
+#define SHGLCORE_ROM_BANK_1_ADDR	0x100000
+#define SHGLCORE_RAM_BANK_0_ADDR	0x200000
+#define SHGLCORE_RAM_BANK_1_ADDR	0x300000
+#define SHGLCORE_FLASH_BANK_0_ADDR	0x400000
+
+#define SHGLCORE_ROM_BANK_0_LENGTH	0x100000
+#define SHGLCORE_ROM_BANK_1_LENGTH	0x100000
+#define SHGLCORE_RAM_BANK_0_LENGTH	0x100000
+#define SHGLCORE_RAM_BANK_1_LENGTH	0x100000
+#define SHGLCORE_FLASH_BANK_0_LENGTH	0x80000
+
+#define SHGLCORE_ACC_ADDR		0x600000
+#define SHGLCORE_LANCE_ADDR		0x700000
+
+#else
+
+#define SHGLCORE_ROM_BANK_0_ADDR	0x000000
+#define SHGLCORE_RAM_BANK_0_ADDR	0x100000
+#define SHGLCORE_FLASH_BANK_0_ADDR	0x300000
+
+#define SHGLCORE_ROM_BANK_0_LENGTH	0x100000
+#define SHGLCORE_RAM_BANK_0_LENGTH	0x100000
+#define SHGLCORE_FLASH_BANK_0_LENGTH	0x80000
+
+#define SHGLCORE_ACC_ADDR		0x400000
+#define SHGLCORE_LANCE_ADDR		0x500000
+
+#endif
+
+#define MAX_DMA_ADDRESS			SHGLCORE_RAM_BANK_0_ADDR + SHGLCORE_RAM_BANK_0_LENGTH
+
+#define SHGLCORE_LATCH_ADDR	(SHGLCORE_ACC_ADDR+0x100)
+#define SHGLCORE_1865_0_ADDR	(SHGLCORE_ACC_ADDR+0x600)
+#define SHGLCORE_1865_1_ADDR	(SHGLCORE_ACC_ADDR+0x700)
+
+#define SHGLCORE_LATCH_BIT(x)	BYTE_REF(SHGLCORE_LATCH_ADDR+x)
+
+#define SHGLCORE_LATCH_STATUS_LED	0
+#define SHGLCORE_LATCH_ERROR_LED	1
+#define SHGLCORE_LATCH_ALARM_LED	2
+
+#define SHGLCORE_LATCH_1865		4
+
+#define SHGLCORE_LATCH_RELAY_1		6
+#define SHGLCORE_LATCH_RELAY_2		7
+
+#endif /* SHGLCORE */
+
+#endif /* _M68K_SHGLCORE_H */
diff -urN linux-2.4.29/include/asm-m68knommu/shglports.h linux-2.4.29-uc1/include/asm-m68knommu/shglports.h
--- linux-2.4.29/include/asm-m68knommu/shglports.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/shglports.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,76 @@
+
+/* Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *         1997, 1998  D. Jeff Dionne <jeff@uClinux.org>,
+ */
+
+#ifndef _M68K_SHGLPORTS_H
+#define _M68K_SHGLPORTS_H
+
+#include <linux/config.h>
+#include <linux/sched.h>
+
+#ifdef CONFIG_SHGLCORE
+
+extern struct semaphore porte_interlock;
+
+struct SHGLCORE_PORT_QS { 
+  unsigned char
+  nullqs:1, /* COM1TX */ 
+  sbin:1,   /* PQS6 (PCS3) */
+  sbclk:1,  /* PQS5 (PCS2) */
+  sbout:1,  /* PQS4 (PCS1) */
+  null4:4;  /* MISO, MOSI, SCLK, /SS=PCS0 */
+};
+
+#define PORT_QS ((volatile struct SHGLCORE_PORT_QS*)PORTQS_ADDR)
+
+struct SHGLCORE_PORT_E {
+  unsigned char
+  dead:1,       /* LED */
+  sbirigb:1,    /* PE6 */
+  ds:1,         /* /DS */
+  nulle1:1,     /* na */ 
+  sbpll:1,      /* PE3 */
+  avec:1,       /* /AVEC */
+  sbsrom:1,     /* PE1 */
+  sbpanel:1;    /* PE0 */
+};
+
+#define PORT_E ((volatile struct SHGLCORE_PORT_E*)PORTE_ADDR)
+
+struct SHGLCORE_PORT_F {
+  unsigned char
+  nullf1:4,
+  nullf2:4;
+};
+
+#define PORT_F ((volatile struct SHGLCORE_PORT_F*)PORTF_ADDR)
+
+extern int comm_status_led, comm_error_led, alarm_led;
+
+static inline void SET_COMM_STATUS_LED(int value) {
+	BYTE_REF(SHGLCORE_ACC_ADDR+0x100+0) = comm_status_led = value;
+}
+static inline int GET_COMM_STATUS_LED(void) {
+	return comm_status_led;
+}
+
+
+static inline void SET_COMM_ERROR_LED(int value) {
+	BYTE_REF(SHGLCORE_ACC_ADDR+0x100+1) = comm_error_led = value;
+}
+static inline int GET_COMM_ERROR_LED(void) {
+	return comm_error_led;
+}
+
+
+static inline void SET_ALARM_LED(int value) {
+	BYTE_REF(SHGLCORE_ACC_ADDR+0x100+2) = alarm_led = value;
+}
+static inline int GET_ALARM_LED(void) {
+	return alarm_led;
+}
+
+#endif
+
+#endif /* _M68K_SHGLPORTS_H */
diff -urN linux-2.4.29/include/asm-m68knommu/shmbuf.h linux-2.4.29-uc1/include/asm-m68knommu/shmbuf.h
--- linux-2.4.29/include/asm-m68knommu/shmbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/shmbuf.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/shmbuf.h>
diff -urN linux-2.4.29/include/asm-m68knommu/shm.h linux-2.4.29-uc1/include/asm-m68knommu/shm.h
--- linux-2.4.29/include/asm-m68knommu/shm.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/shm.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/shm.h>
diff -urN linux-2.4.29/include/asm-m68knommu/shmparam.h linux-2.4.29-uc1/include/asm-m68knommu/shmparam.h
--- linux-2.4.29/include/asm-m68knommu/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/shmparam.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/shmparam.h>
diff -urN linux-2.4.29/include/asm-m68knommu/sigcontext.h linux-2.4.29-uc1/include/asm-m68knommu/sigcontext.h
--- linux-2.4.29/include/asm-m68knommu/sigcontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/sigcontext.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,16 @@
+#ifndef _ASM_M68KNOMMU_SIGCONTEXT_H
+#define _ASM_M68KNOMMU_SIGCONTEXT_H
+
+struct sigcontext {
+	unsigned long  sc_mask; 	/* old sigmask */
+	unsigned long  sc_usp;		/* old user stack pointer */
+	unsigned long  sc_d0;
+	unsigned long  sc_d1;
+	unsigned long  sc_a0;
+	unsigned long  sc_a1;
+	unsigned short sc_sr;
+	unsigned long  sc_pc;
+	unsigned short sc_formatvec;
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/siginfo.h linux-2.4.29-uc1/include/asm-m68knommu/siginfo.h
--- linux-2.4.29/include/asm-m68knommu/siginfo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/siginfo.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/siginfo.h>
diff -urN linux-2.4.29/include/asm-m68knommu/signal.h linux-2.4.29-uc1/include/asm-m68knommu/signal.h
--- linux-2.4.29/include/asm-m68knommu/signal.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/signal.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,181 @@
+#ifndef _M68KNOMMU_SIGNAL_H
+#define _M68KNOMMU_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#ifdef __KERNEL__
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE		SA_ONESHOT
+#define SA_SAMPLE_RANDOM	SA_RESTART
+#define SA_SHIRQ		0x04000000
+#endif
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+#ifdef __KERNEL__
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+
+#include <asm/sigcontext.h>
+#undef __HAVE_ARCH_SIG_BITOPS
+
+#endif /* __KERNEL__ */
+
+#endif /* _M68KNOMMU_SIGNAL_H */
diff -urN linux-2.4.29/include/asm-m68knommu/sl811-hw.h linux-2.4.29-uc1/include/asm-m68knommu/sl811-hw.h
--- linux-2.4.29/include/asm-m68knommu/sl811-hw.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/sl811-hw.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,147 @@
+/*
+File: include/asm-arm/sl811-hw.h
+
+19.09.2003 hne@ist1.de
+Use Kernel 2.4.20 and this source from 2.4.22
+Splitt hardware depens into file sl811-x86.h and sl811-arm.h.
+Functions as inline.
+
+23.09.2003 hne
+Move Hardware depend header sl811-arm.h into include/asm-arm/sl811-hw.h.
+GPRD as parameter.
+
+24.09.2003 hne
+Use Offset from ADDR to DATA instand of direct io.
+
+03.10.2003 hne
+Low level only for port io into hardware-include.
+*/
+
+#ifndef __LINUX_SL811_HW_H
+#define __LINUX_SL811_HW_H
+
+#define MAX_CONTROLERS		1	/* Max number of sl811 controllers */
+					/* Always 1 for this architecture! */
+
+#define SIZEOF_IO_REGION	1	/* Size for request/release region */
+
+#define OFFSET_DATA_REG data_off	/* Offset from ADDR_IO to DATA_IO (future) */
+					/* Can change by arg */
+
+#if defined(CONFIG_SIGNAL_MCP751)
+static int io[MAX_CONTROLERS] = {0x46000000};	/* Base addr_io */
+static int data_off = 1;	/* Offset from addr_io to addr_io */
+static int irq[MAX_CONTROLERS] = {90};		/* also change gprd !!! */
+
+MODULE_PARM(io,"i");
+MODULE_PARM_DESC(io,"sl811 address io port 0x46000000");
+MODULE_PARM(data_off,"i");
+MODULE_PARM_DESC(data_off,"sl811 data io port offset from address port (default 1)");
+MODULE_PARM(irq,"i");
+MODULE_PARM_DESC(irq,"sl811 irq 90(default)");
+#endif
+
+
+
+/*
+ * Low level: Read from Data port [arm]
+ */
+static __u8 inline sl811_read_data (struct sl811_hc *hc)
+{
+	__u8 data;
+	data = readb(hc->data_io);
+	rmb();
+	return data;
+}
+
+/*
+ * Low level: Write to index register [arm]
+ */
+static void inline sl811_write_index (struct sl811_hc *hc, __u8 index)
+{
+	writeb(index, hc->addr_io);
+	wmb();
+}
+
+/*
+ * Low level: Write to Data port [arm]
+ */
+static void inline sl811_write_data (struct sl811_hc *hc, __u8 data)
+{
+	writeb(data, hc->data_io);
+	wmb();
+}
+
+/*
+ * Low level: Write to index register and data port [arm]
+ */
+static void inline sl811_write_index_data (struct sl811_hc *hc, __u8 index, __u8 data)
+{
+	writeb(index, hc->addr_io);
+	writeb(data, hc->data_io);
+	wmb();
+}
+
+
+/*
+ * This	function is board specific.  It	sets up	the interrupt to
+ * be an edge trigger and trigger on the rising	edge
+ */
+static void inline sl811_init_irq(void)
+{
+#if defined(CONFIG_SIGNAL_MCP751)
+	// ICR4 enable INT5
+	{
+	volatile unsigned long *icrp;
+
+	// PORTD configure pin K3 for INT5
+	*((volatile unsigned long  *) (MCF_MBAR+MCFSIM_PDCNT)) |= 0x000000C0;
+
+	// transition low to high
+	*((volatile unsigned long  *) (MCF_MBAR+MCFSIM_PITR)) |= 0x00000040;
+
+	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR4);
+	*icrp = (*icrp & 0x70777777) | 0x0d000000; // INT5
+	}
+#endif
+}
+
+/*****************************************************************
+ *
+ * Function Name: release_regions [arm]
+ *
+ * This function is board specific. It release all io address
+ * from memory (if can).
+ *
+ * Input: struct sl811_hc * *
+ *
+ * Return value  : 0 = OK
+ *
+ *****************************************************************/
+static void inline sl811_release_regions(struct sl811_hc *hc)
+{
+	hc->addr_io = 0;
+	hc->data_io = 0;
+}
+
+/*****************************************************************
+ *
+ * Function Name: request_regions [arm]
+ *
+ * This function is board specific. It request all io address and
+ * maps into memory (if can).
+ *
+ * Input: struct sl811_hc *
+ *
+ * Return value  : 0 = OK
+ *
+ *****************************************************************/
+static int inline sl811_request_regions (struct sl811_hc *hc, int addr_io, int data_io, const char *name)
+{
+	hc->addr_io =	addr_io;
+	hc->data_io =	data_io;
+
+	return 0;
+}
+
+#endif // __LINUX_SL811_HW_H
diff -urN linux-2.4.29/include/asm-m68knommu/smp.h linux-2.4.29-uc1/include/asm-m68knommu/smp.h
--- linux-2.4.29/include/asm-m68knommu/smp.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/smp.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+/* nothing required here yet */
diff -urN linux-2.4.29/include/asm-m68knommu/smplock.h linux-2.4.29-uc1/include/asm-m68knommu/smplock.h
--- linux-2.4.29/include/asm-m68knommu/smplock.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/smplock.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/smplock.h>
diff -urN linux-2.4.29/include/asm-m68knommu/socket.h linux-2.4.29-uc1/include/asm-m68knommu/socket.h
--- linux-2.4.29/include/asm-m68knommu/socket.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/socket.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/socket.h>
diff -urN linux-2.4.29/include/asm-m68knommu/sockios.h linux-2.4.29-uc1/include/asm-m68knommu/sockios.h
--- linux-2.4.29/include/asm-m68knommu/sockios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/sockios.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/sockios.h>
diff -urN linux-2.4.29/include/asm-m68knommu/softirq.h linux-2.4.29-uc1/include/asm-m68knommu/softirq.h
--- linux-2.4.29/include/asm-m68knommu/softirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/softirq.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,19 @@
+#ifndef __M68K_SOFTIRQ_H
+#define __M68K_SOFTIRQ_H
+
+#include <asm/atomic.h>
+#include <asm/hardirq.h>
+
+#define __cpu_bh_enable(cpu) \
+		do { barrier(); local_bh_count(cpu)--; } while (0)
+#define cpu_bh_disable(cpu) \
+		do { local_bh_count(cpu)++; barrier(); } while (0)
+
+#define local_bh_disable()	cpu_bh_disable(smp_processor_id())
+#define __local_bh_enable()	__cpu_bh_enable(smp_processor_id())
+
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
+
+#define local_bh_enable() __local_bh_enable()
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/spinlock.h linux-2.4.29-uc1/include/asm-m68knommu/spinlock.h
--- linux-2.4.29/include/asm-m68knommu/spinlock.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/spinlock.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/spinlock.h>
diff -urN linux-2.4.29/include/asm-m68knommu/statfs.h linux-2.4.29-uc1/include/asm-m68knommu/statfs.h
--- linux-2.4.29/include/asm-m68knommu/statfs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/statfs.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/statfs.h>
diff -urN linux-2.4.29/include/asm-m68knommu/stat.h linux-2.4.29-uc1/include/asm-m68knommu/stat.h
--- linux-2.4.29/include/asm-m68knommu/stat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/stat.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/stat.h>
diff -urN linux-2.4.29/include/asm-m68knommu/string.h linux-2.4.29-uc1/include/asm-m68knommu/string.h
--- linux-2.4.29/include/asm-m68knommu/string.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/string.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,126 @@
+#ifndef _M68KNOMMU_STRING_H_
+#define _M68KNOMMU_STRING_H_
+
+#ifdef __KERNEL__ /* only set these up for kernel code */
+
+#include <asm/setup.h>
+#include <asm/page.h>
+
+#define __HAVE_ARCH_STRCPY
+static inline char * strcpy(char * dest,const char *src)
+{
+  char *xdest = dest;
+
+  __asm__ __volatile__
+       ("1:\tmoveb %1@+,%0@+\n\t"
+        "jne 1b"
+	: "=a" (dest), "=a" (src)
+        : "0" (dest), "1" (src) : "memory");
+  return xdest;
+}
+
+#define __HAVE_ARCH_STRNCPY
+static inline char * strncpy(char *dest, const char *src, size_t n)
+{
+  char *xdest = dest;
+
+  if (n == 0)
+    return xdest;
+
+  __asm__ __volatile__
+       ("1:\tmoveb %1@+,%0@+\n\t"
+	"jeq 2f\n\t"
+        "subql #1,%2\n\t"
+        "jne 1b\n\t"
+        "2:"
+        : "=a" (dest), "=a" (src), "=d" (n)
+        : "0" (dest), "1" (src), "2" (n)
+        : "memory");
+  return xdest;
+}
+
+
+#ifndef CONFIG_COLDFIRE
+
+#define __HAVE_ARCH_STRCMP
+static inline int strcmp(const char * cs,const char * ct)
+{
+  char __res;
+
+  __asm__
+       ("1:\tmoveb %0@+,%2\n\t" /* get *cs */
+        "cmpb %1@+,%2\n\t"      /* compare a byte */
+        "jne  2f\n\t"           /* not equal, break out */
+        "tstb %2\n\t"           /* at end of cs? */
+        "jne  1b\n\t"           /* no, keep going */
+        "jra  3f\n\t"		/* strings are equal */
+        "2:\tsubb %1@-,%2\n\t"  /* *cs - *ct */
+        "3:"
+        : "=a" (cs), "=a" (ct), "=d" (__res)
+        : "0" (cs), "1" (ct));
+
+  return __res;
+}
+
+#define __HAVE_ARCH_STRNCMP
+static inline int strncmp(const char * cs,const char * ct,size_t count)
+{
+  char __res;
+
+  if (!count)
+    return 0;
+  __asm__
+       ("1:\tmovb %0@+,%3\n\t"          /* get *cs */
+        "cmpb   %1@+,%3\n\t"            /* compare a byte */
+        "jne    3f\n\t"                 /* not equal, break out */
+        "tstb   %3\n\t"                 /* at end of cs? */
+        "jeq    4f\n\t"                 /* yes, all done */
+        "subql  #1,%2\n\t"              /* no, adjust count */
+        "jne    1b\n\t"                 /* more to do, keep going */
+        "2:\tmoveq #0,%3\n\t"           /* strings are equal */
+        "jra    4f\n\t"
+        "3:\tsubb %1@-,%3\n\t"          /* *cs - *ct */
+        "4:"
+        : "=a" (cs), "=a" (ct), "=d" (count), "=d" (__res)
+        : "0" (cs), "1" (ct), "2" (count));
+  return __res;
+}
+
+#endif /* CONFIG_COLDFIRE */
+
+#define __HAVE_ARCH_MEMSET
+extern void * memset(void * s, int c, size_t count);
+
+#define __HAVE_ARCH_MEMCPY
+extern void * memcpy(void *d, const void *s, size_t count);
+
+#else /* KERNEL */
+
+/*
+ *	let user libraries deal with these,
+ *	IMHO the kernel has no place defining these functions for user apps
+ */
+
+#define __HAVE_ARCH_STRCPY 1
+#define __HAVE_ARCH_STRNCPY 1
+#define __HAVE_ARCH_STRCAT 1
+#define __HAVE_ARCH_STRNCAT 1
+#define __HAVE_ARCH_STRCMP 1
+#define __HAVE_ARCH_STRNCMP 1
+#define __HAVE_ARCH_STRNICMP 1
+#define __HAVE_ARCH_STRCHR 1
+#define __HAVE_ARCH_STRRCHR 1
+#define __HAVE_ARCH_STRSTR 1
+#define __HAVE_ARCH_STRLEN 1
+#define __HAVE_ARCH_STRNLEN 1
+#define __HAVE_ARCH_MEMSET 1
+#define __HAVE_ARCH_MEMCPY 1
+#define __HAVE_ARCH_MEMMOVE 1
+#define __HAVE_ARCH_MEMSCAN 1
+#define __HAVE_ARCH_MEMCMP 1
+#define __HAVE_ARCH_MEMCHR 1
+#define __HAVE_ARCH_STRTOK 1
+
+#endif /* KERNEL */
+
+#endif /* _M68K_STRING_H_ */
diff -urN linux-2.4.29/include/asm-m68knommu/system.h linux-2.4.29-uc1/include/asm-m68knommu/system.h
--- linux-2.4.29/include/asm-m68knommu/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/system.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,333 @@
+#ifndef _M68KNOMMU_SYSTEM_H
+#define _M68KNOMMU_SYSTEM_H
+
+#include <linux/config.h> /* get configuration macros */
+#include <linux/linkage.h>
+#include <asm/segment.h>
+#include <asm/entry.h>
+#ifdef CONFIG_COLDFIRE
+#include <asm/mcfsim.h>
+#include <asm/coldfire.h>
+#endif
+
+#define prepare_to_switch()	do { } while(0)
+
+/*
+ * switch_to(n) should switch tasks to task ptr, first checking that
+ * ptr isn't the current task, in which case it does nothing.  This
+ * also clears the TS-flag if the task we switched to has used the
+ * math co-processor latest.
+ */
+/*
+ * switch_to() saves the extra registers, that are not saved
+ * automatically by SAVE_SWITCH_STACK in resume(), ie. d0-d5 and
+ * a0-a1. Some of these are used by schedule() and its predecessors
+ * and so we might get see unexpected behaviors when a task returns
+ * with unexpected register values.
+ *
+ * syscall stores these registers itself and none of them are used
+ * by syscall after the function in the syscall has been called.
+ *
+ * Beware that resume now expects *next to be in d1 and the offset of
+ * tss to be in a1. This saves a few instructions as we no longer have
+ * to push them onto the stack and read them back right after.
+ *
+ * 02/17/96 - Jes Sorensen (jds@kom.auc.dk)
+ *
+ * Changed 96/09/19 by Andreas Schwab
+ * pass prev in a0, next in a1, offset of tss in d1, and whether
+ * the mm structures are shared in d2 (to avoid atc flushing).
+ */
+asmlinkage void resume(void);
+#define switch_to(prev,next,last) { \
+  void *_last;										\
+  __asm__ __volatile__(								\
+  			"movel	%1, %%a0\n\t"					\
+			"movel	%2, %%a1\n\t"					\
+			"jbsr " SYMBOL_NAME_STR(resume) "\n\t" 	\
+			"movel	%%d1, %0\n\t"					\
+		       : "=d" (_last)						\
+		       : "d" (prev),						\
+			     "d" (next)							\
+		       : "cc", "d0", "d1", "d2", "d3", "d4", "d5", "a0", "a1");	\
+  (last) = _last; 									\
+}
+
+#ifdef CONFIG_COLDFIRE
+#define __sti() __asm__ __volatile__ ( \
+	"move %/sr,%%d0\n\t" \
+	"andi.l #0xf8ff,%%d0\n\t" \
+	"move %%d0,%/sr\n" \
+	: /* no outputs */ \
+	: \
+        : "cc", "%d0", "memory")
+#define __cli() __asm__ __volatile__ ( \
+	"move %/sr,%%d0\n\t" \
+	"ori.l  #0x0700,%%d0\n\t" \
+	"move %%d0,%/sr\n" \
+	: /* no inputs */ \
+	: \
+	: "cc", "%d0", "memory")
+#else
+
+/* portable version */ /* FIXME - see entry.h*/
+#define ALLOWINT 0xf8ff
+
+#define __sti() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory")
+#define __cli() asm volatile ("oriw  #0x0700,%%sr": : : "memory")
+#endif
+
+#define __save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory")
+#define __restore_flags(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory")
+#define	__save_and_cli(flags) do { save_flags(flags); cli(); } while(0) 
+#define	__save_and_sti(flags) do { save_flags(flags); sti(); } while(0) 
+
+#define iret() __asm__ __volatile__ ("rte": : :"memory", "sp", "cc")
+
+/* For spinlocks etc */
+#define local_irq_save(x)	__save_and_cli(x)
+#define local_irq_set(x)	__save_and_sti(x)
+#define local_irq_restore(x)	__restore_flags(x)
+#define local_irq_disable()	__cli()
+#define local_irq_enable()	__sti()
+
+#define cli()			__cli()
+#define sti()			__sti()
+#define save_flags(x)		__save_flags(x)
+#define restore_flags(x)	__restore_flags(x)
+#define save_and_cli(x)	__save_and_cli(x)
+#define save_and_set(x)	__save_and_sti(x)
+
+/*
+ * Force strict CPU ordering.
+ * Not really required on m68k...
+ */
+#define nop()  asm volatile ("nop"::)
+#define mb()   asm volatile (""   : : :"memory")
+#define rmb()  asm volatile (""   : : :"memory")
+#define wmb()  asm volatile (""   : : :"memory")
+#define set_mb(var, value)     do { var = value; mb(); } while (0)
+#define set_wmb(var, value)    do { var = value; wmb(); } while (0)
+
+#ifdef CONFIG_SMP
+#define smp_mb()	mb()
+#define smp_rmb()	rmb()
+#define smp_wmb()	wmb()
+#else
+#define smp_mb()	barrier()
+#define smp_rmb()	barrier()
+#define smp_wmb()	barrier()
+#endif
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+#define tas(ptr) (xchg((ptr),1))
+
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((volatile struct __xchg_dummy *)(x))
+
+#ifndef CONFIG_RMW_INSNS
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+  unsigned long tmp, flags;
+
+  save_flags(flags);
+  cli();
+
+  switch (size) {
+  case 1:
+    __asm__ __volatile__
+    ("moveb %2,%0\n\t"
+     "moveb %1,%2"
+    : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
+    break;
+  case 2:
+    __asm__ __volatile__
+    ("movew %2,%0\n\t"
+     "movew %1,%2"
+    : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
+    break;
+  case 4:
+    __asm__ __volatile__
+    ("movel %2,%0\n\t"
+     "movel %1,%2"
+    : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
+    break;
+  }
+  restore_flags(flags);
+  return tmp;
+}
+#else
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+	switch (size) {
+	    case 1:
+		__asm__ __volatile__
+			("moveb %2,%0\n\t"
+			 "1:\n\t"
+			 "casb %0,%1,%2\n\t"
+			 "jne 1b"
+			 : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
+		break;
+	    case 2:
+		__asm__ __volatile__
+			("movew %2,%0\n\t"
+			 "1:\n\t"
+			 "casw %0,%1,%2\n\t"
+			 "jne 1b"
+			 : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
+		break;
+	    case 4:
+		__asm__ __volatile__
+			("movel %2,%0\n\t"
+			 "1:\n\t"
+			 "casl %0,%1,%2\n\t"
+			 "jne 1b"
+			 : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
+		break;
+	}
+	return x;
+}
+#endif
+
+
+
+#ifdef CONFIG_M68332
+#define HARD_RESET_NOW() ({		\
+        cli();				\
+        asm("				\
+	movew   #0x0000, 0xfffa6a;	\
+        reset;				\
+        /*movew #0x1557, 0xfffa44;*/	\
+        /*movew #0x0155, 0xfffa46;*/	\
+        moveal #0, %a0;			\
+        movec %a0, %vbr;		\
+        moveal 0, %sp;			\
+        moveal 4, %a0;			\
+        jmp (%a0);			\
+        ");				\
+})
+#endif
+
+#if defined( CONFIG_M68328 ) || defined( CONFIG_M68EZ328 ) || \
+	defined (CONFIG_M68360) || defined( CONFIG_M68VZ328 )
+#define HARD_RESET_NOW() ({		\
+        cli();				\
+        asm("				\
+        moveal #0x10c00000, %a0;	\
+        moveb #0, 0xFFFFF300;		\
+        moveal 0(%a0), %sp;		\
+        moveal 4(%a0), %a0;		\
+        jmp (%a0);			\
+        ");				\
+})
+#endif
+
+#if defined(CONFIG_COLDFIRE)
+#if defined(CONFIG_M5272) && (defined(CONFIG_NETtel) || \
+	defined(CONFIG_GILBARCONAP) || defined(CONFIG_SE1100) || defined(CONFIG_HW_FEITH))
+/*
+ *	Need to account for broken early mask of 5272 silicon. So don't
+ *	jump through the original start address. Jump strait into the
+ *	known start of the FLASH code.
+ */
+#define HARD_RESET_NOW() ({		\
+        asm("				\
+	movew #0x2700, %sr;		\
+        jmp 0xf0000400;			\
+        ");				\
+})
+/*
+ * HARD_RESET_NOW() for senTec COBRA5272:
+ *
+ * ATTENTION!
+ * This seems to be a dirty workaround for the reboot!
+ * We currently just jump to the startcode of colilo.
+ * 
+ * If you are using dBUG, you will have to ajust the jmp
+ * destination. Look for the address of _asm_startmeup, and
+ * put it in the jump statement!
+ * 
+ */
+#elif defined(CONFIG_COBRA5272)
+#define HARD_RESET_NOW() ({      \
+   asm("           \
+         jmp 0xffe00400;             \
+       ");          \
+})
+
+#elif defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA)
+#define HARD_RESET_NOW() ({		\
+        asm("				\
+	movew #0x2700, %sr;		\
+	moveal #0x10000044, %a0;	\
+	movel #0xffffffff, (%a0);	\
+	moveal #0x10000001, %a0;	\
+	moveb #0x00, (%a0);		\
+        moveal #0xf0000004, %a0;	\
+        moveal (%a0), %a0;		\
+        jmp (%a0);			\
+        ");				\
+})
+#elif defined(CONFIG_M5272) && defined(CONFIG_SIGNAL_MCP751)
+#define HARD_RESET_NOW() ({		\
+        asm("				\
+	movew #0x2700, %sr;		\
+	jmp 0xff000400;			\
+        ");				\
+})
+
+#elif defined(CONFIG_SED_SIOSIII)
+	/*
+	 * The SIOS III has a bit in memory, that when set, resets the SIOS III.
+	 * This routine sets that bit. It gets the address of the bit by
+	 * looking at the chip select register. This way, I only need to
+	 * hardcode which chip select the reset bit is on, not the address.
+	 */
+#define HARD_RESET_NOW() \
+({						\
+	unsigned short csar;			\
+	unsigned long csarl;			\
+	unsigned long volatile *reset;		\
+	asm("move.w	#0x2700, %sr");		\
+	csar = *((volatile unsigned short *)(MCF_MBAR + MCFSIM_CSAR2));	\
+	csarl = csar;				\
+	csarl = csarl << 16;			\
+	reset = (unsigned long volatile *)csarl;\
+	while(1)				\
+	*reset = (0x00000001 << 6);\
+})
+#elif defined(CONFIG_M5282)
+	/*
+	 * The MCF5282 has a bit (SOFTRST) in memory (Reset Control Register RCR),
+	 * that when set, resets the MCF5282.
+	 */
+#define HARD_RESET_NOW() \
+({						\
+	unsigned char volatile *reset;		\
+	asm("move.w	#0x2700, %sr");		\
+	reset = ((volatile unsigned short *)(MCF_IPSBAR + 0x110000));	\
+	while(1)				\
+	*reset |= (0x01 << 7);\
+})
+#elif defined(CONFIG_M5235) // did not use MCF_IPSBAR define
+#define HARD_RESET_NOW() ({		\
+	asm("				\
+	movew #0x2700, %sr;		\
+	movel #0x01000000, %sp;		\
+	moveal #0x40110000, %a0;	\
+	moveb #0x80, (%a0);		\
+	");				\
+})
+#else
+#define HARD_RESET_NOW() ({		\
+	asm("				\
+	movew #0x2700, %sr;		\
+	moveal #0x4, %a0;		\
+	moveal (%a0), %a0;		\
+	jmp (%a0);			\
+	");				\
+})
+#endif
+#endif
+
+#endif /* _M68KNOMMU_SYSTEM_H */
diff -urN linux-2.4.29/include/asm-m68knommu/termbits.h linux-2.4.29-uc1/include/asm-m68knommu/termbits.h
--- linux-2.4.29/include/asm-m68knommu/termbits.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/termbits.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/termbits.h>
diff -urN linux-2.4.29/include/asm-m68knommu/termios.h linux-2.4.29-uc1/include/asm-m68knommu/termios.h
--- linux-2.4.29/include/asm-m68knommu/termios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/termios.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/termios.h>
diff -urN linux-2.4.29/include/asm-m68knommu/timex.h linux-2.4.29-uc1/include/asm-m68knommu/timex.h
--- linux-2.4.29/include/asm-m68knommu/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/timex.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/timex.h>
diff -urN linux-2.4.29/include/asm-m68knommu/tlb.h linux-2.4.29-uc1/include/asm-m68knommu/tlb.h
--- linux-2.4.29/include/asm-m68knommu/tlb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/tlb.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/tlb.h>
diff -urN linux-2.4.29/include/asm-m68knommu/traps.h linux-2.4.29-uc1/include/asm-m68knommu/traps.h
--- linux-2.4.29/include/asm-m68knommu/traps.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/traps.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,252 @@
+/*
+ *  linux/include/asm/traps.h
+ *
+ *  Copyright (C) 1993        Hamish Macdonald
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _M68K_TRAPS_H
+#define _M68K_TRAPS_H
+
+#ifndef __ASSEMBLY__
+
+typedef void (*e_vector)(void);
+
+extern e_vector vectors[];
+
+#endif
+
+#define VEC_BUSERR  (2)
+#define VEC_ADDRERR (3)
+#define VEC_ILLEGAL (4)
+#define VEC_ZERODIV (5)
+#define VEC_CHK     (6)
+#define VEC_TRAP    (7)
+#define VEC_PRIV    (8)
+#define VEC_TRACE   (9)
+#define VEC_LINE10  (10)
+#define VEC_LINE11  (11)
+#define VEC_RESV1   (12)
+#define VEC_COPROC  (13)
+#define VEC_FORMAT  (14)
+#define VEC_UNINT   (15)
+#define VEC_SPUR    (24)
+#define VEC_INT1    (25)
+#define VEC_INT2    (26)
+#define VEC_INT3    (27)
+#define VEC_INT4    (28)
+#define VEC_INT5    (29)
+#define VEC_INT6    (30)
+#define VEC_INT7    (31)
+#define VEC_SYS     (32)
+#define VEC_TRAP1   (33)
+#define VEC_TRAP2   (34)
+#define VEC_TRAP3   (35)
+#define VEC_TRAP4   (36)
+#define VEC_TRAP5   (37)
+#define VEC_TRAP6   (38)
+#define VEC_TRAP7   (39)
+#define VEC_TRAP8   (40)
+#define VEC_TRAP9   (41)
+#define VEC_TRAP10  (42)
+#define VEC_TRAP11  (43)
+#define VEC_TRAP12  (44)
+#define VEC_TRAP13  (45)
+#define VEC_TRAP14  (46)
+#define VEC_TRAP15  (47)
+#define VEC_FPBRUC  (48)
+#define VEC_FPIR    (49)
+#define VEC_FPDIVZ  (50)
+#define VEC_FPUNDER (51)
+#define VEC_FPOE    (52)
+#define VEC_FPOVER  (53)
+#define VEC_FPNAN   (54)
+#define VEC_FPUNSUP (55)
+#define	VEC_UNIMPEA (60)
+#define	VEC_UNIMPII (61)
+#define VEC_USER    (64)
+
+#define VECOFF(vec) ((vec)<<2)
+
+#ifndef __ASSEMBLY__
+
+/* Status register bits */
+#define PS_T  (0x8000)
+#define PS_S  (0x2000)
+#define PS_M  (0x1000)
+#define PS_C  (0x0001)
+
+/* bits for 68020/68030 special status word */
+
+#define FC    (0x8000)
+#define FB    (0x4000)
+#define RC    (0x2000)
+#define RB    (0x1000)
+#define DF    (0x0100)
+#define RM    (0x0080)
+#define RW    (0x0040)
+#define SZ    (0x0030)
+#define DFC   (0x0007)
+
+/* bits for 68030 MMU status register (mmusr,psr) */
+
+#define MMU_B	     (0x8000)    /* bus error */
+#define MMU_L	     (0x4000)    /* limit violation */
+#define MMU_S	     (0x2000)    /* supervisor violation */
+#define MMU_WP	     (0x0800)    /* write-protected */
+#define MMU_I	     (0x0400)    /* invalid descriptor */
+#define MMU_M	     (0x0200)    /* ATC entry modified */
+#define MMU_T	     (0x0040)    /* transparent translation */
+#define MMU_NUM      (0x0007)    /* number of levels traversed */
+
+
+/* bits for 68040 special status word */
+#define CP_040	(0x8000)
+#define CU_040	(0x4000)
+#define CT_040	(0x2000)
+#define CM_040	(0x1000)
+#define MA_040	(0x0800)
+#define ATC_040 (0x0400)
+#define LK_040	(0x0200)
+#define RW_040	(0x0100)
+#define SIZ_040 (0x0060)
+#define TT_040	(0x0018)
+#define TM_040	(0x0007)
+
+/* bits for 68040 write back status word */
+#define WBV_040   (0x80)
+#define WBSIZ_040 (0x60)
+#define WBBYT_040 (0x20)
+#define WBWRD_040 (0x40)
+#define WBLNG_040 (0x00)
+#define WBTT_040  (0x18)
+#define WBTM_040  (0x07)
+
+/* bus access size codes */
+#define BA_SIZE_BYTE    (0x20)
+#define BA_SIZE_WORD    (0x40)
+#define BA_SIZE_LONG    (0x00)
+#define BA_SIZE_LINE    (0x60)
+
+/* bus access transfer type codes */
+#define BA_TT_MOVE16    (0x08)
+
+#ifndef NO_MM
+/* bits for 68040 MMU status register (mmusr) */
+#define MMU_B_040   (0x0800)
+#define MMU_G_040   (0x0400)
+#define MMU_S_040   (0x0080)
+#define MMU_CM_040  (0x0060)
+#define MMU_M_040   (0x0010)
+#define MMU_WP_040  (0x0004)
+#define MMU_T_040   (0x0002)
+#define MMU_R_040   (0x0001)
+
+/* bits in the 68060 fault status long word (FSLW) */
+#define	MMU060_MA	(0x08000000)	/* misaligned */
+#define	MMU060_LK	(0x02000000)	/* locked transfer */
+#define	MMU060_RW	(0x01800000)	/* read/write */
+# define MMU060_RW_W	(0x00800000)	/* write */
+# define MMU060_RW_R	(0x01000000)	/* read */
+# define MMU060_RW_RMW	(0x01800000)	/* read/modify/write */
+# define MMU060_W		(0x00800000)	/* general write, includes rmw */
+#define	MMU060_SIZ	(0x00600000)	/* transfer size */
+#define	MMU060_TT	(0x00180000)	/* transfer type (TT) bits */
+#define	MMU060_TM	(0x00070000)	/* transfer modifier (TM) bits */
+#define	MMU060_IO	(0x00008000)	/* instruction or operand */
+#define	MMU060_PBE	(0x00004000)	/* push buffer bus error */
+#define	MMU060_SBE	(0x00002000)	/* store buffer bus error */
+#define	MMU060_PTA	(0x00001000)	/* pointer A fault */
+#define	MMU060_PTB	(0x00000800)	/* pointer B fault */
+#define	MMU060_IL	(0x00000400)	/* double indirect descr fault */
+#define	MMU060_PF	(0x00000200)	/* page fault (invalid descr) */
+#define	MMU060_SP	(0x00000100)	/* supervisor protection */
+#define	MMU060_WP	(0x00000080)	/* write protection */
+#define	MMU060_TWE	(0x00000040)	/* bus error on table search */
+#define	MMU060_RE	(0x00000020)	/* bus error on read */
+#define	MMU060_WE	(0x00000010)	/* bus error on write */
+#define	MMU060_TTR	(0x00000008)	/* error caused by TTR translation */
+#define	MMU060_BPE	(0x00000004)	/* branch prediction error */
+#define	MMU060_SEE	(0x00000001)	/* software emulated error */
+
+/* cases of missing or invalid descriptors */
+#define MMU060_DESC_ERR	(MMU060_TWE | MMU060_PTA | MMU060_PTB | \
+						 MMU060_IL  | MMU060_PF)
+/* bits that indicate real errors */
+#define MMU060_ERR_BITS	(MMU060_PBE | MMU060_SBE | MMU060_DESC_ERR | \
+						 MMU060_SP  | MMU060_WP  | MMU060_RE | \
+						 MMU060_WE)
+#endif /* NO_MM */
+
+/* structure for stack frames */
+
+struct frame {
+    struct pt_regs ptregs;
+    union {
+	    struct {
+		    unsigned long  iaddr;    /* instruction address */
+	    } fmt2;
+	    struct {
+		    unsigned long  effaddr;  /* effective address */
+	    } fmt3;
+	    struct {
+		    unsigned long  effaddr;  /* effective address */
+		    unsigned long  pc;	     /* pc of faulted instr */
+	    } fmt4;
+	    struct {
+		    unsigned long  effaddr;  /* effective address */
+		    unsigned short ssw;      /* special status word */
+		    unsigned short wb3s;     /* write back 3 status */
+		    unsigned short wb2s;     /* write back 2 status */
+		    unsigned short wb1s;     /* write back 1 status */
+		    unsigned long  faddr;    /* fault address */
+		    unsigned long  wb3a;     /* write back 3 address */
+		    unsigned long  wb3d;     /* write back 3 data */
+		    unsigned long  wb2a;     /* write back 2 address */
+		    unsigned long  wb2d;     /* write back 2 data */
+		    unsigned long  wb1a;     /* write back 1 address */
+		    unsigned long  wb1dpd0;  /* write back 1 data/push data 0*/
+		    unsigned long  pd1;      /* push data 1*/
+		    unsigned long  pd2;      /* push data 2*/
+		    unsigned long  pd3;      /* push data 3*/
+	    } fmt7;
+	    struct {
+		    unsigned long  iaddr;    /* instruction address */
+		    unsigned short int1[4];  /* internal registers */
+	    } fmt9;
+	    struct {
+		    unsigned short int1;
+		    unsigned short ssw;      /* special status word */
+		    unsigned short isc;      /* instruction stage c */
+		    unsigned short isb;      /* instruction stage b */
+		    unsigned long  daddr;    /* data cycle fault address */
+		    unsigned short int2[2];
+		    unsigned long  dobuf;    /* data cycle output buffer */
+		    unsigned short int3[2];
+	    } fmta;
+	    struct {
+		    unsigned short int1;
+		    unsigned short ssw;     /* special status word */
+		    unsigned short isc;     /* instruction stage c */
+		    unsigned short isb;     /* instruction stage b */
+		    unsigned long  daddr;   /* data cycle fault address */
+		    unsigned short int2[2];
+		    unsigned long  dobuf;   /* data cycle output buffer */
+		    unsigned short int3[4];
+		    unsigned long  baddr;   /* stage B address */
+		    unsigned short int4[2];
+		    unsigned long  dibuf;   /* data cycle input buffer */
+		    unsigned short int5[3];
+		    unsigned	   ver : 4; /* stack frame version # */
+		    unsigned	   int6:12;
+		    unsigned short int7[18];
+	    } fmtb;
+    } un;
+};
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _M68K_TRAPS_H */
diff -urN linux-2.4.29/include/asm-m68knommu/types.h linux-2.4.29-uc1/include/asm-m68knommu/types.h
--- linux-2.4.29/include/asm-m68knommu/types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/types.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,59 @@
+#ifndef _M68K_TYPES_H
+#define _M68K_TYPES_H
+
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue.  However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ */
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide.  */
+
+typedef u32 dma_addr_t;
+typedef u32 dma64_addr_t;
+
+#endif /* __KERNEL__ */
+
+#endif /* _M68K_TYPES_H */
diff -urN linux-2.4.29/include/asm-m68knommu/uaccess.h linux-2.4.29-uc1/include/asm-m68knommu/uaccess.h
--- linux-2.4.29/include/asm-m68knommu/uaccess.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/uaccess.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,185 @@
+#ifndef __M68KNOMMU_UACCESS_H
+#define __M68KNOMMU_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/segment.h>
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+/* We let the MMU do all checking */
+extern inline int access_ok(int type, const void * addr, unsigned long size)
+{
+#define	RANGE_CHECK_OK(addr, size, lower, upper) \
+	(((addr) >= (lower)) && (((addr) + (size)) < (upper)))
+#if defined CONFIG_COLDFIRE
+	extern unsigned long _ramend;
+    extern int is_in_rom(unsigned long addr);
+
+	return(RANGE_CHECK_OK((unsigned long) addr, size, 0L, _ramend) ||
+			(is_in_rom((unsigned long) addr) &&
+					is_in_rom((unsigned long) addr + size)));
+#else
+	/* DAVIDM - this could be restricted a lot more */
+	return(RANGE_CHECK_OK((unsigned long)addr, size, 0, 0x10f00000));
+#endif
+}
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+	return access_ok(type,addr,size)?0:-EFAULT;
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ */
+
+#define put_user(x, ptr)				\
+({							\
+    int __pu_err = 0;					\
+    typeof(*(ptr)) __pu_val = (x);			\
+    switch (sizeof (*(ptr))) {				\
+    case 1:						\
+	__put_user_asm(__pu_err, __pu_val, ptr, b);	\
+	break;						\
+    case 2:						\
+	__put_user_asm(__pu_err, __pu_val, ptr, w);	\
+	break;						\
+    case 4:						\
+	__put_user_asm(__pu_err, __pu_val, ptr, l);	\
+	break;						\
+    case 8:						\
+	memcpy(ptr, &__pu_val, sizeof (*(ptr))); \
+	break;						\
+    default:						\
+	__pu_err = __put_user_bad();			\
+	break;						\
+    }							\
+    __pu_err;						\
+})
+#define __put_user(x, ptr) put_user(x, ptr)
+
+extern int __put_user_bad(void);
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+
+#define __ptr(x) ((unsigned long *)(x))
+
+#define __put_user_asm(err,x,ptr,bwl)				\
+	__asm__ ("move" #bwl " %0,%1"				\
+		: /* no outputs */						\
+		:"d" (x),"m" (*__ptr(ptr)) : "memory")
+
+#define get_user(x, ptr)					\
+({								\
+    int __gu_err = 0;						\
+    typeof(*(ptr)) __gu_val = 0;				\
+    switch (sizeof(*(ptr))) {					\
+    case 1:							\
+	__get_user_asm(__gu_err, __gu_val, ptr, b, "=d");	\
+	break;							\
+    case 2:							\
+	__get_user_asm(__gu_err, __gu_val, ptr, w, "=r");	\
+	break;							\
+    case 4:							\
+	__get_user_asm(__gu_err, __gu_val, ptr, l, "=r");	\
+	break;							\
+    case 8:							\
+	memcpy(&__gu_val, ptr, sizeof (*(ptr))); \
+	break;							\
+    default:							\
+	__gu_val = 0;						\
+	__gu_err = __get_user_bad();				\
+	break;							\
+    }								\
+    (x) = __gu_val;						\
+    __gu_err;							\
+})
+#define __get_user(x, ptr) get_user(x, ptr)
+
+extern int __get_user_bad(void);
+
+#define __get_user_asm(err,x,ptr,bwl,reg)	\
+	__asm__ ("move" #bwl " %1,%0"			\
+		 : "=d" (x)							\
+		 : "m" (*__ptr(ptr)))
+
+#define copy_from_user(to, from, n)		(memcpy(to, from, n), 0)
+#define copy_to_user(to, from, n)		(memcpy(to, from, n), 0)
+
+#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
+#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
+
+#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; })
+
+#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; })
+
+/*
+ * Copy a null terminated string from userspace.
+ */
+
+static inline long
+strncpy_from_user(char *dst, const char *src, long count)
+{
+	char *tmp;
+	strncpy(dst, src, count);
+	for (tmp = dst; *tmp && count > 0; tmp++, count--)
+		;
+	return(tmp - dst); /* DAVIDM should we count a NUL ?  check getname */
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 on exception, a value greater than N if too long
+ */
+static inline long strnlen_user(const char *src, long n)
+{
+	return(strlen(src) + 1); /* DAVIDM make safer */
+}
+
+#define strlen_user(str) strnlen_user(str, 32767)
+
+/*
+ * Zero Userspace
+ */
+
+static inline unsigned long
+clear_user(void *to, unsigned long n)
+{
+	memset(to, 0, n);
+    return(0);
+}
+
+#endif /* _M68KNOMMU_UACCESS_H */
diff -urN linux-2.4.29/include/asm-m68knommu/uCbootstrap.h linux-2.4.29-uc1/include/asm-m68knommu/uCbootstrap.h
--- linux-2.4.29/include/asm-m68knommu/uCbootstrap.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/uCbootstrap.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,207 @@
+/*
+ * uCbootstrap.h:  uCbootstrap and uCbootloader system call interface
+ *
+ * (c) Copyright 1999 Rt-Control Inc.
+ * (c) Copyright 2001 Arcturus Networks Inc.
+ * Maintained by Michael Durrant <mdurrant@arcturusnetworks.com>
+ *
+ * Release notes:
+ * 7 Nov 2001 by mdurrant@arcturusnetworks.com
+ *            - moved old uCbootloader.h file from the 
+ *              uCdimm platform directory into linux/asm-m68knommu/
+ *            - combined the bootstd.h and flash.h file from uCsimm
+ *              and uCdimm into a common uCbootloader.h file.
+ *
+ */
+
+#ifndef __UCBOOTSTRAP_H__
+#define __UCBOOTSTRAP_H__
+
+#define NR_BSC 23            /* last used bootloader system call */
+
+#define __BN_reset        0  /* reset and start the bootloader */
+#define __BN_test         1  /* tests the system call interface */
+#define __BN_exec         2  /* executes a bootloader image */
+#define __BN_exit         3  /* terminates a bootloader image */
+#define __BN_program      4  /* program FLASH from a chain */
+#define __BN_erase        5  /* erase sector(s) of FLASH */
+#define __BN_open         6
+#define __BN_write        7
+#define __BN_read         8
+#define __BN_close        9
+#define __BN_mmap         10 /* map a file descriptor into memory */
+#define __BN_munmap       11 /* remove a file to memory mapping */
+#define __BN_gethwaddr    12 /* get the hardware address of my interfaces */
+#define __BN_getserialnum 13 /* get the serial number of this board */
+#define __BN_getbenv      14 /* get a bootloader envvar */
+#define __BN_setbenv      15 /* get a bootloader envvar */
+#define __BN_setpmask     16 /* set the protection mask */
+#define __BN_readbenv     17 /* read environment variables */
+#define __BN_flash_chattr_range		18
+#define __BN_flash_erase_range		19
+#define __BN_flash_write_range		20
+#define __BN_ramload			21 /* load kernel into RAM and exec */
+#define __BN_program2      22  /* program second FLASH from a chain */
+
+
+/* Calling conventions compatible to (uC)linux/68k
+ * We use simmilar macros to call into the bootloader as for uClinux
+ */
+
+#define __bsc_return(type, res) \
+do { \
+   if ((unsigned long)(res) >= (unsigned long)(-64)) { \
+      /* let errno be a function, preserve res in %d0 */ \
+      int __err = -(res); \
+      errno = __err; \
+      res = -1; \
+   } \
+   return (type)(res); \
+} while (0)
+
+#define _bsc0(type,name) \
+type name(void) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc1(type,name,atype,a) \
+type name(atype a) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc2(type,name,atype,a,btype,b) \
+type name(atype a, btype b) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc3(type,name,atype,a,btype,b,ctype,c) \
+type name(atype a, btype b, ctype c) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
+type name(atype a, btype b, ctype c, dtype d) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   register long __d __asm__ ("%d4") = (long)d; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c), "d" (__d) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+#define _bsc5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
+type name(atype a, btype b, ctype c, dtype d, etype e) \
+{ \
+   register long __res __asm__ ("%d0") = __BN_##name; \
+   register long __a __asm__ ("%d1") = (long)a; \
+   register long __b __asm__ ("%d2") = (long)b; \
+   register long __c __asm__ ("%d3") = (long)c; \
+   register long __d __asm__ ("%d4") = (long)d; \
+   register long __e __asm__ ("%d5") = (long)e; \
+   __asm__ __volatile__ ("trap #2" \
+                         : "=g" (__res) \
+                         : "0" (__res), "d" (__a), "d" (__b), \
+                           "d" (__c), "d" (__d), "d" (__e) \
+                         : "%d0"); \
+   __bsc_return(type,__res); \
+}
+
+/* Command codes for the flash_command routine */
+#define FLASH_SELECT    0       /* no command; just perform the mapping */
+#define FLASH_RESET     1       /* reset to read mode */
+#define FLASH_READ      1       /* reset to read mode, by any other name */
+#define FLASH_AUTOSEL   2       /* autoselect (fake Vid on pin 9) */
+#define FLASH_PROG      3       /* program a word */
+#define FLASH_CERASE    4       /* chip erase */
+#define FLASH_SERASE    5       /* sector erase */
+#define FLASH_ESUSPEND  6       /* suspend sector erase */
+#define FLASH_ERESUME   7       /* resume sector erase */
+#define FLASH_UB        8       /* go into unlock bypass mode */
+#define FLASH_UBPROG    9       /* program a word using unlock bypass */
+#define FLASH_UBRESET   10      /* reset to read mode from unlock bypass mode */
+#define FLASH_LASTCMD   10      /* used for parameter checking */
+
+/* Return codes from flash_status */
+#define STATUS_READY    0       /* ready for action */
+#define STATUS_BUSY     1       /* operation in progress */
+#define STATUS_ERSUSP   2       /* erase suspended */
+#define STATUS_TIMEOUT  3       /* operation timed out */
+#define STATUS_ERROR    4       /* unclassified but unhappy status */
+
+/* manufacturer ID */
+#define AMDPART   	0x01
+#define TOSPART		0x98
+#define SSTPART		0xbf
+#define ATPART		0x1f
+
+/* A list of 4 AMD device ID's - add others as needed */
+#define ID_AM29DL800T   0x224A
+#define ID_AM29DL800B   0x22CB
+#define ID_AM29LV800T   0x22DA
+#define ID_AM29LV800B   0x225B
+#define ID_AM29LV160B   0x2249
+#define ID_AM29LV160T   0x22C4
+#define ID_TC58FVT160	0x00C2
+#define ID_TC58FVB160	0x0043
+#define ID_TC58FVB160X2	0x00430043
+#define ID_AM29LV400B   0x22BA
+#define ID_AT49BV1614   0x00C0
+#define ID_SST39VF160   0x2782
+/* definition for arm7tdni */
+#define ID_AT27LV1024	0x0000
+#define ID_AT29LV1024	0x0001
+
+#define SECTOR_DIRTY   0x01
+#define SECTOR_ERASED  0x02
+#define SECTOR_PROTECT 0x04
+
+#define PGM_ERASE_FIRST 0x0001
+#define PGM_RESET_AFTER 0x0002
+#define PGM_EXEC_AFTER  0x0004
+#define PGM_HALT_AFTER  0x0008
+#define PGM_DEBUG       0x0010
+
+/* an mnode points at 4k pages of data through an offset table. */
+typedef struct _memnode {
+  int len;
+  int *offset;
+} mnode_t;
+
+#endif /* __UCBOOTSTRAP_H__ */
diff -urN linux-2.4.29/include/asm-m68knommu/ucontext.h linux-2.4.29-uc1/include/asm-m68knommu/ucontext.h
--- linux-2.4.29/include/asm-m68knommu/ucontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/ucontext.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,41 @@
+#ifndef _M68KNOMMU_UCONTEXT_H
+#define _M68KNOMMU_UCONTEXT_H
+
+typedef int greg_t;
+#define NGREG 18
+typedef greg_t gregset_t[NGREG];
+
+#ifndef NO_FPU
+typedef struct fpregset {
+	int f_pcr;
+	int f_psr;
+	int f_fpiaddr;
+	int f_fpregs[8][3];
+} fpregset_t;
+#endif
+
+struct mcontext {
+	int version;
+	gregset_t gregs;
+#ifndef NO_FPU
+	fpregset_t fpregs;
+#endif
+};
+
+#define MCONTEXT_VERSION 2
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct mcontext	  uc_mcontext;
+#ifndef NO_FPU
+	unsigned long	  uc_filler[80];
+#endif
+#ifdef CONFIG_COLDFIRE
+	unsigned short 	  uc_formatvec;	/* to restore format / vector in exception frame */
+#endif
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/unaligned.h linux-2.4.29-uc1/include/asm-m68knommu/unaligned.h
--- linux-2.4.29/include/asm-m68knommu/unaligned.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/unaligned.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,32 @@
+#ifndef __M68K_UNALIGNED_H
+#define __M68K_UNALIGNED_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_COLDFIRE
+
+/* Use memmove here, so gcc does not insert a __builtin_memcpy. */
+
+#define get_unaligned(ptr) \
+  ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
+
+#define put_unaligned(val, ptr)				\
+  ({ __typeof__(*(ptr)) __tmp = (val);			\
+     memmove((ptr), &__tmp, sizeof(*(ptr)));		\
+     (void)0; })
+
+#else
+/*
+ * The m68k can do unaligned accesses itself. 
+ *
+ * The strange macros are there to make sure these can't
+ * be misused in a way that makes them not work on other
+ * architectures where unaligned accesses aren't as simple.
+ */
+
+#define get_unaligned(ptr) (*(ptr))
+#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
+
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-m68knommu/unistd.h linux-2.4.29-uc1/include/asm-m68knommu/unistd.h
--- linux-2.4.29/include/asm-m68knommu/unistd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/unistd.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,426 @@
+#ifndef _ASM_M68K_UNISTD_H_
+#define _ASM_M68K_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_chown		 16
+#define __NR_break		 17
+#define __NR_oldstat		 18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_umount2		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+#define __NR_oldolduname	 59
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_old_getrlimit	 76
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+#define __NR_ioperm		101
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_olduname		109
+#define __NR_iopl		/* 110 */ not supported
+#define __NR_vhangup		111
+#define __NR_idle		/* 112 */ Obsolete
+#define __NR_vm86		/* 113 */ not supported
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_cacheflush		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl		172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread		180
+#define __NR_pwrite		181
+#define __NR_lchown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_getpmsg		188	/* some people actually want streams */
+#define __NR_putpmsg		189	/* some people actually want streams */
+#define __NR_vfork		190
+#define __NR_getrlimit		191
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_chown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_lchown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+#define __NR_pivot_root		217
+#define __NR_getdents64		220
+#define __NR_gettid		221
+#define __NR_tkill		222
+#define __NR_setxattr		223
+#define __NR_lsetxattr		224
+#define __NR_fsetxattr		225
+#define __NR_getxattr		226
+#define __NR_lgetxattr		227
+#define __NR_fgetxattr		228
+#define __NR_listxattr		229
+#define __NR_llistxattr		230
+#define __NR_flistxattr		231
+#define __NR_removexattr	232
+#define __NR_lremovexattr	233
+#define __NR_fremovexattr	234
+
+/* user-visible error numbers are in the range -1 - -122: see
+   <asm-m68k/errno.h> */
+
+#define __syscall_return(type, res) \
+do { \
+	if ((unsigned long)(res) >= (unsigned long)(-125)) { \
+	/* avoid using res which is declared to be in register d0; \
+	   errno might expand to a function call and clobber it.  */ \
+		int __err = -(res); \
+		errno = __err; \
+		res = -1; \
+	} \
+	return (type) (res); \
+} while (0)
+
+#define _syscall0(type, name)							\
+type name(void)									\
+{										\
+  long __res;									\
+  __asm__ __volatile__ ("movel	%1, %%d0\n\t"					\
+  			"trap	#0\n\t"						\
+  			"movel	%%d0, %0"					\
+			: "=g" (__res)						\
+			: "i" (__NR_##name)					\
+			: "cc", "%d0");						\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {				\
+    errno = -__res;								\
+    __res = -1;									\
+  }										\
+  return (type)__res;								\
+}
+
+#define _syscall1(type, name, atype, a)						\
+type name(atype a)								\
+{										\
+  long __res;									\
+  __asm__ __volatile__ ("movel	%2, %%d1\n\t"					\
+  			"movel	%1, %%d0\n\t"					\
+  			"trap	#0\n\t"						\
+  			"movel	%%d0, %0"					\
+			: "=g" (__res)						\
+			: "i" (__NR_##name),					\
+			  "g" ((long)a)						\
+			: "cc", "%d0", "%d1");					\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {				\
+    errno = -__res;								\
+    __res = -1;									\
+  }										\
+  return (type)__res;								\
+}
+
+#define _syscall2(type, name, atype, a, btype, b)				\
+type name(atype a, btype b)							\
+{										\
+  long __res;									\
+  __asm__ __volatile__ ("movel	%3, %%d2\n\t"					\
+  			"movel	%2, %%d1\n\t"					\
+			"movel	%1, %%d0\n\t"					\
+  			"trap	#0\n\t"						\
+  			"movel	%%d0, %0"					\
+			: "=g" (__res)						\
+			: "i" (__NR_##name),					\
+			  "a" ((long)a),					\
+			  "g" ((long)b)						\
+			: "cc", "%d0", "%d1", "%d2");				\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {				\
+    errno = -__res;								\
+    __res = -1;									\
+  }										\
+  return (type)__res;								\
+}
+
+#define _syscall3(type, name, atype, a, btype, b, ctype, c)			\
+type name(atype a, btype b, ctype c)						\
+{										\
+  long __res;									\
+  __asm__ __volatile__ ("movel	%4, %%d3\n\t"					\
+			"movel	%3, %%d2\n\t"					\
+  			"movel	%2, %%d1\n\t"					\
+			"movel	%1, %%d0\n\t"					\
+  			"trap	#0\n\t"						\
+  			"movel	%%d0, %0"					\
+			: "=g" (__res)						\
+			: "i" (__NR_##name),					\
+			  "a" ((long)a),					\
+			  "a" ((long)b),					\
+			  "g" ((long)c)						\
+			: "cc", "%d0", "%d1", "%d2", "%d3");			\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {				\
+    errno = -__res;								\
+    __res = -1;									\
+  }										\
+  return (type)__res;								\
+}
+
+#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d)		\
+type name(atype a, btype b, ctype c, dtype d)					\
+{										\
+  long __res;									\
+  __asm__ __volatile__ ("movel	%5, %%d4\n\t"					\
+			"movel	%4, %%d3\n\t"					\
+			"movel	%3, %%d2\n\t"					\
+  			"movel	%2, %%d1\n\t"					\
+			"movel	%1, %%d0\n\t"					\
+  			"trap	#0\n\t"						\
+  			"movel	%%d0, %0"					\
+			: "=g" (__res)						\
+			: "i" (__NR_##name),					\
+			  "a" ((long)a),					\
+			  "a" ((long)b),					\
+			  "a" ((long)c),					\
+			  "g" ((long)d)						\
+			: "cc", "%d0", "%d1", "%d2", "%d3",			\
+			  "%d4");						\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {				\
+    errno = -__res;								\
+    __res = -1;									\
+  }										\
+  return (type)__res;								\
+}
+
+#define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e)	\
+type name(atype a, btype b, ctype c, dtype d, etype e)				\
+{										\
+  long __res;									\
+  __asm__ __volatile__ ("movel	%6, %%d5\n\t"					\
+			"movel	%5, %%d4\n\t"					\
+			"movel	%4, %%d3\n\t"					\
+			"movel	%3, %%d2\n\t"					\
+  			"movel	%2, %%d1\n\t"					\
+			"movel	%1, %%d0\n\t"					\
+  			"trap	#0\n\t"						\
+  			"movel	%%d0, %0"					\
+			: "=g" (__res)						\
+			: "i" (__NR_##name),					\
+			  "a" ((long)a),					\
+			  "a" ((long)b),					\
+			  "a" ((long)c),					\
+			  "a" ((long)d),					\
+			  "g" ((long)e)						\
+			: "cc", "%d0", "%d1", "%d2", "%d3",			\
+			  "%d4", "%d5");					\
+  if ((unsigned long)(__res) >= (unsigned long)(-125)) {				\
+    errno = -__res;								\
+    __res = -1;									\
+  }										\
+  return (type)__res;								\
+}
+		
+
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+static inline _syscall0(int,pause)
+static inline _syscall0(int,sync)
+static inline _syscall0(pid_t,setsid)
+static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+static inline _syscall1(int,dup,int,fd)
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+static inline _syscall1(int,close,int,fd)
+static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,delete_module,const char *,name)
+
+static inline pid_t wait(int * wait_stat)
+{
+	return waitpid(-1,wait_stat,0);
+}
+
+#endif
+
+#endif /* _ASM_M68K_UNISTD_H_ */
diff -urN linux-2.4.29/include/asm-m68knommu/user.h linux-2.4.29-uc1/include/asm-m68knommu/user.h
--- linux-2.4.29/include/asm-m68knommu/user.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/user.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-m68k/user.h>
diff -urN linux-2.4.29/include/asm-m68knommu/virtconvert.h linux-2.4.29-uc1/include/asm-m68knommu/virtconvert.h
--- linux-2.4.29/include/asm-m68knommu/virtconvert.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-m68knommu/virtconvert.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef __M68KNOMMU_VIRT_CONVERT__
+#define __M68KNOMMU_VIRT_CONVERT__
+
+/*
+ * Macros used for converting between virtual and physical mappings.
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <asm/setup.h>
+
+#define mm_ptov(vaddr)		((void *) (vaddr))
+#define mm_vtop(vaddr)		((unsigned long) (vaddr))
+#define phys_to_virt(vaddr)	((void *) (vaddr))
+#define virt_to_phys(vaddr)	((unsigned long) (vaddr))
+
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define page_to_phys(page)	virt_to_phys((void *)__page_address(page))
+
+#endif
+#endif
diff -urN linux-2.4.29/include/asm-microblaze/a.out.h linux-2.4.29-uc1/include/asm-microblaze/a.out.h
--- linux-2.4.29/include/asm-microblaze/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/a.out.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,21 @@
+#ifndef __MICROBLAZE_A_OUT_H__
+#define __MICROBLAZE_A_OUT_H__
+
+struct exec
+{
+  unsigned long a_info;		/* Use macros N_MAGIC, etc for access */
+  unsigned a_text;		/* length of text, in bytes */
+  unsigned a_data;		/* length of data, in bytes */
+  unsigned a_bss;		/* length of uninitialized data area for file, in bytes */
+  unsigned a_syms;		/* length of symbol table data in file, in bytes */
+  unsigned a_entry;		/* start address */
+  unsigned a_trsize;		/* length of relocation info for text, in bytes */
+  unsigned a_drsize;		/* length of relocation info for data, in bytes */
+};
+
+#define N_TRSIZE(a)	((a).a_trsize)
+#define N_DRSIZE(a)	((a).a_drsize)
+#define N_SYMSIZE(a)	((a).a_syms)
+
+
+#endif /* __MICROBLAZE_A_OUT_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/asm.h linux-2.4.29-uc1/include/asm-microblaze/asm.h
--- linux-2.4.29/include/asm-microblaze/asm.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/asm.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,27 @@
+/*
+ * include/asm-microblaze/asm.h -- Macros for writing assembly code
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#define G_ENTRY(name)							      \
+   .align 4;								      \
+   .globl name;								      \
+   .type  name,@function;						      \
+   name
+#define END(name)							      \
+   .size  name,.-name
+
+#define L_ENTRY(name)							      \
+   .align 4;								      \
+   .type  name,@function;						      \
+   name
diff -urN linux-2.4.29/include/asm-microblaze/atomic.h linux-2.4.29-uc1/include/asm-microblaze/atomic.h
--- linux-2.4.29/include/asm-microblaze/atomic.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/atomic.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,91 @@
+/*
+ * include/asm-microblaze/atomic.h -- Atomic operations
+ *
+ *  Copyright (C) 2003  John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_ATOMIC_H__
+#define __MICROBLAZE_ATOMIC_H__
+
+#include <linux/config.h>
+
+#include <asm/system.h>
+
+#ifdef CONFIG_SMP
+#error SMP not supported
+#endif
+
+typedef struct { int counter; } atomic_t;
+
+#define ATOMIC_INIT(i)	{ (i) }
+
+#ifdef __KERNEL__
+
+#define atomic_read(v)		((v)->counter)
+#define atomic_set(v,i)		(((v)->counter) = (i))
+
+extern __inline__ int atomic_add_return (int i, volatile atomic_t *v)
+{
+	unsigned long flags;
+	int res;
+
+	__save_flags_cli (flags);
+	res = v->counter + i;
+	v->counter = res;
+	__restore_flags (flags);
+
+	return res;
+}
+
+static __inline__ int atomic_sub_return (int i, volatile atomic_t *v)
+{
+	unsigned long flags;
+	int res;
+
+	__save_flags_cli (flags);
+	res = v->counter - i;
+	v->counter = res;
+	__restore_flags (flags);
+
+	return res;
+}
+
+static __inline__ void atomic_clear_mask (unsigned long mask, unsigned long *addr)
+{
+	unsigned long flags;
+
+	__save_flags_cli (flags);
+	*addr &= ~mask;
+	__restore_flags (flags);
+}
+
+#endif
+
+#define atomic_add(i, v)	atomic_add_return ((i), (v))
+#define atomic_sub(i, v)	atomic_sub_return ((i), (v))
+
+#define atomic_dec_return(v)	atomic_sub_return (1, (v))
+#define atomic_inc_return(v)	atomic_add_return (1, (v))
+#define atomic_inc(v) 		atomic_inc_return (v)
+#define atomic_dec(v) 		atomic_dec_return (v)
+
+#define atomic_sub_and_test(i,v)	(atomic_sub_return ((i), (v)) == 0)
+#define atomic_dec_and_test(v)		(atomic_sub_return (1, (v)) == 0)
+#define atomic_add_negative(i,v)	(atomic_add_return ((i), (v)) < 0)
+
+/* Atomic operations are already serializing on ARM */
+#define smp_mb__before_atomic_dec()	barrier()
+#define smp_mb__after_atomic_dec()	barrier()
+#define smp_mb__before_atomic_inc()	barrier()
+#define smp_mb__after_atomic_inc()	barrier()
+
+#endif /* __MICROBLAZE_ATOMIC_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/autoconfig.h linux-2.4.29-uc1/include/asm-microblaze/autoconfig.h
--- linux-2.4.29/include/asm-microblaze/autoconfig.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/autoconfig.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,112 @@
+/*
+ * autoconfig.h
+ *
+ * Create mappings between new-style autoconfigured parameters, and the
+ * old-style hard coded approach.
+ *
+ *  Copyright (C) 2004        John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * Released under the GPL etc etc
+ */
+
+#ifndef _AUTOCONFIG_H
+#define _AUTOCONFIG_H
+
+/* Only need this if the uclinux-auto target is not selected */
+#ifndef PLATFORM
+
+#include <linux/config.h>
+#include <asm/xparameters.h>
+ /* Backwards compatability mappings for old-style code
+    Essentially use the old config macro values, to provide values that are
+    now provided by the auto-config file, and required in various drivers */
+
+/* The timer and clock frequency */
+#define CONFIG_XILINX_CPU_CLOCK_FREQ CONFIG_CPU_CLOCK_FREQ
+#define CONFIG_XILINX_TIMER_0_BASEADDR MICROBLAZE_TIMER_BASE_ADDR
+#define CONFIG_XILINX_TIMER_0_IRQ 0
+
+/* The interrupt controller */
+#define CONFIG_XILINX_INTC_0_BASEADDR MICROBLAZE_INTC_BASE_ADDR 
+#define CONFIG_XILINX_INTC_0_KIND_OF_INTR XPAR_SYSTEM_INTC_KIND_OF_INTR 
+
+#ifdef CONFIG_MICROBLAZE_INTC_HAS_IVR
+#define CONFIG_XILINX_INTC_0_HAS_IVR 1
+#else
+#define CONFIG_XILINX_INTC_0_HAS_IVR 0
+#endif
+
+#ifdef CONFIG_MICROBLAZE_INTC_HAS_SIE
+#define CONFIG_XILINX_INTC_0_HAS_SIE 1
+#else
+#define CONFIG_XILINX_INTC_0_HAS_SIE 0
+#endif
+
+#ifdef CONFIG_MICROBLAZE_INTC_HAS_CIE
+#define CONFIG_XILINX_INTC_0_HAS_CIE 1
+#else
+#define CONFIG_XILINX_INTC_0_HAS_CIE 0
+#endif
+
+/* Cache support */
+#ifdef CONFIG_MICROBLAZE_ICACHE
+#define CONFIG_XILINX_MICROBLAZE0_USE_ICACHE 1
+#define CONFIG_XILINX_MICROBLAZE0_ICACHE_BASEADDR CONFIG_MICROBLAZE_ICACHE_BASE
+#define CONFIG_XILINX_MICROBLAZE0_CACHE_BYTE_SIZE CONFIG_MICROBLAZE_ICACHE_SIZE
+#else
+#define CONFIG_XILINX_MICROBLAZE0_USE_ICACHE 0
+#endif
+
+#ifdef CONFIG_MICROBLAZE_DCACHE
+#define CONFIG_XILINX_MICROBLAZE0_USE_DCACHE 1
+#define CONFIG_XILINX_MICROBLAZE0_DCACHE_BASEADDR CONFIG_MICROBLAZE_DCACHE_BASE
+#define CONFIG_XILINX_MICROBLAZE0_DCACHE_BYTE_SIZE CONFIG_MICROBLAZE_DCACHE_SIZE
+#else
+#define CONFIG_XILINX_MICROBLAZE0_USE_DCACHE 0
+#endif
+
+#ifdef CONFIG_MICROBLAZE_MSRSETCLR
+#define CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR (1)
+#else
+#define CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR (0)
+#endif
+
+/* The UARTLITES */
+#ifdef XPAR_CONSOLE_UART_BASEADDR
+#define CONFIG_XILINX_UARTLITE_0_INSTANCE "console_uart"
+#define CONFIG_XILINX_UARTLITE_0_BASEADDR XPAR_CONSOLE_UART_BASEADDR 
+#define CONFIG_XILINX_UARTLITE_0_IRQ 1
+#endif
+
+
+/* The GPIO */
+#ifdef XPAR_SYSTEM_GPIO_BASEADDR
+#define CONFIG_XILINX_GPIO_0_BASEADDR XPAR_SYSTEM_GPIO_BASEADDR
+#define CONFIG_XILINX_GPIO_0_HIGHADDR XPAR_SYSTEM_GPIO_HIGHADDR
+#define CONFIG_XILINX_GPIO_NUM_INSTANCES 1
+#endif
+
+#ifndef CONFIG_SUZAKU
+
+#ifdef XPAR_DEBUG_UART_BASEADDR
+#define CONFIG_XILINX_UARTLITE_1_INSTANCE "debug_uart"
+#define CONFIG_XILINX_UARTLITE_1_BASEADDR XPAR_DEBUG_UART_BASEADDR
+#define CONFIG_XILINX_UARTLITE_1_IRQ 2
+#endif
+
+/* The ethernet MAC */
+#define CONFIG_XILINX_ETHERNET_0_INSTANCE "system_ethernet"
+#define CONFIG_XILINX_ETHERNET_0_DEVICE_ID XPAR_OPB_ETHERNET_0_DEVICE_ID
+#define CONFIG_XILINX_ETHERNET_0_ERR_COUNT_EXIST XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST
+#define CONFIG_XILINX_ETHERNET_0_DMA_PRESENT XPAR_OPB_ETHERNET_0_DMA_PRESENT
+#define CONFIG_XILINX_ETHERNET_0_MII_EXIST XPAR_OPB_ETHERNET_0_MII_EXIST
+#define CONFIG_XILINX_ETHERNET_0_BASEADDR XPAR_EMAC_0_BASEADDR
+#define CONFIG_XILINX_ETHERNET_0_HIGHADDR XPAR_EMAC_0_HIGHADDR
+#define CONFIG_XILINX_ETHERNET_0_IRQ 3
+#define CONFIG_XILINX_ETHERNET_NUM_INSTANCES XPAR_XEMAC_NUM_INSTANCES
+
+#endif /* !CONFIG_SUZAKU */
+
+#endif /* PLATFORM */
+
+#endif /* !defined _AUTOCONFIG_H */
diff -urN linux-2.4.29/include/asm-microblaze/bitops.h linux-2.4.29-uc1/include/asm-microblaze/bitops.h
--- linux-2.4.29/include/asm-microblaze/bitops.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/bitops.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,392 @@
+#ifndef _MICROBLAZE_BITOPS_H
+#define _MICROBLAZE_BITOPS_H
+
+/*
+ * Copyright 1992, Linus Torvalds.
+ */
+
+#include <linux/config.h>
+#include <asm/byteorder.h>	/* swab32 */
+#include <asm/system.h>		/* save_flags */
+
+#ifdef __KERNEL__
+/*
+ * Function prototypes to keep gcc -Wall happy
+ */
+
+/*
+ * The __ functions are not atomic
+ */
+
+extern void set_bit(int nr, volatile void * addr);
+extern void __set_bit(int nr, volatile void * addr);
+
+extern void clear_bit(int nr, volatile void * addr);
+#define __clear_bit(nr, addr) clear_bit(nr, addr)
+
+extern void change_bit(int nr, volatile void * addr);
+extern void __change_bit(int nr, volatile void * addr);
+extern int test_and_set_bit(int nr, volatile void * addr);
+extern int __test_and_set_bit(int nr, volatile void * addr);
+extern int test_and_clear_bit(int nr, volatile void * addr);
+extern int __test_and_clear_bit(int nr, volatile void * addr);
+extern int test_and_change_bit(int nr, volatile void * addr);
+extern int __test_and_change_bit(int nr, volatile void * addr);
+extern int __constant_test_bit(int nr, const volatile void * addr);
+extern int __test_bit(int nr, volatile void * addr);
+extern int find_first_zero_bit(void * addr, unsigned size);
+extern int find_next_zero_bit (void * addr, int size, int offset);
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+extern __inline__ unsigned long ffz(unsigned long word)
+{
+	unsigned long result = 0;
+
+	while(word & 1) {
+		result++;
+		word >>= 1;
+	}
+	return result;
+}
+
+
+extern __inline__ void set_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_flags_cli(flags);
+	*a |= mask;
+	restore_flags(flags);
+}
+
+extern __inline__ void __set_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	*a |= mask;
+}
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+
+extern __inline__ void clear_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_flags_cli(flags);
+	*a &= ~mask;
+	restore_flags(flags);
+}
+
+extern __inline__ void change_bit(int nr, volatile void * addr)
+{
+	int mask;
+	unsigned long flags;
+	unsigned long *ADDR = (unsigned long *) addr;
+
+	ADDR += nr >> 5;
+	mask = 1 << (nr & 31);
+	save_flags_cli(flags);
+	*ADDR ^= mask;
+	restore_flags(flags);
+}
+
+extern __inline__ void __change_bit(int nr, volatile void * addr)
+{
+	int mask;
+	unsigned long *ADDR = (unsigned long *) addr;
+
+	ADDR += nr >> 5;
+	mask = 1 << (nr & 31);
+	*ADDR ^= mask;
+}
+
+extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_flags_cli(flags);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+extern __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+	return retval;
+}
+
+extern __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_flags_cli(flags);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+	return retval;
+}
+
+extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+	unsigned long flags;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	save_flags_cli(flags);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	restore_flags(flags);
+
+	return retval;
+}
+
+extern __inline__ int __test_and_change_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	return retval;
+}
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+extern __inline__ int __constant_test_bit(int nr, const volatile void * addr)
+{
+	return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
+}
+
+extern __inline__ int __test_bit(int nr, volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	return ((mask & *a) != 0);
+}
+
+#define test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ __constant_test_bit((nr),(addr)) : \
+ __test_bit((nr),(addr)))
+
+#define find_first_zero_bit(addr, size) \
+        find_next_zero_bit((addr), (size), 0)
+
+extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if (offset) {
+		tmp = *(p++);
+		tmp |= ~0UL >> (32-offset);
+		if (size < 32)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while (size & ~31UL) {
+		if (~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp |= ~0UL >> size;
+found_middle:
+	return result + ffz(tmp);
+}
+
+#define ffs(x) generic_ffs(x)
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+
+extern __inline__ int ext2_set_bit(int nr, volatile void * addr)
+{
+	int		mask, retval;
+	unsigned long	flags;
+	volatile unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	save_flags_cli(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR |= mask;
+	restore_flags(flags);
+	return retval;
+}
+
+extern __inline__ int ext2_clear_bit(int nr, volatile void * addr)
+{
+	int		mask, retval;
+	unsigned long	flags;
+	volatile unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	save_flags_cli(flags);
+	retval = (mask & *ADDR) != 0;
+	*ADDR &= ~mask;
+	restore_flags(flags);
+	return retval;
+}
+
+extern __inline__ int ext2_test_bit(int nr, const volatile void * addr)
+{
+	int			mask;
+	const volatile unsigned char	*ADDR = (const unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	return ((mask & *ADDR) != 0);
+}
+
+#define ext2_find_first_zero_bit(addr, size) \
+        ext2_find_next_zero_bit((addr), (size), 0)
+
+extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if(offset) {
+		/* We hold the little endian value in tmp, but then the
+		 * shift is illegal. So we could keep a big endian value
+		 * in tmp, like this:
+		 *
+		 * tmp = __swab32(*(p++));
+		 * tmp |= ~0UL >> (32-offset);
+		 *
+		 * but this would decrease preformance, so we change the
+		 * shift:
+		 */
+		tmp = *(p++);
+		tmp |= __swab32(~0UL >> (32-offset));
+		if(size < 32)
+			goto found_first;
+		if(~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while(size & ~31UL) {
+		if(~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if(!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	/* tmp is little endian, so we would have to swab the shift,
+	 * see above. But then we have to swab tmp below for ffz, so
+	 * we might as well do this here.
+	 */
+	return result + ffz(__swab32(tmp) | (~0UL << size));
+found_middle:
+	return result + ffz(__swab32(tmp));
+}
+
+/* Bitmap functions for the minix filesystem.  */
+#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr) set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+
+/**
+ * hweightN - returns the hamming weight of a N-bit word
+ * @x: the word to weigh
+ *
+ * The Hamming Weight of a number is the total number of bits set in it.
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+#endif /* __KERNEL__ */
+
+#endif /* _MICROBLAZE_BITOPS_H */
diff -urN linux-2.4.29/include/asm-microblaze/blkmem.h linux-2.4.29-uc1/include/asm-microblaze/blkmem.h
--- linux-2.4.29/include/asm-microblaze/blkmem.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/blkmem.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,52 @@
+/*
+ * include/asm-microblaze/blkmem.h -- `blkmem' device configuration
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_BLKMEM_H__
+#define __MICROBLAZE_BLKMEM_H__
+
+/* Look for a device specific memory array location.  */
+#include <asm/machdep.h>
+
+
+#ifndef FIXUP_ARENAS  /* provide a default */
+
+#ifndef ROOT_FS_IMAGE_RW
+#define ROOT_FS_IMAGE_RW	0 /* assume read-only */
+#endif
+
+/* For <asm/blkmem.h> */
+
+/* The rootfs image exists straight after ebss */
+extern char _ebss;
+
+#define CAT_ROMARRAY
+
+/* Make the single arena point use them.  
+   The fs length should be detected automagically */
+#define FIXUP_ARENAS							      \
+        arena[0].rw = ROOT_FS_IMAGE_RW;					      \
+	arena[0].address = (unsigned long)&_ebss;
+
+#endif /* FIXUP_ARENAS */
+
+/* Used by the blkmem flash programming code.  */
+/* Not a very good reset, but at least we clear interrupts before restarting */
+#define HARD_RESET_NOW() 						      \
+	__asm__ __volatile__ ("	mfs	r11, rmsr;			      \
+				andi	r11, r11, ~2;			      \
+				mts	rmsr, r11;			      \
+				bra r0;")
+
+#endif /* __MICROBLAZE_BLKMEM_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/bugs.h linux-2.4.29-uc1/include/asm-microblaze/bugs.h
--- linux-2.4.29/include/asm-microblaze/bugs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/bugs.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,16 @@
+/*
+ *  include/asm-microblaze/bugs.h
+ *
+ *  Copyright (C) 1994  Linus Torvalds
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *	void check_bugs(void);
+ */
+
+static void check_bugs(void)
+{
+}
diff -urN linux-2.4.29/include/asm-microblaze/byteorder.h linux-2.4.29-uc1/include/asm-microblaze/byteorder.h
--- linux-2.4.29/include/asm-microblaze/byteorder.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/byteorder.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,54 @@
+/*
+ * include/asm-microblaze/byteorder.h -- Endian id and conversion ops
+ *
+ *  Copyright (C) 2003  John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_BYTEORDER_H__
+#define __MICROBLAZE_BYTEORDER_H__
+
+#include <asm/types.h>
+
+#ifdef __GNUC__
+
+/* This is effectively a dupe of the arch-independent byteswap
+   code in include/linux/byteorder/swab.h, however we force a cast 
+   of the result up to 32 bits.  This in turn forces the compiler
+   to explicitly clear the high 16 bits, which it wasn't doing otherwise.
+
+   I think this is a symptom of a bug in mb-gcc.  JW 20040303
+*/
+static __inline__ __const__ __u16 ___arch__swab16 (__u16 half_word)
+{
+	/* 32 bit temp to cast result, forcing clearing of high word */
+	__u32 temp;
+
+	temp = ((half_word & 0x00FFU) << 8) |
+		((half_word & 0xFF00U) >> 8);
+
+	return (__u16) temp;
+}
+
+#define __arch__swab16(x) ___arch__swab16(x)
+
+/* Microblaze has no arch-specific endian conversion insns */
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#endif /* __GNUC__ */
+
+#include <linux/byteorder/big_endian.h>
+
+#endif /* __MICROBLAZE_BYTEORDER_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/cache.h linux-2.4.29-uc1/include/asm-microblaze/cache.h
--- linux-2.4.29/include/asm-microblaze/cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/cache.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,145 @@
+/*
+ * include/asm-microblaze/cache.h -- Cache operations
+ *
+ *  Copyright (C) 2003  John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#ifndef __MICROBLAZE_CACHE_H__
+#define __MICROBLAZE_CACHE_H__
+
+/* All cache operations are machine-dependent.  */
+#include <asm/machdep.h>
+
+#ifndef L1_CACHE_BYTES
+/* word-granular cache in microblaze */
+#define L1_CACHE_BYTES		4
+#endif
+
+/* Detect cache style used, to set cache line size*/
+/* FSL caches (CacheLink) uses 16 byte cache line */
+#if CONFIG_XILINX_MICROBLAZE0_ICACHE_USE_FSL
+#define ICACHE_LINE_SIZE 16
+#else
+#define ICACHE_LINE_SIZE 4
+#endif
+
+#if CONFIG_XILINX_MICROBLAZE0_DCACHE_USE_FSL
+#define DCACHE_LINE_SIZE 16
+#else
+#define DCACHE_LINE_SIZE 4
+#endif
+
+/* Define MSR enable bits for instruction and data caches */
+#define ICACHE_MSR_BIT (1 << 5)
+#define DCACHE_MSR_BIT (1 << 7)
+
+#if CONFIG_XILINX_MICROBLAZE0_USE_ICACHE		/* Cache support? */
+
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+#define __enable_icache()						\
+	__asm__ __volatile__ ("	msrset	r0, %0;				\
+				nop;"					\
+				: 					\
+				: "i" (ICACHE_MSR_BIT)			\
+				: "memory")
+
+#define __disable_icache()						\
+	__asm__ __volatile__ ("	msrclr r0, %0;				\
+				nop;"					\
+				: 					\
+				: "i" (ICACHE_MSR_BIT)			\
+				: "memory")
+
+
+#else /* !CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+#define __enable_icache()						\
+	__asm__ __volatile__ ("						\
+				mfs	r12, rmsr;			\
+				ori	r12, r12, %0;			\
+				mts	rmsr, r12;			\
+				nop;"					\
+				: 					\
+				: "i" (ICACHE_MSR_BIT)			\
+				: "memory", "r12")
+
+#define __disable_icache()						\
+	__asm__ __volatile__ ("						\
+				mfs	r12, rmsr;			\
+				andi	r12, r12, ~%0;			\
+				mts	rmsr, r12;			\
+				nop;"					\
+				: 					\
+				: "i" (ICACHE_MSR_BIT)			\
+				: "memory", "r12")
+
+ 
+#endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+
+#define __invalidate_icache(addr)					\
+	__asm__ __volatile__ ("						\
+				wic	%0, r0"				\
+				:					\
+				: "r" (addr))
+#else
+#define __enable_icache()
+#define __disable_icache()
+#define __invalidate_icache(addr)
+#endif
+
+#if CONFIG_XILINX_MICROBLAZE0_USE_DCACHE
+
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+#define __enable_dcache()						\
+	__asm__ __volatile__ (" msrset	r0, %0;				\
+				nop;"					\
+				: 					\
+				: "i" (DCACHE_MSR_BIT)			\
+				: "memory")
+
+#define __disable_dcache()						\
+	__asm__ __volatile__ (" msrclr	r0, %0;				\
+				nop;"					\
+				: 					\
+				: "i" (DCACHE_MSR_BIT)			\
+				: "memory")
+
+#else /* !CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+#define __enable_dcache()						\
+	__asm__ __volatile__ ("						\
+				mfs	r12, rmsr;			\
+				ori	r12, r12, %0;			\
+				mts	rmsr, r12;			\
+				nop;"					\
+				: 					\
+				: "i" (DCACHE_MSR_BIT)			\
+				: "memory", "r12")
+
+#define __disable_dcache()						\
+	__asm__ __volatile__ ("						\
+				mfs	r12, rmsr;			\
+				andi	r12, r12, ~%0;			\
+				mts	rmsr, r12;			\
+				nop;"					\
+				: 					\
+				: "i" (DCACHE_MSR_BIT)			\
+				: "memory", "r12")
+
+#endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+
+#define __invalidate_dcache(addr)					\
+	__asm__ __volatile__ ("						\
+				wdc	%0, r0"				\
+				:					\
+				: "r" (addr))
+#else
+#define __enable_dcache()
+#define __disable_dcache()
+#define __invalidate_dcache(addr)
+#endif /* CONFIG_XILINX_MICROBLAZE0_USE_DCACHE */
+
+#endif /* __MICROBLAZE_CACHE_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/checksum.h linux-2.4.29-uc1/include/asm-microblaze/checksum.h
--- linux-2.4.29/include/asm-microblaze/checksum.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/checksum.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,132 @@
+#ifndef _MICROBLAZE_CHECKSUM_H
+#define _MICROBLAZE_CHECKSUM_H
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
+
+
+/*
+ * the same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
+						int len, int sum, int *csum_err);
+
+#define csum_partial_copy_nocheck(src, dst, len, sum)	\
+	csum_partial_copy ((src), (dst), (len), (sum))
+
+unsigned short ip_fast_csum (unsigned char *iph, unsigned int ihl);
+
+/*
+ *	Fold a partial checksum
+ */
+
+static inline unsigned int csum_fold(unsigned int sum)
+{
+	sum = (sum & 0xffff) + (sum >> 16);
+	sum = (sum & 0xffff) + (sum >> 16);
+	return ~sum;
+}
+
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+
+static inline unsigned int
+csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
+		    unsigned short proto, unsigned int sum)
+{
+	__asm__ ("add	%0, %4, %1\n\t"
+		 "addc	%0, %4, %2\n\t"
+		 "addc	%0, %4, %3\n\t"
+		 "addc	%0, %4, r0\n\t"
+		 : "=d" (sum)
+		 : "d" (saddr), "d" (daddr), "d" (len + proto),
+		   "0"(sum));
+
+# if 0
+	__asm__ ("addl  %1,%0\n\t"
+		 "addxl %4,%0\n\t"
+		 "addxl %5,%0\n\t"
+		 "clrl %1\n\t"
+		 "addxl %1,%0"
+		 : "=&d" (sum), "=&d" (saddr)
+		 : "0" (daddr), "1" (saddr), "d" (len + proto),
+		   "d"(sum));
+#endif
+
+	return sum;
+}
+
+static inline unsigned short int
+csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
+		   unsigned short proto, unsigned int sum)
+{
+	return csum_fold (csum_tcpudp_nofold (saddr, daddr, len, proto, sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+extern unsigned short ip_compute_csum (const unsigned char * buff, int len);
+
+#define _HAVE_ARCH_IPV6_CSUM
+static __inline__ unsigned short int
+csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr,
+		__u32 len, unsigned short proto, unsigned int sum) 
+{
+	register unsigned long tmp;
+	__asm__("addl %2@,%0\n\t"
+		"movel %2@(4),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %2@(8),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %2@(12),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %3@,%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %3@(4),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %3@(8),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %3@(12),%1\n\t"
+		"addxl %1,%0\n\t"
+		"addxl %4,%0\n\t"
+		"clrl %1\n\t"
+		"addxl %1,%0"
+		: "=&d" (sum), "=&d" (tmp)
+		: "a" (saddr), "a" (daddr), "d" (len + proto),
+		  "0" (sum));
+
+	return csum_fold(sum);
+}
+
+#endif /* _MICROBLAZE_CHECKSUM_H */
diff -urN linux-2.4.29/include/asm-microblaze/clinkage.h linux-2.4.29-uc1/include/asm-microblaze/clinkage.h
--- linux-2.4.29/include/asm-microblaze/clinkage.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/clinkage.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ * include/asm-microblaze/clinkage.h -- Macros to reflect C symbol-naming conventions
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporatione
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_CLINKAGE_H__
+#define __MICROBLAZE_CLINKAGE_H__
+
+#include <asm/macrology.h>
+#include <asm/asm.h>
+
+/* #define LEADING_UNDERSCORES 1 */
+
+#ifdef LEADING_UNDERSCORES
+#define C_SYMBOL_NAME(name) 	macrology_paste(_, name) 
+#else
+#define C_SYMBOL_NAME(name) 	name 
+#endif
+
+#define C_ENTRY(name)		G_ENTRY(C_SYMBOL_NAME(name))
+#define C_END(name)		END(C_SYMBOL_NAME(name))
+
+#endif /* __MICROBLAZE_CLINKAGE_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/current.h linux-2.4.29-uc1/include/asm-microblaze/current.h
--- linux-2.4.29/include/asm-microblaze/current.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/current.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,81 @@
+/*
+ * include/asm-microblaze/current.h -- Current task
+ *
+ *  Copyright (C) 2003  John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_CURRENT_H__
+#define __MICROBLAZE_CURRENT_H__
+
+#include <asm/macrology.h>
+
+// #define CONFIG_REGISTER_TASK_PTR 1
+
+/* The size allocated for kernel stacks.  This _must_ be a power of two!  */
+#define KERNEL_STACK_SIZE	0x2000
+
+
+#ifdef CONFIG_REGISTER_TASK_PTR
+/* Register used to hold the current task pointer while in the kernel.
+   Any `call clobbered' register without a special meaning should be OK,
+   but check asm/microblaze/kernel/entry.S to be sure.  */
+	#define CURRENT_TASK_REGNUM	31
+	#define CURRENT_TASK 		macrology_paste (r, CURRENT_TASK_REGNUM)
+#else
+/* Memory location where current task ptr is stored */
+	#define CURRENT_TASK		C_SYMBOL_NAME(current)
+#endif
+
+/* The alignment of kernel stacks, with task structures at their base.
+   Thus, a pointer for a task's task structure can be derived from its
+   kernel stack pointer.  */
+#define CURRENT_TASK_ALIGNMENT	KERNEL_STACK_SIZE
+#define CURRENT_TASK_MASK	(-CURRENT_TASK_ALIGNMENT)
+
+
+#ifdef __ASSEMBLY__
+
+#ifdef CONFIG_REGISTER_TASK_PTR							
+/* Return the current task pointer into the specified register */
+#define RETRIEVE_CURRENT_TASK(reg)					      \
+	add	reg, r0, CURRENT_TASK;	
+#else
+#define RETRIEVE_CURRENT_TASK(reg)					      \
+	lwi	reg, r0, CURRENT_TASK;
+#endif
+
+#ifdef CONFIG_REGISTER_TASK_PTR							
+/* Put a pointer to the current task structure into REG. */
+#define GET_CURRENT_TASK(reg)						      \
+	andi	reg, r1, CURRENT_TASK_MASK;
+#else
+/* Morph current stack pointer into task pointer, and store in addr.	      
+   clobbers r11 but should only be done within a saved state. */	      
+#define GET_CURRENT_TASK(addr)						      \
+	andi	r11, r1, CURRENT_TASK_MASK;				      \
+	swi	r11, r0, addr;
+#endif
+
+#else /* !__ASSEMBLY__ */
+
+/* A pointer to the current task.  */
+#ifdef CONFIG_REGISTER_TASK_PTR
+register struct task_struct *current 
+		__asm__ (macrology_stringify (CURRENT_TASK)); 
+#else
+extern struct task_struct *current;
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+
+#endif /* _MICROBLAZE_CURRENT_H */
diff -urN linux-2.4.29/include/asm-microblaze/delay.h linux-2.4.29-uc1/include/asm-microblaze/delay.h
--- linux-2.4.29/include/asm-microblaze/delay.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/delay.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,52 @@
+/*
+ * include/asm-microblaze/delay.h -- Delay routines, using a pre-computed
+ * 	"loops_per_second" value
+ *
+ *  Copyright (C) 2003  John Williams <jwilliams@itee.uq.edu.au>
+ *                      based upon v850 version
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 1994 Hamish Macdonald
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+#ifndef __MICROBLAZE_DELAY_H__
+#define __MICROBLAZE_DELAY_H__
+
+#include <asm/param.h>
+
+extern __inline__ void __delay(unsigned long loops)
+{
+	__asm__ __volatile__ ("1:	addi	%0, %0, -1;		\
+					bneid	%0, 1b;			\
+					nop;"
+			      : "=r" (loops) : "0" (loops));
+}
+
+/*
+ * Use only for very small delays ( < 1 msec).  Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays.  This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)  
+ */
+
+extern unsigned long loops_per_jiffy;
+
+extern __inline__ void udelay(unsigned long usecs)
+{
+	register unsigned long full_loops, part_loops;
+
+	full_loops = ((usecs * HZ) / 1000000) * loops_per_jiffy;
+	usecs %= (1000000 / HZ);
+	part_loops = (usecs * HZ * loops_per_jiffy) / 1000000;
+
+	__delay(full_loops + part_loops);
+}
+
+#define ndelay(nsecs) udelay((nsecs) * 5)
+
+#endif /* __MICROBLAZE_DELAY_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/div64.h linux-2.4.29-uc1/include/asm-microblaze/div64.h
--- linux-2.4.29/include/asm-microblaze/div64.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/div64.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-generic/div64.h>
diff -urN linux-2.4.29/include/asm-microblaze/dma.h linux-2.4.29-uc1/include/asm-microblaze/dma.h
--- linux-2.4.29/include/asm-microblaze/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/dma.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,18 @@
+#ifndef __MICROBLAZE_DMA_H__
+#define __MICROBLAZE_DMA_H__
+
+/* What should this be?  */
+#define MAX_DMA_ADDRESS	0xFFFFFFFF
+
+/* reserve a DMA channel */
+extern int request_dma (unsigned int dmanr, const char * device_id);
+/* release it again */
+extern void free_dma (unsigned int dmanr);
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy    (0)
+#endif
+
+#endif /* __MICROBLAZE_DMA_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/elf.h linux-2.4.29-uc1/include/asm-microblaze/elf.h
--- linux-2.4.29/include/asm-microblaze/elf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/elf.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,95 @@
+#ifndef __MICROBLAZE_ELF_H__
+#define __MICROBLAZE_ELF_H__
+
+/* 
+ * Note there is no "official" ELF designation for Microblaze.
+ * I've snaffled the value from the microblaze binutils source code
+ * /binutils/microblaze/include/elf/microblaze.h
+ */
+
+#define EM_XILINX_MICROBLAZE 0xbaab
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+#include <asm/byteorder.h>
+
+#ifndef ELF_GREG_T
+#define ELF_GREG_T
+typedef unsigned long elf_greg_t;
+#endif
+
+#ifndef ELF_NGREG
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+#endif
+
+#ifndef ELF_GREGSET_T
+#define ELF_GREGSET_T
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+#endif
+
+#ifndef ELF_FPREGSET_T
+#define ELF_FPREGSET_T
+typedef struct user_fpu_struct elf_fpregset_t;
+#endif
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ( (x)->e_machine == EM_XILINX_MICROBLAZE )
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#ifdef __LITTLE_ENDIAN__
+#define ELF_DATA	ELFDATA2LSB
+#else
+#define ELF_DATA	ELFDATA2MSB
+#endif
+#define ELF_ARCH	EM_XILINX_MICROBLAZE
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	4096
+
+
+#define ELF_CORE_COPY_REGS(_dest,_regs)				\
+	memcpy((char *) &_dest, (char *) _regs,			\
+	       sizeof(struct pt_regs));
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this CPU supports.  This could be done in user space,
+   but it's not easy, and we've already done it here.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.
+
+   For the moment, we have only optimizations for the Intel generations,
+   but that could change... */
+
+#define ELF_PLATFORM  (NULL)
+
+#define ELF_PLAT_INIT(_r)						      \
+  do {									      \
+	 _r->gpr[0] =  _r->gpr[1] =  _r->gpr[2] =  _r->gpr[3] =		      \
+	 _r->gpr[4] =  _r->gpr[5] =  _r->gpr[6] =  _r->gpr[7] =		      \
+	 _r->gpr[8] =  _r->gpr[9] = _r->gpr[10] = _r->gpr[11] =		      \
+	_r->gpr[12] = _r->gpr[13] = _r->gpr[14] = _r->gpr[15] =		      \
+	_r->gpr[16] = _r->gpr[17] = _r->gpr[18] = _r->gpr[19] =		      \
+	_r->gpr[20] = _r->gpr[21] = _r->gpr[22] = _r->gpr[23] =		      \
+	_r->gpr[24] = _r->gpr[25] = _r->gpr[26] = _r->gpr[27] =		      \
+	_r->gpr[28] = _r->gpr[29] = _r->gpr[30] = _r->gpr[31] =		      \
+	0;								      \
+  } while (0)
+
+#ifdef __KERNEL__
+#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+#endif
+
+#endif /* __MICROBLAZE_ELF_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/entry.h linux-2.4.29-uc1/include/asm-microblaze/entry.h
--- linux-2.4.29/include/asm-microblaze/entry.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/entry.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,136 @@
+/*
+ * include/asm-microblaze/entry.h -- Definitions used by low-level trap handlers
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_ENTRY_H__
+#define __MICROBLAZE_ENTRY_H__
+
+
+#include <asm/ptrace.h>
+#include <asm/machdep.h>
+
+
+/* If true, system calls save and restore all registers (except result
+   registers, of course).  If false, then `call clobbered' registers
+   will not be preserved, on the theory that system calls are basically
+   function calls anyway, and the caller should be able to deal with it.
+   This is a security risk, of course, as `internal' values may leak out
+   after a system call, but that certainly doesn't matter very much for
+   a processor with no MMU protection!  For a protected-mode kernel, it
+   would be faster to just zero those registers before returning.  */
+#define TRAPS_PRESERVE_CALL_CLOBBERED_REGS	0
+
+/* If TRAPS_PRESERVE_CALL_CLOBBERED_REGS is false, then zero `call
+   clobbered' registers before returning from a system call.  */
+#define TRAPS_ZERO_CALL_CLOBBERED_REGS		0
+
+
+/* These are special variables using by the kernel trap/interrupt code
+   to save registers in, at a time when there are no spare registers we
+   can use to do so, and we can't depend on the value of the stack
+   pointer.  This means that they must be within a signed 16-bit
+   displacement of 0x00000000.  */
+
+#define KERNEL_VAR_SPACE_ADDR	R0_RAM_ADDR
+
+/* 
+ * KERNEL_VAR is from the microblaze port.  To maintain compatability
+ * we keep it, but the mb-gas doesn't do the reg[offset] syntax. 
+ * instead, we should get away with something like addi reg, r0, offset.
+ * Here's hoping.
+ */
+#ifdef __ASSEMBLY__
+/* #define KERNEL_VAR(addr)	addr[r0] */
+#define KERNEL_VAR(addr)	addr
+#else
+#define KERNEL_VAR(addr)	(*(volatile unsigned long *)(addr))
+#endif
+
+/* Kernel stack pointer, 4 bytes.  */
+#define KSP_ADDR		(KERNEL_VAR_SPACE_ADDR +  0)
+#define KSP			KERNEL_VAR (KSP_ADDR)
+/* 1 if in kernel-mode, 0 if in user mode, 1 byte.  */
+#define KM_ADDR 		(KERNEL_VAR_SPACE_ADDR +  4)
+#define KM			KERNEL_VAR (KM_ADDR)
+/* Temporary storage for interrupt handlers, 4 bytes.  */
+#define INT_SCRATCH_ADDR	(KERNEL_VAR_SPACE_ADDR +  8)
+#define INT_SCRATCH		KERNEL_VAR (INT_SCRATCH_ADDR)
+/* Where the stack-pointer is saved when jumping to various sorts of
+   interrupt handlers.  ENTRY_SP is used by everything except NMIs,
+   which have their own location.  Higher-priority NMIs can clobber the
+   value written by a lower priority NMI, since they can't be disabled,
+   but that's OK, because only NMI0 (the lowest-priority one) is allowed
+   to return.  */
+#define ENTRY_SP_ADDR		(KERNEL_VAR_SPACE_ADDR + 12)
+#define ENTRY_SP		KERNEL_VAR (ENTRY_SP_ADDR)
+#define NMI_ENTRY_SP_ADDR	(KERNEL_VAR_SPACE_ADDR + 16)
+#define NMI_ENTRY_SP		KERNEL_VAR (NMI_ENTRY_SP_ADDR)
+
+/* Somewhere to save r11 upon entry to a syscall/irq */
+#define R11_SAVE_ADDR		(KERNEL_VAR_SPACE_ADDR + 20)
+#define R11_SAVE		KERNEL_VAR (R11_SAVE_ADDR)
+
+#ifdef CONFIG_RESET_GUARD
+/* Used to detect unexpected resets (since the microblaze has no MMU, any call
+   through a null pointer will jump to the reset vector).  We detect
+   such resets by checking for a magic value, RESET_GUARD_ACTIVE, in
+   this location.  Properly resetting the machine stores zero there, so
+   it shouldn't trigger the guard; the power-on value is uncertain, but
+   it's unlikely to be RESET_GUARD_ACTIVE.  */
+#define RESET_GUARD_ADDR	(KERNEL_VAR_SPACE_ADDR + 28)
+#define RESET_GUARD		KERNEL_VAR (RESET_GUARD_ADDR)
+#define RESET_GUARD_ACTIVE	0xFAB4BEEF
+#endif /* CONFIG_RESET_GUARD */
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_RESET_GUARD
+/* Turn off reset guard, so that resetting the machine works normally.
+   This should be called in the various machine_halt, etc., functions.  */
+static inline void disable_reset_guard (void)
+{
+	RESET_GUARD = 0;
+}
+#endif /* CONFIG_RESET_GUARD */
+
+#endif /* !__ASSEMBLY__ */
+
+
+/* A `state save frame' is a struct pt_regs preceded by some extra space
+   suitable for a function call stack frame.  */
+
+/* Amount of room on the stack reserved for arguments and to satisfy the
+   C calling conventions, in addition to the space used by the struct
+   pt_regs that actually holds saved values.  */
+#define STATE_SAVE_ARG_SPACE	(6*4) /* Up to six arguments.  */
+
+
+#ifdef __ASSEMBLY__
+
+/* The size of a state save frame.  */
+#define STATE_SAVE_SIZE		(PT_SIZE + STATE_SAVE_ARG_SPACE)
+
+#else /* !__ASSEMBLY__ */
+
+/* The size of a state save frame.  */
+#define STATE_SAVE_SIZE	       (sizeof (struct pt_regs) + STATE_SAVE_ARG_SPACE)
+
+#endif /* __ASSEMBLY__ */
+
+
+/* Offset of the struct pt_regs in a state save frame.  */
+#define STATE_SAVE_PT_OFFSET	STATE_SAVE_ARG_SPACE
+
+
+#endif /* __MICROBLAZE_ENTRY_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/errno.h linux-2.4.29-uc1/include/asm-microblaze/errno.h
--- linux-2.4.29/include/asm-microblaze/errno.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/errno.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,132 @@
+#ifndef __MICROBLAZE_ERRNO_H__
+#define __MICROBLAZE_ERRNO_H__
+
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Arg list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	EDEADLK		35	/* Resource deadlock would occur */
+#define	ENAMETOOLONG	36	/* File name too long */
+#define	ENOLCK		37	/* No record locks available */
+#define	ENOSYS		38	/* Function not implemented */
+#define	ENOTEMPTY	39	/* Directory not empty */
+#define	ELOOP		40	/* Too many symbolic links encountered */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	ENOMSG		42	/* No message of desired type */
+#define	EIDRM		43	/* Identifier removed */
+#define	ECHRNG		44	/* Channel number out of range */
+#define	EL2NSYNC	45	/* Level 2 not synchronized */
+#define	EL3HLT		46	/* Level 3 halted */
+#define	EL3RST		47	/* Level 3 reset */
+#define	ELNRNG		48	/* Link number out of range */
+#define	EUNATCH		49	/* Protocol driver not attached */
+#define	ENOCSI		50	/* No CSI structure available */
+#define	EL2HLT		51	/* Level 2 halted */
+#define	EBADE		52	/* Invalid exchange */
+#define	EBADR		53	/* Invalid request descriptor */
+#define	EXFULL		54	/* Exchange full */
+#define	ENOANO		55	/* No anode */
+#define	EBADRQC		56	/* Invalid request code */
+#define	EBADSLT		57	/* Invalid slot */
+
+#define	EDEADLOCK	EDEADLK
+
+#define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
+#define	EMULTIHOP	72	/* Multihop attempted */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EBADMSG		74	/* Not a data message */
+#define	EOVERFLOW	75	/* Value too large for defined data type */
+#define	ENOTUNIQ	76	/* Name not unique on network */
+#define	EBADFD		77	/* File descriptor in bad state */
+#define	EREMCHG		78	/* Remote address changed */
+#define	ELIBACC		79	/* Can not access a needed shared library */
+#define	ELIBBAD		80	/* Accessing a corrupted shared library */
+#define	ELIBSCN		81	/* .lib section in a.out corrupted */
+#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	EILSEQ		84	/* Illegal byte sequence */
+#define	ERESTART	85	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUSERS		87	/* Too many users */
+#define	ENOTSOCK	88	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	89	/* Destination address required */
+#define	EMSGSIZE	90	/* Message too long */
+#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	92	/* Protocol not available */
+#define	EPROTONOSUPPORT	93	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
+#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	96	/* Protocol family not supported */
+#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
+#define	EADDRINUSE	98	/* Address already in use */
+#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
+#define	ENETDOWN	100	/* Network is down */
+#define	ENETUNREACH	101	/* Network is unreachable */
+#define	ENETRESET	102	/* Network dropped connection because of reset */
+#define	ECONNABORTED	103	/* Software caused connection abort */
+#define	ECONNRESET	104	/* Connection reset by peer */
+#define	ENOBUFS		105	/* No buffer space available */
+#define	EISCONN		106	/* Transport endpoint is already connected */
+#define	ENOTCONN	107	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
+#define	ETIMEDOUT	110	/* Connection timed out */
+#define	ECONNREFUSED	111	/* Connection refused */
+#define	EHOSTDOWN	112	/* Host is down */
+#define	EHOSTUNREACH	113	/* No route to host */
+#define	EALREADY	114	/* Operation already in progress */
+#define	EINPROGRESS	115	/* Operation now in progress */
+#define	ESTALE		116	/* Stale NFS file handle */
+#define	EUCLEAN		117	/* Structure needs cleaning */
+#define	ENOTNAM		118	/* Not a XENIX named type file */
+#define	ENAVAIL		119	/* No XENIX semaphores available */
+#define	EISNAM		120	/* Is a named type file */
+#define	EREMOTEIO	121	/* Remote I/O error */
+#define	EDQUOT		122	/* Quota exceeded */
+
+#define	ENOMEDIUM	123	/* No medium found */
+#define	EMEDIUMTYPE	124	/* Wrong medium type */
+
+#endif /* __MICROBLAZE_ERRNO_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/exceptions.h linux-2.4.29-uc1/include/asm-microblaze/exceptions.h
--- linux-2.4.29/include/asm-microblaze/exceptions.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/exceptions.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,109 @@
+/*
+ * Preliminary support for HW exception handing for Microblaze
+ *
+ * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+#ifndef _ASM_EXCEPTIONS_H
+#define _ASM_EXCEPTIONS_H
+
+#include <linux/config.h>
+
+/* This is klunky, but too bad.  How many HW exception types are there, 
+ * apart from the unaligned exception?
+ */
+#define NUM_OTHER_EXCEPTIONS 4
+
+/* Some helper macros to let the exception handler code cleaner */
+
+/* Are there *any* HW exceptions enabled? */
+#define MICROBLAZE_EXCEPTIONS_ENABLED 					\
+	(CONFIG_XILINX_MICROBLAZE0_UNALIGNED_EXCEPTIONS ||		\
+	 CONFIG_XILINX_MICROBLAZE0_ILL_OPCODE_EXCEPTION ||		\
+	 CONFIG_XILINX_MICROBLAZE0_IOPB_BUS_EXCEPTION ||		\
+	 CONFIG_XILINX_MICROBLAZE0_DOPB_BUS_EXCEPTION ||		\
+	 CONFIG_XILINX_MICROBLAZE0_DIV_ZERO_EXCEPTION)
+
+/* Are there any HW exceptions *other than* the unaligned exception? */
+#define NO_OTHER_EXCEPTIONS						\
+	(!(								\
+	 CONFIG_XILINX_MICROBLAZE0_ILL_OPCODE_EXCEPTION ||		\
+	 CONFIG_XILINX_MICROBLAZE0_IOPB_BUS_EXCEPTION ||		\
+	 CONFIG_XILINX_MICROBLAZE0_DOPB_BUS_EXCEPTION ||		\
+	 CONFIG_XILINX_MICROBLAZE0_DIV_ZERO_EXCEPTION))
+
+#ifndef __ASSEMBLY__
+
+/* Data tsructure used by the "other" exception handlers (non-unaligned) */
+typedef void (*ex_handler_t)(unsigned);
+
+struct mb_exception_vector {
+	ex_handler_t handler;
+	unsigned param;
+};
+
+extern struct mb_exception_vector MB_ExceptionVectorTable[NUM_OTHER_EXCEPTIONS];
+
+extern void initialize_exception_handlers(void);
+
+/* Macros to enable and disable HW exceptions in the MSR */
+/* Define MSR enable bit for HW exceptions */
+#define HWEX_MSR_BIT (1 << 8)
+
+#if MICROBLAZE_EXCEPTIONS_ENABLED
+
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+#define __enable_hw_exceptions()					\
+	__asm__ __volatile__ ("	msrset	r0, %0;				\
+				nop;"					\
+				: 					\
+				: "i" (HWEX_MSR_BIT)			\
+				: "memory")
+
+#define __disable_hw_exceptions()					\
+	__asm__ __volatile__ ("	msrclr r0, %0;				\
+				nop;"					\
+				: 					\
+				: "i" (HWEX_MSR_BIT)			\
+				: "memory")
+
+
+#else /* !CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+#define __enable_hw_exceptions()					\
+	__asm__ __volatile__ ("						\
+				mfs	r12, rmsr;			\
+				ori	r12, r12, %0;			\
+				mts	rmsr, r12;			\
+				nop;"					\
+				: 					\
+				: "i" (HWEX_MSR_BIT)			\
+				: "memory", "r12")
+
+#define __disable_hw_exceptions()					\
+	__asm__ __volatile__ ("						\
+				mfs	r12, rmsr;			\
+				andi	r12, r12, ~%0;			\
+				mts	rmsr, r12;			\
+				nop;"					\
+				: 					\
+				: "i" (HWEX_MSR_BIT)			\
+				: "memory", "r12")
+
+ 
+#endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+
+#else		/* MICROBLAZE_EXCEPTIONS_ENABLED */
+#define __enable_hw_exceptions()
+#define __disable_hw_exceptions()
+#endif		/* MICROBLAZE_EXCEPTIONS_ENABLED */
+
+#endif /*__ASSEMBLY__ */
+
+
+#endif
+
+
diff -urN linux-2.4.29/include/asm-microblaze/fcntl.h linux-2.4.29-uc1/include/asm-microblaze/fcntl.h
--- linux-2.4.29/include/asm-microblaze/fcntl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/fcntl.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,86 @@
+#ifndef __MICROBLAZE_FCNTL_H__
+#define __MICROBLAZE_FCNTL_H__
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	  0003
+#define O_RDONLY	    00
+#define O_WRONLY	    01
+#define O_RDWR		    02
+#define O_CREAT		  0100	/* not fcntl */
+#define O_EXCL		  0200	/* not fcntl */
+#define O_NOCTTY	  0400	/* not fcntl */
+#define O_TRUNC		 01000	/* not fcntl */
+#define O_APPEND	 02000
+#define O_NONBLOCK	 04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC		010000
+#define FASYNC		020000	/* fcntl, for BSD compatibility */
+#define O_DIRECTORY	040000	/* must be a directory */
+#define O_NOFOLLOW     0100000	/* don't follow links */
+#define O_DIRECT       0200000	/* direct disk access hint - currently ignored */
+#define O_LARGEFILE    0400000
+
+#define F_DUPFD		0	/* dup */
+#define F_GETFD		1	/* get close_on_exec */
+#define F_SETFD		2	/* set/clear close_on_exec */
+#define F_GETFL		3	/* get file->f_flags */
+#define F_SETFL		4	/* set file->f_flags */
+#define F_GETLK		5
+#define F_SETLK		6
+#define F_SETLKW	7
+
+#define F_SETOWN	8	/*  for sockets. */
+#define F_GETOWN	9	/*  for sockets. */
+#define F_SETSIG	10	/*  for sockets. */
+#define F_GETSIG	11	/*  for sockets. */
+
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK		0
+#define F_WRLCK		1
+#define F_UNLCK		2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+/* for leases */
+#define F_INPROGRESS	16
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* or'd with one of the above to prevent
+				   blocking */
+#define LOCK_UN		8	/* remove lock */
+
+#define LOCK_MAND	32	/* This is a mandatory flock */
+#define LOCK_READ	64	/* ... Which allows concurrent read operations */
+#define LOCK_WRITE	128	/* ... Which allows concurrent write operations */
+#define LOCK_RW		192	/* ... Which allows concurrent read & write ops */
+
+struct flock {
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE	1024
+#endif /* __MICROBLAZE_FCNTL_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/flat.h linux-2.4.29-uc1/include/asm-microblaze/flat.h
--- linux-2.4.29/include/asm-microblaze/flat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/flat.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,88 @@
+/*
+ * include/asm-microblaze/flat.h -- uClinux flat-format executables
+ */
+
+#ifndef __MICROBLAZE_FLAT_H__
+#define __MICROBLAZE_FLAT_H__
+
+#include <asm/unaligned.h>
+
+#define	flat_stack_align(sp)		/* nothing needed */
+#define	flat_argvp_envp_on_stack()	0
+#define	flat_old_ram_flag(flags)	(flags)
+#define	flat_reloc_valid(reloc, size)	((reloc) <= (size))
+
+/*
+ * Microblaze works a little differently from other arches, because 
+ * of the MICROBLAZE_64 reloc type.  Here, a 32 bit address is split
+ * over two instructions, an 'imm' instruction which provides the top
+ * 16 bits, then the instruction "proper" which provides the low 16
+ * bits.
+ */
+
+/*
+ * Crack open a symbol reference and extract the address to be
+ * relocated.  rp is a potentially unaligned pointer to the 
+ * reference
+ */
+
+static inline unsigned long
+flat_get_addr_from_rp(unsigned long *rp, unsigned long relval, unsigned long flags)
+{
+	unsigned long addr;
+	(void)flags;
+
+	/* Is it a split 64/32 reference? */
+	if(relval & 0x80000000)
+	{
+		/* Grab the two halves of the reference */
+		unsigned long val_hi, val_lo;
+
+		val_hi = get_unaligned(rp);
+		val_lo = get_unaligned(rp+1);
+
+		/* Crack the address out */
+		addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff);
+	}
+	else
+	{
+		/* Get the address straight out */
+		addr = get_unaligned(rp);
+	}
+
+	return addr;
+}
+
+/*
+ * Insert an address into the symbol reference at rp.  rp is potentially
+ * unaligned.
+ */
+
+static inline void
+flat_put_addr_at_rp(unsigned long *rp, unsigned long addr, unsigned long relval)
+{
+	/* Is this a split 64/32 reloc? */
+	if(relval & 0x80000000)
+	{
+		/* Get the two "halves" */
+		unsigned long val_hi = get_unaligned(rp);
+		unsigned long val_lo = get_unaligned(rp + 1);
+
+		/* insert the address */
+		val_hi = (val_hi & 0xffff0000) | addr >> 16;
+		val_lo = (val_lo & 0xffff0000) | (addr & 0xffff);
+
+		/* store the two halves back into memory */
+		put_unaligned(val_hi, rp);
+		put_unaligned(val_lo, rp+1);
+	}
+	else
+	{
+		/* Put it straight in, no messing around */
+		put_unaligned(addr, rp);
+	}
+}
+
+#define	flat_get_relocate_addr(rel)			(rel & 0x7fffffff)
+
+#endif /* __MICROBLAZE_FLAT_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/fslfifo_ioctl.h linux-2.4.29-uc1/include/asm-microblaze/fslfifo_ioctl.h
--- linux-2.4.29/include/asm-microblaze/fslfifo_ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/fslfifo_ioctl.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,46 @@
+/*
+ * IOCTL constants for the FSL FIFO device/driver
+ *
+ * Copyright (C) 2004 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ *
+ */
+
+#ifndef _FSLFIFO_IOCTL_H
+#define _FSLFIFO_IOCTL_H
+
+#include <linux/ioctl.h>
+
+#define FSLFIFO_MAGIC 'f'
+
+/* Reset the SW buffers */
+#define FSLFIFO_IOCRESET _IO(FSLFIFO_MAGIC, 0)
+
+/*
+ * S means "Set" through a ptr
+ * T means "Tell" directly with the argument value
+ * G means "Get" reply by setting through a ptr
+ * Q means "Query" response is on the return value
+ */
+
+/* Write a control value to the FSL channel */
+#define FSLFIFO_IOCTCONTROL _IOW(FSLFIFO_MAGIC, 1, unsigned)
+
+/* Read a control value from the FSL channel */
+#define FSLFIFO_IOCQCONTROL _IOR(FSLFIFO_MAGIC, 2, unsigned)
+
+/* Set the data width.  This forces a reset of the SW buffers */
+#define FSLFIFO_IOCTWIDTH  _IOW(FSLFIFO_MAGIC, 3, unsigned)
+
+/* Read the data width */
+#define FSLFIFO_IOCQWIDTH  _IOR(FSLFIFO_MAGIC, 4, unsigned)
+
+#define FSLFIFO_IOC_MAXNR 4
+
+#endif
+
+
diff -urN linux-2.4.29/include/asm-microblaze/fsl.h linux-2.4.29-uc1/include/asm-microblaze/fsl.h
--- linux-2.4.29/include/asm-microblaze/fsl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/fsl.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,158 @@
+/*
+ * include/asm-microblaze/fsl.h -- Low-level FSL ops
+ *
+ *  Copyright (C) 2004  John Williams (jwilliams@itee.uq.edu.au)
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#ifndef _FSL_H
+#define _FSL_H
+
+/*
+ * We provide a bunch of kernel macros to make life easier when writing
+ * device drivers for FSL-based cores.  Specifically, we have:
+ *
+ * Put values onto a particular FSL channel (id):
+ *	fsl_nput(id,value,status)	- data put
+ *	fsl_ncput(id,value,status)	- control put
+ *
+ * Get values from an FSL channel:
+ *	fsl_nget(id,value,status)	- data get
+ *	fsl_ncget(id,value,status)	- control get
+ *
+ * Interpret status value returned from the above macros:
+ *	fsl_error(status) 		- error (usually control/data mismatch)
+ *	fsl_nodata(status)		- no data (or FSL full)
+ */
+
+#include <asm/macrology.h>
+
+#ifndef __KERNEL__
+#warning You really should not use these from userspace! 
+#endif
+
+/* How to do this?  FSL channel ID is embedded in opcode...
+
+   Do it as a bunch of macros, using a case statement.  gcc at optimisation
+   level 2 seems to make a pretty good job of it.
+
+   This creates cryptic (ab)use of the C preprocessor.
+   cc can detect and optimise for the situation where the fsl port ID is a 
+   compile-time constant.  Otherwise, it generates the full packet of guff...
+
+   Goran promised that if I had to write self-modifying code, he would 
+	alter the instruction set!
+*/
+
+/* Bit positions within Microblaze MSR */
+#define MSR_CARRY_MASK		((1 << 2))
+#define MSR_FSL_ERROR_MASK	((1 << 4))
+
+/* Operators to query return status from fsl operations */
+#define fsl_error(status) (((status) & MSR_FSL_ERROR_MASK) ? 1 : 0)
+#define fsl_nodata(status) (((status) & MSR_CARRY_MASK) ? 1 : 0)
+
+/* "raw" nget and nput macros, using macro params to specify the 
+   FSL channel number. Obviously, "id" must be statically and numerically 
+   specified at compile time.  status is just a sample of the MSR immediately 
+   following the fsl operation.  No idea what happens if we get interrupted
+   in between, but really don't want to do save_flags_cli()/restore_flags()...
+   Hopefully the interrupt handler is well behaved and saves/restores flags reg
+
+   Blocking gets and puts are not supported - they could (will) lock up 
+   the processor harder than you can imagine!  Not even an NMI will recover
+   an FSL blocked microblaze - only reset!
+
+   We support control and data get/put ops.
+*/
+
+/* Form a string like rFSL{id} */
+#define __fsl_id(id)							\
+	macrology_stringify(macrology_paste(rFSL,id))
+
+/* Construct the standard sequences of "fsl op; get msr" */
+#define __fsl_nget(id, value, status)					\
+	__asm__ __volatile__ ("	nget  %0, " __fsl_id(id) ";\n		\
+				mfs %1, rMSR; \n"			\
+				: "=r" (value), "=r" (status)		\
+				:					\
+				: "memory");
+
+#define __fsl_ncget(id, value, status)					\
+	__asm__ __volatile__ ("	ncget	%0, " __fsl_id(id) ";\n		\
+				mfs	%1, rMSR;\n"			\
+				: "=r" (value), "=r" (status)		\
+				:					\
+				: "memory");
+
+#define __fsl_nput(id, value, status)					\
+	__asm__ __volatile__ ("nput	%1, " __fsl_id(id) " ;\n	\
+				mfs	%0, rMSR;\n"			\
+				: "=r" (status)				\
+				: "r" (value)				\
+				: "memory");
+
+
+#define __fsl_ncput(id, value, status)					\
+	__asm__ __volatile__ ("ncput	%1, "  __fsl_id(id) ";\n	\
+				mfs	%0, rMSR;\n"			\
+				: "=r" (status)				\
+				: "r" (value)				\
+				: "memory");
+
+
+/* Some more hideous C preproc stuff to save typing 
+
+  op is the fsl op (get|put}
+  id is the fsl id (0-7)
+  iscont is either 'c' or blank - is it a control put/get?
+*/
+#define __fsl_op(op,iscont)						\
+	macrology_paste(__fsl_n,macrology_paste(iscont,op))
+
+#define __fsl_case_helper(id,value,status,op,iscont)			\
+	case id:							\
+		__fsl_op(op,iscont)(id,value,status);			\
+		break;
+
+#define fsl_op(id,value,status,op,iscont)				\
+{									\
+	switch((id))							\
+	{								\
+		__fsl_case_helper(0,value,status,op,iscont);		\
+		__fsl_case_helper(1,value,status,op,iscont);		\
+		__fsl_case_helper(2,value,status,op,iscont);		\
+		__fsl_case_helper(3,value,status,op,iscont);		\
+		__fsl_case_helper(4,value,status,op,iscont);		\
+		__fsl_case_helper(5,value,status,op,iscont);		\
+		__fsl_case_helper(6,value,status,op,iscont);		\
+		__fsl_case_helper(7,value,status,op,iscont);		\
+		default:						\
+			status=~0;					\
+	}								\
+}
+
+/* The main user "routines"  The nice thing about this is that at -O2, if
+   a constant is passed as the fsl ID, the entire case structure gets
+   optimised away, reducing to just the specific fsl and rmsr opcodes 
+   for the operation.  Very nice :)
+*/
+#define fsl_nput(id,value,status)					\
+	{fsl_op(id,value,status,put,)}
+
+#define fsl_ncput(id,value,status)					\
+	{fsl_op(id,value,status,put,c)}
+
+#define fsl_nget(id,value,status)					\
+	{fsl_op(id,value,status,get,)}
+
+#define fsl_ncget(id,value,status)					\
+	{fsl_op(id,value,status,get,c)}
+
+#endif
+
+
diff -urN linux-2.4.29/include/asm-microblaze/hardirq.h linux-2.4.29-uc1/include/asm-microblaze/hardirq.h
--- linux-2.4.29/include/asm-microblaze/hardirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/hardirq.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,42 @@
+#ifndef __MICROBLAZE_HARDIRQ_H__
+#define __MICROBLAZE_HARDIRQ_H__
+
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <linux/cache.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned int __local_irq_count;
+	unsigned int __local_bh_count;
+	unsigned int __syscall_count;
+	struct task_struct * __ksoftirqd_task;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt() (local_irq_count(smp_processor_id()) + local_bh_count(smp_processor_id()) != 0)
+
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
+
+#ifndef CONFIG_SMP
+
+#define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
+#define hardirq_endlock(cpu)	do { } while (0)
+
+#define irq_enter(cpu, irq)	(local_irq_count(cpu)++)
+#define irq_exit(cpu, irq)	(local_irq_count(cpu)--)
+
+#define synchronize_irq()	barrier()
+
+#else
+
+#error microblaze SMP is not available
+
+#endif /* CONFIG_SMP */
+
+#endif /* __MICROBLAZE_HARDIRQ_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/hw_irq.h linux-2.4.29-uc1/include/asm-microblaze/hw_irq.h
--- linux-2.4.29/include/asm-microblaze/hw_irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/hw_irq.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,8 @@
+#ifndef __MICROBLAZE_HW_IRQ_H__
+#define __MICROBLAZE_HW_IRQ_H__
+
+extern inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int i)
+{
+}
+
+#endif /* __MICROBLAZE_HW_IRQ_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/ioctl.h linux-2.4.29-uc1/include/asm-microblaze/ioctl.h
--- linux-2.4.29/include/asm-microblaze/ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/ioctl.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,79 @@
+/*
+ * linux/ioctl.h for Linux by H.H. Bergman.
+ */
+
+#ifndef _MICROBLAZE_IOCTL_H
+#define _MICROBLAZE_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * I don't really have any idea about what this should look like, so
+ * for the time being, this is heavily based on the PC definitions.
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	14
+#define _IOC_DIRBITS	2
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE	0U
+#define _IOC_WRITE	1U
+#define _IOC_READ	2U
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* __MICROBLAZE_IOCTL_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/ioctls.h linux-2.4.29-uc1/include/asm-microblaze/ioctls.h
--- linux-2.4.29/include/asm-microblaze/ioctls.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/ioctls.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,82 @@
+#ifndef __MICROBLAZE_IOCTLS_H__
+#define __MICROBLAZE_IOCTLS_H__
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+#define TIOCSBRK	0x5427  /* BSD compatibility */
+#define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define FIONCLEX	0x5450  /* these numbers need to be adjusted. */
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+
+#define	FIOQSIZE	0x545E
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+#endif /* __MICROBLAZE_IOCTLS_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/io.h linux-2.4.29-uc1/include/asm-microblaze/io.h
--- linux-2.4.29/include/asm-microblaze/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/io.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,166 @@
+/*
+ * include/asm-microblaze/io.h -- Misc I/O operations
+ *
+ *  Copyright (C) 2003     John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_IO_H__
+#define __MICROBLAZE_IO_H__
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/virtconvert.h>
+#include <asm/page.h>
+#include <linux/mm.h>		/* Get struct page {...} */
+
+#define IO_SPACE_LIMIT 0xFFFFFFFF
+
+#if CONFIG_XILINX_UNCACHED_SHADOW
+#define UNCACHED_SHADOW_MASK (1 << CONFIG_XILINX_UNCACHED_BIT)
+#else
+#define UNCACHED_SHADOW_MASK (0x0)
+#endif
+
+#define readb(addr) \
+  ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
+#define readw(addr) \
+  ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
+#define readl(addr) \
+  ({ unsigned long __v = (*(volatile unsigned long *) (addr)); __v; })
+
+#define writeb(b, addr) \
+  (void)((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b, addr) \
+  (void)((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b, addr) \
+  (void)((*(volatile unsigned int *) (addr)) = (b))
+
+#define memset_io(a,b,c)        memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)    memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)      memcpy((void *)(a),(b),(c))
+
+#define inb(addr)	readb (addr)
+#define inw(addr)	readw (addr)
+#define inl(addr)	readl (addr)
+#define outb(x, addr)	((void) writeb (x, addr))
+#define outw(x, addr)	((void) writew (x, addr))
+#define outl(x, addr)	((void) writel (x, addr))
+
+/* Some #definitions to keep strange Xilinx code happy */
+#define in_8(addr)	readb (addr)
+#define in_be16(addr)	readw (addr)
+#define in_be32(addr)	readl (addr)
+
+#define out_8(addr,x )	outb (x,addr)
+#define out_be16(addr,x )	outw (x,addr)
+#define out_be32(addr,x )	outl (x,addr)
+
+
+
+#define inb_p(port)		inb((port))
+#define outb_p(val, port)	outb((val), (port))
+#define inw_p(port)		inw((port))
+#define outw_p(val, port)	outw((val), (port))
+#define inl_p(port)		inl((port))
+#define outl_p(val, port)	outl((val), (port))
+
+/* Some defines to keep the MTD flash drivers happy */
+
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
+
+static inline void io_insb (unsigned long port, void *dst, unsigned long count)
+{
+	unsigned char *p = dst;
+	while (count--)
+		*p++ = inb (port);
+}
+static inline void io_insw (unsigned long port, void *dst, unsigned long count)
+{
+	unsigned short *p = dst;
+	while (count--)
+		*p++ = inw (port);
+}
+static inline void io_insl (unsigned long port, void *dst, unsigned long count)
+{
+	unsigned long *p = dst;
+	while (count--)
+		*p++ = inl (port);
+}
+
+static inline void
+io_outsb (unsigned long port, const void *src, unsigned long count)
+{
+	const unsigned char *p = src;
+	while (count--)
+		outb (*p++, port);
+}
+static inline void
+io_outsw (unsigned long port, const void *src, unsigned long count)
+{
+	const unsigned short *p = src;
+	while (count--)
+		outw (*p++, port);
+}
+static inline void
+io_outsl (unsigned long port, const void *src, unsigned long count)
+{
+	const unsigned long *p = src;
+	while (count--)
+		outl (*p++, port);
+}
+
+#define outsb(a,b,l) io_outsb(a,b,l)
+#define outsw(a,b,l) io_outsw(a,b,l)
+#define outsl(a,b,l) io_outsl(a,b,l)
+
+#define insb(a,b,l) io_insb(a,b,l)
+#define insw(a,b,l) io_insw(a,b,l)
+#define insl(a,b,l) io_insl(a,b,l)
+
+#define iounmap(addr)				((void)0)
+#define ioremap(physaddr, size)			(physaddr)
+#define ioremap_writethrough(physaddr, size)	(physaddr)
+#define ioremap_nocache(physaddr, size)		(physaddr)
+#define ioremap_fullcache(physaddr, size)	(physaddr)
+
+
+/*
+ * DMA mapping functions.  Microblaze has no cache coherency, so we must
+ * handle the cache flushing stuff properly.  
+ */
+#define dma_cache_inv(_start,_size) \
+        invalidate_dcache_range(_start, (_start + _size))
+#define dma_cache_wback(_start,_size) \
+        clean_dcache_range(_start, (_start + _size))
+#define dma_cache_wback_inv(_start,_size) \
+        flush_dcache_range(_start, (_start + _size))
+
+/*              
+ * DMA-consistent mapping functions, since Microblaze doesn't support
+ * cache snooping.  These allocate/free a region of uncached mapped
+ * memory space for use with DMA devices.  On Microblaze, the config variable
+ * CONFIG_XILINX_UNCACHED_SHADOW determines if this is implemented physically,
+ * using a shadow memory region outside the processor cacheable range, or
+ * if driver/kernel code must simulate it by explicitly flushing the cache
+ */     
+extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle);
+extern void consistent_free(void *vaddr);
+extern void consistent_sync(void *vaddr, size_t size, int rw);
+extern void consistent_sync_page(struct page *page, unsigned long offset,
+                                 size_t size, int rw);
+
+#endif /* __MICROBLAZE_IO_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/ipcbuf.h linux-2.4.29-uc1/include/asm-microblaze/ipcbuf.h
--- linux-2.4.29/include/asm-microblaze/ipcbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/ipcbuf.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,29 @@
+#ifndef __MICROBLAZEE_IPCBUF_H__
+#define __MICROBLAZEE_IPCBUF_H__
+
+/*
+ * The user_ipc_perm structure for microblazee architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
+	__kernel_mode_t		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* __MICROBLAZEE_IPCBUF_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/ipc.h linux-2.4.29-uc1/include/asm-microblaze/ipc.h
--- linux-2.4.29/include/asm-microblaze/ipc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/ipc.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef __MICROBLAZE_IPC_H__
+#define __MICROBLAZE_IPC_H__
+
+/* 
+ * These are used to wrap system calls on microblaze.
+ *
+ * See arch/microblaze/kernel/syscalls.c for ugly details..
+ */
+struct ipc_kludge {
+	struct msgbuf *msgp;
+	long msgtyp;
+};
+
+#define SEMOP		 1
+#define SEMGET		 2
+#define SEMCTL		 3
+#define MSGSND		11
+#define MSGRCV		12
+#define MSGGET		13
+#define MSGCTL		14
+#define SHMAT		21
+#define SHMDT		22
+#define SHMGET		23
+#define SHMCTL		24
+
+/* Used by the DIPC package, try and avoid reusing it */
+#define DIPC		25
+
+#define IPCCALL(version,op)	((version)<<16 | (op))
+
+#endif /* __MICROBLAZE_IPC_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/irq.h linux-2.4.29-uc1/include/asm-microblaze/irq.h
--- linux-2.4.29/include/asm-microblaze/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/irq.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,58 @@
+/*
+ * include/asm-microblaze/irq.h -- Machine interrupt handling
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_IRQ_H__
+#define __MICROBLAZE_IRQ_H__
+
+#include <asm/machdep.h>
+
+/* Default NUM_MACH_IRQS.  */
+#ifndef NUM_MACH_IRQS
+#define NUM_MACH_IRQS	NUM_CPU_IRQS
+#endif
+
+/* NMIs have IRQ numbers from FIRST_NMI to FIRST_NMI+NUM_NMIS-1.  */
+#define FIRST_NMI	NUM_MACH_IRQS
+#define IRQ_NMI(n)	(FIRST_NMI + (n))
+/* microblaze processors have 3 non-maskable interrupts.  */
+#define NUM_NMIS	3
+
+/* Includes both maskable and non-maskable irqs.  */
+#define NR_IRQS		(NUM_MACH_IRQS + NUM_NMIS)
+
+
+#ifndef __ASSEMBLY__
+
+struct pt_regs;
+struct hw_interrupt_type;
+struct irqaction;
+
+/* Initialize irq handling for IRQs BASE to BASE+NUM-1 to IRQ_TYPE.
+   An IRQ_TYPE of 0 means to use a generic interrupt type.  */
+extern void init_irq_handlers (int base_irq, int num,
+			       struct hw_interrupt_type *irq_type);
+
+typedef void (*irq_handler_t)(int irq, void *data, struct pt_regs *regs);
+
+/* Handle interrupt IRQ.  REGS are the registers at the time of ther
+   interrupt.  */
+extern unsigned int handle_irq (int irq, struct pt_regs *regs);
+
+extern void enable_irq(unsigned int);
+extern void disable_irq(unsigned int);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __MICROBLAZE_IRQ_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/long_shift.h linux-2.4.29-uc1/include/asm-microblaze/long_shift.h
--- linux-2.4.29/include/asm-microblaze/long_shift.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/long_shift.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,10 @@
+#ifndef _LONG_SHIFT_H
+#define _LONG_SHIFT_H
+
+/* Slow but compileable shift operations for unsigned long data type */
+unsigned long long longshift_left(unsigned long long val, int shift);
+unsigned long long longshift_right(unsigned long long val, int shift);
+
+#endif
+
+
diff -urN linux-2.4.29/include/asm-microblaze/machdep.h linux-2.4.29-uc1/include/asm-microblaze/machdep.h
--- linux-2.4.29/include/asm-microblaze/machdep.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/machdep.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,37 @@
+/*
+ * include/asm-microblaze/machdep.h -- Machine-dependent definitions
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_MACHDEP_H__
+#define __MICROBLAZE_MACHDEP_H__
+
+#include <linux/config.h>
+
+/* chips */
+#ifdef CONFIG_MICROBLAZE
+#include <asm/microblaze.h>
+#endif
+
+/* platforms */
+#ifdef CONFIG_MBVANILLA
+#include <asm/mbvanilla.h>
+#endif
+#ifdef CONFIG_MBEGRET
+#include <asm/mbegret.h>
+#endif
+#ifdef CONFIG_SUZAKU
+#include <asm/suzaku.h>
+#endif
+
+#endif /* __MICROBLAZE_MACHDEP_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/mach.h linux-2.4.29-uc1/include/asm-microblaze/mach.h
--- linux-2.4.29/include/asm-microblaze/mach.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/mach.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,60 @@
+/*
+ * arch/microblaze/kernel/mach.h -- Machine-dependent functions used by Microblaze port
+ *
+ *  Copyright (C) 2003	     John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#ifndef __MICROBLAZE_MACH_H__
+#define __MICROBLAZE_MACH_H__
+
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+
+#include <asm/ptrace.h>
+#include <asm/entry.h>
+#include <asm/clinkage.h>
+
+#define DEBUG_MSG printk(KERN_INFO "%s:%s:%s\n",__FILE__,__FUNCTION__, __LINE__)
+
+void mach_heartbeat(unsigned int value);
+void mach_setup (char **cmdline);
+void mach_gettimeofday (struct timeval *tv);
+unsigned long mach_gettimeoffset(void);
+void mach_sched_init (struct irqaction *timer_action);
+void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len);
+void mach_init_irqs (void);
+
+/* If defined, is called very early in the kernel initialization.  The
+   stack pointer is valid, but very little has been initialized (e.g.,
+   bss is not zeroed yet) when this is called, so care must taken.  */
+void mach_early_init (void);
+
+/* If defined, called after the bootmem allocator has been initialized,
+   to allow the platform-dependent code to reserve any areas of RAM that
+   the kernel shouldn't touch.  */
+void mach_reserve_bootmem (void) __attribute__ ((__weak__));
+
+/* Called with each timer tick, if non-zero.  */
+extern void (*mach_tick) (void);
+
+/* The following establishes aliases for various mach_ functions to the
+   name by which the rest of the kernal calls them.  These statements
+   should only have an effect in the file that defines the actual functions. */
+#define MACH_ALIAS(to, from)						      \
+   asm (".global " macrology_stringify (C_SYMBOL_NAME (to)) ";"		      \
+	macrology_stringify (C_SYMBOL_NAME (to))			      \
+	" = " macrology_stringify (C_SYMBOL_NAME (from)))
+/* e.g.: MACH_ALIAS (kernel_name,	arch_spec_name);  */
+
+#endif /* __MICROBLAZE_MACH_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/macrology.h linux-2.4.29-uc1/include/asm-microblaze/macrology.h
--- linux-2.4.29/include/asm-microblaze/macrology.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/macrology.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,19 @@
+/*
+ * include/asm-microblaze/macrology.h -- Various useful CPP macros
+ *
+ *  Copyright (C) 2003  John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#define macrology_paste(arg1, arg2)	macrology_paste_1(arg1, arg2)
+#define macrology_paste_1(arg1, arg2)	arg1 ## arg2
+#define macrology_stringify(sym)	macrology_stringify_1(sym)
+#define macrology_stringify_1(sym)	#sym
diff -urN linux-2.4.29/include/asm-microblaze/map.h linux-2.4.29-uc1/include/asm-microblaze/map.h
--- linux-2.4.29/include/asm-microblaze/map.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/map.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ *  linux/include/asm-microblaze/map.h
+ *
+ *  Copyright (C) 1999-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Page table mapping constructs and function prototypes
+ */
+struct map_desc {
+	unsigned long virtual;
+	unsigned long physical;
+	unsigned long length;
+	int domain:4,
+	    prot_read:1,
+	    prot_write:1,
+	    cacheable:1,
+	    bufferable:1,
+	    last:1;
+};
+
+#define LAST_DESC \
+  { last: 1 }
+
+struct meminfo;
+
+extern void create_memmap_holes(struct meminfo *);
+extern void memtable_init(struct meminfo *);
+extern void iotable_init(struct map_desc *);
+extern void setup_io_desc(void);
diff -urN linux-2.4.29/include/asm-microblaze/mbvanilla.h linux-2.4.29-uc1/include/asm-microblaze/mbvanilla.h
--- linux-2.4.29/include/asm-microblaze/mbvanilla.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/mbvanilla.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,71 @@
+/*  /include/asm-microblaze/mbvanilla.h
+ *
+ *  (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ *  Defines board specific stuff for a "vanilla" microblaze system
+ *
+ */
+
+#ifndef _ASM_MICROBLAZE_MBVANILLA_H
+#define _ASM_MICROBLAZE_MBVANILLA_H
+
+#include <asm/autoconfig.h>
+
+/*
+ * All Microblaze uClinux systems require a timer, interrupt controller
+ * and UART.  Here, we define base addresses for each, then include
+ * specific header files to get the rest.
+ *
+ * Note other, non-system peripherals may also exist (including UARTs and
+ * timers), however these are handled differently (haven't worked out how yet!)
+ */
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+/* interrupt controller */
+#ifndef MICROBLAZE_INTC_BASE_ADDR
+#define MICROBLAZE_INTC_BASE_ADDR 0xFFFF3000
+#endif
+
+/* timer */
+#ifndef MICROBLAZE_TIMER_BASE_ADDR
+#define MICROBLAZE_TIMER_BASE_ADDR 0xFFFF1000
+#endif
+#define MICROBLAZE_TIMER_IRQ_NO 0
+
+/* UART */
+#ifndef MICROBLAZE_UART_BASE_ADDR
+#define MICROBLAZE_UART_BASE_ADDR 0xFFFF2000
+#endif
+#define MICROBLAZE_UART_IRQ_NO 1
+
+/* Memory controller */
+#ifndef MICROBLAZE_MEMCON_BASE_ADDR
+#define MICROBLAZE_MEMCON_BASE_ADDR 0xFFFF0000
+#endif
+
+/* GPIO */
+#ifndef MICROBLAZE_GPIO_BASE_ADDR
+#define MICROBLAZE_GPIO_BASE_ADDR 0xFFFF5000
+#define MICROBLAZE_GPIO_DIR 0x0000FF00
+#endif
+
+/* Start and size of external RAM */
+/* #define ERAM_ADDR 0xFFE00000
+#define ERAM_SIZE 0x00100000 */
+#define ERAM_ADDR 0x80000000
+#define ERAM_SIZE 0x02000000
+
+/* for <asm/page.h> */
+#define PAGE_OFFSET ERAM_ADDR
+
+/* Something to do with interrupts - not quite sure yet */
+#define IRQ_RPU(n) 3+(n)
+#define IRQ_RPU_NUM 4
+
+#define NUM_CPU_IRQS 32
+
+#endif
+
diff -urN linux-2.4.29/include/asm-microblaze/microblaze_cache.h linux-2.4.29-uc1/include/asm-microblaze/microblaze_cache.h
--- linux-2.4.29/include/asm-microblaze/microblaze_cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/microblaze_cache.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,40 @@
+/*
+ * include/asm-microblaze/microblaze_cache.h -- Cache control for Microblaze
+ *
+ *  Copyright (C) 2003  John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_MICROBLAZE_CACHE_H__
+#define __MICROBLAZE_MICROBLAZE_CACHE_H__
+
+/* Size of a cache line in bytes.  */
+/* Microblaze has direct mapped cache, so line size is a single word */
+#define MICROBLAZE_CACHE_LINE_SIZE		4
+
+/* Define standard definitions in terms of processor-specific ones.  */
+/* Microblaze has no cache, so these all expand to nothing           */
+
+/* For <asm/cache.h> */
+#define L1_CACHE_BYTES				MICROBLAZE_CACHE_LINE_SIZE
+
+/* For <asm/pgalloc.h> */
+#define flush_cache_all()			
+#define flush_cache_mm(mm)			
+#define flush_cache_range(mm, start, end)	
+#define flush_cache_page(vma, vmaddr)		
+#define flush_page_to_ram(page)			
+#define flush_dcache_page(page)			
+#define flush_icache_range(start, end)		
+#define flush_icache_page(vma,pg)		
+#define flush_icache()				
+#define flush_cache_sigtramp(vaddr)		
+
+#endif /* __MICROBLAZE_MICROBLAZE_CACHE_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/microblaze_gpio.h linux-2.4.29-uc1/include/asm-microblaze/microblaze_gpio.h
--- linux-2.4.29/include/asm-microblaze/microblaze_gpio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/microblaze_gpio.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,23 @@
+
+#ifndef _microblaze_gpio_h
+#define _microblaze_gpio_h
+
+/*
+ * - MICROBLAZE_GPIO_DATA_OFFSET    Data register
+ * - MICROBLAZE_GPIO_TRI_OFFSET     Three state register (sets input/output direction)
+ *                        0 configures pin for output and 1 for input.
+ */
+#define MICROBLAZE_GPIO_DATA_OFFSET  0x00000000
+#define MICROBLAZE_GPIO_TRI_OFFSET   0x00000004
+
+#define microblaze_gpio_setdir(BaseAddress, Data) \
+	*((unsigned int *)(BaseAddress+MICROBLAZE_GPIO_TRI_OFFSET)) = (unsigned int)Data
+
+#define microblaze_gpio_write(BaseAddress, Data) \
+	*((unsigned int *)(BaseAddress+MICROBLAZE_GPIO_DATA_OFFSET)) = (unsigned int)Data
+
+#define microblaze_gpio_read(BaseAddress) \
+	*((unsigned int *)(BaseAddress+MICROBLAZE_GPIO_DATA_OFFSET))
+
+#endif
+
diff -urN linux-2.4.29/include/asm-microblaze/microblaze.h linux-2.4.29-uc1/include/asm-microblaze/microblaze.h
--- linux-2.4.29/include/asm-microblaze/microblaze.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/microblaze.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,37 @@
+/*
+ * include/asm-microblaze/microblaze.h -- Xilinx Microblaze softcore CPU
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_H__
+#define __MICROBLAZE_H__
+
+#include <asm/clinkage.h>
+
+#define CPU_MODEL	"Microblaze"
+#define CPU_MODEL_LONG	"Xilinx Microblaze"
+#define CPU_ARCH 	"microblaze"
+
+/* For <asm/irq.h> */
+#define NUM_CPU_IRQS	32
+
+#ifdef __ASSEMBLY__
+#define R0_RAM_ADDR (C_SYMBOL_NAME(r0_ram))
+#else
+extern char C_SYMBOL_NAME(r0_ram);
+#define R0_RAM_ADDR ((unsigned int)&C_SYMBOL_NAME(r0_ram))
+#endif
+ 
+/* #include <asm/microblaze_cache.h>  */
+
+#endif /* __MICROBLAZE_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/microblaze_intc.h linux-2.4.29-uc1/include/asm-microblaze/microblaze_intc.h
--- linux-2.4.29/include/asm-microblaze/microblaze_intc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/microblaze_intc.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,124 @@
+/*
+ * include/asm-microblaze/microblaze_intc.h -- Microblaze cpu core interrupt controller (INTC)
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * The following functions were previously all "extern inline", but that
+ * was causing some wierd problems.   
+ * The function bodies are now found in /arch/microblaze/microblaze_intc.c
+ */
+
+#ifndef __MICROBLAZE_INTC_H__
+#define __MICROBLAZE_INTC_H__
+
+#include <linux/config.h>
+
+#ifndef __ASSEMBLY__
+
+
+/* Test if an IRQ is edge or level sensitive */
+#define IRQ_LEVEL_SENSITIVE(irq,IRQ_KINDOFINTR)			\
+	((1 << irq) & IRQ_KINDOFINTR)
+
+#define IRQ_EDGE_SENSITIVE(irq,IRQ_KINDOFINTR)			\
+	(!IRQ_LEVEL_SENSITIVE(irq,IRQ_KINDOFINTR))
+
+/* What sort of edge sensitive IRQ? */
+#define IRQ_RISING_EDGE(irq,IRQ_KINDOFEDGE) 			\
+	((1<<irq) & IRQ_KINDOFEDGE)
+
+#define IRQ_FALLING_EDGE(irq,IRQ_KINDOFEDGE) 			\
+	(!IRQ_RISING_EDGE(irq,IRQ_KINDOFEDGE)
+
+/* What sort of level sensitive IRQ? */
+#define IRQ_ACTIVE_HIGH(irq,IRQ_KINDOFLVL)			\
+	((1<<irq) & IRQ_KINDOFLVL)
+
+#define IRQ_ACTIVE_LOW(irq,IRQ_KINDOFLVL)			\
+	(!IRQ_ACTIVE_HIGH(irq,IRQ_KINDOFLVL));
+
+/* Address map for Microblaze interrupt controller */
+#define MICROBLAZE_INTC_ISR_OFFSET 0
+#define MICROBLAZE_INTC_IPR_OFFSET 0x04
+#define MICROBLAZE_INTC_IER_OFFSET 0x08
+#define MICROBLAZE_INTC_IAR_OFFSET 0x0C
+#define MICROBLAZE_INTC_SIE_OFFSET 0x10
+#define MICROBLAZE_INTC_CIE_OFFSET 0x14
+#define MICROBLAZE_INTC_IVR_OFFSET 0x18
+#define MICROBLAZE_INTC_MER_OFFSET 0x1C
+
+/* Various status bits for writing to the intc */
+#define MICROBLAZE_INTC_MASTER_ENABLE_MASK      0x1UL
+#define MICROBLAZE_INTC_HARDWARE_ENABLE_MASK    0x2UL /* once set cannot be cleared */
+
+/* 
+ * Master enable on interrupt controller 
+ */
+extern void microblaze_intc_master_enable(void);
+
+/* 
+ * Get active IRQ from controller 
+ * Returns -1 if no IRQ is active.  This shouldn't happen because 
+ * this is only called from handle_irq()
+ */
+extern int microblaze_intc_get_active_irq(void);
+
+/* Acknowledge irq */
+extern void microblaze_intc_ack_irq(unsigned irq);
+
+/* Enable interrupt handling for interrupt IRQ.  */
+extern void microblaze_intc_enable_irq (unsigned irq);
+
+/* Disable interrupt handling for interrupt IRQ.  Note that any
+   interrupts received while disabled will be delivered once the
+   interrupt is enabled again, unless they are explicitly cleared using
+   `microblaze_intc_clear_pending_irq'.  */
+extern void microblaze_intc_disable_irq (unsigned irq);
+
+/* Disable specified IRQ and acknolwedge (used on IRQ entry) */
+extern void microblaze_intc_disable_and_ack_irq(unsigned irq);
+
+/* Enable specified IRQ (if not disabled by kernel) and acknowledge */
+extern void microblaze_intc_end(unsigned irq);
+
+/* Return true if interrupt handling for interrupt IRQ is enabled.  */
+extern int microblaze_intc_irq_enabled (unsigned irq);
+
+/* Disable irqs from 0 until LIMIT.  */
+extern void _microblaze_intc_disable_irqs (unsigned limit);
+
+/* Disable all irqs.  This is purposely a macro, because NUM_MACH_IRQS
+   will be only be defined later.  */
+#define microblaze_intc_disable_irqs()   _microblaze_intc_disable_irqs (NUM_MACH_IRQS)
+
+/* Clear any pending interrupts for IRQ.  */
+extern void microblaze_intc_clear_pending_irq (unsigned irq);
+
+/* Return true if interrupt IRQ is pending (but disabled).  */
+extern int microblaze_intc_irq_pending (unsigned irq);
+
+struct microblaze_intc_irq_init {
+	const char *name;	/* name of interrupt type */
+	unsigned base, num;	/* range of kernel irq numbers for this type */
+	unsigned priority;	/* interrupt priority to assign */
+};
+struct hw_interrupt_type;	/* fwd decl */
+
+/* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
+   INITS (which is terminated by an entry with the name field == 0).  */
+extern void microblaze_intc_init_irq_types (struct microblaze_intc_irq_init *inits,
+				       struct hw_interrupt_type *hw_irq_types);
+
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __MICROBLAZE_INTC_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/microblaze_system_timer.h linux-2.4.29-uc1/include/asm-microblaze/microblaze_system_timer.h
--- linux-2.4.29/include/asm-microblaze/microblaze_system_timer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/microblaze_system_timer.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,27 @@
+/*
+ * include/asm-microblaze/microblaze_system_timer.h -- 
+ *             Timer component required to bring up a Microblaze uClinux
+ *
+ *  Copyright (C) 2003  John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+/* 
+ * NOTE: doesn't do anything yet.  
+ */
+
+#ifndef __MICROBLAZE_MICROBLAZE_SYSTEM_TIMER_H__
+#define __MICROBLAZE_MICROBLAZE_SYSTEM_TIMER_H__
+
+#include <asm/types.h>
+#include <asm/machdep.h>	/* Pick up chip-specific defs.  */
+
+#endif /* __MICROBLAZE_MICROBLAZE_SYSTEM_TIMER_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/microblaze_system_uart.h linux-2.4.29-uc1/include/asm-microblaze/microblaze_system_uart.h
--- linux-2.4.29/include/asm-microblaze/microblaze_system_uart.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/microblaze_system_uart.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ * include/asm-microblaze/microblaze_system_uart.h -- system UART required 
+ * 	for booting a microblaze uClinux system
+ *
+ *  Copyright (C) 2003  John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+/* 
+ * Note this is all place-holder stuff grabbed from v850 code.  
+ * Doesn't do anything yet.
+ */
+
+#ifndef __MICROBLAZE_MICROBLAZE_SYSTEM_UART_H__
+#define __MICROBLAZE_MICROBLAZE_SYSTEM_UART_H__
+
+#include <asm/types.h>
+#include <asm/machdep.h>	/* Pick up chip-specific defs.  */
+
+#endif /* __MICROBLAZE_MICROBLAZE_SYSTEM_UART_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/microblaze_timer.h linux-2.4.29-uc1/include/asm-microblaze/microblaze_timer.h
--- linux-2.4.29/include/asm-microblaze/microblaze_timer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/microblaze_timer.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,132 @@
+/*************************************************************/
+/*   Copyright (c) 2001 Xilinx, Inc.  All rights reserved.   */
+/*                                                           */
+/*************************************************************/
+
+#ifndef __TIMER_H__
+#define __TIMER_H__
+
+#include <asm/types.h>
+#include <linux/config.h>
+
+/* Hack to optionally use Xilinx autoconfig if available */
+#if !defined(CONFIG_CPU_CLOCK_FREQ)
+#if defined(CONFIG_XILINX_CPU_CLOCK_FREQ)
+#define CONFIG_CPU_CLOCK_FREQ CONFIG_XILINX_CPU_CLOCK_FREQ
+#else
+#error CPU Clock frequerncy not defined!
+#endif
+#endif /* !defined(CONFIG_CPU_CLOCK_FREQ) */
+
+#if !defined(MICROBLAZE_TIMER_BASE_ADDR)
+#if defined(CONFIG_XILINX_TIMER_0_BASEADDR)
+#define MICROBLAZE_TIMER_BASE_ADDR CONFIG_XILINX_TIMER_0_BASEADDR
+#else
+#error No timer peripheral specified
+#endif
+#endif
+
+/*
+ * OPB Timer/Counter definitions
+ */
+
+/*
+ * Masks for the control/status register
+ */
+
+#define TIMER_ENABLE_ALL    0x400
+#define TIMER_PWM           0x200
+#define TIMER_INTERRUPT     0x100
+#define TIMER_ENABLE        0x080
+#define TIMER_ENABLE_INTR   0x040
+#define TIMER_RESET         0x020
+#define TIMER_RELOAD        0x010
+#define TIMER_EXT_CAPTURE   0x008
+#define TIMER_EXT_COMPARE   0x004
+#define TIMER_DOWN_COUNT    0x002
+#define TIMER_CAPTURE_MODE  0x001
+
+/*
+ * Timer/counter register positions: Note that these are offsets from the timer base address
+ */
+
+#define TIMER_CONTROL_STATUS_0  0x0
+#define TIMER_COMPARE_CAPTURE_0 0x4
+#define TIMER_COUNTER_0         0x8
+#define TIMER_CONTROL_STATUS_1  0x10
+#define TIMER_COMPARE_CAPTURE_1 0x14
+#define TIMER_COUNTER_1         0x18
+
+/*
+ * Macros to access the timer registers
+ */
+
+#define TIMER_TCSR0(base_addr) ((volatile __u32 *)(base_addr + TIMER_CONTROL_STATUS_0))
+#define TIMER_TCCR0(base_addr) ((volatile __u32 *)(base_addr + TIMER_COMPARE_CAPTURE_0))
+#define TIMER_TCR0(base_addr)  ((volatile __u32 *)(base_addr + TIMER_COUNTER_0))
+#define TIMER_TCSR1(base_addr) ((volatile __u32 *)(base_addr + TIMER_CONTROL_STATUS_1))
+#define TIMER_TCCR1(base_addr) ((volatile __u32 *)(base_addr + TIMER_COMPARE_CAPTURE_1))
+#define TIMER_TCR1(base_addr)  ((volatile __u32 *)(base_addr + TIMER_COUNTER_1))
+
+/*
+* Note that for all the following macros, timer_number must be 0 or 1 
+*/
+
+#define TIMER_TCSR(base_addr, timer_number) ((volatile __u32 *)(base_addr + (timer_number ? 0x10 : 0) + TIMER_CONTROL_STATUS_0))
+#define TIMER_TCCR(base_addr, timer_number) ((volatile __u32 *)(base_addr + (timer_number ? 0x10 : 0) + TIMER_COMPARE_CAPTURE_0))
+#define TIMER_TCR(base_addr, timer_number)  ((volatile __u32 *)(base_addr + (timer_number ? 0x10 : 0) + TIMER_COUNTER_0))
+
+/* 
+ * Set the control/status register
+ */
+
+#define timer_set_csr(base_addr, timer_number, status_value) (*TIMER_TCSR(base_addr, timer_number) = status_value)
+
+/*
+ * Get the control/status register
+ */
+
+#define timer_get_csr(base_addr, timer_number) (*TIMER_TCSR(base_addr, timer_number))
+
+/*
+ * Read the time value from the timer/counter register
+ */
+
+#define timer_get_time(base_addr, timer_number) (*TIMER_TCR(base_addr, timer_number))
+
+/*
+ * Get the capture register
+ */
+
+#define timer_get_capture(base_addr, timer_number) (*TIMER_TCCR(base_addr, timer_number))
+
+/*
+ * Get the compare register
+ */
+
+#define timer_get_compare(base_addr, timer_number) (*TIMER_TCCR(base_addr, timer_number))
+
+/*
+ * Set the compare register
+ */
+
+#define timer_set_compare(base_addr, timer_number, compare_value) (*TIMER_TCCR(base_addr, timer_number) = compare_value)
+
+/*
+ * Start timing a portion of code
+ */
+extern void start_timer(__u32 base_addr, __u32 timer_number);
+
+/*
+ * Get the elapsed time since the start of timing using start_timer
+ */
+
+extern __u32 get_elapsed_time(__u32 base_addr, __u32 timer_number);
+
+/*
+ * Setup the specified timer to generate an interrupt at the specified rate
+ * (expressed in Hertz) 
+ */
+void microblaze_timer_configure(unsigned timer, unsigned rate);
+
+#endif
diff -urN linux-2.4.29/include/asm-microblaze/mman.h linux-2.4.29-uc1/include/asm-microblaze/mman.h
--- linux-2.4.29/include/asm-microblaze/mman.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/mman.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,38 @@
+#ifndef __MICROBLAZE_MMAN_H__
+#define __MICROBLAZE_MMAN_H__
+
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_NONE	0x0		/* page can not be accessed */
+
+#define MAP_SHARED	0x01		/* Share changes */
+#define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_TYPE	0x0f		/* Mask for type of mapping */
+#define MAP_FIXED	0x10		/* Interpret addr exactly */
+#define MAP_ANONYMOUS	0x20		/* don't use a file */
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
+#define MAP_LOCKED	0x2000		/* pages are locked */
+#define MAP_NORESERVE	0x4000		/* don't check for reservations */
+
+#define MS_ASYNC	1		/* sync memory asynchronously */
+#define MS_INVALIDATE	2		/* invalidate the caches */
+#define MS_SYNC		4		/* synchronous memory sync */
+
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
+
+#define MADV_NORMAL	0x0		/* default page-in behavior */
+#define MADV_RANDOM	0x1		/* page-in minimum required */
+#define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
+#define MADV_WILLNEED	0x3		/* pre-fault pages */
+#define MADV_DONTNEED	0x4		/* discard these pages */
+
+/* compatibility flags */
+#define MAP_ANON	MAP_ANONYMOUS
+#define MAP_FILE	0
+
+#endif /* __MICROBLAZE_MMAN_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/mmu_context.h linux-2.4.29-uc1/include/asm-microblaze/mmu_context.h
--- linux-2.4.29/include/asm-microblaze/mmu_context.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/mmu_context.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,10 @@
+#ifndef __MICROBLAZE_MMU_CONTEXT_H__
+#define __MICROBLAZE_MMU_CONTEXT_H__
+
+#define destroy_context(mm)		((void)0)
+#define init_new_context(tsk,mm)	0
+#define switch_mm(prev,next,tsk,cpu)	((void)0)
+#define activate_mm(prev,next)		((void)0)
+#define enter_lazy_tlb(mm,tsk,cpu)	((void)0)
+
+#endif /* __MICROBLAZE_MMU_CONTEXT_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/mmu.h linux-2.4.29-uc1/include/asm-microblaze/mmu.h
--- linux-2.4.29/include/asm-microblaze/mmu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/mmu.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,9 @@
+#ifndef __MICROBLAZE_MMU_H__
+#define __MICROBLAZE_MMU_H__
+
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_t;
+
+typedef unsigned long phys_addr_t;
+
+#endif /* __MICROBLAZE_MMU_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/module.h linux-2.4.29-uc1/include/asm-microblaze/module.h
--- linux-2.4.29/include/asm-microblaze/module.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/module.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+ * include/asm-microblaze/module.h -- Architecture-specific module hooks
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_MODULE_H__
+#define __MICROBLAZE_MODULE_H__
+
+#define arch_init_modules(x)	((void)0)
+#define module_arch_init(x)	(0)
+#define module_map(sz)		vmalloc (sz)
+#define module_unmap(sz)	vfree (sz)
+
+#endif /* __MICROBLAZE_MODULE_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/msgbuf.h linux-2.4.29-uc1/include/asm-microblaze/msgbuf.h
--- linux-2.4.29/include/asm-microblaze/msgbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/msgbuf.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef __MICROBLAZE_MSGBUF_H__
+#define __MICROBLAZE_MSGBUF_H__
+
+/* 
+ * The msqid64_ds structure for microblaze architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm msg_perm;
+	__kernel_time_t msg_stime;	/* last msgsnd time */
+	unsigned long	__unused1;
+	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	unsigned long	__unused2;
+	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned long	__unused3;
+	unsigned long  msg_cbytes;	/* current number of bytes on queue */
+	unsigned long  msg_qnum;	/* number of messages in queue */
+	unsigned long  msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t msg_lrpid;	/* last receive pid */
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+#endif /* __MICROBLAZE_MSGBUF_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/namei.h linux-2.4.29-uc1/include/asm-microblaze/namei.h
--- linux-2.4.29/include/asm-microblaze/namei.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/namei.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-microblaze/namei.h
+ *
+ * Included from linux/fs/namei.c
+ */
+
+#ifndef __MICROBLAZE_NAMEI_H__
+#define __MICROBLAZE_NAMEI_H__
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+
+#define __emul_prefix() NULL
+
+#endif /* __MICROBLAZE_NAMEI_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/page.h linux-2.4.29-uc1/include/asm-microblaze/page.h
--- linux-2.4.29/include/asm-microblaze/page.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/page.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,143 @@
+/*
+ * include/asm-microblaze/page.h -- VM ops
+ *
+ *  Copyright (C) 2003        John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001, 2002  NEC Corporation
+ *  Copyright (C) 2001, 2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_PAGE_H__
+#define __MICROBLAZE_PAGE_H__
+
+#include <asm/machdep.h>
+
+
+#define PAGE_SHIFT	12
+#define PAGE_SIZE       (1UL << PAGE_SHIFT)
+#define PAGE_MASK       (~(PAGE_SIZE-1))
+
+/*
+ * PAGE_OFFSET -- the first address of the first page of memory. For archs with
+ * no MMU this corresponds to the first free page in physical memory (aligned
+ * on a page boundary).
+ */
+#ifndef PAGE_OFFSET
+#define PAGE_OFFSET  CONFIG_XILINX_ERAM_START
+#endif
+
+/*
+ * MAP_NR -- given an address, calculate the index of the page struct which
+ * points to the address's page.
+ */
+#define MAP_NR(addr) (((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT)
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#define STRICT_MM_TYPECHECKS
+
+#define clear_page(page)		memset ((void *)(page), 0, PAGE_SIZE)
+extern void copy_page(void *to, void *from);
+
+#define clear_user_page(page, vaddr)	clear_page (page)
+#define copy_user_page(to, from, vaddr)	copy_page (to, from)
+
+#ifdef STRICT_MM_TYPECHECKS
+/*
+ * These are used to make use of C type-checking..
+ */
+
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pmd; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)      ((x).pte)
+#define pmd_val(x)      ((x).pmd)
+#define pgd_val(x)      ((x).pgd)
+#define pgprot_val(x)   ((x).pgprot)
+
+#define __pte(x)        ((pte_t) { (x) } )
+#define __pmd(x)        ((pmd_t) { (x) } )
+#define __pgd(x)        ((pgd_t) { (x) } )
+#define __pgprot(x)     ((pgprot_t) { (x) } )
+
+#else /* !STRICT_MM_TYPECHECKS */
+/*
+ * .. while these make it easier on the compiler
+ */
+
+typedef unsigned long pte_t;
+typedef unsigned long pmd_t;
+typedef unsigned long pgd_t;
+typedef unsigned long pgprot_t;
+
+#define pte_val(x)      (x)
+#define pmd_val(x)      (x)
+#define pgd_val(x)      (x)
+#define pgprot_val(x)   (x)
+
+#define __pte(x)        (x)
+#define __pmd(x)        (x)
+#define __pgd(x)        (x)
+#define __pgprot(x)     (x)
+
+#endif /* STRICT_MM_TYPECHECKS */
+
+#endif /* !__ASSEMBLY__ */
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr) + PAGE_SIZE - 1) & PAGE_MASK)
+
+#ifndef __ASSEMBLY__
+
+extern void __bug(const char *file, int line, void *data);
+
+#define BUG()		__bug(__FILE__, __LINE__, NULL)
+#define PAGE_BUG(page)	__bug(__FILE__, __LINE__, page)
+
+/* Pure 2^n version of get_order */
+extern __inline__ int get_order (unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#define __pa(x)			__virt_to_phys ((unsigned long)(x))
+#define __va(x)			((void *)__phys_to_virt ((unsigned long)(x)))
+#ifndef CONFIG_DISCONTIGMEM
+#define pfn_to_page(pfn)        (mem_map + (pfn))
+#define page_to_pfn(page)       ((unsigned long)((page) - mem_map))
+#define pfn_valid(pfn)          ((pfn) < max_mapnr)
+#endif
+
+/* No current microblaze processor has virtual memory.  */
+#define __virt_to_phys(addr)	(addr)
+#define __phys_to_virt(addr)	(addr)
+
+#define virt_to_page(kaddr) 	(mem_map +  MAP_NR (kaddr))
+#define VALID_PAGE(page) 	((page - mem_map) < max_mapnr)
+
+#endif /* KERNEL */
+
+#ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
+#define WANT_PAGE_VIRTUAL 1 /* page alloc 2 relies on this */
+#endif
+
+#endif /* __MICROBLAZE_PAGE_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/param.h linux-2.4.29-uc1/include/asm-microblaze/param.h
--- linux-2.4.29/include/asm-microblaze/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/param.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,37 @@
+/*
+ * include/asm-microblaze/param.h -- Varions kernel parameters
+ *
+ *  Copyright (C) 2003  John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_PARAM_H__
+#define __MICROBLAZE_PARAM_H__
+
+#include <asm/machdep.h>	/* For HZ */
+
+#define EXEC_PAGESIZE	4096
+
+#ifndef NGROUPS
+#define NGROUPS		32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#ifdef __KERNEL__
+# define CLOCKS_PER_SEC	HZ
+#endif
+
+#endif /* __MICROBLAZE_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/pci.h linux-2.4.29-uc1/include/asm-microblaze/pci.h
--- linux-2.4.29/include/asm-microblaze/pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/pci.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,292 @@
+#ifndef __MICROBLAZE_PCI_H
+#define __MICROBLAZE_PCI_H
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <asm/scatterlist.h>
+#include <asm/io.h>
+#include <asm/virtconvert.h>
+
+struct pci_dev;
+
+/* Values for the `which' argument to sys_pciconfig_iobase syscall.  */
+#define IOBASE_BRIDGE_NUMBER	0
+#define IOBASE_MEMORY		1
+#define IOBASE_IO		2
+#define IOBASE_ISA_IO		3
+#define IOBASE_ISA_MEM		4
+
+/*
+ * Set this to 1 if you want the kernel to re-assign all PCI
+ * bus numbers
+ */
+extern int pci_assign_all_busses;
+
+#define pcibios_assign_all_busses()	(pci_assign_all_busses)
+#define pcibios_scan_all_fns()		0
+
+#define PCIBIOS_MIN_IO		0x1000
+#define PCIBIOS_MIN_MEM		0x10000000
+
+extern inline void pcibios_set_master(struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling */
+}
+
+extern inline void pcibios_penalize_isa_irq(int irq)
+{
+	/* We don't do dynamic PCI IRQ allocation */
+}
+
+extern unsigned long pci_resource_to_bus(struct pci_dev *pdev, struct resource *res);
+
+/*
+ * The PCI bus bridge can translate addresses issued by the processor(s)
+ * into a different address on the PCI bus.  On 32-bit cpus, we assume
+ * this mapping is 1-1, but on 64-bit systems it often isn't.
+ *
+ * Obsolete ! Drivers should now use pci_resource_to_bus
+ */
+extern unsigned long phys_to_bus(unsigned long pa);
+extern unsigned long pci_phys_to_bus(unsigned long pa, int busnr);
+extern unsigned long pci_bus_to_phys(unsigned int ba, int busnr);
+
+/*
+ * Dynamic DMA Mapping stuff
+ * Originally stolen from i386 by ajoshi and updated by paulus
+ * Non-consistent cache support by Dan Malek
+ */
+
+/* The PCI address space does equal the physical memory
+ * address space.  The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS	(1)
+
+/* Allocate and map kernel buffer using consistent mode DMA for a device.
+ * hwdev should be valid struct pci_dev pointer for PCI devices,
+ * NULL for PCI-like buses (ISA, EISA).
+ * Returns non-NULL cpu-view pointer to the buffer if successful and
+ * sets *dma_addrp to the pci side dma address as well, else *dma_addrp
+ * is undefined.
+ */
+extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+				  dma_addr_t *dma_handle);
+
+/* Free and unmap a consistent DMA buffer.
+ * cpu_addr is what was returned from pci_alloc_consistent,
+ * size must be the same as what as passed into pci_alloc_consistent,
+ * and likewise dma_addr must be the same as what *dma_addrp was set to.
+ *
+ * References to the memory and mappings associated with cpu_addr/dma_addr
+ * past this call are illegal.
+ */
+extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+				void *vaddr, dma_addr_t dma_handle);
+
+/* Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Once the device is given the dma address, the device owns this memory
+ * until either pci_unmap_single or pci_dma_sync_single is performed.
+ */
+static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+					size_t size, int direction)
+{
+	BUG_ON(direction == PCI_DMA_NONE);
+	consistent_sync(ptr, size, direction);
+	return virt_to_bus(ptr);
+}
+
+static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+				    size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+	/* nothing to do */
+}
+
+/* pci_unmap_{page,single} is a nop so... */
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+#define pci_unmap_addr(PTR, ADDR_NAME)		(0)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)	do { } while (0)
+#define pci_unmap_len(PTR, LEN_NAME)		(0)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)	do { } while (0)
+
+
+/*
+ * pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical
+ * to pci_map_single, but takes a struct page instead of a virtual address
+ */
+static inline dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
+				      unsigned long offset, size_t size,
+				      int direction)
+{
+	BUG_ON(direction == PCI_DMA_NONE);
+	consistent_sync_page(page, offset, size, direction);
+	return (page - mem_map) * PAGE_SIZE + offset;
+}
+
+static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
+				  size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+		BUG();
+	/* Nothing to do */
+}
+
+/* Map a set of buffers described by scatterlist in streaming
+ * mode for DMA.  This is the scather-gather version of the
+ * above pci_map_single interface.  Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length.  They are obtained via sg_dma_{address,len}(SG),
+ * defined in <asm/scatterlist.h>.
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ *       DMA address/length pairs than there are SG table elements.
+ *       (for example via virtual mapping capabilities)
+ *       The routine returns the number of addr/length pairs actually
+ *       used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+			     int nents, int direction)
+{
+	int i;
+
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/*
+	 * temporary 2.4 hack
+	 */
+	for (i = 0; i < nents; i++) {
+		if (sg[i].address && sg[i].page)
+			BUG();
+		else if (!sg[i].address && !sg[i].page)
+			BUG();
+
+		if (sg[i].address) {
+			consistent_sync(sg[i].address, sg[i].length, direction);
+			sg[i].dma_address = virt_to_bus(sg[i].address);
+		} else {
+			consistent_sync_page(sg[i].page, sg[i].offset,
+					     sg[i].length, direction);
+			sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset;
+		}
+		sg[i].dma_length = sg[i].length;
+	}
+
+	return nents;
+}
+
+/* Unmap a set of streaming mode DMA translations.
+ * Again, cpu read rules concerning calls here are the same as for
+ * pci_unmap_single() above.
+ */
+static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+				int nents, int direction)
+{
+	BUG_ON(direction == PCI_DMA_NONE);
+	/* nothing to do */
+}
+
+/* Make physical memory consistent for a single
+ * streaming mode DMA translation after a transfer.
+ *
+ * If you perform a pci_map_single() but wish to interrogate the
+ * buffer using the cpu, yet do not wish to teardown the PCI dma
+ * mapping, you must call this function before doing so.  At the
+ * next point you give the PCI dma address back to the card, the
+ * device again owns the buffer.
+ */
+static inline void pci_dma_sync_single(struct pci_dev *hwdev,
+				       dma_addr_t dma_handle,
+				       size_t size, int direction)
+{
+	BUG_ON(direction == PCI_DMA_NONE);
+
+	consistent_sync(bus_to_virt(dma_handle), size, direction);
+}
+
+/* Make physical memory consistent for a set of streaming
+ * mode DMA translations after a transfer.
+ *
+ * The same as pci_dma_sync_single but for a scatter-gather list,
+ * same rules and usage.
+ */
+static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
+				   struct scatterlist *sg,
+				   int nelems, int direction)
+{
+	int i;
+
+	BUG_ON(direction == PCI_DMA_NONE);
+
+	for (i = 0; i < nelems; i++, sg++) {
+		if (sg->address)
+			consistent_sync(sg->address, sg->length, direction);
+		else
+			consistent_sync_page(sg->page, sg->offset,
+					sg->length, direction);
+	}
+}
+
+/* Return whether the given PCI device DMA address mask can
+ * be supported properly.  For example, if your device can
+ * only drive the low 24-bits during PCI bus mastering, then
+ * you would pass 0x00ffffff as the mask to this function.
+ */
+static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
+{
+	return 1;
+}
+
+/*
+ * At present there are very few 32-bit MICROBLAZE machines that can have
+ * memory above the 4GB point, and we don't support that.
+ */
+#define pci_dac_dma_supported(pci_dev, mask)	(0)
+
+static __inline__ dma_addr_t
+pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
+{
+	return (dma_addr_t) page_to_bus(page) + offset;
+}
+
+static __inline__ struct page *
+pci_dac_dma_to_page(struct pci_dev *pdev, dma_addr_t dma_addr)
+{
+	return mem_map + (unsigned long)(dma_addr >> PAGE_SHIFT);
+}
+
+static __inline__ unsigned long
+pci_dac_dma_to_offset(struct pci_dev *pdev, dma_addr_t dma_addr)
+{
+	return (dma_addr & ~PAGE_MASK);
+}
+
+static __inline__ void
+pci_dac_dma_sync_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t len, int direction)
+{
+	/* Nothing to do. */
+}
+
+/* Return the index of the PCI controller for device PDEV. */
+extern int pci_controller_num(struct pci_dev *pdev);
+
+/* Map a range of PCI memory or I/O space for a device into user space */
+int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state, int write_combine);
+
+/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
+#define HAVE_PCI_MMAP	1
+
+#endif	/* __KERNEL__ */
+
+#endif /* __MICROBLAZE_PCI_H */
diff -urN linux-2.4.29/include/asm-microblaze/pgalloc.h linux-2.4.29-uc1/include/asm-microblaze/pgalloc.h
--- linux-2.4.29/include/asm-microblaze/pgalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/pgalloc.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,177 @@
+#ifndef _MICROBLAZE_PGALLOC_H
+#define _MICROBLAZE_PGALLOC_H
+
+/*
+ * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
+ * Copyright (C) 2000 Lineo, David McCullough <davidm@lineo.com>
+ * Copyright (C) 2001 Lineo, Greg Ungerer <gerg@snapgear.com>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>	/* For min/max macros */
+#include <asm/setup.h>
+#include <asm/virtconvert.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+
+/*
+ * Cache handling functions.
+ * Microblaze has a write-through data cache, meaning that the data cache
+ * never needs to be flushed.  The only flushing operations that are
+ * implemented are to invalidate the instruction cache.  These are called
+ * after loading a user application into memory, we must invalidate the
+ * instruction cache to make sure we don't fetch old, bad code.
+ */
+
+extern inline void __flush_dcache_all(void)
+{
+#if CONFIG_XILINX_MICROBLAZE0_USE_DCACHE==1
+	unsigned int i;
+	unsigned flags;
+
+	save_flags_cli(flags);
+	__disable_dcache();
+
+	for(i=0;i<CONFIG_XILINX_MICROBLAZE0_DCACHE_BYTE_SIZE;i+=DCACHE_LINE_SIZE)
+		__invalidate_dcache(i);
+
+	__enable_dcache();
+	restore_flags(flags);
+#else
+	do { } while(0);
+#endif /* CONFIG_XILINX_MICROBLAZE0_USE_DCACHE */
+}
+
+extern inline void __flush_dcache_range(unsigned int start, unsigned int end)
+{
+#if CONFIG_XILINX_MICROBLAZE0_USE_DCACHE==1
+	unsigned int i;
+	unsigned flags;
+
+	/* No need to cover entire cache range, just cover cache footprint */
+	end=min(start+CONFIG_XILINX_MICROBLAZE0_DCACHE_BYTE_SIZE, end);
+
+	save_flags_cli(flags);
+	__disable_dcache();
+
+	for(i=start;i<end;i+=DCACHE_LINE_SIZE)
+		__invalidate_dcache(i);
+
+	__enable_dcache();
+	restore_flags(flags);
+#else
+	do { } while(0);
+#endif /* CONFIG_XILINX_MICROBLAZE0_USE_DCACHE */
+}
+
+extern inline void __flush_icache_all(void)
+{
+#if CONFIG_XILINX_MICROBLAZE0_USE_ICACHE==1
+	unsigned int i;
+	unsigned flags;
+
+	save_flags_cli(flags);
+	__disable_icache();
+
+	/* Just loop through cache size and invalidate, no need to add
+	   CACHE_BASE address */
+	for(i=0;i<CONFIG_XILINX_MICROBLAZE0_CACHE_BYTE_SIZE;i+=ICACHE_LINE_SIZE)
+		__invalidate_icache(i);
+
+	__enable_icache();
+	restore_flags(flags);
+#else
+	do { } while(0);
+#endif /* CONFIG_XILINX_MICROBLAZE0_USE_ICACHE */
+}
+
+extern inline void __flush_icache_range(unsigned int start, unsigned int end)
+{
+#if CONFIG_XILINX_MICROBLAZE0_USE_ICACHE==1
+	unsigned int i;
+	unsigned flags;
+
+	/* No need to cover entire cache range, just cover cache footprint */
+	end=min(start+CONFIG_XILINX_MICROBLAZE0_CACHE_BYTE_SIZE, end);
+
+	save_flags_cli(flags);
+	__disable_icache();
+
+	for(i=start;i<end;i+=ICACHE_LINE_SIZE)
+		__invalidate_icache(i);
+
+	__enable_icache();
+	restore_flags(flags);
+#else
+	do { } while(0);
+#endif /* CONFIG_XILINX_MICROBLAZE0_USE_ICACHE */
+}
+
+#define flush_cache_all()			__flush_icache_all()
+#define flush_cache_mm(mm)			do { } while(0)
+#define flush_cache_range(mm, start, end)	do { } while(0)
+#define flush_cache_page(vma, vmaddr)		do { } while(0)
+#define flush_page_to_ram(page)			do { } while(0)
+#define flush_dcache_page(page)			do { } while(0)
+#define flush_dcache_range(start, end)		__flush_dcache_range(start,end)
+#define flush_icache_range(start, end)		__flush_icache_range(start,end)
+#define flush_icache_user_range(vma,pg,adr,len) __flush_icache_all()
+#define flush_icache_page(vma,pg)		__flush_icache_all()
+#define flush_icache()				__flush_icache_all()
+#define flush_cache_sigtramp(vaddr)		__flush_icache_range(vaddr,vaddr+8)
+
+/*
+ * DAVIDM - the rest of these are just so I can check where they happen
+ */
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+	BUG();
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+	BUG();
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+	BUG();
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+	BUG();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+	BUG();
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+				   unsigned long start, unsigned long end)
+{
+	BUG();
+}
+
+extern inline void flush_tlb_kernel_page(unsigned long addr)
+{
+	BUG();
+}
+
+extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+				      unsigned long start, unsigned long end)
+{
+	BUG();
+}
+
+#endif /* _MICROBLAZE_PGALLOC_H */
diff -urN linux-2.4.29/include/asm-microblaze/pgtable.h linux-2.4.29-uc1/include/asm-microblaze/pgtable.h
--- linux-2.4.29/include/asm-microblaze/pgtable.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/pgtable.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,20 @@
+#ifndef __MICROBLAZE_PGTABLE_H__
+#define __MICROBLAZE_PGTABLE_H__
+
+#include <linux/config.h>
+#include <asm/setup.h>
+
+#define pgd_present(pgd)     (1)       /* pages are always present on NO_MM */
+#define kern_addr_valid(addr) (1)
+
+#define PAGE_NONE		__pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_SHARED		__pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_COPY		__pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_READONLY		__pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_KERNEL		__pgprot(0) /* these mean nothing to NO_MM */
+
+extern void paging_init(struct meminfo *);
+
+#define pgtable_cache_init()   ((void)0)
+
+#endif /* __MICROBLAZE_PGTABLE_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/poll.h linux-2.4.29-uc1/include/asm-microblaze/poll.h
--- linux-2.4.29/include/asm-microblaze/poll.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/poll.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,22 @@
+#ifndef __MICROBLAZE_POLL_H__
+#define __MICROBLAZE_POLL_H__
+
+#define POLLIN		0x0001
+#define POLLPRI		0x0002
+#define POLLOUT		0x0004
+#define POLLERR		0x0008
+#define POLLHUP		0x0010
+#define POLLNVAL	0x0020
+#define POLLRDNORM	0x0040
+#define POLLWRNORM	POLLOUT
+#define POLLRDBAND	0x0080
+#define POLLWRBAND	0x0100
+#define POLLMSG		0x0400
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+#endif /* __MICROBLAZE_POLL_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/posix_types.h linux-2.4.29-uc1/include/asm-microblaze/posix_types.h
--- linux-2.4.29/include/asm-microblaze/posix_types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/posix_types.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,76 @@
+/*
+ * include/asm-microblaze/posix_types.h -- Kernel versions of standard types
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_POSIX_TYPES_H__
+#define __MICROBLAZE_POSIX_TYPES_H__
+
+#include <asm/bitops.h>
+
+
+typedef unsigned int	__kernel_dev_t;
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned long long __kernel_ino64_t;
+typedef unsigned int	__kernel_mode_t;
+typedef unsigned int	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef long long	__kernel_loff_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
+typedef unsigned int	__kernel_uid_t;
+typedef unsigned int	__kernel_gid_t;
+typedef unsigned int	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+typedef unsigned short	__kernel_old_uid_t;
+typedef unsigned short	__kernel_old_gid_t;
+
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+	int	val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+	int	__val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#undef	__FD_SET
+#define __FD_SET(fd, fd_set) \
+  __set_bit (fd, (void *)&((__kernel_fd_set *)fd_set)->fds_bits)
+#undef __FD_CLR
+#define __FD_CLR(fd, fd_set) \
+  __clear_bit (fd, (void *)&((__kernel_fd_set *)fd_set)->fds_bits)
+#undef	__FD_ISSET
+#define __FD_ISSET(fd, fd_set) \
+  __test_bit (fd, (void *)&((__kernel_fd_set *)fd_set)->fds_bits)
+#undef	__FD_ZERO
+#define __FD_ZERO(fd_set) \
+  memset (fd_set, 0, sizeof (*(fd_set *)fd_set))
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif /* __MICROBLAZE_POSIX_TYPES_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/processor.h linux-2.4.29-uc1/include/asm-microblaze/processor.h
--- linux-2.4.29/include/asm-microblaze/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/processor.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,130 @@
+/*
+ * include/asm-microblaze/processor.h
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_PROCESSOR_H__
+#define __MICROBLAZE_PROCESSOR_H__
+
+#include <linux/config.h>
+
+#include <asm/ptrace.h>
+#include <asm/current.h>
+#include <asm/entry.h>
+
+/* Some code expects `segment' stuff to be defined here.  */
+#include <asm/segment.h>
+
+/*
+ * The only places this is used seem to be horrible bletcherous kludges,
+ * so we just define it to be as large as possible.
+ */
+#define TASK_SIZE	(0xFFFFFFFF)
+
+
+#define THREAD_SIZE	(2*PAGE_SIZE)
+
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr()	({ __label__ _l; _l: &&_l;})
+
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+#define MCA_bus 0
+#define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+/* If you change this, you must change the associated assembly-languages
+   constants defined below, THREAD_*.  */
+struct thread_struct {
+	/* kernel stack pointer (must be first field in structure) */
+	unsigned long  ksp;
+};
+
+#define INIT_THREAD { sizeof init_stack + (unsigned long)init_stack }
+
+
+/* Do necessary setup to start up a newly executed thread.  */
+extern inline void start_thread (struct pt_regs *regs,
+				 unsigned long pc, unsigned long usp)
+{
+	/* Need the -8 shift get around the offset returns */
+	regs->pc = pc-8;
+	regs->gpr[GPR_SP] = usp;
+	regs->kernel_mode = 0;
+}
+
+/* Free all resources held by a thread. */
+extern inline void release_thread (struct task_struct *dead_task)
+{
+}
+
+extern int arch_kernel_thread (int (*fn)(void *), void * arg, unsigned long flags);
+
+/* Free current thread data structures etc.  */
+static inline void exit_thread (void)
+{
+}
+
+/* Return saved (kernel) PC of a blocked thread.  */
+extern inline unsigned long thread_saved_pc (struct thread_struct *t)
+{
+	struct pt_regs *r = (struct pt_regs *)(t->ksp + STATE_SAVE_PT_OFFSET);
+	/* Actually, we return the LP register, because the thread is
+	   actually blocked in switch_thread, and we're interested in
+	   the PC it will _return_ to.  */
+	return r->gpr[GPR_LP];
+}
+
+unsigned long get_wchan (struct task_struct *p);
+
+
+/* Return some info about the user process TASK.  */
+#define task_tos(task)	((unsigned long)(task) + KERNEL_STACK_SIZE)
+#define task_regs(task) ((struct pt_regs *)task_tos (task) - 1)
+#define task_sp(task)	(task_regs (task)->gpr[GPR_SP])
+#define task_pc(task)	(task_regs (task)->pc)
+/* Grotty old names for some.  */
+#define KSTK_EIP(task)	task_pc (task)
+#define KSTK_ESP(task)	task_sp (task)
+
+#define cpu_relax() barrier()
+
+/* Allocation and freeing of basic task resources. */
+#define alloc_task_struct() \
+   ((struct task_struct *)__get_free_pages(GFP_KERNEL,1))
+#define free_task_struct(p)	free_pages ((unsigned long)(p),1)
+#define get_task_struct(tsk)	atomic_inc (&mem_map[MAP_NR(tsk)].count)
+
+#define init_task	(init_task_union.task)
+#define init_stack	(init_task_union.stack)
+
+
+#else /* !__ASSEMBLY__ */
+
+
+#define THREAD_KSP	0
+
+
+#endif /* __ASSEMBLY__ */
+
+
+#endif /* __MICROBLAZE_PROCESSOR_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/ptrace.h linux-2.4.29-uc1/include/asm-microblaze/ptrace.h
--- linux-2.4.29/include/asm-microblaze/ptrace.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/ptrace.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,120 @@
+/*
+ * include/asm-microblaze/ptrace.h -- Access to CPU registers
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_PTRACE_H__
+#define __MICROBLAZE_PTRACE_H__
+
+
+/* Microblaze general purpose registers with special meanings.  */
+#define GPR_ZERO	0	/* constant zero */
+#define GPR_ASM		18	/* reserved for assembler */
+#define GPR_SP		1	/* stack pointer */
+#define GPR_GP		2	/* global data pointer */
+#define GPR_EP		30	/* `element pointer' */
+#define GPR_LP		15	/* link pointer (current return address) */
+
+/* These aren't official names, but they make some code more descriptive.  */
+#define GPR_ARG0	5
+#define GPR_ARG1	6
+#define GPR_ARG2	7
+#define GPR_ARG3	8
+#define GPR_ARG4	9
+#define GPR_ARG5	10
+#define GPR_RVAL0	3	
+#define GPR_RVAL1	4
+#define GPR_RVAL	GPR_RVAL0
+
+#define NUM_GPRS	32
+
+/* `system' registers.  */
+/* Note these are old v850 values, microblaze has many fewer */
+#define SR_EIPC		0
+#define SR_EIPSW	1
+#define SR_FEPC		2
+#define SR_FEPSW	3
+#define SR_ECR		4
+#define SR_PSW		5
+#define SR_CTPC		16
+#define SR_CTPSW	17
+#define SR_DBPC		18
+#define SR_DBPSW	19
+#define SR_CTBP		20
+#define SR_DIR		21
+#define SR_ASID		23
+
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long microblaze_reg_t;
+
+/* How processor state is stored on the stack during a syscall/signal.
+   If you change this structure, change the associated assembly-language
+   macros below too (PT_*)!  */
+struct pt_regs
+{
+	/* General purpose registers.  */
+	microblaze_reg_t gpr[NUM_GPRS];
+
+	microblaze_reg_t pc;		/* program counter */
+	microblaze_reg_t psw;		/* program status word */
+	microblaze_reg_t ear;		/* exception address register */
+	microblaze_reg_t esr;		/* exception status register */
+
+	microblaze_reg_t kernel_mode;	/* 1 if `kernel mode', 0 if user mode */
+	microblaze_reg_t single_step;	/* 1 if in single step mode */
+};
+
+
+#define instruction_pointer(regs)	((regs)->pc)
+#define user_mode(regs)			(!(regs)->kernel_mode)
+
+/* When a struct pt_regs is used to save user state for a system call in
+   the kernel, the system call is stored in the space for R0 (since it's
+   never used otherwise, R0 being a constant 0).  Non-system-calls
+   simply store 0 there.  */
+#define PT_REGS_SYSCALL(regs)		(regs)->gpr[0]
+#define PT_REGS_SET_SYSCALL(regs, val)	((regs)->gpr[0] = (val))
+
+#endif /* !__ASSEMBLY__ */
+
+
+/* The number of bytes used to store each register.  */
+#define _PT_REG_SIZE	4
+
+/* Offset of a general purpose register in a stuct pt_regs.  */
+#define PT_GPR(num)	((num) * _PT_REG_SIZE)
+
+/* Offsets of various special registers & fields in a struct pt_regs.  */
+#define NUM_SPECIAL	6
+#define PT_PC		((NUM_GPRS + 0) * _PT_REG_SIZE)
+#define PT_PSW		((NUM_GPRS + 1) * _PT_REG_SIZE)
+#define PT_EAR		((NUM_GPRS + 2) * _PT_REG_SIZE)
+#define PT_ESR		((NUM_GPRS + 3) * _PT_REG_SIZE)
+#define PT_KERNEL_MODE	((NUM_GPRS + 4) * _PT_REG_SIZE)
+#define PT_SINGLESTEP	((NUM_GPRS + 5) * _PT_REG_SIZE)
+
+#define PT_SYSCALL	PT_GPR(0)
+
+/* Size of struct pt_regs, including alignment.  */
+#define PT_SIZE		((NUM_GPRS + NUM_SPECIAL) * _PT_REG_SIZE)
+
+/* These are `magic' values for PTRACE_PEEKUSR that return info about where
+   a process is located in memory.  */
+#define PT_TEXT_ADDR    (PT_SIZE + 1)
+#define PT_TEXT_LEN     (PT_SIZE + 2)
+#define PT_DATA_ADDR    (PT_SIZE + 3)
+#define PT_DATA_LEN     (PT_SIZE + 4)
+
+#endif /* __MICROBLAZE_PTRACE_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/resource.h linux-2.4.29-uc1/include/asm-microblaze/resource.h
--- linux-2.4.29/include/asm-microblaze/resource.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/resource.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,47 @@
+#ifndef __MICROBLAZE_RESOURCE_H__
+#define __MICROBLAZE_RESOURCE_H__
+
+/*
+ * Resource limits
+ */
+
+#define RLIMIT_CPU	0		/* CPU time in ms */
+#define RLIMIT_FSIZE	1		/* Maximum filesize */
+#define RLIMIT_DATA	2		/* max data size */
+#define RLIMIT_STACK	3		/* max stack size */
+#define RLIMIT_CORE	4		/* max core file size */
+#define RLIMIT_RSS	5		/* max resident set size */
+#define RLIMIT_NPROC	6		/* max number of processes */
+#define RLIMIT_NOFILE	7		/* max number of open files */
+#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
+#define RLIMIT_AS	9		/* address space limit */
+#define RLIMIT_LOCKS	10		/* maximum file locks held */
+
+#define RLIM_NLIMITS	11
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway.
+ */
+#define RLIM_INFINITY	(~0UL)
+
+#ifdef __KERNEL__
+
+#define INIT_RLIMITS					\
+{							\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{      _STK_LIM, RLIM_INFINITY },		\
+	{             0, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{             0,             0 },		\
+	{      INR_OPEN,     INR_OPEN  },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+        { RLIM_INFINITY, RLIM_INFINITY },		\
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* __MICROBLAZE_RESOURCE_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/scatterlist.h linux-2.4.29-uc1/include/asm-microblaze/scatterlist.h
--- linux-2.4.29/include/asm-microblaze/scatterlist.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/scatterlist.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,35 @@
+#ifdef __KERNEL__
+#ifndef _MICROBLAZE_SCATTERLIST_H
+#define _MICROBLAZE_SCATTERLIST_H
+
+/* Scatter-gather DMA support.  Stolen from PPC tree */
+
+#include <asm/dma.h>
+
+struct scatterlist {
+	char *address;		/* Location data is to be transferred to,
+				 * or NULL for highmem page */
+	struct page * page;	/* Location for highmem page, if any */
+	unsigned int offset;	/* for highmem, page offset */
+	unsigned int length;	/* length at address or page+offset */
+
+	dma_addr_t dma_address;	/* phys/bus dma address	*/
+	unsigned int dma_length; /* number of bytes mapped at dma_address */
+	/* Note that if we coalesce multiple scatterlist elements,
+	   dma_length can be different from length */
+};
+
+/*
+ * These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
+#define sg_dma_address(sg)      ((sg)->dma_address)
+#define sg_dma_len(sg)          ((sg)->dma_length)
+
+#define ISA_DMA_THRESHOLD	(~0UL)
+
+#endif /* !(_MICROBLAZE_SCATTERLIST_H) */
+#endif /* __KERNEL__ */
diff -urN linux-2.4.29/include/asm-microblaze/segment.h linux-2.4.29-uc1/include/asm-microblaze/segment.h
--- linux-2.4.29/include/asm-microblaze/segment.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/segment.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,36 @@
+#ifndef __MICROBLAZE_SEGMENT_H__
+#define __MICROBLAZE_SEGMENT_H__
+
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long mm_segment_t;	/* domain register */
+
+#endif /* !__ASSEMBLY__ */
+
+
+#define __KERNEL_CS	0x0
+#define __KERNEL_DS	0x0
+
+#define __USER_CS	0x1
+#define __USER_DS	0x1
+
+#define KERNEL_DS	__KERNEL_DS
+#define KERNEL_CS	__KERNEL_CS
+#define USER_DS		__USER_DS
+#define USER_CS		__USER_CS
+
+#define segment_eq(a,b)	((a) == (b))
+
+#define get_ds()	(KERNEL_DS)
+#define get_fs()	(USER_DS)
+
+#define set_fs(seg)	((void)(seg))
+
+
+#define copy_segments(task, mm)	((void)((void)(task), (mm)))
+#define release_segments(mm)	((void)(mm))
+#define forget_segments()	((void)0)
+
+
+#endif /* __MICROBLAZE_SEGMENT_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/semaphore.h linux-2.4.29-uc1/include/asm-microblaze/semaphore.h
--- linux-2.4.29/include/asm-microblaze/semaphore.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/semaphore.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,91 @@
+#ifndef __MICROBLAZE_SEMAPHORE_H__
+#define __MICROBLAZE_SEMAPHORE_H__
+
+#include <linux/linkage.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/rwsem.h>
+
+#include <asm/atomic.h>
+
+struct semaphore {
+	atomic_t count;
+	int sleepers;
+	wait_queue_head_t wait;
+};
+
+#define __SEMAPHORE_INITIALIZER(name,count)				      \
+	{ ATOMIC_INIT (count), 0,					      \
+	  __WAIT_QUEUE_HEAD_INITIALIZER ((name).wait) }
+
+#define __MUTEX_INITIALIZER(name)					      \
+	__SEMAPHORE_INITIALIZER (name,1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count)	\
+	struct semaphore name = __SEMAPHORE_INITIALIZER (name,count)
+
+#define DECLARE_MUTEX(name)		__DECLARE_SEMAPHORE_GENERIC (name,1)
+#define DECLARE_MUTEX_LOCKED(name)	__DECLARE_SEMAPHORE_GENERIC (name,0)
+
+extern inline void sema_init (struct semaphore *sem, int val)
+{
+	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
+}
+
+static inline void init_MUTEX (struct semaphore *sem)
+{
+	sema_init (sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+{
+	sema_init (sem, 0);
+}
+
+/*
+ * special register calling convention
+ */
+asmlinkage void __down_failed (void);
+asmlinkage int  __down_interruptible_failed (void);
+asmlinkage int  __down_trylock_failed (void);
+asmlinkage void __up_wakeup (void);
+
+extern void __down (struct semaphore * sem);
+extern int  __down_interruptible (struct semaphore * sem);
+extern int  __down_trylock (struct semaphore * sem);
+extern void __up (struct semaphore * sem);
+
+extern inline void down (struct semaphore * sem)
+{
+	if (atomic_dec_return (&sem->count) < 0)
+		__down (sem);
+}
+
+extern inline int down_interruptible (struct semaphore * sem)
+{
+	int ret = 0;
+	if (atomic_dec_return (&sem->count) < 0)
+		ret = __down_interruptible (sem);
+	return ret;
+}
+
+extern inline int down_trylock (struct semaphore *sem)
+{
+	int ret = 0;
+	if (atomic_dec_return (&sem->count) < 0)
+		ret = __down_trylock (sem);
+	return ret;
+}
+
+extern inline void up (struct semaphore * sem)
+{
+	if (atomic_inc_return (&sem->count) <= 0)
+		__up (sem);
+}
+
+static inline int sem_getcount(struct semaphore *sem)
+{
+	return atomic_read(&sem->count);
+}
+
+#endif /* __MICROBLAZE_SEMAPHORE_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/sembuf.h linux-2.4.29-uc1/include/asm-microblaze/sembuf.h
--- linux-2.4.29/include/asm-microblaze/sembuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/sembuf.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef __MICROBLAZE_SEMBUF_H__
+#define __MICROBLAZE_SEMBUF_H__
+
+/* 
+ * The semid64_ds structure for microblaze architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
+	__kernel_time_t	sem_otime;		/* last semop time */
+	unsigned long	__unused1;
+	__kernel_time_t	sem_ctime;		/* last change time */
+	unsigned long	__unused2;
+	unsigned long	sem_nsems;		/* no. of semaphores in array */
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* __MICROBLAZE_SEMBUF_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/setup.h linux-2.4.29-uc1/include/asm-microblaze/setup.h
--- linux-2.4.29/include/asm-microblaze/setup.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/setup.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,37 @@
+/*
+ * include/asm-microblaze/setup.h
+ *
+ *  Copyright (C) 2003  John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_SETUP_H__
+#define __MICROBLAZE_SETUP_H__
+
+/*
+ * Memory map description
+ */
+#define NR_BANKS 8
+
+struct meminfo {
+	int nr_banks;
+	unsigned long end;
+	struct {
+		unsigned long start;
+		unsigned long size;
+		int           node;
+	} bank[NR_BANKS];
+};
+
+extern struct meminfo meminfo;
+
+
+#endif /* __MICROBLAZE_SETUP_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/shmbuf.h linux-2.4.29-uc1/include/asm-microblaze/shmbuf.h
--- linux-2.4.29/include/asm-microblaze/shmbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/shmbuf.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,42 @@
+#ifndef __MICROBLAZE_SHMBUF_H__
+#define __MICROBLAZE_SHMBUF_H__
+
+/* 
+ * The shmid64_ds structure for microblaze architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	unsigned long		__unused1;
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	unsigned long		__unused2;
+	__kernel_time_t		shm_ctime;	/* last change time */
+	unsigned long		__unused3;
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* __MICROBLAZE_SHMBUF_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/shmparam.h linux-2.4.29-uc1/include/asm-microblaze/shmparam.h
--- linux-2.4.29/include/asm-microblaze/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/shmparam.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __MICROBLAZE_SHMPARAM_H__
+#define __MICROBLAZE_SHMPARAM_H__
+
+#define	SHMLBA		PAGE_SIZE	/* attach addr a multiple of this */
+
+#endif /* __MICROBLAZE_SHMPARAM_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/sigcontext.h linux-2.4.29-uc1/include/asm-microblaze/sigcontext.h
--- linux-2.4.29/include/asm-microblaze/sigcontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/sigcontext.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,27 @@
+/*
+ * include/asm-microblaze/sigcontext.h -- Signal contexts
+ *
+ *  Copyright (C) 2003  John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_SIGCONTEXT_H__
+#define __MICROBLAZE_SIGCONTEXT_H__
+
+#include <asm/ptrace.h>
+
+struct sigcontext
+{
+	struct pt_regs 	regs;
+	unsigned long	oldmask;
+};
+
+#endif /* __MICROBLAZE_SIGCONTEXT_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/siginfo.h linux-2.4.29-uc1/include/asm-microblaze/siginfo.h
--- linux-2.4.29/include/asm-microblaze/siginfo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/siginfo.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,243 @@
+#ifndef __MICROBLAZE_SIGINFO_H__
+#define __MICROBLAZE_SIGINFO_H__
+
+#include <linux/types.h>
+
+/* This is copied from asm-alpha/siginfo.h.  */
+
+typedef union sigval {
+	int sival_int;
+	void *sival_ptr;
+} sigval_t;
+
+#define SI_MAX_SIZE	128
+#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct siginfo {
+	int si_signo;
+	int si_errno;
+	int si_code;
+
+	union {
+		int _pad[SI_PAD_SIZE];
+
+		/* kill() */
+		struct {
+			__kernel_pid_t _pid;	/* sender's pid */
+			__kernel_uid_t _uid;	/* backwards compatibility */
+			__kernel_uid32_t _uid32; /* sender's uid */
+		} _kill;
+
+		/* POSIX.1b timers */
+		struct {
+			unsigned int _timer1;
+			unsigned int _timer2;
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			__kernel_pid_t _pid;	/* sender's pid */
+			__kernel_uid_t _uid;	/* backwards compatibility */
+			sigval_t _sigval;
+			__kernel_uid32_t _uid32; /* sender's uid */
+		} _rt;
+
+		/* SIGCHLD */
+		struct {
+			__kernel_pid_t _pid;	/* which child */
+			__kernel_uid_t _uid;	/* backwards compatibility */
+			int _status;		/* exit code */
+			clock_t _utime;
+			clock_t _stime;
+			__kernel_uid32_t _uid32; /* sender's uid */
+		} _sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			void *_addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+	} _sifields;
+} siginfo_t;
+
+#define UID16_SIGINFO_COMPAT_NEEDED
+
+/*
+ * How these fields are to be accessed.
+ */
+#define si_pid		_sifields._kill._pid
+#ifdef __KERNEL__
+#define si_uid		_sifields._kill._uid32
+#define si_uid16	_sifields._kill._uid
+#else
+#define si_uid		_sifields._kill._uid
+#endif /* __KERNEL__ */
+#define si_status	_sifields._sigchld._status
+#define si_utime	_sifields._sigchld._utime
+#define si_stime	_sifields._sigchld._stime
+#define si_value	_sifields._rt._sigval
+#define si_int		_sifields._rt._sigval.sival_int
+#define si_ptr		_sifields._rt._sigval.sival_ptr
+#define si_addr		_sifields._sigfault._addr
+#define si_band		_sifields._sigpoll._band
+#define si_fd		_sifields._sigpoll._fd
+
+#ifdef __KERNEL__
+#define __SI_MASK	0xffff0000
+#define __SI_KILL	(0 << 16)
+#define __SI_TIMER	(1 << 16)
+#define __SI_POLL	(2 << 16)
+#define __SI_FAULT	(3 << 16)
+#define __SI_CHLD	(4 << 16)
+#define __SI_RT		(5 << 16)
+#define __SI_CODE(T,N)	((T) << 16 | ((N) & 0xffff))
+#else
+#define __SI_KILL	0
+#define __SI_TIMER	0
+#define __SI_POLL	0
+#define __SI_FAULT	0
+#define __SI_CHLD	0
+#define __SI_RT		0
+#define __SI_CODE(T,N)	(N)
+#endif
+
+/*
+ * si_code values
+ * Digital reserves positive values for kernel-generated signals.
+ */
+#define SI_USER		0		/* sent by kill, sigsend, raise */
+#define SI_KERNEL	0x80		/* sent by the kernel from somewhere */
+#define SI_QUEUE	-1		/* sent by sigqueue */
+#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
+#define SI_MESGQ	-3		/* sent by real time mesq state change */
+#define SI_ASYNCIO	-4		/* sent by AIO completion */
+#define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
+
+#define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
+#define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
+
+/*
+ * SIGILL si_codes
+ */
+#define ILL_ILLOPC	(__SI_FAULT|1)	/* illegal opcode */
+#define ILL_ILLOPN	(__SI_FAULT|2)	/* illegal operand */
+#define ILL_ILLADR	(__SI_FAULT|3)	/* illegal addressing mode */
+#define ILL_ILLTRP	(__SI_FAULT|4)	/* illegal trap */
+#define ILL_PRVOPC	(__SI_FAULT|5)	/* privileged opcode */
+#define ILL_PRVREG	(__SI_FAULT|6)	/* privileged register */
+#define ILL_COPROC	(__SI_FAULT|7)	/* coprocessor error */
+#define ILL_BADSTK	(__SI_FAULT|8)	/* internal stack error */
+#define NSIGILL		8
+
+/*
+ * SIGFPE si_codes
+ */
+#define FPE_INTDIV	(__SI_FAULT|1)	/* integer divide by zero */
+#define FPE_INTOVF	(__SI_FAULT|2)	/* integer overflow */
+#define FPE_FLTDIV	(__SI_FAULT|3)	/* floating point divide by zero */
+#define FPE_FLTOVF	(__SI_FAULT|4)	/* floating point overflow */
+#define FPE_FLTUND	(__SI_FAULT|5)	/* floating point underflow */
+#define FPE_FLTRES	(__SI_FAULT|6)	/* floating point inexact result */
+#define FPE_FLTINV	(__SI_FAULT|7)	/* floating point invalid operation */
+#define FPE_FLTSUB	(__SI_FAULT|8)	/* subscript out of range */
+#define NSIGFPE		8
+
+/*
+ * SIGSEGV si_codes
+ */
+#define SEGV_MAPERR	(__SI_FAULT|1)	/* address not mapped to object */
+#define SEGV_ACCERR	(__SI_FAULT|2)	/* invalid permissions for mapped object */
+#define NSIGSEGV	2
+
+/*
+ * SIGBUS si_codes
+ */
+#define BUS_ADRALN	(__SI_FAULT|1)	/* invalid address alignment */
+#define BUS_ADRERR	(__SI_FAULT|2)	/* non-existant physical address */
+#define BUS_OBJERR	(__SI_FAULT|3)	/* object specific hardware error */
+#define NSIGBUS		3
+
+/*
+ * SIGTRAP si_codes
+ */
+#define TRAP_BRKPT	(__SI_FAULT|1)	/* process breakpoint */
+#define TRAP_TRACE	(__SI_FAULT|2)	/* process trace trap */
+#define NSIGTRAP	2
+
+/*
+ * SIGCHLD si_codes
+ */
+#define CLD_EXITED	(__SI_CHLD|1)	/* child has exited */
+#define CLD_KILLED	(__SI_CHLD|2)	/* child was killed */
+#define CLD_DUMPED	(__SI_CHLD|3)	/* child terminated abnormally */
+#define CLD_TRAPPED	(__SI_CHLD|4)	/* traced child has trapped */
+#define CLD_STOPPED	(__SI_CHLD|5)	/* child has stopped */
+#define CLD_CONTINUED	(__SI_CHLD|6)	/* stopped child has continued */
+#define NSIGCHLD	6
+
+/*
+ * SIGPOLL si_codes
+ */
+#define POLL_IN		(__SI_POLL|1)	/* data input available */
+#define POLL_OUT	(__SI_POLL|2)	/* output buffers available */
+#define POLL_MSG	(__SI_POLL|3)	/* input message available */
+#define POLL_ERR	(__SI_POLL|4)	/* i/o error */
+#define POLL_PRI	(__SI_POLL|5)	/* high priority input available */
+#define POLL_HUP	(__SI_POLL|6)	/* device disconnected */
+#define NSIGPOLL	6
+
+/*
+ * sigevent definitions
+ * 
+ * It seems likely that SIGEV_THREAD will have to be handled from 
+ * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
+ * thread manager then catches and does the appropriate nonsense.
+ * However, everything is written out here so as to not get lost.
+ */
+#define SIGEV_SIGNAL	0	/* notify via signal */
+#define SIGEV_NONE	1	/* other notification: meaningless */
+#define SIGEV_THREAD	2	/* deliver via thread creation */
+
+#define SIGEV_MAX_SIZE	64
+#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct sigevent {
+	sigval_t sigev_value;
+	int sigev_signo;
+	int sigev_notify;
+	union {
+		int _pad[SIGEV_PAD_SIZE];
+
+		struct {
+			void (*_function)(sigval_t);
+			void *_attribute;	/* really pthread_attr_t */
+		} _sigev_thread;
+	} _sigev_un;
+} sigevent_t;
+
+#define sigev_notify_function	_sigev_un._sigev_thread._function
+#define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
+
+#ifdef __KERNEL__
+#include <linux/string.h>
+
+extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
+{
+	if (from->si_code < 0)
+		memcpy(to, from, sizeof(siginfo_t));
+	else
+		/* _sigchld is currently the largest know union member */
+		memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
+}
+
+extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
+
+#endif /* __KERNEL__ */
+
+#endif /* __MICROBLAZE_SIGINFO_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/signal.h linux-2.4.29-uc1/include/asm-microblaze/signal.h
--- linux-2.4.29/include/asm-microblaze/signal.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/signal.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,193 @@
+#ifndef __MICROBLAZE_SIGNAL_H__
+#define __MICROBLAZE_SIGNAL_H__
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+
+#ifdef __KERNEL__
+
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else /* !__KERNEL__ */
+
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
+
+#define SA_RESTORER	0x04000000
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+
+#ifdef __KERNEL__
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE		SA_ONESHOT
+#define SA_SAMPLE_RANDOM	SA_RESTART
+#define SA_SHIRQ		0x04000000
+#endif /* __KERNEL__ */
+
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+
+#ifdef __KERNEL__
+
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+
+#else /* !__KERNEL__ */
+
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+
+#include <asm/sigcontext.h>
+#undef __HAVE_ARCH_SIG_BITOPS
+
+#endif /* __KERNEL__ */
+
+#endif /* __MICROBLAZE_SIGNAL_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/socket.h linux-2.4.29-uc1/include/asm-microblaze/socket.h
--- linux-2.4.29/include/asm-microblaze/socket.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/socket.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,64 @@
+#ifndef __MICROBLAZE_SOCKET_H__
+#define __MICROBLAZE_SOCKET_H__
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED	16
+#define SO_PEERCRED	17
+#define SO_RCVLOWAT	18
+#define SO_SNDLOWAT	19
+#define SO_RCVTIMEO	20
+#define SO_SNDTIMEO	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE	25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME             28
+#define SO_TIMESTAMP		29
+#define SCM_TIMESTAMP		SO_TIMESTAMP
+
+#define SO_ACCEPTCONN		30
+
+/* Nast libc5 fixup - bletch */
+#if defined(__KERNEL__)
+/* Socket types. */
+#define SOCK_STREAM	1		/* stream (connection) socket	*/
+#define SOCK_DGRAM	2		/* datagram (conn.less) socket	*/
+#define SOCK_RAW	3		/* raw socket			*/
+#define SOCK_RDM	4		/* reliably-delivered message	*/
+#define SOCK_SEQPACKET	5		/* sequential packet socket	*/
+#define SOCK_PACKET	10		/* linux specific way of	*/
+					/* getting packets at the dev	*/
+					/* level.  For writing rarp and	*/
+					/* other similar things on the	*/
+					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
+#endif
+
+#endif /* __MICROBLAZE_SOCKET_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/sockios.h linux-2.4.29-uc1/include/asm-microblaze/sockios.h
--- linux-2.4.29/include/asm-microblaze/sockios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/sockios.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef __MICROBLAZE_SOCKIOS_H__
+#define __MICROBLAZE_SOCKIOS_H__
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 	0x8901
+#define SIOCSPGRP	0x8902
+#define FIOGETOWN	0x8903
+#define SIOCGPGRP	0x8904
+#define SIOCATMARK	0x8905
+#define SIOCGSTAMP	0x8906		/* Get stamp */
+
+#endif /* __MICROBLAZE_SOCKIOS_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/softirq.h linux-2.4.29-uc1/include/asm-microblaze/softirq.h
--- linux-2.4.29/include/asm-microblaze/softirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/softirq.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,19 @@
+#ifndef __MICROBLAZE_SOFTIRQ_H__
+#define __MICROBLAZE_SOFTIRQ_H__
+
+#include <asm/atomic.h>
+#include <asm/hardirq.h>
+
+#define __cpu_bh_enable(cpu) \
+		do { barrier(); local_bh_count(cpu)--; } while (0)
+#define cpu_bh_disable(cpu) \
+		do { local_bh_count(cpu)++; barrier(); } while (0)
+
+#define local_bh_disable()	cpu_bh_disable(smp_processor_id())
+#define __local_bh_enable()	__cpu_bh_enable(smp_processor_id())
+
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
+
+#define local_bh_enable() __local_bh_enable()
+
+#endif /* __MICROBLAZE_SOFTIRQ_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/statfs.h linux-2.4.29-uc1/include/asm-microblaze/statfs.h
--- linux-2.4.29/include/asm-microblaze/statfs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/statfs.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef __MICROBLAZE_STATFS_H__
+#define __MICROBLAZE_STATFS_H__
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t	fsid_t;
+
+#endif
+
+struct statfs {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_spare[6];
+};
+
+#endif /* __MICROBLAZE_STATFS_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/stat.h linux-2.4.29-uc1/include/asm-microblaze/stat.h
--- linux-2.4.29/include/asm-microblaze/stat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/stat.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,60 @@
+#ifndef __MICROBLAZE_STAT_H__
+#define __MICROBLAZE_STAT_H__
+
+struct stat {
+	__kernel_dev_t	st_dev;
+	__kernel_ino_t	st_ino;
+	__kernel_mode_t	st_mode;
+	__kernel_nlink_t st_nlink;
+	__kernel_uid_t 	st_uid;
+	__kernel_gid_t 	st_gid;
+	__kernel_dev_t	st_rdev;
+	__kernel_off_t	st_size;
+	unsigned long	st_blksize;
+	unsigned long	st_blocks;
+	unsigned long	st_atime;
+	unsigned long	__unused1;
+	unsigned long	st_mtime;
+	unsigned long	__unused2;
+	unsigned long	st_ctime;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+	unsigned long	__unused5;
+};
+
+struct stat64 {
+	__kernel_dev_t	st_dev;
+	unsigned long	__unused0;
+	unsigned long	__unused1;
+
+	__kernel_ino64_t st_ino;
+
+	__kernel_mode_t	st_mode;
+	__kernel_nlink_t st_nlink;
+
+	__kernel_uid_t	st_uid;
+	__kernel_gid_t	st_gid;
+
+	__kernel_dev_t	st_rdev;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+
+	__kernel_loff_t	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	st_blocks; /* No. of 512-byte blocks allocated */
+	unsigned long	__unused4; /* future possible st_blocks high bits */
+
+	unsigned long	st_atime;
+	unsigned long	__unused5;
+
+	unsigned long	st_mtime;
+	unsigned long	__unused6;
+
+	unsigned long	st_ctime;
+	unsigned long	__unused7; /* high 32 bits of ctime someday */
+
+	unsigned long	__unused8;
+};
+
+#endif /* __MICROBLAZE_STAT_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/string.h linux-2.4.29-uc1/include/asm-microblaze/string.h
--- linux-2.4.29/include/asm-microblaze/string.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/string.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,51 @@
+/*
+ * include/asm-microblaze/string.h -- Architecture specific string routines
+ *
+ *  Copyright (C) 2005,2003  John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#include <linux/types.h>
+
+#ifndef __MICROBLAZE_STRING_H__
+#define __MICROBLAZE_STRING_H__
+
+/* Only use optimised memcpy/memmove if we have a HW barrel shift.
+ * Otherwise, it's more efficient to use the naive default implementations.
+ * These funcs are implemented in arch/microblaze/lib
+ */
+#if CONFIG_XILINX_MICROBLAZE0_USE_BARREL
+#define __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMMOVE
+
+extern void *memcpy (void *, const void *, __kernel_size_t);
+extern void *memmove (void *, const void *, __kernel_size_t);
+#endif
+
+/* Always use our optimised memset, it will rarely be slower than 
+   a naive byte set loop */
+#if 1
+#define __HAVE_ARCH_MEMSET
+extern void *memset (void *, int, __kernel_size_t);
+#endif
+
+/* 
+BCOPY still done with naive kernel implementation.  bcopy is just memcpy
+with reversed args, however it's not used in the kernel anyway.  Let's 
+just ignore it for now.
+*/
+
+#if 0
+#define __HAVE_ARCH_BCOPY
+extern void bcopy (const char *, char *, int);
+#endif
+
+#endif /* __MICROBLAZE_STRING_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/suzaku.h linux-2.4.29-uc1/include/asm-microblaze/suzaku.h
--- linux-2.4.29/include/asm-microblaze/suzaku.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/suzaku.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,26 @@
+/*  include/asm-microblaze/suzaku.h
+ *
+ *  (C) 2004 Atmark Techno, Inc. <yashi@atmark-techno.com>
+ *  (C) 2004 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ *  Defines board specific stuff for SUZAKU
+ *
+ */
+
+#ifndef _ASM_MICROBLAZE_SUZAKU_H
+#define _ASM_MICROBLAZE_SUZAKU_H
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+/* System Register (GPIO) */
+#ifndef MICROBLAZE_SYSREG_BASE_ADDR
+#define MICROBLAZE_SYSREG_BASE_ADDR 0xFFFFA000
+#define MICROBLAZE_SYSREG_RECONFIGURE (1 << 0)
+#endif
+
+#define NUM_CPU_IRQS 32
+
+#endif /* _ASM_MICROBLAZE_SUZAKU_H */
+
diff -urN linux-2.4.29/include/asm-microblaze/suzaku_smc.h linux-2.4.29-uc1/include/asm-microblaze/suzaku_smc.h
--- linux-2.4.29/include/asm-microblaze/suzaku_smc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/suzaku_smc.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,152 @@
+/****************************************************************************/
+
+/* suzaku_smc.h -- SMC ethernet support for SUZAKU environments.
+ *
+ * shamelessly copied from:
+ *
+ *	mcfsmc.h -- SMC ethernet support for ColdFire environments.
+ *
+ *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *	(C) Copyright 2000, Lineo Inc. (www.lineo.com) 
+ */
+
+/****************************************************************************/
+#ifndef	suzaku_smc_h
+#define	suzaku_smc_h
+/****************************************************************************/
+
+/*
+ *	None of the current ColdFire targets that use the SMC91x111
+ *	allow 8 bit accesses. So this code is 16bit access only.
+ */
+
+#include <linux/config.h>
+
+#undef	outb
+#undef	inb
+
+/*
+ *	Re-defines for ColdFire environment... The SMC part is
+ *	mapped into memory space, so remap the PC-style in/out
+ *	routines to handle that.
+ */
+#define	outb	smc_outb
+#define	inb	smc_inb
+#define	outw	smc_outw
+#define	outwd	smc_outwd
+#define	inw	smc_inw
+#define	outl	smc_outl
+#define	inl	smc_inl
+
+#define	outsb	smc_outsb
+#define	outsw	smc_outsw
+#define	outsl	smc_outsl
+#define	insb	smc_insb
+#define	insw	smc_insw
+#define	insl	smc_insl
+
+static inline void smc_outb(unsigned int val, unsigned int addr)
+{
+        *((volatile unsigned char *) addr) = (val);
+}
+
+static inline int smc_inb(unsigned int addr)
+{
+	register unsigned short	w;
+	w = *((volatile unsigned short *) (addr & ~0x1));
+	return(((addr & 0x1) ? w : (w >> 8)) & 0xff);
+}
+
+static inline void smc_outw(unsigned int val, unsigned int addr)
+{
+	*((volatile unsigned short *) addr) = (val << 8) | (val >> 8);
+}
+
+static inline int smc_inw(unsigned int addr)
+{
+	register unsigned short	w;
+	w = *((volatile unsigned short *) addr);
+	return(((w << 8) | (w >> 8)) & 0xffff);
+}
+
+static inline void smc_outl(unsigned long val, unsigned int addr)
+{
+	*((volatile unsigned long *) addr) = 
+		((val << 8) & 0xff000000) | ((val >> 8) & 0x00ff0000) |
+		((val << 8) & 0x0000ff00) | ((val >> 8) & 0x000000ff);
+}
+
+static inline void smc_outwd(unsigned int val, unsigned int addr)
+{
+	*((volatile unsigned short *) addr) = val;
+}
+
+
+/*
+ *	The rep* functions are used to feed the data port with
+ *	raw data. So we do not byte swap them when copying.
+ */
+
+static inline void smc_insb(unsigned int addr, void *vbuf, int unsigned long len)
+{
+	volatile unsigned short	*rp;
+	unsigned short		*buf, *ebuf;
+
+	buf = (unsigned short *) vbuf;
+	rp = (volatile unsigned short *) addr;
+
+	/* Copy as words for as long as possible */
+	for (ebuf = buf + (len >> 1); (buf < ebuf); )
+		*buf++ = *rp;
+
+	/* Lastly, handle left over byte */
+	if (len & 0x1)
+		*((unsigned char *) buf) = (*rp >> 8) & 0xff;
+}
+
+static inline void smc_insw(unsigned int addr, void *vbuf, unsigned long len)
+{
+	volatile unsigned short	*rp;
+	unsigned short		*buf, *ebuf;
+
+	buf = (unsigned short *) vbuf;
+	rp = (volatile unsigned short *) addr;
+	for (ebuf = buf + len; (buf < ebuf); )
+		*buf++ = *rp;
+}
+
+static inline void smc_insl(unsigned int addr, void *vbuf, unsigned long len)
+{
+	volatile unsigned long	*rp;
+	unsigned long		*buf, *ebuf;
+
+	buf = (unsigned long *) vbuf;
+	rp = (volatile unsigned long *) addr;
+	for (ebuf = buf + len; (buf < ebuf); )
+		*buf++ = *rp;
+}
+
+static inline void smc_outsw(unsigned int addr, const void *vbuf, unsigned long len)
+{
+	volatile unsigned short	*rp;
+	unsigned short		*buf, *ebuf;
+
+	buf = (unsigned short *) vbuf;
+	rp = (volatile unsigned short *) addr;
+	for (ebuf = buf + len; (buf < ebuf); )
+		*rp = *buf++;
+}
+
+static inline void smc_outsl(unsigned int addr, void *vbuf, unsigned long len)
+{
+	volatile unsigned long	*rp;
+	unsigned long		*buf, *ebuf;
+
+	buf = (unsigned long *) vbuf;
+	rp = (volatile unsigned long *) addr;
+	for (ebuf = buf + len; (buf < ebuf); )
+		*rp = *buf++;
+}
+
+/****************************************************************************/
+#endif	/* suzaku_smc_h */
diff -urN linux-2.4.29/include/asm-microblaze/system.h linux-2.4.29-uc1/include/asm-microblaze/system.h
--- linux-2.4.29/include/asm-microblaze/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/system.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,206 @@
+/*
+ * include/asm-microblaze/system.h -- Low-level interrupt/thread ops
+ *
+ *  Copyright (C) 2003  John Williams (jwilliams@itee.uq.edu.au)
+ *                      based upon microblaze version 
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_SYSTEM_H__
+#define __MICROBLAZE_SYSTEM_H__
+
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+
+#define prepare_to_switch()	do { } while (0)
+
+/*
+ * switch_to(n) should switch tasks to task ptr, first checking that
+ * ptr isn't the current task, in which case it does nothing.
+ */
+struct thread_struct;
+extern void *switch_thread (struct thread_struct *last,
+			    struct thread_struct *next);
+#define switch_to(prev,next,last)					      \
+  do {									      \
+        if (prev != next) {						      \
+ 		(last) = switch_thread (&prev->thread, &next->thread);	      \
+	}								      \
+  } while (0)
+
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+/* the msrset/msrclr instructions are available, let's use them! */
+
+/* Enable/disable interrupts.  */
+#define __sti() \
+{								\
+  __asm__ __volatile__ ("msrset	r0, 0x2;			\
+			 nop;"					\
+			: 					\
+			:					\
+			: "memory");				\
+}
+
+#define __cli() 						\
+{								\
+  __asm__ __volatile__ ("msrclr r0, 0x2;			\
+			 nop;"					\
+			: 					\
+			:					\
+			: "memory");				\
+}
+
+#define	__save_flags_cli(flags) 				\
+{								\
+  	__asm__ __volatile__ ("msrclr %0, 0x2;			\
+				nop;"				\
+			: "=r" (flags)				\
+			: 					\
+			: "memory");				\
+}
+
+#define	__save_flags_sti(flags) 				\
+{								\
+  	__asm__ __volatile__ ("msrset %0, 0x2;			\
+				nop;"				\
+			: "=r" (flags)				\
+			:					\
+			: "memory");				\
+}
+
+#else /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR not set */
+/* Enable/disable interrupts.  */
+#define __sti() \
+{								\
+	register unsigned tmp;					\
+  __asm__ __volatile__ ("					\
+			mfs 	%0, rmsr;			\
+			ori	%0, %0, 2;			\
+			mts	rmsr, %0;			\
+			nop;"					\
+			: "=r" (tmp)				\
+			:					\
+			: "memory");				\
+}
+
+#define __cli() \
+{								\
+	register unsigned tmp;					\
+  __asm__ __volatile__ ("					\
+			mfs 	%0, rmsr;			\
+			andi	%0, %0, ~2;			\
+			mts	rmsr, %0;			\
+			nop;"					\
+			: "=r" (tmp)				\
+			:					\
+			: "memory");				\
+}
+
+#define	__save_flags_cli(flags) \
+{								\
+	register unsigned tmp;					\
+  	__asm__ __volatile__ ("					\
+			mfs 	%0, rmsr;			\
+			andi	%1, %0, ~2;			\
+			mts	rmsr, %1;			\
+			nop;"					\
+			: "=r" (flags), "=r" (tmp)		\
+			: 					\
+			: "memory");				\
+}
+
+#define	__save_flags_sti(flags) 				\
+{								\
+	register unsigned tmp;					\
+  	__asm__ __volatile__ ("					\
+			mfs 	%0, rmsr;			\
+			ori	%1, %0, 2;			\
+			mts	rmsr, %1;			\
+			nop;"					\
+			: "=r" (flags) ,"=r" (tmp)		\
+			:					\
+			: "memory");				\
+}
+
+#endif
+
+#define __save_flags(flags) \
+  __asm__ __volatile__ ("mfs	%0, rmsr;nop;" : "=r" (flags))
+#define __restore_flags(flags) \
+  __asm__ __volatile__ ("mts	rmsr, %0;nop;" :: "r" (flags))
+
+/* For spinlocks etc */
+#define local_irq_save(flags)	__save_flags_cli (flags)
+#define local_irq_set(flags)	__save_flags_sti (flags)
+#define local_irq_restore(flags) __restore_flags (flags)
+#define local_irq_disable()	__cli ()
+#define local_irq_enable()	__sti ()
+
+#define cli()			__cli ()
+#define sti()			__sti ()
+#define save_flags(flags)	__save_flags (flags)
+#define restore_flags(flags)	__restore_flags (flags)
+#define save_flags_cli(flags)	__save_flags_cli (flags)
+
+/*
+ * Force strict CPU ordering.
+ * Not really required on microblaze...
+ */
+#define nop()			__asm__ __volatile__ ("nop")
+#define mb()			__asm__ __volatile__ ("nop" ::: "memory")
+#define rmb()			mb ()
+#define wmb()			mb ()
+#define set_mb(var, value)	do { var = value; mb(); } while (0)
+#define set_wmb(var, value)	do { var = value; wmb (); } while (0)
+
+#ifdef CONFIG_SMP
+#define smp_mb()	mb ()
+#define smp_rmb()	rmb ()
+#define smp_wmb()	wmb ()
+#else
+#define smp_mb()	barrier ()
+#define smp_rmb()	barrier ()
+#define smp_wmb()	barrier ()
+#endif
+
+#define xchg(ptr, with) \
+  ((__typeof__ (*(ptr)))__xchg ((unsigned long)(with), (ptr), sizeof (*(ptr))))
+#define tas(ptr) (xchg ((ptr), 1))
+
+extern inline unsigned long __xchg (unsigned long with,
+				    __volatile__ void *ptr, int size)
+{
+	unsigned long tmp, flags;
+
+	save_flags_cli (flags);
+
+	switch (size) {
+	case 1:
+		tmp = *(unsigned char *)ptr;
+		*(unsigned char *)ptr = with;
+		break;
+	case 2:
+		tmp = *(unsigned short *)ptr;
+		*(unsigned short *)ptr = with;
+		break;
+	case 4:
+		tmp = *(unsigned long *)ptr;
+		*(unsigned long *)ptr = with;
+		break;
+	}
+
+	restore_flags (flags);
+
+	return tmp;
+}
+
+#endif /* __MICROBLAZE_SYSTEM_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/teg.h linux-2.4.29-uc1/include/asm-microblaze/teg.h
--- linux-2.4.29/include/asm-microblaze/teg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/teg.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,59 @@
+/*
+ * include/asm-microblaze/nb85e_teg.h -- NB85E-TEG cpu chip
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_NB85E_TEG_H__
+#define __MICROBLAZE_NB85E_TEG_H__
+
+/* The NB85E_TEG uses the NB85E cpu core.  */
+#include <asm/nb85e.h>
+
+#define CHIP		"microblazee/nb85e-teg"
+#define CHIP_LONG	"NEC MICROBLAZEE/NB85E TEG"
+
+/* Hardware-specific interrupt numbers (in the kernel IRQ namespace).  */
+#define IRQ_INTOV(n)	(n)	/* 0-3 */
+#define IRQ_INTOV_NUM	4
+#define IRQ_INTCMD(n)	(0x1c + (n)) /* interval timer interrupts 0-3 */
+#define IRQ_INTCMD_NUM	4
+#define IRQ_INTDMA(n)	(0x20 + (n)) /* DMA interrupts 0-3 */
+#define IRQ_INTDMA_NUM	4
+#define IRQ_INTCSI(n)	(0x24 + (n)) /* CSI 0-2 transmit/receive completion */
+#define IRQ_INTCSI_NUM	3
+#define IRQ_INTSER(n)	(0x25 + (n)) /* UART 0-2 reception error */
+#define IRQ_INTSER_NUM	3
+#define IRQ_INTSR(n)	(0x26 + (n)) /* UART 0-2 reception completion */
+#define IRQ_INTSR_NUM	3
+#define IRQ_INTST(n)	(0x27 + (n)) /* UART 0-2 transmission completion */
+#define IRQ_INTST_NUM	3
+
+/* For <asm/irq.h> */
+#define NUM_MACH_IRQS	0x30
+
+/* TEG UART details.  */
+#define NB85E_UART_NUM_CHANNELS		3
+#define NB85E_UART_BASE_ADDR		0xFFFFF600
+#define NB85E_UART_ASIM_BASE_ADDR	(NB85E_UART_BASE_ADDR + 0x0)
+#define NB85E_UART_ASIS_BASE_ADDR	(NB85E_UART_BASE_ADDR + 0x2)
+#define NB85E_UART_ASIF_BASE_ADDR	(NB85E_UART_BASE_ADDR + 0x6)
+#define NB85E_UART_TXB_BASE_ADDR	(NB85E_UART_BASE_ADDR + 0xA)
+#define NB85E_UART_RXB_BASE_ADDR	(NB85E_UART_BASE_ADDR + 0xC)
+#define NB85E_UART_CKSR_BASE_ADDR	(NB85E_UART_BASE_ADDR + 0x6)
+#define NB85E_UART_BRGC_BASE_ADDR	(NB85E_UART_BASE_ADDR + 0x8)
+
+/* The TEG RTPU.  */
+#define NB85E_RTPU_BASE_ADDR		0xFFFFF210
+
+
+#endif /* __MICROBLAZE_NB85E_TEG_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/termbits.h linux-2.4.29-uc1/include/asm-microblaze/termbits.h
--- linux-2.4.29/include/asm-microblaze/termbits.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/termbits.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,174 @@
+#ifndef __MICROBLAZE_TERMBITS_H__
+#define __MICROBLAZE_TERMBITS_H__
+
+#include <linux/posix_types.h>
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#define NCCS 19
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IUCLC	0001000
+#define IXON	0002000
+#define IXANY	0004000
+#define IXOFF	0010000
+#define IMAXBEL	0020000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define OLCUC	0000002
+#define ONLCR	0000004
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#define NLDLY	0000400
+#define   NL0	0000000
+#define   NL1	0000400
+#define CRDLY	0003000
+#define   CR0	0000000
+#define   CR1	0001000
+#define   CR2	0002000
+#define   CR3	0003000
+#define TABDLY	0014000
+#define   TAB0	0000000
+#define   TAB1	0004000
+#define   TAB2	0010000
+#define   TAB3	0014000
+#define   XTABS	0014000
+#define BSDLY	0020000
+#define   BS0	0000000
+#define   BS1	0020000
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+#define FFDLY	0100000
+#define   FF0	0000000
+#define   FF1	0100000
+
+/* c_cflag bit meaning */
+#define CBAUD	0010017
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE	0000060
+#define   CS5	0000000
+#define   CS6	0000020
+#define   CS7	0000040
+#define   CS8	0000060
+#define CSTOPB	0000100
+#define CREAD	0000200
+#define PARENB	0000400
+#define PARODD	0001000
+#define HUPCL	0002000
+#define CLOCAL	0004000
+#define CBAUDEX 0010000
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+#define CIBAUD	  002003600000	/* input baud rate (not used) */
+#define CMSPAR	  010000000000		/* mark or space (stick) parity */
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+#define ISIG	0000001
+#define ICANON	0000002
+#define XCASE	0000004
+#define ECHO	0000010
+#define ECHOE	0000020
+#define ECHOK	0000040
+#define ECHONL	0000100
+#define NOFLSH	0000200
+#define TOSTOP	0000400
+#define ECHOCTL	0001000
+#define ECHOPRT	0002000
+#define ECHOKE	0004000
+#define FLUSHO	0010000
+#define PENDIN	0040000
+#define IEXTEN	0100000
+
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* __MICROBLAZE_TERMBITS_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/termios.h linux-2.4.29-uc1/include/asm-microblaze/termios.h
--- linux-2.4.29/include/asm-microblaze/termios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/termios.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,106 @@
+#ifndef __MICROBLAZE_TERMIOS_H__
+#define __MICROBLAZE_TERMIOS_H__
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6	/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14	/* synchronous PPP */
+#define N_HCI		15  /* Bluetooth HCI UART */
+
+#ifdef __KERNEL__
+
+/*	intr=^C		quit=^\		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+	unsigned short __tmp; \
+	get_user(__tmp,&(termio)->x); \
+	*(unsigned short *) &(termios)->x = __tmp; \
+}
+
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif	/* __KERNEL__ */
+
+#endif	/* __MICROBLAZE_TERMIOS_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/timex.h linux-2.4.29-uc1/include/asm-microblaze/timex.h
--- linux-2.4.29/include/asm-microblaze/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/timex.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ * linux/include/asm-microblaze/timex.h
+ *
+ * microblaze architecture timex specifications
+ */
+#ifndef __MICROBLAZE_TIMEX_H__
+#define __MICROBLAZE_TIMEX_H__
+
+#define vxtime_lock() do{} while(0)
+#define vxtime_unlock() do{} while(0)
+
+#define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
+#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
+#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
+	(1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
+		<< (SHIFT_SCALE-SHIFT_HZ)) / HZ)
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+	return 0;
+}
+
+#endif /* __MICROBLAZE_TIMEX_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/tlb.h linux-2.4.29-uc1/include/asm-microblaze/tlb.h
--- linux-2.4.29/include/asm-microblaze/tlb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/tlb.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-generic/tlb.h>
diff -urN linux-2.4.29/include/asm-microblaze/types.h linux-2.4.29-uc1/include/asm-microblaze/types.h
--- linux-2.4.29/include/asm-microblaze/types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/types.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,63 @@
+#ifndef __MICROBLAZE_TYPES_H__
+#define __MICROBLAZE_TYPES_H__
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue.  However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ */
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide.  */
+
+typedef u32 dma_addr_t;
+typedef u32 dma64_addr_t;
+
+#endif /* __KERNEL__ */
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __MICROBLAZE_TYPES_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/uaccess.h linux-2.4.29-uc1/include/asm-microblaze/uaccess.h
--- linux-2.4.29/include/asm-microblaze/uaccess.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/uaccess.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,165 @@
+/*
+ * User space memory access functions
+ *
+ * Note that Microblaze can't throw exeptions yet, so these functions
+ * do simple bare-bones data copying, with very few sanity checks
+ */
+#ifndef __MICROBLAZE_UACCESS_H__
+#define __MICROBLAZE_UACCESS_H__
+
+#include <linux/sched.h>
+
+#include <asm/segment.h>
+#include <asm/machdep.h>
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+extern inline int access_ok (int type, const void *addr, unsigned long size)
+{
+	/* XXX I guess we should check against real ram bounds at least, and
+	   possibly make sure ADDR is not within the kernel.
+	   For now we just check to make sure it's not a small positive
+	   or negative value, as that will at least catch some kinds of
+	   error.  In particular, we make sure that ADDR's not within the
+	   interrupt vector area, which we know starts at zero, or within the
+	   peripheral-I/O area, which is located just _before_ zero.  */
+	unsigned long val = (unsigned long)addr;
+	return val >= (0x80 + NUM_CPU_IRQS*16) && val < 0xFFFFF000;
+}
+
+extern inline int verify_area (int type, const void *addr, unsigned long size)
+{
+	return access_ok (type, addr, size) ? 0 : -EFAULT;
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table (unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ */
+
+extern inline int bad_user_access_length (void)
+{
+	return 0;
+}
+
+#define __get_user(var, ptr)						      \
+  ({									      \
+	  int __gu_err = 0;						      \
+	  typeof(*(ptr)) __gu_val = 0;					      \
+	  switch (sizeof (*(ptr))) {					      \
+	  case 1:							      \
+	  case 2:							      \
+	  case 4:							      \
+		  __gu_val = *(ptr);					      \
+		  break;						      \
+	  case 8:							      \
+		  memcpy(&__gu_val, ptr, sizeof(__gu_val));		      \
+		  break;						      \
+	  default:							      \
+		  __gu_val = 0;						      \
+		  __gu_err = __get_user_bad ();				      \
+		  break;						      \
+	  }								      \
+	  (var) = __gu_val;						      \
+	  __gu_err;							      \
+  })
+#define __get_user_bad()	(bad_user_access_length (), (-EFAULT))
+
+#define __put_user(var, ptr)						      \
+  ({									      \
+	  int __pu_err = 0;						      \
+	  switch (sizeof (*(ptr))) {					      \
+	  case 1:							      \
+	  case 2:							      \
+	  case 4:							      \
+		  *(ptr) = (var);					      \
+		  break;						      \
+	  case 8: {							      \
+	  	  typeof(*(ptr)) __pu_val = 0;				      \
+		  memcpy(ptr, &__pu_val, sizeof(__pu_val));		      \
+		  }							      \
+		  break;						      \
+	  default:							      \
+		  __pu_err = __put_user_bad ();				      \
+		  break;						      \
+	  }								      \
+	  __pu_err;							      \
+  })
+#define __put_user_bad()	(bad_user_access_length (), (-EFAULT))
+
+#define put_user(x, ptr)	__put_user(x, ptr)
+#define get_user(x, ptr)	__get_user(x, ptr)
+
+#define __copy_from_user(to, from, n)	(memcpy (to, from, n), 0)
+#define __copy_to_user(to, from, n)	(memcpy(to, from, n), 0)
+
+#define copy_from_user(to, from, n)	__copy_from_user (to, from, n)
+#define copy_to_user(to, from, n) 	__copy_to_user(to, from, n)
+
+#define copy_to_user_ret(to,from,n,retval) \
+  ({ if (copy_to_user (to,from,n)) return retval; })
+
+#define copy_from_user_ret(to,from,n,retval) \
+  ({ if (copy_from_user (to,from,n)) return retval; })
+
+/*
+ * Copy a null terminated string from userspace.
+ */
+
+static inline long
+strncpy_from_user (char *dst, const char *src, long count)
+{
+	char *tmp;
+	strncpy (dst, src, count);
+	for (tmp = dst; *tmp && count > 0; tmp++, count--)
+		;
+	return tmp - dst;
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 on exception, a value greater than N if too long
+ */
+static inline long strnlen_user (const char *src, long n)
+{
+	return strlen (src) + 1;
+}
+
+#define strlen_user(str)	strnlen_user (str, 32767)
+
+/*
+ * Zero Userspace
+ */
+
+static inline unsigned long
+clear_user (void *to, unsigned long n)
+{
+	memset (to, 0, n);
+	return 0;
+}
+
+#endif /* __MICROBLAZE_UACCESS_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/ucontext.h linux-2.4.29-uc1/include/asm-microblaze/ucontext.h
--- linux-2.4.29/include/asm-microblaze/ucontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/ucontext.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,14 @@
+#ifndef __MICROBLAZE_UCONTEXT_H__
+#define __MICROBLAZE_UCONTEXT_H__
+
+#include <asm/sigcontext.h>
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct sigcontext uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif /* __MICROBLAZE_UCONTEXT_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/unaligned.h linux-2.4.29-uc1/include/asm-microblaze/unaligned.h
--- linux-2.4.29/include/asm-microblaze/unaligned.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/unaligned.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,129 @@
+/*
+ * include/asm-microblaze/unaligned.h -- Unaligned memory access
+ *
+ *  Copyright (C) 2003  John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * This file is a copy of the arm version, include/asm-arm/unaligned.h
+ *
+ */
+
+#ifndef __MICROBLAZE_UNALIGNED_H__
+#define __MICROBLAZE_UNALIGNED_H__
+
+#include <asm/types.h>
+
+extern int __bug_unaligned_x(void *ptr);
+
+/*
+ * What is the most efficient way of loading/storing an unaligned value?
+ *
+ * That is the subject of this file.  Efficiency here is defined as
+ * minimum code size with minimum register usage for the common cases.
+ * It is currently not believed that long longs are common, so we
+ * trade efficiency for the chars, shorts and longs against the long
+ * longs.
+ *
+ * Current stats with gcc 2.7.2.2 for these functions:
+ *
+ *	ptrsize	get:	code	regs	put:	code	regs
+ *	1		1	1		1	2
+ *	2		3	2		3	2
+ *	4		7	3		7	3
+ *	8		20	6		16	6
+ *
+ * gcc 2.95.1 seems to code differently:
+ *
+ *	ptrsize	get:	code	regs	put:	code	regs
+ *	1		1	1		1	2
+ *	2		3	2		3	2
+ *	4		7	4		7	4
+ *	8		19	8		15	6
+ *
+ * which may or may not be more efficient (depending upon whether
+ * you can afford the extra registers).  Hopefully the gcc 2.95
+ * is inteligent enough to decide if it is better to use the
+ * extra register, but evidence so far seems to suggest otherwise.
+ *
+ * Unfortunately, gcc is not able to optimise the high word
+ * out of long long >> 32, or the low word from long long << 32
+ */
+
+#define __get_unaligned_2(__p)					\
+	(__p[1] | __p[0] << 8)
+
+#define __get_unaligned_4(__p)					\
+	(__p[3] | __p[2] << 8 | __p[1] << 16 | __p[0] << 24)
+
+#define get_unaligned(ptr)					\
+	({							\
+		__typeof__(*(ptr)) __v;				\
+		__u8 *__p = (__u8 *)(ptr);			\
+		switch (sizeof(*(ptr))) {			\
+		case 1:	__v = *(ptr);			break;	\
+		case 2: __v = __get_unaligned_2(__p);	break;	\
+		case 4: __v = __get_unaligned_4(__p);	break;	\
+		case 8: {					\
+				unsigned int __v1, __v2;	\
+				__v2 = __get_unaligned_4((__p+4)); \
+				__v1 = __get_unaligned_4(__p);	\
+				__v = ((unsigned long long)__v2 | (unsigned long long)__v1 << 32);	\
+			}					\
+			break;					\
+		default: __v = __bug_unaligned_x(__p);	break;	\
+		}						\
+		__v;						\
+	})
+
+
+extern inline void __put_unaligned_2(__u32 __v, register __u8 *__p)
+{
+	*__p++ = __v >> 8;
+	*__p++ = __v;
+}
+
+extern inline void __put_unaligned_4(__u32 __v, register __u8 *__p)
+{
+	__put_unaligned_2(__v , __p + 2);
+	__put_unaligned_2(__v >> 16, __p);
+}
+
+extern inline void __put_unaligned_8(const unsigned long long __v, register __u8 *__p)
+{
+	/*
+	 * tradeoff: 8 bytes of stack for all unaligned puts (2
+	 * instructions), or an extra register in the long long
+	 * case - go for the extra register.
+	 */
+	__put_unaligned_4(__v , __p+4);
+	__put_unaligned_4(__v >> 32, __p);
+}
+
+/*
+ * Try to store an unaligned value as efficiently as possible.
+ */
+#define put_unaligned(val,ptr)					\
+	({							\
+		switch (sizeof(*(ptr))) {			\
+		case 1:						\
+			*(ptr) = (val);				\
+			break;					\
+		case 2: __put_unaligned_2((val),(__u8 *)(ptr));	\
+			break;					\
+		case 4:	__put_unaligned_4((val),(__u8 *)(ptr));	\
+			break;					\
+		case 8:	__put_unaligned_8((val),(__u8 *)(ptr)); \
+			break;					\
+		default: __bug_unaligned_x(ptr);		\
+			break;					\
+		}						\
+		(void) 0;					\
+	})
+
+
+#endif /* __MICROBLAZE_UNALIGNED_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/unistd.h linux-2.4.29-uc1/include/asm-microblaze/unistd.h
--- linux-2.4.29/include/asm-microblaze/unistd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/unistd.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,451 @@
+/*
+ * include/asm-microblaze/unistd.h -- System call numbers and invocation mechanism
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_UNISTD_H__
+#define __MICROBLAZE_UNISTD_H__
+
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_chown		 16
+#define __NR_break		 17
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_umount2		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_old_getrlimit	 76
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_vhangup		111
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_cacheflush		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl		172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread		180
+#define __NR_pwrite		181
+#define __NR_lchown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_getpmsg		188	/* some people actually want streams */
+#define __NR_putpmsg		189	/* some people actually want streams */
+#define __NR_vfork		190
+#define __NR_getrlimit		191
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_chown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_lchown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+#define __NR_pivot_root		217
+/* #define __NR_mincore		218 */
+/* #define __NR_madvise		219 */
+#define __NR_getdents64		220
+#define __NR_fcntl64		221
+/* 224 `reserved for TUX' */
+/* #define __NR_security	223 */	/* syscall for security modules */
+#define __NR_gettid		224
+/* #define __NR_readahead	225 */
+
+
+/* Microblaze syscall protocol:
+   Syscall number in r12, args in r5-r10
+   Return value in r3.
+
+   System calls are achieved by branching to absolute address 0x8, 
+   the exception handler.  Microblaze doesn't currently use exceptions
+   so we take them over.  Contrary to the Microblaze ABI, we use r14
+   as the exception/trap return link address.  This is due to the
+   structure of entry.S, which uses common return code for traps and
+   interrupts.  This probably reflects some architectural stuff about 
+   the microblaze.  For now, lets leave it that way and worry about it in the future!
+*/
+
+#define SYSCALL_NUM	"r12"
+#define SYSCALL_ARG0	"r5"
+#define SYSCALL_ARG1	"r6"
+#define SYSCALL_ARG2	"r7"
+#define SYSCALL_ARG3	"r8"
+#define SYSCALL_ARG4	"r9"
+#define SYSCALL_ARG5	"r10"
+#define SYSCALL_RET	"r3"
+
+/* Backwards compatability for old dodgy way of doing syscalls with bralid.
+   As soon as possible, all targets must migrate to using brki instruction */
+
+#define SYSCALL_ENTRY_POINT C_SYMBOL_NAME(syscall_entry)
+
+/*
+ * Registers clobbered by a syscall.
+ * all volatile registers, except r5-r10, must be in the clobbered list.
+ * r5-r10 should be in input list.
+ * Note we don't use this any more, it's left purely for back-compatability
+ * for uClibc's microblaze syscall support
+ */
+#define SYSCALL_CLOBBERS	"cc", "r3", "r4", "r11", "r12", "r14"
+
+#define __syscall_return(type, res)			 		\
+do {									\
+	/* user-visible error numbers are in the range -1 - -124:	\
+	   see <asm-microblaze/errno.h> */				\
+	if ((unsigned long)(res) >= (unsigned long)(-125)) {		\
+		errno = -(res);						\
+		res = -1;						\
+	}								\
+	return (type) (res);						\
+} while (0)
+
+#define _syscall0(type, name)						\
+type name (void)							\
+{									\
+	long __ret;							\
+	__asm__ __volatile__ ("addik	r12, r0, %1	\n\t"		\
+			      "brki	r14, 0x8	\n\t"		\
+			      "addk	%0, r3, r0	\n\t"		\
+			      : "=r" (__ret)				\
+			      : "i" (__NR_##name)			\
+			      : "r3", "r4", "r12", "r14", "cc");	\
+	__syscall_return (type, __ret);					\
+}
+
+#define _syscall1(type, name, type1, arg1)				\
+type name (type1 arg1)							\
+{									\
+	long __ret;							\
+	__asm__ __volatile__ ("addk	r5, r0, %2	\n\t"		\
+			      "addik	r12, r0, %1	\n\t"		\
+			      "brki	r14, 0x8	\n\t"		\
+			      "addk	%0, r3, r0	\n\t"		\
+			      : "=r" (__ret)				\
+			      : "i" (__NR_##name),			\
+				"r" ((long)arg1)			\
+			      : "r3", "r4", "r5", "r12", "r14", "cc" );	\
+	__syscall_return (type, __ret);					\
+}
+
+#define _syscall2(type, name, type1, arg1, type2, arg2)			\
+type name (type1 arg1, type2 arg2)					\
+{									\
+	long __ret;							\
+	__asm__ __volatile__ ("addk	r5, r0, %2	\n\t"		\
+			      "addk	r6, r0, %3	\n\t"	   	\
+			      "addik	r12, r0, %1	\n\t"	   	\
+			      "brki	r14, 0x8	\n\t"	   	\
+			      "addk	%0, r3, r0	\n\t"	   	\
+			      : "=r" (__ret)			    	\
+			      : "i" (__NR_##name),		      	\
+				"r" ((long)arg1),		       	\
+				"r" ((long)arg2)			\
+			      : "r3", "r4", "r5", "r6", "r12", "r14", "cc");	\
+	__syscall_return (type, __ret);				 	\
+}
+
+#define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3)    \
+type name (type1 arg1, type2 arg2, type3 arg3)			  	\
+{								       	\
+	long __ret;						     	\
+	__asm__ __volatile__ ("addk	r5, r0, %2	\n\t"	   	\
+			      "addk	r6, r0, %3	\n\t"	   	\
+			      "addk	r7, r0, %4	\n\t"	   	\
+			      "addik	r12, r0, %1	\n\t"	   	\
+			      "brki	r14, 0x8	\n\t"	   	\
+			      "addk	%0, r3, r0	\n\t"	   	\
+			      : "=r" (__ret)			    	\
+			      : "i" (__NR_##name),		      	\
+				"r" ((long)arg1),		       	\
+				"r" ((long)arg2),		       	\
+				"r" ((long)arg3)			\
+			      : "r3", "r4", "r5", "r6", "r7", "r12", "r14", "cc");\
+	__syscall_return (type, __ret);				 \
+}
+
+#define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, type4, arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4)	      	\
+{								       	\
+	long __ret;						     	\
+	__asm__ __volatile__ ("addk	r5, r0, %2	\n\t"	   	\
+			      "addk	r6, r0, %3	\n\t"	   	\
+			      "addk	r7, r0, %4	\n\t"	   	\
+			      "addk	r8, r0, %5	\n\t"	   	\
+			      "addik	r12, r0, %1	\n\t"	   	\
+			      "brki	r14, 0x8	\n\t"	   	\
+			      "addk	%0, r3, r0	\n\t"	   	\
+			      : "=r" (__ret)			    	\
+			      : "i" (__NR_##name),		      	\
+				"r" ((long)arg1),		       	\
+				"r" ((long)arg2),		       	\
+				"r" ((long)arg3),		       	\
+				"r" ((long)arg4)			\
+			      : "r3", "r4", "r5", "r6", "r6", "r8", "r12", "r14", "cc");    \
+	__syscall_return (type, __ret);				 	\
+}
+
+#define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)  \
+{								       	\
+	long __ret;						     	\
+	__asm__ __volatile__ ("addk	r5, r0, %2	\n\t"	   	\
+			      "addk	r6, r0, %3	\n\t"	   	\
+			      "addk	r7, r0, %4	\n\t"	   	\
+			      "addk	r8, r0, %5	\n\t"	   	\
+			      "addk	r9, r0, %6	\n\t"	   	\
+			      "addik	r12, r0, %1	\n\t"	   	\
+			      "brki	r14, 0x8	\n\t"	   	\
+			      "addk	%0, r3, r0	\n\t"	   	\
+			      : "=r" (__ret)			    	\
+			      : "i" (__NR_##name),		      	\
+				"r" ((long)arg1),		       	\
+				"r" ((long)arg2),		       	\
+				"r" ((long)arg3),		       	\
+				"r" ((long)arg4),		       	\
+				"r" ((long)arg5)			\
+			      : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r12", "r14", "cc");\
+	__syscall_return (type, __ret);				 	\
+}
+
+#define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5, type6, arg6) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
+{									\
+	long __ret;							\
+	__asm__ __volatile__ ("addk	r5, r0, %2	\n\t"	   	\
+			      "addk	r6, r0, %3	\n\t"	   	\
+			      "addk	r7, r0, %4	\n\t"	   	\
+			      "addk	r8, r0, %5	\n\t"	   	\
+			      "addk	r9, r0, %6	\n\t"	   	\
+			      "addk	r10, r0, %7	\n\t"	   	\
+			      "addik	r12, r0, %1	\n\t"	   	\
+			      "brki	r14, 0x8	\n\t"	   	\
+			      "addk	%0, r3, r0	\n\t"	   	\
+			      : "=r" (__ret)			    	\
+			      : "i" (__NR_##name),		      	\
+				"r" ((long)arg1),		       	\
+				"r" ((long)arg2),		       	\
+				"r" ((long)arg3),		       	\
+				"r" ((long)arg4),		       	\
+				"r" ((long)arg5),		       	\
+				"r" ((long)arg6)			\
+			      : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "r14", "cc");		      	\
+	__syscall_return (type, __ret);				 	\
+}
+
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+extern inline _syscall0(int,pause)
+extern inline _syscall0(int,sync)
+extern inline _syscall0(pid_t,setsid)
+extern inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+extern inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+extern inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+extern inline _syscall1(int,dup,int,fd)
+extern inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+extern inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+extern inline _syscall1(int,close,int,fd)
+extern inline _syscall1(int,_exit,int,exitcode)
+extern inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+extern inline _syscall1(int,delete_module,const char *,name)
+
+extern inline pid_t wait(int * wait_stat)
+{
+	return waitpid (-1, wait_stat, 0);
+}
+
+#endif
+
+#endif /* __MICROBLAZE_UNISTD_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/user.h linux-2.4.29-uc1/include/asm-microblaze/user.h
--- linux-2.4.29/include/asm-microblaze/user.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/user.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,56 @@
+#ifndef __MICROBLAZE_USER_H__
+#define __MICROBLAZE_USER_H__
+
+/* Adapted from <asm-ppc/user.h>.  */
+
+#ifdef __KERNEL__
+
+#include <linux/ptrace.h>
+#include <asm/page.h>
+
+/*
+ * Core file format: The core file is written in such a way that gdb
+ * can understand it and provide useful information to the user (under
+ * linux we use the `trad-core' bfd, NOT the osf-core).  The file contents
+ * are as follows:
+ *
+ *  upage: 1 page consisting of a user struct that tells gdb
+ *	what is present in the file.  Directly after this is a
+ *	copy of the task_struct, which is currently not used by gdb,
+ *	but it may come in handy at some point.  All of the registers
+ *	are stored as part of the upage.  The upage should always be
+ *	only one page long.
+ *  data: The data segment follows next.  We use current->end_text to
+ *	current->brk to pick up all of the user variables, plus any memory
+ *	that may have been sbrk'ed.  No attempt is made to determine if a
+ *	page is demand-zero or if a page is totally unused, we just cover
+ *	the entire range.  All of the addresses are rounded in such a way
+ *	that an integral number of pages is written.
+ *  stack: We need the stack information in order to get a meaningful
+ *	backtrace.  We need to write the data from usp to
+ *	current->start_stack, so we round each of these in order to be able
+ *	to write an integer number of pages.
+ */
+struct user {
+	struct pt_regs	regs;			/* entire machine state */
+	size_t		u_tsize;		/* text size (pages) */
+	size_t		u_dsize;		/* data size (pages) */
+	size_t		u_ssize;		/* stack size (pages) */
+	unsigned long	start_code;		/* text starting address */
+	unsigned long	start_data;		/* data starting address */
+	unsigned long	start_stack;		/* stack starting address */
+	long int	signal;			/* signal causing core dump */
+	struct regs *	u_ar0;			/* help gdb find registers */
+	unsigned long	magic;			/* identifies a core file */
+	char		u_comm[32];		/* user command name */
+};
+
+#define NBPG			PAGE_SIZE
+#define UPAGES			1
+#define HOST_TEXT_START_ADDR	(u.start_code)
+#define HOST_DATA_START_ADDR	(u.start_data)
+#define HOST_STACK_END_ADDR	(u.start_stack + u.u_ssize * NBPG)
+
+#endif /* __KERNEL__ */
+
+#endif /* __MICROBLAZE_USER_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/virtconvert.h linux-2.4.29-uc1/include/asm-microblaze/virtconvert.h
--- linux-2.4.29/include/asm-microblaze/virtconvert.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/virtconvert.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,38 @@
+/*
+ * include/asm-microblaze/virtconvert.h -- conversion between virtual and
+ * 	physical mappings
+ *
+ *  Copyright (C) 2003       John Williams <jwilliams@itee.uq.edu.au>
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef __MICROBLAZE_VIRTCONVERT_H__
+#define __MICROBLAZE_VIRTCONVERT_H__
+
+#ifdef __KERNEL__
+
+#include <asm/page.h>
+
+#define mm_ptov(addr)		((void *)__phys_to_virt (addr))
+#define mm_vtop(addr)		((unsigned long)__virt_to_phys (addr))
+#define phys_to_virt(addr)	((void *)__phys_to_virt (addr))
+#define virt_to_phys(addr)	((unsigned long)__virt_to_phys (addr))
+#define virt_to_bus(addr)	((unsigned long)__virt_to_phys (addr))
+
+#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define page_to_phys(page)	virt_to_phys((void *)__page_address(page))
+#define page_to_bus(page)	(page_to_phys(page))
+#define bus_to_virt(addr)	(phys_to_virt(addr))
+
+
+#endif /* __KERNEL__ */
+
+#endif /* __MICROBLAZE_VIRTCONVERT_H__ */
diff -urN linux-2.4.29/include/asm-microblaze/xparameters.h linux-2.4.29-uc1/include/asm-microblaze/xparameters.h
--- linux-2.4.29/include/asm-microblaze/xparameters.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/xparameters.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,105 @@
+
+/*******************************************************************
+*
+* CAUTION: This file is automatically generated by libgen.
+* Version: Xilinx EDK 3.2.2 EDK_Cm.22
+* DO NOT EDIT.
+*
+* Copyright (c) 2003 Xilinx, Inc.  All rights reserved. 
+* 
+* Description: Driver parameters
+*
+*******************************************************************/
+
+#ifdef PLATFORM
+#error Autoconfig-targets and platforms should not include xparameters.h
+#else
+
+#define XPAR_D_LMB_BRAM_IF_CNTLR_BASEADDR 0x00000000
+#define XPAR_D_LMB_BRAM_IF_CNTLR_HIGHADDR 0x00003FFF
+#define XPAR_I_LMB_BRAM_IF_CNTLR_BASEADDR 0x00000000
+#define XPAR_I_LMB_BRAM_IF_CNTLR_HIGHADDR 0x00003FFF
+#define XPAR_DDR_CONTROLLER_BASEADDR 0x80000000
+#define XPAR_DDR_CONTROLLER_HIGHADDR 0x80FFFFFF
+#define XPAR_SYSTEM_MEMCON_BASEADDR 0xFFFF0000
+#define XPAR_SYSTEM_MEMCON_HIGHADDR 0xFFFF00FF
+
+/******************************************************************/
+
+#define XPAR_XUARTLITE_NUM_INSTANCES 2
+#define XPAR_CONSOLE_UART_BASEADDR 0xFFFF2000
+#define XPAR_CONSOLE_UART_HIGHADDR 0xFFFF20FF
+#define XPAR_DEBUG_UART_BASEADDR 0xFFFF4000
+#define XPAR_DEBUG_UART_HIGHADDR 0xFFFF40FF
+
+/******************************************************************/
+
+#define XPAR_INTC_MAX_NUM_INTR_INPUTS 3
+#define XPAR_INTC_SINGLE_BASEADDR 0xFFFF3000
+#define XPAR_INTC_SINGLE_HIGHADDR 0xFFFF30FF
+#define XPAR_XINTC_NUM_INSTANCES 1
+#define XPAR_XINTC_USE_DCR 0
+#define XPAR_SYSTEM_INTC_BASEADDR 0xFFFF3000
+#define XPAR_SYSTEM_INTC_HIGHADDR 0xFFFF30FF
+#define XPAR_SYSTEM_INTC_KIND_OF_INTR 0x0000006E
+
+/* These should link in to the intc core peripheral setup */
+#define CONFIG_MICROBLAZE_INTC_HAS_IVR
+#define CONFIG_MICROBLAZE_INTC_HAS_SIE
+#define CONFIG_MICROBLAZE_INTC_HAS_CIE
+
+/******************************************************************/
+
+#define XPAR_SYSTEM_TIMER_INTERRUPT_MASK 0X000001
+#define XPAR_CONSOLE_UART_INTERRUPT_MASK 0X000002
+#define XPAR_DEBUG_UART_INTERRUPT_MASK 0X000004
+
+/******************************************************************/
+
+#define XPAR_XTMRCTR_NUM_INSTANCES 1
+#define XPAR_SYSTEM_TIMER_BASEADDR 0xFFFF1000
+#define XPAR_SYSTEM_TIMER_HIGHADDR 0xFFFF10FF
+
+/******************************************************************/
+
+#define XPAR_XGPIO_NUM_INSTANCES 1
+#define XPAR_SYSTEM_GPIO_BASEADDR 0xFFFF5000
+#define XPAR_SYSTEM_GPIO_HIGHADDR 0xFFFF50FF
+#define XPAR_SYSTEM_GPIO_DEVICE_ID 0
+
+#define XPAR_GPIO_0_BASEADDR XPAR_SYSTEM_GPIO_BASEADDR
+#define XPAR_GPIO_0_HIGHADDR XPAR_SYSTEM_GPIO_HIGHADDR
+#define XPAR_GPIO_0_DEVICE_ID XPAR_SYSTEM_GPIO_DEVICE_ID
+
+/******************************************************************/
+
+#define XPAR_XEMAC_NUM_INSTANCES 1
+#define XPAR_EMAC_0_BASEADDR 0xC0000000
+#define XPAR_EMAC_0_HIGHADDR 0xC0003FFF
+#define XPAR_EMAC_0_DEVICE_ID 0
+
+#define XPAR_OPB_ETHERNET_0_DEVICE_ID XPAR_EMAC_0_DEVICE_ID
+#define XPAR_OPB_ETHERNET_0_BASEADDR XPAR_EMAC_0_BASEADDR
+
+#define XPAR_OPB_ETHERNET_0_DMA_PRESENT 1
+#define XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST 1
+#define XPAR_OPB_ETHERNET_0_MII_EXIST 1
+
+/******************************************************************/
+
+#define XPAR_XSYSACE_NUM_INSTANCES 1
+#define XPAR_SYSACE_0_HIGHADDR 0xCF0001FF
+#define XPAR_SYSACE_0_BASEADDR 0xCF000000
+#define XPAR_OPB_SYSACE_0_DEVICE_ID 0
+#define XPAR_OPB_SYSACE_0_BASEADDR XPAR_SYSACE_0_BASEADDR
+
+/******************************************************************/
+
+#define STDIN_BASEADDRESS 0xFFFF2000
+#define STDOUT_BASEADDRESS 0xFFFF2000
+
+#ifndef __ASSEMBLY__
+extern void XIntc_LowLevelInterruptHandler(void) __attribute__ ((interrupt_handler));
+#endif
+
+#endif /* defined(PLATFORM) */
diff -urN linux-2.4.29/include/asm-microblaze/xuartlite_l.h linux-2.4.29-uc1/include/asm-microblaze/xuartlite_l.h
--- linux-2.4.29/include/asm-microblaze/xuartlite_l.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-microblaze/xuartlite_l.h	2005-06-14 02:11:40.000000000 +0100
@@ -0,0 +1,256 @@
+/*****************************************************************************
+*
+*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
+*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
+*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*       FOR A PARTICULAR PURPOSE.
+*
+*       (c) Copyright 2002 Xilinx Inc.
+*       All rights reserved.
+*
+*****************************************************************************/
+/****************************************************************************/
+/**
+*
+* @file xuartlite_l.h
+*
+* This header file contains identifiers and low-level driver functions (or
+* macros) that can be used to access the device.  High-level driver functions
+* are defined in xuartlite.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00b rpm  04/25/02 First release
+* </pre>
+*
+*****************************************************************************/
+
+#ifndef XUARTLITE_L_H /* prevent circular inclusions */
+#define XUARTLITE_L_H /* by using protection macros */
+
+/***************************** Include Files ********************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+
+/************************** Constant Definitions ****************************/
+
+/* UART Lite register offsets */
+
+#define XUL_RX_FIFO_OFFSET              0   /* receive FIFO, read only */
+#define XUL_TX_FIFO_OFFSET              4   /* transmit FIFO, write only */
+#define XUL_STATUS_REG_OFFSET           8   /* status register, read only */
+#define XUL_CONTROL_REG_OFFSET          12  /* control register, write only */
+
+/* control register bit positions */
+
+#define XUL_CR_ENABLE_INTR              0x10    /* enable interrupt */
+#define XUL_CR_FIFO_RX_RESET            0x02    /* reset receive FIFO */
+#define XUL_CR_FIFO_TX_RESET            0x01    /* reset transmit FIFO */
+
+/* status register bit positions */
+
+#define XUL_SR_PARITY_ERROR             0x80
+#define XUL_SR_FRAMING_ERROR            0x40
+#define XUL_SR_OVERRUN_ERROR            0x20
+#define XUL_SR_INTR_ENABLED             0x10    /* interrupt enabled */
+#define XUL_SR_TX_FIFO_FULL             0x08    /* transmit FIFO full */
+#define XUL_SR_TX_FIFO_EMPTY            0x04    /* transmit FIFO empty */
+#define XUL_SR_RX_FIFO_FULL             0x02    /* receive FIFO full */
+#define XUL_SR_RX_FIFO_VALID_DATA       0x01    /* data in receive FIFO */
+
+/* the following constant specifies the size of the FIFOs, the size of the
+ * FIFOs includes the transmitter and receiver such that it is the total number
+ * of bytes that the UART can buffer
+ */
+#define XUL_FIFO_SIZE               16
+
+/* Stop bits are fixed at 1. Baud, parity, and data bits are fixed on a
+ * per instance basis
+ */
+#define XUL_STOP_BITS               1
+
+/* Parity definitions
+ */
+#define XUL_PARITY_NONE             0
+#define XUL_PARITY_ODD              1
+#define XUL_PARITY_EVEN             2
+
+/**************************** Type Definitions ******************************/
+
+/***************** Macros (Inline Functions) Definitions ********************/
+
+/*****************************************************************************
+*
+* Low-level driver macros and functions. The list below provides signatures
+* to help the user use the macros.
+*
+* void XUartLite_mSetControlReg(Xuint32 BaseAddress, Xuint32 Mask)
+* Xuint32 XUartLite_mGetControlReg(Xuint32 BaseAddress)
+* Xuint32 XUartLite_mGetStatusReg(Xuint32 BaseAddress)
+*
+* Xboolean XUartLite_mIsReceiveEmpty(Xuint32 BaseAddress)
+* Xboolean XUartLite_mIsTransmitFull(Xuint32 BaseAddress)
+* Xboolean XUartLite_mIsIntrEnabled(Xuint32 BaseAddress)
+*
+* void XUartLite_mEnableIntr(Xuint32 BaseAddress)
+* void XUartLite_mDisableIntr(Xuint32 BaseAddress)
+*
+* void XUartLite_SendByte(Xuint32 BaseAddress, Xuint8 Data);
+* Xuint8 XUartLite_RecvByte(Xuint32 BaseAddress);
+*
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*
+* Set the contents of the control register. Use the XUL_CR_* constants defined
+* above to create the bit-mask to be written to the register.
+*
+* @param    BaseAddress is the base address of the device
+* @param    Mask is the 32-bit value to write to the control register
+*
+* @return   None.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XUartLite_mSetControlReg(BaseAddress, Mask) \
+                    XIo_Out32((BaseAddress) + XUL_CONTROL_REG_OFFSET, (Mask))
+
+
+/****************************************************************************/
+/**
+*
+* Get the contents of the control register. Use the XUL_CR_* constants defined
+* above to interpret the bit-mask returned.
+*
+* @param    BaseAddress is the  base address of the device
+*
+* @return   A 32-bit value representing the contents of the control register.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XUartLite_mGetControlReg(BaseAddress) \
+                    XIo_In32((BaseAddress) + XUL_CONTROL_REG_OFFSET)
+
+
+/****************************************************************************/
+/**
+*
+* Get the contents of the status register. Use the XUL_SR_* constants defined
+* above to interpret the bit-mask returned.
+*
+* @param    BaseAddress is the  base address of the device
+*
+* @return   A 32-bit value representing the contents of the status register.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XUartLite_mGetStatusReg(BaseAddress) \
+                    XIo_In32((BaseAddress) + XUL_STATUS_REG_OFFSET)
+
+
+/****************************************************************************/
+/**
+*
+* Check to see if the receiver has data.
+*
+* @param    BaseAddress is the  base address of the device
+*
+* @return   XTRUE if the receiver is empty, XFALSE if there is data present.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XUartLite_mIsReceiveEmpty(BaseAddress) \
+          (!(XUartLite_mGetStatusReg((BaseAddress)) & XUL_SR_RX_FIFO_VALID_DATA))
+
+
+/****************************************************************************/
+/**
+*
+* Check to see if the transmitter is full.
+*
+* @param    BaseAddress is the  base address of the device
+*
+* @return   XTRUE if the transmitter is full, XFALSE otherwise.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XUartLite_mIsTransmitFull(BaseAddress) \
+                (XUartLite_mGetStatusReg((BaseAddress)) & XUL_SR_TX_FIFO_FULL)
+
+
+/****************************************************************************/
+/**
+*
+* Check to see if the interrupt is enabled.
+*
+* @param    BaseAddress is the  base address of the device
+*
+* @return   XTRUE if the interrupt is enabled, XFALSE otherwise.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XUartLite_mIsIntrEnabled(BaseAddress) \
+                (XUartLite_mGetStatusReg((BaseAddress)) & XUL_SR_INTR_ENABLED)
+
+
+/****************************************************************************/
+/**
+*
+* Enable the device interrupt. Preserve the contents of the control register.
+*
+* @param    BaseAddress is the  base address of the device
+*
+* @return   None.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XUartLite_mEnableIntr(BaseAddress) \
+               XUartLite_mSetControlReg((BaseAddress), \
+                   XUartLite_mGetControlReg((BaseAddress)) | XUL_CR_ENABLE_INTR)
+
+
+/****************************************************************************/
+/**
+*
+* Disable the device interrupt. Preserve the contents of the control register.
+*
+* @param    BaseAddress is the  base address of the device
+*
+* @return   None.
+*
+* @note     None.
+*
+*****************************************************************************/
+#define XUartLite_mDisableIntr(BaseAddress) \
+              XUartLite_mSetControlReg((BaseAddress), \
+                  XUartLite_mGetControlReg((BaseAddress)) & ~XUL_CR_ENABLE_INTR)
+
+
+/************************** Function Prototypes *****************************/
+
+void XUartLite_SendByte(Xuint32 BaseAddress, Xuint8 Data);
+Xuint8 XUartLite_RecvByte(Xuint32 BaseAddress);
+
+
+#endif            /* end of protection macro */
diff -urN linux-2.4.29/include/asm-mips/mc146818rtc.h linux-2.4.29-uc1/include/asm-mips/mc146818rtc.h
--- linux-2.4.29/include/asm-mips/mc146818rtc.h	2003-08-25 12:44:43.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-mips/mc146818rtc.h	2005-06-14 02:11:30.000000000 +0100
@@ -50,7 +50,7 @@
 
 #include <asm/dec/rtc-dec.h>
 
-#elif defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100)
+#elif defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_VEGAS)
 
 #define RTC_PORT(x)	(0x0c000000 + (x))
 #define RTC_IOMAPPED	0
diff -urN linux-2.4.29/include/asm-mips/vegas.h linux-2.4.29-uc1/include/asm-mips/vegas.h
--- linux-2.4.29/include/asm-mips/vegas.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-mips/vegas.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,85 @@
+/*
+ * Alchemy Semi PB1100 Referrence Board
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  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 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.
+ *
+ * ########################################################################
+ *
+ *
+ */
+#ifndef __ASM_VEGAS_H
+#define __ASM_VEGAS_H
+
+#define PB1100_IDENT          0xAE000000
+#define PB1100_BOARD_STATUS   0xAE000004
+  #define PB1100_ROM_SEL         (1<<15)
+  #define PB1100_ROM_SIZ         (1<<14)
+  #define PB1100_SWAP_BOOT       (1<<13)
+  #define PB1100_FLASH_WP        (1<<12)
+  #define PB1100_ROM_H_STS       (1<<11)
+  #define PB1100_ROM_L_STS       (1<<10)
+  #define PB1100_FLASH_H_STS      (1<<9)
+  #define PB1100_FLASH_L_STS      (1<<8)
+  #define PB1100_SRAM_SIZ         (1<<7)
+  #define PB1100_TSC_BUSY         (1<<6)
+  #define PB1100_PCMCIA_VS_MASK   (3<<4)
+  #define PB1100_RS232_CD         (1<<3)
+  #define PB1100_RS232_CTS        (1<<2)
+  #define PB1100_RS232_DSR        (1<<1)
+  #define PB1100_RS232_RI         (1<<0)
+
+#define PB1100_IRDA_RS232     0xAE00000C
+  #define PB1100_IRDA_FULL       (0<<14) /* full power */
+  #define PB1100_IRDA_SHUTDOWN   (1<<14)
+  #define PB1100_IRDA_TT         (2<<14) /* 2/3 power */
+  #define PB1100_IRDA_OT         (3<<14) /* 1/3 power */
+  #define PB1100_IRDA_FIR        (1<<13)
+
+#define PB1100_MEM_PCMCIA     0xAE000010
+  #define PB1100_SD_WP1_RO       (1<<15) /* read only */
+  #define PB1100_SD_WP0_RO       (1<<14) /* read only */
+  #define PB1100_SD_PWR1         (1<<11) /* applies power to SD1 */
+  #define PB1100_SD_PWR0         (1<<10) /* applies power to SD0 */
+  #define PB1100_SEL_SD_CONN1     (1<<9)
+  #define PB1100_SEL_SD_CONN0     (1<<8)
+  #define PB1100_PC_DEASSERT_RST  (1<<7)
+  #define PB1100_PC_DRV_EN        (1<<4)
+
+#define PB1100_G_CONTROL      0xAE000014 /* graphics control */
+
+#define PB1100_RST_VDDI       0xAE00001C
+  #define PB1100_SOFT_RESET      (1<<15) /* clear to reset the board */
+  #define PB1100_VDDI_MASK        (0x1F)
+
+#define PB1100_LEDS           0xAE000018
+
+/* 11:8 is 4 discreet LEDs. Clearing a bit illuminates the LED.
+ * 7:0 is the LED Display's decimal points.
+ */
+#define PB1100_HEX_LED        0xAE000018
+
+/* PCMCIA PB1100 specific defines */
+#define PCMCIA_MAX_SOCK 0
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+
+/* VPP/VCC */
+#define SET_VCC_VPP(VCC, VPP) (((VCC)<<2) | ((VPP)<<0))
+
+#endif /* __ASM_VEGAS_H */
diff -urN linux-2.4.29/include/asm-niosnommu/a.out.h linux-2.4.29-uc1/include/asm-niosnommu/a.out.h
--- linux-2.4.29/include/asm-niosnommu/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/a.out.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,49 @@
+#ifndef __NIOS_A_OUT_H__
+#define __NIOS_A_OUT_H__
+
+#define SPARC_PGSIZE    0x1000        /* Thanks to the sun4 architecture... */
+#define SEGMENT_SIZE    SPARC_PGSIZE  /* whee... */
+
+struct exec {
+	unsigned char a_dynamic:1;      /* A __DYNAMIC is in this image */
+	unsigned char a_toolversion:7;
+	unsigned char a_machtype;
+	unsigned short a_info;
+	unsigned long a_text;		/* length of text, in bytes */
+	unsigned long a_data;		/* length of data, in bytes */
+	unsigned long a_bss;		/* length of bss, in bytes */
+	unsigned long a_syms;		/* length of symbol table, in bytes */
+	unsigned long a_entry;		/* where program begins */
+	unsigned long a_trsize;
+	unsigned long a_drsize;
+};
+
+/* Where in the file does the text information begin? */
+#define N_TXTOFF(x)     (N_MAGIC(x) == ZMAGIC ? 0 : sizeof (struct exec))
+
+/* Where do the Symbols start? */
+#define N_SYMOFF(x)     (N_TXTOFF(x) + (x).a_text +   \
+                         (x).a_data + (x).a_trsize +  \
+                         (x).a_drsize)
+
+/* Where does text segment go in memory after being loaded? */
+#define N_TXTADDR(x)    (((N_MAGIC(x) == ZMAGIC) &&        \
+	                 ((x).a_entry < SPARC_PGSIZE)) ?   \
+                          0 : SPARC_PGSIZE)
+
+/* And same for the data segment.. */
+#define N_DATADDR(x) (N_MAGIC(x)==OMAGIC ?         \
+                      (N_TXTADDR(x) + (x).a_text)  \
+                       : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
+
+#define N_TRSIZE(a)	((a).a_trsize)
+#define N_DRSIZE(a)	((a).a_drsize)
+#define N_SYMSIZE(a)	((a).a_syms)
+
+#ifdef __KERNEL__
+
+#define STACK_TOP	TASK_SIZE
+
+#endif
+
+#endif /* __NIOS_A_OUT_H__ */
diff -urN linux-2.4.29/include/asm-niosnommu/asmmacro.h linux-2.4.29-uc1/include/asm-niosnommu/asmmacro.h
--- linux-2.4.29/include/asm-niosnommu/asmmacro.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/asmmacro.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,56 @@
+/* asmmacro.h: Assembler macros.
+ *
+ * Copyright (C) 2001 Microtronix Datacom Ltd.
+ *
+ * Based on Altera's Excalibur sdk "NM_Macros.s"
+ *
+ */
+
+#ifndef _NIOS_ASMMACRO_H
+#define _NIOS_ASMMACRO_H
+
+;----------------------------
+;
+; Macros I: Load and store instructions
+;           who index using byte offset values they
+;	    use the general LD & ST with a PFX if the
+;	    the offset is none zero and checks the length
+;	    /4 will fit in 11 bits.
+;
+; LDBO dst,src,val
+; STBO dst,val,src
+;
+;----------------------------
+
+.macro LDBO dst,src,val
+.if (\val & 0x3)
+.print "Offset not word aligned"
+.err
+.endif
+.if (\val/4 > 0x7FF)
+.print "Offset to great for K register"
+.else
+.if (\val/4 > 0)
+	pfx	\val/4
+.endif
+	ld	\dst,[\src]
+.endif
+.endm
+
+.macro STBO dst,val,src
+.if (\val & 0x3)
+.print "Offset not word aligned"
+.err
+.endif
+.if (\val/4 > 0x7FF)
+.print "Offset to great for K register"
+.err
+.else
+.if (\val/4 > 0)
+	pfx	\val/4
+.endif
+	st	[\dst],\src
+.endif
+.endm
+
+#endif /* !(_NIOS_ASMMACRO_H) */
diff -urN linux-2.4.29/include/asm-niosnommu/atomic.h linux-2.4.29-uc1/include/asm-niosnommu/atomic.h
--- linux-2.4.29/include/asm-niosnommu/atomic.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/atomic.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,128 @@
+//vic - add 'atomic_add/sub_return', 'atomic_add_negative'
+//vic     from v850 architecture
+
+/* atomic.h: 
+ *
+ * Copyright (C) 2001 Vic Phillips (vic@microtronix.com)
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __ARCH_NIOS_ATOMIC__
+#define __ARCH_NIOS_ATOMIC__
+
+#include <asm/system.h>
+
+typedef struct { int counter; } atomic_t;
+#define ATOMIC_INIT(i)	{ (i) }
+
+#define atomic_read(v)		((v)->counter)
+#define atomic_set(v, i)	(((v)->counter) = i)
+
+
+extern __inline__ void atomic_add(int i, atomic_t *v)
+{
+	_disable_interrupts();
+	v->counter += i;
+	_enable_interrupts();
+}
+
+extern __inline__ void atomic_sub(int i, atomic_t *v)
+{
+	_disable_interrupts();
+	v->counter -= i;
+	_enable_interrupts();
+}
+
+extern __inline__ int atomic_sub_and_test(int i, atomic_t *v)
+{
+	int result;
+	_disable_interrupts();
+	v->counter -= i;
+	result = (v->counter == 0);
+	_enable_interrupts();
+	return result;
+}
+
+extern __inline__ void atomic_inc(atomic_t *v)
+{
+	_disable_interrupts();
+	v->counter += 1;
+	_enable_interrupts();
+}
+
+extern __inline__ void atomic_dec(atomic_t *v)
+{
+	int i = 1;					/* the compiler optimizes better this way */
+	_disable_interrupts();
+	v->counter -= i;
+	_enable_interrupts();
+}
+
+extern __inline__ int atomic_dec_and_test(atomic_t *v)
+{
+	int result;
+	int i = 1;					/* the compiler optimizes better this way */
+	_disable_interrupts();
+	v->counter -= i;
+	result = (v->counter == 0);
+	_enable_interrupts();
+	return result;
+}
+
+extern __inline__ int atomic_inc_return(atomic_t *v)
+{
+	int result;
+	_disable_interrupts();
+	result = ++v->counter;
+	_enable_interrupts();
+	return result;
+}
+
+extern __inline__ int atomic_dec_return(atomic_t *v)
+{
+	int result;
+	int i = 1;					/* the compiler optimizes better this way */
+	_disable_interrupts();
+	v->counter -= i;
+	result = v->counter;
+	_enable_interrupts();
+	return result;
+}
+
+extern __inline__ int atomic_add_return (int i, volatile atomic_t *v)
+{
+	int res;
+
+	_disable_interrupts();
+	res = v->counter + i;
+	v->counter = res;
+	_enable_interrupts();
+
+	return res;
+}
+
+static __inline__ int atomic_sub_return (int i, volatile atomic_t *v)
+{
+	int res;
+
+	_disable_interrupts();
+	res = v->counter - i;
+	v->counter = res;
+	_enable_interrupts();
+
+	return res;
+}
+
+#define atomic_add_negative(i,v)	(atomic_add_return ((i), (v)) < 0)
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec()	barrier()
+#define smp_mb__after_atomic_dec()	barrier()
+#define smp_mb__before_atomic_inc()	barrier()
+#define smp_mb__after_atomic_inc()	barrier()
+
+
+#endif /* !(__ARCH_NIOS_ATOMIC__) */
+
+
diff -urN linux-2.4.29/include/asm-niosnommu/bitops.h linux-2.4.29-uc1/include/asm-niosnommu/bitops.h
--- linux-2.4.29/include/asm-niosnommu/bitops.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/bitops.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,272 @@
+#ifndef _ASM_NIOS_BITOPS_H_
+#define _ASM_NIOS_BITOPS_H_
+
+#ifdef __KERNEL__
+#include <asm/system.h>
+#endif
+
+/*
+ * Adapted to NIOS from generic bitops.h:
+ *
+ * For the benefit of those who are trying to port Linux to another
+ * architecture, here are some C-language equivalents.  You should
+ * recode these in the native assembly language, if at all possible.
+ * To guarantee atomicity, these routines call cli() and sti() to
+ * disable interrupts while they operate.  (You have to provide inline
+ * routines to cli() and sti().)
+ *
+ * Also note, these routines assume that you have 32 bit integers.
+ * You will have to change this if you are trying to port Linux to the
+ * Alpha architecture or to a Cray.  :-)
+ * 
+ * C language equivalents written by Theodore Ts'o, 9/26/92
+ */
+
+extern __inline__ void set_bit(int nr, volatile void * a)
+{
+	int * addr = (int *) a;
+	int	mask;
+
+	addr += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	_disable_interrupts();
+	*addr |= mask;
+	_enable_interrupts();
+}
+
+extern __inline__ void __set_bit(int nr, volatile void * a)
+{
+	int * addr = (int *) a;
+	int	mask;
+
+	addr += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	*addr |= mask;
+}
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+
+extern __inline__ void clear_bit(int nr, volatile void * a)
+{
+	int * addr = (int *) a;
+	int	mask;
+
+	addr += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	_disable_interrupts();
+	*addr &= ~mask;
+	_enable_interrupts();
+}
+
+extern __inline__ void __clear_bit(int nr, volatile void * a)
+{
+	int * addr = (int *) a;
+	int	mask;
+
+	addr += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	*addr &= ~mask;
+}
+
+extern __inline__ int test_and_clear_bit(int nr, volatile void * a)
+{
+	int * addr = (int *) a;
+	int	mask, retval;
+
+	addr += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	_disable_interrupts();
+	retval = (mask & *addr) != 0;
+	*addr &= ~mask;
+	_enable_interrupts();
+	return retval;
+}
+
+extern __inline__ int __test_and_clear_bit(int nr, volatile void * a)
+{
+	int * addr = (int *) a;
+	int	mask, retval;
+
+	addr += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *addr) != 0;
+	*addr &= ~mask;
+	return retval;
+}
+
+extern __inline__ void change_bit(unsigned long nr, volatile void *addr)
+{
+	int mask;
+	unsigned long *ADDR = (unsigned long *) addr;
+
+	ADDR += nr >> 5;
+	mask = 1 << (nr & 31);
+	_disable_interrupts();
+	*ADDR ^= mask;
+	_enable_interrupts();
+}
+
+extern __inline__ void __change_bit(unsigned long nr, volatile void *addr)
+{
+	int mask;
+	unsigned long *ADDR = (unsigned long *) addr;
+
+	ADDR += nr >> 5;
+	mask = 1 << (nr & 31);
+	*ADDR ^= mask;
+}
+
+extern __inline__ int test_and_set_bit(int nr, volatile void * a)
+{
+	volatile unsigned int *addr = (volatile unsigned int *) a;
+	int	mask,retval;
+
+	addr += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	_disable_interrupts();
+	retval = (mask & *addr) != 0;
+	*addr |= mask;
+	_enable_interrupts();
+	return retval;
+}
+
+extern __inline__ int __test_and_set_bit(int nr, volatile void * a)
+{
+	volatile unsigned int *addr = (volatile unsigned int *) a;
+	int	mask,retval;
+
+	addr += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *addr) != 0;
+	*addr |= mask;
+	return retval;
+}
+
+extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	_disable_interrupts();
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	_enable_interrupts();
+
+	return retval;
+}
+
+extern __inline__ int __test_and_change_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = (volatile unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	return retval;
+}
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+extern __inline__ int __constant_test_bit(int nr, const volatile void * addr)
+{
+	return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
+}
+
+extern __inline__ int __test_bit(int nr, volatile void * addr)
+{
+	int * a = (int *) addr;
+	int	mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	return ((mask & *a) != 0);
+}
+
+#define test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ __constant_test_bit((nr),(addr)) : \
+ __test_bit((nr),(addr)))
+
+
+/* The easy/cheese version for now. */
+extern __inline__ unsigned long ffz(unsigned long word)
+{
+	unsigned long result = 0;
+
+	while(word & 1) {
+		result++;
+		word >>= 1;
+	}
+	return result;
+}
+
+/* find_next_zero_bit() finds the first zero bit in a bit string of length
+ * 'size' bits, starting the search at bit 'offset'. This is largely based
+ * on Linus's ALPHA routines, which are pretty portable BTW.
+ */
+
+extern __inline__ unsigned long find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if (offset) {
+		tmp = *(p++);
+		tmp |= ~0UL >> (32-offset);
+		if (size < 32)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while (size & ~31UL) {
+		if (~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp |= ~0UL >> size;
+found_middle:
+	return result + ffz(tmp);
+}
+
+/* Linus sez that gcc can optimize the following correctly, we'll see if this
+ * holds on the Sparc as it does for the ALPHA.
+ */
+
+#define find_first_zero_bit(addr, size) \
+        find_next_zero_bit((addr), (size), 0)
+
+/* Now for the ext2 filesystem bit operations and helper routines.
+ *
+ * Both NIOS and ext2 are little endian, so these are the same as above.
+ */
+
+#define ext2_set_bit   test_and_set_bit
+#define ext2_clear_bit test_and_clear_bit
+#define ext2_test_bit  test_bit
+
+#define ext2_find_first_zero_bit find_first_zero_bit
+#define ext2_find_next_zero_bit  find_next_zero_bit
+
+#endif /* _ASM_NIOS_BITOPS_H */
diff -urN linux-2.4.29/include/asm-niosnommu/bugs.h linux-2.4.29-uc1/include/asm-niosnommu/bugs.h
--- linux-2.4.29/include/asm-niosnommu/bugs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/bugs.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,17 @@
+/* vic */
+/*
+ *  include/asm-nios/bugs.h
+ *
+ *  Copyright (C) 1994  Linus Torvalds
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *	void check_bugs(void);
+ */
+
+static void check_bugs(void)
+{
+}
diff -urN linux-2.4.29/include/asm-niosnommu/byteorder.h linux-2.4.29-uc1/include/asm-niosnommu/byteorder.h
--- linux-2.4.29/include/asm-niosnommu/byteorder.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/byteorder.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,20 @@
+/*
+ *  linux/include/asm-niosnommu/byteorder.h
+ */
+#ifndef __ASM_NIOS_BYTEORDER_H
+#define __ASM_NIOS_BYTEORDER_H
+
+
+#include <asm/types.h>
+
+//vic FIXME need some swab defines ...
+
+//vic#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+//vic#  define __BYTEORDER_HAS_U64__
+//vic#  define __SWAB_64_THRU_32__
+//vic#endif
+
+#include <linux/byteorder/little_endian.h>
+
+#endif
+
diff -urN linux-2.4.29/include/asm-niosnommu/cache.h linux-2.4.29-uc1/include/asm-niosnommu/cache.h
--- linux-2.4.29/include/asm-niosnommu/cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/cache.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,11 @@
+#ifndef __ARCH_NIOSNOMMU_CACHE_H
+#define __ARCH_NIOSNOMMU_CACHE_H
+
+/* bytes per L1 cache line */
+#define        L1_CACHE_BYTES  16	/* this need to be at least 1 */
+
+
+#define __cacheline_aligned
+#define ____cacheline_aligned
+
+#endif
diff -urN linux-2.4.29/include/asm-niosnommu/checksum.h linux-2.4.29-uc1/include/asm-niosnommu/checksum.h
--- linux-2.4.29/include/asm-niosnommu/checksum.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/checksum.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,294 @@
+#ifndef __NIOS_CHECKSUM_H
+#define __NIOS_CHECKSUM_H
+
+/*  checksum.h:  IP/UDP/TCP checksum routines on the NIOS.
+ *
+ *  Copyright(C) 1995 Linus Torvalds
+ *  Copyright(C) 1995 Miguel de Icaza
+ *  Copyright(C) 1996 David S. Miller
+ *  Copyright(C) 2001 Ken Hill
+ *
+ * derived from:
+ *	Alpha checksum c-code
+ *      ix86 inline assembly
+ *      Spar nommu
+ */
+
+
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+
+extern inline unsigned short csum_tcpudp_magic(unsigned long saddr,
+					       unsigned long daddr,
+					       unsigned short len,
+					       unsigned short proto,
+					       unsigned int sum)
+{
+	__asm__ __volatile__("
+		add    	%0, %3
+		skps	cc_nc
+		addi	%0, 1
+		add	%0, %4
+		skps	cc_nc
+		addi	%0, 1
+		add	%0, %5
+		skps	cc_nc
+		addi	%0, 1
+
+		; We need the carry from the addition of 16-bit
+		; significant addition, so we zap out the low bits
+		; in one half, zap out the high bits in another,
+		; shift them both up to the top 16-bits of a word
+		; and do the carry producing addition, finally
+		; shift the result back down to the low 16-bits.
+
+		; Actually, we can further optimize away two shifts
+		; because we know the low bits of the original
+		; value will be added to zero-only bits so cannot
+		; affect the addition result nor the final carry
+		; bit.
+
+		mov	%1,%0			; Need a copy to fold with
+		lsli	%1, 16			; Bring the LOW 16 bits up
+		add	%0, %1			; add and set carry, neat eh?
+		lsri	%0, 16			; shift back down the result
+		skps	cc_nc			; get remaining carry bit
+		addi	%0, 1
+		not	%0			; negate
+		"
+	        : "=&r" (sum), "=&r" (saddr)
+		: "0" (sum), "1" (saddr), "r" (ntohl(len+proto)), "r" (daddr));
+		return ((unsigned short) sum); 
+}
+
+
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+
+  extern inline unsigned short from32to16(unsigned long x)
+  {
+	__asm__ __volatile__("
+		add	%0, %1
+		lsri	%0, 16
+		skps	cc_nc
+		addi	%0, 1
+		"
+		: "=r" (x)
+		: "r" (x << 16), "0" (x));
+	return x;
+  }
+
+
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+
+extern inline unsigned long do_csum(unsigned char * buff, int len)
+{
+ int odd, count;
+ unsigned long result = 0;
+
+ if (len <= 0)
+ 	goto out;
+ odd = 1 & (unsigned long) buff;
+ if (odd) {
+////result = *buff;                     // dgt: Big    endian
+ 	result = *buff << 8;                // dgt: Little endian
+
+ 	len--;
+ 	buff++;
+ }
+ count = len >> 1;		/* nr of 16-bit words.. */
+ if (count) {
+ 	if (2 & (unsigned long) buff) {
+ 		result += *(unsigned short *) buff;
+ 		count--;
+ 		len -= 2;
+ 		buff += 2;
+ 	}
+ 	count >>= 1;		/* nr of 32-bit words.. */
+ 	if (count) {
+ 	        unsigned long carry = 0;
+ 		do {
+ 			unsigned long w = *(unsigned long *) buff;
+ 			count--;
+ 			buff += 4;
+ 			result += carry;
+ 			result += w;
+ 			carry = (w > result);
+ 		} while (count);
+ 		result += carry;
+ 		result = (result & 0xffff) + (result >> 16);
+ 	}
+ 	if (len & 2) {
+ 		result += *(unsigned short *) buff;
+ 		buff += 2;
+ 	}
+ }
+ if (len & 1)
+ 	result += *buff;  /* This is little machine, byte is right */
+ result = from32to16(result);
+ if (odd)
+ 	result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+	return result;
+  }
+
+
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+
+/* ihl is always 5 or greater, almost always is 5, iph is always word
+ * aligned but can fail to be dword aligned very often.
+ */
+
+  extern inline unsigned short ip_fast_csum(const unsigned char *iph, unsigned int ihl)
+  {
+	unsigned int sum;
+
+	__asm__ __volatile__("
+		mov	%%g1, %1	; Remember original alignment
+		skp1	%1,1		; Aligned on 16 bit boundary, get first 16 bits
+		br	1f		; Aligned on 32 bit boundary, go
+		ld	%0, [%1]
+		ext16d	%0, %1		; Get correct 16 bits
+		subi	%2, 1		; Take off for 4 bytes, pickup last 2 at end
+		addi	%1, 2		; Adjust pointer to 32 bit boundary
+		br	2f
+		 nop
+1:
+		subi	%2, 1
+		addi	%1, 4		; Bump ptr a long word
+2:
+		ld      %%g2, [%1]
+1:
+		add     %0, %%g2
+		skps	cc_nc
+		addi	%0, 1
+		addi	%1, 0x4
+		subi	%2, 0x1
+		ld      %%g2, [%1]
+		skps	cc_z
+		br      1b
+		 nop
+		skp1	%%g1,1		; Started on 16 bit boundary, pickup last 2 bytes
+		br	1f		; 32 bit boundary read to leave
+		 ext16d	%%g2, %1	; Get correct 16 bits
+		add     %0, %%g2
+		skps	cc_nc
+		addi	%0, 1
+1:
+		mov     %2, %0
+		lsli	%2, 16
+		add     %0, %2
+		lsri	%0, 16
+		skps	cc_nc
+		addi	%0, 1
+		not     %0
+		"
+		: "=&r" (sum), "=&r" (iph), "=&r" (ihl)
+		: "1" (iph), "2" (ihl)
+		: "g1", "g2");
+	return sum;
+  }
+
+/*these 2 functions are now in checksum.c */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
+
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+/*
+ * the same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+extern inline unsigned int
+csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err)
+{
+	if (csum_err) *csum_err = 0;
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
+
+#define csum_partial_copy_nocheck(src, dst, len, sum)	\
+	csum_partial_copy ((src), (dst), (len), (sum))
+
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+extern inline unsigned short ip_compute_csum(unsigned char * buff, int len)
+{
+ return ~from32to16(do_csum(buff,len));
+}
+
+
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+
+#define csum_partial_copy_fromuser(s, d, l, w)  \
+                     csum_partial_copy((char *) (s), (d), (l), (w))
+
+
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+
+/*
+ *	Fold a partial checksum without adding pseudo headers
+ */
+extern inline unsigned int csum_fold(unsigned int sum)
+{
+	__asm__ __volatile__("
+		add	%0, %1
+		lsri	%0, 16
+		skps	cc_nc
+		addi	%0, 1
+		not	%0
+		"
+		: "=r" (sum)
+		: "r" (sum << 16), "0" (sum)); 
+	return sum;
+}
+
+
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+//vic - FIXME - should check the constraints - they may not correct
+
+extern __inline__ unsigned long csum_tcpudp_nofold(unsigned long saddr,
+						   unsigned long daddr,
+						   unsigned short len,
+						   unsigned short proto,
+						   unsigned int sum)
+{
+	__asm__ __volatile__("
+		add		%0, %1
+		skps	cc_nc
+		addi	%0, 1		; add carry
+		add	%0, %2
+		skps	cc_nc
+		addi	%0, 1		; add carry
+		add	%0, %3
+		skps	cc_nc
+		addi	%0, 1		; add carry
+		"
+		: "=r" (sum), "=r" (saddr)
+		: "r" (daddr), "r" ( (ntohs(len)<<16) + (proto*256) ),
+		  "0" (sum),
+		  "1" (saddr)
+		: "cc");
+
+	return sum;
+}
+
+
+#endif /* (__NIOS_CHECKSUM_H) */
+
+
diff -urN linux-2.4.29/include/asm-niosnommu/cprefix.h linux-2.4.29-uc1/include/asm-niosnommu/cprefix.h
--- linux-2.4.29/include/asm-niosnommu/cprefix.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/cprefix.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,19 @@
+/* cprefix.h:  This file is included by assembly source which needs
+ *             to know what the c-label prefixes are. The newer versions
+ *	       of cpp that come with gcc predefine such things to help
+ *	       us out. The reason this stuff is needed is to make
+ *	       solaris compiles of the kernel work.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+#ifndef __NIOS_CPREFIX_H
+#define __NIOS_CPREFIX_H
+
+#define C_LABEL_PREFIX
+
+#define CONCAT(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a##b
+
+#define C_LABEL(name) CONCAT(C_LABEL_PREFIX, name)
+
+#endif /* !(__NIOS_CPREFIX_H) */
diff -urN linux-2.4.29/include/asm-niosnommu/current.h linux-2.4.29-uc1/include/asm-niosnommu/current.h
--- linux-2.4.29/include/asm-niosnommu/current.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/current.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,18 @@
+#ifndef _NIOS_CURRENT_H
+#define _NIOS_CURRENT_H
+
+struct task_struct;
+
+static inline struct task_struct * get_current(void)
+{
+	struct task_struct *current;
+	__asm__("mov %0, %%sp\n\t"
+		"lsri %0, 13\n\t"
+		"lsli %0, 13\n\t"
+		:"=r" (current));
+	return current;
+ }
+ 
+#define current get_current()
+
+#endif /* _NIOS_CURRENT_H */
diff -urN linux-2.4.29/include/asm-niosnommu/delay.h linux-2.4.29-uc1/include/asm-niosnommu/delay.h
--- linux-2.4.29/include/asm-niosnommu/delay.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/delay.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,44 @@
+#ifndef _NIOS_DELAY_H
+#define _NIOS_DELAY_H
+
+#include <asm/param.h>
+
+extern __inline__ void __delay(unsigned long loops)
+{
+	unsigned long dummy;
+	__asm__ __volatile__("cmpi %0, 0\n\t"
+			     "1: skps cc_eq\n\t"
+			     "br 1b\n\t"
+			     "subi %0, 1\n" 
+			     :
+			     "=&r" (dummy) :
+			     "0" (loops) :
+			     "cc");
+}
+
+/*
+ * Use only for very small delays ( < 1 msec).  Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays.  This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)  
+ */
+
+extern unsigned long loops_per_jiffy;
+
+extern __inline__ void udelay(unsigned long usecs)
+{
+	register unsigned long full_loops, part_loops;
+
+	full_loops = ((usecs * HZ) / 1000000) * loops_per_jiffy;
+	usecs %= (1000000 / HZ);
+	part_loops = (usecs * HZ * loops_per_jiffy) / 1000000;
+
+	__delay(full_loops + part_loops);
+}
+
+#define ndelay(nsecs) udelay((nsecs) * 5)
+
+#define muldiv(a, b, c)    (((a)*(b))/(c))
+
+#endif /* defined(_NIOS_DELAY_H) */
diff -urN linux-2.4.29/include/asm-niosnommu/div64.h linux-2.4.29-uc1/include/asm-niosnommu/div64.h
--- linux-2.4.29/include/asm-niosnommu/div64.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/div64.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-generic/div64.h>
diff -urN linux-2.4.29/include/asm-niosnommu/dma.h linux-2.4.29-uc1/include/asm-niosnommu/dma.h
--- linux-2.4.29/include/asm-niosnommu/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/dma.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,21 @@
+/*
+ * include/asm-sparc/dma.h
+ *
+ * Copyright 1995 (C) David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _ASM_SPARC_DMA_H
+#define _ASM_SPARC_DMA_H
+
+#include <linux/kernel.h>
+
+#define MAX_DMA_CHANNELS 2
+#define MAX_DMA_ADDRESS  (~0UL)
+#define DMA_MODE_READ    1
+#define DMA_MODE_WRITE   2
+
+extern int get_dma_list(char *);
+extern int request_dma(unsigned int, const char *);
+extern void free_dma(unsigned int);
+
+#endif /* !(_ASM_SPARC_DMA_H) */
diff -urN linux-2.4.29/include/asm-niosnommu/elf.h linux-2.4.29-uc1/include/asm-niosnommu/elf.h
--- linux-2.4.29/include/asm-niosnommu/elf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/elf.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,33 @@
+/* December 21, 2000 Ken Hill  */
+#ifndef __ASMNIOS_ELF_H
+#define __ASMNIOS_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef unsigned long elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x) == EM_NIOS)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_ARCH	EM_NIOS
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2MSB;
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	4096
+
+#endif
diff -urN linux-2.4.29/include/asm-niosnommu/errno.h linux-2.4.29-uc1/include/asm-niosnommu/errno.h
--- linux-2.4.29/include/asm-niosnommu/errno.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/errno.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,132 @@
+#ifndef _NIOS_ERRNO_H
+#define _NIOS_ERRNO_H
+
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Arg list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	EDEADLK		35	/* Resource deadlock would occur */
+#define	ENAMETOOLONG	36	/* File name too long */
+#define	ENOLCK		37	/* No record locks available */
+#define	ENOSYS		38	/* Function not implemented */
+#define	ENOTEMPTY	39	/* Directory not empty */
+#define	ELOOP		40	/* Too many symbolic links encountered */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	ENOMSG		42	/* No message of desired type */
+#define	EIDRM		43	/* Identifier removed */
+#define	ECHRNG		44	/* Channel number out of range */
+#define	EL2NSYNC	45	/* Level 2 not synchronized */
+#define	EL3HLT		46	/* Level 3 halted */
+#define	EL3RST		47	/* Level 3 reset */
+#define	ELNRNG		48	/* Link number out of range */
+#define	EUNATCH		49	/* Protocol driver not attached */
+#define	ENOCSI		50	/* No CSI structure available */
+#define	EL2HLT		51	/* Level 2 halted */
+#define	EBADE		52	/* Invalid exchange */
+#define	EBADR		53	/* Invalid request descriptor */
+#define	EXFULL		54	/* Exchange full */
+#define	ENOANO		55	/* No anode */
+#define	EBADRQC		56	/* Invalid request code */
+#define	EBADSLT		57	/* Invalid slot */
+
+#define	EDEADLOCK	EDEADLK
+
+#define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
+#define	EMULTIHOP	72	/* Multihop attempted */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EBADMSG		74	/* Not a data message */
+#define	EOVERFLOW	75	/* Value too large for defined data type */
+#define	ENOTUNIQ	76	/* Name not unique on network */
+#define	EBADFD		77	/* File descriptor in bad state */
+#define	EREMCHG		78	/* Remote address changed */
+#define	ELIBACC		79	/* Can not access a needed shared library */
+#define	ELIBBAD		80	/* Accessing a corrupted shared library */
+#define	ELIBSCN		81	/* .lib section in a.out corrupted */
+#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	EILSEQ		84	/* Illegal byte sequence */
+#define	ERESTART	85	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUSERS		87	/* Too many users */
+#define	ENOTSOCK	88	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	89	/* Destination address required */
+#define	EMSGSIZE	90	/* Message too long */
+#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	92	/* Protocol not available */
+#define	EPROTONOSUPPORT	93	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
+#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	96	/* Protocol family not supported */
+#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
+#define	EADDRINUSE	98	/* Address already in use */
+#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
+#define	ENETDOWN	100	/* Network is down */
+#define	ENETUNREACH	101	/* Network is unreachable */
+#define	ENETRESET	102	/* Network dropped connection because of reset */
+#define	ECONNABORTED	103	/* Software caused connection abort */
+#define	ECONNRESET	104	/* Connection reset by peer */
+#define	ENOBUFS		105	/* No buffer space available */
+#define	EISCONN		106	/* Transport endpoint is already connected */
+#define	ENOTCONN	107	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
+#define	ETIMEDOUT	110	/* Connection timed out */
+#define	ECONNREFUSED	111	/* Connection refused */
+#define	EHOSTDOWN	112	/* Host is down */
+#define	EHOSTUNREACH	113	/* No route to host */
+#define	EALREADY	114	/* Operation already in progress */
+#define	EINPROGRESS	115	/* Operation now in progress */
+#define	ESTALE		116	/* Stale NFS file handle */
+#define	EUCLEAN		117	/* Structure needs cleaning */
+#define	ENOTNAM		118	/* Not a XENIX named type file */
+#define	ENAVAIL		119	/* No XENIX semaphores available */
+#define	EISNAM		120	/* Is a named type file */
+#define	EREMOTEIO	121	/* Remote I/O error */
+#define	EDQUOT		122	/* Quota exceeded */
+
+#define	ENOMEDIUM	123	/* No medium found */
+#define	EMEDIUMTYPE	124	/* Wrong medium type */
+
+#endif /* _NIOS_ERRNO_H */
diff -urN linux-2.4.29/include/asm-niosnommu/fcntl.h linux-2.4.29-uc1/include/asm-niosnommu/fcntl.h
--- linux-2.4.29/include/asm-niosnommu/fcntl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/fcntl.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,87 @@
+//vic - update by copying from:
+#ifndef _M68K_FCNTL_H
+#define _M68K_FCNTL_H
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	  0003
+#define O_RDONLY	    00
+#define O_WRONLY	    01
+#define O_RDWR		    02
+#define O_CREAT		  0100	/* not fcntl */
+#define O_EXCL		  0200	/* not fcntl */
+#define O_NOCTTY	  0400	/* not fcntl */
+#define O_TRUNC		 01000	/* not fcntl */
+#define O_APPEND	 02000
+#define O_NONBLOCK	 04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC		010000
+#define FASYNC		020000	/* fcntl, for BSD compatibility */
+#define O_DIRECTORY	040000	/* must be a directory */
+#define O_NOFOLLOW	0100000	/* don't follow links */
+#define O_DIRECT	0200000	/* direct disk access hint - currently ignored */
+#define O_LARGEFILE	0400000
+
+#define F_DUPFD		0	/* dup */
+#define F_GETFD		1	/* get close_on_exec */
+#define F_SETFD		2	/* set/clear close_on_exec */
+#define F_GETFL		3	/* get file->f_flags */
+#define F_SETFL		4	/* set file->f_flags */
+#define F_GETLK		5
+#define F_SETLK		6
+#define F_SETLKW	7
+
+#define F_SETOWN	8	/*  for sockets. */
+#define F_GETOWN	9	/*  for sockets. */
+#define F_SETSIG	10	/*  for sockets. */
+#define F_GETSIG	11	/*  for sockets. */
+
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK		0
+#define F_WRLCK		1
+#define F_UNLCK		2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+/* for leases */
+#define F_INPROGRESS	16
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* or'd with one of the above to prevent
+				   blocking */
+#define LOCK_UN		8	/* remove lock */
+
+#define LOCK_MAND	32	/* This is a mandatory flock */
+#define LOCK_READ	64	/* ... Which allows concurrent read operations */
+#define LOCK_WRITE	128	/* ... Which allows concurrent write operations */
+#define LOCK_RW		192	/* ... Which allows concurrent read & write ops */
+
+struct flock {
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE	1024
+#endif /* _M68K_FCNTL_H */
diff -urN linux-2.4.29/include/asm-niosnommu/flat.h linux-2.4.29-uc1/include/asm-niosnommu/flat.h
--- linux-2.4.29/include/asm-niosnommu/flat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/flat.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,18 @@
+/*
+ * include/asm-niosnommu/flat.h -- uClinux flat-format executables
+ *
+ * this file is yet to be completed: davidm@snapgear.com
+ */
+
+#ifndef __NIOSNOMMU_FLAT_H__
+#define __NIOSNOMMU_FLAT_H__
+
+#define	flat_stack_align(sp)			XXXX
+#define	flat_argvp_envp_on_stack()		XXXX
+#define	flat_old_ram_flag(flags)		(flags)
+#define	flat_reloc_valid(reloc, size)		((reloc) <= (size))
+#define	flat_get_addr_from_rp(rp, relval, flags)	XXXX
+#define	flat_put_addr_at_rp(rp, val, relval)	XXXX
+#define	flat_get_relocate_addr(rel)		XXXX
+
+#endif /* __NIOSNOMMU_FLAT_H__ */
diff -urN linux-2.4.29/include/asm-niosnommu/hardirq.h linux-2.4.29-uc1/include/asm-niosnommu/hardirq.h
--- linux-2.4.29/include/asm-niosnommu/hardirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/hardirq.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,41 @@
+#ifndef __NIOS_HARDIRQ_H
+#define __NIOS_HARDIRQ_H
+
+#include <linux/config.h>
+#include <linux/threads.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned int __local_irq_count;
+	unsigned int __local_bh_count;
+	unsigned int __syscall_count;
+	struct task_struct * __ksoftirqd_task;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt() (local_irq_count(smp_processor_id()) + local_bh_count(smp_processor_id()) != 0)
+
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
+
+#ifndef CONFIG_SMP
+
+#define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
+#define hardirq_endlock(cpu)	do { } while (0)
+
+#define irq_enter(cpu, irq)	(local_irq_count(cpu)++)
+#define irq_exit(cpu, irq)	(local_irq_count(cpu)--)
+
+#define synchronize_irq()	barrier()
+
+#else
+
+#error niosnommu SMP is not available
+
+#endif /* CONFIG_SMP */
+
+#endif
diff -urN linux-2.4.29/include/asm-niosnommu/hdreg.h linux-2.4.29-uc1/include/asm-niosnommu/hdreg.h
--- linux-2.4.29/include/asm-niosnommu/hdreg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/hdreg.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,11 @@
+/*
+ *  Copyright (C) 1994-1996  Linus Torvalds & authors
+ *  Copyright (C) 2002  Wentau Xu (www.microtronix.com)
+ */
+
+#ifndef __NIOS_HDREG_H
+#define __NIOS_HDREG_H
+
+typedef unsigned long ide_ioreg_t;
+
+#endif /* __NIOS_HDREG_H */
diff -urN linux-2.4.29/include/asm-niosnommu/ide.h linux-2.4.29-uc1/include/asm-niosnommu/ide.h
--- linux-2.4.29/include/asm-niosnommu/ide.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/ide.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,127 @@
+//FIXME - copied from armnommu version - needs to be ported
+/*
+ *  linux/include/asm-niosnommu/ide.h
+ *
+ *  Copyright (C) 1994-1996  Linus Torvalds & authors
+ */
+
+/*
+ *  This file contains the nios architecture specific IDE code.
+ */
+
+#ifndef __ASMNIOS_IDE_H
+#define __ASMNIOS_IDE_H
+
+#ifdef __KERNEL__
+
+#include <asm/nios.h>
+
+
+#undef MAX_HWIFS		/* we're going to force it */
+
+#ifndef MAX_HWIFS
+#define MAX_HWIFS	1
+#endif
+
+
+#define ide__sti()	__sti()
+
+
+typedef union {
+	unsigned all			: 8;	/* all of the bits together */
+	struct {
+		unsigned head		: 4;	/* always zeros here */
+		unsigned unit		: 1;	/* drive select number, 0 or 1 */
+		unsigned bit5		: 1;	/* always 1 */
+		unsigned lba		: 1;	/* using LBA instead of CHS */
+		unsigned bit7		: 1;	/* always 1 */
+	} b;
+	} select_t;
+
+
+static __inline__ int ide_default_irq(ide_ioreg_t base)
+{
+	switch (base) {
+		case ((int) na_ide_interface)+0x40:
+			return na_ide_interface_irq;
+		default:
+			return 0;
+	}
+}
+
+static __inline__ ide_ioreg_t ide_default_io_base(int index)
+{
+	switch (index) {
+		case 0:
+			return ((int) na_ide_interface)+0x40;
+		default:
+			return 0;
+	}
+}
+
+static __inline__ void ide_init_hwif_ports(hw_regs_t *hw,
+					   ide_ioreg_t data_port,
+					   ide_ioreg_t ctrl_port, int *irq)
+{
+	ide_ioreg_t reg = data_port;
+	int i;
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = reg;
+		reg += 4;
+	}
+	if (ctrl_port) {
+		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+	} else {
+		hw->io_ports[IDE_CONTROL_OFFSET] = data_port + (0xE*4);
+	}
+	if (irq != NULL)
+		*irq = 0;
+	hw->io_ports[IDE_IRQ_OFFSET] = 0;
+}
+
+static __inline__ void ide_init_default_hwifs(void)
+{
+	hw_regs_t hw;
+	int index;
+	ide_ioreg_t base;
+
+	for (index = 0; index < MAX_HWIFS; index++) {
+		base = ide_default_io_base(index);
+		if (base == 0)
+			continue;
+		ide_init_hwif_ports(&hw, base, 0, NULL);
+		hw.irq = ide_default_irq(base);
+		ide_register_hw(&hw, NULL);
+	}
+}
+
+#define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
+#define ide_free_irq(irq,dev_id)		free_irq((irq), (dev_id))
+#define ide_check_region(from,extent)		check_region((from), (extent))
+#define ide_request_region(from,extent,name)	request_region((from), (extent), (name))
+#define ide_release_region(from,extent)		release_region((from), (extent))
+
+/*
+ * The following are not needed for the non-m68k ports
+ */
+#define ide_ack_intr(hwif)		(1)
+#define ide_fix_driveid(id)		do {} while (0)
+#define ide_release_lock(lock)		do {} while (0)
+#define ide_get_lock(lock, hdlr, data)	do {} while (0)
+
+/*
+ * We always use the new IDE port registering,
+ * so these are fixed here.
+ */
+//vic#define ide_default_io_base(i)		((ide_ioreg_t)0)
+//vic#define ide_default_irq(b)		(0)
+
+/* now for some arch-specific io functions */
+
+#define HAVE_ARCH_OUT_BYTE
+#define OUT_BYTE(b,p) outl((b),(p))
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASMNIOS_IDE_H */
diff -urN linux-2.4.29/include/asm-niosnommu/init.h linux-2.4.29-uc1/include/asm-niosnommu/init.h
--- linux-2.4.29/include/asm-niosnommu/init.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/init.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1 @@
+#error "<asm/init.h> should never be used - use <linux/init.h> instead"
diff -urN linux-2.4.29/include/asm-niosnommu/ioctl.h linux-2.4.29-uc1/include/asm-niosnommu/ioctl.h
--- linux-2.4.29/include/asm-niosnommu/ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/ioctl.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,79 @@
+/*
+ * linux/ioctl.h for Linux by H.H. Bergman.
+ */
+
+#ifndef _NIOS_IOCTL_H
+#define _NIOS_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * I don't really have any idea about what this should look like, so
+ * for the time being, this is heavily based on the PC definitions.
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	14
+#define _IOC_DIRBITS	2
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE	0U
+#define _IOC_WRITE	1U
+#define _IOC_READ	2U
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* _NIOS_IOCTL_H */
diff -urN linux-2.4.29/include/asm-niosnommu/ioctls.h linux-2.4.29-uc1/include/asm-niosnommu/ioctls.h
--- linux-2.4.29/include/asm-niosnommu/ioctls.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/ioctls.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,83 @@
+//vic - update by copying from:
+#ifndef __ARCH_M68K_IOCTLS_H__
+#define __ARCH_M68K_IOCTLS_H__
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+#define TIOCSBRK	0x5427  /* BSD compatibility */
+#define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define FIONCLEX	0x5450  /* these numbers need to be adjusted. */
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+
+#define	FIOQSIZE	0x545E
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+#endif /* __ARCH_M68K_IOCTLS_H__ */
diff -urN linux-2.4.29/include/asm-niosnommu/io.h linux-2.4.29-uc1/include/asm-niosnommu/io.h
--- linux-2.4.29/include/asm-niosnommu/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/io.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,130 @@
+#ifndef __NIOS_IO_H
+#define __NIOS_IO_H
+
+#include <linux/kernel.h>
+
+#include <asm/page.h>      /* IO address mapping routines need this */
+#include <asm/system.h>
+
+extern void insw(unsigned long port, void *dst, unsigned long count);
+extern void outsw(unsigned long port, void *src, unsigned long count);
+
+
+/*
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the Nios architecture, we just read/write the
+ * memory location directly.
+ */
+
+#define readb(addr) (*(volatile unsigned char *)  (addr))
+#define readw(addr) (*(volatile unsigned short *) (addr))
+#define readl(addr) (*(volatile unsigned int *)   (addr))
+
+#define writeb(b,addr) (*(volatile unsigned char *)  (addr) = (b))
+#define writew(b,addr) (*(volatile unsigned short *) (addr) = (b))
+#define writel(b,addr) (*(volatile unsigned int *)   (addr) = (b))
+
+
+/*
+ *	make the short names macros so specific devices
+ *	can override them as required
+ */
+
+#define inb(addr)    readb(addr)
+#define inw(addr)    readw(addr)
+#define inl(addr)    readl(addr)
+
+#define outb(x,addr) ((void) writeb(x,addr))
+#define outw(x,addr) ((void) writew(x,addr))
+#define outl(x,addr) ((void) writel(x,addr))
+
+#define inb_p(addr)    inb(addr)
+#define inw_p(addr)    inw(addr)
+#define inl_p(addr)    inl(addr)
+
+#define outb_p(x,addr) outb(x,addr)
+#define outw_p(x,addr) outw(x,addr)
+#define outl_p(x,addr) outl(x,addr)
+
+
+
+extern inline void insb(unsigned long port, void *dst, unsigned long count)
+{
+	while (count--)
+		*(((unsigned char *)dst)++) = inb(port);
+}
+
+/* See arch/niosnommu/io.c for optimized version */
+extern inline void _insw(unsigned long port, void *dst, unsigned long count)
+{
+	while (count--)
+		*(((unsigned short *)dst)++) = inw(port);
+}
+
+extern inline void insl(unsigned long port, void *dst, unsigned long count)
+{
+	while (count--)
+		*(((unsigned long *)dst)++) = inl(port);
+}
+
+extern inline void outsb(unsigned long port, void *src, unsigned long count)
+{
+	while (count--) 
+        outb( *(((unsigned char *)src)++), port );
+}
+
+/* See arch/niosnommu/io.c for optimized version */
+extern inline void _outsw(unsigned long port, void *src, unsigned long count)
+{
+	while (count--) 
+        outw( *(((unsigned short *)src)++), port );
+}
+
+extern inline void outsl(unsigned long port, void *src, unsigned long count)
+{
+	while (count--) 
+        outl( *(((unsigned long *)src)++), port );
+}
+
+
+
+extern inline void mapioaddr(unsigned long physaddr, unsigned long virt_addr,
+			     int bus, int rdonly)
+{
+	return;
+}
+
+//vic - copied from m68knommu
+
+/* Values for nocacheflag and cmode */
+#define IOMAP_FULL_CACHING		0
+#define IOMAP_NOCACHE_SER		1
+#define IOMAP_NOCACHE_NONSER		2
+#define IOMAP_WRITETHROUGH		3
+
+extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
+extern void __iounmap(void *addr, unsigned long size);
+
+extern inline void *ioremap(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+extern inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+extern inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
+}
+extern inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
+}
+
+extern void iounmap(void *addr);
+
+#define IO_SPACE_LIMIT 0xffff
+#endif /* !(__NIOS_IO_H) */
+
diff -urN linux-2.4.29/include/asm-niosnommu/ipcbuf.h linux-2.4.29-uc1/include/asm-niosnommu/ipcbuf.h
--- linux-2.4.29/include/asm-niosnommu/ipcbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/ipcbuf.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,29 @@
+#ifndef __NIOS_IPCBUF_H__
+#define __NIOS_IPCBUF_H__
+
+/* Copied from asm-m68k/ipcbuf.h
+ * The user_ipc_perm structure for Nios architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
+	__kernel_mode_t		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* __NIOS_IPCBUF_H__ */
diff -urN linux-2.4.29/include/asm-niosnommu/ipc.h linux-2.4.29-uc1/include/asm-niosnommu/ipc.h
--- linux-2.4.29/include/asm-niosnommu/ipc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/ipc.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef __NIOS_IPC_H__
+#define __NIOS_IPC_H__
+
+/* Copied from sparc version
+ * These are used to wrap system calls on the Nios.
+ *
+ * See arch/niosnommu/kernel/sys_nios.c for ugly details..
+ */
+struct ipc_kludge {
+	struct msgbuf *msgp;
+	long msgtyp;
+};
+
+#define SEMOP		 1
+#define SEMGET		 2
+#define SEMCTL		 3
+#define MSGSND		11
+#define MSGRCV		12
+#define MSGGET		13
+#define MSGCTL		14
+#define SHMAT		21
+#define SHMDT		22
+#define SHMGET		23
+#define SHMCTL		24
+
+/* Used by the DIPC package, try and avoid reusing it */
+#define DIPC            25
+
+#define IPCCALL(version,op)	((version)<<16 | (op))
+
+#endif
diff -urN linux-2.4.29/include/asm-niosnommu/irq.h linux-2.4.29-uc1/include/asm-niosnommu/irq.h
--- linux-2.4.29/include/asm-niosnommu/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/irq.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,108 @@
+/*
+  21Mar2001    1.1    dgt/microtronix
+*/
+
+
+#ifndef _NIOSNOMMU_IRQ_H_
+#define _NIOSNOMMU_IRQ_H_
+
+extern void disable_irq(unsigned int);
+extern void enable_irq(unsigned int);
+
+#include <linux/config.h>
+
+#define	SYS_IRQS	64
+#define	NR_IRQS		SYS_IRQS
+
+/*
+ * Interrupt source definitions
+ * General interrupt sources are the level 1-7.
+ * Adding an interrupt service routine for one of these sources
+ * results in the addition of that routine to a chain of routines.
+ * Each one is called in succession.  Each individual interrupt
+ * service routine should determine if the device associated with
+ * that routine requires service.
+ */
+
+//#define IRQ1		(1)	/* level 1  interrupt */
+//#define IRQ2		(2)	/* level 2  interrupt */
+//#define IRQ3		(3)	/* level 3  interrupt */
+//#define IRQ4		(4)	/* level 4  interrupt */
+//#define IRQ5		(5)	/* level 5  interrupt */
+//#define IRQ6		(6)	/* level 6  interrupt */
+//#define IRQ7		(7)	/* level 7  interrupt */
+//#define IRQ8		(8)	/* level 8  interrupt */
+//#define IRQ9		(9)	/* level 9  interrupt */
+//#define IRQA		(10)	/* level 10 interrupt */
+//#define IRQB		(11)	/* level 11 interrupt */
+//#define IRQC		(12)	/* level 12 interrupt */
+//#define IRQD		(13)	/* level 13 interrupt */
+//#define IRQE		(14)	/* level 14 interrupt */
+//#define IRQF		(15)	/* level 15 interrupt */
+//
+//#define IRQMAX		IRQF
+
+#define IRQMIN		16
+#define IRQMAX		SYS_IRQS-1
+
+/*
+ * "Generic" interrupt sources
+ */
+
+//#define IRQ_SCHED_TIMER	IRQ8    /* interrupt source for scheduling timer */
+
+/*
+ * Machine specific interrupt sources.
+ *
+ * Adding an interrupt service routine for a source with this bit
+ * set indicates a special machine specific interrupt source.
+ * The machine specific files define these sources.
+ */
+
+  #define IRQ_MACHSPEC	(0)
+//#define IRQ_MACHSPEC	(0x10000000L)
+
+#define IRQ_IDX(irq)	((irq) & ~IRQ_MACHSPEC)
+
+/*
+ * various flags for request_irq()
+ */
+#define IRQ_FLG_LOCK	(0x0001)	/* handler is not replaceable	*/
+#define IRQ_FLG_REPLACE	(0x0002)	/* replace existing handler	*/
+#define IRQ_FLG_FAST	(0x0004)
+#define IRQ_FLG_SLOW	(0x0008)
+#define IRQ_FLG_STD	(0x8000)	/* internally used		*/
+
+/*
+ * This structure is used to chain together the ISRs for a particular
+ * interrupt source (if it supports chaining).
+ */
+typedef struct irq_node {
+	void		(*handler)(int, void *, struct pt_regs *);
+	unsigned long	flags;
+	void		*dev_id;
+	const char	*devname;
+	struct irq_node *next;
+} irq_node_t;
+
+/*
+ * This function returns a new irq_node_t
+ */
+extern irq_node_t *new_irq_node(void);
+
+/*
+ * This structure has only 4 elements for speed reasons
+ */
+typedef struct irq_handler {
+	void		(*handler)(int, void *, struct pt_regs *);
+	unsigned long	flags;
+	void		*dev_id;
+	const char	*devname;
+} irq_handler_t;
+
+/* count of spurious interrupts */
+extern volatile unsigned int num_spurious;
+
+#define disable_irq_nosync(i) disable_irq(i)
+
+#endif /* _NIOSNOMMU_IRQ_H_ */
diff -urN linux-2.4.29/include/asm-niosnommu/kbio.h linux-2.4.29-uc1/include/asm-niosnommu/kbio.h
--- linux-2.4.29/include/asm-niosnommu/kbio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/kbio.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,37 @@
+#ifndef __LINUX_KBIO_H
+#define __LINUX_KBIO_H
+
+/* Return keyboard type */
+#define KIOCTYPE    _IOR('k', 9, int)
+/* Return Keyboard layout */
+#define KIOCLAYOUT  _IOR('k', 20, int)
+
+enum {
+    TR_NONE,
+    TR_ASCII,			/* keyboard is in regular state */
+    TR_EVENT,			/* keystrokes sent as firm events */
+    TR_UNTRANS_EVENT		/* EVENT+up and down+no translation */
+};
+
+/* Return the current keyboard translation */
+#define KIOCGTRANS  _IOR('k', 5, int)
+/* Set the keyboard translation */
+#define KIOCTRANS   _IOW('k', 0, int)
+
+/* Send a keyboard command */
+#define KIOCCMD	    _IOW('k', 8, int)
+
+/* Return if keystrokes are being sent to /dev/kbd */
+
+/* Set routing of keystrokes to /dev/kbd */
+#define KIOCSDIRECT _IOW('k', 10, int)
+
+/* Top bit records if the key is up or down */
+#define KBD_UP	    0x80
+
+/* Usable information */
+#define KBD_KEYMASK 0x7f
+
+/* All keys up */
+#define KBD_IDLE    0x75
+#endif /* __LINUX_KBIO_H */
diff -urN linux-2.4.29/include/asm-niosnommu/keyboard.h linux-2.4.29-uc1/include/asm-niosnommu/keyboard.h
--- linux-2.4.29/include/asm-niosnommu/keyboard.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/keyboard.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,29 @@
+/*
+ *  linux/include/asm-niosnommu/keyboard.h
+ *
+  */
+
+/*
+ *  This file contains the nios architecture specific keyboard definitions
+ */
+
+#ifndef __NIOS_KEYBOARD_H
+#define __NIOS_KEYBOARD_H
+
+#define kbd_setkeycode(x...)	(-ENOSYS)
+#define kbd_getkeycode(x...)	(-ENOSYS)
+#define kbd_translate(x...)	(0)
+#define kbd_unexpected_up(x...)	(1)
+#define kbd_leds(x...)		do {;} while (0)
+#define kbd_init_hw(x...)	do {;} while (0)
+#define kbd_enable_irq(x...)	do {;} while (0)
+#define kbd_disable_irq(x...)	do {;} while (0)
+
+
+/* needed if MAGIC_SYSRQ is enabled for serial console */
+#ifndef SYSRQ_KEY
+#define SYSRQ_KEY		((unsigned char)(-1))
+#endif
+#define kbd_sysrq_xlate         ((unsigned char *)NULL)
+
+#endif /* __NIOS_KEYBOARD_H */
diff -urN linux-2.4.29/include/asm-niosnommu/linux_logo.h linux-2.4.29-uc1/include/asm-niosnommu/linux_logo.h
--- linux-2.4.29/include/asm-niosnommu/linux_logo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/linux_logo.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,934 @@
+/*
+ * include/asm-nios/linux_logo.h: This is a linux logo
+ *                                 to be displayed on boot.
+ *
+ * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
+ * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ *
+ * You can put anything here, but:
+ * LINUX_LOGO_COLORS has to be less than 224
+ * image size has to be 80x80
+ * values have to start from 0x20
+ * (i.e. RGB(linux_logo_red[0],
+ *	     linux_logo_green[0],
+ *	     linux_logo_blue[0]) is color 0x20)
+ * BW image has to be 80x80 as well, with MS bit
+ * on the left
+ * Serial_console ascii image can be any size,
+ * but should contain %s to display the version
+ */
+ 
+#include <linux/init.h>
+#include <linux/version.h>
+
+#define linux_logo_banner "Linux/NIOS version " UTS_RELEASE
+
+#define __HAVE_ARCH_LINUX_LOGO
+#define __HAVE_ARCH_LINUX_LOGO16
+
+#define LINUX_LOGO_COLORS	221
+
+#ifdef INCLUDE_LINUX_LOGO_DATA
+
+unsigned char linux_logo_red[] __initdata = {
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x65, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x76, 0x79,
+    0x62, 0x36, 0x9a, 0xe2, 0xec, 0xe1, 0xb8, 0xd7,
+    0xaf, 0x25, 0xbc, 0xc0, 0xef, 0xea, 0xe8, 0xe8,
+    0xf5, 0xf1, 0xda, 0xd3, 0x79, 0xdb, 0xf4, 0xf6,
+    0xf6, 0xf6, 0xe2, 0x3d, 0xb4, 0xce, 0xe6, 0xee,
+    0xf6, 0x68, 0xd8, 0xec, 0xf5, 0xc6, 0xc8, 0x9c,
+    0x89, 0xd2, 0xee, 0xcb, 0xb9, 0xd2, 0x66, 0x5e,
+    0x8b, 0xbe, 0xa8, 0xd5, 0xca, 0xb6, 0xae, 0x9c,
+    0xc5, 0xbe, 0xbe, 0xca, 0x90, 0xb2, 0x9a, 0xa8,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xfe,
+    0xf6, 0xec, 0xfe, 0xd2, 0xea, 0xf5, 0xf2, 0xf2,
+    0xe9, 0xee, 0xf6, 0xf2, 0xee, 0xf6, 0xda, 0xd4,
+    0xfa, 0xca, 0xf2, 0xf6, 0xfe, 0xf2, 0xda, 0xe4,
+    0xf6, 0xdd, 0xf2, 0xee, 0xfa, 0xf0, 0x12, 0x4a,
+    0xd6, 0xf2, 0x8e, 0xf2, 0xf6, 0xf6, 0xb5, 0xf1,
+    0x26, 0x9a, 0xea, 0xf6, 0xe0, 0xd2, 0x16, 0x9a,
+    0x2e, 0xd2, 0x70, 0xd6, 0x46, 0x7c, 0xb4, 0x62,
+    0xda, 0xee, 0xd6, 0xa3, 0x74, 0xa7, 0xa2, 0xe0,
+    0xae, 0xbe, 0xce, 0xe2, 0xa3, 0x8e, 0x6d, 0x8e,
+    0x32, 0xaf, 0x50, 0x9e, 0x5b, 0x8a, 0x98, 0x82,
+    0x7a, 0x82, 0x56, 0x7c, 0x8a, 0x56, 0x5e, 0x86,
+    0x6a, 0x52, 0x59, 0x64, 0x5e,
+};
+
+unsigned char linux_logo_green[] __initdata = {
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x62, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x62, 0x5c,
+    0x4e, 0x26, 0x72, 0xaa, 0xba, 0xaf, 0x90, 0xae,
+    0x92, 0x1a, 0xa4, 0x85, 0xb6, 0xbe, 0xc3, 0xc8,
+    0xcf, 0xd0, 0xc2, 0xce, 0x57, 0xa2, 0xd6, 0xda,
+    0xda, 0xd7, 0xb8, 0x2a, 0x7b, 0x91, 0xae, 0xca,
+    0xda, 0x45, 0x9e, 0xb2, 0xd7, 0x9b, 0x90, 0x76,
+    0x5c, 0xa2, 0xbe, 0xa6, 0x85, 0x96, 0x4e, 0x46,
+    0x66, 0x92, 0x7a, 0x9a, 0x96, 0x9d, 0x9a, 0x6b,
+    0x8a, 0x8e, 0xb2, 0xca, 0x90, 0xa6, 0x79, 0x7c,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xfa,
+    0xea, 0xd7, 0xf6, 0xbc, 0xda, 0xde, 0xda, 0xe6,
+    0xca, 0xd8, 0xea, 0xe0, 0xcc, 0xf2, 0xce, 0xb2,
+    0xee, 0xa2, 0xd6, 0xe6, 0xf6, 0xd7, 0xc5, 0xb8,
+    0xc6, 0xb9, 0xce, 0xde, 0xce, 0xc6, 0x0e, 0x36,
+    0xae, 0xbe, 0x86, 0xba, 0xbe, 0xe6, 0x8e, 0xc4,
+    0x1e, 0x8e, 0xae, 0xba, 0xb2, 0xa6, 0x12, 0x7a,
+    0x20, 0xc6, 0x64, 0xaa, 0x2f, 0x70, 0x85, 0x46,
+    0xce, 0xd6, 0xa6, 0x6e, 0x51, 0x72, 0x92, 0xa6,
+    0x87, 0x96, 0xa2, 0xd6, 0x85, 0x7a, 0x6a, 0x6e,
+    0x22, 0x76, 0x36, 0x76, 0x3c, 0x6e, 0x63, 0x53,
+    0x66, 0x62, 0x42, 0x50, 0x56, 0x42, 0x56, 0x56,
+    0x56, 0x3e, 0x51, 0x52, 0x56,
+};
+
+unsigned char linux_logo_blue[] __initdata = {
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x01, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x06, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x59, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x2e, 0x08,
+    0x0a, 0x06, 0x0a, 0x0b, 0x0b, 0x0f, 0x0c, 0x0f,
+    0x3d, 0x09, 0x73, 0x09, 0x0d, 0x0a, 0x10, 0x1e,
+    0x2d, 0x13, 0x86, 0xba, 0x19, 0x0a, 0x36, 0x3c,
+    0x26, 0x14, 0x0d, 0x06, 0x07, 0x0a, 0x0b, 0x0f,
+    0x4a, 0x06, 0x0a, 0x0c, 0x2b, 0x0a, 0x0b, 0x0a,
+    0x06, 0x0a, 0x0a, 0x11, 0x0b, 0x0a, 0x0a, 0x1e,
+    0x0f, 0x0d, 0x0a, 0x0b, 0x22, 0x6a, 0x72, 0x0b,
+    0x0b, 0x22, 0x90, 0xca, 0x90, 0x92, 0x3c, 0x2c,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xea,
+    0xb6, 0x7c, 0xda, 0x8e, 0xa6, 0x87, 0x66, 0xb6,
+    0x81, 0x6a, 0xc6, 0x9a, 0x5b, 0xd2, 0xb6, 0x6a,
+    0xca, 0x45, 0x92, 0xb2, 0xca, 0x52, 0x8a, 0x3e,
+    0x2e, 0x66, 0x66, 0xae, 0x3e, 0x47, 0x06, 0x0e,
+    0x52, 0x36, 0x6a, 0x0e, 0x0e, 0xbe, 0x2c, 0x0e,
+    0x0a, 0x5a, 0x0d, 0x0e, 0x3e, 0x0a, 0x06, 0x2e,
+    0x06, 0x9e, 0x4e, 0x36, 0x06, 0x58, 0x24, 0x06,
+    0x9e, 0xae, 0x3a, 0x08, 0x08, 0x07, 0x5e, 0x0a,
+    0x32, 0x2e, 0x2a, 0xb2, 0x43, 0x48, 0x5f, 0x2e,
+    0x06, 0x06, 0x07, 0x24, 0x06, 0x32, 0x06, 0x06,
+    0x46, 0x2e, 0x22, 0x06, 0x06, 0x1e, 0x4c, 0x06,
+    0x3a, 0x22, 0x42, 0x34, 0x42,
+};
+
+unsigned char linux_logo[] __initdata = {
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
+    0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+    0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d,
+    0x2d, 0x2e, 0x2c, 0x2b, 0x2a, 0x25, 0x28, 0x22,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x24, 0x2a, 0x2c, 0x2f, 0x2c, 0x30, 0x30, 0x24,
+    0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25,
+    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
+    0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c,
+    0x30, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
+    0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x31,
+    0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x2a, 0x34,
+    0x25, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36,
+    0x2a, 0x2d, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2c, 0x35,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x25, 0x2f, 0x37, 0x32, 0x22,
+    0x36, 0x35, 0x31, 0x27, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x22,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x26, 0x38, 0x38, 0x35, 0x25,
+    0x36, 0x21, 0x2d, 0x2b, 0x24, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x24, 0x39, 0x39, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22,
+    0x36, 0x36, 0x27, 0x34, 0x30, 0x23, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x26, 0x2d, 0x26, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x2d, 0x33, 0x28, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x2b, 0x2c, 0x25, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36,
+    0x36, 0x21, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
+    0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36,
+    0x36, 0x36, 0x36, 0x22, 0x2f, 0x2a, 0x23, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
+    0x30, 0x3a, 0x38, 0x24, 0x24, 0x36, 0x36, 0x36,
+    0x23, 0x2f, 0x3b, 0x3c, 0x3d, 0x30, 0x25, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23,
+    0x3e, 0x3f, 0x40, 0x3a, 0x22, 0x36, 0x36, 0x21,
+    0x41, 0x42, 0x43, 0x44, 0x45, 0x3e, 0x23, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x2b,
+    0x44, 0x40, 0x46, 0x47, 0x35, 0x36, 0x36, 0x26,
+    0x43, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x2e, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4d,
+    0x4e, 0x25, 0x2f, 0x46, 0x4a, 0x22, 0x23, 0x32,
+    0x4f, 0x50, 0x21, 0x31, 0x51, 0x52, 0x53, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3a,
+    0x4d, 0x21, 0x31, 0x54, 0x55, 0x28, 0x30, 0x2b,
+    0x4b, 0x4d, 0x36, 0x23, 0x32, 0x50, 0x3f, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x38, 0x23, 0x37,
+    0x55, 0x36, 0x28, 0x3a, 0x56, 0x57, 0x57, 0x58,
+    0x3c, 0x4d, 0x36, 0x36, 0x36, 0x40, 0x40, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x51, 0x23, 0x35,
+    0x43, 0x25, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
+    0x5f, 0x60, 0x61, 0x36, 0x31, 0x47, 0x3b, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22,
+    0x40, 0x62, 0x63, 0x5d, 0x64, 0x65, 0x66, 0x67,
+    0x68, 0x69, 0x66, 0x5e, 0x6a, 0x6b, 0x2a, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x2f, 0x23, 0x36,
+    0x6c, 0x63, 0x6d, 0x64, 0x5c, 0x66, 0x69, 0x6e,
+    0x6f, 0x70, 0x71, 0x69, 0x69, 0x72, 0x6c, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x33, 0x34, 0x27, 0x22,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x73,
+    0x74, 0x75, 0x76, 0x64, 0x65, 0x77, 0x69, 0x78,
+    0x70, 0x71, 0x71, 0x71, 0x72, 0x5f, 0x5e, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x25, 0x38, 0x2a, 0x23,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x79,
+    0x63, 0x7a, 0x7b, 0x5c, 0x66, 0x69, 0x6e, 0x7c,
+    0x71, 0x71, 0x69, 0x7d, 0x7e, 0x7a, 0x7f, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x21, 0x51, 0x2b, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x32, 0x24,
+    0x80, 0x81, 0x64, 0x82, 0x77, 0x69, 0x71, 0x71,
+    0x69, 0x83, 0x84, 0x85, 0x7a, 0x85, 0x86, 0x36,
+    0x21, 0x2b, 0x23, 0x36, 0x36, 0x39, 0x2e, 0x26,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21,
+    0x87, 0x88, 0x89, 0x72, 0x67, 0x66, 0x5f, 0x89,
+    0x8a, 0x63, 0x85, 0x8b, 0x8c, 0x8d, 0x41, 0x36,
+    0x36, 0x2d, 0x3a, 0x35, 0x36, 0x24, 0x51, 0x32,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21,
+    0x55, 0x8e, 0x8f, 0x8a, 0x7d, 0x5e, 0x90, 0x7e,
+    0x75, 0x75, 0x90, 0x62, 0x40, 0x3f, 0x49, 0x23,
+    0x36, 0x24, 0x3a, 0x3a, 0x24, 0x36, 0x2e, 0x31,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x28, 0x33, 0x37, 0x25, 0x22,
+    0x3b, 0x50, 0x8e, 0x8f, 0x90, 0x7e, 0x90, 0x63,
+    0x74, 0x91, 0x92, 0x42, 0x93, 0x4b, 0x45, 0x2c,
+    0x36, 0x36, 0x33, 0x39, 0x21, 0x36, 0x22, 0x51,
+    0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21,
+    0x94, 0x3f, 0x50, 0x95, 0x96, 0x8f, 0x8f, 0x97,
+    0x8e, 0x42, 0x50, 0x43, 0x47, 0x48, 0x48, 0x98,
+    0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39,
+    0x2e, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x22, 0x24, 0x2b, 0x38, 0x28, 0x36, 0x32,
+    0x4c, 0x4b, 0x50, 0x50, 0x50, 0x42, 0x42, 0x50,
+    0x50, 0x40, 0x45, 0x99, 0x48, 0x48, 0x48, 0x48,
+    0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23,
+    0x2f, 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x32, 0x51, 0x32, 0x28, 0x21, 0x98,
+    0x48, 0x47, 0x9a, 0x50, 0x50, 0x50, 0x50, 0x50,
+    0x9a, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x93, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x2a, 0x2f, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x51, 0x9b,
+    0x48, 0x48, 0x52, 0x3f, 0x50, 0x50, 0x40, 0x4b,
+    0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2d, 0x31, 0x27, 0x23, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x44, 0x48,
+    0x48, 0x48, 0x48, 0x47, 0x46, 0x4f, 0x47, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x9c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x28, 0x51, 0x39, 0x26, 0x22, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
+    0x35, 0x51, 0x28, 0x36, 0x36, 0x9d, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x4f, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x28, 0x38, 0x2b, 0x25, 0x22, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
+    0x51, 0x25, 0x36, 0x36, 0x23, 0x40, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x9b, 0x99, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x30, 0x2f, 0x33, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x30, 0x34,
+    0x27, 0x36, 0x36, 0x36, 0x2a, 0x40, 0x47, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x99, 0x99, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x47, 0x52,
+    0x46, 0x4f, 0x37, 0x21, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x30, 0x34, 0x2a, 0x23,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x39, 0x2c,
+    0x36, 0x36, 0x36, 0x21, 0x31, 0x4e, 0x9a, 0x4c,
+    0x47, 0x9b, 0x9b, 0x52, 0x46, 0x4f, 0x52, 0x9b,
+    0x9b, 0x9b, 0x47, 0x4f, 0x45, 0x9a, 0x93, 0x93,
+    0x3f, 0x93, 0x98, 0x28, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c, 0x26,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x28,
+    0x36, 0x36, 0x36, 0x22, 0x38, 0x98, 0x44, 0x99,
+    0x9b, 0x48, 0x48, 0x9b, 0x4c, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x47, 0x52, 0x46, 0x43, 0x93,
+    0x40, 0x40, 0x43, 0x53, 0x21, 0x23, 0x33, 0x23,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x2f, 0x32,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x24, 0x2b, 0x31, 0x36,
+    0x36, 0x22, 0x36, 0x24, 0x9e, 0x4f, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x99, 0x9f, 0x52, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47,
+    0x4f, 0x9a, 0x3f, 0x46, 0x38, 0x36, 0x21, 0x30,
+    0x26, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c,
+    0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2e, 0x33, 0x36,
+    0x25, 0x25, 0x36, 0x4d, 0x52, 0x48, 0x48, 0x48,
+    0x47, 0x9f, 0x48, 0x48, 0x48, 0xa0, 0xa1, 0xa2,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x47, 0x44, 0x93, 0x43, 0x23, 0x36, 0x36,
+    0x26, 0x24, 0x36, 0x36, 0x36, 0x36, 0x28, 0x2f,
+    0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x51, 0x24, 0x36,
+    0x2a, 0x36, 0x28, 0x44, 0x48, 0x48, 0x48, 0x48,
+    0xa3, 0xa4, 0x48, 0x48, 0x9f, 0xa5, 0xa6, 0x9f,
+    0x48, 0x48, 0x48, 0xa2, 0xa7, 0x47, 0x48, 0x48,
+    0x48, 0x48, 0x9b, 0x4b, 0x44, 0x37, 0x36, 0x23,
+    0x28, 0x30, 0x22, 0x36, 0x36, 0x36, 0x36, 0x2d,
+    0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x28, 0x2b, 0x34, 0x36, 0x25,
+    0x24, 0x36, 0x4a, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0xa8, 0xa1, 0x48, 0x48, 0x9f, 0xa9, 0xa6, 0x9f,
+    0x48, 0x48, 0xaa, 0xa1, 0xa5, 0x9f, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x52, 0x3f, 0x21, 0x30,
+    0x35, 0x25, 0x30, 0x36, 0x36, 0x36, 0x36, 0x32,
+    0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x22, 0x26, 0x2e, 0x35, 0x36, 0x2a,
+    0x36, 0x24, 0x4f, 0x48, 0x52, 0x52, 0x48, 0x48,
+    0xab, 0xac, 0xa0, 0x48, 0xad, 0xa6, 0xa6, 0x9f,
+    0x48, 0xa2, 0xa9, 0xa6, 0xa2, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x47, 0x32, 0x30,
+    0x2a, 0x23, 0x30, 0x23, 0x36, 0x36, 0x36, 0x21,
+    0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x2a, 0x51, 0x28, 0x28, 0x25,
+    0x36, 0x3a, 0x48, 0x48, 0xae, 0xaf, 0x48, 0x48,
+    0xad, 0xac, 0xa1, 0x9f, 0xa2, 0xa9, 0xa9, 0xa2,
+    0x48, 0xab, 0x78, 0xa7, 0x48, 0x48, 0x48, 0x48,
+    0x9f, 0x48, 0x48, 0x48, 0x48, 0x48, 0x38, 0x21,
+    0x36, 0x36, 0x22, 0x27, 0x36, 0x36, 0x36, 0x36,
+    0x2e, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x22, 0x25, 0x2c, 0x34, 0x36, 0x30, 0x21,
+    0x23, 0x43, 0x48, 0x48, 0xb0, 0xb1, 0xb2, 0x9f,
+    0x48, 0xb3, 0xa5, 0xb3, 0xab, 0xa9, 0xa9, 0xb3,
+    0xb4, 0xa9, 0xb5, 0xb0, 0x48, 0x48, 0xa0, 0xa5,
+    0xa1, 0xad, 0x48, 0x48, 0x48, 0x48, 0x94, 0x36,
+    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
+    0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x2a, 0x51, 0x25, 0x21, 0x2a, 0x36,
+    0x2e, 0x9b, 0x48, 0x48, 0x48, 0xb6, 0xb7, 0xa4,
+    0xa2, 0xa7, 0xb5, 0x78, 0x6f, 0x6f, 0x6e, 0x6f,
+    0xa9, 0xb5, 0xab, 0x48, 0x9f, 0xab, 0xa9, 0xa1,
+    0xaa, 0x48, 0x48, 0x48, 0x48, 0x48, 0x98, 0x36,
+    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
+    0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x22, 0x25, 0x2c, 0x34, 0x36, 0x24, 0x28, 0x36,
+    0x54, 0x48, 0x48, 0x48, 0x48, 0xa2, 0xa8, 0xa1,
+    0xa5, 0xa6, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f,
+    0x6f, 0x78, 0xa5, 0xa0, 0xa0, 0x78, 0xa6, 0xa2,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
+    0x36, 0x36, 0x36, 0x30, 0x36, 0x36, 0x36, 0x36,
+    0x21, 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x28, 0x32, 0x2f, 0x28, 0x36, 0x27, 0x22, 0x21,
+    0x43, 0x48, 0x4b, 0xa2, 0x9f, 0x48, 0xa2, 0xa1,
+    0xb8, 0x6e, 0x6e, 0xb5, 0x78, 0x6f, 0x78, 0x78,
+    0x6e, 0x6f, 0x78, 0xb5, 0xa6, 0xa1, 0xa0, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4b, 0x21,
+    0x36, 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x25, 0x2c, 0x39, 0x36, 0x36, 0x30, 0x22, 0x25,
+    0x52, 0x48, 0xa3, 0xb1, 0xb6, 0xb3, 0xaa, 0xac,
+    0x68, 0x68, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
+    0x78, 0x6f, 0x6f, 0xb5, 0xa6, 0xb4, 0x48, 0x9f,
+    0xb4, 0xb4, 0xa2, 0x9f, 0x48, 0x48, 0x4f, 0x21,
+    0x36, 0x36, 0x22, 0x26, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x30, 0x2d, 0x21, 0x36, 0x36, 0x32, 0x23, 0x2a,
+    0x47, 0x48, 0xa2, 0xb6, 0xaf, 0xb9, 0xba, 0x68,
+    0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x78,
+    0x6f, 0x6f, 0xa6, 0x6f, 0xb5, 0xa0, 0xaa, 0xa6,
+    0xa6, 0xa9, 0xb2, 0xb3, 0x48, 0x48, 0x4c, 0x22,
+    0x36, 0x36, 0x24, 0x23, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0x2e, 0x36, 0x36, 0x23, 0x31, 0x27, 0x39,
+    0x9b, 0x48, 0x48, 0x48, 0xb0, 0xb0, 0xba, 0xb8,
+    0x68, 0x68, 0x69, 0x78, 0x6f, 0xb5, 0x6f, 0xb5,
+    0x78, 0x78, 0x78, 0x78, 0x78, 0xa5, 0xbb, 0xa9,
+    0xa5, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x23,
+    0x36, 0x36, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x2b, 0x39, 0x36, 0x36, 0x36, 0x26, 0x32, 0x31,
+    0x9b, 0x48, 0x48, 0x48, 0x48, 0x9f, 0xac, 0x68,
+    0xbc, 0x6e, 0x6e, 0x6e, 0xb5, 0x6f, 0x6e, 0x6f,
+    0x6f, 0x78, 0x78, 0xb5, 0xb5, 0xa5, 0x9f, 0x9f,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x46, 0x22,
+    0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x35, 0x39, 0x36, 0x36, 0x36, 0x36, 0x26, 0x2d,
+    0x9b, 0x48, 0x48, 0xb0, 0xaa, 0xb3, 0xbd, 0xb8,
+    0xb8, 0x68, 0x6e, 0x6e, 0xb5, 0x6f, 0x78, 0x6e,
+    0x78, 0x6f, 0x78, 0x78, 0xb5, 0xa9, 0xa2, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
+    0x24, 0x27, 0xbe, 0x24, 0x25, 0x28, 0x21, 0x36,
+    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
+    0x39, 0x4d, 0xbf, 0x84, 0x81, 0x57, 0x21, 0x39,
+    0x52, 0x48, 0x48, 0x62, 0xb1, 0xc0, 0xc1, 0xc1,
+    0xb8, 0xb8, 0x68, 0xbc, 0x6e, 0x6e, 0x6e, 0x78,
+    0x78, 0x78, 0x78, 0x6e, 0x78, 0xa9, 0xa0, 0xab,
+    0xb3, 0xa2, 0x48, 0x48, 0x48, 0x48, 0x53, 0x28,
+    0x23, 0x36, 0x36, 0x36, 0x21, 0x28, 0x2c, 0x30,
+    0x21, 0x38, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30,
+    0x2d, 0xc2, 0x7a, 0xc3, 0xc4, 0xc4, 0x7f, 0x22,
+    0x51, 0x52, 0x48, 0x48, 0xb0, 0xaa, 0xa8, 0xbd,
+    0x68, 0xb8, 0xb8, 0x68, 0x68, 0x6e, 0x6e, 0x6f,
+    0x6e, 0x6e, 0xb5, 0x6e, 0x78, 0xab, 0xab, 0xb5,
+    0x78, 0xa6, 0xb3, 0xc5, 0xac, 0xac, 0xc6, 0x61,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32,
+    0x25, 0x4d, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31,
+    0x4d, 0x91, 0x5b, 0xc3, 0xc4, 0xc4, 0xc4, 0x5a,
+    0x21, 0x2e, 0x46, 0x48, 0x48, 0x48, 0xb0, 0x64,
+    0xc1, 0xb8, 0xb8, 0xb8, 0x68, 0x71, 0x6e, 0x6e,
+    0x6f, 0x71, 0x6f, 0x6f, 0xa6, 0xa0, 0x9f, 0xb4,
+    0xb4, 0xa0, 0xa1, 0xb7, 0xc7, 0x69, 0x66, 0xc8,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25,
+    0x83, 0xc9, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x30, 0x35, 0x2d, 0x2f, 0x37, 0x4a,
+    0x60, 0x85, 0xca, 0xcb, 0xc4, 0xc4, 0xc4, 0x82,
+    0x86, 0x36, 0x32, 0x3f, 0xa2, 0xa4, 0xa8, 0xa9,
+    0xb8, 0xb8, 0xb8, 0xb8, 0x68, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x71, 0x6f, 0x71, 0xa6, 0xb4, 0x9f, 0x9f,
+    0x48, 0x48, 0x48, 0xcc, 0xc3, 0xc7, 0xcd, 0xce,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x57,
+    0x77, 0x66, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x23, 0x30, 0x31, 0xcf, 0x91, 0x7e, 0x90, 0x90,
+    0x8b, 0x5b, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0x5d, 0xd0, 0x36, 0x24, 0xd1, 0xb1, 0xaf, 0xaa,
+    0xba, 0xb8, 0x68, 0x68, 0x68, 0x71, 0x6e, 0x6e,
+    0x6e, 0x6f, 0x6e, 0x78, 0xa1, 0xa9, 0xa1, 0xb0,
+    0x9f, 0x9b, 0x99, 0xcc, 0x64, 0x5c, 0x8b, 0xd0,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x73, 0x5d,
+    0x82, 0x5c, 0xd2, 0x2a, 0x23, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x24, 0x2b, 0xcf, 0x8b, 0x5b, 0x76, 0x5b, 0x5b,
+    0x7b, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc7, 0x5e, 0x22, 0x36, 0x21, 0x3a, 0x99, 0x48,
+    0xa2, 0xa8, 0xb7, 0xc1, 0xb8, 0x68, 0x68, 0xbc,
+    0x68, 0x6e, 0xb5, 0xb4, 0xb4, 0xab, 0xb5, 0xa1,
+    0xb0, 0x4f, 0x3f, 0xd3, 0x7b, 0x7b, 0x85, 0x80,
+    0xbe, 0x36, 0x36, 0x36, 0x21, 0xd4, 0x7e, 0x7b,
+    0x64, 0x64, 0xd5, 0x35, 0x24, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x31, 0xd6, 0x5b, 0x64, 0xc3, 0xc3, 0xcb,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0x66, 0xd7, 0x36, 0x36, 0x36, 0x2c, 0x4b,
+    0xd8, 0xd9, 0xb3, 0xa8, 0xbd, 0xbd, 0xbd, 0xbd,
+    0xa9, 0xab, 0xb3, 0xa5, 0xa2, 0x9f, 0xa2, 0xa1,
+    0x6a, 0x9a, 0x3f, 0xda, 0x76, 0x76, 0x7a, 0x63,
+    0xdb, 0xdc, 0x86, 0xdc, 0xdd, 0x90, 0x5b, 0x64,
+    0xc3, 0xc3, 0xde, 0x2d, 0x27, 0x23, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x26, 0x2d, 0x91, 0x5b, 0x64, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc7, 0x83, 0xce, 0x36, 0x36, 0x36, 0x30,
+    0xb1, 0xd9, 0x48, 0xa1, 0xb2, 0xb0, 0xb0, 0xb3,
+    0xa2, 0x48, 0xa7, 0xbd, 0xa9, 0xa2, 0x48, 0x9f,
+    0xaa, 0x9a, 0x3f, 0xb1, 0x5b, 0x7b, 0xdf, 0x85,
+    0x7e, 0x90, 0x63, 0x90, 0x85, 0x5b, 0xc3, 0xc4,
+    0xc4, 0xcb, 0x5d, 0xd5, 0x39, 0x26, 0x23, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2d, 0xe0, 0xdf, 0x64, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc7, 0x88, 0x36, 0x36, 0x36, 0x36,
+    0x2d, 0x9b, 0x48, 0xb9, 0xaf, 0xa2, 0xa2, 0xb9,
+    0xa8, 0x9f, 0x48, 0xa7, 0xb7, 0xd9, 0x48, 0x48,
+    0x9b, 0x45, 0x3f, 0xe1, 0x6d, 0x7b, 0xca, 0xdf,
+    0x7a, 0x8b, 0x8b, 0x7a, 0x5b, 0x64, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc3, 0xe2, 0x37, 0x35, 0x26, 0x23,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2e, 0xe0, 0x7a, 0x7b, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc7, 0x72, 0x73, 0x36, 0x36, 0x36,
+    0x24, 0x52, 0x48, 0xa3, 0xaf, 0x9f, 0x48, 0xb6,
+    0xaf, 0xa2, 0x48, 0x9f, 0xe3, 0xd8, 0x48, 0x48,
+    0x48, 0x46, 0x42, 0xd6, 0x7a, 0x7b, 0x64, 0x7b,
+    0x76, 0x5b, 0x5b, 0x76, 0x7b, 0xc3, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xcb, 0x64, 0xe2, 0x4d, 0x2c, 0x27,
+    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x25, 0x31, 0xe4, 0x8b, 0x7b, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc7, 0x89, 0xbe, 0x36, 0x36,
+    0x32, 0x47, 0x48, 0x4f, 0xa0, 0x48, 0x48, 0xe3,
+    0x92, 0x9f, 0x48, 0x9f, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x4b, 0x2f, 0x8f, 0x7a, 0x7b, 0xc3, 0xcb,
+    0xc3, 0x64, 0x64, 0xc3, 0xc3, 0xcb, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x5d, 0xe5, 0x2c,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x25, 0x31, 0xe4, 0x85, 0x7b, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0x66, 0x57, 0x27, 0x4d,
+    0x4b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x99, 0x34, 0xbe, 0xdb, 0x7a, 0x7b, 0xc3, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0xe4,
+    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2d, 0xe4, 0x85, 0x7b, 0xcb, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc7, 0x5f, 0x92, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x44,
+    0x35, 0x36, 0xce, 0xdd, 0x7a, 0x7b, 0xcb, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0xc3, 0xe1,
+    0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x30, 0x2f, 0xd6, 0x8b, 0x7b, 0xcb, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0x66, 0x89, 0x45,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x4e, 0x25,
+    0x36, 0x36, 0x61, 0xdb, 0x6d, 0x64, 0xcb, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x7b, 0xdf, 0xe5,
+    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0xe6, 0x63, 0xdf, 0xc3, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x72, 0x81, 0xe7,
+    0x46, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x3f, 0x2c, 0x36, 0x36,
+    0x36, 0x36, 0xe8, 0x8f, 0x6d, 0x64, 0xcb, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc3, 0xca, 0x8b, 0xcf, 0x2c,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x35, 0x96, 0x75, 0xca, 0xc3, 0xcb, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x7b, 0x81, 0xdb,
+    0x73, 0x3b, 0x44, 0x9b, 0x48, 0x48, 0x48, 0x9b,
+    0x99, 0x43, 0x94, 0x2c, 0x21, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x73, 0xdb, 0x7a, 0x7b, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0x64, 0x76, 0x7a, 0x91, 0xd5, 0x31, 0x30,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x39, 0x97, 0x75, 0xdf, 0x7b, 0x64, 0xc3, 0xc3,
+    0xcb, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0x7b, 0x7a, 0xe9,
+    0xea, 0x36, 0x21, 0x26, 0x2b, 0x39, 0x33, 0x30,
+    0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xea, 0xdd, 0x8b, 0x7b, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x64, 0x64,
+    0x76, 0x85, 0xe0, 0xd5, 0x34, 0x2b, 0x27, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0xeb, 0x63, 0x7e, 0x7a, 0x6d, 0xdf, 0x5b,
+    0x76, 0x7b, 0x64, 0x64, 0xc3, 0xcb, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x76, 0x85, 0xdb,
+    0x79, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xec, 0xdd, 0x75, 0x76, 0xc3, 0xc4,
+    0xc4, 0xc4, 0xcb, 0xc3, 0x64, 0x76, 0xdf, 0x8b,
+    0xd6, 0xd5, 0x2f, 0x35, 0x30, 0x24, 0x22, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x27, 0x31, 0xed, 0xeb, 0xdd, 0x74, 0x63, 0x90,
+    0x7e, 0x75, 0x8b, 0x6d, 0xdf, 0x76, 0x64, 0xc3,
+    0xcb, 0xcb, 0xcb, 0xcb, 0x64, 0x7a, 0x84, 0xee,
+    0x79, 0xbe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xea, 0xee, 0x63, 0x6d, 0x7b, 0x64,
+    0xcb, 0xc3, 0x64, 0x7b, 0xdf, 0x75, 0x63, 0x96,
+    0x38, 0x39, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x28, 0x27, 0x35, 0x2d, 0x41, 0xd5, 0xe7, 0x8f,
+    0xdb, 0xdd, 0xe9, 0x74, 0x84, 0x90, 0x85, 0x6d,
+    0x5b, 0x7b, 0x7b, 0xca, 0x6d, 0x90, 0xdb, 0xef,
+    0xec, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30,
+    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36,
+    0x36, 0x21, 0xd4, 0x80, 0xe9, 0x7e, 0x6d, 0x76,
+    0xca, 0x76, 0x6d, 0x85, 0x63, 0xdb, 0xd5, 0x34,
+    0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f,
+    0x41, 0xf0, 0xf1, 0x6c, 0x80, 0xee, 0xdb, 0x74,
+    0x84, 0x90, 0x75, 0x7e, 0x74, 0x8f, 0xef, 0x79,
+    0xe8, 0x2b, 0x9d, 0x41, 0x2f, 0x34, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x2f, 0x38,
+    0x4d, 0x37, 0xf2, 0xf3, 0x8f, 0x74, 0x63, 0x7e,
+    0x75, 0x7e, 0x63, 0xe9, 0x88, 0xe6, 0x31, 0x2a,
+    0x24, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x30,
+    0x33, 0x39, 0x2e, 0x51, 0x41, 0xd2, 0x6c, 0xf3,
+    0x80, 0xee, 0xee, 0xee, 0xf4, 0xf3, 0xd7, 0xf5,
+    0x41, 0x34, 0x35, 0x32, 0x30, 0x27, 0x27, 0x27,
+    0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a,
+    0x2b, 0x34, 0xf6, 0xec, 0xf7, 0x8f, 0xdd, 0xe9,
+    0xe9, 0xdd, 0xee, 0x6c, 0x41, 0x39, 0x27, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22,
+    0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x41,
+    0xf8, 0xd7, 0x79, 0x79, 0x79, 0xec, 0xf9, 0x51,
+    0x39, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22,
+    0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23,
+    0x24, 0x2a, 0x31, 0xfa, 0xea, 0x79, 0xf3, 0x80,
+    0xf7, 0xdc, 0xfb, 0x2f, 0x35, 0x26, 0x23, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x22, 0x23, 0x28, 0x25, 0x30, 0x2b,
+    0x31, 0x2f, 0xf6, 0xfa, 0xfa, 0x2f, 0x2e, 0x33,
+    0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x27, 0x35, 0x34, 0xfa, 0xfa, 0xfa,
+    0xfc, 0xf6, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28,
+    0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35,
+    0x2b, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x21, 0x22, 0x23, 0x28, 0x28, 0x23, 0x22, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x23, 0x28, 0x24, 0x24,
+    0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+};
+
+unsigned char linux_logo16[1];
+
+#endif /* INCLUDE_LINUX_LOGO_DATA */
+
+#include <linux/linux_logo.h>
+
diff -urN linux-2.4.29/include/asm-niosnommu/mc146818rtc.h linux-2.4.29-uc1/include/asm-niosnommu/mc146818rtc.h
--- linux-2.4.29/include/asm-niosnommu/mc146818rtc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/mc146818rtc.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,9 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _NIOS_MC146818RTC_H
+#define _NIOS_MC146818RTC_H
+
+/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */
+
+#endif /* _NIOS_MC146818RTC_H */
diff -urN linux-2.4.29/include/asm-niosnommu/mman.h linux-2.4.29-uc1/include/asm-niosnommu/mman.h
--- linux-2.4.29/include/asm-niosnommu/mman.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/mman.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef __NIOS_MMAN_H__
+#define __NIOS_MMAN_H__
+
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_NONE	0x0		/* page can not be accessed */
+
+#define MAP_SHARED	0x01		/* Share changes */
+#define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_TYPE	0x0f		/* Mask for type of mapping */
+#define MAP_FIXED	0x10		/* Interpret addr exactly */
+#define MAP_ANONYMOUS	0x20		/* don't use a file */
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as a executable */
+#define MAP_LOCKED	0x2000		/* pages are locked */
+
+#define MS_ASYNC	1		/* sync memory asynchronously */
+#define MS_INVALIDATE	2		/* invalidate the caches */
+#define MS_SYNC		4		/* synchronous memory sync */
+
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
+
+/* compatibility flags */
+#define MAP_ANON	MAP_ANONYMOUS
+#define MAP_FILE	0
+
+#endif /* __NIOS_MMAN_H__ */
diff -urN linux-2.4.29/include/asm-niosnommu/mmu_context.h linux-2.4.29-uc1/include/asm-niosnommu/mmu_context.h
--- linux-2.4.29/include/asm-niosnommu/mmu_context.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/mmu_context.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,30 @@
+#ifndef __NIOS_MMU_CONTEXT_H
+#define __NIOS_MMU_CONTEXT_H
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
+{
+}
+
+extern inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	// mm->context = virt_to_phys(mm->pgd);
+	return(0);
+}
+
+#define destroy_context(mm)		do { } while(0)
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu)
+{
+}
+
+extern inline void activate_mm(struct mm_struct *prev_mm,
+			       struct mm_struct *next_mm)
+{
+}
+
+#endif /* !(__NIOS_MMU_CONTEXT_H) */
diff -urN linux-2.4.29/include/asm-niosnommu/mmu.h linux-2.4.29-uc1/include/asm-niosnommu/mmu.h
--- linux-2.4.29/include/asm-niosnommu/mmu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/mmu.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,7 @@
+#ifndef __MMU_H
+#define __MMU_H
+
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_t;
+
+#endif
diff -urN linux-2.4.29/include/asm-niosnommu/module.h linux-2.4.29-uc1/include/asm-niosnommu/module.h
--- linux-2.4.29/include/asm-niosnommu/module.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/module.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef _NIOS_MODULE_H
+#define _NIOS_MODULE_H
+/*
+ * This file contains the nios architecture specific module code.
+ */
+unsigned long arch_init_modules(struct module *mod);
+
+#define module_map(x)		vmalloc(x)
+#define module_unmap(x)		vfree(x)
+#define module_arch_init(x)	arch_init_modules((x))
+
+#endif /* _NIOS_MODULE_H */
diff -urN linux-2.4.29/include/asm-niosnommu/msgbuf.h linux-2.4.29-uc1/include/asm-niosnommu/msgbuf.h
--- linux-2.4.29/include/asm-niosnommu/msgbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/msgbuf.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef _NIOS_MSGBUF_H
+#define _NIOS_MSGBUF_H
+
+/* 
+ * The msqid64_ds structure for Nios architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm msg_perm;
+	__kernel_time_t msg_stime;	/* last msgsnd time */
+	unsigned long	__unused1;
+	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	unsigned long	__unused2;
+	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned long	__unused3;
+	unsigned long  msg_cbytes;	/* current number of bytes on queue */
+	unsigned long  msg_qnum;	/* number of messages in queue */
+	unsigned long  msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t msg_lrpid;	/* last receive pid */
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+#endif /* _NIOS_MSGBUF_H */
diff -urN linux-2.4.29/include/asm-niosnommu/namei.h linux-2.4.29-uc1/include/asm-niosnommu/namei.h
--- linux-2.4.29/include/asm-niosnommu/namei.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/namei.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-nios/namei.h
+ * Moved from m68k version
+ * Included from linux/fs/namei.c
+ */
+
+#ifndef __NIOS_NAMEI_H
+#define __NIOS_NAMEI_H
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+
+#define __emul_prefix() NULL
+
+#endif
diff -urN linux-2.4.29/include/asm-niosnommu/niosasm.h linux-2.4.29-uc1/include/asm-niosnommu/niosasm.h
--- linux-2.4.29/include/asm-niosnommu/niosasm.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/niosasm.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,880 @@
+
+;------------------------------
+; Macros I: Faux Instructions
+;
+; The following "faux instructions" are
+; implemented here as macros:
+;
+; MOVIP register,constant		MOVI with optional PFX & MOVHI, or BGEN
+; ADDIP register,constant		PFX and ADDI with optional PFX
+; SUBIP register,constant		PFX and SUBI with optional PFX
+; CMPIP register,constant		PFX and CMPI with optional PFX
+;
+; MOVI16 register,constant		PFX and MOVI
+; MOVI32 register,constant		PFX, MOVI, PFX, and MOVHI
+; MOVIA  register,constant		PFX and MOVHI on Nios32, and PFX and MOVI
+;
+; ANDIP register,constant		PFX and ANDI
+; ANDNIP register,constant		PFX and ANDN
+; ORIP register,constant		PFX and ORI
+; XORIP register,constant		PFX and XORI
+;
+; _BSR address						MOVIP address to %g7, and CALL
+; _BR address						MOVIP address to %g7, and JMP
+;
+; BEQ address						SKPS cc_nz and BR, has delay slot
+; BNE address						SKPS cc_z and BR, has delay slot
+; BLE address						SKPS cc_gt and BR, has delay slot
+; BLT address						SKPS cc_ge and BR, has delay slot
+; RESTRET							RESTORE and JMP %i7 
+;
+;-------------------------------
+; Macros II: Printing
+;
+; These macros are guaranteed *not*
+; to have branch delay slot after them.
+;
+; nm_printchar char
+; nm_print "string"
+; nm_println "string"			Follows it with a carriage return
+; nm_printregister reg			For debugging, prints register name & value
+;
+;-------------------------------
+; Macros III: Inline Debugging
+;
+; These macros print various information
+; using large sections of expanded inline code.
+; They each use either few or no registers.
+; Thus, they may be safely used in interrupt handlers.
+;
+; nm_d_txchar char			print char to UART, affects no registers
+; nm_d_txregister char,char,register	prints the two characters, and the hex register value
+
+; --------------------------------------
+
+
+		.macro	_pfx_op	OP,reg,val,pForce=0
+		.if		(\pForce) || ((\val) > (31)) || ((\val) < (0))
+		PFX		%hi(\val)
+		.endif
+		\OP		\reg,%lo(\val)
+		.endm
+
+		.macro	_bgen reg,val,bit
+		.if ((\val)==(1<<\bit))
+		BGEN	\reg,\bit
+		.equ	_bgenBit,1
+		.endif
+		.endm
+
+	;------------------------
+	; MOVIP %reg,32-bit-value
+		.macro	MOVIP reg,val
+		; Methodically test every BGEN possibility...
+		.equ	_bgenBit,0
+.if 1
+		_bgen \reg,\val,0
+		_bgen \reg,\val,1
+		_bgen \reg,\val,2
+		_bgen \reg,\val,3
+		_bgen \reg,\val,4
+		_bgen \reg,\val,5
+		_bgen \reg,\val,6
+		_bgen \reg,\val,7
+		_bgen \reg,\val,8
+		_bgen \reg,\val,9
+		_bgen \reg,\val,10
+		_bgen \reg,\val,11
+		_bgen \reg,\val,12
+		_bgen \reg,\val,13
+		_bgen \reg,\val,14
+		_bgen \reg,\val,15
+		_bgen \reg,\val,16
+		_bgen \reg,\val,17
+		_bgen \reg,\val,18
+		_bgen \reg,\val,19
+		_bgen \reg,\val,20
+		_bgen \reg,\val,21
+		_bgen \reg,\val,22
+		_bgen \reg,\val,23
+		_bgen \reg,\val,24
+		_bgen \reg,\val,25
+		_bgen \reg,\val,26
+		_bgen \reg,\val,27
+		_bgen \reg,\val,28
+		_bgen \reg,\val,29
+		_bgen \reg,\val,30
+		_bgen \reg,\val,31
+
+		; If no bgen fit...
+.endif
+		.if !_bgenBit
+			.if ((\val) & 0xFFE0)
+				PFX %hi(\val)
+			.endif
+			MOVI \reg,%lo(\val)
+			.if __nios32__
+				.if ((\val) & 0xffff0000)
+					.if ((\val) & 0xFFE00000)
+						PFX %xhi(\val)
+					.endif
+					MOVHI \reg,%xlo(\val)
+				.endif
+			.endif
+		.endif
+
+		.endm
+
+	; ADDIP %reg,16-bit-value
+		.macro	ADDIP reg,val
+		_pfx_op	ADDI,\reg,\val
+		.endm
+
+	; SUBIP %reg,16-bit-value
+		.macro	SUBIP reg,val
+		_pfx_op	SUBI,\reg,\val
+		.endm
+
+	; CMPIP %reg,16-bit-value
+		.macro	CMPIP reg,val
+		_pfx_op	CMPI,\reg,\val
+		.endm
+
+	; ANDIP %reg,16-bit-value
+		.macro	ANDIP reg,val
+		PFX		%hi(\val)
+		AND		\reg,%lo(\val)
+		.endm
+
+	; ANDNIP %reg,16-bit-value
+		.macro	ANDNIP reg,val
+		PFX		%hi(\val)
+		ANDN		\reg,%lo(\val)
+		.endm
+
+	; ORIP %reg,16-bit-value
+		.macro	ORIP reg,val
+		PFX		%hi(\val)
+		OR			\reg,%lo(\val)
+		.endm
+
+	; XORIP %reg,16-bit-value
+		.macro	XORIP reg,val
+		PFX		%hi(\val)
+		XOR		\reg,%lo(\val)
+		.endm
+
+	; BEQ addr
+		.macro	BEQ addr
+		IFS		cc_eq
+		BR			\addr
+		.endm
+
+	; BNE addr
+		.macro	BNE addr
+		IFS		cc_ne
+		BR			\addr
+		.endm
+
+	; BLE addr
+		.macro	BLE addr
+		SKPS		cc_gt
+		BR			\addr
+		.endm
+
+	; BLT addr
+		.macro	BLT addr
+		SKPS		cc_ge
+		BR			\addr
+		.endm
+
+		.macro	digitToChar reg
+		ANDIP	\reg,0x000f
+		CMPI	\reg,10
+		SKPS	cc_lt
+		ADDI	\reg,'A'-'0'-10
+		PFX		%hi('0')
+		ADDI	\reg,%lo('0')
+		.endm
+
+; PUSHRET == dec sp, and stash return addr
+	.macro	PUSHRET
+	SUBI		%sp,2
+	ST			[%sp],%o7
+	.endm
+; POPRET == pop and jump
+	.macro	POPRET
+	LD			%o7,[%sp]
+	JMP		%o7
+	ADDI		%sp,2		; branch delay slot
+	.endm
+
+; RESTRET = restore & return
+	.macro	RESTRET
+	JMP		%i7
+	RESTORE
+	.endm
+
+	;--------------------
+	; MOVI16 %reg,Address
+	;
+	.macro	MOVI16	reg,val
+	PFX	%hi(\val)
+	MOVI	\reg,%lo(\val)
+	.endm
+
+	;--------------------
+	; MOVI32 %reg,Address
+	;
+	.macro	MOVI32	reg,val
+	PFX	%hi(\val)
+	MOVI	\reg,%lo(\val)
+	PFX	%xhi(\val)
+	MOVHI	\reg,%xlo(\val)
+	.endm
+
+	;--------------------
+	; MOVIA %reg,Address
+	;
+	.macro	MOVIA		reg,val
+	.if __nios32__
+		MOVI32 \reg,\val
+	.else
+		MOVI16 \reg,\val
+	.endif
+	.endm
+
+	;--------------------
+	; _BR
+
+	.macro _BR target,viaRegister=%g7
+	MOVIA	\viaRegister,\target@h
+	JMP	\viaRegister
+	.endm
+
+	;--------------------
+	; _BSR
+
+	.macro _BSR target,viaRegister=%g7
+	MOVIA	\viaRegister,\target@h
+	CALL	\viaRegister
+	.endm
+
+	;---------------------
+	; nm_print "Your String Here"
+	;
+	.macro	nm_print	string
+
+	BR		pastStringData\@
+	NOP
+
+stringData\@:
+	.asciz	"\string"
+	.align 1		; aligns by 2^n
+pastStringData\@:
+	MOVIA		%o0,stringData\@
+	_BSR		nr_uart_txstring
+	NOP
+	.endm
+
+	.macro	nm_println string
+	nm_print	"\string"
+	_BSR		nr_uart_txcr
+	NOP
+	.endm
+
+	.macro	nm_printregister reg	; affects %g0 & %g1 & %g7, but thrashes the CWP a bit
+	SAVE		%sp,-16
+	nm_print	"\reg = "
+	RESTORE
+	MOV		%g0,\reg
+	SAVE		%sp,-16
+	MOV		%o0,%g0
+	_BSR		nr_uart_txhex
+	NOP
+	_BSR		nr_uart_txcr
+	NOP
+	RESTORE
+	.endm
+
+	.macro	nm_printchar char
+	MOVIP		%o0,\char
+	_BSR		nr_uart_txchar
+	MOVI		%o1,0
+	.endm
+
+	.macro	nm_print2chars char1,char2
+	MOVIP		%o0,(\char2<<8)+\char1
+	_BSR		nr_uart_txchar
+	NOP
+	_BSR		nr_uart_txchar
+	LSRI		%o0,8
+	.endm
+
+
+
+; ---------------------------
+; Completely inline UART sends
+; Send the char, or %g7 if not there.
+; Trashes %g5 and %g6 and %g7...
+
+	.macro	nm_txchar char=0
+;nm_d_delay 1000
+	MOVIA	%g6,nasys_printf_uart
+txCharLoop\@:
+	PFX	2
+.if \char
+	LD	%g7,[%g6]
+	SKP1	%g7,6
+.else
+	LD	%g5,[%g6]
+	SKP1	%g5,6
+.endif
+	BR	txCharLoop\@
+	NOP
+.if \char
+	MOVIP	%g7,\char
+.endif
+	PFX	1
+	ST	[%g6],%g7
+;nm_d_delay 4
+	.endm
+
+		.macro nm_txcr
+		nm_txchar 13
+		nm_txchar 10
+		.endm
+
+		.macro nm_txhexdigit,reg,shift
+		MOV		%g7,\reg
+		LSRI		%g7,\shift
+		ANDIP		%g7,0x000f
+		CMPI		%g7,10
+		SKPS		cc_lt
+		ADDIP		%g7,'A'-'0'-10
+		ADDIP		%g7,'0'
+		nm_txchar
+		.endm
+
+		.macro nm_txhex
+
+	.if __nios32__
+		nm_txhexdigit %g0,28
+		nm_txhexdigit %g0,24
+		nm_txhexdigit %g0,20
+		nm_txhexdigit %g0,16
+	.endif
+
+		nm_txhexdigit %g0,12
+		nm_txhexdigit %g0,8
+		nm_txhexdigit %g0,4
+		nm_txhexdigit %g0,0
+		.endm
+
+
+
+
+
+
+
+
+
+
+; ----------------------
+; The following macros are
+; rather mighty. They expand
+; to large inline code for
+; printing various things to
+; the serial port. They are
+; useful for debugging
+; trap handlers, where you
+; can't just go and call
+; nr_uart_TxChar and such, because,
+; well, the CWP might be
+; off limits!
+;
+; They do, however, presume
+; that the stack is in good
+; working order.
+
+
+.macro nm_d_pushgregisters
+ 	SUBIP %sp,16+69				; oddball number so if we accidentally see it, it looks funny.
+	STS	[%sp,16+0],%g0
+	STS	[%sp,16+1],%g1
+	STS	[%sp,16+2],%g2
+	STS	[%sp,16+3],%g3
+	STS	[%sp,16+4],%g4
+	STS	[%sp,16+5],%g5
+	STS	[%sp,16+6],%g6
+	STS	[%sp,16+7],%g7
+	.endm
+
+.macro nm_d_popgregisters
+	LDS	%g0,[%sp,16+0]
+	LDS	%g1,[%sp,16+1]
+	LDS	%g2,[%sp,16+2]
+	LDS	%g3,[%sp,16+3]
+	LDS	%g4,[%sp,16+4]
+	LDS	%g5,[%sp,16+5]
+	LDS	%g6,[%sp,16+6]
+	LDS	%g7,[%sp,16+7]
+	ADDIP	%sp,16+69				; must match the push
+	.endm
+
+
+.macro nm_d_txchar	c
+	SUBI	%sp,16+8		; 32 or 16 bit, that's enough space
+	STS	[%sp,16+0],%g6
+	STS	[%sp,16+1],%g7
+	nm_txchar \c
+	LDS	%g6,[%sp,16+0]
+	LDS	%g7,[%sp,16+1]
+	ADDI	%sp,16+8
+	.endm
+
+.macro nm_d_txchar3 c1,c2,c3
+ nm_d_txchar '<'
+ nm_d_txchar \c1
+ nm_d_txchar \c2
+ nm_d_txchar \c3
+ nm_d_txchar '>'
+.endm
+
+.macro nm_d_txregister r,n,reg
+ nm_d_pushgregisters
+ nm_txchar '('
+ nm_txchar \r
+ nm_txchar \n
+ nm_txchar ':'
+ MOV		%g0,\reg
+ nm_txhex
+ nm_txchar ')'
+ nm_d_popgregisters
+.endm
+
+.macro nm_d_txreg r,n,reg
+	nm_d_txregister \r,\n,\reg
+.endm
+
+; Do a delay loop, affects no registers.
+
+.macro nm_d_delay d
+	SUBI	%sp,16+4
+	STS	[%sp,16+0],%g0
+	MOVIP	%g0,\d
+nm_d_delayloop\@:
+	IFRnz	%g0
+	 BR	nm_d_delayloop\@
+	SUBI	%g0,1
+	LDS	%g0,[%sp,16+0]
+	ADDI	%sp,16+4
+.endm
+
+;
+; File: excalibur.s
+;
+; This file is a machine generated address map
+; for a CPU named cpu using toolchain "gnu".
+; C:/Altera/Excalibur/sopc_builder_2_6_1/examples/verilog/nios_dev_board/LDK_2_0_with_91C111_full/LDK2.ptf
+; Generated: 2002.09.26 13:43:23
+;
+
+.ifndef _excalibur_
+.equ _excalibur_,1
+
+
+	; minor macro to .equate and .global
+	.macro	GEQU sym,val
+	.global \sym
+	.equ \sym,\val
+	.endm
+
+; The Memory Map
+
+	GEQU na_mon               , 0x00000000 ; altera_avalon_onchip_memory
+	GEQU na_mon_end           , 0x00000400
+	GEQU na_cpu               , 0x00000000 ; altera_nios
+	GEQU na_uart0             , 0x00000400 ; altera_avalon_uart
+	GEQU na_uart0_irq         , 17
+	GEQU na_timer0            , 0x00000440 ; altera_avalon_timer
+	GEQU na_timer0_irq        , 16
+	GEQU na_ssram_detect      , 0x00000460 ; altera_avalon_pio
+	GEQU na_button_pio        , 0x00000470 ; altera_avalon_pio
+	GEQU na_spi               , 0x00000480 ; altera_avalon_spi
+	GEQU na_spi_irq           , 19
+	GEQU na_uart1             , 0x000004a0 ; altera_avalon_uart
+	GEQU na_uart1_irq         , 18
+	GEQU na_ide_interface     , 0x00000500 ; altera_avalon_user_defined_interface
+	GEQU na_ide_interface_irq , 25
+	GEQU na_enet              , 0x00004000 ; altera_avalon_lan91c111
+	GEQU na_enet_end          , 0x00004020
+	GEQU na_enet_irq          , 35
+	GEQU na_enet_reset_n      , 0x00004020 ; altera_avalon_pio
+	GEQU na_flash             , 0x00100000 ; altera_nios_dev_board_flash
+	GEQU na_flash_end         , 0x00200000
+	GEQU na_flash_kernel      , 0x00800000 ; mtx_sodimm_flash_controller
+	GEQU na_flash_kernel_end  , 0x01000000
+	GEQU na_sdram             , 0x01000000 ; altera_avalon_sdram_controller
+	GEQU na_sdram_end         , 0x02000000
+ 
+	GEQU na_null                 , 0
+	GEQU nasys_flash_count       , 1
+	GEQU nasys_flash_0           , na_flash
+	GEQU nasys_pio_count         , 3
+	GEQU nasys_pio_0             , na_ssram_detect
+	GEQU nasys_pio_1             , na_button_pio
+	GEQU nasys_pio_2             , na_enet_reset_n
+	GEQU nasys_spi_count         , 1
+	GEQU nasys_spi_0             , na_spi
+	GEQU nasys_spi_0_irq         , 19
+	GEQU nasys_timer_count       , 1
+	GEQU nasys_timer_0           , na_timer0
+	GEQU nasys_timer_0_irq       , 16
+	GEQU nasys_uart_count        , 2
+	GEQU nasys_uart_0            , na_uart0
+	GEQU nasys_uart_0_irq        , 17
+	GEQU nasys_uart_1            , na_uart1
+	GEQU nasys_uart_1_irq        , 18
+	GEQU nasys_usersocket_count  , 1
+	GEQU nasys_usersocket_0      , na_ide_interface
+	GEQU nasys_usersocket_0_irq  , 25
+	GEQU nasys_vector_table      , 0x01000000
+	GEQU nasys_vector_table_size , 0x00000100
+	GEQU nasys_vector_table_end  , 0x01000100
+	GEQU nasys_reset_address     , 0x00000000
+	GEQU nasys_clock_freq        , 33333000
+	GEQU nasys_clock_freq_1000   , 33333
+	GEQU nasys_debug_core        , 0
+	GEQU nasys_printf_uart       , na_uart0
+	GEQU nasys_printf_uart_irq   , na_uart0_irq
+	GEQU nasys_debug_uart        , na_uart1
+	GEQU nasys_debug_uart_irq    , na_uart1_irq
+	GEQU nasys_main_flash        , na_flash
+	GEQU nasys_main_flash_size   , na_flash_size
+	GEQU nasys_main_flash_end    , na_flash_end
+	GEQU nasys_program_mem       , 0x01000100
+	GEQU nasys_program_mem_size  , 0x00ffff00
+	GEQU nasys_program_mem_end   , 0x02000000
+	GEQU nasys_data_mem          , 0x01000100
+	GEQU nasys_data_mem_size     , 0x00ffff00
+	GEQU nasys_data_mem_end      , 0x02000000
+	GEQU nasys_stack_top         , 0x02000000
+ 
+	.equ PLUGS_PLUG_COUNT          , 5 ; Maximum number of plugs
+	.equ PLUGS_ADAPTER_COUNT       , 2 ; Maximum number of adapters
+	.equ PLUGS_DNS                 , 1 ; Have routines for DNS lookups
+	.equ PLUGS_PING                , 1 ; Respond to icmp echo (ping) messages
+	.equ PLUGS_TCP                 , 1 ; Support tcp in/out connections
+	.equ PLUGS_IRQ                 , 1 ; Run at interrupte level
+	.equ PLUGS_DEBUG               , 1 ; Support debug routines
+	.equ __nios_catch_irqs__       , 1 ; Include panic handler for all irqs (needs uart)
+	.equ __nios_use_constructors__ , 1 ; Call c++ static constructors
+	.equ __nios_use_cwpmgr__       , 1 ; Handle register window underflows
+	.equ __nios_use_fast_mul__     , 1 ; Faster but larger int multiply routine
+	.equ __nios_use_small_printf__ , 1 ; Smaller non-ANSI printf, with no floating point
+	.equ __nios_use_multiply__     , 0 ; Use MUL instruction for 16x16
+	.equ __nios_use_mstep__        , 0 ; Use MSTEP instruction for 16x16
+
+
+
+	.macro	nm_system_name_string
+	.asciz	"LDK2"
+	.endm
+
+	.macro	nm_cpu_name_string
+	.asciz	"cpu"
+	.endm
+
+	.macro	nm_monitor_string
+	.asciz	"L20e1"
+	.endm
+
+	.equ	nios_32,1
+
+	.macro	nm_cpu_architecture
+	.asciz	"nios_32"
+	.endm
+
+; Structures and Routines For Each Peripheral
+
+
+
+.if __nios32__
+    .equ nios_wordsize,4
+.else
+    .equ nios_wordsize,2
+.endif
+
+    GEQU    nasys_debug_core_irq,     8
+
+;;; debug registers offsets from base
+    GEQU    np_debug_interrupt,        0        ;read-only,  4 bits, reading stops trace
+    GEQU    np_debug_n_samples_lsb,    1        ;read-only, 16 bits
+    GEQU    np_debug_n_samples_msb,    2        ;read-only, 16 bits
+    GEQU    np_debug_data_valid,       3        ;read-only, 1 bit, 
+                                                ;true when trace registers contain valid sample
+    GEQU    np_debug_trace_address,    4        ;read-only, 16 or 32 bits
+    GEQU    np_debug_trace_data,       5        ;read-only, 16 or 32 bits
+    GEQU    np_debug_trace_code,       6        ;read-only, 16 or 32 bits
+    GEQU    np_debug_write_status,     7        ;read-only, 1 bit, 
+                                                ;true when read to readback tracedata
+    GEQU    np_debug_start,            8        ;write-only, write any value to start
+    GEQU    np_debug_stop,             9        ;write-only, write any value to stop
+    GEQU    np_debug_read_sample,      10        ;write-only, write any value to read
+    GEQU    np_debug_trace_mode,       11        ;write-only, 1 bit
+    GEQU    np_debug_mem_int_enable,   12        ;write-only, 16 or 32 bits ?????
+    GEQU    np_debug_ext_brk_enable,   13        ;write-only, 1 bit
+    GEQU    np_debug_sw_reset,         14        ;write-only, reset sampels and trace memory
+    
+    GEQU    np_debug_address_pattern_0,16        ;write-only, 16 or 32 bits
+    GEQU    np_debug_address_mask_0,   17        ;write-only, 16 or 32 bits
+    GEQU    np_debug_data_pattern_0,   18        ;write-only, 16 or 32 bits
+    GEQU    np_debug_data_mask_0,      19        ;write-only, 16 or 32 bits
+    GEQU    np_debug_code_0,           20        ;write-only, 16 or 32 bits
+    
+    GEQU    np_debug_address_pattern_1,24        ;write-only, 16 or 32 bits
+    GEQU    np_debug_address_mask_1,   25        ;write-only, 16 or 32 bits
+    GEQU    np_debug_data_pattern_1,   26        ;write-only, 16 or 32 bits
+    GEQU    np_debug_data_mask_1,      27        ;write-only, 16 or 32 bits
+    GEQU    np_debug_code_1,           28        ;write-only, 16 or 32 bits
+
+;;; debug Register Bits/Codes
+;;; ************************************************
+;;; debug_interrupt register
+;;; bit numbers
+    GEQU    np_debug_interrupt_code_dbp0_bit, 0
+    GEQU    np_debug_interrupt_code_dbp1_bit, 1
+    GEQU    np_debug_interrupt_code_ibp0_bit, 2
+    GEQU    np_debug_interrupt_code_ibp1_bit, 3
+    GEQU    np_debug_interrupt_code_mem_bit, 4
+
+;;; bit masks
+    GEQU    np_debug_interrupt_code_ext_mask,  (0)
+    GEQU    np_debug_interrupt_code_dbp0_mask, (1<<0)
+    GEQU    np_debug_interrupt_code_dbp1_mask, (1<<1)
+    GEQU    np_debug_interrupt_code_ibp0_mask, (1<<2)
+    GEQU    np_debug_interrupt_code_ibp1_mask, (1<<3)
+    GEQU    np_debug_interrupt_code_mem_mask,  (1<<4)
+
+;;; ************************************************
+;;; debug_trace_code register
+;;; bit numbers
+    GEQU    np_debug_trace_code_skp_bit, 1
+    GEQU    np_debug_trace_code_fifo_full_bit, 2
+    GEQU    np_debug_trace_code_bus_bit, 3
+    GEQU    np_debug_trace_code_rw_bit, 4
+    GEQU    np_debug_trace_code_intr_bit, 5
+    
+;;; bit masks
+    GEQU    np_debug_trace_code_skp_mask,       (1<<0)
+    GEQU    np_debug_trace_code_fifo_full_mask, (1<<1)
+    GEQU    np_debug_trace_code_data_trans_mask,(1<<2)     ;instr trans if 0
+    GEQU    np_debug_trace_code_write_mask,     (1<<3)     ;read if 0
+    GEQU    np_debug_trace_code_intr_mask,      (1<<4)
+.if __nios32__
+    GEQU    np_debug_trace_code_skp_cnt_mask, (63<<2)
+.else
+    GEQU    np_debug_trace_code_skp_cnt_mask, (31<<2)
+.endif
+
+;;; useful constants
+    GEQU    np_debug_trace_code_op_mask, (np_debug_trace_code_data_trans_mask|np_debug_trace_code_write_mask)
+    GEQU    np_debug_trace_code_read, np_debug_trace_code_data_trans_mask
+    GEQU    np_debug_trace_code_write, (np_debug_trace_code_data_trans_mask|np_debug_trace_code_write_mask)
+    GEQU    np_debug_trace_code_fetch, 0
+    
+;;; ************************************************
+;;; debug_code_* registers
+;;; bit numbers
+    GEQU    np_debug_break_code_read_bit,  0
+    GEQU    np_debug_break_code_write_bit, 1
+    GEQU    np_debug_break_code_fetch_bit, 2
+    
+;;; bit masks
+    GEQU    np_debug_break_code_read_mask,  (1<<0)
+    GEQU    np_debug_break_code_write_mask, (1<<1)
+    GEQU    np_debug_break_code_fetch_mask, (1<<2)
+    
+;;; ************************************************
+;;; debug_write_status register
+;;; bit numbers
+    GEQU    np_debug_write_status_writing_bit, 0
+    GEQU    np_debug_write_status_nios32_bit,  1
+    GEQU    np_debug_write_status_trace_bit,   2
+    
+;;; bit masks
+    GEQU    np_debug_write_status_writing_mask, (1<<0)
+    GEQU    np_debug_write_status_nios32_mask,  (1<<1)
+    GEQU    np_debug_write_status_trace_mask,   (1<<2)
+    
+; ----------------------------------------------
+; UART Peripheral
+;
+	;
+	; UART Registers
+	;
+	.equ np_uartrxdata,      0 ; Read-only, 8-bit
+	.equ np_uarttxdata,      1 ; Write-only, 8-bit
+	.equ np_uartstatus,      2 ; Read-only, 8-bit
+	.equ np_uartcontrol,     3 ; Read/Write, 9-bit
+	.equ np_uartdivisor,     4 ; Read/Write, 16-bit, optional
+	.equ np_uartendofpacket, 5 ; Read/Write, end-of-packet character
+
+	;
+	; UART Status Register
+	;
+	.equ np_uartstatus_eop_mask,  (1<<12)
+	.equ np_uartstatus_cts_mask,  (1<<11)
+	.equ np_uartstatus_dcts_mask, (1<<10)
+	.equ np_uartstatus_e_mask,    (1<<8)
+	.equ np_uartstatus_rrdy_mask, (1<<7)
+	.equ np_uartstatus_trdy_mask, (1<<6)
+	.equ np_uartstatus_tmt_mask,  (1<<5)
+	.equ np_uartstatus_toe_mask,  (1<<4)
+	.equ np_uartstatus_roe_mask,  (1<<3)
+	.equ np_uartstatus_brk_mask,  (1<<2)
+	.equ np_uartstatus_fe_mask,   (1<<1)
+	.equ np_uartstatus_pe_mask,   (1<<0)
+
+	.equ np_uartstatus_eop_bit,  12
+	.equ np_uartstatus_cts_bit,  11
+	.equ np_uartstatus_dcts_bit, 10
+	.equ np_uartstatus_e_bit,    8
+	.equ np_uartstatus_rrdy_bit, 7
+	.equ np_uartstatus_trdy_bit, 6
+	.equ np_uartstatus_tmt_bit,  5
+	.equ np_uartstatus_toe_bit,  4
+	.equ np_uartstatus_roe_bit,  3
+	.equ np_uartstatus_brk_bit,  2
+	.equ np_uartstatus_fe_bit,   1
+	.equ np_uartstatus_pe_bit,   0
+
+	;
+	; UART Control Register
+	;
+	.equ np_uartcontrol_eop_mask,   (1<<10)
+	.equ np_uartcontrol_tbrk_mask,  (1<<9)
+	.equ np_uartcontrol_ie_mask,    (1<<8)
+	.equ np_uartcontrol_irrdy_mask, (1<<7)
+	.equ np_uartcontrol_itrdy_mask, (1<<6)
+	.equ np_uartcontrol_itmt_mask,  (1<<5)
+	.equ np_uartcontrol_itoe_mask,  (1<<4)
+	.equ np_uartcontrol_iroe_mask,  (1<<3)
+	.equ np_uartcontrol_ibrk_mask,  (1<<2)
+	.equ np_uartcontrol_ife_mask,   (1<<1)
+	.equ np_uartcontrol_ipe_mask,   (1<<0)
+
+	.equ np_uartcontrol_eop_bit,  10
+	.equ np_uartcontrol_tbrk_bit,  9
+	.equ np_uartcontrol_ie_bit,    8
+	.equ np_uartcontrol_irrdy_bit, 7
+	.equ np_uartcontrol_itrdy_bit, 6
+	.equ np_uartcontrol_itmt_bit,  5
+	.equ np_uartcontrol_itoe_bit,  4
+	.equ np_uartcontrol_iroe_bit,  3
+	.equ np_uartcontrol_ibrk_bit,  2
+	.equ np_uartcontrol_ife_bit,   1
+	.equ np_uartcontrol_ipe_bit,   0
+
+; ----------------------------------------------
+; Timer Peripheral
+;
+	;
+	; Timer Register Offsets
+	;
+
+	.equ np_timerstatus,  0  ; read only, 2 bits (any write to clear to)
+	.equ np_timercontrol, 1  ; write/readable, 4 bits
+	.equ np_timerperiodl, 2  ; write/readable, 16 bits
+	.equ np_timerperiodh, 3  ; write/readable, 16 bits
+	.equ np_timersnapl,   4  ; read only, 16 bits
+	.equ np_timersnaph,   5  ; read only, 16 bits
+
+	;
+	; Timer Register Bits
+	;
+
+	.equ np_timerstatus_run_bit,    1 ; timer is running
+	.equ np_timerstatus_to_bit,     0 ; timer has timed out
+ 
+	.equ np_timercontrol_stop_bit,  3 ; stop the timer
+	.equ np_timercontrol_start_bit, 2 ; start the timer
+	.equ np_timercontrol_cont_bit,  1 ; continous mode
+	.equ np_timercontrol_ito_bit,   0 ; enable time out interrupt
+
+	.equ np_timerstatus_run_mask,    (1<<1) ; timer is running
+	.equ np_timerstatus_tO_mask,     (1<<0) ; timer has timed out
+ 
+	.equ np_timercontrol_stop_mask,  (1<<3) ; stop the timer
+	.equ np_timercontrol_start_mask, (1<<2) ; start the timer
+	.equ np_timercontrol_cont_mask,  (1<<1) ; continous mode
+	.equ np_timercontrol_ito_mask,   (1<<0) ; enable time out interrupt
+
+; ----------------------------------------------
+; PIO Peripheral
+;
+	;
+	; PIO Registers
+	;
+	.equ np_piodata,          0 ; read/write, up to 32 bits
+	.equ np_piodirection,     1 ; write/readable, up to 32 bits, 1->output bit
+	.equ np_piointerruptmask, 2 ; write/readable, up to 32 bits, 1->enable interrupt
+	.equ np_pioedgecapture,   3 ; read, up to 32 bits, cleared by any write.
+
+; ----------------------------------------------
+; SPI Peripheral
+;
+	;
+	; SPI Registers
+	;
+	.equ np_spirxdata,      0 ; Read-only, 1-16 bit
+  .equ np_spitxdata,      1 ; Write-only, same width as rxdata
+	.equ np_spistatus,      2 ; Read-only, 9-bit
+	.equ np_spicontrol,     3 ; Read/Write, 9-bit
+	.equ np_spireserved,    4 ; reserved
+	.equ np_spislaveselect, 5 ; Read/Write, 1-16 bit, master only
+  .equ np_spiendofpacket, 6 ; Read/write, same width as txdata, rxdata.
+
+	;
+	; SPI Status Register
+	;
+  .equ np_spistatus_eop_mask,  (1 << 9)
+  .equ np_spistatus_e_mask,    (1 << 8)
+	.equ np_spistatus_rrdy_mask, (1 << 7)
+	.equ np_spistatus_trdy_mask, (1 << 6)
+	.equ np_spistatus_tmt_mask,  (1 << 5)
+	.equ np_spistatus_toe_mask,  (1 << 4)
+	.equ np_spistatus_roe_mask,  (1 << 3)
+
+  .equ np_spistatus_eop_bit,  9
+  .equ np_spistatus_e_bit,    8
+	.equ np_spistatus_rrdy_bit, 7
+	.equ np_spistatus_trdy_bit, 6
+	.equ np_spistatus_tmt_bit,  5
+	.equ np_spistatus_toe_bit,  4
+	.equ np_spistatus_roe_bit,  3
+
+	;
+	; SPI Control Register
+	;
+  .equ np_spicontrol_ieop_mask,  (1 << 9)
+	.equ np_spicontrol_ie_mask,    (1 << 8)
+	.equ np_spicontrol_irrdy_mask, (1 << 7)
+	.equ np_spicontrol_itrdy_mask, (1 << 6)
+	.equ np_spicontrol_itoe_mask,  (1 << 4)
+	.equ np_spicontrol_iroe_mask,  (1 << 3)
+
+  .equ np_spicontrol_ieop_bit,  9
+	.equ np_spicontrol_ie_bit,    8
+	.equ np_spicontrol_irrdy_bit, 7
+	.equ np_spicontrol_itrdy_bit, 6
+	.equ np_spicontrol_itoe_bit,  4
+	.equ np_spicontrol_iroe_bit,  3
+
+
+
+
+.endif ; _excalibur_
+
+; end of file
diff -urN linux-2.4.29/include/asm-niosnommu/niosconf.h linux-2.4.29-uc1/include/asm-niosnommu/niosconf.h
--- linux-2.4.29/include/asm-niosnommu/niosconf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/niosconf.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,21 @@
+#include <asm/nios.h>
+
+#if defined(na_flash_kernel) && defined(na_flash_kernel_end)
+#define NIOS_FLASH_START  	((int)na_flash_kernel)				/* the start address of the flash */
+#define NIOS_FLASH_END		((int)na_flash_kernel_end)			/* the end address of the flash */
+
+#define KERNEL_FLASH_START 	(NIOS_FLASH_START+0) 				/* where the kernel is burned in the flash */
+#define KERNEL_FLASH_LEN   	0x200000 					/* how many flash bytes reserved for the kernel */
+
+#define LINUX_ROMFS_START	(KERNEL_FLASH_START+KERNEL_FLASH_LEN) 	/* where the romdisk start in the flash, dont overwrite the kernel!!! */
+#define LINUX_ROMFS_END		NIOS_FLASH_END		 	 	/* how large the romdisk */
+#else
+#error Sorry,you dont have na_flash_kernel or na_flash_kernel_end defined in the core.
+#endif
+
+#if defined(nasys_program_mem) && defined(nasys_program_mem_end)
+#define LINUX_SDRAM_START 	((int)nasys_program_mem)			/* the sdram where the linux plays */
+#define LINUX_SDRAM_END		((int)nasys_program_mem_end)			/* the lenghth of the sdram linux plays in */
+#else
+#error Sorry,you dont have nasys_program_mem or nasys_program_mem_end defined in the core.
+#endif	
\ No newline at end of file
diff -urN linux-2.4.29/include/asm-niosnommu/nios.h linux-2.4.29-uc1/include/asm-niosnommu/nios.h
--- linux-2.4.29/include/asm-niosnommu/nios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/nios.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,839 @@
+/*
+ * File: excalibur.h
+ *
+ * This file is a machine generated address map
+ * for a CPU named cpu.
+ * C:/Altera/Excalibur/sopc_builder_2_6_1/examples/verilog/nios_dev_board/LDK_2_0_with_91C111_full/LDK2.ptf
+ * Generated: 2002.09.26 13:43:23
+ */
+
+#ifndef _excalibur_
+#define _excalibur_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// The Memory Map
+
+#define na_mon                ((void *)          0x00000000) // altera_avalon_onchip_memory
+#define na_mon_base                              0x00000000
+#define na_mon_end            ((void *)          0x00000400)
+#define na_mon_size                              0x00000400
+#define na_cpu                ((void *)          0x00000000) // altera_nios
+#define na_cpu_base                              0x00000000
+#define na_uart0              ((np_uart *)       0x00000400) // altera_avalon_uart
+#define na_uart0_base                            0x00000400
+#define na_uart0_irq                             17
+#define na_timer0             ((np_timer *)      0x00000440) // altera_avalon_timer
+#define na_timer0_base                           0x00000440
+#define na_timer0_irq                            16
+#define na_ssram_detect       ((np_pio *)        0x00000460) // altera_avalon_pio
+#define na_ssram_detect_base                     0x00000460
+#define na_button_pio         ((np_pio *)        0x00000470) // altera_avalon_pio
+#define na_button_pio_base                       0x00000470
+#define na_spi                ((np_spi *)        0x00000480) // altera_avalon_spi
+#define na_spi_base                              0x00000480
+#define na_spi_irq                               19
+#define na_uart1              ((np_uart *)       0x000004a0) // altera_avalon_uart
+#define na_uart1_base                            0x000004a0
+#define na_uart1_irq                             18
+#define na_ide_interface      ((np_usersocket *) 0x00000500) // altera_avalon_user_defined_interface
+#define na_ide_interface_base                    0x00000500
+#define na_ide_interface_irq                     25
+#define na_enet               ((void *)          0x00004000) // altera_avalon_lan91c111
+#define na_enet_base                             0x00004000
+#define na_enet_end           ((void *)          0x00004020)
+#define na_enet_size                             0x00000020
+#define na_enet_irq                              35
+#define na_enet_reset_n       ((np_pio *)        0x00004020) // altera_avalon_pio
+#define na_enet_reset_n_base                     0x00004020
+#define na_flash              ((void *)          0x00100000) // altera_nios_dev_board_flash
+#define na_flash_base                            0x00100000
+#define na_flash_end          ((void *)          0x00200000)
+#define na_flash_size                            0x00100000
+#define na_flash_kernel       ((void *)          0x00800000) // mtx_sodimm_flash_controller
+#define na_flash_kernel_base                     0x00800000
+#define na_flash_kernel_end   ((void *)          0x01000000)
+#define na_flash_kernel_size                     0x00800000
+#define na_sdram              ((void *)          0x01000000) // altera_avalon_sdram_controller
+#define na_sdram_base                            0x01000000
+#define na_sdram_end          ((void *)          0x02000000)
+#define na_sdram_size                            0x01000000
+ 
+#define na_null                           0
+#define nasys_flash_count                 1
+#define nasys_flash_0                     na_flash
+#define nasys_pio_count                   3
+#define nasys_pio_0                       na_ssram_detect
+#define nasys_pio_1                       na_button_pio
+#define nasys_pio_2                       na_enet_reset_n
+#define nasys_spi_count                   1
+#define nasys_spi_0                       na_spi
+#define nasys_spi_0_irq                   19
+#define nasys_timer_count                 1
+#define nasys_timer_0                     na_timer0
+#define nasys_timer_0_irq                 16
+#define nasys_uart_count                  2
+#define nasys_uart_0                      na_uart0
+#define nasys_uart_0_irq                  17
+#define nasys_uart_1                      na_uart1
+#define nasys_uart_1_irq                  18
+#define nasys_usersocket_count            1
+#define nasys_usersocket_0                na_ide_interface
+#define nasys_usersocket_0_irq            25
+#define nasys_vector_table      ((int *)  0x01000000)
+#define nasys_vector_table_size           0x00000100
+#define nasys_vector_table_end  ((int *)  0x01000100)
+#define nasys_reset_address     ((void *) 0x00000000)
+#define nasys_clock_freq                  33333000
+#define nasys_clock_freq_1000             33333
+#define nasys_debug_core                  0
+#define nasys_printf_uart                 na_uart0
+#define nasys_printf_uart_irq             na_uart0_irq
+#define nm_printf_txchar                  nr_uart_txchar
+#define nm_printf_rxchar                  nr_uart_rxchar
+#define nasys_debug_uart                  na_uart1
+#define nasys_debug_uart_irq              na_uart1_irq
+#define nasys_main_flash                  na_flash
+#define nasys_main_flash_size             na_flash_size
+#define nasys_main_flash_end              na_flash_end
+#define nasys_program_mem       ((void *) 0x01000100)
+#define nasys_program_mem_size            0x00ffff00
+#define nasys_program_mem_end   ((void *) 0x02000000)
+#define nasys_data_mem          ((void *) 0x01000100)
+#define nasys_data_mem_size               0x00ffff00
+#define nasys_data_mem_end      ((void *) 0x02000000)
+#define nasys_stack_top         ((void *) 0x02000000)
+ 
+#define PLUGS_PLUG_COUNT           5 // Maximum number of plugs
+#define PLUGS_ADAPTER_COUNT        2 // Maximum number of adapters
+#define PLUGS_DNS                  1 // Have routines for DNS lookups
+#define PLUGS_PING                 1 // Respond to icmp echo (ping) messages
+#define PLUGS_TCP                  1 // Support tcp in/out connections
+#define PLUGS_IRQ                  1 // Run at interrupte level
+#define PLUGS_DEBUG                1 // Support debug routines
+#define __nios_catch_irqs__        1 // Include panic handler for all irqs (needs uart)
+#define __nios_use_constructors__  1 // Call c++ static constructors
+#define __nios_use_cwpmgr__        1 // Handle register window underflows
+#define __nios_use_fast_mul__      1 // Faster but larger int multiply routine
+#define __nios_use_small_printf__  0 // Smaller non-ANSI printf, with no floating point
+#define __nios_use_multiply__      0 // Use MUL instruction for 16x16
+#define __nios_use_mstep__         0 // Use MSTEP instruction for 16x16
+
+
+
+#define nm_system_name_string "LDK2"
+#define nm_cpu_name_string "cpu"
+#define nm_monitor_string "L20e1"
+#define nm_cpu_architecture nios_32
+#define nm_cpu_architecture_string "nios_32"
+#define nios_32 1
+
+// Structures and Routines For Each Peripheral
+
+
+// Nios CPU Routines
+void nr_installcwpmanager(void);	// called automatically at by nr_setup.s
+void nr_delay(int milliseconds);	// approximate timing based on clock speed
+void nr_zerorange(char *rangeStart,int rangeByteCount);
+void nr_jumptoreset(void);
+
+// Nios ISR Manager Routines
+typedef void (*nios_isrhandlerproc)(int context);
+typedef void (*nios_isrhandlerproc2)(int context,int irq_number,int interruptee_pc);
+void nr_installuserisr(int trapNumber,nios_isrhandlerproc handlerProc,int context);
+void nr_installuserisr2(int trapNumber,nios_isrhandlerproc2 handlerProc,int context);
+
+// Nios GDB Stub Functions
+void nios_gdb_install(int active);
+#define nios_gdb_breakpoint() asm("TRAP 5")
+
+// Default UART routines
+void nr_txchar(int c);
+void nr_txstring(char *s);
+int nr_rxchar(void);
+
+// Debug UART routines
+void nr_debug_txchar(int c);
+void nr_debug_txstring(char *s);
+int nr_debug_rxchar(void);
+
+// Nios Private Printf Routines
+int nr_printf(const char *fmt,...);
+int nr_sprintf(char *sOut,const char *fmt,...);
+
+#if __nios_use_small_printf__
+	#define printf nr_printf
+	#define sprintf nr_sprintf
+#endif
+
+#ifdef na_enet
+void nios_gdb_install_ethernet(int active);
+int nr_debug_plugs_idle (void);
+#endif
+
+#if __nios_debug__
+	#define NIOS_GDB_SETUP 		\
+		nios_gdb_install(1);	\
+		nios_gdb_breakpoint(void);
+#else
+	#define NIOS_GDB_SETUP
+#endif
+
+// Nios setjmp/longjmp support
+// (This will collide with <setjmp.h>
+// if you include it! These are the
+// nios-correct versions, however.)
+
+typedef int jmp_buf[2];
+
+int nr_setjmp(jmp_buf env);
+int nr_longjmp(jmp_buf env,int value);
+
+#define setjmp(a) nr_setjmp((a))
+#define longjmp(a,b) nr_longjmp((a),(b))
+
+
+// debug Core Declarations
+
+#define nasys_debug_core_irq                8
+
+// debug registers offsets from base
+enum
+{
+    np_debug_interrupt =		0,		//read-only,  4 bits, reading stops trace
+    np_debug_n_samples_lsb,			//read-only, 16 bits
+    np_debug_n_samples_msb,			//read-only, 16 bits
+    np_debug_data_valid,				//read-only, 1 bit, 
+    						//true when trace registers contain valid sample
+    np_debug_trace_address,			//read-only, 16 or 32 bits
+    np_debug_trace_data,				//read-only, 16 or 32 bits
+    np_debug_trace_code,				//read-only, 16 or 32 bits
+    np_debug_write_status,			//read-only, 1 bit, 
+    						//true when read to readback tracedata
+    np_debug_start,				//write-only, write any value to start
+    np_debug_stop,				//write-only, write any value to stop
+    np_debug_read_sample,				//write-only, write any value to read
+    np_debug_trace_mode,				//write-only, 1 bit
+    np_debug_mem_int_enable,			//write-only, 16 or 32 bits ?????
+    np_debug_ext_brk_enable,			//write-only, 1 bit
+    np_debug_sw_reset,				//write-only, reset sampels and trace memory
+
+    np_debug_address_pattern_0 =	16,		//write-only, 16 or 32 bits
+    np_debug_address_mask_0,			//write-only, 16 or 32 bits
+    np_debug_data_pattern_0,			//write-only, 16 or 32 bits
+    np_debug_data_mask_0,				//write-only, 16 or 32 bits
+    np_debug_code_0,				//write-only, 16 or 32 bits
+
+    np_debug_address_pattern_1 =	24,		//write-only, 16 or 32 bits
+    np_debug_address_mask_1,			//write-only, 16 or 32 bits
+    np_debug_data_pattern_1,			//write-only, 16 or 32 bits
+    np_debug_data_mask_1,				//write-only, 16 or 32 bits
+    np_debug_code_1,				//write-only, 16 or 32 bits
+};
+
+// debug Register Bits/Codes
+enum 
+{ 
+    /************************************************/
+    // debug_interrupt register
+    // bit numbers
+    np_debug_interrupt_code_dbp0_bit = 0,
+    np_debug_interrupt_code_dbp1_bit = 1,
+    np_debug_interrupt_code_ibp0_bit = 2,
+    np_debug_interrupt_code_ibp1_bit = 3,
+    np_debug_interrupt_code_mem_bit = 4,
+
+    // bit masks
+    np_debug_interrupt_code_ext_mask = (0), 
+    np_debug_interrupt_code_dbp0_mask = (1<<0),
+    np_debug_interrupt_code_dbp1_mask = (1<<1),
+    np_debug_interrupt_code_ibp0_mask = (1<<2),
+    np_debug_interrupt_code_ibp1_mask = (1<<3),
+    np_debug_interrupt_code_mem_mask = (1<<4),
+
+    /************************************************/
+    // debug_trace_code register
+    // bit numbers
+    np_debug_trace_code_skp_bit = 1,
+    np_debug_trace_code_fifo_full_bit = 2,
+    np_debug_trace_code_bus_bit = 3,
+    np_debug_trace_code_rw_bit = 4,
+    np_debug_trace_code_intr_bit = 5,
+    
+    // bit masks
+    np_debug_trace_code_skp_mask = (1<<0),
+    np_debug_trace_code_fifo_full_mask = (1<<1),
+    np_debug_trace_code_data_trans_mask = (1<<2), //instr trans if 0
+    np_debug_trace_code_write_mask = (1<<3),	//read if 0
+    np_debug_trace_code_intr_mask = (1<<4),
+#ifdef __nios32__
+    np_debug_trace_code_skp_cnt_mask = (63<<2),
+#else
+    np_debug_trace_code_skp_cnt_mask = (31<<2),
+#endif
+
+    // useful constants
+    np_debug_trace_code_op_mask = (np_debug_trace_code_data_trans_mask|np_debug_trace_code_write_mask),
+    np_debug_trace_code_read = np_debug_trace_code_data_trans_mask,
+    np_debug_trace_code_write = (np_debug_trace_code_data_trans_mask|np_debug_trace_code_write_mask),
+    np_debug_trace_code_fetch = 0,
+
+    /************************************************/
+    // debug_code_* registers
+    // bit numbers
+    np_debug_break_code_read_bit = 0,
+    np_debug_break_code_write_bit = 1,
+    np_debug_break_code_fetch_bit = 2,
+
+    // bit masks
+    np_debug_break_code_read_mask = (1<<0),
+    np_debug_break_code_write_mask = (1<<1),
+    np_debug_break_code_fetch_mask = (1<<2),
+
+    /************************************************/
+    // debug_write_status register
+    // bit numbers
+    np_debug_write_status_writing_bit = 0,
+    np_debug_write_status_nios32_bit = 1,
+    np_debug_write_status_trace_bit = 2,
+
+    // bit masks
+    np_debug_write_status_writing_mask = (1<<0),
+    np_debug_write_status_nios32_mask = (1<<1),
+    np_debug_write_status_trace_mask = (1<<2)
+};
+
+// debug Routine
+
+
+//Get the number of trace samples 
+unsigned long nr_debug_num_samples (void);	
+
+//Stop debug core - this must be a function so that a branch is the last
+//                  thing in the fifo.  Otherwise a skip or a read/write
+//                  might be logged without the ability to sync it up
+void nr_debug_stop (void);
+
+//Read a trace sample
+void nr_debug_get_sample (unsigned int *trace_addr, 
+			unsigned int *trace_data, 
+			unsigned char *trace_code);
+
+//must have a uart for these functions
+#ifdef nasys_uart_count
+#if (nasys_uart_count > 0)
+
+  //print cause of break
+  void nr_debug_show_break (void *uart);
+                                  // 0 for default printf uart
+
+  //dump the trace memory
+  void nr_debug_dump_trace (void *uart);
+                             // 0 for defualt printf uart
+
+  //ISR for debug interrupts
+  //Show cause of break, dump trace, and halt
+  void nr_debug_isr_halt (int context);		
+                            // 0 for default printf uart otherwise uart base address
+
+  //Show cause of break, dump trace, and continue
+  void nr_debug_isr_continue (int context);		
+                                // 0 for default printf uart otherwise uart base address
+
+#endif
+#endif
+
+// debug macros
+//Read a debug register
+#define nm_debug_get_reg(ret, offset) 		\
+		asm volatile (			\
+			"PFX 3 \n		\
+			WRCTL %1 \n		\
+			PFX 4 \n		\
+			RDCTL %0;"		\
+			:"=r" (ret)		\
+			:"r"(offset)		\
+		);
+
+//Write a debug register
+#define nm_debug_set_reg(val,offset) 		\
+		asm volatile (			\
+			"PFX 3 \n		\
+			WRCTL %1 \n		\
+			PFX 4 \n		\
+			WRCTL %0;"		\
+			: /* no outputs */	\
+			:"r"(val),"r"(offset)	\
+		);
+
+//Set breakpoint 0
+#define nm_debug_set_bp0(ap,am,dp,dm,cd) nm_debug_set_reg(ap,np_debug_address_pattern_0);\
+				       nm_debug_set_reg(am,np_debug_address_mask_0);\
+				       nm_debug_set_reg(dp,np_debug_data_pattern_0);\
+				       nm_debug_set_reg(dm,np_debug_data_mask_0);\
+				       nm_debug_set_reg(cd,np_debug_code_0);
+
+//Set breakpoint 1
+#define nm_debug_set_bp1(ap,am,dp,dm,cd) nm_debug_set_reg(ap,np_debug_address_pattern_1);\
+				       nm_debug_set_reg(am,np_debug_address_mask_1);\
+				       nm_debug_set_reg(dp,np_debug_data_pattern_1);\
+				       nm_debug_set_reg(dm,np_debug_data_mask_1);\
+				       nm_debug_set_reg(cd,np_debug_code_1);
+
+//Set extended trace mode
+#define nm_debug_set_extended_trace nm_debug_set_reg(1,np_debug_trace_mode);
+
+//Set memory interrupt point
+#define nm_debug_set_wrap_point(size) nm_debug_set_reg((size>>2),np_debug_mem_int_enable);
+
+// UART Registers
+typedef volatile struct
+	{
+	int np_uartrxdata;      // Read-only, 8-bit
+	int np_uarttxdata;      // Write-only, 8-bit
+	int np_uartstatus;      // Read-only, 8-bit
+	int np_uartcontrol;     // Read/Write, 9-bit
+	int np_uartdivisor;     // Read/Write, 16-bit, optional
+	int np_uartendofpacket; // Read/Write, end-of-packet character
+	} np_uart;
+
+// UART Status Register Bits
+enum
+	{
+	np_uartstatus_eop_bit  = 12,
+	np_uartstatus_cts_bit  = 11,
+	np_uartstatus_dcts_bit = 10,
+	np_uartstatus_e_bit    = 8,
+	np_uartstatus_rrdy_bit = 7,
+	np_uartstatus_trdy_bit = 6,
+	np_uartstatus_tmt_bit  = 5,
+	np_uartstatus_toe_bit  = 4,
+	np_uartstatus_roe_bit  = 3,
+	np_uartstatus_brk_bit  = 2,
+	np_uartstatus_fe_bit   = 1,
+	np_uartstatus_pe_bit   = 0,
+
+	np_uartstatus_eop_mask  = (1<<12),
+	np_uartstatus_cts_mask  = (1<<11),
+	np_uartstatus_dcts_mask = (1<<10),
+	np_uartstatus_e_mask    = (1<<8),
+	np_uartstatus_rrdy_mask = (1<<7),
+	np_uartstatus_trdy_mask = (1<<6),
+	np_uartstatus_tmt_mask  = (1<<5),
+	np_uartstatus_toe_mask  = (1<<4),
+	np_uartstatus_roe_mask  = (1<<3),
+	np_uartstatus_brk_mask  = (1<<2),
+	np_uartstatus_fe_mask   = (1<<1),
+	np_uartstatus_pe_mask   = (1<<0)
+	};
+
+// UART Control Register Bits
+enum
+	{
+	np_uartcontrol_ieop_bit  = 12,
+	np_uartcontrol_rts_bit   = 11,
+	np_uartcontrol_idcts_bit = 10,
+	np_uartcontrol_tbrk_bit  = 9,
+	np_uartcontrol_ie_bit    = 8,
+	np_uartcontrol_irrdy_bit = 7,
+	np_uartcontrol_itrdy_bit = 6,
+	np_uartcontrol_itmt_bit  = 5,
+	np_uartcontrol_itoe_bit  = 4,
+	np_uartcontrol_iroe_bit  = 3,
+	np_uartcontrol_ibrk_bit  = 2,
+	np_uartcontrol_ife_bit   = 1,
+	np_uartcontrol_ipe_bit   = 0,
+
+	np_uartcontrol_ieop_mask  = (1<<12),
+	np_uartcontrol_rts_mask   = (1<<11),
+	np_uartcontrol_idcts_mask = (1<<10),
+	np_uartcontrol_tbrk_mask  = (1<<9),
+	np_uartcontrol_ie_mask    = (1<<8),
+	np_uartcontrol_irrdy_mask = (1<<7),
+	np_uartcontrol_itrdy_mask = (1<<6),
+	np_uartcontrol_itmt_mask  = (1<<5),
+	np_uartcontrol_itoe_mask  = (1<<4),
+	np_uartcontrol_iroe_mask  = (1<<3),
+	np_uartcontrol_ibrk_mask  = (1<<2),
+	np_uartcontrol_ife_mask   = (1<<1),
+	np_uartcontrol_ipe_mask   = (1<<0)
+	};
+
+// UART Routines
+int nr_uart_rxchar(np_uart *uartBase);        // 0 for default UART
+void nr_uart_txcr(void);
+void nr_uart_txchar(int c,np_uart *uartBase); // 0 for default UART
+void nr_uart_txhex(int x);                     // 16 or 32 bits
+void nr_uart_txhex16(short x);
+void nr_uart_txhex32(long x);
+void nr_uart_txstring(char *s);
+
+
+// ----------------------------------------------
+// Timer Peripheral
+
+// Timer Registers
+typedef volatile struct
+	{
+	int np_timerstatus;  // read only, 2 bits (any write to clear TO)
+	int np_timercontrol; // write/readable, 4 bits
+	int np_timerperiodl; // write/readable, 16 bits
+	int np_timerperiodh; // write/readable, 16 bits
+	int np_timersnapl;   // read only, 16 bits
+	int np_timersnaph;   // read only, 16 bits
+	} np_timer;
+
+// Timer Register Bits
+enum
+	{
+	np_timerstatus_run_bit    = 1, // timer is running
+	np_timerstatus_to_bit     = 0, // timer has timed out
+
+	np_timercontrol_stop_bit  = 3, // stop the timer
+	np_timercontrol_start_bit = 2, // start the timer
+	np_timercontrol_cont_bit  = 1, // continous mode
+	np_timercontrol_ito_bit   = 0, // enable time out interrupt
+
+	np_timerstatus_run_mask    = (1<<1), // timer is running
+	np_timerstatus_to_mask     = (1<<0), // timer has timed out
+
+	np_timercontrol_stop_mask  = (1<<3), // stop the timer
+	np_timercontrol_start_mask = (1<<2), // start the timer
+	np_timercontrol_cont_mask  = (1<<1), // continous mode
+	np_timercontrol_ito_mask   = (1<<0)  // enable time out interrupt
+	};
+
+// Timer Routines
+int nr_timer_milliseconds(void);	// Starts on first call, hogs timer1.
+
+// PIO Peripheral
+
+// PIO Registers
+typedef volatile struct
+	{
+	int np_piodata;          // read/write, up to 32 bits
+	int np_piodirection;     // write/readable, up to 32 bits, 1->output bit
+	int np_piointerruptmask; // write/readable, up to 32 bits, 1->enable interrupt
+	int np_pioedgecapture;   // read, up to 32 bits, cleared by any write
+	} np_pio;
+
+// PIO Routines
+void nr_pio_showhex(int value); // shows low byte on pio named na_seven_seg_pio
+
+// SPI Registers
+typedef volatile struct
+	{
+	int np_spirxdata;       // Read-only, 1-16 bit
+	int np_spitxdata;       // Write-only, same width as rxdata
+	int np_spistatus;       // Read-only, 9-bit
+	int np_spicontrol;      // Read/Write, 9-bit
+	int np_spireserved;     // reserved
+	int np_spislaveselect;  // Read/Write, 1-16 bit, master only
+  int np_spiendofpacket;  // Read/write, same width as txdata, rxdata.
+	} np_spi;
+
+// SPI Status Register Bits
+enum
+{
+  np_spistatus_eop_bit  = 9,
+	np_spistatus_e_bit    = 8,
+	np_spistatus_rrdy_bit = 7,
+	np_spistatus_trdy_bit = 6,
+	np_spistatus_tmt_bit  = 5,
+	np_spistatus_toe_bit  = 4,
+	np_spistatus_roe_bit  = 3,
+
+  np_spistatus_eop_mask  = (1 << 9),
+	np_spistatus_e_mask    = (1 << 8),
+	np_spistatus_rrdy_mask = (1 << 7),
+	np_spistatus_trdy_mask = (1 << 6),
+	np_spistatus_tmt_mask  = (1 << 5),
+	np_spistatus_toe_mask  = (1 << 4),
+	np_spistatus_roe_mask  = (1 << 3),
+	};
+
+// SPI Control Register Bits
+enum
+	{
+  np_spicontrol_ieop_bit  = 9,
+	np_spicontrol_ie_bit    = 8,
+	np_spicontrol_irrdy_bit = 7,
+	np_spicontrol_itrdy_bit = 6,
+	np_spicontrol_itoe_bit  = 4,
+	np_spicontrol_iroe_bit  = 3,
+
+  np_spicontrol_ieop_mask  = (1 << 9),
+	np_spicontrol_ie_mask    = (1 << 8),
+	np_spicontrol_irrdy_mask = (1 << 7),
+	np_spicontrol_itrdy_mask = (1 << 6),
+
+	np_spicontrol_itoe_mask  = (1 << 4),
+	np_spicontrol_iroe_mask  = (1 << 3),
+	};
+
+// SPI Routines.
+int nr_spi_rxchar(np_spi *spiBase);
+int nr_spi_txchar(int i, np_spi *spiBase);
+
+
+
+// ----------------------------------------------
+// User Socket
+
+typedef void *np_usersocket;
+
+
+// Nios Flash Memory Routines
+
+// All routines take a "flash base" parameter.  If -1 is supplied,
+// nasys_main_flash is used.
+
+int nr_flash_erase_sector
+		(
+		unsigned short *flash_base,
+  		unsigned short *sector_address
+		);
+
+int nr_flash_erase
+		(
+		unsigned short *flash_base
+		);
+
+int nr_flash_write
+		(
+		unsigned short *flash_base,
+  		unsigned short *address,
+		unsigned short value
+		);
+
+int nr_flash_write_buffer
+		(
+		unsigned short *flash_base,
+  		unsigned short *start_address,
+  		unsigned short *buffer,
+		int halfword_count
+		);
+
+
+
+
+
+// ===========================================================
+// Parameters for Each Peripheral, Excerpted From The PTF File
+
+
+
+// ------------------
+// Parameters for altera_avalon_onchip_memory named mon
+
+// Writeable              = 0
+// Size_Value             = 1
+// Size_Multiple          = 1024
+// Contents               = blank
+// Shrink_to_fit_contents = 0
+// CONTENTS               = srec
+// use_altsyncram         = 0
+
+
+
+// ------------------
+// Parameters for altera_nios named cpu
+
+// CPU_Architecture     = nios_32
+// mstep                = 1
+// multiply             = 0
+// rom_decoder          = 1
+// wvalid_wr            = 0
+// num_regs             = 512
+// do_generate          = 1
+// include_debug        = 0
+// include_trace        = 0
+// reset_slave          = mon/s1
+// reset_offset         = 0x00000000
+// vecbase_slave        = sdram/s1
+// vecbase_offset       = 0x00000000
+// support_interrupts   = 1
+// implement_forward_b1 = 1
+// support_rlc_rrc      = 0
+// advanced             = 1
+// CONSTANTS            =
+// mainmem_slave        = sdram/s1
+// datamem_slave        = sdram/s1
+// maincomm_slave       = uart0/s1
+// debugcomm_slave      = uart1/s1
+// germs_monitor_id     = L20e1
+
+
+
+// ------------------
+// Parameters for altera_avalon_uart named uart0
+
+// baud             = 115200
+// data_bits        = 8
+// fixed_baud       = 1
+// parity           = N
+// stop_bits        = 2
+// use_cts_rts      = 0
+// use_eop_register = 0
+// sim_true_baud    = 0
+// sim_char_stream  =
+
+
+
+// ------------------
+// Parameters for altera_avalon_timer named timer0
+
+// always_run           = 0
+// fixed_period         = 0
+// snapshot             = 1
+// period               = 1
+// period_units         = msec
+// reset_output         = 0
+// timeout_pulse_output = 0
+// mult                 = 0.001
+
+
+
+// ------------------
+// Parameters for altera_avalon_pio named ssram_detect
+
+// has_tri   = 0
+// has_out   = 0
+// has_in    = 1
+// capture   = 0
+// edge_type = NONE
+// irq_type  = NONE
+
+
+
+// ------------------
+// Parameters for altera_avalon_pio named button_pio
+
+// has_tri   = 0
+// has_out   = 0
+// has_in    = 1
+// capture   = 0
+// edge_type = NONE
+// irq_type  = NONE
+
+
+
+// ------------------
+// Parameters for altera_avalon_spi named spi
+
+// databits      = 16
+// targetclock   = 250
+// clockunits    = kHz
+// clockmult     = 1000
+// numslaves     = 2
+// ismaster      = 1
+// clockpolarity = 0
+// clockphase    = 1
+// lsbfirst      = 0
+// extradelay    = 1
+// targetssdelay = 2
+// delayunits    = us
+// delaymult     = 1e-006
+// clockunit     = kHz
+// delayunit     = us
+
+
+
+// ------------------
+// Parameters for altera_avalon_uart named uart1
+
+// baud             = 115200
+// data_bits        = 8
+// fixed_baud       = 1
+// parity           = N
+// stop_bits        = 1
+// use_cts_rts      = 0
+// use_eop_register = 0
+// sim_true_baud    = 0
+// sim_char_stream  =
+
+
+
+// ------------------
+// Parameters for altera_avalon_user_defined_interface named ide_interface
+
+// HDL_Import              = 0
+// Imported_Wait           = 0
+// Nios_Gen_Waits          = 0
+// Synthesize_Imported_HDL = 1
+// Component_Desc          =
+// Component_Name          =
+// Module_Name             =
+// Technology              =
+// Port_Type               = Avalon Slave
+// Timing_Units            = ns
+// Address_Width           = 32
+// Module_List             =
+
+
+
+// ------------------
+// Parameters for altera_avalon_lan91c111 named enet
+
+// CONSTANTS =
+
+
+
+// ------------------
+// Parameters for altera_avalon_pio named enet_reset_n
+
+// has_tri   = 0
+// has_out   = 1
+// has_in    = 0
+// capture   = 0
+// edge_type = NONE
+// irq_type  = NONE
+
+
+
+// ------------------
+// Parameters for altera_nios_dev_board_flash named flash
+
+// CONTENTS = srec
+
+
+
+// ------------------
+// Parameters for altera_avalon_sdram_controller named sdram
+
+// sdram_data_width      = 32
+// sdram_addr_width      = 11
+// sdram_bank_width      = 2
+// sdram_row_width       = 11
+// sdram_col_width       = 8
+// sdram_num_chipselects = 2
+// refresh_period        = 15.625
+// powerup_delay         = 100
+// cas_latency           = 2
+// precharge_control_bit = 10
+// t_rfc                 = 70
+// t_rp                  = 20
+// t_mrd                 = 2
+// t_rcd                 = 20
+// t_ac                  = 8
+// t_wr_auto_precharge_a = 1
+// t_wr_auto_precharge_b = 7
+// t_wr_precharge        = 14
+// init_refresh_commands = 2
+// init_nop_delay        = 0
+// shared_data           = 0
+// enable_ifetch         = 0
+// highperf              = 0
+// sim_model_base        =
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_excalibur_
+
+// end of file
diff -urN linux-2.4.29/include/asm-niosnommu/page.h linux-2.4.29-uc1/include/asm-niosnommu/page.h
--- linux-2.4.29/include/asm-niosnommu/page.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/page.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,108 @@
+#ifndef _NIOS_PAGE_H
+#define _NIOS_PAGE_H
+
+/* copied from m68knommu arch */
+#include <linux/config.h>
+
+/* PAGE_SHIFT determines the page size */
+
+#define PAGE_SHIFT	(12)
+#define PAGE_SIZE	(4096)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+
+#ifdef __KERNEL__
+
+#include <asm/setup.h>
+
+#if PAGE_SHIFT < 13
+#define THREAD_SIZE (8192)
+#else
+#define THREAD_SIZE PAGE_SIZE
+#endif
+ 
+#ifndef __ASSEMBLY__
+ 
+#define get_user_page(vaddr)		__get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr)	free_page(addr)
+
+#define clear_page(page)	memset((page), 0, PAGE_SIZE)
+#define copy_page(to,from)	memcpy((to), (from), PAGE_SIZE)
+
+#define clear_user_page(page, vaddr)	clear_page(page)
+#define copy_user_page(to, from, vaddr)	copy_page(to, from)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pmd[16]; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)	((x).pte)
+#define pmd_val(x)	((&x)->pmd[0])
+#define pgd_val(x)	((x).pgd)
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x)	((pte_t) { (x) } )
+#define __pmd(x)	((pmd_t) { (x) } )
+#define __pgd(x)	((pgd_t) { (x) } )
+#define __pgprot(x)	((pgprot_t) { (x) } )
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+/* Pure 2^n version of get_order */
+extern __inline__ int get_order(unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+#endif /* !__ASSEMBLY__ */
+#include <asm/nios.h>
+#define PAGE_OFFSET		((int)(na_sdram))
+
+#ifndef __ASSEMBLY__
+
+#define __pa(vaddr)		virt_to_phys((void *)vaddr)
+#define __va(paddr)		phys_to_virt((unsigned long)paddr)
+
+#define MAP_NR(addr)		(((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
+#define virt_to_page(addr)	(mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
+#define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
+
+
+#ifdef CONFIG_NO_KERNEL_MSG
+#define	BUG_PRINT()
+#else
+#define	BUG_PRINT() printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__)
+#endif
+
+
+#define BUG_PANIC()	asm volatile ("trap 5") /* drop to debugger */
+// #define BUG_PANIC()	while(1)
+// #define BUG_PANIC()	panic("BUG!")
+
+
+#define BUG() do { \
+	BUG_PRINT(); \
+	BUG_PANIC(); \
+} while (0)
+
+#define PAGE_BUG(page) do { \
+	BUG(); \
+} while (0)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _NIOS_PAGE_H */
diff -urN linux-2.4.29/include/asm-niosnommu/param.h linux-2.4.29-uc1/include/asm-niosnommu/param.h
--- linux-2.4.29/include/asm-niosnommu/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/param.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,20 @@
+#ifndef _NIOS_PARAM_H
+#define _NIOS_PARAM_H
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#define EXEC_PAGESIZE	4096
+
+#ifndef NGROUPS
+#define NGROUPS		32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#endif
diff -urN linux-2.4.29/include/asm-niosnommu/pci.h linux-2.4.29-uc1/include/asm-niosnommu/pci.h
--- linux-2.4.29/include/asm-niosnommu/pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/pci.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,9 @@
+#ifndef __ASM_NIOS_PCI_H
+#define __ASM_NIOS_PCI_H
+
+/* NIOS systems don't have a PCI bus. This file is just here because some stupid .c code
+ * includes it even if CONFIG_PCI is not set.
+ */
+
+#endif /* __ASM_NIOS_PCI_H */
+
diff -urN linux-2.4.29/include/asm-niosnommu/pgalloc.h linux-2.4.29-uc1/include/asm-niosnommu/pgalloc.h
--- linux-2.4.29/include/asm-niosnommu/pgalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/pgalloc.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,138 @@
+#ifndef _NIOS_PGALLOC_H
+#define _NIOS_PGALLOC_H
+
+/*
+ * Copyright (C) 2000 Lineo, David McCullough <davidm@lineo.com>
+ * Copyright (C) 2001 Lineo, Greg Ungerer <gerg@lineo.com>
+ * 
+ * Moved from m68knommu version
+ */
+
+#include <asm/setup.h>
+#include <asm/virtconvert.h>
+
+/*
+ * Cache handling functions
+ */
+
+#if DAVIDM
+/*
+ * invalidate the cache for the specified memory range.
+ * It starts at the physical address specified for
+ * the given number of bytes.
+ */
+extern void cache_clear(unsigned long paddr, int len);
+
+/*
+ * push any dirty cache in the specified memory range.
+ * It starts at the physical address specified for
+ * the given number of bytes.
+ */
+extern void cache_push(unsigned long paddr, int len);
+
+/*
+ * push and invalidate pages in the specified user virtual
+ * memory range.
+ */
+extern void cache_push_v(unsigned long vaddr, int len);
+
+/* This is needed whenever the virtual mapping of the current
+   process changes.  */
+#endif
+
+extern inline void __flush_cache_all(void)
+{
+#ifdef CONFIG_M5407
+	/*
+	 *	This seems like overkill. Just flushing the cache using
+	 *	cpushl doesn't seem to be enough. I have to go and explicitly
+	 *	invalidate all the caches as well for reliable behavior.
+	 */
+	__asm__ __volatile__ (
+		"nop\n\t"
+		"clrl	%%d0\n\t"
+		"1:\n\t"
+		"movel	%%d0,%%a0\n\t"
+		"2:\n\t"
+		".word	0xf4e8\n\t"
+		"addl	#0x10,%%a0\n\t"
+		"cmpl	#0x00000800,%%a0\n\t"
+		"blt	2b\n\t"
+		"addql	#1,%%d0\n\t"
+		"cmpil	#4,%%d0\n\t"
+		"bne	1b\n\t"
+		"movel  #0x01040100,%%d0\n\t"
+		"movec  %%d0,%%CACR\n\t"
+		"nop\n\t"
+		"movel  #0x86088400,%%d0\n\t"
+		"movec  %%d0,%%CACR\n\t"
+		: : : "d0", "a0" );
+#endif /* CONFIG_M5407 */
+}
+
+#define flush_cache_all()					__flush_cache_all()
+#define flush_cache_mm(mm)					__flush_cache_all()
+#define flush_cache_range(mm, start, end)	__flush_cache_all()
+#define flush_cache_page(vma, vmaddr)		__flush_cache_all()
+#define flush_page_to_ram(page)				__flush_cache_all()
+#define flush_dcache_page(page)				__flush_cache_all()
+#define flush_icache_range(start, end)		__flush_cache_all()
+#define flush_icache_page(vma,pg)			__flush_cache_all()
+#define flush_icache()						__flush_cache_all()
+#define flush_icache_user_range(a,b,c,d)    do { } while(0)
+
+/*
+ * DAVIDM - the rest of these are just so I can check where they happen
+ */
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+	BUG();
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+	BUG();
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+	BUG();
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+	BUG();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+	BUG();
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+				   unsigned long start, unsigned long end)
+{
+	BUG();
+}
+
+extern inline void flush_tlb_kernel_page(unsigned long addr)
+{
+	BUG();
+}
+
+extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+				      unsigned long start, unsigned long end)
+{
+	BUG();
+}
+
+#endif /* _NIOS_PGALLOC_H */
diff -urN linux-2.4.29/include/asm-niosnommu/pgtable.h linux-2.4.29-uc1/include/asm-niosnommu/pgtable.h
--- linux-2.4.29/include/asm-niosnommu/pgtable.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/pgtable.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,48 @@
+#ifndef _NIOS_PGTABLE_H
+#define _NIOS_PGTABLE_H
+
+
+//vic - this bit copied from m68knommu version
+#include <linux/config.h>
+#include <asm/setup.h>
+
+#define pgd_present(pgd)     (1)       /* pages are always present on NO_MM */
+#define kern_addr_valid(addr) (1)
+
+#define PAGE_NONE		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_SHARED		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_COPY		__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_READONLY	__pgprot(0)    /* these mean nothing to NO_MM */
+#define PAGE_KERNEL		__pgprot(0)    /* these mean nothing to NO_MM */
+//vic - this bit copied from m68knommu version
+
+
+extern void paging_init(void);
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()   do { } while (0)
+
+extern inline void flush_cache_mm(struct mm_struct *mm)
+{
+}
+
+extern inline void flush_cache_range(struct mm_struct *mm,
+				     unsigned long start,
+				     unsigned long end)
+{
+}
+
+/* Push the page at kernel virtual address and clear the icache */
+extern inline void flush_page_to_ram (unsigned long address)
+{
+}
+
+/* Push n pages at kernel virtual address and clear the icache */
+extern inline void flush_pages_to_ram (unsigned long address, int n)
+{
+}
+
+
+#endif /* _NIOS_PGTABLE_H */
diff -urN linux-2.4.29/include/asm-niosnommu/poll.h linux-2.4.29-uc1/include/asm-niosnommu/poll.h
--- linux-2.4.29/include/asm-niosnommu/poll.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/poll.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,22 @@
+#ifndef __NIOS_POLL_H
+#define __NIOS_POLL_H
+
+#define POLLIN		  1
+#define POLLPRI		  2
+#define POLLOUT		  4
+#define POLLERR		  8
+#define POLLHUP		 16
+#define POLLNVAL	 32
+#define POLLRDNORM	 64
+#define POLLWRNORM	POLLOUT
+#define POLLRDBAND	128
+#define POLLWRBAND	256
+#define POLLMSG		0x0400
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-niosnommu/posix_types.h linux-2.4.29-uc1/include/asm-niosnommu/posix_types.h
--- linux-2.4.29/include/asm-niosnommu/posix_types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/posix_types.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,63 @@
+#ifndef __ARCH_NIOS_POSIX_TYPES_H
+#define __ARCH_NIOS_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned short	__kernel_dev_t;
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned short	__kernel_mode_t;
+typedef unsigned short	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
+typedef unsigned short	__kernel_uid_t;
+typedef unsigned short	__kernel_gid_t;
+typedef unsigned long	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+typedef unsigned short	__kernel_old_uid_t;
+typedef unsigned short	__kernel_old_gid_t;
+
+#ifdef __GNUC__
+typedef long long	__kernel_loff_t;
+#endif
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+	int	val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+	int	__val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#undef	__FD_SET
+#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+
+#undef	__FD_CLR
+#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+
+#undef	__FD_ISSET
+#define	__FD_ISSET(d, set)	((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
+
+#undef	__FD_ZERO
+#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif
diff -urN linux-2.4.29/include/asm-niosnommu/processor.h linux-2.4.29-uc1/include/asm-niosnommu/processor.h
--- linux-2.4.29/include/asm-niosnommu/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/processor.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,159 @@
+//vic - temp define task_size
+/*
+ * include/asm-niosnommu/processor.h
+ *
+ * Copyright (C) 2001  Ken Hill (khill@microtronix.com)    
+ *                     Vic Phillips (vic@microtronix.com)
+ *
+ * hacked from:
+ *
+ * include/asm-sparc/processor.h
+ *
+ * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __ASM_NIOS_PROCESSOR_H
+#define __ASM_NIOS_PROCESSOR_H
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#include <linux/a.out.h>
+
+#include <asm/psr.h>
+#include <asm/ptrace.h>
+#include <asm/signal.h>
+#include <asm/segment.h>
+#include <asm/current.h>
+#include <asm/system.h> /* for get_hi_limit */
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+#define MCA_bus 0
+#define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+/*
+ * The nios has no problems with write protection
+ */
+#define wp_works_ok 1
+#define wp_works_ok__is_a_macro /* for versions in ksyms.c */
+
+/* Whee, this is STACK_TOP and the lowest kernel address too... */
+#if 0
+#define KERNBASE        0x00000000  /* First address the kernel will eventually be */
+#define TASK_SIZE	(KERNBASE)
+#define MAX_USER_ADDR	TASK_SIZE
+#define MMAP_SEARCH_START (TASK_SIZE/3)
+#endif
+
+#define TASK_SIZE	0x2000000	//vic for lack of something better ...
+
+/* The Nios processor specific thread struct. */
+struct thread_struct {
+	unsigned long spare;
+	struct pt_regs *kregs;
+
+	/* For signal handling */
+	unsigned long sig_address;
+	unsigned long sig_desc;
+
+	/* Context switch saved kernel state. */
+	unsigned long ksp;
+	unsigned long kpc;
+	unsigned long kpsr;
+	unsigned long kwvalid;
+
+	/* Special child fork kpsr/kwim values. */
+	unsigned long fork_kpsr;
+	unsigned long fork_kwvalid;
+
+	/* A place to store user windows and stack pointers
+	 * when the stack needs inspection.
+	 *
+	 * KH - I don't think the nios port requires this
+	 */
+#define NSWINS 1 //vic8
+	struct reg_window spare_reg_window[NSWINS];
+	unsigned long spare_w_saved;
+
+	/* struct sigstack sstk_info; */
+
+	/* Flags are defined below */
+
+	unsigned long flags;
+	int current_ds;
+	struct exec core_exec;     /* just what it says. */
+};
+
+#define NIOS_FLAG_KTHREAD	0x00000001	/* task is a kernel thread */
+#define NIOS_FLAG_COPROC	0x00000002	/* Thread used coprocess */
+#define NIOS_FLAG_DEBUG		0x00000004	/* task is being debugged */
+
+#define INIT_MMAP { &init_mm, (0), (0), \
+		    __pgprot(0x0) , VM_READ | VM_WRITE | VM_EXEC }
+
+#define INIT_THREAD  { \
+/* uwinmask, kregs, sig_address, sig_desc, ksp, kpc, kpsr, kwvalid */ \
+   0,        0,     0,           0,        0,   0,   0,    0, \
+/* fork_kpsr, fork_kwvalid */ \
+   0,         0, \
+/* spare_reg_window */  \
+{ { { 0, }, { 0, } }, }, \
+/* spare_w_saved */ \
+   0, \
+/* sstk_info */ \
+/* flags,              current_ds, */ \
+/*   NIOS_FLAG_KTHREAD, USER_DS, */ \
+   NIOS_FLAG_KTHREAD, __KERNEL_DS, \
+/* core_exec */ \
+{ 0, }, \
+}
+
+/* Return saved PC of a blocked thread. */
+extern inline unsigned long thread_saved_pc(struct thread_struct *t)
+{
+	return t->kregs->pc;
+}
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ */
+extern inline void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
+{
+	unsigned long saved_psr = (get_hi_limit() << 4) | PSR_IPRI | PSR_IE;
+	int i;
+
+	for(i = 0; i < 16; i++) regs->u_regs[i] = 0;
+	regs->pc = pc >> 1;
+	regs->psr = saved_psr;
+	regs->u_regs[UREG_FP] = (sp - REGWIN_SZ);
+}
+
+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+/* Copy and release all segment info associated with a VM */
+#define copy_segments(tsk, mm)		do { } while (0)
+#define release_segments(mm)		do { } while (0)
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define KSTK_EIP(tsk)  ((tsk)->thread.kregs->pc)
+#define KSTK_ESP(tsk)  ((tsk)->thread.kregs->u_regs[UREG_FP])
+
+#ifdef __KERNEL__
+/* Allocation and freeing of basic task resources. */
+#define alloc_task_struct() \
+	((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
+#define free_task_struct(p)	free_pages((unsigned long)(p),1)
+#define get_task_struct(tsk)      atomic_inc(&mem_map[MAP_NR(tsk)].count)
+
+#define init_task	(init_task_union.task)
+#define init_stack	(init_task_union.stack)
+#endif
+
+#define cpu_relax()    do { } while (0)
+#endif /* __ASM_NIOS_PROCESSOR_H */
diff -urN linux-2.4.29/include/asm-niosnommu/psr.h linux-2.4.29-uc1/include/asm-niosnommu/psr.h
--- linux-2.4.29/include/asm-niosnommu/psr.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/psr.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,62 @@
+/*
+ * psr.h: This file holds the macros for masking off various parts of
+ *        the processor status register on the NIOS.
+ *
+ * Copyright (C) 2001 Vic Phillips
+ */
+
+#ifndef __LINUX_NIOS_PSR_H
+#define __LINUX_NIOS_PSR_H
+
+/* The NIOS PSR (STATUS) fields are laid out as the following:
+ *
+ *  ----------------------------
+ *  | IE | IPRI |  CWP  | ICC  |
+ *  | 15 | 9-14 |  4-8  | 0-3  |
+ *  ----------------------------
+ */
+
+#define PSR_C       0x0001         /* carry bit                  */
+#define PSR_Z       0x0002         /* zero bit                   */
+#define PSR_V       0x0004         /* overflow bit               */
+#define PSR_N       0x0008         /* negative bit               */
+#define PSR_ICC     0x000f         /* integer condition codes    */
+#define PSR_CWP     0x01f0         /* current window pointer     */
+#define PSR_IPRI    0x7e00         /* interrupt priority level   */
+#define PSR_IE      0x8000         /* interrupt enable field     */
+
+/* Interrupt priority level 3 is the highest usable when calling c code.
+ * This allows under/over flow traps while blocking all other interrupts.
+ */
+#define PSR_IPRI_3  0x0600         /* interrupt priority level 3  */
+
+/* This bit is not actually in the NIOS STATUS register, but is emulated
+ * using a global variable: nios_status
+ */
+
+#define PSR_SUPERVISOR		0x80000000  /* supervisor privilege level */
+#define PSR_SUPERVISOR_BIT	31				/* (as a bit number)          */
+
+//#ifdef __KERNEL__
+//
+//#ifndef __ASSEMBLY__
+//
+///* Get the %psr register. */
+//extern inline unsigned int get_psr(void)
+//{
+//	unsigned int psr;
+//	__asm__ __volatile__("rdctl	%0\n\t" : "=r" (psr));
+//	return psr;
+//}
+//
+//extern inline void put_psr(unsigned int new_psr)
+//{
+//	__asm__ __volatile__("wrctl	%0\n\t"
+//			     "nop\n\t" : : "r" (new_psr));
+//}
+//
+//#endif /* !(__ASSEMBLY__) */
+//
+//#endif /* (__KERNEL__) */
+
+#endif /* !(__LINUX_NIOS_PSR_H) */
diff -urN linux-2.4.29/include/asm-niosnommu/ptrace.h linux-2.4.29-uc1/include/asm-niosnommu/ptrace.h
--- linux-2.4.29/include/asm-niosnommu/ptrace.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/ptrace.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,121 @@
+#ifndef _NIOS_PTRACE_H
+#define _NIOS_PTRACE_H
+
+#include <asm/psr.h>
+
+/* This struct defines the way the registers are stored on the 
+ * stack during a system call and basically all traps.
+ */
+
+#ifndef __ASSEMBLY__
+
+struct pt_regs {
+	unsigned long psr;
+	unsigned long pc;
+	long orig_i0;
+	long sysc_no;
+	unsigned long u_regs[16]; /* globals and ins */
+};
+
+//vic#define PT_FLAG_SUPERVISOR	0x00000001	/* Emulated supervisor privilage */
+
+#define UREG_G0        0
+#define UREG_G1        1
+#define UREG_G2        2
+#define UREG_G3        3
+#define UREG_G4        4
+#define UREG_G5        5
+#define UREG_G6        6
+#define UREG_G7        7
+#define UREG_I0        8
+#define UREG_I1        9
+#define UREG_I2        10
+#define UREG_I3        11
+#define UREG_I4        12
+#define UREG_I5        13
+#define UREG_I6        14
+#define UREG_I7        15
+#define UREG_FADDR     UREG_G0
+#define UREG_FP        UREG_I6
+#define UREG_RETPC     UREG_I7
+
+/* A register window */
+struct reg_window {
+	unsigned long locals[8];
+	unsigned long ins[8];
+};
+
+
+/* A Nios stack frame */
+struct nios_stackf {
+	unsigned long locals[8];
+	unsigned long ins[6];
+	struct nios_stackf *fp;
+	unsigned long callers_pc;
+	char *structptr;
+	unsigned long xargs[6];
+	unsigned long xxargs[1];
+};	
+
+#define TRACEREG_SZ   sizeof(struct pt_regs)
+#define STACKFRAME_SZ sizeof(struct nios_stackf)
+#define REGWIN_SZ     sizeof(struct reg_window)
+
+#ifdef __KERNEL__
+#define user_mode(regs) (!((regs)->psr & PSR_SUPERVISOR))
+#define instruction_pointer(regs) ((regs)->pc)
+extern void show_regs(struct pt_regs *);
+#endif
+
+#else /* __ASSEMBLY__ */
+
+/* For assembly code. REGWIN_SZ is used by CRT0 in uClibc */
+#define REGWIN_SZ         0x40
+/* these are now defined in nios-defs.h */
+
+#endif /* __ASSEMBLY__ */
+
+
+/* These are for pt_regs. */
+#define PT_PSR    0x0
+#define PT_PC     0x4
+#define PT_ORIG_I0  0x8
+#define PT_SYSC_NO 0xc
+#define PT_G0     0x10
+#define PT_G1     0x14
+#define PT_G2     0x18
+#define PT_G3     0x1c
+#define PT_G4     0x20
+#define PT_G5     0x24
+#define PT_G6     0x28
+#define PT_G7     0x2c
+#define PT_I0     0x30
+#define PT_I1     0x34
+#define PT_I2     0x38
+#define PT_I3     0x3c
+#define PT_I4     0x40
+#define PT_I5     0x44
+#define PT_I6     0x48
+#define PT_FP     PT_I6
+#define PT_I7     0x4c
+
+/* Reg_window offsets */
+#define RW_L0     0x00
+#define RW_L1     0x04
+#define RW_L2     0x08
+#define RW_L3     0x0c
+#define RW_L4     0x10
+#define RW_L5     0x14
+#define RW_L6     0x18
+#define RW_L7     0x1c
+#define RW_I0     0x20
+#define RW_I1     0x24
+#define RW_I2     0x28
+#define RW_I3     0x2c
+#define RW_I4     0x30
+#define RW_I5     0x34
+#define RW_I6     0x38
+#define RW_I7     0x3c
+
+
+#endif /* !(_NIOS_PTRACE_H) */
diff -urN linux-2.4.29/include/asm-niosnommu/resource.h linux-2.4.29-uc1/include/asm-niosnommu/resource.h
--- linux-2.4.29/include/asm-niosnommu/resource.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/resource.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,48 @@
+//vic - update by copying from:
+#ifndef _M68K_RESOURCE_H
+#define _M68K_RESOURCE_H
+
+/*
+ * Resource limits
+ */
+
+#define RLIMIT_CPU	0		/* CPU time in ms */
+#define RLIMIT_FSIZE	1		/* Maximum filesize */
+#define RLIMIT_DATA	2		/* max data size */
+#define RLIMIT_STACK	3		/* max stack size */
+#define RLIMIT_CORE	4		/* max core file size */
+#define RLIMIT_RSS	5		/* max resident set size */
+#define RLIMIT_NPROC	6		/* max number of processes */
+#define RLIMIT_NOFILE	7		/* max number of open files */
+#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space*/
+#define RLIMIT_AS	9		/* address space limit */
+#define RLIMIT_LOCKS	10		/* maximum file locks held */
+
+#define RLIM_NLIMITS	11
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway.
+ */
+#define RLIM_INFINITY	(~0UL)
+
+#ifdef __KERNEL__
+
+#define INIT_RLIMITS	\
+{                       \
+  {LONG_MAX, LONG_MAX}, \
+  {LONG_MAX, LONG_MAX}, \
+  {LONG_MAX, LONG_MAX}, \
+  {_STK_LIM, LONG_MAX}, \
+  {       0, LONG_MAX}, \
+  {LONG_MAX, LONG_MAX}, \
+  {0, 0},		\
+  {INR_OPEN, INR_OPEN}, \
+  {LONG_MAX, LONG_MAX}, \
+  {LONG_MAX, LONG_MAX}, \
+  {LONG_MAX, LONG_MAX}  \
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _M68K_RESOURCE_H */
diff -urN linux-2.4.29/include/asm-niosnommu/segment.h linux-2.4.29-uc1/include/asm-niosnommu/segment.h
--- linux-2.4.29/include/asm-niosnommu/segment.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/segment.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,51 @@
+#ifndef _NIOS_SEGMENT_H
+#define _NIOS_SEGMENT_H
+/* Moved from m68knommu port, further investigation needed */
+/* define constants */
+/* Address spaces (FC0-FC2) */
+#define USER_DATA     (1)
+#ifndef __USER_DS
+#define __USER_DS     (USER_DATA)
+#endif
+#define USER_PROGRAM  (2)
+#define SUPER_DATA    (5)
+#ifndef __KERNEL_DS
+#define __KERNEL_DS   (SUPER_DATA)
+#endif
+#define SUPER_PROGRAM (6)
+#define CPU_SPACE     (7)
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
+#define USER_DS		MAKE_MM_SEG(__USER_DS)
+#define KERNEL_DS	MAKE_MM_SEG(__KERNEL_DS)
+
+/*
+ * Get/set the SFC/DFC registers for MOVES instructions
+ */
+
+static inline mm_segment_t get_fs(void)
+{
+    return USER_DS;
+}
+
+static inline mm_segment_t get_ds(void)
+{
+    /* return the supervisor data space code */
+    return KERNEL_DS;
+}
+
+static inline void set_fs(mm_segment_t val)
+{
+}
+
+#define segment_eq(a,b)	((a).seg == (b).seg)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _NIOS_SEGMENT_H */
diff -urN linux-2.4.29/include/asm-niosnommu/semaphore.h linux-2.4.29-uc1/include/asm-niosnommu/semaphore.h
--- linux-2.4.29/include/asm-niosnommu/semaphore.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/semaphore.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,100 @@
+#ifndef _NIOS_SEMAPHORE_H
+#define _NIOS_SEMAPHORE_H
+
+/* Dinky, good for nothing, just barely irq safe, Nios semaphores. */
+
+#ifdef __KERNEL__
+
+#include <asm/atomic.h>
+#include <linux/wait.h>
+#include <linux/rwsem.h>
+
+struct semaphore {
+	atomic_t count;
+	int sleepers;
+	wait_queue_head_t wait;
+#if WAITQUEUE_DEBUG
+	long __magic;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+# define __SEM_DEBUG_INIT(name) \
+		, (long)&(name).__magic
+#else
+# define __SEM_DEBUG_INIT(name)
+#endif
+
+#define __SEMAPHORE_INITIALIZER(name,count) \
+{ ATOMIC_INIT(count), 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+	__SEM_DEBUG_INIT(name) }
+
+#define __MUTEX_INITIALIZER(name) \
+	__SEMAPHORE_INITIALIZER(name,1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+
+#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
+#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
+
+static inline void sema_init (struct semaphore *sem, int val)
+{
+	atomic_set(&sem->count, val);
+	sem->sleepers = 0;
+	init_waitqueue_head(&sem->wait);
+#if WAITQUEUE_DEBUG
+	sem->__magic = (long)&sem->__magic;
+#endif
+}
+
+static inline void init_MUTEX (struct semaphore *sem)
+{
+	sema_init(sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+{
+	sema_init(sem, 0);
+}
+
+extern void __down(struct semaphore * sem);
+extern int __down_interruptible(struct semaphore * sem);
+extern int  __down_trylock (struct semaphore * sem);
+extern void __up(struct semaphore * sem);
+
+/*
+ * This isn't quite as clever as the x86 side, but the gp register
+ * makes things a bit more complicated on the alpha..
+ */
+extern inline void down(struct semaphore * sem)
+{
+	if (atomic_dec_return(&sem->count) < 0)
+		__down(sem);
+}
+
+extern inline int down_interruptible(struct semaphore * sem)
+{
+	int ret = 0;
+	if(atomic_dec_return(&sem->count) < 0)
+		ret = __down_interruptible(sem);
+	return ret;
+}
+
+extern inline int down_trylock (struct semaphore *sem)
+{
+	int ret = 0;
+	if (atomic_dec_return (&sem->count) < 0)
+		ret = __down_trylock(sem);
+	return ret;
+}
+
+extern inline void up(struct semaphore * sem)
+{
+	if (atomic_inc_return(&sem->count) <= 0)
+		__up(sem);
+}	
+
+#endif /* __KERNEL__ */
+#endif /* !(_NIOS_SEMAPHORE_H) */
+
diff -urN linux-2.4.29/include/asm-niosnommu/sembuf.h linux-2.4.29-uc1/include/asm-niosnommu/sembuf.h
--- linux-2.4.29/include/asm-niosnommu/sembuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/sembuf.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef _NIOS_SEMBUF_H
+#define _NIOS_SEMBUF_H
+
+/* 
+ * The semid64_ds structure for Nios architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
+	__kernel_time_t	sem_otime;		/* last semop time */
+	unsigned long	__unused1;
+	__kernel_time_t	sem_ctime;		/* last change time */
+	unsigned long	__unused2;
+	unsigned long	sem_nsems;		/* no. of semaphores in array */
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _NIOS_SEMBUF_H */
diff -urN linux-2.4.29/include/asm-niosnommu/setup.h linux-2.4.29-uc1/include/asm-niosnommu/setup.h
--- linux-2.4.29/include/asm-niosnommu/setup.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/setup.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,10 @@
+/*	Copied from i386 port.
+ *	Just a place holder. We don't want to have to test x86 before
+ *	we include stuff
+ */
+
+#ifndef _NIOS_SETUP_H
+#define _NIOS_SETUP_H
+
+
+#endif /* _NIOS_SETUP_H */
diff -urN linux-2.4.29/include/asm-niosnommu/shmbuf.h linux-2.4.29-uc1/include/asm-niosnommu/shmbuf.h
--- linux-2.4.29/include/asm-niosnommu/shmbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/shmbuf.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,42 @@
+#ifndef _NIOS_SHMBUF_H
+#define _NIOS_SHMBUF_H
+
+/* Moved from m68k version
+ * The shmid64_ds structure for Nios architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	unsigned long		__unused1;
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	unsigned long		__unused2;
+	__kernel_time_t		shm_ctime;	/* last change time */
+	unsigned long		__unused3;
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _NIOS_SHMBUF_H */
diff -urN linux-2.4.29/include/asm-niosnommu/shmparam.h linux-2.4.29-uc1/include/asm-niosnommu/shmparam.h
--- linux-2.4.29/include/asm-niosnommu/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/shmparam.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,7 @@
+//vic - copied from:
+#ifndef __V850_SHMPARAM_H__
+#define __V850_SHMPARAM_H__
+
+#define	SHMLBA		PAGE_SIZE	/* attach addr a multiple of this */
+
+#endif /* __V850_SHMPARAM_H__ */
diff -urN linux-2.4.29/include/asm-niosnommu/sigcontext.h linux-2.4.29-uc1/include/asm-niosnommu/sigcontext.h
--- linux-2.4.29/include/asm-niosnommu/sigcontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/sigcontext.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef _ASMnios_SIGCONTEXT_H
+#define _ASMnios_SIGCONTEXT_H
+
+#include <asm/ptrace.h>
+
+struct sigcontext {
+	struct pt_regs 	regs;   /* this must be first */
+	int oldmask;            /* sigmask to restore */
+};
+
+#endif /* !(_ASMnios_SIGCONTEXT_H) */
+
diff -urN linux-2.4.29/include/asm-niosnommu/siginfo.h linux-2.4.29-uc1/include/asm-niosnommu/siginfo.h
--- linux-2.4.29/include/asm-niosnommu/siginfo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/siginfo.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,233 @@
+#ifndef _NIOS_SIGINFO_H
+#define _NIOS_SIGINFO_H
+
+#include <linux/types.h>
+
+/* XXX: This structure was copied from the Alpha; is there an iBCS version?  */
+
+typedef union sigval {
+	int sival_int;
+	void *sival_ptr;
+} sigval_t;
+
+#define SI_MAX_SIZE	128
+#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct siginfo {
+	int si_signo;
+	int si_errno;
+	int si_code;
+
+	union {
+		int _pad[SI_PAD_SIZE];
+
+		/* kill() */
+		struct {
+			pid_t _pid;		/* sender's pid */
+			uid_t _uid;		/* sender's uid */
+		} _kill;
+
+		/* POSIX.1b timers */
+		struct {
+			unsigned int _timer1;
+			unsigned int _timer2;
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			pid_t _pid;		/* sender's pid */
+			uid_t _uid;		/* sender's uid */
+			sigval_t _sigval;
+		} _rt;
+
+		/* SIGCHLD */
+		struct {
+			pid_t _pid;		/* which child */
+			uid_t _uid;		/* sender's uid */
+			int _status;		/* exit code */
+			clock_t _utime;
+			clock_t _stime;
+		} _sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			void *_addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+	} _sifields;
+} siginfo_t;
+
+/*
+ * How these fields are to be accessed.
+ */
+#define si_pid		_sifields._kill._pid
+#define si_uid		_sifields._kill._uid
+#define si_status	_sifields._sigchld._status
+#define si_utime	_sifields._sigchld._utime
+#define si_stime	_sifields._sigchld._stime
+#define si_value	_sifields._rt._sigval
+#define si_int		_sifields._rt._sigval.sival_int
+#define si_ptr		_sifields._rt._sigval.sival_ptr
+#define si_addr		_sifields._sigfault._addr
+#define si_band		_sifields._sigpoll._band
+#define si_fd		_sifields._sigpoll._fd
+
+#ifdef __KERNEL__
+#define __SI_MASK	0xffff0000
+#define __SI_KILL	(0 << 16)
+#define __SI_TIMER	(1 << 16)
+#define __SI_POLL	(2 << 16)
+#define __SI_FAULT	(3 << 16)
+#define __SI_CHLD	(4 << 16)
+#define __SI_RT		(5 << 16)
+#define __SI_CODE(T,N)	((T) << 16 | ((N) & 0xffff))
+#else
+#define __SI_KILL	0
+#define __SI_TIMER	0
+#define __SI_POLL	0
+#define __SI_FAULT	0
+#define __SI_CHLD	0
+#define __SI_RT		0
+#define __SI_CODE(T,N)	(N)
+#endif
+
+/*
+ * si_code values
+ * Digital reserves positive values for kernel-generated signals.
+ */
+#define SI_USER		0		/* sent by kill, sigsend, raise */
+#define SI_KERNEL	0x80		/* sent by the kernel from somewhere */
+#define SI_QUEUE	-1		/* sent by sigqueue */
+#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
+#define SI_MESGQ	-3		/* sent by real time mesq state change */
+#define SI_ASYNCIO	-4		/* sent by AIO completion */
+#define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
+
+#define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
+#define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
+
+/*
+ * SIGILL si_codes
+ */
+#define ILL_ILLOPC	(__SI_FAULT|1)	/* illegal opcode */
+#define ILL_ILLOPN	(__SI_FAULT|2)	/* illegal operand */
+#define ILL_ILLADR	(__SI_FAULT|3)	/* illegal addressing mode */
+#define ILL_ILLTRP	(__SI_FAULT|4)	/* illegal trap */
+#define ILL_PRVOPC	(__SI_FAULT|5)	/* privileged opcode */
+#define ILL_PRVREG	(__SI_FAULT|6)	/* privileged register */
+#define ILL_COPROC	(__SI_FAULT|7)	/* coprocessor error */
+#define ILL_BADSTK	(__SI_FAULT|8)	/* internal stack error */
+#define NSIGILL		8
+
+/*
+ * SIGFPE si_codes
+ */
+#define FPE_INTDIV	(__SI_FAULT|1)	/* integer divide by zero */
+#define FPE_INTOVF	(__SI_FAULT|2)	/* integer overflow */
+#define FPE_FLTDIV	(__SI_FAULT|3)	/* floating point divide by zero */
+#define FPE_FLTOVF	(__SI_FAULT|4)	/* floating point overflow */
+#define FPE_FLTUND	(__SI_FAULT|5)	/* floating point underflow */
+#define FPE_FLTRES	(__SI_FAULT|6)	/* floating point inexact result */
+#define FPE_FLTINV	(__SI_FAULT|7)	/* floating point invalid operation */
+#define FPE_FLTSUB	(__SI_FAULT|8)	/* subscript out of range */
+#define NSIGFPE		8
+
+/*
+ * SIGSEGV si_codes
+ */
+#define SEGV_MAPERR	(__SI_FAULT|1)	/* address not mapped to object */
+#define SEGV_ACCERR	(__SI_FAULT|2)	/* invalid permissions for mapped object */
+#define NSIGSEGV	2
+
+/*
+ * SIGBUS si_codes
+ */
+#define BUS_ADRALN	(__SI_FAULT|1)	/* invalid address alignment */
+#define BUS_ADRERR	(__SI_FAULT|2)	/* non-existant physical address */
+#define BUS_OBJERR	(__SI_FAULT|3)	/* object specific hardware error */
+#define NSIGBUS		3
+
+/*
+ * SIGTRAP si_codes
+ */
+#define TRAP_BRKPT	(__SI_FAULT|1)	/* process breakpoint */
+#define TRAP_TRACE	(__SI_FAULT|2)	/* process trace trap */
+#define NSIGTRAP	2
+
+/*
+ * SIGCHLD si_codes
+ */
+#define CLD_EXITED	(__SI_CHLD|1)	/* child has exited */
+#define CLD_KILLED	(__SI_CHLD|2)	/* child was killed */
+#define CLD_DUMPED	(__SI_CHLD|3)	/* child terminated abnormally */
+#define CLD_TRAPPED	(__SI_CHLD|4)	/* traced child has trapped */
+#define CLD_STOPPED	(__SI_CHLD|5)	/* child has stopped */
+#define CLD_CONTINUED	(__SI_CHLD|6)	/* stopped child has continued */
+#define NSIGCHLD	6
+
+/*
+ * SIGPOLL si_codes
+ */
+#define POLL_IN		(__SI_POLL|1)	/* data input available */
+#define POLL_OUT	(__SI_POLL|2)	/* output buffers available */
+#define POLL_MSG	(__SI_POLL|3)	/* input message available */
+#define POLL_ERR	(__SI_POLL|4)	/* i/o error */
+#define POLL_PRI	(__SI_POLL|5)	/* high priority input available */
+#define POLL_HUP	(__SI_POLL|6)	/* device disconnected */
+#define NSIGPOLL	6
+
+/*
+ * sigevent definitions
+ * 
+ * It seems likely that SIGEV_THREAD will have to be handled from 
+ * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
+ * thread manager then catches and does the appropriate nonsense.
+ * However, everything is written out here so as to not get lost.
+ */
+#define SIGEV_SIGNAL	0	/* notify via signal */
+#define SIGEV_NONE	1	/* other notification: meaningless */
+#define SIGEV_THREAD	2	/* deliver via thread creation */
+
+#define SIGEV_MAX_SIZE	64
+#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct sigevent {
+	sigval_t sigev_value;
+	int sigev_signo;
+	int sigev_notify;
+	union {
+		int _pad[SIGEV_PAD_SIZE];
+
+		struct {
+			void (*_function)(sigval_t);
+			void *_attribute;	/* really pthread_attr_t */
+		} _sigev_thread;
+	} _sigev_un;
+} sigevent_t;
+
+#define sigev_notify_function	_sigev_un._sigev_thread._function
+#define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
+
+#ifdef __KERNEL__
+#include <linux/string.h>
+
+extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
+{
+	if (from->si_code < 0)
+		memcpy(to, from, sizeof(siginfo_t));
+	else
+		/* _sigchld is currently the largest know union member */
+		memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
+}
+
+extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
+
+#endif /* __KERNEL__ */
+
+#endif
diff -urN linux-2.4.29/include/asm-niosnommu/signal.h linux-2.4.29-uc1/include/asm-niosnommu/signal.h
--- linux-2.4.29/include/asm-niosnommu/signal.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/signal.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,185 @@
+#ifndef _NIOS_SIGNAL_H
+#define _NIOS_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
+
+// Vic ???
+#define SA_RESTORER	0x04000000
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#ifdef __KERNEL__
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE		SA_ONESHOT
+#define SA_SAMPLE_RANDOM	SA_RESTART
+#define SA_SHIRQ		0x04000000
+#endif
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+#ifdef __KERNEL__
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+//vic	void	*ka_restorer;
+};
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+
+#include <asm/sigcontext.h>
+#undef __HAVE_ARCH_SIG_BITOPS
+
+#endif /* __KERNEL__ */
+
+#endif /* _NIOS_SIGNAL_H */
diff -urN linux-2.4.29/include/asm-niosnommu/smp.h linux-2.4.29-uc1/include/asm-niosnommu/smp.h
--- linux-2.4.29/include/asm-niosnommu/smp.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/smp.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,10 @@
+#ifndef __ASM_SMP_H
+#define __ASM_SMP_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_SMP
+#error SMP not supported
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-niosnommu/smplock.h linux-2.4.29-uc1/include/asm-niosnommu/smplock.h
--- linux-2.4.29/include/asm-niosnommu/smplock.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/smplock.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,51 @@
+/*
+ * <asm/smplock.h>
+ *
+ * Default SMP lock implementation
+ */
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+extern spinlock_t kernel_flag;
+
+#define kernel_locked()		spin_is_locked(&kernel_flag)
+
+/*
+ * Release global kernel lock and global interrupt lock
+ */
+#define release_kernel_lock(task, cpu) \
+do { \
+	if (task->lock_depth >= 0) \
+		spin_unlock(&kernel_flag); \
+	release_irqlock(cpu); \
+	__sti(); \
+} while (0)
+
+/*
+ * Re-acquire the kernel lock
+ */
+#define reacquire_kernel_lock(task) \
+do { \
+	if (task->lock_depth >= 0) \
+		spin_lock(&kernel_flag); \
+} while (0)
+
+
+/*
+ * Getting the big kernel lock.
+ *
+ * This cannot happen asynchronously,
+ * so we only need to worry about other
+ * CPU's.
+ */
+extern __inline__ void lock_kernel(void)
+{
+	if (!++current->lock_depth)
+		spin_lock(&kernel_flag);
+}
+
+extern __inline__ void unlock_kernel(void)
+{
+	if (--current->lock_depth < 0)
+		spin_unlock(&kernel_flag);
+}
diff -urN linux-2.4.29/include/asm-niosnommu/socket.h linux-2.4.29-uc1/include/asm-niosnommu/socket.h
--- linux-2.4.29/include/asm-niosnommu/socket.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/socket.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,65 @@
+//vic - update by copying from:
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED	16
+#define SO_PEERCRED	17
+#define SO_RCVLOWAT	18
+#define SO_SNDLOWAT	19
+#define SO_RCVTIMEO	20
+#define SO_SNDTIMEO	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE	25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME             28
+#define SO_TIMESTAMP		29
+#define SCM_TIMESTAMP		SO_TIMESTAMP
+
+#define SO_ACCEPTCONN		30
+
+/* Nast libc5 fixup - bletch */
+#if defined(__KERNEL__)
+/* Socket types. */
+#define SOCK_STREAM	1		/* stream (connection) socket	*/
+#define SOCK_DGRAM	2		/* datagram (conn.less) socket	*/
+#define SOCK_RAW	3		/* raw socket			*/
+#define SOCK_RDM	4		/* reliably-delivered message	*/
+#define SOCK_SEQPACKET	5		/* sequential packet socket	*/
+#define SOCK_PACKET	10		/* linux specific way of	*/
+					/* getting packets at the dev	*/
+					/* level.  For writing rarp and	*/
+					/* other similar things on the	*/
+					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
+#endif
+
+#endif /* _ASM_SOCKET_H */
diff -urN linux-2.4.29/include/asm-niosnommu/sockios.h linux-2.4.29-uc1/include/asm-niosnommu/sockios.h
--- linux-2.4.29/include/asm-niosnommu/sockios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/sockios.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef _ASM_NIOS_SOCKIOS_H
+#define _ASM_NIOS_SOCKIOS_H
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 	0x8901
+#define SIOCSPGRP	0x8902
+#define FIOGETOWN	0x8903
+#define SIOCGPGRP	0x8904
+#define SIOCATMARK	0x8905
+#define SIOCGSTAMP	0x8906		/* Get stamp */
+
+#endif /* !(_ASM_NIOS_SOCKIOS_H) */
+
diff -urN linux-2.4.29/include/asm-niosnommu/softirq.h linux-2.4.29-uc1/include/asm-niosnommu/softirq.h
--- linux-2.4.29/include/asm-niosnommu/softirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/softirq.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,19 @@
+#ifndef __NIOS_SOFTIRQ_H
+#define __NIOS_SOFTIRQ_H
+/* Copied from asm-m68knommu/softirq.h */
+#include <asm/atomic.h>
+#include <asm/hardirq.h>
+
+#define __cpu_bh_enable(cpu) \
+		do { barrier(); local_bh_count(cpu)--; } while (0)
+#define cpu_bh_disable(cpu) \
+		do { local_bh_count(cpu)++; barrier(); } while (0)
+
+#define local_bh_disable()	cpu_bh_disable(smp_processor_id())
+#define __local_bh_enable()	__cpu_bh_enable(smp_processor_id())
+
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
+
+#define local_bh_enable() __local_bh_enable()
+
+#endif
diff -urN linux-2.4.29/include/asm-niosnommu/spi.h linux-2.4.29-uc1/include/asm-niosnommu/spi.h
--- linux-2.4.29/include/asm-niosnommu/spi.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/spi.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,68 @@
+#ifndef _ASM_SPI_H_
+#define _ASM_SPI_H_ 1
+
+#include <asm/nios.h>
+
+int  register_NIOS_SPI( void );
+void unregister_NIOS_SPI( void );
+
+#if defined(MODULE)
+void cleanup_module( void );
+int  init_module( void );
+#endif
+
+#if defined(__KERNEL__)
+int  spi_reset  ( void );
+#endif
+
+
+#define clockCS 0x01
+#define temperatureCS 0x02
+
+#define clock_read_base 0x00
+#define clock_write_base 0x80
+#define clock_read_control 0x0F
+#define clock_read_trickle 0x11
+
+#define clock_read_sec 0x00
+#define clock_read_min 0x01
+#define clock_read_hour 0x02
+#define clock_read_day 0x03
+#define clock_read_date 0x04
+#define clock_read_month 0x05
+#define clock_read_year 0x06
+
+#define clock_write_control 0x8F
+#define clock_write_trickle 0x91
+#define clock_write_sec 0x80
+#define clock_write_min 0x81
+#define clock_write_hour 0x82
+#define clock_write_day 0x83
+#define clock_write_date 0x84
+#define clock_write_month 0x85
+#define clock_write_year 0x86
+
+#define clock_write_ram_start 0xA0
+#define clock_write_ram_end 0x100
+#define clock_read_ram_start 0x20
+#define clock_read_ram_end 0x80
+
+
+#define	clock_sec_def 0x11
+#define clock_min_def 0x59
+#define clock_hour_def 0x71
+#define clock_day_def 0x00
+#define clock_date_def 0x20
+#define clock_month_def 0x12
+#define clock_year_def 0x34
+
+#define temp_read_base 0x00
+#define temp_write_base 0x80
+#define temp_read_control 0x00
+#define temp_write_control 0x80
+#define temp_read_msb 0x02
+#define temp_read_lsb 0x01
+
+#define MAX_TEMP_VAR 10
+
+#endif /*_ASM_SPI_H_*/
diff -urN linux-2.4.29/include/asm-niosnommu/spinlock.h linux-2.4.29-uc1/include/asm-niosnommu/spinlock.h
--- linux-2.4.29/include/asm-niosnommu/spinlock.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/spinlock.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __NIOS_SPINLOCK_H
+#define __NIOS_SPINLOCK_H
+
+#error "Nios doesn't do SMP yet"
+
+#endif
diff -urN linux-2.4.29/include/asm-niosnommu/statfs.h linux-2.4.29-uc1/include/asm-niosnommu/statfs.h
--- linux-2.4.29/include/asm-niosnommu/statfs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/statfs.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef _NIOS_STATFS_H
+#define _NIOS_STATFS_H
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t	fsid_t;
+
+#endif
+
+struct statfs {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_spare[6];
+};
+
+#endif /* _NIOS_STATFS_H */
diff -urN linux-2.4.29/include/asm-niosnommu/stat.h linux-2.4.29-uc1/include/asm-niosnommu/stat.h
--- linux-2.4.29/include/asm-niosnommu/stat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/stat.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,78 @@
+//vic - update by copying from:
+#ifndef _ASMARM_STAT_H
+#define _ASMARM_STAT_H
+
+struct __old_kernel_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+struct stat {
+	unsigned short st_dev;
+	unsigned short __pad1;
+	unsigned long st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned short __pad2;
+	unsigned long  st_size;
+	unsigned long  st_blksize;
+	unsigned long  st_blocks;
+	unsigned long  st_atime;
+	unsigned long  __unused1;
+	unsigned long  st_mtime;
+	unsigned long  __unused2;
+	unsigned long  st_ctime;
+	unsigned long  __unused3;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat64 {
+	unsigned short	st_dev;
+	unsigned char	__pad0[10];
+
+#define STAT64_HAS_BROKEN_ST_INO	1
+	unsigned long	__st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned short	st_rdev;
+	unsigned char	__pad3[10];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+
+	unsigned long	st_atime;
+	unsigned long	__pad5;
+
+	unsigned long	st_mtime;
+	unsigned long	__pad6;
+
+	unsigned long	st_ctime;
+	unsigned long	__pad7;		/* will be high 32 bits of ctime someday */
+
+	unsigned long long	st_ino;
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-niosnommu/string.h linux-2.4.29-uc1/include/asm-niosnommu/string.h
--- linux-2.4.29/include/asm-niosnommu/string.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/string.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,28 @@
+/* vic - todo - add inline assembler to optimize ? */
+/*
+ * string.h: External definitions for optimized assembly string
+ *           routines for the Linux Kernel.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __NIOS_STRING_H__
+#define __NIOS_STRING_H__
+
+#ifdef __KERNEL__ /* only set these up for kernel code */
+
+#define __HAVE_ARCH_MEMMOVE
+void * memmove(void * d, const void * s, size_t count);
+#define __HAVE_ARCH_MEMCPY
+extern void * memcpy(void *d, const void *s, size_t count);
+#define __HAVE_ARCH_MEMSET
+extern void * memset(void * s,int c,size_t count);
+
+#if 0
+#define __HAVE_ARCH_BCOPY
+#define __HAVE_ARCH_STRLEN
+#endif
+
+#endif /* KERNEL */
+
+#endif /* !(__NIOS_STRING_H__) */
diff -urN linux-2.4.29/include/asm-niosnommu/system.h linux-2.4.29-uc1/include/asm-niosnommu/system.h
--- linux-2.4.29/include/asm-niosnommu/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/system.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2001		Ken Hill
+ *				Adapted from Keith Adams i960 file and Sparcnommu
+ *
+ * Copyright (C) 1999		Keith Adams	<kma@cse.ogi.edu>
+ * 				Oregon Graduate Institute
+ */
+#ifndef _NIOS_SYSTEM_H
+#define _NIOS_SYSTEM_H
+
+#include <linux/linkage.h>
+
+asmlinkage void resume(void);
+struct task_struct;
+
+/* When a context switch happens we must flush all user windows so that
+ * the windows of the current process are flushed onto its stack. This
+ * way the windows are all clean for the next process and the stack
+ * frames are up to date.
+ */
+extern void flush_user_windows(void);
+extern void synchronize_user_stack(void);
+extern void nios_switch_to(void *old_task, void *new_task);
+#define prepare_to_switch()	do { } while(0)
+
+#define switch_to(prev,next,last) do {\
+			nios_switch_to(prev, next); \
+			} while(0)
+
+#define HARD_RESET_NOW() hard_reset_now();
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+#define tas(ptr) (xchg((ptr),1))
+
+/* Changing the IRQ level on the NIOS. */
+extern inline void setipl(int __new_ipl)
+{
+	__asm__ __volatile__("rdctl  %%g1\n\t"
+			     "pfx %%hi(%1)\n\t"
+			     "and %%g1, %%lo(%1)\n\t"
+			     "pfx %%hi(%2)\n\t"
+			     "and %0, %%lo(%2)\n\t"
+			     "or %%g1, %0\n\t"
+			     "wrctl %%g1\n\t"
+			     "nop\n\t"
+			     "nop\n\t"
+			     : /* No output */
+			     : "r" (__new_ipl<<9), "i" (~0x7E00), "i" (0x7E00)
+			     : "g1");
+}
+
+extern inline int getipl(void)
+{
+	int retval;
+
+	__asm__ __volatile__("rdctl %0\n\t"
+			     "pfx %%hi(%1)\n\t"
+			     "and %0, %%lo(%1)\n\t"
+			     "lsri %0, 9\n\t"
+			     : "=r" (retval)
+			     : "i" (0x7E00));
+	return retval;
+}
+
+extern inline int swpipl(int __new_ipl)
+{
+	int retval;
+
+	__asm__ __volatile__("rdctl  %0\n\t"
+			     "mov %%g1,%0\n\t"
+			     "pfx %%hi(%2)\n\t"
+			     "and %%g1, %%lo(%2)\n\t"
+			     "pfx %%hi(%2)\n\t"
+			     "and %1, %%lo(%2)\n\t"
+			     "or %%g1, %1\n\t"
+			     "wrctl %%g1\n\t"
+			     "nop\n\t"
+			     "nop\n\t"
+			     "pfx %%hi(%3)\n\t"
+			     "and %0, %%lo(%3)\n\t"
+			     "lsri %0, 9\n\t"
+			     "nop\n\t"
+			     : "=&r" (retval)
+			     : "r" (__new_ipl<<9), "i" (~0x7E00), "i" (0x7E00)
+			     : "g1");
+	return retval;
+}
+
+#define __cli()			setipl(3)    /* 3 = no int's except reg window over/underflow */
+#define __sti()			setipl(63)   /* This will allow lower priority interrupts
+					        to occur that should not if IE bit could have
+					        been used. */
+#define __save_flags(flags)	do { flags = getipl(); } while (0)
+#define __restore_flags(flags)	setipl(flags)
+
+#define nop() __asm__ __volatile__ ("nop")
+
+#define DEBUG_TRAP5      0x7905  /* Nios Trap 5 instruction */
+#define NOP              0x3000  /* Nios nop instruction    */
+
+/* For spinlocks etc */
+#define local_irq_save(x)	do { __save_flags(x); __cli(); } while (0)
+#define local_irq_set(x)	do { __save_flags(x); __sti(); } while (0)
+#define local_irq_restore(x)	do { __restore_flags(x); } while (0)
+#define local_irq_disable()	__cli()
+#define local_irq_enable()	__sti()
+
+#define cli()			__cli()
+#define sti()			__sti()
+#define save_flags(x)		__save_flags(x)
+#define restore_flags(x)	__restore_flags(x)
+#define save_and_cli(x)	__save_and_cli(x)
+#define save_and_set(x)	__save_and_sti(x)
+
+/* These definitions for en/disabling interrupts can only be used when there
+ * is no chance that the body of code between disable and enable does a call
+ * or save/restore instruction.  Primarily for use in the definition of
+ * atomic operations like xchg, atomic_add, etc.
+ */
+extern inline void _disable_interrupts(void)
+{
+	asm("pfx 8\n\t"
+		 "wrctl %g0\n\t"
+		 "nop\n\t"
+		 "nop");
+}
+
+extern inline void _enable_interrupts(void)
+{
+	asm("pfx 9\n\t"
+		 "wrctl %g0");
+}
+
+
+static inline unsigned long __xchg(unsigned long x, 
+				   volatile void * ptr, int size)
+{
+	unsigned long retval;
+
+	_disable_interrupts();
+
+	switch (size) {
+		case 1:
+			__asm__ __volatile__ ("ld	%0,[%1]\n\t"
+					      "ext8d	%0,%1\n\t"
+					      "fill8	%%r0,%2\n\t"
+					      "st8d	[%1],%%r0\n\t"
+					      : "=&r" (retval)
+					      : "r" (ptr), "r" (x)
+					      : "r0"); /* Same as %r0 */
+			break;
+
+		case 2: /* Alignment for data types is strict therefore
+			   do not need to account for unaligned access */
+			__asm__ __volatile__ ("ld	%0,[%1]\n\t"
+					      "ext16d	%0,%1\n\t"
+					      "fill16	%%r0,%2\n\t"
+					      "st16d	[%1],%%r0\n\t"
+					      : "=&r" (retval)
+					      : "r" (ptr), "r" (x)
+					      : "r0"); /* Same as %r0 */
+			break;
+
+		case 4: /* Alignment for data types is strict therefore
+			   do not need to account for unaligned access */
+			__asm__ __volatile__ ("ld	%0,[%1]\n\t"
+					      "st	[%1],%2\n\t"
+					      : "=&r" (retval)
+					      : "r" (ptr), "r" (x));
+			break;
+	}
+
+	_enable_interrupts();
+	return retval;
+}
+
+/* Get the value of HI_LIMIT from wvalid control register */
+extern inline int get_hi_limit(void)
+{
+	int retval;
+	__asm__ __volatile__(
+			"pfx 2\n\t"
+			"rdctl %0\n\t"
+			"lsri %0, 5\n\t"
+			"pfx %%hi(%1)\n\t"
+			"and %0, %%lo(%1)\n\t"
+			: "=r" (retval)
+			: "i" (0x001f));
+	return retval;
+}
+
+/***********************************************/
+/* hjz: Memory-Barrier definition. If the Nios */
+/* ever supports MP, this function would have  */
+/* to flush the write cache and invalidate the */
+/* read cache so all processors see the same   */
+/* values in memory. But not today...          */
+/***********************************************/
+#define mb()	__asm__ __volatile__ ("" : : : "memory")
+#define rmb()	__asm__ __volatile__ ("" : : : "memory")
+#define wmb()	__asm__ __volatile__ ("" : : : "memory")
+
+#ifdef CONFIG_SMP
+#define smp_mb()	mb()
+#define smp_rmb()	rmb()
+#define smp_wmb()	wmb()
+#else
+#define smp_mb()	barrier()
+#define smp_rmb()	barrier()
+#define smp_wmb()	barrier()
+#endif
+
+#endif /* _NIOS_SYSTEM_H */
+
diff -urN linux-2.4.29/include/asm-niosnommu/termbits.h linux-2.4.29-uc1/include/asm-niosnommu/termbits.h
--- linux-2.4.29/include/asm-niosnommu/termbits.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/termbits.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,174 @@
+#ifndef __ARCH_NIOS_TERMBITS_H__
+#define __ARCH_NIOS_TERMBITS_H__
+
+#include <linux/posix_types.h>
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#define NCCS 19
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IUCLC	0001000
+#define IXON	0002000
+#define IXANY	0004000
+#define IXOFF	0010000
+#define IMAXBEL	0020000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define OLCUC	0000002
+#define ONLCR	0000004
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#define NLDLY	0000400
+#define   NL0	0000000
+#define   NL1	0000400
+#define CRDLY	0003000
+#define   CR0	0000000
+#define   CR1	0001000
+#define   CR2	0002000
+#define   CR3	0003000
+#define TABDLY	0014000
+#define   TAB0	0000000
+#define   TAB1	0004000
+#define   TAB2	0010000
+#define   TAB3	0014000
+#define   XTABS	0014000
+#define BSDLY	0020000
+#define   BS0	0000000
+#define   BS1	0020000
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+#define FFDLY	0100000
+#define   FF0	0000000
+#define   FF1	0100000
+
+/* c_cflag bit meaning */
+#define CBAUD	0010017
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE	0000060
+#define   CS5	0000000
+#define   CS6	0000020
+#define   CS7	0000040
+#define   CS8	0000060
+#define CSTOPB	0000100
+#define CREAD	0000200
+#define PARENB	0000400
+#define PARODD	0001000
+#define HUPCL	0002000
+#define CLOCAL	0004000
+#define CBAUDEX 0010000
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+#define CIBAUD	  002003600000	/* input baud rate (not used) */
+#define CMSPAR	  010000000000		/* mark or space (stick) parity */
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+#define ISIG	0000001
+#define ICANON	0000002
+#define XCASE	0000004
+#define ECHO	0000010
+#define ECHOE	0000020
+#define ECHOK	0000040
+#define ECHONL	0000100
+#define NOFLSH	0000200
+#define TOSTOP	0000400
+#define ECHOCTL	0001000
+#define ECHOPRT	0002000
+#define ECHOKE	0004000
+#define FLUSHO	0010000
+#define PENDIN	0040000
+#define IEXTEN	0100000
+
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* __ARCH_NIOS_TERMBITS_H__ */
diff -urN linux-2.4.29/include/asm-niosnommu/termios.h linux-2.4.29-uc1/include/asm-niosnommu/termios.h
--- linux-2.4.29/include/asm-niosnommu/termios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/termios.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,108 @@
+#ifndef _NIOS_TERMIOS_H
+#define _NIOS_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+ 
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+#ifdef __KERNEL__
+/*	intr=^C		quit=^|		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+#endif
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6	/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14
+#define N_HCI		15  /* Bluetooth HCI UART */
+
+#ifdef __KERNEL__
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+	unsigned short tmp; \
+	get_user(tmp, &(termio)->c_iflag); \
+	(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
+	get_user(tmp, &(termio)->c_oflag); \
+	(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
+	get_user(tmp, &(termio)->c_cflag); \
+	(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
+	get_user(tmp, &(termio)->c_lflag); \
+	(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
+	get_user((termios)->c_line, &(termio)->c_line); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif	/* __KERNEL__ */
+
+#endif /* _NIOS_TERMIOS_H */
diff -urN linux-2.4.29/include/asm-niosnommu/timex.h linux-2.4.29-uc1/include/asm-niosnommu/timex.h
--- linux-2.4.29/include/asm-niosnommu/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/timex.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,22 @@
+/*
+ * linux/include/asm-niosnommu/timex.h
+ *
+ * sparc architecture timex specifications
+ */
+#ifndef _ASMsparc_TIMEX_H
+#define _ASMsparc_TIMEX_H
+#include <asm/nios.h>
+#define CLOCK_TICK_RATE	nasys_clock_freq /* Underlying HZ */
+#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
+#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
+	(1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
+		<< (SHIFT_SCALE-SHIFT_HZ)) / HZ)
+
+typedef unsigned long cycles_t;
+#define get_cycles()	(0)
+
+#define vxtime_lock()		do {} while (0)
+#define vxtime_unlock()		do {} while (0)
+
+
+#endif
diff -urN linux-2.4.29/include/asm-niosnommu/tlb.h linux-2.4.29-uc1/include/asm-niosnommu/tlb.h
--- linux-2.4.29/include/asm-niosnommu/tlb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/tlb.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-generic/tlb.h>
diff -urN linux-2.4.29/include/asm-niosnommu/traps.h linux-2.4.29-uc1/include/asm-niosnommu/traps.h
--- linux-2.4.29/include/asm-niosnommu/traps.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/traps.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,11 @@
+/*
+	This is just a fragment of the original "traps.h" file,
+	enough to get the one symbol defined for "traps.c".
+*/
+#ifndef _NIOS_TRAPS_H
+#define _NIOS_TRAPS_H
+
+/* Now the Software Traps... */
+#define SP_TRAP_SBPT    0x81         /* Software Breakpoint */
+
+#endif /* !(_NIOS_TRAPS_H) */
diff -urN linux-2.4.29/include/asm-niosnommu/types.h linux-2.4.29-uc1/include/asm-niosnommu/types.h
--- linux-2.4.29/include/asm-niosnommu/types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/types.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,57 @@
+#ifndef _NIOS_TYPES_H
+#define _NIOS_TYPES_H
+
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue.  However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ */
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide.  */
+
+typedef u32 dma_addr_t;
+#endif /* __KERNEL__ */
+
+#endif /* _NIOS_TYPES_H */
diff -urN linux-2.4.29/include/asm-niosnommu/uaccess.h linux-2.4.29-uc1/include/asm-niosnommu/uaccess.h
--- linux-2.4.29/include/asm-niosnommu/uaccess.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/uaccess.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,156 @@
+#ifndef __NIOSNOMMU_UACCESS_H
+#define __NIOSNOMMU_UACCESS_H
+
+/* 
+ * Ported from asm-m68knommu/uaccess.h --wentao
+ *
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <asm/segment.h>
+#include <asm/nios.h>
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+/* We let the MMU do all checking */
+extern inline int access_ok(int type, const void * addr, unsigned long size)
+{
+	if (((unsigned long)addr >= (unsigned long)nasys_program_mem_end) ||
+		((type==VERIFY_WRITE) &&((unsigned long)addr < (unsigned long)nasys_program_mem) ))
+		return 0;
+	else	return 1;
+}
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+	return access_ok(type,addr,size)?0:-EFAULT;
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ */
+
+#define put_user(x, ptr)				\
+({							\
+    int __pu_err = 0;					\
+    typeof(*(ptr)) __pu_val = (x);			\
+    switch (sizeof (*(ptr))) {				\
+    case 1:						\
+    case 2:						\
+    case 4:						\
+    case 8:						\
+	memcpy(ptr, &__pu_val, sizeof (*(ptr))); \
+	break;						\
+    default:						\
+	__pu_err = __put_user_bad();			\
+	break;						\
+    }							\
+    __pu_err;						\
+})
+#define __put_user(x, ptr) put_user(x, ptr)
+
+extern int __put_user_bad(void);
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+
+#define __ptr(x) ((unsigned long *)(x))
+
+#define get_user(x, ptr)					\
+({								\
+    int __gu_err = 0;						\
+    typeof(*(ptr)) __gu_val = 0;				\
+    switch (sizeof(*(ptr))) {					\
+    case 1:						\
+    case 2:						\
+    case 4:						\
+    case 8:						\
+	memcpy(&__gu_val, ptr, sizeof (*(ptr))); \
+	break;							\
+    default:							\
+	__gu_val = 0;						\
+	__gu_err = __get_user_bad();				\
+	break;							\
+    }								\
+    (x) = __gu_val;						\
+    __gu_err;							\
+})
+#define __get_user(x, ptr) get_user(x, ptr)
+
+extern int __get_user_bad(void);
+
+#define copy_from_user(to, from, n)		(memcpy(to, from, n), 0)
+#define copy_to_user(to, from, n)		(memcpy(to, from, n), 0)
+
+#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
+#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
+
+#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; })
+
+#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; })
+
+/*
+ * Copy a null terminated string from userspace.
+ */
+
+static inline long
+strncpy_from_user(char *dst, const char *src, long count)
+{
+	char *tmp;
+	strncpy(dst, src, count);
+	for (tmp = dst; *tmp && count > 0; tmp++, count--)
+		;
+	return(tmp - dst); /* DAVIDM should we count a NUL ?  check getname */
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 on exception, a value greater than N if too long
+ */
+static inline long strnlen_user(const char *src, long n)
+{
+	return(strlen(src) + 1); /* DAVIDM make safer */
+}
+
+#define strlen_user(str) strnlen_user(str, 32767)
+
+/*
+ * Zero Userspace
+ */
+
+static inline unsigned long
+clear_user(void *to, unsigned long n)
+{
+	memset(to, 0, n);
+    return(0);
+}
+
+#endif /* _NIOSNOMMU_UACCESS_H */
diff -urN linux-2.4.29/include/asm-niosnommu/ucontext.h linux-2.4.29-uc1/include/asm-niosnommu/ucontext.h
--- linux-2.4.29/include/asm-niosnommu/ucontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/ucontext.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef _NIOS_UCONTEXT_H
+#define _NIOS_UCONTEXT_H
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct sigcontext uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif /* !_NIOS_UCONTEXT_H */
diff -urN linux-2.4.29/include/asm-niosnommu/unaligned.h linux-2.4.29-uc1/include/asm-niosnommu/unaligned.h
--- linux-2.4.29/include/asm-niosnommu/unaligned.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/unaligned.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,19 @@
+#ifndef __NIOS_UNALIGNED_H
+#define __NIOS_UNALIGNED_H
+
+/*
+ * The nios cannot do unaligned accesses itself. 
+ */ 
+
+#define get_unaligned(ptr) ({			\
+	typeof((*(ptr))) x;			\
+	memcpy(&x, (void*)ptr, sizeof(*(ptr)));	\
+	x;					\
+})
+
+#define put_unaligned(val, ptr) ({		\
+	typeof((*(ptr))) x = val;		\
+	memcpy((void*)ptr, &x, sizeof(*(ptr)));	\
+})
+
+#endif /* __NIOS_UNALIGNED_H */
diff -urN linux-2.4.29/include/asm-niosnommu/unistd.h linux-2.4.29-uc1/include/asm-niosnommu/unistd.h
--- linux-2.4.29/include/asm-niosnommu/unistd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/unistd.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,399 @@
+//vic - kernel_thread moved to process.c
+
+/* For now, the TRAP isr is assumed to expect the syscall # in %g1,
+ * and the other arguments passed in %o0, %o1, %o2, %o3, %o4.
+ * The return argument is expected in %o0.
+ * The isr's are defined in entry.S.
+ */
+
+#ifndef _ASM_NIOS_UNISTD_H_
+#define _ASM_NIOS_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ */
+
+//vic #define __NR_setup		  0	/* used only by init, to get system going */
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_chown		 16
+#define __NR_break		 17
+#define __NR_oldstat		 18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_umount2		 52	//vic #define __NR_phys		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+#define __NR_oldolduname	 59
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_old_getrlimit	 76
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+#define __NR_ioperm		101
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_olduname		109
+#define __NR_iopl		/* 110 */ not supported
+#define __NR_vhangup		111
+#define __NR_idle		/* 112 */ Obsolete
+#define __NR_vm86		/* 113 */ not supported
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_cacheflush		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+//vic - added from m68knommu's
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl		172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread		180
+#define __NR_pwrite		181
+#define __NR_lchown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_getpmsg		188	/* some people actually want streams */
+#define __NR_putpmsg		189	/* some people actually want streams */
+#define __NR_vfork		190
+#define __NR_getrlimit		191
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_chown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_lchown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+#define __NR_getdents64		220
+
+
+/* user-visible error numbers are in the range -1 - -122: see
+   <asm-niosnommu/errno.h> */
+
+#define __syscall_return(type, res) \
+do { \
+	if ((unsigned long)(res) >= (unsigned long)(-125)) { \
+	/* avoid using res which is declared to be in register g1; \
+	   errno might expand to a function call and clobber it.  */ \
+		int __err = -(res); \
+		errno = __err; \
+		res = -1; \
+	} \
+	return (type) (res); \
+} while (0)
+
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+register long __res __asm__ ("%g1") = __NR_##name; \
+__asm__ __volatile__ ("trap  63\n\t" \
+				"mov	%%g1, %%o0"	\
+              : "=r" (__res) \
+		      : "0" (__res) \
+		      : "g1","o0"); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall1(type,name,atype,a) \
+type name(atype a) \
+{ \
+register long __res __asm__ ("%g1") = __NR_##name; \
+register long __a __asm__ ("%o0") = (long)(a); \
+__asm__ __volatile__ ("trap  63\n\t" \
+				"mov	%%g1, %%o0"	\
+		      : "=r" (__res) \
+		      : "0" (__res), "d" (__a) \
+		      : "g1","o0"); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall2(type,name,atype,a,btype,b) \
+type name(atype a,btype b) \
+{ \
+register long __res __asm__ ("%g1") = __NR_##name; \
+register long __a __asm__ ("%o0") = (long)(a); \
+register long __b __asm__ ("%o1") = (long)(b); \
+__asm__ __volatile__ ("trap  63\n\t" \
+				"mov	%%g1, %%o0"	\
+		      : "=r" (__res) \
+            : "0" (__res), "d" (__a), "d" (__b) \
+		      : "g1","o0"); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall3(type,name,atype,a,btype,b,ctype,c) \
+type name(atype a,btype b,ctype c) \
+{ \
+register long __res __asm__ ("%g1") = __NR_##name; \
+register long __a __asm__ ("%o0") = (long)(a); \
+register long __b __asm__ ("%o1") = (long)(b); \
+register long __c __asm__ ("%o2") = (long)(c); \
+__asm__ __volatile__ ("trap  63\n\t" \
+				"mov	%%g1, %%o0"	\
+		      : "=r" (__res) \
+            : "0" (__res), "d" (__a), "d" (__b), \
+			"d" (__c) \
+		      : "g1","o0"); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
+type name (atype a, btype b, ctype c, dtype d) \
+{ \
+register long __res __asm__ ("%g1") = __NR_##name; \
+register long __a __asm__ ("%o0") = (long)(a); \
+register long __b __asm__ ("%o1") = (long)(b); \
+register long __c __asm__ ("%o2") = (long)(c); \
+register long __d __asm__ ("%o3") = (long)(d); \
+__asm__ __volatile__ ("trap  63\n\t" \
+				"mov	%%g1, %%o0"	\
+                      : "=r" (__res) \
+                      : "0" (__res), "d" (__a), "d" (__b), \
+			"d" (__c), "d" (__d)  \
+		      : "g1","o0"); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
+type name (atype a,btype b,ctype c,dtype d,etype e) \
+{ \
+register long __res __asm__ ("%g1") = __NR_##name; \
+register long __a __asm__ ("%o0") = (long)(a); \
+register long __b __asm__ ("%o1") = (long)(b); \
+register long __c __asm__ ("%o2") = (long)(c); \
+register long __d __asm__ ("%o3") = (long)(d); \
+register long __e __asm__ ("%o4") = (long)(e); \
+__asm__ __volatile__ ("trap  63\n\t" \
+				"mov	%%g1, %%o0"	\
+		      : "=r" (__res) \
+		      : "0" (__res), "d" (__a), "d" (__b), \
+			"d" (__c), "d" (__d), "d" (__e)  \
+                      : "g1","o0"); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \
+type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \
+{ \
+register long __res __asm__ ("%g1") = __NR_##name; \
+register long __a __asm__ ("%o0") = (long)(a); \
+register long __b __asm__ ("%o1") = (long)(b); \
+register long __c __asm__ ("%o2") = (long)(c); \
+register long __d __asm__ ("%o3") = (long)(d); \
+register long __e __asm__ ("%o4") = (long)(e); \
+register long __e __asm__ ("%o5") = (long)(f); \
+__asm__ __volatile__ ("trap  63\n\t" \
+				"mov	%%g1, %%o0"	\
+		      : "=r" (__res) \
+		      : "0" (__res), "d" (__a), "d" (__b), \
+			"d" (__c), "d" (__d), "d" (__e), "d" (__f)  \
+                      : "g1","o0"); \
+__syscall_return(type,__res); \
+}
+
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+//vic FIXME obsolete ?
+//vic static inline _syscall0(int,fork)
+//vic static inline _syscall2(int,clone,unsigned long,flags,char *,usp)
+static inline _syscall0(int,pause)
+static inline _syscall0(int,sync)
+static inline _syscall0(pid_t,setsid)
+static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+static inline _syscall1(int,dup,int,fd)
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+static inline _syscall1(int,close,int,fd)
+static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,delete_module,const char *,name)
+
+static inline pid_t wait(int * wait_stat)
+{
+	return waitpid(-1,wait_stat,0);
+}
+
+#endif
+
+#endif /* _ASM_NIOS_UNISTD_H_ */
diff -urN linux-2.4.29/include/asm-niosnommu/user.h linux-2.4.29-uc1/include/asm-niosnommu/user.h
--- linux-2.4.29/include/asm-niosnommu/user.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/user.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,68 @@
+/* Vic - copied from i960 */
+#ifndef _NIOS_USER_H
+#define _NIOS_USER_H
+
+#include <asm/page.h>
+#include <linux/ptrace.h>
+/* Core file format: The core file is written in such a way that gdb
+   can understand it and provide useful information to the user (under
+   linux we use the 'trad-core' bfd).  There are quite a number of
+   obstacles to being able to view the contents of the floating point
+   registers, and until these are solved you will not be able to view the
+   contents of them.  Actually, you can read in the core file and look at
+   the contents of the user struct to find out what the floating point
+   registers contain.
+   The actual file contents are as follows:
+   UPAGE: 1 page consisting of a user struct that tells gdb what is present
+   in the file.  Directly after this is a copy of the task_struct, which
+   is currently not used by gdb, but it may come in useful at some point.
+   All of the registers are stored as part of the upage.  The upage should
+   always be only one page.
+   DATA: The data area is stored.  We use current->end_text to
+   current->brk to pick up all of the user variables, plus any memory
+   that may have been malloced.  No attempt is made to determine if a page
+   is demand-zero or if a page is totally unused, we just cover the entire
+   range.  All of the addresses are rounded in such a way that an integral
+   number of pages is written.
+   STACK: We need the stack information in order to get a meaningful
+   backtrace.  We need to write the data from (esp) to
+   current->start_stack, so we round each of these off in order to be able
+   to write an integer number of pages.
+   The minimum core file size is 3 pages, or 12288 bytes.
+*/
+
+struct user_fp_struct {
+	unsigned long  fpregs[8*3];	/* fp0-fp7 registers */
+	unsigned long  fpcntl[3];	/* fp control regs */
+};
+
+/* When the kernel dumps core, it starts by dumping the user struct -
+   this will be used by gdb to figure out where the data and stack segments
+   are within the file, and what virtual addresses to use. */
+struct user{
+/* We start with the registers, to mimic the way that "memory" is returned
+   from the ptrace(3,...) function.  */
+  struct pt_regs regs;		/* Where the registers are actually stored */
+/* ptrace does not yet supply these.  Someday.... */
+/* The rest of this junk is to help gdb figure out what goes where */
+  unsigned long int u_tsize;	/* Text segment size (pages). */
+  unsigned long int u_dsize;	/* Data segment size (pages). */
+  unsigned long int u_ssize;	/* Stack segment size (pages). */
+  unsigned long start_code;     /* Starting virtual address of text. */
+  unsigned long start_stack;	/* Starting virtual address of stack area.
+				   This is actually the bottom of the stack,
+				   the top of the stack is always found in the
+				   esp register.  */
+  long int signal;     		/* Signal that caused the core dump. */
+  int reserved;			/* No longer used */
+  struct pt_regs * u_ar0;	/* Used by gdb to help find the values for */
+				/* the registers. */
+  unsigned long magic;		/* To uniquely identify a core file */
+  char u_comm[32];		/* User command that was responsible */
+};
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+#endif	/* _NIOS_USER_H */
diff -urN linux-2.4.29/include/asm-niosnommu/virtconvert.h linux-2.4.29-uc1/include/asm-niosnommu/virtconvert.h
--- linux-2.4.29/include/asm-niosnommu/virtconvert.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/virtconvert.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,26 @@
+#ifndef __NIOS_VIRT_CONVERT__
+#define __NIOS_VIRT_CONVERT__
+
+/*
+ * Macros used for converting between virtual and physical mappings.
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+
+#define mm_ptov(vaddr)		((void *) (vaddr))
+#define mm_vtop(vaddr)		((unsigned long) (vaddr))
+#define phys_to_virt(vaddr)	((void *) (vaddr))
+#define virt_to_phys(vaddr)	((unsigned long) (vaddr))
+
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define page_to_phys(page)	virt_to_phys((void *)__page_address(page))
+
+#endif /*__KERNEL__ */
+#endif /*__NIOS_VIRT_CONVERT__*/
diff -urN linux-2.4.29/include/asm-niosnommu/winmacro.h linux-2.4.29-uc1/include/asm-niosnommu/winmacro.h
--- linux-2.4.29/include/asm-niosnommu/winmacro.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-niosnommu/winmacro.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,285 @@
+//vic - change use of current_set to just current - needs verification
+/*
+ * Feb 27, 2000 - Ken Hill
+ *    Convert to Nios assembler. Note, most immediate values have to be word
+ *    sized. The Nios processor word scales (*4) most immediate values.
+ *    Convert most defines to .macro would not process them. this also allows for
+ *    more offset size checking for required PFX instruction.
+ *
+ * winmacro.h: Window loading-unloading macros.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _NIOS_WINMACRO_H
+#define _NIOS_WINMACRO_H
+
+#include <asm/ptrace.h>
+#include <asm/psr.h>
+
+#define WRITE_PAUSE      nop; /* Have to do this after %psr chg */
+
+	.macro FLUSH_ALL_KERNEL_WINDOWS
+
+	rdctl	%g7			;vic; get STATUS
+	mov	%g6, %g7		;vic;
+	ANDIP	%g6, 0x01ff ;vic; clear IE, IPRI
+	ORIP	%g6, 0x0600 ;vic; set IPRI = 3
+	wrctl	%g6			;vic;
+	 nop					;vic;
+	 nop					;vic;
+
+	.rept	31
+	save	%sp, -REGWIN_SZ/4
+	.endr
+	.rept	31
+	restore
+	.endr
+
+	wrctl	%g7			;vic; restore STATUS
+	 nop					;vic;
+
+	.endm
+
+/* Store the register window onto the stack. */
+
+	.macro STORE_WINDOW
+
+	sts	[%sp, RW_L0/4], %l0;
+	sts	[%sp, RW_L1/4], %l1;
+	sts	[%sp, RW_L2/4], %l2;
+	sts	[%sp, RW_L3/4], %l3;
+	sts	[%sp, RW_L4/4], %l4;
+	sts	[%sp, RW_L5/4], %l5;
+	sts	[%sp, RW_L6/4], %l6;
+	sts	[%sp, RW_L7/4], %l7;
+	sts	[%sp, RW_I0/4], %i0;
+	sts	[%sp, RW_I1/4], %i1;
+	sts	[%sp, RW_I2/4], %i2;
+	sts	[%sp, RW_I3/4], %i3;
+	sts	[%sp, RW_I4/4], %i4;
+	sts	[%sp, RW_I5/4], %i5;
+	sts	[%sp, RW_I6/4], %i6;
+	sts	[%sp, RW_I7/4], %i7;
+
+	.endm
+
+
+/* Load a register window from the area beginning at %sp. */
+
+	.macro LOAD_WINDOW
+
+	lds	%l0, [%sp, RW_L0/4];
+	lds	%l1, [%sp, RW_L1/4];
+	lds	%l2, [%sp, RW_L2/4];
+	lds	%l3, [%sp, RW_L3/4];
+	lds	%l4, [%sp, RW_L4/4];
+	lds	%l5, [%sp, RW_L5/4];
+	lds	%l6, [%sp, RW_L6/4];
+	lds	%l7, [%sp, RW_L7/4];
+	lds	%i0, [%sp, RW_I0/4];
+	lds	%i1, [%sp, RW_I1/4];
+	lds	%i2, [%sp, RW_I2/4];
+	lds	%i3, [%sp, RW_I3/4];
+	lds	%i4, [%sp, RW_I4/4];
+	lds	%i5, [%sp, RW_I5/4];
+	lds	%i6, [%sp, RW_I6/4];
+	lds	%i7, [%sp, RW_I7/4]; 
+
+	.endm
+
+/* Loading and storing struct pt_reg trap frames. */
+
+	.macro LOAD_PT_INS
+
+        lds    %i0, [%sp, (REGWIN_SZ + PT_I0)/4]
+        lds    %i1, [%sp, (REGWIN_SZ + PT_I1)/4]
+        lds    %i2, [%sp, (REGWIN_SZ + PT_I2)/4]
+        lds    %i3, [%sp, (REGWIN_SZ + PT_I3)/4]
+        lds    %i4, [%sp, (REGWIN_SZ + PT_I4)/4]
+        lds    %i5, [%sp, (REGWIN_SZ + PT_I5)/4]
+        lds    %i6, [%sp, (REGWIN_SZ + PT_I6)/4]
+        lds    %i7, [%sp, (REGWIN_SZ + PT_I7)/4]
+
+	.endm
+
+	.macro LOAD_PT_GLOBALS
+
+        lds    %g0, [%sp, (REGWIN_SZ + PT_G0)/4]
+        lds    %g1, [%sp, (REGWIN_SZ + PT_G1)/4]
+        lds    %g2, [%sp, (REGWIN_SZ + PT_G2)/4]
+        lds    %g3, [%sp, (REGWIN_SZ + PT_G3)/4]
+        lds    %g4, [%sp, (REGWIN_SZ + PT_G4)/4]
+        lds    %g5, [%sp, (REGWIN_SZ + PT_G5)/4]
+        lds    %g6, [%sp, (REGWIN_SZ + PT_G6)/4]
+        lds    %g7, [%sp, (REGWIN_SZ + PT_G7)/4]
+
+	.endm
+
+	.macro LOAD_PT_PRIV pt_psr, pt_pc
+
+        lds    %\pt_psr, [%sp, (REGWIN_SZ + PT_PSR)/4]
+        lds    %\pt_pc, [%sp, (REGWIN_SZ + PT_PC)/4] 
+
+	.endm
+
+	.macro LOAD_PT_ALL pt_psr, pt_pc
+
+        LOAD_PT_INS
+        LOAD_PT_GLOBALS
+        LOAD_PT_PRIV \pt_psr, \pt_pc
+
+	.endm
+
+	.macro STORE_PT_INS
+
+        sts    [%sp, (REGWIN_SZ + PT_I0)/4], %i0
+        sts    [%sp, (REGWIN_SZ + PT_I1)/4], %i1
+        sts    [%sp, (REGWIN_SZ + PT_I2)/4], %i2
+        sts    [%sp, (REGWIN_SZ + PT_I3)/4], %i3
+        sts    [%sp, (REGWIN_SZ + PT_I4)/4], %i4
+        sts    [%sp, (REGWIN_SZ + PT_I5)/4], %i5
+        sts    [%sp, (REGWIN_SZ + PT_I6)/4], %i6
+        sts    [%sp, (REGWIN_SZ + PT_I7)/4], %i7
+
+	.endm
+
+	.macro STORE_PT_GLOBALS
+
+        sts    [%sp, (REGWIN_SZ + PT_G0)/4], %g0
+        sts    [%sp, (REGWIN_SZ + PT_G1)/4], %g1
+        sts    [%sp, (REGWIN_SZ + PT_G2)/4], %g2
+        sts    [%sp, (REGWIN_SZ + PT_G3)/4], %g3
+        sts    [%sp, (REGWIN_SZ + PT_G4)/4], %g4
+        sts    [%sp, (REGWIN_SZ + PT_G5)/4], %g5
+        sts    [%sp, (REGWIN_SZ + PT_G6)/4], %g6
+        sts    [%sp, (REGWIN_SZ + PT_G7)/4], %g7
+
+	.endm
+
+	.macro STORE_PT_PRIV pt_psr, pt_pc
+
+        sts    [%sp, (REGWIN_SZ + PT_PSR)/4], %\pt_psr
+        sts    [%sp, (REGWIN_SZ + PT_PC)/4], %\pt_pc
+
+	.endm
+
+	.macro STORE_PT_ALL reg_psr, reg_pc
+
+        STORE_PT_PRIV \reg_psr, \reg_pc
+        STORE_PT_GLOBALS
+        STORE_PT_INS
+
+	.endm
+
+	.macro LOAD_CURRENT dest_reg
+
+//vic	MOVIA	%\dest_reg,C_LABEL(current_set);
+//vic	MOVIA	%\dest_reg,C_LABEL(current);
+	MOVIA	%\dest_reg,C_LABEL(_current_task);
+	ld      %\dest_reg, [%\dest_reg];
+
+	.endm
+
+	.macro STORE_CURRENT new_task, scratch_reg
+
+//vic	MOVIA	%\scratch_reg,C_LABEL(current_set);
+//vic	MOVIA	%\scratch_reg,C_LABEL(current);
+	MOVIA	%\scratch_reg,C_LABEL(_current_task);
+	st      [%\scratch_reg], %\new_task;
+
+	.endm
+
+;;	As long as kernel sp is valid, the task struct can be accessed
+	.macro GET_CURRENT dest_reg
+
+	mov	%\dest_reg, %sp
+	lsri	%\dest_reg, 13
+	lsli	%\dest_reg, 13
+
+	.endm
+/* macro for flushing register from current CWP to HI_LIMIT into the stack windows */
+/* xwt: the caller is responsible for disabling interrupts for the following two macros */
+
+	.macro	FLUSH_WINDOWS
+
+;;	pfx	8
+;;	wrctl	%g5				; disable interrupts
+
+;	pfx	0
+	rdctl	%g5				; read STATUS
+	mov	%g3, %g5			; save STATUS
+	mov	%g6, %o6			; save stack ptr
+	mov	%g7, %o7			; save return address
+
+	ANDIP	%g5, PSR_CWP			; isolate CWP
+
+	pfx	2
+	rdctl	%g4				; read WVALID
+	lsri	%g4, 1				; get HI_LIMIT into CWP position
+	ANDIP	%g4, PSR_CWP			; isolate it
+8:
+	STORE_WINDOW				; save %i's & %l's into stack register window
+	restore					; CWP += 1
+	cmp	%g5, %g4			; reached HI_LIMIT yet ?
+	BNE	8b					; No
+	 addi	%g5, 0x10			; step our value for CWP
+
+;	pfx	0
+	wrctl	%g3				; restore STATUS
+	 nop
+	 nop
+	mov	%sp, %g6			; restore stack ptr
+	mov	%o7, %g7			; restore return address
+
+;;	pfx	9
+;;	wrctl	%g5				; enable interrupts
+
+	.endm
+
+/* macro for filling register from current CWP to HI_LIMIT from the stack windows */
+	.macro	FILL_WINDOWS
+
+;;	pfx	8
+;;	wrctl	%g5				; disable interrupts
+
+;;	pfx	0
+	rdctl	%g5				; read STATUS
+	mov	%g3, %g5			; save STATUS
+	mov	%g6, %sp			; save stack ptr
+	mov	%g7, %o7			; save return address
+
+	ANDIP	%g5, PSR_CWP			; isolate CWP
+
+	pfx	2
+	rdctl	%g4				; read WVALID
+	lsri	%g4, 1				; get HI_LIMIT into CWP position
+	ANDIP	%g4, PSR_CWP			; isolate it
+9:
+	LOAD_WINDOW				; load %i's & %l's from stack into register window
+	restore					; CWP += 1
+	cmp	%g5, %g4			; reached HI_LIMIT yet ?
+	BNE	9b				; No
+	 addi	%g5, 0x10			; step our value for CWP
+
+;;	pfx	0
+	wrctl	%g3				; restore STATUS
+	 nop
+	 nop
+	mov	%sp, %g6			; restore stack ptr
+	mov	%o7, %g7			; restore return address
+
+;;	pfx	9
+;;	wrctl	%g5				; enable interrupts
+
+	.endm
+
+
+#endif /* !(_NIOS_WINMACRO_H) */
+
+
+
+
+
+
+
diff -urN linux-2.4.29/include/asm-parisc/div64.h linux-2.4.29-uc1/include/asm-parisc/div64.h
--- linux-2.4.29/include/asm-parisc/div64.h	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-parisc/div64.h	2005-06-14 02:11:37.000000000 +0100
@@ -2,23 +2,7 @@
 #define __ASM_PARISC_DIV64
 
 #ifdef __LP64__
-
-/*
- * Copyright (C) 1999 Hewlett-Packard Co
- * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * vsprintf uses this to divide a 64-bit integer N by a small integer BASE.
- * This is incredibly hard on IA-64 and HPPA
- */
-
-#define do_div(n,base)						\
-({								\
-	int _res;						\
-	_res = ((unsigned long) (n)) % (unsigned) (base);	\
-	(n) = ((unsigned long) (n)) / (unsigned) (base);	\
-	_res;							\
-})
-
+#include <asm-generic/div64.h>
 #else
 /*
  * unsigned long long division.  Yuck Yuck!  What is Linux coming to?
@@ -30,21 +14,21 @@
 	__low  = (n) & 0xffffffff;					\
 	__high = (n) >> 32;						\
 	if (__high) {							\
-		__rem   = __high % (unsigned long)base;			\
-		__high  = __high / (unsigned long)base;			\
+		__rem   = __high % (unsigned long)(base);		\
+		__high  = __high / (unsigned long)(base);		\
 		__low2  = __low >> 16;					\
 		__low2 += __rem << 16;					\
-		__rem   = __low2 % (unsigned long)base;			\
-		__low2  = __low2 / (unsigned long)base;			\
+		__rem   = __low2 % (unsigned long)(base);		\
+		__low2  = __low2 / (unsigned long)(base);		\
 		__low   = __low & 0xffff;				\
 		__low  += __rem << 16;					\
-		__rem   = __low  % (unsigned long)base;			\
-		__low   = __low  / (unsigned long)base;			\
-		n = __low  + ((long long)__low2 << 16) +		\
+		__rem   = __low  % (unsigned long)(base);		\
+		__low   = __low  / (unsigned long)(base);		\
+		(n) = __low  + ((long long)__low2 << 16) +		\
 			((long long) __high << 32);			\
 	} else {							\
-		__rem = __low % (unsigned long)base;			\
-		n = (__low / (unsigned long)base);			\
+		__rem = __low % (unsigned long)(base);			\
+		(n) = (__low / (unsigned long)(base));			\
 	}								\
 	__rem;								\
 })
diff -urN linux-2.4.29/include/asm-ppc64/div64.h linux-2.4.29-uc1/include/asm-ppc64/div64.h
--- linux-2.4.29/include/asm-ppc64/div64.h	2002-08-03 01:39:45.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-ppc64/div64.h	2005-06-14 02:11:39.000000000 +0100
@@ -1,18 +1 @@
-#ifndef __PPC_DIV64
-#define __PPC_DIV64
-
-/* Copyright 2001 PPC64 Team, IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#define do_div(n,base) ({ \
-	int __res; \
-	__res = ((unsigned long) (n)) % (unsigned) (base); \
-	(n) = ((unsigned long) (n)) / (unsigned) (base); \
-	__res; })
-
-#endif
+#include <asm-generic/div64.h>
diff -urN linux-2.4.29/include/asm-s390x/div64.h linux-2.4.29-uc1/include/asm-s390x/div64.h
--- linux-2.4.29/include/asm-s390x/div64.h	2001-02-13 22:13:44.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-s390x/div64.h	2005-06-14 02:11:40.000000000 +0100
@@ -1,10 +1 @@
-#ifndef __S390_DIV64
-#define __S390_DIV64
-
-#define do_div(n,base) ({ \
-int __res; \
-__res = ((unsigned long) n) % (unsigned) base; \
-n = ((unsigned long) n) / (unsigned) base; \
-__res; })
-
-#endif
+#include <asm-generic/div64.h>
diff -urN linux-2.4.29/include/asm-sh/bugs.h linux-2.4.29-uc1/include/asm-sh/bugs.h
--- linux-2.4.29/include/asm-sh/bugs.h	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/bugs.h	2005-06-14 02:11:39.000000000 +0100
@@ -32,11 +32,23 @@
 		break;
 	case CPU_SH7750:
 		*p++ = '4';
-		printk("CPU: SH7750/SH7751\n");
+		printk("CPU: SH7750\n");
 		break;
-	case CPU_ST40:
+	case CPU_ST40RA:
 		*p++ = '4';
-		printk("CPU: ST40STB1/GX1\n");
+		printk("CPU: ST40RA\n");
+		break;
+	case CPU_ST40GX1:
+		*p++ = '4';
+		printk("CPU: ST40GX1\n");
+		break;
+	case CPU_SH7751:
+		*p++ = '4';
+		printk("CPU: SH7751\n");
+		break;
+	case CPU_SH7751R:
+		*p++ = '4';
+		printk("CPU: SH7751R\n");
 		break;
 	default:
 		printk("CPU: ??????\n");
diff -urN linux-2.4.29/include/asm-sh/cacheflush.h linux-2.4.29-uc1/include/asm-sh/cacheflush.h
--- linux-2.4.29/include/asm-sh/cacheflush.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/cacheflush.h	2005-06-14 02:11:39.000000000 +0100
@@ -0,0 +1,15 @@
+#ifndef __ASM_SH_CACHEFLUSH_H
+#define __ASM_SH_CACHEFLUSH_H
+
+#define	flush_page_to_ram(page)		do { } while (0)
+
+#include <asm/cpu/cacheflush.h>
+
+/* Flush (write-back only) a region (smaller than a page) */
+extern void __flush_wback_region(void *start, int size);
+/* Flush (write-back & invalidate) a region (smaller than a page) */
+extern void __flush_purge_region(void *start, int size);
+/* Flush (invalidate only) a region (smaller than a page) */
+extern void __flush_invalidate_region(void *start, int size);
+
+#endif /* __ASM_SH_CACHEFLUSH_H */
diff -urN linux-2.4.29/include/asm-sh/cache.h linux-2.4.29-uc1/include/asm-sh/cache.h
--- linux-2.4.29/include/asm-sh/cache.h	2001-09-08 20:29:09.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/cache.h	2005-06-14 02:11:39.000000000 +0100
@@ -1,17 +1,54 @@
-/* $Id: cache.h,v 1.3 2000/07/04 06:24:49 gniibe Exp $
+/* $Id: cache.h,v 1.5 2003/07/16 04:08:29 lethal Exp $
  *
  * include/asm-sh/cache.h
  *
  * Copyright 1999 (C) Niibe Yutaka
+ * Copyright 2002, 2003 (C) Paul Mundt
  */
 #ifndef __ASM_SH_CACHE_H
 #define __ASM_SH_CACHE_H
 
-/* bytes per L1 cache line */
-#if defined(__sh3__)
-#define        L1_CACHE_BYTES  16
-#elif defined(__SH4__)
-#define        L1_CACHE_BYTES  32
+#include <asm/cpu/cache.h>
+#include <asm/cpu/cacheflush.h>
+
+#define SH_CACHE_VALID		1
+#define SH_CACHE_UPDATED	2
+#define SH_CACHE_COMBINED	4
+#define SH_CACHE_ASSOC		8
+
+#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
+#define SMP_CACHE_BYTES		L1_CACHE_BYTES
+
+#define L1_CACHE_ALIGN(x)	(((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
+
+#ifdef MODULE
+#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES)))
+#else
+#define __cacheline_aligned					\
+  __attribute__((__aligned__(L1_CACHE_BYTES),			\
+		 __section__(".data.cacheline_aligned")))
 #endif
 
+#define L1_CACHE_SHIFT_MAX 	5	/* largest L1 which this arch supports */
+
+struct cache_info {
+	unsigned int ways;
+	unsigned int sets;
+	unsigned int linesz;
+
+	unsigned int way_shift;
+	unsigned int entry_shift;
+	unsigned int entry_mask;
+
+	unsigned long flags;
+};
+
+/* Flush (write-back only) a region (smaller than a page) */
+extern void __flush_wback_region(void *start, int size);
+/* Flush (write-back & invalidate) a region (smaller than a page) */
+extern void __flush_purge_region(void *start, int size);
+/* Flush (invalidate only) a region (smaller than a page) */
+extern void __flush_invalidate_region(void *start, int size);
+
 #endif /* __ASM_SH_CACHE_H */
+
diff -urN linux-2.4.29/include/asm-sh/cpu-sh3/cacheflush.h linux-2.4.29-uc1/include/asm-sh/cpu-sh3/cacheflush.h
--- linux-2.4.29/include/asm-sh/cpu-sh3/cacheflush.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/cpu-sh3/cacheflush.h	2005-06-14 02:11:39.000000000 +0100
@@ -0,0 +1,41 @@
+/*
+ * include/asm-sh/cpu-sh3/cacheflush.h
+ *
+ * Copyright (C) 1999 Niibe Yutaka
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __ASM_CPU_SH3_CACHEFLUSH_H
+#define __ASM_CPU_SH3_CACHEFLUSH_H
+
+/* 
+ * Cache flushing:
+ *
+ *  - flush_cache_all() flushes entire cache
+ *  - flush_cache_mm(mm) flushes the specified mm context's cache lines
+ *  - flush_cache_page(mm, vmaddr) flushes a single page
+ *  - flush_cache_range(vma, start, end) flushes a range of pages
+ *
+ *  - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache
+ *  - flush_icache_range(start, end) flushes(invalidates) a range for icache
+ *  - flush_icache_page(vma, pg) flushes(invalidates) a page for icache
+ *
+ *  Caches are indexed (effectively) by physical address on SH-3, so
+ *  we don't need them.
+ */
+#define flush_cache_all()			do { } while (0)
+#define flush_cache_mm(mm)			do { } while (0)
+#define flush_cache_range(vma, start, end)	do { } while (0)
+#define flush_cache_page(vma, vmaddr)		do { } while (0)
+#define flush_dcache_page(page)			do { } while (0)
+#define flush_icache_range(start, end)		do { } while (0)
+#define flush_icache_page(vma,pg)		do { } while (0)
+#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
+#define flush_cache_sigtramp(vaddr)		do { } while (0)
+
+#define p3_cache_init()				do { } while (0)
+
+#endif /* __ASM_CPU_SH3_CACHEFLUSH_H */
+
diff -urN linux-2.4.29/include/asm-sh/cpu-sh3/cache.h linux-2.4.29-uc1/include/asm-sh/cpu-sh3/cache.h
--- linux-2.4.29/include/asm-sh/cpu-sh3/cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/cpu-sh3/cache.h	2005-06-14 02:11:39.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ * include/asm-sh/cpu-sh3/cache.h
+ *
+ * Copyright (C) 1999 Niibe Yutaka
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __ASM_CPU_SH3_CACHE_H
+#define __ASM_CPU_SH3_CACHE_H
+
+#define L1_CACHE_SHIFT	4
+
+#define CCR		0xffffffec	/* Address of Cache Control Register */
+
+#define CCR_CACHE_CE	0x01	/* Cache Enable */
+#define CCR_CACHE_WT	0x02	/* Write-Through (for P0,U0,P3) (else writeback) */
+#define CCR_CACHE_CB	0x04	/* Write-Back (for P1) (else writethrough) */
+#define CCR_CACHE_CF	0x08	/* Cache Flush */
+#define CCR_CACHE_ORA	0x20	/* RAM mode */
+
+#define CACHE_OC_ADDRESS_ARRAY	0xf0000000
+#define CACHE_PHYSADDR_MASK	0x1ffffc00
+
+#define CCR_CACHE_ENABLE	CCR_CACHE_CE
+#define CCR_CACHE_INVALIDATE	CCR_CACHE_CF
+
+#endif /* __ASM_CPU_SH3_CACHE_H */
+
diff -urN linux-2.4.29/include/asm-sh/cpu-sh4/cacheflush.h linux-2.4.29-uc1/include/asm-sh/cpu-sh4/cacheflush.h
--- linux-2.4.29/include/asm-sh/cpu-sh4/cacheflush.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/cpu-sh4/cacheflush.h	2005-06-14 02:11:39.000000000 +0100
@@ -0,0 +1,52 @@
+/*
+ * include/asm-sh/cpu-sh4/cacheflush.h
+ *
+ * Copyright (C) 1999 Niibe Yutaka
+ * Copyright (C) 2003 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __ASM_CPU_SH4_CACHEFLUSH_H
+#define __ASM_CPU_SH4_CACHEFLUSH_H
+
+/*
+ *  Caches are broken on SH-4 (unless we use write-through
+ *  caching; in which case they're only semi-broken),
+ *  so we need them.
+ */
+
+/* Page is 4K, OC size is 16K, there are four lines. */
+#define CACHE_ALIAS 0x00003000
+
+struct page;
+struct mm_struct;
+struct vm_area_struct;
+
+extern void flush_cache_all(void);
+extern void flush_cache_mm(struct mm_struct *mm);
+extern void flush_cache_range(struct mm_struct *mm, unsigned long start,
+			      unsigned long end);
+extern void flush_cache_page(struct vm_area_struct *vma, unsigned long addr);
+extern void flush_dcache_page(struct page *pg);
+extern void flush_icache_range(unsigned long start, unsigned long end);
+extern void flush_cache_sigtramp(unsigned long addr);
+extern void flush_icache_user_range(struct vm_area_struct *vma,
+				    struct page *page, unsigned long addr,
+				    int len);
+
+#define flush_icache_page(vma,pg)		do { } while (0)
+
+/* Initialization of P3 area for copy_user_page */
+extern void p3_cache_init(void);
+
+#define PG_mapped	PG_arch_1
+
+/* We provide our own get_unmapped_area to avoid cache alias issue */
+#define HAVE_ARCH_UNMAPPED_AREA
+
+extern int remap_area_pages(unsigned long addr, unsigned long phys_addr,
+			    unsigned long size, unsigned long flags);
+#endif /* __ASM_CPU_SH4_CACHEFLUSH_H */
+
diff -urN linux-2.4.29/include/asm-sh/cpu-sh4/cache.h linux-2.4.29-uc1/include/asm-sh/cpu-sh4/cache.h
--- linux-2.4.29/include/asm-sh/cpu-sh4/cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/cpu-sh4/cache.h	2005-06-14 02:11:39.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ * include/asm-sh/cpu-sh4/cache.h
+ *
+ * Copyright (C) 1999 Niibe Yutaka
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __ASM_CPU_SH4_CACHE_H
+#define __ASM_CPU_SH4_CACHE_H
+
+#define L1_CACHE_SHIFT	5
+
+#define CCR		0xff00001c	/* Address of Cache Control Register */
+#define CCR_CACHE_OCE	0x0001	/* Operand Cache Enable */
+#define CCR_CACHE_WT	0x0002	/* Write-Through (for P0,U0,P3) (else writeback)*/
+#define CCR_CACHE_CB	0x0004	/* Copy-Back (for P1) (else writethrough) */
+#define CCR_CACHE_OCI	0x0008	/* OC Invalidate */
+#define CCR_CACHE_ORA	0x0020	/* OC RAM Mode */
+#define CCR_CACHE_OIX	0x0080	/* OC Index Enable */
+#define CCR_CACHE_ICE	0x0100	/* Instruction Cache Enable */
+#define CCR_CACHE_ICI	0x0800	/* IC Invalidate */
+#define CCR_CACHE_IIX	0x8000	/* IC Index Enable */
+#define CCR_CACHE_EMODE	0x80000000	/* EMODE Enable */
+
+/* Default CCR setup: 8k+16k-byte cache,P1-wb,enable */
+#define CCR_CACHE_ENABLE	(CCR_CACHE_OCE|CCR_CACHE_ICE)
+#define CCR_CACHE_INVALIDATE	(CCR_CACHE_OCI|CCR_CACHE_ICI)
+
+#define CACHE_IC_ADDRESS_ARRAY	0xf0000000
+#define CACHE_OC_ADDRESS_ARRAY	0xf4000000
+
+#endif /* __ASM_CPU_SH4_CACHE_H */
+
diff -urN linux-2.4.29/include/asm-sh/fast_timer.h linux-2.4.29-uc1/include/asm-sh/fast_timer.h
--- linux-2.4.29/include/asm-sh/fast_timer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/fast_timer.h	2005-06-14 02:11:39.000000000 +0100
@@ -0,0 +1,95 @@
+#ifndef __ASM_SH_FAST_TIMER_H
+#define __ASM_SH_FAST_TIMER_H
+
+#include <linux/sched.h>
+#include <asm/io.h>
+
+#define FAST_POLL_INTR
+
+#define FASTTIMER_IRQ   17
+#define FASTTIMER_IPR_ADDR  INTC_IPRA
+#define FASTTIMER_IPR_POS    2
+#define FASTTIMER_PRIORITY   3
+
+#ifdef FAST_POLL_INTR
+#define TMU1_TCR_INIT	0x0020
+#else
+#define TMU1_TCR_INIT	0
+#endif
+#define TMU_TSTR_INIT	1
+#define TMU1_TCR_CALIB	0x0000
+#define TMU_TOCR	0xffd80000	/* Byte access */
+#define TMU_TSTR	0xffd80004	/* Byte access */
+#define TMU1_TCOR	0xffd80014	/* Long access */
+#define TMU1_TCNT	0xffd80018	/* Long access */
+#define TMU1_TCR	0xffd8001c	/* Word access */
+
+static void fast_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long timer_status;
+
+	timer_status = ctrl_inw(TMU1_TCR);
+	timer_status &= ~0x100;
+	ctrl_outw(timer_status, TMU1_TCR);
+
+	do_fast_timer();
+}
+
+static void fast_timer_set(void)
+{
+	unsigned long interval;
+
+#ifdef FAST_POLL_INTR
+	interval = (current_cpu_data.module_clock/4 + fast_timer_rate/2) / fast_timer_rate;
+#else
+	interval = 0xffffffff;
+#endif
+
+	ctrl_outb(ctrl_inb(TMU_TSTR) & ~0x2, TMU_TSTR); /* disable timer 1 */
+	ctrl_outw(TMU1_TCR_INIT, TMU1_TCR);
+	ctrl_outl(interval, TMU1_TCOR);
+	ctrl_outl(interval, TMU1_TCNT);
+	ctrl_outb(ctrl_inb(TMU_TSTR) | 0x2, TMU_TSTR); /* enable timer 1 */
+}
+
+static int __init fast_timer_setup(void)
+{
+#ifdef FAST_POLL_INTR
+	make_ipr_irq(FASTTIMER_IRQ, FASTTIMER_IPR_ADDR, FASTTIMER_IPR_POS,
+			FASTTIMER_PRIORITY);
+
+	if (request_irq(FASTTIMER_IRQ, fast_timer_interrupt, SA_INTERRUPT,
+			"fast timer", NULL))
+		return -EBUSY;
+#endif
+
+	fast_timer_rate = cpu_data->type == CPU_SH7751R ? 2000 : 1000;
+	fast_timer_set();
+
+#ifdef FAST_POLL_INTR
+	printk("fast timer: %d Hz, IRQ %d\n", fast_timer_rate,
+			FASTTIMER_IRQ);
+#else
+	printk("fast timer: %d Hz\n", fast_timer_rate);
+#endif
+	return 0;
+}
+
+static void __exit fast_timer_cleanup(void)
+{
+	ctrl_outb(ctrl_inb(TMU_TSTR) & ~0x2, TMU_TSTR); /* disable timer 1 */
+	free_irq(FASTTIMER_IRQ, NULL);
+}
+
+#if 0
+/*
+ * return the current ticks on the fast timer
+ */
+
+unsigned long fast_timer_count(void)
+{
+	return(ctrl_inl(TMU1_TCNT));
+}
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-sh/hitachi_keywest.h linux-2.4.29-uc1/include/asm-sh/hitachi_keywest.h
--- linux-2.4.29/include/asm-sh/hitachi_keywest.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/hitachi_keywest.h	2005-06-14 02:11:39.000000000 +0100
@@ -0,0 +1,138 @@
+#ifndef __ASM_SH_HITACHI_KEYWEST_H
+#define __ASM_SH_HITACHI_KEYWEST_H
+
+#ifndef CONFIG_SH_TAHOE
+#define CONFIG_SH_TAHOE 1
+/* for hiword interrupts of FPGA Interrupt controller */
+#if 0
+#define FPGA_HIWORD_IRQ            (15 - 7)
+#define FPGA_HIWORD_IRQBASE 48
+#endif
+#if defined(CONFIG_SH_TAHOE)
+
+/* for HD64465 INTC */
+#define HD64465_IOBASE  0xb0000000
+//#define HD64465_IRQBASE         64
+#define HD64465_IRQBASE         80
+//debug
+//#define HD64465_IRQ     (15 - 3)
+//#define HD64465_PCC0_IRQ (HD64465_IRQBASE + 16)
+//#define HD64465_PCC1_IRQ (HD64465_IRQBASE + 17)
+
+#if !defined(CONFIG_SH_MQ200)
+#define CONFIG_SH_MQ200 1
+#endif
+#define MQ200_IOBASE 0xb2000000
+//#define MQ200_IRQ    13
+#define MQ200_IRQ    34
+
+#endif
+#if 0
+#define CMDREG    0xa4040000 /* FPGA Command Register */
+#define STSREG    0xa4040010 /* FPGA Status Register */
+#define SWRST     0xa4040020 /* FPGA System Reset Regster */
+#define SYSLED    0xa4040030 /* FPGA System LED Register */
+#define PCIBMP    0xa4040040 /* FPGA PCI Base Map Address Register */
+#define DATECD    0xa4040050 /* FPGA Date Code Register */
+#define IMASK     0xa4040060 /* FPGA Interrupt Mask Regster */
+#define ISTAT     0xa4040070 /* FPGA Interrupt Status Register */
+
+#define IDEREG    0xa4050100 /* IDE Control Mask Register */
+
+#define HPLED0    0xa4010060 /* FPGA HP LED Registers */
+#define HPLED1    0xa4010064
+#define HPLED2    0xa4010068
+#define HPLED3    0xa401006C
+#define HPLED4    0xa4010070
+#define HPLED5    0xa4010074
+#define HPLED6    0xa4010078
+#define HPLED7    0xa401007C
+
+#define PPDATA    0xa4020000
+#define PPCTRL    0xa4020008
+
+#define IDE_IOBASE  0xa4050FC0
+#define IDE_01F0  (IDE_IOBASE+0)
+#define IDE_01F1  (IDE_IOBASE+4)
+#define IDE_01F2  (IDE_IOBASE+8)
+#define IDE_01F3  (IDE_IOBASE+12)
+
+#define IDE_01F4  (IDE_IOBASE+16)
+#define IDE_01F5  (IDE_IOBASE+20)
+#define IDE_01F6  (IDE_IOBASE+24)
+#define IDE_01F7  (IDE_IOBASE+28)
+#define IDE_03F6  0xa40507D8
+#endif
+//#define SMSC_BASE 0xa4400300
+#define SMSC_BASE 0xb1fe0000
+
+#define CMDREG_DBDTR   0x80000000 /* DBG-DTR of RS232 CN1 (1:on) */
+#define CMDREG_DDT     0x08000000 /* DDT DMA Mode (1:on) */
+#define CMDREG_RSTLAN  0x00200000 /* Reset SMSCI (1:reset) */
+#define CMDREG_RSTPCI  0x00000010 /* Reset PCI (1:reset) */
+#define CMDREG_FLWP    0x00000001 /* Flash write protect (1:off) */
+
+#define STSREG_DBDST   0x00000400 /* DBG-DSR from RS232 CN1 */
+#define STSREG_DBGCD   0x00000200 /* DBG-CD  from RS232 CN1 */
+#define STSREG_DBGRI   0x00000100 /* DBG-RI  from RS232 CN1 */
+#define STSREG_S1_MASK 0x0000000F
+
+#define SYSLED_OFF     0x00000001
+#define SYSLED_0N      0x00000000
+
+#define PCIBMP_AC32    0x00000000 /* 32bit */
+#define PCIBMP_AC16    0x00000100 /* 16bit */
+#define PCIBMP_AC8     0x00001000 /* 8bit */
+
+#define IMASK_APCI9S   0x00800000 /* AutoPCI9 */
+#define IMASK_APCI8S   0x00400000 /* AutoPCI8 */
+#define IMASK_APCI7S   0x00200000 /* AutoPCI7 */
+#define IMASK_APCI6S   0x00100000 /* AutoPCI6 */
+#define IMASK_APCI5S   0x00080000 /* AutoPCI5 */
+#define IMASK_APCI4S   0x00040000 /* AutoPCI4 */
+#define IMASK_APCI3S   0x00020000 /* AutoPCI3 */
+#define IMASK_APCI2S   0x00010000 /* AutoPCI2 */
+#define IMASK_IPCIDS   0x00008000 /* PCI Power supplu degrade  */
+#define IMASK_IPCIES   0x00004000 /* PCI ENUM# */
+#define IMASK_ILANS    0x00002000 /* SMSC Ethernet */
+#define IMASK_IV3S     0x00000800 /* V3 */
+#define IMASK_IV3TS    0x00000400 /* V3 timeout */
+#define IMASK_IPCISS   0x00000200 /* PCI party error */
+#define IMASK_APCIS    0x00000080 /* AutoPCI */
+#define IMASK_IIDES    0x00000020 /* IDE */
+#define IMASK_IIOS     0x00000010 /* Expansion IO */
+#define IMASK_IRS65S   0x00000008 /* HD64465 */
+#define IMASK_IRS64S   0x00000004 /* HD64464 LCD/CRT */
+#define IMASK_IRS2S    0x00000002 /* Ring Indicator from RS232 CN1 */
+
+#define ISTAT_APCI9S   0x00800000
+#define ISTAT_APCI8S   0x00400000
+#define ISTAT_APCI7S   0x00200000
+#define ISTAT_APCI6S   0x00100000
+#define ISTAT_APCI5S   0x00080000
+#define ISTAT_APCI4S   0x00040000
+#define ISTAT_APCI3S   0x00020000
+#define ISTAT_APCI2S   0x00010000
+#define ISTAT_IPCIDS   0x00008000
+#define ISTAT_IPCIES   0x00004000
+#define ISTAT_ILANS    0x00002000
+#define ISTAT_IV3S     0x00000800
+#define ISTAT_IV3TS    0x00000400
+#define ISTAT_IPCISS   0x00000200
+#define ISTAT_APCIS    0x00000080
+#define ISTAT_IIDES    0x00000020
+#define ISTAT_IIOS     0x00000010
+#define ISTAT_IRS65S   0x00000008
+#define ISTAT_IRS64S   0x00000004
+#define ISTAT_IRS2S    0x00000002
+
+//#if defined(__KERNEL__)
+//void SysLED(int);
+//void HpLED_set(int, int);
+//void HpLED_puts(const char*);
+//void HpLED_printf(const char*, ...);
+//#endif
+
+#endif
+
+#endif
diff -urN linux-2.4.29/include/asm-sh/hitachi_se.h linux-2.4.29-uc1/include/asm-sh/hitachi_se.h
--- linux-2.4.29/include/asm-sh/hitachi_se.h	2001-07-02 21:56:40.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/hitachi_se.h	2005-06-14 02:11:39.000000000 +0100
@@ -33,10 +33,17 @@
 #define PA_83902_RST	0xb0080000	/* DP83902A reset port */
 
 #define PA_SUPERIO	0xb0400000	/* SMC37C935A super io chip */
+#if defined(CONFIG_CPU_SUBTYPE_SH7751)
+#define PA_DIPSW0  0xb9000000  /* Dip switch 5,6 */
+#define PA_DIPSW1  0xb9000002  /* Dip switch 7,8 */
+#define PA_LED     0xba000000  /* LED */
+#define PA_BCR          0xbb000000      /* FPGA for SE7751 */
+#else
 #define PA_DIPSW0	0xb0800000	/* Dip switch 5,6 */
 #define PA_DIPSW1	0xb0800002	/* Dip switch 7,8 */
 #define PA_LED		0xb0c00000	/* LED */
 #define PA_BCR		0xb1400000	/* FPGA */
+#endif
 
 #define PA_MRSHPC	0xb83fffe0	/* MR-SHPC-01 PCMCIA controller */
 #define PA_MRSHPC_MW1	0xb8400000	/* MR-SHPC-01 memory window base */
diff -urN linux-2.4.29/include/asm-sh/hw_irq.h linux-2.4.29-uc1/include/asm-sh/hw_irq.h
--- linux-2.4.29/include/asm-sh/hw_irq.h	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/hw_irq.h	2005-06-14 02:11:39.000000000 +0100
@@ -1,4 +1,5 @@
 #ifndef __ASM_SH_HW_IRQ_H
 #define __ASM_SH_HW_IRQ_H
 static __inline__ void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) { /* Nothing to do */ }
+
 #endif /* __ASM_SH_HW_IRQ_H */
diff -urN linux-2.4.29/include/asm-sh/io_bigsur.h linux-2.4.29-uc1/include/asm-sh/io_bigsur.h
--- linux-2.4.29/include/asm-sh/io_bigsur.h	2001-06-27 21:55:29.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/io_bigsur.h	2005-06-14 02:11:39.000000000 +0100
@@ -49,6 +49,8 @@
 /* Map a range of ports to a range of kernel virtual memory. */
 extern void bigsur_port_map(u32 baseport, u32 nports, u32 addr, u8 shift);
 extern void bigsur_port_unmap(u32 baseport, u32 nports);
+#define mach_port_map bigsur_port_map
+#define mach_port_unmap bigsur_port_unmap
 
 #endif /* _ASM_SH_IO_BIGSUR_H */
 
diff -urN linux-2.4.29/include/asm-sh/io.h linux-2.4.29-uc1/include/asm-sh/io.h
--- linux-2.4.29/include/asm-sh/io.h	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-sh/io.h	2005-06-14 02:11:39.000000000 +0100
@@ -125,6 +125,8 @@
 #  include <asm/io_cat68701.h>
 # elif defined(CONFIG_SH_BIGSUR)
 #  include <asm/io_bigsur.h>
+# elif defined(CONFIG_SH_KEYWEST)
+#  include <asm/io_keywest.h>
 # elif defined(CONFIG_SH_HS7729PCI)
 #  include <asm/io_hs7729pci.h>
 # elif defined(CONFIG_SH_7751_SOLUTION_ENGINE)
diff -urN linux-2.4.29/include/asm-sh/io_hd64465.h linux-2.4.29-uc1/include/asm-sh/io_hd64465.h
--- linux-2.4.29/include/asm-sh/io_hd64465.h	2001-04-12 05:24:52.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/io_hd64465.h	2005-06-14 02:11:39.000000000 +0100
@@ -48,6 +48,8 @@
 extern void hd64465_port_map(unsigned short baseport, unsigned int nports,
 			     unsigned long addr, unsigned char shift);
 extern void hd64465_port_unmap(unsigned short baseport, unsigned int nports);
+#define mach_port_map hd64465_port_map
+#define mach_port_unmap hd64465_port_unmap
 
 
 #ifdef __WANT_IO_DEF
diff -urN linux-2.4.29/include/asm-sh/io_snapgear.h linux-2.4.29-uc1/include/asm-sh/io_snapgear.h
--- linux-2.4.29/include/asm-sh/io_snapgear.h	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/io_snapgear.h	2005-06-14 02:11:39.000000000 +0100
@@ -128,6 +128,7 @@
  * D10        -                      RTC SCLK
  * D11        RTC DATA               RTC DATA
  * D12        -                      RTS RESET
+ * D13        -                      DMZ
  */
 
  #define SECUREEDGE_IOPORT_ADDR ((volatile short *) 0xb0000000)
diff -urN linux-2.4.29/include/asm-sh/irq.h linux-2.4.29-uc1/include/asm-sh/irq.h
--- linux-2.4.29/include/asm-sh/irq.h	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-sh/irq.h	2005-06-14 02:11:39.000000000 +0100
@@ -157,7 +157,7 @@
 #else
 # if defined(CONFIG_HD64461)
 #  define OFFCHIP_NR_IRQS 16
-# elif defined (CONFIG_SH_BIGSUR) /* must be before CONFIG_HD64465 */
+# elif defined (CONFIG_SH_BIGSUR) || defined(CONFIG_SH_KEYWEST) /* must be before CONFIG_HD64465 */
 #  define OFFCHIP_NR_IRQS 48
 # elif defined(CONFIG_HD64465)
 #  define OFFCHIP_NR_IRQS 16
@@ -327,6 +327,11 @@
 extern int bigsur_irq_demux(int irq);
 #define irq_demux(irq) bigsur_irq_demux(irq)
 
+#elif defined(CONFIG_SH_KEYWEST)
+
+extern int keywest_irq_demux(int irq);
+#define irq_demux(irq) keywest_irq_demux(irq)
+
 #elif defined(CONFIG_HD64461)
 
 extern int hd64461_irq_demux(int irq);
diff -urN linux-2.4.29/include/asm-sh/keyboard.h linux-2.4.29-uc1/include/asm-sh/keyboard.h
--- linux-2.4.29/include/asm-sh/keyboard.h	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/keyboard.h	2005-06-14 02:11:39.000000000 +0100
@@ -8,6 +8,10 @@
 #include <linux/config.h>
 #include <asm/machvec.h>
 
+#ifdef CONFIG_SH_KEYWEST
+#include <asm/keyboard_keywest.h>
+#endif
+
 #ifdef CONFIG_SH_EC3104
 #include <asm/keyboard-ec3104.h>
 #elif defined(CONFIG_SH_HS7729PCI)
diff -urN linux-2.4.29/include/asm-sh/keyboard_keywest.h linux-2.4.29-uc1/include/asm-sh/keyboard_keywest.h
--- linux-2.4.29/include/asm-sh/keyboard_keywest.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/keyboard_keywest.h	2005-06-14 02:11:39.000000000 +0100
@@ -0,0 +1,76 @@
+#ifndef __ASM_SH_KEYBOARD_KEYWEST_H
+#define __ASM_SH_KEYBOARD_KEYWEST_H
+
+#ifdef __KERNEL__
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+#ifdef CONFIG_SH_KEYWEST
+#include <asm/hitachi_keywest.h>
+#endif
+#ifdef CONFIG_SH_HD64465
+#include <asm/hd64465.h>
+#endif
+
+#ifdef  CONFIG_SH_HD64465
+#define KEYBOARD_IRQ (HD64465_IRQBASE+15)
+#define AUX_IRQ      (HD64465_IRQBASE+7)
+#else
+#define KEYBOARD_IRQ 1
+#define AUX_IRQ      12
+#endif
+
+#define DISABLE_KBD_DURING_INTERRUPTS 0
+
+extern int  pckbd_setkeycode(unsigned int, unsigned int);
+extern int  pckbd_getkeycode(unsigned int);
+extern int  pckbd_translate(unsigned char, unsigned char*, char);
+extern char pckbd_unexpected_up(unsigned char);
+extern void pckbd_leds(unsigned char);
+extern void pckbd_init_hw(void);
+extern unsigned char pckbd_sysrq_xlate[128];
+
+#define kbd_setkeycode    pckbd_setkeycode
+#define kbd_getkeycode    pckbd_getkeycode
+#define kbd_translate     pckbd_translate
+#define kbd_unexpected_up pckbd_unexpected_up
+#define kbd_leds          pckbd_leds
+#define kbd_init_hw       pckbd_init_hw
+#define kbd_sysrq_xlate   pckbd_sysrq_xlate
+
+#define kbd_request_region()
+
+#define kbd_request_irq(handler) \
+  request_irq(KEYBOARD_IRQ, handler, 0, "keyboard", NULL)
+
+#ifdef CONFIG_SH_HD64465
+#define kbd_read_input()       inw(KBD_DATA_REG)
+#define kbd_read_status()      inw(KBD_STATUS_REG)
+#define kbd_write_output(val)  outw(val, KBD_DATA_REG)
+#define kbd_write_command(val) do { } while(0)
+#define kbd_clear_status()     outw(0x0001, KBD_STATUS_REG)
+#define aux_read_input()       inw(AUX_DATA_REG)
+#define aux_read_status()      inw(AUX_STATUS_REG)
+#define aux_write_output(val)  outw(val, AUX_DATA_REG)
+#define aux_clear_status()     outw(0x0001, AUX_STATUS_REG)
+#else
+#define kbd_read_input()       inb(KBD_DATA_REG)
+#define kbd_read_status()      inb(KBD_STATUS_REG)
+#define kbd_write_output(val)  outb(val, KBD_DATA_REG)
+#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
+#endif
+
+#define kbd_pause() do { } while(0)
+
+#define aux_request_irq(hand, dev_id) \
+  request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id)
+#define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id)
+
+#define SYSRQ_KEY 0x54
+
+#endif /* __KERNEL__ */
+
+#endif
+
+
diff -urN linux-2.4.29/include/asm-sh/keywest.h linux-2.4.29-uc1/include/asm-sh/keywest.h
--- linux-2.4.29/include/asm-sh/keywest.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/keywest.h	2005-06-14 02:11:39.000000000 +0100
@@ -0,0 +1,58 @@
+/*
+ * include/asm/keywest.h
+ *
+ * Hitachi KeyWest Platform support 
+ *
+ * Copyright (C) 2001 Lineo, Japan
+ *
+ * This file is subject to the terms and conditions of the GNU General Publi
+c
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#ifndef _ASM_KEYWEST_H_
+#define _ASM_KEYWEST_H_
+
+#include <asm/irq.h>
+#include <asm/hd64465.h>
+
+/* 7751 Internal IRQ's used by external CPLD controller */
+#define KEYWEST_IRQ_LOW	0
+#define KEYWEST_IRQ_NUM  14         /* External CPLD level 1 IRQs */
+#define KEYWEST_IRQ_HIGH (KEYWEST_IRQ_LOW + KEYWEST_IRQ_NUM)
+#define KEYWEST_2NDLVL_IRQ_LOW   (HD64465_IRQ_BASE+HD64465_IRQ_NUM)  
+#define KEYWEST_2NDLVL_IRQ_NUM   32 /* Level 2 IRQs = 4 regs * 8 bits */
+#define KEYWEST_2NDLVL_IRQ_HIGH  (KEYWEST_2NDLVL_IRQ_LOW + \
+                                 KEYWEST_2NDLVL_IRQ_NUM)
+
+
+/* CPLD registers and external chip addresses */
+//#define KEYWEST_HD64464_ADDR	0xB2000000
+#define KEYWEST_DGDR	0xB1FFE000
+#define KEYWEST_BIDR	0xB1FFD000
+#define KEYWEST_CSLR	0xB1FFC000
+#define KEYWEST_SW1R	0xB1FFB000
+#define KEYWEST_DBGR	0xB1FFA000
+#define KEYWEST_BDTR	0xB1FF9000
+#define KEYWEST_BDRR	0xB1FF8000
+#define KEYWEST_ETHR    0xB1FE0000
+
+#define KEYWEST_V320USC_ADDR  0xB1000000
+#define KEYWEST_HD64465_ADDR  0xB0000000
+#define KEYWEST_INTERNAL_BASE 0xB0000000
+
+/* SMC ethernet card parameters */
+//#define KEYWEST_ETHER_IOPORT		0x220
+#define KEYWEST_ETHER_IOPORT		0x0
+
+/* IDE register paramters */
+#define KEYWEST_IDECMD_IOPORT	0x1f0
+#define KEYWEST_IDECTL_IOPORT	0x1f8
+
+/* PCI: default LOCAL memory window sizes (seen from PCI bus) */
+#define KEYWEST_LSR0_SIZE    (64*(1<<20)) //64MB
+#define KEYWEST_LSR1_SIZE    (64*(1<<20)) //64MB
+
+#endif /* _ASM_KEYWEST_H_ */
diff -urN linux-2.4.29/include/asm-sh/kmap_types.h linux-2.4.29-uc1/include/asm-sh/kmap_types.h
--- linux-2.4.29/include/asm-sh/kmap_types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/kmap_types.h	2005-06-14 02:11:39.000000000 +0100
@@ -0,0 +1,16 @@
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+enum km_type {
+	KM_BOUNCE_READ,
+	KM_SKB_SUNRPC_DATA,
+	KM_SKB_DATA_SOFTIRQ,
+	KM_USER0,
+	KM_USER1,
+	KM_BH_IRQ,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
+	KM_TYPE_NR
+};
+
+#endif
diff -urN linux-2.4.29/include/asm-sh/machvec.h linux-2.4.29-uc1/include/asm-sh/machvec.h
--- linux-2.4.29/include/asm-sh/machvec.h	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-sh/machvec.h	2005-06-14 02:11:39.000000000 +0100
@@ -99,6 +99,7 @@
 #define MACH_SH2000	(sh_mv.mv_hw_sh2000)
 #define MACH_DREAMCAST	(sh_mv.mv_hw_dreamcast)
 #define MACH_BIGSUR	(sh_mv.mv_hw_bigsur)
+#define MACH_KEYWEST	(sh_mv.mv_hw_keywest)
 #define MACH_HS7729PCI	(sh_mv.mv_hw_hs7729pci)
 #define MACH_7751SE	(sh_mv.mv_hw_7751se)
 #define MACH_ADX	(sh_mv.mv_hw_adx)
@@ -170,6 +171,11 @@
 # else
 #  define MACH_BIGSUR		0
 # endif
+# ifdef CONFIG_SH_KEYWEST
+#  define MACH_KEYWEST		1
+# else
+#  define MACH_KEYWEST		0
+# endif
 # ifdef CONFIG_SH_HS7729PCI
 #  define MACH_HS7729PCI	1
 # else
diff -urN linux-2.4.29/include/asm-sh/pci.h linux-2.4.29-uc1/include/asm-sh/pci.h
--- linux-2.4.29/include/asm-sh/pci.h	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-sh/pci.h	2005-06-14 02:11:39.000000000 +0100
@@ -1,6 +1,8 @@
 #ifndef __ASM_SH_PCI_H
 #define __ASM_SH_PCI_H
 
+#include <linux/config.h>
+
 #ifdef __KERNEL__
 
 #include <linux/config.h>
@@ -20,6 +22,15 @@
 #define PCIBIOS_MIN_IO		0x2000
 #define PCIBIOS_MIN_MEM		0x10000000
 
+#elif defined(CONFIG_SH_KEYWEST)
+
+#define PCIBIOS_MIN_IO		0x2000
+#ifndef CONFIG_PCMCIA
+#define PCIBIOS_MIN_MEM		0xb8000000
+#else
+#define PCIBIOS_MIN_MEM		0xab000000
+#endif
+
 #elif defined(CONFIG_SH_DREAMCAST)
 #define PCIBIOS_MIN_IO		0x2000
 #define PCIBIOS_MIN_MEM		0x10000000
diff -urN linux-2.4.29/include/asm-sh/pgalloc.h linux-2.4.29-uc1/include/asm-sh/pgalloc.h
--- linux-2.4.29/include/asm-sh/pgalloc.h	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/pgalloc.h	2005-06-14 02:11:39.000000000 +0100
@@ -43,7 +43,7 @@
 
 static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
 {
-	return 0;
+	return (pte_t *) 0;
 }
 
 static inline void pte_free_slow(pte_t *pte)
diff -urN linux-2.4.29/include/asm-sh/pgtable.h linux-2.4.29-uc1/include/asm-sh/pgtable.h
--- linux-2.4.29/include/asm-sh/pgtable.h	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/pgtable.h	2005-06-14 02:11:39.000000000 +0100
@@ -32,6 +32,13 @@
  *
  *  Caches are indexed (effectively) by physical address on SH-3, so
  *  we don't need them.
+ *
+ *  DAVIDM: we do,  specifically bus mastering PCI controllers !
+ *          so that we don't cripple the SH3 with cache flushing,
+ *          we implment a special flush for sh3 to use in the pci
+ *          mapping functions.  Even though you can fic pci_alloc_consistent,
+ *          you cannot (and don't want to) have all skbuffs allocated from
+ *          uncached memory !
  */
 #define flush_cache_all()			do { } while (0)
 #define flush_cache_mm(mm)			do { } while (0)
@@ -43,35 +50,14 @@
 #define flush_icache_page(vma,pg)		do { } while (0)
 #define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
 #define flush_cache_sigtramp(vaddr)		do { } while (0)
-#define __flush_icache_all()			do { } while (0)
+#define flush_icache_all()			do { } while (0)
 
 #define p3_cache_init()				do { } while (0)
 
 #elif defined(__SH4__)
-/*
- *  Caches are broken on SH-4, so we need them.
- */
-
-/* Page is 4K, OC size is 16K, there are four lines. */
-#define CACHE_ALIAS 0x00003000
-
-extern void flush_cache_all(void);
-extern void flush_cache_mm(struct mm_struct *mm);
-extern void flush_cache_range(struct mm_struct *mm, unsigned long start,
-			      unsigned long end);
-extern void flush_cache_page(struct vm_area_struct *vma, unsigned long addr);
-extern void flush_dcache_page(struct page *pg);
-extern void flush_icache_range(unsigned long start, unsigned long end);
-extern void flush_cache_sigtramp(unsigned long addr);
-
-#define flush_page_to_ram(page)			do { } while (0)
-#define flush_icache_page(vma,pg)		do { } while (0)
-#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
-
-/* Initialization of P3 area for copy_user_page */
-extern void p3_cache_init(void);
 
-#define PG_mapped	PG_arch_1
+#include <asm/cache.h>
+#include <asm/cacheflush.h>
 
 /* We provide our own get_unmapped_area to avoid cache alias issue */
 #define HAVE_ARCH_UNMAPPED_AREA
diff -urN linux-2.4.29/include/asm-sh/processor.h linux-2.4.29-uc1/include/asm-sh/processor.h
--- linux-2.4.29/include/asm-sh/processor.h	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-sh/processor.h	2005-06-14 02:11:39.000000000 +0100
@@ -9,6 +9,7 @@
 
 #include <asm/page.h>
 #include <asm/types.h>
+#include <asm/cache.h>
 #include <linux/threads.h>
 
 /*
@@ -17,15 +18,26 @@
  */
 #define current_text_addr() ({ void *pc; __asm__("mova	1f, %0\n1:":"=z" (pc)); pc; })
 
+/* Core Processor Version Register */
+#define CCN_PVR		0xff000030
+#define CCN_PRR		0xff000044
+
 /*
  *  CPU type and hardware bug flags. Kept separately for each CPU.
  */
 enum cpu_type {
+	CPU_SH7300,		/* Represents 7300 (SH-Mobile) */
+	CPU_SH7604,		/* Represents 7604 */
 	CPU_SH7708,		/* Represents 7707, 7708, 7708S, 7708R, 7709 */
 	CPU_SH7729,		/* Represents 7709A, 7729 */
-	CPU_SH7750,             /* Represents 7750, 7751 */
-	CPU_ST40,		/* Represents ST40STB1 and ST40GX1 */
-        CPU_SH4202,
+	CPU_SH7750,     	/* Represents 7750 */
+	CPU_SH7750S,		/* Represents 7750S */
+	CPU_SH7750R,		/* Represents 7750R */
+	CPU_SH7751,		/* Represents 7751 */
+	CPU_SH7751R,		/* Represents 7751R */
+	CPU_ST40RA,		/* Represents ST40RA (formerly ST40STB1) */
+	CPU_ST40GX1,		/* Represents ST40GX1 */
+    CPU_SH4202,
 	CPU_SH_NONE
 };
 
@@ -38,6 +50,11 @@
 #ifdef CONFIG_CPU_SUBTYPE_ST40
 	unsigned int memory_clock;
 #endif
+
+	struct cache_info icache;
+	struct cache_info dcache;
+
+	unsigned long flags;
 };
 
 extern struct sh_cpuinfo boot_cpu_data;
@@ -100,6 +117,14 @@
 	struct sh_fpu_soft_struct soft;
 };
 
+/* 
+ * Processor flags
+ */
+
+#define CPU_HAS_FPU		0x0001	/* Hardware FPU support */
+#define CPU_HAS_P2_FLUSH_BUG	0x0002	/* Need to flush the cache in P2 area */
+#define CPU_HAS_MMU_PAGE_ASSOC	0x0004	/* SH3: TLB way selection bit support */
+
 struct thread_struct {
 	unsigned long sp;
 	unsigned long pc;
diff -urN linux-2.4.29/include/asm-sh/ptrace.h linux-2.4.29-uc1/include/asm-sh/ptrace.h
--- linux-2.4.29/include/asm-sh/ptrace.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-sh/ptrace.h	2005-06-14 02:11:39.000000000 +0100
@@ -91,6 +91,7 @@
 
 #ifdef __KERNEL__
 #define user_mode(regs) (((regs)->sr & 0x40000000)==0)
+#define user_stack(regs) ((regs)->regs[15])
 #define instruction_pointer(regs) ((regs)->pc)
 extern void show_regs(struct pt_regs *);
 #endif
diff -urN linux-2.4.29/include/asm-sh/segment.h linux-2.4.29-uc1/include/asm-sh/segment.h
--- linux-2.4.29/include/asm-sh/segment.h	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/segment.h	2005-06-14 02:11:39.000000000 +0100
@@ -1,6 +1,6 @@
-#ifndef _ASM_SH_SEGMENT_H
-#define _ASM_SH_SEGMENT_H
+#ifndef _ASM_SEGMENT_H
+#define _ASM_SEGMENT_H
 
 /* Only here because we have some old header files that expect it.. */
 
-#endif /* _ASM_SH_SEGMENT_H */
+#endif /* _ASM_SEGMENT_H */
diff -urN linux-2.4.29/include/asm-sh/serial.h linux-2.4.29-uc1/include/asm-sh/serial.h
--- linux-2.4.29/include/asm-sh/serial.h	2001-06-27 21:55:29.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/serial.h	2005-06-14 02:11:39.000000000 +0100
@@ -14,6 +14,8 @@
 #include <asm/serial-ec3104.h>
 #elif defined (CONFIG_SH_BIGSUR)
 #include <asm/serial-bigsur.h>
+#elif defined (CONFIG_SH_KEYWEST)
+#include <asm/serial-keywest.h>
 #else
 /*
  * This assumes you have a 1.8432 MHz clock for your UART.
diff -urN linux-2.4.29/include/asm-sh/serial-keywest.h linux-2.4.29-uc1/include/asm-sh/serial-keywest.h
--- linux-2.4.29/include/asm-sh/serial-keywest.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/serial-keywest.h	2005-06-14 02:11:39.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ * include/asm-sh/serial-keywest.h
+ *
+ * Configuration details for keywest 16550 based serial ports 
+ * i.e. HD64465, PCMCIA, etc.
+ */
+
+#ifndef _ASM_SERIAL_KEYWEST_H
+#define _ASM_SERIAL_KEYWEST_H
+#include <asm/hd64465.h>
+
+#define BASE_BAUD (3379200 / 16)
+
+/* Leave 2 spare for possible PCMCIA serial cards */
+#define RS_TABLE_SIZE  3
+
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+
+#define STD_SERIAL_PORT_DEFNS                   \
+        /* UART CLK   PORT IRQ     FLAGS        */                      \
+        { 0, BASE_BAUD, 0x3F8, HD64465_IRQ_UART, STD_COM_FLAGS } /* ttyS0 */ 
+
+
+#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS
+
+/* XXX: This should be moved ino irq.h */
+#define irq_cannonicalize(x) (x)
+
+#endif /* _ASM_SERIAL_KEYWEST_H */
diff -urN linux-2.4.29/include/asm-sh/setup.h linux-2.4.29-uc1/include/asm-sh/setup.h
--- linux-2.4.29/include/asm-sh/setup.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/setup.h	2005-06-14 02:11:39.000000000 +0100
@@ -0,0 +1 @@
+/* nothing needed here */
diff -urN linux-2.4.29/include/asm-sh/uaccess.h linux-2.4.29-uc1/include/asm-sh/uaccess.h
--- linux-2.4.29/include/asm-sh/uaccess.h	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sh/uaccess.h	2005-06-14 02:11:39.000000000 +0100
@@ -98,6 +98,7 @@
 case 1: __get_user_asm("b"); break; \
 case 2: __get_user_asm("w"); break; \
 case 4: __get_user_asm("l"); break; \
+case 8: __copy_user(&__gu_val, ptr, size); break; \
 default: __get_user_unknown(); break; \
 } x = (__typeof__(*(ptr))) __gu_val; __gu_err; })
 
@@ -112,6 +113,7 @@
 case 1: __get_user_asm("b"); break; \
 case 2: __get_user_asm("w"); break; \
 case 4: __get_user_asm("l"); break; \
+case 8: __copy_user(&__gu_val, ptr, size); break; \
 default: __get_user_unknown(); break; \
 } } x = (__typeof__(*(ptr))) __gu_val; __gu_err; })
 
diff -urN linux-2.4.29/include/asm-sparc/div64.h linux-2.4.29-uc1/include/asm-sparc/div64.h
--- linux-2.4.29/include/asm-sparc/div64.h	1999-12-21 06:05:52.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-sparc/div64.h	2005-06-14 02:11:31.000000000 +0100
@@ -1,11 +1 @@
-#ifndef __SPARC_DIV64
-#define __SPARC_DIV64
-
-/* We're not 64-bit, but... */
-#define do_div(n,base) ({ \
-	int __res; \
-	__res = ((unsigned long) n) % (unsigned) base; \
-	n = ((unsigned long) n) / (unsigned) base; \
-	__res; })
-
-#endif /* __SPARC_DIV64 */
+#include <asm-generic/div64.h>
diff -urN linux-2.4.29/include/asm-sparc64/div64.h linux-2.4.29-uc1/include/asm-sparc64/div64.h
--- linux-2.4.29/include/asm-sparc64/div64.h	1999-12-21 06:05:52.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-sparc64/div64.h	2005-06-14 02:11:32.000000000 +0100
@@ -1,14 +1 @@
-#ifndef __SPARC64_DIV64
-#define __SPARC64_DIV64
-
-/*
- * Hey, we're already 64-bit, no
- * need to play games..
- */
-#define do_div(n,base) ({ \
-	int __res; \
-	__res = ((unsigned long) n) % (unsigned) base; \
-	n = ((unsigned long) n) / (unsigned) base; \
-	__res; })
-
-#endif /* __SPARC64_DIV64 */
+#include <asm-generic/div64.h>
diff -urN linux-2.4.29/include/asm-sparcnommu/flat.h linux-2.4.29-uc1/include/asm-sparcnommu/flat.h
--- linux-2.4.29/include/asm-sparcnommu/flat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-sparcnommu/flat.h	2005-06-14 02:11:32.000000000 +0100
@@ -0,0 +1,58 @@
+/*
+ * include/asm-sparcnommu/flat.h -- uClinux flat-format executables
+ */
+
+#ifndef __SPARCNOMMU_FLAT_H__
+#define __SPARCNOMMU_FLAT_H__
+
+/*
+ * Sparc requires stacks to start on 8byte boundary
+ */
+
+#define	flat_stack_align(sp)		\
+	(sp) = (unsigned long *) (((unsigned long) (sp)) & 0xfffffff8); \
+	--sp; put_user(0,--sp)
+
+#define flat_argvp_envp_on_stack()	0
+#define	flat_old_ram_flag(flags)	(flags)
+#define	flat_reloc_valid(reloc, size)	((reloc) <= (size))
+
+/*
+ * For SPARC architecture we need to handle the funky HI22 and LO10
+ * addressing modes. The relocations occur inside of an instruction,
+ * and so we need to preserve the instruction bits but also perform
+ * the relocation on the address component.
+ */
+
+static inline unsigned long
+flat_get_relocate_addr(unsigned long rel)
+{
+	return(rel & 0x3fffffff);
+}
+
+static inline unsigned long
+flat_get_addr_from_rp(unsigned long *rp, unsigned long relval, unsigned long flags)
+{
+	unsigned long addr = get_unaligned (rp);
+	(void)flags;
+	if (relval & 0x80000000)
+		addr &= 0x003fffff;
+	else if (relval & 0x40000000)
+		addr &= 0x000003ff;
+	return(addr);
+}
+
+static inline unsigned long
+flat_put_addr_at_rp(unsigned long *rp,unsigned long addr,unsigned long relval)
+{
+	if (relval & 0xC0000000) {
+		unsigned long old_val = get_unaligned (rp);
+		if (relval & 0x80000000)
+			addr = (old_val & 0xffc00000) | (addr >> 10);
+		else
+			addr = (old_val & 0xfffffc00) | (addr & 0x3ff);
+	}
+	put_unaligned (addr, rp);
+}
+
+#endif /* __SPARCNOMMU_FLAT_H__ */
diff -urN linux-2.4.29/include/asm-v850/anna.h linux-2.4.29-uc1/include/asm-v850/anna.h
--- linux-2.4.29/include/asm-v850/anna.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/anna.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,144 @@
+/*
+ * include/asm-v850/anna.h -- Anna V850E2 evaluation cpu chip/board
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_ANNA_H__
+#define __V850_ANNA_H__
+
+#include <asm/v850e2.h>		/* Based on V850E2 core.  */
+
+
+#define CPU_MODEL	"v850e2/anna"
+#define CPU_MODEL_LONG	"NEC V850E2/Anna"
+#define PLATFORM	"anna"
+#define PLATFORM_LONG	"NEC/Midas lab V850E2/Anna evaluation board"
+
+#define CPU_CLOCK_FREQ	200000000 /*  200MHz */
+#define SYS_CLOCK_FREQ	 33300000 /* 33.3MHz */
+#define FIXED_BOGOMIPS	79.66	  /* Only valid for 2.4.x */
+
+
+/* 1MB of static RAM.  This memory is mirrored 64 times.  */
+#define SRAM_ADDR	0x04000000
+#define SRAM_SIZE	0x00100000 /* 1MB */
+/* 64MB of DRAM.  */
+#define SDRAM_ADDR	0x08000000	
+#define SDRAM_SIZE	0x04000000 /* 64MB */
+
+
+/* For <asm/page.h> */
+#define PAGE_OFFSET 	SRAM_ADDR
+
+/* We use on-chip RAM, for a few miscellaneous variables that must be
+   accessible using a load instruction relative to R0.  The Anna chip has
+   128K of `dLB' ram nominally located at 0xFFF00000, but it's mirrored
+   every 128K, so we can use the `last mirror' (except for the portion at
+   the top which is overridden by I/O space).  In addition, the early
+   sample chip we're using has lots of memory errors in the dLB ram, so we
+   use a specially chosen location that has at least 20 bytes of contiguous
+   valid memory (xxxF0020 - xxxF003F).  */
+#define R0_RAM_ADDR			0xFFFF8020
+
+
+/* Anna specific control registers.  */
+#define ANNA_ILBEN_ADDR			0xFFFFF7F2
+#define ANNA_ILBEN			(*(volatile u16 *)ANNA_ILBEN_ADDR)
+
+
+/* I/O port P0-P3. */
+/* Direct I/O.  Bits 0-7 are pins Pn0-Pn7.  */
+#define ANNA_PORT_IO_ADDR(n)		(0xFFFFF400 + (n) * 2)
+#define ANNA_PORT_IO(n)			(*(volatile u8 *)ANNA_PORT_IO_ADDR(n))
+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
+#define ANNA_PORT_PM_ADDR(n)		(0xFFFFF410 + (n) * 2)
+#define ANNA_PORT_PM(n)			(*(volatile u8 *)ANNA_PORT_PM_ADDR(n))
+
+
+/* Hardware-specific interrupt numbers (in the kernel IRQ namespace).  */
+#define IRQ_INTP(n)	(n)	/* Pnnn (pin) interrupts 0-15 */
+#define IRQ_INTP_NUM	16
+#define IRQ_INTOV(n)	(0x10 + (n)) /* 0-2 */
+#define IRQ_INTOV_NUM	2
+#define IRQ_INTCCC(n)	(0x12 + (n))
+#define IRQ_INTCCC_NUM	4
+#define IRQ_INTCMD(n)	(0x16 + (n)) /* interval timer interrupts 0-5 */
+#define IRQ_INTCMD_NUM	6
+#define IRQ_INTDMA(n)	(0x1C + (n)) /* DMA interrupts 0-3 */
+#define IRQ_INTDMA_NUM	4
+#define IRQ_INTDMXER	0x20
+#define IRQ_INTSRE(n)	(0x21 + (n)*3) /* UART 0-1 reception error */
+#define IRQ_INTSRE_NUM	2
+#define IRQ_INTSR(n)	(0x22 + (n)*3) /* UART 0-1 reception completion */
+#define IRQ_INTSR_NUM	2
+#define IRQ_INTST(n)	(0x23 + (n)*3) /* UART 0-1 transmission completion */
+#define IRQ_INTST_NUM	2
+
+#define NUM_CPU_IRQS	64
+
+#ifndef __ASSEMBLY__
+/* Initialize chip interrupts.  */
+extern void anna_init_irqs (void);
+#endif
+
+
+/* Anna UART details (basically the same as the V850E/MA1, but 2 channels).  */
+#define V850E_UART_NUM_CHANNELS		2
+#define V850E_UART_BASE_FREQ		(SYS_CLOCK_FREQ / 2)
+#define V850E_UART_CHIP_NAME 		"V850E2/NA85E2A"
+
+/* This is the UART channel that's actually connected on the board.  */
+#define V850E_UART_CONSOLE_CHANNEL	1
+
+/* This is a function that gets called before configuring the UART.  */
+#define V850E_UART_PRE_CONFIGURE	anna_uart_pre_configure
+#ifndef __ASSEMBLY__
+extern void anna_uart_pre_configure (unsigned chan,
+				     unsigned cflags, unsigned baud);
+#endif
+
+/* This board supports RTS/CTS for the on-chip UART, but only for channel 1. */
+
+/* CTS for UART channel 1 is pin P37 (bit 7 of port 3).  */
+#define V850E_UART_CTS(chan)	((chan) == 1 ? !(ANNA_PORT_IO(3) & 0x80) : 1)
+/* RTS for UART channel 1 is pin P07 (bit 7 of port 0).  */
+#define V850E_UART_SET_RTS(chan, val)					      \
+   do {									      \
+	   if (chan == 1) {						      \
+		   unsigned old = ANNA_PORT_IO(0); 			      \
+		   if (val)						      \
+			   ANNA_PORT_IO(0) = old & ~0x80;		      \
+		   else							      \
+			   ANNA_PORT_IO(0) = old | 0x80;		      \
+	   }								      \
+   } while (0)
+
+
+/* Timer C details.  */
+#define V850E_TIMER_C_BASE_ADDR		0xFFFFF600
+
+/* Timer D details (the Anna actually has 5 of these; should change later). */
+#define V850E_TIMER_D_BASE_ADDR		0xFFFFF540
+#define V850E_TIMER_D_TMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x0)
+#define V850E_TIMER_D_CMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x2)
+#define V850E_TIMER_D_TMCD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x4)
+
+#define V850E_TIMER_D_BASE_FREQ		SYS_CLOCK_FREQ
+#define V850E_TIMER_D_TMCD_CS_MIN	1 /* min 2^1 divider */
+
+
+/* For <asm/param.h> */
+#ifndef HZ
+#define HZ	100
+#endif
+
+
+#endif /* __V850_ANNA_H__ */
diff -urN linux-2.4.29/include/asm-v850/a.out.h linux-2.4.29-uc1/include/asm-v850/a.out.h
--- linux-2.4.29/include/asm-v850/a.out.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/a.out.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,21 @@
+#ifndef __V850_A_OUT_H__
+#define __V850_A_OUT_H__
+
+struct exec
+{
+  unsigned long a_info;		/* Use macros N_MAGIC, etc for access */
+  unsigned a_text;		/* length of text, in bytes */
+  unsigned a_data;		/* length of data, in bytes */
+  unsigned a_bss;		/* length of uninitialized data area for file, in bytes */
+  unsigned a_syms;		/* length of symbol table data in file, in bytes */
+  unsigned a_entry;		/* start address */
+  unsigned a_trsize;		/* length of relocation info for text, in bytes */
+  unsigned a_drsize;		/* length of relocation info for data, in bytes */
+};
+
+#define N_TRSIZE(a)	((a).a_trsize)
+#define N_DRSIZE(a)	((a).a_drsize)
+#define N_SYMSIZE(a)	((a).a_syms)
+
+
+#endif /* __V850_A_OUT_H__ */
diff -urN linux-2.4.29/include/asm-v850/as85ep1.h linux-2.4.29-uc1/include/asm-v850/as85ep1.h
--- linux-2.4.29/include/asm-v850/as85ep1.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/as85ep1.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,158 @@
+/*
+ * include/asm-v850/as85ep1.h -- AS85EP1 evaluation CPU chip/board
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_AS85EP1_H__
+#define __V850_AS85EP1_H__
+
+#include <asm/v850e.h>
+
+
+#define CPU_MODEL	"as85ep1"
+#define CPU_MODEL_LONG	"NEC V850E/AS85EP1"
+#define PLATFORM	"AS85EP1"
+#define PLATFORM_LONG	"NEC V850E/AS85EP1 evaluation board"
+
+#define CPU_CLOCK_FREQ	96000000 /*  96MHz */
+#define SYS_CLOCK_FREQ	CPU_CLOCK_FREQ
+
+
+/* 1MB of static RAM.  */
+#define SRAM_ADDR	0x00400000
+#define SRAM_SIZE	0x00100000 /* 1MB */
+/* About 58MB of DRAM.  This can actually be at one of two positions,
+   determined by jump JP3; we have to use the first position because the
+   second is partially out of processor instruction addressing range
+   (though in the second position there's actually 64MB available).  */
+#define SDRAM_ADDR	0x00600000
+#define SDRAM_SIZE	0x039F8000 /* approx 58MB */
+
+/* For <asm/page.h> */
+#define PAGE_OFFSET 	SRAM_ADDR
+
+/* We use on-chip RAM, for a few miscellaneous variables that must be
+   accessible using a load instruction relative to R0.  The AS85EP1 chip
+   16K of internal RAM located slightly before I/O space.  */
+#define R0_RAM_ADDR	0xFFFF8000
+
+
+/* AS85EP1 specific control registers.  */
+#define AS85EP1_CSC_ADDR(n)	(0xFFFFF060 + (n) * 2)
+#define AS85EP1_CSC(n)		(*(volatile u16 *)AS85EP1_CSC_ADDR(n))
+#define AS85EP1_BSC_ADDR	0xFFFFF066
+#define AS85EP1_BSC		(*(volatile u16 *)AS85EP1_BSC_ADDR)
+#define AS85EP1_BCT_ADDR(n)	(0xFFFFF480 + (n) * 2)
+#define AS85EP1_BCT(n)		(*(volatile u16 *)AS85EP1_BCT_ADDR(n))
+#define AS85EP1_DWC_ADDR(n)	(0xFFFFF484 + (n) * 2)
+#define AS85EP1_DWC(n)		(*(volatile u16 *)AS85EP1_DWC_ADDR(n))
+#define AS85EP1_BCC_ADDR	0xFFFFF488
+#define AS85EP1_BCC		(*(volatile u16 *)AS85EP1_BCC_ADDR)
+#define AS85EP1_ASC_ADDR	0xFFFFF48A
+#define AS85EP1_ASC		(*(volatile u16 *)AS85EP1_ASC_ADDR)
+#define AS85EP1_BCP_ADDR	0xFFFFF48C
+#define AS85EP1_BCP		(*(volatile u16 *)AS85EP1_BCP_ADDR)
+#define AS85EP1_LBS_ADDR	0xFFFFF48E
+#define AS85EP1_LBS		(*(volatile u16 *)AS85EP1_LBS_ADDR)
+#define AS85EP1_BMC_ADDR	0xFFFFF498
+#define AS85EP1_BMC		(*(volatile u16 *)AS85EP1_BMC_ADDR)
+#define AS85EP1_PRC_ADDR	0xFFFFF49A
+#define AS85EP1_PRC		(*(volatile u16 *)AS85EP1_PRC_ADDR)
+#define AS85EP1_SCR_ADDR(n)	(0xFFFFF4A0 + (n) * 4)
+#define AS85EP1_SCR(n)		(*(volatile u16 *)AS85EP1_SCR_ADDR(n))
+#define AS85EP1_RFS_ADDR(n)	(0xFFFFF4A2 + (n) * 4)
+#define AS85EP1_RFS(n)		(*(volatile u16 *)AS85EP1_RFS_ADDR(n))
+#define AS85EP1_IRAMM_ADDR	0xFFFFF80A
+#define AS85EP1_IRAMM		(*(volatile u8 *)AS85EP1_IRAMM_ADDR)
+
+
+
+/* I/O port P0-P13. */
+/* Direct I/O.  Bits 0-7 are pins Pn0-Pn7.  */
+#define AS85EP1_PORT_IO_ADDR(n)	(0xFFFFF400 + (n) * 2)
+#define AS85EP1_PORT_IO(n)	(*(volatile u8 *)AS85EP1_PORT_IO_ADDR(n))
+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
+#define AS85EP1_PORT_PM_ADDR(n)	(0xFFFFF420 + (n) * 2)
+#define AS85EP1_PORT_PM(n)	(*(volatile u8 *)AS85EP1_PORT_PM_ADDR(n))
+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
+#define AS85EP1_PORT_PMC_ADDR(n) (0xFFFFF440 + (n) * 2)
+#define AS85EP1_PORT_PMC(n)	(*(volatile u8 *)AS85EP1_PORT_PMC_ADDR(n))
+
+
+/* Hardware-specific interrupt numbers (in the kernel IRQ namespace).  */
+#define IRQ_INTCCC(n)	(0x0C + (n))
+#define IRQ_INTCCC_NUM	8
+#define IRQ_INTCMD(n)	(0x14 + (n)) /* interval timer interrupts 0-5 */
+#define IRQ_INTCMD_NUM	6
+#define IRQ_INTSRE(n)	(0x1E + (n)*3) /* UART 0-1 reception error */
+#define IRQ_INTSRE_NUM	2
+#define IRQ_INTSR(n)	(0x1F + (n)*3) /* UART 0-1 reception completion */
+#define IRQ_INTSR_NUM	2
+#define IRQ_INTST(n)	(0x20 + (n)*3) /* UART 0-1 transmission completion */
+#define IRQ_INTST_NUM	2
+
+#define NUM_CPU_IRQS	64
+
+#ifndef __ASSEMBLY__
+/* Initialize chip interrupts.  */
+extern void as85ep1_init_irqs (void);
+#endif
+
+
+/* AS85EP1 UART details (basically the same as the V850E/MA1, but 2 channels).  */
+#define V850E_UART_NUM_CHANNELS		2
+#define V850E_UART_BASE_FREQ		(SYS_CLOCK_FREQ / 4)
+#define V850E_UART_CHIP_NAME 		"V850E/NA85E"
+
+/* This is a function that gets called before configuring the UART.  */
+#define V850E_UART_PRE_CONFIGURE	as85ep1_uart_pre_configure
+#ifndef __ASSEMBLY__
+extern void as85ep1_uart_pre_configure (unsigned chan,
+					unsigned cflags, unsigned baud);
+#endif
+
+/* This board supports RTS/CTS for the on-chip UART, but only for channel 1. */
+
+/* CTS for UART channel 1 is pin P54 (bit 4 of port 5).  */
+#define V850E_UART_CTS(chan)   ((chan) == 1 ? !(AS85EP1_PORT_IO(5) & 0x10) : 1)
+/* RTS for UART channel 1 is pin P53 (bit 3 of port 5).  */
+#define V850E_UART_SET_RTS(chan, val)					      \
+   do {									      \
+	   if (chan == 1) {						      \
+		   unsigned old = AS85EP1_PORT_IO(5); 			      \
+		   if (val)						      \
+			   AS85EP1_PORT_IO(5) = old & ~0x8;		      \
+		   else							      \
+			   AS85EP1_PORT_IO(5) = old | 0x8;		      \
+	   }								      \
+   } while (0)
+
+
+/* Timer C details.  */
+#define V850E_TIMER_C_BASE_ADDR		0xFFFFF600
+
+/* Timer D details (the AS85EP1 actually has 5 of these; should change later). */
+#define V850E_TIMER_D_BASE_ADDR		0xFFFFF540
+#define V850E_TIMER_D_TMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x0)
+#define V850E_TIMER_D_CMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x2)
+#define V850E_TIMER_D_TMCD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x4)
+
+#define V850E_TIMER_D_BASE_FREQ		SYS_CLOCK_FREQ
+#define V850E_TIMER_D_TMCD_CS_MIN	2 /* min 2^2 divider */
+
+
+/* For <asm/param.h> */
+#ifndef HZ
+#define HZ	100
+#endif
+
+
+#endif /* __V850_AS85EP1_H__ */
diff -urN linux-2.4.29/include/asm-v850/asm.h linux-2.4.29-uc1/include/asm-v850/asm.h
--- linux-2.4.29/include/asm-v850/asm.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/asm.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ * include/asm-v850/asm.h -- Macros for writing assembly code
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#define G_ENTRY(name)							      \
+   .balign 4;								      \
+   .globl name;								      \
+   .type  name,@function;						      \
+   name
+#define G_DATA(name)							      \
+   .globl name;								      \
+   .type  name,@object;							      \
+   name
+#define END(name)							      \
+   .size  name,.-name
+
+#define L_ENTRY(name)							      \
+   .balign 4;								      \
+   .type  name,@function;						      \
+   name
+#define L_DATA(name)							      \
+   .type  name,@object;							      \
+   name
diff -urN linux-2.4.29/include/asm-v850/atomic.h linux-2.4.29-uc1/include/asm-v850/atomic.h
--- linux-2.4.29/include/asm-v850/atomic.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/atomic.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,89 @@
+/*
+ * include/asm-v850/atomic.h -- Atomic operations
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_ATOMIC_H__
+#define __V850_ATOMIC_H__
+
+#include <linux/config.h>
+
+#include <asm/system.h>
+
+#ifdef CONFIG_SMP
+#error SMP not supported
+#endif
+
+typedef struct { int counter; } atomic_t;
+
+#define ATOMIC_INIT(i)	{ (i) }
+
+#ifdef __KERNEL__
+
+#define atomic_read(v)		((v)->counter)
+#define atomic_set(v,i)		(((v)->counter) = (i))
+
+extern __inline__ int atomic_add_return (int i, volatile atomic_t *v)
+{
+	unsigned long flags;
+	int res;
+
+	local_irq_save (flags);
+	res = v->counter + i;
+	v->counter = res;
+	local_irq_restore (flags);
+
+	return res;
+}
+
+static __inline__ int atomic_sub_return (int i, volatile atomic_t *v)
+{
+	unsigned long flags;
+	int res;
+
+	local_irq_save (flags);
+	res = v->counter - i;
+	v->counter = res;
+	local_irq_restore (flags);
+
+	return res;
+}
+
+static __inline__ void atomic_clear_mask (unsigned long mask, unsigned long *addr)
+{
+	unsigned long flags;
+
+	local_irq_save (flags);
+	*addr &= ~mask;
+	local_irq_restore (flags);
+}
+
+#endif
+
+#define atomic_add(i, v)	atomic_add_return ((i), (v))
+#define atomic_sub(i, v)	atomic_sub_return ((i), (v))
+
+#define atomic_dec_return(v)	atomic_sub_return (1, (v))
+#define atomic_inc_return(v)	atomic_add_return (1, (v))
+#define atomic_inc(v) 		atomic_inc_return (v)
+#define atomic_dec(v) 		atomic_dec_return (v)
+
+#define atomic_sub_and_test(i,v)	(atomic_sub_return ((i), (v)) == 0)
+#define atomic_dec_and_test(v)		(atomic_sub_return (1, (v)) == 0)
+#define atomic_add_negative(i,v)	(atomic_add_return ((i), (v)) < 0)
+
+/* Atomic operations are already serializing on ARM */
+#define smp_mb__before_atomic_dec()	barrier()
+#define smp_mb__after_atomic_dec()	barrier()
+#define smp_mb__before_atomic_inc()	barrier()
+#define smp_mb__after_atomic_inc()	barrier()
+
+#endif /* __V850_ATOMIC_H__ */
diff -urN linux-2.4.29/include/asm-v850/bitops.h linux-2.4.29-uc1/include/asm-v850/bitops.h
--- linux-2.4.29/include/asm-v850/bitops.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/bitops.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,219 @@
+/*
+ * include/asm-v850/bitops.h -- Bit operations
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 1992  Linus Torvalds.
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+#ifndef __V850_BITOPS_H__
+#define __V850_BITOPS_H__
+
+
+#include <linux/config.h>
+#include <linux/compiler.h>	/* unlikely  */
+#include <asm/byteorder.h>	/* swab32 */
+#include <asm/system.h>		/* interrupt enable/disable */
+
+
+#ifdef __KERNEL__
+
+/*
+ * The __ functions are not atomic
+ */
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+extern __inline__ unsigned long ffz (unsigned long word)
+{
+	unsigned long result = 0;
+
+	while (word & 1) {
+		result++;
+		word >>= 1;
+	}
+	return result;
+}
+
+
+/* In the following constant-bit-op macros, a "g" constraint is used when
+   we really need an integer ("i" constraint).  This is to avoid
+   warnings/errors from the compiler in the case where the associated
+   operand _isn't_ an integer, and shouldn't produce bogus assembly because
+   use of that form is protected by a guard statement that checks for
+   constants, and should otherwise be removed by the optimizer.  This
+   _usually_ works -- however, __builtin_constant_p returns true for a
+   variable with a known constant value too, and unfortunately gcc will
+   happily put the variable in a register and use the register for the "g"
+   constraint'd asm operand.  To avoid the latter problem, we add a
+   constant offset to the operand and subtract it back in the asm code;
+   forcing gcc to do arithmetic on the value is usually enough to get it
+   to use a real constant value.  This is horrible, and ultimately
+   unreliable too, but it seems to work for now (hopefully gcc will offer
+   us more control in the future, so we can do a better job).  */
+
+#define __const_bit_op(op, nr, addr)					\
+  ({ __asm__ (op " (%0 - 0x123), %1"					\
+	      :: "g" (((nr) & 0x7) + 0x123),				\
+		 "m" (*((char *)(addr) + ((nr) >> 3)))			\
+	      : "memory"); })
+#define __var_bit_op(op, nr, addr)					\
+  ({ int __nr = (nr);							\
+     __asm__ (op " %0, [%1]"						\
+	      :: "r" (__nr & 0x7),					\
+		 "r" ((char *)(addr) + (__nr >> 3))			\
+	      : "memory"); })
+#define __bit_op(op, nr, addr)						\
+  ((__builtin_constant_p (nr) && (unsigned)(nr) <= 0x7FFFF)		\
+   ? __const_bit_op (op, nr, addr)					\
+   : __var_bit_op (op, nr, addr))
+
+#define __set_bit(nr, addr)		__bit_op ("set1", nr, addr)
+#define __clear_bit(nr, addr)		__bit_op ("clr1", nr, addr)
+#define __change_bit(nr, addr)		__bit_op ("not1", nr, addr)
+
+/* The bit instructions used by `non-atomic' variants are actually atomic.  */
+#define set_bit __set_bit
+#define clear_bit __clear_bit
+#define change_bit __change_bit
+
+
+#define __const_tns_bit_op(op, nr, addr)				\
+  ({ int __tns_res;							\
+     __asm__ ("tst1 (%1 - 0x123), %2; setf nz, %0; " op " (%1 - 0x123), %2" \
+	      : "=&r" (__tns_res)					\
+	      : "g" (((nr) & 0x7) + 0x123),				\
+		"m" (*((char *)(addr) + ((nr) >> 3)))			\
+	      : "memory");						\
+     __tns_res;							\
+  })
+#define __var_tns_bit_op(op, nr, addr)					\
+  ({ int __nr = (nr);							\
+     int __tns_res;							\
+     __asm__ ("tst1 %1, [%2]; setf nz, %0; " op " %1, [%2]"		\
+	      : "=&r" (__tns_res)					\
+	      : "r" (__nr & 0x7),					\
+		"r" ((char *)(addr) + (__nr >> 3))			\
+	      : "memory");						\
+     __tns_res;							\
+  })
+#define __tns_bit_op(op, nr, addr)					\
+  ((__builtin_constant_p (nr) && (unsigned)(nr) <= 0x7FFFF)		\
+   ? __const_tns_bit_op (op, nr, addr)					\
+   : __var_tns_bit_op (op, nr, addr))
+#define __tns_atomic_bit_op(op, nr, addr)				\
+  ({ int __tns_atomic_res, __tns_atomic_flags;				\
+     local_irq_save (__tns_atomic_flags);				\
+     __tns_atomic_res = __tns_bit_op (op, nr, addr);			\
+     local_irq_restore (__tns_atomic_flags);				\
+     __tns_atomic_res;							\
+  })
+
+#define __test_and_set_bit(nr, addr)	__tns_bit_op ("set1", nr, addr)
+#define test_and_set_bit(nr, addr)	__tns_atomic_bit_op ("set1", nr, addr)
+
+#define __test_and_clear_bit(nr, addr)	__tns_bit_op ("clr1", nr, addr)
+#define test_and_clear_bit(nr, addr)	__tns_atomic_bit_op ("clr1", nr, addr)
+
+#define __test_and_change_bit(nr, addr)	__tns_bit_op ("not1", nr, addr)
+#define test_and_change_bit(nr, addr)	__tns_atomic_bit_op ("not1", nr, addr)
+
+
+#define __const_test_bit(nr, addr)					\
+  ({ int __test_bit_res;						\
+     __asm__ ("tst1 (%1 - 0x123), %2; setf nz, %0"			\
+	      : "=r" (__test_bit_res)					\
+	      : "g" (((nr) & 0x7) + 0x123),				\
+                "m" (*((const char *)(addr) + ((nr) >> 3))));		\
+     __test_bit_res;							\
+  })
+extern __inline__ int __test_bit (int nr, const void *addr)
+{
+	int res;
+	__asm__ ("tst1 %1, [%2]; setf nz, %0"
+		 : "=r" (res)
+		 : "r" (nr & 0x7), "r" (addr + (nr >> 3)));
+	return res;
+}
+#define test_bit(nr,addr)						\
+  ((__builtin_constant_p (nr) && (unsigned)(nr) <= 0x7FFFF)		\
+   ? __const_test_bit ((nr), (addr))					\
+   : __test_bit ((nr), (addr)))
+
+
+/* clear_bit doesn't provide any barrier for the compiler.  */
+#define smp_mb__before_clear_bit()	barrier ()
+#define smp_mb__after_clear_bit()	barrier ()
+
+
+#define find_first_zero_bit(addr, size) \
+  find_next_zero_bit ((addr), (size), 0)
+
+extern __inline__ int find_next_zero_bit (void *addr, int size, int offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if (offset) {
+		tmp = * (p++);
+		tmp |= ~0UL >> (32-offset);
+		if (size < 32)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while (size & ~31UL) {
+		if (~ (tmp = * (p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+ found_first:
+	tmp |= ~0UL >> size;
+ found_middle:
+	return result + ffz (tmp);
+}
+
+#define ffs(x) generic_ffs (x)
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+#define hweight32(x) 			generic_hweight32 (x)
+#define hweight16(x) 			generic_hweight16 (x)
+#define hweight8(x) 			generic_hweight8 (x)
+
+#define ext2_set_bit			test_and_set_bit
+#define ext2_clear_bit			test_and_clear_bit
+#define ext2_test_bit			test_bit
+#define ext2_find_first_zero_bit	find_first_zero_bit
+#define ext2_find_next_zero_bit		find_next_zero_bit
+
+/* Bitmap functions for the minix filesystem.  */
+#define minix_test_and_set_bit		test_and_set_bit
+#define minix_set_bit			set_bit
+#define minix_test_and_clear_bit	test_and_clear_bit
+#define minix_test_bit 			test_bit
+#define minix_find_first_zero_bit 	find_first_zero_bit
+
+#endif /* __KERNEL__ */
+
+#endif /* __V850_BITOPS_H__ */
diff -urN linux-2.4.29/include/asm-v850/blkmem.h linux-2.4.29-uc1/include/asm-v850/blkmem.h
--- linux-2.4.29/include/asm-v850/blkmem.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/blkmem.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,44 @@
+/*
+ * include/asm-v850/blkmem.h -- `blkmem' device configuration
+ *
+ *  Copyright (C) 2001,2002  NEC Corporation
+ *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_BLKMEM_H__
+#define __V850_BLKMEM_H__
+
+/* Look for a device specific memory array location.  */
+#include <asm/machdep.h>
+
+
+#ifndef FIXUP_ARENAS  /* provide a default */
+
+#ifndef ROOT_FS_IMAGE_RW
+#define ROOT_FS_IMAGE_RW	0 /* assume read-only */
+#endif
+
+/* For <asm/blkmem.h> */
+/* This gives us a single arena.  */
+#define CAT_ROMARRAY
+/* These should be defined by the linker map.  */
+extern char _root_fs_image_start, _root_fs_image_end;
+/* Make the single arena point use them.  */
+#define FIXUP_ARENAS							      \
+        arena[0].rw = ROOT_FS_IMAGE_RW;					      \
+	arena[0].address = (unsigned long)&_root_fs_image_start;	      \
+	arena[0].length = &_root_fs_image_end - &_root_fs_image_start;
+#endif /* FIXUP_ARENAS */
+
+
+/* Used by the blkmem flash programming code.  */
+#define HARD_RESET_NOW() __asm__ __volatile__ ("jmp r0")
+
+
+#endif /* __V850_BLKMEM_H__ */
diff -urN linux-2.4.29/include/asm-v850/bugs.h linux-2.4.29-uc1/include/asm-v850/bugs.h
--- linux-2.4.29/include/asm-v850/bugs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/bugs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,16 @@
+/*
+ *  include/asm-v850e/bugs.h
+ *
+ *  Copyright (C) 1994  Linus Torvalds
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *	void check_bugs(void);
+ */
+
+static void check_bugs(void)
+{
+}
diff -urN linux-2.4.29/include/asm-v850/byteorder.h linux-2.4.29-uc1/include/asm-v850/byteorder.h
--- linux-2.4.29/include/asm-v850/byteorder.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/byteorder.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,47 @@
+/*
+ * include/asm-v850/byteorder.h -- Endian id and conversion ops
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_BYTEORDER_H__
+#define __V850_BYTEORDER_H__
+
+#include <asm/types.h>
+
+#ifdef __GNUC__
+
+static __inline__ __const__ __u32 ___arch__swab32 (__u32 word)
+{
+	__u32 res;
+	__asm__ ("bsw %1, %0" : "=r" (res) : "r" (word));
+	return res;
+}
+
+static __inline__ __const__ __u16 ___arch__swab16 (__u16 half_word)
+{
+	__u16 res;
+	__asm__ ("bsh %1, %0" : "=r" (res) : "r" (half_word));
+	return res;
+}
+
+#define __arch__swab32(x) ___arch__swab32(x)
+#define __arch__swab16(x) ___arch__swab16(x)
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#endif /* __GNUC__ */
+
+#include <linux/byteorder/little_endian.h>
+
+#endif /* __V850_BYTEORDER_H__ */
diff -urN linux-2.4.29/include/asm-v850/cache.h linux-2.4.29-uc1/include/asm-v850/cache.h
--- linux-2.4.29/include/asm-v850/cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/cache.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ * include/asm-v850/cache.h -- Cache operations
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_CACHE_H__
+#define __V850_CACHE_H__
+
+/* All cache operations are machine-dependent.  */
+#include <asm/machdep.h>
+
+#ifndef L1_CACHE_BYTES
+/* This processor has no cache, so just choose an arbitrary value.  */
+#define L1_CACHE_BYTES		16
+#endif
+
+#endif /* __V850_CACHE_H__ */
diff -urN linux-2.4.29/include/asm-v850/checksum.h linux-2.4.29-uc1/include/asm-v850/checksum.h
--- linux-2.4.29/include/asm-v850/checksum.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/checksum.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,115 @@
+/*
+ * include/asm-v850/checksum.h -- Checksum ops
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_CHECKSUM_H__
+#define __V850_CHECKSUM_H__
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+extern unsigned int csum_partial (const unsigned char * buff, int len,
+				  unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+extern unsigned csum_partial_copy (const char *src, char *dst, int len,
+				   unsigned sum);
+
+
+/*
+ * the same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+extern unsigned csum_partial_copy_from_user (const char *src, char *dst,
+					     int len, unsigned sum,
+					     int *csum_err);
+
+#define csum_partial_copy_nocheck(src, dst, len, sum)	\
+	csum_partial_copy ((src), (dst), (len), (sum))
+
+unsigned short ip_fast_csum (unsigned char *iph, unsigned int ihl);
+
+/*
+ *	Fold a partial checksum
+ */
+static inline unsigned int csum_fold (unsigned long sum)
+{
+	unsigned int result;
+	/*
+			        %0		%1
+	      hsw %1, %0	H     L		L     H
+	      add %1, %0	H     L		H+L+C H+L
+	*/
+	asm ("hsw %1, %0; add %1, %0" : "=&r" (result) : "r" (sum));
+	return (~result) >> 16;
+}
+
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline unsigned int
+csum_tcpudp_nofold (unsigned long saddr, unsigned long daddr,
+		    unsigned short len,
+		    unsigned short proto, unsigned int sum)
+{
+	int __carry;
+	__asm__ ("add %2, %0;"
+		 "setf c, %1;"
+		 "add %1, %0;"
+		 "add %3, %0;"
+		 "setf c, %1;"
+		 "add %1, %0;"
+		 "add %4, %0;"
+		 "setf c, %1;"
+		 "add %1, %0"
+		 : "=&r" (sum), "=&r" (__carry)
+		 : "r" (daddr), "r" (saddr),
+		 "r" (ntohs (len) + (proto << 8)),
+		 "0" (sum));
+	return sum;
+}
+
+static inline unsigned short int
+csum_tcpudp_magic (unsigned long saddr, unsigned long daddr,
+		   unsigned short len,
+		   unsigned short proto, unsigned int sum)
+{
+	return csum_fold (csum_tcpudp_nofold (saddr, daddr, len, proto, sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+extern unsigned short ip_compute_csum (const unsigned char * buff, int len);
+
+
+#endif /* __V850_CHECKSUM_H__ */
diff -urN linux-2.4.29/include/asm-v850/clinkage.h linux-2.4.29-uc1/include/asm-v850/clinkage.h
--- linux-2.4.29/include/asm-v850/clinkage.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/clinkage.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,26 @@
+/*
+ * include/asm-v850/clinkage.h -- Macros to reflect C symbol-naming conventions
+ *
+ *  Copyright (C) 2001,02  NEC Corporatione
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __CLINKAGE_H__
+#define __V850_CLINKAGE_H__
+
+#include <asm/macrology.h>
+#include <asm/asm.h>
+
+#define C_SYMBOL_NAME(name) 	macrology_paste(_, name)
+#define C_SYMBOL_STRING(name)	macrology_stringify(C_SYMBOL_NAME(name))
+#define C_ENTRY(name)		G_ENTRY(C_SYMBOL_NAME(name))
+#define C_DATA(name)		G_DATA(C_SYMBOL_NAME(name))
+#define C_END(name)		END(C_SYMBOL_NAME(name))
+
+#endif /* __V850_CLINKAGE_H__ */
diff -urN linux-2.4.29/include/asm-v850/current.h linux-2.4.29-uc1/include/asm-v850/current.h
--- linux-2.4.29/include/asm-v850/current.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/current.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,59 @@
+/*
+ * include/asm-v850/current.h -- Current task
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_CURRENT_H__
+#define __V850_CURRENT_H__
+
+#include <asm/macrology.h>
+
+
+/* The size allocated for kernel stacks.  This _must_ be a power of two!  */
+#define KERNEL_STACK_SIZE	0x2000
+
+
+/* Register used to hold the current task pointer while in the kernel.
+   Any `call clobbered' register without a special meaning should be OK,
+   but check asm/v850/kernel/entry.S to be sure.  */
+#define CURRENT_TASK_REGNUM	16
+#define CURRENT_TASK 		macrology_paste (r, CURRENT_TASK_REGNUM)
+
+
+/* The alignment of kernel stacks, with task structures at their base.
+   Thus, a pointer for a task's task structure can be derived from its
+   kernel stack pointer.  */
+#define CURRENT_TASK_ALIGNMENT	KERNEL_STACK_SIZE
+#define CURRENT_TASK_MASK	(-CURRENT_TASK_ALIGNMENT)
+
+
+#ifdef __ASSEMBLY__
+
+/* Put a pointer to the current task structure into REG.  Note that this
+   definition requires CURRENT_TASK_MASK to be representable as a
+   signed 16-bit value.  */
+#define GET_CURRENT_TASK(reg)						      \
+        /* Use `addi' and then `and' instead of just `andi', because	      \
+	   `addi' sign-extends the immediate value, whereas `andi'	      \
+	   zero-extends it.  */						      \
+	addi	CURRENT_TASK_MASK, r0, reg;				      \
+	and	sp, reg
+
+#else /* !__ASSEMBLY__ */
+
+/* A pointer to the current task.  */
+register struct task_struct *current					      \
+   __asm__ (macrology_stringify (CURRENT_TASK));
+
+#endif /* __ASSEMBLY__ */
+
+
+#endif /* _V850_CURRENT_H */
diff -urN linux-2.4.29/include/asm-v850/delay.h linux-2.4.29-uc1/include/asm-v850/delay.h
--- linux-2.4.29/include/asm-v850/delay.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/delay.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,48 @@
+/*
+ * include/asm-v850/delay.h -- Delay routines, using a pre-computed
+ * 	"loops_per_second" value
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 1994 Hamish Macdonald
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+#ifndef __V850_DELAY_H__
+#define __V850_DELAY_H__
+
+#include <asm/param.h>
+
+extern __inline__ void __delay(unsigned long loops)
+{
+	__asm__ __volatile__ ("1: add -1, %0; bnz 1b"
+			      : "=r" (loops) : "0" (loops));
+}
+
+/*
+ * Use only for very small delays ( < 1 msec).  Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays.  This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)  
+ */
+
+extern unsigned long loops_per_jiffy;
+
+extern __inline__ void udelay(unsigned long usecs)
+{
+	register unsigned long full_loops, part_loops;
+
+	full_loops = ((usecs * HZ) / 1000000) * loops_per_jiffy;
+	usecs %= (1000000 / HZ);
+	part_loops = (usecs * HZ * loops_per_jiffy) / 1000000;
+
+	__delay(full_loops + part_loops);
+}
+
+#define ndelay(nsecs) udelay((nsecs) * 5)
+
+#endif /* __V850_DELAY_H__ */
diff -urN linux-2.4.29/include/asm-v850/div64.h linux-2.4.29-uc1/include/asm-v850/div64.h
--- linux-2.4.29/include/asm-v850/div64.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/div64.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-generic/div64.h>
diff -urN linux-2.4.29/include/asm-v850/dma.h linux-2.4.29-uc1/include/asm-v850/dma.h
--- linux-2.4.29/include/asm-v850/dma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/dma.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,18 @@
+#ifndef __V850_DMA_H__
+#define __V850_DMA_H__
+
+/* What should this be?  */
+#define MAX_DMA_ADDRESS	0xFFFFFFFF
+
+/* reserve a DMA channel */
+extern int request_dma (unsigned int dmanr, const char * device_id);
+/* release it again */
+extern void free_dma (unsigned int dmanr);
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy    (0)
+#endif
+
+#endif /* __V850_DMA_H__ */
diff -urN linux-2.4.29/include/asm-v850/elf.h linux-2.4.29-uc1/include/asm-v850/elf.h
--- linux-2.4.29/include/asm-v850/elf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/elf.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,101 @@
+#ifndef __V850_ELF_H__
+#define __V850_ELF_H__
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+#include <asm/byteorder.h>
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_fpu_struct elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x)  \
+  ((x)->e_machine == EM_V850 || (x)->e_machine == EM_CYGNUS_V850)
+
+
+/* v850 relocation types.  */
+#define R_V850_NONE		0
+#define R_V850_9_PCREL		1
+#define R_V850_22_PCREL		2
+#define R_V850_HI16_S		3
+#define R_V850_HI16		4
+#define R_V850_LO16		5
+#define R_V850_32		6
+#define R_V850_16		7
+#define R_V850_8		8
+#define R_V850_SDA_16_16_OFFSET	9	/* For ld.b, st.b, set1, clr1,
+					   not1, tst1, movea, movhi */
+#define R_V850_SDA_15_16_OFFSET	10	/* For ld.w, ld.h, ld.hu, st.w, st.h */
+#define R_V850_ZDA_16_16_OFFSET	11	/* For ld.b, st.b, set1, clr1,
+					   not1, tst1, movea, movhi */
+#define R_V850_ZDA_15_16_OFFSET	12	/* For ld.w, ld.h, ld.hu, st.w, st.h */
+#define R_V850_TDA_6_8_OFFSET	13	/* For sst.w, sld.w */
+#define R_V850_TDA_7_8_OFFSET	14	/* For sst.h, sld.h */
+#define R_V850_TDA_7_7_OFFSET	15	/* For sst.b, sld.b */
+#define R_V850_TDA_16_16_OFFSET	16	/* For set1, clr1, not1, tst1,
+					   movea, movhi */
+#define R_V850_NUM		17
+
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#ifdef __LITTLE_ENDIAN__
+#define ELF_DATA	ELFDATA2LSB
+#else
+#define ELF_DATA	ELFDATA2MSB
+#endif
+#define ELF_ARCH	EM_V850
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	4096
+
+
+#define ELF_CORE_COPY_REGS(_dest,_regs)				\
+	memcpy((char *) &_dest, (char *) _regs,			\
+	       sizeof(struct pt_regs));
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this CPU supports.  This could be done in user space,
+   but it's not easy, and we've already done it here.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.
+
+   For the moment, we have only optimizations for the Intel generations,
+   but that could change... */
+
+#define ELF_PLATFORM  (NULL)
+
+#define ELF_PLAT_INIT(_r, load_addr)					      \
+  do {									      \
+	 _r->gpr[0] =  _r->gpr[1] =  _r->gpr[2] =  _r->gpr[3] =		      \
+	 _r->gpr[4] =  _r->gpr[5] =  _r->gpr[6] =  _r->gpr[7] =		      \
+	 _r->gpr[8] =  _r->gpr[9] = _r->gpr[10] = _r->gpr[11] =		      \
+	_r->gpr[12] = _r->gpr[13] = _r->gpr[14] = _r->gpr[15] =		      \
+	_r->gpr[16] = _r->gpr[17] = _r->gpr[18] = _r->gpr[19] =		      \
+	_r->gpr[20] = _r->gpr[21] = _r->gpr[22] = _r->gpr[23] =		      \
+	_r->gpr[24] = _r->gpr[25] = _r->gpr[26] = _r->gpr[27] =		      \
+	_r->gpr[28] = _r->gpr[29] = _r->gpr[30] = _r->gpr[31] =		      \
+	0;								      \
+  } while (0)
+
+#ifdef __KERNEL__
+#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+#endif
+
+#endif /* __V850_ELF_H__ */
diff -urN linux-2.4.29/include/asm-v850/entry.h linux-2.4.29-uc1/include/asm-v850/entry.h
--- linux-2.4.29/include/asm-v850/entry.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/entry.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,113 @@
+/*
+ * include/asm-v850/entry.h -- Definitions used by low-level trap handlers
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_ENTRY_H__
+#define __V850_ENTRY_H__
+
+
+#include <asm/ptrace.h>
+#include <asm/machdep.h>
+
+
+/* These are special variables using by the kernel trap/interrupt code
+   to save registers in, at a time when there are no spare registers we
+   can use to do so, and we can't depend on the value of the stack
+   pointer.  This means that they must be within a signed 16-bit
+   displacement of 0x00000000.  */
+
+#define KERNEL_VAR_SPACE_ADDR	R0_RAM_ADDR
+
+#ifdef __ASSEMBLY__
+#define KERNEL_VAR(addr)	addr[r0]
+#else
+#define KERNEL_VAR(addr)	(*(volatile unsigned long *)(addr))
+#endif
+
+/* Kernel stack pointer, 4 bytes.  */
+#define KSP_ADDR		(KERNEL_VAR_SPACE_ADDR +  0)
+#define KSP			KERNEL_VAR (KSP_ADDR)
+/* 1 if in kernel-mode, 0 if in user mode, 1 byte.  */
+#define KM_ADDR 		(KERNEL_VAR_SPACE_ADDR +  4)
+#define KM			KERNEL_VAR (KM_ADDR)
+/* Temporary storage for interrupt handlers, 4 bytes.  */
+#define INT_SCRATCH_ADDR	(KERNEL_VAR_SPACE_ADDR +  8)
+#define INT_SCRATCH		KERNEL_VAR (INT_SCRATCH_ADDR)
+/* Where the stack-pointer is saved when jumping to various sorts of
+   interrupt handlers.  ENTRY_SP is used by everything except NMIs,
+   which have their own location.  Higher-priority NMIs can clobber the
+   value written by a lower priority NMI, since they can't be disabled,
+   but that's OK, because only NMI0 (the lowest-priority one) is allowed
+   to return.  */
+#define ENTRY_SP_ADDR		(KERNEL_VAR_SPACE_ADDR + 12)
+#define ENTRY_SP		KERNEL_VAR (ENTRY_SP_ADDR)
+#define NMI_ENTRY_SP_ADDR	(KERNEL_VAR_SPACE_ADDR + 16)
+#define NMI_ENTRY_SP		KERNEL_VAR (NMI_ENTRY_SP_ADDR)
+
+#ifdef CONFIG_RESET_GUARD
+/* Used to detect unexpected resets (since the v850 has no MMU, any call
+   through a null pointer will jump to the reset vector).  We detect
+   such resets by checking for a magic value, RESET_GUARD_ACTIVE, in
+   this location.  Properly resetting the machine stores zero there, so
+   it shouldn't trigger the guard; the power-on value is uncertain, but
+   it's unlikely to be RESET_GUARD_ACTIVE.  */
+#define RESET_GUARD_ADDR	(KERNEL_VAR_SPACE_ADDR + 28)
+#define RESET_GUARD		KERNEL_VAR (RESET_GUARD_ADDR)
+#define RESET_GUARD_ACTIVE	0xFAB4BEEF
+#endif /* CONFIG_RESET_GUARD */
+
+#ifdef CONFIG_V850E_HIGHRES_TIMER
+#define HIGHRES_TIMER_SLOW_TICKS_ADDR (KERNEL_VAR_SPACE_ADDR + 32)
+#define HIGHRES_TIMER_SLOW_TICKS     KERNEL_VAR (HIGHRES_TIMER_SLOW_TICKS_ADDR)
+#endif /* CONFIG_V850E_HIGHRES_TIMER */
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_RESET_GUARD
+/* Turn off reset guard, so that resetting the machine works normally.
+   This should be called in the various machine_halt, etc., functions.  */
+static inline void disable_reset_guard (void)
+{
+	RESET_GUARD = 0;
+}
+#endif /* CONFIG_RESET_GUARD */
+
+#endif /* !__ASSEMBLY__ */
+
+
+/* A `state save frame' is a struct pt_regs preceded by some extra space
+   suitable for a function call stack frame.  */
+
+/* Amount of room on the stack reserved for arguments and to satisfy the
+   C calling conventions, in addition to the space used by the struct
+   pt_regs that actually holds saved values.  */
+#define STATE_SAVE_ARG_SPACE	(6*4) /* Up to six arguments.  */
+
+
+#ifdef __ASSEMBLY__
+
+/* The size of a state save frame.  */
+#define STATE_SAVE_SIZE		(PT_SIZE + STATE_SAVE_ARG_SPACE)
+
+#else /* !__ASSEMBLY__ */
+
+/* The size of a state save frame.  */
+#define STATE_SAVE_SIZE	       (sizeof (struct pt_regs) + STATE_SAVE_ARG_SPACE)
+
+#endif /* __ASSEMBLY__ */
+
+
+/* Offset of the struct pt_regs in a state save frame.  */
+#define STATE_SAVE_PT_OFFSET	STATE_SAVE_ARG_SPACE
+
+
+#endif /* __V850_ENTRY_H__ */
diff -urN linux-2.4.29/include/asm-v850/errno.h linux-2.4.29-uc1/include/asm-v850/errno.h
--- linux-2.4.29/include/asm-v850/errno.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/errno.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,132 @@
+#ifndef __V850_ERRNO_H__
+#define __V850_ERRNO_H__
+
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Arg list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	EDEADLK		35	/* Resource deadlock would occur */
+#define	ENAMETOOLONG	36	/* File name too long */
+#define	ENOLCK		37	/* No record locks available */
+#define	ENOSYS		38	/* Function not implemented */
+#define	ENOTEMPTY	39	/* Directory not empty */
+#define	ELOOP		40	/* Too many symbolic links encountered */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	ENOMSG		42	/* No message of desired type */
+#define	EIDRM		43	/* Identifier removed */
+#define	ECHRNG		44	/* Channel number out of range */
+#define	EL2NSYNC	45	/* Level 2 not synchronized */
+#define	EL3HLT		46	/* Level 3 halted */
+#define	EL3RST		47	/* Level 3 reset */
+#define	ELNRNG		48	/* Link number out of range */
+#define	EUNATCH		49	/* Protocol driver not attached */
+#define	ENOCSI		50	/* No CSI structure available */
+#define	EL2HLT		51	/* Level 2 halted */
+#define	EBADE		52	/* Invalid exchange */
+#define	EBADR		53	/* Invalid request descriptor */
+#define	EXFULL		54	/* Exchange full */
+#define	ENOANO		55	/* No anode */
+#define	EBADRQC		56	/* Invalid request code */
+#define	EBADSLT		57	/* Invalid slot */
+
+#define	EDEADLOCK	EDEADLK
+
+#define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
+#define	EMULTIHOP	72	/* Multihop attempted */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EBADMSG		74	/* Not a data message */
+#define	EOVERFLOW	75	/* Value too large for defined data type */
+#define	ENOTUNIQ	76	/* Name not unique on network */
+#define	EBADFD		77	/* File descriptor in bad state */
+#define	EREMCHG		78	/* Remote address changed */
+#define	ELIBACC		79	/* Can not access a needed shared library */
+#define	ELIBBAD		80	/* Accessing a corrupted shared library */
+#define	ELIBSCN		81	/* .lib section in a.out corrupted */
+#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	EILSEQ		84	/* Illegal byte sequence */
+#define	ERESTART	85	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUSERS		87	/* Too many users */
+#define	ENOTSOCK	88	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	89	/* Destination address required */
+#define	EMSGSIZE	90	/* Message too long */
+#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	92	/* Protocol not available */
+#define	EPROTONOSUPPORT	93	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
+#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	96	/* Protocol family not supported */
+#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
+#define	EADDRINUSE	98	/* Address already in use */
+#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
+#define	ENETDOWN	100	/* Network is down */
+#define	ENETUNREACH	101	/* Network is unreachable */
+#define	ENETRESET	102	/* Network dropped connection because of reset */
+#define	ECONNABORTED	103	/* Software caused connection abort */
+#define	ECONNRESET	104	/* Connection reset by peer */
+#define	ENOBUFS		105	/* No buffer space available */
+#define	EISCONN		106	/* Transport endpoint is already connected */
+#define	ENOTCONN	107	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
+#define	ETIMEDOUT	110	/* Connection timed out */
+#define	ECONNREFUSED	111	/* Connection refused */
+#define	EHOSTDOWN	112	/* Host is down */
+#define	EHOSTUNREACH	113	/* No route to host */
+#define	EALREADY	114	/* Operation already in progress */
+#define	EINPROGRESS	115	/* Operation now in progress */
+#define	ESTALE		116	/* Stale NFS file handle */
+#define	EUCLEAN		117	/* Structure needs cleaning */
+#define	ENOTNAM		118	/* Not a XENIX named type file */
+#define	ENAVAIL		119	/* No XENIX semaphores available */
+#define	EISNAM		120	/* Is a named type file */
+#define	EREMOTEIO	121	/* Remote I/O error */
+#define	EDQUOT		122	/* Quota exceeded */
+
+#define	ENOMEDIUM	123	/* No medium found */
+#define	EMEDIUMTYPE	124	/* Wrong medium type */
+
+#endif /* __V850_ERRNO_H__ */
diff -urN linux-2.4.29/include/asm-v850/fcntl.h linux-2.4.29-uc1/include/asm-v850/fcntl.h
--- linux-2.4.29/include/asm-v850/fcntl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/fcntl.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,86 @@
+#ifndef __V850_FCNTL_H__
+#define __V850_FCNTL_H__
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	  0003
+#define O_RDONLY	    00
+#define O_WRONLY	    01
+#define O_RDWR		    02
+#define O_CREAT		  0100	/* not fcntl */
+#define O_EXCL		  0200	/* not fcntl */
+#define O_NOCTTY	  0400	/* not fcntl */
+#define O_TRUNC		 01000	/* not fcntl */
+#define O_APPEND	 02000
+#define O_NONBLOCK	 04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC		010000
+#define FASYNC		020000	/* fcntl, for BSD compatibility */
+#define O_DIRECTORY	040000	/* must be a directory */
+#define O_NOFOLLOW     0100000	/* don't follow links */
+#define O_DIRECT       0200000	/* direct disk access hint - currently ignored */
+#define O_LARGEFILE    0400000
+
+#define F_DUPFD		0	/* dup */
+#define F_GETFD		1	/* get close_on_exec */
+#define F_SETFD		2	/* set/clear close_on_exec */
+#define F_GETFL		3	/* get file->f_flags */
+#define F_SETFL		4	/* set file->f_flags */
+#define F_GETLK		5
+#define F_SETLK		6
+#define F_SETLKW	7
+
+#define F_SETOWN	8	/*  for sockets. */
+#define F_GETOWN	9	/*  for sockets. */
+#define F_SETSIG	10	/*  for sockets. */
+#define F_GETSIG	11	/*  for sockets. */
+
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK		0
+#define F_WRLCK		1
+#define F_UNLCK		2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+/* for leases */
+#define F_INPROGRESS	16
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* or'd with one of the above to prevent
+				   blocking */
+#define LOCK_UN		8	/* remove lock */
+
+#define LOCK_MAND	32	/* This is a mandatory flock */
+#define LOCK_READ	64	/* ... Which allows concurrent read operations */
+#define LOCK_WRITE	128	/* ... Which allows concurrent write operations */
+#define LOCK_RW		192	/* ... Which allows concurrent read & write ops */
+
+struct flock {
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE	1024
+#endif /* __V850_FCNTL_H__ */
diff -urN linux-2.4.29/include/asm-v850/flat.h linux-2.4.29-uc1/include/asm-v850/flat.h
--- linux-2.4.29/include/asm-v850/flat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/flat.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,132 @@
+/*
+ * include/asm-v850/flat.h -- uClinux flat-format executables
+ *
+ *  Copyright (C) 2002,03  NEC Electronics Corporation
+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_FLAT_H__
+#define __V850_FLAT_H__
+
+/* The amount by which a relocation can exceed the program image limits
+   without being regarded as an error.  On the v850, the relocations of
+   some base-pointers can be offset by 0x8000 (to allow better usage of the
+   space offered by 16-bit signed offsets -- in most cases the offsets used
+   with such a base-pointer will be negative).  */
+
+#define	flat_reloc_valid(reloc, size)	((reloc) <= (size + 0x8000))
+
+#define	flat_stack_align(sp)		/* nothing needed */
+#define	flat_argvp_envp_on_stack()	0
+#define	flat_old_ram_flag(flags)	(flags)
+
+/* We store the type of relocation in the top 4 bits of the `relval.' */
+
+/* Convert a relocation entry into an address.  */
+static inline unsigned long
+flat_get_relocate_addr (unsigned long relval)
+{
+	return relval & 0x0fffffff; /* Mask out top 4-bits */
+}
+
+#define flat_v850_get_reloc_type(relval) ((relval) >> 28)
+
+#define FLAT_V850_R_32		0 /* Normal 32-bit reloc */
+#define FLAT_V850_R_HI16S_LO15	1 /* High 16-bits + signed 15-bit low field */
+#define FLAT_V850_R_HI16S_LO16	2 /* High 16-bits + signed 16-bit low field */
+
+/* Extract the address to be relocated from the symbol reference at RP;
+   RELVAL is the raw relocation-table entry from which RP is derived.
+   For the v850, RP should always be half-word aligned.  */
+static inline unsigned long flat_get_addr_from_rp (unsigned long *rp,
+						   unsigned long relval,
+						   unsigned long flags)
+{
+	short *srp = (short *)rp;
+	(void)flags;
+
+	switch (flat_v850_get_reloc_type (relval))
+	{
+	case FLAT_V850_R_32:
+		/* Simple 32-bit address.  */
+		return srp[0] | (srp[1] << 16);
+
+	case FLAT_V850_R_HI16S_LO16:
+		/* The high and low halves of the address are in the 16
+		   bits at RP, and the 2nd word of the 32-bit instruction
+		   following that, respectively.  The low half is _signed_
+		   so we have to sign-extend it and add it to the upper
+		   half instead of simply or-ing them together.
+
+		   Unlike most relocated address, this one is stored in
+		   native (little-endian) byte-order to avoid problems with
+		   trashing the low-order bit, so we have to convert to
+		   network-byte-order before returning, as that's what the
+		   caller expects.  */
+		return htonl ((srp[0] << 16) + srp[2]);
+
+	case FLAT_V850_R_HI16S_LO15:
+		/* The high and low halves of the address are in the 16
+		   bits at RP, and the upper 15 bits of the 2nd word of the
+		   32-bit instruction following that, respectively.  The
+		   low half is _signed_ so we have to sign-extend it and
+		   add it to the upper half instead of simply or-ing them
+		   together.  The lowest bit is always zero.
+
+		   Unlike most relocated address, this one is stored in
+		   native (little-endian) byte-order to avoid problems with
+		   trashing the low-order bit, so we have to convert to
+		   network-byte-order before returning, as that's what the
+		   caller expects.  */
+		return htonl ((srp[0] << 16) + (srp[2] & ~0x1));
+
+	default:
+		return ~0;	/* bogus value */
+	}
+}
+
+/* Insert the address ADDR into the symbol reference at RP;
+   RELVAL is the raw relocation-table entry from which RP is derived.
+   For the v850, RP should always be half-word aligned.  */
+static inline void flat_put_addr_at_rp (unsigned long *rp, unsigned long addr,
+					unsigned long relval)
+{
+	short *srp = (short *)rp;
+
+	switch (flat_v850_get_reloc_type (relval)) {
+	case FLAT_V850_R_32:
+		/* Simple 32-bit address.  */
+		srp[0] = addr & 0xFFFF;
+		srp[1] = (addr >> 16);
+		break;
+
+	case FLAT_V850_R_HI16S_LO16:
+		/* The high and low halves of the address are in the 16
+		   bits at RP, and the 2nd word of the 32-bit instruction
+		   following that, respectively.  The low half is _signed_
+		   so we must carry its sign bit to the upper half before
+		   writing the upper half.  */
+		srp[0] = (addr >> 16) + ((addr >> 15) & 0x1);
+		srp[2] = addr & 0xFFFF;
+		break;
+
+	case FLAT_V850_R_HI16S_LO15:
+		/* The high and low halves of the address are in the 16
+		   bits at RP, and the upper 15 bits of the 2nd word of the
+		   32-bit instruction following that, respectively.  The
+		   low half is _signed_ so we must carry its sign bit to
+		   the upper half before writing the upper half.  The
+		   lowest bit we preserve from the existing instruction.  */
+		srp[0] = (addr >> 16) + ((addr >> 15) & 0x1);
+		srp[2] = (addr & 0xFFFE) | (srp[2] & 0x1);
+		break;
+	}
+}
+
+#endif /* __V850_FLAT_H__ */
diff -urN linux-2.4.29/include/asm-v850/fpga85e2c.h linux-2.4.29-uc1/include/asm-v850/fpga85e2c.h
--- linux-2.4.29/include/asm-v850/fpga85e2c.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/fpga85e2c.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,88 @@
+/*
+ * include/asm-v850/fpga85e2c.h -- Machine-dependent defs for
+ *	FPGA implementation of V850E2/NA85E2C
+ *
+ *  Copyright (C) 2002,03  NEC Electronics Corporation
+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_FPGA85E2C_H__
+#define __V850_FPGA85E2C_H__
+
+#include <asm/v850e2.h>
+#include <asm/clinkage.h>
+
+
+#define CPU_MODEL	"v850e2/fpga85e2c"
+#define CPU_MODEL_LONG	"NEC V850E2/NA85E2C"
+#define PLATFORM	"fpga85e2c"
+#define PLATFORM_LONG	"NA85E2C FPGA implementation"
+
+
+/* `external ram'.  */
+#define ERAM_ADDR		0
+#define ERAM_SIZE		0x00100000 /* 1MB */
+
+
+/* FPGA specific control registers.  */
+
+/* Writing a non-zero value to FLGREG(0) will signal the controlling CPU
+   to stop execution.  */
+#define FLGREG_ADDR(n)		(0xFFE80100 + 2*(n))
+#define FLGREG(n)		(*(volatile unsigned char *)FLGREG_ADDR (n))
+#define FLGREG_NUM		2
+
+#define CSDEV_ADDR(n)		(0xFFE80110 + 2*(n))
+#define CSDEV(n)		(*(volatile unsigned char *)CSDEV_ADDR (n))
+
+
+/* Timer interrupts 0-3, interrupt at intervals from CLK/4096 to CLK/16384.  */
+#define IRQ_RPU(n)		(60 + (n))
+#define IRQ_RPU_NUM		4
+
+/* For <asm/irq.h> */
+#define NUM_CPU_IRQS		64
+
+
+/* General-purpose timer.  */
+/* control/status register (can only be read/written via bit insns) */
+#define RPU_GTMC_ADDR		0xFFFFFB00
+#define RPU_GTMC		(*(volatile unsigned char *)RPU_GTMC_ADDR)
+#define RPU_GTMC_CE_BIT		7 /* clock enable (control) */
+#define RPU_GTMC_OV_BIT		6 /* overflow (status) */
+#define RPU_GTMC_CLK_BIT	1 /* 0 = .5 MHz CLK, 1 = 1 Mhz (control) */
+/* 32-bit count (8 least-significant bits are always zero).  */
+#define RPU_GTM_ADDR		0xFFFFFB28
+#define RPU_GTM			(*(volatile unsigned long *)RPU_GTMC_ADDR)
+
+
+/* For <asm/page.h> */
+#define PAGE_OFFSET		ERAM_ADDR /* minimum allocatable address */
+
+
+/* For <asm/entry.h> */
+/* `R0 RAM', used for a few miscellaneous variables that must be accessible
+   using a load instruction relative to R0.  The FPGA implementation
+   actually has no on-chip RAM, so we use part of main ram just after the
+   interrupt vectors.  */
+#ifdef __ASSEMBLY__
+#define R0_RAM_ADDR		lo(C_SYMBOL_NAME(_r0_ram))
+#else
+extern char _r0_ram;
+#define R0_RAM_ADDR		((unsigned long)&_r0_ram);
+#endif
+
+
+/* For <asm/param.h> */
+#ifndef HZ
+#define HZ			122 /* actually, 8.192ms ticks =~ 122.07 */
+#endif
+
+
+#endif /* __V850_FPGA85E2C_H__ */
diff -urN linux-2.4.29/include/asm-v850/gbus_int.h linux-2.4.29-uc1/include/asm-v850/gbus_int.h
--- linux-2.4.29/include/asm-v850/gbus_int.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/gbus_int.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,97 @@
+/*
+ * include/asm-v850/gbus_int.h -- Midas labs GBUS interrupt support
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_GBUS_INT_H__
+#define __V850_GBUS_INT_H__
+
+
+/* The GBUS interrupt interface has 32 interrupts shared among 4
+   processor interrupts.  The 32 GBUS interrupts are divided into two
+   sets of 16 each, for allocating among control registers, etc (there
+   are two of each control register, with bits 0-15 controlling an
+   interrupt each).  */
+
+/* The GBUS interrupts themselves.  */
+#define IRQ_GBUS_INT(n)		(GBUS_INT_BASE_IRQ + (n))
+#define IRQ_GBUS_INT_NUM	32
+
+/* Control registers.  */
+#define GBUS_INT_STATUS_ADDR(w)	(GBUS_INT_BASE_ADDR + (w)*0x40)
+#define GBUS_INT_STATUS(w)	(*(volatile u16 *)GBUS_INT_STATUS_ADDR(w))
+#define GBUS_INT_CLEAR_ADDR(w)	(GBUS_INT_BASE_ADDR + 0x10 + (w)*0x40)
+#define GBUS_INT_CLEAR(w)	(*(volatile u16 *)GBUS_INT_CLEAR_ADDR(w))
+#define GBUS_INT_EDGE_ADDR(w)	(GBUS_INT_BASE_ADDR + 0x20 + (w)*0x40)
+#define GBUS_INT_EDGE(w)	(*(volatile u16 *)GBUS_INT_EDGE_ADDR(w))
+#define GBUS_INT_POLARITY_ADDR(w)	(GBUS_INT_BASE_ADDR + 0x30 + (w)*0x40)
+#define GBUS_INT_POLARITY(w)	(*(volatile u16 *)GBUS_INT_POLARITY_ADDR(w))
+/* This allows enabling interrupt bits in word W for interrupt GINTn.  */
+#define GBUS_INT_ENABLE_ADDR(w, n) \
+   (GBUS_INT_BASE_ADDR + 0x100 + (w)*0x10 + (n)*0x20)
+#define GBUS_INT_ENABLE(w, n)	(*(volatile u16 *)GBUS_INT_ENABLE_ADDR(w, n))
+
+/* Mapping between kernel interrupt numbers and hardware control regs/bits.  */
+#define GBUS_INT_BITS_PER_WORD	16
+#define GBUS_INT_NUM_WORDS	(IRQ_GBUS_INT_NUM / GBUS_INT_BITS_PER_WORD)
+#define GBUS_INT_IRQ_WORD(irq)	(((irq) - GBUS_INT_BASE_IRQ) >> 4)
+#define GBUS_INT_IRQ_BIT(irq)	(((irq) - GBUS_INT_BASE_IRQ) & 0xF)
+#define GBUS_INT_IRQ_MASK(irq)	(1 << GBUS_INT_IRQ_BIT(irq))
+
+
+/* Possible priorities for GBUS interrupts.  */
+#define GBUS_INT_PRIORITY_HIGH		2
+#define GBUS_INT_PRIORITY_MEDIUM	4
+#define GBUS_INT_PRIORITY_LOW		6
+
+
+#ifndef __ASSEMBLY__
+
+/* Enable interrupt handling for interrupt IRQ.  */
+extern void gbus_int_enable_irq (unsigned irq);
+/* Disable interrupt handling for interrupt IRQ.  Note that any
+   interrupts received while disabled will be delivered once the
+   interrupt is enabled again, unless they are explicitly cleared using
+   `gbus_int_clear_pending_irq'.  */
+extern void gbus_int_disable_irq (unsigned irq);
+/* Return true if interrupt handling for interrupt IRQ is enabled.  */
+extern int gbus_int_irq_enabled (unsigned irq);
+/* Disable all GBUS irqs.  */
+extern void gbus_int_disable_irqs (void);
+/* Clear any pending interrupts for IRQ.  */
+extern void gbus_int_clear_pending_irq (unsigned irq);
+/* Return true if interrupt IRQ is pending (but disabled).  */
+extern int gbus_int_irq_pending (unsigned irq);
+
+
+struct gbus_int_irq_init {
+	const char *name;	/* name of interrupt type */
+
+	/* Range of kernel irq numbers for this type:
+	   BASE, BASE+INTERVAL, ..., BASE+INTERVAL*NUM  */
+	unsigned base, num, interval;
+
+	unsigned priority;	/* interrupt priority to assign */
+};
+struct hw_interrupt_type;	/* fwd decl */
+
+/* Initialize HW_IRQ_TYPES for GBUS irqs described in array
+   INITS (which is terminated by an entry with the name field == 0).  */
+extern void gbus_int_init_irq_types (struct gbus_int_irq_init *inits,
+				     struct hw_interrupt_type *hw_irq_types);
+
+/* Initialize GBUS interrupts.  */
+extern void gbus_int_init_irqs (void);
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_GBUS_INT_H__ */
diff -urN linux-2.4.29/include/asm-v850/hardirq.h linux-2.4.29-uc1/include/asm-v850/hardirq.h
--- linux-2.4.29/include/asm-v850/hardirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/hardirq.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,42 @@
+#ifndef __V850_HARDIRQ_H__
+#define __V850_HARDIRQ_H__
+
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <linux/cache.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned int __local_irq_count;
+	unsigned int __local_bh_count;
+	unsigned int __syscall_count;
+	struct task_struct * __ksoftirqd_task;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt() (local_irq_count(smp_processor_id()) + local_bh_count(smp_processor_id()) != 0)
+
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
+
+#ifndef CONFIG_SMP
+
+#define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
+#define hardirq_endlock(cpu)	do { } while (0)
+
+#define irq_enter(cpu, irq)	(local_irq_count(cpu)++)
+#define irq_exit(cpu, irq)	(local_irq_count(cpu)--)
+
+#define synchronize_irq()	barrier()
+
+#else
+
+#error v850 SMP is not available
+
+#endif /* CONFIG_SMP */
+
+#endif /* __V850_HARDIRQ_H__ */
diff -urN linux-2.4.29/include/asm-v850/highres_timer.h linux-2.4.29-uc1/include/asm-v850/highres_timer.h
--- linux-2.4.29/include/asm-v850/highres_timer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/highres_timer.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,44 @@
+/*
+ * include/asm-v850/highres_timer.h -- High resolution timing routines
+ *
+ *  Copyright (C) 2001,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_HIGHRES_TIMER_H__
+#define __V850_HIGHRES_TIMER_H__
+
+#ifndef __ASSEMBLY__
+#include <linux/time.h>
+#endif
+
+#include <asm/entry.h>
+
+
+/* Frequency of the `slow ticks' (one tick each time the fast-tick
+   counter overflows).  */
+#define HIGHRES_TIMER_SLOW_TICK_RATE	25
+
+/* Which timer in the V850E `Timer D' we use.  */
+#define HIGHRES_TIMER_TIMER_D_UNIT	3
+
+
+#ifndef __ASSEMBLY__
+
+extern void highres_timer_start (void), highres_timer_stop (void);
+extern void highres_timer_reset (void);
+extern void highres_timer_read_ticks (u32 *slow_ticks, u32 *fast_ticks);
+extern void highres_timer_ticks_to_timeval (u32 slow_ticks, u32 fast_ticks,
+					    struct timeval *tv);
+extern void highres_timer_read (struct timeval *tv);
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_HIGHRES_TIMER_H__ */
diff -urN linux-2.4.29/include/asm-v850/hw_irq.h linux-2.4.29-uc1/include/asm-v850/hw_irq.h
--- linux-2.4.29/include/asm-v850/hw_irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/hw_irq.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,8 @@
+#ifndef __V850_HW_IRQ_H__
+#define __V850_HW_IRQ_H__
+
+extern inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int i)
+{
+}
+
+#endif /* __V850_HW_IRQ_H__ */
diff -urN linux-2.4.29/include/asm-v850/ioctl.h linux-2.4.29-uc1/include/asm-v850/ioctl.h
--- linux-2.4.29/include/asm-v850/ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/ioctl.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,80 @@
+/* $Id: ioctl.h,v 1.3 1997/04/16 15:10:07 jes Exp $
+ *
+ * linux/ioctl.h for Linux by H.H. Bergman.
+ */
+
+#ifndef _V850_IOCTL_H
+#define _V850_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * I don't really have any idea about what this should look like, so
+ * for the time being, this is heavily based on the PC definitions.
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	14
+#define _IOC_DIRBITS	2
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE	0U
+#define _IOC_WRITE	1U
+#define _IOC_READ	2U
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* __V850_IOCTL_H__ */
diff -urN linux-2.4.29/include/asm-v850/ioctls.h linux-2.4.29-uc1/include/asm-v850/ioctls.h
--- linux-2.4.29/include/asm-v850/ioctls.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/ioctls.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,81 @@
+#ifndef __V850_IOCTLS_H__
+#define __V850_IOCTLS_H__
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+#define TIOCSBRK	0x5427  /* BSD compatibility */
+#define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define FIONCLEX	0x5450  /* these numbers need to be adjusted. */
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+#define FIOQSIZE	0x545E
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+#endif /* __V850_IOCTLS_H__ */
diff -urN linux-2.4.29/include/asm-v850/io.h linux-2.4.29-uc1/include/asm-v850/io.h
--- linux-2.4.29/include/asm-v850/io.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/io.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,96 @@
+/*
+ * include/asm-v850/io.h -- Misc I/O operations
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_IO_H__
+#define __V850_IO_H__
+
+#include <asm/virtconvert.h>
+
+#define IO_SPACE_LIMIT 0xFFFFFFFF
+
+#define readb(addr) \
+  ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
+#define readw(addr) \
+  ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
+#define readl(addr) \
+  ({ unsigned long __v = (*(volatile unsigned long *) (addr)); __v; })
+
+#define writeb(b, addr) \
+  (void)((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b, addr) \
+  (void)((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b, addr) \
+  (void)((*(volatile unsigned int *) (addr)) = (b))
+
+#define inb(addr)	readb (addr)
+#define inw(addr)	readw (addr)
+#define inl(addr)	readl (addr)
+#define outb(x, addr)	((void) writeb (x, addr))
+#define outw(x, addr)	((void) writew (x, addr))
+#define outl(x, addr)	((void) writel (x, addr))
+
+#define inb_p(port)		inb((port))
+#define outb_p(val, port)	outb((val), (port))
+#define inw_p(port)		inw((port))
+#define outw_p(val, port)	outw((val), (port))
+#define inl_p(port)		inl((port))
+#define outl_p(val, port)	outl((val), (port))
+
+static inline void insb (unsigned long port, void *dst, unsigned long count)
+{
+	unsigned char *p = dst;
+	while (count--)
+		*p++ = inb (port);
+}
+static inline void insw (unsigned long port, void *dst, unsigned long count)
+{
+	unsigned short *p = dst;
+	while (count--)
+		*p++ = inw (port);
+}
+static inline void insl (unsigned long port, void *dst, unsigned long count)
+{
+	unsigned long *p = dst;
+	while (count--)
+		*p++ = inl (port);
+}
+
+static inline void
+outsb (unsigned long port, const void *src, unsigned long count)
+{
+	const unsigned char *p = src;
+	while (count--)
+		outb (*p++, port);
+}
+static inline void
+outsw (unsigned long port, const void *src, unsigned long count)
+{
+	const unsigned short *p = src;
+	while (count--)
+		outw (*p++, port);
+}
+static inline void
+outsl (unsigned long port, const void *src, unsigned long count)
+{
+	const unsigned long *p = src;
+	while (count--)
+		outl (*p++, port);
+}
+
+#define iounmap(addr)				((void)0)
+#define ioremap(physaddr, size)			(physaddr)
+#define ioremap_nocache(physaddr, size)		(physaddr)
+#define ioremap_writethrough(physaddr, size)	(physaddr)
+#define ioremap_fullcache(physaddr, size)	(physaddr)
+
+#endif /* __V850_IO_H__ */
diff -urN linux-2.4.29/include/asm-v850/ipcbuf.h linux-2.4.29-uc1/include/asm-v850/ipcbuf.h
--- linux-2.4.29/include/asm-v850/ipcbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/ipcbuf.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,29 @@
+#ifndef __V850E_IPCBUF_H__
+#define __V850E_IPCBUF_H__
+
+/*
+ * The user_ipc_perm structure for v850e architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
+	__kernel_mode_t		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* __V850E_IPCBUF_H__ */
diff -urN linux-2.4.29/include/asm-v850/ipc.h linux-2.4.29-uc1/include/asm-v850/ipc.h
--- linux-2.4.29/include/asm-v850/ipc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/ipc.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef __V850_IPC_H__
+#define __V850_IPC_H__
+
+/* 
+ * These are used to wrap system calls on v850.
+ *
+ * See arch/v850/kernel/syscalls.c for ugly details..
+ */
+struct ipc_kludge {
+	struct msgbuf *msgp;
+	long msgtyp;
+};
+
+#define SEMOP		 1
+#define SEMGET		 2
+#define SEMCTL		 3
+#define MSGSND		11
+#define MSGRCV		12
+#define MSGGET		13
+#define MSGCTL		14
+#define SHMAT		21
+#define SHMDT		22
+#define SHMGET		23
+#define SHMCTL		24
+
+/* Used by the DIPC package, try and avoid reusing it */
+#define DIPC		25
+
+#define IPCCALL(version,op)	((version)<<16 | (op))
+
+#endif /* __V850_IPC_H__ */
diff -urN linux-2.4.29/include/asm-v850/irq.h linux-2.4.29-uc1/include/asm-v850/irq.h
--- linux-2.4.29/include/asm-v850/irq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/irq.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,55 @@
+/*
+ * include/asm-v850/irq.h -- Machine interrupt handling
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_IRQ_H__
+#define __V850_IRQ_H__
+
+#include <asm/machdep.h>
+
+/* Default NUM_MACH_IRQS.  */
+#ifndef NUM_MACH_IRQS
+#define NUM_MACH_IRQS	NUM_CPU_IRQS
+#endif
+
+/* NMIs have IRQ numbers from FIRST_NMI to FIRST_NMI+NUM_NMIS-1.  */
+#define FIRST_NMI	NUM_MACH_IRQS
+#define IRQ_NMI(n)	(FIRST_NMI + (n))
+/* v850 processors have 3 non-maskable interrupts.  */
+#define NUM_NMIS	3
+
+/* Includes both maskable and non-maskable irqs.  */
+#define NR_IRQS		(NUM_MACH_IRQS + NUM_NMIS)
+
+
+#ifndef __ASSEMBLY__
+
+struct pt_regs;
+struct hw_interrupt_type;
+struct irqaction;
+
+/* Initialize irq handling for IRQs.
+   BASE_IRQ, BASE_IRQ+INTERVAL, ..., BASE_IRQ+NUM*INTERVAL
+   to IRQ_TYPE.  An IRQ_TYPE of 0 means to use a generic interrupt type.  */
+extern void
+init_irq_handlers (int base_irq, int num, int interval,
+		   struct hw_interrupt_type *irq_type);
+
+typedef void (*irq_handler_t)(int irq, void *data, struct pt_regs *regs);
+
+/* Handle interrupt IRQ.  REGS are the registers at the time of ther
+   interrupt.  */
+extern unsigned int handle_irq (int irq, struct pt_regs *regs);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __V850_IRQ_H__ */
diff -urN linux-2.4.29/include/asm-v850/ma1.h linux-2.4.29-uc1/include/asm-v850/ma1.h
--- linux-2.4.29/include/asm-v850/ma1.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/ma1.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ * include/asm-v850/ma1.h -- V850E/MA1 cpu chip
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_MA1_H__
+#define __V850_MA1_H__
+
+/* Inherit more generic details from MA series.  */
+#include <asm/ma.h>
+
+
+#define CPU_MODEL	"v850e/ma1"
+#define CPU_MODEL_LONG	"NEC V850E/MA1"
+
+
+/* Hardware-specific interrupt numbers (in the kernel IRQ namespace).  */
+#define IRQ_INTOV(n)	(n)	/* 0-3 */
+#define IRQ_INTOV_NUM	4
+#define IRQ_INTP(n)	(0x4  + (n)) /* Pnnn (pin) interrupts */
+#define IRQ_INTP_NUM	24
+#define IRQ_INTCMD(n)	(0x1c + (n)) /* interval timer interrupts 0-3 */
+#define IRQ_INTCMD_NUM	4
+#define IRQ_INTDMA(n)	(0x20 + (n)) /* DMA interrupts 0-3 */
+#define IRQ_INTDMA_NUM	4
+#define IRQ_INTCSI(n)	(0x24 + (n)*4)/* CSI 0-2 transmit/receive completion */
+#define IRQ_INTCSI_NUM	3
+#define IRQ_INTSER(n)	(0x25 + (n)*4) /* UART 0-2 reception error */
+#define IRQ_INTSER_NUM	3
+#define IRQ_INTSR(n)	(0x26 + (n)*4) /* UART 0-2 reception completion */
+#define IRQ_INTSR_NUM	3
+#define IRQ_INTST(n)	(0x27 + (n)*4) /* UART 0-2 transmission completion */
+#define IRQ_INTST_NUM	3
+
+#define NUM_CPU_IRQS	0x30
+
+
+/* The MA1 has a UART with 3 channels.  */
+#define V850E_UART_NUM_CHANNELS	3
+
+
+#endif /* __V850_MA1_H__ */
diff -urN linux-2.4.29/include/asm-v850/machdep.h linux-2.4.29-uc1/include/asm-v850/machdep.h
--- linux-2.4.29/include/asm-v850/machdep.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/machdep.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,61 @@
+/*
+ * include/asm-v850/machdep.h -- Machine-dependent definitions
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_MACHDEP_H__
+#define __V850_MACHDEP_H__
+
+#include <linux/config.h>
+
+/* chips */
+#ifdef CONFIG_V850E_MA1
+#include <asm/ma1.h>
+#endif
+#ifdef CONFIG_V850E_ME2
+#include <asm/me2.h>
+#endif
+#ifdef CONFIG_V850E_TEG
+#include <asm/teg.h>
+#endif
+
+/* These are both chips _and_ platforms, so put them in the middle... */
+#ifdef CONFIG_V850E2_ANNA
+#include <asm/anna.h>
+#endif
+#ifdef CONFIG_V850E_AS85EP1
+#include <asm/as85ep1.h>
+#endif
+
+/* platforms */
+#ifdef CONFIG_RTE_CB_MA1
+#include <asm/rte_ma1_cb.h>
+#endif
+#ifdef CONFIG_RTE_CB_ME2
+#include <asm/rte_me2_cb.h>
+#endif
+#ifdef CONFIG_RTE_CB_NB85E
+#include <asm/rte_nb85e_cb.h>
+#endif
+#ifdef CONFIG_V850E_SIM
+#include <asm/sim.h>
+#endif
+#ifdef CONFIG_V850E2_SIM85E2C
+#include <asm/sim85e2c.h>
+#endif
+#ifdef CONFIG_V850E2_SIM85E2S
+#include <asm/sim85e2s.h>
+#endif
+#ifdef CONFIG_V850E2_FPGA85E2C
+#include <asm/fpga85e2c.h>
+#endif
+
+#endif /* __V850_MACHDEP_H__ */
diff -urN linux-2.4.29/include/asm-v850/macrology.h linux-2.4.29-uc1/include/asm-v850/macrology.h
--- linux-2.4.29/include/asm-v850/macrology.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/macrology.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * include/asm-v850/macrology.h -- Various useful CPP macros
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#define macrology_paste(arg1, arg2)	macrology_paste_1(arg1, arg2)
+#define macrology_paste_1(arg1, arg2)	arg1 ## arg2
+#define macrology_stringify(sym)	macrology_stringify_1(sym)
+#define macrology_stringify_1(sym)	#sym
diff -urN linux-2.4.29/include/asm-v850/ma.h linux-2.4.29-uc1/include/asm-v850/ma.h
--- linux-2.4.29/include/asm-v850/ma.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/ma.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,101 @@
+/*
+ * include/asm-v850/ma.h -- V850E/MA series of cpu chips
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_MA_H__
+#define __V850_MA_H__
+
+/* The MA series uses the V850E cpu core.  */
+#include <asm/v850e.h>
+
+
+/* For <asm/entry.h> */
+/* We use on-chip RAM, for a few miscellaneous variables that must be
+   accessible using a load instruction relative to R0.  The amount
+   varies between chip models, but there's always at least 4K, and it
+   should always start at FFFFC000.  */
+#define R0_RAM_ADDR			0xFFFFC000
+
+
+/* MA series UART details.  */
+#define V850E_UART_BASE_FREQ		CPU_CLOCK_FREQ
+
+/* This is a function that gets called before configuring the UART.  */
+#define V850E_UART_PRE_CONFIGURE	ma_uart_pre_configure
+#ifndef __ASSEMBLY__
+extern void ma_uart_pre_configure (unsigned chan,
+				   unsigned cflags, unsigned baud);
+#endif
+
+
+/* MA series timer C details.  */
+#define V850E_TIMER_C_BASE_ADDR		0xFFFFF600
+
+
+/* MA series timer D details.  */
+#define V850E_TIMER_D_BASE_ADDR		0xFFFFF540
+#define V850E_TIMER_D_TMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x0)
+#define V850E_TIMER_D_CMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x2)
+#define V850E_TIMER_D_TMCD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x4)
+
+#define V850E_TIMER_D_BASE_FREQ		CPU_CLOCK_FREQ
+
+
+/* Port 0 */
+/* Direct I/O.  Bits 0-7 are pins P00-P07.  */
+#define MA_PORT0_IO_ADDR		0xFFFFF400
+#define MA_PORT0_IO			(*(volatile u8 *)MA_PORT0_IO_ADDR)
+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
+#define MA_PORT0_PM_ADDR		0xFFFFF420
+#define MA_PORT0_PM			(*(volatile u8 *)MA_PORT0_PM_ADDR)
+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
+#define MA_PORT0_PMC_ADDR		0xFFFFF440
+#define MA_PORT0_PMC			(*(volatile u8 *)MA_PORT0_PMC_ADDR)
+/* Port function control (for P04-P07, 0 = IRQ, 1 = DMARQ).  */
+#define MA_PORT0_PFC_ADDR		0xFFFFF460
+#define MA_PORT0_PFC			(*(volatile u8 *)MA_PORT0_PFC_ADDR)
+
+/* Port 1 */
+/* Direct I/O.  Bits 0-3 are pins P10-P13.  */
+#define MA_PORT1_IO_ADDR		0xFFFFF402
+#define MA_PORT1_IO			(*(volatile u8 *)MA_PORT1_IO_ADDR)
+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
+#define MA_PORT1_PM_ADDR		0xFFFFF420
+#define MA_PORT1_PM			(*(volatile u8 *)MA_PORT1_PM_ADDR)
+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
+#define MA_PORT1_PMC_ADDR		0xFFFFF442
+#define MA_PORT1_PMC			(*(volatile u8 *)MA_PORT1_PMC_ADDR)
+
+/* Port 4 */
+/* Direct I/O.  Bits 0-5 are pins P40-P45.  */
+#define MA_PORT4_IO_ADDR		0xFFFFF408
+#define MA_PORT4_IO			(*(volatile u8 *)MA_PORT4_IO_ADDR)
+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
+#define MA_PORT4_PM_ADDR		0xFFFFF428
+#define MA_PORT4_PM			(*(volatile u8 *)MA_PORT4_PM_ADDR)
+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
+#define MA_PORT4_PMC_ADDR		0xFFFFF448
+#define MA_PORT4_PMC			(*(volatile u8 *)MA_PORT4_PMC_ADDR)
+/* Port function control (for serial interfaces, 0 = CSI, 1 = UART).  */
+#define MA_PORT4_PFC_ADDR		0xFFFFF468
+#define MA_PORT4_PFC			(*(volatile u8 *)MA_PORT4_PFC_ADDR)
+
+
+#ifndef __ASSEMBLY__
+
+/* Initialize MA chip interrupts.  */
+extern void ma_init_irqs (void);
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_MA_H__ */
diff -urN linux-2.4.29/include/asm-v850/me2.h linux-2.4.29-uc1/include/asm-v850/me2.h
--- linux-2.4.29/include/asm-v850/me2.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/me2.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,182 @@
+/*
+ * include/asm-v850/me2.h -- V850E/ME2 cpu chip
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_ME2_H__
+#define __V850_ME2_H__
+
+#include <asm/v850e.h>
+#include <asm/v850e_cache.h>
+
+
+#define CPU_MODEL	"v850e/me2"
+#define CPU_MODEL_LONG	"NEC V850E/ME2"
+
+
+/* Hardware-specific interrupt numbers (in the kernel IRQ namespace).  */
+#define IRQ_INTP(n)       (n) /* Pnnn (pin) interrupts */
+#define IRQ_INTP_NUM      31
+#define IRQ_INTCMD(n)     (0x31 + (n)) /* interval timer interrupts 0-3 */
+#define IRQ_INTCMD_NUM    4
+#define IRQ_INTDMA(n)     (0x41 + (n)) /* DMA interrupts 0-3 */
+#define IRQ_INTDMA_NUM    4
+#define IRQ_INTUBTIRE(n)  (0x49 + (n)*5)/* UARTB 0-1 reception error */
+#define IRQ_INTUBTIRE_NUM 2
+#define IRQ_INTUBTIR(n)   (0x4a + (n)*5) /* UARTB 0-1 reception complete */
+#define IRQ_INTUBTIR_NUM  2
+#define IRQ_INTUBTIT(n)   (0x4b + (n)*5) /* UARTB 0-1 transmission complete */
+#define IRQ_INTUBTIT_NUM  2
+#define IRQ_INTUBTIF(n)   (0x4c + (n)*5) /* UARTB 0-1 FIFO trans. complete */
+#define IRQ_INTUBTIF_NUM  2
+#define IRQ_INTUBTITO(n)  (0x4d + (n)*5) /* UARTB 0-1 reception timeout */
+#define IRQ_INTUBTITO_NUM 2
+
+/* For <asm/irq.h> */
+#define NUM_CPU_IRQS		0x59 /* V850E/ME2 */
+
+
+/* For <asm/entry.h> */
+/* We use on-chip RAM, for a few miscellaneous variables that must be
+   accessible using a load instruction relative to R0.  */
+#define R0_RAM_ADDR			0xFFFFB000 /* V850E/ME2 */
+
+
+/* V850E/ME2 UARTB details.*/
+#define V850E_UART_NUM_CHANNELS		2
+#define V850E_UARTB_BASE_FREQ		(CPU_CLOCK_FREQ / 4)
+
+/* This is a function that gets called before configuring the UART.  */
+#define V850E_UART_PRE_CONFIGURE	me2_uart_pre_configure
+#ifndef __ASSEMBLY__
+extern void me2_uart_pre_configure (unsigned chan,
+				    unsigned cflags, unsigned baud);
+#endif /* __ASSEMBLY__ */
+
+
+/* V850E/ME2 timer C details.  */
+#define V850E_TIMER_C_BASE_ADDR		0xFFFFF600
+
+
+/* V850E/ME2 timer D details.  */
+#define V850E_TIMER_D_BASE_ADDR		0xFFFFF540
+#define V850E_TIMER_D_TMD_BASE_ADDR	(V850E_TIMER_D_BASE_ADDR + 0x0)
+#define V850E_TIMER_D_CMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x2)
+#define V850E_TIMER_D_TMCD_BASE_ADDR	(V850E_TIMER_D_BASE_ADDR + 0x4)
+
+#define V850E_TIMER_D_BASE_FREQ		(CPU_CLOCK_FREQ / 2)
+
+
+/* Select iRAM mode.  */
+#define ME2_IRAMM_ADDR			0xFFFFF80A
+#define ME2_IRAMM			(*(volatile u8*)ME2_IRAMM_ADDR)
+
+
+/* Interrupt edge-detection configuration.  INTF(n) and INTR(n) are only
+   valid for n == 1, 2, or 5.  */
+#define ME2_INTF_ADDR(n)		(0xFFFFFC00 + (n) * 0x2)
+#define ME2_INTF(n)			(*(volatile u8*)ME2_INTF_ADDR(n))
+#define ME2_INTR_ADDR(n)		(0xFFFFFC20 + (n) * 0x2)
+#define ME2_INTR(n)			(*(volatile u8*)ME2_INTR_ADDR(n))
+#define ME2_INTFAL_ADDR			0xFFFFFC10
+#define ME2_INTFAL			(*(volatile u8*)ME2_INTFAL_ADDR)
+#define ME2_INTRAL_ADDR			0xFFFFFC30
+#define ME2_INTRAL			(*(volatile u8*)ME2_INTRAL_ADDR)
+#define ME2_INTFDH_ADDR			0xFFFFFC16
+#define ME2_INTFDH			(*(volatile u16*)ME2_INTFDH_ADDR)
+#define ME2_INTRDH_ADDR			0xFFFFFC36
+#define ME2_INTRDH			(*(volatile u16*)ME2_INTRDH_ADDR)
+#define ME2_SESC_ADDR(n)		(0xFFFFF609 + (n) * 0x10)
+#define ME2_SESC(n)			(*(volatile u8*)ME2_SESC_ADDR(n))
+#define ME2_SESA10_ADDR			0xFFFFF5AD
+#define ME2_SESA10			(*(volatile u8*)ME2_SESA10_ADDR)
+#define ME2_SESA11_ADDR			0xFFFFF5DD
+#define ME2_SESA11			(*(volatile u8*)ME2_SESA11_ADDR)
+
+
+/* Port 1 */
+/* Direct I/O.  Bits 0-3 are pins P10-P13.  */
+#define ME2_PORT1_IO_ADDR		0xFFFFF402
+#define ME2_PORT1_IO			(*(volatile u8 *)ME2_PORT1_IO_ADDR)
+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
+#define ME2_PORT1_PM_ADDR		0xFFFFF422
+#define ME2_PORT1_PM			(*(volatile u8 *)ME2_PORT1_PM_ADDR)
+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
+#define ME2_PORT1_PMC_ADDR		0xFFFFF442
+#define ME2_PORT1_PMC			(*(volatile u8 *)ME2_PORT1_PMC_ADDR)
+/* Port function control (for serial interfaces, 0 = CSI30, 1 = UARTB0 ).  */
+#define ME2_PORT1_PFC_ADDR		0xFFFFF462
+#define ME2_PORT1_PFC			(*(volatile u8 *)ME2_PORT1_PFC_ADDR)
+
+/* Port 2 */
+/* Direct I/O.  Bits 0-3 are pins P20-P25.  */
+#define ME2_PORT2_IO_ADDR		0xFFFFF404
+#define ME2_PORT2_IO			(*(volatile u8 *)ME2_PORT2_IO_ADDR)
+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
+#define ME2_PORT2_PM_ADDR		0xFFFFF424
+#define ME2_PORT2_PM			(*(volatile u8 *)ME2_PORT2_PM_ADDR)
+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
+#define ME2_PORT2_PMC_ADDR		0xFFFFF444
+#define ME2_PORT2_PMC			(*(volatile u8 *)ME2_PORT2_PMC_ADDR)
+/* Port function control (for serial interfaces, 0 = INTP2x, 1 = UARTB1 ).  */
+#define ME2_PORT2_PFC_ADDR		0xFFFFF464
+#define ME2_PORT2_PFC			(*(volatile u8 *)ME2_PORT2_PFC_ADDR)
+
+/* Port 5 */
+/* Direct I/O.  Bits 0-5 are pins P50-P55.  */
+#define ME2_PORT5_IO_ADDR		0xFFFFF40A
+#define ME2_PORT5_IO			(*(volatile u8 *)ME2_PORT5_IO_ADDR)
+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
+#define ME2_PORT5_PM_ADDR		0xFFFFF42A
+#define ME2_PORT5_PM			(*(volatile u8 *)ME2_PORT5_PM_ADDR)
+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
+#define ME2_PORT5_PMC_ADDR		0xFFFFF44A
+#define ME2_PORT5_PMC			(*(volatile u8 *)ME2_PORT5_PMC_ADDR)
+/* Port function control ().  */
+#define ME2_PORT5_PFC_ADDR		0xFFFFF46A
+#define ME2_PORT5_PFC			(*(volatile u8 *)ME2_PORT5_PFC_ADDR)
+
+/* Port 6 */
+/* Direct I/O.  Bits 5-7 are pins P65-P67.  */
+#define ME2_PORT6_IO_ADDR		0xFFFFF40C
+#define ME2_PORT6_IO			(*(volatile u8 *)ME2_PORT6_IO_ADDR)
+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
+#define ME2_PORT6_PM_ADDR		0xFFFFF42C
+#define ME2_PORT6_PM			(*(volatile u8 *)ME2_PORT6_PM_ADDR)
+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
+#define ME2_PORT6_PMC_ADDR		0xFFFFF44C
+#define ME2_PORT6_PMC			(*(volatile u8 *)ME2_PORT6_PMC_ADDR)
+/* Port function control ().  */
+#define ME2_PORT6_PFC_ADDR		0xFFFFF46C
+#define ME2_PORT6_PFC			(*(volatile u8 *)ME2_PORT6_PFC_ADDR)
+
+/* Port 7 */
+/* Direct I/O.  Bits 2-7 are pins P72-P77.  */
+#define ME2_PORT7_IO_ADDR		0xFFFFF40E
+#define ME2_PORT7_IO			(*(volatile u8 *)ME2_PORT7_IO_ADDR)
+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
+#define ME2_PORT7_PM_ADDR		0xFFFFF42E
+#define ME2_PORT7_PM			(*(volatile u8 *)ME2_PORT7_PM_ADDR)
+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
+#define ME2_PORT7_PMC_ADDR		0xFFFFF44E
+#define ME2_PORT7_PMC			(*(volatile u8 *)ME2_PORT7_PMC_ADDR)
+/* Port function control ().  */
+#define ME2_PORT7_PFC_ADDR		0xFFFFF46E
+#define ME2_PORT7_PFC			(*(volatile u8 *)ME2_PORT7_PFC_ADDR)
+
+
+#ifndef __ASSEMBLY__
+/* Initialize V850E/ME2 chip interrupts.  */
+extern void me2_init_irqs (void);
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_ME2_H__ */
diff -urN linux-2.4.29/include/asm-v850/mman.h linux-2.4.29-uc1/include/asm-v850/mman.h
--- linux-2.4.29/include/asm-v850/mman.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/mman.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,40 @@
+#ifndef __V850_MMAN_H__
+#define __V850_MMAN_H__
+
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_NONE	0x0		/* page can not be accessed */
+#define PROT_GROWSDOWN	0x01000000	/* mprotect flag: extend change to start of growsdown vma */
+#define PROT_GROWSUP	0x02000000	/* mprotect flag: extend change to end of growsup vma */
+
+#define MAP_SHARED	0x01		/* Share changes */
+#define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_TYPE	0x0f		/* Mask for type of mapping */
+#define MAP_FIXED	0x10		/* Interpret addr exactly */
+#define MAP_ANONYMOUS	0x20		/* don't use a file */
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
+#define MAP_LOCKED	0x2000		/* pages are locked */
+#define MAP_NORESERVE	0x4000		/* don't check for reservations */
+
+#define MS_ASYNC	1		/* sync memory asynchronously */
+#define MS_INVALIDATE	2		/* invalidate the caches */
+#define MS_SYNC		4		/* synchronous memory sync */
+
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
+
+#define MADV_NORMAL	0x0		/* default page-in behavior */
+#define MADV_RANDOM	0x1		/* page-in minimum required */
+#define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
+#define MADV_WILLNEED	0x3		/* pre-fault pages */
+#define MADV_DONTNEED	0x4		/* discard these pages */
+
+/* compatibility flags */
+#define MAP_ANON	MAP_ANONYMOUS
+#define MAP_FILE	0
+
+#endif /* __V850_MMAN_H__ */
diff -urN linux-2.4.29/include/asm-v850/mmu_context.h linux-2.4.29-uc1/include/asm-v850/mmu_context.h
--- linux-2.4.29/include/asm-v850/mmu_context.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/mmu_context.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,10 @@
+#ifndef __V850_MMU_CONTEXT_H__
+#define __V850_MMU_CONTEXT_H__
+
+#define destroy_context(mm)		((void)0)
+#define init_new_context(tsk,mm)	0
+#define switch_mm(prev,next,tsk,cpu)	((void)0)
+#define activate_mm(prev,next)		((void)0)
+#define enter_lazy_tlb(mm,tsk,cpu)	((void)0)
+
+#endif /* __V850_MMU_CONTEXT_H__ */
diff -urN linux-2.4.29/include/asm-v850/mmu.h linux-2.4.29-uc1/include/asm-v850/mmu.h
--- linux-2.4.29/include/asm-v850/mmu.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/mmu.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,7 @@
+#ifndef __V850_MMU_H__
+#define __V850_MMU_H__
+
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_t;
+
+#endif /* __V850_MMU_H__ */
diff -urN linux-2.4.29/include/asm-v850/module.h linux-2.4.29-uc1/include/asm-v850/module.h
--- linux-2.4.29/include/asm-v850/module.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/module.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,22 @@
+/*
+ * include/asm-v850/module.h -- Architecture-specific module hooks
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_MODULE_H__
+#define __V850_MODULE_H__
+
+#define arch_init_modules(x)	((void)0)
+#define module_arch_init(x)	(0)
+#define module_map(sz)		vmalloc (sz)
+#define module_unmap(sz)	vfree (sz)
+
+#endif /* __V850_MODULE_H__ */
diff -urN linux-2.4.29/include/asm-v850/msgbuf.h linux-2.4.29-uc1/include/asm-v850/msgbuf.h
--- linux-2.4.29/include/asm-v850/msgbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/msgbuf.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef __V850_MSGBUF_H__
+#define __V850_MSGBUF_H__
+
+/* 
+ * The msqid64_ds structure for v850 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm msg_perm;
+	__kernel_time_t msg_stime;	/* last msgsnd time */
+	unsigned long	__unused1;
+	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	unsigned long	__unused2;
+	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned long	__unused3;
+	unsigned long  msg_cbytes;	/* current number of bytes on queue */
+	unsigned long  msg_qnum;	/* number of messages in queue */
+	unsigned long  msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t msg_lrpid;	/* last receive pid */
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+#endif /* __V850_MSGBUF_H__ */
diff -urN linux-2.4.29/include/asm-v850/namei.h linux-2.4.29-uc1/include/asm-v850/namei.h
--- linux-2.4.29/include/asm-v850/namei.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/namei.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-v850/namei.h
+ *
+ * Included from linux/fs/namei.c
+ */
+
+#ifndef __V850_NAMEI_H__
+#define __V850_NAMEI_H__
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+
+#define __emul_prefix() NULL
+
+#endif /* __V850_NAMEI_H__ */
diff -urN linux-2.4.29/include/asm-v850/page.h linux-2.4.29-uc1/include/asm-v850/page.h
--- linux-2.4.29/include/asm-v850/page.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/page.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,150 @@
+/*
+ * include/asm-v850/page.h -- VM ops
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_PAGE_H__
+#define __V850_PAGE_H__
+
+#include <asm/machdep.h>
+
+
+#define PAGE_SHIFT	12
+#define PAGE_SIZE       (1UL << PAGE_SHIFT)
+#define PAGE_MASK       (~(PAGE_SIZE-1))
+
+
+/*
+ * PAGE_OFFSET -- the first address of the first page of memory. For archs with
+ * no MMU this corresponds to the first free page in physical memory (aligned
+ * on a page boundary).
+ */
+#ifndef PAGE_OFFSET
+#define PAGE_OFFSET  0x0000000
+#endif
+
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#define STRICT_MM_TYPECHECKS
+
+#define clear_page(page)		memset ((void *)(page), 0, PAGE_SIZE)
+extern void copy_page(void *to, void *from);
+
+#define clear_user_page(page, vaddr)	clear_page (page)
+#define copy_user_page(to, from, vaddr)	copy_page (to, from)
+
+#ifdef STRICT_MM_TYPECHECKS
+/*
+ * These are used to make use of C type-checking..
+ */
+
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pmd; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)      ((x).pte)
+#define pmd_val(x)      ((x).pmd)
+#define pgd_val(x)      ((x).pgd)
+#define pgprot_val(x)   ((x).pgprot)
+
+#define __pte(x)        ((pte_t) { (x) } )
+#define __pmd(x)        ((pmd_t) { (x) } )
+#define __pgd(x)        ((pgd_t) { (x) } )
+#define __pgprot(x)     ((pgprot_t) { (x) } )
+
+#else /* !STRICT_MM_TYPECHECKS */
+/*
+ * .. while these make it easier on the compiler
+ */
+
+typedef unsigned long pte_t;
+typedef unsigned long pmd_t;
+typedef unsigned long pgd_t;
+typedef unsigned long pgprot_t;
+
+#define pte_val(x)      (x)
+#define pmd_val(x)      (x)
+#define pgd_val(x)      (x)
+#define pgprot_val(x)   (x)
+
+#define __pte(x)        (x)
+#define __pmd(x)        (x)
+#define __pgd(x)        (x)
+#define __pgprot(x)     (x)
+
+#endif /* STRICT_MM_TYPECHECKS */
+
+#endif /* !__ASSEMBLY__ */
+
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr) + PAGE_SIZE - 1) & PAGE_MASK)
+
+
+#ifndef __ASSEMBLY__
+
+extern void __bug (void) __attribute__ ((noreturn));
+#define BUG()		__bug()
+#define PAGE_BUG(page)	__bug()
+
+/* Pure 2^n version of get_order */
+extern __inline__ int get_order (unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+
+/* No current v850 processor has virtual memory.  */
+#define __virt_to_phys(addr)	(addr)
+#define __phys_to_virt(addr)	(addr)
+
+#define virt_to_pfn(kaddr)	(__virt_to_phys (kaddr) >> PAGE_SHIFT)
+#define pfn_to_virt(pfn)	__phys_to_virt ((pfn) << PAGE_SHIFT)
+
+#define MAP_NR(kaddr) \
+  (((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT)
+#define virt_to_page(kaddr)	(mem_map + MAP_NR (kaddr))
+#define page_to_virt(page) \
+  ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
+
+#define pfn_to_page(pfn)	virt_to_page (pfn_to_virt (pfn))
+#define page_to_pfn(page)	virt_to_pfn (page_to_virt (page))
+
+#define	virt_addr_valid(kaddr)						\
+  (((void *)(kaddr) >= (void *)PAGE_OFFSET) && MAP_NR (kaddr) < max_mapnr)
+
+#define VALID_PAGE(page) 	((page - mem_map) < max_mapnr)
+
+
+#define __pa(x)		     __virt_to_phys ((unsigned long)(x))
+#define __va(x)		     ((void *)__phys_to_virt ((unsigned long)(x)))
+
+
+#endif /* KERNEL */
+
+#ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
+#define WANT_PAGE_VIRTUAL 1 /* page alloc 2 relies on this */
+#endif
+
+#endif /* __V850_PAGE_H__ */
diff -urN linux-2.4.29/include/asm-v850/param.h linux-2.4.29-uc1/include/asm-v850/param.h
--- linux-2.4.29/include/asm-v850/param.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/param.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ * include/asm-v850/param.h -- Varions kernel parameters
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_PARAM_H__
+#define __V850_PARAM_H__
+
+#include <asm/machdep.h>	/* For HZ */
+
+#define EXEC_PAGESIZE	4096
+
+#ifndef NGROUPS
+#define NGROUPS		32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#ifdef __KERNEL__
+# define CLOCKS_PER_SEC	HZ
+#endif
+
+#endif /* __V850_PARAM_H__ */
diff -urN linux-2.4.29/include/asm-v850/pci.h linux-2.4.29-uc1/include/asm-v850/pci.h
--- linux-2.4.29/include/asm-v850/pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/pci.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,77 @@
+/*
+ * include/asm-v850/pci.h -- PCI support
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_PCI_H__
+#define __V850_PCI_H__
+
+/* Get any platform-dependent definitions.  */
+#include <asm/machdep.h>
+
+/* Generic declarations.  */
+
+struct scatterlist;
+
+extern void pcibios_set_master (struct pci_dev *dev);
+
+/* `Grant' to PDEV the memory block at CPU_ADDR, for doing DMA.  The
+   32-bit PCI bus mastering address to use is returned.  the device owns
+   this memory until either pci_unmap_single or pci_dma_sync_single is
+   performed.  */
+extern dma_addr_t
+pci_map_single (struct pci_dev *pdev, void *cpu_addr, size_t size, int dir);
+
+/* Return to the CPU the PCI DMA memory block previously `granted' to
+   PDEV, at DMA_ADDR.  */
+extern void
+pci_unmap_single (struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
+		  int dir);
+
+/* Make physical memory consistent for a single streaming mode DMA
+   translation after a transfer.
+
+   If you perform a pci_map_single() but wish to interrogate the
+   buffer using the cpu, yet do not wish to teardown the PCI dma
+   mapping, you must call this function before doing so.  At the next
+   point you give the PCI dma address back to the card, the device
+   again owns the buffer.  */
+extern void
+pci_dma_sync_single (struct pci_dev *dev, dma_addr_t dma_addr, size_t size,
+		     int dir);
+
+
+/* Do multiple DMA mappings at once.  */
+extern int
+pci_map_sg (struct pci_dev *pdev, struct scatterlist *sg, int sg_len, int dir);
+
+/* Unmap multiple DMA mappings at once.  */
+extern void
+pci_unmap_sg (struct pci_dev *pdev, struct scatterlist *sg, int sg_len,
+	      int dir);
+
+/* Allocate and map kernel buffer using consistent mode DMA for PCI
+   device.  Returns non-NULL cpu-view pointer to the buffer if
+   successful and sets *DMA_ADDR to the pci side dma address as well,
+   else DMA_ADDR is undefined.  */
+extern void *
+pci_alloc_consistent (struct pci_dev *pdev, size_t size, dma_addr_t *dma_addr);
+
+/* Free and unmap a consistent DMA buffer.  CPU_ADDR and DMA_ADDR must
+   be values that were returned from pci_alloc_consistent.  SIZE must be
+   the same as what as passed into pci_alloc_consistent.  References to
+   the memory and mappings assosciated with CPU_ADDR or DMA_ADDR past
+   this call are illegal.  */
+extern void
+pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr,
+		     dma_addr_t dma_addr);
+
+#endif /* __V850_PCI_H__ */
diff -urN linux-2.4.29/include/asm-v850/pgalloc.h linux-2.4.29-uc1/include/asm-v850/pgalloc.h
--- linux-2.4.29/include/asm-v850/pgalloc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/pgalloc.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,110 @@
+/*
+ * include/asm-v850/pgalloc.h
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_PGALLOC_H__
+#define __V850_PGALLOC_H__
+
+#include <asm/machdep.h>
+
+/*
+ * Cache handling functions
+ */
+
+/* The following are all used by the kernel in ways that only affect
+   systems with MMUs, so we don't need them.  */
+#define flush_cache_all()			((void)0)
+#define flush_cache_mm(mm)			((void)0)
+#define flush_cache_range(mm, start, end)	((void)0)
+#define flush_cache_page(vma, vmaddr)		((void)0)
+#define flush_page_to_ram(page)			((void)0)
+#define flush_dcache_page(page)			((void)0)
+
+#ifdef CONFIG_NO_CACHE
+
+/* Some systems have no cache at all, in which case we don't need these
+   either.  */
+#define flush_icache()				((void)0)
+#define flush_icache_range(start, end)		((void)0)
+#define flush_icache_page(vma,pg)		((void)0)
+#define flush_icache_user_range(vma,pg,adr,len)	((void)0)
+#define flush_cache_sigtramp(vaddr)		((void)0)
+
+#else /* !CONFIG_NO_CACHE */
+
+struct page;
+struct mm_struct;
+struct vm_area_struct;
+
+/* Otherwise, somebody had better define them.  */
+extern void flush_icache (void);
+extern void flush_icache_range (unsigned long start, unsigned long end);
+extern void flush_icache_page (struct vm_area_struct *vma, struct page *page);
+extern void flush_icache_user_range (struct vm_area_struct *vma,
+				     struct page *page,
+				     unsigned long adr, int len);
+extern void flush_cache_sigtramp (unsigned long addr);
+
+#endif /* CONFIG_NO_CACHE */
+
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+	BUG ();
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+	BUG ();
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+	BUG ();
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+	BUG ();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+	BUG ();
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+				   unsigned long start, unsigned long end)
+{
+	BUG ();
+}
+
+extern inline void flush_tlb_kernel_page(unsigned long addr)
+{
+	BUG ();
+}
+
+extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+				      unsigned long start, unsigned long end)
+{
+	BUG ();
+}
+
+#endif /* _V850_PGALLOC_H */
diff -urN linux-2.4.29/include/asm-v850/pgtable.h linux-2.4.29-uc1/include/asm-v850/pgtable.h
--- linux-2.4.29/include/asm-v850/pgtable.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/pgtable.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,20 @@
+#ifndef __V850_PGTABLE_H__
+#define __V850_PGTABLE_H__
+
+#include <linux/config.h>
+
+#define pgd_present(pgd)     (1)       /* pages are always present on NO_MM */
+#define kern_addr_valid(addr) (1)
+
+/* These mean nothing to !CONFIG_MMU.  */
+#define PAGE_NONE		__pgprot(0)
+#define PAGE_SHARED		__pgprot(0)
+#define PAGE_COPY		__pgprot(0)
+#define PAGE_READONLY		__pgprot(0)
+#define PAGE_KERNEL		__pgprot(0)
+
+extern void paging_init(void);
+
+#define pgtable_cache_init()   ((void)0)
+
+#endif /* __V850_PGTABLE_H__ */
diff -urN linux-2.4.29/include/asm-v850/poll.h linux-2.4.29-uc1/include/asm-v850/poll.h
--- linux-2.4.29/include/asm-v850/poll.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/poll.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,23 @@
+#ifndef __V850_POLL_H__
+#define __V850_POLL_H__
+
+#define POLLIN		0x0001
+#define POLLPRI		0x0002
+#define POLLOUT		0x0004
+#define POLLERR		0x0008
+#define POLLHUP		0x0010
+#define POLLNVAL	0x0020
+#define POLLRDNORM	0x0040
+#define POLLWRNORM	POLLOUT
+#define POLLRDBAND	0x0080
+#define POLLWRBAND	0x0100
+#define POLLMSG		0x0400
+#define POLLREMOVE	0x1000
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+#endif /* __V850_POLL_H__ */
diff -urN linux-2.4.29/include/asm-v850/posix_types.h linux-2.4.29-uc1/include/asm-v850/posix_types.h
--- linux-2.4.29/include/asm-v850/posix_types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/posix_types.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,75 @@
+/*
+ * include/asm-v850/posix_types.h -- Kernel versions of standard types
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_POSIX_TYPES_H__
+#define __V850_POSIX_TYPES_H__
+
+typedef unsigned int	__kernel_dev_t;
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned long long __kernel_ino64_t;
+typedef unsigned int	__kernel_mode_t;
+typedef unsigned int	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef long long	__kernel_loff_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
+typedef unsigned int	__kernel_uid_t;
+typedef unsigned int	__kernel_gid_t;
+typedef unsigned int	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_timer_t;
+typedef int		__kernel_clockid_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+/* Some bogus code depends on this; we don't care.  */
+typedef __kernel_uid_t __kernel_old_uid_t;
+typedef unsigned int	__kernel_old_dev_t;
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+	int	val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+	int	__val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#include <asm/bitops.h>
+
+#undef	__FD_SET
+#define __FD_SET(fd, fd_set) \
+  __set_bit (fd, (void *)&((__kernel_fd_set *)fd_set)->fds_bits)
+#undef __FD_CLR
+#define __FD_CLR(fd, fd_set) \
+  __clear_bit (fd, (void *)&((__kernel_fd_set *)fd_set)->fds_bits)
+#undef	__FD_ISSET
+#define __FD_ISSET(fd, fd_set) \
+  __test_bit (fd, (void *)&((__kernel_fd_set *)fd_set)->fds_bits)
+#undef	__FD_ZERO
+#define __FD_ZERO(fd_set) \
+  memset (fd_set, 0, sizeof (*(fd_set *)fd_set))
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif /* __V850_POSIX_TYPES_H__ */
diff -urN linux-2.4.29/include/asm-v850/processor.h linux-2.4.29-uc1/include/asm-v850/processor.h
--- linux-2.4.29/include/asm-v850/processor.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/processor.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,130 @@
+/*
+ * include/asm-v850/processor.h
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_PROCESSOR_H__
+#define __V850_PROCESSOR_H__
+
+#include <linux/config.h>
+
+#include <asm/ptrace.h>
+#include <asm/current.h>
+#include <asm/entry.h>
+
+/* Some code expects `segment' stuff to be defined here.  */
+#include <asm/segment.h>
+
+
+/*
+ * The only places this is used seem to be horrible bletcherous kludges,
+ * so we just define it to be as large as possible.
+ */
+#define TASK_SIZE	(0xFFFFFFFF)
+
+
+#define THREAD_SIZE	(2*PAGE_SIZE)
+
+
+#ifndef __ASSEMBLY__
+
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr()	({ __label__ _l; _l: &&_l;})
+
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+#define MCA_bus 0
+#define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+/* If you change this, you must change the associated assembly-languages
+   constants defined below, THREAD_*.  */
+struct thread_struct {
+	/* kernel stack pointer (must be first field in structure) */
+	unsigned long  ksp;
+};
+
+#define INIT_THREAD { sizeof init_stack + (unsigned long)init_stack }
+
+
+/* Do necessary setup to start up a newly executed thread.  */
+extern inline void start_thread (struct pt_regs *regs,
+				 unsigned long pc, unsigned long usp)
+{
+	regs->pc = pc;
+	regs->gpr[GPR_SP] = usp;
+	regs->kernel_mode = 0;
+}
+
+/* Free all resources held by a thread. */
+extern inline void release_thread (struct task_struct *dead_task)
+{
+}
+
+extern int arch_kernel_thread (int (*fn)(void *), void * arg, unsigned long flags);
+
+/* Free current thread data structures etc.  */
+static inline void exit_thread (void)
+{
+}
+
+
+/* Return the registers saved during context-switch by the currently
+   not-running thread T.  Note that this only includes some registers!
+   See entry.S for details.  */
+#define thread_saved_regs(t) ((struct pt_regs*)((t)->ksp + STATE_SAVE_PT_OFFSET))
+/* Return saved (kernel) PC of a blocked thread.  Actually, we return the
+   LP register, because the thread is actually blocked in switch_thread,
+   and we're interested in the PC it will _return_ to.  */
+#define thread_saved_pc(t)   (thread_saved_regs(t)->gpr[GPR_LP])
+
+
+unsigned long get_wchan (struct task_struct *p);
+
+
+/* Return some info about the user process TASK.  */
+#define task_tos(task)	((unsigned long)(task) + KERNEL_STACK_SIZE)
+#define task_regs(task) ((struct pt_regs *)task_tos (task) - 1)
+#define task_sp(task)	(task_regs (task)->gpr[GPR_SP])
+#define task_pc(task)	(task_regs (task)->pc)
+/* Grotty old names for some.  */
+#define KSTK_EIP(task)	task_pc (task)
+#define KSTK_ESP(task)	task_sp (task)
+
+
+#define cpu_relax()    ((void)0)
+
+
+/* Allocation and freeing of basic task resources. */
+#define alloc_task_struct() \
+   ((struct task_struct *)__get_free_pages(GFP_KERNEL,1))
+#define free_task_struct(p)	free_pages ((unsigned long)(p),1)
+#define get_task_struct(tsk)	atomic_inc (&mem_map[MAP_NR(tsk)].count)
+
+#define init_task	(init_task_union.task)
+#define init_stack	(init_task_union.stack)
+
+
+#else /* __ASSEMBLY__ */
+
+#define THREAD_KSP	0
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_PROCESSOR_H__ */
diff -urN linux-2.4.29/include/asm-v850/ptrace.h linux-2.4.29-uc1/include/asm-v850/ptrace.h
--- linux-2.4.29/include/asm-v850/ptrace.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/ptrace.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,120 @@
+/*
+ * include/asm-v850/ptrace.h -- Access to CPU registers
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_PTRACE_H__
+#define __V850_PTRACE_H__
+
+
+/* v850 general purpose registers with special meanings.  */
+#define GPR_ZERO	0	/* constant zero */
+#define GPR_ASM		1	/* reserved for assembler */
+#define GPR_SP		3	/* stack pointer */
+#define GPR_GP		4	/* global data pointer */
+#define GPR_TP		5	/* `text pointer' */
+#define GPR_EP		30	/* `element pointer' */
+#define GPR_LP		31	/* link pointer (current return address) */
+
+/* These aren't official names, but they make some code more descriptive.  */
+#define GPR_ARG0	6
+#define GPR_ARG1	7
+#define GPR_ARG2	8
+#define GPR_ARG3	9
+#define GPR_RVAL0	10
+#define GPR_RVAL1	11
+#define GPR_RVAL	GPR_RVAL0
+
+#define NUM_GPRS	32
+
+/* v850 `system' registers.  */
+#define SR_EIPC		0
+#define SR_EIPSW	1
+#define SR_FEPC		2
+#define SR_FEPSW	3
+#define SR_ECR		4
+#define SR_PSW		5
+#define SR_CTPC		16
+#define SR_CTPSW	17
+#define SR_DBPC		18
+#define SR_DBPSW	19
+#define SR_CTBP		20
+#define SR_DIR		21
+#define SR_ASID		23
+
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long v850_reg_t;
+
+/* How processor state is stored on the stack during a syscall/signal.
+   If you change this structure, change the associated assembly-language
+   macros below too (PT_*)!  */
+struct pt_regs
+{
+	/* General purpose registers.  */
+	v850_reg_t gpr[NUM_GPRS];
+
+	v850_reg_t pc;		/* program counter */
+	v850_reg_t psw;		/* program status word */
+
+	/* Registers used by `callt' instruction:  */
+	v850_reg_t ctpc;	/* saved program counter */
+	v850_reg_t ctpsw;	/* saved psw */
+	v850_reg_t ctbp;	/* base pointer for callt table */
+
+	char kernel_mode;	/* 1 if in `kernel mode', 0 if user mode */
+};
+
+
+#define instruction_pointer(regs)	((regs)->pc)
+#define user_mode(regs)			(!(regs)->kernel_mode)
+
+/* When a struct pt_regs is used to save user state for a system call in
+   the kernel, the system call is stored in the space for R0 (since it's
+   never used otherwise, R0 being a constant 0).  Non-system-calls
+   simply store 0 there.  */
+#define PT_REGS_SYSCALL(regs)		(regs)->gpr[0]
+#define PT_REGS_SET_SYSCALL(regs, val)	((regs)->gpr[0] = (val))
+
+#endif /* !__ASSEMBLY__ */
+
+
+/* The number of bytes used to store each register.  */
+#define _PT_REG_SIZE	4
+
+/* Offset of a general purpose register in a stuct pt_regs.  */
+#define PT_GPR(num)	((num) * _PT_REG_SIZE)
+
+/* Offsets of various special registers & fields in a struct pt_regs.  */
+#define PT_PC		((NUM_GPRS + 0) * _PT_REG_SIZE)
+#define PT_PSW		((NUM_GPRS + 1) * _PT_REG_SIZE)
+#define PT_CTPC		((NUM_GPRS + 2) * _PT_REG_SIZE)
+#define PT_CTPSW	((NUM_GPRS + 3) * _PT_REG_SIZE)
+#define PT_CTBP		((NUM_GPRS + 4) * _PT_REG_SIZE)
+#define PT_KERNEL_MODE	((NUM_GPRS + 5) * _PT_REG_SIZE)
+
+/* Where the current syscall number is stashed; obviously only valid in
+   the kernel!  */
+#define PT_CUR_SYSCALL	PT_GPR(0)
+
+/* Size of struct pt_regs, including alignment.  */
+#define PT_SIZE		((NUM_GPRS + 6) * _PT_REG_SIZE)
+
+
+/* These are `magic' values for PTRACE_PEEKUSR that return info about where
+   a process is located in memory.  */
+#define PT_TEXT_ADDR	(PT_SIZE + 1)
+#define PT_TEXT_LEN	(PT_SIZE + 2)
+#define PT_DATA_ADDR	(PT_SIZE + 3)
+
+
+#endif /* __V850_PTRACE_H__ */
diff -urN linux-2.4.29/include/asm-v850/resource.h linux-2.4.29-uc1/include/asm-v850/resource.h
--- linux-2.4.29/include/asm-v850/resource.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/resource.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,47 @@
+#ifndef __V850_RESOURCE_H__
+#define __V850_RESOURCE_H__
+
+/*
+ * Resource limits
+ */
+
+#define RLIMIT_CPU	0		/* CPU time in ms */
+#define RLIMIT_FSIZE	1		/* Maximum filesize */
+#define RLIMIT_DATA	2		/* max data size */
+#define RLIMIT_STACK	3		/* max stack size */
+#define RLIMIT_CORE	4		/* max core file size */
+#define RLIMIT_RSS	5		/* max resident set size */
+#define RLIMIT_NPROC	6		/* max number of processes */
+#define RLIMIT_NOFILE	7		/* max number of open files */
+#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
+#define RLIMIT_AS	9		/* address space limit */
+#define RLIMIT_LOCKS	10		/* maximum file locks held */
+
+#define RLIM_NLIMITS	11
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway.
+ */
+#define RLIM_INFINITY	(~0UL)
+
+#ifdef __KERNEL__
+
+#define INIT_RLIMITS					\
+{							\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{      _STK_LIM, RLIM_INFINITY },		\
+	{             0, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{             0,             0 },		\
+	{      INR_OPEN,     INR_OPEN  },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+        { RLIM_INFINITY, RLIM_INFINITY },		\
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* __V850_RESOURCE_H__ */
diff -urN linux-2.4.29/include/asm-v850/rte_cb.h linux-2.4.29-uc1/include/asm-v850/rte_cb.h
--- linux-2.4.29/include/asm-v850/rte_cb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/rte_cb.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,86 @@
+/*
+ * include/asm-v850/rte_cb.h -- Midas labs RTE-CB series of evaluation boards
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_RTE_CB_H__
+#define __V850_RTE_CB_H__
+
+
+/* The SRAM on the Mother-A motherboard.  */
+#define MB_A_SRAM_ADDR		GCS0_ADDR
+#define MB_A_SRAM_SIZE		0x00200000 /* 2MB */
+
+
+#ifdef CONFIG_RTE_GBUS_INT
+/* GBUS interrupt support.  */
+
+# include <asm/gbus_int.h>
+
+# define GBUS_INT_BASE_IRQ	NUM_RTE_CB_IRQS
+# define GBUS_INT_BASE_ADDR	(GCS2_ADDR + 0x00006000)
+
+/* Some specific interrupts.  */
+# define IRQ_MB_A_LAN		IRQ_GBUS_INT(10)
+# define IRQ_MB_A_PCI1(n)	(IRQ_GBUS_INT(16) + (n))
+# define IRQ_MB_A_PCI1_NUM	4
+# define IRQ_MB_A_PCI2(n)	(IRQ_GBUS_INT(20) + (n))
+# define IRQ_MB_A_PCI2_NUM	4
+# define IRQ_MB_A_EXT(n)	(IRQ_GBUS_INT(24) + (n))
+# define IRQ_MB_A_EXT_NUM	4
+# define IRQ_MB_A_USB_OC(n)	(IRQ_GBUS_INT(28) + (n))
+# define IRQ_MB_A_USB_OC_NUM	2
+# define IRQ_MB_A_PCMCIA_OC	IRQ_GBUS_INT(30)
+
+/* We define NUM_MACH_IRQS to include extra interrupts from the GBUS.  */
+# define NUM_MACH_IRQS		(NUM_RTE_CB_IRQS + IRQ_GBUS_INT_NUM)
+
+#else /* !CONFIG_RTE_GBUS_INT */
+
+# define NUM_MACH_IRQS		NUM_RTE_CB_IRQS
+
+#endif /* CONFIG_RTE_GBUS_INT */
+
+
+#ifdef CONFIG_RTE_MB_A_PCI
+/* Mother-A PCI bus support.  */
+
+# include <asm/rte_mb_a_pci.h>
+
+/* These are the base addresses used for allocating device address
+   space.  512K of the motherboard SRAM is in the same space, so we have
+   to be careful not to let it be allocated.  */
+# define PCIBIOS_MIN_MEM	(MB_A_PCI_MEM_ADDR + 0x80000)
+# define PCIBIOS_MIN_IO		MB_A_PCI_IO_ADDR
+
+/* As we don't really support PCI DMA to cpu memory, and use bounce-buffers
+   instead, perversely enough, this becomes always true! */
+# define pci_dma_supported(dev, mask)		1
+# define pci_dac_dma_supported(dev, mask)	0
+# define pci_controller_num(dev)		0
+# define pcibios_assign_all_busses()		1
+
+#endif /* CONFIG_RTE_MB_A_PCI */
+
+
+/* For <asm/param.h> */
+#ifndef HZ
+#define HZ	100
+#endif
+
+
+#ifndef __ASSEMBLY__
+extern void rte_cb_early_init (void);
+extern void rte_cb_init_irqs (void);
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_RTE_CB_H__ */
diff -urN linux-2.4.29/include/asm-v850/rte_ma1_cb.h linux-2.4.29-uc1/include/asm-v850/rte_ma1_cb.h
--- linux-2.4.29/include/asm-v850/rte_ma1_cb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/rte_ma1_cb.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,134 @@
+/*
+ * include/asm-v850/rte_ma1_cb.h -- Midas labs RTE-V850/MA1-CB board
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_RTE_MA1_CB_H__
+#define __V850_RTE_MA1_CB_H__
+
+#include <asm/rte_cb.h>		/* Common defs for Midas RTE-CB boards.  */
+
+
+#define PLATFORM		"rte-v850e/ma1-cb"
+#define PLATFORM_LONG		"Midas lab RTE-V850E/MA1-CB"
+
+#define CPU_CLOCK_FREQ		50000000 /* 50MHz */
+#define FIXED_BOGOMIPS		6.43	 /* Only valid for 2.4.x */
+
+/* 1MB of onboard SRAM.  Note that the monitor ROM uses parts of this
+   for its own purposes, so care must be taken.  Some address lines are
+   not decoded, so the SRAM area is mirrored every 1MB from 0x400000 to
+   0x800000 (exclusive).  */
+#define SRAM_ADDR		0x00400000
+#define SRAM_SIZE		0x00100000 /* 1MB */
+
+/* 32MB of onbard SDRAM.  */
+#define SDRAM_ADDR		0x00800000
+#define SDRAM_SIZE		0x02000000 /* 32MB */
+
+
+/* CPU addresses of GBUS memory spaces.  */
+#define GCS0_ADDR		0x05000000 /* GCS0 - Common SRAM (2MB) */
+#define GCS0_SIZE		0x00200000 /*   2MB */
+#define GCS1_ADDR		0x06000000 /* GCS1 - Flash ROM (8MB) */
+#define GCS1_SIZE		0x00800000 /*   8MB */
+#define GCS2_ADDR		0x07900000 /* GCS2 - I/O registers */
+#define GCS2_SIZE		0x00400000 /*   4MB */
+#define GCS5_ADDR		0x04000000 /* GCS5 - PCI bus space */
+#define GCS5_SIZE		0x01000000 /*   16MB */
+#define GCS6_ADDR		0x07980000 /* GCS6 - PCI control registers */
+#define GCS6_SIZE		0x00000200 /*   512B */
+
+
+/* For <asm/page.h> */
+#define PAGE_OFFSET 		SRAM_ADDR
+
+
+/* The GBUS GINT0 - GINT3 interrupts are connected to the INTP000 - INTP011
+   pins on the CPU.  These are shared among the GBUS interrupts.  */
+#define IRQ_GINT(n)		IRQ_INTP(n)
+#define IRQ_GINT_NUM		4
+
+/* Used by <asm/rte_cb.h> to derive NUM_MACH_IRQS.  */
+#define NUM_RTE_CB_IRQS		NUM_CPU_IRQS
+
+
+#ifdef CONFIG_ROM_KERNEL
+/* Kernel is in ROM, starting at address 0.  */
+
+#define INTV_BASE		0
+#define ROOT_FS_IMAGE_RW	0
+
+#else /* !CONFIG_ROM_KERNEL */
+
+/* It's in RAM anyway, so might as well allow writing to it.  */
+#define ROOT_FS_IMAGE_RW	1
+
+#ifdef CONFIG_RTE_CB_MULTI
+/* Using RAM kernel with ROM monitor for Multi debugger.  */
+
+/* The chip's real interrupt vectors are in ROM, but they jump to a
+   secondary interrupt vector table in RAM.  */
+#define INTV_BASE		0x004F8000
+
+/* Scratch memory used by the ROM monitor, which shouldn't be used by
+   linux (except for the alternate interrupt vector area, defined
+   above).  */
+#define MON_SCRATCH_ADDR	0x004F8000
+#define MON_SCRATCH_SIZE	0x00008000 /* 32KB */
+
+#else /* !CONFIG_RTE_CB_MULTI */
+/* Using RAM-kernel.  Assume some sort of boot-loader got us loaded at
+   address 0.  */
+
+#define INTV_BASE		0
+#define ROOT_FS_IMAGE_RW	1
+
+#endif /* CONFIG_RTE_CB_MULTI */
+
+#endif /* CONFIG_ROM_KERNEL */
+
+
+/* Some misc. on-board devices.  */
+
+/* Seven-segment LED display (two digits).  Write-only.  */
+#define LED_ADDR(n)		(0x07802000 + (n))
+#define LED(n)			(*(volatile unsigned char *)LED_ADDR(n))
+#define LED_NUM_DIGITS		2
+
+
+/* Override the basic MA uart pre-initialization so that we can
+   initialize extra stuff.  */
+#undef V850E_UART_PRE_CONFIGURE	/* should be defined by <asm/ma.h> */
+#define V850E_UART_PRE_CONFIGURE	rte_ma1_cb_uart_pre_configure
+#ifndef __ASSEMBLY__
+extern void rte_ma1_cb_uart_pre_configure (unsigned chan,
+					   unsigned cflags, unsigned baud);
+#endif
+
+/* This board supports RTS/CTS for the on-chip UART, but only for channel 0. */
+
+/* CTS for UART channel 0 is pin P43 (bit 3 of port 4).  */
+#define V850E_UART_CTS(chan)	((chan) == 0 ? !(MA_PORT4_IO & 0x8) : 1)
+/* RTS for UART channel 0 is pin P42 (bit 2 of port 4).  */
+#define V850E_UART_SET_RTS(chan, val)					      \
+   do {									      \
+	   if (chan == 0) {						      \
+		   unsigned old = MA_PORT4_IO; 				      \
+		   if (val)						      \
+			   MA_PORT4_IO = old & ~0x4;			      \
+		   else							      \
+			   MA_PORT4_IO = old | 0x4;			      \
+	   }								      \
+   } while (0)
+
+
+#endif /* __V850_RTE_MA1_CB_H__ */
diff -urN linux-2.4.29/include/asm-v850/rte_mb_a_pci.h linux-2.4.29-uc1/include/asm-v850/rte_mb_a_pci.h
--- linux-2.4.29/include/asm-v850/rte_mb_a_pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/rte_mb_a_pci.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,56 @@
+/*
+ * include/asm-v850/mb_a_pci.h -- PCI support for Midas lab RTE-MOTHER-A board
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_MB_A_PCI_H__
+#define __V850_MB_A_PCI_H__
+
+
+#define MB_A_PCI_MEM_ADDR	GCS5_ADDR
+#define MB_A_PCI_MEM_SIZE	(GCS5_SIZE / 2)
+#define MB_A_PCI_IO_ADDR	(GCS5_ADDR + MB_A_PCI_MEM_SIZE)
+#define MB_A_PCI_IO_SIZE	(GCS5_SIZE / 2)
+#define MB_A_PCI_REG_BASE_ADDR	GCS6_ADDR
+
+#define MB_A_PCI_PCICR_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0x4)
+#define MB_A_PCI_PCICR		(*(volatile u16 *)MB_A_PCI_PCICR_ADDR)
+#define MB_A_PCI_PCISR_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0x6)
+#define MB_A_PCI_PCISR		(*(volatile u16 *)MB_A_PCI_PCISR_ADDR)
+#define MB_A_PCI_PCILTR_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0xD)
+#define MB_A_PCI_PCILTR		(*(volatile u8 *)MB_A_PCI_PCILTR_ADDR)
+#define MB_A_PCI_PCIBAR0_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0x10)
+#define MB_A_PCI_PCIBAR0	(*(volatile u32 *)MB_A_PCI_PCIBAR0_ADDR)
+#define MB_A_PCI_PCIBAR1_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0x14)
+#define MB_A_PCI_PCIBAR1	(*(volatile u32 *)MB_A_PCI_PCIBAR1_ADDR)
+#define MB_A_PCI_PCIBAR2_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0x18)
+#define MB_A_PCI_PCIBAR2	(*(volatile u32 *)MB_A_PCI_PCIBAR2_ADDR)
+#define MB_A_PCI_VENDOR_ID_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0x2C)
+#define MB_A_PCI_VENDOR_ID	(*(volatile u16 *)MB_A_PCI_VENDOR_ID_ADDR)
+#define MB_A_PCI_DEVICE_ID_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0x2E)
+#define MB_A_PCI_DEVICE_ID	(*(volatile u16 *)MB_A_PCI_DEVICE_ID_ADDR)
+#define MB_A_PCI_DMRR_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0x9C)
+#define MB_A_PCI_DMRR		(*(volatile u32 *)MB_A_PCI_DMRR_ADDR)
+#define MB_A_PCI_DMLBAM_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0xA0)
+#define MB_A_PCI_DMLBAM		(*(volatile u32 *)MB_A_PCI_DMLBAM_ADDR)
+#define MB_A_PCI_DMLBAI_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0xA4)
+#define MB_A_PCI_DMLBAI		(*(volatile u32 *)MB_A_PCI_DMLBAI_ADDR)
+#define MB_A_PCI_PCIPBAM_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0xA8)
+#define MB_A_PCI_PCIPBAM	(*(volatile u32 *)MB_A_PCI_PCIPBAM_ADDR)
+/* `PCI Configuration Address Register for Direct Master to PCI IO/CFG'  */
+#define MB_A_PCI_DMCFGA_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0xAC)
+#define MB_A_PCI_DMCFGA		(*(volatile u32 *)MB_A_PCI_DMCFGA_ADDR)
+/* `PCI Permanent Configuration ID Register'  */
+#define MB_A_PCI_PCIHIDR_ADDR	(MB_A_PCI_REG_BASE_ADDR + 0xF0)
+#define MB_A_PCI_PCIHIDR	(*(volatile u32 *)MB_A_PCI_PCIHIDR_ADDR)
+
+
+#endif /* __V850_MB_A_PCI_H__ */
diff -urN linux-2.4.29/include/asm-v850/rte_me2_cb.h linux-2.4.29-uc1/include/asm-v850/rte_me2_cb.h
--- linux-2.4.29/include/asm-v850/rte_me2_cb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/rte_me2_cb.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,202 @@
+/*
+ * include/asm-v850/rte_me2_cb.h -- Midas labs RTE-V850E/ME2-CB board
+ *
+ *  Copyright (C) 2001,02,03  NEC Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_RTE_ME2_CB_H__
+#define __V850_RTE_ME2_CB_H__
+
+#include <asm/rte_cb.h>		/* Common defs for Midas RTE-CB boards.  */
+
+
+#define PLATFORM		"rte-v850e/me2-cb"
+#define PLATFORM_LONG		"Midas lab RTE-V850E/ME2-CB"
+
+#define CPU_CLOCK_FREQ		150000000 /* 150MHz */
+#define FIXED_BOGOMIPS		52.42
+
+/* 32MB of onbard SDRAM.  */
+#define SDRAM_ADDR		0x00800000
+#define SDRAM_SIZE		0x02000000 /* 32MB */
+
+
+/* CPU addresses of GBUS memory spaces.  */
+#define GCS0_ADDR		0x04000000 /* GCS0 - Common SRAM (2MB) */
+#define GCS0_SIZE		0x00800000 /*   8MB */
+#define GCS1_ADDR		0x04800000 /* GCS1 - Flash ROM (8MB) */
+#define GCS1_SIZE		0x00800000 /*   8MB */
+#define GCS2_ADDR		0x07000000 /* GCS2 - I/O registers */
+#define GCS2_SIZE		0x00800000 /*   8MB */
+#define GCS5_ADDR		0x08000000 /* GCS5 - PCI bus space */
+#define GCS5_SIZE		0x02000000 /*   32MB */
+#define GCS6_ADDR		0x07800000 /* GCS6 - PCI control registers */
+#define GCS6_SIZE		0x00800000 /*   8MB */
+
+
+/* For <asm/page.h> */
+#define PAGE_OFFSET 		SDRAM_ADDR
+
+
+#ifdef CONFIG_ROM_KERNEL
+/* Kernel is in ROM, starting at address 0.  */
+
+#define INTV_BASE		0
+#define ROOT_FS_IMAGE_RW	0
+
+#else /* !CONFIG_ROM_KERNEL */
+/* Using RAM-kernel.  Assume some sort of boot-loader got us loaded at
+   address 0.  */
+
+#define INTV_BASE		0
+#define ROOT_FS_IMAGE_RW	1
+
+#endif /* CONFIG_ROM_KERNEL */
+
+
+/* Some misc. on-board devices.  */
+
+/* Seven-segment LED display (four digits).  */
+#define LED_ADDR(n)		(0x0FE02000 + (n))
+#define LED(n)			(*(volatile unsigned char *)LED_ADDR(n))
+#define LED_NUM_DIGITS		4
+
+
+/* On-board PIC.  */
+
+#define CB_PIC_BASE_ADDR 	0x0FE04000
+
+#define CB_PIC_INT0M_ADDR 	(CB_PIC_BASE_ADDR + 0x00)
+#define CB_PIC_INT0M      	(*(volatile u16 *)CB_PIC_INT0M_ADDR)
+#define CB_PIC_INT1M_ADDR 	(CB_PIC_BASE_ADDR + 0x10)
+#define CB_PIC_INT1M      	(*(volatile u16 *)CB_PIC_INT1M_ADDR)
+#define CB_PIC_INTR_ADDR  	(CB_PIC_BASE_ADDR + 0x20)
+#define CB_PIC_INTR       	(*(volatile u16 *)CB_PIC_INTR_ADDR)
+#define CB_PIC_INTEN_ADDR 	(CB_PIC_BASE_ADDR + 0x30)
+#define CB_PIC_INTEN      	(*(volatile u16 *)CB_PIC_INTEN_ADDR)
+
+#define CB_PIC_INT0EN        	0x0001
+#define CB_PIC_INT1EN        	0x0002
+#define CB_PIC_INT0SEL       	0x0080
+
+/* The PIC interrupts themselves.  */
+#define CB_PIC_BASE_IRQ		NUM_CPU_IRQS
+#define IRQ_CB_PIC_NUM		10
+
+/* Some specific CB_PIC interrupts. */
+#define IRQ_CB_EXTTM0		(CB_PIC_BASE_IRQ + 0)
+#define IRQ_CB_EXTSIO		(CB_PIC_BASE_IRQ + 1)
+#define IRQ_CB_TOVER		(CB_PIC_BASE_IRQ + 2)
+#define IRQ_CB_GINT0		(CB_PIC_BASE_IRQ + 3)
+#define IRQ_CB_USB		(CB_PIC_BASE_IRQ + 4)
+#define IRQ_CB_LANC		(CB_PIC_BASE_IRQ + 5)
+#define IRQ_CB_USB_VBUS_ON	(CB_PIC_BASE_IRQ + 6)
+#define IRQ_CB_USB_VBUS_OFF	(CB_PIC_BASE_IRQ + 7)
+#define IRQ_CB_EXTTM1		(CB_PIC_BASE_IRQ + 8)
+#define IRQ_CB_EXTTM2		(CB_PIC_BASE_IRQ + 9)
+
+/* The GBUS GINT1 - GINT3 (note, not GINT0!) interrupts are connected to
+   the INTP65 - INTP67 pins on the CPU.  These are shared among the GBUS
+   interrupts.  */
+#define IRQ_GINT(n)		IRQ_INTP((n) + 9)  /* 0 is unused! */
+#define IRQ_GINT_NUM		4		   /* 0 is unused! */
+
+/* The shared interrupt line from the PIC is connected to CPU pin INTP23.  */
+#define IRQ_CB_PIC		IRQ_INTP(4) /* P23 */
+
+/* Used by <asm/rte_cb.h> to derive NUM_MACH_IRQS.  */
+#define NUM_RTE_CB_IRQS		(NUM_CPU_IRQS + IRQ_CB_PIC_NUM)
+
+
+#ifndef __ASSEMBLY__
+struct cb_pic_irq_init {
+	const char *name;	/* name of interrupt type */
+
+	/* Range of kernel irq numbers for this type:
+	   BASE, BASE+INTERVAL, ..., BASE+INTERVAL*NUM  */
+	unsigned base, num, interval;
+
+	unsigned priority;	/* interrupt priority to assign */
+};
+struct hw_interrupt_type;	/* fwd decl */
+
+/* Enable interrupt handling for interrupt IRQ.  */
+extern void cb_pic_enable_irq (unsigned irq);
+/* Disable interrupt handling for interrupt IRQ.  Note that any interrupts
+   received while disabled will be delivered once the interrupt is enabled
+   again, unless they are explicitly cleared using `cb_pic_clear_pending_irq'.  */
+extern void cb_pic_disable_irq (unsigned irq);
+/* Initialize HW_IRQ_TYPES for PIC irqs described in array INITS (which is
+   terminated by an entry with the name field == 0).  */
+extern void cb_pic_init_irq_types (struct cb_pic_irq_init *inits,
+				   struct hw_interrupt_type *hw_irq_types);
+/* Initialize PIC interrupts.  */
+extern void cb_pic_init_irqs (void);
+#endif /* __ASSEMBLY__ */
+
+
+/* TL16C550C on board UART see also asm/serial.h */
+#define CB_UART_BASE    	0x0FE08000
+#define CB_UART_REG_GAP 	0x10
+#define CB_UART_CLOCK   	0x16000000
+
+/* CompactFlash setting see also asm/ide.h, asm/hdreg.h.  */
+#define CB_CF_BASE     		0x0FE0C000
+#define CB_CF_CCR_ADDR 		(CB_CF_BASE+0x200)
+#define CB_CF_CCR      		(*(volatile u8 *)CB_CF_CCR_ADDR)
+#define CB_CF_REG0_ADDR		(CB_CF_BASE+0x1000)
+#define CB_CF_REG0     		(*(volatile u16 *)CB_CF_REG0_ADDR)
+#define CB_CF_STS0_ADDR		(CB_CF_BASE+0x1004)
+#define CB_CF_STS0     		(*(volatile u16 *)CB_CF_STS0_ADDR)
+#define CB_PCATA_BASE  		(CB_CF_BASE+0x800)
+#define CB_IDE_BASE    		(CB_CF_BASE+0x9F0)
+#define CB_IDE_CTRL    		(CB_CF_BASE+0xBF6)
+#define CB_IDE_REG_OFFS		0x1
+
+
+/* SMSC LAN91C111 setting */
+#if defined(CONFIG_SMC91111)
+#define CB_LANC_BASE 		0x0FE10300
+#define CONFIG_SMC16BITONLY
+#define ETH0_ADDR 		CB_LANC_BASE
+#define ETH0_IRQ 		IRQ_CB_LANC
+#endif /* CONFIG_SMC16BITONLY */
+
+
+#undef V850E_UART_PRE_CONFIGURE
+#define V850E_UART_PRE_CONFIGURE	rte_me2_cb_uart_pre_configure
+#ifndef __ASSEMBLY__
+extern void rte_me2_cb_uart_pre_configure (unsigned chan,
+					   unsigned cflags, unsigned baud);
+#endif /* __ASSEMBLY__ */
+
+/* This board supports RTS/CTS for the on-chip UART, but only for channel 0. */
+
+/* CTS for UART channel 0 is pin P22 (bit 2 of port 2).  */
+#define V850E_UART_CTS(chan)	((chan) == 0 ? !(ME2_PORT2_IO & 0x4) : 1)
+/* RTS for UART channel 0 is pin P21 (bit 1 of port 2).  */
+#define V850E_UART_SET_RTS(chan, val)					      \
+   do {									      \
+	   if (chan == 0) {						      \
+		   unsigned old = ME2_PORT2_IO; 			      \
+		   if (val)						      \
+			   ME2_PORT2_IO = old & ~0x2;			      \
+		   else							      \
+			   ME2_PORT2_IO = old | 0x2;			      \
+	   }								      \
+   } while (0)
+
+
+#ifndef __ASSEMBLY__
+extern void rte_me2_cb_init_irqs (void);
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_RTE_ME2_CB_H__ */
diff -urN linux-2.4.29/include/asm-v850/rte_nb85e_cb.h linux-2.4.29-uc1/include/asm-v850/rte_nb85e_cb.h
--- linux-2.4.29/include/asm-v850/rte_nb85e_cb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/rte_nb85e_cb.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,113 @@
+/*
+ * include/asm-v850/rte_nb85e_cb.h -- Midas labs RTE-V850/NB85E-CB board
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_RTE_NB85E_CB_H__
+#define __V850_RTE_NB85E_CB_H__
+
+#include <asm/rte_cb.h>		/* Common defs for Midas RTE-CB boards.  */
+
+
+#define PLATFORM		"rte-v850e/nb85e-cb"
+#define PLATFORM_LONG		"Midas lab RTE-V850E/NB85E-CB"
+
+#define CPU_CLOCK_FREQ		50000000 /* 50MHz */
+#define FIXED_BOGOMIPS		16.53	 /* Only valid for 2.4.x */
+
+/* 1MB of onboard SRAM.  Note that the monitor ROM uses parts of this
+   for its own purposes, so care must be taken.  */
+#define SRAM_ADDR		0x03C00000
+#define SRAM_SIZE		0x00100000 /* 1MB */
+
+/* 16MB of onbard SDRAM.  */
+#define SDRAM_ADDR		0x01000000
+#define SDRAM_SIZE		0x01000000 /* 16MB */
+
+
+/* CPU addresses of GBUS memory spaces.  */
+#define GCS0_ADDR		0x00400000 /* GCS0 - Common SRAM (2MB) */
+#define GCS0_SIZE		0x00400000 /*   4MB */
+#define GCS1_ADDR		0x02000000 /* GCS1 - Flash ROM (8MB) */
+#define GCS1_SIZE		0x00800000 /*   8MB */
+#define GCS2_ADDR		0x03900000 /* GCS2 - I/O registers */
+#define GCS2_SIZE		0x00080000 /*   512KB */
+#define GCS3_ADDR		0x02800000 /* GCS3 - EXT-bus: memory space */
+#define GCS3_SIZE		0x00800000 /*   8MB */
+#define GCS4_ADDR		0x03A00000 /* GCS4 - EXT-bus: I/O space */
+#define GCS4_SIZE		0x00200000 /*   2MB */
+#define GCS5_ADDR		0x00800000 /* GCS5 - PCI bus space */
+#define GCS5_SIZE		0x00800000 /*   8MB */
+#define GCS6_ADDR		0x03980000 /* GCS6 - PCI control registers */
+#define GCS6_SIZE		0x00010000 /*   64KB */
+
+
+/* The GBUS GINT0 - GINT3 interrupts are connected to CPU interrupts 10-12.
+   These are shared among the GBUS interrupts.  */
+#define IRQ_GINT(n)		(10 + (n))
+#define IRQ_GINT_NUM		3
+
+/* Used by <asm/rte_cb.h> to derive NUM_MACH_IRQS.  */
+#define NUM_RTE_CB_IRQS		NUM_CPU_IRQS
+
+
+#ifdef CONFIG_ROM_KERNEL
+/* Kernel is in ROM, starting at address 0.  */
+
+#define INTV_BASE		0
+#define ROOT_FS_IMAGE_RW	0
+
+#else /* !CONFIG_ROM_KERNEL */
+/* We're using the ROM monitor.  */
+
+/* The chip's real interrupt vectors are in ROM, but they jump to a
+   secondary interrupt vector table in RAM.  */
+#define INTV_BASE		0x03CF8000
+
+/* Scratch memory used by the ROM monitor, which shouldn't be used by
+   linux (except for the alternate interrupt vector area, defined
+   above).  */
+#define MON_SCRATCH_ADDR	0x03CE8000
+#define MON_SCRATCH_SIZE	0x00018000 /* 96KB */
+
+#endif /* CONFIG_ROM_KERNEL */
+
+
+/* Some misc. on-board devices.  */
+
+/* Seven-segment LED display (two digits).  Write-only.  */
+#define LED_ADDR(n)	(0x03802000 + (n))
+#define LED(n)		(*(volatile unsigned char *)LED_ADDR(n))
+#define LED_NUM_DIGITS	4
+
+
+/* Override the basic TEG UART pre-initialization so that we can
+   initialize extra stuff.  */
+#undef V850E_UART_PRE_CONFIGURE	/* should be defined by <asm/teg.h> */
+#define V850E_UART_PRE_CONFIGURE	rte_nb85e_cb_uart_pre_configure
+#ifndef __ASSEMBLY__
+extern void rte_nb85e_cb_uart_pre_configure (unsigned chan,
+					     unsigned cflags, unsigned baud);
+#endif
+
+/* This board supports RTS/CTS for the on-chip UART. */
+
+/* CTS is pin P00.  */
+#define V850E_UART_CTS(chan)	(! (TEG_PORT0_IO & 0x1))
+/* RTS is pin P02.  */
+#define V850E_UART_SET_RTS(chan, val)					      \
+   do {									      \
+	   unsigned old = TEG_PORT0_IO;					      \
+	   TEG_PORT0_IO = val ? (old & ~0x4) : (old | 0x4);		      \
+   } while (0)
+
+
+#endif /* __V850_RTE_NB85E_CB_H__ */
diff -urN linux-2.4.29/include/asm-v850/segment.h linux-2.4.29-uc1/include/asm-v850/segment.h
--- linux-2.4.29/include/asm-v850/segment.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/segment.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,36 @@
+#ifndef __V850_SEGMENT_H__
+#define __V850_SEGMENT_H__
+
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long mm_segment_t;	/* domain register */
+
+#endif /* !__ASSEMBLY__ */
+
+
+#define __KERNEL_CS	0x0
+#define __KERNEL_DS	0x0
+
+#define __USER_CS	0x1
+#define __USER_DS	0x1
+
+#define KERNEL_DS	__KERNEL_DS
+#define KERNEL_CS	__KERNEL_CS
+#define USER_DS		__USER_DS
+#define USER_CS		__USER_CS
+
+#define segment_eq(a,b)	((a) == (b))
+
+#define get_ds()	(KERNEL_DS)
+#define get_fs()	(USER_DS)
+
+#define set_fs(seg)	((void)(seg))
+
+
+#define copy_segments(task, mm)	((void)((void)(task), (mm)))
+#define release_segments(mm)	((void)(mm))
+#define forget_segments()	((void)0)
+
+
+#endif /* __V850_SEGMENT_H__ */
diff -urN linux-2.4.29/include/asm-v850/semaphore.h linux-2.4.29-uc1/include/asm-v850/semaphore.h
--- linux-2.4.29/include/asm-v850/semaphore.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/semaphore.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,91 @@
+#ifndef __V850_SEMAPHORE_H__
+#define __V850_SEMAPHORE_H__
+
+#include <linux/linkage.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/rwsem.h>
+
+#include <asm/atomic.h>
+
+struct semaphore {
+	atomic_t count;
+	int sleepers;
+	wait_queue_head_t wait;
+};
+
+#define __SEMAPHORE_INITIALIZER(name,count)				      \
+	{ ATOMIC_INIT (count), 0,					      \
+	  __WAIT_QUEUE_HEAD_INITIALIZER ((name).wait) }
+
+#define __MUTEX_INITIALIZER(name)					      \
+	__SEMAPHORE_INITIALIZER (name,1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count)	\
+	struct semaphore name = __SEMAPHORE_INITIALIZER (name,count)
+
+#define DECLARE_MUTEX(name)		__DECLARE_SEMAPHORE_GENERIC (name,1)
+#define DECLARE_MUTEX_LOCKED(name)	__DECLARE_SEMAPHORE_GENERIC (name,0)
+
+extern inline void sema_init (struct semaphore *sem, int val)
+{
+	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
+}
+
+static inline void init_MUTEX (struct semaphore *sem)
+{
+	sema_init (sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+{
+	sema_init (sem, 0);
+}
+
+/*
+ * special register calling convention
+ */
+asmlinkage void __down_failed (void);
+asmlinkage int  __down_interruptible_failed (void);
+asmlinkage int  __down_trylock_failed (void);
+asmlinkage void __up_wakeup (void);
+
+extern void __down (struct semaphore * sem);
+extern int  __down_interruptible (struct semaphore * sem);
+extern int  __down_trylock (struct semaphore * sem);
+extern void __up (struct semaphore * sem);
+
+extern inline void down (struct semaphore * sem)
+{
+	if (atomic_dec_return (&sem->count) < 0)
+		__down (sem);
+}
+
+extern inline int down_interruptible (struct semaphore * sem)
+{
+	int ret = 0;
+	if (atomic_dec_return (&sem->count) < 0)
+		ret = __down_interruptible (sem);
+	return ret;
+}
+
+extern inline int down_trylock (struct semaphore *sem)
+{
+	int ret = 0;
+	if (atomic_dec_return (&sem->count) < 0)
+		ret = __down_trylock (sem);
+	return ret;
+}
+
+extern inline void up (struct semaphore * sem)
+{
+	if (atomic_inc_return (&sem->count) <= 0)
+		__up (sem);
+}
+
+static inline int sem_getcount(struct semaphore *sem)
+{
+	return atomic_read(&sem->count);
+}
+
+#endif /* __V850_SEMAPHORE_H__ */
diff -urN linux-2.4.29/include/asm-v850/sembuf.h linux-2.4.29-uc1/include/asm-v850/sembuf.h
--- linux-2.4.29/include/asm-v850/sembuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/sembuf.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef __V850_SEMBUF_H__
+#define __V850_SEMBUF_H__
+
+/* 
+ * The semid64_ds structure for v850 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
+	__kernel_time_t	sem_otime;		/* last semop time */
+	unsigned long	__unused1;
+	__kernel_time_t	sem_ctime;		/* last change time */
+	unsigned long	__unused2;
+	unsigned long	sem_nsems;		/* no. of semaphores in array */
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* __V850_SEMBUF_H__ */
diff -urN linux-2.4.29/include/asm-v850/serial.h linux-2.4.29-uc1/include/asm-v850/serial.h
--- linux-2.4.29/include/asm-v850/serial.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/serial.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,58 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */ 
+#include <linux/config.h>
+
+#ifdef CONFIG_RTE_CB_ME2
+
+#include <asm/rte_me2_cb.h>
+
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+#define irq_cannonicalize(x) (x)
+#define BASE_BAUD	250000	/* (16MHz / (16 * 38400)) * 9600 */
+#define RS_TABLE_SIZE	1
+#define SERIAL_PORT_DFNS \
+   { 0, BASE_BAUD, CB_UART_BASE, IRQ_CB_EXTSIO, STD_COM_FLAGS },
+
+/* Redefine UART register offsets.  */
+#undef UART_RX
+#undef UART_TX
+#undef UART_DLL
+#undef UART_TRG
+#undef UART_DLM
+#undef UART_IER
+#undef UART_FCTR
+#undef UART_IIR
+#undef UART_FCR
+#undef UART_EFR
+#undef UART_LCR
+#undef UART_MCR
+#undef UART_LSR
+#undef UART_MSR
+#undef UART_SCR
+#undef UART_EMSR
+
+#define UART_RX		(0 * CB_UART_REG_GAP)
+#define UART_TX		(0 * CB_UART_REG_GAP)
+#define UART_DLL	(0 * CB_UART_REG_GAP)
+#define UART_TRG	(0 * CB_UART_REG_GAP)
+#define UART_DLM	(1 * CB_UART_REG_GAP)
+#define UART_IER	(1 * CB_UART_REG_GAP)
+#define UART_FCTR	(1 * CB_UART_REG_GAP)
+#define UART_IIR	(2 * CB_UART_REG_GAP)
+#define UART_FCR	(2 * CB_UART_REG_GAP)
+#define UART_EFR	(2 * CB_UART_REG_GAP)
+#define UART_LCR	(3 * CB_UART_REG_GAP)
+#define UART_MCR	(4 * CB_UART_REG_GAP)
+#define UART_LSR	(5 * CB_UART_REG_GAP)
+#define UART_MSR	(6 * CB_UART_REG_GAP)
+#define UART_SCR	(7 * CB_UART_REG_GAP)
+#define UART_EMSR	(7 * CB_UART_REG_GAP)
+
+#endif /* CONFIG_RTE_CB_ME2 */
diff -urN linux-2.4.29/include/asm-v850/shmbuf.h linux-2.4.29-uc1/include/asm-v850/shmbuf.h
--- linux-2.4.29/include/asm-v850/shmbuf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/shmbuf.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,42 @@
+#ifndef __V850_SHMBUF_H__
+#define __V850_SHMBUF_H__
+
+/* 
+ * The shmid64_ds structure for v850 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	unsigned long		__unused1;
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	unsigned long		__unused2;
+	__kernel_time_t		shm_ctime;	/* last change time */
+	unsigned long		__unused3;
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* __V850_SHMBUF_H__ */
diff -urN linux-2.4.29/include/asm-v850/shmparam.h linux-2.4.29-uc1/include/asm-v850/shmparam.h
--- linux-2.4.29/include/asm-v850/shmparam.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/shmparam.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef __V850_SHMPARAM_H__
+#define __V850_SHMPARAM_H__
+
+#define	SHMLBA		PAGE_SIZE	/* attach addr a multiple of this */
+
+#endif /* __V850_SHMPARAM_H__ */
diff -urN linux-2.4.29/include/asm-v850/sigcontext.h linux-2.4.29-uc1/include/asm-v850/sigcontext.h
--- linux-2.4.29/include/asm-v850/sigcontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/sigcontext.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ * include/asm-v850/sigcontext.h -- Signal contexts
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_SIGCONTEXT_H__
+#define __V850_SIGCONTEXT_H__
+
+#include <asm/ptrace.h>
+
+struct sigcontext
+{
+	struct pt_regs 	regs;
+	unsigned long	oldmask;
+};
+
+#endif /* __V850_SIGCONTEXT_H__ */
diff -urN linux-2.4.29/include/asm-v850/siginfo.h linux-2.4.29-uc1/include/asm-v850/siginfo.h
--- linux-2.4.29/include/asm-v850/siginfo.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/siginfo.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,243 @@
+#ifndef __V850_SIGINFO_H__
+#define __V850_SIGINFO_H__
+
+#include <linux/types.h>
+
+/* This is copied from asm-alpha/siginfo.h.  */
+
+typedef union sigval {
+	int sival_int;
+	void *sival_ptr;
+} sigval_t;
+
+#define SI_MAX_SIZE	128
+#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct siginfo {
+	int si_signo;
+	int si_errno;
+	int si_code;
+
+	union {
+		int _pad[SI_PAD_SIZE];
+
+		/* kill() */
+		struct {
+			__kernel_pid_t _pid;	/* sender's pid */
+			__kernel_uid_t _uid;	/* backwards compatibility */
+			__kernel_uid32_t _uid32; /* sender's uid */
+		} _kill;
+
+		/* POSIX.1b timers */
+		struct {
+			unsigned int _timer1;
+			unsigned int _timer2;
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			__kernel_pid_t _pid;	/* sender's pid */
+			__kernel_uid_t _uid;	/* backwards compatibility */
+			sigval_t _sigval;
+			__kernel_uid32_t _uid32; /* sender's uid */
+		} _rt;
+
+		/* SIGCHLD */
+		struct {
+			__kernel_pid_t _pid;	/* which child */
+			__kernel_uid_t _uid;	/* backwards compatibility */
+			int _status;		/* exit code */
+			clock_t _utime;
+			clock_t _stime;
+			__kernel_uid32_t _uid32; /* sender's uid */
+		} _sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			void *_addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+	} _sifields;
+} siginfo_t;
+
+#define UID16_SIGINFO_COMPAT_NEEDED
+
+/*
+ * How these fields are to be accessed.
+ */
+#define si_pid		_sifields._kill._pid
+#ifdef __KERNEL__
+#define si_uid		_sifields._kill._uid32
+#define si_uid16	_sifields._kill._uid
+#else
+#define si_uid		_sifields._kill._uid
+#endif /* __KERNEL__ */
+#define si_status	_sifields._sigchld._status
+#define si_utime	_sifields._sigchld._utime
+#define si_stime	_sifields._sigchld._stime
+#define si_value	_sifields._rt._sigval
+#define si_int		_sifields._rt._sigval.sival_int
+#define si_ptr		_sifields._rt._sigval.sival_ptr
+#define si_addr		_sifields._sigfault._addr
+#define si_band		_sifields._sigpoll._band
+#define si_fd		_sifields._sigpoll._fd
+
+#ifdef __KERNEL__
+#define __SI_MASK	0xffff0000
+#define __SI_KILL	(0 << 16)
+#define __SI_TIMER	(1 << 16)
+#define __SI_POLL	(2 << 16)
+#define __SI_FAULT	(3 << 16)
+#define __SI_CHLD	(4 << 16)
+#define __SI_RT		(5 << 16)
+#define __SI_CODE(T,N)	((T) << 16 | ((N) & 0xffff))
+#else
+#define __SI_KILL	0
+#define __SI_TIMER	0
+#define __SI_POLL	0
+#define __SI_FAULT	0
+#define __SI_CHLD	0
+#define __SI_RT		0
+#define __SI_CODE(T,N)	(N)
+#endif
+
+/*
+ * si_code values
+ * Digital reserves positive values for kernel-generated signals.
+ */
+#define SI_USER		0		/* sent by kill, sigsend, raise */
+#define SI_KERNEL	0x80		/* sent by the kernel from somewhere */
+#define SI_QUEUE	-1		/* sent by sigqueue */
+#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
+#define SI_MESGQ	-3		/* sent by real time mesq state change */
+#define SI_ASYNCIO	-4		/* sent by AIO completion */
+#define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
+
+#define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
+#define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
+
+/*
+ * SIGILL si_codes
+ */
+#define ILL_ILLOPC	(__SI_FAULT|1)	/* illegal opcode */
+#define ILL_ILLOPN	(__SI_FAULT|2)	/* illegal operand */
+#define ILL_ILLADR	(__SI_FAULT|3)	/* illegal addressing mode */
+#define ILL_ILLTRP	(__SI_FAULT|4)	/* illegal trap */
+#define ILL_PRVOPC	(__SI_FAULT|5)	/* privileged opcode */
+#define ILL_PRVREG	(__SI_FAULT|6)	/* privileged register */
+#define ILL_COPROC	(__SI_FAULT|7)	/* coprocessor error */
+#define ILL_BADSTK	(__SI_FAULT|8)	/* internal stack error */
+#define NSIGILL		8
+
+/*
+ * SIGFPE si_codes
+ */
+#define FPE_INTDIV	(__SI_FAULT|1)	/* integer divide by zero */
+#define FPE_INTOVF	(__SI_FAULT|2)	/* integer overflow */
+#define FPE_FLTDIV	(__SI_FAULT|3)	/* floating point divide by zero */
+#define FPE_FLTOVF	(__SI_FAULT|4)	/* floating point overflow */
+#define FPE_FLTUND	(__SI_FAULT|5)	/* floating point underflow */
+#define FPE_FLTRES	(__SI_FAULT|6)	/* floating point inexact result */
+#define FPE_FLTINV	(__SI_FAULT|7)	/* floating point invalid operation */
+#define FPE_FLTSUB	(__SI_FAULT|8)	/* subscript out of range */
+#define NSIGFPE		8
+
+/*
+ * SIGSEGV si_codes
+ */
+#define SEGV_MAPERR	(__SI_FAULT|1)	/* address not mapped to object */
+#define SEGV_ACCERR	(__SI_FAULT|2)	/* invalid permissions for mapped object */
+#define NSIGSEGV	2
+
+/*
+ * SIGBUS si_codes
+ */
+#define BUS_ADRALN	(__SI_FAULT|1)	/* invalid address alignment */
+#define BUS_ADRERR	(__SI_FAULT|2)	/* non-existant physical address */
+#define BUS_OBJERR	(__SI_FAULT|3)	/* object specific hardware error */
+#define NSIGBUS		3
+
+/*
+ * SIGTRAP si_codes
+ */
+#define TRAP_BRKPT	(__SI_FAULT|1)	/* process breakpoint */
+#define TRAP_TRACE	(__SI_FAULT|2)	/* process trace trap */
+#define NSIGTRAP	2
+
+/*
+ * SIGCHLD si_codes
+ */
+#define CLD_EXITED	(__SI_CHLD|1)	/* child has exited */
+#define CLD_KILLED	(__SI_CHLD|2)	/* child was killed */
+#define CLD_DUMPED	(__SI_CHLD|3)	/* child terminated abnormally */
+#define CLD_TRAPPED	(__SI_CHLD|4)	/* traced child has trapped */
+#define CLD_STOPPED	(__SI_CHLD|5)	/* child has stopped */
+#define CLD_CONTINUED	(__SI_CHLD|6)	/* stopped child has continued */
+#define NSIGCHLD	6
+
+/*
+ * SIGPOLL si_codes
+ */
+#define POLL_IN		(__SI_POLL|1)	/* data input available */
+#define POLL_OUT	(__SI_POLL|2)	/* output buffers available */
+#define POLL_MSG	(__SI_POLL|3)	/* input message available */
+#define POLL_ERR	(__SI_POLL|4)	/* i/o error */
+#define POLL_PRI	(__SI_POLL|5)	/* high priority input available */
+#define POLL_HUP	(__SI_POLL|6)	/* device disconnected */
+#define NSIGPOLL	6
+
+/*
+ * sigevent definitions
+ * 
+ * It seems likely that SIGEV_THREAD will have to be handled from 
+ * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
+ * thread manager then catches and does the appropriate nonsense.
+ * However, everything is written out here so as to not get lost.
+ */
+#define SIGEV_SIGNAL	0	/* notify via signal */
+#define SIGEV_NONE	1	/* other notification: meaningless */
+#define SIGEV_THREAD	2	/* deliver via thread creation */
+
+#define SIGEV_MAX_SIZE	64
+#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct sigevent {
+	sigval_t sigev_value;
+	int sigev_signo;
+	int sigev_notify;
+	union {
+		int _pad[SIGEV_PAD_SIZE];
+
+		struct {
+			void (*_function)(sigval_t);
+			void *_attribute;	/* really pthread_attr_t */
+		} _sigev_thread;
+	} _sigev_un;
+} sigevent_t;
+
+#define sigev_notify_function	_sigev_un._sigev_thread._function
+#define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
+
+#ifdef __KERNEL__
+#include <linux/string.h>
+
+extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
+{
+	if (from->si_code < 0)
+		memcpy(to, from, sizeof(siginfo_t));
+	else
+		/* _sigchld is currently the largest know union member */
+		memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
+}
+
+extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
+
+#endif /* __KERNEL__ */
+
+#endif /* __V850_SIGINFO_H__ */
diff -urN linux-2.4.29/include/asm-v850/signal.h linux-2.4.29-uc1/include/asm-v850/signal.h
--- linux-2.4.29/include/asm-v850/signal.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/signal.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,193 @@
+#ifndef __V850_SIGNAL_H__
+#define __V850_SIGNAL_H__
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+
+#ifdef __KERNEL__
+
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else /* !__KERNEL__ */
+
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
+
+#define SA_RESTORER	0x04000000
+
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+
+#ifdef __KERNEL__
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE		SA_ONESHOT
+#define SA_SAMPLE_RANDOM	SA_RESTART
+#define SA_SHIRQ		0x04000000
+#endif /* __KERNEL__ */
+
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+
+#ifdef __KERNEL__
+
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+
+#else /* !__KERNEL__ */
+
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+
+#include <asm/sigcontext.h>
+#undef __HAVE_ARCH_SIG_BITOPS
+
+#endif /* __KERNEL__ */
+
+#endif /* __V850_SIGNAL_H__ */
diff -urN linux-2.4.29/include/asm-v850/sim85e2c.h linux-2.4.29-uc1/include/asm-v850/sim85e2c.h
--- linux-2.4.29/include/asm-v850/sim85e2c.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/sim85e2c.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,26 @@
+/*
+ * include/asm-v850/sim85e2c.h -- Machine-dependent defs for
+ *	V850E2 RTL simulator
+ *
+ *  Copyright (C) 2002,03  NEC Electronics Corporation
+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_SIM85E2C_H__
+#define __V850_SIM85E2C_H__
+
+/* Use generic sim85e2 settings, other than the various names.  */
+#include <asm/sim85e2.h>
+
+#define CPU_MODEL	"v850e2"
+#define CPU_MODEL_LONG	"NEC V850E2"
+#define PLATFORM	"sim85e2c"
+#define PLATFORM_LONG	"SIM85E2C V850E2 simulator"
+
+#endif /* __V850_SIM85E2C_H__ */
diff -urN linux-2.4.29/include/asm-v850/sim85e2.h linux-2.4.29-uc1/include/asm-v850/sim85e2.h
--- linux-2.4.29/include/asm-v850/sim85e2.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/sim85e2.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,75 @@
+/*
+ * include/asm-v850/sim85e2.h -- Machine-dependent defs for
+ *	V850E2 RTL simulator
+ *
+ *  Copyright (C) 2002,03  NEC Electronics Corporation
+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_SIM85E2_H__
+#define __V850_SIM85E2_H__
+
+
+#include <asm/v850e2.h>		/* Based on V850E2 core.  */
+
+
+/* Various memory areas supported by the simulator.
+   These should match the corresponding definitions in the linker script.  */
+
+/* `instruction RAM'; instruction fetches are much faster from IRAM than
+   from DRAM.  */
+#define IRAM_ADDR		0
+#define IRAM_SIZE		0x00100000 /* 1MB */
+/* `data RAM', below and contiguous with the I/O space.
+   Data fetches are much faster from DRAM than from IRAM.  */
+#define DRAM_ADDR		0xfff00000
+#define DRAM_SIZE		0x000ff000 /* 1020KB */
+/* `external ram'.  Unlike the above RAM areas, this memory is cached,
+   so both instruction and data fetches should be (mostly) fast --
+   however, currently only write-through caching is supported, so writes
+   to ERAM will be slow.  */
+#define ERAM_ADDR		0x00100000
+#define ERAM_SIZE		0x07f00000 /* 127MB (max) */
+/* Dynamic RAM; uses memory controller.  */
+#define SDRAM_ADDR		0x10000000
+#define SDRAM_SIZE		0x01000000 /* 16MB */
+
+
+/* Simulator specific control registers.  */
+/* NOTHAL controls whether the simulator will stop at a `halt' insn.  */
+#define SIM85E2_NOTHAL_ADDR	0xffffff22
+#define SIM85E2_NOTHAL		(*(volatile u8 *)SIM85E2_NOTHAL_ADDR)
+/* The simulator will stop N cycles after N is written to SIMFIN.  */
+#define SIM85E2_SIMFIN_ADDR	0xffffff24
+#define SIM85E2_SIMFIN		(*(volatile u16 *)SIM85E2_SIMFIN_ADDR)
+
+
+/* For <asm/irq.h> */
+#define NUM_CPU_IRQS		64
+
+
+/* For <asm/page.h> */
+#define PAGE_OFFSET		SDRAM_ADDR
+
+
+/* For <asm/entry.h> */
+/* `R0 RAM', used for a few miscellaneous variables that must be accessible
+   using a load instruction relative to R0.  The sim85e2 simulator
+   actually puts 1020K of RAM from FFF00000 to FFFFF000, so we arbitarily
+   choose a small portion at the end of that.  */
+#define R0_RAM_ADDR		0xFFFFE000
+
+
+/* For <asm/param.h> */
+#ifndef HZ
+#define HZ			24	/* Minimum supported frequency.  */
+#endif
+
+
+#endif /* __V850_SIM85E2_H__ */
diff -urN linux-2.4.29/include/asm-v850/sim85e2s.h linux-2.4.29-uc1/include/asm-v850/sim85e2s.h
--- linux-2.4.29/include/asm-v850/sim85e2s.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/sim85e2s.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ * include/asm-v850/sim85e2s.h -- Machine-dependent defs for
+ *	V850E2 RTL simulator
+ *
+ *  Copyright (C) 2003  NEC Electronics Corporation
+ *  Copyright (C) 2003  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_SIM85E2S_H__
+#define __V850_SIM85E2S_H__
+
+#include <asm/sim85e2.h>	/* Use generic sim85e2 settings.  */
+#if 0
+#include <asm/v850e2_cache.h>	/* + cache */
+#endif
+
+#define CPU_MODEL	"v850e2"
+#define CPU_MODEL_LONG	"NEC V850E2"
+#define PLATFORM	"sim85e2s"
+#define PLATFORM_LONG	"SIM85E2S V850E2 simulator"
+
+#endif /* __V850_SIM85E2S_H__ */
diff -urN linux-2.4.29/include/asm-v850/sim.h linux-2.4.29-uc1/include/asm-v850/sim.h
--- linux-2.4.29/include/asm-v850/sim.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/sim.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,75 @@
+/*
+ * include/asm-v850/sim.h -- Machine-dependent defs for GDB v850e simulator
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_SIM_H__
+#define __V850_SIM_H__
+
+
+#define CPU_ARCH		"v850e"
+#define CPU_MODEL		"v850e"
+#define CPU_MODEL_LONG		"NEC V850E"
+#define PLATFORM		"gdb/v850e"
+#define PLATFORM_LONG		"GDB V850E simulator"
+
+
+/* Though it varies based on the speed of the host processor, the bogomips
+   value on the simulator is basically always completely wrong anyway, and
+   fixing it allows faster startup.  */
+#define FIXED_BOGOMIPS		13
+
+
+/* We use a weird value for RAM, not just 0, for testing purposes.
+   These must match the values used in the linker script.  */
+#define RAM_ADDR		0x8F000000
+#define RAM_SIZE		0x03000000
+
+
+/* For <asm/page.h> */
+#define PAGE_OFFSET 		RAM_ADDR
+
+
+/* For <asm/entry.h> */
+/* `R0 RAM', used for a few miscellaneous variables that must be
+   accessible using a load instruction relative to R0.  On real
+   processors, this usually is on-chip RAM, but here we just
+   choose an arbitrary address that meets the above constraint.  */
+#define R0_RAM_ADDR		0xFFFFF000
+
+
+/* For <asm/param.h> */
+#ifndef HZ
+#define HZ			24	/* Minimum supported frequency.  */
+#endif
+
+/* For <asm/irq.h> */
+#define NUM_CPU_IRQS		6
+
+
+#ifndef __ASSEMBLY__
+
+/* For <asm/blkmem.h> */
+/* This gives us a single arena.  */
+#define CAT_ROMARRAY
+/* These should be defined by sim startup.  */
+extern unsigned long root_fs_image_addr, root_fs_image_len;
+extern int root_fs_image_rw;
+/* Make the single arena point use them.  */
+#define FIXUP_ARENAS							      \
+        arena[0].rw = root_fs_image_rw;					      \
+	arena[0].address = root_fs_image_addr;				      \
+	arena[0].length = root_fs_image_len;
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_SIM_H__ */
diff -urN linux-2.4.29/include/asm-v850/simsyscall.h linux-2.4.29-uc1/include/asm-v850/simsyscall.h
--- linux-2.4.29/include/asm-v850/simsyscall.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/simsyscall.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,99 @@
+/*
+ * include/asm-v850/simsyscall.h -- `System calls' under the v850e emulator
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_SIMSYSCALL_H__
+#define __V850_SIMSYSCALL_H__
+
+#define V850_SIM_SYS_exit(a...)		V850_SIM_SYSCALL_1 (1	, ##a)
+#define V850_SIM_SYS_fork(a...)		V850_SIM_SYSCALL_0 (2	, ##a)
+#define V850_SIM_SYS_read(a...)		V850_SIM_SYSCALL_3 (3	, ##a)
+#define V850_SIM_SYS_write(a...)	V850_SIM_SYSCALL_3 (4	, ##a)
+#define V850_SIM_SYS_open(a...)		V850_SIM_SYSCALL_2 (5	, ##a)
+#define V850_SIM_SYS_close(a...)	V850_SIM_SYSCALL_1 (6	, ##a)
+#define V850_SIM_SYS_wait4(a...)	V850_SIM_SYSCALL_4 (7	, ##a)
+/* #define V850_SIM_SYS_creat(a...)	V850_SIM_SYSCALL_1 (8	, ##a) */
+/* #define V850_SIM_SYS_link(a...)	V850_SIM_SYSCALL_1 (9	, ##a) */
+/* #define V850_SIM_SYS_unlink(a...)	V850_SIM_SYSCALL_1 (10	, ##a) */
+#define V850_SIM_SYS_execv(a...)	V850_SIM_SYSCALL_2 (11	, ##a)
+/* #define V850_SIM_SYS_chdir(a...)	V850_SIM_SYSCALL_1 (12	, ##a) */
+/* #define V850_SIM_SYS_mknod(a...)	V850_SIM_SYSCALL_1 (14	, ##a) */
+#define V850_SIM_SYS_chmod(a...)	V850_SIM_SYSCALL_2 (15	, ##a)
+#define V850_SIM_SYS_chown(a...)	V850_SIM_SYSCALL_2 (16	, ##a)
+#define V850_SIM_SYS_lseek(a...)	V850_SIM_SYSCALL_3 (19	, ##a)
+/* #define V850_SIM_SYS_getpid(a...)	V850_SIM_SYSCALL_1 (20	, ##a) */
+/* #define V850_SIM_SYS_isatty(a...)	V850_SIM_SYSCALL_1 (21	, ##a) */
+/* #define V850_SIM_SYS_fstat(a...)	V850_SIM_SYSCALL_1 (22	, ##a) */
+#define V850_SIM_SYS_time(a...)		V850_SIM_SYSCALL_1 (23	, ##a)
+#define V850_SIM_SYS_poll(a...)		V850_SIM_SYSCALL_3 (24	, ##a)
+#define V850_SIM_SYS_stat(a...)		V850_SIM_SYSCALL_2 (38	, ##a)
+#define V850_SIM_SYS_pipe(a...)		V850_SIM_SYSCALL_1 (42	, ##a)
+#define V850_SIM_SYS_times(a...)	V850_SIM_SYSCALL_1 (43	, ##a)
+#define V850_SIM_SYS_execve(a...)	V850_SIM_SYSCALL_3 (59	, ##a)
+#define V850_SIM_SYS_gettimeofday(a...)	V850_SIM_SYSCALL_2 (116	, ##a)
+/* #define V850_SIM_SYS_utime(a...)	V850_SIM_SYSCALL_2 (201	, ##a) */
+/* #define V850_SIM_SYS_wait(a...)	V850_SIM_SYSCALL_1 (202	, ##a) */
+
+#define V850_SIM_SYS_make_raw(a...)	V850_SIM_SYSCALL_1 (1024 , ##a)
+
+
+#define V850_SIM_SYSCALL_0(_call)					      \
+({									      \
+	register int call __asm__ ("r6") = _call;			      \
+	register int rval __asm__ ("r10");				      \
+	__asm__ __volatile__ ("trap 31"					      \
+			      : "=r" (rval)				      \
+			      : "r" (call)				      \
+			      : "r11", "memory");			      \
+	rval;								      \
+})
+#define V850_SIM_SYSCALL_1(_call, _arg0)				      \
+({									      \
+	register int call __asm__ ("r6") = _call;			      \
+	register long arg0 __asm__ ("r7") = (long)_arg0;		      \
+	register int rval __asm__ ("r10");				      \
+	__asm__ __volatile__ ("trap 31"					      \
+			      : "=r" (rval)				      \
+			      : "r" (call), "r" (arg0)			      \
+			      : "r11", "memory");			      \
+	rval;								      \
+})
+#define V850_SIM_SYSCALL_2(_call, _arg0, _arg1)				      \
+({									      \
+	register int call __asm__ ("r6") = _call;			      \
+	register long arg0 __asm__ ("r7") = (long)_arg0;		      \
+	register long arg1 __asm__ ("r8") = (long)_arg1;		      \
+	register int rval __asm__ ("r10");				      \
+	__asm__ __volatile__ ("trap 31"					      \
+			      : "=r" (rval)				      \
+			      : "r" (call), "r" (arg0), "r" (arg1)	      \
+			      : "r11", "memory");			      \
+	rval;								      \
+})
+#define V850_SIM_SYSCALL_3(_call, _arg0, _arg1, _arg2)			      \
+({									      \
+	register int call __asm__ ("r6") = _call;			      \
+	register long arg0 __asm__ ("r7") = (long)_arg0;		      \
+	register long arg1 __asm__ ("r8") = (long)_arg1;		      \
+	register long arg2 __asm__ ("r9") = (long)_arg2;		      \
+	register int rval __asm__ ("r10");				      \
+	__asm__ __volatile__ ("trap 31"					      \
+			      : "=r" (rval)				      \
+			      : "r" (call), "r" (arg0), "r" (arg1), "r" (arg2)\
+			      : "r11", "memory");			      \
+	rval;								      \
+})
+
+#define V850_SIM_SYSCALL(call, args...) \
+   V850_SIM_SYS_##call (args)
+
+#endif /* __V850_SIMSYSCALL_H__ */
diff -urN linux-2.4.29/include/asm-v850/socket.h linux-2.4.29-uc1/include/asm-v850/socket.h
--- linux-2.4.29/include/asm-v850/socket.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/socket.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,64 @@
+#ifndef __V850_SOCKET_H__
+#define __V850_SOCKET_H__
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED	16
+#define SO_PEERCRED	17
+#define SO_RCVLOWAT	18
+#define SO_SNDLOWAT	19
+#define SO_RCVTIMEO	20
+#define SO_SNDTIMEO	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE	25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME             28
+#define SO_TIMESTAMP		29
+#define SCM_TIMESTAMP		SO_TIMESTAMP
+
+#define SO_ACCEPTCONN		30
+
+/* Nast libc5 fixup - bletch */
+#if defined(__KERNEL__)
+/* Socket types. */
+#define SOCK_STREAM	1		/* stream (connection) socket	*/
+#define SOCK_DGRAM	2		/* datagram (conn.less) socket	*/
+#define SOCK_RAW	3		/* raw socket			*/
+#define SOCK_RDM	4		/* reliably-delivered message	*/
+#define SOCK_SEQPACKET	5		/* sequential packet socket	*/
+#define SOCK_PACKET	10		/* linux specific way of	*/
+					/* getting packets at the dev	*/
+					/* level.  For writing rarp and	*/
+					/* other similar things on the	*/
+					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
+#endif
+
+#endif /* __V850_SOCKET_H__ */
diff -urN linux-2.4.29/include/asm-v850/sockios.h linux-2.4.29-uc1/include/asm-v850/sockios.h
--- linux-2.4.29/include/asm-v850/sockios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/sockios.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef __V850_SOCKIOS_H__
+#define __V850_SOCKIOS_H__
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 	0x8901
+#define SIOCSPGRP	0x8902
+#define FIOGETOWN	0x8903
+#define SIOCGPGRP	0x8904
+#define SIOCATMARK	0x8905
+#define SIOCGSTAMP	0x8906		/* Get stamp */
+
+#endif /* __V850_SOCKIOS_H__ */
diff -urN linux-2.4.29/include/asm-v850/softirq.h linux-2.4.29-uc1/include/asm-v850/softirq.h
--- linux-2.4.29/include/asm-v850/softirq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/softirq.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,19 @@
+#ifndef __V850_SOFTIRQ_H__
+#define __V850_SOFTIRQ_H__
+
+#include <asm/atomic.h>
+#include <asm/hardirq.h>
+
+#define __cpu_bh_enable(cpu) \
+		do { barrier(); local_bh_count(cpu)--; } while (0)
+#define cpu_bh_disable(cpu) \
+		do { local_bh_count(cpu)++; barrier(); } while (0)
+
+#define local_bh_disable()	cpu_bh_disable(smp_processor_id())
+#define __local_bh_enable()	__cpu_bh_enable(smp_processor_id())
+
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
+
+#define local_bh_enable() __local_bh_enable()
+
+#endif /* __V850_SOFTIRQ_H__ */
diff -urN linux-2.4.29/include/asm-v850/statfs.h linux-2.4.29-uc1/include/asm-v850/statfs.h
--- linux-2.4.29/include/asm-v850/statfs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/statfs.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef __V850_STATFS_H__
+#define __V850_STATFS_H__
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t	fsid_t;
+
+#endif
+
+struct statfs {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_spare[6];
+};
+
+#endif /* __V850_STATFS_H__ */
diff -urN linux-2.4.29/include/asm-v850/stat.h linux-2.4.29-uc1/include/asm-v850/stat.h
--- linux-2.4.29/include/asm-v850/stat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/stat.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,73 @@
+/*
+ * include/asm-v850/stat.h -- v850 stat structure
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_STAT_H__
+#define __V850_STAT_H__
+
+#include <asm/posix_types.h>
+
+struct stat {
+	unsigned int	st_dev;
+	unsigned long	st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+	unsigned int 	st_uid;
+	unsigned int 	st_gid;
+	unsigned int	st_rdev;
+	long		st_size;
+	unsigned long	st_blksize;
+	unsigned long	st_blocks;
+	unsigned long	st_atime;
+	unsigned long	__unused1;
+	unsigned long	st_mtime;
+	unsigned long	__unused2;
+	unsigned long	st_ctime;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+	unsigned long	__unused5;
+};
+
+struct stat64 {
+	unsigned long long	st_dev;
+	unsigned long	__unused1;
+
+	unsigned long long	st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned long	__unused3;
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	st_blocks; /* No. of 512-byte blocks allocated */
+	unsigned long	__unused4; /* future possible st_blocks high bits */
+
+	unsigned long	st_atime;
+	unsigned long	st_atime_nsec;
+
+	unsigned long	st_mtime;
+	unsigned long	st_mtime_nsec;
+
+	unsigned long	st_ctime;
+	unsigned long	st_ctime_nsec;
+
+	unsigned long	__unused8;
+};
+
+#endif /* __V850_STAT_H__ */
diff -urN linux-2.4.29/include/asm-v850/string.h linux-2.4.29-uc1/include/asm-v850/string.h
--- linux-2.4.29/include/asm-v850/string.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/string.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,27 @@
+/*
+ * include/asm-v850/string.h -- Architecture specific string routines
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_STRING_H__
+#define __V850_STRING_H__
+
+#define __HAVE_ARCH_BCOPY
+#define __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMSET
+#define __HAVE_ARCH_MEMMOVE
+
+extern void *memcpy (void *, const void *, __kernel_size_t);
+extern void bcopy (const char *, char *, int);
+extern void *memset (void *, int, __kernel_size_t);
+extern void *memmove (void *, const void *, __kernel_size_t);
+
+#endif /* __V850_STRING_H__ */
diff -urN linux-2.4.29/include/asm-v850/system.h linux-2.4.29-uc1/include/asm-v850/system.h
--- linux-2.4.29/include/asm-v850/system.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/system.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,121 @@
+/*
+ * include/asm-v850/system.h -- Low-level interrupt/thread ops
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_SYSTEM_H__
+#define __V850_SYSTEM_H__
+
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+
+
+#define prepare_to_switch()	do { } while (0)
+
+/*
+ * switch_to(n) should switch tasks to task ptr, first checking that
+ * ptr isn't the current task, in which case it does nothing.
+ */
+struct thread_struct;
+extern void *switch_thread (struct thread_struct *last,
+			    struct thread_struct *next);
+#define switch_to(prev,next,last)					      \
+  do {									      \
+        if (prev != next) {						      \
+ 		(last) = switch_thread (&prev->thread, &next->thread);	      \
+	}								      \
+  } while (0)
+
+
+/* Enable/disable interrupts.  */
+#define local_irq_enable()	__asm__ __volatile__ ("ei")
+#define local_irq_disable()	__asm__ __volatile__ ("di")
+
+#define local_save_flags(flags) \
+  __asm__ __volatile__ ("stsr %1, %0" : "=r" (flags) : "i" (SR_PSW))
+#define local_restore_flags(flags) \
+  __asm__ __volatile__ ("ldsr %0, %1" :: "r" (flags), "i" (SR_PSW))
+
+/* For spinlocks etc */
+#define	local_irq_save(flags) \
+  do { local_save_flags (flags); local_irq_disable (); } while (0) 
+#define	local_irq_set(flags) \
+  do { local_save_flags (flags); local_irq_enable (); } while (0) 
+#define local_irq_restore(flags) \
+  local_restore_flags (flags);
+
+
+/* The above names are used exclusively in 2.5.x, but define some
+   traditional aliases for 2.4.  */
+#define cli()			local_irq_disable()
+#define sti()			local_irq_enable()
+#define save_flags(x)		local_save_flags(x)
+#define save_flags_cli(x)	local_irq_save(x)
+#define restore_flags(x)	local_irq_restore(x)
+
+
+static inline int irqs_disabled (void)
+{
+	unsigned flags;
+	local_save_flags (flags);
+	return !!(flags & 0x20);
+}
+
+
+/*
+ * Force strict CPU ordering.
+ * Not really required on v850...
+ */
+#define nop()			__asm__ __volatile__ ("nop")
+#define mb()			__asm__ __volatile__ ("" ::: "memory")
+#define rmb()			mb ()
+#define wmb()			mb ()
+#define read_barrier_depends()	((void)0)
+#define set_mb(var, value)	do { var = value; mb (); } while (0)
+#define set_wmb(var, value)	do { var = value; wmb (); } while (0)
+
+#define smp_mb()	mb ()
+#define smp_rmb()	rmb ()
+#define smp_wmb()	wmb ()
+#define smp_read_barrier_depends()	read_barrier_depends()
+
+#define xchg(ptr, with) \
+  ((__typeof__ (*(ptr)))__xchg ((unsigned long)(with), (ptr), sizeof (*(ptr))))
+#define tas(ptr) (xchg ((ptr), 1))
+
+extern inline unsigned long __xchg (unsigned long with,
+				    __volatile__ void *ptr, int size)
+{
+	unsigned long tmp, flags;
+
+	local_irq_save (flags);
+
+	switch (size) {
+	case 1:
+		tmp = *(unsigned char *)ptr;
+		*(unsigned char *)ptr = with;
+		break;
+	case 2:
+		tmp = *(unsigned short *)ptr;
+		*(unsigned short *)ptr = with;
+		break;
+	case 4:
+		tmp = *(unsigned long *)ptr;
+		*(unsigned long *)ptr = with;
+		break;
+	}
+
+	local_irq_restore (flags);
+
+	return tmp;
+}
+
+#endif /* __V850_SYSTEM_H__ */
diff -urN linux-2.4.29/include/asm-v850/teg.h linux-2.4.29-uc1/include/asm-v850/teg.h
--- linux-2.4.29/include/asm-v850/teg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/teg.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,101 @@
+/*
+ * include/asm-v850/teg.h -- NB85E-TEG cpu chip
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_TEG_H__
+#define __V850_TEG_H__
+
+
+/* The TEG uses the V850E cpu core.  */
+#include <asm/v850e.h>
+#include <asm/v850e_cache.h>
+
+
+#define CPU_MODEL	"v850e/nb85e-teg"
+#define CPU_MODEL_LONG	"NEC V850E/NB85E TEG"
+
+
+/* For <asm/entry.h> */
+/* We use on-chip RAM, for a few miscellaneous variables that must be
+   accessible using a load instruction relative to R0.  On the NB85E/TEG,
+   There's 60KB of iRAM starting at 0xFFFF0000, however we need the base
+   address to be addressable by a 16-bit signed offset, so we only use the
+   second half of it starting from 0xFFFF8000.  */
+#define R0_RAM_ADDR			0xFFFF8000
+
+
+/* Hardware-specific interrupt numbers (in the kernel IRQ namespace).
+   Some of these are parameterized even though there's only a single
+   interrupt, for compatibility with some generic code that works on other
+   processor models.  */
+#define IRQ_INTCMD(n)	6	/* interval timer interrupt */
+#define IRQ_INTCMD_NUM	1
+#define IRQ_INTSER(n)	16	/* UART reception error */
+#define IRQ_INTSER_NUM	1
+#define IRQ_INTSR(n)	17	/* UART reception completion */
+#define IRQ_INTSR_NUM	1
+#define IRQ_INTST(n)	18	/* UART transmission completion */
+#define IRQ_INTST_NUM	1
+
+/* For <asm/irq.h> */
+#define NUM_CPU_IRQS	64
+
+
+/* TEG UART details.  */
+#define V850E_UART_BASE_ADDR(n)		(0xFFFFF600 + 0x10 * (n))
+#define V850E_UART_ASIM_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x0)
+#define V850E_UART_ASIS_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x2)
+#define V850E_UART_ASIF_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x4)
+#define V850E_UART_CKSR_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x6)
+#define V850E_UART_BRGC_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x8)
+#define V850E_UART_TXB_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0xA)
+#define V850E_UART_RXB_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0xC)
+#define V850E_UART_NUM_CHANNELS		1
+#define V850E_UART_BASE_FREQ		CPU_CLOCK_FREQ
+/* This is a function that gets called before configuring the UART.  */
+#define V850E_UART_PRE_CONFIGURE	teg_uart_pre_configure
+#ifndef __ASSEMBLY__
+extern void teg_uart_pre_configure (unsigned chan,
+				    unsigned cflags, unsigned baud);
+#endif
+
+
+/* The TEG RTPU.  */
+#define V850E_RTPU_BASE_ADDR		0xFFFFF210
+
+
+/* TEG series timer D details.  */
+#define V850E_TIMER_D_BASE_ADDR		0xFFFFF210
+#define V850E_TIMER_D_TMCD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x0)
+#define V850E_TIMER_D_TMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x4)
+#define V850E_TIMER_D_CMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x8)
+#define V850E_TIMER_D_BASE_FREQ		CPU_CLOCK_FREQ
+
+
+/* `Interrupt Source Select' control register.  */
+#define TEG_ISS_ADDR			0xFFFFF7FA
+#define TEG_ISS				(*(volatile u8 *)TEG_ISS_ADDR)
+
+/* Port 0 I/O register (bits 0-3 used).  */
+#define TEG_PORT0_IO_ADDR		0xFFFFF7F2
+#define TEG_PORT0_IO			(*(volatile u8 *)TEG_PORT0_IO_ADDR)
+/* Port 0 control register (bits 0-3 control mode, 0 = output, 1 = input).  */
+#define TEG_PORT0_PM_ADDR		0xFFFFF7F4
+#define TEG_PORT0_PM			(*(volatile u8 *)TEG_PORT0_PM_ADDR)
+
+
+#ifndef __ASSEMBLY__
+extern void teg_init_irqs (void);
+#endif
+
+
+#endif /* __V850_TEG_H__ */
diff -urN linux-2.4.29/include/asm-v850/termbits.h linux-2.4.29-uc1/include/asm-v850/termbits.h
--- linux-2.4.29/include/asm-v850/termbits.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/termbits.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,174 @@
+#ifndef __V850_TERMBITS_H__
+#define __V850_TERMBITS_H__
+
+#include <linux/posix_types.h>
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#define NCCS 19
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IUCLC	0001000
+#define IXON	0002000
+#define IXANY	0004000
+#define IXOFF	0010000
+#define IMAXBEL	0020000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define OLCUC	0000002
+#define ONLCR	0000004
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#define NLDLY	0000400
+#define   NL0	0000000
+#define   NL1	0000400
+#define CRDLY	0003000
+#define   CR0	0000000
+#define   CR1	0001000
+#define   CR2	0002000
+#define   CR3	0003000
+#define TABDLY	0014000
+#define   TAB0	0000000
+#define   TAB1	0004000
+#define   TAB2	0010000
+#define   TAB3	0014000
+#define   XTABS	0014000
+#define BSDLY	0020000
+#define   BS0	0000000
+#define   BS1	0020000
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+#define FFDLY	0100000
+#define   FF0	0000000
+#define   FF1	0100000
+
+/* c_cflag bit meaning */
+#define CBAUD	0010017
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE	0000060
+#define   CS5	0000000
+#define   CS6	0000020
+#define   CS7	0000040
+#define   CS8	0000060
+#define CSTOPB	0000100
+#define CREAD	0000200
+#define PARENB	0000400
+#define PARODD	0001000
+#define HUPCL	0002000
+#define CLOCAL	0004000
+#define CBAUDEX 0010000
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+#define CIBAUD	  002003600000	/* input baud rate (not used) */
+#define CMSPAR	  010000000000		/* mark or space (stick) parity */
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+#define ISIG	0000001
+#define ICANON	0000002
+#define XCASE	0000004
+#define ECHO	0000010
+#define ECHOE	0000020
+#define ECHOK	0000040
+#define ECHONL	0000100
+#define NOFLSH	0000200
+#define TOSTOP	0000400
+#define ECHOCTL	0001000
+#define ECHOPRT	0002000
+#define ECHOKE	0004000
+#define FLUSHO	0010000
+#define PENDIN	0040000
+#define IEXTEN	0100000
+
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* __V850_TERMBITS_H__ */
diff -urN linux-2.4.29/include/asm-v850/termios.h linux-2.4.29-uc1/include/asm-v850/termios.h
--- linux-2.4.29/include/asm-v850/termios.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/termios.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,106 @@
+#ifndef __V850_TERMIOS_H__
+#define __V850_TERMIOS_H__
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6	/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14	/* synchronous PPP */
+#define N_HCI		15  /* Bluetooth HCI UART */
+
+#ifdef __KERNEL__
+
+/*	intr=^C		quit=^\		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+	unsigned short __tmp; \
+	get_user(__tmp,&(termio)->x); \
+	*(unsigned short *) &(termios)->x = __tmp; \
+}
+
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif	/* __KERNEL__ */
+
+#endif	/* __V850_TERMIOS_H__ */
diff -urN linux-2.4.29/include/asm-v850/timex.h linux-2.4.29-uc1/include/asm-v850/timex.h
--- linux-2.4.29/include/asm-v850/timex.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/timex.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ * linux/include/asm-v850/timex.h
+ *
+ * v850 architecture timex specifications
+ */
+#ifndef __V850_TIMEX_H__
+#define __V850_TIMEX_H__
+
+#define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
+#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
+#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
+	(1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
+		<< (SHIFT_SCALE-SHIFT_HZ)) / HZ)
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+	return 0;
+}
+
+#define vxtime_lock()		do {} while (0)
+#define vxtime_unlock()		do {} while (0)
+
+#endif /* __V850_TIMEX_H__ */
diff -urN linux-2.4.29/include/asm-v850/tlb.h linux-2.4.29-uc1/include/asm-v850/tlb.h
--- linux-2.4.29/include/asm-v850/tlb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/tlb.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1 @@
+#include <asm-generic/tlb.h>
diff -urN linux-2.4.29/include/asm-v850/types.h linux-2.4.29-uc1/include/asm-v850/types.h
--- linux-2.4.29/include/asm-v850/types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/types.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,66 @@
+#ifndef __V850_TYPES_H__
+#define __V850_TYPES_H__
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue.  However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ */
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+#define BITS_PER_LONG 32
+
+#ifndef __ASSEMBLY__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+/* Dma addresses are 32-bits wide.  */
+
+typedef u32 dma_addr_t;
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* __V850_TYPES_H__ */
diff -urN linux-2.4.29/include/asm-v850/uaccess.h linux-2.4.29-uc1/include/asm-v850/uaccess.h
--- linux-2.4.29/include/asm-v850/uaccess.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/uaccess.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,159 @@
+#ifndef __V850_UACCESS_H__
+#define __V850_UACCESS_H__
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+
+#include <asm/segment.h>
+#include <asm/machdep.h>
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+extern inline int access_ok (int type, const void *addr, unsigned long size)
+{
+	/* XXX I guess we should check against real ram bounds at least, and
+	   possibly make sure ADDR is not within the kernel.
+	   For now we just check to make sure it's not a small positive
+	   or negative value, as that will at least catch some kinds of
+	   error.  In particular, we make sure that ADDR's not within the
+	   interrupt vector area, which we know starts at zero, or within the
+	   peripheral-I/O area, which is located just _before_ zero.  */
+	unsigned long val = (unsigned long)addr;
+	return val >= (0x80 + NUM_CPU_IRQS*16) && val < 0xFFFFF000;
+}
+
+extern inline int verify_area (int type, const void *addr, unsigned long size)
+{
+	return access_ok (type, addr, size) ? 0 : -EFAULT;
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table (unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ */
+
+extern int bad_user_access_length (void);
+
+#define __get_user(var, ptr)						      \
+  ({									      \
+	  int __gu_err = 0;						      \
+	  typeof(*(ptr)) __gu_val = 0;					      \
+	  switch (sizeof (*(ptr))) {					      \
+	  case 1:							      \
+	  case 2:							      \
+	  case 4:							      \
+		  __gu_val = *(ptr);					      \
+		  break;						      \
+	  case 8:							      \
+		  memcpy(&__gu_val, ptr, sizeof(__gu_val));		      \
+		  break;						      \
+	  default:							      \
+		  __gu_val = 0;						      \
+		  __gu_err = __get_user_bad ();				      \
+		  break;						      \
+	  }								      \
+	  (var) = __gu_val;						      \
+	  __gu_err;							      \
+  })
+#define __get_user_bad()	(bad_user_access_length (), (-EFAULT))
+
+#define __put_user(var, ptr)						      \
+  ({									      \
+	  int __pu_err = 0;						      \
+	  switch (sizeof (*(ptr))) {					      \
+	  case 1:							      \
+	  case 2:							      \
+	  case 4:							      \
+		  *(ptr) = (var);					      \
+		  break;						      \
+	  case 8: {							      \
+	  	  typeof(*(ptr)) __pu_val = 0;				      \
+		  memcpy(ptr, &__pu_val, sizeof(__pu_val));		      \
+		  }							      \
+		  break;						      \
+	  default:							      \
+		  __pu_err = __put_user_bad ();				      \
+		  break;						      \
+	  }								      \
+	  __pu_err;							      \
+  })
+#define __put_user_bad()	(bad_user_access_length (), (-EFAULT))
+
+#define put_user(x, ptr)	__put_user(x, ptr)
+#define get_user(x, ptr)	__get_user(x, ptr)
+
+#define __copy_from_user(to, from, n)	(memcpy (to, from, n), 0)
+#define __copy_to_user(to, from, n)	(memcpy(to, from, n), 0)
+
+#define copy_from_user(to, from, n)	__copy_from_user (to, from, n)
+#define copy_to_user(to, from, n) 	__copy_to_user(to, from, n)
+
+#define copy_to_user_ret(to,from,n,retval) \
+  ({ if (copy_to_user (to,from,n)) return retval; })
+
+#define copy_from_user_ret(to,from,n,retval) \
+  ({ if (copy_from_user (to,from,n)) return retval; })
+
+/*
+ * Copy a null terminated string from userspace.
+ */
+
+static inline long
+strncpy_from_user (char *dst, const char *src, long count)
+{
+	char *tmp;
+	strncpy (dst, src, count);
+	for (tmp = dst; *tmp && count > 0; tmp++, count--)
+		;
+	return tmp - dst;
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 on exception, a value greater than N if too long
+ */
+static inline long strnlen_user (const char *src, long n)
+{
+	return strlen (src) + 1;
+}
+
+#define strlen_user(str)	strnlen_user (str, 32767)
+
+/*
+ * Zero Userspace
+ */
+
+static inline unsigned long
+clear_user (void *to, unsigned long n)
+{
+	memset (to, 0, n);
+	return 0;
+}
+
+#endif /* __V850_UACCESS_H__ */
diff -urN linux-2.4.29/include/asm-v850/ucontext.h linux-2.4.29-uc1/include/asm-v850/ucontext.h
--- linux-2.4.29/include/asm-v850/ucontext.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/ucontext.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,14 @@
+#ifndef __V850_UCONTEXT_H__
+#define __V850_UCONTEXT_H__
+
+#include <asm/sigcontext.h>
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct sigcontext uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif /* __V850_UCONTEXT_H__ */
diff -urN linux-2.4.29/include/asm-v850/unaligned.h linux-2.4.29-uc1/include/asm-v850/unaligned.h
--- linux-2.4.29/include/asm-v850/unaligned.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/unaligned.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,130 @@
+/*
+ * include/asm-v850/unaligned.h -- Unaligned memory access
+ *
+ *  Copyright (C) 2001  NEC Corporation
+ *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * This file is a copy of the arm version, include/asm-arm/unaligned.h
+ *
+ * Note that some v850 chips support unaligned access, but it seems too
+ * annoying to use.
+ */
+
+#ifndef __V850_UNALIGNED_H__
+#define __V850_UNALIGNED_H__
+
+#include <asm/types.h>
+
+extern int __bug_unaligned_x(void *ptr);
+
+/*
+ * What is the most efficient way of loading/storing an unaligned value?
+ *
+ * That is the subject of this file.  Efficiency here is defined as
+ * minimum code size with minimum register usage for the common cases.
+ * It is currently not believed that long longs are common, so we
+ * trade efficiency for the chars, shorts and longs against the long
+ * longs.
+ *
+ * Current stats with gcc 2.7.2.2 for these functions:
+ *
+ *	ptrsize	get:	code	regs	put:	code	regs
+ *	1		1	1		1	2
+ *	2		3	2		3	2
+ *	4		7	3		7	3
+ *	8		20	6		16	6
+ *
+ * gcc 2.95.1 seems to code differently:
+ *
+ *	ptrsize	get:	code	regs	put:	code	regs
+ *	1		1	1		1	2
+ *	2		3	2		3	2
+ *	4		7	4		7	4
+ *	8		19	8		15	6
+ *
+ * which may or may not be more efficient (depending upon whether
+ * you can afford the extra registers).  Hopefully the gcc 2.95
+ * is inteligent enough to decide if it is better to use the
+ * extra register, but evidence so far seems to suggest otherwise.
+ *
+ * Unfortunately, gcc is not able to optimise the high word
+ * out of long long >> 32, or the low word from long long << 32
+ */
+
+#define __get_unaligned_2(__p)					\
+	(__p[0] | __p[1] << 8)
+
+#define __get_unaligned_4(__p)					\
+	(__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24)
+
+#define get_unaligned(ptr)					\
+	({							\
+		__typeof__(*(ptr)) __v;				\
+		__u8 *__p = (__u8 *)(ptr);			\
+		switch (sizeof(*(ptr))) {			\
+		case 1:	__v = *(ptr);			break;	\
+		case 2: __v = __get_unaligned_2(__p);	break;	\
+		case 4: __v = __get_unaligned_4(__p);	break;	\
+		case 8: {					\
+				unsigned int __v1, __v2;	\
+				__v2 = __get_unaligned_4((__p+4)); \
+				__v1 = __get_unaligned_4(__p);	\
+				__v = ((unsigned long long)__v2 << 32 | __v1);	\
+			}					\
+			break;					\
+		default: __v = __bug_unaligned_x(__p);	break;	\
+		}						\
+		__v;						\
+	})
+
+
+extern inline void __put_unaligned_2(__u32 __v, register __u8 *__p)
+{
+	*__p++ = __v;
+	*__p++ = __v >> 8;
+}
+
+extern inline void __put_unaligned_4(__u32 __v, register __u8 *__p)
+{
+	__put_unaligned_2(__v >> 16, __p + 2);
+	__put_unaligned_2(__v, __p);
+}
+
+extern inline void __put_unaligned_8(const unsigned long long __v, register __u8 *__p)
+{
+	/*
+	 * tradeoff: 8 bytes of stack for all unaligned puts (2
+	 * instructions), or an extra register in the long long
+	 * case - go for the extra register.
+	 */
+	__put_unaligned_4(__v >> 32, __p+4);
+	__put_unaligned_4(__v, __p);
+}
+
+/*
+ * Try to store an unaligned value as efficiently as possible.
+ */
+#define put_unaligned(val,ptr)					\
+	({							\
+		switch (sizeof(*(ptr))) {			\
+		case 1:						\
+			*(ptr) = (val);				\
+			break;					\
+		case 2: __put_unaligned_2((val),(__u8 *)(ptr));	\
+			break;					\
+		case 4:	__put_unaligned_4((val),(__u8 *)(ptr));	\
+			break;					\
+		case 8:	__put_unaligned_8((val),(__u8 *)(ptr)); \
+			break;					\
+		default: __bug_unaligned_x(ptr);		\
+			break;					\
+		}						\
+		(void) 0;					\
+	})
+
+
+#endif /* __V850_UNALIGNED_H__ */
diff -urN linux-2.4.29/include/asm-v850/unistd.h linux-2.4.29-uc1/include/asm-v850/unistd.h
--- linux-2.4.29/include/asm-v850/unistd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/unistd.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,434 @@
+/*
+ * include/asm-v850/unistd.h -- System call numbers and invocation mechanism
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_UNISTD_H__
+#define __V850_UNISTD_H__
+
+#include <asm/clinkage.h>
+
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_chown		 16
+#define __NR_break		 17
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_umount2		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_setpgid		 57
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_ugetrlimit	 	 76
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_vhangup		111
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_cacheflush		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl		172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread		180
+#define __NR_pwrite		181
+#define __NR_lchown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_getpmsg		188	/* some people actually want streams */
+#define __NR_putpmsg		189	/* some people actually want streams */
+#define __NR_vfork		190
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_fcntl64		198
+#define __NR_getdents64		199
+#define __NR_pivot_root		200
+#define __NR_gettid		201
+#define __NR_tkill		202
+
+
+/* Syscall protocol:
+   Syscall number in r12, args in r6-r9, r13-r14
+   Return value in r10
+   Trap 0 for `short' syscalls, where all the args can fit in function
+   call argument registers, and trap 1 when there are additional args in
+   r13-r14.  */
+
+#define SYSCALL_NUM	"r12"
+#define SYSCALL_ARG0	"r6"
+#define SYSCALL_ARG1	"r7"
+#define SYSCALL_ARG2	"r8"
+#define SYSCALL_ARG3	"r9"
+#define SYSCALL_ARG4	"r13"
+#define SYSCALL_ARG5	"r14"
+#define SYSCALL_RET	"r10"
+
+#define SYSCALL_SHORT_TRAP	"0"
+#define SYSCALL_LONG_TRAP	"1"
+
+/* Registers clobbered by any syscall.  This _doesn't_ include the syscall
+   number (r12) or the `extended arg' registers (r13, r14), even though
+   they are actually clobbered too (this is because gcc's `asm' statement
+   doesn't allow a clobber to be used as an input or output).  */
+#define SYSCALL_CLOBBERS	"r1", "r5", "r11", "r15", "r16", \
+				"r17", "r18", "r19"
+
+/* Registers clobbered by a `short' syscall.  This includes all clobbers
+   except the syscall number (r12).  */
+#define SYSCALL_SHORT_CLOBBERS	SYSCALL_CLOBBERS, "r13", "r14"
+
+
+/* User programs sometimes end up including this header file
+   (indirectly, via uClibc header files), so I'm a bit nervous just
+   including <linux/compiler.h>.  */
+#if !defined(__builtin_expect) && __GNUC__ == 2 && __GNUC_MINOR__ < 96
+#define __builtin_expect(x, expected_value) (x)
+#endif
+
+#define __syscall_return(type, res)					      \
+  do {									      \
+	  /* user-visible error numbers are in the range -1 - -124:	      \
+	     see <asm-v850/errno.h> */					      \
+	  if (__builtin_expect ((unsigned long)(res) >= (unsigned long)(-125), 0)) { \
+		  errno = -(res);					      \
+		  res = -1;						      \
+	  }								      \
+	  return (type) (res);						      \
+  } while (0)
+
+
+#define _syscall0(type, name)						      \
+type name (void)							      \
+{									      \
+  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
+  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
+  __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP			      \
+			: "=r" (__ret), "=r" (__syscall)	 	      \
+			: "1" (__syscall)				      \
+			: SYSCALL_SHORT_CLOBBERS);			      \
+  __syscall_return (type, __ret);					      \
+}
+
+#define _syscall1(type, name, atype, a)					      \
+type name (atype a)							      \
+{									      \
+  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
+  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
+  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
+  __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP			      \
+			: "=r" (__ret), "=r" (__syscall)		      \
+			: "1" (__syscall), "r" (__a)			      \
+			: SYSCALL_SHORT_CLOBBERS);			      \
+  __syscall_return (type, __ret);					      \
+}
+
+#define _syscall2(type, name, atype, a, btype, b)			      \
+type name (atype a, btype b)						      \
+{									      \
+  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
+  register btype __b __asm__ (SYSCALL_ARG1) = b;			      \
+  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
+  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
+  __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP			      \
+			: "=r" (__ret), "=r" (__syscall)		      \
+			: "1" (__syscall), "r" (__a), "r" (__b)		      \
+			: SYSCALL_SHORT_CLOBBERS);			      \
+  __syscall_return (type, __ret);					      \
+}
+
+#define _syscall3(type, name, atype, a, btype, b, ctype, c)		      \
+type name (atype a, btype b, ctype c)					      \
+{									      \
+  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
+  register btype __b __asm__ (SYSCALL_ARG1) = b;			      \
+  register ctype __c __asm__ (SYSCALL_ARG2) = c;			      \
+  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
+  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
+  __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP			      \
+			: "=r" (__ret), "=r" (__syscall)		      \
+			: "1" (__syscall), "r" (__a), "r" (__b), "r" (__c)    \
+			: SYSCALL_SHORT_CLOBBERS);			      \
+  __syscall_return (type, __ret);					      \
+}
+
+#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d)	      \
+type name (atype a, btype b, ctype c, dtype d)				      \
+{									      \
+  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
+  register btype __b __asm__ (SYSCALL_ARG1) = b;			      \
+  register ctype __c __asm__ (SYSCALL_ARG2) = c;			      \
+  register dtype __d __asm__ (SYSCALL_ARG3) = d;			      \
+  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
+  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
+  __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP			      \
+			: "=r" (__ret), "=r" (__syscall)		      \
+			: "1" (__syscall),				      \
+			"r" (__a), "r" (__b), "r" (__c), "r" (__d)	      \
+			: SYSCALL_SHORT_CLOBBERS);			      \
+  __syscall_return (type, __ret);					      \
+}
+
+#define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, etype,e)\
+type name (atype a, btype b, ctype c, dtype d, etype e)			      \
+{									      \
+  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
+  register btype __b __asm__ (SYSCALL_ARG1) = b;			      \
+  register ctype __c __asm__ (SYSCALL_ARG2) = c;			      \
+  register dtype __d __asm__ (SYSCALL_ARG3) = d;			      \
+  register etype __e __asm__ (SYSCALL_ARG4) = e;			      \
+  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
+  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
+  __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP			      \
+			: "=r" (__ret), "=r" (__syscall), "=r" (__e)	      \
+			: "1" (__syscall),				      \
+			"r" (__a), "r" (__b), "r" (__c), "r" (__d), "2" (__e) \
+			: SYSCALL_CLOBBERS);				      \
+  __syscall_return (type, __ret);					      \
+}
+
+#if __GNUC__ < 3
+/* In older versions of gcc, `asm' statements with more than 10
+   input/output arguments produce a fatal error.  To work around this
+   problem, we use two versions, one for gcc-3.x and one for earlier
+   versions of gcc (the `earlier gcc' version doesn't work with gcc-3.x
+   because gcc-3.x doesn't allow clobbers to also be input arguments).  */
+#define __SYSCALL6_TRAP(syscall, ret, a, b, c, d, e, f)			      \
+  __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP			      \
+			: "=r" (ret), "=r" (syscall)			      \
+			: "1" (syscall),				      \
+			"r" (a), "r" (b), "r" (c), "r" (d),		      \
+ 			"r" (e), "r" (f)				      \
+			: SYSCALL_CLOBBERS, SYSCALL_ARG4, SYSCALL_ARG5);
+#else /* __GNUC__ >= 3 */
+#define __SYSCALL6_TRAP(syscall, ret, a, b, c, d, e, f)			      \
+  __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP			      \
+			: "=r" (ret), "=r" (syscall),			      \
+ 			"=r" (e), "=r" (f)				      \
+			: "1" (syscall),				      \
+			"r" (a), "r" (b), "r" (c), "r" (d),		      \
+			"2" (e), "3" (f)				      \
+			: SYSCALL_CLOBBERS);
+#endif
+
+#define _syscall6(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e, ftype, f) \
+type name (atype a, btype b, ctype c, dtype d, etype e, ftype f)	      \
+{									      \
+  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
+  register btype __b __asm__ (SYSCALL_ARG1) = b;			      \
+  register ctype __c __asm__ (SYSCALL_ARG2) = c;			      \
+  register dtype __d __asm__ (SYSCALL_ARG3) = d;			      \
+  register etype __e __asm__ (SYSCALL_ARG4) = e;			      \
+  register etype __f __asm__ (SYSCALL_ARG5) = f;			      \
+  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
+  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
+  __SYSCALL6_TRAP(__syscall, __ret, __a, __b, __c, __d, __e, __f);	      \
+  __syscall_return (type, __ret);					      \
+}
+		
+
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+extern inline _syscall0(pid_t,setsid)
+extern inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+extern inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+extern inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+extern inline _syscall1(int,dup,int,fd)
+extern inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+extern inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+extern inline _syscall1(int,close,int,fd)
+extern inline _syscall1(int,_exit,int,exitcode)
+extern inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+
+extern inline pid_t wait(int * wait_stat)
+{
+	return waitpid (-1, wait_stat, 0);
+}
+
+#endif
+
+/*
+ * "Conditional" syscalls
+ */
+#define cond_syscall(name)						      \
+  asm (".weak\t" C_SYMBOL_STRING(name) ";"				      \
+       ".set\t" C_SYMBOL_STRING(name) "," C_SYMBOL_STRING(sys_ni_syscall));
+#if 0
+/* This doesn't work if there's a function prototype for NAME visible,
+   because the argument types probably won't match.  */
+#define cond_syscall(name)  \
+  void name (void) __attribute__ ((weak, alias ("sys_ni_syscall")));
+#endif
+
+#endif /* __V850_UNISTD_H__ */
diff -urN linux-2.4.29/include/asm-v850/user.h linux-2.4.29-uc1/include/asm-v850/user.h
--- linux-2.4.29/include/asm-v850/user.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/user.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,56 @@
+#ifndef __V850_USER_H__
+#define __V850_USER_H__
+
+/* Adapted from <asm-ppc/user.h>.  */
+
+#ifdef __KERNEL__
+
+#include <linux/ptrace.h>
+#include <asm/page.h>
+
+/*
+ * Core file format: The core file is written in such a way that gdb
+ * can understand it and provide useful information to the user (under
+ * linux we use the `trad-core' bfd, NOT the osf-core).  The file contents
+ * are as follows:
+ *
+ *  upage: 1 page consisting of a user struct that tells gdb
+ *	what is present in the file.  Directly after this is a
+ *	copy of the task_struct, which is currently not used by gdb,
+ *	but it may come in handy at some point.  All of the registers
+ *	are stored as part of the upage.  The upage should always be
+ *	only one page long.
+ *  data: The data segment follows next.  We use current->end_text to
+ *	current->brk to pick up all of the user variables, plus any memory
+ *	that may have been sbrk'ed.  No attempt is made to determine if a
+ *	page is demand-zero or if a page is totally unused, we just cover
+ *	the entire range.  All of the addresses are rounded in such a way
+ *	that an integral number of pages is written.
+ *  stack: We need the stack information in order to get a meaningful
+ *	backtrace.  We need to write the data from usp to
+ *	current->start_stack, so we round each of these in order to be able
+ *	to write an integer number of pages.
+ */
+struct user {
+	struct pt_regs	regs;			/* entire machine state */
+	size_t		u_tsize;		/* text size (pages) */
+	size_t		u_dsize;		/* data size (pages) */
+	size_t		u_ssize;		/* stack size (pages) */
+	unsigned long	start_code;		/* text starting address */
+	unsigned long	start_data;		/* data starting address */
+	unsigned long	start_stack;		/* stack starting address */
+	long int	signal;			/* signal causing core dump */
+	struct regs *	u_ar0;			/* help gdb find registers */
+	unsigned long	magic;			/* identifies a core file */
+	char		u_comm[32];		/* user command name */
+};
+
+#define NBPG			PAGE_SIZE
+#define UPAGES			1
+#define HOST_TEXT_START_ADDR	(u.start_code)
+#define HOST_DATA_START_ADDR	(u.start_data)
+#define HOST_STACK_END_ADDR	(u.start_stack + u.u_ssize * NBPG)
+
+#endif /* __KERNEL__ */
+
+#endif /* __V850_USER_H__ */
diff -urN linux-2.4.29/include/asm-v850/v850e2_cache.h linux-2.4.29-uc1/include/asm-v850/v850e2_cache.h
--- linux-2.4.29/include/asm-v850/v850e2_cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/v850e2_cache.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,74 @@
+/*
+ * include/asm-v850/v850e2_cache_cache.h -- Cache control for V850E2
+ * 	cache memories
+ *
+ *  Copyright (C) 2003  NEC Electronics Corporation
+ *  Copyright (C) 2003  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_V850E2_CACHE_H__
+#define __V850_V850E2_CACHE_H__
+
+#include <asm/types.h>
+
+
+/* Cache control registers.  */
+
+/* Bus Transaction Control */
+#define V850E2_CACHE_BTSC_ADDR	0xFFFFF070
+#define V850E2_CACHE_BTSC 	(*(volatile u16 *)V850E2_CACHE_BTSC_ADDR)
+#define V850E2_CACHE_BTSC_ICM	0x0001 /* icache enable */
+#define V850E2_CACHE_BTSC_DCM0	0x0004 /* dcache enable, bit 0 */
+#define V850E2_CACHE_BTSC_DCM1	0x0008 /* dcache enable, bit 1 */
+#define V850E2_CACHE_BTSC_DCM_WT		      /* write-through */ \
+			V850E2_CACHE_BTSC_DCM0
+#ifdef CONFIG_V850E2_V850E2S
+# define V850E2_CACHE_BTSC_DCM_WB_NO_ALLOC    /* write-back, non-alloc */ \
+			V850E2_CACHE_BTSC_DCM1	
+# define V850E2_CACHE_BTSC_DCM_WB_ALLOC	      /* write-back, non-alloc */ \
+			(V850E2_CACHE_BTSC_DCM1 | V850E2_CACHE_BTSC_DCM0)
+# define V850E2_CACHE_BTSC_ISEQ	0x0010 /* icache `address sequence mode' */
+# define V850E2_CACHE_BTSC_DSEQ	0x0020 /* dcache `address sequence mode' */
+# define V850E2_CACHE_BTSC_IRFC	0x0030
+# define V850E2_CACHE_BTSC_ILCD	0x4000
+# define V850E2_CACHE_BTSC_VABE	0x8000
+#endif /* CONFIG_V850E2_V850E2S */
+
+/* Cache operation start address register (low-bits).  */
+#define V850E2_CACHE_CADL_ADDR	0xFFFFF074
+#define V850E2_CACHE_CADL 	(*(volatile u16 *)V850E2_CACHE_CADL_ADDR)
+/* Cache operation start address register (high-bits).  */
+#define V850E2_CACHE_CADH_ADDR	0xFFFFF076
+#define V850E2_CACHE_CADH 	(*(volatile u16 *)V850E2_CACHE_CADH_ADDR)
+/* Cache operation count register.  */
+#define V850E2_CACHE_CCNT_ADDR	0xFFFFF078
+#define V850E2_CACHE_CCNT 	(*(volatile u16 *)V850E2_CACHE_CCNT_ADDR)
+/* Cache operation specification register.  */
+#define V850E2_CACHE_COPR_ADDR	0xFFFFF07A
+#define V850E2_CACHE_COPR 	(*(volatile u16 *)V850E2_CACHE_COPR_ADDR)
+#define V850E2_CACHE_COPR_STRT	0x0001 /* start cache operation */
+#define V850E2_CACHE_COPR_LBSL	0x0100 /* 0 = icache, 1 = dcache */
+#define V850E2_CACHE_COPR_WSLE	0x0200 /* operate on cache way */
+#define V850E2_CACHE_COPR_WSL(way) ((way) * 0x0400) /* way select */
+#define V850E2_CACHE_COPR_CFC(op)  ((op)  * 0x1000) /* cache function code */
+
+
+/* Size of a cache line in bytes.  */
+#define V850E2_CACHE_LINE_SIZE_BITS	4
+#define V850E2_CACHE_LINE_SIZE		(1 << V850E2_CACHE_LINE_SIZE_BITS)
+
+/* The size of each cache `way' in lines.  */
+#define V850E2_CACHE_WAY_SIZE		256
+
+
+/* For <asm/cache.h> */
+#define L1_CACHE_BYTES			V850E2_CACHE_LINE_SIZE
+
+
+#endif /* __V850_V850E2_CACHE_H__ */
diff -urN linux-2.4.29/include/asm-v850/v850e2.h linux-2.4.29-uc1/include/asm-v850/v850e2.h
--- linux-2.4.29/include/asm-v850/v850e2.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/v850e2.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,69 @@
+/*
+ * include/asm-v850/v850e2.h -- Machine-dependent defs for V850E2 CPUs
+ *
+ *  Copyright (C) 2002,03  NEC Electronics Corporation
+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_V850E2_H__
+#define __V850_V850E2_H__
+
+#include <asm/v850e_intc.h>	/* v850e-style interrupt system.  */
+
+
+#define CPU_ARCH "v850e2"
+
+
+/* Control registers.  */
+
+/* Chip area select control */ 
+#define V850E2_CSC_ADDR(n)	(0xFFFFF060 + (n) * 2)
+#define V850E2_CSC(n)		(*(volatile u16 *)V850E2_CSC_ADDR(n))
+/* I/O area select control */
+#define V850E2_BPC_ADDR		0xFFFFF064
+#define V850E2_BPC		(*(volatile u16 *)V850E2_BPC_ADDR)
+/* Bus size configuration */
+#define V850E2_BSC_ADDR		0xFFFFF066
+#define V850E2_BSC		(*(volatile u16 *)V850E2_BSC_ADDR)
+/* Endian configuration */
+#define V850E2_BEC_ADDR		0xFFFFF068
+#define V850E2_BEC		(*(volatile u16 *)V850E2_BEC_ADDR)
+/* Cache configuration */
+#define V850E2_BHC_ADDR		0xFFFFF06A
+#define V850E2_BHC		(*(volatile u16 *)V850E2_BHC_ADDR)
+/* NPB strobe-wait configuration */
+#define V850E2_VSWC_ADDR	0xFFFFF06E
+#define V850E2_VSWC		(*(volatile u16 *)V850E2_VSWC_ADDR)
+/* Bus cycle type */
+#define V850E2_BCT_ADDR(n)	(0xFFFFF480 + (n) * 2)
+#define V850E2_BCT(n)		(*(volatile u16 *)V850E2_BCT_ADDR(n))
+/* Data wait control */
+#define V850E2_DWC_ADDR(n)	(0xFFFFF484 + (n) * 2)
+#define V850E2_DWC(n)		(*(volatile u16 *)V850E2_DWC_ADDR(n))
+/* Bus cycle control */
+#define V850E2_BCC_ADDR		0xFFFFF488
+#define V850E2_BCC		(*(volatile u16 *)V850E2_BCC_ADDR)
+/* Address wait control */
+#define V850E2_ASC_ADDR		0xFFFFF48A
+#define V850E2_ASC		(*(volatile u16 *)V850E2_ASC_ADDR)
+/* Local bus sizing control */
+#define V850E2_LBS_ADDR		0xFFFFF48E
+#define V850E2_LBS		(*(volatile u16 *)V850E2_LBS_ADDR)
+/* Line buffer control */
+#define V850E2_LBC_ADDR(n)	(0xFFFFF490 + (n) * 2)
+#define V850E2_LBC(n)		(*(volatile u16 *)V850E2_LBC_ADDR(n))
+/* SDRAM configuration */
+#define V850E2_SCR_ADDR(n)	(0xFFFFF4A0 + (n) * 4)
+#define V850E2_SCR(n)		(*(volatile u16 *)V850E2_SCR_ADDR(n))
+/* SDRAM refresh cycle control */
+#define V850E2_RFS_ADDR(n)	(0xFFFFF4A2 + (n) * 4)
+#define V850E2_RFS(n)		(*(volatile u16 *)V850E2_RFS_ADDR(n))
+
+
+#endif /* __V850_V850E2_H__ */
diff -urN linux-2.4.29/include/asm-v850/v850e_cache.h linux-2.4.29-uc1/include/asm-v850/v850e_cache.h
--- linux-2.4.29/include/asm-v850/v850e_cache.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/v850e_cache.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,48 @@
+/*
+ * include/asm-v850/v850e_cache.h -- Cache control for V850E cache memories
+ *
+ *  Copyright (C) 2001,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+/* This file implements cache control for the rather simple cache used on
+   some V850E CPUs, specifically the NB85E/TEG CPU-core and the V850E/ME2
+   CPU.  V850E2 processors have their own (better) cache
+   implementation.  */
+
+#ifndef __V850_V850E_CACHE_H__
+#define __V850_V850E_CACHE_H__
+
+#include <asm/types.h>
+
+
+/* Cache control registers.  */
+#define V850E_CACHE_BHC_ADDR	0xFFFFF06A
+#define V850E_CACHE_BHC		(*(volatile u16 *)V850E_CACHE_BHC_ADDR)
+#define V850E_CACHE_ICC_ADDR	0xFFFFF070
+#define V850E_CACHE_ICC		(*(volatile u16 *)V850E_CACHE_ICC_ADDR)
+#define V850E_CACHE_ISI_ADDR	0xFFFFF072
+#define V850E_CACHE_ISI		(*(volatile u16 *)V850E_CACHE_ISI_ADDR)
+#define V850E_CACHE_DCC_ADDR	0xFFFFF078
+#define V850E_CACHE_DCC		(*(volatile u16 *)V850E_CACHE_DCC_ADDR)
+
+/* Size of a cache line in bytes.  */
+#define V850E_CACHE_LINE_SIZE	16
+
+/* For <asm/cache.h> */
+#define L1_CACHE_BYTES		V850E_CACHE_LINE_SIZE
+
+
+#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
+/* Set caching params via the BHC, ICC, and DCC registers.  */
+void v850e_cache_enable (u16 bhc, u16 icc, u16 dcc);
+#endif /* __KERNEL__ && !__ASSEMBLY__ */
+
+
+#endif /* __V850_V850E_CACHE_H__ */
diff -urN linux-2.4.29/include/asm-v850/v850e.h linux-2.4.29-uc1/include/asm-v850/v850e.h
--- linux-2.4.29/include/asm-v850/v850e.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/v850e.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,21 @@
+/*
+ * include/asm-v850/v850e.h -- V850E CPU
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_V850E_H__
+#define __V850_V850E_H__
+
+#include <asm/v850e_intc.h>
+
+#define CPU_ARCH "v850e"
+
+#endif /* __V850_V850E_H__ */
diff -urN linux-2.4.29/include/asm-v850/v850e_intc.h linux-2.4.29-uc1/include/asm-v850/v850e_intc.h
--- linux-2.4.29/include/asm-v850/v850e_intc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/v850e_intc.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,133 @@
+/*
+ * include/asm-v850/v850e_intc.h -- V850E CPU interrupt controller (INTC)
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_V850E_INTC_H__
+#define __V850_V850E_INTC_H__
+
+
+/* There are 4 16-bit `Interrupt Mask Registers' located contiguously
+   starting from this base.  Each interrupt uses a single bit to
+   indicated enabled/disabled status.  */
+#define V850E_INTC_IMR_BASE_ADDR  0xFFFFF100
+#define V850E_INTC_IMR_ADDR(irq)  (V850E_INTC_IMR_BASE_ADDR + ((irq) >> 3))
+#define V850E_INTC_IMR_BIT(irq)	  ((irq) & 0x7)
+
+/* Each maskable interrupt has a single-byte control register at this
+   address.  */
+#define V850E_INTC_IC_BASE_ADDR	  0xFFFFF110
+#define V850E_INTC_IC_ADDR(irq)	  (V850E_INTC_IC_BASE_ADDR + ((irq) << 1))
+#define V850E_INTC_IC(irq)	  (*(volatile u8 *)V850E_INTC_IC_ADDR(irq))
+/* Encode priority PR for storing in an interrupt control register.  */
+#define V850E_INTC_IC_PR(pr)	  (pr)
+/* Interrupt disable bit in an interrupt control register.  */
+#define V850E_INTC_IC_MK_BIT	  6
+#define V850E_INTC_IC_MK	  (1 << V850E_INTC_IC_MK_BIT)
+/* Interrupt pending flag in an interrupt control register.  */
+#define V850E_INTC_IC_IF_BIT	  7
+#define V850E_INTC_IC_IF	  (1 << V850E_INTC_IC_IF_BIT)
+
+/* The ISPR (In-service priority register) contains one bit for each interrupt
+   priority level, which is set to one when that level is currently being
+   serviced (and thus blocking any interrupts of equal or lesser level).  */
+#define V850E_INTC_ISPR_ADDR	  0xFFFFF1FA
+#define V850E_INTC_ISPR		  (*(volatile u8 *)V850E_INTC_ISPR_ADDR)
+
+
+#ifndef __ASSEMBLY__
+
+/* Enable interrupt handling for interrupt IRQ.  */
+static inline void v850e_intc_enable_irq (unsigned irq)
+{
+	__asm__ __volatile__ ("clr1 %0, [%1]"
+			      :: "r" (V850E_INTC_IMR_BIT (irq)),
+			         "r" (V850E_INTC_IMR_ADDR (irq))
+			      : "memory");
+}
+
+/* Disable interrupt handling for interrupt IRQ.  Note that any
+   interrupts received while disabled will be delivered once the
+   interrupt is enabled again, unless they are explicitly cleared using
+   `v850e_intc_clear_pending_irq'.  */
+static inline void v850e_intc_disable_irq (unsigned irq)
+{
+	__asm__ __volatile__ ("set1 %0, [%1]"
+			      :: "r" (V850E_INTC_IMR_BIT (irq)),
+			         "r" (V850E_INTC_IMR_ADDR (irq))
+			      : "memory");
+}
+
+/* Return true if interrupt handling for interrupt IRQ is enabled.  */
+static inline int v850e_intc_irq_enabled (unsigned irq)
+{
+	int rval;
+	__asm__ __volatile__ ("tst1 %1, [%2]; setf z, %0"
+			      : "=r" (rval)
+			      : "r" (V850E_INTC_IMR_BIT (irq)),
+			        "r" (V850E_INTC_IMR_ADDR (irq)));
+	return rval;
+}
+
+/* Disable irqs from 0 until LIMIT.  LIMIT must be a multiple of 8.  */
+static inline void _v850e_intc_disable_irqs (unsigned limit)
+{
+	unsigned long addr;
+	for (addr = V850E_INTC_IMR_BASE_ADDR; limit >= 8; addr++, limit -= 8)
+		*(char *)addr = 0xFF;
+}
+
+/* Disable all irqs.  This is purposely a macro, because NUM_MACH_IRQS
+   will be only be defined later.  */
+#define v850e_intc_disable_irqs()   _v850e_intc_disable_irqs (NUM_MACH_IRQS)
+
+/* Clear any pending interrupts for IRQ.  */
+static inline void v850e_intc_clear_pending_irq (unsigned irq)
+{
+	__asm__ __volatile__ ("clr1 %0, 0[%1]"
+			      :: "i" (V850E_INTC_IC_IF_BIT),
+			         "r" (V850E_INTC_IC_ADDR (irq))
+			      : "memory");
+}
+
+/* Return true if interrupt IRQ is pending (but disabled).  */
+static inline int v850e_intc_irq_pending (unsigned irq)
+{
+	int rval;
+	__asm__ __volatile__ ("tst1 %1, 0[%2]; setf nz, %0"
+			      : "=r" (rval)
+			      : "i" (V850E_INTC_IC_IF_BIT),
+			        "r" (V850E_INTC_IC_ADDR (irq)));
+	return rval;
+}
+
+
+struct v850e_intc_irq_init {
+	const char *name;	/* name of interrupt type */
+
+	/* Range of kernel irq numbers for this type:
+	   BASE, BASE+INTERVAL, ..., BASE+INTERVAL*NUM  */
+	unsigned base, num, interval;
+
+	unsigned priority;	/* interrupt priority to assign */
+};
+struct hw_interrupt_type;	/* fwd decl */
+
+/* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
+   INITS (which is terminated by an entry with the name field == 0).  */
+extern void v850e_intc_init_irq_types (struct v850e_intc_irq_init *inits,
+				       struct hw_interrupt_type *hw_irq_types);
+
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_V850E_INTC_H__ */
diff -urN linux-2.4.29/include/asm-v850/v850e_timer_c.h linux-2.4.29-uc1/include/asm-v850/v850e_timer_c.h
--- linux-2.4.29/include/asm-v850/v850e_timer_c.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/v850e_timer_c.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,48 @@
+/*
+ * include/asm-v850/v850e_timer_c.h -- `Timer C' component often used
+ *	with the V850E cpu core
+ *
+ *  Copyright (C) 2001,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+/* NOTE: this include file currently contains only enough to allow us to
+   use timer C as an interrupt pass-through.  */
+
+#ifndef __V850_V850E_TIMER_C_H__
+#define __V850_V850E_TIMER_C_H__
+
+#include <asm/types.h>
+#include <asm/machdep.h>	/* Pick up chip-specific defs.  */
+
+
+/* Timer C (16-bit interval timers).  */
+
+/* Control register 0 for timer C.  */
+#define V850E_TIMER_C_TMCC0_ADDR(n) (V850E_TIMER_C_BASE_ADDR + 0x6 + 0x10 *(n))
+#define V850E_TIMER_C_TMCC0(n)	  (*(volatile u8 *)V850E_TIMER_C_TMCC0_ADDR(n))
+#define V850E_TIMER_C_TMCC0_CAE	  0x01 /* clock action enable */
+#define V850E_TIMER_C_TMCC0_CE	  0x02 /* count enable */
+/* ... */
+
+/* Control register 1 for timer C.  */
+#define V850E_TIMER_C_TMCC1_ADDR(n) (V850E_TIMER_C_BASE_ADDR + 0x8 + 0x10 *(n))
+#define V850E_TIMER_C_TMCC1(n)	  (*(volatile u8 *)V850E_TIMER_C_TMCC1_ADDR(n))
+#define V850E_TIMER_C_TMCC1_CMS0  0x01 /* capture/compare mode select (ccc0) */
+#define V850E_TIMER_C_TMCC1_CMS1  0x02 /* capture/compare mode select (ccc1) */
+/* ... */
+
+/* Interrupt edge-sensitivity control for timer C.  */
+#define V850E_TIMER_C_SESC_ADDR(n) (V850E_TIMER_C_BASE_ADDR + 0x9 + 0x10 *(n))
+#define V850E_TIMER_C_SESC(n)	  (*(volatile u8 *)V850E_TIMER_C_SESC_ADDR(n))
+
+/* ...etc... */
+
+
+#endif /* __V850_V850E_TIMER_C_H__  */
diff -urN linux-2.4.29/include/asm-v850/v850e_timer_d.h linux-2.4.29-uc1/include/asm-v850/v850e_timer_d.h
--- linux-2.4.29/include/asm-v850/v850e_timer_d.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/v850e_timer_d.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,62 @@
+/*
+ * include/asm-v850/v850e_timer_d.h -- `Timer D' component often used
+ *	with the V850E cpu core
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_V850E_TIMER_D_H__
+#define __V850_V850E_TIMER_D_H__
+
+#include <asm/types.h>
+#include <asm/machdep.h>	/* Pick up chip-specific defs.  */
+
+
+/* Timer D (16-bit interval timers).  */
+
+/* Count registers for timer D.  */
+#define V850E_TIMER_D_TMD_ADDR(n) (V850E_TIMER_D_TMD_BASE_ADDR + 0x10 * (n))
+#define V850E_TIMER_D_TMD(n)	  (*(volatile u16 *)V850E_TIMER_D_TMD_ADDR(n))
+
+/* Count compare registers for timer D.  */
+#define V850E_TIMER_D_CMD_ADDR(n) (V850E_TIMER_D_CMD_BASE_ADDR + 0x10 * (n))
+#define V850E_TIMER_D_CMD(n)	  (*(volatile u16 *)V850E_TIMER_D_CMD_ADDR(n))
+
+/* Control registers for timer D.  */
+#define V850E_TIMER_D_TMCD_ADDR(n) (V850E_TIMER_D_TMCD_BASE_ADDR + 0x10 * (n))
+#define V850E_TIMER_D_TMCD(n)	   (*(volatile u8 *)V850E_TIMER_D_TMCD_ADDR(n))
+/* Control bits for timer D.  */
+#define V850E_TIMER_D_TMCD_CE  	   0x2 /* count enable */
+#define V850E_TIMER_D_TMCD_CAE	   0x1 /* clock action enable */
+/* Clock divider setting (log2).  */
+#define V850E_TIMER_D_TMCD_CS(divlog2) (((divlog2) - V850E_TIMER_D_TMCD_CS_MIN) << 4)
+/* Minimum clock divider setting (log2).  */
+#ifndef V850E_TIMER_D_TMCD_CS_MIN /* Can be overridden by mach-specific hdrs */
+#define V850E_TIMER_D_TMCD_CS_MIN  2 /* Default is correct for the v850e/ma1 */
+#endif
+/* Maximum clock divider setting (log2).  */
+#define V850E_TIMER_D_TMCD_CS_MAX  (V850E_TIMER_D_TMCD_CS_MIN + 7)
+
+/* Return the clock-divider (log2) of timer D unit N.  */
+#define V850E_TIMER_D_DIVLOG2(n) \
+  (((V850E_TIMER_D_TMCD(n) >> 4) & 0x7) + V850E_TIMER_D_TMCD_CS_MIN)
+
+
+#ifndef __ASSEMBLY__
+
+/* Start interval timer TIMER (0-3).  The timer will issue the
+   corresponding INTCMD interrupt RATE times per second.  This function
+   does not enable the interrupt.  */
+extern void v850e_timer_d_configure (unsigned timer, unsigned rate);
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_V850E_TIMER_D_H__  */
diff -urN linux-2.4.29/include/asm-v850/v850e_uarta.h linux-2.4.29-uc1/include/asm-v850/v850e_uarta.h
--- linux-2.4.29/include/asm-v850/v850e_uarta.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/v850e_uarta.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,278 @@
+/*
+ * include/asm-v850/v850e_uarta.h -- original V850E on-chip UART
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+/* This is the original V850E UART implementation is called just `UART' in
+   the docs, but we name this header file <asm/v850e_uarta.h> because the
+   name <asm/v850e_uart.h> is used for the common driver that handles both
+   `UART' and `UARTB' implementations.  */
+
+#ifndef __V850_V850E_UARTA_H__
+#define __V850_V850E_UARTA_H__
+
+
+/* Raw hardware interface.  */
+
+/* The base address of the UART control registers for channel N.
+   The default is the address used on the V850E/MA1.  */
+#ifndef V850E_UART_BASE_ADDR
+#define V850E_UART_BASE_ADDR(n)		(0xFFFFFA00 + 0x10 * (n))
+#endif 
+
+/* Addresses of specific UART control registers for channel N.
+   The defaults are the addresses used on the V850E/MA1; if a platform
+   wants to redefine any of these, it must redefine them all.  */
+#ifndef V850E_UART_ASIM_ADDR
+#define V850E_UART_ASIM_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x0)
+#define V850E_UART_RXB_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x2)
+#define V850E_UART_ASIS_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x3)
+#define V850E_UART_TXB_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x4)
+#define V850E_UART_ASIF_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x5)
+#define V850E_UART_CKSR_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x6)
+#define V850E_UART_BRGC_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x7)
+#endif
+
+/* UART config registers.  */
+#define V850E_UART_ASIM(n)	(*(volatile u8 *)V850E_UART_ASIM_ADDR(n))
+/* Control bits for config registers.  */
+#define V850E_UART_ASIM_CAE	0x80 /* clock enable */
+#define V850E_UART_ASIM_TXE	0x40 /* transmit enable */
+#define V850E_UART_ASIM_RXE	0x20 /* receive enable */
+#define V850E_UART_ASIM_PS_MASK	0x18 /* mask covering parity-select bits */
+#define V850E_UART_ASIM_PS_NONE	0x00 /* no parity */
+#define V850E_UART_ASIM_PS_ZERO	0x08 /* zero parity */
+#define V850E_UART_ASIM_PS_ODD	0x10 /* odd parity */
+#define V850E_UART_ASIM_PS_EVEN	0x18 /* even parity */
+#define V850E_UART_ASIM_CL_8	0x04 /* char len is 8 bits (otherwise, 7) */
+#define V850E_UART_ASIM_SL_2	0x02 /* 2 stop bits (otherwise, 1) */
+#define V850E_UART_ASIM_ISRM	0x01 /* generate INTSR interrupt on errors
+					(otherwise, generate INTSER) */
+
+/* UART serial interface status registers.  */
+#define V850E_UART_ASIS(n)	(*(volatile u8 *)V850E_UART_ASIS_ADDR(n))
+/* Control bits for status registers.  */
+#define V850E_UART_ASIS_PE	0x04 /* parity error */
+#define V850E_UART_ASIS_FE	0x02 /* framing error */
+#define V850E_UART_ASIS_OVE	0x01 /* overrun error */
+
+/* UART serial interface transmission status registers.  */
+#define V850E_UART_ASIF(n)	(*(volatile u8 *)V850E_UART_ASIF_ADDR(n))
+#define V850E_UART_ASIF_TXBF	0x02 /* transmit buffer flag (data in TXB) */
+#define V850E_UART_ASIF_TXSF	0x01 /* transmit shift flag (sending data) */
+
+/* UART receive buffer register.  */
+#define V850E_UART_RXB(n)	(*(volatile u8 *)V850E_UART_RXB_ADDR(n))
+
+/* UART transmit buffer register.  */
+#define V850E_UART_TXB(n)	(*(volatile u8 *)V850E_UART_TXB_ADDR(n))
+
+/* UART baud-rate generator control registers.  */
+#define V850E_UART_CKSR(n)	(*(volatile u8 *)V850E_UART_CKSR_ADDR(n))
+#define V850E_UART_CKSR_MAX	11
+#define V850E_UART_BRGC(n)	(*(volatile u8 *)V850E_UART_BRGC_ADDR(n))
+#define V850E_UART_BRGC_MIN	8
+
+
+#ifndef V850E_UART_CKSR_MAX_FREQ
+#define V850E_UART_CKSR_MAX_FREQ (25*1000*1000)
+#endif
+
+/* Calculate the minimum value for CKSR on this processor.  */
+static inline unsigned v850e_uart_cksr_min (void)
+{
+	int min = 0;
+	unsigned freq = V850E_UART_BASE_FREQ;
+	while (freq > V850E_UART_CKSR_MAX_FREQ) {
+		freq >>= 1;
+		min++;
+	}
+	return min;
+}
+
+
+/* Slightly abstract interface used by driver.  */
+
+
+/* Interrupts used by the UART.  */
+
+/* Received when the most recently transmitted character has been sent.  */
+#define V850E_UART_TX_IRQ(chan)		IRQ_INTST (chan)
+/* Received when a new character has been received.  */
+#define V850E_UART_RX_IRQ(chan)		IRQ_INTSR (chan)
+
+
+/* UART clock generator interface.  */
+
+/* This type encapsulates a particular uart frequency.  */
+typedef struct {
+	unsigned clk_divlog2;
+	unsigned brgen_count;
+} v850e_uart_speed_t;
+
+/* Calculate a uart speed from BAUD for this uart.  */
+static inline v850e_uart_speed_t v850e_uart_calc_speed (unsigned baud)
+{
+	v850e_uart_speed_t speed;
+
+	/* Calculate the log2 clock divider and baud-rate counter values
+	   (note that the UART divides the resulting clock by 2, so
+	   multiply BAUD by 2 here to compensate).  */
+	calc_counter_params (V850E_UART_BASE_FREQ, baud * 2,
+			     v850e_uart_cksr_min(),
+			     V850E_UART_CKSR_MAX, 8/*bits*/,
+			     &speed.clk_divlog2, &speed.brgen_count);
+
+	return speed;
+}
+
+/* Return the current speed of uart channel CHAN.  */
+static inline v850e_uart_speed_t v850e_uart_speed (unsigned chan)
+{
+	v850e_uart_speed_t speed;
+	speed.clk_divlog2 = V850E_UART_CKSR (chan);
+	speed.brgen_count = V850E_UART_BRGC (chan);
+	return speed;
+}
+
+/* Set the current speed of uart channel CHAN.  */
+static inline void v850e_uart_set_speed(unsigned chan,v850e_uart_speed_t speed)
+{
+	V850E_UART_CKSR (chan) = speed.clk_divlog2;
+	V850E_UART_BRGC (chan) = speed.brgen_count;
+}
+
+static inline int
+v850e_uart_speed_eq (v850e_uart_speed_t speed1, v850e_uart_speed_t speed2)
+{
+	return speed1.clk_divlog2 == speed2.clk_divlog2
+		&& speed1.brgen_count == speed2.brgen_count;
+}
+
+/* Minimum baud rate possible.  */
+#define v850e_uart_min_baud() \
+   ((V850E_UART_BASE_FREQ >> V850E_UART_CKSR_MAX) / (2 * 255) + 1)
+
+/* Maximum baud rate possible.  The error is quite high at max, though.  */
+#define v850e_uart_max_baud() \
+   ((V850E_UART_BASE_FREQ >> v850e_uart_cksr_min()) / (2 *V850E_UART_BRGC_MIN))
+
+/* The `maximum' clock rate the uart can used, which is wanted (though not
+   really used in any useful way) by the serial framework.  */
+#define v850e_uart_max_clock() \
+   ((V850E_UART_BASE_FREQ >> v850e_uart_cksr_min()) / 2)
+
+
+/* UART configuration interface.  */
+
+/* Type of the uart config register; must be a scalar.  */
+typedef u16 v850e_uart_config_t;
+
+/* The uart hardware config register for channel CHAN.  */
+#define V850E_UART_CONFIG(chan)		V850E_UART_ASIM (chan)
+
+/* This config bit set if the uart is enabled.  */
+#define V850E_UART_CONFIG_ENABLED	V850E_UART_ASIM_CAE
+/* If the uart _isn't_ enabled, store this value to it to do so.  */
+#define V850E_UART_CONFIG_INIT		V850E_UART_ASIM_CAE
+/* Store this config value to disable the uart channel completely.  */
+#define V850E_UART_CONFIG_FINI		0
+
+/* Setting/clearing these bits enable/disable TX/RX, respectively (but
+   otherwise generally leave things running).  */
+#define V850E_UART_CONFIG_RX_ENABLE	V850E_UART_ASIM_RXE
+#define V850E_UART_CONFIG_TX_ENABLE	V850E_UART_ASIM_TXE
+
+/* These masks define which config bits affect TX/RX modes, respectively.  */
+#define V850E_UART_CONFIG_RX_BITS \
+  (V850E_UART_ASIM_PS_MASK | V850E_UART_ASIM_CL_8 | V850E_UART_ASIM_ISRM)
+#define V850E_UART_CONFIG_TX_BITS \
+  (V850E_UART_ASIM_PS_MASK | V850E_UART_ASIM_CL_8 | V850E_UART_ASIM_SL_2)
+
+static inline v850e_uart_config_t v850e_uart_calc_config (unsigned cflags)
+{
+	v850e_uart_config_t config = 0;
+
+	/* Figure out new configuration of control register.  */
+	if (cflags & CSTOPB)
+		/* Number of stop bits, 1 or 2.  */
+		config |= V850E_UART_ASIM_SL_2;
+	if ((cflags & CSIZE) == CS8)
+		/* Number of data bits, 7 or 8.  */
+		config |= V850E_UART_ASIM_CL_8;
+	if (! (cflags & PARENB))
+		/* No parity check/generation.  */
+		config |= V850E_UART_ASIM_PS_NONE;
+	else if (cflags & PARODD)
+		/* Odd parity check/generation.  */
+		config |= V850E_UART_ASIM_PS_ODD;
+	else
+		/* Even parity check/generation.  */
+		config |= V850E_UART_ASIM_PS_EVEN;
+	if (cflags & CREAD)
+		/* Reading enabled.  */
+		config |= V850E_UART_ASIM_RXE;
+
+	config |= V850E_UART_ASIM_CAE;
+	config |= V850E_UART_ASIM_TXE; /* Writing is always enabled.  */
+	config |= V850E_UART_ASIM_ISRM; /* Errors generate a read-irq.  */
+
+	return config;
+}
+
+/* This should delay as long as necessary for a recently written config
+   setting to settle, before we turn the uart back on.  */
+static inline void
+v850e_uart_config_delay (v850e_uart_config_t config, v850e_uart_speed_t speed)
+{
+	/* The UART may not be reset properly unless we wait at least 2
+	   `basic-clocks' until turning on the TXE/RXE bits again.
+	   A `basic clock' is the clock used by the baud-rate generator,
+	   i.e., the cpu clock divided by the 2^new_clk_divlog2.
+	   The loop takes 2 insns, so loop CYCLES / 2 times.  */
+	register unsigned count = 1 << speed.clk_divlog2;
+	while (--count != 0)
+		/* nothing */;
+}
+
+
+/* RX/TX interface.  */
+
+/* Return true if all characters awaiting transmission on uart channel N
+   have been transmitted.  */
+#define v850e_uart_xmit_done(n)						      \
+   (! (V850E_UART_ASIF(n) & V850E_UART_ASIF_TXBF))
+/* Wait for this to be true.  */
+#define v850e_uart_wait_for_xmit_done(n)				      \
+   do { } while (! v850e_uart_xmit_done (n))
+
+/* Return true if uart channel N is ready to transmit a character.  */
+#define v850e_uart_xmit_ok(n)						      \
+   (v850e_uart_xmit_done(n) && v850e_uart_cts(n))
+/* Wait for this to be true.  */
+#define v850e_uart_wait_for_xmit_ok(n)					      \
+   do { } while (! v850e_uart_xmit_ok (n))
+
+/* Write character CH to uart channel CHAN.  */
+#define v850e_uart_putc(chan, ch)	(V850E_UART_TXB(chan) = (ch))
+
+/* Return latest character read on channel CHAN.  */
+#define v850e_uart_getc(chan)		V850E_UART_RXB (chan)
+
+/* Return bit-mask of uart error status.  */
+#define v850e_uart_err(chan)		V850E_UART_ASIS (chan)
+/* Various error bits set in the error result.  */
+#define V850E_UART_ERR_OVERRUN		V850E_UART_ASIS_OVE
+#define V850E_UART_ERR_FRAME		V850E_UART_ASIS_FE
+#define V850E_UART_ERR_PARITY		V850E_UART_ASIS_PE
+
+
+#endif /* __V850_V850E_UARTA_H__ */
diff -urN linux-2.4.29/include/asm-v850/v850e_uartb.h linux-2.4.29-uc1/include/asm-v850/v850e_uartb.h
--- linux-2.4.29/include/asm-v850/v850e_uartb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/v850e_uartb.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,262 @@
+/*
+ * include/asm-v850/v850e_uartb.h -- V850E on-chip `UARTB' UART
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+/* The V850E UARTB is basically a superset of the original V850E UART, but
+   even where it's the same, the names and details have changed a bit.
+   It's similar enough to use the same driver (v850e_uart.c), but the
+   details have been abstracted slightly to do so.  */
+
+#ifndef __V850_V850E_UARTB_H__
+#define __V850_V850E_UARTB_H__
+
+
+/* Raw hardware interface.  */
+
+#define V850E_UARTB_BASE_ADDR(n)	(0xFFFFFA00 + 0x10 * (n))
+
+/* Addresses of specific UART control registers for channel N.  */
+#define V850E_UARTB_CTL0_ADDR(n)	(V850E_UARTB_BASE_ADDR(n) + 0x0)
+#define V850E_UARTB_CTL2_ADDR(n)	(V850E_UARTB_BASE_ADDR(n) + 0x2)
+#define V850E_UARTB_STR_ADDR(n)		(V850E_UARTB_BASE_ADDR(n) + 0x4)
+#define V850E_UARTB_RX_ADDR(n)		(V850E_UARTB_BASE_ADDR(n) + 0x6)
+#define V850E_UARTB_RXAP_ADDR(n)	(V850E_UARTB_BASE_ADDR(n) + 0x6)
+#define V850E_UARTB_TX_ADDR(n)		(V850E_UARTB_BASE_ADDR(n) + 0x8)
+#define V850E_UARTB_FIC0_ADDR(n)	(V850E_UARTB_BASE_ADDR(n) + 0xA)
+#define V850E_UARTB_FIC1_ADDR(n)	(V850E_UARTB_BASE_ADDR(n) + 0xB)
+#define V850E_UARTB_FIC2_ADDR(n)	(V850E_UARTB_BASE_ADDR(n) + 0xC)
+#define V850E_UARTB_FIS0_ADDR(n)	(V850E_UARTB_BASE_ADDR(n) + 0xE)
+#define V850E_UARTB_FIS1_ADDR(n)	(V850E_UARTB_BASE_ADDR(n) + 0xF)
+
+/* UARTB control register 0 (general config).  */
+#define V850E_UARTB_CTL0(n)	(*(volatile u8 *)V850E_UARTB_CTL0_ADDR(n))
+/* Control bits for config registers.  */
+#define V850E_UARTB_CTL0_PWR		0x80	/* clock enable */
+#define V850E_UARTB_CTL0_TXE		0x40	/* transmit enable */
+#define V850E_UARTB_CTL0_RXE		0x20	/* receive enable */
+#define V850E_UARTB_CTL0_DIR		0x10	/*  */
+#define V850E_UARTB_CTL0_PS1		0x08	/* parity */
+#define V850E_UARTB_CTL0_PS0		0x04	/* parity */
+#define V850E_UARTB_CTL0_CL		0x02	/* char len 1:8bit, 0:7bit */
+#define V850E_UARTB_CTL0_SL		0x01	/* stop bit 1:2bit, 0:1bit */
+#define V850E_UARTB_CTL0_PS_MASK	0x0C	/* mask covering parity bits */
+#define V850E_UARTB_CTL0_PS_NONE	0x00	/* no parity */
+#define V850E_UARTB_CTL0_PS_ZERO	0x04	/* zero parity */
+#define V850E_UARTB_CTL0_PS_ODD		0x08	/* odd parity */
+#define V850E_UARTB_CTL0_PS_EVEN	0x0C	/* even parity */
+#define V850E_UARTB_CTL0_CL_8		0x02	/* char len 1:8bit, 0:7bit */
+#define V850E_UARTB_CTL0_SL_2		0x01	/* stop bit 1:2bit, 0:1bit */
+
+/* UARTB control register 2 (clock divider).  */
+#define V850E_UARTB_CTL2(n)	(*(volatile u16 *)V850E_UARTB_CTL2_ADDR(n))
+#define V850E_UARTB_CTL2_MIN	4
+#define V850E_UARTB_CTL2_MAX	0xFFFF
+
+/* UARTB serial interface status register.  */
+#define V850E_UARTB_STR(n)	(*(volatile u8 *)V850E_UARTB_STR_ADDR(n))
+/* Control bits for status registers.  */
+#define V850E_UARTB_STR_TSF	0x80	/* UBTX or FIFO exist data  */
+#define V850E_UARTB_STR_OVF	0x08	/* overflow error */
+#define V850E_UARTB_STR_PE	0x04	/* parity error */
+#define V850E_UARTB_STR_FE	0x02	/* framing error */
+#define V850E_UARTB_STR_OVE	0x01	/* overrun error */
+
+/* UARTB receive data register.  */
+#define V850E_UARTB_RX(n)	(*(volatile u8 *)V850E_UARTB_RX_ADDR(n))
+#define V850E_UARTB_RXAP(n)	(*(volatile u16 *)V850E_UARTB_RXAP_ADDR(n))
+/* Control bits for status registers.  */
+#define V850E_UARTB_RXAP_PEF	0x0200 /* parity error */
+#define V850E_UARTB_RXAP_FEF	0x0100 /* framing error */
+
+/* UARTB transmit data register.  */
+#define V850E_UARTB_TX(n)	(*(volatile u8 *)V850E_UARTB_TX_ADDR(n))
+
+/* UARTB FIFO control register 0.  */
+#define V850E_UARTB_FIC0(n)	(*(volatile u8 *)V850E_UARTB_FIC0_ADDR(n))
+
+/* UARTB FIFO control register 1.  */
+#define V850E_UARTB_FIC1(n)	(*(volatile u8 *)V850E_UARTB_FIC1_ADDR(n))
+
+/* UARTB FIFO control register 2.  */
+#define V850E_UARTB_FIC2(n)	(*(volatile u16 *)V850E_UARTB_FIC2_ADDR(n))
+
+/* UARTB FIFO status register 0.  */
+#define V850E_UARTB_FIS0(n)	(*(volatile u8 *)V850E_UARTB_FIS0_ADDR(n))
+
+/* UARTB FIFO status register 1.  */
+#define V850E_UARTB_FIS1(n)	(*(volatile u8 *)V850E_UARTB_FIS1_ADDR(n))
+
+
+/* Slightly abstract interface used by driver.  */
+
+
+/* Interrupts used by the UART.  */
+
+/* Received when the most recently transmitted character has been sent.  */
+#define V850E_UART_TX_IRQ(chan)		IRQ_INTUBTIT (chan)
+/* Received when a new character has been received.  */
+#define V850E_UART_RX_IRQ(chan)		IRQ_INTUBTIR (chan)
+
+/* Use by serial driver for information purposes.  */
+#define V850E_UART_BASE_ADDR(chan)	V850E_UARTB_BASE_ADDR(chan)
+
+
+/* UART clock generator interface.  */
+
+/* This type encapsulates a particular uart frequency.  */
+typedef u16 v850e_uart_speed_t;
+
+/* Calculate a uart speed from BAUD for this uart.  */
+static inline v850e_uart_speed_t v850e_uart_calc_speed (unsigned baud)
+{
+	v850e_uart_speed_t speed;
+
+	/*
+	 * V850E/ME2 UARTB baud rate is determined by the value of UBCTL2
+	 * fx = V850E_UARTB_BASE_FREQ = CPU_CLOCK_FREQ/4
+	 * baud = fx / 2*speed   [ speed >= 4 ]
+	 */
+	speed = V850E_UARTB_CTL2_MIN;
+	while (((V850E_UARTB_BASE_FREQ / 2) / speed ) > baud)
+		speed++;
+
+	return speed;
+}
+
+/* Return the current speed of uart channel CHAN.  */
+#define v850e_uart_speed(chan)		    V850E_UARTB_CTL2 (chan)
+
+/* Set the current speed of uart channel CHAN.  */
+#define v850e_uart_set_speed(chan, speed)   (V850E_UARTB_CTL2 (chan) = (speed))
+
+/* Return true if SPEED1 and SPEED2 are the same.  */
+#define v850e_uart_speed_eq(speed1, speed2) ((speed1) == (speed2))
+
+/* Minimum baud rate possible.  */
+#define v850e_uart_min_baud() \
+   ((V850E_UARTB_BASE_FREQ / 2) / V850E_UARTB_CTL2_MAX)
+
+/* Maximum baud rate possible.  The error is quite high at max, though.  */
+#define v850e_uart_max_baud() \
+   ((V850E_UARTB_BASE_FREQ / 2) / V850E_UARTB_CTL2_MIN)
+
+/* The `maximum' clock rate the uart can used, which is wanted (though not
+   really used in any useful way) by the serial framework.  */
+#define v850e_uart_max_clock() \
+   (V850E_UARTB_BASE_FREQ / 2)
+
+
+/* UART configuration interface.  */
+
+/* Type of the uart config register; must be a scalar.  */
+typedef u16 v850e_uart_config_t;
+
+/* The uart hardware config register for channel CHAN.  */
+#define V850E_UART_CONFIG(chan)		V850E_UARTB_CTL0 (chan)
+
+/* This config bit set if the uart is enabled.  */
+#define V850E_UART_CONFIG_ENABLED	V850E_UARTB_CTL0_PWR
+/* If the uart _isn't_ enabled, store this value to it to do so.  */
+#define V850E_UART_CONFIG_INIT		V850E_UARTB_CTL0_PWR
+/* Store this config value to disable the uart channel completely.  */
+#define V850E_UART_CONFIG_FINI		0
+
+/* Setting/clearing these bits enable/disable TX/RX, respectively (but
+   otherwise generally leave things running).  */
+#define V850E_UART_CONFIG_RX_ENABLE	V850E_UARTB_CTL0_RXE
+#define V850E_UART_CONFIG_TX_ENABLE	V850E_UARTB_CTL0_TXE
+
+/* These masks define which config bits affect TX/RX modes, respectively.  */
+#define V850E_UART_CONFIG_RX_BITS \
+  (V850E_UARTB_CTL0_PS_MASK | V850E_UARTB_CTL0_CL_8)
+#define V850E_UART_CONFIG_TX_BITS \
+  (V850E_UARTB_CTL0_PS_MASK | V850E_UARTB_CTL0_CL_8 | V850E_UARTB_CTL0_SL_2)
+
+static inline v850e_uart_config_t v850e_uart_calc_config (unsigned cflags)
+{
+	v850e_uart_config_t config = 0;
+
+	/* Figure out new configuration of control register.  */
+	if (cflags & CSTOPB)
+		/* Number of stop bits, 1 or 2.  */
+		config |= V850E_UARTB_CTL0_SL_2;
+	if ((cflags & CSIZE) == CS8)
+		/* Number of data bits, 7 or 8.  */
+		config |= V850E_UARTB_CTL0_CL_8;
+	if (! (cflags & PARENB))
+		/* No parity check/generation.  */
+		config |= V850E_UARTB_CTL0_PS_NONE;
+	else if (cflags & PARODD)
+		/* Odd parity check/generation.  */
+		config |= V850E_UARTB_CTL0_PS_ODD;
+	else
+		/* Even parity check/generation.  */
+		config |= V850E_UARTB_CTL0_PS_EVEN;
+	if (cflags & CREAD)
+		/* Reading enabled.  */
+		config |= V850E_UARTB_CTL0_RXE;
+
+	config |= V850E_UARTB_CTL0_PWR;
+	config |= V850E_UARTB_CTL0_TXE; /* Writing is always enabled.  */
+	config |= V850E_UARTB_CTL0_DIR; /* LSB first.  */
+
+	return config;
+}
+
+/* This should delay as long as necessary for a recently written config
+   setting to settle, before we turn the uart back on.  */
+static inline void
+v850e_uart_config_delay (v850e_uart_config_t config, v850e_uart_speed_t speed)
+{
+	/* The UART may not be reset properly unless we wait at least 2
+	   `basic-clocks' until turning on the TXE/RXE bits again.
+	   A `basic clock' is the clock used by the baud-rate generator,
+	   i.e., the cpu clock divided by the 2^new_clk_divlog2.
+	   The loop takes 2 insns, so loop CYCLES / 2 times.  */
+	register unsigned count = 1 << speed;
+	while (--count != 0)
+		/* nothing */;
+}
+
+
+/* RX/TX interface.  */
+
+/* Return true if all characters awaiting transmission on uart channel N
+   have been transmitted.  */
+#define v850e_uart_xmit_done(n)						      \
+   (! (V850E_UARTB_STR(n) & V850E_UARTB_STR_TSF))
+/* Wait for this to be true.  */
+#define v850e_uart_wait_for_xmit_done(n)				      \
+   do { } while (! v850e_uart_xmit_done (n))
+
+/* Return true if uart channel N is ready to transmit a character.  */
+#define v850e_uart_xmit_ok(n)						      \
+   (v850e_uart_xmit_done(n) && v850e_uart_cts(n))
+/* Wait for this to be true.  */
+#define v850e_uart_wait_for_xmit_ok(n)					      \
+   do { } while (! v850e_uart_xmit_ok (n))
+
+/* Write character CH to uart channel CHAN.  */
+#define v850e_uart_putc(chan, ch)	(V850E_UARTB_TX(chan) = (ch))
+
+/* Return latest character read on channel CHAN.  */
+#define v850e_uart_getc(chan)		V850E_UARTB_RX (chan)
+
+/* Return bit-mask of uart error status.  */
+#define v850e_uart_err(chan)		V850E_UARTB_STR (chan)
+/* Various error bits set in the error result.  */
+#define V850E_UART_ERR_OVERRUN		V850E_UARTB_STR_OVE
+#define V850E_UART_ERR_FRAME		V850E_UARTB_STR_FE
+#define V850E_UART_ERR_PARITY		V850E_UARTB_STR_PE
+
+
+#endif /* __V850_V850E_UARTB_H__ */
diff -urN linux-2.4.29/include/asm-v850/v850e_uart.h linux-2.4.29-uc1/include/asm-v850/v850e_uart.h
--- linux-2.4.29/include/asm-v850/v850e_uart.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/v850e_uart.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,76 @@
+/*
+ * include/asm-v850/v850e_uart.h -- common V850E on-chip UART driver
+ *
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+/* There's not actually a single UART implementation used by V850E CPUs,
+   but rather a series of implementations that are all `close' to one
+   another.  This file corresponds to the single driver which handles all
+   of them.  */
+
+#ifndef __V850_V850E_UART_H__
+#define __V850_V850E_UART_H__
+
+#include <linux/termios.h>
+
+#include <asm/v850e_utils.h>
+#include <asm/types.h>
+#include <asm/machdep.h>	/* Pick up chip-specific defs.  */
+
+
+/* Include model-specific definitions.  */
+#ifdef CONFIG_V850E_UART
+# ifdef CONFIG_V850E_UARTB
+#  include <asm-v850/v850e_uartb.h>
+# else
+#  include <asm-v850/v850e_uarta.h> /* original V850E UART */
+# endif
+#endif
+
+
+/* Optional capabilities some hardware provides.  */
+
+/* This UART doesn't implement RTS/CTS by default, but some platforms
+   implement them externally, so check to see if <asm/machdep.h> defined
+   anything.  */
+#ifdef V850E_UART_CTS
+#define v850e_uart_cts(n)		V850E_UART_CTS(n)
+#else
+#define v850e_uart_cts(n)		(1)
+#endif
+
+/* Do the same for RTS.  */
+#ifdef V850E_UART_SET_RTS
+#define v850e_uart_set_rts(n,v)		V850E_UART_SET_RTS(n,v)
+#else
+#define v850e_uart_set_rts(n,v)		((void)0)
+#endif
+
+
+/* This is the serial channel to use for the boot console (if desired).  */
+#ifndef V850E_UART_CONSOLE_CHANNEL
+# define V850E_UART_CONSOLE_CHANNEL 0
+#endif
+
+
+#ifndef __ASSEMBLY__
+
+/* Setup a console using channel 0 of the builtin uart.  */
+extern void v850e_uart_cons_init (unsigned chan);
+
+/* Configure and turn on uart channel CHAN, using the termios `control
+   modes' bits in CFLAGS, and a baud-rate of BAUD.  */
+void v850e_uart_configure (unsigned chan, unsigned cflags, unsigned baud);
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __V850_V850E_UART_H__ */
diff -urN linux-2.4.29/include/asm-v850/v850e_utils.h linux-2.4.29-uc1/include/asm-v850/v850e_utils.h
--- linux-2.4.29/include/asm-v850/v850e_utils.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/v850e_utils.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ * include/asm-v850/v850e_utils.h -- Utility functions associated with
+ *	V850E CPUs
+ *
+ *  Copyright (C) 2001,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,03  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_V850E_UTILS_H__
+#define __V850_V850E_UTILS_H__
+
+/* Calculate counter clock-divider and count values to attain the
+   desired frequency RATE from the base frequency BASE_FREQ.  The
+   counter is expected to have a clock-divider, which can divide the
+   system cpu clock by a power of two value from MIN_DIVLOG2 to
+   MAX_DIV_LOG2, and a word-size of COUNTER_SIZE bits (the counter
+   counts up and resets whenever it's equal to the compare register,
+   generating an interrupt or whatever when it does so).  The returned
+   values are: *DIVLOG2 -- log2 of the desired clock divider and *COUNT
+   -- the counter compare value to use.  Returns true if it was possible
+   to find a reasonable value, otherwise false (and the other return
+   values will be set to be as good as possible).  */
+extern int calc_counter_params (unsigned long base_freq,
+				unsigned long rate,
+				unsigned min_divlog2, unsigned max_divlog2,
+				unsigned counter_size,
+				unsigned *divlog2, unsigned *count);
+
+#endif /* __V850_V850E_UTILS_H__ */
diff -urN linux-2.4.29/include/asm-v850/virtconvert.h linux-2.4.29-uc1/include/asm-v850/virtconvert.h
--- linux-2.4.29/include/asm-v850/virtconvert.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/asm-v850/virtconvert.h	2005-06-14 02:11:30.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ * include/asm-v850/virtconvert.h -- conversion between virtual and
+ * 	physical mappings
+ *
+ *  Copyright (C) 2001,02  NEC Corporation
+ *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef __V850_VIRTCONVERT_H__
+#define __V850_VIRTCONVERT_H__
+
+#ifdef __KERNEL__
+
+#include <asm/page.h>
+
+#define mm_ptov(addr)		((void *)__phys_to_virt (addr))
+#define mm_vtop(addr)		((unsigned long)__virt_to_phys (addr))
+#define phys_to_virt(addr)	((void *)__phys_to_virt (addr))
+#define virt_to_phys(addr)	((unsigned long)__virt_to_phys (addr))
+
+#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define page_to_phys(page)	virt_to_phys((void *)__page_address(page))
+
+#endif /* __KERNEL__ */
+
+#endif /* __V850_VIRTCONVERT_H__ */
diff -urN linux-2.4.29/include/asm-x86_64/div64.h linux-2.4.29-uc1/include/asm-x86_64/div64.h
--- linux-2.4.29/include/asm-x86_64/div64.h	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-uc1/include/asm-x86_64/div64.h	2005-06-14 02:11:41.000000000 +0100
@@ -1,14 +1 @@
-#ifndef __X86_64_DIV64
-#define __X86_64_DIV64
-
-/*
- * Hey, we're already 64-bit, no
- * need to play games..
- */
-#define do_div(n,base) ({ \
-	int __res; \
-	__res = ((unsigned long) (n)) % (unsigned) (base); \
-	(n) = ((unsigned long) (n)) / (unsigned) (base); \
-	__res; })
-
-#endif
+#include <asm-generic/div64.h>
diff -urN linux-2.4.29/include/linux/atmioc.h linux-2.4.29-uc1/include/linux/atmioc.h
--- linux-2.4.29/include/linux/atmioc.h	2001-11-09 22:11:15.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/atmioc.h	2005-06-14 02:11:36.000000000 +0100
@@ -29,7 +29,7 @@
 #define ATMIOC_ITF_END	  0x8f
 #define ATMIOC_BACKEND	  0x90 /* ATM generic backend ioctls, u. per backend */
 #define ATMIOC_BACKEND_END 0xaf
-/* 0xb0-0xbf: Reserved for future use */
+#define ATMIOC_IPV6       0xb0 /* IPv6 enhancement, glob. u. */
 #define ATMIOC_AREQUIPA	  0xc0 /* Application requested IP over ATM, glob. u. */
 #define ATMIOC_LANE	  0xd0 /* LAN Emulation, globally unique */
 #define ATMIOC_MPOA       0xd8 /* MPOA, globally unique */
diff -urN linux-2.4.29/include/linux/atmipv6.h linux-2.4.29-uc1/include/linux/atmipv6.h
--- linux-2.4.29/include/linux/atmipv6.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/atmipv6.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,35 @@
+/* $USAGI: atmipv6.h,v 1.4 2003/05/28 23:27:31 yoshfuji Exp $
+ *
+ * RFC2492 IPv6 over ATM
+ *
+ * Copyright (C)2001 USAGI/WIDE Project
+ * 
+ * Written by Kazuyoshi SERIZAWA based on atmclip.h - Classical IP over ATM
+ * Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA
+ */
+
+#ifndef LINUX_ATMIPV6_H
+#define LINUX_ATMIPV6_H
+
+#include <linux/sockios.h>
+#include <linux/atmioc.h>
+
+
+#define RFC1483LLC_LEN	8		/* LLC+OUI+PID = 8 */
+#define RFC1626_MTU	9180		/* RFC1626 default MTU */
+
+#define CLIP_DEFAULT_IDLETIMER 1200	/* 20 minutes, see RFC1755 */
+#define CLIP_CHECK_INTERVAL	 10	/* check every ten seconds */
+
+#define	SIOCMKP2PPVC		_IO('a',ATMIOC_IPV6)	/* create Point to Point PVC */
+
+#define ATMIPV6_MKIPV6	_IO('a',ATMIOC_IPV6+1)	/* attach socket to IP */
+#define ATMIPV6_SETP2P	_IO('a',ATMIOC_IPV6+2)	/* attach socket to P2P PVC */
+#define ATMIPV6_ENCAP	_IO('a',ATMIOC_IPV6+3)	/* change encapsulation */
+
+#ifdef __KERNEL__
+extern const unsigned char llc_oui[6];
+//TODO: extern const unsigned char llc_oui[6];
+#endif
+
+#endif
diff -urN linux-2.4.29/include/linux/blk.h linux-2.4.29-uc1/include/linux/blk.h
--- linux-2.4.29/include/linux/blk.h	2002-08-03 01:39:45.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/blk.h	2005-06-14 02:11:37.000000000 +0100
@@ -46,6 +46,7 @@
 extern int bpcd_init(void);
 extern int ps2esdi_init(void);
 extern int jsfd_init(void);
+extern int blkmem_init(void);
 extern int viodasd_init(void);
 extern int viocd_init(void);
 
diff -urN linux-2.4.29/include/linux/blkmem.h linux-2.4.29-uc1/include/linux/blkmem.h
--- linux-2.4.29/include/linux/blkmem.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/blkmem.h	2005-06-14 02:11:37.000000000 +0100
@@ -0,0 +1,55 @@
+
+/* 
+ * linux/blkmem.h header file for Linux.
+ *
+ * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
+ *
+ */
+
+#ifndef _LINUX_BLKMEM_H
+#define _LINUX_BLKMEM_H
+
+#include <linux/ioctl.h>
+
+/*
+ * Structures and definitions for mag tape io control commands
+ */
+ 
+#define BMSERASE       1	/* erase sector containing address */
+#define BMSGSIZE       2	/* get size of sector */
+#define BMSGERASEVALUE 3	/* get value of bytes in erased sectors */
+#define BMGETSIZES     4	/* get length of device in sectors */
+#define BMGETSIZEB     5	/* get length of device in bytes */
+
+#define BMPROGRAM      6	/* program entire arena in one go */
+
+struct blkmem_program_t {
+	unsigned long magic1;
+	int	blocks;
+	int	reset;
+	unsigned long magic2;
+	struct {
+		unsigned char * data;
+		unsigned long pos;
+		unsigned long length;
+		int magic3;
+	}block[0];
+};
+
+#define BMPROGRAM_MAGIC_1 0x123abc32
+
+#define BMPROGRAM_MAGIC_2 0x9C00C00F
+
+#define BMPROGRAM_MAGIC_3 0x56408F26
+
+#if 0
+#define BMSSAUTOERASE  10	/* set auto-erase bits */
+#endif
+
+#define DEVICE_NAME "Blkmem"
+#define DEVICE_REQUEST do_blkmem_request
+#define DEVICE_NR(device) (MINOR(device))
+#define DEVICE_ON(device)
+#define DEVICE_OFF(device)
+
+#endif /* _LINUX_BLKMEM_H */
diff -urN linux-2.4.29/include/linux/compiler.h linux-2.4.29-uc1/include/linux/compiler.h
--- linux-2.4.29/include/linux/compiler.h	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/compiler.h	2005-06-14 02:11:35.000000000 +0100
@@ -6,7 +6,7 @@
    expect the blocks to be reordered appropriately.  Define __builtin_expect
    to nothing for earlier compilers.  */
 
-#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
+#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
 #define __builtin_expect(x, expected_value) (x)
 #endif
 
diff -urN linux-2.4.29/include/linux/console_struct.h linux-2.4.29-uc1/include/linux/console_struct.h
--- linux-2.4.29/include/linux/console_struct.h	2003-06-13 15:51:38.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/console_struct.h	2005-06-14 02:11:33.000000000 +0100
@@ -7,6 +7,8 @@
  * Fields marked with [#] must be set by the low-level driver.
  * Fields marked with [!] can be changed by the low-level driver
  * to achieve effects such as fast scrolling by changing the origin.
+ *
+ *  11/07/1998	RMK	Changed vc_state to be a function pointer
  */
 
 #ifndef _LINUX_CONSOLE_STRUCT_H_
@@ -34,7 +36,11 @@
 	unsigned short	vc_s_complement_mask;	/* Saved mouse pointer mask */
 	unsigned int	vc_x, vc_y;		/* Cursor position */
 	unsigned int	vc_top, vc_bottom;	/* Scrolling region */
+#ifdef CONSOLE_WIP
+	int (*vc_state)(int currcons, struct tty_struct *tty, unsigned int c);
+#else
 	unsigned int	vc_state;		/* Escape sequence parser state */
+#endif
 	unsigned int	vc_npar,vc_par[NPAR];	/* Parameters of current escape sequence */
 	unsigned long	vc_origin;		/* [!] Start of real screen */
 	unsigned long	vc_scr_end;		/* [!] End of real screen */
diff -urN linux-2.4.29/include/linux/cramfs_fs.h linux-2.4.29-uc1/include/linux/cramfs_fs.h
--- linux-2.4.29/include/linux/cramfs_fs.h	2002-08-03 01:39:45.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/cramfs_fs.h	2005-06-14 02:11:36.000000000 +0100
@@ -1,13 +1,25 @@
-#ifndef __CRAMFS_H
-#define __CRAMFS_H
+#ifndef __CRAMFS_FS_H
+#define __CRAMFS_FS_H
 
-#ifndef __KERNEL__
+#ifdef __KERNEL__
+
+#include <asm/byteorder.h>
+
+/* Uncompression interfaces to the underlying zlib */
+int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen);
+int cramfs_uncompress_init(void);
+int cramfs_uncompress_exit(void);
+
+#else /* not __KERNEL__ */
+
+#include <byteswap.h>
+#include <endian.h>
 
 typedef unsigned char u8;
 typedef unsigned short u16;
 typedef unsigned int u32;
 
-#endif
+#endif /* not __KERNEL__ */
 
 #define CRAMFS_MAGIC		0x28cd3d45	/* some random number */
 #define CRAMFS_SIGNATURE	"Compressed ROMFS"
@@ -90,9 +102,50 @@
 				| CRAMFS_FLAG_WRONG_SIGNATURE \
 				| CRAMFS_FLAG_SHIFTED_ROOT_OFFSET )
 
-/* Uncompression interfaces to the underlying zlib */
-int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen);
-int cramfs_uncompress_init(void);
-int cramfs_uncompress_exit(void);
+/*
+ * Since cramfs is little-endian, provide macros to swab the bitfields.
+ */
+
+#ifndef __BYTE_ORDER
+#if defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#elif defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN)
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
+#error "unable to define __BYTE_ORDER"
+#endif
+#endif /* not __BYTE_ORDER */
 
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#warning  "__BYTE_ORDER == __LITTLE_ENDIAN"
+#define CRAMFS_16(x)	(x)
+#define CRAMFS_24(x)	(x)
+#define CRAMFS_32(x)	(x)
+#define CRAMFS_GET_NAMELEN(x)	((x)->namelen)
+#define CRAMFS_GET_OFFSET(x)	((x)->offset)
+#define CRAMFS_SET_OFFSET(x,y)	((x)->offset = (y))
+#define CRAMFS_SET_NAMELEN(x,y)	((x)->namelen = (y))
+#elif __BYTE_ORDER == __BIG_ENDIAN
+#warning "__BYTE_ORDER == __BIG_ENDIAN"
+#ifdef __KERNEL__
+#define CRAMFS_16(x)	swab16(x)
+#define CRAMFS_24(x)	((swab32(x)) >> 8)
+#define CRAMFS_32(x)	swab32(x)
+#else /* not __KERNEL__ */
+#define CRAMFS_16(x)	bswap_16(x)
+#define CRAMFS_24(x)	((bswap_32(x)) >> 8)
+#define CRAMFS_32(x)	bswap_32(x)
+#endif /* not __KERNEL__ */
+#define CRAMFS_GET_NAMELEN(x)	(((u8*)(x))[8] & 0x3f)
+#define CRAMFS_GET_OFFSET(x)	((CRAMFS_24(((u32*)(x))[2] & 0xffffff) << 2) |\
+				 ((((u32*)(x))[2] & 0xc0000000) >> 30))
+#define CRAMFS_SET_NAMELEN(x,y)	(((u8*)(x))[8] = (((0x3f & (y))) | \
+						  (0xc0 & ((u8*)(x))[8])))
+#define CRAMFS_SET_OFFSET(x,y)	(((u32*)(x))[2] = (((y) & 3) << 30) | \
+				 CRAMFS_24((((y) & 0x03ffffff) >> 2)) | \
+				 (((u32)(((u8*)(x))[8] & 0x3f)) << 24))
+#else
+#error "__BYTE_ORDER must be __LITTLE_ENDIAN or __BIG_ENDIAN"
 #endif
+
+#endif /* not __CRAMFS_FS_H */
diff -urN linux-2.4.29/include/linux/de2fpga.h linux-2.4.29-uc1/include/linux/de2fpga.h
--- linux-2.4.29/include/linux/de2fpga.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/de2fpga.h	2005-06-14 02:11:34.000000000 +0100
@@ -0,0 +1,40 @@
+/*
+ *  linux/include/linux/de2fpga.h -- FPGA driver for the DragonEngine
+ *
+ *	Copyright (C) 2003 Georges Menie
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#ifndef _DE2FPGA_H
+#define _DE2FPGA_H
+
+#define DE2FPGA_PARAMS_GET _IOR('F', 0, struct de2fpga_info)
+#define DE2FPGA_RESET _IOR('F', 1, struct de2fpga_info)
+
+#define DE2FPGA_MAX_TAGLEN 128
+
+struct de2fpga_info {
+	int status;
+	int file;
+	int part;
+	int date;
+	int time;
+	char buf[DE2FPGA_MAX_TAGLEN];
+};
+
+#define DE2FPGA_STS_UNKNOWN 0
+#define DE2FPGA_STS_OK 1
+#define DE2FPGA_STS_DRV_ERROR -1 /* driver internal error */
+#define DE2FPGA_STS_HDR_ERROR -2 /* the bitstream header is not recognized */
+#define DE2FPGA_STS_TGL_ERROR -3 /* unknown tag letter in the bitstream */
+#define DE2FPGA_STS_TGC_ERROR -4 /* tag content length too long */
+#define DE2FPGA_STS_NSZ_ERROR -5 /* bitstream size is zero */
+#define DE2FPGA_STS_PRG_ERROR -6 /* error starting the programming mode */
+#define DE2FPGA_STS_EPR_ERROR -7 /* error ending the programming mode */
+#define DE2FPGA_STS_FIL_ERROR -8 /* bitstream format error */
+#define DE2FPGA_STS_REL_ERROR -9 /* unexpected end of bitstream */
+
+#endif
diff -urN linux-2.4.29/include/linux/de2ts.h linux-2.4.29-uc1/include/linux/de2ts.h
--- linux-2.4.29/include/linux/de2ts.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/de2ts.h	2005-06-14 02:11:35.000000000 +0100
@@ -0,0 +1,64 @@
+/*
+ *  linux/include/linux/de2ts.h -- Touchscreen driver for the DragonEngine
+ *
+ *	Copyright (C) 2003 Georges Menie
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#ifndef _DE2TS_H
+#define _DE2TS_H
+
+/* Pen events */
+#define EV_PEN_DOWN    1
+#define EV_PEN_MOVE    2
+#define EV_PEN_UP      3
+
+#define DE2TS_VERSION 2
+
+#define DE2TS_DRV_PARAMS_GET _IOR('T', 0, struct de2ts_drv_params)
+#define DE2TS_DRV_PARAMS_SET _IOR('T', 1, struct de2ts_drv_params)
+#define DE2TS_CAL_PARAMS_GET _IOR('T', 2, struct de2ts_cal_params)
+#define DE2TS_CAL_PARAMS_SET _IOR('T', 3, struct de2ts_cal_params)
+
+/* Available info from pen position and status */
+struct de2ts_event {
+	int x, y;					/* calculated pen position               */
+	int xraw, yraw;				/* raw pen position                      */
+	int event;					/* event from pen (DOWN,UP,MOVE)         */
+	int ev_no;					/* no of the event                       */
+	unsigned long ev_time;		/* time of the event (ms) since ts_open  */
+};
+
+/* Structures that define touch screen parameters */
+struct de2ts_drv_params {
+	short version;				/* version number for check, returned by xx_PARAMS_GET */
+								/* you have to set it to DE2TS_VERSION when calling    */
+								/* xx_PARAMS_SET                                       */
+
+	short max_samples_x;		/* maximum number of samples before giving up, for x   */
+	short max_samples_y;		/* and for y conversion                                */
+	short min_equals_x;			/* validate the position when this cconsecutive number */
+	short min_equals_y;			/* of samples on x and y has been reached              */
+	short max_error;			/* below this level, two consecutive samples are equal */
+	short max_speed;			/* max speed allowed. To remove spikes while moving    */
+
+	short xysw;					/* swap x and y coord.    */
+};
+
+struct de2ts_cal_params {
+	short version;				/* version number for check, returned by xx_PARAMS_GET */
+								/* you have to set it to DE2TS_VERSION when calling    */
+								/* xx_PARAMS_SET                                       */
+
+	short xoff;					/* calibration data       */
+	short xden;					/*                        */
+	short yoff;					/*                        */
+	short yden;					/*                        */
+	short xrng;					/* output range coord.    */
+	short yrng;					/*                        */
+};
+
+#endif
diff -urN linux-2.4.29/include/linux/elf.h linux-2.4.29-uc1/include/linux/elf.h
--- linux-2.4.29/include/linux/elf.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/elf.h	2005-06-14 02:11:37.000000000 +0100
@@ -78,6 +78,9 @@
 
 #define EM_SPARCV9     43	/* SPARC v9 64-bit */
 
+#define EM_H8_300H     47       /* Hitachi H8/300H */ 
+#define EM_H8_S        48       /* Hitachi H8S */
+
 #define EM_IA_64	50	/* HP/Intel IA-64 */
 
 #define EM_X86_64	62	/* AMD x86-64 */
@@ -86,6 +89,8 @@
 
 #define EM_CRIS         76      /* Axis Communications 32-bit embedded processor */
 
+#define EM_V850		87	/* NEC v850 */
+
 /*
  * This is an interim value that we will use until the committee comes
  * up with a final number.
@@ -97,6 +102,9 @@
  */
 #define EM_S390_OLD     0xA390
 
+#define EM_NIOS32	0xfebb		/* Altera NIOS 32 */
+#define EM_NIOS		EM_NIOS32	/* Altera NIOS */
+
 /* This is the info that is needed to parse the dynamic section of the file */
 #define DT_NULL		0
 #define DT_NEEDED	1
@@ -613,4 +621,25 @@
 #endif
 
 
+/* Altera NIOS specific */
+#define R_NIOS_NONE		0
+#define R_NIOS_32		1	/* A 32 bit absolute relocation.*/
+#define R_NIOS_LO16_LO5		2	/* A LO-16 5 bit absolute relocation.  */
+#define R_NIOS_LO16_HI11	3	/* A LO-16 top 11 bit absolute relocation.  */
+#define R_NIOS_HI16_LO5		4	/* A HI-16 5 bit absolute relocation.  */
+#define R_NIOS_HI16_HI11	5	/* A HI-16 top 11 bit absolute relocation.  */
+#define R_NIOS_PCREL6		6	/* A 6 bit relative relocation.  */
+#define R_NIOS_PCREL8		7	/* An 8 bit relative relocation.  */
+#define R_NIOS_PCREL11		8	/* An 11 bit relative relocation.  */
+#define R_NIOS_16		9	/* A 16 bit absolute relocation.  */
+#define R_NIOS_H_LO5		10	/* Low 5-bits of absolute relocation in halfwords.  */
+#define R_NIOS_H_HI11		11	/* Top 11 bits of 16-bit absolute relocation in halfwords.  */
+#define R_NIOS_H_XLO5		12	/* Low 5 bits of top 16-bits of 32-bit absolute relocation in halfwords.  */
+#define R_NIOS_H_XHI11		13	/* Top 11 bits of top 16-bits of 32-bit absolute relocation in halfwords.  */
+#define R_NIOS_H_16		14	/* Half-word @h value */
+#define R_NIOS_H_32		15	/* Word @h value */
+#define R_NIOS_GNU_VTINHERIT	200	/* GNU extension to record C++ vtable hierarchy */
+#define R_NIOS_GNU_VTENTRY	201	/* GNU extension to record C++ vtable member usage */
+#define R_NIOS_NUM		202
+
 #endif /* _LINUX_ELF_H */
diff -urN linux-2.4.29/include/linux/fast_timer.h linux-2.4.29-uc1/include/linux/fast_timer.h
--- linux-2.4.29/include/linux/fast_timer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/fast_timer.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,8 @@
+#ifndef _LINUX_FAST_TIMER_H
+#define _LINUX_FAST_TIMER_H
+
+extern void fast_timer_add(void (*func)(void *arg), void *arg);
+extern void fast_timer_remove(void (*func)(void *arg), void *arg);
+extern unsigned long fast_timer_count(void);
+
+#endif
diff -urN linux-2.4.29/include/linux/fec_ioctl.h linux-2.4.29-uc1/include/linux/fec_ioctl.h
--- linux-2.4.29/include/linux/fec_ioctl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/fec_ioctl.h	2005-06-14 02:11:36.000000000 +0100
@@ -0,0 +1,118 @@
+/*
+ * linux/fec_ioctl.h: definitions for 5272 ColdFire Ethernet IOCTL calls
+ *
+ * Mostly a copy of linux/mii.h: definitions for MII-compatible transceivers
+ * Originally drivers/net/sunhme.h.
+ *
+ * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
+ *
+ * Copyright (C) 2002 Arcturus Networks Inc. 
+ *               by MaTed (Ted Ma - mated@ArcturusNetworks.comm)
+ */
+
+#ifndef __LINUX_MII_H__
+#define __LINUX_MII_H__
+
+
+#include <linux/types.h>
+#include <linux/autoconf.h>
+
+#ifdef CONFIG_FEC 
+ 
+/*********
+ * This structure is used in all SIOCxMIIxxx ioctl calls and
+ * is provided only as a reference comment
+struct mii_ioctl_data {
+        u16             phy_id;
+        u16             reg_num;
+        u16             val_in;
+        u16             val_out;
+};
+**********/
+
+/************************
+ * Defines for LXT972a
+ *  Status Register 2
+ ************************/
+#define LXT972_STAT2		17	
+    /* Reserved                            0x8000  */
+#define PHY_STATUS_REG_TWO_MODE_100             0x4000
+#define PHY_STATUS_REG_TWO_TX_STATUS            0x2000
+#define PHY_STATUS_REG_TWO_RX_STATUS            0x1000
+#define PHY_STATUS_REG_TWO_COLLISION_STATUS     0x0800
+#define PHY_STATUS_REG_TWO_LINK                 0x0400
+#define PHY_STATUS_REG_TWO_DUPLEX_MODE          0x0200
+#define PHY_STATUS_REG_TWO_AUTO_NEGOTIATION     0x0100
+#define PHY_STATUS_REG_TWO_AUTO_NEGO_COMPELETE  0x0080
+    /* Reserved                                 0x0040  */
+#define PHY_STATUS_REG_TWO_POLARITY             0x0020
+#define PHY_STATUS_REG_TWO_PAUSE                0x0010
+#define PHY_STATUS_REG_TWO_ERROR                0x0008
+    /* Reserved                                 0x0004  */
+    /* Reserved                                 0x0002  */
+    /* Reserved                                 0x0001  */
+
+// Defines for value_in for subcommands
+#define SIOC_MIIREG_GET		0	// get register / data
+#define SIOC_MIIREG_QUERY	1	// query previous "get" register /data
+
+// Error return codes (in link_speed and duplex
+#define SIOC_FEC_RC_RELINK		-6 	// link staus changed
+#define SIOC_FEC_RC_INVALID_SUBCMND	-5	// invalid subcommand
+#define SIOC_FEC_RC_WRONG_REG	-4	// wrong register
+#define SIOC_FEC_RC_NO_REQUEST	-3	// no outstanding request or exists already
+#define SIOC_FEC_RC_NOT_COMP	-2	// queued command not completed
+#define SIOC_FEC_RC_NO_LINK		-1	// Link is down
+
+/* This structure is used for special FEC only ioctl calls */
+struct fec_ioctl_data
+{
+  unsigned short   phy_id;	/* For SIOMGMIIPHY
+							   - returns phy addr / number associated with 
+							   device
+							   For SIOCSMIIREG and SIOCGMIIREG
+							   - should be set to 1 for future uC5272 
+
+							   compatibility
+							*/
+  unsigned short	reg; 	/* Which register to be read / set
+							   - must be set to 17 for link status inquiry */
+  unsigned short	value_in; 	/* for SIOCSMIIREG
+								   - value to be written to the PHY register
+								   for SIOCGMIIREG
+								   - set to 0 for GET
+								   - set to 1 for QUERY (gets results of
+								   previous GET, if completed) 
+								*/
+  unsigned short   value_out;	/* returns the value of the previously 
+								   requested register.
+								   the value of Status register 2 (register 17
+								   of Intel lxt972a PHY (see lxt972a datasheet
+								   for explanation)) if register == 17, sets
+								   the returnvalues for link_speed and duplex
+								*/
+  unsigned short   link_speed;	   /* returns current link speed
+                           -5 => invalid subcommand
+                           -4 => wrong register
+                           -3 => no outstanding command request
+                           -2 => command not yet completed
+                           -1 => undetermined (ie no link established)
+                            0 => 1 Mbps
+                            1 => 10 Mbps
+                            2 => 100 Mbps
+                            3 => 1 Gbps
+                            4 => 10 Gpbs
+						*/
+  unsigned short   duplex;   	    /* returns established duplex of the link
+                           -5 => invalid subcommand
+                           -4 => wrong register
+                           -3 => no outstanding command request
+                           -2 => command not yet completed
+                           -1 => undetermined (ie no link established)
+                            0 => half duplex
+                            1 => full duplex
+						*/
+};
+
+#endif	// CONFIG_FEC
+#endif	// __LINUX_MII_H__
diff -urN linux-2.4.29/include/linux/flat.h linux-2.4.29-uc1/include/linux/flat.h
--- linux-2.4.29/include/linux/flat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/flat.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2002-2003  David McCullough <davidm@snapgear.com>
+ * Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ *                          The Silver Hammer Group, Ltd.
+ *
+ * This file provides the definitions and structures needed to
+ * support uClinux flat-format executables.
+ */
+
+#ifndef _LINUX_FLAT_H
+#define _LINUX_FLAT_H
+
+#ifdef __KERNEL__
+#include <asm/flat.h>
+#endif
+
+#define	FLAT_VERSION			0x00000004L
+
+#ifdef CONFIG_BINFMT_SHARED_FLAT
+#define	MAX_SHARED_LIBS			(4)
+#else
+#define	MAX_SHARED_LIBS			(1)
+#endif
+
+/*
+ * To make everything easier to port and manage cross platform
+ * development,  all fields are in network byte order.
+ */
+
+struct flat_hdr {
+	char magic[4];
+	unsigned long rev;          /* version (as above) */
+	unsigned long entry;        /* Offset of first executable instruction
+	                               with text segment from beginning of file */
+	unsigned long data_start;   /* Offset of data segment from beginning of
+	                               file */
+	unsigned long data_end;     /* Offset of end of data segment
+	                               from beginning of file */
+	unsigned long bss_end;      /* Offset of end of bss segment from beginning
+	                               of file */
+
+	/* (It is assumed that data_end through bss_end forms the bss segment.) */
+
+	unsigned long stack_size;   /* Size of stack, in bytes */
+	unsigned long reloc_start;  /* Offset of relocation records from
+	                               beginning of file */
+	unsigned long reloc_count;  /* Number of relocation records */
+	unsigned long flags;       
+	unsigned long build_date;   /* When the program/library was built */
+	unsigned long filler[5];    /* Reservered, set to zero */
+};
+
+#define FLAT_FLAG_RAM    0x0001 /* load program entirely into RAM */
+#define FLAT_FLAG_GOTPIC 0x0002 /* program is PIC with GOT */
+#define FLAT_FLAG_GZIP   0x0004 /* all but the header is compressed */
+#define FLAT_FLAG_GZDATA 0x0008 /* only data/relocs are compressed (for XIP) */
+#define FLAT_FLAG_KTRACE 0x0010 /* output useful kernel trace for debugging */
+
+
+#ifdef __KERNEL__ /* so systems without linux headers can compile the apps */
+/*
+ * While it would be nice to keep this header clean,  users of older
+ * tools still need this support in the kernel.  So this section is
+ * purely for compatibility with old tool chains.
+ *
+ * DO NOT make changes or enhancements to the old format please,  just work
+ *        with the format above,  except to fix bugs with old format support.
+ */
+
+#include <asm/byteorder.h>
+
+#define	OLD_FLAT_VERSION			0x00000002L
+#define OLD_FLAT_RELOC_TYPE_TEXT	0
+#define OLD_FLAT_RELOC_TYPE_DATA	1
+#define OLD_FLAT_RELOC_TYPE_BSS		2
+
+typedef union {
+	unsigned long	value;
+	struct {
+# if defined(mc68000) && !defined(CONFIG_COLDFIRE)
+		signed long offset : 30;
+		unsigned long type : 2;
+#   	define OLD_FLAT_FLAG_RAM    0x1 /* load program entirely into RAM */
+# elif defined(__BIG_ENDIAN_BITFIELD)
+		unsigned long type : 2;
+		signed long offset : 30;
+#   	define OLD_FLAT_FLAG_RAM    0x1 /* load program entirely into RAM */
+# elif defined(__LITTLE_ENDIAN_BITFIELD)
+		signed long offset : 30;
+		unsigned long type : 2;
+#   	define OLD_FLAT_FLAG_RAM    0x1 /* load program entirely into RAM */
+# else
+#   	error "Unknown bitfield order for flat files."
+# endif
+	} reloc;
+} flat_v2_reloc_t;
+
+/* 
+ * Version 5 relocation records.
+ * =============================
+ *
+ * +--+-+---+--------------------------+
+ * |  | |   |                          |
+ * +--+-+---+--------------------------+
+ * |  | |   |                          |  
+ * |  | |   +--------------------------+-------------- offset
+ * |  | |   |
+ * |  | +---+----------------------------------------- sp
+ * |  | |
+ * |  +-+--------------------------------------------- hi_lo
+ * |  |
+ * +--+----------------------------------------------- type
+ *
+ * offset - This is the offset of where the relocation must take place.
+ *          The offset is from the start of the section.  To find out 
+ *          which section to look at, see type.
+ * sp     - These bits are special platform specific bits.  See below for 
+ *          further explanation and mapping for supported platforms.
+ * hi_lo  - For relocations where only part of the address is taken, then
+ *          this bit indicates whether it is the high part or the low part of
+ *          the address.
+ *          0 - Low part of address
+ *          1 - High part of address
+ * type   - This indicates which section the relocation is in.
+ *          00 - TEXT section
+ *          01 - DATA section
+ *          10 - BSS section
+ *
+ * MIPS sp Specification
+ * =====================
+ *
+ * +-+-+-+
+ * | | | |
+ * +-+-+-+
+ * | | | |
+ * | | +-+-------------------------------------------- carry
+ * | | |
+ * +-+-+---------------------------------------------- reloc_type
+ *
+ * carry      - This indicates whether the high part of the relcation address 
+ *              requires a carry because of the low part calculations.
+ *              0 - Do not carry from low part
+ *              1 - Carry from low part
+ * reloc_type - For MIPS, there are three types of relocations to handle.
+ *              16-bit High part, 16-bit Low part, and 26-bit.  Thus this 
+ *              indicates whether it is a hi/lo reloc or a 26-bit reloc.
+ *              00 - 16-bit hi/lo relocation
+ *              01 - 26-bit relocation
+ *              10 - 32-bit relocation
+ *
+ * BLACKfin sp Specification
+ * =========================
+ * 
+ * 000 luimm16 and huimm16. hi_lo used for selecting.
+ * 001 pcrel24.
+ * 010 abs32.
+ *
+ * Blackfin has too many kinds of relocations to fit into 3 bits. Only those
+ * types of relocations that are required for compiled code are supported at
+ * this time. Unlike mips tools, we don't have enough support for carry. The
+ * kernel has to do ad-hoc carry calculations for huimm16 relocations. It
+ * doesn't cause any problems for compiler generated code because a compiler
+ * always generates a luimm16 type instruction followed by a huimm16
+ * instruction. - akale
+ *
+ * SPARC sp Specification
+ * ======================
+ *
+ * This architecture is not yet defined.
+ *
+ * ARM and M68K Details
+ * ====================
+ * These architectures use the version 4 bFLT format.  The version 4 format is 
+ * a simple unsigned long integer (32-bits).  This record holds the relocation
+ * offset from the start of text.  The loader must check for size of offset 
+ * against the size of text section for XIP to work properly.
+ *
+ *
+ * Faisal Akber
+ *
+ */
+typedef union {
+	unsigned long value;
+	struct {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+		unsigned long type	:  2;
+		unsigned long hi_lo	:  1;
+		unsigned long sp	:  3;
+		signed long   offset	: 26;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+		signed long   offset	: 26;
+		unsigned long sp	:  3;
+		unsigned long hi_lo	:  1;
+		unsigned long type	:  2;
+#else
+#  error "Unknown bitfield order for flat files."
+#endif
+	} reloc;
+} flat_v5_reloc_t;
+
+#define V5_FLAT_VERSION		0x00000005L
+#define FLAT_V5_RELOC_TYPE_TEXT	0
+#define FLAT_V5_RELOC_TYPE_DATA	1
+#define FLAT_V5_RELOC_TYPE_BSS	2
+#define FLAT_V5_RELOC_PART_LO	0
+#define FLAT_V5_RELOC_PART_HI	1
+
+#ifdef CONFIG_MIPS
+#  define TARGET_MIPS
+#  define FLAT_MIPS_RELOC_SP(type, carry) ((type * 2) + (carry))
+#  define FLAT_MIPS_RELOC_SP_TYPE_16_BIT	0
+#  define FLAT_MIPS_RELOC_SP_TYPE_24_BIT	1
+#  define FLAT_MIPS_RELOC_SP_TYPE_32_BIT	2
+#  define FLAT_MIPS_RELOC_SP_NO_CARRY	0
+#  define FLAT_MIPS_RELOC_SP_CARRY		1
+#endif
+
+#ifdef CONFIG_BLACKFIN
+#  define TARGET_BLACKFIN
+#  define FLAT_BLACKFIN_RELOC_SP_TYPE_16_BIT	0
+#  define FLAT_BLACKFIN_RELOC_SP_TYPE_24_BIT	1
+#  define FLAT_BLACKFIN_RELOC_SP_TYPE_32_BIT	2
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_FLAT_H */
diff -urN linux-2.4.29/include/linux/fs.h linux-2.4.29-uc1/include/linux/fs.h
--- linux-2.4.29/include/linux/fs.h	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/fs.h	2005-06-14 02:11:36.000000000 +0100
@@ -412,9 +412,11 @@
 	unsigned long		nrpages;	/* number of total pages */
 	struct address_space_operations *a_ops;	/* methods */
 	struct inode		*host;		/* owner: inode, block_device */
+#ifndef NO_MM
 	struct vm_area_struct	*i_mmap;	/* list of private mappings */
 	struct vm_area_struct	*i_mmap_shared; /* list of shared mappings */
 	spinlock_t		i_shared_lock;  /* and spinlock protecting it */
+#endif /* NO_MM */
 	int			gfp_mask;	/* how to allocate the pages */
 };
 
@@ -850,6 +852,9 @@
 	int (*check_media_change) (kdev_t);
 	int (*revalidate) (kdev_t);
 	struct module *owner;
+#ifdef MAGIC_ROM_PTR
+	int (*romptr) (kdev_t, struct vm_area_struct *);
+#endif /* MAGIC_ROM_PTR */
 };
 
 /*
@@ -876,6 +881,9 @@
 	ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);
 	ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
 	unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+#ifdef MAGIC_ROM_PTR
+	int (*romptr) (struct file *, struct vm_area_struct *);
+#endif /* MAGIC_ROM_PTR */
 };
 
 struct inode_operations {
diff -urN linux-2.4.29/include/linux/i2c-id.h linux-2.4.29-uc1/include/linux/i2c-id.h
--- linux-2.4.29/include/linux/i2c-id.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/i2c-id.h	2005-06-14 02:11:33.000000000 +0100
@@ -185,6 +185,7 @@
 #define I2C_HW_B_RIVA	0x10	/* Riva based graphics cards		*/
 #define I2C_HW_B_IOC	0x11	/* IOC bit-wiggling			*/
 #define I2C_HW_B_TSUNA  0x12	/* DEC Tsunami chipset			*/
+#define I2C_HW_B_COLDF	0x13	/* Motorola Coldfire GPIO I2C		*/
 
 /* --- PCF 8584 based algorithms					*/
 #define I2C_HW_P_LP	0x00	/* Parallel port interface		*/
diff -urN linux-2.4.29/include/linux/ibm_ocp_gpio.h linux-2.4.29-uc1/include/linux/ibm_ocp_gpio.h
--- linux-2.4.29/include/linux/ibm_ocp_gpio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/ibm_ocp_gpio.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,58 @@
+/*
+ * FILE NAME ibm_ocp_gpio.h
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Generic gpio.
+ *
+ *  Armin Kuster akuster@pacbell.net
+ *  Sept, 2001
+ *
+ *  Orignial driver
+ *  Author: MontaVista Software, Inc.  <source@mvista.com>
+ *          Frank Rowand <frank_rowand@mvista.com>
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __IBM_OCP_GPIO_H
+#define __IBM_OCP_GPIO_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define IBMGPIO_IOCTL_BASE	'Z'
+
+struct ibm_gpio_ioctl_data {
+	__u32 device;
+	__u32 mask;
+	__u32 data;
+};
+
+#define GPIO_MINOR             185
+#define IBMGPIO_IN		_IOWR(IBMGPIO_IOCTL_BASE, 0, struct ibm_gpio_ioctl_data)
+#define IBMGPIO_OUT		_IOW (IBMGPIO_IOCTL_BASE, 1, struct ibm_gpio_ioctl_data)
+#define IBMGPIO_OPEN_DRAIN	_IOW (IBMGPIO_IOCTL_BASE, 2, struct ibm_gpio_ioctl_data)
+#define IBMGPIO_TRISTATE	_IOW (IBMGPIO_IOCTL_BASE, 3, struct ibm_gpio_ioctl_data)
+#define IBMGPIO_CFG		_IOW (IBMGPIO_IOCTL_BASE, 4, struct ibm_gpio_ioctl_data)
+
+#endif
diff -urN linux-2.4.29/include/linux/icmpv6.h linux-2.4.29-uc1/include/linux/icmpv6.h
--- linux-2.4.29/include/linux/icmpv6.h	2004-08-08 00:26:06.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/icmpv6.h	2005-06-14 02:11:37.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: icmpv6.h,v 1.12 2003/08/08 13:46:35 yoshfuji Exp $ */
+
 #ifndef _LINUX_ICMPV6_H
 #define _LINUX_ICMPV6_H
 
@@ -40,20 +42,29 @@
                 struct icmpv6_nd_ra {
 			__u8		hop_limit;
 #if defined(__LITTLE_ENDIAN_BITFIELD)
-			__u8		reserved:6,
+			__u8		reserved:3,
+					router_pref:2,
+				        home_agent:1,
 					other:1,
 					managed:1;
 
 #elif defined(__BIG_ENDIAN_BITFIELD)
 			__u8		managed:1,
 					other:1,
-					reserved:6;
+				        home_agent:1,
+					router_pref:2,
+					reserved:3;
 #else
 #error	"Please fix <asm/byteorder.h>"
 #endif
 			__u16		rt_lifetime;
                 } u_nd_ra;
 
+		struct icmpv6_ni {
+			__u16		qtype;
+			__u16		flags;
+		} u_ni;
+
 	} icmp6_dataun;
 
 #define icmp6_identifier	icmp6_dataun.u_echo.identifier
@@ -70,6 +81,10 @@
 #define icmp6_addrconf_managed	icmp6_dataun.u_nd_ra.managed
 #define icmp6_addrconf_other	icmp6_dataun.u_nd_ra.other
 #define icmp6_rt_lifetime	icmp6_dataun.u_nd_ra.rt_lifetime
+#define icmp6_qtype		icmp6_dataun.u_ni.qtype
+#define icmp6_flags		icmp6_dataun.u_ni.flags
+#define icmp6_home_agent	icmp6_dataun.u_nd_ra.home_agent
+#define icmp6_router_pref	icmp6_dataun.u_nd_ra.router_pref
 };
 
 
@@ -86,6 +101,9 @@
 #define ICMPV6_MGM_REPORT       	131
 #define ICMPV6_MGM_REDUCTION    	132
 
+#define ICMPV6_NI_QUERY			139
+#define ICMPV6_NI_REPLY			140
+
 /* definitions for MLDv2 */
 
 #define MLD2_MODE_IS_INCLUDE	1
@@ -121,6 +139,57 @@
 #define ICMPV6_UNK_OPTION		2
 
 /*
+ *	Codes for Node Information
+ */
+#define ICMPV6_NI_SUBJ_IPV6		0	/* Query Subject is an ipv6 address */
+#define ICMPV6_NI_SUBJ_FQDN		1	/* Query Subject is a Domain name */
+#define ICMPV6_NI_SUBJ_IPV4		2	/* Query Subject is an ipv4 address */
+
+#define ICMPV6_NI_SUCCESS		0	/* NI successful reply */
+#define ICMPV6_NI_REFUSED		1	/* NI request is refused */
+#define ICMPV6_NI_UNKNOWN		2	/* unknown Qtype */
+
+#define ICMPV6_NI_QTYPE_NOOP		0 	/* NOOP  */
+#define ICMPV6_NI_QTYPE_SUPTYPES	1 	/* Supported Qtypes */
+#define ICMPV6_NI_QTYPE_FQDN		2 	/* FQDN */
+#define ICMPV6_NI_QTYPE_NODEADDR	3 	/* Node Addresses */
+#define ICMPV6_NI_QTYPE_IPV4ADDR	4 	/* IPv4 Addresses */
+
+/* Flags */
+#if __BYTE_ORDER == __BIG_ENDIAN || (defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN))
+#define ICMPV6_NI_SUPTYPE_FLAG_COMPRESS		0x1
+#elif __BYTE_ORDER == __LITTLE_ENDIAN || (defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN))
+#define ICMPV6_NI_SUPTYPE_FLAG_COMPRESS		0x0100
+#endif
+#if __BYTE_ORDER == __BIG_ENDIAN || (defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN))
+#define ICMPV6_NI_FQDN_FLAG_VALIDTTL		0x1
+#elif __BYTE_ORDER == __LITTLE_ENDIAN || (defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN))
+#define ICMPV6_NI_FQDN_FLAG_VALIDTTL		0x0100
+#endif
+#if __BYTE_ORDER == __BIG_ENDIAN || (defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN))
+#define ICMPV6_NI_NODEADDR_FLAG_TRUNCATE	0x1
+#define ICMPV6_NI_NODEADDR_FLAG_ALL		0x2
+#define ICMPV6_NI_NODEADDR_FLAG_COMPAT		0x4
+#define ICMPV6_NI_NODEADDR_FLAG_LINKLOCAL	0x8
+#define ICMPV6_NI_NODEADDR_FLAG_SITELOCAL	0x10
+#define ICMPV6_NI_NODEADDR_FLAG_GLOBAL		0x20
+#define ICMPV6_NI_NODEADDR_FLAG_ANYCAST		0x40 /* just experimental. not in spec */
+#elif __BYTE_ORDER == __LITTLE_ENDIAN || (defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN))
+#define ICMPV6_NI_NODEADDR_FLAG_TRUNCATE	0x0100
+#define ICMPV6_NI_NODEADDR_FLAG_ALL		0x0200
+#define ICMPV6_NI_NODEADDR_FLAG_COMPAT		0x0400
+#define ICMPV6_NI_NODEADDR_FLAG_LINKLOCAL	0x0800
+#define ICMPV6_NI_NODEADDR_FLAG_SITELOCAL	0x1000
+#define ICMPV6_NI_NODEADDR_FLAG_GLOBAL		0x2000
+#define ICMPV6_NI_NODEADDR_FLAG_ANYCAST		0x4000 /* just experimental. not in spec */
+#else
+#error	"Please fix <asm/byteorder.h>"
+#endif
+#define ICMPV6_NI_IPV4ADDR_FLAG_TRUNCATE	ICMPV6_NI_NODEADDR_FLAG_TRUNCATE
+#define ICMPV6_NI_IPV4ADDR_FLAG_ALL		ICMPV6_NI_NODEADDR_FLAG_ALL
+
+
+/*
  *	constants for (set|get)sockopt
  */
 
@@ -139,11 +208,13 @@
 	__u32		data[8];
 };
 
+
 #ifdef __KERNEL__
 
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 
+#define IM_ICMPV6_SEND	"icmpv6_send"
 
 extern void				icmpv6_send(struct sk_buff *skb,
 						    int type, int code,
diff -urN linux-2.4.29/include/linux/ide.h linux-2.4.29-uc1/include/linux/ide.h
--- linux-2.4.29/include/linux/ide.h	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/ide.h	2005-06-14 02:11:34.000000000 +0100
@@ -302,7 +302,8 @@
 		ide_qd65xx,	ide_umc8672,	ide_ht6560b,
 		ide_pdc4030,	ide_rz1000,	ide_trm290,
 		ide_cmd646,	ide_cy82c693,	ide_4drives,
-		ide_pmac,	ide_etrax100,	ide_acorn
+		ide_pmac,	ide_etrax100,	ide_acorn,
+		ide_ocidec
 } hwif_chipset_t;
 
 /*
diff -urN linux-2.4.29/include/linux/if_arcnet.h linux-2.4.29-uc1/include/linux/if_arcnet.h
--- linux-2.4.29/include/linux/if_arcnet.h	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/if_arcnet.h	2005-06-14 02:11:35.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: if_arcnet.h,v 1.4 2003/08/08 13:46:35 yoshfuji Exp $ */
+
 /*
  * INET         An implementation of the TCP/IP protocol suite for the LINUX
  *              operating system.  INET is implemented using the  BSD Socket
@@ -24,6 +26,7 @@
  */
 
 /* RFC1201 Protocol ID's */
+#define ARC_P_IPV6		196	/* 0xC4: RFC2497 */
 #define ARC_P_IP		212	/* 0xD4 */
 #define ARC_P_IPV6		196	/* 0xC4: RFC2497 */
 #define ARC_P_ARP		213	/* 0xD5 */
diff -urN linux-2.4.29/include/linux/if_arp.h linux-2.4.29-uc1/include/linux/if_arp.h
--- linux-2.4.29/include/linux/if_arp.h	2005-01-19 14:10:12.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/if_arp.h	2005-06-14 02:11:36.000000000 +0100
@@ -84,6 +84,7 @@
 #define ARPHRD_IEEE802_TR 800		/* Magic type ident for TR	*/
 #define ARPHRD_IEEE80211 801		/* IEEE 802.11			*/
 #define ARPHRD_IEEE80211_PRISM 802	/* IEEE 802.11 + Prism2 header  */
+#define ARPHRD_IPV6_IPV6_TUNNEL 803	/* IPv6-IPv6 tunnel		*/
 
 #define ARPHRD_VOID	  0xFFFF	/* Void type, nothing is known */
 #define ARPHRD_NONE	  0xFFFE	/* zero header length */
diff -urN linux-2.4.29/include/linux/if_bridge.h linux-2.4.29-uc1/include/linux/if_bridge.h
--- linux-2.4.29/include/linux/if_bridge.h	2001-11-22 19:47:12.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/if_bridge.h	2005-06-14 02:11:37.000000000 +0100
@@ -102,7 +102,8 @@
 struct net_bridge_port;
 
 extern int (*br_ioctl_hook)(unsigned long arg);
-extern void (*br_handle_frame_hook)(struct sk_buff *skb);
+extern int (*br_handle_frame_hook)(struct sk_buff *skb);
+extern int (*br_should_route_hook)(struct sk_buff **pskb);
 
 #endif
 
diff -urN linux-2.4.29/include/linux/if_tunnel.h linux-2.4.29-uc1/include/linux/if_tunnel.h
--- linux-2.4.29/include/linux/if_tunnel.h	1997-11-30 22:00:38.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/if_tunnel.h	2005-06-14 02:11:33.000000000 +0100
@@ -15,6 +15,12 @@
 #define GRE_FLAGS	__constant_htons(0x00F8)
 #define GRE_VERSION	__constant_htons(0x0007)
 
+/* Ethernet frames on GRE */
+#define GRE_P_ETH_BR	__constant_htons(0x6558)
+
+/* BPDU packets on GRE */
+#define GRE_P_BPDU	__constant_htons(0x42)
+
 struct ip_tunnel_parm
 {
 	char			name[IFNAMSIZ];
diff -urN linux-2.4.29/include/linux/imq.h linux-2.4.29-uc1/include/linux/imq.h
--- linux-2.4.29/include/linux/imq.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/imq.h	2005-06-14 02:11:35.000000000 +0100
@@ -0,0 +1,9 @@
+#ifndef _IMQ_H
+#define _IMQ_H
+
+#define IMQ_MAX_DEVS	16
+
+#define IMQ_F_IFMASK	0x7f
+#define IMQ_F_ENQUEUE	0x80
+
+#endif /* _IMQ_H */
diff -urN linux-2.4.29/include/linux/in6.h linux-2.4.29-uc1/include/linux/in6.h
--- linux-2.4.29/include/linux/in6.h	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/in6.h	2005-06-14 02:11:34.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: in6.h,v 1.20 2003/08/10 04:41:32 yoshfuji Exp $ */
+
 /*
  *	Types and definitions for AF_INET6 
  *	Linux INET6 implementation 
@@ -21,6 +23,8 @@
 #ifndef _LINUX_IN6_H
 #define _LINUX_IN6_H
 
+#define __USAGI__
+
 #include <linux/types.h>
 
 /*
@@ -40,7 +44,7 @@
 #define s6_addr32		in6_u.u6_addr32
 };
 
-/* IPv6 Wildcard Address (::) and Loopback Address (::1) defined in RFC2553
+/* IPv6 Wildcard Address (::) and Loopback Address (::1) defined in RFC3493
  * NOTE: Be aware the IN6ADDR_* constants and in6addr_* externals are defined
  * in network byte order, not in host byte order as are the IPv4 equivalents
  */
@@ -54,7 +58,7 @@
 	__u16			sin6_port;      /* Transport layer port # */
 	__u32			sin6_flowinfo;  /* IPv6 flow information */
 	struct in6_addr		sin6_addr;      /* IPv6 address */
-	__u32			sin6_scope_id;  /* scope id (new in RFC2553) */
+	__u32			sin6_scope_id;  /* scope id */
 };
 
 struct ipv6_mreq {
@@ -96,32 +100,15 @@
 
 /*
  *	Bitmask constant declarations to help applications select out the 
- *	flow label and priority fields.
+ *	flow label and traffic class fields.
  *
  *	Note that this are in host byte order while the flowinfo field of
  *	sockaddr_in6 is in network byte order.
  */
 
 #define IPV6_FLOWINFO_FLOWLABEL		0x000fffff
-#define IPV6_FLOWINFO_PRIORITY		0x0ff00000
+#define IPV6_FLOWINFO_TCLASS		0x0ff00000
 
-/* These defintions are obsolete */
-#define IPV6_PRIORITY_UNCHARACTERIZED	0x0000
-#define IPV6_PRIORITY_FILLER		0x0100
-#define IPV6_PRIORITY_UNATTENDED	0x0200
-#define IPV6_PRIORITY_RESERVED1		0x0300
-#define IPV6_PRIORITY_BULK		0x0400
-#define IPV6_PRIORITY_RESERVED2		0x0500
-#define IPV6_PRIORITY_INTERACTIVE	0x0600
-#define IPV6_PRIORITY_CONTROL		0x0700
-#define IPV6_PRIORITY_8			0x0800
-#define IPV6_PRIORITY_9			0x0900
-#define IPV6_PRIORITY_10		0x0a00
-#define IPV6_PRIORITY_11		0x0b00
-#define IPV6_PRIORITY_12		0x0c00
-#define IPV6_PRIORITY_13		0x0d00
-#define IPV6_PRIORITY_14		0x0e00
-#define IPV6_PRIORITY_15		0x0f00
 
 /*
  *	IPV6 extension headers
@@ -142,9 +129,20 @@
 #define IPV6_TLV_JUMBO		194
 
 /*
+ *	Mobile IPv6 TLV options.
+ */
+#define MIPV6_TLV_HOMEADDR	201
+
+/*
  *	IPV6 socket options
  */
 
+/*
+ *	NOTE: 	26, 48-63 are reserved by USAGI Project.
+ *		For further information, see <http://www.linux-ipv6.org>
+ *
+ */
+
 #define IPV6_ADDRFORM		1
 #define IPV6_PKTINFO		2
 #define IPV6_HOPOPTS		3
@@ -161,8 +159,10 @@
 #define IPV6_MULTICAST_IF	17
 #define IPV6_MULTICAST_HOPS	18
 #define IPV6_MULTICAST_LOOP	19
-#define IPV6_ADD_MEMBERSHIP	20
-#define IPV6_DROP_MEMBERSHIP	21
+#define IPV6_JOIN_GROUP		20
+#define IPV6_ADD_MEMBERSHIP	IPV6_JOIN_GROUP
+#define IPV6_LEAVE_GROUP	21
+#define IPV6_DROP_MEMBERSHIP	IPV6_LEAVE_GROUP
 #define IPV6_ROUTER_ALERT	22
 #define IPV6_MTU_DISCOVER	23
 #define IPV6_MTU		24
@@ -180,5 +180,77 @@
 #define IPV6_FLOWLABEL_MGR	32
 #define IPV6_FLOWINFO_SEND	33
 
+/* draft-itojun-ipv6-tclass-api-01.txt */
+#define IPV6_RECVTCLASS		66
+#define IPV6_TCLASS		67
+
+/* usagi extension */
+#define IPV6_PRIVACY		68
+
+/*
+ * IPv6 address testing macros (RFC3493; some from KAME)
+ * (to avoid alignment issue, don't use __u64)
+ */
+#ifdef __KERNEL__
+#ifndef IPV6_ADDR_SCOPE_NODELOCAL
+#define IPV6_ADDR_SCOPE_NODELOCAL	0x01
+#define IPV6_ADDR_SCOPE_LINKLOCAL	0x02
+#define IPV6_ADDR_SCOPE_SITELOCAL	0x05
+#define IPV6_ADDR_SCOPE_ORGLOCAL	0x08
+#define IPV6_ADDR_SCOPE_GLOBAL		0x0e
+#endif
+
+#define	IN6_IS_ADDR_UNSPECIFIED(a)			\
+	((((a)->s6_addr32[0]) == 0) &&			\
+	 (((a)->s6_addr32[1]) == 0) &&			\
+	 (((a)->s6_addr32[2]) == 0) &&			\
+	 (((a)->s6_addr32[3]) == 0))
+#define	IN6_IS_ADDR_LOOPBACK(a)				\
+	((((a)->s6_addr32[0]) == 0) &&			\
+	 (((a)->s6_addr32[1]) == 0) &&			\
+	 (((a)->s6_addr32[2]) == 0) && 			\
+	 (((a)->s6_addr32[3]) == __constant_htonl(1)))
+#define IN6_IS_ADDR_V4COMPAT(a)				\
+	((((a)->s6_addr32[0]) == 0) &&			\
+	 (((a)->s6_addr32[1]) == 0) &&			\
+	 (((a)->s6_addr32[2]) == 0) &&			\
+	 (((a)->s6_addr32[3]) != __constant_htonl(1)))
+#define IN6_IS_ADDR_V4MAPPED(a)				\
+	((((a)->s6_addr32[0]) == 0) &&			\
+	 (((a)->s6_addr32[1]) == 0) &&			\
+	 (((a)->s6_addr32[2]) == __constant_htonl(0x0000ffff)))
+#define IN6_IS_ADDR_LINKLOCAL(a)	\
+	(((a)->s6_addr32[0] & __constant_htonl(0xffc00000)) == __constant_htons(0xfe800000))
+#define IN6_IS_ADDR_SITELOCAL(a)	\
+	(((a)->s6_addr32[0] & __constant_htonl(0xffc00000)) == __constant_htons(0xfec00000))
+#define IN6_IS_ADDR_MULTICAST(a)	\
+	((a)->s6_addr[0] == 0xff)
+
+#define IPV6_ADDR_MC_SCOPE(a)		\
+	((a)->s6_addr[1] & 0x0f)	/* XXX nonstandard */
+#define IN6_IS_ADDR_MC_SCOPE(a,b)	\
+	(IPV6_ADDR_MC_SCOPE(a) == (b))	/* XXX nonstandard */
+
+#define IN6_IS_ADDR_MC_NODELOCAL(a)	\
+	(IN6_IS_ADDR_MULTICAST(a) &&	\
+	 IN6_IS_ADDR_MC_SCOPE(a,IPV6_ADDR_SCOPE_NODELOCAL))
+#define IN6_IS_ADDR_MC_LINKLOCAL(a)	\
+	(IN6_IS_ADDR_MULTICAST(a) &&	\
+	 IN6_IS_ADDR_MC_SCOPE(a,IPV6_ADDR_SCOPE_LINKLOCAL))
+#define IN6_IS_ADDR_MC_SITELOCAL(a)	\
+	(IN6_IS_ADDR_MULTICAST(a) &&	\
+	 IN6_IS_ADDR_MC_SCOPE(a,IPV6_ADDR_SCOPE_SITELOCAL))
+#define IN6_IS_ADDR_MC_ORGLOCAL(a)	\
+	(IN6_IS_ADDR_MULTICAST(a) &&	\
+	 IN6_IS_ADDR_MC_SCOPE(a,IPV6_ADDR_SCOPE_ORGLOCAL))
+#define IN6_IS_ADDR_MC_GLOBAL(a)	\
+	(IN6_IS_ADDR_MULTICAST(a) &&	\
+	 IN6_IS_ADDR_MC_SCOPE(a,IPV6_ADDR_SCOPE_GLOBAL))
+#endif
 
+/* device controls */
+#define SIOCGIFZONE	(SIOCPROTOPRIVATE + 0)
+#define SIOCSIFZONE	(SIOCPROTOPRIVATE + 1)
+#define SIOCSDADDRLABEL	(SIOCPROTOPRIVATE + 2)
+#define SIOCDDADDRLABEL	(SIOCPROTOPRIVATE + 3)
 #endif
diff -urN linux-2.4.29/include/linux/inet.h linux-2.4.29-uc1/include/linux/inet.h
--- linux-2.4.29/include/linux/inet.h	2002-08-03 01:39:45.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/inet.h	2005-06-14 02:11:33.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: inet.h,v 1.14 2002/09/27 08:20:08 yoshfuji Exp $ */
+
 /*
  *		Swansea University Computer Society NET3
  *
@@ -44,8 +46,28 @@
 
 #ifdef __KERNEL__
 
+struct net_proto;
+struct in_addr;
+
 extern void		inet_proto_init(struct net_proto *pro);
 extern __u32		in_aton(const char *str);
+#if defined(CONFIG_IPV6)
+struct in6_addr;
+extern char  *in6_ntop(const struct in6_addr *in6, char *buf);
+#elif defined(CONFIG_IPV6_MODULE)
+#include <linux/in6.h>
+extern __inline__ char	*in6_ntop(const struct in6_addr *in6, char *buf){
+	if (!buf)
+		return NULL;
+	sprintf(buf,
+		"%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
+		ntohs(in6->s6_addr16[0]), ntohs(in6->s6_addr16[1]),
+		ntohs(in6->s6_addr16[2]), ntohs(in6->s6_addr16[3]),
+		ntohs(in6->s6_addr16[4]), ntohs(in6->s6_addr16[5]),
+		ntohs(in6->s6_addr16[6]), ntohs(in6->s6_addr16[7]));
+	return buf;
+}
+#endif
 
 #endif
 #endif	/* _LINUX_INET_H */
diff -urN linux-2.4.29/include/linux/in.h linux-2.4.29-uc1/include/linux/in.h
--- linux-2.4.29/include/linux/in.h	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/in.h	2005-06-14 02:11:36.000000000 +0100
@@ -240,11 +240,11 @@
 
 #ifdef __KERNEL__
 /* Some random defines to make it easier in the kernel.. */
-#define LOOPBACK(x)	(((x) & htonl(0xff000000)) == htonl(0x7f000000))
-#define MULTICAST(x)	(((x) & htonl(0xf0000000)) == htonl(0xe0000000))
-#define BADCLASS(x)	(((x) & htonl(0xf0000000)) == htonl(0xf0000000))
-#define ZERONET(x)	(((x) & htonl(0xff000000)) == htonl(0x00000000))
-#define LOCAL_MCAST(x)	(((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
+#define LOOPBACK(x)	(((x) & __constant_htonl(0xff000000)) == __constant_htonl(0x7f000000))
+#define MULTICAST(x)	(((x) & __constant_htonl(0xf0000000)) == __constant_htonl(0xe0000000))
+#define BADCLASS(x)	(((x) & __constant_htonl(0xf0000000)) == __constant_htonl(0xf0000000))
+#define ZERONET(x)	(((x) & __constant_htonl(0xff000000)) == __constant_htonl(0x00000000))
+#define LOCAL_MCAST(x)	(((x) & __constant_htonl(0xFFFFFF00)) == __constant_htonl(0xE0000000))
 
 #endif
 
diff -urN linux-2.4.29/include/linux/init.h linux-2.4.29-uc1/include/linux/init.h
--- linux-2.4.29/include/linux/init.h	2004-04-14 14:05:40.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/init.h	2005-06-14 02:11:35.000000000 +0100
@@ -76,8 +76,13 @@
  * Mark functions and data as being only used at initialization
  * or exit time.
  */
+#ifndef NO_TEXT_SECTIONS
 #define __init		__attribute__ ((__section__ (".text.init")))
 #define __exit		__attribute_used__ __attribute__ (( __section__(".text.exit")))
+#else
+#define __init
+#define __exit		__attribute__ ((unused))
+#endif
 #define __initdata	__attribute__ ((__section__ (".data.init")))
 #define __exitdata	__attribute_used__ __attribute__ ((__section__ (".data.exit")))
 #define __initsetup	__attribute_used__ __attribute__ ((__section__ (".setup.init")))
diff -urN linux-2.4.29/include/linux/ipv6.h linux-2.4.29-uc1/include/linux/ipv6.h
--- linux-2.4.29/include/linux/ipv6.h	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/ipv6.h	2005-06-14 02:11:33.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: ipv6.h,v 1.16 2004/01/11 08:19:25 yoshfuji Exp $ */
+
 #ifndef _IPV6_H
 #define _IPV6_H
 
@@ -27,8 +29,17 @@
 	int		ifr6_ifindex; 
 };
 
+struct in6_addrlabelreq {
+	struct in6_addr		addr;
+	__u16			plen;
+	__u16			__reserved;
+	__u32			ifindex;
+	__u32			label;
+};
+
 #define IPV6_SRCRT_STRICT	0x01	/* this hop must be a neighbor	*/
 #define IPV6_SRCRT_TYPE_0	0	/* IPv6 type 0 Routing Header	*/
+#define IPV6_SRCRT_TYPE_2	2	/*      type 2 for Mobile IPv6  */
 
 /*
  *	routing header
@@ -67,30 +78,56 @@
 
 struct rt0_hdr {
 	struct ipv6_rt_hdr	rt_hdr;
-	__u32			bitmap;		/* strict/loose bit map */
+	__u32			reserved;	/* 'bitmap' is deprecated */
 	struct in6_addr		addr[0];
 
 #define rt0_type		rt_hdr.type
 };
 
+/* IPsec6 header */
+struct ipv6_auth_hdr {
+	__u8  nexthdr;
+	__u8  hdrlen;		/* This one is measured in 32 bit units! */
+	__u16 reserved;
+	__u32 spi;
+	__u32 seq_no;		/* Sequence number */
+	__u8  auth_data[4];	/* Length variable but >=4. Mind the 64 bit alignment! */
+};
+
+struct ipv6_esp_hdr {
+	__u32 spi;
+	__u32 seq_no;		/* Sequence number */
+	__u8  enc_data[8];	/* Length variable but >=8. Mind the 64 bit alignment! */
+};
+
+/*
+ *	routing header type 2
+ */
+
+struct rt2_hdr {
+	struct ipv6_rt_hdr	rt_hdr;
+	__u32			reserved;
+	struct in6_addr		addr;
+
+#define rt2_type		rt_hdr.type;
+};
+
 /*
  *	IPv6 fixed header
- *
- *	BEWARE, it is incorrect. The first 4 bits of flow_lbl
- *	are glued to priority now, forming "class".
  */
 
+/* XXX: RFC3542 */
 struct ipv6hdr {
 #if defined(__LITTLE_ENDIAN_BITFIELD)
-	__u8			priority:4,
+	__u8			tclass1:4,
 				version:4;
 #elif defined(__BIG_ENDIAN_BITFIELD)
 	__u8			version:4,
-				priority:4;
+				tclass1:4;
 #else
 #error	"Please fix <asm/byteorder.h>"
 #endif
-	__u8			flow_lbl[3];
+	__u8			tclass2_flow[3];
 
 	__u16			payload_len;
 	__u8			nexthdr;
@@ -121,6 +158,10 @@
 	__s32		regen_max_retry;
 	__s32		max_desync_factor;
 #endif
+	int		max_addresses;
+#ifdef CONFIG_IPV6_NODEINFO
+	int		accept_ni;
+#endif
 	void		*sysctl;
 };
 
@@ -143,6 +184,10 @@
 	DEVCONF_REGEN_MAX_RETRY,
 	DEVCONF_MAX_DESYNC_FACTOR,
 #endif
+	DEVCONF_MAX_ADDRESSES,
+#ifdef CONFIG_IPV6_NODEINFO
+	DEVCONF_ACCEPT_NI,
+#endif
 	DEVCONF_MAX
 };
 
diff -urN linux-2.4.29/include/linux/ipv6_route.h linux-2.4.29-uc1/include/linux/ipv6_route.h
--- linux-2.4.29/include/linux/ipv6_route.h	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/ipv6_route.h	2005-06-14 02:11:34.000000000 +0100
@@ -27,6 +27,12 @@
 #define RTF_ADDRCONF	0x00040000	/* addrconf route - RA		*/
 #define RTF_PREFIX_RT	0x00080000	/* A prefix only route - RA	*/
 
+#define RTF_PREF_HIGH	0x00080000
+#define RTF_PREF_LOW	0x00180000
+#define RTF_PREF_INVAL	0x00100000
+#define RTF_PREF_MASK	0x00180000
+#define RTF_PREF(pref)	(((pref)&3)<<19)
+
 #define RTF_NONEXTHOP	0x00200000	/* route with no nexthop	*/
 #define RTF_EXPIRES	0x00400000
 
@@ -34,8 +40,15 @@
 #define RTF_FLOW	0x02000000	/* flow significant route	*/
 #define RTF_POLICY	0x04000000	/* policy route			*/
 
+#define RTF_MOBILENODE	0x10000000	/* for routing to Mobile Node	*/
+
 #define RTF_LOCAL	0x80000000
 
+#ifdef __KERNEL__
+#define IPV6_UNSHIFT_PREF(flag)		(((flag)&RTF_PREF_MASK)>>19)
+#define IPV6_SIGNEDPREF(pref)		((((pref)+2)&3)-2)
+#endif
+
 struct in6_rtmsg {
 	struct in6_addr		rtmsg_dst;
 	struct in6_addr		rtmsg_src;
@@ -53,5 +66,10 @@
 #define RTMSG_DELDEVICE		0x12
 #define RTMSG_NEWROUTE		0x21
 #define RTMSG_DELROUTE		0x22
+#define RTMSG_NEWDEVICE		0x11
+
+struct ip6_zoneid {
+	u32			zoneid[16];
+};
 
 #endif
diff -urN linux-2.4.29/include/linux/ipv6_tunnel.h linux-2.4.29-uc1/include/linux/ipv6_tunnel.h
--- linux-2.4.29/include/linux/ipv6_tunnel.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/ipv6_tunnel.h	2005-06-14 02:11:34.000000000 +0100
@@ -0,0 +1,36 @@
+/*
+ * $Id: s.ipv6_tunnel.h 1.2 02/08/02 12:31:56-00:00 ville $
+ */
+
+#ifndef _IPV6_TUNNEL_H
+#define _IPV6_TUNNEL_H
+
+#define IPV6_TLV_TNL_ENCAP_LIMIT 4
+#define IPV6_DEFAULT_TNL_ENCAP_LIMIT 4
+
+/* don't add encapsulation limit, if one isn't present in inner packet */
+#define IPV6_TNL_F_IGN_ENCAP_LIMIT 0x1
+/* copy the traffic class field from the inner packet */
+#define IPV6_TNL_F_USE_ORIG_TCLASS 0x2
+/* also encapsulate packets originating from the tunnel entry-point node */
+#define IPV6_TNL_F_ALLOW_LOCAL 0x4
+/* created and maintaned from within the kernel */
+#define IPV6_TNL_F_KERNEL_DEV 0x8
+/* being used for Mobile IPv6 */
+#define IPV6_TNL_F_MIPV6_DEV 0x10
+/* only capable of receiving packets because local address isn't unicast */
+#define IPV6_TNL_F_RCV_ONLY 0x20
+
+struct ipv6_tnl_parm {
+	char name[IFNAMSIZ];	/* name of tunnel device */
+	int link;		/* ifindex of underlying link layer interface */
+	__u8 proto;		/* tunnel protocol */
+	__u8 encap_limit;	/* encapsulation limit for tunnel */
+	__u8 hop_limit;		/* hop limit for tunnel */
+	__u32 flow_lbl;		/* flow  label for tunnel */
+	__u32 flags;		/* tunnel flags */
+	struct in6_addr laddr;	/* local tunnel end-point address */
+	struct in6_addr raddr;	/* remote tunnel end-point address */
+};
+
+#endif
diff -urN linux-2.4.29/include/linux/jffs.h linux-2.4.29-uc1/include/linux/jffs.h
--- linux-2.4.29/include/linux/jffs.h	2001-10-04 23:13:18.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/jffs.h	2005-06-14 02:11:36.000000000 +0100
@@ -191,6 +191,7 @@
 	struct completion gc_thread_comp; /* GC thread exit mutex */
 	__u32 gc_minfree_threshold;	/* GC trigger thresholds */
 	__u32 gc_maxdirty_threshold;
+	__u16 gc_background;		/* GC currently running in background */
 };
 
 
diff -urN linux-2.4.29/include/linux/ledman.h linux-2.4.29-uc1/include/linux/ledman.h
--- linux-2.4.29/include/linux/ledman.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/ledman.h	2005-06-14 02:11:35.000000000 +0100
@@ -0,0 +1,106 @@
+#ifndef __LINUX_LEDMAN_H__
+#define __LINUX_LEDMAN_H__ 1
+/****************************************************************************/
+/*
+ *	ledman.h:  LED manager header,  generic, device indepedant LED stuff
+ *
+ *	defines for led functionality which may/may not be implemented by the
+ *	currently active LED configuration
+ *
+ *	NOTE: do not change the numbering of the defines below,  tables of
+ *	      LED patterns rely on these values
+ */
+
+#define LEDMAN_ALL			0	/* special case, all LED's */
+
+#define LEDMAN_POWER		1
+#define LEDMAN_HEARTBEAT	2
+#define LEDMAN_COM1_RX		3
+#define LEDMAN_COM1_TX		4
+#define LEDMAN_COM2_RX		5
+#define LEDMAN_COM2_TX		6
+#define LEDMAN_LAN1_RX		7
+#define LEDMAN_LAN1_TX		8
+#define LEDMAN_LAN2_RX		9
+#define LEDMAN_LAN2_TX		10
+#define LEDMAN_USB1_RX		11
+#define LEDMAN_USB1_TX		12
+#define LEDMAN_USB2_RX		13
+#define LEDMAN_USB2_TX		14
+#define LEDMAN_NVRAM_1		15
+#define LEDMAN_NVRAM_2		16
+#define LEDMAN_VPN			17
+#define LEDMAN_LAN1_DHCP	18
+#define LEDMAN_LAN2_DHCP	19
+#define LEDMAN_COM1_DCD		20
+#define LEDMAN_COM2_DCD		21
+#define LEDMAN_ONLINE		22
+#define LEDMAN_LAN1_LINK	23
+#define LEDMAN_LAN2_LINK	24
+#define LEDMAN_VPN_RX		25
+#define LEDMAN_VPN_TX		26
+#define LEDMAN_RESET		27
+#define LEDMAN_STATIC		28
+#define LEDMAN_LAN3_RX		29
+#define LEDMAN_LAN3_TX		30
+#define LEDMAN_LAN3_LINK	31
+#define LEDMAN_LAN3_DHCP	32
+#define LEDMAN_FAILOVER		33
+#define	LEDMAN_MAX			34	/* one more than the highest LED above */
+
+#define LEDMAN_MAX_NAME		16
+
+/****************************************************************************/
+/*
+ *	ioctl cmds
+ */
+
+#define LEDMAN_CMD_SET		0x01	/* turn on briefly to show activity */
+#define LEDMAN_CMD_ON		0x02	/* turn LED on permanently */
+#define LEDMAN_CMD_OFF		0x03	/* turn LED off permanently */
+#define LEDMAN_CMD_FLASH	0x04	/* flash this LED */
+#define LEDMAN_CMD_RESET	0x05	/* reset LED to default behaviour */
+
+#define LEDMAN_CMD_ALT_ON	0x06	/* LED is being used for non-std reasons */
+#define LEDMAN_CMD_ALT_OFF	0x07	/* LED is being used for std reasons */
+
+#define LEDMAN_CMD_MODE			0x80	/* set LED to named mode (led=char *) */
+#define LEDMAN_CMD_STARTTIMER	0x81	/* enable and init the ledman driver */
+#define LEDMAN_CMD_KILLTIMER	0x82	/* disable the ledman driver */
+ 
+#define	LEDMAN_CMD_SIGNAL		0x100	/* pid of process to signal on reset */
+
+#define LEDMAN_CMD_ALTBIT		0x8000	/* operate on alternate LED settings */
+
+/****************************************************************************/
+
+#define LEDMAN_MAJOR	126
+
+/****************************************************************************/
+#ifdef __KERNEL__
+
+#if LINUX_VERSION_CODE < 0x020100
+extern int ledman_init(void);
+#endif
+
+extern int  ledman_setup(char *arg);
+extern void ledman_killtimer(void);
+extern void ledman_starttimer(void);
+extern int  ledman_cmd(int cmd, unsigned long led);
+extern void ledman_signalreset(void);
+
+#else
+
+#include	<fcntl.h>
+
+#define ledman_cmd(cmd, led) ({ \
+	int fd; \
+	if ((fd = open("/dev/ledman", O_RDWR)) != -1) { \
+		ioctl(fd, cmd, led); \
+		close(fd); \
+	} \
+})
+
+#endif
+/****************************************************************************/
+#endif /* __LINUX_LEDMAN_H__ */
diff -urN linux-2.4.29/include/linux/major.h linux-2.4.29-uc1/include/linux/major.h
--- linux-2.4.29/include/linux/major.h	2003-06-13 15:51:38.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/major.h	2005-06-14 02:11:37.000000000 +0100
@@ -64,6 +64,7 @@
 #define ACSI_MAJOR	28
 #define AZTECH_CDROM_MAJOR 29
 #define GRAPHDEV_MAJOR	29	/* SparcLinux & Linux/68k /dev/fb */
+#define BLKMEM_MAJOR	31
 #define SHMIQ_MAJOR	85	/* Linux/mips, SGI /dev/shmiq */
 #define CM206_CDROM_MAJOR 32
 #define IDE2_MAJOR	33
diff -urN linux-2.4.29/include/linux/mba44b0touch.h linux-2.4.29-uc1/include/linux/mba44b0touch.h
--- linux-2.4.29/include/linux/mba44b0touch.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/mba44b0touch.h	2005-06-14 02:11:34.000000000 +0100
@@ -0,0 +1,59 @@
+#ifndef __MBA44B0TOUCH_INC__
+#define __MBA44B0TOUCH_INC__
+
+/*
+ * Copyright (C) 2003 Stefan Macher <macher@sympat.de>
+ *                    Alexander Assel <assel@sympat.de>
+ */
+
+/* debugging stuff */
+#define MBA44B0_TS_DEBUG_ERR    (1 << 0)
+#define MBA44B0_TS_DEBUG_INFO   (1 << 1)
+#define MBA44B0_TS_DEBUG_ADC    (1 << 2)
+#define MBA44B0_TS_DEBUG_POS    (1 << 3)
+#define MBA44B0_TS_DEBUG_PRESS  (1 << 4)
+#define MBA44B0_TS_DEBUG_CONFIG (1 << 5)
+#define MBA44B0_TS_DEBUG_IRQ    (1 << 6)
+#define MBA44B0_TS_DEBUG(x,args...) if(x&mba44b0_ts_debug_mask) printk("mba44b0_touch: " args);
+
+//------------------------------
+//IOCTL COMMANDS und structures
+//------------------------------
+#define MBA44B0_TS_SET_CAL_PARAMS 0
+#define MBA44B0_TS_GET_CAL_PARAMS 1
+#define MBA44B0_TS_SET_X_RES      2
+#define MBA44B0_TS_SET_Y_RES      3
+
+struct mba44b0_cal_settings {
+  int cal_x_off;
+  unsigned int cal_x_scale_num;
+  unsigned int cal_x_scale_denom;
+  int cal_y_off;
+  unsigned int cal_y_scale_num;
+  unsigned int cal_y_scale_denom;
+};
+
+//------------------------------
+// PRESS THRESHOLD
+//------------------------------
+#define MBA44B0_TS_PRESS_THRESHOLD 512
+//------------------------------
+
+//------------------------------
+// Device definintions
+//------------------------------
+#define TS_DEVICE "MBA44B0"
+#define TS_DEVICE_FILE "/dev/touchscreen/mba44b0"
+
+
+/*! \brief Interface struct used for reading from touchscreen device
+ */
+struct ts_event 
+{
+  unsigned char pressure; //!< zero -> not pressed, all other values indicate that the touch is pressed
+  short x; //!< The x position
+  short y; //!< The y position
+  short pad; //!< No meaning for now
+};
+
+#endif
diff -urN linux-2.4.29/include/linux/mc68328digi.h linux-2.4.29-uc1/include/linux/mc68328digi.h
--- linux-2.4.29/include/linux/mc68328digi.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/mc68328digi.h	2005-06-14 02:11:35.000000000 +0100
@@ -0,0 +1,377 @@
+/*----------------------------------------------------------------------------*/
+/*
+ * linux/drivers/char/mc68328digi.h - Touch screen driver.
+ *                                    Header file.
+ *
+ * Author: Philippe Ney <philippe.ney@smartdata.ch>
+ * Copyright (C) 2001 SMARTDATA <www.smartdata.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Thanks to:
+ *   Kenneth Albanowski for is first work on a touch screen driver.
+ *   Alessandro Rubini for is "Linux device drivers" book.
+ *   Ori Pomerantz for is "Linux Kernel Module Programming" guide.
+ *
+ * Updates:
+ *   2001-03-12 Pascal bauermeister
+ *              - Modified the semantics of ts_drv_params;
+ *              - Added check for version in ioctl()
+ *              - included a sample code in the end of this file as comment
+ *
+ *----------------------------------------------------------------------------
+ * Known bugs:
+ *   - read() returns zero
+ *
+ *----------------------------------------------------------------------------
+ * HOW TO SETUP THE PARAMETERS FOR COORDINATES SCALING
+ *
+ * The driver does scaling as follows, in this order:
+ *   o for x and y raw samples:
+ *       - raw position is multiplied by ratio_num
+ *       - result is divided by ratio_den
+ *       - offset is added to the result
+ *       - result is bounded by min and max
+ *   o x and y results are swapped if xy_swap is non-zero
+ *
+ * Appropriate parameter combinations allow things like:
+ *   o rotations in multiples of 90 degrees
+ *   o coordinate mirroring
+ *   o negative coordinates
+ *   o etc.
+ *
+ * How to calculate the parameters:
+ *   o Depending on your hardware, you may need to have x and y swapped. If
+ *     so, set xy_swap to 1, always.
+ *   o Calibration phase:
+ *     choose two physical points, preferrably diagonally opposite corners of
+ *     the touch panel. Measure one first time with num=den=1 and offset=0,
+ *     i.e. do an ioctl() to set these parameters, and some read() to read
+ *     these points.
+ *
+ *   o Let mx1 be the value measured at the left edge of your touchscreen
+ *         mx2 be the value measured at the right edge of your touchscreen
+ *         ux1 be the value you want your userland programs to see for mx1
+ *         ux2 be the value you want your userland programs to see for mx2
+ *   o For X, calculate:
+ *         x_ratio_num = ux1 - ux2
+ *         x_ratio_den = mx1 - mx2
+ *         x_offset = ux1 - mx1*x_ratio_num/x_ratio_den  (or the same with x2)
+ *   o Do the same for Y
+ *   o Then set the min and max according to the bounds you desire for userland
+ *     values
+ *
+ * Notes:
+ *   o We assume linearity between the touchscreen coordinates space and the
+ *     userland coordinate space
+ *   o During calibration, the points may be any pair of points, but best
+ *     results are obtained if they are as distant as possible
+ *  
+ *
+ *----------------------------------------------------------------------------
+ *
+ * Event generated:
+ *                __________      ______________
+ *   1) /PENIRQ            |     |
+ *                         -------
+ *
+ *                         |     |
+ *                         |     +-> generate PEN_UP
+ *                         |
+ *                         +-------> generate PEN_DOWN
+ *
+ *                __________               ______________
+ *   2) /PENIRQ            |              |
+ *                         ------#####-----
+ *
+ *                         |     |||||    |
+ *                         |     |||||    +-> generate PEN_UP
+ *                         |     |||||
+ *                         |     ||||+------> generate PEN_MOVE
+ *                         |     |||+-------> generate PEN_MOVE
+ *                         |     ||+--------> generate PEN_MOVE
+ *                         |     |+---------> generate PEN_MOVE
+ *                         |     +----------> generate PEN_MOVE
+ *                         |
+ *                         -----------------> generate PEN_DOWN
+ *
+ */
+/*----------------------------------------------------------------------------*/
+
+#ifndef _MC68328DIGI_H
+#define _MC68328DIGI_H
+
+#ifdef __KERNEL__
+#include <linux/time.h>   /* for timeval struct */
+#include <linux/ioctl.h>  /* for the _IOR macro to define the ioctl commands  */
+#endif
+
+/*----------------------------------------------------------------------------*/
+/* Used to check the driver vs. userland program.
+ *
+ * If they have the same number, it means that 'struct ts_pen_info' and
+ * 'struct ts_drv_params' have compatible semantics on both side. Otherwise
+ * one side is outdated.
+ *
+ * The number has to be incremented if and only if updates in the driver lead
+ * to any change in the semantics of these interface data structures (and not
+ * if some internal mechanism of the driver are changed).
+ */
+
+#define MC68328DIGI_VERSION 2
+
+/* Userland programs can get this version number in params.version after
+ * ioctl(fd, TS_PARAMS_GET, &params). Userland programs must specify their
+ * version compatibility by setting version_req to MC68328DIGI_VERSION before
+ * doing  ioctl(fd, TS_PARAMS_SET, &params).
+ *
+ * If version_req does not match, ioctl(fd, TS_PARAMS_SET, &params) would return
+ * EBADRQC ('Invalid request code').
+ *
+ * Note:
+ *   it is not possible to check the compatibility for 'struct ts_pen_info'
+ *   without doing an ioctl(fd, TS_PARAMS_SET, &params). So, please, do an
+ *   ioctl(fd, TS_PARAMS_SET, &params)!
+ */
+
+/*----------------------------------------------------------------------------*/
+
+/* Pen events */
+#define EV_PEN_DOWN    0
+#define EV_PEN_UP      1
+#define EV_PEN_MOVE    2
+
+/* Pen states */
+/* defined through the 2 lsb of an integer variable. If an error occure,
+ * the driver will recover the state PEN_UP and the error bit will be set.
+ */
+#define ST_PEN_DOWN    (0<<0)   /* bit 0 at 0 = the pen is down            */
+#define ST_PEN_UP      (1<<0)   /* bit 0 at 1 = the pen is up              */
+#define ST_PEN_ERROR   (1<<1)   /* bit 1 at 1 means that an error occure   */
+
+/* Definition for the ioctl of the driver */
+/* Device is type misc then major=10 */
+#define MC68328DIGI_MAJOR  10
+
+#define TS_PARAMS_GET _IOR(MC68328DIGI_MAJOR, 0, struct ts_drv_params)
+#define TS_PARAMS_SET _IOR(MC68328DIGI_MAJOR, 1, struct ts_drv_params)
+ 
+/*----------------------------------------------------------------------------*/
+
+/* Available info from pen position and status */
+struct ts_pen_info {
+  int x,y;    /* pen position                                      */
+  int dx,dy;  /* delta move from last position                     */
+  int event;  /* event from pen (DOWN,UP,CLICK,MOVE)               */
+  int state;  /* state of pen (DOWN,UP,ERROR)                      */
+  int ev_no;  /* no of the event                                   */
+  unsigned long ev_time;  /* time of the event (ms) since ts_open  */
+};
+
+/* Structure that define touch screen parameters */
+struct ts_drv_params {
+  int version;     /* version number for check, returned by TS_PARAMS_GET
+		    */
+  int version_req; /* version number for check, that MUST be set to
+		    * MC68328DIGI_VERSION prior to do TS_PARAMS_SET,
+		    * or to -1 to bypass checking (do not do this usually)
+		    */
+  int x_ratio_num; /*                        */
+  int x_ratio_den; /*                        */
+  int y_ratio_num; /*                        */
+  int y_ratio_den; /*                        */
+  int x_offset;    /*                        */
+  int y_offset;    /*                        */
+  int xy_swap;     /*                        */
+  int x_min;       /*                        */
+  int y_min;       /*                        */
+  int x_max;       /*                        */
+  int y_max;       /*                        */
+  int mv_thrs;     /* minimum delta move to considere the pen start to move */
+  int follow_thrs; /* minimum delta move to follow the pen move when the pen
+                    * is moving
+		    */
+  int sample_ms;   /* time between sampling (ms) */
+  int deglitch_on; /* whether to filter glitches at pen down */
+  int event_queue_on; /* switch on and off the event queue */
+};
+
+
+/*------------------------------------------------------------------------------
+** The following sample code illustrates the usage of the ts driver:
+** 
+** #include <string.h>
+** #include <errno.h>
+** #include <fcntl.h>
+** #include <stdio.h>
+** #include <linux/mc68328digi.h>
+** 
+** 
+**
+** 
+** const char *ts_device_name = "/dev/ts";
+** 
+**
+**
+**
+** 
+** 
+** void tsdrv_params_fprint(FILE *f, struct ts_drv_params *p)
+** {
+**   fprintf(f, "version     : %d\n",    p->version);
+**   fprintf(f, "version_req : %d\n",    p->version_req);
+**   fprintf(f, "x ratio     : %d/%d\n", p->x_ratio_num, p->x_ratio_den);
+**   fprintf(f, "y ratio     : %d/%d\n", p->y_ratio_num, p->y_ratio_den);
+**   fprintf(f, "x limits    : %d/%d\n", p->x_min, p->x_max);
+**   fprintf(f, "y limits    : %d/%d\n", p->y_min, p->y_max);
+**   fprintf(f, "x offset    : %d\n",    p->x_offset);
+**   fprintf(f, "y offset    : %d\n",    p->y_offset);
+**   fprintf(f, "invert xy   : %d\n",    p->xy_swap);
+**   fprintf(f, "mv thrs     : %d\n",    p->mv_thrs);
+**   fprintf(f, "follow thrs : %d\n",    p->follow_thrs);
+**   fprintf(f, "sample ms   : %d\n",    p->sample_ms);
+**   fprintf(f, "dglitch on  : %d\n",    p->deglitch_on);
+**   fprintf(f, "evt Q on    : %d\n",    p->event_queue_on);
+** }
+** 
+** 
+** int tsdrv_init(int argc, char *argv[])
+** {
+**   int ts_fd;
+**   int err;
+**   struct ts_drv_params  drv_params;
+**   int mx1, mx2, my1, my2;
+**   int ux1, ux2, uy1, uy2;
+** 
+**   ts_fd = open(ts_device_name, O_RDWR);
+**   if(ts_fd==0) {
+**     fprintf(stderr, "%s: error: could not open device %s\n",
+** 	    argv[0], ts_device_name);
+**     return 0;
+**   }
+** 
+**   err = ioctl(ts_fd, TS_PARAMS_GET, &drv_params);
+**   if(err)  {
+**     fprintf(stderr, "%s: ioctl TS_PARAMS_GET error: %s\n",
+** 	    argv[0], strerror(errno));
+**     close(ts_fd);
+**     return 0;
+**   }
+** 
+**   printf("\nDefault driver settings:\n");
+**   tsdrv_params_fprint(stdout, &drv_params);
+** 
+** 
+**   drv_params.version_req    = MC68328DIGI_VERSION;
+**   drv_params.event_queue_on = 1;
+**   drv_params.deglitch_on    = 0;
+**   drv_params.sample_ms      = 10;
+**   drv_params.follow_thrs    = 0;
+**   drv_params.mv_thrs        = 2;
+**   drv_params.y_max          = 159 + 66; 
+**   drv_params.y_min          = 0;
+**   drv_params.x_max          = 159;
+**   drv_params.x_min          = 0;
+**   drv_params.xy_swap        = 0;
+** 
+**  
+**  
+**   mx1 = 508; ux1 =   0;
+**   my1 = 508; uy1 =   0;
+**   mx2 = 188; ux2 = 159;
+**   my2 = 188; uy2 = 159;
+** 
+**  
+**   drv_params.x_ratio_num    = ux1 - ux2;
+**   drv_params.x_ratio_den    = mx1 - mx2;
+**   drv_params.x_offset       =
+**     ux1 - mx1 * drv_params.x_ratio_num / drv_params.x_ratio_den;
+** 
+**   drv_params.y_ratio_num    = uy1 - uy2;
+**   drv_params.y_ratio_den    = my1 - my2;
+**   drv_params.y_offset       =
+**     uy1 - my1 * drv_params.y_ratio_num / drv_params.y_ratio_den;
+** 
+** 
+**   printf("\nNew driver settings:\n");
+**   tsdrv_params_fprint(stdout, &drv_params);
+** 
+**   err = ioctl(ts_fd, TS_PARAMS_SET, &drv_params);
+**   if(err)  {
+**     fprintf(stderr, "%s: ioctl TS_PARAMS_SET error: %s\n",
+** 	    argv[0], strerror(errno));
+**     close(ts_fd);
+**     return 0;
+**   }
+** 
+**   return ts_fd;
+** }
+** 
+**
+**
+**
+** 
+** main(int argc, char *argv[])
+** {
+**   int                   ts_fd = 0;
+**   struct ts_pen_info    pen_info;
+**   int                   bytes_transfered = 0;
+** 
+** 
+**   ts_fd = tsdrv_init(argc, argv);
+**   if(ts_fd==0)
+**     exit(1);
+** 
+** 
+**   while(1) {
+**     char whats_up;
+**     int x, y;
+**     bytes_transfered = read(ts_fd, (void*)&pen_info, sizeof(pen_info));
+**     x = pen_info.x;
+**     y = pen_info.y;
+** 
+**     switch(pen_info.event) {
+** 
+**     case EV_PEN_UP:
+**       whats_up = 'U';
+**       break;
+** 
+**     case EV_PEN_DOWN:
+**       whats_up = 'D';
+**       break;
+** 
+**     case EV_PEN_MOVE:
+**       whats_up = 'M';
+**       break;
+** 
+**     default:
+**       whats_up = '?';
+**     }
+** 
+**     printf("%c(%i,%i) ", whats_up, x, y);
+**     printf("ev_no:%d ", pen_info.ev_no);
+**     printf("ev_usec:%ld ", pen_info.ev_time);
+**     printf("bytes_transfered:%d ", bytes_transfered);
+**     printf("\n");
+**   }
+** 
+**  
+**   close(ts_fd);
+**   exit(0);
+** }
+** 
+**
+** 
+** <<< End of example ----------------------------------------------------------
+*/
+
+
+#endif /* _MC68328DIGI_H */
diff -urN linux-2.4.29/include/linux/miscdevice.h linux-2.4.29-uc1/include/linux/miscdevice.h
--- linux-2.4.29/include/linux/miscdevice.h	2003-06-13 15:51:38.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/miscdevice.h	2005-06-14 02:11:33.000000000 +0100
@@ -14,7 +14,9 @@
 #define PC110PAD_MINOR		9
 #define ADB_MOUSE_MINOR		10
 #define MK712_MINOR 		15	/* MK712 touch screen */
+#define MBA44B0_TS_MINOR        16      /* MBA44B0 touch screen */
 #define SYNTH_MINOR    		25
+#define	CRYPTODEV_MINOR		70	/* OpenBSD cryptographic framework */
 #define WATCHDOG_MINOR		130	/* Watchdog timer     */
 #define TEMP_MINOR		131	/* Temperature Sensor */
 #define RTC_MINOR		135
diff -urN linux-2.4.29/include/linux/mm.h linux-2.4.29-uc1/include/linux/mm.h
--- linux-2.4.29/include/linux/mm.h	2005-01-19 14:10:12.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/mm.h	2005-06-14 02:11:36.000000000 +0100
@@ -26,6 +26,10 @@
 #include <asm/pgtable.h>
 #include <asm/atomic.h>
 
+#ifdef MAGIC_ROM_PTR
+extern int is_in_rom(unsigned long);
+#endif
+
 /*
  * Linux kernel virtual memory manager primitives.
  * The idea being to have a "virtual" mm in the same way
@@ -35,6 +39,8 @@
  * mmap() functions).
  */
 
+#ifndef NO_MM
+
 /*
  * This struct defines a memory VMM memory area. There is one of these
  * per VM-area/task.  A VM area is any part of the process virtual memory
@@ -72,8 +78,23 @@
 	struct file * vm_file;		/* File we map to (can be NULL). */
 	unsigned long vm_raend;		/* XXX: put full readahead info here. */
 	void * vm_private_data;		/* was vm_pte (shared mem) */
+        void * vm_sharing_data;         /* Used by ARM FASS and IA-64 stuff */
+};
+
+#else /* NO_MM */
+
+/* This dummy vm_area_struct does not define a VM area, it is only
+   used to convey data between do_mmap and a f_op's mmap function. */
+ 
+struct vm_area_struct {
+	unsigned long vm_start;
+	unsigned long vm_end;
+	unsigned short vm_flags;
+	unsigned long vm_offset;
 };
 
+#endif /* NO_MM */
+
 /*
  * vm_flags..
  */
@@ -118,6 +139,8 @@
 extern int vm_min_readahead;
 extern int vm_max_readahead;
 
+#ifndef NO_MM
+
 /*
  * mapping from the currently active vm_flags protection bits (the
  * low four bits) to a page protection mask..
@@ -136,6 +159,8 @@
 	struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int unused);
 };
 
+#endif /* NO_MM */
+
 /*
  * Each physical page in the system has a struct page associated with
  * it to keep track of whatever it is we are using the page for at the
@@ -305,6 +330,7 @@
 #define PG_reserved		14
 #define PG_launder		15	/* written out by VM pressure.. */
 #define PG_fs_1			16	/* Filesystem specific */
+#define PG_first_free	17	/* first free flag (used by NOMMU systems) */
 
 #ifndef arch_set_page_uptodate
 #define arch_set_page_uptodate(page)
@@ -335,8 +361,16 @@
  * The zone field is never updated after free_area_init_core()
  * sets it, so none of the operations on it need to be atomic.
  */
-#define NODE_SHIFT 4
+// not used #define NODE_SHIFT 4
+#ifndef NO_MM
 #define ZONE_SHIFT (BITS_PER_LONG - 8)
+#else
+/*
+ * So we can have bigger allocs when using the contiguous page allocator
+ * we reduce the space used by zones as MAX_ZONES is only 3 currently
+ */
+#define ZONE_SHIFT (BITS_PER_LONG - 4)
+#endif
 
 struct zone_struct;
 extern struct zone_struct *zone_table[];
@@ -352,6 +386,10 @@
 	page->flags |= zone_num << ZONE_SHIFT;
 }
 
+#ifdef NO_MM
+#define page_contig(p) (((p)->flags & ~(~0UL << ZONE_SHIFT)) >> PG_first_free)
+#endif
+
 /*
  * In order to avoid #ifdefs within C code itself, we define
  * set_page_address to a noop for non-highmem machines, where
@@ -508,6 +546,8 @@
 int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
 		int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
 
+#ifndef NO_MM
+
 /*
  * On a two-level page table, this ends up being trivial. Thus the
  * inlining and the symmetry break with pte_alloc() that does all
@@ -522,6 +562,7 @@
 
 extern int pgt_cache_water[2];
 extern int check_pgt_cache(void);
+#endif /* NO_MM */
 
 extern void free_area_init(unsigned long * zones_size);
 extern void free_area_init_node(int nid, pg_data_t *pgdat, struct page *pmap,
@@ -530,10 +571,14 @@
 extern void mem_init(void);
 extern void show_mem(void);
 extern void si_meminfo(struct sysinfo * val);
+#ifndef CONFIG_UCLINUX
 extern void swapin_readahead(swp_entry_t);
-
 extern struct address_space swapper_space;
 #define PageSwapCache(page) ((page)->mapping == &swapper_space)
+#else
+#define swap_count(page) 0
+#define PageSwapCache(page) 0
+#endif /* CONFIG_UCLINUX */
 
 static inline int is_page_cache_freeable(struct page * page)
 {
@@ -578,17 +623,21 @@
 
 static inline void __vma_unlink(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct * prev)
 {
+#ifndef NO_MM
 	prev->vm_next = vma->vm_next;
 	rb_erase(&vma->vm_rb, &mm->mm_rb);
 	if (mm->mmap_cache == vma)
 		mm->mmap_cache = prev;
+#endif
 }
 
 static inline int can_vma_merge(struct vm_area_struct * vma, unsigned long vm_flags)
 {
+#ifndef NO_MM
 	if (!vma->vm_file && vma->vm_flags == vm_flags)
 		return 1;
 	else
+#endif
 		return 0;
 }
 
@@ -640,6 +689,8 @@
 	return gfp_mask;
 }
 	
+#ifndef NO_MM
+
 /* vma is the first one with  address < vma->vm_end,
  * and even  address < vma->vm_start. Have to extend vma. */
 static inline int expand_stack(struct vm_area_struct * vma, unsigned long address)
@@ -700,6 +751,8 @@
 }
 
 extern struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr);
+#endif /* NO_MM */
+
 
 extern struct page * vmalloc_to_page(void *addr);
 
diff -urN linux-2.4.29/include/linux/mmzone.h linux-2.4.29-uc1/include/linux/mmzone.h
--- linux-2.4.29/include/linux/mmzone.h	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/mmzone.h	2005-06-14 02:11:35.000000000 +0100
@@ -13,10 +13,12 @@
  * Free memory management - zoned buddy allocator.
  */
 
-#ifndef CONFIG_FORCE_MAX_ZONEORDER
-#define MAX_ORDER 10
-#else
+#ifdef CONFIG_FORCE_MAX_ZONEORDER
 #define MAX_ORDER CONFIG_FORCE_MAX_ZONEORDER
+#elif defined (CONFIG_NO_MMU_LARGE_ALLOCS)
+#define MAX_ORDER 13
+#else
+#define MAX_ORDER 10
 #endif
 
 #define ZONE_DMA               0
@@ -249,7 +251,12 @@
 
 /* page->zone is currently 8 bits ... */
 #ifndef MAX_NR_NODES
+#ifndef NO_MM
 #define MAX_NR_NODES		(255 / MAX_NR_ZONES)
+#else
+/* only 4 bits for nomm */
+#define MAX_NR_NODES		(15 / MAX_NR_ZONES)
+#endif
 #endif
 
 #endif /* !CONFIG_DISCONTIGMEM */
diff -urN linux-2.4.29/include/linux/mtd/cfi.h linux-2.4.29-uc1/include/linux/mtd/cfi.h
--- linux-2.4.29/include/linux/mtd/cfi.h	2003-06-13 15:51:38.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/mtd/cfi.h	2005-06-14 02:11:35.000000000 +0100
@@ -307,7 +307,7 @@
 	struct mtd_info *(*cmdset_setup)(struct map_info *);
 	struct cfi_ident *cfiq; /* For now only one. We insist that all devs
 				  must be of the same type. */
-	int mfr, id;
+	int mfr, id, extra;
 	int numchips;
 	unsigned long chipshift; /* Because they're of the same type */
 	const char *im_name;	 /* inter_module name for cmdset_setup */
diff -urN linux-2.4.29/include/linux/mtd/doc2000.h linux-2.4.29-uc1/include/linux/mtd/doc2000.h
--- linux-2.4.29/include/linux/mtd/doc2000.h	2001-10-04 23:13:18.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/mtd/doc2000.h	2005-06-14 02:11:35.000000000 +0100
@@ -38,12 +38,41 @@
 #define DoC_Mil_CDSN_IO 	0x0800
 #define DoC_2k_CDSN_IO 		0x1800
 
+#define DoC_Mplus_NOP			0x1002
+#define DoC_Mplus_AliasResolution	0x1004
+#define DoC_Mplus_DOCControl		0x1006
+#define DoC_Mplus_AccessStatus		0x1008
+#define DoC_Mplus_DeviceSelect		0x1008
+#define DoC_Mplus_Configuration		0x100a
+#define DoC_Mplus_OutputControl		0x1002
+#define DoC_Mplus_FlashControl		0x1020
+#define DoC_Mplus_FlashSelect 		0x1022
+#define DoC_Mplus_FlashCmd		0x1024
+#define DoC_Mplus_FlashAddress		0x1026
+#define DoC_Mplus_FlashData0		0x1028
+#define DoC_Mplus_FlashData1		0x1029
+#define DoC_Mplus_ReadPipeInit		0x102a
+#define DoC_Mplus_LastDataRead		0x102c
+#define DoC_Mplus_LastDataRead1		0x102d
+#define DoC_Mplus_WritePipeTerm 	0x102e
+#define DoC_Mplus_ECCSyndrome0		0x1040
+#define DoC_Mplus_ECCSyndrome1		0x1041
+#define DoC_Mplus_ECCSyndrome2		0x1042
+#define DoC_Mplus_ECCSyndrome3		0x1043
+#define DoC_Mplus_ECCSyndrome4		0x1044
+#define DoC_Mplus_ECCSyndrome5		0x1045
+#define DoC_Mplus_ECCConf 		0x1046
+#define DoC_Mplus_Toggle		0x1046
+#define DoC_Mplus_DownloadStatus	0x1074
+#define DoC_Mplus_CtrlConfirm		0x1076
+#define DoC_Mplus_Power			0x1fff
+
 /* How to access the device? 
  * On ARM, it'll be mmap'd directly with 32-bit wide accesses. 
  * On PPC, it's mmap'd and 16-bit wide.
  * Others use readb/writeb 
  */
-#if defined(__arm__)
+#if defined(__arm__) && !defined(CONFIG_MACH_ESS710) && !defined(CONFIG_MACH_SE5100)
 #define ReadDOC_(adr, reg)      ((unsigned char)(*(__u32 *)(((unsigned long)adr)+((reg)<<2))))
 #define WriteDOC_(d, adr, reg)  do{ *(__u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0)
 #define DOC_IOREMAP_LEN 0x8000
@@ -51,6 +80,24 @@
 #define ReadDOC_(adr, reg)      ((unsigned char)(*(__u16 *)(((unsigned long)adr)+((reg)<<1))))
 #define WriteDOC_(d, adr, reg)  do{ *(__u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0)
 #define DOC_IOREMAP_LEN 0x4000
+#elif defined(CONFIG_SH_SECUREEDGE5410)
+
+static inline unsigned char _ReadDOC_(unsigned long adr, int reg)
+{
+	readb((adr ^ 0x04000000) & 0xf4000000); /* read other flash chip */
+	return(readb(((unsigned long)adr)+(reg)));
+}
+
+static inline void _WriteDOC_(unsigned char d, unsigned long adr, int reg)
+{
+	readb((adr ^ 0x04000000) & 0xf4000000); /* read other flash chip */
+	writeb(d, ((unsigned long)adr) + (reg));
+}
+
+#define ReadDOC_(adr, reg) _ReadDOC_((unsigned long)(adr), (int)(reg))
+#define WriteDOC_(d, adr, reg) _WriteDOC_((unsigned char)(d), (unsigned long)(adr), (int)(reg))
+
+#define DOC_IOREMAP_LEN 0x2000
 #else
 #define ReadDOC_(adr, reg)      readb(((unsigned long)adr) + (reg))
 #define WriteDOC_(d, adr, reg)  writeb(d, ((unsigned long)adr) + (reg))
@@ -71,13 +118,20 @@
 #define DOC_MODE_RESERVED1 	2
 #define DOC_MODE_RESERVED2 	3
 
-#define DOC_MODE_MDWREN 	4
 #define DOC_MODE_CLR_ERR 	0x80
+#define	DOC_MODE_RST_LAT	0x10
+#define	DOC_MODE_BDECT		0x08
+#define DOC_MODE_MDWREN 	0x04
 
 #define DOC_ChipID_Doc2k 	0x20
 #define DOC_ChipID_DocMil 	0x30
+#define DOC_ChipID_DocMilPlus32	0x40
+#define DOC_ChipID_DocMilPlus16	0x41
 
 #define CDSN_CTRL_FR_B 		0x80
+#define CDSN_CTRL_FR_B0		0x40
+#define CDSN_CTRL_FR_B1		0x80
+
 #define CDSN_CTRL_ECC_IO 	0x20
 #define CDSN_CTRL_FLASH_IO 	0x10
 #define CDSN_CTRL_WP 		0x08
@@ -93,6 +147,10 @@
 #define DOC_ECC_RESV 		0x02
 #define DOC_ECC_IGNORE		0x01
 
+#define DOC_FLASH_CE		0x80
+#define DOC_FLASH_WP		0x40
+#define DOC_FLASH_BANK		0x02
+
 /* We have to also set the reserved bit 1 for enable */
 #define DOC_ECC_EN (DOC_ECC__EN | DOC_ECC_RESV)
 #define DOC_ECC_DIS (DOC_ECC_RESV)
@@ -110,6 +168,9 @@
 #define MAX_FLOORS_MIL 4
 #define MAX_CHIPS_MIL 1
 
+#define MAX_FLOORS_MPLUS 1
+#define MAX_CHIPS_MPLUS 1
+
 #define ADDR_COLUMN 1
 #define ADDR_PAGE 2
 #define ADDR_COLUMN_PAGE 3
@@ -126,6 +187,7 @@
 	int chipshift;
 	char page256;
 	char pageadrlen;
+	char interleave; /* Internal interleaving - Millennium Plus style */
 	unsigned long erasesize;
 	
 	int curfloor;
diff -urN linux-2.4.29/include/linux/mtd/inftl.h linux-2.4.29-uc1/include/linux/mtd/inftl.h
--- linux-2.4.29/include/linux/mtd/inftl.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/mtd/inftl.h	2005-06-14 02:11:35.000000000 +0100
@@ -0,0 +1,132 @@
+/*
+ *	inftl.h -- defines to support the Inverse NAND Flash Translation Layer
+ *
+ *	(C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
+ */
+
+#ifndef __MTD_INFTL_H__
+#define __MTD_INFTL_H__
+
+#ifndef __BOOT__
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nftl.h>
+#endif
+
+#define	OSAK_VERSION	0x5120
+#define	PERCENTUSED	98
+
+#define	SECTORSIZE	512
+
+/* Block Control Information */
+
+struct inftl_bci {
+	__u8 ECCsig[6];
+	__u8 Status;
+	__u8 Status1;
+} __attribute__((packed));
+
+struct inftl_unithead1 {
+	__u16 virtualUnitNo;
+	__u16 prevUnitNo;
+	__u8 ANAC;
+	__u8 NACs;
+	__u8 parityPerField;
+	__u8 discarded;
+} __attribute__((packed));
+
+struct inftl_unithead2 {
+	__u8 parityPerField;
+	__u8 ANAC;
+	__u16 prevUnitNo;
+	__u16 virtualUnitNo;
+	__u8 NACs;
+	__u8 discarded;
+} __attribute__((packed));
+
+struct inftl_unittail {
+	__u8 Reserved[4];
+	__u16 EraseMark;
+	__u16 EraseMark1;
+} __attribute__((packed));
+
+union inftl_uci {
+	struct inftl_unithead1 a;
+	struct inftl_unithead2 b;
+	struct inftl_unittail c;
+};
+
+struct inftl_oob {
+	struct inftl_bci b;
+	union inftl_uci u;
+};
+
+
+/* INFTL Media Header */
+
+struct INFTLPartition {
+	__u32 virtualUnits;
+	__u32 firstUnit;
+	__u32 lastUnit;
+	__u32 flags;
+	__u32 spareUnits;
+	__u32 Reserved0;
+	__u32 Reserved1;
+} __attribute__((packed));
+
+struct INFTLMediaHeader {
+	char bootRecordID[8];
+	__u32 NoOfBootImageBlocks;
+	__u32 NoOfBinaryPartitions;
+	__u32 NoOfBDTLPartitions;
+	__u32 BlockMultiplierBits;
+	__u32 FormatFlags;
+	__u32 OsakVersion;
+	__u32 PercentUsed;
+	struct INFTLPartition Partitions[4];
+} __attribute__((packed));
+
+/* Partition flag types */
+#define	INFTL_BINARY	0x20000000
+#define	INFTL_BDTL	0x40000000
+#define	INFTL_LAST	0x80000000
+
+
+#ifdef __KERNEL__
+
+struct INFTLrecord {
+	struct mtd_info *mtd;
+	struct semaphore mutex;
+	__u16 MediaUnit, SpareMediaUnit;
+	__u32 EraseSize;
+	struct INFTLMediaHeader MediaHdr;
+	int usecount;
+	unsigned char heads;
+	unsigned char sectors;
+	unsigned short cylinders;
+	__u16 numvunits;
+	__u16 firstEUN;
+	__u16 lastEUN;
+	__u16 numfreeEUNs;
+	__u16 LastFreeEUN; 		/* To speed up finding a free EUN */
+	__u32 long nr_sects;
+	int head,sect,cyl;
+	__u16 *PUtable;	 		/* Physical Unit Table  */
+	__u16 *VUtable; 		/* Virtual Unit Table */
+        unsigned int nb_blocks;		/* number of physical blocks */
+        unsigned int nb_boot_blocks;	/* number of blocks used by the bios */
+        struct erase_info instr;
+};
+
+#ifndef INFTL_MAJOR
+#define INFTL_MAJOR 94
+#endif
+
+#define MAX_INFTLS 16
+#define INFTL_PARTN_BITS 4
+
+int INFTL_mount(struct INFTLrecord *s);
+int INFTL_formatblock(struct INFTLrecord *s, int block);
+
+#endif /* __KERNEL__ */
+
+#endif /* __MTD_INFTL_H__ */
diff -urN linux-2.4.29/include/linux/mtd/mtd.h linux-2.4.29-uc1/include/linux/mtd/mtd.h
--- linux-2.4.29/include/linux/mtd/mtd.h	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/mtd/mtd.h	2005-06-14 02:11:35.000000000 +0100
@@ -93,8 +93,21 @@
 #define MEMUNLOCK               _IOW('M', 6, struct erase_info_user)
 #define MEMGETREGIONCOUNT	_IOR('M', 7, int)
 #define MEMGETREGIONINFO	_IOWR('M', 8, struct region_info_user)
-#define	MEMREADDATA             _IOWR('M', 9, struct mtd_oob_buf)
-#define	MEMWRITEDATA            _IOWR('M', 10, struct mtd_oob_buf)
+
+/*
+ * some place holder definitions from 2.6
+ *
+#define MEMSETOOBSEL		_IOW('M', 9, struct nand_oobinfo)
+#define MEMGETOOBSEL		_IOR('M', 10, struct nand_oobinfo)
+#define MEMGETBADBLOCK		_IOW('M', 11, loff_t)
+#define MEMSETBADBLOCK		_IOW('M', 12, loff_t)
+ */
+
+/*
+ * until these are part of the linux kernel,  put them out of harms way
+ */
+#define	MEMREADDATA             _IOWR('M', 64, struct mtd_oob_buf)
+#define	MEMWRITEDATA            _IOWR('M', 65, struct mtd_oob_buf)
 
 #ifndef __KERNEL__
 
diff -urN linux-2.4.29/include/linux/mtd/nand_ids.h linux-2.4.29-uc1/include/linux/mtd/nand_ids.h
--- linux-2.4.29/include/linux/mtd/nand_ids.h	2000-12-11 22:57:58.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/mtd/nand_ids.h	2005-06-14 02:11:35.000000000 +0100
@@ -41,9 +41,10 @@
 	{"Samsung unknown 4Mb",   NAND_MFR_SAMSUNG, 0x6b, 22, 0, 2, 0x2000},
 	{"Samsung KM29U128T",     NAND_MFR_SAMSUNG, 0x73, 24, 0, 2, 0x4000},
 	{"Samsung KM29U256T",     NAND_MFR_SAMSUNG, 0x75, 25, 0, 2, 0x4000},
-	{"Samsung unknown 64Mb",  NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000},
+	{"Samsung KM29V512000",   NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000},
+	{"Samsung KM29V1024000",  NAND_MFR_SAMSUNG, 0x79, 27, 0, 3, 0x4000},
 	{"Samsung KM29W32000",    NAND_MFR_SAMSUNG, 0xe3, 22, 0, 2, 0x2000},
-	{"Samsung unknown 4Mb",   NAND_MFR_SAMSUNG, 0xe5, 22, 0, 2, 0x2000},
+	{"Samsung KM29N32000",    NAND_MFR_SAMSUNG, 0xe5, 22, 0, 2, 0x2000},
 	{"Samsung KM29U64000",    NAND_MFR_SAMSUNG, 0xe6, 23, 0, 2, 0x2000},
 	{"Samsung KM29W16000",    NAND_MFR_SAMSUNG, 0xea, 21, 1, 2, 0x1000},
 	{NULL,}
diff -urN linux-2.4.29/include/linux/mtd/nftl.h linux-2.4.29-uc1/include/linux/mtd/nftl.h
--- linux-2.4.29/include/linux/mtd/nftl.h	2003-06-13 15:51:38.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/mtd/nftl.h	2005-06-14 02:11:35.000000000 +0100
@@ -114,7 +114,7 @@
 #endif
 
 #define MAX_NFTLS 16
-#define MAX_SECTORS_PER_UNIT 32
+#define MAX_SECTORS_PER_UNIT 64
 #define NFTL_PARTN_BITS 4
 
 #endif /* __KERNEL__ */
diff -urN linux-2.4.29/include/linux/netdevice.h linux-2.4.29-uc1/include/linux/netdevice.h
--- linux-2.4.29/include/linux/netdevice.h	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/netdevice.h	2005-06-14 02:11:35.000000000 +0100
@@ -506,6 +506,11 @@
 extern struct net_device	*__dev_get_by_index(int ifindex);
 extern int		dev_restart(struct net_device *dev);
 
+extern struct net_device	*dev_get_by_flags(unsigned short flags,
+						  unsigned short mask);
+extern struct net_device	*__dev_get_by_flags(unsigned short flags,
+						    unsigned short mask);
+
 typedef int gifconf_func_t(struct net_device * dev, char * bufptr, int len);
 extern int		register_gifconf(unsigned int family, gifconf_func_t * gifconf);
 static inline int unregister_gifconf(unsigned int family)
diff -urN linux-2.4.29/include/linux/netfilter_bridge/ebtables.h linux-2.4.29-uc1/include/linux/netfilter_bridge/ebtables.h
--- linux-2.4.29/include/linux/netfilter_bridge/ebtables.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_bridge/ebtables.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,361 @@
+/*
+ *  ebtables
+ *
+ *	Authors:
+ *	Bart De Schuymer		<bart.de.schuymer@pandora.be>
+ *
+ *  ebtables.c,v 2.0, September, 2002
+ *
+ *  This code is stongly inspired on the iptables code which is
+ *  Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
+ */
+
+#ifndef __LINUX_BRIDGE_EFF_H
+#define __LINUX_BRIDGE_EFF_H
+#include <linux/if.h>
+#include <linux/netfilter_bridge.h>
+#include <linux/if_ether.h>
+
+#define EBT_TABLE_MAXNAMELEN 32
+#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN
+#define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN
+
+// verdicts >0 are "branches"
+#define EBT_ACCEPT   -1
+#define EBT_DROP     -2
+#define EBT_CONTINUE -3
+#define EBT_RETURN   -4
+#define NUM_STANDARD_TARGETS   4
+
+struct ebt_counter
+{
+	uint64_t pcnt;
+	uint64_t bcnt;
+};
+
+struct ebt_entries {
+	// this field is always set to zero
+	// See EBT_ENTRY_OR_ENTRIES.
+	// Must be same size as ebt_entry.bitmask
+	unsigned int distinguisher;
+	// the chain name
+	char name[EBT_CHAIN_MAXNAMELEN];
+	// counter offset for this chain
+	unsigned int counter_offset;
+	// one standard (accept, drop, return) per hook
+	int policy;
+	// nr. of entries
+	unsigned int nentries;
+	// entry list
+	char data[0];
+};
+
+// used for the bitmask of struct ebt_entry
+
+// This is a hack to make a difference between an ebt_entry struct and an
+// ebt_entries struct when traversing the entries from start to end.
+// Using this simplifies the code alot, while still being able to use
+// ebt_entries.
+// Contrary, iptables doesn't use something like ebt_entries and therefore uses
+// different techniques for naming the policy and such. So, iptables doesn't
+// need a hack like this.
+#define EBT_ENTRY_OR_ENTRIES 0x01
+// these are the normal masks
+#define EBT_NOPROTO 0x02
+#define EBT_802_3 0x04
+#define EBT_SOURCEMAC 0x08
+#define EBT_DESTMAC 0x10
+#define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \
+   | EBT_ENTRY_OR_ENTRIES)
+
+#define EBT_IPROTO 0x01
+#define EBT_IIN 0x02
+#define EBT_IOUT 0x04
+#define EBT_ISOURCE 0x8
+#define EBT_IDEST 0x10
+#define EBT_ILOGICALIN 0x20
+#define EBT_ILOGICALOUT 0x40
+#define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \
+   | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST)
+
+struct ebt_entry_match
+{
+	union {
+		char name[EBT_FUNCTION_MAXNAMELEN];
+		struct ebt_match *match;
+	} u;
+	// size of data
+	unsigned int match_size;
+	unsigned char data[0];
+};
+
+struct ebt_entry_watcher
+{
+	union {
+		char name[EBT_FUNCTION_MAXNAMELEN];
+		struct ebt_watcher *watcher;
+	} u;
+	// size of data
+	unsigned int watcher_size;
+	unsigned char data[0];
+};
+
+struct ebt_entry_target
+{
+	union {
+		char name[EBT_FUNCTION_MAXNAMELEN];
+		struct ebt_target *target;
+	} u;
+	// size of data
+	unsigned int target_size;
+	unsigned char data[0];
+};
+
+#define EBT_STANDARD_TARGET "standard"
+struct ebt_standard_target
+{
+	struct ebt_entry_target target;
+	int verdict;
+};
+
+// one entry
+struct ebt_entry {
+	// this needs to be the first field
+	unsigned int bitmask;
+	unsigned int invflags;
+	uint16_t ethproto;
+	// the physical in-dev
+	char in[IFNAMSIZ];
+	// the logical in-dev
+	char logical_in[IFNAMSIZ];
+	// the physical out-dev
+	char out[IFNAMSIZ];
+	// the logical out-dev
+	char logical_out[IFNAMSIZ];
+	unsigned char sourcemac[ETH_ALEN];
+	unsigned char sourcemsk[ETH_ALEN];
+	unsigned char destmac[ETH_ALEN];
+	unsigned char destmsk[ETH_ALEN];
+	// sizeof ebt_entry + matches
+	unsigned int watchers_offset;
+	// sizeof ebt_entry + matches + watchers
+	unsigned int target_offset;
+	// sizeof ebt_entry + matches + watchers + target
+	unsigned int next_offset;
+	unsigned char elems[0];
+};
+
+struct ebt_replace
+{
+	char name[EBT_TABLE_MAXNAMELEN];
+	unsigned int valid_hooks;
+	// nr of rules in the table
+	unsigned int nentries;
+	// total size of the entries
+	unsigned int entries_size;
+	// start of the chains
+	struct ebt_entries *hook_entry[NF_BR_NUMHOOKS];
+	// nr of counters userspace expects back
+	unsigned int num_counters;
+	// where the kernel will put the old counters
+	struct ebt_counter *counters;
+	char *entries;
+};
+
+// [gs]etsockopt numbers
+#define EBT_BASE_CTL            128
+
+#define EBT_SO_SET_ENTRIES      (EBT_BASE_CTL)
+#define EBT_SO_SET_COUNTERS     (EBT_SO_SET_ENTRIES+1)
+#define EBT_SO_SET_MAX          (EBT_SO_SET_COUNTERS+1)
+
+#define EBT_SO_GET_INFO         (EBT_BASE_CTL)
+#define EBT_SO_GET_ENTRIES      (EBT_SO_GET_INFO+1)
+#define EBT_SO_GET_INIT_INFO    (EBT_SO_GET_ENTRIES+1)
+#define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1)
+#define EBT_SO_GET_MAX          (EBT_SO_GET_INIT_ENTRIES+1)
+
+#ifdef __KERNEL__
+
+// return values for match() functions
+#define EBT_MATCH 0
+#define EBT_NOMATCH 1
+
+struct ebt_match
+{
+	struct list_head list;
+	const char name[EBT_FUNCTION_MAXNAMELEN];
+	// 0 == it matches
+	int (*match)(const struct sk_buff *skb, const struct net_device *in,
+	   const struct net_device *out, const void *matchdata,
+	   unsigned int datalen);
+	// 0 == let it in
+	int (*check)(const char *tablename, unsigned int hookmask,
+	   const struct ebt_entry *e, void *matchdata, unsigned int datalen);
+	void (*destroy)(void *matchdata, unsigned int datalen);
+	struct module *me;
+};
+
+struct ebt_watcher
+{
+	struct list_head list;
+	const char name[EBT_FUNCTION_MAXNAMELEN];
+	void (*watcher)(const struct sk_buff *skb, const struct net_device *in,
+	   const struct net_device *out, const void *watcherdata,
+	   unsigned int datalen);
+	// 0 == let it in
+	int (*check)(const char *tablename, unsigned int hookmask,
+	   const struct ebt_entry *e, void *watcherdata, unsigned int datalen);
+	void (*destroy)(void *watcherdata, unsigned int datalen);
+	struct module *me;
+};
+
+struct ebt_target
+{
+	struct list_head list;
+	const char name[EBT_FUNCTION_MAXNAMELEN];
+	// returns one of the standard verdicts
+	int (*target)(struct sk_buff **pskb, unsigned int hooknr,
+	   const struct net_device *in, const struct net_device *out,
+	   const void *targetdata, unsigned int datalen);
+	// 0 == let it in
+	int (*check)(const char *tablename, unsigned int hookmask,
+	   const struct ebt_entry *e, void *targetdata, unsigned int datalen);
+	void (*destroy)(void *targetdata, unsigned int datalen);
+	struct module *me;
+};
+
+// used for jumping from and into user defined chains (udc)
+struct ebt_chainstack
+{
+	struct ebt_entries *chaininfo; // pointer to chain data
+	struct ebt_entry *e; // pointer to entry data
+	unsigned int n; // n'th entry
+};
+
+struct ebt_table_info
+{
+	// total size of the entries
+	unsigned int entries_size;
+	unsigned int nentries;
+	// pointers to the start of the chains
+	struct ebt_entries *hook_entry[NF_BR_NUMHOOKS];
+	// room to maintain the stack used for jumping from and into udc
+	struct ebt_chainstack **chainstack;
+	char *entries;
+	struct ebt_counter counters[0] ____cacheline_aligned;
+};
+
+struct ebt_table
+{
+	struct list_head list;
+	char name[EBT_TABLE_MAXNAMELEN];
+	struct ebt_replace *table;
+	unsigned int valid_hooks;
+	rwlock_t lock;
+	// e.g. could be the table explicitly only allows certain
+	// matches, targets, ... 0 == let it in
+	int (*check)(const struct ebt_table_info *info,
+	   unsigned int valid_hooks);
+	// the data used by the kernel
+	struct ebt_table_info *private;
+};
+
+#define EBT_ALIGN(s) (((s) + (__alignof__(struct ebt_entry_target)-1)) & \
+		     ~(__alignof__(struct ebt_entry_target)-1))
+extern int ebt_register_table(struct ebt_table *table);
+extern void ebt_unregister_table(struct ebt_table *table);
+extern int ebt_register_match(struct ebt_match *match);
+extern void ebt_unregister_match(struct ebt_match *match);
+extern int ebt_register_watcher(struct ebt_watcher *watcher);
+extern void ebt_unregister_watcher(struct ebt_watcher *watcher);
+extern int ebt_register_target(struct ebt_target *target);
+extern void ebt_unregister_target(struct ebt_target *target);
+extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff **pskb,
+   const struct net_device *in, const struct net_device *out,
+   struct ebt_table *table);
+
+   // Used in the kernel match() functions
+#define FWINV(bool,invflg) ((bool) ^ !!(info->invflags & invflg))
+// True if the hook mask denotes that the rule is in a base chain,
+// used in the check() functions
+#define BASE_CHAIN (hookmask & (1 << NF_BR_NUMHOOKS))
+// Clear the bit in the hook mask that tells if the rule is on a base chain
+#define CLEAR_BASE_CHAIN_BIT (hookmask &= ~(1 << NF_BR_NUMHOOKS))
+// True if the target is not a standard target
+#define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0)
+
+#endif /* __KERNEL__ */
+
+// blatently stolen from ip_tables.h
+// fn returns 0 to continue iteration
+#define EBT_MATCH_ITERATE(e, fn, args...)                   \
+({                                                          \
+	unsigned int __i;                                   \
+	int __ret = 0;                                      \
+	struct ebt_entry_match *__match;                    \
+	                                                    \
+	for (__i = sizeof(struct ebt_entry);                \
+	     __i < (e)->watchers_offset;                    \
+	     __i += __match->match_size +                   \
+	     sizeof(struct ebt_entry_match)) {              \
+		__match = (void *)(e) + __i;                \
+		                                            \
+		__ret = fn(__match , ## args);              \
+		if (__ret != 0)                             \
+			break;                              \
+	}                                                   \
+	if (__ret == 0) {                                   \
+		if (__i != (e)->watchers_offset)            \
+			__ret = -EINVAL;                    \
+	}                                                   \
+	__ret;                                              \
+})
+
+#define EBT_WATCHER_ITERATE(e, fn, args...)                 \
+({                                                          \
+	unsigned int __i;                                   \
+	int __ret = 0;                                      \
+	struct ebt_entry_watcher *__watcher;                \
+	                                                    \
+	for (__i = e->watchers_offset;                      \
+	     __i < (e)->target_offset;                      \
+	     __i += __watcher->watcher_size +               \
+	     sizeof(struct ebt_entry_watcher)) {            \
+		__watcher = (void *)(e) + __i;              \
+		                                            \
+		__ret = fn(__watcher , ## args);            \
+		if (__ret != 0)                             \
+			break;                              \
+	}                                                   \
+	if (__ret == 0) {                                   \
+		if (__i != (e)->target_offset)              \
+			__ret = -EINVAL;                    \
+	}                                                   \
+	__ret;                                              \
+})
+
+#define EBT_ENTRY_ITERATE(entries, size, fn, args...)       \
+({                                                          \
+	unsigned int __i;                                   \
+	int __ret = 0;                                      \
+	struct ebt_entry *__entry;                          \
+	                                                    \
+	for (__i = 0; __i < (size);) {                      \
+		__entry = (void *)(entries) + __i;          \
+		__ret = fn(__entry , ## args);              \
+		if (__ret != 0)                             \
+			break;                              \
+		if (__entry->bitmask != 0)                  \
+			__i += __entry->next_offset;        \
+		else                                        \
+			__i += sizeof(struct ebt_entries);  \
+	}                                                   \
+	if (__ret == 0) {                                   \
+		if (__i != (size))                          \
+			__ret = -EINVAL;                    \
+	}                                                   \
+	__ret;                                              \
+})
+
+#endif
diff -urN linux-2.4.29/include/linux/netfilter_bridge/ebt_arp.h linux-2.4.29-uc1/include/linux/netfilter_bridge/ebt_arp.h
--- linux-2.4.29/include/linux/netfilter_bridge/ebt_arp.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_bridge/ebt_arp.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,32 @@
+#ifndef __LINUX_BRIDGE_EBT_ARP_H
+#define __LINUX_BRIDGE_EBT_ARP_H
+
+#define EBT_ARP_OPCODE 0x01
+#define EBT_ARP_HTYPE 0x02
+#define EBT_ARP_PTYPE 0x04
+#define EBT_ARP_SRC_IP 0x08
+#define EBT_ARP_DST_IP 0x10
+#define EBT_ARP_SRC_MAC 0x20
+#define EBT_ARP_DST_MAC 0x40
+#define EBT_ARP_MASK (EBT_ARP_OPCODE | EBT_ARP_HTYPE | EBT_ARP_PTYPE | \
+   EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)
+#define EBT_ARP_MATCH "arp"
+
+struct ebt_arp_info
+{
+	uint16_t htype;
+	uint16_t ptype;
+	uint16_t opcode;
+	uint32_t saddr;
+	uint32_t smsk;
+	uint32_t daddr;
+	uint32_t dmsk;
+	unsigned char smaddr[ETH_ALEN];
+	unsigned char smmsk[ETH_ALEN];
+	unsigned char dmaddr[ETH_ALEN];
+	unsigned char dmmsk[ETH_ALEN];
+	uint8_t  bitmask;
+	uint8_t  invflags;
+};
+
+#endif
diff -urN linux-2.4.29/include/linux/netfilter_bridge/ebt_ip.h linux-2.4.29-uc1/include/linux/netfilter_bridge/ebt_ip.h
--- linux-2.4.29/include/linux/netfilter_bridge/ebt_ip.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_bridge/ebt_ip.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,43 @@
+/*
+ *  ebt_ip
+ *
+ *	Authors:
+ *	Bart De Schuymer <bart.de.schuymer@pandora.be>
+ *
+ *  April, 2002
+ *
+ *  Changes:
+ *    added ip-sport and ip-dport
+ *    Innominate Security Technologies AG <mhopf@innominate.com>
+ *    September, 2002
+ */
+
+#ifndef __LINUX_BRIDGE_EBT_IP_H
+#define __LINUX_BRIDGE_EBT_IP_H
+
+#define EBT_IP_SOURCE 0x01
+#define EBT_IP_DEST 0x02
+#define EBT_IP_TOS 0x04
+#define EBT_IP_PROTO 0x08
+#define EBT_IP_SPORT 0x10
+#define EBT_IP_DPORT 0x20
+#define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\
+ EBT_IP_SPORT | EBT_IP_DPORT )
+#define EBT_IP_MATCH "ip"
+
+// the same values are used for the invflags
+struct ebt_ip_info
+{
+	uint32_t saddr;
+	uint32_t daddr;
+	uint32_t smsk;
+	uint32_t dmsk;
+	uint8_t  tos;
+	uint8_t  protocol;
+	uint8_t  bitmask;
+	uint8_t  invflags;
+	uint16_t sport[2];
+	uint16_t dport[2];
+};
+
+#endif
diff -urN linux-2.4.29/include/linux/netfilter_bridge/ebt_log.h linux-2.4.29-uc1/include/linux/netfilter_bridge/ebt_log.h
--- linux-2.4.29/include/linux/netfilter_bridge/ebt_log.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_bridge/ebt_log.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,17 @@
+#ifndef __LINUX_BRIDGE_EBT_LOG_H
+#define __LINUX_BRIDGE_EBT_LOG_H
+
+#define EBT_LOG_IP 0x01 // if the frame is made by ip, log the ip information
+#define EBT_LOG_ARP 0x02
+#define EBT_LOG_MASK (EBT_LOG_IP | EBT_LOG_ARP)
+#define EBT_LOG_PREFIX_SIZE 30
+#define EBT_LOG_WATCHER "log"
+
+struct ebt_log_info
+{
+	uint8_t loglevel;
+	uint8_t prefix[EBT_LOG_PREFIX_SIZE];
+	uint32_t bitmask;
+};
+
+#endif
diff -urN linux-2.4.29/include/linux/netfilter_bridge/ebt_mark_m.h linux-2.4.29-uc1/include/linux/netfilter_bridge/ebt_mark_m.h
--- linux-2.4.29/include/linux/netfilter_bridge/ebt_mark_m.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_bridge/ebt_mark_m.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,15 @@
+#ifndef __LINUX_BRIDGE_EBT_MARK_M_H
+#define __LINUX_BRIDGE_EBT_MARK_M_H
+
+#define EBT_MARK_AND 0x01
+#define EBT_MARK_OR 0x02
+#define EBT_MARK_MASK (EBT_MARK_AND | EBT_MARK_OR)
+struct ebt_mark_m_info
+{
+	unsigned long mark, mask;
+	uint8_t invert;
+	uint8_t bitmask;
+};
+#define EBT_MARK_MATCH "mark_m"
+
+#endif
diff -urN linux-2.4.29/include/linux/netfilter_bridge/ebt_mark_t.h linux-2.4.29-uc1/include/linux/netfilter_bridge/ebt_mark_t.h
--- linux-2.4.29/include/linux/netfilter_bridge/ebt_mark_t.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_bridge/ebt_mark_t.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef __LINUX_BRIDGE_EBT_MARK_T_H
+#define __LINUX_BRIDGE_EBT_MARK_T_H
+
+struct ebt_mark_t_info
+{
+	unsigned long mark;
+	// EBT_ACCEPT, EBT_DROP or EBT_CONTINUE or EBT_RETURN
+	int target;
+};
+#define EBT_MARK_TARGET "mark"
+
+#endif
diff -urN linux-2.4.29/include/linux/netfilter_bridge/ebt_nat.h linux-2.4.29-uc1/include/linux/netfilter_bridge/ebt_nat.h
--- linux-2.4.29/include/linux/netfilter_bridge/ebt_nat.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_bridge/ebt_nat.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef __LINUX_BRIDGE_EBT_NAT_H
+#define __LINUX_BRIDGE_EBT_NAT_H
+
+struct ebt_nat_info
+{
+	unsigned char mac[ETH_ALEN];
+	// EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN
+	int target;
+};
+#define EBT_SNAT_TARGET "snat"
+#define EBT_DNAT_TARGET "dnat"
+
+#endif
diff -urN linux-2.4.29/include/linux/netfilter_bridge/ebt_redirect.h linux-2.4.29-uc1/include/linux/netfilter_bridge/ebt_redirect.h
--- linux-2.4.29/include/linux/netfilter_bridge/ebt_redirect.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_bridge/ebt_redirect.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,11 @@
+#ifndef __LINUX_BRIDGE_EBT_REDIRECT_H
+#define __LINUX_BRIDGE_EBT_REDIRECT_H
+
+struct ebt_redirect_info
+{
+	// EBT_ACCEPT, EBT_DROP or EBT_CONTINUE or EBT_RETURN
+	int target;
+};
+#define EBT_REDIRECT_TARGET "redirect"
+
+#endif
diff -urN linux-2.4.29/include/linux/netfilter_bridge/ebt_vlan.h linux-2.4.29-uc1/include/linux/netfilter_bridge/ebt_vlan.h
--- linux-2.4.29/include/linux/netfilter_bridge/ebt_vlan.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_bridge/ebt_vlan.h	2005-06-14 02:11:33.000000000 +0100
@@ -0,0 +1,20 @@
+#ifndef __LINUX_BRIDGE_EBT_VLAN_H
+#define __LINUX_BRIDGE_EBT_VLAN_H
+
+#define EBT_VLAN_ID	0x01
+#define EBT_VLAN_PRIO	0x02
+#define EBT_VLAN_ENCAP	0x04
+#define EBT_VLAN_MASK (EBT_VLAN_ID | EBT_VLAN_PRIO | EBT_VLAN_ENCAP)
+#define EBT_VLAN_MATCH "vlan"
+
+struct ebt_vlan_info {
+	uint16_t id;		/* VLAN ID {1-4095} */
+	uint8_t prio;		/* VLAN User Priority {0-7} */
+	uint16_t encap;		/* VLAN Encapsulated frame code {0-65535} */
+	uint8_t bitmask;		/* Args bitmask bit 1=1 - ID arg,
+				   bit 2=1 User-Priority arg, bit 3=1 encap*/
+	uint8_t invflags;		/* Inverse bitmask  bit 1=1 - inversed ID arg, 
+				   bit 2=1 - inversed Pirority arg */
+};
+
+#endif
diff -urN linux-2.4.29/include/linux/netfilter_bridge.h linux-2.4.29-uc1/include/linux/netfilter_bridge.h
--- linux-2.4.29/include/linux/netfilter_bridge.h	2001-06-12 03:15:27.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_bridge.h	2005-06-14 02:11:35.000000000 +0100
@@ -6,6 +6,12 @@
 
 #include <linux/config.h>
 #include <linux/netfilter.h>
+#if defined(__KERNEL__) && defined(CONFIG_NETFILTER)
+#include <asm/atomic.h>
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#include <linux/if_ether.h>
+#endif
+#endif
 
 /* Bridge Hooks */
 /* After promisc drops, checksum checks. */
@@ -18,7 +24,80 @@
 #define NF_BR_LOCAL_OUT		3
 /* Packets about to hit the wire. */
 #define NF_BR_POST_ROUTING	4
-#define NF_BR_NUMHOOKS		5
+/* Not really a hook, but used for the ebtables broute table */
+#define NF_BR_BROUTING		5
+#define NF_BR_NUMHOOKS		6
+
+#ifdef __KERNEL__
+
+#define BRNF_PKT_TYPE			0x01
+#define BRNF_BRIDGED_DNAT		0x02
+#define BRNF_DONT_TAKE_PARENT		0x04
+#define BRNF_BRIDGED			0x08
+#define BRNF_NF_BRIDGE_PREROUTING	0x10
+
+enum nf_br_hook_priorities {
+	NF_BR_PRI_FIRST = INT_MIN,
+	NF_BR_PRI_NAT_DST_BRIDGED = -300,
+	NF_BR_PRI_FILTER_BRIDGED = -200,
+	NF_BR_PRI_BRNF = 0,
+	NF_BR_PRI_NAT_DST_OTHER = 100,
+	NF_BR_PRI_FILTER_OTHER = 200,
+	NF_BR_PRI_NAT_SRC = 300,
+	NF_BR_PRI_LAST = INT_MAX,
+};
+
+#ifdef CONFIG_NETFILTER
+static inline
+struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
+{
+	struct nf_bridge_info **nf_bridge = &(skb->nf_bridge);
+
+	if ((*nf_bridge = kmalloc(sizeof(**nf_bridge), GFP_ATOMIC)) != NULL) {
+		atomic_set(&(*nf_bridge)->use, 1);
+		(*nf_bridge)->mask = 0;
+		(*nf_bridge)->physindev = (*nf_bridge)->physoutdev = NULL;
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+		(*nf_bridge)->netoutdev = NULL;
+#endif
+	}
+
+	return *nf_bridge;
+}
+
+/* Only used in br_forward.c */
+static inline
+void nf_bridge_maybe_copy_header(struct sk_buff *skb)
+{
+	if (skb->nf_bridge) {
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+		if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+			memcpy(skb->data - 18, skb->nf_bridge->hh, 18);
+			skb_push(skb, 4);
+		} else
+#endif
+			memcpy(skb->data - 16, skb->nf_bridge->hh, 16);
+	}
+}
+
+static inline
+void nf_bridge_save_header(struct sk_buff *skb)
+{
+        int header_size = 16;
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+	if (skb->protocol == __constant_htons(ETH_P_8021Q))
+		header_size = 18;
+#endif
+	memcpy(skb->nf_bridge->hh, skb->data - header_size, header_size);
+}
 
+struct bridge_skb_cb {
+	union {
+		__u32 ipv4;
+	} daddr;
+};
+#endif /* CONFIG_NETFILTER */
 
+#endif /* __KERNEL__ */
 #endif
diff -urN linux-2.4.29/include/linux/netfilter.h linux-2.4.29-uc1/include/linux/netfilter.h
--- linux-2.4.29/include/linux/netfilter.h	2005-01-19 14:10:12.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/netfilter.h	2005-06-14 02:11:36.000000000 +0100
@@ -20,7 +20,7 @@
 #define NF_MAX_VERDICT NF_REPEAT
 
 /* Generic cache responses from hook functions.
-   <= 0x2000 is used for protocol-flags. */
+   <= 0x2000 is reserved for conntrack event cache. */
 #define NFC_UNKNOWN 0x4000
 #define NFC_ALTERED 0x8000
 
@@ -118,17 +118,23 @@
 /* This is gross, but inline doesn't cut it for avoiding the function
    call in fast path: gcc doesn't inline (needs value tracking?). --RR */
 #ifdef CONFIG_NETFILTER_DEBUG
-#define NF_HOOK nf_hook_slow
+#define NF_HOOK(pf, hook, skb, indev, outdev, okfn)			\
+nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn), INT_MIN)
+#define NF_HOOK_THRESH nf_hook_slow
 #else
 #define NF_HOOK(pf, hook, skb, indev, outdev, okfn)			\
 (list_empty(&nf_hooks[(pf)][(hook)])					\
  ? (okfn)(skb)								\
- : nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn)))
+ : nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn), INT_MIN))
+#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh)	\
+(list_empty(&nf_hooks[(pf)][(hook)])					\
+ ? (okfn)(skb)								\
+ : nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn), (thresh)))
 #endif
 
 int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
 		 struct net_device *indev, struct net_device *outdev,
-		 int (*okfn)(struct sk_buff *));
+		 int (*okfn)(struct sk_buff *), int thresh);
 
 /* Call setsockopt() */
 int nf_setsockopt(struct sock *sk, int pf, int optval, char *opt, 
diff -urN linux-2.4.29/include/linux/netfilter_ipv4/ip_conntrack_core.h linux-2.4.29-uc1/include/linux/netfilter_ipv4/ip_conntrack_core.h
--- linux-2.4.29/include/linux/netfilter_ipv4/ip_conntrack_core.h	2005-01-19 14:10:12.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/netfilter_ipv4/ip_conntrack_core.h	2005-06-14 02:11:34.000000000 +0100
@@ -34,15 +34,19 @@
 ip_conntrack_find_get(const struct ip_conntrack_tuple *tuple,
 		      const struct ip_conntrack *ignored_conntrack);
 
-extern int __ip_conntrack_confirm(struct nf_ct_info *nfct);
+extern int __ip_conntrack_confirm(struct sk_buff *skb);
 
 /* Confirm a connection: returns NF_DROP if packet must be dropped. */
 static inline int ip_conntrack_confirm(struct sk_buff *skb)
 {
+	int ret = NF_ACCEPT;
+
 	if (skb->nfct
 	    && !is_confirmed((struct ip_conntrack *)skb->nfct->master))
-		return __ip_conntrack_confirm(skb->nfct);
-	return NF_ACCEPT;
+		ret = __ip_conntrack_confirm(skb);
+	ip_conntrack_deliver_cached_events(skb);
+
+	return ret;
 }
 
 extern struct list_head *ip_conntrack_hash;
diff -urN linux-2.4.29/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.4.29-uc1/include/linux/netfilter_ipv4/ip_conntrack.h
--- linux-2.4.29/include/linux/netfilter_ipv4/ip_conntrack.h	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/netfilter_ipv4/ip_conntrack.h	2005-06-14 02:11:34.000000000 +0100
@@ -46,23 +46,53 @@
 	/* Connection is confirmed: originating packet has left box */
 	IPS_CONFIRMED_BIT = 3,
 	IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
+
+	/* Connection is destroyed (removed from lists), can not be unset. */
+	IPS_DESTROYED_BIT = 9,
+	IPS_DESTROYED = (1 << IPS_DESTROYED_BIT),
+
+	/* Connection should be logged. */
+	IPS_LOG_BIT = 10,
+	IPS_LOG = (1 << IPS_LOG_BIT),
+};
+
+/* Connection tracking event bits */
+enum ip_conntrack_events
+{
+	/* New conntrack */
+	IPCT_NEW_BIT = 0,
+	IPCT_NEW = (1 << IPCT_NEW_BIT),
+
+	/* Expected connection */
+	IPCT_RELATED_BIT = 1,
+	IPCT_RELATED = (1 << IPCT_RELATED_BIT),
+
+	/* Destroyed conntrack */
+	IPCT_DESTROY_BIT = 2,
+	IPCT_DESTROY = (1 << IPCT_DESTROY_BIT),
 };
 
 #include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
 #include <linux/netfilter_ipv4/ip_conntrack_icmp.h>
+#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
 
 /* per conntrack: protocol private data */
 union ip_conntrack_proto {
 	/* insert conntrack proto private data here */
+	struct ip_ct_gre gre;
 	struct ip_ct_tcp tcp;
 	struct ip_ct_icmp icmp;
 };
 
 union ip_conntrack_expect_proto {
 	/* insert expect proto private data here */
+	struct ip_ct_gre_expect gre;
 };
 
 /* Add protocol helper include file here */
+#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
+
+#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
 #include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
 
 #include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
@@ -71,6 +101,8 @@
 /* per expectation: application helper private data */
 union ip_conntrack_expect_help {
 	/* insert conntrack helper private data (expect) here */
+	struct ip_ct_h225_expect exp_h225_info;
+	struct ip_ct_pptp_expect exp_pptp_info;
 	struct ip_ct_amanda_expect exp_amanda_info;
 	struct ip_ct_ftp_expect exp_ftp_info;
 	struct ip_ct_irc_expect exp_irc_info;
@@ -85,16 +117,20 @@
 /* per conntrack: application helper private data */
 union ip_conntrack_help {
 	/* insert conntrack helper private data (master) here */
+	struct ip_ct_h225_master ct_h225_info;
+	struct ip_ct_pptp_master ct_pptp_info;
 	struct ip_ct_ftp_master ct_ftp_info;
 	struct ip_ct_irc_master ct_irc_info;
 };
 
 #ifdef CONFIG_IP_NF_NAT_NEEDED
 #include <linux/netfilter_ipv4/ip_nat.h>
+#include <linux/netfilter_ipv4/ip_nat_pptp.h>
 
 /* per conntrack: nat application helper private data */
 union ip_conntrack_nat_help {
 	/* insert nat helper private data here */
+	struct ip_nat_pptp nat_pptp_info;
 };
 #endif
 
@@ -156,6 +192,12 @@
 	union ip_conntrack_expect_help help;
 };
 
+struct ip_conntrack_counter
+{
+	u_int64_t packets;
+	u_int64_t bytes;
+};
+
 struct ip_conntrack_helper;
 
 struct ip_conntrack
@@ -173,6 +215,11 @@
 	/* Timer function; drops refcnt when it goes off. */
 	struct timer_list timeout;
 
+#ifdef CONFIG_IP_NF_CT_ACCT
+	/* Accounting Information (same cache line as other written members) */
+	struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
+#endif
+
 	/* If we're expecting another related connection, this will be
            in expected linked list */
 	struct list_head sibling_list;
@@ -207,6 +254,9 @@
 	} nat;
 #endif /* CONFIG_IP_NF_NAT_NEEDED */
 
+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
+	unsigned long mark;
+#endif
 };
 
 /* get master conntrack via master expectation */
@@ -242,8 +292,10 @@
 			  const struct ip_conntrack_tuple *orig);
 
 /* Refresh conntrack for this many jiffies */
-extern void ip_ct_refresh(struct ip_conntrack *ct,
-			  unsigned long extra_jiffies);
+extern void ip_ct_refresh_acct(struct ip_conntrack *ct,
+			       enum ip_conntrack_info ctinfo,
+			       struct iphdr *iph,
+			       unsigned long extra_jiffies);
 
 /* These are for NAT.  Icky. */
 /* Call me when a conntrack is destroyed. */
@@ -265,6 +317,67 @@
 	return test_bit(IPS_CONFIRMED_BIT, &ct->status);
 }
 
+static inline int is_destroyed(struct ip_conntrack *ct)
+{
+	return test_bit(IPS_DESTROYED_BIT, &ct->status);
+}
+
 extern unsigned int ip_conntrack_htable_size;
+
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+#include <linux/notifier.h>
+ 
+extern struct notifier_block *ip_conntrack_chain;
+
+static inline int ip_conntrack_register_notifier(struct notifier_block *nb)
+{
+	return notifier_chain_register(&ip_conntrack_chain, nb);
+}
+
+static inline int ip_conntrack_unregister_notifier(struct notifier_block *nb)
+{
+	return notifier_chain_unregister(&ip_conntrack_chain, nb);
+}
+
+static inline void ip_conntrack_event_cache_init(struct sk_buff *skb)
+{
+	/* Set to zero first 14 bits, see netfilter.h */
+	skb->nfcache &= 0xc000;
+}
+
+static inline void 
+ip_conntrack_event_cache(enum ip_conntrack_events event, struct sk_buff *skb)
+{
+	skb->nfcache |= event;
+}
+
+static inline void 
+ip_conntrack_deliver_cached_events(struct sk_buff *skb)
+{
+	struct ip_conntrack *ct;
+
+	if (!skb->nfct)
+		return;
+
+	ct = (struct ip_conntrack *)skb->nfct->master;
+	if (is_confirmed(ct) && !is_destroyed(ct) && skb->nfcache)
+		notifier_call_chain(&ip_conntrack_chain, skb->nfcache, ct);
+}
+
+static inline void ip_conntrack_event(enum ip_conntrack_events event,
+				      struct ip_conntrack *ct)
+{
+	if (is_confirmed(ct) && !is_destroyed(ct))
+		notifier_call_chain(&ip_conntrack_chain, event, ct);
+}
+#else /* CONFIG_IP_NF_CONNTRACK_EVENTS */
+static inline void ip_conntrack_event_cache_init(struct sk_buff *skb) {}
+static inline void ip_conntrack_event_cache(enum ip_conntrack_events event, 
+					    struct sk_buff *skb) {}
+static inline void ip_conntrack_event(enum ip_conntrack_events event, 
+				      struct ip_conntrack *ct) {}
+static inline void ip_conntrack_deliver_cached_events(struct sk_buff *skb) {}
+#endif /* CONFIG_IP_NF_CONNTRACK_EVENTS */
+
 #endif /* __KERNEL__ */
 #endif /* _IP_CONNTRACK_H */
diff -urN linux-2.4.29/include/linux/netfilter_ipv4/ip_conntrack_h323.h linux-2.4.29-uc1/include/linux/netfilter_ipv4/ip_conntrack_h323.h
--- linux-2.4.29/include/linux/netfilter_ipv4/ip_conntrack_h323.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_ipv4/ip_conntrack_h323.h	2005-06-14 02:11:34.000000000 +0100
@@ -0,0 +1,30 @@
+#ifndef _IP_CONNTRACK_H323_H
+#define _IP_CONNTRACK_H323_H
+/* H.323 connection tracking. */
+
+#ifdef __KERNEL__
+/* Protects H.323 related data */
+DECLARE_LOCK_EXTERN(ip_h323_lock);
+#endif
+
+/* Default H.225 port */
+#define H225_PORT	1720
+
+/* This structure is per expected connection */
+struct ip_ct_h225_expect {
+	u_int16_t port;			/* Port of the H.225 helper/RTCP/RTP channel */
+	enum ip_conntrack_dir dir;	/* Direction of the original connection */
+	unsigned int offset;		/* offset of the address in the payload */
+};
+
+/* This structure exists only once per master */
+struct ip_ct_h225_master {
+	int is_h225;				/* H.225 or H.245 connection */
+#ifdef CONFIG_IP_NF_NAT_NEEDED
+	enum ip_conntrack_dir dir;		/* Direction of the original connection */
+	u_int32_t seq[IP_CT_DIR_MAX];		/* Exceptional packet mangling for signal addressess... */
+	unsigned int offset[IP_CT_DIR_MAX];	/* ...and the offset of the addresses in the payload */
+#endif
+};
+
+#endif /* _IP_CONNTRACK_H323_H */
diff -urN linux-2.4.29/include/linux/netfilter_ipv4/ip_conntrack_pptp.h linux-2.4.29-uc1/include/linux/netfilter_ipv4/ip_conntrack_pptp.h
--- linux-2.4.29/include/linux/netfilter_ipv4/ip_conntrack_pptp.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_ipv4/ip_conntrack_pptp.h	2005-06-14 02:11:34.000000000 +0100
@@ -0,0 +1,313 @@
+/* PPTP constants and structs */
+#ifndef _CONNTRACK_PPTP_H
+#define _CONNTRACK_PPTP_H
+
+/* state of the control session */
+enum pptp_ctrlsess_state {
+	PPTP_SESSION_NONE,			/* no session present */
+	PPTP_SESSION_ERROR,			/* some session error */
+	PPTP_SESSION_STOPREQ,			/* stop_sess request seen */
+	PPTP_SESSION_REQUESTED,			/* start_sess request seen */
+	PPTP_SESSION_CONFIRMED,			/* session established */
+};
+
+/* state of the call inside the control session */
+enum pptp_ctrlcall_state {
+	PPTP_CALL_NONE,
+	PPTP_CALL_ERROR,
+	PPTP_CALL_OUT_REQ,
+	PPTP_CALL_OUT_CONF,
+	PPTP_CALL_IN_REQ,
+	PPTP_CALL_IN_REP,
+	PPTP_CALL_IN_CONF,
+	PPTP_CALL_CLEAR_REQ,
+};
+
+
+/* conntrack private data */
+struct ip_ct_pptp_master {
+	enum pptp_ctrlsess_state sstate;	/* session state */
+
+	/* everything below is going to be per-expectation in newnat,
+	 * since there could be more than one call within one session */
+	enum pptp_ctrlcall_state cstate;	/* call state */
+	u_int16_t pac_call_id;			/* call id of PAC, host byte order */
+	u_int16_t pns_call_id;			/* call id of PNS, host byte order */
+};
+
+/* conntrack_expect private member */
+struct ip_ct_pptp_expect {
+	enum pptp_ctrlcall_state cstate; 	/* call state */
+	u_int16_t pac_call_id;			/* call id of PAC */
+	u_int16_t pns_call_id;			/* call id of PNS */
+};
+
+
+#ifdef __KERNEL__
+
+#include <linux/netfilter_ipv4/lockhelp.h>
+DECLARE_LOCK_EXTERN(ip_pptp_lock);
+
+#define IP_CONNTR_PPTP		PPTP_CONTROL_PORT
+
+union pptp_ctrl_union {
+                void				*rawreq;
+		struct PptpStartSessionRequest	*sreq;
+		struct PptpStartSessionReply	*srep;
+		struct PptpStopSessionReqest	*streq;
+		struct PptpStopSessionReply	*strep;
+                struct PptpOutCallRequest       *ocreq;
+                struct PptpOutCallReply         *ocack;
+                struct PptpInCallRequest        *icreq;
+                struct PptpInCallReply          *icack;
+                struct PptpInCallConnected      *iccon;
+		struct PptpClearCallRequest	*clrreq;
+                struct PptpCallDisconnectNotify *disc;
+                struct PptpWanErrorNotify       *wanerr;
+                struct PptpSetLinkInfo          *setlink;
+};
+
+
+
+#define PPTP_CONTROL_PORT	1723
+
+#define PPTP_PACKET_CONTROL	1
+#define PPTP_PACKET_MGMT	2
+
+#define PPTP_MAGIC_COOKIE	0x1a2b3c4d
+
+struct pptp_pkt_hdr {
+	__u16	packetLength;
+	__u16	packetType;
+	__u32	magicCookie;
+};
+
+/* PptpControlMessageType values */
+#define PPTP_START_SESSION_REQUEST	1
+#define PPTP_START_SESSION_REPLY	2
+#define PPTP_STOP_SESSION_REQUEST	3
+#define PPTP_STOP_SESSION_REPLY		4
+#define PPTP_ECHO_REQUEST		5
+#define PPTP_ECHO_REPLY			6
+#define PPTP_OUT_CALL_REQUEST		7
+#define PPTP_OUT_CALL_REPLY		8
+#define PPTP_IN_CALL_REQUEST		9
+#define PPTP_IN_CALL_REPLY		10
+#define PPTP_IN_CALL_CONNECT		11
+#define PPTP_CALL_CLEAR_REQUEST		12
+#define PPTP_CALL_DISCONNECT_NOTIFY	13
+#define PPTP_WAN_ERROR_NOTIFY		14
+#define PPTP_SET_LINK_INFO		15
+
+#define PPTP_MSG_MAX			15
+
+/* PptpGeneralError values */
+#define PPTP_ERROR_CODE_NONE		0
+#define PPTP_NOT_CONNECTED		1
+#define PPTP_BAD_FORMAT			2
+#define PPTP_BAD_VALUE			3
+#define PPTP_NO_RESOURCE		4
+#define PPTP_BAD_CALLID			5
+#define PPTP_REMOVE_DEVICE_ERROR	6
+
+struct PptpControlHeader {
+	__u16	messageType;
+	__u16	reserved;
+};
+
+/* FramingCapability Bitmap Values */
+#define PPTP_FRAME_CAP_ASYNC		0x1
+#define PPTP_FRAME_CAP_SYNC		0x2
+
+/* BearerCapability Bitmap Values */
+#define PPTP_BEARER_CAP_ANALOG		0x1
+#define PPTP_BEARER_CAP_DIGITAL		0x2
+
+struct PptpStartSessionRequest {
+	__u16	protocolVersion;
+	__u8	reserved1;
+	__u8	reserved2;
+	__u32	framingCapability;
+	__u32	bearerCapability;
+	__u16	maxChannels;
+	__u16	firmwareRevision;
+	__u8	hostName[64];
+	__u8	vendorString[64];
+};
+
+/* PptpStartSessionResultCode Values */
+#define PPTP_START_OK			1
+#define PPTP_START_GENERAL_ERROR	2
+#define PPTP_START_ALREADY_CONNECTED	3
+#define PPTP_START_NOT_AUTHORIZED	4
+#define PPTP_START_UNKNOWN_PROTOCOL	5
+
+struct PptpStartSessionReply {
+	__u16	protocolVersion;
+	__u8	resultCode;
+	__u8	generalErrorCode;
+	__u32	framingCapability;
+	__u32	bearerCapability;
+	__u16	maxChannels;
+	__u16	firmwareRevision;
+	__u8	hostName[64];
+	__u8	vendorString[64];
+};
+
+/* PptpStopReasons */
+#define PPTP_STOP_NONE			1
+#define PPTP_STOP_PROTOCOL		2
+#define PPTP_STOP_LOCAL_SHUTDOWN	3
+
+struct PptpStopSessionRequest {
+	__u8	reason;
+};
+
+/* PptpStopSessionResultCode */
+#define PPTP_STOP_OK			1
+#define PPTP_STOP_GENERAL_ERROR		2
+
+struct PptpStopSessionReply {
+	__u8	resultCode;
+	__u8	generalErrorCode;
+};
+
+struct PptpEchoRequest {
+	__u32 identNumber;
+};
+
+/* PptpEchoReplyResultCode */
+#define PPTP_ECHO_OK			1
+#define PPTP_ECHO_GENERAL_ERROR		2
+
+struct PptpEchoReply {
+	__u32	identNumber;
+	__u8	resultCode;
+	__u8	generalErrorCode;
+	__u16	reserved;
+};
+
+/* PptpFramingType */
+#define PPTP_ASYNC_FRAMING		1
+#define PPTP_SYNC_FRAMING		2
+#define PPTP_DONT_CARE_FRAMING		3
+
+/* PptpCallBearerType */
+#define PPTP_ANALOG_TYPE		1
+#define PPTP_DIGITAL_TYPE		2
+#define PPTP_DONT_CARE_BEARER_TYPE	3
+
+struct PptpOutCallRequest {
+	__u16	callID;
+	__u16	callSerialNumber;
+	__u32	minBPS;
+	__u32	maxBPS;
+	__u32	bearerType;
+	__u32	framingType;
+	__u16	packetWindow;
+	__u16	packetProcDelay;
+	__u16	reserved1;
+	__u16	phoneNumberLength;
+	__u16	reserved2;
+	__u8	phoneNumber[64];
+	__u8	subAddress[64];
+};
+
+/* PptpCallResultCode */
+#define PPTP_OUTCALL_CONNECT		1
+#define PPTP_OUTCALL_GENERAL_ERROR	2
+#define PPTP_OUTCALL_NO_CARRIER		3
+#define PPTP_OUTCALL_BUSY		4
+#define PPTP_OUTCALL_NO_DIAL_TONE	5
+#define PPTP_OUTCALL_TIMEOUT		6
+#define PPTP_OUTCALL_DONT_ACCEPT	7
+
+struct PptpOutCallReply {
+	__u16	callID;
+	__u16	peersCallID;
+	__u8	resultCode;
+	__u8	generalErrorCode;
+	__u16	causeCode;
+	__u32	connectSpeed;
+	__u16	packetWindow;
+	__u16	packetProcDelay;
+	__u32	physChannelID;
+};
+
+struct PptpInCallRequest {
+	__u16	callID;
+	__u16	callSerialNumber;
+	__u32	callBearerType;
+	__u32	physChannelID;
+	__u16	dialedNumberLength;
+	__u16	dialingNumberLength;
+	__u8	dialedNumber[64];
+	__u8	dialingNumber[64];
+	__u8	subAddress[64];
+};
+
+/* PptpInCallResultCode */
+#define PPTP_INCALL_ACCEPT		1
+#define PPTP_INCALL_GENERAL_ERROR	2
+#define PPTP_INCALL_DONT_ACCEPT		3
+
+struct PptpInCallReply {
+	__u16	callID;
+	__u16	peersCallID;
+	__u8	resultCode;
+	__u8	generalErrorCode;
+	__u16	packetWindow;
+	__u16	packetProcDelay;
+	__u16	reserved;
+};
+
+struct PptpInCallConnected {
+	__u16	peersCallID;
+	__u16	reserved;
+	__u32	connectSpeed;
+	__u16	packetWindow;
+	__u16	packetProcDelay;
+	__u32	callFramingType;
+};
+
+struct PptpClearCallRequest {
+	__u16	callID;
+	__u16	reserved;
+};
+
+struct PptpCallDisconnectNotify {
+	__u16	callID;
+	__u8	resultCode;
+	__u8	generalErrorCode;
+	__u16	causeCode;
+	__u16	reserved;
+	__u8	callStatistics[128];
+};
+
+struct PptpWanErrorNotify {
+	__u16	peersCallID;
+	__u16	reserved;
+	__u32	crcErrors;
+	__u32	framingErrors;
+	__u32	hardwareOverRuns;
+	__u32	bufferOverRuns;
+	__u32	timeoutErrors;
+	__u32	alignmentErrors;
+};
+
+struct PptpSetLinkInfo {
+	__u16	peersCallID;
+	__u16	reserved;
+	__u32	sendAccm;
+	__u32	recvAccm;
+};
+
+
+struct pptp_priv_data {
+	__u16	call_id;
+	__u16	mcall_id;
+	__u16	pcall_id;
+};
+
+#endif /* __KERNEL__ */
+#endif /* _CONNTRACK_PPTP_H */
diff -urN linux-2.4.29/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h linux-2.4.29-uc1/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h
--- linux-2.4.29/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h	2005-06-14 02:11:34.000000000 +0100
@@ -0,0 +1,123 @@
+#ifndef _CONNTRACK_PROTO_GRE_H
+#define _CONNTRACK_PROTO_GRE_H
+#include <asm/byteorder.h>
+
+/* GRE PROTOCOL HEADER */
+
+/* GRE Version field */
+#define GRE_VERSION_1701	0x0
+#define GRE_VERSION_PPTP	0x1
+
+/* GRE Protocol field */
+#define GRE_PROTOCOL_PPTP	0x880B
+
+/* GRE Flags */
+#define GRE_FLAG_C		0x80
+#define GRE_FLAG_R		0x40
+#define GRE_FLAG_K		0x20
+#define GRE_FLAG_S		0x10
+#define GRE_FLAG_A		0x80
+
+#define GRE_IS_C(f)	((f)&GRE_FLAG_C)
+#define GRE_IS_R(f)	((f)&GRE_FLAG_R)
+#define GRE_IS_K(f)	((f)&GRE_FLAG_K)
+#define GRE_IS_S(f)	((f)&GRE_FLAG_S)
+#define GRE_IS_A(f)	((f)&GRE_FLAG_A)
+
+/* GRE is a mess: Four different standards */
+struct gre_hdr {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+	__u16	rec:3,
+		srr:1,
+		seq:1,
+		key:1,
+		routing:1,
+		csum:1,
+		version:3,
+		reserved:4,
+		ack:1;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+	__u16	csum:1,
+		routing:1,
+		key:1,
+		seq:1,
+		srr:1,
+		rec:3,
+		ack:1,
+		reserved:4,
+		version:3;
+#else
+#error "Adjust your <asm/byteorder.h> defines"
+#endif
+	__u16	protocol;
+};
+
+/* modified GRE header for PPTP */
+struct gre_hdr_pptp {
+	__u8  flags;		/* bitfield */
+	__u8  version;		/* should be GRE_VERSION_PPTP */
+	__u16 protocol;		/* should be GRE_PROTOCOL_PPTP */
+	__u16 payload_len;	/* size of ppp payload, not inc. gre header */
+	__u16 call_id;		/* peer's call_id for this session */
+	__u32 seq;		/* sequence number.  Present if S==1 */
+	__u32 ack;		/* seq number of highest packet recieved by */
+				/*  sender in this session */
+};
+
+
+/* this is part of ip_conntrack */
+struct ip_ct_gre {
+	unsigned int stream_timeout;
+	unsigned int timeout;
+};
+
+/* this is part of ip_conntrack_expect */
+struct ip_ct_gre_expect {
+	struct ip_ct_gre_keymap *keymap_orig, *keymap_reply;
+};
+
+#ifdef __KERNEL__
+struct ip_conntrack_expect;
+
+/* structure for original <-> reply keymap */
+struct ip_ct_gre_keymap {
+	struct list_head list;
+
+	struct ip_conntrack_tuple tuple;
+};
+
+
+/* add new tuple->key_reply pair to keymap */
+int ip_ct_gre_keymap_add(struct ip_conntrack_expect *exp,
+			 struct ip_conntrack_tuple *t,
+			 int reply);
+
+/* change an existing keymap entry */
+void ip_ct_gre_keymap_change(struct ip_ct_gre_keymap *km,
+			     struct ip_conntrack_tuple *t);
+
+/* delete keymap entries */
+void ip_ct_gre_keymap_destroy(struct ip_conntrack_expect *exp);
+
+
+/* get pointer to gre key, if present */
+static inline u_int32_t *gre_key(struct gre_hdr *greh)
+{
+	if (!greh->key)
+		return NULL;
+	if (greh->csum || greh->routing)
+		return (u_int32_t *) (greh+sizeof(*greh)+4);
+	return (u_int32_t *) (greh+sizeof(*greh));
+}
+
+/* get pointer ot gre csum, if present */
+static inline u_int16_t *gre_csum(struct gre_hdr *greh)
+{
+	if (!greh->csum)
+		return NULL;
+	return (u_int16_t *) (greh+sizeof(*greh));
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _CONNTRACK_PROTO_GRE_H */
diff -urN linux-2.4.29/include/linux/netfilter_ipv4/ip_conntrack_tuple.h linux-2.4.29-uc1/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
--- linux-2.4.29/include/linux/netfilter_ipv4/ip_conntrack_tuple.h	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/netfilter_ipv4/ip_conntrack_tuple.h	2005-06-14 02:11:34.000000000 +0100
@@ -14,7 +14,7 @@
 union ip_conntrack_manip_proto
 {
 	/* Add other protocols here. */
-	u_int16_t all;
+	u_int32_t all;
 
 	struct {
 		u_int16_t port;
@@ -25,6 +25,9 @@
 	struct {
 		u_int16_t id;
 	} icmp;
+	struct {
+		u_int32_t key;
+	} gre;
 };
 
 /* The manipulable part of the tuple. */
@@ -44,7 +47,7 @@
 		u_int32_t ip;
 		union {
 			/* Add other protocols here. */
-			u_int16_t all;
+			u_int64_t all;
 
 			struct {
 				u_int16_t port;
@@ -55,6 +58,11 @@
 			struct {
 				u_int8_t type, code;
 			} icmp;
+			struct {
+				u_int16_t protocol;
+				u_int8_t version;
+				u_int32_t key;
+			} gre;
 		} u;
 
 		/* The protocol. */
@@ -80,10 +88,16 @@
 #ifdef __KERNEL__
 
 #define DUMP_TUPLE(tp)						\
-DEBUGP("tuple %p: %u %u.%u.%u.%u:%hu -> %u.%u.%u.%u:%hu\n",	\
+DEBUGP("tuple %p: %u %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n",	\
        (tp), (tp)->dst.protonum,				\
-       NIPQUAD((tp)->src.ip), ntohs((tp)->src.u.all),		\
-       NIPQUAD((tp)->dst.ip), ntohs((tp)->dst.u.all))
+       NIPQUAD((tp)->src.ip), ntohl((tp)->src.u.all),		\
+       NIPQUAD((tp)->dst.ip), ntohl((tp)->dst.u.all))
+
+#define DUMP_TUPLE_RAW(x) 						\
+	DEBUGP("tuple %p: %u %u.%u.%u.%u:0x%08x -> %u.%u.%u.%u:0x%08x\n",\
+	(x), (x)->dst.protonum,						\
+	NIPQUAD((x)->src.ip), ntohl((x)->src.u.all), 			\
+	NIPQUAD((x)->dst.ip), ntohl((x)->dst.u.all))
 
 #define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL)
 
diff -urN linux-2.4.29/include/linux/netfilter_ipv4/ip_nat_pptp.h linux-2.4.29-uc1/include/linux/netfilter_ipv4/ip_nat_pptp.h
--- linux-2.4.29/include/linux/netfilter_ipv4/ip_nat_pptp.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_ipv4/ip_nat_pptp.h	2005-06-14 02:11:34.000000000 +0100
@@ -0,0 +1,11 @@
+/* PPTP constants and structs */
+#ifndef _NAT_PPTP_H
+#define _NAT_PPTP_H
+
+/* conntrack private data */
+struct ip_nat_pptp {
+	u_int16_t pns_call_id;		/* NAT'ed PNS call id */
+	u_int16_t pac_call_id;		/* NAT'ed PAC call id */
+};
+
+#endif /* _NAT_PPTP_H */
diff -urN linux-2.4.29/include/linux/netfilter_ipv4/ipt_connmark.h linux-2.4.29-uc1/include/linux/netfilter_ipv4/ipt_connmark.h
--- linux-2.4.29/include/linux/netfilter_ipv4/ipt_connmark.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_ipv4/ipt_connmark.h	2005-06-14 02:11:34.000000000 +0100
@@ -0,0 +1,9 @@
+#ifndef _IPT_CONNMARK_H
+#define _IPT_CONNMARK_H
+
+struct ipt_connmark_info {
+	unsigned long mark, mask;
+	u_int8_t invert;
+};
+
+#endif /*_IPT_CONNMARK_H*/
diff -urN linux-2.4.29/include/linux/netfilter_ipv4/ipt_CONNMARK.h linux-2.4.29-uc1/include/linux/netfilter_ipv4/ipt_CONNMARK.h
--- linux-2.4.29/include/linux/netfilter_ipv4/ipt_CONNMARK.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_ipv4/ipt_CONNMARK.h	2005-06-14 02:11:34.000000000 +0100
@@ -0,0 +1,25 @@
+#ifndef _IPT_CONNMARK_H_target
+#define _IPT_CONNMARK_H_target
+
+/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
+ * by Henrik Nordstrom <hno@marasystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+enum {
+	IPT_CONNMARK_SET = 0,
+	IPT_CONNMARK_SAVE,
+	IPT_CONNMARK_RESTORE
+};
+
+struct ipt_connmark_target_info {
+	unsigned long mark;
+	unsigned long mask;
+	u_int8_t mode;
+};
+
+#endif /*_IPT_CONNMARK_H_target*/
diff -urN linux-2.4.29/include/linux/netfilter_ipv4/ipt_IMQ.h linux-2.4.29-uc1/include/linux/netfilter_ipv4/ipt_IMQ.h
--- linux-2.4.29/include/linux/netfilter_ipv4/ipt_IMQ.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_ipv4/ipt_IMQ.h	2005-06-14 02:11:34.000000000 +0100
@@ -0,0 +1,8 @@
+#ifndef _IPT_IMQ_H
+#define _IPT_IMQ_H
+
+struct ipt_imq_info {
+	unsigned int todev;	/* target imq device */
+};
+
+#endif /* _IPT_IMQ_H */
diff -urN linux-2.4.29/include/linux/netfilter_ipv4/ipt_iprange.h linux-2.4.29-uc1/include/linux/netfilter_ipv4/ipt_iprange.h
--- linux-2.4.29/include/linux/netfilter_ipv4/ipt_iprange.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_ipv4/ipt_iprange.h	2005-06-14 02:11:34.000000000 +0100
@@ -0,0 +1,23 @@
+#ifndef _IPT_IPRANGE_H
+#define _IPT_IPRANGE_H
+
+#define IPRANGE_SRC		0x01	/* Match source IP address */
+#define IPRANGE_DST		0x02	/* Match destination IP address */
+#define IPRANGE_SRC_INV		0x10	/* Negate the condition */
+#define IPRANGE_DST_INV		0x20	/* Negate the condition */
+
+struct ipt_iprange {
+	/* Inclusive: network order. */
+	u_int32_t min_ip, max_ip;
+};
+
+struct ipt_iprange_info
+{
+	struct ipt_iprange src;
+	struct ipt_iprange dst;
+
+	/* Flags from above */
+	u_int8_t flags;
+};
+
+#endif /* _IPT_IPRANGE_H */
diff -urN linux-2.4.29/include/linux/netfilter_ipv4/ipt_string.h linux-2.4.29-uc1/include/linux/netfilter_ipv4/ipt_string.h
--- linux-2.4.29/include/linux/netfilter_ipv4/ipt_string.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_ipv4/ipt_string.h	2005-06-14 02:11:34.000000000 +0100
@@ -0,0 +1,21 @@
+#ifndef _IPT_STRING_H
+#define _IPT_STRING_H
+
+/* *** PERFORMANCE TWEAK ***
+ * Packet size and search string threshold,
+ * above which sublinear searches is used. */
+#define IPT_STRING_HAYSTACK_THRESH	100
+#define IPT_STRING_NEEDLE_THRESH	20
+
+#define BM_MAX_NLEN 256
+#define BM_MAX_HLEN 1024
+
+typedef char *(*proc_ipt_search) (char *, char *, int, int);
+
+struct ipt_string_info {
+    char string[BM_MAX_NLEN];
+    u_int16_t invert;
+    u_int16_t len;
+};
+
+#endif /* _IPT_STRING_H */
diff -urN linux-2.4.29/include/linux/netfilter_ipv4/ipt_time.h linux-2.4.29-uc1/include/linux/netfilter_ipv4/ipt_time.h
--- linux-2.4.29/include/linux/netfilter_ipv4/ipt_time.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_ipv4/ipt_time.h	2005-06-14 02:11:34.000000000 +0100
@@ -0,0 +1,15 @@
+#ifndef __ipt_time_h_included__
+#define __ipt_time_h_included__
+
+
+struct ipt_time_info {
+	u_int8_t  days_match;   /* 1 bit per day. -SMTWTFS                      */
+	u_int16_t time_start;   /* 0 < time_start < 23*60+59 = 1439             */
+	u_int16_t time_stop;    /* 0:0 < time_stat < 23:59                      */
+	u_int8_t  kerneltime;   /* ignore skb time (and use kerneltime) or not. */
+	time_t    date_start;
+	time_t    date_stop;
+};
+
+
+#endif /* __ipt_time_h_included__ */
diff -urN linux-2.4.29/include/linux/netfilter_ipv4.h linux-2.4.29-uc1/include/linux/netfilter_ipv4.h
--- linux-2.4.29/include/linux/netfilter_ipv4.h	2002-02-25 19:38:13.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/netfilter_ipv4.h	2005-06-14 02:11:36.000000000 +0100
@@ -49,15 +49,19 @@
 #define NF_IP_POST_ROUTING	4
 #define NF_IP_NUMHOOKS		5
 
+#ifdef __KERNEL__
 enum nf_ip_hook_priorities {
 	NF_IP_PRI_FIRST = INT_MIN,
 	NF_IP_PRI_CONNTRACK = -200,
+	NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
 	NF_IP_PRI_MANGLE = -150,
 	NF_IP_PRI_NAT_DST = -100,
+	NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50,
 	NF_IP_PRI_FILTER = 0,
 	NF_IP_PRI_NAT_SRC = 100,
 	NF_IP_PRI_LAST = INT_MAX,
 };
+#endif
 
 /* Arguments for setsockopt SOL_IP: */
 /* 2.0 firewalling went from 64 through 71 (and +256, +512, etc). */
diff -urN linux-2.4.29/include/linux/netfilter_ipv6/ip6t_IMQ.h linux-2.4.29-uc1/include/linux/netfilter_ipv6/ip6t_IMQ.h
--- linux-2.4.29/include/linux/netfilter_ipv6/ip6t_IMQ.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_ipv6/ip6t_IMQ.h	2005-06-14 02:11:34.000000000 +0100
@@ -0,0 +1,8 @@
+#ifndef _IP6T_IMQ_H
+#define _IP6T_IMQ_H
+
+struct ip6t_imq_info {
+	unsigned int todev;	/* target imq device */
+};
+
+#endif /* _IP6T_IMQ_H */
diff -urN linux-2.4.29/include/linux/netfilter_ipv6/ip6t_REJECT.h linux-2.4.29-uc1/include/linux/netfilter_ipv6/ip6t_REJECT.h
--- linux-2.4.29/include/linux/netfilter_ipv6/ip6t_REJECT.h	2000-06-20 22:32:27.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/netfilter_ipv6/ip6t_REJECT.h	2005-06-14 02:11:34.000000000 +0100
@@ -2,15 +2,17 @@
 #define _IP6T_REJECT_H
 
 enum ip6t_reject_with {
-	IP6T_ICMP_NET_UNREACHABLE,
-	IP6T_ICMP_HOST_UNREACHABLE,
-	IP6T_ICMP_PROT_UNREACHABLE,
-	IP6T_ICMP_PORT_UNREACHABLE,
-	IP6T_ICMP_ECHOREPLY
+	IP6T_ICMP6_NO_ROUTE,
+	IP6T_ICMP6_ADM_PROHIBITED,
+	IP6T_ICMP6_NOT_NEIGHBOUR,
+	IP6T_ICMP6_ADDR_UNREACH,
+	IP6T_ICMP6_PORT_UNREACH,
+	IP6T_ICMP6_ECHOREPLY,
+	IP6T_TCP_RESET
 };
 
 struct ip6t_reject_info {
 	enum ip6t_reject_with with;      /* reject type */
 };
 
-#endif /*_IPT_REJECT_H*/
+#endif /*_IP6T_REJECT_H*/
diff -urN linux-2.4.29/include/linux/pkt_sched.h linux-2.4.29-uc1/include/linux/pkt_sched.h
--- linux-2.4.29/include/linux/pkt_sched.h	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/pkt_sched.h	2005-06-14 02:11:35.000000000 +0100
@@ -453,6 +453,118 @@
 	__u32	jitter;		/* random jitter in latency (us) */
 };
 
+/* WRR section */
+
+/* Other includes */
+#include <linux/if_ether.h>
+
+// A sub weight and of a class
+// All numbers are represented as parts of (2^64-1).
+struct tc_wrr_class_weight {
+  __u64 val;  // Current value                        (0 is not valid)
+  __u64 decr; // Value pr bytes                       (2^64-1 is not valid)
+  __u64 incr; // Value pr seconds                     (2^64-1 is not valid)
+  __u64 min;  // Minimal value                        (0 is not valid)
+  __u64 max;  // Minimal value                        (0 is not valid)
+
+  // The time where the above information was correct:
+  time_t tim;
+};
+
+// Pakcet send when modifying a class:
+struct tc_wrr_class_modf {
+  // Not-valid values are ignored.
+  struct tc_wrr_class_weight weight1;
+  struct tc_wrr_class_weight weight2;
+};
+
+// Packet returned when quering a class:
+struct tc_wrr_class_stats {
+  char used; // If this is false the information below is invalid
+
+  struct tc_wrr_class_modf class_modf;
+
+  unsigned char addr[ETH_ALEN];
+  char usemac;    // True if addr is a MAC address, else it is an IP address
+                  // (this value is only for convience, it is always the same
+		  //  value as in the qdisc)
+  int heappos;    // Current heap position or 0 if not in heap  
+  __u64 penal_ls; // Penalty value in heap (ls)
+  __u64 penal_ms; // Penalty value in heap (ms)
+};
+
+// Qdisc-wide penalty information (boolean values - 2 not valid)
+struct tc_wrr_qdisc_weight {
+  char weight_mode; // 0=No automatic change to weight
+                    // 1=Decrease normally
+		    // 2=Also multiply with number of machines
+		    // 3=Instead multiply with priority divided
+		    //   with priority of the other.
+		    // -1=no change
+};
+
+// Packet send when modifing a qdisc:
+struct tc_wrr_qdisc_modf {
+  // Not-valid values are ignored:
+  struct tc_wrr_qdisc_weight weight1;
+  struct tc_wrr_qdisc_weight weight2;
+};
+
+// Packet send when creating a qdisc:
+struct tc_wrr_qdisc_crt {
+  struct tc_wrr_qdisc_modf qdisc_modf;
+  
+  char srcaddr;      // 1=lookup source, 0=lookup destination
+  char usemac;       // 1=Classify on MAC addresses, 0=classify on IP
+  char usemasq;      // 1=Classify based on masqgrading - only valid
+                     //   if usemac is zero
+  int bands_max;     // Maximal number of bands (i.e.: classes)  
+  int proxy_maxconn; // If differnt from 0 then we support proxy remapping
+                     // of packets. And this is the number of maximal
+		     // concurrent proxy connections.
+};
+
+// Packet returned when quering a qdisc:
+struct tc_wrr_qdisc_stats {
+  struct tc_wrr_qdisc_crt qdisc_crt;
+  int proxy_curconn;		     
+  int nodes_in_heap;  // Current number of bands wanting to send something
+  int bands_cur;      // Current number of bands used (i.e.: MAC/IP addresses seen)
+  int bands_reused;   // Number of times this band has been reused.
+  int packets_requed; // Number of times packets have been requeued.
+  __u64 priosum;      // Sum of priorities in heap where 1 is 2^32
+};
+
+struct tc_wrr_qdisc_modf_std {
+  // This indicates which of the tc_wrr_qdisc_modf structers this is:
+  char proxy; // 0=This struct
+
+  // Should we also change a class?
+  char change_class;
+
+  // Only valid if change_class is false
+  struct tc_wrr_qdisc_modf qdisc_modf;
+    
+  // Only valid if change_class is true:
+  unsigned char addr[ETH_ALEN]; // Class to change (non-used bytes should be 0)
+  struct tc_wrr_class_modf class_modf; // The change    
+};
+
+// Used for proxyrempping:
+struct tc_wrr_qdisc_modf_proxy {
+  // This indicates which of the tc_wrr_qdisc_modf structers this is:
+  char proxy; // 1=This struct
+  
+  // This is 1 if the proxyremap information should be reset
+  char reset;
+  
+  // changec is the number of elements in changes.
+  int changec; 
+  
+  // This is an array of type ProxyRemapBlock:
+  long changes[0];  
+};
+
 struct tc_netem_corr
 {
 	__u32	delay_corr;	/* delay correlation */
diff -urN linux-2.4.29/include/linux/ppp-comp.h linux-2.4.29-uc1/include/linux/ppp-comp.h
--- linux-2.4.29/include/linux/ppp-comp.h	1999-08-06 18:44:11.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/ppp-comp.h	2005-06-14 02:11:36.000000000 +0100
@@ -24,11 +24,11 @@
  * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
  * OR MODIFICATIONS.
  *
- * $Id: ppp-comp.h,v 1.6 1997/11/27 06:04:44 paulus Exp $
+ * $Id: ppp-comp.h,v 1.8 1999/07/23 06:53:40 paulus Exp $
  */
 
 /*
- *  ==FILEVERSION 980319==
+ *  ==FILEVERSION 990623==
  *
  *  NOTE TO MAINTAINERS:
  *     If you modify this file at all, please set the above date.
@@ -120,6 +120,7 @@
  * Don't you just lurve software patents.
  */
 
+#define DECOMP_OK		0	/* no error occured */
 #define DECOMP_ERROR		-1	/* error detected before decomp. */
 #define DECOMP_FATALERROR	-2	/* error detected after decomp. */
 
@@ -138,7 +139,7 @@
  * Max # bytes for a CCP option
  */
 
-#define CCP_MAX_OPTION_LENGTH	32
+#define CCP_MAX_OPTION_LENGTH	64
 
 /*
  * Parts of a CCP packet.
@@ -187,6 +188,20 @@
 #define DEFLATE_CHK_SEQUENCE	0
 
 /*
+ * Definitions for MPPE.
+ */
+
+#define CI_MPPE			18	/* config. option for MPPE */
+#define CILEN_MPPE		6	/* length of config. option */
+
+/*
+ * Definitions for Stac LZS.
+ */
+
+#define CI_LZS			17	/* config option for Stac LZS */
+#define CILEN_LZS		5	/* length of config option */
+
+/*
  * Definitions for other, as yet unsupported, compression methods.
  */
 
diff -urN linux-2.4.29/include/linux/random.h linux-2.4.29-uc1/include/linux/random.h
--- linux-2.4.29/include/linux/random.h	2000-01-25 22:13:46.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/random.h	2005-06-14 02:11:37.000000000 +0100
@@ -52,6 +52,7 @@
 extern void add_mouse_randomness(__u32 mouse_data);
 extern void add_interrupt_randomness(int irq);
 extern void add_blkdev_randomness(int major);
+extern void add_true_randomness(__u32 *buf, int nwords);
 
 extern void get_random_bytes(void *buf, int nbytes);
 void generate_random_uuid(unsigned char uuid_out[16]);
diff -urN linux-2.4.29/include/linux/rtnetlink.h linux-2.4.29-uc1/include/linux/rtnetlink.h
--- linux-2.4.29/include/linux/rtnetlink.h	2004-08-08 00:26:06.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/rtnetlink.h	2005-06-14 02:11:37.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: rtnetlink.h,v 1.13 2003/11/12 05:11:56 yoshfuji Exp $ */
+
 #ifndef __LINUX_RTNETLINK_H
 #define __LINUX_RTNETLINK_H
 
@@ -315,6 +317,7 @@
 	IFA_BROADCAST,
 	IFA_ANYCAST,
 	IFA_CACHEINFO,
+	IFA_HOMEAGENT,
 	__IFA_MAX
 };
 
@@ -323,7 +326,9 @@
 /* ifa_flags */
 
 #define IFA_F_SECONDARY		0x01
+#define IFA_F_TEMPORARY		IFA_F_SECONDARY
 
+#define IFA_F_HOMEADDR		0x10
 #define IFA_F_DEPRECATED	0x20
 #define IFA_F_TENTATIVE		0x40
 #define IFA_F_PERMANENT		0x80
diff -urN linux-2.4.29/include/linux/sched.h linux-2.4.29-uc1/include/linux/sched.h
--- linux-2.4.29/include/linux/sched.h	2005-01-19 14:10:12.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/sched.h	2005-06-14 02:11:36.000000000 +0100
@@ -26,6 +26,9 @@
 #include <linux/signal.h>
 #include <linux/securebits.h>
 #include <linux/fs_struct.h>
+#ifdef NO_MM
+#include <linux/wait.h>
+#endif
 
 struct exec_domain;
 
@@ -199,6 +202,9 @@
 }
 
 /* Maximum number of active map areas.. This is a random (large) number */
+
+#ifndef NO_MM
+
 #define DEFAULT_MAX_MAP_COUNT	(65536)
 
 extern int max_map_count;
@@ -246,6 +252,52 @@
 	mmlist:		LIST_HEAD_INIT(name.mmlist),	\
 }
 
+#else /* NO_MM */
+
+struct mm_rblock_struct {
+	int size;
+	int refcount;
+	void * kblock;
+};
+
+struct mm_tblock_struct {
+	struct mm_rblock_struct * rblock;
+	struct mm_tblock_struct * next;
+};
+
+struct mm_struct {
+	/* How many users with user space? */
+	atomic_t mm_users;
+	/* How many references to "struct mm_struct" (users count as 1) */
+	atomic_t mm_count;
+
+	unsigned dumpable:1;
+
+	struct list_head mmlist;		/* List of all active mm's */
+
+	struct rw_semaphore mmap_sem;
+	spinlock_t page_table_lock;
+	unsigned long start_code, end_code, start_data, end_data;
+	unsigned long start_brk, brk, end_brk, start_stack;
+	unsigned long arg_start, arg_end, env_start, env_end;
+	unsigned long rss, total_vm, locked_vm;
+	unsigned long def_flags;
+	unsigned long cpu_vm_mask;
+	struct mm_tblock_struct tblock;
+};
+
+extern int mmlist_nr;
+
+#define INIT_MM(name) {											\
+		mm_users:		ATOMIC_INIT(2),							\
+		mm_count:		ATOMIC_INIT(1),							\
+		mmlist:			LIST_HEAD_INIT(name.mmlist),			\
+		mmap_sem:		__RWSEM_INITIALIZER(name.mmap_sem), 	\
+		page_table_lock:SPIN_LOCK_UNLOCKED,						\
+		tblock:			{NULL, NULL} }
+
+#endif /* NO_MM */
+
 struct signal_struct {
 	atomic_t		count;
 	struct k_sigaction	action[_NSIG];
@@ -415,8 +467,18 @@
 
 /* journalling filesystem info */
 	void *journal_info;
+
+#ifdef CONFIG_SYSCALLTIMER
+	int curr_syscall;
+#endif
 };
 
+#ifdef CONFIG_SYSCALLTIMER
+#define CURR_SYSCALL curr_syscall:	0,
+#else
+#define CURR_SYSCALL
+#endif
+
 /*
  * Per process flags
  */
@@ -436,6 +498,10 @@
 
 #define PF_USEDFPU	0x00100000	/* task used FPU this quantum (SMP) */
 
+#ifdef CONFIG_EP93XX_CRUNCH
+#define PF_USEDCRUNCH	0x00200000
+#endif
+
 /*
  * Ptrace flags
  */
@@ -510,6 +576,7 @@
     blocked:		{{0}},						\
     alloc_lock:		SPIN_LOCK_UNLOCKED,				\
     journal_info:	NULL,						\
+    CURR_SYSCALL							\
 }
 
 
diff -urN linux-2.4.29/include/linux/serial_core.h linux-2.4.29-uc1/include/linux/serial_core.h
--- linux-2.4.29/include/linux/serial_core.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/serial_core.h	2005-06-14 02:11:35.000000000 +0100
@@ -0,0 +1,441 @@
+/*
+ *  linux/drivers/char/serial_core.h
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ *
+ *  $Id: serial_core.h,v 1.9.2.3 2001/11/26 22:32:45 rmk Exp $
+ */
+
+/*
+ * The type definitions.  These are from Ted Ts'o's serial.h
+ */
+#define PORT_UNKNOWN	0
+#define PORT_8250	1
+#define PORT_16450	2
+#define PORT_16550	3
+#define PORT_16550A	4
+#define PORT_CIRRUS	5
+#define PORT_16650	6
+#define PORT_16650V2	7
+#define PORT_16750	8
+#define PORT_STARTECH	9
+#define PORT_16C950	10
+#define PORT_16654	11
+#define PORT_16850	12
+#define PORT_RSA	13
+#define PORT_NS16550A	14
+#define PORT_MAX_8250	14	/* max port ID */
+
+/*
+ * ARM specific type numbers.  These are not currently guaranteed
+ * to be implemented, and will change in the future.  These are
+ * separate so any additions to the old serial.c that occur before
+ * we are merged can be easily merged here.
+ */
+#define PORT_AMBA	32
+#define PORT_CLPS711X	33
+#define PORT_SA1100	34
+#define PORT_UART00	35
+#define PORT_21285	37
+
+/* Sparc type numbers.  */
+#define PORT_SUNZILOG	38
+#define PORT_SUNSAB	39
+
+/* NEC v850.  */
+#define PORT_NB85E_UART	40
+
+/* NEC PC-9800 */
+#define PORT_8251_PC98	41
+#define PORT_19K_PC98	42
+#define PORT_FIFO_PC98	43
+#define PORT_VFAST_PC98	44
+#define PORT_PC9861	45
+#define PORT_PC9801_101	46
+
+/* DZ */
+#define PORT_DZ		47
+
+#define PORT_OMAHA	48
+#define PORT_AT91RM9200	49
+
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/spinlock.h>
+
+struct uart_port;
+struct uart_info;
+struct serial_struct;
+
+/*
+ * This structure describes all the operations that can be
+ * done on the physical hardware.
+ */
+struct uart_ops {
+	unsigned int	(*tx_empty)(struct uart_port *);
+	void		(*set_mctrl)(struct uart_port *, unsigned int mctrl);
+	unsigned int	(*get_mctrl)(struct uart_port *);
+	void		(*stop_tx)(struct uart_port *, unsigned int tty_stop);
+	void		(*start_tx)(struct uart_port *, unsigned int tty_start);
+	void		(*send_xchar)(struct uart_port *, char ch);
+	void		(*stop_rx)(struct uart_port *);
+	void		(*enable_ms)(struct uart_port *);
+	void		(*break_ctl)(struct uart_port *, int ctl);
+	int		(*startup)(struct uart_port *);
+	void		(*shutdown)(struct uart_port *);
+	void		(*change_speed)(struct uart_port *, unsigned int cflag, unsigned int iflag, unsigned int quot);
+	void		(*pm)(struct uart_port *, unsigned int state, unsigned int oldstate);
+	int		(*set_wake)(struct uart_port *, unsigned int state);
+
+	/*
+	 * Return a string describing the type of the port
+	 */
+	const char *(*type)(struct uart_port *);
+
+	/*
+	 * Release IO and memory resources used by the port.
+	 * This includes iounmap if necessary.
+	 */
+	void		(*release_port)(struct uart_port *);
+
+	/*
+	 * Request IO and memory resources used by the port.
+	 * This includes iomapping the port if necessary.
+	 */
+	int		(*request_port)(struct uart_port *);
+	void		(*config_port)(struct uart_port *, int);
+	int		(*verify_port)(struct uart_port *, struct serial_struct *);
+	int		(*ioctl)(struct uart_port *, unsigned int, unsigned long);
+};
+
+#define UART_CONFIG_TYPE	(1 << 0)
+#define UART_CONFIG_IRQ		(1 << 1)
+
+struct uart_icount {
+	__u32	cts;
+	__u32	dsr;
+	__u32	rng;
+	__u32	dcd;
+	__u32	rx;
+	__u32	tx;
+	__u32	frame;
+	__u32	overrun;
+	__u32	parity;
+	__u32	brk;
+	__u32	buf_overrun;
+};
+
+struct uart_port {
+	spinlock_t		lock;			/* port lock */
+	unsigned int		iobase;			/* in/out[bwl] */
+	char			*membase;		/* read/write[bwl] */
+	unsigned char		fifosize;		/* tx fifo size */
+	unsigned char		x_char;			/* xon/xoff char */
+	unsigned char		regshift;		/* reg offset shift */
+	unsigned char		iotype;			/* io access style */
+
+#define UPIO_PORT		(0)
+#define UPIO_HUB6		(1)
+#define UPIO_MEM		(2)
+
+	unsigned int		read_status_mask;	/* driver specific */
+	unsigned int		ignore_status_mask;	/* driver specific */
+
+	struct uart_info	*info;			/* pointer to parent info */
+	struct uart_icount	icount;			/* statistics */
+
+	struct console		*cons;			/* struct console, if any */
+	unsigned long		sysrq;			/* sysrq timeout */
+
+	unsigned int		flags;
+
+#define UPF_HUP_NOTIFY		ASYNC_HUP_NOTIFY
+#define UPF_FOURPORT		ASYNC_FOURPORT
+#define UPF_SAK			ASYNC_SAK
+#define UPF_SPLIT_TERMIOS	ASYNC_SPLIT_TERMIOS
+#define UPF_SPD_MASK		(0x1030)
+#define UPF_SPD_HI		(0x0010)
+#define UPF_SPD_VHI		(0x0020)
+#define UPF_SPD_CUST		(0x0030)
+#define UPF_SPD_SHI		(0x1000)
+#define UPF_SPD_WARP		(0x1010)
+#define UPF_SKIP_TEST		ASYNC_SKIP_TEST
+#define UPF_AUTO_IRQ		ASYNC_AUTO_IRQ
+#define UPF_SESSION_LOCKOUT	ASYNC_SESSION_LOCKOUT
+#define UPF_PGRP_LOCKOUT	ASYNCPGRP_LOCKOUT
+#define UPF_CALLOUT_NOHUP	ASYNC_CALLOUT_NOHUP
+#define UPF_HARDPPS_CD		ASYNC_HARDPPS_CD
+				/* 12 */
+#define UPF_LOW_LATENCY		ASYNC_LOW_LATENCY
+#define UPF_BUGGY_UART		ASYNC_BUGGY_UART
+#define UPF_AUTOPROBE		ASYNC_AUTOPROBE
+#define UPF_MAGIC_MULTIPLIER	(1 << 16)
+#define UPF_BOOT_ONLYMCA	ASYNC_BOOT_ONLYMCA
+#define UPF_CONS_FLOW		ASYNC_CONS_FLOW
+#define UPF_SHARE_IRQ		ASYNC_SHARE_IRQ
+#define UPF_BOOT_AUTOCONF	ASYNC_BOOT_AUTOCONF
+#define UPF_RESOURCES		(1 << 30)
+#define UPF_IOREMAP		(1 << 31)
+
+#define UPF_CHANGE_MASK		(0x17fff)
+#define UPF_USR_MASK		(UPF_SPD_MASK|UPF_LOW_LATENCY)
+
+	unsigned int		mctrl;			/* current modem ctrl settings */
+	unsigned int		timeout;		/* character-based timeout */
+	unsigned int		type;			/* port type */
+	struct uart_ops		*ops;
+	unsigned int		uartclk;		/* base uart clock */
+	unsigned int		custom_divisor;
+	unsigned int		irq;			/* irq number */
+	unsigned int		line;			/* port index */
+	unsigned long		mapbase;		/* for ioremap */
+	unsigned char		hub6;			/* this should be in the 8250 driver */
+	unsigned char		unused[7];
+};
+
+/*
+ * This is the state information which is persistent across opens.
+ * The low level driver must not to touch any elements contained
+ * within.
+ */
+struct uart_state {
+	unsigned int		close_delay;
+	unsigned int		closing_wait;
+
+#define USF_CLOSING_WAIT_INF	(0)
+#define USF_CLOSING_WAIT_NONE	(65535)
+
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+
+	int			count;
+	struct uart_info	*info;
+	struct uart_port	*port;
+
+	struct semaphore	sem;
+#ifdef CONFIG_PM
+	struct pm_dev		*pm;
+#endif
+};
+
+#define UART_XMIT_SIZE 1024
+/*
+ * This is the state information which is only valid when the port
+ * is open; it may be freed by the core driver once the device has
+ * been closed.  Either the low level driver or the core can modify
+ * stuff here.
+ */
+struct uart_info {
+	struct tty_struct	*tty;
+	struct circ_buf		xmit;
+	unsigned int		flags;
+
+/*
+ * These are the flags that specific to info->flags, and reflect our
+ * internal state.  They can not be accessed via port->flags.  Low
+ * level drivers must not change these, but may query them instead.
+ */
+#define UIF_CHECK_CD		ASYNC_CHECK_CD
+#define UIF_CTS_FLOW		ASYNC_CTS_FLOW
+#define UIF_CALLOUT_ACTIVE	ASYNC_CALLOUT_ACTIVE
+#define UIF_NORMAL_ACTIVE	ASYNC_NORMAL_ACTIVE
+#define UIF_INITIALIZED		ASYNC_INITIALIZED
+
+	unsigned char		*tmpbuf;
+	struct semaphore	tmpbuf_sem;
+
+	unsigned int		driver_priv;
+	int			blocked_open;
+	pid_t			session;
+	pid_t			pgrp;
+
+	struct tasklet_struct	tlet;
+
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	delta_msr_wait;
+};
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS		256
+
+struct module;
+struct tty_driver;
+
+struct uart_driver {
+	struct module		*owner;
+	int			 normal_major;
+	const char		*normal_name;
+	struct tty_driver	*normal_driver;
+	int			 callout_major;
+	const char		*callout_name;
+	struct tty_driver	*callout_driver;
+	struct tty_struct	**table;
+	struct termios		**termios;
+	struct termios		**termios_locked;
+	int			 minor;
+	int			 nr;
+	struct console		*cons;
+
+	/*
+	 * these are private; the low level driver should not
+	 * touch these; they should be initialised to NULL
+	 */
+	struct uart_state	*state;
+};
+
+void uart_write_wakeup(struct uart_port *port);
+struct uart_port *uart_get_console(struct uart_port *ports, int nr,
+				   struct console *c);
+void uart_parse_options(char *options, int *baud, int *parity, int *bits,
+			int *flow);
+int uart_set_options(struct uart_port *port, struct console *co, int baud,
+		     int parity, int bits, int flow);
+
+/*
+ * Port/driver registration/removal
+ */
+int uart_register_driver(struct uart_driver *uart);
+void uart_unregister_driver(struct uart_driver *uart);
+void uart_unregister_port(struct uart_driver *reg, int line);
+int uart_register_port(struct uart_driver *reg, struct uart_port *port);
+int uart_add_one_port(struct uart_driver *reg, struct uart_port *port);
+int uart_remove_one_port(struct uart_driver *reg, struct uart_port *port);
+
+#define uart_circ_empty(circ)		((circ)->head == (circ)->tail)
+#define uart_circ_clear(circ)		((circ)->head = (circ)->tail = 0)
+
+#define uart_circ_chars_pending(circ)	\
+	(CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
+
+#define uart_circ_chars_free(circ)	\
+	(CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
+
+#define uart_tx_stopped(port)		\
+	((port)->info->tty->stopped || (port)->info->tty->hw_stopped)
+
+/*
+ * The following are helper functions for the low level drivers.
+ */
+#ifdef SUPPORT_SYSRQ
+static inline int
+uart_handle_sysrq_char(struct uart_port *port, unsigned int ch,
+		       struct pt_regs *regs)
+{
+	if (port->sysrq) {
+		if (ch && time_before(jiffies, port->sysrq)) {
+			handle_sysrq(ch, regs, NULL, NULL);
+			port->sysrq = 0;
+			return 1;
+		}
+		port->sysrq = 0;
+	}
+	return 0;
+}
+#else
+#define uart_handle_sysrq_char(port,ch,regs)	(0)
+#endif
+
+/*
+ * We do the SysRQ and SAK checking like this...
+ */
+static inline int uart_handle_break(struct uart_port *port)
+{
+	struct uart_info *info = port->info;
+#ifdef SUPPORT_SYSRQ
+	if (port->cons && port->cons->index == port->line) {
+		if (!port->sysrq) {
+			port->sysrq = jiffies + HZ*5;
+			return 1;
+		}
+		port->sysrq = 0;
+	}
+#endif
+	if (port->flags & UPF_SAK)
+		do_SAK(info->tty);
+	return 0;
+}
+
+/**
+ *	uart_handle_dcd_change - handle a change of carrier detect state
+ *	@port: uart_port structure for the open port
+ *	@status: new carrier detect status, nonzero if active
+ */
+static inline void
+uart_handle_dcd_change(struct uart_port *port, unsigned int status)
+{
+	struct uart_info *info = port->info;
+
+	port->icount.dcd++;
+
+#ifdef CONFIG_HARD_PPS
+	if ((port->flags & UPF_HARDPPS_CD) && status)
+		hardpps();
+#endif
+
+	if (info->flags & UIF_CHECK_CD) {
+		if (status)
+			wake_up_interruptible(&info->open_wait);
+		else if (!((info->flags & UIF_CALLOUT_ACTIVE) &&
+			   (port->flags & UPF_CALLOUT_NOHUP))) {
+			if (info->tty)
+				tty_hangup(info->tty);
+		}
+	}
+}
+
+/**
+ *	uart_handle_cts_change - handle a change of clear-to-send state
+ *	@port: uart_port structure for the open port
+ *	@status: new clear to send status, nonzero if active
+ */
+static inline void
+uart_handle_cts_change(struct uart_port *port, unsigned int status)
+{
+	struct uart_info *info = port->info;
+	struct tty_struct *tty = info->tty;
+
+	port->icount.cts++;
+
+	if (info->flags & UIF_CTS_FLOW) {
+		if (tty->hw_stopped) {
+			if (status) {
+				tty->hw_stopped = 0;
+				port->ops->start_tx(port, 0);
+				uart_write_wakeup(port);
+			}
+		} else {
+			if (!status) {
+				tty->hw_stopped = 1;
+				port->ops->stop_tx(port, 0);
+			}
+		}
+	}
+}
+
+/*
+ *	UART_ENABLE_MS - determine if port should enable modem status irqs
+ */
+#define UART_ENABLE_MS(port,cflag)	((port)->flags & UPF_HARDPPS_CD || \
+					 (cflag) & CRTSCTS || \
+					 !((cflag) & CLOCAL))
+
+#endif
diff -urN linux-2.4.29/include/linux/serial.h linux-2.4.29-uc1/include/linux/serial.h
--- linux-2.4.29/include/linux/serial.h	2002-08-03 01:39:45.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/serial.h	2005-06-14 02:11:37.000000000 +0100
@@ -75,7 +75,11 @@
 #define PORT_16654	11
 #define PORT_16850	12
 #define PORT_RSA	13	/* RSA-DV II/S card */
-#define PORT_MAX	13
+#define PORT_XSCALE	14
+#define PORT_DSC21	15
+#define PORT_C5471	16
+#define PORT_DM270	17
+#define PORT_MAX	17
 
 #define SERIAL_IO_PORT	0
 #define SERIAL_IO_HUB6	1
diff -urN linux-2.4.29/include/linux/serialP.h linux-2.4.29-uc1/include/linux/serialP.h
--- linux-2.4.29/include/linux/serialP.h	2002-08-03 01:39:45.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/serialP.h	2005-06-14 02:11:35.000000000 +0100
@@ -126,11 +126,14 @@
 	int		port_monitor;
 };
 
-#if defined(__alpha__) && !defined(CONFIG_PCI)
+#if (defined(__alpha__) && !defined(CONFIG_PCI)) || defined(CONFIG_SERIAL_CDB4)
 /*
  * Digital did something really horribly wrong with the OUT1 and OUT2
  * lines on at least some ALPHA's.  The failure mode is that if either
  * is cleared, the machine locks up with endless interrupts.
+ *
+ * CDB4 board has the very same problem, so we're using the very same
+ * workaround.
  */
 #define ALPHA_KLUDGE_MCR  (UART_MCR_OUT2 | UART_MCR_OUT1)
 #else
diff -urN linux-2.4.29/include/linux/serial_reg.h linux-2.4.29-uc1/include/linux/serial_reg.h
--- linux-2.4.29/include/linux/serial_reg.h	2001-05-02 00:05:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/serial_reg.h	2005-06-14 02:11:33.000000000 +0100
@@ -119,6 +119,14 @@
 #define UART_IERX_SLEEP  0x10	/* Enable sleep mode */
 
 /*
+ * The Intel PXA250/210 & IXP425 chips define these bits
+ */
+#define UART_IER_DMAE	0x80	/* DMA Requests Enable */
+#define UART_IER_UUE	0x40	/* UART Unit Enable */
+#define UART_IER_NRZE	0x20	/* NRZ coding Enable */
+#define UART_IER_RTOIE	0x10	/* Receiver Time Out Interrupt Enable */
+
+/*
  * These are the definitions for the Modem Control Register
  */
 #define UART_MCR_LOOP	0x10	/* Enable loopback test mode */
diff -urN linux-2.4.29/include/linux/serio.h linux-2.4.29-uc1/include/linux/serio.h
--- linux-2.4.29/include/linux/serio.h	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/serio.h	2005-06-14 02:11:34.000000000 +0100
@@ -110,6 +110,7 @@
 #define SERIO_H3600	0x21
 #define SERIO_PS2SER	0x22
 #define SERIO_HIL	0x25
+#define SERIO_IPOD_REM	0x26
 
 #define SERIO_ID	0xff00UL
 #define SERIO_EXTRA	0xff0000UL
diff -urN linux-2.4.29/include/linux/skbuff.h linux-2.4.29-uc1/include/linux/skbuff.h
--- linux-2.4.29/include/linux/skbuff.h	2004-08-08 00:26:06.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/skbuff.h	2005-06-14 02:11:35.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: skbuff.h,v 1.9 2003/08/08 13:46:35 yoshfuji Exp $ */
+
 /*
  *	Definitions for the 'struct sk_buff' memory handlers.
  *
@@ -82,6 +84,9 @@
 #else
 #define NET_CALLER(arg) __builtin_return_address(0)
 #endif
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
+struct nf_info;
+#endif
 
 #ifdef CONFIG_NETFILTER
 struct nf_conntrack {
@@ -92,6 +97,20 @@
 struct nf_ct_info {
 	struct nf_conntrack *master;
 };
+
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+struct nf_bridge_info {
+	atomic_t use;
+	struct net_device *physindev;
+	struct net_device *physoutdev;
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+	struct net_device *netoutdev;
+#endif
+	unsigned int mask;
+	unsigned long hh[32 / sizeof(unsigned long)];
+};
+#endif
+
 #endif
 
 struct sk_buff_head {
@@ -146,6 +165,7 @@
 		struct tcphdr	*th;
 		struct udphdr	*uh;
 		struct icmphdr	*icmph;
+		struct icmp6hdr	*icmp6h;
 		struct igmphdr	*igmph;
 		struct iphdr	*ipiph;
 		struct spxhdr	*spxh;
@@ -182,7 +202,7 @@
 	unsigned int 	len;			/* Length of actual data			*/
  	unsigned int 	data_len;
 	unsigned int	csum;			/* Checksum 					*/
-	unsigned char 	__unused,		/* Dead field, may be reused			*/
+	unsigned char 	imq_flags,		/* intermediate queueing device	*/
 			cloned, 		/* head may be cloned (check refcnt to be sure). */
   			pkt_type,		/* Packet class					*/
   			ip_summed;		/* Driver fed us an IP checksum			*/
@@ -208,6 +228,9 @@
 #ifdef CONFIG_NETFILTER_DEBUG
         unsigned int nf_debug;
 #endif
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+	struct nf_bridge_info	*nf_bridge;	/* Saved data about a bridged frame - see br_netfilter.c */
+#endif
 #endif /*CONFIG_NETFILTER*/
 
 #if defined(CONFIG_HIPPI)
@@ -219,6 +242,9 @@
 #ifdef CONFIG_NET_SCHED
        __u32           tc_index;               /* traffic control index */
 #endif
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
+       struct nf_info	*nf_info;
+#endif
 };
 
 #ifdef __KERNEL__
@@ -1166,6 +1192,20 @@
 	if (nfct)
 		atomic_inc(&nfct->master->use);
 }
+
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge)
+{
+	if (nf_bridge && atomic_dec_and_test(&nf_bridge->use))
+		kfree(nf_bridge);
+}
+static inline void nf_bridge_get(struct nf_bridge_info *nf_bridge)
+{
+	if (nf_bridge)
+		atomic_inc(&nf_bridge->use);
+}
+#endif
+
 static inline void
 nf_reset(struct sk_buff *skb)
 {
diff -urN linux-2.4.29/include/linux/slab.h linux-2.4.29-uc1/include/linux/slab.h
--- linux-2.4.29/include/linux/slab.h	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/slab.h	2005-06-14 02:11:35.000000000 +0100
@@ -61,6 +61,9 @@
 
 extern void *kmalloc(size_t, int);
 extern void kfree(const void *);
+#ifdef NO_MM
+extern size_t ksize(const void *);
+#endif
 
 extern int FASTCALL(kmem_cache_reap(int));
 
diff -urN linux-2.4.29/include/linux/socket.h linux-2.4.29-uc1/include/linux/socket.h
--- linux-2.4.29/include/linux/socket.h	2005-01-19 14:10:12.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/socket.h	2005-06-14 02:11:36.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: socket.h,v 1.8 2003/11/12 05:11:56 yoshfuji Exp $ */
+
 #ifndef _LINUX_SOCKET_H
 #define _LINUX_SOCKET_H
 
diff -urN linux-2.4.29/include/linux/string.h linux-2.4.29-uc1/include/linux/string.h
--- linux-2.4.29/include/linux/string.h	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/string.h	2005-06-14 02:11:36.000000000 +0100
@@ -13,18 +13,20 @@
 extern "C" {
 #endif
 
-extern char * ___strtok;
-extern char * strpbrk(const char *,const char *);
-extern char * strtok(char *,const char *);
-extern char * strsep(char **,const char *);
-extern __kernel_size_t strspn(const char *,const char *);
-
 
 /*
  * Include machine specific inline routines
  */
 #include <asm/string.h>
 
+#ifndef __HAVE_ARCH_STRTOK
+extern char * ___strtok;
+extern char * strpbrk(const char *,const char *);
+extern char * strtok(char *,const char *);
+extern char * strsep(char **,const char *);
+extern __kernel_size_t strspn(const char *,const char *);
+#endif
+
 #ifndef __HAVE_ARCH_STRCPY
 extern char * strcpy(char *,const char *);
 #endif
diff -urN linux-2.4.29/include/linux/swap.h linux-2.4.29-uc1/include/linux/swap.h
--- linux-2.4.29/include/linux/swap.h	2005-01-19 14:10:12.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/swap.h	2005-06-14 02:11:34.000000000 +0100
@@ -41,12 +41,14 @@
 
 #ifdef __KERNEL__
 
+#ifndef NO_MM
 /*
  * Max bad pages in the new format..
  */
 #define __swapoffset(x) ((unsigned long)&((union swap_header *)0)->x)
 #define MAX_SWAP_BADPAGES \
 	((__swapoffset(magic.magic) - __swapoffset(info.badpages)) / sizeof(int))
+#endif /* NO_MM */
 
 #include <asm/atomic.h>
 
@@ -217,6 +219,8 @@
 #define inc_nr_cache_pages(page) delta_nr_cache_pages(page, 1)
 #define dec_nr_cache_pages(page) delta_nr_cache_pages(page, -1)
 
+#ifndef NO_MM
+
 extern spinlock_t swaplock;
 
 #define swap_list_lock()	spin_lock(&swaplock)
@@ -224,6 +228,8 @@
 #define swap_device_lock(p)	spin_lock(&p->sdev_lock)
 #define swap_device_unlock(p)	spin_unlock(&p->sdev_lock)
 
+#endif /* NO_MM */
+
 extern int shmem_unuse(swp_entry_t entry, struct page *page);
 
 #endif /* __KERNEL__*/
diff -urN linux-2.4.29/include/linux/sysctl.h linux-2.4.29-uc1/include/linux/sysctl.h
--- linux-2.4.29/include/linux/sysctl.h	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/sysctl.h	2005-06-14 02:11:34.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: sysctl.h,v 1.36 2004/01/11 08:19:25 yoshfuji Exp $ */
+
 /*
  * sysctl.h: General linux system control interface
  *
@@ -404,7 +406,13 @@
 	NET_IPV6_ROUTE=18,
 	NET_IPV6_ICMP=19,
 	NET_IPV6_BINDV6ONLY=20,
+	NET_IPV6_IP6FRAG_HIGH_THRESH=21,
+	NET_IPV6_IP6FRAG_LOW_THRESH=22,
+	NET_IPV6_IP6FRAG_TIME=23,
+	/* NET_IPV6_IP6FRAG_SECRET_INTERVAL=24, */
 	NET_IPV6_MLD_MAX_MSF=25,
+	NET_IPV6_BINDV6ONLY_RESTRICTION=26,	/* unofficial */
+	NET_IPV6_MOBILITY=27,			/* unofficial */
 };
 
 enum {
@@ -429,7 +437,14 @@
 	NET_IPV6_DAD_TRANSMITS=7,
 	NET_IPV6_RTR_SOLICITS=8,
 	NET_IPV6_RTR_SOLICIT_INTERVAL=9,
-	NET_IPV6_RTR_SOLICIT_DELAY=10
+	NET_IPV6_RTR_SOLICIT_DELAY=10,
+	NET_IPV6_USE_TEMPADDR=11,
+	NET_IPV6_TEMP_VALID_LFT=12,
+	NET_IPV6_TEMP_PREFERED_LFT=13,
+	NET_IPV6_REGEN_MAX_RETRY=14,
+	NET_IPV6_MAX_DESYNC_FACTOR=15,
+	NET_IPV6_MAX_ADDRESSES=16,	/* unofficial */
+	NET_IPV6_ACCEPT_NI,	/* unofficial */
 };
 
 /* /proc/sys/net/ipv6/icmp */
diff -urN linux-2.4.29/include/linux/udf_fs_sb.h linux-2.4.29-uc1/include/linux/udf_fs_sb.h
--- linux-2.4.29/include/linux/udf_fs_sb.h	2002-08-03 01:39:46.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/udf_fs_sb.h	2005-06-14 02:11:36.000000000 +0100
@@ -18,8 +18,6 @@
 #ifndef _UDF_FS_SB_H
 #define _UDF_FS_SB_H 1
 
-#pragma pack(1)
-
 #define UDF_MAX_BLOCK_LOADED	8
 
 #define UDF_TYPE1_MAP15			0x1511U
@@ -31,13 +29,13 @@
 {
 	__u16	s_packet_len;
 	struct buffer_head *s_spar_map[4];
-};
+} __attribute ((packed));
 
 struct udf_virtual_data
 {
 	__u32	s_num_entries;
 	__u16	s_start_offset;
-};
+} __attribute ((packed));
 
 struct udf_bitmap
 {
@@ -45,7 +43,7 @@
 	__u32			s_extPosition;
 	__u16			s_nr_groups;
 	struct buffer_head 	**s_block_bitmap;
-};
+} __attribute ((packed));
 
 struct udf_part_map
 {
@@ -71,9 +69,7 @@
 	__u32	(*s_partition_func)(struct super_block *, __u32, __u16, __u32);
 	__u16	s_volumeseqnum;
 	__u16	s_partition_flags;
-};
-
-#pragma pack()
+} __attribute ((packed));
 
 struct udf_sb_info
 {
diff -urN linux-2.4.29/include/linux/usagi-version.h linux-2.4.29-uc1/include/linux/usagi-version.h
--- linux-2.4.29/include/linux/usagi-version.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/usagi-version.h	2005-06-14 02:11:35.000000000 +0100
@@ -0,0 +1,3 @@
+/* $USAGI: usagi-version.h,v 1.3 2003/07/11 16:48:47 yoshfuji Exp $ */
+
+#define	USAGI_RELEASE	"usagi-cvs"
diff -urN linux-2.4.29/include/linux/utsname.h linux-2.4.29-uc1/include/linux/utsname.h
--- linux-2.4.29/include/linux/utsname.h	2000-01-27 14:32:14.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/utsname.h	2005-06-14 02:11:33.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: utsname.h,v 1.4 2001/05/26 11:05:48 yoshfuji Exp $ */
+
 #ifndef _LINUX_UTSNAME_H
 #define _LINUX_UTSNAME_H
 
@@ -33,4 +35,10 @@
 extern struct new_utsname system_utsname;
 
 extern struct rw_semaphore uts_sem;
+
+#ifdef CONFIG_IPV6_NODEINFO
+extern void (*icmpv6_sethostname_hook)(struct new_utsname *);
+extern struct rw_semaphore icmpv6_sethostname_hook_sem;
+#endif
+
 #endif
diff -urN linux-2.4.29/include/linux/vmalloc.h linux-2.4.29-uc1/include/linux/vmalloc.h
--- linux-2.4.29/include/linux/vmalloc.h	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/include/linux/vmalloc.h	2005-06-14 02:11:33.000000000 +0100
@@ -8,6 +8,8 @@
 #include <linux/highmem.h>	/* several arch define VMALLOC_END via PKMAP_BASE */
 #include <asm/pgtable.h>
 
+#ifndef NO_MM
+
 /* bits in vm_struct->flags */
 #define VM_IOREMAP	0x00000001	/* ioremap() and friends */
 #define VM_ALLOC	0x00000002	/* vmalloc() */
@@ -64,5 +66,23 @@
 extern rwlock_t vmlist_lock;
 
 extern struct vm_struct * vmlist;
+
+#else /* NO_MM */
+
+/*
+ * vmlist_lock is a read-write spinlock that protects vmlist
+ * Used in mm/vmalloc.c (get_vm_area() and vfree()) and fs/proc/kcore.c.
+ */
+extern rwlock_t vmlist_lock;
+
+extern void vfree(void * addr);
+extern void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot);
+extern long vread(char *buf, char *addr, unsigned long count);
+#define vmalloc(s)		__vmalloc(s, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL)
+#define vmalloc_dma(s)	__vmalloc(s, GFP_KERNEL|GFP_DMA, PAGE_KERNEL)
+#define vmalloc_32(s)	__vmalloc(s, GFP_KERNEL, PAGE_KERNEL)
+
+#endif /* NO_MM */
+
 #endif
 
diff -urN linux-2.4.29/include/linux/watchdog.h linux-2.4.29-uc1/include/linux/watchdog.h
--- linux-2.4.29/include/linux/watchdog.h	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-uc1/include/linux/watchdog.h	2005-06-14 02:11:34.000000000 +0100
@@ -9,6 +9,7 @@
 #ifndef _LINUX_WATCHDOG_H
 #define _LINUX_WATCHDOG_H
 
+#include <asm/types.h>
 #include <linux/ioctl.h>
 
 #define	WATCHDOG_IOCTL_BASE	'W'
diff -urN linux-2.4.29/include/net/addrconf.h linux-2.4.29-uc1/include/net/addrconf.h
--- linux-2.4.29/include/net/addrconf.h	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/include/net/addrconf.h	2005-06-14 02:11:37.000000000 +0100
@@ -1,13 +1,26 @@
+/* $USAGI: addrconf.h,v 1.36 2004/01/11 08:18:16 yoshfuji Exp $ */
+
 #ifndef _ADDRCONF_H
 #define _ADDRCONF_H
 
+#include <net/ipv6.h>
+
 #define RETRANS_TIMER	HZ
 
 #define MAX_RTR_SOLICITATIONS		3
 #define RTR_SOLICITATION_INTERVAL	(4*HZ)
 
+#define TEMP_VALID_LIFETIME		(7*86400)	/* 1 week */
+#define TEMP_PREFERRED_LIFETIME		(86400)		/* 1 day */
+#define REGEN_MAX_RETRY			(5)		/* 5 times */
+#define MAX_DESYNC_FACTOR		(600)		/* 10 minutes */
+
+#define PINFO_VALID_LIFETIME_INFINITE	0xffffffff	/* infinite lifetime */
+
 #define ADDR_CHECK_FREQUENCY		(120*HZ)
 
+#define IPV6_MAX_ADDRESSES		16
+
 struct prefix_info {
 	__u8			type;
 	__u8			length;
@@ -16,9 +29,11 @@
 #if defined(__BIG_ENDIAN_BITFIELD)
 	__u8			onlink : 1,
 			 	autoconf : 1,
-				reserved : 6;
+				router_address : 1,
+				reserved : 5;
 #elif defined(__LITTLE_ENDIAN_BITFIELD)
-	__u8			reserved : 6,
+	__u8			reserved : 5,
+				router_address : 1,
 				autoconf : 1,
 				onlink : 1;
 #else
@@ -31,6 +46,23 @@
 	struct in6_addr		prefix;
 };
 
+struct route_info {
+	__u8			type;
+	__u8			length;
+	__u8			prefix_len;
+#if defined(__BIG_ENDIAN_BITFIELD)
+	__u8			reserved_h : 3,
+				route_pref : 2,
+				reserved_l : 3;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+	__u8			reserved_l : 3,
+				route_pref : 2,
+				reserved_h : 3;
+#endif
+	__u32			lifetime;
+	__u8			prefix[0];
+	/* 0, 8 or 16 octet prefix follows */
+};
 
 #ifdef __KERNEL__
 
@@ -40,6 +72,12 @@
 
 #define IN6_ADDR_HSIZE		16
 
+struct prefix_element {
+	struct list_head list;
+	struct prefix_info pinfo;
+	unsigned long timestamp;
+};
+
 extern void			addrconf_init(void);
 extern void			addrconf_cleanup(void);
 
@@ -55,19 +93,32 @@
 					      struct net_device *dev);
 extern struct inet6_ifaddr *	ipv6_get_ifaddr(struct in6_addr *addr,
 						struct net_device *dev);
+extern int			ipv6_dev_get_saddr(struct net_device *dev,
+						   struct in6_addr *daddr,
+						   struct in6_addr *saddr,
+						   int pref_privacy);
 extern int			ipv6_get_saddr(struct dst_entry *dst, 
 					       struct in6_addr *daddr,
-					       struct in6_addr *saddr);
-extern int			ipv6_dev_get_saddr(struct net_device *dev, 
-					       struct in6_addr *daddr,
 					       struct in6_addr *saddr,
-					       int onlink);
+					       int pref_privacy);
 extern int			ipv6_get_lladdr(struct net_device *dev, struct in6_addr *);
 extern void			addrconf_join_solict(struct net_device *dev,
 					struct in6_addr *addr);
 extern void			addrconf_leave_solict(struct net_device *dev,
 					struct in6_addr *addr);
 
+#define IPV6_ADDR_SCOPE_RESERVED	-2
+#define IPV6_ADDR_SCOPE_ANY		-1
+
+#ifdef CONFIG_IPV6_NODEINFO	/* icmp.c */
+extern void			icmpv6_ni_join_nigroup_dev(struct net_device *dev);
+#endif
+
+#if defined(CONFIG_IPV6_ROUTER_PREF)
+/* route.c */
+int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, struct in6_addr *gwaddr);
+#endif
+
 /*
  *	multicast prototypes (mcast.c)
  */
@@ -110,20 +161,43 @@
 						struct in6_addr *addr);
 extern int			ipv6_chk_acast_addr(struct net_device *dev,
 						struct in6_addr *addr);
+extern struct net_device *	ipv6_get_acast_dev(struct in6_addr *addr);
+
+extern int			addrconf_pfx_adv_rcv(struct net_device *dev,
+						     struct prefix_info *pinfo,
+						     struct in6_addr *home_addr);
+
+extern int ipv6_get_prefix_entries(struct prefix_info **plist,
+				   int ifindex, int plen);
+
+extern int addrconf_pfx_adv_rcv(struct net_device *dev,
+				struct prefix_info *pinfo,
+				struct in6_addr *home_addr);
 
 
 /* Device notifier */
 extern int register_inet6addr_notifier(struct notifier_block *nb);
 extern int unregister_inet6addr_notifier(struct notifier_block *nb);
 
+#ifndef CONFIG_IPV6_DEBUG
 static inline struct inet6_dev *
 __in6_dev_get(struct net_device *dev)
 {
 	return (struct inet6_dev *)dev->ip6_ptr;
 }
+#else
+#define __in6_dev_get(dev)						\
+({									\
+	struct net_device *_dev = (dev);				\
+	if (!_dev)							\
+		panic("__in6_dev_get(dev=NULL): %s\n", __FUNCTION__);	\
+	(struct inet6_dev *)_dev->ip6_ptr;				\
+})
+#endif
 
 extern rwlock_t addrconf_lock;
 
+#ifndef CONFIG_IPV6_DEBUG
 static inline struct inet6_dev *
 in6_dev_get(struct net_device *dev)
 {
@@ -135,30 +209,102 @@
 	read_unlock(&addrconf_lock);
 	return idev;
 }
+#else
+#define in6_dev_get(dev)						\
+({									\
+	struct net_device *_dev = (dev);				\
+	struct inet6_dev *_idev;					\
+	if (!_dev)							\
+		panic("in6_dev_get(dev=NULL): %s\n", __FUNCTION__);	\
+	read_lock(&addrconf_lock);					\
+	_idev = _dev->ip6_ptr;						\
+	if (_idev)							\
+		atomic_inc(&_idev->refcnt);				\
+	read_unlock(&addrconf_lock);					\
+	_idev;								\
+})
+#endif
 
 extern void in6_dev_finish_destroy(struct inet6_dev *idev);
 
+#ifndef CONFIG_IPV6_DEBUG
 static inline void
 in6_dev_put(struct inet6_dev *idev)
 {
 	if (atomic_dec_and_test(&idev->refcnt))
 		in6_dev_finish_destroy(idev);
 }
+#else
+#define in6_dev_put(idev)						\
+({									\
+	struct inet6_dev *_idev = (idev);				\
+	if (!_idev)							\
+		panic("in6_dev_put(idev=NULL): %s\n",			\
+			__FUNCTION__);					\
+	if (atomic_dec_and_test(&_idev->refcnt))			\
+		in6_dev_finish_destroy(_idev);				\
+})
+#endif
 
+#ifndef CONFIG_IPV6_DEBUG
 #define __in6_dev_put(idev)  atomic_dec(&(idev)->refcnt)
 #define in6_dev_hold(idev)   atomic_inc(&(idev)->refcnt)
+#else
+#define __in6_dev_put(idev)						\
+({									\
+	struct inet6_dev *_idev = (idev);				\
+	if (!_idev)							\
+		panic("__in6_dev_put(idev=NULL): %s\n", __FUNCTION__);	\
+	atomic_dec(&_idev->refcnt);					\
+})
+#define in6_dev_hold(idev)						\
+({									\
+	struct inet6_dev *_idev = (idev);				\
+	if (!_idev)							\
+		panic("in6_dev_hold(idev=NULL): %s\n", __FUNCTION__);	\
+	atomic_inc(&_idev->refcnt);					\
+})
+#endif
 
 
 extern void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp);
 
+#ifndef CONFIG_IPV6_DEBUG
 static inline void in6_ifa_put(struct inet6_ifaddr *ifp)
 {
 	if (atomic_dec_and_test(&ifp->refcnt))
 		inet6_ifa_finish_destroy(ifp);
 }
+#else
+#define in6_ifa_put(ifp)						\
+({									\
+	struct inet6_ifaddr *_ifp = (ifp);				\
+	if (!_ifp)							\
+		panic("in6_ifa_put(ifp=NULL): %s\n", __FUNCTION__);	\
+	if (atomic_dec_and_test(&_ifp->refcnt))				\
+		inet6_ifa_finish_destroy(_ifp);				\
+})
+#endif
 
-#define __in6_ifa_put(idev)  atomic_dec(&(idev)->refcnt)
-#define in6_ifa_hold(idev)   atomic_inc(&(idev)->refcnt)
+#ifndef CONFIG_IPV6_DEBUG
+#define __in6_ifa_put(ifp)  atomic_dec(&(ifp)->refcnt)
+#define in6_ifa_hold(ifp)   atomic_inc(&(ifp)->refcnt)
+#else
+#define __in6_ifa_put(ifp)						\
+({									\
+	struct inet6_ifaddr *_ifp = (ifp);				\
+	if (!_ifp)							\
+		panic("__in6_ifa_put(ifp=NULL): %s\n", __FUNCTION__);	\
+	atomic_dec(&_ifp->refcnt);					\
+})
+#define in6_ifa_hold(ifp)						\
+({									\
+	struct inet6_ifaddr *_ifp = (ifp);				\
+	if (!_ifp)							\
+		panic("in6_ifa_hold(ifp=NULL): %s\n", __FUNCTION__);	\
+	atomic_inc(&_ifp->refcnt);					\
+})
+#endif
 
 
 extern void			addrconf_forwarding_on(void);
diff -urN linux-2.4.29/include/net/atmipv6.h linux-2.4.29-uc1/include/net/atmipv6.h
--- linux-2.4.29/include/net/atmipv6.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/net/atmipv6.h	2005-06-14 02:11:37.000000000 +0100
@@ -0,0 +1,83 @@
+/* $USAGI: atmipv6.h,v 1.4 2003/05/28 23:27:31 yoshfuji Exp $
+ *
+ * RFC2492 IPv6 over ATM
+ *
+ * Copyright (C)2001 USAGI/WIDE Project
+ *
+ * Written by Kazuyoshi SERIZAWA, based on atmarp.h - RFC1577 ATM ARP
+ * Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA
+ */
+ 
+#ifndef _ATMIPV6_H
+#define _ATMIPV6_H
+
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/atm.h>
+#include <linux/atmdev.h>
+#include <linux/atmarp.h>
+#include <linux/spinlock.h>
+#include <net/neighbour.h>
+
+
+#define CLIP6_VCC(vcc) ((struct clip6_vcc *) ((vcc)->user_back))
+//#define NEIGH2ENTRY(neigh) ((struct atmarp_entry *) (neigh)->primary_key)
+
+
+struct clip6_vcc {
+	struct atm_vcc	*vcc;		/* VCC descriptor */
+	struct atmarp_entry *entry;	/* ATMARP table entry, NULL if IP addr.
+					   isn't known yet */
+	int		xoff;		/* 1 if send buffer is full */
+	unsigned char	encap;		/* 0: NULL, 1: LLC/SNAP */
+	unsigned long	last_use;	/* last send or receive operation */
+	unsigned long	idle_timeout;	/* keep open idle for so many jiffies*/
+	void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb);
+					/* keep old push fn for chaining */
+	void (*old_pop)(struct atm_vcc *vcc,struct sk_buff *skb);
+					/* keep old pop fn for chaining */
+	struct clip6_vcc	*next;		/* next VCC */
+        struct net_device *dev;   	/* network interface. */
+};
+
+#if 0
+struct atmarp_entry {
+	u32		ip;		/* IP address */
+	struct clip_vcc	*vccs;		/* active VCCs; NULL if resolution is
+					   pending */
+	unsigned long	expires;	/* entry expiration time */
+	struct neighbour *neigh;	/* neighbour back-pointer */
+};
+#endif /* if 0 */
+
+//TODO:
+#define PRIV(dev) ((struct clip6_priv *) ((struct net_device *) (dev)+1))
+#define PRIV6(dev) ((struct clip6_priv *) ((struct net_device *) (dev)+1))
+
+
+struct clip6_priv {
+	int number;			/* for convenience ... */
+	spinlock_t xoff_lock;		/* ensures that pop is atomic (SMP) */
+	struct net_device_stats stats;
+	struct net_device *next;	/* next CLIP6 interface */
+  	struct clip6_vcc	*vccs;		/* active VCCs; NULL if resolution is
+					   pending */
+//	struct atm_vcc vccc;		/* vcc ToDo: del*/
+	struct atm_vcc *vcc;		/* vcc */
+};
+
+
+//extern struct atm_vcc *atmarpd; /* ugly */
+//extern struct neigh_table clip6_tbl;
+
+int clip6_create(int number);
+int clip6_mkip(struct atm_vcc *vcc,int timeout);
+int clip6_encap(struct atm_vcc *vcc,int mode);
+
+int clip6_set_vcc_netif(struct socket *sock,int number);
+
+void clip6_push(struct atm_vcc *vcc,struct sk_buff *skb);
+
+void atm_clip6_init(void);
+
+#endif
diff -urN linux-2.4.29/include/net/if_inet6.h linux-2.4.29-uc1/include/net/if_inet6.h
--- linux-2.4.29/include/net/if_inet6.h	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/include/net/if_inet6.h	2005-06-14 02:11:37.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: if_inet6.h,v 1.27 2003/11/12 05:11:56 yoshfuji Exp $ */
+
 /*
  *	inet6 interface/address list definitions
  *	Linux INET6 implementation 
@@ -15,12 +17,14 @@
 #ifndef _NET_IF_INET6_H
 #define _NET_IF_INET6_H
 
+#include <net/snmp.h>
+#include <linux/ipv6_route.h>
 #include <linux/ipv6.h>
 
 #define IF_RA_OTHERCONF	0x80
 #define IF_RA_MANAGED	0x40
-#define IF_RA_RCVD	0x20
-#define IF_RS_SENT	0x10
+#define IF_RA_RCVD	0x20	/* for inet6_dev.if_flags */
+#define IF_RS_SENT	0x10	/* for inet6_dev.if_flags */
 
 #ifdef __KERNEL__
 
@@ -47,6 +51,13 @@
 	struct inet6_ifaddr	*lst_next;      /* next addr in addr_lst */
 	struct inet6_ifaddr	*if_next;       /* next addr in inet6_dev */
 
+#ifdef CONFIG_IPV6_PRIVACY
+	struct inet6_ifaddr	*tmp_next;	/* next addr in tempaddr_lst */
+	struct inet6_ifaddr	*ifpub;
+
+	int			regen_count;
+#endif
+
 	int			dead;
 };
 
@@ -128,6 +139,26 @@
 #define	IFA_SITE	IPV6_ADDR_SITELOCAL
 #define	IFA_GLOBAL	0x0000U
 
+/* XXX: put this into include/linux/in6.h (or so) as in6_prefix{} ? */
+struct ipv6_prefix {
+	struct in6_addr		ip6p_prefix;	/* prefix */
+	__u32			ip6p_len;	/* prefix length */
+};
+
+struct inet6_prefix {
+	struct 	list_head	list;		/* list of prefixes */
+	struct in6_addr		prefix;		/* prefix */
+	__u32			prefix_len;	/* prefix length */
+	__u32			lifetime;	/* lifetime for prefix */
+	unsigned long		timestamp;	/* last jiffies updated */
+};
+
+struct ipv6_devstat{
+	struct proc_dir_entry *	proc_dir_entry;
+	struct ipv6_mib		ipv6[NR_CPUS*2];	/* RFC 2465 */
+	struct icmpv6_mib	icmpv6[NR_CPUS*2];	/* RFC 2466 */
+};
+
 struct inet6_dev 
 {
 	struct net_device		*dev;
@@ -146,16 +177,32 @@
 	struct timer_list	mc_ifc_timer;	/* interface change timer */
 
 	struct ifacaddr6	*ac_list;
+	struct list_head	prefix_list;
+	rwlock_t		prefix_lock;
+	int			prefix_count;
 	rwlock_t		lock;
 	atomic_t		refcnt;
 	__u32			if_flags;
 	int			dead;
 
+#ifdef CONFIG_IPV6_ZONE
+	struct ip6_zoneid	zone;
+#endif
+	
+#ifdef CONFIG_IPV6_PRIVACY
+	u8			rndid[8];
+	u8			entropy[8];
+	struct timer_list	regen_timer;
+	struct inet6_ifaddr	*tempaddr_list;
+#endif
+
 	struct neigh_parms	*nd_parms;
 	struct inet6_dev	*next;
 	struct ipv6_devconf	cnf;
+	struct ipv6_devstat	stats;
 };
 
+#define IM_IPV6_DEVCONF	"ipv6_devconf"
 extern struct ipv6_devconf ipv6_devconf;
 
 static inline void ipv6_eth_mc_map(struct in6_addr *addr, char *buf)
diff -urN linux-2.4.29/include/net/ip6_route.h linux-2.4.29-uc1/include/net/ip6_route.h
--- linux-2.4.29/include/net/ip6_route.h	2003-06-13 15:51:39.000000000 +0100
+++ linux-2.4.29-uc1/include/net/ip6_route.h	2005-06-14 02:11:37.000000000 +0100
@@ -1,10 +1,14 @@
+/* $USAGI: ip6_route.h,v 1.15 2003/12/25 00:41:00 yoshfuji Exp $ */
+
 #ifndef _NET_IP6_ROUTE_H
 #define _NET_IP6_ROUTE_H
 
 #define IP6_RT_PRIO_FW		16
-#define IP6_RT_PRIO_USER	1024
+#define IP6_RT_PRIO_MIPV6      	64
 #define IP6_RT_PRIO_ADDRCONF	256
 #define IP6_RT_PRIO_KERN	512
+#define IP6_RT_PRIO_USER	1024
+#define IP6_RT_PRIO_ALLONLINK	2048
 #define IP6_RT_FLOW_MASK	0x00ff
 
 #ifdef __KERNEL__
@@ -56,6 +60,9 @@
 					   int dstlen, int srclen,
 					   int metric, __u32 flags);
 
+#define RT6_LOOKUP_FLAG_STRICT	0x1
+#define RT6_LOOKUP_FLAG_NOUSE	0x2
+
 extern struct rt6_info		*rt6_lookup(struct in6_addr *daddr,
 					    struct in6_addr *saddr,
 					    int oif, int flags);
@@ -67,13 +74,16 @@
 extern struct rt6_info *	rt6_get_dflt_router(struct in6_addr *addr,
 						    struct net_device *dev);
 extern struct rt6_info *	rt6_add_dflt_router(struct in6_addr *gwaddr,
-						    struct net_device *dev);
+						    struct net_device *dev,
+						    int pref);
+extern struct rt6_info *	rt6_exist_dflt_router(void);
 
 extern void			rt6_purge_dflt_routers(int lst_resort);
 
 extern void			rt6_redirect(struct in6_addr *dest,
 					     struct in6_addr *saddr,
 					     struct neighbour *neigh,
+					     u8 *lladdr,
 					     int on_link);
 
 extern void			rt6_pmtu_discovery(struct in6_addr *daddr,
@@ -99,7 +109,8 @@
  */
 
 static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
-				     struct in6_addr *daddr)
+				 struct in6_addr *daddr, 
+				 struct in6_addr *saddr)
 {
 	struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
 	struct rt6_info *rt = (struct rt6_info *) dst;
@@ -107,9 +118,16 @@
 	write_lock(&sk->dst_lock);
 	__sk_dst_set(sk, dst);
 	np->daddr_cache = daddr;
+#ifdef CONFIG_IPV6_SUBTREES
+	np->saddr_cache = saddr;
+#endif
 	np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
 	write_unlock(&sk->dst_lock);
 }
 
+/* Netfilter */
+#ifdef CONFIG_NETFILTER
+int route6_me_harder(struct sk_buff *skb);
+#endif
 #endif
 #endif
diff -urN linux-2.4.29/include/net/ipip.h linux-2.4.29-uc1/include/net/ipip.h
--- linux-2.4.29/include/net/ipip.h	2001-04-12 20:11:39.000000000 +0100
+++ linux-2.4.29-uc1/include/net/ipip.h	2005-06-14 02:11:37.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: ipip.h,v 1.3 2001/07/16 11:13:28 yoshfuji Exp $ */
+
 #ifndef __NET_IPIP_H
 #define __NET_IPIP_H 1
 
@@ -46,6 +48,9 @@
 
 
 extern int	ipip_init(void);
+#ifdef CONFIG_NET_IPIP_IPV6
+struct ip_tunnel *ipip_tunnel_lookup(u32 remote, u32 local);
+#endif
 extern int	ipgre_init(void);
 extern int	sit_init(void);
 extern void	sit_cleanup(void);
diff -urN linux-2.4.29/include/net/ipv6.h linux-2.4.29-uc1/include/net/ipv6.h
--- linux-2.4.29/include/net/ipv6.h	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/include/net/ipv6.h	2005-06-14 02:11:37.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: ipv6.h,v 1.34 2003/11/12 05:11:57 yoshfuji Exp $ */
+
 /*
  *	Linux INET6 implementation
  *
@@ -37,6 +39,7 @@
 #define NEXTHDR_ICMP		58	/* ICMP for IPv6. */
 #define NEXTHDR_NONE		59	/* No next header */
 #define NEXTHDR_DEST		60	/* Destination options header. */
+#define NEXTHDR_MH		0xd2	/* Mobility header */
 
 #define NEXTHDR_MAX		255
 
@@ -104,16 +107,31 @@
 
 /* sysctls */
 extern int sysctl_ipv6_bindv6only;
+extern int sysctl_ipv6_bindv6only_restriction;
+#define IM_IPV6_SYSCTL_BINDV6ONLY_RESTRICTION	"sysctl_ipv6_bindv6only_restriction"
 extern int sysctl_mld_max_msf;
 
+/* mib */
 extern struct ipv6_mib		ipv6_statistics[NR_CPUS*2];
-#define IP6_INC_STATS(field)		SNMP_INC_STATS(ipv6_statistics, field)
-#define IP6_INC_STATS_BH(field)		SNMP_INC_STATS_BH(ipv6_statistics, field)
-#define IP6_INC_STATS_USER(field) 	SNMP_INC_STATS_USER(ipv6_statistics, field)
+#define IP6_INC_STATS(idev,field)	({if (idev) \
+						SNMP_INC_STATS(idev->stats.ipv6, field); \
+					  SNMP_INC_STATS(ipv6_statistics, field);})
+#define IP6_INC_STATS_BH(idev,field)	({if (idev) \
+						SNMP_INC_STATS(idev->stats.ipv6, field); \
+					  SNMP_INC_STATS_BH(ipv6_statistics, field);})
+#define IP6_INC_STATS_USER(idev,field) 	({if (idev) \
+						SNMP_INC_STATS(idev->stats.ipv6, field); \
+					SNMP_INC_STATS_USER(ipv6_statistics, field);})
 extern struct icmpv6_mib	icmpv6_statistics[NR_CPUS*2];
-#define ICMP6_INC_STATS(field)		SNMP_INC_STATS(icmpv6_statistics, field)
-#define ICMP6_INC_STATS_BH(field)	SNMP_INC_STATS_BH(icmpv6_statistics, field)
-#define ICMP6_INC_STATS_USER(field) 	SNMP_INC_STATS_USER(icmpv6_statistics, field)
+#define ICMP6_INC_STATS(idev,field)	({if (idev) \
+						SNMP_INC_STATS(idev->stats.icmpv6, field); \
+					SNMP_INC_STATS(icmpv6_statistics, field);})
+#define ICMP6_INC_STATS_BH(idev,field)	({if (idev) \
+						SNMP_INC_STATS(idev->stats.icmpv6, field); \
+					SNMP_INC_STATS_BH(icmpv6_statistics, field);})
+#define ICMP6_INC_STATS_USER(idev,field) ({if (idev) \
+						SNMP_INC_STATS(idev->stats.icmpv6, field); \
+					SNMP_INC_STATS_USER(icmpv6_statistics, field);})
 extern struct udp_mib		udp_stats_in6[NR_CPUS*2];
 #define UDP6_INC_STATS(field)		SNMP_INC_STATS(udp_stats_in6, field)
 #define UDP6_INC_STATS_BH(field)	SNMP_INC_STATS_BH(udp_stats_in6, field)
@@ -148,7 +166,7 @@
 
 	struct ipv6_opt_hdr	*hopopt;
 	struct ipv6_opt_hdr	*dst0opt;
-	struct ipv6_rt_hdr	*srcrt;	/* Routing Header */
+	struct ipv6_rt_hdr	*srcrt;	/* Routing Header Type 0 */
 	struct ipv6_opt_hdr	*auth;
 	struct ipv6_opt_hdr	*dst1opt;
 
@@ -203,7 +221,7 @@
 
 extern int			ipv6_parse_hopopts(struct sk_buff *skb, int);
 
-extern int			ipv6_parse_exthdrs(struct sk_buff **skb, int);
+extern int			ipv6_parse_exthdrs(struct sk_buff **skb, int, u8* nexthdr);
 
 extern struct ipv6_txoptions *  ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt);
 
@@ -222,11 +240,25 @@
 					   unsigned int, unsigned int);
 
 
-extern int		ipv6_addr_type(const struct in6_addr *addr);
+extern int		__ipv6_addr_type(const struct in6_addr *addr);
+static inline int	ipv6_addr_type(const struct in6_addr *addr)
+{
+	return __ipv6_addr_type(addr) & 0xffff;
+}
 
 static inline int ipv6_addr_scope(const struct in6_addr *addr)
 {
-	return ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK;
+	return __ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK;
+}
+
+static inline int __ipv6_addr_src_scope(int type)
+{
+	return type == IPV6_ADDR_ANY ? __IPV6_ADDR_SCOPE_INVALID : type>>16;
+}
+
+static inline int ipv6_addr_src_scope(struct in6_addr *addr)
+{
+	return __ipv6_addr_src_scope(__ipv6_addr_type(addr));
 }
 
 static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2)
@@ -234,6 +266,69 @@
 	return memcmp((const void *) a1, (const void *) a2, sizeof(struct in6_addr));
 }
 
+/* find 1st bit in difference between the 2 addrs */
+static inline int u32_addr_diff(const void *__a1, const void *__a2, int addrlen)
+{
+	/* find 1st bit in difference between the 2 addrs.
+
+           bit may be an invalid value,
+           but if it is >= plen, the value is ignored in any case.
+         */
+
+	const u32 *a1 = __a1;
+	const u32 *a2 = __a2;
+	int i;
+
+	addrlen >>= 2;
+	for (i = 0; i < addrlen; i++) {
+		u32 xb = a1[i] ^ a2[i];
+		if (xb) {
+			int j = 31;
+			xb = ntohl(xb);
+			while ((xb & (1 << j)) == 0)
+				j--;
+			return (i * 32 + 31 - j);
+		}
+	}
+	return addrlen<<5;
+}
+
+static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_addr *a2)
+{
+	return u32_addr_diff(a1->s6_addr, a2->s6_addr, sizeof(struct in6_addr));
+}
+
+/* compare ipv6 address prefix (0 vs !0) */
+static inline int u32_prefix_cmp(const void *__a1, const void *__a2, int plen)
+{
+	const u32 *a1 = __a1;
+	const u32 *a2 = __a2;
+	int w, b;
+
+	if (plen <= 0)
+		return 0;
+
+	w = plen >> 5;		/* num of whole u32 in prefix */
+	b = plen & 0x1f;	/* num of bits in incomplete u32 in prefix */
+
+	if (w) {
+		if (memcmp(a1, a2, w << 2))
+			return !0;
+	}
+	if (b) {
+		u32 mask = htonl(~0 << (32 - b));
+		return (a1[w] ^ a2[w]) & mask;
+	}
+	return 0;
+}
+
+static inline int ipv6_prefix_cmp(const struct in6_addr *a1, const struct in6_addr *a2, int plen)
+{
+	if (plen > 128)
+		plen = 128;
+	return u32_prefix_cmp(a1->s6_addr, a2->s6_addr, plen);
+}
+
 static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2)
 {
 	memcpy((void *) a1, (const void *) a2, sizeof(struct in6_addr));
@@ -257,6 +352,34 @@
 		 a->s6_addr32[2] | a->s6_addr32[3] ) == 0); 
 }
 
+static void inline u32_addr_prefix(void *__prefix,
+				   const void *__addr, int plen)
+{
+	u8 *prefix = __prefix;
+	const u8 *addr = __addr;
+	int ncopy, nbits;
+
+	if (plen <= 0)
+		return;
+
+	ncopy = plen >> 3;
+	nbits = plen & 7;
+
+	memcpy(prefix, addr, ncopy);
+	if (ncopy < 16)
+		memset(&prefix[ncopy], 0, 16 - ncopy);
+	if (nbits)
+		prefix[ncopy] = addr[ncopy] & (0xff00 >> nbits);
+}
+
+static void inline ipv6_addr_prefix(struct in6_addr *prefix,
+				    const struct in6_addr *addr, int plen)
+{
+	if (plen > 128)
+		plen = 128;
+	u32_addr_prefix(prefix->s6_addr32, addr->s6_addr32, plen);
+}
+
 /*
  *	Prototypes exported by ipv6
  */
@@ -290,7 +413,7 @@
 					       struct flowi *fl,
 					       unsigned length,
 					       struct ipv6_txoptions *opt,
-					       int hlimit, int flags);
+					       int hlimit, int tclass, int flags);
 
 /*
  *	skb processing functions
@@ -323,7 +446,6 @@
 
 extern int			ipv6_skip_exthdr(const struct sk_buff *, int start,
 					         u8 *nexthdrp, int len);
-
 extern int 			ipv6_ext_hdr(u8 nexthdr);
 
 extern struct ipv6_txoptions *	ipv6_invert_rthdr(struct sock *sk,
@@ -354,6 +476,16 @@
 						u32 info, u8 *payload);
 extern void			ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info);
 
+/* for MIPL */
+extern struct net_proto_family inet6_family_ops;
+
+/*
+ * reassembly.c
+ */
+extern int sysctl_ip6frag_high_thresh;
+extern int sysctl_ip6frag_low_thresh;
+extern int sysctl_ip6frag_time;
+
 extern int inet6_release(struct socket *sock);
 extern int inet6_bind(struct socket *sock, struct sockaddr *uaddr, 
 		      int addr_len);
diff -urN linux-2.4.29/include/net/ipv6_tunnel.h linux-2.4.29-uc1/include/net/ipv6_tunnel.h
--- linux-2.4.29/include/net/ipv6_tunnel.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/net/ipv6_tunnel.h	2005-06-14 02:11:37.000000000 +0100
@@ -0,0 +1,78 @@
+/*
+ * $Id: s.ipv6_tunnel.h 1.7 02/08/09 14:09:15-00:00 ville $
+ */
+
+#ifndef _NET_IPV6_TUNNEL_H
+#define _NET_IPV6_TUNNEL_H
+
+#include <linux/ipv6.h>
+#include <linux/netdevice.h>
+#include <linux/ipv6_tunnel.h>
+#include <linux/skbuff.h>
+#include <asm/atomic.h>
+
+#define IPV6_TNL_MAX 128
+
+/* IPv6 tunnel */
+
+struct ipv6_tnl {
+	struct ipv6_tnl *next;	/* next tunnel in list */
+	struct net_device *dev;	/* virtual device associated with tunnel */
+	struct net_device_stats stat;	/* statistics for tunnel device */
+	int recursion;		/* depth of hard_start_xmit recursion */
+	struct ipv6_tnl_parm parms;	/* tunnel configuration paramters */
+	struct flowi fl;	/* flowi template for xmit */
+	atomic_t refcnt;	/* nr of identical tunnels used by kernel */
+};
+
+#define IPV6_TNL_PRE_ENCAP 0
+#define IPV6_TNL_PRE_DECAP 1
+#define IPV6_TNL_MAXHOOKS 2
+
+#define IPV6_TNL_DROP 0
+#define IPV6_TNL_ACCEPT 1
+#define IPV6_TNL_STOLEN 2
+
+typedef int ipv6_tnl_hookfn(struct ipv6_tnl *t, struct sk_buff *skb);
+
+struct ipv6_tnl_hook_ops {
+	struct list_head list;
+	unsigned int hooknum;
+	int priority;
+	ipv6_tnl_hookfn *hook;
+};
+
+enum ipv6_tnl_hook_priorities {
+	IPV6_TNL_PRI_FIRST = INT_MIN,
+	IPV6_TNL_PRI_LAST = INT_MAX
+};
+
+/* Tunnel encapsulation limit destination sub-option */
+
+struct ipv6_tlv_tnl_enc_lim {
+	__u8 type;		/* type-code for option         */
+	__u8 length;		/* option length                */
+	__u8 encap_limit;	/* tunnel encapsulation limit   */
+} __attribute__ ((packed));
+
+#ifdef __KERNEL__
+extern struct ipv6_tnl *ipv6_ipv6_tnl_lookup(struct in6_addr *remote,
+					     struct in6_addr *local);
+
+extern int ipv6_ipv6_kernel_tnl_add(struct ipv6_tnl_parm *p);
+
+extern int ipv6_ipv6_kernel_tnl_del(struct ipv6_tnl *t);
+
+extern unsigned int ipv6_ipv6_tnl_inc_max_kdev_count(unsigned int n);
+
+extern unsigned int ipv6_ipv6_tnl_dec_max_kdev_count(unsigned int n);
+
+extern unsigned int ipv6_ipv6_tnl_inc_min_kdev_count(unsigned int n);
+
+extern unsigned int ipv6_ipv6_tnl_dec_min_kdev_count(unsigned int n);
+
+extern void ipv6_ipv6_tnl_register_hook(struct ipv6_tnl_hook_ops *reg);
+
+extern void ipv6_ipv6_tnl_unregister_hook(struct ipv6_tnl_hook_ops *reg);
+#endif
+#endif
diff -urN linux-2.4.29/include/net/irda/ep93xx_irda.h linux-2.4.29-uc1/include/net/irda/ep93xx_irda.h
--- linux-2.4.29/include/net/irda/ep93xx_irda.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/net/irda/ep93xx_irda.h	2005-06-14 02:11:37.000000000 +0100
@@ -0,0 +1,279 @@
+ /*********************************************************************
+ *                
+ * Filename:      ep93xx_irda.h
+ * Version:       0.2
+ * Description:   Header for the EP93xx SOC IrDA driver.
+ * Status:        Experimental.
+ *
+ * Copyright 2003 Cirrus Logic, Inc.
+ *
+ * Based on the ali-ircc.c implementation:
+ *      Author:        Benjamin Kong <benjamin_kong@ali.com.tw>
+ *      Created at:    2000/10/16 03:46PM
+ *      Modified at:   2001/1/3 02:55PM
+ *      Modified by:   Benjamin Kong <benjamin_kong@ali.com.tw>
+ * 
+ *      Copyright (c) 2000 Benjamin Kong <benjamin_kong@ali.com.tw>
+ *      All Rights Reserved
+ *      
+ *      This program is free software; you can redistribute it and/or 
+ *      modify it under the terms of the GNU General Public License as 
+ *      published by the Free Software Foundation; either version 2 of 
+ *      the License, or (at your option) any later version.
+ *  
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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:
+ *      Free Software Foundation, Inc.
+ *      59 Temple Place, Suite 330 
+ *      Boston, MA  02111-1307  USA
+ ********************************************************************/
+
+
+#ifndef EP93XX_IRDA_H
+#define EP93XX_IRDA_H
+
+#include <linux/time.h>
+
+#include <linux/spinlock.h>
+#include <linux/pm.h>
+#include <asm/io.h>
+//#include <regmap.h>
+//#include <regs_syscon.h>
+
+
+/*
+ * Number of DMA channels used
+ */
+#define DMA_COUNT 3
+
+/*
+ * TX/RX window queues
+ */
+#define MAX_TX_WINDOW 7
+#define MAX_RX_WINDOW 7
+
+
+struct ep93xx_chip 
+{
+    char *name;
+    int iSIR_IRQ, iMFIR_IRQ;
+    ep93xx_dma_dev_t eSIR_DMATx;
+    ep93xx_dma_dev_t eMFIR_DMATx;
+    ep93xx_dma_dev_t eMFIR_DMARx;
+	int (*init)(struct ep93xx_chip *chip); 
+};
+
+typedef struct ep93xx_chip ep93xx_chip_t;
+
+/* For storing entries in the status FIFO */
+
+struct st_fifo_entry 
+{
+	int status;
+	int len;
+};
+
+struct st_fifo 
+{
+	struct st_fifo_entry entries[MAX_RX_WINDOW];
+	int pending_bytes;
+	int head;
+	int tail;
+	int len;
+};
+
+struct frame_cb 
+{
+	void *start; /* Start of frame in DMA mem */
+	int len;     /* Lenght of frame in DMA mem */
+};
+
+struct tx_fifo 
+{
+	struct frame_cb queue[MAX_TX_WINDOW]; /* Info about frames in queue */
+	int             ptr;                  /* Currently being sent */
+	int             len;                  /* Length of queue */
+	int             free;                 /* Next free slot */
+	void           *tail;                 /* Next free start in DMA mem */
+};
+
+/* Private data for each instance */
+struct ep93xx_irda_cb 
+{
+	struct st_fifo st_fifo;         /* Info about received frames */
+	struct tx_fifo tx_fifo;         /* Info about frames to be transmitted */
+
+	struct net_device *netdev;      /* Net device pointer */
+	struct net_device_stats stats;  /* Net device stats */
+	
+	struct irlap_cb *irlap;         /* The link layer we are binded with */
+	struct qos_info qos;            /* QoS capabilities for this device */
+
+    int iSIR_irq, iMFIR_irq;        /* Interrupts used */
+
+    ep93xx_dma_dev_t ePorts[DMA_COUNT];     /* DMA port ids */
+
+    int iDMAh[DMA_COUNT];          /* handles for DMA channels */
+    dma_addr_t rx_dmaphysh, tx_dmaphysh;
+
+    int fifo_size;                  /* FIFO size */
+    iobuff_t tx_buff;               /* Transmit buffer */
+    iobuff_t rx_buff;               /* Receive buffer */
+
+    char *conv_buf;                 /* Buffer used for SIR conversion */
+
+    struct timeval stamp;           /* ? */
+	struct timeval now;             /* ? */
+
+	spinlock_t lock;                /* Used for serializing operations */
+	
+	__u32 flags;                    /* Interface flags */
+
+    __u8 direction;                 /* TX/RX flag */
+
+    __u32 speed;                    /* Currently used speed */
+    __u32 new_speed;                /* New target tx/rx speed */
+
+	int index;                      /* Instance index */
+	
+  	int suspended;                  /* APM suspend flag */
+    struct pm_dev *dev;             /* Power Management device */
+
+};
+
+
+/*
+ * DMA array handle index meanings
+ */
+#define DMA_SIR_TX                          0
+#define DMA_MFIR_TX                         1
+#define DMA_MFIR_RX                         2
+
+/*
+ * Directional defines
+ */
+#define DIR_TX                              0x01
+#define DIR_RX                              0x02
+#define DIR_BOTH                            0x03
+
+/*
+ * Modes support flag defines.
+ */
+#define CLK_SIR				    0x01
+#define CLK_MIR				    0x02
+#define CLK_FIR				    0x04
+
+/* Name friendly bit defines for register accesses */
+
+/* UART2/SIR */
+#define U2RSR_OvnErr                        0x08
+#define U2RSR_BrkErr                        0x04
+#define U2RSR_PtyErr                        0x02
+#define U2RSR_FrmErr                        0x01
+
+#define U2CRH_WLen                          0x60
+#define U2CRH_FEn                           0x10
+#define U2CRH_Stp2                          0x08
+#define U2CRH_EPS                           0x04
+#define U2CRH_PEn                           0x02
+#define U2CRH_Brk                           0x01
+
+#define U2CR_LoopBk                         0x80
+#define U2CR_RxTO                           0x40
+#define U2CR_TxIrq                          0x20
+#define U2CR_RxIrq                          0x10
+#define U2CR_MdmStsIrq                      0x08
+#define U2CR_SIRLowPwr                      0x04
+#define U2CR_SIR                            0x02
+#define U2CR_UART                           0x01
+
+#define U2FR_TXFE                           0x80
+#define U2FR_RXFF                           0x40
+#define U2FR_TXFF                           0x20
+#define U2FR_RXFE                           0x10
+#define U2FR_BUSY                           0x08
+#define U2FR_DCD                            0x04
+#define U2FR_DSR                            0x02
+#define U2FR_CTS                            0x01
+
+#define U2IICR_RXTOIRQ                      0x08
+#define U2IICR_TXIRQ                        0x04
+#define U2IICR_RXIRQ                        0x02
+#define U2IICR_MDMIRQ                       0x01
+
+#define U2DMACR_DMAErr                      0x04
+#define U2DMACR_TXDMA                       0x02
+#define U2DMACR_RXDMA                       0x01
+
+
+#define IrENABLE_SIR                        0x01
+
+
+/* IrDA block - MIR/FIR */
+#define IrENABLE_FIR                        0x03
+#define IrENABLE_MIR                        0x02
+
+#define IrCONTROL_RXRP                      0x40
+#define IrCONTROL_TXRP                      0x20
+#define IrCONTROL_RXON                      0x10
+#define IrCONTROL_TXON                      0x08
+#define IrCONTROL_TXUNDER                   0x04
+#define IrCONTROL_MIRBR                     0x02
+
+
+#define IrFLAG_TXBUSY                       0x200
+#define IrFLAG_RXINFRM                      0x100
+#define IrFLAG_RXSYNC                       0x80
+#define IrFLAG_EOF                          0x40
+#define IrFLAG_WIDTHST                      0x30
+#define IrFLAG_FIRFE                        0x08
+#define IrFLAG_RXOR                         0x04
+#define IrFLAG_CRCERR                       0x02
+#define IrFLAG_RXABORT                      0x01
+
+#define IrRIB_ByteCt                        0x7FF0
+#define IrRIB_BUFFE                         0x08
+#define IrRIB_BUFOR                         0x04
+#define IrRIB_BUFCRCERR                     0x02
+#define IrRIB_BUFRXABORT                    0x01
+
+#define IrDMACR_DMAERR                      0x04
+#define IrDMACR_DMATXE                      0x02
+#define IrDMACR_DMARXE                      0x01
+
+#define MFISR_RXFL                          0x40
+#define MFISR_RXIL                          0x20
+#define MFISR_RXFC                          0x10
+#define MFISR_RXFS                          0x08
+#define MFISR_TXFABORT                      0x04
+#define MFISR_TXFC                          0x02
+#define MFISR_TXSR                          0x01
+
+#define MFIMR_RXFL                          0x40
+#define MFIMR_RXIL                          0x20
+#define MFIMR_RXFC                          0x10
+#define MFIMR_RXFS                          0x08
+#define MFIMR_TXABORT                       0x04
+#define MFIMR_TXFC                          0x02
+#define MFIMR_TXFS                          0x01
+
+#define MFIIR_RXFL                          0x40
+#define MFIIR_RXIL                          0x20
+#define MFIIR_RXFC                          0x10
+#define MFIIR_RXFS                          0x08
+#define MFIIR_TXABORT                       0x04
+#define MFIIR_TXFC                          0x02
+#define MFIIR_TXFS                          0x01
+
+
+#endif /* EP93XX_IRDA_H */
diff -urN linux-2.4.29/include/net/ndisc.h linux-2.4.29-uc1/include/net/ndisc.h
--- linux-2.4.29/include/net/ndisc.h	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-uc1/include/net/ndisc.h	2005-06-14 02:11:37.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: ndisc.h,v 1.17 2003/01/24 02:05:23 yoshfuji Exp $ */
+
 #ifndef _NDISC_H
 #define _NDISC_H
 
@@ -20,6 +22,9 @@
 #define ND_OPT_PREFIX_INFO		3
 #define ND_OPT_REDIRECT_HDR		4
 #define ND_OPT_MTU			5
+#define ND_OPT_RTR_ADV_INTERVAL		7	/* Mobile IPv6 */
+#define ND_OPT_HOME_AGENT_INFO		8	/* Mobile IPv6 */
+#define ND_OPT_ROUTE_INFO		9	/* Route Info. */
 
 #define MAX_RTR_SOLICITATION_DELAY	HZ
 
@@ -31,6 +36,7 @@
 
 #ifdef __KERNEL__
 
+#include <linux/config.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/icmpv6.h>
@@ -45,10 +51,23 @@
 	__u8		opt[0];
 };
 
+struct rs_msg {
+	struct icmp6hdr	icmph;
+	__u8		opt[0];
+};
+
 struct ra_msg {
-        struct icmp6hdr		icmph;
-	__u32			reachable_time;
-	__u32			retrans_timer;
+        struct icmp6hdr	icmph;
+	__u32		reachable_time;
+	__u32		retrans_timer;
+	__u8		opt[0];
+};
+
+struct rd_msg {
+	struct icmp6hdr icmph;
+	struct in6_addr	rd_target;
+	struct in6_addr	rd_dst;
+	__u8		opt[0];
 };
 
 struct nd_opt_hdr {
@@ -57,16 +76,21 @@
 } __attribute__((__packed__));
 
 struct ndisc_options {
-	struct nd_opt_hdr *nd_opt_array[7];
+	struct nd_opt_hdr *nd_opt_array[10];	/*max = route info. */
 	struct nd_opt_hdr *nd_opt_piend;
+	struct nd_opt_hdr *nd_opt_riend;
 };
 
 #define nd_opts_src_lladdr	nd_opt_array[ND_OPT_SOURCE_LL_ADDR]
 #define nd_opts_tgt_lladdr	nd_opt_array[ND_OPT_TARGET_LL_ADDR]
 #define nd_opts_pi		nd_opt_array[ND_OPT_PREFIX_INFO]
 #define nd_opts_pi_end		nd_opt_piend
+#define nd_opts_ri		nd_opt_array[ND_OPT_ROUTE_INFO]
+#define nd_opts_ri_end		nd_opt_riend
 #define nd_opts_rh		nd_opt_array[ND_OPT_REDIRECT_HDR]
 #define nd_opts_mtu		nd_opt_array[ND_OPT_MTU]
+#define nd_opts_adv		nd_opt_array[ND_OPT_RTR_ADV_INTERVAL]
+#define nd_opts_hai		nd_opt_array[ND_OPT_HOME_AGENT_INFO]
 
 extern struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur, struct nd_opt_hdr *end);
 extern struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len, struct ndisc_options *ndopts);
@@ -81,7 +105,17 @@
 					      struct neighbour *neigh,
 					      struct in6_addr *solicit,
 					      struct in6_addr *daddr,
-					      struct in6_addr *saddr);
+					      struct in6_addr *saddr,
+					      int dad);
+
+extern void			ndisc_send_na(struct net_device *dev,
+					      struct neighbour *neigh,
+					      struct in6_addr *daddr,
+					      struct in6_addr *solicited_addr,
+					      int router,
+					      int solicited,
+					      int overide,
+					      int inc_opt);
 
 extern void			ndisc_send_rs(struct net_device *dev,
 					      struct in6_addr *saddr,
diff -urN linux-2.4.29/include/net/neighbour.h linux-2.4.29-uc1/include/net/neighbour.h
--- linux-2.4.29/include/net/neighbour.h	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/include/net/neighbour.h	2005-06-14 02:11:37.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: neighbour.h,v 1.10 2003/12/22 04:36:30 yoshfuji Exp $ */
+
 #ifndef _NET_NEIGHBOUR_H
 #define _NET_NEIGHBOUR_H
 
@@ -52,7 +54,15 @@
 #include <linux/skbuff.h>
 #include <linux/seq_file.h>
 
-#define NUD_IN_TIMER	(NUD_INCOMPLETE|NUD_DELAY|NUD_PROBE)
+#define NUD_IN_TIMER	(NUD_INCOMPLETE|NUD_REACHABLE|NUD_DELAY|NUD_PROBE)
+
+
+#ifndef USE_IPV6_MOBILITY
+#if defined(CONFIG_IPV6_MOBILITY) || defined(CONFIG_IPV6_MOBILITY_MODULE)
+#define USE_IPV6_MOBILITY
+#endif
+#endif
+
 #define NUD_VALID	(NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY)
 #define NUD_CONNECTED	(NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE)
 
@@ -143,8 +153,11 @@
 struct pneigh_entry
 {
 	struct pneigh_entry	*next;
-	struct net_device		*dev;
+	struct net_device      	*dev;
 	u8			key[0];
+#ifdef USE_IPV6_MOBILITY
+	atomic_t       		refcnt;
+#endif
 };
 
 /*
@@ -191,6 +204,34 @@
 #endif
 };
 
+#define NEIGH_UPDATE_F_ADMIN			0x00000001
+#define NEIGH_UPDATE_F_ISROUTER			0x00000002
+#define NEIGH_UPDATE_F_OVERRIDE			0x00000004
+#define NEIGH_UPDATE_F_OVERRIDE_VALID_ISROUTER	0x00000008
+#define NEIGH_UPDATE_F_REUSEADDR		0x00000010
+#define NEIGH_UPDATE_F_REUSESUSPECTSTATE	0x00000020
+#define NEIGH_UPDATE_F_SETUP_ISROUTER		0x00000040
+#define NEIGH_UPDATE_F_SUSPECT_CONNECTED	0x00000080
+
+#define NEIGH_UPDATE_F_IP6NS		(NEIGH_UPDATE_F_SETUP_ISROUTER|\
+					 NEIGH_UPDATE_F_REUSESUSPECTSTATE|\
+					 NEIGH_UPDATE_F_OVERRIDE)
+#define NEIGH_UPDATE_F_IP6NA		(NEIGH_UPDATE_F_SETUP_ISROUTER|\
+					 NEIGH_UPDATE_F_REUSESUSPECTSTATE|\
+					 NEIGH_UPDATE_F_SUSPECT_CONNECTED|\
+					 NEIGH_UPDATE_F_OVERRIDE_VALID_ISROUTER)
+#define NEIGH_UPDATE_F_IP6RS		(NEIGH_UPDATE_F_SETUP_ISROUTER|\
+					 NEIGH_UPDATE_F_REUSESUSPECTSTATE|\
+					 NEIGH_UPDATE_F_OVERRIDE|\
+					 NEIGH_UPDATE_F_OVERRIDE_VALID_ISROUTER)
+#define NEIGH_UPDATE_F_IP6RA		(NEIGH_UPDATE_F_SETUP_ISROUTER|\
+					 NEIGH_UPDATE_F_REUSESUSPECTSTATE|\
+					 NEIGH_UPDATE_F_OVERRIDE|\
+					 NEIGH_UPDATE_F_OVERRIDE_VALID_ISROUTER|\
+					 NEIGH_UPDATE_F_ISROUTER)
+#define NEIGH_UPDATE_F_IP6REDIRECT	(NEIGH_UPDATE_F_REUSESUSPECTSTATE|\
+					 NEIGH_UPDATE_F_OVERRIDE)
+
 extern void			neigh_table_init(struct neigh_table *tbl);
 extern int			neigh_table_clear(struct neigh_table *tbl);
 extern struct neighbour *	neigh_lookup(struct neigh_table *tbl,
@@ -203,6 +244,7 @@
 					     struct net_device *dev);
 extern void			neigh_destroy(struct neighbour *neigh);
 extern int			__neigh_event_send(struct neighbour *neigh, struct sk_buff *skb);
+extern int			__neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, u32 flags);
 extern int			neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, int override, int arp);
 extern void			neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev);
 extern int			neigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
@@ -228,6 +270,7 @@
 extern int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
 extern int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
 extern void neigh_app_ns(struct neighbour *n);
+extern void neigh_app_notify(struct neighbour *n);
 
 extern void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie);
 extern void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct neighbour *));
@@ -288,10 +331,18 @@
 
 static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
 {
+	int ret = 0;
+	write_lock_bh(&neigh->lock);
 	neigh->used = jiffies;
-	if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE)))
-		return __neigh_event_send(neigh, skb);
-	return 0;
+	if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE))) 
+		ret = __neigh_event_send(neigh, skb);
+	write_unlock_bh(&neigh->lock);
+	if (ret < 0) {
+		if (skb)
+			kfree_skb(skb);
+		ret = 1;
+	}
+	return ret;
 }
 
 static inline struct neighbour *
@@ -318,7 +369,67 @@
 	return neigh_create(tbl, pkey, dev);
 }
 
+static inline const char *
+neigh_state(int state) 
+{
+	switch(state) {
+	case NUD_NONE:		return "NONE";
+	case NUD_INCOMPLETE:	return "INCOMPLETE";
+	case NUD_REACHABLE:	return "REACHABLE";
+	case NUD_STALE:		return "STALE";
+	case NUD_DELAY:		return "DELAY";
+	case NUD_PROBE:		return "PROBE";
+	case NUD_FAILED:	return "FAILED";
+	case NUD_NOARP:		return "NOARP";
+	case NUD_PERMANENT:	return "PERMANENT";
+	}
+	return "unknown";
+}
 #endif
+#ifdef USE_IPV6_MOBILITY
+
+static inline struct pneigh_entry *pneigh_clone(struct pneigh_entry *pneigh)
+{
+	if (pneigh)
+		atomic_inc(&pneigh->refcnt);
+	return pneigh;
+}
+
+static inline void pneigh_refcnt_init(struct pneigh_entry *pneigh)
+{
+	atomic_set(&pneigh->refcnt, 1);
+}
+
+static inline int pneigh_refcnt_dec_and_test(struct pneigh_entry *pneigh)
+{
+	return atomic_dec_and_test(&pneigh->refcnt);
+}
+
+static inline int pneigh_alloc_flag(void)
+{
+	return in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
+}
+
+#else 
+
+static inline struct pneigh_entry *pneigh_clone(struct pneigh_entry *pneigh)
+{
+	return pneigh;
+}
+
+static inline void pneigh_refcnt_init(struct pneigh_entry *pneigh) {}
+
+static inline int pneigh_refcnt_dec_and_test(struct pneigh_entry *pneigh)
+{
+	return 1;
+}
+
+static inline int pneigh_alloc_flag(void)
+{
+	return GFP_KERNEL;
+}
+
+#endif /* USE_IPV6_MOBILITY */
 #endif
 
 
diff -urN linux-2.4.29/include/net/snmp.h linux-2.4.29-uc1/include/net/snmp.h
--- linux-2.4.29/include/net/snmp.h	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/include/net/snmp.h	2005-06-14 02:11:37.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: snmp.h,v 1.13 2003/11/12 05:11:57 yoshfuji Exp $ */
+
 /*
  *
  *		SNMP MIB entries for the IP subsystem.
@@ -66,7 +68,7 @@
  	unsigned long	IpFragOKs;
  	unsigned long	IpFragFails;
  	unsigned long	IpFragCreates;
-	unsigned long   __pad[0]; 
+	unsigned long	__pad[0];
 } ____cacheline_aligned;
  
 /*
@@ -74,6 +76,7 @@
  */
 struct ipv6_mib
 {
+	unsigned long	Ip6LastChange;
 	unsigned long	Ip6InReceives;
  	unsigned long	Ip6InHdrErrors;
  	unsigned long	Ip6InTooBigErrors;
@@ -96,7 +99,7 @@
  	unsigned long	Ip6FragCreates;
  	unsigned long	Ip6InMcastPkts;
  	unsigned long	Ip6OutMcastPkts;
-	unsigned long   __pad[0]; 
+	unsigned long	__pad[0];
 } ____cacheline_aligned;
  
 /*
@@ -143,36 +146,49 @@
 	unsigned long	Icmp6InMsgs;
 	unsigned long	Icmp6InErrors;
 
-	unsigned long	Icmp6InDestUnreachs;
-	unsigned long	Icmp6InPktTooBigs;
-	unsigned long	Icmp6InTimeExcds;
-	unsigned long	Icmp6InParmProblems;
-
-	unsigned long	Icmp6InEchos;
-	unsigned long	Icmp6InEchoReplies;
-	unsigned long	Icmp6InGroupMembQueries;
-	unsigned long	Icmp6InGroupMembResponses;
-	unsigned long	Icmp6InGroupMembReductions;
-	unsigned long	Icmp6InRouterSolicits;
-	unsigned long	Icmp6InRouterAdvertisements;
-	unsigned long	Icmp6InNeighborSolicits;
-	unsigned long	Icmp6InNeighborAdvertisements;
-	unsigned long	Icmp6InRedirects;
+	/* XXX: order is important: net/ipv6/icmp.c */
+	unsigned long	Icmp6InDestUnreachs;		/*   1 */
+	unsigned long	Icmp6InPktTooBigs;		/*   2 */
+	unsigned long	Icmp6InTimeExcds;		/*   3 */
+	unsigned long	Icmp6InParmProblems;		/*   4 */
+
+	unsigned long	Icmp6InAdminProhibs;
+
+	/* XXX: order is important: net/ipv6/icmp.c */
+	unsigned long	Icmp6InEchos;			/* 128 */
+	unsigned long	Icmp6InEchoReplies;		/* 129 */
+	unsigned long	Icmp6InGroupMembQueries;	/* 130 */
+	unsigned long	Icmp6InGroupMembResponses;	/* 131 */
+	unsigned long	Icmp6InGroupMembReductions;	/* 132 */
+	unsigned long	Icmp6InRouterSolicits;		/* 133 */
+	unsigned long	Icmp6InRouterAdvertisements;	/* 134 */
+	unsigned long	Icmp6InNeighborSolicits;	/* 135 */
+	unsigned long	Icmp6InNeighborAdvertisements;	/* 136 */
+	unsigned long	Icmp6InRedirects;		/* 137 */
 
 	unsigned long	Icmp6OutMsgs;
+	unsigned long	Icmp6OutErrors;
+
+	/* XXX: order is important: net/ipv6/icmp.c */
+	unsigned long	Icmp6OutDestUnreachs;		/*   1 */
+	unsigned long	Icmp6OutPktTooBigs;		/*   2 */
+	unsigned long	Icmp6OutTimeExcds;		/*   3 */
+	unsigned long	Icmp6OutParmProblems;		/*   4 */
+
+	unsigned long	Icmp6OutAdminProhibs;
+
+	/* XXX: order is important: net/ipv6/icmp.c */
+	unsigned long	Icmp6OutEchos;			/* 128 */
+	unsigned long	Icmp6OutEchoReplies;		/* 129 */
+	unsigned long	Icmp6OutGroupMembQueries;	/* 130 */
+	unsigned long	Icmp6OutGroupMembResponses;	/* 131 */
+	unsigned long	Icmp6OutGroupMembReductions;	/* 132 */
+	unsigned long	Icmp6OutRouterSolicits;		/* 133 */
+	unsigned long	Icmp6OutRouterAdvertisements;	/* 134 */
+	unsigned long	Icmp6OutNeighborSolicits;	/* 135 */
+	unsigned long	Icmp6OutNeighborAdvertisements;	/* 136 */
+	unsigned long	Icmp6OutRedirects;		/* 137 */
 
-	unsigned long	Icmp6OutDestUnreachs;
-	unsigned long	Icmp6OutPktTooBigs;
-	unsigned long	Icmp6OutTimeExcds;
-	unsigned long	Icmp6OutParmProblems;
-
-	unsigned long	Icmp6OutEchoReplies;
-	unsigned long	Icmp6OutRouterSolicits;
-	unsigned long	Icmp6OutNeighborSolicits;
-	unsigned long	Icmp6OutNeighborAdvertisements;
-	unsigned long	Icmp6OutRedirects;
-	unsigned long	Icmp6OutGroupMembResponses;
-	unsigned long	Icmp6OutGroupMembReductions;
 	unsigned long   __pad[0]; 
 } ____cacheline_aligned;
  
diff -urN linux-2.4.29/include/net/sock.h linux-2.4.29-uc1/include/net/sock.h
--- linux-2.4.29/include/net/sock.h	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/include/net/sock.h	2005-06-14 02:11:37.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: sock.h,v 1.24 2003/11/12 05:11:57 yoshfuji Exp $ */
+
 /*
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
@@ -149,13 +151,22 @@
 	struct in6_addr 	rcv_saddr;
 	struct in6_addr		daddr;
 	struct in6_addr		*daddr_cache;
-
+#if defined(CONFIG_IPV6_SUBTREES)
+	struct in6_addr		*saddr_cache;
+#endif
 	__u32			flow_label;
 	__u32			frag_size;
 	int			hop_limit;
 	int			mcast_hops;
 	int			mcast_oif;
 
+	/* stuff related to RFC2292bis and its variants */
+	struct {
+		__u8		tclass:1;
+	} recvopt;
+
+	__u8			tclass;
+
 	/* pktoption flags */
 	union {
 		struct {
@@ -177,6 +188,8 @@
 	                        pmtudisc:2,
 				ipv6only:1;
 
+	__s8			use_tempaddr;
+
 	struct ipv6_mc_socklist	*ipv6_mc_list;
 	struct ipv6_ac_socklist	*ipv6_ac_list;
 	struct ipv6_fl_socklist *ipv6_fl_list;
@@ -256,6 +269,12 @@
 	__u32	end_seq;
 };
 
+#if 1
+struct udp_opt {
+	__u32 esp_in_udp;
+};
+#endif
+
 enum tcp_congestion_algo {
  	TCP_RENO=0,
  	TCP_VEGAS,
@@ -574,6 +593,9 @@
 
 	unsigned short		family;		/* Address family			*/
 	unsigned char		reuse;		/* SO_REUSEADDR setting			*/
+#ifdef SO_REUSEPORT
+	unsigned char		reuseport;	/* SO_REUSEPORT setting			*/
+#endif
 	unsigned char		shutdown;
 	atomic_t		refcnt;		/* Reference count			*/
 
@@ -655,6 +677,9 @@
 #if defined(CONFIG_SPX) || defined (CONFIG_SPX_MODULE)
 		struct spx_opt		af_spx;
 #endif /* CONFIG_SPX */
+#if 1
+		struct udp_opt 		af_udp;
+#endif
 
 	} tp_pinfo;
 
@@ -1119,6 +1144,41 @@
 	return uid;
 }
 
+static inline uid_t sock_i_uid_t(struct sock*sk)
+{
+	uid_t uid = -1;
+	read_lock(&sk->callback_lock);
+	if (sk->socket)
+		uid = sk->socket->inode->i_uid;
+	read_unlock(&sk->callback_lock);
+	return uid;
+}
+
+static inline int *sock_i_uidp(struct sock *sk, int *uidp)
+{
+	if (!uidp)
+		return NULL;
+	read_lock(&sk->callback_lock);
+	if (sk->socket)
+		*uidp = sk->socket->inode->i_uid;
+	else {
+		*uidp = 0;
+		uidp = NULL;
+	}
+	read_unlock(&sk->callback_lock);
+	return uidp;
+}
+
+static inline int check_sock_i_uid(struct sock *sk, int uid)
+{
+	int ret = -1;
+	read_lock(&sk->callback_lock);
+	if (sk->socket)
+		ret = sk->socket->inode->i_uid != uid;
+	read_unlock(&sk->callback_lock);
+	return ret;
+}
+
 static inline unsigned long sock_i_ino(struct sock *sk)
 {
 	unsigned long ino;
diff -urN linux-2.4.29/include/net/tcp.h linux-2.4.29-uc1/include/net/tcp.h
--- linux-2.4.29/include/net/tcp.h	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/include/net/tcp.h	2005-06-14 02:11:37.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: tcp.h,v 1.13 2003/11/12 05:11:57 yoshfuji Exp $ */
+
 /*
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
@@ -78,6 +80,7 @@
 struct tcp_bind_bucket {
 	unsigned short		port;
 	signed short		fastreuse;
+	uid_t			uid;
 	struct tcp_bind_bucket	*next;
 	struct sock		*owners;
 	struct tcp_bind_bucket	**pprev;
@@ -171,6 +174,9 @@
 	__u16			sport;
 	unsigned short		family;
 	unsigned char		reuse,
+#ifdef SO_REUSEPORT
+				reuseport,
+#endif
 				rcv_wscale; /* It is also TW bucket specific */
 	atomic_t		refcnt;
 
@@ -187,6 +193,8 @@
 	struct tcp_tw_bucket	*next_death;
 	struct tcp_tw_bucket	**pprev_death;
 
+	uid_t			uid;
+
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	struct in6_addr		v6_daddr;
 	struct in6_addr		v6_rcv_saddr;
diff -urN linux-2.4.29/include/net/transp_v6.h linux-2.4.29-uc1/include/net/transp_v6.h
--- linux-2.4.29/include/net/transp_v6.h	2003-06-13 15:51:39.000000000 +0100
+++ linux-2.4.29-uc1/include/net/transp_v6.h	2005-06-14 02:11:37.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: transp_v6.h,v 1.4 2003/06/25 06:34:37 yoshfuji Exp $ */
+
 #ifndef _TRANSP_V6_H
 #define _TRANSP_V6_H
 
@@ -32,7 +34,7 @@
 extern int			datagram_send_ctl(struct msghdr *msg,
 						  struct flowi *fl,
 						  struct ipv6_txoptions *opt,
-						  int *hlimit);
+						  int *hlimit, int *tclass);
 
 #define		LOOPBACK4_IPV6		__constant_htonl(0x7f000006)
 
diff -urN linux-2.4.29/include/openssl/opensslconf.h linux-2.4.29-uc1/include/openssl/opensslconf.h
--- linux-2.4.29/include/openssl/opensslconf.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/openssl/opensslconf.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,180 @@
+/* opensslconf.h */
+/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
+
+#ifdef __KERNEL__
+/* OpenSSL was configured with the following options: */
+#ifdef OPENSSL_ALGORITHM_DEFINES
+   /* no ciphers excluded */
+#endif
+#ifdef OPENSSL_THREAD_DEFINES
+# ifndef THREADS
+#  define THREADS
+# endif
+#endif
+#ifdef OPENSSL_OTHER_DEFINES
+# ifndef DSO_DLFCN
+#  define DSO_DLFCN
+# endif
+# ifndef HAVE_DLFCN_H
+#  define HAVE_DLFCN_H
+# endif
+#endif
+
+/* crypto/opensslconf.h.in */
+
+/* Generate 80386 code? */
+#undef I386_ONLY
+
+#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
+#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
+#define OPENSSLDIR "/usr/local/ssl"
+#endif
+#endif
+
+#define OPENSSL_UNISTD <unistd.h>
+
+#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
+#define IDEA_INT unsigned int
+#endif
+
+#if defined(HEADER_MD2_H) && !defined(MD2_INT)
+#define MD2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC2_H) && !defined(RC2_INT)
+/* I need to put in a mod for the alpha - eay */
+#define RC2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC4_H)
+#if !defined(RC4_INT)
+/* using int types make the structure larger but make the code faster
+ * on most boxes I have tested - up to %20 faster. */
+/*
+ * I don't know what does "most" mean, but declaring "int" is a must on:
+ * - Intel P6 because partial register stalls are very expensive;
+ * - elder Alpha because it lacks byte load/store instructions;
+ */
+#define RC4_INT unsigned int
+#endif
+#if !defined(RC4_CHUNK)
+/*
+ * This enables code handling data aligned at natural CPU word
+ * boundary. See crypto/rc4/rc4_enc.c for further details.
+ */
+#undef RC4_CHUNK
+#endif
+#endif
+
+#if defined(HEADER_DES_H) && !defined(DES_LONG)
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+#ifndef DES_LONG
+#define DES_LONG unsigned long
+#endif
+#endif
+
+#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
+#define CONFIG_HEADER_BN_H
+#define BN_LLONG
+
+/* Should we define BN_DIV2W here? */
+
+/* Only one for the following should be defined */
+/* The prime number generation stuff may not work when
+ * EIGHT_BIT but I don't care since I've only used this mode
+ * for debuging the bignum libraries */
+#undef SIXTY_FOUR_BIT_LONG
+#undef SIXTY_FOUR_BIT
+#define THIRTY_TWO_BIT
+#undef SIXTEEN_BIT
+#undef EIGHT_BIT
+#endif
+
+#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
+#define CONFIG_HEADER_RC4_LOCL_H
+/* if this is defined data[i] is used instead of *data, this is a %20
+ * speedup on x86 */
+#define RC4_INDEX
+#endif
+
+#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
+#define CONFIG_HEADER_BF_LOCL_H
+#undef BF_PTR
+#endif /* HEADER_BF_LOCL_H */
+
+#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
+#define CONFIG_HEADER_DES_LOCL_H
+#ifndef DES_DEFAULT_OPTIONS
+/* the following is tweaked from a config script, that is why it is a
+ * protected undef/define */
+#ifndef DES_PTR
+#define DES_PTR
+#endif
+
+/* This helps C compiler generate the correct code for multiple functional
+ * units.  It reduces register dependancies at the expense of 2 more
+ * registers */
+#ifndef DES_RISC1
+#define DES_RISC1
+#endif
+
+#ifndef DES_RISC2
+#undef DES_RISC2
+#endif
+
+#if defined(DES_RISC1) && defined(DES_RISC2)
+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
+#endif
+
+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+#ifndef DES_UNROLL
+#define DES_UNROLL
+#endif
+
+/* These default values were supplied by
+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
+ * They are only used if nothing else has been defined */
+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
+/* Special defines which change the way the code is built depending on the
+   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
+   even newer MIPS CPU's, but at the moment one size fits all for
+   optimization options.  Older Sparc's work better with only UNROLL, but
+   there's no way to tell at compile time what it is you're running on */
+ 
+#if defined( sun )		/* Newer Sparc's */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#elif defined( __ultrix )	/* Older MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined( __osf1__ )	/* Alpha */
+#  define DES_PTR
+#  define DES_RISC2
+#elif defined ( _AIX )		/* RS6000 */
+  /* Unknown */
+#elif defined( __hpux )		/* HP-PA */
+  /* Unknown */
+#elif defined( __aux )		/* 68K */
+  /* Unknown */
+#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
+#  define DES_UNROLL
+#elif defined( __sgi )		/* Newer MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined( i386 )		/* x86 boxes, should be gcc */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#endif /* Systems-specific speed defines */
+#endif
+
+#endif /* DES_DEFAULT_OPTIONS */
+#endif /* HEADER_DES_LOCL_H */
+#else /* KERNEL */
+#include_next <openssl/opensslconf.h>
+#endif
diff -urN linux-2.4.29/include/openssl/opensslv.h linux-2.4.29-uc1/include/openssl/opensslv.h
--- linux-2.4.29/include/openssl/opensslv.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/openssl/opensslv.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,89 @@
+#ifdef __KERNEL__
+#ifndef HEADER_OPENSSLV_H
+#define HEADER_OPENSSLV_H
+
+/* Numeric release version identifier:
+ * MMNNFFPPS: major minor fix patch status
+ * The status nibble has one of the values 0 for development, 1 to e for betas
+ * 1 to 14, and f for release.  The patch level is exactly that.
+ * For example:
+ * 0.9.3-dev	  0x00903000
+ * 0.9.3-beta1	  0x00903001
+ * 0.9.3-beta2-dev 0x00903002
+ * 0.9.3-beta2    0x00903002 (same as ...beta2-dev)
+ * 0.9.3	  0x0090300f
+ * 0.9.3a	  0x0090301f
+ * 0.9.4 	  0x0090400f
+ * 1.2.3z	  0x102031af
+ *
+ * For continuity reasons (because 0.9.5 is already out, and is coded
+ * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level
+ * part is slightly different, by setting the highest bit.  This means
+ * that 0.9.5a looks like this: 0x0090581f.  At 0.9.6, we can start
+ * with 0x0090600S...
+ *
+ * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.)
+ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
+ *  major minor fix final patch/beta)
+ */
+#define OPENSSL_VERSION_NUMBER	0x0090601fL
+#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.6a 5 Apr 2001"
+#define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
+
+
+/* The macros below are to be used for shared library (.so, .dll, ...)
+ * versioning.  That kind of versioning works a bit differently between
+ * operating systems.  The most usual scheme is to set a major and a minor
+ * number, and have the runtime loader check that the major number is equal
+ * to what it was at application link time, while the minor number has to
+ * be greater or equal to what it was at application link time.  With this
+ * scheme, the version number is usually part of the file name, like this:
+ *
+ *	libcrypto.so.0.9
+ *
+ * Some unixen also make a softlink with the major verson number only:
+ *
+ *	libcrypto.so.0
+ *
+ * On True64 it works a little bit differently.  There, the shared library
+ * version is stored in the file, and is actually a series of versions,
+ * separated by colons.  The rightmost version present in the library when
+ * linking an application is stored in the application to be matched at
+ * run time.  When the application is run, a check is done to see if the
+ * library version stored in the application matches any of the versions
+ * in the version string of the library itself.
+ * This version string can be constructed in any way, depending on what
+ * kind of matching is desired.  However, to implement the same scheme as
+ * the one used in the other unixen, all compatible versions, from lowest
+ * to highest, should be part of the string.  Consecutive builds would
+ * give the following versions strings:
+ *
+ *	3.0
+ *	3.0:3.1
+ *	3.0:3.1:3.2
+ *	4.0
+ *	4.0:4.1
+ *
+ * Notice how version 4 is completely incompatible with version, and
+ * therefore give the breach you can see.
+ *
+ * There may be other schemes as well that I haven't yet discovered.
+ *
+ * So, here's the way it works here: first of all, the library version
+ * number doesn't need at all to match the overall OpenSSL version.
+ * However, it's nice and more understandable if it actually does.
+ * The current library version is stored in the macro SHLIB_VERSION_NUMBER,
+ * which is just a piece of text in the format "M.m.e" (Major, minor, edit).
+ * For the sake of True64 and any other OS that behaves in similar ways,
+ * we need to keep a history of version numbers, which is done in the
+ * macro SHLIB_VERSION_HISTORY.  The numbers are separated by colons and
+ * should only keep the versions that are binary compatible with the current.
+ */
+#define SHLIB_VERSION_HISTORY ""
+#define SHLIB_VERSION_NUMBER "0.9.6"
+
+
+#endif /* HEADER_OPENSSLV_H */
+#else /* __KERNEL__ */
+#include_next <openssl/opensslv.h>
+#endif
diff -urN linux-2.4.29/include/openssl/rc4.h linux-2.4.29-uc1/include/openssl/rc4.h
--- linux-2.4.29/include/openssl/rc4.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/openssl/rc4.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,92 @@
+/* crypto/rc4/rc4.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifdef __KERNEL__
+#ifndef HEADER_RC4_H
+#define HEADER_RC4_H
+
+#ifdef NO_RC4
+#error RC4 is disabled.
+#endif
+
+#include <openssl/opensslconf.h> /* RC4_INT */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct rc4_key_st
+	{
+	RC4_INT x,y;
+	RC4_INT data[256];
+	} RC4_KEY;
+
+ 
+const char *RC4_options(void);
+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
+void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
+		unsigned char *outdata);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+#else /* __KERNEL__ */
+#include_next <openssl/rc4.h>
+#endif
diff -urN linux-2.4.29/include/openssl/sha.h linux-2.4.29-uc1/include/openssl/sha.h
--- linux-2.4.29/include/openssl/sha.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/openssl/sha.h	2005-06-14 02:11:38.000000000 +0100
@@ -0,0 +1,122 @@
+/* crypto/sha/sha.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+#ifdef __KERNEL__
+#ifndef HEADER_SHA_H
+#define HEADER_SHA_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if defined(NO_SHA) || (defined(NO_SHA0) && defined(NO_SHA1))
+#error SHA is disabled.
+#endif
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! SHA_LONG_LOG2 has to be defined along.                        !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(WIN16) || defined(__LP32__)
+#define SHA_LONG unsigned long
+#elif defined(_CRAY) || defined(__ILP64__)
+#define SHA_LONG unsigned long
+#define SHA_LONG_LOG2 3
+#else
+#define SHA_LONG unsigned int
+#endif
+
+#define SHA_LBLOCK	16
+#define SHA_CBLOCK	(SHA_LBLOCK*4)	/* SHA treats input data as a
+					 * contiguous array of 32 bit
+					 * wide big-endian values. */
+#define SHA_LAST_BLOCK  (SHA_CBLOCK-8)
+#define SHA_DIGEST_LENGTH 20
+
+typedef struct SHAstate_st
+	{
+	SHA_LONG h0,h1,h2,h3,h4;
+	SHA_LONG Nl,Nh;
+	SHA_LONG data[SHA_LBLOCK];
+	int num;
+	} SHA_CTX;
+
+#ifndef NO_SHA0
+void SHA_Init(SHA_CTX *c);
+void SHA_Update(SHA_CTX *c, const void *data, unsigned long len);
+void SHA_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA(const unsigned char *d, unsigned long n,unsigned char *md);
+void SHA_Transform(SHA_CTX *c, const unsigned char *data);
+#endif
+#ifndef NO_SHA1
+void SHA1_Init(SHA_CTX *c);
+void SHA1_Update(SHA_CTX *c, const void *data, unsigned long len);
+void SHA1_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA1(const unsigned char *d, unsigned long n,unsigned char *md);
+void SHA1_Transform(SHA_CTX *c, const unsigned char *data);
+#endif
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+#else /* __KERNEL__ */
+#include_next <openssl/sha.h>
+#endif
diff -urN linux-2.4.29/include/video/fbcon-cfb12.h linux-2.4.29-uc1/include/video/fbcon-cfb12.h
--- linux-2.4.29/include/video/fbcon-cfb12.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/include/video/fbcon-cfb12.h	2005-06-14 02:11:41.000000000 +0100
@@ -0,0 +1,34 @@
+/*
+ *  FBcon low-level driver for 12 bpp packed pixel (cfb12)
+ */
+
+#ifndef _VIDEO_FBCON_CFB12_H
+#define _VIDEO_FBCON_CFB12_H
+
+#include <linux/config.h>
+
+#ifdef MODULE
+#if defined(CONFIG_FBCON_CFB12) || defined(CONFIG_FBCON_CFB12_MODULE)
+#define FBCON_HAS_CFB12
+#endif
+#else
+#if defined(CONFIG_FBCON_CFB12)
+#define FBCON_HAS_CFB12
+#endif
+#endif
+
+extern struct display_switch fbcon_cfb12;
+extern void fbcon_cfb12_setup(struct display *p);
+extern void fbcon_cfb12_bmove(struct display *p, int sy, int sx, int dy,
+			      int dx, int height, int width);
+extern void fbcon_cfb12_clear(struct vc_data *conp, struct display *p, int sy,
+			      int sx, int height, int width);
+extern void fbcon_cfb12_putc(struct vc_data *conp, struct display *p, int c,
+			     int yy, int xx);
+extern void fbcon_cfb12_putcs(struct vc_data *conp, struct display *p,
+			      const unsigned short *s, int count, int yy, int xx);
+extern void fbcon_cfb12_revc(struct display *p, int xx, int yy);
+extern void fbcon_cfb12_clear_margins(struct vc_data *conp, struct display *p,
+				      int bottom_only);
+
+#endif /* _VIDEO_FBCON_CFB12_H */
diff -urN linux-2.4.29/include/video/fbcon.h linux-2.4.29-uc1/include/video/fbcon.h
--- linux-2.4.29/include/video/fbcon.h	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/include/video/fbcon.h	2005-06-14 02:11:41.000000000 +0100
@@ -296,6 +296,7 @@
          : "=a" (s), "=d" (count)
          : "d" (0), "0" ((char *)s+count), "1" (count)
    );
+#ifndef CONFIG_COLDFIRE
    __asm__ __volatile__(
          "subql  #1,%1 ; jcs 3f\n\t"
 	 "movel %2,%%d4; movel %2,%%d5; movel %2,%%d6\n\t"
@@ -306,7 +307,22 @@
          : "d" (0), "0" (s), "1" (count)
 	 : "d4", "d5", "d6"
   );
-
+#else
+   __asm__ __volatile__(
+         "subql  #1,%1 ; jcs 3f\n\t"
+	 "movel %2,%%d4; movel %2,%%d5; movel %2,%%d6\n\t"
+      "2: movel %2,%0@-\n\t"
+	 "movel %%d4,%0@-\n\t"
+	 "movel %%d5,%0@-\n\t"
+	 "movel %%d6,%0@-\n\t"
+         "subql #1,%1\n\t"
+	 "bra 2b\n\t"
+      "3:"
+         : "=a" (s), "=d" (count)
+         : "d" (0), "0" (s), "1" (count)
+	 : "d4", "d5", "d6"
+  );
+#endif
    return(0);
 }
 
@@ -328,6 +344,7 @@
      );
    } else {
       long tmp;
+#ifndef CONFIG_COLDFIRE
       __asm__ __volatile__(
             "movel %1,%2\n\t"
             "lsrl   #1,%2 ; jcc 1f ; clrb %0@+ ; subqw #1,%1\n\t"
@@ -347,6 +364,28 @@
             : "=a" (s), "=d" (count), "=d" (tmp)
             : "0" (s), "1" (count)
      );
+#else
+      __asm__ __volatile__(
+            "movel %1,%2\n\t"
+            "lsrl   #1,%2 ; jcc 1f ; clrb %0@+ ; subql #1,%1\n\t"
+            "lsrl   #1,%2 ; jcs 2f\n\t"  /* %0 increased=>bit 2 switched*/
+            "clrw   %0@+  ; subql  #2,%1 ; jra 2f\n\t"
+         "1: lsrl   #1,%2 ; jcc 2f\n\t"
+            "clrw   %0@+  ; subql  #2,%1\n\t"
+         "2: movew %1,%2; lsrl #2,%1 ; jeq 6f\n\t"
+            "lsrl   #1,%1 ; jcc 3f ; clrl %0@+\n\t"
+         "3: lsrl   #1,%1 ; jcc 4f ; clrl %0@+ ; clrl %0@+\n\t"
+         "4: subql  #1,%1 ; jcs 6f\n\t"
+         "5: clrl %0@+; clrl %0@+ ; clrl %0@+ ; clrl %0@+\n\t"
+	    "subql #1,%1  ; bra 5b\n\t"
+            "clrw %1; subql #1,%1; jcc 5b\n\t"
+         "6: movew %2,%1; btst #1,%1 ; jeq 7f ; clrw %0@+\n\t"
+         "7:            ; btst #0,%1 ; jeq 8f ; clrb %0@+\n\t"
+         "8:"
+            : "=a" (s), "=d" (count), "=d" (tmp)
+            : "0" (s), "1" (count)
+     );
+#endif
    }
 
    return(0);
@@ -367,6 +406,7 @@
          : "=a" (s), "=d" (count)
          : "d" (-1), "0" ((char *)s+count), "1" (count)
    );
+#ifndef CONFIG_COLDFIRE
    __asm__ __volatile__(
          "subql  #1,%1 ; jcs 3f\n\t"
 	 "movel %2,%%d4; movel %2,%%d5; movel %2,%%d6\n\t"
@@ -377,6 +417,23 @@
          : "d" (-1), "0" (s), "1" (count)
 	 : "d4", "d5", "d6"
   );
+#else
+   __asm__ __volatile__(
+         "subql  #1,%1 ; jcs 3f\n\t"
+	 "movel %2,%%d4; movel %2,%%d5; movel %2,%%d6\n\t"
+      "2: movel %2,%0@-\n\t"
+	 "movel %%d4, %0@-\n\t"
+	 "movel %%d5,%0@-\n\t"
+	 "movel %%d6,%0@-\n\t"
+	 "subql #1,%1\n\t"
+	 "bra 2b\n\t"
+      "3:"
+         : "=a" (s), "=d" (count)
+         : "d" (-1), "0" (s), "1" (count)
+	 : "d4", "d5", "d6"
+  );
+#endif
+
 
    return(0);
 }
@@ -397,6 +454,7 @@
         );
       } else {
          long tmp;
+#ifndef CONFIG_COLDFIRE
          __asm__ __volatile__(
                "movel  %0,%3\n\t"
                "lsrl   #1,%3 ; jcc 1f ; moveb %1@+,%0@+ ; subqw #1,%2\n\t"
@@ -417,6 +475,29 @@
                : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
                : "0" (d), "1" (s), "2" (count)
         );
+#else
+         __asm__ __volatile__(
+               "movel  %0,%3\n\t"
+               "lsrl   #1,%3 ; jcc 1f ; moveb %1@+,%0@+ ; subql #1,%2\n\t"
+               "lsrl   #1,%3 ; jcs 2f\n\t"  /* %0 increased=>bit 2 switched*/
+               "movew  %1@+,%0@+  ; subql  #2,%2 ; jra 2f\n\t"
+            "1: lsrl   #1,%3 ; jcc 2f\n\t"
+               "movew  %1@+,%0@+  ; subql  #2,%2\n\t"
+            "2: movew  %2,%-; lsrl #2,%2 ; jeq 6f\n\t"
+               "lsrl   #1,%2 ; jcc 3f ; movel %1@+,%0@+\n\t"
+            "3: lsrl   #1,%2 ; jcc 4f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t"
+            "4: subql  #1,%2 ; jcs 6f\n\t"
+            "5: movel  %1@+,%0@+;movel %1@+,%0@+\n\t"
+               "movel  %1@+,%0@+;movel %1@+,%0@+\n\t"
+               "subql #1,%2 ; clrw %2; subql #1,%2; jcc 5b\n\t"
+               "bra 5b ; clrw %2\n\t"
+            "6: movew  %+,%2; btst #1,%2 ; jeq 7f ; movew %1@+,%0@+\n\t"
+            "7:              ; btst #0,%2 ; jeq 8f ; moveb %1@+,%0@+\n\t"
+            "8:"
+               : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
+               : "0" (d), "1" (s), "2" (count)
+        );
+#endif
       }
    } else {
       if (count < 16) {
@@ -431,6 +512,7 @@
         );
       } else {
          long tmp;
+#ifndef CONFIG_COLDFIRE
          __asm__ __volatile__(
                "movel %0,%3\n\t"
                "lsrl   #1,%3 ; jcc 1f ; moveb %1@-,%0@- ; subqw #1,%2\n\t"
@@ -451,6 +533,29 @@
                : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
                : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
         );
+#else
+         __asm__ __volatile__(
+               "movel %0,%3\n\t"
+               "lsrl   #1,%3 ; jcc 1f ; moveb %1@-,%0@- ; subql #1,%2\n\t"
+               "lsrl   #1,%3 ; jcs 2f\n\t"  /* %0 increased=>bit 2 switched*/
+               "movew  %1@-,%0@-  ; subql  #2,%2 ; jra 2f\n\t"
+            "1: lsrl   #1,%3 ; jcc 2f\n\t"
+               "movew  %1@-,%0@-  ; subql  #2,%2\n\t"
+            "2: movew %2,%-; lsrl #2,%2 ; jeq 6f\n\t"
+               "lsrl   #1,%2 ; jcc 3f ; movel %1@-,%0@-\n\t"
+            "3: lsrl   #1,%2 ; jcc 4f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t"
+            "4: subql  #1,%2 ; jcs 6f\n\t"
+            "5: movel %1@-,%0@-;movel %1@-,%0@-\n\t"
+               "movel %1@-,%0@-;movel %1@-,%0@-\n\t"
+               "subql #1,%2 ; clrw %2; subql #1,%2; jcc 5b\n\t"
+               "bra 5b\n\t"
+            "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@-,%0@-\n\t"
+            "7:              ; btst #0,%2 ; jeq 8f ; moveb %1@-,%0@-\n\t"
+            "8:"
+               : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
+               : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
+        );
+#endif
       }
    }
 
@@ -465,6 +570,7 @@
   if (!size)
     return;
   if (dst < src)
+#ifndef CONFIG_COLDFIRE
     __asm__ __volatile__
       ("1:"
        "  moveml %0@+,%/d0/%/d1/%/a0/%/a1\n"
@@ -476,7 +582,22 @@
        : "=a" (src), "=a" (dst), "=d" (size)
        : "0" (src), "1" (dst), "2" (size / 16 - 1)
        : "d0", "d1", "a0", "a1", "memory");
+#else
+    __asm__ __volatile__
+      ("1:"
+       "  moveml %0@+,%/d0/%/d1/%/a0/%/a1\n"
+       "  moveml %/d0/%/d1/%/a0/%/a1,%1@\n"
+       "  addql #8,%1; addql #8,%1\n"
+       "  subql #1,%2\n"
+       "  bra 1b\n"
+       "  clrw %2; subql #1,%2\n"
+       "  jcc 1b"
+       : "=a" (src), "=a" (dst), "=d" (size)
+       : "0" (src), "1" (dst), "2" (size / 16 - 1)
+       : "d0", "d1", "a0", "a1", "memory");
+#endif
   else
+#ifndef CONFIG_COLDFIRE
     __asm__ __volatile__
       ("1:"
        "  subql #8,%0; subql #8,%0\n"
@@ -488,6 +609,20 @@
        : "=a" (src), "=a" (dst), "=d" (size)
        : "0" (src + size), "1" (dst + size), "2" (size / 16 - 1)
        : "d0", "d1", "a0", "a1", "memory");
+#else
+    __asm__ __volatile__
+      ("1:"
+       "  subql #8,%0; subql #8,%0\n"
+       "  moveml %0@,%/d0/%/d1/%/a0/%/a1\n"
+       "  moveml %/d0/%/d1/%/a0/%/a1,%1@-\n"
+       "  subql #1,%2\n"
+       "  bra 1b\n"
+       "  clrw %2; subql #1,%2\n"
+       "  jcc 1b"
+       : "=a" (src), "=a" (dst), "=d" (size)
+       : "0" (src + size), "1" (dst + size), "2" (size / 16 - 1)
+       : "d0", "d1", "a0", "a1", "memory");
+#endif
 }
 
 #elif defined(CONFIG_SUN4)
diff -urN linux-2.4.29/include/video/font.h linux-2.4.29-uc1/include/video/font.h
--- linux-2.4.29/include/video/font.h	1999-01-19 18:47:48.000000000 +0000
+++ linux-2.4.29-uc1/include/video/font.h	2005-06-14 02:11:41.000000000 +0100
@@ -28,6 +28,8 @@
 #define SUN8x16_IDX	4
 #define SUN12x22_IDX	5
 #define ACORN8x8_IDX	6
+#define VTX6x8_IDX	7
+#define VTX4x8_IDX	8
 
 extern struct fbcon_font_desc	font_vga_8x8,
 				font_vga_8x16,
@@ -35,7 +37,9 @@
 				font_vga_6x11,
 				font_sun_8x16,
 				font_sun_12x22,
-				font_acorn_8x8;
+				font_acorn_8x8,
+				font_vtx_6x8,
+				font_vtx_4x8;
 
 /* Find a font with a specific name */
 
diff -urN linux-2.4.29/init/do_mounts.c linux-2.4.29-uc1/init/do_mounts.c
--- linux-2.4.29/init/do_mounts.c	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/init/do_mounts.c	2005-06-14 02:11:54.000000000 +0100
@@ -527,11 +527,11 @@
 		goto done;
 	}
 
-	if (cramfsb->magic == CRAMFS_MAGIC) {
+	if (cramfsb->magic == CRAMFS_32(CRAMFS_MAGIC)) {
 		printk(KERN_NOTICE
 		       "RAMDISK: cramfs filesystem found at block %d\n",
 		       start_block);
-		nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
+		nblocks = (CRAMFS_32(cramfsb->size) + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
 		goto done;
 	}
 
diff -urN linux-2.4.29/init/main.c linux-2.4.29-uc1/init/main.c
--- linux-2.4.29/init/main.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/init/main.c	2005-06-14 02:11:54.000000000 +0100
@@ -81,7 +81,11 @@
  * with a gcc that is known to be too old from the very beginning.
  */
 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 91)
+#if !defined(CONFIG_V850E) && !defined(CONFIG_NIOS)
 #error Sorry, your GCC is too old. It builds incorrect kernels.
+#else
+#warning Sorry, your GCC is too old. It builds incorrect kernels.
+#endif
 #endif
 
 extern char _stext, _etext;
@@ -172,6 +176,46 @@
 	unsigned long ticks, loopbit;
 	int lps_precision = LPS_PREC;
 
+#ifdef FIXED_BOGOMIPS
+	int bogus;
+
+/* FIXED_BOGOMIPS converted to __delay units.  */
+#define FIXED_LOOPS_PER_JIFFY	(unsigned long)(FIXED_BOGOMIPS * (500000 / HZ))
+
+/* The maximum error in FIXED_LOOPS_PER_JIFFY that we will tolerate.  */
+#define FIXED_LPJ_TOLERANCE	(unsigned long)(FIXED_LOOPS_PER_JIFFY * 0.10)
+
+	/* Make sure fixed delay - T% is zero ticks.  */
+	ticks = jiffies;
+	while (ticks == jiffies) /* Synchronize with start of tick */
+		/* nothing */;
+	ticks = jiffies;
+	__delay(FIXED_LOOPS_PER_JIFFY - FIXED_LPJ_TOLERANCE);
+	bogus = (jiffies != ticks);
+
+	if (! bogus) {
+		/* Make sure fixed delay + T% is one tick.  The delay here
+		   is very short because we're actually continuing timing from
+		   the tick synchronization above (we don't resynchronize).  */
+		__delay(2 * FIXED_LPJ_TOLERANCE);
+		bogus = (jiffies != ticks + 1);
+	}
+	
+	if (! bogus) {
+		/* Use the precomputed value.  */
+		loops_per_jiffy = FIXED_LOOPS_PER_JIFFY;
+		printk("Delay loop constant: %lu.%02lu BogoMIPS (precomputed)\n",
+		       (unsigned long)FIXED_BOGOMIPS,
+		       ((unsigned long)(FIXED_BOGOMIPS * 100)) % 100);
+		return;
+	} else {
+		printk("Precomputed BogoMIPS value (%lu.%02lu) inaccurate!\n",
+		       (unsigned long)FIXED_BOGOMIPS,
+		       ((unsigned long)(FIXED_BOGOMIPS * 100)) % 100);
+		/* ... and fall through to normal bogomips calculation.  */
+	}
+#endif /* FIXED_BOGOMIPS */
+
 	loops_per_jiffy = (1<<12);
 
 	printk("Calibrating delay loop... ");
@@ -359,6 +403,7 @@
 {
 	char * command_line;
 	extern char saved_command_line[];
+
 /*
  * Interrupts are still disabled. Do necessary setups, then
  * enable them
diff -urN linux-2.4.29/ipc/shm.c linux-2.4.29-uc1/ipc/shm.c
--- linux-2.4.29/ipc/shm.c	2002-08-03 01:39:46.000000000 +0100
+++ linux-2.4.29-uc1/ipc/shm.c	2005-06-14 02:12:27.000000000 +0100
@@ -15,6 +15,14 @@
  *
  */
 
+ /*
+  * uClinux revisions for NO_MM
+  *
+  * A simplistic attempt to get shared memory under a mmu-less system.  Uses
+  * the shm_file pointer as a pointer to a chunk of shared memory instead of
+  * a "struct file".
+  */
+
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/shm.h>
@@ -42,8 +50,10 @@
 
 #define shm_flags	shm_perm.mode
 
+#ifndef NO_MM
 static struct file_operations shm_file_operations;
 static struct vm_operations_struct shm_vm_ops;
+#endif /* NO_MM */
 
 static struct ipc_ids shm_ids;
 
@@ -56,8 +66,10 @@
 	ipc_buildid(&shm_ids, id, seq)
 
 static int newseg (key_t key, int shmflg, size_t size);
+#ifndef NO_MM
 static void shm_open (struct vm_area_struct *shmd);
 static void shm_close (struct vm_area_struct *shmd);
+#endif /* NO_MM */
 #ifdef CONFIG_PROC_FS
 static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
 #endif
@@ -106,11 +118,13 @@
 	shm_unlock(id);
 }
 
+#ifndef NO_MM
 /* This is called by fork, once for every shm attach. */
 static void shm_open (struct vm_area_struct *shmd)
 {
 	shm_inc (shmd->vm_file->f_dentry->d_inode->i_ino);
 }
+#endif /* NO_MM */
 
 /*
  * shm_destroy - free the struct shmid_kernel
@@ -124,12 +138,17 @@
 {
 	shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	shm_rmid (shp->id);
+#ifndef NO_MM
 	shm_unlock(shp->id);
 	shmem_lock(shp->shm_file, 0);
 	fput (shp->shm_file);
+#else
+	kfree (shp->shm_file);
+#endif /* NO_MM */
 	kfree (shp);
 }
 
+#ifndef NO_MM
 /*
  * remove the attach descriptor shmd.
  * free memory for segment if it is marked destroyed.
@@ -174,6 +193,14 @@
 	close:	shm_close,	/* callback for when the vm-area is released */
 	nopage:	shmem_nopage,
 };
+#else
+struct file *shmem_file_setup(char * name, loff_t size)
+{
+	void * f = kmalloc(size, GFP_KERNEL);
+
+	return (struct file *)(PTR_ERR(f) ? f : (void *)-ENOMEM);
+}
+#endif /* NO_MM */
 
 static int newseg (key_t key, int shmflg, size_t size)
 {
@@ -213,14 +240,21 @@
 	shp->shm_nattch = 0;
 	shp->id = shm_buildid(id,shp->shm_perm.seq);
 	shp->shm_file = file;
+#ifndef NO_MM
 	file->f_dentry->d_inode->i_ino = shp->id;
 	file->f_op = &shm_file_operations;
+#endif /* NO_MM */
 	shm_tot += numpages;
 	shm_unlock (id);
 	return shp->id;
 
 no_id:
+#ifndef NO_MM
 	fput(file);
+#else
+	kfree(file);
+#endif
+
 no_file:
 	kfree(shp);
 	return error;
@@ -350,7 +384,9 @@
 
 static void shm_get_stat (unsigned long *rss, unsigned long *swp) 
 {
+#ifndef NO_MM
 	struct shmem_inode_info *info;
+#endif
 	int i;
 
 	*rss = 0;
@@ -358,17 +394,23 @@
 
 	for(i = 0; i <= shm_ids.max_id; i++) {
 		struct shmid_kernel* shp;
+#ifndef NO_MM
 		struct inode * inode;
+#endif
 
 		shp = shm_get(i);
 		if(shp == NULL)
 			continue;
+#ifndef NO_MM
 		inode = shp->shm_file->f_dentry->d_inode;
 		info = SHMEM_I(inode);
 		spin_lock (&info->lock);
 		*rss += inode->i_mapping->nrpages;
 		*swp += info->swapped;
 		spin_unlock (&info->lock);
+#else
+		*rss += (shp->shm_segsz + PAGE_SIZE -1) >> PAGE_SHIFT;
+#endif
 	}
 }
 
@@ -474,10 +516,14 @@
 		if(err)
 			goto out_unlock;
 		if(cmd==SHM_LOCK) {
+#ifndef NO_MM
 			shmem_lock(shp->shm_file, 1);
+#endif /* NO_MM */
 			shp->shm_flags |= SHM_LOCKED;
 		} else {
+#ifndef NO_MM
 			shmem_lock(shp->shm_file, 0);
+#endif /* NO_MM */
 			shp->shm_flags &= ~SHM_LOCKED;
 		}
 		shm_unlock(shmid);
@@ -569,8 +615,10 @@
 {
 	struct shmid_kernel *shp;
 	unsigned long addr;
+#ifndef NO_MM
 	unsigned long size;
 	struct file * file;
+#endif /* NO_MM */
 	int    err;
 	unsigned long flags;
 	unsigned long prot;
@@ -622,12 +670,15 @@
 		shm_unlock(shmid);
 		return -EACCES;
 	}
+#ifndef NO_MM
 	file = shp->shm_file;
 	size = file->f_dentry->d_inode->i_size;
+#endif /* NO_MM */
 	shp->shm_nattch++;
 	shm_unlock(shmid);
 
 	down_write(&current->mm->mmap_sem);
+#ifndef NO_MM
 	if (addr && !(shmflg & SHM_REMAP)) {
 		user_addr = ERR_PTR(-EINVAL);
 		if (find_vma_intersection(current->mm, addr, addr + size))
@@ -642,6 +693,16 @@
 	}
 		
 	user_addr = (void*) do_mmap (file, addr, size, prot, flags, 0);
+#else
+	if (addr) {
+		user_addr = ERR_PTR(-EINVAL);
+		goto invalid;
+	}
+
+	user_addr = (void*)shp->shm_file;
+	if (user_addr)
+		shm_inc(shmid);
+#endif /* NO_MM */
 
 invalid:
 	up_write(&current->mm->mmap_sem);
@@ -671,6 +732,7 @@
  */
 asmlinkage long sys_shmdt (char *shmaddr)
 {
+#ifndef NO_MM
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *shmd, *shmdnext;
 	int retval = -EINVAL;
@@ -686,6 +748,30 @@
 	}
 	up_write(&mm->mmap_sem);
 	return retval;
+#else
+	int i;
+
+	down (&shm_ids.sem);
+	for(i= 0; i <= shm_ids.max_id; i++) {
+		struct shmid_kernel* shp;
+
+		shp = shm_lock(i);
+		if(shp!=NULL) {
+			if (shp->shm_file == (struct file *)shmaddr) {
+				shp->shm_lprid = current->pid;
+				shp->shm_dtim = CURRENT_TIME;
+				shp->shm_nattch--;
+				if(shp->shm_nattch == 0 &&
+				   shp->shm_flags & SHM_DEST)
+					shm_destroy (shp);
+				i = shm_ids.max_id+1; /* Make this the last iteration */
+			}
+			shm_unlock(i);
+		}
+	}
+	up (&shm_ids.sem);
+	return 0;
+#endif /* NO_MM */
 }
 
 #ifdef CONFIG_PROC_FS
diff -urN linux-2.4.29/kernel/dma.c linux-2.4.29-uc1/kernel/dma.c
--- linux-2.4.29/kernel/dma.c	2001-02-13 22:14:06.000000000 +0000
+++ linux-2.4.29-uc1/kernel/dma.c	2005-06-14 02:11:54.000000000 +0100
@@ -56,12 +56,16 @@
 
 static struct dma_chan dma_chan_busy[MAX_DMA_CHANNELS] = {
 	{ 0, 0 },
+#if defined(CONFIG_M5307) || defined(CONFIG_M5407)
 	{ 0, 0 },
 	{ 0, 0 },
+#endif
+#ifndef CONFIG_UCLINUX
 	{ 0, 0 },
 	{ 1, "cascade" },
 	{ 0, 0 },
 	{ 0, 0 },
+#endif
 	{ 0, 0 }
 };
 
diff -urN linux-2.4.29/kernel/exit.c linux-2.4.29-uc1/kernel/exit.c
--- linux-2.4.29/kernel/exit.c	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-uc1/kernel/exit.c	2005-06-14 02:11:54.000000000 +0100
@@ -427,7 +427,7 @@
 	struct task_struct *tsk = current;
 
 	if (in_interrupt())
-		panic("Aiee, killing interrupt handler!");
+		panic("Aiee, killing interrupt handler\n");
 	if (!tsk->pid)
 		panic("Attempted to kill the idle task!");
 	if (tsk->pid == 1)
@@ -458,6 +458,9 @@
 
 	tsk->exit_code = code;
 	exit_notify();
+#ifdef CONFIG_SYSCALLTIMER
+ 	current->curr_syscall = 0;
+#endif
 	schedule();
 	BUG();
 /*
@@ -587,7 +590,7 @@
 	return retval;
 }
 
-#if !defined(__alpha__) && !defined(__ia64__)
+#if !defined(__alpha__) && !defined(__ia64__) && !defined(__arm__)
 
 /*
  * sys_waitpid() remains for compatibility. waitpid() should be
diff -urN linux-2.4.29/kernel/fork.c linux-2.4.29-uc1/kernel/fork.c
--- linux-2.4.29/kernel/fork.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/kernel/fork.c	2005-06-14 02:11:54.000000000 +0100
@@ -77,8 +77,11 @@
 	 */
 	max_threads = mempages / (THREAD_SIZE/PAGE_SIZE) / 8;
 
-	init_task.rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
-	init_task.rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
+	/*
+	 * we need to allow at least 10 threads to boot a system
+	 */
+	init_task.rlim[RLIMIT_NPROC].rlim_cur = max(10, max_threads/2);
+	init_task.rlim[RLIMIT_NPROC].rlim_max = max(10, max_threads/2);
 }
 
 /* Protects next_safe and last_pid. */
@@ -142,6 +145,8 @@
 	return 0;
 }
 
+#ifndef CONFIG_UCLINUX
+
 static inline int dup_mmap(struct mm_struct * mm)
 {
 	struct vm_area_struct * mpnt, *tmp, **pprev;
@@ -181,6 +186,7 @@
 		tmp->vm_flags &= ~VM_LOCKED;
 		tmp->vm_mm = mm;
 		tmp->vm_next = NULL;
+		tmp->vm_sharing_data = NULL;
 		file = tmp->vm_file;
 		if (file) {
 			struct inode *inode = file->f_dentry->d_inode;
@@ -218,6 +224,10 @@
 	retval = 0;
 	build_mmap_rb(mm);
 
+#ifdef CONFIG_ARM_FASS
+	arch_new_mm(current, mm);
+#endif
+
 fail_nomem:
 	flush_tlb_mm(current->mm);
 	return retval;
@@ -378,6 +388,131 @@
 	return retval;
 }
 
+#else /* !CONFIG_UCLINUX */
+
+/*
+ * Allocate and initialize an mm_struct.
+ */
+struct mm_struct * mm_alloc(void)
+{
+	struct mm_struct * mm;
+
+	mm = kmem_cache_alloc(mm_cachep, SLAB_KERNEL);
+	if (mm) {
+		memset(mm, 0, sizeof(*mm));
+		atomic_set(&mm->mm_users, 1);
+		atomic_set(&mm->mm_count, 1);
+		init_rwsem(&mm->mmap_sem);
+		mm->page_table_lock = SPIN_LOCK_UNLOCKED;
+		return mm;
+	}
+	return NULL;
+}
+
+/*
+ * Called when the last reference to the mm
+ * is dropped: either by a lazy thread or by
+ * mmput. Free the mm.
+ */
+void fastcall __mmdrop(struct mm_struct *mm)
+{
+	if (mm == &init_mm) BUG();
+	kmem_cache_free(mm_cachep, mm);
+}
+
+/*
+ * Decrement the use count and release all resources for an mm.
+ */
+void mmput(struct mm_struct *mm)
+{
+	if (atomic_dec_and_test(&mm->mm_users)) {
+		exit_mmap(mm);
+		mmdrop(mm);
+	}
+}
+
+/* Please note the differences between mmput and mm_release.
+ * mmput is called whenever we stop holding onto a mm_struct,
+ * error success whatever.
+ *
+ * mm_release is called after a mm_struct has been removed
+ * from the current process.
+ *
+ * This difference is important for error handling, when we
+ * only half set up a mm_struct for a new process and need to restore
+ * the old one.  Because we mmput the new mm_struct before
+ * restoring the old one. . .
+ * Eric Biederman 10 January 1998
+ */
+void mm_release(void)
+{
+	struct task_struct *tsk = current;
+	struct completion *vfork_done = tsk->vfork_done;
+
+	/* notify parent sleeping on vfork() */
+	if (vfork_done) {
+		tsk->vfork_done = NULL;
+		complete(vfork_done);
+	}
+}
+
+static inline int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
+{
+	struct mm_struct * mm;
+	int retval;
+
+	tsk->min_flt = tsk->maj_flt = 0;
+	tsk->cmin_flt = tsk->cmaj_flt = 0;
+	tsk->nswap = tsk->cnswap = 0;
+
+	tsk->mm = NULL;
+	tsk->active_mm = NULL;
+
+	/*
+	 * Are we cloning a kernel thread?
+	 *
+	 * We need to steal a active VM for that..
+	 */
+	mm = current->mm;
+	if (!mm)
+		return 0;
+
+	if (clone_flags & CLONE_VM) {
+		atomic_inc(&mm->mm_users);
+		goto good_mm;
+	}
+
+	retval = -ENOMEM;
+	mm = mm_alloc();
+	if (!mm)
+		goto fail_nomem;
+
+	tsk->mm = mm;
+	tsk->active_mm = mm;
+
+#if DAVIDM /* is this needed,  I took it out as it didn't appear to be */
+	if (tsk->mm->executable)
+		atomic_inc(&tsk->mm->executable->i_count);
+#endif
+
+	/*
+	 * child gets a private LDT (if there was an LDT in the parent)
+	 */
+	copy_segments(tsk, mm);
+
+good_mm:
+	tsk->mm = mm;
+	tsk->active_mm = mm;
+	return 0;
+
+free_pt:
+	mmput(mm);
+fail_nomem:
+	return retval;
+}
+
+#endif /* !CONFIG_UCLINUX */
+
 static inline struct fs_struct *__copy_fs_struct(struct fs_struct *old)
 {
 	struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
@@ -672,6 +807,10 @@
 
 	*p = *current;
 
+#ifdef CONFIG_SYSCALLTIMER
+	p->curr_syscall = 0;
+#endif
+
 	retval = -EAGAIN;
 	/*
 	 * Check if we are over our maximum process limit, but be sure to
diff -urN linux-2.4.29/kernel/ksyms.c linux-2.4.29-uc1/kernel/ksyms.c
--- linux-2.4.29/kernel/ksyms.c	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-uc1/kernel/ksyms.c	2005-06-14 02:11:54.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: ksyms.c,v 1.33 2003/11/12 05:11:57 yoshfuji Exp $ */
+
 /*
  * Herein lies all the functions/variables that are "exported" for linkage
  * with dynamically loaded kernel modules.
@@ -87,7 +89,9 @@
 /* process memory management */
 EXPORT_SYMBOL(do_mmap_pgoff);
 EXPORT_SYMBOL(do_munmap);
+#ifndef NO_MM
 EXPORT_SYMBOL(do_brk);
+#endif
 EXPORT_SYMBOL(exit_mm);
 EXPORT_SYMBOL(exit_files);
 EXPORT_SYMBOL(exit_fs);
@@ -111,17 +115,24 @@
 EXPORT_SYMBOL(kmem_cache_size);
 EXPORT_SYMBOL(kmalloc);
 EXPORT_SYMBOL(kfree);
+#ifdef NO_MM
+EXPORT_SYMBOL(ksize);
+#endif
 EXPORT_SYMBOL(vfree);
 EXPORT_SYMBOL(__vmalloc);
+#ifndef NO_MM
 EXPORT_SYMBOL(vmap);
+#endif
 EXPORT_SYMBOL(vmalloc_to_page);
 EXPORT_SYMBOL(mem_map);
 EXPORT_SYMBOL(remap_page_range);
 EXPORT_SYMBOL(max_mapnr);
 EXPORT_SYMBOL(high_memory);
 EXPORT_SYMBOL(vmtruncate);
+#ifndef NO_MM
 EXPORT_SYMBOL(find_vma);
 EXPORT_SYMBOL(get_unmapped_area);
+#endif
 EXPORT_SYMBOL(init_mm);
 #ifdef CONFIG_HIGHMEM
 EXPORT_SYMBOL(kmap_high);
@@ -303,11 +314,13 @@
 /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
 EXPORT_SYMBOL(default_llseek);
 EXPORT_SYMBOL(dentry_open);
+#ifndef NO_MM
 EXPORT_SYMBOL(filemap_nopage);
 EXPORT_SYMBOL(filemap_sync);
 EXPORT_SYMBOL(filemap_fdatawrite);
 EXPORT_SYMBOL(filemap_fdatasync);
 EXPORT_SYMBOL(filemap_fdatawait);
+#endif
 EXPORT_SYMBOL(lock_page);
 EXPORT_SYMBOL(unlock_page);
 EXPORT_SYMBOL(wakeup_page_waiters);
@@ -365,7 +378,9 @@
 EXPORT_SYMBOL(search_binary_handler);
 EXPORT_SYMBOL(prepare_binprm);
 EXPORT_SYMBOL(compute_creds);
+#ifndef NO_MM
 EXPORT_SYMBOL(remove_arg_zero);
+#endif
 EXPORT_SYMBOL(set_binfmt);
 
 /* sysctl table registration */
@@ -439,9 +454,11 @@
 EXPORT_SYMBOL(kiobuf_wait_for_io);
 
 /* dma handling */
+#ifndef CONFIG_ARM
 EXPORT_SYMBOL(request_dma);
 EXPORT_SYMBOL(free_dma);
 EXPORT_SYMBOL(dma_spin_lock);
+#endif
 #ifdef HAVE_DISABLE_HLT
 EXPORT_SYMBOL(disable_hlt);
 EXPORT_SYMBOL(enable_hlt);
@@ -505,6 +522,10 @@
 EXPORT_SYMBOL(simple_strtoull);
 EXPORT_SYMBOL(system_utsname);	/* UTS data */
 EXPORT_SYMBOL(uts_sem);		/* UTS semaphore */
+#ifdef CONFIG_IPV6_NODEINFO
+EXPORT_SYMBOL(icmpv6_sethostname_hook);
+EXPORT_SYMBOL(icmpv6_sethostname_hook_sem);
+#endif
 #ifndef __mips__
 EXPORT_SYMBOL(sys_call_table);
 #endif
@@ -530,8 +551,10 @@
 EXPORT_SYMBOL(seq_release_private);
 
 /* Program loader interfaces */
+#ifndef NO_MM
 EXPORT_SYMBOL(setup_arg_pages);
 EXPORT_SYMBOL(copy_strings_kernel);
+#endif
 EXPORT_SYMBOL(do_execve);
 EXPORT_SYMBOL(flush_old_exec);
 EXPORT_SYMBOL(kernel_read);
diff -urN linux-2.4.29/kernel/Makefile linux-2.4.29-uc1/kernel/Makefile
--- linux-2.4.29/kernel/Makefile	2001-09-17 05:22:40.000000000 +0100
+++ linux-2.4.29-uc1/kernel/Makefile	2005-06-14 02:11:54.000000000 +0100
@@ -9,13 +9,19 @@
 
 O_TARGET := kernel.o
 
-export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o
+export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o dma.o
 
-obj-y     = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
+obj-y     = sched.o fork.o exec_domain.o panic.o printk.o \
 	    module.o exit.o itimer.o info.o time.o softirq.o resource.o \
 	    sysctl.o acct.o capability.o ptrace.o timer.o user.o \
 	    signal.o sys.o kmod.o context.o
 
+ifndef CONFIG_ARM
+obj-y	 += dma.o
+endif
+
+OX_OBJS  += signal.o sys.o kmod.o context.o
+
 obj-$(CONFIG_UID16) += uid16.o
 obj-$(CONFIG_MODULES) += ksyms.o
 obj-$(CONFIG_PM) += pm.o
diff -urN linux-2.4.29/kernel/module.c linux-2.4.29-uc1/kernel/module.c
--- linux-2.4.29/kernel/module.c	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/kernel/module.c	2005-06-14 02:11:54.000000000 +0100
@@ -25,6 +25,7 @@
  *     http://www.uwsg.iu.edu/hypermail/linux/kernel/0008.3/0379.html
  * Replace xxx_module_symbol with inter_module_xxx.  Keith Owens <kaos@ocs.com.au> Oct 2000
  * Add a module list lock for kernel fault race fixing. Alan Cox <alan@redhat.com>
+ * Fix to respect mod->can_unload(). YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
  *
  * This source is covered by the GNU GPL, the same as all kernel sources.
  */
@@ -880,7 +881,8 @@
 		/* usecount is one too high here - report appropriately to
 		   compensate for locking */
 		info.usecount = (mod_member_present(mod, can_unload)
-				 && mod->can_unload ? -1 : atomic_read(&mod->uc.usecount)-1);
+				 && mod->can_unload && mod->can_unload() 
+				 ? -1 : atomic_read(&mod->uc.usecount)-1);
 
 		if (copy_to_user(buf, &info, sizeof(struct module_info)))
 			return -EFAULT;
@@ -1124,7 +1126,7 @@
 		if (mod->flags & MOD_RUNNING) {
 			len = sprintf(tmpstr, "%4ld",
 				      (mod_member_present(mod, can_unload)
-				       && mod->can_unload
+				       && mod->can_unload && mod->can_unload()
 				       ? -1L : (long)atomic_read(&mod->uc.usecount)));
 			safe_copy_str(tmpstr, len);
 		}
diff -urN linux-2.4.29/kernel/panic.c linux-2.4.29-uc1/kernel/panic.c
--- linux-2.4.29/kernel/panic.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/kernel/panic.c	2005-06-14 02:11:54.000000000 +0100
@@ -76,8 +76,9 @@
 
 	notifier_call_chain(&panic_notifier_list, 0, NULL);
 
-	if (panic_timeout > 0)
-	{
+	if (panic_timeout < 0) {
+		machine_halt();
+	} else if (panic_timeout > 0) {
 		/*
 	 	 * Delay timeout seconds before rebooting the machine. 
 		 * We can't use the "normal" timers since we just panicked..
diff -urN linux-2.4.29/kernel/printk.c linux-2.4.29-uc1/kernel/printk.c
--- linux-2.4.29/kernel/printk.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/kernel/printk.c	2005-06-14 02:11:54.000000000 +0100
@@ -154,6 +154,25 @@
 	return 1;
 }
 
+#ifdef CONFIG_UCLINUX
+/*
+ * DAVIDM - put this in so 2.0 and 2.4 NETtel images work with the
+ *          same boot args.
+ */
+
+static int __init CONSOLE_setup(char *str)
+{
+	/*
+	 *	2.4 does not want the /dev/ options on the front
+	 */
+	if (strncmp(str, "/dev/", 5) == 0)
+		return(console_setup(str + 5));
+	return(console_setup(str));
+}
+
+__setup("CONSOLE=", CONSOLE_setup);
+#endif
+
 __setup("console=", console_setup);
 
 /*
diff -urN linux-2.4.29/kernel/ptrace.c linux-2.4.29-uc1/kernel/ptrace.c
--- linux-2.4.29/kernel/ptrace.c	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/kernel/ptrace.c	2005-06-14 02:11:54.000000000 +0100
@@ -232,3 +232,4 @@
 	}
 	return copied;
 }
+
diff -urN linux-2.4.29/kernel/sched.c linux-2.4.29-uc1/kernel/sched.c
--- linux-2.4.29/kernel/sched.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/kernel/sched.c	2005-06-14 02:11:54.000000000 +0100
@@ -534,6 +534,11 @@
 	__schedule_tail(prev);
 }
 
+#ifdef CONFIG_SYSCALLTIMER
+extern void timepeg_schedule_switchout(void);
+extern void timepeg_schedule_switchin(void);
+#endif
+
 /*
  *  'schedule()' is the scheduler function. It's a very simple and nice
  * scheduler: it's not perfect, but certainly works for most things.
@@ -692,7 +697,13 @@
 	 * This just switches the register state and the
 	 * stack.
 	 */
+#ifdef CONFIG_SYSCALLTIMER
+	timepeg_schedule_switchout();
+#endif
 	switch_to(prev, next, prev);
+#ifdef CONFIG_SYSCALLTIMER
+	timepeg_schedule_switchin();
+#endif
 	__schedule_tail(prev);
 
 same_process:
diff -urN linux-2.4.29/kernel/signal.c linux-2.4.29-uc1/kernel/signal.c
--- linux-2.4.29/kernel/signal.c	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-uc1/kernel/signal.c	2005-06-14 02:11:54.000000000 +0100
@@ -1277,7 +1277,7 @@
 #endif /* __sparc__ */
 #endif
 
-#if !defined(__alpha__) && !defined(__ia64__)
+#if !defined(__alpha__) && !defined(__ia64__) && !defined(__arm__)
 /*
  * For backwards compatibility.  Functionality superseded by sigprocmask.
  */
@@ -1305,7 +1305,8 @@
 }
 #endif /* !defined(__alpha__) */
 
-#if !defined(__alpha__) && !defined(__ia64__) && !defined(__mips__)
+#if !defined(__alpha__) && !defined(__ia64__) && !defined(__mips__) && \
+    !defined(__arm__)
 /*
  * For backwards compatibility.  Functionality superseded by sigaction.
  */
@@ -1322,4 +1323,4 @@
 
 	return ret ? ret : (unsigned long)old_sa.sa.sa_handler;
 }
-#endif /* !alpha && !__ia64__ && !defined(__mips__) */
+#endif /* !alpha && !__ia64__ && !defined(__mips__) && !defined(__arm__) */
diff -urN linux-2.4.29/kernel/softirq.c linux-2.4.29-uc1/kernel/softirq.c
--- linux-2.4.29/kernel/softirq.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/kernel/softirq.c	2005-06-14 02:11:54.000000000 +0100
@@ -16,6 +16,7 @@
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/tqueue.h>
+#include <linux/compiler.h>
 
 /*
    - No shared variables, all the data are CPU local.
@@ -58,20 +59,44 @@
 		wake_up_process(tsk);
 }
 
-asmlinkage void do_softirq()
+static inline int softirqd_is_waken(unsigned cpu)
+{
+	struct task_struct * tsk = ksoftirqd_task(cpu);
+
+	return tsk && tsk->state == TASK_RUNNING;
+}
+
+/*
+ * the higher this number the less likely ksoftirqd will be waken by
+ * a short irq flood peak, but the higher unfariness the softirq load
+ * will generate against the regular scheduler tasks.
+ * Each loop will allow one more block to pass through to the
+ * higher layer. If further blocks keeps arriving we giveup and we
+ * offload the work in a scheduler friendly way. After ksoftirqd
+ * is started we will stop wasting time here, so under attack
+ * we're still competely fair.
+ */
+#define MAX_SOFTIRQ_LOOPS 8
+
+static void __do_softirq(int ksoftirqd)
 {
 	int cpu = smp_processor_id();
 	__u32 pending;
 	unsigned long flags;
 	__u32 mask;
+	int loops;
 
 	if (in_interrupt())
 		return;
 
 	local_irq_save(flags);
 
-	pending = softirq_pending(cpu);
+	if (!ksoftirqd && softirqd_is_waken(cpu))
+		pending = 0;
+	else
+		pending = softirq_pending(cpu);
 
+	loops = 0;
 	if (pending) {
 		struct softirq_action *h;
 
@@ -101,13 +126,26 @@
 		}
 		__local_bh_enable();
 
-		if (pending)
-			wakeup_softirqd(cpu);
+		if (!softirqd_is_waken(cpu)) {
+			if (unlikely(++loops >= MAX_SOFTIRQ_LOOPS)) {
+				if (pending)
+					wakeup_softirqd(cpu);
+			} else {
+				mask = ~pending;
+				local_bh_disable();
+				goto restart;
+			}
+		}
 	}
 
 	local_irq_restore(flags);
 }
 
+asmlinkage void do_softirq()
+{
+	__do_softirq(0);
+}
+
 /*
  * This function must run with irq disabled!
  */
@@ -386,7 +424,7 @@
 		__set_current_state(TASK_RUNNING);
 
 		while (softirq_pending(cpu)) {
-			do_softirq();
+			__do_softirq(1);
 			if (current->need_resched)
 				schedule();
 		}
diff -urN linux-2.4.29/kernel/sys.c linux-2.4.29-uc1/kernel/sys.c
--- linux-2.4.29/kernel/sys.c	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/kernel/sys.c	2005-06-14 02:11:54.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: sys.c,v 1.16 2003/11/12 05:11:57 yoshfuji Exp $ */
+
 /*
  *  linux/kernel/sys.c
  *
@@ -1022,6 +1024,11 @@
 
 DECLARE_RWSEM(uts_sem);
 
+#ifdef CONFIG_IPV6_NODEINFO
+DECLARE_RWSEM(icmpv6_sethostname_hook_sem);
+void (*icmpv6_sethostname_hook)(struct new_utsname *) = NULL;
+#endif
+
 asmlinkage long sys_newuname(struct new_utsname * name)
 {
 	int errno = 0;
@@ -1047,6 +1054,12 @@
 	if (!copy_from_user(tmp, name, len)) {
 		memcpy(system_utsname.nodename, tmp, len);
 		system_utsname.nodename[len] = 0;
+#ifdef CONFIG_IPV6_NODEINFO
+		down_read(&icmpv6_sethostname_hook_sem);
+		if (icmpv6_sethostname_hook)
+			icmpv6_sethostname_hook(&system_utsname);
+		up_read(&icmpv6_sethostname_hook_sem);
+#endif
 		errno = 0;
 	}
 	up_write(&uts_sem);
diff -urN linux-2.4.29/kernel/sysctl.c linux-2.4.29-uc1/kernel/sysctl.c
--- linux-2.4.29/kernel/sysctl.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/kernel/sysctl.c	2005-06-14 02:11:54.000000000 +0100
@@ -33,6 +33,7 @@
 #include <linux/swap.h>
 
 #include <asm/uaccess.h>
+#include <asm/semaphore.h>
 
 #ifdef CONFIG_ROOT_NFS
 #include <linux/nfs_fs.h>
@@ -44,7 +45,9 @@
 extern int panic_timeout;
 extern int C_A_D;
 extern int bdf_prm[], bdflush_min[], bdflush_max[];
+#ifndef NO_MM
 extern int sysctl_overcommit_memory;
+#endif
 extern int max_threads;
 extern atomic_t nr_queued_signals;
 extern int max_queued_signals;
@@ -106,7 +109,9 @@
 extern int acct_parm[];
 #endif
 
+#ifndef NO_MM
 extern int pgt_cache_water[];
+#endif
 
 static int parse_table(int *, int, void *, size_t *, void *, size_t,
 		       ctl_table *, void **);
@@ -118,7 +123,9 @@
 	{ root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
 
 static ctl_table kern_table[];
+#ifndef NO_MM
 static ctl_table vm_table[];
+#endif
 #ifdef CONFIG_NET
 extern ctl_table net_table[];
 #endif
@@ -155,7 +162,9 @@
 
 static ctl_table root_table[] = {
 	{CTL_KERN, "kernel", NULL, 0, 0555, kern_table},
+#ifndef NO_MM
 	{CTL_VM, "vm", NULL, 0, 0555, vm_table},
+#endif
 #ifdef CONFIG_NET
 	{CTL_NET, "net", NULL, 0, 0555, net_table},
 #endif
@@ -281,6 +290,7 @@
 	{0}
 };
 
+#ifndef NO_MM
 static ctl_table vm_table[] = {
 	{VM_GFP_DEBUG, "vm_gfp_debug", 
 	 &vm_gfp_debug, sizeof(int), 0644, NULL, &proc_dointvec},
@@ -319,6 +329,7 @@
 	 &block_dump, sizeof(int), 0644, NULL, &proc_dointvec},
 	{0}
 };
+#endif /* NO_MM */
 
 static ctl_table proc_table[] = {
 	{0}
diff -urN linux-2.4.29/kernel/time.c linux-2.4.29-uc1/kernel/time.c
--- linux-2.4.29/kernel/time.c	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-uc1/kernel/time.c	2005-06-14 02:11:54.000000000 +0100
@@ -40,6 +40,38 @@
    serializing all accesses to the global NTP variables now. */
 extern rwlock_t xtime_lock;
 
+void print_current_time(int new) {
+	long s, j, d, m, y;
+	struct timeval	new_tv;
+
+	do_gettimeofday(&new_tv);
+
+	j = new_tv.tv_sec / 86400L + 719469;
+	s = new_tv.tv_sec % 86400L;
+
+	if( s < 0 ) { s += 86400L; j--; }
+
+	y = (4L * j - 1L) / 146097L;
+	j = 4L * j - 1L - 146097L * y;
+	d = j / 4L;
+	j = (4L * d + 3L) / 1461L;
+	d = 4L * d + 3L - 1461L * j;
+	d = (d + 4L) / 4L;
+	m = (5L * d - 3L) / 153L;
+	d = 5L * d - 3 - 153L * m;
+	d = (d + 5L) / 5L;
+	y = 100L * y + j;
+	if (m < 10)
+		m += 2;
+	else
+	{
+		m -= 10;
+		++y;
+	}
+	printk(KERN_NOTICE "Clock: %s time %04d/%02d/%02d - %02d:%02d:%02d\n",
+		new ? "new" : "old", y, (int) m + 1, (int) d, (int) (s / 3600 ), (int) (s / 60) % 60, (int) s % 60);
+}
+
 #if !defined(__alpha__) && !defined(__ia64__)
 
 /*
@@ -79,6 +111,7 @@
 		return -EPERM;
 	if (get_user(value, tptr))
 		return -EFAULT;
+	print_current_time(0);
 	write_lock_irq(&xtime_lock);
 	vxtime_lock();
 	xtime.tv_sec = value;
@@ -89,6 +122,7 @@
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
 	write_unlock_irq(&xtime_lock);
+	print_current_time(1);
 	return 0;
 }
 
@@ -175,7 +209,9 @@
 {
 	struct timeval	new_tv;
 	struct timezone new_tz;
+	int ret;
 
+	print_current_time(0);
 	if (tv) {
 		if (copy_from_user(&new_tv, tv, sizeof(*tv)))
 			return -EFAULT;
@@ -184,8 +220,10 @@
 		if (copy_from_user(&new_tz, tz, sizeof(*tz)))
 			return -EFAULT;
 	}
+	ret = do_sys_settimeofday(tv ? &new_tv : NULL, tz ? &new_tz : NULL);
+	print_current_time(1);
 
-	return do_sys_settimeofday(tv ? &new_tv : NULL, tz ? &new_tz : NULL);
+	return ret;
 }
 
 long pps_offset;		/* pps time offset (us) */
diff -urN linux-2.4.29/kernel/timer.c linux-2.4.29-uc1/kernel/timer.c
--- linux-2.4.29/kernel/timer.c	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-uc1/kernel/timer.c	2005-06-14 02:11:54.000000000 +0100
@@ -24,6 +24,7 @@
 #include <linux/kernel_stat.h>
 
 #include <asm/uaccess.h>
+#include <asm/io.h>
 
 /*
  * Timekeeping variables
@@ -495,7 +496,23 @@
 	    /* Reduce by this step the amount of time left  */
 	    time_adjust -= time_adjust_step;
 	}
+#if 0
+//#if defined(CONFIG_MTD_NETtel) && !defined(CONFIG_TIMEPEG)
+{
+	extern void *cpu_mmcrp;
+	register long ms;
+	/* Work around for glitching problem of SC520 - Rev A1 silicon */
+	if (cpu_mmcrp) {
+		/* Use SC520 millisecond timer */
+		ms = *((volatile unsigned short *) (cpu_mmcrp + 0xc60));
+		xtime.tv_usec += (ms * 1000) + time_adjust_step;
+	} else {
+		xtime.tv_usec += tick + time_adjust_step;
+	}
+}
+#else
 	xtime.tv_usec += tick + time_adjust_step;
+#endif
 	/*
 	 * Advance the phase, once it gets to one microsecond, then
 	 * advance the tick more.
@@ -707,6 +724,9 @@
 	mark_bh(TIMER_BH);
 	if (TQ_ACTIVE(tq_timer))
 		mark_bh(TQUEUE_BH);
+#ifdef CONFIG_SNAPDOG
+    snapdog_service(regs);
+#endif
 }
 
 #if !defined(__alpha__) && !defined(__ia64__)
diff -urN linux-2.4.29/lib/Config.in linux-2.4.29-uc1/lib/Config.in
--- linux-2.4.29/lib/Config.in	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/lib/Config.in	2005-06-14 02:11:48.000000000 +0100
@@ -13,6 +13,7 @@
      "$CONFIG_PPP_DEFLATE" = "y" -o \
      "$CONFIG_CRYPTO_DEFLATE" = "y" -o \
      "$CONFIG_JFFS2_FS" = "y" -o \
+     "$CONFIG_BINFMT_ZFLAT" = "y" -o \
      "$CONFIG_ZISOFS_FS" = "y" ]; then
    define_tristate CONFIG_ZLIB_INFLATE y
 else
diff -urN linux-2.4.29/lib/inflate2.c linux-2.4.29-uc1/lib/inflate2.c
--- linux-2.4.29/lib/inflate2.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/lib/inflate2.c	2005-06-14 02:11:48.000000000 +0100
@@ -0,0 +1,1165 @@
+#define DEBG(x)
+#define DEBG1(x)
+/* inflate.c -- Not copyrighted 1992 by Mark Adler
+   version c10p1, 10 January 1993 */
+
+/* 
+ * Adapted for booting Linux by Hannu Savolainen 1993
+ * based on gzip-1.0.3 
+ */
+
+/*
+   Inflate deflated (PKZIP's method 8 compressed) data.  The compression
+   method searches for as much of the current string of bytes (up to a
+   length of 258) in the previous 32K bytes.  If it doesn't find any
+   matches (of at least length 3), it codes the next byte.  Otherwise, it
+   codes the length of the matched string and its distance backwards from
+   the current position.  There is a single Huffman code that codes both
+   single bytes (called "literals") and match lengths.  A second Huffman
+   code codes the distance information, which follows a length code.  Each
+   length or distance code actually represents a base value and a number
+   of "extra" (sometimes zero) bits to get to add to the base value.  At
+   the end of each deflated block is a special end-of-block (EOB) literal/
+   length code.  The decoding process is basically: get a literal/length
+   code; if EOB then done; if a literal, emit the decoded byte; if a
+   length then get the distance and emit the referred-to bytes from the
+   sliding window of previously emitted data.
+
+   There are (currently) three kinds of inflate blocks: stored, fixed, and
+   dynamic.  The compressor deals with some chunk of data at a time, and
+   decides which method to use on a chunk-by-chunk basis.  A chunk might
+   typically be 32K or 64K.  If the chunk is uncompressible, then the
+   "stored" method is used.  In this case, the bytes are simply stored as
+   is, eight bits per byte, with none of the above coding.  The bytes are
+   preceded by a count, since there is no longer an EOB code.
+
+   If the data is compressible, then either the fixed or dynamic methods
+   are used.  In the dynamic method, the compressed data is preceded by
+   an encoding of the literal/length and distance Huffman codes that are
+   to be used to decode this block.  The representation is itself Huffman
+   coded, and so is preceded by a description of that code.  These code
+   descriptions take up a little space, and so for small blocks, there is
+   a predefined set of codes, called the fixed codes.  The fixed method is
+   used if the block codes up smaller that way (usually for quite small
+   chunks), otherwise the dynamic method is used.  In the latter case, the
+   codes are customized to the probabilities in the current block, and so
+   can code it much better than the pre-determined fixed codes.
+ 
+   The Huffman codes themselves are decoded using a multi-level table
+   lookup, in order to maximize the speed of decoding plus the speed of
+   building the decoding tables.  See the comments below that precede the
+   lbits and dbits tuning parameters.
+ */
+
+
+/*
+   Notes beyond the 1.93a appnote.txt:
+
+   1. Distance pointers never point before the beginning of the output
+      stream.
+   2. Distance pointers can point back across blocks, up to 32k away.
+   3. There is an implied maximum of 7 bits for the bit length table and
+      15 bits for the actual data.
+   4. If only one code exists, then it is encoded using one bit.  (Zero
+      would be more efficient, but perhaps a little confusing.)  If two
+      codes exist, they are coded using one bit each (0 and 1).
+   5. There is no way of sending zero distance codes--a dummy must be
+      sent if there are none.  (History: a pre 2.0 version of PKZIP would
+      store blocks with no distance codes, but this was discovered to be
+      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
+      zero distance codes, which is sent as one code of zero bits in
+      length.
+   6. There are up to 286 literal/length codes.  Code 256 represents the
+      end-of-block.  Note however that the static length tree defines
+      288 codes just to fill out the Huffman codes.  Codes 286 and 287
+      cannot be used though, since there is no length base or extra bits
+      defined for them.  Similarly, there are up to 30 distance codes.
+      However, static trees define 32 codes (all 5 bits) to fill out the
+      Huffman codes, but the last two had better not show up in the data.
+   7. Unzip can check dynamic Huffman blocks for complete code sets.
+      The exception is that a single code would not be complete (see #4).
+   8. The five bits following the block type is really the number of
+      literal codes sent minus 257.
+   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
+      (1+6+6).  Therefore, to output three times the length, you output
+      three codes (1+1+1), whereas to output four times the same length,
+      you only need two codes (1+3).  Hmm.
+  10. In the tree reconstruction algorithm, Code = Code + Increment
+      only if BitLength(i) is not zero.  (Pretty obvious.)
+  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
+  12. Note: length code 284 can represent 227-258, but length code 285
+      really is 258.  The last length deserves its own, short code
+      since it gets used a lot in very redundant files.  The length
+      258 is special since 258 - 3 (the min match length) is 255.
+  13. The literal/length and distance code bit lengths are read as a
+      single stream of lengths.  It is possible (and advantageous) for
+      a repeat code (16, 17, or 18) to go across the boundary between
+      the two sets of lengths.
+ */
+
+#ifdef RCSID
+static char rcsid[] = "#Id: inflate.c,v 0.14 1993/06/10 13:27:04 jloup Exp #";
+#endif
+
+#ifndef STATIC
+
+#if defined(STDC_HEADERS) || defined(HAVE_STDLIB_H)
+#  include <sys/types.h>
+#  include <stdlib.h>
+#endif
+
+#include "gzip.h"
+#define STATIC
+#endif /* !STATIC */
+	
+#define slide window
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+   that have 16-bit pointers (e.g. PC's in the small or medium model).
+   Valid extra bits are 0..13.  e == 15 is EOB (end of block), e == 16
+   means that v is a literal, 16 < e < 32 means that v is a pointer to
+   the next table, which codes e - 16 bits, and lastly e == 99 indicates
+   an unused code.  If a code with e == 99 is looked up, this implies an
+   error in the data. */
+struct huft {
+  uch e;                /* number of extra bits or operation */
+  uch b;                /* number of bits in this code or subcode */
+  union {
+    ush n;              /* literal, length base, or distance base */
+    struct huft *t;     /* pointer to next level of table */
+  } v;
+};
+
+
+/* Function prototypes */
+STATIC int huft_build OF((struct s_zloc*, unsigned *, unsigned, unsigned, ush *, ush *,
+                   struct huft **, int *));
+STATIC int huft_free OF((struct s_zloc*, struct huft *));
+STATIC int inflate_codes OF((struct s_zloc*, struct huft *, struct huft *, int, int));
+STATIC int inflate_stored OF((struct s_zloc*));
+STATIC int inflate_fixed OF((struct s_zloc*));
+STATIC int inflate_dynamic OF((struct s_zloc*));
+STATIC int inflate_block OF((struct s_zloc*, int *));
+STATIC int inflate OF((struct s_zloc*));
+
+
+/* The inflate algorithm uses a sliding 32K byte window on the uncompressed
+   stream to find repeated byte strings.  This is implemented here as a
+   circular buffer.  The index is updated simply by incrementing and then
+   and'ing with 0x7fff (32K-1). */
+/* It is left to other modules to supply the 32K area.  It is assumed
+   to be usable as if it were declared "uch slide[32768];" or as just
+   "uch *slide;" and then malloc'ed in the latter case.  The definition
+   must be in unzip.h, included above. */
+/* unsigned wp;             current position in slide */
+#define wp outcnt
+#define flush_output(w) (wp=(w),flush_window(zloc))
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+static unsigned border[] = {    /* Order of the bit length code lengths */
+        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+static ush cplens[] = {         /* Copy lengths for literal codes 257..285 */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+        /* note: see note #13 above about the 258 in this list. */
+static ush cplext[] = {         /* Extra bits for literal codes 257..285 */
+        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */
+static ush cpdist[] = {         /* Copy offsets for distance codes 0..29 */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577};
+static ush cpdext[] = {         /* Extra bits for distance codes */
+        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+        12, 12, 13, 13};
+
+
+
+/* Macros for inflate() bit peeking and grabbing.
+   The usage is:
+   
+        NEEDBITS(j)
+        x = b & mask_bits[j];
+        DUMPBITS(j)
+
+   where NEEDBITS makes sure that b has at least j bits in it, and
+   DUMPBITS removes the bits from b.  The macros use the variable k
+   for the number of bits in b.  Normally, b and k are register
+   variables for speed, and are initialized at the beginning of a
+   routine that uses these macros from a global bit buffer and count.
+
+   If we assume that EOB will be the longest code, then we will never
+   ask for bits with NEEDBITS that are beyond the end of the stream.
+   So, NEEDBITS should not read any more bytes than are needed to
+   meet the request.  Then no bytes need to be "returned" to the buffer
+   at the end of the last block.
+
+   However, this assumption is not true for fixed blocks--the EOB code
+   is 7 bits, but the other literal/length codes can be 8 or 9 bits.
+   (The EOB code is shorter than other codes because fixed blocks are
+   generally short.  So, while a block always has an EOB, many other
+   literal/length codes have a significantly lower probability of
+   showing up at all.)  However, by making the first table have a
+   lookup of seven bits, the EOB code will be found in that first
+   lookup, and so will not require that too many bits be pulled from
+   the stream.
+ */
+
+STATIC ush mask_bits[] = {
+    0x0000,
+    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+#define NEXTBYTE()  (uch)get_byte()
+#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}}
+#define DUMPBITS(n) {b>>=(n);k-=(n);}
+
+
+/*
+   Huffman code decoding is performed using a multi-level table lookup.
+   The fastest way to decode is to simply build a lookup table whose
+   size is determined by the longest code.  However, the time it takes
+   to build this table can also be a factor if the data being decoded
+   is not very long.  The most common codes are necessarily the
+   shortest codes, so those codes dominate the decoding time, and hence
+   the speed.  The idea is you can have a shorter table that decodes the
+   shorter, more probable codes, and then point to subsidiary tables for
+   the longer codes.  The time it costs to decode the longer codes is
+   then traded against the time it takes to make longer tables.
+
+   This results of this trade are in the variables lbits and dbits
+   below.  lbits is the number of bits the first level table for literal/
+   length codes can decode in one step, and dbits is the same thing for
+   the distance codes.  Subsequent tables are also less than or equal to
+   those sizes.  These values may be adjusted either when all of the
+   codes are shorter than that, in which case the longest code length in
+   bits is used, or when the shortest code is *longer* than the requested
+   table size, in which case the length of the shortest code in bits is
+   used.
+
+   There are two different values for the two tables, since they code a
+   different number of possibilities each.  The literal/length table
+   codes 286 possible values, or in a flat code, a little over eight
+   bits.  The distance table codes 30 possible values, or a little less
+   than five bits, flat.  The optimum values for speed end up being
+   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
+   The optimum values may differ though from machine to machine, and
+   possibly even between compilers.  Your mileage may vary.
+ */
+
+
+STATIC int lbits = 9;          /* bits in base literal/length lookup table */
+STATIC int dbits = 6;          /* bits in base distance lookup table */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
+#define BMAX 16         /* maximum bit length of any code (16 for explode) */
+#define N_MAX 288       /* maximum number of codes in any set */
+
+
+STATIC int huft_build(zloc, b, n, s, d, e, t, m)
+struct s_zloc *zloc;
+unsigned *b;            /* code lengths in bits (all assumed <= BMAX) */
+unsigned n;             /* number of codes (assumed <= N_MAX) */
+unsigned s;             /* number of simple-valued codes (0..s-1) */
+ush *d;                 /* list of base values for non-simple codes */
+ush *e;                 /* list of extra bits for non-simple codes */
+struct huft **t;        /* result: starting table */
+int *m;                 /* maximum lookup bits, returns actual */
+/* Given a list of code lengths and a maximum table size, make a set of
+   tables to decode that set of codes.  Return zero on success, one if
+   the given code set is incomplete (the tables are still built in this
+   case), two if the input is invalid (all zero length codes or an
+   oversubscribed set of lengths), and three if not enough memory. */
+{
+  unsigned a;                   /* counter for codes of length k */
+  unsigned c[BMAX+1];           /* bit length count table */
+  unsigned f;                   /* i repeats in table every f entries */
+  int g;                        /* maximum code length */
+  int h;                        /* table level */
+  register unsigned i;          /* counter, current code */
+  register unsigned j;          /* counter */
+  register int k;               /* number of bits in current code */
+  int l;                        /* bits per table (returned in m) */
+  register unsigned *p;         /* pointer into c[], b[], or v[] */
+  register struct huft *q;      /* points to current table */
+  struct huft r;                /* table entry for structure assignment */
+  struct huft *u[BMAX];         /* table stack */
+  static unsigned v[N_MAX];     /* values in order of bit length */
+  register int w;               /* bits before this table == (l * h) */
+  unsigned x[BMAX+1];           /* bit offsets, then code stack */
+  unsigned *xp;                 /* pointer into x */
+  int y;                        /* number of dummy codes added */
+  unsigned z;                   /* number of entries in current table */
+
+DEBG("huft1 ");
+
+  /* Generate counts for each bit length */
+  memzero(c, sizeof(c));
+  p = b;  i = n;
+  do {
+    Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"), 
+	    n-i, *p));
+    c[*p]++;                    /* assume all entries <= BMAX */
+    p++;                      /* Can't combine with above line (Solaris bug) */
+  } while (--i);
+  if (c[0] == n)                /* null input--all zero length codes */
+  {
+    *t = (struct huft *)NULL;
+    *m = 0;
+    return 0;
+  }
+
+DEBG("huft2 ");
+
+  /* Find minimum and maximum length, bound *m by those */
+  l = *m;
+  for (j = 1; j <= BMAX; j++)
+    if (c[j])
+      break;
+  k = j;                        /* minimum code length */
+  if ((unsigned)l < j)
+    l = j;
+  for (i = BMAX; i; i--)
+    if (c[i])
+      break;
+  g = i;                        /* maximum code length */
+  if ((unsigned)l > i)
+    l = i;
+  *m = l;
+
+DEBG("huft3 ");
+
+  /* Adjust last length count to fill out codes, if needed */
+  for (y = 1 << j; j < i; j++, y <<= 1)
+    if ((y -= c[j]) < 0)
+      return 2;                 /* bad input: more codes than bits */
+  if ((y -= c[i]) < 0)
+    return 2;
+  c[i] += y;
+
+DEBG("huft4 ");
+
+  /* Generate starting offsets into the value table for each length */
+  x[1] = j = 0;
+  p = c + 1;  xp = x + 2;
+  while (--i) {                 /* note that i == g from above */
+    *xp++ = (j += *p++);
+  }
+
+DEBG("huft5 ");
+
+  /* Make a table of values in order of bit lengths */
+  p = b;  i = 0;
+  do {
+    if ((j = *p++) != 0)
+      v[x[j]++] = i;
+  } while (++i < n);
+
+DEBG("h6 ");
+
+  /* Generate the Huffman codes and for each, make the table entries */
+  x[0] = i = 0;                 /* first Huffman code is zero */
+  p = v;                        /* grab values in bit order */
+  h = -1;                       /* no tables yet--level -1 */
+  w = -l;                       /* bits decoded == (l * h) */
+  u[0] = (struct huft *)NULL;   /* just to keep compilers happy */
+  q = (struct huft *)NULL;      /* ditto */
+  z = 0;                        /* ditto */
+DEBG("h6a ");
+
+  /* go through the bit lengths (k already is bits in shortest code) */
+  for (; k <= g; k++)
+  {
+DEBG("h6b ");
+    a = c[k];
+    while (a--)
+    {
+DEBG("h6b1 ");
+      /* here i is the Huffman code of length k bits for value *p */
+      /* make tables up to required level */
+      while (k > w + l)
+      {
+DEBG1("1 ");
+        h++;
+        w += l;                 /* previous table always l bits */
+
+        /* compute minimum size table less than or equal to l bits */
+        z = (z = g - w) > (unsigned)l ? l : z;  /* upper limit on table size */
+        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
+        {                       /* too few codes for k-w bit table */
+DEBG1("2 ");
+          f -= a + 1;           /* deduct codes from patterns left */
+          xp = c + k;
+          while (++j < z)       /* try smaller tables up to z bits */
+          {
+            if ((f <<= 1) <= *++xp)
+              break;            /* enough codes to use up j bits */
+            f -= *xp;           /* else deduct codes from patterns */
+          }
+        }
+DEBG1("3 ");
+        z = 1 << j;             /* table entries for j-bit table */
+
+        /* allocate and link in new table */
+        if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) ==
+            (struct huft *)NULL)
+        {
+          if (h)
+            huft_free(zloc, u[0]);
+          return 3;             /* not enough memory */
+        }
+DEBG1("4 ");
+        hufts += z + 1;         /* track memory usage */
+        *t = q + 1;             /* link to list for huft_free() */
+        *(t = &(q->v.t)) = (struct huft *)NULL;
+        u[h] = ++q;             /* table starts after link */
+
+DEBG1("5 ");
+        /* connect to last table, if there is one */
+        if (h)
+        {
+          x[h] = i;             /* save pattern for backing up */
+          r.b = (uch)l;         /* bits to dump before this table */
+          r.e = (uch)(16 + j);  /* bits in this table */
+          r.v.t = q;            /* pointer to this table */
+          j = i >> (w - l);     /* (get around Turbo C bug) */
+          u[h-1][j] = r;        /* connect to last table */
+        }
+DEBG1("6 ");
+      }
+DEBG("h6c ");
+
+      /* set up table entry in r */
+      r.b = (uch)(k - w);
+      if (p >= v + n)
+        r.e = 99;               /* out of values--invalid code */
+      else if (*p < s)
+      {
+        r.e = (uch)(*p < 256 ? 16 : 15);    /* 256 is end-of-block code */
+        r.v.n = (ush)(*p);             /* simple code is just the value */
+	p++;                           /* one compiler does not like *p++ */
+      }
+      else
+      {
+        r.e = (uch)e[*p - s];   /* non-simple--look up in lists */
+        r.v.n = d[*p++ - s];
+      }
+DEBG("h6d ");
+
+      /* fill code-like entries with r */
+      f = 1 << (k - w);
+      for (j = i >> w; j < z; j += f)
+        q[j] = r;
+
+      /* backwards increment the k-bit code i */
+      for (j = 1 << (k - 1); i & j; j >>= 1)
+        i ^= j;
+      i ^= j;
+
+      /* backup over finished tables */
+      while ((i & ((1 << w) - 1)) != x[h])
+      {
+        h--;                    /* don't need to update q */
+        w -= l;
+      }
+DEBG("h6e ");
+    }
+DEBG("h6f ");
+  }
+
+DEBG("huft7 ");
+
+  /* Return true (1) if we were given an incomplete table */
+  return y != 0 && g != 1;
+}
+
+
+
+STATIC int huft_free(zloc, t)
+struct s_zloc *zloc;
+struct huft *t;         /* table to free */
+/* Free the malloc'ed tables built by huft_build(), which makes a linked
+   list of the tables it made, with the links in a dummy first entry of
+   each table. */
+{
+  register struct huft *p, *q;
+
+
+  /* Go through linked list, freeing from the malloced (t[-1]) address. */
+  p = t;
+  while (p != (struct huft *)NULL)
+  {
+    q = (--p)->v.t;
+    free((char*)p);
+    p = q;
+  } 
+  return 0;
+}
+
+
+STATIC int inflate_codes(zloc, tl, td, bl, bd)
+struct s_zloc *zloc;
+struct huft *tl, *td;   /* literal/length and distance decoder tables */
+int bl, bd;             /* number of bits decoded by tl[] and td[] */
+/* inflate (decompress) the codes in a deflated (compressed) block.
+   Return an error code or zero if it all goes ok. */
+{
+  register unsigned e;  /* table entry flag/number of extra bits */
+  unsigned n, d;        /* length and index for copy */
+  unsigned w;           /* current window position */
+  struct huft *t;       /* pointer to table entry */
+  unsigned ml, md;      /* masks for bl and bd bits */
+  register ulg b;       /* bit buffer */
+  register unsigned k;  /* number of bits in bit buffer */
+
+
+  /* make local copies of globals */
+  b = bb;                       /* initialize bit buffer */
+  k = bk;
+  w = wp;                       /* initialize window position */
+
+  /* inflate the coded data */
+  ml = mask_bits[bl];           /* precompute masks for speed */
+  md = mask_bits[bd];
+  for (;;)                      /* do until end of block */
+  {
+    NEEDBITS((unsigned)bl)
+    if ((e = (t = tl + ((unsigned)b & ml))->e) > 16)
+      do {
+        if (e == 99)
+          return 1;
+        DUMPBITS(t->b)
+        e -= 16;
+        NEEDBITS(e)
+      } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16);
+    DUMPBITS(t->b)
+    if (e == 16)                /* then it's a literal */
+    {
+      slide[w++] = (uch)t->v.n;
+      Tracevv((stderr, "%c", slide[w-1]));
+      if (w == WSIZE)
+      {
+        flush_output(w);
+        w = 0;
+      }
+    }
+    else                        /* it's an EOB or a length */
+    {
+      /* exit if end of block */
+      if (e == 15)
+        break;
+
+      /* get length of block to copy */
+      NEEDBITS(e)
+      n = t->v.n + ((unsigned)b & mask_bits[e]);
+      DUMPBITS(e);
+
+      /* decode distance of block to copy */
+      NEEDBITS((unsigned)bd)
+      if ((e = (t = td + ((unsigned)b & md))->e) > 16)
+        do {
+          if (e == 99)
+            return 1;
+          DUMPBITS(t->b)
+          e -= 16;
+          NEEDBITS(e)
+        } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16);
+      DUMPBITS(t->b)
+      NEEDBITS(e)
+      d = w - t->v.n - ((unsigned)b & mask_bits[e]);
+      DUMPBITS(e)
+      Tracevv((stderr,"\\[%d,%d]", w-d, n));
+
+      /* do the copy */
+      do {
+        n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
+#if !defined(NOMEMCPY) && !defined(INFDEBUG)
+        if (w - d >= e)         /* (this test assumes unsigned comparison) */
+        {
+          memcpy(slide + w, slide + d, e);
+          w += e;
+          d += e;
+        }
+        else                      /* do it slow to avoid memcpy() overlap */
+#endif /* !NOMEMCPY */
+          do {
+            slide[w++] = slide[d++];
+	    Tracevv((stderr, "%c", slide[w-1]));
+          } while (--e);
+        if (w == WSIZE)
+        {
+          flush_output(w);
+          w = 0;
+        }
+      } while (n);
+    }
+  }
+
+
+  /* restore the globals from the locals */
+  wp = w;                       /* restore global window pointer */
+  bb = b;                       /* restore global bit buffer */
+  bk = k;
+
+  /* done */
+  return 0;
+}
+
+
+
+STATIC int inflate_stored(zloc)
+struct s_zloc *zloc;
+/* "decompress" an inflated type 0 (stored) block. */
+{
+  unsigned n;           /* number of bytes in block */
+  unsigned w;           /* current window position */
+  register ulg b;       /* bit buffer */
+  register unsigned k;  /* number of bits in bit buffer */
+
+DEBG("<stor");
+
+  /* make local copies of globals */
+  b = bb;                       /* initialize bit buffer */
+  k = bk;
+  w = wp;                       /* initialize window position */
+
+
+  /* go to byte boundary */
+  n = k & 7;
+  DUMPBITS(n);
+
+
+  /* get the length and its complement */
+  NEEDBITS(16)
+  n = ((unsigned)b & 0xffff);
+  DUMPBITS(16)
+  NEEDBITS(16)
+  if (n != (unsigned)((~b) & 0xffff))
+    return 1;                   /* error in compressed data */
+  DUMPBITS(16)
+
+
+  /* read and output the compressed data */
+  while (n--)
+  {
+    NEEDBITS(8)
+    slide[w++] = (uch)b;
+    if (w == WSIZE)
+    {
+      flush_output(w);
+      w = 0;
+    }
+    DUMPBITS(8)
+  }
+
+
+  /* restore the globals from the locals */
+  wp = w;                       /* restore global window pointer */
+  bb = b;                       /* restore global bit buffer */
+  bk = k;
+
+  DEBG(">");
+  return 0;
+}
+
+
+
+STATIC int inflate_fixed(zloc)
+struct s_zloc *zloc;
+/* decompress an inflated type 1 (fixed Huffman codes) block.  We should
+   either replace this with a custom decoder, or at least precompute the
+   Huffman tables. */
+{
+  int i;                  /* temporary variable */
+  struct huft *tl;        /* literal/length code table */
+  struct huft *td;        /* distance code table */
+  int bl;                 /* lookup bits for tl */
+  int bd;                 /* lookup bits for td */
+  static unsigned l[288]; /* length list for huft_build */
+
+DEBG("<fix");
+
+  /* set up literal table */
+  for (i = 0; i < 144; i++)
+    l[i] = 8;
+  for (; i < 256; i++)
+    l[i] = 9;
+  for (; i < 280; i++)
+    l[i] = 7;
+  for (; i < 288; i++)          /* make a complete, but wrong code set */
+    l[i] = 8;
+  bl = 7;
+  if ((i = huft_build(zloc, l, 288, 257, cplens, cplext, &tl, &bl)) != 0)
+    return i;
+
+
+  /* set up distance table */
+  for (i = 0; i < 30; i++)      /* make an incomplete code set */
+    l[i] = 5;
+  bd = 5;
+  if ((i = huft_build(zloc, l, 30, 0, cpdist, cpdext, &td, &bd)) > 1)
+  {
+    huft_free(zloc, tl);
+
+    DEBG(">");
+    return i;
+  }
+
+
+  /* decompress until an end-of-block code */
+  if (inflate_codes(zloc, tl, td, bl, bd))
+    return 1;
+
+
+  /* free the decoding tables, return */
+  huft_free(zloc, tl);
+  huft_free(zloc, td);
+  return 0;
+}
+
+
+
+STATIC int inflate_dynamic(zloc)
+struct s_zloc *zloc;
+/* decompress an inflated type 2 (dynamic Huffman codes) block. */
+{
+  int i;                /* temporary variables */
+  unsigned j;
+  unsigned l;           /* last length */
+  unsigned m;           /* mask for bit lengths table */
+  unsigned n;           /* number of lengths to get */
+  struct huft *tl;      /* literal/length code table */
+  struct huft *td;      /* distance code table */
+  int bl;               /* lookup bits for tl */
+  int bd;               /* lookup bits for td */
+  unsigned nb;          /* number of bit length codes */
+  unsigned nl;          /* number of literal/length codes */
+  unsigned nd;          /* number of distance codes */
+#ifdef PKZIP_BUG_WORKAROUND
+  static unsigned ll[288+32];  /* literal/length and distance code lengths */
+#else
+  static unsigned ll[286+30];  /* literal/length and distance code lengths */
+#endif
+  register ulg b;       /* bit buffer */
+  register unsigned k;  /* number of bits in bit buffer */
+
+DEBG("<dyn");
+
+  /* make local bit buffer */
+  b = bb;
+  k = bk;
+
+
+  /* read in table lengths */
+  NEEDBITS(5)
+  nl = 257 + ((unsigned)b & 0x1f);      /* number of literal/length codes */
+  DUMPBITS(5)
+  NEEDBITS(5)
+  nd = 1 + ((unsigned)b & 0x1f);        /* number of distance codes */
+  DUMPBITS(5)
+  NEEDBITS(4)
+  nb = 4 + ((unsigned)b & 0xf);         /* number of bit length codes */
+  DUMPBITS(4)
+#ifdef PKZIP_BUG_WORKAROUND
+  if (nl > 288 || nd > 32)
+#else
+  if (nl > 286 || nd > 30)
+#endif
+    return 1;                   /* bad lengths */
+
+DEBG("dyn1 ");
+
+  /* read in bit-length-code lengths */
+  for (j = 0; j < nb; j++)
+  {
+    NEEDBITS(3)
+    ll[border[j]] = (unsigned)b & 7;
+    DUMPBITS(3)
+  }
+  for (; j < 19; j++)
+    ll[border[j]] = 0;
+
+DEBG("dyn2 ");
+
+  /* build decoding table for trees--single level, 7 bit lookup */
+  bl = 7;
+  if ((i = huft_build(zloc, ll, 19, 19, NULL, NULL, &tl, &bl)) != 0)
+  {
+    if (i == 1)
+      huft_free(zloc, tl);
+    return i;                   /* incomplete code set */
+  }
+
+DEBG("dyn3 ");
+
+  /* read in literal and distance code lengths */
+  n = nl + nd;
+  m = mask_bits[bl];
+  i = l = 0;
+  while ((unsigned)i < n)
+  {
+    NEEDBITS((unsigned)bl)
+    j = (td = tl + ((unsigned)b & m))->b;
+    DUMPBITS(j)
+    j = td->v.n;
+    if (j < 16)                 /* length of code in bits (0..15) */
+      ll[i++] = l = j;          /* save last length in l */
+    else if (j == 16)           /* repeat last length 3 to 6 times */
+    {
+      NEEDBITS(2)
+      j = 3 + ((unsigned)b & 3);
+      DUMPBITS(2)
+      if ((unsigned)i + j > n)
+        return 1;
+      while (j--)
+        ll[i++] = l;
+    }
+    else if (j == 17)           /* 3 to 10 zero length codes */
+    {
+      NEEDBITS(3)
+      j = 3 + ((unsigned)b & 7);
+      DUMPBITS(3)
+      if ((unsigned)i + j > n)
+        return 1;
+      while (j--)
+        ll[i++] = 0;
+      l = 0;
+    }
+    else                        /* j == 18: 11 to 138 zero length codes */
+    {
+      NEEDBITS(7)
+      j = 11 + ((unsigned)b & 0x7f);
+      DUMPBITS(7)
+      if ((unsigned)i + j > n)
+        return 1;
+      while (j--)
+        ll[i++] = 0;
+      l = 0;
+    }
+  }
+
+DEBG("dyn4 ");
+
+  /* free decoding table for trees */
+  huft_free(zloc, tl);
+
+DEBG("dyn5 ");
+
+  /* restore the global bit buffer */
+  bb = b;
+  bk = k;
+
+DEBG("dyn5a ");
+
+  /* build the decoding tables for literal/length and distance codes */
+  bl = lbits;
+  if ((i = huft_build(zloc, ll, nl, 257, cplens, cplext, &tl, &bl)) != 0)
+  {
+DEBG("dyn5b ");
+    if (i == 1) {
+      error(" incomplete literal tree");
+      huft_free(zloc, tl);
+    }
+    return i;                   /* incomplete code set */
+  }
+DEBG("dyn5c ");
+  bd = dbits;
+  if ((i = huft_build(zloc, ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0)
+  {
+DEBG("dyn5d ");
+    if (i == 1) {
+      error(" incomplete distance tree");
+#ifdef PKZIP_BUG_WORKAROUND
+      i = 0;
+    }
+#else
+      huft_free(zloc, td);
+    }
+    huft_free(zloc, tl);
+    return i;                   /* incomplete code set */
+#endif
+  }
+
+DEBG("dyn6 ");
+
+  /* decompress until an end-of-block code */
+  if (inflate_codes(zloc, tl, td, bl, bd))
+    return 1;
+
+DEBG("dyn7 ");
+
+  /* free the decoding tables, return */
+  huft_free(zloc, tl);
+  huft_free(zloc, td);
+
+  DEBG(">");
+  return 0;
+}
+
+
+
+STATIC int inflate_block(zloc, e)
+struct s_zloc *zloc;
+int *e;                 /* last block flag */
+/* decompress an inflated block */
+{
+  unsigned t;           /* block type */
+  register ulg b;       /* bit buffer */
+  register unsigned k;  /* number of bits in bit buffer */
+
+  DEBG("<blk");
+
+  /* make local bit buffer */
+  b = bb;
+  k = bk;
+
+
+  /* read in last block bit */
+  NEEDBITS(1)
+  *e = (int)b & 1;
+  DUMPBITS(1)
+
+
+  /* read in block type */
+  NEEDBITS(2)
+  t = (unsigned)b & 3;
+  DUMPBITS(2)
+
+
+  /* restore the global bit buffer */
+  bb = b;
+  bk = k;
+
+  /* inflate that block type */
+  if (t == 2)
+    return inflate_dynamic(zloc);
+  if (t == 0)
+    return inflate_stored(zloc);
+  if (t == 1)
+    return inflate_fixed(zloc);
+
+  DEBG(">");
+
+  /* bad block type */
+  return 2;
+}
+
+
+
+STATIC int inflate(zloc)
+struct s_zloc *zloc;
+/* decompress an inflated entry */
+{
+  int e;                /* last block flag */
+  int r;                /* result code */
+  unsigned h;           /* maximum struct huft's malloc'ed */
+
+  /* initialize window, bit buffer */
+  wp = 0;
+  bk = 0;
+  bb = 0;
+
+
+  /* decompress until the last block */
+  h = 0;
+  do {
+    hufts = 0;
+    if ((r = inflate_block(zloc, &e)) != 0) {
+      return r;
+    }
+    if (hufts > h)
+      h = hufts;
+  } while (!e);
+
+  /* Undo too much lookahead. The next read will be byte aligned so we
+   * can discard unused bits in the last meaningful byte.
+   */
+  while (bk >= 8) {
+    bk -= 8;
+    inptr--;
+  }
+
+  /* flush out slide */
+  flush_output(wp);
+
+
+  /* return success */
+#ifdef INFDEBUG
+  fprintf(stderr, "<%u> ", h);
+#endif /* INFDEBUG */
+  return 0;
+}
+
+/**********************************************************************
+ *
+ * The following are support routines for inflate.c
+ *
+ **********************************************************************/
+
+#define CRC_VALUE (crc ^ 0xffffffffL)
+
+/*
+ * Code to compute the CRC-32 table. Borrowed from 
+ * gzip-1.0.3/makecrc.c.
+ */
+
+static void
+makecrc(struct s_zloc *zloc)
+{
+/* Not copyrighted 1990 Mark Adler	*/
+
+  unsigned long c;      /* crc shift register */
+  unsigned long e;      /* polynomial exclusive-or pattern */
+  int i;                /* counter for all possible eight bit values */
+  int k;                /* byte being shifted into crc apparatus */
+
+  /* terms of polynomial defining this crc (except x^32): */
+  static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+  /* Make exclusive-or pattern from polynomial */
+  e = 0;
+  for (i = 0; i < sizeof(p)/sizeof(int); i++)
+    e |= 1L << (31 - p[i]);
+
+  crc_32_tab[0] = 0;
+
+  for (i = 1; i < 256; i++)
+  {
+    c = 0;
+    for (k = i | 256; k != 1; k >>= 1)
+    {
+      c = c & 1 ? (c >> 1) ^ e : c >> 1;
+      if (k & 1)
+        c ^= e;
+    }
+    crc_32_tab[i] = c;
+  }
+}
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
+#define RESERVED     0xC0 /* bit 6,7:   reserved */
+
+/*
+ * Do the uncompression!
+ */
+static int gunzip(struct s_zloc *zloc)
+{
+    uch flags;
+    unsigned char magic[2]; /* magic header */
+    char method;
+    ulg orig_crc = 0;       /* original crc */
+    ulg orig_len = 0;       /* original uncompressed length */
+    int res;
+#if 1
+    magic[0] = (unsigned char)get_byte();
+    magic[1] = (unsigned char)get_byte();
+    method = (unsigned char)get_byte();
+
+    if (magic[0] != 037 ||
+	((magic[1] != 0213) && (magic[1] != 0236))) {
+	    error("bad gzip magic numbers");
+	    return -1;
+    }
+
+    /* We only support method #8, DEFLATED */
+    if (method != 8)  {
+	    error("internal error, invalid method");
+	    return -1;
+    }
+
+    flags  = (uch)get_byte();
+    if ((flags & ENCRYPTED) != 0) {
+	    error("Input is encrypted");
+	    return -1;
+    }
+    if ((flags & CONTINUATION) != 0) {
+	    error("Multi part input");
+	    return -1;
+    }
+    if ((flags & RESERVED) != 0) {
+	    error("Input has invalid flags");
+	    return -1;
+    }
+    (ulg)get_byte();	/* Get timestamp */
+    ((ulg)get_byte()) << 8;
+    ((ulg)get_byte()) << 16;
+    ((ulg)get_byte()) << 24;
+
+    (void)get_byte();  /* Ignore extra flags for the moment */
+    (void)get_byte();  /* Ignore OS type for the moment */
+
+    if ((flags & EXTRA_FIELD) != 0) {
+	    unsigned len = (unsigned)get_byte();
+	    len |= ((unsigned)get_byte())<<8;
+	    while (len--) (void)get_byte();
+    }
+
+    /* Get original file name if it was truncated */
+    if ((flags & ORIG_NAME) != 0) {
+	    /* Discard the old name */
+	    while (get_byte() != 0) /* null */ ;
+    } 
+
+    /* Discard file comment if any */
+    if ((flags & COMMENT) != 0) {
+	    while (get_byte() != 0) /* null */ ;
+    }
+#endif
+    /* Decompress */
+    if ((res = inflate(zloc))) {
+	    switch (res) {
+	    case 0:
+		    break;
+	    case 1:
+		    error("invalid compressed format (err=1)");
+		    break;
+	    case 2:
+		    error("invalid compressed format (err=2)");
+		    break;
+	    case 3:
+		    error("out of memory");
+		    break;
+	    default:
+		    error("invalid compressed format (other)");
+	    }
+	    return -1;
+    }
+	    
+    /* Get the crc and original length */
+    /* crc32  (see algorithm.doc)
+     * uncompressed input size modulo 2^32
+     */
+#if 1
+    orig_crc = (ulg) get_byte();
+    orig_crc |= (ulg) get_byte() << 8;
+    orig_crc |= (ulg) get_byte() << 16;
+    orig_crc |= (ulg) get_byte() << 24;
+    
+    orig_len = (ulg) get_byte();
+    orig_len |= (ulg) get_byte() << 8;
+    orig_len |= (ulg) get_byte() << 16;
+    orig_len |= (ulg) get_byte() << 24;
+    
+    /* Validate decompression */
+    if (orig_crc != CRC_VALUE) {
+	    error("crc error");
+	    return -1;
+    }
+    if (orig_len != bytes_out) {
+	    error("length error");
+	    return -1;
+    }
+#endif
+    return 0;
+}
+
+
diff -urN linux-2.4.29/lib/inflate.c linux-2.4.29-uc1/lib/inflate.c
--- linux-2.4.29/lib/inflate.c	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-uc1/lib/inflate.c	2005-06-14 02:11:48.000000000 +0100
@@ -996,7 +996,7 @@
 
   /* return success */
 #ifdef DEBUG
-  fprintf(stderr, "<%u> ", h);
+  printk("<%u> ", h);
 #endif /* DEBUG */
   return 0;
 }
diff -urN linux-2.4.29/MAINTAINERS linux-2.4.29-uc1/MAINTAINERS
--- linux-2.4.29/MAINTAINERS	2005-01-19 14:09:24.000000000 +0000
+++ linux-2.4.29-uc1/MAINTAINERS	2005-06-14 02:11:48.000000000 +0100
@@ -2145,6 +2145,23 @@
 P:	Jeff Garzik
 S:	Odd fixes
 
+UCLINUX LINUX WITHOUT MMU SUPPORT
+P:	Greg Ungerer
+M:	gerg@snapgear.com
+P:	David McCullough
+M:	davidm@snapgear.com
+P:	D. Jeff Dionne
+M:	jeff@uclinux.org
+L:	uclinux-dev@uclinux.org
+W:	http://www.uclinux.org
+S:	Maintained
+
+UCLINUX FOR NEC V850
+P:	Miles Bader
+M:	uclinux-v850@lsi.nec.co.jp
+W:	http://www.ic.nec.co.jp/micro/uclinux/eng/
+S:	Supported
+
 VIA RHINE NETWORK DRIVER
 P:	Roger Luethi
 M:	rl@hellgate.ch
diff -urN linux-2.4.29/Makefile linux-2.4.29-uc1/Makefile
--- linux-2.4.29/Makefile	2005-01-19 14:10:14.000000000 +0000
+++ linux-2.4.29-uc1/Makefile	2005-06-14 02:11:22.000000000 +0100
@@ -1,11 +1,31 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 29
-EXTRAVERSION =
+EXTRAVERSION = -uc1
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
-ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
+# ARCH := armnommu
+# ARCH := m68knommu
+# ARCH := h8300
+# ARCH := niosnommu
+# ARCH := e1nommu
+
+# SUBARCH tells the usermode build what the underlying arch is.  That is set
+# first, and if a usermode build is happening, the "ARCH=um" on the command
+# line overrides the setting of ARCH below.  If a native build is happening,
+# then ARCH is assigned, getting whatever value it gets normally, and 
+# SUBARCH is subsequently ignored.
+ 
+ifndef SUBARCH
+SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
+endif
+
+ifndef ARCH
+ARCH := $(SUBARCH)
+endif
+
+
 KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
 
 CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -16,10 +36,17 @@
 HPATH   	= $(TOPDIR)/include
 FINDHPATH	= $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net $(HPATH)/math-emu
 
-HOSTCC  	= gcc
+HOSTCC  	= unset GCC_EXEC_PREFIX; gcc
 HOSTCFLAGS	= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
 
+# CROSS_COMPILE 	= m68k-elf-
+# CROSS_COMPILE 	= arm-elf-
+# CROSS_COMPILE 	= h8300-elf-
+# CROSS_COMPILE 	= nios-elf-
+# CROSS_COMPILE		= e1-coff-
+ifndef CROSS_COMPILE
 CROSS_COMPILE 	=
+endif
 
 #
 # Include the make variables (CC, etc...)
@@ -48,6 +75,8 @@
 	CONFIG_SHELL TOPDIR HPATH HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
 	CPP AR NM STRIP OBJCOPY OBJDUMP MAKE MAKEFILES GENKSYMS MODFLAGS PERL AWK
 
+.PHONY: dummy
+
 all:	do-it-all
 
 #
@@ -59,7 +88,12 @@
 include .config
 ifeq (.depend,$(wildcard .depend))
 include .depend
-do-it-all:	Version vmlinux
+ifndef CONFIG_UCLINUX
+	LINUX=vmlinux
+else
+	LINUX=linux
+endif
+do-it-all:	Version $(LINUX)
 else
 CONFIGURATION = depend
 do-it-all:	depend
@@ -90,9 +124,16 @@
 #
 
 CPPFLAGS := -D__KERNEL__ -I$(HPATH)
+CPPFLAGS += $(KERNEL_EXTRA_CFLAGS)
 
+ifndef CONFIG_FULLDEBUG
 CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
 	  -fno-strict-aliasing -fno-common
+else
+CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O1 \
+          -g -fno-strict-aliasing -fno-common
+CONFIG_FRAME_POINTER := y
+endif
 ifndef CONFIG_FRAME_POINTER
 CFLAGS += -fomit-frame-pointer
 endif
@@ -124,12 +165,21 @@
 
 #export RAMDISK = -DRAMDISK=512
 
+ifndef CONFIG_UCLINUX
+
 CORE_FILES	=kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o
 NETWORKS	=net/network.o
 
 LIBS		=$(TOPDIR)/lib/lib.a
 SUBDIRS		=kernel drivers mm fs net ipc lib crypto
 
+else # CONFIG_UCLINUX
+CORE_FILES	=kernel/kernel.o mmnommu/mmnommu.o fs/fs.o ipc/ipc.o
+NETWORKS	=net/network.o
+LIBS		=$(TOPDIR)/lib/lib.a
+SUBDIRS		=kernel drivers mmnommu fs net ipc lib crypto
+endif # CONFIG_UCLINUX
+
 DRIVERS-n :=
 DRIVERS-y :=
 DRIVERS-m :=
@@ -138,6 +188,7 @@
 DRIVERS-$(CONFIG_ACPI_BOOT) += drivers/acpi/acpi.o
 DRIVERS-$(CONFIG_PARPORT) += drivers/parport/driver.o
 DRIVERS-y += drivers/char/char.o \
+	drivers/serial/serial.o \
 	drivers/block/block.o \
 	drivers/misc/misc.o \
 	drivers/net/net.o
@@ -194,6 +245,7 @@
 DRIVERS-$(CONFIG_HOTPLUG_PCI) += drivers/hotplug/vmlinux-obj.o
 DRIVERS-$(CONFIG_ISDN_BOOL) += drivers/isdn/vmlinux-obj.o
 DRIVERS-$(CONFIG_CRYPTO) += crypto/crypto.o
+DRIVERS-$(CONFIG_ARCH_AT91RM9200) += drivers/at91/at91drv.o
 
 DRIVERS := $(DRIVERS-y)
 
@@ -201,7 +253,7 @@
 # files removed with 'make clean'
 CLEAN_FILES = \
 	kernel/ksyms.lst include/linux/compile.h \
-	vmlinux System.map \
+	$(LINUX) System.map \
 	.tmp* \
 	drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \
 	drivers/char/conmakehash \
@@ -223,6 +275,7 @@
 	drivers/tc/lk201-map.c \
 	net/khttpd/make_times_h \
 	net/khttpd/times.h \
+	net/ipsec/*.c \
 	submenu* \
 	drivers/ieee1394/oui.c
 # directories removed with 'make clean'
@@ -257,7 +310,6 @@
 	include/config \
 	$(TOPDIR)/include/linux/modules
 
-
 include arch/$(ARCH)/Makefile
 
 # Extra cflags for kbuild 2.4.  The default is to forbid includes by kernel code
@@ -282,10 +334,10 @@
 Version: dummy
 	@rm -f include/linux/compile.h
 
-boot: vmlinux
-	@$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C arch/$(ARCH)/boot
+boot: $(LINUX)
+	@$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" LINUX="$(LINUX)" -C arch/$(ARCH)/boot
 
-vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o init/do_mounts.o linuxsubdirs
+$(LINUX): include/linux/version.h $(CONFIGURATION) init/main.o init/version.o init/do_mounts.o linuxsubdirs
 	$(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o init/do_mounts.o \
 		--start-group \
 		$(CORE_FILES) \
@@ -293,8 +345,8 @@
 		$(NETWORKS) \
 		$(LIBS) \
 		--end-group \
-		-o vmlinux
-	$(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
+		-o $(LINUX)
+	$(NM) $(LINUX) | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
 
 symlinks:
 	rm -f include/asm
@@ -335,6 +387,7 @@
 
 uts_len		:= 64
 uts_truncate	:= sed -e 's/\(.\{1,$(uts_len)\}\).*/\1/'
+uts_nodomain	:= sed -e 's/[.].*$$//'
 
 include/linux/compile.h: $(CONFIGURATION) include/linux/version.h newversion
 	@echo -n \#`cat .version` > .ver1
@@ -344,7 +397,7 @@
 	@echo \#define UTS_VERSION \"`cat .ver1 | $(uts_truncate)`\" > .ver
 	@LANG=C echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> .ver
 	@echo \#define LINUX_COMPILE_BY \"`whoami`\" >> .ver
-	@echo \#define LINUX_COMPILE_HOST \"`hostname | $(uts_truncate)`\" >> .ver
+	@echo \#define LINUX_COMPILE_HOST \"`hostname | $(uts_truncate) | $(uts_nodomain)`\" >> .ver
 	@([ -x /bin/dnsdomainname ] && /bin/dnsdomainname > .ver1) || \
 	 ([ -x /bin/domainname ] && /bin/domainname > .ver1) || \
 	 echo > .ver1
@@ -403,11 +456,15 @@
 modules_install: _modinst_ $(patsubst %, _modinst_%, $(SUBDIRS)) _modinst_post
 
 .PHONY: _modinst_
+ifeq (y,y)
+_modinst_:
+else
 _modinst_:
 	@rm -rf $(MODLIB)/kernel
 	@rm -f $(MODLIB)/build
 	@mkdir -p $(MODLIB)/kernel
 	@ln -s $(TOPDIR) $(MODLIB)/build
+endif
 
 # If System.map exists, run depmod.  This deliberately does not have a
 # dependency on System.map since that would run the dependency tree on
@@ -417,7 +474,7 @@
 ifeq "$(strip $(INSTALL_MOD_PATH))" ""
 depmod_opts	:=
 else
-depmod_opts	:= -b $(INSTALL_MOD_PATH) -r
+depmod_opts	:= -b $(INSTALL_MOD_PATH)/lib/modules -r
 endif
 .PHONY: _modinst_post
 _modinst_post: _modinst_post_pcmcia
@@ -500,7 +557,7 @@
 ifdef CONFIG_MODVERSIONS
 	$(MAKE) update-modverfile
 endif
-	scripts/mkdep -- `find $(FINDHPATH) \( -name SCCS -o -name .svn \) -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
+	find $(FINDHPATH) \( -name SCCS -o -name .svn \) -prune -o -follow -name \*.h ! -name modversions.h -print | xargs scripts/mkdep --  > .hdepend
 	scripts/mkdep -- init/*.c > .depend
 
 ifdef CONFIG_MODVERSIONS
diff -urN linux-2.4.29/mm/mmap.c linux-2.4.29-uc1/mm/mmap.c
--- linux-2.4.29/mm/mmap.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/mm/mmap.c	2005-06-14 02:11:48.000000000 +0100
@@ -1,6 +1,8 @@
 /*
  *	linux/mm/mmap.c
  *
+ *      Modifications for TLB sharing in Linux (ARM/IA-64) (c) 2001 Adam Wiggins
+ *
  * Written by obz.
  */
 #include <linux/slab.h>
@@ -94,6 +96,19 @@
 	return free > pages;
 }
 
+
+#ifndef HAVE_ARCH_VM_SHARING_DATA
+
+/* Dummy function for default */
+static inline void
+arch_remove_shared_vm_struct(struct vm_area_struct* vma_p){}
+
+#else
+
+extern void arch_remove_shared_vm_struct(struct vm_area_struct* vma_p);
+
+#endif
+
 /* Remove one vm structure from the inode's i_mapping address space. */
 static inline void __remove_shared_vm_struct(struct vm_area_struct *vma)
 {
@@ -107,6 +122,9 @@
 			vma->vm_next_share->vm_pprev_share = vma->vm_pprev_share;
 		*vma->vm_pprev_share = vma->vm_next_share;
 	}
+
+	/* Deal with vm_sharing_data */
+	arch_remove_shared_vm_struct(vma);
 }
 
 static inline void remove_shared_vm_struct(struct vm_area_struct *vma)
@@ -528,6 +546,7 @@
 	vma->vm_pgoff = pgoff;
 	vma->vm_file = NULL;
 	vma->vm_private_data = NULL;
+	vma->vm_sharing_data = NULL;
 	vma->vm_raend = 0;
 
 	if (file) {
@@ -842,6 +861,7 @@
 		mpnt->vm_pgoff = area->vm_pgoff + ((end - area->vm_start) >> PAGE_SHIFT);
 		mpnt->vm_file = area->vm_file;
 		mpnt->vm_private_data = area->vm_private_data;
+		mpnt->vm_sharing_data = NULL;
 		if (mpnt->vm_file)
 			get_file(mpnt->vm_file);
 		if (mpnt->vm_ops && mpnt->vm_ops->open)
@@ -1119,6 +1139,7 @@
 	vma->vm_pgoff = 0;
 	vma->vm_file = NULL;
 	vma->vm_private_data = NULL;
+	vma->vm_sharing_data = NULL;
 
 	vma_link(mm, vma, prev, rb_link, rb_parent);
 
diff -urN linux-2.4.29/mmnommu/bootmem.c linux-2.4.29-uc1/mmnommu/bootmem.c
--- linux-2.4.29/mmnommu/bootmem.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/bootmem.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,370 @@
+/*
+ *  linux/mm/bootmem.c
+ *
+ *  Copyright (C) 1999 Ingo Molnar
+ *  Discontiguous memory support, Kanoj Sarcar, SGI, Nov 1999
+ *
+ *  simple boot-time physical memory area allocator and
+ *  free memory collector. It's used to deal with reserved
+ *  system memory and memory holes as well.
+ */
+
+#include <linux/mm.h>
+#include <linux/kernel_stat.h>
+#include <linux/swap.h>
+#include <linux/swapctl.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mmzone.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#ifdef NO_MM
+#include <asm/virtconvert.h>
+#endif
+
+/*
+ * Access to this subsystem has to be serialized externally. (this is
+ * true for the boot process anyway)
+ */
+unsigned long max_low_pfn;
+unsigned long min_low_pfn;
+unsigned long max_pfn;
+
+/* return the number of _pages_ that will be allocated for the boot bitmap */
+unsigned long __init bootmem_bootmap_pages (unsigned long pages)
+{
+	unsigned long mapsize;
+
+	mapsize = (pages+7)/8;
+	mapsize = (mapsize + ~PAGE_MASK) & PAGE_MASK;
+	mapsize >>= PAGE_SHIFT;
+
+	return mapsize;
+}
+
+/*
+ * Called once to set up the allocator itself.
+ */
+static unsigned long __init init_bootmem_core (pg_data_t *pgdat,
+	unsigned long mapstart, unsigned long start, unsigned long end)
+{
+	bootmem_data_t *bdata = pgdat->bdata;
+	unsigned long mapsize = ((end - start)+7)/8;
+
+	pgdat->node_next = pgdat_list;
+	pgdat_list = pgdat;
+
+	mapsize = (mapsize + (sizeof(long) - 1UL)) & ~(sizeof(long) - 1UL);
+	bdata->node_bootmem_map = phys_to_virt(mapstart << PAGE_SHIFT);
+	bdata->node_boot_start = (start << PAGE_SHIFT);
+	bdata->node_low_pfn = end;
+
+	/*
+	 * Initially all pages are reserved - setup_arch() has to
+	 * register free RAM areas explicitly.
+	 */
+	memset(bdata->node_bootmem_map, 0xff, mapsize);
+
+	return mapsize;
+}
+
+/*
+ * Marks a particular physical memory range as unallocatable. Usable RAM
+ * might be used for boot-time allocations - or it might get added
+ * to the free page pool later on.
+ */
+static void __init reserve_bootmem_core(bootmem_data_t *bdata, unsigned long addr, unsigned long size)
+{
+	unsigned long i;
+	
+	if (addr >= bdata->node_boot_start) {
+	/*
+	 * round up, partially reserved pages are considered
+	 * fully reserved.
+	 */
+	unsigned long sidx = (addr - bdata->node_boot_start)/PAGE_SIZE;
+	unsigned long eidx = (addr + size - bdata->node_boot_start + 
+							PAGE_SIZE-1)/PAGE_SIZE;
+	unsigned long end = (addr + size + PAGE_SIZE-1)/PAGE_SIZE;
+
+	if (!size) BUG();
+
+	if (sidx < 0)
+		BUG();
+	if (eidx < 0)
+		BUG();
+	if (sidx >= eidx)
+		BUG();
+	if ((addr >> PAGE_SHIFT) >= bdata->node_low_pfn)
+		BUG();
+	if (end > bdata->node_low_pfn)
+		BUG();
+	for (i = sidx; i < eidx; i++)
+		if (test_and_set_bit(i, bdata->node_bootmem_map))
+			printk("hm, page %08lx reserved twice.\n", i*PAGE_SIZE);
+	} else {
+	    printk(KERN_WARNING
+		"reserve_bootmem_core: address %08lx below node_boot_start\n", addr);
+	}
+}
+
+static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr, unsigned long size)
+{
+	unsigned long i;
+	unsigned long start;
+	/*
+	 * round down end of usable mem, partially free pages are
+	 * considered reserved.
+	 */
+	unsigned long sidx;
+	unsigned long eidx = (addr + size - bdata->node_boot_start)/PAGE_SIZE;
+	unsigned long end = (addr + size)/PAGE_SIZE;
+
+	if (!size) BUG();
+	if (end > bdata->node_low_pfn)
+		BUG();
+
+	/*
+	 * Round up the beginning of the address.
+	 */
+	start = (addr + PAGE_SIZE-1) / PAGE_SIZE;
+	sidx = start - (bdata->node_boot_start/PAGE_SIZE);
+
+	for (i = sidx; i < eidx; i++) {
+		if (!test_and_clear_bit(i, bdata->node_bootmem_map))
+			BUG();
+	}
+}
+
+/*
+ * We 'merge' subsequent allocations to save space. We might 'lose'
+ * some fraction of a page if allocations cannot be satisfied due to
+ * size constraints on boxes where there is physical RAM space
+ * fragmentation - in these cases * (mostly large memory boxes) this
+ * is not a problem.
+ *
+ * On low memory boxes we get it right in 100% of the cases.
+ */
+
+/*
+ * alignment has to be a power of 2 value.
+ */
+static void * __init __alloc_bootmem_core (bootmem_data_t *bdata, 
+	unsigned long size, unsigned long align, unsigned long goal)
+{
+	unsigned long i, start = 0;
+	void *ret;
+	unsigned long offset, remaining_size;
+	unsigned long areasize, preferred, incr;
+	unsigned long eidx = bdata->node_low_pfn - (bdata->node_boot_start >>
+							PAGE_SHIFT);
+
+	if (!size) BUG();
+
+	if (align & (align-1))
+		BUG();
+
+	offset = 0;
+	if (align &&
+	    (bdata->node_boot_start & (align - 1UL)) != 0)
+		offset = (align - (bdata->node_boot_start & (align - 1UL)));
+	offset >>= PAGE_SHIFT;
+
+	/*
+	 * We try to allocate bootmem pages above 'goal'
+	 * first, then we try to allocate lower pages.
+	 */
+	if (goal && (goal >= bdata->node_boot_start) && 
+			((goal >> PAGE_SHIFT) < bdata->node_low_pfn)) {
+		preferred = goal - bdata->node_boot_start;
+	} else
+		preferred = 0;
+
+	preferred = ((preferred + align - 1) & ~(align - 1)) >> PAGE_SHIFT;
+	preferred += offset;
+	areasize = (size+PAGE_SIZE-1)/PAGE_SIZE;
+	incr = align >> PAGE_SHIFT ? : 1;
+
+restart_scan:
+	for (i = preferred; i < eidx; i += incr) {
+		unsigned long j;
+		if (test_bit(i, bdata->node_bootmem_map))
+			continue;
+		for (j = i + 1; j < i + areasize; ++j) {
+			if (j >= eidx)
+				goto fail_block;
+			if (test_bit (j, bdata->node_bootmem_map))
+				goto fail_block;
+		}
+		start = i;
+		goto found;
+	fail_block:;
+	}
+	if (preferred) {
+		preferred = offset;
+		goto restart_scan;
+	}
+	return NULL;
+found:
+	if (start >= eidx)
+		BUG();
+
+	/*
+	 * Is the next page of the previous allocation-end the start
+	 * of this allocation's buffer? If yes then we can 'merge'
+	 * the previous partial page with this allocation.
+	 */
+	if (align <= PAGE_SIZE
+	    && bdata->last_offset && bdata->last_pos+1 == start) {
+		offset = (bdata->last_offset+align-1) & ~(align-1);
+		if (offset > PAGE_SIZE)
+			BUG();
+		remaining_size = PAGE_SIZE-offset;
+		if (size < remaining_size) {
+			areasize = 0;
+			// last_pos unchanged
+			bdata->last_offset = offset+size;
+			ret = phys_to_virt(bdata->last_pos*PAGE_SIZE + offset +
+						bdata->node_boot_start);
+		} else {
+			remaining_size = size - remaining_size;
+			areasize = (remaining_size+PAGE_SIZE-1)/PAGE_SIZE;
+			ret = phys_to_virt(bdata->last_pos*PAGE_SIZE + offset +
+						bdata->node_boot_start);
+			bdata->last_pos = start+areasize-1;
+			bdata->last_offset = remaining_size;
+		}
+		bdata->last_offset &= ~PAGE_MASK;
+	} else {
+		bdata->last_pos = start + areasize - 1;
+		bdata->last_offset = size & ~PAGE_MASK;
+		ret = phys_to_virt(start * PAGE_SIZE + bdata->node_boot_start);
+	}
+	/*
+	 * Reserve the area now:
+	 */
+	for (i = start; i < start+areasize; i++)
+		if (test_and_set_bit(i, bdata->node_bootmem_map))
+			BUG();
+	memset(ret, 0, size);
+	return ret;
+}
+
+static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
+{
+	struct page *page = pgdat->node_mem_map;
+	bootmem_data_t *bdata = pgdat->bdata;
+	unsigned long i, count, total = 0;
+	unsigned long idx;
+
+	if (!bdata->node_bootmem_map) BUG();
+
+	count = 0;
+	idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
+	for (i = 0; i < idx; i++, page++) {
+		if (!test_bit(i, bdata->node_bootmem_map)) {
+			count++;
+			ClearPageReserved(page);
+			set_page_count(page, 1);
+			__free_page(page);
+		}
+	}
+	total += count;
+
+	/*
+	 * Now free the allocator bitmap itself, it's not
+	 * needed anymore:
+	 */
+	page = virt_to_page(bdata->node_bootmem_map);
+	count = 0;
+#if !defined(__arm__)
+	for (i = 0; i < ((bdata->node_low_pfn-(bdata->node_boot_start >> PAGE_SHIFT))/8 + PAGE_SIZE-1)/PAGE_SIZE; i++,page++) {
+		count++;
+		ClearPageReserved(page);
+		set_page_count(page, 1);
+		__free_page(page);
+	}
+#endif
+	total += count;
+	bdata->node_bootmem_map = NULL;
+
+	return total;
+}
+
+unsigned long __init init_bootmem_node (pg_data_t *pgdat, unsigned long freepfn, unsigned long startpfn, unsigned long endpfn)
+{
+	return(init_bootmem_core(pgdat, freepfn, startpfn, endpfn));
+}
+
+void __init reserve_bootmem_node (pg_data_t *pgdat, unsigned long physaddr, unsigned long size)
+{
+	reserve_bootmem_core(pgdat->bdata, physaddr, size);
+}
+
+void __init free_bootmem_node (pg_data_t *pgdat, unsigned long physaddr, unsigned long size)
+{
+	return(free_bootmem_core(pgdat->bdata, physaddr, size));
+}
+
+unsigned long __init free_all_bootmem_node (pg_data_t *pgdat)
+{
+	return(free_all_bootmem_core(pgdat));
+}
+
+unsigned long __init init_bootmem (unsigned long start, unsigned long pages)
+{
+	max_low_pfn = pages;
+	min_low_pfn = start;
+	return(init_bootmem_core(&contig_page_data, start, 0, pages));
+}
+
+void __init reserve_bootmem (unsigned long addr, unsigned long size)
+{
+	reserve_bootmem_core(contig_page_data.bdata, addr, size);
+}
+
+void __init free_bootmem (unsigned long addr, unsigned long size)
+{
+	return(free_bootmem_core(contig_page_data.bdata, addr, size));
+}
+
+unsigned long __init free_all_bootmem (void)
+{
+	return(free_all_bootmem_core(&contig_page_data));
+}
+
+void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal)
+{
+	pg_data_t *pgdat;
+	void *ptr;
+
+	for_each_pgdat(pgdat)
+		if ((ptr = __alloc_bootmem_core(pgdat->bdata, size,
+						align, goal)))
+			return(ptr);
+
+	/*
+	 * Whoops, we cannot satisfy the allocation request.
+	 */
+	printk(KERN_ALERT "bootmem alloc of %lu bytes failed!\n", size);
+	panic("Out of memory");
+	return NULL;
+}
+
+void * __init __alloc_bootmem_node (pg_data_t *pgdat, unsigned long size, unsigned long align, unsigned long goal)
+{
+	void *ptr;
+
+	ptr = __alloc_bootmem_core(pgdat->bdata, size, align, goal);
+	if (ptr)
+		return (ptr);
+
+	/*
+	 * Whoops, we cannot satisfy the allocation request.
+	 */
+	printk(KERN_ALERT "bootmem alloc of %lu bytes failed!\n", size);
+	panic("Out of memory");
+	return NULL;
+}
+
diff -urN linux-2.4.29/mmnommu/filemap.c linux-2.4.29-uc1/mmnommu/filemap.c
--- linux-2.4.29/mmnommu/filemap.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/filemap.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,3461 @@
+/*
+ *	linux/mm/filemap.c
+ *
+ * Copyright (C) 1994-1999  Linus Torvalds
+ * Copyright (c) 2001 Lineo Inc., David McCullough <davidm@lineo.com>
+ * Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org> ref uClinux 2.0
+ */
+
+/*
+ * This file handles the generic file mmap semantics used by
+ * most "normal" filesystems (but you don't /have/ to use this:
+ * the NFS filesystem used to do this differently, for example)
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/shm.h>
+#include <linux/mman.h>
+#include <linux/locks.h>
+#include <linux/pagemap.h>
+#include <linux/swap.h>
+#include <linux/smp_lock.h>
+#include <linux/blkdev.h>
+#include <linux/file.h>
+#include <linux/swapctl.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/iobuf.h>
+
+#include <asm/pgalloc.h>
+#include <asm/uaccess.h>
+#include <asm/mman.h>
+#ifdef NO_MM
+#include <asm/virtconvert.h>
+#endif
+
+#include <linux/highmem.h>
+
+/*
+ * Shared mappings implemented 30.11.1994. It's not fully working yet,
+ * though.
+ *
+ * Shared mappings now work. 15.8.1995  Bruno.
+ *
+ * finished 'unifying' the page and buffer cache and SMP-threaded the
+ * page-cache, 21.05.1999, Ingo Molnar <mingo@redhat.com>
+ *
+ * SMP-threaded pagemap-LRU 1999, Andrea Arcangeli <andrea@suse.de>
+ */
+
+unsigned long page_cache_size;
+unsigned int page_hash_bits;
+struct page **page_hash_table;
+
+int vm_max_readahead = 31;
+int vm_min_readahead = 3;
+EXPORT_SYMBOL(vm_max_readahead);
+EXPORT_SYMBOL(vm_min_readahead);
+
+
+spinlock_cacheline_t pagecache_lock_cacheline  = {SPIN_LOCK_UNLOCKED};
+/*
+ * NOTE: to avoid deadlocking you must never acquire the pagemap_lru_lock 
+ *	with the pagecache_lock held.
+ *
+ * Ordering:
+ *	swap_lock ->
+ *		pagemap_lru_lock ->
+ *			pagecache_lock
+ */
+spinlock_cacheline_t pagemap_lru_lock_cacheline = {SPIN_LOCK_UNLOCKED};
+
+#define CLUSTER_PAGES		(1 << page_cluster)
+#define CLUSTER_OFFSET(x)	(((x) >> page_cluster) << page_cluster)
+
+static void FASTCALL(add_page_to_hash_queue(struct page * page, struct page **p));
+static void fastcall add_page_to_hash_queue(struct page * page, struct page **p)
+{
+	struct page *next = *p;
+
+	*p = page;
+	page->next_hash = next;
+	page->pprev_hash = p;
+	if (next)
+		next->pprev_hash = &page->next_hash;
+	if (page->buffers)
+		PAGE_BUG(page);
+	inc_nr_cache_pages(page);
+}
+
+static inline void add_page_to_inode_queue(struct address_space *mapping, struct page * page)
+{
+	struct list_head *head = &mapping->clean_pages;
+
+	mapping->nrpages++;
+	list_add(&page->list, head);
+	page->mapping = mapping;
+}
+
+static inline void remove_page_from_inode_queue(struct page * page)
+{
+	struct address_space * mapping = page->mapping;
+
+	if (mapping->a_ops->removepage)
+		mapping->a_ops->removepage(page);
+	
+	list_del(&page->list);
+	page->mapping = NULL;
+	wmb();
+	mapping->nrpages--;
+	if (!mapping->nrpages)
+		refile_inode(mapping->host);
+}
+
+static inline void remove_page_from_hash_queue(struct page * page)
+{
+	struct page *next = page->next_hash;
+	struct page **pprev = page->pprev_hash;
+
+	if (next)
+		next->pprev_hash = pprev;
+	*pprev = next;
+	page->pprev_hash = NULL;
+	dec_nr_cache_pages(page);
+}
+
+/*
+ * Remove a page from the page cache and free it. Caller has to make
+ * sure the page is locked and that nobody else uses it - or that usage
+ * is safe.
+ */
+void __remove_inode_page(struct page *page)
+{
+	remove_page_from_inode_queue(page);
+	remove_page_from_hash_queue(page);
+}
+
+void remove_inode_page(struct page *page)
+{
+	if (!PageLocked(page))
+		PAGE_BUG(page);
+
+	spin_lock(&pagecache_lock);
+	__remove_inode_page(page);
+	spin_unlock(&pagecache_lock);
+}
+
+static inline int sync_page(struct page *page)
+{
+	struct address_space *mapping = page->mapping;
+
+	if (mapping && mapping->a_ops && mapping->a_ops->sync_page)
+		return mapping->a_ops->sync_page(page);
+	return 0;
+}
+
+/*
+ * Add a page to the dirty page list.
+ */
+void fastcall set_page_dirty(struct page *page)
+{
+	if (!test_and_set_bit(PG_dirty, &page->flags)) {
+		struct address_space *mapping = page->mapping;
+
+		if (mapping) {
+			spin_lock(&pagecache_lock);
+			mapping = page->mapping;
+			if (mapping) {	/* may have been truncated */
+				list_del(&page->list);
+				list_add(&page->list, &mapping->dirty_pages);
+			}
+			spin_unlock(&pagecache_lock);
+
+			if (mapping && mapping->host)
+				mark_inode_dirty_pages(mapping->host);
+			if (block_dump)
+				printk(KERN_DEBUG "%s: dirtied page\n", current->comm);
+		}
+	}
+}
+
+/**
+ * invalidate_inode_pages - Invalidate all the unlocked pages of one inode
+ * @inode: the inode which pages we want to invalidate
+ *
+ * This function only removes the unlocked pages, if you want to
+ * remove all the pages of one inode, you must call truncate_inode_pages.
+ */
+
+void invalidate_inode_pages(struct inode * inode)
+{
+	struct list_head *head, *curr;
+	struct page * page;
+
+	head = &inode->i_mapping->clean_pages;
+
+	spin_lock(&pagemap_lru_lock);
+	spin_lock(&pagecache_lock);
+	curr = head->next;
+
+	while (curr != head) {
+		page = list_entry(curr, struct page, list);
+		curr = curr->next;
+
+		/* We cannot invalidate something in dirty.. */
+		if (PageDirty(page))
+			continue;
+
+		/* ..or locked */
+		if (TryLockPage(page))
+			continue;
+
+		if (page->buffers && !try_to_free_buffers(page, 0))
+			goto unlock;
+
+		if (page_count(page) != 1)
+			goto unlock;
+
+		__lru_cache_del(page);
+		__remove_inode_page(page);
+		UnlockPage(page);
+		page_cache_release(page);
+		continue;
+unlock:
+		UnlockPage(page);
+		continue;
+	}
+
+	spin_unlock(&pagecache_lock);
+	spin_unlock(&pagemap_lru_lock);
+}
+
+static int do_flushpage(struct page *page, unsigned long offset)
+{
+	int (*flushpage) (struct page *, unsigned long);
+	flushpage = page->mapping->a_ops->flushpage;
+	if (flushpage)
+		return (*flushpage)(page, offset);
+	return block_flushpage(page, offset);
+}
+
+static inline void truncate_partial_page(struct page *page, unsigned partial)
+{
+	memclear_highpage_flush(page, partial, PAGE_CACHE_SIZE-partial);
+	if (page->buffers)
+		do_flushpage(page, partial);
+}
+
+static void truncate_complete_page(struct page *page)
+{
+	/* Leave it on the LRU if it gets converted into anonymous buffers */
+	if (!page->buffers || do_flushpage(page, 0))
+		lru_cache_del(page);
+
+	/*
+	 * We remove the page from the page cache _after_ we have
+	 * destroyed all buffer-cache references to it. Otherwise some
+	 * other process might think this inode page is not in the
+	 * page cache and creates a buffer-cache alias to it causing
+	 * all sorts of fun problems ...  
+	 */
+	ClearPageDirty(page);
+	ClearPageUptodate(page);
+	remove_inode_page(page);
+	page_cache_release(page);
+}
+
+static int FASTCALL(truncate_list_pages(struct list_head *, unsigned long, unsigned *));
+static int fastcall truncate_list_pages(struct list_head *head, unsigned long start, unsigned *partial)
+{
+	struct list_head *curr;
+	struct page * page;
+	int unlocked = 0;
+
+ restart:
+	curr = head->prev;
+	while (curr != head) {
+		unsigned long offset;
+
+		page = list_entry(curr, struct page, list);
+		offset = page->index;
+
+		/* Is one of the pages to truncate? */
+		if ((offset >= start) || (*partial && (offset + 1) == start)) {
+			int failed;
+
+			page_cache_get(page);
+			failed = TryLockPage(page);
+
+			list_del(head);
+			if (!failed)
+				/* Restart after this page */
+				list_add_tail(head, curr);
+			else
+				/* Restart on this page */
+				list_add(head, curr);
+
+			spin_unlock(&pagecache_lock);
+			unlocked = 1;
+
+ 			if (!failed) {
+				if (*partial && (offset + 1) == start) {
+					truncate_partial_page(page, *partial);
+					*partial = 0;
+				} else 
+					truncate_complete_page(page);
+
+				UnlockPage(page);
+			} else
+ 				wait_on_page(page);
+
+			page_cache_release(page);
+
+			if (current->need_resched) {
+				__set_current_state(TASK_RUNNING);
+				schedule();
+			}
+
+			spin_lock(&pagecache_lock);
+			goto restart;
+		}
+		curr = curr->prev;
+	}
+	return unlocked;
+}
+
+
+/**
+ * truncate_inode_pages - truncate *all* the pages from an offset
+ * @mapping: mapping to truncate
+ * @lstart: offset from with to truncate
+ *
+ * Truncate the page cache at a set offset, removing the pages
+ * that are beyond that offset (and zeroing out partial pages).
+ * If any page is locked we wait for it to become unlocked.
+ */
+void truncate_inode_pages(struct address_space * mapping, loff_t lstart) 
+{
+	unsigned long start = (lstart + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	unsigned partial = lstart & (PAGE_CACHE_SIZE - 1);
+	int unlocked;
+
+	spin_lock(&pagecache_lock);
+	do {
+		unlocked = truncate_list_pages(&mapping->clean_pages, start, &partial);
+		unlocked |= truncate_list_pages(&mapping->dirty_pages, start, &partial);
+		unlocked |= truncate_list_pages(&mapping->locked_pages, start, &partial);
+	} while (unlocked);
+	/* Traversed all three lists without dropping the lock */
+	spin_unlock(&pagecache_lock);
+}
+
+static inline int invalidate_this_page2(struct page * page,
+					struct list_head * curr,
+					struct list_head * head)
+{
+	int unlocked = 1;
+
+	/*
+	 * The page is locked and we hold the pagecache_lock as well
+	 * so both page_count(page) and page->buffers stays constant here.
+	 */
+	if (page_count(page) == 1 + !!page->buffers) {
+		/* Restart after this page */
+		list_del(head);
+		list_add_tail(head, curr);
+
+		page_cache_get(page);
+		spin_unlock(&pagecache_lock);
+		truncate_complete_page(page);
+	} else {
+		if (page->buffers) {
+			/* Restart after this page */
+			list_del(head);
+			list_add_tail(head, curr);
+
+			page_cache_get(page);
+			spin_unlock(&pagecache_lock);
+			block_invalidate_page(page);
+		} else
+			unlocked = 0;
+
+		ClearPageDirty(page);
+		ClearPageUptodate(page);
+	}
+
+	return unlocked;
+}
+
+static int FASTCALL(invalidate_list_pages2(struct list_head *));
+static int fastcall invalidate_list_pages2(struct list_head *head)
+{
+	struct list_head *curr;
+	struct page * page;
+	int unlocked = 0;
+
+ restart:
+	curr = head->prev;
+	while (curr != head) {
+		page = list_entry(curr, struct page, list);
+
+		if (!TryLockPage(page)) {
+			int __unlocked;
+
+			__unlocked = invalidate_this_page2(page, curr, head);
+			UnlockPage(page);
+			unlocked |= __unlocked;
+			if (!__unlocked) {
+				curr = curr->prev;
+				continue;
+			}
+		} else {
+			/* Restart on this page */
+			list_del(head);
+			list_add(head, curr);
+
+			page_cache_get(page);
+			spin_unlock(&pagecache_lock);
+			unlocked = 1;
+			wait_on_page(page);
+		}
+
+		page_cache_release(page);
+		if (current->need_resched) {
+			__set_current_state(TASK_RUNNING);
+			schedule();
+		}
+
+		spin_lock(&pagecache_lock);
+		goto restart;
+	}
+	return unlocked;
+}
+
+/**
+ * invalidate_inode_pages2 - Clear all the dirty bits around if it can't
+ * free the pages because they're mapped.
+ * @mapping: the address_space which pages we want to invalidate
+ */
+void invalidate_inode_pages2(struct address_space * mapping)
+{
+	int unlocked;
+
+	spin_lock(&pagecache_lock);
+	do {
+		unlocked = invalidate_list_pages2(&mapping->clean_pages);
+		unlocked |= invalidate_list_pages2(&mapping->dirty_pages);
+		unlocked |= invalidate_list_pages2(&mapping->locked_pages);
+	} while (unlocked);
+	spin_unlock(&pagecache_lock);
+}
+
+static inline struct page * __find_page_nolock(struct address_space *mapping, unsigned long offset, struct page *page)
+{
+	goto inside;
+
+	for (;;) {
+		page = page->next_hash;
+inside:
+		if (!page)
+			goto not_found;
+		if (page->mapping != mapping)
+			continue;
+		if (page->index == offset)
+			break;
+	}
+
+not_found:
+	return page;
+}
+
+static int do_buffer_fdatasync(struct list_head *head, unsigned long start, unsigned long end, int (*fn)(struct page *))
+{
+	struct list_head *curr;
+	struct page *page;
+	int retval = 0;
+
+	spin_lock(&pagecache_lock);
+	curr = head->next;
+	while (curr != head) {
+		page = list_entry(curr, struct page, list);
+		curr = curr->next;
+		if (!page->buffers)
+			continue;
+		if (page->index >= end)
+			continue;
+		if (page->index < start)
+			continue;
+
+		page_cache_get(page);
+		spin_unlock(&pagecache_lock);
+		lock_page(page);
+
+		/* The buffers could have been free'd while we waited for the page lock */
+		if (page->buffers)
+			retval |= fn(page);
+
+		UnlockPage(page);
+		spin_lock(&pagecache_lock);
+		curr = page->list.next;
+		page_cache_release(page);
+	}
+	spin_unlock(&pagecache_lock);
+
+	return retval;
+}
+
+/*
+ * Two-stage data sync: first start the IO, then go back and
+ * collect the information..
+ */
+int generic_buffer_fdatasync(struct inode *inode, unsigned long start_idx, unsigned long end_idx)
+{
+	int retval;
+
+	/* writeout dirty buffers on pages from both clean and dirty lists */
+	retval = do_buffer_fdatasync(&inode->i_mapping->dirty_pages, start_idx, end_idx, writeout_one_page);
+	retval |= do_buffer_fdatasync(&inode->i_mapping->clean_pages, start_idx, end_idx, writeout_one_page);
+	retval |= do_buffer_fdatasync(&inode->i_mapping->locked_pages, start_idx, end_idx, writeout_one_page);
+
+	/* now wait for locked buffers on pages from both clean and dirty lists */
+	retval |= do_buffer_fdatasync(&inode->i_mapping->dirty_pages, start_idx, end_idx, waitfor_one_page);
+	retval |= do_buffer_fdatasync(&inode->i_mapping->clean_pages, start_idx, end_idx, waitfor_one_page);
+	retval |= do_buffer_fdatasync(&inode->i_mapping->locked_pages, start_idx, end_idx, waitfor_one_page);
+
+	return retval;
+}
+
+/*
+ * In-memory filesystems have to fail their
+ * writepage function - and this has to be
+ * worked around in the VM layer..
+ *
+ * We
+ *  - mark the page dirty again (but do NOT
+ *    add it back to the inode dirty list, as
+ *    that would livelock in fdatasync)
+ *  - activate the page so that the page stealer
+ *    doesn't try to write it out over and over
+ *    again.
+ */
+int fail_writepage(struct page *page)
+{
+	/* Only activate on memory-pressure, not fsync.. */
+	if (PageLaunder(page)) {
+		activate_page(page);
+		SetPageReferenced(page);
+	}
+
+	/* Set the page dirty again, unlock */
+	SetPageDirty(page);
+	UnlockPage(page);
+	return 0;
+}
+
+EXPORT_SYMBOL(fail_writepage);
+
+/**
+ *      filemap_fdatawrite - walk the list of dirty pages of the given address space
+ *     	and writepage() each unlocked page (does not wait on locked pages).
+ * 
+ *      @mapping: address space structure to write
+ *
+ */
+int filemap_fdatawrite(struct address_space * mapping)
+{
+	int ret = 0;
+	int (*writepage)(struct page *) = mapping->a_ops->writepage;
+
+	spin_lock(&pagecache_lock);
+
+	while (!list_empty(&mapping->dirty_pages)) {
+		struct page *page = list_entry(mapping->dirty_pages.prev, struct page, list);
+
+		list_del(&page->list);
+		list_add(&page->list, &mapping->locked_pages);
+
+		if (!PageDirty(page))
+			continue;
+
+		page_cache_get(page);
+		spin_unlock(&pagecache_lock);
+
+		if (!TryLockPage(page)) {
+			if (PageDirty(page)) {
+				int err;
+				ClearPageDirty(page);
+				err = writepage(page);
+				if (err && !ret)
+					ret = err;
+			} else
+				UnlockPage(page);
+		}
+		page_cache_release(page);
+		spin_lock(&pagecache_lock);
+	}
+	spin_unlock(&pagecache_lock);
+	return ret;
+}
+
+/**
+ *      filemap_fdatasync - walk the list of dirty pages of the given address space
+ *     	and writepage() all of them.
+ * 
+ *      @mapping: address space structure to write
+ *
+ */
+int filemap_fdatasync(struct address_space * mapping)
+{
+	int ret = 0;
+	int (*writepage)(struct page *) = mapping->a_ops->writepage;
+
+	spin_lock(&pagecache_lock);
+
+        while (!list_empty(&mapping->dirty_pages)) {
+		struct page *page = list_entry(mapping->dirty_pages.prev, struct page, list);
+
+		list_del(&page->list);
+		list_add(&page->list, &mapping->locked_pages);
+
+		if (!PageDirty(page))
+			continue;
+
+		page_cache_get(page);
+		spin_unlock(&pagecache_lock);
+
+		lock_page(page);
+
+		if (PageDirty(page)) {
+			int err;
+			ClearPageDirty(page);
+			err = writepage(page);
+			if (err && !ret)
+				ret = err;
+		} else
+			UnlockPage(page);
+
+		page_cache_release(page);
+		spin_lock(&pagecache_lock);
+	}
+	spin_unlock(&pagecache_lock);
+	return ret;
+}
+
+/**
+ *      filemap_fdatawait - walk the list of locked pages of the given address space
+ *     	and wait for all of them.
+ * 
+ *      @mapping: address space structure to wait for
+ *
+ */
+int filemap_fdatawait(struct address_space * mapping)
+{
+	int ret = 0;
+
+	spin_lock(&pagecache_lock);
+
+        while (!list_empty(&mapping->locked_pages)) {
+		struct page *page = list_entry(mapping->locked_pages.next, struct page, list);
+
+		list_del(&page->list);
+		list_add(&page->list, &mapping->clean_pages);
+
+		if (!PageLocked(page))
+			continue;
+
+		page_cache_get(page);
+		spin_unlock(&pagecache_lock);
+
+		___wait_on_page(page);
+		if (PageError(page))
+			ret = -EIO;
+
+		page_cache_release(page);
+		spin_lock(&pagecache_lock);
+	}
+	spin_unlock(&pagecache_lock);
+	return ret;
+}
+
+/*
+ * Add a page to the inode page cache.
+ *
+ * The caller must have locked the page and 
+ * set all the page flags correctly..
+ */
+void add_to_page_cache_locked(struct page * page, struct address_space *mapping, unsigned long index)
+{
+	if (!PageLocked(page))
+		BUG();
+
+	page->index = index;
+	page_cache_get(page);
+	spin_lock(&pagecache_lock);
+	add_page_to_inode_queue(mapping, page);
+	add_page_to_hash_queue(page, page_hash(mapping, index));
+	spin_unlock(&pagecache_lock);
+
+	lru_cache_add(page);
+}
+
+/*
+ * This adds a page to the page cache, starting out as locked,
+ * owned by us, but unreferenced, not uptodate and with no errors.
+ */
+static inline void __add_to_page_cache(struct page * page,
+	struct address_space *mapping, unsigned long offset,
+	struct page **hash)
+{
+	/*
+	 * Yes this is inefficient, however it is needed.  The problem
+	 * is that we could be adding a page to the swap cache while
+	 * another CPU is also modifying page->flags, so the updates
+	 * really do need to be atomic.  -- Rik
+	 */
+	ClearPageUptodate(page);
+	ClearPageError(page);
+	ClearPageDirty(page);
+	ClearPageReferenced(page);
+	ClearPageArch1(page);
+	ClearPageChecked(page);
+	LockPage(page);
+	page_cache_get(page);
+	page->index = offset;
+	add_page_to_inode_queue(mapping, page);
+	add_page_to_hash_queue(page, hash);
+}
+
+void add_to_page_cache(struct page * page, struct address_space * mapping, unsigned long offset)
+{
+	spin_lock(&pagecache_lock);
+	__add_to_page_cache(page, mapping, offset, page_hash(mapping, offset));
+	spin_unlock(&pagecache_lock);
+	lru_cache_add(page);
+}
+
+int add_to_page_cache_unique(struct page * page,
+	struct address_space *mapping, unsigned long offset,
+	struct page **hash)
+{
+	int err;
+	struct page *alias;
+
+	spin_lock(&pagecache_lock);
+	alias = __find_page_nolock(mapping, offset, *hash);
+
+	err = 1;
+	if (!alias) {
+		__add_to_page_cache(page,mapping,offset,hash);
+		err = 0;
+	}
+
+	spin_unlock(&pagecache_lock);
+	if (!err)
+		lru_cache_add(page);
+	return err;
+}
+
+/*
+ * This adds the requested page to the page cache if it isn't already there,
+ * and schedules an I/O to read in its contents from disk.
+ */
+static int FASTCALL(page_cache_read(struct file * file, unsigned long offset));
+static int fastcall page_cache_read(struct file * file, unsigned long offset)
+{
+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+	struct page **hash = page_hash(mapping, offset);
+	struct page *page; 
+
+	spin_lock(&pagecache_lock);
+	page = __find_page_nolock(mapping, offset, *hash);
+	spin_unlock(&pagecache_lock);
+	if (page)
+		return 0;
+
+	page = page_cache_alloc(mapping);
+	if (!page)
+		return -ENOMEM;
+
+	if (!add_to_page_cache_unique(page, mapping, offset, hash)) {
+		int error = mapping->a_ops->readpage(file, page);
+		page_cache_release(page);
+		return error;
+	}
+	/*
+	 * We arrive here in the unlikely event that someone 
+	 * raced with us and added our page to the cache first.
+	 */
+	page_cache_release(page);
+	return 0;
+}
+
+#ifndef NO_MM
+/*
+ * Read in an entire cluster at once.  A cluster is usually a 64k-
+ * aligned block that includes the page requested in "offset."
+ */
+static int FASTCALL(read_cluster_nonblocking(struct file * file, unsigned long offset,
+					     unsigned long filesize));
+static int fastcall read_cluster_nonblocking(struct file * file, unsigned long offset,
+	unsigned long filesize)
+{
+	unsigned long pages = CLUSTER_PAGES;
+
+	offset = CLUSTER_OFFSET(offset);
+	while ((pages-- > 0) && (offset < filesize)) {
+		int error = page_cache_read(file, offset);
+		if (error < 0)
+			return error;
+		offset ++;
+	}
+
+	return 0;
+}
+#endif /* NO_MM */
+
+/*
+ * Knuth recommends primes in approximately golden ratio to the maximum
+ * integer representable by a machine word for multiplicative hashing.
+ * Chuck Lever verified the effectiveness of this technique:
+ * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf
+ *
+ * These primes are chosen to be bit-sparse, that is operations on
+ * them can use shifts and additions instead of multiplications for
+ * machines where multiplications are slow.
+ */
+#if BITS_PER_LONG == 32
+/* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
+#define GOLDEN_RATIO_PRIME 0x9e370001UL
+#elif BITS_PER_LONG == 64
+/*  2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */
+#define GOLDEN_RATIO_PRIME 0x9e37fffffffc0001UL
+#else
+#error Define GOLDEN_RATIO_PRIME for your wordsize.
+#endif
+
+/*
+ * In order to wait for pages to become available there must be
+ * waitqueues associated with pages. By using a hash table of
+ * waitqueues where the bucket discipline is to maintain all
+ * waiters on the same queue and wake all when any of the pages
+ * become available, and for the woken contexts to check to be
+ * sure the appropriate page became available, this saves space
+ * at a cost of "thundering herd" phenomena during rare hash
+ * collisions.
+ */
+static inline wait_queue_head_t *page_waitqueue(struct page *page)
+{
+	const zone_t *zone = page_zone(page);
+	wait_queue_head_t *wait = zone->wait_table;
+	unsigned long hash = (unsigned long)page;
+
+	if (zone->wait_table_shift == BITS_PER_LONG)
+		return &wait[0];
+
+#if BITS_PER_LONG == 64
+	/*  Sigh, gcc can't optimise this alone like it does for 32 bits. */
+	unsigned long n = hash;
+	n <<= 18;
+	hash -= n;
+	n <<= 33;
+	hash -= n;
+	n <<= 3;
+	hash += n;
+	n <<= 3;
+	hash -= n;
+	n <<= 4;
+	hash += n;
+	n <<= 2;
+	hash += n;
+#else
+	/* On some cpus multiply is faster, on others gcc will do shifts */
+	hash *= GOLDEN_RATIO_PRIME;
+#endif
+	hash >>= zone->wait_table_shift;
+
+	return &wait[hash];
+}
+
+/*
+ * This must be called after every submit_bh with end_io
+ * callbacks that would result into the blkdev layer waking
+ * up the page after a queue unplug.
+ */
+void fastcall wakeup_page_waiters(struct page * page)
+{
+	wait_queue_head_t * head;
+
+	head = page_waitqueue(page);
+	if (waitqueue_active(head))
+		wake_up(head);
+}
+
+/* 
+ * Wait for a page to get unlocked.
+ *
+ * This must be called with the caller "holding" the page,
+ * ie with increased "page->count" so that the page won't
+ * go away during the wait..
+ *
+ * The waiting strategy is to get on a waitqueue determined
+ * by hashing. Waiters will then collide, and the newly woken
+ * task must then determine whether it was woken for the page
+ * it really wanted, and go back to sleep on the waitqueue if
+ * that wasn't it. With the waitqueue semantics, it never leaves
+ * the waitqueue unless it calls, so the loop moves forward one
+ * iteration every time there is
+ * (1) a collision 
+ * and
+ * (2) one of the colliding pages is woken
+ *
+ * This is the thundering herd problem, but it is expected to
+ * be very rare due to the few pages that are actually being
+ * waited on at any given time and the quality of the hash function.
+ */
+void ___wait_on_page(struct page *page)
+{
+	wait_queue_head_t *waitqueue = page_waitqueue(page);
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+
+	add_wait_queue(waitqueue, &wait);
+	do {
+		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+		if (!PageLocked(page))
+			break;
+		sync_page(page);
+		schedule();
+	} while (PageLocked(page));
+	__set_task_state(tsk, TASK_RUNNING);
+	remove_wait_queue(waitqueue, &wait);
+}
+
+/*
+ * unlock_page() is the other half of the story just above
+ * __wait_on_page(). Here a couple of quick checks are done
+ * and a couple of flags are set on the page, and then all
+ * of the waiters for all of the pages in the appropriate
+ * wait queue are woken.
+ */
+void fastcall unlock_page(struct page *page)
+{
+	wait_queue_head_t *waitqueue = page_waitqueue(page);
+	ClearPageLaunder(page);
+	smp_mb__before_clear_bit();
+	if (!test_and_clear_bit(PG_locked, &(page)->flags))
+		BUG();
+	smp_mb__after_clear_bit(); 
+
+	/*
+	 * Although the default semantics of wake_up() are
+	 * to wake all, here the specific function is used
+	 * to make it even more explicit that a number of
+	 * pages are being waited on here.
+	 */
+	if (waitqueue_active(waitqueue))
+		wake_up_all(waitqueue);
+}
+
+/*
+ * Get a lock on the page, assuming we need to sleep
+ * to get it..
+ */
+static void __lock_page(struct page *page)
+{
+	wait_queue_head_t *waitqueue = page_waitqueue(page);
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+
+	add_wait_queue_exclusive(waitqueue, &wait);
+	for (;;) {
+		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+		if (PageLocked(page)) {
+			sync_page(page);
+			schedule();
+		}
+		if (!TryLockPage(page))
+			break;
+	}
+	__set_task_state(tsk, TASK_RUNNING);
+	remove_wait_queue(waitqueue, &wait);
+}
+
+/*
+ * Get an exclusive lock on the page, optimistically
+ * assuming it's not locked..
+ */
+void fastcall lock_page(struct page *page)
+{
+	if (TryLockPage(page))
+		__lock_page(page);
+}
+
+/*
+ * a rather lightweight function, finding and getting a reference to a
+ * hashed page atomically.
+ */
+struct page * __find_get_page(struct address_space *mapping,
+			      unsigned long offset, struct page **hash)
+{
+	struct page *page;
+
+	/*
+	 * We scan the hash list read-only. Addition to and removal from
+	 * the hash-list needs a held write-lock.
+	 */
+	spin_lock(&pagecache_lock);
+	page = __find_page_nolock(mapping, offset, *hash);
+	if (page)
+		page_cache_get(page);
+	spin_unlock(&pagecache_lock);
+	return page;
+}
+
+/*
+ * Same as above, but trylock it instead of incrementing the count.
+ */
+struct page *find_trylock_page(struct address_space *mapping, unsigned long offset)
+{
+	struct page *page;
+	struct page **hash = page_hash(mapping, offset);
+
+	spin_lock(&pagecache_lock);
+	page = __find_page_nolock(mapping, offset, *hash);
+	if (page) {
+		if (TryLockPage(page))
+			page = NULL;
+	}
+	spin_unlock(&pagecache_lock);
+	return page;
+}
+
+/*
+ * Must be called with the pagecache lock held,
+ * will return with it held (but it may be dropped
+ * during blocking operations..
+ */
+static struct page * FASTCALL(__find_lock_page_helper(struct address_space *, unsigned long, struct page *));
+static struct page * fastcall __find_lock_page_helper(struct address_space *mapping,
+					unsigned long offset, struct page *hash)
+{
+	struct page *page;
+
+	/*
+	 * We scan the hash list read-only. Addition to and removal from
+	 * the hash-list needs a held write-lock.
+	 */
+repeat:
+	page = __find_page_nolock(mapping, offset, hash);
+	if (page) {
+		page_cache_get(page);
+		if (TryLockPage(page)) {
+			spin_unlock(&pagecache_lock);
+			lock_page(page);
+			spin_lock(&pagecache_lock);
+
+			/* Has the page been re-allocated while we slept? */
+			if (page->mapping != mapping || page->index != offset) {
+				UnlockPage(page);
+				page_cache_release(page);
+				goto repeat;
+			}
+		}
+	}
+	return page;
+}
+
+/*
+ * Same as the above, but lock the page too, verifying that
+ * it's still valid once we own it.
+ */
+struct page * __find_lock_page (struct address_space *mapping,
+				unsigned long offset, struct page **hash)
+{
+	struct page *page;
+
+	spin_lock(&pagecache_lock);
+	page = __find_lock_page_helper(mapping, offset, *hash);
+	spin_unlock(&pagecache_lock);
+	return page;
+}
+
+/*
+ * Same as above, but create the page if required..
+ */
+struct page * find_or_create_page(struct address_space *mapping, unsigned long index, unsigned int gfp_mask)
+{
+	struct page *page;
+	struct page **hash = page_hash(mapping, index);
+
+	spin_lock(&pagecache_lock);
+	page = __find_lock_page_helper(mapping, index, *hash);
+	spin_unlock(&pagecache_lock);
+	if (!page) {
+		struct page *newpage = alloc_page(gfp_mask);
+		if (newpage) {
+			spin_lock(&pagecache_lock);
+			page = __find_lock_page_helper(mapping, index, *hash);
+			if (likely(!page)) {
+				page = newpage;
+				__add_to_page_cache(page, mapping, index, hash);
+				newpage = NULL;
+			}
+			spin_unlock(&pagecache_lock);
+			if (newpage == NULL)
+				lru_cache_add(page);
+			else 
+				page_cache_release(newpage);
+		}
+	}
+	return page;	
+}
+
+/*
+ * Same as grab_cache_page, but do not wait if the page is unavailable.
+ * This is intended for speculative data generators, where the data can
+ * be regenerated if the page couldn't be grabbed.  This routine should
+ * be safe to call while holding the lock for another page.
+ */
+struct page *grab_cache_page_nowait(struct address_space *mapping, unsigned long index)
+{
+	struct page *page, **hash;
+
+	hash = page_hash(mapping, index);
+	page = __find_get_page(mapping, index, hash);
+
+	if ( page ) {
+		if ( !TryLockPage(page) ) {
+			/* Page found and locked */
+			/* This test is overly paranoid, but what the heck... */
+			if ( unlikely(page->mapping != mapping || page->index != index) ) {
+				/* Someone reallocated this page under us. */
+				UnlockPage(page);
+				page_cache_release(page);
+				return NULL;
+			} else {
+				return page;
+			}
+		} else {
+			/* Page locked by someone else */
+			page_cache_release(page);
+			return NULL;
+		}
+	}
+
+	page = page_cache_alloc(mapping);
+	if ( unlikely(!page) )
+		return NULL;	/* Failed to allocate a page */
+
+	if ( unlikely(add_to_page_cache_unique(page, mapping, index, hash)) ) {
+		/* Someone else grabbed the page already. */
+		page_cache_release(page);
+		return NULL;
+	}
+
+	return page;
+}
+
+#if 0
+#define PROFILE_READAHEAD
+#define DEBUG_READAHEAD
+#endif
+
+/*
+ * Read-ahead profiling information
+ * --------------------------------
+ * Every PROFILE_MAXREADCOUNT, the following information is written 
+ * to the syslog:
+ *   Percentage of asynchronous read-ahead.
+ *   Average of read-ahead fields context value.
+ * If DEBUG_READAHEAD is defined, a snapshot of these fields is written 
+ * to the syslog.
+ */
+
+#ifdef PROFILE_READAHEAD
+
+#define PROFILE_MAXREADCOUNT 1000
+
+static unsigned long total_reada;
+static unsigned long total_async;
+static unsigned long total_ramax;
+static unsigned long total_ralen;
+static unsigned long total_rawin;
+
+static void profile_readahead(int async, struct file *filp)
+{
+	unsigned long flags;
+
+	++total_reada;
+	if (async)
+		++total_async;
+
+	total_ramax	+= filp->f_ramax;
+	total_ralen	+= filp->f_ralen;
+	total_rawin	+= filp->f_rawin;
+
+	if (total_reada > PROFILE_MAXREADCOUNT) {
+		save_flags(flags);
+		cli();
+		if (!(total_reada > PROFILE_MAXREADCOUNT)) {
+			restore_flags(flags);
+			return;
+		}
+
+		printk("Readahead average:  max=%ld, len=%ld, win=%ld, async=%ld%%\n",
+			total_ramax/total_reada,
+			total_ralen/total_reada,
+			total_rawin/total_reada,
+			(total_async*100)/total_reada);
+#ifdef DEBUG_READAHEAD
+		printk("Readahead snapshot: max=%ld, len=%ld, win=%ld, raend=%Ld\n",
+			filp->f_ramax, filp->f_ralen, filp->f_rawin, filp->f_raend);
+#endif
+
+		total_reada	= 0;
+		total_async	= 0;
+		total_ramax	= 0;
+		total_ralen	= 0;
+		total_rawin	= 0;
+
+		restore_flags(flags);
+	}
+}
+#endif  /* defined PROFILE_READAHEAD */
+
+/*
+ * Read-ahead context:
+ * -------------------
+ * The read ahead context fields of the "struct file" are the following:
+ * - f_raend : position of the first byte after the last page we tried to
+ *	       read ahead.
+ * - f_ramax : current read-ahead maximum size.
+ * - f_ralen : length of the current IO read block we tried to read-ahead.
+ * - f_rawin : length of the current read-ahead window.
+ *		if last read-ahead was synchronous then
+ *			f_rawin = f_ralen
+ *		otherwise (was asynchronous)
+ *			f_rawin = previous value of f_ralen + f_ralen
+ *
+ * Read-ahead limits:
+ * ------------------
+ * MIN_READAHEAD   : minimum read-ahead size when read-ahead.
+ * MAX_READAHEAD   : maximum read-ahead size when read-ahead.
+ *
+ * Synchronous read-ahead benefits:
+ * --------------------------------
+ * Using reasonable IO xfer length from peripheral devices increase system 
+ * performances.
+ * Reasonable means, in this context, not too large but not too small.
+ * The actual maximum value is:
+ *	MAX_READAHEAD + PAGE_CACHE_SIZE = 76k is CONFIG_READA_SMALL is undefined
+ *      and 32K if defined (4K page size assumed).
+ *
+ * Asynchronous read-ahead benefits:
+ * ---------------------------------
+ * Overlapping next read request and user process execution increase system 
+ * performance.
+ *
+ * Read-ahead risks:
+ * -----------------
+ * We have to guess which further data are needed by the user process.
+ * If these data are often not really needed, it's bad for system 
+ * performances.
+ * However, we know that files are often accessed sequentially by 
+ * application programs and it seems that it is possible to have some good 
+ * strategy in that guessing.
+ * We only try to read-ahead files that seems to be read sequentially.
+ *
+ * Asynchronous read-ahead risks:
+ * ------------------------------
+ * In order to maximize overlapping, we must start some asynchronous read 
+ * request from the device, as soon as possible.
+ * We must be very careful about:
+ * - The number of effective pending IO read requests.
+ *   ONE seems to be the only reasonable value.
+ * - The total memory pool usage for the file access stream.
+ *   This maximum memory usage is implicitly 2 IO read chunks:
+ *   2*(MAX_READAHEAD + PAGE_CACHE_SIZE) = 156K if CONFIG_READA_SMALL is undefined,
+ *   64k if defined (4K page size assumed).
+ */
+
+static inline int get_max_readahead(struct inode * inode)
+{
+	if (!inode->i_dev || !max_readahead[MAJOR(inode->i_dev)])
+		return vm_max_readahead;
+	return max_readahead[MAJOR(inode->i_dev)][MINOR(inode->i_dev)];
+}
+
+static void generic_file_readahead(int reada_ok,
+	struct file * filp, struct inode * inode,
+	struct page * page)
+{
+	unsigned long end_index;
+	unsigned long index = page->index;
+	unsigned long max_ahead, ahead;
+	unsigned long raend;
+	int max_readahead = get_max_readahead(inode);
+
+	end_index = inode->i_size >> PAGE_CACHE_SHIFT;
+
+	raend = filp->f_raend;
+	max_ahead = 0;
+
+/*
+ * The current page is locked.
+ * If the current position is inside the previous read IO request, do not
+ * try to reread previously read ahead pages.
+ * Otherwise decide or not to read ahead some pages synchronously.
+ * If we are not going to read ahead, set the read ahead context for this 
+ * page only.
+ */
+	if (PageLocked(page)) {
+		if (!filp->f_ralen || index >= raend || index + filp->f_rawin < raend) {
+			raend = index;
+			if (raend < end_index)
+				max_ahead = filp->f_ramax;
+			filp->f_rawin = 0;
+			filp->f_ralen = 1;
+			if (!max_ahead) {
+				filp->f_raend  = index + filp->f_ralen;
+				filp->f_rawin += filp->f_ralen;
+			}
+		}
+	}
+/*
+ * The current page is not locked.
+ * If we were reading ahead and,
+ * if the current max read ahead size is not zero and,
+ * if the current position is inside the last read-ahead IO request,
+ *   it is the moment to try to read ahead asynchronously.
+ * We will later force unplug device in order to force asynchronous read IO.
+ */
+	else if (reada_ok && filp->f_ramax && raend >= 1 &&
+		 index <= raend && index + filp->f_ralen >= raend) {
+/*
+ * Add ONE page to max_ahead in order to try to have about the same IO max size
+ * as synchronous read-ahead (MAX_READAHEAD + 1)*PAGE_CACHE_SIZE.
+ * Compute the position of the last page we have tried to read in order to 
+ * begin to read ahead just at the next page.
+ */
+		raend -= 1;
+		if (raend < end_index)
+			max_ahead = filp->f_ramax + 1;
+
+		if (max_ahead) {
+			filp->f_rawin = filp->f_ralen;
+			filp->f_ralen = 0;
+			reada_ok      = 2;
+		}
+	}
+/*
+ * Try to read ahead pages.
+ * We hope that ll_rw_blk() plug/unplug, coalescence, requests sort and the
+ * scheduler, will work enough for us to avoid too bad actuals IO requests.
+ */
+	ahead = 0;
+	while (ahead < max_ahead) {
+		unsigned long ra_index = raend + ahead + 1;
+
+		if (ra_index >= end_index)
+			break;
+		if (page_cache_read(filp, ra_index) < 0)
+			break;
+
+		ahead++;
+	}
+/*
+ * If we tried to read ahead some pages,
+ * If we tried to read ahead asynchronously,
+ *   Try to force unplug of the device in order to start an asynchronous
+ *   read IO request.
+ * Update the read-ahead context.
+ * Store the length of the current read-ahead window.
+ * Double the current max read ahead size.
+ *   That heuristic avoid to do some large IO for files that are not really
+ *   accessed sequentially.
+ */
+	if (ahead) {
+		filp->f_ralen += ahead;
+		filp->f_rawin += filp->f_ralen;
+		filp->f_raend = raend + ahead + 1;
+
+		filp->f_ramax += filp->f_ramax;
+
+		if (filp->f_ramax > max_readahead)
+			filp->f_ramax = max_readahead;
+
+#ifdef PROFILE_READAHEAD
+		profile_readahead((reada_ok == 2), filp);
+#endif
+	}
+
+	return;
+}
+
+/*
+ * Mark a page as having seen activity.
+ *
+ * If it was already so marked, move it to the active queue and drop
+ * the referenced bit.  Otherwise, just mark it for future action..
+ */
+void fastcall mark_page_accessed(struct page *page)
+{
+	if (!PageActive(page) && PageReferenced(page)) {
+		activate_page(page);
+		ClearPageReferenced(page);
+	} else
+		SetPageReferenced(page);
+}
+
+/*
+ * This is a generic file read routine, and uses the
+ * inode->i_op->readpage() function for the actual low-level
+ * stuff.
+ *
+ * This is really ugly. But the goto's actually try to clarify some
+ * of the logic when it comes to error handling etc.
+ */
+void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t * desc, read_actor_t actor)
+{
+	struct address_space *mapping = filp->f_dentry->d_inode->i_mapping;
+	struct inode *inode = mapping->host;
+	unsigned long index, offset;
+	struct page *cached_page;
+	int reada_ok;
+	int error;
+	int max_readahead = get_max_readahead(inode);
+
+	cached_page = NULL;
+	index = *ppos >> PAGE_CACHE_SHIFT;
+	offset = *ppos & ~PAGE_CACHE_MASK;
+
+/*
+ * If the current position is outside the previous read-ahead window, 
+ * we reset the current read-ahead context and set read ahead max to zero
+ * (will be set to just needed value later),
+ * otherwise, we assume that the file accesses are sequential enough to
+ * continue read-ahead.
+ */
+#ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
+	if (1 || index > filp->f_raend || index + filp->f_rawin < filp->f_raend) {
+#else
+	if (index > filp->f_raend || index + filp->f_rawin < filp->f_raend) {
+#endif
+		reada_ok = 0;
+		filp->f_raend = 0;
+		filp->f_ralen = 0;
+		filp->f_ramax = 0;
+		filp->f_rawin = 0;
+	} else {
+		reada_ok = 1;
+	}
+/*
+ * Adjust the current value of read-ahead max.
+ * If the read operation stay in the first half page, force no readahead.
+ * Otherwise try to increase read ahead max just enough to do the read request.
+ * Then, at least MIN_READAHEAD if read ahead is ok,
+ * and at most MAX_READAHEAD in all cases.
+ */
+	if (!index && offset + desc->count <= (PAGE_CACHE_SIZE >> 1)) {
+		filp->f_ramax = 0;
+	} else {
+		unsigned long needed;
+
+		needed = ((offset + desc->count) >> PAGE_CACHE_SHIFT) + 1;
+
+		if (filp->f_ramax < needed)
+			filp->f_ramax = needed;
+
+		if (reada_ok && filp->f_ramax < vm_min_readahead)
+				filp->f_ramax = vm_min_readahead;
+		if (filp->f_ramax > max_readahead)
+			filp->f_ramax = max_readahead;
+	}
+
+	for (;;) {
+		struct page *page, **hash;
+		unsigned long end_index, nr, ret;
+
+		end_index = inode->i_size >> PAGE_CACHE_SHIFT;
+			
+		if (index > end_index)
+			break;
+		nr = PAGE_CACHE_SIZE;
+		if (index == end_index) {
+			nr = inode->i_size & ~PAGE_CACHE_MASK;
+			if (nr <= offset)
+				break;
+		}
+
+		nr = nr - offset;
+
+		/*
+		 * Try to find the data in the page cache..
+		 */
+		hash = page_hash(mapping, index);
+
+		spin_lock(&pagecache_lock);
+		page = __find_page_nolock(mapping, index, *hash);
+		if (!page)
+			goto no_cached_page;
+found_page:
+		page_cache_get(page);
+		spin_unlock(&pagecache_lock);
+
+		if (!Page_Uptodate(page))
+			goto page_not_up_to_date;
+		generic_file_readahead(reada_ok, filp, inode, page);
+page_ok:
+#ifndef NO_MM
+		/* If users can be writing to this page using arbitrary
+		 * virtual addresses, take care about potential aliasing
+		 * before reading the page on the kernel side.
+		 */
+		if (mapping->i_mmap_shared != NULL)
+			flush_dcache_page(page);
+#endif /* NO_MM */
+
+		/*
+		 * Mark the page accessed if we read the
+		 * beginning or we just did an lseek.
+		 */
+		if (!offset || !filp->f_reada)
+			mark_page_accessed(page);
+
+		/*
+		 * Ok, we have the page, and it's up-to-date, so
+		 * now we can copy it to user space...
+		 *
+		 * The actor routine returns how many bytes were actually used..
+		 * NOTE! This may not be the same as how much of a user buffer
+		 * we filled up (we may be padding etc), so we can only update
+		 * "pos" here (the actor routine has to update the user buffer
+		 * pointers and the remaining count).
+		 */
+		ret = actor(desc, page, offset, nr);
+		offset += ret;
+		index += offset >> PAGE_CACHE_SHIFT;
+		offset &= ~PAGE_CACHE_MASK;
+
+		page_cache_release(page);
+		if (ret == nr && desc->count)
+			continue;
+		break;
+
+/*
+ * Ok, the page was not immediately readable, so let's try to read ahead while we're at it..
+ */
+page_not_up_to_date:
+		generic_file_readahead(reada_ok, filp, inode, page);
+
+		if (Page_Uptodate(page))
+			goto page_ok;
+
+		/* Get exclusive access to the page ... */
+		lock_page(page);
+
+		/* Did it get unhashed before we got the lock? */
+		if (!page->mapping) {
+			UnlockPage(page);
+			page_cache_release(page);
+			continue;
+		}
+
+		/* Did somebody else fill it already? */
+		if (Page_Uptodate(page)) {
+			UnlockPage(page);
+			goto page_ok;
+		}
+
+readpage:
+		/* ... and start the actual read. The read will unlock the page. */
+		error = mapping->a_ops->readpage(filp, page);
+
+		if (!error) {
+			if (Page_Uptodate(page))
+				goto page_ok;
+
+			/* Again, try some read-ahead while waiting for the page to finish.. */
+			generic_file_readahead(reada_ok, filp, inode, page);
+			wait_on_page(page);
+			if (Page_Uptodate(page))
+				goto page_ok;
+			error = -EIO;
+		}
+
+		/* UHHUH! A synchronous read error occurred. Report it */
+		desc->error = error;
+		page_cache_release(page);
+		break;
+
+no_cached_page:
+		/*
+		 * Ok, it wasn't cached, so we need to create a new
+		 * page..
+		 *
+		 * We get here with the page cache lock held.
+		 */
+		if (!cached_page) {
+			spin_unlock(&pagecache_lock);
+			cached_page = page_cache_alloc(mapping);
+			if (!cached_page) {
+				desc->error = -ENOMEM;
+				break;
+			}
+
+			/*
+			 * Somebody may have added the page while we
+			 * dropped the page cache lock. Check for that.
+			 */
+			spin_lock(&pagecache_lock);
+			page = __find_page_nolock(mapping, index, *hash);
+			if (page)
+				goto found_page;
+		}
+
+		/*
+		 * Ok, add the new page to the hash-queues...
+		 */
+		page = cached_page;
+		__add_to_page_cache(page, mapping, index, hash);
+		spin_unlock(&pagecache_lock);
+		lru_cache_add(page);		
+		cached_page = NULL;
+
+		goto readpage;
+	}
+
+	*ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
+	filp->f_reada = 1;
+	if (cached_page)
+		page_cache_release(cached_page);
+	UPDATE_ATIME(inode);
+}
+
+static inline int have_mapping_directIO(struct address_space * mapping)
+{
+	return mapping->a_ops->direct_IO || mapping->a_ops->direct_fileIO;
+}
+
+/* Switch between old and new directIO formats */
+static inline int do_call_directIO(int rw, struct file *filp, struct kiobuf *iobuf, unsigned long offset, int blocksize)
+{
+	struct address_space * mapping = filp->f_dentry->d_inode->i_mapping;
+
+	if (mapping->a_ops->direct_fileIO)
+		return mapping->a_ops->direct_fileIO(rw, filp, iobuf, offset, blocksize);
+	return mapping->a_ops->direct_IO(rw, mapping->host, iobuf, offset, blocksize);
+}
+
+/*
+ * i_sem and i_alloc_sem should be held already.  i_sem may be dropped
+ * later once we've mapped the new IO.  i_alloc_sem is kept until the IO
+ * completes.
+ */
+
+static ssize_t generic_file_direct_IO(int rw, struct file * filp, char * buf, size_t count, loff_t offset)
+{
+	ssize_t retval, progress;
+	int new_iobuf, chunk_size, blocksize_mask, blocksize, blocksize_bits;
+	ssize_t iosize;
+	struct kiobuf * iobuf;
+	struct address_space * mapping = filp->f_dentry->d_inode->i_mapping;
+	struct inode * inode = mapping->host;
+	loff_t size = inode->i_size;
+
+	new_iobuf = 0;
+	iobuf = filp->f_iobuf;
+	if (test_and_set_bit(0, &filp->f_iobuf_lock)) {
+		/*
+		 * A parallel read/write is using the preallocated iobuf
+		 * so just run slow and allocate a new one.
+		 */
+		retval = alloc_kiovec(1, &iobuf);
+		if (retval)
+			goto out;
+		new_iobuf = 1;
+	}
+
+	blocksize = 1 << inode->i_blkbits;
+	blocksize_bits = inode->i_blkbits;
+	blocksize_mask = blocksize - 1;
+	chunk_size = KIO_MAX_ATOMIC_IO << 10;
+
+	retval = -EINVAL;
+	if ((offset & blocksize_mask) || (count & blocksize_mask) || ((unsigned long) buf & blocksize_mask))
+		goto out_free;
+	if (!have_mapping_directIO(mapping))
+		goto out_free;
+
+	if ((rw == READ) && (offset + count > size))
+		count = size - offset;
+
+	/*
+	 * Flush to disk exclusively the _data_, metadata must remain
+	 * completly asynchronous or performance will go to /dev/null.
+	 */
+	retval = filemap_fdatasync(mapping);
+	if (retval == 0)
+		retval = fsync_inode_data_buffers(inode);
+	if (retval == 0)
+		retval = filemap_fdatawait(mapping);
+	if (retval < 0)
+		goto out_free;
+
+	progress = retval = 0;
+	while (count > 0) {
+		iosize = count;
+		if (iosize > chunk_size)
+			iosize = chunk_size;
+
+		retval = map_user_kiobuf(rw, iobuf, (unsigned long) buf, iosize);
+		if (retval)
+			break;
+
+		retval = do_call_directIO(rw, filp, iobuf, (offset+progress) >> blocksize_bits, blocksize);
+
+		if (rw == READ && retval > 0)
+			mark_dirty_kiobuf(iobuf, retval);
+		
+		if (retval >= 0) {
+			count -= retval;
+			buf += retval;
+			/* warning: weird semantics here, we're reporting a read behind the end of the file */
+			progress += retval;
+		}
+
+		unmap_kiobuf(iobuf);
+
+		if (retval != iosize)
+			break;
+	}
+
+	if (progress)
+		retval = progress;
+
+ out_free:
+	if (!new_iobuf)
+		clear_bit(0, &filp->f_iobuf_lock);
+	else
+		free_kiovec(1, &iobuf);
+ out:	
+	return retval;
+}
+
+int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size)
+{
+	char *kaddr;
+	unsigned long left, count = desc->count;
+
+	if (size > count)
+		size = count;
+
+	kaddr = kmap(page);
+	left = __copy_to_user(desc->buf, kaddr + offset, size);
+	kunmap(page);
+	
+	if (left) {
+		size -= left;
+		desc->error = -EFAULT;
+	}
+	desc->count = count - size;
+	desc->written += size;
+	desc->buf += size;
+	return size;
+}
+
+inline ssize_t do_generic_direct_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
+{
+	ssize_t retval;
+	loff_t pos = *ppos;
+
+	retval = generic_file_direct_IO(READ, filp, buf, count, pos);
+	if (retval > 0)
+		*ppos = pos + retval;
+	return retval;
+}
+
+/*
+ * This is the "read()" routine for all filesystems
+ * that can use the page cache directly.
+ */
+ssize_t generic_file_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
+{
+	ssize_t retval;
+
+	if ((ssize_t) count < 0)
+		return -EINVAL;
+
+	if (filp->f_flags & O_DIRECT)
+		goto o_direct;
+
+	retval = -EFAULT;
+	if (access_ok(VERIFY_WRITE, buf, count)) {
+		retval = 0;
+
+		if (count) {
+			read_descriptor_t desc;
+
+			desc.written = 0;
+			desc.count = count;
+			desc.buf = buf;
+			desc.error = 0;
+			do_generic_file_read(filp, ppos, &desc, file_read_actor);
+
+			retval = desc.written;
+			if (!retval)
+				retval = desc.error;
+		}
+	}
+ out:
+	return retval;
+
+ o_direct:
+	{
+		loff_t size;
+		struct address_space *mapping = filp->f_dentry->d_inode->i_mapping;
+		struct inode *inode = mapping->host;
+
+		retval = 0;
+		if (!count)
+			goto out; /* skip atime */
+		down_read(&inode->i_alloc_sem);
+		down(&inode->i_sem);
+		size = inode->i_size;
+		if (*ppos < size)
+			retval = do_generic_direct_read(filp, buf, count, ppos);
+		up(&inode->i_sem);
+		up_read(&inode->i_alloc_sem);
+		UPDATE_ATIME(filp->f_dentry->d_inode);
+		goto out;
+	}
+}
+
+static int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset , unsigned long size)
+{
+	ssize_t written;
+	unsigned long count = desc->count;
+	struct file *file = (struct file *) desc->buf;
+
+	if (size > count)
+		size = count;
+
+ 	if (file->f_op->sendpage) {
+ 		written = file->f_op->sendpage(file, page, offset,
+					       size, &file->f_pos, size<count);
+	} else {
+		char *kaddr;
+		mm_segment_t old_fs;
+
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+
+		kaddr = kmap(page);
+		written = file->f_op->write(file, kaddr + offset, size, &file->f_pos);
+		kunmap(page);
+
+		set_fs(old_fs);
+	}
+	if (written < 0) {
+		desc->error = written;
+		written = 0;
+	}
+	desc->count = count - written;
+	desc->written += written;
+	return written;
+}
+
+static ssize_t common_sendfile(int out_fd, int in_fd, loff_t *offset, size_t count)
+{
+	ssize_t retval;
+	struct file * in_file, * out_file;
+	struct inode * in_inode, * out_inode;
+
+	/*
+	 * Get input file, and verify that it is ok..
+	 */
+	retval = -EBADF;
+	in_file = fget(in_fd);
+	if (!in_file)
+		goto out;
+	if (!(in_file->f_mode & FMODE_READ))
+		goto fput_in;
+	retval = -EINVAL;
+	in_inode = in_file->f_dentry->d_inode;
+	if (!in_inode)
+		goto fput_in;
+	if (!in_inode->i_mapping->a_ops->readpage)
+		goto fput_in;
+	retval = locks_verify_area(FLOCK_VERIFY_READ, in_inode, in_file, in_file->f_pos, count);
+	if (retval)
+		goto fput_in;
+
+	/*
+	 * Get output file, and verify that it is ok..
+	 */
+	retval = -EBADF;
+	out_file = fget(out_fd);
+	if (!out_file)
+		goto fput_in;
+	if (!(out_file->f_mode & FMODE_WRITE))
+		goto fput_out;
+	retval = -EINVAL;
+	if (!out_file->f_op || !out_file->f_op->write)
+		goto fput_out;
+	out_inode = out_file->f_dentry->d_inode;
+	retval = locks_verify_area(FLOCK_VERIFY_WRITE, out_inode, out_file, out_file->f_pos, count);
+	if (retval)
+		goto fput_out;
+
+	retval = 0;
+	if (count) {
+		read_descriptor_t desc;
+		
+		if (!offset)
+			offset = &in_file->f_pos;
+
+		desc.written = 0;
+		desc.count = count;
+		desc.buf = (char *) out_file;
+		desc.error = 0;
+		do_generic_file_read(in_file, offset, &desc, file_send_actor);
+
+		retval = desc.written;
+		if (!retval)
+			retval = desc.error;
+	}
+
+fput_out:
+	fput(out_file);
+fput_in:
+	fput(in_file);
+out:
+	return retval;
+}
+
+asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
+{
+	loff_t pos, *ppos = NULL;
+	ssize_t ret;
+	if (offset) {
+		off_t off;
+		if (unlikely(get_user(off, offset)))
+			return -EFAULT;
+		pos = off;
+		ppos = &pos;
+	}
+	ret = common_sendfile(out_fd, in_fd, ppos, count);
+	if (offset)
+		put_user((off_t)pos, offset);
+	return ret;
+}
+
+asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd, loff_t *offset, size_t count)
+{
+	loff_t pos, *ppos = NULL;
+	ssize_t ret;
+	if (offset) {
+		if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
+			return -EFAULT;
+		ppos = &pos;
+	}
+	ret = common_sendfile(out_fd, in_fd, ppos, count);
+	if (offset)
+		put_user(pos, offset);
+	return ret;
+}
+
+static ssize_t do_readahead(struct file *file, unsigned long index, unsigned long nr)
+{
+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+	unsigned long max;
+
+	if (!mapping || !mapping->a_ops || !mapping->a_ops->readpage)
+		return -EINVAL;
+
+	/* Limit it to the size of the file.. */
+	max = (mapping->host->i_size + ~PAGE_CACHE_MASK) >> PAGE_CACHE_SHIFT;
+	if (index > max)
+		return 0;
+	max -= index;
+	if (nr > max)
+		nr = max;
+
+	/* And limit it to a sane percentage of the inactive list.. */
+	max = (nr_free_pages() + nr_inactive_pages) / 2;
+	if (nr > max)
+		nr = max;
+
+	while (nr) {
+		page_cache_read(file, index);
+		index++;
+		nr--;
+	}
+	return 0;
+}
+
+asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count)
+{
+	ssize_t ret;
+	struct file *file;
+
+	ret = -EBADF;
+	file = fget(fd);
+	if (file) {
+		if (file->f_mode & FMODE_READ) {
+			unsigned long start = offset >> PAGE_CACHE_SHIFT;
+			unsigned long len = (count + ((long)offset & ~PAGE_CACHE_MASK)) >> PAGE_CACHE_SHIFT;
+			ret = do_readahead(file, start, len);
+		}
+		fput(file);
+	}
+	return ret;
+}
+
+#ifndef NO_MM
+
+/*
+ * Read-ahead and flush behind for MADV_SEQUENTIAL areas.  Since we are
+ * sure this is sequential access, we don't need a flexible read-ahead
+ * window size -- we can always use a large fixed size window.
+ */
+static void nopage_sequential_readahead(struct vm_area_struct * vma,
+	unsigned long pgoff, unsigned long filesize)
+{
+	unsigned long ra_window;
+
+	ra_window = get_max_readahead(vma->vm_file->f_dentry->d_inode);
+	ra_window = CLUSTER_OFFSET(ra_window + CLUSTER_PAGES - 1);
+
+	/* vm_raend is zero if we haven't read ahead in this area yet.  */
+	if (vma->vm_raend == 0)
+		vma->vm_raend = vma->vm_pgoff + ra_window;
+
+	/*
+	 * If we've just faulted the page half-way through our window,
+	 * then schedule reads for the next window, and release the
+	 * pages in the previous window.
+	 */
+	if ((pgoff + (ra_window >> 1)) == vma->vm_raend) {
+		unsigned long start = vma->vm_pgoff + vma->vm_raend;
+		unsigned long end = start + ra_window;
+
+		if (end > ((vma->vm_end >> PAGE_SHIFT) + vma->vm_pgoff))
+			end = (vma->vm_end >> PAGE_SHIFT) + vma->vm_pgoff;
+		if (start > end)
+			return;
+
+		while ((start < end) && (start < filesize)) {
+			if (read_cluster_nonblocking(vma->vm_file,
+							start, filesize) < 0)
+				break;
+			start += CLUSTER_PAGES;
+		}
+		run_task_queue(&tq_disk);
+
+		/* if we're far enough past the beginning of this area,
+		   recycle pages that are in the previous window. */
+		if (vma->vm_raend > (vma->vm_pgoff + ra_window + ra_window)) {
+			unsigned long window = ra_window << PAGE_SHIFT;
+
+			end = vma->vm_start + (vma->vm_raend << PAGE_SHIFT);
+			end -= window + window;
+			filemap_sync(vma, end - window, window, MS_INVALIDATE);
+		}
+
+		vma->vm_raend += ra_window;
+	}
+
+	return;
+}
+
+/*
+ * filemap_nopage() is invoked via the vma operations vector for a
+ * mapped memory region to read in file data during a page fault.
+ *
+ * The goto's are kind of ugly, but this streamlines the normal case of having
+ * it in the page cache, and handles the special cases reasonably without
+ * having a lot of duplicated code.
+ */
+struct page * filemap_nopage(struct vm_area_struct * area, unsigned long address, int unused)
+{
+	int error;
+	struct file *file = area->vm_file;
+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+	struct inode *inode = mapping->host;
+	struct page *page, **hash;
+	unsigned long size, pgoff, endoff;
+
+	pgoff = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) + area->vm_pgoff;
+	endoff = ((area->vm_end - area->vm_start) >> PAGE_CACHE_SHIFT) + area->vm_pgoff;
+
+retry_all:
+	/*
+	 * An external ptracer can access pages that normally aren't
+	 * accessible..
+	 */
+	size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	if ((pgoff >= size) && (area->vm_mm == current->mm))
+		return NULL;
+
+	/* The "size" of the file, as far as mmap is concerned, isn't bigger than the mapping */
+	if (size > endoff)
+		size = endoff;
+
+	/*
+	 * Do we have something in the page cache already?
+	 */
+	hash = page_hash(mapping, pgoff);
+retry_find:
+	page = __find_get_page(mapping, pgoff, hash);
+	if (!page)
+		goto no_cached_page;
+
+	/*
+	 * Ok, found a page in the page cache, now we need to check
+	 * that it's up-to-date.
+	 */
+	if (!Page_Uptodate(page))
+		goto page_not_uptodate;
+
+success:
+ 	/*
+	 * Try read-ahead for sequential areas.
+	 */
+	if (VM_SequentialReadHint(area))
+		nopage_sequential_readahead(area, pgoff, size);
+
+	/*
+	 * Found the page and have a reference on it, need to check sharing
+	 * and possibly copy it over to another page..
+	 */
+	mark_page_accessed(page);
+	flush_page_to_ram(page);
+	return page;
+
+no_cached_page:
+	/*
+	 * If the requested offset is within our file, try to read a whole 
+	 * cluster of pages at once.
+	 *
+	 * Otherwise, we're off the end of a privately mapped file,
+	 * so we need to map a zero page.
+	 */
+	if ((pgoff < size) && !VM_RandomReadHint(area))
+		error = read_cluster_nonblocking(file, pgoff, size);
+	else
+		error = page_cache_read(file, pgoff);
+
+	/*
+	 * The page we want has now been added to the page cache.
+	 * In the unlikely event that someone removed it in the
+	 * meantime, we'll just come back here and read it again.
+	 */
+	if (error >= 0)
+		goto retry_find;
+
+	/*
+	 * An error return from page_cache_read can result if the
+	 * system is low on memory, or a problem occurs while trying
+	 * to schedule I/O.
+	 */
+	if (error == -ENOMEM)
+		return NOPAGE_OOM;
+	return NULL;
+
+page_not_uptodate:
+	lock_page(page);
+
+	/* Did it get unhashed while we waited for it? */
+	if (!page->mapping) {
+		UnlockPage(page);
+		page_cache_release(page);
+		goto retry_all;
+	}
+
+	/* Did somebody else get it up-to-date? */
+	if (Page_Uptodate(page)) {
+		UnlockPage(page);
+		goto success;
+	}
+
+	if (!mapping->a_ops->readpage(file, page)) {
+		wait_on_page(page);
+		if (Page_Uptodate(page))
+			goto success;
+	}
+
+	/*
+	 * Umm, take care of errors if the page isn't up-to-date.
+	 * Try to re-read it _once_. We do this synchronously,
+	 * because there really aren't any performance issues here
+	 * and we need to check for errors.
+	 */
+	lock_page(page);
+
+	/* Somebody truncated the page on us? */
+	if (!page->mapping) {
+		UnlockPage(page);
+		page_cache_release(page);
+		goto retry_all;
+	}
+
+	/* Somebody else successfully read it in? */
+	if (Page_Uptodate(page)) {
+		UnlockPage(page);
+		goto success;
+	}
+	ClearPageError(page);
+	if (!mapping->a_ops->readpage(file, page)) {
+		wait_on_page(page);
+		if (Page_Uptodate(page))
+			goto success;
+	}
+
+	/*
+	 * Things didn't work out. Return zero to tell the
+	 * mm layer so, possibly freeing the page cache page first.
+	 */
+	page_cache_release(page);
+	return NULL;
+}
+
+/* Called with mm->page_table_lock held to protect against other
+ * threads/the swapper from ripping pte's out from under us.
+ */
+static inline int filemap_sync_pte(pte_t * ptep, struct vm_area_struct *vma,
+	unsigned long address, unsigned int flags)
+{
+	pte_t pte = *ptep;
+
+	if (pte_present(pte)) {
+		struct page *page = pte_page(pte);
+		if (VALID_PAGE(page) && !PageReserved(page) && ptep_test_and_clear_dirty(ptep)) {
+			flush_tlb_page(vma, address);
+			set_page_dirty(page);
+		}
+	}
+	return 0;
+}
+
+static inline int filemap_sync_pte_range(pmd_t * pmd,
+	unsigned long address, unsigned long size, 
+	struct vm_area_struct *vma, unsigned long offset, unsigned int flags)
+{
+	pte_t * pte;
+	unsigned long end;
+	int error;
+
+	if (pmd_none(*pmd))
+		return 0;
+	if (pmd_bad(*pmd)) {
+		pmd_ERROR(*pmd);
+		pmd_clear(pmd);
+		return 0;
+	}
+	pte = pte_offset(pmd, address);
+	offset += address & PMD_MASK;
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	error = 0;
+	do {
+		error |= filemap_sync_pte(pte, vma, address + offset, flags);
+		address += PAGE_SIZE;
+		pte++;
+	} while (address && (address < end));
+	return error;
+}
+
+static inline int filemap_sync_pmd_range(pgd_t * pgd,
+	unsigned long address, unsigned long size, 
+	struct vm_area_struct *vma, unsigned int flags)
+{
+	pmd_t * pmd;
+	unsigned long offset, end;
+	int error;
+
+	if (pgd_none(*pgd))
+		return 0;
+	if (pgd_bad(*pgd)) {
+		pgd_ERROR(*pgd);
+		pgd_clear(pgd);
+		return 0;
+	}
+	pmd = pmd_offset(pgd, address);
+	offset = address & PGDIR_MASK;
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	error = 0;
+	do {
+		error |= filemap_sync_pte_range(pmd, address, end - address, vma, offset, flags);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address && (address < end));
+	return error;
+}
+
+int filemap_sync(struct vm_area_struct * vma, unsigned long address,
+	size_t size, unsigned int flags)
+{
+	pgd_t * dir;
+	unsigned long end = address + size;
+	int error = 0;
+
+	/* Aquire the lock early; it may be possible to avoid dropping
+	 * and reaquiring it repeatedly.
+	 */
+	spin_lock(&vma->vm_mm->page_table_lock);
+
+	dir = pgd_offset(vma->vm_mm, address);
+	flush_cache_range(vma->vm_mm, end - size, end);
+	if (address >= end)
+		BUG();
+	do {
+		error |= filemap_sync_pmd_range(dir, address, end - address, vma, flags);
+		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	} while (address && (address < end));
+	flush_tlb_range(vma->vm_mm, end - size, end);
+
+	spin_unlock(&vma->vm_mm->page_table_lock);
+
+	return error;
+}
+
+static struct vm_operations_struct generic_file_vm_ops = {
+	nopage:		filemap_nopage,
+};
+
+#endif /* NO_MM */
+
+/* This is used for a general mmap of a disk file */
+
+int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
+{
+#ifndef NO_MM
+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+	struct inode *inode = mapping->host;
+  
+  	if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) {
+		if (!mapping->a_ops->writepage)
+  			return -EINVAL;
+  	}
+	if (!mapping->a_ops->readpage)
+		return -ENOEXEC;
+	UPDATE_ATIME(inode);
+	vma->vm_ops = &generic_file_vm_ops;
+	return 0;
+#else /* NO_MM */
+	/* DAVIDM should do something here to get shared mappings working */
+	if (vma->vm_flags & VM_MAYWRITE)
+		return(-ENOSYS);
+	return 0;
+#endif /* NO_MM */
+}
+
+#ifndef NO_MM
+/*
+ * The msync() system call.
+ */
+
+/*
+ * MS_SYNC syncs the entire file - including mappings.
+ *
+ * MS_ASYNC initiates writeout of just the dirty mapped data.
+ * This provides no guarantee of file integrity - things like indirect
+ * blocks may not have started writeout.  MS_ASYNC is primarily useful
+ * where the application knows that it has finished with the data and
+ * wishes to intelligently schedule its own I/O traffic.
+ */
+static int msync_interval(struct vm_area_struct * vma,
+	unsigned long start, unsigned long end, int flags)
+{
+	int ret = 0;
+	struct file * file = vma->vm_file;
+
+	if ( (flags & MS_INVALIDATE) && (vma->vm_flags & VM_LOCKED) )
+		return -EBUSY;
+
+	if (file && (vma->vm_flags & VM_SHARED)) {
+		ret = filemap_sync(vma, start, end-start, flags);
+
+		if (!ret && (flags & (MS_SYNC|MS_ASYNC))) {
+			struct inode * inode = file->f_dentry->d_inode;
+
+			down(&inode->i_sem);
+			ret = filemap_fdatasync(inode->i_mapping);
+			if (flags & MS_SYNC) {
+				int err;
+
+				if (file->f_op && file->f_op->fsync) {
+					err = file->f_op->fsync(file, file->f_dentry, 1);
+					if (err && !ret)
+						ret = err;
+				}
+				err = filemap_fdatawait(inode->i_mapping);
+				if (err && !ret)
+					ret = err;
+			}
+			up(&inode->i_sem);
+		}
+	}
+	return ret;
+}
+
+#endif /* NO_MM */
+
+asmlinkage long sys_msync(unsigned long start, size_t len, int flags)
+{
+#ifndef NO_MM
+	unsigned long end;
+	struct vm_area_struct * vma;
+	int unmapped_error, error = -EINVAL;
+
+	down_read(&current->mm->mmap_sem);
+	if (start & ~PAGE_MASK)
+		goto out;
+	len = (len + ~PAGE_MASK) & PAGE_MASK;
+	end = start + len;
+	if (end < start)
+		goto out;
+	if (flags & ~(MS_ASYNC | MS_INVALIDATE | MS_SYNC))
+		goto out;
+	if ((flags & MS_ASYNC) && (flags & MS_SYNC))
+		goto out;
+
+	error = 0;
+	if (end == start)
+		goto out;
+	/*
+	 * If the interval [start,end) covers some unmapped address ranges,
+	 * just ignore them, but return -ENOMEM at the end.
+	 */
+	vma = find_vma(current->mm, start);
+	unmapped_error = 0;
+	for (;;) {
+		/* Still start < end. */
+		error = -ENOMEM;
+		if (!vma)
+			goto out;
+		/* Here start < vma->vm_end. */
+		if (start < vma->vm_start) {
+			unmapped_error = -ENOMEM;
+			start = vma->vm_start;
+		}
+		/* Here vma->vm_start <= start < vma->vm_end. */
+		if (end <= vma->vm_end) {
+			if (start < end) {
+				error = msync_interval(vma, start, end, flags);
+				if (error)
+					goto out;
+			}
+			error = unmapped_error;
+			goto out;
+		}
+		/* Here vma->vm_start <= start < vma->vm_end < end. */
+		error = msync_interval(vma, start, vma->vm_end, flags);
+		if (error)
+			goto out;
+		start = vma->vm_end;
+		vma = vma->vm_next;
+	}
+out:
+	up_read(&current->mm->mmap_sem);
+	return error;
+#else
+	return(-ENOSYS);
+#endif /* NO_MM */
+}
+
+#ifndef NO_MM
+
+static inline void setup_read_behavior(struct vm_area_struct * vma,
+	int behavior)
+{
+	VM_ClearReadHint(vma);
+	switch(behavior) {
+		case MADV_SEQUENTIAL:
+			vma->vm_flags |= VM_SEQ_READ;
+			break;
+		case MADV_RANDOM:
+			vma->vm_flags |= VM_RAND_READ;
+			break;
+		default:
+			break;
+	}
+	return;
+}
+
+static long madvise_fixup_start(struct vm_area_struct * vma,
+	unsigned long end, int behavior)
+{
+	struct vm_area_struct * n;
+	struct mm_struct * mm = vma->vm_mm;
+
+	n = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+	if (!n)
+		return -EAGAIN;
+	*n = *vma;
+	n->vm_end = end;
+	setup_read_behavior(n, behavior);
+	n->vm_raend = 0;
+	if (n->vm_file)
+		get_file(n->vm_file);
+	if (n->vm_ops && n->vm_ops->open)
+		n->vm_ops->open(n);
+	vma->vm_pgoff += (end - vma->vm_start) >> PAGE_SHIFT;
+	lock_vma_mappings(vma);
+	spin_lock(&mm->page_table_lock);
+	vma->vm_start = end;
+	__insert_vm_struct(mm, n);
+	spin_unlock(&mm->page_table_lock);
+	unlock_vma_mappings(vma);
+	return 0;
+}
+
+static long madvise_fixup_end(struct vm_area_struct * vma,
+	unsigned long start, int behavior)
+{
+	struct vm_area_struct * n;
+	struct mm_struct * mm = vma->vm_mm;
+
+	n = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+	if (!n)
+		return -EAGAIN;
+	*n = *vma;
+	n->vm_start = start;
+	n->vm_pgoff += (n->vm_start - vma->vm_start) >> PAGE_SHIFT;
+	setup_read_behavior(n, behavior);
+	n->vm_raend = 0;
+	if (n->vm_file)
+		get_file(n->vm_file);
+	if (n->vm_ops && n->vm_ops->open)
+		n->vm_ops->open(n);
+	lock_vma_mappings(vma);
+	spin_lock(&mm->page_table_lock);
+	vma->vm_end = start;
+	__insert_vm_struct(mm, n);
+	spin_unlock(&mm->page_table_lock);
+	unlock_vma_mappings(vma);
+	return 0;
+}
+
+static long madvise_fixup_middle(struct vm_area_struct * vma,
+	unsigned long start, unsigned long end, int behavior)
+{
+	struct vm_area_struct * left, * right;
+	struct mm_struct * mm = vma->vm_mm;
+
+	left = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+	if (!left)
+		return -EAGAIN;
+	right = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+	if (!right) {
+		kmem_cache_free(vm_area_cachep, left);
+		return -EAGAIN;
+	}
+	*left = *vma;
+	*right = *vma;
+	left->vm_end = start;
+	right->vm_start = end;
+	right->vm_pgoff += (right->vm_start - left->vm_start) >> PAGE_SHIFT;
+	left->vm_raend = 0;
+	right->vm_raend = 0;
+	if (vma->vm_file)
+		atomic_add(2, &vma->vm_file->f_count);
+
+	if (vma->vm_ops && vma->vm_ops->open) {
+		vma->vm_ops->open(left);
+		vma->vm_ops->open(right);
+	}
+	vma->vm_pgoff += (start - vma->vm_start) >> PAGE_SHIFT;
+	vma->vm_raend = 0;
+	lock_vma_mappings(vma);
+	spin_lock(&mm->page_table_lock);
+	vma->vm_start = start;
+	vma->vm_end = end;
+	setup_read_behavior(vma, behavior);
+	__insert_vm_struct(mm, left);
+	__insert_vm_struct(mm, right);
+	spin_unlock(&mm->page_table_lock);
+	unlock_vma_mappings(vma);
+	return 0;
+}
+
+/*
+ * We can potentially split a vm area into separate
+ * areas, each area with its own behavior.
+ */
+static long madvise_behavior(struct vm_area_struct * vma,
+	unsigned long start, unsigned long end, int behavior)
+{
+	int error = 0;
+
+	/* This caps the number of vma's this process can own */
+	if (vma->vm_mm->map_count > max_map_count)
+		return -ENOMEM;
+
+	if (start == vma->vm_start) {
+		if (end == vma->vm_end) {
+			setup_read_behavior(vma, behavior);
+			vma->vm_raend = 0;
+		} else
+			error = madvise_fixup_start(vma, end, behavior);
+	} else {
+		if (end == vma->vm_end)
+			error = madvise_fixup_end(vma, start, behavior);
+		else
+			error = madvise_fixup_middle(vma, start, end, behavior);
+	}
+
+	return error;
+}
+
+/*
+ * Schedule all required I/O operations, then run the disk queue
+ * to make sure they are started.  Do not wait for completion.
+ */
+static long madvise_willneed(struct vm_area_struct * vma,
+	unsigned long start, unsigned long end)
+{
+	long error = -EBADF;
+	struct file * file;
+	struct inode * inode;
+	unsigned long size, rlim_rss;
+
+	/* Doesn't work if there's no mapped file. */
+	if (!vma->vm_file)
+		return error;
+	file = vma->vm_file;
+	inode = file->f_dentry->d_inode;
+	if (!inode->i_mapping->a_ops->readpage)
+		return error;
+	size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+
+	start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+	if (end > vma->vm_end)
+		end = vma->vm_end;
+	end = ((end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+
+	/* Make sure this doesn't exceed the process's max rss. */
+	error = -EIO;
+	rlim_rss = current->rlim ?  current->rlim[RLIMIT_RSS].rlim_cur :
+				LONG_MAX; /* default: see resource.h */
+	if ((vma->vm_mm->rss + (end - start)) > rlim_rss)
+		return error;
+
+	/* round to cluster boundaries if this isn't a "random" area. */
+	if (!VM_RandomReadHint(vma)) {
+		start = CLUSTER_OFFSET(start);
+		end = CLUSTER_OFFSET(end + CLUSTER_PAGES - 1);
+
+		while ((start < end) && (start < size)) {
+			error = read_cluster_nonblocking(file, start, size);
+			start += CLUSTER_PAGES;
+			if (error < 0)
+				break;
+		}
+	} else {
+		while ((start < end) && (start < size)) {
+			error = page_cache_read(file, start);
+			start++;
+			if (error < 0)
+				break;
+		}
+	}
+
+	/* Don't wait for someone else to push these requests. */
+	run_task_queue(&tq_disk);
+
+	return error;
+}
+
+/*
+ * Application no longer needs these pages.  If the pages are dirty,
+ * it's OK to just throw them away.  The app will be more careful about
+ * data it wants to keep.  Be sure to free swap resources too.  The
+ * zap_page_range call sets things up for refill_inactive to actually free
+ * these pages later if no one else has touched them in the meantime,
+ * although we could add these pages to a global reuse list for
+ * refill_inactive to pick up before reclaiming other pages.
+ *
+ * NB: This interface discards data rather than pushes it out to swap,
+ * as some implementations do.  This has performance implications for
+ * applications like large transactional databases which want to discard
+ * pages in anonymous maps after committing to backing store the data
+ * that was kept in them.  There is no reason to write this data out to
+ * the swap area if the application is discarding it.
+ *
+ * An interface that causes the system to free clean pages and flush
+ * dirty pages is already available as msync(MS_INVALIDATE).
+ */
+static long madvise_dontneed(struct vm_area_struct * vma,
+	unsigned long start, unsigned long end)
+{
+	if (vma->vm_flags & VM_LOCKED)
+		return -EINVAL;
+
+	zap_page_range(vma->vm_mm, start, end - start);
+	return 0;
+}
+
+static long madvise_vma(struct vm_area_struct * vma, unsigned long start,
+	unsigned long end, int behavior)
+{
+	long error = -EBADF;
+
+	switch (behavior) {
+	case MADV_NORMAL:
+	case MADV_SEQUENTIAL:
+	case MADV_RANDOM:
+		error = madvise_behavior(vma, start, end, behavior);
+		break;
+
+	case MADV_WILLNEED:
+		error = madvise_willneed(vma, start, end);
+		break;
+
+	case MADV_DONTNEED:
+		error = madvise_dontneed(vma, start, end);
+		break;
+
+	default:
+		error = -EINVAL;
+		break;
+	}
+		
+	return error;
+}
+
+#endif /* NO_MM */
+
+/*
+ * The madvise(2) system call.
+ *
+ * Applications can use madvise() to advise the kernel how it should
+ * handle paging I/O in this VM area.  The idea is to help the kernel
+ * use appropriate read-ahead and caching techniques.  The information
+ * provided is advisory only, and can be safely disregarded by the
+ * kernel without affecting the correct operation of the application.
+ *
+ * behavior values:
+ *  MADV_NORMAL - the default behavior is to read clusters.  This
+ *		results in some read-ahead and read-behind.
+ *  MADV_RANDOM - the system should read the minimum amount of data
+ *		on any access, since it is unlikely that the appli-
+ *		cation will need more than what it asks for.
+ *  MADV_SEQUENTIAL - pages in the given range will probably be accessed
+ *		once, so they can be aggressively read ahead, and
+ *		can be freed soon after they are accessed.
+ *  MADV_WILLNEED - the application is notifying the system to read
+ *		some pages ahead.
+ *  MADV_DONTNEED - the application is finished with the given range,
+ *		so the kernel can free resources associated with it.
+ *
+ * return values:
+ *  zero    - success
+ *  -EINVAL - start + len < 0, start is not page-aligned,
+ *		"behavior" is not a valid value, or application
+ *		is attempting to release locked or shared pages.
+ *  -ENOMEM - addresses in the specified range are not currently
+ *		mapped, or are outside the AS of the process.
+ *  -EIO    - an I/O error occurred while paging in data.
+ *  -EBADF  - map exists, but area maps something that isn't a file.
+ *  -EAGAIN - a kernel resource was temporarily unavailable.
+ */
+asmlinkage long sys_madvise(unsigned long start, size_t len, int behavior)
+{
+#ifndef NO_MM
+	unsigned long end;
+	struct vm_area_struct * vma;
+	int unmapped_error = 0;
+	int error = -EINVAL;
+
+	down_write(&current->mm->mmap_sem);
+
+	if (start & ~PAGE_MASK)
+		goto out;
+	len = (len + ~PAGE_MASK) & PAGE_MASK;
+	end = start + len;
+	if (end < start)
+		goto out;
+
+	error = 0;
+	if (end == start)
+		goto out;
+
+	/*
+	 * If the interval [start,end) covers some unmapped address
+	 * ranges, just ignore them, but return -ENOMEM at the end.
+	 */
+	vma = find_vma(current->mm, start);
+	for (;;) {
+		/* Still start < end. */
+		error = -ENOMEM;
+		if (!vma)
+			goto out;
+
+		/* Here start < vma->vm_end. */
+		if (start < vma->vm_start) {
+			unmapped_error = -ENOMEM;
+			start = vma->vm_start;
+		}
+
+		/* Here vma->vm_start <= start < vma->vm_end. */
+		if (end <= vma->vm_end) {
+			if (start < end) {
+				error = madvise_vma(vma, start, end,
+							behavior);
+				if (error)
+					goto out;
+			}
+			error = unmapped_error;
+			goto out;
+		}
+
+		/* Here vma->vm_start <= start < vma->vm_end < end. */
+		error = madvise_vma(vma, start, vma->vm_end, behavior);
+		if (error)
+			goto out;
+		start = vma->vm_end;
+		vma = vma->vm_next;
+	}
+
+out:
+	up_write(&current->mm->mmap_sem);
+	return error;
+#else /* NO_MM */
+	return(-ENOSYS);
+#endif /* NO_MM */
+}
+
+#ifndef NO_MM
+
+/*
+ * Later we can get more picky about what "in core" means precisely.
+ * For now, simply check to see if the page is in the page cache,
+ * and is up to date; i.e. that no page-in operation would be required
+ * at this time if an application were to map and access this page.
+ */
+static unsigned char mincore_page(struct vm_area_struct * vma,
+	unsigned long pgoff)
+{
+	unsigned char present = 0;
+	struct address_space * as = vma->vm_file->f_dentry->d_inode->i_mapping;
+	struct page * page, ** hash = page_hash(as, pgoff);
+
+	spin_lock(&pagecache_lock);
+	page = __find_page_nolock(as, pgoff, *hash);
+	if ((page) && (Page_Uptodate(page)))
+		present = 1;
+	spin_unlock(&pagecache_lock);
+
+	return present;
+}
+
+static long mincore_vma(struct vm_area_struct * vma,
+	unsigned long start, unsigned long end, unsigned char * vec)
+{
+	long error, i, remaining;
+	unsigned char * tmp;
+
+	error = -ENOMEM;
+	if (!vma->vm_file)
+		return error;
+
+	start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+	if (end > vma->vm_end)
+		end = vma->vm_end;
+	end = ((end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+
+	error = -EAGAIN;
+	tmp = (unsigned char *) __get_free_page(GFP_KERNEL);
+	if (!tmp)
+		return error;
+
+	/* (end - start) is # of pages, and also # of bytes in "vec */
+	remaining = (end - start),
+
+	error = 0;
+	for (i = 0; remaining > 0; remaining -= PAGE_SIZE, i++) {
+		int j = 0;
+		long thispiece = (remaining < PAGE_SIZE) ?
+						remaining : PAGE_SIZE;
+
+		while (j < thispiece)
+			tmp[j++] = mincore_page(vma, start++);
+
+		if (copy_to_user(vec + PAGE_SIZE * i, tmp, thispiece)) {
+			error = -EFAULT;
+			break;
+		}
+	}
+
+	free_page((unsigned long) tmp);
+	return error;
+}
+
+#endif /* NO_MM */
+
+/*
+ * The mincore(2) system call.
+ *
+ * mincore() returns the memory residency status of the pages in the
+ * current process's address space specified by [addr, addr + len).
+ * The status is returned in a vector of bytes.  The least significant
+ * bit of each byte is 1 if the referenced page is in memory, otherwise
+ * it is zero.
+ *
+ * Because the status of a page can change after mincore() checks it
+ * but before it returns to the application, the returned vector may
+ * contain stale information.  Only locked pages are guaranteed to
+ * remain in memory.
+ *
+ * return values:
+ *  zero    - success
+ *  -EFAULT - vec points to an illegal address
+ *  -EINVAL - addr is not a multiple of PAGE_CACHE_SIZE,
+ *		or len has a nonpositive value
+ *  -ENOMEM - Addresses in the range [addr, addr + len] are
+ *		invalid for the address space of this process, or
+ *		specify one or more pages which are not currently
+ *		mapped
+ *  -EAGAIN - A kernel resource was temporarily unavailable.
+ */
+asmlinkage long sys_mincore(unsigned long start, size_t len,
+	unsigned char * vec)
+{
+#ifndef NO_MM
+	int index = 0;
+	unsigned long end;
+	struct vm_area_struct * vma;
+	int unmapped_error = 0;
+	long error = -EINVAL;
+
+	down_read(&current->mm->mmap_sem);
+
+	if (start & ~PAGE_CACHE_MASK)
+		goto out;
+	len = (len + ~PAGE_CACHE_MASK) & PAGE_CACHE_MASK;
+	end = start + len;
+	if (end < start)
+		goto out;
+
+	error = 0;
+	if (end == start)
+		goto out;
+
+	/*
+	 * If the interval [start,end) covers some unmapped address
+	 * ranges, just ignore them, but return -ENOMEM at the end.
+	 */
+	vma = find_vma(current->mm, start);
+	for (;;) {
+		/* Still start < end. */
+		error = -ENOMEM;
+		if (!vma)
+			goto out;
+
+		/* Here start < vma->vm_end. */
+		if (start < vma->vm_start) {
+			unmapped_error = -ENOMEM;
+			start = vma->vm_start;
+		}
+
+		/* Here vma->vm_start <= start < vma->vm_end. */
+		if (end <= vma->vm_end) {
+			if (start < end) {
+				error = mincore_vma(vma, start, end,
+							&vec[index]);
+				if (error)
+					goto out;
+			}
+			error = unmapped_error;
+			goto out;
+		}
+
+		/* Here vma->vm_start <= start < vma->vm_end < end. */
+		error = mincore_vma(vma, start, vma->vm_end, &vec[index]);
+		if (error)
+			goto out;
+		index += (vma->vm_end - start) >> PAGE_CACHE_SHIFT;
+		start = vma->vm_end;
+		vma = vma->vm_next;
+	}
+
+out:
+	up_read(&current->mm->mmap_sem);
+	return error;
+#else /* NO_MM */
+	return(-ENOSYS);
+#endif /* NO_MM */
+}
+
+static inline
+struct page *__read_cache_page(struct address_space *mapping,
+				unsigned long index,
+				int (*filler)(void *,struct page*),
+				void *data)
+{
+	struct page **hash = page_hash(mapping, index);
+	struct page *page, *cached_page = NULL;
+	int err;
+repeat:
+	page = __find_get_page(mapping, index, hash);
+	if (!page) {
+		if (!cached_page) {
+			cached_page = page_cache_alloc(mapping);
+			if (!cached_page)
+				return ERR_PTR(-ENOMEM);
+		}
+		page = cached_page;
+		if (add_to_page_cache_unique(page, mapping, index, hash))
+			goto repeat;
+		cached_page = NULL;
+		err = filler(data, page);
+		if (err < 0) {
+			page_cache_release(page);
+			page = ERR_PTR(err);
+		}
+	}
+	if (cached_page)
+		page_cache_release(cached_page);
+	return page;
+}
+
+/*
+ * Read into the page cache. If a page already exists,
+ * and Page_Uptodate() is not set, try to fill the page.
+ */
+struct page *read_cache_page(struct address_space *mapping,
+				unsigned long index,
+				int (*filler)(void *,struct page*),
+				void *data)
+{
+	struct page *page;
+	int err;
+
+retry:
+	page = __read_cache_page(mapping, index, filler, data);
+	if (IS_ERR(page))
+		goto out;
+	mark_page_accessed(page);
+	if (Page_Uptodate(page))
+		goto out;
+
+	lock_page(page);
+	if (!page->mapping) {
+		UnlockPage(page);
+		page_cache_release(page);
+		goto retry;
+	}
+	if (Page_Uptodate(page)) {
+		UnlockPage(page);
+		goto out;
+	}
+	err = filler(data, page);
+	if (err < 0) {
+		page_cache_release(page);
+		page = ERR_PTR(err);
+	}
+ out:
+	return page;
+}
+
+static inline struct page * __grab_cache_page(struct address_space *mapping,
+				unsigned long index, struct page **cached_page)
+{
+	struct page *page, **hash = page_hash(mapping, index);
+repeat:
+	page = __find_lock_page(mapping, index, hash);
+	if (!page) {
+		if (!*cached_page) {
+			*cached_page = page_cache_alloc(mapping);
+			if (!*cached_page)
+				return NULL;
+		}
+		page = *cached_page;
+		if (add_to_page_cache_unique(page, mapping, index, hash))
+			goto repeat;
+		*cached_page = NULL;
+	}
+	return page;
+}
+
+inline void remove_suid(struct inode *inode)
+{
+	unsigned int mode;
+
+	/* set S_IGID if S_IXGRP is set, and always set S_ISUID */
+	mode = (inode->i_mode & S_IXGRP)*(S_ISGID/S_IXGRP) | S_ISUID;
+
+	/* was any of the uid bits set? */
+	mode &= inode->i_mode;
+	if (mode && !capable(CAP_FSETID)) {
+		inode->i_mode &= ~mode;
+		mark_inode_dirty(inode);
+	}
+}
+
+/*
+ * precheck_file_write():
+ * Check the conditions on a file descriptor prior to beginning a write
+ * on it.  Contains the common precheck code for both buffered and direct
+ * IO.
+ */
+int precheck_file_write(struct file *file, struct inode *inode,
+			size_t *count, loff_t *ppos)
+{
+	ssize_t		err;
+	unsigned long	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
+	loff_t		pos = *ppos;
+	
+	err = -EINVAL;
+	if (pos < 0)
+		goto out;
+
+	err = file->f_error;
+	if (err) {
+		file->f_error = 0;
+		goto out;
+	}
+
+	/* FIXME: this is for backwards compatibility with 2.4 */
+	if (!S_ISBLK(inode->i_mode) && (file->f_flags & O_APPEND))
+		*ppos = pos = inode->i_size;
+
+	/*
+	 * Check whether we've reached the file size limit.
+	 */
+	err = -EFBIG;
+	
+	if (!S_ISBLK(inode->i_mode) && limit != RLIM_INFINITY) {
+		if (pos >= limit) {
+			send_sig(SIGXFSZ, current, 0);
+			goto out;
+		}
+		if (pos > 0xFFFFFFFFULL || *count > limit - (u32)pos) {
+			/* send_sig(SIGXFSZ, current, 0); */
+			*count = limit - (u32)pos;
+		}
+	}
+
+	/*
+	 *	LFS rule 
+	 */
+	if ( pos + *count > MAX_NON_LFS && !(file->f_flags&O_LARGEFILE)) {
+		if (pos >= MAX_NON_LFS) {
+			send_sig(SIGXFSZ, current, 0);
+			goto out;
+		}
+		if (*count > MAX_NON_LFS - (u32)pos) {
+			/* send_sig(SIGXFSZ, current, 0); */
+			*count = MAX_NON_LFS - (u32)pos;
+		}
+	}
+
+	/*
+	 *	Are we about to exceed the fs block limit ?
+	 *
+	 *	If we have written data it becomes a short write
+	 *	If we have exceeded without writing data we send
+	 *	a signal and give them an EFBIG.
+	 *
+	 *	Linus frestrict idea will clean these up nicely..
+	 */
+	 
+	if (!S_ISBLK(inode->i_mode)) {
+		if (pos >= inode->i_sb->s_maxbytes)
+		{
+			if (*count || pos > inode->i_sb->s_maxbytes) {
+				send_sig(SIGXFSZ, current, 0);
+				err = -EFBIG;
+				goto out;
+			}
+			/* zero-length writes at ->s_maxbytes are OK */
+		}
+
+		if (pos + *count > inode->i_sb->s_maxbytes)
+			*count = inode->i_sb->s_maxbytes - pos;
+	} else {
+		if (is_read_only(inode->i_rdev)) {
+			err = -EPERM;
+			goto out;
+		}
+		if (pos >= inode->i_size) {
+			if (*count || pos > inode->i_size) {
+				err = -ENOSPC;
+				goto out;
+			}
+		}
+
+		if (pos + *count > inode->i_size)
+			*count = inode->i_size - pos;
+	}
+
+	err = 0;
+out:
+	return err;
+}
+
+/*
+ * Write to a file through the page cache. 
+ *
+ * We currently put everything into the page cache prior to writing it.
+ * This is not a problem when writing full pages. With partial pages,
+ * however, we first have to read the data into the cache, then
+ * dirty the page, and finally schedule it for writing. Alternatively, we
+ * could write-through just the portion of data that would go into that
+ * page, but that would kill performance for applications that write data
+ * line by line, and it's prone to race conditions.
+ *
+ * Note that this routine doesn't try to keep track of dirty pages. Each
+ * file system has to do this all by itself, unfortunately.
+ *							okir@monad.swb.de
+ */
+ssize_t
+do_generic_file_write(struct file *file,const char *buf,size_t count, loff_t *ppos)
+{
+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+	struct inode	*inode = mapping->host;
+	loff_t		pos;
+	struct page	*page, *cached_page;
+	ssize_t		written;
+	long		status = 0;
+	ssize_t		err;
+	unsigned	bytes;
+
+	cached_page = NULL;
+	pos = *ppos;
+	written = 0;
+
+	err = precheck_file_write(file, inode, &count, &pos);
+	if (err != 0 || count == 0)
+		goto out;
+
+	remove_suid(inode);
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	mark_inode_dirty_sync(inode);
+
+	do {
+		unsigned long index, offset;
+		long page_fault;
+		char *kaddr;
+
+		/*
+		 * Try to find the page in the cache. If it isn't there,
+		 * allocate a free page.
+		 */
+		offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
+		index = pos >> PAGE_CACHE_SHIFT;
+		bytes = PAGE_CACHE_SIZE - offset;
+		if (bytes > count)
+			bytes = count;
+
+		/*
+		 * Bring in the user page that we will copy from _first_.
+		 * Otherwise there's a nasty deadlock on copying from the
+		 * same page as we're writing to, without it being marked
+		 * up-to-date.
+		 */
+		{ volatile unsigned char dummy;
+			__get_user(dummy, buf);
+			__get_user(dummy, buf+bytes-1);
+		}
+
+		status = -ENOMEM;	/* we'll assign it later anyway */
+		page = __grab_cache_page(mapping, index, &cached_page);
+		if (!page)
+			break;
+
+		/* We have exclusive IO access to the page.. */
+		if (!PageLocked(page)) {
+			PAGE_BUG(page);
+		}
+
+		kaddr = kmap(page);
+		status = mapping->a_ops->prepare_write(file, page, offset, offset+bytes);
+		if (status)
+			goto sync_failure;
+		page_fault = __copy_from_user(kaddr+offset, buf, bytes);
+		flush_dcache_page(page);
+		status = mapping->a_ops->commit_write(file, page, offset, offset+bytes);
+		if (page_fault)
+			goto fail_write;
+		if (!status)
+			status = bytes;
+
+		if (status >= 0) {
+			written += status;
+			count -= status;
+			pos += status;
+			buf += status;
+		}
+unlock:
+		kunmap(page);
+		/* Mark it unlocked again and drop the page.. */
+		SetPageReferenced(page);
+		UnlockPage(page);
+		page_cache_release(page);
+
+		if (status < 0)
+			break;
+	} while (count);
+done:
+	*ppos = pos;
+
+	if (cached_page)
+		page_cache_release(cached_page);
+
+	/* For now, when the user asks for O_SYNC, we'll actually
+	 * provide O_DSYNC. */
+	if (status >= 0) {
+		if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
+			status = generic_osync_inode(inode, OSYNC_METADATA|OSYNC_DATA);
+	}
+	
+	err = written ? written : status;
+out:
+
+	return err;
+fail_write:
+	status = -EFAULT;
+	goto unlock;
+
+sync_failure:
+	/*
+	 * If blocksize < pagesize, prepare_write() may have instantiated a
+	 * few blocks outside i_size.  Trim these off again.
+	 */
+	kunmap(page);
+	UnlockPage(page);
+	page_cache_release(page);
+	if (pos + bytes > inode->i_size)
+		vmtruncate(inode, inode->i_size);
+	goto done;
+}
+
+ssize_t
+do_generic_direct_write(struct file *file,const char *buf,size_t count, loff_t *ppos)
+{
+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+	struct inode	*inode = mapping->host;
+	loff_t		pos;
+	ssize_t		written;
+	long		status = 0;
+	ssize_t		err;
+
+	pos = *ppos;
+	written = 0;
+
+	err = precheck_file_write(file, inode, &count, &pos);
+	if (err != 0 || count == 0)
+		goto out;
+
+	if (!(file->f_flags & O_DIRECT))
+		BUG();
+
+	remove_suid(inode);
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	mark_inode_dirty_sync(inode);
+
+	written = generic_file_direct_IO(WRITE, file, (char *) buf, count, pos);
+	if (written > 0) {
+		loff_t end = pos + written;
+		if (end > inode->i_size && !S_ISBLK(inode->i_mode)) {
+			inode->i_size = end;
+			mark_inode_dirty(inode);
+		}
+		*ppos = end;
+		invalidate_inode_pages2(mapping);
+	}
+	/*
+	 * Sync the fs metadata but not the minor inode changes and
+	 * of course not the data as we did direct DMA for the IO.
+	 */
+	if (written >= 0 && (file->f_flags & O_SYNC))
+		status = generic_osync_inode(inode, OSYNC_METADATA);
+
+	err = written ? written : status;
+out:
+	return err;
+}
+
+static int do_odirect_fallback(struct file *file, struct inode *inode,
+			       const char *buf, size_t count, loff_t *ppos)
+{
+	ssize_t ret;
+	int err;
+
+	down(&inode->i_sem);
+	ret = do_generic_file_write(file, buf, count, ppos);
+	if (ret > 0) {
+		err = do_fdatasync(file);
+		if (err)
+			ret = err;
+	}
+	up(&inode->i_sem);
+	return ret;
+}
+
+ssize_t
+generic_file_write(struct file *file,const char *buf,size_t count, loff_t *ppos)
+{
+	struct inode	*inode = file->f_dentry->d_inode->i_mapping->host;
+	ssize_t		err;
+
+	if ((ssize_t) count < 0)
+		return -EINVAL;
+
+	if (!access_ok(VERIFY_READ, buf, count))
+		return -EFAULT;
+
+	if (file->f_flags & O_DIRECT) {
+		/* do_generic_direct_write may drop i_sem during the
+		   actual IO */
+		down_read(&inode->i_alloc_sem);
+		down(&inode->i_sem);
+		err = do_generic_direct_write(file, buf, count, ppos);
+		up(&inode->i_sem);
+		up_read(&inode->i_alloc_sem);
+		if (unlikely(err == -ENOTBLK))
+			err = do_odirect_fallback(file, inode, buf, count, ppos);
+	} else {
+		down(&inode->i_sem);
+		err = do_generic_file_write(file, buf, count, ppos);
+		up(&inode->i_sem);
+	}
+
+	return err;
+}
+
+void __init page_cache_init(unsigned long mempages)
+{
+	unsigned long htable_size, order;
+
+	htable_size = mempages;
+	htable_size *= sizeof(struct page *);
+	for(order = 0; (PAGE_SIZE << order) < htable_size; order++)
+		;
+
+	do {
+		unsigned long tmp = (PAGE_SIZE << order) / sizeof(struct page *);
+
+		page_hash_bits = 0;
+		while((tmp >>= 1UL) != 0UL)
+			page_hash_bits++;
+
+		page_hash_table = (struct page **)
+			__get_free_pages(GFP_ATOMIC, order);
+	} while(page_hash_table == NULL && --order > 0);
+
+	printk("Page-cache hash table entries: %d (order: %lu, %lu bytes)\n",
+	       (1 << page_hash_bits), order, (PAGE_SIZE << order));
+	if (!page_hash_table)
+		panic("Failed to allocate page hash table\n");
+	memset((void *)page_hash_table, 0, PAGE_HASH_SIZE * sizeof(struct page *));
+}
diff -urN linux-2.4.29/mmnommu/Makefile linux-2.4.29-uc1/mmnommu/Makefile
--- linux-2.4.29/mmnommu/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/Makefile	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,24 @@
+#
+# Makefile for the linux memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET := mmnommu.o
+obj-y	 := bootmem.o filemap.o mlock.o mmap.o \
+			mprotect.o mremap.o numa.o \
+			slab.o swapfile.o vmalloc.o vmscan.o memory.o \
+			swap.o oom_kill.o
+
+ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
+obj-y    += page_alloc2.o
+else
+obj-y    += page_alloc.o
+endif
+
+export-objs := filemap.o memory.o page_alloc.o page_alloc2.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/mmnommu/memory.c linux-2.4.29-uc1/mmnommu/memory.c
--- linux-2.4.29/mmnommu/memory.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/memory.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,182 @@
+/*
+ *  linux/mmnommu/memory.c
+ *
+ *  Copyright (c) 2000-2002 SnapGear Inc., David McCullough <davidm@snapgear.com>
+ *  Copyright (c) 2000 Lineo,Inc. David McCullough <davidm@lineo.com>
+ */
+
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/iobuf.h>
+#include <linux/pagemap.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+#include <asm/tlb.h>
+
+void *high_memory;
+mem_map_t * mem_map = NULL;
+unsigned long max_mapnr;
+unsigned long num_physpages;
+unsigned long num_mappedpages;
+unsigned long askedalloc, realalloc;
+
+/*
+ * Force in an entire range of pages from the current process's user VA,
+ * and pin them in physical memory.  
+ */
+
+int map_user_kiobuf(int rw, struct kiobuf *iobuf, unsigned long va, size_t len)
+{
+	return(0);
+}
+
+/*
+ * Mark all of the pages in a kiobuf as dirty 
+ *
+ * We need to be able to deal with short reads from disk: if an IO error
+ * occurs, the number of bytes read into memory may be less than the
+ * size of the kiobuf, so we have to stop marking pages dirty once the
+ * requested byte count has been reached.
+ *
+ * Must be called from process context - set_page_dirty() takes VFS locks.
+ */
+
+void mark_dirty_kiobuf(struct kiobuf *iobuf, int bytes)
+{
+	int index, offset, remaining;
+	struct page *page;
+	
+	index = iobuf->offset >> PAGE_SHIFT;
+	offset = iobuf->offset & ~PAGE_MASK;
+	remaining = bytes;
+	if (remaining > iobuf->length)
+		remaining = iobuf->length;
+	
+	while (remaining > 0 && index < iobuf->nr_pages) {
+		page = iobuf->maplist[index];
+		
+		if (!PageReserved(page))
+			set_page_dirty(page);
+
+		remaining -= (PAGE_SIZE - offset);
+		offset = 0;
+		index++;
+	}
+}
+
+/*
+ * Unmap all of the pages referenced by a kiobuf.  We release the pages,
+ * and unlock them if they were locked. 
+ */
+
+void unmap_kiobuf (struct kiobuf *iobuf) 
+{
+}
+
+
+/*
+ * Lock down all of the pages of a kiovec for IO.
+ *
+ * If any page is mapped twice in the kiovec, we return the error -EINVAL.
+ *
+ * The optional wait parameter causes the lock call to block until all
+ * pages can be locked if set.  If wait==0, the lock operation is
+ * aborted if any locked pages are found and -EAGAIN is returned.
+ */
+
+int lock_kiovec(int nr, struct kiobuf *iovec[], int wait)
+{
+	return 0;
+}
+
+/*
+ * Unlock all of the pages of a kiovec after IO.
+ */
+
+int unlock_kiovec(int nr, struct kiobuf *iovec[])
+{
+	return 0;
+}
+
+/*
+ * Handle all mappings that got truncated by a "truncate()"
+ * system call.
+ *
+ * NOTE! We have to be ready to update the memory sharing
+ * between the file and the memory map for a potential last
+ * incomplete page.  Ugly, but necessary.
+ */
+int vmtruncate(struct inode * inode, loff_t offset)
+{
+	struct address_space *mapping = inode->i_mapping;
+	unsigned long limit;
+
+	if (inode->i_size < offset)
+		goto do_expand;
+	inode->i_size = offset;
+
+	truncate_inode_pages(mapping, offset);
+	goto out_truncate;
+
+do_expand:
+	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
+	if (limit != RLIM_INFINITY && offset > limit)
+		goto out_sig;
+	if (offset > inode->i_sb->s_maxbytes)
+		goto out;
+	inode->i_size = offset;
+
+out_truncate:
+	if (inode->i_op && inode->i_op->truncate) {
+		lock_kernel();
+		inode->i_op->truncate(inode);
+		unlock_kernel();
+	}
+	return 0;
+out_sig:
+	send_sig(SIGXFSZ, current, 0);
+out:
+	return -EFBIG;
+}
+
+
+/*  Note: this is only safe if the mm semaphore is held when called. */
+int remap_page_range(unsigned long from, unsigned long phys_addr, unsigned long size, pgprot_t prot)
+{
+	return -EPERM;
+}
+
+
+/*
+ *	The nommu dodgy version :-)
+ */
+
+int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+		unsigned long start, int len, int write, int force,
+		struct page **pages, struct vm_area_struct **vmas)
+{
+	int i;
+	static struct vm_area_struct dummy_vma;
+
+	for (i = 0; i < len; i++) {
+		if (pages) {
+			pages[i] = virt_to_page(start);
+			if (pages[i])
+				page_cache_get(pages[i]);
+		}
+		if (vmas)
+			vmas[i] = &dummy_vma;
+		start += PAGE_SIZE;
+	}
+	return(i);
+}
+
+EXPORT_SYMBOL(get_user_pages);
+
+struct page * vmalloc_to_page(void * vmalloc_addr)
+{
+	return(virt_to_page(vmalloc_addr));
+}
diff -urN linux-2.4.29/mmnommu/mlock.c linux-2.4.29-uc1/mmnommu/mlock.c
--- linux-2.4.29/mmnommu/mlock.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/mlock.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ *	linux/mm/mlock.c
+ *
+ *  Copyright (c) 2001 Lineo, Inc. David McCullough <davidm@lineo.com>
+ *  Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org> ref uClinux 2.0
+ *  (C) Copyright 1995 Linus Torvalds
+ */
+#include <linux/slab.h>
+#include <linux/shm.h>
+#include <linux/mman.h>
+#include <linux/smp_lock.h>
+#include <linux/pagemap.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+asmlinkage long sys_mlock(unsigned long start, size_t len)
+{
+	return -ENOSYS;
+}
+
+asmlinkage long sys_munlock(unsigned long start, size_t len)
+{
+	return -ENOSYS;
+}
+
+asmlinkage long sys_mlockall(int flags)
+{
+	return -ENOSYS;
+}
+
+asmlinkage long sys_munlockall(void)
+{
+	return -ENOSYS;
+}
diff -urN linux-2.4.29/mmnommu/mmap.c linux-2.4.29-uc1/mmnommu/mmap.c
--- linux-2.4.29/mmnommu/mmap.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/mmap.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,1606 @@
+/*
+ *	linux/mm/mmap.c
+ *
+ * Written by obz.
+ *
+ * NO_MM
+ *  Copyright (c) 2001 Lineo, Inc. David McCullough <davidm@lineo.com>
+ *  Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org> ref uClinux 2.0
+ */
+#include <linux/slab.h>
+#include <linux/shm.h>
+#include <linux/mman.h>
+#include <linux/pagemap.h>
+#include <linux/swap.h>
+#include <linux/swapctl.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/personality.h>
+#include <linux/mount.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+
+#ifndef NO_MM
+/*
+ * WARNING: the debugging will use recursive algorithms so never enable this
+ * unless you know what you are doing.
+ */
+#undef DEBUG_MM_RB
+
+/* description of effects of mapping type and prot in current implementation.
+ * this is due to the limited x86 page protection hardware.  The expected
+ * behavior is in parens:
+ *
+ * map_type	prot
+ *		PROT_NONE	PROT_READ	PROT_WRITE	PROT_EXEC
+ * MAP_SHARED	r: (no) no	r: (yes) yes	r: (no) yes	r: (no) yes
+ *		w: (no) no	w: (no) no	w: (yes) yes	w: (no) no
+ *		x: (no) no	x: (no) yes	x: (no) yes	x: (yes) yes
+ *		
+ * MAP_PRIVATE	r: (no) no	r: (yes) yes	r: (no) yes	r: (no) yes
+ *		w: (no) no	w: (no) no	w: (copy) copy	w: (no) no
+ *		x: (no) no	x: (no) yes	x: (no) yes	x: (yes) yes
+ *
+ */
+pgprot_t protection_map[16] = {
+	__P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
+	__S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
+};
+
+int sysctl_overcommit_memory;
+int max_map_count = DEFAULT_MAX_MAP_COUNT;
+
+/* Check that a process has enough memory to allocate a
+ * new virtual mapping.
+ */
+int vm_enough_memory(long pages)
+{
+	/* Stupid algorithm to decide if we have enough memory: while
+	 * simple, it hopefully works in most obvious cases.. Easy to
+	 * fool it, but this should catch most mistakes.
+	 */
+	/* 23/11/98 NJC: Somewhat less stupid version of algorithm,
+	 * which tries to do "TheRightThing".  Instead of using half of
+	 * (buffers+cache), use the minimum values.  Allow an extra 2%
+	 * of num_physpages for safety margin.
+	 */
+
+	unsigned long free;
+	
+        /* Sometimes we want to use more memory than we have. */
+	if (sysctl_overcommit_memory)
+	    return 1;
+
+	/* The page cache contains buffer pages these days.. */
+	free = page_cache_size;
+	free += nr_free_pages();
+	free += nr_swap_pages;
+
+	/*
+	 * This double-counts: the nrpages are both in the page-cache
+	 * and in the swapper space. At the same time, this compensates
+	 * for the swap-space over-allocation (ie "nr_swap_pages" being
+	 * too small.
+	 */
+	free += swapper_space.nrpages;
+
+	/*
+	 * The code below doesn't account for free space in the inode
+	 * and dentry slab cache, slab cache fragmentation, inodes and
+	 * dentries which will become freeable under VM load, etc.
+	 * Lets just hope all these (complex) factors balance out...
+	 */
+	free += (dentry_stat.nr_unused * sizeof(struct dentry)) >> PAGE_SHIFT;
+	free += (inodes_stat.nr_unused * sizeof(struct inode)) >> PAGE_SHIFT;
+
+	return free > pages;
+}
+
+/* Remove one vm structure from the inode's i_mapping address space. */
+static inline void __remove_shared_vm_struct(struct vm_area_struct *vma)
+{
+	struct file * file = vma->vm_file;
+
+	if (file) {
+		struct inode *inode = file->f_dentry->d_inode;
+		if (vma->vm_flags & VM_DENYWRITE)
+			atomic_inc(&inode->i_writecount);
+		if(vma->vm_next_share)
+			vma->vm_next_share->vm_pprev_share = vma->vm_pprev_share;
+		*vma->vm_pprev_share = vma->vm_next_share;
+	}
+}
+
+static inline void remove_shared_vm_struct(struct vm_area_struct *vma)
+{
+	lock_vma_mappings(vma);
+	__remove_shared_vm_struct(vma);
+	unlock_vma_mappings(vma);
+}
+
+void lock_vma_mappings(struct vm_area_struct *vma)
+{
+	struct address_space *mapping;
+
+	mapping = NULL;
+	if (vma->vm_file)
+		mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
+	if (mapping)
+		spin_lock(&mapping->i_shared_lock);
+}
+
+void unlock_vma_mappings(struct vm_area_struct *vma)
+{
+	struct address_space *mapping;
+
+	mapping = NULL;
+	if (vma->vm_file)
+		mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
+	if (mapping)
+		spin_unlock(&mapping->i_shared_lock);
+}
+
+#endif /* NO_MM */
+
+/*
+ *  sys_brk() for the most part doesn't need the global kernel
+ *  lock, except when an application is doing something nasty
+ *  like trying to un-brk an area that has already been mapped
+ *  to a regular file.  in this case, the unmapping will need
+ *  to invoke file system routines that need the global lock.
+ */
+asmlinkage unsigned long sys_brk(unsigned long brk)
+{
+#ifndef NO_MM
+	unsigned long rlim, retval;
+	unsigned long newbrk, oldbrk;
+	struct mm_struct *mm = current->mm;
+
+	down_write(&mm->mmap_sem);
+
+	if (brk < mm->end_code)
+		goto out;
+	newbrk = PAGE_ALIGN(brk);
+	oldbrk = PAGE_ALIGN(mm->brk);
+	if (oldbrk == newbrk)
+		goto set_brk;
+
+	/* Always allow shrinking brk. */
+	if (brk <= mm->brk) {
+		if (!do_munmap(mm, newbrk, oldbrk-newbrk))
+			goto set_brk;
+		goto out;
+	}
+
+	/* Check against rlimit.. */
+	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+	if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
+		goto out;
+
+	/* Check against existing mmap mappings. */
+	if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE))
+		goto out;
+
+	/* Check if we have enough memory.. */
+	if (!vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT))
+		goto out;
+
+	/* Ok, looks good - let it rip. */
+	if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk)
+		goto out;
+set_brk:
+	mm->brk = brk;
+out:
+	retval = mm->brk;
+	up_write(&mm->mmap_sem);
+	return retval;
+#else
+	struct mm_struct *mm = current->mm;
+
+	if (brk < mm->end_code || brk < mm->start_brk || brk > mm->end_brk)
+		return mm->brk;
+
+	if (mm->brk == brk)
+		return mm->brk;
+
+	/*
+	 * Always allow shrinking brk
+	 */
+	if (brk <= mm->brk) {
+		mm->brk = brk;
+		return brk;
+	}
+
+	/*
+	 * Ok, looks good - let it rip.
+	 */
+	return mm->brk = brk;
+#endif
+}
+
+
+/* Combine the mmap "prot" and "flags" argument into one "vm_flags" used
+ * internally. Essentially, translate the "PROT_xxx" and "MAP_xxx" bits
+ * into "VM_xxx".
+ */
+static inline unsigned long calc_vm_flags(unsigned long prot, unsigned long flags)
+{
+#define _trans(x,bit1,bit2) \
+((bit1==bit2)?(x&bit1):(x&bit1)?bit2:0)
+
+	unsigned long prot_bits, flag_bits;
+	prot_bits =
+		_trans(prot, PROT_READ, VM_READ) |
+		_trans(prot, PROT_WRITE, VM_WRITE) |
+		_trans(prot, PROT_EXEC, VM_EXEC);
+	flag_bits =
+		_trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN) |
+		_trans(flags, MAP_DENYWRITE, VM_DENYWRITE) |
+		_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE);
+	return prot_bits | flag_bits;
+#undef _trans
+}
+
+#ifndef NO_MM
+
+#ifdef DEBUG_MM_RB
+static int browse_rb(rb_node_t * rb_node) {
+	int i = 0;
+	if (rb_node) {
+		i++;
+		i += browse_rb(rb_node->rb_left);
+		i += browse_rb(rb_node->rb_right);
+	}
+	return i;
+}
+
+static void validate_mm(struct mm_struct * mm) {
+	int bug = 0;
+	int i = 0;
+	struct vm_area_struct * tmp = mm->mmap;
+	while (tmp) {
+		tmp = tmp->vm_next;
+		i++;
+	}
+	if (i != mm->map_count)
+		printk("map_count %d vm_next %d\n", mm->map_count, i), bug = 1;
+	i = browse_rb(mm->mm_rb.rb_node);
+	if (i != mm->map_count)
+		printk("map_count %d rb %d\n", mm->map_count, i), bug = 1;
+	if (bug)
+		BUG();
+}
+#else
+#define validate_mm(mm) do { } while (0)
+#endif
+
+static struct vm_area_struct * find_vma_prepare(struct mm_struct * mm, unsigned long addr,
+						struct vm_area_struct ** pprev,
+						rb_node_t *** rb_link, rb_node_t ** rb_parent)
+{
+	struct vm_area_struct * vma;
+	rb_node_t ** __rb_link, * __rb_parent, * rb_prev;
+
+	__rb_link = &mm->mm_rb.rb_node;
+	rb_prev = __rb_parent = NULL;
+	vma = NULL;
+
+	while (*__rb_link) {
+		struct vm_area_struct *vma_tmp;
+
+		__rb_parent = *__rb_link;
+		vma_tmp = rb_entry(__rb_parent, struct vm_area_struct, vm_rb);
+
+		if (vma_tmp->vm_end > addr) {
+			vma = vma_tmp;
+			if (vma_tmp->vm_start <= addr)
+				return vma;
+			__rb_link = &__rb_parent->rb_left;
+		} else {
+			rb_prev = __rb_parent;
+			__rb_link = &__rb_parent->rb_right;
+		}
+	}
+
+	*pprev = NULL;
+	if (rb_prev)
+		*pprev = rb_entry(rb_prev, struct vm_area_struct, vm_rb);
+	*rb_link = __rb_link;
+	*rb_parent = __rb_parent;
+	return vma;
+}
+
+static inline void __vma_link_list(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct * prev,
+				   rb_node_t * rb_parent)
+{
+	if (prev) {
+		vma->vm_next = prev->vm_next;
+		prev->vm_next = vma;
+	} else {
+		mm->mmap = vma;
+		if (rb_parent)
+			vma->vm_next = rb_entry(rb_parent, struct vm_area_struct, vm_rb);
+		else
+			vma->vm_next = NULL;
+	}
+}
+
+static inline void __vma_link_rb(struct mm_struct * mm, struct vm_area_struct * vma,
+				 rb_node_t ** rb_link, rb_node_t * rb_parent)
+{
+	rb_link_node(&vma->vm_rb, rb_parent, rb_link);
+	rb_insert_color(&vma->vm_rb, &mm->mm_rb);
+}
+
+static inline void __vma_link_file(struct vm_area_struct * vma)
+{
+	struct file * file;
+
+	file = vma->vm_file;
+	if (file) {
+		struct inode * inode = file->f_dentry->d_inode;
+		struct address_space *mapping = inode->i_mapping;
+		struct vm_area_struct **head;
+
+		if (vma->vm_flags & VM_DENYWRITE)
+			atomic_dec(&inode->i_writecount);
+
+		head = &mapping->i_mmap;
+		if (vma->vm_flags & VM_SHARED)
+			head = &mapping->i_mmap_shared;
+      
+		/* insert vma into inode's share list */
+		if((vma->vm_next_share = *head) != NULL)
+			(*head)->vm_pprev_share = &vma->vm_next_share;
+		*head = vma;
+		vma->vm_pprev_share = head;
+	}
+}
+
+static void __vma_link(struct mm_struct * mm, struct vm_area_struct * vma,  struct vm_area_struct * prev,
+		       rb_node_t ** rb_link, rb_node_t * rb_parent)
+{
+	__vma_link_list(mm, vma, prev, rb_parent);
+	__vma_link_rb(mm, vma, rb_link, rb_parent);
+	__vma_link_file(vma);
+}
+
+static inline void vma_link(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct * prev,
+			    rb_node_t ** rb_link, rb_node_t * rb_parent)
+{
+	lock_vma_mappings(vma);
+	spin_lock(&mm->page_table_lock);
+	__vma_link(mm, vma, prev, rb_link, rb_parent);
+	spin_unlock(&mm->page_table_lock);
+	unlock_vma_mappings(vma);
+
+	mm->map_count++;
+	validate_mm(mm);
+}
+
+static int vma_merge(struct mm_struct * mm, struct vm_area_struct * prev,
+		     rb_node_t * rb_parent, unsigned long addr, unsigned long end, unsigned long vm_flags)
+{
+	spinlock_t * lock = &mm->page_table_lock;
+	if (!prev) {
+		prev = rb_entry(rb_parent, struct vm_area_struct, vm_rb);
+		goto merge_next;
+	}
+	if (prev->vm_end == addr && can_vma_merge(prev, vm_flags)) {
+		struct vm_area_struct * next;
+
+		spin_lock(lock);
+		prev->vm_end = end;
+		next = prev->vm_next;
+		if (next && prev->vm_end == next->vm_start && can_vma_merge(next, vm_flags)) {
+			prev->vm_end = next->vm_end;
+			__vma_unlink(mm, next, prev);
+			spin_unlock(lock);
+
+			mm->map_count--;
+			kmem_cache_free(vm_area_cachep, next);
+			return 1;
+		}
+		spin_unlock(lock);
+		return 1;
+	}
+
+	prev = prev->vm_next;
+	if (prev) {
+ merge_next:
+		if (!can_vma_merge(prev, vm_flags))
+			return 0;
+		if (end == prev->vm_start) {
+			spin_lock(lock);
+			prev->vm_start = addr;
+			spin_unlock(lock);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags, unsigned long pgoff)
+{
+	struct mm_struct * mm = current->mm;
+	struct vm_area_struct * vma, * prev;
+	unsigned int vm_flags;
+	int correct_wcount = 0;
+	int error;
+	rb_node_t ** rb_link, * rb_parent;
+
+	if (file) {
+		if (!file->f_op || !file->f_op->mmap)
+			return -ENODEV;
+
+		if ((prot & PROT_EXEC) && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC))
+			return -EPERM;
+	}
+
+	if (!len)
+		return addr;
+
+	len = PAGE_ALIGN(len);
+
+	if (len > TASK_SIZE || len == 0)
+		return -EINVAL;
+
+	/* offset overflow? */
+	if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
+		return -EINVAL;
+
+	/* Too many mappings? */
+	if (mm->map_count > max_map_count)
+		return -ENOMEM;
+
+	/* Obtain the address to map to. we verify (or select) it and ensure
+	 * that it represents a valid section of the address space.
+	 */
+	addr = get_unmapped_area(file, addr, len, pgoff, flags);
+	if (addr & ~PAGE_MASK)
+		return addr;
+
+	/* Do simple checking here so the lower-level routines won't have
+	 * to. we assume access permissions have been handled by the open
+	 * of the memory object, so we don't do any here.
+	 */
+	vm_flags = calc_vm_flags(prot,flags) | mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
+
+	/* mlock MCL_FUTURE? */
+	if (vm_flags & VM_LOCKED) {
+		unsigned long locked = mm->locked_vm << PAGE_SHIFT;
+		locked += len;
+		if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
+			return -EAGAIN;
+	}
+
+	if (file) {
+		switch (flags & MAP_TYPE) {
+		case MAP_SHARED:
+			if ((prot & PROT_WRITE) && !(file->f_mode & FMODE_WRITE))
+				return -EACCES;
+
+			/* Make sure we don't allow writing to an append-only file.. */
+			if (IS_APPEND(file->f_dentry->d_inode) && (file->f_mode & FMODE_WRITE))
+				return -EACCES;
+
+			/* make sure there are no mandatory locks on the file. */
+			if (locks_verify_locked(file->f_dentry->d_inode))
+				return -EAGAIN;
+
+			vm_flags |= VM_SHARED | VM_MAYSHARE;
+			if (!(file->f_mode & FMODE_WRITE))
+				vm_flags &= ~(VM_MAYWRITE | VM_SHARED);
+
+			/* fall through */
+		case MAP_PRIVATE:
+			if (!(file->f_mode & FMODE_READ))
+				return -EACCES;
+			break;
+
+		default:
+			return -EINVAL;
+		}
+	} else {
+		vm_flags |= VM_SHARED | VM_MAYSHARE;
+		switch (flags & MAP_TYPE) {
+		default:
+			return -EINVAL;
+		case MAP_PRIVATE:
+			vm_flags &= ~(VM_SHARED | VM_MAYSHARE);
+			/* fall through */
+		case MAP_SHARED:
+			break;
+		}
+	}
+
+	/* Clear old maps */
+munmap_back:
+	vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
+	if (vma && vma->vm_start < addr + len) {
+		if (do_munmap(mm, addr, len))
+			return -ENOMEM;
+		goto munmap_back;
+	}
+
+	/* Check against address space limit. */
+	if ((mm->total_vm << PAGE_SHIFT) + len
+	    > current->rlim[RLIMIT_AS].rlim_cur)
+		return -ENOMEM;
+
+	/* Private writable mapping? Check memory availability.. */
+	if ((vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE &&
+	    !(flags & MAP_NORESERVE)				 &&
+	    !vm_enough_memory(len >> PAGE_SHIFT))
+		return -ENOMEM;
+
+	/* Can we just expand an old anonymous mapping? */
+	if (!file && !(vm_flags & VM_SHARED) && rb_parent)
+		if (vma_merge(mm, prev, rb_parent, addr, addr + len, vm_flags))
+			goto out;
+
+	/* Determine the object being mapped and call the appropriate
+	 * specific mapper. the address has already been validated, but
+	 * not unmapped, but the maps are removed from the list.
+	 */
+	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+	if (!vma)
+		return -ENOMEM;
+
+	vma->vm_mm = mm;
+	vma->vm_start = addr;
+	vma->vm_end = addr + len;
+	vma->vm_flags = vm_flags;
+	vma->vm_page_prot = protection_map[vm_flags & 0x0f];
+	vma->vm_ops = NULL;
+	vma->vm_pgoff = pgoff;
+	vma->vm_file = NULL;
+	vma->vm_private_data = NULL;
+	vma->vm_raend = 0;
+
+	if (file) {
+		error = -EINVAL;
+		if (vm_flags & (VM_GROWSDOWN|VM_GROWSUP))
+			goto free_vma;
+		if (vm_flags & VM_DENYWRITE) {
+			error = deny_write_access(file);
+			if (error)
+				goto free_vma;
+			correct_wcount = 1;
+		}
+		vma->vm_file = file;
+		get_file(file);
+		error = file->f_op->mmap(file, vma);
+		if (error)
+			goto unmap_and_free_vma;
+	} else if (flags & MAP_SHARED) {
+		error = shmem_zero_setup(vma);
+		if (error)
+			goto free_vma;
+	}
+
+	/* Can addr have changed??
+	 *
+	 * Answer: Yes, several device drivers can do it in their
+	 *         f_op->mmap method. -DaveM
+	 */
+	if (addr != vma->vm_start) {
+		/*
+		 * It is a bit too late to pretend changing the virtual
+		 * area of the mapping, we just corrupted userspace
+		 * in the do_munmap, so FIXME (not in 2.4 to avoid breaking
+		 * the driver API).
+		 */
+		struct vm_area_struct * stale_vma;
+		/* Since addr changed, we rely on the mmap op to prevent 
+		 * collisions with existing vmas and just use find_vma_prepare 
+		 * to update the tree pointers.
+		 */
+		addr = vma->vm_start;
+		stale_vma = find_vma_prepare(mm, addr, &prev,
+						&rb_link, &rb_parent);
+		/*
+		 * Make sure the lowlevel driver did its job right.
+		 */
+		if (unlikely(stale_vma && stale_vma->vm_start < vma->vm_end)) {
+			printk(KERN_ERR "buggy mmap operation: [<%p>]\n",
+				file ? file->f_op->mmap : NULL);
+			BUG();
+		}
+	}
+
+	vma_link(mm, vma, prev, rb_link, rb_parent);
+	if (correct_wcount)
+		atomic_inc(&file->f_dentry->d_inode->i_writecount);
+
+out:	
+	mm->total_vm += len >> PAGE_SHIFT;
+	if (vm_flags & VM_LOCKED) {
+		mm->locked_vm += len >> PAGE_SHIFT;
+		make_pages_present(addr, addr + len);
+	}
+	return addr;
+
+unmap_and_free_vma:
+	if (correct_wcount)
+		atomic_inc(&file->f_dentry->d_inode->i_writecount);
+	vma->vm_file = NULL;
+	fput(file);
+
+	/* Undo any partial mapping done by a device driver. */
+	zap_page_range(mm, vma->vm_start, vma->vm_end - vma->vm_start);
+free_vma:
+	kmem_cache_free(vm_area_cachep, vma);
+	return error;
+}
+
+/* Get an address range which is currently unmapped.
+ * For shmat() with addr=0.
+ *
+ * Ugly calling convention alert:
+ * Return value with the low bits set means error value,
+ * ie
+ *	if (ret & ~PAGE_MASK)
+ *		error = ret;
+ *
+ * This function "knows" that -ENOMEM has the bits set.
+ */
+#ifndef HAVE_ARCH_UNMAPPED_AREA
+static inline unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	struct vm_area_struct *vma;
+
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+
+	if (addr) {
+		addr = PAGE_ALIGN(addr);
+		vma = find_vma(current->mm, addr);
+		if (TASK_SIZE - len >= addr &&
+		    (!vma || addr + len <= vma->vm_start))
+			return addr;
+	}
+	addr = PAGE_ALIGN(TASK_UNMAPPED_BASE);
+
+	for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
+		/* At this point:  (!vma || addr < vma->vm_end). */
+		if (TASK_SIZE - len < addr)
+			return -ENOMEM;
+		if (!vma || addr + len <= vma->vm_start)
+			return addr;
+		addr = vma->vm_end;
+	}
+}
+#else
+extern unsigned long arch_get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+#endif	
+
+unsigned long get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	if (flags & MAP_FIXED) {
+		if (addr > TASK_SIZE - len || addr >= TASK_SIZE)
+			return -ENOMEM;
+		if (addr & ~PAGE_MASK)
+			return -EINVAL;
+		return addr;
+	}
+
+	if (file && file->f_op && file->f_op->get_unmapped_area)
+		return file->f_op->get_unmapped_area(file, addr, len, pgoff, flags);
+
+	return arch_get_unmapped_area(file, addr, len, pgoff, flags);
+}
+
+/* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
+struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr)
+{
+	struct vm_area_struct *vma = NULL;
+
+	if (mm) {
+		/* Check the cache first. */
+		/* (Cache hit rate is typically around 35%.) */
+		vma = mm->mmap_cache;
+		if (!(vma && vma->vm_end > addr && vma->vm_start <= addr)) {
+			rb_node_t * rb_node;
+
+			rb_node = mm->mm_rb.rb_node;
+			vma = NULL;
+
+			while (rb_node) {
+				struct vm_area_struct * vma_tmp;
+
+				vma_tmp = rb_entry(rb_node, struct vm_area_struct, vm_rb);
+
+				if (vma_tmp->vm_end > addr) {
+					vma = vma_tmp;
+					if (vma_tmp->vm_start <= addr)
+						break;
+					rb_node = rb_node->rb_left;
+				} else
+					rb_node = rb_node->rb_right;
+			}
+			if (vma)
+				mm->mmap_cache = vma;
+		}
+	}
+	return vma;
+}
+
+/* Same as find_vma, but also return a pointer to the previous VMA in *pprev. */
+struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
+				      struct vm_area_struct **pprev)
+{
+	if (mm) {
+		/* Go through the RB tree quickly. */
+		struct vm_area_struct * vma;
+		rb_node_t * rb_node, * rb_last_right, * rb_prev;
+		
+		rb_node = mm->mm_rb.rb_node;
+		rb_last_right = rb_prev = NULL;
+		vma = NULL;
+
+		while (rb_node) {
+			struct vm_area_struct * vma_tmp;
+
+			vma_tmp = rb_entry(rb_node, struct vm_area_struct, vm_rb);
+
+			if (vma_tmp->vm_end > addr) {
+				vma = vma_tmp;
+				rb_prev = rb_last_right;
+				if (vma_tmp->vm_start <= addr)
+					break;
+				rb_node = rb_node->rb_left;
+			} else {
+				rb_last_right = rb_node;
+				rb_node = rb_node->rb_right;
+			}
+		}
+		if (vma) {
+			if (vma->vm_rb.rb_left) {
+				rb_prev = vma->vm_rb.rb_left;
+				while (rb_prev->rb_right)
+					rb_prev = rb_prev->rb_right;
+			}
+			*pprev = NULL;
+			if (rb_prev)
+				*pprev = rb_entry(rb_prev, struct vm_area_struct, vm_rb);
+			if ((rb_prev ? (*pprev)->vm_next : mm->mmap) != vma)
+				BUG();
+			return vma;
+		}
+	}
+	*pprev = NULL;
+	return NULL;
+}
+
+struct vm_area_struct * find_extend_vma(struct mm_struct * mm, unsigned long addr)
+{
+	struct vm_area_struct * vma;
+	unsigned long start;
+
+	addr &= PAGE_MASK;
+	vma = find_vma(mm,addr);
+	if (!vma)
+		return NULL;
+	if (vma->vm_start <= addr)
+		return vma;
+	if (!(vma->vm_flags & VM_GROWSDOWN))
+		return NULL;
+	start = vma->vm_start;
+	if (expand_stack(vma, addr))
+		return NULL;
+	if (vma->vm_flags & VM_LOCKED) {
+		make_pages_present(addr, start);
+	}
+	return vma;
+}
+
+/* Normal function to fix up a mapping
+ * This function is the default for when an area has no specific
+ * function.  This may be used as part of a more specific routine.
+ * This function works out what part of an area is affected and
+ * adjusts the mapping information.  Since the actual page
+ * manipulation is done in do_mmap(), none need be done here,
+ * though it would probably be more appropriate.
+ *
+ * By the time this function is called, the area struct has been
+ * removed from the process mapping list, so it needs to be
+ * reinserted if necessary.
+ *
+ * The 4 main cases are:
+ *    Unmapping the whole area
+ *    Unmapping from the start of the segment to a point in it
+ *    Unmapping from an intermediate point to the end
+ *    Unmapping between to intermediate points, making a hole.
+ *
+ * Case 4 involves the creation of 2 new areas, for each side of
+ * the hole.  If possible, we reuse the existing area rather than
+ * allocate a new one, and the return indicates whether the old
+ * area was reused.
+ */
+static struct vm_area_struct * unmap_fixup(struct mm_struct *mm, 
+	struct vm_area_struct *area, unsigned long addr, size_t len, 
+	struct vm_area_struct *extra)
+{
+	struct vm_area_struct *mpnt;
+	unsigned long end = addr + len;
+
+	area->vm_mm->total_vm -= len >> PAGE_SHIFT;
+	if (area->vm_flags & VM_LOCKED)
+		area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
+
+	/* Unmapping the whole area. */
+	if (addr == area->vm_start && end == area->vm_end) {
+		if (area->vm_ops && area->vm_ops->close)
+			area->vm_ops->close(area);
+		if (area->vm_file)
+			fput(area->vm_file);
+		kmem_cache_free(vm_area_cachep, area);
+		return extra;
+	}
+
+	/* Work out to one of the ends. */
+	if (end == area->vm_end) {
+		/*
+		 * here area isn't visible to the semaphore-less readers
+		 * so we don't need to update it under the spinlock.
+		 */
+		area->vm_end = addr;
+		lock_vma_mappings(area);
+		spin_lock(&mm->page_table_lock);
+	} else if (addr == area->vm_start) {
+		area->vm_pgoff += (end - area->vm_start) >> PAGE_SHIFT;
+		/* same locking considerations of the above case */
+		area->vm_start = end;
+		lock_vma_mappings(area);
+		spin_lock(&mm->page_table_lock);
+	} else {
+	/* Unmapping a hole: area->vm_start < addr <= end < area->vm_end */
+		/* Add end mapping -- leave beginning for below */
+		mpnt = extra;
+		extra = NULL;
+
+		mpnt->vm_mm = area->vm_mm;
+		mpnt->vm_start = end;
+		mpnt->vm_end = area->vm_end;
+		mpnt->vm_page_prot = area->vm_page_prot;
+		mpnt->vm_flags = area->vm_flags;
+		mpnt->vm_raend = 0;
+		mpnt->vm_ops = area->vm_ops;
+		mpnt->vm_pgoff = area->vm_pgoff + ((end - area->vm_start) >> PAGE_SHIFT);
+		mpnt->vm_file = area->vm_file;
+		mpnt->vm_private_data = area->vm_private_data;
+		if (mpnt->vm_file)
+			get_file(mpnt->vm_file);
+		if (mpnt->vm_ops && mpnt->vm_ops->open)
+			mpnt->vm_ops->open(mpnt);
+		area->vm_end = addr;	/* Truncate area */
+
+		/* Because mpnt->vm_file == area->vm_file this locks
+		 * things correctly.
+		 */
+		lock_vma_mappings(area);
+		spin_lock(&mm->page_table_lock);
+		__insert_vm_struct(mm, mpnt);
+	}
+
+	__insert_vm_struct(mm, area);
+	spin_unlock(&mm->page_table_lock);
+	unlock_vma_mappings(area);
+	return extra;
+}
+
+/*
+ * Try to free as many page directory entries as we can,
+ * without having to work very hard at actually scanning
+ * the page tables themselves.
+ *
+ * Right now we try to free page tables if we have a nice
+ * PGDIR-aligned area that got free'd up. We could be more
+ * granular if we want to, but this is fast and simple,
+ * and covers the bad cases.
+ *
+ * "prev", if it exists, points to a vma before the one
+ * we just free'd - but there's no telling how much before.
+ */
+static void free_pgtables(struct mm_struct * mm, struct vm_area_struct *prev,
+	unsigned long start, unsigned long end)
+{
+	unsigned long first = start & PGDIR_MASK;
+	unsigned long last = end + PGDIR_SIZE - 1;
+	unsigned long start_index, end_index;
+
+	if (!prev) {
+		prev = mm->mmap;
+		if (!prev)
+			goto no_mmaps;
+		if (prev->vm_end > start) {
+			if (last > prev->vm_start)
+				last = prev->vm_start;
+			goto no_mmaps;
+		}
+	}
+	for (;;) {
+		struct vm_area_struct *next = prev->vm_next;
+
+		if (next) {
+			if (next->vm_start < start) {
+				prev = next;
+				continue;
+			}
+			if (last > next->vm_start)
+				last = next->vm_start;
+		}
+		if (prev->vm_end > first)
+			first = prev->vm_end + PGDIR_SIZE - 1;
+		break;
+	}
+no_mmaps:
+	if (last < first)
+		return;
+	/*
+	 * If the PGD bits are not consecutive in the virtual address, the
+	 * old method of shifting the VA >> by PGDIR_SHIFT doesn't work.
+	 */
+	start_index = pgd_index(first);
+	end_index = pgd_index(last);
+	if (end_index > start_index) {
+		clear_page_tables(mm, start_index, end_index - start_index);
+		flush_tlb_pgtables(mm, first & PGDIR_MASK, last & PGDIR_MASK);
+	}
+}
+
+/* Munmap is split into 2 main parts -- this part which finds
+ * what needs doing, and the areas themselves, which do the
+ * work.  This now handles partial unmappings.
+ * Jeremy Fitzhardine <jeremy@sw.oz.au>
+ */
+int do_munmap(struct mm_struct *mm, unsigned long addr, size_t len)
+{
+	struct vm_area_struct *mpnt, *prev, **npp, *free, *extra;
+
+	if ((addr & ~PAGE_MASK) || addr >= TASK_SIZE || len > TASK_SIZE-addr)
+		return -EINVAL;
+
+	if ((len = PAGE_ALIGN(len)) == 0)
+		return -EINVAL;
+
+	/* Check if this memory area is ok - put it on the temporary
+	 * list if so..  The checks here are pretty simple --
+	 * every area affected in some way (by any overlap) is put
+	 * on the list.  If nothing is put on, nothing is affected.
+	 */
+	mpnt = find_vma_prev(mm, addr, &prev);
+	if (!mpnt)
+		return 0;
+	/* we have  addr < mpnt->vm_end  */
+
+	if (mpnt->vm_start >= addr+len)
+		return 0;
+
+	/* If we'll make "hole", check the vm areas limit */
+	if ((mpnt->vm_start < addr && mpnt->vm_end > addr+len)
+	    && mm->map_count >= max_map_count)
+		return -ENOMEM;
+
+	/*
+	 * We may need one additional vma to fix up the mappings ... 
+	 * and this is the last chance for an easy error exit.
+	 */
+	extra = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+	if (!extra)
+		return -ENOMEM;
+
+	npp = (prev ? &prev->vm_next : &mm->mmap);
+	free = NULL;
+	spin_lock(&mm->page_table_lock);
+	for ( ; mpnt && mpnt->vm_start < addr+len; mpnt = *npp) {
+		*npp = mpnt->vm_next;
+		mpnt->vm_next = free;
+		free = mpnt;
+		rb_erase(&mpnt->vm_rb, &mm->mm_rb);
+	}
+	mm->mmap_cache = NULL;	/* Kill the cache. */
+	spin_unlock(&mm->page_table_lock);
+
+	/* Ok - we have the memory areas we should free on the 'free' list,
+	 * so release them, and unmap the page range..
+	 * If the one of the segments is only being partially unmapped,
+	 * it will put new vm_area_struct(s) into the address space.
+	 * In that case we have to be careful with VM_DENYWRITE.
+	 */
+	while ((mpnt = free) != NULL) {
+		unsigned long st, end, size;
+		struct file *file = NULL;
+
+		free = free->vm_next;
+
+		st = addr < mpnt->vm_start ? mpnt->vm_start : addr;
+		end = addr+len;
+		end = end > mpnt->vm_end ? mpnt->vm_end : end;
+		size = end - st;
+
+		if (mpnt->vm_flags & VM_DENYWRITE &&
+		    (st != mpnt->vm_start || end != mpnt->vm_end) &&
+		    (file = mpnt->vm_file) != NULL) {
+			atomic_dec(&file->f_dentry->d_inode->i_writecount);
+		}
+		remove_shared_vm_struct(mpnt);
+		mm->map_count--;
+
+		zap_page_range(mm, st, size);
+
+		/*
+		 * Fix the mapping, and free the old area if it wasn't reused.
+		 */
+		extra = unmap_fixup(mm, mpnt, st, size, extra);
+		if (file)
+			atomic_inc(&file->f_dentry->d_inode->i_writecount);
+	}
+	validate_mm(mm);
+
+	/* Release the extra vma struct if it wasn't used */
+	if (extra)
+		kmem_cache_free(vm_area_cachep, extra);
+
+	free_pgtables(mm, prev, addr, addr+len);
+
+	return 0;
+}
+
+asmlinkage long sys_munmap(unsigned long addr, size_t len)
+{
+	int ret;
+	struct mm_struct *mm = current->mm;
+
+	down_write(&mm->mmap_sem);
+	ret = do_munmap(mm, addr, len);
+	up_write(&mm->mmap_sem);
+	return ret;
+}
+
+
+static inline void verify_mmap_write_lock_held(struct mm_struct *mm)
+{
+	if (down_read_trylock(&mm->mmap_sem)) {
+		WARN_ON(1);
+		up_read(&mm->mmap_sem);
+	}
+}
+
+/*
+ *  this is really a simplified "do_mmap".  it only handles
+ *  anonymous maps.  eventually we may be able to do some
+ *  brk-specific accounting here.
+ */
+unsigned long do_brk(unsigned long addr, unsigned long len)
+{
+	struct mm_struct * mm = current->mm;
+	struct vm_area_struct * vma, * prev;
+	unsigned long flags;
+	rb_node_t ** rb_link, * rb_parent;
+
+	len = PAGE_ALIGN(len);
+	if (!len)
+		return addr;
+
+	if ((addr + len) > TASK_SIZE || (addr + len) < addr)
+		return -EINVAL;
+
+	/*
+	 * mlock MCL_FUTURE?
+	 */
+	if (mm->def_flags & VM_LOCKED) {
+		unsigned long locked = mm->locked_vm << PAGE_SHIFT;
+		locked += len;
+		if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
+			return -EAGAIN;
+	}
+
+	/*
+	 * mm->mmap_sem is required to protect against another thread
+	 * changing the mappings while we sleep (on kmalloc for one).
+	 */
+	verify_mmap_write_lock_held(mm);
+
+	/*
+	 * Clear old maps.  this also does some error checking for us
+	 */
+ munmap_back:
+	vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
+	if (vma && vma->vm_start < addr + len) {
+		if (do_munmap(mm, addr, len))
+			return -ENOMEM;
+		goto munmap_back;
+	}
+
+	/* Check against address space limits *after* clearing old maps... */
+	if ((mm->total_vm << PAGE_SHIFT) + len
+	    > current->rlim[RLIMIT_AS].rlim_cur)
+		return -ENOMEM;
+
+	if (mm->map_count > max_map_count)
+		return -ENOMEM;
+
+	if (!vm_enough_memory(len >> PAGE_SHIFT))
+		return -ENOMEM;
+
+	flags = VM_DATA_DEFAULT_FLAGS | mm->def_flags;
+
+	/* Can we just expand an old anonymous mapping? */
+	if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len, flags))
+		goto out;
+
+	/*
+	 * create a vma struct for an anonymous mapping
+	 */
+	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+	if (!vma)
+		return -ENOMEM;
+
+	vma->vm_mm = mm;
+	vma->vm_start = addr;
+	vma->vm_end = addr + len;
+	vma->vm_flags = flags;
+	vma->vm_page_prot = protection_map[flags & 0x0f];
+	vma->vm_ops = NULL;
+	vma->vm_pgoff = 0;
+	vma->vm_file = NULL;
+	vma->vm_private_data = NULL;
+
+	vma_link(mm, vma, prev, rb_link, rb_parent);
+
+out:
+	mm->total_vm += len >> PAGE_SHIFT;
+	if (flags & VM_LOCKED) {
+		mm->locked_vm += len >> PAGE_SHIFT;
+		make_pages_present(addr, addr + len);
+	}
+	return addr;
+}
+
+/* Build the RB tree corresponding to the VMA list. */
+void build_mmap_rb(struct mm_struct * mm)
+{
+	struct vm_area_struct * vma;
+	rb_node_t ** rb_link, * rb_parent;
+
+	mm->mm_rb = RB_ROOT;
+	rb_link = &mm->mm_rb.rb_node;
+	rb_parent = NULL;
+	for (vma = mm->mmap; vma; vma = vma->vm_next) {
+		__vma_link_rb(mm, vma, rb_link, rb_parent);
+		rb_parent = &vma->vm_rb;
+		rb_link = &rb_parent->rb_right;
+	}
+}
+
+/* Release all mmaps. */
+void exit_mmap(struct mm_struct * mm)
+{
+	struct vm_area_struct * mpnt;
+
+	release_segments(mm);
+	spin_lock(&mm->page_table_lock);
+	mpnt = mm->mmap;
+	mm->mmap = mm->mmap_cache = NULL;
+	mm->mm_rb = RB_ROOT;
+	mm->rss = 0;
+	spin_unlock(&mm->page_table_lock);
+	mm->total_vm = 0;
+	mm->locked_vm = 0;
+
+	flush_cache_mm(mm);
+	while (mpnt) {
+		struct vm_area_struct * next = mpnt->vm_next;
+		unsigned long start = mpnt->vm_start;
+		unsigned long end = mpnt->vm_end;
+		unsigned long size = end - start;
+
+		if (mpnt->vm_ops) {
+			if (mpnt->vm_ops->close)
+				mpnt->vm_ops->close(mpnt);
+		}
+		mm->map_count--;
+		remove_shared_vm_struct(mpnt);
+		zap_page_range(mm, start, size);
+		if (mpnt->vm_file)
+			fput(mpnt->vm_file);
+		kmem_cache_free(vm_area_cachep, mpnt);
+		mpnt = next;
+	}
+
+	/* This is just debugging */
+	if (mm->map_count)
+		BUG();
+
+	clear_page_tables(mm, FIRST_USER_PGD_NR, USER_PTRS_PER_PGD);
+
+	flush_tlb_mm(mm);
+}
+
+/* Insert vm structure into process list sorted by address
+ * and into the inode's i_mmap ring.  If vm_file is non-NULL
+ * then the i_shared_lock must be held here.
+ */
+void __insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
+{
+	struct vm_area_struct * __vma, * prev;
+	rb_node_t ** rb_link, * rb_parent;
+
+	__vma = find_vma_prepare(mm, vma->vm_start, &prev, &rb_link, &rb_parent);
+	if (__vma && __vma->vm_start < vma->vm_end)
+		BUG();
+	__vma_link(mm, vma, prev, rb_link, rb_parent);
+	mm->map_count++;
+	validate_mm(mm);
+}
+
+int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
+{
+	struct vm_area_struct * __vma, * prev;
+	rb_node_t ** rb_link, * rb_parent;
+
+	__vma = find_vma_prepare(mm, vma->vm_start, &prev, &rb_link, &rb_parent);
+	if (__vma && __vma->vm_start < vma->vm_end)
+		return -ENOMEM;
+	vma_link(mm, vma, prev, rb_link, rb_parent);
+	validate_mm(mm);
+	return 0;
+}
+
+#else /* NO_MM */
+
+unsigned long get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	if (flags & MAP_FIXED) {
+		if (addr > TASK_SIZE - len)
+			return -EINVAL;
+		if (addr & ~PAGE_MASK)
+			return -EINVAL;
+		return addr;
+	}
+
+	if (file && file->f_op && file->f_op->get_unmapped_area)
+		return file->f_op->get_unmapped_area(file, addr, len, pgoff, flags);
+
+	return 0;
+}
+
+#ifdef DEBUG
+static void show_process_blocks(void)
+{
+	struct mm_tblock_struct * tblock, *tmp;
+	
+	printk("Process blocks %d:", current->pid);
+	
+	tmp = &current->mm->tblock;
+	while (tmp) {
+		printk(" %p: %p", tmp, tmp->rblock);
+		if (tmp->rblock)
+			printk(" (%d @%p #%d)", ksize(tmp->rblock->kblock), tmp->rblock->kblock, tmp->rblock->refcount);
+		if (tmp->next)
+			printk(" ->");
+		else
+			printk(".");
+		tmp = tmp->next;
+	}
+	printk("\n");
+}
+#endif /* DEBUG */
+
+extern unsigned long askedalloc, realalloc;
+
+unsigned long do_mmap_pgoff(
+	struct file * file,
+	unsigned long addr,
+	unsigned long len,
+	unsigned long prot,
+	unsigned long flags,
+	unsigned long pgoff)
+{
+	void * result;
+#if 0
+	struct mm_struct * mm = current->mm;
+#endif
+	struct mm_tblock_struct * tblock;
+	unsigned int vm_flags;
+
+	/*
+	 * Get the NO_MM specific checks done first
+	 */
+	if ((flags & MAP_SHARED) && (prot & PROT_WRITE) && (file)) {
+		printk("MAP_SHARED not supported (cannot write mappings to disk)\n");
+		return -EINVAL;
+	}
+	
+	if ((prot & PROT_WRITE) && (flags & MAP_PRIVATE)) {
+		printk("Private writable mappings not supported\n");
+		return -EINVAL;
+	}
+	
+	/*
+	 *	now all the standard checks
+	 */
+	if (file && (!file->f_op || !file->f_op->mmap))
+		return -ENODEV;
+
+	if (PAGE_ALIGN(len) == 0)
+		return addr;
+
+	if (len > TASK_SIZE)
+		return -EINVAL;
+
+	/* offset overflow? */
+	if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
+		return -EINVAL;
+
+#if 0
+	/* Too many mappings? */
+	if (mm->map_count > MAX_MAP_COUNT)
+		return -ENOMEM;
+#endif
+
+	/* Obtain the address to map to. we verify (or select) it and ensure
+	 * that it represents a valid section of the address space.
+	 */
+	addr = get_unmapped_area(file, addr, len, pgoff, flags);
+	if (addr & ~PAGE_MASK)
+		return addr;
+
+	/* Do simple checking here so the lower-level routines won't have
+	 * to. we assume access permissions have been handled by the open
+	 * of the memory object, so we don't do any here.
+	 */
+	vm_flags = calc_vm_flags(prot,flags) /* | mm->def_flags */ | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
+
+#if 0
+	/* mlock MCL_FUTURE? */
+	if (vm_flags & VM_LOCKED) {
+		unsigned long locked = mm->locked_vm << PAGE_SHIFT;
+		locked += len;
+		if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
+			return -EAGAIN;
+	}
+#endif
+
+	/*
+	 * determine the object being mapped and call the appropriate
+	 * specific mapper. 
+	 */
+
+	if (file) {
+		struct vm_area_struct vma;
+		int error;
+		
+		
+		if (!file->f_op)
+			return -ENODEV;
+
+		vma.vm_start = addr;
+		vma.vm_end = addr + len;
+		vma.vm_flags = vm_flags;
+		vma.vm_offset = pgoff << PAGE_SHIFT;
+
+#ifdef MAGIC_ROM_PTR
+		/* First, try simpler routine designed to give us a ROM pointer. */
+
+		if (file->f_op->romptr && !(prot & PROT_WRITE)) {
+			error = file->f_op->romptr(file, &vma);
+#ifdef DEBUG
+			printk("romptr mmap returned %d, start 0x%.8x\n", error,
+					vma.vm_start);
+#endif
+			if (!error)
+				return vma.vm_start;
+			else if (error != -ENOSYS)
+				return error;
+		} else
+#endif /* MAGIC_ROM_PTR */
+		/* Then try full mmap routine, which might return a RAM pointer,
+		   or do something truly complicated. */
+		   
+		if (file->f_op->mmap) {
+			error = file->f_op->mmap(file, &vma);
+				   
+#ifdef DEBUG
+			printk("mmap mmap returned %d /%x\n", error, vma.vm_start);
+#endif
+			if (!error)
+				return vma.vm_start;
+			else if (error != -ENOSYS)
+				return error;
+		} else
+			return -ENODEV; /* No mapping operations defined */
+
+		/* An ENOSYS error indicates that mmap isn't possible (as opposed to
+		   tried but failed) so we'll fall through to the copy. */
+	}
+
+	tblock = (struct mm_tblock_struct *)
+                        kmalloc(sizeof(struct mm_tblock_struct), GFP_KERNEL);
+	if (!tblock) {
+		printk("Allocation of tblock for %lu byte allocation from process %d failed\n", len, current->pid);
+		show_buffers();
+		show_free_areas();
+		return -ENOMEM;
+	}
+
+	tblock->rblock = (struct mm_rblock_struct *)
+			kmalloc(sizeof(struct mm_rblock_struct), GFP_KERNEL);
+
+	if (!tblock->rblock) {
+		printk("Allocation of rblock for %lu byte allocation from process %d failed\n", len, current->pid);
+		show_buffers();
+		show_free_areas();
+		kfree(tblock);
+		return -ENOMEM;
+	}
+
+	
+	result = kmalloc(len, GFP_KERNEL);
+	if (!result) {
+		printk("Allocation of length %lu from process %d failed\n", len,
+				current->pid);
+		show_buffers();
+		show_free_areas();
+		kfree(tblock->rblock);
+		kfree(tblock);
+		return -ENOMEM;
+	}
+
+	tblock->rblock->refcount = 1;
+	tblock->rblock->kblock = result;
+	tblock->rblock->size = len;
+	
+	realalloc += ksize(result);
+	askedalloc += len;
+
+#ifdef WARN_ON_SLACK	
+	if ((len+WARN_ON_SLACK) <= ksize(result))
+		printk("Allocation of %lu bytes from process %d has %lu bytes of slack\n", len, current->pid, ksize(result)-len);
+#endif
+	
+	if (file) {
+		int error;
+		mm_segment_t old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		error = file->f_op->read(file, (char *) result, len, &file->f_pos);
+		set_fs(old_fs);
+		if (error < 0) {
+			kfree(result);
+			kfree(tblock->rblock);
+			kfree(tblock);
+			return error;
+		}
+		if (error<len)
+			memset(result+error, '\0', len-error);
+	} else {
+		memset(result, '\0', len);
+	}
+
+        
+	realalloc += ksize(tblock);
+	askedalloc += sizeof(struct mm_tblock_struct);
+
+	realalloc += ksize(tblock->rblock);
+	askedalloc += sizeof(struct mm_rblock_struct);
+
+	tblock->next = current->mm->tblock.next;
+	current->mm->tblock.next = tblock;
+	current->mm->total_vm += len >> PAGE_SHIFT;
+
+#ifdef DEBUG
+	printk("do_mmap:\n");
+	show_process_blocks();
+#endif	  
+
+	return (unsigned long)result;
+}
+
+int do_munmap(struct mm_struct * mm, unsigned long addr, size_t len)
+{
+	struct mm_tblock_struct * tblock, *tmp;
+
+#ifdef MAGIC_ROM_PTR
+	/* For efficiency's sake, if the pointer is obviously in ROM,
+	   don't bother walking the lists to free it */
+	if (is_in_rom(addr))
+		return 0;
+#endif
+
+#ifdef DEBUG
+	printk("do_munmap:\n");
+#endif
+
+	tmp = &mm->tblock; /* dummy head */
+	while ((tblock=tmp->next) && tblock->rblock &&
+			tblock->rblock->kblock != (void*)addr) 
+		tmp = tblock;
+		
+	if (!tblock) {
+		printk("munmap of non-mmaped memory by process %d (%s): %p\n",
+				current->pid, current->comm, (void*)addr);
+		return -EINVAL;
+	}
+	if (tblock->rblock) {
+		if (!--tblock->rblock->refcount) {
+			if (tblock->rblock->kblock) {
+				realalloc -= ksize(tblock->rblock->kblock);
+				askedalloc -= tblock->rblock->size;
+				kfree(tblock->rblock->kblock);
+			}
+			
+			realalloc -= ksize(tblock->rblock);
+			askedalloc -= sizeof(struct mm_rblock_struct);
+			kfree(tblock->rblock);
+		}
+	}
+	tmp->next = tblock->next;
+	realalloc -= ksize(tblock);
+	askedalloc -= sizeof(struct mm_tblock_struct);
+	kfree(tblock);
+	mm->total_vm -= len >> PAGE_SHIFT;
+
+#ifdef DEBUG
+	show_process_blocks();
+#endif	  
+
+	return 0;
+}
+
+/* Release all mmaps. */
+void exit_mmap(struct mm_struct * mm)
+{
+	struct mm_tblock_struct *tmp;
+	mm->total_vm = 0;
+
+	if (!mm)
+		return;
+
+#ifdef DEBUG
+	printk("Exit_mmap:\n");
+#endif
+
+	while((tmp = mm->tblock.next)) {
+		if (tmp->rblock) {
+			if (!--tmp->rblock->refcount) {
+				if (tmp->rblock->kblock) {
+					realalloc -= ksize(tmp->rblock->kblock);
+					askedalloc -= tmp->rblock->size;
+					kfree(tmp->rblock->kblock);
+				}
+				realalloc -= ksize(tmp->rblock);
+				askedalloc -= sizeof(struct mm_rblock_struct);
+				kfree(tmp->rblock);
+			}
+			tmp->rblock = 0;
+		}
+		mm->tblock.next = tmp->next;
+		realalloc -= ksize(tmp);
+		askedalloc -= sizeof(struct mm_tblock_struct);
+		kfree(tmp);
+	}
+
+#ifdef DEBUG
+	show_process_blocks();
+#endif	  
+}
+
+asmlinkage long sys_munmap(unsigned long addr, size_t len)
+{
+	int ret;
+	struct mm_struct *mm = current->mm;
+
+	down_write(&mm->mmap_sem);
+	ret = do_munmap(mm, addr, len);
+	up_write(&mm->mmap_sem);
+	return ret;
+}
+
+#endif /* NO_MM */
diff -urN linux-2.4.29/mmnommu/mprotect.c linux-2.4.29-uc1/mmnommu/mprotect.c
--- linux-2.4.29/mmnommu/mprotect.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/mprotect.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,18 @@
+/*
+ *	linux/mm/mprotect.c
+ *
+ *  Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org> ref uClinux 2.0
+ *  (C) Copyright 1994 Linus Torvalds
+ */
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/shm.h>
+#include <linux/mman.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+
+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
+{
+	return -ENOSYS;
+}
diff -urN linux-2.4.29/mmnommu/mremap.c linux-2.4.29-uc1/mmnommu/mremap.c
--- linux-2.4.29/mmnommu/mremap.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/mremap.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,26 @@
+/*
+ *	linux/mm/remap.c
+ *
+ *  Copyright (c) 2001 Lineo, Inc. David McCullough <davidm@lineo.com>
+ *  Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org> ref uClinux 2.0
+ *	(C) Copyright 1996 Linus Torvalds
+ */
+
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/shm.h>
+#include <linux/mman.h>
+#include <linux/swap.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+
+/*
+ * FIXME: Could do a tradional realloc() in some cases.
+ */
+asmlinkage unsigned long sys_mremap(unsigned long addr,
+	unsigned long old_len, unsigned long new_len,
+	unsigned long flags, unsigned long new_addr)
+{
+	return -ENOSYS;
+}
diff -urN linux-2.4.29/mmnommu/numa.c linux-2.4.29-uc1/mmnommu/numa.c
--- linux-2.4.29/mmnommu/numa.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/numa.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,130 @@
+/*
+ * Written by Kanoj Sarcar, SGI, Aug 1999
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mmzone.h>
+#include <linux/spinlock.h>
+
+int numnodes = 1;	/* Initialized for UMA platforms */
+
+static bootmem_data_t contig_bootmem_data;
+pg_data_t contig_page_data = { bdata: &contig_bootmem_data };
+
+#ifndef CONFIG_DISCONTIGMEM
+
+/*
+ * This is meant to be invoked by platforms whose physical memory starts
+ * at a considerably higher value than 0. Examples are Super-H, ARM, m68k.
+ * Should be invoked with paramters (0, 0, unsigned long *[], start_paddr).
+ */
+void __init free_area_init_node(int nid, pg_data_t *pgdat, struct page *pmap,
+	unsigned long *zones_size, unsigned long zone_start_paddr, 
+	unsigned long *zholes_size)
+{
+	free_area_init_core(0, &contig_page_data, &mem_map, zones_size, 
+				zone_start_paddr, zholes_size, pmap);
+}
+
+#endif /* !CONFIG_DISCONTIGMEM */
+
+struct page * alloc_pages_node(int nid, unsigned int gfp_mask, unsigned int order)
+{
+#ifdef CONFIG_NUMA
+	return __alloc_pages(gfp_mask, order, NODE_DATA(nid)->node_zonelists + (gfp_mask & GFP_ZONEMASK));
+#else
+	return alloc_pages(gfp_mask, order);
+#endif
+}
+
+#ifdef CONFIG_DISCONTIGMEM
+
+#define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
+
+static spinlock_t node_lock = SPIN_LOCK_UNLOCKED;
+
+void show_free_areas_node(pg_data_t *pgdat)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&node_lock, flags);
+	show_free_areas_core(pgdat);
+	spin_unlock_irqrestore(&node_lock, flags);
+}
+
+/*
+ * Nodes can be initialized parallely, in no particular order.
+ */
+void __init free_area_init_node(int nid, pg_data_t *pgdat, struct page *pmap,
+	unsigned long *zones_size, unsigned long zone_start_paddr, 
+	unsigned long *zholes_size)
+{
+	int i, size = 0;
+	struct page *discard;
+
+	if (mem_map == (mem_map_t *)NULL)
+		mem_map = (mem_map_t *)PAGE_OFFSET;
+
+	free_area_init_core(nid, pgdat, &discard, zones_size, zone_start_paddr,
+					zholes_size, pmap);
+	pgdat->node_id = nid;
+
+	/*
+	 * Get space for the valid bitmap.
+	 */
+	for (i = 0; i < MAX_NR_ZONES; i++)
+		size += zones_size[i];
+	size = LONG_ALIGN((size + 7) >> 3);
+	pgdat->valid_addr_bitmap = (unsigned long *)alloc_bootmem_node(pgdat, size);
+	memset(pgdat->valid_addr_bitmap, 0, size);
+}
+
+static struct page * alloc_pages_pgdat(pg_data_t *pgdat, unsigned int gfp_mask,
+	unsigned int order)
+{
+	return __alloc_pages(gfp_mask, order, pgdat->node_zonelists + (gfp_mask & GFP_ZONEMASK));
+}
+
+/*
+ * This can be refined. Currently, tries to do round robin, instead
+ * should do concentratic circle search, starting from current node.
+ */
+struct page * _alloc_pages(unsigned int gfp_mask, unsigned int order)
+{
+	struct page *ret = 0;
+	pg_data_t *start, *temp;
+#ifndef CONFIG_NUMA
+	unsigned long flags;
+	static pg_data_t *next = 0;
+#endif
+
+	if (order >= MAX_ORDER)
+		return NULL;
+#ifdef CONFIG_NUMA
+	temp = NODE_DATA(numa_node_id());
+#else
+	spin_lock_irqsave(&node_lock, flags);
+	if (!next) next = pgdat_list;
+	temp = next;
+	next = next->node_next;
+	spin_unlock_irqrestore(&node_lock, flags);
+#endif
+	start = temp;
+	while (temp) {
+		if ((ret = alloc_pages_pgdat(temp, gfp_mask, order)))
+			return(ret);
+		temp = temp->node_next;
+	}
+	temp = pgdat_list;
+	while (temp != start) {
+		if ((ret = alloc_pages_pgdat(temp, gfp_mask, order)))
+			return(ret);
+		temp = temp->node_next;
+	}
+	return(0);
+}
+
+#endif /* CONFIG_DISCONTIGMEM */
diff -urN linux-2.4.29/mmnommu/oom_kill.c linux-2.4.29-uc1/mmnommu/oom_kill.c
--- linux-2.4.29/mmnommu/oom_kill.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/oom_kill.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,298 @@
+/*
+ *  linux/mm/oom_kill.c
+ * 
+ *  Copyright (C)  1998,2000  Rik van Riel
+ *	Thanks go out to Claus Fischer for some serious inspiration and
+ *	for goading me into coding this file...
+ *
+ *  The routines in this file are used to kill a process when
+ *  we're seriously out of memory. This gets called from kswapd()
+ *  in linux/mm/vmscan.c when we really run out of memory.
+ *
+ *  Since we won't call these routines often (on a well-configured
+ *  machine) this file will double as a 'coding guide' and a signpost
+ *  for newbie kernel hackers. It features several pointers to major
+ *  kernel subsystems and hints as to where to find out what things do.
+ */
+
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/swap.h>
+#include <linux/swapctl.h>
+#include <linux/timex.h>
+
+/* #define DEBUG */
+
+/**
+ * int_sqrt - oom_kill.c internal function, rough approximation to sqrt
+ * @x: integer of which to calculate the sqrt
+ * 
+ * A very rough approximation to the sqrt() function.
+ */
+static unsigned int int_sqrt(unsigned int x)
+{
+	unsigned int out = x;
+	while (x & ~(unsigned int)1) x >>=2, out >>=1;
+	if (x) out -= out >> 2;
+	return (out ? out : 1);
+}	
+
+/**
+ * oom_badness - calculate a numeric value for how bad this task has been
+ * @p: task struct of which task we should calculate
+ *
+ * The formula used is relatively simple and documented inline in the
+ * function. The main rationale is that we want to select a good task
+ * to kill when we run out of memory.
+ *
+ * Good in this context means that:
+ * 1) we lose the minimum amount of work done
+ * 2) we recover a large amount of memory
+ * 3) we don't kill anything innocent of eating tons of memory
+ * 4) we want to kill the minimum amount of processes (one)
+ * 5) we try to kill the process the user expects us to kill, this
+ *    algorithm has been meticulously tuned to meet the priniciple
+ *    of least surprise ... (be careful when you change it)
+ */
+
+static int badness(struct task_struct *p)
+{
+	int points, cpu_time, run_time;
+
+	if (!p->mm)
+		return 0;
+
+	if (p->flags & PF_MEMDIE)
+		return 0;
+
+	/*
+	 * The memory size of the process is the basis for the badness.
+	 */
+	points = p->mm->total_vm;
+
+	/*
+	 * CPU time is in seconds and run time is in minutes. There is no
+	 * particular reason for this other than that it turned out to work
+	 * very well in practice. This is not safe against jiffie wraps
+	 * but we don't care _that_ much...
+	 */
+	cpu_time = (p->times.tms_utime + p->times.tms_stime) >> (SHIFT_HZ + 3);
+	run_time = (jiffies - p->start_time) >> (SHIFT_HZ + 10);
+
+	points /= int_sqrt(cpu_time);
+	points /= int_sqrt(int_sqrt(run_time));
+
+	/*
+	 * Niced processes are most likely less important, so double
+	 * their badness points.
+	 */
+	if (p->nice > 0)
+		points *= 2;
+
+	/*
+	 * Superuser processes are usually more important, so we make it
+	 * less likely that we kill those.
+	 */
+	if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_ADMIN) ||
+				p->uid == 0 || p->euid == 0)
+		points /= 4;
+
+	/*
+	 * We don't want to kill a process with direct hardware access.
+	 * Not only could that mess up the hardware, but usually users
+	 * tend to only have this flag set on applications they think
+	 * of as important.
+	 */
+	if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO))
+		points /= 4;
+#ifdef DEBUG
+	printk(KERN_DEBUG "OOMkill: task %d (%s) got %d points\n",
+	p->pid, p->comm, points);
+#endif
+	return points;
+}
+
+/*
+ * Simple selection loop. We chose the process with the highest
+ * number of 'points'. We expect the caller will lock the tasklist.
+ *
+ * (not docbooked, we don't want this one cluttering up the manual)
+ */
+static struct task_struct * select_bad_process(void)
+{
+	int maxpoints = 0;
+	struct task_struct *p = NULL;
+	struct task_struct *chosen = NULL;
+
+	for_each_task(p) {
+		if (p->pid) {
+			int points = badness(p);
+			if (points > maxpoints) {
+				chosen = p;
+				maxpoints = points;
+			}
+		}
+	}
+	return chosen;
+}
+
+/**
+ * We must be careful though to never send SIGKILL a process with
+ * CAP_SYS_RAW_IO set, send SIGTERM instead (but it's unlikely that
+ * we select a process with CAP_SYS_RAW_IO set).
+ */
+static void __oom_kill_task(struct task_struct *p)
+{
+	printk(KERN_ERR "Out of Memory: Killed process %d (%s).\n", p->pid, p->comm);
+
+	/*
+	 * We give our sacrificial lamb high priority and access to
+	 * all the memory it needs. That way it should be able to
+	 * exit() and clear out its resources quickly...
+	 */
+	p->counter = 5 * HZ;
+	p->flags |= PF_MEMALLOC | PF_MEMDIE;
+
+	/* This process has hardware access, be more careful. */
+	if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO)) {
+		force_sig(SIGTERM, p);
+	} else {
+		force_sig(SIGKILL, p);
+	}
+}
+
+static struct mm_struct *oom_kill_task(struct task_struct *p)
+{
+	struct mm_struct *mm;
+
+	task_lock(p);
+	mm = p->mm;
+	if (mm) {
+		spin_lock(&mmlist_lock);
+		if (atomic_read(&mm->mm_users))
+			atomic_inc(&mm->mm_users);
+		else
+			mm = NULL;
+		spin_unlock(&mmlist_lock);
+	}
+	task_unlock(p);
+	if (mm)
+		__oom_kill_task(p);
+	return mm;
+}
+
+/**
+ * oom_kill - kill the "best" process when we run out of memory
+ *
+ * If we run out of memory, we have the choice between either
+ * killing a random task (bad), letting the system crash (worse)
+ * OR try to be smart about which process to kill. Note that we
+ * don't have to be perfect here, we just have to be good.
+ */
+static void oom_kill(void)
+{
+	struct task_struct *p, *q;
+	struct mm_struct *mm;
+
+retry:
+	read_lock(&tasklist_lock);
+	p = select_bad_process();
+
+	/* Found nothing?!?! Either we hang forever, or we panic. */
+	if (p == NULL)
+		panic("Out of memory and no killable processes...\n");
+	mm = oom_kill_task(p);
+	if (!mm) {
+		read_unlock(&tasklist_lock);
+		goto retry;
+	}
+	/* kill all processes that share the ->mm (i.e. all threads) */
+	for_each_task(q) {
+		if (q->mm == mm)
+			__oom_kill_task(q);
+	}
+	read_unlock(&tasklist_lock);
+	mmput(mm);
+	/*
+	 * Make kswapd go out of the way, so "p" has a good chance of
+	 * killing itself before someone else gets the chance to ask
+	 * for more memory.
+	 */
+	yield();
+	return;
+}
+
+/**
+ * out_of_memory - is the system out of memory?
+ */
+void out_of_memory(void)
+{
+	/*
+	 * oom_lock protects out_of_memory()'s static variables.
+	 * It's a global lock; this is not performance-critical.
+	 */
+	static spinlock_t oom_lock = SPIN_LOCK_UNLOCKED;
+	static unsigned long first, last, count, lastkill;
+	unsigned long now, since;
+
+	/*
+	 * Enough swap space left?  Not OOM.
+	 */
+	if (nr_swap_pages > 0)
+		return;
+
+	spin_lock(&oom_lock);
+	now = jiffies;
+	since = now - last;
+	last = now;
+
+	/*
+	 * If it's been a long time since last failure,
+	 * we're not oom.
+	 */
+	last = now;
+	if (since > 5*HZ)
+		goto reset;
+
+	/*
+	 * If we haven't tried for at least one second,
+	 * we're not really oom.
+	 */
+	since = now - first;
+	if (since < HZ)
+		goto out_unlock;
+
+	/*
+	 * If we have gotten only a few failures,
+	 * we're not really oom. 
+	 */
+	if (++count < 10)
+		goto out_unlock;
+
+	/*
+	 * If we just killed a process, wait a while
+	 * to give that task a chance to exit. This
+	 * avoids killing multiple processes needlessly.
+	 */
+	since = now - lastkill;
+	if (since < HZ*5)
+		goto out_unlock;
+
+	/*
+	 * Ok, really out of memory. Kill something.
+	 */
+	lastkill = now;
+
+	/* oom_kill() can sleep */
+	spin_unlock(&oom_lock);
+	oom_kill();
+	spin_lock(&oom_lock);
+
+reset:
+	if ((long)first - (long)now < 0)
+		first = now;
+	count = 0;
+
+out_unlock:
+	spin_unlock(&oom_lock);
+}
diff -urN linux-2.4.29/mmnommu/page_alloc2.c linux-2.4.29-uc1/mmnommu/page_alloc2.c
--- linux-2.4.29/mmnommu/page_alloc2.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/page_alloc2.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,1159 @@
+/****************************************************************************/
+/*
+ *  linux/mmnommu/page_alloc2.c
+ *
+ *  	Copyright (C) 2001, 2002 David McCullough <davidm@snapgear.com>
+ *
+ *	A page allocator that attempts to be better than the
+ *	standard power of 2 allocator.
+ *
+ *	Based on page_alloc.c, see credits in that file.
+ *
+ *	12/2003 David McCullough <davidm@snapgear.com>
+ *	  - speedups to allocation methods
+ *	    cleanup CONFIG_UNCACHED_MEM to use common code
+ *
+ *	01/2003 Oleksandr Zhadan <Oleks@ArcturusNetworks.com>
+ *	  - Added support for a specific region on top of the memory.
+ *      Now it is set to use this region as uncached memory and it is
+ *	    ARM940 specific things(ARM940 has no functions to invalidate/clean
+ *	    part of the cache, only whole one), but it could be use for any
+ *	    user proposal.
+ *	    To back to original code just remove everything between
+ *	    "#ifdef CONFIG_UNCACHED_MEM" and "#endif"
+ *
+ */  
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/swapctl.h>
+#include <linux/interrupt.h>
+#include <linux/pagemap.h>
+#include <linux/bootmem.h>
+#include <linux/slab.h>
+#include <linux/compiler.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+/****************************************************************************/
+/*
+ *	do we want nasty stuff checking enabled
+ */
+
+#if 0
+#define SADISTIC_PAGE_ALLOC 1
+#endif
+
+/*
+ *	Some accounting stuff
+ */
+extern unsigned long askedalloc, realalloc;
+
+int nr_swap_pages;
+int nr_active_pages;
+int nr_inactive_pages;
+struct list_head inactive_list;
+struct list_head active_list;
+pg_data_t *pgdat_list;
+
+#define memlist_init(x) INIT_LIST_HEAD(x)
+#define memlist_add_head list_add
+#define memlist_add_tail list_add_tail
+#define memlist_del list_del
+#define memlist_entry list_entry
+#define memlist_next(x) ((x)->next)
+#define memlist_prev(x) ((x)->prev)
+
+zone_t *zone_table[MAX_NR_ZONES*MAX_NR_NODES];
+EXPORT_SYMBOL(zone_table);
+
+static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
+static int lower_zone_reserve_ratio[MAX_NR_ZONES-1] = { 256, 32 };
+
+/*
+ *	A simple method to save us searching all the reserved kernel
+ *	pages every time is to remember where the first free page is
+ */
+
+static char *bit_map = NULL;
+static int	 bit_map_size = 0;
+static int	 first_usable_page = 0;
+static int   _nr_free_pages = 0;
+
+unsigned int nr_free_pages() { return _nr_free_pages; }
+
+extern struct wait_queue *buffer_wait;
+
+#define ADDRESS(x) (PAGE_OFFSET + ((x) << PAGE_SHIFT))
+
+/****************************************************************************/
+
+#if 1
+#define DBG_ALLOC(fmt...)
+#else
+#define DBG_ALLOC(fmt...) printk(##fmt)
+#endif
+
+extern unsigned long __get_contiguous_pages(unsigned int gfp_mask,
+			unsigned long num_adjpages, unsigned int align_order);
+static void find_some_memory(int n);
+
+#ifdef CONFIG_MEM_MAP
+static int mem_map_read_proc(char *page, char **start, off_t off,
+				 int count, int *eof, void *data);
+#endif
+
+#ifdef __mc68000__
+#define ALIGN_ORDER(x)	0
+#else
+#define ALIGN_ORDER(x)	((x) == 1 ? 1 : 0)
+#endif
+
+/*
+ * The number of pages that constitute a small allocation that is located
+ * at the bottom of memory
+ */
+#define SMALL_ALLOC_PAGES 2
+
+/****************************************************************************/
+
+#ifdef CONFIG_UNCACHED_MEM
+/*
+ * handle a special region of memory at the end of normal RAM.
+ * This should be done with zones,  but for now this hack will suffice.
+ */
+
+#if defined(CONFIG_UNCACHED_256)
+# define SizeUnCacheRegion	0x40000
+#elif defined(CONFIG_UNCACHED_512)
+# define SizeUnCacheRegion	0x80000
+#elif defined(CONFIG_UNCACHED_1024)
+# define SizeUnCacheRegion	0x100000
+#elif defined(CONFIG_UNCACHED_2048)
+# define SizeUnCacheRegion	0x200000
+#elif defined(CONFIG_UNCACHED_4096)
+# define SizeUnCacheRegion	0x400000
+#elif defined(CONFIG_UNCACHED_8192)
+# define SizeUnCacheRegion	0x800000
+#endif
+
+#define GFP_SPECIAL			GFP_DMA
+
+static int  bit_map_size_common  = 0;
+static int  bit_map_size_special = SizeUnCacheRegion>>PAGE_SHIFT;
+
+#endif	/* CONFIG_UNCACHED_MEM */
+
+/****************************************************************************/
+#ifdef SADISTIC_PAGE_ALLOC
+
+static void
+mem_set(unsigned char *p, unsigned char value, int n)
+{
+	while (n-- > 0)
+		*p++ = value;
+}
+
+static void
+mem_test(unsigned char *p, unsigned char value, int n)
+{
+	while (n-- > 0)
+		if (*p++ != value)
+			break;
+	if (n >= 0)
+		printk("free memory changed 0x%x, 0x%x != 0x%x\n",
+				(unsigned int) p - 1, *(p - 1), value);
+}
+
+#endif
+/****************************************************************************/
+
+void free_contiguous_pages(unsigned long addr, unsigned int num_adjpages)
+{
+	unsigned long map_nr = MAP_NR(addr);
+	unsigned long flags;
+
+	DBG_ALLOC("%s,%d: %s(0x%x, %d)\n", __FILE__, __LINE__, __FUNCTION__,
+			addr, num_adjpages);
+	if (map_nr < bit_map_size) {
+		int freed = 0;
+		mem_map_t *p, *ep;
+
+		p = mem_map + map_nr;
+
+		save_flags(flags);
+		cli();
+
+		if (!put_page_testzero(p)) {
+			restore_flags(flags);
+			return;
+		}
+
+		if (PageReserved(p)) /* we never hand out reserved pages */
+			BUG();
+		if (PageLRU(p)) {
+			/* DAVIDM - may need free_pages_ok_no_irq_head here */
+			lru_cache_del(p);
+		}
+
+
+		if (p->buffers)
+			BUG();
+		if (p->mapping)
+			BUG();
+		if (!VALID_PAGE(p))
+			BUG();
+		if (PageLocked(p))
+			BUG();
+		if (PageActive(p))
+			BUG();
+
+		for (ep = p + num_adjpages; p < ep; p++) {
+			p->flags &= ~((1<<PG_referenced) | (1<<PG_dirty));
+			p->flags &= ~(page_contig(p) << PG_first_free);
+#ifdef SADISTIC_PAGE_ALLOC
+			mem_set((char *) page_address(p), 0xdd, PAGE_SIZE);
+#endif
+			if (p-mem_map < first_usable_page)
+				first_usable_page = p-mem_map;
+			clear_bit(p-mem_map, bit_map);
+			set_page_count(p, 0);
+			freed++;
+			_nr_free_pages++;
+		}
+		restore_flags(flags);
+
+		if (waitqueue_active(&kswapd_wait))
+			wake_up_interruptible(&kswapd_wait);
+	}
+}
+
+/****************************************************************************/
+/*
+ * Amount of free RAM allocatable as buffer memory:
+ */
+
+unsigned int nr_free_buffer_pages (void)
+{
+	return _nr_free_pages + nr_active_pages + nr_inactive_pages;
+}
+
+/****************************************************************************/
+/*
+ *	We have to keep this interface as some parts of the kernel
+ *	source reference them directly
+ */
+
+unsigned long get_zeroed_page(unsigned int gfp_mask)
+{
+	struct page * page;
+
+	page = alloc_pages(gfp_mask, 0);
+	if (page) {
+		void *address = page_address(page);
+		clear_page(address);
+		return (unsigned long) address;
+	}
+	return 0;
+}
+
+void free_pages(unsigned long addr, unsigned int order)
+{
+	DBG_ALLOC("%s,%d: %s(0x%x, %d)\n", __FILE__, __LINE__, __FUNCTION__,
+			addr, order);
+	if (addr != 0)
+		__free_pages(virt_to_page(addr), order);
+}
+
+void __free_pages(struct page *page, unsigned int order)
+{
+	DBG_ALLOC("%s,%d: %s(0x%x[0x%x], %d)\n", __FILE__, __LINE__,
+			__FUNCTION__, page, page_address(page), order);
+
+	if (!PageReserved(page))
+		free_contiguous_pages((unsigned long) page_address(page), 1 << order);
+}
+
+struct page *_alloc_pages(unsigned int gfp_mask, unsigned int order)
+{
+	unsigned long addr;
+	DBG_ALLOC("%s,%d: %s(0x%x, %d)\n", __FILE__, __LINE__, __FUNCTION__,
+			gfp_mask, order);
+	addr = __get_contiguous_pages(gfp_mask, 1 << order, ALIGN_ORDER(order));
+	if (addr)
+		return(virt_to_page(addr));
+	return(NULL);
+}
+
+struct page * __alloc_pages(unsigned int gfp_mask, unsigned int order, zonelist_t *zonelist)
+{
+	unsigned long addr;
+	DBG_ALLOC("%s,%d: %s(0x%x, %d)\n", __FILE__, __LINE__, __FUNCTION__,
+			gfp_mask, order);
+	addr = __get_contiguous_pages(gfp_mask, 1 << order, ALIGN_ORDER(order));
+	if (addr)
+		return(virt_to_page(addr));
+	return(NULL);
+}
+
+/****************************************************************************/
+
+static void find_some_memory(int n)
+{
+	int loops = 0, i;
+	pg_data_t * pgdat;
+	zone_t * zone;
+
+	if (in_interrupt()) /* sorry, you lose */
+		return;
+
+	do {
+		pgdat = pgdat_list;
+		do {
+			for (i = pgdat->nr_zones-1; i >= 0; i--) {
+				zone = pgdat->node_zones + i;
+				zone->need_balance = 1;
+				try_to_free_pages_zone(zone, GFP_KSWAPD);
+			}
+		} while ((pgdat = pgdat->node_next));
+	} while (loops++ < n);
+}
+
+/****************************************************************************/
+/*
+ *	look through the map for a run of consecutive pages that will
+ *	hold a # of pages
+ */
+
+unsigned long
+__get_contiguous_pages(
+	unsigned int gfp_mask,
+	unsigned long num_adjpages,
+	unsigned int align_order)
+{
+	unsigned long	 flags;
+	mem_map_t		*p;
+	int              repeats = 0;
+	pg_data_t		*pgdat;
+	zone_t			*zone;
+
+#ifdef CONFIG_UNCACHED_MEM
+	int				 my_bit_map_size = bit_map_size - bit_map_size_special;
+	char			*my_bit_map = bit_map;
+#else
+	#define			 my_bit_map_size bit_map_size
+	#define			 my_bit_map bit_map
+#endif
+
+	DBG_ALLOC("%s,%d: %s(0x%x, %d, %d) - mem_map=0x%x\n", __FILE__, __LINE__,
+			__FUNCTION__, gfp_mask, num_adjpages, align_order, mem_map);
+	save_flags(flags);
+
+	if (waitqueue_active(&kswapd_wait))
+		wake_up_interruptible(&kswapd_wait);
+
+repeat:
+	cli();
+/*
+ *	Don't bother trying to find pages unless there are enough
+ *	for the given context
+ */
+	if (num_adjpages <= _nr_free_pages) {
+
+		int n = 0, topdown = 0, ff;
+
+		p = NULL;
+		
+#ifdef CONFIG_UNCACHED_MEM
+		/* check for switch to the special area at the end of RAM */
+		if (gfp_mask & GFP_SPECIAL) {
+			my_bit_map       = bit_map + bit_map_size_common/8;
+			my_bit_map_size  = bit_map_size_special;
+		}
+#endif
+		
+		if (num_adjpages > SMALL_ALLOC_PAGES) {
+			topdown = my_bit_map_size - num_adjpages;
+			ff = find_next_zero_bit(my_bit_map, my_bit_map_size, topdown);
+		} else
+			ff = find_next_zero_bit(my_bit_map, my_bit_map_size,
+#ifdef CONFIG_UNCACHED_MEM
+				(gfp_mask & GFP_SPECIAL) ? 0 : first_usable_page
+#else
+				first_usable_page
+#endif
+				);
+  
+		while (ff + num_adjpages <= my_bit_map_size || topdown > 0) {
+			if (ff + num_adjpages <= my_bit_map_size) {
+				p = mem_map + ff;
+#ifdef CONFIG_UNCACHED_MEM
+				if (gfp_mask & GFP_SPECIAL) /* convert to global page number */
+					p += bit_map_size_common;
+#endif
+				if (((unsigned long) page_address(p)) &
+						((PAGE_SIZE << align_order) - 1))
+					n = 0;
+				else
+					for (n = 0; n < num_adjpages; n++, p++) {
+						if (test_bit(p-mem_map, bit_map))
+							break;
+#if 0
+						if (dma && !PageDMA(p))
+							break;
+#endif
+					}
+				if (n >= num_adjpages)
+					break;
+			}
+			if (num_adjpages > SMALL_ALLOC_PAGES) {
+				topdown -= num_adjpages;
+				ff = find_next_zero_bit(my_bit_map, topdown+num_adjpages,
+						topdown);
+			} else
+				ff = find_next_zero_bit(my_bit_map, my_bit_map_size,
+						ff + n + 1);
+		}
+
+		if (p && n >= num_adjpages) {
+			_nr_free_pages -= num_adjpages;
+			while (n-- > 0) {
+				p--;
+#ifdef SADISTIC_PAGE_ALLOC
+				if (atomic_read(&p->count))
+					printk("allocated a non-free page\n");
+#endif
+				set_page_count(p, 1);
+				set_bit(p-mem_map, bit_map);
+				p->flags |= (num_adjpages << PG_first_free);
+				if (page_contig(p) != num_adjpages) {
+					printk("num=0x%lx flags=0x%lx\n", num_adjpages, p->flags);
+					BUG();
+				}
+			}
+#ifdef SADISTIC_PAGE_ALLOC
+			mem_test((char *) page_address(p), 0xdd, num_adjpages * PAGE_SIZE);
+			mem_set((char *) page_address(p), 0xcc, num_adjpages * PAGE_SIZE);
+#endif
+			DBG_ALLOC(" return(0x%x[p=0x%x])\n", page_address(p), p);
+			pgdat = pgdat_list;
+			do { /* try and keep memory freed */
+				int i;
+				for (i = pgdat->nr_zones-1; i >= 0; i--) {
+					zone = pgdat->node_zones + i;
+					zone->need_balance = 1;
+				}
+			} while ((pgdat = pgdat->node_next));
+			restore_flags(flags);
+			return((unsigned long) page_address(p));
+		}
+	}
+	restore_flags(flags);
+	if ((current->flags & PF_MEMALLOC) == 0) {
+		find_some_memory(3);
+		if (repeats++ < 3)
+			goto repeat;
+		printk("%s: allocation of %d pages failed!\n", current->comm,
+				(int) num_adjpages);
+#ifdef CONFIG_MEM_MAP
+		mem_map_read_proc(NULL, NULL, 0, 0, 0, 0);
+#endif
+	}
+	return(0);
+}
+
+/****************************************************************************/
+/*
+ *	as for free_pages,  we have to provide this one as well
+ */
+
+unsigned long __get_free_pages(unsigned int gfp_mask, unsigned int order)
+{
+	DBG_ALLOC("%s,%d: %s(0x%x, %d)\n", __FILE__, __LINE__, __FUNCTION__,
+			gfp_mask, order);
+	return(__get_contiguous_pages(gfp_mask, 1 << order, ALIGN_ORDER(order)));
+}
+
+/****************************************************************************/
+/*
+ *	dump some stats on how we are doing
+ */
+
+#define PRINTK(a...) (buffer ? (len+=sprintf(buffer+len, a)) : printk(a))
+#define FIXUP(t)	if (buffer && len >= count - 80) goto t; else
+
+static int
+print_free_areas(char *buffer, int count)
+{
+	int				len = 0;
+	mem_map_t		*p, *ep;
+ 	unsigned long	flags, slack;
+ 	unsigned long	min_free = bit_map_size * PAGE_SIZE;
+ 	unsigned long	min_used = bit_map_size * PAGE_SIZE;
+	unsigned long	max_free=0, avg_free=0, free_blks=0;
+	unsigned long	max_used=0, avg_used=0, used_blks=0;
+
+	find_some_memory(1);
+
+	if (realalloc)
+		slack = (realalloc-askedalloc) * 100 / realalloc;
+	else
+		slack = 0;
+	
+	save_flags(flags);
+	cli();
+
+	FIXUP(got_data);
+
+ 	for (p = mem_map, ep = p + bit_map_size; p < ep; ) {
+		int n;
+		
+		n = 0;
+
+		if (test_bit(p-mem_map, bit_map)) {
+			while (p < ep && test_bit(p-mem_map, bit_map)) {
+				n++;
+				p++;
+			}
+			avg_used += n;
+			if (n < min_used)
+				min_used = n;
+			if (n > max_used)
+				max_used = n;
+			used_blks++;
+		} else {
+			while (p < ep && !test_bit(p-mem_map, bit_map)) {
+				n++;
+				p++;
+			}
+			avg_free += n;
+			if (n < min_free)
+				min_free = n;
+			if (n > max_free)
+				max_free = n;
+			free_blks++;
+		}
+	}
+	
+	PRINTK("Active: %d, inactive: %d, free: %d\n",
+	       nr_active_pages, nr_inactive_pages, nr_free_pages());
+	FIXUP(got_data);
+	PRINTK("Free pages:%8d (%dkB), %%%lu frag, %%%lu slack\n",
+			_nr_free_pages, _nr_free_pages << (PAGE_SHIFT-10),
+			(free_blks * 100) / _nr_free_pages, slack);
+	FIXUP(got_data);
+	PRINTK("Free blks: %8lu min=%lu max=%lu avg=%lu\n",
+			free_blks, min_free, max_free, avg_free / free_blks);
+	FIXUP(got_data);
+	PRINTK("Used blks: %8lu min=%lu max=%lu avg=%lu\n",
+			used_blks, min_used, max_used, avg_used / used_blks);
+	FIXUP(got_data);
+
+got_data:
+	restore_flags(flags);
+	return(len);
+}
+
+#undef FIXUP
+#undef PRINTK
+/****************************************************************************/
+
+void
+show_free_areas(void)
+{
+	(void) print_free_areas(NULL, 0);
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_MEM_MAP)
+	(void) mem_map_read_proc(NULL, NULL, 0, 0, NULL, NULL);
+#endif
+}
+
+/****************************************************************************/
+
+/*
+ * Builds allocation fallback zone lists.
+ */
+static inline void build_zonelists(pg_data_t *pgdat)
+{
+	int i, j, k;
+
+	for (i = 0; i <= GFP_ZONEMASK; i++) {
+		zonelist_t *zonelist;
+		zone_t *zone;
+
+		zonelist = pgdat->node_zonelists + i;
+		memset(zonelist, 0, sizeof(*zonelist));
+
+		j = 0;
+		k = ZONE_NORMAL;
+		if (i & __GFP_HIGHMEM)
+			k = ZONE_HIGHMEM;
+		if (i & __GFP_DMA)
+			k = ZONE_DMA;
+
+		switch (k) {
+			default:
+				BUG();
+			/*
+			 * fallthrough:
+			 */
+			case ZONE_HIGHMEM:
+				zone = pgdat->node_zones + ZONE_HIGHMEM;
+				if (zone->size) {
+#ifndef CONFIG_HIGHMEM
+					BUG();
+#endif
+					zonelist->zones[j++] = zone;
+				}
+			case ZONE_NORMAL:
+				zone = pgdat->node_zones + ZONE_NORMAL;
+				if (zone->size)
+					zonelist->zones[j++] = zone;
+			case ZONE_DMA:
+				zone = pgdat->node_zones + ZONE_DMA;
+				if (zone->size)
+					zonelist->zones[j++] = zone;
+		}
+		zonelist->zones[j++] = NULL;
+	} 
+}
+
+/****************************************************************************/
+#if CONFIG_HIGHMEM
+
+unsigned int nr_free_highpages (void)
+{
+	pg_data_t *pgdat;
+	unsigned int pages = 0;
+
+	for_each_pgdat(pgdat)
+		pages += pgdat->node_zones[ZONE_HIGHMEM].free_pages;
+
+	return pages;
+}
+
+unsigned int freeable_lowmem(void)
+{
+	unsigned int pages = 0;
+	pg_data_t *pgdat;
+
+	for_each_pgdat(pgdat) {
+		pages += pgdat->node_zones[ZONE_DMA].free_pages;
+		pages += pgdat->node_zones[ZONE_DMA].nr_active_pages;
+		pages += pgdat->node_zones[ZONE_DMA].nr_inactive_pages;
+		pages += pgdat->node_zones[ZONE_NORMAL].free_pages;
+		pages += pgdat->node_zones[ZONE_NORMAL].nr_active_pages;
+		pages += pgdat->node_zones[ZONE_NORMAL].nr_inactive_pages;
+	}
+
+	return pages;
+}
+
+#endif
+/****************************************************************************/
+/*
+ * Helper functions to size the waitqueue hash table.
+ * Essentially these want to choose hash table sizes sufficiently
+ * large so that collisions trying to wait on pages are rare.
+ * But in fact, the number of active page waitqueues on typical
+ * systems is ridiculously low, less than 200. So this is even
+ * conservative, even though it seems large.
+ *
+ * The constant PAGES_PER_WAITQUEUE specifies the ratio of pages to
+ * waitqueues, i.e. the size of the waitq table given the number of pages.
+ */
+
+#define PAGES_PER_WAITQUEUE	256
+
+static inline unsigned long wait_table_size(unsigned long pages)
+{
+	unsigned long size = 1;
+
+	pages /= PAGES_PER_WAITQUEUE;
+
+	while (size < pages)
+		size <<= 1;
+
+	/*
+	 * Once we have dozens or even hundreds of threads sleeping
+	 * on IO we've got bigger problems than wait queue collision.
+	 * Limit the size of the wait table to a reasonable size.
+	 */
+	size = min(size, 4096UL);
+
+	return size;
+}
+
+/*
+ * This is an integer logarithm so that shifts can be used later
+ * to extract the more random high bits from the multiplicative
+ * hash function before the remainder is taken.
+ */
+static inline unsigned long wait_table_bits(unsigned long size)
+{
+	return ffz(~size);
+}
+
+
+#define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
+
+/****************************************************************************/
+/*
+ * Set up the zone data structures:
+ *   - mark all pages reserved
+ *   - mark all memory queues empty
+ *   - clear the memory bitmaps
+ *
+ * static in this version because I haven't though it out yet ;-)
+ */
+
+void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
+	unsigned long *zones_size, unsigned long zone_start_paddr, 
+	unsigned long *zholes_size, struct page *lmem_map)
+{
+	unsigned long i, j;
+	unsigned long map_size;
+	unsigned long totalpages, offset, realtotalpages;
+	const unsigned long zone_required_alignment = 1UL << (MAX_ORDER-1);
+
+	if (zone_start_paddr & ~PAGE_MASK)
+		BUG();
+
+	totalpages = 0;
+	for (i = 0; i < MAX_NR_ZONES; i++) {
+		unsigned long size = zones_size[i];
+		totalpages += size;
+	}
+	realtotalpages = totalpages;
+	if (zholes_size)
+		for (i = 0; i < MAX_NR_ZONES; i++)
+			realtotalpages -= zholes_size[i];
+			
+	printk("On node %d totalpages: %lu\n", nid, realtotalpages);
+
+	INIT_LIST_HEAD(&active_list);
+	INIT_LIST_HEAD(&inactive_list);
+
+	/*
+	 * Some architectures (with lots of mem and discontinous memory
+	 * maps) have to search for a good mem_map area:
+	 * For discontigmem, the conceptual mem map array starts from 
+	 * PAGE_OFFSET, we need to align the actual array onto a mem map 
+	 * boundary, so that MAP_NR works.
+	 */
+	map_size = (totalpages + 1)*sizeof(struct page);
+	if (lmem_map == (struct page *)0) {
+		lmem_map = (struct page *) alloc_bootmem_node(pgdat, map_size);
+		lmem_map = (struct page *)(PAGE_OFFSET + 
+			MAP_ALIGN((unsigned long)lmem_map - PAGE_OFFSET));
+	}
+	*gmap = pgdat->node_mem_map = lmem_map;
+	pgdat->node_size = totalpages;
+	pgdat->node_start_paddr = zone_start_paddr;
+	pgdat->node_start_mapnr = (lmem_map - mem_map);
+	pgdat->nr_zones = 0;
+
+	/*
+	 *	as we free pages we mark the first page that is usable
+	 */
+	bit_map_size = totalpages;
+	bit_map = (unsigned char *)
+			alloc_bootmem_node(pgdat, LONG_ALIGN(bit_map_size / 8));
+	memset(bit_map, 0, LONG_ALIGN(bit_map_size / 8));
+
+#ifdef CONFIG_UNCACHED_MEM
+	bit_map_size_common = bit_map_size - bit_map_size_special;
+#endif
+
+	/*
+	 * Initially all pages are reserved - free ones are freed
+	 * up by free_all_bootmem() once the early boot process is
+	 * done.
+	 */
+
+	first_usable_page = totalpages;
+
+	offset = lmem_map - mem_map;	
+	for (j = 0; j < MAX_NR_ZONES; j++) {
+		zone_t *zone = pgdat->node_zones + j;
+		unsigned long mask;
+		unsigned long size, realsize;
+		int idx;
+
+		zone_table[nid * MAX_NR_ZONES + j] = zone;
+		realsize = size = zones_size[j];
+		if (zholes_size)
+			realsize -= zholes_size[j];
+
+		printk("zone(%lu): %lu pages.\n", j, size);
+		zone->size = size;
+		zone->realsize = realsize;
+		zone->name = zone_names[j];
+		zone->lock = SPIN_LOCK_UNLOCKED;
+		zone->zone_pgdat = pgdat;
+		zone->free_pages = 0;
+		zone->need_balance = 0;
+		zone->nr_active_pages = zone->nr_inactive_pages = 0;
+
+
+		if (!size)
+			continue;
+
+		/*
+		 * The per-page waitqueue mechanism uses hashed waitqueues
+		 * per zone.
+		 */
+		zone->wait_table_size = wait_table_size(size);
+		zone->wait_table_shift =
+			BITS_PER_LONG - wait_table_bits(zone->wait_table_size);
+		zone->wait_table = (wait_queue_head_t *)
+			alloc_bootmem_node(pgdat, zone->wait_table_size
+						* sizeof(wait_queue_head_t));
+
+		for(i = 0; i < zone->wait_table_size; ++i)
+			init_waitqueue_head(zone->wait_table + i);
+
+		pgdat->nr_zones = j+1;
+
+		zone->watermarks[j].min = 0; /* agressive values */
+		zone->watermarks[j].low = 0;
+		zone->watermarks[j].high = realsize;
+		/* now set the watermarks of the lower zones in the "j" classzone */
+		for (idx = j-1; idx >= 0; idx--) {
+			zone_t * lower_zone = pgdat->node_zones + idx;
+			unsigned long lower_zone_reserve;
+			if (!lower_zone->size)
+				continue;
+
+			mask = lower_zone->watermarks[idx].min;
+			lower_zone->watermarks[j].min = 0;
+			lower_zone->watermarks[j].low = 0;
+			lower_zone->watermarks[j].high = realsize;
+
+			/* now the brainer part */
+			lower_zone_reserve = realsize / lower_zone_reserve_ratio[idx];
+			lower_zone->watermarks[j].min += lower_zone_reserve;
+			lower_zone->watermarks[j].low += lower_zone_reserve;
+			lower_zone->watermarks[j].high += lower_zone_reserve;
+
+			realsize += lower_zone->realsize;
+		}
+
+		zone->zone_mem_map = mem_map + offset;
+		zone->zone_start_mapnr = offset;
+		zone->zone_start_paddr = zone_start_paddr;
+
+		if ((zone_start_paddr >> PAGE_SHIFT) & (zone_required_alignment-1))
+			printk("BUG: wrong zone alignment, it will crash\n");
+
+		/*
+		 * Initially all pages are reserved - free ones are freed
+		 * up by free_all_bootmem() once the early boot process is
+		 * done. Non-atomic initialization, single-pass.
+		 */
+		for (i = 0; i < size; i++) {
+			struct page *page = mem_map + offset + i;
+			set_page_zone(page, nid * MAX_NR_ZONES + j);
+			set_page_count(page, 0);
+			SetPageReserved(page);
+			set_bit(page-mem_map, bit_map);
+			INIT_LIST_HEAD(&page->list);
+			if (j != ZONE_HIGHMEM)
+				set_page_address(page, __va(zone_start_paddr));
+			zone_start_paddr += PAGE_SIZE;
+		}
+
+		offset += size;
+	}
+	build_zonelists(pgdat);
+}
+
+/****************************************************************************/
+
+void __init free_area_init(unsigned long *zones_size)
+{
+	free_area_init_core(0, &contig_page_data, &mem_map, zones_size, 0, 0, 0);
+}
+
+/****************************************************************************/
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_MEM_MAP)
+/****************************************************************************/
+/*
+ *	A small tool to help debug/display memory allocation problems
+ *	Creates /proc/mem_map,  an ascii representation of what each
+ *	page in memory is being used for.  It displays the address of the
+ *	memory down the left column and 64 pages per line (ie., 256K).
+ *
+ *	If you want better reporting,  define MEGA_HACK below and then
+ *	find all the referenced FS routines in the kernel and remove static
+ *	from their definition (see page_alloc2.hack for patch).
+ *
+ *	Obviously this code needs proc_fs,  but it is trivial to make it
+ *	use printk and always include it.
+ *
+ *	KEY:
+ *
+ *	  Normal letters
+ *	  --------------
+ *		-         free
+ *	    R         reserved (usually the kernel/mem_map/bitmap)
+ *		X         owned by a device/fs (see MEGA_HACK code)
+ *		S         swap cache
+ *		L         locked
+ *		A         Active
+ *		U         LRU
+ *		s         owned by the slab allocator
+ *		r         referenced
+ *		C         non zero count
+ *		?         who knows ?
+ *
+ *	  Contiguous Page Alloc
+ *	  ---------------------
+ *		1         a single page_alloc2 page
+ *		[=*]      contigous pages allocated by page_alloc2
+ *
+ *	  MEGA HACK values
+ *	  ---------------------
+ *		*         ram disk
+ *		#         romfs
+ *		M         minix
+ *		%         ext2
+ *		B         block dev (cache etc)
+ *
+ *	TODO:
+ *	   print process name for contiguous blocks
+ */  
+/****************************************************************************/
+
+#if 0
+#define MEGA_HACK 1
+#endif
+
+/****************************************************************************/
+
+#define PRINTK(a...) (page ? (len += sprintf(page + len, a)) : printk(a))
+
+#define FIXUP(t)				\
+	if (page) {					\
+		if (len <= off) {		\
+			off -= len;		\
+			len = 0;		\
+		} else {			\
+			if (len-off > count - 80)	\
+				goto t;		\
+		}				\
+	} else
+
+
+static int
+mem_map_read_proc(char *page, char **start, off_t off,
+				 int count, int *eof, void *data)
+{
+	int len = 0;
+	struct page *p, *ep;
+	int cols;
+	int flags;
+
+	save_flags(flags);
+	cli();
+
+	FIXUP(got_data);
+
+	cols = 0;
+ 	for (p = mem_map, ep = p + bit_map_size; p < ep; p++) {
+#ifdef MEGA_HACK
+		extern int blkdev_readpage(struct page *page);
+# ifdef CONFIG_BLK_DEV_RAM
+		extern int ramdisk_readpage(struct page *page);
+# endif
+# ifdef CONFIG_ROMFS_FS
+		extern int romfs_readpage(struct page *page);
+# endif
+# ifdef CONFIG_EXT2_FS
+		extern int ext2_readpage(struct page *page);
+# endif
+# ifdef CONFIG_MINIX_FS
+		extern int minix_readpage(struct page *page);
+# endif
+#endif
+
+		if (cols == 0)
+			PRINTK("0x%08x: ",(unsigned)page_address(p));
+		if (test_bit(p-mem_map, bit_map)) {
+			if (PageReserved(p))
+				PRINTK("R");
+			else if (p->mapping && p->mapping->a_ops) {
+#ifdef MEGA_HACK
+				if (p->mapping->a_ops->readpage == blkdev_readpage)
+					PRINTK("B");
+				else
+# ifdef CONFIG_BLK_DEV_RAM
+				if (p->mapping->a_ops->readpage == ramdisk_readpage)
+					PRINTK("*");
+				else
+# endif
+# ifdef CONFIG_ROMFS_FS
+				if (p->mapping->a_ops->readpage == romfs_readpage)
+					PRINTK("#");
+				else
+# endif
+# ifdef CONFIG_MINIX_FS
+				if (p->mapping->a_ops->readpage == minix_readpage)
+					PRINTK("M");
+				else
+# endif
+# ifdef CONFIG_EXT2_FS
+				if (p->mapping->a_ops->readpage == ext2_readpage)
+					PRINTK("%");
+				else
+# endif
+#endif
+					PRINTK("X");
+			} else if (PageSwapCache(p))
+				PRINTK("S");
+			else if (PageLocked(p))
+				PRINTK("L");
+			else if (PageActive(p))
+				PRINTK("A");
+			else if (PageLRU(p))
+				PRINTK("U");
+			else if (PageSlab(p))
+				PRINTK("s");
+			else if (p->flags & (1<<PG_referenced))
+				PRINTK("r");
+			else if (atomic_read(&p->count)) {
+#ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
+				if (page_contig(p)) {
+					if (page_contig(p) == 1)
+						PRINTK("1");
+					else {
+						int i = page_contig(p);
+						PRINTK("["); p++; i--; cols++;
+						if (cols >= 64) {
+							PRINTK("\n");
+							cols = 0;
+							FIXUP(got_data);
+						}
+						while (i > 1) {
+							if (cols == 0)
+								PRINTK("0x%08x: ",(unsigned)page_address(p));
+							PRINTK("="); p++; i--; cols++;
+							if (cols >= 64) {
+								PRINTK("\n");
+								cols = 0;
+								FIXUP(got_data);
+							}
+						}
+						if (cols == 0)
+							PRINTK("0x%08x: ",(unsigned)page_address(p));
+						PRINTK("]");
+					}
+				} else
+#endif
+					PRINTK("C");
+			} else
+				PRINTK("?");
+		} else
+			PRINTK("-");
+		cols++;
+		if (cols >= 64) {
+			PRINTK("\n");
+			cols = 0;
+			FIXUP(got_data);
+		}
+	}
+	if (cols)
+		PRINTK("\n");
+	FIXUP(got_data);
+	PRINTK("\n");
+	FIXUP(got_data);
+
+{
+	unsigned long total_bytes = 0, total_sbytes = 0, total_slack = 0;
+	struct task_struct *p;
+
+	for_each_task(p) {
+		struct mm_struct *mm = p->mm;
+		unsigned long bytes = 0, sbytes = 0, slack = 0;
+		struct mm_tblock_struct * tblock;
+
+		if (!mm)
+			continue;
+        
+		for (tblock = &mm->tblock; tblock; tblock = tblock->next) {
+			if (tblock->rblock) {
+				bytes += ksize(tblock);
+				if (atomic_read(&mm->mm_count) > 1 ||
+						tblock->rblock->refcount > 1) {
+					sbytes += ksize(tblock->rblock->kblock);
+					sbytes += ksize(tblock->rblock) ;
+				} else {
+					bytes += ksize(tblock->rblock->kblock);
+					bytes += ksize(tblock->rblock) ;
+					slack += ksize(tblock->rblock->kblock) - tblock->rblock->size;
+				}
+			}
+		}
+		
+		((atomic_read(&mm->mm_count) > 1) ? sbytes : bytes)
+				+= ksize(mm);
+		(current->fs && atomic_read(&current->fs->count) > 1 ? sbytes : bytes)
+				+= ksize(current->fs);
+		(current->files && atomic_read(&current->files->count) > 1 ? sbytes : bytes)
+				+= ksize(current->files);
+		(current->sig && atomic_read(&current->sig->count) > 1 ? sbytes : bytes)
+				+= ksize(current->sig);
+		bytes += ksize(current); /* includes kernel stack */
+
+		PRINTK("%-16s Mem:%8lu Slack:%8lu Shared:%8lu\n", p->comm, bytes,
+				slack, sbytes);
+		FIXUP(got_data);
+		total_slack += slack;
+		total_sbytes += sbytes;
+		total_bytes += bytes;
+	}
+	PRINTK("%-16s Mem:%8lu Slack:%8lu Shared:%8lu\n\n", "Total", total_bytes,
+				total_slack, total_sbytes);
+	FIXUP(got_data);
+}
+
+	len += print_free_areas(page + len, count - len);
+	FIXUP(got_data);
+
+got_data:
+	restore_flags(flags);
+	
+	if (page) {
+		*start = page+off;
+
+		len -= (*start-page);
+		if (len <= count - 80)
+			*eof = 1;
+		if (len>count) len = count;
+		if (len<0) len = 0;
+	}
+	return(len);
+}
+
+#undef FIXUP
+#undef PRINTK
+/****************************************************************************/
+
+static __init int
+page_alloc2_init(void)
+{
+	create_proc_read_entry("mem_map", S_IWUSR | S_IRUGO, NULL,
+			mem_map_read_proc, NULL);
+	return(0);
+}
+
+/****************************************************************************/
+
+module_init(page_alloc2_init);
+
+/****************************************************************************/
+#endif /* CONFIG_PROC_FS && CONFIG_MEM_MAP */
+/****************************************************************************/
diff -urN linux-2.4.29/mmnommu/page_alloc2.hack linux-2.4.29-uc1/mmnommu/page_alloc2.hack
--- linux-2.4.29/mmnommu/page_alloc2.hack	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/page_alloc2.hack	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,64 @@
+Index: fs/block_dev.c
+===================================================================
+RCS file: /cvs/sw/linux-2.4.x/fs/block_dev.c,v
+retrieving revision 1.1.1.4
+diff -u -r1.1.1.4 block_dev.c
+--- fs/block_dev.c	7 Jan 2002 23:15:54 -0000	1.1.1.4
++++ fs/block_dev.c	5 Feb 2002 01:55:11 -0000
+@@ -123,7 +123,7 @@
+ 	return block_write_full_page(page, blkdev_get_block);
+ }
+ 
+-static int blkdev_readpage(struct file * file, struct page * page)
++int blkdev_readpage(struct file * file, struct page * page)
+ {
+ 	return block_read_full_page(page, blkdev_get_block);
+ }
+Index: fs/ext2/inode.c
+===================================================================
+RCS file: /cvs/sw/linux-2.4.x/fs/ext2/inode.c,v
+retrieving revision 1.1.1.4
+diff -u -r1.1.1.4 inode.c
+--- fs/ext2/inode.c	7 Jan 2002 23:15:55 -0000	1.1.1.4
++++ fs/ext2/inode.c	5 Feb 2002 01:55:12 -0000
+@@ -580,7 +580,7 @@
+ {
+ 	return block_write_full_page(page,ext2_get_block);
+ }
+-static int ext2_readpage(struct file *file, struct page *page)
++int ext2_readpage(struct file *file, struct page *page)
+ {
+ 	return block_read_full_page(page,ext2_get_block);
+ }
+Index: fs/romfs/inode.c
+===================================================================
+RCS file: /cvs/sw/linux-2.4.x/fs/romfs/inode.c,v
+retrieving revision 1.3
+diff -u -r1.3 inode.c
+--- fs/romfs/inode.c	8 Jan 2002 00:51:17 -0000	1.3
++++ fs/romfs/inode.c	5 Feb 2002 01:55:13 -0000
+@@ -390,7 +390,7 @@
+  * we can't use bmap, since we may have looser alignments.
+  */
+ 
+-static int
++int
+ romfs_readpage(struct file *file, struct page * page)
+ {
+ 	struct inode *inode = page->mapping->host;
+Index: drivers/block/rd.c
+===================================================================
+RCS file: /cvs/sw/linux-2.4.x/drivers/block/rd.c,v
+retrieving revision 1.1.1.3
+diff -u -r1.1.1.3 rd.c
+--- drivers/block/rd.c	7 Jan 2002 23:15:32 -0000	1.1.1.3
++++ drivers/block/rd.c	5 Feb 2002 01:55:14 -0000
+@@ -191,7 +191,7 @@
+  *               2000 Transmeta Corp.
+  * aops copied from ramfs.
+  */
+-static int ramdisk_readpage(struct file *file, struct page * page)
++int ramdisk_readpage(struct file *file, struct page * page)
+ {
+ 	if (!Page_Uptodate(page)) {
+ 		memset(kmap(page), 0, PAGE_CACHE_SIZE);
diff -urN linux-2.4.29/mmnommu/page_alloc.c linux-2.4.29-uc1/mmnommu/page_alloc.c
--- linux-2.4.29/mmnommu/page_alloc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/page_alloc.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,1007 @@
+/*
+ *  linux/mm/page_alloc.c
+ *
+ *  Manages the free list, the system allocates free pages here.
+ *  Note that kmalloc() lives in slab.c
+ *
+ *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ *  Swap reorganised 29.12.95, Stephen Tweedie
+ *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
+ *  Reshaped it to be a zoned allocator, Ingo Molnar, Red Hat, 1999
+ *  Discontiguous memory support, Kanoj Sarcar, SGI, Nov 1999
+ *  Zone balancing, Kanoj Sarcar, SGI, Jan 2000
+ *  Copyright (c) 2001 Lineo Inc., David McCullough <davidm@lineo.com>
+ *  Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org> ref uClinux 2.0
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/swapctl.h>
+#include <linux/interrupt.h>
+#include <linux/pagemap.h>
+#include <linux/bootmem.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+int nr_swap_pages;
+int nr_active_pages;
+int nr_inactive_pages;
+LIST_HEAD(inactive_list);
+LIST_HEAD(active_list);
+pg_data_t *pgdat_list;
+
+/*
+ *
+ * The zone_table array is used to look up the address of the
+ * struct zone corresponding to a given zone number (ZONE_DMA,
+ * ZONE_NORMAL, or ZONE_HIGHMEM).
+ */
+zone_t *zone_table[MAX_NR_ZONES*MAX_NR_NODES];
+EXPORT_SYMBOL(zone_table);
+
+static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
+static int zone_balance_ratio[MAX_NR_ZONES] __initdata = { 128, 128, 128, };
+static int zone_balance_min[MAX_NR_ZONES] __initdata = { 20 , 20, 20, };
+static int zone_balance_max[MAX_NR_ZONES] __initdata = { 255 , 255, 255, };
+static int lower_zone_reserve_ratio[MAX_NR_ZONES-1] = { 256, 32 };
+
+int vm_gfp_debug = 0;
+
+static void FASTCALL(__free_pages_ok (struct page *page, unsigned int order));
+
+static spinlock_t free_pages_ok_no_irq_lock = SPIN_LOCK_UNLOCKED;
+struct page * free_pages_ok_no_irq_head;
+
+static void do_free_pages_ok_no_irq(void * arg)
+{
+       struct page * page, * __page;
+
+       spin_lock_irq(&free_pages_ok_no_irq_lock);
+
+       page = free_pages_ok_no_irq_head;
+       free_pages_ok_no_irq_head = NULL;
+
+       spin_unlock_irq(&free_pages_ok_no_irq_lock);
+
+       while (page) {
+               __page = page;
+               page = page->next_hash;
+               __free_pages_ok(__page, __page->index);
+       }
+}
+
+static struct tq_struct free_pages_ok_no_irq_task = {
+       .routine        = do_free_pages_ok_no_irq,
+};
+
+
+/*
+ * Temporary debugging check.
+ */
+#define BAD_RANGE(zone, page)						\
+(									\
+	(((page) - mem_map) >= ((zone)->zone_start_mapnr+(zone)->size))	\
+	|| (((page) - mem_map) < (zone)->zone_start_mapnr)		\
+	|| ((zone) != page_zone(page))					\
+)
+
+/*
+ * Freeing function for a buddy system allocator.
+ * Contrary to prior comments, this is *NOT* hairy, and there
+ * is no reason for anyone not to understand it.
+ *
+ * The concept of a buddy system is to maintain direct-mapped tables
+ * (containing bit values) for memory blocks of various "orders".
+ * The bottom level table contains the map for the smallest allocatable
+ * units of memory (here, pages), and each level above it describes
+ * pairs of units from the levels below, hence, "buddies".
+ * At a high level, all that happens here is marking the table entry
+ * at the bottom level available, and propagating the changes upward
+ * as necessary, plus some accounting needed to play nicely with other
+ * parts of the VM system.
+ * At each level, we keep one bit for each pair of blocks, which
+ * is set to 1 iff only one of the pair is allocated.  So when we
+ * are allocating or freeing one, we can derive the state of the
+ * other.  That is, if we allocate a small block, and both were   
+ * free, the remainder of the region must be split into blocks.   
+ * If a block is freed, and its buddy is also free, then this
+ * triggers coalescing into a block of larger size.            
+ *
+ * -- wli
+ */
+
+static void fastcall __free_pages_ok (struct page *page, unsigned int order)
+{
+	unsigned long index, page_idx, mask, flags;
+	free_area_t *area;
+	struct page *base;
+	zone_t *zone;
+
+	/*
+	 * Subtle. We do not want to test this in the inlined part of
+	 * __free_page() - it's a rare condition and just increases
+	 * cache footprint unnecesserily. So we do an 'incorrect'
+	 * decrement on page->count for reserved pages, but this part
+	 * makes it safe.
+	 */
+	if (PageReserved(page))
+		return;
+
+	/*
+	 * Yes, think what happens when other parts of the kernel take 
+	 * a reference to a page in order to pin it for io. -ben
+	 */
+	if (PageLRU(page)) {
+		if (unlikely(in_interrupt())) {
+			unsigned long flags;
+
+			spin_lock_irqsave(&free_pages_ok_no_irq_lock, flags);
+			page->next_hash = free_pages_ok_no_irq_head;
+			free_pages_ok_no_irq_head = page;
+			page->index = order;
+	
+			spin_unlock_irqrestore(&free_pages_ok_no_irq_lock, flags);
+	
+			schedule_task(&free_pages_ok_no_irq_task);
+			return;
+		}
+		
+		lru_cache_del(page);
+	}
+
+	if (page->buffers)
+		BUG();
+	if (page->mapping)
+		BUG();
+	if (!VALID_PAGE(page))
+		BUG();
+	if (PageLocked(page))
+		BUG();
+	if (PageActive(page))
+		BUG();
+
+	ClearPageReferenced(page);
+	ClearPageDirty(page);
+
+	/* de-reference all the pages for this order */
+	for (page_idx = 1; page_idx < (1 << order); page_idx++)
+		set_page_count(&page[page_idx], 0);
+
+	if (current->flags & PF_FREE_PAGES)
+		goto local_freelist;
+ back_local_freelist:
+
+	zone = page_zone(page);
+
+	mask = (~0UL) << order;
+	base = zone->zone_mem_map;
+	page_idx = page - base;
+	if (page_idx & ~mask)
+		BUG();
+	index = page_idx >> (1 + order);
+
+	area = zone->free_area + order;
+
+	spin_lock_irqsave(&zone->lock, flags);
+
+	zone->free_pages -= mask;
+
+	while (mask + (1 << (MAX_ORDER-1))) {
+		struct page *buddy1, *buddy2;
+
+		if (area >= zone->free_area + MAX_ORDER)
+			BUG();
+		if (!__test_and_change_bit(index, area->map))
+			/*
+			 * the buddy page is still allocated.
+			 */
+			break;
+		/*
+		 * Move the buddy up one level.
+		 * This code is taking advantage of the identity:
+		 * 	-mask = 1+~mask
+		 */
+		buddy1 = base + (page_idx ^ -mask);
+		buddy2 = base + page_idx;
+		if (BAD_RANGE(zone,buddy1))
+			BUG();
+		if (BAD_RANGE(zone,buddy2))
+			BUG();
+
+		list_del(&buddy1->list);
+		mask <<= 1;
+		area++;
+		index >>= 1;
+		page_idx &= mask;
+	}
+	list_add(&(base + page_idx)->list, &area->free_list);
+
+	spin_unlock_irqrestore(&zone->lock, flags);
+	return;
+
+ local_freelist:
+	if (current->nr_local_pages)
+		goto back_local_freelist;
+	if (in_interrupt())
+		goto back_local_freelist;		
+
+	list_add(&page->list, &current->local_pages);
+	page->index = order;
+	current->nr_local_pages++;
+}
+
+#define MARK_USED(index, order, area) \
+	__change_bit((index) >> (1+(order)), (area)->map)
+
+static inline struct page * expand (zone_t *zone, struct page *page,
+	 unsigned long index, int low, int high, free_area_t * area)
+{
+	unsigned long size = 1 << high;
+
+	while (high > low) {
+		if (BAD_RANGE(zone,page))
+			BUG();
+		area--;
+		high--;
+		size >>= 1;
+		list_add(&(page)->list, &(area)->free_list);
+		MARK_USED(index, high, area);
+		index += size;
+		page += size;
+	}
+	if (BAD_RANGE(zone,page))
+		BUG();
+	return page;
+}
+
+static FASTCALL(struct page * rmqueue(zone_t *zone, unsigned int order));
+static struct page * fastcall rmqueue(zone_t *zone, unsigned int order)
+{
+	free_area_t * area = zone->free_area + order;
+	unsigned int curr_order = order;
+	struct list_head *head, *curr;
+	unsigned long flags;
+	struct page *page;
+	int i;
+
+	spin_lock_irqsave(&zone->lock, flags);
+	do {
+		head = &area->free_list;
+		curr = head->next;
+
+		if (curr != head) {
+			unsigned int index;
+
+			page = list_entry(curr, struct page, list);
+			if (BAD_RANGE(zone,page))
+				BUG();
+			list_del(curr);
+			index = page - zone->zone_mem_map;
+			if (curr_order != MAX_ORDER-1)
+				MARK_USED(index, curr_order, area);
+			zone->free_pages -= 1UL << order;
+
+			page = expand(zone, page, index, order, curr_order, area);
+			spin_unlock_irqrestore(&zone->lock, flags);
+
+			set_page_count(page, 1);
+			if (BAD_RANGE(zone,page))
+				BUG();
+			if (PageLRU(page))
+				BUG();
+			if (PageActive(page))
+				BUG();
+
+			/*
+			 * we need to reference all the pages for this order,
+			 * otherwise if anyone accesses one of the pages with
+			 * (get/put) it * will be freed :-(
+			 */
+			for (i = 1; i < (1 << order); i++)
+				set_page_count(&page[i], 1);
+
+			return page;	
+		}
+		curr_order++;
+		area++;
+	} while (curr_order < MAX_ORDER);
+	spin_unlock_irqrestore(&zone->lock, flags);
+
+	return NULL;
+}
+
+#ifndef CONFIG_DISCONTIGMEM
+struct page * fastcall _alloc_pages(unsigned int gfp_mask, unsigned int order)
+{
+	return __alloc_pages(gfp_mask, order,
+		contig_page_data.node_zonelists+(gfp_mask & GFP_ZONEMASK));
+}
+#endif
+
+static struct page * FASTCALL(balance_classzone(zone_t *, unsigned int, unsigned int, int *));
+static struct page * fastcall balance_classzone(zone_t * classzone, unsigned int gfp_mask, unsigned int order, int * freed)
+{
+	struct page * page = NULL;
+	int __freed, i;
+
+	if (in_interrupt())
+		BUG();
+
+	current->allocation_order = order;
+	current->flags |= PF_MEMALLOC | PF_FREE_PAGES;
+
+	__freed = try_to_free_pages_zone(classzone, gfp_mask);
+
+	current->flags &= ~(PF_MEMALLOC | PF_FREE_PAGES);
+
+	if (current->nr_local_pages) {
+		struct list_head * entry, * local_pages;
+		struct page * tmp;
+		int nr_pages;
+
+		local_pages = &current->local_pages;
+
+		if (likely(__freed)) {
+			/* pick from the last inserted so we're lifo */
+			entry = local_pages->next;
+			do {
+				tmp = list_entry(entry, struct page, list);
+				if (tmp->index == order && memclass(page_zone(tmp), classzone)) {
+					list_del(entry);
+					current->nr_local_pages--;
+					set_page_count(tmp, 1);
+
+					page = tmp;
+
+					/*
+					 * we need to reference all the pages for this order,
+					 * otherwise if anyone accesses one of the pages with
+					 * (get/put) it * will be freed :-(
+					 */
+					for (i = 1; i < (1 << order); i++)
+						set_page_count(&page[i], 1);
+
+					if (page->buffers)
+						BUG();
+					if (page->mapping)
+						BUG();
+					if (!VALID_PAGE(page))
+						BUG();
+					if (PageLocked(page))
+						BUG();
+					if (PageLRU(page))
+						BUG();
+					if (PageActive(page))
+						BUG();
+					if (PageDirty(page))
+						BUG();
+
+					break;
+				}
+			} while ((entry = entry->next) != local_pages);
+		}
+
+		nr_pages = current->nr_local_pages;
+		/* free in reverse order so that the global order will be lifo */
+		while ((entry = local_pages->prev) != local_pages) {
+			list_del(entry);
+			tmp = list_entry(entry, struct page, list);
+			__free_pages_ok(tmp, tmp->index);
+			if (!nr_pages--)
+				BUG();
+		}
+		current->nr_local_pages = 0;
+	}
+
+	*freed = __freed;
+	return page;
+}
+
+static inline unsigned long zone_free_pages(zone_t * zone, unsigned int order)
+{
+	long free = zone->free_pages - (1UL << order);
+	return free >= 0 ? free : 0;
+}
+
+/*
+ * This is the 'heart' of the zoned buddy allocator:
+ */
+struct page * fastcall __alloc_pages(unsigned int gfp_mask, unsigned int order, zonelist_t *zonelist)
+{
+	zone_t **zone, * classzone;
+	struct page * page;
+	int freed, class_idx;
+
+	zone = zonelist->zones;
+	classzone = *zone;
+	class_idx = zone_idx(classzone);
+
+	for (;;) {
+		zone_t *z = *(zone++);
+		if (!z)
+			break;
+
+		if (zone_free_pages(z, order) > z->watermarks[class_idx].low) {
+			page = rmqueue(z, order);
+			if (page)
+				return page;
+		}
+	}
+
+	classzone->need_balance = 1;
+	mb();
+	if (waitqueue_active(&kswapd_wait))
+		wake_up_interruptible(&kswapd_wait);
+
+	zone = zonelist->zones;
+	for (;;) {
+		unsigned long min;
+		zone_t *z = *(zone++);
+		if (!z)
+			break;
+
+		min = z->watermarks[class_idx].min;
+		if (!(gfp_mask & __GFP_WAIT))
+			min >>= 2;
+		if (zone_free_pages(z, order) > min) {
+			page = rmqueue(z, order);
+			if (page)
+				return page;
+		}
+	}
+
+	/* here we're in the low on memory slow path */
+
+	if ((current->flags & PF_MEMALLOC) && 
+			(!in_interrupt() || (current->flags & PF_MEMDIE))) {
+		zone = zonelist->zones;
+		for (;;) {
+			zone_t *z = *(zone++);
+			if (!z)
+				break;
+
+			page = rmqueue(z, order);
+			if (page)
+				return page;
+		}
+		return NULL;
+	}
+
+	/* Atomic allocations - we can't balance anything */
+	if (!(gfp_mask & __GFP_WAIT))
+		goto out;
+
+ rebalance:
+	page = balance_classzone(classzone, gfp_mask, order, &freed);
+	if (page)
+		return page;
+
+	zone = zonelist->zones;
+	if (likely(freed)) {
+		for (;;) {
+			zone_t *z = *(zone++);
+			if (!z)
+				break;
+
+			if (zone_free_pages(z, order) > z->watermarks[class_idx].min) {
+				page = rmqueue(z, order);
+				if (page)
+					return page;
+			}
+		}
+		goto rebalance;
+	} else {
+		/* 
+		 * Check that no other task is been killed meanwhile,
+		 * in such a case we can succeed the allocation.
+		 */
+		for (;;) {
+			zone_t *z = *(zone++);
+			if (!z)
+				break;
+
+			if (zone_free_pages(z, order) > z->watermarks[class_idx].high) {
+				page = rmqueue(z, order);
+				if (page)
+					return page;
+			}
+		}
+	}
+
+ out:
+	printk(KERN_NOTICE "__alloc_pages: %u-order allocation failed (gfp=0x%x/%i)\n",
+	       order, gfp_mask, !!(current->flags & PF_MEMALLOC));
+	if (unlikely(vm_gfp_debug))
+		dump_stack();
+	return NULL;
+}
+
+/*
+ * Common helper functions.
+ */
+fastcall unsigned long __get_free_pages(unsigned int gfp_mask, unsigned int order)
+{
+	struct page * page;
+
+	page = alloc_pages(gfp_mask, order);
+	if (!page)
+		return 0;
+	return (unsigned long) page_address(page);
+}
+
+fastcall unsigned long get_zeroed_page(unsigned int gfp_mask)
+{
+	struct page * page;
+
+	page = alloc_pages(gfp_mask, 0);
+	if (page) {
+		void *address = page_address(page);
+		clear_page(address);
+		return (unsigned long) address;
+	}
+	return 0;
+}
+
+fastcall void __free_pages(struct page *page, unsigned int order)
+{
+	if (!PageReserved(page) && put_page_testzero(page))
+		__free_pages_ok(page, order);
+}
+
+fastcall void free_pages(unsigned long addr, unsigned int order)
+{
+	if (addr != 0)
+		__free_pages(virt_to_page(addr), order);
+}
+
+/*
+ * Total amount of free (allocatable) RAM:
+ */
+unsigned int nr_free_pages (void)
+{
+	unsigned int sum = 0;
+	zone_t *zone;
+
+	for_each_zone(zone)
+		sum += zone->free_pages;
+
+	return sum;
+}
+
+/*
+ * Amount of free RAM allocatable as buffer memory:
+ */
+unsigned int nr_free_buffer_pages (void)
+{
+	pg_data_t *pgdat;
+	unsigned int sum = 0;
+	zonelist_t *zonelist;
+	zone_t **zonep, *zone;
+
+	for_each_pgdat(pgdat) {
+		int class_idx;
+		zonelist = pgdat->node_zonelists + (GFP_USER & GFP_ZONEMASK);
+		zonep = zonelist->zones;
+		zone = *zonep;
+		class_idx = zone_idx(zone);
+
+		sum += zone->nr_cache_pages;
+		for (zone = pgdat->node_zones; zone < pgdat->node_zones + MAX_NR_ZONES; zone++) {
+			int free = zone->free_pages - zone->watermarks[class_idx].high;
+			if (free <= 0)
+				continue;
+			sum += free;
+		}
+	}
+
+	return sum;
+}
+
+#if CONFIG_HIGHMEM
+unsigned int nr_free_highpages (void)
+{
+	pg_data_t *pgdat;
+	unsigned int pages = 0;
+
+	for_each_pgdat(pgdat)
+		pages += pgdat->node_zones[ZONE_HIGHMEM].free_pages;
+
+	return pages;
+}
+
+unsigned int freeable_lowmem(void)
+{
+	unsigned int pages = 0;
+	pg_data_t *pgdat;
+
+	for_each_pgdat(pgdat) {
+		pages += pgdat->node_zones[ZONE_DMA].free_pages;
+		pages += pgdat->node_zones[ZONE_DMA].nr_active_pages;
+		pages += pgdat->node_zones[ZONE_DMA].nr_inactive_pages;
+		pages += pgdat->node_zones[ZONE_NORMAL].free_pages;
+		pages += pgdat->node_zones[ZONE_NORMAL].nr_active_pages;
+		pages += pgdat->node_zones[ZONE_NORMAL].nr_inactive_pages;
+	}
+
+	return pages;
+}
+#endif
+
+#define K(x) ((x) << (PAGE_SHIFT-10))
+
+/*
+ * Show free area list (used inside shift_scroll-lock stuff)
+ * We also calculate the percentage fragmentation. We do this by counting the
+ * memory on each free list with the exception of the first item on the list.
+ */
+void show_free_areas_core(pg_data_t *pgdat)
+{
+ 	unsigned int order;
+	unsigned type;
+	pg_data_t *tmpdat = pgdat;
+
+	printk("Free pages:      %6dkB (%6dkB HighMem)\n",
+		K(nr_free_pages()),
+		K(nr_free_highpages()));
+
+	while (tmpdat) {
+		zone_t *zone;
+		for (zone = tmpdat->node_zones;
+			       	zone < tmpdat->node_zones + MAX_NR_ZONES; zone++)
+			printk("Zone:%s freepages:%6lukB\n", 
+					zone->name,
+					K(zone->free_pages));
+			
+		tmpdat = tmpdat->node_next;
+	}
+
+	printk("( Active: %d, inactive: %d, free: %d )\n",
+	       nr_active_pages,
+	       nr_inactive_pages,
+	       nr_free_pages());
+
+	for (type = 0; type < MAX_NR_ZONES; type++) {
+		struct list_head *head, *curr;
+		zone_t *zone = pgdat->node_zones + type;
+ 		unsigned long nr, total, flags;
+
+		total = 0;
+		if (zone->size) {
+			spin_lock_irqsave(&zone->lock, flags);
+		 	for (order = 0; order < MAX_ORDER; order++) {
+				head = &(zone->free_area + order)->free_list;
+				curr = head;
+				nr = 0;
+				for (;;) {
+					if ((curr = curr->next) == head)
+						break;
+					nr++;
+				}
+				total += nr * (1 << order);
+				printk("%lu*%lukB ", nr, K(1UL) << order);
+			}
+			spin_unlock_irqrestore(&zone->lock, flags);
+		}
+		printk("= %lukB)\n", K(total));
+	}
+
+#ifndef NO_MM
+#ifdef SWAP_CACHE_INFO
+	show_swap_cache_info();
+#endif	
+#endif	
+}
+
+void show_free_areas(void)
+{
+	show_free_areas_core(pgdat_list);
+}
+
+/*
+ * Builds allocation fallback zone lists.
+ */
+static inline void build_zonelists(pg_data_t *pgdat)
+{
+	int i, j, k;
+
+	for (i = 0; i <= GFP_ZONEMASK; i++) {
+		zonelist_t *zonelist;
+		zone_t *zone;
+
+		zonelist = pgdat->node_zonelists + i;
+		memset(zonelist, 0, sizeof(*zonelist));
+
+		j = 0;
+		k = ZONE_NORMAL;
+		if (i & __GFP_HIGHMEM)
+			k = ZONE_HIGHMEM;
+		if (i & __GFP_DMA)
+			k = ZONE_DMA;
+
+		switch (k) {
+			default:
+				BUG();
+			/*
+			 * fallthrough:
+			 */
+			case ZONE_HIGHMEM:
+				zone = pgdat->node_zones + ZONE_HIGHMEM;
+				if (zone->size) {
+#ifndef CONFIG_HIGHMEM
+					BUG();
+#endif
+					zonelist->zones[j++] = zone;
+				}
+			case ZONE_NORMAL:
+				zone = pgdat->node_zones + ZONE_NORMAL;
+				if (zone->size)
+					zonelist->zones[j++] = zone;
+			case ZONE_DMA:
+				zone = pgdat->node_zones + ZONE_DMA;
+				if (zone->size)
+					zonelist->zones[j++] = zone;
+		}
+		zonelist->zones[j++] = NULL;
+	} 
+}
+
+/*
+ * Helper functions to size the waitqueue hash table.
+ * Essentially these want to choose hash table sizes sufficiently
+ * large so that collisions trying to wait on pages are rare.
+ * But in fact, the number of active page waitqueues on typical
+ * systems is ridiculously low, less than 200. So this is even
+ * conservative, even though it seems large.
+ *
+ * The constant PAGES_PER_WAITQUEUE specifies the ratio of pages to
+ * waitqueues, i.e. the size of the waitq table given the number of pages.
+ */
+#define PAGES_PER_WAITQUEUE	256
+
+static inline unsigned long wait_table_size(unsigned long pages)
+{
+	unsigned long size = 1;
+
+	pages /= PAGES_PER_WAITQUEUE;
+
+	while (size < pages)
+		size <<= 1;
+
+	/*
+	 * Once we have dozens or even hundreds of threads sleeping
+	 * on IO we've got bigger problems than wait queue collision.
+	 * Limit the size of the wait table to a reasonable size.
+	 */
+	size = min(size, 4096UL);
+
+	return size;
+}
+
+/*
+ * This is an integer logarithm so that shifts can be used later
+ * to extract the more random high bits from the multiplicative
+ * hash function before the remainder is taken.
+ */
+static inline unsigned long wait_table_bits(unsigned long size)
+{
+	return ffz(~size);
+}
+
+#define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
+
+/*
+ * Set up the zone data structures:
+ *   - mark all pages reserved
+ *   - mark all memory queues empty
+ *   - clear the memory bitmaps
+ */
+void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
+	unsigned long *zones_size, unsigned long zone_start_paddr, 
+	unsigned long *zholes_size, struct page *lmem_map)
+{
+	unsigned long i, j;
+	unsigned long map_size;
+	unsigned long totalpages, offset, realtotalpages;
+	const unsigned long zone_required_alignment = 1UL << (MAX_ORDER-1);
+
+	if (zone_start_paddr & ~PAGE_MASK)
+		BUG();
+
+	totalpages = 0;
+	for (i = 0; i < MAX_NR_ZONES; i++) {
+		unsigned long size = zones_size[i];
+		totalpages += size;
+	}
+	realtotalpages = totalpages;
+	if (zholes_size)
+		for (i = 0; i < MAX_NR_ZONES; i++)
+			realtotalpages -= zholes_size[i];
+			
+	printk("On node %d totalpages: %lu\n", nid, realtotalpages);
+
+	/*
+	 * Some architectures (with lots of mem and discontinous memory
+	 * maps) have to search for a good mem_map area:
+	 * For discontigmem, the conceptual mem map array starts from 
+	 * PAGE_OFFSET, we need to align the actual array onto a mem map 
+	 * boundary, so that MAP_NR works.
+	 */
+	map_size = (totalpages + 1)*sizeof(struct page);
+	if (lmem_map == (struct page *)0) {
+		lmem_map = (struct page *) alloc_bootmem_node(pgdat, map_size);
+		lmem_map = (struct page *)(PAGE_OFFSET + 
+			MAP_ALIGN((unsigned long)lmem_map - PAGE_OFFSET));
+	}
+	*gmap = pgdat->node_mem_map = lmem_map;
+	pgdat->node_size = totalpages;
+	pgdat->node_start_paddr = zone_start_paddr;
+	pgdat->node_start_mapnr = (lmem_map - mem_map);
+	pgdat->nr_zones = 0;
+
+	offset = lmem_map - mem_map;	
+	for (j = 0; j < MAX_NR_ZONES; j++) {
+		zone_t *zone = pgdat->node_zones + j;
+		unsigned long mask;
+		unsigned long size, realsize;
+		int idx;
+
+		zone_table[nid * MAX_NR_ZONES + j] = zone;
+		realsize = size = zones_size[j];
+		if (zholes_size)
+			realsize -= zholes_size[j];
+
+		printk("zone(%lu): %lu pages.\n", j, size);
+		zone->size = size;
+		zone->realsize = realsize;
+		zone->name = zone_names[j];
+		zone->lock = SPIN_LOCK_UNLOCKED;
+		zone->zone_pgdat = pgdat;
+		zone->free_pages = 0;
+		zone->need_balance = 0;
+		 zone->nr_active_pages = zone->nr_inactive_pages = 0;
+
+
+		if (!size)
+			continue;
+
+		/*
+		 * The per-page waitqueue mechanism uses hashed waitqueues
+		 * per zone.
+		 */
+		zone->wait_table_size = wait_table_size(size);
+		zone->wait_table_shift =
+			BITS_PER_LONG - wait_table_bits(zone->wait_table_size);
+		zone->wait_table = (wait_queue_head_t *)
+			alloc_bootmem_node(pgdat, zone->wait_table_size
+						* sizeof(wait_queue_head_t));
+
+		for(i = 0; i < zone->wait_table_size; ++i)
+			init_waitqueue_head(zone->wait_table + i);
+
+		pgdat->nr_zones = j+1;
+
+		mask = (realsize / zone_balance_ratio[j]);
+		if (mask < zone_balance_min[j])
+			mask = zone_balance_min[j];
+		else if (mask > zone_balance_max[j])
+			mask = zone_balance_max[j];
+		zone->watermarks[j].min = mask;
+		zone->watermarks[j].low = mask*2;
+		zone->watermarks[j].high = mask*3;
+		/* now set the watermarks of the lower zones in the "j" classzone */
+		for (idx = j-1; idx >= 0; idx--) {
+			zone_t * lower_zone = pgdat->node_zones + idx;
+			unsigned long lower_zone_reserve;
+			if (!lower_zone->size)
+				continue;
+
+			mask = lower_zone->watermarks[idx].min;
+			lower_zone->watermarks[j].min = mask;
+			lower_zone->watermarks[j].low = mask*2;
+			lower_zone->watermarks[j].high = mask*3;
+
+			/* now the brainer part */
+			lower_zone_reserve = realsize / lower_zone_reserve_ratio[idx];
+			lower_zone->watermarks[j].min += lower_zone_reserve;
+			lower_zone->watermarks[j].low += lower_zone_reserve;
+			lower_zone->watermarks[j].high += lower_zone_reserve;
+
+			realsize += lower_zone->realsize;
+		}
+
+		zone->zone_mem_map = mem_map + offset;
+		zone->zone_start_mapnr = offset;
+		zone->zone_start_paddr = zone_start_paddr;
+
+		if ((zone_start_paddr >> PAGE_SHIFT) & (zone_required_alignment-1))
+			printk("BUG: wrong zone alignment, it will crash\n");
+
+		/*
+		 * Initially all pages are reserved - free ones are freed
+		 * up by free_all_bootmem() once the early boot process is
+		 * done. Non-atomic initialization, single-pass.
+		 */
+		for (i = 0; i < size; i++) {
+			struct page *page = mem_map + offset + i;
+			set_page_zone(page, nid * MAX_NR_ZONES + j);
+			set_page_count(page, 0);
+			SetPageReserved(page);
+			INIT_LIST_HEAD(&page->list);
+			if (j != ZONE_HIGHMEM)
+				set_page_address(page, __va(zone_start_paddr));
+			zone_start_paddr += PAGE_SIZE;
+		}
+
+		offset += size;
+		for (i = 0; ; i++) {
+			unsigned long bitmap_size;
+
+			INIT_LIST_HEAD(&zone->free_area[i].free_list);
+			if (i == MAX_ORDER-1) {
+				zone->free_area[i].map = NULL;
+				break;
+			}
+
+			/*
+			 * Page buddy system uses "index >> (i+1)",
+			 * where "index" is at most "size-1".
+			 *
+			 * The extra "+3" is to round down to byte
+			 * size (8 bits per byte assumption). Thus
+			 * we get "(size-1) >> (i+4)" as the last byte
+			 * we can access.
+			 *
+			 * The "+1" is because we want to round the
+			 * byte allocation up rather than down. So
+			 * we should have had a "+7" before we shifted
+			 * down by three. Also, we have to add one as
+			 * we actually _use_ the last bit (it's [0,n]
+			 * inclusive, not [0,n[).
+			 *
+			 * So we actually had +7+1 before we shift
+			 * down by 3. But (n+8) >> 3 == (n >> 3) + 1
+			 * (modulo overflows, which we do not have).
+			 *
+			 * Finally, we LONG_ALIGN because all bitmap
+			 * operations are on longs.
+			 */
+			bitmap_size = (size-1) >> (i+4);
+			bitmap_size = LONG_ALIGN(bitmap_size+1);
+			zone->free_area[i].map = 
+			  (unsigned long *) alloc_bootmem_node(pgdat, bitmap_size);
+		}
+	}
+	build_zonelists(pgdat);
+}
+
+void __init free_area_init(unsigned long *zones_size)
+{
+	free_area_init_core(0, &contig_page_data, &mem_map, zones_size, 0, 0, 0);
+}
+
+static int __init setup_mem_frac(char *str)
+{
+	int j = 0;
+
+	while (get_option(&str, &zone_balance_ratio[j++]) == 2);
+	printk("setup_mem_frac: ");
+	for (j = 0; j < MAX_NR_ZONES; j++) printk("%d  ", zone_balance_ratio[j]);
+	printk("\n");
+	return 1;
+}
+
+__setup("memfrac=", setup_mem_frac);
+
+static int __init setup_lower_zone_reserve(char *str)
+{
+	int j = 0;
+
+	while (get_option(&str, &lower_zone_reserve_ratio[j++]) == 2);
+	printk("setup_lower_zone_reserve: ");
+	for (j = 0; j < MAX_NR_ZONES-1; j++) printk("%d  ", lower_zone_reserve_ratio[j]);
+	printk("\n");
+	return 1;
+}
+
+__setup("lower_zone_reserve=", setup_lower_zone_reserve);
diff -urN linux-2.4.29/mmnommu/slab.c linux-2.4.29-uc1/mmnommu/slab.c
--- linux-2.4.29/mmnommu/slab.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/slab.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,2190 @@
+/*
+ * linux/mm/slab.c
+ * Written by Mark Hemment, 1996/97.
+ * (markhe@nextd.demon.co.uk)
+ *
+ * kmem_cache_destroy() + some cleanup - 1999 Andrea Arcangeli
+ *
+ * Major cleanup, different bufctl logic, per-cpu arrays
+ *	(c) 2000 Manfred Spraul
+ *
+ * An implementation of the Slab Allocator as described in outline in;
+ *	UNIX Internals: The New Frontiers by Uresh Vahalia
+ *	Pub: Prentice Hall	ISBN 0-13-101908-2
+ * or with a little more detail in;
+ *	The Slab Allocator: An Object-Caching Kernel Memory Allocator
+ *	Jeff Bonwick (Sun Microsystems).
+ *	Presented at: USENIX Summer 1994 Technical Conference
+ *
+ *
+ * The memory is organized in caches, one cache for each object type.
+ * (e.g. inode_cache, dentry_cache, buffer_head, vm_area_struct)
+ * Each cache consists out of many slabs (they are small (usually one
+ * page long) and always contiguous), and each slab contains multiple
+ * initialized objects.
+ *
+ * Each cache can only support one memory type (GFP_DMA, GFP_HIGHMEM,
+ * normal). If you need a special memory type, then must create a new
+ * cache for that memory type.
+ *
+ * In order to reduce fragmentation, the slabs are sorted in 3 groups:
+ *   full slabs with 0 free objects
+ *   partial slabs
+ *   empty slabs with no allocated objects
+ *
+ * If partial slabs exist, then new allocations come from these slabs,
+ * otherwise from empty slabs or new slabs are allocated.
+ *
+ * kmem_cache_destroy() CAN CRASH if you try to allocate from the cache
+ * during kmem_cache_destroy(). The caller must prevent concurrent allocs.
+ *
+ * On SMP systems, each cache has a short per-cpu head array, most allocs
+ * and frees go into that array, and if that array overflows, then 1/2
+ * of the entries in the array are given back into the global cache.
+ * This reduces the number of spinlock operations.
+ *
+ * The c_cpuarray may not be read with enabled local interrupts.
+ *
+ * SMP synchronization:
+ *  constructors and destructors are called without any locking.
+ *  Several members in kmem_cache_t and slab_t never change, they
+ *	are accessed without any locking.
+ *  The per-cpu arrays are never accessed from the wrong cpu, no locking.
+ *  The non-constant members are protected with a per-cache irq spinlock.
+ *
+ * Further notes from the original documentation:
+ *
+ * 11 April '97.  Started multi-threading - markhe
+ *	The global cache-chain is protected by the semaphore 'cache_chain_sem'.
+ *	The sem is only needed when accessing/extending the cache-chain, which
+ *	can never happen inside an interrupt (kmem_cache_create(),
+ *	kmem_cache_shrink() and kmem_cache_reap()).
+ *
+ *	To prevent kmem_cache_shrink() trying to shrink a 'growing' cache (which
+ *	maybe be sleeping and therefore not holding the semaphore/lock), the
+ *	growing field is used.  This also prevents reaping from a cache.
+ *
+ *	At present, each engine can be growing a cache.  This should be blocked.
+ *
+ */
+
+#include	<linux/config.h>
+#include	<linux/slab.h>
+#include	<linux/interrupt.h>
+#include	<linux/init.h>
+#include	<linux/compiler.h>
+#include	<linux/seq_file.h>
+#ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
+#include	<linux/pagemap.h>
+#endif
+#include	<asm/uaccess.h>
+
+
+#ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
+extern unsigned long __get_contiguous_pages(unsigned int gfp_mask,
+			unsigned long num, unsigned int align_order);
+extern void free_contiguous_pages(unsigned long addr, unsigned int num);
+#endif
+
+
+/*
+ * DEBUG	- 1 for kmem_cache_create() to honour; SLAB_DEBUG_INITIAL,
+ *		  SLAB_RED_ZONE & SLAB_POISON.
+ *		  0 for faster, smaller code (especially in the critical paths).
+ *
+ * STATS	- 1 to collect stats for /proc/slabinfo.
+ *		  0 for faster, smaller code (especially in the critical paths).
+ *
+ * FORCED_DEBUG	- 1 enables SLAB_RED_ZONE and SLAB_POISON (if possible)
+ */
+
+#ifdef CONFIG_DEBUG_SLAB
+#define	DEBUG		1
+#define	STATS		1
+#define	FORCED_DEBUG	1
+#else
+#define	DEBUG		0
+#define	STATS		0
+#define	FORCED_DEBUG	0
+#endif
+
+/*
+ * Parameters for kmem_cache_reap
+ */
+#define REAP_SCANLEN	10
+#define REAP_PERFECT	10
+
+/* Shouldn't this be in a header file somewhere? */
+#if (defined(CONFIG_UCSIMM) || defined(CONFIG_UCDIMM) || defined(CONFIG_DRAGEN2)|| defined(CONFIG_CWEZ328) || defined (CONFIG_CWVZ328)) && !DEBUG
+/* a size other than 32 bits break the debug code */
+#define BYTES_PER_WORD          sizeof(short)
+#else
+#define	BYTES_PER_WORD		sizeof(void *)
+#endif
+
+/* Legal flag mask for kmem_cache_create(). */
+#if DEBUG
+# define CREATE_MASK	(SLAB_DEBUG_INITIAL | SLAB_RED_ZONE | \
+			 SLAB_POISON | SLAB_HWCACHE_ALIGN | \
+			 SLAB_NO_REAP | SLAB_CACHE_DMA | \
+			 SLAB_MUST_HWCACHE_ALIGN)
+#else
+# define CREATE_MASK	(SLAB_HWCACHE_ALIGN | SLAB_NO_REAP | \
+			 SLAB_CACHE_DMA | SLAB_MUST_HWCACHE_ALIGN)
+#endif
+
+/*
+ * kmem_bufctl_t:
+ *
+ * Bufctl's are used for linking objs within a slab
+ * linked offsets.
+ *
+ * This implementation relies on "struct page" for locating the cache &
+ * slab an object belongs to.
+ * This allows the bufctl structure to be small (one int), but limits
+ * the number of objects a slab (not a cache) can contain when off-slab
+ * bufctls are used. The limit is the size of the largest general cache
+ * that does not use off-slab slabs.
+ * For 32bit archs with 4 kB pages, is this 56.
+ * This is not serious, as it is only for large objects, when it is unwise
+ * to have too many per slab.
+ * Note: This limit can be raised by introducing a general cache whose size
+ * is less than 512 (PAGE_SIZE<<3), but greater than 256.
+ */
+
+#define BUFCTL_END 0xffffFFFF
+#define	SLAB_LIMIT 0xffffFFFE
+typedef unsigned int kmem_bufctl_t;
+
+/* Max number of objs-per-slab for caches which use off-slab slabs.
+ * Needed to avoid a possible looping condition in kmem_cache_grow().
+ */
+static unsigned long offslab_limit;
+
+/*
+ * slab_t
+ *
+ * Manages the objs in a slab. Placed either at the beginning of mem allocated
+ * for a slab, or allocated from an general cache.
+ * Slabs are chained into three list: fully used, partial, fully free slabs.
+ */
+typedef struct slab_s {
+	struct list_head	list;
+	unsigned long		colouroff;
+	void			*s_mem;		/* including colour offset */
+	unsigned int		inuse;		/* num of objs active in slab */
+	kmem_bufctl_t		free;
+} slab_t;
+
+#define slab_bufctl(slabp) \
+	((kmem_bufctl_t *)(((slab_t*)slabp)+1))
+
+/*
+ * cpucache_t
+ *
+ * Per cpu structures
+ * The limit is stored in the per-cpu structure to reduce the data cache
+ * footprint.
+ */
+typedef struct cpucache_s {
+	unsigned int avail;
+	unsigned int limit;
+} cpucache_t;
+
+#define cc_entry(cpucache) \
+	((void **)(((cpucache_t*)(cpucache))+1))
+#define cc_data(cachep) \
+	((cachep)->cpudata[smp_processor_id()])
+/*
+ * kmem_cache_t
+ *
+ * manages a cache.
+ */
+
+#define CACHE_NAMELEN	20	/* max name length for a slab cache */
+
+struct kmem_cache_s {
+/* 1) each alloc & free */
+	/* full, partial first, then free */
+	struct list_head	slabs_full;
+	struct list_head	slabs_partial;
+	struct list_head	slabs_free;
+	unsigned int		objsize;
+	unsigned int	 	flags;	/* constant flags */
+	unsigned int		num;	/* # of objs per slab */
+	spinlock_t		spinlock;
+#ifdef CONFIG_SMP
+	unsigned int		batchcount;
+#endif
+
+/* 2) slab additions /removals */
+	/* order of pgs per slab (2^n) */
+	unsigned int		gfporder;
+
+	/* force GFP flags, e.g. GFP_DMA */
+	unsigned int		gfpflags;
+
+	size_t			colour;		/* cache colouring range */
+	unsigned int		colour_off;	/* colour offset */
+	unsigned int		colour_next;	/* cache colouring */
+	kmem_cache_t		*slabp_cache;
+	unsigned int		growing;
+	unsigned int		dflags;		/* dynamic flags */
+
+	/* constructor func */
+	void (*ctor)(void *, kmem_cache_t *, unsigned long);
+
+	/* de-constructor func */
+	void (*dtor)(void *, kmem_cache_t *, unsigned long);
+
+	unsigned long		failures;
+
+/* 3) cache creation/removal */
+	char			name[CACHE_NAMELEN];
+	struct list_head	next;
+#ifdef CONFIG_SMP
+/* 4) per-cpu data */
+	cpucache_t		*cpudata[NR_CPUS];
+#endif
+#if STATS
+	unsigned long		num_active;
+	unsigned long		num_allocations;
+	unsigned long		high_mark;
+	unsigned long		grown;
+	unsigned long		reaped;
+	unsigned long 		errors;
+#ifdef CONFIG_SMP
+	atomic_t		allochit;
+	atomic_t		allocmiss;
+	atomic_t		freehit;
+	atomic_t		freemiss;
+#endif
+#endif
+};
+
+/* internal c_flags */
+#define	CFLGS_OFF_SLAB	0x010000UL	/* slab management in own cache */
+#define	CFLGS_OPTIMIZE	0x020000UL	/* optimized slab lookup */
+
+/* c_dflags (dynamic flags). Need to hold the spinlock to access this member */
+#define	DFLGS_GROWN	0x000001UL	/* don't reap a recently grown */
+
+#define	OFF_SLAB(x)	((x)->flags & CFLGS_OFF_SLAB)
+#define	OPTIMIZE(x)	((x)->flags & CFLGS_OPTIMIZE)
+#define	GROWN(x)	((x)->dlags & DFLGS_GROWN)
+
+#if STATS
+#define	STATS_INC_ACTIVE(x)	((x)->num_active++)
+#define	STATS_DEC_ACTIVE(x)	((x)->num_active--)
+#define	STATS_INC_ALLOCED(x)	((x)->num_allocations++)
+#define	STATS_INC_GROWN(x)	((x)->grown++)
+#define	STATS_INC_REAPED(x)	((x)->reaped++)
+#define	STATS_SET_HIGH(x)	do { if ((x)->num_active > (x)->high_mark) \
+					(x)->high_mark = (x)->num_active; \
+				} while (0)
+#define	STATS_INC_ERR(x)	((x)->errors++)
+#else
+#define	STATS_INC_ACTIVE(x)	do { } while (0)
+#define	STATS_DEC_ACTIVE(x)	do { } while (0)
+#define	STATS_INC_ALLOCED(x)	do { } while (0)
+#define	STATS_INC_GROWN(x)	do { } while (0)
+#define	STATS_INC_REAPED(x)	do { } while (0)
+#define	STATS_SET_HIGH(x)	do { } while (0)
+#define	STATS_INC_ERR(x)	do { } while (0)
+#endif
+
+#if STATS && defined(CONFIG_SMP)
+#define STATS_INC_ALLOCHIT(x)	atomic_inc(&(x)->allochit)
+#define STATS_INC_ALLOCMISS(x)	atomic_inc(&(x)->allocmiss)
+#define STATS_INC_FREEHIT(x)	atomic_inc(&(x)->freehit)
+#define STATS_INC_FREEMISS(x)	atomic_inc(&(x)->freemiss)
+#else
+#define STATS_INC_ALLOCHIT(x)	do { } while (0)
+#define STATS_INC_ALLOCMISS(x)	do { } while (0)
+#define STATS_INC_FREEHIT(x)	do { } while (0)
+#define STATS_INC_FREEMISS(x)	do { } while (0)
+#endif
+
+#if DEBUG
+/* Magic nums for obj red zoning.
+ * Placed in the first word before and the first word after an obj.
+ */
+#define	RED_MAGIC1	0x5A2CF071UL	/* when obj is active */
+#define	RED_MAGIC2	0x170FC2A5UL	/* when obj is inactive */
+
+/* ...and for poisoning */
+#define	POISON_BYTE	0x5a		/* byte value for poisoning */
+#define	POISON_END	0xa5		/* end-byte of poisoning */
+
+#endif
+
+/* maximum size of an obj (in 2^order pages) */
+#ifndef NO_MM
+#define	MAX_OBJ_ORDER	5	/* 32 pages */
+#elif defined (CONFIG_NO_MMU_LARGE_ALLOCS)
+#define	MAX_OBJ_ORDER	13	/* up to 32Mb */
+#else
+#define	MAX_OBJ_ORDER	8	/* up to 1MB */
+#endif
+
+/*
+ * Do not go above this order unless 0 objects fit into the slab.
+ */
+#define	BREAK_GFP_ORDER_HI	2
+#define	BREAK_GFP_ORDER_LO	1
+static int slab_break_gfp_order = BREAK_GFP_ORDER_LO;
+
+/*
+ * Absolute limit for the gfp order
+ */
+#ifndef NO_MM
+#define	MAX_GFP_ORDER	5	/* 32 pages */
+#elif defined (CONFIG_NO_MMU_LARGE_ALLOCS)
+#define	MAX_GFP_ORDER	13	/* up to 32MB */
+#else
+#define	MAX_GFP_ORDER	8	/* up to 1MB */
+#endif
+
+
+/* Macros for storing/retrieving the cachep and or slab from the
+ * global 'mem_map'. These are used to find the slab an obj belongs to.
+ * With kfree(), these are used to find the cache which an obj belongs to.
+ */
+#define	SET_PAGE_CACHE(pg,x)  ((pg)->list.next = (struct list_head *)(x))
+#define	GET_PAGE_CACHE(pg)    ((kmem_cache_t *)(pg)->list.next)
+#define	SET_PAGE_SLAB(pg,x)   ((pg)->list.prev = (struct list_head *)(x))
+#define	GET_PAGE_SLAB(pg)     ((slab_t *)(pg)->list.prev)
+
+/* Size description struct for general caches. */
+typedef struct cache_sizes {
+	size_t		 cs_size;
+	kmem_cache_t	*cs_cachep;
+	kmem_cache_t	*cs_dmacachep;
+} cache_sizes_t;
+
+static cache_sizes_t cache_sizes[] = {
+#if PAGE_SIZE == 4096
+	{    32,	NULL, NULL},
+#endif
+	{    64,	NULL, NULL},
+	{   128,	NULL, NULL},
+	{   256,	NULL, NULL},
+	{   512,	NULL, NULL},
+	{  1024,	NULL, NULL},
+	{  2048,	NULL, NULL},
+	{  4096,	NULL, NULL},
+#ifndef CONFIG_CONTIGUOUS_PAGE_ALLOC /* assumes page size of 4096 */
+	{  8192,	NULL, NULL},
+	{ 16384,	NULL, NULL},
+	{ 32768,	NULL, NULL},
+	{ 65536,	NULL, NULL},
+	{131072,	NULL, NULL},
+#ifdef NO_MM
+	{262144,	NULL, NULL},
+	{524288,	NULL, NULL},
+	{1048576,	NULL, NULL},
+#ifdef CONFIG_NO_MMU_LARGE_ALLOCS
+	{2097152,	NULL, NULL},
+	{4194304,	NULL, NULL},
+	{8388608,	NULL, NULL},
+	{16777216,	NULL, NULL},
+	{33554432,	NULL, NULL},
+#endif /* CONFIG_NO_MMU_LARGE_ALLOCS */
+#endif /* NO_MM */
+#endif /* CONFIG_CONTIGUOUS_PAGE_ALLOC */
+	{     0,	NULL, NULL}
+};
+
+/* internal cache of cache description objs */
+static kmem_cache_t cache_cache = {
+	slabs_full:	LIST_HEAD_INIT(cache_cache.slabs_full),
+	slabs_partial:	LIST_HEAD_INIT(cache_cache.slabs_partial),
+	slabs_free:	LIST_HEAD_INIT(cache_cache.slabs_free),
+	objsize:	sizeof(kmem_cache_t),
+	flags:		SLAB_NO_REAP,
+	spinlock:	SPIN_LOCK_UNLOCKED,
+	colour_off:	L1_CACHE_BYTES,
+	name:		"kmem_cache",
+};
+
+/* Guard access to the cache-chain. */
+static struct semaphore	cache_chain_sem;
+
+/* Place maintainer for reaping. */
+static kmem_cache_t *clock_searchp = &cache_cache;
+
+#define cache_chain (cache_cache.next)
+
+#ifdef CONFIG_SMP
+/*
+ * chicken and egg problem: delay the per-cpu array allocation
+ * until the general caches are up.
+ */
+static int g_cpucache_up;
+
+static void enable_cpucache (kmem_cache_t *cachep);
+static void enable_all_cpucaches (void);
+#endif
+
+/* Cal the num objs, wastage, and bytes left over for a given slab size. */
+static void kmem_cache_estimate (unsigned long gfporder, size_t size,
+		 int flags, size_t *left_over, unsigned int *num)
+{
+	unsigned int i;
+	size_t wastage = PAGE_SIZE<<gfporder;
+	size_t extra = 0;
+	size_t base = 0;
+
+	if (!(flags & CFLGS_OFF_SLAB)) {
+		base = sizeof(slab_t);
+		extra = sizeof(kmem_bufctl_t);
+	}
+	i = 0;
+	while (i*size + L1_CACHE_ALIGN(base+i*extra) <= wastage)
+		i++;
+	if (i > 0)
+		i--;
+
+	if (i > SLAB_LIMIT)
+		i = SLAB_LIMIT;
+
+	*num = i;
+	wastage -= i*size;
+	wastage -= L1_CACHE_ALIGN(base+i*extra);
+	*left_over = wastage;
+}
+
+/* Initialisation - setup the `cache' cache. */
+void __init kmem_cache_init(void)
+{
+	size_t left_over;
+
+	init_MUTEX(&cache_chain_sem);
+	INIT_LIST_HEAD(&cache_chain);
+
+	kmem_cache_estimate(0, cache_cache.objsize, 0,
+			&left_over, &cache_cache.num);
+	if (!cache_cache.num)
+		BUG();
+
+	cache_cache.colour = left_over/cache_cache.colour_off;
+	cache_cache.colour_next = 0;
+}
+
+
+/* Initialisation - setup remaining internal and general caches.
+ * Called after the gfp() functions have been enabled, and before smp_init().
+ */
+void __init kmem_cache_sizes_init(void)
+{
+	cache_sizes_t *sizes = cache_sizes;
+	char name[20];
+	/*
+	 * Fragmentation resistance on low memory - only use bigger
+	 * page orders on machines with more than 32MB of memory.
+	 */
+	if (num_physpages > (32 << 20) >> PAGE_SHIFT)
+		slab_break_gfp_order = BREAK_GFP_ORDER_HI;
+	do {
+		/* For performance, all the general caches are L1 aligned.
+		 * This should be particularly beneficial on SMP boxes, as it
+		 * eliminates "false sharing".
+		 * Note for systems short on memory removing the alignment will
+		 * allow tighter packing of the smaller caches. */
+		snprintf(name, sizeof(name), "size-%lu",(unsigned long)sizes->cs_size);
+		if (!(sizes->cs_cachep =
+			kmem_cache_create(name, sizes->cs_size,
+					0, SLAB_HWCACHE_ALIGN, NULL, NULL))) {
+			BUG();
+		}
+
+		/* Inc off-slab bufctl limit until the ceiling is hit. */
+		if (!(OFF_SLAB(sizes->cs_cachep))) {
+			offslab_limit = sizes->cs_size-sizeof(slab_t);
+			offslab_limit /= 2;
+		}
+		snprintf(name, sizeof(name), "size-%lu(DMA)",(unsigned long)sizes->cs_size);
+		sizes->cs_dmacachep = kmem_cache_create(name, sizes->cs_size, 0,
+			      SLAB_CACHE_DMA|SLAB_HWCACHE_ALIGN, NULL, NULL);
+		if (!sizes->cs_dmacachep)
+			BUG();
+		sizes++;
+	} while (sizes->cs_size);
+}
+
+int __init kmem_cpucache_init(void)
+{
+#ifdef CONFIG_SMP
+	g_cpucache_up = 1;
+	enable_all_cpucaches();
+#endif
+	return 0;
+}
+
+__initcall(kmem_cpucache_init);
+
+/* Interface to system's page allocator. No need to hold the cache-lock.
+ */
+static inline void * kmem_getpages (kmem_cache_t *cachep, unsigned long flags)
+{
+	void	*addr;
+
+	/*
+	 * If we requested dmaable memory, we will get it. Even if we
+	 * did not request dmaable memory, we might get it, but that
+	 * would be relatively rare and ignorable.
+	 */
+	flags |= cachep->gfpflags;
+	addr = (void*) __get_free_pages(flags, cachep->gfporder);
+	/* Assume that now we have the pages no one else can legally
+	 * messes with the 'struct page's.
+	 * However vm_scan() might try to test the structure to see if
+	 * it is a named-page or buffer-page.  The members it tests are
+	 * of no interest here.....
+	 */
+	return addr;
+}
+
+/* Interface to system's page release. */
+static inline void kmem_freepages (kmem_cache_t *cachep, void *addr)
+{
+	unsigned long i = (1<<cachep->gfporder);
+	struct page *page = virt_to_page(addr);
+
+	/* free_pages() does not clear the type bit - we do that.
+	 * The pages have been unlinked from their cache-slab,
+	 * but their 'struct page's might be accessed in
+	 * vm_scan(). Shouldn't be a worry.
+	 */
+	while (i--) {
+		PageClearSlab(page);
+		page++;
+	}
+	free_pages((unsigned long)addr, cachep->gfporder);
+}
+
+#if DEBUG
+static inline void kmem_poison_obj (kmem_cache_t *cachep, void *addr)
+{
+	int size = cachep->objsize;
+	if (cachep->flags & SLAB_RED_ZONE) {
+		addr += BYTES_PER_WORD;
+		size -= 2*BYTES_PER_WORD;
+	}
+	memset(addr, POISON_BYTE, size);
+	*(unsigned char *)(addr+size-1) = POISON_END;
+}
+
+static inline int kmem_check_poison_obj (kmem_cache_t *cachep, void *addr)
+{
+	int size = cachep->objsize;
+	void *end;
+	if (cachep->flags & SLAB_RED_ZONE) {
+		addr += BYTES_PER_WORD;
+		size -= 2*BYTES_PER_WORD;
+	}
+	end = memchr(addr, POISON_END, size);
+	if (end != (addr+size-1))
+		return 1;
+	return 0;
+}
+#endif
+
+/* Destroy all the objs in a slab, and release the mem back to the system.
+ * Before calling the slab must have been unlinked from the cache.
+ * The cache-lock is not held/needed.
+ */
+static void kmem_slab_destroy (kmem_cache_t *cachep, slab_t *slabp)
+{
+	if (cachep->dtor
+#if DEBUG
+		|| cachep->flags & (SLAB_POISON | SLAB_RED_ZONE)
+#endif
+	) {
+		int i;
+		for (i = 0; i < cachep->num; i++) {
+			void* objp = slabp->s_mem+cachep->objsize*i;
+#if DEBUG
+			if (cachep->flags & SLAB_RED_ZONE) {
+				if (*((unsigned long*)(objp)) != RED_MAGIC1)
+					BUG();
+				if (*((unsigned long*)(objp + cachep->objsize
+						-BYTES_PER_WORD)) != RED_MAGIC1)
+					BUG();
+				objp += BYTES_PER_WORD;
+			}
+#endif
+			if (cachep->dtor)
+				(cachep->dtor)(objp, cachep, 0);
+#if DEBUG
+			if (cachep->flags & SLAB_RED_ZONE) {
+				objp -= BYTES_PER_WORD;
+			}	
+			if ((cachep->flags & SLAB_POISON)  &&
+				kmem_check_poison_obj(cachep, objp))
+				BUG();
+#endif
+		}
+	}
+
+	kmem_freepages(cachep, slabp->s_mem-slabp->colouroff);
+	if (OFF_SLAB(cachep))
+		kmem_cache_free(cachep->slabp_cache, slabp);
+}
+
+/**
+ * kmem_cache_create - Create a cache.
+ * @name: A string which is used in /proc/slabinfo to identify this cache.
+ * @size: The size of objects to be created in this cache.
+ * @offset: The offset to use within the page.
+ * @flags: SLAB flags
+ * @ctor: A constructor for the objects.
+ * @dtor: A destructor for the objects.
+ *
+ * Returns a ptr to the cache on success, NULL on failure.
+ * Cannot be called within a int, but can be interrupted.
+ * The @ctor is run when new pages are allocated by the cache
+ * and the @dtor is run before the pages are handed back.
+ * The flags are
+ *
+ * %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5)
+ * to catch references to uninitialised memory.
+ *
+ * %SLAB_RED_ZONE - Insert `Red' zones around the allocated memory to check
+ * for buffer overruns.
+ *
+ * %SLAB_NO_REAP - Don't automatically reap this cache when we're under
+ * memory pressure.
+ *
+ * %SLAB_HWCACHE_ALIGN - Align the objects in this cache to a hardware
+ * cacheline.  This can be beneficial if you're counting cycles as closely
+ * as davem.
+ */
+kmem_cache_t *
+kmem_cache_create (const char *name, size_t size, size_t offset,
+	unsigned long flags, void (*ctor)(void*, kmem_cache_t *, unsigned long),
+	void (*dtor)(void*, kmem_cache_t *, unsigned long))
+{
+	const char *func_nm = "kmem_create: ";
+	size_t left_over, align, slab_size;
+	kmem_cache_t *cachep = NULL;
+
+	/*
+	 * Sanity checks... these are all serious usage bugs.
+	 */
+	if ((!name) ||
+		((strlen(name) >= CACHE_NAMELEN - 1)) ||
+		in_interrupt() ||
+		(size < BYTES_PER_WORD) ||
+		(size > (1<<MAX_OBJ_ORDER)*PAGE_SIZE) ||
+		(dtor && !ctor) ||
+		(offset < 0 || offset > size))
+			BUG();
+
+#if DEBUG
+	if ((flags & SLAB_DEBUG_INITIAL) && !ctor) {
+		/* No constructor, but inital state check requested */
+		printk(KERN_ERR "%sNo con, but init state check requested - %s\n", func_nm, name);
+		flags &= ~SLAB_DEBUG_INITIAL;
+	}
+
+	if ((flags & SLAB_POISON) && ctor) {
+		/* request for poisoning, but we can't do that with a constructor */
+		printk(KERN_ERR "%sPoisoning requested, but con given - %s\n", func_nm, name);
+		flags &= ~SLAB_POISON;
+	}
+#if FORCED_DEBUG
+	if ((size < (PAGE_SIZE>>3)) && !(flags & SLAB_MUST_HWCACHE_ALIGN))
+		/*
+		 * do not red zone large object, causes severe
+		 * fragmentation.
+		 */
+		flags |= SLAB_RED_ZONE;
+	if (!ctor)
+		flags |= SLAB_POISON;
+#endif
+#endif
+
+	/*
+	 * Always checks flags, a caller might be expecting debug
+	 * support which isn't available.
+	 */
+	BUG_ON(flags & ~CREATE_MASK);
+
+	/* Get cache's description obj. */
+	cachep = (kmem_cache_t *) kmem_cache_alloc(&cache_cache, SLAB_KERNEL);
+	if (!cachep)
+		goto opps;
+	memset(cachep, 0, sizeof(kmem_cache_t));
+
+	/* Check that size is in terms of words.  This is needed to avoid
+	 * unaligned accesses for some archs when redzoning is used, and makes
+	 * sure any on-slab bufctl's are also correctly aligned.
+	 */
+	if (size & (BYTES_PER_WORD-1)) {
+		size += (BYTES_PER_WORD-1);
+		size &= ~(BYTES_PER_WORD-1);
+		printk(KERN_WARNING "%sForcing size word alignment - %s\n", func_nm, name);
+	}
+	
+#if DEBUG
+	if (flags & SLAB_RED_ZONE) {
+		/*
+		 * There is no point trying to honour cache alignment
+		 * when redzoning.
+		 */
+		flags &= ~SLAB_HWCACHE_ALIGN;
+		size += 2*BYTES_PER_WORD;	/* words for redzone */
+	}
+#endif
+	align = BYTES_PER_WORD;
+	if (flags & SLAB_HWCACHE_ALIGN)
+		align = L1_CACHE_BYTES;
+
+	/* Determine if the slab management is 'on' or 'off' slab. */
+	if (size >= (PAGE_SIZE>>3))
+		/*
+		 * Size is large, assume best to place the slab management obj
+		 * off-slab (should allow better packing of objs).
+		 */
+		flags |= CFLGS_OFF_SLAB;
+
+	if (flags & SLAB_HWCACHE_ALIGN) {
+		/* Need to adjust size so that objs are cache aligned. */
+		/* Small obj size, can get at least two per cache line. */
+		/* FIXME: only power of 2 supported, was better */
+		while (size < align/2)
+			align /= 2;
+		size = (size+align-1)&(~(align-1));
+	}
+
+	/* Cal size (in pages) of slabs, and the num of objs per slab.
+	 * This could be made much more intelligent.  For now, try to avoid
+	 * using high page-orders for slabs.  When the gfp() funcs are more
+	 * friendly towards high-order requests, this should be changed.
+	 */
+	do {
+		unsigned int break_flag = 0;
+cal_wastage:
+		kmem_cache_estimate(cachep->gfporder, size, flags,
+						&left_over, &cachep->num);
+		if (break_flag)
+			break;
+		if (cachep->gfporder >= MAX_GFP_ORDER)
+			break;
+		if (!cachep->num)
+			goto next;
+		if (flags & CFLGS_OFF_SLAB && cachep->num > offslab_limit) {
+			/* Oops, this num of objs will cause problems. */
+			cachep->gfporder--;
+			break_flag++;
+			goto cal_wastage;
+		}
+
+		/*
+		 * Large num of objs is good, but v. large slabs are currently
+		 * bad for the gfp()s.
+		 */
+		if (cachep->gfporder >= slab_break_gfp_order)
+			break;
+
+		if ((left_over*8) <= (PAGE_SIZE<<cachep->gfporder))
+			break;	/* Acceptable internal fragmentation. */
+next:
+		cachep->gfporder++;
+	} while (1);
+
+	if (!cachep->num) {
+		printk("kmem_cache_create: couldn't create cache %s.\n", name);
+		kmem_cache_free(&cache_cache, cachep);
+		cachep = NULL;
+		goto opps;
+	}
+	slab_size = L1_CACHE_ALIGN(cachep->num*sizeof(kmem_bufctl_t)+sizeof(slab_t));
+
+	/*
+	 * If the slab has been placed off-slab, and we have enough space then
+	 * move it on-slab. This is at the expense of any extra colouring.
+	 */
+	if (flags & CFLGS_OFF_SLAB && left_over >= slab_size) {
+		flags &= ~CFLGS_OFF_SLAB;
+		left_over -= slab_size;
+	}
+
+	/* Offset must be a multiple of the alignment. */
+	offset += (align-1);
+	offset &= ~(align-1);
+	if (!offset)
+		offset = L1_CACHE_BYTES;
+	cachep->colour_off = offset;
+	cachep->colour = left_over/offset;
+
+	/* init remaining fields */
+	if (!cachep->gfporder && !(flags & CFLGS_OFF_SLAB))
+		flags |= CFLGS_OPTIMIZE;
+
+	cachep->flags = flags;
+	cachep->gfpflags = 0;
+	if (flags & SLAB_CACHE_DMA)
+		cachep->gfpflags |= GFP_DMA;
+	spin_lock_init(&cachep->spinlock);
+	cachep->objsize = size;
+	INIT_LIST_HEAD(&cachep->slabs_full);
+	INIT_LIST_HEAD(&cachep->slabs_partial);
+	INIT_LIST_HEAD(&cachep->slabs_free);
+
+	if (flags & CFLGS_OFF_SLAB)
+		cachep->slabp_cache = kmem_find_general_cachep(slab_size,0);
+	cachep->ctor = ctor;
+	cachep->dtor = dtor;
+	/* Copy name over so we don't have problems with unloaded modules */
+	strcpy(cachep->name, name);
+
+#ifdef CONFIG_SMP
+	if (g_cpucache_up)
+		enable_cpucache(cachep);
+#endif
+	/* Need the semaphore to access the chain. */
+	down(&cache_chain_sem);
+	{
+		struct list_head *p;
+
+		list_for_each(p, &cache_chain) {
+			kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
+
+			/* The name field is constant - no lock needed. */
+			if (!strcmp(pc->name, name))
+				BUG();
+		}
+	}
+
+	/* There is no reason to lock our new cache before we
+	 * link it in - no one knows about it yet...
+	 */
+	list_add(&cachep->next, &cache_chain);
+	up(&cache_chain_sem);
+opps:
+	return cachep;
+}
+
+
+#if DEBUG
+/*
+ * This check if the kmem_cache_t pointer is chained in the cache_cache
+ * list. -arca
+ */
+static int is_chained_kmem_cache(kmem_cache_t * cachep)
+{
+	struct list_head *p;
+	int ret = 0;
+
+	/* Find the cache in the chain of caches. */
+	down(&cache_chain_sem);
+	list_for_each(p, &cache_chain) {
+		if (p == &cachep->next) {
+			ret = 1;
+			break;
+		}
+	}
+	up(&cache_chain_sem);
+
+	return ret;
+}
+#else
+#define is_chained_kmem_cache(x) 1
+#endif
+
+#ifdef CONFIG_SMP
+/*
+ * Waits for all CPUs to execute func().
+ */
+static void smp_call_function_all_cpus(void (*func) (void *arg), void *arg)
+{
+	local_irq_disable();
+	func(arg);
+	local_irq_enable();
+
+	if (smp_call_function(func, arg, 1, 1))
+		BUG();
+}
+typedef struct ccupdate_struct_s
+{
+	kmem_cache_t *cachep;
+	cpucache_t *new[NR_CPUS];
+} ccupdate_struct_t;
+
+static void do_ccupdate_local(void *info)
+{
+	ccupdate_struct_t *new = (ccupdate_struct_t *)info;
+	cpucache_t *old = cc_data(new->cachep);
+	
+	cc_data(new->cachep) = new->new[smp_processor_id()];
+	new->new[smp_processor_id()] = old;
+}
+
+static void free_block (kmem_cache_t* cachep, void** objpp, int len);
+
+static void drain_cpu_caches(kmem_cache_t *cachep)
+{
+	ccupdate_struct_t new;
+	int i;
+
+	memset(&new.new,0,sizeof(new.new));
+
+	new.cachep = cachep;
+
+	down(&cache_chain_sem);
+	smp_call_function_all_cpus(do_ccupdate_local, (void *)&new);
+
+	for (i = 0; i < smp_num_cpus; i++) {
+		cpucache_t* ccold = new.new[cpu_logical_map(i)];
+		if (!ccold || (ccold->avail == 0))
+			continue;
+		local_irq_disable();
+		free_block(cachep, cc_entry(ccold), ccold->avail);
+		local_irq_enable();
+		ccold->avail = 0;
+	}
+	smp_call_function_all_cpus(do_ccupdate_local, (void *)&new);
+	up(&cache_chain_sem);
+}
+
+#else
+#define drain_cpu_caches(cachep)	do { } while (0)
+#endif
+
+/*
+ * Called with the &cachep->spinlock held, returns number of slabs released
+ */
+static int __kmem_cache_shrink_locked(kmem_cache_t *cachep)
+{
+	slab_t *slabp;
+	int ret = 0;
+
+	/* If the cache is growing, stop shrinking. */
+	while (!cachep->growing) {
+		struct list_head *p;
+
+		p = cachep->slabs_free.prev;
+		if (p == &cachep->slabs_free)
+			break;
+
+		slabp = list_entry(cachep->slabs_free.prev, slab_t, list);
+#if DEBUG
+		if (slabp->inuse)
+			BUG();
+#endif
+		list_del(&slabp->list);
+
+		spin_unlock_irq(&cachep->spinlock);
+		kmem_slab_destroy(cachep, slabp);
+		ret++;
+		spin_lock_irq(&cachep->spinlock);
+	}
+	return ret;
+}
+
+static int __kmem_cache_shrink(kmem_cache_t *cachep)
+{
+	int ret;
+
+	drain_cpu_caches(cachep);
+
+	spin_lock_irq(&cachep->spinlock);
+	__kmem_cache_shrink_locked(cachep);
+	ret = !list_empty(&cachep->slabs_full) ||
+		!list_empty(&cachep->slabs_partial);
+	spin_unlock_irq(&cachep->spinlock);
+	return ret;
+}
+
+/**
+ * kmem_cache_shrink - Shrink a cache.
+ * @cachep: The cache to shrink.
+ *
+ * Releases as many slabs as possible for a cache.
+ * Returns number of pages released.
+ */
+int kmem_cache_shrink(kmem_cache_t *cachep)
+{
+	int ret;
+
+	if (!cachep || in_interrupt() || !is_chained_kmem_cache(cachep))
+		BUG();
+
+	spin_lock_irq(&cachep->spinlock);
+	ret = __kmem_cache_shrink_locked(cachep);
+	spin_unlock_irq(&cachep->spinlock);
+
+	return ret << cachep->gfporder;
+}
+
+/**
+ * kmem_cache_destroy - delete a cache
+ * @cachep: the cache to destroy
+ *
+ * Remove a kmem_cache_t object from the slab cache.
+ * Returns 0 on success.
+ *
+ * It is expected this function will be called by a module when it is
+ * unloaded.  This will remove the cache completely, and avoid a duplicate
+ * cache being allocated each time a module is loaded and unloaded, if the
+ * module doesn't have persistent in-kernel storage across loads and unloads.
+ *
+ * The cache must be empty before calling this function.
+ *
+ * The caller must guarantee that noone will allocate memory from the cache
+ * during the kmem_cache_destroy().
+ */
+int kmem_cache_destroy (kmem_cache_t * cachep)
+{
+	if (!cachep || in_interrupt() || cachep->growing)
+		BUG();
+
+	/* Find the cache in the chain of caches. */
+	down(&cache_chain_sem);
+	/* the chain is never empty, cache_cache is never destroyed */
+	if (clock_searchp == cachep)
+		clock_searchp = list_entry(cachep->next.next,
+						kmem_cache_t, next);
+	list_del(&cachep->next);
+	up(&cache_chain_sem);
+
+	if (__kmem_cache_shrink(cachep)) {
+		printk(KERN_ERR "kmem_cache_destroy: Can't free all objects %p\n",
+		       cachep);
+		down(&cache_chain_sem);
+		list_add(&cachep->next,&cache_chain);
+		up(&cache_chain_sem);
+		return 1;
+	}
+#ifdef CONFIG_SMP
+	{
+		int i;
+		for (i = 0; i < NR_CPUS; i++)
+			kfree(cachep->cpudata[i]);
+	}
+#endif
+	kmem_cache_free(&cache_cache, cachep);
+
+	return 0;
+}
+
+/* Get the memory for a slab management obj. */
+static inline slab_t * kmem_cache_slabmgmt (kmem_cache_t *cachep,
+			void *objp, int colour_off, int local_flags)
+{
+	slab_t *slabp;
+	
+	if (OFF_SLAB(cachep)) {
+		/* Slab management obj is off-slab. */
+		slabp = kmem_cache_alloc(cachep->slabp_cache, local_flags);
+		if (!slabp)
+			return NULL;
+	} else {
+		/* FIXME: change to
+			slabp = objp
+		 * if you enable OPTIMIZE
+		 */
+		slabp = objp+colour_off;
+		colour_off += L1_CACHE_ALIGN(cachep->num *
+				sizeof(kmem_bufctl_t) + sizeof(slab_t));
+	}
+	slabp->inuse = 0;
+	slabp->colouroff = colour_off;
+	slabp->s_mem = objp+colour_off;
+
+	return slabp;
+}
+
+static inline void kmem_cache_init_objs (kmem_cache_t * cachep,
+			slab_t * slabp, unsigned long ctor_flags)
+{
+	int i;
+
+	for (i = 0; i < cachep->num; i++) {
+		void* objp = slabp->s_mem+cachep->objsize*i;
+#if DEBUG
+		if (cachep->flags & SLAB_RED_ZONE) {
+			*((unsigned long*)(objp)) = RED_MAGIC1;
+			*((unsigned long*)(objp + cachep->objsize -
+					BYTES_PER_WORD)) = RED_MAGIC1;
+			objp += BYTES_PER_WORD;
+		}
+#endif
+
+		/*
+		 * Constructors are not allowed to allocate memory from
+		 * the same cache which they are a constructor for.
+		 * Otherwise, deadlock. They must also be threaded.
+		 */
+		if (cachep->ctor)
+			cachep->ctor(objp, cachep, ctor_flags);
+#if DEBUG
+		if (cachep->flags & SLAB_RED_ZONE)
+			objp -= BYTES_PER_WORD;
+		if (cachep->flags & SLAB_POISON)
+			/* need to poison the objs */
+			kmem_poison_obj(cachep, objp);
+		if (cachep->flags & SLAB_RED_ZONE) {
+			if (*((unsigned long*)(objp)) != RED_MAGIC1)
+				BUG();
+			if (*((unsigned long*)(objp + cachep->objsize -
+					BYTES_PER_WORD)) != RED_MAGIC1)
+				BUG();
+		}
+#endif
+		slab_bufctl(slabp)[i] = i+1;
+	}
+	slab_bufctl(slabp)[i-1] = BUFCTL_END;
+	slabp->free = 0;
+}
+
+/*
+ * Grow (by 1) the number of slabs within a cache.  This is called by
+ * kmem_cache_alloc() when there are no active objs left in a cache.
+ */
+static int kmem_cache_grow (kmem_cache_t * cachep, int flags)
+{
+	slab_t	*slabp;
+	struct page	*page;
+	void		*objp;
+	size_t		 offset;
+	unsigned int	 i, local_flags;
+	unsigned long	 ctor_flags;
+	unsigned long	 save_flags;
+
+	/* Be lazy and only check for valid flags here,
+ 	 * keeping it out of the critical path in kmem_cache_alloc().
+	 */
+	if (flags & ~(SLAB_DMA|SLAB_LEVEL_MASK|SLAB_NO_GROW))
+		BUG();
+	if (flags & SLAB_NO_GROW)
+		return 0;
+
+	/*
+	 * The test for missing atomic flag is performed here, rather than
+	 * the more obvious place, simply to reduce the critical path length
+	 * in kmem_cache_alloc(). If a caller is seriously mis-behaving they
+	 * will eventually be caught here (where it matters).
+	 */
+	if (in_interrupt() && (flags & SLAB_LEVEL_MASK) != SLAB_ATOMIC)
+		BUG();
+
+	ctor_flags = SLAB_CTOR_CONSTRUCTOR;
+	local_flags = (flags & SLAB_LEVEL_MASK);
+	if (local_flags == SLAB_ATOMIC)
+		/*
+		 * Not allowed to sleep.  Need to tell a constructor about
+		 * this - it might need to know...
+		 */
+		ctor_flags |= SLAB_CTOR_ATOMIC;
+
+	/* About to mess with non-constant members - lock. */
+	spin_lock_irqsave(&cachep->spinlock, save_flags);
+
+	/* Get colour for the slab, and cal the next value. */
+	offset = cachep->colour_next;
+	cachep->colour_next++;
+	if (cachep->colour_next >= cachep->colour)
+		cachep->colour_next = 0;
+	offset *= cachep->colour_off;
+	cachep->dflags |= DFLGS_GROWN;
+
+	cachep->growing++;
+	spin_unlock_irqrestore(&cachep->spinlock, save_flags);
+
+	/* A series of memory allocations for a new slab.
+	 * Neither the cache-chain semaphore, or cache-lock, are
+	 * held, but the incrementing c_growing prevents this
+	 * cache from being reaped or shrunk.
+	 * Note: The cache could be selected in for reaping in
+	 * kmem_cache_reap(), but when the final test is made the
+	 * growing value will be seen.
+	 */
+
+	/* Get mem for the objs. */
+	if (!(objp = kmem_getpages(cachep, flags)))
+		goto failed;
+
+	/* Get slab management. */
+	if (!(slabp = kmem_cache_slabmgmt(cachep, objp, offset, local_flags)))
+		goto opps1;
+
+	/* Nasty!!!!!! I hope this is OK. */
+	i = 1 << cachep->gfporder;
+	page = virt_to_page(objp);
+	do {
+		SET_PAGE_CACHE(page, cachep);
+		SET_PAGE_SLAB(page, slabp);
+		PageSetSlab(page);
+		page++;
+	} while (--i);
+
+	kmem_cache_init_objs(cachep, slabp, ctor_flags);
+
+	spin_lock_irqsave(&cachep->spinlock, save_flags);
+	cachep->growing--;
+
+	/* Make slab active. */
+	list_add_tail(&slabp->list, &cachep->slabs_free);
+	STATS_INC_GROWN(cachep);
+	cachep->failures = 0;
+
+	spin_unlock_irqrestore(&cachep->spinlock, save_flags);
+	return 1;
+opps1:
+	kmem_freepages(cachep, objp);
+failed:
+	spin_lock_irqsave(&cachep->spinlock, save_flags);
+	cachep->growing--;
+	spin_unlock_irqrestore(&cachep->spinlock, save_flags);
+	return 0;
+}
+
+/*
+ * Perform extra freeing checks:
+ * - detect double free
+ * - detect bad pointers.
+ * Called with the cache-lock held.
+ */
+
+#if DEBUG
+static int kmem_extra_free_checks (kmem_cache_t * cachep,
+			slab_t *slabp, void * objp)
+{
+	int i;
+	unsigned int objnr = (objp-slabp->s_mem)/cachep->objsize;
+
+	if (objnr >= cachep->num)
+		BUG();
+	if (objp != slabp->s_mem + objnr*cachep->objsize)
+		BUG();
+
+	/* Check slab's freelist to see if this obj is there. */
+	for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
+		if (i == objnr)
+			BUG();
+	}
+	return 0;
+}
+#endif
+
+static inline void kmem_cache_alloc_head(kmem_cache_t *cachep, int flags)
+{
+	if (flags & SLAB_DMA) {
+		if (!(cachep->gfpflags & GFP_DMA))
+			BUG();
+	} else {
+		if (cachep->gfpflags & GFP_DMA)
+			BUG();
+	}
+}
+
+static inline void * kmem_cache_alloc_one_tail (kmem_cache_t *cachep,
+						slab_t *slabp)
+{
+	void *objp;
+
+	STATS_INC_ALLOCED(cachep);
+	STATS_INC_ACTIVE(cachep);
+	STATS_SET_HIGH(cachep);
+
+	/* get obj pointer */
+	slabp->inuse++;
+	objp = slabp->s_mem + slabp->free*cachep->objsize;
+	slabp->free=slab_bufctl(slabp)[slabp->free];
+
+	if (unlikely(slabp->free == BUFCTL_END)) {
+		list_del(&slabp->list);
+		list_add(&slabp->list, &cachep->slabs_full);
+	}
+#if DEBUG
+	if (cachep->flags & SLAB_POISON)
+		if (kmem_check_poison_obj(cachep, objp))
+			BUG();
+	if (cachep->flags & SLAB_RED_ZONE) {
+		/* Set alloc red-zone, and check old one. */
+		if (xchg((unsigned long *)objp, RED_MAGIC2) !=
+							 RED_MAGIC1)
+			BUG();
+		if (xchg((unsigned long *)(objp+cachep->objsize -
+			  BYTES_PER_WORD), RED_MAGIC2) != RED_MAGIC1)
+			BUG();
+		objp += BYTES_PER_WORD;
+	}
+#endif
+	return objp;
+}
+
+/*
+ * Returns a ptr to an obj in the given cache.
+ * caller must guarantee synchronization
+ * #define for the goto optimization 8-)
+ */
+#define kmem_cache_alloc_one(cachep)				\
+({								\
+	struct list_head * slabs_partial, * entry;		\
+	slab_t *slabp;						\
+								\
+	slabs_partial = &(cachep)->slabs_partial;		\
+	entry = slabs_partial->next;				\
+	if (unlikely(entry == slabs_partial)) {			\
+		struct list_head * slabs_free;			\
+		slabs_free = &(cachep)->slabs_free;		\
+		entry = slabs_free->next;			\
+		if (unlikely(entry == slabs_free))		\
+			goto alloc_new_slab;			\
+		list_del(entry);				\
+		list_add(entry, slabs_partial);			\
+	}							\
+								\
+	slabp = list_entry(entry, slab_t, list);		\
+	kmem_cache_alloc_one_tail(cachep, slabp);		\
+})
+
+#ifdef CONFIG_SMP
+void* kmem_cache_alloc_batch(kmem_cache_t* cachep, cpucache_t* cc, int flags)
+{
+	int batchcount = cachep->batchcount;
+
+	spin_lock(&cachep->spinlock);
+	while (batchcount--) {
+		struct list_head * slabs_partial, * entry;
+		slab_t *slabp;
+		/* Get slab alloc is to come from. */
+		slabs_partial = &(cachep)->slabs_partial;
+		entry = slabs_partial->next;
+		if (unlikely(entry == slabs_partial)) {
+			struct list_head * slabs_free;
+			slabs_free = &(cachep)->slabs_free;
+			entry = slabs_free->next;
+			if (unlikely(entry == slabs_free))
+				break;
+			list_del(entry);
+			list_add(entry, slabs_partial);
+		}
+
+		slabp = list_entry(entry, slab_t, list);
+		cc_entry(cc)[cc->avail++] =
+				kmem_cache_alloc_one_tail(cachep, slabp);
+	}
+	spin_unlock(&cachep->spinlock);
+
+	if (cc->avail)
+		return cc_entry(cc)[--cc->avail];
+	return NULL;
+}
+#endif
+
+static inline void * __kmem_cache_alloc (kmem_cache_t *cachep, int flags)
+{
+	unsigned long save_flags;
+	void* objp;
+
+	kmem_cache_alloc_head(cachep, flags);
+try_again:
+	local_irq_save(save_flags);
+#ifdef CONFIG_SMP
+	{
+		cpucache_t *cc = cc_data(cachep);
+
+		if (cc) {
+			if (cc->avail) {
+				STATS_INC_ALLOCHIT(cachep);
+				objp = cc_entry(cc)[--cc->avail];
+			} else {
+				STATS_INC_ALLOCMISS(cachep);
+				objp = kmem_cache_alloc_batch(cachep,cc,flags);
+				if (!objp)
+					goto alloc_new_slab_nolock;
+			}
+		} else {
+			spin_lock(&cachep->spinlock);
+			objp = kmem_cache_alloc_one(cachep);
+			spin_unlock(&cachep->spinlock);
+		}
+	}
+#else
+	objp = kmem_cache_alloc_one(cachep);
+#endif
+	local_irq_restore(save_flags);
+	return objp;
+alloc_new_slab:
+#ifdef CONFIG_SMP
+	spin_unlock(&cachep->spinlock);
+alloc_new_slab_nolock:
+#endif
+	local_irq_restore(save_flags);
+	if (kmem_cache_grow(cachep, flags))
+		/* Someone may have stolen our objs.  Doesn't matter, we'll
+		 * just come back here again.
+		 */
+		goto try_again;
+	return NULL;
+}
+
+/*
+ * Release an obj back to its cache. If the obj has a constructed
+ * state, it should be in this state _before_ it is released.
+ * - caller is responsible for the synchronization
+ */
+
+#if DEBUG
+# define CHECK_NR(pg)						\
+	do {							\
+		if (!VALID_PAGE(pg)) {				\
+			printk(KERN_ERR "kfree: out of range ptr %lxh.\n", \
+				(unsigned long)objp);		\
+			BUG();					\
+		} \
+	} while (0)
+# define CHECK_PAGE(page)					\
+	do {							\
+		CHECK_NR(page);					\
+		if (!PageSlab(page)) {				\
+			printk(KERN_ERR "kfree: bad ptr %lxh.\n", \
+				(unsigned long)objp);		\
+			BUG();					\
+		}						\
+	} while (0)
+
+#else
+# define CHECK_PAGE(pg)	do { } while (0)
+#endif
+
+static inline void kmem_cache_free_one(kmem_cache_t *cachep, void *objp)
+{
+	slab_t* slabp;
+
+	CHECK_PAGE(virt_to_page(objp));
+	/* reduces memory footprint
+	 *
+	if (OPTIMIZE(cachep))
+		slabp = (void*)((unsigned long)objp&(~(PAGE_SIZE-1)));
+	 else
+	 */
+	slabp = GET_PAGE_SLAB(virt_to_page(objp));
+
+#if DEBUG
+	if (cachep->flags & SLAB_DEBUG_INITIAL)
+		/* Need to call the slab's constructor so the
+		 * caller can perform a verify of its state (debugging).
+		 * Called without the cache-lock held.
+		 */
+		cachep->ctor(objp, cachep, SLAB_CTOR_CONSTRUCTOR|SLAB_CTOR_VERIFY);
+
+	if (cachep->flags & SLAB_RED_ZONE) {
+		objp -= BYTES_PER_WORD;
+		if (xchg((unsigned long *)objp, RED_MAGIC1) != RED_MAGIC2)
+			/* Either write before start, or a double free. */
+			BUG();
+		if (xchg((unsigned long *)(objp+cachep->objsize -
+				BYTES_PER_WORD), RED_MAGIC1) != RED_MAGIC2)
+			/* Either write past end, or a double free. */
+			BUG();
+	}
+	if (cachep->flags & SLAB_POISON)
+		kmem_poison_obj(cachep, objp);
+	if (kmem_extra_free_checks(cachep, slabp, objp))
+		return;
+#endif
+	{
+		unsigned int objnr = (objp-slabp->s_mem)/cachep->objsize;
+
+		slab_bufctl(slabp)[objnr] = slabp->free;
+		slabp->free = objnr;
+	}
+	STATS_DEC_ACTIVE(cachep);
+	
+	/* fixup slab chains */
+	{
+		int inuse = slabp->inuse;
+		if (unlikely(!--slabp->inuse)) {
+			/* Was partial or full, now empty. */
+			list_del(&slabp->list);
+			list_add(&slabp->list, &cachep->slabs_free);
+		} else if (unlikely(inuse == cachep->num)) {
+			/* Was full. */
+			list_del(&slabp->list);
+			list_add(&slabp->list, &cachep->slabs_partial);
+		}
+	}
+}
+
+#ifdef CONFIG_SMP
+static inline void __free_block (kmem_cache_t* cachep,
+							void** objpp, int len)
+{
+	for ( ; len > 0; len--, objpp++)
+		kmem_cache_free_one(cachep, *objpp);
+}
+
+static void free_block (kmem_cache_t* cachep, void** objpp, int len)
+{
+	spin_lock(&cachep->spinlock);
+	__free_block(cachep, objpp, len);
+	spin_unlock(&cachep->spinlock);
+}
+#endif
+
+/*
+ * __kmem_cache_free
+ * called with disabled ints
+ */
+static inline void __kmem_cache_free (kmem_cache_t *cachep, void* objp)
+{
+#ifdef CONFIG_SMP
+	cpucache_t *cc = cc_data(cachep);
+
+	CHECK_PAGE(virt_to_page(objp));
+	if (cc) {
+		int batchcount;
+		if (cc->avail < cc->limit) {
+			STATS_INC_FREEHIT(cachep);
+			cc_entry(cc)[cc->avail++] = objp;
+			return;
+		}
+		STATS_INC_FREEMISS(cachep);
+		batchcount = cachep->batchcount;
+		cc->avail -= batchcount;
+		free_block(cachep,
+					&cc_entry(cc)[cc->avail],batchcount);
+		cc_entry(cc)[cc->avail++] = objp;
+		return;
+	} else {
+		free_block(cachep, &objp, 1);
+	}
+#else
+	kmem_cache_free_one(cachep, objp);
+#endif
+}
+
+/**
+ * kmem_cache_alloc - Allocate an object
+ * @cachep: The cache to allocate from.
+ * @flags: See kmalloc().
+ *
+ * Allocate an object from this cache.  The flags are only relevant
+ * if the cache has no available objects.
+ */
+void * kmem_cache_alloc (kmem_cache_t *cachep, int flags)
+{
+	return __kmem_cache_alloc(cachep, flags);
+}
+
+/**
+ * kmalloc - allocate memory
+ * @size: how many bytes of memory are required.
+ * @flags: the type of memory to allocate.
+ *
+ * kmalloc is the normal method of allocating memory
+ * in the kernel.
+ *
+ * The @flags argument may be one of:
+ *
+ * %GFP_USER - Allocate memory on behalf of user.  May sleep.
+ *
+ * %GFP_KERNEL - Allocate normal kernel ram.  May sleep.
+ *
+ * %GFP_ATOMIC - Allocation will not sleep.  Use inside interrupt handlers.
+ *
+ * Additionally, the %GFP_DMA flag may be set to indicate the memory
+ * must be suitable for DMA.  This can mean different things on different
+ * platforms.  For example, on i386, it means that the memory must come
+ * from the first 16MB.
+ */
+void * kmalloc (size_t size, int flags)
+{
+	cache_sizes_t *csizep = cache_sizes;
+
+#ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
+	if (size >= PAGE_SIZE) {
+		unsigned long addr;
+		addr = __get_contiguous_pages(flags, (size+PAGE_SIZE-1)/PAGE_SIZE, 0);
+		return (void *)addr;
+	}
+#endif
+
+	for (; csizep->cs_size; csizep++) {
+		if (size > csizep->cs_size)
+			continue;
+		return __kmem_cache_alloc(flags & GFP_DMA ?
+			 csizep->cs_dmacachep : csizep->cs_cachep, flags);
+	}
+	return NULL;
+}
+
+/**
+ * kmem_cache_free - Deallocate an object
+ * @cachep: The cache the allocation was from.
+ * @objp: The previously allocated object.
+ *
+ * Free an object which was previously allocated from this
+ * cache.
+ */
+void kmem_cache_free (kmem_cache_t *cachep, void *objp)
+{
+	unsigned long flags;
+#if DEBUG
+	CHECK_PAGE(virt_to_page(objp));
+	if (cachep != GET_PAGE_CACHE(virt_to_page(objp)))
+		BUG();
+#endif
+
+	local_irq_save(flags);
+	__kmem_cache_free(cachep, objp);
+	local_irq_restore(flags);
+}
+
+/**
+ * kfree - free previously allocated memory
+ * @objp: pointer returned by kmalloc.
+ *
+ * Don't free memory not originally allocated by kmalloc()
+ * or you will run into trouble.
+ */
+void kfree (const void *objp)
+{
+	kmem_cache_t *c;
+	unsigned long flags;
+	struct page *p = virt_to_page(objp);
+
+	if (!objp)
+		return;
+
+	local_irq_save(flags);
+#ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
+	if (!PageSlab(p)) {
+		if (objp != page_address(p)) {
+			printk("flgs=0x%x objp=0x%x pga=0x%x\n", p->flags, objp, page_address(p));
+			BUG();
+		}
+		if (!page_contig(p)) {
+			printk("flgs=0x%x objp=0x%x pga=0x%x\n", p->flags, objp, page_address(p));
+			BUG();
+		}
+		free_contiguous_pages((unsigned long)objp, page_contig(p));
+		local_irq_restore(flags);
+		return;
+	}
+#endif
+	CHECK_PAGE(p);
+	c = GET_PAGE_CACHE(p);
+	__kmem_cache_free(c, (void*)objp);
+	local_irq_restore(flags);
+}
+
+unsigned int kmem_cache_size(kmem_cache_t *cachep)
+{
+#if DEBUG
+	if (cachep->flags & SLAB_RED_ZONE)
+		return (cachep->objsize - 2*BYTES_PER_WORD);
+#endif
+	return cachep->objsize;
+}
+
+kmem_cache_t * kmem_find_general_cachep (size_t size, int gfpflags)
+{
+	cache_sizes_t *csizep = cache_sizes;
+
+	/* This function could be moved to the header file, and
+	 * made inline so consumers can quickly determine what
+	 * cache pointer they require.
+	 */
+	for ( ; csizep->cs_size; csizep++) {
+		if (size > csizep->cs_size)
+			continue;
+		break;
+	}
+	return (gfpflags & GFP_DMA) ? csizep->cs_dmacachep : csizep->cs_cachep;
+}
+
+#ifdef CONFIG_SMP
+
+/* called with cache_chain_sem acquired.  */
+static int kmem_tune_cpucache (kmem_cache_t* cachep, int limit, int batchcount)
+{
+	ccupdate_struct_t new;
+	int i;
+
+	/*
+	 * These are admin-provided, so we are more graceful.
+	 */
+	if (limit < 0)
+		return -EINVAL;
+	if (batchcount < 0)
+		return -EINVAL;
+	if (batchcount > limit)
+		return -EINVAL;
+	if (limit != 0 && !batchcount)
+		return -EINVAL;
+
+	memset(&new.new,0,sizeof(new.new));
+	if (limit) {
+		for (i = 0; i< smp_num_cpus; i++) {
+			cpucache_t* ccnew;
+
+			ccnew = kmalloc(sizeof(void*)*limit+
+					sizeof(cpucache_t), GFP_KERNEL);
+			if (!ccnew)
+				goto oom;
+			ccnew->limit = limit;
+			ccnew->avail = 0;
+			new.new[cpu_logical_map(i)] = ccnew;
+		}
+	}
+	new.cachep = cachep;
+	spin_lock_irq(&cachep->spinlock);
+	cachep->batchcount = batchcount;
+	spin_unlock_irq(&cachep->spinlock);
+
+	smp_call_function_all_cpus(do_ccupdate_local, (void *)&new);
+
+	for (i = 0; i < smp_num_cpus; i++) {
+		cpucache_t* ccold = new.new[cpu_logical_map(i)];
+		if (!ccold)
+			continue;
+		local_irq_disable();
+		free_block(cachep, cc_entry(ccold), ccold->avail);
+		local_irq_enable();
+		kfree(ccold);
+	}
+	return 0;
+oom:
+	for (i--; i >= 0; i--)
+		kfree(new.new[cpu_logical_map(i)]);
+	return -ENOMEM;
+}
+
+static void enable_cpucache (kmem_cache_t *cachep)
+{
+	int err;
+	int limit;
+
+	/* FIXME: optimize */
+	if (cachep->objsize > PAGE_SIZE)
+		return;
+	if (cachep->objsize > 1024)
+		limit = 60;
+	else if (cachep->objsize > 256)
+		limit = 124;
+	else
+		limit = 252;
+
+	err = kmem_tune_cpucache(cachep, limit, limit/2);
+	if (err)
+		printk(KERN_ERR "enable_cpucache failed for %s, error %d.\n",
+					cachep->name, -err);
+}
+
+static void enable_all_cpucaches (void)
+{
+	struct list_head* p;
+
+	down(&cache_chain_sem);
+
+	p = &cache_cache.next;
+	do {
+		kmem_cache_t* cachep = list_entry(p, kmem_cache_t, next);
+
+		enable_cpucache(cachep);
+		p = cachep->next.next;
+	} while (p != &cache_cache.next);
+
+	up(&cache_chain_sem);
+}
+#endif
+
+/**
+ * kmem_cache_reap - Reclaim memory from caches.
+ * @gfp_mask: the type of memory required.
+ *
+ * Called from do_try_to_free_pages() and __alloc_pages()
+ */
+int fastcall kmem_cache_reap (int gfp_mask)
+{
+	slab_t *slabp;
+	kmem_cache_t *searchp;
+	kmem_cache_t *best_cachep;
+	unsigned int best_pages;
+	unsigned int best_len;
+	unsigned int scan;
+	int ret = 0;
+
+	if (gfp_mask & __GFP_WAIT)
+		down(&cache_chain_sem);
+	else
+		if (down_trylock(&cache_chain_sem))
+			return 0;
+
+	scan = REAP_SCANLEN;
+	best_len = 0;
+	best_pages = 0;
+	best_cachep = NULL;
+	searchp = clock_searchp;
+	do {
+		unsigned int pages;
+		struct list_head* p;
+		unsigned int full_free;
+
+		/* It's safe to test this without holding the cache-lock. */
+		if (searchp->flags & SLAB_NO_REAP)
+			goto next;
+		spin_lock_irq(&searchp->spinlock);
+		if (searchp->growing)
+			goto next_unlock;
+		if (searchp->dflags & DFLGS_GROWN) {
+			searchp->dflags &= ~DFLGS_GROWN;
+			goto next_unlock;
+		}
+#ifdef CONFIG_SMP
+		{
+			cpucache_t *cc = cc_data(searchp);
+			if (cc && cc->avail) {
+				__free_block(searchp, cc_entry(cc), cc->avail);
+				cc->avail = 0;
+			}
+		}
+#endif
+
+		full_free = 0;
+		p = searchp->slabs_free.next;
+		while (p != &searchp->slabs_free) {
+#if DEBUG
+			slabp = list_entry(p, slab_t, list);
+
+			if (slabp->inuse)
+				BUG();
+#endif
+			full_free++;
+			p = p->next;
+		}
+
+		/*
+		 * Try to avoid slabs with constructors and/or
+		 * more than one page per slab (as it can be difficult
+		 * to get high orders from gfp()).
+		 */
+		pages = full_free * (1<<searchp->gfporder);
+		if (searchp->ctor)
+			pages = (pages*4+1)/5;
+		if (searchp->gfporder)
+			pages = (pages*4+1)/5;
+		if (pages > best_pages) {
+			best_cachep = searchp;
+			best_len = full_free;
+			best_pages = pages;
+			if (pages >= REAP_PERFECT) {
+				clock_searchp = list_entry(searchp->next.next,
+							kmem_cache_t,next);
+				goto perfect;
+			}
+		}
+next_unlock:
+		spin_unlock_irq(&searchp->spinlock);
+next:
+		searchp = list_entry(searchp->next.next,kmem_cache_t,next);
+	} while (--scan && searchp != clock_searchp);
+
+	clock_searchp = searchp;
+
+	if (!best_cachep)
+		/* couldn't find anything to reap */
+		goto out;
+
+	spin_lock_irq(&best_cachep->spinlock);
+perfect:
+	/* free only 50% of the free slabs */
+	best_len = (best_len + 1)/2;
+	for (scan = 0; scan < best_len; scan++) {
+		struct list_head *p;
+
+		if (best_cachep->growing)
+			break;
+		p = best_cachep->slabs_free.prev;
+		if (p == &best_cachep->slabs_free)
+			break;
+		slabp = list_entry(p,slab_t,list);
+#if DEBUG
+		if (slabp->inuse)
+			BUG();
+#endif
+		list_del(&slabp->list);
+		STATS_INC_REAPED(best_cachep);
+
+		/* Safe to drop the lock. The slab is no longer linked to the
+		 * cache.
+		 */
+		spin_unlock_irq(&best_cachep->spinlock);
+		kmem_slab_destroy(best_cachep, slabp);
+		spin_lock_irq(&best_cachep->spinlock);
+	}
+	spin_unlock_irq(&best_cachep->spinlock);
+	ret = scan * (1 << best_cachep->gfporder);
+out:
+	up(&cache_chain_sem);
+	return ret;
+}
+
+#ifdef CONFIG_PROC_FS
+
+static void *s_start(struct seq_file *m, loff_t *pos)
+{
+	loff_t n = *pos;
+	struct list_head *p;
+
+	down(&cache_chain_sem);
+	if (!n)
+		return (void *)1;
+	p = &cache_cache.next;
+	while (--n) {
+		p = p->next;
+		if (p == &cache_cache.next)
+			return NULL;
+	}
+	return list_entry(p, kmem_cache_t, next);
+}
+
+static void *s_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	kmem_cache_t *cachep = p;
+	++*pos;
+	if (p == (void *)1)
+		return &cache_cache;
+	cachep = list_entry(cachep->next.next, kmem_cache_t, next);
+	return cachep == &cache_cache ? NULL : cachep;
+}
+
+static void s_stop(struct seq_file *m, void *p)
+{
+	up(&cache_chain_sem);
+}
+
+static int s_show(struct seq_file *m, void *p)
+{
+	kmem_cache_t *cachep = p;
+	struct list_head *q;
+	slab_t		*slabp;
+	unsigned long	active_objs;
+	unsigned long	num_objs;
+	unsigned long	active_slabs = 0;
+	unsigned long	num_slabs;
+	const char *name; 
+
+	if (p == (void*)1) {
+		/*
+		 * Output format version, so at least we can change it
+		 * without _too_ many complaints.
+		 */
+		seq_puts(m, "slabinfo - version: 1.1"
+#if STATS
+				" (statistics)"
+#endif
+#ifdef CONFIG_SMP
+				" (SMP)"
+#endif
+				"\n");
+		return 0;
+	}
+
+	spin_lock_irq(&cachep->spinlock);
+	active_objs = 0;
+	num_slabs = 0;
+	list_for_each(q,&cachep->slabs_full) {
+		slabp = list_entry(q, slab_t, list);
+		if (slabp->inuse != cachep->num)
+			BUG();
+		active_objs += cachep->num;
+		active_slabs++;
+	}
+	list_for_each(q,&cachep->slabs_partial) {
+		slabp = list_entry(q, slab_t, list);
+		if (slabp->inuse == cachep->num || !slabp->inuse)
+			BUG();
+		active_objs += slabp->inuse;
+		active_slabs++;
+	}
+	list_for_each(q,&cachep->slabs_free) {
+		slabp = list_entry(q, slab_t, list);
+		if (slabp->inuse)
+			BUG();
+		num_slabs++;
+	}
+	num_slabs+=active_slabs;
+	num_objs = num_slabs*cachep->num;
+
+	name = cachep->name; 
+	{
+	char tmp; 
+	mm_segment_t	old_fs;
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	if (__get_user(tmp, name)) 
+		name = "broken"; 
+	set_fs(old_fs);
+	}       
+
+	seq_printf(m, "%-17s %6lu %6lu %6u %4lu %4lu %4u",
+		name, active_objs, num_objs, cachep->objsize,
+		active_slabs, num_slabs, (1<<cachep->gfporder));
+
+#if STATS
+	{
+		unsigned long errors = cachep->errors;
+		unsigned long high = cachep->high_mark;
+		unsigned long grown = cachep->grown;
+		unsigned long reaped = cachep->reaped;
+		unsigned long allocs = cachep->num_allocations;
+
+		seq_printf(m, " : %6lu %7lu %5lu %4lu %4lu",
+				high, allocs, grown, reaped, errors);
+	}
+#endif
+#ifdef CONFIG_SMP
+	{
+		cpucache_t *cc = cc_data(cachep);
+		unsigned int batchcount = cachep->batchcount;
+		unsigned int limit;
+
+		if (cc)
+			limit = cc->limit;
+		else
+			limit = 0;
+		seq_printf(m, " : %4u %4u",
+				limit, batchcount);
+	}
+#endif
+#if STATS && defined(CONFIG_SMP)
+	{
+		unsigned long allochit = atomic_read(&cachep->allochit);
+		unsigned long allocmiss = atomic_read(&cachep->allocmiss);
+		unsigned long freehit = atomic_read(&cachep->freehit);
+		unsigned long freemiss = atomic_read(&cachep->freemiss);
+		seq_printf(m, " : %6lu %6lu %6lu %6lu",
+				allochit, allocmiss, freehit, freemiss);
+	}
+#endif
+	spin_unlock_irq(&cachep->spinlock);
+	seq_putc(m, '\n');
+	return 0;
+}
+
+/**
+ * slabinfo_op - iterator that generates /proc/slabinfo
+ *
+ * Output layout:
+ * cache-name
+ * num-active-objs
+ * total-objs
+ * object size
+ * num-active-slabs
+ * total-slabs
+ * num-pages-per-slab
+ * + further values on SMP and with statistics enabled
+ */
+
+struct seq_operations slabinfo_op = {
+	start:	s_start,
+	next:	s_next,
+	stop:	s_stop,
+	show:	s_show
+};
+
+#define MAX_SLABINFO_WRITE 128
+/**
+ * slabinfo_write - SMP tuning for the slab allocator
+ * @file: unused
+ * @buffer: user buffer
+ * @count: data len
+ * @data: unused
+ */
+ssize_t slabinfo_write(struct file *file, const char *buffer,
+				size_t count, loff_t *ppos)
+{
+#ifdef CONFIG_SMP
+	char kbuf[MAX_SLABINFO_WRITE+1], *tmp;
+	int limit, batchcount, res;
+	struct list_head *p;
+	
+	if (count > MAX_SLABINFO_WRITE)
+		return -EINVAL;
+	if (copy_from_user(&kbuf, buffer, count))
+		return -EFAULT;
+	kbuf[MAX_SLABINFO_WRITE] = '\0'; 
+
+	tmp = strchr(kbuf, ' ');
+	if (!tmp)
+		return -EINVAL;
+	*tmp = '\0';
+	tmp++;
+	limit = simple_strtol(tmp, &tmp, 10);
+	while (*tmp == ' ')
+		tmp++;
+	batchcount = simple_strtol(tmp, &tmp, 10);
+
+	/* Find the cache in the chain of caches. */
+	down(&cache_chain_sem);
+	res = -EINVAL;
+	list_for_each(p,&cache_chain) {
+		kmem_cache_t *cachep = list_entry(p, kmem_cache_t, next);
+
+		if (!strcmp(cachep->name, kbuf)) {
+			res = kmem_tune_cpucache(cachep, limit, batchcount);
+			break;
+		}
+	}
+	up(&cache_chain_sem);
+	if (res >= 0)
+		res = count;
+	return res;
+#else
+	return -EINVAL;
+#endif
+}
+#endif
+
+
+#ifdef NO_MM
+/*
+ * return the total memory allocated for this pointer,  not
+ * just what the caller asked for
+ */
+
+size_t
+ksize(const void *objp)
+{
+	struct page *page;
+	kmem_cache_t *c;
+	unsigned long flags;
+	int size;
+
+	if (!objp)
+		return(0);
+	local_irq_save(flags);
+	size = MAP_NR(objp);
+	if (size < 0 || size >= max_mapnr)
+		return(0);
+	page = &mem_map[size];
+
+	if (!PageSlab(page)) { /* not allocated with kmalloc */
+#ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
+		if (page_contig(page))
+			size = page_contig(page) * PAGE_SIZE;
+		else
+#endif
+		if (page->index < 0 || page->index >= MAX_ORDER) {
+			printk("ksize on unknown page type (index=%ld)!\n", page->index);
+			size = PAGE_SIZE;
+		} else
+			size = PAGE_SIZE << page->index;
+	} else {
+		CHECK_PAGE(page);
+		c = GET_PAGE_CACHE(page);
+		size = c->objsize;
+	}
+	local_irq_restore(flags);
+	return size;
+}
+
+#endif
diff -urN linux-2.4.29/mmnommu/swap.c linux-2.4.29-uc1/mmnommu/swap.c
--- linux-2.4.29/mmnommu/swap.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/swap.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,185 @@
+/*
+ *  linux/mm/swap.c
+ *
+ *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ */
+
+/*
+ * This file contains the default values for the opereation of the
+ * Linux VM subsystem. Fine-tuning documentation can be found in
+ * linux/Documentation/sysctl/vm.txt.
+ * Started 18.12.91
+ * Swap aging added 23.2.95, Stephen Tweedie.
+ * Buffermem limits added 12.3.98, Rik van Riel.
+ */
+
+#include <linux/mm.h>
+#include <linux/kernel_stat.h>
+#include <linux/swap.h>
+#include <linux/swapctl.h>
+#include <linux/pagemap.h>
+#include <linux/init.h>
+
+#include <asm/dma.h>
+#include <asm/uaccess.h> /* for copy_to/from_user */
+#include <asm/pgtable.h>
+
+/* How many pages do we try to swap or page in/out together? */
+int page_cluster;
+
+pager_daemon_t pager_daemon = {
+	512,	/* base number for calculating the number of tries */
+	SWAP_CLUSTER_MAX,	/* minimum number of tries */
+	8,	/* do swap I/O in clusters of this size */
+};
+
+/*
+ * Move an inactive page to the active list.
+ */
+static inline void activate_page_nolock(struct page * page)
+{
+	if (PageLRU(page) && !PageActive(page)) {
+		del_page_from_inactive_list(page);
+		add_page_to_active_list(page);
+	}
+}
+
+void fastcall activate_page(struct page * page)
+{
+	spin_lock(&pagemap_lru_lock);
+	activate_page_nolock(page);
+	spin_unlock(&pagemap_lru_lock);
+}
+
+/**
+ * lru_cache_add: add a page to the page lists
+ * @page: the page to add
+ */
+void fastcall lru_cache_add(struct page * page)
+{
+	if (!PageLRU(page)) {
+		spin_lock(&pagemap_lru_lock);
+		if (!TestSetPageLRU(page))
+			add_page_to_inactive_list(page);
+		spin_unlock(&pagemap_lru_lock);
+	}
+}
+
+/**
+ * __lru_cache_del: remove a page from the page lists
+ * @page: the page to add
+ *
+ * This function is for when the caller already holds
+ * the pagemap_lru_lock.
+ */
+void fastcall __lru_cache_del(struct page * page)
+{
+	if (TestClearPageLRU(page)) {
+		if (PageActive(page)) {
+			del_page_from_active_list(page);
+		} else {
+			del_page_from_inactive_list(page);
+		}
+	}
+}
+
+/**
+ * lru_cache_del: remove a page from the page lists
+ * @page: the page to remove
+ */
+void fastcall lru_cache_del(struct page * page)
+{
+	spin_lock(&pagemap_lru_lock);
+	__lru_cache_del(page);
+	spin_unlock(&pagemap_lru_lock);
+}
+
+/**
+ * delta_nr_active_pages: alter the number of active pages.
+ *
+ * @page: the page which is being activated/deactivated
+ * @delta: +1 for activation, -1 for deactivation
+ *
+ * Called under pagecache_lock
+ */
+void delta_nr_active_pages(struct page *page, long delta)
+{
+	pg_data_t *pgdat;
+	zone_t *classzone, *overflow;
+
+	classzone = page_zone(page);
+	pgdat = classzone->zone_pgdat;
+	overflow = pgdat->node_zones + pgdat->nr_zones;
+
+	while (classzone < overflow) {
+		classzone->nr_active_pages += delta;
+		classzone++;
+	}
+	nr_active_pages += delta;
+}
+
+/**
+ * delta_nr_inactive_pages: alter the number of inactive pages.
+ *
+ * @page: the page which is being deactivated/activated
+ * @delta: +1 for deactivation, -1 for activation
+ *
+ * Called under pagecache_lock
+ */
+void delta_nr_inactive_pages(struct page *page, long delta)
+{
+	pg_data_t *pgdat;
+	zone_t *classzone, *overflow;
+
+	classzone = page_zone(page);
+	pgdat = classzone->zone_pgdat;
+	overflow = pgdat->node_zones + pgdat->nr_zones;
+
+	while (classzone < overflow) {
+		classzone->nr_inactive_pages += delta;
+		classzone++;
+	}
+	nr_inactive_pages += delta;
+}
+
+/**
+ * delta_nr_cache_pages: alter the number of pages in the pagecache
+ *
+ * @page: the page which is being added/removed
+ * @delta: +1 for addition, -1 for removal
+ *
+ * Called under pagecache_lock
+ */
+void delta_nr_cache_pages(struct page *page, long delta)
+{
+	pg_data_t *pgdat;
+	zone_t *classzone, *overflow;
+
+	classzone = page_zone(page);
+	pgdat = classzone->zone_pgdat;
+	overflow = pgdat->node_zones + pgdat->nr_zones;
+
+	while (classzone < overflow) {
+		classzone->nr_cache_pages += delta;
+		classzone++;
+	}
+	page_cache_size += delta;
+}
+
+/*
+ * Perform any setup for the swap system
+ */
+void __init swap_setup(void)
+{
+	unsigned long megs = num_physpages >> (20 - PAGE_SHIFT);
+
+	/* Use a smaller cluster for small-memory machines */
+	if (megs < 16)
+		page_cluster = 2;
+	else
+		page_cluster = 3;
+	/*
+	 * Right now other parts of the system means that we
+	 * _really_ don't want to cluster much more
+	 */
+}
diff -urN linux-2.4.29/mmnommu/swapfile.c linux-2.4.29-uc1/mmnommu/swapfile.c
--- linux-2.4.29/mmnommu/swapfile.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/swapfile.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,1293 @@
+/*
+ *  linux/mm/swapfile.c
+ *
+ *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ *  Swap reorganised 29.12.95, Stephen Tweedie
+ *  NO_MM
+ *     Copyright (c) 2001 Lineo, Inc. David McCullough <davidm@lineo.com>
+ *     Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org> ref uClinux 2.0
+ */
+
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel_stat.h>
+#include <linux/swap.h>
+#include <linux/swapctl.h>
+#include <linux/blkdev.h> /* for blk_size */
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <linux/shm.h>
+
+#include <asm/pgtable.h>
+
+#ifndef NO_MM
+
+spinlock_t swaplock = SPIN_LOCK_UNLOCKED;
+unsigned int nr_swapfiles;
+int total_swap_pages;
+static int swap_overflow;
+
+static const char Bad_file[] = "Bad swap file entry ";
+static const char Unused_file[] = "Unused swap file entry ";
+static const char Bad_offset[] = "Bad swap offset entry ";
+static const char Unused_offset[] = "Unused swap offset entry ";
+
+struct swap_list_t swap_list = {-1, -1};
+
+struct swap_info_struct swap_info[MAX_SWAPFILES];
+
+#define SWAPFILE_CLUSTER 256
+
+static inline int scan_swap_map(struct swap_info_struct *si)
+{
+	unsigned long offset;
+	/* 
+	 * We try to cluster swap pages by allocating them
+	 * sequentially in swap.  Once we've allocated
+	 * SWAPFILE_CLUSTER pages this way, however, we resort to
+	 * first-free allocation, starting a new cluster.  This
+	 * prevents us from scattering swap pages all over the entire
+	 * swap partition, so that we reduce overall disk seek times
+	 * between swap pages.  -- sct */
+	if (si->cluster_nr) {
+		while (si->cluster_next <= si->highest_bit) {
+			offset = si->cluster_next++;
+			if (si->swap_map[offset])
+				continue;
+			si->cluster_nr--;
+			goto got_page;
+		}
+	}
+	si->cluster_nr = SWAPFILE_CLUSTER;
+
+	/* try to find an empty (even not aligned) cluster. */
+	offset = si->lowest_bit;
+ check_next_cluster:
+	if (offset+SWAPFILE_CLUSTER-1 <= si->highest_bit)
+	{
+		int nr;
+		for (nr = offset; nr < offset+SWAPFILE_CLUSTER; nr++)
+			if (si->swap_map[nr])
+			{
+				offset = nr+1;
+				goto check_next_cluster;
+			}
+		/* We found a completly empty cluster, so start
+		 * using it.
+		 */
+		goto got_page;
+	}
+	/* No luck, so now go finegrined as usual. -Andrea */
+	for (offset = si->lowest_bit; offset <= si->highest_bit ; offset++) {
+		if (si->swap_map[offset])
+			continue;
+		si->lowest_bit = offset+1;
+	got_page:
+		if (offset == si->lowest_bit)
+			si->lowest_bit++;
+		if (offset == si->highest_bit)
+			si->highest_bit--;
+		if (si->lowest_bit > si->highest_bit) {
+			si->lowest_bit = si->max;
+			si->highest_bit = 0;
+		}
+		si->swap_map[offset] = 1;
+		nr_swap_pages--;
+		si->cluster_next = offset+1;
+		return offset;
+	}
+	si->lowest_bit = si->max;
+	si->highest_bit = 0;
+	return 0;
+}
+
+swp_entry_t get_swap_page(void)
+{
+	struct swap_info_struct * p;
+	unsigned long offset;
+	swp_entry_t entry;
+	int type, wrapped = 0;
+
+	entry.val = 0;	/* Out of memory */
+	swap_list_lock();
+	type = swap_list.next;
+	if (type < 0)
+		goto out;
+	if (nr_swap_pages <= 0)
+		goto out;
+
+	while (1) {
+		p = &swap_info[type];
+		if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
+			swap_device_lock(p);
+			offset = scan_swap_map(p);
+			swap_device_unlock(p);
+			if (offset) {
+				entry = SWP_ENTRY(type,offset);
+				type = swap_info[type].next;
+				if (type < 0 ||
+					p->prio != swap_info[type].prio) {
+						swap_list.next = swap_list.head;
+				} else {
+					swap_list.next = type;
+				}
+				goto out;
+			}
+		}
+		type = p->next;
+		if (!wrapped) {
+			if (type < 0 || p->prio != swap_info[type].prio) {
+				type = swap_list.head;
+				wrapped = 1;
+			}
+		} else
+			if (type < 0)
+				goto out;	/* out of swap space */
+	}
+out:
+	swap_list_unlock();
+	return entry;
+}
+
+static struct swap_info_struct * swap_info_get(swp_entry_t entry)
+{
+	struct swap_info_struct * p;
+	unsigned long offset, type;
+
+	if (!entry.val)
+		goto out;
+	type = SWP_TYPE(entry);
+	if (type >= nr_swapfiles)
+		goto bad_nofile;
+	p = & swap_info[type];
+	if (!(p->flags & SWP_USED))
+		goto bad_device;
+	offset = SWP_OFFSET(entry);
+	if (offset >= p->max)
+		goto bad_offset;
+	if (!p->swap_map[offset])
+		goto bad_free;
+	swap_list_lock();
+	if (p->prio > swap_info[swap_list.next].prio)
+		swap_list.next = type;
+	swap_device_lock(p);
+	return p;
+
+bad_free:
+	printk(KERN_ERR "swap_free: %s%08lx\n", Unused_offset, entry.val);
+	goto out;
+bad_offset:
+	printk(KERN_ERR "swap_free: %s%08lx\n", Bad_offset, entry.val);
+	goto out;
+bad_device:
+	printk(KERN_ERR "swap_free: %s%08lx\n", Unused_file, entry.val);
+	goto out;
+bad_nofile:
+	printk(KERN_ERR "swap_free: %s%08lx\n", Bad_file, entry.val);
+out:
+	return NULL;
+}	
+
+static void swap_info_put(struct swap_info_struct * p)
+{
+	swap_device_unlock(p);
+	swap_list_unlock();
+}
+
+static int swap_entry_free(struct swap_info_struct *p, unsigned long offset)
+{
+	int count = p->swap_map[offset];
+
+	if (count < SWAP_MAP_MAX) {
+		count--;
+		p->swap_map[offset] = count;
+		if (!count) {
+			if (offset < p->lowest_bit)
+				p->lowest_bit = offset;
+			if (offset > p->highest_bit)
+				p->highest_bit = offset;
+			nr_swap_pages++;
+		}
+	}
+	return count;
+}
+
+/*
+ * Caller has made sure that the swapdevice corresponding to entry
+ * is still around or has not been recycled.
+ */
+void swap_free(swp_entry_t entry)
+{
+	struct swap_info_struct * p;
+
+	p = swap_info_get(entry);
+	if (p) {
+		swap_entry_free(p, SWP_OFFSET(entry));
+		swap_info_put(p);
+	}
+}
+
+/*
+ * Check if we're the only user of a swap page,
+ * when the page is locked.
+ */
+static int exclusive_swap_page(struct page *page)
+{
+	int retval = 0;
+	struct swap_info_struct * p;
+	swp_entry_t entry;
+
+	entry.val = page->index;
+	p = swap_info_get(entry);
+	if (p) {
+		/* Is the only swap cache user the cache itself? */
+		if (p->swap_map[SWP_OFFSET(entry)] == 1) {
+			/* Recheck the page count with the pagecache lock held.. */
+			spin_lock(&pagecache_lock);
+			if (page_count(page) - !!page->buffers == 2)
+				retval = 1;
+			spin_unlock(&pagecache_lock);
+		}
+		swap_info_put(p);
+	}
+	return retval;
+}
+
+/*
+ * We can use this swap cache entry directly
+ * if there are no other references to it.
+ *
+ * Here "exclusive_swap_page()" does the real
+ * work, but we opportunistically check whether
+ * we need to get all the locks first..
+ */
+int fastcall can_share_swap_page(struct page *page)
+{
+	int retval = 0;
+
+	if (!PageLocked(page))
+		BUG();
+	switch (page_count(page)) {
+	case 3:
+		if (!page->buffers)
+			break;
+		/* Fallthrough */
+	case 2:
+		if (!PageSwapCache(page))
+			break;
+		retval = exclusive_swap_page(page);
+		break;
+	case 1:
+		if (PageReserved(page))
+			break;
+		retval = 1;
+	}
+	return retval;
+}
+
+/*
+ * Work out if there are any other processes sharing this
+ * swap cache page. Free it if you can. Return success.
+ */
+int fastcall remove_exclusive_swap_page(struct page *page)
+{
+	int retval;
+	struct swap_info_struct * p;
+	swp_entry_t entry;
+
+	if (!PageLocked(page))
+		BUG();
+	if (!PageSwapCache(page))
+		return 0;
+	if (page_count(page) - !!page->buffers != 2)	/* 2: us + cache */
+		return 0;
+
+	entry.val = page->index;
+	p = swap_info_get(entry);
+	if (!p)
+		return 0;
+
+	/* Is the only swap cache user the cache itself? */
+	retval = 0;
+	if (p->swap_map[SWP_OFFSET(entry)] == 1) {
+		/* Recheck the page count with the pagecache lock held.. */
+		spin_lock(&pagecache_lock);
+		if (page_count(page) - !!page->buffers == 2) {
+			__delete_from_swap_cache(page);
+			SetPageDirty(page);
+			retval = 1;
+		}
+		spin_unlock(&pagecache_lock);
+	}
+	swap_info_put(p);
+
+	if (retval) {
+		block_flushpage(page, 0);
+		swap_free(entry);
+		page_cache_release(page);
+	}
+
+	return retval;
+}
+
+/*
+ * Free the swap entry like above, but also try to
+ * free the page cache entry if it is the last user.
+ */
+void free_swap_and_cache(swp_entry_t entry)
+{
+	struct swap_info_struct * p;
+	struct page *page = NULL;
+
+	p = swap_info_get(entry);
+	if (p) {
+		if (swap_entry_free(p, SWP_OFFSET(entry)) == 1)
+			page = find_trylock_page(&swapper_space, entry.val);
+		swap_info_put(p);
+	}
+	if (page) {
+		page_cache_get(page);
+		/* Only cache user (+us), or swap space full? Free it! */
+		if (page_count(page) - !!page->buffers == 2 || vm_swap_full()) {
+			delete_from_swap_cache(page);
+			SetPageDirty(page);
+		}
+		UnlockPage(page);
+		page_cache_release(page);
+	}
+}
+
+/*
+ * The swap entry has been read in advance, and we return 1 to indicate
+ * that the page has been used or is no longer needed.
+ *
+ * Always set the resulting pte to be nowrite (the same as COW pages
+ * after one process has exited).  We don't know just how many PTEs will
+ * share this swap entry, so be cautious and let do_wp_page work out
+ * what to do if a write is requested later.
+ */
+/* mmlist_lock and vma->vm_mm->page_table_lock are held */
+static inline void unuse_pte(struct vm_area_struct * vma, unsigned long address,
+	pte_t *dir, swp_entry_t entry, struct page* page)
+{
+	pte_t pte = *dir;
+
+	if (likely(pte_to_swp_entry(pte).val != entry.val))
+		return;
+	if (unlikely(pte_none(pte) || pte_present(pte)))
+		return;
+	get_page(page);
+	set_pte(dir, pte_mkold(mk_pte(page, vma->vm_page_prot)));
+	swap_free(entry);
+	++vma->vm_mm->rss;
+}
+
+/* mmlist_lock and vma->vm_mm->page_table_lock are held */
+static inline void unuse_pmd(struct vm_area_struct * vma, pmd_t *dir,
+	unsigned long address, unsigned long size, unsigned long offset,
+	swp_entry_t entry, struct page* page)
+{
+	pte_t * pte;
+	unsigned long end;
+
+	if (pmd_none(*dir))
+		return;
+	if (pmd_bad(*dir)) {
+		pmd_ERROR(*dir);
+		pmd_clear(dir);
+		return;
+	}
+	pte = pte_offset(dir, address);
+	offset += address & PMD_MASK;
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	do {
+		unuse_pte(vma, offset+address-vma->vm_start, pte, entry, page);
+		address += PAGE_SIZE;
+		pte++;
+	} while (address && (address < end));
+}
+
+/* mmlist_lock and vma->vm_mm->page_table_lock are held */
+static inline void unuse_pgd(struct vm_area_struct * vma, pgd_t *dir,
+	unsigned long address, unsigned long size,
+	swp_entry_t entry, struct page* page)
+{
+	pmd_t * pmd;
+	unsigned long offset, end;
+
+	if (pgd_none(*dir))
+		return;
+	if (pgd_bad(*dir)) {
+		pgd_ERROR(*dir);
+		pgd_clear(dir);
+		return;
+	}
+	pmd = pmd_offset(dir, address);
+	offset = address & PGDIR_MASK;
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	if (address >= end)
+		BUG();
+	do {
+		unuse_pmd(vma, pmd, address, end - address, offset, entry,
+			  page);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address && (address < end));
+}
+
+/* mmlist_lock and vma->vm_mm->page_table_lock are held */
+static void unuse_vma(struct vm_area_struct * vma, pgd_t *pgdir,
+			swp_entry_t entry, struct page* page)
+{
+	unsigned long start = vma->vm_start, end = vma->vm_end;
+
+	if (start >= end)
+		BUG();
+	do {
+		unuse_pgd(vma, pgdir, start, end - start, entry, page);
+		start = (start + PGDIR_SIZE) & PGDIR_MASK;
+		pgdir++;
+	} while (start && (start < end));
+}
+
+static void unuse_process(struct mm_struct * mm,
+			swp_entry_t entry, struct page* page)
+{
+	struct vm_area_struct* vma;
+
+	/*
+	 * Go through process' page directory.
+	 */
+	spin_lock(&mm->page_table_lock);
+	for (vma = mm->mmap; vma; vma = vma->vm_next) {
+		pgd_t * pgd = pgd_offset(mm, vma->vm_start);
+		unuse_vma(vma, pgd, entry, page);
+	}
+	spin_unlock(&mm->page_table_lock);
+	return;
+}
+
+/*
+ * Scan swap_map from current position to next entry still in use.
+ * Recycle to start on reaching the end, returning 0 when empty.
+ */
+static int find_next_to_unuse(struct swap_info_struct *si, int prev)
+{
+	int max = si->max;
+	int i = prev;
+	int count;
+
+	/*
+	 * No need for swap_device_lock(si) here: we're just looking
+	 * for whether an entry is in use, not modifying it; false
+	 * hits are okay, and sys_swapoff() has already prevented new
+	 * allocations from this area (while holding swap_list_lock()).
+	 */
+	for (;;) {
+		if (++i >= max) {
+			if (!prev) {
+				i = 0;
+				break;
+			}
+			/*
+			 * No entries in use at top of swap_map,
+			 * loop back to start and recheck there.
+			 */
+			max = prev + 1;
+			prev = 0;
+			i = 1;
+		}
+		count = si->swap_map[i];
+		if (count && count != SWAP_MAP_BAD)
+			break;
+	}
+	return i;
+}
+
+/*
+ * We completely avoid races by reading each swap page in advance,
+ * and then search for the process using it.  All the necessary
+ * page table adjustments can then be made atomically.
+ */
+static int try_to_unuse(unsigned int type)
+{
+	struct swap_info_struct * si = &swap_info[type];
+	struct mm_struct *start_mm;
+	unsigned short *swap_map;
+	unsigned short swcount;
+	struct page *page;
+	swp_entry_t entry;
+	int i = 0;
+	int retval = 0;
+	int reset_overflow = 0;
+	int shmem;
+
+	/*
+	 * When searching mms for an entry, a good strategy is to
+	 * start at the first mm we freed the previous entry from
+	 * (though actually we don't notice whether we or coincidence
+	 * freed the entry).  Initialize this start_mm with a hold.
+	 *
+	 * A simpler strategy would be to start at the last mm we
+	 * freed the previous entry from; but that would take less
+	 * advantage of mmlist ordering (now preserved by swap_out()),
+	 * which clusters forked address spaces together, most recent
+	 * child immediately after parent.  If we race with dup_mmap(),
+	 * we very much want to resolve parent before child, otherwise
+	 * we may miss some entries: using last mm would invert that.
+	 */
+	start_mm = &init_mm;
+	atomic_inc(&init_mm.mm_users);
+
+	/*
+	 * Keep on scanning until all entries have gone.  Usually,
+	 * one pass through swap_map is enough, but not necessarily:
+	 * mmput() removes mm from mmlist before exit_mmap() and its
+	 * zap_page_range().  That's not too bad, those entries are
+	 * on their way out, and handled faster there than here.
+	 * do_munmap() behaves similarly, taking the range out of mm's
+	 * vma list before zap_page_range().  But unfortunately, when
+	 * unmapping a part of a vma, it takes the whole out first,
+	 * then reinserts what's left after (might even reschedule if
+	 * open() method called) - so swap entries may be invisible
+	 * to swapoff for a while, then reappear - but that is rare.
+	 */
+	while ((i = find_next_to_unuse(si, i))) {
+		/* 
+		 * Get a page for the entry, using the existing swap
+		 * cache page if there is one.  Otherwise, get a clean
+		 * page and read the swap into it. 
+		 */
+		swap_map = &si->swap_map[i];
+		entry = SWP_ENTRY(type, i);
+		page = read_swap_cache_async(entry);
+		if (!page) {
+			/*
+			 * Either swap_duplicate() failed because entry
+			 * has been freed independently, and will not be
+			 * reused since sys_swapoff() already disabled
+			 * allocation from here, or alloc_page() failed.
+			 */
+			if (!*swap_map)
+				continue;
+			retval = -ENOMEM;
+			break;
+		}
+
+		/*
+		 * Don't hold on to start_mm if it looks like exiting.
+		 */
+		if (atomic_read(&start_mm->mm_users) == 1) {
+			mmput(start_mm);
+			start_mm = &init_mm;
+			atomic_inc(&init_mm.mm_users);
+		}
+
+		/*
+		 * Wait for and lock page.  When do_swap_page races with
+		 * try_to_unuse, do_swap_page can handle the fault much
+		 * faster than try_to_unuse can locate the entry.  This
+		 * apparently redundant "wait_on_page" lets try_to_unuse
+		 * defer to do_swap_page in such a case - in some tests,
+		 * do_swap_page and try_to_unuse repeatedly compete.
+		 */
+		wait_on_page(page);
+		lock_page(page);
+
+		/*
+		 * Remove all references to entry, without blocking.
+		 * Whenever we reach init_mm, there's no address space
+		 * to search, but use it as a reminder to search shmem.
+		 */
+		shmem = 0;
+		swcount = *swap_map;
+		if (swcount > 1) {
+			flush_page_to_ram(page);
+			if (start_mm == &init_mm)
+				shmem = shmem_unuse(entry, page);
+			else
+				unuse_process(start_mm, entry, page);
+		}
+		if (*swap_map > 1) {
+			int set_start_mm = (*swap_map >= swcount);
+			struct list_head *p = &start_mm->mmlist;
+			struct mm_struct *new_start_mm = start_mm;
+			struct mm_struct *mm;
+
+			spin_lock(&mmlist_lock);
+			while (*swap_map > 1 &&
+					(p = p->next) != &start_mm->mmlist) {
+				mm = list_entry(p, struct mm_struct, mmlist);
+				swcount = *swap_map;
+				if (mm == &init_mm) {
+					set_start_mm = 1;
+					spin_unlock(&mmlist_lock);
+					shmem = shmem_unuse(entry, page);
+					spin_lock(&mmlist_lock);
+				} else
+					unuse_process(mm, entry, page);
+				if (set_start_mm && *swap_map < swcount) {
+					new_start_mm = mm;
+					set_start_mm = 0;
+				}
+			}
+			atomic_inc(&new_start_mm->mm_users);
+			spin_unlock(&mmlist_lock);
+			mmput(start_mm);
+			start_mm = new_start_mm;
+		}
+
+		/*
+		 * How could swap count reach 0x7fff when the maximum
+		 * pid is 0x7fff, and there's no way to repeat a swap
+		 * page within an mm (except in shmem, where it's the
+		 * shared object which takes the reference count)?
+		 * We believe SWAP_MAP_MAX cannot occur in Linux 2.4.
+		 *
+		 * If that's wrong, then we should worry more about
+		 * exit_mmap() and do_munmap() cases described above:
+		 * we might be resetting SWAP_MAP_MAX too early here.
+		 * We know "Undead"s can happen, they're okay, so don't
+		 * report them; but do report if we reset SWAP_MAP_MAX.
+		 */
+		if (*swap_map == SWAP_MAP_MAX) {
+			swap_list_lock();
+			swap_device_lock(si);
+			nr_swap_pages++;
+			*swap_map = 1;
+			swap_device_unlock(si);
+			swap_list_unlock();
+			reset_overflow = 1;
+		}
+
+		/*
+		 * If a reference remains (rare), we would like to leave
+		 * the page in the swap cache; but try_to_swap_out could
+		 * then re-duplicate the entry once we drop page lock,
+		 * so we might loop indefinitely; also, that page could
+		 * not be swapped out to other storage meanwhile.  So:
+		 * delete from cache even if there's another reference,
+		 * after ensuring that the data has been saved to disk -
+		 * since if the reference remains (rarer), it will be
+		 * read from disk into another page.  Splitting into two
+		 * pages would be incorrect if swap supported "shared
+		 * private" pages, but they are handled by tmpfs files.
+		 *
+		 * Note shmem_unuse already deleted swappage from cache,
+		 * unless corresponding filepage found already in cache:
+		 * in which case it left swappage in cache, lowered its
+		 * swap count to pass quickly through the loops above,
+		 * and now we must reincrement count to try again later.
+		 */
+		if ((*swap_map > 1) && PageDirty(page) && PageSwapCache(page)) {
+			rw_swap_page(WRITE, page);
+			lock_page(page);
+		}
+		if (PageSwapCache(page)) {
+			if (shmem)
+				swap_duplicate(entry);
+			else
+				delete_from_swap_cache(page);
+		}
+
+		/*
+		 * So we could skip searching mms once swap count went
+		 * to 1, we did not mark any present ptes as dirty: must
+		 * mark page dirty so try_to_swap_out will preserve it.
+		 */
+		SetPageDirty(page);
+		UnlockPage(page);
+		page_cache_release(page);
+
+		/*
+		 * Make sure that we aren't completely killing
+		 * interactive performance.  Interruptible check on
+		 * signal_pending() would be nice, but changes the spec?
+		 */
+		if (current->need_resched)
+			schedule();
+	}
+
+	mmput(start_mm);
+	if (reset_overflow) {
+		printk(KERN_WARNING "swapoff: cleared swap entry overflow\n");
+		swap_overflow = 0;
+	}
+	return retval;
+}
+#endif /* NO_MM */
+
+asmlinkage long sys_swapoff(const char * specialfile)
+{
+#ifndef NO_MM
+	struct swap_info_struct * p = NULL;
+	unsigned short *swap_map;
+	struct nameidata nd;
+	int i, type, prev;
+	int err;
+	
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	err = user_path_walk(specialfile, &nd);
+	if (err)
+		goto out;
+
+	lock_kernel();
+	prev = -1;
+	swap_list_lock();
+	for (type = swap_list.head; type >= 0; type = swap_info[type].next) {
+		p = swap_info + type;
+		if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
+			if (p->swap_file == nd.dentry)
+			  break;
+		}
+		prev = type;
+	}
+	err = -EINVAL;
+	if (type < 0) {
+		swap_list_unlock();
+		goto out_dput;
+	}
+
+	if (prev < 0) {
+		swap_list.head = p->next;
+	} else {
+		swap_info[prev].next = p->next;
+	}
+	if (type == swap_list.next) {
+		/* just pick something that's safe... */
+		swap_list.next = swap_list.head;
+	}
+	nr_swap_pages -= p->pages;
+	total_swap_pages -= p->pages;
+	p->flags = SWP_USED;
+	swap_list_unlock();
+	unlock_kernel();
+	err = try_to_unuse(type);
+	lock_kernel();
+	if (err) {
+		/* re-insert swap space back into swap_list */
+		swap_list_lock();
+		for (prev = -1, i = swap_list.head; i >= 0; prev = i, i = swap_info[i].next)
+			if (p->prio >= swap_info[i].prio)
+				break;
+		p->next = i;
+		if (prev < 0)
+			swap_list.head = swap_list.next = p - swap_info;
+		else
+			swap_info[prev].next = p - swap_info;
+		nr_swap_pages += p->pages;
+		total_swap_pages += p->pages;
+		p->flags = SWP_WRITEOK;
+		swap_list_unlock();
+		goto out_dput;
+	}
+	if (p->swap_device)
+		blkdev_put(p->swap_file->d_inode->i_bdev, BDEV_SWAP);
+	path_release(&nd);
+
+	swap_list_lock();
+	swap_device_lock(p);
+	nd.mnt = p->swap_vfsmnt;
+	nd.dentry = p->swap_file;
+	p->swap_vfsmnt = NULL;
+	p->swap_file = NULL;
+	p->swap_device = 0;
+	p->max = 0;
+	swap_map = p->swap_map;
+	p->swap_map = NULL;
+	p->flags = 0;
+	swap_device_unlock(p);
+	swap_list_unlock();
+	vfree(swap_map);
+	err = 0;
+
+out_dput:
+	unlock_kernel();
+	path_release(&nd);
+out:
+	return err;
+#else
+	return(-ENOSYS);
+#endif /* NO_MM */
+}
+
+int get_swaparea_info(char *buf)
+{
+#ifndef NO_MM
+	char * page = (char *) __get_free_page(GFP_KERNEL);
+	struct swap_info_struct *ptr = swap_info;
+	int i, j, len = 0, usedswap;
+
+	if (!page)
+		return -ENOMEM;
+
+	len += sprintf(buf, "Filename\t\t\tType\t\tSize\tUsed\tPriority\n");
+	for (i = 0 ; i < nr_swapfiles ; i++, ptr++) {
+		if ((ptr->flags & SWP_USED) && ptr->swap_map) {
+			char * path = d_path(ptr->swap_file, ptr->swap_vfsmnt,
+						page, PAGE_SIZE);
+
+			len += sprintf(buf + len, "%-31s ", path);
+
+			if (!ptr->swap_device)
+				len += sprintf(buf + len, "file\t\t");
+			else
+				len += sprintf(buf + len, "partition\t");
+
+			usedswap = 0;
+			for (j = 0; j < ptr->max; ++j)
+				switch (ptr->swap_map[j]) {
+					case SWAP_MAP_BAD:
+					case 0:
+						continue;
+					default:
+						usedswap++;
+				}
+			len += sprintf(buf + len, "%d\t%d\t%d\n", ptr->pages << (PAGE_SHIFT - 10), 
+				usedswap << (PAGE_SHIFT - 10), ptr->prio);
+		}
+	}
+	free_page((unsigned long) page);
+	return len;
+#else
+	return sprintf(buf, "No swap");
+#endif /* NO_MM */
+}
+
+int is_swap_partition(kdev_t dev) {
+#ifndef NO_MM
+	struct swap_info_struct *ptr = swap_info;
+	int i;
+
+	for (i = 0 ; i < nr_swapfiles ; i++, ptr++) {
+		if (ptr->flags & SWP_USED)
+			if (ptr->swap_device == dev)
+				return 1;
+	}
+#endif
+	return 0;
+}
+
+/*
+ * Written 01/25/92 by Simmule Turner, heavily changed by Linus.
+ *
+ * The swapon system call
+ */
+asmlinkage long sys_swapon(const char * specialfile, int swap_flags)
+{
+#ifndef NO_MM
+	struct swap_info_struct * p;
+	struct nameidata nd;
+	struct inode * swap_inode;
+	unsigned int type;
+	int i, j, prev;
+	int error;
+	static int least_priority = 0;
+	union swap_header *swap_header = 0;
+	int swap_header_version;
+	int nr_good_pages = 0;
+	unsigned long maxpages = 1;
+	int swapfilesize;
+	struct block_device *bdev = NULL;
+	unsigned short *swap_map;
+	
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	lock_kernel();
+	swap_list_lock();
+	p = swap_info;
+	for (type = 0 ; type < nr_swapfiles ; type++,p++)
+		if (!(p->flags & SWP_USED))
+			break;
+	error = -EPERM;
+	if (type >= MAX_SWAPFILES) {
+		swap_list_unlock();
+		goto out;
+	}
+	if (type >= nr_swapfiles)
+		nr_swapfiles = type+1;
+	p->flags = SWP_USED;
+	p->swap_file = NULL;
+	p->swap_vfsmnt = NULL;
+	p->swap_device = 0;
+	p->swap_map = NULL;
+	p->lowest_bit = 0;
+	p->highest_bit = 0;
+	p->cluster_nr = 0;
+	p->sdev_lock = SPIN_LOCK_UNLOCKED;
+	p->next = -1;
+	if (swap_flags & SWAP_FLAG_PREFER) {
+		p->prio =
+		  (swap_flags & SWAP_FLAG_PRIO_MASK)>>SWAP_FLAG_PRIO_SHIFT;
+	} else {
+		p->prio = --least_priority;
+	}
+	swap_list_unlock();
+	error = user_path_walk(specialfile, &nd);
+	if (error)
+		goto bad_swap_2;
+
+	p->swap_file = nd.dentry;
+	p->swap_vfsmnt = nd.mnt;
+	swap_inode = nd.dentry->d_inode;
+	error = -EINVAL;
+
+	if (S_ISBLK(swap_inode->i_mode)) {
+		kdev_t dev = swap_inode->i_rdev;
+		struct block_device_operations *bdops;
+		devfs_handle_t de;
+
+		if (is_mounted(dev)) {
+			error = -EBUSY;
+			goto bad_swap_2;
+		}
+
+		p->swap_device = dev;
+		set_blocksize(dev, PAGE_SIZE);
+		
+		bd_acquire(swap_inode);
+		bdev = swap_inode->i_bdev;
+		de = devfs_get_handle_from_inode(swap_inode);
+		bdops = devfs_get_ops(de);  /*  Increments module use count  */
+		if (bdops) bdev->bd_op = bdops;
+
+		error = blkdev_get(bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_SWAP);
+		devfs_put_ops(de);/*Decrement module use count now we're safe*/
+		if (error)
+			goto bad_swap_2;
+		set_blocksize(dev, PAGE_SIZE);
+		error = -ENODEV;
+		if (!dev || (blk_size[MAJOR(dev)] &&
+		     !blk_size[MAJOR(dev)][MINOR(dev)]))
+			goto bad_swap;
+		swapfilesize = 0;
+		if (blk_size[MAJOR(dev)])
+			swapfilesize = blk_size[MAJOR(dev)][MINOR(dev)]
+				>> (PAGE_SHIFT - 10);
+	} else if (S_ISREG(swap_inode->i_mode))
+		swapfilesize = swap_inode->i_size >> PAGE_SHIFT;
+	else
+		goto bad_swap;
+
+	error = -EBUSY;
+	for (i = 0 ; i < nr_swapfiles ; i++) {
+		struct swap_info_struct *q = &swap_info[i];
+		if (i == type || !q->swap_file)
+			continue;
+		if (swap_inode->i_mapping == q->swap_file->d_inode->i_mapping)
+			goto bad_swap;
+	}
+
+	swap_header = (void *) __get_free_page(GFP_USER);
+	if (!swap_header) {
+		printk("Unable to start swapping: out of memory :-)\n");
+		error = -ENOMEM;
+		goto bad_swap;
+	}
+
+	lock_page(virt_to_page(swap_header));
+	rw_swap_page_nolock(READ, SWP_ENTRY(type,0), (char *) swap_header);
+
+	if (!memcmp("SWAP-SPACE",swap_header->magic.magic,10))
+		swap_header_version = 1;
+	else if (!memcmp("SWAPSPACE2",swap_header->magic.magic,10))
+		swap_header_version = 2;
+	else {
+		printk("Unable to find swap-space signature\n");
+		error = -EINVAL;
+		goto bad_swap;
+	}
+	
+	switch (swap_header_version) {
+	case 1:
+		memset(((char *) swap_header)+PAGE_SIZE-10,0,10);
+		j = 0;
+		p->lowest_bit = 0;
+		p->highest_bit = 0;
+		for (i = 1 ; i < 8*PAGE_SIZE ; i++) {
+			if (test_bit(i,(char *) swap_header)) {
+				if (!p->lowest_bit)
+					p->lowest_bit = i;
+				p->highest_bit = i;
+				maxpages = i+1;
+				j++;
+			}
+		}
+		nr_good_pages = j;
+		p->swap_map = vmalloc(maxpages * sizeof(short));
+		if (!p->swap_map) {
+			error = -ENOMEM;		
+			goto bad_swap;
+		}
+		for (i = 1 ; i < maxpages ; i++) {
+			if (test_bit(i,(char *) swap_header))
+				p->swap_map[i] = 0;
+			else
+				p->swap_map[i] = SWAP_MAP_BAD;
+		}
+		break;
+
+	case 2:
+		/* Check the swap header's sub-version and the size of
+                   the swap file and bad block lists */
+		if (swap_header->info.version != 1) {
+			printk(KERN_WARNING
+			       "Unable to handle swap header version %d\n",
+			       swap_header->info.version);
+			error = -EINVAL;
+			goto bad_swap;
+		}
+
+		p->lowest_bit  = 1;
+		maxpages = SWP_OFFSET(SWP_ENTRY(0,~0UL)) - 1;
+		if (maxpages > swap_header->info.last_page)
+			maxpages = swap_header->info.last_page;
+		p->highest_bit = maxpages - 1;
+
+		error = -EINVAL;
+		if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES)
+			goto bad_swap;
+		
+		/* OK, set up the swap map and apply the bad block list */
+		if (!(p->swap_map = vmalloc(maxpages * sizeof(short)))) {
+			error = -ENOMEM;
+			goto bad_swap;
+		}
+
+		error = 0;
+		memset(p->swap_map, 0, maxpages * sizeof(short));
+		for (i=0; i<swap_header->info.nr_badpages; i++) {
+			int page = swap_header->info.badpages[i];
+			if (page <= 0 || page >= swap_header->info.last_page)
+				error = -EINVAL;
+			else
+				p->swap_map[page] = SWAP_MAP_BAD;
+		}
+		nr_good_pages = swap_header->info.last_page -
+				swap_header->info.nr_badpages -
+				1 /* header page */;
+		if (error) 
+			goto bad_swap;
+	}
+	
+	if (swapfilesize && maxpages > swapfilesize) {
+		printk(KERN_WARNING
+		       "Swap area shorter than signature indicates\n");
+		error = -EINVAL;
+		goto bad_swap;
+	}
+	if (!nr_good_pages) {
+		printk(KERN_WARNING "Empty swap-file\n");
+		error = -EINVAL;
+		goto bad_swap;
+	}
+	p->swap_map[0] = SWAP_MAP_BAD;
+	swap_list_lock();
+	swap_device_lock(p);
+	p->max = maxpages;
+	p->flags = SWP_WRITEOK;
+	p->pages = nr_good_pages;
+	nr_swap_pages += nr_good_pages;
+	total_swap_pages += nr_good_pages;
+	printk(KERN_INFO "Adding Swap: %dk swap-space (priority %d)\n",
+	       nr_good_pages<<(PAGE_SHIFT-10), p->prio);
+
+	/* insert swap space into swap_list: */
+	prev = -1;
+	for (i = swap_list.head; i >= 0; i = swap_info[i].next) {
+		if (p->prio >= swap_info[i].prio) {
+			break;
+		}
+		prev = i;
+	}
+	p->next = i;
+	if (prev < 0) {
+		swap_list.head = swap_list.next = p - swap_info;
+	} else {
+		swap_info[prev].next = p - swap_info;
+	}
+	swap_device_unlock(p);
+	swap_list_unlock();
+	error = 0;
+	goto out;
+bad_swap:
+	if (bdev)
+		blkdev_put(bdev, BDEV_SWAP);
+bad_swap_2:
+	swap_list_lock();
+	swap_map = p->swap_map;
+	nd.mnt = p->swap_vfsmnt;
+	nd.dentry = p->swap_file;
+	p->swap_device = 0;
+	p->swap_file = NULL;
+	p->swap_vfsmnt = NULL;
+	p->swap_map = NULL;
+	p->flags = 0;
+	if (!(swap_flags & SWAP_FLAG_PREFER))
+		++least_priority;
+	swap_list_unlock();
+	if (swap_map)
+		vfree(swap_map);
+	path_release(&nd);
+out:
+	if (swap_header)
+		free_page((long) swap_header);
+	unlock_kernel();
+	return error;
+#else
+	return(-ENOSYS);
+#endif /* NO_MM */
+}
+
+void si_swapinfo(struct sysinfo *val)
+{
+#ifndef NO_MM
+	unsigned int i;
+	unsigned long nr_to_be_unused = 0;
+
+	swap_list_lock();
+	for (i = 0; i < nr_swapfiles; i++) {
+		unsigned int j;
+		if (swap_info[i].flags != SWP_USED)
+			continue;
+		for (j = 0; j < swap_info[i].max; ++j) {
+			switch (swap_info[i].swap_map[j]) {
+				case 0:
+				case SWAP_MAP_BAD:
+					continue;
+				default:
+					nr_to_be_unused++;
+			}
+		}
+	}
+	val->freeswap = nr_swap_pages + nr_to_be_unused;
+	val->totalswap = total_swap_pages + nr_to_be_unused;
+	swap_list_unlock();
+#else
+	val->freeswap = val->totalswap = 0;
+#endif /* NO_MM */
+}
+
+#ifndef NO_MM
+/*
+ * Verify that a swap entry is valid and increment its swap map count.
+ *
+ * Note: if swap_map[] reaches SWAP_MAP_MAX the entries are treated as
+ * "permanent", but will be reclaimed by the next swapoff.
+ */
+int swap_duplicate(swp_entry_t entry)
+{
+	struct swap_info_struct * p;
+	unsigned long offset, type;
+	int result = 0;
+
+	type = SWP_TYPE(entry);
+	if (type >= nr_swapfiles)
+		goto bad_file;
+	p = type + swap_info;
+	offset = SWP_OFFSET(entry);
+
+	swap_device_lock(p);
+	if (offset < p->max && p->swap_map[offset]) {
+		if (p->swap_map[offset] < SWAP_MAP_MAX - 1) {
+			p->swap_map[offset]++;
+			result = 1;
+		} else if (p->swap_map[offset] <= SWAP_MAP_MAX) {
+			if (swap_overflow++ < 5)
+				printk(KERN_WARNING "swap_dup: swap entry overflow\n");
+			p->swap_map[offset] = SWAP_MAP_MAX;
+			result = 1;
+		}
+	}
+	swap_device_unlock(p);
+out:
+	return result;
+
+bad_file:
+	printk(KERN_ERR "swap_dup: %s%08lx\n", Bad_file, entry.val);
+	goto out;
+}
+
+/*
+ * Prior swap_duplicate protects against swap device deletion.
+ */
+void get_swaphandle_info(swp_entry_t entry, unsigned long *offset, 
+			kdev_t *dev, struct inode **swapf)
+{
+	unsigned long type;
+	struct swap_info_struct *p;
+
+	type = SWP_TYPE(entry);
+	if (type >= nr_swapfiles) {
+		printk(KERN_ERR "rw_swap_page: %s%08lx\n", Bad_file, entry.val);
+		return;
+	}
+
+	p = &swap_info[type];
+	*offset = SWP_OFFSET(entry);
+	if (*offset >= p->max && *offset != 0) {
+		printk(KERN_ERR "rw_swap_page: %s%08lx\n", Bad_offset, entry.val);
+		return;
+	}
+	if (p->swap_map && !p->swap_map[*offset]) {
+		printk(KERN_ERR "rw_swap_page: %s%08lx\n", Unused_offset, entry.val);
+		return;
+	}
+	if (!(p->flags & SWP_USED)) {
+		printk(KERN_ERR "rw_swap_page: %s%08lx\n", Unused_file, entry.val);
+		return;
+	}
+
+	if (p->swap_device) {
+		*dev = p->swap_device;
+	} else if (p->swap_file) {
+		*swapf = p->swap_file->d_inode;
+	} else {
+		printk(KERN_ERR "rw_swap_page: no swap file or device\n");
+	}
+	return;
+}
+
+/*
+ * swap_device_lock prevents swap_map being freed. Don't grab an extra
+ * reference on the swaphandle, it doesn't matter if it becomes unused.
+ */
+int valid_swaphandles(swp_entry_t entry, unsigned long *offset)
+{
+	int ret = 0, i = 1 << page_cluster;
+	unsigned long toff;
+	struct swap_info_struct *swapdev = SWP_TYPE(entry) + swap_info;
+
+	if (!page_cluster)	/* no readahead */
+		return 0;
+	toff = (SWP_OFFSET(entry) >> page_cluster) << page_cluster;
+	if (!toff)		/* first page is swap header */
+		toff++, i--;
+	*offset = toff;
+
+	swap_device_lock(swapdev);
+	do {
+		/* Don't read-ahead past the end of the swap area */
+		if (toff >= swapdev->max)
+			break;
+		/* Don't read in free or bad pages */
+		if (!swapdev->swap_map[toff])
+			break;
+		if (swapdev->swap_map[toff] == SWAP_MAP_BAD)
+			break;
+		toff++;
+		ret++;
+	} while (--i);
+	swap_device_unlock(swapdev);
+	return ret;
+}
+
+#endif /* NO_MM */
diff -urN linux-2.4.29/mmnommu/swap_state.c linux-2.4.29-uc1/mmnommu/swap_state.c
--- linux-2.4.29/mmnommu/swap_state.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/swap_state.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,266 @@
+/*
+ *  linux/mm/swap_state.c
+ *
+ *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ *  Swap reorganised 29.12.95, Stephen Tweedie
+ *
+ *  Rewritten to use page cache, (C) 1998 Stephen Tweedie
+ *
+ *  NO_MM - Copyright (c) 2000 Lineo,Inc. David McCullough <davidm@lineo.com>
+ */
+
+#include <linux/mm.h>
+#include <linux/kernel_stat.h>
+#include <linux/swap.h>
+#include <linux/swapctl.h>
+#include <linux/init.h>
+#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
+
+#include <asm/pgtable.h>
+
+#ifndef NO_MM
+
+/*
+ * We may have stale swap cache pages in memory: notice
+ * them here and get rid of the unnecessary final write.
+ */
+static int swap_writepage(struct page *page)
+{
+	if (remove_exclusive_swap_page(page)) {
+		UnlockPage(page);
+		return 0;
+	}
+	rw_swap_page(WRITE, page);
+	return 0;
+}
+
+static struct address_space_operations swap_aops = {
+	writepage: swap_writepage,
+	sync_page: block_sync_page,
+};
+
+#endif /* NO_MM */
+
+struct address_space swapper_space = {
+	LIST_HEAD_INIT(swapper_space.clean_pages),
+	LIST_HEAD_INIT(swapper_space.dirty_pages),
+	LIST_HEAD_INIT(swapper_space.locked_pages),
+	0,				/* nrpages	*/
+#ifndef NO_MM
+	&swap_aops,
+#else
+	NULL,
+#endif
+};
+
+#ifndef NO_MM
+
+#ifdef SWAP_CACHE_INFO
+#define INC_CACHE_INFO(x)	(swap_cache_info.x++)
+
+static struct {
+	unsigned long add_total;
+	unsigned long del_total;
+	unsigned long find_success;
+	unsigned long find_total;
+	unsigned long noent_race;
+	unsigned long exist_race;
+} swap_cache_info;
+
+void show_swap_cache_info(void)
+{
+	printk("Swap cache: add %lu, delete %lu, find %lu/%lu, race %lu+%lu\n",
+		swap_cache_info.add_total, swap_cache_info.del_total,
+		swap_cache_info.find_success, swap_cache_info.find_total,
+		swap_cache_info.noent_race, swap_cache_info.exist_race);
+}
+#else
+#define INC_CACHE_INFO(x)	do { } while (0)
+#endif
+
+int add_to_swap_cache(struct page *page, swp_entry_t entry)
+{
+	if (page->mapping)
+		BUG();
+	if (!swap_duplicate(entry)) {
+		INC_CACHE_INFO(noent_race);
+		return -ENOENT;
+	}
+	if (add_to_page_cache_unique(page, &swapper_space, entry.val,
+			page_hash(&swapper_space, entry.val)) != 0) {
+		swap_free(entry);
+		INC_CACHE_INFO(exist_race);
+		return -EEXIST;
+	}
+	if (!PageLocked(page))
+		BUG();
+	if (!PageSwapCache(page))
+		BUG();
+	INC_CACHE_INFO(add_total);
+	return 0;
+}
+
+#endif /* NO_MM */
+
+/*
+ * This must be called only on pages that have
+ * been verified to be in the swap cache.
+ */
+void __delete_from_swap_cache(struct page *page)
+{
+#ifndef NO_MM
+	if (!PageLocked(page))
+		BUG();
+	if (!PageSwapCache(page))
+		BUG();
+	ClearPageDirty(page);
+	__remove_inode_page(page);
+	INC_CACHE_INFO(del_total);
+#else
+	BUG();
+#endif /* NO_MM */
+}
+
+/*
+ * This must be called only on pages that have
+ * been verified to be in the swap cache and locked.
+ * It will never put the page into the free list,
+ * the caller has a reference on the page.
+ */
+void delete_from_swap_cache(struct page *page)
+{
+#ifndef NO_MM
+	swp_entry_t entry;
+
+	if (!PageLocked(page))
+		BUG();
+
+	if (unlikely(!block_flushpage(page, 0)))
+		BUG();	/* an anonymous page cannot have page->buffers set */
+
+	entry.val = page->index;
+
+	spin_lock(&pagecache_lock);
+	__delete_from_swap_cache(page);
+	spin_unlock(&pagecache_lock);
+
+	swap_free(entry);
+	page_cache_release(page);
+#else
+	BUG();
+#endif /* NO_MM */
+}
+
+/* 
+ * Perform a free_page(), also freeing any swap cache associated with
+ * this page if it is the last user of the page. Can not do a lock_page,
+ * as we are holding the page_table_lock spinlock.
+ */
+void free_page_and_swap_cache(struct page *page)
+{
+	/* 
+	 * If we are the only user, then try to free up the swap cache. 
+	 * 
+	 * Its ok to check for PageSwapCache without the page lock
+	 * here because we are going to recheck again inside 
+	 * exclusive_swap_page() _with_ the lock. 
+	 * 					- Marcelo
+	 */
+	if (PageSwapCache(page) && !TryLockPage(page)) {
+#ifndef NO_MM
+		remove_exclusive_swap_page(page);
+#endif
+		UnlockPage(page);
+	}
+	page_cache_release(page);
+}
+
+/*
+ * Lookup a swap entry in the swap cache. A found page will be returned
+ * unlocked and with its refcount incremented - we rely on the kernel
+ * lock getting page table operations atomic even if we drop the page
+ * lock before returning.
+ */
+struct page * lookup_swap_cache(swp_entry_t entry)
+{
+#ifndef NO_MM
+	struct page *found;
+
+	found = find_get_page(&swapper_space, entry.val);
+	/*
+	 * Unsafe to assert PageSwapCache and mapping on page found:
+	 * if SMP nothing prevents swapoff from deleting this page from
+	 * the swap cache at this moment.  find_lock_page would prevent
+	 * that, but no need to change: we _have_ got the right page.
+	 */
+	INC_CACHE_INFO(find_total);
+	if (found)
+		INC_CACHE_INFO(find_success);
+	return found;
+#else
+	BUG();
+	return((struct page *) 0);
+#endif /* NO_MM */
+}
+
+/* 
+ * Locate a page of swap in physical memory, reserving swap cache space
+ * and reading the disk if it is not already cached.
+ * A failure return means that either the page allocation failed or that
+ * the swap entry is no longer in use.
+ */
+
+struct page * read_swap_cache_async(swp_entry_t entry)
+{
+#ifndef NO_MM
+	struct page *found_page, *new_page = NULL;
+	int err;
+
+	do {
+		/*
+		 * First check the swap cache.  Since this is normally
+		 * called after lookup_swap_cache() failed, re-calling
+		 * that would confuse statistics: use find_get_page()
+		 * directly.
+		 */
+		found_page = find_get_page(&swapper_space, entry.val);
+		if (found_page)
+			break;
+
+		/*
+		 * Get a new page to read into from swap.
+		 */
+		if (!new_page) {
+			new_page = alloc_page(GFP_HIGHUSER);
+			if (!new_page)
+				break;		/* Out of memory */
+		}
+
+		/*
+		 * Associate the page with swap entry in the swap cache.
+		 * May fail (-ENOENT) if swap entry has been freed since
+		 * our caller observed it.  May fail (-EEXIST) if there
+		 * is already a page associated with this entry in the
+		 * swap cache: added by a racing read_swap_cache_async,
+		 * or by try_to_swap_out (or shmem_writepage) re-using
+		 * the just freed swap entry for an existing page.
+		 */
+		err = add_to_swap_cache(new_page, entry);
+		if (!err) {
+			/*
+			 * Initiate read into locked page and return.
+			 */
+			rw_swap_page(READ, new_page);
+			return new_page;
+		}
+	} while (err != -ENOENT);
+
+	if (new_page)
+		page_cache_release(new_page);
+	return found_page;
+#else
+	BUG();
+	return((struct page *) 0);
+#endif
+}
diff -urN linux-2.4.29/mmnommu/vmalloc.c linux-2.4.29-uc1/mmnommu/vmalloc.c
--- linux-2.4.29/mmnommu/vmalloc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/vmalloc.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,56 @@
+/*
+ *  linux/mm/vmalloc.c
+ *
+ *  Copyright (C) 1993  Linus Torvalds
+ *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
+ *  SMP-safe vmalloc/vfree/ioremap, Tigran Aivazian <tigran@veritas.com>, May 2000
+ *  Copyright (c) 2001 Lineo Inc., David McCullough <davidm@lineo.com>
+ *  Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org>
+ */
+
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/spinlock.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+
+rwlock_t vmlist_lock = RW_LOCK_UNLOCKED;
+struct vm_struct * vmlist;
+
+void __vfree(void * addr, int free_area_pages)
+{
+	kfree(addr);
+}
+
+void vfree(void * addr)
+{
+	__vfree(addr,1);
+}
+
+void * __vmalloc (unsigned long size, int gfp_mask, pgprot_t prot)
+{
+	/*
+	 * kmalloc doesn't like __GFP_HIGHMEM for some reason
+	 * I doubt we need it - DAVIDM
+	 */
+	return kmalloc(size, gfp_mask & ~__GFP_HIGHMEM);
+}
+
+long vread(char *buf, char *addr, unsigned long count)
+{
+	memcpy(buf, addr, count);
+	return count;
+}
+
+long vwrite(char *buf, char *addr, unsigned long count)
+{
+	/* Don't allow overflow */
+	if ((unsigned long) addr + count < count)
+		count = -(unsigned long) addr;
+	
+	memcpy(addr, buf, count);
+	return(count);
+}
+
diff -urN linux-2.4.29/mmnommu/vmscan.c linux-2.4.29-uc1/mmnommu/vmscan.c
--- linux-2.4.29/mmnommu/vmscan.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/mmnommu/vmscan.c	2005-06-14 02:11:54.000000000 +0100
@@ -0,0 +1,874 @@
+/*
+ *  linux/mm/vmscan.c
+ *
+ *  The pageout daemon, decides which pages to evict (swap out) and
+ *  does the actual work of freeing them.
+ *
+ *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ *
+ *  NO_MM
+ *     Copyright (c) 2001 Lineo, Inc. David McCullough <davidm@lineo.com>
+ *     Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org> ref uClinux 2.0
+ *
+ *  Swap reorganised 29.12.95, Stephen Tweedie.
+ *  kswapd added: 7.1.96  sct
+ *  Removed kswapd_ctl limits, and swap out as many pages as needed
+ *  to bring the system back to freepages.high: 2.4.97, Rik van Riel.
+ *  Zone aware kswapd started 02/00, Kanoj Sarcar (kanoj@sgi.com).
+ *  Multiqueue VM started 5.8.00, Rik van Riel.
+ */
+
+#include <linux/slab.h>
+#include <linux/kernel_stat.h>
+#include <linux/swap.h>
+#include <linux/swapctl.h>
+#include <linux/smp_lock.h>
+#include <linux/pagemap.h>
+#include <linux/init.h>
+#include <linux/highmem.h>
+#include <linux/file.h>
+#include <linux/config.h>
+
+#include <asm/pgalloc.h>
+
+/*
+ * "vm_passes" is the number of vm passes before failing the
+ * memory balancing. Take into account 3 passes are needed
+ * for a flush/wait/free cycle and that we only scan 1/vm_cache_scan_ratio
+ * of the inactive list at each pass.
+ */
+int vm_passes = 60;
+
+/*
+ * "vm_cache_scan_ratio" is how much of the inactive LRU queue we will scan
+ * in one go. A value of 6 for vm_cache_scan_ratio implies that we'll
+ * scan 1/6 of the inactive lists during a normal aging round.
+ */
+int vm_cache_scan_ratio = 6;
+
+/*
+ * "vm_mapped_ratio" controls the pageout rate, the smaller, the earlier
+ * we'll start to pageout.
+ */
+int vm_mapped_ratio = 100;
+
+/*
+ * "vm_lru_balance_ratio" controls the balance between active and
+ * inactive cache. The bigger vm_balance is, the easier the
+ * active cache will grow, because we'll rotate the active list
+ * slowly. A value of 2 means we'll go towards a balance of
+ * 1/3 of the cache being inactive.
+ */
+int vm_lru_balance_ratio = 2;
+
+/*
+ * "vm_vfs_scan_ratio" is what proportion of the VFS queues we will scan
+ * in one go. A value of 6 for vm_vfs_scan_ratio implies that 1/6th of
+ * the unused-inode, dentry and dquot caches will be freed during a normal
+ * aging round.
+ */
+int vm_vfs_scan_ratio = 6;
+
+#ifndef NO_MM
+/*
+ * "vm_anon_lru" select if to immdiatly insert anon pages in the
+ * lru. Immediatly means as soon as they're allocated during the
+ * page faults.
+ *
+ * If this is set to 0, they're inserted only after the first
+ * swapout.
+ *
+ * Having anon pages immediatly inserted in the lru allows the
+ * VM to know better when it's worthwhile to start swapping
+ * anonymous ram, it will start to swap earlier and it should
+ * swap smoother and faster, but it will decrease scalability
+ * on the >16-ways of an order of magnitude. Big SMP/NUMA
+ * definitely can't take an hit on a global spinlock at
+ * every anon page allocation. So this is off by default.
+ *
+ * Low ram machines that swaps all the time want to turn
+ * this on (i.e. set to 1).
+ */
+int vm_anon_lru = 0;
+
+/*
+ * The swap-out function returns 1 if it successfully
+ * scanned all the pages it was asked to (`count').
+ * It returns zero if it couldn't do anything,
+ *
+ * rss may decrease because pages are shared, but this
+ * doesn't count as having freed a page.
+ */
+
+/* mm->page_table_lock is held. mmap_sem is not held */
+static inline int try_to_swap_out(struct mm_struct * mm, struct vm_area_struct* vma, unsigned long address, pte_t * page_table, struct page *page, zone_t * classzone)
+{
+	pte_t pte;
+	swp_entry_t entry;
+
+	/* Don't look at this pte if it's been accessed recently. */
+	if ((vma->vm_flags & VM_LOCKED) || ptep_test_and_clear_young(page_table)) {
+		mark_page_accessed(page);
+		return 0;
+	}
+
+	/* Don't bother unmapping pages that are active */
+	if (PageActive(page))
+		return 0;
+
+	/* Don't bother replenishing zones not under pressure.. */
+	if (!memclass(page_zone(page), classzone))
+		return 0;
+
+	if (TryLockPage(page))
+		return 0;
+
+	/* From this point on, the odds are that we're going to
+	 * nuke this pte, so read and clear the pte.  This hook
+	 * is needed on CPUs which update the accessed and dirty
+	 * bits in hardware.
+	 */
+	flush_cache_page(vma, address);
+	pte = ptep_get_and_clear(page_table);
+	flush_tlb_page(vma, address);
+
+	if (pte_dirty(pte))
+		set_page_dirty(page);
+
+	/*
+	 * Is the page already in the swap cache? If so, then
+	 * we can just drop our reference to it without doing
+	 * any IO - it's already up-to-date on disk.
+	 */
+	if (PageSwapCache(page)) {
+		entry.val = page->index;
+		swap_duplicate(entry);
+set_swap_pte:
+		set_pte(page_table, swp_entry_to_pte(entry));
+drop_pte:
+		mm->rss--;
+#ifdef __arm__
+		memc_clear(vma->vm_mm, page);
+#endif
+		UnlockPage(page);
+		{
+			int freeable = page_count(page) - !!page->buffers <= 2;
+			page_cache_release(page);
+			return freeable;
+		}
+	}
+
+	/*
+	 * Is it a clean page? Then it must be recoverable
+	 * by just paging it in again, and we can just drop
+	 * it..  or if it's dirty but has backing store,
+	 * just mark the page dirty and drop it.
+	 *
+	 * However, this won't actually free any real
+	 * memory, as the page will just be in the page cache
+	 * somewhere, and as such we should just continue
+	 * our scan.
+	 *
+	 * Basically, this just makes it possible for us to do
+	 * some real work in the future in "refill_inactive()".
+	 */
+	if (page->mapping)
+		goto drop_pte;
+	if (!PageDirty(page))
+		goto drop_pte;
+
+	/*
+	 * Anonymous buffercache pages can be left behind by
+	 * concurrent truncate and pagefault.
+	 */
+	if (page->buffers)
+		goto preserve;
+
+	/*
+	 * This is a dirty, swappable page.  First of all,
+	 * get a suitable swap entry for it, and make sure
+	 * we have the swap cache set up to associate the
+	 * page with that swap entry.
+	 */
+	for (;;) {
+		entry = get_swap_page();
+		if (!entry.val)
+			break;
+		/* Add it to the swap cache and mark it dirty
+		 * (adding to the page cache will clear the dirty
+		 * and uptodate bits, so we need to do it again)
+		 */
+		if (add_to_swap_cache(page, entry) == 0) {
+			SetPageUptodate(page);
+			set_page_dirty(page);
+			goto set_swap_pte;
+		}
+		/* Raced with "speculative" read_swap_cache_async */
+		swap_free(entry);
+	}
+
+	/* No swap space left */
+preserve:
+	set_pte(page_table, pte);
+	UnlockPage(page);
+	return 0;
+}
+
+/* mm->page_table_lock is held. mmap_sem is not held */
+static inline int swap_out_pmd(struct mm_struct * mm, struct vm_area_struct * vma, pmd_t *dir, unsigned long address, unsigned long end, int count, zone_t * classzone)
+{
+	pte_t * pte;
+	unsigned long pmd_end;
+
+	if (pmd_none(*dir))
+		return count;
+	if (pmd_bad(*dir)) {
+		pmd_ERROR(*dir);
+		pmd_clear(dir);
+		return count;
+	}
+	
+	pte = pte_offset(dir, address);
+	
+	pmd_end = (address + PMD_SIZE) & PMD_MASK;
+	if (end > pmd_end)
+		end = pmd_end;
+
+	do {
+		if (pte_present(*pte)) {
+			struct page *page = pte_page(*pte);
+
+			if (VALID_PAGE(page) && !PageReserved(page)) {
+				count -= try_to_swap_out(mm, vma, address, pte, page, classzone);
+				if (!count) {
+					address += PAGE_SIZE;
+					break;
+				}
+			}
+		}
+		address += PAGE_SIZE;
+		pte++;
+	} while (address && (address < end));
+	mm->swap_address = address;
+	return count;
+}
+
+/* mm->page_table_lock is held. mmap_sem is not held */
+static inline int swap_out_pgd(struct mm_struct * mm, struct vm_area_struct * vma, pgd_t *dir, unsigned long address, unsigned long end, int count, zone_t * classzone)
+{
+	pmd_t * pmd;
+	unsigned long pgd_end;
+
+	if (pgd_none(*dir))
+		return count;
+	if (pgd_bad(*dir)) {
+		pgd_ERROR(*dir);
+		pgd_clear(dir);
+		return count;
+	}
+
+	pmd = pmd_offset(dir, address);
+
+	pgd_end = (address + PGDIR_SIZE) & PGDIR_MASK;	
+	if (pgd_end && (end > pgd_end))
+		end = pgd_end;
+	
+	do {
+		count = swap_out_pmd(mm, vma, pmd, address, end, count, classzone);
+		if (!count)
+			break;
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address && (address < end));
+	return count;
+}
+
+/* mm->page_table_lock is held. mmap_sem is not held */
+static inline int swap_out_vma(struct mm_struct * mm, struct vm_area_struct * vma, unsigned long address, int count, zone_t * classzone)
+{
+	pgd_t *pgdir;
+	unsigned long end;
+
+	/* Don't swap out areas which are reserved */
+	if (vma->vm_flags & VM_RESERVED)
+		return count;
+
+	pgdir = pgd_offset(mm, address);
+
+	end = vma->vm_end;
+	BUG_ON(address >= end);
+	do {
+		count = swap_out_pgd(mm, vma, pgdir, address, end, count, classzone);
+		if (!count)
+			break;
+		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+		pgdir++;
+	} while (address && (address < end));
+	return count;
+}
+
+/* Placeholder for swap_out(): may be updated by fork.c:mmput() */
+struct mm_struct *swap_mm = &init_mm;
+
+/*
+ * Returns remaining count of pages to be swapped out by followup call.
+ */
+static inline int swap_out_mm(struct mm_struct * mm, int count, int * mmcounter, zone_t * classzone)
+{
+	unsigned long address;
+	struct vm_area_struct* vma;
+
+	/*
+	 * Find the proper vm-area after freezing the vma chain 
+	 * and ptes.
+	 */
+	spin_lock(&mm->page_table_lock);
+	address = mm->swap_address;
+	if (address == TASK_SIZE || swap_mm != mm) {
+		/* We raced: don't count this mm but try again */
+		++*mmcounter;
+		goto out_unlock;
+	}
+	vma = find_vma(mm, address);
+	if (vma) {
+		if (address < vma->vm_start)
+			address = vma->vm_start;
+
+		for (;;) {
+			count = swap_out_vma(mm, vma, address, count, classzone);
+			vma = vma->vm_next;
+			if (!vma)
+				break;
+			if (!count)
+				goto out_unlock;
+			address = vma->vm_start;
+		}
+	}
+	/* Indicate that we reached the end of address space */
+	mm->swap_address = TASK_SIZE;
+
+out_unlock:
+	spin_unlock(&mm->page_table_lock);
+	return count;
+}
+
+#endif /* NO_MM */
+
+static int FASTCALL(swap_out(zone_t * classzone));
+static int fastcall swap_out(zone_t * classzone)
+{
+#ifndef NO_MM
+	int counter, nr_pages = SWAP_CLUSTER_MAX;
+	struct mm_struct *mm;
+
+	/* Then, look at the other mm's */
+	counter = mmlist_nr << 1;
+	do {
+		if (unlikely(current->need_resched)) {
+			__set_current_state(TASK_RUNNING);
+			schedule();
+		}
+
+		spin_lock(&mmlist_lock);
+		mm = swap_mm;
+		while (mm->swap_address == TASK_SIZE || mm == &init_mm) {
+			mm->swap_address = 0;
+			mm = list_entry(mm->mmlist.next, struct mm_struct, mmlist);
+			if (mm == swap_mm)
+				goto empty;
+			swap_mm = mm;
+		}
+
+		/* Make sure the mm doesn't disappear when we drop the lock.. */
+		atomic_inc(&mm->mm_users);
+		spin_unlock(&mmlist_lock);
+
+		nr_pages = swap_out_mm(mm, nr_pages, &counter, classzone);
+
+		mmput(mm);
+
+		if (!nr_pages)
+			return 1;
+	} while (--counter >= 0);
+
+	return 0;
+
+empty:
+	spin_unlock(&mmlist_lock);
+#endif /* NO_MM */
+	return 0;
+}
+
+static void FASTCALL(refill_inactive(int nr_pages, zone_t * classzone));
+static int FASTCALL(shrink_cache(int nr_pages, zone_t * classzone, unsigned int gfp_mask, int * failed_swapout));
+static int fastcall shrink_cache(int nr_pages, zone_t * classzone, unsigned int gfp_mask, int * failed_swapout)
+{
+	struct list_head * entry;
+	int max_scan = (classzone->nr_inactive_pages + classzone->nr_active_pages) / vm_cache_scan_ratio;
+	int max_mapped = vm_mapped_ratio * nr_pages;
+
+	while (max_scan && classzone->nr_inactive_pages && (entry = inactive_list.prev) != &inactive_list) {
+		struct page * page;
+
+		if (unlikely(current->need_resched)) {
+			spin_unlock(&pagemap_lru_lock);
+			__set_current_state(TASK_RUNNING);
+			schedule();
+			spin_lock(&pagemap_lru_lock);
+			continue;
+		}
+
+		page = list_entry(entry, struct page, lru);
+
+		BUG_ON(!PageLRU(page));
+		BUG_ON(PageActive(page));
+
+		list_del(entry);
+		list_add(entry, &inactive_list);
+
+		/*
+		 * Zero page counts can happen because we unlink the pages
+		 * _after_ decrementing the usage count..
+		 */
+		if (unlikely(!page_count(page)))
+			continue;
+
+		if (!memclass(page_zone(page), classzone))
+			continue;
+
+		max_scan--;
+
+		/* Racy check to avoid trylocking when not worthwhile */
+		if (!page->buffers && (page_count(page) != 1 || !page->mapping))
+			goto page_mapped;
+
+		/*
+		 * The page is locked. IO in progress?
+		 * Move it to the back of the list.
+		 */
+		if (unlikely(TryLockPage(page))) {
+			if (PageLaunder(page) && (gfp_mask & __GFP_FS)) {
+				page_cache_get(page);
+				spin_unlock(&pagemap_lru_lock);
+				wait_on_page(page);
+				page_cache_release(page);
+				spin_lock(&pagemap_lru_lock);
+			}
+			continue;
+		}
+
+		if (PageDirty(page) && is_page_cache_freeable(page) && page->mapping) {
+			/*
+			 * It is not critical here to write it only if
+			 * the page is unmapped beause any direct writer
+			 * like O_DIRECT would set the PG_dirty bitflag
+			 * on the phisical page after having successfully
+			 * pinned it and after the I/O to the page is finished,
+			 * so the direct writes to the page cannot get lost.
+			 */
+			int (*writepage)(struct page *);
+
+			writepage = page->mapping->a_ops->writepage;
+			if ((gfp_mask & __GFP_FS) && writepage) {
+				ClearPageDirty(page);
+				SetPageLaunder(page);
+				page_cache_get(page);
+				spin_unlock(&pagemap_lru_lock);
+
+				writepage(page);
+				page_cache_release(page);
+
+				spin_lock(&pagemap_lru_lock);
+				continue;
+			}
+		}
+
+		/*
+		 * If the page has buffers, try to free the buffer mappings
+		 * associated with this page. If we succeed we try to free
+		 * the page as well.
+		 */
+		if (page->buffers) {
+			spin_unlock(&pagemap_lru_lock);
+
+			/* avoid to free a locked page */
+			page_cache_get(page);
+
+			if (try_to_release_page(page, gfp_mask)) {
+				if (!page->mapping) {
+					/*
+					 * We must not allow an anon page
+					 * with no buffers to be visible on
+					 * the LRU, so we unlock the page after
+					 * taking the lru lock
+					 */
+					spin_lock(&pagemap_lru_lock);
+					UnlockPage(page);
+					__lru_cache_del(page);
+
+					/* effectively free the page here */
+					page_cache_release(page);
+
+					if (--nr_pages)
+						continue;
+					break;
+				} else {
+					/*
+					 * The page is still in pagecache so undo the stuff
+					 * before the try_to_release_page since we've not
+					 * finished and we can now try the next step.
+					 */
+					page_cache_release(page);
+
+					spin_lock(&pagemap_lru_lock);
+				}
+			} else {
+				/* failed to drop the buffers so stop here */
+				UnlockPage(page);
+				page_cache_release(page);
+
+				spin_lock(&pagemap_lru_lock);
+				continue;
+			}
+		}
+
+		spin_lock(&pagecache_lock);
+
+		/*
+		 * This is the non-racy check for busy page.
+		 * It is critical to check PageDirty _after_ we made sure
+		 * the page is freeable so not in use by anybody.
+		 * At this point we're guaranteed that page->buffers is NULL,
+		 * nobody can refill page->buffers under us because we still
+		 * hold the page lock.
+		 */
+		if (!page->mapping || page_count(page) > 1) {
+			spin_unlock(&pagecache_lock);
+			UnlockPage(page);
+page_mapped:
+			if (--max_mapped < 0) {
+				spin_unlock(&pagemap_lru_lock);
+
+				nr_pages -= kmem_cache_reap(gfp_mask);
+				if (nr_pages <= 0)
+					goto out;
+
+				shrink_dcache_memory(vm_vfs_scan_ratio, gfp_mask);
+				shrink_icache_memory(vm_vfs_scan_ratio, gfp_mask);
+#ifdef CONFIG_QUOTA
+				shrink_dqcache_memory(vm_vfs_scan_ratio, gfp_mask);
+#endif
+
+				if (!*failed_swapout)
+					*failed_swapout = !swap_out(classzone);
+
+				max_mapped = nr_pages * vm_mapped_ratio;
+
+				spin_lock(&pagemap_lru_lock);
+				refill_inactive(nr_pages, classzone);
+			}
+			continue;
+			
+		}
+		if (PageDirty(page)) {
+			spin_unlock(&pagecache_lock);
+			UnlockPage(page);
+			continue;
+		}
+
+		__lru_cache_del(page);
+
+		/* point of no return */
+#ifdef NO_MM
+		__remove_inode_page(page);
+		spin_unlock(&pagecache_lock);
+#else /* !NO_MM */
+		if (likely(!PageSwapCache(page))) {
+			__remove_inode_page(page);
+			spin_unlock(&pagecache_lock);
+		} else {
+			swp_entry_t swap;
+			swap.val = page->index;
+			__delete_from_swap_cache(page);
+			/* must drop lru lock if getting swap_list lock */
+			spin_unlock(&pagecache_lock);
+			swap_free(swap);
+		}
+#endif /* !NO_MM */
+
+		UnlockPage(page);
+
+		/* effectively free the page here */
+		page_cache_release(page);
+
+		if (--nr_pages)
+			continue;
+		break;
+	}
+	spin_unlock(&pagemap_lru_lock);
+
+ out:
+	return nr_pages;
+}
+
+/*
+ * This moves pages from the active list to
+ * the inactive list.
+ *
+ * We move them the other way when we see the
+ * reference bit on the page.
+ */
+static void fastcall refill_inactive(int nr_pages, zone_t * classzone)
+{
+	struct list_head * entry;
+	unsigned long ratio;
+
+	ratio = (unsigned long) nr_pages * classzone->nr_active_pages / (((unsigned long) classzone->nr_inactive_pages * vm_lru_balance_ratio) + 1);
+
+	entry = active_list.prev;
+	while (ratio && entry != &active_list) {
+		struct page * page;
+
+		page = list_entry(entry, struct page, lru);
+		entry = entry->prev;
+		if (PageTestandClearReferenced(page)) {
+			list_del(&page->lru);
+			list_add(&page->lru, &active_list);
+			continue;
+		}
+
+
+		del_page_from_active_list(page);
+		add_page_to_inactive_list(page);
+		SetPageReferenced(page);
+	}
+}
+
+static int FASTCALL(shrink_caches(zone_t * classzone, unsigned int gfp_mask, int nr_pages, int * failed_swapout));
+static int fastcall shrink_caches(zone_t * classzone, unsigned int gfp_mask, int nr_pages, int * failed_swapout)
+{
+	nr_pages -= kmem_cache_reap(gfp_mask);
+	if (nr_pages <= 0)
+		goto out;
+
+	spin_lock(&pagemap_lru_lock);
+	refill_inactive(nr_pages, classzone);
+
+	nr_pages = shrink_cache(nr_pages, classzone, gfp_mask, failed_swapout);
+
+out:
+        return nr_pages;
+}
+
+static int check_classzone_need_balance(zone_t * classzone);
+
+int fastcall try_to_free_pages_zone(zone_t *classzone, unsigned int gfp_mask)
+{
+	gfp_mask = pf_gfp_mask(gfp_mask);
+
+	for (;;) {
+		int tries = vm_passes;
+		int failed_swapout = !(gfp_mask & __GFP_IO);
+		int nr_pages = SWAP_CLUSTER_MAX;
+
+		do {
+			nr_pages = shrink_caches(classzone, gfp_mask, nr_pages, &failed_swapout);
+			if (nr_pages <= 0)
+				return 1;
+			shrink_dcache_memory(vm_vfs_scan_ratio, gfp_mask);
+			shrink_icache_memory(vm_vfs_scan_ratio, gfp_mask);
+#ifdef CONFIG_QUOTA
+			shrink_dqcache_memory(vm_vfs_scan_ratio, gfp_mask);
+#endif
+			if (!failed_swapout)
+				failed_swapout = !swap_out(classzone);
+		} while (--tries);
+
+#ifdef	CONFIG_OOM_KILLER
+	out_of_memory();
+#else
+	if (likely(current->pid != 1))
+		break;
+	if (!check_classzone_need_balance(classzone))
+		break;
+
+	__set_current_state(TASK_RUNNING);
+	yield();
+#endif
+	}
+
+	return 0;
+}
+
+int fastcall try_to_free_pages(unsigned int gfp_mask)
+{
+	pg_data_t *pgdat;
+	zonelist_t *zonelist;
+	unsigned long pf_free_pages;
+	int error = 0;
+
+	pf_free_pages = current->flags & PF_FREE_PAGES;
+	current->flags &= ~PF_FREE_PAGES;
+
+	for_each_pgdat(pgdat) {
+		zonelist = pgdat->node_zonelists + (gfp_mask & GFP_ZONEMASK);
+		error |= try_to_free_pages_zone(zonelist->zones[0], gfp_mask);
+	}
+
+	current->flags |= pf_free_pages;
+	return error;
+}
+
+DECLARE_WAIT_QUEUE_HEAD(kswapd_wait);
+
+static int check_classzone_need_balance(zone_t * classzone)
+{
+	zone_t * first_zone;
+	int class_idx = zone_idx(classzone);
+
+	first_zone = classzone->zone_pgdat->node_zones;
+	while (classzone >= first_zone) {
+		if (classzone->free_pages > classzone->watermarks[class_idx].high)
+			return 0;
+		classzone--;
+	}
+	return 1;
+}
+
+static int kswapd_balance_pgdat(pg_data_t * pgdat)
+{
+	int need_more_balance = 0, i;
+	zone_t * zone;
+
+	for (i = pgdat->nr_zones-1; i >= 0; i--) {
+		zone = pgdat->node_zones + i;
+		if (unlikely(current->need_resched))
+			schedule();
+		if (!zone->need_balance || !zone->size)
+			continue;
+		if (!try_to_free_pages_zone(zone, GFP_KSWAPD)) {
+			zone->need_balance = 0;
+#ifndef CONFIG_CONTIGUOUS_PAGE_ALLOC /* we always want the memory now !! */
+			__set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(HZ*5);
+#endif
+			continue;
+		}
+		if (check_classzone_need_balance(zone))
+			need_more_balance = 1;
+		else
+			zone->need_balance = 0;
+	}
+
+	return need_more_balance;
+}
+
+static void kswapd_balance(void)
+{
+	int need_more_balance;
+	pg_data_t * pgdat;
+
+	do {
+		need_more_balance = 0;
+
+		for_each_pgdat(pgdat)
+			need_more_balance |= kswapd_balance_pgdat(pgdat);
+	} while (need_more_balance);
+}
+
+static int kswapd_can_sleep_pgdat(pg_data_t * pgdat)
+{
+	zone_t * zone;
+	int i;
+
+	for (i = pgdat->nr_zones-1; i >= 0; i--) {
+		zone = pgdat->node_zones + i;
+		if (!zone->need_balance || !zone->size)
+			continue;
+		return 0;
+	}
+
+	return 1;
+}
+
+static int kswapd_can_sleep(void)
+{
+	pg_data_t * pgdat;
+
+	for_each_pgdat(pgdat) {
+		if (!kswapd_can_sleep_pgdat(pgdat))
+			return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * The background pageout daemon, started as a kernel thread
+ * from the init process. 
+ *
+ * This basically trickles out pages so that we have _some_
+ * free memory available even if there is no other activity
+ * that frees anything up. This is needed for things like routing
+ * etc, where we otherwise might have all activity going on in
+ * asynchronous contexts that cannot page things out.
+ *
+ * If there are applications that are active memory-allocators
+ * (most normal use), this basically shouldn't matter.
+ */
+int kswapd(void *unused)
+{
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+
+	daemonize();
+	strcpy(tsk->comm, "kswapd");
+	sigfillset(&tsk->blocked);
+	
+	/*
+	 * Tell the memory management that we're a "memory allocator",
+	 * and that if we need more memory we should get access to it
+	 * regardless (see "__alloc_pages()"). "kswapd" should
+	 * never get caught in the normal page freeing logic.
+	 *
+	 * (Kswapd normally doesn't need memory anyway, but sometimes
+	 * you need a small amount of memory in order to be able to
+	 * page out something else, and this flag essentially protects
+	 * us from recursively trying to free more memory as we're
+	 * trying to free the first piece of memory in the first place).
+	 */
+	tsk->flags |= PF_MEMALLOC;
+
+	/*
+	 * Kswapd main loop.
+	 */
+	for (;;) {
+		__set_current_state(TASK_INTERRUPTIBLE);
+		add_wait_queue(&kswapd_wait, &wait);
+
+		mb();
+		if (kswapd_can_sleep())
+			schedule();
+
+		__set_current_state(TASK_RUNNING);
+		remove_wait_queue(&kswapd_wait, &wait);
+
+		/*
+		 * If we actually get into a low-memory situation,
+		 * the processes needing more memory will wake us
+		 * up on a more timely basis.
+		 */
+		kswapd_balance();
+		run_task_queue(&tq_disk);
+	}
+}
+
+static int __init kswapd_init(void)
+{
+	printk("Starting kswapd\n");
+	swap_setup();
+	kernel_thread(kswapd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
+	return 0;
+}
+
+module_init(kswapd_init)
diff -urN linux-2.4.29/net/8021q/vlan.c linux-2.4.29-uc1/net/8021q/vlan.c
--- linux-2.4.29/net/8021q/vlan.c	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-uc1/net/8021q/vlan.c	2005-06-14 02:11:53.000000000 +0100
@@ -85,7 +85,7 @@
 
 	printk(VLAN_INF "%s v%u.%u %s\n",
 	       vlan_fullname, vlan_version, vlan_release, vlan_copyright);
-	printk(VLAN_INF "All bugs added by %s\n",
+	printk(VLAN_INF "Other stuff added by %s\n",
 	       vlan_buggyright);
 
 	/* proc file system initialization */
diff -urN linux-2.4.29/net/8021q/vlan_dev.c linux-2.4.29-uc1/net/8021q/vlan_dev.c
--- linux-2.4.29/net/8021q/vlan_dev.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/8021q/vlan_dev.c	2005-06-14 02:11:53.000000000 +0100
@@ -488,6 +488,10 @@
 	stats->tx_packets++; /* for statics only */
 	stats->tx_bytes += skb->len;
 
+	skb->protocol = __constant_htons(ETH_P_8021Q);
+	skb->mac.raw -= VLAN_HLEN;
+	skb->nh.raw -= VLAN_HLEN;
+
 	skb->dev = VLAN_DEV_INFO(dev)->real_dev;
 	dev_queue_xmit(skb);
 
diff -urN linux-2.4.29/net/8021q/vlan.h linux-2.4.29-uc1/net/8021q/vlan.h
--- linux-2.4.29/net/8021q/vlan.h	2004-08-08 00:26:06.000000000 +0100
+++ linux-2.4.29-uc1/net/8021q/vlan.h	2005-06-14 02:11:53.000000000 +0100
@@ -8,7 +8,7 @@
 
 #define VLAN_ERR KERN_ERR
 #define VLAN_INF KERN_INFO
-#define VLAN_DBG KERN_ALERT /* change these... to debug, having a hard time
+#define VLAN_DBG KERN_DEBUG /* change these... to debug, having a hard time
                              * changing the log level at run-time..for some reason.
                              */
 
diff -urN linux-2.4.29/net/atm/br2684.c linux-2.4.29-uc1/net/atm/br2684.c
--- linux-2.4.29/net/atm/br2684.c	2004-08-08 00:26:06.000000000 +0100
+++ linux-2.4.29-uc1/net/atm/br2684.c	2005-06-14 02:11:52.000000000 +0100
@@ -9,9 +9,11 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
+#include <asm/uaccess.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/etherdevice.h>
+#include <net/arp.h>
 #include <linux/rtnetlink.h>
 #include <linux/ip.h>
 #include <asm/uaccess.h>
@@ -414,13 +416,6 @@
 
 	if (skb == NULL) {	/* skb==NULL means VCC is being destroyed */
 		br2684_close_vcc(brvcc);
-		if (list_empty(&brdev->brvccs)) {
-			read_lock(&devs_lock);
-			list_del(&brdev->br2684_devs);
-			read_unlock(&devs_lock);
-			unregister_netdev(&brdev->net_dev);
-			kfree(brdev);
-		}
 		return;
 	}
 
diff -urN linux-2.4.29/net/atm/clip.c linux-2.4.29-uc1/net/atm/clip.c
--- linux-2.4.29/net/atm/clip.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/atm/clip.c	2005-06-14 02:11:52.000000000 +0100
@@ -372,6 +372,7 @@
 	struct clip_priv *clip_priv = PRIV(dev);
 	struct atmarp_entry *entry;
 	struct atm_vcc *vcc;
+	struct clip_vcc *vccs;
 	int old;
 	unsigned long flags;
 
@@ -397,7 +398,8 @@
 		return 0;
 	}
 	entry = NEIGH2ENTRY(skb->dst->neighbour);
-	if (!entry->vccs) {
+	vccs = entry->vccs;
+	if (!vccs) {
 		if (time_after(jiffies, entry->expires)) {
 			/* should be resolved */
 			entry->expires = jiffies+ATMARP_RETRY_DELAY*HZ;
@@ -411,10 +413,10 @@
 		}
 		return 0;
 	}
-	DPRINTK("neigh %p, vccs %p\n",entry,entry->vccs);
-	ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc;
+	DPRINTK("neigh %p, vccs %p\n",entry,vccs);
+	ATM_SKB(skb)->vcc = vcc = vccs->vcc;
 	DPRINTK("using neighbour %p, vcc %p\n",skb->dst->neighbour,vcc);
-	if (entry->vccs->encap) {
+	if (vccs->encap) {
 		void *here;
 
 		here = skb_push(skb,RFC1483LLC_LEN);
@@ -423,9 +425,9 @@
 	}
 	atomic_add(skb->truesize,&vcc->sk->wmem_alloc);
 	ATM_SKB(skb)->atm_options = vcc->atm_options;
-	entry->vccs->last_use = jiffies;
+	vccs->last_use = jiffies;
 	DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n",skb,vcc,vcc->dev);
-	old = xchg(&entry->vccs->xoff,1); /* assume XOFF ... */
+	old = xchg(&vccs->xoff,1); /* assume XOFF ... */
 	if (old) {
 		printk(KERN_WARNING "clip_start_xmit: XOFF->XOFF transition\n");
 		return 0;
@@ -434,13 +436,13 @@
 	clip_priv->stats.tx_bytes += skb->len;
 	(void) vcc->send(vcc,skb);
 	if (atm_may_send(vcc,0)) {
-		entry->vccs->xoff = 0;
+		vccs->xoff = 0;
 		return 0;
 	}
 	spin_lock_irqsave(&clip_priv->xoff_lock,flags);
 	netif_stop_queue(dev); /* XOFF -> throttle immediately */
 	barrier();
-	if (!entry->vccs->xoff)
+	if (!vccs->xoff)
 		netif_start_queue(dev);
 		/* Oh, we just raced with clip_pop. netif_start_queue should be
 		   good enough, because nothing should really be asleep because
diff -urN linux-2.4.29/net/atm/common.c linux-2.4.29-uc1/net/atm/common.c
--- linux-2.4.29/net/atm/common.c	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-uc1/net/atm/common.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,4 @@
+/* $USAGI: common.c,v 1.9 2003/11/12 22:50:57 yoshfuji Exp $ */
 /* net/atm/common.c - ATM sockets (common part for PVC and SVC) */
 
 /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
@@ -11,6 +12,10 @@
 #include <linux/atm.h>		/* ATM stuff */
 #include <linux/atmdev.h>
 #include <linux/atmclip.h>	/* CLIP_*ENCAP */
+#ifdef CONFIG_ATM_IPV6
+#include <linux/atmipv6.h>	/* IPv6 over ATM */
+#include <net/atmipv6.h>	/* IPv6 over ATM */
+#endif /* ifdef CONFIG_ATM_IPV6 */
 #include <linux/atmarp.h>	/* manifest constants */
 #include <linux/sonet.h>	/* for ioctls */
 #include <linux/socket.h>	/* SOL_SOCKET */
@@ -297,7 +302,9 @@
 	struct sk_buff *skb;
 
 	vcc = sk->protinfo.af_atm;
+	DPRINTK("atm_release_vcc_sk(vcc:0x%08x)\n", (unsigned int)vcc);
 	clear_bit(ATM_VF_READY, &vcc->flags);
+	DPRINTK("atm_release_vcc_sk(dev:0x%08x)\n", (unsigned int)vcc->dev);
 	if (vcc->dev) {
 		if (vcc->dev->ops->close)
 			vcc->dev->ops->close(vcc);
@@ -786,6 +793,32 @@
 				error = -ENOSYS;
 			goto done;
 #endif
+#ifdef CONFIG_ATM_IPV6
+		case SIOCMKP2PPVC:
+			if (!capable(CAP_NET_ADMIN))
+				error = -EPERM;
+			else 
+				error = clip6_create(arg);
+			goto done;
+		case ATMIPV6_MKIPV6:
+			if (!capable(CAP_NET_ADMIN)) 
+				error = -EPERM;
+			else 
+				error = clip6_mkip(vcc,arg);
+			goto done;
+		case ATMIPV6_SETP2P:
+			if (!capable(CAP_NET_ADMIN)) 
+				error = -EPERM;
+			else
+				error = clip6_set_vcc_netif(sock,arg);
+			goto done;
+		case ATMIPV6_ENCAP:
+			if (!capable(CAP_NET_ADMIN)) 
+				error = -EPERM;
+			else
+				error = clip6_encap(vcc,arg);
+			goto done;
+#endif /* ifdef CONFIG_ATM_IPV6 */
 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
                 case ATMLEC_CTRL:
                         if (!capable(CAP_NET_ADMIN)) {
diff -urN linux-2.4.29/net/atm/ipv6atm.c linux-2.4.29-uc1/net/atm/ipv6atm.c
--- linux-2.4.29/net/atm/ipv6atm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/atm/ipv6atm.c	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,419 @@
+/* $USAGI: ipv6atm.c,v 1.11 2003/12/01 08:01:21 sekiya Exp $
+ *
+ * RFC2492 IPv6 over ATM
+ *
+ * Copyright (C)2001 USAGI/WIDE Project
+ * 
+ * Written by Kazuyoshi SERIZAWA, based on
+ * net/atm/clip.c - RFC1577 Classical IP over ATM
+ * Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA
+ */
+
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/kernel.h> /* for UINT_MAX */
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/wait.h>
+#include <linux/timer.h>
+#include <linux/if_arp.h> /* for some manifest constants */
+#include <linux/notifier.h>
+#include <linux/atm.h>
+#include <linux/atmdev.h>
+#include <linux/atmipv6.h>	/* IPv6 over ATM */
+#include <linux/ip.h> /* for net/route.h */
+#include <linux/in.h> /* for struct sockaddr_in */
+#include <linux/if.h> /* for IFF_UP */
+#include <linux/inetdevice.h>
+#include <linux/bitops.h>
+#include <net/route.h> /* for struct rtable and routing */
+#include <net/icmp.h> /* icmp_send */
+#include <asm/param.h> /* for HZ */
+#include <asm/byteorder.h> /* for htons etc. */
+#include <asm/system.h> /* save/restore_flags */
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+
+#include "common.h"
+#include "resources.h"
+#include "ipcommon.h"
+#include <net/atmipv6.h>
+
+#if 0
+#define DPRINTK(format,args...) printk(format,##args)
+#else
+#define DPRINTK(format,args...)
+#endif
+
+
+struct net_device *clip6_devs = NULL;
+
+
+void clip6_push(struct atm_vcc *vcc,struct sk_buff *skb)
+{
+	struct clip6_vcc *clip6_vcc = CLIP6_VCC(vcc);
+
+	DPRINTK("clip6 push\n");
+	if (!skb) {
+		DPRINTK("removing VCC %p\n",clip6_vcc);
+		clip6_vcc->old_push(vcc,NULL); /* pass on the bad news */
+		kfree(clip6_vcc);
+		return;
+	}
+	atm_return(vcc,skb->truesize);
+	skb->dev = clip6_vcc->dev;
+		/* clip6_vcc->entry == NULL if we don't have an IP address yet */
+	if (!skb->dev) {
+		dev_kfree_skb_any(skb);
+		return;
+	}
+	ATM_SKB(skb)->vcc = vcc;
+	skb->mac.raw = skb->data;
+	if (!clip6_vcc->encap || skb->len < RFC1483LLC_LEN || memcmp(skb->data,
+	    llc_oui,sizeof(llc_oui))) {
+		skb->protocol = ((u16 *) skb->data)[3];
+				/* ??? Should I validate skb->protocol is
+				   either ETH_P_IPV6 or ETH_P_IP? */
+	}
+	else {
+		skb->protocol = ((u16 *) skb->data)[3];
+		skb_pull(skb,RFC1483LLC_LEN);
+				/* TODO: check */
+#if 0
+		if (skb->protocol == htons(ETH_P_ARP)) {
+			PRIV(skb->dev)->stats.rx_packets++;
+			PRIV(skb->dev)->stats.rx_bytes += skb->len;
+			clip6_arp_rcv(skb);
+			return;
+		}
+#endif /* if 0 */
+	}
+	clip6_vcc->last_use = jiffies;
+	PRIV(skb->dev)->stats.rx_packets++;
+	PRIV(skb->dev)->stats.rx_bytes += skb->len;
+	netif_rx(skb);
+}
+
+
+/*
+ * Note: these spinlocks _must_not_ block on non-SMP. The only goal is that
+ * clip6_pop is atomic with respect to the critical section in clip6_start_xmit.
+ */
+
+
+static void clip6_pop(struct atm_vcc *vcc,struct sk_buff *skb)
+{
+	struct clip6_vcc *clip6_vcc = CLIP6_VCC(vcc);
+	struct net_device *dev = skb->dev;
+	int old;
+	unsigned long flags;
+
+	DPRINTK("clip6_pop(vcc %p)\n",vcc);
+	clip6_vcc->old_pop(vcc,skb);
+	/* skb->dev == NULL in outbound ARP packets */
+	if (!dev) return;
+	spin_lock_irqsave(&PRIV(dev)->xoff_lock,flags);
+	if (atm_may_send(vcc,0)) {
+		old = xchg(&clip6_vcc->xoff,0);
+		if (old) netif_wake_queue(dev);
+	}
+	spin_unlock_irqrestore(&PRIV(dev)->xoff_lock,flags);
+}
+
+
+/* @@@ copy bh locking from arp.c -- need to bh-enable atm code before */
+
+/*
+ * We play with the resolve flag: 0 and 1 have the usual meaning, but -1 means
+ * to allocate the neighbour entry but not to ask atmarpd for resolution. Also,
+ * don't increment the usage count. This is used to create entries in
+ * clip6_setentry.
+ */
+
+
+int clip6_encap(struct atm_vcc *vcc,int mode)
+{
+	if (mode != 1) return -EINVAL; /* Only LLC/SNAP is supported */
+	CLIP6_VCC(vcc)->encap = mode;
+	return 0;
+}
+
+
+static int clip6_start_xmit(struct sk_buff *skb,struct net_device *dev)
+{
+	struct clip6_priv *clip6_priv = PRIV(dev);
+	struct atm_vcc *vcc;
+	struct clip6_vcc *vccs;
+	int old;
+	unsigned long flags;
+
+	DPRINTK("clip6_start_xmit (skb %p)\n",skb);
+
+	vccs = clip6_priv->vccs;
+	if (!vccs) {
+		/* SVC is not supported yet. */
+		printk(KERN_ERR "clip6_start_xmit: vccs == NULL\n");
+		dev_kfree_skb(skb);
+		clip6_priv->stats.tx_dropped++;
+		return 0;
+	}
+	DPRINTK("vccs %p\n", vccs);
+	ATM_SKB(skb)->vcc = vcc = vccs->vcc;
+	DPRINTK("using p2p vcc %p\n",vcc);
+	if (vccs->encap) {
+		void *here;
+
+		here = skb_push(skb,RFC1483LLC_LEN);
+		memcpy(here,llc_oui,sizeof(llc_oui));
+		((u16 *) here)[3] = skb->protocol;
+	}
+	atomic_add(skb->truesize, &vcc->sk->wmem_alloc);
+	ATM_SKB(skb)->atm_options = vcc->atm_options;
+		/* TODO: check */
+	vccs->last_use = jiffies;
+	DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n",skb,vcc,vcc->dev);
+	old = xchg(&vccs->xoff,1); /* assume XOFF ... */
+	if (old) {
+		printk(KERN_WARNING "clip6_start_xmit: XOFF->XOFF transition\n");
+		return 0;
+	}
+	clip6_priv->stats.tx_packets++;
+	clip6_priv->stats.tx_bytes += skb->len;
+	(void) vcc->send(vcc,skb);
+	if (atm_may_send(vcc,0)) {
+		vccs->xoff = 0;
+		return 0;
+	}
+	spin_lock_irqsave(&clip6_priv->xoff_lock,flags);
+	netif_stop_queue(dev); /* XOFF -> throttle immediately */
+	barrier();
+	if (!vccs->xoff)
+		netif_start_queue(dev);
+		/* Oh, we just raced with clip6_pop. netif_start_queue should be
+		   good enough, because nothing should really be asleep because
+		   of the brief netif_stop_queue. If this isn't true or if it
+		   changes, use netif_wake_queue instead. */
+	spin_unlock_irqrestore(&clip6_priv->xoff_lock,flags);
+	return 0;
+}
+
+
+static struct net_device_stats *clip6_get_stats(struct net_device *dev)
+{
+	return &PRIV(dev)->stats;
+}
+
+
+int clip6_mkip(struct atm_vcc *vcc,int timeout)
+{
+	struct clip6_vcc *clip6_vcc;
+	struct sk_buff_head copy;
+	struct sk_buff *skb;
+
+	if (!vcc->push) return -EBADFD;
+	clip6_vcc = kmalloc(sizeof(struct clip6_vcc),GFP_KERNEL);
+	if (!clip6_vcc) return -ENOMEM;
+	DPRINTK("mkip6 clip6_vcc %p vcc %p\n",clip6_vcc,vcc);
+	clip6_vcc->vcc = vcc;
+	vcc->user_back = clip6_vcc;
+	clip6_vcc->entry = NULL;
+	clip6_vcc->dev = NULL;
+	clip6_vcc->xoff = 0;
+	clip6_vcc->encap = 1;
+	clip6_vcc->last_use = jiffies;
+	clip6_vcc->idle_timeout = timeout*HZ;
+	clip6_vcc->old_push = vcc->push;
+	clip6_vcc->old_pop = vcc->pop;
+	vcc->push = clip6_push;
+	vcc->pop = clip6_pop;
+	skb_queue_head_init(&copy);
+	skb_migrate(&vcc->sk->receive_queue,&copy);
+	/* re-process everything received between connection setup and MKIP */
+	while ((skb = skb_dequeue(&copy)))
+		if (!clip6_devs) {
+			atm_return(vcc,skb->truesize);
+			kfree_skb(skb);
+		}
+		else {
+			unsigned int len = skb->len;
+
+			clip6_push(vcc,skb);
+			PRIV(skb->dev)->stats.rx_packets--;
+			PRIV(skb->dev)->stats.rx_bytes -= len;
+		}
+	return 0;
+}
+
+
+int clip6_set_vcc_netif(struct socket *sock,int number)
+{
+	struct clip6_vcc *clip6_vcc;
+	struct sock *sk = NULL;
+	struct net_device *dev;
+	struct atm_vcc *vcc = ATM_SD(sock);
+	
+	DPRINTK("clip6_set_vcc_netif 0x%08x\n", (unsigned int)vcc);
+	if (vcc->push != clip6_push) {
+		printk(KERN_WARNING "clip6_set_vcc_netif: non-CLIP VCC\n");
+		return -EBADF;
+	}
+
+	/* allocate a scapegoat sk and vcc */
+	if (sock->type == SOCK_STREAM)
+		return -EINVAL;
+	sk = sk_alloc(sock->sk->family, GFP_KERNEL, 1);
+	if (!sk)
+		return -ENOMEM;
+	sock_init_data(NULL, sk);
+
+	vcc = sk->protinfo.af_atm = kmalloc(sizeof(*vcc), GFP_KERNEL);
+	if (!vcc) {
+		sk_free(sk);
+		return -ENOMEM;
+	}
+
+	memset(vcc, 0, sizeof(*vcc));
+	vcc->sk = sk;
+
+	clip6_vcc = CLIP6_VCC(vcc);
+
+	for (dev = clip6_devs; dev; dev = PRIV(dev)->next) {
+	    if (PRIV(dev)->number == number) {
+	        PRIV(dev)->vccs = clip6_vcc;
+		clip6_vcc->dev = dev;
+		if (vcc->dev) {
+				/* copy MAC address */
+				/* TODO: This will cause address duplication
+				     in case loop back. 
+				     To avoid this, dev_addr should include
+				     the number of interface, or such. */
+			dev->addr_len = ESI_LEN;
+			memcpy(dev->dev_addr, vcc->dev->esi, dev->addr_len);
+		}
+			/* detach vcc from a soket */
+		sk->rcvbuf = vcc->sk->rcvbuf;
+		sk->sndbuf = vcc->sk->sndbuf;
+
+		PRIV(dev)->vcc = vcc;
+		PRIV(dev)->vcc->sk = sk;
+		
+		*(&ATM_SD(sock)) = sk->protinfo.af_atm;
+		sk->protinfo.af_atm->sk = sock->sk;
+
+				/* TODO: ininialize lists, 	vcc->prev,next, nodev_vccs */
+		return 0;
+	    }
+	}
+	return -ENODEV;
+}
+
+
+static int clip6_init(struct net_device *dev)
+{
+	DPRINTK("clip6_init %s\n",dev->name);
+	dev->hard_start_xmit = clip6_start_xmit;
+	/* sg_xmit ... */
+	dev->hard_header = NULL;
+	dev->rebuild_header = NULL;
+	dev->set_mac_address = NULL;
+	dev->hard_header_parse = NULL;
+	dev->hard_header_cache = NULL;
+	dev->header_cache_update = NULL;
+	dev->change_mtu = NULL;
+	dev->do_ioctl = NULL;
+	dev->get_stats = clip6_get_stats;
+	dev->type = ARPHRD_ATM;
+	dev->hard_header_len = RFC1483LLC_LEN;
+				/* TODO: check */
+	dev->mtu = RFC1626_MTU;
+	dev->addr_len = 0;
+	dev->tx_queue_len = 100; /* "normal" queue (packets) */
+	    /* When using a "real" qdisc, the qdisc determines the queue */
+	    /* length. tx_queue_len is only used for the default case, */
+	    /* without any more elaborate queuing. 100 is a reasonable */
+	    /* compromise between decent burst-tolerance and protection */
+	    /* against memory hogs. */
+	dev->flags = 0;
+	return 0;
+}
+
+
+int clip6_create(int number)
+{
+	struct net_device *dev;
+	struct clip6_priv *clip6_priv;
+	int error;
+
+	DPRINTK("clip6_create\n");
+	if (number != -1) {
+		for (dev = clip6_devs; dev; dev = PRIV(dev)->next)
+			if (PRIV(dev)->number == number) return -EEXIST;
+	}
+	else {
+		number = 0;
+		for (dev = clip6_devs; dev; dev = PRIV(dev)->next)
+			if (PRIV(dev)->number >= number)
+				number = PRIV(dev)->number+1;
+		DPRINTK("clip6_create number %d\n", number);
+	}
+	dev = kmalloc(sizeof(struct net_device)+sizeof(struct clip6_priv),
+	    GFP_KERNEL); 
+	DPRINTK("clip6_create mem\n");
+	if (!dev) return -ENOMEM;
+	DPRINTK("clip6_create mem ok\n");
+	memset(dev,0,sizeof(struct net_device)+sizeof(struct clip6_priv));
+	clip6_priv = PRIV(dev);
+	sprintf(dev->name,"atm%d",number);
+	dev->init = clip6_init;
+	spin_lock_init(&clip6_priv->xoff_lock);
+	clip6_priv->number = number;
+	error = register_netdev(dev);
+	if (error) {
+		kfree(dev);
+		DPRINTK("clip6_create error %d\n",error);
+		return error;
+	}
+	clip6_priv->next = clip6_devs;
+	clip6_devs = dev;
+	clip6_priv->vccs = NULL;
+	clip6_priv->vcc = NULL;
+	DPRINTK("registered (net:%s)\n",dev->name);
+	return number;
+}
+
+
+static int clip6_device_event(struct notifier_block *this,unsigned long event,
+    void *dev)
+{
+	/* ignore non-CLIP devices */
+	if (((struct net_device *) dev)->type != ARPHRD_ATM ||
+	    ((struct net_device *) dev)->init != clip6_init)
+		return NOTIFY_DONE;
+	switch (event) {
+		case NETDEV_UP:
+			DPRINTK("clip6_device_event NETDEV_UP\n");
+			/* ignore */
+			break;
+		case NETDEV_GOING_DOWN:
+			DPRINTK("clip6_device_event NETDEV_DOWN\n");
+			/* ignore */
+			break;
+		case NETDEV_CHANGE:
+		case NETDEV_CHANGEMTU:
+			DPRINTK("clip6_device_event NETDEV_CHANGE*\n");
+			/* ignore */
+			break;
+		case NETDEV_REBOOT:
+		case NETDEV_REGISTER:
+		case NETDEV_DOWN:
+			DPRINTK("clip6_device_event %ld\n",event);
+			/* ignore */
+			break;
+		default:
+			printk(KERN_WARNING "clip6_device_event: unknown event "
+			    "%ld\n",event);
+			break;
+	}
+	return NOTIFY_DONE;
+}
diff -urN linux-2.4.29/net/atm/Makefile linux-2.4.29-uc1/net/atm/Makefile
--- linux-2.4.29/net/atm/Makefile	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/net/atm/Makefile	2005-06-14 02:11:52.000000000 +0100
@@ -19,6 +19,11 @@
   obj-m += $(O_TARGET)
 endif
 
+ifeq ($(CONFIG_ATM_IPV6),y)
+obj-y += ipv6atm.o
+NEED_IPCOM = ipcommon.o
+endif
+
 ifneq ($(CONFIG_ATM_CLIP),n)
   NEED_IPCOM = ipcommon.o
 endif
diff -urN linux-2.4.29/net/atm/proc.c linux-2.4.29-uc1/net/atm/proc.c
--- linux-2.4.29/net/atm/proc.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/atm/proc.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,4 @@
+/* $USAGI: proc.c,v 1.8 2003/11/12 05:11:59 yoshfuji Exp $ */
 /* net/atm/proc.c - ATM /proc interface */
 
 /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
@@ -288,6 +289,10 @@
 };
 #endif
 
+#ifdef CONFIG_ATM_IPV6
+  /* TODO: solve conflicts. */
+#include <net/atmipv6.h>
+#endif /* ifdef CONFIG_ATM_IPV6 */
 
 static void pvc_info(struct atm_vcc *vcc, char *buf, int clip_info)
 {
@@ -308,9 +313,17 @@
 #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
 	if (clip_info && (vcc->push == atm_clip_ops->clip_push)) {
 		struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
+#ifdef CONFIG_ATM_IPV6
+		struct clip6_vcc *clip6_vcc = CLIP6_VCC(vcc);
+#endif
 		struct net_device *dev;
 
+#ifdef CONFIG_ATM_IPV6
+		dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : 
+		    (clip6_vcc->dev ? clip6_vcc->dev : NULL);
+#else /* i.e., !ifdef CONFIG_ATM_IPV6 */
 		dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : NULL;
+#endif /* ifdef CONFIG_ATM_IPV6 */
 		off += sprintf(buf+off,"CLIP, Itf:%s, Encap:",
 		    dev ? dev->name : "none?");
 		if (clip_vcc->encap)
@@ -319,6 +332,18 @@
 			off += sprintf(buf+off,"None");
 	}
 #endif
+#ifdef CONFIG_ATM_IPV6
+	if (vcc->push == clip6_push) {
+		struct clip6_vcc *clip6_vcc = CLIP6_VCC(vcc);
+		struct net_device *dev;
+
+		dev = clip6_vcc->dev ? clip6_vcc->dev : NULL;
+		off += sprintf(buf+off,"CLIP6, Itf:%s, Encap:",
+		    dev ? dev->name : "none?");
+		if (clip6_vcc->encap) off += sprintf(buf+off,"LLC/SNAP");
+		else off += sprintf(buf+off,"None");
+	}
+#endif /* ifdef CONFIG_ATM_IPV6 */
 	strcpy(buf+off,"\n");
 }
 
diff -urN linux-2.4.29/net/bridge/br.c linux-2.4.29-uc1/net/bridge/br.c
--- linux-2.4.29/net/bridge/br.c	2004-08-08 00:26:06.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/br.c	2005-06-14 02:11:49.000000000 +0100
@@ -30,6 +30,8 @@
 #include "../atm/lec.h"
 #endif
 
+int (*br_should_route_hook) (struct sk_buff **pskb) = NULL;
+
 void br_dec_use_count()
 {
 	MOD_DEC_USE_COUNT;
@@ -44,6 +46,10 @@
 {
 	printk(KERN_INFO "NET4: Ethernet Bridge 008 for NET4.0\n");
 
+#ifdef CONFIG_NETFILTER
+	if (br_netfilter_init())
+		return 1;
+#endif
 	br_handle_frame_hook = br_handle_frame;
 	br_ioctl_hook = br_ioctl_deviceless_stub;
 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
@@ -57,6 +63,9 @@
 
 static void __exit br_deinit(void)
 {
+#ifdef CONFIG_NETFILTER
+	br_netfilter_fini();
+#endif
 	unregister_netdevice_notifier(&br_device_notifier);
 
 	rtnl_lock();
@@ -73,7 +82,7 @@
 #endif
 }
 
-EXPORT_NO_SYMBOLS;
+EXPORT_SYMBOL(br_should_route_hook);
 
 module_init(br_init)
 module_exit(br_deinit)
diff -urN linux-2.4.29/net/bridge/br_forward.c linux-2.4.29-uc1/net/bridge/br_forward.c
--- linux-2.4.29/net/bridge/br_forward.c	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/net/bridge/br_forward.c	2005-06-14 02:11:49.000000000 +0100
@@ -30,18 +30,21 @@
 	return 1;
 }
 
-static int __dev_queue_push_xmit(struct sk_buff *skb)
+int br_dev_queue_push_xmit(struct sk_buff *skb)
 {
+#ifdef CONFIG_NETFILTER
+	nf_bridge_maybe_copy_header(skb);
+#endif
 	skb_push(skb, ETH_HLEN);
 	dev_queue_xmit(skb);
 
 	return 0;
 }
 
-static int __br_forward_finish(struct sk_buff *skb)
+int br_forward_finish(struct sk_buff *skb)
 {
 	NF_HOOK(PF_BRIDGE, NF_BR_POST_ROUTING, skb, NULL, skb->dev,
-			__dev_queue_push_xmit);
+			br_dev_queue_push_xmit);
 
 	return 0;
 }
@@ -49,8 +52,11 @@
 static void __br_deliver(struct net_bridge_port *to, struct sk_buff *skb)
 {
 	skb->dev = to->dev;
+#ifdef CONFIG_NETFILTER_DEBUG
+	skb->nf_debug = 0;
+#endif
 	NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
-			__br_forward_finish);
+			br_forward_finish);
 }
 
 static void __br_forward(struct net_bridge_port *to, struct sk_buff *skb)
@@ -62,7 +68,7 @@
 	skb->ip_summed = CHECKSUM_NONE;
 
 	NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev,
-			__br_forward_finish);
+			br_forward_finish);
 }
 
 /* called under bridge lock */
diff -urN linux-2.4.29/net/bridge/br_if.c linux-2.4.29-uc1/net/bridge/br_if.c
--- linux-2.4.29/net/bridge/br_if.c	2004-08-08 00:26:06.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/br_if.c	2005-06-14 02:11:49.000000000 +0100
@@ -215,8 +215,10 @@
 	if (dev->br_port != NULL)
 		return -EBUSY;
 
+#if 0
 	if (dev->flags & IFF_LOOPBACK || dev->type != ARPHRD_ETHER)
 		return -EINVAL;
+#endif
 
 	if (dev->hard_start_xmit == br_dev_xmit)
 		return -ELOOP;
@@ -257,14 +259,20 @@
 	return retval;
 }
 
-int br_get_bridge_ifindices(int *indices, int num)
+int br_get_bridge_ifindices(int *indices, int num, int user_buf)
 {
 	struct net_device *dev;
 	int i = 0;
 
 	for (dev = dev_base; i < num && dev != NULL; dev = dev->next) {
 		if (dev->hard_start_xmit == br_dev_xmit)
-			indices[i++] = dev->ifindex;
+			if (user_buf) {
+				if (copy_to_user(indices+i, &dev->ifindex, sizeof(dev->ifindex)))
+					return -EFAULT;
+				i++;
+			} else {
+				indices[i++] = dev->ifindex;
+			}
 	}
 
 	return i;
diff -urN linux-2.4.29/net/bridge/br_input.c linux-2.4.29-uc1/net/bridge/br_input.c
--- linux-2.4.29/net/bridge/br_input.c	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/br_input.c	2005-06-14 02:11:49.000000000 +0100
@@ -24,6 +24,9 @@
 
 static int br_pass_frame_up_finish(struct sk_buff *skb)
 {
+#ifdef CONFIG_NETFILTER_DEBUG
+	skb->nf_debug = 0;
+#endif
 	netif_rx(skb);
 
 	return 0;
@@ -46,7 +49,7 @@
 			br_pass_frame_up_finish);
 }
 
-static int br_handle_frame_finish(struct sk_buff *skb)
+int br_handle_frame_finish(struct sk_buff *skb)
 {
 	struct net_bridge *br;
 	unsigned char *dest;
@@ -112,7 +115,7 @@
 	return 0;
 }
 
-void br_handle_frame(struct sk_buff *skb)
+int br_handle_frame(struct sk_buff *skb)
 {
 	struct net_bridge *br;
 	unsigned char *dest;
@@ -146,26 +149,34 @@
 		goto handle_special_frame;
 
 	if (p->state == BR_STATE_FORWARDING) {
+ 		if (br_should_route_hook && br_should_route_hook(&skb)) {
+ 			read_unlock(&br->lock);
+ 			return -1;
+ 		}
+ 
+ 		if (!memcmp(p->br->dev.dev_addr, dest, ETH_ALEN))
+ 			skb->pkt_type = PACKET_HOST;
+ 
 		NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
 			br_handle_frame_finish);
 		read_unlock(&br->lock);
-		return;
+		return 0;
 	}
 
 err:
 	read_unlock(&br->lock);
 err_nolock:
 	kfree_skb(skb);
-	return;
+	return 0;
 
 handle_special_frame:
 	if (!dest[5]) {
-		NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,NULL,
-			br_stp_handle_bpdu);
+ 		br_stp_handle_bpdu(skb);
 		read_unlock(&br->lock);
-		return;
+		return 0;
 	}
 
 	read_unlock(&br->lock);
 	kfree_skb(skb);
+	return 0;
 }
diff -urN linux-2.4.29/net/bridge/br_ioctl.c linux-2.4.29-uc1/net/bridge/br_ioctl.c
--- linux-2.4.29/net/bridge/br_ioctl.c	2004-08-08 00:26:06.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/br_ioctl.c	2005-06-14 02:11:49.000000000 +0100
@@ -196,17 +196,7 @@
 
 	case BRCTL_GET_BRIDGES:
 	{
-		int i;
-		int indices[64];
-
-		for (i=0;i<64;i++)
-			indices[i] = 0;
-
-		if (arg1 > 64)
-			arg1 = 64;
-		arg1 = br_get_bridge_ifindices(indices, arg1);
-		if (copy_to_user((void *)arg0, indices, arg1*sizeof(int)))
-			return -EFAULT;
+		arg1 = br_get_bridge_ifindices((void *)arg0, arg1, 1);
 
 		return arg1;
 	}
diff -urN linux-2.4.29/net/bridge/br_netfilter.c linux-2.4.29-uc1/net/bridge/br_netfilter.c
--- linux-2.4.29/net/bridge/br_netfilter.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/br_netfilter.c	2005-06-14 02:11:49.000000000 +0100
@@ -0,0 +1,720 @@
+/*
+ *	Handle firewalling
+ *	Linux ethernet bridge
+ *
+ *	Authors:
+ *	Lennert Buytenhek               <buytenh@gnu.org>
+ *	Bart De Schuymer (maintainer)	<bdschuym@pandora.be>
+ *
+ *	Changes:
+ *	Apr 29 2003: physdev module support (bdschuym)
+ *	Jun 19 2003: let arptables see bridged ARP traffic (bdschuym)
+ *	Oct 06 2003: filter encapsulated IP/ARP VLAN traffic on untagged bridge
+ *	             (bdschuym)
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ *	Lennert dedicates this file to Kerstin Wurdinger.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/ip.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
+#include <linux/netfilter_bridge.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/in_route.h>
+#include <net/ip.h>
+#include <asm/uaccess.h>
+#include <asm/checksum.h>
+#include "br_private.h"
+
+
+#define skb_origaddr(skb)	 (((struct bridge_skb_cb *) \
+				 (skb->cb))->daddr.ipv4)
+#define store_orig_dstaddr(skb)	 (skb_origaddr(skb) = (skb)->nh.iph->daddr)
+#define dnat_took_place(skb)	 (skb_origaddr(skb) != (skb)->nh.iph->daddr)
+#define clear_cb(skb)		 (memset(&skb_origaddr(skb), 0, \
+				 sizeof(struct bridge_skb_cb)))
+
+#define has_bridge_parent(device)	((device)->br_port != NULL)
+#define bridge_parent(device)		(&((device)->br_port->br->dev))
+
+#define IS_VLAN_IP (skb->protocol == __constant_htons(ETH_P_8021Q) && \
+	hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_IP))
+
+/* We need these fake structures to make netfilter happy --
+ * lots of places assume that skb->dst != NULL, which isn't
+ * all that unreasonable.
+ *
+ * Currently, we fill in the PMTU entry because netfilter
+ * refragmentation needs it, and the rt_flags entry because
+ * ipt_REJECT needs it.  Future netfilter modules might
+ * require us to fill additional fields.
+ */
+static struct net_device __fake_net_device = {
+	.hard_header_len	= ETH_HLEN
+};
+
+static struct rtable __fake_rtable = {
+	u: {
+		dst: {
+			__refcnt:		ATOMIC_INIT(1),
+			dev:			&__fake_net_device,
+			pmtu:			1500
+		}
+	},
+
+	rt_flags:	0
+};
+
+
+/* PF_BRIDGE/PRE_ROUTING *********************************************/
+static void __br_dnat_complain(void)
+{
+	static unsigned long last_complaint;
+
+	if (jiffies - last_complaint >= 5 * HZ) {
+		printk(KERN_WARNING "Performing cross-bridge DNAT requires IP "
+			"forwarding to be enabled\n");
+		last_complaint = jiffies;
+	}
+}
+
+
+/* This requires some explaining. If DNAT has taken place,
+ * we will need to fix up the destination Ethernet address,
+ * and this is a tricky process.
+ *
+ * There are two cases to consider:
+ * 1. The packet was DNAT'ed to a device in the same bridge
+ *    port group as it was received on. We can still bridge
+ *    the packet.
+ * 2. The packet was DNAT'ed to a different device, either
+ *    a non-bridged device or another bridge port group.
+ *    The packet will need to be routed.
+ *
+ * The correct way of distinguishing between these two cases is to
+ * call ip_route_input() and to look at skb->dst->dev, which is
+ * changed to the destination device if ip_route_input() succeeds.
+ *
+ * Let us first consider the case that ip_route_input() succeeds:
+ *
+ * If skb->dst->dev equals the logical bridge device the packet
+ * came in on, we can consider this bridging. We then call
+ * skb->dst->output() which will make the packet enter br_nf_local_out()
+ * not much later. In that function it is assured that the iptables
+ * FORWARD chain is traversed for the packet.
+ *
+ * Otherwise, the packet is considered to be routed and we just
+ * change the destination MAC address so that the packet will
+ * later be passed up to the IP stack to be routed.
+ *
+ * Let us now consider the case that ip_route_input() fails:
+ *
+ * After a "echo '0' > /proc/sys/net/ipv4/ip_forward" ip_route_input()
+ * will fail, while __ip_route_output_key() will return success. The source
+ * address for __ip_route_output_key() is set to zero, so __ip_route_output_key
+ * thinks we're handling a locally generated packet and won't care
+ * if IP forwarding is allowed. We send a warning message to the users's
+ * log telling her to put IP forwarding on.
+ *
+ * ip_route_input() will also fail if there is no route available.
+ * In that case we just drop the packet.
+ *
+ * --Lennert, 20020411
+ * --Bart, 20020416 (updated)
+ * --Bart, 20021007 (updated)
+ */
+
+static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
+{
+#ifdef CONFIG_NETFILTER_DEBUG
+	skb->nf_debug |= (1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_FORWARD);
+#endif
+
+	if (skb->pkt_type == PACKET_OTHERHOST) {
+		skb->pkt_type = PACKET_HOST;
+		skb->nf_bridge->mask |= BRNF_PKT_TYPE;
+	}
+	skb->nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
+
+	skb->dev = bridge_parent(skb->dev);
+	if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+		skb_pull(skb, VLAN_HLEN);
+		skb->nh.raw += VLAN_HLEN;
+	}
+	skb->dst->output(skb);
+	return 0;
+}
+
+static int br_nf_pre_routing_finish(struct sk_buff *skb)
+{
+	struct net_device *dev = skb->dev;
+	struct iphdr *iph = skb->nh.iph;
+	struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+
+#ifdef CONFIG_NETFILTER_DEBUG
+	skb->nf_debug ^= (1 << NF_BR_PRE_ROUTING);
+#endif
+
+	if (nf_bridge->mask & BRNF_PKT_TYPE) {
+		skb->pkt_type = PACKET_OTHERHOST;
+		nf_bridge->mask ^= BRNF_PKT_TYPE;
+	}
+	nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
+
+	if (dnat_took_place(skb)) {
+		if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,
+		    dev)) {
+			struct rtable *rt;
+
+			if (!ip_route_output(&rt, iph->daddr, 0, iph->tos, 0)) {
+				/* Bridged-and-DNAT'ed traffic doesn't
+				 * require ip_forwarding.
+				 */
+				if (((struct dst_entry *)rt)->dev == dev) {
+					skb->dst = (struct dst_entry *)rt;
+					goto bridged_dnat;
+				}
+				__br_dnat_complain();
+				dst_release((struct dst_entry *)rt);
+			}
+			kfree_skb(skb);
+			return 0;
+		} else {
+			if (skb->dst->dev == dev) {
+bridged_dnat:
+				/* Tell br_nf_local_out this is a
+				 * bridged frame
+				 */
+				nf_bridge->mask |= BRNF_BRIDGED_DNAT;
+				skb->dev = nf_bridge->physindev;
+				clear_cb(skb);
+				if (skb->protocol ==
+				    __constant_htons(ETH_P_8021Q)) {
+					skb_push(skb, VLAN_HLEN);
+					skb->nh.raw -= VLAN_HLEN;
+				}
+				NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING,
+					       skb, skb->dev, NULL,
+					       br_nf_pre_routing_finish_bridge,
+					       1);
+				return 0;
+			}
+			memcpy(skb->mac.ethernet->h_dest, dev->dev_addr,
+			       ETH_ALEN);
+			skb->pkt_type = PACKET_HOST;
+		}
+	} else {
+		skb->dst = (struct dst_entry *)&__fake_rtable;
+		dst_hold(skb->dst);
+	}
+
+	clear_cb(skb);
+	skb->dev = nf_bridge->physindev;
+	if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+		skb_push(skb, VLAN_HLEN);
+		skb->nh.raw -= VLAN_HLEN;
+	}
+	NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
+		       br_handle_frame_finish, 1);
+
+	return 0;
+}
+
+/* Replicate the checks that IPv4 does on packet reception.
+ * Set skb->dev to the bridge device (i.e. parent of the
+ * receiving device) to make netfilter happy, the REDIRECT
+ * target in particular.  Save the original destination IP
+ * address to be able to detect DNAT afterwards.
+ */
+static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
+   const struct net_device *in, const struct net_device *out,
+   int (*okfn)(struct sk_buff *))
+{
+	struct iphdr *iph;
+	__u32 len;
+	struct sk_buff *skb = *pskb;
+	struct nf_bridge_info *nf_bridge;
+
+	if (skb->protocol != __constant_htons(ETH_P_IP)) {
+		struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)
+					  ((*pskb)->mac.ethernet);
+
+		if (!IS_VLAN_IP)
+			return NF_ACCEPT;
+		if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL)
+			goto out;
+		skb_pull(*pskb, VLAN_HLEN);
+		(*pskb)->nh.raw += VLAN_HLEN;
+	} else if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL)
+		goto out;
+
+	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+		goto inhdr_error;
+
+	iph = skb->nh.iph;
+	if (iph->ihl < 5 || iph->version != 4)
+		goto inhdr_error;
+
+	if (!pskb_may_pull(skb, 4*iph->ihl))
+		goto inhdr_error;
+
+	iph = skb->nh.iph;
+	if (ip_fast_csum((__u8 *)iph, iph->ihl) != 0)
+		goto inhdr_error;
+
+	len = ntohs(iph->tot_len);
+	if (skb->len < len || len < 4*iph->ihl)
+		goto inhdr_error;
+
+	if (skb->len > len) {
+		__pskb_trim(skb, len);
+		if (skb->ip_summed == CHECKSUM_HW)
+			skb->ip_summed = CHECKSUM_NONE;
+	}
+
+#ifdef CONFIG_NETFILTER_DEBUG
+	skb->nf_debug ^= (1 << NF_IP_PRE_ROUTING);
+#endif
+ 	if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
+		return NF_DROP;
+
+	if (skb->pkt_type == PACKET_OTHERHOST) {
+		skb->pkt_type = PACKET_HOST;
+		nf_bridge->mask |= BRNF_PKT_TYPE;
+	}
+
+	nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING;
+	nf_bridge->physindev = skb->dev;
+	skb->dev = bridge_parent(skb->dev);
+	store_orig_dstaddr(skb);
+
+	NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL,
+		br_nf_pre_routing_finish);
+
+	return NF_STOLEN;
+
+inhdr_error:
+//	IP_INC_STATS_BH(IpInHdrErrors);
+out:
+	return NF_DROP;
+}
+
+
+/* PF_BRIDGE/LOCAL_IN ************************************************/
+/* The packet is locally destined, which requires a real
+ * dst_entry, so detach the fake one.  On the way up, the
+ * packet would pass through PRE_ROUTING again (which already
+ * took place when the packet entered the bridge), but we
+ * register an IPv4 PRE_ROUTING 'sabotage' hook that will
+ * prevent this from happening.
+ */
+static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff **pskb,
+   const struct net_device *in, const struct net_device *out,
+   int (*okfn)(struct sk_buff *))
+{
+	struct sk_buff *skb = *pskb;
+
+	if (skb->dst == (struct dst_entry *)&__fake_rtable) {
+		dst_release(skb->dst);
+		skb->dst = NULL;
+	}
+
+	return NF_ACCEPT;
+}
+
+/* PF_BRIDGE/FORWARD *************************************************/
+static int br_nf_forward_finish(struct sk_buff *skb)
+{
+	struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+	struct net_device *in;
+	struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet);
+
+#ifdef CONFIG_NETFILTER_DEBUG
+	skb->nf_debug ^= (1 << NF_BR_FORWARD);
+#endif
+
+	if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP) {
+		in = nf_bridge->physindev;
+		if (nf_bridge->mask & BRNF_PKT_TYPE) {
+			skb->pkt_type = PACKET_OTHERHOST;
+			nf_bridge->mask ^= BRNF_PKT_TYPE;
+		}
+	} else {
+		in = *((struct net_device **)(skb->cb));
+	}
+	if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+		skb_push(skb, VLAN_HLEN);
+		skb->nh.raw -= VLAN_HLEN;
+	}
+	NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in,
+			skb->dev, br_forward_finish, 1);
+	return 0;
+}
+
+/* This is the 'purely bridged' case.  For IP, we pass the packet to
+ * netfilter with indev and outdev set to the bridge device,
+ * but we are still able to filter on the 'real' indev/outdev
+ * because of the ipt_physdev.c module.
+ */
+static unsigned int br_nf_forward(unsigned int hook, struct sk_buff **pskb,
+   const struct net_device *in, const struct net_device *out,
+   int (*okfn)(struct sk_buff *))
+{
+	struct sk_buff *skb = *pskb;
+	struct nf_bridge_info *nf_bridge;
+	struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet);
+
+	if (skb->protocol != __constant_htons(ETH_P_IP)) {
+		if (!IS_VLAN_IP)
+			return NF_ACCEPT;
+		skb_pull(*pskb, VLAN_HLEN);
+		(*pskb)->nh.raw += VLAN_HLEN;
+	}
+
+#ifdef CONFIG_NETFILTER_DEBUG
+	skb->nf_debug ^= (1 << NF_BR_FORWARD);
+#endif
+	nf_bridge = skb->nf_bridge;
+	if (skb->pkt_type == PACKET_OTHERHOST) {
+		skb->pkt_type = PACKET_HOST;
+		nf_bridge->mask |= BRNF_PKT_TYPE;
+	}
+
+	/* The physdev module checks on this */
+	nf_bridge->mask |= BRNF_BRIDGED;
+	nf_bridge->physoutdev = skb->dev;
+
+	NF_HOOK(PF_INET, NF_IP_FORWARD, skb, bridge_parent(in),
+		bridge_parent(out), br_nf_forward_finish);
+
+	return NF_STOLEN;
+}
+
+
+/* PF_BRIDGE/LOCAL_OUT ***********************************************/
+static int br_nf_local_out_finish(struct sk_buff *skb)
+{
+#ifdef CONFIG_NETFILTER_DEBUG
+	skb->nf_debug &= ~(1 << NF_BR_LOCAL_OUT);
+#endif
+	if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+		skb_push(skb, VLAN_HLEN);
+		skb->nh.raw -= VLAN_HLEN;
+	}
+
+	NF_HOOK_THRESH(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
+			br_forward_finish, NF_BR_PRI_FIRST + 1);
+
+	return 0;
+}
+
+
+/* This function sees both locally originated IP packets and forwarded
+ * IP packets (in both cases the destination device is a bridge
+ * device). It also sees bridged-and-DNAT'ed packets.
+ * To be able to filter on the physical bridge devices (with the ipt_physdev.c
+ * module), we steal packets destined to a bridge device away from the
+ * PF_INET/FORWARD and PF_INET/OUTPUT hook functions, and give them back later,
+ * when we have determined the real output device. This is done in here.
+ *
+ * If (nf_bridge->mask & BRNF_BRIDGED_DNAT) then the packet is bridged
+ * and we fake the PF_BRIDGE/FORWARD hook. The function br_nf_forward()
+ * will then fake the PF_INET/FORWARD hook. br_nf_local_out() has priority
+ * NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor
+ * will be executed.
+ * Otherwise, if nf_bridge->physindev is NULL, the bridge-nf code never touched
+ * this packet before, and so the packet was locally originated. We fake
+ * the PF_INET/LOCAL_OUT hook.
+ * Finally, if nf_bridge->physindev isn't NULL, then the packet was IP routed,
+ * so we fake the PF_INET/FORWARD hook. ipv4_sabotage_out() makes sure
+ * even routed packets that didn't arrive on a bridge interface have their
+ * nf_bridge->physindev set.
+ */
+
+static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
+   const struct net_device *in, const struct net_device *out,
+   int (*_okfn)(struct sk_buff *))
+{
+	int (*okfn)(struct sk_buff *skb);
+	struct net_device *realindev;
+	struct sk_buff *skb = *pskb;
+	struct nf_bridge_info *nf_bridge;
+	struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet);
+
+	if (skb->protocol != __constant_htons(ETH_P_IP) && !IS_VLAN_IP)
+		return NF_ACCEPT;
+
+	/* Sometimes we get packets with NULL ->dst here (for example,
+	 * running a dhcp client daemon triggers this).
+	 */
+	if (skb->dst == NULL)
+		return NF_ACCEPT;
+
+	nf_bridge = skb->nf_bridge;
+	nf_bridge->physoutdev = skb->dev;
+
+	realindev = nf_bridge->physindev;
+
+	/* Bridged, take PF_BRIDGE/FORWARD.
+	 * (see big note in front of br_nf_pre_routing_finish)
+	 */
+	if (nf_bridge->mask & BRNF_BRIDGED_DNAT) {
+		okfn = br_forward_finish;
+
+		if (nf_bridge->mask & BRNF_PKT_TYPE) {
+			skb->pkt_type = PACKET_OTHERHOST;
+			nf_bridge->mask ^= BRNF_PKT_TYPE;
+		}
+		if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+			skb_push(skb, VLAN_HLEN);
+			skb->nh.raw -= VLAN_HLEN;
+		}
+
+		NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev,
+			skb->dev, okfn);
+	} else {
+		struct net_device *realoutdev = bridge_parent(skb->dev);
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+		/* iptables should match -o br0.x */
+		if (nf_bridge->netoutdev)
+			realoutdev = nf_bridge->netoutdev;
+#endif
+		okfn = br_nf_local_out_finish;
+		if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+			skb_pull(skb, VLAN_HLEN);
+			(*pskb)->nh.raw += VLAN_HLEN;
+		}
+		/* IP forwarded traffic has a physindev, locally
+		 * generated traffic hasn't.
+		 */
+		if (realindev != NULL) {
+			if (((nf_bridge->mask & BRNF_DONT_TAKE_PARENT) == 0) &&
+			    has_bridge_parent(realindev))
+				realindev = bridge_parent(realindev);
+			NF_HOOK_THRESH(PF_INET, NF_IP_FORWARD, skb, realindev,
+				       realoutdev, okfn,
+				       NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD + 1);
+		} else {
+#ifdef CONFIG_NETFILTER_DEBUG
+			skb->nf_debug ^= (1 << NF_IP_LOCAL_OUT);
+#endif
+
+			NF_HOOK_THRESH(PF_INET, NF_IP_LOCAL_OUT, skb, realindev,
+				       realoutdev, okfn,
+				       NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT + 1);
+		}
+	}
+
+	return NF_STOLEN;
+}
+
+
+/* PF_BRIDGE/POST_ROUTING ********************************************/
+static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
+   const struct net_device *in, const struct net_device *out,
+   int (*okfn)(struct sk_buff *))
+{
+	struct sk_buff *skb = *pskb;
+	struct nf_bridge_info *nf_bridge = (*pskb)->nf_bridge;
+	struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet);
+	struct net_device *realoutdev = bridge_parent(skb->dev);
+
+	/* Be very paranoid. Must be a device driver bug. */
+	if (skb->mac.raw < skb->head || skb->mac.raw + ETH_HLEN > skb->data) {
+		printk(KERN_CRIT "br_netfilter: Argh!! br_nf_post_routing: "
+				 "bad mac.raw pointer.");
+		if (skb->dev != NULL) {
+			printk("[%s]", skb->dev->name);
+			if (has_bridge_parent(skb->dev))
+				printk("[%s]", bridge_parent(skb->dev)->name);
+		}
+		printk(" head:%p, raw:%p\n", skb->head, skb->mac.raw);
+		return NF_ACCEPT;
+	}
+
+	if (skb->protocol != __constant_htons(ETH_P_IP) && !IS_VLAN_IP)
+		return NF_ACCEPT;
+
+	/* Sometimes we get packets with NULL ->dst here (for example,
+	 * running a dhcp client daemon triggers this).
+	 */
+	if (skb->dst == NULL)
+		return NF_ACCEPT;
+
+#ifdef CONFIG_NETFILTER_DEBUG
+	skb->nf_debug ^= (1 << NF_IP_POST_ROUTING);
+#endif
+
+	/* We assume any code from br_dev_queue_push_xmit onwards doesn't care
+	 * about the value of skb->pkt_type.
+	 */
+	if (skb->pkt_type == PACKET_OTHERHOST) {
+		skb->pkt_type = PACKET_HOST;
+		nf_bridge->mask |= BRNF_PKT_TYPE;
+	}
+
+	if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+		skb_pull(skb, VLAN_HLEN);
+		skb->nh.raw += VLAN_HLEN;
+	}
+
+	nf_bridge_save_header(skb);
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+	if (nf_bridge->netoutdev)
+		realoutdev = nf_bridge->netoutdev;
+#endif
+	NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL,
+		realoutdev, br_dev_queue_push_xmit);
+
+	return NF_STOLEN;
+}
+
+
+/* IPv4/SABOTAGE *****************************************************/
+
+/* Don't hand locally destined packets to PF_INET/PRE_ROUTING
+ * for the second time.
+ */
+static unsigned int ipv4_sabotage_in(unsigned int hook, struct sk_buff **pskb,
+   const struct net_device *in, const struct net_device *out,
+   int (*okfn)(struct sk_buff *))
+{
+	if ((*pskb)->nf_bridge &&
+	    !((*pskb)->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)) {
+		okfn(*pskb);
+		return NF_STOLEN;
+	}
+
+	return NF_ACCEPT;
+}
+
+/* Postpone execution of PF_INET/FORWARD, PF_INET/LOCAL_OUT
+ * and PF_INET/POST_ROUTING until we have done the forwarding
+ * decision in the bridge code and have determined skb->physoutdev.
+ */
+static unsigned int ipv4_sabotage_out(unsigned int hook, struct sk_buff **pskb,
+   const struct net_device *in, const struct net_device *out,
+   int (*okfn)(struct sk_buff *))
+{
+	if ((out->hard_start_xmit == br_dev_xmit &&
+	    okfn != br_nf_forward_finish &&
+	    okfn != br_nf_local_out_finish &&
+	    okfn != br_dev_queue_push_xmit)
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+	    || ((out->priv_flags & IFF_802_1Q_VLAN) &&
+	    VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit)
+#endif
+	    ) {
+		struct sk_buff *skb = *pskb;
+		struct nf_bridge_info *nf_bridge;
+
+		if (!skb->nf_bridge && !nf_bridge_alloc(skb))
+			return NF_DROP;
+
+		nf_bridge = skb->nf_bridge;
+
+		/* This frame will arrive on PF_BRIDGE/LOCAL_OUT and we
+		 * will need the indev then. For a brouter, the real indev
+		 * can be a bridge port, so we make sure br_nf_local_out()
+		 * doesn't use the bridge parent of the indev by using
+		 * the BRNF_DONT_TAKE_PARENT mask.
+		 */
+		if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) {
+			nf_bridge->mask &= BRNF_DONT_TAKE_PARENT;
+			nf_bridge->physindev = (struct net_device *)in;
+		}
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+		/* the iptables outdev is br0.x, not br0 */
+		if (out->priv_flags & IFF_802_1Q_VLAN)
+			nf_bridge->netoutdev = (struct net_device *)out;
+#endif
+		okfn(skb);
+		return NF_STOLEN;
+	}
+
+	return NF_ACCEPT;
+}
+
+/* For br_nf_local_out we need (prio = NF_BR_PRI_FIRST), to insure that innocent
+ * PF_BRIDGE/NF_BR_LOCAL_OUT functions don't get bridged traffic as input.
+ * For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because
+ * ip_refrag() can return NF_STOLEN.
+ */
+static struct nf_hook_ops br_nf_ops[] = {
+	{ .hook = br_nf_pre_routing, 
+	  .pf = PF_BRIDGE, 
+	  .hooknum = NF_BR_PRE_ROUTING, 
+	  .priority = NF_BR_PRI_BRNF, },
+	{ .hook = br_nf_local_in,
+	  .pf = PF_BRIDGE,
+	  .hooknum = NF_BR_LOCAL_IN,
+	  .priority = NF_BR_PRI_BRNF, },
+	{ .hook = br_nf_forward,
+	  .pf = PF_BRIDGE,
+	  .hooknum = NF_BR_FORWARD,
+	  .priority = NF_BR_PRI_BRNF, },
+	{ .hook = br_nf_local_out,
+	  .pf = PF_BRIDGE,
+	  .hooknum = NF_BR_LOCAL_OUT,
+	  .priority = NF_BR_PRI_FIRST, },
+	{ .hook = br_nf_post_routing,
+	  .pf = PF_BRIDGE,
+	  .hooknum = NF_BR_POST_ROUTING,
+	  .priority = NF_BR_PRI_LAST, },
+	{ .hook = ipv4_sabotage_in,
+	  .pf = PF_INET,
+	  .hooknum = NF_IP_PRE_ROUTING,
+	  .priority = NF_IP_PRI_FIRST, },
+	{ .hook = ipv4_sabotage_out,
+	  .pf = PF_INET,
+	  .hooknum = NF_IP_FORWARD,
+	  .priority = NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD, },
+	{ .hook = ipv4_sabotage_out,
+	  .pf = PF_INET,
+	  .hooknum = NF_IP_LOCAL_OUT,
+	  .priority = NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT, },
+	{ .hook = ipv4_sabotage_out,
+	  .pf = PF_INET,
+	  .hooknum = NF_IP_POST_ROUTING,
+	  .priority = NF_IP_PRI_FIRST, },
+};
+
+int br_netfilter_init(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(br_nf_ops); i++) {
+		int ret;
+
+		if ((ret = nf_register_hook(&br_nf_ops[i])) >= 0)
+			continue;
+
+		while (i--)
+			nf_unregister_hook(&br_nf_ops[i]);
+
+		return ret;
+	}
+
+	printk(KERN_NOTICE "Bridge firewalling registered\n");
+
+	return 0;
+}
+
+void br_netfilter_fini(void)
+{
+	int i;
+
+	for (i = ARRAY_SIZE(br_nf_ops) - 1; i >= 0; i--)
+		nf_unregister_hook(&br_nf_ops[i]);
+}
diff -urN linux-2.4.29/net/bridge/br_private.h linux-2.4.29-uc1/net/bridge/br_private.h
--- linux-2.4.29/net/bridge/br_private.h	2004-08-08 00:26:06.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/br_private.h	2005-06-14 02:11:49.000000000 +0100
@@ -143,8 +143,10 @@
 /* br_forward.c */
 extern void br_deliver(struct net_bridge_port *to,
 		struct sk_buff *skb);
+extern int br_dev_queue_push_xmit(struct sk_buff *skb);
 extern void br_forward(struct net_bridge_port *to,
 		struct sk_buff *skb);
+extern int br_forward_finish(struct sk_buff *skb);
 extern void br_flood_deliver(struct net_bridge *br,
 		      struct sk_buff *skb,
 		      int clone);
@@ -160,12 +162,13 @@
 extern int br_del_if(struct net_bridge *br,
 	      struct net_device *dev);
 extern int br_get_bridge_ifindices(int *indices,
-			    int num);
+			    int num, int user_buf);
 extern void br_get_port_ifindices(struct net_bridge *br,
 			   int *ifindices);
 
 /* br_input.c */
-extern void br_handle_frame(struct sk_buff *skb);
+extern int br_handle_frame_finish(struct sk_buff *skb);
+extern int br_handle_frame(struct sk_buff *skb);
 
 /* br_ioctl.c */
 extern int br_ioctl(struct net_bridge *br,
@@ -175,6 +178,10 @@
 	     unsigned long arg2);
 extern int br_ioctl_deviceless_stub(unsigned long arg);
 
+/* br_netfilter.c */
+extern int br_netfilter_init(void);
+extern void br_netfilter_fini(void);
+
 /* br_stp.c */
 extern int br_is_root_bridge(struct net_bridge *br);
 extern struct net_bridge_port *br_get_port(struct net_bridge *br,
diff -urN linux-2.4.29/net/bridge/br_stp_bpdu.c linux-2.4.29-uc1/net/bridge/br_stp_bpdu.c
--- linux-2.4.29/net/bridge/br_stp_bpdu.c	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/net/bridge/br_stp_bpdu.c	2005-06-14 02:11:49.000000000 +0100
@@ -134,25 +134,26 @@
 
 static unsigned char header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00};
 
-/* called under bridge lock */
-int br_stp_handle_bpdu(struct sk_buff *skb)
+
+/* Must be called under bridge lock */
+void
+br_stp_do_bpdu(struct sk_buff *skb)
 {
 	unsigned char *buf;
 	struct net_bridge_port *p;
 
 	p = skb->dev->br_port;
 
-	if (!p->br->stp_enabled ||
-	    !pskb_may_pull(skb, sizeof(header)+1) ||
-	    memcmp(skb->data, header, sizeof(header)))
-		goto err;
+	buf = skb->data;
+
+	if (!p->br->stp_enabled || !buf)
+		return;
 
-	buf = skb_pull(skb, sizeof(header));
 	if (buf[0] == BPDU_TYPE_CONFIG) {
 		struct br_config_bpdu bpdu;
 
 		if (!pskb_may_pull(skb, 32))
-			goto err;
+			return;
 
 		buf = skb->data;
 		bpdu.topology_change = (buf[1] & 0x01) ? 1 : 0;
@@ -192,6 +193,42 @@
 	else if (buf[0] == BPDU_TYPE_TCN) {
 		br_received_tcn_bpdu(p);
 	}
+}
+
+/* 
+ Any header should already be pulled off and the data must be pointing
+ to the start of the actual bpdu.
+ We start by ripping off the GRE protocol id and the version.
+*/
+void
+br_stp_do_bpdu_lock(struct sk_buff *skb)
+{
+	struct net_bridge_port *p;
+	struct net_bridge *br;
+
+	p = skb->dev->br_port;
+
+	if (!p || !(br = p->br) ||
+		!pskb_may_pull(skb, 4) || !skb_pull(skb, 4)) {
+		return;
+	}
+	read_lock(&br->lock);
+
+	br_stp_do_bpdu(skb);
+
+	read_unlock(&br->lock);
+}
+
+/* called under bridge lock */
+int br_stp_handle_bpdu(struct sk_buff *skb)
+{
+	if (!pskb_may_pull(skb, sizeof(header)+1) ||
+	    memcmp(skb->data, header, sizeof(header)))
+		goto err;
+
+	skb_pull(skb, sizeof(header));
+
+	br_stp_do_bpdu(skb);
 
  err:
 	kfree_skb(skb);
diff -urN linux-2.4.29/net/bridge/Makefile linux-2.4.29-uc1/net/bridge/Makefile
--- linux-2.4.29/net/bridge/Makefile	2000-12-29 22:07:24.000000000 +0000
+++ linux-2.4.29-uc1/net/bridge/Makefile	2005-06-14 02:11:49.000000000 +0100
@@ -7,10 +7,17 @@
 #
 # Note 2! The CFLAGS definition is now in the main makefile...
 
+export-objs := br.o
+
 O_TARGET	:= bridge.o
 obj-y		:= br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \
 			br_ioctl.o br_notify.o br_stp.o br_stp_bpdu.o \
 			br_stp_if.o br_stp_timer.o
+
+ifeq ($(CONFIG_NETFILTER),y)
+obj-y		+= br_netfilter.o
+endif
+
 obj-m		:= $(O_TARGET)
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/net/bridge/netfilter/Config.in linux-2.4.29-uc1/net/bridge/netfilter/Config.in
--- linux-2.4.29/net/bridge/netfilter/Config.in	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/netfilter/Config.in	2005-06-14 02:11:49.000000000 +0100
@@ -0,0 +1,22 @@
+#
+# Bridge netfilter configuration
+#
+dep_tristate '  Bridge: ebtables' CONFIG_BRIDGE_NF_EBTABLES $CONFIG_BRIDGE
+dep_tristate '    ebt: filter table support' CONFIG_BRIDGE_EBT_T_FILTER $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: nat table support' CONFIG_BRIDGE_EBT_T_NAT $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: broute table support' CONFIG_BRIDGE_EBT_BROUTE $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: log support' CONFIG_BRIDGE_EBT_LOG $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: IP filter support' CONFIG_BRIDGE_EBT_IPF $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: ARP filter support' CONFIG_BRIDGE_EBT_ARPF $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: among filter support' CONFIG_BRIDGE_EBT_AMONG $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: limit filter support' CONFIG_BRIDGE_EBT_LIMIT $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: 802.1Q VLAN filter support' CONFIG_BRIDGE_EBT_VLANF $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: 802.3 filter support' CONFIG_BRIDGE_EBT_802_3 $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: packet type filter support' CONFIG_BRIDGE_EBT_PKTTYPE $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: STP filter support' CONFIG_BRIDGE_EBT_STP $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: mark filter support' CONFIG_BRIDGE_EBT_MARKF $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: arp reply target support' CONFIG_BRIDGE_EBT_ARPREPLY $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: snat target support' CONFIG_BRIDGE_EBT_SNAT $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: dnat target support' CONFIG_BRIDGE_EBT_DNAT $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: redirect target support' CONFIG_BRIDGE_EBT_REDIRECT $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: mark target support' CONFIG_BRIDGE_EBT_MARK_T $CONFIG_BRIDGE_NF_EBTABLES
diff -urN linux-2.4.29/net/bridge/netfilter/ebtable_broute.c linux-2.4.29-uc1/net/bridge/netfilter/ebtable_broute.c
--- linux-2.4.29/net/bridge/netfilter/ebtable_broute.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/netfilter/ebtable_broute.c	2005-06-14 02:11:49.000000000 +0100
@@ -0,0 +1,79 @@
+/*
+ *  ebtable_broute
+ *
+ *	Authors:
+ *	Bart De Schuymer <bart.de.schuymer@pandora.be>
+ *
+ *  April, 2002
+ *
+ *  This table lets you choose between routing and bridging for frames
+ *  entering on a bridge enslaved nic. This table is traversed before any
+ *  other ebtables table. See net/bridge/br_input.c.
+ */
+
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/module.h>
+#include <linux/if_bridge.h>
+#include <linux/brlock.h>
+
+// EBT_ACCEPT means the frame will be bridged
+// EBT_DROP means the frame will be routed
+static struct ebt_entries initial_chain =
+  {0, "BROUTING", 0, EBT_ACCEPT, 0};
+
+static struct ebt_replace initial_table =
+{
+  "broute", 1 << NF_BR_BROUTING, 0, sizeof(struct ebt_entries),
+  { [NF_BR_BROUTING]&initial_chain}, 0, NULL, (char *)&initial_chain
+};
+
+static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
+{
+	if (valid_hooks & ~(1 << NF_BR_BROUTING))
+		return -EINVAL;
+	return 0;
+}
+
+static struct ebt_table broute_table =
+{
+  {NULL, NULL}, "broute", &initial_table, 1 << NF_BR_BROUTING,
+  RW_LOCK_UNLOCKED, check, NULL
+};
+
+static int ebt_broute(struct sk_buff **pskb)
+{
+	int ret;
+
+	ret = ebt_do_table(NF_BR_BROUTING, pskb, (*pskb)->dev, NULL,
+	   &broute_table);
+	if (ret == NF_DROP)
+		return 1; // route it
+	return 0; // bridge it
+}
+
+static int __init init(void)
+{
+	int ret;
+
+	ret = ebt_register_table(&broute_table);
+	if (ret < 0)
+		return ret;
+	br_write_lock_bh(BR_NETPROTO_LOCK);
+	// see br_input.c
+	br_should_route_hook = ebt_broute;
+	br_write_unlock_bh(BR_NETPROTO_LOCK);
+	return ret;
+}
+
+static void __exit fini(void)
+{
+	br_write_lock_bh(BR_NETPROTO_LOCK);
+	br_should_route_hook = NULL;
+	br_write_unlock_bh(BR_NETPROTO_LOCK);
+	ebt_unregister_table(&broute_table);
+}
+
+module_init(init);
+module_exit(fini);
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/net/bridge/netfilter/ebtable_filter.c linux-2.4.29-uc1/net/bridge/netfilter/ebtable_filter.c
--- linux-2.4.29/net/bridge/netfilter/ebtable_filter.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/netfilter/ebtable_filter.c	2005-06-14 02:11:49.000000000 +0100
@@ -0,0 +1,90 @@
+/*
+ *  ebtable_filter
+ *
+ *	Authors:
+ *	Bart De Schuymer <bart.de.schuymer@pandora.be>
+ *
+ *  April, 2002
+ *
+ */
+
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/module.h>
+
+#define FILTER_VALID_HOOKS ((1 << NF_BR_LOCAL_IN) | (1 << NF_BR_FORWARD) | \
+   (1 << NF_BR_LOCAL_OUT))
+
+static struct ebt_entries initial_chains[] =
+{
+  {0, "INPUT", 0, EBT_ACCEPT, 0},
+  {0, "FORWARD", 0, EBT_ACCEPT, 0},
+  {0, "OUTPUT", 0, EBT_ACCEPT, 0}
+};
+
+static struct ebt_replace initial_table =
+{
+  "filter", FILTER_VALID_HOOKS, 0, 3 * sizeof(struct ebt_entries),
+  { [NF_BR_LOCAL_IN]&initial_chains[0], [NF_BR_FORWARD]&initial_chains[1],
+    [NF_BR_LOCAL_OUT]&initial_chains[2] }, 0, NULL, (char *)initial_chains
+};
+
+static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
+{
+	if (valid_hooks & ~FILTER_VALID_HOOKS)
+		return -EINVAL;
+	return 0;
+}
+
+static struct ebt_table frame_filter =
+{ 
+  {NULL, NULL}, "filter", &initial_table, FILTER_VALID_HOOKS, 
+  RW_LOCK_UNLOCKED, check, NULL
+};
+
+static unsigned int
+ebt_hook (unsigned int hook, struct sk_buff **pskb, const struct net_device *in,
+   const struct net_device *out, int (*okfn)(struct sk_buff *))
+{
+	return ebt_do_table(hook, pskb, in, out, &frame_filter);
+}
+
+static struct nf_hook_ops ebt_ops_filter[] = {
+	{ { NULL, NULL }, ebt_hook, PF_BRIDGE, NF_BR_LOCAL_IN,
+	   NF_BR_PRI_FILTER_BRIDGED},
+	{ { NULL, NULL }, ebt_hook, PF_BRIDGE, NF_BR_FORWARD,
+	   NF_BR_PRI_FILTER_BRIDGED},
+	{ { NULL, NULL }, ebt_hook, PF_BRIDGE, NF_BR_LOCAL_OUT,
+	   NF_BR_PRI_FILTER_OTHER}
+};
+
+static int __init init(void)
+{
+	int i, j, ret;
+
+	ret = ebt_register_table(&frame_filter);
+	if (ret < 0)
+		return ret;
+	for (i = 0; i < sizeof(ebt_ops_filter) / sizeof(ebt_ops_filter[0]); i++)
+		if ((ret = nf_register_hook(&ebt_ops_filter[i])) < 0)
+			goto cleanup;
+	return ret;
+cleanup:
+	for (j = 0; j < i; j++)
+		nf_unregister_hook(&ebt_ops_filter[j]);
+	ebt_unregister_table(&frame_filter);
+	return ret;
+}
+
+static void __exit fini(void)
+{
+	int i;
+
+	for (i = 0; i < sizeof(ebt_ops_filter) / sizeof(ebt_ops_filter[0]); i++)
+		nf_unregister_hook(&ebt_ops_filter[i]);
+	ebt_unregister_table(&frame_filter);
+}
+
+module_init(init);
+module_exit(fini);
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/net/bridge/netfilter/ebtable_nat.c linux-2.4.29-uc1/net/bridge/netfilter/ebtable_nat.c
--- linux-2.4.29/net/bridge/netfilter/ebtable_nat.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/netfilter/ebtable_nat.c	2005-06-14 02:11:49.000000000 +0100
@@ -0,0 +1,96 @@
+/*
+ *  ebtable_nat
+ *
+ *	Authors:
+ *	Bart De Schuymer <bart.de.schuymer@pandora.be>
+ *
+ *  April, 2002
+ *
+ */
+
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/module.h>
+#define NAT_VALID_HOOKS ((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT) | \
+   (1 << NF_BR_POST_ROUTING))
+
+static struct ebt_entries initial_chains[] =
+{
+  {0, "PREROUTING", 0, EBT_ACCEPT, 0},
+  {0, "OUTPUT", 0, EBT_ACCEPT, 0},
+  {0, "POSTROUTING", 0, EBT_ACCEPT, 0}
+};
+
+static struct ebt_replace initial_table =
+{
+  "nat", NAT_VALID_HOOKS, 0, 3 * sizeof(struct ebt_entries),
+  { [NF_BR_PRE_ROUTING]&initial_chains[0], [NF_BR_LOCAL_OUT]&initial_chains[1],
+    [NF_BR_POST_ROUTING]&initial_chains[2] }, 0, NULL, (char *)initial_chains
+};
+
+static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
+{
+	if (valid_hooks & ~NAT_VALID_HOOKS)
+		return -EINVAL;
+	return 0;
+}
+
+static struct ebt_table frame_nat =
+{
+  {NULL, NULL}, "nat", &initial_table, NAT_VALID_HOOKS,
+  RW_LOCK_UNLOCKED, check, NULL
+};
+
+static unsigned int
+ebt_nat_dst(unsigned int hook, struct sk_buff **pskb, const struct net_device *in
+   , const struct net_device *out, int (*okfn)(struct sk_buff *))
+{
+	return ebt_do_table(hook, pskb, in, out, &frame_nat);
+}
+
+static unsigned int
+ebt_nat_src(unsigned int hook, struct sk_buff **pskb, const struct net_device *in
+   , const struct net_device *out, int (*okfn)(struct sk_buff *))
+{
+	return ebt_do_table(hook, pskb, in, out, &frame_nat);
+}
+
+static struct nf_hook_ops ebt_ops_nat[] = {
+	{ { NULL, NULL }, ebt_nat_dst, PF_BRIDGE, NF_BR_LOCAL_OUT,
+	   NF_BR_PRI_NAT_DST_OTHER},
+	{ { NULL, NULL }, ebt_nat_src, PF_BRIDGE, NF_BR_POST_ROUTING,
+	   NF_BR_PRI_NAT_SRC},
+	{ { NULL, NULL }, ebt_nat_dst, PF_BRIDGE, NF_BR_PRE_ROUTING,
+	   NF_BR_PRI_NAT_DST_BRIDGED},
+};
+
+static int __init init(void)
+{
+	int i, ret, j;
+
+	ret = ebt_register_table(&frame_nat);
+	if (ret < 0)
+		return ret;
+	for (i = 0; i < sizeof(ebt_ops_nat) / sizeof(ebt_ops_nat[0]); i++)
+		if ((ret = nf_register_hook(&ebt_ops_nat[i])) < 0)
+			goto cleanup;
+	return ret;
+cleanup:
+	for (j = 0; j < i; j++)
+		nf_unregister_hook(&ebt_ops_nat[j]);
+	ebt_unregister_table(&frame_nat);
+	return ret;
+}
+
+static void __exit fini(void)
+{
+	int i;
+
+	for (i = 0; i < sizeof(ebt_ops_nat) / sizeof(ebt_ops_nat[0]); i++)
+		nf_unregister_hook(&ebt_ops_nat[i]);
+	ebt_unregister_table(&frame_nat);
+}
+
+module_init(init);
+module_exit(fini);
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/net/bridge/netfilter/ebtables.c linux-2.4.29-uc1/net/bridge/netfilter/ebtables.c
--- linux-2.4.29/net/bridge/netfilter/ebtables.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/netfilter/ebtables.c	2005-06-14 02:11:49.000000000 +0100
@@ -0,0 +1,1490 @@
+/*
+ *  ebtables
+ *
+ *  Author:
+ *  Bart De Schuymer		<bart.de.schuymer@pandora.be>
+ *
+ *  ebtables.c,v 2.0, July, 2002
+ *
+ *  This code is stongly inspired on the iptables code which is
+ *  Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+// used for print_string
+#include <linux/sched.h>
+#include <linux/tty.h>
+
+#include <linux/kmod.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+#include <linux/smp.h>
+#include <net/sock.h>
+// needed for logical [in,out]-dev filtering
+#include "../br_private.h"
+
+// list_named_find
+#define ASSERT_READ_LOCK(x)
+#define ASSERT_WRITE_LOCK(x)
+#include <linux/netfilter_ipv4/listhelp.h>
+
+#if 0 // use this for remote debugging
+// Copyright (C) 1998 by Ori Pomerantz
+// Print the string to the appropriate tty, the one
+// the current task uses
+static void print_string(char *str)
+{
+	struct tty_struct *my_tty;
+
+	/* The tty for the current task */
+	my_tty = current->tty;
+	if (my_tty != NULL) {
+		(*(my_tty->driver).write)(my_tty, 0, str, strlen(str));
+		(*(my_tty->driver).write)(my_tty, 0, "\015\012", 2);
+	}
+}
+
+#define BUGPRINT(args) print_string(args);
+#else
+#define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\
+                                         "report to author: "format, ## args)
+// #define BUGPRINT(format, args...)
+#endif
+#define MEMPRINT(format, args...) printk("kernel msg: ebtables "\
+                                         ": out of memory: "format, ## args)
+// #define MEMPRINT(format, args...)
+
+
+
+// Each cpu has its own set of counters, so there is no need for write_lock in
+// the softirq
+// For reading or updating the counters, the user context needs to
+// get a write_lock
+
+// The size of each set of counters is altered to get cache alignment
+#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
+#define COUNTER_OFFSET(n) (SMP_ALIGN(n * sizeof(struct ebt_counter)))
+#define COUNTER_BASE(c, n, cpu) ((struct ebt_counter *)(((char *)c) + \
+   COUNTER_OFFSET(n) * cpu))
+
+
+
+static DECLARE_MUTEX(ebt_mutex);
+static LIST_HEAD(ebt_tables);
+static LIST_HEAD(ebt_targets);
+static LIST_HEAD(ebt_matches);
+static LIST_HEAD(ebt_watchers);
+
+static struct ebt_target ebt_standard_target =
+{ {NULL, NULL}, EBT_STANDARD_TARGET, NULL, NULL, NULL, NULL};
+
+static inline int ebt_do_watcher (struct ebt_entry_watcher *w,
+   const struct sk_buff *skb, const struct net_device *in,
+   const struct net_device *out)
+{
+	w->u.watcher->watcher(skb, in, out, w->data,
+	   w->watcher_size);
+	// watchers don't give a verdict
+	return 0;
+}
+
+static inline int ebt_do_match (struct ebt_entry_match *m,
+   const struct sk_buff *skb, const struct net_device *in,
+   const struct net_device *out)
+{
+	return m->u.match->match(skb, in, out, m->data,
+	   m->match_size);
+}
+
+static inline int ebt_dev_check(char *entry, const struct net_device *device)
+{
+	if (*entry == '\0')
+		return 0;
+	if (!device)
+		return 1;
+	return !!strcmp(entry, device->name);
+}
+
+#define FWINV2(bool,invflg) ((bool) ^ !!(e->invflags & invflg))
+// process standard matches
+static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h,
+   const struct net_device *in, const struct net_device *out)
+{
+	int verdict, i;
+
+	if (e->bitmask & EBT_802_3) {
+		if (FWINV2(ntohs(h->h_proto) >= 1536, EBT_IPROTO))
+			return 1;
+	} else if (!(e->bitmask & EBT_NOPROTO) &&
+	   FWINV2(e->ethproto != h->h_proto, EBT_IPROTO))
+		return 1;
+
+	if (FWINV2(ebt_dev_check(e->in, in), EBT_IIN))
+		return 1;
+	if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT))
+		return 1;
+	if ((!in || !in->br_port) ? 0 : FWINV2(ebt_dev_check(
+	   e->logical_in, &in->br_port->br->dev), EBT_ILOGICALIN))
+		return 1;
+	if ((!out || !out->br_port) ? 0 : FWINV2(ebt_dev_check(
+	   e->logical_out, &out->br_port->br->dev), EBT_ILOGICALOUT))
+		return 1;
+
+	if (e->bitmask & EBT_SOURCEMAC) {
+		verdict = 0;
+		for (i = 0; i < 6; i++)
+			verdict |= (h->h_source[i] ^ e->sourcemac[i]) &
+			   e->sourcemsk[i];
+		if (FWINV2(verdict != 0, EBT_ISOURCE) )
+			return 1;
+	}
+	if (e->bitmask & EBT_DESTMAC) {
+		verdict = 0;
+		for (i = 0; i < 6; i++)
+			verdict |= (h->h_dest[i] ^ e->destmac[i]) &
+			   e->destmsk[i];
+		if (FWINV2(verdict != 0, EBT_IDEST) )
+			return 1;
+	}
+	return 0;
+}
+
+// Do some firewalling
+unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb,
+   const struct net_device *in, const struct net_device *out,
+   struct ebt_table *table)
+{
+	int i, nentries;
+	struct ebt_entry *point;
+	struct ebt_counter *counter_base, *cb_base;
+	struct ebt_entry_target *t;
+	int verdict, sp = 0;
+	struct ebt_chainstack *cs;
+	struct ebt_entries *chaininfo;
+	char *base;
+	struct ebt_table_info *private = table->private;
+
+	read_lock_bh(&table->lock);
+	cb_base = COUNTER_BASE(private->counters, private->nentries,
+	   cpu_number_map(smp_processor_id()));
+	if (private->chainstack)
+		cs = private->chainstack[cpu_number_map(smp_processor_id())];
+	else
+		cs = NULL;
+	chaininfo = private->hook_entry[hook];
+	nentries = private->hook_entry[hook]->nentries;
+	point = (struct ebt_entry *)(private->hook_entry[hook]->data);
+	counter_base = cb_base + private->hook_entry[hook]->counter_offset;
+	// base for chain jumps
+	base = private->entries;
+	i = 0;
+	while (i < nentries) {
+		if (ebt_basic_match(point, (**pskb).mac.ethernet, in, out))
+			goto letscontinue;
+
+		if (EBT_MATCH_ITERATE(point, ebt_do_match, *pskb, in, out) != 0)
+			goto letscontinue;
+
+		// increase counter
+		(*(counter_base + i)).pcnt++;
+		(*(counter_base + i)).bcnt+=(**pskb).len;
+
+		// these should only watch: not modify, nor tell us
+		// what to do with the packet
+		EBT_WATCHER_ITERATE(point, ebt_do_watcher, *pskb, in,
+		   out);
+
+		t = (struct ebt_entry_target *)
+		   (((char *)point) + point->target_offset);
+		// standard target
+		if (!t->u.target->target)
+			verdict = ((struct ebt_standard_target *)t)->verdict;
+		else
+			verdict = t->u.target->target(pskb, hook,
+			   in, out, t->data, t->target_size);
+		if (verdict == EBT_ACCEPT) {
+			read_unlock_bh(&table->lock);
+			return NF_ACCEPT;
+		}
+		if (verdict == EBT_DROP) {
+			read_unlock_bh(&table->lock);
+			return NF_DROP;
+		}
+		if (verdict == EBT_RETURN) {
+letsreturn:
+#ifdef CONFIG_NETFILTER_DEBUG
+			if (sp == 0) {
+				BUGPRINT("RETURN on base chain");
+				// act like this is EBT_CONTINUE
+				goto letscontinue;
+			}
+#endif
+			sp--;
+			// put all the local variables right
+			i = cs[sp].n;
+			chaininfo = cs[sp].chaininfo;
+			nentries = chaininfo->nentries;
+			point = cs[sp].e;
+			counter_base = cb_base +
+			   chaininfo->counter_offset;
+			continue;
+		}
+		if (verdict == EBT_CONTINUE)
+			goto letscontinue;
+#ifdef CONFIG_NETFILTER_DEBUG
+		if (verdict < 0) {
+			BUGPRINT("bogus standard verdict\n");
+			read_unlock_bh(&table->lock);
+			return NF_DROP;
+		}
+#endif
+		// jump to a udc
+		cs[sp].n = i + 1;
+		cs[sp].chaininfo = chaininfo;
+		cs[sp].e = (struct ebt_entry *)
+		   (((char *)point) + point->next_offset);
+		i = 0;
+		chaininfo = (struct ebt_entries *) (base + verdict);
+#ifdef CONFIG_NETFILTER_DEBUG
+		if (chaininfo->distinguisher) {
+			BUGPRINT("jump to non-chain\n");
+			read_unlock_bh(&table->lock);
+			return NF_DROP;
+		}
+#endif
+		nentries = chaininfo->nentries;
+		point = (struct ebt_entry *)chaininfo->data;
+		counter_base = cb_base + chaininfo->counter_offset;
+		sp++;
+		continue;
+letscontinue:
+		point = (struct ebt_entry *)
+		   (((char *)point) + point->next_offset);
+		i++;
+	}
+
+	// I actually like this :)
+	if (chaininfo->policy == EBT_RETURN)
+		goto letsreturn;
+	if (chaininfo->policy == EBT_ACCEPT) {
+		read_unlock_bh(&table->lock);
+		return NF_ACCEPT;
+	}
+	read_unlock_bh(&table->lock);
+	return NF_DROP;
+}
+
+// If it succeeds, returns element and locks mutex
+static inline void *
+find_inlist_lock_noload(struct list_head *head, const char *name, int *error,
+   struct semaphore *mutex)
+{
+	void *ret;
+
+	*error = down_interruptible(mutex);
+	if (*error != 0)
+		return NULL;
+
+	ret = list_named_find(head, name);
+	if (!ret) {
+		*error = -ENOENT;
+		up(mutex);
+	}
+	return ret;
+}
+
+#ifndef CONFIG_KMOD
+#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m))
+#else
+static void *
+find_inlist_lock(struct list_head *head, const char *name, const char *prefix,
+   int *error, struct semaphore *mutex)
+{
+	void *ret;
+
+	ret = find_inlist_lock_noload(head, name, error, mutex);
+	if (!ret) {
+		char modulename[EBT_FUNCTION_MAXNAMELEN + strlen(prefix) + 1];
+		strcpy(modulename, prefix);
+		strcat(modulename, name);
+		request_module(modulename);
+		ret = find_inlist_lock_noload(head, name, error, mutex);
+	}
+	return ret;
+}
+#endif
+
+static inline struct ebt_table *
+find_table_lock(const char *name, int *error, struct semaphore *mutex)
+{
+	return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex);
+}
+
+static inline struct ebt_match *
+find_match_lock(const char *name, int *error, struct semaphore *mutex)
+{
+	return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex);
+}
+
+static inline struct ebt_watcher *
+find_watcher_lock(const char *name, int *error, struct semaphore *mutex)
+{
+	return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex);
+}
+
+static inline struct ebt_target *
+find_target_lock(const char *name, int *error, struct semaphore *mutex)
+{
+	return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex);
+}
+
+static inline int
+ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e,
+   const char *name, unsigned int hookmask, unsigned int *cnt)
+{
+	struct ebt_match *match;
+	int ret;
+
+	if (((char *)m) + m->match_size + sizeof(struct ebt_entry_match) >
+	   ((char *)e) + e->watchers_offset)
+		return -EINVAL;
+	match = find_match_lock(m->u.name, &ret, &ebt_mutex);
+	if (!match)
+		return ret;
+	m->u.match = match;
+	if (match->me)
+		__MOD_INC_USE_COUNT(match->me);
+	up(&ebt_mutex);
+	if (match->check &&
+	   match->check(name, hookmask, e, m->data, m->match_size) != 0) {
+		BUGPRINT("match->check failed\n");
+		if (match->me)
+			__MOD_DEC_USE_COUNT(match->me);
+		return -EINVAL;
+	}
+	(*cnt)++;
+	return 0;
+}
+
+static inline int
+ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e,
+   const char *name, unsigned int hookmask, unsigned int *cnt)
+{
+	struct ebt_watcher *watcher;
+	int ret;
+
+	if (((char *)w) + w->watcher_size + sizeof(struct ebt_entry_watcher) >
+	   ((char *)e) + e->target_offset)
+		return -EINVAL;
+	watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex);
+	if (!watcher)
+		return ret;
+	w->u.watcher = watcher;
+	if (watcher->me)
+		__MOD_INC_USE_COUNT(watcher->me);
+	up(&ebt_mutex);
+	if (watcher->check &&
+	   watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) {
+		BUGPRINT("watcher->check failed\n");
+		if (watcher->me)
+			__MOD_DEC_USE_COUNT(watcher->me);
+		return -EINVAL;
+	}
+	(*cnt)++;
+	return 0;
+}
+
+// this one is very careful, as it is the first function
+// to parse the userspace data
+static inline int
+ebt_check_entry_size_and_hooks(struct ebt_entry *e,
+   struct ebt_table_info *newinfo, char *base, char *limit,
+   struct ebt_entries **hook_entries, unsigned int *n, unsigned int *cnt,
+   unsigned int *totalcnt, unsigned int *udc_cnt, unsigned int valid_hooks)
+{
+	int i;
+
+	for (i = 0; i < NF_BR_NUMHOOKS; i++) {
+		if ((valid_hooks & (1 << i)) == 0)
+			continue;
+		if ( (char *)hook_entries[i] - base ==
+		   (char *)e - newinfo->entries)
+			break;
+	}
+	// beginning of a new chain
+	// if i == NF_BR_NUMHOOKS it must be a user defined chain
+	if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) {
+		if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) != 0) {
+			// we make userspace set this right,
+			// so there is no misunderstanding
+			BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set "
+			         "in distinguisher\n");
+			return -EINVAL;
+		}
+		// this checks if the previous chain has as many entries
+		// as it said it has
+		if (*n != *cnt) {
+			BUGPRINT("nentries does not equal the nr of entries "
+		                 "in the chain\n");
+			return -EINVAL;
+		}
+		// before we look at the struct, be sure it is not too big
+		if ((char *)hook_entries[i] + sizeof(struct ebt_entries)
+		   > limit) {
+			BUGPRINT("entries_size too small\n");
+			return -EINVAL;
+		}
+		if (((struct ebt_entries *)e)->policy != EBT_DROP &&
+		   ((struct ebt_entries *)e)->policy != EBT_ACCEPT) {
+			// only RETURN from udc
+			if (i != NF_BR_NUMHOOKS ||
+			   ((struct ebt_entries *)e)->policy != EBT_RETURN) {
+				BUGPRINT("bad policy\n");
+				return -EINVAL;
+			}
+		}
+		if (i == NF_BR_NUMHOOKS) // it's a user defined chain
+			(*udc_cnt)++;
+		else
+			newinfo->hook_entry[i] = (struct ebt_entries *)e;
+		if (((struct ebt_entries *)e)->counter_offset != *totalcnt) {
+			BUGPRINT("counter_offset != totalcnt");
+			return -EINVAL;
+		}
+		*n = ((struct ebt_entries *)e)->nentries;
+		*cnt = 0;
+		return 0;
+	}
+	// a plain old entry, heh
+	if (sizeof(struct ebt_entry) > e->watchers_offset ||
+	   e->watchers_offset > e->target_offset ||
+	   e->target_offset >= e->next_offset) {
+		BUGPRINT("entry offsets not in right order\n");
+		return -EINVAL;
+	}
+	// this is not checked anywhere else
+	if (e->next_offset - e->target_offset < sizeof(struct ebt_entry_target)) {
+		BUGPRINT("target size too small\n");
+		return -EINVAL;
+	}
+
+	(*cnt)++;
+	(*totalcnt)++;
+	return 0;
+}
+
+struct ebt_cl_stack
+{
+	struct ebt_chainstack cs;
+	int from;
+	unsigned int hookmask;
+};
+
+// we need these positions to check that the jumps to a different part of the
+// entries is a jump to the beginning of a new chain.
+static inline int
+ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo,
+   struct ebt_entries **hook_entries, unsigned int *n, unsigned int valid_hooks,
+   struct ebt_cl_stack *udc)
+{
+	int i;
+
+	// we're only interested in chain starts
+	if (e->bitmask & EBT_ENTRY_OR_ENTRIES)
+		return 0;
+	for (i = 0; i < NF_BR_NUMHOOKS; i++) {
+		if ((valid_hooks & (1 << i)) == 0)
+			continue;
+		if (newinfo->hook_entry[i] == (struct ebt_entries *)e)
+			break;
+	}
+	// only care about udc
+	if (i != NF_BR_NUMHOOKS)
+		return 0;
+
+	udc[*n].cs.chaininfo = (struct ebt_entries *)e;
+	// these initialisations are depended on later in check_chainloops()
+	udc[*n].cs.n = 0;
+	udc[*n].hookmask = 0;
+
+	(*n)++;
+	return 0;
+}
+
+static inline int
+ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)
+{
+	if (i && (*i)-- == 0)
+		return 1;
+	if (m->u.match->destroy)
+		m->u.match->destroy(m->data, m->match_size);
+	if (m->u.match->me)
+		__MOD_DEC_USE_COUNT(m->u.match->me);
+
+	return 0;
+}
+
+static inline int
+ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)
+{
+	if (i && (*i)-- == 0)
+		return 1;
+	if (w->u.watcher->destroy)
+		w->u.watcher->destroy(w->data, w->watcher_size);
+	if (w->u.watcher->me)
+		__MOD_DEC_USE_COUNT(w->u.watcher->me);
+
+	return 0;
+}
+
+static inline int
+ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
+{
+	struct ebt_entry_target *t;
+
+	if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0)
+		return 0;
+	// we're done
+	if (cnt && (*cnt)-- == 0)
+		return 1;
+	EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL);
+	EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL);
+	t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
+	if (t->u.target->destroy)
+		t->u.target->destroy(t->data, t->target_size);
+	if (t->u.target->me)
+		__MOD_DEC_USE_COUNT(t->u.target->me);
+
+	return 0;
+}
+
+static inline int
+ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
+   const char *name, unsigned int *cnt, unsigned int valid_hooks,
+   struct ebt_cl_stack *cl_s, unsigned int udc_cnt)
+{
+	struct ebt_entry_target *t;
+	struct ebt_target *target;
+	unsigned int i, j, hook = 0, hookmask = 0;
+	int ret;
+
+	// Don't mess with the struct ebt_entries
+	if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0)
+		return 0;
+
+	if (e->bitmask & ~EBT_F_MASK) {
+		BUGPRINT("Unknown flag for bitmask\n");
+		return -EINVAL;
+	}
+	if (e->invflags & ~EBT_INV_MASK) {
+		BUGPRINT("Unknown flag for inv bitmask\n");
+		return -EINVAL;
+	}
+	if ( (e->bitmask & EBT_NOPROTO) && (e->bitmask & EBT_802_3) ) {
+		BUGPRINT("NOPROTO & 802_3 not allowed\n");
+		return -EINVAL;
+	}
+	// what hook do we belong to?
+	for (i = 0; i < NF_BR_NUMHOOKS; i++) {
+		if ((valid_hooks & (1 << i)) == 0)
+			continue;
+		if ((char *)newinfo->hook_entry[i] < (char *)e)
+			hook = i;
+		else
+			break;
+	}
+	// (1 << NF_BR_NUMHOOKS) tells the check functions the rule is on
+	// a base chain
+	if (i < NF_BR_NUMHOOKS)
+		hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
+	else {
+		for (i = 0; i < udc_cnt; i++)
+			if ((char *)(cl_s[i].cs.chaininfo) > (char *)e)
+				break;
+		if (i == 0)
+			hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
+		else
+			hookmask = cl_s[i - 1].hookmask;
+	}
+	i = 0;
+	ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i);
+	if (ret != 0)
+		goto cleanup_matches;
+	j = 0;
+	ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j);
+	if (ret != 0)
+		goto cleanup_watchers;
+	t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
+	target = find_target_lock(t->u.name, &ret, &ebt_mutex);
+	if (!target)
+		goto cleanup_watchers;
+	if (target->me)
+		__MOD_INC_USE_COUNT(target->me);
+	up(&ebt_mutex);
+
+	t->u.target = target;
+	if (t->u.target == &ebt_standard_target) {
+		if (e->target_offset + sizeof(struct ebt_standard_target) >
+		   e->next_offset) {
+			BUGPRINT("Standard target size too big\n");
+			ret = -EFAULT;
+			goto cleanup_watchers;
+		}
+		if (((struct ebt_standard_target *)t)->verdict <
+		   -NUM_STANDARD_TARGETS) {
+			BUGPRINT("Invalid standard target\n");
+			ret = -EFAULT;
+			goto cleanup_watchers;
+		}
+	} else if ((e->target_offset + t->target_size +
+	   sizeof(struct ebt_entry_target) > e->next_offset) ||
+	   (t->u.target->check &&
+	   t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){
+		if (t->u.target->me)
+			__MOD_DEC_USE_COUNT(t->u.target->me);
+		ret = -EFAULT;
+		goto cleanup_watchers;
+	}
+	(*cnt)++;
+	return 0;
+cleanup_watchers:
+	EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, &j);
+cleanup_matches:
+	EBT_MATCH_ITERATE(e, ebt_cleanup_match, &i);
+	return ret;
+}
+
+// checks for loops and sets the hook mask for udc
+// the hook mask for udc tells us from which base chains the udc can be
+// accessed. This mask is a parameter to the check() functions of the extensions
+static int check_chainloops(struct ebt_entries *chain,
+   struct ebt_cl_stack *cl_s, unsigned int udc_cnt, 
+   unsigned int hooknr, char *base)
+{
+	int i, chain_nr = -1, pos = 0, nentries = chain->nentries, verdict;
+	struct ebt_entry *e = (struct ebt_entry *)chain->data;
+	struct ebt_entry_target *t;
+
+	while (pos < nentries || chain_nr != -1) {
+		// end of udc, go back one 'recursion' step
+		if (pos == nentries) {
+			// put back values of the time when this chain was called
+			e = cl_s[chain_nr].cs.e;
+			if (cl_s[chain_nr].from != -1)
+				nentries =
+				cl_s[cl_s[chain_nr].from].cs.chaininfo->nentries;
+			else
+				nentries = chain->nentries;
+			pos = cl_s[chain_nr].cs.n;
+			// make sure we won't see a loop that isn't one
+			cl_s[chain_nr].cs.n = 0;
+			chain_nr = cl_s[chain_nr].from;
+			if (pos == nentries)
+				continue;
+		}
+		t = (struct ebt_entry_target *)
+		   (((char *)e) + e->target_offset);
+		if (strcmp(t->u.name, EBT_STANDARD_TARGET))
+			goto letscontinue;
+		if (e->target_offset + sizeof(struct ebt_standard_target) >
+		   e->next_offset) {
+			BUGPRINT("Standard target size too big\n");
+			return -1;
+		}
+		verdict = ((struct ebt_standard_target *)t)->verdict;
+		if (verdict >= 0) { // jump to another chain
+			struct ebt_entries *hlp2 =
+			   (struct ebt_entries *)(base + verdict);
+			for (i = 0; i < udc_cnt; i++)
+				if (hlp2 == cl_s[i].cs.chaininfo)
+					break;
+			// bad destination or loop
+			if (i == udc_cnt) {
+				BUGPRINT("bad destination\n");
+				return -1;
+			}
+			if (cl_s[i].cs.n) {
+				BUGPRINT("loop\n");
+				return -1;
+			}
+			// this can't be 0, so the above test is correct
+			cl_s[i].cs.n = pos + 1;
+			pos = 0;
+			cl_s[i].cs.e = ((void *)e + e->next_offset);
+			e = (struct ebt_entry *)(hlp2->data);
+			nentries = hlp2->nentries;
+			cl_s[i].from = chain_nr;
+			chain_nr = i;
+			// this udc is accessible from the base chain for hooknr
+			cl_s[i].hookmask |= (1 << hooknr);
+			continue;
+		}
+letscontinue:
+		e = (void *)e + e->next_offset;
+		pos++;
+	}
+	return 0;
+}
+
+// do the parsing of the table/chains/entries/matches/watchers/targets, heh
+static int translate_table(struct ebt_replace *repl,
+   struct ebt_table_info *newinfo)
+{
+	unsigned int i, j, k, udc_cnt;
+	int ret;
+	struct ebt_cl_stack *cl_s = NULL; // used in the checking for chain loops
+
+	i = 0;
+	while (i < NF_BR_NUMHOOKS && !(repl->valid_hooks & (1 << i)))
+		i++;
+	if (i == NF_BR_NUMHOOKS) {
+		BUGPRINT("No valid hooks specified\n");
+		return -EINVAL;
+	}
+	if (repl->hook_entry[i] != (struct ebt_entries *)repl->entries) {
+		BUGPRINT("Chains don't start at beginning\n");
+		return -EINVAL;
+	}
+	// make sure chains are ordered after each other in same order
+	// as their corresponding hooks
+	for (j = i + 1; j < NF_BR_NUMHOOKS; j++) {
+		if (!(repl->valid_hooks & (1 << j)))
+			continue;
+		if ( repl->hook_entry[j] <= repl->hook_entry[i] ) {
+			BUGPRINT("Hook order must be followed\n");
+			return -EINVAL;
+		}
+		i = j;
+	}
+
+	for (i = 0; i < NF_BR_NUMHOOKS; i++)
+		newinfo->hook_entry[i] = NULL;
+
+	newinfo->entries_size = repl->entries_size;
+	newinfo->nentries = repl->nentries;
+
+	// do some early checkings and initialize some things
+	i = 0; // holds the expected nr. of entries for the chain
+	j = 0; // holds the up to now counted entries for the chain
+	k = 0; // holds the total nr. of entries, should equal
+	       // newinfo->nentries afterwards
+	udc_cnt = 0; // will hold the nr. of user defined chains (udc)
+	ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
+	   ebt_check_entry_size_and_hooks, newinfo, repl->entries,
+	   repl->entries + repl->entries_size, repl->hook_entry, &i, &j, &k,
+	   &udc_cnt, repl->valid_hooks);
+
+	if (ret != 0)
+		return ret;
+
+	if (i != j) {
+		BUGPRINT("nentries does not equal the nr of entries in the "
+		         "(last) chain\n");
+		return -EINVAL;
+	}
+	if (k != newinfo->nentries) {
+		BUGPRINT("Total nentries is wrong\n");
+		return -EINVAL;
+	}
+
+	// check if all valid hooks have a chain
+	for (i = 0; i < NF_BR_NUMHOOKS; i++) {
+		if (newinfo->hook_entry[i] == NULL &&
+		   (repl->valid_hooks & (1 << i))) {
+			BUGPRINT("Valid hook without chain\n");
+			return -EINVAL;
+		}
+	}
+
+	// Get the location of the udc, put them in an array
+	// While we're at it, allocate the chainstack
+	if (udc_cnt) {
+		// this will get free'd in do_replace()/ebt_register_table()
+		// if an error occurs
+		newinfo->chainstack = (struct ebt_chainstack **)
+		   vmalloc(smp_num_cpus * sizeof(struct ebt_chainstack));
+		if (!newinfo->chainstack)
+			return -ENOMEM;
+		for (i = 0; i < smp_num_cpus; i++) {
+			newinfo->chainstack[i] =
+			   vmalloc(udc_cnt * sizeof(struct ebt_chainstack));
+			if (!newinfo->chainstack[i]) {
+				while (i)
+					vfree(newinfo->chainstack[--i]);
+				vfree(newinfo->chainstack);
+				newinfo->chainstack = NULL;
+				return -ENOMEM;
+			}
+		}
+
+		cl_s = (struct ebt_cl_stack *)
+		   vmalloc(udc_cnt * sizeof(struct ebt_cl_stack));
+		if (!cl_s)
+			return -ENOMEM;
+		i = 0; // the i'th udc
+		EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
+		   ebt_get_udc_positions, newinfo, repl->hook_entry, &i,
+		   repl->valid_hooks, cl_s);
+		// sanity check
+		if (i != udc_cnt) {
+			BUGPRINT("i != udc_cnt\n");
+			vfree(cl_s);
+			return -EFAULT;
+		}
+	}
+
+	// Check for loops
+	for (i = 0; i < NF_BR_NUMHOOKS; i++)
+		if (repl->valid_hooks & (1 << i))
+			if (check_chainloops(newinfo->hook_entry[i],
+			   cl_s, udc_cnt, i, newinfo->entries)) {
+				if (cl_s)
+					vfree(cl_s);
+				return -EINVAL;
+			}
+
+	// we now know the following (along with E=mc²):
+	// - the nr of entries in each chain is right
+	// - the size of the allocated space is right
+	// - all valid hooks have a corresponding chain
+	// - there are no loops
+	// - wrong data can still be on the level of a single entry
+	// - could be there are jumps to places that are not the
+	//   beginning of a chain. This can only occur in chains that
+	//   are not accessible from any base chains, so we don't care.
+
+	// used to know what we need to clean up if something goes wrong
+	i = 0;
+	ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
+	   ebt_check_entry, newinfo, repl->name, &i, repl->valid_hooks,
+	   cl_s, udc_cnt);
+	if (ret != 0) {
+		EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
+		   ebt_cleanup_entry, &i);
+	}
+	if (cl_s)
+		vfree(cl_s);
+	return ret;
+}
+
+// called under write_lock
+static void get_counters(struct ebt_counter *oldcounters,
+   struct ebt_counter *counters, unsigned int nentries)
+{
+	int i, cpu;
+	struct ebt_counter *counter_base;
+
+	// counters of cpu 0
+	memcpy(counters, oldcounters,
+	   sizeof(struct ebt_counter) * nentries);
+	// add other counters to those of cpu 0
+	for (cpu = 1; cpu < smp_num_cpus; cpu++) {
+		counter_base = COUNTER_BASE(oldcounters, nentries, cpu);
+		for (i = 0; i < nentries; i++) {
+			counters[i].pcnt += counter_base[i].pcnt;
+			counters[i].bcnt += counter_base[i].bcnt;
+		}
+	}
+}
+
+// replace the table
+static int do_replace(void *user, unsigned int len)
+{
+	int ret, i, countersize;
+	struct ebt_table_info *newinfo;
+	struct ebt_replace tmp;
+	struct ebt_table *t;
+	struct ebt_counter *counterstmp = NULL;
+	// used to be able to unlock earlier
+	struct ebt_table_info *table;
+
+	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
+		return -EFAULT;
+
+	if (len != sizeof(tmp) + tmp.entries_size) {
+		BUGPRINT("Wrong len argument\n");
+		return -EINVAL;
+	}
+
+	if (tmp.entries_size == 0) {
+		BUGPRINT("Entries_size never zero\n");
+		return -EINVAL;
+	}
+	countersize = COUNTER_OFFSET(tmp.nentries) * smp_num_cpus;
+	newinfo = (struct ebt_table_info *)
+	   vmalloc(sizeof(struct ebt_table_info) + countersize);
+	if (!newinfo)
+		return -ENOMEM;
+
+	if (countersize)
+		memset(newinfo->counters, 0, countersize);
+
+	newinfo->entries = (char *)vmalloc(tmp.entries_size);
+	if (!newinfo->entries) {
+		ret = -ENOMEM;
+		goto free_newinfo;
+	}
+	if (copy_from_user(
+	   newinfo->entries, tmp.entries, tmp.entries_size) != 0) {
+		BUGPRINT("Couldn't copy entries from userspace\n");
+		ret = -EFAULT;
+		goto free_entries;
+	}
+
+	// the user wants counters back
+	// the check on the size is done later, when we have the lock
+	if (tmp.num_counters) {
+		counterstmp = (struct ebt_counter *)
+		   vmalloc(tmp.num_counters * sizeof(struct ebt_counter));
+		if (!counterstmp) {
+			ret = -ENOMEM;
+			goto free_entries;
+		}
+	}
+	else
+		counterstmp = NULL;
+
+	// this can get initialized by translate_table()
+	newinfo->chainstack = NULL;
+	ret = translate_table(&tmp, newinfo);
+
+	if (ret != 0)
+		goto free_counterstmp;
+
+	t = find_table_lock(tmp.name, &ret, &ebt_mutex);
+	if (!t)
+		goto free_iterate;
+
+	// the table doesn't like it
+	if (t->check && (ret = t->check(newinfo, tmp.valid_hooks)))
+		goto free_unlock;
+
+	if (tmp.num_counters && tmp.num_counters != t->private->nentries) {
+		BUGPRINT("Wrong nr. of counters requested\n");
+		ret = -EINVAL;
+		goto free_unlock;
+	}
+
+	// we have the mutex lock, so no danger in reading this pointer
+	table = t->private;
+	// we need an atomic snapshot of the counters
+	write_lock_bh(&t->lock);
+	if (tmp.num_counters)
+		get_counters(t->private->counters, counterstmp,
+		   t->private->nentries);
+
+	t->private = newinfo;
+	write_unlock_bh(&t->lock);
+	up(&ebt_mutex);
+	// So, a user can change the chains while having messed up her counter
+	// allocation. Only reason why this is done is because this way the lock
+	// is held only once, while this doesn't bring the kernel into a
+	// dangerous state.
+	if (tmp.num_counters &&
+	   copy_to_user(tmp.counters, counterstmp,
+	   tmp.num_counters * sizeof(struct ebt_counter))) {
+		BUGPRINT("Couldn't copy counters to userspace\n");
+		ret = -EFAULT;
+	}
+	else
+		ret = 0;
+
+	// decrease module count and free resources
+	EBT_ENTRY_ITERATE(table->entries, table->entries_size,
+	   ebt_cleanup_entry, NULL);
+
+	vfree(table->entries);
+	if (table->chainstack) {
+		for (i = 0; i < smp_num_cpus; i++)
+			vfree(table->chainstack[i]);
+		vfree(table->chainstack);
+	}
+	vfree(table);
+
+	if (counterstmp)
+		vfree(counterstmp);
+	return ret;
+
+free_unlock:
+	up(&ebt_mutex);
+free_iterate:
+	EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
+	   ebt_cleanup_entry, NULL);
+free_counterstmp:
+	if (counterstmp)
+		vfree(counterstmp);
+	// can be initialized in translate_table()
+	if (newinfo->chainstack) {
+		for (i = 0; i < smp_num_cpus; i++)
+			vfree(newinfo->chainstack[i]);
+		vfree(newinfo->chainstack);
+	}
+free_entries:
+	if (newinfo->entries)
+		vfree(newinfo->entries);
+free_newinfo:
+	if (newinfo)
+		vfree(newinfo);
+	return ret;
+}
+
+int ebt_register_target(struct ebt_target *target)
+{
+	int ret;
+
+	ret = down_interruptible(&ebt_mutex);
+	if (ret != 0)
+		return ret;
+	if (!list_named_insert(&ebt_targets, target)) {
+		up(&ebt_mutex);
+		return -EEXIST;
+	}
+	up(&ebt_mutex);
+	MOD_INC_USE_COUNT;
+
+	return 0;
+}
+
+void ebt_unregister_target(struct ebt_target *target)
+{
+	down(&ebt_mutex);
+	LIST_DELETE(&ebt_targets, target);
+	up(&ebt_mutex);
+	MOD_DEC_USE_COUNT;
+}
+
+int ebt_register_match(struct ebt_match *match)
+{
+	int ret;
+
+	ret = down_interruptible(&ebt_mutex);
+	if (ret != 0)
+		return ret;
+	if (!list_named_insert(&ebt_matches, match)) {
+		up(&ebt_mutex);
+		return -EEXIST;
+	}
+	up(&ebt_mutex);
+	MOD_INC_USE_COUNT;
+
+	return 0;
+}
+
+void ebt_unregister_match(struct ebt_match *match)
+{
+	down(&ebt_mutex);
+	LIST_DELETE(&ebt_matches, match);
+	up(&ebt_mutex);
+	MOD_DEC_USE_COUNT;
+}
+
+int ebt_register_watcher(struct ebt_watcher *watcher)
+{
+	int ret;
+
+	ret = down_interruptible(&ebt_mutex);
+	if (ret != 0)
+		return ret;
+	if (!list_named_insert(&ebt_watchers, watcher)) {
+		up(&ebt_mutex);
+		return -EEXIST;
+	}
+	up(&ebt_mutex);
+	MOD_INC_USE_COUNT;
+
+	return 0;
+}
+
+void ebt_unregister_watcher(struct ebt_watcher *watcher)
+{
+	down(&ebt_mutex);
+	LIST_DELETE(&ebt_watchers, watcher);
+	up(&ebt_mutex);
+	MOD_DEC_USE_COUNT;
+}
+
+int ebt_register_table(struct ebt_table *table)
+{
+	struct ebt_table_info *newinfo;
+	int ret, i, countersize;
+
+	if (!table || !table->table ||!table->table->entries ||
+	    table->table->entries_size == 0 ||
+	    table->table->counters || table->private) {
+		BUGPRINT("Bad table data for ebt_register_table!!!\n");
+		return -EINVAL;
+	}
+
+	countersize = COUNTER_OFFSET(table->table->nentries) * smp_num_cpus;
+	newinfo = (struct ebt_table_info *)
+	   vmalloc(sizeof(struct ebt_table_info) + countersize);
+	ret = -ENOMEM;
+	if (!newinfo)
+		return -ENOMEM;
+
+	newinfo->entries = (char *)vmalloc(table->table->entries_size);
+	if (!(newinfo->entries))
+		goto free_newinfo;
+
+	memcpy(newinfo->entries, table->table->entries,
+	   table->table->entries_size);
+
+	if (countersize)
+		memset(newinfo->counters, 0, countersize);
+
+	// fill in newinfo and parse the entries
+	newinfo->chainstack = NULL;
+	ret = translate_table(table->table, newinfo);
+	if (ret != 0) {
+		BUGPRINT("Translate_table failed\n");
+		goto free_chainstack;
+	}
+
+	if (table->check && table->check(newinfo, table->valid_hooks)) {
+		BUGPRINT("The table doesn't like its own initial data, lol\n");
+		return -EINVAL;
+	}
+
+	table->private = newinfo;
+	table->lock = RW_LOCK_UNLOCKED;
+	ret = down_interruptible(&ebt_mutex);
+	if (ret != 0)
+		goto free_chainstack;
+
+	if (list_named_find(&ebt_tables, table->name)) {
+		ret = -EEXIST;
+		BUGPRINT("Table name already exists\n");
+		goto free_unlock;
+	}
+
+	list_prepend(&ebt_tables, table);
+	up(&ebt_mutex);
+	MOD_INC_USE_COUNT;
+	return 0;
+free_unlock:
+	up(&ebt_mutex);
+free_chainstack:
+	if (newinfo->chainstack) {
+		for (i = 0; i < smp_num_cpus; i++)
+			vfree(newinfo->chainstack[i]);
+		vfree(newinfo->chainstack);
+	}
+	vfree(newinfo->entries);
+free_newinfo:
+	vfree(newinfo);
+	return ret;
+}
+
+void ebt_unregister_table(struct ebt_table *table)
+{
+	int i;
+
+	if (!table) {
+		BUGPRINT("Request to unregister NULL table!!!\n");
+		return;
+	}
+	down(&ebt_mutex);
+	LIST_DELETE(&ebt_tables, table);
+	up(&ebt_mutex);
+	EBT_ENTRY_ITERATE(table->private->entries,
+	   table->private->entries_size, ebt_cleanup_entry, NULL);
+	if (table->private->entries)
+		vfree(table->private->entries);
+	if (table->private->chainstack) {
+		for (i = 0; i < smp_num_cpus; i++)
+			vfree(table->private->chainstack[i]);
+		vfree(table->private->chainstack);
+	}
+	vfree(table->private);
+	MOD_DEC_USE_COUNT;
+}
+
+// userspace just supplied us with counters
+static int update_counters(void *user, unsigned int len)
+{
+	int i, ret;
+	struct ebt_counter *tmp;
+	struct ebt_replace hlp;
+	struct ebt_table *t;
+
+	if (copy_from_user(&hlp, user, sizeof(hlp)))
+		return -EFAULT;
+
+	if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
+		return -EINVAL;
+	if (hlp.num_counters == 0)
+		return -EINVAL;
+
+	if ( !(tmp = (struct ebt_counter *)
+	   vmalloc(hlp.num_counters * sizeof(struct ebt_counter))) ){
+		MEMPRINT("Update_counters && nomemory\n");
+		return -ENOMEM;
+	}
+
+	t = find_table_lock(hlp.name, &ret, &ebt_mutex);
+	if (!t)
+		goto free_tmp;
+
+	if (hlp.num_counters != t->private->nentries) {
+		BUGPRINT("Wrong nr of counters\n");
+		ret = -EINVAL;
+		goto unlock_mutex;
+	}
+
+	if ( copy_from_user(tmp, hlp.counters,
+	   hlp.num_counters * sizeof(struct ebt_counter)) ) {
+		BUGPRINT("Updata_counters && !cfu\n");
+		ret = -EFAULT;
+		goto unlock_mutex;
+	}
+
+	// we want an atomic add of the counters
+	write_lock_bh(&t->lock);
+
+	// we add to the counters of the first cpu
+	for (i = 0; i < hlp.num_counters; i++) {
+		t->private->counters[i].pcnt += tmp[i].pcnt;
+		t->private->counters[i].bcnt += tmp[i].bcnt;
+	}
+
+	write_unlock_bh(&t->lock);
+	ret = 0;
+unlock_mutex:
+	up(&ebt_mutex);
+free_tmp:
+	vfree(tmp);
+	return ret;
+}
+
+static inline int ebt_make_matchname(struct ebt_entry_match *m,
+   char *base, char *ubase)
+{
+	char *hlp = ubase - base + (char *)m;
+	if (copy_to_user(hlp, m->u.match->name, EBT_FUNCTION_MAXNAMELEN))
+		return -EFAULT;
+	return 0;
+}
+
+static inline int ebt_make_watchername(struct ebt_entry_watcher *w,
+   char *base, char *ubase)
+{
+	char *hlp = ubase - base + (char *)w;
+	if (copy_to_user(hlp , w->u.watcher->name, EBT_FUNCTION_MAXNAMELEN))
+		return -EFAULT;
+	return 0;
+}
+
+static inline int ebt_make_names(struct ebt_entry *e, char *base, char *ubase)
+{
+	int ret;
+	char *hlp;
+	struct ebt_entry_target *t;
+
+	if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0)
+		return 0;
+
+	hlp = ubase - base + (char *)e + e->target_offset;
+	t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
+	
+	ret = EBT_MATCH_ITERATE(e, ebt_make_matchname, base, ubase);
+	if (ret != 0)
+		return ret;
+	ret = EBT_WATCHER_ITERATE(e, ebt_make_watchername, base, ubase);
+	if (ret != 0)
+		return ret;
+	if (copy_to_user(hlp, t->u.target->name, EBT_FUNCTION_MAXNAMELEN))
+		return -EFAULT;
+	return 0;
+}
+
+// called with ebt_mutex down
+static int copy_everything_to_user(struct ebt_table *t, void *user,
+   int *len, int cmd)
+{
+	struct ebt_replace tmp;
+	struct ebt_counter *counterstmp, *oldcounters;
+	unsigned int entries_size, nentries;
+	char *entries;
+
+	if (cmd == EBT_SO_GET_ENTRIES) {
+		entries_size = t->private->entries_size;
+		nentries = t->private->nentries;
+		entries = t->private->entries;
+		oldcounters = t->private->counters;
+	} else {
+		entries_size = t->table->entries_size;
+		nentries = t->table->nentries;
+		entries = t->table->entries;
+		oldcounters = t->table->counters;
+	}
+
+	if (copy_from_user(&tmp, user, sizeof(tmp))) {
+		BUGPRINT("Cfu didn't work\n");
+		return -EFAULT;
+	}
+
+	if (*len != sizeof(struct ebt_replace) + entries_size +
+	   (tmp.num_counters? nentries * sizeof(struct ebt_counter): 0)) {
+		BUGPRINT("Wrong size\n");
+		return -EINVAL;
+	}
+
+	if (tmp.nentries != nentries) {
+		BUGPRINT("Nentries wrong\n");
+		return -EINVAL;
+	}
+
+	if (tmp.entries_size != entries_size) {
+		BUGPRINT("Wrong size\n");
+		return -EINVAL;
+	}
+
+	// userspace might not need the counters
+	if (tmp.num_counters) {
+		if (tmp.num_counters != nentries) {
+			BUGPRINT("Num_counters wrong\n");
+			return -EINVAL;
+		}
+		counterstmp = (struct ebt_counter *)
+		   vmalloc(nentries * sizeof(struct ebt_counter));
+		if (!counterstmp) {
+			MEMPRINT("Couldn't copy counters, out of memory\n");
+			return -ENOMEM;
+		}
+		write_lock_bh(&t->lock);
+		get_counters(oldcounters, counterstmp, nentries);
+		write_unlock_bh(&t->lock);
+
+		if (copy_to_user(tmp.counters, counterstmp,
+		   nentries * sizeof(struct ebt_counter))) {
+			BUGPRINT("Couldn't copy counters to userspace\n");
+			vfree(counterstmp);
+			return -EFAULT;
+		}
+		vfree(counterstmp);
+	}
+
+	if (copy_to_user(tmp.entries, entries, entries_size)) {
+		BUGPRINT("Couldn't copy entries to userspace\n");
+		return -EFAULT;
+	}
+	// set the match/watcher/target names right
+	return EBT_ENTRY_ITERATE(entries, entries_size,
+	   ebt_make_names, entries, tmp.entries);
+}
+
+static int do_ebt_set_ctl(struct sock *sk,
+	int cmd, void *user, unsigned int len)
+{
+	int ret;
+
+	switch(cmd) {
+	case EBT_SO_SET_ENTRIES:
+		ret = do_replace(user, len);
+		break;
+	case EBT_SO_SET_COUNTERS:
+		ret = update_counters(user, len);
+		break;
+	default:
+		ret = -EINVAL;
+  }
+	return ret;
+}
+
+static int do_ebt_get_ctl(struct sock *sk, int cmd, void *user, int *len)
+{
+	int ret;
+	struct ebt_replace tmp;
+	struct ebt_table *t;
+
+	if (copy_from_user(&tmp, user, sizeof(tmp)))
+		return -EFAULT;
+
+	t = find_table_lock(tmp.name, &ret, &ebt_mutex);
+	if (!t)
+		return ret;
+
+	switch(cmd) {
+	case EBT_SO_GET_INFO:
+	case EBT_SO_GET_INIT_INFO:
+		if (*len != sizeof(struct ebt_replace)){
+			ret = -EINVAL;
+			up(&ebt_mutex);
+			break;
+		}
+		if (cmd == EBT_SO_GET_INFO) {
+			tmp.nentries = t->private->nentries;
+			tmp.entries_size = t->private->entries_size;
+			tmp.valid_hooks = t->valid_hooks;
+		} else {
+			tmp.nentries = t->table->nentries;
+			tmp.entries_size = t->table->entries_size;
+			tmp.valid_hooks = t->table->valid_hooks;
+		}
+		up(&ebt_mutex);
+		if (copy_to_user(user, &tmp, *len) != 0){
+			BUGPRINT("c2u Didn't work\n");
+			ret = -EFAULT;
+			break;
+		}
+		ret = 0;
+		break;
+
+	case EBT_SO_GET_ENTRIES:
+	case EBT_SO_GET_INIT_ENTRIES:
+		ret = copy_everything_to_user(t, user, len, cmd);
+		up(&ebt_mutex);
+		break;
+
+	default:
+		up(&ebt_mutex);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static struct nf_sockopt_ops ebt_sockopts =
+{ { NULL, NULL }, PF_INET, EBT_BASE_CTL, EBT_SO_SET_MAX + 1, do_ebt_set_ctl,
+    EBT_BASE_CTL, EBT_SO_GET_MAX + 1, do_ebt_get_ctl, 0, NULL
+};
+
+static int __init init(void)
+{
+	int ret;
+
+	down(&ebt_mutex);
+	list_named_insert(&ebt_targets, &ebt_standard_target);
+	up(&ebt_mutex);
+	if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0)
+		return ret;
+
+	printk(KERN_NOTICE "Ebtables v2.0 registered\n");
+	return 0;
+}
+
+static void __exit fini(void)
+{
+	nf_unregister_sockopt(&ebt_sockopts);
+	printk(KERN_NOTICE "Ebtables v2.0 unregistered\n");
+}
+
+EXPORT_SYMBOL(ebt_register_table);
+EXPORT_SYMBOL(ebt_unregister_table);
+EXPORT_SYMBOL(ebt_register_match);
+EXPORT_SYMBOL(ebt_unregister_match);
+EXPORT_SYMBOL(ebt_register_watcher);
+EXPORT_SYMBOL(ebt_unregister_watcher);
+EXPORT_SYMBOL(ebt_register_target);
+EXPORT_SYMBOL(ebt_unregister_target);
+EXPORT_SYMBOL(ebt_do_table);
+module_init(init);
+module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/net/bridge/netfilter/ebt_arp.c linux-2.4.29-uc1/net/bridge/netfilter/ebt_arp.c
--- linux-2.4.29/net/bridge/netfilter/ebt_arp.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/netfilter/ebt_arp.c	2005-06-14 02:11:49.000000000 +0100
@@ -0,0 +1,149 @@
+/*
+ *  ebt_arp
+ *
+ *	Authors:
+ *	Bart De Schuymer <bart.de.schuymer@pandora.be>
+ *	Tim Gardner <timg@tpi.com>
+ *
+ *  April, 2002
+ *
+ */
+
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_arp.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/module.h>
+
+static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in,
+   const struct net_device *out, const void *data, unsigned int datalen)
+{
+	struct ebt_arp_info *info = (struct ebt_arp_info *)data;
+
+	if (info->bitmask & EBT_ARP_OPCODE && FWINV(info->opcode !=
+	   ((*skb).nh.arph)->ar_op, EBT_ARP_OPCODE))
+		return EBT_NOMATCH;
+	if (info->bitmask & EBT_ARP_HTYPE && FWINV(info->htype !=
+	   ((*skb).nh.arph)->ar_hrd, EBT_ARP_HTYPE))
+		return EBT_NOMATCH;
+	if (info->bitmask & EBT_ARP_PTYPE && FWINV(info->ptype !=
+	   ((*skb).nh.arph)->ar_pro, EBT_ARP_PTYPE))
+		return EBT_NOMATCH;
+
+	if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP))
+	{
+		uint32_t arp_len = sizeof(struct arphdr) +
+		   (2 * (((*skb).nh.arph)->ar_hln)) +
+		   (2 * (((*skb).nh.arph)->ar_pln));
+		uint32_t dst;
+		uint32_t src;
+
+		// Make sure the packet is long enough.
+		if ((((*skb).nh.raw) + arp_len) > (*skb).tail)
+			return EBT_NOMATCH;
+		// IPv4 addresses are always 4 bytes.
+		if (((*skb).nh.arph)->ar_pln != sizeof(uint32_t))
+			return EBT_NOMATCH;
+
+		if (info->bitmask & EBT_ARP_SRC_IP) {
+			memcpy(&src, ((*skb).nh.raw) + sizeof(struct arphdr) +
+			   ((*skb).nh.arph)->ar_hln, sizeof(uint32_t));
+			if (FWINV(info->saddr != (src & info->smsk),
+			   EBT_ARP_SRC_IP))
+				return EBT_NOMATCH;
+		}
+
+		if (info->bitmask & EBT_ARP_DST_IP) {
+			memcpy(&dst, ((*skb).nh.raw)+sizeof(struct arphdr) +
+			   (2*(((*skb).nh.arph)->ar_hln)) +
+			   (((*skb).nh.arph)->ar_pln), sizeof(uint32_t));
+			if (FWINV(info->daddr != (dst & info->dmsk),
+			   EBT_ARP_DST_IP))
+				return EBT_NOMATCH;
+		}
+	}
+
+	if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC))
+	{
+		uint32_t arp_len = sizeof(struct arphdr) +
+		   (2 * (((*skb).nh.arph)->ar_hln)) +
+		   (2 * (((*skb).nh.arph)->ar_pln));
+		unsigned char dst[ETH_ALEN];
+		unsigned char src[ETH_ALEN];
+
+		// Make sure the packet is long enough.
+		if ((((*skb).nh.raw) + arp_len) > (*skb).tail)
+			return EBT_NOMATCH;
+		// MAC addresses are 6 bytes.
+		if (((*skb).nh.arph)->ar_hln != ETH_ALEN)
+			return EBT_NOMATCH;
+		if (info->bitmask & EBT_ARP_SRC_MAC) {
+			uint8_t verdict, i;
+
+			memcpy(&src, ((*skb).nh.raw) +
+					sizeof(struct arphdr),
+					ETH_ALEN);
+			verdict = 0;
+			for (i = 0; i < 6; i++)
+				verdict |= (src[i] ^ info->smaddr[i]) &
+				       info->smmsk[i];	
+			if (FWINV(verdict != 0, EBT_ARP_SRC_MAC))
+				return EBT_NOMATCH;
+		}
+
+		if (info->bitmask & EBT_ARP_DST_MAC) { 
+			uint8_t verdict, i;
+
+			memcpy(&dst, ((*skb).nh.raw) +
+					sizeof(struct arphdr) +
+			   		(((*skb).nh.arph)->ar_hln) +
+			   		(((*skb).nh.arph)->ar_pln),
+					ETH_ALEN);
+			verdict = 0;
+			for (i = 0; i < 6; i++)
+				verdict |= (dst[i] ^ info->dmaddr[i]) &
+					info->dmmsk[i];
+			if (FWINV(verdict != 0, EBT_ARP_DST_MAC))
+				return EBT_NOMATCH;
+		}
+	}
+
+	return EBT_MATCH;
+}
+
+static int ebt_arp_check(const char *tablename, unsigned int hookmask,
+   const struct ebt_entry *e, void *data, unsigned int datalen)
+{
+	struct ebt_arp_info *info = (struct ebt_arp_info *)data;
+
+	if (datalen != EBT_ALIGN(sizeof(struct ebt_arp_info)))
+		return -EINVAL;
+	if ((e->ethproto != __constant_htons(ETH_P_ARP) &&
+	   e->ethproto != __constant_htons(ETH_P_RARP)) ||
+	   e->invflags & EBT_IPROTO)
+		return -EINVAL;
+	if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK)
+		return -EINVAL;
+	return 0;
+}
+
+static struct ebt_match filter_arp =
+{
+	{NULL, NULL}, EBT_ARP_MATCH, ebt_filter_arp, ebt_arp_check, NULL,
+	THIS_MODULE
+};
+
+static int __init init(void)
+{
+	return ebt_register_match(&filter_arp);
+}
+
+static void __exit fini(void)
+{
+	ebt_unregister_match(&filter_arp);
+}
+
+module_init(init);
+module_exit(fini);
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/net/bridge/netfilter/ebt_dnat.c linux-2.4.29-uc1/net/bridge/netfilter/ebt_dnat.c
--- linux-2.4.29/net/bridge/netfilter/ebt_dnat.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/netfilter/ebt_dnat.c	2005-06-14 02:11:49.000000000 +0100
@@ -0,0 +1,65 @@
+/*
+ *  ebt_dnat
+ *
+ *	Authors:
+ *	Bart De Schuymer <bart.de.schuymer@pandora.be>
+ *
+ *  June, 2002
+ *
+ */
+
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_nat.h>
+#include <linux/module.h>
+#include <net/sock.h>
+
+static int ebt_target_dnat(struct sk_buff **pskb, unsigned int hooknr,
+   const struct net_device *in, const struct net_device *out,
+   const void *data, unsigned int datalen)
+{
+	struct ebt_nat_info *info = (struct ebt_nat_info *)data;
+
+	memcpy(((**pskb).mac.ethernet)->h_dest, info->mac,
+	   ETH_ALEN * sizeof(unsigned char));
+	return info->target;
+}
+
+static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask,
+   const struct ebt_entry *e, void *data, unsigned int datalen)
+{
+	struct ebt_nat_info *info = (struct ebt_nat_info *)data;
+
+	if (BASE_CHAIN && info->target == EBT_RETURN)
+		return -EINVAL;
+	CLEAR_BASE_CHAIN_BIT;
+	if ( (strcmp(tablename, "nat") ||
+	   (hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))) &&
+	   (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) )
+		return -EINVAL;
+	if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info)))
+		return -EINVAL;
+	if (INVALID_TARGET)
+		return -EINVAL;
+	return 0;
+}
+
+static struct ebt_target dnat =
+{
+	{NULL, NULL}, EBT_DNAT_TARGET, ebt_target_dnat, ebt_target_dnat_check,
+	NULL, THIS_MODULE
+};
+
+static int __init init(void)
+{
+	return ebt_register_target(&dnat);
+}
+
+static void __exit fini(void)
+{
+	ebt_unregister_target(&dnat);
+}
+
+module_init(init);
+module_exit(fini);
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/net/bridge/netfilter/ebt_ip.c linux-2.4.29-uc1/net/bridge/netfilter/ebt_ip.c
--- linux-2.4.29/net/bridge/netfilter/ebt_ip.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/netfilter/ebt_ip.c	2005-06-14 02:11:49.000000000 +0100
@@ -0,0 +1,121 @@
+/*
+ *  ebt_ip
+ *
+ *	Authors:
+ *	Bart De Schuymer <bart.de.schuymer@pandora.be>
+ *
+ *  April, 2002
+ *
+ *  Changes:
+ *    added ip-sport and ip-dport
+ *    Innominate Security Technologies AG <mhopf@innominate.com>
+ *    September, 2002
+ */
+
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_ip.h>
+#include <linux/ip.h>
+#include <linux/in.h>
+#include <linux/module.h>
+
+struct tcpudphdr {
+	uint16_t src;
+	uint16_t dst;
+};
+
+union h_u {
+	unsigned char *raw;
+	struct tcpudphdr *tuh;
+};
+
+static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in,
+   const struct net_device *out, const void *data,
+   unsigned int datalen)
+{
+	struct ebt_ip_info *info = (struct ebt_ip_info *)data;
+
+	if (info->bitmask & EBT_IP_TOS &&
+	   FWINV(info->tos != ((*skb).nh.iph)->tos, EBT_IP_TOS))
+		return EBT_NOMATCH;
+	if (info->bitmask & EBT_IP_PROTO) {
+		if (FWINV(info->protocol != ((*skb).nh.iph)->protocol,
+		          EBT_IP_PROTO))
+			return EBT_NOMATCH;
+		if ( info->protocol == IPPROTO_TCP ||
+		     info->protocol == IPPROTO_UDP )
+		{
+			union h_u h;
+			h.raw = skb->data + skb->nh.iph->ihl*4;
+			if (info->bitmask & EBT_IP_DPORT) {
+				uint16_t port = ntohs(h.tuh->dst);
+				if (FWINV(port < info->dport[0] ||
+				          port > info->dport[1],
+				          EBT_IP_DPORT))
+				return EBT_NOMATCH;
+			}
+			if (info->bitmask & EBT_IP_SPORT) {
+				uint16_t port = ntohs(h.tuh->src);
+				if (FWINV(port < info->sport[0] ||
+				          port > info->sport[1],
+				          EBT_IP_SPORT))
+				return EBT_NOMATCH;
+			}
+		}
+	}
+	if (info->bitmask & EBT_IP_SOURCE &&
+	   FWINV((((*skb).nh.iph)->saddr & info->smsk) !=
+	   info->saddr, EBT_IP_SOURCE))
+		return EBT_NOMATCH;
+	if ((info->bitmask & EBT_IP_DEST) &&
+	   FWINV((((*skb).nh.iph)->daddr & info->dmsk) !=
+	   info->daddr, EBT_IP_DEST))
+		return EBT_NOMATCH;
+	return EBT_MATCH;
+}
+
+static int ebt_ip_check(const char *tablename, unsigned int hookmask,
+   const struct ebt_entry *e, void *data, unsigned int datalen)
+{
+	struct ebt_ip_info *info = (struct ebt_ip_info *)data;
+
+	if (datalen != EBT_ALIGN(sizeof(struct ebt_ip_info)))
+		return -EINVAL;
+	if (e->ethproto != __constant_htons(ETH_P_IP) ||
+	   e->invflags & EBT_IPROTO)
+		return -EINVAL;
+	if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK)
+		return -EINVAL;
+	if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) {
+		if (!info->bitmask & EBT_IPROTO)
+			return -EINVAL;
+		if (info->protocol != IPPROTO_TCP &&
+		    info->protocol != IPPROTO_UDP)
+			 return -EINVAL;
+	}
+	if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1])
+		return -EINVAL;
+	if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1])
+		return -EINVAL;
+	return 0;
+}
+
+static struct ebt_match filter_ip =
+{
+	{NULL, NULL}, EBT_IP_MATCH, ebt_filter_ip, ebt_ip_check, NULL,
+	THIS_MODULE
+};
+
+static int __init init(void)
+{
+	return ebt_register_match(&filter_ip);
+}
+
+static void __exit fini(void)
+{
+	ebt_unregister_match(&filter_ip);
+}
+
+module_init(init);
+module_exit(fini);
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/net/bridge/netfilter/ebt_log.c linux-2.4.29-uc1/net/bridge/netfilter/ebt_log.c
--- linux-2.4.29/net/bridge/netfilter/ebt_log.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/netfilter/ebt_log.c	2005-06-14 02:11:49.000000000 +0100
@@ -0,0 +1,152 @@
+/*
+ *  ebt_log
+ *
+ *	Authors:
+ *	Bart De Schuymer <bart.de.schuymer@pandora.be>
+ *
+ *  April, 2002
+ *
+ */
+
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_log.h>
+#include <linux/module.h>
+#include <linux/ip.h>
+#include <linux/in.h>
+#include <linux/if_arp.h>
+#include <linux/spinlock.h>
+
+static spinlock_t ebt_log_lock = SPIN_LOCK_UNLOCKED;
+
+static int ebt_log_check(const char *tablename, unsigned int hookmask,
+   const struct ebt_entry *e, void *data, unsigned int datalen)
+{
+	struct ebt_log_info *info = (struct ebt_log_info *)data;
+
+	if (datalen != EBT_ALIGN(sizeof(struct ebt_log_info)))
+		return -EINVAL;
+	if (info->bitmask & ~EBT_LOG_MASK)
+		return -EINVAL;
+	if (info->loglevel >= 8)
+		return -EINVAL;
+	info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0';
+	return 0;
+}
+
+struct tcpudphdr
+{
+	uint16_t src;
+	uint16_t dst;
+};
+
+struct arppayload
+{
+	unsigned char mac_src[ETH_ALEN];
+	unsigned char ip_src[4];
+	unsigned char mac_dst[ETH_ALEN];
+	unsigned char ip_dst[4];
+};
+
+static void print_MAC(unsigned char *p)
+{
+	int i;
+
+	for (i = 0; i < ETH_ALEN; i++, p++)
+		printk("%02x%c", *p, i == ETH_ALEN - 1 ? ' ':':');
+}
+
+#define myNIPQUAD(a) a[0], a[1], a[2], a[3]
+static void ebt_log(const struct sk_buff *skb, const struct net_device *in,
+   const struct net_device *out, const void *data, unsigned int datalen)
+{
+	struct ebt_log_info *info = (struct ebt_log_info *)data;
+	char level_string[4] = "< >";
+	level_string[1] = '0' + info->loglevel;
+
+	spin_lock_bh(&ebt_log_lock);
+	printk(level_string);
+	printk("%s IN=%s OUT=%s ", info->prefix, in ? in->name : "",
+	   out ? out->name : "");
+
+	printk("MAC source = ");
+	print_MAC((skb->mac.ethernet)->h_source);
+	printk("MAC dest = ");
+	print_MAC((skb->mac.ethernet)->h_dest);
+
+	printk("proto = 0x%04x", ntohs(((*skb).mac.ethernet)->h_proto));
+
+	if ((info->bitmask & EBT_LOG_IP) && skb->mac.ethernet->h_proto ==
+	   htons(ETH_P_IP)){
+		struct iphdr *iph = skb->nh.iph;
+		printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,",
+		   NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
+		printk(" IP tos=0x%02X, IP proto=%d", iph->tos, iph->protocol);
+		if (iph->protocol == IPPROTO_TCP ||
+		    iph->protocol == IPPROTO_UDP) {
+			struct tcpudphdr *ports = (struct tcpudphdr *)(skb->data + iph->ihl*4);
+
+			if (skb->data + iph->ihl*4 > skb->tail) {
+				printk(" INCOMPLETE TCP/UDP header");
+				goto out;
+			}
+			printk(" SPT=%u DPT=%u", ntohs(ports->src),
+			   ntohs(ports->dst));
+		}
+		goto out;
+	}
+
+	if ((info->bitmask & EBT_LOG_ARP) &&
+	    ((skb->mac.ethernet->h_proto == __constant_htons(ETH_P_ARP)) ||
+	    (skb->mac.ethernet->h_proto == __constant_htons(ETH_P_RARP)))) {
+		struct arphdr * arph = skb->nh.arph;
+		printk(" ARP HTYPE=%d, PTYPE=0x%04x, OPCODE=%d",
+		   ntohs(arph->ar_hrd), ntohs(arph->ar_pro),
+		   ntohs(arph->ar_op));
+		/* If it's for Ethernet and the lengths are OK,
+		 * then log the ARP payload */
+		if (arph->ar_hrd == __constant_htons(1) &&
+		    arph->ar_hln == ETH_ALEN &&
+		    arph->ar_pln == sizeof(uint32_t)) {
+			struct arppayload *arpp = (struct arppayload *)(skb->data + sizeof(*arph));
+
+			if (skb->data + sizeof(*arph) > skb->tail) {
+				printk(" INCOMPLETE ARP header");
+				goto out;
+			}
+
+			printk(" ARP MAC SRC=");
+			print_MAC(arpp->mac_src);
+			printk(" ARP IP SRC=%u.%u.%u.%u",
+			       myNIPQUAD(arpp->ip_src));
+			printk(" ARP MAC DST=");
+			print_MAC(arpp->mac_dst);
+			printk(" ARP IP DST=%u.%u.%u.%u",
+			       myNIPQUAD(arpp->ip_dst));
+		}
+
+	}
+out:
+	printk("\n");
+	spin_unlock_bh(&ebt_log_lock);
+}
+
+static struct ebt_watcher log =
+{
+	{NULL, NULL}, EBT_LOG_WATCHER, ebt_log, ebt_log_check, NULL,
+	THIS_MODULE
+};
+
+static int __init init(void)
+{
+	return ebt_register_watcher(&log);
+}
+
+static void __exit fini(void)
+{
+	ebt_unregister_watcher(&log);
+}
+
+module_init(init);
+module_exit(fini);
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/net/bridge/netfilter/ebt_mark.c linux-2.4.29-uc1/net/bridge/netfilter/ebt_mark.c
--- linux-2.4.29/net/bridge/netfilter/ebt_mark.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/netfilter/ebt_mark.c	2005-06-14 02:11:49.000000000 +0100
@@ -0,0 +1,66 @@
+/*
+ *  ebt_mark
+ *
+ *	Authors:
+ *	Bart De Schuymer <bart.de.schuymer@pandora.be>
+ *
+ *  July, 2002
+ *
+ */
+
+// The mark target can be used in any chain
+// I believe adding a mangle table just for marking is total overkill
+// Marking a frame doesn't really change anything in the frame anyway
+
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_mark_t.h>
+#include <linux/module.h>
+
+static int ebt_target_mark(struct sk_buff **pskb, unsigned int hooknr,
+   const struct net_device *in, const struct net_device *out,
+   const void *data, unsigned int datalen)
+{
+	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data;
+
+	if ((*pskb)->nfmark != info->mark) {
+		(*pskb)->nfmark = info->mark;
+		(*pskb)->nfcache |= NFC_ALTERED;
+	}
+	return info->target;
+}
+
+static int ebt_target_mark_check(const char *tablename, unsigned int hookmask,
+   const struct ebt_entry *e, void *data, unsigned int datalen)
+{
+	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data;
+
+	if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info)))
+		return -EINVAL;
+	if (BASE_CHAIN && info->target == EBT_RETURN)
+		return -EINVAL;
+	CLEAR_BASE_CHAIN_BIT;
+	if (INVALID_TARGET)
+		return -EINVAL;
+	return 0;
+}
+
+static struct ebt_target mark_target =
+{
+	{NULL, NULL}, EBT_MARK_TARGET, ebt_target_mark,
+	ebt_target_mark_check, NULL, THIS_MODULE
+};
+
+static int __init init(void)
+{
+	return ebt_register_target(&mark_target);
+}
+
+static void __exit fini(void)
+{
+	ebt_unregister_target(&mark_target);
+}
+
+module_init(init);
+module_exit(fini);
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/net/bridge/netfilter/ebt_mark_m.c linux-2.4.29-uc1/net/bridge/netfilter/ebt_mark_m.c
--- linux-2.4.29/net/bridge/netfilter/ebt_mark_m.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/netfilter/ebt_mark_m.c	2005-06-14 02:11:49.000000000 +0100
@@ -0,0 +1,61 @@
+/*
+ *  ebt_mark_m
+ *
+ *	Authors:
+ *	Bart De Schuymer <bart.de.schuymer@pandora.be>
+ *
+ *  July, 2002
+ *
+ */
+
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_mark_m.h>
+#include <linux/module.h>
+
+static int ebt_filter_mark(const struct sk_buff *skb,
+   const struct net_device *in, const struct net_device *out, const void *data,
+   unsigned int datalen)
+{
+	struct ebt_mark_m_info *info = (struct ebt_mark_m_info *) data;
+
+	if (info->bitmask & EBT_MARK_OR)
+		return !(!!(skb->nfmark & info->mask) ^ info->invert);
+	return !(((skb->nfmark & info->mask) == info->mark) ^ info->invert);
+}
+
+static int ebt_mark_check(const char *tablename, unsigned int hookmask,
+   const struct ebt_entry *e, void *data, unsigned int datalen)
+{
+        struct ebt_mark_m_info *info = (struct ebt_mark_m_info *) data;
+
+	if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_m_info)))
+		return -EINVAL;
+	if (info->bitmask & ~EBT_MARK_MASK)
+		return -EINVAL;
+	if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND))
+		return -EINVAL;
+	if (!info->bitmask)
+		return -EINVAL;
+	return 0;
+}
+
+static struct ebt_match filter_mark =
+{
+	{NULL, NULL}, EBT_MARK_MATCH, ebt_filter_mark, ebt_mark_check, NULL,
+	THIS_MODULE
+};
+
+static int __init init(void)
+{
+	return ebt_register_match(&filter_mark);
+}
+
+static void __exit fini(void)
+{
+	ebt_unregister_match(&filter_mark);
+}
+
+module_init(init);
+module_exit(fini);
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/net/bridge/netfilter/ebt_redirect.c linux-2.4.29-uc1/net/bridge/netfilter/ebt_redirect.c
--- linux-2.4.29/net/bridge/netfilter/ebt_redirect.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/netfilter/ebt_redirect.c	2005-06-14 02:11:49.000000000 +0100
@@ -0,0 +1,71 @@
+/*
+ *  ebt_redirect
+ *
+ *	Authors:
+ *	Bart De Schuymer <bart.de.schuymer@pandora.be>
+ *
+ *  April, 2002
+ *
+ */
+
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_redirect.h>
+#include <linux/module.h>
+#include <net/sock.h>
+#include "../br_private.h"
+
+static int ebt_target_redirect(struct sk_buff **pskb, unsigned int hooknr,
+   const struct net_device *in, const struct net_device *out,
+   const void *data, unsigned int datalen)
+{
+	struct ebt_redirect_info *info = (struct ebt_redirect_info *)data;
+
+	if (hooknr != NF_BR_BROUTING)
+		memcpy((**pskb).mac.ethernet->h_dest,
+		   in->br_port->br->dev.dev_addr, ETH_ALEN);
+	else {
+		memcpy((**pskb).mac.ethernet->h_dest,
+		   in->dev_addr, ETH_ALEN);
+		(*pskb)->pkt_type = PACKET_HOST;
+	}
+	return info->target;
+}
+
+static int ebt_target_redirect_check(const char *tablename, unsigned int hookmask,
+   const struct ebt_entry *e, void *data, unsigned int datalen)
+{
+	struct ebt_redirect_info *info = (struct ebt_redirect_info *)data;
+
+	if (datalen != EBT_ALIGN(sizeof(struct ebt_redirect_info)))
+		return -EINVAL;
+	if (BASE_CHAIN && info->target == EBT_RETURN)
+		return -EINVAL;
+	CLEAR_BASE_CHAIN_BIT;
+	if ( (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) &&
+	     (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) )
+		return -EINVAL;
+	if (INVALID_TARGET)
+		return -EINVAL;
+	return 0;
+}
+
+static struct ebt_target redirect_target =
+{
+	{NULL, NULL}, EBT_REDIRECT_TARGET, ebt_target_redirect,
+	ebt_target_redirect_check, NULL, THIS_MODULE
+};
+
+static int __init init(void)
+{
+	return ebt_register_target(&redirect_target);
+}
+
+static void __exit fini(void)
+{
+	ebt_unregister_target(&redirect_target);
+}
+
+module_init(init);
+module_exit(fini);
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/net/bridge/netfilter/ebt_snat.c linux-2.4.29-uc1/net/bridge/netfilter/ebt_snat.c
--- linux-2.4.29/net/bridge/netfilter/ebt_snat.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/netfilter/ebt_snat.c	2005-06-14 02:11:49.000000000 +0100
@@ -0,0 +1,64 @@
+/*
+ *  ebt_snat
+ *
+ *	Authors:
+ *	Bart De Schuymer <bart.de.schuymer@pandora.be>
+ *
+ *  June, 2002
+ *
+ */
+
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_nat.h>
+#include <linux/module.h>
+
+static int ebt_target_snat(struct sk_buff **pskb, unsigned int hooknr,
+   const struct net_device *in, const struct net_device *out,
+   const void *data, unsigned int datalen)
+{
+	struct ebt_nat_info *info = (struct ebt_nat_info *) data;
+
+	memcpy(((**pskb).mac.ethernet)->h_source, info->mac,
+	   ETH_ALEN * sizeof(unsigned char));
+	return info->target;
+}
+
+static int ebt_target_snat_check(const char *tablename, unsigned int hookmask,
+   const struct ebt_entry *e, void *data, unsigned int datalen)
+{
+	struct ebt_nat_info *info = (struct ebt_nat_info *) data;
+
+	if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info)))
+		return -EINVAL;
+	if (BASE_CHAIN && info->target == EBT_RETURN)
+		return -EINVAL;
+	CLEAR_BASE_CHAIN_BIT;
+	if (strcmp(tablename, "nat"))
+		return -EINVAL;
+	if (hookmask & ~(1 << NF_BR_POST_ROUTING))
+		return -EINVAL;
+	if (INVALID_TARGET)
+		return -EINVAL;
+	return 0;
+}
+
+static struct ebt_target snat =
+{
+	{NULL, NULL}, EBT_SNAT_TARGET, ebt_target_snat, ebt_target_snat_check,
+	NULL, THIS_MODULE
+};
+
+static int __init init(void)
+{
+	return ebt_register_target(&snat);
+}
+
+static void __exit fini(void)
+{
+	ebt_unregister_target(&snat);
+}
+
+module_init(init);
+module_exit(fini);
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/net/bridge/netfilter/ebt_vlan.c linux-2.4.29-uc1/net/bridge/netfilter/ebt_vlan.c
--- linux-2.4.29/net/bridge/netfilter/ebt_vlan.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/netfilter/ebt_vlan.c	2005-06-14 02:11:49.000000000 +0100
@@ -0,0 +1,259 @@
+/*
+ * Description: EBTables 802.1Q match extension kernelspace module.
+ * Authors: Nick Fedchik <nick@fedchik.org.ua>
+ *          Bart De Schuymer <bart.de.schuymer@pandora.be>
+ *    
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * 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 <linux/if_ether.h>
+#include <linux/if_vlan.h>
+#include <linux/module.h>
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_vlan.h>
+
+static unsigned char debug;
+#define MODULE_VERSION "0.6"
+
+MODULE_PARM(debug, "0-1b");
+MODULE_PARM_DESC(debug, "debug=1 is turn on debug messages");
+MODULE_AUTHOR("Nick Fedchik <nick@fedchik.org.ua>");
+MODULE_DESCRIPTION("802.1Q match module (ebtables extension), v"
+		   MODULE_VERSION);
+MODULE_LICENSE("GPL");
+
+
+#define DEBUG_MSG(args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args)
+#define INV_FLAG(_inv_flag_) (info->invflags & _inv_flag_) ? "!" : ""
+#define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_
+#define SET_BITMASK(_BIT_MASK_) info->bitmask |= _BIT_MASK_
+#define EXIT_ON_MISMATCH(_MATCH_,_MASK_) if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return 1;
+
+/*
+ * Function description: ebt_filter_vlan() is main engine for 
+ * checking passed 802.1Q frame according to 
+ * the passed extension parameters (in the *data buffer)
+ * ebt_filter_vlan() is called after successfull check the rule params
+ * by ebt_check_vlan() function.
+ * Parameters:
+ * const struct sk_buff *skb - pointer to passed ethernet frame buffer
+ * const void *data - pointer to passed extension parameters
+ * unsigned int datalen - length of passed *data buffer
+ * const struct net_device *in  -
+ * const struct net_device *out -
+ * const struct ebt_counter *c -
+ * Returned values:
+ * 0 - ok (all rule params matched)
+ * 1 - miss (rule params not acceptable to the parsed frame)
+ */
+static int
+ebt_filter_vlan(const struct sk_buff *skb,
+		const struct net_device *in,
+		const struct net_device *out,
+		const void *data, unsigned int datalen)
+{
+	struct ebt_vlan_info *info = (struct ebt_vlan_info *) data;	/* userspace data */
+	struct vlan_ethhdr *frame = (struct vlan_ethhdr *) skb->mac.raw;	/* Passed tagged frame */
+
+	unsigned short TCI;	/* Whole TCI, given from parsed frame */
+	unsigned short id;	/* VLAN ID, given from frame TCI */
+	unsigned char prio;	/* user_priority, given from frame TCI */
+	unsigned short encap;	/* VLAN encapsulated Type/Length field, given from orig frame */
+
+	/*
+	 * Tag Control Information (TCI) consists of the following elements:
+	 * - User_priority. The user_priority field is three bits in length, 
+	 * interpreted as a binary number. 
+	 * - Canonical Format Indicator (CFI). The Canonical Format Indicator 
+	 * (CFI) is a single bit flag value. Currently ignored.
+	 * - VLAN Identifier (VID). The VID is encoded as 
+	 * an unsigned binary number. 
+	 */
+	TCI = ntohs(frame->h_vlan_TCI);
+	id = TCI & VLAN_VID_MASK;
+	prio = (TCI >> 13) & 0x7;
+	encap = frame->h_vlan_encapsulated_proto;
+
+	/*
+	 * Checking VLAN Identifier (VID)
+	 */
+	if (GET_BITMASK(EBT_VLAN_ID)) {	/* Is VLAN ID parsed? */
+		EXIT_ON_MISMATCH(id, EBT_VLAN_ID);
+	}
+	/*
+	 * Checking user_priority
+	 */
+	if (GET_BITMASK(EBT_VLAN_PRIO)) {	/* Is VLAN user_priority parsed? */
+		EXIT_ON_MISMATCH(prio, EBT_VLAN_PRIO);
+	}
+	/*
+	 * Checking Encapsulated Proto (Length/Type) field
+	 */
+	if (GET_BITMASK(EBT_VLAN_ENCAP)) {	/* Is VLAN Encap parsed? */
+		EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP);
+	}
+	/*
+	 * All possible extension parameters was parsed.
+	 * If rule never returned by missmatch, then all ok.
+	 */
+	return 0;
+}
+
+/*
+ * Function description: ebt_vlan_check() is called when userspace 
+ * delivers the table entry to the kernel, 
+ * and to check that userspace doesn't give a bad table.
+ * Parameters:
+ * const char *tablename - table name string
+ * unsigned int hooknr - hook number
+ * const struct ebt_entry *e - ebtables entry basic set
+ * const void *data - pointer to passed extension parameters
+ * unsigned int datalen - length of passed *data buffer
+ * Returned values:
+ * 0 - ok (all delivered rule params are correct)
+ * 1 - miss (rule params is out of range, invalid, incompatible, etc.)
+ */
+static int
+ebt_check_vlan(const char *tablename,
+	       unsigned int hooknr,
+	       const struct ebt_entry *e, void *data, unsigned int datalen)
+{
+	struct ebt_vlan_info *info = (struct ebt_vlan_info *) data;
+
+	/*
+	 * Parameters buffer overflow check 
+	 */
+	if (datalen != EBT_ALIGN(sizeof(struct ebt_vlan_info))) {
+		DEBUG_MSG
+		    ("passed size %d is not eq to ebt_vlan_info (%d)\n",
+		     datalen, sizeof(struct ebt_vlan_info));
+		return -EINVAL;
+	}
+
+	/*
+	 * Is it 802.1Q frame checked?
+	 */
+	if (e->ethproto != __constant_htons(ETH_P_8021Q)) {
+		DEBUG_MSG
+		    ("passed entry proto %2.4X is not 802.1Q (8100)\n",
+		     (unsigned short) ntohs(e->ethproto));
+		return -EINVAL;
+	}
+
+	/*
+	 * Check for bitmask range 
+	 * True if even one bit is out of mask
+	 */
+	if (info->bitmask & ~EBT_VLAN_MASK) {
+		DEBUG_MSG("bitmask %2X is out of mask (%2X)\n",
+			  info->bitmask, EBT_VLAN_MASK);
+		return -EINVAL;
+	}
+
+	/*
+	 * Check for inversion flags range 
+	 */
+	if (info->invflags & ~EBT_VLAN_MASK) {
+		DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n",
+			  info->invflags, EBT_VLAN_MASK);
+		return -EINVAL;
+	}
+
+	/*
+	 * Reserved VLAN ID (VID) values
+	 * -----------------------------
+	 * 0 - The null VLAN ID. 
+	 * 1 - The default Port VID (PVID)
+	 * 0x0FFF - Reserved for implementation use. 
+	 * if_vlan.h: VLAN_GROUP_ARRAY_LEN 4096.
+	 */
+	if (GET_BITMASK(EBT_VLAN_ID)) {	/* when vlan-id param was spec-ed */
+		if (!!info->id) {	/* if id!=0 => check vid range */
+			if (info->id > VLAN_GROUP_ARRAY_LEN) {
+				DEBUG_MSG
+				    ("id %d is out of range (1-4096)\n",
+				     info->id);
+				return -EINVAL;
+			}
+			/*
+			 * Note: This is valid VLAN-tagged frame point.
+			 * Any value of user_priority are acceptable, 
+			 * but should be ignored according to 802.1Q Std.
+			 * So we just drop the prio flag. 
+			 */
+			info->bitmask &= ~EBT_VLAN_PRIO;
+		}
+		/*
+		 * Else, id=0 (null VLAN ID)  => user_priority range (any?)
+		 */
+	}
+
+	if (GET_BITMASK(EBT_VLAN_PRIO)) {
+		if ((unsigned char) info->prio > 7) {
+			DEBUG_MSG
+			    ("prio %d is out of range (0-7)\n",
+			     info->prio);
+			return -EINVAL;
+		}
+	}
+	/*
+	 * Check for encapsulated proto range - it is possible to be 
+	 * any value for u_short range.
+	 * if_ether.h:  ETH_ZLEN        60   -  Min. octets in frame sans FCS
+	 */
+	if (GET_BITMASK(EBT_VLAN_ENCAP)) {
+		if ((unsigned short) ntohs(info->encap) < ETH_ZLEN) {
+			DEBUG_MSG
+			    ("encap frame length %d is less than minimal\n",
+			     ntohs(info->encap));
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static struct ebt_match filter_vlan = {
+	{NULL, NULL},
+	EBT_VLAN_MATCH,
+	ebt_filter_vlan,
+	ebt_check_vlan,
+	NULL,
+	THIS_MODULE
+};
+
+/*
+ * Module initialization function.
+ */
+static int __init init(void)
+{
+	DEBUG_MSG("ebtables 802.1Q extension module v"
+		  MODULE_VERSION "\n");
+	DEBUG_MSG("module debug=%d\n", !!debug);
+	return ebt_register_match(&filter_vlan);
+}
+
+/*
+ * Module "finalization" function
+ */
+static void __exit fini(void)
+{
+	ebt_unregister_match(&filter_vlan);
+}
+
+module_init(init);
+module_exit(fini);
+
+EXPORT_NO_SYMBOLS;
diff -urN linux-2.4.29/net/bridge/netfilter/Makefile linux-2.4.29-uc1/net/bridge/netfilter/Makefile
--- linux-2.4.29/net/bridge/netfilter/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/bridge/netfilter/Makefile	2005-06-14 02:11:49.000000000 +0100
@@ -0,0 +1,33 @@
+#
+# Makefile for the netfilter modules on top of bridging.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET	:= netfilter.o
+
+export-objs := ebtables.o
+
+obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o
+obj-$(CONFIG_BRIDGE_EBT_T_FILTER) += ebtable_filter.o
+obj-$(CONFIG_BRIDGE_EBT_T_NAT) += ebtable_nat.o
+obj-$(CONFIG_BRIDGE_EBT_BROUTE) += ebtable_broute.o
+obj-$(CONFIG_BRIDGE_EBT_802_3) += ebt_802_3.o
+obj-$(CONFIG_BRIDGE_EBT_ARPF) += ebt_arp.o
+obj-$(CONFIG_BRIDGE_EBT_AMONG) += ebt_among.o
+obj-$(CONFIG_BRIDGE_EBT_IPF) += ebt_ip.o
+obj-$(CONFIG_BRIDGE_EBT_LIMIT) += ebt_limit.o
+obj-$(CONFIG_BRIDGE_EBT_MARKF) += ebt_mark_m.o
+obj-$(CONFIG_BRIDGE_EBT_PKTTYPE) += ebt_pkttype.o
+obj-$(CONFIG_BRIDGE_EBT_STP) += ebt_stp.o
+obj-$(CONFIG_BRIDGE_EBT_VLANF) += ebt_vlan.o
+obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o
+obj-$(CONFIG_BRIDGE_EBT_ARPREPLY) += ebt_arpreply.o
+obj-$(CONFIG_BRIDGE_EBT_DNAT) += ebt_dnat.o
+obj-$(CONFIG_BRIDGE_EBT_MARK_T) += ebt_mark.o
+obj-$(CONFIG_BRIDGE_EBT_REDIRECT) += ebt_redirect.o
+obj-$(CONFIG_BRIDGE_EBT_SNAT) += ebt_snat.o
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/net/Config.in linux-2.4.29-uc1/net/Config.in
--- linux-2.4.29/net/Config.in	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/Config.in	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,4 @@
+# $USAGI: Config.in,v 1.26 2003/11/12 05:11:58 yoshfuji Exp $
 #
 # Network configuration
 #
@@ -15,6 +16,8 @@
    bool '  Network packet filtering debugging' CONFIG_NETFILTER_DEBUG
 fi
 bool 'Socket Filtering'  CONFIG_FILTER
+bool 'Address Resolution / Neighbour Discovery Debugging' CONFIG_NET_NEIGH_DEBUG
+bool 'Restrict SO_REUSEADDR only for same user' CONFIG_NET_RESTRICTED_REUSE
 tristate 'Unix domain sockets' CONFIG_UNIX
 bool 'TCP/IP networking' CONFIG_INET
 if [ "$CONFIG_INET" = "y" ]; then
@@ -41,6 +44,9 @@
 	 if [ "$CONFIG_ATM_CLIP" != "n" ]; then
 	    bool '    Do NOT send ICMP if no neighbour' CONFIG_ATM_CLIP_NO_ICMP
 	 fi
+	 if [ "$CONFIG_IPV6" != "n" ]; then
+	    bool '  IPv6 Enhance for ATM' CONFIG_ATM_IPV6
+	 fi
       fi
       dep_tristate '  LAN Emulation (LANE) support' CONFIG_ATM_LANE $CONFIG_ATM
       if [ "$CONFIG_INET" = "y" -a "$CONFIG_ATM_LANE" != "n" ]; then
@@ -70,6 +76,9 @@
    source net/decnet/Config.in
 fi
 dep_tristate '802.1d Ethernet Bridging' CONFIG_BRIDGE $CONFIG_INET
+if [ "$CONFIG_BRIDGE" != "n" -a "$CONFIG_NETFILTER" != "n" ]; then
+   source net/bridge/netfilter/Config.in
+fi
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
    tristate 'CCITT X.25 Packet Layer (EXPERIMENTAL)' CONFIG_X25
    tristate 'LAPB Data Link Driver (EXPERIMENTAL)' CONFIG_LAPB
@@ -99,6 +108,15 @@
 #bool 'Network code profiler' CONFIG_NET_PROFILE
 endmenu
 
+tristate 'IP Security Protocol (FreeS/WAN IPSEC)' CONFIG_IPSEC
+if [ "$CONFIG_IPSEC" != "n" ]; then
+  source ../freeswan/klips/net/ipsec/Config.in
+fi
+tristate 'IP Security Protocol (Openswan IPSEC)' CONFIG_KLIPS
+if [ "$CONFIG_KLIPS" != "n" ]; then
+  source ../openswan/linux/net/ipsec/Config.in
+fi
+
 mainmenu_option next_comment
 comment 'Network testing'
 dep_tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN $CONFIG_PROC_FS
diff -urN linux-2.4.29/net/core/dev.c linux-2.4.29-uc1/net/core/dev.c
--- linux-2.4.29/net/core/dev.c	2004-04-14 14:05:41.000000000 +0100
+++ linux-2.4.29-uc1/net/core/dev.c	2005-06-14 02:11:53.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: dev.c,v 1.24 2003/11/12 05:12:00 yoshfuji Exp $ */
+
 /*
  * 	NET3	Protocol independent device support routines.
  *
@@ -1426,7 +1428,7 @@
 
 
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
-void (*br_handle_frame_hook)(struct sk_buff *skb) = NULL;
+int (*br_handle_frame_hook)(struct sk_buff *skb) = NULL;
 #endif
 
 static __inline__ int handle_bridge(struct sk_buff *skb,
@@ -1443,7 +1445,6 @@
 		}
 	}
 
-	br_handle_frame_hook(skb);
 	return ret;
 }
 
@@ -1503,8 +1504,13 @@
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
 	if (skb->dev->br_port != NULL && br_handle_frame_hook != NULL &&
 	    skb->pkt_type != PACKET_LOOPBACK) {
-		return handle_bridge(skb, pt_prev);
-	}
+		int ret;
+
+		ret = handle_bridge(skb, pt_prev);
+		if (br_handle_frame_hook(skb) == 0)
+			return ret;
+		pt_prev = NULL;
+ 	}
 #endif
 
 	type = skb->protocol;
@@ -2105,7 +2111,8 @@
 			return err;
 
 		case SIOCGIFHWADDR:
-			memcpy(ifr->ifr_hwaddr.sa_data,dev->dev_addr, MAX_ADDR_LEN);
+			memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr, 
+			       min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
 			ifr->ifr_hwaddr.sa_family=dev->type;
 			return 0;
 				
@@ -2120,11 +2127,20 @@
 			if (!err)
 				notifier_call_chain(&netdev_chain, NETDEV_CHANGEADDR, dev);
 			return err;
-			
+
+#ifdef SIOCGIFHWBROADCAST
+		case SIOCGIFHWBROADCAST:
+			memcpy(ifr->ifr_hwaddr.sa_data, dev->broadcast, 
+			       min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
+			ifr->ifr_hwaddr.sa_family=dev->type;
+			return 0;
+#endif
+
 		case SIOCSIFHWBROADCAST:
 			if (ifr->ifr_hwaddr.sa_family!=dev->type)
 				return -EINVAL;
-			memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, MAX_ADDR_LEN);
+			memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, 
+			       min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
 			notifier_call_chain(&netdev_chain, NETDEV_CHANGEADDR, dev);
 			return 0;
 
diff -urN linux-2.4.29/net/core/neighbour.c linux-2.4.29-uc1/net/core/neighbour.c
--- linux-2.4.29/net/core/neighbour.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/core/neighbour.c	2005-06-14 02:11:53.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: neighbour.c,v 1.40 2005/01/19 17:22:32 yoshfuji Exp $ */
+
 /*
  *	Generic address resolution entity
  *
@@ -34,13 +36,18 @@
 #include <linux/random.h>
 #include <linux/module.h>
 
+#ifdef CONFIG_NET_NEIGH_DEBUG
+#define NEIGH_DEBUG 3
+#else
 #define NEIGH_DEBUG 1
+#endif
 
 #define NEIGH_PRINTK(x...) printk(x)
 #define NEIGH_NOPRINTK(x...) do { ; } while(0)
 #define NEIGH_PRINTK0 NEIGH_PRINTK
 #define NEIGH_PRINTK1 NEIGH_NOPRINTK
 #define NEIGH_PRINTK2 NEIGH_NOPRINTK
+#define NEIGH_PRINTK3 NEIGH_NOPRINTK
 
 #if NEIGH_DEBUG >= 1
 #undef NEIGH_PRINTK1
@@ -50,13 +57,14 @@
 #undef NEIGH_PRINTK2
 #define NEIGH_PRINTK2 NEIGH_PRINTK
 #endif
+#if NEIGH_DEBUG >= 3
+#undef NEIGH_PRINTK3
+#define NEIGH_PRINTK3 NEIGH_PRINTK
+#endif
 
 #define PNEIGH_HASHMASK		0xF
 
 static void neigh_timer_handler(unsigned long arg);
-#ifdef CONFIG_ARPD
-static void neigh_app_notify(struct neighbour *n);
-#endif
 static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
 void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev);
 
@@ -120,6 +128,7 @@
 	int shrunk = 0;
 	int i;
 
+	NEIGH_PRINTK3(KERN_DEBUG "neigh_foced_gc(tbl=%p)\n", tbl);
 	NEIGH_CACHE_STAT_INC(tbl, forced_gc_runs);
 
 	write_lock_bh(&tbl->lock);
@@ -135,6 +144,8 @@
 			write_lock(&n->lock);
 			if (atomic_read(&n->refcnt) == 1 &&
 			    !(n->nud_state&NUD_PERMANENT)) {
+				NEIGH_PRINTK3(KERN_DEBUG "neigh %p: %s (dead, neigh_forced_gc)\n", 
+						n, neigh_state(n->nud_state));
 				*np = n->next;
 				n->dead = 1;
 				shrunk = 1;
@@ -156,6 +167,7 @@
 
 static int neigh_del_timer(struct neighbour *n)
 {
+	NEIGH_PRINTK3(KERN_DEBUG "neigh_del_timer(n=%p)\n", n);
 	if (n->nud_state & NUD_IN_TIMER) {
 		if (del_timer(&n->timer)) {
 			neigh_release(n);
@@ -169,6 +181,8 @@
 {
 	struct sk_buff *skb;
 
+	NEIGH_PRINTK3(KERN_DEBUG "pneigh_queue_purge(list=%p)\n", list);
+
 	while ((skb = skb_dequeue(list)) != NULL) {
 		dev_put(skb->dev);
 		kfree_skb(skb);
@@ -206,6 +220,9 @@
 {
 	int i;
 
+	NEIGH_PRINTK3(KERN_DEBUG "neigh_ifdown(tbl=%p, dev=%p(%s))\n",
+			tbl, dev, dev?dev->name:"<null>");
+
 	write_lock_bh(&tbl->lock);
 
 	for (i = 0; i <= tbl->hash_mask; i++) {
@@ -239,7 +256,8 @@
 					n->nud_state = NUD_NOARP;
 				else
 					n->nud_state = NUD_NONE;
-				NEIGH_PRINTK2("neigh %p is stray.\n", n);
+				NEIGH_PRINTK3(KERN_DEBUG "neigh %p: ->%s (stray, neigh_ifdown).\n", 
+						n, neigh_state(n->nud_state));
 			}
 			write_unlock(&n->lock);
 			neigh_release(n);
@@ -259,17 +277,23 @@
 	struct neighbour *n;
 	unsigned long now = jiffies;
 
+	NEIGH_PRINTK3(KERN_DEBUG "neigh_alloc(tbl=%p)\n", tbl);
+
 	if (atomic_read(&tbl->entries) > tbl->gc_thresh3 ||
 	    (atomic_read(&tbl->entries) > tbl->gc_thresh2 &&
 	     now - tbl->last_flush > 5*HZ)) {
 		if (neigh_forced_gc(tbl) == 0 &&
-		    atomic_read(&tbl->entries) > tbl->gc_thresh3)
+		    atomic_read(&tbl->entries) > tbl->gc_thresh3) {
+			NEIGH_PRINTK1(KERN_WARNING "neigh_alloc(): neighbour table flood for neigh_table %p\n", tbl);
 			return NULL;
+		}
 	}
 
 	n = kmem_cache_alloc(tbl->kmem_cachep, SLAB_ATOMIC);
-	if (n == NULL)
+	if (n == NULL) {
+		NEIGH_PRINTK1(KERN_WARNING "neigh_alloc(): kmem_cache_alloc() failed for neigh_table %p\n", tbl);
 		return NULL;
+	}
 
 	memset(n, 0, tbl->entry_size);
 
@@ -288,6 +312,7 @@
 	n->tbl = tbl;
 	atomic_set(&n->refcnt, 1);
 	n->dead = 1;
+	NEIGH_PRINTK3(KERN_DEBUG "neigh %p: NUD_NONE (neigh_alloc).\n", n);
 	return n;
 }
 
@@ -404,6 +429,9 @@
 	int key_len = tbl->key_len;
 	int error;
 
+	NEIGH_PRINTK3("neigh_create(tbl=%p, pkey=%p, dev=%p(%s))\n",
+			tbl, pkey, dev, dev?dev->name:"<null>");
+
 	n = neigh_alloc(tbl);
 	if (n == NULL)
 		return ERR_PTR(-ENOBUFS);
@@ -447,8 +475,8 @@
 	tbl->hash_buckets[hash_val] = n;
 	n->dead = 0;
 	neigh_hold(n);
+	NEIGH_PRINTK3(KERN_DEBUG "neigh %p: %s (neigh_create).\n", n, neigh_state(n->nud_state));
 	write_unlock_bh(&tbl->lock);
-	NEIGH_PRINTK2("neigh %p is created.\n", n);
 	return n;
 }
 
@@ -478,10 +506,21 @@
 	if (!creat)
 		return NULL;
 
-	n = kmalloc(sizeof(*n) + key_len, GFP_KERNEL);
+#ifdef USE_IPV6_MOBILITY
+	n = kmalloc(sizeof(*n) + key_len, pneigh_alloc_flag());
+#else
+	n = kmalloc(sizeof(*n) + key_len, 
+		    (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL));
+#endif 
+
+
 	if (n == NULL)
 		return NULL;
 
+#ifdef USE_IPV6_MOBILITY
+	pneigh_refcnt_init(n);
+#endif
+
 	memcpy(n->key, pkey, key_len);
 	n->dev = dev;
 
@@ -504,6 +543,9 @@
 	u32 hash_val;
 	int key_len = tbl->key_len;
 
+	NEIGH_PRINTK3(KERN_DEBUG "pneigh_delete(tbl=%p, pkey=%p, dev=%p(%s))\n",
+			tbl, pkey, dev, dev?dev->name:"<null>");
+
 	hash_val = *(u32*)(pkey + key_len - 4);
 	hash_val ^= (hash_val>>16);
 	hash_val ^= hash_val>>8;
@@ -513,6 +555,12 @@
 	write_lock_bh(&tbl->lock);
 	for (np = &tbl->phash_buckets[hash_val]; (n=*np) != NULL; np = &n->next) {
 		if (memcmp(n->key, pkey, key_len) == 0 && n->dev == dev) {
+#ifdef USE_IPV6_MOBILITY
+			if (!pneigh_refcnt_dec_and_test(n)) {
+				write_unlock_bh(&tbl->lock);
+				return 0;
+			}
+#endif
 			*np = n->next;
 			write_unlock_bh(&tbl->lock);
 			if (tbl->pdestructor)
@@ -530,6 +578,9 @@
 	struct pneigh_entry *n, **np;
 	u32 h;
 
+	NEIGH_PRINTK3(KERN_DEBUG "pneigh_ifdown(tbl=%p, dev=%p(%s))\n",
+			tbl, dev, dev?dev->name:"<null>");
+
 	for (h=0; h<=PNEIGH_HASHMASK; h++) {
 		np = &tbl->phash_buckets[h]; 
 		while ((n=*np) != NULL) {
@@ -555,16 +606,19 @@
 {	
 	struct hh_cache *hh;
 
+	NEIGH_PRINTK3(KERN_DEBUG "neigh_destroy(neigh=%p)\n", neigh);
 	NEIGH_CACHE_STAT_INC(neigh->tbl, destroys);
 
 	if (!neigh->dead) {
-		printk("Destroying alive neighbour %p\n", neigh);
+		NEIGH_PRINTK1(KERN_WARNING
+			"neigh_destroy(): destroying alive neighbour %p\n",
+			neigh);
 		dump_stack();
 		return;
 	}
 
 	if (neigh_del_timer(neigh))
-		printk("Impossible event.\n");
+		NEIGH_PRINTK1(KERN_WARNING "neigh_destroy: impossible event; timer was alive.\n");
 
 	while ((hh = neigh->hh) != NULL) {
 		neigh->hh = hh->hh_next;
@@ -583,7 +637,7 @@
 
 	dev_put(neigh->dev);
 
-	NEIGH_PRINTK2("neigh %p is destroyed.\n", neigh);
+	NEIGH_PRINTK3(KERN_DEBUG "neigh %p: (destroyed)\n", neigh);
 
 	neigh_glbl_allocs--;
 	atomic_dec(&neigh->tbl->entries);
@@ -599,7 +653,7 @@
 {
 	struct hh_cache *hh;
 
-	NEIGH_PRINTK2("neigh %p is suspected.\n", neigh);
+	NEIGH_PRINTK3(KERN_DEBUG "neigh_suspect(neigh=%p)\n", neigh);
 
 	neigh->output = neigh->ops->output;
 
@@ -616,7 +670,7 @@
 {
 	struct hh_cache *hh;
 
-	NEIGH_PRINTK2("neigh %p is connected.\n", neigh);
+	NEIGH_PRINTK3(KERN_DEBUG "neigh_connect(neigh=%p)\n", neigh);
 
 	neigh->output = neigh->ops->connected_output;
 
@@ -624,49 +678,20 @@
 		hh->hh_output = neigh->ops->hh_output;
 }
 
-/*
-   Transitions NUD_STALE <-> NUD_REACHABLE do not occur
-   when fast path is built: we have no timers associated with
-   these states, we do not have time to check state when sending.
-   neigh_periodic_timer check periodically neigh->confirmed
-   time and moves NUD_REACHABLE -> NUD_STALE.
-
-   If a routine wants to know TRUE entry state, it calls
-   neigh_sync before checking state.
-
-   Called with write_locked neigh.
- */
-
-static void neigh_sync(struct neighbour *n)
-{
-	unsigned long now = jiffies;
-	u8 state = n->nud_state;
-
-	if (state&(NUD_NOARP|NUD_PERMANENT))
-		return;
-	if (state&NUD_REACHABLE) {
-		if (now - n->confirmed > n->parms->reachable_time) {
-			n->nud_state = NUD_STALE;
-			neigh_suspect(n);
-		}
-	} else if (state&NUD_VALID) {
-		if (now - n->confirmed < n->parms->reachable_time) {
-			neigh_del_timer(n);
-			n->nud_state = NUD_REACHABLE;
-			neigh_connect(n);
-		}
-	}
-}
-
 static void SMP_TIMER_NAME(neigh_periodic_timer)(unsigned long arg)
 {
 	struct neigh_table *tbl = (struct neigh_table*)arg;
 	struct neighbour *n, **np;
 	unsigned long expire, now = jiffies;
 
+#ifdef CONFIG_SMP
+	NEIGH_PRINTK3(KERN_DEBUG "neigh_periodic_timer tasklet(tbl=%p)\n", tbl);
+#else
+	NEIGH_PRINTK3(KERN_DEBUG "neigh_periodic_timer(tbl=%p)\n", tbl);
+#endif
 	NEIGH_CACHE_STAT_INC(tbl, periodic_gc_runs);
 
-	write_lock(&tbl->lock);
+	write_lock_bh(&tbl->lock);
 
 	/*
 	 *	periodicly recompute ReachableTime from random function
@@ -674,6 +699,7 @@
 	
 	if (now - tbl->last_rand > 300*HZ) {
 		struct neigh_parms *p;
+		NEIGH_PRINTK3(KERN_DEBUG "neigh_periodic_timer(): re-generating reachable_time\n");
 		tbl->last_rand = now;
 		for (p=&tbl->parms; p; p = p->next)
 			p->reachable_time = neigh_rand_reach_time(p->base_reachable_time);
@@ -685,27 +711,31 @@
 	while ((n = *np) != NULL) {
 		unsigned int state;
 
-		write_lock(&n->lock);
-  
-		state = n->nud_state;
-		if (state & (NUD_PERMANENT | NUD_IN_TIMER)) {
-			write_unlock(&n->lock);
-			goto next_elt;
-		}
+			write_lock_bh(&n->lock);
 
-		if (time_before(n->used, n->confirmed))
-			n->used = n->confirmed;
+			state = n->nud_state;
+			if (state == NUD_NONE || 
+			    (state&(NUD_PERMANENT|NUD_IN_TIMER))) {
+				write_unlock_bh(&n->lock);
+				goto next_elt;
+			}
 
-		if (atomic_read(&n->refcnt) == 1 &&
-		    (state == NUD_FAILED ||
-		     time_after(now, n->used + n->parms->gc_staletime))) {
-			*np = n->next;
-			n->dead = 1;
-			write_unlock(&n->lock);
-			neigh_release(n);
-			continue;
-		}
-		write_unlock(&n->lock);
+			/* STALE,FAILED,NOARP */
+			if ((long)(n->used - n->confirmed) < 0)
+				n->used = n->confirmed;
+
+			if (atomic_read(&n->refcnt) == 1 &&
+			    ((state&NUD_FAILED) || 
+			     (now - n->used > n->parms->gc_staletime))) {
+				NEIGH_PRINTK3(KERN_DEBUG "neigh %p: %s (dead, neigh_periodic_timer)\n", 
+						n, neigh_state(state));
+				*np = n->next;
+				n->dead = 1;
+				write_unlock_bh(&n->lock);
+				neigh_release(n);
+				continue;
+			}
+			write_unlock_bh(&n->lock);
 
 next_elt:
 		np = &n->next;
@@ -721,8 +751,7 @@
 		expire = 1;
 
  	mod_timer(&tbl->gc_timer, now + expire);
-
-	write_unlock(&tbl->lock);
+	write_unlock_bh(&tbl->lock);
 }
 
 #ifdef CONFIG_SMP
@@ -730,6 +759,7 @@
 {
 	struct neigh_table *tbl = (struct neigh_table*)arg;
 	
+	NEIGH_PRINTK3(KERN_DEBUG "neigh_periodic_timer(tbl=%p)\n", tbl);
 	tasklet_schedule(&tbl->gc_task);
 }
 #endif
@@ -737,7 +767,9 @@
 static __inline__ int neigh_max_probes(struct neighbour *n)
 {
 	struct neigh_parms *p = n->parms;
-	return p->ucast_probes + p->app_probes + p->mcast_probes;
+	return ((n->nud_state & NUD_PROBE) ?
+		 p->ucast_probes : 
+		 p->ucast_probes + p->app_probes + p->mcast_probes);
 }
 
 
@@ -745,132 +777,178 @@
 
 static void neigh_timer_handler(unsigned long arg) 
 {
-	unsigned long now = jiffies;
+	unsigned long now, next;
 	struct neighbour *neigh = (struct neighbour*)arg;
-	struct sk_buff *skb;
 	unsigned state;
-	int notify = 0;
 
-	write_lock(&neigh->lock);
+	NEIGH_PRINTK3(KERN_DEBUG "neigh_timer_handler(neigh=%p)\n", neigh);
+
+	write_lock_bh(&neigh->lock);
+	now = jiffies;
+	next = now + HZ;
 
 	state = neigh->nud_state;
 
 	if (!(state&NUD_IN_TIMER)) {
-#ifndef CONFIG_SMP
-		printk("neigh: timer & !nud_in_timer\n");
-#endif
-		goto out;
-	}
-
-	if ((state&NUD_VALID) &&
-	    now - neigh->confirmed < neigh->parms->reachable_time) {
-		neigh->nud_state = NUD_REACHABLE;
-		NEIGH_PRINTK2("neigh %p is still alive.\n", neigh);
-		neigh_connect(neigh);
-		goto out;
-	}
-	if (state == NUD_DELAY) {
-		NEIGH_PRINTK2("neigh %p is probed.\n", neigh);
-		neigh->nud_state = NUD_PROBE;
-		atomic_set(&neigh->probes, 0);
+		/* impossible */
+		write_unlock_bh(&neigh->lock);
+		NEIGH_PRINTK1(KERN_CRIT "neigh_timer_handler(): timer & !nud_in_timer\n");
+		return;
 	}
 
-	if (atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) {
-		struct sk_buff *skb;
-
-		neigh->nud_state = NUD_FAILED;
-		notify = 1;
-		NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed);
-		NEIGH_PRINTK2("neigh %p is failed.\n", neigh);
-
-		/* It is very thin place. report_unreachable is very complicated
-		   routine. Particularly, it can hit the same neighbour entry!
-		   
-		   So that, we try to be accurate and avoid dead loop. --ANK
-		 */
-		while(neigh->nud_state==NUD_FAILED && (skb=__skb_dequeue(&neigh->arp_queue)) != NULL) {
-			write_unlock(&neigh->lock);
-			neigh->ops->error_report(neigh, skb);
-			write_lock(&neigh->lock);
+	if (state&NUD_REACHABLE) {
+		if (now - neigh->confirmed < neigh->parms->reachable_time) {
+			NEIGH_PRINTK3(KERN_DEBUG "neigh %p: REACHABLE (neigh_timer_handler).\n",
+					neigh);
+			next = neigh->confirmed + neigh->parms->reachable_time;
+		} else if (now - neigh->used <= neigh->parms->delay_probe_time) {
+			NEIGH_PRINTK3(KERN_DEBUG "neigh %p: REACHABLE->DELAY (neigh_timer_handler).\n",
+					neigh);
+			neigh->nud_state = NUD_DELAY;
+			neigh_suspect(neigh);
+			next = now + neigh->parms->delay_probe_time;
+		} else {
+			NEIGH_PRINTK3(KERN_DEBUG "neigh %p: REACHABLE->STALE (neigh_timer_handler).\n",
+					neigh);
+			neigh->nud_state = NUD_STALE;
+			neigh_suspect(neigh);
 		}
-		skb_queue_purge(&neigh->arp_queue);
-		goto out;
+	} else if (state&NUD_DELAY) {
+		if (now - neigh->confirmed <= neigh->parms->delay_probe_time) {
+			NEIGH_PRINTK3(KERN_DEBUG "neigh %p: DELAY->REACHABLE (neigh_timer_handler).\n",
+					neigh);
+			neigh->nud_state = NUD_REACHABLE;
+			neigh_connect(neigh);
+			next = neigh->confirmed + neigh->parms->reachable_time;
+		} else {
+			NEIGH_PRINTK3(KERN_DEBUG "neigh %p: DELAY->PROBE (neigh_timer_handler).\n",
+					neigh);
+			neigh->nud_state = NUD_PROBE;
+			atomic_set(&neigh->probes, 0);
+			next = now + neigh->parms->retrans_time;
+		}
+	} else {
+		/* PROBE,INCOMPLETE */
+		NEIGH_PRINTK3(KERN_DEBUG "neigh %p: %s (neigh_timer_handler).\n",
+			neigh, neigh_state(state));
+		next = now + neigh->parms->retrans_time;
 	}
 
-	neigh->timer.expires = now + neigh->parms->retrans_time;
-	add_timer(&neigh->timer);
+	if (neigh->nud_state&(NUD_INCOMPLETE|NUD_PROBE)) {
+		if (atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) {
+			struct sk_buff *skb;
 
-	/* keep skb alive even if arp_queue overflows */
-	skb = skb_peek(&neigh->arp_queue);
-	if (skb)
-		skb_get(skb);
+			NEIGH_PRINTK3(KERN_DEBUG "neigh %p: %s->FAILED (neigh_timer_handler).\n",
+					neigh, neigh_state(neigh->nud_state));
+			neigh->updated = now;
+			neigh->nud_state = NUD_FAILED;
 
-	write_unlock(&neigh->lock);
+			del_timer(&neigh->timer);	/* release neigh later */
 
-	neigh->ops->solicit(neigh, skb);
-	atomic_inc(&neigh->probes);
+			NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed);
 
-	if (skb)
-		kfree_skb(skb);
+			/* It is very thin place. report_unreachable is very complicated
+			   routine. Particularly, it can hit the same neighbour entry!
+			   
+			   So that, we try to be accurate and avoid dead loop. --ANK
+			 */
 
-	return;
+			/*
+			   neigh_periodic_timer() should not release this entry 
+			   while processing. -- yoshfuji
+			 */
+			neigh_hold(neigh);
 
-out:
-	write_unlock(&neigh->lock);
+			while(neigh->nud_state==NUD_FAILED && (skb=__skb_dequeue(&neigh->arp_queue)) != NULL) {
+				write_unlock_bh(&neigh->lock);
+				neigh->ops->error_report(neigh, skb);
+				write_lock_bh(&neigh->lock);
+			}
+			skb_queue_purge(&neigh->arp_queue);	/* XXX: !FAILED case? */
 #ifdef CONFIG_ARPD
-	if (notify && neigh->parms->app_probes)
-		neigh_app_notify(neigh);
+			if (neigh->parms->app_probes) {
+				write_unlock_bh(&neigh->lock);
+				neigh_app_notify(neigh);
+			} else {
+				write_unlock_bh(&neigh->lock);
+			}
+#else
+			write_unlock_bh(&neigh->lock);
 #endif
+			neigh_release(neigh);
+			neigh_release(neigh);	/* timer */
+		 	return;
+		}
+	}
+
+	if (neigh->nud_state&NUD_IN_TIMER) {
+		neigh_hold(neigh);	/* don't release while processing */
+		if (time_before(next, jiffies + HZ/2))
+			next = jiffies + HZ/2;
+		mod_timer(&neigh->timer, next);
+		NEIGH_PRINTK3(KERN_DEBUG "neigh_timer_handler(neigh=%p): next=%lu (%lu sec)\n",
+				neigh, next, (next-jiffies)/HZ);
+		if (neigh->nud_state&(NUD_INCOMPLETE|NUD_PROBE)) {
+			struct sk_buff *skb = skb_peek(&neigh->arp_queue);
+			if (skb)
+				skb_get(skb);
+			write_unlock_bh(&neigh->lock);
+ 			neigh->ops->solicit(neigh, skb_peek(&neigh->arp_queue));
+			atomic_inc(&neigh->probes);	/* XXX: race */
+			if (skb)
+				kfree_skb(skb);
+		} else {
+			write_unlock_bh(&neigh->lock);
+		}
+	} else {
+		del_timer(&neigh->timer);
+		write_unlock_bh(&neigh->lock);
+	}
 	neigh_release(neigh);
 }
 
 int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
 {
-	write_lock_bh(&neigh->lock);
-	if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE))) {
-		if (!(neigh->nud_state&(NUD_STALE|NUD_INCOMPLETE))) {
-			if (neigh->parms->mcast_probes + neigh->parms->app_probes) {
-				atomic_set(&neigh->probes, neigh->parms->ucast_probes);
-				neigh->nud_state = NUD_INCOMPLETE;
-				neigh_hold(neigh);
-				neigh->timer.expires = jiffies + neigh->parms->retrans_time;
-				add_timer(&neigh->timer);
-				write_unlock_bh(&neigh->lock);
-				neigh->ops->solicit(neigh, skb);
-				atomic_inc(&neigh->probes);
-				write_lock_bh(&neigh->lock);
-			} else {
-				neigh->nud_state = NUD_FAILED;
-				write_unlock_bh(&neigh->lock);
+	int ret = 0;
+	unsigned long now = jiffies;
 
-				if (skb)
-					kfree_skb(skb);
-				return 1;
-			}
-		}
-		if (neigh->nud_state == NUD_INCOMPLETE) {
-			if (skb) {
-				if (skb_queue_len(&neigh->arp_queue) >= neigh->parms->queue_len) {
-					struct sk_buff *buff;
-					buff = neigh->arp_queue.next;
-					__skb_unlink(buff, &neigh->arp_queue);
-					kfree_skb(buff);
-				}
-				__skb_queue_tail(&neigh->arp_queue, skb);
+	NEIGH_PRINTK3(KERN_DEBUG "__neigh_event_send(neigh=%p, skb=%p)\n", neigh, skb);
+	if (neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE)) {
+		/* PERMANENT,NOARP,REACHABLE,DELAY,PROBE */
+		goto out;
+	}
+	/* INCOMPLETE,STALE,FAILED,NONE */
+	if (!(neigh->nud_state&(NUD_STALE|NUD_INCOMPLETE))) {
+		/* FAILED,NONE */
+		NEIGH_PRINTK3(KERN_DEBUG "neigh %p: %s->INCOMPLETE (neigh_event_send).\n", 
+				neigh, neigh_state(neigh->nud_state));
+		neigh_hold(neigh);
+		atomic_set(&neigh->probes, neigh->parms->ucast_probes);
+		neigh->nud_state = NUD_INCOMPLETE;
+		neigh->timer.expires = jiffies;
+		add_timer(&neigh->timer);
+	} else if (neigh->nud_state == NUD_STALE) {
+		NEIGH_PRINTK3(KERN_DEBUG "neigh %p: STALE->DELAY (neigh_event_send).\n",
+				neigh);
+		neigh_hold(neigh);
+		neigh->nud_state = NUD_DELAY;
+		neigh->timer.expires = now + neigh->parms->delay_probe_time;
+		add_timer(&neigh->timer);
+	}
+	if (neigh->nud_state == NUD_INCOMPLETE) {
+		if (skb) {
+			if (skb_queue_len(&neigh->arp_queue) >= neigh->parms->queue_len) {
+				struct sk_buff *buff;
+				buff = neigh->arp_queue.next;
+				__skb_unlink(buff, &neigh->arp_queue);
+				kfree_skb(buff);
 			}
-			write_unlock_bh(&neigh->lock);
-			return 1;
-		}
-		if (neigh->nud_state == NUD_STALE) {
-			NEIGH_PRINTK2("neigh %p is delayed.\n", neigh);
-			neigh_hold(neigh);
-			neigh->nud_state = NUD_DELAY;
-			neigh->timer.expires = jiffies + neigh->parms->delay_probe_time;
-			add_timer(&neigh->timer);
+			__skb_queue_tail(&neigh->arp_queue, skb);
 		}
+		ret = 1;
 	}
-	write_unlock_bh(&neigh->lock);
-	return 0;
+out:
+	return ret;
 }
 
 static __inline__ void neigh_update_hhs(struct neighbour *neigh)
@@ -879,6 +957,8 @@
 	void (*update)(struct hh_cache*, struct net_device*, unsigned char*) =
 		neigh->dev->header_cache_update;
 
+	NEIGH_PRINTK3(KERN_DEBUG "neigh_update_hhs(neigh=%p)\n", neigh);
+
 	if (update) {
 		for (hh=neigh->hh; hh; hh=hh->hh_next) {
 			write_lock_bh(&hh->hh_lock);
@@ -889,31 +969,49 @@
 }
 
 
-
 /* Generic update routine.
    -- lladdr is new lladdr or NULL, if it is not supplied.
    -- new    is new state.
-   -- override==1 allows to override existing lladdr, if it is different.
-   -- arp==0 means that the change is administrative.
+   -- flags  specifies details of update
 
    Caller MUST hold reference count on the entry.
+   __neigh_update() is called under write_lock_bh().
+
  */
 
-int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, int override, int arp)
+int __neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, u32 flags)
 {
 	u8 old;
 	int err;
 	int notify = 0;
-	struct net_device *dev = neigh->dev;
+	struct net_device *dev;
+	unsigned long now = jiffies;
+	int hold = 0;
+	int update_isrouter = 0;
+
+	if (!neigh) {
+		NEIGH_PRINTK1(KERN_WARNING "__neigh_update(): neigh==NULL\n");
+		return -EINVAL;
+	}
 
-	write_lock_bh(&neigh->lock);
 	old = neigh->nud_state;
 
+	NEIGH_PRINTK3(KERN_DEBUG "__neigh_update(neigh=%p, lladdr=%p, new=%u(%s), flags=%08x): old=%u(%s)\n",
+			neigh, lladdr, new, neigh_state(new), flags,
+			old, neigh_state(old));
+
+	dev = neigh->dev;
+	if (!dev) {
+		NEIGH_PRINTK1(KERN_WARNING "__neigh_update(): neigh->dev==NULL\n");
+		return -EINVAL;
+	}
+
 	err = -EPERM;
-	if (arp && (old&(NUD_NOARP|NUD_PERMANENT)))
+	if (!(flags&NEIGH_UPDATE_F_ADMIN) && (old&(NUD_NOARP|NUD_PERMANENT)))
 		goto out;
 
 	if (!(new&NUD_VALID)) {
+		/* NONE,INCOMPLETE,FAILED */
 		neigh_del_timer(neigh);
 		if (old&NUD_CONNECTED)
 			neigh_suspect(neigh);
@@ -936,8 +1034,6 @@
 		if (old&NUD_VALID) {
 			if (memcmp(lladdr, neigh->ha, dev->addr_len) == 0)
 				lladdr = neigh->ha;
-			else if (!override)
-				goto out;
 		}
 	} else {
 		/* No address is supplied; if we know something,
@@ -949,31 +1045,68 @@
 		lladdr = neigh->ha;
 	}
 
-	neigh_sync(neigh);
-	old = neigh->nud_state;
-	if (new&NUD_CONNECTED)
-		neigh->confirmed = jiffies;
-	neigh->updated = jiffies;
-
 	/* If entry was valid and address is not changed,
 	   do not change entry state, if new one is STALE.
 	 */
 	err = 0;
 	if (old&NUD_VALID) {
-		if (lladdr == neigh->ha)
-			if (new == old || (new == NUD_STALE && (old&NUD_CONNECTED)))
+		if (lladdr != neigh->ha &&
+		    !(flags&NEIGH_UPDATE_F_OVERRIDE)) {
+			if ((flags&NEIGH_UPDATE_F_SUSPECT_CONNECTED) &&
+			    (old&NUD_CONNECTED)) {
+				new = NUD_STALE;
+				lladdr = neigh->ha;
+			} else {
 				goto out;
+			}
+		} else {
+			if ((flags&NEIGH_UPDATE_F_REUSEADDR) &&
+			    new == old)
+				lladdr = neigh->ha;
+			else if (lladdr == neigh->ha && new == NUD_STALE) {
+				if ((flags&NEIGH_UPDATE_F_REUSESUSPECTSTATE) ||
+				    (old&NUD_CONNECTED))
+					new = old;
+			}
+			update_isrouter = flags&NEIGH_UPDATE_F_OVERRIDE_VALID_ISROUTER;
+		}
+	} else {
+		/* INCOMPLETE */
+		update_isrouter = flags&NEIGH_UPDATE_F_OVERRIDE_VALID_ISROUTER;
 	}
-	neigh_del_timer(neigh);
-	neigh->nud_state = new;
+
+	if (new != old) {
+		if (new&NUD_IN_TIMER) {
+			unsigned long next = now;
+			switch(new) {
+			case NUD_REACHABLE:
+				next += neigh->parms->reachable_time;
+				break;
+			default:;
+				/*XXX*/
+			}
+			if (old&NUD_IN_TIMER) {
+				mod_timer(&neigh->timer, next);
+			} else {
+				neigh_hold(neigh);
+				neigh->timer.expires = next;
+				add_timer(&neigh->timer);
+			}
+		} else {
+			neigh_del_timer(neigh);
+		}
+		neigh->nud_state = new;
+	}
+	if ((new != old || lladdr != neigh->ha) &&
+	    new&NUD_CONNECTED)
+		neigh->confirmed = now;
 	if (lladdr != neigh->ha) {
+		neigh->updated = now;
 		memcpy(&neigh->ha, lladdr, dev->addr_len);
 		neigh_update_hhs(neigh);
 		if (!(new&NUD_CONNECTED))
-			neigh->confirmed = jiffies - (neigh->parms->base_reachable_time<<1);
-#ifdef CONFIG_ARPD
+			neigh->confirmed = now - (neigh->parms->base_reachable_time<<1);
 		notify = 1;
-#endif
 	}
 	if (new == old)
 		goto out;
@@ -984,8 +1117,13 @@
 	if (!(old&NUD_VALID)) {
 		struct sk_buff *skb;
 
-		/* Again: avoid dead loop if something went wrong */
+		neigh_hold(neigh);	/* don't release neigh while processing */
+		hold = 1;
+
+		if (new&NUD_VALID)
+			notify = 1;
 
+		/* Again: avoid dead loop if something went wrong */
 		while (neigh->nud_state&NUD_VALID &&
 		       (skb=__skb_dequeue(&neigh->arp_queue)) != NULL) {
 			struct neighbour *n1 = neigh;
@@ -999,12 +1137,39 @@
 		skb_queue_purge(&neigh->arp_queue);
 	}
 out:
-	write_unlock_bh(&neigh->lock);
+	if (update_isrouter) {
+		neigh->flags = (flags&NEIGH_UPDATE_F_ISROUTER) ?
+				(neigh->flags|NTF_ROUTER) :
+				(neigh->flags&~NTF_ROUTER);
+	}
+	NEIGH_PRINTK3(KERN_DEBUG "neigh %p: %s->%s (neigh_update).\n",
+			neigh, neigh_state(old), neigh_state(neigh->nud_state));
+	if (hold)
+		neigh_release(neigh);
+	return err ? err : notify;
+}
+
+int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, int override, int arp)
+{
+	int update;
+	write_lock_bh(&neigh->lock);
+	neigh_hold(neigh);
+	update = __neigh_update(neigh, lladdr, new, 
+				NEIGH_UPDATE_F_REUSEADDR|
+				(override ? NEIGH_UPDATE_F_OVERRIDE : 0) |
+				(arp ? 0 : NEIGH_UPDATE_F_ADMIN));
 #ifdef CONFIG_ARPD
-	if (notify && neigh->parms->app_probes)
+	if (update > 0 && neigh->parms->app_probes) {
+		write_unlock_bh(&neigh->lock);
 		neigh_app_notify(neigh);
+	} else {
+		write_unlock_bh(&neigh->lock);
+	}
+#else
+	write_unlock_bh(&neigh->lock);
 #endif
-	return err;
+	neigh_release(neigh);	/*XXX: may invalidate neigh... */
+	return update >= 0 ? 0 : update;
 }
 
 struct neighbour * neigh_event_ns(struct neigh_table *tbl,
@@ -1013,7 +1178,14 @@
 {
 	struct neighbour *neigh;
 
+	NEIGH_PRINTK3(KERN_DEBUG "neigh_event_ns(tbl=%p, lladdr=%p, saddr=%p, dev=%p(%s))\n",
+			tbl, lladdr, saddr, dev, dev?dev->name:"<null>");
+
+	/*  neighbour status should be changed to NUD_STALE
+	    if lladdr != neigh->ha
+	*/
 	neigh = __neigh_lookup(tbl, saddr, dev, lladdr || !dev->addr_len);
+
 	if (neigh)
 		neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
 	return neigh;
@@ -1024,6 +1196,9 @@
 	struct hh_cache	*hh = NULL;
 	struct net_device *dev = dst->dev;
 
+	NEIGH_PRINTK3(KERN_DEBUG "neigh_hh_init(n=%p, dst=%p, protocol=%u)\n",
+			n, dst, protocol);
+
 	for (hh=n->hh; hh; hh = hh->hh_next)
 		if (hh->hh_type == protocol)
 			break;
@@ -1076,9 +1251,12 @@
 
 int neigh_resolve_output(struct sk_buff *skb)
 {
-	struct dst_entry *dst = skb->dst;
-	struct neighbour *neigh;
+	struct dst_entry *dst = NULL;
+	struct neighbour *neigh = NULL;
 
+	if (!skb)
+		goto discard;
+	dst = skb->dst;
 	if (!dst || !(neigh = dst->neighbour))
 		goto discard;
 
@@ -1106,8 +1284,9 @@
 	return 0;
 
 discard:
-	NEIGH_PRINTK1("neigh_resolve_output: dst=%p neigh=%p\n", dst, dst ? dst->neighbour : NULL);
-	kfree_skb(skb);
+	NEIGH_PRINTK1("neigh_resolve_output(skb=%p): dst=%p neigh=%p\n", skb, dst, neigh);
+	if (skb)
+		kfree_skb(skb);
 	return -EINVAL;
 }
 
@@ -1303,6 +1482,8 @@
 {
 	struct neigh_table **tp;
 
+	NEIGH_PRINTK3("neigh_table_clean(tbl=%p)\n", tbl);
+	
 	/* It is not clean... Fix it to unload IPv6 module safely */
 	del_timer_sync(&tbl->gc_timer);
 	tasklet_kill(&tbl->gc_task);
@@ -1310,7 +1491,7 @@
 	pneigh_queue_purge(&tbl->proxy_queue);
 	neigh_ifdown(tbl, NULL);
 	if (atomic_read(&tbl->entries))
-		printk(KERN_CRIT "neighbour leakage\n");
+		NEIGH_PRINTK1(KERN_CRIT "neighbour leakage\n");
 	write_lock(&neigh_tbl_lock);
 	for (tp = &neigh_tables; *tp; tp = &(*tp)->next) {
 		if (*tp == tbl) {
@@ -1326,6 +1507,16 @@
 	kfree(tbl->phash_buckets);
 	tbl->phash_buckets = NULL;
 
+	if (kmem_cache_destroy(tbl->kmem_cachep) == 0) {
+		NEIGH_PRINTK3("%s(tbl=%p): kmem_cache %p for %s destroyed.\n",
+				__FUNCTION__, tbl, tbl->kmem_cachep, tbl->id);
+		tbl->kmem_cachep = NULL;
+	} else {
+		NEIGH_PRINTK1(KERN_WARNING 
+			     "%s(tbl=%p): failed to destroy kmem_cache %p for %s.\n",
+				__FUNCTION__, tbl, tbl->kmem_cachep, tbl->id);
+	}
+
 #ifdef CONFIG_SYSCTL
 	neigh_sysctl_unregister(&tbl->parms);
 #endif
@@ -1340,6 +1531,9 @@
 	struct net_device *dev = NULL;
 	int err = 0;
 
+	NEIGH_PRINTK3(KERN_DEBUG "neigh_delete(skb=%p, nlh=%p, nda=%p)\n",
+			skb, nlh, arg);
+
 	if (ndm->ndm_ifindex) {
 		if ((dev = dev_get_by_index(ndm->ndm_ifindex)) == NULL)
 			return -ENODEV;
@@ -1933,7 +2127,7 @@
 	netlink_broadcast(rtnl, skb, 0, RTMGRP_NEIGH, GFP_ATOMIC);
 }
 
-static void neigh_app_notify(struct neighbour *n)
+void neigh_app_notify(struct neighbour *n)
 {
 	struct sk_buff *skb;
 	struct nlmsghdr  *nlh;
diff -urN linux-2.4.29/net/core/netfilter.c linux-2.4.29-uc1/net/core/netfilter.c
--- linux-2.4.29/net/core/netfilter.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/core/netfilter.c	2005-06-14 02:11:53.000000000 +0100
@@ -342,10 +342,15 @@
 			       const struct net_device *indev,
 			       const struct net_device *outdev,
 			       struct list_head **i,
-			       int (*okfn)(struct sk_buff *))
+			       int (*okfn)(struct sk_buff *),
+			       int hook_thresh)
 {
 	for (*i = (*i)->next; *i != head; *i = (*i)->next) {
 		struct nf_hook_ops *elem = (struct nf_hook_ops *)*i;
+
+		if (hook_thresh > elem->priority)
+			continue;
+
 		switch (elem->hook(hook, skb, indev, outdev, okfn)) {
 		case NF_QUEUE:
 			return NF_QUEUE;
@@ -413,6 +418,10 @@
 {
 	int status;
 	struct nf_info *info;
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+	struct net_device *physindev = NULL;
+	struct net_device *physoutdev = NULL;
+#endif
 
 	if (!queue_handler[pf].outfn) {
 		kfree_skb(skb);
@@ -435,11 +444,24 @@
 	if (indev) dev_hold(indev);
 	if (outdev) dev_hold(outdev);
 
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+	if (skb->nf_bridge) {
+		physindev = skb->nf_bridge->physindev;
+		if (physindev) dev_hold(physindev);
+		physoutdev = skb->nf_bridge->physoutdev;
+		if (physoutdev) dev_hold(physoutdev);
+	}
+#endif
+
 	status = queue_handler[pf].outfn(skb, info, queue_handler[pf].data);
 	if (status < 0) {
 		/* James M doesn't say fuck enough. */
 		if (indev) dev_put(indev);
 		if (outdev) dev_put(outdev);
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+		if (physindev) dev_put(physindev);
+		if (physoutdev) dev_put(physoutdev);
+#endif
 		kfree(info);
 		kfree_skb(skb);
 		return;
@@ -449,7 +471,8 @@
 int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
 		 struct net_device *indev,
 		 struct net_device *outdev,
-		 int (*okfn)(struct sk_buff *))
+		 int (*okfn)(struct sk_buff *),
+		 int hook_thresh)
 {
 	struct list_head *elem;
 	unsigned int verdict;
@@ -481,7 +504,7 @@
 
 	elem = &nf_hooks[pf][hook];
 	verdict = nf_iterate(&nf_hooks[pf][hook], &skb, hook, indev,
-			     outdev, &elem, okfn);
+			     outdev, &elem, okfn, hook_thresh);
 	if (verdict == NF_QUEUE) {
 		NFDEBUG("nf_hook: Verdict = QUEUE.\n");
 		nf_queue(skb, elem, pf, hook, indev, outdev, okfn);
@@ -510,6 +533,14 @@
 
 	/* We don't have BR_NETPROTO_LOCK here */
 	br_read_lock_bh(BR_NETPROTO_LOCK);
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+	if (skb->nf_bridge) {
+		if (skb->nf_bridge->physindev)
+			dev_put(skb->nf_bridge->physindev);
+		if (skb->nf_bridge->physoutdev)
+			dev_put(skb->nf_bridge->physoutdev);
+	}
+#endif
 	for (i = nf_hooks[info->pf][info->hook].next; i != elem; i = i->next) {
 		if (i == &nf_hooks[info->pf][info->hook]) {
 			/* The module which sent it to userspace is gone. */
@@ -530,7 +561,7 @@
 		verdict = nf_iterate(&nf_hooks[info->pf][info->hook],
 				     &skb, info->hook, 
 				     info->indev, info->outdev, &elem,
-				     info->okfn);
+				     info->okfn, INT_MIN);
 	}
 
 	switch (verdict) {
diff -urN linux-2.4.29/net/core/skbuff.c linux-2.4.29-uc1/net/core/skbuff.c
--- linux-2.4.29/net/core/skbuff.c	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/net/core/skbuff.c	2005-06-14 02:11:53.000000000 +0100
@@ -166,6 +166,10 @@
 	struct sk_buff *skb;
 	u8 *data;
 
+#if defined(CONFIG_ARCH_IXP425)
+	gfp_mask |= GFP_DMA;
+#endif
+
 	if (in_interrupt() && (gfp_mask & __GFP_WAIT)) {
 		static int count = 0;
 		if (++count < 5) {
@@ -202,6 +206,10 @@
 	/* Set up other state */
 	skb->len = 0;
 	skb->cloned = 0;
+#if defined(CONFIG_IMQ) || defined (CONFIG_IMQ_MODULE)
+	skb->imq_flags = 0;
+	skb->nf_info = NULL;
+#endif
 	skb->data_len = 0;
 
 	atomic_set(&skb->users, 1); 
@@ -246,10 +254,17 @@
 #ifdef CONFIG_NETFILTER_DEBUG
 	skb->nf_debug = 0;
 #endif
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+	skb->nf_bridge	  = NULL;
+#endif
 #endif
 #ifdef CONFIG_NET_SCHED
 	skb->tc_index = 0;
 #endif
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
+	skb->imq_flags = 0;
+	skb->nf_info = NULL;
+#endif
 }
 
 static void skb_drop_fraglist(struct sk_buff *skb)
@@ -326,6 +341,9 @@
 	}
 #ifdef CONFIG_NETFILTER
 	nf_conntrack_put(skb->nfct);
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+	nf_bridge_put(skb->nf_bridge);
+#endif
 #endif
 	skb_headerinit(skb, NULL, 0);  /* clean state */
 	kfree_skbmem(skb);
@@ -393,6 +411,9 @@
 #ifdef CONFIG_NETFILTER_DEBUG
 	C(nf_debug);
 #endif
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+	C(nf_bridge);
+#endif
 #endif /*CONFIG_NETFILTER*/
 #if defined(CONFIG_HIPPI)
 	C(private);
@@ -400,11 +421,18 @@
 #ifdef CONFIG_NET_SCHED
 	C(tc_index);
 #endif
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
+	C(imq_flags);
+	C(nf_info);
+#endif
 
 	atomic_inc(&(skb_shinfo(skb)->dataref));
 	skb->cloned = 1;
 #ifdef CONFIG_NETFILTER
 	nf_conntrack_get(skb->nfct);
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+	nf_bridge_get(skb->nf_bridge);
+#endif
 #endif
 	return n;
 }
@@ -440,10 +468,18 @@
 #ifdef CONFIG_NETFILTER_DEBUG
 	new->nf_debug=old->nf_debug;
 #endif
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+	new->nf_bridge=old->nf_bridge;
+	nf_bridge_get(new->nf_bridge);
+#endif
 #endif
 #ifdef CONFIG_NET_SCHED
 	new->tc_index = old->tc_index;
 #endif
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
+	new->imq_flags=old->imq_flags;
+	new->nf_info=old->nf_info;
+#endif
 }
 
 /**
@@ -726,9 +762,9 @@
 	/* Set the tail pointer and length */
 	skb_put(n,skb->len);
 
-	/* Copy the data only. */
-	if (skb_copy_bits(skb, 0, n->data, skb->len))
-		BUG();
+       /* Copy the linear data and header. */
+       if (skb_copy_bits(skb, -newheadroom, n->head, newheadroom + skb->len))
+                BUG();
 
 	copy_skb_header(n, skb);
 	return n;
diff -urN linux-2.4.29/net/core/sock.c linux-2.4.29-uc1/net/core/sock.c
--- linux-2.4.29/net/core/sock.c	2004-08-08 00:26:06.000000000 +0100
+++ linux-2.4.29-uc1/net/core/sock.c	2005-06-14 02:11:53.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: sock.c,v 1.13 2003/12/20 18:32:15 yoshfuji Exp $ */
+
 /*
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
@@ -217,6 +219,11 @@
 		case SO_REUSEADDR:
 			sk->reuse = valbool;
 			break;
+#ifdef SO_REUSEPORT
+		case SO_REUSEPORT:
+			sk->reuseport = valbool;
+			break;
+#endif
 		case SO_TYPE:
 		case SO_ERROR:
 			ret = -ENOPROTOOPT;
@@ -469,6 +476,12 @@
 			v.val = sk->reuse;
 			break;
 
+#ifdef SO_REUSEPORT
+		case SO_REUSEPORT:
+			v.val = sk->reuseport;
+			break;
+#endif
+
 		case SO_KEEPALIVE:
 			v.val = sk->keepopen;
 			break;
diff -urN linux-2.4.29/net/decnet/dn_neigh.c linux-2.4.29-uc1/net/decnet/dn_neigh.c
--- linux-2.4.29/net/decnet/dn_neigh.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/decnet/dn_neigh.c	2005-06-14 02:11:53.000000000 +0100
@@ -488,7 +488,9 @@
 
 	dn_dn2eth(s->rs, dn->addr);
 	s->rs += 6;
+	read_lock(&neigh->lock);
 	*(s->rs) = neigh->nud_state & NUD_CONNECTED ? 0x80 : 0x0;
+	read_unlock(&neigh->lock);
 	*(s->rs) |= dn->priority;
 	s->rs++;
 }
diff -urN linux-2.4.29/net/ethernet/eth.c linux-2.4.29-uc1/net/ethernet/eth.c
--- linux-2.4.29/net/ethernet/eth.c	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/net/ethernet/eth.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: eth.c,v 1.6 2003/08/08 13:46:37 yoshfuji Exp $ */
+
 /*
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
@@ -171,6 +173,18 @@
 		else
 			skb->pkt_type=PACKET_MULTICAST;
 	}
+
+#ifdef CONFIG_PCNET32_VMWARE
+	/*      For VMware hack.
+	 *      VMware network interfaces picks up MULTICAST packet
+	 *      which is generated by themselves.
+	 */
+	if(*eth->h_dest&1)  /* BROADCAST or MULTICAST Packet */
+	{
+		if(memcmp(dev->dev_addr,eth->h_source, ETH_ALEN)==0)
+			return 0;
+	}
+#endif
 	
 	/*
 	 *	This ALLMULTI check should be redundant by 1.4
diff -urN linux-2.4.29/net/ipsec/alg/Makefile linux-2.4.29-uc1/net/ipsec/alg/Makefile
--- linux-2.4.29/net/ipsec/alg/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipsec/alg/Makefile	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,17 @@
+
+.EXPORT_ALL_VARIABLES:
+CONFIG_HW_ASSIST := y
+
+EXTRA_CFLAGS += -I$(ROOTDIR)/freeswan -I$(ROOTDIR)/freeswan/lib \
+			-I$(ROOTDIR)/freeswan/klips/net/ipsec/alg \
+			-I$(ROOTDIR)/freeswan/libdes
+
+vpath %.h $(ROOTDIR)/freeswan/klips/net/ipsec/alg
+vpath %.c $(ROOTDIR)/freeswan/klips/net/ipsec/alg
+
+# special hack required because of exported object files
+# %.c: $(ROOTDIR)/freeswan/klips/net/ipsec/alg/%.c
+#	ln -fs $< $@
+
+include $(ROOTDIR)/freeswan/klips/net/ipsec/alg/Makefile
+
diff -urN linux-2.4.29/net/ipsec/alg/Makefile.alg_aes linux-2.4.29-uc1/net/ipsec/alg/Makefile.alg_aes
--- linux-2.4.29/net/ipsec/alg/Makefile.alg_aes	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipsec/alg/Makefile.alg_aes	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,18 @@
+.EXPORT_ALL_VARIABLES:
+
+EXTRA_CFLAGS += -I$(ROOTDIR)/freeswan -I$(ROOTDIR)/freeswan/lib \
+			-I$(ROOTDIR)/freeswan/klips/net/ipsec \
+			-I$(ROOTDIR)/freeswan/klips/net/ipsec/alg \
+			-I$(ROOTDIR)/freeswan/libcrypto \
+			-I$(ROOTDIR)/freeswan/libdes
+
+vpath %.h $(ROOTDIR)/freeswan/klips/net/ipsec/alg
+vpath %.c $(ROOTDIR)/freeswan/klips/net/ipsec/alg
+
+# special hack required because of exported object files
+# %.c: $(ROOTDIR)/freeswan/klips/net/ipsec/%.c
+#	ln -fs $< $@
+
+include $(ROOTDIR)/freeswan/klips/net/ipsec/alg/Makefile.alg_aes
+
+
diff -urN linux-2.4.29/net/ipsec/libdes/Makefile linux-2.4.29-uc1/net/ipsec/libdes/Makefile
--- linux-2.4.29/net/ipsec/libdes/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipsec/libdes/Makefile	2005-06-14 02:21:42.000000000 +0100
@@ -0,0 +1,18 @@
+
+.EXPORT_ALL_VARIABLES:
+
+EXTRA_CFLAGS += -I$(ROOTDIR)/freeswan/libdes -I$(ROOTDIR)/lib/$(LIBCDIR)/include
+
+ifdef CONFIG_MODULES
+EXTRA_CFLAGS += -DEXPORT_SYMTAB
+endif
+
+VPATH = $(ROOTDIR)/freeswan/libdes
+
+ifdef CONFIG_COLDFIRE
+COLDFIRE_KERNEL = y # get the ASM functions
+endif
+
+
+include $(ROOTDIR)/freeswan/libdes/Makefile
+
diff -urN linux-2.4.29/net/ipsec/libfreeswan/Makefile linux-2.4.29-uc1/net/ipsec/libfreeswan/Makefile
--- linux-2.4.29/net/ipsec/libfreeswan/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipsec/libfreeswan/Makefile	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,10 @@
+
+.EXPORT_ALL_VARIABLES:
+
+EXTRA_CFLAGS += -I$(ROOTDIR)/freeswan/lib
+EXTRA_CFLAGS += -I$(ROOTDIR)/freeswan/klips/net/ipsec
+
+VPATH = $(ROOTDIR)/freeswan/lib
+
+include $(ROOTDIR)/freeswan/lib/Makefile.kernel
+
diff -urN linux-2.4.29/net/ipsec/Makefile linux-2.4.29-uc1/net/ipsec/Makefile
--- linux-2.4.29/net/ipsec/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipsec/Makefile	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,60 @@
+ifneq ($(CONFIG_KLIPS),)
+.EXPORT_ALL_VARIABLES:
+
+include $(ROOTDIR)/openswan/Makefile.ver
+
+EXTRA_CFLAGS += -I$(ROOTDIR)/openswan -I$(ROOTDIR)/openswan/lib \
+			-I$(ROOTDIR)/openswan/linux/net/ipsec \
+			-I$(ROOTDIR)/openswan/linux/include \
+			-D__HAVE_ARCH_STRSTR
+
+vpath %.h $(ROOTDIR)/openswan/linux/net/ipsec
+
+# special hack required because of exported object files
+%.c: $(ROOTDIR)/openswan/linux/net/ipsec/%.c
+	ln -fs $< $@
+%.c: $(ROOTDIR)/openswan/linux/net/ipsec/aes/%.c
+	ln -fs $< $@
+%.c: $(ROOTDIR)/openswan/linux/net/ipsec/des/%.c
+	ln -fs $< $@
+
+include $(ROOTDIR)/openswan/linux/net/ipsec/Makefile.fs2_4
+
+version.c:	version.in.c
+	sed '/"/s/xxx/$(IPSECVERSION)/' version.in.c >$@
+
+else
+
+ifneq ($(CONFIG_IPSEC),)
+.EXPORT_ALL_VARIABLES:
+
+ifdef CONFIG_IXP4XX_CRYPTO	
+EXTRA_CFLAGS += -I$(ROOTDIR)/freeswan/klips/net/ipsec_xscale -I$(ROOTDIR)/include
+endif
+EXTRA_CFLAGS += -I$(ROOTDIR)/freeswan -I$(ROOTDIR)/freeswan/lib \
+			-I$(ROOTDIR)/freeswan/klips/net/ipsec \
+			-I$(ROOTDIR)/freeswan/libdes
+
+ifdef CONFIG_IXP4XX_CRYPTO
+vpath %.h $(ROOTDIR)/freeswan/klips/net/ipsec_xscale:$(ROOTDIR)/freeswan/klips/net/ipsec
+else
+vpath %.h $(ROOTDIR)/freeswan/klips/net/ipsec
+endif
+
+ifdef CONFIG_IXP4XX_CRYPTO
+%.c: $(ROOTDIR)/freeswan/klips/net/ipsec_xscale/%.c
+	ln -fs $< $@
+endif
+
+# special hack required because of exported object files
+%.c: $(ROOTDIR)/freeswan/klips/net/ipsec/%.c
+	ln -fs $< $@
+
+include $(ROOTDIR)/freeswan/klips/net/ipsec/Makefile
+
+else
+
+fastdep:
+
+endif
+endif
diff -urN linux-2.4.29/net/ipsec/zlib/Makefile linux-2.4.29-uc1/net/ipsec/zlib/Makefile
--- linux-2.4.29/net/ipsec/zlib/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipsec/zlib/Makefile	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,9 @@
+
+.EXPORT_ALL_VARIABLES:
+
+EXTRA_CFLAGS += -I$(ROOTDIR)/freeswan/zlib -DNO_ERRNO_H
+
+VPATH = $(ROOTDIR)/freeswan/zlib
+
+include $(ROOTDIR)/freeswan/zlib/Makefile
+
diff -urN linux-2.4.29/net/ipv4/af_inet.c linux-2.4.29-uc1/net/ipv4/af_inet.c
--- linux-2.4.29/net/ipv4/af_inet.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/af_inet.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: af_inet.c,v 1.16 2003/11/12 05:12:00 yoshfuji Exp $ */
+
 /*
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
@@ -724,6 +726,7 @@
 		sin->sin_port = sk->sport;
 		sin->sin_addr.s_addr = addr;
 	}
+	memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
 	*uaddr_len = sizeof(*sin);
 	return(0);
 }
@@ -1207,6 +1210,27 @@
 	ip_mr_init();
 #endif
 
+#if defined(CONFIG_IPSEC)
+	{
+               extern /* void */ int ipsec_init(void);
+		/*
+		 *  Initialise AF_INET ESP and AH protocol support including 
+		 *  e-routing and SA tables
+		 */
+		ipsec_init();
+	}
+#endif /* CONFIG_IPSEC */
+#if defined(CONFIG_KLIPS)
+	{
+               extern /* void */ int ipsec_klips_init(void);
+		/*
+		 *  Initialise AF_INET ESP and AH protocol support including 
+		 *  e-routing and SA tables
+		 */
+		ipsec_klips_init();
+	}
+#endif /* CONFIG_KLIPS */
+
 	/*
 	 *	Create all the /proc entries.
 	 */
diff -urN linux-2.4.29/net/ipv4/arp.c linux-2.4.29-uc1/net/ipv4/arp.c
--- linux-2.4.29/net/ipv4/arp.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/arp.c	2005-06-14 02:11:50.000000000 +0100
@@ -353,12 +353,13 @@
 	if (!saddr)
 		saddr = inet_select_addr(dev, target, RT_SCOPE_LINK);
 
+	read_lock_bh(&neigh->lock);
 	if ((probes -= neigh->parms->ucast_probes) < 0) {
 		if (!(neigh->nud_state&NUD_VALID))
 			printk(KERN_DEBUG "trying to ucast probe in NUD_INVALID\n");
 		dst_ha = neigh->ha;
-		read_lock_bh(&neigh->lock);
 	} else if ((probes -= neigh->parms->app_probes) < 0) {
+		read_unlock_bh(&neigh->lock);
 #ifdef CONFIG_ARPD
 		neigh_app_ns(neigh);
 #endif
@@ -367,8 +368,7 @@
 
 	arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
 		 dst_ha, dev->dev_addr, NULL);
-	if (dst_ha)
-		read_unlock_bh(&neigh->lock);
+	read_unlock_bh(&neigh->lock);
 }
 
 static int arp_ignore(struct in_device *in_dev, struct net_device *dev,
@@ -457,6 +457,7 @@
 	struct net_device *dev = skb->dev;
 	u32 paddr;
 	struct neighbour *n;
+	int free_skb = 0, ret = 0;
 
 	if (!skb->dst) {
 		printk(KERN_DEBUG "arp_find is called with dst==NULL\n");
@@ -472,18 +473,34 @@
 	n = __neigh_lookup(&arp_tbl, &paddr, dev, 1);
 
 	if (n) {
+		int copy = 0;
+		write_lock_bh(&n->lock);
 		n->used = jiffies;
-		if (n->nud_state&NUD_VALID || neigh_event_send(n, skb) == 0) {
-			read_lock_bh(&n->lock);
- 			memcpy(haddr, n->ha, dev->addr_len);
-			read_unlock_bh(&n->lock);
-			neigh_release(n);
-			return 0;
+		if (n->nud_state&NUD_VALID) {
+			copy = 1;
+			ret = 0;
+			free_skb = 0;
+		} else {
+			int ne_ret = __neigh_event_send(n, skb);
+			if (ne_ret == 0) {
+				copy = 1;
+				ret = 0;
+			} else if (ne_ret < 0) {
+				free_skb = 1;
+				ret = 1;
+			} else {
+				ret = 1;
+			}
 		}
+		if (copy)
+			memcpy(haddr, n->ha, dev->addr_len);
+		write_unlock_bh(&n->lock);
 		neigh_release(n);
 	} else
+		ret = 1;
+	if (free_skb)
 		kfree_skb(skb);
-	return 1;
+	return ret;
 }
 
 /* END OF OBSOLETE FUNCTIONS */
@@ -925,6 +942,16 @@
 		if (arp->ar_op != htons(ARPOP_REPLY) ||
 		    skb->pkt_type != PACKET_HOST)
 			state = NUD_STALE;
+#ifdef CONFIG_NET_ARP_LIMIT
+		if ((arp_tbl.entries > CONFIG_ARP_LIMIT) && !(n->nud_state & NUD_PERMANENT)) {
+			printk(KERN_ERR "***** ARP limit reached ****\n");
+			printk(KERN_ERR "* ignoring %u.%u.%u.%u *\n", 
+				NIPQUAD(*(u32*)n->primary_key));
+			state = NUD_FAILED;
+			override = 1;
+		} else
+			state |= NUD_PERMANENT;
+#endif
 		neigh_update(n, sha, state, override, 1);
 		neigh_release(n);
 	}
diff -urN linux-2.4.29/net/ipv4/Config.in linux-2.4.29-uc1/net/ipv4/Config.in
--- linux-2.4.29/net/ipv4/Config.in	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/Config.in	2005-06-14 02:11:49.000000000 +0100
@@ -1,3 +1,5 @@
+# $USAGI: Config.in,v 1.12 2003/11/12 05:12:00 yoshfuji Exp $
+
 #
 # IP configuration
 #
@@ -5,6 +7,7 @@
 bool '  IP: advanced router' CONFIG_IP_ADVANCED_ROUTER
 if [ "$CONFIG_IP_ADVANCED_ROUTER" = "y" ]; then
    bool '    IP: policy routing' CONFIG_IP_MULTIPLE_TABLES
+   bool '    IP: increase default route cache size' CONFIG_IP_ROUTE_BIG_RT_CACHE
    if [ "$CONFIG_IP_MULTIPLE_TABLES" = "y" ]; then
       if [ "$CONFIG_NETFILTER" = "y" ]; then
          bool '      IP: use netfilter MARK value as routing key' CONFIG_IP_ROUTE_FWMARK
@@ -12,6 +15,7 @@
       bool '      IP: fast network address translation' CONFIG_IP_ROUTE_NAT
    fi
    bool '    IP: equal cost multipath' CONFIG_IP_ROUTE_MULTIPATH
+   dep_bool '      IP: Use sequential path selection.' CONFIG_IP_ROUTE_MULTIPATH_SEQUENTIAL $CONFIG_IP_ROUTE_MULTIPATH
    bool '    IP: use TOS value as routing key' CONFIG_IP_ROUTE_TOS
    bool '    IP: verbose route monitoring' CONFIG_IP_ROUTE_VERBOSE
 fi
@@ -23,7 +27,16 @@
 # not yet ready..
 #   bool '    IP: ARP support' CONFIG_IP_PNP_ARP		
 fi
+bool 'ARP MAC Limiting' CONFIG_NET_ARP_LIMIT
+if [ "$CONFIG_NET_ARP_LIMIT" = "y" ]; then
+   int 'Maximum number of MAC addresses' CONFIG_ARP_LIMIT 20
+fi
 tristate '  IP: tunneling' CONFIG_NET_IPIP
+if [ "$CONFIG_NET_IPIP" = "y" ]; then
+   if [ "$CONFIG_IPV6" != "n" ]; then
+      bool '    IP: IPv6 over IPv4 tunneling support (replaces sitXX devices)' CONFIG_NET_IPIP_IPV6
+   fi
+fi
 tristate '  IP: GRE tunnels over IP' CONFIG_NET_IPGRE
 if [ "$CONFIG_IP_MULTICAST" = "y" ]; then
    if [ "$CONFIG_NET_IPGRE" != "n" ]; then
@@ -40,6 +53,7 @@
 fi
 bool '  IP: TCP Explicit Congestion Notification support' CONFIG_INET_ECN
 bool '  IP: TCP syncookie support (disabled per default)' CONFIG_SYN_COOKIES
+
 if [ "$CONFIG_NETFILTER" != "n" ]; then
    source net/ipv4/netfilter/Config.in
 fi
diff -urN linux-2.4.29/net/ipv4/fib_semantics.c linux-2.4.29-uc1/net/ipv4/fib_semantics.c
--- linux-2.4.29/net/ipv4/fib_semantics.c	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/fib_semantics.c	2005-06-14 02:11:49.000000000 +0100
@@ -102,6 +102,9 @@
 	{ -EINVAL, RT_SCOPE_NOWHERE}	/* RTN_XRESOLVE */
 };
 
+#ifdef CONFIG_IP_ROUTE_MULTIPATH_SEQUENTIAL
+unsigned int mp_counter=0;
+#endif
 
 /* Release a nexthop info record */
 
@@ -977,7 +980,11 @@
 	   it is pretty bad approximation.
 	 */
 
+#ifdef CONFIG_IP_ROUTE_MULTIPATH_SEQUENTIAL
+	w = mp_counter++ % fi->fib_power;
+#else
 	w = jiffies % fi->fib_power;
+#endif
 
 	change_nexthops(fi) {
 		if (!(nh->nh_flags&RTNH_F_DEAD) && nh->nh_power) {
diff -urN linux-2.4.29/net/ipv4/ipconfig.c linux-2.4.29-uc1/net/ipv4/ipconfig.c
--- linux-2.4.29/net/ipv4/ipconfig.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/ipconfig.c	2005-06-14 02:11:49.000000000 +0100
@@ -107,7 +107,7 @@
  */
 int ic_set_manually __initdata = 0;		/* IPconfig parameters set manually */
 
-int ic_enable __initdata = 0;			/* IP config enabled? */
+int ic_enable __initdata = 1;			/* IP config enabled? */
 
 /* Protocol choice */
 int ic_proto_enabled __initdata = 0
@@ -1177,6 +1177,9 @@
 {
 	unsigned long jiff;
 	u32 addr;
+#ifdef IPCONFIG_DYNAMIC
+	int retries = CONF_OPEN_RETRIES;
+#endif
 
 #ifdef CONFIG_PROC_FS
 	proc_net_create("pnp", 0, pnp_get_info);
@@ -1218,9 +1221,6 @@
 #endif
 	    ic_first_dev->next) {
 #ifdef IPCONFIG_DYNAMIC
-
-		int retries = CONF_OPEN_RETRIES;
-
 		if (ic_dynamic() < 0) {
 			ic_close_devs();
 
diff -urN linux-2.4.29/net/ipv4/ip_gre.c linux-2.4.29-uc1/net/ipv4/ip_gre.c
--- linux-2.4.29/net/ipv4/ip_gre.c	2004-08-08 00:26:06.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/ip_gre.c	2005-06-14 02:11:49.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: ip_gre.c,v 1.17 2003/11/12 05:12:00 yoshfuji Exp $ */
+
 /*
  *	Linux NET3:	GRE over IP protocol decoder. 
  *
@@ -18,6 +20,7 @@
 #include <asm/uaccess.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/etherdevice.h>
 #include <linux/in.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
@@ -38,7 +41,7 @@
 #include <net/checksum.h>
 #include <net/inet_ecn.h>
 
-#ifdef CONFIG_IPV6
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 #include <net/ipv6.h>
 #include <net/ip6_fib.h>
 #include <net/ip6_route.h>
@@ -119,6 +122,14 @@
 
 static int ipgre_fb_tunnel_init(struct net_device *dev);
 
+
+/*
+ * we need a special function to be able to be able to pull the ethernet
+ * buffer out.  It is nearly the same as the eth_type_trans structure except
+ * the header size is adjusted.
+ */
+unsigned short gre_eth_type_trans(struct sk_buff *skb, struct net_device *dev);
+
 static struct net_device ipgre_fb_tunnel_dev = {
 	"gre0", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, ipgre_fb_tunnel_init,
 };
@@ -193,11 +204,11 @@
 	return NULL;
 }
 
-static struct ip_tunnel **ipgre_bucket(struct ip_tunnel *t)
+static __inline__ struct ip_tunnel **__ipgre_bucket(struct ip_tunnel_parm *parms)
 {
-	u32 remote = t->parms.iph.daddr;
-	u32 local = t->parms.iph.saddr;
-	u32 key = t->parms.i_key;
+	u32 remote = parms->iph.daddr;
+	u32 local = parms->iph.saddr;
+	u32 key = parms->i_key;
 	unsigned h = HASH(key);
 	int prio = 0;
 
@@ -211,6 +222,11 @@
 	return &tunnels[prio][h];
 }
 
+static struct ip_tunnel **ipgre_bucket(struct ip_tunnel *t)
+{
+	return __ipgre_bucket(&t->parms);
+}
+
 static void ipgre_tunnel_link(struct ip_tunnel *t)
 {
 	struct ip_tunnel **tp = ipgre_bucket(t);
@@ -242,16 +258,8 @@
 	u32 key = parms->i_key;
 	struct ip_tunnel *t, **tp, *nt;
 	struct net_device *dev;
-	unsigned h = HASH(key);
-	int prio = 0;
 
-	if (local)
-		prio |= 1;
-	if (remote && !MULTICAST(remote)) {
-		prio |= 2;
-		h ^= HASH(remote);
-	}
-	for (tp = &tunnels[prio][h]; (t = *tp) != NULL; tp = &t->next) {
+	for (tp = __ipgre_bucket(parms); (t = *tp) != NULL; tp = &t->next) {
 		if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) {
 			if (key == t->parms.i_key)
 				return t;
@@ -556,6 +564,10 @@
 	return INET_ECN_encapsulate(tos, inner);
 }
 
+
+void
+br_stp_do_bpdu_lock(struct sk_buff *skb);
+
 int ipgre_rcv(struct sk_buff *skb)
 {
 	struct iphdr *iph;
@@ -566,6 +578,7 @@
 	u32    seqno = 0;
 	struct ip_tunnel *tunnel;
 	int    offset = 4;
+	unsigned short 	proto;
 
 	if (!pskb_may_pull(skb, 16))
 		goto drop_nolock;
@@ -573,6 +586,7 @@
 	iph = skb->nh.iph;
 	h = skb->data;
 	flags = *(u16*)h;
+	proto = *(u16*)(h+2);
 
 	if (flags&(GRE_CSUM|GRE_KEY|GRE_ROUTING|GRE_SEQ|GRE_VERSION)) {
 		/* - Version must be 0.
@@ -606,23 +620,6 @@
 
 	read_lock(&ipgre_lock);
 	if ((tunnel = ipgre_tunnel_lookup(iph->saddr, iph->daddr, key)) != NULL) {
-		skb->mac.raw = skb->nh.raw;
-		skb->nh.raw = __pskb_pull(skb, offset);
-		memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
-		if (skb->ip_summed == CHECKSUM_HW)
-			skb->csum = csum_sub(skb->csum,
-					     csum_partial(skb->mac.raw, skb->nh.raw-skb->mac.raw, 0));
-		skb->protocol = *(u16*)(h + 2);
-		skb->pkt_type = PACKET_HOST;
-#ifdef CONFIG_NET_IPGRE_BROADCAST
-		if (MULTICAST(iph->daddr)) {
-			/* Looped back packet, drop it! */
-			if (((struct rtable*)skb->dst)->key.iif == 0)
-				goto drop;
-			tunnel->stat.multicast++;
-			skb->pkt_type = PACKET_BROADCAST;
-		}
-#endif
 
 		if (((flags&GRE_CSUM) && csum) ||
 		    (!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) {
@@ -639,6 +636,65 @@
 			}
 			tunnel->i_seqno = seqno + 1;
 		}
+
+#if defined(CONFIG_BRIDGE)
+		if (tunnel->dev->br_port != NULL) {
+			if (proto == GRE_P_ETH_BR) {
+
+				/* Pull off the offset. */
+				skb->mac.raw = __pskb_pull(skb, offset);
+
+				/* ensure it is linear so we can simply copy the data out */
+				skb_linearize(skb, GFP_ATOMIC);
+
+				skb->protocol = gre_eth_type_trans(skb, tunnel->dev);
+			} else if (proto == GRE_P_BPDU) {
+
+				if (!skb_pull(skb, offset)) {
+					goto drop;
+				}
+
+				skb->dev = tunnel->dev;
+				dst_release(skb->dst);
+				skb->dst = NULL;
+#ifdef CONFIG_NETFILTER
+				nf_conntrack_put(skb->nfct);
+				skb->nfct = NULL;
+#ifdef CONFIG_NETFILTER_DEBUG
+				skb->nf_debug = 0;
+#endif
+#endif
+
+				br_stp_do_bpdu_lock(skb);
+				tunnel->stat.rx_packets++;
+				tunnel->stat.rx_bytes += skb->len;
+				goto drop;
+
+			} else {
+				tunnel->stat.rx_errors++;
+				goto drop;
+			}
+		} else
+#endif
+		{
+		 	skb->mac.raw = skb->nh.raw;
+			skb->nh.raw = __pskb_pull(skb, offset);
+			memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+			if (skb->ip_summed == CHECKSUM_HW)
+				skb->csum = csum_sub(skb->csum,
+							 csum_partial(skb->mac.raw, skb->nh.raw-skb->mac.raw, 0));
+			skb->protocol = *(u16*)(h + 2);
+			skb->pkt_type = PACKET_HOST;
+#ifdef CONFIG_NET_IPGRE_BROADCAST
+			if (MULTICAST(iph->daddr)) {
+				/* Looped back packet, drop it! */
+				if (((struct rtable*)skb->dst)->key.iif == 0)
+					goto drop;
+				tunnel->stat.multicast++;
+				skb->pkt_type = PACKET_BROADCAST;
+			}
+#endif
+		}
 		tunnel->stat.rx_packets++;
 		tunnel->stat.rx_bytes += skb->len;
 		skb->dev = tunnel->dev;
@@ -681,6 +737,8 @@
 	u32    dst;
 	int    mtu;
 
+//	printk(KERN_INFO "xmit - %d\n", skb->len);
+
 	if (tunnel->recursion++) {
 		tunnel->stat.collisions++;
 		goto tx_error;
@@ -707,30 +765,24 @@
 			if ((dst = rt->rt_gateway) == 0)
 				goto tx_error_icmp;
 		}
-#ifdef CONFIG_IPV6
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 		else if (skb->protocol == htons(ETH_P_IPV6)) {
 			struct in6_addr *addr6;
-			int addr_type;
 			struct neighbour *neigh = skb->dst->neighbour;
 
 			if (neigh == NULL)
 				goto tx_error;
 
 			addr6 = (struct in6_addr*)&neigh->primary_key;
-			addr_type = ipv6_addr_type(addr6);
-
-			if (addr_type == IPV6_ADDR_ANY) {
+			if (IN6_IS_ADDR_UNSPECIFIED(addr6))
 				addr6 = &skb->nh.ipv6h->daddr;
-				addr_type = ipv6_addr_type(addr6);
-			}
-
-			if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
+			if (!IN6_IS_ADDR_V4COMPAT(addr6))
 				goto tx_error_icmp;
 
 			dst = addr6->s6_addr32[3];
 		}
 #endif
-		else
+		else 
 			goto tx_error;
 	}
 
@@ -759,38 +811,60 @@
 	else
 		mtu = skb->dst ? skb->dst->pmtu : dev->mtu;
 
-	if (skb->protocol == htons(ETH_P_IP)) {
-		if (skb->dst && mtu < skb->dst->pmtu && mtu >= 68)
-			skb->dst->pmtu = mtu;
-
-		df |= (old_iph->frag_off&htons(IP_DF));
-
-		if ((old_iph->frag_off&htons(IP_DF)) &&
-		    mtu < ntohs(old_iph->tot_len)) {
-			icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
-			ip_rt_put(rt);
-			goto tx_error;
-		}
-	}
-#ifdef CONFIG_IPV6
-	else if (skb->protocol == htons(ETH_P_IPV6)) {
-		struct rt6_info *rt6 = (struct rt6_info*)skb->dst;
-
-		if (rt6 && mtu < rt6->u.dst.pmtu && mtu >= IPV6_MIN_MTU) {
-			if ((tunnel->parms.iph.daddr && !MULTICAST(tunnel->parms.iph.daddr)) ||
-			    rt6->rt6i_dst.plen == 128) {
-				rt6->rt6i_flags |= RTF_MODIFIED;
+	/*
+	 * If we are not being used as an ethernet bridge, then we want to
+	 * honour fragmentation stuff.
+	 */
+	if (!dev->br_port) {
+		if (skb->protocol == __constant_htons(ETH_P_IP)) {
+			if (skb->dst && mtu < skb->dst->pmtu && mtu >= 68)
 				skb->dst->pmtu = mtu;
+
+			df |= (old_iph->frag_off&__constant_htons(IP_DF));
+
+			if ((old_iph->frag_off&__constant_htons(IP_DF)) &&
+				mtu < ntohs(old_iph->tot_len)) {
+				icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
+				ip_rt_put(rt);
+				goto tx_error;
 			}
 		}
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+		else if (skb->protocol == __constant_htons(ETH_P_IPV6)) {
+			struct rt6_info *rt6 = (struct rt6_info*)skb->dst;
+#if defined(CONFIG_IPV6_MODULE_IP_GRE) && !defined(CONFIG_IPV6)
+			void (*icmpv6_send)(struct sk_buff *skb,
+					int type, int code,
+					__u32 info,
+					struct net_device *dev) = inter_module_get(IM_ICMPV6_SEND);
+			if (!icmpv6_send)
+				goto skip_ipv6;
+#endif
+			if (rt6 && mtu < rt6->u.dst.pmtu && mtu >= IPV6_MIN_MTU) {
+				if ((tunnel->parms.iph.daddr && !MULTICAST(tunnel->parms.iph.daddr)) ||
+					rt6->rt6i_dst.plen == 128) {
+					rt6->rt6i_flags |= RTF_MODIFIED;
+					skb->dst->pmtu = mtu;
+				}
+			}
 
-		if (mtu >= IPV6_MIN_MTU && mtu < skb->len - tunnel->hlen + gre_hlen) {
-			icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
-			ip_rt_put(rt);
-			goto tx_error;
+			if (mtu >= IPV6_MIN_MTU && mtu < skb->len - tunnel->hlen + gre_hlen) {
+#ifdef CONFIG_IPV6
+				icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
+#elif defined(CONFIG_IPV6_MODULE_IP_GRE)
+				(*icmpv6_send)(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
+				inter_module_put(IM_ICMPV6_SEND);
+#endif
+				ip_rt_put(rt);
+				goto tx_error;
+			}
+#if defined(CONFIG_IPV6_MODULE_IP_GRE) && !defined(CONFIG_IPV6)
+			inter_module_put(IM_ICMPV6_SEND);
+skip_ipv6:
+#endif
 		}
-	}
 #endif
+	}
 
 	if (tunnel->err_count > 0) {
 		if (jiffies - tunnel->err_time < IPTUNNEL_ERR_TIMEO) {
@@ -801,6 +875,11 @@
 			tunnel->err_count = 0;
 	}
 
+	/*
+	 * This is only the case for ethernet frames!!
+	 */
+	skb->h.raw = skb->mac.raw;
+
 	max_headroom = ((tdev->hard_header_len+15)&~15)+ gre_hlen;
 
 	if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
@@ -824,6 +903,7 @@
 	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
 	dst_release(skb->dst);
 	skb->dst = &rt->u.dst;
+//	printk("%d-%s", skb->len, rt->u.dst.dev->name);
 
 	/*
 	 *	Push down and install the IPIP header.
@@ -832,7 +912,7 @@
 	iph 			=	skb->nh.iph;
 	iph->version		=	4;
 	iph->ihl		=	sizeof(struct iphdr) >> 2;
-	iph->frag_off		=	df;
+	iph->frag_off		=	0;//__constant_htons(IP_DF);
 	iph->protocol		=	IPPROTO_GRE;
 	iph->tos		=	ipgre_ecn_encapsulate(tos, old_iph, skb);
 	iph->daddr		=	rt->rt_dst;
@@ -840,8 +920,13 @@
 
 	if ((iph->ttl = tiph->ttl) == 0) {
 		if (skb->protocol == htons(ETH_P_IP))
+#ifdef CONFIG_NEXTEP
+			if (skb->nf_bridge != NULL)
+				iph->ttl = IPDEFTTL;
+			else
+#endif
 			iph->ttl = old_iph->ttl;
-#ifdef CONFIG_IPV6
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 		else if (skb->protocol == htons(ETH_P_IPV6))
 			iph->ttl = ((struct ipv6hdr*)old_iph)->hop_limit;
 #endif
@@ -850,7 +935,11 @@
 	}
 
 	((u16*)(iph+1))[0] = tunnel->parms.o_flags;
-	((u16*)(iph+1))[1] = skb->protocol;
+
+	if (dev->br_port)
+		((u16*)(iph+1))[1] = GRE_P_ETH_BR;
+	else
+		((u16*)(iph+1))[1] = skb->protocol;
 
 	if (tunnel->parms.o_flags&(GRE_KEY|GRE_CSUM|GRE_SEQ)) {
 		u32 *ptr = (u32*)(((u8*)iph) + tunnel->hlen - 4);
@@ -1243,6 +1332,63 @@
 	return 0;
 }
 
+unsigned short gre_eth_type_trans(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ethhdr *eth;
+	unsigned char *rawp;
+
+	skb->mac.raw=skb->data;
+
+	/*
+	 * hack - we don't actually want to pull the hard header length, we
+	 * want to pull the ethernet frame header.
+	 */
+	skb_pull(skb, ETH_HLEN);
+	eth= skb->mac.ethernet;
+	
+	if(*eth->h_dest&1)
+	{
+		if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
+			skb->pkt_type=PACKET_BROADCAST;
+		else
+			skb->pkt_type=PACKET_MULTICAST;
+	}
+	
+	/*
+	 *	This ALLMULTI check should be redundant by 1.4
+	 *	so don't forget to remove it.
+	 *
+	 *	Seems, you forgot to remove it. All silly devices
+	 *	seems to set IFF_PROMISC.
+	 */
+	 
+	else if(1 /*dev->flags&IFF_PROMISC*/)
+	{
+		if(memcmp(eth->h_dest,dev->dev_addr, ETH_ALEN))
+			skb->pkt_type=PACKET_OTHERHOST;
+	}
+	
+	if (ntohs(eth->h_proto) >= 1536)
+		return eth->h_proto;
+		
+	rawp = skb->data;
+	
+	/*
+	 *	This is a magic hack to spot IPX packets. Older Novell breaks
+	 *	the protocol design and runs IPX over 802.3 without an 802.2 LLC
+	 *	layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
+	 *	won't work for fault tolerant netware but does for the rest.
+	 */
+	if (*(unsigned short *)rawp == 0xFFFF)
+		return htons(ETH_P_802_3);
+		
+	/*
+	 *	Real 802.2 LLC
+	 */
+	return htons(ETH_P_802_2);
+	
+}
+
 
 static struct inet_protocol ipgre_protocol = {
   ipgre_rcv,             /* GRE handler          */
diff -urN linux-2.4.29/net/ipv4/ipip.c linux-2.4.29-uc1/net/ipv4/ipip.c
--- linux-2.4.29/net/ipv4/ipip.c	2004-08-08 00:26:06.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/ipip.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: ipip.c,v 1.36 2003/11/21 20:13:13 yoshfuji Exp $ */
+
 /*
  *	Linux NET3:	IP/IP protocol decoder. 
  *
@@ -18,6 +20,7 @@
  *              Carlos Picoto   :       GRE over IP support
  *		Alexey Kuznetsov:	Reworked. Really, now it is truncated version of ipv4/ip_gre.c.
  *					I do not want to merge them together.
+ *		Fred L. Templin	:	isatap support.
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -104,11 +107,16 @@
 #include <linux/in.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
+#include <linux/icmpv6.h>
 #include <linux/if_arp.h>
 #include <linux/mroute.h>
 #include <linux/init.h>
 #include <linux/netfilter_ipv4.h>
 
+#ifdef CONFIG_NET_IPIP_IPV6
+#include <net/ipv6.h>
+#include <net/addrconf.h>
+#endif
 #include <net/sock.h>
 #include <net/ip.h>
 #include <net/icmp.h>
@@ -138,9 +146,15 @@
 static struct ip_tunnel *tunnels_wc[1];
 static struct ip_tunnel **tunnels[4] = { tunnels_wc, tunnels_l, tunnels_r, tunnels_r_l };
 
-static rwlock_t ipip_lock = RW_LOCK_UNLOCKED;
+#ifndef CONFIG_NET_IPIP_IPV6
+static
+#endif
+rwlock_t ipip_lock = RW_LOCK_UNLOCKED;
 
-static struct ip_tunnel * ipip_tunnel_lookup(u32 remote, u32 local)
+#ifndef CONFIG_NET_IPIP_IPV6
+static
+#endif
+struct ip_tunnel * ipip_tunnel_lookup(u32 remote, u32 local)
 {
 	unsigned h0 = HASH(remote);
 	unsigned h1 = HASH(local);
@@ -164,10 +178,10 @@
 	return NULL;
 }
 
-static struct ip_tunnel **ipip_bucket(struct ip_tunnel *t)
+static __inline__ struct ip_tunnel **__ipip_bucket(struct ip_tunnel_parm *parms)
 {
-	u32 remote = t->parms.iph.daddr;
-	u32 local = t->parms.iph.saddr;
+	u32 remote = parms->iph.daddr;
+	u32 local = parms->iph.saddr;
 	unsigned h = 0;
 	int prio = 0;
 
@@ -182,6 +196,10 @@
 	return &tunnels[prio][h];
 }
 
+static struct ip_tunnel **ipip_bucket(struct ip_tunnel *t)
+{
+	return __ipip_bucket(&t->parms);
+}
 
 static void ipip_tunnel_unlink(struct ip_tunnel *t)
 {
@@ -213,18 +231,8 @@
 	u32 local = parms->iph.saddr;
 	struct ip_tunnel *t, **tp, *nt;
 	struct net_device *dev;
-	unsigned h = 0;
-	int prio = 0;
 
-	if (remote) {
-		prio |= 2;
-		h ^= HASH(remote);
-	}
-	if (local) {
-		prio |= 1;
-		h ^= HASH(local);
-	}
-	for (tp = &tunnels[prio][h]; (t = *tp) != NULL; tp = &t->next) {
+	for (tp = __ipip_bucket(parms); (t = *tp) != NULL; tp = &t->next) {
 		if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr)
 			return t;
 	}
@@ -464,6 +472,10 @@
 #endif
 }
 
+#ifdef CONFIG_NET_IPIP_IPV6
+extern void ipip6_err(struct sk_buff *skb, u32 info);
+#endif
+
 static inline void ipip_ecn_decapsulate(struct iphdr *outer_iph, struct sk_buff *skb)
 {
 	struct iphdr *inner_iph = skb->nh.iph;
@@ -477,19 +489,45 @@
 {
 	struct iphdr *iph;
 	struct ip_tunnel *tunnel;
+	u16 proto;
+	int hdrlen;
 
-	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+	switch(skb->nh.iph->protocol) {
+	case IPPROTO_IPIP:
+		proto = htons(ETH_P_IP);
+		hdrlen = sizeof(struct iphdr);
+		break;
+#ifdef CONFIG_NET_IPIP_IPV6
+	case IPPROTO_IPV6:
+		proto = htons(ETH_P_IPV6);
+		hdrlen = sizeof(struct ipv6hdr);
+		break;
+#endif
+	default:
+		if (net_ratelimit())
+			printk(KERN_WARNING
+				"ipip_rcv(): unsupported protocol (%u)\n",
+				skb->nh.iph->protocol);
+		goto protounreach;
+	}
+
+	if (!pskb_may_pull(skb, hdrlen))
 		goto out;
 
 	iph = skb->nh.iph;
 	skb->mac.raw = skb->nh.raw;
 	skb->nh.raw = skb->data;
 	memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
-	skb->protocol = htons(ETH_P_IP);
+	skb->protocol = proto;
 	skb->pkt_type = PACKET_HOST;
 
 	read_lock(&ipip_lock);
 	if ((tunnel = ipip_tunnel_lookup(iph->saddr, iph->daddr)) != NULL) {
+		if (tunnel->parms.iph.protocol != 0 &&
+		    tunnel->parms.iph.protocol != iph->protocol) {
+			read_unlock(&ipip_lock);
+			goto protounreach;
+		}
 		tunnel->stat.rx_packets++;
 		tunnel->stat.rx_bytes += skb->len;
 		skb->dev = tunnel->dev;
@@ -502,13 +540,17 @@
 		return 0;
 	}
 	read_unlock(&ipip_lock);
-
+protounreach:
 	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0);
 out:
 	kfree_skb(skb);
 	return 0;
 }
 
+#ifdef CONFIG_NET_IPIP_IPV6
+extern int ipip6_rcv(struct sk_buff *skb);
+#endif
+
 /* Need this wrapper because NF_HOOK takes the function address */
 static inline int do_ip_send(struct sk_buff *skb)
 {
@@ -530,29 +572,92 @@
 	struct rtable *rt;     			/* Route to the other host */
 	struct net_device *tdev;			/* Device to other host */
 	struct iphdr  *old_iph = skb->nh.iph;
+#ifdef CONFIG_NET_IPIP_IPV6
+	struct ipv6hdr *iph6 = skb->nh.ipv6h;
+#endif
 	struct iphdr  *iph;			/* Our new IP header */
 	int    max_headroom;			/* The extra header space needed */
 	u32    dst = tiph->daddr;
 	int    mtu;
+	u8 protocol = 0; 
+
+	switch (skb->protocol) {
+	case __constant_htons(ETH_P_IP):
+		protocol = IPPROTO_IPIP;
+		break;
+#ifdef CONFIG_NET_IPIP_IPV6
+	case __constant_htons(ETH_P_IPV6):
+		protocol = IPPROTO_IPV6;
+		break;
+#endif
+	}
 
 	if (tunnel->recursion++) {
 		tunnel->stat.collisions++;
 		goto tx_error;
 	}
 
-	if (skb->protocol != htons(ETH_P_IP))
+	switch(skb->protocol) {
+	case __constant_htons(ETH_P_IP):
+		if (tunnel->parms.iph.protocol &&
+		    tunnel->parms.iph.protocol != IPPROTO_IPIP)
+			goto tx_error;
+		if (tos&1)
+			tos = old_iph->tos;
+		break;
+#ifdef CONFIG_NET_IPIP_IPV6
+	case __constant_htons(ETH_P_IPV6):
+		if (tunnel->parms.iph.protocol &&
+		    tunnel->parms.iph.protocol != IPPROTO_IPV6)
+			goto tx_error;
+		break;
+#endif
+	default:
 		goto tx_error;
-
-	if (tos&1)
-		tos = old_iph->tos;
+	}
 
 	if (!dst) {
-		/* NBMA tunnel */
-		if ((rt = (struct rtable*)skb->dst) == NULL) {
-			tunnel->stat.tx_fifo_errors++;
-			goto tx_error;
+		switch(skb->protocol){
+		case __constant_htons(ETH_P_IP):
+			/* NBMA tunnel */
+			if ((rt = (struct rtable*)skb->dst) == NULL) {
+				tunnel->stat.tx_fifo_errors++;
+				goto tx_error;
+			}
+			dst = rt->rt_gateway;
+			break;
+#ifdef CONFIG_NET_IPIP_IPV6
+		case __constant_htons(ETH_P_IPV6):
+		    {
+			struct in6_addr *addr6 = &iph6->daddr;
+			if (addr6->s6_addr16[0] == htons(0x2002)) {
+				memcpy(&dst, &addr6->s6_addr16[1], 4);
+			} else {
+				/* dst is zero */
+				struct neighbour *neigh = NULL;
+				if (skb->dst)
+					neigh = skb->dst->neighbour;
+				if (neigh == NULL) {
+					printk(KERN_DEBUG "tunl: nexthop == NULL\n");
+					goto tx_error;
+				}
+				addr6 = (struct in6_addr*)&neigh->primary_key;
+				if (IN6_IS_ADDR_UNSPECIFIED(addr6))
+					addr6 = &skb->nh.ipv6h->daddr;
+				if (IN6_IS_ADDR_V4COMPAT(addr6))
+					dst = addr6->s6_addr32[3];
+#ifdef CONFIG_IPV6_6TO4_NEXTHOP
+				else if (addr6->s6_addr16[0] == htons(0x2002)) 
+					memcpy(&dst, &addr6->s6_addr16[1], 4);
+#endif
+				else
+					goto tx_error_icmp;
+			}
+			break;
+		    }
+#endif
 		}
-		if ((dst = rt->rt_gateway) == 0)
+		if (!dst)
 			goto tx_error_icmp;
 	}
 
@@ -578,17 +683,39 @@
 		ip_rt_put(rt);
 		goto tx_error;
 	}
-	if (skb->dst && mtu < skb->dst->pmtu)
-		skb->dst->pmtu = mtu;
 
-	df |= (old_iph->frag_off&htons(IP_DF));
+	switch(skb->protocol){
+	case __constant_htons(ETH_P_IP):
+		if (skb->dst && mtu < skb->dst->pmtu)
+			skb->dst->pmtu = mtu;
 
-	if ((old_iph->frag_off&htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) {
-		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
-		ip_rt_put(rt);
-		goto tx_error;
-	}
+		df |= (old_iph->frag_off&htons(IP_DF));
 
+		if ((old_iph->frag_off&htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) {
+			icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
+			ip_rt_put(rt);
+			goto tx_error;
+		}
+		break;
+
+#ifdef CONFIG_NET_IPIP_IPV6
+	case __constant_htons(ETH_P_IPV6):
+#if 0
+		if (mtu < IPV6_MIN_MTU) {
+			/* XXX: too small; we should fragment this packet? */
+			tunnel->stat.tx_carrier_errors++;
+			goto tx_error_icmp;
+		}
+#endif
+		if (skb->len > mtu && mtu > IPV6_MIN_MTU) {
+			icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
+			ip_rt_put(rt);
+			goto tx_error;
+		}
+		df = mtu > IPV6_MIN_MTU ? htons(IP_DF) : 0;
+		break;
+#endif
+	}
 	if (tunnel->err_count > 0) {
 		if (jiffies - tunnel->err_time < IPTUNNEL_ERR_TIMEO) {
 			tunnel->err_count--;
@@ -601,7 +728,6 @@
 	 * Okay, now see if we can stuff it in the buffer as-is.
 	 */
 	max_headroom = (((tdev->hard_header_len+15)&~15)+sizeof(struct iphdr));
-
 	if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
 		struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
 		if (!new_skb) {
@@ -631,14 +757,28 @@
 	iph 			=	skb->nh.iph;
 	iph->version		=	4;
 	iph->ihl		=	sizeof(struct iphdr)>>2;
-	iph->frag_off		=	df;
-	iph->protocol		=	IPPROTO_IPIP;
-	iph->tos		=	INET_ECN_encapsulate(tos, old_iph->tos);
 	iph->daddr		=	rt->rt_dst;
 	iph->saddr		=	rt->rt_src;
 
-	if ((iph->ttl = tiph->ttl) == 0)
-		iph->ttl	=	old_iph->ttl;
+	iph->ttl		=	tiph->ttl;
+	iph->frag_off		=	df;
+
+	switch(skb->protocol){
+	case __constant_htons(ETH_P_IP):
+		iph->protocol	=	protocol;
+		iph->tos	=	INET_ECN_encapsulate(tos, old_iph->tos);
+		if (iph->ttl == 0)
+			iph->ttl =	old_iph->ttl;
+		break;
+#ifdef CONFIG_NET_IPIP_IPV6
+	case __constant_htons(ETH_P_IPV6):
+		iph->protocol	=	protocol;
+		iph->tos	=	INET_ECN_encapsulate(tos, ip6_get_dsfield(iph6));
+		if (iph->ttl == 0)
+			iph->ttl =	iph6->hop_limit;
+		break;
+#endif
+	}
 
 	nf_reset(skb);
 
@@ -692,8 +832,13 @@
 			goto done;
 
 		err = -EINVAL;
-		if (p.iph.version != 4 || p.iph.protocol != IPPROTO_IPIP ||
-		    p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)))
+		if (p.iph.version != 4 || 
+		    (p.iph.protocol != 0
+		     && p.iph.protocol != IPPROTO_IPIP
+#ifdef CONFIG_NET_IPIP_IPV6
+		     && p.iph.protocol != IPPROTO_IPV6
+#endif
+		     ) || p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)))
 			goto done;
 		if (p.iph.ttl)
 			p.iph.frag_off |= htons(IP_DF);
@@ -858,7 +1003,9 @@
 
 	iph = &ipip_fb_tunnel.parms.iph;
 	iph->version		= 4;
+#ifndef CONFIG_NET_IPIP_IPV6
 	iph->protocol		= IPPROTO_IPIP;
+#endif
 	iph->ihl		= 5;
 
 	dev_hold(dev);
@@ -873,8 +1020,21 @@
 	name:		"IPIP"
 };
 
+#ifdef CONFIG_NET_IPIP_IPV6
+static struct inet_protocol ipip6_protocol = {
+	handler:	ipip6_rcv,
+	err_handler:	ipip6_err,
+	protocol:	IPPROTO_IPV6,
+	name:		"IPv6"
+};
+#endif
+
 static char banner[] __initdata =
+#ifdef CONFIG_NET_IPIP_IPV6
+	KERN_INFO "IPv{4,6} over IPv4 tunneling driver\n";
+#else
 	KERN_INFO "IPv4 over IPv4 tunneling driver\n";
+#endif
 
 int __init ipip_init(void)
 {
@@ -883,11 +1043,18 @@
 	ipip_fb_tunnel_dev.priv = (void*)&ipip_fb_tunnel;
 	register_netdev(&ipip_fb_tunnel_dev);
 	inet_add_protocol(&ipip_protocol);
+#ifdef CONFIG_NET_IPIP_IPV6
+	inet_add_protocol(&ipip6_protocol);
+#endif
 	return 0;
 }
 
 static void __exit ipip_fini(void)
 {
+#ifdef CONFIG_NET_IPIP_IPV6
+	if ( inet_del_protocol(&ipip6_protocol) < 0 )
+		printk(KERN_INFO "ipip close: can't remove ipv6 protocol\n");
+#endif
 	if ( inet_del_protocol(&ipip_protocol) < 0 )
 		printk(KERN_INFO "ipip close: can't remove protocol\n");
 
diff -urN linux-2.4.29/net/ipv4/ip_options.c linux-2.4.29-uc1/net/ipv4/ip_options.c
--- linux-2.4.29/net/ipv4/ip_options.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/ip_options.c	2005-06-14 02:11:49.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: ip_options.c,v 1.5 2002/11/29 10:36:28 yoshfuji Exp $ */
+
 /*
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
@@ -220,6 +222,8 @@
 			optptr++;
 			continue;
 		}
+		if (l < 2)
+		  return;
 		optlen = optptr[1];
 		if (optlen<2 || optlen>l)
 		  return;
@@ -278,6 +282,10 @@
 			optptr++;
 			continue;
 		}
+		if (l < 2) {
+			pp_ptr = optptr;
+			goto error;
+		}
 		optlen = optptr[1];
 		if (optlen<2 || optlen>l) {
 			pp_ptr = optptr;
diff -urN linux-2.4.29/net/ipv4/ip_output.c linux-2.4.29-uc1/net/ipv4/ip_output.c
--- linux-2.4.29/net/ipv4/ip_output.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/ip_output.c	2005-06-14 02:11:50.000000000 +0100
@@ -360,7 +360,7 @@
 
 	/* Make sure we can route this packet. */
 	rt = (struct rtable *)__sk_dst_check(sk, 0);
-	if (rt == NULL) {
+	if (rt == NULL || rt->u.dst.obsolete) {
 		u32 daddr;
 
 		/* Use correct destination address if we have options. */
@@ -404,7 +404,6 @@
 		iph->ihl += opt->optlen >> 2;
 		ip_options_build(skb, opt, sk->daddr, rt, 0);
 	}
-
 	return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
 		       ip_queue_xmit2);
 
@@ -463,6 +462,8 @@
 
 	length -= sizeof(struct iphdr);
 
+	id = sk->protinfo.af_inet.id++;
+
 	if (opt) {
 		fragheaderlen = sizeof(struct iphdr) + opt->optlen;
 		maxfraglen = ((mtu-sizeof(struct iphdr)-opt->optlen) & ~7) + fragheaderlen;
@@ -519,9 +520,6 @@
 	/*
 	 *	Begin outputting the bytes.
 	 */
-
-	id = sk->protinfo.af_inet.id++;
-
 	do {
 		char *data;
 		struct sk_buff * skb;
@@ -672,7 +670,7 @@
 		/*
 		 * 	Check for slow path.
 		 */
-		if (length > rt->u.dst.pmtu || ipc->opt != NULL)  
+		if (length > rt->u.dst.pmtu || ipc->opt != NULL)
 			return ip_build_xmit_slow(sk,getfrag,frag,length,ipc,rt,flags); 
 	} else {
 		if (length > rt->u.dst.dev->mtu) {
@@ -890,6 +888,10 @@
 		/* Connection association is same as pre-frag packet */
 		skb2->nfct = skb->nfct;
 		nf_conntrack_get(skb2->nfct);
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+		skb2->nf_bridge = skb->nf_bridge;
+		nf_bridge_get(skb2->nf_bridge);
+#endif
 #ifdef CONFIG_NETFILTER_DEBUG
 		skb2->nf_debug = skb->nf_debug;
 #endif
diff -urN linux-2.4.29/net/ipv4/ip_sockglue.c linux-2.4.29-uc1/net/ipv4/ip_sockglue.c
--- linux-2.4.29/net/ipv4/ip_sockglue.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/ip_sockglue.c	2005-06-14 02:11:49.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: ip_sockglue.c,v 1.11 2003/08/08 13:46:37 yoshfuji Exp $ */
+
 /*
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
@@ -404,6 +406,12 @@
 
 	/* If optlen==0, it is equivalent to val == 0 */
 
+	if (level != SOL_IP)
+		return -ENOPROTOOPT;
+
+	if (optlen < 0)
+		return -EINVAL;
+
 #ifdef CONFIG_IP_MROUTE
 	if (optname >= MRT_BASE && optname <= (MRT_BASE + 10))
 		return ip_mroute_setsockopt(sk,optname,optval,optlen);
diff -urN linux-2.4.29/net/ipv4/netfilter/Config.in linux-2.4.29-uc1/net/ipv4/netfilter/Config.in
--- linux-2.4.29/net/ipv4/netfilter/Config.in	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/netfilter/Config.in	2005-06-14 02:11:50.000000000 +0100
@@ -7,9 +7,18 @@
 tristate 'Connection tracking (required for masq/NAT)' CONFIG_IP_NF_CONNTRACK
 if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
   dep_tristate '  FTP protocol support' CONFIG_IP_NF_FTP $CONFIG_IP_NF_CONNTRACK
+  bool '  Connection mark tracking support' CONFIG_IP_NF_CONNTRACK_MARK
+  dep_tristate '  H.323 (netmeeting) support' CONFIG_IP_NF_H323 $CONFIG_IP_NF_CONNTRACK
   dep_tristate '  Amanda protocol support' CONFIG_IP_NF_AMANDA $CONFIG_IP_NF_CONNTRACK
   dep_tristate '  TFTP protocol support' CONFIG_IP_NF_TFTP $CONFIG_IP_NF_CONNTRACK
   dep_tristate '  IRC protocol support' CONFIG_IP_NF_IRC $CONFIG_IP_NF_CONNTRACK
+  dep_tristate '  GRE protocol support' CONFIG_IP_NF_CT_PROTO_GRE $CONFIG_IP_NF_CONNTRACK
+  dep_tristate '   PPTP protocol support' CONFIG_IP_NF_PPTP $CONFIG_IP_NF_CT_PROTO_GRE
+  if [ "$CONFIG_IP_NF_PPTP" != "n" ]; then
+	bool   '    PPTP verbose debug' CONFIG_IP_NF_PPTP_DEBUG
+  fi
+  bool '  Connection tracking flow accounting' CONFIG_IP_NF_CT_ACCT
+  bool '  Connection tracking events' CONFIG_IP_NF_CONNTRACK_EVENTS
 fi
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
@@ -19,11 +28,13 @@
 if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; then
 # The simple matches.
   dep_tristate '  limit match support' CONFIG_IP_NF_MATCH_LIMIT $CONFIG_IP_NF_IPTABLES
+  dep_tristate '  IP range match support' CONFIG_IP_NF_MATCH_IPRANGE $CONFIG_IP_NF_IPTABLES
   dep_tristate '  MAC address match support' CONFIG_IP_NF_MATCH_MAC $CONFIG_IP_NF_IPTABLES
   dep_tristate '  Packet type match support' CONFIG_IP_NF_MATCH_PKTTYPE $CONFIG_IP_NF_IPTABLES
   dep_tristate '  netfilter MARK match support' CONFIG_IP_NF_MATCH_MARK $CONFIG_IP_NF_IPTABLES
   dep_tristate '  Multiple port match support' CONFIG_IP_NF_MATCH_MULTIPORT $CONFIG_IP_NF_IPTABLES
   dep_tristate '  TOS match support' CONFIG_IP_NF_MATCH_TOS $CONFIG_IP_NF_IPTABLES
+  dep_tristate '  TIME match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_TIME $CONFIG_IP_NF_IPTABLES
   dep_tristate '  recent match support' CONFIG_IP_NF_MATCH_RECENT $CONFIG_IP_NF_IPTABLES
   dep_tristate '  ECN match support' CONFIG_IP_NF_MATCH_ECN $CONFIG_IP_NF_IPTABLES
  
@@ -38,12 +49,19 @@
   fi
   if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
     dep_tristate '  Connection state match support' CONFIG_IP_NF_MATCH_STATE $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES 
+    if [ "$CONFIG_IP_NF_CONNTRACK_MARK" != "n" ]; then
+      dep_tristate '  Connection mark match support' CONFIG_IP_NF_MATCH_CONNMARK $CONFIG_IP_NF_IPTABLES
+    fi
     dep_tristate '  Connection tracking match support' CONFIG_IP_NF_MATCH_CONNTRACK $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES 
   fi
   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
     dep_tristate '  Unclean match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_UNCLEAN $CONFIG_IP_NF_IPTABLES
+    dep_tristate '  String match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_STRING $CONFIG_IP_NF_IPTABLES
     dep_tristate '  Owner match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_OWNER $CONFIG_IP_NF_IPTABLES
   fi
+  if [ "$CONFIG_BRIDGE" != "n" ]; then
+    dep_tristate '  Physdev match support' CONFIG_IP_NF_MATCH_PHYSDEV $CONFIG_IP_NF_IPTABLES
+  fi
 # The targets
   dep_tristate '  Packet filtering' CONFIG_IP_NF_FILTER $CONFIG_IP_NF_IPTABLES 
   if [ "$CONFIG_IP_NF_FILTER" != "n" ]; then
@@ -54,11 +72,20 @@
   fi
 
   if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
+    bool '  Increase default conntrack table size' CONFIG_IP_NF_BIG_CONNTRACK
     dep_tristate '  Full NAT' CONFIG_IP_NF_NAT $CONFIG_IP_NF_IPTABLES $CONFIG_IP_NF_CONNTRACK
     if [ "$CONFIG_IP_NF_NAT" != "n" ]; then
       define_bool CONFIG_IP_NF_NAT_NEEDED y
       dep_tristate '    MASQUERADE target support' CONFIG_IP_NF_TARGET_MASQUERADE $CONFIG_IP_NF_NAT
       dep_tristate '    REDIRECT target support' CONFIG_IP_NF_TARGET_REDIRECT $CONFIG_IP_NF_NAT
+      dep_tristate '    NETMAP target support' CONFIG_IP_NF_TARGET_NETMAP $CONFIG_IP_NF_NAT
+      if [ "$CONFIG_IP_NF_H323" = "m" ]; then
+       define_tristate CONFIG_IP_NF_NAT_H323 m
+      else
+        if [ "$CONFIG_IP_NF_H323" = "y" ]; then
+          define_tristate CONFIG_IP_NF_NAT_H323 $CONFIG_IP_NF_NAT
+        fi
+      fi
       if [ "$CONFIG_IP_NF_AMANDA" = "m" ]; then
         define_tristate CONFIG_IP_NF_NAT_AMANDA m
       else
@@ -85,6 +112,20 @@
           define_tristate CONFIG_IP_NF_NAT_FTP $CONFIG_IP_NF_NAT
         fi
       fi
+      if [ "$CONFIG_IP_NF_PPTP" = "m" ]; then
+        define_tristate CONFIG_IP_NF_NAT_PPTP m
+      else
+        if [ "$CONFIG_IP_NF_PPTP" = "y" ]; then
+          define_tristate CONFIG_IP_NF_NAT_PPTP $CONFIG_IP_NF_NAT
+        fi
+      fi
+      if [ "$CONFIG_IP_NF_CT_PROTO_GRE" = "m" ]; then
+        define_tristate CONFIG_IP_NF_NAT_PROTO_GRE m
+      else
+        if [ "$CONFIG_IP_NF_CT_PROTO_GRE" = "y" ]; then
+	  define_tristate CONFIG_IP_NF_NAT_PROTO_GRE $CONFIG_IP_NF_NAT
+	fi
+      fi
       if [ "$CONFIG_IP_NF_TFTP" = "m" ]; then
 	define_tristate CONFIG_IP_NF_NAT_TFTP m
       else
@@ -103,8 +144,13 @@
     dep_tristate '    DSCP target support' CONFIG_IP_NF_TARGET_DSCP $CONFIG_IP_NF_MANGLE
  
     dep_tristate '    MARK target support' CONFIG_IP_NF_TARGET_MARK $CONFIG_IP_NF_MANGLE
+    dep_tristate '    IMQ target support' CONFIG_IP_NF_TARGET_IMQ $CONFIG_IP_NF_MANGLE
   fi
   dep_tristate '  LOG target support' CONFIG_IP_NF_TARGET_LOG $CONFIG_IP_NF_IPTABLES
+  if [ "$CONFIG_IP_NF_CONNTRACK_MARK" != "n" ]; then
+    dep_tristate '  CONNMARK target support' CONFIG_IP_NF_TARGET_CONNMARK $CONFIG_IP_NF_IPTABLES
+  fi
+  dep_tristate '  CONNLOG target support' CONFIG_IP_NF_TARGET_CONNLOG $CONFIG_IP_NF_IPTABLES
   dep_tristate '  ULOG target support' CONFIG_IP_NF_TARGET_ULOG $CONFIG_IP_NF_IPTABLES
   dep_tristate '  TCPMSS target support' CONFIG_IP_NF_TARGET_TCPMSS $CONFIG_IP_NF_IPTABLES
 fi
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_conntrack_amanda.c linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_amanda.c
--- linux-2.4.29/net/ipv4/netfilter/ip_conntrack_amanda.c	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_amanda.c	2005-06-14 02:11:50.000000000 +0100
@@ -75,7 +75,7 @@
 
 	/* increase the UDP timeout of the master connection as replies from
 	 * Amanda clients to the server can be quite delayed */
-	ip_ct_refresh(ct, master_timeout * HZ);
+	ip_ct_refresh_acct(ct, ctinfo, NULL, master_timeout * HZ);
 	
 	/* Search for "CONNECT " string */
 	do {
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_conntrack_core.c linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_core.c
--- linux-2.4.29/net/ipv4/netfilter/ip_conntrack_core.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_core.c	2005-06-14 02:11:51.000000000 +0100
@@ -32,6 +32,7 @@
 #include <linux/jhash.h>
 /* For ERR_PTR().  Yeah, I know... --RR */
 #include <linux/fs.h>
+#include <linux/notifier.h>
 
 /* This rwlock protects the main hash table, protocol/helper/expected
    registrations, conntrack timers*/
@@ -65,6 +66,10 @@
 struct list_head *ip_conntrack_hash;
 static kmem_cache_t *ip_conntrack_cachep;
 
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+struct notifier_block *ip_conntrack_chain;
+#endif /* CONFIG_IP_NF_CONNTRACK_EVENTS */
+
 extern struct ip_conntrack_protocol ip_conntrack_generic_protocol;
 
 static inline int proto_cmpfn(const struct ip_conntrack_protocol *curr,
@@ -142,6 +147,8 @@
 	tuple->dst.ip = iph->daddr;
 	tuple->dst.protonum = iph->protocol;
 
+	tuple->src.u.all = tuple->dst.u.all = 0;
+
 	ret = protocol->pkt_to_tuple((u_int32_t *)iph + iph->ihl,
 				     len - 4*iph->ihl,
 				     tuple);
@@ -157,6 +164,8 @@
 	inverse->dst.ip = orig->src.ip;
 	inverse->dst.protonum = orig->dst.protonum;
 
+	inverse->src.u.all = inverse->dst.u.all = 0;
+
 	return protocol->invert_tuple(inverse, orig);
 }
 
@@ -314,6 +323,8 @@
 	IP_NF_ASSERT(atomic_read(&nfct->use) == 0);
 	IP_NF_ASSERT(!timer_pending(&ct->timeout));
 
+	set_bit(IPS_DESTROYED_BIT, &ct->status);
+
 	/* To make sure we don't get any weird locking issues here:
 	 * destroy_conntrack() MUST NOT be called with a write lock
 	 * to ip_conntrack_lock!!! -HW */
@@ -353,6 +364,7 @@
 {
 	struct ip_conntrack *ct = (void *)ul_conntrack;
 
+	ip_conntrack_event(IPCT_DESTROY, ct);
 	WRITE_LOCK(&ip_conntrack_lock);
 	clean_from_lists(ct);
 	WRITE_UNLOCK(&ip_conntrack_lock);
@@ -423,13 +435,13 @@
 
 /* Confirm a connection given skb->nfct; places it in hash table */
 int
-__ip_conntrack_confirm(struct nf_ct_info *nfct)
+__ip_conntrack_confirm(struct sk_buff *skb)
 {
 	unsigned int hash, repl_hash;
 	struct ip_conntrack *ct;
 	enum ip_conntrack_info ctinfo;
 
-	ct = __ip_conntrack_get(nfct, &ctinfo);
+	ct = ip_conntrack_get(skb, &ctinfo);
 
 	/* ipt_REJECT uses ip_conntrack_attach to attach related
 	   ICMP/TCP RST packets in other direction.  Actual packet
@@ -475,6 +487,9 @@
 		atomic_inc(&ct->ct_general.use);
 		set_bit(IPS_CONFIRMED_BIT, &ct->status);
 		WRITE_UNLOCK(&ip_conntrack_lock);
+		ip_conntrack_event_cache(master_ct(ct) ?
+					 IPCT_RELATED : IPCT_NEW, skb);
+
 		return NF_ACCEPT;
 	}
 
@@ -720,7 +735,7 @@
 		conntrack->helper = ip_ct_find_helper(&repl_tuple);
 
 	/* If the expectation is dying, then this is a looser. */
-	if (expected
+	if (expected && expected->expectant && expected->expectant->helper
 	    && expected->expectant->helper->timeout
 	    && ! del_timer(&expected->timeout))
 		expected = NULL;
@@ -732,6 +747,9 @@
 		__set_bit(IPS_EXPECTED_BIT, &conntrack->status);
 		conntrack->master = expected;
 		expected->sibling = conntrack;
+#if CONFIG_IP_NF_CONNTRACK_MARK
+		conntrack->mark = expected->expectant->mark;
+#endif
 		LIST_DELETE(&ip_conntrack_expect_list, expected);
 		expected->expectant->expecting--;
 		nf_conntrack_get(&master_ct(conntrack)->infos[0]);
@@ -812,6 +830,8 @@
 	/* FIXME: Do this right please. --RR */
 	(*pskb)->nfcache |= NFC_UNKNOWN;
 
+	ip_conntrack_event_cache_init(*pskb);
+
 /* Doesn't cover locally-generated broadcast, so not worth it. */
 #if 0
 	/* Ignore broadcast: no `connection'. */
@@ -945,8 +965,8 @@
 	 * so there is no need to use the tuple lock too */
 
 	DEBUGP("ip_conntrack_expect_related %p\n", related_to);
-	DEBUGP("tuple: "); DUMP_TUPLE(&expect->tuple);
-	DEBUGP("mask:  "); DUMP_TUPLE(&expect->mask);
+	DEBUGP("tuple: "); DUMP_TUPLE_RAW(&expect->tuple);
+	DEBUGP("mask:  "); DUMP_TUPLE_RAW(&expect->mask);
 
 	old = LIST_FIND(&ip_conntrack_expect_list, resent_expect,
 		        struct ip_conntrack_expect *, &expect->tuple, 
@@ -1063,15 +1083,14 @@
 
 	MUST_BE_READ_LOCKED(&ip_conntrack_lock);
 	WRITE_LOCK(&ip_conntrack_expect_tuple_lock);
-
 	DEBUGP("change_expect:\n");
-	DEBUGP("exp tuple: "); DUMP_TUPLE(&expect->tuple);
-	DEBUGP("exp mask:  "); DUMP_TUPLE(&expect->mask);
-	DEBUGP("newtuple:  "); DUMP_TUPLE(newtuple);
+	DEBUGP("exp tuple: "); DUMP_TUPLE_RAW(&expect->tuple);
+	DEBUGP("exp mask:  "); DUMP_TUPLE_RAW(&expect->mask);
+	DEBUGP("newtuple:  "); DUMP_TUPLE_RAW(newtuple);
 	if (expect->ct_tuple.dst.protonum == 0) {
 		/* Never seen before */
 		DEBUGP("change expect: never seen before\n");
-		if (!ip_ct_tuple_equal(&expect->tuple, newtuple) 
+		if (!ip_ct_tuple_mask_cmp(&expect->tuple, newtuple, &expect->mask)
 		    && LIST_FIND(&ip_conntrack_expect_list, expect_clash,
 			         struct ip_conntrack_expect *, newtuple, &expect->mask)) {
 			/* Force NAT to find an unused tuple */
@@ -1164,21 +1183,39 @@
 	MOD_DEC_USE_COUNT;
 }
 
-/* Refresh conntrack for this many jiffies. */
-void ip_ct_refresh(struct ip_conntrack *ct, unsigned long extra_jiffies)
+static inline void ct_add_counters(struct ip_conntrack *ct,
+				   enum ip_conntrack_info ctinfo,
+				   struct iphdr *iph)
+{
+#ifdef CONFIG_IP_NF_CT_ACCT
+	if (iph) {
+		ct->counters[CTINFO2DIR(ctinfo)].packets++;
+		ct->counters[CTINFO2DIR(ctinfo)].bytes += ntohs(iph->tot_len);
+	}
+#endif
+}
+
+/* Refresh conntrack for this many jiffies and do accounting (if iph != NULL) */
+void ip_ct_refresh_acct(struct ip_conntrack *ct,
+			enum ip_conntrack_info ctinfo,
+			struct iphdr *iph,
+			unsigned long extra_jiffies)
 {
 	IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct);
 
 	WRITE_LOCK(&ip_conntrack_lock);
 	/* If not in hash table, timer will not be active yet */
-	if (!is_confirmed(ct))
+	if (!is_confirmed(ct)) {
 		ct->timeout.expires = extra_jiffies;
+		ct_add_counters(ct, ctinfo, iph);
+	}
 	else {
 		/* Need del_timer for race avoidance (may already be dying). */
 		if (del_timer(&ct->timeout)) {
 			ct->timeout.expires = jiffies + extra_jiffies;
 			add_timer(&ct->timeout);
 		}
+		ct_add_counters(ct, ctinfo, iph);
 	}
 	WRITE_UNLOCK(&ip_conntrack_lock);
 }
@@ -1382,6 +1419,7 @@
 	nf_unregister_sockopt(&so_getorigdst);
 }
 
+#define HASHRATIO 8
 static int hashsize = 0;
 MODULE_PARM(hashsize, "i");
 
@@ -1395,6 +1433,14 @@
  	if (hashsize) {
  		ip_conntrack_htable_size = hashsize;
  	} else {
+#ifdef CONFIG_IP_NF_BIG_CONNTRACK
+		/* Increase hash table size for dedicated routers.
+		 * Allow all of memory to be used;  it's just as bad
+		 * as having a full conntrack table. */
+		ip_conntrack_htable_size 
+			= (((num_physpages << PAGE_SHIFT) / HASHRATIO)
+                	   / sizeof(struct ip_conntrack));
+#else
 		ip_conntrack_htable_size
 			= (((num_physpages << PAGE_SHIFT) / 16384)
 			   / sizeof(struct list_head));
@@ -1402,8 +1448,9 @@
 			ip_conntrack_htable_size = 8192;
 		if (ip_conntrack_htable_size < 16)
 			ip_conntrack_htable_size = 16;
+#endif
 	}
-	ip_conntrack_max = 8 * ip_conntrack_htable_size;
+	ip_conntrack_max = HASHRATIO * ip_conntrack_htable_size;
 
 	printk("ip_conntrack version %s (%u buckets, %d max)"
 	       " - %Zd bytes per conntrack\n", IP_CONNTRACK_VERSION,
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_conntrack_h323.c linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_h323.c
--- linux-2.4.29/net/ipv4/netfilter/ip_conntrack_h323.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_h323.c	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,313 @@
+/* 
+ * H.323 'brute force' extension for H.323 connection tracking. 
+ * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
+ *
+ * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project.
+ * (http://www.coritel.it/projects/sofia/nat/)
+ * Uses Sampsa Ranta's excellent idea on using expectfn to 'bind'
+ * the unregistered helpers to the conntrack entries.
+ */
+
+
+#include <linux/module.h>
+#include <linux/netfilter.h>
+#include <linux/ip.h>
+#include <net/checksum.h>
+#include <net/tcp.h>
+
+#include <linux/netfilter_ipv4/lockhelp.h>
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <linux/netfilter_ipv4/ip_conntrack_core.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
+#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
+
+MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
+MODULE_DESCRIPTION("H.323 'brute force' connection tracking module");
+MODULE_LICENSE("GPL");
+
+DECLARE_LOCK(ip_h323_lock);
+struct module *ip_conntrack_h323 = THIS_MODULE;
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+/* FIXME: This should be in userspace.  Later. */
+static int h245_help(const struct iphdr *iph, size_t len,
+		     struct ip_conntrack *ct,
+		     enum ip_conntrack_info ctinfo)
+{
+	struct tcphdr *tcph = (void *)iph + iph->ihl * 4;
+	unsigned char *data = (unsigned char *) tcph + tcph->doff * 4;
+	unsigned char *data_limit;
+	u_int32_t tcplen = len - iph->ihl * 4;
+	u_int32_t datalen = tcplen - tcph->doff * 4;
+	int dir = CTINFO2DIR(ctinfo);
+	struct ip_ct_h225_master *info = &ct->help.ct_h225_info;
+	struct ip_conntrack_expect expect, *exp = &expect;
+	struct ip_ct_h225_expect *exp_info = &exp->help.exp_h225_info;
+	u_int16_t data_port;
+	u_int32_t data_ip;
+	unsigned int i;
+
+	DEBUGP("ct_h245_help: help entered %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
+		NIPQUAD(iph->saddr), ntohs(tcph->source),
+		NIPQUAD(iph->daddr), ntohs(tcph->dest));
+
+	/* Can't track connections formed before we registered */
+	if (!info)
+		return NF_ACCEPT;
+		
+	/* Until there's been traffic both ways, don't look in packets. */
+	if (ctinfo != IP_CT_ESTABLISHED
+	    && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
+		DEBUGP("ct_h245_help: Conntrackinfo = %u\n", ctinfo);
+		return NF_ACCEPT;
+	}
+
+	/* Not whole TCP header or too short packet? */
+	if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4 + 5) {
+		DEBUGP("ct_h245_help: tcplen = %u\n", (unsigned)tcplen);
+		return NF_ACCEPT;
+	}
+
+	/* Checksum invalid?  Ignore. */
+	/* FIXME: Source route IP option packets --RR */
+	if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
+			      csum_partial((char *)tcph, tcplen, 0))) {
+		DEBUGP("ct_h245_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n",
+		       tcph, tcplen, NIPQUAD(iph->saddr),
+		       NIPQUAD(iph->daddr));
+		return NF_ACCEPT;
+	}
+
+	data_limit = (unsigned char *) data + datalen;
+	/* bytes: 0123   45
+	          ipadrr port */
+	for (i = 0; data < (data_limit - 5); data++, i++) {
+		data_ip = *((u_int32_t *)data);
+		if (data_ip == iph->saddr) {
+			data_port = *((u_int16_t *)(data + 4));
+			memset(&expect, 0, sizeof(expect));
+			/* update the H.225 info */
+			DEBUGP("ct_h245_help: new RTCP/RTP requested %u.%u.%u.%u:->%u.%u.%u.%u:%u\n",
+				NIPQUAD(ct->tuplehash[!dir].tuple.src.ip),
+				NIPQUAD(iph->saddr), ntohs(data_port));
+			LOCK_BH(&ip_h323_lock);
+			info->is_h225 = H225_PORT + 1;
+			exp_info->port = data_port;
+			exp_info->dir = dir;
+			exp_info->offset = i;
+
+			exp->seq = ntohl(tcph->seq) + i;
+		    
+			exp->tuple = ((struct ip_conntrack_tuple)
+				{ { ct->tuplehash[!dir].tuple.src.ip,
+				    { 0 } },
+				  { data_ip,
+				    { udp: { port: data_port } },
+				    IPPROTO_UDP }});
+			exp->mask = ((struct ip_conntrack_tuple)
+				{ { 0xFFFFFFFF, { 0 } },
+				  { 0xFFFFFFFF,
+				    { udp: { port: 0xFFFF } }, 0xFFFF }});
+	
+			exp->expectfn = NULL;
+			
+			/* Ignore failure; should only happen with NAT */
+			ip_conntrack_expect_related(ct, exp);
+
+			UNLOCK_BH(&ip_h323_lock);
+		}
+	}
+
+	return NF_ACCEPT;
+
+}
+
+/* H.245 helper is not registered! */
+static struct ip_conntrack_helper h245 = 
+	{ { NULL, NULL },
+          "H.245",				/* name */
+          IP_CT_HELPER_F_REUSE_EXPECT,		/* flags */
+          NULL,					/* module */
+          16,					/* max_ expected */
+          240,					/* timeout */
+          { { 0, { 0 } },			/* tuple */
+            { 0, { 0 }, IPPROTO_TCP } },
+          { { 0, { tcp: { port: 0xFFFF } } },	/* mask */
+            { 0, { 0 }, 0xFFFF } },
+          h245_help				/* helper */
+	};
+
+static int h225_expect(struct ip_conntrack *ct)
+{
+	WRITE_LOCK(&ip_conntrack_lock);
+	ct->helper = &h245;
+	DEBUGP("h225_expect: helper for %p added\n", ct);
+	WRITE_UNLOCK(&ip_conntrack_lock);
+	
+	return NF_ACCEPT;	/* unused */
+}
+
+/* FIXME: This should be in userspace.  Later. */
+static int h225_help(const struct iphdr *iph, size_t len,
+		     struct ip_conntrack *ct,
+		     enum ip_conntrack_info ctinfo)
+{
+	struct tcphdr *tcph = (void *)iph + iph->ihl * 4;
+	unsigned char *data = (unsigned char *) tcph + tcph->doff * 4;
+	unsigned char *data_limit;
+	u_int32_t tcplen = len - iph->ihl * 4;
+	u_int32_t datalen = tcplen - tcph->doff * 4;
+	int dir = CTINFO2DIR(ctinfo);
+	struct ip_ct_h225_master *info = &ct->help.ct_h225_info;
+	struct ip_conntrack_expect expect, *exp = &expect;
+	struct ip_ct_h225_expect *exp_info = &exp->help.exp_h225_info;
+	u_int16_t data_port;
+	u_int32_t data_ip;
+	unsigned int i;
+	
+	DEBUGP("ct_h225_help: help entered %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
+		NIPQUAD(iph->saddr), ntohs(tcph->source),
+		NIPQUAD(iph->daddr), ntohs(tcph->dest));
+
+	/* Can't track connections formed before we registered */
+	if (!info)
+		return NF_ACCEPT;
+
+	/* Until there's been traffic both ways, don't look in packets. */
+	if (ctinfo != IP_CT_ESTABLISHED
+	    && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
+		DEBUGP("ct_h225_help: Conntrackinfo = %u\n", ctinfo);
+		return NF_ACCEPT;
+	}
+
+	/* Not whole TCP header or too short packet? */
+	if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4 + 5) {
+		DEBUGP("ct_h225_help: tcplen = %u\n", (unsigned)tcplen);
+		return NF_ACCEPT;
+	}
+
+	/* Checksum invalid?  Ignore. */
+	/* FIXME: Source route IP option packets --RR */
+	if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
+			      csum_partial((char *)tcph, tcplen, 0))) {
+		DEBUGP("ct_h225_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n",
+		       tcph, tcplen, NIPQUAD(iph->saddr),
+		       NIPQUAD(iph->daddr));
+		return NF_ACCEPT;
+	}
+	
+	data_limit = (unsigned char *) data + datalen;
+	/* bytes: 0123   45
+	          ipadrr port */
+	for (i = 0; data < (data_limit - 5); data++, i++) {
+		data_ip = *((u_int32_t *)data);
+		if (data_ip == iph->saddr) {
+			data_port = *((u_int16_t *)(data + 4));
+			if ((data_port == tcph->source) || (data_port == 0)) {
+				/* Signal address */
+				DEBUGP("ct_h225_help: sourceCallSignalAddress from %u.%u.%u.%u\n",
+					NIPQUAD(iph->saddr));
+				/* Update the H.225 info so that NAT can mangle the address/port
+				   even when we have no expected connection! */
+#ifdef CONFIG_IP_NF_NAT_NEEDED
+				LOCK_BH(&ip_h323_lock);
+				info->dir = dir;
+				info->seq[IP_CT_DIR_ORIGINAL] = ntohl(tcph->seq) + i;
+				info->offset[IP_CT_DIR_ORIGINAL] = i;
+				UNLOCK_BH(&ip_h323_lock);
+#endif
+			} else {
+				memset(&expect, 0, sizeof(expect));
+
+				/* update the H.225 info */
+				LOCK_BH(&ip_h323_lock);
+				info->is_h225 = H225_PORT;
+				exp_info->port = data_port;
+				exp_info->dir = dir;
+				exp_info->offset = i;
+
+				exp->seq = ntohl(tcph->seq) + i;
+
+				exp->tuple = ((struct ip_conntrack_tuple)
+					{ { ct->tuplehash[!dir].tuple.src.ip,
+					    { 0 } },
+					  { data_ip,
+					    { tcp: { port: data_port } },
+					    IPPROTO_TCP }});
+				exp->mask = ((struct ip_conntrack_tuple)
+					{ { 0xFFFFFFFF, { 0 } },
+					  { 0xFFFFFFFF,
+					    { tcp: { port: 0xFFFF } },
+					    0xFFFF }});
+	
+				exp->expectfn = h225_expect;
+				
+				/* Ignore failure */
+				ip_conntrack_expect_related(ct, exp);
+
+				DEBUGP("ct_h225_help: new H.245 requested %u.%u.%u.%u->%u.%u.%u.%u:%u\n",
+					NIPQUAD(ct->tuplehash[!dir].tuple.src.ip),
+					NIPQUAD(iph->saddr), ntohs(data_port));
+
+				UNLOCK_BH(&ip_h323_lock);
+                	}  
+#ifdef CONFIG_IP_NF_NAT_NEEDED
+		} else if (data_ip == iph->daddr) {
+			data_port = *((u_int16_t *)(data + 4));
+			if (data_port == tcph->dest) {
+				/* Signal address */
+				DEBUGP("ct_h225_help: destCallSignalAddress %u.%u.%u.%u\n",
+					NIPQUAD(iph->daddr));
+				/* Update the H.225 info so that NAT can mangle the address/port
+				   even when we have no expected connection! */
+				LOCK_BH(&ip_h323_lock);
+				info->dir = dir;
+				info->seq[IP_CT_DIR_REPLY] = ntohl(tcph->seq) + i;
+				info->offset[IP_CT_DIR_REPLY] = i;
+				UNLOCK_BH(&ip_h323_lock);
+			}
+#endif
+		}
+	}
+
+	return NF_ACCEPT;
+
+}
+
+static struct ip_conntrack_helper h225 = 
+	{ { NULL, NULL },
+	  "H.225",					/* name */
+	  IP_CT_HELPER_F_REUSE_EXPECT,			/* flags */
+	  THIS_MODULE,					/* module */
+	  2,						/* max_expected */
+	  240,						/* timeout */
+	  { { 0, { tcp: { port: __constant_htons(H225_PORT) } } },
+	    { 0, { 0 }, IPPROTO_TCP } },		/* tuple */
+	  { { 0, { tcp: { port: 0xFFFF } } },		/* mask */
+	    { 0, { 0 }, 0xFFFF } },
+	  h225_help					/* helper */
+	};
+
+static int __init init(void)
+{
+	return ip_conntrack_helper_register(&h225);
+}
+
+static void __exit fini(void)
+{
+	/* Unregister H.225 helper */	
+	ip_conntrack_helper_unregister(&h225);
+}
+
+#ifdef CONFIG_IP_NF_NAT_NEEDED
+EXPORT_SYMBOL(ip_h323_lock);
+#endif
+
+module_init(init);
+module_exit(fini);
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_conntrack_pptp.c linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_pptp.c
--- linux-2.4.29/net/ipv4/netfilter/ip_conntrack_pptp.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_pptp.c	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,637 @@
+/*
+ * ip_conntrack_pptp.c	- Version $Revision: 1.8 $
+ *
+ * Connection tracking support for PPTP (Point to Point Tunneling Protocol).
+ * PPTP is a a protocol for creating virtual private networks.
+ * It is a specification defined by Microsoft and some vendors
+ * working with Microsoft.  PPTP is built on top of a modified
+ * version of the Internet Generic Routing Encapsulation Protocol.
+ * GRE is defined in RFC 1701 and RFC 1702.  Documentation of
+ * PPTP can be found in RFC 2637
+ *
+ * (C) 2000-2003 by Harald Welte <laforge@gnumonks.org>
+ *
+ * Development of this code funded by Astaro AG (http://www.astaro.com/)
+ *
+ * Limitations:
+ * 	 - We blindly assume that control connections are always
+ * 	   established in PNS->PAC direction.  This is a violation
+ * 	   of RFFC2673
+ *
+ * TODO: - finish support for multiple calls within one session
+ * 	   (needs expect reservations in newnat)
+ *	 - testing of incoming PPTP calls 
+ *
+ * Changes: 
+ * 	2002-02-05 - Version 1.3
+ * 	  - Call ip_conntrack_unexpect_related() from 
+ * 	    pptp_timeout_related() to destroy expectations in case
+ * 	    CALL_DISCONNECT_NOTIFY or tcp fin packet was seen
+ * 	    (Philip Craig <philipc@snapgear.com>)
+ * 	  - Add Version information at module loadtime
+ * 	2002-02-10 - Version 1.6
+ * 	  - move to C99 style initializers
+ * 	  - remove second expectation if first arrives
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/netfilter.h>
+#include <linux/ip.h>
+#include <net/checksum.h>
+#include <net/tcp.h>
+
+#include <linux/netfilter_ipv4/lockhelp.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
+#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
+
+#define IP_CT_PPTP_VERSION "$Revision: 1.8 $"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
+MODULE_DESCRIPTION("Netfilter connection tracking helper module for PPTP");
+
+DECLARE_LOCK(ip_pptp_lock);
+
+#if 0
+#include "ip_conntrack_pptp_priv.h"
+#define DEBUGP(format, args...)	printk(KERN_DEBUG __FILE__ ":" __FUNCTION__ \
+					": " format, ## args)
+#else
+#define DEBUGP(format, args...)
+#endif
+
+#define SECS *HZ
+#define MINS * 60 SECS
+#define HOURS * 60 MINS
+#define DAYS * 24 HOURS
+
+#define PPTP_GRE_TIMEOUT 		(10 MINS)
+#define PPTP_GRE_STREAM_TIMEOUT 	(5 DAYS)
+
+static int pptp_expectfn(struct ip_conntrack *ct)
+{
+	struct ip_conntrack *master;
+	struct ip_conntrack_expect *exp;
+
+	DEBUGP("increasing timeouts\n");
+	/* increase timeout of GRE data channel conntrack entry */
+	ct->proto.gre.timeout = PPTP_GRE_TIMEOUT;
+	ct->proto.gre.stream_timeout = PPTP_GRE_STREAM_TIMEOUT;
+
+	master = master_ct(ct);
+	if (!master) {
+		DEBUGP(" no master!!!\n");
+		return 0;
+	}
+
+	exp = ct->master;
+	if (!exp) {
+		DEBUGP("no expectation!!\n");
+		return 0;
+	}
+
+	DEBUGP("completing tuples with ct info\n");
+	/* we can do this, since we're unconfirmed */
+	if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key == 
+		htonl(master->help.ct_pptp_info.pac_call_id)) {	
+		/* assume PNS->PAC */
+		ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key = 
+			htonl(master->help.ct_pptp_info.pns_call_id);
+		ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key =
+			htonl(master->help.ct_pptp_info.pns_call_id);
+	} else {
+		/* assume PAC->PNS */
+		ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key =
+			htonl(master->help.ct_pptp_info.pac_call_id);
+		ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key =
+			htonl(master->help.ct_pptp_info.pac_call_id);
+	}
+	
+	/* delete other expectation */
+	if (exp->expected_list.next != &exp->expected_list) {
+		struct ip_conntrack_expect *other_exp;
+		struct list_head *cur_item, *next;
+
+		for (cur_item = master->sibling_list.next;
+		     cur_item != &master->sibling_list; cur_item = next) {
+			next = cur_item->next;
+			other_exp = list_entry(cur_item,
+					       struct ip_conntrack_expect,
+					       expected_list);
+			/* remove only if occurred at same sequence number */
+			if (other_exp != exp && other_exp->seq == exp->seq) {
+				DEBUGP("unexpecting other direction\n");
+				ip_ct_gre_keymap_destroy(other_exp);
+				ip_conntrack_unexpect_related(other_exp);
+			}
+		}
+	}
+
+	return 0;
+}
+
+/* timeout GRE data connections */
+static int pptp_timeout_related(struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
+{
+	struct list_head *cur_item, *next;
+	struct ip_conntrack_expect *exp;
+
+	/* FIXME: do we have to lock something ? */
+	for (cur_item = ct->sibling_list.next;
+	    cur_item != &ct->sibling_list; cur_item = next) {
+		next = cur_item->next;
+		exp = list_entry(cur_item, struct ip_conntrack_expect,
+				 expected_list);
+
+		ip_ct_gre_keymap_destroy(exp);
+		if (!exp->sibling) {
+			ip_conntrack_unexpect_related(exp);
+			continue;
+		}
+
+		DEBUGP("setting timeout of conntrack %p to 0\n",
+			exp->sibling);
+		exp->sibling->proto.gre.timeout = 0;
+		exp->sibling->proto.gre.stream_timeout = 0;
+		ip_ct_refresh_acct(exp->sibling, ctinfo, NULL, 0);
+	}
+
+	return 0;
+}
+
+/* expect GRE connections (PNS->PAC and PAC->PNS direction) */
+static inline int
+exp_gre(struct ip_conntrack *master,
+	u_int32_t seq,
+	u_int16_t callid,
+	u_int16_t peer_callid)
+{
+	struct ip_conntrack_expect exp;
+	struct ip_conntrack_tuple inv_tuple;
+
+	memset(&exp, 0, sizeof(exp));
+	/* tuple in original direction, PNS->PAC */
+	exp.tuple.src.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
+	exp.tuple.src.u.gre.key = htonl(ntohs(peer_callid));
+	exp.tuple.dst.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
+	exp.tuple.dst.u.gre.key = htonl(ntohs(callid));
+	exp.tuple.dst.u.gre.protocol = __constant_htons(GRE_PROTOCOL_PPTP);
+	exp.tuple.dst.u.gre.version = GRE_VERSION_PPTP;
+	exp.tuple.dst.protonum = IPPROTO_GRE;
+
+	exp.mask.src.ip = 0xffffffff;
+	exp.mask.src.u.all = 0;
+	exp.mask.dst.u.all = 0;
+	exp.mask.dst.u.gre.key = 0xffffffff;
+	exp.mask.dst.u.gre.version = 0xff;
+	exp.mask.dst.u.gre.protocol = 0xffff;
+	exp.mask.dst.ip = 0xffffffff;
+	exp.mask.dst.protonum = 0xffff;
+			
+	exp.seq = seq;
+	exp.expectfn = pptp_expectfn;
+
+	exp.help.exp_pptp_info.pac_call_id = ntohs(callid);
+	exp.help.exp_pptp_info.pns_call_id = ntohs(peer_callid);
+
+	DEBUGP("calling expect_related ");
+	DUMP_TUPLE_RAW(&exp.tuple);
+	
+	/* Add GRE keymap entries */
+	if (ip_ct_gre_keymap_add(&exp, &exp.tuple, 0) != 0)
+		return 1;
+
+	invert_tuplepr(&inv_tuple, &exp.tuple);
+	if (ip_ct_gre_keymap_add(&exp, &inv_tuple, 1) != 0) {
+		ip_ct_gre_keymap_destroy(&exp);
+		return 1;
+	}
+	
+	if (ip_conntrack_expect_related(master, &exp) != 0) {
+		ip_ct_gre_keymap_destroy(&exp);
+		DEBUGP("cannot expect_related()\n");
+		return 1;
+	}
+
+	/* tuple in reply direction, PAC->PNS */
+	exp.tuple.src.ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
+	exp.tuple.src.u.gre.key = htonl(ntohs(callid));
+	exp.tuple.dst.ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
+	exp.tuple.dst.u.gre.key = htonl(ntohs(peer_callid));
+
+	DEBUGP("calling expect_related ");
+	DUMP_TUPLE_RAW(&exp.tuple);
+	
+	/* Add GRE keymap entries */
+	ip_ct_gre_keymap_add(&exp, &exp.tuple, 0);
+	invert_tuplepr(&inv_tuple, &exp.tuple);
+	ip_ct_gre_keymap_add(&exp, &inv_tuple, 1);
+	/* FIXME: cannot handle error correctly, since we need to free
+	 * the above keymap :( */
+	
+	if (ip_conntrack_expect_related(master, &exp) != 0) {
+		/* free the second pair of keypmaps */
+		ip_ct_gre_keymap_destroy(&exp);
+		DEBUGP("cannot expect_related():\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+static inline int 
+pptp_inbound_pkt(struct tcphdr *tcph,
+		 struct pptp_pkt_hdr *pptph, 
+		 size_t datalen,
+		 struct ip_conntrack *ct,
+		 enum ip_conntrack_info ctinfo)
+{
+	struct PptpControlHeader *ctlh;
+        union pptp_ctrl_union pptpReq;
+	
+	struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
+	u_int16_t msg, *cid, *pcid;
+	u_int32_t seq;	
+
+	ctlh = (struct PptpControlHeader *) 
+		((char *) pptph + sizeof(struct pptp_pkt_hdr));
+	pptpReq.rawreq = (void *) 
+		((char *) ctlh + sizeof(struct PptpControlHeader));
+
+	msg = ntohs(ctlh->messageType);
+	DEBUGP("inbound control message %s\n", strMName[msg]);
+
+	switch (msg) {
+	case PPTP_START_SESSION_REPLY:
+		/* server confirms new control session */
+		if (info->sstate < PPTP_SESSION_REQUESTED) {
+			DEBUGP("%s without START_SESS_REQUEST\n",
+				strMName[msg]);
+			break;
+		}
+		if (pptpReq.srep->resultCode == PPTP_START_OK)
+			info->sstate = PPTP_SESSION_CONFIRMED;
+		else 
+			info->sstate = PPTP_SESSION_ERROR;
+		break;
+
+	case PPTP_STOP_SESSION_REPLY:
+		/* server confirms end of control session */
+		if (info->sstate > PPTP_SESSION_STOPREQ) {
+			DEBUGP("%s without STOP_SESS_REQUEST\n",
+				strMName[msg]);
+			break;
+		}
+		if (pptpReq.strep->resultCode == PPTP_STOP_OK)
+			info->sstate = PPTP_SESSION_NONE;
+		else
+			info->sstate = PPTP_SESSION_ERROR;
+		break;
+
+	case PPTP_OUT_CALL_REPLY:
+		/* server accepted call, we now expect GRE frames */
+		if (info->sstate != PPTP_SESSION_CONFIRMED) {
+			DEBUGP("%s but no session\n", strMName[msg]);
+			break;
+		}
+		if (info->cstate != PPTP_CALL_OUT_REQ &&
+		    info->cstate != PPTP_CALL_OUT_CONF) {
+			DEBUGP("%s without OUTCALL_REQ\n", strMName[msg]);
+			break;
+		}
+		if (pptpReq.ocack->resultCode != PPTP_OUTCALL_CONNECT) {
+			info->cstate = PPTP_CALL_NONE;
+			break;
+		}
+
+		cid = &pptpReq.ocack->callID;
+		pcid = &pptpReq.ocack->peersCallID;
+
+		info->pac_call_id = ntohs(*cid);
+		
+		if (htons(info->pns_call_id) != *pcid) {
+			DEBUGP("%s for unknown callid %u\n",
+				strMName[msg], ntohs(*pcid));
+			break;
+		}
+
+		DEBUGP("%s, CID=%X, PCID=%X\n", strMName[msg], 
+			ntohs(*cid), ntohs(*pcid));
+		
+		info->cstate = PPTP_CALL_OUT_CONF;
+
+		seq = ntohl(tcph->seq) + ((void *)pcid - (void *)pptph);
+		if (exp_gre(ct, seq, *cid, *pcid) != 0)
+			printk("ip_conntrack_pptp: error during exp_gre\n");
+		break;
+
+	case PPTP_IN_CALL_REQUEST:
+		/* server tells us about incoming call request */
+		if (info->sstate != PPTP_SESSION_CONFIRMED) {
+			DEBUGP("%s but no session\n", strMName[msg]);
+			break;
+		}
+		pcid = &pptpReq.icack->peersCallID;
+		DEBUGP("%s, PCID=%X\n", strMName[msg], ntohs(*pcid));
+		info->cstate = PPTP_CALL_IN_REQ;
+		info->pac_call_id= ntohs(*pcid);
+		break;
+
+	case PPTP_IN_CALL_CONNECT:
+		/* server tells us about incoming call established */
+		if (info->sstate != PPTP_SESSION_CONFIRMED) {
+			DEBUGP("%s but no session\n", strMName[msg]);
+			break;
+		}
+		if (info->sstate != PPTP_CALL_IN_REP
+		    && info->sstate != PPTP_CALL_IN_CONF) {
+			DEBUGP("%s but never sent IN_CALL_REPLY\n",
+				strMName[msg]);
+			break;
+		}
+
+		pcid = &pptpReq.iccon->peersCallID;
+		cid = &info->pac_call_id;
+
+		if (info->pns_call_id != ntohs(*pcid)) {
+			DEBUGP("%s for unknown CallID %u\n", 
+				strMName[msg], ntohs(*cid));
+			break;
+		}
+
+		DEBUGP("%s, PCID=%X\n", strMName[msg], ntohs(*pcid));
+		info->cstate = PPTP_CALL_IN_CONF;
+
+		/* we expect a GRE connection from PAC to PNS */
+		seq = ntohl(tcph->seq) + ((void *)pcid - (void *)pptph);
+		if (exp_gre(ct, seq, *cid, *pcid) != 0)
+			printk("ip_conntrack_pptp: error during exp_gre\n");
+
+		break;
+
+	case PPTP_CALL_DISCONNECT_NOTIFY:
+		/* server confirms disconnect */
+		cid = &pptpReq.disc->callID;
+		DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*cid));
+		info->cstate = PPTP_CALL_NONE;
+
+		/* untrack this call id, unexpect GRE packets */
+		pptp_timeout_related(ct, ctinfo);
+		break;
+
+	case PPTP_WAN_ERROR_NOTIFY:
+		break;
+
+	case PPTP_ECHO_REQUEST:
+	case PPTP_ECHO_REPLY:
+		/* I don't have to explain these ;) */
+		break;
+	default:
+		DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX)
+			? strMName[msg]:strMName[0], msg);
+		break;
+	}
+
+	return NF_ACCEPT;
+
+}
+
+static inline int
+pptp_outbound_pkt(struct tcphdr *tcph,
+		  struct pptp_pkt_hdr *pptph,
+		  size_t datalen,
+		  struct ip_conntrack *ct,
+		  enum ip_conntrack_info ctinfo)
+{
+	struct PptpControlHeader *ctlh;
+        union pptp_ctrl_union pptpReq;
+	struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
+	u_int16_t msg, *cid, *pcid;
+
+	ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph));
+	pptpReq.rawreq = (void *) ((void *) ctlh + sizeof(*ctlh));
+
+	msg = ntohs(ctlh->messageType);
+	DEBUGP("outbound control message %s\n", strMName[msg]);
+
+	switch (msg) {
+	case PPTP_START_SESSION_REQUEST:
+		/* client requests for new control session */
+		if (info->sstate != PPTP_SESSION_NONE) {
+			DEBUGP("%s but we already have one",
+				strMName[msg]);
+		}
+		info->sstate = PPTP_SESSION_REQUESTED;
+		break;
+	case PPTP_STOP_SESSION_REQUEST:
+		/* client requests end of control session */
+		info->sstate = PPTP_SESSION_STOPREQ;
+		break;
+
+	case PPTP_OUT_CALL_REQUEST:
+		/* client initiating connection to server */
+		if (info->sstate != PPTP_SESSION_CONFIRMED) {
+			DEBUGP("%s but no session\n",
+				strMName[msg]);
+			break;
+		}
+		info->cstate = PPTP_CALL_OUT_REQ;
+		/* track PNS call id */
+		cid = &pptpReq.ocreq->callID;
+		DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*cid));
+		info->pns_call_id = ntohs(*cid);
+		break;
+	case PPTP_IN_CALL_REPLY:
+		/* client answers incoming call */
+		if (info->cstate != PPTP_CALL_IN_REQ
+		    && info->cstate != PPTP_CALL_IN_REP) {
+			DEBUGP("%s without incall_req\n", 
+				strMName[msg]);
+			break;
+		}
+		if (pptpReq.icack->resultCode != PPTP_INCALL_ACCEPT) {
+			info->cstate = PPTP_CALL_NONE;
+			break;
+		}
+		pcid = &pptpReq.icack->peersCallID;
+		if (info->pac_call_id != ntohs(*pcid)) {
+			DEBUGP("%s for unknown call %u\n", 
+				strMName[msg], ntohs(*pcid));
+			break;
+		}
+		DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*pcid));
+		/* part two of the three-way handshake */
+		info->cstate = PPTP_CALL_IN_REP;
+		info->pns_call_id = ntohs(pptpReq.icack->callID);
+		break;
+
+	case PPTP_CALL_CLEAR_REQUEST:
+		/* client requests hangup of call */
+		if (info->sstate != PPTP_SESSION_CONFIRMED) {
+			DEBUGP("CLEAR_CALL but no session\n");
+			break;
+		}
+		/* FUTURE: iterate over all calls and check if
+		 * call ID is valid.  We don't do this without newnat,
+		 * because we only know about last call */
+		info->cstate = PPTP_CALL_CLEAR_REQ;
+		break;
+	case PPTP_SET_LINK_INFO:
+		break;
+	case PPTP_ECHO_REQUEST:
+	case PPTP_ECHO_REPLY:
+		/* I don't have to explain these ;) */
+		break;
+	default:
+		DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX)? 
+			strMName[msg]:strMName[0], msg);
+		/* unknown: no need to create GRE masq table entry */
+		break;
+	}
+
+	return NF_ACCEPT;
+}
+
+
+/* track caller id inside control connection, call expect_related */
+static int 
+conntrack_pptp_help(const struct iphdr *iph, size_t len,
+		    struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
+
+{
+	struct pptp_pkt_hdr *pptph;
+	
+	struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
+	u_int32_t tcplen = len - iph->ihl * 4;
+	u_int32_t datalen = tcplen - tcph->doff * 4;
+	void *datalimit;
+	int dir = CTINFO2DIR(ctinfo);
+	struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
+
+	int oldsstate, oldcstate;
+	int ret;
+
+	/* don't do any tracking before tcp handshake complete */
+	if (ctinfo != IP_CT_ESTABLISHED 
+	    && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) {
+		DEBUGP("ctinfo = %u, skipping\n", ctinfo);
+		return NF_ACCEPT;
+	}
+	
+	/* not a complete TCP header? */
+	if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4) {
+		DEBUGP("tcplen = %u\n", tcplen);
+		return NF_ACCEPT;
+	}
+
+	/* checksum invalid? */
+	if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
+			csum_partial((char *) tcph, tcplen, 0))) {
+		printk(KERN_NOTICE __FILE__ ": bad csum\n");
+		/* W2K PPTP server sends TCP packets with wrong checksum :(( */
+		//return NF_ACCEPT;
+	}
+
+	if (tcph->fin || tcph->rst) {
+		DEBUGP("RST/FIN received, timeouting GRE\n");
+		/* can't do this after real newnat */
+		info->cstate = PPTP_CALL_NONE;
+
+		/* untrack this call id, unexpect GRE packets */
+		pptp_timeout_related(ct, ctinfo);
+	}
+
+
+	pptph = (struct pptp_pkt_hdr *) ((void *) tcph + tcph->doff * 4);
+	datalimit = (void *) pptph + datalen;
+
+	/* not a full pptp packet header? */
+	if ((void *) pptph+sizeof(*pptph) >= datalimit) {
+		DEBUGP("no full PPTP header, can't track\n");
+		return NF_ACCEPT;
+	}
+	
+	/* if it's not a control message we can't do anything with it */
+        if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL ||
+	    ntohl(pptph->magicCookie) != PPTP_MAGIC_COOKIE) {
+		DEBUGP("not a control packet\n");
+		return NF_ACCEPT;
+	}
+
+	oldsstate = info->sstate;
+	oldcstate = info->cstate;
+
+	LOCK_BH(&ip_pptp_lock);
+
+	/* FIXME: We just blindly assume that the control connection is always
+	 * established from PNS->PAC.  However, RFC makes no guarantee */
+	if (dir == IP_CT_DIR_ORIGINAL)
+		/* client -> server (PNS -> PAC) */
+		ret = pptp_outbound_pkt(tcph, pptph, datalen, ct, ctinfo);
+	else
+		/* server -> client (PAC -> PNS) */
+		ret = pptp_inbound_pkt(tcph, pptph, datalen, ct, ctinfo);
+	DEBUGP("sstate: %d->%d, cstate: %d->%d\n",
+		oldsstate, info->sstate, oldcstate, info->cstate);
+	UNLOCK_BH(&ip_pptp_lock);
+
+	return ret;
+}
+
+/* control protocol helper */
+static struct ip_conntrack_helper pptp = { 
+	.list = { NULL, NULL },
+	.name = "pptp", 
+	.flags = IP_CT_HELPER_F_REUSE_EXPECT,
+	.me = THIS_MODULE,
+	.max_expected = 2,
+	.timeout = 0,
+	.tuple = { .src = { .ip = 0, 
+		 	    .u = { .tcp = { .port =  
+				    __constant_htons(PPTP_CONTROL_PORT) } } 
+			  }, 
+		   .dst = { .ip = 0, 
+			    .u = { .all = 0 },
+			    .protonum = IPPROTO_TCP
+			  } 
+		 },
+	.mask = { .src = { .ip = 0, 
+			   .u = { .tcp = { .port = 0xffff } } 
+			 }, 
+		  .dst = { .ip = 0, 
+			   .u = { .all = 0 },
+			   .protonum = 0xffff 
+		 	 } 
+		},
+	.help = conntrack_pptp_help
+};
+
+/* ip_conntrack_pptp initialization */
+static int __init init(void)
+{
+	int retcode;
+
+	DEBUGP(__FILE__ ": registering helper\n");
+	if ((retcode = ip_conntrack_helper_register(&pptp))) {
+                printk(KERN_ERR "Unable to register conntrack application "
+				"helper for pptp: %d\n", retcode);
+		return -EIO;
+	}
+
+	printk("ip_conntrack_pptp version %s loaded\n", IP_CT_PPTP_VERSION);
+	return 0;
+}
+
+static void __exit fini(void)
+{
+	ip_conntrack_helper_unregister(&pptp);
+	printk("ip_conntrack_pptp version %s unloaded\n", IP_CT_PPTP_VERSION);
+}
+
+module_init(init);
+module_exit(fini);
+
+EXPORT_SYMBOL(ip_pptp_lock);
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_conntrack_pptp_priv.h linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_pptp_priv.h
--- linux-2.4.29/net/ipv4/netfilter/ip_conntrack_pptp_priv.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_pptp_priv.h	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,24 @@
+#ifndef _IP_CT_PPTP_PRIV_H
+#define _IP_CT_PPTP_PRIV_H
+
+/* PptpControlMessageType names */
+static const char *strMName[] = {
+	"UNKNOWN_MESSAGE",
+	"START_SESSION_REQUEST",
+	"START_SESSION_REPLY",
+	"STOP_SESSION_REQUEST",
+	"STOP_SESSION_REPLY",
+	"ECHO_REQUEST",
+	"ECHO_REPLY",
+	"OUT_CALL_REQUEST",
+	"OUT_CALL_REPLY",
+	"IN_CALL_REQUEST",
+	"IN_CALL_REPLY",
+	"IN_CALL_CONNECT",
+	"CALL_CLEAR_REQUEST",
+	"CALL_DISCONNECT_NOTIFY",
+	"WAN_ERROR_NOTIFY",
+	"SET_LINK_INFO"
+};
+
+#endif
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_conntrack_proto_generic.c linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_proto_generic.c
--- linux-2.4.29/net/ipv4/netfilter/ip_conntrack_proto_generic.c	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_proto_generic.c	2005-06-14 02:11:50.000000000 +0100
@@ -41,9 +41,9 @@
 /* Returns verdict for packet, or -1 for invalid. */
 static int established(struct ip_conntrack *conntrack,
 		       struct iphdr *iph, size_t len,
-		       enum ip_conntrack_info conntrackinfo)
+		       enum ip_conntrack_info ctinfo)
 {
-	ip_ct_refresh(conntrack, ip_ct_generic_timeout);
+	ip_ct_refresh_acct(conntrack, ctinfo, iph, ip_ct_generic_timeout);
 	return NF_ACCEPT;
 }
 
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_conntrack_proto_gre.c linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_proto_gre.c
--- linux-2.4.29/net/ipv4/netfilter/ip_conntrack_proto_gre.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_proto_gre.c	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,345 @@
+/*
+ * ip_conntrack_proto_gre.c - Version 1.2 
+ *
+ * Connection tracking protocol helper module for GRE.
+ *
+ * GRE is a generic encapsulation protocol, which is generally not very
+ * suited for NAT, as it has no protocol-specific part as port numbers.
+ *
+ * It has an optional key field, which may help us distinguishing two 
+ * connections between the same two hosts.
+ *
+ * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784 
+ *
+ * PPTP is built on top of a modified version of GRE, and has a mandatory
+ * field called "CallID", which serves us for the same purpose as the key
+ * field in plain GRE.
+ *
+ * Documentation about PPTP can be found in RFC 2637
+ *
+ * (C) 2000-2003 by Harald Welte <laforge@gnumonks.org>
+ *
+ * Development of this code funded by Astaro AG (http://www.astaro.com/)
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/timer.h>
+#include <linux/netfilter.h>
+#include <linux/ip.h>
+#include <linux/in.h>
+#include <linux/list.h>
+
+#include <linux/netfilter_ipv4/lockhelp.h>
+
+DECLARE_RWLOCK(ip_ct_gre_lock);
+#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_ct_gre_lock)
+#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_ct_gre_lock)
+
+#include <linux/netfilter_ipv4/listhelp.h>
+#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+#include <linux/netfilter_ipv4/ip_conntrack_core.h>
+
+#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
+#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
+MODULE_DESCRIPTION("netfilter connection tracking protocol helper for GRE");
+
+/* shamelessly stolen from ip_conntrack_proto_udp.c */
+#define GRE_TIMEOUT		(30*HZ)
+#define GRE_STREAM_TIMEOUT	(180*HZ)
+
+#if 0
+#define DEBUGP(format, args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__ \
+		                       ": " format, ## args)
+#define DUMP_TUPLE_GRE(x) printk("%u.%u.%u.%u:0x%x -> %u.%u.%u.%u:0x%x:%u:0x%x\n", \
+			NIPQUAD((x)->src.ip), ntohl((x)->src.u.gre.key), \
+			NIPQUAD((x)->dst.ip), ntohl((x)->dst.u.gre.key), \
+			(x)->dst.u.gre.version, \
+			ntohs((x)->dst.u.gre.protocol))
+#else
+#define DEBUGP(x, args...)
+#define DUMP_TUPLE_GRE(x)
+#endif
+				
+/* GRE KEYMAP HANDLING FUNCTIONS */
+static LIST_HEAD(gre_keymap_list);
+
+static inline int gre_key_cmpfn(const struct ip_ct_gre_keymap *km,
+				const struct ip_conntrack_tuple *t)
+{
+	return ((km->tuple.src.ip == t->src.ip) &&
+		(km->tuple.dst.ip == t->dst.ip) &&
+	        (km->tuple.dst.protonum == t->dst.protonum) &&
+	        (km->tuple.dst.u.all == t->dst.u.all));
+}
+
+/* look up the source key for a given tuple */
+static u_int32_t gre_keymap_lookup(struct ip_conntrack_tuple *t)
+{
+	struct ip_ct_gre_keymap *km;
+	u_int32_t key;
+
+	READ_LOCK(&ip_ct_gre_lock);
+	km = LIST_FIND(&gre_keymap_list, gre_key_cmpfn,
+			struct ip_ct_gre_keymap *, t);
+	if (!km) {
+		READ_UNLOCK(&ip_ct_gre_lock);
+		return 0;
+	}
+
+	key = km->tuple.src.u.gre.key;
+	READ_UNLOCK(&ip_ct_gre_lock);
+
+	return key;
+}
+
+/* add a single keymap entry, associate with specified expect */
+int ip_ct_gre_keymap_add(struct ip_conntrack_expect *exp,
+			 struct ip_conntrack_tuple *t, int reply)
+{
+	struct ip_ct_gre_keymap *km;
+
+	km = kmalloc(sizeof(*km), GFP_ATOMIC);
+	if (!km)
+		return -1;
+
+	/* initializing list head should be sufficient */
+	memset(km, 0, sizeof(*km));
+
+	memcpy(&km->tuple, t, sizeof(*t));
+
+	if (!reply)
+		exp->proto.gre.keymap_orig = km;
+	else
+		exp->proto.gre.keymap_reply = km;
+
+	DEBUGP("adding new entry %p: ", km);
+	DUMP_TUPLE_GRE(&km->tuple);
+
+	WRITE_LOCK(&ip_ct_gre_lock);
+	list_append(&gre_keymap_list, km);
+	WRITE_UNLOCK(&ip_ct_gre_lock);
+
+	return 0;
+}
+
+/* change the tuple of a keymap entry (used by nat helper) */
+void ip_ct_gre_keymap_change(struct ip_ct_gre_keymap *km,
+			     struct ip_conntrack_tuple *t)
+{
+	DEBUGP("changing entry %p to: ", km);
+	DUMP_TUPLE_GRE(t);
+
+	WRITE_LOCK(&ip_ct_gre_lock);
+	memcpy(&km->tuple, t, sizeof(km->tuple));
+	WRITE_UNLOCK(&ip_ct_gre_lock);
+}
+
+/* destroy the keymap entries associated with specified expect */
+void ip_ct_gre_keymap_destroy(struct ip_conntrack_expect *exp)
+{
+	DEBUGP("entering for exp %p\n", exp);
+	WRITE_LOCK(&ip_ct_gre_lock);
+	if (exp->proto.gre.keymap_orig) {
+		DEBUGP("removing %p from list\n", exp->proto.gre.keymap_orig);
+		list_del(&exp->proto.gre.keymap_orig->list);
+		kfree(exp->proto.gre.keymap_orig);
+		exp->proto.gre.keymap_orig = NULL;
+	}
+	if (exp->proto.gre.keymap_reply) {
+		DEBUGP("removing %p from list\n", exp->proto.gre.keymap_reply);
+		list_del(&exp->proto.gre.keymap_reply->list);
+		kfree(exp->proto.gre.keymap_reply);
+		exp->proto.gre.keymap_reply = NULL;
+	}
+	WRITE_UNLOCK(&ip_ct_gre_lock);
+}
+
+
+/* PUBLIC CONNTRACK PROTO HELPER FUNCTIONS */
+
+/* invert gre part of tuple */
+static int gre_invert_tuple(struct ip_conntrack_tuple *tuple,
+			    const struct ip_conntrack_tuple *orig)
+{
+	tuple->dst.u.gre.protocol = orig->dst.u.gre.protocol;
+	tuple->dst.u.gre.version = orig->dst.u.gre.version;
+
+	tuple->dst.u.gre.key = orig->src.u.gre.key;
+	tuple->src.u.gre.key = orig->dst.u.gre.key;
+
+	return 1;
+}
+
+/* gre hdr info to tuple */
+static int gre_pkt_to_tuple(const void *datah, size_t datalen,
+			    struct ip_conntrack_tuple *tuple)
+{
+	struct gre_hdr *grehdr = (struct gre_hdr *) datah;
+	struct gre_hdr_pptp *pgrehdr = (struct gre_hdr_pptp *) datah;
+	u_int32_t srckey;
+
+	/* core guarantees 8 protocol bytes, no need for size check */
+
+	tuple->dst.u.gre.version = grehdr->version; 
+	tuple->dst.u.gre.protocol = grehdr->protocol;
+
+	switch (grehdr->version) {
+		case GRE_VERSION_1701:
+			if (!grehdr->key) {
+				DEBUGP("Can't track multiple tunnels without key\n");
+				tuple->dst.u.gre.key = 0;
+			} else {
+				tuple->dst.u.gre.key = *(gre_key(grehdr));
+			}
+			break;
+
+		case GRE_VERSION_PPTP:
+			if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) {
+				DEBUGP("GRE_VERSION_PPTP but unknown proto\n");
+				return 0;
+			}
+			tuple->dst.u.gre.key = htonl(ntohs(pgrehdr->call_id));
+			break;
+
+		default:
+			printk(KERN_WARNING "unknown GRE version %hu\n",
+				tuple->dst.u.gre.version);
+			return 0;
+	}
+
+	srckey = gre_keymap_lookup(tuple);
+
+#if 0
+	DEBUGP("found src key %x for tuple ", ntohl(srckey));
+	DUMP_TUPLE_GRE(tuple);
+#endif
+	tuple->src.u.gre.key = srckey;
+
+	return 1;
+}
+
+/* print gre part of tuple */
+static unsigned int gre_print_tuple(char *buffer,
+				    const struct ip_conntrack_tuple *tuple)
+{
+	return sprintf(buffer, "version=%d protocol=0x%04x srckey=0x%x dstkey=0x%x ", 
+			tuple->dst.u.gre.version,
+			ntohs(tuple->dst.u.gre.protocol),
+			ntohl(tuple->src.u.gre.key),
+			ntohl(tuple->dst.u.gre.key));
+}
+
+/* print private data for conntrack */
+static unsigned int gre_print_conntrack(char *buffer,
+					const struct ip_conntrack *ct)
+{
+	return sprintf(buffer, "timeout=%u, stream_timeout=%u ",
+		       (ct->proto.gre.timeout / HZ),
+		       (ct->proto.gre.stream_timeout / HZ));
+}
+
+/* Returns verdict for packet, and may modify conntrack */
+static int gre_packet(struct ip_conntrack *ct,
+		      struct iphdr *iph, size_t len,
+		      enum ip_conntrack_info ctinfo)
+{
+	/* If we've seen traffic both ways, this is a GRE connection.
+	 * Extend timeout. */
+	if (ct->status & IPS_SEEN_REPLY) {
+		ip_ct_refresh_acct(ct, ctinfo, iph,
+				ct->proto.gre.stream_timeout);
+		/* Also, more likely to be important, and not a probe. */
+		set_bit(IPS_ASSURED_BIT, &ct->status);
+	} else
+		ip_ct_refresh_acct(ct, ctinfo, iph, ct->proto.gre.timeout);
+	
+	return NF_ACCEPT;
+}
+
+/* Called when a new connection for this protocol found. */
+static int gre_new(struct ip_conntrack *ct,
+		   struct iphdr *iph, size_t len)
+{ 
+	DEBUGP(": ");
+	DUMP_TUPLE_GRE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+
+	/* initialize to sane value.  Ideally a conntrack helper
+	 * (e.g. in case of pptp) is increasing them */
+	ct->proto.gre.stream_timeout = GRE_STREAM_TIMEOUT;
+	ct->proto.gre.timeout = GRE_TIMEOUT;
+
+	return 1;
+}
+
+/* Called when a conntrack entry has already been removed from the hashes
+ * and is about to be deleted from memory */
+static void gre_destroy(struct ip_conntrack *ct)
+{
+	struct ip_conntrack_expect *master = ct->master;
+
+	DEBUGP(" entering\n");
+
+	if (!master) {
+		DEBUGP("no master exp for ct %p\n", ct);
+		return;
+	}
+
+	ip_ct_gre_keymap_destroy(master);
+}
+
+/* protocol helper struct */
+static struct ip_conntrack_protocol gre = { { NULL, NULL }, IPPROTO_GRE,
+					    "gre", 
+					    gre_pkt_to_tuple,
+					    gre_invert_tuple,
+					    gre_print_tuple,
+					    gre_print_conntrack,
+					    gre_packet,
+					    gre_new,
+					    gre_destroy,
+					    NULL,
+					    THIS_MODULE };
+
+/* ip_conntrack_proto_gre initialization */
+static int __init init(void)
+{
+	int retcode;
+
+	if ((retcode = ip_conntrack_protocol_register(&gre))) {
+                printk(KERN_ERR "Unable to register conntrack protocol "
+			        "helper for gre: %d\n",	retcode);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void __exit fini(void)
+{
+	struct list_head *pos, *n;
+
+	/* delete all keymap entries */
+	WRITE_LOCK(&ip_ct_gre_lock);
+	list_for_each_safe(pos, n, &gre_keymap_list) {
+		DEBUGP("deleting keymap %p at module unload time\n", pos);
+		list_del(pos);
+		kfree(pos);
+	}
+	WRITE_UNLOCK(&ip_ct_gre_lock);
+
+	ip_conntrack_protocol_unregister(&gre); 
+}
+
+EXPORT_SYMBOL(ip_ct_gre_keymap_add);
+EXPORT_SYMBOL(ip_ct_gre_keymap_change);
+EXPORT_SYMBOL(ip_ct_gre_keymap_destroy);
+
+module_init(init);
+module_exit(fini);
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_conntrack_proto_icmp.c linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
--- linux-2.4.29/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	2005-06-14 02:11:52.000000000 +0100
@@ -82,7 +82,7 @@
 			ct->timeout.function((unsigned long)ct);
 	} else {
 		atomic_inc(&ct->proto.icmp.count);
-		ip_ct_refresh(ct, ip_ct_icmp_timeout);
+		ip_ct_refresh_acct(ct, ctinfo, iph, ip_ct_icmp_timeout);
 	}
 
 	return NF_ACCEPT;
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_conntrack_proto_tcp.c linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
--- linux-2.4.29/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2005-06-14 02:11:52.000000000 +0100
@@ -211,7 +211,8 @@
 			set_bit(IPS_ASSURED_BIT, &conntrack->status);
 
 		WRITE_UNLOCK(&tcp_lock);
-		ip_ct_refresh(conntrack, *tcp_timeouts[newconntrack]);
+		ip_ct_refresh_acct(conntrack, ctinfo, iph,
+				*tcp_timeouts[newconntrack]);
 	}
 
 	return NF_ACCEPT;
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_conntrack_proto_udp.c linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_proto_udp.c
--- linux-2.4.29/net/ipv4/netfilter/ip_conntrack_proto_udp.c	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_proto_udp.c	2005-06-14 02:11:52.000000000 +0100
@@ -47,16 +47,17 @@
 /* Returns verdict for packet, and may modify conntracktype */
 static int udp_packet(struct ip_conntrack *conntrack,
 		      struct iphdr *iph, size_t len,
-		      enum ip_conntrack_info conntrackinfo)
+		      enum ip_conntrack_info ctinfo)
 {
 	/* If we've seen traffic both ways, this is some kind of UDP
 	   stream.  Extend timeout. */
 	if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
-		ip_ct_refresh(conntrack, ip_ct_udp_timeout_stream);
+		ip_ct_refresh_acct(conntrack, ctinfo, iph,
+				   ip_ct_udp_timeout_stream);
 		/* Also, more likely to be important, and not a probe */
 		set_bit(IPS_ASSURED_BIT, &conntrack->status);
 	} else
-		ip_ct_refresh(conntrack, ip_ct_udp_timeout);
+		ip_ct_refresh_acct(conntrack, ctinfo, iph, ip_ct_udp_timeout);
 
 	return NF_ACCEPT;
 }
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_standalone.c
--- linux-2.4.29/net/ipv4/netfilter/ip_conntrack_standalone.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_conntrack_standalone.c	2005-06-14 02:11:50.000000000 +0100
@@ -79,6 +79,17 @@
 	return len;
 }
 
+#ifdef CONFIG_IP_NF_CT_ACCT
+static unsigned int
+print_counters(char *buffer, struct ip_conntrack_counter *counter)
+{
+	return sprintf(buffer, "packets=%llu bytes=%llu ",
+			counter->packets, counter->bytes);
+}
+#else
+#define print_counters(x, y)	0
+#endif
+
 static unsigned int
 print_conntrack(char *buffer, struct ip_conntrack *conntrack)
 {
@@ -98,15 +109,22 @@
 	len += print_tuple(buffer + len,
 			   &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
 			   proto);
+	len += print_counters(buffer + len,
+			      &conntrack->counters[IP_CT_DIR_ORIGINAL]);
 	if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)))
 		len += sprintf(buffer + len, "[UNREPLIED] ");
 	len += print_tuple(buffer + len,
 			   &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
 			   proto);
+	len += print_counters(buffer + len,
+			      &conntrack->counters[IP_CT_DIR_REPLY]);
 	if (test_bit(IPS_ASSURED_BIT, &conntrack->status))
 		len += sprintf(buffer + len, "[ASSURED] ");
 	len += sprintf(buffer + len, "use=%u ",
 		       atomic_read(&conntrack->ct_general.use));
+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
+	len += sprintf(buffer + len, "mark=%ld ", conntrack->mark);
+#endif
 	len += sprintf(buffer + len, "\n");
 
 	return len;
@@ -127,14 +145,17 @@
 	if (DIRECTION(hash))
 		return 0;
 
-	if ((*upto)++ < offset)
+	if (*upto < offset) {
+		(*upto)++;
 		return 0;
+	}
 
 	newlen = print_conntrack(buffer + *len, hash->ctrack);
 	if (*len + newlen > maxlen)
 		return 1;
-	else *len += newlen;
 
+	*len += newlen;
+	(*upto)++;
 	return 0;
 }
 
@@ -161,7 +182,10 @@
 		unsigned int last_len;
 		struct ip_conntrack_expect *expect
 			= (struct ip_conntrack_expect *)e;
-		if (upto++ < offset) continue;
+		if (upto < offset) {
+			upto++;
+			continue;
+		}
 
 		last_len = len;
 		len += print_expect(buffer + len, expect);
@@ -169,6 +193,7 @@
 			len = last_len;
 			goto finished;
 		}
+		upto++;
 	}
 
  finished:
@@ -179,6 +204,125 @@
 	return len;
 }
 
+/* Map sparse protocol list to dense stats array for proto's we care about */
+static int proto_map[IPPROTO_MAX];
+
+static int
+list_conntracks_stats(char *buffer, char **start, off_t offset, int length)
+{
+	unsigned int i;
+	unsigned int len = 0;
+	struct list_head *p;
+	struct ip_conntrack_tuple_hash *hash;
+
+	unsigned int ct = 0;         /* number of conntracks found       */
+	unsigned int ctreply = 0;    /* number of reply conntracks found */
+	unsigned int expect = 0;     /* number of expects found          */
+	unsigned int unreplied = 0;  /* count unreplied conntracks       */
+	unsigned int hashmax = 0;    /* max ct per hash bucket found     */
+	unsigned int hashmin = 9999; /* min ct per hash bucket found     */
+	unsigned int hashcnt;        /* count ct in current hash bucket  */
+	unsigned int proto;          /* temp protocol number */
+#define MAXSTATS 32
+	unsigned int hashfreq[MAXSTATS];  /* frequency count of list depth */
+	unsigned int protonum[MAXSTATS];  /* frequency count of protocols  */
+	unsigned int prototime[MAXSTATS]; /* timeout count of protocols  */
+
+	/* proto_map should only be initialized once...
+	 * but then this is all ridiculously inefficent...  */
+	for (i = 0; i < IPPROTO_MAX; i++) {
+        	proto_map[i] = 0;
+	}
+	i = 1;
+	proto_map[IPPROTO_ICMP] = i++;
+	proto_map[IPPROTO_TCP]  = i++;
+	proto_map[IPPROTO_UDP]  = i++;
+	proto_map[IPPROTO_GRE]  = i++;
+	proto_map[IPPROTO_IPV6] = i++;
+	proto_map[IPPROTO_ESP]  = i++;
+	proto_map[IPPROTO_AH]   = i++;
+
+	for (i = 0; i < MAXSTATS; i++) {
+		hashfreq[i] = protonum[i] = prototime[i] = 0;
+	}
+
+	READ_LOCK(&ip_conntrack_lock);
+
+	/*
+	 * count hash-table entries
+	 */
+	for (i = 0; i < ip_conntrack_htable_size; i++) {
+		hashcnt = 0;
+		list_for_each(p, &ip_conntrack_hash[i]) {
+			hashcnt++;
+
+			/* count originals differently */
+			hash = (struct ip_conntrack_tuple_hash *)p;
+			if (DIRECTION(hash)) {
+				ctreply++;
+				continue;
+			}
+			ct++;
+
+			proto = hash->ctrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
+			proto = (proto < IPPROTO_MAX) ? proto_map[proto] : 0;
+			protonum[proto]++;
+			if (timer_pending(&hash->ctrack->timeout))
+				prototime[proto] += (hash->ctrack->timeout.expires - jiffies)/HZ;
+
+			if (!(test_bit(IPS_SEEN_REPLY_BIT, &hash->ctrack->status)))
+				unreplied++;
+		}
+		if (hashmin > hashcnt) 
+			hashmin = hashcnt;
+		if (hashmax < hashcnt)
+			hashmax = hashcnt;
+		/* all counts above 31 accumulate in bucket 31 */
+		if (hashcnt >= MAXSTATS)
+			hashcnt = MAXSTATS-1;
+		hashfreq[hashcnt]++;
+	}
+
+	/*
+	 * count the expect list
+	 */
+	list_for_each(p, &ip_conntrack_expect_list) {
+		expect++;
+	}
+
+	READ_UNLOCK(&ip_conntrack_lock);
+
+	len = sprintf(buffer, 
+		"ct=%d ctreply=%d expect=%d unreplied=%d\n"
+		"hash min=%d max=%d avg=%d\n"
+		"f0=%d f1=%d f2=%d f3=%d f4=%d f5=%d f6=%d  fmax=%d\n"
+		"count othr=%d icmp=%d tcp=%d udp=%d gre=%d ip6=%d esp=%d ah=%d\n"
+		"avtmo othr=%d icmp=%d tcp=%d udp=%d gre=%d ip6=%d esp=%d ah=%d\n",
+		ct, ctreply, expect, unreplied,
+		hashmin, hashmax, (ct+ctreply)/ip_conntrack_htable_size,
+		hashfreq[0], hashfreq[1], hashfreq[2], hashfreq[3],
+		hashfreq[4], hashfreq[5], hashfreq[6], hashfreq[MAXSTATS-1],
+		protonum[0], protonum[1], protonum[2], protonum[3],
+		protonum[4], protonum[5], protonum[6], protonum[7],
+		protonum[0] ? prototime[0]/protonum[0] : 0,
+		protonum[1] ? prototime[1]/protonum[1] : 0,
+		protonum[2] ? prototime[2]/protonum[2] : 0,
+		protonum[3] ? prototime[3]/protonum[3] : 0,
+		protonum[4] ? prototime[4]/protonum[4] : 0,
+		protonum[5] ? prototime[5]/protonum[5] : 0,
+		protonum[6] ? prototime[6]/protonum[6] : 0,
+		protonum[7] ? prototime[7]/protonum[7] : 0);
+
+	len -= offset;
+	if (len > length)
+		len = length;
+	if (len < 0)
+		len = 0;
+
+	*start = buffer + offset;
+	return len;
+}
+
 static unsigned int ip_confirm(unsigned int hooknum,
 			       struct sk_buff **pskb,
 			       const struct net_device *in,
@@ -353,6 +497,10 @@
 	if (!proc) goto cleanup_init;
 	proc->owner = THIS_MODULE;
 
+	proc = proc_net_create("ip_conntrack_stat",0,list_conntracks_stats);
+	if (!proc) goto cleanup_init;
+	proc->owner = THIS_MODULE;
+
 	ret = nf_register_hook(&ip_conntrack_in_ops);
 	if (ret < 0) {
 		printk("ip_conntrack: can't register pre-routing hook.\n");
@@ -403,6 +551,7 @@
 	nf_unregister_hook(&ip_conntrack_in_ops);
  cleanup_proc:
 	proc_net_remove("ip_conntrack");
+	proc_net_remove("ip_conntrack_stat");
  cleanup_init:
 	ip_conntrack_cleanup();
  cleanup_nothing:
@@ -475,7 +624,7 @@
 EXPORT_SYMBOL(ip_conntrack_helper_register);
 EXPORT_SYMBOL(ip_conntrack_helper_unregister);
 EXPORT_SYMBOL(ip_ct_selective_cleanup);
-EXPORT_SYMBOL(ip_ct_refresh);
+EXPORT_SYMBOL(ip_ct_refresh_acct);
 EXPORT_SYMBOL(ip_ct_find_proto);
 EXPORT_SYMBOL(__ip_ct_find_proto);
 EXPORT_SYMBOL(ip_ct_find_helper);
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_fw_compat_masq.c linux-2.4.29-uc1/net/ipv4/netfilter/ip_fw_compat_masq.c
--- linux-2.4.29/net/ipv4/netfilter/ip_fw_compat_masq.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_fw_compat_masq.c	2005-06-14 02:11:50.000000000 +0100
@@ -254,14 +254,17 @@
 	if (DIRECTION(hash))
 		return 0;
 
-	if ((*upto)++ < offset)
+	if (*upto < offset) {
+		(*upto)++;
 		return 0;
+	}
 
 	newlen = print_masq(buffer + *len, hash->ctrack);
 	if (*len + newlen > maxlen)
 		return 1;
-	else *len += newlen;
 
+	*len += newlen;
+	(*upto)++;
 	return 0;
 }
 
@@ -271,7 +274,7 @@
 {
 	unsigned int i;
 	int len = 0;
-	off_t upto = 1;
+	off_t upto = 0;
 
 	/* Header: first record */
 	if (offset == 0) {
@@ -280,8 +283,12 @@
 		sprintf(temp,
 			"Prc FromIP   FPrt ToIP     TPrt Masq Init-seq  Delta PDelta Expires (free=0,0,0)");
 		len = sprintf(buffer, "%-127s\n", temp);
-		offset = 1;
+		if (len > length) {
+			len = 0;
+			goto finished;
+		}
 	}
+	upto++;
 
 	READ_LOCK(&ip_conntrack_lock);
 	/* Traverse hash; print originals then reply. */
@@ -293,6 +300,7 @@
 	}
 	READ_UNLOCK(&ip_conntrack_lock);
 
+ finished:
 	/* `start' hack - see fs/proc/generic.c line ~165 */
 	*start = (char *)((unsigned int)upto - offset);
 	return len;
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_nat_core.c linux-2.4.29-uc1/net/ipv4/netfilter/ip_nat_core.c
--- linux-2.4.29/net/ipv4/netfilter/ip_nat_core.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_nat_core.c	2005-06-14 02:11:50.000000000 +0100
@@ -157,8 +157,8 @@
 				continue;
 		}
 
-		if ((mr->range[i].flags & IP_NAT_RANGE_PROTO_SPECIFIED)
-		    && proto->in_range(&newtuple, IP_NAT_MANIP_SRC,
+		if (!(mr->range[i].flags & IP_NAT_RANGE_PROTO_SPECIFIED)
+		    || proto->in_range(&newtuple, IP_NAT_MANIP_SRC,
 				       &mr->range[i].min, &mr->range[i].max))
 			return 1;
 	}
@@ -424,7 +424,7 @@
 	*tuple = *orig_tuple;
 	while ((rptr = find_best_ips_proto_fast(tuple, mr, conntrack, hooknum))
 	       != NULL) {
-		DEBUGP("Found best for "); DUMP_TUPLE(tuple);
+		DEBUGP("Found best for "); DUMP_TUPLE_RAW(tuple);
 		/* 3) The per-protocol part of the manip is made to
 		   map into the range to make a unique tuple. */
 
@@ -508,6 +508,7 @@
 	struct ip_conntrack_tuple orig_tp;
 	struct ip_nat_info *info = &conntrack->nat.info;
 	int in_hashes = info->initialized;
+	int  cnt = 0;
 
 	MUST_BE_WRITE_LOCKED(&ip_nat_lock);
 	IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
@@ -552,6 +553,7 @@
 #endif
 
 	do {
+		cnt++;
 		if (!get_unique_tuple(&new_tuple, &orig_tp, mr, conntrack,
 				      hooknum)) {
 			DEBUGP("ip_nat_setup_info: Can't get unique for %p.\n",
@@ -564,9 +566,9 @@
 		       HOOK2MANIP(hooknum)==IP_NAT_MANIP_SRC ? "SRC" : "DST",
 		       conntrack);
 		DEBUGP("Original: ");
-		DUMP_TUPLE(&orig_tp);
+		DUMP_TUPLE_RAW(&orig_tp);
 		DEBUGP("New: ");
-		DUMP_TUPLE(&new_tuple);
+		DUMP_TUPLE_RAW(&new_tuple);
 #endif
 
 		/* We now have two tuples (SRCIP/SRCPT/DSTIP/DSTPT):
@@ -582,7 +584,32 @@
 
 		/* Alter conntrack table so it recognizes replies.
                    If fail this race (reply tuple now used), repeat. */
-	} while (!ip_conntrack_alter_reply(conntrack, &reply));
+	} while (!ip_conntrack_alter_reply(conntrack, &reply) && (cnt < 200));
+
+	if (cnt>=200) {
+		/*
+		 * Print out some useful information.
+		 */
+		printk(KERN_ERR, "Failed getting result for packet\n", conntrack);
+
+		/*
+		 * It appears as though we have a tuple which is marked
+		 * as free but a conntrack entry exists for it!!
+		 */
+#undef DEBUGP
+#define DEBUGP printk
+		printk("Hook %u (%s) %p\n", hooknum,
+		       HOOK2MANIP(hooknum)==IP_NAT_MANIP_SRC ? "SRC" : "DST",
+		       conntrack);
+		printk("Original: ");
+		DUMP_TUPLE(&orig_tp);
+		printk("New: ");
+		DUMP_TUPLE(&new_tuple);
+#undef DEBUGP 
+#define DEBUGP(format, args...)
+
+		return NF_DROP;
+	}
 
 	/* FIXME: We can simply used existing conntrack reply tuple
            here --RR */
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_nat_h323.c linux-2.4.29-uc1/net/ipv4/netfilter/ip_nat_h323.c
--- linux-2.4.29/net/ipv4/netfilter/ip_nat_h323.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_nat_h323.c	2005-06-14 02:11:50.000000000 +0100
@@ -0,0 +1,419 @@
+/* 
+ * H.323 'brute force' extension for NAT alteration. 
+ * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
+ *
+ * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project.
+ * (http://www.coritel.it/projects/sofia/nat.html)
+ * Uses Sampsa Ranta's excellent idea on using expectfn to 'bind'
+ * the unregistered helpers to the conntrack entries.
+ */
+
+
+#include <linux/module.h>
+#include <linux/netfilter.h>
+#include <linux/ip.h>
+#include <net/checksum.h>
+#include <net/tcp.h>
+
+#include <linux/netfilter_ipv4/lockhelp.h>
+#include <linux/netfilter_ipv4/ip_nat.h>
+#include <linux/netfilter_ipv4/ip_nat_helper.h>
+#include <linux/netfilter_ipv4/ip_nat_rule.h>
+#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
+
+MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
+MODULE_DESCRIPTION("H.323 'brute force' connection tracking module");
+MODULE_LICENSE("GPL");
+
+DECLARE_LOCK_EXTERN(ip_h323_lock);
+struct module *ip_nat_h323 = THIS_MODULE;
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+/* FIXME: Time out? --RR */
+
+static unsigned int 
+h225_nat_expected(struct sk_buff **pskb,
+		  unsigned int hooknum,
+		  struct ip_conntrack *ct,
+		  struct ip_nat_info *info);
+
+static unsigned int h225_nat_help(struct ip_conntrack *ct,
+				  struct ip_conntrack_expect *exp,
+			 	  struct ip_nat_info *info,
+			 	  enum ip_conntrack_info ctinfo,
+			 	  unsigned int hooknum,
+			 	  struct sk_buff **pskb);
+		  
+static struct ip_nat_helper h245 = 
+	{ { NULL, NULL },
+          "H.245",				/* name */
+	  0,					/* flags */
+	  NULL,					/* module */
+	  { { 0, { 0 } },			/* tuple */
+	    { 0, { 0 }, IPPROTO_TCP } },
+	  { { 0, { tcp: { port: 0xFFFF } } },	/* mask */
+	    { 0, { 0 }, 0xFFFF } },
+	  h225_nat_help,			/* helper */
+	  h225_nat_expected			/* expectfn */
+	};
+
+static unsigned int
+h225_nat_expected(struct sk_buff **pskb,
+		  unsigned int hooknum,
+		  struct ip_conntrack *ct,
+		  struct ip_nat_info *info)
+{
+	struct ip_nat_multi_range mr;
+	u_int32_t newdstip, newsrcip, newip;
+	u_int16_t port;
+	struct ip_ct_h225_expect *exp_info;
+	struct ip_ct_h225_master *master_info;
+	struct ip_conntrack *master = master_ct(ct);
+	unsigned int is_h225, ret;
+	
+	IP_NF_ASSERT(info);
+	IP_NF_ASSERT(master);
+
+	IP_NF_ASSERT(!(info->initialized & (1<<HOOK2MANIP(hooknum))));
+
+	DEBUGP("h225_nat_expected: We have a connection!\n");
+	master_info = &ct->master->expectant->help.ct_h225_info;
+	exp_info = &ct->master->help.exp_h225_info;
+
+	LOCK_BH(&ip_h323_lock);
+
+	DEBUGP("master: ");
+	DUMP_TUPLE_RAW(&master->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+	DUMP_TUPLE_RAW(&master->tuplehash[IP_CT_DIR_REPLY].tuple);
+	DEBUGP("conntrack: ");
+	DUMP_TUPLE_RAW(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+	if (exp_info->dir == IP_CT_DIR_ORIGINAL) {
+		/* Make connection go to the client. */
+		newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
+		newsrcip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
+		DEBUGP("h225_nat_expected: %u.%u.%u.%u->%u.%u.%u.%u (to client)\n",
+		       NIPQUAD(newsrcip), NIPQUAD(newdstip));
+	} else {
+		/* Make the connection go to the server */
+		newdstip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
+		newsrcip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
+		DEBUGP("h225_nat_expected: %u.%u.%u.%u->%u.%u.%u.%u (to server)\n",
+		       NIPQUAD(newsrcip), NIPQUAD(newdstip));
+	}
+	port = exp_info->port;
+	is_h225 = master_info->is_h225 == H225_PORT;
+	UNLOCK_BH(&ip_h323_lock);
+	
+	if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC)
+		newip = newsrcip;
+	else
+		newip = newdstip;
+
+	DEBUGP("h225_nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip));
+
+	mr.rangesize = 1;
+	/* We don't want to manip the per-protocol, just the IPs... */
+	mr.range[0].flags = IP_NAT_RANGE_MAP_IPS;
+	mr.range[0].min_ip = mr.range[0].max_ip = newip;
+
+	/* ... unless we're doing a MANIP_DST, in which case, make
+	   sure we map to the correct port */
+	if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) {
+		mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
+		mr.range[0].min = mr.range[0].max
+			= ((union ip_conntrack_manip_proto)
+				{ tcp: { port: port } });
+	}
+
+	ret = ip_nat_setup_info(ct, &mr, hooknum);
+	
+	if (is_h225) {
+		DEBUGP("h225_nat_expected: H.225, setting NAT helper for %p\n", ct);
+		/* NAT expectfn called with ip_nat_lock write-locked */
+		info->helper = &h245;
+	}
+	return ret;
+}
+
+static int h323_signal_address_fixup(struct ip_conntrack *ct,
+			      	     struct sk_buff **pskb,
+			      	     enum ip_conntrack_info ctinfo)
+{
+	struct iphdr *iph = (*pskb)->nh.iph;
+	struct tcphdr *tcph = (void *)iph + iph->ihl*4;
+	char *data = (char *) tcph + tcph->doff * 4;
+	u_int32_t tcplen = (*pskb)->len - iph->ihl*4;
+	u_int32_t datalen = tcplen - tcph->doff*4;
+	struct ip_ct_h225_master *info = &ct->help.ct_h225_info; 
+	u_int32_t newip;
+	u_int16_t port;
+	int i;
+
+	MUST_BE_LOCKED(&ip_h323_lock);
+
+	DEBUGP("h323_signal_address_fixup: %s %s\n",
+		between(info->seq[IP_CT_DIR_ORIGINAL], ntohl(tcph->seq), ntohl(tcph->seq) + datalen)
+			? "yes" : "no",
+		between(info->seq[IP_CT_DIR_REPLY], ntohl(tcph->seq), ntohl(tcph->seq) + datalen)
+			? "yes" : "no");
+	if (!(between(info->seq[IP_CT_DIR_ORIGINAL], ntohl(tcph->seq), ntohl(tcph->seq) + datalen)
+		|| between(info->seq[IP_CT_DIR_REPLY], ntohl(tcph->seq), ntohl(tcph->seq) + datalen)))
+		return 1;
+
+	DEBUGP("h323_signal_address_fixup: offsets %u + 6  and %u + 6 in %u\n", 
+		info->offset[IP_CT_DIR_ORIGINAL], 
+		info->offset[IP_CT_DIR_REPLY],
+		tcplen);
+	DUMP_TUPLE_RAW(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+	DUMP_TUPLE_RAW(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+
+	for (i = 0; i < IP_CT_DIR_MAX; i++) {
+		DEBUGP("h323_signal_address_fixup: %s %s\n",
+			info->dir == IP_CT_DIR_ORIGINAL ? "original" : "reply",
+			i == IP_CT_DIR_ORIGINAL ? "caller" : "callee");
+		if (!between(info->seq[i], ntohl(tcph->seq), 
+			     ntohl(tcph->seq) + datalen))
+			continue;
+		if (!between(info->seq[i] + 6, ntohl(tcph->seq),
+			     ntohl(tcph->seq) + datalen)) {
+			/* Partial retransmisison. It's a cracker being funky. */
+			if (net_ratelimit()) {
+				printk("H.323_NAT: partial packet %u/6 in %u/%u\n",
+				     info->seq[i],
+				     ntohl(tcph->seq),
+				     ntohl(tcph->seq) + datalen);
+			}
+			return 0;
+		}
+
+		/* Change address inside packet to match way we're mapping
+		   this connection. */
+		if (i == IP_CT_DIR_ORIGINAL) {
+			newip = ct->tuplehash[!info->dir].tuple.dst.ip;
+			port = ct->tuplehash[!info->dir].tuple.dst.u.tcp.port;
+		} else {
+			newip = ct->tuplehash[!info->dir].tuple.src.ip;
+			port = ct->tuplehash[!info->dir].tuple.src.u.tcp.port;
+		}
+
+		DEBUGP("h323_signal_address_fixup: orig %s IP:port %u.%u.%u.%u:%u\n", 
+			i == IP_CT_DIR_ORIGINAL ? "source" : "dest  ", 
+			NIPQUAD(*((u_int32_t *)(data + info->offset[i]))), 
+			ntohs(*((u_int16_t *)(data + info->offset[i] + 4))));
+
+		/* Modify the packet */
+		*(u_int32_t *)(data + info->offset[i]) = newip;
+		*(u_int16_t *)(data + info->offset[i] + 4) = port;
+	
+		DEBUGP("h323_signal_address_fixup:  new %s IP:port %u.%u.%u.%u:%u\n", 
+			i == IP_CT_DIR_ORIGINAL ? "source" : "dest  ", 
+			NIPQUAD(*((u_int32_t *)(data + info->offset[i]))), 
+			ntohs(*((u_int16_t *)(data + info->offset[i] + 4))));
+	}
+
+	/* fix checksum information */
+
+	(*pskb)->csum = csum_partial((char *)tcph + tcph->doff*4,
+				     datalen, 0);
+
+	tcph->check = 0;
+	tcph->check = tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
+				   csum_partial((char *)tcph, tcph->doff*4,
+					   (*pskb)->csum));
+	ip_send_check(iph);
+
+	return 1;
+}
+
+static int h323_data_fixup(struct ip_ct_h225_expect *info,
+			   struct ip_conntrack *ct,
+			   struct sk_buff **pskb,
+			   enum ip_conntrack_info ctinfo,
+			   struct ip_conntrack_expect *expect)
+{
+	u_int32_t newip;
+	u_int16_t port;
+	struct ip_conntrack_tuple newtuple;
+	struct iphdr *iph = (*pskb)->nh.iph;
+	struct tcphdr *tcph = (void *)iph + iph->ihl*4;
+	char *data = (char *) tcph + tcph->doff * 4;
+	u_int32_t tcplen = (*pskb)->len - iph->ihl*4;
+	struct ip_ct_h225_master *master_info = &ct->help.ct_h225_info;
+	int is_h225;
+
+	MUST_BE_LOCKED(&ip_h323_lock);
+	DEBUGP("h323_data_fixup: offset %u + 6 in %u\n", info->offset, tcplen);
+	DUMP_TUPLE_RAW(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+	DUMP_TUPLE_RAW(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+
+	if (!between(expect->seq + 6, ntohl(tcph->seq),
+		    ntohl(tcph->seq) + tcplen - tcph->doff * 4)) {
+		/* Partial retransmisison. It's a cracker being funky. */
+		if (net_ratelimit()) {
+			printk("H.323_NAT: partial packet %u/6 in %u/%u\n",
+			     expect->seq,
+			     ntohl(tcph->seq),
+			     ntohl(tcph->seq) + tcplen - tcph->doff * 4);
+		}
+		return 0;
+	}
+
+	/* Change address inside packet to match way we're mapping
+	   this connection. */
+	if (info->dir == IP_CT_DIR_REPLY) {
+		/* Must be where client thinks server is */
+		newip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
+		/* Expect something from client->server */
+		newtuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
+		newtuple.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
+	} else {
+		/* Must be where server thinks client is */
+		newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
+		/* Expect something from server->client */
+		newtuple.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
+		newtuple.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
+	}
+
+	is_h225 = (master_info->is_h225 == H225_PORT);
+
+	if (is_h225) {
+		newtuple.dst.protonum = IPPROTO_TCP;
+		newtuple.src.u.tcp.port = expect->tuple.src.u.tcp.port;
+	} else {
+		newtuple.dst.protonum = IPPROTO_UDP;
+		newtuple.src.u.udp.port = expect->tuple.src.u.udp.port;
+	}
+	
+	/* Try to get same port: if not, try to change it. */
+	for (port = ntohs(info->port); port != 0; port++) {
+		if (is_h225)
+			newtuple.dst.u.tcp.port = htons(port);
+		else
+			newtuple.dst.u.udp.port = htons(port);
+
+		if (ip_conntrack_change_expect(expect, &newtuple) == 0)
+			break;
+	}
+	if (port == 0) {
+		DEBUGP("h323_data_fixup: no free port found!\n");
+		return 0;
+	}
+
+	port = htons(port);
+
+	DEBUGP("h323_data_fixup: orig IP:port %u.%u.%u.%u:%u\n", 
+		NIPQUAD(*((u_int32_t *)(data + info->offset))), 
+		ntohs(*((u_int16_t *)(data + info->offset + 4))));
+
+	/* Modify the packet */
+	*(u_int32_t *)(data + info->offset) = newip;
+	*(u_int16_t *)(data + info->offset + 4) = port;
+	
+	DEBUGP("h323_data_fixup: new IP:port %u.%u.%u.%u:%u\n", 
+		NIPQUAD(*((u_int32_t *)(data + info->offset))), 
+		ntohs(*((u_int16_t *)(data + info->offset + 4))));
+
+	/* fix checksum information  */
+	/* FIXME: usually repeated multiple times in the case of H.245! */
+
+	(*pskb)->csum = csum_partial((char *)tcph + tcph->doff*4,
+				     tcplen - tcph->doff*4, 0);
+
+	tcph->check = 0;
+	tcph->check = tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
+				   csum_partial((char *)tcph, tcph->doff*4,
+					   (*pskb)->csum));
+	ip_send_check(iph);
+
+	return 1;
+}
+
+static unsigned int h225_nat_help(struct ip_conntrack *ct,
+				  struct ip_conntrack_expect *exp,
+			 	  struct ip_nat_info *info,
+			 	  enum ip_conntrack_info ctinfo,
+			 	  unsigned int hooknum,
+			 	  struct sk_buff **pskb)
+{
+	int dir;
+	struct ip_ct_h225_expect *exp_info;
+	
+	/* Only mangle things once: original direction in POST_ROUTING
+	   and reply direction on PRE_ROUTING. */
+	dir = CTINFO2DIR(ctinfo);
+	DEBUGP("nat_h323: dir %s at hook %s\n",
+	       dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
+	       hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
+	       : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
+	       : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???");
+	if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
+	      || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) {
+		DEBUGP("nat_h323: Not touching dir %s at hook %s\n",
+		       dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
+		       hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
+		       : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
+		       : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???");
+		return NF_ACCEPT;
+	}
+
+	if (!exp) {
+		LOCK_BH(&ip_h323_lock);
+		if (!h323_signal_address_fixup(ct, pskb, ctinfo)) {
+			UNLOCK_BH(&ip_h323_lock);
+			return NF_DROP;
+		}
+		UNLOCK_BH(&ip_h323_lock);
+		return NF_ACCEPT;
+	}
+		
+	exp_info = &exp->help.exp_h225_info;
+
+	LOCK_BH(&ip_h323_lock);
+	if (!h323_data_fixup(exp_info, ct, pskb, ctinfo, exp)) {
+		UNLOCK_BH(&ip_h323_lock);
+		return NF_DROP;
+	}
+	UNLOCK_BH(&ip_h323_lock);
+
+	return NF_ACCEPT;
+}
+
+static struct ip_nat_helper h225 = 
+	{ { NULL, NULL },
+	  "H.225",					/* name */
+	  IP_NAT_HELPER_F_ALWAYS, 			/* flags */
+	  THIS_MODULE,					/* module */
+	  { { 0, { tcp: { port: __constant_htons(H225_PORT) } } },
+	    { 0, { 0 }, IPPROTO_TCP } },		/* tuple */
+	  { { 0, { tcp: { port: 0xFFFF } } },		/* mask */
+	    { 0, { 0 }, 0xFFFF } },
+	  h225_nat_help,				/* helper */
+	  h225_nat_expected				/* expectfn */
+	};
+
+static int __init init(void)
+{
+	int ret;
+	
+	ret = ip_nat_helper_register(&h225);
+
+	if (ret != 0)
+		printk("ip_nat_h323: cannot initialize the module!\n");
+
+	return ret;
+}
+
+static void __exit fini(void)
+{
+	ip_nat_helper_unregister(&h225);
+}
+
+module_init(init);
+module_exit(fini);
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_nat_pptp.c linux-2.4.29-uc1/net/ipv4/netfilter/ip_nat_pptp.c
--- linux-2.4.29/net/ipv4/netfilter/ip_nat_pptp.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_nat_pptp.c	2005-06-14 02:11:51.000000000 +0100
@@ -0,0 +1,475 @@
+/*
+ * ip_nat_pptp.c	- Version $Revision: 1.4 $
+ *
+ * NAT support for PPTP (Point to Point Tunneling Protocol).
+ * PPTP is a a protocol for creating virtual private networks.
+ * It is a specification defined by Microsoft and some vendors
+ * working with Microsoft.  PPTP is built on top of a modified
+ * version of the Internet Generic Routing Encapsulation Protocol.
+ * GRE is defined in RFC 1701 and RFC 1702.  Documentation of
+ * PPTP can be found in RFC 2637
+ *
+ * (C) 2000-2003 by Harald Welte <laforge@gnumonks.org>
+ *
+ * Development of this code funded by Astaro AG (http://www.astaro.com/)
+ *
+ * TODO: - Support for multiple calls within one session
+ * 	   (needs netfilter newnat code)
+ * 	 - NAT to a unique tuple, not to TCP source port
+ * 	   (needs netfilter tuple reservation)
+ *
+ * Changes:
+ *     2002-02-10 - Version 1.3
+ *       - Use ip_nat_mangle_tcp_packet() because of cloned skb's
+ *	   in local connections (Philip Craig <philipc@snapgear.com>)
+ *       - add checks for magicCookie and pptp version
+ *       - make argument list of pptp_{out,in}bound_packet() shorter
+ *       - move to C99 style initializers
+ *       - print version number at module loadtime
+ *     2003-09-22 - Version 1.5
+ *       - use SNATed tcp sourceport as callid, since we get called before
+ *         TCP header is mangled (Philip Craig <philipc@snapgear.com>)
+ * 
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <net/tcp.h>
+#include <linux/netfilter_ipv4/ip_nat.h>
+#include <linux/netfilter_ipv4/ip_nat_rule.h>
+#include <linux/netfilter_ipv4/ip_nat_helper.h>
+#include <linux/netfilter_ipv4/ip_nat_pptp.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
+#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
+
+#define IP_NAT_PPTP_VERSION "$Revision: 1.4 $"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
+MODULE_DESCRIPTION("Netfilter NAT helper module for PPTP");
+
+
+#if 0
+#include "ip_conntrack_pptp_priv.h"
+#define DEBUGP(format, args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__ \
+				       ": " format, ## args)
+#else
+#define DEBUGP(format, args...)
+#endif
+
+static unsigned int
+pptp_nat_expected(struct sk_buff **pskb,
+		  unsigned int hooknum,
+		  struct ip_conntrack *ct,
+		  struct ip_nat_info *info)
+{
+	struct ip_conntrack *master = master_ct(ct);
+	struct ip_nat_multi_range mr;
+	struct ip_ct_pptp_master *ct_pptp_info;
+	struct ip_nat_pptp *nat_pptp_info;
+	u_int32_t newip, newcid;
+	int ret;
+
+	IP_NF_ASSERT(info);
+	IP_NF_ASSERT(master);
+	IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
+
+	DEBUGP("we have a connection!\n");
+
+	LOCK_BH(&ip_pptp_lock);
+	ct_pptp_info = &master->help.ct_pptp_info;
+	nat_pptp_info = &master->nat.help.nat_pptp_info;
+
+	/* need to alter GRE tuple because conntrack expectfn() used 'wrong'
+	 * (unmanipulated) values */
+	if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) {
+		DEBUGP("completing tuples with NAT info \n");
+		/* we can do this, since we're unconfirmed */
+		if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key ==
+			htonl(ct_pptp_info->pac_call_id)) {	
+			/* assume PNS->PAC */
+			ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key =
+				htonl(nat_pptp_info->pns_call_id);
+			ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key =
+				htonl(nat_pptp_info->pns_call_id);
+			newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
+			newcid = htonl(nat_pptp_info->pac_call_id);
+		} else {
+			/* assume PAC->PNS */
+			ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key =
+				htonl(nat_pptp_info->pac_call_id);
+			ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key =
+				htonl(nat_pptp_info->pac_call_id);
+			newip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
+			newcid = htonl(nat_pptp_info->pns_call_id);
+		}
+	} else {
+		if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key ==
+			htonl(ct_pptp_info->pac_call_id)) {	
+			/* assume PNS->PAC */
+			newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
+			newcid = htonl(ct_pptp_info->pns_call_id);
+		}
+		else {
+			/* assume PAC->PNS */
+			newip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
+			newcid = htonl(ct_pptp_info->pac_call_id);
+		}
+	}
+
+	mr.rangesize = 1;
+	mr.range[0].flags = IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED;
+	mr.range[0].min_ip = mr.range[0].max_ip = newip;
+	mr.range[0].min = mr.range[0].max = 
+		((union ip_conntrack_manip_proto ) { newcid }); 
+	DEBUGP("change ip to %u.%u.%u.%u\n", 
+		NIPQUAD(newip));
+	DEBUGP("change key to 0x%x\n", ntohl(newcid));
+	ret = ip_nat_setup_info(ct, &mr, hooknum);
+
+	UNLOCK_BH(&ip_pptp_lock);
+
+	return ret;
+
+}
+
+/* outbound packets == from PNS to PAC */
+static inline unsigned int
+pptp_outbound_pkt(struct sk_buff **pskb,
+		  struct ip_conntrack *ct,
+		  enum ip_conntrack_info ctinfo,
+		  struct ip_conntrack_expect *exp)
+
+{
+	struct iphdr *iph = (*pskb)->nh.iph;
+	struct tcphdr *tcph = (void *) iph + iph->ihl*4;
+	struct pptp_pkt_hdr *pptph = (struct pptp_pkt_hdr *) 
+					((void *)tcph + tcph->doff*4);
+
+	struct PptpControlHeader *ctlh;
+	union pptp_ctrl_union pptpReq;
+	struct ip_ct_pptp_master *ct_pptp_info = &ct->help.ct_pptp_info;
+	struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info;
+
+	u_int16_t msg, *cid = NULL, new_callid;
+
+	/* FIXME: size checks !!! */
+	ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph));
+	pptpReq.rawreq = (void *) ((void *) ctlh + sizeof(*ctlh));
+
+	new_callid = htons(ct_pptp_info->pns_call_id);
+	
+	switch (msg = ntohs(ctlh->messageType)) {
+		case PPTP_OUT_CALL_REQUEST:
+			cid = &pptpReq.ocreq->callID;
+			/* FIXME: ideally we would want to reserve a call ID
+			 * here.  current netfilter NAT core is not able to do
+			 * this :( For now we use TCP source port. This breaks
+			 * multiple calls within one control session */
+
+			/* save original call ID in nat_info */
+			nat_pptp_info->pns_call_id = ct_pptp_info->pns_call_id;
+
+			/* don't use tcph->source since we are at a DSTmanip
+			 * hook (e.g. PREROUTING) and pkt is not mangled yet */
+			new_callid = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.tcp.port;
+
+			/* save new call ID in ct info */
+			ct_pptp_info->pns_call_id = ntohs(new_callid);
+			break;
+		case PPTP_IN_CALL_REPLY:
+			cid = &pptpReq.icreq->callID;
+			break;
+		case PPTP_CALL_CLEAR_REQUEST:
+			cid = &pptpReq.clrreq->callID;
+			break;
+		default:
+			DEBUGP("unknown outbound packet 0x%04x:%s\n", msg,
+			      (msg <= PPTP_MSG_MAX)? strMName[msg]:strMName[0]);
+			/* fall through */
+
+		case PPTP_SET_LINK_INFO:
+			/* only need to NAT in case PAC is behind NAT box */
+		case PPTP_START_SESSION_REQUEST:
+		case PPTP_START_SESSION_REPLY:
+		case PPTP_STOP_SESSION_REQUEST:
+		case PPTP_STOP_SESSION_REPLY:
+		case PPTP_ECHO_REQUEST:
+		case PPTP_ECHO_REPLY:
+			/* no need to alter packet */
+			return NF_ACCEPT;
+	}
+
+	IP_NF_ASSERT(cid);
+
+	DEBUGP("altering call id from 0x%04x to 0x%04x\n",
+		ntohs(*cid), ntohs(new_callid));
+
+	/* mangle packet */
+	ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, (void *)cid - (void *)pptph,
+				 sizeof(new_callid), (char *)&new_callid,
+				 sizeof(new_callid));
+
+	return NF_ACCEPT;
+}
+
+/* inbound packets == from PAC to PNS */
+static inline unsigned int
+pptp_inbound_pkt(struct sk_buff **pskb,
+		 struct ip_conntrack *ct,
+		 enum ip_conntrack_info ctinfo,
+		 struct ip_conntrack_expect *oldexp)
+{
+	struct iphdr *iph = (*pskb)->nh.iph;
+	struct tcphdr *tcph = (void *) iph + iph->ihl*4;
+	struct pptp_pkt_hdr *pptph = (struct pptp_pkt_hdr *) 
+					((void *)tcph + tcph->doff*4);
+
+	struct PptpControlHeader *ctlh;
+	union pptp_ctrl_union pptpReq;
+	struct ip_ct_pptp_master *ct_pptp_info = &ct->help.ct_pptp_info;
+	struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info;
+
+	u_int16_t msg, new_cid = 0, new_pcid, *pcid = NULL, *cid = NULL;
+	u_int32_t old_dst_ip;
+
+	struct ip_conntrack_tuple t, inv_t;
+	struct ip_conntrack_tuple *orig_t, *reply_t;
+
+	/* FIXME: size checks !!! */
+	ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph));
+	pptpReq.rawreq = (void *) ((void *) ctlh + sizeof(*ctlh));
+
+	new_pcid = htons(nat_pptp_info->pns_call_id);
+
+	switch (msg = ntohs(ctlh->messageType)) {
+	case PPTP_OUT_CALL_REPLY:
+		pcid = &pptpReq.ocack->peersCallID;	
+		cid = &pptpReq.ocack->callID;
+		if (!oldexp) {
+			DEBUGP("outcall but no expectation\n");
+			break;
+		}
+		old_dst_ip = oldexp->tuple.dst.ip;
+		t = oldexp->tuple;
+		invert_tuplepr(&inv_t, &t);
+
+		/* save original PAC call ID in nat_info */
+		nat_pptp_info->pac_call_id = ct_pptp_info->pac_call_id;
+
+		/* alter expectation */
+		orig_t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
+		reply_t = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+		if (t.src.ip == orig_t->src.ip && t.dst.ip == orig_t->dst.ip) {
+			/* expectation for PNS->PAC direction */
+			t.src.u.gre.key = htonl(nat_pptp_info->pns_call_id);
+			t.dst.u.gre.key = htonl(ct_pptp_info->pac_call_id);
+			inv_t.src.ip = reply_t->src.ip;
+			inv_t.dst.ip = reply_t->dst.ip;
+			inv_t.src.u.gre.key = htonl(nat_pptp_info->pac_call_id);
+			inv_t.dst.u.gre.key = htonl(ct_pptp_info->pns_call_id);
+		} else {
+			/* expectation for PAC->PNS direction */
+			t.src.u.gre.key = htonl(nat_pptp_info->pac_call_id);
+			t.dst.u.gre.key = htonl(ct_pptp_info->pns_call_id);
+			inv_t.src.ip = orig_t->src.ip;
+			inv_t.dst.ip = orig_t->dst.ip;
+			inv_t.src.u.gre.key = htonl(nat_pptp_info->pns_call_id);
+			inv_t.dst.u.gre.key = htonl(ct_pptp_info->pac_call_id);
+		}
+
+		if (!ip_conntrack_change_expect(oldexp, &t)) {
+			DEBUGP("successfully changed expect\n");
+		} else {
+			DEBUGP("can't change expect\n");
+		}
+		ip_ct_gre_keymap_change(oldexp->proto.gre.keymap_orig, &t);
+		ip_ct_gre_keymap_change(oldexp->proto.gre.keymap_reply, &inv_t);
+		break;
+	case PPTP_IN_CALL_CONNECT:
+		pcid = &pptpReq.iccon->peersCallID;
+		if (!oldexp)
+			break;
+		old_dst_ip = oldexp->tuple.dst.ip;
+		t = oldexp->tuple;
+
+		/* alter expectation, no need for callID */
+		if (t.dst.ip == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip) {
+			/* expectation for PNS->PAC direction */
+			t.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
+		} else {
+			/* expectation for PAC->PNS direction */
+			t.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
+		}
+
+		if (!ip_conntrack_change_expect(oldexp, &t)) {
+			DEBUGP("successfully changed expect\n");
+		} else {
+			DEBUGP("can't change expect\n");
+		}
+		break;
+	case PPTP_IN_CALL_REQUEST:
+		/* only need to nat in case PAC is behind NAT box */
+		break;
+	case PPTP_WAN_ERROR_NOTIFY:
+		pcid = &pptpReq.wanerr->peersCallID;
+		break;
+	case PPTP_CALL_DISCONNECT_NOTIFY:
+		pcid = &pptpReq.disc->callID;
+		break;
+
+	default:
+		DEBUGP("unknown inbound packet %s\n",
+			(msg <= PPTP_MSG_MAX)? strMName[msg]:strMName[0]);
+		/* fall through */
+
+	case PPTP_START_SESSION_REQUEST:
+	case PPTP_START_SESSION_REPLY:
+	case PPTP_STOP_SESSION_REQUEST:
+	case PPTP_STOP_SESSION_REPLY:
+	case PPTP_ECHO_REQUEST:
+	case PPTP_ECHO_REPLY:
+		/* no need to alter packet */
+		return NF_ACCEPT;
+	}
+
+	/* mangle packet */
+	IP_NF_ASSERT(pcid);
+	DEBUGP("altering peer call id from 0x%04x to 0x%04x\n",
+		ntohs(*pcid), ntohs(new_pcid));
+	ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, (void *)pcid - (void *)pptph,
+				 sizeof(new_pcid), (char *)&new_pcid, 
+				 sizeof(new_pcid));
+
+	if (new_cid) {
+		IP_NF_ASSERT(cid);
+		DEBUGP("altering call id from 0x%04x to 0x%04x\n",
+			ntohs(*cid), ntohs(new_cid));
+		ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, 
+					 (void *)cid - (void *)pptph, 
+					 sizeof(new_cid), (char *)&new_cid, 
+					 sizeof(new_cid));
+	}
+
+	/* great, at least we don't need to resize packets */
+	return NF_ACCEPT;
+}
+
+
+static unsigned int tcp_help(struct ip_conntrack *ct,
+			     struct ip_conntrack_expect *exp,
+			     struct ip_nat_info *info,
+			     enum ip_conntrack_info ctinfo,
+			     unsigned int hooknum, struct sk_buff **pskb)
+{
+	struct iphdr *iph = (*pskb)->nh.iph;
+	struct tcphdr *tcph = (void *) iph + iph->ihl*4;
+	unsigned int datalen = (*pskb)->len - iph->ihl*4 - tcph->doff*4;
+	struct pptp_pkt_hdr *pptph;
+
+	int dir;
+
+	DEBUGP("entering\n");
+
+	/* Only mangle things once: DST for original direction
+	   and SRC for reply direction. */
+	dir = CTINFO2DIR(ctinfo);
+	if (!((HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
+	     && dir == IP_CT_DIR_ORIGINAL)
+	      || (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST
+		  && dir == IP_CT_DIR_REPLY))) {
+		DEBUGP("Not touching dir %s at hook %s\n",
+		       dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
+		       hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
+		       : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
+		       : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT"
+		       : hooknum == NF_IP_LOCAL_IN ? "INPUT" : "???");
+		return NF_ACCEPT;
+	}
+
+	/* if packet is too small, just skip it */
+	if (datalen < sizeof(struct pptp_pkt_hdr)+
+		      sizeof(struct PptpControlHeader)) {
+		DEBUGP("pptp packet too short\n");
+		return NF_ACCEPT;	
+	}
+
+	pptph = (struct pptp_pkt_hdr *) ((void *)tcph + tcph->doff*4);
+
+	/* if it's not a control message, we can't handle it */
+	if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL ||
+	    ntohl(pptph->magicCookie) != PPTP_MAGIC_COOKIE) {
+		DEBUGP("not a pptp control packet\n");
+		return NF_ACCEPT;
+	}
+
+	LOCK_BH(&ip_pptp_lock);
+
+	if (dir == IP_CT_DIR_ORIGINAL) {
+		/* reuqests sent by client to server (PNS->PAC) */
+		pptp_outbound_pkt(pskb, ct, ctinfo, exp);
+	} else {
+		/* response from the server to the client (PAC->PNS) */
+		pptp_inbound_pkt(pskb, ct, ctinfo, exp);
+	}
+
+	UNLOCK_BH(&ip_pptp_lock);
+
+	return NF_ACCEPT;
+}
+
+/* nat helper struct for control connection */
+static struct ip_nat_helper pptp_tcp_helper = { 
+	.list = { NULL, NULL },
+	.name = "pptp", 
+	.flags = IP_NAT_HELPER_F_ALWAYS, 
+	.me = THIS_MODULE,
+	.tuple = { .src = { .ip = 0, 
+			    .u = { .tcp = { .port = 
+				    	__constant_htons(PPTP_CONTROL_PORT) } 
+				 } 
+			  },
+	  	   .dst = { .ip = 0, 
+			    .u = { .all = 0 }, 
+			    .protonum = IPPROTO_TCP 
+		   	  } 
+		 },
+
+	.mask = { .src = { .ip = 0, 
+			   .u = { .tcp = { .port = 0xFFFF } } 
+			 },
+		  .dst = { .ip = 0, 
+			   .u = { .all = 0 }, 
+			   .protonum = 0xFFFF 
+		  	 } 
+		},
+	.help = tcp_help, 
+	.expect = pptp_nat_expected 
+};
+
+			  
+static int __init init(void)
+{
+	DEBUGP("%s: registering NAT helper\n", __FILE__);
+	if (ip_nat_helper_register(&pptp_tcp_helper)) {
+		printk(KERN_ERR "Unable to register NAT application helper "
+				"for pptp\n");
+		return -EIO;
+	}
+
+	printk("ip_nat_pptp version %s loaded\n", IP_NAT_PPTP_VERSION);
+	return 0;
+}
+
+static void __exit fini(void)
+{
+	DEBUGP("cleanup_module\n" );
+	ip_nat_helper_unregister(&pptp_tcp_helper);
+	printk("ip_nat_pptp version %s unloaded\n", IP_NAT_PPTP_VERSION);
+}
+
+module_init(init);
+module_exit(fini);
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_nat_proto_gre.c linux-2.4.29-uc1/net/ipv4/netfilter/ip_nat_proto_gre.c
--- linux-2.4.29/net/ipv4/netfilter/ip_nat_proto_gre.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_nat_proto_gre.c	2005-06-14 02:11:50.000000000 +0100
@@ -0,0 +1,225 @@
+/*
+ * ip_nat_proto_gre.c - Version $Revision: 1.3 $
+ *
+ * NAT protocol helper module for GRE.
+ *
+ * GRE is a generic encapsulation protocol, which is generally not very
+ * suited for NAT, as it has no protocol-specific part as port numbers.
+ *
+ * It has an optional key field, which may help us distinguishing two 
+ * connections between the same two hosts.
+ *
+ * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784 
+ *
+ * PPTP is built on top of a modified version of GRE, and has a mandatory
+ * field called "CallID", which serves us for the same purpose as the key
+ * field in plain GRE.
+ *
+ * Documentation about PPTP can be found in RFC 2637
+ *
+ * (C) 2000-2003 by Harald Welte <laforge@gnumonks.org>
+ *
+ * Development of this code funded by Astaro AG (http://www.astaro.com/)
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/ip.h>
+#include <linux/netfilter_ipv4/ip_nat.h>
+#include <linux/netfilter_ipv4/ip_nat_rule.h>
+#include <linux/netfilter_ipv4/ip_nat_protocol.h>
+#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
+MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE");
+
+#if 0
+#define DEBUGP(format, args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__ \
+				       ": " format, ## args)
+#else
+#define DEBUGP(x, args...)
+#endif
+
+/* is key in given range between min and max */
+static int
+gre_in_range(const struct ip_conntrack_tuple *tuple,
+	     enum ip_nat_manip_type maniptype,
+	     const union ip_conntrack_manip_proto *min,
+	     const union ip_conntrack_manip_proto *max)
+{
+	u_int32_t key;
+
+	if (maniptype == IP_NAT_MANIP_SRC)
+		key = tuple->src.u.gre.key;
+	else
+		key = tuple->dst.u.gre.key;
+
+	return ntohl(key) >= ntohl(min->gre.key)
+		&& ntohl(key) <= ntohl(max->gre.key);
+}
+
+/* generate unique tuple ... */
+static int 
+gre_unique_tuple(struct ip_conntrack_tuple *tuple,
+		 const struct ip_nat_range *range,
+		 enum ip_nat_manip_type maniptype,
+		 const struct ip_conntrack *conntrack)
+{
+	u_int32_t min, i, range_size;
+	u_int32_t key = 0, *keyptr;
+
+	if (maniptype == IP_NAT_MANIP_SRC)
+		keyptr = &tuple->src.u.gre.key;
+	else
+		keyptr = &tuple->dst.u.gre.key;
+
+	if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
+
+		switch (tuple->dst.u.gre.version) {
+		case 0:
+			DEBUGP("NATing GRE version 0 (ct=%p)\n",
+				conntrack);
+			min = 1;
+			range_size = 0xffffffff;
+			break;
+		case GRE_VERSION_PPTP:
+			DEBUGP("%p: NATing GRE PPTP\n", 
+				conntrack);
+			min = 1;
+			range_size = 0xffff;
+			break;
+		default:
+			printk(KERN_WARNING "nat_gre: unknown GRE version\n");
+			return 0;
+			break;
+		}
+
+	} else {
+		min = ntohl(range->min.gre.key);
+		range_size = ntohl(range->max.gre.key) - min + 1;
+	}
+
+	DEBUGP("min = %u, range_size = %u\n", min, range_size); 
+
+	for (i = 0; i < range_size; i++, key++) {
+		*keyptr = htonl(min + key % range_size);
+		if (!ip_nat_used_tuple(tuple, conntrack))
+			return 1;
+	}
+
+	DEBUGP("%p: no NAT mapping\n", conntrack);
+
+	return 0;
+}
+
+/* manipulate a GRE packet according to maniptype */
+static void 
+gre_manip_pkt(struct iphdr *iph, size_t len, 
+	      const struct ip_conntrack_manip *manip,
+	      enum ip_nat_manip_type maniptype)
+{
+	struct gre_hdr *greh = (struct gre_hdr *)((u_int32_t *)iph+iph->ihl);
+	struct gre_hdr_pptp *pgreh = (struct gre_hdr_pptp *) greh;
+
+	/* we only have destination manip of a packet, since 'source key' 
+	 * is not present in the packet itself */
+	if (maniptype == IP_NAT_MANIP_DST) {
+		/* key manipulation is always dest */
+		switch (greh->version) {
+		case 0:
+			if (!greh->key) {
+				DEBUGP("can't nat GRE w/o key\n");
+				break;
+			}
+			if (greh->csum) {
+				/* FIXME: Never tested this code... */
+				*(gre_csum(greh)) = 
+					ip_nat_cheat_check(~*(gre_key(greh)),
+							manip->u.gre.key,
+							*(gre_csum(greh)));
+			}
+			*(gre_key(greh)) = manip->u.gre.key;
+			break;
+		case GRE_VERSION_PPTP:
+			DEBUGP("call_id -> 0x%04x\n", 
+				ntohl(manip->u.gre.key));
+			pgreh->call_id = htons(ntohl(manip->u.gre.key));
+			break;
+		default:
+			DEBUGP("can't nat unknown GRE version\n");
+			break;
+		}
+	}
+}
+
+/* print out a nat tuple */
+static unsigned int 
+gre_print(char *buffer, 
+	  const struct ip_conntrack_tuple *match,
+	  const struct ip_conntrack_tuple *mask)
+{
+	unsigned int len = 0;
+
+	if (mask->dst.u.gre.version)
+		len += sprintf(buffer + len, "version=%d ",
+				ntohs(match->dst.u.gre.version));
+
+	if (mask->dst.u.gre.protocol)
+		len += sprintf(buffer + len, "protocol=0x%x ",
+				ntohs(match->dst.u.gre.protocol));
+
+	if (mask->src.u.gre.key)
+		len += sprintf(buffer + len, "srckey=0x%x ", 
+				ntohl(match->src.u.gre.key));
+
+	if (mask->dst.u.gre.key)
+		len += sprintf(buffer + len, "dstkey=0x%x ",
+				ntohl(match->src.u.gre.key));
+
+	return len;
+}
+
+/* print a range of keys */
+static unsigned int 
+gre_print_range(char *buffer, const struct ip_nat_range *range)
+{
+	if (range->min.gre.key != 0 
+	    || range->max.gre.key != 0xFFFF) {
+		if (range->min.gre.key == range->max.gre.key)
+			return sprintf(buffer, "key 0x%x ",
+					ntohl(range->min.gre.key));
+		else
+			return sprintf(buffer, "keys 0x%u-0x%u ",
+					ntohl(range->min.gre.key),
+					ntohl(range->max.gre.key));
+	} else
+		return 0;
+}
+
+/* nat helper struct */
+static struct ip_nat_protocol gre = 
+	{ { NULL, NULL }, "GRE", IPPROTO_GRE,
+	  gre_manip_pkt,
+	  gre_in_range,
+	  gre_unique_tuple,
+	  gre_print,
+	  gre_print_range 
+	};
+				  
+static int __init init(void)
+{
+        if (ip_nat_protocol_register(&gre))
+                return -EIO;
+
+        return 0;
+}
+
+static void __exit fini(void)
+{
+        ip_nat_protocol_unregister(&gre);
+}
+
+module_init(init);
+module_exit(fini);
diff -urN linux-2.4.29/net/ipv4/netfilter/ip_tables.c linux-2.4.29-uc1/net/ipv4/netfilter/ip_tables.c
--- linux-2.4.29/net/ipv4/netfilter/ip_tables.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ip_tables.c	2005-06-14 02:11:50.000000000 +0100
@@ -118,12 +118,19 @@
 static inline int
 ip_packet_match(const struct iphdr *ip,
 		const char *indev,
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+		const char *physindev,
+#endif
 		const char *outdev,
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+		const char *physoutdev,
+#endif
 		const struct ipt_ip *ipinfo,
 		int isfrag)
 {
 	size_t i;
 	unsigned long ret;
+	unsigned long ret2 = 1;
 
 #define FWINV(bool,invflg) ((bool) ^ !!(ipinfo->invflags & invflg))
 
@@ -153,7 +160,15 @@
 			& ((const unsigned long *)ipinfo->iniface_mask)[i];
 	}
 
-	if (FWINV(ret != 0, IPT_INV_VIA_IN)) {
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+	for (i = 0, ret2 = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
+		ret2 |= (((const unsigned long *)physindev)[i]
+			^ ((const unsigned long *)ipinfo->iniface)[i])
+			& ((const unsigned long *)ipinfo->iniface_mask)[i];
+	}
+#endif
+
+	if (FWINV(ret != 0 && ret2 != 0, IPT_INV_VIA_IN)) {
 		dprintf("VIA in mismatch (%s vs %s).%s\n",
 			indev, ipinfo->iniface,
 			ipinfo->invflags&IPT_INV_VIA_IN ?" (INV)":"");
@@ -166,7 +181,15 @@
 			& ((const unsigned long *)ipinfo->outiface_mask)[i];
 	}
 
-	if (FWINV(ret != 0, IPT_INV_VIA_OUT)) {
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+	for (i = 0, ret2 = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
+		ret2 |= (((const unsigned long *)physoutdev)[i]
+			^ ((const unsigned long *)ipinfo->outiface)[i])
+			& ((const unsigned long *)ipinfo->outiface_mask)[i];
+	}
+#endif
+
+	if (FWINV(ret != 0 && ret2 != 0, IPT_INV_VIA_OUT)) {
 		dprintf("VIA out mismatch (%s vs %s).%s\n",
 			outdev, ipinfo->outiface,
 			ipinfo->invflags&IPT_INV_VIA_OUT ?" (INV)":"");
@@ -265,6 +288,9 @@
 	/* Initializing verdict to NF_DROP keeps gcc happy. */
 	unsigned int verdict = NF_DROP;
 	const char *indev, *outdev;
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+	const char *physindev, *physoutdev;
+#endif
 	void *table_base;
 	struct ipt_entry *e, *back;
 
@@ -274,6 +300,13 @@
 	datalen = (*pskb)->len - ip->ihl * 4;
 	indev = in ? in->name : nulldevname;
 	outdev = out ? out->name : nulldevname;
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+	physindev = ((*pskb)->nf_bridge && (*pskb)->nf_bridge->physindev) ?
+		(*pskb)->nf_bridge->physindev->name : nulldevname;
+	physoutdev = ((*pskb)->nf_bridge && (*pskb)->nf_bridge->physoutdev) ?
+		(*pskb)->nf_bridge->physoutdev->name : nulldevname;
+#endif
+
 	/* We handle fragments by dealing with the first fragment as
 	 * if it was a normal packet.  All other fragments are treated
 	 * normally, except that they will NEVER match rules that ask
@@ -308,8 +341,15 @@
 	do {
 		IP_NF_ASSERT(e);
 		IP_NF_ASSERT(back);
-		(*pskb)->nfcache |= e->nfcache;
-		if (ip_packet_match(ip, indev, outdev, &e->ip, offset)) {
+		if (ip_packet_match(ip, indev,
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+		    physindev,
+#endif
+		    outdev,
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+		    physoutdev,
+#endif
+		    &e->ip, offset)) {
 			struct ipt_entry_target *t;
 
 			if (IPT_MATCH_ITERATE(e, do_match,
@@ -1700,7 +1740,7 @@
 			     off_t start_offset, char *buffer, int length,
 			     off_t *pos, unsigned int *count)
 {
-	if ((*count)++ >= start_offset) {
+	if (*count >= start_offset) {
 		unsigned int namelen;
 
 		namelen = sprintf(buffer + *pos, "%s\n",
@@ -1711,6 +1751,7 @@
 		}
 		*pos += namelen;
 	}
+	(*count)++;
 	return 0;
 }
 
diff -urN linux-2.4.29/net/ipv4/netfilter/ipt_CONNLOG.c linux-2.4.29-uc1/net/ipv4/netfilter/ipt_CONNLOG.c
--- linux-2.4.29/net/ipv4/netfilter/ipt_CONNLOG.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ipt_CONNLOG.c	2005-06-14 02:11:50.000000000 +0100
@@ -0,0 +1,148 @@
+/* Optionally log start and end of connections.
+ */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
+#include <linux/netfilter_ipv4/ip_conntrack_core.h>
+
+/* Use lock to serialize, so printks don't overlap */
+static spinlock_t log_lock = SPIN_LOCK_UNLOCKED;
+
+static unsigned int
+target(struct sk_buff **pskb,
+       unsigned int hooknum,
+       const struct net_device *in,
+       const struct net_device *out,
+       const void *targinfo,
+       void *userinfo)
+{
+	enum ip_conntrack_info ctinfo;
+	struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo);
+
+	if (ct)
+		set_bit(IPS_LOG_BIT, &ct->status);
+
+	return IPT_CONTINUE;
+}
+
+static int
+checkentry(const char *tablename,
+	   const struct ipt_entry *e,
+           void *targinfo,
+           unsigned int targinfosize,
+           unsigned int hook_mask)
+{
+	if (targinfosize != IPT_ALIGN(0))
+		return 0;
+
+	return 1;
+}
+
+static struct ipt_target ipt_connlog_reg = {
+	.name = "CONNLOG",
+	.target = target,
+	.checkentry = checkentry,
+	.me = THIS_MODULE,
+};
+
+static void dump_tuple(char *buffer, const struct ip_conntrack_tuple *tuple,
+		       struct ip_conntrack_protocol *proto)
+{
+	printk("src=%u.%u.%u.%u dst=%u.%u.%u.%u ",
+		NIPQUAD(tuple->src.ip), NIPQUAD(tuple->dst.ip));
+
+	if (proto->print_tuple(buffer, tuple))
+		printk("%s", buffer);
+}
+
+#ifdef CONFIG_IP_NF_CT_ACCT
+static void dump_counters(struct ip_conntrack_counter *counter)
+{
+	printk("packets=%llu bytes=%llu ", counter->packets, counter->bytes);
+}
+#else
+static inline void dump_counters(struct ip_conntrack_counter *counter) {}
+#endif
+
+static void dump_conntrack(struct ip_conntrack *ct)
+{
+	struct ip_conntrack_protocol *proto
+		= __ip_ct_find_proto(ct->tuplehash[IP_CT_DIR_ORIGINAL]
+			       .tuple.dst.protonum);
+	char buffer[256];
+
+	printk("proto=%s ", proto->name);
+
+	if (proto->print_conntrack(buffer, ct))
+		printk("%s", buffer);
+
+	dump_tuple(buffer, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, proto);
+	dump_counters(&ct->counters[IP_CT_DIR_ORIGINAL]);
+
+	dump_tuple(buffer, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, proto);
+	dump_counters(&ct->counters[IP_CT_DIR_REPLY]);
+
+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
+	printk("mark=%ld ", ct->mark);
+#endif
+}
+
+static int conntrack_event(struct notifier_block *this,
+			   unsigned long event,
+			   void *ptr)
+{
+	struct ip_conntrack *ct = ptr;
+	const char *log_prefix = NULL;
+
+	if (event & (IPCT_NEW|IPCT_RELATED))
+		log_prefix = "create";
+	else if (event & (IPCT_DESTROY))
+		log_prefix = "destroy";
+
+	if (log_prefix && test_bit(IPS_LOG_BIT, &ct->status)) {
+		spin_lock_bh(&log_lock);
+		printk(KERN_INFO "conntrack %s: ", log_prefix);
+		dump_conntrack(ct);
+		printk("\n");
+		spin_unlock_bh(&log_lock);
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block conntrack_notifier = {
+	.notifier_call = conntrack_event,
+};
+
+static int __init init(void)
+{
+	int ret;
+
+	ret = ipt_register_target(&ipt_connlog_reg);
+	if (ret != 0)
+		return ret;
+
+	ret = ip_conntrack_register_notifier(&conntrack_notifier);
+	if (ret != 0)
+		goto unregister_connlog;
+
+	return ret;
+
+unregister_connlog:
+	ipt_unregister_target(&ipt_connlog_reg);
+
+	return ret;
+}
+
+static void __exit fini(void)
+{
+	ipt_unregister_target(&ipt_connlog_reg);
+	ip_conntrack_unregister_notifier(&conntrack_notifier);
+}
+
+module_init(init);
+module_exit(fini);
diff -urN linux-2.4.29/net/ipv4/netfilter/ipt_connmark.c linux-2.4.29-uc1/net/ipv4/netfilter/ipt_connmark.c
--- linux-2.4.29/net/ipv4/netfilter/ipt_connmark.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ipt_connmark.c	2005-06-14 02:11:51.000000000 +0100
@@ -0,0 +1,55 @@
+/* Kernel module to match connection mark values. */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_connmark.h>
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset,
+      const void *hdr,
+      u_int16_t datalen,
+      int *hotdrop)
+{
+	const struct ipt_connmark_info *info = matchinfo;
+	enum ip_conntrack_info ctinfo;
+	struct ip_conntrack *ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
+	if (!ct)
+	    return 0;
+
+	return ((ct->mark & info->mask) == info->mark) ^ info->invert;
+}
+
+static int
+checkentry(const char *tablename,
+           const struct ipt_ip *ip,
+           void *matchinfo,
+           unsigned int matchsize,
+           unsigned int hook_mask)
+{
+	if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info)))
+		return 0;
+
+	return 1;
+}
+
+static struct ipt_match connmark_match
+= { { NULL, NULL }, "connmark", &match, &checkentry, NULL, THIS_MODULE };
+
+static int __init init(void)
+{
+	return ipt_register_match(&connmark_match);
+}
+
+static void __exit fini(void)
+{
+	ipt_unregister_match(&connmark_match);
+}
+
+module_init(init);
+module_exit(fini);
diff -urN linux-2.4.29/net/ipv4/netfilter/ipt_CONNMARK.c linux-2.4.29-uc1/net/ipv4/netfilter/ipt_CONNMARK.c
--- linux-2.4.29/net/ipv4/netfilter/ipt_CONNMARK.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ipt_CONNMARK.c	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,87 @@
+/* This is a module which is used for setting/remembering the mark field of
+ * an connection, or optionally restore it to the skb
+ */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <net/checksum.h>
+
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_CONNMARK.h>
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+
+static unsigned int
+target(struct sk_buff **pskb,
+       unsigned int hooknum,
+       const struct net_device *in,
+       const struct net_device *out,
+       const void *targinfo,
+       void *userinfo)
+{
+	const struct ipt_connmark_target_info *markinfo = targinfo;
+
+	enum ip_conntrack_info ctinfo;
+	struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo);
+	if (ct) {
+	    switch(markinfo->mode) {
+	    case IPT_CONNMARK_SET:
+		ct->mark = markinfo->mark;
+		break;
+	    case IPT_CONNMARK_SAVE:
+		ct->mark = (*pskb)->nfmark;
+		break;
+	    case IPT_CONNMARK_RESTORE:
+		if (ct->mark != (*pskb)->nfmark) {
+		    (*pskb)->nfmark = ct->mark;
+		    (*pskb)->nfcache |= NFC_ALTERED;
+		}
+		break;
+	    }
+	}
+
+	return IPT_CONTINUE;
+}
+
+static int
+checkentry(const char *tablename,
+	   const struct ipt_entry *e,
+           void *targinfo,
+           unsigned int targinfosize,
+           unsigned int hook_mask)
+{
+	struct ipt_connmark_target_info *matchinfo = targinfo;
+	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) {
+		printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n",
+		       targinfosize,
+		       IPT_ALIGN(sizeof(struct ipt_connmark_target_info)));
+		return 0;
+	}
+
+	if (matchinfo->mode == IPT_CONNMARK_RESTORE) {
+	    if (strcmp(tablename, "mangle") != 0) {
+		    printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename);
+		    return 0;
+	    }
+	}
+
+	return 1;
+}
+
+static struct ipt_target ipt_connmark_reg
+= { { NULL, NULL }, "CONNMARK", target, checkentry, NULL, THIS_MODULE };
+
+static int __init init(void)
+{
+	if (ipt_register_target(&ipt_connmark_reg))
+		return -EINVAL;
+
+	return 0;
+}
+
+static void __exit fini(void)
+{
+	ipt_unregister_target(&ipt_connmark_reg);
+}
+
+module_init(init);
+module_exit(fini);
diff -urN linux-2.4.29/net/ipv4/netfilter/ipt_IMQ.c linux-2.4.29-uc1/net/ipv4/netfilter/ipt_IMQ.c
--- linux-2.4.29/net/ipv4/netfilter/ipt_IMQ.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ipt_IMQ.c	2005-06-14 02:11:51.000000000 +0100
@@ -0,0 +1,78 @@
+/* This target marks packets to be enqueued to an imq device */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_IMQ.h>
+#include <linux/imq.h>
+
+static unsigned int imq_target(struct sk_buff **pskb,
+			       unsigned int hooknum,
+			       const struct net_device *in,
+			       const struct net_device *out,
+			       const void *targinfo,
+			       void *userinfo)
+{
+	struct ipt_imq_info *mr = (struct ipt_imq_info*)targinfo;
+
+	(*pskb)->imq_flags = mr->todev | IMQ_F_ENQUEUE;
+	(*pskb)->nfcache |= NFC_ALTERED;
+
+	return IPT_CONTINUE;
+}
+
+static int imq_checkentry(const char *tablename,
+			  const struct ipt_entry *e,
+			  void *targinfo,
+			  unsigned int targinfosize,
+			  unsigned int hook_mask)
+{
+	struct ipt_imq_info *mr;
+
+	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_imq_info))) {
+		printk(KERN_WARNING "IMQ: invalid targinfosize\n");
+		return 0;
+	}
+	mr = (struct ipt_imq_info*)targinfo;
+
+	if (strcmp(tablename, "mangle") != 0) {
+		printk(KERN_WARNING
+		       "IMQ: IMQ can only be called from \"mangle\" table, not \"%s\"\n",
+		       tablename);
+		return 0;
+	}
+	
+	if (mr->todev > IMQ_MAX_DEVS) {
+		printk(KERN_WARNING
+		       "IMQ: invalid device specified, highest is %u\n",
+		       IMQ_MAX_DEVS);
+		return 0;
+	}
+	
+	return 1;
+}
+
+static struct ipt_target ipt_imq_reg = {
+	{ NULL, NULL},
+	"IMQ",
+	imq_target,
+	imq_checkentry,
+	NULL,
+	THIS_MODULE
+};
+
+static int __init init(void)
+{
+	if (ipt_register_target(&ipt_imq_reg))
+		return -EINVAL;
+
+	return 0;
+}
+
+static void __exit fini(void)
+{
+	ipt_unregister_target(&ipt_imq_reg);
+}
+
+module_init(init);
+module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/net/ipv4/netfilter/ipt_iprange.c linux-2.4.29-uc1/net/ipv4/netfilter/ipt_iprange.c
--- linux-2.4.29/net/ipv4/netfilter/ipt_iprange.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ipt_iprange.c	2005-06-14 02:11:51.000000000 +0100
@@ -0,0 +1,101 @@
+/*
+ * iptables module to match IP address ranges
+ *   (c) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
+ *
+ * Released under the terms of GNU GPLv2.
+ *
+ */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_iprange.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
+MODULE_DESCRIPTION("iptables arbitrary IP range match module");
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset,
+      const void *hdr,
+      u_int16_t datalen,
+      int *hotdrop)
+{
+	const struct ipt_iprange_info *info = matchinfo;
+	const struct iphdr *iph = skb->nh.iph;
+	
+
+	if (info->flags & IPRANGE_SRC) {
+		if (((ntohl(iph->saddr) < ntohl(info->src.min_ip))
+			  || (ntohl(iph->saddr) > ntohl(info->src.max_ip)))
+			 ^ !!(info->flags & IPRANGE_SRC_INV)) {
+			DEBUGP("src IP %u.%u.%u.%u NOT in range %s"
+			       "%u.%u.%u.%u-%u.%u.%u.%u\n",
+				NIPQUAD(iph->saddr),
+			        info->flags & IPRANGE_SRC_INV ? "(INV) " : "",
+				NIPQUAD(info->src.min_ip),
+				NIPQUAD(info->src.max_ip));
+			return 0;
+		}
+	}
+	if (info->flags & IPRANGE_DST) {
+		if (((ntohl(iph->daddr) < ntohl(info->dst.min_ip))
+			  || (ntohl(iph->daddr) > ntohl(info->dst.max_ip)))
+			 ^ !!(info->flags & IPRANGE_DST_INV)) {
+			DEBUGP("dst IP %u.%u.%u.%u NOT in range %s"
+			       "%u.%u.%u.%u-%u.%u.%u.%u\n",
+				NIPQUAD(iph->daddr),
+			        info->flags & IPRANGE_DST_INV ? "(INV) " : "",
+				NIPQUAD(info->dst.min_ip),
+				NIPQUAD(info->dst.max_ip));
+			return 0;
+		}
+	}
+	return 1;
+}
+
+static int check(const char *tablename,
+		 const struct ipt_ip *ip,
+		 void *matchinfo,
+		 unsigned int matchsize,
+		 unsigned int hook_mask)
+{
+	/* verify size */
+	if (matchsize != IPT_ALIGN(sizeof(struct ipt_iprange_info)))
+		return 0;
+
+	return 1;
+}
+
+static struct ipt_match iprange_match = 
+{ 
+	.list = { NULL, NULL }, 
+	.name = "iprange", 
+	.match = &match, 
+	.checkentry = &check, 
+	.destroy = NULL, 
+	.me = THIS_MODULE
+};
+
+static int __init init(void)
+{
+	return ipt_register_match(&iprange_match);
+}
+
+static void __exit fini(void)
+{
+	ipt_unregister_match(&iprange_match);
+}
+
+module_init(init);
+module_exit(fini);
diff -urN linux-2.4.29/net/ipv4/netfilter/ipt_LOG.c linux-2.4.29-uc1/net/ipv4/netfilter/ipt_LOG.c
--- linux-2.4.29/net/ipv4/netfilter/ipt_LOG.c	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ipt_LOG.c	2005-06-14 02:11:51.000000000 +0100
@@ -316,6 +316,18 @@
 	       loginfo->prefix,
 	       in ? in->name : "",
 	       out ? out->name : "");
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+	if ((*pskb)->nf_bridge) {
+		struct net_device *physindev = (*pskb)->nf_bridge->physindev;
+		struct net_device *physoutdev = (*pskb)->nf_bridge->physoutdev;
+
+		if (physindev && in != physindev)
+			printk("PHYSIN=%s ", physindev->name);
+		if (physoutdev && out != physoutdev)
+			printk("PHYSOUT=%s ", physoutdev->name);
+	}
+#endif
+
 	if (in && !out) {
 		/* MAC logging for input chain only. */
 		printk("MAC=");
diff -urN linux-2.4.29/net/ipv4/netfilter/ipt_MASQUERADE.c linux-2.4.29-uc1/net/ipv4/netfilter/ipt_MASQUERADE.c
--- linux-2.4.29/net/ipv4/netfilter/ipt_MASQUERADE.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ipt_MASQUERADE.c	2005-06-14 02:11:52.000000000 +0100
@@ -95,7 +95,7 @@
                 /* Funky routing can do this. */
                 if (net_ratelimit())
                         printk("MASQUERADE:"
-                               " No route: Rusty's brain broke!\n");
+                               " No route.\n");
                 return NF_DROP;
         }
         if (rt->u.dst.dev != out) {
diff -urN linux-2.4.29/net/ipv4/netfilter/ipt_NETMAP.c linux-2.4.29-uc1/net/ipv4/netfilter/ipt_NETMAP.c
--- linux-2.4.29/net/ipv4/netfilter/ipt_NETMAP.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ipt_NETMAP.c	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,109 @@
+/* NETMAP - static NAT mapping of IP network addresses (1:1).
+   The mapping can be applied to source (POSTROUTING),
+   destination (PREROUTING), or both (with separate rules).
+
+   Author: Svenning Soerensen <svenning@post5.tele.dk>
+*/
+
+#include <linux/config.h>
+#include <linux/ip.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv4/ip_nat_rule.h>
+
+#define MODULENAME "NETMAP"
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>");
+MODULE_DESCRIPTION("iptables 1:1 NAT mapping of IP networks target");
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+static int
+check(const char *tablename,
+      const struct ipt_entry *e,
+      void *targinfo,
+      unsigned int targinfosize,
+      unsigned int hook_mask)
+{
+	const struct ip_nat_multi_range *mr = targinfo;
+
+	if (strcmp(tablename, "nat") != 0) {
+		DEBUGP(MODULENAME":check: bad table `%s'.\n", tablename);
+		return 0;
+	}
+	if (targinfosize != IPT_ALIGN(sizeof(*mr))) {
+		DEBUGP(MODULENAME":check: size %u.\n", targinfosize);
+		return 0;
+	}
+	if (hook_mask & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_POST_ROUTING))) {
+		DEBUGP(MODULENAME":check: bad hooks %x.\n", hook_mask);
+		return 0;
+	}
+	if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) {
+		DEBUGP(MODULENAME":check: bad MAP_IPS.\n");
+		return 0;
+	}
+	if (mr->rangesize != 1) {
+		DEBUGP(MODULENAME":check: bad rangesize %u.\n", mr->rangesize);
+		return 0;
+	}
+	return 1;
+}
+
+static unsigned int
+target(struct sk_buff **pskb,
+       unsigned int hooknum,
+       const struct net_device *in,
+       const struct net_device *out,
+       const void *targinfo,
+       void *userinfo)
+{
+	struct ip_conntrack *ct;
+	enum ip_conntrack_info ctinfo;
+	u_int32_t new_ip, netmask;
+	const struct ip_nat_multi_range *mr = targinfo;
+	struct ip_nat_multi_range newrange;
+
+	IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
+		     || hooknum == NF_IP_POST_ROUTING);
+	ct = ip_conntrack_get(*pskb, &ctinfo);
+
+	netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip);
+
+	if (hooknum == NF_IP_PRE_ROUTING)
+		new_ip = (*pskb)->nh.iph->daddr & ~netmask;
+	else
+		new_ip = (*pskb)->nh.iph->saddr & ~netmask;
+	new_ip |= mr->range[0].min_ip & netmask;
+
+	newrange = ((struct ip_nat_multi_range)
+	{ 1, { { mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
+		 new_ip, new_ip,
+		 mr->range[0].min, mr->range[0].max } } });
+
+	/* Hand modified range to generic setup. */
+	return ip_nat_setup_info(ct, &newrange, hooknum);
+}
+
+static struct ipt_target target_module
+= { { NULL, NULL }, MODULENAME, target, check, NULL,
+    THIS_MODULE };
+
+static int __init init(void)
+{
+	return ipt_register_target(&target_module);
+}
+
+static void __exit fini(void)
+{
+	ipt_unregister_target(&target_module);
+}
+
+module_init(init);
+module_exit(fini);
diff -urN linux-2.4.29/net/ipv4/netfilter/ipt_physdev.c linux-2.4.29-uc1/net/ipv4/netfilter/ipt_physdev.c
--- linux-2.4.29/net/ipv4/netfilter/ipt_physdev.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ipt_physdev.c	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,127 @@
+/* Kernel module to match the bridge port in and
+ * out device for IP packets coming into contact with a bridge. */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/netfilter_ipv4/ipt_physdev.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_bridge.h>
+#include <linux/netdevice.h>
+#define MATCH   1
+#define NOMATCH 0
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset,
+      const void *hdr,
+      u_int16_t datalen,
+      int *hotdrop)
+{
+	int i;
+	static const char nulldevname[IFNAMSIZ] = { 0 };
+	const struct ipt_physdev_info *info = matchinfo;
+	unsigned long ret;
+	const char *indev, *outdev;
+	struct nf_bridge_info *nf_bridge;
+
+	/* Not a bridged IP packet or no info available yet:
+	 * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if
+	 * the destination device will be a bridge. */
+	if (!(nf_bridge = skb->nf_bridge)) {
+		/* Return MATCH if the invert flags of the used options are on */
+		if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) &&
+		    !(info->invert & IPT_PHYSDEV_OP_BRIDGED))
+			return NOMATCH;
+		if ((info->bitmask & IPT_PHYSDEV_OP_ISIN) &&
+		    !(info->invert & IPT_PHYSDEV_OP_ISIN))
+			return NOMATCH;
+		if ((info->bitmask & IPT_PHYSDEV_OP_ISOUT) &&
+		    !(info->invert & IPT_PHYSDEV_OP_ISOUT))
+			return NOMATCH;
+		if ((info->bitmask & IPT_PHYSDEV_OP_IN) &&
+		    !(info->invert & IPT_PHYSDEV_OP_IN))
+			return NOMATCH;
+		if ((info->bitmask & IPT_PHYSDEV_OP_OUT) &&
+		    !(info->invert & IPT_PHYSDEV_OP_OUT))
+			return NOMATCH;
+		return MATCH;
+	}
+
+	/* This only makes sense in the FORWARD and POSTROUTING chains */
+	if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) &&
+	    (!!(nf_bridge->mask & BRNF_BRIDGED) ^
+	    !(info->invert & IPT_PHYSDEV_OP_BRIDGED)))
+		return NOMATCH;
+
+	if ((info->bitmask & IPT_PHYSDEV_OP_ISIN &&
+	    (!nf_bridge->physindev ^ !!(info->invert & IPT_PHYSDEV_OP_ISIN))) ||
+	    (info->bitmask & IPT_PHYSDEV_OP_ISOUT &&
+	    (!nf_bridge->physoutdev ^ !!(info->invert & IPT_PHYSDEV_OP_ISOUT))))
+		return NOMATCH;
+
+	if (!(info->bitmask & IPT_PHYSDEV_OP_IN))
+		goto match_outdev;
+	indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname;
+	for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
+		ret |= (((const unsigned long *)indev)[i]
+			^ ((const unsigned long *)info->physindev)[i])
+			& ((const unsigned long *)info->in_mask)[i];
+	}
+
+	if ((ret == 0) ^ !(info->invert & IPT_PHYSDEV_OP_IN))
+		return NOMATCH;
+
+match_outdev:
+	if (!(info->bitmask & IPT_PHYSDEV_OP_OUT))
+		return MATCH;
+	outdev = nf_bridge->physoutdev ?
+		 nf_bridge->physoutdev->name : nulldevname;
+	for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
+		ret |= (((const unsigned long *)outdev)[i]
+			^ ((const unsigned long *)info->physoutdev)[i])
+			& ((const unsigned long *)info->out_mask)[i];
+	}
+
+	return (ret != 0) ^ !(info->invert & IPT_PHYSDEV_OP_OUT);
+}
+
+static int
+checkentry(const char *tablename,
+		       const struct ipt_ip *ip,
+		       void *matchinfo,
+		       unsigned int matchsize,
+		       unsigned int hook_mask)
+{
+	const struct ipt_physdev_info *info = matchinfo;
+
+	if (matchsize != IPT_ALIGN(sizeof(struct ipt_physdev_info)))
+		return 0;
+	if (!(info->bitmask & IPT_PHYSDEV_OP_MASK) ||
+	    info->bitmask & ~IPT_PHYSDEV_OP_MASK)
+		return 0;
+	return 1;
+}
+
+static struct ipt_match physdev_match = {
+	.name		= "physdev",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
+
+static int __init init(void)
+{
+	return ipt_register_match(&physdev_match);
+}
+
+static void __exit fini(void)
+{
+	ipt_unregister_match(&physdev_match);
+}
+
+module_init(init);
+module_exit(fini);
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
diff -urN linux-2.4.29/net/ipv4/netfilter/ipt_string.c linux-2.4.29-uc1/net/ipv4/netfilter/ipt_string.c
--- linux-2.4.29/net/ipv4/netfilter/ipt_string.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ipt_string.c	2005-06-14 02:11:51.000000000 +0100
@@ -0,0 +1,216 @@
+/* Kernel module to match a string into a packet.
+ *
+ * Copyright (C) 2000 Emmanuel Roger  <winfield@freegates.be>
+ * 
+ * ChangeLog
+ *	19.02.2002: Gianni Tedesco <gianni@ecsc.co.uk>
+ *		Fixed SMP re-entrancy problem using per-cpu data areas
+ *		for the skip/shift tables.
+ *	02.05.2001: Gianni Tedesco <gianni@ecsc.co.uk>
+ *		Fixed kernel panic, due to overrunning boyer moore string
+ *		tables. Also slightly tweaked heuristic for deciding what
+ * 		search algo to use.
+ * 	27.01.2001: Gianni Tedesco <gianni@ecsc.co.uk>
+ * 		Implemented Boyer Moore Sublinear search algorithm
+ * 		alongside the existing linear search based on memcmp().
+ * 		Also a quick check to decide which method to use on a per
+ * 		packet basis.
+ */
+
+#include <linux/smp.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/file.h>
+#include <net/sock.h>
+
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_string.h>
+
+struct string_per_cpu {
+	int *skip;
+	int *shift;
+	int *len;
+};
+
+struct string_per_cpu *bm_string_data=NULL;
+
+/* Boyer Moore Sublinear string search - VERY FAST */
+char *search_sublinear (char *needle, char *haystack, int needle_len, int haystack_len) 
+{
+	int M1, right_end, sk, sh;  
+	int ended, j, i;
+
+	int *skip, *shift, *len;
+	
+	/* use data suitable for this CPU */
+	shift=bm_string_data[smp_processor_id()].shift;
+	skip=bm_string_data[smp_processor_id()].skip;
+	len=bm_string_data[smp_processor_id()].len;
+	
+	/* Setup skip/shift tables */
+	M1 = right_end = needle_len-1;
+	for (i = 0; i < BM_MAX_HLEN; i++) skip[i] = needle_len;  
+	for (i = 0; needle[i]; i++) skip[needle[i]] = M1 - i;  
+
+	for (i = 1; i < needle_len; i++) {   
+		for (j = 0; j < needle_len && needle[M1 - j] == needle[M1 - i - j]; j++);  
+		len[i] = j;  
+	}  
+
+	shift[0] = 1;  
+	for (i = 1; i < needle_len; i++) shift[i] = needle_len;  
+	for (i = M1; i > 0; i--) shift[len[i]] = i;  
+	ended = 0;  
+	
+	for (i = 0; i < needle_len; i++) {  
+		if (len[i] == M1 - i) ended = i;  
+		if (ended) shift[i] = ended;  
+	}  
+
+	/* Do the search*/  
+	while (right_end < haystack_len)
+	{
+		for (i = 0; i < needle_len && haystack[right_end - i] == needle[M1 - i]; i++);  
+		if (i == needle_len) {
+			return haystack+(right_end - M1);
+		}
+		
+		sk = skip[haystack[right_end - i]];  
+		sh = shift[i];
+		right_end = max(right_end - i + sk, right_end + sh);  
+	}
+
+	return NULL;
+}  
+
+/* Linear string search based on memcmp() */
+char *search_linear (char *needle, char *haystack, int needle_len, int haystack_len) 
+{
+	char *k = haystack + (haystack_len-needle_len);
+	char *t = haystack;
+	
+	while ( t <= k ) {
+		if (memcmp(t, needle, needle_len) == 0)
+			return t;
+		t++;
+	}
+
+	return NULL;
+}
+
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset,
+      const void *hdr,
+      u_int16_t datalen,
+      int *hotdrop)
+{
+	const struct ipt_string_info *info = matchinfo;
+	struct iphdr *ip = skb->nh.iph;
+	int hlen, nlen;
+	char *needle, *haystack;
+	proc_ipt_search search=search_linear;
+
+	if ( !ip ) return 0;
+
+	/* get lenghts, and validate them */
+	nlen=info->len;
+	hlen=ntohs(ip->tot_len)-(ip->ihl*4);
+	if ( nlen > hlen ) return 0;
+
+	needle=(char *)&info->string;
+	haystack=(char *)ip+(ip->ihl*4);
+
+	/* The sublinear search comes in to its own
+	 * on the larger packets */
+	if ( (hlen>IPT_STRING_HAYSTACK_THRESH) &&
+	  	(nlen>IPT_STRING_NEEDLE_THRESH) ) {
+		if ( hlen < BM_MAX_HLEN ) {
+			search=search_sublinear;
+		}else{
+			if (net_ratelimit())
+				printk(KERN_INFO "ipt_string: Packet too big "
+					"to attempt sublinear string search "
+					"(%d bytes)\n", hlen );
+		}
+	}
+	
+    return ((search(needle, haystack, nlen, hlen)!=NULL) ^ info->invert);
+}
+
+static int
+checkentry(const char *tablename,
+           const struct ipt_ip *ip,
+           void *matchinfo,
+           unsigned int matchsize,
+           unsigned int hook_mask)
+{
+
+       if (matchsize != IPT_ALIGN(sizeof(struct ipt_string_info)))
+               return 0;
+
+       return 1;
+}
+
+void string_freeup_data(void)
+{
+	int c;
+	
+	if ( bm_string_data ) {
+		for(c=0; c<smp_num_cpus; c++) {
+			if ( bm_string_data[c].shift ) kfree(bm_string_data[c].shift);
+			if ( bm_string_data[c].skip ) kfree(bm_string_data[c].skip);
+			if ( bm_string_data[c].len ) kfree(bm_string_data[c].len);
+		}
+		kfree(bm_string_data);
+	}
+}
+
+static struct ipt_match string_match
+= { { NULL, NULL }, "string", &match, &checkentry, NULL, THIS_MODULE };
+
+static int __init init(void)
+{
+	int c;
+	size_t tlen;
+	size_t alen;
+
+	tlen=sizeof(struct string_per_cpu)*smp_num_cpus;
+	alen=sizeof(int)*BM_MAX_HLEN;
+	
+	/* allocate array of structures */
+	if ( !(bm_string_data=kmalloc(tlen,GFP_KERNEL)) ) {
+		return 0;
+	}
+	
+	memset(bm_string_data, 0, tlen);
+	
+	/* allocate our skip/shift tables */
+	for(c=0; c<smp_num_cpus; c++) {
+		if ( !(bm_string_data[c].shift=kmalloc(alen, GFP_KERNEL)) )
+			goto alloc_fail;
+		if ( !(bm_string_data[c].skip=kmalloc(alen, GFP_KERNEL)) )
+			goto alloc_fail;
+		if ( !(bm_string_data[c].len=kmalloc(alen, GFP_KERNEL)) )
+			goto alloc_fail;
+	}
+	
+	return ipt_register_match(&string_match);
+
+alloc_fail:
+	string_freeup_data();
+	return 0;
+}
+
+static void __exit fini(void)
+{
+	ipt_unregister_match(&string_match);
+	string_freeup_data();
+}
+
+module_init(init);
+module_exit(fini);
diff -urN linux-2.4.29/net/ipv4/netfilter/ipt_TCPMSS.c linux-2.4.29-uc1/net/ipv4/netfilter/ipt_TCPMSS.c
--- linux-2.4.29/net/ipv4/netfilter/ipt_TCPMSS.c	2001-12-21 17:42:05.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ipt_TCPMSS.c	2005-06-14 02:11:51.000000000 +0100
@@ -45,7 +45,7 @@
 	const struct ipt_tcpmss_info *tcpmssinfo = targinfo;
 	struct tcphdr *tcph;
 	struct iphdr *iph;
-	u_int16_t tcplen, newtotlen, oldval, newmss;
+	u_int16_t tcplen, newtotlen, oldval, newmss, mtu;
 	unsigned int i;
 	u_int8_t *opt;
 
@@ -91,8 +91,20 @@
 		       			"ipt_tcpmss_target: unknown or invalid path-MTU (%d)\n", (*pskb)->dst->pmtu);
 			return NF_DROP; /* or IPT_CONTINUE ?? */
 		}
+		mtu = (*pskb)->dst->pmtu;
 
-		newmss = (*pskb)->dst->pmtu - sizeof(struct iphdr) - sizeof(struct tcphdr);
+		if (in) {
+			if (in->mtu <= (sizeof(struct iphdr) + sizeof(struct tcphdr))) {
+				if (net_ratelimit())
+					printk(KERN_ERR
+		       				"ipt_tcpmss_target: invalid interface MTU (%d)\n", in->mtu);
+				return NF_DROP; /* or IPT_CONTINUE ?? */
+			}
+			if (in->mtu < mtu)
+				mtu = in->mtu;
+		}
+
+		newmss = mtu - sizeof(struct iphdr) - sizeof(struct tcphdr);
 	} else
 		newmss = tcpmssinfo->mss;
 
diff -urN linux-2.4.29/net/ipv4/netfilter/ipt_time.c linux-2.4.29-uc1/net/ipv4/netfilter/ipt_time.c
--- linux-2.4.29/net/ipv4/netfilter/ipt_time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/ipt_time.c	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,189 @@
+/*
+  This is a module which is used for time matching
+  It is using some modified code from dietlibc (localtime() function)
+  that you can find at http://www.fefe.de/dietlibc/
+  This file is distributed under the terms of the GNU General Public
+  License (GPL). Copies of the GPL can be obtained from: ftp://prep.ai.mit.edu/pub/gnu/GPL
+  2001-05-04 Fabrice MARIE <fabrice@netfilter.org> : initial development.
+  2001-21-05 Fabrice MARIE <fabrice@netfilter.org> : bug fix in the match code,
+     thanks to "Zeng Yu" <zengy@capitel.com.cn> for bug report.
+  2001-26-09 Fabrice MARIE <fabrice@netfilter.org> : force the match to be in LOCAL_IN or PRE_ROUTING only.
+  2001-30-11 Fabrice : added the possibility to use the match in FORWARD/OUTPUT with a little hack,
+     added Nguyen Dang Phuoc Dong <dongnd@tlnet.com.vn> patch to support timezones.
+  2004-05-02 Fabrice : added support for date matching, from an idea of Fabien COELHO.
+*/
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_time.h>
+#include <linux/time.h>
+
+MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
+MODULE_DESCRIPTION("Match arrival timestamp/date");
+MODULE_LICENSE("GPL");
+
+struct tm
+{
+	int tm_sec;                   /* Seconds.     [0-60] (1 leap second) */
+	int tm_min;                   /* Minutes.     [0-59] */
+	int tm_hour;                  /* Hours.       [0-23] */
+	int tm_mday;                  /* Day.         [1-31] */
+	int tm_mon;                   /* Month.       [0-11] */
+	int tm_year;                  /* Year - 1900.  */
+	int tm_wday;                  /* Day of week. [0-6] */
+	int tm_yday;                  /* Days in year.[0-365] */
+	int tm_isdst;                 /* DST.         [-1/0/1]*/
+
+	long int tm_gmtoff;           /* we don't care, we count from GMT */
+	const char *tm_zone;          /* we don't care, we count from GMT */
+};
+
+void
+localtime(const time_t *timepr, struct tm *r);
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset,
+      const void *hdr,
+      u_int16_t datalen,
+      int *hotdrop)
+{
+	const struct ipt_time_info *info = matchinfo;   /* match info for rule */
+	struct tm currenttime;                          /* time human readable */
+	u_int8_t days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
+	u_int16_t packet_time;
+	struct timeval kerneltimeval;
+	time_t packet_local_time;
+
+	/* if kerneltime=1, we don't read the skb->timestamp but kernel time instead */
+	if (info->kerneltime)
+	{
+		do_gettimeofday(&kerneltimeval);
+		packet_local_time = kerneltimeval.tv_sec;
+	}
+	else
+		packet_local_time = skb->stamp.tv_sec;
+
+	/* First we make sure we are in the date start-stop boundaries */
+	if ((packet_local_time < info->date_start) || (packet_local_time > info->date_stop))
+		return 0; /* We are outside the date boundaries */
+
+	/* Transform the timestamp of the packet, in a human readable form */
+	localtime(&packet_local_time, &currenttime);
+
+	/* check if we match this timestamp, we start by the days... */
+	if ((days_of_week[currenttime.tm_wday] & info->days_match) != days_of_week[currenttime.tm_wday])
+		return 0; /* the day doesn't match */
+
+	/* ... check the time now */
+	packet_time = (currenttime.tm_hour * 60) + currenttime.tm_min;
+	if ((packet_time < info->time_start) || (packet_time > info->time_stop))
+		return 0;
+
+	/* here we match ! */
+	return 1;
+}
+
+static int
+checkentry(const char *tablename,
+           const struct ipt_ip *ip,
+           void *matchinfo,
+           unsigned int matchsize,
+           unsigned int hook_mask)
+{
+	struct ipt_time_info *info = matchinfo;   /* match info for rule */
+
+	/* First, check that we are in the correct hooks */
+	if (hook_mask
+            & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
+	{
+		printk("ipt_time: error, only valid for PRE_ROUTING, LOCAL_IN, FORWARD and OUTPUT)\n");
+		return 0;
+	}
+	/* we use the kerneltime if we are in forward or output */
+	info->kerneltime = 1;
+	if (hook_mask & ~((1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT))) 
+		/* we use the skb time */
+		info->kerneltime = 0;
+
+	/* Check the size */
+	if (matchsize != IPT_ALIGN(sizeof(struct ipt_time_info)))
+		return 0;
+	/* Now check the coherence of the data ... */
+	if ((info->time_start > 1439) ||        /* 23*60+59 = 1439*/
+	    (info->time_stop  > 1439))
+	{
+		printk(KERN_WARNING "ipt_time: invalid argument\n");
+		return 0;
+	}
+
+	return 1;
+}
+
+static struct ipt_match time_match
+= { { NULL, NULL }, "time", &match, &checkentry, NULL, THIS_MODULE };
+
+static int __init init(void)
+{
+	printk("ipt_time loading\n");
+	return ipt_register_match(&time_match);
+}
+
+static void __exit fini(void)
+{
+	ipt_unregister_match(&time_match);
+	printk("ipt_time unloaded\n");
+}
+
+module_init(init);
+module_exit(fini);
+
+
+/* The part below is borowed and modified from dietlibc */
+
+/* seconds per day */
+#define SPD 24*60*60
+
+void
+localtime(const time_t *timepr, struct tm *r) {
+	time_t i;
+	time_t timep;
+	extern struct timezone sys_tz;
+	const unsigned int __spm[12] =
+		{ 0,
+		  (31),
+		  (31+28),
+		  (31+28+31),
+		  (31+28+31+30),
+		  (31+28+31+30+31),
+		  (31+28+31+30+31+30),
+		  (31+28+31+30+31+30+31),
+		  (31+28+31+30+31+30+31+31),
+		  (31+28+31+30+31+30+31+31+30),
+		  (31+28+31+30+31+30+31+31+30+31),
+		  (31+28+31+30+31+30+31+31+30+31+30),
+		};
+	register time_t work;
+
+	timep = (*timepr) - (sys_tz.tz_minuteswest * 60);
+	work=timep%(SPD);
+	r->tm_sec=work%60; work/=60;
+	r->tm_min=work%60; r->tm_hour=work/60;
+	work=timep/(SPD);
+	r->tm_wday=(4+work)%7;
+	for (i=1970; ; ++i) {
+		register time_t k= (!(i%4) && ((i%100) || !(i%400)))?366:365;
+		if (work>k)
+			work-=k;
+		else
+			break;
+	}
+	r->tm_year=i-1900;
+	for (i=11; i && __spm[i]>work; --i) ;
+	r->tm_mon=i;
+	r->tm_mday=work-__spm[i]+1;
+}
diff -urN linux-2.4.29/net/ipv4/netfilter/Makefile linux-2.4.29-uc1/net/ipv4/netfilter/Makefile
--- linux-2.4.29/net/ipv4/netfilter/Makefile	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/netfilter/Makefile	2005-06-14 02:11:51.000000000 +0100
@@ -30,8 +30,29 @@
 
 # connection tracking
 obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
+ 
+# H.323 support
+obj-$(CONFIG_IP_NF_H323) += ip_conntrack_h323.o
+obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o
+ifdef CONFIG_IP_NF_NAT_H323
+	export-objs += ip_conntrack_h323.o
+endif
+
+
+# connection tracking protocol helpers
+obj-$(CONFIG_IP_NF_CT_PROTO_GRE) += ip_conntrack_proto_gre.o
+ifdef CONFIG_IP_NF_CT_PROTO_GRE
+	export-objs += ip_conntrack_proto_gre.o
+endif
+
+# NAT protocol helpers
+obj-$(CONFIG_IP_NF_NAT_PROTO_GRE) += ip_nat_proto_gre.o
 
 # connection tracking helpers
+obj-$(CONFIG_IP_NF_PPTP) += ip_conntrack_pptp.o
+ifdef CONFIG_IP_NF_NAT_PPTP
+	export-objs += ip_conntrack_pptp.o
+endif
 obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o
 ifdef CONFIG_IP_NF_AMANDA
 	export-objs += ip_conntrack_amanda.o
@@ -49,6 +70,7 @@
 endif
 
 # NAT helpers 
+obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o
 obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o
 obj-$(CONFIG_IP_NF_NAT_TFTP) += ip_nat_tftp.o
 obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o
@@ -65,6 +87,7 @@
 # matches
 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
 obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
+obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
 obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
 obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
 
@@ -73,6 +96,9 @@
 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
 
+obj-$(CONFIG_IP_NF_MATCH_TIME) += ipt_time.o
+
+
 obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
 
 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
@@ -83,10 +109,14 @@
 
 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
 obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
+obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o
 obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
 obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o
+obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o
 obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
 
+obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
+
 # targets
 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
 obj-$(CONFIG_IP_NF_TARGET_MIRROR) += ipt_MIRROR.o
@@ -94,10 +124,14 @@
 obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
 obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o
 obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o
+obj-$(CONFIG_IP_NF_TARGET_IMQ) += ipt_IMQ.o
 obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
 obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
+obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
+obj-$(CONFIG_IP_NF_TARGET_CONNLOG) += ipt_CONNLOG.o
+obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o
 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
 
diff -urN linux-2.4.29/net/ipv4/raw.c linux-2.4.29-uc1/net/ipv4/raw.c
--- linux-2.4.29/net/ipv4/raw.c	2005-01-19 14:10:13.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/raw.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: raw.c,v 1.12 2003/08/08 13:46:37 yoshfuji Exp $ */
+
 /*
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
@@ -520,6 +522,7 @@
 	if (sin) {
 		sin->sin_family = AF_INET;
 		sin->sin_addr.s_addr = skb->nh.iph->saddr;
+		sin->sin_port = 0;
 		memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
 	}
 	if (sk->protinfo.af_inet.cmsg_flags)
diff -urN linux-2.4.29/net/ipv4/route.c linux-2.4.29-uc1/net/ipv4/route.c
--- linux-2.4.29/net/ipv4/route.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/route.c	2005-06-14 02:11:49.000000000 +0100
@@ -2574,9 +2574,15 @@
 	if (!ipv4_dst_ops.kmem_cachep)
 		panic("IP: failed to allocate ip_dst_cache\n");
 
-	goal = num_physpages >> (26 - PAGE_SHIFT);
+#if CONFIG_IP_ROUTE_BIG_RT_CACHE
+	/* Increase default for dedicated routers. */
+	goal = (num_physpages << PAGE_SHIFT) >> 11;
+#else
+	goal = (num_physpages << PAGE_SHIFT) >> 14;
+#endif
+	ip_rt_max_size = goal / sizeof(struct rt_hash_bucket) * 16;
 
-	for (order = 0; (1UL << order) < goal; order++)
+	for (order = 0; (1UL << order) < (goal >> PAGE_SHIFT); order++)
 		/* NOTHING */;
 
 	do {
@@ -2605,7 +2611,10 @@
 	}
 
 	ipv4_dst_ops.gc_thresh = (rt_hash_mask + 1);
-	ip_rt_max_size = (rt_hash_mask + 1) * 16;
+	if (ip_rt_max_size > (rt_hash_mask + 1) * 16)
+		ip_rt_max_size = (rt_hash_mask + 1) * 16;
+	else if (ip_rt_max_size < rt_hash_mask + 1)
+		ip_rt_max_size = rt_hash_mask + 1;
 
 	devinet_init();
 	ip_fib_init();
diff -urN linux-2.4.29/net/ipv4/tcp_ipv4.c linux-2.4.29-uc1/net/ipv4/tcp_ipv4.c
--- linux-2.4.29/net/ipv4/tcp_ipv4.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/tcp_ipv4.c	2005-06-14 02:11:49.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: tcp_ipv4.c,v 1.81 2003/11/12 05:12:00 yoshfuji Exp $ */
+
 /*
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
@@ -45,12 +47,20 @@
  *	Vitaly E. Lavrov	:	Transparent proxy revived after year coma.
  *	Andi Kleen		:	Fix new listen.
  *	Andi Kleen		:	Fix accept error reporting.
- *	YOSHIFUJI Hideaki @USAGI and:	Support IPV6_V6ONLY socket option, which
- *	Alexey Kuznetsov		allow both IPv4 and IPv6 sockets to bind
- *					a single port at the same time.
+ *		yoshfuji@USAGI	:	Reworked bind(2) behavior, including:
+ *					- Allow ipv6 and ipv4 bind(2) to the
+ *					  same port.
+ *					- Don't allow narrow binding unless
+ *					  later uid is the same as before:
+ *					  CONFIG_NET_RESTRICTED_REUSE
+ *					- Don't allow binding to the same
+ *					  address unless it is one of multi-
+ *					  cast address even if SO_REUSEADDR 
+ *					  is set.
  */
 
 #include <linux/config.h>
+#include <linux/module.h>
 
 #include <linux/types.h>
 #include <linux/fcntl.h>
@@ -138,6 +148,7 @@
 	if(tb != NULL) {
 		tb->port = snum;
 		tb->fastreuse = 0;
+		tb->uid = (uid_t)-1;
 		tb->owners = NULL;
 		if((tb->next = head->chain) != NULL)
 			tb->next->pprev = &tb->next;
@@ -183,9 +194,146 @@
 static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb)
 {
 	struct sock *sk2 = tb->owners;
-	int sk_reuse = sk->reuse;
-	
+	int sk_reuse, sk2_reuse;
+	int addr_type2;
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+	uid_t sk_uid = sk->state != TCP_TIME_WAIT ? sock_i_uid_t(sk) : ((struct tcp_tw_bucket *)sk)->uid;
+#endif
+#if defined(CONFIG_IPV6_IM) && defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+	int *sysctl_ipv6_bindv6only_restriction = inter_module_get(IM_IPV6_SYSCTL_BINDV6ONLY_RESTRICTION);
+#endif
+	int ret;
+
+	sk_reuse = 0;
+	if (sk->reuse)
+		sk_reuse |= 1;
+#ifdef SO_REUSEPORT
+	if (sk->reuseport)
+		sk_reuse |= 2;
+#endif
+#if 0
+	if (sk_reuse &&
+	    MULTICAST(sk->rcv_saddr))
+			sk_reuse |= 4;
+#endif
+
 	for( ; sk2 != NULL; sk2 = sk2->bind_next) {
+#if 1	/* XXX: should be recoded like 2.4.21 */
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+		uid_t sk2_uid;
+		int uid_ok;
+#endif
+		int both_specified = 0;
+
+		if (sk2 == sk ||
+		    (sk2->bound_dev_if && sk->bound_dev_if &&
+		     sk2->bound_dev_if != sk->bound_dev_if))
+			continue;
+#if 0
+		if (sk2->family != AF_INET6 && sk2->family != AF_INET)
+			continue;
+#endif
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+		if (sk2->family == AF_INET6) {
+			struct in6_addr *sk2_rcv_saddr6 = sk2->state != TCP_TIME_WAIT ?
+								&sk2->net_pinfo.af_inet6.rcv_saddr :
+								&((struct tcp_tw_bucket*)sk2)->v6_rcv_saddr;
+			if (IN6_IS_ADDR_UNSPECIFIED(sk2_rcv_saddr6))
+				addr_type2 = IPV6_ADDR_ANY;
+			else if (IN6_IS_ADDR_V4MAPPED(sk2_rcv_saddr6))
+				addr_type2 = IPV6_ADDR_MAPPED;
+			else
+				addr_type2 = IPV6_ADDR_UNICAST;	/*XXX*/
+		} else
+			addr_type2 = IPV6_ADDR_MAPPED;
+#else
+		addr_type2 = IPV6_ADDR_MAPPED;
+#endif
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+		sk2_uid = sk2->state != TCP_TIME_WAIT ? sock_i_uid(sk2) : ((struct tcp_tw_bucket *)sk2)->uid;
+#endif
+		if ((addr_type2 != IPV6_ADDR_MAPPED ? addr_type2 != IPV6_ADDR_ANY : sk2->rcv_saddr) &&
+		    sk->rcv_saddr) {
+			if (sk2->rcv_saddr != sk->rcv_saddr)
+				continue;
+			both_specified = 1;
+		}
+
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+		uid_ok = sk2_uid == (uid_t) -1 || sk_uid == sk2_uid;
+#endif
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+		if (addr_type2 != IPV6_ADDR_MAPPED && __ipv6_only_sock(sk2)) {
+#ifdef CONFIG_IPV6_RESTRICTED_DOUBLE_BIND
+#ifndef CONFIG_IPV6_IM
+			if (sysctl_ipv6_bindv6only_restriction == 0 || uid_ok)
+				continue;
+#else
+			if ((sysctl_ipv6_bindv6only_restriction && *sysctl_ipv6_bindv6only_restriction == 0) || uid_ok)
+				continue;
+#endif
+#else
+			continue;
+#endif
+		}
+#endif
+
+		sk2_reuse = 0;
+		if (sk2->reuse)
+			sk2_reuse |= 1;
+#ifdef SO_REUSEPORT
+		if (sk2->reuseport)
+			sk2_reuse |= 2;
+#endif
+#if 0
+		if (sk2_reuse &&
+		    (addr_type2 != IPV6_ADDR_MAPPED ? (addr_type2 & IPV6_ADDR_MULTICAST) : MULTICAST(sk2->rcv_saddr)))
+			sk2_reuse |= 4;
+#endif
+
+		if (sk2_reuse & sk_reuse & 3) {	/* NOT && */
+			ret = 1;
+#if 0
+			if (sk2_reuse & sk_reuse & 4)
+				continue;
+#endif
+#ifdef CONFIG_NET_RESTRICTED_REUSE
+			if (!uid_ok)
+				goto failed;
+#endif
+#ifdef SO_REUSEPORT
+			if (sk2_reuse & sk_reuse & 2)
+				continue;
+#endif
+			if (both_specified) {
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+				struct in6_addr *sk2_daddr6 = sk2->state != TCP_TIME_WAIT ?
+								&sk2->net_pinfo.af_inet6.daddr :
+								&((struct tcp_tw_bucket*)sk2)->v6_daddr;
+#endif
+				int addr_type2d;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+				if (sk2->family == AF_INET6) {
+					if (IN6_IS_ADDR_UNSPECIFIED(sk2_daddr6))
+						addr_type2d = IPV6_ADDR_ANY;
+					else if (IN6_IS_ADDR_V4MAPPED(sk2_daddr6))
+						addr_type2d = IPV6_ADDR_MAPPED;
+					else
+						addr_type2d = IPV6_ADDR_UNICAST; /*XXX*/
+				} else
+					addr_type2d = IPV6_ADDR_MAPPED;
+#else
+				addr_type2d = IPV6_ADDR_MAPPED;
+#endif
+				if (addr_type2d != IPV6_ADDR_MAPPED ? addr_type2d != IPV6_ADDR_ANY : sk2->daddr)
+					continue;
+			} else {
+				if ((addr_type2 != IPV6_ADDR_MAPPED ? addr_type2 != IPV6_ADDR_ANY : sk2->rcv_saddr) ||
+				    sk->rcv_saddr)
+					continue;
+#else	/* XXX: should be recoded like 2.4.21 */
 		if (sk != sk2 &&
 		    sk2->reuse <= 1 &&
 		    !ipv6_only_sock(sk2) &&
@@ -199,10 +347,20 @@
 				    !sk->rcv_saddr	||
 				    (sk2->rcv_saddr == sk->rcv_saddr))
 					break;
+#endif	/* XXX: should be recoded like 2.4.21 */
 			}
 		}
+		ret = 1;
+		goto failed;
 	}
-	return sk2 != NULL;
+	/* If we found a conflict, fail. */
+	ret = sk2 != NULL;
+failed:
+#if defined(CONFIG_IPV6_IM) && defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+	if (sysctl_ipv6_bindv6only_restriction)
+		inter_module_put(IM_IPV6_SYSCTL_BINDV6ONLY_RESTRICTION);
+#endif
+	return ret;
 }
 
 /* Obtain a reference to a local port for the given sock,
@@ -212,6 +370,9 @@
 {
 	struct tcp_bind_hashbucket *head;
 	struct tcp_bind_bucket *tb;
+#if defined(CONFIG_NET_RESTRICTED_REUSE)
+	uid_t sk_uid = sk->state != TCP_TIME_WAIT ? sock_i_uid_t(sk) : ((struct tcp_tw_bucket *)sk)->uid;
+#endif
 	int ret;
 
 	local_bh_disable();
@@ -256,9 +417,17 @@
 				break;
 	}
 	if (tb != NULL && tb->owners != NULL) {
-		if (sk->reuse > 1)
-			goto success;
-		if (tb->fastreuse > 0 && sk->reuse != 0 && sk->state != TCP_LISTEN) {
+		ret = 1; 
+		if (tb->fastreuse > 0 && 
+		    (sk->reuse != 0 
+#ifdef SO_REUSEPORT
+		     || sk->reuseport != 0
+#endif
+		    ) &&
+#if defined(CONFIG_NET_RESTRICTED_REUSE)
+		    sk_uid == tb->uid &&
+#endif
+		    sk->state != TCP_LISTEN) {
 			goto success;
 		} else {
 			ret = 1;
@@ -271,12 +440,27 @@
 	    (tb = tcp_bucket_create(head, snum)) == NULL)
 			goto fail_unlock;
 	if (tb->owners == NULL) {
-		if (sk->reuse && sk->state != TCP_LISTEN)
+		if ((sk->reuse
+#ifdef SO_REUSEPORT
+		     || sk->reuseport
+#endif
+		    ) && sk->state != TCP_LISTEN) {
 			tb->fastreuse = 1;
-		else
+#if defined(CONFIG_NET_RESTRICTED_REUSE)
+			tb->uid = sk_uid;
+#endif
+		} else
 			tb->fastreuse = 0;
 	} else if (tb->fastreuse &&
-		   ((sk->reuse == 0) || (sk->state == TCP_LISTEN)))
+		   ((sk->reuse == 0
+#ifdef SO_REUSEPORT
+		     && sk_reuseport == 0
+#endif
+		    ) || 
+#if defined(CONFIG_NET_RESTRICTED_REUSE)
+		    (sk_uid != tb->uid) ||
+#endif
+		    (sk->state == TCP_LISTEN)))
 		tb->fastreuse = 0;
 success:
 	if (sk->prev == NULL)
@@ -1927,6 +2111,7 @@
 	sin->sin_family		= AF_INET;
 	sin->sin_addr.s_addr	= sk->daddr;
 	sin->sin_port		= sk->dport;
+	memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
 }
 
 /* VJ's idea. Save last timestamp seen from this destination
diff -urN linux-2.4.29/net/ipv4/tcp_minisocks.c linux-2.4.29-uc1/net/ipv4/tcp_minisocks.c
--- linux-2.4.29/net/ipv4/tcp_minisocks.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/tcp_minisocks.c	2005-06-14 02:11:50.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: tcp_minisocks.c,v 1.12 2003/08/08 13:46:37 yoshfuji Exp $ */
+
 /*
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
@@ -369,6 +371,9 @@
 		tw->dport	= sk->dport;
 		tw->family	= sk->family;
 		tw->reuse	= sk->reuse;
+#ifdef SO_REUSEPORT
+		tw->reuseport	= sk->reuseport;
+#endif
 		tw->rcv_wscale	= tp->rcv_wscale;
 		atomic_set(&tw->refcnt, 1);
 
@@ -380,6 +385,8 @@
 		tw->ts_recent_stamp= tp->ts_recent_stamp;
 		tw->pprev_death = NULL;
 
+		tw->uid		= sock_i_uid_t(sk);
+
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 		if(tw->family == PF_INET6) {
 			memcpy(&tw->v6_daddr,
diff -urN linux-2.4.29/net/ipv4/udp.c linux-2.4.29-uc1/net/ipv4/udp.c
--- linux-2.4.29/net/ipv4/udp.c	2005-01-19 14:10:14.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv4/udp.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: udp.c,v 1.59 2003/11/12 05:12:00 yoshfuji Exp $ */
+
 /*
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
@@ -61,9 +63,16 @@
  *					return ENOTCONN for unconnected sockets (POSIX)
  *		Janos Farkas	:	don't deliver multi/broadcasts to a different
  *					bound-to-device socket
- *	YOSHIFUJI Hideaki @USAGI and:	Support IPV6_V6ONLY socket option, which
- *	Alexey Kuznetsov:		allow both IPv4 and IPv6 sockets to bind
- *					a single port at the same time.
+ *		yoshfuji@USAGI	:	Reworked bind(2) behavior, including:
+ *					- Allow ipv6 and ipv4 bind(2) to the
+ *					  same port.
+ *					- Don't allow narrow binding unless
+ *					  later uid is the same as before:
+ *					  CONFIG_NET_RESTRICTED_REUSE
+ *					- Don't allow binding to the same
+ *					  address unless it is one of multi-
+ *					  cast address even if SO_REUSEADDR 
+ *					  is set.
  *
  *
  *		This program is free software; you can redistribute it and/or
@@ -79,6 +88,7 @@
 #include <linux/fcntl.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
+#include <linux/module.h>
 #include <linux/in.h>
 #include <linux/errno.h>
 #include <linux/timer.h>
@@ -112,6 +122,9 @@
 
 static int udp_v4_get_port(struct sock *sk, unsigned short snum)
 {
+#if defined(CONFIG_IPV6_IM) && defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+	int *sysctl_ipv6_bindv6only_restriction = inter_module_get(IM_IPV6_SYSCTL_BINDV6ONLY_RESTRICTION);
+#endif
 	write_lock_bh(&udp_hash_lock);
 	if (snum == 0) {
 		int best_size_so_far, best, result, i;
@@ -157,10 +170,134 @@
 		udp_port_rover = snum = result;
 	} else {
 		struct sock *sk2;
+		int sk_reuse, sk2_reuse;
+		int addr_type2;
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+		uid_t sk_uid = sock_i_uid_t(sk),
+		      sk2_uid;
+#endif
+
+		sk_reuse = 0;
+		if (sk->reuse)
+			sk_reuse |= 1;
+#ifdef SO_REUSEPORT
+		if (sk->reuseport)
+			sk_reuse |= 2;
+#endif
+		if (sk_reuse &&
+		    MULTICAST(sk->rcv_saddr))
+			sk_reuse |= 4;
 
 		for (sk2 = udp_hash[snum & (UDP_HTABLE_SIZE - 1)];
 		     sk2 != NULL;
 		     sk2 = sk2->next) {
+#if 1	/* XXX: linux-2.4.21 style */
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+			int uid_ok;
+#endif
+			int both_specified = 0;
+
+			if (sk2->num != snum ||
+			    sk2 == sk ||
+			    (sk2->bound_dev_if && sk->bound_dev_if &&
+			     sk2->bound_dev_if != sk->bound_dev_if))
+				continue;
+#if 0
+			if (sk2->family != AF_INET6 && sk2->family != AF_INET)
+				continue;
+#endif
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+			if (sk2->family == AF_INET6) {
+				if (IN6_IS_ADDR_UNSPECIFIED(&sk2->net_pinfo.af_inet6.rcv_saddr))
+					addr_type2 = IPV6_ADDR_ANY;
+				else if (IN6_IS_ADDR_V4MAPPED(&sk2->net_pinfo.af_inet6.rcv_saddr))
+					addr_type2 = IPV6_ADDR_MAPPED;
+				else
+					addr_type2 = IPV6_ADDR_UNICAST;	/*XXX*/
+			} else
+				addr_type2 = IPV6_ADDR_MAPPED;
+#else
+			addr_type2 = IPV6_ADDR_MAPPED;
+#endif
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+			sk2_uid = sock_i_uid_t(sk2);
+#endif
+
+			if ((addr_type2 != IPV6_ADDR_MAPPED ? addr_type2 != IPV6_ADDR_ANY : sk2->rcv_saddr) &&
+			    sk->rcv_saddr) {
+				if (sk2->rcv_saddr != sk->rcv_saddr)
+					continue;
+				both_specified = 1;
+			}
+
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+			uid_ok = sk2_uid == (uid_t) -1 || sk_uid == sk2_uid;
+#endif
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+			if (addr_type2 != IPV6_ADDR_MAPPED && __ipv6_only_sock(sk2)) {
+#ifdef CONFIG_IPV6_RESTRICTED_DOUBLE_BIND
+#ifndef CONFIG_IPV6_IM
+				if (sysctl_ipv6_bindv6only_restriction == 0 || uid_ok)
+					continue;
+#else
+				if ((sysctl_ipv6_bindv6only_restriction && *sysctl_ipv6_bindv6only_restriction == 0) || uid_ok)
+					continue;
+#endif
+#else
+				continue;
+#endif
+			}
+#endif
+
+			sk2_reuse = 0;
+			if (sk2->reuse)
+				sk2_reuse |= 1;
+#ifdef SO_REUSEPORT
+			if (sk2->reuseport)
+				sk2_reuse |= 2;
+#endif
+			if (sk2_reuse &&
+			    (addr_type2 != IPV6_ADDR_MAPPED ? (addr_type2 & IPV6_ADDR_MULTICAST) : MULTICAST(sk2->rcv_saddr)))
+				sk2_reuse |= 4;
+
+			if (sk2_reuse & sk_reuse & 3) {	/* NOT && */
+				if (sk2_reuse & sk_reuse & 4)
+					continue;
+#ifdef CONFIG_NET_RESTRICTED_REUSE
+				if (!uid_ok)
+					goto fail;
+#endif
+#ifdef SO_REUSEPORT
+				if (sk2_reuse & sk_reuse & 2)
+					continue;
+#endif
+				if (both_specified) {
+					int addr_type2d;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+					if (sk2->family == AF_INET6) {
+						if (IN6_IS_ADDR_UNSPECIFIED(&sk2->net_pinfo.af_inet6.daddr))
+							addr_type2d = IPV6_ADDR_ANY;
+						else if (IN6_IS_ADDR_V4MAPPED(&sk2->net_pinfo.af_inet6.daddr))
+							addr_type2d = IPV6_ADDR_MAPPED;
+						else
+							addr_type2d = IPV6_ADDR_UNICAST; /*XXX*/
+					} else
+						addr_type2d = IPV6_ADDR_MAPPED;
+#else
+					addr_type2d = IPV6_ADDR_MAPPED;
+#endif
+					if (addr_type2d != IPV6_ADDR_MAPPED ? addr_type2d != IPV6_ADDR_ANY : sk2->daddr)
+						continue;
+				} else {
+					if ((addr_type2 != IPV6_ADDR_MAPPED ? addr_type2 != IPV6_ADDR_ANY : sk2->rcv_saddr) ||
+					    sk->rcv_saddr)
+						continue;
+				}
+			}
+			goto fail;
+#else	/* XXX: linux-2.4.21 style */
 			if (sk2->num == snum &&
 			    sk2 != sk &&
 			    !ipv6_only_sock(sk2) &&
@@ -172,6 +309,7 @@
 			     sk2->rcv_saddr == sk->rcv_saddr) &&
 			    (!sk2->reuse || !sk->reuse))
 				goto fail;
+#endif	/* XXX: linux-2.4.21 style */
 		}
 	}
 	sk->num = snum;
@@ -185,10 +323,18 @@
 		sock_hold(sk);
 	}
 	write_unlock_bh(&udp_hash_lock);
+#if defined(CONFIG_IPV6_IM) && defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+	if (sysctl_ipv6_bindv6only_restriction)
+		inter_module_put(IM_IPV6_SYSCTL_BINDV6ONLY_RESTRICTION);
+#endif
 	return 0;
 
 fail:
 	write_unlock_bh(&udp_hash_lock);
+#if defined(CONFIG_IPV6_IM) && defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+	if (sysctl_ipv6_bindv6only_restriction)
+		inter_module_put(IM_IPV6_SYSCTL_BINDV6ONLY_RESTRICTION);
+#endif
 	return 1;
 }
 
@@ -860,6 +1006,9 @@
 
 static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
 {
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+	struct udp_opt *tp =  &(sk->tp_pinfo.af_udp);
+#endif
 	/*
 	 *	Charge it to the socket, dropping if the queue is full.
 	 */
@@ -876,7 +1025,38 @@
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 	}
 #endif
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+	if (tp->esp_in_udp) {
+		/*
+		 * Set skb->sk and xmit packet to ipsec_rcv.
+		 *
+		 * If ret != 0, ipsec_rcv refused the packet (not ESPinUDP),
+		 * restore skb->sk and fall back to sock_queue_rcv_skb
+		 */
+		struct inet_protocol *esp = NULL;
+
+#ifdef CONFIG_IPSEC_MODULE
+		for (esp = (struct inet_protocol *)inet_protos[IPPROTO_ESP & (MAX_INET_PROTOS - 1)];
+			(esp) && (esp->protocol != IPPROTO_ESP);
+			esp = esp->next);
+#else
+		extern struct inet_protocol esp_protocol;
+		esp = &esp_protocol;
+#endif
 
+		if (esp && esp->handler) {
+			struct sock *sav_sk = skb->sk;
+			skb->sk = sk;
+		if (esp->handler(skb) == 0) {
+				skb->sk = sav_sk;
+				/* not sure we might count ESPinUDP as UDP... */
+				UDP_INC_STATS_BH(UdpInDatagrams);
+				return 0;
+			}
+			skb->sk = sav_sk;
+		}
+	}
+#endif
 	if (sock_queue_rcv_skb(sk,skb)<0) {
 		UDP_INC_STATS_BH(UdpInErrors);
 		IP_INC_STATS_BH(IpInDiscards);
@@ -1100,13 +1280,55 @@
 	return len;
 }
 
+#if 1
+static int udp_setsockopt(struct sock *sk, int level, int optname,
+	char *optval, int optlen)
+{
+	struct udp_opt *tp = &(sk->tp_pinfo.af_udp);
+	int val;
+	int err = 0;
+
+	if (level != SOL_UDP)
+		return ip_setsockopt(sk, level, optname, optval, optlen);
+
+	if(optlen<sizeof(int))
+		return -EINVAL;
+
+	if (get_user(val, (int *)optval))
+		return -EFAULT;
+	
+	lock_sock(sk);
+
+	switch(optname) {
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+#ifndef UDP_ESPINUDP
+#define UDP_ESPINUDP 100
+#endif
+		case UDP_ESPINUDP:
+			tp->esp_in_udp = val;
+			break;
+#endif
+		default:
+			err = -ENOPROTOOPT;
+			break;
+	}
+
+	release_sock(sk);
+	return err;
+}
+#endif
+
 struct proto udp_prot = {
  	name:		"UDP",
 	close:		udp_close,
 	connect:	udp_connect,
 	disconnect:	udp_disconnect,
 	ioctl:		udp_ioctl,
-	setsockopt:	ip_setsockopt,
+#if 1
+	setsockopt:	udp_setsockopt,
+#else
+ 	setsockopt:	ip_setsockopt,
+#endif
 	getsockopt:	ip_getsockopt,
 	sendmsg:	udp_sendmsg,
 	recvmsg:	udp_recvmsg,
diff -urN linux-2.4.29/net/ipv4/utils.c linux-2.4.29-uc1/net/ipv4/utils.c
--- linux-2.4.29/net/ipv4/utils.c	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv4/utils.c	2005-06-14 02:11:50.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: utils.c,v 1.10 2003/08/24 01:16:44 yoshfuji Exp $ */
+
 /*
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
@@ -22,7 +24,22 @@
  */
 
 #include <linux/types.h>
+#include <linux/socket.h>
+#include <linux/in.h>
 #include <asm/byteorder.h>
+#include <linux/kernel.h>
+
+/*
+ *	Display an IP address in readable format. 
+ */
+ 
+char *in_ntop(struct in_addr *in, char *buff)
+{
+	char *p = (char *)in;
+	sprintf(buff, "%d.%d.%d.%d", 
+		(p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
+	return buff;
+}
 
 /*
  *	Convert an ASCII string to binary IP. 
diff -urN linux-2.4.29/net/ipv6/addrconf.c linux-2.4.29-uc1/net/ipv6/addrconf.c
--- linux-2.4.29/net/ipv6/addrconf.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/addrconf.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: addrconf.c,v 1.235 2004/01/15 11:35:15 yoshfuji Exp $ */
+
 /*
  *	IPv6 Address [auto]configuration
  *	Linux INET6 implementation
@@ -31,16 +33,27 @@
  *	Yuji SEKIYA @USAGI		:	Don't assign a same IPv6
  *						address on a same interface.
  *	YOSHIFUJI Hideaki @USAGI	:	ARCnet support
+ *	YOSHIFUJI Hideaki @USAGI	:	improved source address
+ *						selection; consider scope,
+ *						status etc.
+ *	yoshfuji@USAGI			:	Privacy Extensions (RFC 3041)
+ *						support.
+ *	Antonio Tapiador		:	Label table user level
+ *	<atapiador@dit.upm.es>			configuration
  */
 
 #include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/types.h>
+#include <linux/random.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
 #include <linux/sched.h>
 #include <linux/net.h>
 #include <linux/in6.h>
+#ifdef CONFIG_IPV6_NODEINFO
+#include <linux/icmpv6.h>
+#endif
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/if_arcnet.h>
@@ -57,6 +70,7 @@
 #include <net/sock.h>
 #include <net/snmp.h>
 
+#include <net/addrconf.h>
 #include <net/ipv6.h>
 #include <net/protocol.h>
 #include <net/ndisc.h>
@@ -66,19 +80,69 @@
 #include <linux/if_tunnel.h>
 #include <linux/rtnetlink.h>
 
+#ifdef CONFIG_IPV6_PRIVACY
+#include <linux/crypto.h>
+#include <asm/scatterlist.h>
+#endif
+
 #include <asm/uaccess.h>
 
-#define IPV6_MAX_ADDRESSES 16
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+#include <linux/inet.h>
+#endif
 
 /* Set to 3 to get tracing... */
-#define ACONF_DEBUG 2
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+#define ACONF_DEBUG 3
+#else
+#define ACONF_DEBUG 1
+#endif
 
+#define ADBG(x)		printk x
+#define NOADBG(x)	do { ; } while(0)
 #if ACONF_DEBUG >= 3
-#define ADBG(x) printk x
+#define ADBG3(x)	ADBG(x)
+#else
+#define ADBG3(x)	NOADBG(x)
+#endif
+
+#if ACONF_DEBUG >= 2
+#define ADBG2(x)	ADBG(x)
+#else
+#define ADBG2(x)	NOADBG(x)
+#endif
+
+#if ACONF_DEBUG >=1
+#define ADBG1(x)	ADBG(x)
+#else
+#define ADBG1(x)	NOADBG(x)
+#endif
+
+/* /proc/net/snmp6, /proc/net/dev_snmp6/ things */
+#ifdef CONFIG_PROC_FS
+extern struct proc_dir_entry *proc_net_devsnmp6;
+extern int afinet6_read_devsnmp(char *buffer, 
+				char **start, off_t offset, int length, 
+				int *eof, void *data);
+#endif
+
+#if HZ == 100
+#define	timeticks(jif)	(jif)
+#elif HZ < 100
+#define timeticks(jif)	({ unsigned long _j=(jif);			\
+			   unsigned long _j1 = _j/HZ, _j2 = _j%HZ;	\
+			   (100/HZ)*_j1*HZ + 				\
+			   (100/HZ)*_j2+_j1*(100%HZ) +			\
+			   ((100%HZ)*_j2)/HZ;				\
+			})
 #else
-#define ADBG(x)
+#define timeticks(jif)	({ unsigned long _j=(jif);			\
+			   (_j/HZ)*(100%HZ)+((100%HZ)*(_j%HZ))/HZ;	\
+			})
 #endif
 
+#define INFINITE	0xffffffff
+
 #ifdef CONFIG_SYSCTL
 static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf *p);
 static void addrconf_sysctl_unregister(struct ipv6_devconf *p);
@@ -87,6 +151,31 @@
 int inet6_dev_count;
 int inet6_ifa_count;
 
+#ifdef CONFIG_IPV6_PRIVACY
+static int __ipv6_regen_rndid(struct inet6_dev *idev);
+static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr); 
+static void ipv6_regen_rndid(unsigned long data);
+
+static int desync_factor = MAX_DESYNC_FACTOR * HZ;
+static struct crypto_tfm *md5_tfm;
+static spinlock_t md5_tfm_lock = SPIN_LOCK_UNLOCKED;
+#endif
+
+int ipv6_count_addresses(struct inet6_dev *idev);
+static u32 ipv6_addrselect_label_lookup(const struct in6_addr *addr, int ifindex);
+
+struct ipv6_addrselect_label 
+{
+	struct ipv6_addrselect_label *next;
+	struct in6_addr addr;
+	u16     plen;
+	u32     ifindex;
+	u32     label;
+};
+
+struct ipv6_addrselect_label 	*ipv6_addrselect_label_table;
+rwlock_t	addrselect_label_lock = RW_LOCK_UNLOCKED;
+
 /*
  *	Configured unicast address hash table
  */
@@ -125,6 +214,17 @@
 	MAX_RTR_SOLICITATIONS,		/* router solicits	*/
 	RTR_SOLICITATION_INTERVAL,	/* rtr solicit interval	*/
 	MAX_RTR_SOLICITATION_DELAY,	/* rtr solicit delay	*/
+	max_addresses: 		IPV6_MAX_ADDRESSES,
+#ifdef CONFIG_IPV6_NODEINFO
+	accept_ni:		1,
+#endif
+#ifdef CONFIG_IPV6_PRIVACY
+	use_tempaddr:		1,
+	temp_valid_lft:		TEMP_VALID_LIFETIME,
+	temp_prefered_lft:	TEMP_PREFERRED_LIFETIME,
+	regen_max_retry:	REGEN_MAX_RETRY,
+	max_desync_factor:	MAX_DESYNC_FACTOR,
+#endif
 };
 
 static struct ipv6_devconf ipv6_devconf_dflt =
@@ -139,13 +239,24 @@
 	MAX_RTR_SOLICITATIONS,		/* router solicits	*/
 	RTR_SOLICITATION_INTERVAL,	/* rtr solicit interval	*/
 	MAX_RTR_SOLICITATION_DELAY,	/* rtr solicit delay	*/
+	max_addresses: 		IPV6_MAX_ADDRESSES,
+#ifdef CONFIG_IPV6_NODEINFO
+	accept_ni:		1,
+#endif
+#ifdef CONFIG_IPV6_PRIVACY
+	use_tempaddr:		1,
+	temp_valid_lft:		TEMP_VALID_LIFETIME,
+	temp_prefered_lft:	TEMP_PREFERRED_LIFETIME,
+	regen_max_retry:	REGEN_MAX_RETRY,
+	max_desync_factor:	MAX_DESYNC_FACTOR,
+#endif
 };
 
-/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
+/* IPv6 Wildcard Address and Loopback Address defined by RFC3493 */
 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
 
-int ipv6_addr_type(const struct in6_addr *addr)
+int __ipv6_addr_type(const struct in6_addr *addr)
 {
 	int type;
 	u32 st;
@@ -153,74 +264,87 @@
 	st = addr->s6_addr32[0];
 
 	if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
-		type = IPV6_ADDR_MULTICAST;
+		/* multicast */
 
-		switch((st & htonl(0x00FF0000))) {
-			case __constant_htonl(0x00010000):
-				type |= IPV6_ADDR_LOOPBACK;
-				break;
+		type = IPV6_ADDR_MC_SCOPE(addr)<<16;	/* addr-select 3.1 */
+		switch(type) {
+		case IPV6_ADDR_SCOPE_NODELOCAL<<16:
+			type |= IPV6_ADDR_LOOPBACK;
+			break;
 
-			case __constant_htonl(0x00020000):
-				type |= IPV6_ADDR_LINKLOCAL;
-				break;
+		case IPV6_ADDR_SCOPE_LINKLOCAL<<16:
+			type |= IPV6_ADDR_LINKLOCAL;
+			break;
 
-			case __constant_htonl(0x00050000):
-				type |= IPV6_ADDR_SITELOCAL;
-				break;
-		};
+		case IPV6_ADDR_SCOPE_SITELOCAL<<16:
+			type |= IPV6_ADDR_SITELOCAL;
+			break;
+#if 0
+		default:
+			/* XXX: orglocal, global and other scopes */
+#endif
+		}
+		type |= IPV6_ADDR_MULTICAST;
 		return type;
 	}
+
+	if ((st & htonl(0xE0000000)) == htonl(0x00000000)) {
+		if (st == htonl(0x00000000)) {
+			/* ipv4-compatible, ipv4-mapped and reserved addresses */
+			if ((addr->s6_addr32[1]|addr->s6_addr32[2]) == htonl(0x00000000)) {
+				if (addr->s6_addr32[3] == htonl(0x00000000))
+					return IPV6_ADDR_ANY;
+				if (addr->s6_addr32[3] == htonl(0x00000001))
+					return (IPV6_ADDR_LOOPBACK | IPV6_ADDR_UNICAST |
+						IPV6_ADDR_SCOPE_LINKLOCAL<<16);	/* addr-select 3.4 */
+				return (IPV6_ADDR_COMPATv4 | 
+					IPV6_ADDR_SCOPE_GLOBAL<<16);		/* addr-select 3.3 */
+			}
+			if (addr->s6_addr32[1] == htonl(0x00000000) &&
+			    addr->s6_addr32[2] == htonl(0x0000ffff)) {
+				return (IPV6_ADDR_MAPPED | 
+					IPV6_ADDR_SCOPE_GLOBAL<<16);	/* addr-select 3.3 */
+			}
+		}
+		/* NSAP and IPX addresses, too */
+		return (IPV6_ADDR_RESERVED | 
+			IPV6_ADDR_SCOPE_GLOBAL<<16);		/* addr-select 3.3 */
+	}
+
 	/* check for reserved anycast addresses */
-	
 	if ((st & htonl(0xE0000000)) &&
-	    ((addr->s6_addr32[2] == htonl(0xFDFFFFFF) &&
-	    (addr->s6_addr32[3] | htonl(0x7F)) == (u32)~0) ||
-	    (addr->s6_addr32[2] == 0 && addr->s6_addr32[3] == 0)))
+		((addr->s6_addr32[2] == htonl(0xFDFFFFFF) &&
+		(addr->s6_addr32[3] | htonl(0x0000007F)) == (u32)~0) ||
+		(addr->s6_addr32[2] == 0 && addr->s6_addr32[3] == 0))) {
 		type = IPV6_ADDR_ANYCAST;
-	else
+	} else
 		type = IPV6_ADDR_UNICAST;
 
-	/* Consider all addresses with the first three bits different of
-	   000 and 111 as finished.
-	 */
-	if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
-	    (st & htonl(0xE0000000)) != htonl(0xE0000000))
-		return type;
-	
-	if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
-		return (IPV6_ADDR_LINKLOCAL | type);
-
-	if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))
-		return (IPV6_ADDR_SITELOCAL | type);
-
-	if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) {
-		if (addr->s6_addr32[2] == 0) {
-			if (addr->in6_u.u6_addr32[3] == 0)
-				return IPV6_ADDR_ANY;
-
-			if (addr->s6_addr32[3] == htonl(0x00000001))
-				return (IPV6_ADDR_LOOPBACK | type);
-
-			return (IPV6_ADDR_COMPATv4 | type);
+	/* check for local-use unicasts */
+	if ((st & htonl(0xE0000000)) == htonl(0xE0000000)) {
+		switch(st & htonl(0xFFC00000)) {
+		case __constant_htonl(0xFE800000):
+			type |= IPV6_ADDR_LINKLOCAL | IPV6_ADDR_SCOPE_LINKLOCAL<<16;
+			break;
+		case __constant_htonl(0xFEC00000):
+			type |= IPV6_ADDR_SITELOCAL | IPV6_ADDR_SCOPE_SITELOCAL<<16;
+			break;
+		default:
+			return IPV6_ADDR_RESERVED | IPV6_ADDR_SCOPE_GLOBAL<<16;
 		}
-
-		if (addr->s6_addr32[2] == htonl(0x0000ffff))
-			return IPV6_ADDR_MAPPED;
+	} else {
+		type |= IPV6_ADDR_SCOPE_GLOBAL<<16;	/* addr-select 3.3 */
 	}
 
-	st &= htonl(0xFF000000);
-	if (st == 0)
-		return IPV6_ADDR_RESERVED;
-	st &= htonl(0xFE000000);
-	if (st == htonl(0x02000000))
-		return IPV6_ADDR_RESERVED;	/* for NSAP */
-	if (st == htonl(0x04000000))
-		return IPV6_ADDR_RESERVED;	/* for IPX */
 	return type;
 }
 
 static void addrconf_del_timer(struct inet6_ifaddr *ifp)
 {
+	ADBG3((KERN_DEBUG
+	       "addrconf_del_timer(ifp=%p)\n",
+	       ifp));
+
 	if (del_timer(&ifp->timer))
 		__in6_ifa_put(ifp);
 }
@@ -236,15 +360,25 @@
 			       enum addrconf_timer_t what,
 			       unsigned long when)
 {
+	ADBG3((KERN_DEBUG
+	       "addrconf_mod_timer(ifp=%p, what=%d, when=%lu): jiffies=%lu\n",
+	       ifp, what, when, jiffies));
+
 	if (!del_timer(&ifp->timer))
 		in6_ifa_hold(ifp);
 
 	switch (what) {
 	case AC_DAD:
 		ifp->timer.function = addrconf_dad_timer;
+		ADBG3((KERN_DEBUG "AC_DAD timer = %d\n", ifp->probes));
 		break;
 	case AC_RS:
 		ifp->timer.function = addrconf_rs_timer;
+		ADBG3((KERN_DEBUG "AC_RS timer = %d\n", ifp->probes));
+
+		/* Check whether entering AC_RS function after receiving RA */
+		if (ifp->idev->if_flags & IF_RA_RCVD)
+			ADBG1((KERN_DEBUG "AC_RS timer is called when IF_RA_RCVD is on.\n"));
 		break;
 	default:;
 	}
@@ -259,14 +393,25 @@
 	struct net_device *dev = idev->dev;
 	BUG_TRAP(idev->addr_list==NULL);
 	BUG_TRAP(idev->mc_list==NULL);
+#ifdef CONFIG_IPV6_PREFIXLIST
+	BUG_TRAP(list_empty(&idev->prefix_list) == 1);
+#endif
 #ifdef NET_REFCNT_DEBUG
-	printk(KERN_DEBUG "in6_dev_finish_destroy: %s\n", dev ? dev->name : "NIL");
+	ADBG3((KERN_DEBUG "in6_dev_finish_destroy: %s\n", dev ? dev->name : "NIL"));
 #endif
 	dev_put(dev);
 	if (!idev->dead) {
-		printk("Freeing alive inet6 device %p\n", idev);
+		ADBG1((KERN_WARNING
+		       "Freeing alive inet6 device %p\n", idev));
 		return;
 	}
+#ifdef CONFIG_PROC_FS
+	if (idev->stats.proc_dir_entry){
+		remove_proc_entry(idev->stats.proc_dir_entry->name, 
+				  proc_net_devsnmp6);
+	}
+#endif
+	ipv6_statistics[0].Ip6LastChange = timeticks(jiffies);
 	inet6_dev_count--;
 	kfree(idev);
 }
@@ -277,16 +422,27 @@
 
 	ASSERT_RTNL();
 
+	ADBG3((KERN_DEBUG
+	       "ipv6_add_dev(dev=%p(%s))\n",
+		dev, dev->name));
+
 	if (dev->mtu < IPV6_MIN_MTU)
 		return NULL;
 
 	ndev = kmalloc(sizeof(struct inet6_dev), GFP_KERNEL);
 
 	if (ndev) {
+#ifdef CONFIG_IPV6_ZONE
+		int i;
+#endif
 		memset(ndev, 0, sizeof(struct inet6_dev));
 
+		INIT_LIST_HEAD(&ndev->prefix_list);
+		ndev->prefix_lock = RW_LOCK_UNLOCKED;
 		ndev->lock = RW_LOCK_UNLOCKED;
 		ndev->dev = dev;
+		ndev->prefix_lock = RW_LOCK_UNLOCKED;
+		INIT_LIST_HEAD(&ndev->prefix_list);
 		memcpy(&ndev->cnf, &ipv6_devconf_dflt, sizeof(ndev->cnf));
 		ndev->cnf.mtu6 = dev->mtu;
 		ndev->cnf.sysctl = NULL;
@@ -295,15 +451,73 @@
 			kfree(ndev);
 			return NULL;
 		}
+
 		inet6_dev_count++;
 		/* We refer to the device */
 		dev_hold(dev);
 
-		write_lock_bh(&addrconf_lock);
-		dev->ip6_ptr = ndev;
+#ifdef CONFIG_IPV6_ZONE
+		memset(&ndev->zone, 0, sizeof(ndev->zone));
+		for (i=0; i<16; i++) {
+			if (
+#ifndef CONFIG_IPV6_ZONE_SITELOCAL
+			    i <= IPV6_ADDR_SCOPE_LINKLOCAL
+#else
+			    i <= IPV6_ADDR_SCOPE_SITELOCAL
+#endif
+			   )
+				ndev->zone.zoneid[i] = dev->ifindex;
+			else
+				ndev->zone.zoneid[i] = 0x0000001;
+		}
+#endif
+
+		if ((dev->flags&IFF_LOOPBACK) ||
+#ifdef CONFIG_NET_IPIP_IPV6
+		    dev->type == ARPHRD_TUNNEL
+#else
+		    dev->type == ARPHRD_SIT
+#endif
+		    ) {
+		}
+
 		/* One reference from device */
 		in6_dev_hold(ndev);
+
+#ifdef CONFIG_IPV6_PRIVACY
+		get_random_bytes(ndev->rndid, sizeof(ndev->rndid));
+		get_random_bytes(ndev->entropy, sizeof(ndev->entropy));
+		init_timer(&ndev->regen_timer);
+		ndev->regen_timer.function = ipv6_regen_rndid;
+		ndev->regen_timer.data = (unsigned long) ndev;
+		if ((dev->flags&IFF_LOOPBACK) ||
+		    dev->type == ARPHRD_TUNNEL ||
+		    dev->type == ARPHRD_SIT) {
+			ADBG2((KERN_DEBUG
+			       "Disabled Privacy Extensions on device %p(%s)\n",
+			       dev, dev->name));
+			ndev->cnf.use_tempaddr = -1;
+		} else {
+			__ipv6_regen_rndid(ndev);
+		}
+#endif
+
+		write_lock_bh(&addrconf_lock);
+		dev->ip6_ptr = ndev;
 		write_unlock_bh(&addrconf_lock);
+		ipv6_statistics[0].Ip6LastChange = timeticks(jiffies);
+		ndev->stats.ipv6[0].Ip6LastChange = timeticks(jiffies);
+
+#ifdef CONFIG_PROC_FS
+		ndev->stats.proc_dir_entry = create_proc_read_entry(dev->name, 0, 
+								    proc_net_devsnmp6, 
+								    afinet6_read_devsnmp, 
+								    ndev);
+		if (!ndev->stats.proc_dir_entry)
+			ADBG1((KERN_WARNING
+			       "addrconf_notify(): cannot create /proc/net/dev_snmp6/%s\n", 
+			       dev->name));
+#endif
 
 		ipv6_mc_init_dev(ndev);
 
@@ -321,6 +535,10 @@
 
 	ASSERT_RTNL();
 
+	ADBG3((KERN_DEBUG
+	       "ipv6_find_idev(dev=%p(%s))\n",
+	       dev, dev->name));
+
 	if ((idev = __in6_dev_get(dev)) == NULL) {
 		if ((idev = ipv6_add_dev(dev)) == NULL)
 			return NULL;
@@ -330,86 +548,72 @@
 	return idev;
 }
 
-void ipv6_addr_prefix(struct in6_addr *prefix,
-	struct in6_addr *addr, int prefix_len)
-{
-	unsigned long mask;
-	int ncopy, nbits;
-
-	memset(prefix, 0, sizeof(*prefix));
-
-	if (prefix_len <= 0)
-		return;
-	if (prefix_len > 128)
-		prefix_len = 128;
-
-	ncopy = prefix_len / 32;
-	switch (ncopy) {
-	case 4:	prefix->s6_addr32[3] = addr->s6_addr32[3];
-	case 3:	prefix->s6_addr32[2] = addr->s6_addr32[2];
-	case 2:	prefix->s6_addr32[1] = addr->s6_addr32[1];
-	case 1:	prefix->s6_addr32[0] = addr->s6_addr32[0];
-	case 0:	break;
-	}
-	nbits = prefix_len % 32;
-	if (nbits == 0)
-		return;
-
-	mask = ~((1 << (32 - nbits)) - 1);
-	mask = htonl(mask);
-
-	prefix->s6_addr32[ncopy] = addr->s6_addr32[ncopy] & mask;
-}
-
-
 static void dev_forward_change(struct inet6_dev *idev)
 {
 	struct net_device *dev;
 	struct inet6_ifaddr *ifa;
 	struct in6_addr addr;
 
-	if (!idev)
+	ADBG3((KERN_DEBUG
+	       "dev_forward_change(idev=%p)\n", idev));
+
+	if (!idev || idev->dead)
 		return;
+
 	dev = idev->dev;
-	if (dev && (dev->flags & IFF_MULTICAST)) {
-		ipv6_addr_all_routers(&addr);
-	
-		if (idev->cnf.forwarding)
-			ipv6_dev_mc_inc(dev, &addr);
-		else
-			ipv6_dev_mc_dec(dev, &addr);
+	if (!dev)
+		return;
+
+	ipv6_addr_all_routers(&addr);
+
+	read_lock(&idev->lock);
+	if (idev->cnf.forwarding) {
+		read_unlock(&idev->lock);
+		ipv6_dev_mc_inc(dev, &addr);	/* XXX: race */
+	} else {
+		read_unlock(&idev->lock);
+		ipv6_dev_mc_dec(dev, &addr);	/* XXX: race */
 	}
+
 	for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
 		ipv6_addr_prefix(&addr, &ifa->addr, ifa->prefix_len);
 		if (ipv6_addr_any(&addr))
 			continue;
-		if (idev->cnf.forwarding)
+		read_lock(&idev->lock);
+		if (idev->cnf.forwarding) {
+			read_unlock(&idev->lock);
 			ipv6_dev_ac_inc(idev->dev, &addr);
-		else
+		} else {
+			read_unlock(&idev->lock);
 			ipv6_dev_ac_dec(idev->dev, &addr);
+		}
 	}
 }
 
-
-static void addrconf_forward_change(struct inet6_dev *idev)
+static void addrconf_forward_change(void)
 {
 	struct net_device *dev;
 
-	if (idev) {
-		dev_forward_change(idev);
-		return;
-	}
+	ADBG3((KERN_DEBUG "addrconf_forward_change()\n"));
 
 	read_lock(&dev_base_lock);
+	read_lock(&addrconf_lock);
 	for (dev=dev_base; dev; dev=dev->next) {
-		read_lock(&addrconf_lock);
-		idev = __in6_dev_get(dev);
+		struct inet6_dev *idev = __in6_dev_get(dev);
 		if (idev) {
-			idev->cnf.forwarding = ipv6_devconf.forwarding;
-			dev_forward_change(idev);
+			int changed = 0;
+			write_lock(&idev->lock);
+			if (!idev->dead) {
+				changed = idev->cnf.forwarding != ipv6_devconf.forwarding;
+				idev->cnf.forwarding = ipv6_devconf.forwarding;
+			}
+			write_unlock(&idev->lock);
+			if (changed)
+				dev_forward_change(idev);
 		}
-		read_unlock(&addrconf_lock);
 	}
+	ipv6_devconf_dflt.forwarding = ipv6_devconf.forwarding;
+	read_unlock(&addrconf_lock);
 	read_unlock(&dev_base_lock);
 }
 
@@ -418,19 +622,25 @@
 
 void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
 {
+	ADBG3((KERN_DEBUG
+	       "inet6_ifa_finish_destroy(ifp=%p)\n",
+	       ifp));
+
 	BUG_TRAP(ifp->if_next==NULL);
 	BUG_TRAP(ifp->lst_next==NULL);
 #ifdef NET_REFCNT_DEBUG
-	printk(KERN_DEBUG "inet6_ifa_finish_destroy\n");
+	ADBG3((KERN_DEBUG "inet6_ifa_finish_destroy\n"));
 #endif
 
 	in6_dev_put(ifp->idev);
 
 	if (del_timer(&ifp->timer))
-		printk("Timer is still running, when freeing ifa=%p\n", ifp);
+		ADBG1((KERN_WARNING
+		       "Timer is still running, when freeing ifa=%p\n", ifp));
 
 	if (!ifp->dead) {
-		printk("Freeing alive inet6 address %p\n", ifp);
+		ADBG1((KERN_WARNING
+		       "Freeing alive inet6 address %p\n", ifp));
 		return;
 	}
 	inet6_ifa_count--;
@@ -446,6 +656,14 @@
 	struct inet6_ifaddr *ifa;
 	int hash;
 	static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+	char abuf[128];
+
+	in6_ntop(addr, abuf);
+	ADBG3((KERN_DEBUG
+	       "ipv6_add_addr(idev=%p, addr=%s, pfxlen=%d, scope=%d, flags=%08X)\n",
+		idev, abuf, pfxlen, scope, flags));
+#endif
 
 	spin_lock_bh(&lock);
 
@@ -460,8 +678,9 @@
 
 	if (ifa == NULL) {
 		spin_unlock_bh(&lock);
-		ADBG(("ipv6_add_addr: malloc failed\n"));
-		return ERR_PTR(-ENOBUFS);
+		ADBG1((KERN_WARNING
+		       "ipv6_add_addr: malloc failed\n"));
+		return NULL;
 	}
 
 	memset(ifa, 0, sizeof(struct inet6_ifaddr));
@@ -502,6 +721,16 @@
 	ifa->if_next = idev->addr_list;
 	idev->addr_list = ifa;
 	in6_ifa_hold(ifa);
+#ifdef CONFIG_IPV6_PRIVACY
+	ifa->regen_count = 0;
+	if (ifa->flags&IFA_F_TEMPORARY) {
+		ifa->tmp_next = idev->tempaddr_list;
+		idev->tempaddr_list = ifa;
+		in6_ifa_hold(ifa);
+	} else {
+		ifa->tmp_next = NULL;
+	}
+#endif
 	write_unlock_bh(&idev->lock);
 	read_unlock(&addrconf_lock);
 	spin_unlock_bh(&lock);
@@ -519,10 +748,22 @@
 	struct inet6_dev *idev = ifp->idev;
 	int hash;
 
-	hash = ipv6_addr_hash(&ifp->addr);
+	ADBG3((KERN_DEBUG
+	       "ipv6_del_addr(ifp=%p)\n", ifp));
 
 	ifp->dead = 1;
 
+#ifdef CONFIG_IPV6_PRIVACY
+	spin_lock_bh(&ifp->lock);
+	if (ifp->ifpub) {
+		__in6_ifa_put(ifp->ifpub);
+		ifp->ifpub = NULL;
+	}
+	spin_unlock_bh(&ifp->lock);
+#endif
+
+	hash = ipv6_addr_hash(&ifp->addr);
+
 	write_lock_bh(&addrconf_hash_lock);
 	for (ifap = &inet6_addr_lst[hash]; (ifa=*ifap) != NULL;
 	     ifap = &ifa->lst_next) {
@@ -536,6 +777,23 @@
 	write_unlock_bh(&addrconf_hash_lock);
 
 	write_lock_bh(&idev->lock);
+#ifdef CONFIG_IPV6_PRIVACY
+	if (ifp->flags&IFA_F_TEMPORARY) {
+		for (ifap = &idev->tempaddr_list; (ifa=*ifap) != NULL;
+		     ifap = &ifa->tmp_next) {
+			if (ifa == ifp) {
+				*ifap = ifa->tmp_next;
+				if (ifp->ifpub) {
+					__in6_ifa_put(ifp->ifpub);
+					ifp->ifpub = NULL;
+				}
+				__in6_ifa_put(ifp);
+				ifa->tmp_next = NULL;
+				break;
+			}
+		}
+	}
+#endif
 	for (ifap = &idev->addr_list; (ifa=*ifap) != NULL;
 	     ifap = &ifa->if_next) {
 		if (ifa == ifp) {
@@ -545,6 +803,9 @@
 			break;
 		}
 	}
+
+	/* XXX: if ifp is public, also delete tmporary adddress */
+
 	write_unlock_bh(&idev->lock);
 
 	ipv6_ifa_notify(RTM_DELADDR, ifp);
@@ -556,136 +817,482 @@
 	in6_ifa_put(ifp);
 }
 
-/*
- *	Choose an apropriate source address
- *	should do:
- *	i)	get an address with an apropriate scope
- *	ii)	see if there is a specific route for the destination and use
- *		an address of the attached interface 
- *	iii)	don't use deprecated addresses
- */
-int ipv6_dev_get_saddr(struct net_device *dev,
-		   struct in6_addr *daddr, struct in6_addr *saddr, int onlink)
+#ifdef CONFIG_IPV6_PRIVACY
+static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *ift)
 {
-	struct inet6_ifaddr *ifp = NULL;
-	struct inet6_ifaddr *match = NULL;
 	struct inet6_dev *idev;
-	int scope;
-	int err;
-
-
-	if (!onlink)
-		scope = ipv6_addr_scope(daddr);
-	else
-		scope = IFA_LINK;
-
-	/*
-	 *	known dev
-	 *	search dev and walk through dev addresses
-	 */
-
-	if (dev) {
-		if (dev->flags & IFF_LOOPBACK)
-			scope = IFA_HOST;
-
-		read_lock(&addrconf_lock);
-		idev = __in6_dev_get(dev);
-		if (idev) {
-			read_lock_bh(&idev->lock);
-			for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) {
-				if (ifp->scope == scope) {
-					if (!(ifp->flags & (IFA_F_DEPRECATED|IFA_F_TENTATIVE))) {
-						in6_ifa_hold(ifp);
-						read_unlock_bh(&idev->lock);
-						read_unlock(&addrconf_lock);
-						goto out;
-					}
-
-					if (!match && !(ifp->flags & IFA_F_TENTATIVE)) {
-						match = ifp;
-						in6_ifa_hold(ifp);
-					}
-				}
-			}
-			read_unlock_bh(&idev->lock);
-		}
-		read_unlock(&addrconf_lock);
+	struct in6_addr addr, *tmpaddr;
+	unsigned long tmp_prefered_lft, tmp_valid_lft;
+	int tmp_plen;
+	int ret = 0;
+	int max_addresses;
+
+	ADBG3((KERN_DEBUG
+	       "ipv6_create_tempaddr(ifp=%p, ift=%p)\n", 
+	       ifp, ift));
+
+	if (ift) {
+		spin_lock_bh(&ift->lock);
+		memcpy(&addr.s6_addr[8], &ift->addr.s6_addr[8], 8);
+		spin_unlock_bh(&ift->lock);
+		tmpaddr = &addr;
+	} else {
+		tmpaddr = NULL;
 	}
-
-	if (scope == IFA_LINK)
+retry:
+	spin_lock_bh(&ifp->lock);
+	in6_ifa_hold(ifp);
+	idev = ifp->idev;
+	in6_dev_hold(idev);
+	memcpy(addr.s6_addr, ifp->addr.s6_addr, 8);
+	write_lock(&idev->lock);
+	if (idev->cnf.use_tempaddr <= 0) {
+		write_unlock(&idev->lock);
+		spin_unlock_bh(&ifp->lock);
+		ADBG2((KERN_INFO
+		       "ipv6_create_tempaddr(): use_tempaddr is disabled.\n"));
+		in6_dev_put(idev);
+		in6_ifa_put(ifp);
+		ret = -1;
 		goto out;
-
-	/*
-	 *	dev == NULL or search failed for specified dev
-	 */
-
-	read_lock(&dev_base_lock);
-	read_lock(&addrconf_lock);
-	for (dev = dev_base; dev; dev=dev->next) {
-		idev = __in6_dev_get(dev);
-		if (idev) {
-			read_lock_bh(&idev->lock);
-			for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) {
-				if (ifp->scope == scope) {
-					if (!(ifp->flags&(IFA_F_DEPRECATED|IFA_F_TENTATIVE))) {
-						in6_ifa_hold(ifp);
-						read_unlock_bh(&idev->lock);
-						goto out_unlock_base;
-					}
-
-					if (!match && !(ifp->flags&IFA_F_TENTATIVE)) {
-						match = ifp;
-						in6_ifa_hold(ifp);
-					}
-				}
-			}
-			read_unlock_bh(&idev->lock);
-		}
 	}
-
-out_unlock_base:
-	read_unlock(&addrconf_lock);
-	read_unlock(&dev_base_lock);
-
-out:
-	if (ifp == NULL) {
-		ifp = match;
-		match = NULL;
+	if (ifp->regen_count++ >= idev->cnf.regen_max_retry) {
+		idev->cnf.use_tempaddr = -1;	/*XXX*/
+		write_unlock(&idev->lock);
+		spin_unlock_bh(&ifp->lock);
+		ADBG1((KERN_WARNING
+		       "ipv6_create_tempaddr(): regeneration time exceeded. disabled temporary address support.\n"));
+		in6_dev_put(idev);
+		in6_ifa_put(ifp);
+		ret = -1;
+		goto out;
 	}
-
-	err = -EADDRNOTAVAIL;
-	if (ifp) {
-		ipv6_addr_copy(saddr, &ifp->addr);
-		err = 0;
+	if (__ipv6_try_regen_rndid(idev, tmpaddr) < 0) {
+		write_unlock(&idev->lock);
+		spin_unlock_bh(&ifp->lock);
+		ADBG1((KERN_WARNING
+		       "ipv6_create_tempaddr(): regeneration of randomized interface id failed.\n"));
+		in6_dev_put(idev);
 		in6_ifa_put(ifp);
+		ret = -1;
+		goto out;
 	}
-	if (match)
-		in6_ifa_put(match);
-
-	return err;
+	memcpy(&addr.s6_addr[8], idev->rndid, 8);
+	tmp_valid_lft = min_t(__u32,
+			      ifp->valid_lft,
+			      idev->cnf.temp_valid_lft);
+	tmp_prefered_lft = min_t(__u32, 
+				 ifp->prefered_lft, 
+				 idev->cnf.temp_prefered_lft - desync_factor / HZ);
+	tmp_plen = ifp->prefix_len;
+	max_addresses = idev->cnf.max_addresses;
+	write_unlock(&idev->lock);
+	spin_unlock_bh(&ifp->lock);
+	ift = !max_addresses ||
+	      ipv6_count_addresses(idev) < max_addresses ?
+		ipv6_add_addr(idev, &addr, tmp_plen,
+			      ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, IFA_F_TEMPORARY) : 0;
+	if (!ift) {
+		in6_dev_put(idev);
+		in6_ifa_put(ifp);
+		ADBG2((KERN_WARNING
+		       "ipv6_create_tempaddr(): retry temporary address regeneration.\n"));
+		tmpaddr = &addr;
+		goto retry;
+	}
+	spin_lock_bh(&ift->lock);
+	ift->ifpub = ifp;
+	ift->valid_lft = tmp_valid_lft;
+	ift->prefered_lft = tmp_prefered_lft;
+	ift->tstamp = ifp->tstamp;
+	spin_unlock_bh(&ift->lock);
+	addrconf_dad_start(ift, RTF_ADDRCONF|RTF_PREFIX_RT);
+	in6_ifa_put(ift);
+	in6_dev_put(idev);
+out:
+	return ret;
 }
 
+#endif
 
-int ipv6_get_saddr(struct dst_entry *dst,
-		   struct in6_addr *daddr, struct in6_addr *saddr)
+int ipv6_get_prefix_entries(struct prefix_info **plist, int ifindex, int plen)
 {
-	struct rt6_info *rt;
-	struct net_device *dev = NULL;
-	int onlink;
+	int count;
+	struct net_device *dev;
+	struct inet6_dev *idev;
+	struct list_head *head;
+	struct prefix_element *p;
 
-	rt = (struct rt6_info *) dst;
-	if (rt)
-		dev = rt->rt6i_dev;
+	if (plist == NULL) {
+		BUG_TRAP(plist != NULL);
+		return -EINVAL;
+	}
+	if ((dev = dev_get_by_index(ifindex)) == NULL) {
+		printk(KERN_WARNING "Bad I/F (%d) in ipv6_get_prefix_entries\n",
+		       ifindex);
+		return -EINVAL;
+	}
 
-	onlink = (rt && (rt->rt6i_flags & RTF_ALLONLINK));
+	if ((idev = __in6_dev_get(dev)) == NULL) {
+		dev_put(dev);
+		return -EINVAL;
+	}
 
-	return ipv6_dev_get_saddr(dev, daddr, saddr, onlink);
+	read_lock_bh(&idev->lock);
+	if (!(count = idev->prefix_count)) {
+		/* No elements on list */
+		goto out;
+	}
+	if ((*plist = kmalloc(count * sizeof(struct prefix_info),
+			      GFP_ATOMIC)) == NULL) {
+		count = -ENOMEM;
+		goto out;
+	}
+	count = 0;
+	spin_lock_bh(&idev->prefix_lock);
+	list_for_each(head, &idev->prefix_list) {
+		p = list_entry(head, struct prefix_element, list);
+		if (plen == 0 || p->pinfo.prefix_len == plen) {
+			memcpy(*plist + count, &p->pinfo,
+			       sizeof(struct prefix_info));
+			count++;
+		}
+	}
+	spin_unlock_bh(&idev->prefix_lock);
+ out:
+	read_unlock_bh(&idev->lock);
+	dev_put(dev);
+	return count;
 }
 
+/*
+ *	Choose an appropriate source address
+ *	draft-ietf-ipv6-default-addr-select-09.txt
+ */
+#define IPV6_SADDRSELECT_SELF		0x01
+#define IPV6_SADDRSELECT_PREFERRED	0x02
+#define IPV6_SADDRSELECT_HOME		0x04
+#define IPV6_SADDRSELECT_PUBLIC		0x08
+#define IPV6_SADDRSELECT_INTERFACE	0x10
+#define IPV6_SADDRSELECT_LABEL		0x20
 
-int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr)
+struct addrselect_attrs {
+	struct inet6_ifaddr *ifp;
+	u16	flags;
+	s16	matchlen;
+	u8	scope;
+};
+
+static int __inline__ ipv6_addrselect_preferred(int type)
 {
-	struct inet6_dev *idev;
+#if 0
+	if (type == IPV6_ADDR_ANY)
+		return -1;
+#endif
+	/* section 3.3, 3.4 */
+	if (type&(IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|
+		  IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED))
+		return 1;
+	return 0;
+}
+
+int ipv6_dev_get_saddr(struct net_device *daddr_dev,
+		       struct in6_addr *daddr, struct in6_addr *saddr,
+		       int pref_privacy)
+{
+	int daddr_type, daddr_scope;
+	u32 daddr_label;
+	struct inet6_ifaddr *ifp0, *ifp = NULL;
+	struct net_device *dev;
+	struct inet6_dev *idev;
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+	char daddrbuf[128];
+	char saddrbuf[128];
+#endif
+
+	int err;
+	int update;
+	struct addrselect_attrs candidate = {NULL,0,0,0};
+#if defined(CONFIG_IPV6_PRIVACY)
+	u16 invpref = 0;
+#endif
+
+#ifdef CONFIG_IPV6_PRIVACY
+	if (pref_privacy > 0 ||
+	    (pref_privacy == 0 && ipv6_devconf.use_tempaddr > 1))
+		invpref |= IPV6_SADDRSELECT_PUBLIC;
+#endif
+
+	daddr_type = __ipv6_addr_type(daddr);
+	daddr_scope = __ipv6_addr_src_scope(daddr_type);
+	daddr_label = ipv6_addrselect_label_lookup(daddr, daddr_dev?daddr_dev->ifindex:0);
+
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+	in6_ntop(daddr, daddrbuf);
+	ADBG3((KERN_DEBUG 
+	       "ipv6_dev_get_saddr(daddr_dev=%p(%s), daddr=%s, saddr=%p, pref_privacy=%d)\n", 
+	       daddr_dev, daddr_dev ? daddr_dev->name : "<null>", 
+	       daddrbuf, saddr, pref_privacy));
+#endif
+
+	read_lock(&dev_base_lock);
+	read_lock(&addrconf_lock);
+	for (dev = dev_base; dev; dev=dev->next) {
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+		ADBG3((KERN_DEBUG 
+		       "ipv6_dev_get_saddr():  dev=%p(%s)\n", dev, dev->name));
+#endif
+
+		/* Rule 0: Candidate Source Address (section 4)
+		 *  - multicast and link-local destination address,
+		 *    the set of candidate source address MUST only
+		 *    include addresses assigned to interfaces
+		 *    belonging to the same link as the outgoing
+		 *    interface.
+		 * (- For site-local destination addresses, the 
+		 *    set of candidate source addresses MUST only
+		 *    include addresses assigned to interfaces 
+		 *    belonging to the same site as the outgoing 
+		 *    interface.)
+		 */
+		if ((daddr_type&IPV6_ADDR_MULTICAST ||
+		     daddr_scope <= IPV6_ADDR_SCOPE_LINKLOCAL) &&
+		    daddr_dev && dev != daddr_dev)
+			continue;
+
+		idev = __in6_dev_get(dev);
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+		ADBG3((KERN_DEBUG
+		       "ipv6_dev_get_saddr():  idev=%p\n", idev));
+#endif
+		if (!idev)
+			continue;
+
+		read_lock_bh(&idev->lock);
+		ifp0 = idev->addr_list;
+		for (ifp=ifp0; ifp; ifp=ifp->if_next) {
+			struct addrselect_attrs temp = {NULL,0,0,0};
+			int addr_type;
+			update = 0;
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+			in6_ntop(&ifp->addr, saddrbuf);
+			ADBG3((KERN_DEBUG
+			       "ipv6_dev_get_saddr():   ifp=%p(ifp->addr=%s)\n", ifp, saddrbuf));
+#endif
+
+			/* Rule 0: Candidate Source Address (section 4)
+			 *  - In any case, anycast addresses, multicast
+			 *    addresses, and the unspecified address MUST
+			 *    NOT be included in a candidate set.
+			 */
+			addr_type = __ipv6_addr_type(&ifp->addr);
+			if (addr_type == IPV6_ADDR_ANY ||
+			    addr_type&IPV6_ADDR_MULTICAST)
+				continue;
+
+			/* Rule 1: Prefer same address */
+			if (ipv6_addr_cmp(&ifp->addr, daddr) == 0)
+				temp.flags |= IPV6_SADDRSELECT_SELF;
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+				ADBG3((KERN_DEBUG
+				       "ipv6_dev_get_saddr():    update=%d, Rule 1: %d vs %d\n",
+				       update,
+				       temp.flags&IPV6_SADDRSELECT_SELF?1:0,
+				       candidate.flags&IPV6_SADDRSELECT_SELF?1:0));
+#endif
+			if ((temp.flags^candidate.flags)&IPV6_SADDRSELECT_SELF) {
+				update = temp.flags&IPV6_SADDRSELECT_SELF;
+				if (!update) {
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+					ADBG3((KERN_DEBUG
+					       "ipv6_dev_get_saddr():    lose at Rule 1\n"));
+#endif
+					continue;
+				}
+			}
+
+			/* Rule 2: Prefer appropriate scope */
+			temp.scope = __ipv6_addr_src_scope(addr_type);
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+			ADBG3((KERN_DEBUG
+			       "ipv6_dev_get_saddr():    update=%d, Rule 2: %u vs %u\n",
+			       update,
+			       temp.scope, candidate.scope));
+#endif
+			if (!update) {
+				update = temp.scope - candidate.scope;
+				if (update > 0) {
+					update = candidate.scope < daddr_scope ? 1 : -1;
+				} else if (update < 0) {
+					update = temp.scope < daddr_scope ? -1 : 1;
+				}
+				if (update < 0) {
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+					ADBG3((KERN_DEBUG
+					       "ipv6_dev_get_saddr():    lose at Rule 2\n"));
+#endif
+					continue;
+				}
+			}
+
+			/* Rule 3: Avoid deprecated address */
+			if (ipv6_addrselect_preferred(addr_type) ||
+			    !(ifp->flags & IFA_F_DEPRECATED))
+				temp.flags |= IPV6_SADDRSELECT_PREFERRED;
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+			ADBG3((KERN_DEBUG
+			       "ipv6_dev_get_saddr():    update=%d, Rule 3: %d vs %d\n",
+			       update,
+			       temp.flags&IPV6_SADDRSELECT_PREFERRED?1:0,
+			       candidate.flags&IPV6_SADDRSELECT_PREFERRED?1:0));
+#endif
+			if (!update && (temp.flags^candidate.flags)&IPV6_SADDRSELECT_PREFERRED) {
+				update = temp.flags&IPV6_SADDRSELECT_PREFERRED;
+				if (!update) {
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+					ADBG3((KERN_DEBUG
+					       "ipv6_dev_get_saddr():    lose at Rule 3\n"));
+#endif
+					continue;
+				}
+			}
+
+			/* XXX: Rule 4: Prefer home address */
+
+			/* Rule 5: Prefer outgoing interface */
+			if (daddr_dev == NULL || daddr_dev == dev)
+				temp.flags |= IPV6_SADDRSELECT_INTERFACE;
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+			ADBG3((KERN_DEBUG
+			       "ipv6_dev_get_saddr():    update=%d, Rule 5: %d vs %d\n",
+			       update,
+			       temp.flags&IPV6_SADDRSELECT_INTERFACE?1:0,
+			       candidate.flags&IPV6_SADDRSELECT_INTERFACE?1:0));
+#endif
+			if (!update && (temp.flags^candidate.flags)&IPV6_SADDRSELECT_INTERFACE) {
+				update = temp.flags&IPV6_SADDRSELECT_INTERFACE;
+				if (!update) {
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+					ADBG3((KERN_DEBUG
+					       "ipv6_dev_get_saddr():    lose at Rule 5\n"));
+#endif
+					continue;
+				}
+			}
+
+			/* Rule 6: Prefer matching label */
+			if (ipv6_addrselect_label_lookup(&ifp->addr, dev->ifindex) == daddr_label)
+				temp.flags |= IPV6_SADDRSELECT_LABEL;
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+			ADBG3((KERN_DEBUG
+			       "ipv6_dev_get_saddr():    update=%d, Rule 6: %d vs %d\n",
+				update,
+				temp.flags&IPV6_SADDRSELECT_LABEL?1:0,
+				candidate.flags&IPV6_SADDRSELECT_LABEL?1:0));
+#endif
+			if (!update && (temp.flags^candidate.flags)&IPV6_SADDRSELECT_LABEL) {
+				update = temp.flags&IPV6_SADDRSELECT_LABEL;
+				if (!update) {
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+					ADBG3((KERN_DEBUG
+					       "ipv6_dev_get_saddr():    lose at Rule 6\n"));
+#endif
+					continue;
+				}
+			}
+
+			/* Rule 7: Prefer public address */
+#ifdef CONFIG_IPV6_PRIVACY
+			if (!(ifp->flags & IFA_F_TEMPORARY))
+				temp.flags |= IPV6_SADDRSELECT_PUBLIC;
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+			ADBG3((KERN_DEBUG
+			       "ipv6_dev_get_saddr():    update=%d, Rule 7: %d vs %d\n",
+				update,
+				temp.flags&IPV6_SADDRSELECT_PUBLIC?1:0,
+				candidate.flags&IPV6_SADDRSELECT_PUBLIC?1:0));
+#endif
+			if (!update && (temp.flags^candidate.flags)&IPV6_SADDRSELECT_PUBLIC) {
+				update = (temp.flags^invpref)&IPV6_SADDRSELECT_PUBLIC;
+				if (!update) {
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+					ADBG3((KERN_DEBUG
+					       "ipv6_dev_get_saddr():    lose at Rule 7\n"));
+#endif
+					continue;
+				}
+			}
+#endif
+
+			/* Rule 8: Use longest matching prefix */
+			temp.matchlen = ipv6_addr_diff(&ifp->addr, daddr);
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+			ADBG3((KERN_DEBUG
+			       "ipv6_dev_get_saddr():    update=%d, Rule 8: %d vs %d\n",
+				update,
+				temp.matchlen,candidate.matchlen));
+#endif
+			if (!update) {
+				update = temp.matchlen - candidate.matchlen;
+				if (update < 0) {
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+					ADBG3((KERN_DEBUG
+					       "ipv6_dev_get_saddr():    lose at Rule 8\n"));
+#endif
+					continue;
+				}
+			}
+
+			/* Final Rule */
+			if (!update && candidate.ifp) {
+				ADBG3((KERN_DEBUG
+				       "ipv6_dev_get_saddr():    candidate already exists\n"));
+				continue;
+			}
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+			ADBG3((KERN_DEBUG
+			       "ipv6_dev_get_saddr():    update=%d, candidate updated; %s\n", 
+			       update,
+			       saddrbuf));
+#endif
+
+			/* update candidate */
+			temp.ifp = ifp;
+			in6_ifa_hold(ifp);
+			if (candidate.ifp)
+				in6_ifa_put(candidate.ifp);
+			candidate = temp;
+		}
+		read_unlock_bh(&idev->lock);
+	}
+	read_unlock(&addrconf_lock);
+	read_unlock(&dev_base_lock);
+
+	if (candidate.ifp) {
+		ipv6_addr_copy(saddr, &candidate.ifp->addr);
+		in6_ifa_put(candidate.ifp);
+		err = 0;
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+		in6_ntop(saddr, saddrbuf);
+		ADBG3((KERN_DEBUG "ipv6_dev_get_saddr(): %s is selected\n", saddrbuf));
+#endif
+	} else {
+		err = -EADDRNOTAVAIL;
+	}
+	return err;
+}
+
+int ipv6_get_saddr(struct dst_entry *dst,
+		   struct in6_addr *daddr, struct in6_addr *saddr,
+		   int pref_privacy)
+{
+	return ipv6_dev_get_saddr(dst ? ((struct rt6_info *)dst)->rt6i_dev : NULL,
+				  daddr, saddr, pref_privacy);
+}
+
+int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr)
+{
+	struct inet6_dev *idev;
 	int err = -EADDRNOTAVAIL;
 
 	read_lock(&addrconf_lock);
@@ -706,14 +1313,22 @@
 	return err;
 }
 
-int ipv6_count_addresses(struct inet6_dev *idev)
+static int __ipv6_count_addresses(struct inet6_dev *idev)
 {
 	int cnt = 0;
 	struct inet6_ifaddr *ifp;
 
-	read_lock_bh(&idev->lock);
 	for (ifp=idev->addr_list; ifp; ifp=ifp->if_next)
 		cnt++;
+	return cnt;
+}
+
+int ipv6_count_addresses(struct inet6_dev *idev)
+{
+	int cnt;
+
+	read_lock_bh(&idev->lock);
+	cnt = __ipv6_count_addresses(idev);
 	read_unlock_bh(&idev->lock);
 	return cnt;
 }
@@ -761,10 +1376,11 @@
 	read_lock_bh(&addrconf_hash_lock);
 	for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) {
 		if (ipv6_addr_cmp(&ifp->addr, addr) == 0) {
-			if (dev == NULL || ifp->idev->dev == dev ||
-			    !(ifp->scope&(IFA_LINK|IFA_HOST))) {
-				in6_ifa_hold(ifp);
-				break;
+			if (dev == NULL || ifp->idev->dev == dev) {
+				if (!(ifp->scope&IFA_HOST)) {
+					in6_ifa_hold(ifp);
+					break;
+				}
 			}
 		}
 	}
@@ -773,20 +1389,291 @@
 	return ifp;
 }
 
+/* address selection: policy label */
+/* default policy table in rfc 3484 */
+int ipv6_addrselect_add_label(int ifindex, struct in6_addr *addr, int plen, int label)
+{
+	struct ipv6_addrselect_label *p, *p_last;
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+	char abuf[128];
+
+	in6_ntop(addr, abuf);
+	ADBG3((KERN_DEBUG
+	       "ipv6_addrselect_add_label(ifindex=%d, addr=%s, plen=%d, label=%d)\n",
+	       ifindex, abuf, plen, label));
+#endif
+
+	/* Update label on duplicate addresses */
+	write_lock_bh(&addrselect_label_lock);
+	p_last = ipv6_addrselect_label_table;
+	for (p = ipv6_addrselect_label_table;
+	     p;
+	     p = p->next) {
+		if (!ipv6_prefix_cmp(addr, &p->addr, p->plen) && plen == p->plen) {
+			p->ifindex = ifindex;
+			p->label = label;
+			write_unlock_bh(&addrselect_label_lock);
+			return 0;
+		}
+		p_last = p;
+	}
+
+	p = kmalloc(sizeof(struct ipv6_addrselect_label), GFP_KERNEL);
+	if (p == NULL) {
+		ADBG1((KERN_WARNING
+		       "ipv6_addrselect_add_label: malloc failed\n"));
+		write_unlock_bh(&addrselect_label_lock);
+		return -ENOMEM;
+	}
+
+	memset(p, 0, sizeof(struct ipv6_addrselect_label));
+
+	if (!ipv6_addrselect_label_table) 
+		ipv6_addrselect_label_table = p;
+	else 
+        	p_last->next = p;
+	p->addr = *addr;
+	p->plen = plen;
+	p->ifindex = ifindex;
+	p->label = label;
+	write_unlock_bh(&addrselect_label_lock);
+	return 0;
+}
+
+int ipv6_addrselect_del_label(struct in6_addr *addr, int plen)
+{
+	struct ipv6_addrselect_label *p, *p_last;
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+	char abuf[128];
+
+	in6_ntop(addr, abuf);
+	ADBG3((KERN_DEBUG
+	       "ipv6_addrselect_del_label(addr=%s, plen=%d)\n",
+	       abuf, plen));
+#endif
+
+	write_lock_bh(&addrselect_label_lock);
+	p_last = ipv6_addrselect_label_table;
+	for (p = ipv6_addrselect_label_table;
+	     p;
+	     p = p->next) {
+		if (!ipv6_prefix_cmp(addr, &p->addr, p->plen) && plen == p->plen) {
+
+ 			if (ipv6_addrselect_label_table == p) {
+ 				ipv6_addrselect_label_table = p->next;
+ 			} else {
+				p_last->next = p->next;
+ 			}
+			kfree(p);
+			write_unlock_bh(&addrselect_label_lock);
+			return 0;
+		}
+		p_last = p;
+	}
+	write_unlock_bh(&addrselect_label_lock);
+	return -ENOENT;
+}
+
+int addrconf_label_ioctl(unsigned int cmd, void *arg)
+{
+	struct in6_addrlabelreq req;
+	int err = -EINVAL;
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+	switch(cmd) {
+	case SIOCSDADDRLABEL:
+		err = copy_from_user(&req, arg, sizeof(struct in6_addrlabelreq));
+		if (err)
+			return -EFAULT;
+		err = ipv6_addrselect_add_label(req.ifindex, &req.addr, req.plen, req.label);
+		break;
+
+	case SIOCDDADDRLABEL:
+		err = copy_from_user(&req, arg, sizeof(struct in6_addrlabelreq));
+		if (err)
+			return -EFAULT;
+		err = ipv6_addrselect_del_label(&req.addr, req.plen);
+		break;
+	}
+	return err;
+}
+
+static u32 ipv6_addrselect_label_lookup(const struct in6_addr *addr, int ifindex)
+{
+	struct ipv6_addrselect_label *p;
+	int plen, matchlen = -1;
+	u32 label = 0xffffffff;
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+	char buf[64];
+
+	in6_ntop(addr, buf);
+	ADBG3((KERN_DEBUG
+	       "ipv6_addrselect_label_lookup(addr=%s, ifindex=%d)\n",
+	       buf, ifindex));
+#endif
+	
+	read_lock_bh(&addrselect_label_lock);
+	for (p = ipv6_addrselect_label_table;
+	     p;
+	     p = p->next) {
+		if (ifindex && p->ifindex && ifindex != p->ifindex)
+			continue;
+		plen = ipv6_addr_diff(addr, &p->addr);
+		if (plen < p->plen || plen < matchlen)
+			continue;
+		matchlen = plen;
+		label = p->label;
+	}
+#ifdef CONFIG_IPV6_ACONF_DEBUG_SADDR
+	ADBG3((KERN_DEBUG
+	       "ipv6_addrselect_label_lookup() = %u\n",
+	       label));
+#endif
+	read_unlock_bh(&addrselect_label_lock);
+	return label;
+}
+
+
+static struct ipv6_addrselect_label ipv6_addrselect_label_init_table[] = {
+	/* prefix = ::1/128, label = 0 */
+	{
+		addr:	{{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}},
+		plen:	128,
+		label:	0,
+	},
+	/* prefix = ::/0, label = 1 */
+	{
+		label:	1,
+	},
+	/* prefix = 2002::/16, label = 2 */
+	{
+		addr:	{{{ 0x20,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}},
+		plen:	16,
+		label:	2,
+	},
+	/* prefix = ::/96, label = 3 */
+	{
+		plen:	96,
+		label:	3,
+	},
+	/* prefix = ::ffff:0:0/96, label = 4 */
+	{
+		addr:	{{{ 0,0,0,0,0,0,0,0,0,0xff,0xff,0,0,0,0 }}},
+		plen:	96,
+		label:	4,
+	},
+	/* sentinel */
+	{
+		label:	0xffffffff,
+	}
+};
+
+void ipv6_addrselect_init(void)
+{
+	struct ipv6_addrselect_label **pnext, *p0;
+	
+	for (p0 = ipv6_addrselect_label_init_table,
+	     pnext = &ipv6_addrselect_label_table;
+	     p0->label != 0xffffffff;
+	     p0++,
+	     pnext = &(*pnext)->next) {
+		*pnext = kmalloc(sizeof(**pnext), GFP_ATOMIC);
+		if (*pnext == NULL) {
+			printk(KERN_WARNING
+				"%s(): failed to allocate memory\n",
+				__FUNCTION__);
+			break;
+		}
+		memcpy(*pnext, p0, sizeof(**pnext));
+	}
+};
+
+#ifdef CONFIG_PROC_FS
+static int ipv6_addrselect_label_proc_info(char *buffer, char **start, off_t offset,
+					   int length)
+{
+	struct ipv6_addrselect_label *p;
+	int len = 0;
+	off_t pos = 0;
+	off_t begin = 0;
+
+	read_lock_bh(&addrselect_label_lock);
+	for (p = ipv6_addrselect_label_table;
+	     p;
+	     p = p->next) {
+		int i;
+		for (i = 0; i < 16; i++) {
+		    sprintf(buffer + len, "%02x", p->addr.s6_addr[i]);
+		    len += 2;
+		}
+
+		len += sprintf(buffer + len,
+			   " %02x %02x %02x\n",
+			   p->plen,
+			   p->ifindex,
+			   p->label);
+		pos = begin + len;
+		if (pos < offset) {
+		        len = 0;
+		        begin = pos;
+		}
+		if(pos > offset + length) {
+		        read_unlock_bh(&addrselect_label_lock);
+		        goto done;
+		}                
+	}
+	read_unlock_bh(&addrselect_label_lock);
+
+ done:
+	*start = buffer + (offset - begin);
+	len -= (offset - begin);
+	if (len > length)
+		len = length;
+	if (len < 0)
+		len = 0;
+	return len;
+}
+#endif  /* CONFIG_PROC_FS */
+
+
 /* Gets referenced address, destroys ifaddr */
 
 void addrconf_dad_failure(struct inet6_ifaddr *ifp)
 {
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+	ADBG3((KERN_DEBUG
+	       "addrconf_dad_failure(ifp=%p): jiffies=%lu\n",
+	       ifp, jiffies));
+#endif
 	if (net_ratelimit())
-		printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name);
+		ADBG1((KERN_WARNING 
+		       "%s: duplicate address detected!\n", 
+		       ifp->idev->dev->name));
+	spin_lock_bh(&ifp->lock);
 	if (ifp->flags&IFA_F_PERMANENT) {
-		spin_lock_bh(&ifp->lock);
 		addrconf_del_timer(ifp);
 		ifp->flags |= IFA_F_TENTATIVE;
 		spin_unlock_bh(&ifp->lock);
 		in6_ifa_put(ifp);
-	} else
+#ifdef CONFIG_IPV6_PRIVACY
+	} else if (ifp->flags&IFA_F_TEMPORARY) {
+		struct inet6_ifaddr *ifpub;
+		ifpub = ifp->ifpub;
+		if (ifpub) {
+			in6_ifa_hold(ifpub);
+			spin_unlock_bh(&ifp->lock);
+			ipv6_create_tempaddr(ifpub, ifp);
+			in6_ifa_put(ifpub);
+		} else {
+			spin_unlock_bh(&ifp->lock);
+		}
 		ipv6_del_addr(ifp);
+#endif
+	} else {
+		spin_unlock_bh(&ifp->lock);
+		ipv6_del_addr(ifp);
+	}
 }
 
 
@@ -857,6 +1744,135 @@
 	return err;
 }
 
+#ifdef CONFIG_IPV6_PRIVACY
+/* (re)generation of randomized interface identifier (RFC 3041 3.2, 3.5) */
+static int __ipv6_regen_rndid(struct inet6_dev *idev)
+{
+	struct net_device *dev;
+	u8 eui64[8];
+	u8 digest[16];
+	struct scatterlist sg[2];
+
+	ADBG3((KERN_DEBUG
+	       "__ipv6_regen_rndid(idev=%p)\n",
+	       idev));
+
+	if (!del_timer(&idev->regen_timer))
+		in6_dev_hold(idev);
+
+	dev = idev->dev;
+#if 0
+	if (!dev) {
+		panic("__ipv6_regen_rndid(idev=%p): idev->dev=NULL\n");
+	}
+#endif
+	if (ipv6_generate_eui64(eui64, dev)) {
+		ADBG1((KERN_WARNING
+		       "__ipv6_regen_rndid(idev=%p): cannot get EUI64 identifier; use random bytes.\n", 
+		       idev));
+		get_random_bytes(eui64, sizeof(eui64));
+	}
+
+	sg[0].page = virt_to_page(idev->entropy);
+	sg[0].offset = ((long) idev->entropy & ~PAGE_MASK);
+	sg[0].length = 8;
+	sg[1].page = virt_to_page(eui64);
+	sg[1].offset = ((long) eui64 & ~PAGE_MASK);
+	sg[1].length = 8;
+regen:
+	spin_lock(&md5_tfm_lock);
+	if (md5_tfm == NULL) {
+		spin_unlock(&md5_tfm_lock);
+		in6_dev_put(idev);
+		return -1;
+	}
+	crypto_digest_init(md5_tfm);
+	crypto_digest_update(md5_tfm, sg, 2);
+	crypto_digest_final(md5_tfm, digest);
+	spin_unlock(&md5_tfm_lock);
+	
+	memcpy(idev->rndid, &digest[0], 8);
+	idev->rndid[0] &= ~0x02;
+	memcpy(idev->entropy, &digest[8], 8);
+
+	/*
+	 * <draft-ietf-ipngwg-temp-addresses-v2-00.txt>:
+	 * check if generated address is not inappropriate
+	 * 
+	 *  - Reserved subnet anycast (RFC 2526)
+	 * 	11111101 11....11 1xxxxxxx
+	 *  - ISATAP (draft-ietf-ngtrans-isatap-01.txt) 4.3
+	 * 	00-00-5E-FE-xx-xx-xx-xx
+	 *  - value 0
+	 *  - XXX: already assigned to an address on the device
+	 */
+	if (idev->rndid[0] == 0xfd && 
+	    (idev->rndid[1]&idev->rndid[2]&idev->rndid[3]&idev->rndid[4]&idev->rndid[5]&idev->rndid[6]) == 0xff &&
+	    (idev->rndid[7]&0x80))
+		goto regen;
+	if ((idev->rndid[0]|idev->rndid[1]) == 0) {
+		if (idev->rndid[2] == 0x5e && idev->rndid[3] == 0xfe)
+			goto regen;
+		if ((idev->rndid[2]|idev->rndid[3]|idev->rndid[4]|idev->rndid[5]|idev->rndid[6]|idev->rndid[7]) == 0x00)
+			goto regen;
+	}
+
+	ADBG3((KERN_INFO
+	       "__ipv6_regen_rndid(): new rndid for %s = %02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
+	       idev->dev->name,
+	       idev->rndid[0], idev->rndid[1], idev->rndid[2], idev->rndid[3], 
+	       idev->rndid[4], idev->rndid[5], idev->rndid[6], idev->rndid[7]));
+
+	idev->regen_timer.expires = jiffies + 
+					idev->cnf.temp_prefered_lft * HZ - 
+					idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time - desync_factor;
+	if (time_before(idev->regen_timer.expires, jiffies)) {
+		idev->regen_timer.expires = 0;
+		ADBG1((KERN_WARNING
+		       "__ipv6_regen_rndid(): too short regeneration interval; timer diabled for %s.\n",
+		       idev->dev->name));
+		in6_dev_put(idev);
+		return -1;
+	}
+
+	ADBG3((KERN_DEBUG
+	       "__ipv6_regen_rndid(): next timer = %lu sec(s); temp_preferred_lft = %u\n",
+	       (idev->regen_timer.expires - jiffies) / HZ,
+	       idev->cnf.temp_prefered_lft));
+
+	add_timer(&idev->regen_timer);
+	return 0;
+}
+
+static void ipv6_regen_rndid(unsigned long data)
+{
+	struct inet6_dev *idev = (struct inet6_dev *) data;
+
+	ADBG3((KERN_DEBUG
+	       "ipv6_regen_rndid(idev=%p)\n", 
+	       idev));
+
+	read_lock_bh(&addrconf_lock);
+	write_lock_bh(&idev->lock);
+	if (!idev->dead)
+		__ipv6_regen_rndid(idev);
+	write_unlock_bh(&idev->lock);
+	read_unlock_bh(&addrconf_lock);
+}
+
+static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr) {
+	int ret = 0;
+
+	ADBG3((KERN_DEBUG
+	       "__ipv6_try_regen_rndid(idev=%p,tmpaddr=%p)\n",
+	       idev, tmpaddr));
+
+	if (tmpaddr && memcmp(idev->rndid, &tmpaddr->s6_addr[8], 8) == 0)
+		ret = __ipv6_regen_rndid(idev);
+	return ret;
+}
+#endif
+		
 /*
  *	Add prefix route.
  */
@@ -868,7 +1884,7 @@
 	struct in6_rtmsg rtmsg;
 
 	memset(&rtmsg, 0, sizeof(rtmsg));
-	memcpy(&rtmsg.rtmsg_dst, pfx, sizeof(struct in6_addr));
+	ipv6_addr_copy(&rtmsg.rtmsg_dst, pfx);
 	rtmsg.rtmsg_dst_len = plen;
 	rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF;
 	rtmsg.rtmsg_ifindex = dev->ifindex;
@@ -880,7 +1896,13 @@
 	   This thing is done here expecting that the whole
 	   class of non-broadcast devices need not cloning.
 	 */
-	if (dev->type == ARPHRD_SIT && (dev->flags&IFF_POINTOPOINT))
+	if (
+#ifdef CONFIG_NET_IPIP_IPV6
+	    dev->type == ARPHRD_TUNNEL
+#else
+	    dev->type == ARPHRD_SIT
+#endif
+	    && (dev->flags&IFF_POINTOPOINT))
 		rtmsg.rtmsg_flags |= RTF_NONEXTHOP;
 
 	ip6_route_add(&rtmsg, NULL);
@@ -945,20 +1967,140 @@
 	return idev;
 }
 
+#if 0
+#ifdef CONFIG_IPV6_PREFIXLIST
+static int ipv6_add_prefix(struct inet6_dev *idev, struct in6_addr *addr,
+		__u8 prefix_len, __u32 lifetime)
+{
+	struct in6_addr		prefix;
+	struct list_head	*pos;
+	struct inet6_prefix	*pfx;
+#ifdef CONFIG_IPV6_PREFIXLIST_DEBUG
+	char abuf[64];
+#endif
+
+	ipv6_addr_prefix(&prefix, addr, (int) prefix_len);
+
+#ifdef CONFIG_IPV6_PREFIXLIST_DEBUG
+	in6_ntop(&prefix, abuf);
+#endif
+
+	/* Check if the prefix already exists in the list */
+	read_lock_bh(&idev->lock);
+	write_lock_bh(&idev->prefix_lock);
+	list_for_each(pos, &idev->prefix_list) {
+		pfx = list_entry(pos, struct inet6_prefix, list);
+		if (pfx->prefix_len == prefix_len && ipv6_addr_cmp(&pfx->prefix,
+						&prefix) == 0) {
+			pfx->lifetime = lifetime;
+			pfx->timestamp = jiffies;
+			write_unlock_bh(&idev->prefix_lock);
+			read_unlock_bh(&idev->lock);
+#ifdef CONFIG_IPV6_PREFIXLIST_DEBUG
+			printk(KERN_INFO "%s: changing prefix %s/%d, lifetime = %d\n",
+				__FUNCTION__, abuf, prefix_len, lifetime);
+#endif
+			return 0;
+		}
+	}
+
+	/* New Prefix, allocate one and fill in */
+	if ((pfx = kmalloc(sizeof(struct inet6_prefix), GFP_ATOMIC)) == NULL) {
+		ADBG(("ipv6_add_prefix: malloc failed\n"));
+		return -1;
+	}
+	INIT_LIST_HEAD(&pfx->list);
+	pfx->lifetime = lifetime;
+	pfx->timestamp = jiffies;
+	pfx->prefix_len = prefix_len;
+	ipv6_addr_copy(&pfx->prefix, &prefix);
+
+	list_add(&pfx->list, idev->prefix_list.prev);	/* add to end of list */
+#ifdef CONFIG_IPV6_PREFIXLIST_DEBUG
+	printk(KERN_INFO "%s: adding prefix %s/%d, lifetime = %d\n",
+		__FUNCTION__, abuf, prefix_len, lifetime);
+#endif
+	write_unlock_bh(&idev->prefix_lock);
+	read_unlock_bh(&idev->lock);
+	return 0;
+}
+#endif
+#endif
+
+void ipv6_wash_prefix(struct in6_addr *pfx, int plen)
+{
+	int b = plen&0x7;
+	int o = (plen + 7)>>3;
+
+	if (o < 16)
+		memset(pfx->s6_addr + o, 0, 16 - o);
+	if (b != 0)
+		pfx->s6_addr[plen>>3] &= (0xFF<<(8-b));
+}
+
+#ifdef CONFIG_IPV6_PREFIXLIST
+static int ipv6_add_prefix(struct inet6_dev *idev, struct prefix_info *pinfo)
+{
+	int ifindex;
+	struct in6_addr	prefix;
+	struct list_head *head;
+	struct prefix_element *p;
+
+	ipv6_addr_prefix(&prefix, &pinfo->prefix, (int)pinfo->prefix_len);
+
+	/* Check if the prefix already exists in the list */
+	read_lock_bh(&idev->lock);
+	spin_lock_bh(&idev->prefix_lock);
+
+	ifindex = idev->dev->ifindex;
+
+	list_for_each(head, &idev->prefix_list) {
+		p = list_entry(head, struct prefix_element, list);
+		if (p->pinfo.prefix_len == pinfo->prefix_len
+		    && ipv6_addr_cmp(&p->pinfo.prefix, &prefix) == 0) {
+			p->pinfo.valid = pinfo->valid;
+			p->timestamp = jiffies;
+			spin_unlock_bh(&idev->prefix_lock);
+			read_unlock_bh(&idev->lock);
+			return 0;
+		}
+	}
+
+	/* New Prefix, allocate one and fill in */
+	if ((p = kmalloc(sizeof(struct prefix_element), GFP_ATOMIC)) == NULL) {
+		ADBG(("ipv6_add_prefix: malloc failed\n"));
+		spin_unlock_bh(&idev->prefix_lock);
+		read_unlock_bh(&idev->lock);
+		return -1;
+	}
+
+	memcpy(&p->pinfo, pinfo, sizeof(struct prefix_info));
+	ipv6_wash_prefix(&p->pinfo.prefix, pinfo->prefix_len);
+	p->timestamp = jiffies;
+
+	idev->prefix_count++;
+	list_add(&p->list, idev->prefix_list.prev);	/* add to end of list */
+
+	spin_unlock_bh(&idev->prefix_lock);
+	read_unlock_bh(&idev->lock);
+
+	return 0;
+}
+#endif
+
 void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
 {
 	struct prefix_info *pinfo;
-	struct rt6_info *rt;
 	__u32 valid_lft;
 	__u32 prefered_lft;
 	int addr_type;
-	unsigned long rt_expires;
 	struct inet6_dev *in6_dev;
 
 	pinfo = (struct prefix_info *) opt;
 	
 	if (len < sizeof(struct prefix_info)) {
-		ADBG(("addrconf: prefix option too short\n"));
+		ADBG2((KERN_WARNING
+		       "addrconf: prefix option too short\n"));
 		return;
 	}
 	
@@ -973,18 +2115,33 @@
 
 	valid_lft = ntohl(pinfo->valid);
 	prefered_lft = ntohl(pinfo->prefered);
+	ADBG3((KERN_INFO
+	       "Valid Lifetime of Received Prefix = %d\n", valid_lft));
+	ADBG3((KERN_INFO
+	       "Prefered Lifetime of Received Prefix = %d\n", prefered_lft));
 
 	if (prefered_lft > valid_lft) {
 		if (net_ratelimit())
-			printk(KERN_WARNING "addrconf: prefix option has invalid lifetime\n");
+			ADBG2((KERN_WARNING "addrconf: prefix option has invalid lifetime\n"));
 		return;
 	}
 
+	if (valid_lft >= 0x7FFFFFFF/HZ) {
+		/* Avoid arithemtic overflow */
+		if (net_ratelimit())
+			ADBG1((KERN_DEBUG "addrconf: valid lifetime %u is too long; adjusted to %u.\n",
+			       valid_lft, 0x7FFFFFFF/HZ-1));
+		valid_lft = 0x7FFFFFFF/HZ-1;
+		if (prefered_lft > valid_lft)
+			prefered_lft = valid_lft;
+	}
+
 	in6_dev = in6_dev_get(dev);
 
 	if (in6_dev == NULL) {
 		if (net_ratelimit())
-			printk(KERN_DEBUG "addrconf: device %s not configured\n", dev->name);
+			ADBG1((KERN_DEBUG 
+			       "addrconf: device %s not configured\n", dev->name));
 		return;
 	}
 
@@ -994,87 +2151,104 @@
 	 *	2) Configure prefixes with the auto flag set
 	 */
 
-	/* Avoid arithemtic overflow. Really, we could
-	   save rt_expires in seconds, likely valid_lft,
-	   but it would require division in fib gc, that it
-	   not good.
-	 */
-	if (valid_lft >= 0x7FFFFFFF/HZ)
-		rt_expires = 0;
-	else
-		rt_expires = jiffies + valid_lft * HZ;
-
-	rt = rt6_lookup(&pinfo->prefix, NULL, dev->ifindex, 1);
+	if (pinfo->onlink) {
+		struct rt6_info *rt;
+		unsigned long rt_expires = jiffies + valid_lft + HZ;
 
-	if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
-		if (rt->rt6i_flags&RTF_EXPIRES) {
-			if (pinfo->onlink == 0 || valid_lft == 0) {
-				ip6_del_rt(rt, NULL);
-				rt = NULL;
-			} else {
-				rt->rt6i_expires = rt_expires;
+		rt = rt6_lookup(&pinfo->prefix, NULL, dev->ifindex, 
+					 RT6_LOOKUP_FLAG_STRICT|RT6_LOOKUP_FLAG_NOUSE);
+	
+		if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
+			if (rt->rt6i_flags&RTF_EXPIRES) {
+				if (valid_lft) {
+					rt->rt6i_expires = rt_expires;
+				} else {
+					ip6_del_rt(rt, NULL);
+					rt = NULL;
+				}
 			}
-		}
-	} else if (pinfo->onlink && valid_lft) {
-		addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len,
-				      dev, rt_expires, RTF_ADDRCONF|RTF_EXPIRES|RTF_PREFIX_RT);
+		} else if (valid_lft) {
+			addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len,
+					      dev, rt_expires, RTF_ADDRCONF|RTF_EXPIRES|RTF_PREFIX_RT);
+		}
+		if (rt)
+			dst_release(&rt->u.dst);
+#ifdef CONFIG_IPV6_PREFIXLIST
+		/* Add this prefix to the list of prefixes on this interface */
+		ipv6_add_prefix(in6_dev, pinfo);
+#endif
 	}
-	if (rt)
-		dst_release(&rt->u.dst);
 
 	/* Try to figure out our local address for this prefix */
 
 	if (pinfo->autoconf && in6_dev->cnf.autoconf) {
-		struct inet6_ifaddr * ifp;
+		struct inet6_ifaddr *ifp = NULL;
+#ifdef CONFIG_IPV6_PRIVACY
+		struct inet6_ifaddr *ift = NULL;
+#endif
+		int flags;
 		struct in6_addr addr;
-		int plen;
-
-		plen = pinfo->prefix_len >> 3;
+		int update_lft = 0, create = 0;
+		unsigned long now, stored_lft;
 
-		if (pinfo->prefix_len == 64) {
-			memcpy(&addr, &pinfo->prefix, 8);
-			if (ipv6_generate_eui64(addr.s6_addr + 8, dev) &&
-			    ipv6_inherit_eui64(addr.s6_addr + 8, in6_dev)) {
-				in6_dev_put(in6_dev);
-				return;
-			}
-			goto ok;
+		if (pinfo->prefix_len != 64) {
+			if (net_ratelimit())
+				ADBG2((KERN_DEBUG
+				       "IPv6 addrconf: prefix with wrong length %d\n", 
+				       pinfo->prefix_len));
+			goto autoconf_fail;
 		}
-		if (net_ratelimit())
-			printk(KERN_DEBUG "IPv6 addrconf: prefix with wrong length %d\n",
-			       pinfo->prefix_len);
-		in6_dev_put(in6_dev);
-		return;
 
-ok:
+		memcpy(&addr, &pinfo->prefix, 8);
+		if (ipv6_generate_eui64(addr.s6_addr + 8, dev) &&
+		    ipv6_inherit_eui64(addr.s6_addr + 8, in6_dev))
+			goto autoconf_fail;
 
 		ifp = ipv6_get_ifaddr(&addr, dev);
 
-		if (ifp == NULL && valid_lft) {
-			/* Do not allow to create too much of autoconfigured
-			 * addresses; this would be too easy way to crash kernel.
-			 */
-			if (ipv6_count_addresses(in6_dev) < IPV6_MAX_ADDRESSES)
+		if (!ifp) {
+			int max_addresses = in6_dev->cnf.max_addresses;
+
+			if (!valid_lft)
+				goto autoconf_fail;
+
+			if (!max_addresses ||
+			    ipv6_count_addresses(in6_dev) < max_addresses)
 				ifp = ipv6_add_addr(in6_dev, &addr, pinfo->prefix_len,
 						    addr_type&IPV6_ADDR_SCOPE_MASK, 0);
-
-			if (IS_ERR(ifp)) {
-				in6_dev_put(in6_dev);
-				return;
-			}
+			if (!ifp)
+				goto autoconf_fail;
 
 			addrconf_dad_start(ifp, RTF_ADDRCONF|RTF_PREFIX_RT);
+			update_lft = 1;
+			create = 1;
 		}
 
-		if (ifp && valid_lft == 0) {
-			ipv6_del_addr(ifp);
-			ifp = NULL;
+		spin_lock(&ifp->lock);
+		now = jiffies;
+		if (ifp->valid_lft > (now - ifp->tstamp) / HZ)
+			stored_lft = ifp->valid_lft - (now - ifp->tstamp) / HZ;
+		else
+			stored_lft = 0;
+#define TWO_HOURS	7200
+		if (!update_lft && stored_lft) {
+			if (valid_lft > TWO_HOURS ||
+			    valid_lft > stored_lft) {
+				update_lft = 1;
+			} else if (stored_lft <= TWO_HOURS
+#if 0	/* this rule is logically redundant */
+				   && valid_lft <= stored_lft
+#endif
+				   ) {
+				update_lft = 0;
+			} else {
+				valid_lft = TWO_HOURS;
+				if (valid_lft < prefered_lft)
+					prefered_lft = valid_lft;
+				update_lft = 1;
+			}
 		}
-
-		if (ifp) {
-			int flags;
-
-			spin_lock(&ifp->lock);
+		if (update_lft) {
 			ifp->valid_lft = valid_lft;
 			ifp->prefered_lft = prefered_lft;
 			ifp->tstamp = jiffies;
@@ -1085,10 +2259,49 @@
 			if (!(flags&IFA_F_TENTATIVE))
 				ipv6_ifa_notify((flags&IFA_F_DEPRECATED) ?
 						0 : RTM_NEWADDR, ifp);
-			in6_ifa_put(ifp);
-			addrconf_verify(0);
+		} else {
+			spin_unlock(&ifp->lock);
+		}
+#ifdef CONFIG_IPV6_PRIVACY
+		read_lock_bh(&in6_dev->lock);
+
+		/* update all temporary addresses in the list */
+		for (ift=in6_dev->tempaddr_list; ift; ift=ift->tmp_next) {
+			/*
+			 * When adjusting the lifetimes of an existing 
+			 * temporary address, only lower the lifetimes.  
+			 * Implementations must not increase the 
+			 * lifetimes of an existing temporary address 
+			 * when processing a Prefix Information Option.
+			 */
+			spin_lock(&ift->lock);
+			flags = ift->flags;
+			if (ift->valid_lft > valid_lft &&
+			    ift->valid_lft - valid_lft > (jiffies - ift->tstamp) / HZ)
+				ift->valid_lft = valid_lft + (jiffies - ift->tstamp) / HZ;
+			if (ift->prefered_lft > prefered_lft &&
+			    ift->prefered_lft - prefered_lft > (jiffies - ift->tstamp) / HZ)
+				ift->prefered_lft = prefered_lft + (jiffies - ift->tstamp) / HZ;
+			spin_unlock(&ift->lock);
+			if (!(flags&IFA_F_TENTATIVE))
+				ipv6_ifa_notify(0, ift);
+		}
+
+		if (create && in6_dev->cnf.use_tempaddr > 0) {
+			/*
+			 * When a new public address is created as described in [ADDRCONF],
+			 * also create a new temporary address.
+			 */
+			read_unlock_bh(&in6_dev->lock);	
+			ipv6_create_tempaddr(ifp, NULL);
+		} else {
+			read_unlock_bh(&in6_dev->lock);
 		}
+#endif
+		addrconf_verify(0);
+		in6_ifa_put(ifp);
 	}
+autoconf_fail:
 	in6_dev_put(in6_dev);
 }
 
@@ -1115,7 +2328,12 @@
 	if (dev == NULL)
 		goto err_exit;
 
-	if (dev->type == ARPHRD_SIT) {
+#ifdef CONFIG_NET_IPIP_IPV6
+	if (dev->type == ARPHRD_TUNNEL)
+#else
+	if (dev->type == ARPHRD_SIT)
+#endif
+	{
 		struct ifreq ifr;
 		mm_segment_t	oldfs;
 		struct ip_tunnel_parm p;
@@ -1158,7 +2376,15 @@
 	struct inet6_ifaddr *ifp;
 	struct inet6_dev *idev;
 	struct net_device *dev;
-	int scope;
+	int type, scope;
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+	char abuf[128];
+
+	in6_ntop(pfx, abuf);
+	ADBG3((KERN_DEBUG
+	       "inet6_addr_addr(ifindex=%d, pfx=%s, plen=%d)\n",
+	       ifindex, abuf, plen));
+#endif
 
 	ASSERT_RTNL();
 	
@@ -1171,6 +2397,10 @@
 	if ((idev = addrconf_add_dev(dev)) == NULL)
 		return -ENOBUFS;
 
+	type = ipv6_addr_type(pfx);
+	if (type & IPV6_ADDR_MULTICAST)
+		return -EINVAL;
+
 	scope = ipv6_addr_scope(pfx);
 
 	ifp = ipv6_add_addr(idev, pfx, plen, scope, IFA_F_PERMANENT);
@@ -1221,6 +2451,12 @@
 {
 	struct in6_ifreq ireq;
 	int err;
+
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+	ADBG3((KERN_DEBUG
+	       "addrconf_add_ifaddr(arg=%p)\n",
+	       arg));
+#endif
 	
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
@@ -1238,6 +2474,12 @@
 {
 	struct in6_ifreq ireq;
 	int err;
+
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+	ADBG3((KERN_DEBUG
+	       "addrconf_add_ifaddr(arg=%p)\n",
+	       arg));
+#endif
 	
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
@@ -1251,34 +2493,42 @@
 	return err;
 }
 
+static void __sit_add_v4_addr(struct inet6_dev *idev, struct in6_addr *addr, int plen, int scope)
+{
+	struct inet6_ifaddr *ifp = ipv6_add_addr(idev, addr, plen, scope, IFA_F_PERMANENT);
+	if (!IS_ERR(ifp)) {
+		spin_lock_bh(&ifp->lock);
+		ifp->flags &= ~IFA_F_TENTATIVE;
+		spin_unlock_bh(&ifp->lock);
+		ipv6_ifa_notify(RTM_NEWADDR, ifp);
+		in6_ifa_put(ifp);
+	}
+}
+
 static void sit_add_v4_addrs(struct inet6_dev *idev)
 {
-	struct inet6_ifaddr * ifp;
 	struct in6_addr addr;
+	int plen;
 	struct net_device *dev;
 	int scope;
+	__u32 dev_addr = *(__u32 *)idev->dev->dev_addr;
 
 	ASSERT_RTNL();
 
-	memset(&addr, 0, sizeof(struct in6_addr));
-	memcpy(&addr.s6_addr32[3], idev->dev->dev_addr, 4);
-
 	if (idev->dev->flags&IFF_POINTOPOINT) {
-		addr.s6_addr32[0] = htonl(0xfe800000);
+		ipv6_addr_set(&addr, 
+			      htonl(0xfe800000), 0, 0, dev_addr);
+		plen = addr.s6_addr32[3] ? 128 : 64;
 		scope = IFA_LINK;
 	} else {
+		ipv6_addr_set(&addr, 
+			      0, 0, 0, dev_addr);
+		plen = 96;
 		scope = IPV6_ADDR_COMPATv4;
 	}
 
 	if (addr.s6_addr32[3]) {
-		ifp = ipv6_add_addr(idev, &addr, 128, scope, IFA_F_PERMANENT);
-		if (!IS_ERR(ifp)) {
-			spin_lock_bh(&ifp->lock);
-			ifp->flags &= ~IFA_F_TENTATIVE;
-			spin_unlock_bh(&ifp->lock);
-			ipv6_ifa_notify(RTM_NEWADDR, ifp);
-			in6_ifa_put(ifp);
-		}
+		__sit_add_v4_addr(idev, &addr, 128, scope);
 		return;
 	}
 
@@ -1290,8 +2540,6 @@
 			int flag = scope;
 
 			for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
-				int plen;
-
 				addr.s6_addr32[3] = ifa->ifa_local;
 
 				if (ifa->ifa_scope == RT_SCOPE_LINK)
@@ -1301,26 +2549,13 @@
 						continue;
 					flag |= IFA_HOST;
 				}
-				if (idev->dev->flags&IFF_POINTOPOINT)
-					plen = 64;
-				else
-					plen = 96;
-
-				ifp = ipv6_add_addr(idev, &addr, plen, flag,
-						    IFA_F_PERMANENT);
-				if (!IS_ERR(ifp)) {
-					spin_lock_bh(&ifp->lock);
-					ifp->flags &= ~IFA_F_TENTATIVE;
-					spin_unlock_bh(&ifp->lock);
-					ipv6_ifa_notify(RTM_NEWADDR, ifp);
-					in6_ifa_put(ifp);
-				}
+				__sit_add_v4_addr(idev, &addr, plen, flag);
 			}
 		}
         }
 }
 
-static void init_loopback(struct net_device *dev)
+static struct inet6_dev * init_loopback(struct net_device *dev)
 {
 	struct inet6_dev  *idev;
 	struct inet6_ifaddr * ifp;
@@ -1330,10 +2565,12 @@
 	ASSERT_RTNL();
 
 	if ((idev = ipv6_find_idev(dev)) == NULL) {
-		printk(KERN_DEBUG "init loopback: add_dev failed\n");
-		return;
+		ADBG1((KERN_WARNING "init loopback: add_dev failed\n"));
+		return NULL;
 	}
 
+	ipv6_mc_up(idev);
+
 	ifp = ipv6_add_addr(idev, &in6addr_loopback, 128, IFA_HOST, IFA_F_PERMANENT);
 	if (!IS_ERR(ifp)) {
 		spin_lock_bh(&ifp->lock);
@@ -1342,6 +2579,8 @@
 		ipv6_ifa_notify(RTM_NEWADDR, ifp);
 		in6_ifa_put(ifp);
 	}
+
+	return idev;
 }
 
 static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr *addr)
@@ -1355,33 +2594,37 @@
 	}
 }
 
-static void addrconf_dev_config(struct net_device *dev)
+static struct inet6_dev * addrconf_dev_config(struct net_device *dev)
 {
 	struct in6_addr addr;
 	struct inet6_dev    * idev;
 
 	ASSERT_RTNL();
 
-	if ((dev->type != ARPHRD_ETHER) && 
-	    (dev->type != ARPHRD_FDDI) &&
-	    (dev->type != ARPHRD_IEEE802_TR) &&
-	    (dev->type != ARPHRD_ARCNET)) {
+	switch(dev->type){
+	case ARPHRD_ETHER:
+	case ARPHRD_FDDI:
+	case ARPHRD_IEEE802_TR:
+	case ARPHRD_ARCNET:
+		break;
+	default:
 		/* Alas, we support only Ethernet autoconfiguration. */
-		return;
+		return NULL;
 	}
 
 	idev = addrconf_add_dev(dev);
 	if (idev == NULL)
-		return;
+		return NULL;
 
-	memset(&addr, 0, sizeof(struct in6_addr));
-	addr.s6_addr32[0] = htonl(0xFE800000);
+	ipv6_addr_set(&addr, htonl(0xfe800000), 0, 0, 0);
 
 	if (ipv6_generate_eui64(addr.s6_addr + 8, dev) == 0)
 		addrconf_add_linklocal(idev, &addr);
+
+	return idev;
 }
 
-static void addrconf_sit_config(struct net_device *dev)
+static struct inet6_dev * addrconf_sit_config(struct net_device *dev)
 {
 	struct inet6_dev *idev;
 
@@ -1394,9 +2637,10 @@
 	 */
 
 	if ((idev = ipv6_find_idev(dev)) == NULL) {
-		printk(KERN_DEBUG "init sit: add_dev failed\n");
-		return;
+		ADBG1((KERN_WARNING "init sit: add_dev failed\n"));
+		return NULL;
 	}
+	ipv6_mc_up(idev);
 
 	sit_add_v4_addrs(idev);
 
@@ -1405,6 +2649,27 @@
 		addrconf_add_lroute(dev);
 	} else
 		sit_route_add(dev);
+
+	return idev;
+}
+
+
+/**
+ * addrconf_ipv6_tunnel_config - configure IPv6 tunnel device
+ * @dev: tunnel device
+ **/
+
+static void addrconf_ipv6_tunnel_config(struct net_device *dev)
+{
+	struct inet6_dev *idev;
+
+	ASSERT_RTNL();
+
+	/* Assign inet6_dev structure to tunnel device */
+	if ((idev = ipv6_find_idev(dev)) == NULL) {
+		printk(KERN_DEBUG "init ipv6 tunnel: add_dev failed\n");
+		return;
+	}
 }
 
 
@@ -1412,24 +2677,37 @@
 		    void * data)
 {
 	struct net_device *dev = (struct net_device *) data;
-	struct inet6_dev *idev = __in6_dev_get(dev);
 
 	switch(event) {
 	case NETDEV_UP:
+	{
+		struct inet6_dev *idev = NULL;
 		switch(dev->type) {
+#ifdef CONFIG_NET_IPIP_IPV6
+		case ARPHRD_TUNNEL:
+#else
 		case ARPHRD_SIT:
-			addrconf_sit_config(dev);
+#endif
+		    {
+			idev = addrconf_sit_config(dev);
+			break;
+		    }
+
+		case ARPHRD_IPV6_IPV6_TUNNEL:
+			addrconf_ipv6_tunnel_config(dev);
 			break;
 
 		case ARPHRD_LOOPBACK:
-			init_loopback(dev);
+			idev = init_loopback(dev);
 			break;
 
 		default:
-			addrconf_dev_config(dev);
+			idev = addrconf_dev_config(dev);
 			break;
 		};
 		if (idev) {
+			idev->stats.ipv6[0].Ip6LastChange = timeticks(jiffies);
+
 			/* If the MTU changed during the interface down, when the 
 			   interface up, the changed MTU must be reflected in the 
 			   idev as well as routers.
@@ -1443,10 +2721,15 @@
 			 */
 			if (dev->mtu < IPV6_MIN_MTU)
 				addrconf_ifdown(dev, event != NETDEV_DOWN);
+#ifdef CONFIG_IPV6_NODEINFO
+			icmpv6_ni_join_nigroup_dev(dev);
+#endif
 		}
 		break;
-
+	}
 	case NETDEV_CHANGEMTU:
+	{
+		struct inet6_dev *idev = __in6_dev_get(dev);
 		if ( idev && dev->mtu >= IPV6_MIN_MTU) {
 			rt6_mtu_change(dev, dev->mtu);
 			idev->cnf.mtu6 = dev->mtu;
@@ -1454,14 +2737,19 @@
 		}
 
 		/* MTU falled under IPV6_MIN_MTU. Stop IPv6 on this interface. */
-
+	}
 	case NETDEV_DOWN:
 	case NETDEV_UNREGISTER:
+	{
+		struct inet6_dev *idev = __in6_dev_get(dev);
 		/*
 		 *	Remove all addresses from this interface.
 		 */
+		if (idev)
+			idev->stats.ipv6[0].Ip6LastChange = timeticks(jiffies);
 		addrconf_ifdown(dev, event != NETDEV_DOWN);
 		break;
+	}
 	case NETDEV_CHANGE:
 		break;
 	};
@@ -1473,8 +2761,16 @@
 {
 	struct inet6_dev *idev;
 	struct inet6_ifaddr *ifa, **bifa;
+#ifdef CONFIG_IPV6_PREFIXLIST
+	struct list_head	*head, *next;
+	struct prefix_element	*p;
+#endif
 	int i;
 
+	ADBG3((KERN_DEBUG
+	       "addrconf_ifdown(dev=%p(%s), how=%d)\n",
+	       dev, dev->name, how));
+
 	ASSERT_RTNL();
 
 	rt6_ifdown(dev);
@@ -1512,9 +2808,33 @@
 		write_unlock_bh(&addrconf_hash_lock);
 	}
 
-	/* Step 3: clear address list */
-
 	write_lock_bh(&idev->lock);
+
+	/* Step 3: clear flags for stateless addrconf */
+	if (how != 1)
+		idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+
+	/* Step 4: clear address list */
+#ifdef CONFIG_IPV6_PRIVACY
+	if (del_timer(&idev->regen_timer))
+		in6_dev_put(idev);
+
+	/* clear tempaddr list */
+	while ((ifa = idev->tempaddr_list) != NULL) {
+		idev->tempaddr_list = ifa->tmp_next;
+		ifa->tmp_next = NULL;
+		ifa->dead = 1;
+		write_unlock_bh(&idev->lock);
+		spin_lock_bh(&ifa->lock);
+		if (ifa->ifpub) {
+			in6_ifa_put(ifa->ifpub);
+			ifa->ifpub = NULL;
+		}
+		spin_unlock_bh(&ifa->lock);
+		in6_ifa_put(ifa);
+		write_lock_bh(&idev->lock);
+	}
+#endif
 	while ((ifa = idev->addr_list) != NULL) {
 		idev->addr_list = ifa->if_next;
 		ifa->if_next = NULL;
@@ -1529,13 +2849,33 @@
 	}
 	write_unlock_bh(&idev->lock);
 
-	/* Step 4: Discard multicast list */
+	/* Step 5: Discard multicast list */
 
 	if (how == 1)
 		ipv6_mc_destroy_dev(idev);
 	else
 		ipv6_mc_down(idev);
 
+#ifdef CONFIG_IPV6_PREFIXLIST
+	/* Step 6: Free up Prefix List */
+	spin_lock_bh(&idev->prefix_lock);
+	list_for_each_safe(head, next, &idev->prefix_list) {
+		p = list_entry(head, struct prefix_element, list);
+#ifdef CONFIG_IPV6_PREFIXLIST_DEBUG
+		{
+			char abuf[64];
+			struct inet6_prefix *pl = (struct inet6_prefix *)pfx;
+			in6_ntop(&pl->prefix, abuf);
+			printk(KERN_INFO "%s: deleting prefix %s/%d, lifetime = %d\n",
+				__FUNCTION__, abuf, pl->prefix_len, pl->lifetime);
+		}
+#endif
+		kfree(p);
+	}
+	INIT_LIST_HEAD(&idev->prefix_list);
+	spin_unlock_bh(&idev->prefix_lock);
+
+#endif
 	/* Shot the device (if unregistered) */
 
 	if (how == 1) {
@@ -1552,6 +2892,11 @@
 {
 	struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data;
 
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+	ADBG3((KERN_DEBUG
+	       "addrconf_rs_timer(ifp=%p): jiffies=%lu\n", ifp, jiffies));
+#endif
+
 	if (ifp->idev->cnf.forwarding)
 		goto out;
 
@@ -1582,13 +2927,14 @@
 
 		spin_unlock(&ifp->lock);
 
-		printk(KERN_DEBUG "%s: no IPv6 routers present\n",
-		       ifp->idev->dev->name);
+		ADBG1((KERN_DEBUG "%s: no IPv6 routers present\n",
+		       ifp->idev->dev->name));
 
 		memset(&rtmsg, 0, sizeof(struct in6_rtmsg));
 		rtmsg.rtmsg_type = RTMSG_NEWROUTE;
 		rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF;
-		rtmsg.rtmsg_flags = (RTF_ALLONLINK | RTF_DEFAULT | RTF_UP);
+		rtmsg.rtmsg_flags = (RTF_ALLONLINK | RTF_ADDRCONF |
+				     RTF_DEFAULT | RTF_UP);
 
 		rtmsg.rtmsg_ifindex = ifp->idev->dev->ifindex;
 
@@ -1609,13 +2955,19 @@
 
 	dev = ifp->idev->dev;
 
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+	ADBG3((KERN_DEBUG
+	       "addrconf_dad_start(ifp=%p): jiffies=%lu\n", ifp, jiffies));
+#endif
+
+	/*  Join his own solicit address  */
 	addrconf_join_solict(dev, &ifp->addr);
 
 	if (ifp->prefix_len != 128 && (ifp->flags&IFA_F_PERMANENT))
 		addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev, 0, flags);
 
-	net_srandom(ifp->addr.s6_addr32[3]);
-	rand_num = net_random() % (ifp->idev->cnf.rtr_solicit_delay ? : 1);
+	get_random_bytes(&rand_num, sizeof(rand_num));
+	rand_num %= (ifp->idev->cnf.rtr_solicit_delay ? : 1);
 
 	spin_lock_bh(&ifp->lock);
 
@@ -1640,6 +2992,11 @@
 	struct in6_addr unspec;
 	struct in6_addr mcaddr;
 
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+	ADBG3((KERN_DEBUG
+	       "addrconf_dad_timer(ifp=%p): jiffies=%lu\n", ifp, jiffies));
+#endif
+
 	spin_lock_bh(&ifp->lock);
 	if (ifp->probes == 0) {
 		/*
@@ -1662,14 +3019,17 @@
 	/* send a neighbour solicitation for our addr */
 	memset(&unspec, 0, sizeof(unspec));
 	addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
-	ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &unspec);
+	ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &unspec, 1);
 
 	in6_ifa_put(ifp);
 }
 
 static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
 {
-	struct net_device *	dev = ifp->idev->dev;
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+	ADBG3((KERN_DEBUG
+	       "addrconf_dad_completed(ifp=%p): jiffies=%lu\n", ifp, jiffies));
+#endif
 
 	/*
 	 *	Configure the address for reception. Now it is valid.
@@ -1681,8 +3041,25 @@
 	   start sending router solicitations.
 	 */
 
+#ifdef CONFIG_IPV6_PRIVACY
+	spin_lock_bh(&ifp->lock);
+	if (ifp->flags&IFA_F_TEMPORARY) {
+		if (!ifp->ifpub) {
+			ADBG1((KERN_WARNING
+			       "addrconf_dad_completed(): ifp->ifpub is NULL.\n"));
+		} else {
+			spin_lock(&ifp->ifpub->lock);
+			ifp->ifpub->regen_count = 0;
+			spin_unlock(&ifp->ifpub->lock);
+		}
+		spin_unlock_bh(&ifp->lock);
+		return;
+	}
+	spin_unlock_bh(&ifp->lock);
+#endif
+
 	if (ifp->idev->cnf.forwarding == 0 &&
-	    (dev->flags&IFF_LOOPBACK) == 0 &&
+	    ifp->idev->cnf.accept_ra  &&
 	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
 		struct in6_addr all_routers;
 
@@ -1706,8 +3083,9 @@
 		struct in6_addr addr;
 
 		ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
-		if (!ipv6_addr_any(&addr))
+		if (!ipv6_addr_any(&addr)) {
 			ipv6_dev_ac_inc(ifp->idev->dev, &addr);
+		}
 	}
 }
 
@@ -1763,8 +3141,116 @@
 	return len;
 }
 
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+
+#define print_ifa_flag(_ifp,_flag)	do {		\
+	if ((_ifp)->flags&IFA_F_ ## _flag) {		\
+		len += sprintf(buffer + len, "%s%s",	\
+				fcount ? "," : "",	\
+				# _flag);		\
+		fcount++;				\
+	}						\
+} while(0);
+
+static int iface_debug_proc_info(char *buffer, char **start, off_t offset,
+			   int length)
+{
+	struct inet6_ifaddr *ifp;
+	int i;
+	int len = 0;
+	off_t pos=0;
+	off_t begin=0;
+
+	for (i=0; i < IN6_ADDR_HSIZE; i++) {
+		read_lock_bh(&addrconf_hash_lock);
+		for (ifp=inet6_addr_lst[i]; ifp; ifp=ifp->lst_next) {
+			int j;
+			int fcount = 0;
+
+			for (j=0; j<16; j++) {
+				sprintf(buffer + len, "%02x",
+					ifp->addr.s6_addr[j]);
+				len += 2;
+			}
+
+			len += sprintf(buffer + len,
+				       " %08lx %08x %08x "
+				       "%8s ",
+				       (jiffies - ifp->tstamp) / HZ,
+				       ifp->prefered_lft, ifp->valid_lft,
+				       ifp->idev->dev->name);
+			print_ifa_flag(ifp,TENTATIVE);
+			print_ifa_flag(ifp,PERMANENT);
+			print_ifa_flag(ifp,TEMPORARY);
+			print_ifa_flag(ifp,DEPRECATED);
+			len += sprintf(buffer + len, "\n");
+			pos=begin+len;
+			if(pos<offset) {
+				len=0;
+				begin=pos;
+			}
+			if(pos>offset+length) {
+				read_unlock_bh(&addrconf_hash_lock);
+				goto done;
+			}
+		}
+		read_unlock_bh(&addrconf_hash_lock);
+	}
+
+done:
+
+	*start=buffer+(offset-begin);
+	len-=(offset-begin);
+	if(len>length)
+		len=length;
+	if(len<0)
+		len=0;
+	return len;
+}
+#endif
+
 #endif	/* CONFIG_PROC_FS */
 
+#ifdef CONFIG_IPV6_PREFIXLIST
+static void ipv6_expire_prefixes(void)
+{
+	unsigned long		now = jiffies;
+	struct net_device	*dev;
+	struct inet6_dev	*idev;
+	struct list_head	*head, *next;
+	struct prefix_element	*p;
+	unsigned long		age;
+
+	read_lock(&dev_base_lock);
+	for (dev = dev_base; dev; dev = dev->next) {
+		if (!(idev = __in6_dev_get(dev))) {
+			continue;
+		}
+		read_lock_bh(&idev->lock);
+		spin_lock_bh(&idev->prefix_lock);
+		if (list_empty(&idev->prefix_list)) {
+			spin_unlock_bh(&idev->prefix_lock);
+			read_unlock_bh(&idev->lock);
+			continue;
+		}
+		list_for_each_safe(head, next, &idev->prefix_list) {
+			p = list_entry(head, struct prefix_element, list);
+			if (p->pinfo.valid != INFINITE) {
+				age = (now - p->timestamp) / HZ;
+				if (age > ntohl(p->pinfo.valid)) {
+					idev->prefix_count--;
+					list_del(&p->list);
+					kfree(p);
+				}
+			}
+		}
+		spin_unlock_bh(&idev->prefix_lock);
+		read_unlock_bh(&idev->lock);
+	}
+	read_unlock(&dev_base_lock);
+}
+#endif
+
 /*
  *	Periodic address status verification
  */
@@ -1774,6 +3260,16 @@
 	struct inet6_ifaddr *ifp;
 	unsigned long now, next;
 	int i;
+#ifdef CONFIG_IPV6_PREFIXLIST
+	struct net_device *dev;
+	struct inet6_dev *idev;
+	struct list_head *pos, *n;
+	struct inet6_prefix *pfx;
+#endif
+
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+	char abuf[128];
+#endif
 
 	spin_lock_bh(&addrconf_verify_lock);
 	now = jiffies;
@@ -1787,14 +3283,39 @@
 		write_lock(&addrconf_hash_lock);
 		for (ifp=inet6_addr_lst[i]; ifp; ifp=ifp->lst_next) {
 			unsigned long age;
+#ifdef CONFIG_IPV6_PRIVACY
+			unsigned long regen_advance;
+#endif
+
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+			in6_ntop(&ifp->addr, abuf);
+#endif
+
+#ifdef CONFIG_IPV6_PRIVACY
+			read_lock(&ifp->idev->lock);
+			regen_advance = ifp->idev->cnf.regen_max_retry * ifp->idev->cnf.dad_transmits * ifp->idev->nd_parms->retrans_time / HZ;
+			read_unlock(&ifp->idev->lock);
+#endif
 
-			if (ifp->flags & IFA_F_PERMANENT)
+			if (ifp->flags & IFA_F_PERMANENT) {
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+				ADBG3((KERN_DEBUG
+				       "addrconf_verify(): ifp->addr=%s, IFA_F_PERMANENT\n",
+				       abuf));
+#endif
 				continue;
+			}
 
 			spin_lock(&ifp->lock);
 			age = (now - ifp->tstamp) / HZ;
 
 			if (age >= ifp->valid_lft) {
+				/* jiffies - ifp->tsamp > age >= ifp->valid_lft */
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+				ADBG3((KERN_DEBUG
+				       "addrconf_verify(): ifp->addr=%s, valid_lft(%u) <= age(%lu)\n",
+				       abuf, ifp->valid_lft, age));
+#endif
 				spin_unlock(&ifp->lock);
 				in6_ifa_hold(ifp);
 				write_unlock(&addrconf_hash_lock);
@@ -1812,6 +3333,14 @@
 				if (time_before(ifp->tstamp + ifp->valid_lft * HZ, next))
 					next = ifp->tstamp + ifp->valid_lft * HZ;
 
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+				ADBG3((KERN_DEBUG
+				       "addrconf_verify(): "
+				       "ifp->addr=%s, "
+				       "prefered_lft(%u) <= age(%lu) < valid_lft(%u), "
+				       "deprecate=%d, next=%ld\n",
+				       abuf, ifp->prefered_lft, age, ifp->valid_lft, deprecate, (long)next-(long)now));
+#endif
 				spin_unlock(&ifp->lock);
 
 				if (deprecate) {
@@ -1822,17 +3351,118 @@
 					in6_ifa_put(ifp);
 					goto restart;
 				}
+#ifdef CONFIG_IPV6_PRIVACY
+			} else if ((ifp->flags&IFA_F_TEMPORARY) &&
+				   !(ifp->flags&IFA_F_TENTATIVE)) {
+				if (age >= ifp->prefered_lft - regen_advance) {
+					struct inet6_ifaddr *ifpub = ifp->ifpub;
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+					ADBG3((KERN_DEBUG
+					       "addrconf_verify(): "
+					       "ifp->addr=%s, "
+					       "prefered_lft(%u)-regen_advance(%lu) <= age(%lu) < prefered_lft(%u), "
+					       "regen_count=%d, next=%ld\n",
+					       abuf, ifp->prefered_lft, regen_advance, age, 
+					       ifp->prefered_lft, ifp->regen_count, (long)next-(long)now));
+#endif
+					if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
+						next = ifp->tstamp + ifp->prefered_lft * HZ;
+					if (!ifp->regen_count && ifpub) {
+						ifp->regen_count++;
+						in6_ifa_hold(ifp);
+						in6_ifa_hold(ifpub);
+						spin_unlock(&ifp->lock);
+						write_unlock(&addrconf_hash_lock);
+						ipv6_create_tempaddr(ifpub, ifp);
+						in6_ifa_put(ifpub);
+						in6_ifa_put(ifp);
+						goto restart;
+					}
+				} else if (time_before(ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ, next))
+					next = ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ;
+				spin_unlock(&ifp->lock);
+#endif
 			} else {
 				/* ifp->prefered_lft <= ifp->valid_lft */
 				if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
 					next = ifp->tstamp + ifp->prefered_lft * HZ;
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+ 				ADBG3((KERN_DEBUG
+				       "addrconf_verify(): "
+				       "ifp->addr=%s, "
+				       "age(%lu) <= prefered_lft(%u) (<= valid_lft(%u)), "
+				       "next=%ld\n",
+				       abuf, age, ifp->prefered_lft, ifp->valid_lft, (long)next-(long)now));
+#endif
 				spin_unlock(&ifp->lock);
 			}
 		}
 		write_unlock(&addrconf_hash_lock);
 	}
+#ifdef CONFIG_IPV6_PREFIXLIST
+	/*
+	 * We need to expire prefixes even if no addresses are deleted in the
+	 * loop above, since autoconfiguration may not be set in all router
+	 * advertisements.
+	 */
+	read_lock(&dev_base_lock);
+	for (dev = dev_base; dev; dev = dev->next) {
+		unsigned long age;
+		if (!(idev = __in6_dev_get(dev))) {
+			continue;
+		}
+		read_lock_bh(&idev->lock);
+		write_lock_bh(&idev->prefix_lock);
+		if (list_empty(&idev->prefix_list)) {
+			write_unlock_bh(&idev->prefix_lock);
+			read_unlock_bh(&idev->lock);
+			continue;
+		}
+		list_for_each_safe(pos, n, &idev->prefix_list) {
+			pfx = list_entry(pos, struct inet6_prefix, list);
+			if (pfx->lifetime != PINFO_VALID_LIFETIME_INFINITE) {
+#ifdef CONFIG_IPV6_PREFIXLIST_DEBUG
+#ifndef CONFIG_IPV6_ACONF_DEBUG
+				char abuf[64];
+#endif
+				in6_ntop(&pfx->prefix, abuf);
+#endif
+				age = (now - pfx->timestamp) / HZ;
+				if (age > pfx->lifetime) {
+#ifdef CONFIG_IPV6_PREFIXLIST_DEBUG
+					printk(KERN_INFO "%s: deleting prefix %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x/%d, lifetime = %d\n",
+					__FUNCTION__, abuf, pfx->prefix_len, pfx->lifetime);
+#endif
+					list_del(&pfx->list);
+					kfree(pfx);
+				} else if (time_before(pfx->timestamp + pfx->lifetime * HZ, next))
+					next = pfx->timestamp + pfx->lifetime * HZ;
+			}
+		}
+		write_unlock_bh(&idev->prefix_lock);
+		read_unlock_bh(&idev->lock);
+	}
+	read_unlock(&dev_base_lock);
+#endif
 
-	addr_chk_timer.expires = time_before(next, jiffies + HZ) ? jiffies + HZ : next;
+	if (time_before(now + HZ/2, jiffies)) {
+		ADBG1((KERN_WARNING 
+		       "addrconf_verify(): too slow; jiffies - now = %lu\n",
+		       jiffies - now));
+	}
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+	/* don't fire too frequently */
+	ADBG3((KERN_DEBUG
+	       "addrconf_verify(): new timer: %lu (jiffies = %lu, after %ld sec)\n",
+	       time_before(next, jiffies + HZ/2) ? jiffies + HZ/2 : next,
+	       jiffies,
+	       time_before(next, jiffies + HZ/2) ? HZ/2 : ((long)next - (long)jiffies)/HZ
+	));
+#endif
+#ifdef CONFIG_IPV6_PREFIXLIST
+	ipv6_expire_prefixes();
+#endif
+	addr_chk_timer.expires = time_before(next, jiffies + HZ/2) ? jiffies + HZ/2 : next;
 	add_timer(&addr_chk_timer);
 	spin_unlock_bh(&addrconf_verify_lock);
 }
@@ -2002,6 +3632,10 @@
 	array[DEVCONF_REGEN_MAX_RETRY] = cnf->regen_max_retry;
 	array[DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor;
 #endif
+	array[DEVCONF_MAX_ADDRESSES] = cnf->max_addresses;
+#ifdef CONFIG_IPV6_NODEINFO
+	array[DEVCONF_ACCEPT_NI] = cnf->accept_ni;
+#endif
 }
 
 static int inet6_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
@@ -2114,8 +3748,9 @@
 			struct in6_addr addr;
 
 			ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
-			if (!ipv6_addr_any(&addr))
+			if (!ipv6_addr_any(&addr)) {
 				ipv6_dev_ac_dec(ifp->idev->dev, &addr);
+			}
 		}
 		if (!ipv6_chk_addr(&ifp->addr, NULL))
 			ip6_rt_addr_del(&ifp->addr, ifp->idev->dev);
@@ -2129,6 +3764,7 @@
 int addrconf_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
 			   void *buffer, size_t *lenp)
 {
+	/* XXX: race */
 	int *valp = ctl->data;
 	int val = *valp;
 	int ret;
@@ -2136,19 +3772,14 @@
 	ret = proc_dointvec(ctl, write, filp, buffer, lenp);
 
 	if (write && *valp != val && valp != &ipv6_devconf_dflt.forwarding) {
-		struct inet6_dev *idev = NULL;
-
-		if (valp != &ipv6_devconf.forwarding) {
-			idev = (struct inet6_dev *)ctl->extra1;
-			if (idev == NULL)
-				return ret;
-		} else
-			ipv6_devconf_dflt.forwarding = ipv6_devconf.forwarding;
-
-		addrconf_forward_change(idev);
-
-		if (*valp)
+		if (valp == &ipv6_devconf.forwarding)
+			addrconf_forward_change();
+		else
+			dev_forward_change((struct inet6_dev*)ctl->extra1);
+		if (*valp) {
+			ADBG3((KERN_DEBUG "Purge default routes(0)\n"));
 			rt6_purge_dflt_routers(0);
+		}
 	}
 
         return ret;
@@ -2157,7 +3788,7 @@
 static struct addrconf_sysctl_table
 {
 	struct ctl_table_header *sysctl_header;
-	ctl_table addrconf_vars[11];
+	ctl_table addrconf_vars[19];
 	ctl_table addrconf_dev[2];
 	ctl_table addrconf_conf_dir[2];
 	ctl_table addrconf_proto_dir[2];
@@ -2204,6 +3835,37 @@
          &ipv6_devconf.rtr_solicit_delay, sizeof(int), 0644, NULL,
          &proc_dointvec_jiffies},
 
+#ifdef CONFIG_IPV6_NODEINFO
+	{NET_IPV6_ACCEPT_NI, "accept_ni",
+         &ipv6_devconf.accept_ni, sizeof(int), 0644, NULL,
+         &proc_dointvec},
+#endif
+
+#ifdef CONFIG_IPV6_PRIVACY
+	{NET_IPV6_USE_TEMPADDR, "use_tempaddr",
+	 &ipv6_devconf.use_tempaddr, sizeof(int), 0644, NULL,
+	 &proc_dointvec},
+
+	{NET_IPV6_TEMP_VALID_LFT, "temp_valid_lft",
+	 &ipv6_devconf.temp_valid_lft, sizeof(int), 0644, NULL,
+	 &proc_dointvec},
+
+	{NET_IPV6_TEMP_PREFERED_LFT, "temp_prefered_lft",
+	 &ipv6_devconf.temp_prefered_lft, sizeof(int), 0644, NULL,
+	 &proc_dointvec},
+
+	{NET_IPV6_REGEN_MAX_RETRY, "regen_max_retry",
+	 &ipv6_devconf.regen_max_retry, sizeof(int), 0644, NULL,
+	 &proc_dointvec},
+
+	{NET_IPV6_MAX_DESYNC_FACTOR, "max_desync_factor",
+	 &ipv6_devconf.max_desync_factor, sizeof(int), 0644, NULL,
+	 &proc_dointvec},
+#endif
+	{NET_IPV6_MAX_ADDRESSES, "max_addresses",
+	 &ipv6_devconf.max_addresses, sizeof(int), 0644, NULL,
+	 &proc_dointvec},
+
 	{0}},
 
 	{{NET_PROTO_CONF_ALL, "all", NULL, 0, 0555, addrconf_sysctl.addrconf_vars},{0}},
@@ -2222,7 +3884,7 @@
 	if (t == NULL)
 		return;
 	memcpy(t, &addrconf_sysctl, sizeof(*t));
-	for (i=0; i<sizeof(t->addrconf_vars)/sizeof(t->addrconf_vars[0])-1; i++) {
+	for (i=0; t->addrconf_vars[i].ctl_name; i++) {
 		t->addrconf_vars[i].data += (char*)p - (char*)&ipv6_devconf;
 		t->addrconf_vars[i].de = NULL;
 		t->addrconf_vars[i].extra1 = idev; /* embedded; no ref */
@@ -2283,9 +3945,36 @@
 
 void __init addrconf_init(void)
 {
+#ifdef CONFIG_IPV6_PRIVACY
+	unsigned long regen_advance;
+#endif
 #ifdef MODULE
 	struct net_device *dev;
+#endif
+
+#ifdef CONFIG_IPV6_PRIVACY
+	struct crypto_tfm *tfm = crypto_alloc_tfm("md5", 0);
+	if (tfm != NULL) {
+		spin_lock(&md5_tfm_lock);
+		if (md5_tfm == NULL) {
+			md5_tfm = tfm;
+			spin_unlock(&md5_tfm_lock);
+		} else {
+			spin_unlock(&md5_tfm_lock);
+			crypto_free_tfm(tfm);
+		}
+	} else {
+		printk(KERN_WARNING
+			"failed to load transform for md5\n");
+	}
+
+	regen_advance = ipv6_devconf.regen_max_retry * ipv6_devconf.dad_transmits * HZ; /* XXX */
+	get_random_bytes(&desync_factor, sizeof(desync_factor));
+	desync_factor %= MAX_DESYNC_FACTOR * HZ < TEMP_VALID_LIFETIME * HZ - regen_advance ? 
+				MAX_DESYNC_FACTOR * HZ : TEMP_VALID_LIFETIME * HZ - regen_advance;
+#endif
 
+#ifdef MODULE
 	/* This takes sense only during module load. */
 	rtnl_lock();
 	for (dev = dev_base; dev; dev = dev->next) {
@@ -2311,6 +4000,10 @@
 
 #ifdef CONFIG_PROC_FS
 	proc_net_create("if_inet6", 0, iface_proc_info);
+	proc_net_create("addrselect_label_table", 0, ipv6_addrselect_label_proc_info);
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+	proc_net_create("if_inet6_debug", 0, iface_debug_proc_info);
+#endif
 #endif
 	
 	addrconf_verify(0);
@@ -2320,6 +4013,7 @@
 		register_sysctl_table(addrconf_sysctl.addrconf_root_dir, 0);
 	addrconf_sysctl_register(NULL, &ipv6_devconf_dflt);
 #endif
+        ipv6_addrselect_init();
 }
 
 #ifdef MODULE
@@ -2334,7 +4028,7 @@
 #ifdef CONFIG_SYSCTL
 	addrconf_sysctl_unregister(&ipv6_devconf_dflt);
 	addrconf_sysctl_unregister(&ipv6_devconf);
-#endif
+#endif 
 
 	rtnl_lock();
 
@@ -2359,7 +4053,9 @@
 
 			bifa = ifa;
 			ifa = ifa->lst_next;
-			printk(KERN_DEBUG "bug: IPv6 address leakage detected: ifa=%p\n", bifa);
+			ADBG1((KERN_DEBUG 
+			       "bug: IPv6 address leakage detected: ifa=%p\n", 
+			       bifa));
 			/* Do not free it; something is wrong.
 			   Now we can investigate it with debugger.
 			 */
@@ -2371,7 +4067,19 @@
 
 	rtnl_unlock();
 
+#ifdef CONFIG_IPV6_PRIVACY
+	spin_unlock(&md5_tfm_lock);
+	tfm = md5_tfm;
+	md5_tfm = NULL;
+	spin_unlock(&md5_tfm_lock);
+	if (tfm != NULL)
+		crypto_free_tfm(tfm);
+#endif
+
 #ifdef CONFIG_PROC_FS
+#ifdef CONFIG_IPV6_ACONF_DEBUG
+	proc_net_remove("if_inet6_debug");
+#endif
 	proc_net_remove("if_inet6");
 #endif
 }
diff -urN linux-2.4.29/net/ipv6/af_inet6.c linux-2.4.29-uc1/net/ipv6/af_inet6.c
--- linux-2.4.29/net/ipv6/af_inet6.c	2005-01-19 14:10:14.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/af_inet6.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: af_inet6.c,v 1.42 2003/11/12 05:12:01 yoshfuji Exp $ */
+
 /*
  *	PF_INET6 socket protocol family
  *	Linux INET6 implementation 
@@ -41,6 +43,7 @@
 #include <linux/stat.h>
 #include <linux/init.h>
 #include <linux/version.h>
+#include <linux/usagi-version.h>
 
 #include <linux/inet.h>
 #include <linux/netdevice.h>
@@ -76,17 +79,29 @@
 /* IPv6 procfs goodies... */
 
 #ifdef CONFIG_PROC_FS
+extern int afinet6_getversion(char *, char **, off_t, int);
 extern int anycast6_get_info(char *, char **, off_t, int);
 extern int raw6_get_info(char *, char **, off_t, int);
 extern int tcp6_get_info(char *, char **, off_t, int);
 extern int udp6_get_info(char *, char **, off_t, int);
 extern int afinet6_get_info(char *, char **, off_t, int);
 extern int afinet6_get_snmp(char *, char **, off_t, int);
+extern int rt6_get_dfltrt(char *, char **, off_t, int);
+struct proc_dir_entry *proc_net_devsnmp6 = NULL;
+#endif
+
+#ifdef CONFIG_IPV6_ZONE
+int ipv6_zone_ioctl(unsigned int cmd, void *arg);
 #endif
 
 #ifdef CONFIG_SYSCTL
 extern void ipv6_sysctl_register(void);
 extern void ipv6_sysctl_unregister(void);
+
+int sysctl_ipv6_bindv6only;
+#ifdef CONFIG_IPV6_RESTRICTED_DOUBLE_BIND
+int sysctl_ipv6_bindv6only_restriction;
+#endif
 #endif
 
 int sysctl_ipv6_bindv6only;
@@ -253,6 +268,8 @@
 
 	/* Check if the address belongs to the host. */
 	if (addr_type == IPV6_ADDR_MAPPED) {
+		if (sk->net_pinfo.af_inet6.ipv6only)
+			return -EADDRNOTAVAIL;
 		v4addr = addr->sin6_addr.s6_addr32[3];
 		if (inet_addr_type(v4addr) != RTN_LOCAL)
 			return -EADDRNOTAVAIL;
@@ -291,11 +308,13 @@
 			sk->bound_dev_if = addr->sin6_scope_id;
 		}
 
+#ifndef CONFIG_IPV6_LOOSE_SCOPE_ID
 		/* Binding to link-local address requires an interface */
 		if (sk->bound_dev_if == 0) {
 			release_sock(sk);
 			return -EINVAL;
 		}
+#endif
 	}
 
 	sk->rcv_saddr = v4addr;
@@ -324,6 +343,7 @@
 	sk->sport = ntohs(sk->num);
 	sk->dport = 0;
 	sk->daddr = 0;
+
 	release_sock(sk);
 
 	return 0;
@@ -391,19 +411,14 @@
 		if (((1<<sk->state)&(TCPF_CLOSE|TCPF_SYN_SENT)) && peer == 1)
 			return -ENOTCONN;
 		sin->sin6_port = sk->dport;
-		memcpy(&sin->sin6_addr, &sk->net_pinfo.af_inet6.daddr,
-		       sizeof(struct in6_addr));
+		ipv6_addr_copy(&sin->sin6_addr, &sk->net_pinfo.af_inet6.daddr);
 		if (sk->net_pinfo.af_inet6.sndflow)
 			sin->sin6_flowinfo = sk->net_pinfo.af_inet6.flow_label;
 	} else {
 		if (ipv6_addr_type(&sk->net_pinfo.af_inet6.rcv_saddr) == IPV6_ADDR_ANY)
-			memcpy(&sin->sin6_addr, 
-			       &sk->net_pinfo.af_inet6.saddr,
-			       sizeof(struct in6_addr));
+			ipv6_addr_copy(&sin->sin6_addr, &sk->net_pinfo.af_inet6.saddr);
 		else
-			memcpy(&sin->sin6_addr, 
-			       &sk->net_pinfo.af_inet6.rcv_saddr,
-			       sizeof(struct in6_addr));
+			ipv6_addr_copy(&sin->sin6_addr, &sk->net_pinfo.af_inet6.rcv_saddr);
 
 		sin->sin6_port = sk->sport;
 	}
@@ -454,6 +469,16 @@
 		return addrconf_del_ifaddr((void *) arg);
 	case SIOCSIFDSTADDR:
 		return addrconf_set_dstaddr((void *) arg);
+#ifdef CONFIG_IPV6_ZONE
+	case SIOCSIFZONE:
+		return ipv6_zone_ioctl(cmd, (void *) arg);
+	case SIOCGIFZONE:
+		return ipv6_zone_ioctl(cmd, (void *) arg);
+#endif
+	case SIOCSDADDRLABEL:
+		return addrconf_label_ioctl(cmd, (void *) arg);
+	case SIOCDDADDRLABEL:
+		return addrconf_label_ioctl(cmd, (void *) arg);
 	default:
 		if ((cmd >= SIOCDEVPRIVATE) &&
 		    (cmd <= (SIOCDEVPRIVATE + 15)))
@@ -538,9 +563,14 @@
 #ifdef MODULE
 int ipv6_unload(void)
 {
+#ifdef CONFIG_IPV6_DEBUG
+	printk(KERN_DEBUG "%s: unloadable=%d, usecount=%d\n",
+			__FUNCTION__,
+			unloadable, atomic_read(&(__this_module.uc.usecount)));
+#endif
 	if (!unloadable) return 1;
 	/* We keep internally 3 raw sockets */
-	return atomic_read(&(__this_module.uc.usecount)) - 3;
+	return atomic_read(&(__this_module.uc.usecount)) == 3 ? 0 : -EBUSY;
 }
 #endif
 
@@ -634,7 +664,7 @@
 	__this_module.can_unload = &ipv6_unload;
 #endif
 
-	printk(KERN_INFO "IPv6 v0.8 for NET4.0\n");
+	printk(KERN_INFO "IPv6 v0.8 (" USAGI_RELEASE ") for NET4.0\n");
 
 	if (sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb))
 	{
@@ -673,6 +703,8 @@
 	/* Create /proc/foo6 entries. */
 #ifdef CONFIG_PROC_FS
 	err = -ENOMEM;
+	if (!proc_net_create("inet6_version", 0, afinet6_getversion))
+		goto proc_inet6version_fail;
 	if (!proc_net_create("raw6", 0, raw6_get_info))
 		goto proc_raw6_fail;
 	if (!proc_net_create("tcp6", 0, tcp6_get_info))
@@ -685,25 +717,44 @@
 		goto proc_snmp6_fail;
 	if (!proc_net_create("anycast6", 0, anycast6_get_info))
 		goto proc_anycast6_fail;
+	if (!(proc_net_create("rt6_default", 0, rt6_get_dfltrt)))
+		goto proc_dfltrt6_fail;
+	if (!(proc_net_devsnmp6 = proc_mkdir("dev_snmp6", proc_net)))
+		goto proc_devsnmp6_fail;
 #endif
 	ipv6_netdev_notif_init();
 	ipv6_packet_init();
 	ip6_route_init();
 	ip6_flowlabel_init();
 	addrconf_init();
+#ifndef CONFIG_NET_IPIP_IPV6
 	sit_init();
+#endif
 	ipv6_frag_init();
 
 	/* Init v6 transport protocols. */
 	udpv6_init();
 	tcpv6_init();
 
+#if !defined(CONFIG_IPV6) && defined(CONFIG_IPV6_IM)
+	inter_module_register(IM_ICMPV6_SEND, THIS_MODULE, &icmpv6_send);
+	inter_module_register(IM_IPV6_DEVCONF, THIS_MODULE, &ipv6_devconf);
+#endif
+
 	/* Now the userspace is allowed to create INET6 sockets. */
 	(void) sock_register(&inet6_family_ops);
+
+#ifdef CONFIG_IPV6_IPV6_TUNNEL
+	ipv6_ipv6_tunnel_init();
+#endif
 	
 	return 0;
 
 #ifdef CONFIG_PROC_FS
+proc_devsnmp6_fail:
+	proc_net_remove("snmp6");
+ proc_dfltrt6_fail:
+	proc_net_remove("rt6_default");
 proc_anycast6_fail:
 	proc_net_remove("anycast6");
 proc_snmp6_fail:
@@ -715,6 +766,8 @@
 proc_tcp6_fail:
         proc_net_remove("raw6");
 proc_raw6_fail:
+	proc_net_remove("inet6_version");
+proc_inet6version_fail:
 	igmp6_cleanup();
 #endif
 igmp_fail:
@@ -735,13 +788,24 @@
 {
 	/* First of all disallow new sockets creation. */
 	sock_unregister(PF_INET6);
+#if !defined(CONFIG_IPV6) && defined(CONFIG_IPV6_IM)
+	inter_module_unregister(IM_IPV6_DEVCONF);
+	inter_module_unregister(IM_ICMPV6_SEND);
+#endif
 #ifdef CONFIG_PROC_FS
+	proc_net_remove("inet6_version");
 	proc_net_remove("raw6");
 	proc_net_remove("tcp6");
 	proc_net_remove("udp6");
 	proc_net_remove("sockstat6");
 	proc_net_remove("snmp6");
 	proc_net_remove("anycast6");
+	proc_net_remove("rt6_default");
+	if (proc_net_devsnmp6)
+		remove_proc_entry("dev_snmp6", proc_net);
+#endif
+#ifdef CONFIG_IPV6_IPV6_TUNNEL
+	ipv6_ipv6_tunnel_exit();
 #endif
 	/* Cleanup code parts. */
 	sit_cleanup();
diff -urN linux-2.4.29/net/ipv6/anycast.c linux-2.4.29-uc1/net/ipv6/anycast.c
--- linux-2.4.29/net/ipv6/anycast.c	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv6/anycast.c	2005-06-14 02:11:52.000000000 +0100
@@ -45,31 +45,7 @@
 /* Big ac list lock for all the sockets */
 static rwlock_t ipv6_sk_ac_lock = RW_LOCK_UNLOCKED;
 
-/* XXX ip6_addr_match() and ip6_onlink() really belong in net/core.c */
-
-static int
-ip6_addr_match(struct in6_addr *addr1, struct in6_addr *addr2, int prefix)
-{
-	__u32	mask;
-	int	i;
-
-	if (prefix > 128 || prefix < 0)
-		return 0;
-	if (prefix == 0)
-		return 1;
-	for (i=0; i<4; ++i) {
-		if (prefix >= 32)
-			mask = ~0;
-		else
-			mask = htonl(~0 << (32 - prefix));
-		if ((addr1->s6_addr32[i] ^ addr2->s6_addr32[i]) & mask)
-			return 0;
-		prefix -= 32;
-		if (prefix <= 0)
-			break;
-	}
-	return 1;
-}
+/* XXX ip6_onlink() really belong in net/core.c */
 
 static int
 ip6_onlink(struct in6_addr *addr, struct net_device *dev)
@@ -84,8 +60,8 @@
 	if (idev) {
 		read_lock_bh(&idev->lock);
 		for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
-			onlink = ip6_addr_match(addr, &ifa->addr,
-					ifa->prefix_len);
+			onlink = !ipv6_prefix_cmp(addr, &ifa->addr,
+						  ifa->prefix_len);
 			if (onlink)
 				break;
 		}
diff -urN linux-2.4.29/net/ipv6/Config.in linux-2.4.29-uc1/net/ipv6/Config.in
--- linux-2.4.29/net/ipv6/Config.in	2001-12-21 17:42:05.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/Config.in	2005-06-14 02:11:52.000000000 +0100
@@ -1,10 +1,92 @@
+# $USAGI: Config.in,v 1.80 2004/01/31 09:27:11 yoshfuji Exp $
 #
 # IPv6 configuration
-# 
+#
 
-#bool '    IPv6: flow policy support' CONFIG_RT6_POLICY
-#bool '    IPv6: firewall support' CONFIG_IPV6_FIREWALL
+#mainmenu_option next_comment
+#comment '  IPv6 Configuration'
 
+# --- overall ---
+bool '    IPv6: Verbose debugging messages' CONFIG_IPV6_DEBUG
+
+# --- module interface ---
+if [ "$CONFIG_IPV6" = "m" ]; then
+   bool '    IPv6: inter-module support.' CONFIG_IPV6_IM
+   if [ "$CONFIG_NET_IPGRE" != "n" ]; then
+      bool '      IPv6: enable gre tunnel support with modulized ipv6' CONFIG_IPV6_MODULE_IP_GRE
+   fi
+fi
+
+# --- IPv6 Specification (RFC2460) and Addressing Architecture (RFC2373) ---
+bool '    IPv6: Scoped routing' CONFIG_IPV6_ZONE
+if [ "$CONFIG_IPV6_ZONE" = "y" ]; then
+   bool '      IPv6: Site-border routing by default' CONFIG_IPV6_ZONE_SITELOCAL
+fi
+#bool '    IPv6: Loose scope_id' CONFIG_IPV6_LOOSE_SCOPE_ID
+bool '    IPv6: drop packets with fake ipv4-mapped address(es)' CONFIG_IPV6_DROP_FAKE_V4MAPPED
+if [ "$CONFIG_IPV6" = "y" -o "$CONFIG_IPV6_IM" = "y" ]; then
+   bool '    IPv6: Restrict "double binding" only for same user' CONFIG_IPV6_RESTRICTED_DOUBLE_BIND
+fi
+bool '    IPv6: 6to4-address in nexthop support.' CONFIG_IPV6_6TO4_NEXTHOP
+bool '    IPv6: Privacy Extensions (RFC 3041) support' CONFIG_IPV6_PRIVACY
+dep_tristate '    IPv6: IPv6 over IPv6 Tunneling (EXPERIMENTAL)' CONFIG_IPV6_IPV6_TUNNEL m
+
+# --- NDP (RFC2461) ---
+bool '    IPv6: Prefix List support' CONFIG_IPV6_PREFIXLIST
+define_bool CONFIG_IPV6_NDISC_NEW y
+if [ "$CONFIG_IPV6_DEBUG" = "y" ]; then
+   bool '    IPv6: Neighbor Discovery debugging' CONFIG_IPV6_NDISC_DEBUG
+fi
+
+# --- Stateless Address Configuration (RFC2462) ---
+if [ "$CONFIG_IPV6_DEBUG" = "y" ]; then
+   bool '    IPv6: Address Autoconfigration debugging' CONFIG_IPV6_ACONF_DEBUG
+   if [ "$CONFIG_IPV6_ACONF_DEBUG" = "y" ]; then
+      bool '      IPv6: Debug on source address selection' CONFIG_IPV6_ACONF_DEBUG_SADDR
+   fi
+fi
+
+# --- Routing ---
+if [ "$CONFIG_IPV6_DEBUG" = "y" ]; then
+   bool '    IPv6: Routing Information debugging' CONFIG_IPV6_RT6_DEBUG
+fi
+bool '    IPv6: sub-tree in routing table support (just for testing)' CONFIG_IPV6_SUBTREES
+bool '    IPv6: default router preference' CONFIG_IPV6_ROUTER_PREF
+if [ "$CONFIG_IPV6_ROUTER_PREF" != "n" ]; then
+	#bool '    IPv6: new round-robin architecture' CONFIG_IPV6_NEW_ROUNDROBIN
+	define_bool CONFIG_IPV6_NEW_ROUNDROBIN y
+	bool '      IPv6: Route Information Option support' CONFIG_IPV6_ROUTE_INFO
+fi
+
+# --- MLD (RFC2710) ---
+if [ "$CONFIG_IPV6_DEBUG" = "y" ]; then
+   bool '    IPv6: Multicast Listener Discovery debugging' CONFIG_IPV6_MLD6_DEBUG
+fi
+bool '    IPv6: disable optimization MLD6 Done message' CONFIG_IPV6_MLD6_ALL_DONE
+
+# --- Node Information Queries (Internet Draft) ---
+bool '    IPv6: enable Node Information Queries' CONFIG_IPV6_NODEINFO
+if [ "$CONFIG_IPV6_NODEINFO" = "y" ]; then
+   if [ "$CONFIG_IPV6_DEBUG" = "y" ]; then
+       bool '      IPv6: Node Information Queries debugging' CONFIG_IPV6_NODEINFO_DEBUG
+   fi
+   bool '      IPv6: regard NIS domain as DNS domain' CONFIG_IPV6_NODEINFO_USE_UTS_DOMAIN
+fi
+
+# --- Socket Interface (RFC2292/3542, RFC2553/3493) ---
+
+# --- Filtering ---
 if [ "$CONFIG_NETFILTER" != "n" ]; then
    source net/ipv6/netfilter/Config.in
 fi
+
+# --- Misc. ---
+# 
+#bool '    IPv6: flow policy support' CONFIG_RT6_POLICY
+#bool '    IPv6: firewall support' CONFIG_IPV6_FIREWALL
+
+# -- IPsec --
+
+# --- Mobile IP ---
+
+#endmenu
diff -urN linux-2.4.29/net/ipv6/datagram.c linux-2.4.29-uc1/net/ipv6/datagram.c
--- linux-2.4.29/net/ipv6/datagram.c	2005-01-19 14:10:14.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/datagram.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: datagram.c,v 1.10 2002/10/03 23:05:05 yoshfuji Exp $ */
+
 /*
  *	common UDP/RAW code
  *	Linux INET6 implementation 
@@ -78,7 +80,7 @@
 
 	iph = (struct ipv6hdr*)skb_put(skb, sizeof(struct ipv6hdr));
 	skb->nh.ipv6h = iph;
-	memcpy(&iph->daddr, fl->fl6_dst, 16);
+	ipv6_addr_copy(&iph->daddr, fl->fl6_dst);
 
 	serr = SKB_EXT_ERR(skb);
 	serr->ee.ee_errno = err;
@@ -138,7 +140,8 @@
 		sin->sin6_port = serr->port; 
 		sin->sin6_scope_id = 0;
 		if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) {
-			memcpy(&sin->sin6_addr, skb->nh.raw + serr->addr_offset, 16);
+			ipv6_addr_copy(&sin->sin6_addr, 
+				       (struct in6_addr *)(skb->nh.raw + serr->addr_offset));
 			if (sk->net_pinfo.af_inet6.sndflow)
 				sin->sin6_flowinfo = *(u32*)(skb->nh.raw + serr->addr_offset - 24) & IPV6_FLOWINFO_MASK;
 			if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
@@ -160,7 +163,7 @@
 		sin->sin6_flowinfo = 0;
 		sin->sin6_scope_id = 0;
 		if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) {
-			memcpy(&sin->sin6_addr, &skb->nh.ipv6h->saddr, 16);
+			ipv6_addr_copy(&sin->sin6_addr, &skb->nh.ipv6h->saddr);
 			if (sk->net_pinfo.af_inet6.rxopt.all)
 				datagram_recv_ctl(sk, msg, skb);
 			if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
@@ -244,12 +247,19 @@
 		u8 *ptr = skb->nh.raw + opt->dst1;
 		put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr);
 	}
+
+	if (np->recvopt.tclass) {
+		struct ipv6hdr *ipv6h = skb->nh.ipv6h;
+		int tclass = ((ipv6h->tclass1 << 4) | (ipv6h->tclass2_flow[0] >> 4)) & 0xff;
+		put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
+	}
+
 	return 0;
 }
 
 int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
 		      struct ipv6_txoptions *opt,
-		      int *hlimit)
+		      int *hlimit, int *tclass)
 {
 	struct in6_pktinfo *src_info;
 	struct cmsghdr *cmsg;
@@ -425,6 +435,14 @@
 			*hlimit = *(int *)CMSG_DATA(cmsg);
 			break;
 
+		case IPV6_TCLASS:
+			if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
+				err = -EINVAL;
+				goto exit_f;
+			}
+			*tclass = *(int *)CMSG_DATA(cmsg);
+			break;
+
 		default:
 			if (net_ratelimit())
 				printk(KERN_DEBUG "invalid cmsg type: %d\n", cmsg->cmsg_type);
diff -urN linux-2.4.29/net/ipv6/exthdrs.c linux-2.4.29-uc1/net/ipv6/exthdrs.c
--- linux-2.4.29/net/ipv6/exthdrs.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/exthdrs.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: exthdrs.c,v 1.40 2003/08/08 13:46:38 yoshfuji Exp $ */
+
 /*
  *	Extension Header handling for IPv6
  *	Linux INET6 implementation
@@ -20,6 +22,7 @@
  *				  tlv options.
  */
 
+#include <linux/autoconf.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/socket.h>
@@ -43,6 +46,8 @@
 
 #include <asm/uaccess.h>
 
+
+
 /*
  *	Parsing inbound headers.
  *
@@ -116,7 +121,7 @@
 	len -= 2;
 
 	while (len > 0) {
-		int optlen = skb->nh.raw[off+1]+2;
+		int optlen;
 
 		switch (skb->nh.raw[off]) {
 		case IPV6_TLV_PAD0:
@@ -124,10 +129,18 @@
 			break;
 
 		case IPV6_TLV_PADN:
+			if (len < 2)
+				goto bad;
+			optlen = skb->nh.raw[off+1]+2;
+			if (len < optlen)
+				goto bad;
 			break;
 
 		default: /* Other TLV code so scan list */
-			if (optlen > len)
+			if (len < 2)
+				goto bad;
+			optlen = skb->nh.raw[off+1]+2;
+			if (len < optlen)
 				goto bad;
 			for (curr=procs; curr->type >= 0; curr++) {
 				if (curr->type == skb->nh.raw[off]) {
@@ -160,7 +173,6 @@
  *****************************/
 
 struct tlvtype_proc tlvprocdestopt_lst[] = {
-	/* No destination options are defined now */
 	{-1,			NULL}
 };
 
@@ -205,7 +217,6 @@
 	struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
 	struct in6_addr *addr;
 	struct in6_addr daddr;
-	int addr_type;
 	int n, i;
 
 	struct ipv6_rt_hdr *hdr;
@@ -213,7 +224,10 @@
 
 	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
 	    !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
-		IP6_INC_STATS_BH(Ip6InHdrErrors);
+		struct inet6_dev *idev = in6_dev_get(skb->dev);
+		IP6_INC_STATS_BH(idev,Ip6InHdrErrors);
+		if (idev)
+			in6_dev_put(idev);
 		kfree_skb(skb);
 		return -1;
 	}
@@ -247,7 +261,7 @@
 
 	/*
 	 *	This is the routing header forwarding algorithm from
-	 *	RFC 1883, page 17.
+	 *	RFC 2460, page 15-16 in Section 4.4: Routing Header.
 	 */
 
 	n = hdr->hdrlen >> 1;
@@ -279,9 +293,8 @@
 	addr = rthdr->addr;
 	addr += i - 1;
 
-	addr_type = ipv6_addr_type(addr);
-
-	if (addr_type&IPV6_ADDR_MULTICAST) {
+	if ((ipv6_addr_type(addr) & IPV6_ADDR_MULTICAST) ||
+	    (ipv6_addr_type(&skb->nh.ipv6h->daddr) & IPV6_ADDR_MULTICAST)) {
 		kfree_skb(skb);
 		return -1;
 	}
@@ -333,6 +346,10 @@
    temporary (or permanent) backdoor.
    If listening socket set IPV6_RTHDR to 2, then we invert header.
                                                    --ANK (980729)
+
+   By the Mobile IPv6 specification Type 2 routing header MUST NOT be
+   inverted.
+                                                   --AJT (20020917)
  */
 
 struct ipv6_txoptions *
@@ -372,7 +389,7 @@
 	memcpy(opt->srcrt, hdr, sizeof(*hdr));
 	irthdr = (struct rt0_hdr*)opt->srcrt;
 	/* Obsolete field, MBZ, when originated by us */
-	irthdr->bitmap = 0;
+	irthdr->reserved = 0;
 	opt->srcrt->segments_left = n;
 	for (i=0; i<n; i++)
 		memcpy(irthdr->addr+i, rthdr->addr+(n-1-i), 16);
@@ -451,20 +468,19 @@
 	{-1,			NULL}
 };
 
-int ipv6_parse_exthdrs(struct sk_buff **skb_in, int nhoff)
+int ipv6_parse_exthdrs(struct sk_buff **skb_in, int nhoff, u8* nexthdr)
 {
 	struct hdrtype_proc *hdrt;
-	u8 nexthdr = (*skb_in)->nh.raw[nhoff];
 
 restart:
 	for (hdrt=hdrproc_lst; hdrt->type >= 0; hdrt++) {
-		if (hdrt->type == nexthdr) {
+		if (hdrt->type == *nexthdr) {
 			if ((nhoff = hdrt->func(skb_in, nhoff)) >= 0) {
-				nexthdr = (*skb_in)->nh.raw[nhoff];
+				*nexthdr = (*skb_in)->nh.raw[nhoff];
 				goto restart;
 			}
 			return -1;
-		}
+		} 
 	}
 	return nhoff;
 }
@@ -474,7 +490,8 @@
   Hop-by-hop options.
  **********************************/
 
-/* Router Alert as of draft-ietf-ipngwg-ipv6router-alert-04 */
+
+/* RFC 2711 : IPv6 Router Alert Option */
 
 static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
 {
@@ -511,7 +528,10 @@
 	}
 
 	if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
-		IP6_INC_STATS_BH(Ip6InTruncatedPkts);
+		struct inet6_dev *idev = in6_dev_get(skb->dev);
+		IP6_INC_STATS_BH(idev,Ip6InTruncatedPkts);
+		if (idev)
+			in6_dev_put(idev);
 		goto drop;
 	}
 	if (pkt_len + sizeof(struct ipv6hdr) < skb->len) {
@@ -553,6 +573,7 @@
 u8 *ipv6_build_rthdr(struct sk_buff *skb, u8 *prev_hdr,
 		     struct ipv6_rt_hdr *opt, struct in6_addr *addr)
 {
+	struct inet6_skb_parm *parm = (struct inet6_skb_parm*)skb->cb;
 	struct rt0_hdr *phdr, *ihdr;
 	int hops;
 
@@ -571,26 +592,30 @@
 
 	phdr->rt_hdr.nexthdr = *prev_hdr;
 	*prev_hdr = NEXTHDR_ROUTING;
+	parm->srcrt = (unsigned char*)phdr - skb->nh.raw;
 	return &phdr->rt_hdr.nexthdr;
 }
 
-static u8 *ipv6_build_exthdr(struct sk_buff *skb, u8 *prev_hdr, u8 type, struct ipv6_opt_hdr *opt)
+static u8 *ipv6_build_exthdr(struct sk_buff *skb, u8 *prev_hdr, u8 type, struct ipv6_opt_hdr *opt, __u16 *optoff)
 {
 	struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_put(skb, ipv6_optlen(opt));
 
 	memcpy(h, opt, ipv6_optlen(opt));
 	h->nexthdr = *prev_hdr;
 	*prev_hdr = type;
+	*optoff = (unsigned char*)h - skb->nh.raw;
 	return &h->nexthdr;
 }
 
 static u8 *ipv6_build_authhdr(struct sk_buff *skb, u8 *prev_hdr, struct ipv6_opt_hdr *opt)
 {
+	struct inet6_skb_parm *parm = (struct inet6_skb_parm*)skb->cb;
 	struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_put(skb, (opt->hdrlen+2)<<2);
 
 	memcpy(h, opt, (opt->hdrlen+2)<<2);
 	h->nexthdr = *prev_hdr;
 	*prev_hdr = NEXTHDR_AUTH;
+	parm->auth = (unsigned char*)h - skb->nh.raw;
 	return &h->nexthdr;
 }
 
@@ -598,10 +623,11 @@
 u8 *ipv6_build_nfrag_opts(struct sk_buff *skb, u8 *prev_hdr, struct ipv6_txoptions *opt,
 			  struct in6_addr *daddr, u32 jumbolen)
 {
+	struct inet6_skb_parm *parm = (struct inet6_skb_parm*)skb->cb;
 	struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb->data;
 
 	if (opt && opt->hopopt)
-		prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_HOP, opt->hopopt);
+		prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_HOP, opt->hopopt, &parm->hop);
 
 	if (jumbolen) {
 		u8 *jumboopt = (u8 *)skb_put(skb, 8);
@@ -624,7 +650,7 @@
 	}
 	if (opt) {
 		if (opt->dst0opt)
-			prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_DEST, opt->dst0opt);
+			prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_DEST, opt->dst0opt, &parm->dst0);
 		if (opt->srcrt)
 			prev_hdr = ipv6_build_rthdr(skb, prev_hdr, opt->srcrt, daddr);
 	}
@@ -633,21 +659,23 @@
 
 u8 *ipv6_build_frag_opts(struct sk_buff *skb, u8 *prev_hdr, struct ipv6_txoptions *opt)
 {
+	struct inet6_skb_parm *parm = (struct inet6_skb_parm*)skb->cb;
+
 	if (opt->auth)
 		prev_hdr = ipv6_build_authhdr(skb, prev_hdr, opt->auth);
 	if (opt->dst1opt)
-		prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_DEST, opt->dst1opt);
+		prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_DEST, opt->dst1opt, &parm->dst1);
 	return prev_hdr;
 }
 
 static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
-			    struct ipv6_rt_hdr *opt,
+			    struct ipv6_rt_hdr **opt,
 			    struct in6_addr **addr_p)
 {
 	struct rt0_hdr *phdr, *ihdr;
 	int hops;
 
-	ihdr = (struct rt0_hdr *) opt;
+	ihdr = (struct rt0_hdr *) *opt;
 	
 	phdr = (struct rt0_hdr *) skb_push(skb, (ihdr->rt_hdr.hdrlen + 1) << 3);
 	memcpy(phdr, ihdr, sizeof(struct rt0_hdr));
@@ -665,20 +693,20 @@
 	*proto = NEXTHDR_ROUTING;
 }
 
-static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv6_opt_hdr *opt)
+static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv6_opt_hdr **opt)
 {
-	struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, ipv6_optlen(opt));
+	struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, ipv6_optlen(*opt));
 
-	memcpy(h, opt, ipv6_optlen(opt));
+	memcpy(h, *opt, ipv6_optlen(*opt));
 	h->nexthdr = *proto;
 	*proto = type;
 }
 
-static void ipv6_push_authhdr(struct sk_buff *skb, u8 *proto, struct ipv6_opt_hdr *opt)
+static void ipv6_push_authhdr(struct sk_buff *skb, u8 *proto, struct ipv6_opt_hdr **opt)
 {
-	struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, (opt->hdrlen+2)<<2);
+	struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, ((*opt)->hdrlen+2)<<2);
 
-	memcpy(h, opt, (opt->hdrlen+2)<<2);
+	memcpy(h, *opt, ((*opt)->hdrlen+2)<<2);
 	h->nexthdr = *proto;
 	*proto = NEXTHDR_AUTH;
 }
@@ -688,19 +716,19 @@
 			  struct in6_addr **daddr)
 {
 	if (opt->srcrt)
-		ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
+		ipv6_push_rthdr(skb, proto, &opt->srcrt, daddr);
 	if (opt->dst0opt)
-		ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
+		ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, &opt->dst0opt);
 	if (opt->hopopt)
-		ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
+		ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, &opt->hopopt);
 }
 
 void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto)
 {
 	if (opt->dst1opt)
-		ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst1opt);
+		ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, &opt->dst1opt);
 	if (opt->auth)
-		ipv6_push_authhdr(skb, proto, opt->auth);
+		ipv6_push_authhdr(skb, proto, &opt->auth);
 }
 
 struct ipv6_txoptions *
@@ -740,6 +768,7 @@
 		 (nexthdr == NEXTHDR_ROUTING)	||
 		 (nexthdr == NEXTHDR_FRAGMENT)	||
 		 (nexthdr == NEXTHDR_AUTH)	||
+		 (nexthdr == NEXTHDR_ESP)	||
 		 (nexthdr == NEXTHDR_NONE)	||
 		 (nexthdr == NEXTHDR_DEST) );
 }
diff -urN linux-2.4.29/net/ipv6/icmp.c linux-2.4.29-uc1/net/ipv6/icmp.c
--- linux-2.4.29/net/ipv6/icmp.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/icmp.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: icmp.c,v 1.169 2003/11/24 11:03:18 yoshfuji Exp $ */
+
 /*
  *	Internet Control Message Protocol (ICMPv6)
  *	Linux INET6 implementation
@@ -48,6 +50,14 @@
 #include <linux/netdevice.h>
 #include <linux/icmpv6.h>
 
+#ifdef CONFIG_IPV6_NODEINFO
+#include <linux/utsname.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/crypto.h>
+#include <asm/scatterlist.h>
+#endif
+
 #include <net/ip.h>
 #include <net/sock.h>
 
@@ -168,6 +178,11 @@
  *	  (i.e. in the middle of some exthdr)
  *
  *	--ANK (980726)
+ *
+ * Note: We MUST send Parameter Problem even if it is not for the first
+ *       fragment.  See RFC2460.
+ *
+ *	--yoshfuji (2001/01/05)
  */
 
 static int is_ineligible(struct sk_buff *skb)
@@ -197,15 +212,20 @@
 /* 
  * Check the ICMP output rate limit 
  */
-static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
+static inline int icmpv6_xrlim_allow(struct sock *sk, int type, int code,
 				     struct flowi *fl)
 {
 	struct dst_entry *dst;
 	int res = 0;
 
 	/* Informational messages are not limited. */
-	if (type & ICMPV6_INFOMSG_MASK)
-		return 1;
+	if (type & ICMPV6_INFOMSG_MASK) {
+		/* but 'REFUSED' or 'UNKNOWN' NI Reply should be limited */
+		if (type != ICMPV6_NI_REPLY)
+			return 1;
+		if (!(code == ICMPV6_NI_REFUSED || code == ICMPV6_NI_UNKNOWN))
+			return 1;
+	}
 
 	/* Do not limit pmtu discovery, it would break it. */
 	if (type == ICMPV6_PKT_TOOBIG)
@@ -218,7 +238,7 @@
 	 */
 	dst = ip6_route_output(sk, fl);
 	if (dst->error) {
-		IP6_INC_STATS(Ip6OutNoRoutes);
+		IP6_INC_STATS(((struct inet6_dev *)NULL),Ip6OutNoRoutes);	/* XXX(?) */
 	} else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) {
 		res = 1;
 	} else {
@@ -261,6 +281,7 @@
 {
 	struct ipv6hdr *hdr = skb->nh.ipv6h;
 	struct sock *sk = icmpv6_socket->sk;
+	struct inet6_dev *idev;
 	struct in6_addr *saddr = NULL;
 	int iif = 0;
 	struct icmpv6_msg msg;
@@ -268,6 +289,10 @@
 	int addr_type = 0;
 	int len;
 
+	/*
+	 *	sanity check pointer in case of parameter problem
+	 */
+
 	if ((u8*)hdr < skb->head || (u8*)(hdr+1) > skb->tail)
 		return;
 
@@ -309,9 +334,11 @@
 	 *	Must not send if we know that source is Anycast also.
 	 *	for now we don't know that.
 	 */
-	if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
+	if ((addr_type == IPV6_ADDR_ANY) || 
+	    (addr_type & (IPV6_ADDR_MULTICAST|IPV6_ADDR_ANYCAST)) ||
+	    (saddr && ipv6_chk_acast_addr(0, saddr))) {
 		if (net_ratelimit())
-			printk(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n");
+			printk(KERN_DEBUG "icmpv6_send: unspec/anycast/mcast source\n");
 		return;
 	}
 
@@ -335,7 +362,7 @@
 	if (icmpv6_xmit_lock())
 		return;
 
-	if (!icmpv6_xrlim_allow(sk, type, &fl))
+	if (!icmpv6_xrlim_allow(sk, type, code, &fl))
 		goto out;
 
 	/*
@@ -364,11 +391,18 @@
 
 	msg.len = len;
 
-	ip6_build_xmit(sk, icmpv6_getfrag, &msg, &fl, len, NULL, -1,
+	ip6_build_xmit(sk, icmpv6_getfrag, &msg, &fl, len, NULL, -1, -1,
 		       MSG_DONTWAIT);
-	if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB)
-		(&(icmpv6_statistics[smp_processor_id()*2].Icmp6OutDestUnreachs))[type-1]++;
-	ICMP6_INC_STATS_BH(Icmp6OutMsgs);
+	idev = in6_dev_get(dev);
+	if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB) {
+		(&(icmpv6_statistics[smp_processor_id()*2].Icmp6OutDestUnreachs))[type-ICMPV6_DEST_UNREACH]++;
+		(&(idev->stats.icmpv6[smp_processor_id()*2].Icmp6OutDestUnreachs))[type-ICMPV6_DEST_UNREACH]++;
+	}
+	if (type == ICMPV6_DEST_UNREACH && code == ICMPV6_ADM_PROHIBITED)
+		ICMP6_INC_STATS_BH(idev,Icmp6OutAdminProhibs);
+	ICMP6_INC_STATS_BH(idev,Icmp6OutMsgs);
+	if (idev)
+		in6_dev_put(idev);
 out:
 	icmpv6_xmit_unlock();
 }
@@ -376,6 +410,7 @@
 static void icmpv6_echo_reply(struct sk_buff *skb)
 {
 	struct sock *sk = icmpv6_socket->sk;
+	struct inet6_dev *idev;
 	struct icmp6hdr *icmph = (struct icmp6hdr *) skb->h.raw;
 	struct in6_addr *saddr;
 	struct icmpv6_msg msg;
@@ -383,8 +418,8 @@
 
 	saddr = &skb->nh.ipv6h->daddr;
 
-	if (ipv6_addr_type(saddr) & IPV6_ADDR_MULTICAST ||
-	    ipv6_chk_acast_addr(0, saddr)) 
+	if ((ipv6_addr_type(saddr) & (IPV6_ADDR_MULTICAST|IPV6_ADDR_ANYCAST)) ||
+	    ipv6_chk_acast_addr(0, saddr))
 		saddr = NULL;
 
 	msg.icmph.icmp6_type = ICMPV6_ECHO_REPLY;
@@ -410,13 +445,953 @@
 	if (icmpv6_xmit_lock())
 		return;
 
-	ip6_build_xmit(sk, icmpv6_getfrag, &msg, &fl, msg.len, NULL, -1,
+	ip6_build_xmit(sk, icmpv6_getfrag, &msg, &fl, msg.len, NULL, -1, -1,
+		       MSG_DONTWAIT);
+	idev = in6_dev_get(skb->dev);
+	ICMP6_INC_STATS_BH(idev,Icmp6OutEchoReplies);
+	ICMP6_INC_STATS_BH(idev,Icmp6OutMsgs);
+	if (idev)
+		in6_dev_put(idev);
+
+	icmpv6_xmit_unlock();
+}
+
+#ifdef CONFIG_IPV6_NODEINFO
+/*
+ *	IPv6 Node Information Queries
+ *	<draft-ietf-ipngwg-icmp-name-lookups-07.txt>
+ */
+/*
+ * Authors:
+ *	Koichi KUNITAKE
+ *	Hideaki YOSHIFUJI
+ */
+
+#define __UTS_NODENAME_NONE	"(none)"
+#define NI_NONCE_LEN		8
+#define NI_TTL_LEN		4	/* sizeof(__u32) */
+#define NI_MAX_SYSNAME_LEN	(sizeof(system_utsname.domainname) + \
+				sizeof(system_utsname.nodename) + 1)
+#define NI_MAX_REPLY_LEN	(IPV6_MIN_MTU - sizeof(struct ipv6hdr))
+
+static struct crypto_tfm *md5_tfm;
+
+static int icmpv6_ni_getname(struct sk_buff *skb, 
+			     __u8 *subj, int subjlen, 
+			     struct net_device **devp, 
+			     struct in6_addr *daddr, __u16 *flagsp);
+static int icmpv6_ni_getaddrs6(struct sk_buff *skb,
+			       __u8 *subj, int subjlen, 
+			       struct net_device **devp, 
+			       struct in6_addr *daddr, __u16 *flagsp);
+static int icmpv6_ni_getaddrs4(struct sk_buff *skb,
+			       __u8 *subj, int subjlen, 
+			       struct net_device **devp, 
+			       struct in6_addr *daddr, __u16 *flagsp);
+
+struct icmpv6_ni_table {
+	const char	*name;
+	int		(*getinfo)(struct sk_buff *skb,
+				   __u8 *subj, int subjlen,
+				   struct net_device **devp,
+				   struct in6_addr *daddr,
+				   __u16 *flagsp);
+};
+
+struct icmpv6_ni_table icmpv6_ni_code_table[] = {
+	{	"IPV6",		icmpv6_ni_getaddrs6,	},
+	{	"FQDN",		icmpv6_ni_getname,	},
+	{	"IPV4",		icmpv6_ni_getaddrs4,	},
+};
+
+struct icmpv6_ni_table icmpv6_ni_qtype_table[] = {
+	{	"NOOP",		NULL,			},
+	{	"SUPTYPES",	NULL,			},
+	{	"FQDN",		icmpv6_ni_getname,	},
+	{	"NODEADDR",	icmpv6_ni_getaddrs6,	},
+	{	"IPV4ADDR",	icmpv6_ni_getaddrs4,	},
+};
+
+struct in6_addr icmpv6_ni_in6;
+DECLARE_RWSEM(icmpv6_ni_in6_sem);
+
+static __inline__ const char *icmpv6_ni_qtypename(__u16 qtype)
+{
+	return ((qtype < sizeof(icmpv6_ni_qtype_table)/sizeof(icmpv6_ni_qtype_table[0])) ?
+		icmpv6_ni_qtype_table[qtype].name : "unknown");
+}
+
+static size_t str2lower(char *dst, const char *src, size_t len)
+{
+	const char *p;
+	char *q;
+	size_t i;
+	for (p = src, q = dst, i = 0; *p && i + 1 < len; p++, i++)
+		*q++ = (isascii(*p) && isupper(*p)) ? tolower(*p) : *p;
+	*q = '\0';
+	return i;
+}
+
+static struct in6_addr icmpv6_ni_group(const char *name)
+{
+	char *p;
+	__u8 digest[16];
+	char hbuf[NI_MAX_SYSNAME_LEN];
+	struct in6_addr in6;
+	int len;
+	struct scatterlist sg[1];
+
+	if (!md5_tfm)
+		goto err;
+
+	(void)str2lower(&hbuf[1], name, sizeof(hbuf)-1);
+	p = strchr(&hbuf[1], '.');
+	len = p ? (p - &hbuf[1]) : strlen(&hbuf[1]);
+	if (len >= 0x40)
+		goto err;
+	hbuf[0] = (char)len;
+
+	sg[0].page = virt_to_page(hbuf);
+	sg[0].offset = ((long) hbuf & ~PAGE_MASK);
+	sg[0].length = 1 + len;
+
+	crypto_digest_init(md5_tfm);
+	crypto_digest_update(md5_tfm, sg, 1);
+	crypto_digest_final(md5_tfm, digest);
+
+	ipv6_addr_set (&in6, 
+			htonl(0xff020000), htonl(0x00000000),
+			htonl(0x00000002), *(__u32 *)digest);   
+	return in6;
+err:
+	memset(&in6, 0, sizeof(in6));
+	return in6;
+}
+
+void icmpv6_ni_join_nigroup_dev(struct net_device *dev)
+{
+	struct sock *sock = icmpv6_socket->sk;
+	if (!(dev->flags&IFF_UP))
+		return;
+	down_read(&icmpv6_ni_in6_sem);
+	if (icmpv6_ni_in6.s6_addr32[0] == htonl(0x00000000)) {
+		up_read(&icmpv6_ni_in6_sem);
+		return;
+	}
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+	printk(KERN_DEBUG
+		"ni_join_nigroup_dev(): %s (index=%d)\n",
+		dev->name ? dev->name : "(null)",
+		dev->ifindex);
+#endif
+	ipv6_sock_mc_join(sock, dev->ifindex, &icmpv6_ni_in6);
+	up_read(&icmpv6_ni_in6_sem);
+}
+
+static void icmpv6_ni_joinleave_group(struct in6_addr *nigroup, int join)
+{
+	struct sock *sock = icmpv6_socket->sk;
+	struct net_device *dev;
+	if (nigroup->s6_addr32[0] == htonl(0x00000000))
+		return;
+	read_lock(&dev_base_lock);
+	for (dev = dev_base; dev; dev = dev->next) {
+		if (!(dev->flags&IFF_UP))
+			continue;
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+		printk(KERN_DEBUG
+			"ni_joinleave_group(): %s, %s (index=%d)\n",
+			join ? "join" : "leave",
+			dev->name ? dev->name : "(null)",
+			dev->ifindex);
+#endif
+		if (join) {
+			ipv6_sock_mc_join(sock, dev->ifindex, nigroup);
+		} else {
+			ipv6_sock_mc_drop(sock, dev->ifindex, nigroup);
+		}
+	}
+	read_unlock(&dev_base_lock);
+}
+
+static void __icmpv6_sethostname_hook(struct new_utsname *sysname)
+{
+	struct in6_addr new;
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+	char addrbuf[128];
+#endif
+	down_write(&icmpv6_ni_in6_sem);
+	if (strcmp(sysname->nodename, __UTS_NODENAME_NONE) == 0) {
+		memset(&new, 0, sizeof(new));
+	} else {
+		new = icmpv6_ni_group(sysname->nodename);
+	}
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+	in6_ntop(&icmpv6_ni_in6, addrbuf);
+	printk(KERN_DEBUG
+		"icmpv6_sethostname_hook: old = %s\n",
+		addrbuf);
+	in6_ntop(&new, addrbuf);
+	printk(KERN_DEBUG
+		"icmpv6_sethostname_hook: new = %s\n",
+		addrbuf);
+#endif
+	if (ipv6_addr_cmp(&icmpv6_ni_in6, &new)) {
+		if (new.s6_addr32[0] != htonl(0x00000000)) {
+			icmpv6_ni_joinleave_group(&new, 1);
+		}
+		if (icmpv6_ni_in6.s6_addr32[0] != htonl(0x00000000)) {
+			icmpv6_ni_joinleave_group(&icmpv6_ni_in6, 0);
+		}
+		icmpv6_ni_in6 = new;
+	}
+	up_write(&icmpv6_ni_in6_sem);
+}
+
+static int icmpv6_ni_dnscmp(__u8 *p, int plen, __u8 *q, int qlen, int qtrunc)
+{
+	/* be sure that p is subject, q is encoded system name */
+	__u8 *p0 = p, *q0 = q;
+	int done = 0, retcode = 0;
+	if (plen < 1 || qlen < 1)
+		return -1;	/* invalid length */
+	/* simple case */
+	if (plen == qlen && memcmp(p0, q0, plen) == 0)
+		return 0;
+	if (*(p0 + plen - 1) || *(q0 + qlen - 1))
+		return -1; /* invalid termination */
+	while(p < p0 + plen && q < q0 + qlen) {
+		if (*p >= 0x40 || *q >= 0x40)
+			return -1;	/* DNS compression cannot be used in subject */
+		if (p + *p + 1 > p0 + plen || q + *q + 1 > q0 + qlen)
+			return -1;	/* overrun */
+		if (*p == '\0') {
+			if (p == p0 + plen - 1)
+				break;		/* FQDN */
+			else if (p + 1 == p0 + plen - 1)
+				return retcode;	/* truncated */
+			else
+				return -1;	/* more than one subject ?! */
+		}
+		if (!done) {
+			if (*q == '\0') {
+				if (q == q0 + qlen - 1) {
+					done = 1;	/* FQDN */
+				} else if (q + 1 == q0 + qlen - 1) {
+					retcode = qtrunc;
+					done = 1;
+				} else
+					return -1;	/* more than one subject ?! */
+			} else {
+				if (*p != *q) {
+					retcode = 1;
+					done = 1;
+				} else {
+					if (memcmp(p+1, q+1, *p)) {
+						retcode = 1;
+						done = 1;
+					}
+				}
+			}
+		}
+		p += *p + 1;
+		q += done ? 0 : (*q + 1);
+	}
+	return retcode;
+}
+
+static int icmpv6_ni_getname(struct sk_buff *skb,
+			     __u8 *subj, int subjlen, 
+			     struct net_device **devp, 
+			     struct in6_addr *daddr, __u16 *flagsp)
+{
+	__u8 tmpbuf[NI_MAX_SYSNAME_LEN];
+	__u8 *dst;
+	int sysname_known = 0, sysname_len = 0;
+	int buflen;
+	int ret;
+	if (subj && subjlen < 2)
+		return -1;	/* too short subject */
+	if (skb) {
+		buflen = skb_tailroom(skb) - NI_TTL_LEN;
+		if (buflen < 0) {
+			printk(KERN_WARNING
+				"icmpv6_ni_getname(): too short skb %p\n", skb);
+			return -1;
+		}
+		memset(skb_put(skb, NI_TTL_LEN), 0, NI_TTL_LEN);
+		dst = skb->tail;	/* XXX */
+	} else {
+		dst = tmpbuf;
+		buflen = sizeof(tmpbuf);
+	}
+	down_read(&uts_sem);
+	if (strcmp(system_utsname.nodename, __UTS_NODENAME_NONE)) {
+		char *cp = (char *)dst;
+		int dcnt = 0;
+#ifdef CONFIG_IPV6_NODEINFO_USE_UTS_DOMAIN
+		size_t nodelen = str2lower(cp + 1, system_utsname.nodename, sizeof(system_utsname.nodename));
+		if (strcmp(system_utsname.domainname, __UTS_NODENAME_NONE)) {
+			*(cp + 1 + nodelen) = '.';
+			(void)str2lower(cp + 1 + nodelen + 1, system_utsname.domainname, sizeof(system_utsname.domainname));
+		}
+#else
+		(void)str2lower(cp + 1, system_utsname.nodename, sizeof(system_utsname.nodename));
+#endif
+		up_read(&uts_sem);
+		sysname_known = 1;
+		while (cp) {
+			char *p;
+			size_t l;
+			p = strchr(cp + 1, '.');
+			l = p ? ((size_t)(p - (cp + 1))) : strlen(cp + 1);
+			/* RFC1035 limits size of single component */
+			if (l == 0 || l >= 0x40) {
+				if (net_ratelimit()) {
+					printk(KERN_WARNING
+						"ICMPv6 NI: invalid length of single component of your hostname (%d); %s.\n",
+						l, l ? "too large" : "zero");
+				}
+                                sysname_known = -1; /* truncated by an error */
+                                break;
+			}
+			/* RFC1035 limits size of names */
+			/* XXX: currently cannot be happeded because nodename is 64 bytes at max. */
+			if (sysname_len + l + 1 > 255 || sysname_len + l + 1 > buflen) {
+				if (net_ratelimit()) {
+					printk(KERN_WARNING
+						"ICMPv6 NI: length of your hostname (%d) is too large\n",
+						1);
+				}
+				sysname_known = -1; /* truncated by an error */
+				break;
+			}
+			*cp = (char)l;
+			sysname_len += l + 1;
+			if (p) {
+				dcnt++;
+			}
+			cp = p;
+		}
+		if (sysname_len > 0) {
+			dst[sysname_len++] = '\0';
+			if (dcnt < 2 || sysname_known < 0) {
+				dst[sysname_len] = '\0';
+				sysname_len++;
+			}
+		}
+		if (subj && icmpv6_ni_dnscmp(subj, subjlen, dst, sysname_len, sysname_known > 0 ? 0 : 1)) {
+			ret = -1;
+		} else {
+			if (skb)
+				skb_put(skb, sysname_len);
+			ret = NI_TTL_LEN + sysname_len;
+		}
+	} else {
+		up_read(&uts_sem);
+		if (net_ratelimit()) {
+			printk(KERN_WARNING "ICMPv6 NI: your hostname is unknown\n");
+		}
+		ret = -1;
+	}
+	return ret;
+}
+
+static int __icmpv6_ni_getaddrs6(struct sk_buff *skb,
+				 struct in6_addr *in6, 
+				 struct net_device *dev, 
+				 __u16 *flagsp, int *subjokp)
+{
+	struct inet6_dev *idev;
+	struct inet6_ifaddr *ifp;
+	__u16 flags = flagsp ? *flagsp : 0;
+	int len = 0;
+	int subjok = in6 ? (subjokp ? *subjokp : 0) : 1;
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+	char addrbuf[128];
+	if (in6) {
+		in6_ntop(in6, addrbuf);
+		printk(KERN_DEBUG
+			"ni_getaddrs6(): subject address: %s, device=%s\n", addrbuf, dev ? dev->name : "(null)");
+	} else {
+		printk(KERN_DEBUG
+			"ni_getaddrs6(): device=%s\n", dev ? dev->name : "(null)");
+	}
+	if (!skb) {
+		printk(KERN_DEBUG
+			"ni_getaddrs6():- result is not needed\n");
+	}
+#endif
+	idev = in6_dev_get(dev);
+	if (!idev)
+		return -1;	/* XXX */
+
+	read_lock(&idev->lock);
+	for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) {
+		int copy_flag = 0;
+		if (subjok >= 0 && in6) {
+			/* we don't allow loopback address as a subject; XXX: REFUSED? */
+			if (ifp->scope != IFA_HOST && !ipv6_addr_cmp(in6, &ifp->addr)) {
+				subjok = ifp->flags&IFA_F_TEMPORARY ? -1 : 1;
+			}
+		}
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+		in6_ntop(&ifp->addr, addrbuf);
+		printk(KERN_DEBUG
+			"ni_getaddrs6():- address: %s, subjok=%d\n", addrbuf, subjok);
+#endif
+		if ((!skb && subjok) || subjok < 0)
+			break;
+		spin_lock_bh(&ifp->lock);
+		if (skb && !(ifp->flags & (IFA_F_DEPRECATED|IFA_F_TENTATIVE|IFA_F_TEMPORARY))) {
+			switch (ifp->scope) {
+			case IPV6_ADDR_COMPATv4:
+				/* If IPv4-compatible addresses are requested, set copy_flag to 1. */
+				if (flags & ICMPV6_NI_NODEADDR_FLAG_COMPAT) {
+					copy_flag = 1;
+				}
+				break;
+			case IFA_LINK:
+				/* If Link-scope addresses are requested, set copy_flag to 1. */
+				if (flags & ICMPV6_NI_NODEADDR_FLAG_LINKLOCAL) {
+					copy_flag = 1;
+				}
+				break;
+			case IFA_SITE:
+				/* If Site-local addresses are requested, set copy_flag to 1. */
+				if (flags & ICMPV6_NI_NODEADDR_FLAG_SITELOCAL) {
+					copy_flag = 1;
+				}
+				break;
+			case IFA_GLOBAL:
+				/* If Global-scope addresses are requested, set copy_flag to 1. */
+				if (flags & ICMPV6_NI_NODEADDR_FLAG_GLOBAL) {
+					copy_flag = 1;
+				}
+				break;
+			default:
+				copy_flag = 0;
+				break;
+			}
+
+			if (copy_flag) {
+				if (skb_tailroom(skb) < NI_TTL_LEN + sizeof(struct in6_addr)) {
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+					printk(KERN_DEBUG
+						"ni_getaddrs6():- to be copied but truncated\n");
+#endif
+					flags |= ICMPV6_NI_NODEADDR_FLAG_TRUNCATE;
+					if (subjok)
+						break;
+				} else {
+					if (skb) {
+						__u8 *p = skb_put(skb, NI_TTL_LEN + sizeof(struct in6_addr));
+						__u32 ttl;
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+						printk(KERN_DEBUG
+							"ni_getaddrs6():- copied\n");
+#endif
+						if (ifp->valid_lft) {
+							if (ifp->valid_lft > (jiffies - ifp->tstamp) / HZ)
+								ttl = ifp->valid_lft - (jiffies - ifp->tstamp) / HZ;
+							else
+								ttl = 0;
+							if (ttl > 0x7fffffff)
+								ttl = 0x7fffffff;
+						} else {
+							ttl = 0x7fffffff;
+						}
+						ttl = htonl(ttl);
+						memcpy(p, &ttl, sizeof(ttl));
+						ipv6_addr_copy((struct in6_addr *)(p + NI_TTL_LEN), &ifp->addr);
+						len += NI_TTL_LEN + sizeof(struct in6_addr);
+					}
+				}
+			}
+		}
+		spin_unlock_bh(&ifp->lock);
+	}
+	read_unlock(&idev->lock);
+	if (flagsp) {
+		*flagsp = flags;
+	}
+	if (subjok && subjokp) {
+		*subjokp = subjok;
+	}
+	if (!subjok && !(flags & ICMPV6_NI_NODEADDR_FLAG_ALL)) {
+		len = -1;
+	} else if (subjok < 0) {
+		len = -2;
+	}
+	
+
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+	printk(KERN_DEBUG
+		"ni_getaddrs6():- len=%d, flags=%04x\n", len, ntohs(flags));
+#endif
+	in6_dev_put(idev);
+	return len;
+}
+
+static int icmpv6_ni_getaddrs6(struct sk_buff *skb,
+			       __u8 *subj, int subjlen, 
+			       struct net_device **devp, 
+			       struct in6_addr *daddr, __u16 *flagsp)
+{
+	struct in6_addr *in6 = (struct in6_addr *)subj;
+	struct net_device *dev = devp ? *devp : NULL;
+	__u16 flags = flagsp ? *flagsp : 0;
+	int len = 0;
+	int subjok = in6 ? 0 : 1;
+
+	if (subj && subjlen != sizeof(struct in6_addr))
+		return -1;	/* too short subject */
+
+	flags &= (ICMPV6_NI_NODEADDR_FLAG_ALL|
+			ICMPV6_NI_NODEADDR_FLAG_LINKLOCAL|
+			ICMPV6_NI_NODEADDR_FLAG_SITELOCAL|
+			ICMPV6_NI_NODEADDR_FLAG_GLOBAL|
+			ICMPV6_NI_NODEADDR_FLAG_COMPAT);
+
+	if (!subjok) {
+		subjok = !ipv6_addr_cmp(in6, daddr);	/* for special case */
+	}
+
+	if (dev && !(flags & ICMPV6_NI_NODEADDR_FLAG_ALL)) {
+		len = __icmpv6_ni_getaddrs6(skb, in6, dev, flagsp ? &flags : NULL, &subjok);
+	} else {
+		read_lock(&dev_base_lock);
+		for (dev = dev_base; dev; dev = dev->next) {
+			int sublen = __icmpv6_ni_getaddrs6(skb, in6, dev, flagsp ? &flags : NULL, &subjok);
+			if (sublen >= 0) {
+				len += sublen;
+				if (devp && !*devp) {
+					dev_hold(dev);
+					*devp = dev;
+				}
+			} else if (subjok < 0) {
+				len = -2;
+				break;
+			}
+		}
+		read_unlock(&dev_base_lock);
+	}
+	if (!subjok) {
+		len = -1;
+		flags &= ~ICMPV6_NI_NODEADDR_FLAG_TRUNCATE;
+	}
+	if (flagsp) {
+		*flagsp = flags;
+	}
+
+	return len;
+}
+
+static int __icmpv6_ni_getaddrs4(struct sk_buff *skb,
+				 struct in_addr *in, 
+				 struct net_device *dev, 
+				 __u16 *flagsp, int *subjokp)
+{
+	struct in_device *in_dev;
+	struct in_ifaddr *ifa;
+	__u16 flags = 0;
+	int len = 0;
+	int subjok = in ? (subjokp ? *subjokp : 0) : 1;
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+	if (in) {
+		printk(KERN_DEBUG
+			"ni_getaddrs4(): subject address: %d.%d.%d.%d, device=%s\n", 
+			NIPQUAD(*(u32*)in), dev ? dev->name : "(null)");
+	} else {
+		printk(KERN_DEBUG
+			"ni_getaddrs4(): device=%s\n", dev ? dev->name : "(null)");
+	}
+	if (!skb) {
+		printk(KERN_DEBUG
+			"ni_getaddrs4():- result is not needed\n");
+	}
+#endif
+	read_lock(&inetdev_lock);
+	if ((in_dev = __in_dev_get(dev)) == NULL) {
+		read_unlock(&inetdev_lock);
+		return -1;	/*XXX*/
+	}
+
+	read_lock(&in_dev->lock);
+	for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
+		int copy_flag = 0;
+		if (!subjok && in) {
+			/* we don't allow loopback address as a subject; XXX: REFUSED? */
+			if (ifa->ifa_scope != RT_SCOPE_HOST && memcmp(in, &ifa->ifa_address, sizeof(*in)) == 0) {
+				subjok = 1;
+			}
+		}
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+		printk(KERN_DEBUG
+			"ni_getaddrs4():- address: %d.%d.%d.%d, subjok=%d\n", NIPQUAD(ifa->ifa_address), subjok);
+#endif
+
+		if (!skb && subjok)
+			break;
+		if (skb && !(ifa->ifa_flags & (IFA_F_DEPRECATED|IFA_F_TENTATIVE))) {
+			switch (ifa->ifa_scope) {
+			case RT_SCOPE_HOST:
+				break;	/*XXX*/
+			default:
+				copy_flag = 1;
+			}
+		}
+		if (copy_flag) {
+			if (skb_tailroom(skb) < NI_TTL_LEN + sizeof(struct in_addr)) {
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+				printk(KERN_DEBUG
+					"ni_getaddrs4():- to be copied but truncated\n");
+#endif
+				flags |= ICMPV6_NI_IPV4ADDR_FLAG_TRUNCATE;
+				if (subjok)
+					break;
+			} else {
+				if (skb) {
+					__u8 *p = skb_put(skb, NI_TTL_LEN + sizeof(struct in_addr));
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+					printk(KERN_DEBUG
+						"ni_getaddrs4():- copied\n");
+#endif
+					memset(p, 0, NI_TTL_LEN);	/* XXX */
+					memcpy(p + NI_TTL_LEN, &ifa->ifa_address, sizeof(struct in_addr));
+					len += NI_TTL_LEN + sizeof(struct in_addr);
+				}
+			}
+		}
+	}
+	read_unlock(&in_dev->lock);
+	read_unlock(&inetdev_lock);
+	if (flagsp) {
+		*flagsp = flags;
+	}
+	if (subjok && subjokp) {
+		*subjokp = 1;
+	}
+	if (!subjok && !(flags & ICMPV6_NI_IPV4ADDR_FLAG_ALL)) {
+		len = -1;
+	}
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+	printk(KERN_DEBUG
+		"ni_getaddrs4():- len=%d, flags=%04x\n", len, ntohs(flags));
+#endif
+	return len;
+}
+
+static int icmpv6_ni_getaddrs4(struct sk_buff *skb,
+			       __u8 *subj, int subjlen, 
+			       struct net_device **devp, 
+			       struct in6_addr *daddr, __u16 *flagsp)
+{
+	struct in_addr *in = (struct in_addr *)subj;
+	struct net_device *dev = devp ? *devp : NULL;
+	__u16 flags = flagsp ? *flagsp : 0;
+	int len = 0;
+	int subjok = in ? 0 : 1;
+
+	if (subj && subjlen != sizeof(struct in_addr))
+		return -1;	/* too short subject */
+
+	flags &= ICMPV6_NI_IPV4ADDR_FLAG_ALL;
+
+	if (dev && !(flags & ICMPV6_NI_IPV4ADDR_FLAG_ALL)) {
+		len = __icmpv6_ni_getaddrs4(skb, in, dev, flagsp ? &flags : NULL, &subjok);
+	} else {
+		read_lock(&dev_base_lock);
+		for (dev = dev_base; dev; dev = dev->next) {
+			int sublen = __icmpv6_ni_getaddrs4(skb, in, dev, flagsp ? &flags : NULL, &subjok);
+			if (sublen >= 0) {
+				len += sublen;
+				if (devp && !*devp) {
+					dev_hold(dev);
+					*devp = dev;
+				}
+			}
+		}
+		read_unlock(&dev_base_lock);
+	}
+	if (!subjok) {
+		len = -1;
+		flags &= ~ICMPV6_NI_IPV4ADDR_FLAG_TRUNCATE;
+	}
+	if (flagsp) {
+		*flagsp = flags;
+	}
+
+	return len;
+}
+
+static void icmpv6_ni_reply(struct sk_buff *skb, int config_accept_ni)
+{
+	struct sock *sk = icmpv6_socket->sk;
+	struct ipv6hdr *hdr = skb->nh.ipv6h;
+	struct icmp6hdr *icmph = (struct icmp6hdr *) skb->h.raw;
+	struct in6_addr *saddr;
+	struct icmpv6_msg msg;
+	struct flowi fl;
+	__u8 *data = (__u8 *) (icmph + 1);
+	int datalen = skb->tail - (unsigned char *)data;
+	__u8 *subject;
+	int subjlen;
+	__u16 qtype = ntohs(icmph->icmp6_qtype);
+	struct sk_buff *ni_reply_skb = NULL;
+	int len = 0;
+	__u8 ni_code;
+	__u16 ni_flags = 0;
+	int flen = 0;
+	__u16 fni_flags = 0;
+	struct net_device *dev = NULL;
+	struct inet6_dev *idev = NULL;
+	struct icmpv6_ni_table *code_table = NULL, *qtype_table = NULL;
+
+
+#ifdef CONFIG_SYSCTL
+	/*
+	 * [Step 0] Decide our policy through sysctl and/or /proc fs
+	 *    >  0 : accept NI
+	 *    == 0 : just ignore NI
+	 *    <  0 : refuse NI
+	 */
+	if (config_accept_ni > 0) {
+		idev = in6_dev_get(skb->dev);
+		if (idev == NULL) {
+			/* Do I need this part? */
+			if (net_ratelimit()) {
+				printk(KERN_WARNING 
+					"ICMPv6 NI: can't find in6 device\n");
+			}
+			goto ni_return;
+		}
+		read_lock(&idev->lock);
+		config_accept_ni = idev->cnf.accept_ni;
+		read_unlock(&idev->lock);
+	}
+	if (!config_accept_ni)
+		goto ni_return;
+#endif
+
+	/*
+	 * [Step 1] Check the size of query packet
+	 */
+	if (datalen < NI_NONCE_LEN) {
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+		if (net_ratelimit()) {
+			printk(KERN_WARNING 
+				"ICMPv6 NI: invalid query packet length(%d): code=%u, qtype=%u, flags=0x%04x\n",
+				datalen, icmph->icmp6_code, qtype, icmph->icmp6_flags);
+		}
+#endif
+		goto ni_return;
+	}
+	subject = data + NI_NONCE_LEN;		/* subject */
+	subjlen = datalen - NI_NONCE_LEN;	/* subject length */
+
+	ni_reply_skb = alloc_skb(NI_MAX_REPLY_LEN, GFP_ATOMIC);
+	if (ni_reply_skb == NULL)
+		goto ni_return;
+	skb_reserve(ni_reply_skb, NI_NONCE_LEN);
+
+	/*
+	 * [Step 2] Code / qtype / subject validation
+	 *  (1) qtype validation (set ni_code to ICMPV6_NI_SUCCESS if it is 
+	 *      known)
+	 *  (2) code validation for codes except for NOOP and SUPTYPES
+	 *      - reply nothing if it is unknown.
+	 *  (3) subject validation
+	 *      a. qtype NOOP and SUPTYPES
+	 *         - only subject name with no data is valid.
+	 *         - we must ignore code for NOOP.
+	 *         - it is not clarified, but we should ignore code for 
+	 *           SUPTYPES.
+	 *      b. qtype FQDN, NODEADDR and IPV4ADDR
+	 *         1) IPV6 subject must have one ipv6 address.
+	 *            this should be one of our address.
+	 *         2) FQDN subject must match up to our system name.
+	 *         3) IPV4 subject must have one ipv4 address.
+	 *            this should be one of our ipv4 address. 
+	 *  NOTE: we do not supply any reply for malformed query;
+	 *        spec. says we must silently dicard the query
+	 *        if subject does not match up to our configuration.
+	 */
+	ni_code = ICMPV6_NI_UNKNOWN;
+	switch(qtype) {
+	case ICMPV6_NI_QTYPE_NOOP:
+	case ICMPV6_NI_QTYPE_SUPTYPES:
+		/* simple case: code should be ICMPV6_NI_SUBJ_FQDN and must have no subject */
+		switch(icmph->icmp6_code) {
+		case ICMPV6_NI_SUBJ_FQDN:
+			if (subjlen) {
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+				if (net_ratelimit()) {
+					printk(KERN_WARNING
+						"ICMPv6 NI (%s): invalid subject length (%d)\n",
+						icmpv6_ni_qtypename(qtype), subjlen);
+				}
+#endif
+				goto ni_return;
+			}
+			break;
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+		default:
+			if(net_ratelimit()) {
+				printk(KERN_WARNING
+					"ICMPv6 NI (%s): invalid/unknown code(%u)\n",
+					icmpv6_ni_qtypename(qtype), icmph->icmp6_code);
+			}
+#endif
+			/* we ignore code */
+		}
+		ni_code = ICMPV6_NI_SUCCESS;
+		break;
+	default:
+		if (qtype < sizeof(icmpv6_ni_qtype_table)/sizeof(icmpv6_ni_qtype_table[0])) {
+			qtype_table = &icmpv6_ni_qtype_table[qtype];
+			ni_code = ICMPV6_NI_SUCCESS;
+		}
+		if (icmph->icmp6_code < sizeof(icmpv6_ni_code_table)/sizeof(icmpv6_ni_code_table[0])) {
+			code_table = &icmpv6_ni_code_table[icmph->icmp6_code];
+			fni_flags = icmph->icmp6_flags;
+			if (qtype_table && qtype_table->getinfo == code_table->getinfo) {
+				flen = code_table->getinfo(ni_reply_skb,
+							   subject, subjlen,
+							   NULL, 
+							   &hdr->daddr, 
+							   &fni_flags);
+			} else {
+				flen = code_table->getinfo(NULL,
+							   subject, subjlen,
+							   &dev, 
+							   &hdr->daddr,
+							   NULL);
+			}
+			if (flen < -1) {
+				config_accept_ni = -1;	/*refused*/
+			} else if (flen < 0) {
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+				if (net_ratelimit()) {
+					printk(KERN_WARNING
+						"ICMPv6 NI (%s): invalid subject %s, length %d\n",
+						icmpv6_ni_qtypename(qtype),
+						code_table->name, subjlen);
+				}
+#endif
+				goto ni_return;
+			}
+		} else {
+#ifdef CONFIG_IPV6_NODEINFO_DEBUG
+			if(net_ratelimit()) {
+				printk(KERN_WARNING
+					"ICMPv6 NI (%s): unknown code(%d)\n",
+					icmpv6_ni_qtypename(qtype), icmph->icmp6_code);
+			}
+#endif
+			goto ni_return;
+		}
+	}
+
+	/*
+	 * [Step 3] Fill common field
+	 */
+	memcpy(skb_push(ni_reply_skb, NI_NONCE_LEN), data, NI_NONCE_LEN);
+
+	/*
+	 * [Step 4] Unsuccessful reply
+	 *  - UNKNOWN reply should be done before policy based refusal (section 3)
+	 */
+	if (ni_code != ICMPV6_NI_SUCCESS)
+		goto ni_unknown;
+	if (config_accept_ni < 0) {
+		ni_code = ICMPV6_NI_REFUSED;
+		goto ni_refused;
+	}
+
+	/*
+	 * [Step 5] Fill the reply
+	 */
+	switch(qtype) {
+	case ICMPV6_NI_QTYPE_NOOP:
+		break;
+	case ICMPV6_NI_QTYPE_SUPTYPES:
+	{
+		/* supports NOOP, SUPTYPES, FQDN and NODEADDR */
+		__u32 suptypes = htonl(0x0000001f);	/* 00000000 00000000 00000000 00011111 */
+		memcpy(skb_put(ni_reply_skb, sizeof(suptypes)), &suptypes, sizeof(suptypes));
+		len += sizeof(suptypes);
+		ni_flags &= ~ICMPV6_NI_SUPTYPE_FLAG_COMPRESS;
+		break;
+	}
+	default:
+		if (qtype_table->getinfo != code_table->getinfo) {
+			flen = icmpv6_ni_qtype_table[qtype].getinfo(ni_reply_skb,
+								    NULL, 0,
+								    &dev, NULL,
+								    &fni_flags);
+		}
+		len += flen;
+		ni_flags = fni_flags;
+	}
+
+ni_unknown:
+ni_refused:
+	/*
+	 * [Step 6] Send reply
+	 */
+	saddr = &hdr->daddr;
+
+	if ((ipv6_addr_type(saddr) & (IPV6_ADDR_MULTICAST|IPV6_ADDR_ANYCAST)) ||
+	    ipv6_chk_acast_addr(0, saddr))
+		saddr = NULL;
+
+	msg.icmph.icmp6_type = ICMPV6_NI_REPLY;
+	msg.icmph.icmp6_code = ni_code;
+	msg.icmph.icmp6_cksum = 0;
+	msg.icmph.icmp6_qtype = icmph->icmp6_qtype;
+	msg.icmph.icmp6_flags = ni_flags;
+
+	msg.skb = ni_reply_skb;
+	msg.offset = 0;
+	msg.csum = 0;
+	msg.len = sizeof(struct icmp6hdr) + ni_reply_skb->len;
+	msg.daddr = &hdr->saddr;
+
+	fl.proto = IPPROTO_ICMPV6;
+	fl.nl_u.ip6_u.daddr = &hdr->saddr;
+	fl.nl_u.ip6_u.saddr = saddr;
+	fl.oif = skb->dev->ifindex;
+	fl.fl6_flowlabel = 0;
+	fl.uli_u.icmpt.type = ICMPV6_NI_REPLY;
+	fl.uli_u.icmpt.code = ni_code;
+
+	icmpv6_xmit_lock();
+
+	/* rate-limit */
+	if (!icmpv6_xrlim_allow(sk, ICMPV6_NI_REPLY, ni_code, &fl))
+		goto out;
+
+	ip6_build_xmit(sk, icmpv6_getfrag, &msg, &fl, msg.len, NULL, -1, -1,
 		       MSG_DONTWAIT);
-	ICMP6_INC_STATS_BH(Icmp6OutEchoReplies);
-	ICMP6_INC_STATS_BH(Icmp6OutMsgs);
 
+#ifndef CONFIG_SYSCTL
+	idev = in6_dev_get(skb->dev);
+#endif
+	ICMP6_INC_STATS_BH(idev,Icmp6OutMsgs);
+out:
 	icmpv6_xmit_unlock();
+ni_return:
+	if (ni_reply_skb)
+		kfree_skb(ni_reply_skb);
+	if (idev) {
+		in6_dev_put(idev);
+	}
+	if (dev) {
+		dev_put(dev);
+	}
 }
+#endif
 
 static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info)
 {
@@ -483,12 +1458,13 @@
 int icmpv6_rcv(struct sk_buff *skb)
 {
 	struct net_device *dev = skb->dev;
+	struct inet6_dev *idev = in6_dev_get(dev);
 	struct in6_addr *saddr, *daddr;
 	struct ipv6hdr *orig_hdr;
 	struct icmp6hdr *hdr;
 	int type;
 
-	ICMP6_INC_STATS_BH(Icmp6InMsgs);
+	ICMP6_INC_STATS_BH(idev,Icmp6InMsgs);
 
 	saddr = &skb->nh.ipv6h->saddr;
 	daddr = &skb->nh.ipv6h->daddr;
@@ -499,31 +1475,19 @@
 		if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
 				    skb->csum)) {
 			if (net_ratelimit())
-				printk(KERN_DEBUG "ICMPv6 hw checksum failed\n");
+				printk(KERN_WARNING "ICMPv6 hw checksum failed\n");
 			skb->ip_summed = CHECKSUM_NONE;
 		}
 	}
 	if (skb->ip_summed == CHECKSUM_NONE) {
 		if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
 				    skb_checksum(skb, 0, skb->len, 0))) {
+			char sbuf[64], dbuf[64];
+			in6_ntop(saddr, sbuf);
+			in6_ntop(daddr, dbuf);
 			if (net_ratelimit())
-				printk(KERN_DEBUG "ICMPv6 checksum failed [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x > %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n",
-				       ntohs(saddr->s6_addr16[0]),
-				       ntohs(saddr->s6_addr16[1]),
-				       ntohs(saddr->s6_addr16[2]),
-				       ntohs(saddr->s6_addr16[3]),
-				       ntohs(saddr->s6_addr16[4]),
-				       ntohs(saddr->s6_addr16[5]),
-				       ntohs(saddr->s6_addr16[6]),
-				       ntohs(saddr->s6_addr16[7]),
-				       ntohs(daddr->s6_addr16[0]),
-				       ntohs(daddr->s6_addr16[1]),
-				       ntohs(daddr->s6_addr16[2]),
-				       ntohs(daddr->s6_addr16[3]),
-				       ntohs(daddr->s6_addr16[4]),
-				       ntohs(daddr->s6_addr16[5]),
-				       ntohs(daddr->s6_addr16[6]),
-				       ntohs(daddr->s6_addr16[7]));
+				printk(KERN_WARNING "ICMPv6 checksum failed [%s > %s]\n",
+					sbuf, dbuf);
 			goto discard_it;
 		}
 	}
@@ -535,10 +1499,15 @@
 
 	type = hdr->icmp6_type;
 
-	if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB)
+	if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB) {
 		(&icmpv6_statistics[smp_processor_id()*2].Icmp6InDestUnreachs)[type-ICMPV6_DEST_UNREACH]++;
-	else if (type >= ICMPV6_ECHO_REQUEST && type <= NDISC_REDIRECT)
+		if (idev)
+			(&idev->stats.icmpv6[smp_processor_id()*2].Icmp6InDestUnreachs)[type-ICMPV6_DEST_UNREACH]++;
+	} else if (type >= ICMPV6_ECHO_REQUEST && type <= NDISC_REDIRECT) {
 		(&icmpv6_statistics[smp_processor_id()*2].Icmp6InEchos)[type-ICMPV6_ECHO_REQUEST]++;
+		if (idev)
+			(&idev->stats.icmpv6[smp_processor_id()*2].Icmp6InEchos)[type-ICMPV6_ECHO_REQUEST]++;
+	}
 
 	switch (type) {
 	case ICMPV6_ECHO_REQUEST:
@@ -562,11 +1531,9 @@
 		rt6_pmtu_discovery(&orig_hdr->daddr, &orig_hdr->saddr, dev,
 				   ntohl(hdr->icmp6_mtu));
 
-		/*
-		 *	Drop through to notify
-		 */
-
 	case ICMPV6_DEST_UNREACH:
+		if (hdr->icmp6_code == ICMPV6_ADM_PROHIBITED)
+			ICMP6_INC_STATS_BH(idev,Icmp6InAdminProhibs);
 	case ICMPV6_TIME_EXCEED:
 	case ICMPV6_PARAMPROB:
 		icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
@@ -598,26 +1565,53 @@
 	case ICMPV6_MLD2_REPORT:
 		break;
 
+	case ICMPV6_NI_QUERY:
+	{
+#ifdef CONFIG_IPV6_NODEINFO
+#ifdef CONFIG_SYSCTL
+		int config_accept_ni = ipv6_devconf.accept_ni;
+		if (!config_accept_ni)
+			break;
+		icmpv6_ni_reply(skb, config_accept_ni);
+#else
+		icmpv6_ni_reply(skb, 1);
+#endif
+#endif
+		break;
+	}
+
+	case ICMPV6_NI_REPLY:
+		break;
+
 	default:
-		if (net_ratelimit())
-			printk(KERN_DEBUG "icmpv6: msg of unkown type\n");
+#ifdef CONFIG_IPV6_DEBUG
+		if (net_ratelimit()) {
+			char abuf[64];
+			in6_ntop(saddr, abuf);
+			printk(KERN_DEBUG "icmpv6: msg of unknown type %d code %d from %s\n", type, hdr->icmp6_code, abuf);
+		}
+#endif
 
 		/* informational */
 		if (type & ICMPV6_INFOMSG_MASK)
 			break;
 
 		/* 
-		 * error of unkown type. 
+		 * error of unknown type. 
 		 * must pass to upper level 
 		 */
 
 		icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
 	};
+	if (idev)
+		in6_dev_put(idev);
 	kfree_skb(skb);
 	return 0;
 
 discard_it:
-	ICMP6_INC_STATS_BH(Icmp6InErrors);
+	ICMP6_INC_STATS_BH(idev,Icmp6InErrors);
+	if (idev)
+		in6_dev_put(idev);
 	kfree_skb(skb);
 	return 0;
 }
@@ -626,6 +1620,9 @@
 {
 	struct sock *sk;
 	int err, i, j;
+#ifdef CONFIG_IPV6_NODEINFO
+	struct crypto_tfm *tfm;
+#endif
 
 	for (i = 0; i < NR_CPUS; i++) {
 		icmpv6_socket_cpu(i) = sock_alloc();
@@ -661,6 +1658,20 @@
 
 	inet6_add_protocol(&icmpv6_protocol);
 
+#ifdef CONFIG_IPV6_NODEINFO
+	tfm = crypto_alloc_tfm("md5", 0);
+
+	down_write(&icmpv6_sethostname_hook_sem);
+	if (tfm) {
+		if (md5_tfm == NULL)
+			md5_tfm = tfm;
+		else
+			crypto_free_tfm(tfm);
+	}
+	icmpv6_sethostname_hook = __icmpv6_sethostname_hook;
+	up_write(&icmpv6_sethostname_hook_sem);
+#endif
+
 	return 0;
 fail:
 	for (j = 0; j < i; j++) {
@@ -674,6 +1685,20 @@
 {
 	int i;
 
+#ifdef CONFIG_IPV6_NODEINFO
+	struct crypto_tfm *tfm;
+
+	down_write(&icmpv6_sethostname_hook_sem);
+	tfm = md5_tfm;
+	md5_tfm = NULL;
+	icmpv6_sethostname_hook = NULL;
+	up_write(&icmpv6_sethostname_hook_sem);
+
+	if (tfm != NULL)
+		crypto_free_tfm(tfm);
+#endif
+
+
 	for (i = 0; i < NR_CPUS; i++) {
 		sock_release(icmpv6_socket_cpu(i));
 		icmpv6_socket_cpu(i) = NULL;
diff -urN linux-2.4.29/net/ipv6/ip6_fib.c linux-2.4.29-uc1/net/ipv6/ip6_fib.c
--- linux-2.4.29/net/ipv6/ip6_fib.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/ip6_fib.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: ip6_fib.c,v 1.32 2004/01/14 14:11:38 yoshfuji Exp $ */
+
 /*
  *	Linux INET6 implementation 
  *	Forwarding Information Database
@@ -14,10 +16,12 @@
  */
 
 /*
+ *	Changes:
  * 	Changes:
  * 	Yuji SEKIYA @USAGI:	Support default route on router node;
  * 				remove ip6_null_entry from the top of
  * 				routing table.
+ * 	Ville Nuorvala:		Fixes to source address sub trees
  */
 #include <linux/config.h>
 #include <linux/errno.h>
@@ -39,9 +43,6 @@
 #include <net/ip6_fib.h>
 #include <net/ip6_route.h>
 
-#define RT6_DEBUG 2
-#undef CONFIG_IPV6_SUBTREES
-
 #if RT6_DEBUG >= 3
 #define RT6_TRACE(x...) printk(KERN_DEBUG x)
 #else
@@ -50,6 +51,11 @@
 
 struct rt6_statistics	rt6_stats;
 
+#if !defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+extern struct rt6_info *rt6_dflt_pointer;
+extern spinlock_t rt6_dflt_lock;
+#endif
+
 static kmem_cache_t * fib6_node_kmem;
 
 enum fib_walk_state_t
@@ -81,9 +87,14 @@
 #define SUBTREE(fn) NULL
 #endif
 
+static struct rt6_info * fib6_find_prefix(struct fib6_node *fn);
 static void fib6_prune_clones(struct fib6_node *fn, struct rt6_info *rt);
 static struct fib6_node * fib6_repair_tree(struct fib6_node *fn);
 
+#ifdef CONFIG_IPV6_SUBTREES
+static struct in6_addr fib6_addr_any;
+#endif
+
 /*
  *	A routing update causes an increase of the serial number on the
  *	afected subtree. This allows for cached routes to be asynchronously
@@ -110,103 +121,16 @@
 }
 
 /*
- *	Auxiliary address test functions for the radix tree.
- *
- *	These assume a 32bit processor (although it will work on 
- *	64bit processors)
- */
-
-/*
- *	compare "prefix length" bits of an address
- */
-
-static __inline__ int addr_match(void *token1, void *token2, int prefixlen)
-{
-	__u32 *a1 = token1;
-	__u32 *a2 = token2;
-	int pdw;
-	int pbi;
-
-	pdw = prefixlen >> 5;	  /* num of whole __u32 in prefix */
-	pbi = prefixlen &  0x1f;  /* num of bits in incomplete u32 in prefix */
-
-	if (pdw)
-		if (memcmp(a1, a2, pdw << 2))
-			return 0;
-
-	if (pbi) {
-		__u32 mask;
-
-		mask = htonl((0xffffffff) << (32 - pbi));
-
-		if ((a1[pdw] ^ a2[pdw]) & mask)
-			return 0;
-	}
-
-	return 1;
-}
-
-/*
  *	test bit
  */
 
-static __inline__ int addr_bit_set(void *token, int fn_bit)
+static __inline__ int addr_bit_set(const void *token, int fn_bit)
 {
-	__u32 *addr = token;
+	const __u32 *addr = token;
 
 	return htonl(1 << ((~fn_bit)&0x1F)) & addr[fn_bit>>5];
 }
 
-/*
- *	find the first different bit between two addresses
- *	length of address must be a multiple of 32bits
- */
-
-static __inline__ int addr_diff(void *token1, void *token2, int addrlen)
-{
-	__u32 *a1 = token1;
-	__u32 *a2 = token2;
-	int i;
-
-	addrlen >>= 2;
-
-	for (i = 0; i < addrlen; i++) {
-		__u32 xb;
-
-		xb = a1[i] ^ a2[i];
-
-		if (xb) {
-			int j = 31;
-
-			xb = ntohl(xb);
-
-			while ((xb & (1 << j)) == 0)
-				j--;
-
-			return (i * 32 + 31 - j);
-		}
-	}
-
-	/*
-	 *	we should *never* get to this point since that 
-	 *	would mean the addrs are equal
-	 *
-	 *	However, we do get to it 8) And exacly, when
-	 *	addresses are equal 8)
-	 *
-	 *	ip route add 1111::/128 via ...
-	 *	ip route add 1111::/64 via ...
-	 *	and we are here.
-	 *
-	 *	Ideally, this function should stop comparison
-	 *	at prefix length. It does not, but it is still OK,
-	 *	if returned value is greater than prefix length.
-	 *					--ANK (980803)
-	 */
-
-	return addrlen<<5;
-}
-
 static __inline__ struct fib6_node * node_alloc(void)
 {
 	struct fib6_node *fn;
@@ -261,7 +185,7 @@
 		 *	Prefix match
 		 */
 		if (plen < fn->fn_bit ||
-		    !addr_match(&key->addr, addr, fn->fn_bit))
+		    u32_prefix_cmp(&key->addr, addr, fn->fn_bit))
 			goto insert_above;
 		
 		/*
@@ -324,13 +248,15 @@
 
 	pn = fn->parent;
 
-	/* find 1st bit in difference between the 2 addrs.
-
-	   See comment in addr_diff: bit may be an invalid value,
-	   but if it is >= plen, the value is ignored in any case.
+	/*
+	 * find 1st bit in difference between the 2 addrs.
+	 *
+	 * Retuned value is ignored if returned valud is
+	 * greater than prefix length.
+	 *					--ANK (980803)
 	 */
-	
-	bit = addr_diff(addr, &key->addr, addrlen);
+
+	bit = u32_addr_diff(addr, &key->addr, addrlen);
 
 	/* 
 	 *		(intermediate)[in]	
@@ -437,6 +363,8 @@
 		/*
 		 * The top fib of ip6 routing table includes ip6_null_entry.
 		 */
+		RT6_TRACE(
+			"fib6_add_rt2node : Try to insert default route into RTN_TL_ROOT.\n");
 		fn->leaf = rt;
 		rt->u.next = NULL;
 		goto out;
@@ -500,6 +428,8 @@
 		mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval);
 }
 
+static struct rt6_info * fib6_find_prefix(struct fib6_node *fn);
+
 /*
  *	Add routing information to the routing tree.
  *	<destination addr>/<source addr>
@@ -508,19 +438,24 @@
 
 int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh)
 {
-	struct fib6_node *fn;
+	struct fib6_node *fn = NULL;
 	int err = -ENOMEM;
-
-	fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr),
-			rt->rt6i_dst.plen, (u8*) &rt->rt6i_dst - (u8*) rt);
+#ifdef CONFIG_IPV6_SUBTREES
+	struct fib6_node *pn = NULL;
+	if (&rt->rt6i_src)
+		fn = fib6_add_1(root, &rt->rt6i_src.addr, sizeof(struct in6_addr),
+			rt->rt6i_src.plen, (u8*) &rt->rt6i_src - (u8*) rt);
 
 	if (fn == NULL)
 		goto out;
 
-#ifdef CONFIG_IPV6_SUBTREES
-	if (rt->rt6i_src.plen) {
+	if (rt->rt6i_dst.plen) {
 		struct fib6_node *sn;
-
+		if (!fn->leaf) {
+			RT6_TRACE("Adding ip6_null_entry to fn->leaf at fib6_add\n");
+			fn->leaf = &ip6_null_entry;
+			atomic_inc(&ip6_null_entry.rt6i_ref);
+		}
 		if (fn->subtree == NULL) {
 			struct fib6_node *sfn;
 
@@ -546,9 +481,9 @@
 
 			/* Now add the first leaf node to new subtree */
 
-			sn = fib6_add_1(sfn, &rt->rt6i_src.addr,
-					sizeof(struct in6_addr), rt->rt6i_src.plen,
-					(u8*) &rt->rt6i_src - (u8*) rt);
+			sn = fib6_add_1(sfn, &rt->rt6i_dst.addr,
+					sizeof(struct in6_addr), rt->rt6i_dst.plen,
+					(u8*) &rt->rt6i_dst - (u8*) rt);
 
 			if (sn == NULL) {
 				/* If it is failed, discard just allocated
@@ -562,21 +497,30 @@
 			/* Now link new subtree to main tree */
 			sfn->parent = fn;
 			fn->subtree = sfn;
-			if (fn->leaf == NULL) {
-				fn->leaf = rt;
-				atomic_inc(&rt->rt6i_ref);
-			}
 		} else {
-			sn = fib6_add_1(fn->subtree, &rt->rt6i_src.addr,
-					sizeof(struct in6_addr), rt->rt6i_src.plen,
-					(u8*) &rt->rt6i_src - (u8*) rt);
+			sn = fib6_add_1(fn->subtree, &rt->rt6i_dst.addr,
+					sizeof(struct in6_addr), rt->rt6i_dst.plen,
+					(u8*) &rt->rt6i_dst - (u8*) rt);
 
 			if (sn == NULL)
 				goto st_failure;
 		}
 
+		/* fib6_add_1 might have cleared the old leaf pointer */
+		if (fn->leaf == NULL) {
+			fn->leaf = rt;
+			atomic_inc(&rt->rt6i_ref);
+		}
+
+		pn = fn;
 		fn = sn;
 	}
+#else 
+	fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr),
+			rt->rt6i_dst.plen, (u8*) &rt->rt6i_dst - (u8*) rt);
+
+	if (fn == NULL)
+		goto out;
 #endif
 
 	err = fib6_add_rt2node(fn, rt, nlh);
@@ -588,8 +532,29 @@
 	}
 
 out:
-	if (err)
+	if (err) {
+#ifdef CONFIG_IPV6_SUBTREES
+		/* If fib6_add_1 has cleared the old leaf pointer in the 
+		 * super-tree leaf node, we have to find a new one for it. 
+		 *
+		 * This situation will never arise in the sub-tree since 
+		 * the node will at least have the duplicate route that 
+		 * caused fib6_add_rt2node to fail in the first place.
+		 */
+
+		if (pn && !(pn->fn_flags & RTN_RTINFO)) {
+			pn->leaf = fib6_find_prefix(pn);
+#if RT6_DEBUG >= 2
+			if (!pn->leaf) {
+				BUG_TRAP(pn->leaf);
+				pn->leaf = &ip6_null_entry;
+			}
+#endif
+			atomic_inc(&pn->leaf->rt6i_ref);
+		}
+#endif
 		dst_free(&rt->u.dst);
+	}
 	return err;
 
 #ifdef CONFIG_IPV6_SUBTREES
@@ -597,8 +562,8 @@
 	   is orphan. If it is, shoot it.
 	 */
 st_failure:
-	if (fn && !(fn->fn_flags&RTN_RTINFO|RTN_ROOT))
-		fib_repair_tree(fn);
+	if (fn && !(fn->fn_flags&(RTN_RTINFO|RTN_ROOT)))
+		fib6_repair_tree(fn);
 	dst_free(&rt->u.dst);
 	return err;
 #endif
@@ -610,15 +575,15 @@
  */
 
 struct lookup_args {
-	int		offset;		/* key offset on rt6_info	*/
-	struct in6_addr	*addr;		/* search key			*/
+	int			offset;		/* key offset on rt6_info	*/
+	const struct in6_addr	*addr;		/* search key			*/
 };
 
 static struct fib6_node * fib6_lookup_1(struct fib6_node *root,
 					struct lookup_args *args)
 {
 	struct fib6_node *fn;
-	int dir;
+	int dir = 0;
 
 	/*
 	 *	Descend on a tree
@@ -628,7 +593,7 @@
 
 	for (;;) {
 		struct fib6_node *next;
-
+		if (args->addr)
 		dir = addr_bit_set(args->addr, fn->fn_bit);
 
 		next = dir ? fn->right : fn->left;
@@ -641,22 +606,28 @@
 		break;
 	}
 
-	while ((fn->fn_flags & RTN_ROOT) == 0) {
+	for(;;) {
 #ifdef CONFIG_IPV6_SUBTREES
 		if (fn->subtree) {
-			struct fib6_node *st;
-			struct lookup_args *narg;
-
-			narg = args + 1;
-
-			if (narg->addr) {
-				st = fib6_lookup_1(fn->subtree, narg);
+			struct rt6key *key;
 
-				if (st && !(st->fn_flags & RTN_ROOT))
-					return st;
+			key = (struct rt6key *) ((u8 *) fn->leaf +
+						 args->offset);
+			
+			if (!u32_prefix_cmp(&key->addr, args->addr, key->plen)) {
+				struct fib6_node *st;
+				struct lookup_args *narg = args + 1;
+				if (!ipv6_addr_any(narg->addr)) {
+					st = fib6_lookup_1(fn->subtree, narg);
+					
+					if (st && !(st->fn_flags & RTN_ROOT))
+						return st;
+				} 
 			}
 		}
 #endif
+		if (fn->fn_flags & RTN_ROOT)
+			break;
 
 		if (fn->fn_flags & RTN_RTINFO) {
 			struct rt6key *key;
@@ -664,13 +635,14 @@
 			key = (struct rt6key *) ((u8 *) fn->leaf +
 						 args->offset);
 
-			if (addr_match(&key->addr, args->addr, key->plen))
+			if (!u32_prefix_cmp(&key->addr, args->addr, key->plen))
 				return fn;
 		}
 
 		fn = fn->parent;
 	}
 
+	RT6_TRACE("no fib found, return NULL\n");
 	return NULL;
 }
 
@@ -679,14 +651,18 @@
 {
 	struct lookup_args args[2];
 	struct rt6_info *rt = NULL;
-	struct fib6_node *fn;
+	struct fib6_node *fn = NULL;
+#ifdef CONFIG_IPV6_SUBTREES
+	if (saddr == NULL)
+		saddr = &fib6_addr_any;
 
+	args[0].offset = (u8*) &rt->rt6i_src - (u8*) rt;
+	args[0].addr = saddr;
+	args[1].offset = (u8*) &rt->rt6i_dst - (u8*) rt;
+	args[1].addr = daddr;
+#else 
 	args[0].offset = (u8*) &rt->rt6i_dst - (u8*) rt;
 	args[0].addr = daddr;
-
-#ifdef CONFIG_IPV6_SUBTREES
-	args[1].offset = (u8*) &rt->rt6i_src - (u8*) rt;
-	args[1].addr = saddr;
 #endif
 
 	fn = fib6_lookup_1(root, args);
@@ -716,7 +692,7 @@
 		 *	Prefix match
 		 */
 		if (plen < fn->fn_bit ||
-		    !addr_match(&key->addr, addr, fn->fn_bit))
+		    u32_prefix_cmp(&key->addr, addr, fn->fn_bit))
 			return NULL;
 
 		if (plen == fn->fn_bit)
@@ -740,18 +716,22 @@
 	struct rt6_info *rt = NULL;
 	struct fib6_node *fn;
 
-	fn = fib6_locate_1(root, daddr, dst_len,
-			   (u8*) &rt->rt6i_dst - (u8*) rt);
-
 #ifdef CONFIG_IPV6_SUBTREES
-	if (src_len) {
-		BUG_TRAP(saddr!=NULL);
-		if (fn == NULL)
-			fn = fn->subtree;
+	if (saddr == NULL)
+		saddr = &fib6_addr_any;
+
+	fn = fib6_locate_1(root, saddr, src_len, 
+			   (u8*) &rt->rt6i_src - (u8*) rt);
+	if (dst_len) {
 		if (fn)
-			fn = fib6_locate_1(fn, saddr, src_len,
-					   (u8*) &rt->rt6i_src - (u8*) rt);
+			fn = fib6_locate_1(fn->subtree, daddr, dst_len,
+					   (u8*) &rt->rt6i_dst - (u8*) rt);
+		else 
+			return NULL;
 	}
+#else
+	fn = fib6_locate_1(root, daddr, dst_len,
+			   (u8*) &rt->rt6i_dst - (u8*) rt);
 #endif
 
 	if (fn && fn->fn_flags&RTN_RTINFO)
@@ -939,7 +919,7 @@
 			}
 			fn = fn->parent;
 		}
-		/* No more references are possiible at this point. */
+		/* No more references are possible at this point. */
 		if (atomic_read(&rt->rt6i_ref) != 1) BUG();
 	}
 
@@ -1183,6 +1163,12 @@
 	if (rt->rt6i_flags&RTF_EXPIRES && rt->rt6i_expires) {
 		if (time_after(now, rt->rt6i_expires)) {
 			RT6_TRACE("expiring %p\n", rt);
+#if !defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+			spin_lock_bh(&rt6_dflt_lock);
+			if (rt == rt6_dflt_pointer)
+				rt6_dflt_pointer = NULL;
+			spin_unlock_bh(&rt6_dflt_lock);
+#endif
 			return -1;
 		}
 		gc_args.more++;
@@ -1243,6 +1229,14 @@
 void fib6_gc_cleanup(void)
 {
 	del_timer(&ip6_fib_timer);
+	if (kmem_cache_destroy(fib6_node_kmem) == 0) {
+		RT6_TRACE("%s(): kmem_cache %p for fib6_nodes destroyed\n",
+			  __FUNCTION__, fib6_node_kmem);
+		fib6_node_kmem = NULL;
+	} else {
+		RT6_TRACE("%s(): failed to destroy kmem_cache %p for fib6_nodes.\n",
+			  __FUNCTION__, fib6_node_kmem);
+	}
 }
 #endif
 
diff -urN linux-2.4.29/net/ipv6/ip6_flowlabel.c linux-2.4.29-uc1/net/ipv6/ip6_flowlabel.c
--- linux-2.4.29/net/ipv6/ip6_flowlabel.c	2000-08-07 06:20:09.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv6/ip6_flowlabel.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: ip6_flowlabel.c,v 1.4 2000/12/29 07:06:58 yoshfuji Exp $ */
+
 /*
  *	ip6_flowlabel.c		IPv6 flowlabel manager.
  *
@@ -12,6 +14,7 @@
 #include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/types.h>
+#include <linux/random.h>
 #include <linux/socket.h>
 #include <linux/net.h>
 #include <linux/netdevice.h>
@@ -155,7 +158,8 @@
 	write_lock_bh(&ip6_fl_lock);
 	if (label == 0) {
 		for (;;) {
-			fl->label = htonl(net_random())&IPV6_FLOWLABEL_MASK;
+			get_random_bytes(&fl->label, sizeof(fl->label));
+			fl->label &= IPV6_FLOWLABEL_MASK;
 			if (fl->label) {
 				struct ip6_flowlabel *lfl;
 				lfl = __fl_lookup(fl->label);
@@ -306,7 +310,7 @@
 		msg.msg_control = (void*)(fl->opt+1);
 		flowi.oif = 0;
 
-		err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk);
+		err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk, &junk);
 		if (err)
 			goto done;
 		err = -EINVAL;
diff -urN linux-2.4.29/net/ipv6/ip6_input.c linux-2.4.29-uc1/net/ipv6/ip6_input.c
--- linux-2.4.29/net/ipv6/ip6_input.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/ip6_input.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: ip6_input.c,v 1.22 2003/08/08 13:46:38 yoshfuji Exp $ */
+
 /*
  *	IPv6 input
  *	Linux INET6 implementation 
@@ -54,11 +56,15 @@
 {
 	struct ipv6hdr *hdr;
 	u32 		pkt_len;
+	struct inet6_dev *idev = NULL;
+	int saddr_type, daddr_type;
 
 	if (skb->pkt_type == PACKET_OTHERHOST)
 		goto drop;
 
-	IP6_INC_STATS_BH(Ip6InReceives);
+	idev = in6_dev_get(dev);
+
+	IP6_INC_STATS_BH(idev,Ip6InReceives);
 
 	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
 		goto out;
@@ -79,6 +85,24 @@
 	if (hdr->version != 6)
 		goto err;
 
+	saddr_type = ipv6_addr_type(&hdr->saddr);
+	daddr_type = ipv6_addr_type(&hdr->daddr);
+
+	if ((saddr_type & IPV6_ADDR_MULTICAST) ||
+	    (daddr_type == IPV6_ADDR_ANY))
+		goto drop;	/*XXX*/
+
+	if (((saddr_type & IPV6_ADDR_LOOPBACK) ||
+	     (daddr_type & IPV6_ADDR_LOOPBACK)) &&
+	     !(dev->flags & IFF_LOOPBACK))
+		goto drop;	/*XXX*/
+
+#ifdef CONFIG_IPV6_DROP_FAKE_V4MAPPED
+	if (saddr_type == IPV6_ADDR_MAPPED ||
+	    daddr_type == IPV6_ADDR_MAPPED)
+		goto drop;	/*XXX*/
+#endif
+
 	pkt_len = ntohs(hdr->payload_len);
 
 	/* pkt_len may be zero if Jumbo payload option is present */
@@ -97,20 +121,26 @@
 	if (hdr->nexthdr == NEXTHDR_HOP) {
 		skb->h.raw = (u8*)(hdr+1);
 		if (ipv6_parse_hopopts(skb, offsetof(struct ipv6hdr, nexthdr)) < 0) {
-			IP6_INC_STATS_BH(Ip6InHdrErrors);
+			IP6_INC_STATS_BH(idev,Ip6InHdrErrors);
+			if (idev)
+				in6_dev_put(idev);
 			return 0;
 		}
 		hdr = skb->nh.ipv6h;
 	}
+	if (idev)
+		in6_dev_put(idev);
 
 	return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish);
 truncated:
-	IP6_INC_STATS_BH(Ip6InTruncatedPkts);
+	IP6_INC_STATS_BH(idev,Ip6InTruncatedPkts);
 err:
-	IP6_INC_STATS_BH(Ip6InHdrErrors);
+	IP6_INC_STATS_BH(idev,Ip6InHdrErrors);
 drop:
 	kfree_skb(skb);
 out:
+	if (idev)
+		in6_dev_put(idev);
 	return 0;
 }
 
@@ -125,7 +155,7 @@
 	struct inet6_protocol *ipprot;
 	struct sock *raw_sk;
 	int nhoff;
-	int nexthdr;
+	u8 nexthdr;
 	int found = 0;
 	u8 hash;
 
@@ -150,10 +180,10 @@
 	   which are missing with probability of 200%
 	 */
 	if (nexthdr != IPPROTO_TCP && nexthdr != IPPROTO_UDP) {
-		nhoff = ipv6_parse_exthdrs(&skb, nhoff);
+		nexthdr = skb->nh.raw[nhoff];
+		nhoff = ipv6_parse_exthdrs(&skb, nhoff, &nexthdr);
 		if (nhoff < 0)
 			return 0;
-		nexthdr = skb->nh.raw[nhoff];
 		hdr = skb->nh.ipv6h;
 	}
 
@@ -195,7 +225,10 @@
 	 *	not found: send ICMP parameter problem back
 	 */
 	if (!found) {
-		IP6_INC_STATS_BH(Ip6InUnknownProtos);
+		struct inet6_dev *idev = in6_dev_get(skb->dev);
+		IP6_INC_STATS_BH(idev,Ip6InUnknownProtos);
+		if (idev)
+			in6_dev_put(idev);
 		icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, nhoff);
 	}
 
@@ -217,8 +250,9 @@
 	struct ipv6hdr *hdr;	
 	int deliver = 0;
 	int discard = 1;
+	struct inet6_dev *idev = in6_dev_get(skb->dev);
 
-	IP6_INC_STATS_BH(Ip6InMcastPkts);
+	IP6_INC_STATS_BH(idev,Ip6InMcastPkts);
 
 	hdr = skb->nh.ipv6h;
 	if (ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, &hdr->saddr))
@@ -259,5 +293,8 @@
 	if (discard)
 		kfree_skb(skb);
 
+	if (idev)
+		in6_dev_put(idev);
+
 	return 0;
 }
diff -urN linux-2.4.29/net/ipv6/ip6_output.c linux-2.4.29-uc1/net/ipv6/ip6_output.c
--- linux-2.4.29/net/ipv6/ip6_output.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/ip6_output.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: ip6_output.c,v 1.70 2003/08/08 13:46:38 yoshfuji Exp $ */
+
 /*
  *	IPv6 output functions
  *	Linux INET6 implementation 
@@ -22,6 +24,7 @@
  *				etc.
  *
  *      H. von Brand    :       Added missing #include <linux/string.h>
+ *	S. Saaristo	:	Support for setting of traffic class.
  *	Imran Patel	: 	frag id should be in NBO
  */
 
@@ -108,6 +111,8 @@
 	skb->dev = dev;
 
 	if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) {
+		struct inet6_dev *idev;
+
 		if (!(dev->flags&IFF_LOOPBACK) &&
 		    (skb->sk == NULL || skb->sk->net_pinfo.af_inet6.mc_loop) &&
 		    ipv6_chk_mcast_addr(dev, &skb->nh.ipv6h->daddr,
@@ -128,7 +133,10 @@
 			}
 		}
 
-		IP6_INC_STATS(Ip6OutMcastPkts);
+		idev = in6_dev_get(dev);
+		IP6_INC_STATS(idev,Ip6OutMcastPkts);
+		if (idev)
+			in6_dev_put(idev);
 	}
 
 	return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish);
@@ -182,6 +190,7 @@
 
 /*
  *	xmit an sk_buff (used by TCP)
+ *	  (this does the real work)
  */
 
 int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
@@ -193,15 +202,17 @@
 	struct ipv6hdr *hdr;
 	u8  proto = fl->proto;
 	int seg_len = skb->len;
-	int hlimit;
+	int hlimit = -1;
+	u8 tclass = 0;
+	int retval = 0;
 
 	if (opt) {
-		int head_room;
+		int head_room = 0;
 
 		/* First: exthdrs may take lots of space (~8K for now)
 		   MAX_HEADER is not enough.
 		 */
-		head_room = opt->opt_nflen + opt->opt_flen;
+		head_room += opt->opt_nflen + opt->opt_flen;
 		seg_len += head_room;
 		head_room += sizeof(struct ipv6hdr) + ((dst->dev->hard_header_len + 15)&~15);
 
@@ -209,8 +220,11 @@
 			struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
 			kfree_skb(skb);
 			skb = skb2;
-			if (skb == NULL)
-				return -ENOBUFS;
+			if (skb == NULL) {
+				printk(KERN_DEBUG "Could not allocate new skb!\n");
+				retval = -ENOBUFS;
+				goto out;
+			}
 			if (sk)
 				skb_set_owner_w(skb, sk);
 		}
@@ -220,16 +234,22 @@
 			ipv6_push_nfrag_opts(skb, opt, &proto, &first_hop);
 	}
 
+	if (np) {
+		hlimit = np->hop_limit;
+		tclass = np->tclass;
+	}
+
 	hdr = skb->nh.ipv6h = (struct ipv6hdr*)skb_push(skb, sizeof(struct ipv6hdr));
 
 	/*
 	 *	Fill in the IPv6 header
 	 */
 
-	*(u32*)hdr = htonl(0x60000000) | fl->fl6_flowlabel;
-	hlimit = -1;
-	if (np)
-		hlimit = np->hop_limit;
+	if (fl->fl6_flowlabel)
+		*(u32*)hdr = htonl(0x60000000) | fl->fl6_flowlabel;
+	else
+		*(u32*)hdr = htonl(0x60000000 | (tclass << 20));
+
 	if (hlimit < 0)
 		hlimit = ((struct rt6_info*)dst)->rt6i_hoplimit;
 
@@ -241,16 +261,23 @@
 	ipv6_addr_copy(&hdr->daddr, first_hop);
 
 	if (skb->len <= dst->pmtu) {
-		IP6_INC_STATS(Ip6OutRequests);
-		return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
+		struct inet6_dev *idev = in6_dev_get(dst->dev);
+		IP6_INC_STATS(idev,Ip6OutRequests);
+		if (idev)
+			in6_dev_put(idev);
+		retval = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
+		goto out;
 	}
 
+	/* packet is too big */
 	if (net_ratelimit())
 		printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
-	skb->dev = dst->dev;
-	icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst->pmtu, skb->dev);
+	icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst->pmtu, &loopback_dev);
 	kfree_skb(skb);
-	return -EMSGSIZE;
+
+	retval = -EMSGSIZE;
+out:
+	return retval;
 }
 
 /*
@@ -276,7 +303,7 @@
 	hdr = (struct ipv6hdr *) skb_put(skb, sizeof(struct ipv6hdr));
 	skb->nh.ipv6h = hdr;
 
-	*(u32*)hdr = htonl(0x60000000);
+	*(u32*)hdr = htonl(0x60000000 | (np->tclass << 20));
 
 	hdr->payload_len = htons(len);
 	hdr->nexthdr = proto;
@@ -289,14 +316,17 @@
 }
 
 static struct ipv6hdr * ip6_bld_1(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
-				  int hlimit, unsigned pktlength)
+				  int hlimit, u8 tclass, unsigned pktlength)
 {
 	struct ipv6hdr *hdr;
 	
 	skb->nh.raw = skb_put(skb, sizeof(struct ipv6hdr));
 	hdr = skb->nh.ipv6h;
 	
-	*(u32*)hdr = fl->fl6_flowlabel | htonl(0x60000000);
+	if (fl->fl6_flowlabel)
+		*(u32*)hdr = htonl(0x60000000) | fl->fl6_flowlabel;
+	else
+		*(u32*)hdr = htonl(0x60000000 | (tclass << 20));
 
 	hdr->payload_len = htons(pktlength - sizeof(struct ipv6hdr));
 	hdr->hop_limit = hlimit;
@@ -327,10 +357,12 @@
 			 const void *data, struct dst_entry *dst,
 			 struct flowi *fl, struct ipv6_txoptions *opt,
 			 struct in6_addr *final_dst,
-			 int hlimit, int flags, unsigned length, int mtu)
+			 int hlimit, u8 tclass, 
+			 int flags, unsigned length, int mtu)
 {
 	struct ipv6hdr *hdr;
 	struct sk_buff *last_skb;
+	struct inet6_dev *idev = in6_dev_get(dst->dev);
 	u8 *prev_hdr;
 	int unfrag_len;
 	int frag_len;
@@ -372,6 +404,8 @@
 	/* Unfragmentable part exceeds mtu. */
 	if (frag_len <= 0) {
 		ipv6_local_error(sk, EMSGSIZE, fl, mtu);
+		if (idev)
+			in6_dev_put(idev);
 		return -EMSGSIZE;
 	}
 
@@ -404,26 +438,34 @@
 	if (opt) {
 		if (frag_len < opt->opt_flen) {
 			ipv6_local_error(sk, EMSGSIZE, fl, mtu);
+			if (idev)
+				in6_dev_put(idev);
 			return -EMSGSIZE;
 		}
 		data_off = frag_off - opt->opt_flen;
 	}
 
-	if (flags&MSG_PROBE)
+	if (flags&MSG_PROBE){
+		if (idev)
+			in6_dev_put(idev);
 		return 0;
+	}
 
 	last_skb = sock_alloc_send_skb(sk, unfrag_len + frag_len +
 				       dst->dev->hard_header_len + 15,
 				       flags & MSG_DONTWAIT, &err);
 
-	if (last_skb == NULL)
+	if (last_skb == NULL){
+		if (idev)
+			in6_dev_put(idev);
 		return err;
+	}
 
 	last_skb->dst = dst_clone(dst);
 
 	skb_reserve(last_skb, (dst->dev->hard_header_len + 15) & ~15);
 
-	hdr = ip6_bld_1(sk, last_skb, fl, hlimit, frag_len+unfrag_len);
+	hdr = ip6_bld_1(sk, last_skb, fl, hlimit, tclass, frag_len+unfrag_len);
 	prev_hdr = &hdr->nexthdr;
 
 	if (opt && opt->opt_nflen)
@@ -443,7 +485,9 @@
 			skb = skb_copy(last_skb, sk->allocation);
 
 			if (skb == NULL) {
-				IP6_INC_STATS(Ip6FragFails);
+				IP6_INC_STATS(idev,Ip6FragFails);
+				if (idev)
+					in6_dev_put(idev);
 				kfree_skb(last_skb);
 				return -ENOMEM;
 			}
@@ -471,10 +515,12 @@
 				break;
 			}
 
-			IP6_INC_STATS(Ip6FragCreates);
-			IP6_INC_STATS(Ip6OutRequests);
+			IP6_INC_STATS(idev,Ip6FragCreates);
+			IP6_INC_STATS(idev,Ip6OutRequests);
 			err = NF_HOOK(PF_INET6,NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
 			if (err) {
+				if (idev)
+					in6_dev_put(idev);
 				kfree_skb(last_skb);
 				return err;
 			}
@@ -482,7 +528,9 @@
 	}
 
 	if (err) {
-		IP6_INC_STATS(Ip6FragFails);
+		IP6_INC_STATS(idev,Ip6FragFails);
+		if (idev)
+			in6_dev_put(idev);
 		kfree_skb(last_skb);
 		return -EFAULT;
 	}
@@ -496,22 +544,30 @@
 
 	skb_put(last_skb, last_len);
 
-	IP6_INC_STATS(Ip6FragCreates);
-	IP6_INC_STATS(Ip6FragOKs);
-	IP6_INC_STATS(Ip6OutRequests);
+	IP6_INC_STATS(idev,Ip6FragCreates);
+	IP6_INC_STATS(idev,Ip6FragOKs);
+	IP6_INC_STATS(idev,Ip6OutRequests);
+	if (idev)
+		in6_dev_put(idev);
 	return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, last_skb, NULL,dst->dev, ip6_maybe_reroute);
 }
 
 int ip6_build_xmit(struct sock *sk, inet_getfrag_t getfrag, const void *data,
 		   struct flowi *fl, unsigned length,
-		   struct ipv6_txoptions *opt, int hlimit, int flags)
+		   struct ipv6_txoptions *opt, int hlimit, int aux_tclass, int flags)
 {
 	struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
 	struct in6_addr *final_dst = NULL;
-	struct dst_entry *dst;
+	struct dst_entry *dst = NULL;
+	struct rt6_info *rt;
+	struct inet6_dev *idev;
+#ifdef CONFIG_IPV6_SUBTREES
+	int reroute = 0;
+#endif
 	int err = 0;
 	unsigned int pktlength, jumbolen, mtu;
 	struct in6_addr saddr;
+	u8 tclass;
 
 	if (opt && opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
@@ -521,10 +577,10 @@
 
 	if (!fl->oif && ipv6_addr_is_multicast(fl->nl_u.ip6_u.daddr))
 		fl->oif = np->mcast_oif;
-
-	dst = __sk_dst_check(sk, np->dst_cookie);
+	if (dst == NULL)
+		dst = __sk_dst_check(sk, np->dst_cookie);
 	if (dst) {
-		struct rt6_info *rt = (struct rt6_info*)dst;
+		rt = (struct rt6_info*)dst;
 
 			/* Yes, checking route validity in not connected
 			   case is not very simple. Take into account,
@@ -548,6 +604,14 @@
 		      ipv6_addr_cmp(fl->fl6_dst, &rt->rt6i_dst.addr))
 		     && (np->daddr_cache == NULL ||
 			 ipv6_addr_cmp(fl->fl6_dst, np->daddr_cache)))
+#ifdef CONFIG_IPV6_SUBTREES
+		    || (fl->fl6_src
+			&& (!ipv6_addr_any(fl->fl6_src)
+			&& (rt->rt6i_src.plen != 128 ||
+			    ipv6_addr_cmp(fl->fl6_src, &rt->rt6i_src.addr))
+			&& (np->saddr_cache == NULL ||
+			    ipv6_addr_cmp(fl->fl6_src, np->saddr_cache))))
+#endif
 		    || (fl->oif && fl->oif != dst->dev->ifindex)) {
 			dst = NULL;
 		} else
@@ -557,14 +621,24 @@
 	if (dst == NULL)
 		dst = ip6_route_output(sk, fl);
 
+	idev = in6_dev_get(dst->dev);
+
+#ifdef CONFIG_IPV6_SUBTREES
+	reroute = (dst->error == -EAGAIN);
+
+	if (!reroute && dst->error) {
+#else 
 	if (dst->error) {
-		IP6_INC_STATS(Ip6OutNoRoutes);
+#endif
+		IP6_INC_STATS(idev,Ip6OutNoRoutes);	/*XXX(?)*/
+		if (idev)
+			in6_dev_put(idev);
 		dst_release(dst);
 		return -ENETUNREACH;
 	}
 
 	if (fl->fl6_src == NULL) {
-		err = ipv6_get_saddr(dst, fl->fl6_dst, &saddr);
+		err = ipv6_get_saddr(dst, fl->fl6_dst, &saddr, np->use_tempaddr);
 
 		if (err) {
 #if IP6_DEBUG >= 2
@@ -574,7 +648,24 @@
 			goto out;
 		}
 		fl->fl6_src = &saddr;
+#ifdef CONFIG_IPV6_SUBTREES
+		rt = (struct rt6_info*)dst;
+		if (ipv6_addr_cmp(fl->fl6_src, &np->saddr) && 
+		    (rt->rt6i_src.plen != 128 || 
+		     ipv6_addr_cmp(fl->fl6_src, &rt->rt6i_src.addr))) {
+			dst_release(dst);
+			dst = ip6_route_output(sk, fl);
+			if (dst->error) {
+				IP6_INC_STATS( idev, Ip6OutNoRoutes);
+				if (idev)
+					in6_dev_put(idev);
+				dst_release(dst);
+				return -ENETUNREACH;
+			}
+		}
+#endif
 	}
+
 	pktlength = length;
 
 	if (hlimit < 0) {
@@ -611,6 +702,8 @@
 			mtu = IPV6_MIN_MTU;
 	}
 
+	tclass = aux_tclass >= 0 ? aux_tclass : np->tclass;
+
 	/* Critical arithmetic overflow check.
 	   FIXME: may gcc optimize it out? --ANK (980726)
 	 */
@@ -637,7 +730,7 @@
 					  flags & MSG_DONTWAIT, &err);
 
 		if (skb == NULL) {
-			IP6_INC_STATS(Ip6OutDiscards);
+			IP6_INC_STATS(idev,Ip6OutDiscards);
 			goto out;
 		}
 
@@ -648,8 +741,9 @@
 		hdr = (struct ipv6hdr *) skb->tail;
 		skb->nh.ipv6h = hdr;
 
+
 		if (!sk->protinfo.af_inet.hdrincl) {
-			ip6_bld_1(sk, skb, fl, hlimit,
+			ip6_bld_1(sk, skb, fl, hlimit, tclass,
 				  jumbolen ? sizeof(struct ipv6hdr) : pktlength);
 
 			if (opt || jumbolen) {
@@ -666,7 +760,7 @@
 			      0, length);
 
 		if (!err) {
-			IP6_INC_STATS(Ip6OutRequests);
+			IP6_INC_STATS(idev,Ip6OutRequests);
 			err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
 		} else {
 			err = -EFAULT;
@@ -681,6 +775,7 @@
 		}
 
 		err = ip6_frag_xmit(sk, getfrag, data, dst, fl, opt, final_dst, hlimit,
+				    tclass,
 				    flags, length, mtu);
 	}
 
@@ -688,9 +783,16 @@
 	 *	cleanup
 	 */
 out:
-	ip6_dst_store(sk, dst, fl->nl_u.ip6_u.daddr == &np->daddr ? &np->daddr : NULL);
+	if (idev)
+		in6_dev_put(idev);
+	ip6_dst_store(sk, dst, 
+ 		      !ipv6_addr_cmp(fl->fl6_dst, &np->daddr) ?
+		      &np->daddr : NULL,
+		      !ipv6_addr_cmp(fl->fl6_src, &np->saddr) ?
+		      &np->saddr : NULL);
 	if (err > 0)
 		err = np->recverr ? net_xmit_errno(err) : 0;
+
 	return err;
 }
 
@@ -729,10 +831,12 @@
 int ip6_forward(struct sk_buff *skb)
 {
 	struct dst_entry *dst = skb->dst;
+	struct inet6_dev *idev = in6_dev_get(dst->dev);
 	struct ipv6hdr *hdr = skb->nh.ipv6h;
 	struct inet6_skb_parm *opt =(struct inet6_skb_parm*)skb->cb;
 	
-	if (ipv6_devconf.forwarding == 0)
+	/* XXX: how about idev_of_input_device->cnf.forwarding? */
+	if (ipv6_devconf.forwarding == 0 && opt->srcrt == 0)
 		goto error;
 
 	skb->ip_summed = CHECKSUM_NONE;
@@ -752,8 +856,11 @@
 	 */
 	if (opt->ra) {
 		u8 *ptr = skb->nh.raw + opt->ra;
-		if (ip6_call_ra_chain(skb, (ptr[2]<<8) + ptr[3]))
+		if (ip6_call_ra_chain(skb, (ptr[2]<<8) + ptr[3])) {
+			if (idev)
+				in6_dev_put(idev);
 			return 0;
+		}
 	}
 
 	/*
@@ -764,7 +871,8 @@
 		skb->dev = dst->dev;
 		icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
 			    0, skb->dev);
-
+		if (idev)
+			in6_dev_put(idev);
 		kfree_skb(skb);
 		return -ETIMEDOUT;
 	}
@@ -802,8 +910,13 @@
 	if (skb->len > dst->pmtu) {
 		/* Again, force OUTPUT device used as source address */
 		skb->dev = dst->dev;
+		if (idev)
+			in6_dev_put(idev);
+		idev = in6_dev_get(skb->dev);
 		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst->pmtu, skb->dev);
-		IP6_INC_STATS_BH(Ip6InTooBigErrors);
+		IP6_INC_STATS_BH(idev,Ip6InTooBigErrors);
+		if (idev)
+			in6_dev_put(idev);
 		kfree_skb(skb);
 		return -EMSGSIZE;
 	}
@@ -817,12 +930,16 @@
  
 	hdr->hop_limit--;
 
-	IP6_INC_STATS_BH(Ip6OutForwDatagrams);
+	IP6_INC_STATS_BH(idev,Ip6OutForwDatagrams);
+	if (idev)
+		in6_dev_put(idev);
 	return NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish);
 
 error:
-	IP6_INC_STATS_BH(Ip6InAddrErrors);
+	IP6_INC_STATS_BH(idev,Ip6InAddrErrors);
 drop:
+	if (idev)
+		in6_dev_put(idev);
 	kfree_skb(skb);
 	return -EINVAL;
 }
diff -urN linux-2.4.29/net/ipv6/ipv6_sockglue.c linux-2.4.29-uc1/net/ipv6/ipv6_sockglue.c
--- linux-2.4.29/net/ipv6/ipv6_sockglue.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/ipv6_sockglue.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: ipv6_sockglue.c,v 1.40 2003/08/08 13:46:38 yoshfuji Exp $ */
+
 /*
  *	IPv6 BSD socket options interface
  *	Linux INET6 implementation 
@@ -16,8 +18,6 @@
  *
  *	FIXME: Make the setsockopt code POSIX compliant: That is
  *
- *	o	Return -EINVAL for setsockopt of short lengths
- *	o	Truncate getsockopt returns
  *	o	Return an optlen of the truncated length if need be
  *
  *	Changes:
@@ -141,9 +141,12 @@
 	if(level!=SOL_IPV6)
 		goto out;
 
+	if (optlen < 0)
+		goto e_inval;
+
 	if (optval == NULL)
 		val=0;
-	else if (get_user(val, (int *) optval))
+	else if (get_user(val, (int *) optval) && get_user(val, (u8 *) optval))
 		return -EFAULT;
 
 	valbool = (val!=0);
@@ -152,6 +155,7 @@
 
 	switch (optname) {
 
+	/* XXX: IPV6_ADDRFORM is deprecated */
 	case IPV6_ADDRFORM:
 		if (val == PF_INET) {
 			struct ipv6_txoptions *opt;
@@ -214,6 +218,10 @@
 		goto e_inval;
 
 	case IPV6_V6ONLY:
+		if (optlen != sizeof(int))
+			goto e_inval;
+		if (sk->userlocks&SOCK_BINDADDR_LOCK)
+			goto e_inval;
 		if (sk->num)
 			goto e_inval;
 		np->ipv6only = valbool;
@@ -221,16 +229,22 @@
 		break;
 
 	case IPV6_PKTINFO:
+		if (optlen != sizeof(int))
+			goto e_inval;
 		np->rxopt.bits.rxinfo = valbool;
 		retv = 0;
 		break;
 
 	case IPV6_HOPLIMIT:
+		if (optlen != sizeof(int))
+			goto e_inval;
 		np->rxopt.bits.rxhlim = valbool;
 		retv = 0;
 		break;
 
 	case IPV6_RTHDR:
+		if (optlen != sizeof(int))
+			goto e_inval;
 		if (val < 0 || val > 2)
 			goto e_inval;
 		np->rxopt.bits.srcrt = val;
@@ -238,21 +252,29 @@
 		break;
 
 	case IPV6_HOPOPTS:
+		if (optlen != sizeof(int))
+			goto e_inval;
 		np->rxopt.bits.hopopts = valbool;
 		retv = 0;
 		break;
 
 	case IPV6_AUTHHDR:
+		if (optlen != sizeof(int))
+			goto e_inval;
 		np->rxopt.bits.authhdr = valbool;
 		retv = 0;
 		break;
 
 	case IPV6_DSTOPTS:
+		if (optlen != sizeof(int))
+			goto e_inval;
 		np->rxopt.bits.dstopts = valbool;
 		retv = 0;
 		break;
 
 	case IPV6_FLOWINFO:
+		if (optlen != sizeof(int))
+			goto e_inval;
 		np->rxopt.bits.rxflow = valbool;
 		retv = 0;
 		break;
@@ -267,7 +289,7 @@
 		fl.fl6_flowlabel = 0;
 		fl.oif = sk->bound_dev_if;
 
-		if (optlen == 0)
+		if (!optval || optlen == 0)
 			goto update;
 
 		/* 1K is probably excessive
@@ -291,7 +313,7 @@
 		msg.msg_controllen = optlen;
 		msg.msg_control = (void*)(opt+1);
 
-		retv = datagram_send_ctl(&msg, &fl, opt, &junk);
+		retv = datagram_send_ctl(&msg, &fl, opt, &junk, &junk);
 		if (retv)
 			goto done;
 update:
@@ -320,6 +342,8 @@
 		break;
 	}
 	case IPV6_UNICAST_HOPS:
+		if (optlen != sizeof(int))
+			goto e_inval;
 		if (val > 255 || val < -1)
 			goto e_inval;
 		np->hop_limit = val;
@@ -327,6 +351,8 @@
 		break;
 
 	case IPV6_MULTICAST_HOPS:
+		if (optlen != sizeof(int))
+			goto e_inval;
 		if (sk->type == SOCK_STREAM)
 			goto e_inval;
 		if (val > 255 || val < -1)
@@ -336,11 +362,17 @@
 		break;
 
 	case IPV6_MULTICAST_LOOP:
+		if (optlen != sizeof(int))
+			goto e_inval;
+		if (val != 0 && val != 1)
+			goto e_inval;
 		np->mc_loop = valbool;
 		retv = 0;
 		break;
 
 	case IPV6_MULTICAST_IF:
+		if (optlen != sizeof(int))
+			goto e_inval;
 		if (sk->type == SOCK_STREAM)
 			goto e_inval;
 		if (sk->bound_dev_if && sk->bound_dev_if != val)
@@ -353,16 +385,19 @@
 		np->mcast_oif = val;
 		retv = 0;
 		break;
-	case IPV6_ADD_MEMBERSHIP:
-	case IPV6_DROP_MEMBERSHIP:
+	case IPV6_JOIN_GROUP:
+	case IPV6_LEAVE_GROUP:
 	{
 		struct ipv6_mreq mreq;
 
+		if (optlen != sizeof(struct ipv6_mreq))
+			goto e_inval;
+
 		retv = -EFAULT;
 		if (copy_from_user(&mreq, optval, sizeof(struct ipv6_mreq)))
 			break;
 
-		if (optname == IPV6_ADD_MEMBERSHIP)
+		if (optname == IPV6_JOIN_GROUP)
 			retv = ipv6_sock_mc_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr);
 		else
 			retv = ipv6_sock_mc_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr);
@@ -493,24 +528,32 @@
 		retv = ip6_ra_control(sk, val, NULL);
 		break;
 	case IPV6_MTU_DISCOVER:
+		if (optlen != sizeof(int))
+			goto e_inval;
 		if (val<0 || val>2)
 			goto e_inval;
 		np->pmtudisc = val;
 		retv = 0;
 		break;
 	case IPV6_MTU:
+		if (optlen != sizeof(int))
+			goto e_inval;
 		if (val && val < IPV6_MIN_MTU)
 			goto e_inval;
 		np->frag_size = val;
 		retv = 0;
 		break;
 	case IPV6_RECVERR:
+		if (optlen != sizeof(int))
+			goto e_inval;
 		np->recverr = valbool;
 		if (!val)
 			skb_queue_purge(&sk->error_queue);
 		retv = 0;
 		break;
 	case IPV6_FLOWINFO_SEND:
+		if (optlen != sizeof(int))
+			goto e_inval;
 		np->sndflow = valbool;
 		retv = 0;
 		break;
@@ -518,6 +561,34 @@
 		retv = ipv6_flowlabel_opt(sk, optval, optlen);
 		break;
 
+	case IPV6_RECVTCLASS:
+		if (optlen != sizeof(int))
+			goto e_inval;
+		np->recvopt.tclass = valbool;
+		retv = 0;
+		break;
+
+	case IPV6_TCLASS:
+		if (optlen != sizeof(int))
+			goto e_inval;
+		np->tclass = val;
+		retv = 0;
+		break;
+
+#ifdef CONFIG_IPV6_PRIVACY
+	case IPV6_PRIVACY:
+		if (optlen != sizeof(int))
+			goto e_inval;
+		if (val > 0)
+			np->use_tempaddr = 1;
+		else if (val < 0)
+			np->use_tempaddr = -1;
+		else
+			np->use_tempaddr = 0;
+		retv = 0;
+		break;
+#endif
+
 #ifdef CONFIG_NETFILTER
 	default:
 		retv = nf_setsockopt(sk, PF_INET6, optname, optval, 
@@ -549,6 +620,8 @@
 		return -ENOPROTOOPT;
 	if (get_user(len, optlen))
 		return -EFAULT;
+	if (optlen < 0)
+		return -EINVAL;
 	switch (optname) {
 	case IPV6_PKTOPTIONS:
 	{
@@ -588,6 +661,7 @@
 		len -= msg.msg_controllen;
 		return put_user(len, optlen);
 	}
+
 	case IPV6_MTU:
 	{
 		struct dst_entry *dst;
@@ -679,6 +753,24 @@
 		val = np->sndflow;
 		break;
 
+	case IPV6_JOIN_GROUP:
+	case IPV6_LEAVE_GROUP:
+		return -EOPNOTSUPP;
+
+	case IPV6_RECVTCLASS:
+                val = np->recvopt.tclass;
+                break;
+
+	case IPV6_TCLASS:
+		val = np->tclass;
+                break;
+
+#ifdef CONFIG_IPV6_PRIVACY
+	case IPV6_PRIVACY:
+		val = np->use_tempaddr;
+		break;
+#endif
+
 	default:
 #ifdef CONFIG_NETFILTER
 		lock_sock(sk);
diff -urN linux-2.4.29/net/ipv6/ipv6_syms.c linux-2.4.29-uc1/net/ipv6/ipv6_syms.c
--- linux-2.4.29/net/ipv6/ipv6_syms.c	2004-04-14 14:05:41.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv6/ipv6_syms.c	2005-06-14 02:11:52.000000000 +0100
@@ -6,17 +6,20 @@
 #include <net/ipv6.h>
 #include <net/addrconf.h>
 #include <net/ip6_route.h>
+#include <linux/inet.h>
 
-EXPORT_SYMBOL(ipv6_addr_type);
+EXPORT_SYMBOL(__ipv6_addr_type);
 EXPORT_SYMBOL(icmpv6_send);
 EXPORT_SYMBOL(icmpv6_statistics);
 EXPORT_SYMBOL(icmpv6_err_convert);
 EXPORT_SYMBOL(ndisc_mc_map);
 EXPORT_SYMBOL(register_inet6addr_notifier);
 EXPORT_SYMBOL(unregister_inet6addr_notifier);
+EXPORT_SYMBOL(ip6_build_xmit);
 EXPORT_SYMBOL(ip6_route_output);
 #ifdef CONFIG_NETFILTER
 EXPORT_SYMBOL(ip6_route_me_harder);
+EXPORT_SYMBOL(ipv6_ext_hdr);
 #endif
 EXPORT_SYMBOL(addrconf_lock);
 EXPORT_SYMBOL(ipv6_setsockopt);
@@ -32,6 +35,14 @@
 EXPORT_SYMBOL(inet6_ioctl);
 EXPORT_SYMBOL(ipv6_get_saddr);
 EXPORT_SYMBOL(ipv6_chk_addr);
+EXPORT_SYMBOL(inet6_ifa_finish_destroy);
+EXPORT_SYMBOL(ipv6_get_ifaddr);
 EXPORT_SYMBOL(in6_dev_finish_destroy);
 EXPORT_SYMBOL(ipv6_skip_exthdr);
+EXPORT_SYMBOL(fl6_sock_lookup);
+EXPORT_SYMBOL(rt6_lookup);
+
+#ifdef CONFIG_IPV6
+EXPORT_SYMBOL(in6_ntop);
+#endif
 
diff -urN linux-2.4.29/net/ipv6/ipv6_tunnel.c linux-2.4.29-uc1/net/ipv6/ipv6_tunnel.c
--- linux-2.4.29/net/ipv6/ipv6_tunnel.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv6/ipv6_tunnel.c	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,1898 @@
+/*
+ *	IPv6 over IPv6 tunnel device
+ *	Linux INET6 implementation
+ *
+ *	Authors:
+ *	Ville Nuorvala		<vnuorval@tml.hut.fi>	
+ *
+ *	$Id: s.ipv6_tunnel.c 1.23 02/11/29 15:33:51+02:00 vnuorval@amber.hut.mediapoli.com $
+ *
+ *      Based on:
+ *      linux/net/ipv6/sit.c
+ *
+ *      RFC 2473
+ *
+ *	This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ *
+ */
+
+#define __NO_VERSION__
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <linux/if.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/if_tunnel.h>
+#include <linux/net.h>
+#include <linux/in6.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/icmpv6.h>
+#include <linux/init.h>
+#include <linux/route.h>
+#include <linux/rtnetlink.h>
+#include <linux/tqueue.h>
+
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+
+#include <net/sock.h>
+#include <net/ipv6.h>
+#include <net/protocol.h>
+#include <net/ip6_route.h>
+#include <net/addrconf.h>
+#include <net/ipv6_tunnel.h>
+
+#ifdef MODULE
+MODULE_AUTHOR("Ville Nuorvala");
+MODULE_DESCRIPTION("IPv6 over IPv6 tunnel");
+MODULE_LICENSE("GPL");
+#endif
+
+#ifdef IPV6_TNL_DEBUG
+#define IPV6_TNL_TRACE(x...) printk(KERN_DEBUG __FUNCTION__ x "\n")
+#else
+#define IPV6_TNL_TRACE(x...) do {;} while(0)
+#endif
+
+/* socket used by ipv6_ipv6_tnl_xmit() for resending packets */
+static struct socket *ipv6_socket;
+
+/* current holder of socket */
+static int ipv6_xmit_holder = -1;
+
+/* socket locking functions copied from net/ipv6/icmp.c */
+
+static int
+ipv6_xmit_lock_bh(void)
+{
+	if (!spin_trylock(&ipv6_socket->sk->lock.slock)) {
+		if (ipv6_xmit_holder == smp_processor_id())
+			return -EAGAIN;
+		spin_lock(&ipv6_socket->sk->lock.slock);
+	}
+	ipv6_xmit_holder = smp_processor_id();
+	return 0;
+}
+
+static inline int
+ipv6_xmit_lock(void)
+{
+	int ret;
+	local_bh_disable();
+	ret = ipv6_xmit_lock_bh();
+	if (ret)
+		local_bh_enable();
+	return ret;
+}
+
+static void
+ipv6_xmit_unlock_bh(void)
+{
+	ipv6_xmit_holder = -1;
+	spin_unlock(&ipv6_socket->sk->lock.slock);
+}
+
+static inline void
+ipv6_xmit_unlock(void)
+{
+	ipv6_xmit_unlock_bh();
+	local_bh_enable();
+}
+
+#define HASH_SIZE  32
+
+#define HASH(addr) (((addr)->s6_addr16[0] ^ (addr)->s6_addr16[1] ^ \
+	             (addr)->s6_addr16[2] ^ (addr)->s6_addr16[3] ^ \
+                     (addr)->s6_addr16[4] ^ (addr)->s6_addr16[5] ^ \
+	             (addr)->s6_addr16[6] ^ (addr)->s6_addr16[7]) & \
+                    (HASH_SIZE - 1))
+
+static int ipv6_ipv6_fb_tnl_dev_init(struct net_device *dev);
+static int ipv6_ipv6_tnl_dev_init(struct net_device *dev);
+
+/* the IPv6 IPv6 tunnel fallback device */
+static struct net_device ipv6_ipv6_fb_tnl_dev = {
+	name:"ip6tnl0",
+	init:ipv6_ipv6_fb_tnl_dev_init
+};
+
+/* the IPv6 IPv6 fallback tunnel */
+static struct ipv6_tnl ipv6_ipv6_fb_tnl = {
+	dev:&ipv6_ipv6_fb_tnl_dev,
+      parms:{name: "ip6tnl0", proto:IPPROTO_IPV6}
+};
+
+/* lists for storing tunnels in use */
+static struct ipv6_tnl *tnls_r_l[HASH_SIZE];
+static struct ipv6_tnl *tnls_wc[1];
+static struct ipv6_tnl **tnls[2] = { tnls_wc, tnls_r_l };
+
+/* list for unused cached kernel tunnels */
+static struct ipv6_tnl *tnls_kernel[1];
+/* maximum number of cached kernel tunnels */
+static unsigned int max_kdev_count = 0;
+/* minimum number of cached kernel tunnels */
+static unsigned int min_kdev_count = 0;
+/* current number of cached kernel tunnels */
+static unsigned int kdev_count = 0;
+
+/* lists for tunnel hook functions */
+static struct list_head hooks[IPV6_TNL_MAXHOOKS];
+
+/* locks for the different lists */
+static rwlock_t ipv6_ipv6_lock = RW_LOCK_UNLOCKED;
+static rwlock_t ipv6_ipv6_kernel_lock = RW_LOCK_UNLOCKED;
+static rwlock_t ipv6_ipv6_hook_lock = RW_LOCK_UNLOCKED;
+
+/* flag indicating if the module is being removed */
+static int shutdown = 0;
+
+/**
+ * ipv6_ipv6_tnl_lookup - fetch tunnel matching the end-point addresses
+ *   @remote: the address of the tunnel exit-point 
+ *   @local: the address of the tunnel entry-point 
+ *
+ * Return:  
+ *   tunnel matching given end-points if found,
+ *   else fallback tunnel if its device is up, 
+ *   else %NULL
+ **/
+
+struct ipv6_tnl *
+ipv6_ipv6_tnl_lookup(struct in6_addr *remote, struct in6_addr *local)
+{
+	unsigned h0 = HASH(remote);
+	unsigned h1 = HASH(local);
+	struct ipv6_tnl *t;
+
+	IPV6_TNL_TRACE();
+
+	for (t = tnls_r_l[h0 ^ h1]; t; t = t->next) {
+		if (!ipv6_addr_cmp(local, &t->parms.laddr) &&
+		    !ipv6_addr_cmp(remote, &t->parms.raddr) &&
+		    (t->dev->flags & IFF_UP))
+			return t;
+	}
+	if ((t = tnls_wc[0]) != NULL && (t->dev->flags & IFF_UP))
+		return t;
+
+	return NULL;
+}
+
+/**
+ * ipv6_ipv6_bucket - get head of list matching given tunnel parameters
+ *   @p: parameters containing tunnel end-points 
+ *
+ * Description:
+ *   ipv6_ipv6_bucket() returns the head of the list matching the 
+ *   &struct in6_addr entries laddr and raddr in @p.
+ *
+ * Return: head of IPv6 tunnel list 
+ **/
+
+static struct ipv6_tnl **
+ipv6_ipv6_bucket(struct ipv6_tnl_parm *p)
+{
+	struct in6_addr *remote = &p->raddr;
+	struct in6_addr *local = &p->laddr;
+	unsigned h = 0;
+	int prio = 0;
+
+	IPV6_TNL_TRACE();
+
+	if (!ipv6_addr_any(remote) || !ipv6_addr_any(local)) {
+		prio = 1;
+		h = HASH(remote) ^ HASH(local);
+	}
+	return &tnls[prio][h];
+}
+
+/**
+ * ipv6_ipv6_kernel_tnl_link - add new kernel tunnel to cache
+ *   @t: kernel tunnel
+ *
+ * Note:
+ *   %IPV6_TNL_F_KERNEL_DEV is assumed to be raised in t->parms.flags. 
+ *   See the comments on ipv6_ipv6_kernel_tnl_add() for more information.
+ **/
+
+static inline void
+ipv6_ipv6_kernel_tnl_link(struct ipv6_tnl *t)
+{
+	IPV6_TNL_TRACE();
+
+	write_lock_bh(&ipv6_ipv6_kernel_lock);
+	t->next = tnls_kernel[0];
+	tnls_kernel[0] = t;
+	kdev_count++;
+	write_unlock_bh(&ipv6_ipv6_kernel_lock);
+}
+
+/**
+ * ipv6_ipv6_kernel_tnl_unlink - remove first kernel tunnel from cache
+ *
+ * Return: first free kernel tunnel
+ *
+ * Note:
+ *   See the comments on ipv6_ipv6_kernel_tnl_add() for more information.
+ **/
+
+static inline struct ipv6_tnl *
+ipv6_ipv6_kernel_tnl_unlink(void)
+{
+	struct ipv6_tnl *t;
+
+	IPV6_TNL_TRACE();
+
+	write_lock_bh(&ipv6_ipv6_kernel_lock);
+	if ((t = tnls_kernel[0]) != NULL) {
+		tnls_kernel[0] = t->next;
+		kdev_count--;
+	}
+	write_unlock_bh(&ipv6_ipv6_kernel_lock);
+	return t;
+}
+
+/**
+ * ipv6_ipv6_tnl_link - add tunnel to hash table
+ *   @t: tunnel to be added
+ **/
+
+static void
+ipv6_ipv6_tnl_link(struct ipv6_tnl *t)
+{
+	struct ipv6_tnl **tp = ipv6_ipv6_bucket(&t->parms);
+
+	IPV6_TNL_TRACE();
+
+	write_lock_bh(&ipv6_ipv6_lock);
+	t->next = *tp;
+	write_unlock_bh(&ipv6_ipv6_lock);
+	*tp = t;
+}
+
+/**
+ * ipv6_ipv6_tnl_unlink - remove tunnel from hash table
+ *   @t: tunnel to be removed
+ **/
+
+static void
+ipv6_ipv6_tnl_unlink(struct ipv6_tnl *t)
+{
+	struct ipv6_tnl **tp;
+
+	IPV6_TNL_TRACE();
+
+	for (tp = ipv6_ipv6_bucket(&t->parms); *tp; tp = &(*tp)->next) {
+		if (t == *tp) {
+			write_lock_bh(&ipv6_ipv6_lock);
+			*tp = t->next;
+			write_unlock_bh(&ipv6_ipv6_lock);
+			break;
+		}
+	}
+}
+
+/**
+ * ipv6_addr_local() - check if address is local
+ *   @addr: address to be checked
+ * 
+ * Return: 
+ *   1 if @addr assigned to any local network device,
+ *   0 otherwise
+ **/
+
+static inline int
+ipv6_addr_local(struct in6_addr *addr)
+{
+	struct inet6_ifaddr *ifr;
+	int local = 0;
+
+	IPV6_TNL_TRACE();
+
+	if ((ifr = ipv6_get_ifaddr(addr, NULL)) != NULL) {
+		local = 1;
+		in6_ifa_put(ifr);
+	}
+	return local;
+}
+
+/**
+ * ipv6_tnl_addrs_sane() - check that the tunnel end points are sane
+ *   @laddr: tunnel entry-point
+ *   @raddr: tunnel exit-point
+ *
+ * Description:
+ *   Sanity checks performed on tunnel end-points as suggested by
+ *   RFCs 1853, 2003 and 2473.
+ * 
+ * Return: 
+ *   1 if sane,
+ *   0 otherwise 
+ **/
+
+static inline int
+ipv6_tnl_addrs_sane(struct in6_addr *laddr, struct in6_addr *raddr)
+{
+	int laddr_type = ipv6_addr_type(laddr);
+	int raddr_type = ipv6_addr_type(raddr);
+
+	IPV6_TNL_TRACE();
+
+	if ((laddr_type &
+	     (IPV6_ADDR_ANY | IPV6_ADDR_LOOPBACK | IPV6_ADDR_RESERVED)) ||
+	    (raddr_type &
+	     (IPV6_ADDR_ANY | IPV6_ADDR_LOOPBACK | IPV6_ADDR_RESERVED)) ||
+	    ((laddr_type & IPV6_ADDR_UNICAST) && !ipv6_addr_local(laddr)) ||
+	    ((raddr_type & IPV6_ADDR_UNICAST) && ipv6_addr_local(raddr))) {
+		return 0;
+	}
+	return 1;
+}
+
+/**
+ * ipv6_tnl_create() - create a new tunnel
+ *   @p: tunnel parameters
+ *   @pt: pointer to new tunnel
+ *
+ * Description:
+ *   Create tunnel matching given parameters. New kernel managed devices are 
+ *   not put in the normal hash structure, but are instead cached for later
+ *   use.
+ * 
+ * Return: 
+ *   0 on success
+ **/
+
+static int
+ipv6_tnl_create(struct ipv6_tnl_parm *p, struct ipv6_tnl **pt)
+{
+	struct net_device *dev;
+	int kernel_dev;
+	int err = -ENOBUFS;
+	struct ipv6_tnl *t;
+
+	IPV6_TNL_TRACE();
+
+	kernel_dev = (p->flags & IPV6_TNL_F_KERNEL_DEV);
+
+	MOD_INC_USE_COUNT;
+	dev = kmalloc(sizeof (*dev) + sizeof (*t), GFP_KERNEL);
+	if (!dev) {
+		MOD_DEC_USE_COUNT;
+		return err;
+	}
+	memset(dev, 0, sizeof (*dev) + sizeof (*t));
+	dev->priv = (void *) (dev + 1);
+	t = (struct ipv6_tnl *) dev->priv;
+	t->dev = dev;
+	dev->init = ipv6_ipv6_tnl_dev_init;
+	dev->features |= NETIF_F_DYNALLOC;
+	if (kernel_dev) {
+		memcpy(t->parms.name, p->name, IFNAMSIZ - 1);
+		t->parms.proto = IPPROTO_IPV6;
+		t->parms.flags = IPV6_TNL_F_KERNEL_DEV;
+	} else {
+		memcpy(&t->parms, p, sizeof (*p));
+	}
+	t->parms.name[IFNAMSIZ - 1] = '\0';
+	if (t->parms.hop_limit > 255)
+		t->parms.hop_limit = -1;
+	strcpy(dev->name, t->parms.name);
+	if (!dev->name[0]) {
+		int i = 0;
+		int exists = 0;
+
+		do {
+			sprintf(dev->name, "ip6tnl%d", ++i);
+			exists = (__dev_get_by_name(dev->name) != NULL);
+		} while (i < IPV6_TNL_MAX && exists);
+
+		if (i == IPV6_TNL_MAX) {
+			goto failed;
+		}
+		memcpy(t->parms.name, dev->name, IFNAMSIZ);
+	}
+	if ((err = register_netdevice(dev)) < 0) {
+		goto failed;
+	}
+	if (kernel_dev) {
+		ipv6_ipv6_kernel_tnl_link(t);
+	} else {
+		ipv6_ipv6_tnl_link(t);
+	}
+	*pt = t;
+	return 0;
+      failed:
+	kfree(dev);
+	MOD_DEC_USE_COUNT;
+	return err;
+}
+
+/**
+ * ipv6_tnl_destroy() - destroy old tunnel
+ *   @t: tunnel to be destroyed
+ *
+ * Return:
+ *   whatever unregister_netdevice() returns
+ **/
+
+static inline int
+ipv6_tnl_destroy(struct ipv6_tnl *t)
+{
+	IPV6_TNL_TRACE();
+	return unregister_netdevice(t->dev);
+}
+
+static void manage_kernel_tnls(void *foo);
+
+static struct tq_struct manager_task = {
+	routine:manage_kernel_tnls,
+	data:NULL
+};
+
+/**
+ * manage_kernel_tnls() - create and destroy kernel tunnels
+ *
+ * Description:
+ *   manage_kernel_tnls() creates new kernel devices if there
+ *   are less than $min_kdev_count of them and deletes old ones if
+ *   there are less than $max_kdev_count of them in the cache
+ *
+ * Note:
+ *   Schedules itself to be run later in process context if called from 
+ *   interrupt. Therefore only works synchronously when called from process 
+ *   context.
+ **/
+
+static void
+manage_kernel_tnls(void *foo)
+{
+	struct ipv6_tnl *t = NULL;
+	struct ipv6_tnl_parm parm;
+
+	IPV6_TNL_TRACE();
+
+	/* We can't do this processing in interrupt 
+	   context so schedule it for later */
+	if (in_interrupt()) {
+		read_lock(&ipv6_ipv6_kernel_lock);
+		if (!shutdown &&
+		    (kdev_count < min_kdev_count ||
+		     kdev_count > max_kdev_count)) {
+			schedule_task(&manager_task);
+		}
+		read_unlock(&ipv6_ipv6_kernel_lock);
+		return;
+	}
+
+	rtnl_lock();
+	read_lock_bh(&ipv6_ipv6_kernel_lock);
+	memset(&parm, 0, sizeof (parm));
+	parm.flags = IPV6_TNL_F_KERNEL_DEV;
+	/* Create tunnels until there are at least min_kdev_count */
+	while (kdev_count < min_kdev_count) {
+		read_unlock_bh(&ipv6_ipv6_kernel_lock);
+		if (!ipv6_tnl_create(&parm, &t)) {
+			dev_open(t->dev);
+		} else {
+			goto err;
+		}
+		read_lock_bh(&ipv6_ipv6_kernel_lock);
+	}
+
+	/* Destroy tunnels until there are at most max_kdev_count */
+	while (kdev_count > max_kdev_count) {
+		read_unlock_bh(&ipv6_ipv6_kernel_lock);
+		if ((t = ipv6_ipv6_kernel_tnl_unlink()) != NULL) {
+			ipv6_tnl_destroy(t);
+		} else {
+			goto err;
+		}
+		read_lock_bh(&ipv6_ipv6_kernel_lock);
+	}
+	read_unlock_bh(&ipv6_ipv6_kernel_lock);
+      err:
+	rtnl_unlock();
+}
+
+/**
+ * ipv6_ipv6_tnl_inc_max_kdev_count() - increase max kernel dev cache size
+ *   @n: size increase
+ * Description:
+ *   Increase the upper limit for the number of kernel devices allowed in the 
+ *   cache at any on time.
+ **/
+
+unsigned int
+ipv6_ipv6_tnl_inc_max_kdev_count(unsigned int n)
+{
+	IPV6_TNL_TRACE();
+
+	write_lock_bh(&ipv6_ipv6_kernel_lock);
+	max_kdev_count += n;
+	write_unlock_bh(&ipv6_ipv6_kernel_lock);
+	manage_kernel_tnls(NULL);
+	return max_kdev_count;
+}
+
+/**
+ * ipv6_ipv6_tnl_dec_max_kdev_count() -  decrease max kernel dev cache size
+ *   @n: size decrement
+ * Description:
+ *   Decrease the upper limit for the number of kernel devices allowed in the 
+ *   cache at any on time.
+ **/
+
+unsigned int
+ipv6_ipv6_tnl_dec_max_kdev_count(unsigned int n)
+{
+	IPV6_TNL_TRACE();
+
+	write_lock_bh(&ipv6_ipv6_kernel_lock);
+	max_kdev_count -= min(max_kdev_count, n);
+	if (max_kdev_count < min_kdev_count)
+		min_kdev_count = max_kdev_count;
+	write_unlock_bh(&ipv6_ipv6_kernel_lock);
+	manage_kernel_tnls(NULL);
+	return max_kdev_count;
+}
+
+/**
+ * ipv6_ipv6_tnl_inc_min_kdev_count() - increase min kernel dev cache size
+ *   @n: size increase
+ * Description:
+ *   Increase the lower limit for the number of kernel devices allowed in the 
+ *   cache at any on time.
+ **/
+
+unsigned int
+ipv6_ipv6_tnl_inc_min_kdev_count(unsigned int n)
+{
+	IPV6_TNL_TRACE();
+
+	write_lock_bh(&ipv6_ipv6_kernel_lock);
+	min_kdev_count += n;
+	if (min_kdev_count > max_kdev_count)
+		max_kdev_count = min_kdev_count;
+	write_unlock_bh(&ipv6_ipv6_kernel_lock);
+	manage_kernel_tnls(NULL);
+	return min_kdev_count;
+}
+
+/**
+ * ipv6_ipv6_tnl_dec_min_kdev_count() -  decrease min kernel dev cache size
+ *   @n: size decrement
+ * Description:
+ *   Decrease the lower limit for the number of kernel devices allowed in the 
+ *   cache at any on time.
+ **/
+
+unsigned int
+ipv6_ipv6_tnl_dec_min_kdev_count(unsigned int n)
+{
+	IPV6_TNL_TRACE();
+
+	write_lock_bh(&ipv6_ipv6_kernel_lock);
+	min_kdev_count -= min(min_kdev_count, n);
+	write_unlock_bh(&ipv6_ipv6_kernel_lock);
+	manage_kernel_tnls(NULL);
+	return min_kdev_count;
+}
+
+/**
+ * ipv6_ipv6_tnl_locate - find or create tunnel matching given parameters
+ *   @p: tunnel parameters 
+ *   @create: != 0 if allowed to create new tunnel if no match found
+ *
+ * Description:
+ *   ipv6_ipv6_tnl_locate() first tries to locate an existing tunnel
+ *   based on @parms. If this is unsuccessful, but @create is set a new
+ *   tunnel device is created and registered for use.
+ *
+ * Return:
+ *   0 if tunnel located or created,
+ *   -EINVAL if parameters incorrect,
+ *   -ENODEV if no matching tunnel available
+ **/
+
+static int
+ipv6_ipv6_tnl_locate(struct ipv6_tnl_parm *p, struct ipv6_tnl **pt, int create)
+{
+	struct in6_addr *remote = &p->raddr;
+	struct in6_addr *local = &p->laddr;
+	struct ipv6_tnl *t;
+
+	IPV6_TNL_TRACE();
+
+	if (p->proto != IPPROTO_IPV6 ||
+	    (!(p->flags & IPV6_TNL_F_KERNEL_DEV) &&
+	     !ipv6_tnl_addrs_sane(local, remote)))
+		return -EINVAL;
+
+	for (t = *ipv6_ipv6_bucket(p); t; t = t->next) {
+		if (!ipv6_addr_cmp(local, &t->parms.laddr) &&
+		    !ipv6_addr_cmp(remote, &t->parms.raddr)) {
+			*pt = t;
+			return (create ? -EEXIST : 0);
+		}
+	}
+	/* Kernel devices are created on demand in 
+	   manage_kernel_tnls() */
+	if (!create || (p->flags & IPV6_TNL_F_KERNEL_DEV)) {
+		return -ENODEV;
+	}
+	return ipv6_tnl_create(p, pt);
+}
+
+/**
+ * ipv6_ipv6_tnl_dev_destructor - tunnel device destructor
+ *   @dev: the device to be destroyed
+ **/
+
+static void
+ipv6_ipv6_tnl_dev_destructor(struct net_device *dev)
+{
+	IPV6_TNL_TRACE();
+
+	if (dev != &ipv6_ipv6_fb_tnl_dev) {
+		MOD_DEC_USE_COUNT;
+	}
+}
+
+/**
+ * ipv6_ipv6_tnl_dev_uninit - tunnel device uninitializer
+ *   @dev: the device to be destroyed
+ *   
+ * Description:
+ *   ipv6_ipv6_tnl_dev_uninit() removes tunnel from its list
+ **/
+
+static void
+ipv6_ipv6_tnl_dev_uninit(struct net_device *dev)
+{
+	IPV6_TNL_TRACE();
+
+	if (dev == &ipv6_ipv6_fb_tnl_dev) {
+		write_lock_bh(&ipv6_ipv6_lock);
+		tnls_wc[0] = NULL;
+		write_unlock_bh(&ipv6_ipv6_lock);
+	} else {
+		struct ipv6_tnl *t = (struct ipv6_tnl *) dev->priv;
+		ipv6_ipv6_tnl_unlink(t);
+	}
+}
+
+/**
+ * parse_tvl_tnl_enc_lim - handle encapsulation limit option
+ *   @skb: received socket buffer
+ *
+ * Return: 
+ *   0 if none was found, 
+ *   else index to encapsulation limit
+ **/
+
+static __u16
+parse_tlv_tnl_enc_lim(struct sk_buff *skb, __u8 * raw)
+{
+	struct ipv6hdr *ipv6h = (struct ipv6hdr *) raw;
+	__u8 nexthdr = ipv6h->nexthdr;
+	__u16 off = sizeof (*ipv6h);
+
+	IPV6_TNL_TRACE();
+
+	while (ipv6_ext_hdr(nexthdr) && nexthdr != NEXTHDR_NONE) {
+		__u16 optlen = 0;
+		struct ipv6_opt_hdr *hdr;
+		if (raw + off + sizeof (*hdr) > skb->data &&
+		    !pskb_may_pull(skb, raw - skb->data + off + sizeof (*hdr)))
+			break;
+
+		hdr = (struct ipv6_opt_hdr *) (raw + off);
+		if (nexthdr == NEXTHDR_FRAGMENT) {
+			struct frag_hdr *frag_hdr = (struct frag_hdr *) hdr;
+			if (frag_hdr->frag_off)
+				break;
+			optlen = 8;
+		} else if (nexthdr == NEXTHDR_AUTH) {
+			optlen = (hdr->hdrlen + 2) << 2;
+		} else {
+			optlen = ipv6_optlen(hdr);
+		}
+		if (nexthdr == NEXTHDR_DEST) {
+			__u16 i = off + 2;
+			while (1) {
+				struct ipv6_tlv_tnl_enc_lim *tel;
+
+				/* No more room for encapsulation limit */
+				if (i + sizeof (*tel) > off + optlen)
+					break;
+
+				tel = (struct ipv6_tlv_tnl_enc_lim *) &raw[i];
+				/* return index of option if found and valid */
+				if (tel->type == IPV6_TLV_TNL_ENCAP_LIMIT &&
+				    tel->length == 1)
+					return i;
+				/* else jump to next option */
+				if (tel->type)
+					i += tel->length + 2;
+				else
+					i++;
+			}
+		}
+		nexthdr = hdr->nexthdr;
+		off += optlen;
+	}
+	return 0;
+}
+
+/**
+ * ipv6_ipv6_err - tunnel error handler
+ *
+ * Description:
+ *   ipv6_ipv6_err() should handle errors in the tunnel according
+ *   to the specifications in RFC 2473.
+ **/
+
+void
+ipv6_ipv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+	      int type, int code, int offset, __u32 info)
+{
+	struct ipv6hdr *tipv6h = (struct ipv6hdr *) skb->data;
+	struct ipv6hdr *ipv6h = NULL;
+	struct ipv6_tnl *t;
+	int rel_msg = 0;
+	int rel_type = ICMPV6_DEST_UNREACH;
+	int rel_code = ICMPV6_ADDR_UNREACH;
+	__u32 rel_info = 0;
+	__u16 len;
+
+	IPV6_TNL_TRACE();
+
+	/* If the packet doesn't contain the original IPv6 header we are 
+	   in trouble since we might need the source address for furter 
+	   processing of the error. */
+
+	if (pskb_may_pull(skb, offset + sizeof (*ipv6h)))
+		ipv6h = (struct ipv6hdr *) &skb->data[offset];
+
+	read_lock(&ipv6_ipv6_lock);
+	if ((t = ipv6_ipv6_tnl_lookup(&tipv6h->daddr, &tipv6h->saddr)) == NULL)
+		goto out;
+
+	switch (type) {
+		__u32 teli;
+		struct ipv6_tlv_tnl_enc_lim *tel;
+		__u32 mtu;
+	case ICMPV6_DEST_UNREACH:
+		printk(KERN_ERR
+		       "%s: Path to destination invalid or inactive!\n",
+		       t->parms.name);
+		rel_msg = 1;
+		break;
+	case ICMPV6_TIME_EXCEED:
+		if (code == ICMPV6_EXC_HOPLIMIT) {
+			printk(KERN_ERR
+			       "%s: Too small hop limit or "
+			       "routing loop in tunnel!\n", t->parms.name);
+			rel_msg = 1;
+		}
+		break;
+	case ICMPV6_PARAMPROB:
+		/* ignore if parameter problem not caused by a tunnel
+		   encapsulation limit sub-option */
+		if (code != ICMPV6_HDR_FIELD) {
+			break;
+		}
+		teli = parse_tlv_tnl_enc_lim(skb, skb->data);
+
+		if (teli && teli == info - 2) {
+			tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli];
+			if (tel->encap_limit <= 1) {
+				printk(KERN_ERR
+				       "%s: Too small encapsulation limit or "
+				       "routing loop in tunnel!\n",
+				       t->parms.name);
+				rel_msg = 1;
+			}
+		}
+		break;
+	case ICMPV6_PKT_TOOBIG:
+		mtu = info - offset;
+		if (mtu <= IPV6_MIN_MTU) {
+			mtu = IPV6_MIN_MTU;
+		}
+		t->dev->mtu = mtu;
+
+		if (ipv6h && (len = sizeof (*ipv6h) + ipv6h->payload_len) > mtu) {
+			rel_type = ICMPV6_PKT_TOOBIG;
+			rel_code = 0;
+			rel_info = mtu;
+			rel_msg = 1;
+		}
+		break;
+	}
+	if (rel_msg && ipv6h) {
+		struct rt6_info *rt6i;
+		struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
+
+		if (!skb2)
+			goto out;
+
+		dst_release(skb2->dst);
+		skb2->dst = NULL;
+		skb_pull(skb2, offset);
+		skb2->nh.raw = skb2->data;
+
+		/* Try to guess incoming interface */
+		rt6i = rt6_lookup(&ipv6h->saddr, NULL, 0, 0);
+		if (rt6i && rt6i->rt6i_dev)
+			skb2->dev = rt6i->rt6i_dev;
+
+		icmpv6_send(skb2, rel_type, rel_code, rel_info, skb2->dev);
+		kfree_skb(skb2);
+	}
+      out:
+	read_unlock(&ipv6_ipv6_lock);
+}
+
+/**
+ * call_hooks - call ipv6 tunnel hooks
+ *   @hooknum: hook number, either %IPV6_TNL_PRE_ENCAP, or 
+ *   %IPV6_TNL_PRE_DECAP
+ *   @t: the current tunnel
+ *   @skb: the tunneled packet
+ *
+ * Description:
+ *   Pass packet to all the hook functions until %IPV6_TNL_DROP or
+ *   %IPV6_TNL_STOLEN returned by one of them.
+ *
+ * Return:
+ *   %IPV6_TNL_ACCEPT, %IPV6_TNL_DROP or %IPV6_TNL_STOLEN
+ **/
+
+static inline int
+call_hooks(unsigned int hooknum, struct ipv6_tnl *t, struct sk_buff *skb)
+{
+	struct ipv6_tnl_hook_ops *h;
+	int accept = IPV6_TNL_ACCEPT;
+
+	IPV6_TNL_TRACE();
+
+	if (hooknum < IPV6_TNL_MAXHOOKS) {
+		struct list_head *i;
+		read_lock(&ipv6_ipv6_hook_lock);
+		for (i = hooks[hooknum].next; i != &hooks[hooknum]; i = i->next) {
+			h = (struct ipv6_tnl_hook_ops *) i;
+
+			if (h->hook) {
+				accept = h->hook(t, skb);
+
+				if (accept != IPV6_TNL_ACCEPT)
+					break;
+			}
+		}
+		read_unlock(&ipv6_ipv6_hook_lock);
+	}
+	return accept;
+}
+
+/**
+ * ipv6_ipv6_rcv - decapsulate IPv6 packet and retransmit it locally
+ *   @skb: received socket buffer
+ *
+ * Return: 0
+ **/
+
+int
+ipv6_ipv6_rcv(struct sk_buff *skb)
+{
+	struct ipv6hdr *ipv6h;
+	struct ipv6_tnl *t;
+
+	IPV6_TNL_TRACE();
+
+	if (!pskb_may_pull(skb, sizeof (*ipv6h)))
+		goto out;
+
+	ipv6h = skb->nh.ipv6h;
+
+	read_lock(&ipv6_ipv6_lock);
+
+	if ((t = ipv6_ipv6_tnl_lookup(&ipv6h->saddr, &ipv6h->daddr)) != NULL) {
+		int hookval = call_hooks(IPV6_TNL_PRE_DECAP, t, skb);
+		switch (hookval) {
+		case IPV6_TNL_ACCEPT:
+			break;
+		case IPV6_TNL_STOLEN:
+			goto ignore_packet;
+		default:
+			if (hookval != IPV6_TNL_DROP) {
+				printk(KERN_ERR
+				       "%s: Unknown return value for tunnel hook!\n",
+				       t->parms.name);
+			}
+			t->stat.rx_dropped++;
+			goto drop_packet;
+		}
+		skb->mac.raw = skb->nh.raw;
+		skb->nh.raw = skb->data;
+		skb->protocol = htons(ETH_P_IPV6);
+		skb->pkt_type = PACKET_HOST;
+		skb->dev = t->dev;
+		dst_release(skb->dst);
+		skb->dst = NULL;
+		t->stat.rx_packets++;
+		t->stat.rx_bytes += skb->len;
+		netif_rx(skb);
+		read_unlock(&ipv6_ipv6_lock);
+		return 0;
+	}
+	icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, skb->dev);
+      drop_packet:
+	kfree_skb(skb);
+      ignore_packet:
+	read_unlock(&ipv6_ipv6_lock);
+      out:
+	return 0;
+}
+
+/**
+ * txopt_len - get necessary size for new &struct ipv6_txoptions
+ *   @orig_opt: old options
+ *
+ * Return:
+ *   Size of old one plus size of tunnel encapsulation limit option
+ **/
+
+static inline int
+txopt_len(struct ipv6_txoptions *orig_opt)
+{
+	int len = sizeof (*orig_opt) + 8;
+
+	IPV6_TNL_TRACE();
+
+	if (orig_opt && orig_opt->dst0opt)
+		len += ipv6_optlen(orig_opt->dst0opt);
+	return len;
+}
+
+/**
+ * merge_options - add encapsulation limit to original options
+ *   @encap_limit: number of allowed encapsulation limits
+ *   @orig_opt: original options
+ * 
+ * Return:
+ *   Pointer to new &struct ipv6_txoptions containing the tunnel
+ *   encapsulation limit
+ **/
+
+static inline struct ipv6_txoptions *
+merge_options(struct sock *sk, __u8 encap_limit,
+	      struct ipv6_txoptions *orig_opt)
+{
+	struct ipv6_tlv_tnl_enc_lim *tel;
+	struct ipv6_txoptions *opt;
+	__u8 *raw;
+	__u8 pad_to = 8;
+	int opt_len = txopt_len(orig_opt);
+
+	IPV6_TNL_TRACE();
+
+	if (!(opt = sock_kmalloc(sk, opt_len, GFP_ATOMIC))) {
+		return NULL;
+	}
+
+	memset(opt, 0, opt_len);
+	opt->tot_len = opt_len;
+	opt->dst0opt = (struct ipv6_opt_hdr *) (opt + 1);
+	opt->opt_nflen = 8;
+
+	raw = (__u8 *) opt->dst0opt;
+
+	tel = (struct ipv6_tlv_tnl_enc_lim *) (opt->dst0opt + 1);
+	tel->type = IPV6_TLV_TNL_ENCAP_LIMIT;
+	tel->length = 1;
+	tel->encap_limit = encap_limit;
+
+	if (orig_opt) {
+		__u8 *orig_raw;
+
+		opt->hopopt = orig_opt->hopopt;
+
+		/* Keep the original destination options properly
+		   aligned and merge possible old paddings to the
+		   new padding option */
+		if ((orig_raw = (__u8 *) orig_opt->dst0opt) != NULL) {
+			__u8 type;
+			int i = sizeof (struct ipv6_opt_hdr);
+			pad_to += sizeof (struct ipv6_opt_hdr);
+			while (i < ipv6_optlen(orig_opt->dst0opt)) {
+				type = orig_raw[i++];
+				if (type == IPV6_TLV_PAD0)
+					pad_to++;
+				else if (type == IPV6_TLV_PADN) {
+					int len = orig_raw[i++];
+					i += len;
+					pad_to += len + 2;
+				} else {
+					break;
+				}
+			}
+			opt->dst0opt->hdrlen = orig_opt->dst0opt->hdrlen + 1;
+			memcpy(raw + pad_to, orig_raw + pad_to - 8,
+			       opt_len - sizeof (*opt) - pad_to);
+		}
+		opt->srcrt = orig_opt->srcrt;
+		opt->opt_nflen += orig_opt->opt_nflen;
+
+		opt->dst1opt = orig_opt->dst1opt;
+		opt->auth = orig_opt->auth;
+		opt->opt_flen = orig_opt->opt_flen;
+	}
+	raw[5] = IPV6_TLV_PADN;
+
+	/* subtract lengths of destination suboption header,
+	   tunnel encapsulation limit and pad N header */
+	raw[6] = pad_to - 7;
+
+	return opt;
+}
+
+static int
+ipv6_ipv6_getfrag(const void *data, struct in6_addr *addr,
+		  char *buff, unsigned int offset, unsigned int len)
+{
+	memcpy(buff, data + offset, len);
+	return 0;
+}
+
+/**
+ * ipv6_ipv6_tnl_addr_conflict - compare packet addresses to tunnel's own
+ *   @t: the outgoing tunnel device
+ *   @hdr: IPv6 header from the incoming packet 
+ *
+ * Description:
+ *   Avoid trivial tunneling loop by checking that tunnel exit-point 
+ *   doesn't match source of incoming packet.
+ *
+ * Return: 
+ *   1 if conflict,
+ *   0 else
+ **/
+
+static inline int
+ipv6_ipv6_tnl_addr_conflict(struct ipv6_tnl *t, struct ipv6hdr *hdr)
+{
+	return !ipv6_addr_cmp(&t->parms.raddr, &hdr->saddr);
+}
+
+/**
+ * ipv6_ipv6_tnl_xmit - encapsulate packet and send 
+ *   @skb: the outgoing socket buffer
+ *   @dev: the outgoing tunnel device 
+ *
+ * Description:
+ *   Build new header and do some sanity checks on the packet before sending
+ *   it to ip6_build_xmit().
+ *
+ * Return: 
+ *   0
+ **/
+
+static int
+ipv6_ipv6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ipv6_tnl *t = (struct ipv6_tnl *) dev->priv;
+	struct net_device_stats *stats = &t->stat;
+	struct ipv6hdr *ipv6h = skb->nh.ipv6h;
+	int hookval;
+	struct ipv6_txoptions *orig_opt = NULL;
+	struct ipv6_txoptions *opt = NULL;
+	__u8 encap_limit = 0;
+	__u16 offset;
+	struct flowi fl;
+	struct ip6_flowlabel *fl_lbl = NULL;
+	int err = 0;
+	struct dst_entry *dst;
+	int link_failure = 0;
+	struct sock *sk = ipv6_socket->sk;
+	struct net_device *tdev;
+	int mtu;
+
+	IPV6_TNL_TRACE();
+
+	if (t->recursion++) {
+		stats->collisions++;
+		goto tx_err;
+	}
+	if (skb->protocol != htons(ETH_P_IPV6) ||
+	    (t->parms.flags & IPV6_TNL_F_RCV_ONLY) ||
+	    ipv6_ipv6_tnl_addr_conflict(t, ipv6h) ||
+	    (!(t->parms.flags & IPV6_TNL_F_ALLOW_LOCAL) &&
+	     ipv6_addr_local(&ipv6h->saddr))) {
+		goto tx_err;
+	}
+	if ((offset = parse_tlv_tnl_enc_lim(skb, skb->nh.raw)) > 0) {
+		struct ipv6_tlv_tnl_enc_lim *tel;
+		tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->nh.raw[offset];
+		if (tel->encap_limit <= 1) {
+			icmpv6_send(skb, ICMPV6_PARAMPROB,
+				    ICMPV6_HDR_FIELD, offset + 2, skb->dev);
+			goto tx_err;
+		}
+		encap_limit = tel->encap_limit - 1;
+	} else if (!(t->parms.flags & IPV6_TNL_F_IGN_ENCAP_LIMIT)) {
+		encap_limit = t->parms.encap_limit;
+	}
+	hookval = call_hooks(IPV6_TNL_PRE_ENCAP, t, skb);
+	switch (hookval) {
+	case IPV6_TNL_ACCEPT:
+		break;
+	case IPV6_TNL_STOLEN:
+		goto ignore_packet;
+	default:
+		if (hookval != IPV6_TNL_DROP) {
+			printk(KERN_ERR
+			       "%s: Unknown return value for tunnel hook!\n",
+			       t->parms.name);
+		}
+		goto drop_packet;
+	}
+	if ((err = ipv6_xmit_lock()))
+		goto tx_err;
+
+	memcpy(&fl, &t->fl, sizeof (fl));
+
+	if (fl.fl6_flowlabel) {
+		fl_lbl = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+		if (fl_lbl)
+			orig_opt = fl_lbl->opt;
+	}
+	if ((t->parms.flags & IPV6_TNL_F_USE_ORIG_TCLASS)) {
+		fl.fl6_flowlabel |= (*(__u32 *) ipv6h &
+				     IPV6_FLOWINFO_MASK & ~IPV6_FLOWLABEL_MASK);
+	}
+	if (encap_limit > 0) {
+		if (!(opt = merge_options(sk, encap_limit, orig_opt))) {
+			goto tx_err_free_fl_lbl;
+		}
+	} else {
+		opt = orig_opt;
+	}
+	dst = ip6_route_output(sk, &fl);
+
+	if (dst->error) {
+		stats->tx_carrier_errors++;
+		link_failure = 1;
+		goto tx_err_dst_release;
+	}
+	tdev = dst->dev;
+
+	/* local routing loop */
+	if (tdev == dev) {
+		stats->collisions++;
+		printk(KERN_ERR "%s: Local routing loop detected!\n",
+		       t->parms.name);
+		goto tx_err_dst_release;
+	}
+	mtu = dst->pmtu - sizeof (*ipv6h);
+	if (opt) {
+		mtu -= (opt->opt_nflen + opt->opt_flen);
+	}
+	if (mtu < IPV6_MIN_MTU)
+		mtu = IPV6_MIN_MTU;
+	if (skb->dst && mtu < skb->dst->pmtu) {
+		struct rt6_info *rt6 = (struct rt6_info *) skb->dst;
+		rt6->rt6i_flags |= RTF_MODIFIED;
+		rt6->u.dst.pmtu = mtu;
+	}
+	if (skb->len > mtu && skb->len > IPV6_MIN_MTU) {
+		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, 
+			    (mtu > IPV6_MIN_MTU ? mtu : IPV6_MIN_MTU), dev);
+		goto tx_err_dst_release;
+	}
+
+	err = ip6_build_xmit(sk, ipv6_ipv6_getfrag, (void *)skb->nh.raw, 
+			     &fl, skb->len, opt, t->parms.hop_limit, 0,
+			     MSG_DONTWAIT);
+
+	if (err == NET_XMIT_SUCCESS || err == NET_XMIT_CN) {
+		stats->tx_bytes += skb->len;
+		stats->tx_packets++;
+	} else {
+		stats->tx_errors++;
+		stats->tx_aborted_errors++;
+	}
+	dst_release(dst);
+	if (opt && opt != orig_opt)
+		sock_kfree_s(sk, opt, opt->tot_len);
+	fl6_sock_release(fl_lbl);
+	ipv6_xmit_unlock();
+	kfree_skb(skb);
+	t->recursion--;
+	return 0;
+      tx_err_dst_release:
+	dst_release(dst);
+	if (opt && opt != orig_opt)
+		sock_kfree_s(sk, opt, opt->tot_len);
+      tx_err_free_fl_lbl:
+	fl6_sock_release(fl_lbl);
+	ipv6_xmit_unlock();
+	if (link_failure)
+		dst_link_failure(skb);
+      tx_err:
+	stats->tx_errors++;
+      drop_packet:
+	stats->tx_dropped++;
+	kfree_skb(skb);
+      ignore_packet:
+	t->recursion--;
+	return 0;
+}
+
+struct ipv6_tnl_link_parm {
+	int iflink;
+	unsigned short hard_header_len;
+	unsigned mtu;
+};
+
+static int
+ipv6_ipv6_tnl_link_parm_get(struct ipv6_tnl_parm *p,
+			    int active, struct ipv6_tnl_link_parm *lp)
+{
+	int err = 0;
+
+	if (active) {
+		struct rt6_info *rt = rt6_lookup(&p->raddr, &p->laddr,
+						 p->link, 0);
+		struct net_device *rtdev;
+		if (!rt) {
+			err = -ENOENT;
+		} else if ((rtdev = rt->rt6i_dev) == NULL) {
+			err = -ENODEV;
+		} else if (rtdev->type == ARPHRD_IPV6_IPV6_TUNNEL) {
+			/* as long as all tunnels use the same socket 
+			   (ipv6_socket) for transmission (locally) 
+			   nested tunnels won't work */
+			err = -ENOMEDIUM;
+		} else {
+			lp->iflink = rtdev->ifindex;
+			lp->hard_header_len = rtdev->hard_header_len +
+			    sizeof (struct ipv6hdr);
+			lp->mtu = rtdev->mtu - sizeof (struct ipv6hdr);
+
+			if (lp->mtu < IPV6_MIN_MTU)
+				lp->mtu = IPV6_MIN_MTU;
+		}
+		if (rt) {
+			dst_release(&rt->u.dst);
+		}
+	} else {
+		lp->iflink = 0;
+		lp->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr);
+		lp->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr);
+	}
+	return err;
+}
+
+static void
+ipv6_ipv6_tnl_dev_config(struct net_device *dev, struct ipv6_tnl_link_parm *lp)
+{
+	struct ipv6_tnl *t = (struct ipv6_tnl *) dev->priv;
+	struct flowi *fl;
+
+	IPV6_TNL_TRACE();
+
+	/* Set up flowi template */
+	fl = &t->fl;
+	fl->fl6_src = &t->parms.laddr;
+	fl->fl6_dst = &t->parms.raddr;
+	fl->oif = t->parms.link;
+	fl->fl6_flowlabel = IPV6_FLOWLABEL_MASK & htonl(t->parms.flow_lbl);
+
+	dev->iflink = lp->iflink;
+	dev->hard_header_len = lp->hard_header_len;
+	dev->mtu = lp->mtu;
+}
+
+/**
+ * ipv6_ipv6_tnl_change - update the tunnel parameters
+ *   @t: tunnel to be changed
+ *   @p: tunnel configuration parameters
+ *   @active: != 0 if tunnel is ready for use
+ *
+ * Description:
+ *   ipv6_ipv6_tnl_change() updates the tunnel parameters
+ **/
+
+static int
+ipv6_ipv6_tnl_change(struct ipv6_tnl *t, struct ipv6_tnl_parm *p, int active)
+{
+	struct net_device *dev = t->dev;
+	int laddr_uc = (ipv6_addr_type(&p->laddr) & IPV6_ADDR_UNICAST);
+	int raddr_uc = (ipv6_addr_type(&p->raddr) & IPV6_ADDR_UNICAST);
+	int err;
+	struct ipv6_tnl_link_parm lp;
+
+	IPV6_TNL_TRACE();
+
+	if ((err = ipv6_ipv6_tnl_link_parm_get(p, active, &lp)))
+		return err;
+
+	if (laddr_uc && raddr_uc) {
+		dev->flags |= IFF_POINTOPOINT;
+	} else {
+		dev->flags &= ~IFF_POINTOPOINT;
+	}
+	ipv6_addr_copy(&t->parms.laddr, &p->laddr);
+	ipv6_addr_copy(&t->parms.raddr, &p->raddr);
+	t->parms.flags = p->flags;
+
+	if (active) {
+		/* Only allow xmit if the tunnel is configured 
+		   with a valid unicast source address */
+		if (laddr_uc) {
+			t->parms.flags &= ~IPV6_TNL_F_RCV_ONLY;
+		} else {
+			t->parms.flags |= IPV6_TNL_F_RCV_ONLY;
+		}
+	}
+	t->parms.hop_limit = (p->hop_limit <= 255 ? p->hop_limit : -1);
+	t->parms.encap_limit = p->encap_limit;
+	t->parms.flow_lbl = p->flow_lbl;
+
+	ipv6_ipv6_tnl_dev_config(dev, &lp);
+	return 0;
+}
+
+static inline int
+ipv6_tnl_flag_cmp(__u32 f1, __u32 f2)
+{
+	return ((f1 & ~IPV6_TNL_F_RCV_ONLY) != (f2 & ~IPV6_TNL_F_RCV_ONLY));
+}
+
+/**
+ * ipv6_ipv6_kernel_tnl_add - configure and add kernel tunnel to hash 
+ *   @p: kernel tunnel configuration parameters
+ *
+ * Description:
+ *   ipv6_ipv6_kernel_tnl_add() fetches an unused kernel tunnel configures
+ *   it according to @p and places it among the active tunnels.
+ * 
+ * Return:
+ *   number of references to tunnel on success,
+ *   %-EEXIST if there is already a device matching description
+ *   %-EINVAL if p->flags doesn't have %IPV6_TNL_F_KERNEL_DEV raised,
+ *   %-ENODEV if there are no unused kernel tunnels available 
+ * 
+ * Note:
+ *   The code for creating, opening, closing and destroying network devices
+ *   must be called from process context, while the Mobile IP code, which 
+ *   needs the tunnel devices, unfortunately runs in interrupt context. 
+ *   
+ *   The devices must be created and opened in advance, then placed in a 
+ *   list where the kernel can fetch and ready them for use at a later time.
+ *
+ **/
+
+int
+ipv6_ipv6_kernel_tnl_add(struct ipv6_tnl_parm *p)
+{
+	struct ipv6_tnl *t;
+	int err;
+
+	IPV6_TNL_TRACE();
+
+	if (!(p->flags & IPV6_TNL_F_KERNEL_DEV) ||
+	    !ipv6_tnl_addrs_sane(&p->laddr, &p->raddr))
+		return -EINVAL;
+	if ((t = ipv6_ipv6_tnl_lookup(&p->raddr, &p->laddr)) != NULL &&
+	    t != &ipv6_ipv6_fb_tnl) {
+		if (ipv6_tnl_flag_cmp(p->flags, t->parms.flags)) {
+			/* Incompatible tunnel already exists for endpoints */
+			return -EEXIST;
+		} else {
+			/* Handle duplicate tunnels by incrementing 
+			   reference count */
+			atomic_inc(&t->refcnt);
+			goto out;
+		}
+	}
+	if ((t = ipv6_ipv6_kernel_tnl_unlink()) == NULL)
+		return -ENODEV;
+	if ((err = ipv6_ipv6_tnl_change(t, p, 1))) {
+		ipv6_ipv6_kernel_tnl_link(t);
+		return err;
+	}
+	atomic_inc(&t->refcnt);
+
+	ipv6_ipv6_tnl_link(t);
+
+	manage_kernel_tnls(NULL);
+      out:
+	return atomic_read(&t->refcnt);
+}
+
+/**
+ * ipv6_ipv6_kernel_tnl_del - delete no longer needed kernel tunnel 
+ *   @t: kernel tunnel to be removed from hash
+ *
+ * Description:
+ *   ipv6_ipv6_kernel_tnl_del() removes and deconfigures the tunnel @t
+ *   and places it among the unused kernel devices.
+ * 
+ * Return:
+ *   number of references on success,
+ *   %-EINVAL if p->flags doesn't have %IPV6_TNL_F_KERNEL_DEV raised,
+ * 
+ * Note:
+ *   See the comments on ipv6_ipv6_kernel_tnl_add() for more information.
+ **/
+
+int
+ipv6_ipv6_kernel_tnl_del(struct ipv6_tnl *t)
+{
+	IPV6_TNL_TRACE();
+
+	if (!t)
+		return -ENODEV;
+
+	if (!(t->parms.flags & IPV6_TNL_F_KERNEL_DEV))
+		return -EINVAL;
+
+	if (atomic_dec_and_test(&t->refcnt)) {
+		struct ipv6_tnl_parm p;
+		ipv6_ipv6_tnl_unlink(t);
+		memset(&p, 0, sizeof (p));
+		p.flags = IPV6_TNL_F_KERNEL_DEV;
+
+		ipv6_ipv6_tnl_change(t, &p, 0);
+
+		ipv6_ipv6_kernel_tnl_link(t);
+
+		manage_kernel_tnls(NULL);
+	}
+	return atomic_read(&t->refcnt);
+}
+
+/**
+ * ipv6_ipv6_tnl_ioctl - configure ipv6 tunnels from userspace 
+ *   @dev: virtual device associated with tunnel
+ *   @ifr: parameters passed from userspace
+ *   @cmd: command to be performed
+ *
+ * Description:
+ *   ipv6_ipv6_tnl_ioctl() is used for managing IPv6 tunnels 
+ *   from userspace. 
+ *
+ *   The possible commands are the following:
+ *     %SIOCGETTUNNEL: get tunnel parameters for device
+ *     %SIOCADDTUNNEL: add tunnel matching given tunnel parameters
+ *     %SIOCCHGTUNNEL: change tunnel parameters to those given
+ *     %SIOCDELTUNNEL: delete tunnel
+ *
+ *   The fallback device "ip6tnl0", created during module 
+ *   initialization, can be used for creating other tunnel devices.
+ *
+ * Return:
+ *   0 on success,
+ *   %-EFAULT if unable to copy data to or from userspace,
+ *   %-EPERM if current process hasn't %CAP_NET_ADMIN set or attempting
+ *   to configure kernel devices from userspace, 
+ *   %-EINVAL if passed tunnel parameters are invalid,
+ *   %-EEXIST if changing a tunnel's parameters would cause a conflict
+ *   %-ENODEV if attempting to change or delete a nonexisting device
+ *
+ * Note:
+ *   See the comments on ipv6_ipv6_kernel_tnl_add() for more information 
+ *   about kernel tunnels.
+ * **/
+
+static int
+ipv6_ipv6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	int err = 0;
+	int create;
+	struct ipv6_tnl_parm p;
+	struct ipv6_tnl *t = NULL;
+
+	IPV6_TNL_TRACE();
+
+	MOD_INC_USE_COUNT;
+
+	switch (cmd) {
+	case SIOCGETTUNNEL:
+		if (dev == &ipv6_ipv6_fb_tnl_dev) {
+			if (copy_from_user(&p,
+					   ifr->ifr_ifru.ifru_data,
+					   sizeof (p))) {
+				err = -EFAULT;
+				break;
+			}
+			if ((err = ipv6_ipv6_tnl_locate(&p, &t, 0)) == -ENODEV)
+				t = (struct ipv6_tnl *) dev->priv;
+			else if (err)
+				break;
+		} else
+			t = (struct ipv6_tnl *) dev->priv;
+
+		memcpy(&p, &t->parms, sizeof (p));
+		if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) {
+			err = -EFAULT;
+		}
+		break;
+	case SIOCADDTUNNEL:
+	case SIOCCHGTUNNEL:
+		err = -EPERM;
+		create = (cmd == SIOCADDTUNNEL);
+		if (!capable(CAP_NET_ADMIN))
+			break;
+		if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) {
+			err = -EFAULT;
+			break;
+		}
+		if (p.flags & IPV6_TNL_F_KERNEL_DEV) {
+			break;
+		}
+		if (!create && dev != &ipv6_ipv6_fb_tnl_dev) {
+			t = (struct ipv6_tnl *) dev->priv;
+		}
+		if (!t && (err = ipv6_ipv6_tnl_locate(&p, &t, create))) {
+			break;
+		}
+		if (cmd == SIOCCHGTUNNEL) {
+			if (t->dev != dev) {
+				err = -EEXIST;
+				break;
+			}
+			if (t->parms.flags & IPV6_TNL_F_KERNEL_DEV) {
+				err = -EPERM;
+				break;
+			}
+			ipv6_ipv6_tnl_unlink(t);
+			err = ipv6_ipv6_tnl_change(t, &p, 1);
+			ipv6_ipv6_tnl_link(t);
+			netdev_state_change(dev);
+		}
+		if (copy_to_user(ifr->ifr_ifru.ifru_data,
+				 &t->parms, sizeof (p))) {
+			err = -EFAULT;
+		} else {
+			err = 0;
+		}
+		break;
+	case SIOCDELTUNNEL:
+		err = -EPERM;
+		if (!capable(CAP_NET_ADMIN))
+			break;
+
+		if (dev == &ipv6_ipv6_fb_tnl_dev) {
+			if (copy_from_user(&p, ifr->ifr_ifru.ifru_data,
+					   sizeof (p))) {
+				err = -EFAULT;
+				break;
+			}
+			err = ipv6_ipv6_tnl_locate(&p, &t, 0);
+			if (err)
+				break;
+			if (t == &ipv6_ipv6_fb_tnl) {
+				err = -EPERM;
+				break;
+			}
+		} else {
+			t = (struct ipv6_tnl *) dev->priv;
+		}
+		if (t->parms.flags & IPV6_TNL_F_KERNEL_DEV)
+			err = -EPERM;
+		else
+			err = ipv6_tnl_destroy(t);
+		break;
+	default:
+		err = -EINVAL;
+	}
+	MOD_DEC_USE_COUNT;
+	return err;
+}
+
+/**
+ * ipv6_ipv6_tnl_get_stats - return the stats for tunnel device 
+ *   @dev: virtual device associated with tunnel
+ *
+ * Return: stats for device
+ **/
+
+static struct net_device_stats *
+ipv6_ipv6_tnl_get_stats(struct net_device *dev)
+{
+	IPV6_TNL_TRACE();
+
+	return &(((struct ipv6_tnl *) dev->priv)->stat);
+}
+
+/**
+ * ipv6_ipv6_tnl_change_mtu - change mtu manually for tunnel device
+ *   @dev: virtual device associated with tunnel
+ *   @new_mtu: the new mtu
+ *
+ * Return:
+ *   0 on success,
+ *   %-EINVAL if mtu too small
+ **/
+
+static int
+ipv6_ipv6_tnl_change_mtu(struct net_device *dev, int new_mtu)
+{
+	IPV6_TNL_TRACE();
+
+	if (new_mtu < IPV6_MIN_MTU) {
+		return -EINVAL;
+	}
+	dev->mtu = new_mtu;
+	return 0;
+}
+
+/**
+ * ipv6_ipv6_tnl_dev_init_gen - general initializer for all tunnel devices
+ *   @dev: virtual device associated with tunnel
+ *
+ * Description:
+ *   Set function pointers and initialize the &struct flowi template used
+ *   by the tunnel.
+ **/
+
+static void
+ipv6_ipv6_tnl_dev_init_gen(struct net_device *dev)
+{
+	struct ipv6_tnl *t = (struct ipv6_tnl *) dev->priv;
+	struct flowi *fl = &t->fl;
+
+	IPV6_TNL_TRACE();
+
+	memset(fl, 0, sizeof (*fl));
+	fl->proto = IPPROTO_IPV6;
+
+	dev->destructor = ipv6_ipv6_tnl_dev_destructor;
+	dev->uninit = ipv6_ipv6_tnl_dev_uninit;
+	dev->hard_start_xmit = ipv6_ipv6_tnl_xmit;
+	dev->get_stats = ipv6_ipv6_tnl_get_stats;
+	dev->do_ioctl = ipv6_ipv6_tnl_ioctl;
+	dev->change_mtu = ipv6_ipv6_tnl_change_mtu;
+	dev->type = ARPHRD_IPV6_IPV6_TUNNEL;
+	dev->flags |= IFF_NOARP;
+	if (ipv6_addr_type(&t->parms.raddr) & IPV6_ADDR_UNICAST)
+		dev->flags |= IFF_POINTOPOINT;
+	dev->iflink = 0;
+	/* Hmm... MAX_ADDR_LEN is 8, so the ipv6 addresses can't be 
+	   copied to dev->dev_addr and dev->broadcast, like the ipv4
+	   addresses were in ipip.c, ip_gre.c and sit.c. */
+	dev->addr_len = 0;
+}
+
+/**
+ * ipv6_ipv6_tnl_dev_init - initializer for all non fallback tunnel devices
+ *   @dev: virtual device associated with tunnel
+ **/
+
+static int
+ipv6_ipv6_tnl_dev_init(struct net_device *dev)
+{
+	struct ipv6_tnl *t = (struct ipv6_tnl *) dev->priv;
+	int active = !(t->parms.flags & IPV6_TNL_F_KERNEL_DEV);
+	struct ipv6_tnl_link_parm lp;
+	int err;
+
+	IPV6_TNL_TRACE();
+
+	if ((err = ipv6_ipv6_tnl_link_parm_get(&t->parms, active, &lp))) {
+		return err;
+	}
+	ipv6_ipv6_tnl_dev_init_gen(dev);
+	ipv6_ipv6_tnl_dev_config(dev, &lp);
+	return 0;
+}
+
+#ifdef MODULE
+
+/**
+ * ipv6_ipv6_fb_tnl_open - function called when fallback device opened
+ *   @dev: fallback device
+ *
+ * Return: 0 
+ **/
+
+static int
+ipv6_ipv6_fb_tnl_open(struct net_device *dev)
+{
+	IPV6_TNL_TRACE();
+
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+/**
+ * ipv6_ipv6_fb_tnl_close - function called when fallback device closed
+ *   @dev: fallback device
+ *
+ * Return: 0 
+ **/
+
+static int
+ipv6_ipv6_fb_tnl_close(struct net_device *dev)
+{
+	IPV6_TNL_TRACE();
+
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+#endif
+
+/**
+ * ipv6_ipv6_fb_tnl_dev_init - initializer for fallback tunnel device
+ *   @dev: fallback device
+ *
+ * Return: 0
+ **/
+
+int __init
+ipv6_ipv6_fb_tnl_dev_init(struct net_device *dev)
+{
+	IPV6_TNL_TRACE();
+
+	ipv6_ipv6_tnl_dev_init_gen(dev);
+#ifdef MODULE
+	dev->open = ipv6_ipv6_fb_tnl_open;
+	dev->stop = ipv6_ipv6_fb_tnl_close;
+#endif
+	tnls_wc[0] = &ipv6_ipv6_fb_tnl;
+	return 0;
+}
+
+/**
+ * ipv6_ipv6_tnl_register_hook - add hook for processing of tunneled packets
+ *   @reg: hook function and its parameters
+ * 
+ * Description:
+ *   Add a netfilter like hook function for special handling of tunneled 
+ *   packets. The hook functions are called before encapsulation 
+ *   (%IPV6_TNL_PRE_ENCAP) and before decapsulation 
+ *   (%IPV6_TNL_PRE_DECAP). The possible return values by the hook 
+ *   functions are %IPV6_TNL_DROP, %IPV6_TNL_ACCEPT and 
+ *   %IPV6_TNL_STOLEN (in case the hook function took care of the packet
+ *   and it doesn't have to be processed any further).
+ **/
+
+void
+ipv6_ipv6_tnl_register_hook(struct ipv6_tnl_hook_ops *reg)
+{
+	IPV6_TNL_TRACE();
+
+	if (reg->hooknum < IPV6_TNL_MAXHOOKS) {
+		struct list_head *i;
+
+		write_lock_bh(&ipv6_ipv6_hook_lock);
+		for (i = hooks[reg->hooknum].next;
+		     i != &hooks[reg->hooknum]; i = i->next) {
+			if (reg->priority <
+			    ((struct ipv6_tnl_hook_ops *) i)->priority) {
+				break;
+			}
+		}
+		list_add(&reg->list, i->prev);
+		write_unlock_bh(&ipv6_ipv6_hook_lock);
+	}
+}
+
+/**
+ * ipv6_ipv6_tnl_unregister_hook - remove tunnel hook
+ *   @reg: hook function and its parameters
+ **/
+
+void
+ipv6_ipv6_tnl_unregister_hook(struct ipv6_tnl_hook_ops *reg)
+{
+	IPV6_TNL_TRACE();
+
+	if (reg->hooknum < IPV6_TNL_MAXHOOKS) {
+		write_lock_bh(&ipv6_ipv6_hook_lock);
+		list_del(&reg->list);
+		write_unlock_bh(&ipv6_ipv6_hook_lock);
+	}
+}
+
+/* the IPv6 over IPv6 protocol structure */
+static struct inet6_protocol ipv6_ipv6_protocol = {
+	ipv6_ipv6_rcv,		/* IPv6 handler         */
+	ipv6_ipv6_err,		/* IPv6 error control   */
+	NULL,			/* next                 */
+	IPPROTO_IPV6,		/* protocol ID          */
+	0,			/* copy                 */
+	NULL,			/* data                 */
+	"IPv6 over IPv6"	/* name                 */
+};
+
+/**
+ * ipv6_ipv6_tnl_init - register protocol and reserve needed resources
+ *
+ * Return: 0 on success
+ **/
+
+int __init
+ipv6_ipv6_tnl_init(void)
+{
+	int i, err;
+	struct sock *sk;
+
+	IPV6_TNL_TRACE();
+
+	ipv6_ipv6_fb_tnl_dev.priv = (void *) &ipv6_ipv6_fb_tnl;
+	err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_IPV6, &ipv6_socket);
+	if (err < 0) {
+		printk(KERN_ERR "Failed to create the IPv6 tunnel socket.\n");
+		return err;
+	}
+	sk = ipv6_socket->sk;
+	sk->allocation = GFP_ATOMIC;
+	sk->net_pinfo.af_inet6.hop_limit = 254;
+	sk->net_pinfo.af_inet6.mc_loop = 0;
+	sk->prot->unhash(sk);
+
+	for (i = 0; i < IPV6_TNL_MAXHOOKS; i++) {
+		INIT_LIST_HEAD(&hooks[i]);
+	}
+	register_netdev(&ipv6_ipv6_fb_tnl_dev);
+	inet6_add_protocol(&ipv6_ipv6_protocol);
+	return 0;
+}
+
+/**
+ * ipv6_ipv6_tnl_exit - free resources and unregister protocol
+ **/
+
+void __exit
+ipv6_ipv6_tnl_exit(void)
+{
+	IPV6_TNL_TRACE();
+
+	write_lock_bh(&ipv6_ipv6_kernel_lock);
+	shutdown = 1;
+	write_unlock_bh(&ipv6_ipv6_kernel_lock);
+	flush_scheduled_tasks();
+	manage_kernel_tnls(NULL);
+	inet6_del_protocol(&ipv6_ipv6_protocol);
+	unregister_netdev(&ipv6_ipv6_fb_tnl_dev);
+	sock_release(ipv6_socket);
+}
+
+#ifdef MODULE
+module_init(ipv6_ipv6_tnl_init);
+module_exit(ipv6_ipv6_tnl_exit);
+#endif
diff -urN linux-2.4.29/net/ipv6/Makefile linux-2.4.29-uc1/net/ipv6/Makefile
--- linux-2.4.29/net/ipv6/Makefile	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/Makefile	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,4 @@
+# $USAGI: Makefile,v 1.27 2003/11/12 05:12:01 yoshfuji Exp $
 #
 # Makefile for the Linux TCP/IP (INET6) layer.
 #
@@ -9,16 +10,22 @@
 
 O_TARGET := ipv6.o
 
+export-objs :=	ipv6_tunnel.o
+
 obj-y :=	af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o sit.o \
 		route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \
 		protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
 		exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \
-		ip6_flowlabel.o ipv6_syms.o
+		ip6_flowlabel.o ipv6_syms.o utils.o
 
 export-objs := ipv6_syms.o
 
-obj-m  := $(O_TARGET)
+obj-$(CONFIG_IPV6_IPV6_TUNNEL) += ipv6_tunnel.o
 
-#obj-$(CONFIG_IPV6_FIREWALL) += ip6_fw.o
+ifneq ($(CONFIG_IPV6),y)
+ifneq ($(CONFIG_IPV6),)
+obj-m += $(O_TARGET)
+endif
+endif
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/net/ipv6/mcast.c linux-2.4.29-uc1/net/ipv6/mcast.c
--- linux-2.4.29/net/ipv6/mcast.c	2005-01-19 14:10:14.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/mcast.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: mcast.c,v 1.35 2003/11/12 05:12:01 yoshfuji Exp $ */
+
 /*
  *	Multicast support for IPv6
  *	Linux INET6 implementation 
@@ -32,6 +34,7 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/types.h>
+#include <linux/random.h>
 #include <linux/string.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
@@ -60,13 +63,36 @@
 
 #include <net/checksum.h>
 
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+#include <linux/inet.h>
+#endif
+
 /* Set to 3 to get tracing... */
-#define MCAST_DEBUG 2
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+#define MCAST_DEBUG 3
+#else
+#define MCAST_DEBUG 1
+#endif
+
+#define MDBG(x)		printk x
+#define NOMDBG(x)	do { ; } while(0)
 
 #if MCAST_DEBUG >= 3
-#define MDBG(x) printk x
+#define MDBG3(x)	MDBG(x)
 #else
-#define MDBG(x)
+#define MDBG3(x)	NOMDBG(x)
+#endif
+
+#if MCAST_DEBUB >= 2
+#define MDBG2(x)	MDBG(x)
+#else
+#define MDBG2(x)	NOMDBG(x)
+#endif
+
+#if MCAST_DEBUG >= 1
+#define MDBG1(x)	MDBG(x)
+#else
+#define MDBG1(x)	NOMDBG(x)
 #endif
 
 /*
@@ -177,6 +203,14 @@
 	struct ipv6_mc_socklist *mc_lst;
 	struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
 	int err;
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	char abuf[128];
+	in6_ntop(addr, abuf);
+
+	MDBG3((KERN_DEBUG
+		"ipv6_sock_mc_join(sk=%p, ifindex=%d, addr=%s)\n",
+		sk, ifindex, abuf));
+#endif
 
 	if (!(ipv6_addr_type(addr) & IPV6_ADDR_MULTICAST))
 		return -EINVAL;
@@ -187,7 +221,7 @@
 		return -ENOMEM;
 
 	mc_lst->next = NULL;
-	memcpy(&mc_lst->addr, addr, sizeof(struct in6_addr));
+	ipv6_addr_copy(&mc_lst->addr, addr);
 
 	if (ifindex == 0) {
 		struct rt6_info *rt;
@@ -238,17 +272,26 @@
 {
 	struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
 	struct ipv6_mc_socklist *mc_lst, **lnk;
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	char abuf[128];
+	in6_ntop(addr, abuf);
+
+	MDBG3((KERN_DEBUG
+		"ipv6_sock_mc_drop(sk=%p, ifindex=%d, addr=%s)\n",
+		sk, ifindex, abuf));
+#endif
 
 	write_lock_bh(&ipv6_sk_mc_lock);
 	for (lnk = &np->ipv6_mc_list; (mc_lst = *lnk) !=NULL ; lnk = &mc_lst->next) {
-		if (mc_lst->ifindex == ifindex &&
+		if ((ifindex == 0 || mc_lst->ifindex == ifindex) &&
 		    ipv6_addr_cmp(&mc_lst->addr, addr) == 0) {
 			struct net_device *dev;
 
 			*lnk = mc_lst->next;
 			write_unlock_bh(&ipv6_sk_mc_lock);
 
-			if ((dev = dev_get_by_index(ifindex)) != NULL) {
+			/* Note: mc_lst->ifindex != 0 */
+			if ((dev = dev_get_by_index(mc_lst->ifindex)) != NULL) {
 				struct inet6_dev *idev = in6_dev_get(dev);
 
 				if (idev) {
@@ -306,6 +349,9 @@
 	struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
 	struct ipv6_mc_socklist *mc_lst;
 
+	MDBG3((KERN_DEBUG
+		"ipv6_sock_mc_close(sk=%p)\n", sk));
+
 	write_lock_bh(&ipv6_sk_mc_lock);
 	while ((mc_lst = np->ipv6_mc_list) != NULL) {
 		struct net_device *dev;
@@ -595,6 +641,15 @@
 	struct ipv6_mc_socklist *mc;
 	struct ip6_sf_socklist *psl;
 	int rv = 1;
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	char abuf[128], sbuf[128];
+	in6_ntop(mc_addr, abuf);
+	in6_ntop(src_addr, sbuf);
+
+	MDBG3((KERN_DEBUG
+		"ipv6_sock_mc_check(sk=%p, mc_addr=%s, src_addr=%s)\n",
+		sk, abuf, sbuf));
+#endif
 
 	read_lock(&ipv6_sk_mc_lock);
 	for (mc = np->ipv6_mc_list; mc; mc = mc->next) {
@@ -627,6 +682,10 @@
 
 static void ma_put(struct ifmcaddr6 *mc)
 {
+	MDBG3((KERN_DEBUG
+		"ma_put(mc=%p): refcnt=%d\n", 
+		mc, atomic_read(&mc->mca_refcnt)));
+
 	if (atomic_dec_and_test(&mc->mca_refcnt)) {
 		in6_dev_put(mc->idev);
 		kfree(mc);
@@ -637,8 +696,17 @@
 {
 	struct net_device *dev = mc->idev->dev;
 	char buf[MAX_ADDR_LEN];
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	char abuf[128];
+#endif
 
 	spin_lock_bh(&mc->mca_lock);
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	in6_ntop(&mc->mca_addr, abuf);
+	MDBG3((KERN_DEBUG
+		"igmp6_group_added(mc=%p): mca_addr=%s, flag=%08x\n", 
+		mc, abuf, mc->mca_flags));
+#endif
 	if (!(mc->mca_flags&MAF_LOADED)) {
 		mc->mca_flags |= MAF_LOADED;
 		if (ndisc_mc_map(&mc->mca_addr, buf, dev, 0) == 0)
@@ -663,8 +731,17 @@
 {
 	struct net_device *dev = mc->idev->dev;
 	char buf[MAX_ADDR_LEN];
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	char abuf[128];
+#endif
 
 	spin_lock_bh(&mc->mca_lock);
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	in6_ntop(&mc->mca_addr, abuf);
+	MDBG3((KERN_DEBUG
+		"igmp6_group_dropped(mc=%p): mca_addr=%s, flag=%08x\n", 
+		mc, abuf, mc->mca_flags));
+#endif
 	if (mc->mca_flags&MAF_LOADED) {
 		mc->mca_flags &= ~MAF_LOADED;
 		if (ndisc_mc_map(&mc->mca_addr, buf, dev, 0) == 0)
@@ -798,6 +875,15 @@
 	struct ifmcaddr6 *mc;
 	struct inet6_dev *idev;
 
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	char abuf[128];
+	in6_ntop(addr, abuf);
+
+	MDBG3((KERN_DEBUG
+		"ipv6_dev_mc_inc(dev=%p(%s), addr=%s)\n",
+		dev, dev->name ? dev->name :"<null>", abuf));
+#endif
+
 	idev = in6_dev_get(dev);
 
 	if (idev == NULL)
@@ -837,7 +923,7 @@
 	mc->mca_timer.function = igmp6_timer_handler;
 	mc->mca_timer.data = (unsigned long) mc;
 
-	memcpy(&mc->mca_addr, addr, sizeof(struct in6_addr));
+	ipv6_addr_copy(&mc->mca_addr, addr);
 	mc->idev = idev;
 	mc->mca_users = 1;
 	atomic_set(&mc->mca_refcnt, 2);
@@ -868,6 +954,15 @@
 {
 	struct ifmcaddr6 *ma, **map;
 
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	char abuf[128];
+	in6_ntop(addr, abuf);
+
+	MDBG3((KERN_DEBUG
+		"ipv6_dev_mc_dec(dev=%p(%s), idev=%p, addr=%s)\n",
+		dev, dev->name ? dev->name : "<null>", idev, abuf));
+#endif
+
 	write_lock_bh(&idev->lock);
 	for (map = &idev->mc_list; (ma=*map) != NULL; map = &ma->next) {
 		if (ipv6_addr_cmp(&ma->mca_addr, addr) == 0) {
@@ -913,6 +1008,15 @@
 	struct inet6_dev *idev;
 	struct ifmcaddr6 *mc;
 	int rv = 0;
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	char abuf[128], sbuf[128];
+	in6_ntop(group, abuf);
+	in6_ntop(src_addr, sbuf);
+
+	MDBG3((KERN_DEBUG
+		"ipv6_chk_mcast_addr(dev=%p(%s), group=%s, src_addr=%s)\n",
+		dev, dev->name ? dev->name : "<null>", abuf, sbuf));
+#endif
 
 	idev = in6_dev_get(dev);
 	if (idev) {
@@ -972,9 +1076,13 @@
 {
 	unsigned long delay = resptime;
 
-	/* Do not start timer for these addresses */
-	if (ipv6_addr_is_ll_all_nodes(&ma->mca_addr) ||
-	    IPV6_ADDR_MC_SCOPE(&ma->mca_addr) < IPV6_ADDR_SCOPE_LINKLOCAL)
+	MDBG3((KERN_DEBUG
+		"igmp6_group_queried(ma=%p, resptime=%lu)\n",
+		ma, resptime));
+
+	/* Do not start timer for addresses with reserved/host scope */
+	if (IPV6_ADDR_MC_SCOPE(&ma->mca_addr) < IPV6_ADDR_SCOPE_LINKLOCAL ||
+	    ipv6_addr_is_ll_all_nodes(&ma->mca_addr))
 		return;
 
 	if (del_timer(&ma->mca_timer)) {
@@ -983,9 +1091,10 @@
 	}
 
 	if (delay >= resptime) {
-		if (resptime)
-			delay = net_random() % resptime;
-		else
+		if (resptime) {
+			get_random_bytes(&delay, sizeof(delay));
+			delay %= resptime;
+		} else
 			delay = 1;
 	}
 
@@ -1026,6 +1135,15 @@
 	int group_type;
 	int mark = 0;
 	int len;
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	char abuf1[128], abuf2[128];
+
+	in6_ntop(&skb->nh.ipv6h->saddr, abuf1);
+	in6_ntop(&skb->nh.ipv6h->daddr, abuf2);
+	MDBG3((KERN_DEBUG
+		"igmp6_event_query(skb=%p): saddr=%s, daddr=%s\n",
+		skb, abuf1, abuf2));
+#endif
 
 	if (!pskb_may_pull(skb, sizeof(struct in6_addr)))
 		return -EINVAL;
@@ -1034,7 +1152,7 @@
 
 	/* Drop queries with not link local source */
 	if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr)&IPV6_ADDR_LINKLOCAL))
-		return -EINVAL;
+ 		return -EINVAL;
 
 	idev = in6_dev_get(skb->dev);
 
@@ -1125,7 +1243,6 @@
 	}
 	read_unlock_bh(&idev->lock);
 	in6_dev_put(idev);
-
 	return 0;
 }
 
@@ -1137,6 +1254,16 @@
 	struct inet6_dev *idev;
 	struct icmp6hdr *hdr;
 	int addr_type;
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	char abuf1[128], abuf2[128];
+	unsigned long resptime;
+
+	in6_ntop(&skb->nh.ipv6h->saddr, abuf1);
+	in6_ntop(&skb->nh.ipv6h->daddr, abuf2);
+	MDBG((KERN_DEBUG
+		"igmp6_event_report(skb=%p): saddr=%s, daddr=%s\n",
+		skb, abuf1, abuf2));
+#endif
 
 	/* Our own report looped back. Ignore it. */
 	if (skb->pkt_type == PACKET_LOOPBACK)
@@ -1153,8 +1280,21 @@
 	    !(addr_type&IPV6_ADDR_LINKLOCAL))
 		return -EINVAL;
 
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	resptime = ntohs(hdr->icmp6_maxdelay);
+#endif
 	addrp = (struct in6_addr *) (hdr + 1);
 
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	in6_ntop(addrp, abuf1);
+	MDBG3((KERN_DEBUG
+		"igmp6_event_report(): maxdelay=%lu, addr=%s\n",
+		resptime, abuf1));
+#endif
+
+	if (!ipv6_addr_is_multicast(addrp))
+		goto drop;
+
 	idev = in6_dev_get(skb->dev);
 	if (idev == NULL)
 		return -ENODEV;
@@ -1169,13 +1309,18 @@
 			spin_lock(&ma->mca_lock);
 			if (del_timer(&ma->mca_timer))
 				atomic_dec(&ma->mca_refcnt);
+#ifndef CONFIG_IPV6_MLD6_ALL_DONE
 			ma->mca_flags &= ~(MAF_LAST_REPORTER|MAF_TIMER_RUNNING);
+#else
+			ma->mca_flags &= ~MAF_TIMER_RUNNING;
+#endif
 			spin_unlock(&ma->mca_lock);
 			break;
 		}
 	}
 	read_unlock_bh(&idev->lock);
 	in6_dev_put(idev);
+  drop:
 	return 0;
 }
 
@@ -1279,6 +1424,7 @@
 {
 	struct ipv6hdr *pip6 = skb->nh.ipv6h;
 	struct mld2_report *pmr = (struct mld2_report *)skb->h.raw;
+	struct inet6_dev *idev;
 	int payload_len, mldlen, err;
 
 	payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h -
@@ -1288,10 +1434,15 @@
 
 	pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen,
 		IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0));
+	idev = in6_dev_get(skb->dev);
+
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
 		      dev_queue_xmit);
 	if (!err)
-		ICMP6_INC_STATS(Icmp6OutMsgs);
+		ICMP6_INC_STATS(idev, Icmp6OutMsgs);
+
+	if (idev)
+		in6_dev_put(idev);
 }
 
 static int grec_size(struct ifmcaddr6 *pmc, int type, int gdel, int sdel)
@@ -1559,6 +1710,7 @@
 {
 	struct sock *sk = igmp6_socket->sk;
         struct sk_buff *skb;
+	struct inet6_dev *idev;
         struct icmp6hdr *hdr;
 	struct in6_addr *snd_addr;
 	struct in6_addr *addrp;
@@ -1568,6 +1720,14 @@
 	u8 ra[8] = { IPPROTO_ICMPV6, 0,
 		     IPV6_TLV_ROUTERALERT, 2, 0, 0,
 		     IPV6_TLV_PADN, 0 };
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	char abuf[128];
+	in6_ntop(addr, abuf);
+
+	MDBG3((KERN_DEBUG
+		"igmp6_send(addr=%s, dev=%p(%s), type=%d)\n",
+		abuf, dev, dev->name ? dev->name :"<null>", type));
+#endif
 
 	snd_addr = addr;
 	if (type == ICMPV6_MGM_REDUCTION) {
@@ -1597,6 +1757,8 @@
 		 * use unspecified address as the source address 
 		 * when a valid link-local address is not available.
 		 */
+		MDBG2((KERN_WARNING "igmp6: %s no linklocal address; use unspecified address\n",
+		       dev->name));
 		memset(&addr_buf, 0, sizeof(addr_buf));
 	}
 
@@ -1617,13 +1779,16 @@
 
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
 		      dev_queue_xmit);
+	idev = in6_dev_get(dev);
 	if (!err) {
 		if (type == ICMPV6_MGM_REDUCTION)
-			ICMP6_INC_STATS(Icmp6OutGroupMembReductions);
+			ICMP6_INC_STATS(idev, Icmp6OutGroupMembReductions);
 		else
-			ICMP6_INC_STATS(Icmp6OutGroupMembResponses);
-		ICMP6_INC_STATS(Icmp6OutMsgs);
+			ICMP6_INC_STATS(idev, Icmp6OutGroupMembResponses);
+		ICMP6_INC_STATS(idev, Icmp6OutMsgs);
 	}
+	if (idev)
+		in6_dev_put(idev);
 
 	return;
 
@@ -1874,13 +2039,22 @@
 static void igmp6_join_group(struct ifmcaddr6 *ma)
 {
 	unsigned long delay;
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	char abuf[128];
+	in6_ntop(&ma->mca_addr, abuf);
+
+	MDBG3((KERN_DEBUG
+		"igmp6_join_group(ma=%p): mca_addr=%s\n",
+		ma, abuf));
+#endif
 
 	if (ma->mca_flags & MAF_NOREPORT)
 		return;
 
 	igmp6_send(&ma->mca_addr, ma->idev->dev, ICMPV6_MGM_REPORT);
 
-	delay = net_random() % IGMP6_UNSOLICITED_IVAL;
+	get_random_bytes(&delay, sizeof(delay));
+	delay %= IGMP6_UNSOLICITED_IVAL;
 
 	spin_lock_bh(&ma->mca_lock);
 	if (del_timer(&ma->mca_timer)) {
@@ -1912,6 +2086,15 @@
 
 static void igmp6_leave_group(struct ifmcaddr6 *ma)
 {
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	char abuf[128];
+	in6_ntop(&ma->mca_addr, abuf);
+
+	MDBG3((KERN_DEBUG
+		"igmp6_leave_group(ma=%p): mca_addr=%s\n",
+		ma, abuf));
+#endif
+
 	if (MLD_V1_SEEN(ma->idev)) {
 		if (ma->mca_flags & MAF_LAST_REPORTER)
 			igmp6_send(&ma->mca_addr, ma->idev->dev,
@@ -1956,6 +2139,14 @@
 static void igmp6_timer_handler(unsigned long data)
 {
 	struct ifmcaddr6 *ma = (struct ifmcaddr6 *) data;
+#ifdef CONFIG_IPV6_MLD6_DEBUG
+	char abuf[128];
+	in6_ntop(&ma->mca_addr, abuf);
+
+	MDBG3((KERN_DEBUG
+		"igmp6_timer_handler(ma=%p): mca_addr=%s\n", 
+		ma, abuf));
+#endif
 
 	if (MLD_V1_SEEN(ma->idev))
 		igmp6_send(&ma->mca_addr, ma->idev->dev, ICMPV6_MGM_REPORT);
@@ -1975,6 +2166,9 @@
 {
 	struct ifmcaddr6 *i;
 
+	MDBG3((KERN_DEBUG
+		"ipv6_mc_down(idev=%p)\n", idev));
+
 	/* Withdraw multicast list */
 
 	read_lock_bh(&idev->lock);
@@ -2032,6 +2226,12 @@
 	/* Add all-nodes address. */
 	ipv6_addr_all_nodes(&maddr);
 	ipv6_dev_mc_inc(idev->dev, &maddr);
+
+	/* Add all-routers address. */
+	if (idev->cnf.forwarding) {
+		ipv6_addr_all_routers(&maddr);
+		ipv6_dev_mc_inc(idev->dev, &maddr);
+	}
 }
 
 /*
@@ -2043,6 +2243,9 @@
 	struct ifmcaddr6 *i;
 	struct in6_addr maddr;
 
+	MDBG3((KERN_DEBUG
+		"ipv6_mc_destroy_dev(idev=%p)\n", idev));
+
 	/* Deactivate timers */
 	ipv6_mc_down(idev);
 
@@ -2055,6 +2258,12 @@
 	 */
 	__ipv6_dev_mc_dec(idev->dev, idev, &maddr);
 
+	/* Delete all-routers address. */
+	if (idev->cnf.forwarding) {
+		ipv6_addr_all_routers(&maddr);
+		ipv6_dev_mc_dec(idev->dev, &maddr);
+	}
+
 	write_lock_bh(&idev->lock);
 	while ((i = idev->mc_list) != NULL) {
 		idev->mc_list = i->next;
@@ -2210,8 +2419,8 @@
 
 	igmp6_socket = sock_alloc();
 	if (igmp6_socket == NULL) {
-		printk(KERN_ERR
-		       "Failed to create the IGMP6 control socket.\n");
+		MDBG1((KERN_ERR
+		       "Failed to create the IGMP6 control socket.\n"));
 		return -1;
 	}
 	igmp6_socket->inode->i_uid = 0;
@@ -2219,9 +2428,9 @@
 	igmp6_socket->type = SOCK_RAW;
 
 	if((err = ops->create(igmp6_socket, IPPROTO_ICMPV6)) < 0) {
-		printk(KERN_DEBUG 
+		MDBG1((KERN_ERR
 		       "Failed to initialize the IGMP6 control socket (err %d).\n",
-		       err);
+		       err));
 		sock_release(igmp6_socket);
 		igmp6_socket = NULL; /* For safety. */
 		return err;
diff -urN linux-2.4.29/net/ipv6/ndisc.c linux-2.4.29-uc1/net/ipv6/ndisc.c
--- linux-2.4.29/net/ipv6/ndisc.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/ndisc.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: ndisc.c,v 1.132 2004/02/01 10:05:55 yoshfuji Exp $ */
+
 /*
  *	Neighbour Discovery for IPv6
  *	Linux INET6 implementation 
@@ -23,16 +25,26 @@
  *						and moved to net/core.
  *	Pekka Savola			:	RFC2461 validation
  *	YOSHIFUJI Hideaki @USAGI	:	Verify ND options properly
+ *	Ville Nuorvala			:	proxy offers protection
+ *						against DAD
  */
 
+#define __NO_VERSION__
+#include <linux/config.h>
+
 /* Set to 3 to get tracing... */
+#ifdef CONFIG_IPV6_NDISC_DEBUG
+#define ND_DEBUG 3
+#else
 #define ND_DEBUG 1
+#endif
 
-#define ND_PRINTK(x...) printk(KERN_DEBUG x)
+#define ND_PRINTK(x...) printk(x)
 #define ND_NOPRINTK(x...) do { ; } while(0)
 #define ND_PRINTK0 ND_PRINTK
 #define ND_PRINTK1 ND_NOPRINTK
 #define ND_PRINTK2 ND_NOPRINTK
+#define ND_PRINTK3 ND_NOPRINTK
 #if ND_DEBUG >= 1
 #undef ND_PRINTK1
 #define ND_PRINTK1 ND_PRINTK
@@ -41,9 +53,12 @@
 #undef ND_PRINTK2
 #define ND_PRINTK2 ND_PRINTK
 #endif
+#if ND_DEBUG >= 3
+#undef ND_PRINTK3
+#define ND_PRINTK3 ND_PRINTK
+#endif
 
 #include <linux/module.h>
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/socket.h>
@@ -60,6 +75,9 @@
 #include <linux/if_arp.h>
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
+#include <linux/inet.h>
+
+#include <linux/if_tr.h>
 #include <linux/jhash.h>
 
 #include <net/sock.h>
@@ -135,7 +153,7 @@
 	pndisc_redo,
 	"ndisc_cache",
         { NULL, NULL, &nd_tbl, 0, NULL, NULL,
-		  30*HZ, 1*HZ, 60*HZ, 30*HZ, 5*HZ, 3, 3, 0, 3, 1*HZ, (8*HZ)/10, 64, 0 },
+		  30*HZ, 1*HZ, 86400*HZ, 30*HZ, 5*HZ, 3, 3, 0, 3, 1*HZ, (8*HZ)/10, 64, 0 },
 	30*HZ, 128, 512, 1024,
 };
 
@@ -173,25 +191,39 @@
 {
 	struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)opt;
 
+	ND_PRINTK3(KERN_DEBUG 
+		   "ndisc_parse_options(opt=%p, opt_len=%d, ndopts=%p)\n",
+		   opt, opt_len, ndopts);
+
 	if (!nd_opt || opt_len < 0 || !ndopts)
 		return NULL;
 	memset(ndopts, 0, sizeof(*ndopts));
 	while (opt_len) {
 		int l;
-		if (opt_len < sizeof(struct nd_opt_hdr))
+		if (opt_len < sizeof(struct nd_opt_hdr)) {
+			ND_PRINTK3(KERN_WARNING 
+				   "ndisc_parse_options(opt=%p, opt_len=%d, ndopts=%p): truncated options found\n",
+				   opt, opt_len, ndopts);
 			return NULL;
+		}
 		l = nd_opt->nd_opt_len << 3;
-		if (opt_len < l || l == 0)
+		if (opt_len < l || l == 0) {
+			ND_PRINTK3(KERN_WARNING
+				   "ndisc_parse_options(): %s found; type=%d, len=%d (remain: %d)\n",
+				   l ? "truncated option" : "zero-length option",
+				   nd_opt->nd_opt_type, l, opt_len);
 			return NULL;
+		}
 		switch (nd_opt->nd_opt_type) {
 		case ND_OPT_SOURCE_LL_ADDR:
 		case ND_OPT_TARGET_LL_ADDR:
 		case ND_OPT_MTU:
 		case ND_OPT_REDIRECT_HDR:
+		case ND_OPT_RTR_ADV_INTERVAL:
 			if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
-				ND_PRINTK2((KERN_WARNING
-					    "ndisc_parse_options(): duplicated ND6 option found: type=%d\n",
-					    nd_opt->nd_opt_type));
+				ND_PRINTK3(KERN_WARNING 
+					   "ndisc_parse_options(): duplicated ND6 option found: type=%d\n",
+					   nd_opt->nd_opt_type);
 			} else {
 				ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
 			}
@@ -201,10 +233,20 @@
 			if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0)
 				ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
 			break;
+		case ND_OPT_ROUTE_INFO:
+#if defined(CONFIG_IPV6_ROUTE_INFO)
+			ndopts->nd_opts_ri_end = nd_opt;
+			if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0)
+				ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
+#endif
+			break;
+		case ND_OPT_HOME_AGENT_INFO:
+			/* These two are handled by the MIPv6 code */
+			break;
 		default:
 			/*
 			 * Unknown options must be silently ignored,
-			 * to accomodate future extension to the protocol.
+			 * to accommodate future extension to the protocol.
 			 */
 			ND_PRINTK2(KERN_WARNING
 				   "ndisc_parse_options(): ignored unsupported option; type=%d, len=%d\n",
@@ -366,6 +408,20 @@
 	return 1;
 }
 
+static void inline ndisc_update(struct neighbour *neigh, 
+				u8 *lladdr, u32 flags)
+{
+	int notify;
+	write_lock_bh(&neigh->lock);
+	notify = __neigh_update(neigh, lladdr, NUD_STALE, flags);
+#ifdef CONFIG_ARPD
+	if (notify > 0 && neigh->parms->app_probes) {
+		write_unlock_bh(&neigh->lock);
+		neigh_app_notify(neigh);
+	} else
+#endif
+	write_unlock_bh(&neigh->lock);
+}
 
 /*
  *	Send a Neighbour Advertisement
@@ -375,16 +431,36 @@
 		   struct in6_addr *daddr, struct in6_addr *solicited_addr,
 		   int router, int solicited, int override, int inc_opt) 
 {
-	static struct in6_addr tmpaddr;
+	struct in6_addr tmpaddr;
 	struct inet6_ifaddr *ifp;
-        struct sock *sk = ndisc_socket->sk;
+	struct sock *sk = ndisc_socket->sk;
 	struct in6_addr *src_addr;
-        struct nd_msg *msg;
-        int len;
-        struct sk_buff *skb;
+	struct nd_msg *msg;
+	int len;
+	struct sk_buff *skb;
+	struct inet6_dev *idev;
 	int err;
 
-	len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
+	/* for proxy or anycast, solicited_addr != src_addr */
+	ifp = ipv6_get_ifaddr(solicited_addr, dev);
+	if (ifp) {
+		src_addr = solicited_addr;
+		in6_ifa_put(ifp);
+	} else {
+		if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr, sk->net_pinfo.af_inet6.use_tempaddr)) {
+#ifdef CONFIG_IPV6_NDISC_DEBUG
+			char abuf[64];
+			in6_ntop(daddr, abuf);
+			ND_PRINTK2(KERN_WARNING 
+				   "ndisc_send_na(): could not get source address for %s on device %p(%s)\n", 
+				   abuf, dev, dev ? dev->name : "<null>");
+#endif
+			return;
+		}
+		src_addr = &tmpaddr;
+	}
+
+	len = sizeof(struct nd_msg);
 
 	if (inc_opt) {
 		if (dev->addr_len)
@@ -397,19 +473,10 @@
 				  1, &err);
 
 	if (skb == NULL) {
-		ND_PRINTK1("send_na: alloc skb failed\n");
+		ND_PRINTK1(KERN_WARNING 
+			   "send_na: alloc skb failed\n");
 		return;
 	}
-	/* for anycast or proxy, solicited_addr != src_addr */
-	ifp = ipv6_get_ifaddr(solicited_addr, dev);
-	if (ifp) {
-		src_addr = solicited_addr;
-		in6_ifa_put(ifp);
-	} else {
-		if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr, 0))
-			return;
-		src_addr = &tmpaddr;
-	}
 
 	if (ndisc_build_ll_hdr(skb, dev, daddr, neigh, len) == 0) {
 		kfree_skb(skb);
@@ -419,7 +486,6 @@
 	ip6_nd_hdr(sk, skb, dev, src_addr, daddr, IPPROTO_ICMPV6, len);
 
 	msg = (struct nd_msg *) skb_put(skb, len);
-
         msg->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
         msg->icmph.icmp6_code = 0;
         msg->icmph.icmp6_cksum = 0;
@@ -443,37 +509,67 @@
 
 	dev_queue_xmit(skb);
 
-	ICMP6_INC_STATS(Icmp6OutNeighborAdvertisements);
-	ICMP6_INC_STATS(Icmp6OutMsgs);
+	idev = in6_dev_get(dev);
+	ICMP6_INC_STATS(idev,Icmp6OutNeighborAdvertisements);
+	ICMP6_INC_STATS(idev,Icmp6OutMsgs);
+	if (idev)
+		in6_dev_put(idev);
 }        
 
 void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
 		   struct in6_addr *solicit,
-		   struct in6_addr *daddr, struct in6_addr *saddr) 
+		   struct in6_addr *daddr, struct in6_addr *saddr,
+		   int dad) 
 {
         struct sock *sk = ndisc_socket->sk;
         struct sk_buff *skb;
+	struct inet6_dev *idev;
         struct nd_msg *msg;
 	struct in6_addr addr_buf;
         int len;
 	int err;
 	int send_llinfo;
 
-	if (saddr == NULL) {
-		if (ipv6_get_lladdr(dev, &addr_buf))
-			return;
+#if CONFIG_IPV6_NDISC_DEBUG
+	char abuf1[128], abuf2[128], abuf3[128];
+
+	if (saddr)
+		in6_ntop(saddr, abuf1);
+	if (daddr)
+		in6_ntop(daddr, abuf2);
+	if (solicit)
+		in6_ntop(solicit, abuf3);
+	ND_PRINTK3(KERN_DEBUG 
+		   "ndisc_send_ns(): saddr=%s, daddr=%s, solicit=%s, dad=%d\n",
+		   saddr ? abuf1 : "<null>",
+		   daddr ? abuf2 : "<null>",
+		   solicit ? abuf3 : "<null>",
+		   dad);
+#endif
+
+	if (dad) {
+		memset(&addr_buf, 0, sizeof(addr_buf));
 		saddr = &addr_buf;
+		send_llinfo = 0;
+	} else {
+		if (saddr == NULL) {
+			if (ipv6_get_lladdr(dev, &addr_buf))
+				return;
+			saddr = &addr_buf;
+		}
+		send_llinfo = !ipv6_addr_any(saddr) && dev->addr_len;
 	}
 
-	len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
-	send_llinfo = dev->addr_len && ipv6_addr_type(saddr) != IPV6_ADDR_ANY;
+	len = sizeof(struct nd_msg);
 	if (send_llinfo)
 		len += NDISC_OPT_SPACE(dev->addr_len);
 
 	skb = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
 				  1, &err);
+
 	if (skb == NULL) {
-		ND_PRINTK1("send_ns: alloc skb failed\n");
+		ND_PRINTK1(KERN_WARNING
+			   "send_ns: alloc skb failed\n");
 		return;
 	}
 
@@ -502,11 +598,29 @@
 						 IPPROTO_ICMPV6,
 						 csum_partial((__u8 *) msg, 
 							      len, 0));
+#if CONFIG_IPV6_NDISC_DEBUG
+	if (saddr)
+		in6_ntop(saddr, abuf1);
+	if (daddr)
+		in6_ntop(daddr, abuf2);
+	if (solicit)
+		in6_ntop(solicit, abuf3);
+	ND_PRINTK3(KERN_DEBUG 
+		   "ndisc_send_ns(): -> saddr=%s, daddr=%s, solicit=%s, option_ok=%d\n",
+		  saddr ? abuf1 : "<null>",
+		  daddr ? abuf2 : "<null>",
+		  solicit ? abuf3 : "<null>",
+		  send_llinfo);
+#endif
+
 	/* send it! */
 	dev_queue_xmit(skb);
 
-	ICMP6_INC_STATS(Icmp6OutNeighborSolicits);
-	ICMP6_INC_STATS(Icmp6OutMsgs);
+	idev = in6_dev_get(dev);
+	ICMP6_INC_STATS(idev,Icmp6OutNeighborSolicits);
+	ICMP6_INC_STATS(idev,Icmp6OutMsgs);
+	if (idev)
+		in6_dev_put(idev);
 }
 
 void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
@@ -514,8 +628,8 @@
 {
 	struct sock *sk = ndisc_socket->sk;
         struct sk_buff *skb;
-        struct icmp6hdr *hdr;
-	__u8 * opt;
+	struct inet6_dev *idev;
+	struct rs_msg *hdr;
         int len;
 	int err;
 
@@ -523,10 +637,12 @@
 	if (dev->addr_len)
 		len += NDISC_OPT_SPACE(dev->addr_len);
 
-        skb = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
+	skb = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
 				  1, &err);
+
 	if (skb == NULL) {
-		ND_PRINTK1("send_ns: alloc skb failed\n");
+		ND_PRINTK1(KERN_WARNING
+			   "send_rs: alloc skb failed\n");
 		return;
 	}
 
@@ -537,29 +653,31 @@
 
 	ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
 
-        hdr = (struct icmp6hdr *) skb_put(skb, len);
-        hdr->icmp6_type = NDISC_ROUTER_SOLICITATION;
-        hdr->icmp6_code = 0;
-        hdr->icmp6_cksum = 0;
-        hdr->icmp6_unused = 0;
-
-	opt = (u8*) (hdr + 1);
+	hdr = (struct rs_msg *)skb_put(skb, len);
+        hdr->icmph.icmp6_type = NDISC_ROUTER_SOLICITATION;
+        hdr->icmph.icmp6_code = 0;
+        hdr->icmph.icmp6_cksum = 0;
+        hdr->icmph.icmp6_unused = 0;
 
 	if (dev->addr_len)
-		ndisc_fill_option(opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
+		ndisc_fill_option(hdr->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
 
 	/* checksum */
-	hdr->icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr, daddr, len,
-					   IPPROTO_ICMPV6,
-					   csum_partial((__u8 *) hdr, len, 0));
+	hdr->icmph.icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr, daddr, len,
+						 IPPROTO_ICMPV6,
+						 csum_partial((__u8 *) hdr, len, 0));
 
 	/* send it! */
+	ND_PRINTK3(KERN_DEBUG 
+		   "ndisc_send_rs: send RS message\n");
 	dev_queue_xmit(skb);
 
-	ICMP6_INC_STATS(Icmp6OutRouterSolicits);
-	ICMP6_INC_STATS(Icmp6OutMsgs);
+	idev = in6_dev_get(dev);
+	ICMP6_INC_STATS(idev,Icmp6OutRouterSolicits);
+	ICMP6_INC_STATS(idev,Icmp6OutMsgs);
+	if (idev)
+		in6_dev_put(idev);
 }
-		   
 
 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
 {
@@ -584,59 +702,173 @@
 	if (skb && ipv6_chk_addr(&skb->nh.ipv6h->saddr, dev))
 		saddr = &skb->nh.ipv6h->saddr;
 
+	read_lock_bh(&neigh->lock);
 	if ((probes -= neigh->parms->ucast_probes) < 0) {
 		if (!(neigh->nud_state&NUD_VALID))
-			ND_PRINTK1("trying to ucast probe in NUD_INVALID\n");
-		ndisc_send_ns(dev, neigh, target, target, saddr);
+			ND_PRINTK1(KERN_WARNING 
+				   "ndisc_solicit(): trying to ucast probe in NUD_INVALID\n");
+		read_unlock_bh(&neigh->lock);
+		ndisc_send_ns(dev, neigh, target, target, saddr, 0);
 	} else if ((probes -= neigh->parms->app_probes) < 0) {
+		read_unlock_bh(&neigh->lock);
 #ifdef CONFIG_ARPD
 		neigh_app_ns(neigh);
 #endif
 	} else {
+		read_unlock_bh(&neigh->lock);
 		addrconf_addr_solict_mult(target, &mcaddr);
-		ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
+		ndisc_send_ns(dev, NULL, target, &mcaddr, saddr, 0);
 	}
 }
 
-void ndisc_recv_ns(struct sk_buff *skb)
+#define IPV6READYLOGO
+#ifdef IPV6READYLOGO
+static int ndisc_getfrag( const void *data, struct in6_addr *addr, char *buff,
+		unsigned int offset, unsigned int len)
+{
+	ND_PRINTK1(KERN_DEBUG "ndisc_getfrag len=%d \n", len);
+	memcpy( buff, data+offset, len);
+	return 0;
+}	
+
+static void no_neigh_send_na( struct net_device *dev, struct sk_buff *oldskb)
+	// copy&modify from icmp.c : static void icmpv6_echo_reply(struct sk_buff *skb)
+	// Need more work if define CONFIG_IPV6_IPSEC
+{
+	struct sock *sk = ndisc_socket->sk;
+	struct nd_msg *msg;
+	int len;
+	struct sk_buff *skb;
+	struct inet6_dev *idev;
+	int err;
+
+	int ipsec_hdrlen = 0;
+	int ipsec_authhdrlen = 0;
+
+	struct in6_addr *daddr ,*saddr;
+	struct flowi fl;
+
+	daddr = &oldskb->nh.ipv6h->saddr;
+	saddr = &oldskb->nh.ipv6h->daddr;
+
+	if ((ipv6_addr_type(saddr) & (IPV6_ADDR_MULTICAST|IPV6_ADDR_ANYCAST))
+#ifdef CONFIG_IPV6_ANYCAST
+			|| ipv6_chk_acast_addr(0, saddr)
+#endif
+	   )
+		saddr = NULL;
+	len = sizeof(struct nd_msg);
+//no opt         len += NDISC_OPT_SPACE(dev->addr_len);
+	skb = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15 + ipsec_hdrlen,0, &err);
+
+	if (skb == NULL) {
+		ND_PRINTK1(KERN_DEBUG "no_neigh_send_ns: alloc skb failed\n");
+		return;
+	}
+#if 0  // Can not make ll here, because ns is w/o ll
+	if (ndisc_build_ll_hdr(skb, dev, daddr, NULL, len + ipsec_hdrlen) == 0
+	   ) {
+		ND_PRINTK1(KERN_DEBUG "no_neigh_send_ns: build_ll_hdr failed\n");
+		kfree_skb(skb);
+		return;
+	}
+#endif
+	ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len + ipsec_authhdrlen);
+	msg = (struct nd_msg *) skb_put(skb, len);
+
+	msg->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
+	msg->icmph.icmp6_code = 0;
+	msg->icmph.icmp6_cksum = 0;
+
+	msg->icmph.icmp6_unused = 0;
+	msg->icmph.icmp6_router    = 1; //router;
+	msg->icmph.icmp6_solicited = 1; //solicited;
+	msg->icmph.icmp6_override  = 0; //!!override;
+
+
+	/* Set the target address. */
+	ipv6_addr_copy(&msg->target, saddr);
+
+	//        if (send_llinfo)
+	// no opt                ndisc_fill_option((void*)(msg+1), ND_OPT_TARGET_LL_ADDR, dev->dev_addr, dev->addr_len);
+
+	/* checksum */
+	msg->icmph.icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr,
+			daddr, len,
+			IPPROTO_ICMPV6,
+			csum_partial((__u8 *) msg,
+				len, 0));
+
+	fl.proto = IPPROTO_ICMPV6;
+	fl.nl_u.ip6_u.daddr = &oldskb->nh.ipv6h->saddr;
+	fl.nl_u.ip6_u.saddr = saddr;
+	fl.oif = skb->dev->ifindex;
+	fl.fl6_flowlabel = 0;
+	fl.uli_u.icmpt.type = NDISC_NEIGHBOUR_ADVERTISEMENT; 
+	fl.uli_u.icmpt.code = 0;
+//may need more effort ?      if (icmpv6_xmit_lock_bh())
+//  			              return;
+
+	ip6_build_xmit(sk, ndisc_getfrag, msg, &fl, len, NULL, -1, -1, MSG_DONTWAIT);
+	idev = in6_dev_get(dev);
+	ICMP6_INC_STATS(idev,Icmp6OutNeighborSolicits);
+	ICMP6_INC_STATS(idev,Icmp6OutMsgs);
+	if (idev)
+		in6_dev_put(idev);
+
+	kfree_skb(skb);
+//may need more effort ?  icmpv6_xmit_unlock_bh();
+}
+#endif
+static void ndisc_recv_ns(struct sk_buff *skb)
 {
-	struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
+	struct nd_msg *msg = (struct nd_msg *) skb->h.raw;
 	struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
 	struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
+	struct neighbour *neigh;
 	u8 *lladdr = NULL;
 	int lladdrlen = 0;
-	u32 ndoptlen = skb->tail - msg->opt;
+	u32 ndoptlen = skb->len - sizeof(*msg);
 	struct ndisc_options ndopts;
 	struct net_device *dev = skb->dev;
 	struct inet6_ifaddr *ifp;
-	struct neighbour *neigh;
+	int addr_type = ipv6_addr_type(saddr);
 
-	if (skb->len < sizeof(struct nd_msg)) {
-		if (net_ratelimit())
-			printk(KERN_WARNING "ICMP NS: packet too short\n");
+	if (skb->len < sizeof(*msg))
 		return;
+
+	if (addr_type == IPV6_ADDR_ANY) {
+		/* dst has to be solicited node multicast address */
+		if (!(daddr->s6_addr32[0] == htonl(0xff020000) &&
+		      daddr->s6_addr32[1] == htonl(0x00000000) &&
+		      daddr->s6_addr32[2] == htonl(0x00000001) &&
+		      daddr->s6_addr [12] == 0xff )) {
+			if (net_ratelimit())
+				ND_PRINTK2(KERN_WARNING 
+					   "ICMP6 NS: bad DAD packet (wrong ip6 dst)\n");
+			goto bad;
+		}
 	}
 
 	if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) {
 		if (net_ratelimit())
-			printk(KERN_WARNING "ICMP NS: target address is multicast\n");
-		return;
+			ND_PRINTK2(KERN_WARNING 
+				   "ICMP6 NS: bad ND target (multicast)\n");
+		goto bad;
 	}
 
 	if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
 		if (net_ratelimit())
-			printk(KERN_WARNING "ICMP NS: invalid ND option, ignored.\n");
-		return;
+			ND_PRINTK2(KERN_WARNING 
+				   "ICMP6 ND: invalid ND option, ignored\n");
+		goto bad;
 	}
 
 	if (ndopts.nd_opts_src_lladdr) {
 		lladdr = (u8*)(ndopts.nd_opts_src_lladdr + 1);
 		lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
-		if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len)) {
-			if (net_ratelimit())
-				printk(KERN_WARNING "ICMP NS: bad lladdr length.\n");
-			return;
-		}
+		if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len))
+			goto bad;
 	}
 
 	/* XXX: RFC2461 7.1.1:
@@ -645,16 +877,17 @@
 	 *
 	 *	NOTE! Linux kernel < 2.4.4 broke this rule.
 	 */
-		 	
-	/* XXX: RFC2461 7.1.1:
-	 *	If the IP source address is the unspecified address, the IP
-      	 *	destination address MUST be a solicited-node multicast address.
-	 */
+	if (addr_type == IPV6_ADDR_ANY && lladdr) {
+		if (net_ratelimit())
+			ND_PRINTK2(KERN_WARNING 
+				   "ICMP6 NS: bad DAD packet (link-layer address option)\n");
+		goto bad;
+	}
 
 	if ((ifp = ipv6_get_ifaddr(&msg->target, dev)) != NULL) {
-		int addr_type = ipv6_addr_type(saddr);
-
 		if (ifp->flags & IFA_F_TENTATIVE) {
+			ND_PRINTK1(KERN_INFO 
+				   "ICMP6 NS : Received DAD NS but our address is TENTATIVE.\n");
 			/* Address is tentative. If the source
 			   is unspecified address, it is someone
 			   does DAD, otherwise we ignore solicitations
@@ -662,19 +895,17 @@
 			 */
 			if (addr_type == IPV6_ADDR_ANY) {
 				if (dev->type == ARPHRD_IEEE802_TR) { 
-					unsigned char *sadr = skb->mac.raw ;
-					if (((sadr[8] &0x7f) != (dev->dev_addr[0] & 0x7f)) ||
-					(sadr[9] != dev->dev_addr[1]) ||
-					(sadr[10] != dev->dev_addr[2]) ||
-					(sadr[11] != dev->dev_addr[3]) ||
-					(sadr[12] != dev->dev_addr[4]) ||
-					(sadr[13] != dev->dev_addr[5])) 
-					{
+					/*
+					 * IMHO, this should be handled in
+					 * network drivers.
+					 * - yoshfuji (2001/01/07)
+					 */
+					struct trh_hdr *thdr = (struct trh_hdr *)skb->mac.raw;
+					if (((thdr->saddr[0] ^ dev->dev_addr[0]) & 0x7f) ||
+					    memcmp(&thdr->saddr[1], &dev->dev_addr[1], dev->addr_len - 1))
 						addrconf_dad_failure(ifp) ; 
-					}
-				} else {
+				} else
 					addrconf_dad_failure(ifp);
-				}
 			} else
 				in6_ifa_put(ifp);
 			return;
@@ -685,9 +916,7 @@
 
 			ipv6_addr_all_nodes(&maddr);
 			ndisc_send_na(dev, NULL, &maddr, &ifp->addr, 
-				      ifp->idev->cnf.forwarding, 0, 
-				      ipv6_addr_type(&ifp->addr)&IPV6_ADDR_ANYCAST ? 0 : 1, 
-				      1);
+				      ifp->idev->cnf.forwarding, 0, 1, 1);
 			in6_ifa_put(ifp);
 			return;
 		}
@@ -702,24 +931,30 @@
 
 			/* 
 			 *	update / create cache entry
-			 *	for the source adddress
+			 *	for the source address
 			 */
 
-			neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev);
-
-			if (neigh || !dev->hard_header) {
+			neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, !inc || lladdr || !skb->dev->addr_len);
+			if (neigh) {
+				/* XXX: !skb->dev->addr_len case? */
+				ndisc_update(neigh, lladdr, NEIGH_UPDATE_F_IP6NS);
 				ndisc_send_na(dev, neigh, saddr, &ifp->addr, 
-					      ifp->idev->cnf.forwarding, 1, 
-					      ipv6_addr_type(&ifp->addr)&IPV6_ADDR_ANYCAST ? 0 : 1, 
-					      1);
-				if (neigh)
-					neigh_release(neigh);
+					      ifp->idev->cnf.forwarding, 1, inc, inc);
+				neigh_release(neigh);
+			} else {
+#define IPV6READYLOGO
+#ifdef IPV6READYLOGO
+				no_neigh_send_na(dev, skb);
+#else
+				if (net_ratelimit())
+					ND_PRINTK3(KERN_DEBUG 
+						   "ICMP6 NS: Received Solicited NS but ignored.\n");
+#endif
 			}
 		}
 		in6_ifa_put(ifp);
 	} else if (ipv6_chk_acast_addr(dev, &msg->target)) {
 		struct inet6_dev *idev = in6_dev_get(dev);
-		int addr_type = ipv6_addr_type(saddr);
 
 		/* anycast */
 
@@ -747,45 +982,48 @@
 
 			/*
 			 *   update / create cache entry
-			 *   for the source adddress
+			 *   for the source address
 			 */
 
-			neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, skb->dev);
+			neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev,
+						!inc || lladdr || !skb->dev->addr_len);
 
-			if (neigh || !dev->hard_header) {
-				ndisc_send_na(dev, neigh, saddr,
-					&msg->target, 
-				        idev->cnf.forwarding, 1, 0, inc);
-				if (neigh)
-					neigh_release(neigh);
+			if (neigh) {
+				/* XXX: !skb->dev->addr_len case? */
+				ndisc_update(neigh, lladdr, NEIGH_UPDATE_F_IP6NS);
+				ndisc_send_na(dev, neigh, saddr, &msg->target,
+					      idev->cnf.forwarding, 1, 0, inc);
+				neigh_release(neigh);
+			} else if (net_ratelimit())
+				ND_PRINTK3(KERN_DEBUG 
+					   "ICMP6 NS: Received Solicited NS but ignored.\n");
 			}
-		}
 		in6_dev_put(idev);
 	} else {
 		struct inet6_dev *in6_dev = in6_dev_get(dev);
-		int addr_type = ipv6_addr_type(saddr);
 
 		if (in6_dev && in6_dev->cnf.forwarding &&
 		    (addr_type & IPV6_ADDR_UNICAST) &&
-		    pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
+			pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
 			int inc = ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST;
 
 			if (skb->stamp.tv_sec == 0 ||
 			    skb->pkt_type == PACKET_HOST ||
 			    inc == 0 ||
 			    in6_dev->nd_parms->proxy_delay == 0) {
+				struct neighbour *neigh;
 				if (inc)
 					NEIGH_CACHE_STAT_INC(&nd_tbl, 
 							rcv_probes_mcast);
 				else
-					NEIGH_CACHE_STAT_INC(&nd_tbl, 
-							rcv_probes_ucast);
-					
 				neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev);
 
 				if (neigh) {
+					/* XXX: !skb->dev->addr_len case? */
+					ndisc_update(neigh, lladdr, 
+						     NEIGH_UPDATE_F_IP6NS);
 					ndisc_send_na(dev, neigh, saddr, &msg->target,
-						      0, 1, 0, 1);
+						      0, 1, 0, inc);
 					neigh_release(neigh);
 				}
 			} else {
@@ -798,54 +1036,58 @@
 		}
 		if (in6_dev)
 			in6_dev_put(in6_dev);
+		
 	}
+bad:
 	return;
 }
 
-void ndisc_recv_na(struct sk_buff *skb)
+static void ndisc_recv_na(struct sk_buff *skb)
 {
-	struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
-	struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
-	struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
+	struct net_device *dev = skb->dev;
+	struct ipv6hdr *ip6 = skb->nh.ipv6h;
+	struct in6_addr *saddr = &ip6->saddr;
+	struct in6_addr *daddr = &ip6->daddr;
+	struct nd_msg *msg = (struct nd_msg *) skb->h.raw;
+	unsigned long ndoptlen = skb->len - sizeof(*msg);
 	u8 *lladdr = NULL;
 	int lladdrlen = 0;
-	u32 ndoptlen = skb->tail - msg->opt;
-	struct ndisc_options ndopts;
-	struct net_device *dev = skb->dev;
 	struct inet6_ifaddr *ifp;
 	struct neighbour *neigh;
+	struct ndisc_options ndopts;
 
-	if (skb->len < sizeof(struct nd_msg)) {
-		if (net_ratelimit())
-			printk(KERN_WARNING "ICMP NA: packet too short\n");
+	if (skb->len < sizeof(struct nd_msg))
 		return;
-	}
 
-	if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) {
-		if (net_ratelimit())
-			printk(KERN_WARNING "NDISC NA: target address is multicast\n");
-		return;
+	if (ipv6_addr_type(&msg->target) & IPV6_ADDR_MULTICAST) {
+		if (net_ratelimit()) {
+			char abuf[128];
+			in6_ntop(&msg->target, abuf);
+			ND_PRINTK2(KERN_WARNING 
+				   "ICMP6 NA: invalid target address %s\n", 
+				   abuf);
+		}
+		goto bad;
 	}
 
 	if ((ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST) &&
 	    msg->icmph.icmp6_solicited) {
-		ND_PRINTK0("NDISC: solicited NA is multicasted\n");
+		if (net_ratelimit())
+			ND_PRINTK2(KERN_WARNING 
+				   "ICMP6 NA: solicited NA is multicasted\n");
 		return;
 	}
-		
 	if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
 		if (net_ratelimit())
-			printk(KERN_WARNING "ICMP NS: invalid ND option, ignored.\n");
-		return;
+			ND_PRINTK2(KERN_WARNING 
+				   "ICMP6 NA: invalid ND option, ignored\n");
+		goto bad;
 	}
 	if (ndopts.nd_opts_tgt_lladdr) {
 		lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1);
 		lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
-		if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len)) {
-			if (net_ratelimit())
-				printk(KERN_WARNING "NDISC NA: invalid lladdr length.\n");
-			return;
-		}
+		if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len))
+			goto bad;
 	}
 	if ((ifp = ipv6_get_ifaddr(&msg->target, dev))) {
 		if (ifp->flags & IFA_F_TENTATIVE) {
@@ -856,63 +1098,145 @@
 		   is invalid, but ndisc specs say nothing
 		   about it. It could be misconfiguration, or
 		   an smart proxy agent tries to help us :-)
-		 */
-		ND_PRINTK0("%s: someone advertises our address!\n",
+		*/
+		if (net_ratelimit())
+			ND_PRINTK1(KERN_WARNING 
+				   "ICMP6 NA: someone advertise our address on %s!\n",
 			   ifp->idev->dev->name);
 		in6_ifa_put(ifp);
 		return;
 	}
-	neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
+	neigh = neigh_lookup(&nd_tbl, &msg->target, skb->dev);
 
 	if (neigh) {
-		if (neigh->flags & NTF_ROUTER) {
-			if (msg->icmph.icmp6_router == 0) {
-				/*
-				 *	Change: router to host
-				 */
-				struct rt6_info *rt;
-				rt = rt6_get_dflt_router(saddr, dev);
-				if (rt) {
-					/* It is safe only because
-					   we aer in BH */
-					dst_release(&rt->u.dst);
-					ip6_del_rt(rt, NULL);
-				}
+		int notify = 0;
+		int was_router = 0;
+
+		write_lock_bh(&neigh->lock);
+		if (!(neigh->nud_state&~NUD_FAILED))
+			goto ignore;
+
+		was_router = neigh->flags&NTF_ROUTER;
+
+		notify = __neigh_update(neigh, lladdr,
+					msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
+					(NEIGH_UPDATE_F_IP6NA|
+					 (msg->icmph.icmp6_override ? NEIGH_UPDATE_F_OVERRIDE : 0) |
+					 (msg->icmph.icmp6_router   ? NEIGH_UPDATE_F_ISROUTER : 0)));
+
+		if (was_router && !(neigh->flags&NTF_ROUTER)) {
+			/* XXX: race, ok? */
+			/*
+			 *	Change: router to host
+			 */
+			struct rt6_info *rt;
+			rt = rt6_get_dflt_router(saddr, skb->dev);
+			if (rt) {
+				/* It is safe only because
+				   we are in BH */
+				dst_release(&rt->u.dst);
+				ip6_del_rt(rt, NULL);
 			}
-		} else {
-			if (msg->icmph.icmp6_router)
-				neigh->flags |= NTF_ROUTER;
 		}
+ignore:
+#ifdef CONFIG_ARPD
+		if (notify > 0 && neigh->parms->app_probes) {
+			write_unlock_bh(&neigh->lock);
+			neigh_app_notify(neigh);
+		} else
+#endif
+		write_unlock_bh(&neigh->lock);
+		neigh_release(neigh);
+	}
+bad:
+	return;
+}
+
+static void ndisc_recv_rs(struct sk_buff *skb)
+{
+	struct rs_msg *rs_msg = (struct rs_msg *) skb->h.raw;
+	unsigned long ndoptlen = skb->len - sizeof(*rs_msg);
+	struct neighbour *neigh;
+	struct inet6_dev *idev;
+	struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
+	struct ndisc_options ndopts;
+	u8 *lladdr = NULL;
+	int lladdrlen = 0;
 
-		neigh_update(neigh, lladdr,
-			     msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
-			     msg->icmph.icmp6_override, 1);
+	ND_PRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__);
+
+	if (skb->len < sizeof(*rs_msg))
+		return;
+
+	idev = in6_dev_get(skb->dev);
+	if (!idev) {
+		ND_PRINTK1(KERN_WARNING 
+			   "%s: can't find in6 device\n",
+			   __FUNCTION__);
+		return;
+	}
+
+	/* Ignore if I'm not a router */
+	if (!idev->cnf.forwarding || idev->cnf.accept_ra)
+		goto out;
+
+	/* sanity check */
+	if (!ndisc_parse_options(rs_msg->opt, ndoptlen, &ndopts)) {
+		if (net_ratelimit())
+			ND_PRINTK2(KERN_WARNING 
+				   "ICMP6 NS: invalid ND option, ignored\n");
+		goto out;
+	}
+
+	/* Don't update NCE if src = :: */
+	if (ipv6_addr_any(saddr)) {
+		/*
+		 * this is ok but ignore because this indicates that
+		 * source has no ip address assigned yet.
+		 */
+		goto out;
+	}
+
+	if (ndopts.nd_opts_src_lladdr) {
+		lladdr = (u8 *)(ndopts.nd_opts_src_lladdr + 1);
+		lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
+		if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len))
+			goto out;
+	}
+
+	neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, 1);
+	if (neigh) {
+		ndisc_update(neigh, lladdr, NEIGH_UPDATE_F_IP6RS);
 		neigh_release(neigh);
 	}
+out:
+	in6_dev_put(idev);
 }
 
-static void ndisc_router_discovery(struct sk_buff *skb)
+static void ndisc_recv_ra(struct sk_buff *skb)
 {
         struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;
+	unsigned long ndoptlen = skb->len - sizeof(*ra_msg);
 	struct neighbour *neigh;
 	struct inet6_dev *in6_dev;
-	struct rt6_info *rt;
+	struct rt6_info *rt = NULL;
 	int lifetime;
+	struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
 	struct ndisc_options ndopts;
-	int optlen;
+	int pref = 0;
 
-	__u8 * opt = (__u8 *)(ra_msg + 1);
+	ND_PRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__);
 
-	optlen = (skb->tail - skb->h.raw) - sizeof(struct ra_msg);
-
-	if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
-		if (net_ratelimit())
-			printk(KERN_WARNING "ICMP RA: source address is not linklocal\n");
+	if (skb->len < sizeof(*ra_msg))
 		return;
-	}
-	if (optlen < 0) {
-		if (net_ratelimit())
-			printk(KERN_WARNING "ICMP RA: packet too short\n");
+
+	if ((ipv6_addr_type(saddr)&(IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) != (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) {
+		if (net_ratelimit()) {
+			char abuf[128];
+			in6_ntop(saddr, abuf);
+			ND_PRINTK2(KERN_WARNING 
+				   "ICMP6 RA: src %s is not link-local\n", abuf);
+		}
 		return;
 	}
 
@@ -922,20 +1246,19 @@
 
 	in6_dev = in6_dev_get(skb->dev);
 	if (in6_dev == NULL) {
-		ND_PRINTK1("RA: can't find in6 device\n");
-		return;
-	}
-	if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
-		in6_dev_put(in6_dev);
+		ND_PRINTK1(KERN_WARNING 
+			   "ICMP6 RA: can't find in6 device\n");
 		return;
 	}
 
-	if (!ndisc_parse_options(opt, optlen, &ndopts)) {
-		in6_dev_put(in6_dev);
+	if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra)
+		goto out;
+
+	if (!ndisc_parse_options(ra_msg->opt, ndoptlen, &ndopts)) {
 		if (net_ratelimit())
-			ND_PRINTK2(KERN_WARNING
-				   "ICMP6 RA: invalid ND option, ignored.\n");
-		return;
+			ND_PRINTK2(KERN_WARNING 
+				   "ICMP6 RA: invalid ND option, ignored\n");
+		goto out;
 	}
 
 	if (in6_dev->if_flags & IF_RS_SENT) {
@@ -958,8 +1281,20 @@
 					IF_RA_OTHERCONF : 0);
 
 	lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
+	ND_PRINTK3(KERN_DEBUG
+		   "ICMP6 RA: router lifetime %u\n", lifetime);
 
-	rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
+#ifdef CONFIG_IPV6_ROUTER_PREF
+	pref = IPV6_SIGNEDPREF(ra_msg->icmph.icmp6_router_pref);
+	if (pref < -1) {
+		if (net_ratelimit())
+			ND_PRINTK2(KERN_WARNING
+				   "ICMP6 RA: invalid RA preference; zero lifetime\n");
+		lifetime = 0;
+	}
+#endif
+	
+	rt = rt6_get_dflt_router(saddr, skb->dev);
 
 	if (rt && lifetime == 0) {
 		ip6_del_rt(rt, NULL);
@@ -967,18 +1302,24 @@
 	}
 
 	if (rt == NULL && lifetime) {
-		ND_PRINTK2("ndisc_rdisc: adding default router\n");
+		ND_PRINTK2(KERN_DEBUG
+			   "ndisc_rdisc: adding default router; lifetime=%u\n", 
+			   lifetime);
 
-		rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
+		rt = rt6_add_dflt_router(saddr, skb->dev, pref);
 		if (rt == NULL) {
-			ND_PRINTK1("route_add failed\n");
+			ND_PRINTK1(KERN_WARNING 
+				   "%s(): route_add failed\n",
+				   __FUNCTION__);
 			in6_dev_put(in6_dev);
 			return;
 		}
 
 		neigh = rt->rt6i_nexthop;
 		if (neigh == NULL) {
-			ND_PRINTK1("nd: add default router: null neighbour\n");
+			ND_PRINTK1(KERN_WARNING 
+				   "%s(): add default router: null neighbour\n",
+				   __FUNCTION__);
 			dst_release(&rt->u.dst);
 			in6_dev_put(in6_dev);
 			return;
@@ -993,8 +1334,12 @@
 		rt6_purge_dflt_routers(RTF_ALLONLINK);
 	}
 
-	if (rt)
+	if (rt) {
 		rt->rt6i_expires = jiffies + (HZ * lifetime);
+#ifdef CONFIG_IPV6_ROUTER_PREF
+		 rt->rt6i_flags = (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
+#endif
+	}
 
 	if (ra_msg->icmph.icmp6_hop_limit)
 		in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
@@ -1022,7 +1367,6 @@
 
 			if (rtime != in6_dev->nd_parms->base_reachable_time) {
 				in6_dev->nd_parms->base_reachable_time = rtime;
-				in6_dev->nd_parms->gc_staletime = 3 * rtime;
 				in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);
 			}
 		}
@@ -1032,60 +1376,57 @@
 	 *	Process options.
 	 */
 
-	if (rt && (neigh = rt->rt6i_nexthop) != NULL) {
-		u8 *lladdr = NULL;
-		int lladdrlen;
-		if (ndopts.nd_opts_src_lladdr) {
-			lladdr = (u8*)((ndopts.nd_opts_src_lladdr)+1);
-			lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
-			if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
-				if (net_ratelimit())
-					ND_PRINTK2(KERN_WARNING
-						   "ICMP6 RA: Invalid lladdr length.\n");
-				goto out;
-			}
+#if defined(CONFIG_IPV6_ROUTE_INFO)
+	if (ndopts.nd_opts_ri) {
+		struct nd_opt_hdr *p;
+		for (p = ndopts.nd_opts_ri;
+		     p;
+		     p = ndisc_next_option(p, ndopts.nd_opts_ri_end)) {
+			rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3, saddr);
 		}
-		neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
 	}
-
+#endif
 	if (ndopts.nd_opts_pi) {
 		struct nd_opt_hdr *p;
-		for (p = ndopts.nd_opts_pi;
+		for (p = ndopts.nd_opts_pi; 
 		     p;
 		     p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
 			addrconf_prefix_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3);
 		}
 	}
-
 	if (ndopts.nd_opts_mtu) {
 		u32 mtu;
-
 		memcpy(&mtu, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
 		mtu = ntohl(mtu);
-
 		if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
-			if (net_ratelimit()) {
-				ND_PRINTK0("NDISC: router announcement with mtu = %d\n",
+			if (net_ratelimit())
+				ND_PRINTK2(KERN_DEBUG 
+					   "ICMP6 RA: router advertisement with invalid mtu = %d\n", 
 					   mtu);
-			}
-		}
-
-		if (in6_dev->cnf.mtu6 != mtu) {
+		} else if (in6_dev->cnf.mtu6 != mtu) {
 			in6_dev->cnf.mtu6 = mtu;
-
 			if (rt)
 				rt->u.dst.pmtu = mtu;
-
 			rt6_mtu_change(skb->dev, mtu);
 		}
 	}
-			
+	if (rt && (neigh = rt->rt6i_nexthop) != NULL) {
+		u8 *lladdr = NULL;
+		int lladdrlen;
+		if (ndopts.nd_opts_src_lladdr) {
+			lladdr = (u8*)((ndopts.nd_opts_src_lladdr)+1);
+			lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
+			if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len))
+				goto out;
+		}
+		ndisc_update(neigh, lladdr, NEIGH_UPDATE_F_IP6RA);
+	}
 	if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
 		if (net_ratelimit())
-			ND_PRINTK0(KERN_WARNING
+			ND_PRINTK2(KERN_WARNING 
 				   "ICMP6 RA: got illegal option with RA");
 	}
-out:
+  out:
 	if (rt)
 		dst_release(&rt->u.dst);
 	in6_dev_put(in6_dev);
@@ -1094,38 +1435,36 @@
 static void ndisc_redirect_rcv(struct sk_buff *skb)
 {
 	struct inet6_dev *in6_dev;
-	struct icmp6hdr *icmph;
+	struct rd_msg *rdmsg;
+	unsigned long ndoptlen = skb->len - sizeof(*rdmsg);
+	u8 *lladdr = NULL;
+	int lladdrlen = 0;
+	struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
 	struct in6_addr *dest;
 	struct in6_addr *target;	/* new first hop to destination */
 	struct neighbour *neigh;
+	struct rt6_info *rt6;
 	int on_link = 0;
 	struct ndisc_options ndopts;
-	int optlen;
-	u8 *lladdr = NULL;
-	int lladdrlen;
 
-	if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
-		if (net_ratelimit())
-			printk(KERN_WARNING "ICMP redirect: source address is not linklocal\n");
+	if (skb->len < sizeof(struct rd_msg))
 		return;
-	}
 
-	optlen = skb->tail - skb->h.raw;
-	optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
-
-	if (optlen < 0) {
+	if (!(ipv6_addr_type(saddr) & IPV6_ADDR_LINKLOCAL)) {
 		if (net_ratelimit())
-			printk(KERN_WARNING "ICMP redirect: packet too small\n");
+			ND_PRINTK2(KERN_WARNING 
+				   "ICMP6 Redirect: source address is not linklocal\n");
 		return;
 	}
 
-	icmph = (struct icmp6hdr *) skb->h.raw;
-	target = (struct in6_addr *) (icmph + 1);
-	dest = target + 1;
+	rdmsg = (struct rd_msg *) skb->h.raw;
+	target = &rdmsg->rd_target;
+	dest = &rdmsg->rd_dst;
 
 	if (ipv6_addr_type(dest) & IPV6_ADDR_MULTICAST) {
 		if (net_ratelimit())
-			printk(KERN_WARNING "ICMP redirect for multicast addr\n");
+			ND_PRINTK2(KERN_WARNING 
+				   "ICMP6 Redirect: redirect for multicast addr\n");
 		return;
 	}
 
@@ -1133,9 +1472,40 @@
 		on_link = 1;
 	} else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) {
 		if (net_ratelimit())
-			printk(KERN_WARNING "ICMP redirect: target address is not linklocal\n");
+			ND_PRINTK2(KERN_WARNING 
+				   "ICMP6 Redirect: target address is not linklocal\n");
+		return;
+	}
+
+#ifndef CONFIG_IPV6_NDISC_NEW
+	rt6 = rt6_lookup(dest, NULL, skb->dev->ifindex, RT6_LOOKUP_FLAG_STRICT|RT6_LOOKUP_FLAG_NOUSE);
+	if (!rt6) {
+		char sbuf[128], dbuf[128], tbuf[128];
+		in6_ntop(saddr, sbuf);
+		in6_ntop(dest, dbuf);
+		in6_ntop(target, tbuf);
+		if (net_ratelimit())
+			ND_PRINTK2(KERN_WARNING 
+				   "ICMP6 Redirect: no route found for redirect dst:"
+				   "src=%s, dst=%s, tgt=%s\n",
+				   sbuf, dbuf, tbuf);
+		return;
+	} else if (ipv6_addr_cmp(saddr, &rt6->rt6i_gateway) != 0) {
+		char sbuf[128], dbuf[128], tbuf[128], gbuf[128];
+		in6_ntop(saddr, sbuf);
+		in6_ntop(dest, dbuf);
+		in6_ntop(target, tbuf);
+		in6_ntop(&rt6->rt6i_gateway, gbuf);
+		if (net_ratelimit())
+			ND_PRINTK2(KERN_WARNING 
+				   "ICMP6 Redirect: not equal to gw-for-src=%s (must be same): "
+				   "src=%s, dst=%s, tgt=%s\n",
+				   gbuf, sbuf, dbuf, tbuf);
+		dst_release(&rt6->u.dst);
 		return;
 	}
+	dst_release(&rt6->u.dst);
+#endif
 
 	in6_dev = in6_dev_get(skb->dev);
 	if (!in6_dev)
@@ -1150,25 +1520,26 @@
 	 *	first-hop router for the specified ICMP Destination Address.
 	 */
 		
-	if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) {
+	/* passed validation tests */
+
+	if (!ndisc_parse_options(rdmsg->opt, ndoptlen, &ndopts)) {
+		char sbuf[128], dbuf[128], tbuf[128];
+		in6_ntop(saddr, sbuf);
+		in6_ntop(dest, dbuf);
+		in6_ntop(target, tbuf);
 		if (net_ratelimit())
 			ND_PRINTK2(KERN_WARNING
-				   "ICMP6 Redirect: invalid ND options, rejected.\n");
-		in6_dev_put(in6_dev);
-		return;
+				   "ICMP6 Redirect: invalid ND options, rejected: "
+				   "src=%s, dst=%s, tgt=%s\n",
+				   sbuf, dbuf, tbuf);
+		goto out;
 	}
 	if (ndopts.nd_opts_tgt_lladdr) {
 		lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1);
 		lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
-		if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
-			if (net_ratelimit())
-				ND_PRINTK2(KERN_WARNING
-					   "ICMP6 Redirect: invalid lladdr length.\n");
-			in6_dev_put(in6_dev);
-			return;
-		}
+		if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len))
+			goto out;
 	}
-	/* passed validation tests */
 
 	/*
 	   We install redirect only if nexthop state is valid.
@@ -1176,13 +1547,34 @@
 
 	neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
 	if (neigh) {
-		neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
-		if (neigh->nud_state&NUD_VALID)
-			rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, on_link);
-		else
+#ifndef CONFIG_IPV6_NDISC_NEW
+		int notify;
+		write_lock_bh(&neigh->lock);
+		notify = __neigh_update(neigh, lladdr, NUD_STALE, 
+					NEIGH_UPDATE_F_IP6REDIRECT|
+					(on_link ? 0 : (NEIGH_UPDATE_F_OVERRIDE_VALID_ISROUTER|
+							NEIGH_UPDATE_F_ISROUTER)));
+#ifdef CONFIG_ARPD
+		if (notify > 0 && !neigh->parms->app_probes)
+			notify = 0;
+#endif
+		if (neigh->nud_state&NUD_VALID) {
+			write_unlock_bh(&neigh->lock);
+			rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, NULL, on_link);
+		} else {
 			__neigh_event_send(neigh, NULL);
+			write_unlock_bh(&neigh->lock);
+		}
+#ifdef CONFIG_ARPD
+		if (notify > 0)
+			neigh_app_notify(neigh);
+#endif
+#else
+		rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, lladdr, on_link);
+#endif
 		neigh_release(neigh);
 	}
+out:
 	in6_dev_put(in6_dev);
 }
 
@@ -1190,26 +1582,29 @@
 			 struct in6_addr *target)
 {
 	struct sock *sk = ndisc_socket->sk;
-	int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
+	int len = sizeof(struct rd_msg);
 	struct sk_buff *buff;
-	struct icmp6hdr *icmph;
+	struct rd_msg *rdmsg;
 	struct in6_addr saddr_buf;
-	struct in6_addr *addrp;
 	struct net_device *dev;
+	struct inet6_dev *idev;
 	struct rt6_info *rt;
 	u8 *opt;
 	int rd_len;
 	int err;
 	int hlen;
+	u8 ha[MAX_ADDR_LEN];
 
 	dev = skb->dev;
-	rt = rt6_lookup(&skb->nh.ipv6h->saddr, NULL, dev->ifindex, 1);
+	rt = rt6_lookup(&skb->nh.ipv6h->saddr, NULL, dev->ifindex, RT6_LOOKUP_FLAG_STRICT);
 
 	if (rt == NULL)
 		return;
 
 	if (rt->rt6i_flags & RTF_GATEWAY) {
-		ND_PRINTK1("ndisc_send_redirect: not a neighbour\n");
+		if (net_ratelimit())
+			ND_PRINTK2(KERN_WARNING 
+				   "redirect: not a neighbour\n");
 		dst_release(&rt->u.dst);
 		return;
 	}
@@ -1220,9 +1615,13 @@
 	dst_release(&rt->u.dst);
 
 	if (dev->addr_len) {
+		read_lock_bh(&neigh->lock);
 		if (neigh->nud_state&NUD_VALID) {
 			len  += NDISC_OPT_SPACE(dev->addr_len);
+			memcpy(ha, neigh->ha, dev->addr_len);
+			read_unlock_bh(&neigh->lock);
 		} else {
+			read_unlock_bh(&neigh->lock);
 			/* If nexthop is not valid, do not redirect!
 			   We will make it later, when will be sure,
 			   that it is alive.
@@ -1237,14 +1636,18 @@
 	len += rd_len;
 
 	if (ipv6_get_lladdr(dev, &saddr_buf)) {
- 		ND_PRINTK1("redirect: no link_local addr for dev\n");
+ 		if (net_ratelimit())
+			ND_PRINTK2(KERN_WARNING 
+				   "redirect: no link_local addr for dev\n");
  		return;
  	}
 
 	buff = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
 				   1, &err);
 	if (buff == NULL) {
-		ND_PRINTK1("ndisc_send_redirect: alloc_skb failed\n");
+		if (net_ratelimit())
+			ND_PRINTK1(KERN_WARNING 
+				   "redirect: alloc_skb failed\n");
 		return;
 	}
 
@@ -1258,28 +1661,26 @@
 	ip6_nd_hdr(sk, buff, dev, &saddr_buf, &skb->nh.ipv6h->saddr,
 		   IPPROTO_ICMPV6, len);
 
-	icmph = (struct icmp6hdr *) skb_put(buff, len);
+	rdmsg = (struct rd_msg *) skb_put(buff, len);
 
-	memset(icmph, 0, sizeof(struct icmp6hdr));
-	icmph->icmp6_type = NDISC_REDIRECT;
+	memset(rdmsg, 0, sizeof(struct rd_msg));
+	rdmsg->icmph.icmp6_type = NDISC_REDIRECT;
 
 	/*
 	 *	copy target and destination addresses
 	 */
 
-	addrp = (struct in6_addr *)(icmph + 1);
-	ipv6_addr_copy(addrp, target);
-	addrp++;
-	ipv6_addr_copy(addrp, &skb->nh.ipv6h->daddr);
+	ipv6_addr_copy(&rdmsg->rd_target, target);
+	ipv6_addr_copy(&rdmsg->rd_dst, &skb->nh.ipv6h->daddr);
 
-	opt = (u8*) (addrp + 1);
+	opt = rdmsg->opt;
 
 	/*
 	 *	include target_address option
 	 */
 
 	if (dev->addr_len)
-		opt = ndisc_fill_option(opt, ND_OPT_TARGET_LL_ADDR, neigh->ha, dev->addr_len);
+		opt = ndisc_fill_option(opt, ND_OPT_TARGET_LL_ADDR, ha, dev->addr_len);
 
 	/*
 	 *	build redirect option and copy skb over to the new packet.
@@ -1292,14 +1693,18 @@
 
 	memcpy(opt, skb->nh.ipv6h, rd_len - 8);
 
-	icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &skb->nh.ipv6h->saddr,
-					     len, IPPROTO_ICMPV6,
-					     csum_partial((u8 *) icmph, len, 0));
+	rdmsg->icmph.icmp6_cksum = csum_ipv6_magic(&saddr_buf, 
+					&skb->nh.ipv6h->saddr,
+					len, IPPROTO_ICMPV6,
+					csum_partial((u8 *) rdmsg, len, 0));
 
 	dev_queue_xmit(buff);
 
-	ICMP6_INC_STATS(Icmp6OutRedirects);
-	ICMP6_INC_STATS(Icmp6OutMsgs);
+	idev = in6_dev_get(dev);
+	ICMP6_INC_STATS(idev,Icmp6OutRedirects);
+	ICMP6_INC_STATS(idev,Icmp6OutMsgs);
+	if (idev)
+		in6_dev_put(idev);
 }
 
 static void pndisc_redo(struct sk_buff *skb)
@@ -1316,18 +1721,19 @@
 
 	if (skb->nh.ipv6h->hop_limit != 255) {
 		if (net_ratelimit())
-			printk(KERN_WARNING
-			       "ICMP NDISC: fake message with non-255 Hop Limit received: %d\n",
-			       		skb->nh.ipv6h->hop_limit);
+			ND_PRINTK2(KERN_WARNING
+				   "ICMP6 NDISC: fake message with non-255 Hop Limit received: %d\n",
+				   skb->nh.ipv6h->hop_limit);
 		return 0;
 	}
 
 	if (msg->icmph.icmp6_code != 0) {
 		if (net_ratelimit())
-			printk(KERN_WARNING "ICMP NDISC: code is not zero\n");
+			ND_PRINTK2(KERN_WARNING
+				   "ICMP6 NDISC: code is not zero\n");
 		return 0;
 	}
-
+	
 	switch (msg->icmph.icmp6_type) {
 	case NDISC_NEIGHBOUR_SOLICITATION:
 		ndisc_recv_ns(skb);
@@ -1338,7 +1744,11 @@
 		break;
 
 	case NDISC_ROUTER_ADVERTISEMENT:
-		ndisc_router_discovery(skb);
+		ndisc_recv_ra(skb);
+		break;
+
+	case NDISC_ROUTER_SOLICITATION:
+		ndisc_recv_rs(skb);
 		break;
 
 	case NDISC_REDIRECT:
@@ -1349,6 +1759,81 @@
 	return 0;
 }
 
+#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_IPV6_NDISC_DEBUG
+static int ndisc_get_info(char *buffer, char **start, off_t offset, int length)
+{
+	int len=0;
+	off_t pos=0;
+	int size;
+	unsigned long now = jiffies;
+	int i;
+
+	for (i = 0; i <= NEIGH_HASHMASK; i++) {
+		struct neighbour *neigh;
+
+		read_lock_bh(&nd_tbl.lock);
+		for (neigh = nd_tbl.hash_buckets[i]; neigh; neigh = neigh->next) {
+			int j;
+
+			size = 0;
+			for (j=0; j<16; j++) {
+				sprintf(buffer+len+size, "%02x", neigh->primary_key[j]);
+				size += 2;
+			}
+
+			read_lock(&neigh->lock);
+			size += sprintf(buffer+len+size,
+				       " %02x %02x %02x %02x %08lx %08lx %08x %04x %04x %04x %8s ", i,
+				       128,
+				       neigh->type,
+				       neigh->nud_state,
+				       now - neigh->used,
+				       now - neigh->confirmed,
+				       neigh->parms->reachable_time,
+				       neigh->parms->gc_staletime,
+				       atomic_read(&neigh->refcnt) - 1,
+				       neigh->flags | (!neigh->hh ? 0 : (neigh->hh->hh_output==dev_queue_xmit ? 4 : 2)),
+				       neigh->dev->name);
+
+			if ((neigh->nud_state&NUD_VALID) && neigh->dev->addr_len) {
+				for (j=0; j < neigh->dev->addr_len; j++) {
+					sprintf(buffer+len+size, "%02x", neigh->ha[j]);
+					size += 2;
+				}
+			} else {
+                                size += sprintf(buffer+len+size, "000000000000");
+			}
+			read_unlock(&neigh->lock);
+			size += sprintf(buffer+len+size, "\n");
+			len += size;
+			pos += size;
+		  
+			if (pos <= offset)
+				len=0;
+			if (pos >= offset+length) {
+				read_unlock_bh(&nd_tbl.lock);
+				goto done;
+			}
+		}
+		read_unlock_bh(&nd_tbl.lock);
+	}
+
+done:
+
+	*start = buffer+len-(pos-offset);	/* Start of wanted data */
+	len = pos-offset;			/* Start slop */
+	if (len>length)
+		len = length;			/* Ending slop */
+	if (len<0)
+		len = 0;
+	return len;
+}
+
+#endif
+#endif	/* CONFIG_PROC_FS */
+
+
 static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
 	struct net_device *dev = ptr;
@@ -1376,8 +1861,8 @@
 
 	ndisc_socket = sock_alloc();
 	if (ndisc_socket == NULL) {
-		printk(KERN_ERR
-		       "Failed to create the NDISC control socket.\n");
+		ND_PRINTK1(KERN_ERR
+			   "ndisc_init(): Failed to create the NDISC control socket.\n");
 		return -1;
 	}
 	ndisc_socket->inode->i_uid = 0;
@@ -1385,9 +1870,9 @@
 	ndisc_socket->type = SOCK_RAW;
 
 	if((err = ops->create(ndisc_socket, IPPROTO_ICMPV6)) < 0) {
-		printk(KERN_DEBUG 
-		       "Failed to initialize the NDISC control socket (err %d).\n",
-		       err);
+		ND_PRINTK1(KERN_ERR
+			   "ndisc_init(): Failed to initialize the NDISC control socket (err %d).\n",
+			   err);
 		sock_release(ndisc_socket);
 		ndisc_socket = NULL; /* For safety. */
 		return err;
@@ -1406,6 +1891,11 @@
 	
 	neigh_table_init(&nd_tbl);
 
+#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_IPV6_NDISC_DEBUG
+	proc_net_create("ndisc", 0, ndisc_get_info);
+#endif
+#endif
 #ifdef CONFIG_SYSCTL
 	neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH, "ipv6");
 #endif
@@ -1416,6 +1906,11 @@
 
 void ndisc_cleanup(void)
 {
+#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_IPV6_NDISC_DEBUG
+        proc_net_remove("ndisc");
+#endif
+#endif
 	neigh_table_clear(&nd_tbl);
 	sock_release(ndisc_socket);
 	ndisc_socket = NULL; /* For safety. */
diff -urN linux-2.4.29/net/ipv6/netfilter/Config.in linux-2.4.29-uc1/net/ipv6/netfilter/Config.in
--- linux-2.4.29/net/ipv6/netfilter/Config.in	2003-06-13 15:51:39.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv6/netfilter/Config.in	2005-06-14 02:11:52.000000000 +0100
@@ -59,6 +59,9 @@
   if [ "$CONFIG_IP6_NF_FILTER" != "n" ]; then
     dep_tristate '    LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_FILTER
   fi
+  if [ "$CONFIG_IP6_NF_FILTER" != "n" ]; then
+    dep_tristate '    REJECT target support' CONFIG_IP6_NF_TARGET_REJECT $CONFIG_IP6_NF_FILTER
+  fi
 
 #  if [ "$CONFIG_IP6_NF_FILTER" != "n" ]; then
 #    dep_tristate '    REJECT target support' CONFIG_IP6_NF_TARGET_REJECT $CONFIG_IP6_NF_FILTER
@@ -71,6 +74,7 @@
   if [ "$CONFIG_IP6_NF_MANGLE" != "n" ]; then
 #    dep_tristate '    TOS target support' CONFIG_IP6_NF_TARGET_TOS $CONFIG_IP_NF_MANGLE
     dep_tristate '    MARK target support' CONFIG_IP6_NF_TARGET_MARK $CONFIG_IP6_NF_MANGLE
+    dep_tristate '    IMQ target support' CONFIG_IP6_NF_TARGET_IMQ $CONFIG_IP6_NF_MANGLE
   fi
   #dep_tristate '  LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
 fi
diff -urN linux-2.4.29/net/ipv6/netfilter/ip6t_agr.c linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_agr.c
--- linux-2.4.29/net/ipv6/netfilter/ip6t_agr.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_agr.c	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,91 @@
+/* Kernel module to match AGR address parameters. */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ipv6.h>
+#include <linux/if_ether.h>
+
+#include <linux/netfilter_ipv6/ip6_tables.h>
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset,
+      const void *hdr,
+      u_int16_t datalen,
+      int *hotdrop)
+{
+
+    unsigned char aggregated[8];
+    int i=0;
+
+    /*TODO size and pointer checking */
+    if ( !(skb->mac.raw >= skb->head
+               && (skb->mac.raw + ETH_HLEN) <= skb->data)
+               && offset != 0) {
+                       *hotdrop = 1;
+                       return 0;
+               }
+ 
+    memset(aggregated, 0, sizeof(aggregated));
+
+    if (skb->mac.ethernet->h_proto == ntohs(ETH_P_IPV6)) {
+      if (skb->nh.ipv6h->version == 0x6) { 
+         memcpy(aggregated, skb->mac.ethernet->h_source, 3);
+         memcpy(aggregated + 5, skb->mac.ethernet->h_source + 3, 3);
+	 aggregated[3]=0xff;
+	 aggregated[4]=0xfe;
+	 aggregated[0] |= 0x02;
+
+	 i=0;
+	 while ((skb->nh.ipv6h->saddr.in6_u.u6_addr8[8+i] ==
+			 aggregated[i]) && (i<8)) i++;
+
+	 if ( i == 8 )
+	 	return 1;
+      }
+    }
+
+    return 0;
+
+/*    return (skb->mac.raw >= skb->head
+  	    && skb->mac.raw < skb->head + skb->len - ETH_HLEN */
+
+    
+}
+
+static int
+ipt_agr_checkentry(const char *tablename,
+		   const struct ip6t_ip6 *ip,
+		   void *matchinfo,
+		   unsigned int matchsize,
+		   unsigned int hook_mask)
+{
+	if (hook_mask
+	    & ~((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN))) {
+		printk("ipt_agr: only valid for PRE_ROUTING or LOCAL_IN.\n");
+		return 0;
+	}
+
+	if (matchsize != IP6T_ALIGN(sizeof(int)))
+		return 0;
+
+	return 1;
+}
+
+static struct ip6t_match agr_match
+= { { NULL, NULL }, "agr", &match, &ipt_agr_checkentry, NULL, THIS_MODULE };
+
+static int __init init(void)
+{
+	return ip6t_register_match(&agr_match);
+}
+
+static void __exit fini(void)
+{
+	ip6t_unregister_match(&agr_match);
+}
+
+module_init(init);
+module_exit(fini);
diff -urN linux-2.4.29/net/ipv6/netfilter/ip6t_ah.c linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_ah.c
--- linux-2.4.29/net/ipv6/netfilter/ip6t_ah.c	2003-08-25 12:44:44.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_ah.c	2005-06-14 02:11:52.000000000 +0100
@@ -69,7 +69,7 @@
        len = skb->len - ptr;
        temp = 0;
 
-        while (ip6t_ext_hdr(nexthdr)) {
+        while (ipv6_ext_hdr(nexthdr)) {
                struct ipv6_opt_hdr *hdr;
 
               DEBUGP("ipv6_ah header iteration \n");
@@ -86,7 +86,7 @@
                      break;
               }
 
-              hdr=(struct ipv6_opt_hdr *)skb->data+ptr;
+              hdr=skb->data+ptr;
 
               /* Calculate the header length */
                 if (nexthdr == NEXTHDR_FRAGMENT) {
diff -urN linux-2.4.29/net/ipv6/netfilter/ip6t_dst.c linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_dst.c
--- linux-2.4.29/net/ipv6/netfilter/ip6t_dst.c	2005-01-19 14:10:14.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_dst.c	2005-06-14 02:11:52.000000000 +0100
@@ -73,7 +73,7 @@
        len = skb->len - ptr;
        temp = 0;
 
-        while (ip6t_ext_hdr(nexthdr)) {
+        while (ipv6_ext_hdr(nexthdr)) {
                struct ipv6_opt_hdr *hdr;
 
               DEBUGP("ipv6_opts header iteration \n");
diff -urN linux-2.4.29/net/ipv6/netfilter/ip6t_esp.c linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_esp.c
--- linux-2.4.29/net/ipv6/netfilter/ip6t_esp.c	2005-01-19 14:10:14.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_esp.c	2005-06-14 02:11:52.000000000 +0100
@@ -65,7 +65,7 @@
 	len = skb->len - ptr;
 	temp = 0;
 
-        while (ip6t_ext_hdr(nexthdr)) {
+        while (ipv6_ext_hdr(nexthdr)) {
         	struct ipv6_opt_hdr *hdr;
         	int hdrlen;
 
@@ -84,7 +84,7 @@
 			break;
 		}
 
-		hdr=(struct ipv6_opt_hdr *)skb->data+ptr;
+		hdr=skb->data+ptr;
 
 		/* Calculate the header length */
                 if (nexthdr == NEXTHDR_FRAGMENT) {
diff -urN linux-2.4.29/net/ipv6/netfilter/ip6t_frag.c linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_frag.c
--- linux-2.4.29/net/ipv6/netfilter/ip6t_frag.c	2005-01-19 14:10:14.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_frag.c	2005-06-14 02:11:52.000000000 +0100
@@ -60,7 +60,7 @@
        len = skb->len - ptr;
        temp = 0;
 
-        while (ip6t_ext_hdr(nexthdr)) {
+        while (ipv6_ext_hdr(nexthdr)) {
                struct ipv6_opt_hdr *hdr;
 
               DEBUGP("ipv6_frag header iteration \n");
diff -urN linux-2.4.29/net/ipv6/netfilter/ip6t_hbh.c linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_hbh.c
--- linux-2.4.29/net/ipv6/netfilter/ip6t_hbh.c	2005-01-19 14:10:14.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_hbh.c	2005-06-14 02:11:52.000000000 +0100
@@ -73,7 +73,7 @@
        len = skb->len - ptr;
        temp = 0;
 
-        while (ip6t_ext_hdr(nexthdr)) {
+        while (ipv6_ext_hdr(nexthdr)) {
                struct ipv6_opt_hdr *hdr;
 
               DEBUGP("ipv6_opts header iteration \n");
diff -urN linux-2.4.29/net/ipv6/netfilter/ip6t_IMQ.c linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_IMQ.c
--- linux-2.4.29/net/ipv6/netfilter/ip6t_IMQ.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_IMQ.c	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,78 @@
+/* This target marks packets to be enqueued to an imq device */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_IMQ.h>
+#include <linux/imq.h>
+
+static unsigned int imq_target(struct sk_buff **pskb,
+			       unsigned int hooknum,
+			       const struct net_device *in,
+			       const struct net_device *out,
+			       const void *targinfo,
+			       void *userinfo)
+{
+	struct ip6t_imq_info *mr = (struct ip6t_imq_info*)targinfo;
+
+	(*pskb)->imq_flags = mr->todev | IMQ_F_ENQUEUE;
+	(*pskb)->nfcache |= NFC_ALTERED;
+
+	return IP6T_CONTINUE;
+}
+
+static int imq_checkentry(const char *tablename,
+			  const struct ip6t_entry *e,
+			  void *targinfo,
+			  unsigned int targinfosize,
+			  unsigned int hook_mask)
+{
+	struct ip6t_imq_info *mr;
+
+	if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_imq_info))) {
+		printk(KERN_WARNING "IMQ: invalid targinfosize\n");
+		return 0;
+	}
+	mr = (struct ip6t_imq_info*)targinfo;
+
+	if (strcmp(tablename, "mangle") != 0) {
+		printk(KERN_WARNING
+		       "IMQ: IMQ can only be called from \"mangle\" table, not \"%s\"\n",
+		       tablename);
+		return 0;
+	}
+	
+	if (mr->todev > IMQ_MAX_DEVS) {
+		printk(KERN_WARNING
+		       "IMQ: invalid device specified, highest is %u\n",
+		       IMQ_MAX_DEVS);
+		return 0;
+	}
+	
+	return 1;
+}
+
+static struct ip6t_target ip6t_imq_reg = {
+	{ NULL, NULL},
+	"IMQ",
+	imq_target,
+	imq_checkentry,
+	NULL,
+	THIS_MODULE
+};
+
+static int __init init(void)
+{
+	if (ip6t_register_target(&ip6t_imq_reg))
+		return -EINVAL;
+
+	return 0;
+}
+
+static void __exit fini(void)
+{
+	ip6t_unregister_target(&ip6t_imq_reg);
+}
+
+module_init(init);
+module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.29/net/ipv6/netfilter/ip6t_ipv6header.c linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_ipv6header.c
--- linux-2.4.29/net/ipv6/netfilter/ip6t_ipv6header.c	2005-01-19 14:10:14.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_ipv6header.c	2005-06-14 02:11:52.000000000 +0100
@@ -45,7 +45,7 @@
 	len = skb->len - ptr;
 	temp = 0;
 
-        while (ip6t_ext_hdr(nexthdr)) {
+        while (ipv6_ext_hdr(nexthdr)) {
         	struct ipv6_opt_hdr *hdr;
         	int hdrlen;
 
diff -urN linux-2.4.29/net/ipv6/netfilter/ip6t_REJECT.c linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_REJECT.c
--- linux-2.4.29/net/ipv6/netfilter/ip6t_REJECT.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_REJECT.c	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,301 @@
+/*
+ * This is a module which is used for rejecting packets.
+ * 	Added support for customized reject packets (Jozsef Kadlecsik).
+ * Sun 12 Nov 2000
+ * 	Port to IPv6 / ip6tables (Harald Welte <laforge@gnumonks.org>)
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/icmpv6.h>
+#include <net/tcp.h>
+#include <net/ipv6.h>
+#include <net/ip6_fib.h>
+#include <net/ip6_route.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_REJECT.h>
+
+#if 1
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+#if 0
+/* Send RST reply */
+static void send_reset(struct sk_buff *oldskb)
+{
+	struct sk_buff *nskb;
+	struct tcphdr *otcph, *tcph;
+	struct rtable *rt;
+	unsigned int otcplen;
+	int needs_ack;
+
+	/* IP header checks: fragment, too short. */
+	if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)
+	    || oldskb->len < (oldskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
+		return;
+
+	otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl);
+	otcplen = oldskb->len - oldskb->nh.iph->ihl*4;
+
+	/* No RST for RST. */
+	if (otcph->rst)
+		return;
+
+	/* Check checksum. */
+	if (tcp_v4_check(otcph, otcplen, oldskb->nh.iph->saddr,
+			 oldskb->nh.iph->daddr,
+			 csum_partial((char *)otcph, otcplen, 0)) != 0)
+		return;
+
+	/* Copy skb (even if skb is about to be dropped, we can't just
+           clone it because there may be other things, such as tcpdump,
+           interested in it) */
+	nskb = skb_copy(oldskb, GFP_ATOMIC);
+	if (!nskb)
+		return;
+
+	/* This packet will not be the same as the other: clear nf fields */
+	nf_conntrack_put(nskb->nfct);
+	nskb->nfct = NULL;
+	nskb->nfcache = 0;
+#ifdef CONFIG_NETFILTER_DEBUG
+	nskb->nf_debug = 0;
+#endif
+
+	tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
+
+	nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
+	tcph->source = xchg(&tcph->dest, tcph->source);
+
+	/* Truncate to length (no data) */
+	tcph->doff = sizeof(struct tcphdr)/4;
+	skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
+	nskb->nh.iph->tot_len = htons(nskb->len);
+
+	if (tcph->ack) {
+		needs_ack = 0;
+		tcph->seq = otcph->ack_seq;
+		tcph->ack_seq = 0;
+	} else {
+		needs_ack = 1;
+		tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin
+				      + otcplen - (otcph->doff<<2));
+		tcph->seq = 0;
+	}
+
+	/* Reset flags */
+	((u_int8_t *)tcph)[13] = 0;
+	tcph->rst = 1;
+	tcph->ack = needs_ack;
+
+	tcph->window = 0;
+	tcph->urg_ptr = 0;
+
+	/* Adjust TCP checksum */
+	tcph->check = 0;
+	tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
+				   nskb->nh.iph->saddr,
+				   nskb->nh.iph->daddr,
+				   csum_partial((char *)tcph,
+						sizeof(struct tcphdr), 0));
+
+	/* Adjust IP TTL, DF */
+	nskb->nh.iph->ttl = MAXTTL;
+	/* Set DF, id = 0 */
+	nskb->nh.iph->frag_off = htons(IP_DF);
+	nskb->nh.iph->id = 0;
+
+	/* Adjust IP checksum */
+	nskb->nh.iph->check = 0;
+	nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph, 
+					   nskb->nh.iph->ihl);
+
+	/* Routing */
+	if (ip_route_output(&rt, nskb->nh.iph->daddr, nskb->nh.iph->saddr,
+			    RT_TOS(nskb->nh.iph->tos) | RTO_CONN,
+			    0) != 0)
+		goto free_nskb;
+
+	dst_release(nskb->dst);
+	nskb->dst = &rt->u.dst;
+
+	/* "Never happens" */
+	if (nskb->len > nskb->dst->pmtu)
+		goto free_nskb;
+
+	NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
+		ip_finish_output);
+	return;
+
+ free_nskb:
+	kfree_skb(nskb);
+}
+#endif
+
+static unsigned int reject6_target(struct sk_buff **pskb,
+			   unsigned int hooknum,
+			   const struct net_device *in,
+			   const struct net_device *out,
+			   const void *targinfo,
+			   void *userinfo)
+{
+	const struct ip6t_reject_info *reject = targinfo;
+	struct sk_buff *skb2 = NULL;
+	struct rt6_info *rt6i;
+	struct net_device odev;
+
+	if (!out) {
+		skb2 = skb_clone(*pskb, GFP_ATOMIC);
+		if (skb2 == NULL) {
+			return NF_DROP;
+		}
+		dst_release(skb2->dst);
+		skb2->dst = NULL;
+
+		rt6i = rt6_lookup(&skb2->nh.ipv6h->saddr, NULL, 0, 0);
+		if (rt6i && rt6i->rt6i_dev) {
+			skb2->dev = rt6i->rt6i_dev;
+			rt6i = rt6_lookup(&skb2->nh.ipv6h->daddr, &skb2->nh.ipv6h->saddr, 0, 0);
+		}
+		memcpy(&odev, skb2->dev, sizeof(odev)); /* XXX 'out' has 'const' qualifier... */
+	} else {
+		memcpy(&odev, out, sizeof(odev));
+	}
+
+	printk(KERN_DEBUG "%s: medium point\n", __FUNCTION__);
+	/* WARNING: This code causes reentry within ip6tables.
+	   This means that the ip6tables jump stack is now crap.  We
+	   must return an absolute verdict. --RR */
+	DEBUGP("REJECTv6: calling icmpv6_send\n");
+    	switch (reject->with) {
+    	case IP6T_ICMP6_NO_ROUTE:
+    		icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, &odev);
+    		break;
+    	case IP6T_ICMP6_ADM_PROHIBITED:
+    		icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADM_PROHIBITED, 0, &odev);
+    		break;
+    	case IP6T_ICMP6_NOT_NEIGHBOUR:
+    		icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOT_NEIGHBOUR, 0, &odev);
+    		break;
+    	case IP6T_ICMP6_ADDR_UNREACH:
+    		icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, &odev);
+    		break;
+    	case IP6T_ICMP6_PORT_UNREACH:
+    		icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, &odev);
+    		break;
+#if 0
+    	case IPT_ICMP_ECHOREPLY: {
+		struct icmp6hdr *icmph  = (struct icmphdr *)
+			((u_int32_t *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl);
+		unsigned int datalen = (*pskb)->len - (*pskb)->nh.iph->ihl * 4;
+
+		/* Not non-head frags, or truncated */
+		if (((ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET) == 0)
+		    && datalen >= 4) {
+			/* Usually I don't like cut & pasting code,
+                           but dammit, my party is starting in 45
+                           mins! --RR */
+			struct icmp_bxm icmp_param;
+
+			icmp_param.icmph=*icmph;
+			icmp_param.icmph.type=ICMP_ECHOREPLY;
+			icmp_param.data_ptr=(icmph+1);
+			icmp_param.data_len=datalen;
+			icmp_reply(&icmp_param, *pskb);
+		}
+	}
+	break;
+	case IPT_TCP_RESET:
+		send_reset(*pskb);
+		break;
+#endif
+	default:
+		printk(KERN_WARNING "REJECTv6: case %u not handled yet\n", reject->with);
+		break;
+	}
+
+	if (skb2) kfree_skb(skb2);
+
+	return NF_DROP;
+}
+
+static inline int find_ping_match(const struct ip6t_entry_match *m)
+{
+	const struct ip6t_icmp *icmpinfo = (const struct ip6t_icmp *)m->data;
+
+	if (strcmp(m->u.kernel.match->name, "icmp6") == 0
+	    && icmpinfo->type == ICMPV6_ECHO_REQUEST
+	    && !(icmpinfo->invflags & IP6T_ICMP_INV))
+		return 1;
+
+	return 0;
+}
+
+static int check(const char *tablename,
+		 const struct ip6t_entry *e,
+		 void *targinfo,
+		 unsigned int targinfosize,
+		 unsigned int hook_mask)
+{
+ 	const struct ip6t_reject_info *rejinfo = targinfo;
+
+ 	if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
+  		DEBUGP("REJECTv6: targinfosize %u != 0\n", targinfosize);
+  		return 0;
+  	}
+
+	/* Only allow these for packet filtering. */
+	if (strcmp(tablename, "filter") != 0) {
+		DEBUGP("REJECTv6: bad table `%s'.\n", tablename);
+		return 0;
+	}
+	if ((hook_mask & ~((1 << NF_IP6_LOCAL_IN)
+			   | (1 << NF_IP6_FORWARD)
+			   | (1 << NF_IP6_LOCAL_OUT))) != 0) {
+		DEBUGP("REJECTv6: bad hook mask %X\n", hook_mask);
+		return 0;
+	}
+
+	if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
+		/* Must specify that it's an ICMP ping packet. */
+		if (e->ipv6.proto != IPPROTO_ICMPV6
+		    || (e->ipv6.invflags & IP6T_INV_PROTO)) {
+			DEBUGP("REJECTv6: ECHOREPLY illegal for non-icmp\n");
+			return 0;
+		}
+		/* Must contain ICMP match. */
+		if (IP6T_MATCH_ITERATE(e, find_ping_match) == 0) {
+			DEBUGP("REJECTv6: ECHOREPLY illegal for non-ping\n");
+			return 0;
+		}
+	} else if (rejinfo->with == IP6T_TCP_RESET) {
+		/* Must specify that it's a TCP packet */
+		if (e->ipv6.proto != IPPROTO_TCP
+		    || (e->ipv6.invflags & IP6T_INV_PROTO)) {
+			DEBUGP("REJECTv6: TCP_RESET illegal for non-tcp\n");
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+static struct ip6t_target ip6t_reject_reg
+= { { NULL, NULL }, "REJECT", reject6_target, check, NULL, THIS_MODULE };
+
+static int __init init(void)
+{
+	if (ip6t_register_target(&ip6t_reject_reg))
+		return -EINVAL;
+	return 0;
+}
+
+static void __exit fini(void)
+{
+	ip6t_unregister_target(&ip6t_reject_reg);
+}
+
+module_init(init);
+module_exit(fini);
diff -urN linux-2.4.29/net/ipv6/netfilter/ip6t_rt.c linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_rt.c
--- linux-2.4.29/net/ipv6/netfilter/ip6t_rt.c	2005-01-19 14:10:14.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/netfilter/ip6t_rt.c	2005-06-14 02:11:52.000000000 +0100
@@ -61,7 +61,7 @@
        len = skb->len - ptr;
        temp = 0;
 
-        while (ip6t_ext_hdr(nexthdr)) {
+        while (ipv6_ext_hdr(nexthdr)) {
                struct ipv6_opt_hdr *hdr;
 
               DEBUGP("ipv6_rt header iteration \n");
@@ -152,8 +152,8 @@
                            ((rtinfo->hdrlen == hdrlen) ^
                            !!(rtinfo->invflags & IP6T_RT_INV_LEN))));
        DEBUGP("res %02X %02X %02X ", 
-       		(rtinfo->flags & IP6T_RT_RES), ((struct rt0_hdr *)route)->bitmap,
-       		!((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)route)->bitmap)));
+       		(rtinfo->flags & IP6T_RT_RES), ((struct rt0_hdr *)route)->reserved,
+       		!((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)route)->reserved)));
 
        ret = (route != NULL)
        		&&
@@ -169,7 +169,7 @@
                            ((rtinfo->rt_type == route->type) ^
                            !!(rtinfo->invflags & IP6T_RT_INV_TYP)))
 		&&
-       		!((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)route)->bitmap));
+       		!((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)route)->reserved));
 
 	DEBUGP("#%d ",rtinfo->addrnr);
        temp = len = ptr = 0;
diff -urN linux-2.4.29/net/ipv6/netfilter/Makefile linux-2.4.29-uc1/net/ipv6/netfilter/Makefile
--- linux-2.4.29/net/ipv6/netfilter/Makefile	2003-06-13 15:51:39.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv6/netfilter/Makefile	2005-06-14 02:11:52.000000000 +0100
@@ -28,8 +28,10 @@
 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
 obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
+obj-$(CONFIG_IP6_NF_TARGET_IMQ) += ip6t_IMQ.o
 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
 obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
+obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.29/net/ipv6/proc.c linux-2.4.29-uc1/net/ipv6/proc.c
--- linux-2.4.29/net/ipv6/proc.c	2002-02-25 19:38:14.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/proc.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: proc.c,v 1.16 2003/06/26 13:54:30 yoshfuji Exp $ */
+
 /*
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
@@ -19,12 +21,15 @@
 #include <linux/sched.h>
 #include <linux/socket.h>
 #include <linux/net.h>
+#include <linux/netdevice.h>
 #include <linux/in6.h>
 #include <linux/stddef.h>
 #include <net/sock.h>
 #include <net/tcp.h>
 #include <net/transp_v6.h>
 #include <net/ipv6.h>
+#include <net/addrconf.h>
+#include <linux/usagi-version.h>
 
 static int fold_prot_inuse(struct proto *proto)
 {
@@ -37,6 +42,17 @@
 	return res;
 }
 
+int afinet6_getversion(char *buffer, char **start, off_t offset, int length)
+{
+	int len = 0;
+	len += sprintf(buffer+len, "%s\n", USAGI_RELEASE);
+	*start = buffer + offset;
+	len -= offset;
+	if (len > length)
+		len = length;
+	return len;
+}
+
 int afinet6_get_info(char *buffer, char **start, off_t offset, int length)
 {
 	int len = 0;
@@ -55,15 +71,16 @@
 	return len;
 }
 
+#define OFFSETOF(s,m)	((size_t)(&((s *)NULL)->m))
 
 struct snmp6_item
 {
 	char *name;
-	unsigned long *ptr;
-	int   mibsize;
-} snmp6_list[] = {
-/* ipv6 mib according to draft-ietf-ipngwg-ipv6-mib-04 */
-#define SNMP6_GEN(x) { #x , &ipv6_statistics[0].x, sizeof(struct ipv6_mib)/sizeof(unsigned long) }
+	size_t offset;
+} snmp6_list_ipv6[] = {
+/* ipv6 mib according to RFC2465 */
+#define SNMP6_GEN(x) { #x , OFFSETOF(struct ipv6_mib, x) }
+	SNMP6_GEN(Ip6LastChange),
 	SNMP6_GEN(Ip6InReceives),
 	SNMP6_GEN(Ip6InHdrErrors),
 	SNMP6_GEN(Ip6InTooBigErrors),
@@ -87,47 +104,48 @@
 	SNMP6_GEN(Ip6InMcastPkts),
 	SNMP6_GEN(Ip6OutMcastPkts),
 #undef SNMP6_GEN
-/* icmpv6 mib according to draft-ietf-ipngwg-ipv6-icmp-mib-02
-
-   Exceptions:  {In|Out}AdminProhibs are removed, because I see
-                no good reasons to account them separately
-		of another dest.unreachs.
-		OutErrs is zero identically.
-		OutEchos too.
-		OutRouterAdvertisements too.
-		OutGroupMembQueries too.
- */
-#define SNMP6_GEN(x) { #x , &icmpv6_statistics[0].x, sizeof(struct icmpv6_mib)/sizeof(unsigned long) }
+};
+struct snmp6_item snmp6_list_icmpv6[] = {
+/* icmpv6 mib according to RFC2466 */
+#define SNMP6_GEN(x) { #x , OFFSETOF(struct icmpv6_mib, x) }
 	SNMP6_GEN(Icmp6InMsgs),
 	SNMP6_GEN(Icmp6InErrors),
 	SNMP6_GEN(Icmp6InDestUnreachs),
-	SNMP6_GEN(Icmp6InPktTooBigs),
+	SNMP6_GEN(Icmp6InAdminProhibs),
 	SNMP6_GEN(Icmp6InTimeExcds),
 	SNMP6_GEN(Icmp6InParmProblems),
+	SNMP6_GEN(Icmp6InPktTooBigs),
 	SNMP6_GEN(Icmp6InEchos),
 	SNMP6_GEN(Icmp6InEchoReplies),
-	SNMP6_GEN(Icmp6InGroupMembQueries),
-	SNMP6_GEN(Icmp6InGroupMembResponses),
-	SNMP6_GEN(Icmp6InGroupMembReductions),
 	SNMP6_GEN(Icmp6InRouterSolicits),
 	SNMP6_GEN(Icmp6InRouterAdvertisements),
 	SNMP6_GEN(Icmp6InNeighborSolicits),
 	SNMP6_GEN(Icmp6InNeighborAdvertisements),
 	SNMP6_GEN(Icmp6InRedirects),
+	SNMP6_GEN(Icmp6InGroupMembQueries),
+	SNMP6_GEN(Icmp6InGroupMembResponses),
+	SNMP6_GEN(Icmp6InGroupMembReductions),
 	SNMP6_GEN(Icmp6OutMsgs),
+	SNMP6_GEN(Icmp6OutErrors),
 	SNMP6_GEN(Icmp6OutDestUnreachs),
-	SNMP6_GEN(Icmp6OutPktTooBigs),
+	SNMP6_GEN(Icmp6OutAdminProhibs),
 	SNMP6_GEN(Icmp6OutTimeExcds),
 	SNMP6_GEN(Icmp6OutParmProblems),
+	SNMP6_GEN(Icmp6OutPktTooBigs),
+	SNMP6_GEN(Icmp6OutEchos),
 	SNMP6_GEN(Icmp6OutEchoReplies),
 	SNMP6_GEN(Icmp6OutRouterSolicits),
+	SNMP6_GEN(Icmp6OutRouterAdvertisements),
 	SNMP6_GEN(Icmp6OutNeighborSolicits),
 	SNMP6_GEN(Icmp6OutNeighborAdvertisements),
 	SNMP6_GEN(Icmp6OutRedirects),
+	SNMP6_GEN(Icmp6OutGroupMembQueries),
 	SNMP6_GEN(Icmp6OutGroupMembResponses),
 	SNMP6_GEN(Icmp6OutGroupMembReductions),
 #undef SNMP6_GEN
-#define SNMP6_GEN(x) { "Udp6" #x , &udp_stats_in6[0].Udp##x, sizeof(struct udp_mib)/sizeof(unsigned long) }
+};
+struct snmp6_item snmp6_list_udp[] = {
+#define SNMP6_GEN(x) { "Udp6" #x , OFFSETOF(struct udp_mib, Udp##x) }
 	SNMP6_GEN(InDatagrams),
 	SNMP6_GEN(NoPorts),
 	SNMP6_GEN(InErrors),
@@ -135,36 +153,76 @@
 #undef SNMP6_GEN
 };
 
-static unsigned long fold_field(unsigned long *ptr, int size)
-{
-	unsigned long res = 0;
-	int i;
-
-	for (i=0; i<smp_num_cpus; i++) {
-		res += ptr[2*cpu_logical_map(i)*size];
-		res += ptr[(2*cpu_logical_map(i)+1)*size];
-	}
-
-	return res;
-}
+#define fold_field(base,offset) ({ \
+	unsigned long res = 0;			\
+	int cpu;					\
+	for (cpu=0 ; cpu<smp_num_cpus; cpu++) {	\
+		res += *((unsigned long *)(((char *)&base[2*cpu_logical_map(cpu)]) + offset)) +	\
+		       *((unsigned long *)(((char *)&base[2*cpu_logical_map(cpu)+1]) + offset));	\
+	}					\
+	res;					\
+})
+
+#define snmp6_explore(_base,_list,_offset,_length,_done,_buffer,_start) ({			\
+	off_t _d = 0;										\
+	int _i, _l;										\
+	for (_i=0; _i<sizeof(_list)/sizeof(_list[0]); _i++){					\
+		if ((_done+_d) >= _offset + _length)						\
+			break;									\
+		_l = sprintf((_done+_d) <= _offset ? _buffer : *_start + (_done+_d) - _offset,	\
+			     "%-32s\t%ld\n", _list[_i].name,					\
+			     fold_field(_base,_list[_i].offset));				\
+		if ((_done+_d) <= _offset && (_done+_d)+_l >= _offset)				\
+			*_start = _buffer + _offset - (_done+_d);				\
+		_d += _l;									\
+	}											\
+	_d;											\
+})
 
 int afinet6_get_snmp(char *buffer, char **start, off_t offset, int length)
 {
 	int len = 0;
-	int i;
+	off_t done = 0;
 
-	for (i=0; i<sizeof(snmp6_list)/sizeof(snmp6_list[0]); i++)
-		len += sprintf(buffer+len, "%-32s\t%ld\n", snmp6_list[i].name,
-			       fold_field(snmp6_list[i].ptr, snmp6_list[i].mibsize));
+	done += snmp6_explore(ipv6_statistics,snmp6_list_ipv6,offset,length,done,buffer,start);
+	done += snmp6_explore(icmpv6_statistics,snmp6_list_icmpv6,offset,length,done,buffer,start);
+	done += snmp6_explore(udp_stats_in6,snmp6_list_udp,offset,length,done,buffer,start);
 
-	len -= offset;
+	len = done - offset;
 
 	if (len > length)
 		len = length;
-	if(len < 0)
+	if (len < 0)
 		len = 0;
 
-	*start = buffer + offset;
+	return len;
+}
+
+int afinet6_read_devsnmp(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
+{
+	int len = 0;
+	struct inet6_dev *idev = data;
+	off_t done = 0;
+
+	if (idev){
+		done += sprintf(buffer, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex);
+		if (done >= offset)
+			*start = buffer + offset;
+		done += snmp6_explore(idev->stats.ipv6,snmp6_list_ipv6,offset,length,done,buffer,start);
+		done += snmp6_explore(idev->stats.icmpv6,snmp6_list_icmpv6,offset,length,done,buffer,start);
+	}
+
+	if (done > offset){
+		len = done - offset;
+		if (len > length)
+			len = length;
+		else if (len < length)
+			*eof = 1;
+	}
+	else{
+		len = 0;
+		*eof = 1;
+	}
 
 	return len;
 }
diff -urN linux-2.4.29/net/ipv6/raw.c linux-2.4.29-uc1/net/ipv6/raw.c
--- linux-2.4.29/net/ipv6/raw.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/raw.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: raw.c,v 1.34 2003/08/11 16:54:00 yoshfuji Exp $ */
+
 /*
  *	RAW sockets for IPv6
  *	Linux INET6 implementation 
@@ -29,6 +31,7 @@
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/icmpv6.h>
+#include <linux/inet.h>
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
 
@@ -207,6 +210,10 @@
 	if (sk->state != TCP_CLOSE)
 		goto out;
 
+	if (addr->sin6_port && 
+	    ntohs(addr->sin6_port) != sk->num)
+		goto out;
+
 	if (addr_type & IPV6_ADDR_LINKLOCAL) {
 		if (addr_len >= sizeof(struct sockaddr_in6) &&
 		    addr->sin6_scope_id) {
@@ -216,9 +223,11 @@
 			sk->bound_dev_if = addr->sin6_scope_id;
 		}
 
+#ifndef CONFIG_IPV6_LOOSE_SCOPE_ID
 		/* Binding to link-local address requires an interface */
 		if (sk->bound_dev_if == 0)
 			goto out;
+#endif
 	}
 
 	/* Check if the address belongs to the host. */
@@ -279,26 +288,39 @@
 
 static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
 {
+	struct inet6_dev *idev = in6_dev_get(skb->dev);
+	struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
+ 	struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
+
 	if ((sk->tp_pinfo.tp_raw.checksum
 #if defined(CONFIG_FILTER)
 	    || sk->filter 
 #endif
 	    ) && skb->ip_summed != CHECKSUM_UNNECESSARY) {
 		if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
-			IP6_INC_STATS_BH(Ip6InDiscards);
-			kfree_skb(skb);
-			return 0;
+			char sbuf[64], dbuf[64];
+			in6_ntop(saddr, sbuf);
+			in6_ntop(daddr, dbuf);
+			if (net_ratelimit())
+				printk(KERN_WARNING "RAWv6 checksum failed [%s > %s]\n",
+					sbuf, dbuf);
+			goto discard_it;
 		}
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
 	}
 	/* Charge it to the socket. */
-	if (sock_queue_rcv_skb(sk,skb)<0) {
-		IP6_INC_STATS_BH(Ip6InDiscards);
-		kfree_skb(skb);
-		return 0;
-	}
+	if (sock_queue_rcv_skb(sk,skb)<0)
+		goto discard_it;
+
+	IP6_INC_STATS_BH(idev,Ip6InDelivers);
+	if (idev)
+		in6_dev_put(idev);
+	return 0;
 
-	IP6_INC_STATS_BH(Ip6InDelivers);
+discard_it:
+	IP6_INC_STATS_BH(idev,Ip6InDiscards);
+	if (idev)
+		in6_dev_put(idev);
+	kfree_skb(skb);
 	return 0;
 }
 
@@ -333,8 +355,11 @@
 	if (sk->protinfo.af_inet.hdrincl) {
 		if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
 		    (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
-			IP6_INC_STATS_BH(Ip6InDiscards);
+			struct inet6_dev *idev = in6_dev_get(skb->dev);
+			IP6_INC_STATS_BH(idev, Ip6InDiscards);
 			kfree_skb(skb);
+			if (idev)
+				in6_dev_put(idev);
 			return 0;
 		}
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -355,6 +380,8 @@
 {
 	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)msg->msg_name;
 	struct sk_buff *skb;
+	struct net_device *dev = NULL;
+	struct inet6_dev *idev = NULL;
 	int copied, err;
 
 	if (flags & MSG_OOB)
@@ -393,8 +420,8 @@
 	/* Copy the address. */
 	if (sin6) {
 		sin6->sin6_family = AF_INET6;
-		memcpy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr, 
-		       sizeof(struct in6_addr));
+		ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr);
+		sin6->sin6_port = htons(sk->num);
 		sin6->sin6_flowinfo = 0;
 		sin6->sin6_scope_id = 0;
 		if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
@@ -435,7 +462,14 @@
 	   as some normal condition.
 	 */
 	err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
-	IP6_INC_STATS_USER(Ip6InDiscards);
+	dev = dev_get_by_index(((struct inet6_skb_parm *) skb->cb)->iif);
+	if (dev) {
+		idev = in6_dev_get(dev);
+		IP6_INC_STATS_USER(idev,Ip6InDiscards);
+		if (idev)
+			in6_dev_put(idev);
+		dev_put(dev);
+	}
 	goto out_free;
 }
 
@@ -503,6 +537,7 @@
 				printk(KERN_DEBUG "icmp: cksum offset too big\n");
 			return -EINVAL;
 		}
+		hdr->cksum = 0;
 	}	
 	return 0; 
 }
@@ -520,6 +555,7 @@
 	struct in6_addr *daddr;
 	struct raw6_opt *raw_opt;
 	int hlimit = -1;
+	int tclass = -1;
 	u16 proto;
 	int err;
 
@@ -552,6 +588,8 @@
 
 		if (!proto)
 			proto = sk->num;
+		else if (proto != sk->num)
+			return(-EINVAL);
 
 		if (proto > 255)
 			return(-EINVAL);
@@ -601,7 +639,7 @@
 		opt = &opt_space;
 		memset(opt, 0, sizeof(struct ipv6_txoptions));
 
-		err = datagram_send_ctl(msg, &fl, opt, &hlimit);
+		err = datagram_send_ctl(msg, &fl, opt, &hlimit, &tclass);
 		if (err < 0) {
 			fl6_sock_release(flowlabel);
 			return err;
@@ -641,12 +679,11 @@
 			hdr.daddr = daddr;
 		else
 			hdr.daddr = NULL;
-
 		err = ip6_build_xmit(sk, rawv6_frag_cksum, &hdr, &fl, len,
-				     opt, hlimit, msg->msg_flags);
+				     opt, hlimit, tclass, msg->msg_flags);
 	} else {
 		err = ip6_build_xmit(sk, rawv6_getfrag, msg->msg_iov, &fl, len,
-				     opt, hlimit, msg->msg_flags);
+				     opt, hlimit, tclass, msg->msg_flags);
 	}
 
 	fl6_sock_release(flowlabel);
@@ -725,6 +762,8 @@
 
 	switch (optname) {
 		case IPV6_CHECKSUM:
+			if (sk->num == IPPROTO_ICMPV6 && val != 2)
+				return(-EINVAL);
 			/* You may get strange result with a positive odd offset;
 			   RFC2292bis agrees with me. */
 			if (val > 0 && (val&1))
diff -urN linux-2.4.29/net/ipv6/reassembly.c linux-2.4.29-uc1/net/ipv6/reassembly.c
--- linux-2.4.29/net/ipv6/reassembly.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/reassembly.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: reassembly.c,v 1.24 2003/08/08 13:46:38 yoshfuji Exp $ */
+
 /*
  *	IPv6 fragment reassembly
  *	Linux INET6 implementation 
@@ -260,7 +262,7 @@
 	}
 }
 
-static void ip6_evictor(void)
+static void ip6_evictor(struct inet6_dev *idev)
 {
 	struct frag_queue *fq;
 	struct list_head *tmp;
@@ -287,13 +289,15 @@
 		spin_unlock(&fq->lock);
 
 		fq_put(fq, &work);
-		IP6_INC_STATS_BH(Ip6ReasmFails);
+		IP6_INC_STATS_BH(idev,Ip6ReasmFails);
 	}
 }
 
 static void ip6_frag_expire(unsigned long data)
 {
 	struct frag_queue *fq = (struct frag_queue *) data;
+	struct net_device *dev;
+	struct inet6_dev *idev;
 
 	spin_lock(&fq->lock);
 
@@ -302,13 +306,14 @@
 
 	fq_kill(fq);
 
-	IP6_INC_STATS_BH(Ip6ReasmTimeout);
-	IP6_INC_STATS_BH(Ip6ReasmFails);
+	dev = dev_get_by_index(fq->iif);
+	idev = dev ? in6_dev_get(dev) : NULL;
+
+	IP6_INC_STATS_BH(idev,Ip6ReasmTimeout);
+	IP6_INC_STATS_BH(idev,Ip6ReasmFails);
 
 	/* Send error only if the first segment arrived. */
 	if (fq->last_in&FIRST_IN && fq->fragments) {
-		struct net_device *dev = dev_get_by_index(fq->iif);
-
 		/*
 		   But use as source device on which LAST ARRIVED
 		   segment was received. And do not use fq->dev
@@ -318,9 +323,12 @@
 			fq->fragments->dev = dev;
 			icmpv6_send(fq->fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0,
 				    dev);
-			dev_put(dev);
 		}
 	}
+	if (idev)
+		in6_dev_put(idev);
+	if (dev)
+		dev_put(dev);
 out:
 	spin_unlock(&fq->lock);
 	fq_put(fq, NULL);
@@ -367,7 +375,8 @@
 
 
 static struct frag_queue *
-ip6_frag_create(unsigned int hash, u32 id, struct in6_addr *src, struct in6_addr *dst)
+ip6_frag_create(unsigned int hash, u32 id, struct in6_addr *src, struct in6_addr *dst,
+		struct inet6_dev *idev)
 {
 	struct frag_queue *fq;
 
@@ -389,12 +398,12 @@
 	return ip6_frag_intern(hash, fq);
 
 oom:
-	IP6_INC_STATS_BH(Ip6ReasmFails);
+	IP6_INC_STATS_BH(idev,Ip6ReasmFails);
 	return NULL;
 }
 
 static __inline__ struct frag_queue *
-fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst)
+fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst, struct inet6_dev *idev)
 {
 	struct frag_queue *fq;
 	unsigned int hash = ip6qhashfn(id, src, dst);
@@ -411,7 +420,7 @@
 	}
 	read_unlock(&ip6_frag_lock);
 
-	return ip6_frag_create(hash, id, src, dst);
+	return ip6_frag_create(hash, id, src, dst, idev);
 }
 
 
@@ -420,6 +429,7 @@
 {
 	struct sk_buff *prev, *next;
 	int offset, end;
+	unsigned int unfrag_len;
 
 	if (fq->last_in & COMPLETE)
 		goto err;
@@ -427,10 +437,18 @@
 	offset = ntohs(fhdr->frag_off) & ~0x7;
 	end = offset + (ntohs(skb->nh.ipv6h->payload_len) -
 			((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1)));
+	if (offset) {
+		struct sk_buff *head = fq->fragments;
+		unfrag_len = (fq->last_in & FIRST_IN) ? 
+				(head->h.raw - (u8 *) (head->nh.ipv6h + 1)) :
+				0;
+	} else {
+		unfrag_len = ((u8 *) fhdr) - (u8 *)(skb->nh.ipv6h + 1);
+	}
 
-	if ((unsigned int)end >= 65536) {
- 		icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw);
- 		return;
+	if (unfrag_len + (unsigned int)end >= 65536) {
+		icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw); 
+		return;
 	}
 
  	if (skb->ip_summed == CHECKSUM_HW)
@@ -589,7 +607,8 @@
 			  struct net_device *dev)
 {
 	struct sk_buff *fp, *head = fq->fragments;
-	int    remove_fraghdr = 0;
+	struct inet6_dev *idev;
+	int    remove_fraghdr = 1;
 	int    payload_len;
 	int    nhoff;
 
@@ -598,16 +617,14 @@
 	BUG_TRAP(head != NULL);
 	BUG_TRAP(FRAG6_CB(head)->offset == 0);
 
+	idev = in6_dev_get(dev);
+
 	/* Unfragmented part is taken from the first segment. */
 	payload_len = (head->data - head->nh.raw) - sizeof(struct ipv6hdr) + fq->len;
 	nhoff = head->h.raw - head->nh.raw;
 
-	if (payload_len > 65535) {
-		payload_len -= 8;
-		if (payload_len > 65535)
-			goto out_oversize;
-		remove_fraghdr = 1;
-	}
+	if (payload_len > 65535 + 8)
+		goto out_oversize;
 
 	/* Head of list must not be cloned. */
 	if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC))
@@ -645,6 +662,7 @@
 		memmove(head->head+8, head->head, (head->data-head->head)-8);
 		head->mac.raw += 8;
 		head->nh.raw += 8;
+		payload_len -= 8;
 	} else {
 		((struct frag_hdr*)head->h.raw)->frag_off = 0;
 	}
@@ -676,7 +694,9 @@
 	if (head->ip_summed == CHECKSUM_HW)
 		head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum);
 
-	IP6_INC_STATS_BH(Ip6ReasmOKs);
+	IP6_INC_STATS_BH(idev,Ip6ReasmOKs);
+	if (idev)
+		in6_dev_put(idev);
 	fq->fragments = NULL;
 	return nhoff;
 
@@ -688,13 +708,16 @@
 	if (net_ratelimit())
 		printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n");
 out_fail:
-	IP6_INC_STATS_BH(Ip6ReasmFails);
+	IP6_INC_STATS_BH(idev,Ip6ReasmFails);
+	if (idev)
+		in6_dev_put(idev);
 	return -1;
 }
 
 int ipv6_reassembly(struct sk_buff **skbp, int nhoff)
 {
 	struct sk_buff *skb = *skbp; 
+	struct inet6_dev *idev = in6_dev_get(skb->dev);
 	struct net_device *dev = skb->dev;
 	struct frag_hdr *fhdr;
 	struct frag_queue *fq;
@@ -702,14 +725,18 @@
 
 	hdr = skb->nh.ipv6h;
 
-	IP6_INC_STATS_BH(Ip6ReasmReqds);
+	IP6_INC_STATS_BH(idev,Ip6ReasmReqds);
 
 	/* Jumbo payload inhibits frag. header */
 	if (hdr->payload_len==0) {
+		if (idev)
+			in6_dev_put(idev);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
 		return -1;
 	}
 	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+sizeof(struct frag_hdr))) {
+		if (idev)
+			in6_dev_put(idev);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
 		return -1;
 	}
@@ -720,15 +747,17 @@
 	if (!(fhdr->frag_off & htons(0xFFF9))) {
 		/* It is not a fragmented frame */
 		skb->h.raw += sizeof(struct frag_hdr);
-		IP6_INC_STATS_BH(Ip6ReasmOKs);
+		IP6_INC_STATS_BH(idev,Ip6ReasmOKs);
 
+		if (idev)
+			in6_dev_put(idev);
 		return (u8*)fhdr - skb->nh.raw;
 	}
 
 	if (atomic_read(&ip6_frag_mem) > sysctl_ip6frag_high_thresh)
-		ip6_evictor();
+		ip6_evictor(idev);
 
-	if ((fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr)) != NULL) {
+	if ((fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr, idev)) != NULL) {
 		int ret = -1;
 
 		spin_lock(&fq->lock);
@@ -744,7 +773,9 @@
 		return ret;
 	}
 
-	IP6_INC_STATS_BH(Ip6ReasmFails);
+	IP6_INC_STATS_BH(idev,Ip6ReasmFails);
+	if (idev)
+		in6_dev_put(idev);
 	kfree_skb(skb);
 	return -1;
 }
diff -urN linux-2.4.29/net/ipv6/route.c linux-2.4.29-uc1/net/ipv6/route.c
--- linux-2.4.29/net/ipv6/route.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/route.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: route.c,v 1.70 2004/01/14 14:11:38 yoshfuji Exp $ */
+
 /*
  *	Linux INET6 implementation
  *	FIB front-end.
@@ -33,6 +35,7 @@
 #include <linux/route.h>
 #include <linux/netdevice.h>
 #include <linux/in6.h>
+#include <linux/inet.h>
 #include <linux/init.h>
 #include <linux/netlink.h>
 #include <linux/if_arp.h>
@@ -59,14 +62,33 @@
 #undef CONFIG_RT6_POLICY
 
 /* Set to 3 to get tracing. */
-#define RT6_DEBUG 2
+#ifdef CONFIG_IPV6_RT6_DEBUG
+#define RT6_DEBUG 3
+#else
+#define RT6_DEBUG 1
+#endif
+
+#define RDBG(x)		printk x
+#define NORDBG(x)	do { ; } while(0)
+
+#define RT6_TRACE(x...)		RDBG((x))
 
 #if RT6_DEBUG >= 3
-#define RDBG(x) printk x
-#define RT6_TRACE(x...) printk(KERN_DEBUG x)
+#define RT6_TRACE3(x...)	RDBG((x))
 #else
-#define RDBG(x)
-#define RT6_TRACE(x...) do { ; } while (0)
+#define RT6_TRACE3(x...)	NORDBG((x))
+#endif
+
+#if RT6_DEBUG >= 2
+#define RT6_TRACE2(x...)	RDBG((x))
+#else
+#define RT6_TRACE2(x...)	NORDBG((x))
+#endif
+
+#if RT6_DEBUG >= 1
+#define RT6_TRACE1(x...)	RDBG((x))
+#else
+#define RT6_TRACE1(x...)	NORDBG((x))
 #endif
 
 
@@ -88,6 +110,11 @@
 static int		ip6_pkt_discard(struct sk_buff *skb);
 static void		ip6_link_failure(struct sk_buff *skb);
 
+#if defined(CONFIG_IPV6_ROUTE_INFO)
+static struct rt6_info *rt6_specific_route(struct in6_addr *prefix, int prefixlen, 
+					   struct in6_addr *saddr, int ifindex);
+#endif
+
 struct dst_ops ip6_dst_ops = {
 	AF_INET6,
 	__constant_htons(ETH_P_IPV6),
@@ -150,86 +177,239 @@
 
 static __inline__ struct rt6_info *rt6_device_match(struct rt6_info *rt,
 						    int oif,
-						    int strict)
+						    int strict,
+						    int scope)
 {
 	struct rt6_info *local = NULL;
 	struct rt6_info *sprt;
+#ifdef CONFIG_IPV6_ZONE
+	struct net_device *odev = NULL;
+	struct inet6_dev *oidev = NULL;
+#endif
 
 	if (oif) {
+#ifdef CONFIG_IPV6_ZONE
+		if (scope < 0 || scope >= 16)
+			scope = 0;	/*XXX*/
+
+		odev = dev_get_by_index(oif);
+		if (odev)
+			oidev = in6_dev_get(odev);
+#endif
+
 		for (sprt = rt; sprt; sprt = sprt->u.next) {
 			struct net_device *dev = sprt->rt6i_dev;
-			if (dev->ifindex == oif)
-				return sprt;
+#ifdef CONFIG_IPV6_ZONE
+			struct inet6_dev *idev;
+#endif
+			if (dev->ifindex == oif) {
+				rt = sprt;
+				goto out;
+			}
+#ifdef CONFIG_IPV6_ZONE
+			idev = in6_dev_get(dev);
+			if (idev) {
+				if (oidev) {
+					if (idev->zone.zoneid[scope] == 0 ||
+					    oidev->zone.zoneid[scope] == idev->zone.zoneid[scope]) {
+						in6_dev_put(idev);
+						rt = sprt;
+						goto out;
+					}
+				}
+				in6_dev_put(idev);
+			}
+#endif
 			if (dev->flags&IFF_LOOPBACK)
 				local = sprt;
 		}
 
-		if (local)
-			return local;
+		if (local) {
+			rt = local;
+			goto out;
+		}
 
-		if (strict)
-			return &ip6_null_entry;
+		if (strict) {
+			rt = &ip6_null_entry;
+			goto out;
+		}
+	}
+out:
+#ifdef CONFIG_IPV6_ZONE
+	if (odev) {
+		if (oidev)
+			in6_dev_put(oidev);
+		dev_put(odev);
 	}
+#endif
 	return rt;
 }
 
 /*
  *	pointer to the last default router chosen. BH is disabled locally.
  */
-static struct rt6_info *rt6_dflt_pointer = NULL;
-static spinlock_t rt6_dflt_lock = SPIN_LOCK_UNLOCKED;
+#if !defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+struct rt6_info *rt6_dflt_pointer = NULL;
+spinlock_t rt6_dflt_lock = SPIN_LOCK_UNLOCKED;
+#endif
 
 /* Default Router Selection (RFC 2461 6.3.6) */
-static struct rt6_info *rt6_best_dflt(struct rt6_info *rt, int oif)
+static int __rt6_score_dflt(struct rt6_info *sprt, struct rt6_info *dflt, int oif)
+{
+	struct neighbour *neigh = sprt->rt6i_nexthop;
+	int m = oif ? 0 : 8;
+
+	if (!neigh)
+		return -1;
+	
+	if (oif && sprt->rt6i_dev &&
+	    sprt->rt6i_dev->ifindex == oif)
+		m += 8;
+
+#if !defined(CONFIG_IPV6_ROUTER_PREF)
+	if (sprt == dflt) 
+		m += 4;
+#endif
+
+	read_lock_bh(&neigh->lock);
+	switch (neigh->nud_state) {
+	case NUD_REACHABLE:
+		m += 3;
+		break;
+
+	case NUD_STALE:
+	case NUD_DELAY:
+	case NUD_PROBE:
+		m += 2;
+		break;
+
+	case NUD_NOARP:
+	case NUD_PERMANENT:
+		m += 1;
+		break;
+
+	case NUD_INCOMPLETE:
+	default:
+		m = -1;
+	}
+	read_unlock_bh(&neigh->lock);
+
+	return m;
+}
+
+static struct rt6_info *rt6_best_dflt(struct rt6_info *rt, struct rt6_info **head, int oif)
 {
 	struct rt6_info *match = NULL;
 	struct rt6_info *sprt;
+#if defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+	struct rt6_info *last = NULL;
+#endif
 	int mpri = 0;
+#if defined(CONFIG_IPV6_ROUTER_PREF)
+	u32 metric = 0;
+	int pref = -3;
+#else
+	static const int okpri = 12;	/* device match, prob. reachable */
+#endif
 
-	for (sprt = rt; sprt; sprt = sprt->u.next) {
-		struct neighbour *neigh;
-		int m = 0;
-
-		if (!oif ||
-		    (sprt->rt6i_dev &&
-		     sprt->rt6i_dev->ifindex == oif))
-			m += 8;
+	if (head != NULL && *head != rt)
+		head = NULL;	/*XXX*/
 
-		if (sprt == rt6_dflt_pointer)
-			m += 4;
-
-		if ((neigh = sprt->rt6i_nexthop) != NULL) {
-			read_lock_bh(&neigh->lock);
-			switch (neigh->nud_state) {
-			case NUD_REACHABLE:
-				m += 3;
+#if !defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+	spin_lock(&rt6_dflt_lock);
+#endif
+#if !defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+	if (rt6_dflt_pointer) {
+		for (sprt = rt; sprt; sprt = sprt->u.next) {
+			if (sprt == rt6_dflt_pointer)
 				break;
+		}
+		if (!sprt)
+			rt6_dflt_pointer = NULL;	/* for sure */
+	}
+#endif
 
-			case NUD_STALE:
-			case NUD_DELAY:
-			case NUD_PROBE:
-				m += 2;
-				break;
+#if defined(CONFIG_IPV6_ROUTER_PREF)
+#if !defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+	if (rt6_dflt_pointer) {
+		for (sprt = rt6_dflt_pointer->u.next; sprt; sprt = sprt->u.next) {
+			int m, p;
 
-			case NUD_NOARP:
-			case NUD_PERMANENT:
-				m += 1;
-				break;
+			if ((metric != 0 && sprt->rt6i_metric > metric) ||
+			    sprt->u.dst.obsolete > 0 ||
+			    sprt->u.dst.error != 0)
+				continue;
 
-			case NUD_INCOMPLETE:
-			default:
-				read_unlock_bh(&neigh->lock);
+#if defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+			m = __rt6_score_dflt(sprt, rt, oif);
+#else
+			m = __rt6_score_dflt(sprt, rt6_dflt_pointer, oif);
+#endif
+			if (m < mpri)
 				continue;
+			p = IPV6_SIGNEDPREF(IPV6_UNSHIFT_PREF(sprt->rt6i_flags));
+			if (sprt->rt6i_metric < metric || m > mpri || p > pref) {
+				match = sprt;
+				metric = sprt->rt6i_metric;
+				mpri = m;
+				pref = p;
 			}
-			read_unlock_bh(&neigh->lock);
-		} else {
+		}
+	}
+#endif
+#if defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+	metric = rt->rt6i_metric;
+#endif
+	for (sprt = rt; sprt; sprt = sprt->u.next) {
+		int m, p;
+#if defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+		if (sprt->rt6i_metric > metric)
+			break;
+#else
+		if ((metric != 0 && sprt->rt6i_metric > metric) ||
+		    sprt->u.dst.obsolete > 0 ||
+		    sprt->u.dst.error != 0)
 			continue;
+
+#endif
+#if defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+		m = __rt6_score_dflt(sprt, rt, oif);
+#else
+		m = __rt6_score_dflt(sprt, rt6_dflt_pointer, oif);
+#endif
+		if (m < mpri)
+			continue;
+		p = IPV6_SIGNEDPREF(IPV6_UNSHIFT_PREF(sprt->rt6i_flags));
+		if (
+#if !defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+		    sprt->rt6i_metric < metric || 
+#endif
+		    m > mpri || p > pref) {
+			match = sprt;
+			metric = sprt->rt6i_metric;
+			mpri = m;
+			pref = p;
 		}
+#if defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+		last = sprt;
+#else
+		if (sprt == rt6_dflt_pointer)
+			break;
+#endif
+	}
+#else	/* CONFIG_IPV6_ROUTER_PREF / !CONFIG_IPV6_ROUTER_PREF */
+	for (sprt = rt; sprt; sprt = sprt->u.next) {
+		int m;
+#if defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+		m = __rt6_score_dflt(sprt, rt, oif);
+#else
+		m = __rt6_score_dflt(sprt, rt6_dflt_pointer, oif);
+#endif
 
-		if (m > mpri || m >= 12) {
+		if (m > mpri || m >= okpri) {
 			match = sprt;
 			mpri = m;
-			if (m >= 12) {
+			if (m >= okpri) {
 				/* we choose the lastest default router if it
 				 * is in (probably) reachable state.
 				 * If route changed, we should do pmtu
@@ -240,7 +420,6 @@
 		}
 	}
 
-	spin_lock(&rt6_dflt_lock);
 	if (!match) {
 		/*
 		 *	No default routers are known to be reachable.
@@ -256,7 +435,7 @@
 				}
 			}
 			for (sprt = rt;
-			     !match && sprt;
+			     !match && sprt; 
 			     sprt = sprt->u.next) {
 				if (sprt->u.dst.obsolete <= 0 &&
 				    sprt->u.dst.error == 0) {
@@ -268,11 +447,26 @@
 			}
 		}
 	}
+#endif /* !CONFIG_IPV6_ROUTER_PREF */
 
-	if (match)
+	if (match) {
+#if defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+		if (rt != last && last) {
+			*head = rt->u.next;
+			rt->u.next = last->u.next;
+			last->u.next = rt;
+		}
+#else
+		if (rt6_dflt_pointer != match)
+			RT6_TRACE1(KERN_INFO 
+					"changed default router: %p->%p\n",
+					rt6_dflt_pointer, match);
 		rt6_dflt_pointer = match;
-
+#endif
+	}
+#if !defined(CONFIG_IPV6_NEW_ROUNDROBIN)
 	spin_unlock(&rt6_dflt_lock);
+#endif
 
 	if (!match) {
 		/*
@@ -299,20 +493,148 @@
 	return match;
 }
 
+#if defined(CONFIG_IPV6_ROUTER_PREF)
+#if defined(CONFIG_IPV6_ROUTE_INFO)
+int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, struct in6_addr *gwaddr)
+{
+	struct route_info *rinfo = (struct route_info *) opt;
+	u32 lifetime;
+	int pref;
+	struct inet6_dev *in6_dev;
+	struct rt6_info *rt;
+	struct in6_addr prefix, *prefix_ptr;
+
+	if (len < sizeof(struct route_info)) {
+		if (net_ratelimit())
+			RT6_TRACE2(KERN_WARNING
+				   "addrconf: too short route information option\n");
+		return -EINVAL;
+	}
+	if (rinfo->length > 3) {
+		if (net_ratelimit())
+			RT6_TRACE2(KERN_WARNING
+				   "addrconf: too long route information option\n");
+		return -EINVAL;
+	}
+	if (rinfo->prefix_len > 128) {
+		if (net_ratelimit())
+			RT6_TRACE2(KERN_WARNING
+				   "addrconf: invalid prefix length in route informatio\n");
+		return -EINVAL;
+	}
+	pref = IPV6_SIGNEDPREF(rinfo->route_pref);
+	if (pref < -1)
+		return -EINVAL;
+
+	lifetime = htonl(rinfo->lifetime);
+#if 0
+	if (lifetime == 0xffffffff) {
+		/* infinity */
+	} else
+#endif
+	if (lifetime > 0x7fffffff/HZ) {
+		/* Avoid arithemtic overflow */
+		if (net_ratelimit())
+			RT6_TRACE1(KERN_WARNING
+				   "addrconf: lifetime %u is too long; adjusted to %u.\n",
+				   lifetime, 0x7fffffff/HZ-1);
+		lifetime = 0x7fffffff/HZ-1;
+	}
+
+	in6_dev = in6_dev_get(dev);
+	if (in6_dev == NULL) {
+		if (net_ratelimit())
+			RT6_TRACE1(KERN_WARNING
+				   "addrconf: device %s not configured\n", dev->name);
+		return -ENODEV;
+	}
+
+	if (rinfo->length < 3) {
+		memset(&prefix, 0, sizeof(prefix));
+		memcpy(&prefix, rinfo->prefix, (rinfo->length-1)<<3);
+		prefix_ptr = &prefix;
+	} else {
+		prefix_ptr = (struct in6_addr *)rinfo->prefix;
+	}
+
+	rt = rt6_specific_route(prefix_ptr, rinfo->prefix_len, gwaddr, dev->ifindex);
+	if (rt && lifetime == 0) {
+		ip6_del_rt(rt, NULL);
+		rt = NULL;
+	}
+
+	if (!rt && lifetime) {
+		/* new route */
+		struct in6_rtmsg rtmsg;
+
+		memset(&rtmsg, 0, sizeof(struct in6_rtmsg));
+		rtmsg.rtmsg_type = RTMSG_NEWROUTE;
+		ipv6_addr_copy(&rtmsg.rtmsg_dst, prefix_ptr);	/*XXX*/
+		rtmsg.rtmsg_dst_len = rinfo->prefix_len;
+		ipv6_addr_copy(&rtmsg.rtmsg_gateway, gwaddr);
+		rtmsg.rtmsg_metric = 1024;
+		rtmsg.rtmsg_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | RTF_UP | RTF_PREF(pref&3);
+
+		rtmsg.rtmsg_ifindex = dev->ifindex;
+
+		ip6_route_add(&rtmsg, NULL);
+	}
+	if (rt) {
+		rt->rt6i_flags = (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref&3);
+		rt->rt6i_expires = jiffies + HZ * lifetime;
+		dst_release(&rt->u.dst);
+	}
+	return 0;
+}
+
+static struct rt6_info *rt6_specific_route(struct in6_addr *prefix, int prefixlen, 
+					   struct in6_addr *saddr, int ifindex)
+{
+	struct fib6_node *fn;
+	struct rt6_info *rt = NULL;
+
+	write_lock_bh(&rt6_lock);
+	fn = fib6_locate(&ip6_routing_table,
+			 prefix, prefixlen,
+			 NULL, 0);
+	if (fn == NULL)
+		goto out;
+	for (rt = fn->leaf; rt; rt = rt->u.next) {
+		if (rt->rt6i_dev == NULL ||
+		    rt->rt6i_dev->ifindex != ifindex)
+			continue;
+		if (!(rt->rt6i_flags & RTF_DEFAULT))
+			continue;
+		if (!(rt->rt6i_flags & RTF_GATEWAY))
+			continue;
+		if (ipv6_addr_cmp(&rt->rt6i_gateway, saddr))
+			continue;
+		dst_hold(&rt->u.dst);
+		break;
+	}
+out:
+	write_unlock_bh(&rt6_lock);
+	return rt;
+}
+#endif
+#endif
+
 struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr,
-			    int oif, int strict)
+			    int oif, int flags)
 {
 	struct fib6_node *fn;
 	struct rt6_info *rt;
+	int scope = ipv6_addr_src_scope(daddr);
 
 	read_lock_bh(&rt6_lock);
 	fn = fib6_lookup(&ip6_routing_table, daddr, saddr);
-	rt = rt6_device_match(fn->leaf, oif, strict);
+	rt = rt6_device_match(fn->leaf, oif, !!(flags & RT6_LOOKUP_FLAG_STRICT), scope);
 	dst_hold(&rt->u.dst);
 	rt->u.dst.__use++;
 	read_unlock_bh(&rt6_lock);
 
-	rt->u.dst.lastuse = jiffies;
+	if (!(flags & RT6_LOOKUP_FLAG_NOUSE))
+		rt->u.dst.lastuse = jiffies;
 	if (rt->u.dst.error == 0)
 		return rt;
 	dst_release(&rt->u.dst);
@@ -363,10 +685,7 @@
 		rt->u.dst.flags |= DST_HOST;
 
 #ifdef CONFIG_IPV6_SUBTREES
-		if (rt->rt6i_src.plen && saddr) {
-			ipv6_addr_copy(&rt->rt6i_src.addr, saddr);
-			rt->rt6i_src.plen = 128;
-		}
+		rt->rt6i_src.plen = ort->rt6i_src.plen;
 #endif
 
 		rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway);
@@ -434,10 +753,17 @@
 {
 	struct fib6_node *fn;
 	struct rt6_info *rt;
-	int strict;
+	int strict, addrtype;
 	int attempts = 3;
 
-	strict = ipv6_addr_type(&skb->nh.ipv6h->daddr) & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL);
+	addrtype = __ipv6_addr_type(&skb->nh.ipv6h->daddr);
+#ifdef CONFIG_IPV6_ZONE
+	strict = (addrtype & IPV6_ADDR_MULTICAST) ||
+		 __ipv6_addr_src_scope(addrtype) < IPV6_ADDR_SCOPE_GLOBAL;
+#else
+	strict = (addrtype & IPV6_ADDR_MULTICAST) ||
+		 __ipv6_addr_src_scope(addrtype) == IPV6_ADDR_SCOPE_LINKLOCAL;
+#endif
 
 relookup:
 	read_lock_bh(&rt6_lock);
@@ -450,7 +776,7 @@
 
 	if ((rt->rt6i_flags & RTF_CACHE)) {
 		if (ip6_rt_policy == 0) {
-			rt = rt6_device_match(rt, skb->dev->ifindex, strict);
+			rt = rt6_device_match(rt, skb->dev->ifindex, strict, __ipv6_addr_src_scope(addrtype));
 			BACKTRACK();
 			dst_hold(&rt->u.dst);
 			goto out;
@@ -471,7 +797,7 @@
 #endif
 	}
 
-	rt = rt6_device_match(rt, skb->dev->ifindex, 0);
+	rt = rt6_device_match(rt, skb->dev->ifindex, 0, __ipv6_addr_src_scope(addrtype));
 	BACKTRACK();
 
 	if (ip6_rt_policy == 0) {
@@ -509,10 +835,17 @@
 {
 	struct fib6_node *fn;
 	struct rt6_info *rt;
-	int strict;
+	int strict, addrtype;
 	int attempts = 3;
 
-	strict = ipv6_addr_type(fl->nl_u.ip6_u.daddr) & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL);
+	addrtype = __ipv6_addr_type(fl->nl_u.ip6_u.daddr);
+#ifdef CONFIG_IPV6_ZONE
+	strict = (addrtype & IPV6_ADDR_MULTICAST) ||
+		 __ipv6_addr_src_scope(addrtype) < IPV6_ADDR_SCOPE_GLOBAL;
+#else
+	strict = (addrtype & IPV6_ADDR_MULTICAST) ||
+		 __ipv6_addr_src_scope(addrtype) == IPV6_ADDR_SCOPE_LINKLOCAL;
+#endif
 
 relookup:
 	read_lock_bh(&rt6_lock);
@@ -525,7 +858,7 @@
 
 	if ((rt->rt6i_flags & RTF_CACHE)) {
 		if (ip6_rt_policy == 0) {
-			rt = rt6_device_match(rt, fl->oif, strict);
+			rt = rt6_device_match(rt, fl->oif, strict, __ipv6_addr_src_scope(addrtype));
 			BACKTRACK();
 			dst_hold(&rt->u.dst);
 			goto out;
@@ -546,10 +879,9 @@
 #endif
 	}
 	if (rt->rt6i_flags & RTF_DEFAULT) {
-		if (rt->rt6i_metric >= IP6_RT_PRIO_ADDRCONF)
-			rt = rt6_best_dflt(rt, fl->oif);
+			rt = rt6_best_dflt(rt, &fn->leaf, fl->oif);
 	} else {
-		rt = rt6_device_match(rt, fl->oif, strict);
+		rt = rt6_device_match(rt, fl->oif, strict, __ipv6_addr_src_scope(addrtype));
 		BACKTRACK();
 	}
 
@@ -608,8 +940,8 @@
 	/*
 	 *	FIXME
 	 */
-	RDBG(("ip6_dst_reroute(%p,%p)[%p] (AIEEE)\n", dst, skb,
-	      __builtin_return_address(0)));
+	RT6_TRACE3(KERN_DEBUG "ip6_dst_reroute(%p,%p)[%p] (AIEEE)\n", dst, skb,
+	      __builtin_return_address(0));
 	return NULL;
 }
 
@@ -663,25 +995,6 @@
 	return (atomic_read(&ip6_dst_ops.entries) > ip6_rt_max_size);
 }
 
-/* Clean host part of a prefix. Not necessary in radix tree,
-   but results in cleaner routing tables.
-
-   Remove it only when all the things will work!
- */
-
-static void ipv6_addr_prefix(struct in6_addr *pfx,
-			     const struct in6_addr *addr, int plen)
-{
-	int b = plen&0x7;
-	int o = plen>>3;
-
-	memcpy(pfx->s6_addr, addr, o);
-	if (o < 16)
-		memset(pfx->s6_addr + o, 0, 16 - o);
-	if (b != 0)
-		pfx->s6_addr[o] = addr->s6_addr[o]&(0xff00 >> b);
-}
-
 static int ipv6_get_mtu(struct net_device *dev)
 {
 	int mtu = IPV6_MIN_MTU;
@@ -810,7 +1123,7 @@
 			if (!(gwa_type&IPV6_ADDR_UNICAST))
 				goto out;
 
-			grt = rt6_lookup(gw_addr, NULL, rtmsg->rtmsg_ifindex, 1);
+			grt = rt6_lookup(gw_addr, NULL, rtmsg->rtmsg_ifindex, RT6_LOOKUP_FLAG_STRICT);
 
 			err = -EHOSTUNREACH;
 			if (grt == NULL)
@@ -880,9 +1193,11 @@
 
 	write_lock_bh(&rt6_lock);
 
+#if !defined(CONFIG_IPV6_NEW_ROUNDROBIN)
 	spin_lock_bh(&rt6_dflt_lock);
 	rt6_dflt_pointer = NULL;
 	spin_unlock_bh(&rt6_dflt_lock);
+#endif
 
 	dst_release(&rt->u.dst);
 
@@ -927,16 +1242,112 @@
 	return err;
 }
 
+#ifdef CONFIG_IPV6_ZONE
+int ip6_get_zone(struct ip6_zoneid *zmsg)
+{
+	struct net_device *dev;
+	struct inet6_dev *idev;
+
+	if (!zmsg->zoneid[IPV6_ADDR_SCOPE_NODELOCAL])
+		return -EINVAL;
+	dev = dev_get_by_index(zmsg->zoneid[IPV6_ADDR_SCOPE_NODELOCAL]);
+	if (!dev)
+		return -ENODEV;
+	idev = in6_dev_get(dev);
+	if (!idev) {
+		dev_put(dev);
+		return -ENODEV;
+	}
+	read_lock(&idev->lock);
+	memcpy(zmsg, &idev->zone, sizeof(*zmsg));
+	read_unlock(&idev->lock);
+	in6_dev_put(idev);
+	dev_put(dev);
+	return 0;
+}
+
+int ip6_set_zone(struct ip6_zoneid *zmsg)
+{
+	struct net_device *dev, *odev;
+	struct inet6_dev *idev, *oidev;
+	int i;
+	int ret = 0;
+
+	if (!zmsg->zoneid[IPV6_ADDR_SCOPE_NODELOCAL])
+		return -EINVAL;
+
+	dev = dev_get_by_index(zmsg->zoneid[IPV6_ADDR_SCOPE_NODELOCAL]);
+	idev = dev ? in6_dev_get(dev) : NULL;
+	if (!idev) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	read_lock(&dev_base_lock);
+	write_lock(&idev->lock);
+
+	for (i=0; i<16; i++) {
+		if (zmsg->zoneid[i] & 0xf0000000) {
+			ret = -EINVAL;
+			goto unlock_out;
+		}
+		if (i <= IPV6_ADDR_SCOPE_NODELOCAL) {
+			if (!zmsg->zoneid[i]) {
+				zmsg->zoneid[i] = dev->ifindex;
+			} else if (zmsg->zoneid[i] != dev->ifindex) {
+				ret = -EINVAL;
+				goto unlock_out;
+			}
+		} else {
+			if (!zmsg->zoneid[i]) {
+				zmsg->zoneid[i] = idev->zone.zoneid[i];
+			}
+		}
+	}
+
+	for (odev = dev_base; odev; odev = odev->next) {
+		int match = 0;
+		if (odev == dev)
+			continue;
+		oidev = __in6_dev_get(odev);
+		if (!oidev)
+			continue;
+
+		for (i=0; i<16; i++) {
+			if (zmsg->zoneid[i] == oidev->zone.zoneid[i]) {
+				match++;
+			} else if (match) {
+				ret = -EINVAL;
+				goto unlock_out;
+			}
+		}
+		if (match)
+			break;
+	}
+	memcpy(&idev->zone, zmsg, sizeof(*zmsg));
+
+unlock_out:
+	write_unlock(&idev->lock);
+	read_unlock(&dev_base_lock);
+out:
+	if (idev)
+		in6_dev_put(idev);
+	dev_put(dev);
+	return ret;
+}
+#endif
+
 /*
  *	Handle redirects
  */
 void rt6_redirect(struct in6_addr *dest, struct in6_addr *saddr,
-		  struct neighbour *neigh, int on_link)
+		  struct neighbour *neigh, u8 *lladdr, int on_link)
 {
 	struct rt6_info *rt, *nrt;
+	int notify;
 
 	/* Locate old route to this destination. */
-	rt = rt6_lookup(dest, NULL, neigh->dev->ifindex, 1);
+	rt = rt6_lookup(dest, saddr, neigh->dev->ifindex, RT6_LOOKUP_FLAG_STRICT);
 
 	if (rt == NULL)
 		return;
@@ -944,16 +1355,6 @@
 	if (neigh->dev != rt->rt6i_dev)
 		goto out;
 
-	/* Redirect received -> path was valid.
-	   Look, redirects are sent only in response to data packets,
-	   so that this nexthop apparently is reachable. --ANK
-	 */
-	dst_confirm(&rt->u.dst);
-
-	/* Duplicate redirect: silently ignore. */
-	if (neigh == rt->u.dst.neighbour)
-		goto out;
-
 	/* Current route is on-link; redirect is always invalid.
 	   
 	   Seems, previous statement is not true. It could
@@ -964,6 +1365,16 @@
 	if (!(rt->rt6i_flags&RTF_GATEWAY))
 		goto out;
 
+	/* Redirect received -> path was valid.
+	   Look, redirects are sent only in response to data packets,
+	   so that this nexthop apparently is reachable. --ANK
+	 */
+	dst_confirm(&rt->u.dst);
+
+	/* Duplicate redirect: silently ignore. */
+	if (neigh == rt->u.dst.neighbour)
+		goto out;
+
 	/*
 	 *	RFC 1970 specifies that redirects should only be
 	 *	accepted if they come from the nexthop to the target.
@@ -989,17 +1400,40 @@
 			read_unlock(&rt6_lock);
 		}
 		if (net_ratelimit())
-			printk(KERN_DEBUG "rt6_redirect: source isn't a valid nexthop "
+			RT6_TRACE2(KERN_DEBUG "rt6_redirect: source isn't a valid nexthop "
 			       "for redirect target\n");
 		goto out;
 	}
 
 source_ok:
-
 	/*
 	 *	We have finally decided to accept it.
 	 */
 
+#ifdef CONFIG_IPV6_NDISC_NEW
+	write_lock_bh(&neigh->lock);
+	notify = __neigh_update(neigh, lladdr, NUD_STALE,
+			NEIGH_UPDATE_F_IP6REDIRECT|
+			(on_link ? 0 : (NEIGH_UPDATE_F_OVERRIDE_VALID_ISROUTER|
+					NEIGH_UPDATE_F_ISROUTER)));
+#ifdef CONFIG_ARPD
+	if (notify > 0 && !neigh->parms->app_probes) {
+		write_unlock_bh(&neigh->lock);
+	} else
+#endif
+	write_unlock_bh(&neigh->lock);
+#endif
+
+	/* Redirect received -> path was valid.
+	   Look, redirects are sent only in response to data packets,
+	   so that this nexthop apparently is reachable. --ANK
+	 */
+	dst_confirm(&rt->u.dst);
+
+	/* Duplicate redirect: silently ignore. */
+	if (neigh == rt->u.dst.neighbour)
+		goto out;
+
 	nrt = ip6_rt_copy(rt);
 	if (nrt == NULL)
 		goto out;
@@ -1046,7 +1480,7 @@
 
 	if (pmtu < IPV6_MIN_MTU) {
 		if (net_ratelimit())
-			printk(KERN_DEBUG "rt6_pmtu_discovery: invalid MTU value %d\n",
+			RT6_TRACE2(KERN_DEBUG "rt6_pmtu_discovery: invalid MTU value %d\n",
 			       pmtu);
 		/* According to RFC1981, the PMTU is set to the IPv6 minimum
 		   link MTU if the node receives a Packet Too Big message
@@ -1098,19 +1532,27 @@
 			 */
 			dst_set_expires(&nrt->u.dst, ip6_rt_mtu_expires);
 			nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES;
-			dst_release(&nrt->u.dst);
 		}
 	} else {
 		nrt = ip6_rt_copy(rt);
 		if (nrt == NULL)
 			goto out;
+#ifdef CONFIG_IPV6_SUBTREES
+		nrt->rt6i_src.plen = rt->rt6i_src.plen;
+#endif
 		ipv6_addr_copy(&nrt->rt6i_dst.addr, daddr);
 		nrt->rt6i_dst.plen = 128;
+#ifdef CONFIG_IPV6_SUBTREES
+		ipv6_addr_copy(&nrt->rt6i_src.addr, &rt->rt6i_src.addr);
+		nrt->rt6i_src.plen = rt->rt6i_src.plen;
+		ipv6_wash_prefix(&rt->rt6i_src.addr, rt->rt6i_src.plen);
+#endif
 		nrt->u.dst.flags |= DST_HOST;
 		nrt->rt6i_nexthop = neigh_clone(rt->rt6i_nexthop);
 		dst_set_expires(&nrt->u.dst, ip6_rt_mtu_expires);
 		nrt->rt6i_flags |= RTF_DYNAMIC|RTF_CACHE|RTF_EXPIRES;
 		nrt->u.dst.pmtu = pmtu;
+		dst_hold(&nrt->u.dst);	/* hold this until it expires */
 		rt6_ins(nrt, NULL);
 	}
 
@@ -1152,6 +1594,49 @@
 	return rt;
 }
 
+int rt6_get_dfltrt(char *buffer, char **start, off_t offset, int length, int dummy)
+{
+/*
+ *      for /proc/net/rt6_default
+ */
+	int len = 0;
+	char buf1[128];
+	struct rt6_info *rt;
+
+#if !defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+	if (rt6_dflt_pointer) {
+		in6_ntop(&rt6_dflt_pointer->rt6i_gateway, buf1);
+		goto out;
+	}
+#endif
+
+	read_lock_bh(&rt6_lock);
+	for (rt = ip6_routing_table.leaf; rt; rt = rt->u.next) {
+		if (rt->rt6i_flags & RTF_DEFAULT) {
+			in6_ntop(&rt->rt6i_gateway, buf1);
+			break;
+		}
+		if (rt->u.next == NULL) {
+			strcpy(buf1, "no default router");
+			break;
+		}
+	}
+	read_unlock_bh(&rt6_lock);
+
+#if !defined(CONFIG_IPV6_NEW_ROUNDROBIN)
+out:
+#endif
+	len += sprintf(buffer+len, "%s\n", buf1);
+	*start = buffer + offset;
+	len -= offset;
+	if (len > length)
+		len = length;
+	return len;
+}
+
+
+
+
 struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *dev)
 {	
 	struct rt6_info *rt;
@@ -1172,7 +1657,8 @@
 }
 
 struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr,
-				     struct net_device *dev)
+				     struct net_device *dev,
+				     int pref)
 {
 	struct in6_rtmsg rtmsg;
 
@@ -1180,7 +1666,7 @@
 	rtmsg.rtmsg_type = RTMSG_NEWROUTE;
 	ipv6_addr_copy(&rtmsg.rtmsg_gateway, gwaddr);
 	rtmsg.rtmsg_metric = 1024;
-	rtmsg.rtmsg_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | RTF_UP;
+	rtmsg.rtmsg_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | RTF_UP | RTF_PREF(pref&3) | RTF_EXPIRES;
 
 	rtmsg.rtmsg_ifindex = dev->ifindex;
 
@@ -1204,9 +1690,11 @@
 		if (rt->rt6i_flags & flags) {
 			dst_hold(&rt->u.dst);
 
+#if !defined(CONFIG_IPV6_NEW_ROUNDROBIN)
 			spin_lock_bh(&rt6_dflt_lock);
 			rt6_dflt_pointer = NULL;
 			spin_unlock_bh(&rt6_dflt_lock);
+#endif
 
 			read_unlock_bh(&rt6_lock);
 
@@ -1252,14 +1740,46 @@
 	return -EINVAL;
 }
 
+#ifdef CONFIG_IPV6_ZONE
+int ipv6_zone_ioctl(unsigned int cmd, void *arg)
+{
+	struct ip6_zoneid zmsg __attribute__((unused));
+	int err = -EINVAL;
+
+	switch(cmd) {
+	case SIOCSIFZONE:
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		err = copy_from_user(&zmsg, arg, sizeof(zmsg));
+		if (err)
+			return -EFAULT;
+		err = ip6_set_zone(&zmsg);
+		break;
+
+	case SIOCGIFZONE:
+		err = copy_from_user(&zmsg, arg, sizeof(zmsg));
+		if (err)
+			return -EFAULT;
+		err = ip6_get_zone(&zmsg);
+		if (err == 0)
+			err = copy_to_user(arg, &zmsg, sizeof(zmsg));
+		break;
+	}
+	return err;
+}
+#endif
+
 /*
  *	Drop the packet on the floor
  */
 
 int ip6_pkt_discard(struct sk_buff *skb)
 {
-	IP6_INC_STATS(Ip6OutNoRoutes);
+	struct inet6_dev *idev = in6_dev_get(skb->dev);
+	IP6_INC_STATS(idev,Ip6OutNoRoutes);
 	icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, skb->dev);
+	if (idev)
+		in6_dev_put(idev);
 	kfree_skb(skb);
 	return 0;
 }
@@ -1280,6 +1800,13 @@
 	rt->u.dst.input = ip6_input;
 	rt->u.dst.output = ip6_output;
 	rt->rt6i_dev = dev_get_by_name("lo");
+	if (rt->rt6i_dev == NULL) {
+		if (net_ratelimit())
+			printk(KERN_WARNING
+				"ip6_rt_addr_addr(): cannot find loopback device.\n");
+		dst_free((struct dst_entry *) rt);
+		return -ENODEV;
+	}
 	rt->u.dst.pmtu = ipv6_get_mtu(rt->rt6i_dev);
 	rt->u.dst.advmss = max_t(unsigned int, rt->u.dst.pmtu - 60, ip6_rt_min_advmss);
 	if (rt->u.dst.advmss > 65535-20)
@@ -1310,7 +1837,7 @@
 	struct rt6_info *rt;
 	int err = -ENOENT;
 
-	rt = rt6_lookup(addr, NULL, loopback_dev.ifindex, 1);
+	rt = rt6_lookup(addr, NULL, loopback_dev.ifindex, RT6_LOOKUP_FLAG_STRICT);
 	if (rt) {
 		if (rt->rt6i_dst.plen == 128)
 			err = ip6_del_rt(rt, NULL);
@@ -1394,7 +1921,7 @@
 				frule = sprt->rt6i_flowr;
 #if RT6_DEBUG >= 2
 				if (frule == NULL) {
-					printk(KERN_DEBUG "NULL flowr\n");
+					RDBG1(KERN_DEBUG "NULL flowr\n");
 					goto error;
 				}
 #endif
@@ -1440,7 +1967,7 @@
 {
 	if (((void*)rt->rt6i_dev == arg || arg == NULL) &&
 	    rt != &ip6_null_entry) {
-		RT6_TRACE("deleted by ifdown %p\n", rt);
+		RT6_TRACE3(KERN_DEBUG "deleted by ifdown %p\n", rt);
 		return -1;
 	}
 	return 0;
@@ -1639,7 +2166,7 @@
 		RTA_PUT(skb, RTA_IIF, 4, &iif);
 	else if (dst) {
 		struct in6_addr saddr_buf;
-		if (ipv6_get_saddr(&rt->u.dst, dst, &saddr_buf) == 0)
+		if (ipv6_get_saddr(&rt->u.dst, dst, &saddr_buf, 0) == 0)
 			RTA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
 	}
 	if (rtnetlink_put_metrics(skb, &rt->u.dst.mxlock) < 0)
@@ -1749,7 +2276,7 @@
 		w = kmalloc(sizeof(*w), GFP_ATOMIC);
 		if (w == NULL)
 			return -ENOMEM;
-		RT6_TRACE("dump<%p", w);
+		RT6_TRACE3(KERN_DEBUG "dump<%p", w);
 		memset(w, 0, sizeof(*w));
 		w->root = &ip6_routing_table;
 		w->func = fib6_dump_node;
@@ -1766,7 +2293,7 @@
 	}
 #if RT6_DEBUG >= 3
 	if (res <= 0 && skb->len == 0)
-		RT6_TRACE("%p>dump end\n", w);
+		RT6_TRACE3("%p>dump end\n", w);
 #endif
 	res = res < 0 ? res : skb->len;
 	/* res < 0 is an error. (really, impossible)
@@ -2037,7 +2564,7 @@
          &proc_dointvec_jiffies, &sysctl_jiffies},
 	{NET_IPV6_ROUTE_MIN_ADVMSS, "min_adv_mss",
          &ip6_rt_min_advmss, sizeof(int), 0644, NULL,
-         &proc_dointvec_jiffies, &sysctl_jiffies},
+         &proc_dointvec},
 	 {0}
 };
 
@@ -2067,5 +2594,13 @@
 
 	rt6_ifdown(NULL);
 	fib6_gc_cleanup();
+	if (kmem_cache_destroy(ip6_dst_ops.kmem_cachep) == 0) {
+		RT6_TRACE3(KERN_DEBUG "%s(): kmem_cache %p for ip6_dst_cache destroyed.\n",
+				__FUNCTION__, ip6_dst_ops.kmem_cachep);
+		ip6_dst_ops.kmem_cachep = NULL;
+	} else {
+		RT6_TRACE1(KERN_WARNING "%s(): failed to destroy kmem_cache %p for ip6_dst_cache.\n",
+				__FUNCTION__, ip6_dst_ops.kmem_cachep);
+	}
 }
 #endif	/* MODULE */
diff -urN linux-2.4.29/net/ipv6/sit.c linux-2.4.29-uc1/net/ipv6/sit.c
--- linux-2.4.29/net/ipv6/sit.c	2005-01-19 14:10:14.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/sit.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: sit.c,v 1.24 2003/11/21 20:13:13 yoshfuji Exp $ */
+
 /*
  *	IPv6 over IPv4 tunnel device - Simple Internet Transition (SIT)
  *	Linux INET6 implementation
@@ -14,8 +16,8 @@
  *      2 of the License, or (at your option) any later version.
  *
  *	Changes:
- * Roger Venning <r.venning@telstra.com>:	6to4 support
- * Nate Thompson <nate@thebog.net>:		6to4 support
+ *		Roger Venning <r.venning@telstra.com>,
+ *		Nate Thompson <nate@thebog.net>:	6to4 support
  */
 
 #include <linux/config.h>
@@ -56,6 +58,10 @@
    For comments look at net/ipv4/ip_gre.c --ANK
  */
 
+#ifdef CONFIG_NET_IPIP_IPV6
+extern rwlock_t ipip_lock;
+#else
+
 #define HASH_SIZE  16
 #define HASH(addr) ((addr^(addr>>4))&0xF)
 
@@ -103,10 +109,10 @@
 	return NULL;
 }
 
-static struct ip_tunnel ** ipip6_bucket(struct ip_tunnel *t)
+static __inline__ struct ip_tunnel ** __ipip6_bucket(struct ip_tunnel_parm *parms)
 {
-	u32 remote = t->parms.iph.daddr;
-	u32 local = t->parms.iph.saddr;
+	u32 remote = parms->iph.daddr;
+	u32 local = parms->iph.saddr;
 	unsigned h = 0;
 	int prio = 0;
 
@@ -121,6 +127,11 @@
 	return &tunnels[prio][h];
 }
 
+static struct ip_tunnel ** ipip6_bucket(struct ip_tunnel *t)
+{
+	return __ipip6_bucket(&t->parms);
+}
+
 static void ipip6_tunnel_unlink(struct ip_tunnel *t)
 {
 	struct ip_tunnel **tp;
@@ -151,18 +162,8 @@
 	u32 local = parms->iph.saddr;
 	struct ip_tunnel *t, **tp, *nt;
 	struct net_device *dev;
-	unsigned h = 0;
-	int prio = 0;
 
-	if (remote) {
-		prio |= 2;
-		h ^= HASH(remote);
-	}
-	if (local) {
-		prio |= 1;
-		h ^= HASH(local);
-	}
-	for (tp = &tunnels[prio][h]; (t = *tp) != NULL; tp = &t->next) {
+	for (tp = __ipip6_bucket(parms); (t = *tp) != NULL; tp = &t->next) {
 		if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr)
 			return t;
 	}
@@ -228,7 +229,7 @@
 		dev_put(dev);
 	}
 }
-
+#endif	/* !CONFIG_NET_IPIP_IPV6 */
 
 void ipip6_err(struct sk_buff *skb, u32 info)
 {
@@ -271,8 +272,13 @@
 		break;
 	}
 
+#ifdef CONFIG_NET_IPIP_IPV6
+	read_lock(&ipip_lock);
+	t = ipip_tunnel_lookup(iph->daddr, iph->saddr);
+#else
 	read_lock(&ipip6_lock);
 	t = ipip6_tunnel_lookup(iph->daddr, iph->saddr);
+#endif
 	if (t == NULL || t->parms.iph.daddr == 0)
 		goto out;
 	if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
@@ -284,7 +290,11 @@
 		t->err_count = 1;
 	t->err_time = jiffies;
 out:
+#ifdef CONFIG_NET_IPIP_IPV6
+	read_unlock(&ipip_lock);
+#else
 	read_unlock(&ipip6_lock);
+#endif
 	return;
 #else
 	struct iphdr *iph = (struct iphdr*)dp;
@@ -390,8 +400,14 @@
 
 	iph = skb->nh.iph;
 
+#ifdef CONFIG_NET_IPIP_IPV6
+	read_lock(&ipip_lock);
+	tunnel = ipip_tunnel_lookup(iph->saddr, iph->daddr);
+#else
 	read_lock(&ipip6_lock);
-	if ((tunnel = ipip6_tunnel_lookup(iph->saddr, iph->daddr)) != NULL) {
+	tunnel = ipip6_tunnel_lookup(iph->saddr, iph->daddr);
+#endif
+	if (tunnel != NULL) {
 		skb->mac.raw = skb->nh.raw;
 		skb->nh.raw = skb->data;
 		memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
@@ -405,17 +421,26 @@
 		nf_reset(skb);
 		ipip6_ecn_decapsulate(iph, skb);
 		netif_rx(skb);
+#ifdef CONFIG_NET_IPIP_IPV6
+		read_unlock(&ipip_lock);
+#else
 		read_unlock(&ipip6_lock);
+#endif
 		return 0;
 	}
 
 	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0);
 	kfree_skb(skb);
+#ifdef CONFIG_NET_IPIP_IPV6
+	read_unlock(&ipip_lock);
+#else
 	read_unlock(&ipip6_lock);
+#endif
 out:
 	return 0;
 }
 
+#ifndef CONFIG_NET_IPIP_IPV6
 /* Need this wrapper because NF_HOOK takes the function address */
 static inline int do_ip_send(struct sk_buff *skb)
 {
@@ -489,10 +514,13 @@
 			addr_type = ipv6_addr_type(addr6);
 		}
 
-		if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
+		if (addr_type & IPV6_ADDR_COMPATv4)
+			dst = addr6->s6_addr32[3];
+		else
+#ifdef CONFIG_IPV6_6TO4_NEXTHOP
+		if (!(dst = try_6to4(addr6)))
+#endif
 			goto tx_error_icmp;
-
-		dst = addr6->s6_addr32[3];
 	}
 
 	if (ip_route_output(&rt, dst, tiph->saddr, RT_TOS(tos), tunnel->parms.link)) {
@@ -850,3 +878,4 @@
 	inet_add_protocol(&sit_protocol);
 	return 0;
 }
+#endif	/* !CONFIG_NET_IPIP_IPV6 */
diff -urN linux-2.4.29/net/ipv6/sysctl_net_ipv6.c linux-2.4.29-uc1/net/ipv6/sysctl_net_ipv6.c
--- linux-2.4.29/net/ipv6/sysctl_net_ipv6.c	2004-04-14 14:05:41.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv6/sysctl_net_ipv6.c	2005-06-14 02:11:52.000000000 +0100
@@ -24,6 +24,17 @@
 	{NET_IPV6_ICMP, "icmp", NULL, 0, 0500, ipv6_icmp_table},
 	{NET_IPV6_BINDV6ONLY, "bindv6only",
 	 &sysctl_ipv6_bindv6only, sizeof(int), 0644, NULL, &proc_dointvec},
+	{NET_IPV6_IP6FRAG_HIGH_THRESH, "ip6frag_high_thresh",
+	 &sysctl_ip6frag_high_thresh, sizeof(int), 0644, NULL, &proc_dointvec},
+	{NET_IPV6_IP6FRAG_LOW_THRESH, "ip6frag_low_thresh",
+	 &sysctl_ip6frag_low_thresh, sizeof(int), 0644, NULL, &proc_dointvec},
+	{NET_IPV6_IP6FRAG_TIME, "ip6frag_time",
+	 &sysctl_ip6frag_time, sizeof(int), 0644, NULL, &proc_dointvec_jiffies,
+	 &sysctl_jiffies},
+#ifdef CONFIG_IPV6_RESTRICTED_DOUBLE_BIND
+	{NET_IPV6_BINDV6ONLY_RESTRICTION, "bindv6only_restriction",
+	 &sysctl_ipv6_bindv6only_restriction, sizeof(int), 0644, NULL, &proc_dointvec},
+#endif
 	{NET_IPV6_MLD_MAX_MSF, "mld_max_msf",
 	 &sysctl_mld_max_msf, sizeof(int), 0644, NULL, &proc_dointvec},
 	{0}
diff -urN linux-2.4.29/net/ipv6/tcp_ipv6.c linux-2.4.29-uc1/net/ipv6/tcp_ipv6.c
--- linux-2.4.29/net/ipv6/tcp_ipv6.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/tcp_ipv6.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: tcp_ipv6.c,v 1.86 2003/11/12 05:12:02 yoshfuji Exp $ */
+
 /*
  *	TCP over IPv6
  *	Linux INET6 implementation 
@@ -14,9 +16,20 @@
  *
  *	Fixes:
  *	Hideaki YOSHIFUJI	:	sin6_scope_id support
- *	YOSHIFUJI Hideaki @USAGI and:	Support IPV6_V6ONLY socket option, which
- *	Alexey Kuznetsov		allow both IPv4 and IPv6 sockets to bind
- *					a single port at the same time.
+ *	yoshfuji@USAGI		:	Reworked bind(2) behavior, including:
+ *					- Allow ipv6 and ipv4 bind(2) to the
+ *					  same port.
+ *					- Don't allow narrow binding unless
+ *					  later uid is the same as before:
+ *					  CONFIG_NET_RESTRICTED_REUSE
+ *					- Don't allow binding to the same
+ *					  address unless it is one of multi-
+ *					  cast address even if SO_REUSEADDR 
+ *					  is set.
+ *
+ * 	Changes:
+ * 	Kazunori MIYAZAWA <miyazawa@linux-ipv6.org> / USAGI : IPsec support
+ * 	Mitsuru KANDA <mk@linux-ipv6.org> / USAGI : IPsec support
  *
  *	This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -94,6 +107,9 @@
 {
 	struct tcp_bind_hashbucket *head;
 	struct tcp_bind_bucket *tb;
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+	uid_t sk_uid = sk->state != TCP_TIME_WAIT ? sock_i_uid_t(sk) : ((struct tcp_tw_bucket *)sk)->uid;
+#endif
 	int ret;
 
 	local_bh_disable();
@@ -136,15 +152,138 @@
 				break;
 	}
 	if (tb != NULL && tb->owners != NULL) {
-		if (tb->fastreuse > 0 && sk->reuse != 0 && sk->state != TCP_LISTEN) {
+		if (tb->fastreuse > 0 && 
+		    (sk->reuse != 0
+#ifdef SO_REUSEPORT
+		     || sk->reuseport != 0
+#endif
+		    ) &&
+#if defined(CONFIG_NET_RESTRICTED_REUSE)
+		    sk_uid == tb->uid &&
+#endif
+		    sk->state != TCP_LISTEN) {
 			goto success;
 		} else {
 			struct sock *sk2 = tb->owners;
-			int sk_reuse = sk->reuse;
-			int addr_type = ipv6_addr_type(&sk->net_pinfo.af_inet6.rcv_saddr);
+			int sk_reuse, sk2_reuse;
+			struct in6_addr *sk_rcv_saddr6 = sk->state != TCP_TIME_WAIT ? 
+								&sk->net_pinfo.af_inet6.rcv_saddr:
+								&((struct tcp_tw_bucket*)sk)->v6_rcv_saddr;
+			int addr_type = ipv6_addr_type(sk_rcv_saddr6),
+			    addr_type2;
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+			uid_t sk2_uid;
+#endif
+
+			sk_reuse = 0;
+			if (sk->reuse)
+				sk_reuse |= 1;
+#ifdef SO_REUSEPORT
+			if (sk->reuseport)
+				sk_reuse |= 2;
+#endif
+#if 0
+			if (sk_reuse &&
+			    (addr_type != IPV6_ADDR_MAPPED ? (addr_type & IPV6_ADDR_MULTICAST) : MULTICAST(sk->rcv_saddr)))
+				sk_reuse |= 4;
+#endif
 
 			/* We must walk the whole port owner list in this case. -DaveM */
 			for( ; sk2 != NULL; sk2 = sk2->bind_next) {
+#if 1	/* XXX: convert like 2.4.21 */
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+				int uid_ok;
+#endif
+				int both_specified = 0;
+				struct in6_addr *sk2_rcv_saddr6;
+				if (sk2 == sk ||
+				    (sk2->bound_dev_if && sk->bound_dev_if &&
+				     sk2->bound_dev_if != sk->bound_dev_if))
+					continue;
+#if 0
+				if (sk2->family != AF_INET6 && sk2->family != AF_INET)
+					continue;
+#endif
+				sk2_rcv_saddr6 = sk2->state != TCP_TIME_WAIT ?
+							&sk2->net_pinfo.af_inet6.rcv_saddr :
+							&((struct tcp_tw_bucket*)sk2)->v6_rcv_saddr;
+				addr_type2 = sk2->family == AF_INET6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED;
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+				sk2_uid = sk2->state != TCP_TIME_WAIT ? sock_i_uid_t(sk2) : ((struct tcp_tw_bucket *)sk2)->uid;
+#endif
+
+				if ((addr_type2 != IPV6_ADDR_MAPPED ? addr_type2 != IPV6_ADDR_ANY : sk2->rcv_saddr) &&
+				    (addr_type != IPV6_ADDR_MAPPED ? addr_type != IPV6_ADDR_ANY : sk->rcv_saddr)) {
+					if (addr_type2 == IPV6_ADDR_MAPPED || addr_type == IPV6_ADDR_MAPPED) {
+						if (addr_type2 != addr_type ||
+						    sk2->rcv_saddr != sk->rcv_saddr)
+							continue;
+					} else {
+						if (ipv6_addr_cmp(sk2_rcv_saddr6, sk_rcv_saddr6))
+							continue;
+					}
+					both_specified = 1;
+				}
+
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+				uid_ok = sk2_uid == (uid_t) -1 || sk_uid == sk2_uid;
+#endif
+
+				if ((addr_type2 == IPV6_ADDR_MAPPED && 
+				     addr_type != IPV6_ADDR_MAPPED && __ipv6_only_sock(sk)) ||
+				    (addr_type == IPV6_ADDR_MAPPED &&
+				     addr_type2 != IPV6_ADDR_MAPPED && __ipv6_only_sock(sk2))) {
+#ifdef CONFIG_IPV6_RESTRICTED_DOUBLE_BIND
+					if (sysctl_ipv6_bindv6only_restriction == 0 || uid_ok)
+						continue;
+#else
+					continue;
+#endif
+				}
+
+				sk2_reuse = 0;
+				if (sk2->reuse)
+					sk2_reuse |= 1;
+#ifdef SO_REUSEPORT
+				if (sk2->reuseport)
+					sk2_reuse |= 2;
+#endif
+#if 0
+				if (sk2_reuse &&
+				    (addr_type2 != IPV6_ADDR_MAPPED ? (addr_type2 & IPV6_ADDR_MULTICAST) : MULTICAST(sk2->rcv_saddr)))
+					sk2_reuse |= 4;
+#endif
+
+				if (sk2_reuse & sk_reuse & 3) {	/* NOT && */
+					ret = 1;
+#if 0
+					if (sk2_reuse & sk_reuse & 4)
+						continue;
+#endif
+#ifdef CONFIG_NET_RESTRICTED_REUSE
+					if (!uid_ok)
+						goto fail_unlock;
+#endif
+#ifdef SO_REUSEPORT
+					if (sk2_reuse & sk_reuse & 2)
+						continue;
+#endif
+					if (both_specified) {
+						struct in6_addr *sk2_daddr6 = sk2->state != TCP_TIME_WAIT ?
+										&sk2->net_pinfo.af_inet6.daddr :
+										&((struct tcp_tw_bucket*)sk2)->v6_daddr;
+						int addr_type2d = sk2->family == AF_INET6 ? ipv6_addr_type(sk2_daddr6) : IPV6_ADDR_MAPPED;
+						if (addr_type2d != IPV6_ADDR_MAPPED ? addr_type2d != IPV6_ADDR_ANY : sk2->daddr)
+							continue;
+					} else {
+						if ((addr_type2 != IPV6_ADDR_MAPPED ? addr_type2 != IPV6_ADDR_ANY : sk2->rcv_saddr) || 
+						    (addr_type != IPV6_ADDR_MAPPED ? addr_type != IPV6_ADDR_ANY : sk->rcv_saddr))
+							continue;
+					}
+				}
+				ret = 1;
+				goto fail_unlock;
+#else	/* XXX: convert like 2.4.21 */
 				if (sk != sk2 &&
 				    (!sk->bound_dev_if ||
 				     !sk2->bound_dev_if ||
@@ -173,6 +312,7 @@
 							break;
 					}
 				}
+#endif	/* XXX: convert like 2.4.21 */
 			}
 			/* If we found a conflict, fail. */
 			ret = 1;
@@ -185,12 +325,27 @@
 	    (tb = tcp_bucket_create(head, snum)) == NULL)
 			goto fail_unlock;
 	if (tb->owners == NULL) {
-		if (sk->reuse && sk->state != TCP_LISTEN)
+		if ((sk->reuse 
+#ifdef SO_REUSEPORT
+		     || sk->reuseport
+#endif
+		    ) && sk->state != TCP_LISTEN) {
 			tb->fastreuse = 1;
-		else
+#if defined(CONFIG_NET_RESTRICTED_REUSE)
+			tb->uid = sk_uid;
+#endif
+		} else
 			tb->fastreuse = 0;
 	} else if (tb->fastreuse &&
-		   ((sk->reuse == 0) || (sk->state == TCP_LISTEN)))
+		   ((sk->reuse == 0
+#ifdef SO_REUSEPORT
+		     && sk_reuseport == 0
+#endif
+		     ) ||
+#if defined(CONFIG_NET_RESTRICTED_REUSE)
+		    (sk_uid != tb->uid) ||
+#endif
+		    (sk->state == TCP_LISTEN)))
 		tb->fastreuse = 0;
 
 success:
@@ -557,6 +712,7 @@
 	struct flowi fl;
 	struct dst_entry *dst;
 	int addr_type;
+	int reroute = 0;
 	int err;
 
 	if (addr_len < SIN6_LEN_RFC2133) 
@@ -565,7 +721,8 @@
 	if (usin->sin6_family != AF_INET6) 
 		return(-EAFNOSUPPORT);
 
-	fl.fl6_flowlabel = 0;
+        memset(&fl, 0, sizeof(fl));
+
 	if (np->sndflow) {
 		fl.fl6_flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
 		IP6_ECN_flow_init(fl.fl6_flowlabel);
@@ -604,9 +761,11 @@
 			sk->bound_dev_if = usin->sin6_scope_id;
 		}
 
+#ifndef CONFIG_IPV6_LOOSE_SCOPE_ID
 		/* Connect to link-local address requires an interface */
 		if (sk->bound_dev_if == 0)
 			return -EINVAL;
+#endif
 	}
 
 	if (tp->ts_recent_stamp && ipv6_addr_cmp(&np->daddr, &usin->sin6_addr)) {
@@ -672,30 +831,52 @@
 
 	dst = ip6_route_output(sk, &fl);
 
+#ifdef CONFIG_IPV6_SUBTREES
+	reroute = (saddr == NULL);
+#endif
 	if ((err = dst->error) != 0) {
 		dst_release(dst);
 		goto failure;
 	}
-
-	ip6_dst_store(sk, dst, NULL);
-	sk->route_caps = dst->dev->features&~NETIF_F_IP_CSUM;
+	if (!reroute) {
+		ip6_dst_store(sk, dst, NULL, NULL);
+		sk->route_caps = dst->dev->features&~NETIF_F_IP_CSUM;
+	}
 
 	if (saddr == NULL) {
-		err = ipv6_get_saddr(dst, &np->daddr, &saddr_buf);
+		err = ipv6_get_saddr(dst, &np->daddr, &saddr_buf, np->use_tempaddr);
+
+
+		if (reroute)
+			dst_release(dst);
 		if (err)
 			goto failure;
 
 		saddr = &saddr_buf;
+#ifdef CONFIG_IPV6_SUBTREES
+		if (saddr) fl.fl6_src = saddr;
+		dst = ip6_route_output(sk, &fl);
+
+		if ((err = dst->error) != 0) {
+			dst_release(dst);
+			goto failure;
+		}
+		ip6_dst_store(sk, dst, NULL, NULL);
+		sk->route_caps = dst->dev->features&~NETIF_F_IP_CSUM;
+#endif
+		ipv6_addr_copy(&np->rcv_saddr, saddr);
 	}
 
 	/* set the source address */
-	ipv6_addr_copy(&np->rcv_saddr, saddr);
 	ipv6_addr_copy(&np->saddr, saddr);
 	sk->rcv_saddr= LOOPBACK4_IPV6;
 
 	tp->ext_header_len = 0;
-	if (np->opt)
-		tp->ext_header_len = np->opt->opt_flen+np->opt->opt_nflen;
+	{
+		if (np->opt)
+			tp->ext_header_len += np->opt->opt_flen +
+				np->opt->opt_nflen;
+	}
 	tp->mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
 
 	sk->dport = usin->sin6_port;
@@ -738,7 +919,10 @@
 	sk = tcp_v6_lookup(&hdr->daddr, th->dest, &hdr->saddr, th->source, skb->dev->ifindex);
 
 	if (sk == NULL) {
-		ICMP6_INC_STATS_BH(Icmp6InErrors);
+		struct inet6_dev *idev = in6_dev_get(skb->dev);
+		ICMP6_INC_STATS_BH(idev,Icmp6InErrors);
+		if (idev)
+			in6_dev_put(idev);
 		return;
 	}
 
@@ -1338,7 +1522,8 @@
 #endif
 	MOD_INC_USE_COUNT;
 
-	ip6_dst_store(newsk, dst, NULL);
+		ip6_dst_store(newsk, dst, NULL, NULL);
+
 	sk->route_caps = dst->dev->features&~NETIF_F_IP_CSUM;
 
 	newtp = &(newsk->tp_pinfo.af_tcp);
@@ -1384,9 +1569,11 @@
 	}
 
 	newtp->ext_header_len = 0;
-	if (np->opt)
-		newtp->ext_header_len = np->opt->opt_nflen + np->opt->opt_flen;
-
+	{
+		if (np->opt)
+			newtp->ext_header_len += np->opt->opt_nflen +
+				np->opt->opt_flen;
+	}
 	tcp_sync_mss(newsk, dst->pmtu);
 	newtp->advmss = dst->advmss;
 	tcp_initialize_rcv_mss(newsk);
@@ -1442,6 +1629,8 @@
 static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
 {
 	struct sk_buff *opt_skb = NULL;
+	struct net_device *dev;
+	struct inet6_dev *idev;
 
 	/* Imagine: socket is IPv6. IPv4 packet arrives,
 	   goes to IPv4 receive handler and backlogged.
@@ -1459,7 +1648,14 @@
 	 *	is currently called with bh processing disabled.
 	 */
 
-  	IP6_INC_STATS_BH(Ip6InDelivers);
+	dev = dev_get_by_index(tcp_v6_iif(skb));
+	idev = dev ? in6_dev_get(dev) : NULL;
+  	IP6_INC_STATS_BH(idev,Ip6InDelivers);
+	if (dev) {
+		if (idev)
+			in6_dev_put(idev);
+		dev_put(dev);
+	}
 
 	/* Do Stevens' IPV6_PKTOPTIONS.
 
@@ -1710,7 +1906,8 @@
 			return err;
 		}
 
-		ip6_dst_store(sk, dst, NULL);
+		ip6_dst_store(sk, dst, NULL, NULL);
+
 		sk->route_caps = dst->dev->features&~NETIF_F_IP_CSUM;
 	}
 
@@ -1749,7 +1946,8 @@
 			return -sk->err_soft;
 		}
 
-		ip6_dst_store(sk, dst, NULL);
+		ip6_dst_store(sk, dst, NULL, NULL);
+
 	}
 
 	skb->dst = dst_clone(dst);
@@ -1766,7 +1964,7 @@
 	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr;
 
 	sin6->sin6_family = AF_INET6;
-	memcpy(&sin6->sin6_addr, &np->daddr, sizeof(struct in6_addr));
+	ipv6_addr_copy(&sin6->sin6_addr, &np->daddr);
 	sin6->sin6_port	= sk->dport;
 	/* We do not store received flowlabel for TCP */
 	sin6->sin6_flowinfo = 0;
diff -urN linux-2.4.29/net/ipv6/udp.c linux-2.4.29-uc1/net/ipv6/udp.c
--- linux-2.4.29/net/ipv6/udp.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/ipv6/udp.c	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: udp.c,v 1.63 2003/11/12 05:12:02 yoshfuji Exp $ */
+
 /*
  *	UDP over IPv6
  *	Linux INET6 implementation 
@@ -11,9 +13,16 @@
  *
  *	Fixes:
  *	Hideaki YOSHIFUJI	:	sin6_scope_id support
- *	YOSHIFUJI Hideaki @USAGI and:	Support IPV6_V6ONLY socket option, which
- *	Alexey Kuznetsov		allow both IPv4 and IPv6 sockets to bind
- *					a single port at the same time.
+ *	yoshfuji@USAGI		:	Reworked bind(2) behavior, including:
+ *					- Allow ipv6 and ipv4 bind(2) to the
+ *					  same port.
+ *					- Don't allow narrow binding unless
+ *					  later uid is the same as before:
+ *					  CONFIG_NET_RESTRICTED_REUSE
+ *					- Don't allow binding to the same
+ *					  address unless it is one of multi-
+ *					  cast address even if SO_REUSEADDR 
+ *					  is set.
  *
  *	This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -29,6 +38,9 @@
 #include <linux/sched.h>
 #include <linux/net.h>
 #include <linux/in6.h>
+#ifdef CONFIG_IPV6_DEBUG
+#include <linux/inet.h>
+#endif
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/ipv6.h>
@@ -101,11 +113,113 @@
 		udp_port_rover = snum = result;
 	} else {
 		struct sock *sk2;
-		int addr_type = ipv6_addr_type(&sk->net_pinfo.af_inet6.rcv_saddr);
+		int sk_reuse, sk2_reuse;
+		int addr_type = ipv6_addr_type(&sk->net_pinfo.af_inet6.rcv_saddr),
+		    addr_type2;
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+		uid_t sk_uid = sock_i_uid_t(sk),
+		      sk2_uid;
+#endif
+
+		sk_reuse = 0;
+		if (sk->reuse)
+			sk_reuse |= 1;
+#ifdef SO_REUSEPORT
+		if (sk->reuseport)
+			sk_reuse |= 2;
+#endif
+		if (sk_reuse &&
+		    (addr_type != IPV6_ADDR_MAPPED ? (addr_type & IPV6_ADDR_MULTICAST) : MULTICAST(sk->rcv_saddr)))
+			sk_reuse |= 4;
 
 		for (sk2 = udp_hash[snum & (UDP_HTABLE_SIZE - 1)];
 		     sk2 != NULL;
 		     sk2 = sk2->next) {
+#if 1	/* XXX: should be recoded like 2.4.21 */
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+			int uid_ok;
+#endif
+			int both_specified = 0;
+
+			if (sk2->num != snum ||
+			    sk2 == sk ||
+			    (sk2->bound_dev_if && sk->bound_dev_if &&
+			     sk2->bound_dev_if != sk->bound_dev_if))
+				continue;
+#if 0
+			if (sk2->family != AF_INET6 && sk2->family != AF_INET)
+				continue;
+#endif
+
+			addr_type2 = sk2->family == AF_INET6 ? ipv6_addr_type(&sk2->net_pinfo.af_inet6.rcv_saddr) : IPV6_ADDR_MAPPED;
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+			sk2_uid = sock_i_uid_t(sk2);
+#endif
+
+			if ((addr_type2 != IPV6_ADDR_MAPPED ? addr_type2 != IPV6_ADDR_ANY : sk2->rcv_saddr) &&
+			    (addr_type != IPV6_ADDR_MAPPED ? addr_type != IPV6_ADDR_ANY : sk->rcv_saddr)) {
+				if (addr_type2 == IPV6_ADDR_MAPPED || addr_type == IPV6_ADDR_MAPPED) {
+					if (addr_type2 != addr_type ||
+					    sk2->rcv_saddr != sk->rcv_saddr)
+						continue;
+				} else {
+					if (ipv6_addr_cmp(&sk2->net_pinfo.af_inet6.rcv_saddr,
+							  &sk->net_pinfo.af_inet6.rcv_saddr))
+						continue;
+				}
+				both_specified = 1;
+			}
+
+#if defined(CONFIG_NET_RESTRICTED_REUSE) || defined(CONFIG_IPV6_RESTRICTED_DOUBLE_BIND)
+			uid_ok = sk2_uid == (uid_t) -1 || sk_uid == sk2_uid;
+#endif
+
+			if ((addr_type2 == IPV6_ADDR_MAPPED && 
+			     addr_type != IPV6_ADDR_MAPPED && sk->net_pinfo.af_inet6.ipv6only) ||
+			    (addr_type == IPV6_ADDR_MAPPED &&
+			     addr_type2 != IPV6_ADDR_MAPPED && sk2->net_pinfo.af_inet6.ipv6only)) {
+#ifdef CONFIG_IPV6_RESTRICTED_DOUBLE_BIND
+				if (sysctl_ipv6_bindv6only_restriction == 0 || uid_ok)
+					continue;
+#else
+				continue;
+#endif
+			}
+
+			sk2_reuse = 0;
+			if (sk2->reuse)
+				sk2_reuse |= 1;
+#ifdef SO_REUSEPORT
+			if (sk2->reuseport)
+				sk2_reuse |= 2;
+#endif
+			if (sk2_reuse &&
+			    (addr_type2 != IPV6_ADDR_MAPPED ? (addr_type2 & IPV6_ADDR_MULTICAST) : MULTICAST(sk2->rcv_saddr)))
+				sk2_reuse |= 4;
+
+			if (sk2_reuse & sk_reuse & 3) {	/* NOT && */
+				if (sk2_reuse & sk_reuse & 4)
+					continue;
+#ifdef CONFIG_NET_RESTRICTED_REUSE
+				if (!uid_ok)
+					goto fail;
+#endif
+#ifdef SO_REUSEPORT
+				if (sk2_reuse & sk_reuse & 2)
+					continue;
+#endif
+				if (both_specified) {
+					int addr_type2d = sk2->family == AF_INET6 ? ipv6_addr_type(&sk2->net_pinfo.af_inet6.daddr) : IPV6_ADDR_MAPPED;
+					if (addr_type2d != IPV6_ADDR_MAPPED ? addr_type2d != IPV6_ADDR_ANY : sk2->daddr)
+						continue;
+				} else {
+					if ((addr_type2 != IPV6_ADDR_MAPPED ? addr_type2 != IPV6_ADDR_ANY : sk2->rcv_saddr) || 
+					    (addr_type != IPV6_ADDR_MAPPED ? addr_type != IPV6_ADDR_ANY : sk->rcv_saddr))
+						continue;
+				}
+			}
+			goto fail;
+#else	/* XXX: should be recoded like 2.4.21 */
 			if (sk2->num == snum &&
 			    sk2 != sk &&
 			    (!sk2->bound_dev_if ||
@@ -128,6 +242,7 @@
 			       sk->rcv_saddr == sk2->rcv_saddr))) &&
 			    (!sk2->reuse || !sk->reuse))
 				goto fail;
+#endif	/* XXX: should be recoded like 2.4.21 */
 		}
 	}
 
@@ -232,6 +347,7 @@
 	struct ip6_flowlabel	*flowlabel = NULL;
 	int			addr_type;
 	int			err;
+	int			reroute = 0;
 
 	if (usin->sin6_family == AF_INET) {
 		if (__ipv6_only_sock(sk))
@@ -314,9 +430,13 @@
 				fl.oif = np->mcast_oif;
 		}
 
+#ifndef CONFIG_IPV6_LOOSE_SCOPE_ID
 		/* Connect to link-local address requires an interface */
-		if (sk->bound_dev_if == 0)
+		if (sk->bound_dev_if == 0){
+			fl6_sock_release(flowlabel);
 			return -EINVAL;
+		}
+#endif
 	}
 
 	ipv6_addr_copy(&np->daddr, daddr);
@@ -357,13 +477,24 @@
 		return err;
 	}
 
-	ip6_dst_store(sk, dst, fl.fl6_dst);
-
 	/* get the source adddress used in the apropriate device */
 
-	err = ipv6_get_saddr(dst, daddr, &saddr);
+	err = ipv6_get_saddr(dst, daddr, &saddr, np->use_tempaddr);
+
+	if (reroute)
+		dst_release(dst);
 
 	if (err == 0) {
+#ifdef CONFIG_IPV6_SUBTREES
+		if (reroute) {
+			dst = ip6_route_output(sk, &fl);
+			if ((err = dst->error) != 0) {
+				dst_release(dst);
+				fl6_sock_release(flowlabel);
+				return err; 
+			} 
+		}
+#endif
 		if(ipv6_addr_any(&np->saddr))
 			ipv6_addr_copy(&np->saddr, &saddr);
 
@@ -371,6 +502,9 @@
 			ipv6_addr_copy(&np->rcv_saddr, &saddr);
 			sk->rcv_saddr = LOOPBACK4_IPV6;
 		}
+		ip6_dst_store(sk, dst, &np->daddr, 
+			      !ipv6_addr_cmp(fl.fl6_src, &np->saddr) ?
+			      &np->saddr : NULL);
 		sk->state = TCP_ESTABLISHED;
 	}
 	fl6_sock_release(flowlabel);
@@ -445,8 +579,7 @@
 			if (sk->protinfo.af_inet.cmsg_flags)
 				ip_cmsg_recv(msg, skb);
 		} else {
-			memcpy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr,
-			       sizeof(struct in6_addr));
+			ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr);
 
 			if (sk->net_pinfo.af_inet6.rxopt.all)
 				datagram_recv_ctl(sk, msg, skb);
@@ -524,10 +657,13 @@
 
 static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
 {
+	struct inet6_dev *idev = in6_dev_get(skb->dev);
 	if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
 		if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
 			UDP6_INC_STATS_BH(UdpInErrors);
-			IP6_INC_STATS_BH(Ip6InDiscards);
+			IP6_INC_STATS_BH(idev,Ip6InDiscards);
+			if (idev)
+				in6_dev_put(idev);
 			kfree_skb(skb);
 			return 0;
 		}
@@ -535,12 +671,17 @@
 	}
 	if (sock_queue_rcv_skb(sk,skb)<0) {
 		UDP6_INC_STATS_BH(UdpInErrors);
-		IP6_INC_STATS_BH(Ip6InDiscards);
+		IP6_INC_STATS_BH(idev,Ip6InDiscards);
+		if (idev)
+			in6_dev_put(idev);
 		kfree_skb(skb);
 		return 0;
 	}
-  	IP6_INC_STATS_BH(Ip6InDelivers);
+  	IP6_INC_STATS_BH(idev,Ip6InDelivers);
 	UDP6_INC_STATS_BH(UdpInDatagrams);
+
+	if (idev)
+		in6_dev_put(idev);
 	return 0;
 }
 
@@ -615,16 +756,14 @@
 	struct sock *sk;
   	struct udphdr *uh;
 	struct net_device *dev = skb->dev;
-	struct in6_addr *saddr, *daddr;
+	struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
+	struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
 	u32 ulen = 0;
 
 	if (!pskb_may_pull(skb, sizeof(struct udphdr)))
 		goto short_packet;
 
-	saddr = &skb->nh.ipv6h->saddr;
-	daddr = &skb->nh.ipv6h->daddr;
 	uh = skb->h.uh;
-
 	ulen = ntohs(uh->len);
 
 	/* Check for jumbo payload */
@@ -696,8 +835,16 @@
 	return(0);
 
 short_packet:	
-	if (net_ratelimit())
-		printk(KERN_DEBUG "UDP: short packet: %d/%u\n", ulen, skb->len);
+	if (net_ratelimit()) {
+#ifdef CONFIG_IPV6_DEBUG
+		char sbuf[128], dbuf[128];
+		in6_ntop(saddr, sbuf);
+		in6_ntop(daddr, dbuf);
+		printk(KERN_DEBUG "UDPv6: short packet: %u/%u (%s->%s)\n", ulen, skb->len, sbuf, dbuf);
+#else
+		printk(KERN_DEBUG "UDPv6: short packet: %u/%u\n", ulen, skb->len);
+#endif
+	}
 
 discard:
 	UDP6_INC_STATS_BH(UdpInErrors);
@@ -732,6 +879,9 @@
 
 	dst = buff;
 
+	if (udh->wcheck == 0)
+		udh->uh.check = 0;
+
 	if (offset) {
 		offset -= sizeof(struct udphdr);
 	} else {
@@ -766,6 +916,7 @@
 			udh->uh.check = -1;
 
 		memcpy(buff, udh, sizeof(struct udphdr));
+		udh->wcheck = 0;
 	}
 	return 0;
 }
@@ -784,6 +935,7 @@
 	int len = ulen + sizeof(struct udphdr);
 	int addr_type;
 	int hlimit = -1;
+	int tclass = -1;
 	
 	int err;
 	
@@ -870,7 +1022,7 @@
 		opt = &opt_space;
 		memset(opt, 0, sizeof(struct ipv6_txoptions));
 
-		err = datagram_send_ctl(msg, &fl, opt, &hlimit);
+		err = datagram_send_ctl(msg, &fl, opt, &hlimit, &tclass);
 		if (err < 0) {
 			fl6_sock_release(flowlabel);
 			return err;
@@ -889,6 +1041,7 @@
 		opt = fl6_merge_options(&opt_space, flowlabel, opt);
 	if (opt && opt->srcrt)
 		udh.daddr = daddr;
+	udh.daddr = daddr;
 
 	udh.uh.source = sk->sport;
 	udh.uh.len = len < 0x10000 ? htons(len) : 0;
@@ -905,6 +1058,7 @@
 	fl.uli_u.ports.sport = udh.uh.source;
 
 	err = ip6_build_xmit(sk, udpv6_getfrag, &udh, &fl, len, opt, hlimit,
+			     tclass,
 			     msg->msg_flags);
 
 	fl6_sock_release(flowlabel);
diff -urN linux-2.4.29/net/ipv6/utils.c linux-2.4.29-uc1/net/ipv6/utils.c
--- linux-2.4.29/net/ipv6/utils.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/ipv6/utils.c	2005-06-14 02:11:52.000000000 +0100
@@ -0,0 +1,50 @@
+/* $USAGI: utils.c,v 1.2 2001/05/26 12:18:53 yoshfuji Exp $ */
+
+/*
+ * Copyright (C) 2000 USAGI/WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <linux/config.h>
+#include <asm/byteorder.h>
+#include <linux/kernel.h>
+#include <linux/in6.h>
+
+#ifdef CONFIG_IPV6
+char* in6_ntop(const struct in6_addr *in6, char *buf){
+	if (!buf)
+		return NULL;
+	sprintf(buf,
+		"%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
+		ntohs(in6->s6_addr16[0]), ntohs(in6->s6_addr16[1]),
+		ntohs(in6->s6_addr16[2]), ntohs(in6->s6_addr16[3]),
+		ntohs(in6->s6_addr16[4]), ntohs(in6->s6_addr16[5]),
+		ntohs(in6->s6_addr16[6]), ntohs(in6->s6_addr16[7]));
+	return buf;
+}
+#endif
+
diff -urN linux-2.4.29/net/irda/af_irda.c linux-2.4.29-uc1/net/irda/af_irda.c
--- linux-2.4.29/net/irda/af_irda.c	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/net/irda/af_irda.c	2005-06-14 02:11:53.000000000 +0100
@@ -2574,7 +2574,6 @@
         dev_add_pack(&irda_packet_type);
 
 	register_netdevice_notifier(&irda_dev_notifier);
-
 	irda_init();
 #ifdef MODULE
  	irda_device_init();  /* Called by init/main.c when non-modular */
@@ -2592,7 +2591,7 @@
  *
  */
 #ifdef MODULE
-void irda_proto_cleanup(void)
+void __exit irda_proto_cleanup(void)
 {
 	irda_packet_type.type = htons(ETH_P_IRDA);
         dev_remove_pack(&irda_packet_type);
@@ -2600,9 +2599,8 @@
         unregister_netdevice_notifier(&irda_dev_notifier);
 	
 	sock_unregister(PF_IRDA);
-	irda_cleanup();
 	
-        return;
+	irda_cleanup();
 }
 module_exit(irda_proto_cleanup);
  
diff -urN linux-2.4.29/net/irda/irda_device.c linux-2.4.29-uc1/net/irda/irda_device.c
--- linux-2.4.29/net/irda/irda_device.c	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/net/irda/irda_device.c	2005-06-14 02:11:53.000000000 +0100
@@ -166,6 +166,12 @@
 #ifdef CONFIG_EP7211_IR
  	ep7211_ir_init();
 #endif
+#ifdef CONFIG_EP93XX_SIR
+	ep93xx_sir_init();
+#endif
+#ifdef CONFIG_EP93XX_IRDA
+	ep93xx_irda_init();
+#endif
 #ifdef CONFIG_MCP2120_DONGLE
 	mcp2120_init();
 #endif
diff -urN linux-2.4.29/net/irda/irlap_event.c linux-2.4.29-uc1/net/irda/irlap_event.c
--- linux-2.4.29/net/irda/irlap_event.c	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-uc1/net/irda/irlap_event.c	2005-06-14 02:11:53.000000000 +0100
@@ -532,7 +532,7 @@
 #endif /* CONFIG_IRDA_ULTRA */
 	case RECV_TEST_CMD:
 		/* Remove test frame header */
-		skb_pull(skb, sizeof(struct test_frame));
+		skb_pull(skb, 10 /*sizeof(struct test_frame)*/);
 
 		/* 
 		 * Send response. This skb will not be sent out again, and
@@ -740,7 +740,7 @@
 
 	switch (event) {
 	case CONNECT_RESPONSE:
-		skb_pull(skb, sizeof(struct snrm_frame));
+		skb_pull(skb, 11 /*sizeof(struct snrm_frame)*/);
 
 		ASSERT(self->netdev != NULL, return -1;);
 
@@ -870,7 +870,7 @@
 
 			ASSERT(self->netdev != NULL, return -1;);
 
-			skb_pull(skb, sizeof(struct snrm_frame));
+			skb_pull(skb, 11 /*sizeof(struct snrm_frame)*/);
 
 			irlap_qos_negotiate(self, skb);
 			
@@ -902,7 +902,7 @@
 		/* Negotiate connection parameters */
 		ASSERT(skb->len > 10, return -1;);
 
-		skb_pull(skb, sizeof(struct ua_frame));
+		skb_pull(skb, 10 /*sizeof(struct ua_frame)*/);
 
 		ASSERT(self->netdev != NULL, return -1;);
 
diff -urN linux-2.4.29/net/khttpd/Config.in linux-2.4.29-uc1/net/khttpd/Config.in
--- linux-2.4.29/net/khttpd/Config.in	1999-10-14 22:22:09.000000000 +0100
+++ linux-2.4.29-uc1/net/khttpd/Config.in	2005-06-14 02:11:48.000000000 +0100
@@ -1,4 +1,10 @@
+# $USAGI: Config.in,v 1.4 2000/11/01 12:57:43 yoshfuji Exp $
 #
 # kHTTPd
 #
 tristate '  Kernel httpd acceleration (EXPERIMENTAL)' CONFIG_KHTTPD
+if [ "$CONFIG_KHTTPD" != "n" ]; then
+  if [ "$CONFIG_IPV6" != "n" ]; then
+    bool '    Use IPv6 socket for khttpd' CONFIG_KHTTPD_IPV6
+  fi
+fi
diff -urN linux-2.4.29/net/khttpd/sockets.c linux-2.4.29-uc1/net/khttpd/sockets.c
--- linux-2.4.29/net/khttpd/sockets.c	2002-08-03 01:39:46.000000000 +0100
+++ linux-2.4.29-uc1/net/khttpd/sockets.c	2005-06-14 02:11:48.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: sockets.c,v 1.5 2002/08/04 02:57:46 yoshfuji Exp $ */
+
 /*
 
 kHTTPd -- the next generation
@@ -42,14 +44,22 @@
 int StartListening(const int Port)
 {
 	struct socket *sock;
+#ifdef CONFIG_KHTTPD_IPV6
+	struct sockaddr_in6 sin;
+#else
 	struct sockaddr_in sin;
+#endif
 	int error;
 	
 	EnterFunction("StartListening");
 	
 	/* First create a socket */
 	
+#ifdef CONFIG_KHTTPD_IPV6
+	error = sock_create(PF_INET6,SOCK_STREAM,IPPROTO_TCP,&sock);
+#else
 	error = sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&sock);
+#endif
 	if (error<0) 
 	     (void)printk(KERN_ERR "Error during creation of socket; terminating\n");
 
@@ -57,9 +67,15 @@
 
 	/* Now bind the socket */
 	
+#ifdef CONFIG_KHTTPD_IPV6
+	memset(&sin, 0, sizeof(sin));
+	sin.sin6_family      = AF_INET6;
+	sin.sin6_port        = htons((unsigned short)Port);
+#else
 	sin.sin_family	     = AF_INET;
 	sin.sin_addr.s_addr  = INADDR_ANY;
 	sin.sin_port         = htons((unsigned short)Port);
+#endif
 	
 	error = sock->ops->bind(sock,(struct sockaddr*)&sin,sizeof(sin));
 	if (error<0)
diff -urN linux-2.4.29/net/Makefile linux-2.4.29-uc1/net/Makefile
--- linux-2.4.29/net/Makefile	2004-08-08 00:26:06.000000000 +0100
+++ linux-2.4.29-uc1/net/Makefile	2005-06-14 02:11:52.000000000 +0100
@@ -1,3 +1,4 @@
+# $USAGI: Makefile,v 1.15 2003/11/12 05:11:58 yoshfuji Exp $
 #
 # Makefile for the linux networking.
 #
@@ -7,7 +8,7 @@
 
 O_TARGET :=	network.o
 
-mod-subdirs :=	ipv4/netfilter ipv6/netfilter ipx irda bluetooth atm netlink sched core sctp 802
+mod-subdirs :=	ipv4/netfilter ipv6/netfilter bridge/netfilter ipx irda bluetooth atm netlink sched core sctp 802
 export-objs :=	netsyms.o
 
 subdir-y :=	core ethernet
@@ -27,6 +28,16 @@
 endif
 endif
 
+ifeq ($(CONFIG_IPV6),y)
+subdir-$(CONFIG_IPV6_IPV6_TUNNEL)              += ipv6
+endif
+
+ifneq ($(CONFIG_BRIDGE),n)
+ifneq ($(CONFIG_BRIDGE),)
+subdir-$(CONFIG_BRIDGE)		+= bridge/netfilter
+endif
+endif
+
 subdir-$(CONFIG_KHTTPD)		+= khttpd
 subdir-$(CONFIG_PACKET)		+= packet
 subdir-$(CONFIG_NET_SCHED)	+= sched
@@ -45,6 +56,8 @@
 subdir-$(CONFIG_ATM)		+= atm
 subdir-$(CONFIG_DECNET)		+= decnet
 subdir-$(CONFIG_ECONET)		+= econet
+subdir-$(CONFIG_IPSEC)		+= ipsec
+subdir-$(CONFIG_KLIPS)		+= ipsec
 subdir-$(CONFIG_VLAN_8021Q)           += 8021q
 
 ifeq ($(CONFIG_NETFILTER),y)
diff -urN linux-2.4.29/net/netsyms.c linux-2.4.29-uc1/net/netsyms.c
--- linux-2.4.29/net/netsyms.c	2005-01-19 14:10:14.000000000 +0000
+++ linux-2.4.29-uc1/net/netsyms.c	2005-06-14 02:11:53.000000000 +0100
@@ -1,3 +1,5 @@
+/* $USAGI: netsyms.c,v 1.61 2003/12/22 04:36:30 yoshfuji Exp $ */
+
 /*
  *  linux/net/netsyms.c
  *
@@ -67,6 +69,7 @@
 #include <net/ndisc.h>
 #include <net/transp_v6.h>
 #include <net/addrconf.h>
+#include <net/ip6_route.h>
 
 extern int sysctl_local_port_range[2];
 extern int tcp_port_rover;
@@ -176,6 +179,7 @@
 EXPORT_SYMBOL(neigh_table_clear);
 EXPORT_SYMBOL(neigh_resolve_output);
 EXPORT_SYMBOL(neigh_connected_output);
+EXPORT_SYMBOL(__neigh_update);
 EXPORT_SYMBOL(neigh_update);
 EXPORT_SYMBOL(neigh_create);
 EXPORT_SYMBOL(neigh_lookup);
@@ -188,12 +192,14 @@
 EXPORT_SYMBOL(neigh_seq_stop);
 #ifdef CONFIG_ARPD
 EXPORT_SYMBOL(neigh_app_ns);
+EXPORT_SYMBOL(neigh_app_notify);
 #endif
 #ifdef CONFIG_SYSCTL
 EXPORT_SYMBOL(neigh_sysctl_register);
 #endif
 EXPORT_SYMBOL(pneigh_lookup);
 EXPORT_SYMBOL(pneigh_enqueue);
+EXPORT_SYMBOL(pneigh_delete);
 EXPORT_SYMBOL(neigh_destroy);
 EXPORT_SYMBOL(neigh_parms_alloc);
 EXPORT_SYMBOL(neigh_parms_release);
@@ -303,7 +309,6 @@
 EXPORT_SYMBOL(dlci_ioctl_hook);
 #endif
 
-
 #if defined (CONFIG_IPV6_MODULE) || defined (CONFIG_KHTTPD) || defined (CONFIG_KHTTPD_MODULE) || defined (CONFIG_IP_SCTP_MODULE)
 /* inet functions common to v4 and v6 */
 EXPORT_SYMBOL(inet_release);
diff -urN linux-2.4.29/net/sched/Config.in linux-2.4.29-uc1/net/sched/Config.in
--- linux-2.4.29/net/sched/Config.in	2004-08-08 00:26:07.000000000 +0100
+++ linux-2.4.29-uc1/net/sched/Config.in	2005-06-14 02:11:53.000000000 +0100
@@ -10,6 +10,7 @@
    dep_tristate '  ATM pseudo-scheduler' CONFIG_NET_SCH_ATM $CONFIG_ATM
 fi
 tristate '  The simplest PRIO pseudoscheduler' CONFIG_NET_SCH_PRIO
+tristate '  WRR packet scheduler' CONFIG_NET_SCH_WRR
 tristate '  RED queue' CONFIG_NET_SCH_RED
 tristate '  SFQ queue' CONFIG_NET_SCH_SFQ
 tristate '  TEQL queue' CONFIG_NET_SCH_TEQL
diff -urN linux-2.4.29/net/sched/Makefile linux-2.4.29-uc1/net/sched/Makefile
--- linux-2.4.29/net/sched/Makefile	2004-08-08 00:26:07.000000000 +0100
+++ linux-2.4.29-uc1/net/sched/Makefile	2005-06-14 02:11:53.000000000 +0100
@@ -13,6 +13,7 @@
 obj-$(CONFIG_NET_CLS_POLICE)	+= police.o
 obj-$(CONFIG_NET_SCH_INGRESS)	+= sch_ingress.o 
 obj-$(CONFIG_NET_SCH_CBQ)	+= sch_cbq.o
+obj-$(CONFIG_NET_SCH_WRR)	+= sch_wrr.o
 obj-$(CONFIG_NET_SCH_CSZ)	+= sch_csz.o
 obj-$(CONFIG_NET_SCH_NETEM)	+= sch_netem.o
 obj-$(CONFIG_NET_SCH_HPFQ)	+= sch_hpfq.o
diff -urN linux-2.4.29/net/sched/proxydict.c linux-2.4.29-uc1/net/sched/proxydict.c
--- linux-2.4.29/net/sched/proxydict.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/sched/proxydict.c	2005-06-14 02:11:53.000000000 +0100
@@ -0,0 +1,153 @@
+#ifndef __KERNEL__
+#include <string.h>
+#include <netinet/in.h>
+#endif
+
+#include "proxyremap.h"
+#include "proxydict.h"
+
+
+/*--------------------------------------------------------------------------
+Implementation.
+*/
+
+// Hash function
+#define hash_fnc(m,server,port,proto) \
+ (((proto)*7+(server)*13+(port)*5)%m->hash_size)
+
+// Size of hash table given maximal number of connections:
+#define hash_size_max_con(max_con) (2*(max_con))
+
+// The memory area we maintain:
+typedef struct {
+  int hash_size;
+  int max_con;
+  int cur_con;
+  
+  int free_first;
+  
+  // Then we have:
+  //   int hash_table[hash_size];
+  //   int next[max_con];
+  //   ProxyRemapBlock info[max_con];
+  //
+  // The idea is the following:
+  //   Given a connection we map it by hash_fnc into hash_table. This gives an 
+  //   index in next which contains a -1 terminated linked list of connections 
+  //   mapping to that hash value.
+  //
+  //   The entries in next not allocated is also in linked list where 
+  //   the first free index is free_first.
+} memory;  
+
+#define Memory(m)     ((memory*)m)
+#define Hash_table(m) ((int*)(((char*)m)+sizeof(memory)))
+#define Next(m)       ((int*)(((char*)m)+sizeof(memory)+     \
+                       sizeof(int)*((memory*)m)->hash_size))
+#define Info(m)       ((ProxyRemapBlock*)(((char*)m)+                          \
+                                           sizeof(memory)+                     \
+                                           sizeof(int)*((memory*)m)->hash_size+\
+					   sizeof(int)*((memory*)m)->max_con   \
+					  ))
+
+int proxyGetMemSize(int max_con) {
+  return sizeof(memory)+
+         sizeof(int)*hash_size_max_con(max_con)+
+	 sizeof(int)*max_con+
+	 sizeof(ProxyRemapBlock)*max_con;
+}
+
+void proxyInitMem(void* data, int max_con) {
+  // Init m:
+  memory* m=Memory(data);
+  m->max_con=max_con;
+  m->cur_con=0;
+  m->hash_size=hash_size_max_con(max_con);
+
+  {
+    // Get pointers:
+    int* hash_table=Hash_table(data);
+    int* next=Next(data);
+    int i;
+  
+    // Init the hash table:
+    for(i=0; i<m->hash_size; i++) hash_table[i]=-1;
+  
+    // Init the free-list
+    for(i=0; i<m->max_con; i++) next[i]=i+1;
+    m->free_first=0;
+  }
+}  
+  
+int proxyGetCurConn(void* data) {
+  return Memory(data)->cur_con;
+}
+
+int proxyGetMaxConn(void* data) {
+  return Memory(data)->max_con;
+}
+
+ProxyRemapBlock* proxyLookup(void* data, unsigned ipaddr, unsigned short port, char proto) {    
+  memory* m=Memory(data);
+  int* hash_table=Hash_table(m);
+  int* next=Next(m);
+  ProxyRemapBlock* info=Info(m);
+  int i;
+  
+  for(i=hash_table[hash_fnc(m,ipaddr,port,proto)]; i!=-1; i=next[i]) {
+    if(info[i].proto==proto &&
+       info[i].sport==port &&
+       info[i].saddr==ipaddr) return &info[i];
+  }
+       
+  return 0;
+}    
+
+int proxyConsumeBlock(void* data, ProxyRemapBlock* blk) {
+  memory* m=Memory(data);
+  int* hash_table=Hash_table(m);
+  int* next=Next(m);
+  ProxyRemapBlock* info=Info(m);
+  int hash=hash_fnc(m,blk->saddr,blk->sport,blk->proto);
+  int foo;
+  
+  if(blk->open) {
+    if(m->cur_con == m->max_con) return -1;
+    
+    // Insert the block at a free entry:
+    info[m->free_first]=*blk;
+    m->cur_con++;
+
+    foo=next[m->free_first];
+    
+    // And insert it in the hash tabel:
+    next[m->free_first]=hash_table[hash];
+    hash_table[hash]=m->free_first;
+    m->free_first=foo;
+  } else {
+    int* toupdate;
+    
+    // Find the block
+    for(toupdate=&hash_table[hash]; 
+        *toupdate!=-1; 
+	toupdate=&next[*toupdate]) {
+      if(info[*toupdate].proto==blk->proto &&
+         info[*toupdate].sport==blk->sport &&
+         info[*toupdate].saddr==blk->saddr) break;
+    }
+    if(*toupdate==-1) return -1;
+
+    foo=*toupdate;
+    
+    // Delete it from the hashing list:    
+    *toupdate=next[*toupdate];
+    
+    // And put it on the free list:
+    next[foo]=m->free_first;
+    m->free_first=foo;
+
+    m->cur_con--;
+  }
+  
+  return 0;
+}
diff -urN linux-2.4.29/net/sched/proxydict.h linux-2.4.29-uc1/net/sched/proxydict.h
--- linux-2.4.29/net/sched/proxydict.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/sched/proxydict.h	2005-06-14 02:11:53.000000000 +0100
@@ -0,0 +1,32 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*--------------------------------------------------------------------------
+This is common code for for handling the tabels containing information about 
+which proxyserver connections are associated with which machines..
+*/
+
+// Returns the number of bytes that should be available in the area
+// maintained by this module given the maximal number of concurrent 
+// connections.
+int proxyGetMemSize(int max_connections);
+
+// Initializes a memory area to use. There must be as many bytes
+// available as returned by getMemSize.
+void proxyInitMem(void* data, int max_connections);
+
+// Queries:
+int proxyGetCurConn(void* data); // Returns current number of connections
+int proxyMaxCurConn(void* data); // Returns maximal number of connections
+
+// This is called to open and close conenctions. Returns -1 if
+// a protocol error occores (i.e.: If it is discovered)
+int proxyConsumeBlock(void* data, ProxyRemapBlock*);
+
+// Returns the RemapBlock associated with this connection or 0:
+ProxyRemapBlock* proxyLookup(void* data, unsigned ipaddr, unsigned short port, char proto);
+
+#ifdef __cplusplus
+}
+#endif
diff -urN linux-2.4.29/net/sched/proxyremap.h linux-2.4.29-uc1/net/sched/proxyremap.h
--- linux-2.4.29/net/sched/proxyremap.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/sched/proxyremap.h	2005-06-14 02:11:53.000000000 +0100
@@ -0,0 +1,33 @@
+#ifndef PROXYREMAP_H
+#define PROXYREMAP_H
+
+// This describes the information that is written in proxyremap.log and which
+// are used in the communication between proxyremapserver and proxyremapclient.
+// Everything is in network order.
+
+// First this header is send:
+#define PROXY_WELCOME_LINE "ProxyRemap 1.02. This is a binary protocol.\r\n"
+
+// Then this block is send every time a connection is opened or closed.
+// Note how it is alligned to use small space usage - arrays of this
+// structure are saved in many places.
+typedef struct {   
+  // Server endpoint of connection:
+  unsigned saddr;
+  unsigned short sport;
+
+  // IP protocol for this connection (typically udp or tcp):
+  unsigned char proto;
+  
+  // Is the connection opened or closed?
+  unsigned char open;
+  
+  // Client the packets should be accounted to:
+  unsigned caddr;
+  unsigned char macaddr[6]; // Might be 0.
+  
+  // An informal two-charecter code from the proxyserver. Used for debugging.
+  char proxyinfo[2];
+} ProxyRemapBlock;
+
+#endif
diff -urN linux-2.4.29/net/sched/sch_api.c linux-2.4.29-uc1/net/sched/sch_api.c
--- linux-2.4.29/net/sched/sch_api.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/sched/sch_api.c	2005-06-14 02:11:53.000000000 +0100
@@ -1230,6 +1230,9 @@
 #ifdef CONFIG_NET_SCH_RED
 	INIT_QDISC(red);
 #endif
+#ifdef CONFIG_NET_SCH_WRR
+	INIT_QDISC(wrr);
+#endif
 #ifdef CONFIG_NET_SCH_GRED
        INIT_QDISC(gred);
 #endif
diff -urN linux-2.4.29/net/sched/sch_generic.c linux-2.4.29-uc1/net/sched/sch_generic.c
--- linux-2.4.29/net/sched/sch_generic.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/sched/sch_generic.c	2005-06-14 02:11:53.000000000 +0100
@@ -29,6 +29,9 @@
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <linux/init.h>
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
+#include <linux/imq.h>
+#endif
 #include <linux/list.h>
 #include <net/sock.h>
 #include <net/pkt_sched.h>
@@ -90,7 +93,11 @@
 			spin_unlock(&dev->queue_lock);
 
 			if (!netif_queue_stopped(dev)) {
-				if (netdev_nit)
+				if (netdev_nit
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
+				    && !(skb->imq_flags & IMQ_F_ENQUEUE)
+#endif
+				    )
 					dev_queue_xmit_nit(skb, dev);
 
 				if (dev->hard_start_xmit(skb, dev) == 0) {
diff -urN linux-2.4.29/net/sched/sch_htb.c linux-2.4.29-uc1/net/sched/sch_htb.c
--- linux-2.4.29/net/sched/sch_htb.c	2004-11-17 11:54:22.000000000 +0000
+++ linux-2.4.29-uc1/net/sched/sch_htb.c	2005-06-14 02:11:53.000000000 +0100
@@ -72,7 +72,7 @@
 
 #define HTB_HSIZE 16	/* classid hash size */
 #define HTB_EWMAC 2	/* rate average over HTB_EWMAC*HTB_HSIZE sec */
-#define HTB_DEBUG 1	/* compile debugging support (activated by tc tool) */
+/*#define HTB_DEBUG 1	* compile debugging support (activated by tc tool) */
 #define HTB_RATECM 1    /* whether to use rate computer */
 #define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */
 #define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock)
diff -urN linux-2.4.29/net/sched/sch_wrr.c linux-2.4.29-uc1/net/sched/sch_wrr.c
--- linux-2.4.29/net/sched/sch_wrr.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.29-uc1/net/sched/sch_wrr.c	2005-06-14 02:11:53.000000000 +0100
@@ -0,0 +1,1364 @@
+/*-----------------------------------------------------------------------------
+Weighted Round Robin scheduler.
+  
+Written by Christian Worm Mortensen, cworm@it-c.dk.
+
+Introduction
+============
+This module implements a weighted round robin queue with build-in classifier.
+The classifier currently map each MAC or IP address (configurable either MAC
+or IP and either source or destination) to different classes. Each such class 
+is called a band. Whan using MAC addresses only bridged packets can be 
+classified other packets go to a default MAC address.
+
+Each band has a weight value, where 0<weight<=1. The bandwidth each band
+get is proportional to the weight as can be deduced from the next section.
+
+
+The queue
+=========
+Each band has a penalty value. Bands having something to sent are kept in
+a heap according to this value. The band with the lowest penalty value
+is in the root of the heap. The penalty value is a 128 bit number. Initially 
+no bands are in the heap.
+
+Two global 64 bit values counter_low_penal and couter_high_penal are initialized
+to 0 and to 2^63 respectively.
+
+Enqueing:
+  The packet is inserted in the queue for the band it belongs to. If the band 
+  is not in the heap it is inserted into it. In this case, the upper 64 bits 
+  of its penalty value is set to the same as for the root-band of the heap. 
+  If the heap is empty 0 is used. The lower 64 bit is set to couter_low_penal
+  and couter_low_penal is incremented by 1.
+  
+Dequing:
+  If the heap is empty we have nothing to send. 
+  
+  If the root band has a non-empty queue a packet is dequeued from that.
+  The upper 64 bit of the penalty value of the band is incremented by the 
+  packet size divided with the weight of the band. The lower 64 bit is set to 
+  couter_high_penal and couter_high_penal is incremented by 1.
+
+  If the root element for some reason has an  empty queue it is removed from 
+  the heap and we try to dequeue again.
+
+The effect of the heap and the upper 64 bit of the penalty values is to 
+implement a weighted round robin queue. The effect of counter_low_penal,
+counter_high_penal and the lower 64 bit of the penalty value is primarily to
+stabilize the queue and to give better quality of service to machines only 
+sending a packet now and then. For example machines which have a single 
+interactive connection such as telnet or simple text chatting.
+
+
+Setting weight
+==============
+The weight value can be changed dynamically by the queue itself. The weight 
+value and how it is changed is described by the two members weight1 and 
+weight2 which has type tc_wrr_class_weight and which are in each class. And 
+by the two integer value members of the qdisc called penalfact1 and penalfact2.
+The structure is defined as:
+
+  struct tc_wrr_class_weight {
+    // All are represented as parts of (2^64-1).
+    __u64 val;  // Current value                        (0 is not valid)
+    __u64 decr; // Value pr bytes                       (2^64-1 is not valid)
+    __u64 incr; // Value pr seconds                     (2^64-1 is not valid)
+    __u64 min;  // Minimal value                        (0 is not valid)
+    __u64 max;  // Minimal value                        (0 is not valid)
+
+    // The time where the above information was correct:
+    time_t tim;
+  };
+    
+The weight value used by the dequeue operations is calculated as 
+weight1.val*weight2.val. weight1 and weight2 and handled independently and in the 
+same way as will be described now.
+
+Every second, the val parameter is incremented by incr.
+
+Every time a packet is transmitted the value is increment by decr times
+the packet size. Depending on the value of the weight_mode parameter it
+is also mulitplied with other numbers. This makes it possible to give 
+penalty to machines transferring much data.
+
+-----------------------------------------------------------------------------*/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <linux/in.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/if_ether.h>
+#include <linux/inet.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/notifier.h>
+#include <net/ip.h>
+#include <net/route.h>
+#include <linux/skbuff.h>
+#include <net/sock.h>
+#include <net/pkt_sched.h>
+
+#include <linux/if_arp.h>
+#include <linux/version.h>
+
+// There seems to be problems when calling functions from userspace when
+// using vmalloc and vfree.
+//#define my_malloc(size) vmalloc(size)
+//#define my_free(ptr)   vfree(ptr)
+#define my_malloc(size) kmalloc(size,GFP_KERNEL)
+#define my_free(ptr)    kfree(ptr)
+
+// Kernel depend stuff:
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+  #define KERNEL22
+#endif
+
+#ifdef KERNEL22  
+  #define LOCK_START start_bh_atomic();
+  #define LOCK_END   end_bh_atomic();
+  #define ENQUEUE_SUCCESS 1
+  #define ENQUEUE_FAIL    0
+  #ifdef CONFIG_IP_MASQUERADE      
+    #include <net/ip_masq.h>
+    #define MASQ_SUPPORT
+  #endif
+#else
+  #define LOCK_START sch_tree_lock(sch);
+  #define LOCK_END   sch_tree_unlock(sch);
+  #define ENQUEUE_SUCCESS 0
+  #define ENQUEUE_FAIL    NET_XMIT_DROP
+  #ifdef CONFIG_NETFILTER
+    #include <linux/netfilter_ipv4/ip_conntrack.h>
+    #define MASQ_SUPPORT
+  #endif
+#endif  
+
+#include "proxydict.c"
+
+// The penalty (priority) type:
+typedef u64 penalty_base_t;
+#define penalty_base_t_max ((penalty_base_t)-1)
+typedef struct penalty_t {
+  penalty_base_t ms;
+  penalty_base_t ls;
+} penalty_t;
+#define penalty_leq(a,b) (a.ms<b.ms || (a.ms==b.ms && a.ls<=b.ls))
+#define penalty_le(a,b)  (a.ms<b.ms || (a.ms==b.ms && a.ls<b.ls))
+static penalty_t penalty_max={penalty_base_t_max,penalty_base_t_max};
+
+//-----------------------------------------------------------------------------
+// A generel heap.
+
+struct heap;
+struct heap_element;
+
+// Initializes an empty heap:
+//   he:   A pointer to an unintialized heap structure identifying the heap
+//   size: Maximal number of elements the heap can contain
+//   poll: An array of size "size" used by the heap.     
+static void heap_init(struct heap* he,int size, struct heap_element* poll);
+
+// Each element in the heap is identified by a user-assigned id which
+// should be a non negative integer less than the size argument
+// given to heap_init.
+static void heap_insert(struct heap*, int id, penalty_t);
+static void heap_remove(struct heap*, int id);
+static void heap_set_penalty(struct heap*, int id, penalty_t);
+
+// Retreviewing information:
+static char      heap_empty(struct heap*); // Heap empty?
+static char      heap_contains(struct heap*, int id); // Does heap contain 
+                                                      // the given id?
+static int       heap_root(struct heap*);  // Returns the id of the root
+static penalty_t heap_get_penalty(struct heap*, int id); // Returns penaly
+                                                         // of root node
+
+//--------------------
+// Heap implementation
+
+struct heap_element {
+  penalty_t penalty;
+  int id;             // The user-assigned id of this element
+  int id2idx;         // Maps from user-assigned ids to indices in root_1
+};
+
+struct heap {
+  struct heap_element* root_1;
+  int elements;
+};
+
+// Heap implementation:
+static void heap_init(struct heap* h, int size, struct heap_element* poll) {
+  int i;
+  
+  h->elements=0;
+  h->root_1=poll-1;
+  
+  for(i=0; i<size; i++) poll[i].id2idx=0;
+};
+
+static char heap_empty(struct heap* h) {
+  return h->elements==0;
+}
+
+static char heap_contains(struct heap* h, int id) {
+  return h->root_1[id+1].id2idx!=0;
+}
+
+static int heap_root(struct heap* h) {
+  return h->root_1[1].id;
+}
+
+static penalty_t heap_get_penalty(struct heap* h, int id) {
+  return h->root_1[ h->root_1[id+1].id2idx ].penalty;
+}
+
+static void heap_penalty_changed_internal(struct heap* h,int idx);
+
+static void heap_set_penalty(struct heap* h, int id, penalty_t p) {
+  int idx=h->root_1[id+1].id2idx;
+  h->root_1[idx].penalty=p;
+  heap_penalty_changed_internal(h,idx);
+}
+
+static void heap_insert(struct heap* h, int id, penalty_t p) {
+  // Insert at the end of the heap:
+  h->elements++;
+  h->root_1[h->elements].id=id;
+  h->root_1[h->elements].penalty=p;
+  h->root_1[id+1].id2idx=h->elements;
+  
+  // And put it in the right position:
+  heap_penalty_changed_internal(h,h->elements);
+}
+
+static void heap_remove(struct heap* h, int id) {
+  int idx=h->root_1[id+1].id2idx;
+  int mvid;
+  h->root_1[id+1].id2idx=0;
+  
+  if(h->elements==idx)  { h->elements--; return; }
+  
+  mvid=h->root_1[h->elements].id;
+  h->root_1[idx].id=mvid;
+  h->root_1[idx].penalty=h->root_1[h->elements].penalty;
+  h->root_1[mvid+1].id2idx=idx;
+  
+  h->elements--;
+  heap_penalty_changed_internal(h,idx);
+}  
+
+static void heap_swap(struct heap* h, int idx0, int idx1) {
+  penalty_t tmp_p;
+  int       tmp_id;
+  int       id0,id1;
+  
+  // Simple content:
+  tmp_p=h->root_1[idx0].penalty;
+  tmp_id=h->root_1[idx0].id;
+  h->root_1[idx0].penalty=h->root_1[idx1].penalty;
+  h->root_1[idx0].id=h->root_1[idx1].id;
+  h->root_1[idx1].penalty=tmp_p;
+  h->root_1[idx1].id=tmp_id;
+  
+  // Update reverse pointers:
+  id0=h->root_1[idx0].id;
+  id1=h->root_1[idx1].id;
+  h->root_1[id0+1].id2idx=idx0;
+  h->root_1[id1+1].id2idx=idx1;
+}
+
+static void heap_penalty_changed_internal(struct heap* h,int cur) {
+  if(cur==1 || penalty_leq(h->root_1[cur>>1].penalty,h->root_1[cur].penalty)) {
+    // We are in heap order upwards - so we should move the element down
+    for(;;) {
+      int nxt0=cur<<1;
+      int nxt1=nxt0+1;
+      penalty_t pen_c=h->root_1[cur].penalty;
+      penalty_t pen_0=nxt0<=h->elements ? h->root_1[nxt0].penalty : penalty_max;
+      penalty_t pen_1=nxt1<=h->elements ? h->root_1[nxt1].penalty : penalty_max;
+    
+      if(penalty_le(pen_0,pen_c) && penalty_leq(pen_0,pen_1)) {
+        // Swap with child 0:
+	heap_swap(h,cur,nxt0);
+        cur=nxt0;
+      } else if(penalty_le(pen_1,pen_c)) {
+        // Swap with child 1:
+	heap_swap(h,cur,nxt1);
+	cur=nxt1;
+      } else {
+        // Heap in heap order:
+        return;
+      }
+    }
+  } else {
+    // We are not in heap order upwards (and thus we must be it downwards).
+    // We move up:
+    while(cur!=1) { // While not root
+      int nxt=cur>>1;
+      if(penalty_leq(h->root_1[nxt].penalty,h->root_1[cur].penalty)) return;
+      heap_swap(h,cur,nxt);
+      cur=nxt;
+    }
+  }
+};
+
+//-----------------------------------------------------------------------------
+// Classification based on MAC or IP adresses. Note that of historical reason
+// these are prefixed with mac_ since originally only MAC bases classification
+// was supported.
+//
+// This code should be in a separate filter module - but it isn't.
+
+// Interface:
+
+struct mac_head;
+
+// Initialices/destroys the structure we maintain.
+// Returns -1 on error
+static int  mac_init(struct mac_head*, int max_macs, char srcaddr, 
+                     char usemac, char usemasq, void* proxyremap);
+static void mac_done(struct mac_head*);
+static void mac_reset(struct mac_head*);
+
+// Classify a packet. Returns a number n where 0<=n<max_macs. Or -1 if
+// the packet should be dropped.
+static int mac_classify(struct mac_head*, struct sk_buff *skb);
+
+//-------------
+// Implementation:
+
+struct mac_addr {
+  unsigned char addr[ETH_ALEN]; // Address of this band (last two are 0 on IP)
+  unsigned long lastused;       // Last time a packet was encountered
+  int class;                    // Classid of this band (0<=classid<max_macs)
+};
+
+static int mac_compare(const void* a, const void* b) {
+  return memcmp(a,b,ETH_ALEN);
+}
+
+struct mac_head {
+  int mac_max;    // Maximal number of MAC addresses/classes allowed
+  int mac_cur;    // Current number of MAC addresses/classes
+  int mac_reused; // Number of times we have reused a class with a new 
+                  // address.
+  u64 incr_time;
+  char srcaddr;   // True if we classify on the source address of packets,
+                  // else we use destination address.
+  char usemac;    // If true we use mac, else we use IP
+  char usemasq;   // If true we try to demasqgrade
+  struct mac_addr* macs; // Allocated mac_max elements, used max_cur
+  char* cls2mac;         // Mapping from classnumbers to addresses -
+                         // there is 6 bytes in each entry
+                          
+  void* proxyremap; // Information on proxy remapping of data or 0
+};
+
+// This is as the standard C library function with the same name:
+static const void* bsearch(const void* key, const void* base, int nmemb, 
+                           size_t size, 
+			   int (*compare)(const void*, const void*)) {	
+  int m_idx;
+  const void* m_ptr;
+  int i;
+  
+  if(nmemb<=0) return 0;
+  
+  m_idx=nmemb>>1;
+  m_ptr=((const char*)base)+m_idx*size;
+  
+  i=compare(key,m_ptr);
+  if(i<0) // key is less
+    return bsearch(key,base,m_idx,size,compare);
+  else if(i>0)
+    return bsearch(key,((const char*)m_ptr)+size,nmemb-m_idx-1,size,compare);
+    
+  return m_ptr;
+}
+
+static int mac_init(struct mac_head* h, int max_macs, char srcaddr, 
+                    char usemac, char usemasq,void* proxyremap) {
+  h->mac_cur=0;
+  h->mac_reused=0;
+  h->incr_time=0;
+  h->srcaddr=srcaddr;
+  h->usemac=usemac;
+  h->usemasq=usemasq;
+  h->mac_max=max_macs;
+  h->proxyremap=proxyremap;
+
+  h->macs=(struct mac_addr*)
+    my_malloc( sizeof(struct mac_addr)*max_macs);
+  h->cls2mac=(char*)my_malloc( 6*max_macs);
+  if(!h->macs || !h->cls2mac) {
+    if(h->macs) my_free(h->macs);
+    if(h->cls2mac) my_free(h->cls2mac);
+    return -1;
+  }
+  return 0;
+}
+
+static void mac_done(struct mac_head* h) {
+  my_free(h->macs);
+  my_free(h->cls2mac);
+}
+
+static void mac_reset(struct mac_head* h) {
+  h->mac_cur=0;
+  h->mac_reused=0;
+  h->incr_time=0;
+}
+
+static int lookup_mac(struct mac_head* h, unsigned char* addr) {
+  int i;
+  int class;
+  
+  // First try to find the address in the table:  
+  struct mac_addr* m=(struct mac_addr*)
+    bsearch(addr,h->macs,h->mac_cur,sizeof(struct mac_addr),mac_compare);
+  if(m) {
+    // Found:
+    m->lastused=h->incr_time++;
+    return m->class;
+  }
+  
+  // Okay - the MAC adress was not in table
+  if(h->mac_cur==h->mac_max) {
+    // And the table is full - delete the oldest entry:
+
+    // Find the oldest entry:
+    int lowidx=0;
+    int i;
+    for(i=1; i<h->mac_cur; i++) 
+      if(h->macs[i].lastused < h->macs[lowidx].lastused) lowidx=i;
+    
+    class=h->macs[lowidx].class;
+    
+    // And delete it:
+    memmove(&h->macs[lowidx],&h->macs[lowidx+1],
+            (h->mac_cur-lowidx-1)*sizeof(struct mac_addr));
+    h->mac_reused++;
+    h->mac_cur--;
+  } else {
+    class=h->mac_cur;
+  }
+  
+  // The table is now not full - find the position we should put the address in:
+  for(i=0; i<h->mac_cur; i++) if(mac_compare(addr,&h->macs[i])<0) break;
+  
+  // We should insert at position i:
+  memmove(&h->macs[i+1],&h->macs[i],(h->mac_cur-i)*sizeof(struct mac_addr));
+  m=&h->macs[i];
+  memcpy(m->addr,addr,ETH_ALEN);
+  m->lastused=h->incr_time++;
+  m->class=class;
+  h->mac_cur++;
+  
+  // Finally update the cls2mac variabel:
+  memcpy(h->cls2mac+ETH_ALEN*class,addr,ETH_ALEN);
+  
+  return m->class;
+}
+
+int valid_ip_checksum(struct iphdr* ip, int size) {
+  __u16 header_len=ip->ihl<<2;
+  __u16 c=0;
+  __u16* ipu=(u16*)ip;
+  int a;
+  
+  // We require 4 bytes in the packet since we access the port numbers:  
+  if((size<header_len) || size<sizeof(struct iphdr)+4) return 0;
+  
+  for(a=0; a<(header_len>>1); a++, ipu++) {
+    if(a!=5) { // If not the checksum field
+      __u16 oldc=c;	
+      c+=(*ipu); 
+      if(c<oldc) c++;	  
+    }
+  }
+  
+  return ip->check==(__u16)~c;
+}   
+ 
+static int mac_classify(struct mac_head* head, struct sk_buff *skb)
+{
+  // We set this to the address we map to. In case we map to an IP
+  // address the last two entries are set to 0.
+  unsigned char addr[ETH_ALEN];
+  
+  
+  // This is the size of the network part of the packet, I think:
+  int size=((char*)skb->data+skb->len)-((char*)skb->nh.iph);
+
+  // Set a default value for the address:
+  memset(addr,0,ETH_ALEN);
+  
+  // Accept IP-ARP traffic with big-enough packets:
+  if(ntohs(skb->protocol)==ETH_P_ARP && 
+           ntohs(skb->nh.arph->ar_pro)==ETH_P_IP) {
+    // Map all ARP trafic to a default adress to make sure
+    // it goes through
+  } else if ((ntohs(skb->protocol)==ETH_P_IP) && 
+          valid_ip_checksum(skb->nh.iph,size)) {
+    // Accept IP packets which have correct checksum.
+	     
+    // This is the IP header:
+    struct iphdr* iph=skb->nh.iph;
+    
+    // And this is the port numbers:
+    const __u16 *portp = (__u16 *)&(((char *)iph)[iph->ihl*4]);
+    __u16 sport=portp[0];
+    __u16 dport=portp[1];
+    
+    // We will set this to the IP address of the packet that should be
+    // accounted to:
+    unsigned ipaddr;
+    
+    // Used below:    
+    ProxyRemapBlock* prm;
+    
+    // Set ipaddr:
+    if(head->srcaddr) 
+      ipaddr=iph->saddr;
+    else
+      ipaddr=iph->daddr;
+      
+#ifdef MASQ_SUPPORT
+    // Update ipaddr if packet is masqgraded:
+    if(head->usemasq) {
+      #ifdef KERNEL22
+        struct ip_masq* src;
+
+        // HACK!:
+        //   ip_masq_in_get must be called for packets comming from the outside
+        //   to the firewall. We have a a packet which is comming from the 
+	//   firewall to the outside - so we switch the parameters:
+        if((src=ip_masq_in_get(
+  	       iph->protocol,
+	       iph->daddr,dport,
+	       iph->saddr,sport))) {
+          // Use masqgraded address:
+  	  ipaddr=src->saddr;
+	
+	  // It seems like we must put it back:
+	  ip_masq_put(src);
+        }
+      #else
+        // Thanks to Rusty Russell for help with the following code:
+        enum ip_conntrack_info ctinfo;
+        struct ip_conntrack *ct;
+        ct = ip_conntrack_get(skb, &ctinfo);
+        if (ct) {
+          if(head->srcaddr)
+            ipaddr=ct->tuplehash[CTINFO2DIR(ctinfo)].tuple.src.ip;
+  	  else
+            ipaddr=ct->tuplehash[CTINFO2DIR(ctinfo)].tuple.dst.ip;
+        }
+      #endif
+    }
+#endif    
+
+    // Set prm based on ipaddr:
+    prm=0;
+    if(head->proxyremap) {
+      if(head->srcaddr) {
+        prm=proxyLookup(head->proxyremap,ipaddr,sport,skb->nh.iph->protocol);
+      } else {
+        prm=proxyLookup(head->proxyremap,ipaddr,dport,skb->nh.iph->protocol);
+      }
+    }
+    
+    // And finally set addr to the address:
+    memset(addr,0,ETH_ALEN);
+    if(prm) {
+      // This package should be remapped:
+      if(head->usemac) 
+        memcpy(addr,prm->macaddr,ETH_ALEN);
+      else {
+        memcpy(addr,&prm->caddr,sizeof(unsigned));
+      }
+    } else {
+      // This packet should not be remapped:
+      if(head->usemac) {	
+        // We should find MAC address of packet.
+	// Unfortunatly, this is not always available.
+	// On bridged packets it always is, however..
+	#ifdef KERNEL22
+          if(skb->pkt_bridged) {
+            if(head->srcaddr) {
+              memcpy(addr,skb->mac.ethernet->h_source,ETH_ALEN);
+            } else {
+              memcpy(addr,skb->mac.ethernet->h_dest,ETH_ALEN);
+  	    }
+	  }
+	#endif	
+      } else {
+        memcpy(addr,&ipaddr,4);              
+      } 
+    }
+  } else {
+    // All other traffic is dropped - this ensures that packets
+    // we consider probably have valid addresses so we don't
+    // get to many strange addresses into our table. And that we
+    // don't use bandwidth on strange packets..
+    return -1;
+  }
+  
+  return lookup_mac(head,addr);
+}
+
+//-----------------------------------------------------------------------------
+// The qdisc itself
+
+// Pr-class information.
+struct wrrc_sched_data {
+  struct Qdisc* que;                   // The queue for this class
+  struct tc_wrr_class_modf class_modf; // Information about the class.
+  
+  // For classes in the heap this is the priority value priosum
+  // was updated with for this class:
+  u64 priosum_val;
+};  
+
+// Pr-qdisc information:
+struct wrr_sched_data
+{
+  // A heap containing all the bands that will send something
+  struct heap h;
+  struct heap_element* poll; // bandc elements
+  
+  // The sum of the prioities of the elements in the heap where
+  // a priority of 1 is saved as 2^32
+  u64 priosum;
+  
+  // A class for each band
+  struct wrrc_sched_data* bands; // bandc elements
+  
+  // Information maintained by the proxydict module of 0 if we
+  // have no proxy remapping
+  void* proxydict;
+  
+  // Always incrementning counters, we always have that any value of
+  // counter_low_penal < any value of counter_high_penal.
+  penalty_base_t counter_low_penal;
+  penalty_base_t counter_high_penal;
+  
+  // Penalty updating:
+  struct tc_wrr_qdisc_modf qdisc_modf;
+  
+  // Statistics:
+  int packets_requed;
+  
+  // The filter:
+  struct mac_head filter;  
+  int bandc; // Number of bands
+};
+
+// Priority handling.
+//   weight is in interval [0..2^32]
+//   priosum has whole numbers in the upper and fragments in the lower 32 bits. 
+static void weight_transmit(struct tc_wrr_class_weight* p, 
+                            struct tc_wrr_qdisc_weight q,
+			    unsigned heapsize,
+			    u64 priosum, u64 weight,
+			    unsigned size) {
+
+  unsigned long now=jiffies/HZ;
+  
+  // Penalty for transmitting:
+  u64 change,old;
+  u32 divisor;
+  
+  change=0;
+  switch(q.weight_mode) {
+    case 1: change=p->decr*size; break;
+    case 2: change=p->decr*size*heapsize; break;
+    case 3: // Note: 64 bit division is not always available..
+      divisor=(u32)(weight>>16);
+      if(divisor<=0) divisor=1;
+      change=p->decr*size*(((u32)(priosum>>16))/divisor); break;
+  }
+  old=p->val;
+  p->val-=change;
+  if(p->val>old || p->val<p->min) p->val=p->min;
+  
+  // Credit for time went:
+  change=(now-p->tim)*p->incr;
+  p->tim=now;
+  old=p->val;
+  p->val+=change;
+  if(p->val<old || p->val>p->max) p->val=p->max;
+}  
+
+static void weight_setdefault(struct tc_wrr_class_weight* p) {
+  p->val=(u64)-1;
+  p->decr=0;
+  p->incr=0;
+  p->min=(u64)-1;
+  p->max=(u64)-1;
+  p->tim=jiffies/HZ;  
+}
+
+static void weight_setvalue(struct tc_wrr_class_weight* dst, 
+                            struct tc_wrr_class_weight* src) {
+  if(src->val!=0) {
+    dst->val=src->val;
+    dst->tim=jiffies/HZ;
+  }
+  if(src->min!=0) dst->min=src->min;
+  if(src->max!=0) dst->max=src->max;
+  if(src->decr!=((u64)-1)) dst->decr=src->decr;
+  if(src->incr!=((u64)-1)) dst->incr=src->incr;
+  if(dst->val<dst->min) dst->val=dst->min;
+  if(dst->val>dst->max) dst->val=dst->max;
+}
+
+static void wrr_destroy(struct Qdisc *sch)
+{
+  struct wrr_sched_data *q=(struct wrr_sched_data *)sch->data;
+  int i;
+  
+  // Destroy our filter:
+  mac_done(&q->filter);
+
+  // Destroy all our childre ques:
+  for(i=0; i<q->bandc; i++) 
+    qdisc_destroy(q->bands[i].que);
+    
+  // And free memory:
+  my_free(q->bands);
+  my_free(q->poll);  
+  if(q->proxydict) my_free(q->proxydict);
+  
+  MOD_DEC_USE_COUNT;
+}
+
+static int wrr_init(struct Qdisc *sch, struct rtattr *opt)
+{
+  struct wrr_sched_data *q = (struct wrr_sched_data *)sch->data;
+  int i,maciniterr;
+  char crterr;
+  struct tc_wrr_qdisc_crt *qopt;
+  
+  // Parse options:
+  if (!opt) return -EINVAL; // Options must be specified
+  if (opt->rta_len < RTA_LENGTH(sizeof(*qopt))) return -EINVAL;
+  qopt = RTA_DATA(opt);
+
+  if(qopt->bands_max>8192 || qopt->bands_max<2) {
+    // More than 8192 queues or less than 2? That cannot be true - it must be 
+    // an error...
+    return -EINVAL;
+  }
+  
+  if(qopt->proxy_maxconn<0 || qopt->proxy_maxconn>20000) {
+    // More than this number of maximal concurrent connections is unrealistic
+    return -EINVAL;
+  }
+
+#ifndef MASQ_SUPPORT
+  if(qopt->usemasq) { 
+    return -ENOSYS;
+  }
+#endif  
+
+#ifndef KERNEL22
+  if(qopt->usemac) { // Not supported - please fix this!
+    return -ENOSYS;
+  }
+#endif      
+
+  q->bandc=qopt->bands_max;
+  q->qdisc_modf=qopt->qdisc_modf;
+  
+  // Create structures:
+  q->poll=(struct heap_element*)
+           my_malloc( sizeof(struct heap_element)*q->bandc);
+  q->bands=(struct wrrc_sched_data*)
+           my_malloc( sizeof(struct wrrc_sched_data)*q->bandc);
+  
+  if(qopt->proxy_maxconn>0) {
+    q->proxydict=my_malloc(proxyGetMemSize(qopt->proxy_maxconn));
+  } else {
+    q->proxydict=0;
+  }
+  
+  // Init mac module:
+  maciniterr=mac_init(&q->filter,qopt->bands_max,qopt->srcaddr,
+                      qopt->usemac,qopt->usemasq,q->proxydict);
+
+  // See if we got the memory we wanted:
+  if(!q->poll || !q->bands || 
+    (qopt->proxy_maxconn>0 && !q->proxydict) || maciniterr<0) {
+    if(q->poll) my_free(q->poll);
+    if(q->bands) my_free(q->bands);
+    if(q->proxydict) my_free(q->proxydict);
+    if(maciniterr>=0) mac_done(&q->filter);
+    return -ENOMEM;
+  }
+  
+  // Initialize proxy:
+  if(q->proxydict) {
+    proxyInitMem(q->proxydict,qopt->proxy_maxconn);
+  }
+    
+  // Initialize values:    
+  q->counter_low_penal=0;
+  q->counter_high_penal=penalty_base_t_max>>1;
+  q->packets_requed=0;
+  
+  // Initialize empty heap:
+  heap_init(&q->h,q->bandc,q->poll);
+  q->priosum=0;
+  
+  // Initialize each band:
+  crterr=0;
+  for (i=0; i<q->bandc; i++) {
+    weight_setdefault(&q->bands[i].class_modf.weight1);
+    weight_setdefault(&q->bands[i].class_modf.weight2);
+    if(!crterr) {
+      struct Qdisc *child=qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
+      if(child)
+        q->bands[i].que = child;
+      else {
+        // Queue couldn't be created :-(
+        crterr=1;
+      }
+    }
+    if(crterr) q->bands[i].que = &noop_qdisc;
+  }
+      
+  MOD_INC_USE_COUNT;
+  
+  if(crterr) {
+    // Destroy again:
+    wrr_destroy(sch);
+    return -ENOMEM;
+  }
+  
+  return 0;
+}
+
+static void wrr_reset(struct Qdisc* sch)
+{
+  struct wrr_sched_data *q = (struct wrr_sched_data *)sch->data;
+  int i;
+  
+  // Reset own values:
+  q->counter_low_penal=0;
+  q->counter_high_penal=penalty_base_t_max>>1;
+  q->packets_requed=0;
+  
+  // Reset filter:
+  mac_reset(&q->filter);
+  
+  // Reinitialize heap:
+  heap_init(&q->h,q->bandc,q->poll);
+  q->priosum=0;
+  
+  // Reset all bands:
+  for (i=0; i<q->bandc; i++) {
+    weight_setdefault(&q->bands[i].class_modf.weight1);
+    weight_setdefault(&q->bands[i].class_modf.weight2);
+    qdisc_reset(q->bands[i].que);
+  }
+  
+  // Reset proxy remapping information:
+  if(q->proxydict)
+    proxyInitMem(q->proxydict,proxyGetMaxConn(q->proxydict));
+}
+
+static int wrr_enqueue(struct sk_buff *skb, struct Qdisc* sch)
+{
+  struct wrr_sched_data *q = (struct wrr_sched_data *)sch->data;
+  int retvalue=ENQUEUE_FAIL;
+  
+  // The packet is in skb.
+  int band=mac_classify(&q->filter,skb);
+
+  if(band>=0) {
+    // Enque packet for this band:
+    struct Qdisc* qdisc = q->bands[band].que;
+
+    if ((retvalue=qdisc->enqueue(skb, qdisc)) == ENQUEUE_SUCCESS) {
+      // Successfull
+      sch->stats.bytes += skb->len;
+      sch->stats.packets++;
+      sch->q.qlen++;
+        
+      // Insert band into heap if not already there:
+      if(!heap_contains(&q->h,band)) {        
+        penalty_t p;
+	if(!heap_empty(&q->h)) 
+  	  p.ms=heap_get_penalty(&q->h,heap_root(&q->h)).ms;
+	else
+	  p.ms=0;
+	p.ls=q->counter_low_penal++;
+        heap_insert(&q->h,band,p);
+	q->bands[band].priosum_val=
+	  ((q->bands[band].class_modf.weight1.val>>48)+1)*
+          ((q->bands[band].class_modf.weight2.val>>48)+1);
+	q->priosum+=q->bands[band].priosum_val;
+      }
+    }
+  } else {
+    // If we decide not to enque it seems like we also need to free the packet:
+    kfree_skb(skb);
+  }
+  
+  if(retvalue!=ENQUEUE_SUCCESS) {
+    // Packet not enqued:
+    sch->stats.drops++;
+  }
+  
+  return retvalue;
+}
+
+static struct sk_buff *wrr_dequeue(struct Qdisc* sch)
+{
+  struct wrr_sched_data *q = (struct wrr_sched_data *)sch->data;
+  struct sk_buff* skb;
+  int band;
+  u64 weight,priosum;
+  struct wrrc_sched_data* b;
+  
+  // Return if heap is empty:
+  if(heap_empty(&q->h)) return 0;
+  
+  // Find root element:
+  band=heap_root(&q->h);
+  
+  // Find priority of this element in interval [1;2^32]
+  b=&q->bands[band];
+  weight=((b->class_modf.weight1.val>>48)+1)*
+         ((b->class_modf.weight2.val>>48)+1); //weight is in interval [1;2^32]
+  priosum=q->priosum;
+  q->priosum-=q->bands[band].priosum_val;
+  
+  // Deque the packet from the root:
+  skb=q->bands[band].que->dequeue(q->bands[band].que);  
+  
+  if(skb) {
+    // There was a packet in this que.
+    unsigned adjlen;
+    penalty_t p;
+    
+    // Find length of packet adjusted with priority:
+    adjlen=(u32)(weight>>(32-16));
+    if(adjlen==0) adjlen=1;
+    adjlen=(skb->len<<16)/adjlen;
+	   
+    // Update penalty information for this class:
+    weight_transmit(&b->class_modf.weight1,q->qdisc_modf.weight1,q->h.elements,priosum,weight,skb->len);
+    weight_transmit(&b->class_modf.weight2,q->qdisc_modf.weight2,q->h.elements,priosum,weight,skb->len);
+    q->bands[band].priosum_val=((b->class_modf.weight1.val>>48)+1)*
+                               ((b->class_modf.weight2.val>>48)+1);    
+    q->priosum+=q->bands[band].priosum_val;	       
+        
+    // And update the class in the heap
+    p=heap_get_penalty(&q->h,band);    
+    p.ms+=adjlen;  
+    p.ls=q->counter_high_penal++; 
+    heap_set_penalty(&q->h,band,p);
+    
+    // Return packet:
+    sch->q.qlen--;
+    return skb;
+  }
+  
+  // No packet - so machine should be removed from heap:
+  heap_remove(&q->h,band);
+  
+  // And try again:
+  return wrr_dequeue(sch);
+}
+
+static int wrr_requeue(struct sk_buff *skb, struct Qdisc* sch)
+{
+  struct wrr_sched_data *q = (struct wrr_sched_data *)sch->data;
+  struct Qdisc* qdisc;
+  int ret;
+  
+  // Find band we took it from:
+  int band=mac_classify(&q->filter,skb);
+  if(band<0) { 
+    // Who should now free the pakcet?
+    printk(KERN_DEBUG "sch_wrr: Oops - packet requed could never have been queued.\n");
+    sch->stats.drops++; 
+    return ENQUEUE_FAIL; 
+  }
+
+  q->packets_requed++;
+  
+  // Try to requeue it on that machine:
+  qdisc=q->bands[band].que;
+
+  if((ret=qdisc->ops->requeue(skb,qdisc))==ENQUEUE_SUCCESS) {
+    // On success:
+    sch->q.qlen++;
+    
+    // We should restore priority information - but we don't
+    //
+    // p=heap_get_penalty(&q->h,band);
+    // ...
+    // heap_set_penalty(&q->h,band,p);
+    
+    return ENQUEUE_SUCCESS;
+  } else {
+    sch->stats.drops++;
+    return ret;
+  }
+}    
+
+static int wrr_drop(struct Qdisc* sch)
+{
+  struct wrr_sched_data *q = (struct wrr_sched_data *)sch->data;
+
+  // Ugly... Drop button up in heap:
+  int i;
+
+  for(i=q->h.elements; i>=1; i--) {
+    int band=q->h.root_1[i].id;
+    if(q->bands[band].que->ops->drop(q->bands[band].que)) {
+      // On success
+      sch->q.qlen--;
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+static int wrr_dump(struct Qdisc *sch, struct sk_buff *skb)
+{
+  struct wrr_sched_data *q = (struct wrr_sched_data *)sch->data;
+  unsigned char	*b = skb->tail;
+  struct tc_wrr_qdisc_stats opt;
+
+  opt.qdisc_crt.qdisc_modf=q->qdisc_modf;
+  opt.qdisc_crt.srcaddr=q->filter.srcaddr;
+  opt.qdisc_crt.usemac=q->filter.usemac;
+  opt.qdisc_crt.usemasq=q->filter.usemasq;
+  opt.qdisc_crt.bands_max=q->filter.mac_max;  
+  opt.nodes_in_heap=q->h.elements;
+  opt.bands_cur=q->filter.mac_cur;
+  opt.bands_reused=q->filter.mac_reused;
+  opt.packets_requed=q->packets_requed;
+  opt.priosum=q->priosum;
+
+  if(q->proxydict) {
+    opt.qdisc_crt.proxy_maxconn=proxyGetMaxConn(q->proxydict);
+    opt.proxy_curconn=proxyGetCurConn(q->proxydict);
+  } else {
+    opt.qdisc_crt.proxy_maxconn=0;
+    opt.proxy_curconn=0;
+  }
+  
+  RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+  return skb->len;
+  
+rtattr_failure: // seems like RTA_PUT jump to this label..
+  skb_trim(skb, b - skb->data);
+  return -1;  
+}
+
+static int wrr_tune_std(struct Qdisc *sch, struct rtattr *opt) 
+{
+  struct wrr_sched_data *q = (struct wrr_sched_data *)sch->data;
+  struct tc_wrr_qdisc_modf_std *qopt = RTA_DATA(opt);
+  
+  if(opt->rta_len < RTA_LENGTH(sizeof(*qopt))) return -EINVAL;  
+
+  LOCK_START
+  
+  if(qopt->change_class) {
+    int idx=lookup_mac(&q->filter,qopt->addr);
+    weight_setvalue
+      (&q->bands[idx].class_modf.weight1,&qopt->class_modf.weight1);
+    weight_setvalue
+      (&q->bands[idx].class_modf.weight2,&qopt->class_modf.weight2);
+  } else {
+    if(qopt->qdisc_modf.weight1.weight_mode!=-1)
+       q->qdisc_modf.weight1.weight_mode=qopt->qdisc_modf.weight1.weight_mode;
+    if(qopt->qdisc_modf.weight2.weight_mode!=-1)
+       q->qdisc_modf.weight2.weight_mode=qopt->qdisc_modf.weight2.weight_mode;
+  }
+  
+  LOCK_END
+  
+  return 0;
+}
+
+static int wrr_tune_proxy(struct Qdisc *sch, struct rtattr *opt) 
+{
+  struct wrr_sched_data *q = (struct wrr_sched_data *)sch->data;
+  struct tc_wrr_qdisc_modf_proxy *qopt = RTA_DATA(opt);
+  int i;
+
+  // Return if we are not configured with proxy support:
+  if(!q->proxydict) return -ENOSYS;
+
+  // Return if not enough data given:
+  if(opt->rta_len<RTA_LENGTH(sizeof(*qopt)) ||
+     opt->rta_len<
+       RTA_LENGTH(sizeof(*qopt)+sizeof(ProxyRemapBlock)*qopt->changec))
+       return -EINVAL;
+
+  LOCK_START;
+  
+  if(qopt->reset) {
+    proxyInitMem(q->proxydict,proxyGetMaxConn(q->proxydict));
+  }
+  
+  // Do all the changes:
+  for(i=0; i<qopt->changec; i++) {
+    proxyConsumeBlock(q->proxydict,&((ProxyRemapBlock*)&qopt->changes)[i]);
+  }
+  
+  LOCK_END;
+  
+  return 0;
+}
+
+static int wrr_tune(struct Qdisc *sch, struct rtattr *opt) {
+  if(((struct tc_wrr_qdisc_modf_std*)RTA_DATA(opt))->proxy) {
+    return wrr_tune_proxy(sch,opt);
+  } else {
+    return wrr_tune_std(sch,opt);
+  }    
+}
+
+//-----------------------------------------------------------------------------
+// Classes.
+//  External and internal IDs are equal. They are the band number plus 1.
+
+// Replace a class with another:
+static int wrr_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
+	             struct Qdisc **old)
+{
+  struct wrr_sched_data *q = (struct wrr_sched_data *)sch->data;
+  if(arg>q->bandc || arg==0)  return -EINVAL;
+  arg--;
+  
+  if (new == NULL)
+    new = &noop_qdisc;
+
+#ifdef KERNEL22
+  *old = xchg(&q->bands[arg].que, new);
+#else
+  LOCK_START
+  *old = q->bands[arg].que;
+  q->bands[arg].que = new;
+  qdisc_reset(*old);
+  LOCK_END	
+#endif
+
+  return 0;
+}
+
+// Returns the qdisc for a class:
+static struct Qdisc * wrr_leaf(struct Qdisc *sch, unsigned long arg)
+{
+  struct wrr_sched_data *q = (struct wrr_sched_data *)sch->data;
+  if(arg>q->bandc || arg==0)  return NULL;
+  arg--;
+  return q->bands[arg].que;
+}
+
+static unsigned long wrr_get(struct Qdisc *sch, u32 classid)
+{
+  struct wrr_sched_data *q = (struct wrr_sched_data *)sch->data;
+  unsigned long band = TC_H_MIN(classid);
+  if(band>q->bandc || band==0) return 0;
+  return band;
+}
+
+static void wrr_put(struct Qdisc *q, unsigned long cl)
+{
+  return;
+}
+
+static int wrr_delete(struct Qdisc *sch, unsigned long cl)
+{
+  struct wrr_sched_data *q = (struct wrr_sched_data *)sch->data;
+  if(cl==0 || cl>q->bandc) return -ENOENT;
+  cl--;
+  return 0;
+}
+
+static int wrr_dump_class(struct Qdisc *sch, unsigned long cl, 
+                          struct sk_buff *skb, struct tcmsg *tcm)
+{
+  struct wrr_sched_data *q = (struct wrr_sched_data *)sch->data;
+  unsigned char *b = skb->tail;
+  struct tc_wrr_class_stats opt;
+
+  // Handle of this class:
+  tcm->tcm_handle = sch->handle|cl;
+  
+  if(cl==0 || cl>q->bandc)
+    goto rtattr_failure;
+  cl--;  
+  
+  if(cl>=q->filter.mac_cur) {
+    // Band is unused:
+    memset(&opt,0,sizeof(opt));
+    opt.used=0;
+  } else {
+    opt.used=1;
+    opt.class_modf.weight1=q->bands[cl].class_modf.weight1;
+    opt.class_modf.weight2=q->bands[cl].class_modf.weight2;
+    weight_transmit(&opt.class_modf.weight1,q->qdisc_modf.weight1,0,0,0,0);
+    weight_transmit(&opt.class_modf.weight2,q->qdisc_modf.weight2,0,0,0,0);
+    memcpy(opt.addr,q->filter.cls2mac+cl*ETH_ALEN,ETH_ALEN);
+    opt.usemac=q->filter.usemac;
+    opt.heappos=q->h.root_1[cl+1].id2idx;
+    if(opt.heappos!=0) { // Is in heap
+      opt.penal_ls=heap_get_penalty(&q->h,cl).ls;  
+      opt.penal_ms=heap_get_penalty(&q->h,cl).ms;
+    } else {
+      opt.penal_ls=0;
+      opt.penal_ms=0;
+    }
+  }
+    
+  // Put quing information:
+  RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+  return skb->len;
+
+rtattr_failure:
+  skb_trim(skb, b - skb->data);
+  return -1;
+}
+
+static int wrr_change(struct Qdisc *sch, u32 handle, u32 parent, 
+                      struct rtattr **tca, unsigned long *arg)
+{
+  unsigned long cl = *arg;
+  struct wrr_sched_data *q = (struct wrr_sched_data *)sch->data;
+  struct rtattr *opt = tca[TCA_OPTIONS-1];
+  struct tc_wrr_class_modf *copt = RTA_DATA(opt);
+  
+  if(cl==0 || cl>q->bandc) return -EINVAL;
+  cl--;  
+  
+  if (opt->rta_len < RTA_LENGTH(sizeof(*copt))) return -EINVAL;
+
+  LOCK_START;
+  
+  weight_setvalue(&q->bands[cl].class_modf.weight1,&copt->weight1);
+  weight_setvalue(&q->bands[cl].class_modf.weight2,&copt->weight2);
+  
+  LOCK_END;
+
+  return 0;
+}
+
+static void wrr_walk(struct Qdisc *sch, struct qdisc_walker *arg)
+{
+  struct wrr_sched_data *q = (struct wrr_sched_data *)sch->data;
+  int prio;
+
+  if (arg->stop) return;
+
+  for (prio = 1; prio <= q->bandc; prio++) {
+    if (arg->count < arg->skip) {
+      arg->count++;
+      continue;
+    }
+    if (arg->fn(sch, prio, arg) < 0) {
+      arg->stop = 1;
+      break;
+    }
+    arg->count++;
+  }
+}
+
+static struct tcf_proto ** wrr_find_tcf(struct Qdisc *sch, unsigned long cl)
+{
+  return NULL;
+}
+
+static unsigned long wrr_bind(struct Qdisc *sch, 
+                              unsigned long parent, u32 classid)
+{
+  return wrr_get(sch, classid);
+}
+
+//-----------------------------------------------------------------------------
+// Generel
+
+static struct Qdisc_class_ops wrr_class_ops =
+{
+	wrr_graft,
+	wrr_leaf,
+
+	wrr_get,
+	wrr_put,
+	wrr_change,
+	wrr_delete,
+	wrr_walk,
+
+	wrr_find_tcf,
+	wrr_bind,
+	wrr_put,
+
+#if !defined(KERNEL22) || defined(CONFIG_RTNETLINK)
+	wrr_dump_class,
+#endif
+};
+
+struct Qdisc_ops wrr_qdisc_ops =
+{
+	NULL,
+	&wrr_class_ops,
+	"wrr",
+	sizeof(struct wrr_sched_data),
+
+	wrr_enqueue,
+	wrr_dequeue,
+	wrr_requeue,
+	wrr_drop,
+
+	wrr_init,
+	wrr_reset,
+	wrr_destroy,
+	wrr_tune,
+
+#if !defined(KERNEL22) || defined(CONFIG_RTNETLINK)
+	wrr_dump,
+#endif
+};
+
+#ifdef MODULE
+
+int init_module(void)
+{
+	return register_qdisc(&wrr_qdisc_ops);
+}
+
+void cleanup_module(void) 
+{
+	unregister_qdisc(&wrr_qdisc_ops);
+}
+
+#ifndef KERNEL22
+  MODULE_LICENSE("GPL");
+#endif
+
+#endif
+
diff -urN linux-2.4.29/net/sctp/ipv6.c linux-2.4.29-uc1/net/sctp/ipv6.c
--- linux-2.4.29/net/sctp/ipv6.c	2005-01-19 14:10:14.000000000 +0000
+++ linux-2.4.29-uc1/net/sctp/ipv6.c	2005-06-14 02:11:49.000000000 +0100
@@ -121,7 +121,7 @@
 	skb->nh.raw = saveip;
 	skb->h.raw = savesctp;
 	if (!sk) {
-		ICMP6_INC_STATS_BH(Icmp6InErrors);
+		ICMP6_INC_STATS_BH(idev, Icmp6InErrors);
 		goto out;
 	}
 
@@ -287,7 +287,8 @@
 			  __FUNCTION__, asoc, dst, NIP6(&daddr->v6.sin6_addr));
 
 	if (!asoc) {
-		ipv6_get_saddr(dst, &daddr->v6.sin6_addr,&saddr->v6.sin6_addr);
+		/* XXX: we need to inherit tp->use_tempaddr */
+		ipv6_get_saddr(dst, &daddr->v6.sin6_addr,&saddr->v6.sin6_addr, 0);
 		SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: "
 				  "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
 				  NIP6(&saddr->v6.sin6_addr));
diff -urN linux-2.4.29/Rules.make linux-2.4.29-uc1/Rules.make
--- linux-2.4.29/Rules.make	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-uc1/Rules.make	2005-06-14 02:11:54.000000000 +0100
@@ -266,7 +266,7 @@
 
 else
 
-$(TOPDIR)/include/linux/modversions.h:
+$(TOPDIR)/include/linux/modversions.h: $(TOPDIR)/include/linux/modsetver.h
 	@echo "#include <linux/modsetver.h>" > $@
 
 endif # CONFIG_MODVERSIONS
diff -urN linux-2.4.29/scripts/mkdep.c linux-2.4.29-uc1/scripts/mkdep.c
--- linux-2.4.29/scripts/mkdep.c	2002-08-03 01:39:46.000000000 +0100
+++ linux-2.4.29-uc1/scripts/mkdep.c	2005-06-14 02:11:42.000000000 +0100
@@ -523,7 +523,9 @@
 void do_depend(const char * filename, const char * command)
 {
 	int mapsize;
+#ifndef __CYGWIN__
 	int pagesizem1 = getpagesize()-1;
+#endif
 	int fd;
 	struct stat st;
 	char * map;
@@ -542,7 +544,9 @@
 	}
 
 	mapsize = st.st_size;
+#ifndef __CYGWIN__
 	mapsize = (mapsize+pagesizem1) & ~pagesizem1;
+#endif
 	map = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
 	if ((long) map == -1) {
 		perror("mkdep: mmap");
diff -urN linux-2.4.29/scripts/pathdown.sh linux-2.4.29-uc1/scripts/pathdown.sh
--- linux-2.4.29/scripts/pathdown.sh	1995-08-15 13:07:03.000000000 +0100
+++ linux-2.4.29-uc1/scripts/pathdown.sh	2005-06-14 02:11:42.000000000 +0100
@@ -3,6 +3,10 @@
 DN=${PWD:?}
 TP=${TOPDIR:?}
 
+if [ "$VIRTUAL_TOPDIR" ]; then
+TP=${VIRTUAL_TOPDIR:?}
+fi
+
 while [ ! $TP/$UP/. -ef $DN ] ;do
 	UP=`basename $PWD`/$UP
 	cd ..
diff -urN linux-2.4.29/scripts/tkgen.c linux-2.4.29-uc1/scripts/tkgen.c
--- linux-2.4.29/scripts/tkgen.c	2002-08-03 01:39:46.000000000 +0100
+++ linux-2.4.29-uc1/scripts/tkgen.c	2005-06-14 02:11:42.000000000 +0100
@@ -545,9 +545,7 @@
 		printf( "\n\t" );
 	    printf( "set %s [expr $%s&15]",
 		vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
-	    printf( "} else {");
-	    printf( "set %s [expr $%s|16]}\n",
-		vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
+		printf( "}\n");
 	    break;
 
 	case token_choice_header:
@@ -607,13 +605,7 @@
 	 */
 	    printf( "set %s [expr $%s&15]",
 		vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
-	    printf( "} else {" );
-
-	/*
-	 * Clear the disable bit to enable the correct radiobutton.
-	 */
-	    printf( "set %s [expr $%s|16]}\n",
-		vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
+	    printf( "}\n" );
 	    break;
 
 	case token_hex:
@@ -903,6 +895,29 @@
 	}
     }
 
+/*
+ *	set all conditional bool/tristates to off unless changed later
+ */
+    for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) {
+		if (cfg->menu_number != menu_num)
+			continue;
+		if (!cfg->cond)
+			continue;
+		switch (cfg->token) {
+		case token_bool:
+		case token_tristate:
+			if (! vartable[cfg->nameindex].global_written) {
+				vartable[cfg->nameindex].global_written = 1;
+				global(vartable[cfg->nameindex].name);
+			}
+			printf("set %s [expr $%s|16]\n", vartable[cfg->nameindex].name,
+					vartable[cfg->nameindex].name);
+			break;
+		default:
+			break;
+		}
+	}
+
     for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
     {
 	char tmp[20];
diff -urN linux-2.4.29/scripts/tkparse.c linux-2.4.29-uc1/scripts/tkparse.c
--- linux-2.4.29/scripts/tkparse.c	2002-08-03 01:39:46.000000000 +0100
+++ linux-2.4.29-uc1/scripts/tkparse.c	2005-06-14 02:11:42.000000000 +0100
@@ -71,6 +71,11 @@
     exit( 1 );
 }
 
+static void syntax_warning( const char * msg )
+{
+    fprintf( stderr, "%s: %d: %s\n", current_file, lineno, msg );
+}
+
 
 
 /*
@@ -135,7 +140,7 @@
 static const char * get_qstring( const char * pnt, char ** label )
 {
     char quote_char;
-    char newlabel [2048];
+    char newlabel [16384];
     char * pnt1;
 
     /* advance to the open quote */
@@ -637,7 +642,7 @@
 	 * Create a conditional for this object's dependencies.
 	 */
 	{
-	    char fake_if [1024];
+	    char fake_if [8192];
 	    struct dependency * dep;
 	    struct condition ** cond_ptr;
 	    int first = 1;
@@ -746,7 +751,7 @@
  */
 static void do_source( const char * filename )
 {
-    char buffer [2048];
+    char buffer [16384];
     FILE * infile;
     const char * old_file;
     int old_lineno;
@@ -768,7 +773,8 @@
     if ( infile == NULL )
     {
 	sprintf( buffer, "unable to open %s", filename );
-	syntax_error( buffer );
+	syntax_warning( buffer );
+        return;
     }
 
     /* push the new file name and line number */
